LyoKICogc2NoZW1hcy5jIDogaW1wbGVtZW50YXRpb24gb2YgdGhlIFhNTCBTY2hlbWEgaGFuZGxpbmcgYW5kCiAqICAgICAgICAgICAgIHNjaGVtYSB2YWxpZGl0eSBjaGVja2luZwogKgogKiBTZWUgQ29weXJpZ2h0IGZvciB0aGUgc3RhdHVzIG9mIHRoaXMgc29mdHdhcmUuCiAqCiAqIERhbmllbCBWZWlsbGFyZCA8dmVpbGxhcmRAcmVkaGF0LmNvbT4KICovCgovKgogKiBUT0RPOgogKiAgIC0gd2hlbiB0eXBlcyBhcmUgcmVkZWZpbmVkIGluIGluY2x1ZGVzLCBjaGVjayB0aGF0IGFsbAogKiAgICAgdHlwZXMgaW4gdGhlIHJlZGVmIGxpc3QgYXJlIGVxdWFsCiAqICAgICAtPiBuZWVkIGEgdHlwZSBlcXVhbGl0eSBvcGVyYXRpb24uCiAqICAgLSBpZiB3ZSBkb24ndCBpbnRlbmQgdG8gdXNlIHRoZSBzY2hlbWEgZm9yIHNjaGVtYXMsIHdlIAogKiAgICAgbmVlZCB0byB2YWxpZGF0ZSBhbGwgc2NoZW1hIGF0dHJpYnV0ZXMgKHJlZiwgdHlwZSwgbmFtZSkKICogICAgIGFnYWluc3QgdGhlaXIgdHlwZXMuCiAqLwojZGVmaW5lIElOX0xJQlhNTAojaW5jbHVkZSAibGlieG1sLmgiCgojaWZkZWYgTElCWE1MX1NDSEVNQVNfRU5BQkxFRAoKI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8bGlieG1sL3htbG1lbW9yeS5oPgojaW5jbHVkZSA8bGlieG1sL3BhcnNlci5oPgojaW5jbHVkZSA8bGlieG1sL3BhcnNlckludGVybmFscy5oPgojaW5jbHVkZSA8bGlieG1sL2hhc2guaD4KI2luY2x1ZGUgPGxpYnhtbC91cmkuaD4KCiNpbmNsdWRlIDxsaWJ4bWwveG1sc2NoZW1hcy5oPgojaW5jbHVkZSA8bGlieG1sL3NjaGVtYXNJbnRlcm5hbHMuaD4KI2luY2x1ZGUgPGxpYnhtbC94bWxzY2hlbWFzdHlwZXMuaD4KI2luY2x1ZGUgPGxpYnhtbC94bWxhdXRvbWF0YS5oPgojaW5jbHVkZSA8bGlieG1sL3htbHJlZ2V4cC5oPgojaW5jbHVkZSA8bGlieG1sL2RpY3QuaD4KCi8qICNkZWZpbmUgREVCVUcgMSAqLwoKLyogI2RlZmluZSBERUJVR19DT05URU5UIDEgKi8KCi8qICNkZWZpbmUgREVCVUdfVFlQRSAxICovCgovKiAjZGVmaW5lIERFQlVHX0NPTlRFTlRfUkVHRVhQIDEgKi8KCi8qICNkZWZpbmUgREVCVUdfQVVUT01BVEEgMSAqLwoKLyogI2RlZmluZSBERUJVR19BVFRSX1ZBTElEQVRJT04gMSAqLwoKI2RlZmluZSBVTkJPVU5ERUQgKDEgPDwgMzApCiNkZWZpbmUgVE9ETyAJCQkJCQkJCVwKICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAkJCQlcCgkgICAgIlVuaW1wbGVtZW50ZWQgYmxvY2sgYXQgJXM6JWRcbiIsCQkJCVwKICAgICAgICAgICAgX19GSUxFX18sIF9fTElORV9fKTsKCiNkZWZpbmUgWE1MX1NDSEVNQVNfREVGQVVMVF9OQU1FU1BBQ0UgKGNvbnN0IHhtbENoYXIgKikidGhlIGRlZmF1bHQgbmFtZXNwYWNlIgoKLyoKICogVGhlIFhNTCBTY2hlbWFzIG5hbWVzcGFjZXMKICovCnN0YXRpYyBjb25zdCB4bWxDaGFyICp4bWxTY2hlbWFOcyA9IChjb25zdCB4bWxDaGFyICopCiAgICAiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiOwoKc3RhdGljIGNvbnN0IHhtbENoYXIgKnhtbFNjaGVtYUluc3RhbmNlTnMgPSAoY29uc3QgeG1sQ2hhciAqKQogICAgImh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIjsKCiNkZWZpbmUgSVNfU0NIRU1BKG5vZGUsIHR5cGUpCQkJCQkJXAogICAoKG5vZGUgIT0gTlVMTCkgJiYgKG5vZGUtPm5zICE9IE5VTEwpICYmCQkJCVwKICAgICh4bWxTdHJFcXVhbChub2RlLT5uYW1lLCAoY29uc3QgeG1sQ2hhciAqKSB0eXBlKSkgJiYJCVwKICAgICh4bWxTdHJFcXVhbChub2RlLT5ucy0+aHJlZiwgeG1sU2NoZW1hTnMpKSkKCiNkZWZpbmUgWE1MX1NDSEVNQVNfUEFSU0VfRVJST1IJCTEKCiNkZWZpbmUgU0NIRU1BU19QQVJTRV9PUFRJT05TIFhNTF9QQVJTRV9OT0VOVAoKc3RydWN0IF94bWxTY2hlbWFQYXJzZXJDdHh0IHsKICAgIHZvaWQgKnVzZXJEYXRhOyAgICAgICAgICAgICAvKiB1c2VyIHNwZWNpZmljIGRhdGEgYmxvY2sgKi8KICAgIHhtbFNjaGVtYVZhbGlkaXR5RXJyb3JGdW5jIGVycm9yOyAgIC8qIHRoZSBjYWxsYmFjayBpbiBjYXNlIG9mIGVycm9ycyAqLwogICAgeG1sU2NoZW1hVmFsaWRpdHlXYXJuaW5nRnVuYyB3YXJuaW5nOyAgICAgICAvKiB0aGUgY2FsbGJhY2sgaW4gY2FzZSBvZiB3YXJuaW5nICovCiAgICB4bWxTY2hlbWFWYWxpZEVycm9yIGVycjsKICAgIGludCBuYmVycm9yczsKICAgIHhtbFN0cnVjdHVyZWRFcnJvckZ1bmMgc2Vycm9yOwoKICAgIHhtbFNjaGVtYVB0ciB0b3BzY2hlbWE7CS8qIFRoZSBtYWluIHNjaGVtYSAqLwogICAgeG1sSGFzaFRhYmxlUHRyIG5hbWVzcGFjZXM7CS8qIEhhc2ggdGFibGUgb2YgbmFtZXNwYWNlcyB0byBzY2hlbWFzICovCgogICAgeG1sU2NoZW1hUHRyIHNjaGVtYTsgICAgICAgIC8qIFRoZSBzY2hlbWEgaW4gdXNlICovCiAgICBjb25zdCB4bWxDaGFyICpjb250YWluZXI7ICAgLyogdGhlIGN1cnJlbnQgZWxlbWVudCwgZ3JvdXAsIC4uLiAqLwogICAgaW50IGNvdW50ZXI7CgogICAgY29uc3QgeG1sQ2hhciAqVVJMOwogICAgeG1sRG9jUHRyIGRvYzsKICAgIGludCBwcmVzZXJ2ZTsJCS8qIFdoZXRoZXIgdGhlIGRvYyBzaG91bGQgYmUgZnJlZWQgICovCgogICAgY29uc3QgY2hhciAqYnVmZmVyOwogICAgaW50IHNpemU7CgogICAgLyoKICAgICAqIFVzZWQgdG8gYnVpbGQgY29tcGxleCBlbGVtZW50IGNvbnRlbnQgbW9kZWxzCiAgICAgKi8KICAgIHhtbEF1dG9tYXRhUHRyIGFtOwogICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBzdGFydDsKICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgZW5kOwogICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBzdGF0ZTsKCiAgICB4bWxEaWN0UHRyIGRpY3Q7CQkvKiBkaWN0aW9ubmFyeSBmb3IgaW50ZXJuZWQgc3RyaW5nIG5hbWVzICovCiAgICBpbnQgICAgICAgIGluY2x1ZGVzOwkvKiB0aGUgaW5jbHVzaW9uIGxldmVsLCAwIGZvciByb290IG9yIGltcG9ydHMgKi8KICAgIHhtbFNjaGVtYVR5cGVQdHIgY3R4dFR5cGU7IC8qIFRoZSBjdXJyZW50IGNvbnRleHQgc2ltcGxlL2NvbXBsZXggdHlwZSAqLwogICAgeG1sU2NoZW1hVHlwZVB0ciBwYXJlbnRJdGVtOyAvKiBUaGUgY3VycmVudCBwYXJlbnQgc2NoZW1hIGl0ZW0gKi8KfTsKCgojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfVU5LTk9XTiAxCiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9DSEVDS0VEIDIKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX1BST0hJQklURUQgMwojZGVmaW5lIFhNTF9TQ0hFTUFTX0FUVFJfTUlTU0lORyA0CiNkZWZpbmUgWE1MX1NDSEVNQVNfQVRUUl9JTlZBTElEX1ZBTFVFIDUKI2RlZmluZSBYTUxfU0NIRU1BU19BVFRSX1RZUEVfTk9UX1JFU09MVkVEIDYKCnR5cGVkZWYgc3RydWN0IF94bWxTY2hlbWFBdHRyU3RhdGUgeG1sU2NoZW1hQXR0clN0YXRlOwp0eXBlZGVmIHhtbFNjaGVtYUF0dHJTdGF0ZSAqeG1sU2NoZW1hQXR0clN0YXRlUHRyOwpzdHJ1Y3QgX3htbFNjaGVtYUF0dHJTdGF0ZSB7CiAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgbmV4dDsKICAgIHhtbEF0dHJQdHIgYXR0cjsKICAgIGludCBzdGF0ZTsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBkZWNsOwp9OwoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkQ3R4dDoKICoKICogQSBTY2hlbWFzIHZhbGlkYXRpb24gY29udGV4dAogKi8KCnN0cnVjdCBfeG1sU2NoZW1hVmFsaWRDdHh0IHsKICAgIHZvaWQgKnVzZXJEYXRhOyAgICAgICAgICAgICAvKiB1c2VyIHNwZWNpZmljIGRhdGEgYmxvY2sgKi8KICAgIHhtbFNjaGVtYVZhbGlkaXR5RXJyb3JGdW5jIGVycm9yOyAgIC8qIHRoZSBjYWxsYmFjayBpbiBjYXNlIG9mIGVycm9ycyAqLwogICAgeG1sU2NoZW1hVmFsaWRpdHlXYXJuaW5nRnVuYyB3YXJuaW5nOyAgICAgICAvKiB0aGUgY2FsbGJhY2sgaW4gY2FzZSBvZiB3YXJuaW5nICovCiAgICB4bWxTdHJ1Y3R1cmVkRXJyb3JGdW5jIHNlcnJvcjsKCiAgICB4bWxTY2hlbWFQdHIgc2NoZW1hOyAgICAgICAgLyogVGhlIHNjaGVtYSBpbiB1c2UgKi8KICAgIHhtbERvY1B0ciBkb2M7CiAgICB4bWxQYXJzZXJJbnB1dEJ1ZmZlclB0ciBpbnB1dDsKICAgIHhtbENoYXJFbmNvZGluZyBlbmM7CiAgICB4bWxTQVhIYW5kbGVyUHRyIHNheDsKICAgIHZvaWQgKnVzZXJfZGF0YTsKCiAgICB4bWxEb2NQdHIgbXlEb2M7CiAgICBpbnQgZXJyOwogICAgaW50IG5iZXJyb3JzOwoKICAgIHhtbE5vZGVQdHIgbm9kZTsKICAgIHhtbE5vZGVQdHIgY3VyOwogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwoKICAgIHhtbFJlZ0V4ZWNDdHh0UHRyIHJlZ2V4cDsKICAgIHhtbFNjaGVtYVZhbFB0ciB2YWx1ZTsKCiAgICB4bWxTY2hlbWFBdHRyU3RhdGVQdHIgYXR0clRvcDsKICAgIC8qIHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciBhdHRyQmFzZTsgKi8KICAgIC8qIGludCBhdHRyTWF4OyAqLwogICAgeG1sU2NoZW1hQXR0clN0YXRlUHRyIGF0dHI7Cn07CgovKgogKiBUaGVzZSBhcmUgdGhlIGVudHJpZXMgaW4gdGhlIHNjaGVtYXMgaW1wb3J0U2NoZW1hcyBoYXNoIHRhYmxlCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hSW1wb3J0IHhtbFNjaGVtYUltcG9ydDsKdHlwZWRlZiB4bWxTY2hlbWFJbXBvcnQgKnhtbFNjaGVtYUltcG9ydFB0cjsKc3RydWN0IF94bWxTY2hlbWFJbXBvcnQgewogICAgY29uc3QgeG1sQ2hhciAqc2NoZW1hTG9jYXRpb247CiAgICB4bWxTY2hlbWFQdHIgc2NoZW1hOwp9OwoKLyoKICogVGhlc2UgYXJlIHRoZSBlbnRyaWVzIGFzc29jaWF0ZWQgdG8gaW5jbHVkZXMgaW4gYSBzY2hlbWFzCiAqLwp0eXBlZGVmIHN0cnVjdCBfeG1sU2NoZW1hSW5jbHVkZSB4bWxTY2hlbWFJbmNsdWRlOwp0eXBlZGVmIHhtbFNjaGVtYUluY2x1ZGUgKnhtbFNjaGVtYUluY2x1ZGVQdHI7CnN0cnVjdCBfeG1sU2NoZW1hSW5jbHVkZSB7CiAgICB4bWxTY2hlbWFJbmNsdWRlUHRyIG5leHQ7CgogICAgY29uc3QgeG1sQ2hhciAqc2NoZW1hTG9jYXRpb247CiAgICB4bWxEb2NQdHIgZG9jOwp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVNvbWUgcHJlZGVjbGFyYXRpb25zCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwojaWYgMCAvKiBOb3QgY3VycmVudGx5IHVzZWQuICovCnN0YXRpYyBpbnQgeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiB2YWx1ZSk7CiNlbmRpZgoKc3RhdGljIGludCB4bWxTY2hlbWFQYXJzZUluY2x1ZGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpOwojaWYgMApzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVmFsdWVJbnRlcm5hbCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsCgkJCSAgICAgY29uc3QgeG1sQ2hhciAqIHZhbHVlLAoJCQkgICAgIGludCBmaXJlRXJyb3JzKTsKI2VuZGlmIC8qIE5vdCBjdXJyZW50bHkgdXNlZC4gKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVHlwZUZpeHVwKHhtbFNjaGVtYVR5cGVQdHIgdHlwZURlY2wsCiAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIGNvbnN0IHhtbENoYXIgKiBuYW1lKTsKc3RhdGljIGNvbnN0IGNoYXIgKgp4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyh4bWxTY2hlbWFUeXBlVHlwZSB0eXBlKTsKc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgCgkJCQkgY29uc3QgeG1sQ2hhciAqdmFsdWUsCgkJCQkgaW50IGZpcmVFcnJvcnMsCQkJCSAKCQkJCSBpbnQgYXBwbHlGYWNldHMpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJCQkJCQkJCSoKICogCQkJRGF0YXR5cGUgZXJyb3IgaGFuZGxlcnMJCQkJKgogKgkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKgogKiB4bWxTY2hlbWFQRXJyTWVtb3J5OgogKiBAbm9kZTogYSBjb250ZXh0IG5vZGUKICogQGV4dHJhOiAgZXh0cmEgaW5mb3JtYXRpb25zCiAqCiAqIEhhbmRsZSBhbiBvdXQgb2YgbWVtb3J5IGNvbmRpdGlvbgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEVyck1lbW9yeSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZXh0cmEsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgaWYgKGN0eHQgIT0gTlVMTCkKICAgICAgICBjdHh0LT5uYmVycm9ycysrOwogICAgX194bWxTaW1wbGVFcnJvcihYTUxfRlJPTV9TQ0hFTUFTUCwgWE1MX0VSUl9OT19NRU1PUlksIG5vZGUsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgIGV4dHJhKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBFcnI6CiAqIEBjdHh0OiB0aGUgcGFyc2luZyBjb250ZXh0CiAqIEBub2RlOiB0aGUgY29udGV4dCBub2RlCiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG1zZzogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IGV4dHJhIGRhdGEKICogQHN0cjI6IGV4dHJhIGRhdGEKICogCiAqIEhhbmRsZSBhIHBhcnNlciBlcnJvcgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUEVycih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwgaW50IGVycm9yLAogICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm1zZywgY29uc3QgeG1sQ2hhciAqIHN0cjEsIGNvbnN0IHhtbENoYXIgKiBzdHIyKQp7CiAgICB4bWxHZW5lcmljRXJyb3JGdW5jIGNoYW5uZWwgPSBOVUxMOwogICAgeG1sU3RydWN0dXJlZEVycm9yRnVuYyBzY2hhbm5lbCA9IE5VTEw7CiAgICB2b2lkICpkYXRhID0gTlVMTDsKCiAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CiAgICAgICAgY3R4dC0+bmJlcnJvcnMrKzsKICAgICAgICBjaGFubmVsID0gY3R4dC0+ZXJyb3I7CiAgICAgICAgZGF0YSA9IGN0eHQtPnVzZXJEYXRhOwoJc2NoYW5uZWwgPSBjdHh0LT5zZXJyb3I7CiAgICB9CiAgICBfX3htbFJhaXNlRXJyb3Ioc2NoYW5uZWwsIGNoYW5uZWwsIGRhdGEsIGN0eHQsIG5vZGUsIFhNTF9GUk9NX1NDSEVNQVNQLAogICAgICAgICAgICAgICAgICAgIGVycm9yLCBYTUxfRVJSX0VSUk9SLCBOVUxMLCAwLAogICAgICAgICAgICAgICAgICAgIChjb25zdCBjaGFyICopIHN0cjEsIChjb25zdCBjaGFyICopIHN0cjIsIE5VTEwsIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgbXNnLCBzdHIxLCBzdHIyKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBFcnIyOgogKiBAY3R4dDogdGhlIHBhcnNpbmcgY29udGV4dAogKiBAbm9kZTogdGhlIGNvbnRleHQgbm9kZQogKiBAbm9kZTogdGhlIGN1cnJlbnQgY2hpbGQKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAbXNnOiB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMTogZXh0cmEgZGF0YQogKiBAc3RyMjogZXh0cmEgZGF0YQogKiAKICogSGFuZGxlIGEgcGFyc2VyIGVycm9yCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQRXJyMih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwKICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBjaGlsZCwgaW50IGVycm9yLAogICAgICAgICAgICAgICBjb25zdCBjaGFyICptc2csIGNvbnN0IHhtbENoYXIgKiBzdHIxLCBjb25zdCB4bWxDaGFyICogc3RyMikKewogICAgaWYgKGNoaWxkICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBjaGlsZCwgZXJyb3IsIG1zZywgc3RyMSwgc3RyMik7CiAgICBlbHNlCiAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCBlcnJvciwgbXNnLCBzdHIxLCBzdHIyKTsKfQoKCi8qKgogKiB4bWxTY2hlbWFQRXJyRXh0OgogKiBAY3R4dDogdGhlIHBhcnNpbmcgY29udGV4dAogKiBAbm9kZTogdGhlIGNvbnRleHQgbm9kZQogKiBAZXJyb3I6IHRoZSBlcnJvciBjb2RlIAogKiBAc3RyRGF0YTE6IGV4dHJhIGRhdGEKICogQHN0ckRhdGEyOiBleHRyYSBkYXRhCiAqIEBzdHJEYXRhMzogZXh0cmEgZGF0YQogKiBAbXNnOiB0aGUgbWVzc2FnZQogKiBAc3RyMTogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiBAc3RyMjogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiBAc3RyMzogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiBAc3RyNDogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiBAc3RyNTogIGV4dHJhIHBhcmFtZXRlciBmb3IgdGhlIG1lc3NhZ2UgZGlzcGxheQogKiAKICogSGFuZGxlIGEgcGFyc2VyIGVycm9yCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQRXJyRXh0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLCBpbnQgZXJyb3IsCgkJY29uc3QgeG1sQ2hhciAqIHN0ckRhdGExLCBjb25zdCB4bWxDaGFyICogc3RyRGF0YTIsIAoJCWNvbnN0IHhtbENoYXIgKiBzdHJEYXRhMywgY29uc3QgY2hhciAqbXNnLCBjb25zdCB4bWxDaGFyICogc3RyMSwgCgkJY29uc3QgeG1sQ2hhciAqIHN0cjIsIGNvbnN0IHhtbENoYXIgKiBzdHIzLCBjb25zdCB4bWxDaGFyICogc3RyNCwKCQljb25zdCB4bWxDaGFyICogc3RyNSkKewoKICAgIHhtbEdlbmVyaWNFcnJvckZ1bmMgY2hhbm5lbCA9IE5VTEw7CiAgICB4bWxTdHJ1Y3R1cmVkRXJyb3JGdW5jIHNjaGFubmVsID0gTlVMTDsKICAgIHZvaWQgKmRhdGEgPSBOVUxMOwoKICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICBjdHh0LT5uYmVycm9ycysrOwogICAgICAgIGNoYW5uZWwgPSBjdHh0LT5lcnJvcjsKICAgICAgICBkYXRhID0gY3R4dC0+dXNlckRhdGE7CglzY2hhbm5lbCA9IGN0eHQtPnNlcnJvcjsKICAgIH0KICAgIF9feG1sUmFpc2VFcnJvcihzY2hhbm5lbCwgY2hhbm5lbCwgZGF0YSwgY3R4dCwgbm9kZSwgWE1MX0ZST01fU0NIRU1BU1AsCiAgICAgICAgICAgICAgICAgICAgZXJyb3IsIFhNTF9FUlJfRVJST1IsIE5VTEwsIDAsCiAgICAgICAgICAgICAgICAgICAgKGNvbnN0IGNoYXIgKikgc3RyRGF0YTEsIChjb25zdCBjaGFyICopIHN0ckRhdGEyLCAKCQkgICAgKGNvbnN0IGNoYXIgKikgc3RyRGF0YTMsIDAsIDAsIG1zZywgc3RyMSwgc3RyMiwgCgkJICAgIHN0cjMsIHN0cjQsIHN0cjUpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYVZUeXBlRXJyTWVtb3J5OgogKiBAbm9kZTogYSBjb250ZXh0IG5vZGUKICogQGV4dHJhOiAgZXh0cmEgaW5mb3JtYXRpb25zCiAqCiAqIEhhbmRsZSBhbiBvdXQgb2YgbWVtb3J5IGNvbmRpdGlvbgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVkVyck1lbW9yeSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpleHRyYSwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBpZiAoY3R4dCAhPSBOVUxMKSB7CiAgICAgICAgY3R4dC0+bmJlcnJvcnMrKzsKICAgICAgICBjdHh0LT5lcnIgPSBYTUxfU0NIRU1BU19FUlJfSU5URVJOQUw7CiAgICB9CiAgICBfX3htbFNpbXBsZUVycm9yKFhNTF9GUk9NX1NDSEVNQVNWLCBYTUxfRVJSX05PX01FTU9SWSwgbm9kZSwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgZXh0cmEpOwp9CgovKioKICogeG1sU2NoZW1hVkVycjM6CiAqIEBjdHh0OiB0aGUgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiB0aGUgY29udGV4dCBub2RlCiAqIEBlcnJvcjogdGhlIGVycm9yIGNvZGUKICogQG1zZzogdGhlIGVycm9yIG1lc3NhZ2UKICogQHN0cjE6IGV4dHJhIGRhdGEKICogQHN0cjI6IGV4dHJhIGRhdGEKICogQHN0cjM6IGV4dHJhIGRhdGEKICogCiAqIEhhbmRsZSBhIHZhbGlkYXRpb24gZXJyb3IKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVZFcnIzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUsIGludCBlcnJvciwKICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbXNnLCBjb25zdCB4bWxDaGFyICpzdHIxLCBjb25zdCB4bWxDaGFyICpzdHIyLAoJICAgICAgIGNvbnN0IHhtbENoYXIgKnN0cjMpCnsKICAgIHhtbFN0cnVjdHVyZWRFcnJvckZ1bmMgc2NoYW5uZWwgPSBOVUxMOwogICAgeG1sR2VuZXJpY0Vycm9yRnVuYyBjaGFubmVsID0gTlVMTDsKICAgIHZvaWQgKmRhdGEgPSBOVUxMOwoKICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICBjdHh0LT5uYmVycm9ycysrOwoJY3R4dC0+ZXJyID0gZXJyb3I7CiAgICAgICAgY2hhbm5lbCA9IGN0eHQtPmVycm9yOwogICAgICAgIHNjaGFubmVsID0gY3R4dC0+c2Vycm9yOwogICAgICAgIGRhdGEgPSBjdHh0LT51c2VyRGF0YTsKICAgIH0KICAgIC8qIHJlYWp1c3QgdG8gZ2xvYmFsIGVycm9yIG51bWJlcnMgKi8KICAgIGVycm9yICs9IFhNTF9TQ0hFTUFWX05PUk9PVCAtIFhNTF9TQ0hFTUFTX0VSUl9OT1JPT1Q7CiAgICBfX3htbFJhaXNlRXJyb3Ioc2NoYW5uZWwsIGNoYW5uZWwsIGRhdGEsIGN0eHQsIG5vZGUsIFhNTF9GUk9NX1NDSEVNQVNWLAogICAgICAgICAgICAgICAgICAgIGVycm9yLCBYTUxfRVJSX0VSUk9SLCBOVUxMLCAwLAogICAgICAgICAgICAgICAgICAgIChjb25zdCBjaGFyICopIHN0cjEsIChjb25zdCBjaGFyICopIHN0cjIsCgkJICAgIChjb25zdCBjaGFyICopIHN0cjMsIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgbXNnLCBzdHIxLCBzdHIyLCBzdHIzKTsKfQovKioKICogeG1sU2NoZW1hVkVycjoKICogQGN0eHQ6IHRoZSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6IHRoZSBjb250ZXh0IG5vZGUKICogQGVycm9yOiB0aGUgZXJyb3IgY29kZQogKiBAbXNnOiB0aGUgZXJyb3IgbWVzc2FnZQogKiBAc3RyMTogZXh0cmEgZGF0YQogKiBAc3RyMjogZXh0cmEgZGF0YQogKiAKICogSGFuZGxlIGEgdmFsaWRhdGlvbiBlcnJvcgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVkVycih4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLCBpbnQgZXJyb3IsCiAgICAgICAgICAgICAgY29uc3QgY2hhciAqbXNnLCBjb25zdCB4bWxDaGFyICogc3RyMSwgY29uc3QgeG1sQ2hhciAqIHN0cjIpCnsKICAgIHhtbFN0cnVjdHVyZWRFcnJvckZ1bmMgc2NoYW5uZWwgPSBOVUxMOwogICAgeG1sR2VuZXJpY0Vycm9yRnVuYyBjaGFubmVsID0gTlVMTDsKICAgIHZvaWQgKmRhdGEgPSBOVUxMOwoKICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICBjdHh0LT5uYmVycm9ycysrOwoJY3R4dC0+ZXJyID0gZXJyb3I7CiAgICAgICAgY2hhbm5lbCA9IGN0eHQtPmVycm9yOwogICAgICAgIGRhdGEgPSBjdHh0LT51c2VyRGF0YTsKICAgICAgICBzY2hhbm5lbCA9IGN0eHQtPnNlcnJvcjsKICAgIH0KICAgIC8qIHJlYWp1c3QgdG8gZ2xvYmFsIGVycm9yIG51bWJlcnMgKi8KICAgIGVycm9yICs9IFhNTF9TQ0hFTUFWX05PUk9PVCAtIFhNTF9TQ0hFTUFTX0VSUl9OT1JPT1Q7CiAgICBfX3htbFJhaXNlRXJyb3Ioc2NoYW5uZWwsIGNoYW5uZWwsIGRhdGEsIGN0eHQsIG5vZGUsIFhNTF9GUk9NX1NDSEVNQVNWLAogICAgICAgICAgICAgICAgICAgIGVycm9yLCBYTUxfRVJSX0VSUk9SLCBOVUxMLCAwLAogICAgICAgICAgICAgICAgICAgIChjb25zdCBjaGFyICopIHN0cjEsIChjb25zdCBjaGFyICopIHN0cjIsIE5VTEwsIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgbXNnLCBzdHIxLCBzdHIyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCUFsbG9jYXRpb24gZnVuY3Rpb25zCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqCiAqIHhtbFNjaGVtYU5ld1NjaGVtYToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogQWxsb2NhdGUgYSBuZXcgU2NoZW1hIHN0cnVjdHVyZS4KICoKICogUmV0dXJucyB0aGUgbmV3bHkgYWxsb2NhdGVkIHN0cnVjdHVyZSBvciBOVUxMIGluIGNhc2Ugb3IgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFQdHIKeG1sU2NoZW1hTmV3U2NoZW1hKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgeG1sU2NoZW1hUHRyIHJldDsKCiAgICByZXQgPSAoeG1sU2NoZW1hUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYSkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBzY2hlbWEiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYSkpOwogICAgcmV0LT5kaWN0ID0gY3R4dC0+ZGljdDsKICAgIHhtbERpY3RSZWZlcmVuY2UocmV0LT5kaWN0KTsKCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFOZXdGYWNldDoKICoKICogQWxsb2NhdGUgYSBuZXcgRmFjZXQgc3RydWN0dXJlLgogKgogKiBSZXR1cm5zIHRoZSBuZXdseSBhbGxvY2F0ZWQgc3RydWN0dXJlIG9yIE5VTEwgaW4gY2FzZSBvciBlcnJvcgogKi8KeG1sU2NoZW1hRmFjZXRQdHIKeG1sU2NoZW1hTmV3RmFjZXQodm9pZCkKewogICAgeG1sU2NoZW1hRmFjZXRQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFGYWNldFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFGYWNldCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFGYWNldCkpOwoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYU5ld0Fubm90OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIGEgbm9kZQogKgogKiBBbGxvY2F0ZSBhIG5ldyBhbm5vdGF0aW9uIHN0cnVjdHVyZS4KICoKICogUmV0dXJucyB0aGUgbmV3bHkgYWxsb2NhdGVkIHN0cnVjdHVyZSBvciBOVUxMIGluIGNhc2Ugb3IgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFBbm5vdFB0cgp4bWxTY2hlbWFOZXdBbm5vdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hQW5ub3RQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFBbm5vdFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBbm5vdCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBhbm5vdGF0aW9uIiwgbm9kZSk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFBbm5vdCkpOwogICAgcmV0LT5jb250ZW50ID0gbm9kZTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVBbm5vdDoKICogQGFubm90OiAgYSBzY2hlbWEgdHlwZSBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIGFubm90YXRpb24gc3RydWN0dXJlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlQW5ub3QoeG1sU2NoZW1hQW5ub3RQdHIgYW5ub3QpCnsKICAgIGlmIChhbm5vdCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIHhtbEZyZWUoYW5ub3QpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZUltcG9ydDoKICogQGltcG9ydDogIGEgc2NoZW1hIGltcG9ydCBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhbiBpbXBvcnQgc3RydWN0dXJlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlSW1wb3J0KHhtbFNjaGVtYUltcG9ydFB0ciBpbXBvcnQpCnsKICAgIGlmIChpbXBvcnQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CgogICAgeG1sU2NoZW1hRnJlZShpbXBvcnQtPnNjaGVtYSk7CiAgICB4bWxGcmVlKGltcG9ydCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlSW5jbHVkZToKICogQGluY2x1ZGU6ICBhIHNjaGVtYSBpbmNsdWRlIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGFuIGluY2x1ZGUgc3RydWN0dXJlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlSW5jbHVkZSh4bWxTY2hlbWFJbmNsdWRlUHRyIGluY2x1ZGUpCnsKICAgIGlmIChpbmNsdWRlID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwoKICAgIHhtbEZyZWVEb2MoaW5jbHVkZS0+ZG9jKTsKICAgIHhtbEZyZWUoaW5jbHVkZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlSW5jbHVkZUxpc3Q6CiAqIEBpbmNsdWRlczogIGEgc2NoZW1hIGluY2x1ZGUgbGlzdAogKgogKiBEZWFsbG9jYXRlIGFuIGluY2x1ZGUgc3RydWN0dXJlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlSW5jbHVkZUxpc3QoeG1sU2NoZW1hSW5jbHVkZVB0ciBpbmNsdWRlcykKewogICAgeG1sU2NoZW1hSW5jbHVkZVB0ciBuZXh0OwoKICAgIHdoaWxlIChpbmNsdWRlcyAhPSBOVUxMKSB7CiAgICAgICAgbmV4dCA9IGluY2x1ZGVzLT5uZXh0OwoJeG1sU2NoZW1hRnJlZUluY2x1ZGUoaW5jbHVkZXMpOwoJaW5jbHVkZXMgPSBuZXh0OwogICAgfQp9CgovKioKICogeG1sU2NoZW1hRnJlZU5vdGF0aW9uOgogKiBAc2NoZW1hOiAgYSBzY2hlbWEgbm90YXRpb24gc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgTm90YXRpb24gc3RydWN0dXJlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZU5vdGF0aW9uKHhtbFNjaGVtYU5vdGF0aW9uUHRyIG5vdGEpCnsKICAgIGlmIChub3RhID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgeG1sRnJlZShub3RhKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGU6CiAqIEBzY2hlbWE6ICBhIHNjaGVtYSBhdHRyaWJ1dGUgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgQXR0cmlidXRlIHN0cnVjdHVyZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVBdHRyaWJ1dGUoeG1sU2NoZW1hQXR0cmlidXRlUHRyIGF0dHIpCnsKICAgIGlmIChhdHRyID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgeG1sRnJlZShhdHRyKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0OgogKiBzZXQ6ICBhIHNjaGVtYSB3aWxkY2FyZCBuYW1lc3BhY2UKICoKICogRGVhbGxvY2F0ZXMgYSBsaXN0IG9mIHdpbGRjYXJkIGNvbnN0cmFpbnQgc3RydWN0dXJlcy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgc2V0KQp7CiAgICB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIG5leHQ7CgogICAgd2hpbGUgKHNldCAhPSBOVUxMKSB7CgluZXh0ID0gc2V0LT5uZXh0OwoJeG1sRnJlZShzZXQpOwoJc2V0ID0gbmV4dDsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVXaWxkY2FyZDoKICogQHdpbGRjYXJkOiAgYSB3aWxkY2FyZCBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZXMgYSB3aWxkY2FyZCBzdHJ1Y3R1cmUuCiAqLwp2b2lkCnhtbFNjaGVtYUZyZWVXaWxkY2FyZCh4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkY2FyZCkKewogICAgaWYgKHdpbGRjYXJkID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKHdpbGRjYXJkLT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVBbm5vdCh3aWxkY2FyZC0+YW5ub3QpOwogICAgaWYgKHdpbGRjYXJkLT5uc1NldCAhPSBOVUxMKSAKCXhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KHdpbGRjYXJkLT5uc1NldCk7ICAgIAogICAgaWYgKHdpbGRjYXJkLT5uZWdOc1NldCAhPSBOVUxMKSAKCXhtbEZyZWUod2lsZGNhcmQtPm5lZ05zU2V0KTsgICAgCiAgICB4bWxGcmVlKHdpbGRjYXJkKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVHcm91cDoKICogQHNjaGVtYTogIGEgc2NoZW1hIGF0dHJpYnV0ZSBncm91cCBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIFNjaGVtYSBBdHRyaWJ1dGUgR3JvdXAgc3RydWN0dXJlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZUdyb3VwKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIGF0dHIpCnsKICAgIGlmIChhdHRyID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGF0dHItPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZUFubm90KGF0dHItPmFubm90KTsKICAgIGlmICgoYXR0ci0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSR1JPVVBfR0xPQkFMKSAmJiAKCShhdHRyLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSkKCXhtbFNjaGVtYUZyZWVXaWxkY2FyZChhdHRyLT5hdHRyaWJ1dGVXaWxkY2FyZCk7CgogICAgeG1sRnJlZShhdHRyKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVVc2VMaXN0OgogKiBAYXR0clVzZTogIGFuIGF0dHJpYnV0ZSBsaW5rCiAqCiAqIERlYWxsb2NhdGUgYSBsaXN0IG9mIHNjaGVtYSBhdHRyaWJ1dGUgdXNlcy4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVVc2VMaXN0KHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIgYXR0clVzZSkKewogICAgeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciBuZXh0OwoKICAgIHdoaWxlIChhdHRyVXNlICE9IE5VTEwpIHsKCW5leHQgPSBhdHRyVXNlLT5uZXh0OwoJeG1sRnJlZShhdHRyVXNlKTsKCWF0dHJVc2UgPSBuZXh0OwogICAgfSAgICAKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVUeXBlTGlua0xpc3Q6CiAqIEBhbGluazogYSB0eXBlIGxpbmsKICoKICogRGVhbGxvY2F0ZSBhIGxpc3Qgb2YgdHlwZXMuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFGcmVlVHlwZUxpbmtMaXN0KHhtbFNjaGVtYVR5cGVMaW5rUHRyIGxpbmspCnsKICAgIHhtbFNjaGVtYVR5cGVMaW5rUHRyIG5leHQ7CgogICAgd2hpbGUgKGxpbmsgIT0gTlVMTCkgewoJbmV4dCA9IGxpbmstPm5leHQ7Cgl4bWxGcmVlKGxpbmspOwoJbGluayA9IG5leHQ7CiAgICB9ICAgIAp9CgovKioKICogeG1sU2NoZW1hRnJlZUVsZW1lbnQ6CiAqIEBzY2hlbWE6ICBhIHNjaGVtYSBlbGVtZW50IHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGEgU2NoZW1hIEVsZW1lbnQgc3RydWN0dXJlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUVsZW1lbnQoeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtKQp7CiAgICBpZiAoZWxlbSA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChlbGVtLT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVBbm5vdChlbGVtLT5hbm5vdCk7CiAgICBpZiAoZWxlbS0+Y29udE1vZGVsICE9IE5VTEwpCiAgICAgICAgeG1sUmVnRnJlZVJlZ2V4cChlbGVtLT5jb250TW9kZWwpOwogICAgeG1sRnJlZShlbGVtKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWVGYWNldDoKICogQGZhY2V0OiAgYSBzY2hlbWEgZmFjZXQgc3RydWN0dXJlCiAqCiAqIERlYWxsb2NhdGUgYSBTY2hlbWEgRmFjZXQgc3RydWN0dXJlLgogKi8Kdm9pZAp4bWxTY2hlbWFGcmVlRmFjZXQoeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQpCnsKICAgIGlmIChmYWNldCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChmYWNldC0+dmFsICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZVZhbHVlKGZhY2V0LT52YWwpOwogICAgaWYgKGZhY2V0LT5yZWdleHAgIT0gTlVMTCkKICAgICAgICB4bWxSZWdGcmVlUmVnZXhwKGZhY2V0LT5yZWdleHApOwogICAgaWYgKGZhY2V0LT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVBbm5vdChmYWNldC0+YW5ub3QpOwogICAgeG1sRnJlZShmYWNldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlVHlwZToKICogQHR5cGU6ICBhIHNjaGVtYSB0eXBlIHN0cnVjdHVyZQogKgogKiBEZWFsbG9jYXRlIGEgU2NoZW1hIFR5cGUgc3RydWN0dXJlLgogKi8Kdm9pZAp4bWxTY2hlbWFGcmVlVHlwZSh4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKHR5cGUtPmFubm90ICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZUFubm90KHR5cGUtPmFubm90KTsKICAgIGlmICh0eXBlLT5mYWNldHMgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0LCBuZXh0OwoKICAgICAgICBmYWNldCA9IHR5cGUtPmZhY2V0czsKICAgICAgICB3aGlsZSAoZmFjZXQgIT0gTlVMTCkgewogICAgICAgICAgICBuZXh0ID0gZmFjZXQtPm5leHQ7CiAgICAgICAgICAgIHhtbFNjaGVtYUZyZWVGYWNldChmYWNldCk7CiAgICAgICAgICAgIGZhY2V0ID0gbmV4dDsKICAgICAgICB9CiAgICB9CiAgICBpZiAodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpIHsKCWlmICh0eXBlLT5hdHRyaWJ1dGVVc2VzICE9IE5VTEwpCgkgICAgeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVVzZUxpc3QodHlwZS0+YXR0cmlidXRlVXNlcyk7CgkvKiBUT0RPOiBUaGVyZSBtdXN0IGJlIGEgd2F5IG1vcmUgc2ltcGxlIHRoYW4gdGhpcy4gKi8KCWlmICgodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgJiYgCgkgICAgKCh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSB8fAoJICAgICgodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgJiYgCgkgICAgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9PV05FRF9BVFRSX1dJTERDQVJEKSkpKSB7IAoJICAgIHhtbFNjaGVtYUZyZWVXaWxkY2FyZCh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCk7Cgl9CiAgICB9CiAgICBpZiAodHlwZS0+bWVtYmVyVHlwZXMgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVUeXBlTGlua0xpc3QodHlwZS0+bWVtYmVyVHlwZXMpOwogICAgaWYgKHR5cGUtPmZhY2V0U2V0ICE9IE5VTEwpIHsKCXhtbFNjaGVtYUZhY2V0TGlua1B0ciBuZXh0LCBsaW5rOwoKCWxpbmsgPSB0eXBlLT5mYWNldFNldDsKCWRvIHsKCSAgICBuZXh0ID0gbGluay0+bmV4dDsKCSAgICB4bWxGcmVlKGxpbmspOwoJICAgIGxpbmsgPSBuZXh0OwoJfSB3aGlsZSAobGluayAhPSBOVUxMKTsKICAgIH0gICAgICAKICAgIHhtbEZyZWUodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlVHlwZUxpc3Q6CiAqIEB0eXBlOiAgYSBzY2hlbWEgdHlwZSBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIFNjaGVtYSBUeXBlIHN0cnVjdHVyZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUZyZWVUeXBlTGlzdCh4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgbmV4dDsKCiAgICB3aGlsZSAodHlwZSAhPSBOVUxMKSB7CiAgICAgICAgbmV4dCA9IHR5cGUtPnJlZGVmOwoJeG1sU2NoZW1hRnJlZVR5cGUodHlwZSk7Cgl0eXBlID0gbmV4dDsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYUZyZWU6CiAqIEBzY2hlbWE6ICBhIHNjaGVtYSBzdHJ1Y3R1cmUKICoKICogRGVhbGxvY2F0ZSBhIFNjaGVtYSBzdHJ1Y3R1cmUuCiAqLwp2b2lkCnhtbFNjaGVtYUZyZWUoeG1sU2NoZW1hUHRyIHNjaGVtYSkKewogICAgaWYgKHNjaGVtYSA9PSBOVUxMKQogICAgICAgIHJldHVybjsKCiAgICBpZiAoc2NoZW1hLT5ub3RhRGVjbCAhPSBOVUxMKQogICAgICAgIHhtbEhhc2hGcmVlKHNjaGVtYS0+bm90YURlY2wsCiAgICAgICAgICAgICAgICAgICAgKHhtbEhhc2hEZWFsbG9jYXRvcikgeG1sU2NoZW1hRnJlZU5vdGF0aW9uKTsKICAgIGlmIChzY2hlbWEtPmF0dHJEZWNsICE9IE5VTEwpCiAgICAgICAgeG1sSGFzaEZyZWUoc2NoZW1hLT5hdHRyRGVjbCwKICAgICAgICAgICAgICAgICAgICAoeG1sSGFzaERlYWxsb2NhdG9yKSB4bWxTY2hlbWFGcmVlQXR0cmlidXRlKTsKICAgIGlmIChzY2hlbWEtPmF0dHJncnBEZWNsICE9IE5VTEwpCiAgICAgICAgeG1sSGFzaEZyZWUoc2NoZW1hLT5hdHRyZ3JwRGVjbCwKICAgICAgICAgICAgICAgICAgICAoeG1sSGFzaERlYWxsb2NhdG9yKSB4bWxTY2hlbWFGcmVlQXR0cmlidXRlR3JvdXApOwogICAgaWYgKHNjaGVtYS0+ZWxlbURlY2wgIT0gTlVMTCkKICAgICAgICB4bWxIYXNoRnJlZShzY2hlbWEtPmVsZW1EZWNsLAogICAgICAgICAgICAgICAgICAgICh4bWxIYXNoRGVhbGxvY2F0b3IpIHhtbFNjaGVtYUZyZWVFbGVtZW50KTsKICAgIGlmIChzY2hlbWEtPnR5cGVEZWNsICE9IE5VTEwpCiAgICAgICAgeG1sSGFzaEZyZWUoc2NoZW1hLT50eXBlRGVjbCwKICAgICAgICAgICAgICAgICAgICAoeG1sSGFzaERlYWxsb2NhdG9yKSB4bWxTY2hlbWFGcmVlVHlwZUxpc3QpOwogICAgaWYgKHNjaGVtYS0+Z3JvdXBEZWNsICE9IE5VTEwpCiAgICAgICAgeG1sSGFzaEZyZWUoc2NoZW1hLT5ncm91cERlY2wsCiAgICAgICAgICAgICAgICAgICAgKHhtbEhhc2hEZWFsbG9jYXRvcikgeG1sU2NoZW1hRnJlZVR5cGUpOwogICAgaWYgKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMgIT0gTlVMTCkKCXhtbEhhc2hGcmVlKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsCgkJICAgICh4bWxIYXNoRGVhbGxvY2F0b3IpIHhtbFNjaGVtYUZyZWVJbXBvcnQpOwogICAgaWYgKHNjaGVtYS0+aW5jbHVkZXMgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYUZyZWVJbmNsdWRlTGlzdCgoeG1sU2NoZW1hSW5jbHVkZVB0cikgc2NoZW1hLT5pbmNsdWRlcyk7CiAgICB9CiAgICBpZiAoc2NoZW1hLT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUZyZWVBbm5vdChzY2hlbWEtPmFubm90KTsKICAgIGlmIChzY2hlbWEtPmRvYyAhPSBOVUxMICYmICFzY2hlbWEtPnByZXNlcnZlKQogICAgICAgIHhtbEZyZWVEb2Moc2NoZW1hLT5kb2MpOwogICAgeG1sRGljdEZyZWUoc2NoZW1hLT5kaWN0KTsKCiAgICB4bWxGcmVlKHNjaGVtYSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlEZWJ1ZyBmdW5jdGlvbnMJCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2lmZGVmIExJQlhNTF9PVVRQVVRfRU5BQkxFRAoKLyoqCiAqIHhtbFNjaGVtYUVsZW1lbnREdW1wOgogKiBAZWxlbTogIGFuIGVsZW1lbnQKICogQG91dHB1dDogIHRoZSBmaWxlIG91dHB1dAogKgogKiBEdW1wIHRoZSBlbGVtZW50CiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFFbGVtZW50RHVtcCh4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW0sIEZJTEUgKiBvdXRwdXQsCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lIEFUVFJJQlVURV9VTlVTRUQsCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBjb250ZXh0IEFUVFJJQlVURV9VTlVTRUQsCiAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lc3BhY2UgQVRUUklCVVRFX1VOVVNFRCkKewogICAgaWYgKGVsZW0gPT0gTlVMTCkKICAgICAgICByZXR1cm47CgogICAgZnByaW50ZihvdXRwdXQsICJFbGVtZW50ICIpOwogICAgaWYgKGVsZW0tPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9HTE9CQUwpCiAgICAgICAgZnByaW50ZihvdXRwdXQsICJnbG9iYWwgIik7CiAgICBmcHJpbnRmKG91dHB1dCwgIjogJXMgIiwgZWxlbS0+bmFtZSk7CiAgICBpZiAobmFtZXNwYWNlICE9IE5VTEwpCiAgICAgICAgZnByaW50ZihvdXRwdXQsICJuYW1lc3BhY2UgJyVzJyAiLCBuYW1lc3BhY2UpOwoKICAgIGlmIChlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fTklMTEFCTEUpCiAgICAgICAgZnByaW50ZihvdXRwdXQsICJuaWxsYWJsZSAiKTsKICAgIGlmIChlbGVtLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fREVGQVVMVCkKICAgICAgICBmcHJpbnRmKG91dHB1dCwgImRlZmF1bHQgIik7CiAgICBpZiAoZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0ZJWEVEKQogICAgICAgIGZwcmludGYob3V0cHV0LCAiZml4ZWQgIik7CiAgICBpZiAoZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX0FCU1RSQUNUKQogICAgICAgIGZwcmludGYob3V0cHV0LCAiYWJzdHJhY3QgIik7CiAgICBpZiAoZWxlbS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19FTEVNX1JFRikKICAgICAgICBmcHJpbnRmKG91dHB1dCwgInJlZiAnJXMnICIsIGVsZW0tPnJlZik7CiAgICBpZiAoZWxlbS0+aWQgIT0gTlVMTCkKICAgICAgICBmcHJpbnRmKG91dHB1dCwgImlkICclcycgIiwgZWxlbS0+aWQpOwogICAgZnByaW50ZihvdXRwdXQsICJcbiIpOwogICAgaWYgKChlbGVtLT5taW5PY2N1cnMgIT0gMSkgfHwgKGVsZW0tPm1heE9jY3VycyAhPSAxKSkgewogICAgICAgIGZwcmludGYob3V0cHV0LCAiICAiKTsKICAgICAgICBpZiAoZWxlbS0+bWluT2NjdXJzICE9IDEpCiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAibWluOiAlZCAiLCBlbGVtLT5taW5PY2N1cnMpOwogICAgICAgIGlmIChlbGVtLT5tYXhPY2N1cnMgPj0gVU5CT1VOREVEKQogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIm1heDogdW5ib3VuZGVkXG4iKTsKICAgICAgICBlbHNlIGlmIChlbGVtLT5tYXhPY2N1cnMgIT0gMSkKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJtYXg6ICVkXG4iLCBlbGVtLT5tYXhPY2N1cnMpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJcbiIpOwogICAgfQogICAgaWYgKGVsZW0tPm5hbWVkVHlwZSAhPSBOVUxMKSB7CiAgICAgICAgZnByaW50ZihvdXRwdXQsICIgIHR5cGU6ICVzIiwgZWxlbS0+bmFtZWRUeXBlKTsKICAgICAgICBpZiAoZWxlbS0+bmFtZWRUeXBlTnMgIT0gTlVMTCkKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICIgbnMgJXNcbiIsIGVsZW0tPm5hbWVkVHlwZU5zKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIH0KICAgIGlmIChlbGVtLT5zdWJzdEdyb3VwICE9IE5VTEwpIHsKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIiAgc3Vic3RpdHV0aW9uR3JvdXA6ICVzIiwgZWxlbS0+c3Vic3RHcm91cCk7CiAgICAgICAgaWYgKGVsZW0tPnN1YnN0R3JvdXBOcyAhPSBOVUxMKQogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIiBucyAlc1xuIiwgZWxlbS0+c3Vic3RHcm91cE5zKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIH0KICAgIGlmIChlbGVtLT52YWx1ZSAhPSBOVUxMKQogICAgICAgIGZwcmludGYob3V0cHV0LCAiICBkZWZhdWx0OiAlcyIsIGVsZW0tPnZhbHVlKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFubm90RHVtcDoKICogQG91dHB1dDogIHRoZSBmaWxlIG91dHB1dAogKiBAYW5ub3Q6ICBhIGFubm90YXRpb24KICoKICogRHVtcCB0aGUgYW5ub3RhdGlvbgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQW5ub3REdW1wKEZJTEUgKiBvdXRwdXQsIHhtbFNjaGVtYUFubm90UHRyIGFubm90KQp7CiAgICB4bWxDaGFyICpjb250ZW50OwoKICAgIGlmIChhbm5vdCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKCiAgICBjb250ZW50ID0geG1sTm9kZUdldENvbnRlbnQoYW5ub3QtPmNvbnRlbnQpOwogICAgaWYgKGNvbnRlbnQgIT0gTlVMTCkgewogICAgICAgIGZwcmludGYob3V0cHV0LCAiICBBbm5vdDogJXNcbiIsIGNvbnRlbnQpOwogICAgICAgIHhtbEZyZWUoY29udGVudCk7CiAgICB9IGVsc2UKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIiAgQW5ub3Q6IGVtcHR5XG4iKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVR5cGVEdW1wOgogKiBAb3V0cHV0OiAgdGhlIGZpbGUgb3V0cHV0CiAqIEB0eXBlOiAgYSB0eXBlIHN0cnVjdHVyZQogKgogKiBEdW1wIGEgU2NoZW1hVHlwZSBzdHJ1Y3R1cmUKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVR5cGVEdW1wKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgRklMRSAqIG91dHB1dCkKewogICAgaWYgKHR5cGUgPT0gTlVMTCkgewogICAgICAgIGZwcmludGYob3V0cHV0LCAiVHlwZTogTlVMTFxuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgZnByaW50ZihvdXRwdXQsICJUeXBlOiAiKTsKICAgIGlmICh0eXBlLT5uYW1lICE9IE5VTEwpCiAgICAgICAgZnByaW50ZihvdXRwdXQsICIlcywgIiwgdHlwZS0+bmFtZSk7CiAgICBlbHNlCiAgICAgICAgZnByaW50ZihvdXRwdXQsICJubyBuYW1lIik7CiAgICBzd2l0Y2ggKHR5cGUtPnR5cGUpIHsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9CQVNJQzoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJiYXNpYyAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgInNpbXBsZSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJjb21wbGV4ICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRToKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJzZXF1ZW5jZSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgImNob2ljZSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQUxMOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgImFsbCAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfVVI6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAidXIgIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1JFU1RSSUNUSU9OOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgInJlc3RyaWN0aW9uICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9FWFRFTlNJT046CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiZXh0ZW5zaW9uICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgInVua25vd250eXBlJWQgIiwgdHlwZS0+dHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgaWYgKHR5cGUtPmJhc2UgIT0gTlVMTCkgewogICAgICAgIGZwcmludGYob3V0cHV0LCAiYmFzZSAlcywgIiwgdHlwZS0+YmFzZSk7CiAgICB9CiAgICBzd2l0Y2ggKHR5cGUtPmNvbnRlbnRUeXBlKSB7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTjoKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJ1bmtub3duICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWToKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJlbXB0eSAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiZWxlbWVudCAiKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQ6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAibWl4ZWQgIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX01JWEVEX09SX0VMRU1FTlRTOgoJLyogbm90IHVzZWQuICovCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0JBU0lDOgogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgImJhc2ljICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAic2ltcGxlICIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9BTlk6CiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiYW55ICIpOwogICAgICAgICAgICBicmVhazsKICAgIH0KICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIGlmICgodHlwZS0+bWluT2NjdXJzICE9IDEpIHx8ICh0eXBlLT5tYXhPY2N1cnMgIT0gMSkpIHsKICAgICAgICBmcHJpbnRmKG91dHB1dCwgIiAgIik7CiAgICAgICAgaWYgKHR5cGUtPm1pbk9jY3VycyAhPSAxKQogICAgICAgICAgICBmcHJpbnRmKG91dHB1dCwgIm1pbjogJWQgIiwgdHlwZS0+bWluT2NjdXJzKTsKICAgICAgICBpZiAodHlwZS0+bWF4T2NjdXJzID49IFVOQk9VTkRFRCkKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICJtYXg6IHVuYm91bmRlZFxuIik7CiAgICAgICAgZWxzZSBpZiAodHlwZS0+bWF4T2NjdXJzICE9IDEpCiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAibWF4OiAlZFxuIiwgdHlwZS0+bWF4T2NjdXJzKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIH0KICAgIGlmICh0eXBlLT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUFubm90RHVtcChvdXRwdXQsIHR5cGUtPmFubm90KTsKICAgIGlmICh0eXBlLT5zdWJ0eXBlcyAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciBzdWIgPSB0eXBlLT5zdWJ0eXBlczsKCiAgICAgICAgZnByaW50ZihvdXRwdXQsICIgIHN1YnR5cGVzOiAiKTsKICAgICAgICB3aGlsZSAoc3ViICE9IE5VTEwpIHsKICAgICAgICAgICAgZnByaW50ZihvdXRwdXQsICIlcyAiLCBzdWItPm5hbWUpOwogICAgICAgICAgICBzdWIgPSBzdWItPm5leHQ7CiAgICAgICAgfQogICAgICAgIGZwcmludGYob3V0cHV0LCAiXG4iKTsKICAgIH0KCn0KCi8qKgogKiB4bWxTY2hlbWFEdW1wOgogKiBAb3V0cHV0OiAgdGhlIGZpbGUgb3V0cHV0CiAqIEBzY2hlbWE6ICBhIHNjaGVtYSBzdHJ1Y3R1cmUKICoKICogRHVtcCBhIFNjaGVtYSBzdHJ1Y3R1cmUuCiAqLwp2b2lkCnhtbFNjaGVtYUR1bXAoRklMRSAqIG91dHB1dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSkKewogICAgaWYgKHNjaGVtYSA9PSBOVUxMKSB7CiAgICAgICAgZnByaW50ZihvdXRwdXQsICJTY2hlbWFzOiBOVUxMXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBmcHJpbnRmKG91dHB1dCwgIlNjaGVtYXM6ICIpOwogICAgaWYgKHNjaGVtYS0+bmFtZSAhPSBOVUxMKQogICAgICAgIGZwcmludGYob3V0cHV0LCAiJXMsICIsIHNjaGVtYS0+bmFtZSk7CiAgICBlbHNlCiAgICAgICAgZnByaW50ZihvdXRwdXQsICJubyBuYW1lLCAiKTsKICAgIGlmIChzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSAhPSBOVUxMKQogICAgICAgIGZwcmludGYob3V0cHV0LCAiJXMiLCAoY29uc3QgY2hhciAqKSBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSk7CiAgICBlbHNlCiAgICAgICAgZnByaW50ZihvdXRwdXQsICJubyB0YXJnZXQgbmFtZXNwYWNlIik7CiAgICBmcHJpbnRmKG91dHB1dCwgIlxuIik7CiAgICBpZiAoc2NoZW1hLT5hbm5vdCAhPSBOVUxMKQogICAgICAgIHhtbFNjaGVtYUFubm90RHVtcChvdXRwdXQsIHNjaGVtYS0+YW5ub3QpOwoKICAgIHhtbEhhc2hTY2FuKHNjaGVtYS0+dHlwZURlY2wsICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hVHlwZUR1bXAsCiAgICAgICAgICAgICAgICBvdXRwdXQpOwogICAgeG1sSGFzaFNjYW5GdWxsKHNjaGVtYS0+ZWxlbURlY2wsCiAgICAgICAgICAgICAgICAgICAgKHhtbEhhc2hTY2FubmVyRnVsbCkgeG1sU2NoZW1hRWxlbWVudER1bXAsIG91dHB1dCk7Cn0KI2VuZGlmIC8qIExJQlhNTF9PVVRQVVRfRU5BQkxFRCAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJCQkJCQkJCSoKICogCQkJVXRpbGl0aWVzCQkJCQkqCiAqCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIHhtbEF0dHJQdHIKeG1sU2NoZW1hR2V0UHJvcE5vZGUoeG1sTm9kZVB0ciBub2RlLCBjb25zdCB4bWxDaGFyICpuYW1lKSAKewogICAgeG1sQXR0clB0ciBwcm9wOwoKICAgIGlmICgobm9kZSA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkgcmV0dXJuKE5VTEwpOwogICAgcHJvcCA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAocHJvcCAhPSBOVUxMKSB7CiAgICAgICAgaWYgKCh4bWxTdHJFcXVhbChwcm9wLT5uYW1lLCBuYW1lKSkgJiYJICAgIAoJICAgIChwcm9wLT5ucyA9PSBOVUxMKSkKCSAgICByZXR1cm4ocHJvcCk7Cglwcm9wID0gcHJvcC0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoTlVMTCk7Cn0KCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hR2V0Tm9kZUNvbnRlbnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbENoYXIgKnZhbDsKICAgIGNvbnN0IHhtbENoYXIgKnJldDsKCiAgICB2YWwgPSB4bWxOb2RlR2V0Q29udGVudChub2RlKTsKICAgIGlmICh2YWwgPT0gTlVMTCkKICAgICAgICByZXR1cm4oTlVMTCk7CiAgICByZXQgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHZhbCwgLTEpOwogICAgeG1sRnJlZSh2YWwpOwogICAgcmV0dXJuKHJldCk7ICAgIAp9CgovKioKICogeG1sU2NoZW1hR2V0UHJvcDoKICogQGN0eHQ6IHRoZSBwYXJzZXIgY29udGV4dAogKiBAbm9kZTogdGhlIG5vZGUKICogQG5hbWU6IHRoZSBwcm9wZXJ0eSBuYW1lCiAqIAogKiBSZWFkIGEgYXR0cmlidXRlIHZhbHVlIGFuZCBpbnRlcm5hbGl6ZSB0aGUgc3RyaW5nCiAqCiAqIFJldHVybnMgdGhlIHN0cmluZyBvciBOVUxMIGlmIG5vdCBwcmVzZW50LgogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFHZXRQcm9wKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLAogICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm5hbWUpCnsKICAgIHhtbENoYXIgKnZhbDsKICAgIGNvbnN0IHhtbENoYXIgKnJldDsKCiAgICB2YWwgPSB4bWxHZXRQcm9wKG5vZGUsIEJBRF9DQVNUIG5hbWUpOwogICAgaWYgKHZhbCA9PSBOVUxMKQogICAgICAgIHJldHVybihOVUxMKTsKICAgIHJldCA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgdmFsLCAtMSk7CiAgICB4bWxGcmVlKHZhbCk7CiAgICByZXR1cm4ocmV0KTsKfQoKI2lmIDAKLyoqCiAqIHhtbFNjaGVtYUdldE5hbWVzcGFjZToKICogQGN0eHQ6IHRoZSBwYXJzZXIgY29udGV4dAogKiBAc2NoZW1hOiB0aGUgc2NoZW1hcyBjb250YWluaW5nIHRoZSBkZWNsYXJhdGlvbgogKiBAbm9kZTogdGhlIG5vZGUKICogQHFuYW1lOiB0aGUgUU5hbWUgdG8gYW5hbHl6ZQogKiAKICogRmluZCB0aGUgbmFtZXNwYWNlIG5hbWUgZm9yIHRoZSBnaXZlbiBkZWNsYXJhdGlvbi4KICoKICogUmV0dXJucyB0aGUgbG9jYWwgbmFtZSBmb3IgdGhhdCBkZWNsYXJhdGlvbiwgYXMgd2VsbCBhcyB0aGUgbmFtZXNwYWNlIG5hbWUKICogTk9URTogVGhpcyBmdW5jdGlvbiBpcyBubyBsb25nZXIgdXNlZCAoQnVjaGNpaywgTWF5ICcwNCkgCiAqLwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbFNjaGVtYUdldE5hbWVzcGFjZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwgY29uc3QgeG1sQ2hhciAqcW5hbWUsCgkgICAgIGNvbnN0IHhtbENoYXIgKipuYW1lc3BhY2UpIHsKICAgIGludCBsZW47CiAgICBjb25zdCB4bWxDaGFyICpuYW1lLCAqcHJlZml4LCAqZGVmID0gTlVMTDsKICAgIHhtbE5zUHRyIG5zOwoKICAgICpuYW1lc3BhY2UgPSBOVUxMOwogICAgCiAgICAvKiBUT0RPOiBUaGUgZm9sbG93aW5nIHNlZW1zIHRvIGJlIG5vdCBjb3JyZWN0IGhlcmU6CiAgICAgKiAxLiBUaGUgbmFtZSBvZiBhIGRlY2xhcmF0aW9uIGlzIGEgTkNOYW1lLCBub3QgYSBRTmFtZS4KICAgICAqIDIuIFRoZSBhdHRyaWJ1dGUgInRhcmdldE5hbWVzcGFjZSIgaXMgYWxsb3dlZCBmb3IgdGhlCiAgICAgKiAgICA8c2NoZW1hPiBFbGVtZW50IEluZm9ybWF0aW9uIEl0ZW0gb25seS4KICAgICAqIDMuIE9uZSBjYW5ub3QgZXZhbHVhdGUgdGhlIHRhcmdldCBuYW1lc3BhY2UsIGJ5IHRoZSB0eXBlCiAgICAgKiAgICBvZiBkZWNsYXJhdGlvbiwgc2luY2UgaXQgaXMgZGVwZW5kYW50IG9uIHRoZSB4eHhGb3JtRGVmYXVsdAogICAgICogICAgb2YgPHNjaGVtYT4gYW5kIHRoZSBmb3JtIGF0dHJpYnV0ZSBvZiBhbiA8ZWxlbWVudD4gb3IgPGF0dHJpYnV0ZT4uCiAgICAgKi8KICAgCiAgICBpZiAoeG1sU3RyRXF1YWwobm9kZS0+bmFtZSwgQkFEX0NBU1QgImVsZW1lbnQiKSB8fAogICAgICAgIHhtbFN0ckVxdWFsKG5vZGUtPm5hbWUsIEJBRF9DQVNUICJhdHRyaWJ1dGUiKSB8fAoJeG1sU3RyRXF1YWwobm9kZS0+bmFtZSwgQkFEX0NBU1QgInNpbXBsZVR5cGUiKSB8fAoJeG1sU3RyRXF1YWwobm9kZS0+bmFtZSwgQkFEX0NBU1QgImNvbXBsZXhUeXBlIikpIHsKCWRlZiA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgInRhcmdldE5hbWVzcGFjZSIpOwogICAgfQoKCiAgICBxbmFtZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgcW5hbWUsIC0xKTsgLyogaW50ZXJuIHRoZSBzdHJpbmcgKi8KICAgIG5hbWUgPSB4bWxTcGxpdFFOYW1lMyhxbmFtZSwgJmxlbik7CiAgICBpZiAobmFtZSA9PSBOVUxMKSB7CiAgICAgICAgaWYgKGRlZiA9PSBOVUxMKSB7CgkgICAgaWYgKHhtbFN0ckVxdWFsKG5vZGUtPm5hbWUsIEJBRF9DQVNUICJlbGVtZW50IikpIHsKCQlpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1FVQUxJRl9FTEVNKQoJCSAgICAqbmFtZXNwYWNlID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7CgkgICAgfSBlbHNlIGlmICh4bWxTdHJFcXVhbChub2RlLT5uYW1lLCBCQURfQ0FTVCAiYXR0cmlidXRlIikpIHsKCQlpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1FVQUxJRl9BVFRSKQoJCSAgICAqbmFtZXNwYWNlID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7CgkgICAgfSBlbHNlIGlmICgoeG1sU3RyRXF1YWwobm9kZS0+bmFtZSwgQkFEX0NBU1QgInNpbXBsZVR5cGUiKSkgfHwKCSAgICAgICAgICAgICAgICh4bWxTdHJFcXVhbChub2RlLT5uYW1lLCBCQURfQ0FTVCAiY29tcGxleFR5cGUiKSkpIHsKCQkqbmFtZXNwYWNlID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7CgkgICAgfQoJfSBlbHNlIHsKCSAgICAqbmFtZXNwYWNlID0gZGVmOwoJfQoJcmV0dXJuKHFuYW1lKTsKICAgIH0KCiAgICBuYW1lID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBuYW1lLCAtMSk7CiAgICBwcmVmaXggPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHFuYW1lLCBsZW4pOwogICAgaWYgKGRlZiAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BUF9ERUZfQU5EX1BSRUZJWCwKICAgICAgICAgICAgICAgICAgICAgICIlczogcHJlc2VuY2Ugb2YgYm90aCBwcmVmaXggJXMgYW5kIHRhcmdldE5hbWVzcGFjZVxuIiwKICAgICAgICAgICAgICAgICAgICAgIG5vZGUtPm5hbWUsIHByZWZpeCk7CiAgICB9CiAgICBucyA9IHhtbFNlYXJjaE5zKG5vZGUtPmRvYywgbm9kZSwgcHJlZml4KTsKICAgIGlmIChucyA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BUF9QUkVGSVhfVU5ERUZJTkVELAogICAgICAgICAgICAgICAgICAgICAgIiVzOiB0aGUgUU5hbWUgcHJlZml4ICVzIGlzIHVuZGVmaW5lZFxuIiwKICAgICAgICAgICAgICAgICAgICAgIG5vZGUtPm5hbWUsIHByZWZpeCk7CglyZXR1cm4obmFtZSk7CiAgICB9CiAgICAqbmFtZXNwYWNlID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBucy0+aHJlZiwgLTEpOwogICAgcmV0dXJuKG5hbWUpOwp9CiNlbmRpZgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVBhcnNpbmcgZnVuY3Rpb25zCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqCiAqIHhtbFNjaGVtYUdldEVsZW06CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hcyBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIGVsZW1lbnQgbmFtZQogKiBAbnM6ICB0aGUgZWxlbWVudCBuYW1lc3BhY2UKICogQGxldmVsOiBob3cgZGVlcCBpcyB0aGUgcmVxdWVzdAogKgogKiBMb29rdXAgYSBhbiBlbGVtZW50IGluIHRoZSBzY2hlbWFzIG9yIHRoZSBhY2Nlc3NpYmxlIHNjaGVtYXMKICoKICogUmV0dXJucyB0aGUgZWxlbWVudCBkZWZpbml0aW9uIG9yIE5VTEwgaWYgbm90IGZvdW5kLgogKi8Kc3RhdGljIHhtbFNjaGVtYUVsZW1lbnRQdHIKeG1sU2NoZW1hR2V0RWxlbSh4bWxTY2hlbWFQdHIgc2NoZW1hLCBjb25zdCB4bWxDaGFyICogbmFtZSwKICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZXNwYWNlLCBpbnQgbGV2ZWwpCnsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgcmV0OwogICAgeG1sU2NoZW1hSW1wb3J0UHRyIGltcG9ydCA9IE5VTEw7CgogICAgaWYgKChuYW1lID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIAogICAgCiAgICAgICAgcmV0ID0geG1sSGFzaExvb2t1cDIoc2NoZW1hLT5lbGVtRGVjbCwgbmFtZSwgbmFtZXNwYWNlKTsKICAgICAgICBpZiAoKHJldCAhPSBOVUxMKSAmJgoJKChsZXZlbCA9PSAwKSB8fCAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fR0xPQkFMKSkpIHsKICAgICAgICAgICAgcmV0dXJuIChyZXQpOwogICAgfSBlbHNlCglyZXQgPSBOVUxMOwogICAgLyoKICAgICAqIFRoaXMgb25lIHdhcyByZW1vdmVkLCBzaW5jZSB0b3AgbGV2ZWwgZWxlbWVudCBkZWNsYXJhdGlvbnMgaGF2ZQogICAgICogdGhlIHRhcmdldCBuYW1lc3BhY2Ugc3BlY2lmaWVkIGluIHRhcmdldE5hbWVzcGFjZSBvZiB0aGUgPHNjaGVtYT4KICAgICAqIGluZm9ybWF0aW9uIGVsZW1lbnQsIGV2ZW4gaWYgZWxlbWVudEZvcm1EZWZhdWx0IGlzICJ1bnF1YWxpZmllZCIuCiAgICAgKi8KICAgIAogICAgLyogZWxzZSBpZiAoKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19RVUFMSUZfRUxFTSkgPT0gMCkgewogICAgICAgIGlmICh4bWxTdHJFcXVhbChuYW1lc3BhY2UsIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlKSkKCSAgICByZXQgPSB4bWxIYXNoTG9va3VwMihzY2hlbWEtPmVsZW1EZWNsLCBuYW1lLCBOVUxMKTsKCWVsc2UKCSAgICByZXQgPSB4bWxIYXNoTG9va3VwMihzY2hlbWEtPmVsZW1EZWNsLCBuYW1lLCBuYW1lc3BhY2UpOwogICAgICAgIGlmICgocmV0ICE9IE5VTEwpICYmCgkgICAgKChsZXZlbCA9PSAwKSB8fCAocmV0LT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fVE9QTEVWRUwpKSkgewogICAgICAgICAgICByZXR1cm4gKHJldCk7Cgl9CiAgICAqLwogICAgCiAgICAvKiBpZiAobGV2ZWwgPiAwKSAqLwogICAgaWYgKG5hbWVzcGFjZSA9PSBOVUxMKQoJaW1wb3J0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLCBYTUxfU0NIRU1BU19ERUZBVUxUX05BTUVTUEFDRSk7CiAgICBlbHNlCiAgICBpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIG5hbWVzcGFjZSk7CiAgICBpZiAoaW1wb3J0ICE9IE5VTEwpIHsKCXJldCA9IHhtbFNjaGVtYUdldEVsZW0oaW1wb3J0LT5zY2hlbWEsIG5hbWUsIG5hbWVzcGFjZSwgbGV2ZWwgKyAxKTsKCWlmICgocmV0ICE9IE5VTEwpICYmIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9HTE9CQUwpKSB7CgkgICAgcmV0dXJuIChyZXQpOwoJfSBlbHNlCgkgICAgcmV0ID0gTlVMTDsKICAgIH0KI2lmZGVmIERFQlVHCiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCB0eXBlICVzIiwgbmFtZSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgdHlwZSAlczolcyIsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlKTsKICAgIH0KI2VuZGlmCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRUeXBlOgogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYXMgY29udGV4dAogKiBAbmFtZTogIHRoZSB0eXBlIG5hbWUKICogQG5zOiAgdGhlIHR5cGUgbmFtZXNwYWNlCiAqCiAqIExvb2t1cCBhIHR5cGUgaW4gdGhlIHNjaGVtYXMgb3IgdGhlIHByZWRlZmluZWQgdHlwZXMKICoKICogUmV0dXJucyB0aGUgZ3JvdXAgZGVmaW5pdGlvbiBvciBOVUxMIGlmIG5vdCBmb3VuZC4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYUdldFR5cGUoeG1sU2NoZW1hUHRyIHNjaGVtYSwgY29uc3QgeG1sQ2hhciAqIG5hbWUsCiAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWVzcGFjZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciByZXQ7CiAgICB4bWxTY2hlbWFJbXBvcnRQdHIgaW1wb3J0OwoKICAgIGlmIChuYW1lID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIGlmIChzY2hlbWEgIT0gTlVMTCkgewogICAgICAgIHJldCA9IHhtbEhhc2hMb29rdXAyKHNjaGVtYS0+dHlwZURlY2wsIG5hbWUsIG5hbWVzcGFjZSk7CiAgICAgICAgaWYgKChyZXQgIT0gTlVMTCkgJiYgKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTCkpCiAgICAgICAgICAgIHJldHVybiAocmV0KTsKICAgIH0KICAgIHJldCA9IHhtbFNjaGVtYUdldFByZWRlZmluZWRUeXBlKG5hbWUsIG5hbWVzcGFjZSk7CiAgICBpZiAocmV0ICE9IE5VTEwpCglyZXR1cm4gKHJldCk7CiAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCglpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIFhNTF9TQ0hFTUFTX0RFRkFVTFRfTkFNRVNQQUNFKTsKICAgIGVsc2UKICAgIGltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgbmFtZXNwYWNlKTsKICAgIGlmIChpbXBvcnQgIT0gTlVMTCkgewoJcmV0ID0geG1sU2NoZW1hR2V0VHlwZShpbXBvcnQtPnNjaGVtYSwgbmFtZSwgbmFtZXNwYWNlKTsKCWlmICgocmV0ICE9IE5VTEwpICYmIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUwpKSB7CgkgICAgcmV0dXJuIChyZXQpOwoJfSBlbHNlCgkgICAgcmV0ID0gTlVMTDsKICAgIH0KI2lmZGVmIERFQlVHCiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCB0eXBlICVzIiwgbmFtZSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgdHlwZSAlczolcyIsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlKTsKICAgIH0KI2VuZGlmCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRBdHRyaWJ1dGU6CiAqIEBzY2hlbWE6ICB0aGUgY29udGV4dCBvZiB0aGUgc2NoZW1hIAogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBhdHRyaWJ1dGUKICogQG5zOiAgdGhlIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhlIGF0dHJpYnV0ZSAKICoKICogTG9va3VwIGEgYW4gYXR0cmlidXRlIGluIHRoZSBzY2hlbWEgb3IgaW1wb3J0ZWQgc2NoZW1hcwogKgogKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gb3IgTlVMTCBpZiBub3QgZm91bmQuCiAqLwpzdGF0aWMgeG1sU2NoZW1hQXR0cmlidXRlUHRyCnhtbFNjaGVtYUdldEF0dHJpYnV0ZSh4bWxTY2hlbWFQdHIgc2NoZW1hLCBjb25zdCB4bWxDaGFyICogbmFtZSwKICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZXNwYWNlKQp7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgcmV0OwogICAgeG1sU2NoZW1hSW1wb3J0UHRyIGltcG9ydCA9IE5VTEw7CgogICAgaWYgKChuYW1lID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIAogICAgCiAgICByZXQgPSB4bWxIYXNoTG9va3VwMihzY2hlbWEtPmF0dHJEZWNsLCBuYW1lLCBuYW1lc3BhY2UpOwogICAgaWYgKChyZXQgIT0gTlVMTCkgJiYgKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX0dMT0JBTCkpCglyZXR1cm4gKHJldCk7IAogICAgZWxzZQoJcmV0ID0gTlVMTDsKICAgIGlmIChuYW1lc3BhY2UgPT0gTlVMTCkKCWltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgWE1MX1NDSEVNQVNfREVGQVVMVF9OQU1FU1BBQ0UpOwogICAgZWxzZQoJaW1wb3J0ID0geG1sSGFzaExvb2t1cChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLCBuYW1lc3BhY2UpOwkKICAgIGlmIChpbXBvcnQgIT0gTlVMTCkgewoJcmV0ID0geG1sU2NoZW1hR2V0QXR0cmlidXRlKGltcG9ydC0+c2NoZW1hLCBuYW1lLCBuYW1lc3BhY2UpOwoJaWYgKChyZXQgIT0gTlVMTCkgJiYgKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSX0dMT0JBTCkpIHsKCSAgICByZXR1cm4gKHJldCk7Cgl9IGVsc2UKCSAgICByZXQgPSBOVUxMOwogICAgfQojaWZkZWYgREVCVUcKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIGlmIChuYW1lc3BhY2UgPT0gTlVMTCkKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIGF0dHJpYnV0ZSAlcyIsIG5hbWUpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmFibGUgdG8gbG9va3VwIGF0dHJpYnV0ZSAlczolcyIsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlKTsKICAgIH0KI2VuZGlmCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFHZXRBdHRyaWJ1dGVHcm91cDoKICogQHNjaGVtYTogIHRoZSBjb250ZXh0IG9mIHRoZSBzY2hlbWEgCiAqIEBuYW1lOiAgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZSBncm91cAogKiBAbnM6ICB0aGUgdGFyZ2V0IG5hbWVzcGFjZSBvZiB0aGUgYXR0cmlidXRlIGdyb3VwIAogKgogKiBMb29rdXAgYSBhbiBhdHRyaWJ1dGUgZ3JvdXAgaW4gdGhlIHNjaGVtYSBvciBpbXBvcnRlZCBzY2hlbWFzCiAqCiAqIFJldHVybnMgdGhlIGF0dHJpYnV0ZSBncm91cCBkZWZpbml0aW9uIG9yIE5VTEwgaWYgbm90IGZvdW5kLgogKi8Kc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyCnhtbFNjaGVtYUdldEF0dHJpYnV0ZUdyb3VwKHhtbFNjaGVtYVB0ciBzY2hlbWEsIGNvbnN0IHhtbENoYXIgKiBuYW1lLAogICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lc3BhY2UpCnsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyIHJldDsKICAgIHhtbFNjaGVtYUltcG9ydFB0ciBpbXBvcnQgPSBOVUxMOwoKICAgIGlmICgobmFtZSA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAKICAgIAogICAgcmV0ID0geG1sSGFzaExvb2t1cDIoc2NoZW1hLT5hdHRyZ3JwRGVjbCwgbmFtZSwgbmFtZXNwYWNlKTsKICAgIGlmICgocmV0ICE9IE5VTEwpICYmIChyZXQtPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUkdST1VQX0dMT0JBTCkpCglyZXR1cm4gKHJldCk7ICAKICAgIGVsc2UKCXJldCA9IE5VTEw7CiAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCglpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIFhNTF9TQ0hFTUFTX0RFRkFVTFRfTkFNRVNQQUNFKTsKICAgIGVsc2UKCWltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgbmFtZXNwYWNlKTsJCiAgICBpZiAoaW1wb3J0ICE9IE5VTEwpIHsKCXJldCA9IHhtbFNjaGVtYUdldEF0dHJpYnV0ZUdyb3VwKGltcG9ydC0+c2NoZW1hLCBuYW1lLCBuYW1lc3BhY2UpOwoJaWYgKChyZXQgIT0gTlVMTCkgJiYgKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19BVFRSR1JPVVBfR0xPQkFMKSkKCSAgICByZXR1cm4gKHJldCk7CgllbHNlCgkgICAgcmV0ID0gTlVMTDsKICAgIH0KI2lmZGVmIERFQlVHCiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCBhdHRyaWJ1dGUgZ3JvdXAgJXMiLCBuYW1lKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCBhdHRyaWJ1dGUgZ3JvdXAgJXM6JXMiLCBuYW1lLAogICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSk7CiAgICB9CiNlbmRpZgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hR2V0R3JvdXA6CiAqIEBzY2hlbWE6ICB0aGUgY29udGV4dCBvZiB0aGUgc2NoZW1hIAogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBncm91cAogKiBAbnM6ICB0aGUgdGFyZ2V0IG5hbWVzcGFjZSBvZiB0aGUgZ3JvdXAgCiAqCiAqIExvb2t1cCBhIGdyb3VwIGluIHRoZSBzY2hlbWEgb3IgaW1wb3J0ZWQgc2NoZW1hcwogKgogKiBSZXR1cm5zIHRoZSBncm91cCBkZWZpbml0aW9uIG9yIE5VTEwgaWYgbm90IGZvdW5kLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hR2V0R3JvdXAoeG1sU2NoZW1hUHRyIHNjaGVtYSwgY29uc3QgeG1sQ2hhciAqIG5hbWUsCiAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWVzcGFjZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciByZXQ7CiAgICB4bWxTY2hlbWFJbXBvcnRQdHIgaW1wb3J0ID0gTlVMTDsKCiAgICBpZiAoKG5hbWUgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgCiAgICAKICAgIHJldCA9IHhtbEhhc2hMb29rdXAyKHNjaGVtYS0+Z3JvdXBEZWNsLCBuYW1lLCBuYW1lc3BhY2UpOwogICAgaWYgKChyZXQgIT0gTlVMTCkgJiYgKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTCkpCglyZXR1cm4gKHJldCk7ICAKICAgIGVsc2UKCXJldCA9IE5VTEw7CiAgICBpZiAobmFtZXNwYWNlID09IE5VTEwpCglpbXBvcnQgPSB4bWxIYXNoTG9va3VwKHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsIFhNTF9TQ0hFTUFTX0RFRkFVTFRfTkFNRVNQQUNFKTsKICAgIGVsc2UKCWltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgbmFtZXNwYWNlKTsJCiAgICBpZiAoaW1wb3J0ICE9IE5VTEwpIHsKCXJldCA9IHhtbFNjaGVtYUdldEdyb3VwKGltcG9ydC0+c2NoZW1hLCBuYW1lLCBuYW1lc3BhY2UpOwoJaWYgKChyZXQgIT0gTlVMTCkgJiYgKHJldC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTCkpCgkgICAgcmV0dXJuIChyZXQpOwoJZWxzZQoJICAgIHJldCA9IE5VTEw7CiAgICB9CiNpZmRlZiBERUJVRwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgaWYgKG5hbWVzcGFjZSA9PSBOVUxMKQogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVuYWJsZSB0byBsb29rdXAgZ3JvdXAgJXMiLCBuYW1lKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5hYmxlIHRvIGxvb2t1cCBncm91cCAlczolcyIsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlKTsKICAgIH0KI2VuZGlmCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlQYXJzaW5nIGZ1bmN0aW9ucwkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNkZWZpbmUgSVNfQkxBTktfTk9ERShuKQkJCQkJCVwKICAgICgoKG4pLT50eXBlID09IFhNTF9URVhUX05PREUpICYmICh4bWxTY2hlbWFJc0JsYW5rKChuKS0+Y29udGVudCkpKQoKLyoqCiAqIHhtbFNjaGVtYUlzQmxhbms6CiAqIEBzdHI6ICBhIHN0cmluZwogKgogKiBDaGVjayBpZiBhIHN0cmluZyBpcyBpZ25vcmFibGUKICoKICogUmV0dXJucyAxIGlmIHRoZSBzdHJpbmcgaXMgTlVMTCBvciBtYWRlIG9mIGJsYW5rcyBjaGFycywgMCBvdGhlcndpc2UKICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hSXNCbGFuayh4bWxDaGFyICogc3RyKQp7CiAgICBpZiAoc3RyID09IE5VTEwpCiAgICAgICAgcmV0dXJuICgxKTsKICAgIHdoaWxlICgqc3RyICE9IDApIHsKICAgICAgICBpZiAoIShJU19CTEFOS19DSCgqc3RyKSkpCiAgICAgICAgICAgIHJldHVybiAoMCk7CiAgICAgICAgc3RyKys7CiAgICB9CiAgICByZXR1cm4gKDEpOwp9CgovKioKICogeG1sU2NoZW1hQWRkTm90YXRpb246CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBuYW1lOiAgdGhlIGl0ZW0gbmFtZQogKgogKiBBZGQgYW4gWE1MIHNjaGVtYSBBdHRycmlidXRlIGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgbmV3IHN0cnV0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYU5vdGF0aW9uUHRyCnhtbFNjaGVtYUFkZE5vdGF0aW9uKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUpCnsKICAgIHhtbFNjaGVtYU5vdGF0aW9uUHRyIHJldCA9IE5VTEw7CiAgICBpbnQgdmFsOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChuYW1lID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgaWYgKHNjaGVtYS0+bm90YURlY2wgPT0gTlVMTCkKICAgICAgICBzY2hlbWEtPm5vdGFEZWNsID0geG1sSGFzaENyZWF0ZSgxMCk7CiAgICBpZiAoc2NoZW1hLT5ub3RhRGVjbCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYU5vdGF0aW9uUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYU5vdGF0aW9uKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhZGQgYW5ub3RhdGlvbiIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hTm90YXRpb24pKTsKICAgIHJldC0+bmFtZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbmFtZSwgLTEpOwogICAgdmFsID0geG1sSGFzaEFkZEVudHJ5MihzY2hlbWEtPm5vdGFEZWNsLCBuYW1lLCBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0KTsKICAgIGlmICh2YWwgIT0gMCkgewoJeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgY3R4dC0+ZG9jLAoJCSAgICAgIFhNTF9TQ0hFTUFQX1JFREVGSU5FRF9OT1RBVElPTiwKICAgICAgICAgICAgICAgICAgICAgICJOb3RhdGlvbiAlcyBhbHJlYWR5IGRlZmluZWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICBuYW1lLCBOVUxMKTsKICAgICAgICB4bWxGcmVlKHJldCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKCi8qKgogKiB4bWxTY2hlbWFBZGRBdHRyaWJ1dGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBuYW1lOiAgdGhlIGl0ZW0gbmFtZQogKiBAbmFtZXNwYWNlOiAgdGhlIG5hbWVzcGFjZQogKgogKiBBZGQgYW4gWE1MIHNjaGVtYSBBdHRycmlidXRlIGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgbmV3IHN0cnV0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZVB0cgp4bWxTY2hlbWFBZGRBdHRyaWJ1dGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUsIGNvbnN0IHhtbENoYXIgKiBuYW1lc3BhY2UpCnsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciByZXQgPSBOVUxMOwogICAgaW50IHZhbDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKI2lmZGVmIERFQlVHCiAgICBmcHJpbnRmKHN0ZGVyciwgIkFkZGluZyBhdHRyaWJ1dGUgJXNcbiIsIG5hbWUpOwogICAgaWYgKG5hbWVzcGFjZSAhPSBOVUxMKQoJZnByaW50ZihzdGRlcnIsICIgIHRhcmdldCBuYW1lc3BhY2UgJXNcbiIsIG5hbWVzcGFjZSk7CiNlbmRpZgoKICAgIGlmIChzY2hlbWEtPmF0dHJEZWNsID09IE5VTEwpCiAgICAgICAgc2NoZW1hLT5hdHRyRGVjbCA9IHhtbEhhc2hDcmVhdGUoMTApOwogICAgaWYgKHNjaGVtYS0+YXR0ckRlY2wgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hQXR0cmlidXRlKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIGF0dHJpYnV0ZSIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hQXR0cmlidXRlKSk7CiAgICByZXQtPm5hbWUgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5hbWUsIC0xKTsKICAgIHJldC0+dGFyZ2V0TmFtZXNwYWNlID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBuYW1lc3BhY2UsIC0xKTsKICAgIHZhbCA9IHhtbEhhc2hBZGRFbnRyeTMoc2NoZW1hLT5hdHRyRGVjbCwgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UsIGN0eHQtPmNvbnRhaW5lciwgcmV0KTsKICAgIGlmICh2YWwgIT0gMCkgewoJeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgY3R4dC0+ZG9jLAoJCSAgICAgIFhNTF9TQ0hFTUFQX1JFREVGSU5FRF9BVFRSLAogICAgICAgICAgICAgICAgICAgICAgIkF0dHJpYnV0ZSAlcyBhbHJlYWR5IGRlZmluZWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICBuYW1lLCBOVUxMKTsKICAgICAgICB4bWxGcmVlKHJldCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZEF0dHJpYnV0ZUdyb3VwOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSBpdGVtIG5hbWUKICoKICogQWRkIGFuIFhNTCBzY2hlbWEgQXR0cnJpYnV0ZSBHcm91cCBkZWNsYXJhdGlvbgogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIKeG1sU2NoZW1hQWRkQXR0cmlidXRlR3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLCBjb25zdCB4bWxDaGFyICogbmFtZSkKewogICAgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgcmV0ID0gTlVMTDsKICAgIGludCB2YWw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBpZiAoc2NoZW1hLT5hdHRyZ3JwRGVjbCA9PSBOVUxMKQogICAgICAgIHNjaGVtYS0+YXR0cmdycERlY2wgPSB4bWxIYXNoQ3JlYXRlKDEwKTsKICAgIGlmIChzY2hlbWEtPmF0dHJncnBEZWNsID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPQogICAgICAgICh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cikKICAgICAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIGF0dHJpYnV0ZSBncm91cCIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXApKTsKICAgIHJldC0+bmFtZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbmFtZSwgLTEpOwogICAgdmFsID0geG1sSGFzaEFkZEVudHJ5MyhzY2hlbWEtPmF0dHJncnBEZWNsLCBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSwgY3R4dC0+Y29udGFpbmVyLCByZXQpOwogICAgaWYgKHZhbCAhPSAwKSB7Cgl4bWxTY2hlbWFQRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBjdHh0LT5kb2MsCgkJICAgICAgWE1MX1NDSEVNQVBfUkVERUZJTkVEX0FUVFJHUk9VUCwKICAgICAgICAgICAgICAgICAgICAgICJBdHRyaWJ1dGUgZ3JvdXAgJXMgYWxyZWFkeSBkZWZpbmVkXG4iLAogICAgICAgICAgICAgICAgICAgICAgbmFtZSwgTlVMTCk7CiAgICAgICAgeG1sRnJlZShyZXQpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBZGRFbGVtZW50OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSB0eXBlIG5hbWUKICogQG5hbWVzcGFjZTogIHRoZSB0eXBlIG5hbWVzcGFjZQogKgogKiBBZGQgYW4gWE1MIHNjaGVtYSBFbGVtZW50IGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgbmV3IHN0cnV0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYUVsZW1lbnRQdHIKeG1sU2NoZW1hQWRkRWxlbWVudCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUsIGNvbnN0IHhtbENoYXIgKiBuYW1lc3BhY2UpCnsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgcmV0ID0gTlVMTDsKICAgIGludCB2YWw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5hbWUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiNpZmRlZiBERUJVRwogICAgZnByaW50ZihzdGRlcnIsICJBZGRpbmcgZWxlbWVudCAlc1xuIiwgbmFtZSk7CiAgICBpZiAobmFtZXNwYWNlICE9IE5VTEwpCglmcHJpbnRmKHN0ZGVyciwgIiAgdGFyZ2V0IG5hbWVzcGFjZSAlc1xuIiwgbmFtZXNwYWNlKTsKI2VuZGlmCgogICAgaWYgKHNjaGVtYS0+ZWxlbURlY2wgPT0gTlVMTCkKICAgICAgICBzY2hlbWEtPmVsZW1EZWNsID0geG1sSGFzaENyZWF0ZSgxMCk7CiAgICBpZiAoc2NoZW1hLT5lbGVtRGVjbCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hRWxlbWVudCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBlbGVtZW50IiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFFbGVtZW50KSk7CiAgICByZXQtPm5hbWUgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIG5hbWUsIC0xKTsKICAgIHJldC0+dGFyZ2V0TmFtZXNwYWNlID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBuYW1lc3BhY2UsIC0xKTsKICAgIHZhbCA9IHhtbEhhc2hBZGRFbnRyeTMoc2NoZW1hLT5lbGVtRGVjbCwgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlLCBjdHh0LT5jb250YWluZXIsIHJldCk7CiAgICBpZiAodmFsICE9IDApIHsKICAgICAgICBjaGFyIGJ1ZlsxMDBdOwoKICAgICAgICBzbnByaW50ZihidWYsIDk5LCAicHJpdmF0aWVlbGVtICVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICAgICAgdmFsID0geG1sSGFzaEFkZEVudHJ5MyhzY2hlbWEtPmVsZW1EZWNsLCBuYW1lLCAoeG1sQ2hhciAqKSBidWYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lc3BhY2UsIHJldCk7CiAgICAgICAgaWYgKHZhbCAhPSAwKSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgY3R4dC0+ZG9jLAoJCQkgIFhNTF9TQ0hFTUFQX1JFREVGSU5FRF9FTEVNRU5ULAoJCQkgICJFbGVtZW50ICVzIGFscmVhZHkgZGVmaW5lZFxuIiwKCQkJICBuYW1lLCBOVUxMKTsKICAgICAgICAgICAgeG1sRnJlZShyZXQpOwogICAgICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZFR5cGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5hbWU6ICB0aGUgaXRlbSBuYW1lCiAqIEBuYW1lc3BhY2U6ICB0aGUgbmFtZXNwYWNlCiAqCiAqIEFkZCBhbiBYTUwgc2NoZW1hIGl0ZW0KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFBZGRUeXBlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSwgY29uc3QgeG1sQ2hhciAqIG5hbWVzcGFjZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciByZXQgPSBOVUxMOwogICAgaW50IHZhbDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKI2lmZGVmIERFQlVHCiAgICBmcHJpbnRmKHN0ZGVyciwgIkFkZGluZyB0eXBlICVzXG4iLCBuYW1lKTsKICAgIGlmIChuYW1lc3BhY2UgIT0gTlVMTCkKCWZwcmludGYoc3RkZXJyLCAiICB0YXJnZXQgbmFtZXNwYWNlICVzXG4iLCBuYW1lc3BhY2UpOwojZW5kaWYKCiAgICBpZiAoc2NoZW1hLT50eXBlRGVjbCA9PSBOVUxMKQogICAgICAgIHNjaGVtYS0+dHlwZURlY2wgPSB4bWxIYXNoQ3JlYXRlKDEwKTsKICAgIGlmIChzY2hlbWEtPnR5cGVEZWNsID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hVHlwZVB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFUeXBlKSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIHR5cGUiLCBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVR5cGUpKTsKICAgIHJldC0+bmFtZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgbmFtZSwgLTEpOwogICAgcmV0LT5yZWRlZiA9IE5VTEw7CiAgICB2YWwgPSB4bWxIYXNoQWRkRW50cnkyKHNjaGVtYS0+dHlwZURlY2wsIG5hbWUsIG5hbWVzcGFjZSwgcmV0KTsKICAgIGlmICh2YWwgIT0gMCkgewogICAgICAgIGlmIChjdHh0LT5pbmNsdWRlcyA9PSAwKSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgY3R4dC0+ZG9jLAoJCQkgIFhNTF9TQ0hFTUFQX1JFREVGSU5FRF9UWVBFLAoJCQkgICJUeXBlICVzIGFscmVhZHkgZGVmaW5lZFxuIiwKCQkJICBuYW1lLCBOVUxMKTsKCSAgICB4bWxGcmVlKHJldCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0gZWxzZSB7CgkgICAgeG1sU2NoZW1hVHlwZVB0ciBwcmV2OwoKCSAgICBwcmV2ID0geG1sSGFzaExvb2t1cDIoc2NoZW1hLT50eXBlRGVjbCwgbmFtZSwgbmFtZXNwYWNlKTsKCSAgICBpZiAocHJldiA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgY3R4dC0+ZG9jLAoJCQkgICAgICBYTUxfRVJSX0lOVEVSTkFMX0VSUk9SLAoJCQkgICAgICAiSW50ZXJuYWwgZXJyb3Igb24gdHlwZSAlcyBkZWZpbml0aW9uXG4iLAoJCQkgICAgICBuYW1lLCBOVUxMKTsKCQl4bWxGcmVlKHJldCk7CgkJcmV0dXJuIChOVUxMKTsKCSAgICB9CgkgICAgcmV0LT5yZWRlZiA9IHByZXYtPnJlZGVmOwoJICAgIHByZXYtPnJlZGVmID0gcmV0OwoJfQogICAgfQogICAgcmV0LT5taW5PY2N1cnMgPSAxOwogICAgcmV0LT5tYXhPY2N1cnMgPSAxOwogICAgcmV0LT5hdHRyaWJ1dGVVc2VzID0gTlVMTDsKICAgIHJldC0+YXR0cmlidXRlV2lsZGNhcmQgPSBOVUxMOwoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYUFkZEdyb3VwOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbmFtZTogIHRoZSBncm91cCBuYW1lCiAqCiAqIEFkZCBhbiBYTUwgc2NoZW1hIEdyb3VwIGRlZmluaXRpb24KICoKICogUmV0dXJucyB0aGUgbmV3IHN0cnV0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hQWRkR3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciByZXQgPSBOVUxMOwogICAgaW50IHZhbDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobmFtZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIGlmIChzY2hlbWEtPmdyb3VwRGVjbCA9PSBOVUxMKQogICAgICAgIHNjaGVtYS0+Z3JvdXBEZWNsID0geG1sSGFzaENyZWF0ZSgxMCk7CiAgICBpZiAoc2NoZW1hLT5ncm91cERlY2wgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFUeXBlUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVR5cGUpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFkZGluZyBncm91cCIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hVHlwZSkpOwogICAgcmV0LT5uYW1lID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBuYW1lLCAtMSk7CiAgICB2YWwgPQogICAgICAgIHhtbEhhc2hBZGRFbnRyeTIoc2NoZW1hLT5ncm91cERlY2wsIG5hbWUsIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgcmV0KTsKICAgIGlmICh2YWwgIT0gMCkgewoJeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgY3R4dC0+ZG9jLAoJCSAgICAgIFhNTF9TQ0hFTUFQX1JFREVGSU5FRF9HUk9VUCwKICAgICAgICAgICAgICAgICAgICAgICJHcm91cCAlcyBhbHJlYWR5IGRlZmluZWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICBuYW1lLCBOVUxMKTsKICAgICAgICB4bWxGcmVlKHJldCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHJldC0+bWluT2NjdXJzID0gMTsKICAgIHJldC0+bWF4T2NjdXJzID0gMTsKCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKgogKiBDcmVhdGVzIGEgbmV3IHdpbGRjYXJkIG5hbWVzcGFjZSBjb25zdHJhaW50LgogKgogKiBSZXR1cm5zIHRoZSBuZXcgc3RydXR1cmUgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hV2lsZGNhcmROc1B0cgp4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFXaWxkY2FyZE5zUHRyKSAKCXhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hV2lsZGNhcmROcykpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJjcmVhdGluZyB3aWxkY2FyZCBuYW1lc3BhY2UgY29uc3RyYWludCIsIE5VTEwpOwoJcmV0dXJuIChOVUxMKTsgICAgCiAgICB9CiAgICByZXQtPnZhbHVlID0gTlVMTDsKICAgIHJldC0+bmV4dCA9IE5VTEw7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFBZGRXaWxkY2FyZDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5hbWU6ICB0aGUgZ3JvdXAgbmFtZQogKgogKiBBZGQgYW4gWE1MIHNjaGVtYSBHcm91cCBkZWZpbml0aW9uCiAqCiAqIFJldHVybnMgdGhlIG5ldyBzdHJ1dHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFXaWxkY2FyZFB0cgp4bWxTY2hlbWFBZGRXaWxkY2FyZCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsKICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHJldCA9IE5VTEw7CgogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFXaWxkY2FyZFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFXaWxkY2FyZCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWRkaW5nIHdpbGRjYXJkIiwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFXaWxkY2FyZCkpOwogICAgcmV0LT5taW5PY2N1cnMgPSAxOwogICAgcmV0LT5tYXhPY2N1cnMgPSAxOwoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqCQlVdGlsaXRpZXMgZm9yIHBhcnNpbmcJCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqCiAqIHhtbEdldFFOYW1lUHJvcDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKiBAbmFtZTogIHRoZSBhdHRyaWJ1dGUgbmFtZQogKiBAbmFtZXNwYWNlOiAgdGhlIHJlc3VsdCBuYW1lc3BhY2UgaWYgYW55CiAqCiAqIEV4dHJhY3QgYSBRTmFtZSBBdHRyaWJ1dGUgdmFsdWUKICoKICogUmV0dXJucyB0aGUgTkNOYW1lIG9yIE5VTEwgaWYgbm90IGZvdW5kLCBhbmQgYWxzbyB1cGRhdGUgQG5hbWVzcGFjZQogKiAgICB3aXRoIHRoZSBuYW1lc3BhY2UgVVJJCiAqLwpzdGF0aWMgY29uc3QgeG1sQ2hhciAqCnhtbEdldFFOYW1lUHJvcCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSwKICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm5hbWUsIGNvbnN0IHhtbENoYXIgKiogbmFtZXNwYWNlKQp7CiAgICBjb25zdCB4bWxDaGFyICp2YWw7CiAgICB4bWxOc1B0ciBuczsKICAgIGNvbnN0IHhtbENoYXIgKnJldCwgKnByZWZpeDsKICAgIGludCBsZW47CgogICAgKm5hbWVzcGFjZSA9IE5VTEw7CiAgICB2YWwgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsIG5hbWUpOwogICAgaWYgKHZhbCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgaWYgKCFzdHJjaHIoKGNoYXIgKikgdmFsLCAnOicpKSB7CglucyA9IHhtbFNlYXJjaE5zKG5vZGUtPmRvYywgbm9kZSwgMCk7CglpZiAobnMpIHsKCSAgICAqbmFtZXNwYWNlID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBucy0+aHJlZiwgLTEpOwoJICAgIHJldHVybiAodmFsKTsKCX0KICAgIH0KICAgIHJldCA9IHhtbFNwbGl0UU5hbWUzKHZhbCwgJmxlbik7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gKHZhbCk7CiAgICB9CiAgICByZXQgPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHJldCwgLTEpOwogICAgcHJlZml4ID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCB2YWwsIGxlbik7CgogICAgbnMgPSB4bWxTZWFyY2hOcyhub2RlLT5kb2MsIG5vZGUsIHByZWZpeCk7CiAgICBpZiAobnMgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVBfUFJFRklYX1VOREVGSU5FRCwKICAgICAgICAgICAgICAgICAgICAgICJBdHRyaWJ1dGUgXCIlc1wiOiB0aGUgUU5hbWUgcHJlZml4IFwiJXNcIiBpcyB1bmRlZmluZWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAoY29uc3QgeG1sQ2hhciAqKSBuYW1lLCBwcmVmaXgpOwogICAgfSBlbHNlIHsKICAgICAgICAqbmFtZXNwYWNlID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBucy0+aHJlZiwgLTEpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sR2V0TWF4T2NjdXJzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIEdldCB0aGUgbWF4T2NjdXJzIHByb3BlcnR5CiAqCiAqIFJldHVybnMgdGhlIGRlZmF1bHQgaWYgbm90IGZvdW5kLCBvciB0aGUgdmFsdWUKICovCnN0YXRpYyBpbnQKeG1sR2V0TWF4T2NjdXJzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBjb25zdCB4bWxDaGFyICp2YWwsICpjdXI7CiAgICBpbnQgcmV0ID0gMDsKCiAgICB2YWwgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJtYXhPY2N1cnMiKTsKICAgIGlmICh2YWwgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKDEpOwoKICAgIGlmICh4bWxTdHJFcXVhbCh2YWwsIChjb25zdCB4bWxDaGFyICopICJ1bmJvdW5kZWQiKSkgewogICAgICAgIHJldHVybiAoVU5CT1VOREVEKTsgIC8qIGVuY29kaW5nIGl0IHdpdGggLTEgbWlnaHQgYmUgYW5vdGhlciBvcHRpb24gKi8KICAgIH0KCiAgICBjdXIgPSB2YWw7CiAgICB3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCiAgICAgICAgY3VyKys7CiAgICB3aGlsZSAoKCpjdXIgPj0gJzAnKSAmJiAoKmN1ciA8PSAnOScpKSB7CiAgICAgICAgcmV0ID0gcmV0ICogMTAgKyAoKmN1ciAtICcwJyk7CiAgICAgICAgY3VyKys7CiAgICB9CiAgICB3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCiAgICAgICAgY3VyKys7CiAgICBpZiAoKmN1ciAhPSAwKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BUF9JTlZBTElEX01BWE9DQ1VSUywKICAgICAgICAgICAgICAgICAgICAgICJpbnZhbGlkIHZhbHVlIGZvciBtYXhPY2N1cnM6ICVzXG4iLCB2YWwsIE5VTEwpOwogICAgICAgIHJldHVybiAoMSk7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxHZXRNaW5PY2N1cnM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogR2V0IHRoZSBtaW5PY2N1cnMgcHJvcGVydHkKICoKICogUmV0dXJucyB0aGUgZGVmYXVsdCBpZiBub3QgZm91bmQsIG9yIHRoZSB2YWx1ZQogKi8Kc3RhdGljIGludAp4bWxHZXRNaW5PY2N1cnMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIGNvbnN0IHhtbENoYXIgKnZhbCwgKmN1cjsKICAgIGludCByZXQgPSAwOwoKICAgIHZhbCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgIm1pbk9jY3VycyIpOwogICAgaWYgKHZhbCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoMSk7CgogICAgY3VyID0gdmFsOwogICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQogICAgICAgIGN1cisrOwogICAgd2hpbGUgKCgqY3VyID49ICcwJykgJiYgKCpjdXIgPD0gJzknKSkgewogICAgICAgIHJldCA9IHJldCAqIDEwICsgKCpjdXIgLSAnMCcpOwogICAgICAgIGN1cisrOwogICAgfQogICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQogICAgICAgIGN1cisrOwogICAgaWYgKCpjdXIgIT0gMCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVBfSU5WQUxJRF9NSU5PQ0NVUlMsCiAgICAgICAgICAgICAgICAgICAgICAiaW52YWxpZCB2YWx1ZSBmb3IgbWluT2NjdXJzOiAlc1xuIiwgdmFsLCBOVUxMKTsKICAgICAgICByZXR1cm4gKDEpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sR2V0Qm9vbGVhblByb3A6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICogQG5hbWU6ICB0aGUgYXR0cmlidXRlIG5hbWUKICogQGRlZjogIHRoZSBkZWZhdWx0IHZhbHVlCiAqCiAqIEdldCBpcyBhIGJvbGVhbiBwcm9wZXJ0eSBpcyBzZXQKICoKICogUmV0dXJucyB0aGUgZGVmYXVsdCBpZiBub3QgZm91bmQsIDAgaWYgZm91bmQgdG8gYmUgZmFsc2UsCiAqICAgICAgICAgMSBpZiBmb3VuZCB0byBiZSB0cnVlCiAqLwpzdGF0aWMgaW50CnhtbEdldEJvb2xlYW5Qcm9wKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlLAogICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpuYW1lLCBpbnQgZGVmKQp7CiAgICBjb25zdCB4bWxDaGFyICp2YWw7CgogICAgdmFsID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCBuYW1lKTsKICAgIGlmICh2YWwgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKGRlZik7CgogICAgaWYgKHhtbFN0ckVxdWFsKHZhbCwgQkFEX0NBU1QgInRydWUiKSkKICAgICAgICBkZWYgPSAxOwogICAgZWxzZSBpZiAoeG1sU3RyRXF1YWwodmFsLCBCQURfQ0FTVCAiZmFsc2UiKSkKICAgICAgICBkZWYgPSAwOwogICAgZWxzZSB7CiAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BUF9JTlZBTElEX0JPT0xFQU4sCiAgICAgICAgICAgICAgICAgICAgICAiQXR0cmlidXRlICVzOiB0aGUgdmFsdWUgJXMgaXMgbm90IGJvb2xlYW5cbiIsCiAgICAgICAgICAgICAgICAgICAgICAoY29uc3QgeG1sQ2hhciAqKSBuYW1lLCB2YWwpOwogICAgfQogICAgcmV0dXJuIChkZWYpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICoJCVNoZW1hIGV4dHJhY3Rpb24gZnJvbSBhbiBJbmZvc2V0CQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyIHhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLAoJCQkJCQkgaW50IHRvcExldmVsKTsKc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIgeG1sU2NoZW1hUGFyc2VDb21wbGV4VHlwZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwgCgkJCQkJCSAgaW50IHRvcExldmVsKTsKc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIgeG1sU2NoZW1hUGFyc2VSZXN0cmljdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSk7CnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyIHhtbFNjaGVtYVBhcnNlU2VxdWVuY2UoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKTsKc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIgeG1sU2NoZW1hUGFyc2VBbGwoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpOwpzdGF0aWMgeG1sU2NoZW1hQXR0cmlidXRlUHRyIHhtbFNjaGVtYVBhcnNlQXR0cmlidXRlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLAoJCQkJCQkgICAgIGludCB0b3BMZXZlbCk7CnN0YXRpYyB4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cgp4bWxTY2hlbWFQYXJzZUF0dHJpYnV0ZUdyb3VwKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLCB4bWxOb2RlUHRyIG5vZGUsCgkJCSAgICAgaW50IHRvcExldmVsKTsKc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIgeG1sU2NoZW1hUGFyc2VDaG9pY2UoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpOwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0ciB4bWxTY2hlbWFQYXJzZUxpc3QoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSk7CnN0YXRpYyB4bWxTY2hlbWFXaWxkY2FyZFB0cgp4bWxTY2hlbWFQYXJzZUFueUF0dHJpYnV0ZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZSk7CgovKioKICogeG1sU2NoZW1hUGFyc2VTY2hlbWFBdHRyVmFsdWU6CiAqIAogKiBAY3R4dDogIGEgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBhdHRyOiAgdGhlIHNjaGVtYSBhdHRyaWJ1dGUgYmVpbmcgdmFsaWRhdGVkCiAqIEB0eXBlOiB0aGUgYnVpbHQtaW4gdHlwZSB0byBiZSB2YWxpZGF0ZWQgYWdhaW5zdAogKiBAdmFsdWU6IHRoZSB2YWx1ZSB0byBiZSB2YWxpZGF0ZWQKICoKICogVmFsaWRhdGVzIGEgdmFsdWUgYWdhaW5zdCB0aGUgZ2l2ZW4gYnVpbHQtaW4gdHlwZS4KICogVGhpcyBvbmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBpbnRlcm5hbGx5IGZvciB2YWxpZGF0aW9uCiAqIG9mIHNjaGVtYSBhdHRyaWJ1dGUgdmFsdWVzIGR1cmluZyBwYXJzaW5nIG9mIHRoZSBzY2hlbWEuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgdmFsdWUgaXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VTY2hlbWFBdHRyVmFsdWUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAoJCQkgIHhtbEF0dHJQdHIgYXR0ciwKCQkJICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlOwogICAgaW50IHJldDsgICAgCiAgICAKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAodHlwZSA9PSBOVUxMKSB8fCAoYXR0ciA9PSBOVUxMKSkKCXJldHVybiAoLTEpOwogICAgdmFsdWUgPSB4bWxTY2hlbWFHZXROb2RlQ29udGVudChjdHh0LCAoeG1sTm9kZVB0cikgYXR0cik7CQogICAgc3dpdGNoICh0eXBlLT5idWlsdEluVHlwZSkgewoJY2FzZSBYTUxfU0NIRU1BU19OQ05BTUU6CgkgICAgcmV0ID0geG1sVmFsaWRhdGVOQ05hbWUodmFsdWUsIDEpOwoJICAgIGJyZWFrOwoJY2FzZSBYTUxfU0NIRU1BU19RTkFNRToKCSAgICByZXQgPSB4bWxWYWxpZGF0ZVFOYW1lKHZhbHVlLCAxKTsKCSAgICBpZiAoKHJldCA9PSAwKSAmJiAoYXR0ciAhPSBOVUxMKSkgewogICAgICAgICAgICAgICAgeG1sQ2hhciAqbG9jYWwgPSBOVUxMOwoJCXhtbENoYXIgKnByZWZpeDsKCQkKCQlsb2NhbCA9IHhtbFNwbGl0UU5hbWUyKHZhbHVlLCAmcHJlZml4KTsKCQlpZiAocHJlZml4ICE9IE5VTEwpIHsKCQkgICAgeG1sTnNQdHIgbnM7CgkJICAgIAoJCSAgICBucyA9IHhtbFNlYXJjaE5zKGF0dHItPmRvYywgKHhtbE5vZGVQdHIpIGF0dHIsIHByZWZpeCk7CgkJICAgIGlmIChucyA9PSBOVUxMKSB7CgkJCXhtbFNjaGVtYVBFcnIoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIsIAoJCQkgICAgWE1MX1NDSEVNQVBfUFJFRklYX1VOREVGSU5FRCwKCQkJICAgICJBdHRyaWJ1dGUgXCIlc1wiOiB0aGUgUU5hbWUgcHJlZml4ICIKCQkJICAgICJcIiVzXCIgaXMgdW5kZWZpbmVkLlxuIiwKCQkJICAgIGF0dHItPm5hbWUsIHByZWZpeCk7CgkJCXJldCA9IDE7CgkJICAgIH0KCQl9CgkJaWYgKGxvY2FsICE9IE5VTEwpCgkJICAgIHhtbEZyZWUobG9jYWwpOwoJCWlmIChwcmVmaXggIT0gTlVMTCkKCQkgICAgeG1sRnJlZShwcmVmaXgpOwoJICAgIH0KCSAgICBicmVhazsKCWRlZmF1bHQ6IHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyLCAKCQkgICAgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVBhcnNlU2NoZW1hQXR0clZhbHVlLCB2YWxpZGF0aW9uICIKCQkgICAgInVzaW5nIHRoaXMgdHlwZSBpbiBub3QgaW1wbGVtZW50ZWQgeWV0XCIlc1wiLlxuIiwKCQkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CiAgICB9ICAgICAgICAgICAgICAgICAgICAgICAKICAgIGlmIChyZXQgPiAwKSB7IAoJaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1QpIHsKCSAgICB4bWxTY2hlbWFQRXJyRXh0KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyLAkJCgkJWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8yLAoJCU5VTEwsIE5VTEwsIE5VTEwsCgkJIlRoZSBzY2hlbWEgYXR0cmlidXRlIFwiJXNcIiB3aXRoIHRoZSB2YWx1ZSBcIiVzXCIgaXMgbm90ICIKCQkib2YgYnVpbHQtaW4gbGlzdCBzaW1wbGUgdHlwZSBcIiVzXCIuXG4iLAoJCWF0dHItPm5hbWUsIHZhbHVlLCB0eXBlLT5uYW1lLCBOVUxMLCBOVUxMKTsKCX0gZWxzZSB7CgkgICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9CVUlMVElOX1BSSU1JVElWRSkgewoJCXhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgKHhtbE5vZGVQdHIpIGF0dHIsIAoJCSAgICBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzEsCgkJICAgIE5VTEwsIE5VTEwsIE5VTEwsCgkJICAgICJUaGUgc2NoZW1hIGF0dHJpYnV0ZSBcIiVzXCIgd2l0aCB0aGUgdmFsdWUgXCIlc1wiIGlzIG5vdCAiCgkJICAgICJvZiBidWlsdC1pbiBwcmltaXRpdmUgdHlwZSBcIiVzXCIuXG4iLAoJCSAgICBhdHRyLT5uYW1lLCB2YWx1ZSwgdHlwZS0+bmFtZSwgTlVMTCwgTlVMTCk7CgkgICAgfSBlbHNlIHsKCQl4bWxTY2hlbWFQRXJyRXh0KGN0eHQsICh4bWxOb2RlUHRyKSBhdHRyLCAKCQkgICAgWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8xLAoJCSAgICBOVUxMLCBOVUxMLCBOVUxMLAoJCSAgICAiVGhlIHNjaGVtYSBhdHRyaWJ1dGUgXCIlc1wiIHdpdGggdGhlIHZhbHVlIFwiJXNcIiBpcyBub3QgIgoJCSAgICAib2YgYnVpbHQtaW4gYXRvbWljIHNpbXBsZSB0eXBlIFwiJXNcIi5cbiIsCgkJICAgIGF0dHItPm5hbWUsIHZhbHVlLCB0eXBlLT5uYW1lLCBOVUxMLCBOVUxMKTsKCSAgICB9Cgl9CiAgICB9ICAgIAogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VBdHRyRGVjbHM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICogQHR5cGU6ICB0aGUgaG9zdGluZyB0eXBlCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBhdHRyRGVjbHMgZGVjbGFyYXRpb24gY29ycmVzcG9uZGluZyB0bwogKiA8IUVOVElUWSAlIGF0dHJEZWNscyAgCiAqICAgICAgICcoKCVhdHRyaWJ1dGU7fCAlYXR0cmlidXRlR3JvdXA7KSosKCVhbnlBdHRyaWJ1dGU7KT8pJz4KICovCnN0YXRpYyB4bWxOb2RlUHRyCnhtbFNjaGVtYVBhcnNlQXR0ckRlY2xzKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBjaGlsZCwgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgbGFzdGF0dHIsIGF0dHI7CgogICAgbGFzdGF0dHIgPSBOVUxMOwogICAgd2hpbGUgKChJU19TQ0hFTUEoY2hpbGQsICJhdHRyaWJ1dGUiKSkgfHwKICAgICAgICAgICAoSVNfU0NIRU1BKGNoaWxkLCAiYXR0cmlidXRlR3JvdXAiKSkpIHsKICAgICAgICBhdHRyID0gTlVMTDsKICAgICAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYXR0cmlidXRlIikpIHsKICAgICAgICAgICAgYXR0ciA9IHhtbFNjaGVtYVBhcnNlQXR0cmlidXRlKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYXR0cmlidXRlR3JvdXAiKSkgewogICAgICAgICAgICBhdHRyID0gKHhtbFNjaGVtYUF0dHJpYnV0ZVB0cikKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlQXR0cmlidXRlR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CiAgICAgICAgfQogICAgICAgIGlmIChhdHRyICE9IE5VTEwpIHsKICAgICAgICAgICAgaWYgKGxhc3RhdHRyID09IE5VTEwpIHsKCQlpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFR1JPVVApCgkJICAgICgoeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIpIHR5cGUpLT5hdHRyaWJ1dGVzID0gYXR0cjsKCQllbHNlCiAgICAgICAgICAgICAgICB0eXBlLT5hdHRyaWJ1dGVzID0gYXR0cjsKICAgICAgICAgICAgICAgIGxhc3RhdHRyID0gYXR0cjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGxhc3RhdHRyLT5uZXh0ID0gYXR0cjsKICAgICAgICAgICAgICAgIGxhc3RhdHRyID0gYXR0cjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFueUF0dHJpYnV0ZSIpKSB7Cgl4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkY2FyZDsKCiAgICAgICAgd2lsZGNhcmQgPSB4bWxTY2hlbWFQYXJzZUFueUF0dHJpYnV0ZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBpZiAod2lsZGNhcmQgIT0gTlVMTCkgewoJICAgIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUCkKCQkoKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKSB0eXBlKS0+YXR0cmlidXRlV2lsZGNhcmQgPSB3aWxkY2FyZDsKCSAgICBlbHNlCgkJdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgPSB3aWxkY2FyZDsKICAgICAgICB9CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoY2hpbGQpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBBdHRycmlidXRlIGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBpbXByb3BlciBhbmQKICogICAgICAgICAxIGluIGNhc2Ugb2Ygc3VjY2Vzcy4KICovCnN0YXRpYyB4bWxTY2hlbWFBbm5vdFB0cgp4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFBbm5vdFB0ciByZXQ7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHJldCA9IHhtbFNjaGVtYU5ld0Fubm90KGN0eHQsIG5vZGUpOwoKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlRmFjZXQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEZhY2V0IGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgbmV3IHR5cGUgc3RydWN0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYUZhY2V0UHRyCnhtbFNjaGVtYVBhcnNlRmFjZXQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQ7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKnZhbHVlOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgZmFjZXQgPSB4bWxTY2hlbWFOZXdGYWNldCgpOwogICAgaWYgKGZhY2V0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIGZhY2V0Iiwgbm9kZSk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIGZhY2V0LT5ub2RlID0gbm9kZTsKICAgIHZhbHVlID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAidmFsdWUiKTsKICAgIGlmICh2YWx1ZSA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsIFhNTF9TQ0hFTUFQX0ZBQ0VUX05PX1ZBTFVFLAogICAgICAgICAgICAgICAgICAgICAgICJGYWNldCAlcyBoYXMgbm8gdmFsdWVcbiIsIG5vZGUtPm5hbWUsIE5VTEwpOwogICAgICAgIHhtbFNjaGVtYUZyZWVGYWNldChmYWNldCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIGlmIChJU19TQ0hFTUEobm9kZSwgIm1pbkluY2x1c2l2ZSIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX01JTklOQ0xVU0lWRTsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJtaW5FeGNsdXNpdmUiKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9NSU5FWENMVVNJVkU7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAibWF4SW5jbHVzaXZlIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfTUFYSU5DTFVTSVZFOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgIm1heEV4Y2x1c2l2ZSIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX01BWEVYQ0xVU0lWRTsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJ0b3RhbERpZ2l0cyIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX1RPVEFMRElHSVRTOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgImZyYWN0aW9uRGlnaXRzIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfRlJBQ1RJT05ESUdJVFM7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAicGF0dGVybiIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk47CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAiZW51bWVyYXRpb24iKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTjsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJ3aGl0ZVNwYWNlIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRTsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKG5vZGUsICJsZW5ndGgiKSkgewogICAgICAgIGZhY2V0LT50eXBlID0gWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShub2RlLCAibWF4TGVuZ3RoIikpIHsKICAgICAgICBmYWNldC0+dHlwZSA9IFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIOwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEobm9kZSwgIm1pbkxlbmd0aCIpKSB7CiAgICAgICAgZmFjZXQtPnR5cGUgPSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSDsKICAgIH0gZWxzZSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsIFhNTF9TQ0hFTUFQX1VOS05PV05fRkFDRVRfVFlQRSwKICAgICAgICAgICAgICAgICAgICAgICAiVW5rbm93biBmYWNldCB0eXBlICVzXG4iLCBub2RlLT5uYW1lLCBOVUxMKTsKICAgICAgICB4bWxTY2hlbWFGcmVlRmFjZXQoZmFjZXQpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBmYWNldC0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwogICAgZmFjZXQtPnZhbHVlID0gdmFsdWU7CiAgICBpZiAoKGZhY2V0LT50eXBlICE9IFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTikgJiYKCShmYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OKSkgewoJY29uc3QgeG1sQ2hhciAqZml4ZWQ7CgoJZml4ZWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJmaXhlZCIpOwoJaWYgKGZpeGVkICE9IE5VTEwpIHsKCSAgICBpZiAoeG1sU3RyRXF1YWwoZml4ZWQsIEJBRF9DQVNUICJ0cnVlIikpCgkJZmFjZXQtPmZpeGVkID0gMTsKCX0KICAgIH0KICAgIAogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKCiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgZmFjZXQtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCBYTUxfU0NIRU1BUF9VTktOT1dOX0ZBQ0VUX0NISUxELAogICAgICAgICAgICAgICAgICAgICAgICJGYWNldCAlcyBoYXMgdW5leHBlY3RlZCBjaGlsZCBjb250ZW50XG4iLAogICAgICAgICAgICAgICAgICAgICAgIG5vZGUtPm5hbWUsIE5VTEwpOwogICAgfQogICAgcmV0dXJuIChmYWNldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUFueToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgQW55IGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgbmV3IHR5cGUgc3RydWN0dXJlIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VBbnkoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQ2hhciBuYW1lWzMwXTsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgc25wcmludGYoKGNoYXIgKikgbmFtZSwgMzAsICJhbnkgJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKICAgIHR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgbmFtZSwgTlVMTCk7CiAgICBpZiAodHlwZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB0eXBlLT5ub2RlID0gbm9kZTsKICAgIHR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQU5ZOwogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIHR5cGUtPm1pbk9jY3VycyA9IHhtbEdldE1pbk9jY3VycyhjdHh0LCBub2RlKTsKICAgIHR5cGUtPm1heE9jY3VycyA9IHhtbEdldE1heE9jY3VycyhjdHh0LCBub2RlKTsKCiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgdHlwZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsCiAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9TRVFVRU5DRV9DSElMRCwKICAgICAgICAgICAgICAgICAgICAgICAiU2VxdWVuY2UgJXMgaGFzIHVuZXhwZWN0ZWQgY29udGVudFxuIiwgdHlwZS0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgIH0KCiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VOb3RhdGlvbjoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgTm90YXRpb24gZGVjbGFyYXRpb24KICoKICogUmV0dXJucyB0aGUgbmV3IHN0cnVjdHVyZSBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFOb3RhdGlvblB0cgp4bWxTY2hlbWFQYXJzZU5vdGF0aW9uKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWU7CiAgICB4bWxTY2hlbWFOb3RhdGlvblB0ciByZXQ7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgbmFtZSA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgIm5hbWUiKTsKICAgIGlmIChuYW1lID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwgWE1MX1NDSEVNQVBfTk9UQVRJT05fTk9fTkFNRSwKICAgICAgICAgICAgICAgICAgICAgICAiTm90YXRpb24gaGFzIG5vIG5hbWVcbiIsIE5VTEwsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXQgPSB4bWxTY2hlbWFBZGROb3RhdGlvbihjdHh0LCBzY2hlbWEsIG5hbWUpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgcmV0LT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9VTktOT1dOX05PVEFUSU9OX0NISUxELAogICAgICAgICAgICAgICAgICAgICAgICJub3RhdGlvbiAlcyBoYXMgdW5leHBlY3RlZCBjb250ZW50XG4iLCBuYW1lLCBOVUxMKTsKICAgIH0KCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUFueUF0dHJpYnV0ZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgQW55QXR0cnJpYnV0ZSBkZWNsYXJhdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgYW4gYXR0cmlidXRlIGRlZiBzdHJ1Y3R1cmUgb3IgTlVMTAogKi8Kc3RhdGljIHhtbFNjaGVtYVdpbGRjYXJkUHRyCnhtbFNjaGVtYVBhcnNlQW55QXR0cmlidXRlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUHRyIHNjaGVtYSwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICBjb25zdCB4bWxDaGFyICpwcm9jZXNzQ29udGVudHMsICpuc0NvbnN0cmFpbnQsICplbmQsICpjdXIsICpkaWN0TWVtYmVyOwogICAgeG1sQ2hhciAqbWVtYmVyOwogICAgeG1sU2NoZW1hV2lsZGNhcmRQdHIgcmV0OwogICAgeG1sU2NoZW1hV2lsZGNhcmROc1B0ciB0bXAsIGxhc3ROcyA9IE5VTEw7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9IHhtbFNjaGVtYUFkZFdpbGRjYXJkKGN0eHQpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9BTllfQVRUUklCVVRFOwogICAgcmV0LT5pZCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImlkIik7CiAgICBwcm9jZXNzQ29udGVudHMgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJwcm9jZXNzQ29udGVudHMiKTsKICAgIGlmICgocHJvY2Vzc0NvbnRlbnRzID09IE5VTEwpCiAgICAgICAgfHwgKHhtbFN0ckVxdWFsKHByb2Nlc3NDb250ZW50cywgKGNvbnN0IHhtbENoYXIgKikgInN0cmljdCIpKSkgewogICAgICAgIHJldC0+cHJvY2Vzc0NvbnRlbnRzID0gWE1MX1NDSEVNQVNfQU5ZX1NUUklDVDsKICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwocHJvY2Vzc0NvbnRlbnRzLCAoY29uc3QgeG1sQ2hhciAqKSAic2tpcCIpKSB7CiAgICAgICAgcmV0LT5wcm9jZXNzQ29udGVudHMgPSBYTUxfU0NIRU1BU19BTllfU0tJUDsKICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwocHJvY2Vzc0NvbnRlbnRzLCAoY29uc3QgeG1sQ2hhciAqKSAibGF4IikpIHsKICAgICAgICByZXQtPnByb2Nlc3NDb250ZW50cyA9IFhNTF9TQ0hFTUFTX0FOWV9MQVg7CiAgICB9IGVsc2UgewogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgCiAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9QUk9DRVNTQ09OVEVOVF9DSElMRCwKICAgICAgICAgICAgICAgICAgICAgICAiYW55QXR0cmlidXRlIGhhcyB1bmV4cGVjdGVkIGNvbnRlbnQgIgoJCSAgICAgICAiZm9yIHByb2Nlc3NDb250ZW50czogJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc0NvbnRlbnRzLCBOVUxMKTsKICAgICAgICByZXQtPnByb2Nlc3NDb250ZW50cyA9IFhNTF9TQ0hFTUFTX0FOWV9TVFJJQ1Q7CiAgICB9CiAgICAvKgogICAgICogQnVpbGQgdGhlIG5hbWVzcGFjZSBjb25zdHJhaW50cy4KICAgICAqLwogICAgbnNDb25zdHJhaW50ID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAibmFtZXNwYWNlIik7CiAgICBpZiAoKG5zQ29uc3RyYWludCA9PSBOVUxMKSB8fCAoeG1sU3RyRXF1YWwobnNDb25zdHJhaW50LCBCQURfQ0FTVCAiIyNhbnkiKSkpCglyZXQtPmFueSA9IDE7CiAgICBlbHNlIGlmICh4bWxTdHJFcXVhbChuc0NvbnN0cmFpbnQsIEJBRF9DQVNUICIjI290aGVyIikpIHsKCXJldC0+bmVnTnNTZXQgPSB4bWxTY2hlbWFOZXdXaWxkY2FyZE5zQ29uc3RyYWludChjdHh0KTsKCWlmIChyZXQtPm5lZ05zU2V0ID09IE5VTEwpIHsJICAgIAoJICAgIHhtbFNjaGVtYUZyZWVXaWxkY2FyZChyZXQpOwoJICAgIHJldHVybiAoTlVMTCk7Cgl9CglyZXQtPm5lZ05zU2V0LT52YWx1ZSA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOyAKICAgIH0gZWxzZSB7ICAgIAoJY3VyID0gbnNDb25zdHJhaW50OwoJZG8gewoJICAgIHdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKCQljdXIrKzsKCSAgICBlbmQgPSBjdXI7CgkgICAgd2hpbGUgKCgqZW5kICE9IDApICYmICghKElTX0JMQU5LX0NIKCplbmQpKSkpCgkJZW5kKys7CgkgICAgaWYgKGVuZCA9PSBjdXIpCgkJYnJlYWs7CgkgICAgbWVtYmVyID0geG1sU3RybmR1cChjdXIsIGVuZCAtIGN1cik7ICAgIAkgICAgCgkgICAgaWYgKCh4bWxTdHJFcXVhbChtZW1iZXIsIEJBRF9DQVNUICIjI290aGVyIikpIHx8CgkJICAgICh4bWxTdHJFcXVhbChtZW1iZXIsIEJBRF9DQVNUICIjI2FueSIpKSkgewoJCXhtbFNjaGVtYVBFcnIoY3R4dCwgcmV0LT5ub2RlLCBYTUxfU0NIRU1BUF9XSUxEQ0FSRF9JTlZBTElEX05TX01FTUJFUiwKCQkgICAgIlRoZSBuYW1lc3BhY2UgY29uc3RyYWludCBvZiBhbiBhbnlBdHRyaWJ1dGUgIgoJCSAgICAiaXMgYSBzZXQgYW5kIG11c3Qgbm90IGNvbnRhaW4gXCIlc1wiXG4iLAoJCSAgICBtZW1iZXIsIE5VTEwpOwkJCSAgICAJCSAgICAKCSAgICB9IGVsc2UgewkJCgkJLyoKCQkqIFRPRE86IFZhbGlkYXRlIHRoZSB2YWx1ZSAoYW55VVJJKS4KCQkqLwkJCgkJaWYgKHhtbFN0ckVxdWFsKG1lbWJlciwgQkFEX0NBU1QgIiMjdGFyZ2V0TmFtZXNwYWNlIikpIHsKCQkgICAgZGljdE1lbWJlciA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJCX0gZWxzZSBpZiAoeG1sU3RyRXF1YWwobWVtYmVyLCBCQURfQ0FTVCAiIyNsb2NhbCIpKSB7CgkJICAgIGRpY3RNZW1iZXIgPSBOVUxMOwoJCX0gZWxzZQoJCSAgICBkaWN0TWVtYmVyID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBtZW1iZXIsIC0xKTsKCQkvKgoJCSogQXZvaWQgZHVibGljYXRlIG5hbWVzcGFjZXMuCgkJKi8KCQl0bXAgPSByZXQtPm5zU2V0OwoJCXdoaWxlICh0bXAgIT0gTlVMTCkgewoJCSAgICBpZiAoZGljdE1lbWJlciA9PSB0bXAtPnZhbHVlKQoJCQlicmVhazsKCQkgICAgdG1wID0gdG1wLT5uZXh0OwoJCX0KCQlpZiAodG1wID09IE5VTEwpIHsKCQkgICAgdG1wID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CgkJICAgIGlmICh0bXAgPT0gTlVMTCkgewoJCQl4bWxGcmVlKG1lbWJlcik7CgkJCXhtbFNjaGVtYUZyZWVXaWxkY2FyZChyZXQpOwoJCQlyZXR1cm4gKE5VTEwpOwoJCSAgICB9CgkJICAgIHRtcC0+dmFsdWUgPSBkaWN0TWVtYmVyOwoJCSAgICB0bXAtPm5leHQgPSBOVUxMOwoJCSAgICBpZiAocmV0LT5uc1NldCA9PSBOVUxMKSAKCQkJcmV0LT5uc1NldCA9IHRtcDsKCQkgICAgZWxzZQoJCQlsYXN0TnMtPm5leHQgPSB0bXA7CgkJICAgIGxhc3ROcyA9IHRtcDsKCQl9CgoJICAgIH0JCgkgICAgeG1sRnJlZShtZW1iZXIpOwoJICAgIGN1ciA9IGVuZDsKCX0gd2hpbGUgKCpjdXIgIT0gMCk7ICAgIAogICAgfQoKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgcmV0LT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9VTktOT1dOX0FOWUFUVFJJQlVURV9DSElMRCwKICAgICAgICAgICAgICAgICAgICAgICAiYW55QXR0cmlidXRlIGhhcyB1bmV4cGVjdGVkIGNvbnRlbnRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCk7CiAgICB9CgogICAgcmV0dXJuIChyZXQpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlQXR0cmlidXRlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBBdHRycmlidXRlIGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgYXR0cmlidXRlIGRlY2xhcmF0aW9uLgogKi8Kc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZVB0cgp4bWxTY2hlbWFQYXJzZUF0dHJpYnV0ZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwgaW50IHRvcExldmVsKQp7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lLCAqcmVmTnMgPSBOVUxMLCAqcmVmID0gTlVMTCwgKmF0dHJWYWw7CiAgICB4bWxTY2hlbWFBdHRyaWJ1dGVQdHIgcmV0OwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICBjaGFyIGJ1ZlsxMDBdOwogICAgaW50IGhhc1JlZlR5cGUgPSAwOwoKICAgIC8qCiAgICAgKiBOb3RlIHRoYXQgdGhlIHczYyBzcGVjIGFzc3VtZXMgdGhlIHNjaGVtYSB0byBiZSB2YWxpZGF0ZWQgd2l0aCBzY2hlbWEKICAgICAqIGZvciBzY2hlbWFzIGJlZm9yZWhhbmQuCiAgICAgKgogICAgICogMy4yLjMgQ29uc3RyYWludHMgb24gWE1MIFJlcHJlc2VudGF0aW9ucyBvZiBBdHRyaWJ1dGUgRGVjbGFyYXRpb25zCiAgICAgKgogICAgICogVE9ETzogQ29tcGxldGUgaW1wbGVtZW50YXRpb24gb2Y6IAogICAgICogMy4yLjYgU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBBdHRyaWJ1dGUgRGVjbGFyYXRpb24gUHJvcGVydGllcwogICAgICogICAgICAgQ29ycmVjdCAKICAgICAqLwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAKICAgIG5hbWUgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJuYW1lIik7CiAgICBpZiAobmFtZSA9PSBOVUxMKSB7CiAgICAgICAgcmVmID0geG1sR2V0UU5hbWVQcm9wKGN0eHQsIG5vZGUsICJyZWYiLCAmcmVmTnMpOwoJLyogMy4yLjMgOiAzLjEKCSAqIE9uZSBvZiByZWYgb3IgbmFtZSBtdXN0IGJlIHByZXNlbnQsIGJ1dCBub3QgYm90aCAKCSAqLwogICAgICAgIGlmIChyZWYgPT0gTlVMTCkgewkgICAgCiAgICAgICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgCgkJCSAgWE1MX1NDSEVNQVBfQVRUUl9OT05BTUVfTk9SRUYsCgkJCSAgIkF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBoYXMgbm8gXCJuYW1lXCIgb3IgXCJyZWZcIlxuIiwKCQkJICBOVUxMLCBOVUxMKTsKCSAgICByZXR1cm4gKE5VTEwpOwogICAgICAgIH0KCWhhc1JlZlR5cGUgPSAxOwogICAgICAgIHNucHJpbnRmKGJ1ZiwgOTksICJhbm9uYXR0ciAlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgICAgIG5hbWUgPSAoY29uc3QgeG1sQ2hhciAqKSBidWY7CglyZXQgPSB4bWxTY2hlbWFBZGRBdHRyaWJ1dGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBOVUxMKTsKCWlmICghdG9wTGV2ZWwpIHsKCSAgICAvKiAzLjIuMyA6IDMuMgoJICAgICAqIElmIHJlZiBpcyBwcmVzZW50LCB0aGVuIGFsbCBvZiA8c2ltcGxlVHlwZT4sCgkgICAgICogZm9ybSBhbmQgdHlwZSBtdXN0IGJlIGFic2VudC4gCgkgICAgICovCgkgICAgaWYgKHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImZvcm0iKSAhPSBOVUxMKSB7CQkKCQl4bWxTY2hlbWFQRXJyKGN0eHQsIG5vZGUsIAoJCSAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfSU5WQUxJRF9BVFRSX0NPTUJJTkFUSU9OLAoJCQkgICAgICAiQXR0cmlidXRlIGRlY2xhcmF0aW9uICVzIGhhcyBcInJlZlwiLCB0aHVzICIKCQkJICAgICAgIlwiZm9ybVwiIG11c3QgYmUgYWJzZW50XG4iLCBuYW1lLCBOVUxMKTsKCSAgICB9CgkgICAgaWYgKHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgInR5cGUiKSAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCAKCQkgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfQVRUUl9DT01CSU5BVElPTiwKCQkJICAgICAgIkF0dHJpYnV0ZSBkZWNsYXJhdGlvbiAlcyBoYXMgXCJyZWZcIiwgdGh1cyAiCgkJCSAgICAgICJcInR5cGVcIiBtdXN0IGJlIGFic2VudFxuIiwgbmFtZSwgTlVMTCk7CgkgICAgfQoJfQogICAgfSBlbHNlIHsKICAgICAgICBjb25zdCB4bWxDaGFyICpucyA9IE5VTEw7CgkvKiAzLjIuMyA6IDMuMQoJICogT25lIG9mIHJlZiBvciBuYW1lIG11c3QgYmUgcHJlc2VudCwgYnV0IG5vdCBib3RoIAoJICovCglpZiAoKCF0b3BMZXZlbCkgJiYgKHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgInJlZiIpICE9IE5VTEwpKSB7CSAgICAKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIG5vZGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfQVRUUl9DT01CSU5BVElPTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiQXR0cmlidXRlIGRlY2xhcmF0aW9uIFwiJXNcIiBoYXMgYm90aCwgXCJuYW1lXCIgYW5kICIKCQkJICAiXCJyZWZcIlxuIiwgbmFtZSwgTlVMTCk7Cgl9CgogICAgICAgIC8qIGxvY2FsID0geG1sU2NoZW1hR2V0TmFtZXNwYWNlKGN0eHQsIHNjaGVtYSwgbm9kZSwgbmFtZSwgJm5zKTsgKi8KCS8qIEV2YWx1YXRlIHRoZSB0YXJnZXQgbmFtZXNwYWNlICovCglpZiAoc2NoZW1hLT50YXJnZXROYW1lc3BhY2UgIT0gTlVMTCkgewoJICAgIGlmICh0b3BMZXZlbCkgewoJCW5zID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7CgkgICAgfSBlbHNlIGlmICh4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJmb3JtIikgIT0gTlVMTCkgewoJCWlmICh4bWxTdHJFcXVhbCggeG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiZm9ybSIpLAoJCQkJIEJBRF9DQVNUICJxdWFsaWZpZWQiKSkgewoJCSAgICBucyA9IHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlOwoJCX0KCSAgICB9IGVsc2UgaWYgKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19RVUFMSUZfQVRUUikgewoJCW5zID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7CQkKCSAgICB9Cgl9CglyZXQgPSB4bWxTY2hlbWFBZGRBdHRyaWJ1dGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBucyk7CglpZiAocmV0ID09IE5VTEwpCgkgICAgcmV0dXJuIChOVUxMKTsKCS8qIDMuMi42IFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogeG1sbnMgTm90IEFsbG93ZWQgKi8KCWlmICh4bWxTdHJFcXVhbChuYW1lLCBCQURfQ0FTVCAieG1sbnMiKSkgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgCiAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9JTlZBTElEX0FUVFJfTkFNRSwKICAgICAgICAgICAgICAgICAgICAgICJUaGUgbmFtZSBvZiBhbiBhdHRyaWJ1dGUgZGVjbGFyYXRpb24gbXVzdCBub3QgbWF0Y2ggIgoJCSAgICAgICJcInhtbG5zXCIuXG4iLCBOVUxMLCBOVUxMKTsKCX0JCgkKCS8qIDMuMi42IFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogeHNpOiBOb3QgQWxsb3dlZCAqLwkKCWlmICh4bWxTdHJFcXVhbChyZXQtPnRhcmdldE5hbWVzcGFjZSwgeG1sU2NoZW1hSW5zdGFuY2VOcykpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIG5vZGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfQVRUUl9OQU1FLAoJICAgICAgICAgICAgICAgICAgIlRoZSB0YXJnZXQgbmFtZXNwYWNlIG9mIGFuIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiwgIgoJCQkgICJtdXN0IG5vdCBtYXRjaCBcImh0dHA6Ly93d3cudzMub3JnLzIwMDEvIgoJCQkgICJYTUxTY2hlbWEtaW5zdGFuY2VcIiIsIE5VTEwsIE5VTEwpOwoJfQkKICAgIH0KICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXQtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFOwogICAgaWYgKHRvcExldmVsKSAKICAgICAgICByZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0FUVFJfR0xPQkFMOwogICAgCiAgICAvKiBIYW5kbGUgdGhlICJ1c2UiIGF0dHJpYnV0ZS4gKi8KICAgIGF0dHJWYWwgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJ1c2UiKTsKICAgIGlmIChhdHRyVmFsICE9IE5VTEwpIHsKCWlmICh4bWxTdHJFcXVhbChhdHRyVmFsLCBCQURfQ0FTVCAib3B0aW9uYWwiKSkKCSAgICByZXQtPm9jY3VycyA9IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX09QVElPTkFMOwoJZWxzZSBpZiAoeG1sU3RyRXF1YWwoYXR0clZhbCwgQkFEX0NBU1QgInByb2hpYml0ZWQiKSkKCSAgICByZXQtPm9jY3VycyA9IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1BST0hJQklURUQ7CgllbHNlIGlmICh4bWxTdHJFcXVhbChhdHRyVmFsLCBCQURfQ0FTVCAicmVxdWlyZWQiKSkKCSAgICByZXQtPm9jY3VycyA9IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1JFUVVJUkVEOwoJZWxzZQoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwKCQkJICBYTUxfU0NIRU1BUF9JTlZBTElEX0FUVFJfVVNFLAoJCQkgICJBdHRyaWJ1dGUgZGVjbGFyYXRpb24gJXMgaGFzIGFuIGludmFsaWQgIgoJCQkgICJ2YWx1ZSBmb3IgXCJ1c2VcIlxuIiwgbmFtZSwgTlVMTCk7CiAgICB9IGVsc2UKCXJldC0+b2NjdXJzID0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfT1BUSU9OQUw7CgogICAgCiAgICBpZiAoeG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiZGVmYXVsdCIpICE9IE5VTEwpIHsKCS8qIDMuMi4zIDogMQoJICogZGVmYXVsdCBhbmQgZml4ZWQgbXVzdCBub3QgYm90aCBiZSBwcmVzZW50LiAKCSAqLwoJaWYgKHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImZpeGVkIikgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfSU5WQUxJRF9BVFRSX0NPTUJJTkFUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgICJBdHRyaWJ1dGUgZGVjbGFyYXRpb24gaGFzIGJvdGgsIFwiZGVmYXVsdFwiICIKCQkJICAiYW5kIFwiZml4ZWRcIlxuIiwgTlVMTCwgTlVMTCk7Cgl9CgkvKiAzLjIuMyA6IDIKCSAqIElmIGRlZmF1bHQgYW5kIHVzZSBhcmUgYm90aCBwcmVzZW50LCB1c2UgbXVzdCBoYXZlCgkgKiB0aGUgYWN0dWFsIHZhbHVlIG9wdGlvbmFsLgoJICovCglpZiAocmV0LT5vY2N1cnMgIT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfT1BUSU9OQUwpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIG5vZGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfQVRUUl9DT01CSU5BVElPTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiQXR0cmlidXRlIGRlY2xhcmF0aW9uIGhhcyBcImRlZmF1bHRcIiBidXQgIgoJCQkgICJcInVzZVwiIGlzIG5vdCBcIm9wdGlvbmFsXCJcbiIsIE5VTEwsIE5VTEwpOwoJfQkKICAgIH0gICAgCgogICAgcmV0LT5yZWYgPSByZWY7CiAgICByZXQtPnJlZk5zID0gcmVmTnM7CiAgICAvKiAKICAgICAqIFRoZSBzZXR0aW5nIG9mIFhNTF9TQ0hFTUFTX0FUVFJfTlNERUZBVUxUIGlzIG5vdCBuZWVkZWQgYW55bW9yZSwKICAgICAqIHNpbmNlIHRoZSB0YXJnZXQgbmFtZXNwYWNlIHdhcyBhbHJlYWR5IGV2YWx1YXRlZCBhbmQgdG9vawogICAgICogYXR0cmlidXRlRm9ybURlZmF1bHQgaW50byBhY2NvdW50LgogICAgICovCiAgICAvKgogICAgaWYgKChyZXQtPnRhcmdldE5hbWVzcGFjZSAhPSBOVUxMKSAmJgogICAgICAgICgoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1FVQUxJRl9BVFRSKSA9PSAwKSAmJgoJKHhtbFN0ckVxdWFsKHJldC0+dGFyZ2V0TmFtZXNwYWNlLCBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSkpKQoJcmV0LT5mbGFncyB8PSBYTUxfU0NIRU1BU19BVFRSX05TREVGQVVMVDsKICAgICovCiAgICByZXQtPnR5cGVOYW1lID0geG1sR2V0UU5hbWVQcm9wKGN0eHQsIG5vZGUsICJ0eXBlIiwgJihyZXQtPnR5cGVOcykpOwogICAgaWYgKHJldC0+dHlwZU5hbWUgIT0gTlVMTCkKCWhhc1JlZlR5cGUgPSAxOwogICAgcmV0LT5ub2RlID0gbm9kZTsKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgcmV0LT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgewoJaWYgKGhhc1JlZlR5cGUpIHsKCSAgICAvKiAzLjIuMyA6IDQKCSAgICAgKiB0eXBlIGFuZCA8c2ltcGxlVHlwZT4gbXVzdCBub3QgYm90aCBiZSBwcmVzZW50LiAKCSAgICAgKgoJICAgICAqIFRPRE86IFhNTF9TQ0hFTUFQX0lOVkFMSURfQVRUUl9DT01CSU5BVElPTiBzZWVtcyBub3QgdG8gYmUKCSAgICAgKiBhIHByb3BlciBlcnJvciB0eXBlIGhlcmUuIAoJICAgICAqLwoJICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCAKCSAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9JTlZBTElEX0FUVFJfQ09NQklOQVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJBdHRyaWJ1dGUgZGVjbGFyYXRpb24gJXMgaGFzIGJvdGggKFwicmVmXCIgb3IgIgoJCQkgICAiXCJ0eXBlXCIpIGFuZCA8c2ltcGxlVHlwZT5cbiIsIG5hbWUsIE5VTEwpOwoJfSBlbHNlCgkgICAgcmV0LT5zdWJ0eXBlcyA9IHhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwgWE1MX1NDSEVNQVBfVU5LTk9XTl9BVFRSX0NISUxELAogICAgICAgICAgICAgICAgICAgICAgICJhdHRyaWJ1dGUgJXMgaGFzIHVuZXhwZWN0ZWQgY29udGVudFxuIiwgbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgIH0KCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUF0dHJpYnV0ZUdyb3VwOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBBdHRyaWJ1dGUgR3JvdXAgZGVjbGFyYXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBhdHRyaWJ1dGUgZ3JvdXAgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yLgogKi8Kc3RhdGljIHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyCnhtbFNjaGVtYVBhcnNlQXR0cmlidXRlR3JvdXAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZSwKCQkJICAgICBpbnQgdG9wTGV2ZWwpCnsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWUsICpyZWZOcyA9IE5VTEwsICpyZWYgPSBOVUxMOwogICAgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgcmV0OwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICpvbGRjb250YWluZXI7CiAgICBjaGFyIGJ1ZlsxMDBdOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICBvbGRjb250YWluZXIgPSBjdHh0LT5jb250YWluZXI7CiAgICBuYW1lID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAibmFtZSIpOwogICAgaWYgKG5hbWUgPT0gTlVMTCkgewogICAgICAgIHJlZiA9IHhtbEdldFFOYW1lUHJvcChjdHh0LCBub2RlLCAicmVmIiwgJnJlZk5zKTsKICAgICAgICBpZiAocmVmID09IE5VTEwpIHsKICAgICAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX0FUVFJHUlBfTk9OQU1FX05PUkVGLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiQXR0cmlidXRlR3JvdXAgaGFzIG5vIG5hbWUgbm9yIHJlZlxuIiwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAgICAgfQogICAgICAgIHNucHJpbnRmKGJ1ZiwgOTksICJhbm9uYXR0cmdyb3VwICVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICAgICAgbmFtZSA9IChjb25zdCB4bWxDaGFyICopIGJ1ZjsKICAgICAgICBpZiAobmFtZSA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiY3JlYXRpbmcgYXR0cmlidXRlIGdyb3VwIiwgbm9kZSk7CiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAgICAgfQogICAgfQogICAgcmV0ID0geG1sU2NoZW1hQWRkQXR0cmlidXRlR3JvdXAoY3R4dCwgc2NoZW1hLCBuYW1lKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXQtPnJlZiA9IHJlZjsKICAgIHJldC0+cmVmTnMgPSByZWZOczsKICAgIHJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDsKICAgIGlmICh0b3BMZXZlbCkgCiAgICAgICAgcmV0LT5mbGFncyB8PSBYTUxfU0NIRU1BU19BVFRSR1JPVVBfR0xPQkFMOwogICAgcmV0LT5ub2RlID0gbm9kZTsKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBjdHh0LT5jb250YWluZXIgPSBuYW1lOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHJldC0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGNoaWxkID0geG1sU2NoZW1hUGFyc2VBdHRyRGVjbHMoY3R4dCwgc2NoZW1hLCBjaGlsZCwgKHhtbFNjaGVtYVR5cGVQdHIpIHJldCk7IAogICAgLyogU2VlbXMgdGhhdCB0aGlzIGNhbiBiZSByZW1vdmVkLiAqLwogICAgLyoKICAgIHdoaWxlICgoSVNfU0NIRU1BKGNoaWxkLCAiYXR0cmlidXRlIikpIHx8CiAgICAgICAgICAgKElTX1NDSEVNQShjaGlsZCwgImF0dHJpYnV0ZUdyb3VwIikpKSB7CiAgICAgICAgYXR0ciA9IE5VTEw7CiAgICAgICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImF0dHJpYnV0ZSIpKSB7CiAgICAgICAgICAgIGF0dHIgPSB4bWxTY2hlbWFQYXJzZUF0dHJpYnV0ZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImF0dHJpYnV0ZUdyb3VwIikpIHsKICAgICAgICAgICAgYXR0ciA9ICh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpCiAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZUF0dHJpYnV0ZUdyb3VwKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwogICAgICAgIH0KICAgICAgICBpZiAoYXR0ciAhPSBOVUxMKSB7CiAgICAgICAgICAgIGlmIChsYXN0ID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIHJldC0+YXR0cmlidXRlcyA9IGF0dHI7CiAgICAgICAgICAgICAgICBsYXN0ID0gYXR0cjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGxhc3QtPm5leHQgPSBhdHRyOwogICAgICAgICAgICAgICAgbGFzdCA9IGF0dHI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbnlBdHRyaWJ1dGUiKSkgewogICAgICAgIFRPRE8KCWNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICAqLwogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9VTktOT1dOX0FUVFJHUlBfQ0hJTEQsCiAgICAgICAgICAgICAgICAgICAgICAgImF0dHJpYnV0ZSBncm91cCAlcyBoYXMgdW5leHBlY3RlZCBjb250ZW50XG4iLCBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgfQogICAgY3R4dC0+Y29udGFpbmVyID0gb2xkY29udGFpbmVyOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VFbGVtZW50OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBFbGVtZW50IGRlY2xhcmF0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgcGFyc2VkIGVsZW1lbnQgZGVjbGFyYXRpb24uCiAqLwpzdGF0aWMgeG1sU2NoZW1hRWxlbWVudFB0cgp4bWxTY2hlbWFQYXJzZUVsZW1lbnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLCBpbnQgdG9wTGV2ZWwpCnsKICAgIGNvbnN0IHhtbENoYXIgKm5hbWUsICpmaXhlZDsKICAgIGNvbnN0IHhtbENoYXIgKnJlZk5zID0gTlVMTCwgKnJlZiA9IE5VTEw7CiAgICB4bWxTY2hlbWFFbGVtZW50UHRyIHJldDsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgY29uc3QgeG1sQ2hhciAqb2xkY29udGFpbmVyOwogICAgY2hhciBidWZbMTAwXTsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICAvKiAzLjMuMyBDb25zdHJhaW50cyBvbiBYTUwgUmVwcmVzZW50YXRpb25zIG9mIEVsZW1lbnQgRGVjbGFyYXRpb25zICovCiAgICAvKiBUT0RPOiBDb21wbGV0ZSBpbXBsZW1lbnRhdGlvbiBvZiAzLjMuNiAqLwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICBvbGRjb250YWluZXIgPSBjdHh0LT5jb250YWluZXI7CiAgICBuYW1lID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAibmFtZSIpOwogICAgaWYgKG5hbWUgPT0gTlVMTCkgewogICAgICAgIHJlZiA9IHhtbEdldFFOYW1lUHJvcChjdHh0LCBub2RlLCAicmVmIiwgJnJlZk5zKTsKCS8qIDMuMy4zIDogMi4xCgkgKiBPbmUgb2YgcmVmIG9yIG5hbWUgbXVzdCBiZSBwcmVzZW50LCBidXQgbm90IGJvdGggCgkgKi8KICAgICAgICBpZiAocmVmID09IE5VTEwpIHsKICAgICAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfRUxFTV9OT05BTUVfTk9SRUYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJFbGVtZW50IGRlY2xhcmF0aW9uIGhhcyBubyBuYW1lIG5vciByZWZcbiIsIE5VTEwsIE5VTEwpOwogICAgICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgICAgIH0JCiAgICAgICAgCiAgICAgICAgc25wcmludGYoYnVmLCA5OSwgImFub25lbGVtICVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICAgICAgbmFtZSA9IChjb25zdCB4bWxDaGFyICopIGJ1ZjsKCXJldCA9IHhtbFNjaGVtYUFkZEVsZW1lbnQoY3R4dCwgc2NoZW1hLCBuYW1lLCBOVUxMKTsKICAgIH0gZWxzZSB7Cgljb25zdCB4bWxDaGFyICpucyA9IE5VTEw7CgoJLyogRXZhbHVhdGUgdGhlIHRhcmdldCBuYW1lc3BhY2UgKi8KCWlmIChzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSAhPSBOVUxMKSB7CgkgICAgaWYgKHRvcExldmVsKSB7CgkJbnMgPSBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZTsKCSAgICB9IGVsc2UgaWYgKHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImZvcm0iKSAhPSBOVUxMKSB7CgkJaWYgKHhtbFN0ckVxdWFsKCB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJmb3JtIiksCgkJCQkgQkFEX0NBU1QgInF1YWxpZmllZCIpKSB7CgkJICAgIG5zID0gc2NoZW1hLT50YXJnZXROYW1lc3BhY2U7CgkJfQoJICAgIH0gZWxzZSBpZiAoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1FVQUxJRl9BVFRSKSB7CgkJbnMgPSBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZTsKCSAgICB9Cgl9CgkvKmxvY2FsID0geG1sU2NoZW1hR2V0TmFtZXNwYWNlKGN0eHQsIHNjaGVtYSwgbm9kZSwgbmFtZSwgJm5zKTsgKi8KCXJldCA9IHhtbFNjaGVtYUFkZEVsZW1lbnQoY3R4dCwgc2NoZW1hLCBuYW1lLCBucyk7CgkvKiAzLjMuMyA6IDIuMQoJICogT25lIG9mIHJlZiBvciBuYW1lIG11c3QgYmUgcHJlc2VudCwgYnV0IG5vdCBib3RoIAoJICovCglpZiAoKCF0b3BMZXZlbCkgJiYgKHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgInJlZiIpICE9IE5VTEwpKSB7CSAgICAKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIG5vZGUsIAogICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfQVRUUl9DT01CSU5BVElPTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAiRWxlbWVudCBkZWNsYXJhdGlvbiBoYXMgYm90aCwgXCJuYW1lXCIgYW5kICIKCQkJICAiXCJyZWZcIlxuIiwgTlVMTCwgTlVMTCk7Cgl9CiAgICB9CiAgICBpZiAocmV0ICE9IE5VTEwpCglyZXQtPm5vZGUgPSBub2RlOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHJldC0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9FTEVNRU5UOwogICAgcmV0LT5yZWYgPSByZWY7CiAgICByZXQtPnJlZk5zID0gcmVmTnM7CiAgICBpZiAocmVmICE9IE5VTEwpCiAgICAgICAgcmV0LT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX1JFRjsKCiAgICAvKiAzLjMuMyA6IDIuMiAqLyAgICAgCiAgICBpZiAoKCF0b3BMZXZlbCkgJiYgKHJlZiAhPSBOVUxMKSkgewoJYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7Cgl3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CgkgICAgaWYgKChhdHRyLT5ucyA9PSBOVUxMKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInJlZiIpKSAmJiAKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJpZCIpKSAmJgoJCSgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm1heE9jY3VycyIpKSAmJiAKCQkoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJtaW5PY2N1cnMiKSkpIHsKCgkJeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BUF9JTlZBTElEX0FUVFJfQ09NQklOQVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAgIkVsZW1lbnQgZGVjbGFyYXRpb24gJXM6IG9ubHkgbWluT2NjdXJzLCBtYXhPY2N1cnMgIgoJCSAgICAgICAiYW5kIGlkIGFyZSBhbGxvd2VkIGluIGFkZGl0aW9uIHRvIHJlZlxuIiwKCQkgICAgICAgcmV0LT5uYW1lLCBOVUxMKTsKCSAgICB9CgkgICAgYXR0ciA9IGF0dHItPm5leHQ7Cgl9CiAgICB9CgogICAgaWYgKHRvcExldmVsKSB7CiAgICAgICAgcmV0LT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX0dMT0JBTDsKICAgICAgICByZXQtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0VMRU1fVE9QTEVWRUw7CiAgICB9CiAgICBpZiAoeG1sR2V0Qm9vbGVhblByb3AoY3R4dCwgbm9kZSwgIm5pbGxhYmxlIiwgMCkpCiAgICAgICAgcmV0LT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX05JTExBQkxFOwogICAgaWYgKHhtbEdldEJvb2xlYW5Qcm9wKGN0eHQsIG5vZGUsICJhYnN0cmFjdCIsIDApKQogICAgICAgIHJldC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRUxFTV9BQlNUUkFDVDsKICAgIGN0eHQtPmNvbnRhaW5lciA9IG5hbWU7CgogICAgcmV0LT5pZCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImlkIik7CiAgICByZXQtPm5hbWVkVHlwZSA9CiAgICAgICAgeG1sR2V0UU5hbWVQcm9wKGN0eHQsIG5vZGUsICJ0eXBlIiwgJihyZXQtPm5hbWVkVHlwZU5zKSk7IAogICAgcmV0LT5zdWJzdEdyb3VwID0KICAgICAgICB4bWxHZXRRTmFtZVByb3AoY3R4dCwgbm9kZSwgInN1YnN0aXR1dGlvbkdyb3VwIiwKICAgICAgICAgICAgICAgICAgICAgICAgJihyZXQtPnN1YnN0R3JvdXBOcykpOwogICAgaWYgKChyZXQtPnN1YnN0R3JvdXAgIT0gTlVMTCkgJiYgKCF0b3BMZXZlbCkpIHsKCS8qIDMuMy42IDogMyAqLwoJLyoKCSAqIFRPRE86IFRoaXMgc2VlbXMgdG8gYmUgcmVkdW5kYW50LCBzaW5jZSB0aGUgc2NoZW1hIGZvciBzY2hlbWFzCgkgKiBhbHJlYWR5IHByb2hpYml0cyB0aGUgdXNlIG9mIHRoZSAic3Vic3RpdHV0aW9uR3JvdXAiIGF0dHJpYnV0ZQoJICogaW4gbG9jYWwgZWxlbWVudCBkZWNsYXJhdGlvbnMuCgkgKi8KICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFQX0lOVkFMSURfQVRUUl9DT01CSU5BVElPTiwKCSAgICAgICAgICAgICAgIkVsZW1lbnQgZGVjbGFyYXRpb24gJXM6IHN1YnN0aXR1dGlvbkdyb3VwIGlzIGFsbG93ZWQgIgoJCSAgICAgICJvbiB0b3AtbGV2ZWwgZGVjbGFyYXRpb25zIG9ubHlcbiIsIHJldC0+bmFtZSwgTlVMTCk7CgkKICAgIH0KICAgIGZpeGVkID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiZml4ZWQiKTsKICAgIHJldC0+bWluT2NjdXJzID0geG1sR2V0TWluT2NjdXJzKGN0eHQsIG5vZGUpOwogICAgcmV0LT5tYXhPY2N1cnMgPSB4bWxHZXRNYXhPY2N1cnMoY3R4dCwgbm9kZSk7CgogICAgcmV0LT52YWx1ZSA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImRlZmF1bHQiKTsKICAgIGlmICgocmV0LT52YWx1ZSAhPSBOVUxMKSAmJiAoZml4ZWQgIT0gTlVMTCkpIHsKCS8qIDMuMy4zIDogMSAKCSAqIGRlZmF1bHQgYW5kIGZpeGVkIG11c3Qgbm90IGJvdGggYmUgcHJlc2VudC4gCgkgKi8KICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwgWE1MX1NDSEVNQVBfRUxFTV9ERUZBVUxUX0ZJWEVELAogICAgICAgICAgICAgICAgICAgICAgICJFbGVtZW50ICVzIGhhcyBib3RoIGRlZmF1bHQgYW5kIGZpeGVkXG4iLAoJCSAgICAgICByZXQtPm5hbWUsIE5VTEwpOwogICAgfSBlbHNlIGlmIChmaXhlZCAhPSBOVUxMKSB7CiAgICAgICAgcmV0LT5mbGFncyB8PSBYTUxfU0NIRU1BU19FTEVNX0ZJWEVEOwogICAgICAgIHJldC0+dmFsdWUgPSBmaXhlZDsKICAgIH0KCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHJldC0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIAogICAgaWYgKHJlZiAhPSBOVUxMKSB7CgkvKiAzLjMuMyAoMi4yKSAqLyAKCXdoaWxlIChjaGlsZCAhPSBOVUxMKSB7CgkgICAgaWYgKChJU19TQ0hFTUEoY2hpbGQsICJjb21wbGV4VHlwZSIpKSB8fAoJCShJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikpIHx8CgkJKElTX1NDSEVNQShjaGlsZCwgInVuaXF1ZSIpKSB8fAoJICAgICAgICAoSVNfU0NIRU1BKGNoaWxkLCAia2V5IikpIHx8IAoJCShJU19TQ0hFTUEoY2hpbGQsICJrZXlyZWYiKSkpIHsKCgkJeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsIFhNTF9TQ0hFTUFQX1JFRl9BTkRfQ09OVEVOVCwKCQkgICAgICAgICAgICAgICAiRWxlbWVudCBkZWNsYXJhdGlvbiAlczogb25seSBhbm5vdGF0aW9uIGlzICIKCQkJICAgICAgICJhbGxvd2VkIGFzIGNvbnRlbnQgaW4gYWRkaXRpb24gdG8gcmVmXG4iLAoJCQkgICAgICAgcmV0LT5uYW1lLCBOVUxMKTsKCSAgICB9IGVsc2UgewoJCXhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCBYTUxfU0NIRU1BUF9VTktOT1dOX0VMRU1fQ0hJTEQsCgkJICAgICAgICAgICAiZWxlbWVudCAlcyBoYXMgdW5leHBlY3RlZCBjb250ZW50XG4iLCBuYW1lLCBOVUxMKTsKCSAgICB9CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KICAgIH0gZWxzZSB7CglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiY29tcGxleFR5cGUiKSkgewoJICAgIC8qIDMuMy4zIDogMyAKCSAgICAgKiB0eXBlIGFuZCBlaXRoZXIgPHNpbXBsZVR5cGU+IG9yIDxjb21wbGV4VHlwZT4gYXJlIG11dHVhbGx5CgkgICAgICogZXhjbHVzaXZlIAoJICAgICAqLwoJICAgIGlmIChyZXQtPm5hbWVkVHlwZSAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsCgkJCSAgICAgICBYTUxfU0NIRU1BUF9JTlZBTElEX0FUVFJfSU5MSU5FX0NPTUJJTkFUSU9OLAoJCSAgICAgICAgICAgICAgICJFbGVtZW50IGRlY2xhcmF0aW9uICVzIGhhcyBib3RoIFwidHlwZVwiICIKCQkJICAgICAgICJhbmQgYSBsb2NhbCBjb21wbGV4IHR5cGVcbiIsCgkJCSAgICAgICByZXQtPm5hbWUsIE5VTEwpOwoJICAgIH0gZWxzZQoJCXJldC0+c3VidHlwZXMgPSB4bWxTY2hlbWFQYXJzZUNvbXBsZXhUeXBlKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgewoJICAgIC8qIDMuMy4zIDogMyAKCSAgICAgKiB0eXBlIGFuZCBlaXRoZXIgPHNpbXBsZVR5cGU+IG9yIDxjb21wbGV4VHlwZT4gYXJlCgkgICAgICogbXV0dWFsbHkgZXhjbHVzaXZlIAoJICAgICAqLwoJICAgIGlmIChyZXQtPm5hbWVkVHlwZSAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsCgkJCSAgICAgICBYTUxfU0NIRU1BUF9JTlZBTElEX0FUVFJfSU5MSU5FX0NPTUJJTkFUSU9OLAoJCSAgICAgICAgICAgICAgICJFbGVtZW50IGRlY2xhcmF0aW9uICVzIGhhcyBib3RoIFwidHlwZVwiICIKCQkJICAgICAgICJhbmQgYSBsb2NhbCBzaW1wbGUgdHlwZVxuIiwKCQkJICAgICAgIHJldC0+bmFtZSwgTlVMTCk7CgkgICAgfSBlbHNlCgkJcmV0LT5zdWJ0eXBlcyA9IHhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQogICAgCgl3aGlsZSAoKElTX1NDSEVNQShjaGlsZCwgInVuaXF1ZSIpKSB8fAoJICAgICAgIChJU19TQ0hFTUEoY2hpbGQsICJrZXkiKSkgfHwgKElTX1NDSEVNQShjaGlsZCwgImtleXJlZiIpKSkgewoJICAgIFRPRE8gY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KCWlmIChjaGlsZCAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsIFhNTF9TQ0hFTUFQX1VOS05PV05fRUxFTV9DSElMRCwKCQkgICAgICAgICAgICJlbGVtZW50ICVzIGhhcyB1bmV4cGVjdGVkIGNvbnRlbnRcbiIsIG5hbWUsIE5VTEwpOwoJfQogICAgfQoKICAgIGN0eHQtPmNvbnRhaW5lciA9IG9sZGNvbnRhaW5lcjsKICAgIHJldHVybiAocmV0KTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlVW5pb246CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIFVuaW9uIGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAgICAgICAgIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VVbmlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIHN1YnR5cGUsIGxhc3QgPSBOVUxMOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxDaGFyIG5hbWVbMzBdOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgoKICAgIHNucHJpbnRmKChjaGFyICopIG5hbWUsIDMwLCAidW5pb24gJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKICAgIHR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgbmFtZSwgTlVMTCk7CiAgICBpZiAodHlwZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX1VOSU9OOwogICAgdHlwZS0+bm9kZSA9IG5vZGU7CiAgICB0eXBlLT5pZCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImlkIik7CiAgICB0eXBlLT5iYXNlID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAibWVtYmVyVHlwZXMiKTsKCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHR5cGUtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICB3aGlsZSAoSVNfU0NIRU1BKGNoaWxkLCAic2ltcGxlVHlwZSIpKSB7CiAgICAgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQogICAgICAgICAgICB4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CiAgICAgICAgaWYgKHN1YnR5cGUgIT0gTlVMTCkgewogICAgICAgICAgICBpZiAobGFzdCA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7CiAgICAgICAgICAgICAgICBsYXN0ID0gc3VidHlwZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGxhc3QtPm5leHQgPSBzdWJ0eXBlOwogICAgICAgICAgICAgICAgbGFzdCA9IHN1YnR5cGU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGFzdC0+bmV4dCA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCBYTUxfU0NIRU1BUF9VTktOT1dOX1VOSU9OX0NISUxELAogICAgICAgICAgICAgICAgICAgICAgICJVbmlvbiAlcyBoYXMgdW5leHBlY3RlZCBjb250ZW50XG4iLCB0eXBlLT5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgfQogICAgcmV0dXJuICh0eXBlKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlTGlzdDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgTGlzdCBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBpbXByb3BlciBhbmQKICogICAgICAgICAxIGluIGNhc2Ugb2Ygc3VjY2Vzcy4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlTGlzdCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgc3VidHlwZTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQ2hhciBuYW1lWzMwXTsKICAgIHhtbEF0dHJQdHIgYXR0cjsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHNucHJpbnRmKChjaGFyICopIG5hbWUsIDMwLCAibGlzdCAlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBOVUxMKTsKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHR5cGUtPm5vZGUgPSBub2RlOwogICAgdHlwZS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9MSVNUOwogICAgdHlwZS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwoKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgdHlwZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIC8qCiAgICAqIENoZWNrIHR5cGUgb2YgIml0ZW1UeXBlIi4gCiAgICAqLwogICAgYXR0ciA9IHhtbFNjaGVtYUdldFByb3BOb2RlKG5vZGUsIEJBRF9DQVNUICJpdGVtVHlwZSIpOwogICAgaWYgKGF0dHIgIT0gTlVMTCkgewoJdHlwZS0+YmFzZSA9IHhtbEdldFFOYW1lUHJvcChjdHh0LCBub2RlLCAiaXRlbVR5cGUiLCAmKHR5cGUtPmJhc2VOcykpOwoJeG1sU2NoZW1hUGFyc2VTY2hlbWFBdHRyVmFsdWUoY3R4dCwgYXR0ciwgCgkgICAgeG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfUU5BTUUpKTsKCQogICAgfSAgICAKICAgIHN1YnR5cGUgPSBOVUxMOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgewkKCXN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKCSAgICB4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7Cgl0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7CgkvKgoJKiBUaGlzIGlzIGEgaGFjayB0byBzYXZlIHRoZSBpbmZvcm1hdGlvbiB0aGF0IGEgbG9jYWwKCSogc2ltcGxlIHR5cGUgd2FzIGRlZmluZWQuCgkqLwoJdHlwZS0+YmFzZVR5cGUgPSBzdWJ0eXBlOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7ICAgICAgICAKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsIFhNTF9TQ0hFTUFQX1VOS05PV05fTElTVF9DSElMRCwKICAgICAgICAgICAgICAgICAgICAgICAiTGlzdCAlcyBoYXMgdW5leHBlY3RlZCBjb250ZW50XG4iLCB0eXBlLT5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgfQogICAgcmV0dXJuICh0eXBlKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlU2ltcGxlVHlwZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgU2ltcGxlIFR5cGUgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciwgMCBpZiB0aGUgZGVjbGFyYXRpb24gaXMgaW1wcm9wZXIgYW5kCiAqICAgICAgICAgMSBpbiBjYXNlIG9mIHN1Y2Nlc3MuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLCBpbnQgdG9wTGV2ZWwpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgc3VidHlwZSwgY3R4dFR5cGU7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIGNvbnN0IHhtbENoYXIgKnByb3BWYWw7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBjdHh0VHlwZSA9IGN0eHQtPmN0eHRUeXBlOwogICAgcHJvcFZhbCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgIm5hbWUiKTsKICAgIGlmIChwcm9wVmFsID09IE5VTEwpIHsKICAgICAgICBjaGFyIGJ1ZlsxMDBdOwoKICAgICAgICBzbnByaW50ZihidWYsIDk5LCAic2ltcGxlVHlwZSAlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwoJdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCAoY29uc3QgeG1sQ2hhciAqKWJ1ZiwgTlVMTCk7CiAgICB9IGVsc2UgewkKCWlmICghdG9wTGV2ZWwpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIG5vZGUsIAoJCVhNTF9TQ0hFTUFQX1M0U19BVFRSX05PVF9BTExPV0VELAoJCSJUaGUgYXR0cmlidXRlIFwibmFtZVwiIGlzIG5vdCBhbGxvd2VkIG9uIGEgbG9jYWwgIgoJCSJzaW1wbGVUeXBlIGRlZmluaXRpb25cbiIsCgkJcHJvcFZhbCwgTlVMTCk7CgkgICAgcmV0dXJuIChOVUxMKTsKCX0KCS8qCgkqICJuYW1lIiBoYXMgdG8gYmUgb2YgdHlwZSBOQ05hbWUuIAoJKiBUT0RPOiBBY3R1YWxseSB0aGlzIHNob3VsZCBiZSB2YWxpZGF0ZWQgYnkgdGhlIHNjaGVtYSBmb3Igc2NoZW1hcy4KCSovCglpZiAoeG1sU2NoZW1hUGFyc2VTY2hlbWFBdHRyVmFsdWUoY3R4dCwKCSAgICB4bWxTY2hlbWFHZXRQcm9wTm9kZShub2RlLCBCQURfQ0FTVCAibmFtZSIpLAoJICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX05DTkFNRSkpICE9IDApCgkgICAgcmV0dXJuIChOVUxMKTsJCgl0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsIHByb3BWYWwsIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlKTsKICAgIH0KICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHR5cGUtPm5vZGUgPSBub2RlOwogICAgdHlwZS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU7CiAgICBpZiAodG9wTGV2ZWwpIAogICAgICAgIHR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfR0xPQkFMOwogICAgdHlwZS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwogICAgcHJvcFZhbCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImZpbmFsIik7CiAgICBpZiAocHJvcFZhbCA9PSBOVUxMKSB7Cgl0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX0RFRkFVTFQ7CiAgICB9IGVsc2UgewoJaWYgKHhtbFN0ckVxdWFsKHByb3BWYWwsIEJBRF9DQVNUICIjYWxsIikpIHsKCSAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OOyAKCSAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1VOSU9OOyAKCSAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX0xJU1Q7IAoJfSBlbHNlIHsKCSAgICBjb25zdCB4bWxDaGFyICplbmQsICpjdXIgPSBwcm9wVmFsOwoJICAgIHhtbENoYXIgKml0ZW07CgkgICAgCgkgICAgZG8gewoJCXdoaWxlIChJU19CTEFOS19DSCgqY3VyKSkKCQkgICAgY3VyKys7CgkJZW5kID0gY3VyOwoJCXdoaWxlICgoKmVuZCAhPSAwKSAmJiAoIShJU19CTEFOS19DSCgqZW5kKSkpKQoJCSAgICBlbmQrKzsKCQlpZiAoZW5kID09IGN1cikKCQkgICAgYnJlYWs7CgkJaXRlbSA9IHhtbFN0cm5kdXAoY3VyLCBlbmQgLSBjdXIpOyAgICAJICAgIAoJCWlmICh4bWxTdHJFcXVhbChpdGVtLCBCQURfQ0FTVCAicmVzdHJpY3Rpb24iKSkgewoJCSAgICBpZiAoKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTikgPT0gMCkKCQkJdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTjsgCgkJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChpdGVtLCBCQURfQ0FTVCAibGlzdCIpKSB7CgkJICAgIGlmICgodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX0xJU1QpID09IDApCgkJCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfTElTVDsgCgkJfSBlbHNlIGlmICh4bWxTdHJFcXVhbChpdGVtLCBCQURfQ0FTVCAidW5pb24iKSkgewoJCSAgICBpZiAoKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9VTklPTikgPT0gMCkKCQkJdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9VTklPTjsgCgkJfSBlbHNlIHsKCQkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCAKCQkJWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCQkiVGhlIGF0dHJpYnV0ZSBcImZpbmFsXCIgb2YgdHlwZSBcIiVzXCIgIgoJCQkiaGFzIGFuIGludmFsaWQgdmFsdWVcbiIsCgkJCXR5cGUtPm5hbWUsIE5VTEwpOwkJCSAgICAJCSAgICAKCQl9CgkJaWYgKGl0ZW0gIT0gTlVMTCkKCQkgICAgeG1sRnJlZShpdGVtKTsKCQljdXIgPSBlbmQ7CgkgICAgfSB3aGlsZSAoKmN1ciAhPSAwKTsgCgl9CiAgICB9CiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHR5cGUtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBzdWJ0eXBlID0gTlVMTDsKICAgIGN0eHQtPmN0eHRUeXBlID0gdHlwZTsgCiAgICBjdHh0LT5wYXJlbnRJdGVtID0gdHlwZTsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJyZXN0cmljdGlvbiIpKSB7CiAgICAgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQogICAgICAgICAgICB4bWxTY2hlbWFQYXJzZVJlc3RyaWN0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImxpc3QiKSkgewogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VMaXN0KGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInVuaW9uIikpIHsKICAgICAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCiAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlVW5pb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsCiAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfUzRTX0VMRU1fTk9UX0FMTE9XRUQsCiAgICAgICAgICAgICAgICAgICAgICAgIlNpbXBsZVR5cGUgXCIlc1wiIGhhcyB1bmV4cGVjdGVkIGNvbnRlbnRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+bmFtZSwgTlVMTCk7CiAgICB9IGVsc2UgewoJaWYgKHN1YnR5cGUgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLAoJCVhNTF9TQ0hFTUFQX1M0U19FTEVNX01JU1NJTkcsCgkJIlNpbXBsZVR5cGUgXCIlc1wiIG11c3QgaGF2ZSBvbmUgb2YgPHJlc3RyaWN0aW9uPiBvciAiCgkJIjxsaXN0PiBvciA8dW5pb24+IGFzIGEgY2hpbGRcbiIsCgkJdHlwZS0+bmFtZSwgTlVMTCk7Cgl9CiAgICB9CgogICAgY3R4dC0+Y3R4dFR5cGUgPSBjdHh0VHlwZTsKCiAgICByZXR1cm4gKHR5cGUpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlR3JvdXA6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEdyb3VwIGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IsIDAgaWYgdGhlIGRlY2xhcmF0aW9uIGlzIGltcHJvcGVyIGFuZAogKiAgICAgICAgIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VHcm91cCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlLCBpbnQgdG9wTGV2ZWwpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgc3VidHlwZTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgY29uc3QgeG1sQ2hhciAqbmFtZTsKICAgIGNvbnN0IHhtbENoYXIgKnJlZiA9IE5VTEwsICpyZWZOcyA9IE5VTEw7CiAgICBjaGFyIGJ1ZlsxMDBdOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgoKICAgIG5hbWUgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJuYW1lIik7CiAgICBpZiAobmFtZSA9PSBOVUxMKSB7CiAgICAgICAgcmVmID0geG1sR2V0UU5hbWVQcm9wKGN0eHQsIG5vZGUsICJyZWYiLCAmcmVmTnMpOwogICAgICAgIGlmIChyZWYgPT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfR1JPVVBfTk9OQU1FX05PUkVGLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiR3JvdXAgaGFzIG5vIG5hbWUgbm9yIHJlZlxuIiwgTlVMTCwgTlVMTCk7CiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAgICAgfQoJaWYgKHJlZk5zID09IE5VTEwpCgkgICAgcmVmTnMgPSBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZTsKICAgICAgICBzbnByaW50ZihidWYsIDk5LCAiYW5vbmdyb3VwICVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICAgICAgbmFtZSA9IChjb25zdCB4bWxDaGFyICopIGJ1ZjsKICAgIH0KICAgIHR5cGUgPSB4bWxTY2hlbWFBZGRHcm91cChjdHh0LCBzY2hlbWEsIG5hbWUpOwogICAgaWYgKHR5cGUgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgdHlwZS0+bm9kZSA9IG5vZGU7CiAgICB0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0dST1VQOwogICAgaWYgKHRvcExldmVsKSAKICAgICAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX0dMT0JBTDsKICAgIHR5cGUtPmlkID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiaWQiKTsKICAgIHR5cGUtPnJlZiA9IHJlZjsKICAgIHR5cGUtPnJlZk5zID0gcmVmTnM7CiAgICB0eXBlLT5taW5PY2N1cnMgPSB4bWxHZXRNaW5PY2N1cnMoY3R4dCwgbm9kZSk7CiAgICB0eXBlLT5tYXhPY2N1cnMgPSB4bWxHZXRNYXhPY2N1cnMoY3R4dCwgbm9kZSk7CgogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgc3VidHlwZSA9IE5VTEw7CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYWxsIikpIHsKICAgICAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCiAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlQWxsKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB7CiAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlQ2hvaWNlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInNlcXVlbmNlIikpIHsKICAgICAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCiAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlU2VxdWVuY2UoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChzdWJ0eXBlICE9IE5VTEwpCiAgICAgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwgWE1MX1NDSEVNQVBfVU5LTk9XTl9HUk9VUF9DSElMRCwKICAgICAgICAgICAgICAgICAgICAgICAiR3JvdXAgJXMgaGFzIHVuZXhwZWN0ZWQgY29udGVudFxuIiwgdHlwZS0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgIH0KCiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VBbGw6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEFsbCBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBpbXByb3BlciBhbmQKICogICAgICAgICAxIGluIGNhc2Ugb2Ygc3VjY2Vzcy4KICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlQWxsKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIHN1YnR5cGUsIGxhc3QgPSBOVUxMOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxDaGFyIG5hbWVbMzBdOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgoKICAgIHNucHJpbnRmKChjaGFyICopIG5hbWUsIDMwLCAiYWxsJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKICAgIHR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgbmFtZSwgTlVMTCk7CiAgICBpZiAodHlwZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB0eXBlLT5ub2RlID0gbm9kZTsKICAgIHR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQUxMOwogICAgdHlwZS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwogICAgdHlwZS0+bWluT2NjdXJzID0geG1sR2V0TWluT2NjdXJzKGN0eHQsIG5vZGUpOwogICAgaWYgKHR5cGUtPm1pbk9jY3VycyA+IDEpCiAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BUF9JTlZBTElEX01JTk9DQ1VSUywKCSAgICAiaW52YWxpZCB2YWx1ZSBmb3IgbWluT2NjdXJzIChtdXN0IGJlIDAgb3IgMSlcbiIsIE5VTEwsIE5VTEwpOwogICAgdHlwZS0+bWF4T2NjdXJzID0geG1sR2V0TWF4T2NjdXJzKGN0eHQsIG5vZGUpOwogICAgaWYgKHR5cGUtPm1heE9jY3VycyA+IDEpCiAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BUF9JTlZBTElEX01BWE9DQ1VSUywKCSAgICAiaW52YWxpZCB2YWx1ZSBmb3IgbWF4T2NjdXJzIChtdXN0IGJlIDAgb3IgMSlcbiIsIE5VTEwsIE5VTEwpOwoKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgdHlwZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHdoaWxlIChJU19TQ0hFTUEoY2hpbGQsICJlbGVtZW50IikpIHsKICAgICAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCiAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlRWxlbWVudChjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKICAgICAgICBpZiAoc3VidHlwZSAhPSBOVUxMKSB7CgkgICAgaWYgKHN1YnR5cGUtPm1pbk9jY3VycyA+IDEpCiAgICAgICAgICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGNoaWxkLCBYTUxfU0NIRU1BUF9JTlZBTElEX01JTk9DQ1VSUywKCSAgICAgICAgICAgICAiaW52YWxpZCB2YWx1ZSBmb3IgbWluT2NjdXJzIChtdXN0IGJlIDAgb3IgMSlcbiIsCgkJICAgICBOVUxMLCBOVUxMKTsKCSAgICBpZiAoc3VidHlwZS0+bWF4T2NjdXJzID4gMSkKCSAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBjaGlsZCwgWE1MX1NDSEVNQVBfSU5WQUxJRF9NQVhPQ0NVUlMsCgkgICAgICAgICAgICAgImludmFsaWQgdmFsdWUgZm9yIG1heE9jY3VycyAobXVzdCBiZSAwIG9yIDEpXG4iLAoJCSAgICAgTlVMTCwgTlVMTCk7CiAgICAgICAgICAgIGlmIChsYXN0ID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKICAgICAgICAgICAgICAgIGxhc3QgPSBzdWJ0eXBlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbGFzdC0+bmV4dCA9IHN1YnR5cGU7CiAgICAgICAgICAgICAgICBsYXN0ID0gc3VidHlwZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBsYXN0LT5uZXh0ID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsIFhNTF9TQ0hFTUFQX1VOS05PV05fQUxMX0NISUxELAogICAgICAgICAgICAgICAgICAgICAgICJBbGwgJXMgaGFzIHVuZXhwZWN0ZWQgY29udGVudFxuIiwgdHlwZS0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgIH0KCiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hSW1wb3J0U2NoZW1hCiAqIAogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hTG9jYXRpb246ICBhbiBVUkkgZGVmaW5pbmcgd2hlcmUgdG8gZmluZCB0aGUgaW1wb3J0ZWQgc2NoZW1hCiAqCiAqIGltcG9ydCBhIFhNTCBzY2hlbWEKICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIC0xIGluIGNhc2Ugb2YgZXJyb3IgYW5kIDEgaW4gY2FzZSBvZiBzdWNjZXNzLgogKi8Kc3RhdGljIHhtbFNjaGVtYUltcG9ydFB0cgp4bWxTY2hlbWFJbXBvcnRTY2hlbWEoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqc2NoZW1hTG9jYXRpb24pCnsKICAgIHhtbFNjaGVtYUltcG9ydFB0ciBpbXBvcnQ7CiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIG5ld2N0eHQ7CgogICAgbmV3Y3R4dCA9ICh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVBhcnNlckN0eHQpKTsKICAgIGlmIChuZXdjdHh0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIHNjaGVtYSBwYXJzZXIgY29udGV4dCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KG5ld2N0eHQsIDAsIHNpemVvZih4bWxTY2hlbWFQYXJzZXJDdHh0KSk7CiAgICAvKiBLZWVwIHRoZSBzYW1lIGRpY3Rpb25uYXJ5IGZvciBwYXJzaW5nLCByZWFsbHkgKi8KICAgIHhtbERpY3RSZWZlcmVuY2UoY3R4dC0+ZGljdCk7CiAgICBuZXdjdHh0LT5kaWN0ID0gY3R4dC0+ZGljdDsKICAgIG5ld2N0eHQtPmluY2x1ZGVzID0gMDsKICAgIG5ld2N0eHQtPlVSTCA9IHhtbERpY3RMb29rdXAobmV3Y3R4dC0+ZGljdCwgc2NoZW1hTG9jYXRpb24sIC0xKTsKCiAgICB4bWxTY2hlbWFTZXRQYXJzZXJFcnJvcnMobmV3Y3R4dCwgY3R4dC0+ZXJyb3IsIGN0eHQtPndhcm5pbmcsCgkgICAgICAgICAgICAgICAgICAgICBjdHh0LT51c2VyRGF0YSk7CgogICAgaW1wb3J0ID0gKHhtbFNjaGVtYUltcG9ydCopIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hSW1wb3J0KSk7CiAgICBpZiAoaW1wb3J0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIGltcG9ydGVkIHNjaGVtYSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKCXhtbFNjaGVtYUZyZWVQYXJzZXJDdHh0KG5ld2N0eHQpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CgogICAgbWVtc2V0KGltcG9ydCwgMCwgc2l6ZW9mKHhtbFNjaGVtYUltcG9ydCkpOwogICAgaW1wb3J0LT5zY2hlbWFMb2NhdGlvbiA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgc2NoZW1hTG9jYXRpb24sIC0xKTsKICAgIGltcG9ydC0+c2NoZW1hID0geG1sU2NoZW1hUGFyc2UobmV3Y3R4dCk7CgogICAgaWYgKGltcG9ydC0+c2NoZW1hID09IE5VTEwpIHsKICAgICAgICAvKiBGSVhNRSB1c2UgYW5vdGhlciBlcnJvciBlbnVtIGhlcmUgPyAqLwogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgTlVMTCwgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJICAgICAgICAgICAgICAiZmFpbGVkIHRvIGltcG9ydCBzY2hlbWEgYXQgbG9jYXRpb24gJXNcbiIsCgkJICAgICAgc2NoZW1hTG9jYXRpb24sIE5VTEwpOwoKCXhtbFNjaGVtYUZyZWVQYXJzZXJDdHh0KG5ld2N0eHQpOwoJaWYgKGltcG9ydC0+c2NoZW1hTG9jYXRpb24gIT0gTlVMTCkKCSAgICB4bWxGcmVlKCh4bWxDaGFyICopaW1wb3J0LT5zY2hlbWFMb2NhdGlvbik7Cgl4bWxGcmVlKGltcG9ydCk7CglyZXR1cm4gTlVMTDsKICAgIH0KCiAgICB4bWxTY2hlbWFGcmVlUGFyc2VyQ3R4dChuZXdjdHh0KTsKICAgIHJldHVybiBpbXBvcnQ7Cn0KCgovKioKICogeG1sU2NoZW1hUGFyc2VJbXBvcnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIEltcG9ydCBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBpbXByb3BlciBhbmQKICogICAgICAgICAxIGluIGNhc2Ugb2Ygc3VjY2Vzcy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VJbXBvcnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sU2NoZW1hSW1wb3J0UHRyIGltcG9ydCA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lc3BhY2U7CiAgICBjb25zdCB4bWxDaGFyICpzY2hlbWFMb2NhdGlvbjsKICAgIGNvbnN0IHhtbENoYXIgKnByZXZpb3VzOwogICAgeG1sVVJJUHRyIGNoZWNrOwoKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKC0xKTsKCiAgICBuYW1lc3BhY2UgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJuYW1lc3BhY2UiKTsKICAgIGlmIChuYW1lc3BhY2UgIT0gTlVMTCkgewogICAgICAgIGNoZWNrID0geG1sUGFyc2VVUkkoKGNvbnN0IGNoYXIgKikgbmFtZXNwYWNlKTsKICAgICAgICBpZiAoY2hlY2sgPT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfSU1QT1JUX05BTUVTUEFDRV9OT1RfVVJJLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiSW1wb3J0IG5hbWVzcGFjZSBhdHRyaWJ1dGUgaXMgbm90IGFuIFVSSTogJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSwgTlVMTCk7CiAgICAgICAgICAgIHJldHVybiAoLTEpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHhtbEZyZWVVUkkoY2hlY2spOwogICAgICAgIH0KICAgIH0KICAgIHNjaGVtYUxvY2F0aW9uID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAic2NoZW1hTG9jYXRpb24iKTsKICAgIGlmIChzY2hlbWFMb2NhdGlvbiAhPSBOVUxMKSB7CiAgICAgICAgeG1sQ2hhciAqYmFzZSA9IE5VTEw7CiAgICAgICAgeG1sQ2hhciAqVVJJID0gTlVMTDsKICAgICAgICBjaGVjayA9IHhtbFBhcnNlVVJJKChjb25zdCBjaGFyICopIHNjaGVtYUxvY2F0aW9uKTsKICAgICAgICBpZiAoY2hlY2sgPT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfSU1QT1JUX1NDSEVNQV9OT1RfVVJJLAogICAgICAgICAgICAgICAgICAgICAgICAgICAiSW1wb3J0IHNjaGVtYUxvY2F0aW9uIGF0dHJpYnV0ZSBpcyBub3QgYW4gVVJJOiAlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2NoZW1hTG9jYXRpb24sIE5VTEwpOwogICAgICAgICAgICByZXR1cm4gKC0xKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB4bWxGcmVlVVJJKGNoZWNrKTsKICAgICAgICB9CgliYXNlID0geG1sTm9kZUdldEJhc2Uobm9kZS0+ZG9jLCBub2RlKTsKCWlmIChiYXNlID09IE5VTEwpIHsKCSAgICBVUkkgPSB4bWxCdWlsZFVSSShzY2hlbWFMb2NhdGlvbiwgbm9kZS0+ZG9jLT5VUkwpOwoJfSBlbHNlIHsKCSAgICBVUkkgPSB4bWxCdWlsZFVSSShzY2hlbWFMb2NhdGlvbiwgYmFzZSk7CgkgICAgeG1sRnJlZShiYXNlKTsKCX0KCWlmIChVUkkgIT0gTlVMTCkgewoJICAgIHNjaGVtYUxvY2F0aW9uID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBVUkksIC0xKTsKCSAgICB4bWxGcmVlKFVSSSk7Cgl9CiAgICB9CiAgICBpZiAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cyA9PSBOVUxMKSB7CiAgICAgICAgc2NoZW1hLT5zY2hlbWFzSW1wb3J0cyA9IHhtbEhhc2hDcmVhdGUoMTApOwogICAgICAgIGlmIChzY2hlbWEtPnNjaGVtYXNJbXBvcnRzID09IE5VTEwpIHsKICAgICAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX0ZBSUxFRF9CVUlMRF9JTVBPUlQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJJbnRlcm5hbDogZmFpbGVkIHRvIGJ1aWxkIGltcG9ydCB0YWJsZVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCk7CiAgICAgICAgICAgIHJldHVybiAoLTEpOwogICAgICAgIH0KICAgIH0KICAgIGlmIChuYW1lc3BhY2UgPT0gTlVMTCkgewogICAgICAgIGltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BU19ERUZBVUxUX05BTUVTUEFDRSk7CglpZiAoaW1wb3J0ICE9IE5VTEwpCiAgICAgICAgICAgIHByZXZpb3VzID0gaW1wb3J0LT5zY2hlbWFMb2NhdGlvbjsKCWVsc2UKCSAgICBwcmV2aW91cyA9IE5VTEw7CgogICAgICAgIGlmIChzY2hlbWFMb2NhdGlvbiAhPSBOVUxMKSB7CiAgICAgICAgICAgIGlmIChwcmV2aW91cyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICBpZiAoIXhtbFN0ckVxdWFsKHNjaGVtYUxvY2F0aW9uLCBwcmV2aW91cykpIHsKICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9JTVBPUlRfUkVERUZJTkVfTlNOQU1FLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZWRlZmluaW5nIGltcG9ydCBmb3IgZGVmYXVsdCBuYW1lc3BhY2UgIgoJCQkJICAgIndpdGggYSBkaWZmZXJlbnQgVVJJOiAlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY2hlbWFMb2NhdGlvbiwgTlVMTCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CgkgICAgICAgIGltcG9ydCA9IHhtbFNjaGVtYUltcG9ydFNjaGVtYShjdHh0LCBzY2hlbWFMb2NhdGlvbik7CgkJaWYgKGltcG9ydCA9PSBOVUxMKSB7CgkJICAgIHJldHVybiAoLTEpOwoJCX0KICAgICAgICAgICAgICAgIHhtbEhhc2hBZGRFbnRyeShzY2hlbWEtPnNjaGVtYXNJbXBvcnRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFTX0RFRkFVTFRfTkFNRVNQQUNFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltcG9ydCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIGltcG9ydCA9IHhtbEhhc2hMb29rdXAoc2NoZW1hLT5zY2hlbWFzSW1wb3J0cywgbmFtZXNwYWNlKTsKCWlmIChpbXBvcnQgIT0gTlVMTCkKCSAgICBwcmV2aW91cyA9IGltcG9ydC0+c2NoZW1hTG9jYXRpb247CgllbHNlCgkgICAgcHJldmlvdXMgPSBOVUxMOwoKICAgICAgICBpZiAoc2NoZW1hTG9jYXRpb24gIT0gTlVMTCkgewogICAgICAgICAgICBpZiAocHJldmlvdXMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgaWYgKCF4bWxTdHJFcXVhbChzY2hlbWFMb2NhdGlvbiwgcHJldmlvdXMpKSB7CiAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfSU1QT1JUX1JFREVGSU5FX05TTkFNRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUmVkZWZpbmluZyBpbXBvcnQgZm9yIG5hbWVzcGFjZSAlcyB3aXRoICIKCQkJCSAgICJhIGRpZmZlcmVudCBVUkk6ICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzcGFjZSwgc2NoZW1hTG9jYXRpb24pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewoJICAgICAgICBpbXBvcnQgPSB4bWxTY2hlbWFJbXBvcnRTY2hlbWEoY3R4dCwgc2NoZW1hTG9jYXRpb24pOwoJCWlmIChpbXBvcnQgPT0gTlVMTCkgewoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkJaWYgKCF4bWxTdHJFcXVhbChpbXBvcnQtPnNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlLCBuYW1lc3BhY2UpKSB7CgkJICAgIGlmIChuYW1lc3BhY2UgPT0gTlVMTCkgewoJCQlpZiAoaW1wb3J0LT5zY2hlbWEtPnRhcmdldE5hbWVzcGFjZSAhPSBOVUxMKSB7CgkJCSAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8zXzIsCgkJCSAgICAiVGhlcmUgaXMgbm8gbmFtZXNwYWNlIGF0dHJpYnV0ZSBvbiB0aGUgPGltcG9ydD4gIgoJCQkgICAgImVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSwgc28gdGhlIGltcG9ydGVkIGRvY3VtZW50ICIKCQkJICAgICJtdXN0IGhhdmUgbm8gdGFyZ2V0TmFtZXNwYWNlIGF0dHJpYnV0ZS5cbiIsIAoJCQkgICAgTlVMTCwgTlVMTCk7IAoJCQl9CgkJICAgIH0gZWxzZSB7CgkJCWlmIChpbXBvcnQtPnNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlICE9IE5VTEwpIHsKCQkJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVBfU1JDX0lNUE9SVF8zXzEsCgkJCQkiVGhlIG5hbWVzcGFjZSBhdHRyaWJ1dGUgXCIlc1wiIG9mIGFuIDxpbXBvcnQ+ICIKCQkJCSJlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gbXVzdCBiZSBpZGVudGljYWwgdG8gdGhlICIKCQkJCSJ0YXJnZXROYW1lc3BhY2UgYXR0cmlidXRlIFwiJXNcIiBvZiB0aGUgIgoJCQkJImltcG9ydGVkIGRvY3VtZW50LlxuIiwgCgkJCQluYW1lc3BhY2UsIGltcG9ydC0+c2NoZW1hLT50YXJnZXROYW1lc3BhY2UpOwoJCQl9IGVsc2UgewoJCQkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BUF9TUkNfSU1QT1JUXzNfMSwKCQkJCSJUaGUgbmFtZXNwYWNlIGF0dHJpYnV0ZSBvbiB0aGUgPGltcG9ydD4gIgoJCQkJImVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSwgcmVxdWlyZXMgdGhlIGltcG9ydGVkICIKCQkJCSJkb2N1bWVudCB0byBoYXZlIGEgdGFyZ2V0TmFtZXNwYWNlIGF0dHJpYnV0ZSAiCgkJCQkid2l0aCB0aGUgdmFsdWUgXCIlc1wiLlxuIiwgCgkJCQluYW1lc3BhY2UsIE5VTEwpOwoJCQl9CgkJICAgIH0KCQkgICAgeG1sU2NoZW1hRnJlZUltcG9ydChpbXBvcnQpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgogICAgICAgICAgICAgICAgeG1sSGFzaEFkZEVudHJ5KHNjaGVtYS0+c2NoZW1hc0ltcG9ydHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZXNwYWNlLCBpbXBvcnQpOwoJCQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICB3aGlsZSAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgLyoKICAgICAgICAgKiB0aGUgYW5ub3RhdGlvbnMgaGVyZSBhcmUgc2ltcGx5IGRpc2NhcmRlZCAuLi4KICAgICAgICAgKi8KICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwgWE1MX1NDSEVNQVBfVU5LTk9XTl9JTVBPUlRfQ0hJTEQsCiAgICAgICAgICAgICAgICAgICAgICAgIkltcG9ydCBoYXMgdW5leHBlY3RlZCBjb250ZW50XG4iLCBOVUxMLCBOVUxMKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KICAgIHJldHVybiAoMSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDbGVhbnVwRG9jOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIHRoZSByb290IG9mIHRoZSBkb2N1bWVudC4KICoKICogcmVtb3ZlcyB1bndhbnRlZCBub2RlcyBpbiBhIHNjaGVtYXMgZG9jdW1lbnQgdHJlZQogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2xlYW51cERvYyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgcm9vdCkKewogICAgeG1sTm9kZVB0ciBkZWxldGUsIGN1cjsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHJvb3QgPT0gTlVMTCkpIHJldHVybjsKCiAgICAvKgogICAgICogUmVtb3ZlIGFsbCB0aGUgYmxhbmsgdGV4dCBub2RlcwogICAgICovCiAgICBkZWxldGUgPSBOVUxMOwogICAgY3VyID0gcm9vdDsKICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewogICAgICAgIGlmIChkZWxldGUgIT0gTlVMTCkgewogICAgICAgICAgICB4bWxVbmxpbmtOb2RlKGRlbGV0ZSk7CiAgICAgICAgICAgIHhtbEZyZWVOb2RlKGRlbGV0ZSk7CiAgICAgICAgICAgIGRlbGV0ZSA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGlmIChjdXItPnR5cGUgPT0gWE1MX1RFWFRfTk9ERSkgewogICAgICAgICAgICBpZiAoSVNfQkxBTktfTk9ERShjdXIpKSB7CiAgICAgICAgICAgICAgICBpZiAoeG1sTm9kZUdldFNwYWNlUHJlc2VydmUoY3VyKSAhPSAxKSB7CiAgICAgICAgICAgICAgICAgICAgZGVsZXRlID0gY3VyOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmICgoY3VyLT50eXBlICE9IFhNTF9FTEVNRU5UX05PREUpICYmCiAgICAgICAgICAgICAgICAgICAoY3VyLT50eXBlICE9IFhNTF9DREFUQV9TRUNUSU9OX05PREUpKSB7CiAgICAgICAgICAgIGRlbGV0ZSA9IGN1cjsKICAgICAgICAgICAgZ290byBza2lwX2NoaWxkcmVuOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBTa2lwIHRvIG5leHQgbm9kZQogICAgICAgICAqLwogICAgICAgIGlmIChjdXItPmNoaWxkcmVuICE9IE5VTEwpIHsKICAgICAgICAgICAgaWYgKChjdXItPmNoaWxkcmVuLT50eXBlICE9IFhNTF9FTlRJVFlfREVDTCkgJiYKICAgICAgICAgICAgICAgIChjdXItPmNoaWxkcmVuLT50eXBlICE9IFhNTF9FTlRJVFlfUkVGX05PREUpICYmCiAgICAgICAgICAgICAgICAoY3VyLT5jaGlsZHJlbi0+dHlwZSAhPSBYTUxfRU5USVRZX05PREUpKSB7CiAgICAgICAgICAgICAgICBjdXIgPSBjdXItPmNoaWxkcmVuOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIHNraXBfY2hpbGRyZW46CiAgICAgICAgaWYgKGN1ci0+bmV4dCAhPSBOVUxMKSB7CiAgICAgICAgICAgIGN1ciA9IGN1ci0+bmV4dDsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKICAgICAgICBkbyB7CiAgICAgICAgICAgIGN1ciA9IGN1ci0+cGFyZW50OwogICAgICAgICAgICBpZiAoY3VyID09IE5VTEwpCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgaWYgKGN1ciA9PSByb290KSB7CiAgICAgICAgICAgICAgICBjdXIgPSBOVUxMOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGN1ci0+bmV4dCAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICBjdXIgPSBjdXItPm5leHQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0gd2hpbGUgKGN1ciAhPSBOVUxMKTsKICAgIH0KICAgIGlmIChkZWxldGUgIT0gTlVMTCkgewogICAgICAgIHhtbFVubGlua05vZGUoZGVsZXRlKTsKICAgICAgICB4bWxGcmVlTm9kZShkZWxldGUpOwogICAgICAgIGRlbGV0ZSA9IE5VTEw7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZVNjaGVtYVRvcExldmVsOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYXMKICogQG5vZGVzOiAgdGhlIGxpc3Qgb2YgdG9wIGxldmVsIG5vZGVzCiAqCiAqIFJldHVybnMgdGhlIGludGVybmFsIFhNTCBTY2hlbWEgc3RydWN0dXJlIGJ1aWx0IGZyb20gdGhlIHJlc291cmNlIG9yCiAqICAgICAgICAgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFQYXJzZVNjaGVtYVRvcExldmVsKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLCB4bWxOb2RlUHRyIG5vZGVzKQp7CiAgICB4bWxOb2RlUHRyIGNoaWxkOwogICAgeG1sU2NoZW1hQW5ub3RQdHIgYW5ub3Q7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGVzID09IE5VTEwpKQogICAgICAgIHJldHVybjsKCiAgICBjaGlsZCA9IG5vZGVzOwogICAgd2hpbGUgKChJU19TQ0hFTUEoY2hpbGQsICJpbmNsdWRlIikpIHx8CgkgICAoSVNfU0NIRU1BKGNoaWxkLCAiaW1wb3J0IikpIHx8CgkgICAoSVNfU0NIRU1BKGNoaWxkLCAicmVkZWZpbmUiKSkgfHwKCSAgIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpKSB7CglpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CgkgICAgYW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgaWYgKHNjaGVtYS0+YW5ub3QgPT0gTlVMTCkKCQlzY2hlbWEtPmFubm90ID0gYW5ub3Q7CgkgICAgZWxzZQoJCXhtbFNjaGVtYUZyZWVBbm5vdChhbm5vdCk7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImltcG9ydCIpKSB7CgkgICAgeG1sU2NoZW1hUGFyc2VJbXBvcnQoY3R4dCwgc2NoZW1hLCBjaGlsZCk7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImluY2x1ZGUiKSkgewoJICAgIGN0eHQtPmluY2x1ZGVzKys7CgkgICAgeG1sU2NoZW1hUGFyc2VJbmNsdWRlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwoJICAgIGN0eHQtPmluY2x1ZGVzLS07Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInJlZGVmaW5lIikpIHsKCSAgICBUT0RPCgl9CgljaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgd2hpbGUgKGNoaWxkICE9IE5VTEwpIHsKCWlmIChJU19TQ0hFTUEoY2hpbGQsICJjb21wbGV4VHlwZSIpKSB7CgkgICAgeG1sU2NoZW1hUGFyc2VDb21wbGV4VHlwZShjdHh0LCBzY2hlbWEsIGNoaWxkLCAxKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVUeXBlIikpIHsKCSAgICB4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMSk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZWxlbWVudCIpKSB7CgkgICAgeG1sU2NoZW1hUGFyc2VFbGVtZW50KGN0eHQsIHNjaGVtYSwgY2hpbGQsIDEpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImF0dHJpYnV0ZSIpKSB7CgkgICAgeG1sU2NoZW1hUGFyc2VBdHRyaWJ1dGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMSk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYXR0cmlidXRlR3JvdXAiKSkgewoJICAgIHhtbFNjaGVtYVBhcnNlQXR0cmlidXRlR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMSk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgewoJICAgIHhtbFNjaGVtYVBhcnNlR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMSk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAibm90YXRpb24iKSkgewoJICAgIHhtbFNjaGVtYVBhcnNlTm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0gZWxzZSB7CgkgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgTlVMTCwgY2hpbGQsCgkJCSAgIFhNTF9TQ0hFTUFQX1VOS05PV05fU0NIRU1BU19DSElMRCwKCQkJICAgIlNjaGVtYXM6IHVuZXhwZWN0ZWQgZWxlbWVudCAlcyBoZXJlIFxuIiwKCQkJICAgY2hpbGQtPm5hbWUsIE5VTEwpOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7Cgl9Cgl3aGlsZSAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CgkgICAgYW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgaWYgKHNjaGVtYS0+YW5ub3QgPT0gTlVMTCkKCQlzY2hlbWEtPmFubm90ID0gYW5ub3Q7CgkgICAgZWxzZQoJCXhtbFNjaGVtYUZyZWVBbm5vdChhbm5vdCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KICAgIH0KICAgIGN0eHQtPnBhcmVudEl0ZW0gPSBOVUxMOwogICAgY3R4dC0+Y3R4dFR5cGUgPSBOVUxMOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VJbmNsdWRlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBJbmNsdWRlIGRlZmluaXRpb24KICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIGlmIHRoZSBkZWNsYXJhdGlvbiBpcyBpbXByb3BlciBhbmQKICogICAgICAgICAxIGluIGNhc2Ugb2Ygc3VjY2Vzcy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VJbmNsdWRlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICpzY2hlbWFMb2NhdGlvbjsKICAgIHhtbFVSSVB0ciBjaGVjazsKICAgIHhtbERvY1B0ciBkb2M7CiAgICB4bWxOb2RlUHRyIHJvb3Q7CiAgICB4bWxTY2hlbWFJbmNsdWRlUHRyIGluY2x1ZGU7CgoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoLTEpOwoKICAgIC8qCiAgICAgKiBQcmVsaW1pbmFyeSBzdGVwLCBleHRyYWN0IHRoZSBVUkktUmVmZXJlbmNlIGZvciB0aGUgaW5jbHVkZSBhbmQKICAgICAqIG1ha2UgYW4gVVJJIGZyb20gdGhlIGJhc2UuCiAgICAgKi8KICAgIHNjaGVtYUxvY2F0aW9uID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAic2NoZW1hTG9jYXRpb24iKTsKICAgIGlmIChzY2hlbWFMb2NhdGlvbiAhPSBOVUxMKSB7CiAgICAgICAgeG1sQ2hhciAqYmFzZSA9IE5VTEw7CiAgICAgICAgeG1sQ2hhciAqVVJJID0gTlVMTDsKICAgICAgICBjaGVjayA9IHhtbFBhcnNlVVJJKChjb25zdCBjaGFyICopIHNjaGVtYUxvY2F0aW9uKTsKICAgICAgICBpZiAoY2hlY2sgPT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfSU5DTFVERV9TQ0hFTUFfTk9UX1VSSSwKCQkgICAgICAgIkluY2x1ZGUgc2NoZW1hTG9jYXRpb24gYXR0cmlidXRlIGlzIG5vdCBhbiBVUkk6ICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzY2hlbWFMb2NhdGlvbiwgTlVMTCk7CiAgICAgICAgICAgIHJldHVybiAoLTEpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHhtbEZyZWVVUkkoY2hlY2spOwogICAgICAgIH0KCWJhc2UgPSB4bWxOb2RlR2V0QmFzZShub2RlLT5kb2MsIG5vZGUpOwoJaWYgKGJhc2UgPT0gTlVMTCkgewoJICAgIFVSSSA9IHhtbEJ1aWxkVVJJKHNjaGVtYUxvY2F0aW9uLCBub2RlLT5kb2MtPlVSTCk7Cgl9IGVsc2UgewoJICAgIFVSSSA9IHhtbEJ1aWxkVVJJKHNjaGVtYUxvY2F0aW9uLCBiYXNlKTsKCSAgICB4bWxGcmVlKGJhc2UpOwoJfQoJaWYgKFVSSSAhPSBOVUxMKSB7CgkgICAgc2NoZW1hTG9jYXRpb24gPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIFVSSSwgLTEpOwoJICAgIHhtbEZyZWUoVVJJKTsKCX0KICAgIH0gZWxzZSB7Cgl4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKCQkgICAgICAgWE1MX1NDSEVNQVBfSU5DTFVERV9TQ0hFTUFfTk9fVVJJLAoJCSAgICJJbmNsdWRlIHNjaGVtYUxvY2F0aW9uIGF0dHJpYnV0ZSBtaXNzaW5nXG4iLAoJCSAgICAgICBOVUxMLCBOVUxMKTsKCXJldHVybiAoLTEpOwogICAgfQoKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICB3aGlsZSAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgLyoKICAgICAgICAgKiB0aGUgYW5ub3RhdGlvbnMgaGVyZSBhcmUgc2ltcGx5IGRpc2NhcmRlZCAuLi4KICAgICAgICAgKi8KICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwgWE1MX1NDSEVNQVBfVU5LTk9XTl9JTkNMVURFX0NISUxELAogICAgICAgICAgICAgICAgICAgICAgICJJbmNsdWRlIGhhcyB1bmV4cGVjdGVkIGNvbnRlbnRcbiIsIE5VTEwsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQoKICAgIC8qCiAgICAgKiBGaXJzdCBzdGVwIGlzIHRvIHBhcnNlIHRoZSBpbnB1dCBkb2N1bWVudCBpbnRvIGFuIERPTS9JbmZvc2V0CiAgICAgKi8KICAgIGRvYyA9IHhtbFJlYWRGaWxlKChjb25zdCBjaGFyICopIHNjaGVtYUxvY2F0aW9uLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgU0NIRU1BU19QQVJTRV9PUFRJT05TKTsKICAgIGlmIChkb2MgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVycihjdHh0LCBOVUxMLAoJCSAgICAgIFhNTF9TQ0hFTUFQX0ZBSUxFRF9MT0FELAoJCSAgICAgICJ4bWxTY2hlbWFQYXJzZTogY291bGQgbm90IGxvYWQgJXNcbiIsCgkJICAgICAgY3R4dC0+VVJMLCBOVUxMKTsKCXJldHVybigtMSk7CiAgICB9CgogICAgLyoKICAgICAqIFRoZW4gZXh0cmFjdCB0aGUgcm9vdCBvZiB0aGUgc2NoZW1hCiAgICAgKi8KICAgIHJvb3QgPSB4bWxEb2NHZXRSb290RWxlbWVudChkb2MpOwogICAgaWYgKHJvb3QgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgZG9jLAoJCSAgICAgIFhNTF9TQ0hFTUFQX05PUk9PVCwKCQkgICAgICAic2NoZW1hcyAlcyBoYXMgbm8gcm9vdCIsIHNjaGVtYUxvY2F0aW9uLCBOVUxMKTsKCXhtbEZyZWVEb2MoZG9jKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KCiAgICAvKgogICAgICogUmVtb3ZlIGFsbCB0aGUgYmxhbmsgdGV4dCBub2RlcwogICAgICovCiAgICB4bWxTY2hlbWFDbGVhbnVwRG9jKGN0eHQsIHJvb3QpOwoKICAgIC8qCiAgICAgKiBDaGVjayB0aGUgc2NoZW1hcyB0b3AgbGV2ZWwgZWxlbWVudAogICAgICovCiAgICBpZiAoIUlTX1NDSEVNQShyb290LCAic2NoZW1hIikpIHsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgKHhtbE5vZGVQdHIpIGRvYywKCQkgICAgICBYTUxfU0NIRU1BUF9OT1RfU0NIRU1BLAoJCSAgICAgICJGaWxlICVzIGlzIG5vdCBhIHNjaGVtYSIsIHNjaGVtYUxvY2F0aW9uLCBOVUxMKTsKCXhtbEZyZWVEb2MoZG9jKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KCiAgICAvKgogICAgICogcmVnaXN0ZXIgdGhlIGluY2x1ZGUKICAgICAqLwogICAgaW5jbHVkZSA9ICh4bWxTY2hlbWFJbmNsdWRlUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUluY2x1ZGUpKTsKICAgIGlmIChpbmNsdWRlID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KGN0eHQsICJhbGxvY2F0aW5nIGluY2x1ZGVkIHNjaGVtYSIsIE5VTEwpOwoJeG1sRnJlZURvYyhkb2MpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQoKICAgIG1lbXNldChpbmNsdWRlLCAwLCBzaXplb2YoeG1sU2NoZW1hSW5jbHVkZSkpOwogICAgaW5jbHVkZS0+c2NoZW1hTG9jYXRpb24gPSB4bWxEaWN0TG9va3VwKGN0eHQtPmRpY3QsIHNjaGVtYUxvY2F0aW9uLCAtMSk7CiAgICBpbmNsdWRlLT5kb2MgPSBkb2M7CiAgICBpbmNsdWRlLT5uZXh0ID0gc2NoZW1hLT5pbmNsdWRlczsKICAgIHNjaGVtYS0+aW5jbHVkZXMgPSBpbmNsdWRlOwoKCiAgICAvKgogICAgICogcGFyc2UgdGhlIGRlY2xhcmF0aW9ucyBpbiB0aGUgaW5jbHVkZWQgZmlsZSBsaWtlIGlmIHRoZXkKICAgICAqIHdlcmUgaW4gdGhlIG9yaWdpbmFsIGZpbGUuCiAgICAgKi8KICAgIHhtbFNjaGVtYVBhcnNlU2NoZW1hVG9wTGV2ZWwoY3R4dCwgc2NoZW1hLCByb290LT5jaGlsZHJlbik7CgogICAgcmV0dXJuICgxKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlQ2hvaWNlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBDaG9pY2UgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciwgMCBpZiB0aGUgZGVjbGFyYXRpb24gaXMgaW1wcm9wZXIgYW5kCiAqICAgICAgICAgMSBpbiBjYXNlIG9mIHN1Y2Nlc3MuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZUNob2ljZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBzdWJ0eXBlLCBsYXN0ID0gTlVMTDsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQ2hhciBuYW1lWzMwXTsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKCiAgICBzbnByaW50ZigoY2hhciAqKSBuYW1lLCAzMCwgImNob2ljZSAlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBOVUxMKTsKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHR5cGUtPm5vZGUgPSBub2RlOwogICAgdHlwZS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0U7CiAgICB0eXBlLT5pZCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImlkIik7CiAgICB0eXBlLT5taW5PY2N1cnMgPSB4bWxHZXRNaW5PY2N1cnMoY3R4dCwgbm9kZSk7CiAgICB0eXBlLT5tYXhPY2N1cnMgPSB4bWxHZXRNYXhPY2N1cnMoY3R4dCwgbm9kZSk7CgogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgd2hpbGUgKChJU19TQ0hFTUEoY2hpbGQsICJlbGVtZW50IikpIHx8CiAgICAgICAgICAgKElTX1NDSEVNQShjaGlsZCwgImdyb3VwIikpIHx8CiAgICAgICAgICAgKElTX1NDSEVNQShjaGlsZCwgImFueSIpKSB8fAogICAgICAgICAgIChJU19TQ0hFTUEoY2hpbGQsICJjaG9pY2UiKSkgfHwKICAgICAgICAgICAoSVNfU0NIRU1BKGNoaWxkLCAic2VxdWVuY2UiKSkpIHsKICAgICAgICBzdWJ0eXBlID0gTlVMTDsKICAgICAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZWxlbWVudCIpKSB7CiAgICAgICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlRWxlbWVudChjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImdyb3VwIikpIHsKICAgICAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlR3JvdXAoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CiAgICAgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbnkiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VBbnkoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzZXF1ZW5jZSIpKSB7CiAgICAgICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZVNlcXVlbmNlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiY2hvaWNlIikpIHsKICAgICAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlQ2hvaWNlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIH0KICAgICAgICBpZiAoc3VidHlwZSAhPSBOVUxMKSB7CiAgICAgICAgICAgIGlmIChsYXN0ID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKICAgICAgICAgICAgICAgIGxhc3QgPSBzdWJ0eXBlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbGFzdC0+bmV4dCA9IHN1YnR5cGU7CiAgICAgICAgICAgICAgICBsYXN0ID0gc3VidHlwZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBsYXN0LT5uZXh0ID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsIFhNTF9TQ0hFTUFQX1VOS05PV05fQ0hPSUNFX0NISUxELAogICAgICAgICAgICAgICAgICAgICAgICJDaG9pY2UgJXMgaGFzIHVuZXhwZWN0ZWQgY29udGVudFxuIiwgdHlwZS0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgIH0KCiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VTZXF1ZW5jZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgU2VxdWVuY2UgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvciwgMCBpZiB0aGUgZGVjbGFyYXRpb24gaXMgaW1wcm9wZXIgYW5kCiAqICAgICAgICAgMSBpbiBjYXNlIG9mIHN1Y2Nlc3MuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZVNlcXVlbmNlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgeG1sU2NoZW1hUHRyIHNjaGVtYSwKICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgc3VidHlwZSwgbGFzdCA9IE5VTEw7CiAgICB4bWxOb2RlUHRyIGNoaWxkID0gTlVMTDsKICAgIHhtbENoYXIgbmFtZVszMF07CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCgogICAgc25wcmludGYoKGNoYXIgKikgbmFtZSwgMzAsICJzZXF1ZW5jZSAlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBOVUxMKTsKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHR5cGUtPm5vZGUgPSBub2RlOwogICAgdHlwZS0+dHlwZSA9IFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRTsKICAgIHR5cGUtPmlkID0geG1sU2NoZW1hR2V0UHJvcChjdHh0LCBub2RlLCAiaWQiKTsKICAgIHR5cGUtPm1pbk9jY3VycyA9IHhtbEdldE1pbk9jY3VycyhjdHh0LCBub2RlKTsKICAgIHR5cGUtPm1heE9jY3VycyA9IHhtbEdldE1heE9jY3VycyhjdHh0LCBub2RlKTsKCiAgICBjaGlsZCA9IG5vZGUtPmNoaWxkcmVuOwogICAgaWYgKElTX1NDSEVNQShjaGlsZCwgImFubm90YXRpb24iKSkgewogICAgICAgIHR5cGUtPmFubm90ID0geG1sU2NoZW1hUGFyc2VBbm5vdGF0aW9uKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICB3aGlsZSAoKElTX1NDSEVNQShjaGlsZCwgImVsZW1lbnQiKSkgfHwKICAgICAgICAgICAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgfHwKICAgICAgICAgICAoSVNfU0NIRU1BKGNoaWxkLCAiYW55IikpIHx8CiAgICAgICAgICAgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB8fAogICAgICAgICAgIChJU19TQ0hFTUEoY2hpbGQsICJzZXF1ZW5jZSIpKSkgewogICAgICAgIHN1YnR5cGUgPSBOVUxMOwogICAgICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJlbGVtZW50IikpIHsKICAgICAgICAgICAgc3VidHlwZSA9ICh4bWxTY2hlbWFUeXBlUHRyKQogICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VFbGVtZW50KGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImFueSIpKSB7CiAgICAgICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZUFueShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNob2ljZSIpKSB7CiAgICAgICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZUNob2ljZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInNlcXVlbmNlIikpIHsKICAgICAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlU2VxdWVuY2UoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgfQogICAgICAgIGlmIChzdWJ0eXBlICE9IE5VTEwpIHsKICAgICAgICAgICAgaWYgKGxhc3QgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwogICAgICAgICAgICAgICAgbGFzdCA9IHN1YnR5cGU7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBsYXN0LT5uZXh0ID0gc3VidHlwZTsKICAgICAgICAgICAgICAgIGxhc3QgPSBzdWJ0eXBlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxhc3QtPm5leHQgPSBOVUxMOwogICAgICAgIH0KICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9VTktOT1dOX1NFUVVFTkNFX0NISUxELAogICAgICAgICAgICAgICAgICAgICAgICJTZXF1ZW5jZSAlcyBoYXMgdW5leHBlY3RlZCBjb250ZW50XG4iLCB0eXBlLT5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgfQoKICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZVJlc3RyaWN0aW9uOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBSZXN0cmljdGlvbiBkZWZpbml0aW9uCiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgdHlwZSBkZWZpbml0aW9uIG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hUGFyc2VSZXN0cmljdGlvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIHN1YnR5cGU7ICAgIAogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxDaGFyIG5hbWVbMzBdOwogICAgY29uc3QgeG1sQ2hhciAqb2xkY29udGFpbmVyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgb2xkY29udGFpbmVyID0gY3R4dC0+Y29udGFpbmVyOwoKICAgIHNucHJpbnRmKChjaGFyICopIG5hbWUsIDMwLCAicmVzdHJpY3Rpb24gJWQiLCBjdHh0LT5jb3VudGVyKysgKyAxKTsKICAgIHR5cGUgPSB4bWxTY2hlbWFBZGRUeXBlKGN0eHQsIHNjaGVtYSwgbmFtZSwgTlVMTCk7CiAgICBpZiAodHlwZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX1JFU1RSSUNUSU9OOwogICAgdHlwZS0+bm9kZSA9IG5vZGU7CiAgICB0eXBlLT5pZCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImlkIik7CiAgICB0eXBlLT5iYXNlID0geG1sR2V0UU5hbWVQcm9wKGN0eHQsIG5vZGUsICJiYXNlIiwgJih0eXBlLT5iYXNlTnMpKTsKICAgIGlmICgodHlwZS0+YmFzZSA9PSBOVUxMKSAmJiAKCShjdHh0LT5wYXJlbnRJdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQpKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsCgkgICAgWE1MX1NDSEVNQVBfUkVTVFJJQ1RJT05fTk9OQU1FX05PUkVGLAoJICAgICJSZXN0cmljdGlvbiBcIiVzXCIgbXVzdCBoYXZlIGEgXCJiYXNlXCIgYXR0cmlidXRlLlxuIiwgCgkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CiAgICB9CiAgICBjdHh0LT5jb250YWluZXIgPSBuYW1lOwoKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgdHlwZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHN1YnR5cGUgPSBOVUxMOwoKICAgIGlmIChjdHh0LT5wYXJlbnRJdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQpIHsKCWlmIChJU19TQ0hFTUEoY2hpbGQsICJhbGwiKSkgewoJICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKCQl4bWxTY2hlbWFQYXJzZUFsbChjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiY2hvaWNlIikpIHsKCSAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VDaG9pY2UoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCSAgICB0eXBlLT5zdWJ0eXBlcyA9IHN1YnR5cGU7Cgl9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgInNlcXVlbmNlIikpIHsKCSAgICBzdWJ0eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpCgkJeG1sU2NoZW1hUGFyc2VTZXF1ZW5jZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKCX0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgewoJICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKCQl4bWxTY2hlbWFQYXJzZUdyb3VwKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwoJICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CgkgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwoJfQogICAgfSBlbHNlIGlmICgoY3R4dC0+Y3R4dFR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkgfHwKCShjdHh0LT5wYXJlbnRJdGVtLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEVfQ09OVEVOVCkpIHsKCXhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0LCBsYXN0ZmFjZXQgPSBOVUxMOwkKCQoJaWYgKElTX1NDSEVNQShjaGlsZCwgInNpbXBsZVR5cGUiKSkgewoJICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKCQl4bWxTY2hlbWFQYXJzZVNpbXBsZVR5cGUoY3R4dCwgc2NoZW1hLCBjaGlsZCwgMCk7CgkgICAgLyogCgkgICAgKiBGb3IgdGhlIHNpbXBsZSB0eXBlIHRoaXMgc2VydmVzIGFzIHRoZSBiYXNlIHR5cGUuCgkgICAgKi8KCSAgICB0eXBlLT5iYXNlVHlwZSA9IHN1YnR5cGU7CgkgICAgLyogCgkgICAgKiBGb3IgdGhlIGNvbXBsZXggdHlwZSB0aGlzIHNlcnZlcyBhcyBpbmZvcm1hdGlvbiBmb3IgdGhlIAoJICAgICogZGVmaW5pdGlvbiBvZiB0aGUgY29udGVudCB0eXBlLgoJICAgICogQWRkaXRpb25hbGx5IHRoaXMgaXMgYSBoYWNrIGZvciB0aGUgc2ltcGxlIHR5cGUsIHRvIHNhdmUgCgkgICAgKiB0aGUgaW5mb3JtYXRpb24gdGhhdCBhIGxvY2FsIHNpbXBsZSB0eXBlIHdhcyBkZWZpbmVkOyB0aHVzCgkgICAgKiBhbGxvd2luZyB0byBjaGVjazogc3JjLXJlc3RyaWN0aW9uLWJhc2Utb3Itc2ltcGxlVHlwZS4KCSAgICAqLwoJICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQoJLyoKCSogQWRkIHRoZSBmYWNldHMgdG8gdGhlIHBhcmVudCBzaW1wbGVUeXBlL2NvbXBsZXhUeXBlLgoJKi8KCXdoaWxlICgoSVNfU0NIRU1BKGNoaWxkLCAibWluSW5jbHVzaXZlIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgIm1pbkV4Y2x1c2l2ZSIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJtYXhJbmNsdXNpdmUiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAibWF4RXhjbHVzaXZlIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgInRvdGFsRGlnaXRzIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgImZyYWN0aW9uRGlnaXRzIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgInBhdHRlcm4iKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAiZW51bWVyYXRpb24iKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAid2hpdGVTcGFjZSIpKSB8fAoJICAgIChJU19TQ0hFTUEoY2hpbGQsICJsZW5ndGgiKSkgfHwKCSAgICAoSVNfU0NIRU1BKGNoaWxkLCAibWF4TGVuZ3RoIikpIHx8CgkgICAgKElTX1NDSEVNQShjaGlsZCwgIm1pbkxlbmd0aCIpKSkgewoJICAgIGZhY2V0ID0geG1sU2NoZW1hUGFyc2VGYWNldChjdHh0LCBzY2hlbWEsIGNoaWxkKTsKCSAgICBpZiAoZmFjZXQgIT0gTlVMTCkgewoJCWlmIChsYXN0ZmFjZXQgPT0gTlVMTCkKCQkgICAgY3R4dC0+Y3R4dFR5cGUtPmZhY2V0cyA9IGZhY2V0OwkJCQoJCWVsc2UKCQkgICAgbGFzdGZhY2V0LT5uZXh0ID0gZmFjZXQ7CgkJbGFzdGZhY2V0ID0gZmFjZXQ7CgkJbGFzdGZhY2V0LT5uZXh0ID0gTlVMTDsKCSAgICB9CgkgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKCX0KCS8qCgkqIENyZWF0ZSBsaW5rcyBmb3IgZGVyaXZhdGlvbiBhbmQgdmFsaWRhdGlvbi4KCSovCSAgICAKCWlmIChsYXN0ZmFjZXQgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYUZhY2V0TGlua1B0ciBmYWNldExpbmssIGxhc3RGYWNldExpbmsgPSBOVUxMOwoKCSAgICBmYWNldCA9IGN0eHQtPmN0eHRUeXBlLT5mYWNldHM7CgkgICAgZG8gewkJICAgIAoJCWZhY2V0TGluayA9ICh4bWxTY2hlbWFGYWNldExpbmtQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hRmFjZXRMaW5rKSk7CgkJaWYgKGZhY2V0TGluayA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpb24gYSBmYWNldCBsaW5rIiwgTlVMTCk7CgkJICAgIHhtbEZyZWUoZmFjZXRMaW5rKTsKCQkgICAgcmV0dXJuIChOVUxMKTsKCQl9CQoJCWZhY2V0TGluay0+ZmFjZXQgPSBmYWNldDsKCQlmYWNldExpbmstPm5leHQgPSBOVUxMOwoJCWlmIChsYXN0RmFjZXRMaW5rID09IE5VTEwpIAoJCSAgICBjdHh0LT5jdHh0VHlwZS0+ZmFjZXRTZXQgPSBmYWNldExpbms7CQkJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKCQllbHNlCgkJICAgIGxhc3RGYWNldExpbmstPm5leHQgPSBmYWNldExpbms7CgkJbGFzdEZhY2V0TGluayA9IGZhY2V0TGluazsKCQlmYWNldCA9IGZhY2V0LT5uZXh0OwoJICAgIH0gd2hpbGUgKGZhY2V0ICE9IE5VTEwpOwoJfQogICAgfSAgICAKICAgIGlmIChjdHh0LT5jdHh0VHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkKCWNoaWxkID0geG1sU2NoZW1hUGFyc2VBdHRyRGVjbHMoY3R4dCwgc2NoZW1hLCBjaGlsZCwgdHlwZSk7CQogICAgaWYgKGNoaWxkICE9IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLAoJICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fUkVTVFJJQ1RJT05fQ0hJTEQsCgkgICAgIlJlc3RyaWN0aW9uIFwiJXNcIiBoYXMgdW5leHBlY3RlZCBjb250ZW50LlxuIiwKCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKICAgIH0gICAKICAgIGN0eHQtPmNvbnRhaW5lciA9IG9sZGNvbnRhaW5lcjsKICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUV4dGVuc2lvbjoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgRXh0ZW5zaW9uIGRlZmluaXRpb24KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSB0eXBlIGRlZmluaXRpb24gb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFQYXJzZUV4dGVuc2lvbih4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIHhtbFNjaGVtYVB0ciBzY2hlbWEsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBzdWJ0eXBlOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxDaGFyIG5hbWVbMzBdOwogICAgY29uc3QgeG1sQ2hhciAqb2xkY29udGFpbmVyOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgb2xkY29udGFpbmVyID0gY3R4dC0+Y29udGFpbmVyOwoKICAgIHNucHJpbnRmKChjaGFyICopIG5hbWUsIDMwLCAiZXh0ZW5zaW9uICVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CiAgICB0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsIG5hbWUsIE5VTEwpOyAgICAKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfRVhURU5TSU9OOwogICAgdHlwZS0+bm9kZSA9IG5vZGU7CiAgICB0eXBlLT5pZCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImlkIik7CiAgICBjdHh0LT5jb250YWluZXIgPSBuYW1lOwoKICAgIHR5cGUtPmJhc2UgPSB4bWxHZXRRTmFtZVByb3AoY3R4dCwgbm9kZSwgImJhc2UiLCAmKHR5cGUtPmJhc2VOcykpOwogICAgaWYgKHR5cGUtPmJhc2UgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLCBYTUxfU0NIRU1BUF9FWFRFTlNJT05fTk9fQkFTRSwKICAgICAgICAgICAgICAgICAgICAgICAiRXh0ZW5zaW9uICVzIGhhcyBubyBiYXNlXG4iLCB0eXBlLT5uYW1lLCBOVUxMKTsKICAgIH0KICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgdHlwZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHN1YnR5cGUgPSBOVUxMOwoKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbGwiKSkgewogICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZUFsbChjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJjaG9pY2UiKSkgewogICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZUNob2ljZShjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzZXF1ZW5jZSIpKSB7CiAgICAgICAgc3VidHlwZSA9IHhtbFNjaGVtYVBhcnNlU2VxdWVuY2UoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgewogICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZUdyb3VwKGN0eHQsIHNjaGVtYSwgY2hpbGQsIDApOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9CiAgICBpZiAoc3VidHlwZSAhPSBOVUxMKQogICAgICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKICAgIGNoaWxkID0geG1sU2NoZW1hUGFyc2VBdHRyRGVjbHMoY3R4dCwgc2NoZW1hLCBjaGlsZCwgdHlwZSk7CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLAogICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fRVhURU5TSU9OX0NISUxELAogICAgICAgICAgICAgICAgICAgICAgICJFeHRlbnNpb24gJXMgaGFzIHVuZXhwZWN0ZWQgY29udGVudFxuIiwgdHlwZS0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgIH0KICAgIGN0eHQtPmNvbnRhaW5lciA9IG9sZGNvbnRhaW5lcjsKICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZVNpbXBsZUNvbnRlbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBzY2hlbWE6ICB0aGUgc2NoZW1hIGJlaW5nIGJ1aWx0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIFNpbXBsZUNvbnRlbnQgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIHR5cGUgZGVmaW5pdGlvbiBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlU2ltcGxlQ29udGVudCh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQdHIgc2NoZW1hLCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgc3VidHlwZTsKICAgIHhtbE5vZGVQdHIgY2hpbGQgPSBOVUxMOwogICAgeG1sQ2hhciBuYW1lWzMwXTsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHNjaGVtYSA9PSBOVUxMKSB8fCAobm9kZSA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHNucHJpbnRmKChjaGFyICopIG5hbWUsIDMwLCAic2ltcGxlQ29udGVudCAlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBOVUxMKTsgICAgCiAgICBpZiAodHlwZSA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB0eXBlLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UOwogICAgdHlwZS0+bm9kZSA9IG5vZGU7CiAgICB0eXBlLT5pZCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImlkIik7CgogICAgY2hpbGQgPSBub2RlLT5jaGlsZHJlbjsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbm5vdGF0aW9uIikpIHsKICAgICAgICB0eXBlLT5hbm5vdCA9IHhtbFNjaGVtYVBhcnNlQW5ub3RhdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfQogICAgY3R4dC0+cGFyZW50SXRlbSA9IHR5cGU7CiAgICBzdWJ0eXBlID0gTlVMTDsgICAgCiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAicmVzdHJpY3Rpb24iKSkgewogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VSZXN0cmljdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJleHRlbnNpb24iKSkgewogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VFeHRlbnNpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsCiAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9TSU1QTEVDT05URU5UX0NISUxELAogICAgICAgICAgICAgICAgICAgICAgICJTaW1wbGVDb250ZW50ICVzIGhhcyB1bmV4cGVjdGVkIGNvbnRlbnRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+bmFtZSwgTlVMTCk7CiAgICB9CiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VDb21wbGV4Q29udGVudDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHNjaGVtYTogIHRoZSBzY2hlbWEgYmVpbmcgYnVpbHQKICogQG5vZGU6ICBhIHN1YnRyZWUgY29udGFpbmluZyBYTUwgU2NoZW1hIGluZm9ybWF0aW9ucwogKgogKiBwYXJzZSBhIFhNTCBzY2hlbWEgQ29tcGxleENvbnRlbnQgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIHR5cGUgZGVmaW5pdGlvbiBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlQ29tcGxleENvbnRlbnQoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBzdWJ0eXBlOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICB4bWxDaGFyIG5hbWVbMzBdOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoc2NoZW1hID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgc25wcmludGYoKGNoYXIgKikgbmFtZSwgMzAsICJjb21wbGV4Q29udGVudCAlZCIsIGN0eHQtPmNvdW50ZXIrKyArIDEpOwogICAgdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBOVUxMKTsKICAgIGlmICh0eXBlID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIHR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UOwogICAgdHlwZS0+bm9kZSA9IG5vZGU7ICAgIAogICAgdHlwZS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwoKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgdHlwZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGN0eHQtPnBhcmVudEl0ZW0gPSB0eXBlOwogICAgc3VidHlwZSA9IE5VTEw7CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAicmVzdHJpY3Rpb24iKSkgewogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VSZXN0cmljdGlvbihjdHh0LCBzY2hlbWEsIGNoaWxkKTsKICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJleHRlbnNpb24iKSkgewogICAgICAgIHN1YnR5cGUgPSAoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VFeHRlbnNpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIHR5cGUtPnN1YnR5cGVzID0gc3VidHlwZTsKICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycjIoY3R4dCwgbm9kZSwgY2hpbGQsCiAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfVU5LTk9XTl9DT01QTEVYQ09OVEVOVF9DSElMRCwKICAgICAgICAgICAgICAgICAgICAgICAiQ29tcGxleENvbnRlbnQgJXMgaGFzIHVuZXhwZWN0ZWQgY29udGVudFxuIiwKICAgICAgICAgICAgICAgICAgICAgICB0eXBlLT5uYW1lLCBOVUxMKTsKICAgIH0KICAgIHJldHVybiAodHlwZSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUNvbXBsZXhUeXBlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAc2NoZW1hOiAgdGhlIHNjaGVtYSBiZWluZyBidWlsdAogKiBAbm9kZTogIGEgc3VidHJlZSBjb250YWluaW5nIFhNTCBTY2hlbWEgaW5mb3JtYXRpb25zCiAqCiAqIHBhcnNlIGEgWE1MIHNjaGVtYSBDb21wbGV4IFR5cGUgZGVmaW5pdGlvbgogKiAqV0FSTklORyogdGhpcyBpbnRlcmZhY2UgaXMgaGlnaGx5IHN1YmplY3QgdG8gY2hhbmdlCiAqCiAqIFJldHVybnMgdGhlIHR5cGUgZGVmaW5pdGlvbiBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFUeXBlUHRyCnhtbFNjaGVtYVBhcnNlQ29tcGxleFR5cGUoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFQdHIgc2NoZW1hLAogICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgbm9kZSwgaW50IHRvcExldmVsKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIHN1YnR5cGUsIGN0eHRUeXBlOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICpuYW1lOwogICAgY29uc3QgeG1sQ2hhciAqb2xkY29udGFpbmVyOyAgICAKICAgIGNoYXIgYnVmWzEwMF07CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChzY2hlbWEgPT0gTlVMTCkgfHwgKG5vZGUgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICBjdHh0VHlwZSA9IGN0eHQtPmN0eHRUeXBlOwoKICAgIG9sZGNvbnRhaW5lciA9IGN0eHQtPmNvbnRhaW5lcjsKICAgIG5hbWUgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJuYW1lIik7CiAgICBpZiAobmFtZSA9PSBOVUxMKSB7CiAgICAgICAgc25wcmludGYoYnVmLCA5OSwgImNvbXBsZXhUeXBlICVkIiwgY3R4dC0+Y291bnRlcisrICsgMSk7CgluYW1lID0gKGNvbnN0IHhtbENoYXIgKilidWY7Cgl0eXBlID0geG1sU2NoZW1hQWRkVHlwZShjdHh0LCBzY2hlbWEsIG5hbWUsIE5VTEwpOwogICAgfSBlbHNlIHsKCiAgICAgICAgLyogbG9jYWwgPSB4bWxTY2hlbWFHZXROYW1lc3BhY2UoY3R4dCwgc2NoZW1hLCBub2RlLCBuYW1lLCAmbnMpOyAqLwoJdHlwZSA9IHhtbFNjaGVtYUFkZFR5cGUoY3R4dCwgc2NoZW1hLCBuYW1lLCBzY2hlbWEtPnRhcmdldE5hbWVzcGFjZSk7CiAgICB9CiAgICBpZiAodHlwZSA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIGlmICh4bWxHZXRCb29sZWFuUHJvcChjdHh0LCBub2RlLCAibWl4ZWQiLCAwKSkgCgl0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX01JWEVEOyAgICAKCiAgICB0eXBlLT5ub2RlID0gbm9kZTsKICAgIHR5cGUtPnR5cGUgPSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDsKICAgIGlmICh0b3BMZXZlbCkgCiAgICAgICAgdHlwZS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9HTE9CQUw7CiAgICB0eXBlLT5pZCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImlkIik7CiAgICBjdHh0LT5jb250YWluZXIgPSBuYW1lOwoKICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CiAgICBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiYW5ub3RhdGlvbiIpKSB7CiAgICAgICAgdHlwZS0+YW5ub3QgPSB4bWxTY2hlbWFQYXJzZUFubm90YXRpb24oY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0KICAgIGN0eHQtPmN0eHRUeXBlID0gdHlwZTsKICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzaW1wbGVDb250ZW50IikpIHsKCS8qIDMuNC4zIDogMi4yICAKCSAqIFNwZWNpZnlpbmcgbWl4ZWQ9J3RydWUnIHdoZW4gdGhlIDxzaW1wbGVDb250ZW50PgoJICogYWx0ZXJuYXRpdmUgaXMgY2hvc2VuIGhhcyBubyBlZmZlY3QKCSAqLwoJaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9NSVhFRCkKCSAgICB0eXBlLT5mbGFncyBePSBYTUxfU0NIRU1BU19UWVBFX01JWEVEOwogICAgICAgIHR5cGUtPnN1YnR5cGVzID0geG1sU2NoZW1hUGFyc2VTaW1wbGVDb250ZW50KGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICB9IGVsc2UgaWYgKElTX1NDSEVNQShjaGlsZCwgImNvbXBsZXhDb250ZW50IikpIHsKICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9IHhtbFNjaGVtYVBhcnNlQ29tcGxleENvbnRlbnQoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgIH0gZWxzZSB7CiAgICAgICAgc3VidHlwZSA9IE5VTEw7CgogICAgICAgIGlmIChJU19TQ0hFTUEoY2hpbGQsICJhbGwiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VBbGwoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICAgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJjaG9pY2UiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VDaG9pY2UoY3R4dCwgc2NoZW1hLCBjaGlsZCk7CiAgICAgICAgICAgIGNoaWxkID0gY2hpbGQtPm5leHQ7CiAgICAgICAgfSBlbHNlIGlmIChJU19TQ0hFTUEoY2hpbGQsICJzZXF1ZW5jZSIpKSB7CiAgICAgICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFQYXJzZVNlcXVlbmNlKGN0eHQsIHNjaGVtYSwgY2hpbGQpOwogICAgICAgICAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwogICAgICAgIH0gZWxzZSBpZiAoSVNfU0NIRU1BKGNoaWxkLCAiZ3JvdXAiKSkgewogICAgICAgICAgICBzdWJ0eXBlID0geG1sU2NoZW1hUGFyc2VHcm91cChjdHh0LCBzY2hlbWEsIGNoaWxkLCAwKTsKICAgICAgICAgICAgY2hpbGQgPSBjaGlsZC0+bmV4dDsKICAgICAgICB9CiAgICAgICAgaWYgKHN1YnR5cGUgIT0gTlVMTCkKICAgICAgICAgICAgdHlwZS0+c3VidHlwZXMgPSBzdWJ0eXBlOwogICAgICAgIGNoaWxkID0geG1sU2NoZW1hUGFyc2VBdHRyRGVjbHMoY3R4dCwgc2NoZW1hLCBjaGlsZCwgdHlwZSk7CiAgICB9CiAgICBpZiAoY2hpbGQgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLAogICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fQ09NUExFWFRZUEVfQ0hJTEQsCiAgICAgICAgICAgICAgICAgICAgICAgIkNvbXBsZXhUeXBlICVzIGhhcyB1bmV4cGVjdGVkIGNvbnRlbnRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+bmFtZSwgTlVMTCk7CiAgICB9CiAgICBpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkKCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfT1dORURfQVRUUl9XSUxEQ0FSRDsKICAgIGN0eHQtPmNvbnRhaW5lciA9IG9sZGNvbnRhaW5lcjsKICAgIGN0eHQtPmN0eHRUeXBlID0gY3R4dFR5cGU7CiAgICByZXR1cm4gKHR5cGUpOwp9CgovKioKICogeG1sU2NoZW1hUGFyc2VTY2hlbWE6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgYSBzdWJ0cmVlIGNvbnRhaW5pbmcgWE1MIFNjaGVtYSBpbmZvcm1hdGlvbnMKICoKICogcGFyc2UgYSBYTUwgc2NoZW1hIGRlZmluaXRpb24gZnJvbSBhIG5vZGUgc2V0CiAqICpXQVJOSU5HKiB0aGlzIGludGVyZmFjZSBpcyBoaWdobHkgc3ViamVjdCB0byBjaGFuZ2UKICoKICogUmV0dXJucyB0aGUgaW50ZXJuYWwgWE1MIFNjaGVtYSBzdHJ1Y3R1cmUgYnVpbHQgZnJvbSB0aGUgcmVzb3VyY2Ugb3IKICogICAgICAgICBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnN0YXRpYyB4bWxTY2hlbWFQdHIKeG1sU2NoZW1hUGFyc2VTY2hlbWEoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbFNjaGVtYVB0ciBzY2hlbWEgPSBOVUxMOwogICAgeG1sTm9kZVB0ciBjaGlsZCA9IE5VTEw7CiAgICBjb25zdCB4bWxDaGFyICp2YWw7CiAgICBpbnQgbmJlcnJvcnM7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChub2RlID09IE5VTEwpKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAKICAgIG5iZXJyb3JzID0gY3R4dC0+bmJlcnJvcnM7CiAgICBjdHh0LT5uYmVycm9ycyA9IDA7CiAgICBpZiAoSVNfU0NIRU1BKG5vZGUsICJzY2hlbWEiKSkgewogICAgICAgIHNjaGVtYSA9IHhtbFNjaGVtYU5ld1NjaGVtYShjdHh0KTsKICAgICAgICBpZiAoc2NoZW1hID09IE5VTEwpCiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7Cgl2YWwgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJ0YXJnZXROYW1lc3BhY2UiKTsKCWlmICh2YWwgIT0gTlVMTCkgewoJICAgIHNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCB2YWwsIC0xKTsKCX0gZWxzZSB7CgkgICAgc2NoZW1hLT50YXJnZXROYW1lc3BhY2UgPSBOVUxMOwoJfQogICAgICAgIHNjaGVtYS0+aWQgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJpZCIpOwogICAgICAgIHNjaGVtYS0+dmVyc2lvbiA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgInZlcnNpb24iKTsKICAgICAgICB2YWwgPSB4bWxTY2hlbWFHZXRQcm9wKGN0eHQsIG5vZGUsICJlbGVtZW50Rm9ybURlZmF1bHQiKTsKICAgICAgICBpZiAodmFsICE9IE5VTEwpIHsKICAgICAgICAgICAgaWYgKHhtbFN0ckVxdWFsKHZhbCwgQkFEX0NBU1QgInF1YWxpZmllZCIpKQogICAgICAgICAgICAgICAgc2NoZW1hLT5mbGFncyB8PSBYTUxfU0NIRU1BU19RVUFMSUZfRUxFTTsKICAgICAgICAgICAgZWxzZSBpZiAoIXhtbFN0ckVxdWFsKHZhbCwgQkFEX0NBU1QgInVucXVhbGlmaWVkIikpIHsKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBFcnIyKGN0eHQsIG5vZGUsIGNoaWxkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfRUxFTUZPUk1ERUZBVUxUX1ZBTFVFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkludmFsaWQgdmFsdWUgJXMgZm9yIGVsZW1lbnRGb3JtRGVmYXVsdFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbCwgTlVMTCk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewoJICAgIC8qIFJlbW92ZWQsIHNpbmNlIHRoZSBkZWZhdWx0IHZhbHVlIGZvciBlbGVtZW50Rm9ybURlZmF1bHQKCSAgICAqIGlzICJ1bnF1YWxpZmllZCIuCgkgICAgKi8KCSAgICAvKiBzY2hlbWEtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1FVQUxJRl9FTEVNOyAqLwoJfQogICAgICAgIHZhbCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImF0dHJpYnV0ZUZvcm1EZWZhdWx0Iik7CiAgICAgICAgaWYgKHZhbCAhPSBOVUxMKSB7CiAgICAgICAgICAgIGlmICh4bWxTdHJFcXVhbCh2YWwsIEJBRF9DQVNUICJxdWFsaWZpZWQiKSkKICAgICAgICAgICAgICAgIHNjaGVtYS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfUVVBTElGX0FUVFI7CiAgICAgICAgICAgIGVsc2UgaWYgKCF4bWxTdHJFcXVhbCh2YWwsIEJBRF9DQVNUICJ1bnF1YWxpZmllZCIpKSB7CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFQRXJyMihjdHh0LCBub2RlLCBjaGlsZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX0FUVFJGT1JNREVGQVVMVF9WQUxVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJJbnZhbGlkIHZhbHVlICVzIGZvciBhdHRyaWJ1dGVGb3JtRGVmYXVsdFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbCwgTlVMTCk7CiAgICAgICAgICAgIH0KICAgICAgICB9IAoKCXZhbCA9IHhtbFNjaGVtYUdldFByb3AoY3R4dCwgbm9kZSwgImZpbmFsRGVmYXVsdCIpOwoJaWYgKHZhbCAhPSBOVUxMKSB7CgkgICAgaWYgKHhtbFN0ckVxdWFsKHZhbCwgQkFEX0NBU1QgIiNhbGwiKSkgewoJCXNjaGVtYS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9FWFRFTlNJT047IAoJCXNjaGVtYS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9SRVNUUklDVElPTjsgCgkJc2NoZW1hLT5mbGFncyB8PSBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX0xJU1Q7IAoJCXNjaGVtYS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9VTklPTjsgCQkKCSAgICB9IGVsc2UgewoJCWNvbnN0IHhtbENoYXIgKmVuZCwgKmN1ciA9IHZhbDsKCQl4bWxDaGFyICppdGVtOwoJCQoJCWRvIHsKCQkgICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQoJCQljdXIrKzsKCQkgICAgZW5kID0gY3VyOwoJCSAgICB3aGlsZSAoKCplbmQgIT0gMCkgJiYgKCEoSVNfQkxBTktfQ0goKmVuZCkpKSkKCQkJZW5kKys7CgkJICAgIGlmIChlbmQgPT0gY3VyKQoJCQlicmVhazsKCQkgICAgaXRlbSA9IHhtbFN0cm5kdXAoY3VyLCBlbmQgLSBjdXIpOyAgICAJICAgIAoJCSAgICBpZiAoeG1sU3RyRXF1YWwoaXRlbSwgQkFEX0NBU1QgImV4dGVuc2lvbiIpKSB7CgkJCWlmICgoc2NoZW1hLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfRVhURU5TSU9OKSA9PSAwKQoJCQkgICAgc2NoZW1hLT5mbGFncyB8PSBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX0VYVEVOU0lPTjsgCgkJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoaXRlbSwgQkFEX0NBU1QgInJlc3RyaWN0aW9uIikpIHsKCQkJaWYgKChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9SRVNUUklDVElPTikgPT0gMCkKCQkJICAgIHNjaGVtYS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9SRVNUUklDVElPTjsgCgkJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoaXRlbSwgQkFEX0NBU1QgImxpc3QiKSkgewoJCQlpZiAoKHNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX0xJU1QpID09IDApCgkJCSAgICBzY2hlbWEtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfTElTVDsgCgkJICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoaXRlbSwgQkFEX0NBU1QgInVuaW9uIikpIHsKCQkJaWYgKChzY2hlbWEtPmZsYWdzICYgWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9VTklPTikgPT0gMCkKCQkJICAgIHNjaGVtYS0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfRklOQUxfREVGQVVMVF9VTklPTjsgCgkJICAgIH0gZWxzZSB7CgkJCXhtbFNjaGVtYVBFcnIoY3R4dCwgbm9kZSwgCgkJCSAgICBYTUxfU0NIRU1BU19FUlJfSU5URVJOQUwsCgkJCSAgICAiSW52YWxpZCB2YWx1ZSBmb3IgdGhlIGF0dHJpYnV0ZSBcImZpbmFsRGVmYXVsdFwiLlxuIiwKCQkJICAgIE5VTEwsIE5VTEwpOwkJCSAgICAJCSAgICAKCQkgICAgfQoJCSAgICBpZiAoaXRlbSAhPSBOVUxMKQoJCQl4bWxGcmVlKGl0ZW0pOwoJCSAgICBjdXIgPSBlbmQ7CgkJfSB3aGlsZSAoKmN1ciAhPSAwKTsgCgkgICAgfQoJfQoKICAgICAgICB4bWxTY2hlbWFQYXJzZVNjaGVtYVRvcExldmVsKGN0eHQsIHNjaGVtYSwgbm9kZS0+Y2hpbGRyZW4pOwogICAgfSBlbHNlIHsKICAgICAgICB4bWxEb2NQdHIgZG9jOwoKCWRvYyA9IG5vZGUtPmRvYzsKCiAgICAgICAgaWYgKChkb2MgIT0gTlVMTCkgJiYgKGRvYy0+VVJMICE9IE5VTEwpKSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgZG9jLAoJCSAgICAgIFhNTF9TQ0hFTUFQX05PVF9TQ0hFTUEsCgkJICAgICAgIkZpbGUgJXMgaXMgbm90IGEgc2NoZW1hcyIsIGRvYy0+VVJMLCBOVUxMKTsKCX0gZWxzZSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgZG9jLAoJCSAgICAgIFhNTF9TQ0hFTUFQX05PVF9TQ0hFTUEsCgkJICAgICAgIkZpbGUgaXMgbm90IGEgc2NoZW1hcyIsIE5VTEwsIE5VTEwpOwoJfQoJcmV0dXJuKE5VTEwpOwogICAgfQogICAgaWYgKGN0eHQtPm5iZXJyb3JzICE9IDApIHsKICAgICAgICBpZiAoc2NoZW1hICE9IE5VTEwpIHsKICAgICAgICAgICAgeG1sU2NoZW1hRnJlZShzY2hlbWEpOwogICAgICAgICAgICBzY2hlbWEgPSBOVUxMOwogICAgICAgIH0KICAgIH0KICAgIGN0eHQtPm5iZXJyb3JzID0gbmJlcnJvcnM7CiNpZmRlZiBERUJVRwogICAgaWYgKHNjaGVtYSA9PSBOVUxMKQogICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAieG1sU2NoZW1hUGFyc2UoKSBmYWlsZWRcbiIpOwojZW5kaWYKICAgIHJldHVybiAoc2NoZW1hKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVZhbGlkYXRpbmcgdXNpbmcgU2NoZW1hcwkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVJlYWRpbmcvV3JpdGluZyBTY2hlbWFzCQkJCSoKICogCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqCiAqIHhtbFNjaGVtYU5ld1BhcnNlckN0eHQ6CiAqIEBVUkw6ICB0aGUgbG9jYXRpb24gb2YgdGhlIHNjaGVtYQogKgogKiBDcmVhdGUgYW4gWE1MIFNjaGVtYXMgcGFyc2UgY29udGV4dCBmb3IgdGhhdCBmaWxlL3Jlc291cmNlIGV4cGVjdGVkCiAqIHRvIGNvbnRhaW4gYW4gWE1MIFNjaGVtYXMgZmlsZS4KICoKICogUmV0dXJucyB0aGUgcGFyc2VyIGNvbnRleHQgb3IgTlVMTCBpbiBjYXNlIG9mIGVycm9yCiAqLwp4bWxTY2hlbWFQYXJzZXJDdHh0UHRyCnhtbFNjaGVtYU5ld1BhcnNlckN0eHQoY29uc3QgY2hhciAqVVJMKQp7CiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHJldDsKCiAgICBpZiAoVVJMID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChOVUxMKTsKCiAgICByZXQgPSAoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFQYXJzZXJDdHh0KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIHNjaGFtYSBwYXJzZXIgY29udGV4dCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldCwgMCwgc2l6ZW9mKHhtbFNjaGVtYVBhcnNlckN0eHQpKTsKICAgIHJldC0+ZGljdCA9IHhtbERpY3RDcmVhdGUoKTsKICAgIHJldC0+VVJMID0geG1sRGljdExvb2t1cChyZXQtPmRpY3QsIChjb25zdCB4bWxDaGFyICopIFVSTCwgLTEpOwogICAgcmV0LT5pbmNsdWRlcyA9IDA7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFOZXdNZW1QYXJzZXJDdHh0OgogKiBAYnVmZmVyOiAgYSBwb2ludGVyIHRvIGEgY2hhciBhcnJheSBjb250YWluaW5nIHRoZSBzY2hlbWFzCiAqIEBzaXplOiAgdGhlIHNpemUgb2YgdGhlIGFycmF5CiAqCiAqIENyZWF0ZSBhbiBYTUwgU2NoZW1hcyBwYXJzZSBjb250ZXh0IGZvciB0aGF0IG1lbW9yeSBidWZmZXIgZXhwZWN0ZWQKICogdG8gY29udGFpbiBhbiBYTUwgU2NoZW1hcyBmaWxlLgogKgogKiBSZXR1cm5zIHRoZSBwYXJzZXIgY29udGV4dCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnhtbFNjaGVtYVBhcnNlckN0eHRQdHIKeG1sU2NoZW1hTmV3TWVtUGFyc2VyQ3R4dChjb25zdCBjaGFyICpidWZmZXIsIGludCBzaXplKQp7CiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHJldDsKCiAgICBpZiAoKGJ1ZmZlciA9PSBOVUxMKSB8fCAoc2l6ZSA8PSAwKSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIHJldCA9ICh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVBhcnNlckN0eHQpKTsKICAgIGlmIChyZXQgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgImFsbG9jYXRpbmcgc2NoYW1hIHBhcnNlciBjb250ZXh0IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hUGFyc2VyQ3R4dCkpOwogICAgcmV0LT5idWZmZXIgPSBidWZmZXI7CiAgICByZXQtPnNpemUgPSBzaXplOwogICAgcmV0LT5kaWN0ID0geG1sRGljdENyZWF0ZSgpOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hTmV3RG9jUGFyc2VyQ3R4dDoKICogQGRvYzogIGEgcHJlcGFyc2VkIGRvY3VtZW50IHRyZWUKICoKICogQ3JlYXRlIGFuIFhNTCBTY2hlbWFzIHBhcnNlIGNvbnRleHQgZm9yIHRoYXQgZG9jdW1lbnQuCiAqIE5CLiBUaGUgZG9jdW1lbnQgbWF5IGJlIG1vZGlmaWVkIGR1cmluZyB0aGUgcGFyc2luZyBwcm9jZXNzLgogKgogKiBSZXR1cm5zIHRoZSBwYXJzZXIgY29udGV4dCBvciBOVUxMIGluIGNhc2Ugb2YgZXJyb3IKICovCnhtbFNjaGVtYVBhcnNlckN0eHRQdHIKeG1sU2NoZW1hTmV3RG9jUGFyc2VyQ3R4dCh4bWxEb2NQdHIgZG9jKQp7CiAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIHJldDsKCiAgICBpZiAoZG9jID09IE5VTEwpCiAgICAgIHJldHVybiAoTlVMTCk7CgogICAgcmV0ID0gKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hUGFyc2VyQ3R4dCkpOwogICAgaWYgKHJldCA9PSBOVUxMKSB7CiAgICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoTlVMTCwgImFsbG9jYXRpbmcgc2NoZW1hIHBhcnNlciBjb250ZXh0IiwKCQkJICBOVUxMKTsKICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbXNldChyZXQsIDAsIHNpemVvZih4bWxTY2hlbWFQYXJzZXJDdHh0KSk7CiAgICByZXQtPmRvYyA9IGRvYzsKICAgIHJldC0+ZGljdCA9IHhtbERpY3RDcmVhdGUoKTsKICAgIC8qIFRoZSBhcHBsaWNhdGlvbiBoYXMgcmVzcG9uc2liaWxpdHkgZm9yIHRoZSBkb2N1bWVudCAqLwogICAgcmV0LT5wcmVzZXJ2ZSA9IDE7CgogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hRnJlZVBhcnNlckN0eHQ6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKgogKiBGcmVlIHRoZSByZXNvdXJjZXMgYXNzb2NpYXRlZCB0byB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqLwp2b2lkCnhtbFNjaGVtYUZyZWVQYXJzZXJDdHh0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBpZiAoY3R4dC0+ZG9jICE9IE5VTEwgJiYgIWN0eHQtPnByZXNlcnZlKQogICAgICAgIHhtbEZyZWVEb2MoY3R4dC0+ZG9jKTsKICAgIHhtbERpY3RGcmVlKGN0eHQtPmRpY3QpOwogICAgeG1sRnJlZShjdHh0KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJCQkJCQkJCSoKICoJCQlCdWlsZGluZyB0aGUgY29udGVudCBtb2RlbHMJCQkqCiAqCQkJCQkJCQkJKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqCiAqIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbDoKICogQHR5cGU6ICB0aGUgc2NoZW1hIHR5cGUgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgZWxlbWVudCBuYW1lIHdob3NlIGNvbnRlbnQgaXMgYmVpbmcgYnVpbHQKICoKICogR2VuZXJhdGUgdGhlIGF1dG9tYXRhIHNlcXVlbmNlIG5lZWRlZCBmb3IgdGhhdCB0eXBlCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwoeG1sU2NoZW1hVHlwZVB0ciB0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUpCnsKICAgIGlmICh0eXBlID09IE5VTEwpIHsKICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgIkZvdW5kIHVuZXhwZWN0ZWQgdHlwZSA9IE5VTEwgaW4gJXMgY29udGVudCBtb2RlbFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgc3dpdGNoICh0eXBlLT50eXBlKSB7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZOgogICAgICAgICAgICAvKiBUT0RPIDogaGFuZGxlIHRoZSBuYW1lc3BhY2UgdG9vICovCiAgICAgICAgICAgIC8qIFRPRE8gOiBtYWtlIHRoYXQgYSBzcGVjaWZpYyB0cmFuc2l0aW9uIHR5cGUgKi8KCSAgICAvKiBEYW5pZWwgc2F5czogdXNlIHhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbjIgKi8KICAgICAgICAgICAgVE9ETyBjdHh0LT5zdGF0ZSA9CiAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJBRF9DQVNUICIqIiwgTlVMTCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6ewogICAgICAgICAgICAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHR5cGU7CgogICAgICAgICAgICAgICAgLyogVE9ETyA6IGhhbmRsZSB0aGUgbmFtZXNwYWNlIHRvbyAqLwogICAgICAgICAgICAgICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBvbGRzdGF0ZSA9IGN0eHQtPnN0YXRlOwoKICAgICAgICAgICAgICAgIGlmIChlbGVtLT5tYXhPY2N1cnMgPj0gVU5CT1VOREVEKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW0tPm1pbk9jY3VycyA+IDEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFTdGF0ZVB0ciB0bXA7CiAgICAgICAgICAgICAgICAgICAgICAgIGludCBjb3VudGVyOwoKICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUgPSBjdHh0LT5zdGF0ZTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXIgPSB4bWxBdXRvbWF0YU5ld0NvdW50ZXIoY3R4dC0+YW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbS0+bWluT2NjdXJzIC0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCBVTkJPVU5ERUQpOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW0tPnJlZkRlY2wgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKCh4bWxTY2hlbWFUeXBlUHRyKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0tPnJlZkRlY2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtLT5yZWZEZWNsLT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld1RyYW5zaXRpb24oY3R4dC0+YW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtLT5uYW1lLCB0eXBlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB0bXAgPSBjdHh0LT5zdGF0ZTsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudGVkVHJhbnMoY3R4dC0+YW0sIHRtcCwgb2xkc3RhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXIpOwogICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZXJUcmFucyhjdHh0LT5hbSwgdG1wLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnRlcik7CgogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbGVtLT5yZWZEZWNsICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbCgoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtLT5yZWZEZWNsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbS0+cmVmRGVjbC0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uKGN0eHQtPmFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbS0+bmFtZSwgdHlwZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW0tPm1pbk9jY3VycyA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBiYXNpY2FsbHkgYW4gZWxlbSogKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgb2xkc3RhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIGlmICgoZWxlbS0+bWF4T2NjdXJzID4gMSkgfHwgKGVsZW0tPm1pbk9jY3VycyA+IDEpKSB7CiAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFTdGF0ZVB0ciB0bXA7CiAgICAgICAgICAgICAgICAgICAgaW50IGNvdW50ZXI7CgogICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICBvbGRzdGF0ZSA9IGN0eHQtPnN0YXRlOwoKICAgICAgICAgICAgICAgICAgICBjb3VudGVyID0geG1sQXV0b21hdGFOZXdDb3VudGVyKGN0eHQtPmFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbS0+bWluT2NjdXJzIC0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0tPm1heE9jY3VycyAtIDEpOwoKICAgICAgICAgICAgICAgICAgICBpZiAoZWxlbS0+cmVmRGVjbCAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbCgoeG1sU2NoZW1hVHlwZVB0cikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0tPnJlZkRlY2wsIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtLT5yZWZEZWNsLT5uYW1lKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3VHJhbnNpdGlvbihjdHh0LT5hbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0tPm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB0bXAgPSBjdHh0LT5zdGF0ZTsKICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZWRUcmFucyhjdHh0LT5hbSwgdG1wLCBvbGRzdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudGVyKTsKICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9IHhtbEF1dG9tYXRhTmV3Q291bnRlclRyYW5zKGN0eHQtPmFtLCB0bXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnRlcik7CiAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW0tPm1pbk9jY3VycyA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIGJhc2ljYWxseSBhbiBlbGVtPyAqLwogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIG9sZHN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmIChlbGVtLT5yZWZEZWNsICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKCh4bWxTY2hlbWFUeXBlUHRyKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbS0+cmVmRGVjbCwgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0tPnJlZkRlY2wtPm5hbWUpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdUcmFuc2l0aW9uKGN0eHQtPmFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbS0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChlbGVtLT5taW5PY2N1cnMgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBiYXNpY2FsbHkgYW4gZWxlbT8gKi8KICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBvbGRzdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFOnsKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgc3VidHlwZXM7CgogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIElmIG1heCBhbmQgbWluIG9jY3VyYW5jZXMgYXJlIGRlZmF1bHQgKDEpIHRoZW4KICAgICAgICAgICAgICAgICAqIHNpbXBseSBpdGVyYXRlIG92ZXIgdGhlIHN1YnR5cGVzCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmICgodHlwZS0+bWluT2NjdXJzID09IDEpICYmICh0eXBlLT5tYXhPY2N1cnMgPT0gMSkpIHsKICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHR5cGUtPnN1YnR5cGVzOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdWJ0eXBlcyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChzdWJ0eXBlcywgY3R4dCwgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gc3VidHlwZXMtPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIG9sZHN0YXRlID0gY3R4dC0+c3RhdGU7CgogICAgICAgICAgICAgICAgICAgIGlmICh0eXBlLT5tYXhPY2N1cnMgPj0gVU5CT1VOREVEKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlLT5taW5PY2N1cnMgPiAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHRtcDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBjb3VudGVyOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlID0gY3R4dC0+c3RhdGU7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnRlciA9IHhtbEF1dG9tYXRhTmV3Q291bnRlcihjdHh0LT5hbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbk9jY3VycyAtIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVOQk9VTkRFRCk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSB0eXBlLT5zdWJ0eXBlczsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdWJ0eXBlcyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHN1YnR5cGVzLCBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHN1YnR5cGVzLT5uZXh0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wID0gY3R4dC0+c3RhdGU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZWRUcmFucyhjdHh0LT5hbSwgdG1wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkc3RhdGUsIGNvdW50ZXIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlclRyYW5zKGN0eHQtPmFtLCB0bXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgY291bnRlcik7CgogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSB0eXBlLT5zdWJ0eXBlczsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdWJ0eXBlcyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHN1YnR5cGVzLCBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHN1YnR5cGVzLT5uZXh0OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRzdGF0ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZS0+bWluT2NjdXJzID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIG9sZHN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCh0eXBlLT5tYXhPY2N1cnMgPiAxKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgKHR5cGUtPm1pbk9jY3VycyA+IDEpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgdG1wOwogICAgICAgICAgICAgICAgICAgICAgICBpbnQgY291bnRlcjsKCiAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0geG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRzdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgIG9sZHN0YXRlID0gY3R4dC0+c3RhdGU7CgogICAgICAgICAgICAgICAgICAgICAgICBjb3VudGVyID0geG1sQXV0b21hdGFOZXdDb3VudGVyKGN0eHQtPmFtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPm1pbk9jY3VycyAtCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLT5tYXhPY2N1cnMgLQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEpOwoKICAgICAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSB0eXBlLT5zdWJ0eXBlczsKICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHN1YnR5cGVzICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChzdWJ0eXBlcywgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gc3VidHlwZXMtPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgdG1wID0gY3R4dC0+c3RhdGU7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlZFRyYW5zKGN0eHQtPmFtLCB0bXAsIG9sZHN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudGVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdDb3VudGVyVHJhbnMoY3R4dC0+YW0sIHRtcCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ZXIpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZS0+bWluT2NjdXJzID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgb2xkc3RhdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gdHlwZS0+c3VidHlwZXM7CiAgICAgICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdWJ0eXBlcyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwoc3VidHlwZXMsIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHN1YnR5cGVzLT5uZXh0OwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlLT5taW5PY2N1cnMgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sQXV0b21hdGFOZXdFcHNpbG9uKGN0eHQtPmFtLCBvbGRzdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRTp7CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHN1YnR5cGVzOwogICAgICAgICAgICAgICAgeG1sQXV0b21hdGFTdGF0ZVB0ciBzdGFydCwgZW5kOwoKICAgICAgICAgICAgICAgIHN0YXJ0ID0gY3R4dC0+c3RhdGU7CiAgICAgICAgICAgICAgICBlbmQgPSB4bWxBdXRvbWF0YU5ld1N0YXRlKGN0eHQtPmFtKTsKCiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogaXRlcmF0ZSBvdmVyIHRoZSBzdWJ0eXBlcyBhbmQgcmVtZXJnZSB0aGUgZW5kIHdpdGggYW4KICAgICAgICAgICAgICAgICAqIGVwc2lsb24gdHJhbnNpdGlvbgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAodHlwZS0+bWF4T2NjdXJzID09IDEpIHsKICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHR5cGUtPnN1YnR5cGVzOwogICAgICAgICAgICAgICAgICAgIHdoaWxlIChzdWJ0eXBlcyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0gc3RhcnQ7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbChzdWJ0eXBlcywgY3R4dCwgbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3RXBzaWxvbihjdHh0LT5hbSwgY3R4dC0+c3RhdGUsIGVuZCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gc3VidHlwZXMtPm5leHQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBpbnQgY291bnRlcjsKICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIGhvcDsKICAgICAgICAgICAgICAgICAgICBpbnQgbWF4T2NjdXJzID0gdHlwZS0+bWF4T2NjdXJzID09IFVOQk9VTkRFRCA/CiAgICAgICAgICAgICAgICAgICAgICAgIFVOQk9VTkRFRCA6IHR5cGUtPm1heE9jY3VycyAtIDE7CiAgICAgICAgICAgICAgICAgICAgaW50IG1pbk9jY3VycyA9CiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPm1pbk9jY3VycyA8IDEgPyAwIDogdHlwZS0+bWluT2NjdXJzIC0gMTsKCiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiB1c2UgYSBjb3VudGVyIHRvIGtlZXAgdHJhY2sgb2YgdGhlIG51bWJlciBvZiB0cmFuc3Rpb25zCiAgICAgICAgICAgICAgICAgICAgICogd2hpY2ggd2VudCB0aHJvdWdoIHRoZSBjaG9pY2UuCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgY291bnRlciA9CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3Q291bnRlcihjdHh0LT5hbSwgbWluT2NjdXJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4T2NjdXJzKTsKICAgICAgICAgICAgICAgICAgICBob3AgPSB4bWxBdXRvbWF0YU5ld1N0YXRlKGN0eHQtPmFtKTsKCiAgICAgICAgICAgICAgICAgICAgc3VidHlwZXMgPSB0eXBlLT5zdWJ0eXBlczsKICAgICAgICAgICAgICAgICAgICB3aGlsZSAoc3VidHlwZXMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5zdGF0ZSA9IHN0YXJ0OwogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwoc3VidHlwZXMsIGN0eHQsIG5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIGN0eHQtPnN0YXRlLCBob3ApOwogICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHN1YnR5cGVzLT5uZXh0OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZWRUcmFucyhjdHh0LT5hbSwgaG9wLCBzdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudGVyKTsKICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50ZXJUcmFucyhjdHh0LT5hbSwgaG9wLCBlbmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnRlcik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAodHlwZS0+bWluT2NjdXJzID09IDApIHsKICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0Vwc2lsb24oY3R4dC0+YW0sIHN0YXJ0LCBlbmQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUgPSBlbmQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0FMTDp7CiAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YVN0YXRlUHRyIHN0YXJ0OwogICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciBzdWJ0eXBlczsKCQkvKiAKCQkgKiBDaGFuZ2VkLCBzaW5jZSB0eXBlIGluIG5vdCBhbiB4bWxTY2hlbWFFbGVtZW50IGhlcmUuCgkJICovCiAgICAgICAgICAgICAgICAvKiB4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW0gPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgdHlwZTsgKi8KCQl4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW07CiAgICAgICAgICAgICAgICBpbnQgbGF4OwoKICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gdHlwZS0+c3VidHlwZXM7CiAgICAgICAgICAgICAgICBpZiAoc3VidHlwZXMgPT0gTlVMTCkKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIHN0YXJ0ID0gY3R4dC0+c3RhdGU7CiAgICAgICAgICAgICAgICB3aGlsZSAoc3VidHlwZXMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0gc3RhcnQ7CgkJICAgIC8qCgkJICAgICAqIHRoZSBmb2xsb3dpbmcgJ2lmJyB3YXMgbmVlZGVkIHRvIGZpeCBidWcgMTM5ODk3CgkJICAgICAqIG5vdCBxdWl0ZSBzdXJlIHdoeSBpdCBvbmx5IG5lZWRzIHRvIGJlIGRvbmUgZm9yCgkJICAgICAqIGVsZW1lbnRzIHdpdGggYSAncmVmJywgYnV0IGl0IHNlZW1zIHRvIHdvcmsgb2suCgkJICAgICAqLwoJCSAgICBpZiAoc3VidHlwZXMtPnJlZiAhPSBOVUxMKQoJCSAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHN1YnR5cGVzLCBjdHh0LCBuYW1lKTsKICAgICAgICAgICAgICAgICAgICBlbGVtID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHN1YnR5cGVzOwkJICAgIAogICAgICAgICAgICAgICAgICAgIC8qIFRPRE8gOiBoYW5kbGUgdGhlIG5hbWVzcGFjZSB0b28gKi8KICAgICAgICAgICAgICAgICAgICBpZiAoKGVsZW0tPm1pbk9jY3VycyA9PSAxKSAmJiAoZWxlbS0+bWF4T2NjdXJzID09IDEpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHhtbEF1dG9tYXRhTmV3T25jZVRyYW5zKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUsIGVsZW0tPm5hbWUsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsIHN1YnR5cGVzKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0NvdW50VHJhbnMoY3R4dC0+YW0sIGN0eHQtPnN0YXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4dC0+c3RhdGUsIGVsZW0tPm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtLT5taW5PY2N1cnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtLT5tYXhPY2N1cnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlcyk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gc3VidHlwZXMtPm5leHQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBsYXggPSB0eXBlLT5taW5PY2N1cnMgPT0gMDsKICAgICAgICAgICAgICAgIGN0eHQtPnN0YXRlID0KICAgICAgICAgICAgICAgICAgICB4bWxBdXRvbWF0YU5ld0FsbFRyYW5zKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxheCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1JFU1RSSUNUSU9OOgogICAgICAgICAgICBpZiAodHlwZS0+c3VidHlwZXMgIT0gTlVMTCkKICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbCh0eXBlLT5zdWJ0eXBlcywgY3R4dCwgbmFtZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VYVEVOU0lPTjoKICAgICAgICAgICAgaWYgKHR5cGUtPmJhc2VUeXBlICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgc3VidHlwZXM7CgoJCWlmICh0eXBlLT5yZWN1cnNlKSB7IAoJCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsIAoJCSAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFQX1VOS05PV05fQkFTRV9UWVBFLCAKCQkJICAgICJTY2hlbWFzOiBleHRlbnNpb24gdHlwZSAlcyBpcyByZWN1cnNpdmVcbiIsIAoJCQkJICB0eXBlLT5uYW1lLCBOVUxMKTsgCgkJICAgIHJldHVybjsgCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB0eXBlLT5yZWN1cnNlID0gMTsgCiAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwodHlwZS0+YmFzZVR5cGUsIGN0eHQsIG5hbWUpOwogICAgICAgICAgICAJdHlwZS0+cmVjdXJzZSA9IDA7CiAgICAgICAgICAgICAgICBzdWJ0eXBlcyA9IHR5cGUtPnN1YnR5cGVzOwogICAgICAgICAgICAgICAgd2hpbGUgKHN1YnR5cGVzICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwoc3VidHlwZXMsIGN0eHQsIG5hbWUpOwogICAgICAgICAgICAgICAgICAgIHN1YnR5cGVzID0gc3VidHlwZXMtPm5leHQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZS0+c3VidHlwZXMgIT0gTlVMTCkKICAgICAgICAgICAgICAgIHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbCh0eXBlLT5zdWJ0eXBlcywgY3R4dCwgbmFtZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0dST1VQOgogICAgICAgICAgICBpZiAodHlwZS0+c3VidHlwZXMgPT0gTlVMTCkgewoJICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHJncm91cDsKCQlpZiAodHlwZS0+cmVmICE9IE5VTEwpIHsKCQkgICAgcmdyb3VwID0geG1sU2NoZW1hR2V0R3JvdXAoY3R4dC0+c2NoZW1hLCB0eXBlLT5yZWYsCgkJICAgIAkJCSAgIHR5cGUtPnJlZk5zKTsKCQkgICAgaWYgKHJncm91cCA9PSBOVUxMKSB7CgkJICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsCgkJCQkgICAgICBYTUxfU0NIRU1BUF9VTktOT1dOX1JFRiwKCQkJCSJTY2hlbWFzOiBncm91cCAlcyByZWZlcmVuY2UgJXMgaXMgbm90IGZvdW5kIiwKCQkJCW5hbWUsIHR5cGUtPnJlZik7CgkJCXJldHVybjsKCQkgICAgfQoJCSAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwocmdyb3VwLCBjdHh0LCBuYW1lKTsKCQkgICAgYnJlYWs7CgkJfQogICAgICAgICAgICB9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWDoKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQ6CiAgICAgICAgICAgIGlmICh0eXBlLT5zdWJ0eXBlcyAhPSBOVUxMKQogICAgICAgICAgICAgICAgeG1sU2NoZW1hQnVpbGRBQ29udGVudE1vZGVsKHR5cGUtPnN1YnR5cGVzLCBjdHh0LCBuYW1lKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRm91bmQgdW5leHBlY3RlZCB0eXBlICVkIGluICVzIGNvbnRlbnQgbW9kZWxcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLT50eXBlLCBuYW1lKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgfQp9CgovKioKICogeG1sU2NoZW1hQnVpbGRDb250ZW50TW9kZWw6CiAqIEBlbGVtOiAgdGhlIGVsZW1lbnQKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEBuYW1lOiAgdGhlIGVsZW1lbnQgbmFtZQogKgogKiBCdWlsZHMgdGhlIGNvbnRlbnQgbW9kZWwgb2YgdGhlIGVsZW1lbnQuCiAqLwpzdGF0aWMgdm9pZAp4bWxTY2hlbWFCdWlsZENvbnRlbnRNb2RlbCh4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgeG1sQ2hhciAqIG5hbWUpCnsKICAgIHhtbEF1dG9tYXRhU3RhdGVQdHIgc3RhcnQ7CgogICAgaWYgKGVsZW0tPmNvbnRNb2RlbCAhPSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGlmIChlbGVtLT5zdWJ0eXBlcyA9PSBOVUxMKSB7CiAgICAgICAgZWxlbS0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfQU5ZOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChlbGVtLT5zdWJ0eXBlcy0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkKICAgICAgICByZXR1cm47CiAgICBpZiAoKGVsZW0tPnN1YnR5cGVzLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUMpIHx8CiAgICAgICAgKGVsZW0tPnN1YnR5cGVzLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFKSkKICAgICAgICByZXR1cm47CgojaWZkZWYgREVCVUdfQ09OVEVOVAogICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgIkJ1aWxkaW5nIGNvbnRlbnQgbW9kZWwgZm9yICVzXG4iLCBuYW1lKTsKI2VuZGlmCgogICAgY3R4dC0+YW0gPSB4bWxOZXdBdXRvbWF0YSgpOwogICAgaWYgKGN0eHQtPmFtID09IE5VTEwpIHsKICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgIkNhbm5vdCBjcmVhdGUgYXV0b21hdGEgZm9yIGVsZW0gJXNcbiIsIG5hbWUpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIHN0YXJ0ID0gY3R4dC0+c3RhdGUgPSB4bWxBdXRvbWF0YUdldEluaXRTdGF0ZShjdHh0LT5hbSk7CiAgICB4bWxTY2hlbWFCdWlsZEFDb250ZW50TW9kZWwoZWxlbS0+c3VidHlwZXMsIGN0eHQsIG5hbWUpOwogICAgeG1sQXV0b21hdGFTZXRGaW5hbFN0YXRlKGN0eHQtPmFtLCBjdHh0LT5zdGF0ZSk7CiAgICBlbGVtLT5jb250TW9kZWwgPSB4bWxBdXRvbWF0YUNvbXBpbGUoY3R4dC0+YW0pOwogICAgaWYgKGVsZW0tPmNvbnRNb2RlbCA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBlbGVtLT5ub2RlLCBYTUxfU0NIRU1BU19FUlJfSU5URVJOQUwsCiAgICAgICAgICAgICAgICAgICAgICAiZmFpbGVkIHRvIGNvbXBpbGUgJXMgY29udGVudCBtb2RlbFxuIiwgbmFtZSwgTlVMTCk7CiAgICB9IGVsc2UgaWYgKHhtbFJlZ2V4cElzRGV0ZXJtaW5pc3QoZWxlbS0+Y29udE1vZGVsKSAhPSAxKSB7CiAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBlbGVtLT5ub2RlLCBYTUxfU0NIRU1BU19FUlJfTk9UREVURVJNSU5JU1QsCiAgICAgICAgICAgICAgICAgICAgICAiQ29udGVudCBtb2RlbCBvZiAlcyBpcyBub3QgZGV0ZXJtaW5pc3Q6XG4iLCBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICB9IGVsc2UgewojaWZkZWYgREVCVUdfQ09OVEVOVF9SRUdFWFAKICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgIkNvbnRlbnQgbW9kZWwgb2YgJXM6XG4iLCBuYW1lKTsKICAgICAgICB4bWxSZWdleHBQcmludChzdGRlcnIsIGVsZW0tPmNvbnRNb2RlbCk7CiNlbmRpZgogICAgfQogICAgY3R4dC0+c3RhdGUgPSBOVUxMOwogICAgeG1sRnJlZUF1dG9tYXRhKGN0eHQtPmFtKTsKICAgIGN0eHQtPmFtID0gTlVMTDsKfQoKLyoqCiAqIHhtbFNjaGVtYVJlZkZpeHVwQ2FsbGJhY2s6CiAqIEBlbGVtOiAgdGhlIHNjaGVtYSBlbGVtZW50IGNvbnRleHQKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqCiAqIEZyZWUgdGhlIHJlc291cmNlcyBhc3NvY2lhdGVkIHRvIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVJlZkZpeHVwQ2FsbGJhY2soeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtLAogICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogY29udGV4dCBBVFRSSUJVVEVfVU5VU0VELAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHhtbENoYXIgKiBuYW1lc3BhY2UgQVRUUklCVVRFX1VOVVNFRCkKewogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChlbGVtID09IE5VTEwpKQogICAgICAgIHJldHVybjsKCiAgICBpZiAoZWxlbS0+cmVmICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFFbGVtZW50UHRyIGVsZW1EZWNsOwoKICAgICAgICBpZiAoZWxlbS0+c3VidHlwZXMgIT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGVsZW0tPm5vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQVBfSU5WQUxJRF9SRUZfQU5EX1NVQlRZUEUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlNjaGVtYXM6IGVsZW1lbnQgJXMgaGFzIGJvdGggcmVmIGFuZCBzdWJ0eXBlXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIE5VTEwpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGVsZW1EZWNsID0geG1sU2NoZW1hR2V0RWxlbShjdHh0LT5zY2hlbWEsIGVsZW0tPnJlZiwgZWxlbS0+cmVmTnMsIDApOwoKICAgICAgICBpZiAoZWxlbURlY2wgPT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGVsZW0tPm5vZGUsIAoJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCSJFbGVtZW50IFwiJXNcIjogdGhlIFFOYW1lIFwiJXNcIiBvZiB0aGUgYXR0cmlidXRlICIKCQkiXCJyZWZcIiBkb2VzIG5vdCByZXNvbHZlIHRvIGEgc2NoZW1hICIKCQkiY29tcG9uZW50LlxuIiwKCQluYW1lLCBlbGVtLT5yZWYpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGVsZW0tPnJlZkRlY2wgPSBlbGVtRGVjbDsKICAgIH0gZWxzZSBpZiAoZWxlbS0+bmFtZWRUeXBlICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWNsOwoKICAgICAgICBpZiAoZWxlbS0+c3VidHlwZXMgIT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGVsZW0tPm5vZGUsIFhNTF9TQ0hFTUFQX1RZUEVfQU5EX1NVQlRZUEUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIlNjaGVtYXM6IGVsZW1lbnQgJXMgaGFzIGJvdGggdHlwZSBhbmQgc3VidHlwZVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCBOVUxMKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICB0eXBlRGVjbCA9IHhtbFNjaGVtYUdldFR5cGUoY3R4dC0+c2NoZW1hLCBlbGVtLT5uYW1lZFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0tPm5hbWVkVHlwZU5zKTsKCiAgICAgICAgaWYgKHR5cGVEZWNsID09IE5VTEwpIHsKICAgICAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBlbGVtLT5ub2RlLCAKCQlYTUxfU0NIRU1BUF9TUkNfUkVTT0xWRSwKCQkiRWxlbWVudCBcIiVzXCI6IHRoZSBRTmFtZSBcIiVzXCIgb2YgdGhlIGF0dHJpYnV0ZSAiCgkJIlwidHlwZVwiIGRvZXMgbm90IHJlc29sdmUgdG8gYSBzY2hlbWEgIgoJCSJjb21wb25lbnQuXG4iLCBuYW1lLCBlbGVtLT5uYW1lZFR5cGUpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIGVsZW0tPnN1YnR5cGVzID0gdHlwZURlY2w7CiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZUxpc3RSZWZGaXh1cDoKICogQHR5cGU6ICB0aGUgc2NoZW1hIHR5cGUgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICoKICogRml4dXAgb2YgdGhlIGl0ZW1UeXBlIHJlZmVyZW5jZSBvZiB0aGUgbGlzdCB0eXBlLgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hUGFyc2VMaXN0UmVmRml4dXAoeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQpCnsgICAgCiAgICAvKgogICAgKiBzcmMtbGlzdC1pdGVtVHlwZS1vci1zaW1wbGVUeXBlCiAgICAqIEVpdGhlciB0aGUgaXRlbVR5cGUgW2F0dHJpYnV0ZV0gb3IgdGhlIDxzaW1wbGVUeXBlPiBbY2hpbGRdIG9mIAogICAgKiB0aGUgPGxpc3Q+IGVsZW1lbnQgbXVzdCBiZSBwcmVzZW50LCBidXQgbm90IGJvdGguIAogICAgKi8KICAgIGlmICgoKHR5cGUtPmJhc2UgPT0gTlVMTCkgJiYgCgkgKHR5cGUtPnN1YnR5cGVzID09IE5VTEwpKSB8fAoJKCh0eXBlLT5iYXNlICE9IE5VTEwpICYmCgkgKHR5cGUtPnN1YnR5cGVzICE9IE5VTEwpKSkgewkKCS8qIAoJKiBzcmMtcmVzdHJpY3Rpb24tYmFzZS1vci1zaW1wbGVUeXBlCgkqIEVpdGhlciB0aGUgYmFzZSBbYXR0cmlidXRlXSBvciB0aGUgc2ltcGxlVHlwZSBbY2hpbGRdIG9mIHRoZSAKCSogPHJlc3RyaWN0aW9uPiBlbGVtZW50IG11c3QgYmUgcHJlc2VudCwgYnV0IG5vdCBib3RoLiAKCSovCgl4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsCgkgICAgWE1MX1NDSEVNQVBfU1JDX0xJU1RfSVRFTVRZUEVfT1JfU0lNUExFVFlQRSwKCSAgICAiTGlzdCBcIiVzXCI6ICIKCSAgICAiRWl0aGVyIHRoZSBcImJhc2VcIiBhdHRyaWJ1dGUgb3IgdGhlIDxzaW1wbGVUeXBlPiBjaGlsZCAiCgkgICAgIm11c3QgYmUgcHJlc2VudCwgYnV0IG5vdCBib3RoLlxuIiwKCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKICAgIH0gZWxzZSBpZiAodHlwZS0+YmFzZSE9IE5VTEwpIHsgICAgICAgIAkKICAgICAgICB0eXBlLT5zdWJ0eXBlcyA9IHhtbFNjaGVtYUdldFR5cGUoY3R4dC0+c2NoZW1hLCB0eXBlLT5iYXNlLCB0eXBlLT5iYXNlTnMpOwogICAgICAgIGlmICh0eXBlLT5zdWJ0eXBlcyA9PSBOVUxMKSB7CiAgICAgICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwgWE1MX1NDSEVNQVBfVU5LTk9XTl9UWVBFLAogICAgICAgICAgICAgICAgICAgICAgICAgICJMaXN0IFwiJXNcIiByZWZlcmVuY2VzIGFuIHVua25vd24gaXRlbSB0eXBlOiBcIiVzXCJcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+bmFtZSwgdHlwZS0+YmFzZSk7CiAgICAgICAgfQogICAgfSAgICAgICAgICAgICAgIAogICAgaWYgKCh0eXBlLT5zdWJ0eXBlcyAhPSBOVUxMKSAmJiAKCSh0eXBlLT5zdWJ0eXBlcy0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV04pKQoJeG1sU2NoZW1hVHlwZUZpeHVwKHR5cGUtPnN1YnR5cGVzLCBjdHh0LCBOVUxMKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVBhcnNlVW5pb25SZWZDaGVjazoKICogQHR5cGVEZWNsOiAgdGhlIHNjaGVtYSB0eXBlIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqCiAqIENoZWNrcyBhbmQgYnVpbGRzIHRoZSBtZW1iZXJUeXBlcyBvZiB0aGUgdW5pb24gdHlwZS4KICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIGVycm9yLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hUGFyc2VVbmlvblJlZkNoZWNrKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgY29uc3QgeG1sQ2hhciAqY3VyLCAqZW5kLCAqcHJlZml4LCAqbmNOYW1lLCAqbmFtZXNwYWNlOwogICAgeG1sQ2hhciAqdG1wOwogICAgeG1sU2NoZW1hVHlwZUxpbmtQdHIgbGluaywgbGFzdExpbmsgPSBOVUxMLCBwcmV2TGluaywgc3ViTGluaywgbmV3TGluazsKICAgIHhtbFNjaGVtYVR5cGVQdHIgbWVtYmVyVHlwZSwgY3R4dFR5cGU7CiAgICB4bWxOc1B0ciBuczsKICAgIGludCBsZW47CgogICAgLyogMSBJZiB0aGUgPHVuaW9uPiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4sIHRoZW4gW0RlZmluaXRpb246XSAgCiAgICAqIGRlZmluZSB0aGUgZXhwbGljaXQgbWVtYmVycyBhcyB0aGUgdHlwZSBkZWZpbml0aW9ucyC3cmVzb2x2ZWS3IAogICAgKiB0byBieSB0aGUgaXRlbXMgaW4gdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZSBtZW1iZXJUeXBlcyBbYXR0cmlidXRlXSwgCiAgICAqIGlmIGFueSwgZm9sbG93ZWQgYnkgdGhlIHR5cGUgZGVmaW5pdGlvbnMgY29ycmVzcG9uZGluZyB0byB0aGUgCiAgICAqIDxzaW1wbGVUeXBlPnMgYW1vbmcgdGhlIFtjaGlsZHJlbl0gb2YgPHVuaW9uPiwgaWYgYW55LiAKICAgICovICAgCgogICAgaWYgKHR5cGUtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX1VOSU9OKQogICAgICAgIHJldHVybiAoLTEpOwogICAgaWYgKGN0eHQtPmN0eHRUeXBlID09IE5VTEwpIHsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwKCSAgICBYTUxfU0NIRU1BU19FUlJfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFQYXJzZVVuaW9uUmVmQ2hlY2ssIG5vIHBhcmVudCB0eXBlICIKCSAgICAiYXZhaWxhYmxlIiwgTlVMTCwgTlVMTCk7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIC8qCiAgICAqIHNyYy11bmlvbi1tZW1iZXJUeXBlcy1vci1zaW1wbGVUeXBlcwogICAgKiBFaXRoZXIgdGhlIG1lbWJlclR5cGVzIFthdHRyaWJ1dGVdIG9mIHRoZSA8dW5pb24+IGVsZW1lbnQgbXVzdCAKICAgICogYmUgbm9uLWVtcHR5IG9yIHRoZXJlIG11c3QgYmUgYXQgbGVhc3Qgb25lIHNpbXBsZVR5cGUgW2NoaWxkXS4gCiAgICAqLwogICAgaWYgKCh0eXBlLT5iYXNlID09IE5VTEwpICYmIAoJKHR5cGUtPnN1YnR5cGVzID09IE5VTEwpKSB7CgkvKiAKCSogc3JjLXJlc3RyaWN0aW9uLWJhc2Utb3Itc2ltcGxlVHlwZQoJKiBFaXRoZXIgdGhlIGJhc2UgW2F0dHJpYnV0ZV0gb3IgdGhlIHNpbXBsZVR5cGUgW2NoaWxkXSBvZiB0aGUgCgkqIDxyZXN0cmljdGlvbj4gZWxlbWVudCBtdXN0IGJlIHByZXNlbnQsIGJ1dCBub3QgYm90aC4gCgkqLwoJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJICAgIFhNTF9TQ0hFTUFQX1NSQ19VTklPTl9NRU1CRVJUWVBFU19PUl9TSU1QTEVUWVBFUywKCSAgICAiVW5pb24gXCIlc1wiOiAiCgkgICAgIkVpdGhlciB0aGUgXCJtZW1iZXJUeXBlc1wiIGF0dHJpYnV0ZSBtdXN0IGJlIG5vbi1lbXB0eSAiCgkgICAgIm9yIHRoZXJlIG11c3QgYmUgYXQgbGVhc3Qgb25lIDxzaW1wbGVUeXBlPiBjaGlsZC5cbiIsCgkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CiAgICB9IAoJCiAgICBjdHh0VHlwZSA9IGN0eHQtPmN0eHRUeXBlOwogICAgaWYgKHR5cGUtPmJhc2UgIT0gTlVMTCkgewoJY3VyID0gdHlwZS0+YmFzZTsKCWRvIHsKCSAgICB3aGlsZSAoSVNfQkxBTktfQ0goKmN1cikpCgkJY3VyKys7CgkgICAgZW5kID0gY3VyOwoJICAgIHdoaWxlICgoKmVuZCAhPSAwKSAmJiAoIShJU19CTEFOS19DSCgqZW5kKSkpKQoJCWVuZCsrOwoJICAgIGlmIChlbmQgPT0gY3VyKQoJCWJyZWFrOwoJICAgIHRtcCA9IHhtbFN0cm5kdXAoY3VyLCBlbmQgLSBjdXIpOwoJICAgIG5jTmFtZSA9IHhtbFNwbGl0UU5hbWUzKHRtcCwgJmxlbik7CgkgICAgaWYgKG5jTmFtZSAhPSBOVUxMKSB7CgkJcHJlZml4ID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCB0bXAsIGxlbik7CgkgICAgfSBlbHNlIHsKCQlwcmVmaXggPSBOVUxMOwoJCW5jTmFtZSA9IHRtcDsKCSAgICB9CgkgICAgbnMgPSB4bWxTZWFyY2hOcyh0eXBlLT5ub2RlLT5kb2MsIHR5cGUtPm5vZGUsIHByZWZpeCk7CgkgICAgaWYgKG5zID09IE5VTEwpIHsKCQlpZiAocHJlZml4ICE9IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLCBYTUxfU0NIRU1BUF9QUkVGSVhfVU5ERUZJTkVELAoJCQkiVW5pb24gXCIlc1wiOiB0aGUgbmFtZXNwYWNlIHByZWZpeCBvZiBtZW1iZXIgdHlwZSAiCgkJCSJcIiVzXCIgaXMgdW5kZWZpbmVkXG4iLAoJCQl0eXBlLT5uYW1lLCAoY29uc3QgeG1sQ2hhciAqKSB0bXApOwoJCX0KCQluYW1lc3BhY2UgPSBOVUxMOwoJICAgIH0gZWxzZSB7CgkJbmFtZXNwYWNlID0geG1sRGljdExvb2t1cChjdHh0LT5kaWN0LCBucy0+aHJlZiwgLTEpOwoJICAgIH0gICAgICAgIAoJICAgIG1lbWJlclR5cGUgPSB4bWxTY2hlbWFHZXRUeXBlKGN0eHQtPnNjaGVtYSwgbmNOYW1lLCBuYW1lc3BhY2UpOwoJICAgIGlmIChtZW1iZXJUeXBlID09IE5VTEwpIHsKCQl4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsIFhNTF9TQ0hFTUFQX1VOS05PV05fTUVNQkVSX1RZUEUsCgkJICAgICJVbmlvbiBcIiVzXCIgcmVmZXJlbmNlcyBhbiB1bmtub3duIG1lbWJlciB0eXBlIFwiJXNcIi5cbiIsCgkJICAgIHR5cGUtPm5hbWUsICAoY29uc3QgeG1sQ2hhciAqKSB0bXApOwoJICAgIH0gZWxzZSB7CgkJaWYgKG1lbWJlclR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSAKCQkgICAgeG1sU2NoZW1hVHlwZUZpeHVwKG1lbWJlclR5cGUsIGN0eHQsIE5VTEwpOwkgICAgCgkJbGluayA9ICh4bWxTY2hlbWFUeXBlTGlua1B0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFUeXBlTGluaykpOwoJCWlmIChsaW5rID09IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBhIHR5cGUgbGluayIsIE5VTEwpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkJbGluay0+dHlwZSA9IG1lbWJlclR5cGU7CgkJbGluay0+bmV4dCA9IE5VTEw7CgkJaWYgKGxhc3RMaW5rID09IE5VTEwpCgkJICAgIGN0eHRUeXBlLT5tZW1iZXJUeXBlcyA9IGxpbms7CQkgICAgCgkJZWxzZSAKCQkgICAgbGFzdExpbmstPm5leHQgPSBsaW5rOwoJCWxhc3RMaW5rID0gbGluazsJICAgIAoJICAgIH0KCSAgICB4bWxGcmVlKHRtcCk7CgkgICAgY3VyID0gZW5kOwoJfSB3aGlsZSAoKmN1ciAhPSAwKTsgCiAgICB9CiAgICAvKgogICAgKiBBZGQgbG9jYWwgc2ltcGxlIHR5cGVzLAogICAgKi8gICAgCiAgICBtZW1iZXJUeXBlID0gdHlwZS0+c3VidHlwZXM7CiAgICB3aGlsZSAobWVtYmVyVHlwZSAhPSBOVUxMKSB7CglpZiAobWVtYmVyVHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV04pCgkgICAgeG1sU2NoZW1hVHlwZUZpeHVwKG1lbWJlclR5cGUsIGN0eHQsIE5VTEwpOwkgICAgCglsaW5rID0gKHhtbFNjaGVtYVR5cGVMaW5rUHRyKSB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVR5cGVMaW5rKSk7CglpZiAobGluayA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hUEVyck1lbW9yeShjdHh0LCAiYWxsb2NhdGluZyBhIHR5cGUgbGluayIsIE5VTEwpOwoJICAgIHJldHVybiAoLTEpOwoJfQoJbGluay0+dHlwZSA9IG1lbWJlclR5cGU7CglsaW5rLT5uZXh0ID0gTlVMTDsKCWlmIChsYXN0TGluayA9PSBOVUxMKQoJICAgIGN0eHRUeXBlLT5tZW1iZXJUeXBlcyA9IGxpbms7CQkgICAgCgllbHNlIAoJICAgIGxhc3RMaW5rLT5uZXh0ID0gbGluazsKCWxhc3RMaW5rID0gbGluazsKCW1lbWJlclR5cGUgPSBtZW1iZXJUeXBlLT5uZXh0OwogICAgfSAgICAKICAgIC8qCiAgICAqIFRoZSBhY3R1YWwgdmFsdWUgaXMgdGhlbiBmb3JtZWQgYnkgcmVwbGFjaW5nIGFueSB1bmlvbiB0eXBlIAogICAgKiBkZWZpbml0aW9uIGluIHRoZSC3ZXhwbGljaXQgbWVtYmVyc7cgd2l0aCB0aGUgbWVtYmVycyBvZiB0aGVpciAKICAgICoge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSwgaW4gb3JkZXIuCiAgICAqLwogICAgbGluayA9IGN0eHRUeXBlLT5tZW1iZXJUeXBlczsKICAgIHdoaWxlIChsaW5rICE9IE5VTEwpIHsKCWlmIChsaW5rLT50eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9VTklPTikgewoJICAgIHN1YkxpbmsgPSBsaW5rLT50eXBlLT5tZW1iZXJUeXBlczsJICAgIAoJICAgIGlmIChzdWJMaW5rICE9IE5VTEwpIHsJCQoJCWxpbmstPnR5cGUgPSBzdWJMaW5rLT50eXBlOwoJCWlmIChzdWJMaW5rLT5uZXh0ICE9IE5VTEwpIHsKCQkgICAgbGFzdExpbmsgPSBsaW5rLT5uZXh0OwoJCSAgICBzdWJMaW5rID0gc3ViTGluay0+bmV4dDsJCQoJCSAgICBwcmV2TGluayA9IGxpbms7CgkJICAgIHdoaWxlIChzdWJMaW5rICE9IE5VTEwpIHsJCSAgICAKCQkJbmV3TGluayA9ICh4bWxTY2hlbWFUeXBlTGlua1B0cikgCgkJCSAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYVR5cGVMaW5rKSk7CgkJCWlmIChuZXdMaW5rID09IE5VTEwpIHsKCQkJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgImFsbG9jYXRpbmcgYSB0eXBlIGxpbmsiLCAKCQkJCU5VTEwpOwoJCQkgICAgcmV0dXJuICgtMSk7CgkJCX0KCQkJbmV3TGluay0+dHlwZSA9IG1lbWJlclR5cGU7CSAgICAKCQkJcHJldkxpbmstPm5leHQgPSBuZXdMaW5rOwoJCQlwcmV2TGluayA9IG5ld0xpbms7CgkJCW5ld0xpbmstPm5leHQgPSBsYXN0TGluazsKCQkJCgkJCXN1YkxpbmsgPSBzdWJMaW5rLT5uZXh0OwoJCSAgICB9CgkJfQoJICAgIH0KCX0KCWxpbmsgPSBsaW5rLT5uZXh0OwogICAgfSAgICAKCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hR2V0T255bW91c1R5cGVOYW1lOgogKiBAYXR0cjogIHRoZSBhdHRyaWJ1dGUgZGVjbGFyYXRpb24vdXNlCiAqCiAqIFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGF0dHJpYnV0ZTsgaWYgdGhlIGF0dHJpYnV0ZQogKiBpcyBhIHJlZmVyZW5jZSwgdGhlIG5hbWUgb2YgdGhlIHJlZmVyZW5jZWQgZ2xvYmFsIHR5cGUgd2lsbCBiZSByZXR1cm5lZC4KICovCnN0YXRpYyBjb25zdCB4bWxDaGFyICoKeG1sU2NoZW1hR2V0T255bW91c0F0dHJOYW1lKHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyKSAKewogICAgaWYgKGF0dHItPnJlZiAhPSBOVUxMKSAKCXJldHVybihhdHRyLT5yZWYpOwogICAgZWxzZQoJcmV0dXJuKGF0dHItPm5hbWUpOwkKfQoKLyoqCiAqIHhtbFNjaGVtYUdldE9ueW1vdXNUYXJnZXROc1VSSToKICogQHR5cGU6ICB0aGUgdHlwZSAoZWxlbWVudCBvciBhdHRyaWJ1dGUpCiAqCiAqIFJldHVybnMgdGhlIHRhcmdldCBuYW1lc3BhY2UgVVJJIG9mIHRoZSB0eXBlOyBpZiB0aGUgdHlwZSBpcyBhIHJlZmVyZW5jZSwKICogdGhlIHRhcmdldCBuYW1lc3BhY2Ugb2YgdGhlIHJlZmVyZW5jZWQgdHlwZSB3aWxsIGJlIHJldHVybmVkLgogKi8Kc3RhdGljIGNvbnN0IHhtbENoYXIgKgp4bWxTY2hlbWFHZXRPbnltb3VzVGFyZ2V0TnNVUkkoeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVCkgewoJaWYgKHR5cGUtPnJlZiAhPSBOVUxMKQoJICAgIHJldHVybigoKHhtbFNjaGVtYUVsZW1lbnRQdHIpKCh4bWxTY2hlbWFFbGVtZW50UHRyKSAKCQl0eXBlKS0+c3VidHlwZXMpLT50YXJnZXROYW1lc3BhY2UpOwoJZWxzZQoJICAgIHJldHVybigoKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHR5cGUpLT50YXJnZXROYW1lc3BhY2UpOwogICAgfSBlbHNlIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEUpIHsKCWlmICh0eXBlLT5yZWYgIT0gTlVMTCkKCSAgICByZXR1cm4oKCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpKCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIAoJCXR5cGUpLT5zdWJ0eXBlcyktPnRhcmdldE5hbWVzcGFjZSk7CgllbHNlCgkgICAgcmV0dXJuKCgoeG1sU2NoZW1hQXR0cmlidXRlUHRyKSB0eXBlKS0+dGFyZ2V0TmFtZXNwYWNlKTsKICAgIH0gZWxzZSAKCXJldHVybiAoTlVMTCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFJc0Rlcml2ZWRGcm9tQnVpbHRJblR5cGU6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSB0eXBlIGRlZmluaXRpb24KICogQHZhbFR5cGU6IHRoZSB2YWx1ZSB0eXBlCiAqIAogKgogKiBSZXR1cm5zIDEgaWYgdGhlIHR5cGUgaGFzIHRoZSBnaXZlbiB2YWx1ZSB0eXBlLCBvcgogKiBpcyBkZXJpdmVkIGZyb20gc3VjaCBhIHR5cGUuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUlzRGVyaXZlZEZyb21CdWlsdEluVHlwZSh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsIAoJCQkJICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIGludCB2YWxUeXBlKQp7CiAgICAvKiBUT0RPOiBDaGVjayBpZiB0aGlzIHdvcmtzIGluIGV2ZXJ5IGNhc2UuICovCiAgICBpZiAoKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSAmJgoJCSh0eXBlLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUMpKSB7CgkJaWYgKHR5cGUtPmJ1aWx0SW5UeXBlID09IHZhbFR5cGUpCgkJCXJldHVybigxKTsKICAgIH0gZWxzZSBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFKSB7CglpZiAoKCh4bWxTY2hlbWFBdHRyaWJ1dGVQdHIpIHR5cGUpLT5zdWJ0eXBlcyAhPSBOVUxMKSAKCSAgICByZXR1cm4oeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKGN0eHQsIAoJCSgoeG1sU2NoZW1hQXR0cmlidXRlUHRyKSB0eXBlKS0+c3VidHlwZXMsIHZhbFR5cGUpKTsKICAgIH0gZWxzZSBpZiAoKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1JFU1RSSUNUSU9OKSB8fAoJKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0VYVEVOU0lPTikpIHsKCWlmICh0eXBlLT5iYXNlVHlwZSAhPSBOVUxMKSAKCSAgICByZXR1cm4oeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKGN0eHQsIHR5cGUtPmJhc2VUeXBlLCAKCQl2YWxUeXBlKSk7CiAgICB9IGVsc2UgaWYgKCh0eXBlLT5zdWJ0eXBlcyAhPSBOVUxMKSAmJgoJKCh0eXBlLT5zdWJ0eXBlcy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgfHwKCSAodHlwZS0+c3VidHlwZXMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVCkgfHwKCSAodHlwZS0+c3VidHlwZXMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkgfHwKCSAodHlwZS0+c3VidHlwZXMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UKSkpIHsKCXJldHVybih4bWxTY2hlbWFJc0Rlcml2ZWRGcm9tQnVpbHRJblR5cGUoY3R4dCwgdHlwZS0+c3VidHlwZXMsIAoJICAgIHZhbFR5cGUpKTsKICAgIH0KCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlOgogKiBAdHlwZTogIHRoZSBzaW1wbGVUeXBlIGRlZmluaXRpb24KICoKICogUmV0dXJucyB0aGUgcHJpbWl0aXZlIHR5cGUgb2YgdGhlIGdpdmVuIHR5cGUgb3IKICogTlVMTCBpbiBjYXNlIG9mIGVycm9yLgogKi8Kc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIKeG1sU2NoZW1hR2V0UHJpbWl0aXZlVHlwZSh4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHdoaWxlICh0eXBlICE9IE5VTEwpIHsKCWlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfQlVJTFRJTl9QUklNSVRJVkUpCgkgICAgcmV0dXJuICh0eXBlKTsKCXR5cGUgPSB0eXBlLT5iYXNlVHlwZTsKICAgIH0KCiAgICByZXR1cm4gKE5VTEwpOwp9CgoKLyoqCiAqIHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVXNlc093bmVkOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24KICogQGN1cjogdGhlIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbiBsaXN0CiAqIEBsYXN0VXNlOiB0aGUgdG9wIG9mIHRoZSBhdHRyaWJ1dGUgdXNlIGxpc3QKICoKICogQnVpbGRzIHRoZSBhdHRyaWJ1dGUgdXNlcyBsaXN0IG9uIHRoZSBnaXZlbiBjb21wbGV4IHR5cGUuCiAqIFRoaXMgb25lIGlzIHN1cHBvc2VkIHRvIGJlIGNhbGxlZCBieSAKICogeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVWYWxpZGF0aW9uIG9ubHkuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVXNlc093bmVkKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCQkgeG1sU2NoZW1hQXR0cmlidXRlUHRyIGN1ciwKCQkJCSB4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rUHRyICp1c2VzLAoJCQkJIHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIgKmxhc3RVc2UpCnsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIgdG1wOwogICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CglpZiAoY3VyLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUCkgewoJICAgIC8qIAoJICAgICAqIFczQzogIjIgVGhlIHthdHRyaWJ1dGUgdXNlc30gb2YgdGhlIGF0dHJpYnV0ZSBncm91cHMgt3Jlc29sdmVktyAKCSAgICAgKiB0byBieSB0aGUgt2FjdHVhbCB2YWx1ZbdzIG9mIHRoZSByZWYgW2F0dHJpYnV0ZV0gb2YgdGhlIAoJICAgICAqIDxhdHRyaWJ1dGVHcm91cD4gW2NoaWxkcmVuXSwgaWYgYW55LiIKCSAgICAgKi8KCSAgICBpZiAoeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVVc2VzT3duZWQoY3R4dCwgCgkJKCh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0cikgY3VyKS0+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+bnNTZXQgPSBOVUxMOwoJICAgIH0KCSAgICBpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSB7CgkJY29tcGxldGVXaWxkLT5uZWdOc1NldCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJCWlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpCgkJICAgIHJldHVybiAoLTEpOwoJICAgIH0KCSAgICBjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9IE5VTEw7Cgl9IGVsc2UgaWYgKCghbnNGb3VuZCkgJiYgYWJzZW50Rm91bmQpIHsKCSAgICAvKgoJICAgICogNS4zIElmIHRoZSBzZXQgUyBpbmNsdWRlcyC3YWJzZW50tyBidXQgbm90IHRoZSBuZWdhdGVkIAoJICAgICogbmFtZXNwYWNlIG5hbWUsIHRoZW4gdGhlIHVuaW9uIGlzIG5vdCBleHByZXNzaWJsZS4KCSAgICAqLwoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgY29tcGxldGVXaWxkLT5ub2RlLCAKCQlYTUxfU0NIRU1BUF9VTklPTl9OT1RfRVhQUkVTU0lCTEUsCgkJIlRoZSB1bmlvbiBvZiB0aGUgd2lsY2FyZCBpcyBub3QgZXhwcmVzc2libGVcbiIsCgkJTlVMTCwgTlVMTCk7CQoJICAgIHJldHVybihYTUxfU0NIRU1BUF9VTklPTl9OT1RfRVhQUkVTU0lCTEUpOwoJfSBlbHNlIGlmICgoIW5zRm91bmQpICYmICghYWJzZW50Rm91bmQpKSB7CgkgICAgLyogCgkgICAgKiA1LjQgSWYgdGhlIHNldCBTIGRvZXMgbm90IGluY2x1ZGUgZWl0aGVyIHRoZSBuZWdhdGVkIG5hbWVzcGFjZSAKCSAgICAqIG5hbWUgb3Igt2Fic2VudLcsIHRoZW4gd2hpY2hldmVyIG9mIE8xIG9yIE8yIGlzIGEgcGFpciBvZiBub3QgCgkgICAgKiBhbmQgYSBuYW1lc3BhY2UgbmFtZSBtdXN0IGJlIHRoZSB2YWx1ZS4KCSAgICAqLwoJICAgIGlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpIHsKCQlpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KGNvbXBsZXRlV2lsZC0+bnNTZXQpOwoJCSAgICBjb21wbGV0ZVdpbGQtPm5zU2V0ID0gTlVMTDsKCQl9CgkJY29tcGxldGVXaWxkLT5uZWdOc1NldCA9IHhtbFNjaGVtYU5ld1dpbGRjYXJkTnNDb25zdHJhaW50KGN0eHQpOwoJCWlmIChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpCgkJICAgIHJldHVybiAoLTEpOwoJCWNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlOwoJICAgIH0KCX0KCXJldHVybiAoMCk7CiAgICB9CiAgICAvKiAKICAgICAqIDYuCiAgICAgKi8KICAgIGlmICgoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPT0gTlVMTCkgJiYKCShjdXJXaWxkLT5uc1NldCAhPSBOVUxMKSkgfHwKCSgoY3VyV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgCgkoY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlID09IE5VTEwpICYmCgkoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSkpIHsKCglpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkgICAgY3VyID0gY29tcGxldGVXaWxkLT5uc1NldDsKCX0gZWxzZSB7CgkgICAgY3VyID0gY3VyV2lsZC0+bnNTZXQ7Cgl9CQoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgaWYgKGN1ci0+dmFsdWUgPT0gTlVMTCkgewoJCS8qCgkJKiA2LjEgSWYgdGhlIHNldCBTIGluY2x1ZGVzILdhYnNlbnS3LCB0aGVuIGFueSBtdXN0IGJlIHRoZSAKCQkqIHZhbHVlLgoJCSovCgkJY29tcGxldGVXaWxkLT5hbnkgPSAxOwoJCWlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ICE9IE5VTEwpIHsKCQkgICAgeG1sU2NoZW1hRnJlZVdpbGRjYXJkTnNTZXQoY29tcGxldGVXaWxkLT5uc1NldCk7CgkJICAgIGNvbXBsZXRlV2lsZC0+bnNTZXQgPSBOVUxMOwoJCX0KCQlpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSB7CgkJICAgIHhtbEZyZWUoY29tcGxldGVXaWxkLT5uZWdOc1NldCk7CgkJICAgIGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPSBOVUxMOwoJCX0KCQlyZXR1cm4gKDApOwoJICAgIH0KCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CQkJCglpZiAoY29tcGxldGVXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIDYuMiBJZiB0aGUgc2V0IFMgZG9lcyBub3QgaW5jbHVkZSC3YWJzZW50tywgdGhlbiBhIHBhaXIgb2Ygbm90IAoJICAgICogYW5kILdhYnNlbnS3IG11c3QgYmUgdGhlIHZhbHVlLgoJICAgICovCgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJCXhtbFNjaGVtYUZyZWVXaWxkY2FyZE5zU2V0KGNvbXBsZXRlV2lsZC0+bnNTZXQpOwoJCWNvbXBsZXRlV2lsZC0+bnNTZXQgPSBOVUxMOwoJICAgIH0KCSAgICBjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID0geG1sU2NoZW1hTmV3V2lsZGNhcmROc0NvbnN0cmFpbnQoY3R4dCk7CgkgICAgaWYgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgPT0gTlVMTCkKCQlyZXR1cm4gKC0xKTsKCSAgICBjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSA9IE5VTEw7Cgl9CglyZXR1cm4gKDApOwogICAgfQogICAgcmV0dXJuICgwKTsKCn0KCi8qKgogKiB4bWxTY2hlbWFJbnRlcnNlY3RXaWxkY2FyZHM6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAY29tcGxldGVXaWxkOiAgdGhlIGZpcnN0IHdpbGRjYXJkCiAqIEBjdXJXaWxkOiB0aGUgc2Vjb25kIHdpbGRjYXJkIAogKgogKiBJbnRlcnNlY3RzIHRoZSBuYW1lc3BhY2UgY29uc3RyYWludHMgb2YgdGhlIGdpdmVuIHdpbGRjYXJkcy4KICogQGNvbXBsZXRlV2lsZCB3aWxsIGhvbGQgdGhlIHJlc3VsdGluZyBpbnRlcnNlY3Rpb24uCiAqIFJldHVybnMgYSBwb3NpdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUsIC0xIGluIGNhc2Ugb2YgYW4KICogaW50ZXJuYWwgZXJyb3IsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFJbnRlcnNlY3RXaWxkY2FyZHMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAJCQkgICAgCgkJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciBjb21wbGV0ZVdpbGQsCgkJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciBjdXJXaWxkKQp7CiAgICB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIGN1ciwgY3VyQiwgcHJldiwgIHRtcDsKCiAgICAvKgogICAgKiAxIElmIE8xIGFuZCBPMiBhcmUgdGhlIHNhbWUgdmFsdWUsIHRoZW4gdGhhdCB2YWx1ZSBtdXN0IGJlIHRoZSAKICAgICogdmFsdWUuCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPmFueSA9PSBjdXJXaWxkLT5hbnkpICYmCgkoKGNvbXBsZXRlV2lsZC0+bnNTZXQgPT0gTlVMTCkgPT0gKGN1cldpbGQtPm5zU2V0ID09IE5VTEwpKSAmJgoJKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpID09IChjdXJXaWxkLT5uZWdOc1NldCA9PSBOVUxMKSkpIHsKCQoJaWYgKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ID09IE5VTEwpIHx8CgkgICAgKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID09IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSkpIHsKCSAgICAKCSAgICBpZiAoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSB7CgkJaW50IGZvdW5kID0gMDsKCQkKCQkvKiAKCQkqIENoZWNrIGVxdWFsaXR5IG9mIHNldHMuIAoJCSovCgkJY3VyID0gY29tcGxldGVXaWxkLT5uc1NldDsKCQl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCQkgICAgZm91bmQgPSAwOwoJCSAgICBjdXJCID0gY3VyV2lsZC0+bnNTZXQ7CgkJICAgIHdoaWxlIChjdXJCICE9IE5VTEwpIHsKCQkJaWYgKGN1ci0+dmFsdWUgPT0gY3VyQi0+dmFsdWUpIHsKCQkJICAgIGZvdW5kID0gMTsKCQkJICAgIGJyZWFrOwoJCQl9CgkJCWN1ckIgPSBjdXJCLT5uZXh0OwoJCSAgICB9CgkJICAgIGlmICghZm91bmQpCgkJCWJyZWFrOwoJCSAgICBjdXIgPSBjdXItPm5leHQ7CgkJfQoJCWlmIChmb3VuZCkKCQkgICAgcmV0dXJuKDApOwoJICAgIH0gZWxzZQoJCXJldHVybigwKTsKCX0KICAgIH0JICAgICAgICAKICAgIC8qCiAgICAqIDIgSWYgZWl0aGVyIE8xIG9yIE8yIGlzIGFueSwgdGhlbiB0aGUgb3RoZXIgbXVzdCBiZSB0aGUgdmFsdWUuCiAgICAqLwogICAgaWYgKChjb21wbGV0ZVdpbGQtPmFueSAhPSBjdXJXaWxkLT5hbnkpICYmIChjb21wbGV0ZVdpbGQtPmFueSkpIHsJCSAgICAKCWlmICh4bWxTY2hlbWFDbG9uZVdpbGRjYXJkTnNDb25zdHJhaW50cyhjdHh0LCAmY29tcGxldGVXaWxkLCBjdXJXaWxkKSA9PSAtMSkKCSAgICByZXR1cm4oLTEpOwkgICAgCglyZXR1cm4oMCk7CiAgICB9CSAgICAgICAgICAgIAogICAgLyoKICAgICogMyBJZiBlaXRoZXIgTzEgb3IgTzIgaXMgYSBwYWlyIG9mIG5vdCBhbmQgYSB2YWx1ZSAoYSBuYW1lc3BhY2UgCiAgICAqIG5hbWUgb3Igt2Fic2VudLcpIGFuZCB0aGUgb3RoZXIgaXMgYSBzZXQgb2YgKG5hbWVzcGFjZSBuYW1lcyBvciAKICAgICogt2Fic2VudLcpLCB0aGVuIHRoYXQgc2V0LCBtaW51cyB0aGUgbmVnYXRlZCB2YWx1ZSBpZiBpdCB3YXMgaW4gCiAgICAqIHRoZSBzZXQsIG1pbnVzILdhYnNlbnS3IGlmIGl0IHdhcyBpbiB0aGUgc2V0LCBtdXN0IGJlIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKChjb21wbGV0ZVdpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmIChjdXJXaWxkLT5uc1NldCAhPSBOVUxMKSkgfHwKCSgoY3VyV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgKGNvbXBsZXRlV2lsZC0+bnNTZXQgIT0gTlVMTCkpKSB7Cgljb25zdCB4bWxDaGFyICpuZWc7CgkKCWlmIChjb21wbGV0ZVdpbGQtPm5zU2V0ID09IE5VTEwpIHsKCSAgICBuZWcgPSBjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZTsKCSAgICBpZiAoeG1sU2NoZW1hQ2xvbmVXaWxkY2FyZE5zQ29uc3RyYWludHMoY3R4dCwgJmNvbXBsZXRlV2lsZCwgY3VyV2lsZCkgPT0gLTEpCgkJcmV0dXJuKC0xKTsKCX0gZWxzZQoJICAgIG5lZyA9IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZTsKCS8qCgkqIFJlbW92ZSBhYnNlbnQgYW5kIG5lZ2F0ZWQuCgkqLwoJcHJldiA9IE5VTEw7CgljdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgaWYgKGN1ci0+dmFsdWUgPT0gTlVMTCkgewoJCWlmIChwcmV2ID09IE5VTEwpIAoJCSAgICBjb21wbGV0ZVdpbGQtPm5zU2V0ID0gY3VyLT5uZXh0OwoJCWVsc2UgCgkJICAgIHByZXYtPm5leHQgPSBjdXItPm5leHQ7CgkJeG1sRnJlZShjdXIpOwoJCWJyZWFrOwoJICAgIH0KCSAgICBwcmV2ID0gY3VyOwoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0KCWlmIChuZWcgIT0gTlVMTCkgewoJICAgIHByZXYgPSBOVUxMOwoJICAgIGN1ciA9IGNvbXBsZXRlV2lsZC0+bnNTZXQ7CgkgICAgd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkJaWYgKGN1ci0+dmFsdWUgPT0gbmVnKSB7CgkJICAgIGlmIChwcmV2ID09IE5VTEwpIAoJCQljb21wbGV0ZVdpbGQtPm5zU2V0ID0gY3VyLT5uZXh0OwoJCSAgICBlbHNlIAoJCQlwcmV2LT5uZXh0ID0gY3VyLT5uZXh0OwoJCSAgICB4bWxGcmVlKGN1cik7CgkJICAgIGJyZWFrOwoJCX0KCQlwcmV2ID0gY3VyOwoJCWN1ciA9IGN1ci0+bmV4dDsKCSAgICB9Cgl9CgoJcmV0dXJuKDApOwogICAgfQkgICAgICAgIAogICAgLyoKICAgICogNCBJZiBib3RoIE8xIGFuZCBPMiBhcmUgc2V0cyBvZiAobmFtZXNwYWNlIG5hbWVzIG9yILdhYnNlbnS3KSwgCiAgICAqIHRoZW4gdGhlIGludGVyc2VjdGlvbiBvZiB0aG9zZSBzZXRzIG11c3QgYmUgdGhlIHZhbHVlLgogICAgKi8KICAgIGlmICgoY29tcGxldGVXaWxkLT5uc1NldCAhPSBOVUxMKSAmJiAoY3VyV2lsZC0+bnNTZXQgIT0gTlVMTCkpIHsJCQoJaW50IGZvdW5kOwoJCgljdXIgPSBjb21wbGV0ZVdpbGQtPm5zU2V0OwoJcHJldiA9IE5VTEw7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBmb3VuZCA9IDA7CgkgICAgY3VyQiA9IGN1cldpbGQtPm5zU2V0OwoJICAgIHdoaWxlIChjdXJCICE9IE5VTEwpIHsKCQlpZiAoY3VyLT52YWx1ZSA9PSBjdXJCLT52YWx1ZSkgewoJCSAgICBmb3VuZCA9IDE7CgkJICAgIGJyZWFrOwoJCX0KCQljdXJCID0gY3VyQi0+bmV4dDsKCSAgICB9CgkgICAgaWYgKCFmb3VuZCkgewoJCWlmIChwcmV2ID09IE5VTEwpCgkJICAgIGNvbXBsZXRlV2lsZC0+bnNTZXQgPSBjdXItPm5leHQ7CgkJZWxzZSAKCQkgICAgcHJldi0+bmV4dCA9IGN1ci0+bmV4dDsKCQl0bXAgPSBjdXItPm5leHQ7CgkJeG1sRnJlZShjdXIpOwoJCWN1ciA9IHRtcDsJCQoJCWNvbnRpbnVlOwoJICAgIH0KCSAgICBwcmV2ID0gY3VyOwoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0JCgkJICAgIAkJCglyZXR1cm4oMCk7CiAgICB9ICAgIAogICAgLyogNSBJZiB0aGUgdHdvIGFyZSBuZWdhdGlvbnMgb2YgZGlmZmVyZW50IG5hbWVzcGFjZSBuYW1lcywgCiAgICAqIHRoZW4gdGhlIGludGVyc2VjdGlvbiBpcyBub3QgZXhwcmVzc2libGUKICAgICovCSAgICAKICAgIGlmICgoY29tcGxldGVXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAKCShjdXJXaWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlICE9IGN1cldpbGQtPm5lZ05zU2V0LT52YWx1ZSkgJiYKCShjb21wbGV0ZVdpbGQtPm5lZ05zU2V0LT52YWx1ZSAhPSBOVUxMKSAmJiAKCShjdXJXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gTlVMTCkpIHsKCgl4bWxTY2hlbWFQRXJyKGN0eHQsIGNvbXBsZXRlV2lsZC0+bm9kZSwgWE1MX1NDSEVNQVBfSU5URVJTRUNUSU9OX05PVF9FWFBSRVNTSUJMRSwKCSAgICAiVGhlIGludGVyc2VjdGlvbiBvZiB0aGUgd2lsY2FyZCBpcyBub3QgZXhwcmVzc2libGVcbiIsCgkgICAgTlVMTCwgTlVMTCk7CQoJcmV0dXJuKFhNTF9TQ0hFTUFQX0lOVEVSU0VDVElPTl9OT1RfRVhQUkVTU0lCTEUpOwogICAgfQkJICAgIAogICAgLyogCiAgICAqIDYgSWYgdGhlIG9uZSBpcyBhIG5lZ2F0aW9uIG9mIGEgbmFtZXNwYWNlIG5hbWUgYW5kIHRoZSBvdGhlciAKICAgICogaXMgYSBuZWdhdGlvbiBvZiC3YWJzZW50tywgdGhlbiB0aGUgb25lIHdoaWNoIGlzIHRoZSBuZWdhdGlvbiAKICAgICogb2YgYSBuYW1lc3BhY2UgbmFtZSBtdXN0IGJlIHRoZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQgIT0gTlVMTCkgJiYgKGN1cldpbGQtPm5lZ05zU2V0ICE9IE5VTEwpICYmCgkoY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgIT0gY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlKSAmJgoJKGNvbXBsZXRlV2lsZC0+bmVnTnNTZXQtPnZhbHVlID09IE5VTEwpKSB7CQoJY29tcGxldGVXaWxkLT5uZWdOc1NldC0+dmFsdWUgPSAgY3VyV2lsZC0+bmVnTnNTZXQtPnZhbHVlOyAKICAgIH0KICAgIHJldHVybigwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUlzV2lsZGNhcmROc0NvbnN0cmFpbnRTdWJzZXQ6CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAd2lsZEE6ICB0aGUgZmlyc3Qgd2lsZGNhcmQKICogQHdpbGRCOiB0aGUgc2Vjb25kIHdpbGRjYXJkIAogKgogKiBSZXR1cm5zIDEgaWYgdGhlIG5hbWVzcGFjZSBjb25zdHJhaW50IG9mIEB3aWxkQSBpcyBhbiBpbnRlbnNpb25hbCAKICogc3Vic2V0IG9mIEB3aWxkQiwgMCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUlzV2lsZGNhcmROc0NvbnN0cmFpbnRTdWJzZXQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQgQVRUUklCVVRFX1VOVVNFRCwgCgkJCSAgICB4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkQSwKCQkJICAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyIHdpbGRCKQp7ICAgIAoKICAgIC8qCiAgICAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogV2lsZGNhcmQgU3Vic2V0IAogICAgKi8KICAgIC8qCiAgICAqIDEgc3VwZXIgbXVzdCBiZSBhbnkuIAogICAgKi8KICAgIGlmICh3aWxkQi0+YW55KQoJcmV0dXJuICgxKTsKICAgIC8qCiAgICAqIDIuMSBzdWIgbXVzdCBiZSBhIHBhaXIgb2Ygbm90IGFuZCBhIG5hbWVzcGFjZSBuYW1lIG9yILdhYnNlbnS3LgogICAgKiAyLjIgc3VwZXIgbXVzdCBiZSBhIHBhaXIgb2Ygbm90IGFuZCB0aGUgc2FtZSB2YWx1ZS4KICAgICovCiAgICBpZiAoKHdpbGRBLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKHdpbGRCLT5uZWdOc1NldCAhPSBOVUxMKSAmJgoJKHdpbGRBLT5uZWdOc1NldC0+dmFsdWUgPT0gd2lsZEEtPm5lZ05zU2V0LT52YWx1ZSkpCglyZXR1cm4gKDEpOyAgICAKICAgIC8qIAogICAgKiAzLjEgc3ViIG11c3QgYmUgYSBzZXQgd2hvc2UgbWVtYmVycyBhcmUgZWl0aGVyIG5hbWVzcGFjZSBuYW1lcyBvciC3YWJzZW50ty4gCiAgICAqLwogICAgaWYgKHdpbGRBLT5uc1NldCAhPSBOVUxMKSB7CgkvKgoJKiAzLjIuMSBzdXBlciBtdXN0IGJlIHRoZSBzYW1lIHNldCBvciBhIHN1cGVyc2V0IHRoZXJlb2YuIAoJKi8KCWlmICh3aWxkQi0+bnNTZXQgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgY3VyLCBjdXJCOwoJICAgIGludCBmb3VuZCA9IDA7CgkgICAgCgkgICAgY3VyID0gd2lsZEEtPm5zU2V0OwoJICAgIHdoaWxlIChjdXIgIT0gTlVMTCkgewoJCWZvdW5kID0gMDsKCQljdXJCID0gd2lsZEItPm5zU2V0OwoJCXdoaWxlIChjdXJCICE9IE5VTEwpIHsKCQkgICAgaWYgKGN1ci0+dmFsdWUgPT0gY3VyQi0+dmFsdWUpIHsKCQkJZm91bmQgPSAxOwoJCQlicmVhazsKCQkgICAgfQoJCSAgICBjdXJCID0gY3VyQi0+bmV4dDsKCQl9CgkJaWYgKCFmb3VuZCkKCQkgICAgcmV0dXJuICgwKTsKCQljdXIgPSBjdXItPm5leHQ7CgkgICAgfQoJICAgIGlmIChmb3VuZCkKCQlyZXR1cm4gKDEpOyAKCX0gZWxzZSBpZiAod2lsZEItPm5lZ05zU2V0ICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFXaWxkY2FyZE5zUHRyIGN1cjsKCSAgICAvKgoJICAgICogMy4yLjIgc3VwZXIgbXVzdCBiZSBhIHBhaXIgb2Ygbm90IGFuZCBhIG5hbWVzcGFjZSBuYW1lIG9yIAoJICAgICogt2Fic2VudLcgYW5kIHRoYXQgdmFsdWUgbXVzdCBub3QgYmUgaW4gc3ViJ3Mgc2V0LiAKCSAgICAqLwoJICAgIGN1ciA9IHdpbGRBLT5uc1NldDsKCSAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsJCQoJCWlmIChjdXItPnZhbHVlID09IHdpbGRCLT5uZWdOc1NldC0+dmFsdWUpCgkJICAgIHJldHVybiAoMCk7CgkJY3VyID0gY3VyLT5uZXh0OwoJICAgIH0gIAoJICAgIHJldHVybiAoMSk7Cgl9CiAgICB9CiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQnVpbGRDb21wbGV0ZUF0dHJpYnV0ZVdpbGRjYXJkOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQGF0dHJzOiB0aGUgYXR0cmlidXRlIGxpc3QgCiAqIEBjb21wbGV0ZVdpbGQ6IHRoZSByZXN1bHRpbmcgY29tcGxldGUgd2lsZGNhcmQKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIGVycm9yLCAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQnVpbGRDb21wbGV0ZUF0dHJpYnV0ZVdpbGRjYXJkKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCQkJCSAgICAKCQkJCSAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRycywKCQkJCSAgIHhtbFNjaGVtYVdpbGRjYXJkUHRyICpjb21wbGV0ZVdpbGQpCQkJCQp7ICAgICAgICAKICAgIHdoaWxlIChhdHRycyAhPSBOVUxMKSB7CglpZiAoYXR0cnMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0FUVFJJQlVURUdST1VQKSB7CgkgICAgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgZ3JvdXA7CgoJICAgIGdyb3VwID0gKHhtbFNjaGVtYUF0dHJpYnV0ZUdyb3VwUHRyKSBhdHRyczsJICAKCSAgICBpZiAoKGdyb3VwLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9XSUxEQ0FSRF9CVUlMREVEKSA9PSAwKSB7CgkJaWYgKGdyb3VwLT5hdHRyaWJ1dGVzICE9IE5VTEwpIHsKCQkgICAgaWYgKHhtbFNjaGVtYUJ1aWxkQ29tcGxldGVBdHRyaWJ1dGVXaWxkY2FyZChjdHh0LCAKCQkJZ3JvdXAtPmF0dHJpYnV0ZXMsICZncm91cC0+YXR0cmlidXRlV2lsZGNhcmQpID09IC0xKQoJCQlyZXR1cm4gKC0xKTsKCQl9CgkJZ3JvdXAtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX0FUVFJHUk9VUF9XSUxEQ0FSRF9CVUlMREVEOwoJICAgIH0JCQoJICAgIGlmIChncm91cC0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgewkJCgkJaWYgKCpjb21wbGV0ZVdpbGQgPT0gTlVMTCkgewoJCSAgICAvKgoJCSAgICAqIENvcHkgdGhlIGZpcnN0IGVuY291bnRlcmVkIHdpbGRjYXJkIGFzIGNvbnRleHQsIGV4Y2VwdCBmb3IgdGhlIGFubm90YXRpb24uCgkJICAgICovCgkJICAgICpjb21wbGV0ZVdpbGQgPSB4bWxTY2hlbWFBZGRXaWxkY2FyZChjdHh0KTsKCQkgICAgKCpjb21wbGV0ZVdpbGQpLT50eXBlID0gWE1MX1NDSEVNQV9UWVBFX0FOWV9BVFRSSUJVVEU7CSAgIAoJCSAgICBpZiAoeG1sU2NoZW1hQ2xvbmVXaWxkY2FyZE5zQ29uc3RyYWludHMoY3R4dCwgCgkJCWNvbXBsZXRlV2lsZCwgZ3JvdXAtPmF0dHJpYnV0ZVdpbGRjYXJkKSA9PSAtMSkKCQkJcmV0dXJuICgtMSk7CgkJICAgICgqY29tcGxldGVXaWxkKS0+cHJvY2Vzc0NvbnRlbnRzID0gZ3JvdXAtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHM7CgkJICAgIC8qCgkJICAgICogQWx0aG91Z2ggdGhlIGNvbXBsZXRlIHdpbGRjYXJkIG1pZ2h0IG5vdCBjb3JyZXNwb25kIHRvIGFueQoJCSAgICAqIG5vZGUgaW4gdGhlIHNjaGVtYSwgd2Ugd2lsbCBzYXZlIHRoaXMgY29udGV4dCBub2RlLgoJCSAgICAqLwoJCSAgICAoKmNvbXBsZXRlV2lsZCktPm5vZGUgPSBncm91cC0+YXR0cmlidXRlV2lsZGNhcmQtPm5vZGU7ICAKCQkgICAgCgkJfSBlbHNlIGlmICh4bWxTY2hlbWFJbnRlcnNlY3RXaWxkY2FyZHMoY3R4dCwgKmNvbXBsZXRlV2lsZCwgZ3JvdXAtPmF0dHJpYnV0ZVdpbGRjYXJkKSA9PSAtMSkgewoJCSAgICB4bWxTY2hlbWFGcmVlV2lsZGNhcmQoKmNvbXBsZXRlV2lsZCk7CgkJICAgIHJldHVybiAoLTEpOwoJCX0JCQoJICAgIH0KCX0KCWF0dHJzID0gYXR0cnMtPm5leHQ7CiAgICB9CiAgIAkJICAgICAgICAgICAgICAgICAKICAgIHJldHVybiAoMCk7ICAgCn0KCi8qKgogKiB4bWxTY2hlbWFNYXRjaGVzV2lsZGNhcmROczoKICogQHdpbGQ6ICB0aGUgd2lsZGNhcmQKICogQG5zOiAgdGhlIG5hbWVzcGFjZQogKiAKICoKICogUmV0dXJucyAxIGlmIHRoZSBnaXZlbiBuYW1lc3BhY2UgbWF0Y2hlcyB0aGUgd2lsZGNhcmQsCiAqIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFNYXRjaGVzV2lsZGNhcmROcyh4bWxTY2hlbWFXaWxkY2FyZFB0ciB3aWxkLCBjb25zdCB4bWxDaGFyKiBucykKewogICAgaWYgKHdpbGQgPT0gTlVMTCkKCXJldHVybigwKTsKCiAgICBpZiAod2lsZC0+YW55KQoJcmV0dXJuKDEpOwogICAgZWxzZSBpZiAod2lsZC0+bnNTZXQgIT0gTlVMTCkgewoJeG1sU2NoZW1hV2lsZGNhcmROc1B0ciBjdXI7CgoJY3VyID0gd2lsZC0+bnNTZXQ7Cgl3aGlsZSAoY3VyICE9IE5VTEwpIHsKCSAgICBpZiAoeG1sU3RyRXF1YWwoY3VyLT52YWx1ZSwgbnMpKQoJCXJldHVybigxKTsKCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CiAgICB9IGVsc2UgaWYgKCh3aWxkLT5uZWdOc1NldCAhPSBOVUxMKSAmJiAobnMgIT0gTlVMTCkgJiYgCgkoIXhtbFN0ckVxdWFsKHdpbGQtPm5lZ05zU2V0LT52YWx1ZSwgbnMpKSkKCXJldHVybigxKTsJCgkKICAgIHJldHVybigwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbjoKICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0CiAqIEB0eXBlOiAgdGhlIGNvbXBsZXggdHlwZSBkZWZpbml0aW9uCiAqIAogKgogKiBCdWlsZHMgdGhlIHdpbGRjYXJkIGFuZCB0aGUgYXR0cmlidXRlIHVzZXMgb24gdGhlIGdpdmVuIGNvbXBsZXggdHlwZS4KICogUmV0dXJucyAtMSBpZiBhbiBpbnRlcm5hbCBlcnJvciBvY2N1cnMsIDAgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb24oeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCB4bWxTY2hlbWFUeXBlUHRyIHR5cGUpCnsKICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZVR5cGUgPSBOVUxMOwogICAgeG1sU2NoZW1hQXR0cmlidXRlTGlua1B0ciBjdXIsIGJhc2UsIHRtcCwgaWQgPSBOVUxMLCBwcmV2ID0gTlVMTCwgdXNlcyA9IE5VTEwsIAoJbGFzdFVzZSA9IE5VTEwsIGxhc3RCYXNlVXNlID0gTlVMTDsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyczsKICAgIHhtbFNjaGVtYVR5cGVQdHIgYW55VHlwZTsKICAgIGludCBiYXNlSXNBbnlUeXBlID0gMDsKCiAgICBhbnlUeXBlID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZVFlQRSk7CiAgICAvKiAKICAgICAqIENvbXBsZXggVHlwZSBEZWZpbml0aW9uIHdpdGggY29tcGxleCBjb250ZW50IFNjaGVtYSBDb21wb25lbnQuCiAgICAgKgogICAgICogQXR0cmlidXRlIHVzZXMuCiAgICAgKi8KICAgIGlmICh0eXBlLT5hdHRyaWJ1dGVVc2VzICE9IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKCQkgICAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbjogIgoJCSAgICAgICJhdHRyaWJ1dGUgdXNlcyBhbHJlYWR5IGJ1aWxkZWQuXG4iLAoJCSAgICAgIE5VTEwsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQogICAgaWYgKHR5cGUtPmJhc2VUeXBlID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKCQkgICAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUJ1aWxkQXR0cmlidXRlVmFsaWRhdGlvbjogIgoJCSAgICAgICJjb21wbGV4IHR5cGUgXCIlc1wiIGhhcyBubyBiYXNlIHR5cGUuXG4iLAoJCSAgICAgIHR5cGUtPm5hbWUsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQoKICAgIGJhc2VUeXBlID0gdHlwZS0+YmFzZVR5cGU7CiAgICBpZiAoYmFzZVR5cGUgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLCBYTUxfU0NIRU1BU19FUlJfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb246ICIKCSAgICAidHlwZSBoYXMgbm8gYmFzZSB0eXBlLlxuIiwKCSAgICBOVUxMLCBOVUxMKTsKCXJldHVybiAoLTEpOwogICAgfQoKICAgIGlmIChiYXNlVHlwZSA9PSBhbnlUeXBlKQoJYmFzZUlzQW55VHlwZSA9IDE7CiAgICAvKgogICAgICogSW5oZXJpdCB0aGUgYXR0cmlidXRlIHVzZXMgb2YgdGhlIGJhc2UgdHlwZS4KICAgICAqLwogICAgLyoKICAgICAqIE5PVEU6IEl0IGlzIGFsbG93ZWQgdG8gImV4dGVuZCIgdGhlIGFueVR5cGUgY29tcGxleCB0eXBlLgogICAgICovCiAgICBpZiAoIWJhc2VJc0FueVR5cGUpIHsKCWlmIChiYXNlVHlwZSAhPSBOVUxMKSB7CgkgICAgZm9yIChjdXIgPSBiYXNlVHlwZS0+YXR0cmlidXRlVXNlczsgY3VyICE9IE5VTEw7IGN1ciA9IGN1ci0+bmV4dCkgewoJCXRtcCA9ICh4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rUHRyKSAKCQkgICAgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBdHRyaWJ1dGVMaW5rKSk7CgkJaWYgKHRtcCA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgCgkJCSJidWlsZGluZyBhdHRyaWJ1dGUgdXNlcyBvZiBjb21wbGV4VHlwZSIsIE5VTEwpOwoJCSAgICByZXR1cm4gKC0xKTsKCQl9CgkJdG1wLT5hdHRyID0gY3VyLT5hdHRyOwoJCXRtcC0+bmV4dCA9IE5VTEw7CgkJaWYgKHR5cGUtPmF0dHJpYnV0ZVVzZXMgPT0gTlVMTCkgewoJCSAgICB0eXBlLT5hdHRyaWJ1dGVVc2VzID0gdG1wOwoJCX0gZWxzZSAKCQkgICAgbGFzdEJhc2VVc2UtPm5leHQgPSB0bXA7CgkJbGFzdEJhc2VVc2UgPSB0bXA7IAoJICAgIH0KCX0KICAgIH0KICAgIGlmICgodHlwZS0+c3VidHlwZXMgIT0gTlVMTCkgJiYgCgkoKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQpIHx8IAoJICh0eXBlLT5zdWJ0eXBlcy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFX0NPTlRFTlQpKSkgewoJYXR0cnMgPSB0eXBlLT5zdWJ0eXBlcy0+c3VidHlwZXMtPmF0dHJpYnV0ZXM7Cgl0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCA9IHR5cGUtPnN1YnR5cGVzLT5zdWJ0eXBlcy0+YXR0cmlidXRlV2lsZGNhcmQ7CiAgICB9IGVsc2UgewoJLyogU2hvcnQgaGFuZCBmb3JtIG9mIHRoZSBjb21wbGV4VHlwZS4gKi8KCWF0dHJzID0gdHlwZS0+YXR0cmlidXRlczsKICAgIH0KICAgIC8qCiAgICAqIEhhbmRsZSBhdHRyaWJ1dGUgd2lsZGNhcmRzLgogICAgKi8JCiAgICBpZiAoeG1sU2NoZW1hQnVpbGRDb21wbGV0ZUF0dHJpYnV0ZVdpbGRjYXJkKGN0eHQsIAoJYXR0cnMsICZ0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCkgPT0gLTEpIHsJICAgIAoJaWYgKCh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSAmJgoJICAgIC8qIEVpdGhlciB3ZSB1c2VkIHRoZSBzaG9ydCBoYW5kIGZvcm0uLi4gKi8KCSAgICAoKHR5cGUtPnN1YnR5cGVzID09IE5VTEwpIHx8CgkgICAgLyogT3IgY29tcGxleFR5cGUgLT4gcmVzdHJpY3Rpb24vZXh0ZW5zaW9uICovCgkgICAgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IHR5cGUtPnN1YnR5cGVzLT5zdWJ0eXBlcy0+YXR0cmlidXRlV2lsZGNhcmQpKSkKCSAgICB0eXBlLT5mbGFncyB8PSBYTUxfU0NIRU1BU19UWVBFX09XTkVEX0FUVFJfV0lMRENBUkQ7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIC8qCiAgICAqIFRPRE86IFRoaXMgIm9ud2VkX2F0dHJfd2lsZGNhcmQiIGlzIHF1aXRlIHNlbnNsZXNzOiB3ZSBzaG91bGQKICAgICogY3JlYXRlIHRoZSB3aWxkY2FyZCByaWdodCBmcm9tIHRoZSBzdGFydCBvbiB0aGUgY29tcGxleFR5cGUsCiAgICAqIHJhdGhlciB0aGFuIG9uIHRoZSA8cmVzdHJpY3Rpb24+LzxleHRlbnNpb24+LgogICAgKi8KICAgIGlmICgodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgJiYKCS8qIEVpdGhlciB3ZSB1c2VkIHRoZSBzaG9ydCBoYW5kIGZvcm0uLi4gKi8KCSgodHlwZS0+c3VidHlwZXMgPT0gTlVMTCkgfHwKCS8qIE9yIGNvbXBsZXhUeXBlIC0+IHJlc3RyaWN0aW9uL2V4dGVuc2lvbiAqLwoJKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IHR5cGUtPnN1YnR5cGVzLT5zdWJ0eXBlcy0+YXR0cmlidXRlV2lsZGNhcmQpKSkKCXR5cGUtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfT1dORURfQVRUUl9XSUxEQ0FSRDsKCiAgICBpZiAoKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT04pICYmIAoJKChiYXNlSXNBbnlUeXBlKSB8fAoJICgoYmFzZVR5cGUgIT0gTlVMTCkgJiYgCSAgICAKCSAgKGJhc2VUeXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSAmJgkgICAgICAKCSAgKGJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSkpKSB7CSAgICAKCWlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCAhPSBOVUxMKSB7CgkgICAgLyoKCSAgICAqIFVuaW9uIHRoZSBjb21wbGV0ZSB3aWxkY2FyZCB3aXRoIHRoZSBiYXNlIHdpbGRjYXJkLgoJICAgICovCgkgICAgaWYgKHhtbFNjaGVtYVVuaW9uV2lsZGNhcmRzKGN0eHQsIHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLCAKCQliYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQpID09IC0xKQoJCXJldHVybiAoLTEpOwoJfSBlbHNlIHsKCSAgICAvKgoJICAgICogSnVzdCBpbmhlcml0IHRoZSB3aWxkY2FyZC4KCSAgICAqLwoJICAgIHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkID0gYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkOwoJfQogICAgfQogICAgCiAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OKSB7CglpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgewoJICAgIC8qIAoJICAgICogRGVyaXZhdGlvbiBWYWxpZCAoUmVzdHJpY3Rpb24sIENvbXBsZXgpIAkgICAgCgkgICAgKiA0LjEgVGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBhbHNvIGhhdmUgb25lLiAKCSAgICAqLwoJICAgIGlmIChiYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgPT0gTlVMTCkgewkgICAgCgkJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLCBYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzRfMSwKCQkgICAgIlRoZSBkZXJpdmVkIHR5cGUgXCIlc1wiIGhhcyBhbiBhdHRyaWJ1dGUgd2lsZGNhcmQsICIKCQkgICAgImJ1dCB0aGUgYmFzZSB0eXBlIFwiJXNcIiBkb2VzIG5vdCBoYXZlIG9uZS5cbiIsCgkJICAgIHR5cGUtPm5hbWUsIGJhc2VUeXBlLT5uYW1lKTsKCQlyZXR1cm4gKDEpOwoJICAgIH0gZWxzZSBpZiAoeG1sU2NoZW1hSXNXaWxkY2FyZE5zQ29uc3RyYWludFN1YnNldChjdHh0LCAKCQl0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwgYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkKSA9PSAwKSB7CgkJLyogNC4yICovCgkJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLCBYTUxfU0NIRU1BUF9ERVJJVkFUSU9OX09LX1JFU1RSSUNUSU9OXzRfMiwKCQkgICAgIlRoZSB3aWxkY2FyZCBpbiB0aGUgZGVyaXZlZCB0eXBlIFwiJXNcIiBpcyBub3QgYSB2YWxpZCAiIAoJCSAgICAic3Vic2V0IG9mIHRoZSBvbmUgaW4gdGhlIGJhc2UgdHlwZSBcIiVzXCIuXG4iLAoJCSAgICB0eXBlLT5uYW1lLCBiYXNlVHlwZS0+bmFtZSk7CSAgICAKCQlyZXR1cm4gKDEpOwoJICAgIH0KCSAgICAvKiA0LjMgVW5sZXNzIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IGlzIHRoZSC3dXItdHlwZSAKCSAgICAqIGRlZmluaXRpb263LCB0aGUgY29tcGxleCB0eXBlIGRlZmluaXRpb24ncyB7YXR0cmlidXRlIAoJICAgICogd2lsZGNhcmR9J3Mge3Byb2Nlc3MgY29udGVudHN9IG11c3QgYmUgaWRlbnRpY2FsIHRvIG9yIAoJICAgICogc3Ryb25nZXIgdGhhbiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSdzIHthdHRyaWJ1dGUgCgkgICAgKiB3aWxkY2FyZH0ncyB7cHJvY2VzcyBjb250ZW50c30sIHdoZXJlIHN0cmljdCBpcyBzdHJvbmdlciAKCSAgICAqIHRoYW4gbGF4IGlzIHN0cm9uZ2VyIHRoYW4gc2tpcC4KCSAgICAqLwoJICAgIGlmICgodHlwZS0+YmFzZVR5cGUgIT0gYW55VHlwZSkgJiYgCgkJKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHMgPCAKCQliYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPnByb2Nlc3NDb250ZW50cykpIHsKCQl4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsIFhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fNF8zLAoJCSAgICAiVGhlIHByb2Nlc3MgY29udGVudHMgb2YgdGhlIHdpbGRjYXJkIGluIHRoZSAiCgkJICAgICJkZXJpdmVkIHR5cGUgXCIlc1wiIGlzIHdlYWtlciB0aGFuICIgCgkJICAgICJ0aGF0IGluIHRoZSBiYXNlIHR5cGUgXCIlc1wiLlxuIiwKCQkgICAgdHlwZS0+bmFtZSwgYmFzZVR5cGUtPm5hbWUpOwoJCXJldHVybiAoMSk7CgkgICAgfQoJfQogICAgfSBlbHNlIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OKSB7CgkvKgoJKiBEZXJpdmF0aW9uIFZhbGlkIChFeHRlbnNpb24pCgkqIEF0IHRoaXMgcG9pbnQgdGhlIHR5cGUgYW5kIHRoZSBiYXNlIGhhdmUgYm90aCwgZWl0aGVyCgkqIG5vIHdpbGRjYXJkIG9yIGEgd2lsZGNhcmQuCgkqLwoJaWYgKChiYXNlVHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgJiYKCSAgICAoYmFzZVR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkKSkgewoJICAgIC8qIDEuMyAqLwoJICAgIGlmICh4bWxTY2hlbWFJc1dpbGRjYXJkTnNDb25zdHJhaW50U3Vic2V0KGN0eHQsIAoJCWJhc2VUeXBlLT5hdHRyaWJ1dGVXaWxkY2FyZCwgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQpID09IDApIHsKCQl4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsIFhNTF9TQ0hFTUFQX0NPU19DVF9FWFRFTkRTXzFfMywKCQkgICAgIlRoZSB3aWxkY2FyZCBpbiB0aGUgZGVyaXZlZCB0eXBlIFwiJXNcIiBpcyBub3QgYSB2YWxpZCAiIAoJCSAgICAic3VwZXJzZXQgb2YgdGhlIG9uZSBpbiB0aGUgYmFzZSB0eXBlIFwiJXNcIi5cbiIsCgkJICAgIHR5cGUtPm5hbWUsIGJhc2VUeXBlLT5uYW1lKTsKCQlyZXR1cm4gKDEpOwkJCgkgICAgfQoJfQkJCiAgICB9CQoKICAgIC8qCiAgICAgKiBHYXRoZXIgYXR0cmlidXRlIHVzZXMgZGVmaW5lZCBieSB0aGlzIHR5cGUuCiAgICAgKi8KICAgIGlmIChhdHRycyAhPSBOVUxMKSB7CglpZiAoeG1sU2NoZW1hQnVpbGRBdHRyaWJ1dGVVc2VzT3duZWQoY3R4dCwgYXR0cnMsIAoJICAgICZ1c2VzLCAmbGFzdFVzZSkgPT0gLTEpIHsKCSAgICByZXR1cm4gKC0xKTsKCX0KICAgIH0KICAgIC8qIDMuNC42IC0+IENvbXBsZXggVHlwZSBEZWZpbml0aW9uIFByb3BlcnRpZXMgQ29ycmVjdCA0LgogICAgICogIlR3byBkaXN0aW5jdCBhdHRyaWJ1dGUgZGVjbGFyYXRpb25zIGluIHRoZSB7YXR0cmlidXRlIHVzZXN9IG11c3QgCiAgICAgKiBub3QgaGF2ZSBpZGVudGljYWwge25hbWV9cyBhbmQge3RhcmdldCBuYW1lc3BhY2V9cy4iCiAgICAgKgogICAgICogRm9yICJleHRlbnNpb24iIHRoaXMgaXMgZG9uZSBmdXJ0aGVyIGRvd24uCiAgICAgKi8KICAgIGlmICgodXNlcyAhPSBOVUxMKSAmJiAoKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT04pID09IDApKSB7CgljdXIgPSB1c2VzOwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgdG1wID0gY3VyLT5uZXh0OwoJICAgIHdoaWxlICh0bXAgIT0gTlVMTCkgewkgICAgCgkJaWYgKCh4bWxTdHJFcXVhbCh4bWxTY2hlbWFHZXRPbnltb3VzQXR0ck5hbWUoY3VyLT5hdHRyKSwgCgkJICAgIHhtbFNjaGVtYUdldE9ueW1vdXNBdHRyTmFtZSh0bXAtPmF0dHIpKSkgJiYKCQkgICAgKHhtbFN0ckVxdWFsKHhtbFNjaGVtYUdldE9ueW1vdXNUYXJnZXROc1VSSSgoeG1sU2NoZW1hVHlwZVB0cikgY3VyLT5hdHRyICksIAoJCSAgICB4bWxTY2hlbWFHZXRPbnltb3VzVGFyZ2V0TnNVUkkoKHhtbFNjaGVtYVR5cGVQdHIpIHRtcC0+YXR0cikpKSkgewoJCSAgICAKCQkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBjdXItPmF0dHItPm5vZGUsIFhNTF9TQ0hFTUFQX0NUX1BST1BTX0NPUlJFQ1RfNCwKCQkJImN0LXByb3BzLWNvcnJlY3QuNDogRHVwbGljYXRlIGF0dHJpYnV0ZSB1c2Ugd2l0aCB0aGUgbmFtZSBcIiVzXCIgc3BlY2lmaWVkXG4iLAoJCQl4bWxTY2hlbWFHZXRPbnltb3VzQXR0ck5hbWUoY3VyLT5hdHRyKSwgIE5VTEwpOwoJCSAgICBicmVhazsKCQl9CgkJdG1wID0gdG1wLT5uZXh0OwoJICAgIH0KCSAgICBjdXIgPSBjdXItPm5leHQ7Cgl9CiAgICB9CQogICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9SRVNUUklDVElPTikgewkKCS8qCgkgKiBEZXJpdmUgYnkgcmVzdHJpY3Rpb24uCgkgKi8KCWlmIChiYXNlSXNBbnlUeXBlKSB7CgkgICAgdHlwZS0+YXR0cmlidXRlVXNlcyA9IHVzZXM7Cgl9IGVsc2UgewoJICAgIGludCBmb3VuZDsKCgkgICAgY3VyID0gdXNlczsKCSAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKCQlmb3VuZCA9IDA7CgkJYmFzZSA9IHR5cGUtPmF0dHJpYnV0ZVVzZXM7CgkJd2hpbGUgKGJhc2UgIT0gTlVMTCkgewoJCSAgICBpZiAoKHhtbFN0ckVxdWFsKHhtbFNjaGVtYUdldE9ueW1vdXNBdHRyTmFtZShjdXItPmF0dHIpLCAKCQkJeG1sU2NoZW1hR2V0T255bW91c0F0dHJOYW1lKGJhc2UtPmF0dHIpKSkgJiYKCQkJKHhtbFN0ckVxdWFsKHhtbFNjaGVtYUdldE9ueW1vdXNUYXJnZXROc1VSSSgoeG1sU2NoZW1hVHlwZVB0cikgY3VyLT5hdHRyKSwgCgkJCXhtbFNjaGVtYUdldE9ueW1vdXNUYXJnZXROc1VSSSgoeG1sU2NoZW1hVHlwZVB0cikgYmFzZS0+YXR0cikpKSkgewoJCQkKCQkJZm91bmQgPSAxOwkgICAgCgkJCWlmICgoY3VyLT5hdHRyLT5vY2N1cnMgPT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfT1BUSU9OQUwpICYmCgkJCSAgICAoYmFzZS0+YXR0ci0+b2NjdXJzID09IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1JFUVVJUkVEKSkgewoJCQkgICAgLyoKCQkJICAgICogZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbiAyLjEuMQoJCQkgICAgKi8JCQkKCQkJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgY3VyLT5hdHRyLT5ub2RlLCAKCQkJCVhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fMl8xXzEsCgkJCQkiZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbi4yLjEuMTogIgoJCQkJIlRoZSBcIm9wdGlvbmFsXCIgYXR0cmlidXRlICIKCQkJCSJ1c2UgXCIlc1wiIGlzIGluY29uc2lzdGVudCB3aXRoIGEgbWF0Y2hpbmcgIgoJCQkJIlwicmVxdWlyZWRcIiBhdHRyaWJ1dGUgdXNlIG9mIHRoZSBiYXNlIHR5cGVcbiIsCgkJCQl4bWxTY2hlbWFHZXRPbnltb3VzQXR0ck5hbWUoY3VyLT5hdHRyKSwgTlVMTCk7CQkJCQkKCQkJfSBlbHNlIGlmICgoY3VyLT5hdHRyLT5vY2N1cnMgPT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfUFJPSElCSVRFRCkgJiYKCQkJICAgIChiYXNlLT5hdHRyLT5vY2N1cnMgPT0gWE1MX1NDSEVNQVNfQVRUUl9VU0VfUkVRVUlSRUQpKSB7CgkJCSAgICAvKgoJCQkgICAgKiBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uIDMgCgkJCSAgICAqLwoJCQkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBjdXItPmF0dHItPm5vZGUsIFhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fMywKCQkJCSJkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uLjM6ICIKCQkJCSJUaGUgXCJyZXF1aXJlZFwiIGF0dHJpYnV0ZSB1c2UgXCIlc1wiIG9mIHRoZSBiYXNlIHR5cGUgIgoJCQkJImRvZXMgbm90IGhhdmUgYSBtYXRjaGluZyBhdHRyaWJ1dGUgdXNlIGluIHRoZSBkZXJpdmVkIHR5cGVcbiIsCQkKCQkJCXhtbFNjaGVtYUdldE9ueW1vdXNBdHRyTmFtZShjdXItPmF0dHIpLCBOVUxMKTsKCQkJICAgIAoJCQl9IGVsc2UgewoJCQkgICAgLyoKCQkJICAgICogT3ZlcnJpZGUgdGhlIGF0dHJpYnV0ZSB1c2UuCgkJCSAgICAqLwoJCQkgICAgYmFzZS0+YXR0ciA9IGN1ci0+YXR0cjsKCQkJfQoJCQkvKgoJCQkqIFRPRE86IGRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24gIDIuMS4yICh7dHlwZSBkZWZpbml0aW9ufSBtdXN0IGJlIHZhbGlkbHkgZGVyaXZlZCkKCQkJKiBUT0RPOiBkZXJpdmF0aW9uLW9rLXJlc3RyaWN0aW9uICAyLjEuMyAKCQkJKi8KCQkJYnJlYWs7CgkJICAgIH0JCQkJCgkJICAgIGJhc2UgPSBiYXNlLT5uZXh0OwoJCX0KCQkKCQlpZiAoIWZvdW5kKSB7CgkJICAgIGlmIChjdXItPmF0dHItPm9jY3VycyAhPSBYTUxfU0NIRU1BU19BVFRSX1VTRV9QUk9ISUJJVEVEKSB7CgkJCS8qCgkJCSogZGVyaXZhdGlvbi1vay1yZXN0cmljdGlvbiAgMi4yCgkJCSovCgkJCWlmICgodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgIT0gTlVMTCkgJiYKCQkJICAgIHhtbFNjaGVtYU1hdGNoZXNXaWxkY2FyZE5zKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLAoJCQkJY3VyLT5hdHRyLT50YXJnZXROYW1lc3BhY2UpKQoJCQkgICAgZm91bmQgPSAxOwoKCQkJaWYgKCFmb3VuZCkgewoJCQkgICAgeG1sU2NoZW1hUEVycihjdHh0LCBjdXItPmF0dHItPm5vZGUsIFhNTF9TQ0hFTUFQX0RFUklWQVRJT05fT0tfUkVTVFJJQ1RJT05fMl8yLAoJCQkJImRlcml2YXRpb24tb2stcmVzdHJpY3Rpb24uMi4yOiAiCgkJCQkiVGhlIGF0dHJpYnV0ZSB1c2UgXCIlc1wiIGhhcyBuZWl0aGVyIGEgbWF0Y2hpbmcgYXR0cmlidXRlIHVzZSwgIgoJCQkJIm5vciBhIG1hdGNoaW5nIHdpbGRjYXJkIGluIHRoZSBiYXNlIHR5cGVcbiIsCQkKCQkJCXhtbFNjaGVtYUdldE9ueW1vdXNBdHRyTmFtZShjdXItPmF0dHIpLCBOVUxMKTsKCQkJfSBlbHNlIHsKCQkJICAgIC8qIAoJCQkgICAgKiBBZGQgdGhlIGF0dHJpYnV0ZSB1c2UuCgkJCSAgICAqCgkJCSAgICAqIE5vdGUgdGhhdCB0aGlzIG1heSBsZWFkIHRvIGZ1bm55IGRlcml2YXRpb24gZXJyb3IgcmVwb3J0cywgaWYKCQkJICAgICogbXVsdGlwbGUgZXF1YWwgYXR0cmlidXRlIHVzZXMgZXhpc3Q7IGJ1dCB0aGlzIGlzIG5vdAoJCQkgICAgKiBhbGxvd2VkIGFueXdheSwgYW5kIGl0IHdpbGwgYmUgcmVwb3J0ZWQgYmVmb3JlaGFuZC4KCQkJICAgICovCgkJCSAgICB0bXAgPSBjdXI7CgkJCSAgICBpZiAocHJldiAhPSBOVUxMKQoJCQkJcHJldi0+bmV4dCA9IGN1ci0+bmV4dDsKCQkJICAgIGVsc2UgCgkJCQl1c2VzID0gY3VyLT5uZXh0OwoJCQkgICAgY3VyID0gY3VyLT5uZXh0OyAgICAJCQkKCQkJICAgIGlmICh0eXBlLT5hdHRyaWJ1dGVVc2VzID09IE5VTEwpIHsKCQkJCXR5cGUtPmF0dHJpYnV0ZVVzZXMgPSB0bXA7CgkJCSAgICB9IGVsc2UgCgkJCQlsYXN0QmFzZVVzZS0+bmV4dCA9IHRtcDsKCQkJICAgIGxhc3RCYXNlVXNlID0gdG1wOwkJCgkJCSAgICAKCQkJICAgIGNvbnRpbnVlOwoJCQl9CgkJICAgIH0KCQl9CQkgICAgCSAgICAKCQlwcmV2ID0gY3VyOwkKCQljdXIgPSBjdXItPm5leHQ7CgkgICAgfQoJICAgIGlmICh1c2VzICE9IE5VTEwpCgkJeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVVzZUxpc3QodXNlcyk7Cgl9CiAgICB9IGVsc2UgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9FWFRFTlNJT04pIHsgCgkvKgoJICogVGhlIHNwZWMgYWxsb3dzIG9ubHkgYXBwZW5kaW5nLCBhbmQgbm90IG90aGVyIGtpbmRzIG9mIGV4dGVuc2lvbnMuCgkgKgoJICogVGhpcyBlbnN1cmVzOiBTY2hlbWEgQ29tcG9uZW50IENvbnN0cmFpbnQ6IERlcml2YXRpb24gVmFsaWQgKEV4dGVuc2lvbikgOiAxLjIgCgkgKi8KCWlmICh1c2VzICE9IE5VTEwpIHsKCSAgICBpZiAodHlwZS0+YXR0cmlidXRlVXNlcyA9PSBOVUxMKSB7CgkJdHlwZS0+YXR0cmlidXRlVXNlcyA9IHVzZXM7CgkgICAgfSBlbHNlIAoJCWxhc3RCYXNlVXNlLT5uZXh0ID0gdXNlczsKCX0KICAgIH0gZWxzZSB7CgkvKiAKCSogRGVyaXZlIGltcGxpY2l0ZWx5IGZyb20gdGhlIHVyLXR5cGUuCgkqLwoJdHlwZS0+YXR0cmlidXRlVXNlcyA9IHVzZXM7CiAgICB9CiAgICAvKgogICAgICogMy40LjYgLT4gQ29tcGxleCBUeXBlIERlZmluaXRpb24gUHJvcGVydGllcyBDb3JyZWN0CiAgICAgKi8KICAgIGlmICh0eXBlLT5hdHRyaWJ1dGVVc2VzICE9IE5VTEwpIHsKCWN1ciA9IHR5cGUtPmF0dHJpYnV0ZVVzZXM7CglwcmV2ID0gTlVMTDsKCXdoaWxlIChjdXIgIT0gTlVMTCkgewoJICAgIC8qCgkgICAgKiA0LiBUd28gZGlzdGluY3QgYXR0cmlidXRlIGRlY2xhcmF0aW9ucyBpbiB0aGUge2F0dHJpYnV0ZSB1c2VzfSBtdXN0IAoJICAgICogbm90IGhhdmUgaWRlbnRpY2FsIHtuYW1lfXMgYW5kIHt0YXJnZXQgbmFtZXNwYWNlfXMuCgkgICAgKgoJICAgICogTm90ZSB0aGF0IHRoaXMgd2FzIGFscmVhZHkgZG9uZSBmb3IgInJlc3RyaWN0aW9uIiBhbmQgdHlwZXMgZGVyaXZlZCBmcm9tCgkgICAgKiB0aGUgdXItdHlwZS4KCSAgICAqLwoJICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfREVSSVZBVElPTl9NRVRIT0RfRVhURU5TSU9OKSB7CgkJdG1wID0gY3VyLT5uZXh0OwoJCXdoaWxlICh0bXAgIT0gTlVMTCkgewkgICAgCgkJICAgIGlmICgoeG1sU3RyRXF1YWwoeG1sU2NoZW1hR2V0T255bW91c0F0dHJOYW1lKGN1ci0+YXR0ciksIAoJCQl4bWxTY2hlbWFHZXRPbnltb3VzQXR0ck5hbWUodG1wLT5hdHRyKSkpICYmCgkJCSh4bWxTdHJFcXVhbCh4bWxTY2hlbWFHZXRPbnltb3VzVGFyZ2V0TnNVUkkoKHhtbFNjaGVtYVR5cGVQdHIpIGN1ci0+YXR0ciApLCAKCQkJeG1sU2NoZW1hR2V0T255bW91c1RhcmdldE5zVVJJKCh4bWxTY2hlbWFUeXBlUHRyKSB0bXAtPmF0dHIpKSkpIHsKCgkJCXhtbFNjaGVtYVBFcnIoY3R4dCwgY3VyLT5hdHRyLT5ub2RlLCBYTUxfU0NIRU1BUF9DVF9QUk9QU19DT1JSRUNUXzQsCgkJCSAgICAiY3QtcHJvcHMtY29ycmVjdC40OiBEdXBsaWNhdGUgYXR0cmlidXRlIHVzZSB3aXRoIHRoZSBuYW1lIFwiJXNcIiBzcGVjaWZpZWRcbiIsCgkJCSAgICB4bWxTY2hlbWFHZXRPbnltb3VzQXR0ck5hbWUoY3VyLT5hdHRyKSwgIE5VTEwpOwoJCQlicmVhazsKCQkgICAgfQoJCSAgICB0bXAgPSB0bXAtPm5leHQ7CgkJfQoJICAgIH0KCSAgICAvKgoJICAgICogNS4gVHdvIGRpc3RpbmN0IGF0dHJpYnV0ZSBkZWNsYXJhdGlvbnMgaW4gdGhlIHthdHRyaWJ1dGUgdXNlc30gbXVzdCAKCSAgICAqIG5vdCBoYXZlIHt0eXBlIGRlZmluaXRpb259cyB3aGljaCBhcmUgb3IgYXJlIGRlcml2ZWQgZnJvbSBJRC4KCSAgICAqLwoJICAgIGlmICgoY3VyLT5hdHRyLT5zdWJ0eXBlcyAhPSBOVUxMKSAmJiAKCQkoeG1sU2NoZW1hSXNEZXJpdmVkRnJvbUJ1aWx0SW5UeXBlKGN0eHQsICh4bWxTY2hlbWFUeXBlUHRyKSBjdXItPmF0dHIsIFhNTF9TQ0hFTUFTX0lEKSkpIHsKCQlpZiAoaWQgIT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGN1ci0+YXR0ci0+bm9kZSwgWE1MX1NDSEVNQVBfQ1RfUFJPUFNfQ09SUkVDVF81LCAKCQkJImN0LXByb3BzLWNvcnJlY3QuNTogVHdvIGF0dHJpYnV0ZSBkZWNsYXJhdGlvbnMsICIKCQkJIlwiJXNcIiBhbmQgXCIlc1wiIGhhdmUgdHlwZXMgd2hpY2ggZGVyaXZlZCBmcm9tIElEXG4iLAoJCQl4bWxTY2hlbWFHZXRPbnltb3VzQXR0ck5hbWUoaWQtPmF0dHIpLCAKCQkJeG1sU2NoZW1hR2V0T255bW91c0F0dHJOYW1lKGN1ci0+YXR0cikpOwoJCX0gCgkJaWQgPSBjdXI7CgkgICAgfQoJICAgIC8qCgkgICAgKiBSZW1vdmUgInByb2hpYml0ZWQiIGF0dHJpYnV0ZSB1c2VzLiBUaGUgcmVhc29uIHRoaXMgaXMgZG9uZSBhdCB0aGlzIGxhdGUgCgkgICAgKiBzdGFnZSBpcyB0byBiZSBhYmxlIHRvIGNhdGNoIGR1YmxpY2F0ZSBhdHRyaWJ1dGUgdXNlcy4gU28gd2UgaGFkIHRvIGtlZXAKCSAgICAqIHByb2hpYml0ZWQgdXNlcyBpbiB0aGUgbGlzdCBhcyB3ZWxsLgoJICAgICovCgkgICAgaWYgKGN1ci0+YXR0ci0+b2NjdXJzID09IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1BST0hJQklURUQpIHsKCQl0bXAgPSBjdXI7CgkJaWYgKHByZXYgPT0gTlVMTCkKCQkgICAgdHlwZS0+YXR0cmlidXRlVXNlcyA9IGN1ci0+bmV4dDsKCQllbHNlCgkJICAgIHByZXYtPm5leHQgPSBjdXItPm5leHQ7CgkJY3VyID0gY3VyLT5uZXh0OwoJCXhtbEZyZWUodG1wKTsKCSAgICB9IGVsc2UgewoJCXByZXYgPSBjdXI7CgkJY3VyID0gY3VyLT5uZXh0OwoJICAgIH0KCX0gICAgCiAgICB9CiAgICAvKgkKICAgICAqIFRPRE86IFRoaXMgY2hlY2sgc2hvdWxkIGJlIHJlbW92ZWQgaWYgd2UgYXJlIDEwMCUgc3VyZSBvZgogICAgICogdGhlIGJhc2UgdHlwZSBhdHRyaWJ1dGUgdXNlcyBhbHJlYWR5IGJlaW5nIGJ1aWx0LgogICAgICovCiAgICBpZiAoKGJhc2VUeXBlICE9IE5VTEwpICYmICghYmFzZUlzQW55VHlwZSkgJiYKCShiYXNlVHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgJiYKCShiYXNlVHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV04pKSB7Cgl4bWxTY2hlbWFQRXJyKGN0eHQsIGJhc2VUeXBlLT5ub2RlLCBYTUxfU0NIRU1BU19FUlJfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb246ICIKCSAgICAiYXR0cmlidXRlIHVzZXMgbm90IGJ1aWxkZWQgb24gYmFzZSB0eXBlIFwiJXNcIi5cbiIsCgkgICAgYmFzZVR5cGUtPm5hbWUsIE5VTEwpOwogICAgfSAgICAKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFUeXBlRmluYWxDb250YWluczoKICogQHNjaGVtYTogIHRoZSBzY2hlbWEKICogQHR5cGU6ICB0aGUgdHlwZSBkZWZpbml0aW9uCiAqIEBmaW5hbDogdGhlIGZpbmFsCiAqCiAqIEV2YWx1YXRlcyBpZiBhIHR5cGUgZGVmaW5pdGlvbiBjb250YWlucyB0aGUgZ2l2ZW4gImZpbmFsIi4KICogVGhpcyBkb2VzIHRha2UgImZpbmFsRGVmYXVsdCIgaW50byBhY2NvdW50IGFzIHdlbGwuCiAqCiAqIFJldHVybnMgMSBpZiB0aGUgdHlwZSBkb2VzIGNvbnRhaW50IHRoZSBnaXZlbiAiZmluYWwiLAogKiAwIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVHlwZUZpbmFsQ29udGFpbnMoeG1sU2NoZW1hUHRyIHNjaGVtYSwgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBpbnQgZmluYWwpCnsKICAgIGludCB0ZmluYWwgPSBmaW5hbCwgdGZsYWdzID0gdHlwZS0+ZmxhZ3M7CgogICAgaWYgKHR5cGUgPT0gTlVMTCkKCXJldHVybiAoMCk7ICAgIAogICAgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9ERUZBVUxUKSB7Cglzd2l0Y2ggKGZpbmFsKSB7CgkgICAgY2FzZSBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OOgoJCXRmaW5hbCA9IFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfUkVTVFJJQ1RJT047CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX0VYVEVOU0lPTjoKCQl0ZmluYWwgPSBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX0VYVEVOU0lPTjsKCQlicmVhazsKCSAgICBjYXNlIFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfTElTVDoKCQl0ZmluYWwgPSBYTUxfU0NIRU1BU19GSU5BTF9ERUZBVUxUX0xJU1Q7CgkJYnJlYWs7CgkgICAgY2FzZSBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1VOSU9OOgoJCXRmaW5hbCA9IFhNTF9TQ0hFTUFTX0ZJTkFMX0RFRkFVTFRfVU5JT047CgkJYnJlYWs7Cgl9Cgl0ZmxhZ3MgPSBzY2hlbWEtPmZsYWdzOwogICAgfQogICAgaWYgKHRmbGFncyAmIHRmaW5hbCkgCglyZXR1cm4gKDEpOwogICAgZWxzZQoJcmV0dXJuICgwKTsKICAgIAp9CgovKioKICogeG1sU2NoZW1hR2V0VW5pb25TaW1wbGVUeXBlTWVtYmVyVHlwZXM6CiAqIEB0eXBlOiAgdGhlIFVuaW9uIFNpbXBsZSBUeXBlCiAqCiAqIFJldHVybnMgYSBsaXN0IG9mIG1lbWJlciB0eXBlcyBvZiBAdHlwZSBpZiBleGlzdGluZywgCiAqIHJldHVybnMgTlVMTCBvdGhlcndpc2UuCiAqLwpzdGF0aWMgeG1sU2NoZW1hVHlwZUxpbmtQdHIKeG1sU2NoZW1hR2V0VW5pb25TaW1wbGVUeXBlTWVtYmVyVHlwZXMoeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB3aGlsZSAodHlwZSAhPSBOVUxMKSB7CglpZiAodHlwZS0+bWVtYmVyVHlwZXMgIT0gTlVMTCkKCSAgICByZXR1cm4gKHR5cGUtPm1lbWJlclR5cGVzKTsKCWVsc2UKCSAgICB0eXBlID0gdHlwZS0+YmFzZVR5cGU7CiAgICB9CiAgICByZXR1cm4gKE5VTEwpOwp9CgovKioKICogeG1sU2NoZW1hR2V0TGlzdFNpbXBsZVR5cGVJdGVtVHlwZToKICogQHR5cGU6ICB0aGUgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgogKgogKiBSZXR1cm5zIHRoZSBpdGVtIHR5cGUgZGVmaW5pdGlvbiBvZiB0aGUgbGlzdCBzaW1wbGUgdHlwZS4KICovIApzdGF0aWMgeG1sU2NoZW1hVHlwZVB0cgp4bWxTY2hlbWFHZXRMaXN0U2ltcGxlVHlwZUl0ZW1UeXBlKHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKeyAgICAKICAgIGlmICgodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfTElTVCkgPT0gMCkKCXJldHVybiAoTlVMTCk7CiAgICAvKgogICAgKiBOb3RlOiBJbiBsaWJ4bWwyLCB0aGUgYnVpbHQtaW4gdHlwZXMgZG8gbm90IHJlZmxlY3QgCiAgICAqIHRoZSBkYXRhdHlwZSBoaWVyYXJjaHkgKHlldD8pIC0gd2UgaGF2ZSB0byB0cmVhdCB0aGVtCiAgICAqIGluIGEgc3BlY2lhbCB3YXkuCiAgICAqLwogICAgaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSAKCXJldHVybiAoeG1sU2NoZW1hR2V0QnVpbHRJbkxpc3RTaW1wbGVUeXBlSXRlbVR5cGUodHlwZSkpOwogICAgaWYgKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9MSVNUKQoJLyogMSBJZiB0aGUgPGxpc3Q+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwgdGhlbiB0aGUgdHlwZSAKCSogZGVmaW5pdGlvbiC3cmVzb2x2ZWS3IHRvIGJ5IHRoZSC3YWN0dWFsIHZhbHVltyBvZiB0aGUgCgkqIGl0ZW1UeXBlIFthdHRyaWJ1dGVdIG9mIDxsaXN0PiwgaWYgcHJlc2VudCwgb3RoZXJ3aXNlIAoJKiB0aGUgdHlwZSBkZWZpbml0aW9uIGNvcnJlc3BvbmRpbmcgdG8gdGhlIDxzaW1wbGVUeXBlPiAKCSogYW1vbmcgdGhlIFtjaGlsZHJlbl0gb2YgPGxpc3Q+LgoJKi8KCXJldHVybiAodHlwZS0+c3VidHlwZXMtPnN1YnR5cGVzKTsKICAgIGVsc2UgewoJLyogMiBJZiB0aGUgPHJlc3RyaWN0aW9uPiBvcHRpb24gaXMgY2hvc2VuLCB0aGVuIHRoZSAKCSoge2l0ZW0gdHlwZSBkZWZpbml0aW9ufSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufS4KCSovICAgIAoJcmV0dXJuICh4bWxTY2hlbWFHZXRMaXN0U2ltcGxlVHlwZUl0ZW1UeXBlKHR5cGUtPmJhc2VUeXBlKSk7CiAgICB9ICAgIAp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSzoKICogQHR5cGU6ICB0aGUgZGVyaXZlZCBzaW1wbGUgdHlwZSBkZWZpbml0aW9uCiAqIEBiYXNlVHlwZTogIHRoZSBiYXNlIHR5cGUgZGVmaW5pdGlvbgogKgogKiBDaGVja3Mgd2hldGVyIEB0eXBlIGNhbiBiZSB2YWxpZGx5IAogKiBkZXJpdmVkIGZyb20gQGJhc2VUeXBlLgogKgogKiBSZXR1cm5zIDAgb24gc3VjY2VzcywgYW4gcG9zaXRpdmUgZXJyb3IgY29kZSBvdGhlcndpc2UuCiAqLyAKc3RhdGljIGludAp4bWxTY2hlbWFDaGVja0NPU1NURGVyaXZlZE9LKHhtbFNjaGVtYVB0ciBzY2hlbWEsCgkJCQkgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJCSAgICAgeG1sU2NoZW1hVHlwZVB0ciBiYXNlVHlwZSwKCQkJCSAgICAgaW50IHN1YnNldCkKeyAgIAogICAgLyoKICAgICogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBUeXBlIERlcml2YXRpb24gT0sgKFNpbXBsZSkKICAgICoKICAgICoKICAgICogMSBUaGV5IGFyZSB0aGUgc2FtZSB0eXBlIGRlZmluaXRpb24uCiAgICAqIFRPRE86IFRoZSBpZGVudHkgY2hlY2sgbWlnaHQgaGF2ZSB0byBiZSBtb3JlIGNvbXBsZXggdGhhbiB0aGlzLgogICAgKi8KICAgIGlmICh0eXBlID09IGJhc2VUeXBlKQoJcmV0dXJuICgwKTsgICAgCiAgICAvKiAKICAgICogMi4xIHJlc3RyaWN0aW9uIGlzIG5vdCBpbiB0aGUgc3Vic2V0LCBvciBpbiB0aGUge2ZpbmFsfQogICAgKiBvZiBpdHMgb3duIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn07CiAgICAqLwogICAgaWYgKChzdWJzZXQgJiBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OKSB8fAoJKHhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zKHNjaGVtYSwgCgkgICAgdHlwZS0+YmFzZVR5cGUsIFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfUkVTVFJJQ1RJT04pKSkgewoJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfREVSSVZFRF9PS18yXzEpOyAKICAgIH0KICAgIC8qIDIuMiAqLwogICAgaWYgKHR5cGUtPmJhc2VUeXBlID09IGJhc2VUeXBlKSB7CgkvKgoJKiAyLjIuMSBEJ3Mgt2Jhc2UgdHlwZSBkZWZpbml0aW9utyBpcyBCLgoJKi8KCXJldHVybiAoMCk7CiAgICB9ICAgCiAgICAvKiAKICAgICogMi4yLjIgRCdzILdiYXNlIHR5cGUgZGVmaW5pdGlvbrcgaXMgbm90IHRoZSC3dXItdHlwZSBkZWZpbml0aW9utyAKICAgICogYW5kIGlzIHZhbGlkbHkgZGVyaXZlZCBmcm9tIEIgZ2l2ZW4gdGhlIHN1YnNldCwgYXMgZGVmaW5lZCBieSB0aGlzIAogICAgKiBjb25zdHJhaW50LiAgICAKICAgICovCiAgICBpZiAoKHR5cGUtPmJhc2VUeXBlICE9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVRZUEUpKSAmJgoJKHhtbFNjaGVtYUNoZWNrQ09TU1REZXJpdmVkT0soc2NoZW1hLCB0eXBlLT5iYXNlVHlwZSwgYmFzZVR5cGUsIHN1YnNldCkgPT0gMCkpIHsKCXJldHVybiAoMCk7CQkKICAgIH0gCiAgICAvKiAKICAgICogMi4yLjMgRCdzIHt2YXJpZXR5fSBpcyBsaXN0IG9yIHVuaW9uIGFuZCBCIGlzIHRoZSC3c2ltcGxlIHVyLXR5cGUgCiAgICAqIGRlZmluaXRpb263LgogICAgKi8KICAgIGlmICgoKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1QpIHx8CgkodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT04pKSAmJgoJKGJhc2VUeXBlID09IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpKSkgewoJcmV0dXJuICgwKTsKICAgIH0gICAgCiAgICAvKiAKICAgICogMi4yLjQgQidzIHt2YXJpZXR5fSBpcyB1bmlvbiBhbmQgRCBpcyB2YWxpZGx5IGRlcml2ZWQgZnJvbSBhIHR5cGUgCiAgICAqIGRlZmluaXRpb24gaW4gQidzIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30gZ2l2ZW4gdGhlIHN1YnNldCwgYXMgCiAgICAqIGRlZmluZWQgYnkgdGhpcyBjb25zdHJhaW50LgogICAgKgogICAgKiBOT1RFOiBUaGlzIHNlZW1zIG5vdCB0byBpbnZvbHZlIGJ1aWx0LWluIHR5cGVzLCBzaW5jZSB0aGVyZSBpcyBubwogICAgKiBidWlsdC1pbiBVbmlvbiBTaW1wbGUgVHlwZS4KICAgICovCiAgICBpZiAoYmFzZVR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OKSB7Cgl4bWxTY2hlbWFUeXBlTGlua1B0ciBjdXI7CgoJY3VyID0gYmFzZVR5cGUtPm1lbWJlclR5cGVzOwoJd2hpbGUgKGN1ciAhPSBOVUxMKSB7CgkgICAgaWYgKHhtbFNjaGVtYUNoZWNrQ09TU1REZXJpdmVkT0soc2NoZW1hLCB0eXBlLCAKCQljdXItPnR5cGUsIHN1YnNldCkgPT0gMCkKCQlyZXR1cm4gKDApOwoJICAgIGN1ciA9IGN1ci0+bmV4dDsKCX0JCiAgICB9CiAgICAKICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX0RFUklWRURfT0tfMl8yKTsKfQoKCi8qKgogKiB4bWxTY2hlbWFDaGVja1NUUHJvcHNDb3JyZWN0OgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgogKgogKiBDaGVja3Mgc3QtcHJvcHMtY29ycmVjdC4KICoKICogUmV0dXJucyAwIGlmIHRoZSBwcm9wZXJ0aWVzIGFyZSBjb3JyZWN0LAogKiBpZiBub3QsIGEgcG9zaXRpdmUgZXJyb3IgY29kZSBhbmQgLTEgb24gaW50ZXJuYWwKICogZXJyb3JzLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFDaGVja1NUUHJvcHNDb3JyZWN0KHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgCgkJCSAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2VUeXBlID0gdHlwZS0+YmFzZVR5cGUsIGFueVNpbXBsZVR5cGUsCglhbnlUeXBlOwoKICAgIC8qCiAgICAqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogU2ltcGxlIFR5cGUgRGVmaW5pdGlvbiBQcm9wZXJ0aWVzIENvcnJlY3QKICAgICoKICAgICogTk9URTogVGhpcyBpcyBzb21laG93IHJlZHVuZGFudCwgc2luY2Ugd2UgYWN0dWFsbHkgYnVpbHQgYSBzaW1wbGUgdHlwZQogICAgKiB0byBoYXZlIGFsbCB0aGUgbmVlZGVkIGluZm9ybWF0aW9uOyB0aGlzIGFjdHMgYXMgYW4gc2VsZiB0ZXN0LgogICAgKi8KICAgIGFueVNpbXBsZVR5cGUgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllTSU1QTEVUWVBFKTsKICAgIGFueVR5cGUgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllUWVBFKTsKICAgIC8qIAogICAgKiBUT0RPOiAxIFRoZSB2YWx1ZXMgb2YgdGhlIHByb3BlcnRpZXMgb2YgYSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIG11c3QgYmUgYXMgCiAgICAqIGRlc2NyaWJlZCBpbiB0aGUgcHJvcGVydHkgdGFibGVhdSBpbiBEYXRhdHlwZSBkZWZpbml0aW9uLCBtb2R1bG8gdGhlIAogICAgKiBpbXBhY3Qgb2YgTWlzc2luZyBTdWItY29tcG9uZW50cyAopzUuMykuCiAgICAqLwogICAgLyogQmFzZSB0eXBlOiBJZiB0aGUgZGF0YXR5cGUgaGFzIGJlZW4gt2Rlcml2ZWS3IGJ5ILdyZXN0cmljdGlvbrcgCiAgICAqIHRoZW4gdGhlIFNpbXBsZSBUeXBlIERlZmluaXRpb24gY29tcG9uZW50IGZyb20gd2hpY2ggaXQgaXMgt2Rlcml2ZWS3LCAKICAgICogb3RoZXJ3aXNlIHRoZSBTaW1wbGUgVHlwZSBEZWZpbml0aW9uIGZvciBhbnlTaW1wbGVUeXBlICinNC4xLjYpLiAKICAgICovCiAgICBpZiAoYmFzZVR5cGUgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJICAgIFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSwKCSAgICAiU2ltcGxlIHR5cGUgXCIlc1wiIGRvZXMgbm90IGhhdmUgYSBiYXNlIHR5cGUuXG4iLAoJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJcmV0dXJuIChYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzEpOwogICAgfQogICAgaWYgKChiYXNlVHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSAmJgoJKChiYXNlVHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpIHx8CgkgKGJhc2VUeXBlID09IGFueVR5cGUpKSkgewoJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJICAgIFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSwKCSAgICAiU2ltcGxlIHR5cGUgXCIlc1wiOiBpdHMgYmFzZSB0eXBlIFwiJXNcIiBpcyBub3QgYSBzaW1wbGUgIgoJICAgICJ0eXBlLlxuIiwKCSAgICB0eXBlLT5uYW1lLCBiYXNlVHlwZS0+bmFtZSk7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSk7CiAgICB9CiAgICBpZiAoKGJhc2VUeXBlICE9IGFueVNpbXBsZVR5cGUpICYmCgkodHlwZS0+c3VidHlwZXMtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX1JFU1RSSUNUSU9OKSkgewoJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJICAgIFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMSwKCSAgICAiU2ltcGxlIHR5cGUgXCIlc1wiIChub3QgZGVyaXZlZCBieSByZXN0cmljdGlvbikgbXVzdCBoYXZlIgoJICAgICJ0aGUgc2ltcGxlIHVyLXR5cGUgZGVmaW5pdGlvbiBhcyBiYXNlIHR5cGUsIG5vdCBcIiVzXCIuXG4iLAoJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJcmV0dXJuIChYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzEpOwogICAgfQogICAgLyogCiAgICAqIFZhcmlldHk6IE9uZSBvZiB7YXRvbWljLCBsaXN0LCB1bmlvbn0uIAogICAgKi8KICAgIGlmICgoKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0FUT01JQykgPT0gMCkgJiYKCSgodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT04pID09IDApICYmCgkoKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1QpID09IDApKSB7Cgl4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsCgkgICAgWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8xLAoJICAgICJTaW1wbGUgdHlwZSBcIiVzXCIgaGFzIGFuIGFic2VudCB2YXJpZXR5LlxuIiwKCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKCXJldHVybiAoWE1MX1NDSEVNQVBfU1RfUFJPUFNfQ09SUkVDVF8xKTsKICAgIH0KICAgIC8qIFRPRE86IEZpbmlzaCB0aGlzLiAqLwoKICAgIC8qCiAgICAqIDIgQWxsIHNpbXBsZSB0eXBlIGRlZmluaXRpb25zIG11c3QgYmUgZGVyaXZlZCB1bHRpbWF0ZWx5IGZyb20gdGhlILdzaW1wbGUgCiAgICAqIHVyLXR5cGUgZGVmaW5pdGlvbiAoc2+3IGNpcmN1bGFyIGRlZmluaXRpb25zIGFyZSBkaXNhbGxvd2VkKS4gVGhhdCBpcywgaXQgCiAgICAqIG11c3QgYmUgcG9zc2libGUgdG8gcmVhY2ggYSBidWlsdC1pbiBwcmltaXRpdmUgZGF0YXR5cGUgb3IgdGhlILdzaW1wbGUgCiAgICAqIHVyLXR5cGUgZGVmaW5pdGlvbrcgYnkgcmVwZWF0ZWRseSBmb2xsb3dpbmcgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0uCiAgICAqLyAgICAKICAgIGJhc2VUeXBlID0gdHlwZS0+YmFzZVR5cGU7CiAgICB3aGlsZSAoKGJhc2VUeXBlICE9IE5VTEwpICYmIChiYXNlVHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpKSB7CglpZiAoYmFzZVR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKQoJICAgIHhtbFNjaGVtYVR5cGVGaXh1cChiYXNlVHlwZSwgY3R4dCwgIE5VTEwpOwoJaWYgKGJhc2VUeXBlID09IGFueVNpbXBsZVR5cGUpCgkgICAgYnJlYWs7CgllbHNlIGlmIChiYXNlVHlwZSA9PSB0eXBlKSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJCVhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMiwKCQkiU2ltcGxlIHR5cGUgXCIlc1wiIGlzIG5vdCBkZXJpdmVkIGZyb20gdGhlIHNpbXBsZSAiCgkJInVyLXR5cGUgZGVmaW5pdGlvbiAoY2lyY3VsYXIgZGVmaW5pdGlvbnMgYXJlIGRpc2FsbG93ZWQpLlxuIiwKCQl0eXBlLT5uYW1lLCBOVUxMKTsKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMik7Cgl9CSAgIAoJYmFzZVR5cGUgPSBiYXNlVHlwZS0+YmFzZVR5cGU7CiAgICB9ICAgCiAgICAvKgogICAgKiAzIFRoZSB7ZmluYWx9IG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3Qgbm90IGNvbnRhaW4gcmVzdHJpY3Rpb24uCiAgICAqLwogICAgaWYgKHhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zKGN0eHQtPnNjaGVtYSwgYmFzZVR5cGUsIAoJWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9SRVNUUklDVElPTikpIHsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwKCSAgICBYTUxfU0NIRU1BUF9TVF9QUk9QU19DT1JSRUNUXzMsCgkgICAgIlNpbXBsZSB0eXBlIFwiJXNcIjogdGhlIFwiZmluYWxcIiBvZiBpdHMgYmFzZSB0eXBlICIKCSAgICAiXCIlc1wiIG11c3Qgbm90IGNvbnRhaW4gXCJyZXN0cmljdGlvblwiLlxuIiwKCSAgICB0eXBlLT5uYW1lLCBiYXNlVHlwZS0+bmFtZSk7CglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NUX1BST1BTX0NPUlJFQ1RfMyk7CiAgICB9ICAgIAogICAgcmV0dXJuICgwKTsKfQoKLyoqCiAqIHhtbFNjaGVtYUNoZWNrRGVyaXZhdGlvblZhbGlkU2ltcGxlUmVzdHJpY3Rpb246CiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAdHlwZTogIHRoZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uCiAqCiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gQHR5cGUgKHNpbXBsZVR5cGUpIGlzIGRlcml2ZWQgCiAqIHZhbGlkbHkgYnkgcmVzdHJpY3Rpb24uCiAqCiAqIFJldHVybnMgLTEgb24gaW50ZXJuYWwgZXJyb3JzLCAwIGlmIHRoZSB0eXBlIGlzIHZhbGlkbHkgZGVyaXZlZCwgCiAqIGEgcG9zaXRpdmUgZXJyb3IgY29kZSBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYUNoZWNrQ09TU1RSZXN0cmljdHMoeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCAKCQkJCQkgICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7ICAgIAoKICAgIGlmICh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpIHsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwKCSAgICBYTUxfRVJSX0lOVEVSTkFMX0VSUk9SLAoJICAgICJ4bWxTY2hlbWFDaGVja0Rlcml2YXRpb25WYWxpZFNpbXBsZVJlc3RyaWN0aW9uOiB0aGUgZ2l2ZW4gIgoJICAgICJ0eXBlIFwiJXNcIiBpcyBub3QgYSB1c2VyLWRlcml2ZWQgc2ltcGxlVHlwZS5cbiIsCgkgICAgdHlwZS0+bmFtZSwgTlVMTCk7CglyZXR1cm4gKC0xKTsKICAgIH0KCiAgICBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfQVRPTUlDKSB7Cgl4bWxTY2hlbWFUeXBlUHRyIHByaW1pdGl2ZTsKCS8qIAoJKiAxLjEgVGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBiZSBhbiBhdG9taWMgc2ltcGxlIAoJKiB0eXBlIGRlZmluaXRpb24gb3IgYSBidWlsdC1pbiBwcmltaXRpdmUgZGF0YXR5cGUuCgkqLwkKCWlmICgodHlwZS0+YmFzZVR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0FUT01JQykgPT0gMCkgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwKCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzFfMSwKCQkiQXRvbWljIHNpbXBsZSB0eXBlIFwiJXNcIjogIgoJCSJpdHMgYmFzZSB0eXBlIFwiJXNcIiBpcyBub3QgYW4gYXRvbWljIHNpbXBsZSB0eXBlLlxuIiwKCQl0eXBlLT5uYW1lLCBOVUxMKTsKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMV8xKTsKCX0KCS8qIDEuMiBUaGUge2ZpbmFsfSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IG5vdCBjb250YWluIAoJKiByZXN0cmljdGlvbi4KCSovCgkvKiBPUFRJTUlaRTogVGhpcyBpcyBhbHJlYWR5IGRvbmUgaW4geG1sU2NoZW1hQ2hlY2tTdFByb3BzQ29ycmVjdCAqLwoJaWYgKHhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zKGN0eHQtPnNjaGVtYSwgdHlwZS0+YmFzZVR5cGUsIAoJICAgIFhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfUkVTVFJJQ1RJT04pKSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMV8yLAoJCSJBdG9taWMgc2ltcGxlIHR5cGUgXCIlc1wiOiB0aGUgXCJmaW5hbFwiIG9mIGl0cyBiYXNlIHR5cGUgIgoJCSJcIiVzXCIgbXVzdCBub3QgY29udGFpbiBcInJlc3RyaWN0aW9uXCIuXG4iLAoJCXR5cGUtPm5hbWUsIHR5cGUtPmJhc2VUeXBlLT5uYW1lKTsKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMV8yKTsKCX0KCQoJLyogCgkqIDEuMy4xIERGIG11c3QgYmUgYW4gYWxsb3dlZCBjb25zdHJhaW5pbmcgZmFjZXQgZm9yIHRoZSB7cHJpbWl0aXZlCgkqIHR5cGUgZGVmaW5pdGlvbn0sIGFzIHNwZWNpZmllZCBpbiB0aGUgYXBwcm9wcmlhdGUgc3Vic2VjdGlvbiBvZiAzLjIgCgkqIFByaW1pdGl2ZSBkYXRhdHlwZXMuCgkqLwoJaWYgKHR5cGUtPmZhY2V0cyAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQ7CgkgICAgaW50IG9rID0gMTsKCSAgICAKCSAgICBwcmltaXRpdmUgPSB4bWxTY2hlbWFHZXRQcmltaXRpdmVUeXBlKHR5cGUpOwoJICAgIGlmIChwcmltaXRpdmUgPT0gTlVMTCkgewoJCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwKCQkgICAgWE1MX0VSUl9JTlRFUk5BTF9FUlJPUiwKCQkgICAgInhtbFNjaGVtYUNoZWNrRGVyaXZhdGlvblZhbGlkU2ltcGxlUmVzdHJpY3Rpb246IGZhaWxlZCAiCgkJICAgICJ0byBnZXQgcHJpbWl0aXZlIHR5cGUgb2YgdHlwZSBcIiVzXCIuXG4iLAoJCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKCQlyZXR1cm4gKC0xKTsKCSAgICB9CSAgICAKCSAgICBmYWNldCA9IHR5cGUtPmZhY2V0czsKCSAgICBkbyB7CgkJaWYgKHhtbFNjaGVtYUlzQnVpbHRJblR5cGVGYWNldChwcmltaXRpdmUsIGZhY2V0LT50eXBlKSA9PSAwKSB7CgkJICAgIHhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgdHlwZS0+bm9kZSwKCQkJWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18xXzNfMSwKCQkJTlVMTCwgTlVMTCwgTlVMTCwKCQkJIkF0b21pYyBzaW1wbGUgdHlwZSBcIiVzXCI6IHRoZSBmYWNldCBcIiVzXCIgIgoJCQkiaXMgbm90IGFsbG93ZWQgb24gcHJpbWl0aXZlIHR5cGUgXCIlc1wiLlxuIiwKCQkJdHlwZS0+bmFtZSwgCgkJCShjb25zdCB4bWxDaGFyICopCgkJCXhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKGZhY2V0LT50eXBlKSwKCQkJQkFEX0NBU1QgcHJpbWl0aXZlLT5uYW1lLCBOVUxMLCBOVUxMKTsKCQkgICAgCgkJICAgIG9rID0gMDsJCQkgICAgCgkJfQoJCWZhY2V0ID0gZmFjZXQtPm5leHQ7CgkgICAgfSB3aGlsZSAoZmFjZXQgIT0gTlVMTCk7CSAgICAKCSAgICBpZiAob2sgPT0gMCkKCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMV8zXzEpOwoJICAgIAoJfQoJLyoKCSogVE9ETzogMS4zLjIgKGZhY2V0IGRlcml2YXRpb24pCgkqLwogICAgfSBlbHNlIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSB7Cgl4bWxTY2hlbWFUeXBlUHRyIGl0ZW1UeXBlID0gTlVMTDsKCglpdGVtVHlwZSA9IHhtbFNjaGVtYUdldExpc3RTaW1wbGVUeXBlSXRlbVR5cGUodHlwZSk7CglpZiAoaXRlbVR5cGUgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwKCQlYTUxfRVJSX0lOVEVSTkFMX0VSUk9SLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tEZXJpdmF0aW9uVmFsaWRTaW1wbGVSZXN0cmljdGlvbjogIgoJCSJmYWlsZWQgdG8gZXZhbHVhdGUgdGhlIGl0ZW0gdHlwZSBvZiB0eXBlIFwiJXNcIi5cbiIsCgkJdHlwZS0+bmFtZSwgTlVMTCk7CgkgICAgcmV0dXJuICgtMSk7Cgl9CgkvKgoJKiAyLjEgVGhlIHtpdGVtIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBoYXZlIGEge3ZhcmlldHl9IG9mIGF0b21pYyBvciAKCSogdW5pb24gKGluIHdoaWNoIGNhc2UgYWxsIHRoZSB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9IAoJKiBtdXN0IGJlIGF0b21pYykuCgkqLwoJaWYgKCgoaXRlbVR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0FUT01JQykgPT0gMCkgJiYgIAoJICAgICgoaXRlbVR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OKSA9PSAwKSkgewkgICAgCgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8xLAoJCSJMaXN0IHNpbXBsZSB0eXBlIFwiJXNcIjogaXRzIGl0ZW0gdHlwZSBcIiVzXCIgIgoJCSJpcyBub3QgYW4gYXRvbWljIG9yIHVuaW9uIHNpbXBsZSB0eXBlLlxuIiwKCQl0eXBlLT5uYW1lLCBpdGVtVHlwZS0+bmFtZSk7CSAgICAKCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8xKTsKCX0gZWxzZSBpZiAoaXRlbVR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OKSB7CgkgICAgeG1sU2NoZW1hVHlwZUxpbmtQdHIgbWVtYmVyOwoKCSAgICBtZW1iZXIgPSBpdGVtVHlwZS0+bWVtYmVyVHlwZXM7CgkgICAgd2hpbGUgKG1lbWJlciAhPSBOVUxMKSB7CgkJaWYgKChtZW1iZXItPnR5cGUtPmZsYWdzICYgCgkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9BVE9NSUMpID09IDApIHsKCQkgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfMSwKCQkJIkxpc3Qgc2ltcGxlIHR5cGUgXCIlc1wiOiBpdHMgaXRlbSB0eXBlICIgCgkJCSJpcyBhIHVuaW9uIHNpbXBsZSB0eXBlLCBidXQgdGhlIG1lbWJlciB0eXBlICIKCQkJIlwiJXNcIiBvZiB0aGlzIGl0ZW0gdHlwZSBpcyBub3QgYW4gXCJhdG9taWNcIiAiCgkJCSJzaW1wbGUgdHlwZS5cbiIsCgkJCXR5cGUtPm5hbWUsIG1lbWJlci0+dHlwZS0+bmFtZSk7CgkJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzEpOwoJCX0KCQltZW1iZXIgPSBtZW1iZXItPm5leHQ7CgkgICAgfQoJfQoJCglpZiAodHlwZS0+YmFzZVR5cGUgPT0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSkpIHsKCSAgICB4bWxTY2hlbWFGYWNldFB0ciBmYWNldDsKCSAgICAvKgoJICAgICogVGhpcyBpcyB0aGUgY2FzZSBpZiB3ZSBoYXZlOiA8c2ltcGxlVHlwZT48bGlzdCAuLgoJICAgICovCgkgICAgLyoKCSAgICAqIDIuMy4xIAoJICAgICogMi4zLjEuMSBUaGUge2ZpbmFsfSBvZiB0aGUge2l0ZW0gdHlwZSBkZWZpbml0aW9ufSBtdXN0IG5vdCAKCSAgICAqIGNvbnRhaW4gbGlzdC4KCSAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyhjdHh0LT5zY2hlbWEsIAoJCWl0ZW1UeXBlLCBYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX0xJU1QpKSB7CgkJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJCSAgICBYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18xXzEsCgkJICAgICJMaXN0IHNpbXBsZSB0eXBlIFwiJXNcIjogdGhlIFwiZmluYWxcIiBvZiBpdHMgaXRlbSB0eXBlICIKCQkgICAgIlwiJXNcIiBtdXN0IG5vdCBjb250YWluIFwibGlzdFwiLlxuIiwKCQkgICAgdHlwZS0+bmFtZSwgaXRlbVR5cGUtPm5hbWUpOwoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMV8xKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIDIuMy4xLjIgVGhlIHtmYWNldHN9IG11c3Qgb25seSBjb250YWluIHRoZSB3aGl0ZVNwYWNlCgkgICAgKiBmYWNldCBjb21wb25lbnQuCgkgICAgKi8KCSAgICBpZiAodHlwZS0+ZmFjZXRzICE9IE5VTEwpIHsKCQlmYWNldCA9IHR5cGUtPmZhY2V0czsKCQlkbyB7CgkJICAgIGlmIChmYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX1dISVRFU1BBQ0UpIHsJCSAKCQkJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJCQkgICAgWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMV8yLAoJCQkgICAgIkxpc3Qgc2ltcGxlIHR5cGUgXCIlc1wiOiB0aGUgZmFjZXQgXCIlc1wiICIKCQkJICAgICJpcyBub3QgYWxsb3dlZC5cbiIsIAoJCQkgICAgdHlwZS0+bmFtZSwKCQkJICAgIEJBRF9DQVNUIHhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKGZhY2V0LT50eXBlKSk7CgkJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMV8yKTsKCQkgICAgfQoJCSAgICBmYWNldCA9IGZhY2V0LT5uZXh0OwoJCX0gd2hpbGUgKGZhY2V0ICE9IE5VTEwpOwoJICAgIH0KCSAgICAvKgoJICAgICogVE9ETzogRGF0YXR5cGVzIHN0YXRlczogCgkgICAgKiBBILdsaXN0tyBkYXRhdHlwZSBjYW4gYmUgt2Rlcml2ZWS3IGZyb20gYW4gt2F0b21pY7cgZGF0YXR5cGUgCgkgICAgKiB3aG9zZSC3bGV4aWNhbCBzcGFjZbcgYWxsb3dzIHNwYWNlIChzdWNoIGFzIHN0cmluZyBvciBhbnlVUkkpb3IgCgkgICAgKiBhILd1bmlvbrcgZGF0YXR5cGUgYW55IG9mIHdob3NlIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30ncyAKCSAgICAqILdsZXhpY2FsIHNwYWNltyBhbGxvd3Mgc3BhY2UuCgkgICAgKi8KCX0gZWxzZSB7CgkgICAgLyoKCSAgICAqIFRoaXMgaXMgdGhlIGNhc2UgaWYgd2UgaGF2ZTogPHNpbXBsZVR5cGU+PHJlc3RyaWN0aW9uIC4uLgoJICAgICovCgkgICAgLyoKCSAgICAqIDIuMy4yIAoJICAgICogMi4zLjIuMSBUaGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IGhhdmUgYSB7dmFyaWV0eX0gb2YgbGlzdC4KCSAgICAqLwoJICAgIGlmICgodHlwZS0+YmFzZVR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1QpID09IDApIHsKCQl4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsCgkJICAgIFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzJfMSwKCQkgICAgIkxpc3Qgc2ltcGxlIHR5cGUgXCIlc1wiOiBpdHMgYmFzZSB0eXBlIFwiJXNcIiBtdXN0ICIKCQkgICAgImhhdmUgYSB2YXJpZXR5IG9mIGxpc3QuXG4iLAoJCSAgICB0eXBlLT5uYW1lLCB0eXBlLT5iYXNlVHlwZS0+bmFtZSk7CgkJcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18yXzEpOwoJICAgIH0KCSAgICAvKgoJICAgICogMi4zLjIuMiBUaGUge2ZpbmFsfSBvZiB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSBtdXN0IG5vdAoJICAgICogY29udGFpbiByZXN0cmljdGlvbi4KCSAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyhjdHh0LT5zY2hlbWEsIHR5cGUtPmJhc2VUeXBlLAoJCVhNTF9TQ0hFTUFTX1RZUEVfRklOQUxfUkVTVFJJQ1RJT04pKSB7CgkJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJCSAgICBYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18yXzIsCgkJICAgICJMaXN0IHNpbXBsZSB0eXBlIFwiJXNcIjogaXRzIGJhc2UgdHlwZSBcIiVzXCIgbXVzdCBub3QgIgoJCSAgICAiaGF2ZSBhIFwiZmluYWxcIiBjb250YWluaW5nIFwicmVzdHJpY3Rpb25cIi5cbiIsCgkJICAgIHR5cGUtPm5hbWUsIHR5cGUtPmJhc2VUeXBlLT5uYW1lKTsKCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzJfMik7CgkgICAgfQoJICAgIC8qCgkgICAgKiAyLjMuMi4zIFRoZSB7aXRlbSB0eXBlIGRlZmluaXRpb259IG11c3QgYmUgdmFsaWRseSBkZXJpdmVkIAoJICAgICogZnJvbSB0aGUge2Jhc2UgdHlwZSBkZWZpbml0aW9ufSdzIHtpdGVtIHR5cGUgZGVmaW5pdGlvbn0gZ2l2ZW4KCSAgICAqIHRoZSBlbXB0eSBzZXQsIGFzIGRlZmluZWQgaW4gVHlwZSBEZXJpdmF0aW9uIE9LIChTaW1wbGUpICinMy4xNC42KS4KCSAgICAqLwoJICAgIHsKCQl4bWxTY2hlbWFUeXBlUHRyIGJhc2VJdGVtVHlwZTsKCgkJYmFzZUl0ZW1UeXBlID0geG1sU2NoZW1hR2V0TGlzdFNpbXBsZVR5cGVJdGVtVHlwZSh0eXBlLT5iYXNlVHlwZSk7CgkJaWYgKGJhc2VJdGVtVHlwZSA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwKCQkJWE1MX0VSUl9JTlRFUk5BTF9FUlJPUiwKCQkJInhtbFNjaGVtYUNoZWNrRGVyaXZhdGlvblZhbGlkU2ltcGxlUmVzdHJpY3Rpb246ICIKCQkJIkxpc3Qgc2ltcGxlIHR5cGUgXCIlc1wiOiBmYWlsZWQgdG8gIgoJCQkiZXZhbHVhdGUgdGhlIGl0ZW0gdHlwZSBvZiBpdHMgYmFzZSB0eXBlIFwiJXNcIi5cbiIsCgkJCXR5cGUtPm5hbWUsIHR5cGUtPmJhc2VUeXBlLT5uYW1lKTsKCQkgICAgcmV0dXJuICgtMSk7CgkJfQoJCWlmICgoaXRlbVR5cGUgIT0gYmFzZUl0ZW1UeXBlKSAmJgoJCSAgICAoeG1sU2NoZW1hQ2hlY2tDT1NTVERlcml2ZWRPSyhjdHh0LT5zY2hlbWEsIGl0ZW1UeXBlLAoJCSAgICBiYXNlSXRlbVR5cGUsIDApICE9IDApKSB7CgkJICAgIHhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgdHlwZS0+bm9kZSwgCgkJCVhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfMl8zXzJfMywgTlVMTCwgTlVMTCwgTlVMTCwKCQkJIkxpc3Qgc2ltcGxlIHR5cGUgXCIlc1wiOiBpdHMgaXRlbSB0eXBlIFwiJXNcIiBpcyBub3QgIgoJCQkidmFsaWRseSBkZXJpdmVkIGZyb20gdGhlIGl0ZW0gdHlwZSBcIiVzXCIgb2YgdGhlICIKCQkJImJhc2UgdHlwZSBcIiVzXCIgYXMgZGVmaW5lZCBpbiBUeXBlIERlcml2YXRpb24gT0sgIgoJCQkiKFNpbXBsZSkuXG4iLAoJCQl0eXBlLT5uYW1lLCBpdGVtVHlwZS0+bmFtZSwgYmFzZUl0ZW1UeXBlLT5uYW1lLAoJCQl0eXBlLT5iYXNlVHlwZS0+bmFtZSwgTlVMTCk7CgkJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMl8zKTsKCQl9CgkgICAgfQoJICAgIAoJICAgIGlmICh0eXBlLT5mYWNldHMgIT0gTlVMTCkgewoJCXhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0OwoJCWludCBvayA9IDE7CgkJLyogCgkJKiAyLjMuMi40IE9ubHkgbGVuZ3RoLCBtaW5MZW5ndGgsIG1heExlbmd0aCwgd2hpdGVTcGFjZSwgcGF0dGVybiAKCQkqIGFuZCBlbnVtZXJhdGlvbiBmYWNldCBjb21wb25lbnRzIGFyZSBhbGxvd2VkIGFtb25nIHRoZSB7ZmFjZXRzfS4KCQkqLwoJCWZhY2V0ID0gdHlwZS0+ZmFjZXRzOwoJCWRvIHsKCQkgICAgc3dpdGNoIChmYWNldC0+dHlwZSkgewoJCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOgoJCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIOgoJCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUFYTEVOR1RIOgoJCQljYXNlIFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRToKCQkJICAgIC8qCgkJCSAgICAqIFRPRE86IDIuNS4xLjIgTGlzdCBkYXRhdHlwZXMKCQkJICAgICogVGhlIHZhbHVlIG9mILd3aGl0ZVNwYWNltyBpcyBmaXhlZCB0byB0aGUgdmFsdWUgY29sbGFwc2UuIAoJCQkgICAgKi8KCQkJY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk46CgkJCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTjoKCQkJICAgIGJyZWFrOwoJCQlkZWZhdWx0OiB7CgkJCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsCgkJCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzJfM18yXzQsCgkJCQkiTGlzdCBzaW1wbGUgdHlwZSBcIiVzXCI6IHRoZSBmYWNldCBcIiVzXCIgIgoJCQkJImlzIG5vdCBhbGxvd2VkLlxuIiwKCQkJCXR5cGUtPm5hbWUsIAoJCQkJQkFEX0NBU1QgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoZmFjZXQtPnR5cGUpKTsKCQkJICAgIC8qCgkJCSAgICAqIFdlIGNvdWxkIHJldHVybiwgYnV0IGl0J3MgbmljZXIgdG8gcmVwb3J0IGFsbCAKCQkJICAgICogaW52YWxpZCBmYWNldHMuCgkJCSAgICAqLwoJCQkgICAgb2sgPSAwOwkJCSAgICAKCQkJfQoJCSAgICB9CQkgICAgCgkJICAgIGZhY2V0ID0gZmFjZXQtPm5leHQ7CgkJfSB3aGlsZSAoZmFjZXQgIT0gTlVMTCk7CgkJaWYgKG9rID09IDApCgkJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18yXzNfMl80KTsKCQkvKgoJCSogVE9ETzogMi4zLjIuNSBGb3IgZWFjaCBmYWNldCBpbiB0aGUge2ZhY2V0c30gKGNhbGwgdGhpcyBERiksIGlmIHRoZXJlCgkJKiBpcyBhIGZhY2V0IG9mIHRoZSBzYW1lIGtpbmQgaW4gdGhlIHtmYWNldHN9IG9mIHRoZSB7YmFzZSB0eXBlIAoJCSogZGVmaW5pdGlvbn0gKGNhbGwgdGhpcyBCRiksdGhlbiB0aGUgREYncyB7dmFsdWV9IG11c3QgYmUgYSB2YWxpZCAKCQkqIHJlc3RyaWN0aW9uIG9mIEJGJ3Mge3ZhbHVlfSBhcyBkZWZpbmVkIGluIFtYTUwgU2NoZW1hczogRGF0YXR5cGVzXS4KCQkqLwoJICAgIH0JICAgIAoJICAgIAoKCX0KICAgIH0gZWxzZSBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT04pIHsKCS8qCgkqIDMuMSBUaGUge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSBtdXN0IGFsbCBoYXZlIHt2YXJpZXR5fSBvZiAKCSogYXRvbWljIG9yIGxpc3QuCgkqLwoJeG1sU2NoZW1hVHlwZUxpbmtQdHIgbWVtYmVyOwoKCW1lbWJlciA9IHR5cGUtPm1lbWJlclR5cGVzOwoJd2hpbGUgKG1lbWJlciAhPSBOVUxMKSB7CgkgICAgaWYgKCgobWVtYmVyLT50eXBlLT5mbGFncyAmIAoJCVhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9BVE9NSUMpID09IDApICYmIAoJCSgobWVtYmVyLT50eXBlLT5mbGFncyAmIAoJCVhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSA9PSAwKSkgewoJCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwKCQkgICAgWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzEsCgkJICAgICJVbmlvbiBzaW1wbGUgdHlwZSBcIiVzXCI6IHRoZSBtZW1iZXIgdHlwZSAiIAoJCSAgICAiXCIlc1wiIGlzIG5vdCBhbiBcImF0b21pY1wiIHNpbXBsZSB0eXBlLlxuIiwKCQkgICAgdHlwZS0+bmFtZSwgbWVtYmVyLT50eXBlLT5uYW1lKTsKCQlyZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18xKTsKCSAgICB9CgkgICAgbWVtYmVyID0gbWVtYmVyLT5uZXh0OwoJfQoJLyoKCSogMy4zLjEgSWYgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gaXMgdGhlILdzaW1wbGUgdXItdHlwZSAKCSogZGVmaW5pdGlvbrcgCgkqLwoJaWYgKHR5cGUtPmJhc2VUeXBlID09IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpKSB7CgkgICAgLyoKCSAgICAqIDMuMy4xLjEgQWxsIG9mIHRoZSB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9IG11c3QgaGF2ZSBhIAoJICAgICoge2ZpbmFsfSB3aGljaCBkb2VzIG5vdCBjb250YWluIHVuaW9uLgoJICAgICovCgkgICAgbWVtYmVyID0gdHlwZS0+bWVtYmVyVHlwZXM7CgkgICAgd2hpbGUgKG1lbWJlciAhPSBOVUxMKSB7CgkJaWYgKHhtbFNjaGVtYVR5cGVGaW5hbENvbnRhaW5zKGN0eHQtPnNjaGVtYSwgbWVtYmVyLT50eXBlLCAKCQkgICAgWE1MX1NDSEVNQVNfVFlQRV9GSU5BTF9VTklPTikpIHsKCQkgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18xLAoJCQkiVW5pb24gc2ltcGxlIHR5cGUgXCIlc1wiOiB0aGUgXCJmaW5hbFwiIG9mIG1lbWJlciB0eXBlICIgCgkJCSJcIiVzXCIgY29udGFpbnMgXCJ1bmlvblwiLlxuIiwKCQkJdHlwZS0+bmFtZSwgbWVtYmVyLT50eXBlLT5uYW1lKTsKCQkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18xKTsKCQl9CgkJbWVtYmVyID0gbWVtYmVyLT5uZXh0OwoJICAgIH0KCSAgICAvKgoJICAgICogMy4zLjEuMiBUaGUge2ZhY2V0c30gbXVzdCBiZSBlbXB0eS4KCSAgICAqLwoJICAgIGlmICh0eXBlLT5mYWNldFNldCAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJCSAgICBYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18xXzIsCgkJICAgICJVbmlvbiBzaW1wbGUgdHlwZSBcIiVzXCI6IHRoZSBmYWNldHMgbXVzdCBiZSBlbXB0eS5cbiIsCgkJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMV8yKTsKCSAgICB9Cgl9IGVsc2UgewoJICAgIC8qCgkgICAgKiAzLjMuMi4xIFRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259IG11c3QgaGF2ZSBhIHt2YXJpZXR5fSBvZiB1bmlvbi4KCSAgICAqLwoJICAgIGlmICgodHlwZS0+YmFzZVR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OKSA9PSAwKSB7CgkJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJCSAgICBYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18yXzEsCgkJICAgICJVbmlvbiBzaW1wbGUgdHlwZSBcIiVzXCI6IGl0cyBiYXNlIHR5cGUgXCIlc1wiIGhhcyBub3QgYSAiCgkJICAgICJ2YXJpZXR5IG9mIHVuaW9uLlxuIiwKCQkgICAgdHlwZS0+bmFtZSwgdHlwZS0+YmFzZVR5cGUtPm5hbWUpOwoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl8xKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIDMuMy4yLjIgVGhlIHtmaW5hbH0gb2YgdGhlIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gbXVzdCBub3QgY29udGFpbiByZXN0cmljdGlvbi4KCSAgICAqLwoJICAgIGlmICh4bWxTY2hlbWFUeXBlRmluYWxDb250YWlucyhjdHh0LT5zY2hlbWEsIHR5cGUtPmJhc2VUeXBlLCAKCQlYTUxfU0NIRU1BU19UWVBFX0ZJTkFMX1JFU1RSSUNUSU9OKSkgewoJCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwKCQkgICAgWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl8yLAoJCSAgICAiVW5pb24gc2ltcGxlIHR5cGUgXCIlc1wiOiB0aGUgXCJmaW5hbFwiIG9mIGl0cyBiYXNlICIKCQkgICAgInR5cGUgXCIlc1wiIG11c3Qgbm90IGNvbnRhaW4gXCJyZXN0cmljdGlvblwiLlxuIiwKCQkgICAgdHlwZS0+bmFtZSwgdHlwZS0+YmFzZVR5cGUtPm5hbWUpOwoJCXJldHVybiAoWE1MX1NDSEVNQVBfQ09TX1NUX1JFU1RSSUNUU18zXzNfMl8yKTsKCSAgICB9CgkgICAgLyoKCSAgICAqIDMuMy4yLjMgVGhlIHttZW1iZXIgdHlwZSBkZWZpbml0aW9uc30sIGluIG9yZGVyLCBtdXN0IGJlIHZhbGlkbHkgCgkgICAgKiBkZXJpdmVkIGZyb20gdGhlIGNvcnJlc3BvbmRpbmcgdHlwZSBkZWZpbml0aW9ucyBpbiB0aGUge2Jhc2UgCgkgICAgKiB0eXBlIGRlZmluaXRpb259J3Mge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSBnaXZlbiB0aGUgZW1wdHkgc2V0LCAKCSAgICAqIGFzIGRlZmluZWQgaW4gVHlwZSBEZXJpdmF0aW9uIE9LIChTaW1wbGUpICinMy4xNC42KS4KCSAgICAqLwoJICAgIHsKCQl4bWxTY2hlbWFUeXBlTGlua1B0ciBiYXNlTWVtYmVyOwoKCQkvKgoJCSogT1BUSU1JWkU6IGlmIHRoZSB0eXBlIGlzIHJlc3RyaWN0aW5nLCBpdCBoYXMgbm8gbG9jYWwgZGVmaW5lZCAKCQkqIG1lbWJlciB0eXBlcyBhbmQgaW5oZXJpdHMgdGhlIG1lbWJlciB0eXBlcyBvZiB0aGUgYmFzZSB0eXBlOyAKCQkqIHRodXMgYSBjaGVjayBmb3IgZXF1YWxpdHkgY2FuIGJlIHNraXBwZWQuCgkJKi8KCQkvKgoJCSogVE9ETzogRXZlbiB3b3JzZTogSSBjYW5ub3Qgc2VlIGEgc2NlbmFyaW8gd2hlcmUgYSByZXN0cmljdGluZwoJCSogdW5pb24gc2ltcGxlIHR5cGUgY2FuIGhhdmUgb3RoZXIgbWVtYmVyIHR5cGVzIGFzIHRoZSBtZW1iZXIgCgkJKiB0eXBlcyBvZiBpdCdzIGJhc2UgdHlwZS4gVGhpcyBjaGVjayBzZWVtcyBub3QgbmVjZXNzYXJ5IHdpdGgKCQkqIHJlc3BlY3QgdG8gdGhlIGRlcml2YXRpb24gcHJvY2VzcyBpbiBsaWJ4bWwyLgoJCSovCgkJaWYgKHR5cGUtPm1lbWJlclR5cGVzICE9IE5VTEwpIHsKCQkgICAgbWVtYmVyID0gdHlwZS0+bWVtYmVyVHlwZXM7CgkJICAgIGJhc2VNZW1iZXIgPSB4bWxTY2hlbWFHZXRVbmlvblNpbXBsZVR5cGVNZW1iZXJUeXBlcyh0eXBlLT5iYXNlVHlwZSk7CgkJICAgIGlmICgobWVtYmVyID09IE5VTEwpICYmIChiYXNlTWVtYmVyICE9IE5VTEwpKSB7CQkgICAKCQkJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJCQkgICAgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCQkgICAgIkludGVybmFsIGVycm9yOiAiCgkJCSAgICAieG1sU2NoZW1hQ2hlY2tEZXJpdmF0aW9uVmFsaWRTaW1wbGVSZXN0cmljdGlvbiAiCgkJCSAgICAiKDMuMy4yLjMpLCB1bmlvbiBzaW1wbGUgdHlwZSBcIiVzXCIsIHVuZXF1YWwgbnVtYmVyICIKCQkJICAgICJvZiBtZW1iZXIgdHlwZXMgaW4gdGhlIGJhc2UgdHlwZVxuIiwKCQkJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJCSAgICB9CQkKCQkgICAgd2hpbGUgKG1lbWJlciAhPSBOVUxMKSB7CgkJCWlmIChiYXNlTWVtYmVyID09IE5VTEwpIHsKCQkJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZS0+bm9kZSwKCQkJCVhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKCQkJCSJJbnRlcm5hbCBlcnJvcjogIgoJCQkJInhtbFNjaGVtYUNoZWNrRGVyaXZhdGlvblZhbGlkU2ltcGxlUmVzdHJpY3Rpb24gIgoJCQkJIigzLjMuMi4zKSwgdW5pb24gc2ltcGxlIHR5cGUgXCIlc1wiLCB1bmVxdWFsIG51bWJlciAiCgkJCQkib2YgbWVtYmVyIHR5cGVzIGluIHRoZSBiYXNlIHR5cGVcbiIsCgkJCQl0eXBlLT5uYW1lLCBOVUxMKTsKCQkJfQoJCQlpZiAoKG1lbWJlci0+dHlwZSAhPSBiYXNlTWVtYmVyLT50eXBlKSAmJgoJCQkgICAgKHhtbFNjaGVtYUNoZWNrQ09TU1REZXJpdmVkT0soY3R4dC0+c2NoZW1hLCAKCQkJICAgIG1lbWJlci0+dHlwZSwgYmFzZU1lbWJlci0+dHlwZSwgMCkgIT0gMCkpIHsKCQkJICAgIHhtbFNjaGVtYVBFcnJFeHQoY3R4dCwgdHlwZS0+bm9kZSwgCgkJCQlYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18yXzMsIE5VTEwsIAoJCQkJTlVMTCwgTlVMTCwKCQkJCSJVbmlvbiBzaW1wbGUgdHlwZSBcIiVzXCI6IGl0cyBtZW1iZXIgdHlwZSAiCgkJCQkiXCIlc1wiIGlzIG5vdCB2YWxpZGx5IGRlcml2ZWQgZnJvbSBpdHMgIgoJCQkJImNvcnJlc3BvbmRpbmcgbWVtYmVyIHR5cGUgXCIlc1wiIG9mIHRoZSBiYXNlICIKCQkJCSJ0eXBlIFwiJXNcIiBhcyBkZWZpbmVkIGluIFR5cGUgRGVyaXZhdGlvbiBPSyAiCgkJCQkiKFNpbXBsZSkuXG4iLAoJCQkJdHlwZS0+bmFtZSwgbWVtYmVyLT50eXBlLT5uYW1lLCAKCQkJCWJhc2VNZW1iZXItPnR5cGUtPm5hbWUsCgkJCQl0eXBlLT5iYXNlVHlwZS0+bmFtZSwgTlVMTCk7CgkJCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX0NPU19TVF9SRVNUUklDVFNfM18zXzJfMyk7CgkJCX0JCQoJCQltZW1iZXIgPSBtZW1iZXItPm5leHQ7CgkJCWJhc2VNZW1iZXIgPSBiYXNlTWVtYmVyLT5uZXh0OwoJCSAgICB9CgkJfQoJICAgIH0KCSAgICAvKgoJICAgICogMy4zLjIuNCBPbmx5IHBhdHRlcm4gYW5kIGVudW1lcmF0aW9uIGZhY2V0IGNvbXBvbmVudHMgYXJlIAoJICAgICogYWxsb3dlZCBhbW9uZyB0aGUge2ZhY2V0c30uCgkgICAgKi8JICAgIAoJICAgIGlmICh0eXBlLT5mYWNldHMgIT0gTlVMTCkgewoJCXhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0OwoJCWludCBvayA9IDE7CgoJCWZhY2V0ID0gdHlwZS0+ZmFjZXRzOwoJCWRvIHsKCQkgICAgaWYgKChmYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk4pICYmCgkJCShmYWNldC0+dHlwZSAhPSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OKSkgewoJCQl4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsCgkJCSAgICBYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18yXzQsCgkJCSAgICAiVW5pb24gc2ltcGxlIHR5cGUgXCIlc1wiOiB0aGUgZmFjZXQgXCIlc1wiICIKCQkJICAgICJpcyBub3QgYWxsb3dlZC5cbiIsCgkJCSAgICB0eXBlLT5uYW1lLCAKCQkJICAgIEJBRF9DQVNUIHhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKGZhY2V0LT50eXBlKSk7CgkJCW9rID0gMDsJCQkgICAgCgkJICAgIH0JCSAgICAKCQkgICAgZmFjZXQgPSBmYWNldC0+bmV4dDsKCQl9IHdoaWxlIChmYWNldCAhPSBOVUxMKTsKCQlpZiAob2sgPT0gMCkKCQkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9DT1NfU1RfUkVTVFJJQ1RTXzNfM18yXzQpOwoJCSAgICAKCSAgICB9CgkgICAgLyoKCSAgICAqIFRPRE86IDMuMy4yLjUgKGZhY2V0IGRlcml2YXRpb24pCgkgICAgKi8KCX0KICAgIH0KCiAgICByZXR1cm4gKDApOwp9CgovKioKICogeG1sU2NoZW1hQ2hlY2tTUkNTaW1wbGVUeXBlOgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQHR5cGU6ICB0aGUgc2ltcGxlIHR5cGUgZGVmaW5pdGlvbgogKgogKiBDaGVja3MgY3JjLXNpbXBsZS10eXBlIGNvbnN0cmFpbnRzLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGNvbnN0cmFpbnRzIGFyZSBzYXRpc2ZpZWQsCiAqIGlmIG5vdCBhIHBvc2l0aXZlIGVycm9yIGNvZGUgYW5kIC0xIG9uIGludGVybmFsCiAqIGVycm9ycy4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tTUkNTaW1wbGVUeXBlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwKCQkJICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKeyAgIAogICAgLyoKICAgICogTk9URTogc3JjLXNpbXBsZS10eXBlIDItNCBhcmUgcmVkdW5kYW50LCBzaW5jZSB0aGUgY2hlY2tzCiAgICAqIHdlcmUgYXJlIGRvbmUgZm9yIHRoZSBjb3JyZXNwb25kaW5nIDxyZXN0cmljdGlvbj4sIDxsaXN0PiBhbmQgPHVuaW9uPgogICAgKiBlbGVtZW50cywgYnV0IFczQyB3YW50cyBhIDxzaW1wbGVUeXBlPiBlcnJvciBhcyB3ZWxsLCBzbyBpdCBnZXRzIG9uZS4KICAgICogTWFieSB0aGlzIGNhbiBiZSBza2lwcGVkIGluIHRoZSBmdXR1cmUsIGlmIHdlIGdldCBzdXJlIGl0J3Mgbm90IG5lZWRlZC4KICAgICovCiAgICBpZiAodHlwZS0+c3VidHlwZXMgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJCVhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrU1JDU2ltcGxlVHlwZSwgIgoJCSJubyBzdWJ0eXBlIG9uIHNpbXBsZSB0eXBlIFwiJXNcIi5cbiIsCgkJdHlwZS0+bmFtZSwgTlVMTCk7CglyZXR1cm4gKC0xKTsKICAgIH0KICAgIC8qIAogICAgKiBzcmMtc2ltcGxlLXR5cGUuMSBUaGUgY29ycmVzcG9uZGluZyBzaW1wbGUgdHlwZSBkZWZpbml0aW9uLCBpZiBhbnksCiAgICAqIG11c3Qgc2F0aXNmeSB0aGUgY29uZGl0aW9ucyBzZXQgb3V0IGluIENvbnN0cmFpbnRzIG9uIFNpbXBsZSBUeXBlIAogICAgKiBEZWZpbml0aW9uIFNjaGVtYSBDb21wb25lbnRzICinMy4xNC42KS4gICAgCiAgICAqLwogICAgaWYgKCh4bWxTY2hlbWFDaGVja1NUUHJvcHNDb3JyZWN0KGN0eHQsIHR5cGUpICE9IDApIHx8CgkoeG1sU2NoZW1hQ2hlY2tDT1NTVFJlc3RyaWN0cyhjdHh0LCB0eXBlKSAhPSAwKSkgewoJLyoKCSogVE9ETzogUmVtb3ZlZCB0aGlzLCBzaW5jZSBpdCBnb3QgYW5ub3lpbmcgdG8gZ2V0IGFuCgkqIGV4dHJhIGVycm9yIHJlcG9ydCwgaWYgYW55dGhpbmcgZmFpbGVkIHVudGlsIG5vdy4KCSogRW5hYmxlIHRoaXMgaWYgbmVlZGVkLgoJKi8KCS8qCgl4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsCgkgICAgWE1MX1NDSEVNQVBfU1JDX1NJTVBMRV9UWVBFXzEsCgkgICAgIlNpbXBsZSB0eXBlIFwiJXNcIiBkb2VzIG5vdCBzYXRpc2Z5IHRoZSBjb25zdHJhaW50cyAiCgkgICAgIm9uIHNpbXBsZSB0eXBlIGRlZmluaXRpb25zLlxuIiwKCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKCSovCglyZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV8xKTsKICAgIH0KCiAgICBpZiAodHlwZS0+c3VidHlwZXMtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX1JFU1RSSUNUSU9OKSB7CgkvKgoJKiBzcmMtc2ltcGxlLXR5cGUuMiBJZiB0aGUgPHJlc3RyaWN0aW9uPiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4sIAoJKiBlaXRoZXIgaXQgbXVzdCBoYXZlIGEgYmFzZSBbYXR0cmlidXRlXSBvciBhIDxzaW1wbGVUeXBlPiBhbW9uZyBpdHMgCgkqIFtjaGlsZHJlbl0sIGJ1dCBub3QgYm90aC4KCSovCQoJaWYgKCgodHlwZS0+c3VidHlwZXMtPmJhc2UgPT0gTlVMTCkgJiYgCgkgICAgICgodHlwZS0+c3VidHlwZXMtPnN1YnR5cGVzID09IE5VTEwpIHx8CgkgICAgICAodHlwZS0+c3VidHlwZXMtPnN1YnR5cGVzLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpKSkgfHwKCSAgICAoKHR5cGUtPnN1YnR5cGVzLT5iYXNlICE9IE5VTEwpICYmCgkgICAgICh0eXBlLT5zdWJ0eXBlcy0+c3VidHlwZXMgIT0gTlVMTCkgJiYKCSAgICAgKHR5cGUtPnN1YnR5cGVzLT5zdWJ0eXBlcy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSkpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsCgkJWE1MX1NDSEVNQVBfU1JDX1NJTVBMRV9UWVBFXzIsCgkJIlNpbXBsZSB0eXBlIFwiJXNcIjogIgoJCSJUaGUgPHJlc3RyaWN0aW9uPiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4sIHRodXMgZWl0aGVyIHRoZSAiCgkJIlwiYmFzZVwiIGF0dHJpYnV0ZSBvciB0aGUgPHNpbXBsZVR5cGU+IGNoaWxkICIKCQkibXVzdCBiZSBwcmVzZW50LCBidXQgbm90IGJvdGguXG4iLAoJCXR5cGUtPm5hbWUsIE5VTEwpOwoJICAgIHJldHVybiAoWE1MX1NDSEVNQVBfU1JDX1NJTVBMRV9UWVBFXzIpOwoJfQogICAgfSBlbHNlIGlmICh0eXBlLT5zdWJ0eXBlcy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfTElTVCkgewoJLyogc3JjLXNpbXBsZS10eXBlLjMgSWYgdGhlIDxsaXN0PiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4sIGVpdGhlciBpdCBtdXN0IGhhdmUgCgkqIGFuIGl0ZW1UeXBlIFthdHRyaWJ1dGVdIG9yIGEgPHNpbXBsZVR5cGU+IGFtb25nIGl0cyBbY2hpbGRyZW5dLCAKCSogYnV0IG5vdCBib3RoLgoJKiBOT1RFOiBiYXNlVHlwZSBpcyBzZXQgdG8gdGhlIGxvY2FsIHNpbXBsZSB0eXBlIGRlZmluaXRvbiwKCSogaWYgZXhpc3RlbnQsIGF0IHBhcnNlIHRpbWUuIFRoaXMgaXMgYSBoYWNrIGFuZCBub3QgbmljZS4KCSovCglpZiAoKCh0eXBlLT5zdWJ0eXBlcy0+YmFzZSA9PSBOVUxMKSAmJiAKCSAgICAgKHR5cGUtPmJhc2VUeXBlID09IE5VTEwpKSB8fAkgICAgICAKCSAgICAoKHR5cGUtPnN1YnR5cGVzLT5iYXNlICE9IE5VTEwpICYmCgkgICAgICh0eXBlLT5zdWJ0eXBlcy0+YmFzZVR5cGUgIT0gTlVMTCkpKSB7CgkgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlLT5ub2RlLAoJCVhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV8zLAoJCSJTaW1wbGUgdHlwZSBcIiVzXCI6ICIKCQkiVGhlIDxsaXN0PiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4sIHRodXMgZWl0aGVyIHRoZSAiIAoJCSJcIml0ZW1UeXBlXCIgYXR0cmlidXRlIG9yIHRoZSA8c2ltcGxlVHlwZT4gY2hpbGQgIgoJCSJtdXN0IGJlIHByZXNlbnQsIGJ1dCBub3QgYm90aC5cbiIsCgkJdHlwZS0+bmFtZSwgTlVMTCk7CgkgICAgcmV0dXJuIChYTUxfU0NIRU1BUF9TUkNfU0lNUExFX1RZUEVfMyk7Cgl9CiAgICAKCiAgICB9IGVsc2UgaWYgKHR5cGUtPnN1YnR5cGVzLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9VTklPTikgewoJeG1sU2NoZW1hVHlwZUxpbmtQdHIgbWVtYmVyOwoJeG1sU2NoZW1hVHlwZVB0ciBhbmNlc3RvciwgYW55U2ltcGxlVHlwZTsKCglhbnlTaW1wbGVUeXBlID0geG1sU2NoZW1hR2V0QnVpbHRJblR5cGUoWE1MX1NDSEVNQVNfQU5ZU0lNUExFVFlQRSk7CgoJLyogc3JjLXNpbXBsZS10eXBlLjQgQ2lyY3VsYXIgdW5pb24gdHlwZSBkZWZpbml0aW9uIGlzIGRpc2FsbG93ZWQuIFRoYXQgaXMsIGlmIAoJKiB0aGUgPHVuaW9uPiBhbHRlcm5hdGl2ZSBpcyBjaG9zZW4sIHRoZXJlIG11c3Qgbm90IGJlIGFueSBlbnRyaWVzIAoJKiBpbiB0aGUgbWVtYmVyVHlwZXMgW2F0dHJpYnV0ZV0gYXQgYW55IGRlcHRoIHdoaWNoIHJlc29sdmUgdG8gdGhlIAoJKiBjb21wb25lbnQgY29ycmVzcG9uZGluZyB0byB0aGUgPHNpbXBsZVR5cGU+LgoJKi8JCgltZW1iZXIgPSB0eXBlLT5tZW1iZXJUeXBlczsKCXdoaWxlIChtZW1iZXIgIT0gTlVMTCkgewoJICAgIGFuY2VzdG9yID0gbWVtYmVyLT50eXBlOwoJICAgIHdoaWxlICgoYW5jZXN0b3IgIT0gTlVMTCkgJiYgKGFuY2VzdG9yLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykpIHsKCQlpZiAoYW5jZXN0b3ItPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKQoJCSAgICB4bWxTY2hlbWFUeXBlRml4dXAoYW5jZXN0b3IsIGN0eHQsICBOVUxMKTsKCQlpZiAoYW5jZXN0b3IgPT0gYW55U2ltcGxlVHlwZSkKCQkgICAgYnJlYWs7CgkJZWxzZSBpZiAoYW5jZXN0b3IgPT0gdHlwZSkgewoJCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGUtPm5vZGUsCgkJCVhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV80LAoJCQkiU2ltcGxlIHR5cGUgXCIlc1wiIGlzIG5vdCBkZXJpdmVkIGZyb20gdGhlIHNpbXBsZSAiCgkJCSJ1ci10eXBlIGRlZmluaXRpb24gKGNpcmN1bGFyIGRlZmluaXRpb25zIGFyZSBkaXNhbGxvd2VkKS5cbiIsCgkJCXR5cGUtPm5hbWUsIE5VTEwpOwoJCSAgICByZXR1cm4gKFhNTF9TQ0hFTUFQX1NSQ19TSU1QTEVfVFlQRV80KTsKCQl9IGVsc2UgaWYgKGFuY2VzdG9yLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSB7CgkJICAgIC8qCgkJICAgICogVE9ETzogQWx0aG91Z2ggYSBsaXN0IHNpbXBsZSB0eXBlIG11c3Qgbm90IGhhdmUgYSB1bmlvbiBTVAoJCSAgICAqIHR5cGUgYXMgaXRlbSB0eXBlLCB3aGljaCBpbiB0dXJuIGhhcyBhIGxpc3QgU1QgYXMgbWVtYmVyIAoJCSAgICAqIHR5cGUsIHdlIHdpbGwgYXNzdW1lIHRoaXMgaGVyZSBhcyB3ZWxsLCBzaW5jZSB0aGlzIGNoZWNrIAoJCSAgICAqIHdhcyBub3QgeWV0IHBlcmZvcm1lZC4KCQkgICAgKi8KCgkJfQoJCWFuY2VzdG9yID0gYW5jZXN0b3ItPmJhc2VUeXBlOwoJICAgIH0gICAKCSAgICBtZW1iZXIgPSBtZW1iZXItPm5leHQ7Cgl9CgogICAgfQoKICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFUeXBlRml4dXA6CiAqIEB0eXBlRGVjbDogIHRoZSBzY2hlbWEgdHlwZSBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKgogKiBGaXhlcyB0aGUgY29udGVudCBtb2RlbCBvZiB0aGUgdHlwZS4KICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYVR5cGVGaXh1cCh4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWNsLAogICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCBjb25zdCB4bWxDaGFyICogbmFtZSkKewogICAgeG1sU2NoZW1hVHlwZVB0ciBjdHh0VHlwZTsKCiAgICBpZiAodHlwZURlY2wgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICAvKgogICAgKiBEbyBub3QgYWxsb3cgdGhlIGZvbGxvd2luZyB0eXBlcyB0byBiZSB0eXBlZml4ZWQsIHByaW9yIHRvCiAgICAqIHRoZSBjb3JyZXNwb25kaW5nIHNpbXBsZS9jb21wbGV4IHR5cGVzLgogICAgKi8KICAgIGlmIChjdHh0LT5jdHh0VHlwZSA9PSBOVUxMKSB7Cglzd2l0Y2ggKHR5cGVEZWNsLT50eXBlKSB7CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFX0NPTlRFTlQ6CgkgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1VOSU9OOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1JFU1RSSUNUSU9OOgoJICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VYVEVOU0lPTjoJICAgIAoJCXJldHVybjsKCSAgICBkZWZhdWx0OgoJICAgICAgICBicmVhazsKCX0KICAgIH0KICAgIGlmIChuYW1lID09IE5VTEwpCiAgICAgICAgbmFtZSA9IHR5cGVEZWNsLT5uYW1lOwogICAgaWYgKHR5cGVEZWNsLT5jb250ZW50VHlwZSA9PSBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTikgewogICAgICAgIHN3aXRjaCAodHlwZURlY2wtPnR5cGUpIHsKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFX0NPTlRFTlQ6ewkJICAgIAoJCSAgICBpZiAodHlwZURlY2wtPnN1YnR5cGVzICE9IE5VTEwpIHsKCQkJaWYgKHR5cGVEZWNsLT5zdWJ0eXBlcy0+Y29udGVudFR5cGUgPT0KCQkJICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSB7CgkJCSAgICB4bWxTY2hlbWFUeXBlRml4dXAodHlwZURlY2wtPnN1YnR5cGVzLCBjdHh0LAoJCQkJTlVMTCk7CgkJCX0KICAgICAgICAgICAgICAgICAgICAgICAgdHlwZURlY2wtPmNvbnRlbnRUeXBlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVEZWNsLT5zdWJ0eXBlcy0+Y29udGVudFR5cGU7CgkJICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT046ewoJCSAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2UgPSBOVUxMOwoKCQkgICAgY3R4dC0+Y3R4dFR5cGUtPmZsYWdzIHw9IAoJCQlYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX1JFU1RSSUNUSU9OOwogICAgICAgICAgICAgICAgICAgIGlmICh0eXBlRGVjbC0+c3VidHlwZXMgIT0gTlVMTCkKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZUZpeHVwKHR5cGVEZWNsLT5zdWJ0eXBlcywgY3R4dCwgTlVMTCk7CgogICAgICAgICAgICAgICAgICAgIGlmICh0eXBlRGVjbC0+YmFzZSAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJhc2UgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hR2V0VHlwZShjdHh0LT5zY2hlbWEsIHR5cGVEZWNsLT5iYXNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+YmFzZU5zKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJhc2UgPT0gTlVMTCkgewoJCQkgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlRGVjbC0+bm9kZSwKCQkJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCQkJIlJlc3RyaWN0aW9uIFwiJXNcIjogdGhlIFFOYW1lIFwiJXNcIiBvZiB0aGUgIgoJCQkJImF0dHJpYnV0ZSBcImJhc2VcIiBkb2VzIG5vdCByZXNvbHZlIHRvIGEgc2NoZW1hICIKCQkJCSJjb21wb25lbnQuXG4iLAoJCQkJbmFtZSwgdHlwZURlY2wtPmJhc2UpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGJhc2UtPmNvbnRlbnRUeXBlID09IAoJCQkgICAgWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV04pIHsKCQkJICAgIC8qIAoJCQkgICAgICogVGhlIGJhc2UgdHlwZSBtaWdodCBiZSBub3QgInR5cGUgZml4ZWQiIHlldCwKCQkJICAgICAqIHNvIGRvIGl0IG5vdy4gKi8KCQkJICAgIC8qIAoJCQkgICAgICogVE9ETzogSXMgYSBjaGVjayBmb3IgY2lyY3VsYXIgZGVyaXZhdGlvbiBhbHJlYWR5CgkJCSAgICAgKiBkb25lPwoJCQkgICAgICovCgkJCSAgICB4bWxTY2hlbWFUeXBlRml4dXAoYmFzZSwgY3R4dCwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0JCQkKICAgICAgICAgICAgICAgICAgICB9CgkJICAgIGlmIChjdHh0LT5jdHh0VHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgewoJCQkvKgoJCQkqIENvbXBsZXhUeXBlIHJlc3RyaWN0aW9uLgoJCQkqLwoJCQkvKgoJCQkqIEJhc2UgdHlwZTogVGhlIHR5cGUgZGVmaW5pdGlvbiC3cmVzb2x2ZWS3IHRvIGJ5IHRoZSC3YWN0dWFsIAoJCQkqIHZhbHVltyBvZiB0aGUgYmFzZSBbYXR0cmlidXRlXQoJCQkqLwoJCQljdHh0LT5jdHh0VHlwZS0+YmFzZVR5cGUgPSBiYXNlOwoJCQkvKgoJCQkqIENvbnRlbnQgdHlwZS4KCQkJKi8KCQkJaWYgKHR5cGVEZWNsLT5zdWJ0eXBlcyA9PSBOVUxMKQoJCQkgICAgLyogMS4xLjEgKi8KCQkJICAgIHR5cGVEZWNsLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWTsKCQkJZWxzZSBpZiAoKHR5cGVEZWNsLT5zdWJ0eXBlcy0+c3VidHlwZXMgPT0gTlVMTCkgJiYKCQkJICAgICgodHlwZURlY2wtPnN1YnR5cGVzLT50eXBlID09CgkJCSAgICBYTUxfU0NIRU1BX1RZUEVfQUxMKQoJCQkgICAgfHwgKHR5cGVEZWNsLT5zdWJ0eXBlcy0+dHlwZSA9PQoJCQkgICAgWE1MX1NDSEVNQV9UWVBFX1NFUVVFTkNFKSkpCgkJCSAgICAvKiAxLjEuMiAqLwoJCQkgICAgdHlwZURlY2wtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOwoJCQllbHNlIGlmICgodHlwZURlY2wtPnN1YnR5cGVzLT50eXBlID09CgkJCSAgICBYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFKQoJCQkgICAgJiYgKHR5cGVEZWNsLT5zdWJ0eXBlcy0+c3VidHlwZXMgPT0gTlVMTCkpCgkJCSAgICAvKiAxLjEuMyAqLwoJCQkgICAgdHlwZURlY2wtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOwoJCQllbHNlIHsKCQkJICAgIC8qIDEuMiBhbmQgMi5YIGFyZSBhcHBsaWVkIGF0IHRoZSBvdGhlciBsYXllciAqLwoJCQkgICAgdHlwZURlY2wtPmNvbnRlbnRUeXBlID0KCQkJCVhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzsKCQkJfQoJCSAgICB9IGVsc2UgewkKCQkJLyoKCQkJKiBTaW1wbGVUeXBlIHJlc3RyaWN0aW9uLgoJCQkqLwoJCQkvKiBCYXNlIHR5cGU6IAoJCQkqIFRoZSBTaW1wbGUgVHlwZSBEZWZpbml0aW9uIGNvbXBvbmVudCByZXNvbHZlZCB0byBieSAKCQkJKiB0aGUgYWN0dWFsIHZhbHVlIG9mIHRoZSBiYXNlIFthdHRyaWJ1dGVdIG9yIHRoZSAKCQkJKiA8c2ltcGxlVHlwZT4gW2NoaWxkcmVuXSwgd2hpY2hldmVyIGlzIHByZXNlbnQuIAoJCQkqLwkKCQkJaWYgKChiYXNlID09IE5VTEwpICYmICh0eXBlRGVjbC0+c3VidHlwZXMgIT0gTlVMTCkpIHsKCQkJICAgIGJhc2UgPSB0eXBlRGVjbC0+c3VidHlwZXM7CgkJCSAgICBjdHh0LT5jdHh0VHlwZS0+YmFzZVR5cGUgPSBiYXNlOwoJCQkgICAgaWYgKGJhc2UtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKQkJCQoJCQkJeG1sU2NoZW1hVHlwZUZpeHVwKGJhc2UsIGN0eHQsIE5VTEwpOwoJCQl9IGVsc2UgCgkJCSAgICBjdHh0LT5jdHh0VHlwZS0+YmFzZVR5cGUgPSBiYXNlOwoKCQkJaWYgKCgodHlwZURlY2wtPmJhc2UgPT0gTlVMTCkgJiYgCgkJCSAgICAgKCh0eXBlRGVjbC0+c3VidHlwZXMgPT0gTlVMTCkgfHwJCgkJCSAgICAgICh0eXBlRGVjbC0+c3VidHlwZXMtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkpKSB8fAoJCQkgICAgKCh0eXBlRGVjbC0+YmFzZSAhPSBOVUxMKSAmJgoJCQkgICAgICh0eXBlRGVjbC0+c3VidHlwZXMgIT0gTlVMTCkgJiYJCgkJCSAgICAgKHR5cGVEZWNsLT5zdWJ0eXBlcy0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfU0lNUExFKSkpIHsKCQkJICAgIC8qIAoJCQkgICAgKiBzcmMtcmVzdHJpY3Rpb24tYmFzZS1vci1zaW1wbGVUeXBlCgkJCSAgICAqIEVpdGhlciB0aGUgYmFzZSBbYXR0cmlidXRlXSBvciB0aGUgc2ltcGxlVHlwZSBbY2hpbGRdIG9mIHRoZSAKCQkJICAgICogPHJlc3RyaWN0aW9uPiBlbGVtZW50IG11c3QgYmUgcHJlc2VudCwgYnV0IG5vdCBib3RoLiAKCQkJICAgICovCgkJCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGVEZWNsLT5ub2RlLAoJCQkJWE1MX1NDSEVNQVBfU1JDX1JFU1RSSUNUSU9OX0JBU0VfT1JfU0lNUExFVFlQRSwJCQoJCQkJIlJlc3RyaWN0aW9uIFwiJXNcIjogIgoJCQkJIkVpdGhlciB0aGUgXCJiYXNlXCIgYXR0cmlidXRlIG9yIHRoZSA8c2ltcGxlVHlwZT4gY2hpbGQgIgoJCQkJIm11c3QgYmUgcHJlc2VudCwgYnV0IG5vdCBib3RoLlxuIiwKCQkJCXR5cGVEZWNsLT5uYW1lLCBOVUxMKTsKCQkJfQoJCSAgICB9CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VYVEVOU0lPTjp7CgkJICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZSA9IE5VTEw7CgkJICAgIHhtbFNjaGVtYUNvbnRlbnRUeXBlIGV4cGxpY2l0Q29udGVudFR5cGU7CgkJICAgIAoJCSAgICAvKgoJCSAgICAqIEFuIGV4dGVuc2lvbiBkb2VzIGV4aXN0IG9uIGEgY29tcGxleFR5cGUgb25seS4KCQkgICAgKi8KCQkgICAgY3R4dC0+Y3R4dFR5cGUtPmZsYWdzIHw9IAoJCQlYTUxfU0NIRU1BU19UWVBFX0RFUklWQVRJT05fTUVUSE9EX0VYVEVOU0lPTjsKCQkgICAgaWYgKHR5cGVEZWNsLT5yZWN1cnNlKSB7CgkJCS8qIFRPRE86IFRoZSB3b3JkICJyZWN1cnNpdmUiIHNob3VsZCBiZSBjaGFuZ2VkIHRvICJjaXJjdWxhciIgaGVyZS4gKi8KICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlRGVjbC0+bm9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BUF9VTktOT1dOX0JBU0VfVFlQRSwKCQkJCSAgIlNjaGVtYXM6IGV4dGVuc2lvbiB0eXBlICVzIGlzIHJlY3Vyc2l2ZVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwoJCSAgICB9CgkJICAgIGlmICh0eXBlRGVjbC0+YmFzZSAhPSBOVUxMKSB7ICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgIGJhc2UgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hR2V0VHlwZShjdHh0LT5zY2hlbWEsIHR5cGVEZWNsLT5iYXNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+YmFzZU5zKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJhc2UgPT0gTlVMTCkgewoJCQkgICAgeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlRGVjbC0+bm9kZSwKCQkJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCQkJIkV4dGVuc2lvbiBcIiVzXCI6IHRoZSBRTmFtZSBcIiVzXCIgb2YgdGhlICIKCQkJCSJhdHRyaWJ1dGUgXCJiYXNlXCIgZG9lcyBub3QgcmVzb2x2ZSB0byBhIHNjaGVtYSAiCgkJCQkiY29tcG9uZW50LlxuIiwKCQkJCW5hbWUsIHR5cGVEZWNsLT5iYXNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChiYXNlLT5jb250ZW50VHlwZSA9PSAKCQkJICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSB7CgkJCSAgICB0eXBlRGVjbC0+cmVjdXJzZSA9IDE7CgkJCSAgICB4bWxTY2hlbWFUeXBlRml4dXAoYmFzZSwgY3R4dCwgTlVMTCk7CgkJCSAgICB0eXBlRGVjbC0+cmVjdXJzZSA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCQkJLyoKCQkJKiBUaGUgdHlwZSBkZWZpbml0aW9uILdyZXNvbHZlZLcgdG8gYnkgdGhlILdhY3R1YWwgCgkJCSogdmFsdWW3IG9mIHRoZSBiYXNlIFthdHRyaWJ1dGVdCgkJCSovCgkJCWN0eHQtPmN0eHRUeXBlLT5iYXNlVHlwZSA9IGJhc2U7CgkJCS8qCgkJCSogVE9ETzogVGhpcyBvbmUgaXMgc3RpbGwgbmVlZGVkIGZvciBjb21wdXRhdGlvbiBvZgoJCQkqIHRoZSBjb250ZW50IG1vZGVsIGJ5IHhtbFNjaGVtYUJ1aWxkQUNvbnRlbnRNb2RlbC4KCQkJKiBUcnkgdG8gZ2V0IHJpZCBvZiBpdC4KCQkJKi8KCQkJdHlwZURlY2wtPmJhc2VUeXBlID0gYmFzZTsJCQkKICAgICAgICAgICAgICAgICAgICB9CgkJICAgIGlmICgodHlwZURlY2wtPnN1YnR5cGVzICE9IE5VTEwpICYmCgkJCSh0eXBlRGVjbC0+c3VidHlwZXMtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9VTktOT1dOKSkKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZUZpeHVwKHR5cGVEZWNsLT5zdWJ0eXBlcywgY3R4dCwgTlVMTCk7CSAgICAKCQkgICAgCgkJICAgIGV4cGxpY2l0Q29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM7CgkJICAgIGlmICh0eXBlRGVjbC0+c3VidHlwZXMgPT0gTlVMTCkKCQkJLyogMS4xLjEgKi8KCQkJZXhwbGljaXRDb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWTsKCQkgICAgZWxzZSBpZiAoKHR5cGVEZWNsLT5zdWJ0eXBlcy0+c3VidHlwZXMgPT0gTlVMTCkgJiYKCQkJKCh0eXBlRGVjbC0+c3VidHlwZXMtPnR5cGUgPT0KCQkJWE1MX1NDSEVNQV9UWVBFX0FMTCkKCQkJfHwgKHR5cGVEZWNsLT5zdWJ0eXBlcy0+dHlwZSA9PQoJCQlYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0UpKSkKCQkJLyogMS4xLjIgKi8KCQkJZXhwbGljaXRDb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWTsKCQkgICAgZWxzZSBpZiAoKHR5cGVEZWNsLT5zdWJ0eXBlcy0+dHlwZSA9PQoJCQlYTUxfU0NIRU1BX1RZUEVfQ0hPSUNFKQoJCQkmJiAodHlwZURlY2wtPnN1YnR5cGVzLT5zdWJ0eXBlcyA9PSBOVUxMKSkKCQkJLyogMS4xLjMgKi8KCQkJZXhwbGljaXRDb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWTsKCQkgICAgaWYgKGJhc2UgIT0gTlVMTCkgewoJCQkvKiBJdCB3aWxsIGJlIHJlcG9ydGVkIGxhdGVyLCBpZiB0aGUgYmFzZSBpcyBtaXNzaW5nLiAqLwkJCSAgICAKCQkJaWYgKGV4cGxpY2l0Q29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZKSB7CgkJCSAgICAvKiAyLjEgKi8KCQkJICAgIHR5cGVEZWNsLT5jb250ZW50VHlwZSA9IGJhc2UtPmNvbnRlbnRUeXBlOwoJCQl9IGVsc2UgaWYgKGJhc2UtPmNvbnRlbnRUeXBlID09CgkJCSAgICBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFkpIHsKCQkJICAgIC8qIDIuMiBpbWJpdGFibGUgISAqLwoJCQkgICAgdHlwZURlY2wtPmNvbnRlbnRUeXBlID0KCQkJCVhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzsKCQkJfSBlbHNlIHsKCQkJICAgIC8qIDIuMyBpbWJpdGFibGUgcGFyZWlsICEgKi8KCQkJICAgIHR5cGVEZWNsLT5jb250ZW50VHlwZSA9CgkJCQlYTUxfU0NIRU1BX0NPTlRFTlRfRUxFTUVOVFM7CgkJCX0KCQkgICAgfQkJICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYOnsKCQkgICAgY3R4dFR5cGUgPSBjdHh0LT5jdHh0VHlwZTsKCQkgICAgY3R4dC0+Y3R4dFR5cGUgPSB0eXBlRGVjbDsKCQkgICAgaWYgKCh0eXBlRGVjbC0+c3VidHlwZXMgPT0gTlVMTCkgfHwgCgkJCSgodHlwZURlY2wtPnN1YnR5cGVzLT50eXBlICE9IAoJCQlYTUxfU0NIRU1BX1RZUEVfU0lNUExFX0NPTlRFTlQpICYmIAoJCQkodHlwZURlY2wtPnN1YnR5cGVzLT50eXBlICE9IAoJCQlYTUxfU0NIRU1BX1RZUEVfQ09NUExFWF9DT05URU5UKSkpIHsKCQkJLyogCgkJCSogVGhpcyBjYXNlIGlzIHVuZGVyc3Rvb2QgYXMgc2hvcnRoYW5kIGZvciBjb21wbGV4IAoJCQkqIGNvbnRlbnQgcmVzdHJpY3RpbmcgdGhlIHVyLXR5cGUgZGVmaW5pdGlvbiwgYW5kIAoJCQkqIHRoZSBkZXRhaWxzIG9mIHRoZSBtYXBwaW5ncyBzaG91bGQgYmUgbW9kaWZpZWQgYXMgCgkJCSogbmVjZXNzYXJ5LgoJCQkqLwkJCQoJCQl0eXBlRGVjbC0+YmFzZVR5cGUgPSB4bWxTY2hlbWFHZXRCdWlsdEluVHlwZShYTUxfU0NIRU1BU19BTllUWVBFKTsKCQkJdHlwZURlY2wtPmZsYWdzIHw9IAoJCQkgICAgWE1MX1NDSEVNQVNfVFlQRV9ERVJJVkFUSU9OX01FVEhPRF9SRVNUUklDVElPTjsKCQkgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICh0eXBlRGVjbC0+c3VidHlwZXMgPT0gTlVMTCkgewoJCQl0eXBlRGVjbC0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX01JWEVEKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZURlY2wtPmNvbnRlbnRUeXBlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQ7CQkJCiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKCQkJaWYgKCh0eXBlRGVjbC0+c3VidHlwZXMgIT0gTlVMTCkgJiYKCQkJICAgICh0eXBlRGVjbC0+c3VidHlwZXMtPmNvbnRlbnRUeXBlID09CgkJCSAgICBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTikpIHsJCQkgICAgCgkJCSAgICB4bWxTY2hlbWFUeXBlRml4dXAodHlwZURlY2wtPnN1YnR5cGVzLCBjdHh0LAoJCQkJTlVMTCk7CQkJICAgIAoJCQl9CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX01JWEVEKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+Y29udGVudFR5cGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsJCQkgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZURlY2wtPnN1YnR5cGVzICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+Y29udGVudFR5cGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+c3VidHlwZXMtPmNvbnRlbnRUeXBlOwoJCQkgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CQkJCiAgICAgICAgICAgICAgICAgICAgfQoJCSAgICB4bWxTY2hlbWFCdWlsZEF0dHJpYnV0ZVZhbGlkYXRpb24oY3R4dCwgdHlwZURlY2wpOwoJCSAgICBjdHh0LT5jdHh0VHlwZSA9IGN0eHRUeXBlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYX0NPTlRFTlQ6ewogICAgICAgICAgICAgICAgICAgIGlmICh0eXBlRGVjbC0+c3VidHlwZXMgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfRU1QVFk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlRGVjbC0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX01JWEVEKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZURlY2wtPmNvbnRlbnRUeXBlID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRUQ7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVEZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfTUlYRUQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVEZWNsLT5jb250ZW50VHlwZSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWE1MX1NDSEVNQV9DT05URU5UX01JWEVEOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZUZpeHVwKHR5cGVEZWNsLT5zdWJ0eXBlcywgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlRGVjbC0+c3VidHlwZXMgIT0gTlVMTCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+Y29udGVudFR5cGUgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlRGVjbC0+c3VidHlwZXMtPmNvbnRlbnRUeXBlOwogICAgICAgICAgICAgICAgICAgICAgICB9CgkJCS8qIAoJCQkgKiBSZW1vdmVkIGR1ZSB0byBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgYnVpbGQgb2YgYXR0cmlidXRlIHVzZXMuIAoJCQkgKi8KCQkJLyoKCQkJaWYgKHR5cGVEZWNsLT5hdHRyaWJ1dGVzID09IE5VTEwpCgkJCSAgICB0eXBlRGVjbC0+YXR0cmlidXRlcyA9CgkJCSAgICAgICAgdHlwZURlY2wtPnN1YnR5cGVzLT5hdHRyaWJ1dGVzOwoJCQkqLwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KCSAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEU6CgkJLyoKCQkqIFNpbXBsZSBUeXBlIERlZmluaXRpb24gU2NoZW1hIENvbXBvbmVudAoJCSoKCQkqLwoJCWN0eHRUeXBlID0gY3R4dC0+Y3R4dFR5cGU7CQkKCQl0eXBlRGVjbC0+Y29udGVudFR5cGUgPSBYTUxfU0NIRU1BX0NPTlRFTlRfU0lNUExFOwoJCWlmICh0eXBlRGVjbC0+c3VidHlwZXMtPmNvbnRlbnRUeXBlID09IAoJCSAgICBYTUxfU0NIRU1BX0NPTlRFTlRfVU5LTk9XTikgewoJCSAgICBjdHh0LT5jdHh0VHlwZSA9IHR5cGVEZWNsOwoJCSAgICB4bWxTY2hlbWFUeXBlRml4dXAodHlwZURlY2wtPnN1YnR5cGVzLCBjdHh0LCBOVUxMKTsKCQl9CgkJLyogRml4dXAgYmFzZSB0eXBlICovCQkKCQlpZiAoKHR5cGVEZWNsLT5iYXNlVHlwZSAhPSBOVUxMKSAmJiAKCQkgICAgKHR5cGVEZWNsLT5iYXNlVHlwZS0+Y29udGVudFR5cGUgPT0KCQkgICAgWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV04pKSB7CgkJICAgIC8qIE9QVElNSVpFOiBBY3R1YWxseSB0aGlzIG9uZSB3aWxsIG5ldmVyIGJ5IGhpdCwgc2luY2UKCQkgICAgKiB0aGUgYmFzZSB0eXBlIGlzIGFscmVhZHkgdHlwZS1maXhlZCBpbiA8cmVzdHJpY3Rpb24+LgoJCSAgICAqLwoJCSAgICBjdHh0LT5jdHh0VHlwZSA9IHR5cGVEZWNsOwoJCSAgICB4bWxTY2hlbWFUeXBlRml4dXAodHlwZURlY2wtPmJhc2VUeXBlLCBjdHh0LCBOVUxMKTsKCQl9CgkJLyogQmFzZSB0eXBlOiAKCQkqIDIgSWYgdGhlIDxsaXN0PiBvciA8dW5pb24+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwgCgkJKiB0aGVuIHRoZSC3c2ltcGxlIHVyLXR5cGUgZGVmaW5pdGlvbrcuCgkJKi8KCQlpZiAodHlwZURlY2wtPnN1YnR5cGVzLT50eXBlID09CgkJICAgIFhNTF9TQ0hFTUFfVFlQRV9MSVNUKSB7CgkJICAgIHR5cGVEZWNsLT5iYXNlVHlwZSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpOwoJCSAgICB0eXBlRGVjbC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1Q7CQkgICAgCgkJfSBlbHNlIGlmICh0eXBlRGVjbC0+c3VidHlwZXMtPnR5cGUgPT0KCQkgICAgWE1MX1NDSEVNQV9UWVBFX1VOSU9OKSB7CgkJICAgIHR5cGVEZWNsLT5iYXNlVHlwZSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpOwoJCSAgICB0eXBlRGVjbC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OOwoJCX0gZWxzZSBpZiAodHlwZURlY2wtPnN1YnR5cGVzLT50eXBlID09CgkJICAgIFhNTF9TQ0hFTUFfVFlQRV9SRVNUUklDVElPTikgewoJCSAgICB4bWxTY2hlbWFGYWNldExpbmtQdHIgZmFjZXQsIGN1ciwgbGFzdCA9IE5VTEw7CgkJICAgIAkJICAgIAkgICAgCQkgICAKCQkgICAgLyogCgkJICAgICogVmFyaWV0eQoJCSAgICAqIElmIHRoZSA8cmVzdHJpY3Rpb24+IGFsdGVybmF0aXZlIGlzIGNob3NlbiwgdGhlbiB0aGUgCgkJICAgICoge3ZhcmlldHl9IG9mIHRoZSB7YmFzZSB0eXBlIGRlZmluaXRpb259LgoJCSAgICAqLwkKCQkgICAgaWYgKHR5cGVEZWNsLT5iYXNlVHlwZSAhPSBOVUxMKSB7CgkJCWlmICh0eXBlRGVjbC0+YmFzZVR5cGUtPmZsYWdzICYgCgkJCSAgICBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfQVRPTUlDKQoJCQkgICAgdHlwZURlY2wtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9BVE9NSUM7CgkJCWVsc2UgaWYgKHR5cGVEZWNsLT5iYXNlVHlwZS0+ZmxhZ3MgJiAKCQkJICAgIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKQoJCQkgICAgdHlwZURlY2wtPmZsYWdzIHw9IFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUOwoJCQllbHNlIGlmICh0eXBlRGVjbC0+YmFzZVR5cGUtPmZsYWdzICYgCgkJCSAgICBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT04pCgkJCSAgICB0eXBlRGVjbC0+ZmxhZ3MgfD0gWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX1VOSU9OOwkJICAgIAkJICAgIAkJICAgCgkJCS8qCgkJCSogU2NoZW1hIENvbXBvbmVudCBDb25zdHJhaW50OiBTaW1wbGUgVHlwZSBSZXN0cmljdGlvbiAKCQkJKiAoRmFjZXRzKQoJCQkqIE5PVEU6IFNhdGlzZmFjdGlvbiBvZiAxIGFuZCAyIGFyaXNlIGZyb20gdGhlIGZpeHVwIAoJCQkqIGFwcGxpZWQgYmVmb3JlaGFuZC4KCQkJKgkJCSAgICAKCQkJKiAzIFRoZSB7ZmFjZXRzfSBvZiBSIGFyZSB0aGUgdW5pb24gb2YgUyBhbmQgdGhlIHtmYWNldHN9IAoJCQkqIG9mIEIsIGVsaW1pbmF0aW5nIGR1cGxpY2F0ZXMuIFRvIGVsaW1pbmF0ZSBkdXBsaWNhdGVzLCAKCQkJKiB3aGVuIGEgZmFjZXQgb2YgdGhlIHNhbWUga2luZCBvY2N1cnMgaW4gYm90aCBTIGFuZCB0aGUgCgkJCSoge2ZhY2V0c30gb2YgQiwgdGhlIG9uZSBpbiB0aGUge2ZhY2V0c30gb2YgQiBpcyBub3QgCgkJCSogaW5jbHVkZWQsIHdpdGggdGhlIGV4Y2VwdGlvbiBvZiBlbnVtZXJhdGlvbiBhbmQgcGF0dGVybiAKCQkJKiBmYWNldHMsIGZvciB3aGljaCBtdWx0aXBsZSBvY2N1cnJlbmNlcyB3aXRoIGRpc3RpbmN0IHZhbHVlcyAKCQkJKiBhcmUgYWxsb3dlZC4KCQkJKi8KCQkJaWYgKHR5cGVEZWNsLT5iYXNlVHlwZS0+ZmFjZXRTZXQgIT0gTlVMTCkgewoJCQkgICAgbGFzdCA9IHR5cGVEZWNsLT5mYWNldFNldDsKCQkJICAgIGlmIChsYXN0ICE9IE5VTEwpCgkJCQl3aGlsZSAobGFzdC0+bmV4dCAhPSBOVUxMKQoJCQkJICAgIGxhc3QgPSBsYXN0LT5uZXh0OwoJCQkJY3VyID0gdHlwZURlY2wtPmJhc2VUeXBlLT5mYWNldFNldDsKCQkJCWZvciAoOyBjdXIgIT0gTlVMTDsgY3VyID0gY3VyLT5uZXh0KSB7CgkJCQkgICAgLyogCgkJCQkgICAgKiBCYXNlIHBhdHRlcm5zIHdvbid0IGJlIGFkZCBoZXJlOgoJCQkJICAgICogdGhleSBhcmUgT1JlZCBpbiBhIHR5cGUgYW5kCgkJCQkgICAgKiBBTkRlZCBpbiBkZXJpdmVkIHR5cGVzLiBUaGlzIHdpbGwKCQkJCSAgICAqIGhhcHBlZCBhdCB2YWxpZGF0aW9uIGxldmVsIGJ5CgkJCQkgICAgKiB3YWxraW5nIHRoZSBiYXNlIGF4aXMgb2YgdGhlIHR5cGUuCgkJCQkgICAgKi8KCQkJCSAgICBpZiAoY3VyLT5mYWNldC0+dHlwZSA9PSAKCQkJCQlYTUxfU0NIRU1BX0ZBQ0VUX1BBVFRFUk4pIAoJCQkJCWNvbnRpbnVlOwoJCQkJICAgIGZhY2V0ID0gTlVMTDsKCQkJCSAgICBpZiAoKHR5cGVEZWNsLT5mYWNldFNldCAhPSBOVUxMKSAmJgoJCQkJCShjdXItPmZhY2V0LT50eXBlICE9IAoJCQkJCVhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTikgJiYKCQkJCQkoY3VyLT5mYWNldC0+dHlwZSAhPSAKCQkJCQlYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OKSkgewkJCQkKCQkJCQlmYWNldCA9IHR5cGVEZWNsLT5mYWNldFNldDsKCQkJCQlkbyB7CgkJCQkJICAgIGlmIChjdXItPmZhY2V0LT50eXBlID09IAoJCQkJCQlmYWNldC0+ZmFjZXQtPnR5cGUpIAoJCQkJCQlicmVhazsKCQkJCQkgICAgZmFjZXQgPSBmYWNldC0+bmV4dDsKCQkJCQl9IHdoaWxlIChmYWNldCAhPSBOVUxMKTsKCQkJCSAgICB9CgkJCQkgICAgaWYgKGZhY2V0ID09IE5VTEwpIHsKCQkJCQlmYWNldCA9ICh4bWxTY2hlbWFGYWNldExpbmtQdHIpIAoJCQkJCSAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUZhY2V0TGluaykpOwoJCQkJCWlmIChmYWNldCA9PSBOVUxMKSB7CgkJCQkJICAgIHhtbFNjaGVtYVBFcnJNZW1vcnkoY3R4dCwgCgkJCQkJCSJmaXhpbmcgc2ltcGxlVHlwZSIsIE5VTEwpOwoJCQkJCSAgICByZXR1cm47CgkJCQkJfQoJCQkJCWZhY2V0LT5mYWNldCA9IGN1ci0+ZmFjZXQ7CgkJCQkJZmFjZXQtPm5leHQgPSBOVUxMOwoJCQkJCWlmIChsYXN0ID09IE5VTEwpCgkJCQkJICAgIHR5cGVEZWNsLT5mYWNldFNldCA9IGZhY2V0OwkJICAgIAoJCQkJCWVsc2UgCgkJCQkJICAgIGxhc3QtPm5leHQgPSBmYWNldDsKCQkJCQlsYXN0ID0gZmFjZXQ7CQkJCQoJCQkJICAgIH0JCQkJICAgIAoJCQkJfQoJCQl9CgkJICAgIH0KCQl9CQoJCS8qCgkJKiBDaGVjayBjb25zdHJhaW50cy4KCQkqLwoJCXhtbFNjaGVtYUNoZWNrU1JDU2ltcGxlVHlwZShjdHh0LCB0eXBlRGVjbCk7CgkJY3R4dC0+Y3R4dFR5cGUgPSBjdHh0VHlwZTsKCQlicmVhazsKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfU0VRVUVOQ0U6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0dST1VQOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTEw6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NIT0lDRToKICAgICAgICAgICAgICAgIHR5cGVEZWNsLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9MSVNUOiAKCQl4bWxTY2hlbWFQYXJzZUxpc3RSZWZGaXh1cCh0eXBlRGVjbCwgY3R4dCk7CgkJdHlwZURlY2wtPmNvbnRlbnRUeXBlID0gWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRTsKCQlicmVhazsKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfVU5JT046CQkKCQl4bWxTY2hlbWFQYXJzZVVuaW9uUmVmQ2hlY2sodHlwZURlY2wsIGN0eHQpOwoJCXR5cGVEZWNsLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU7CgkJYnJlYWs7CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0JBU0lDOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTlk6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0ZBQ0VUOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9VUjoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRUxFTUVOVDoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQU5ZX0FUVFJJQlVURToKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfTk9UQVRJT046CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5JTkNMVVNJVkU6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5FWENMVVNJVkU6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhJTkNMVVNJVkU6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhFWENMVVNJVkU6CiAgICAgICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9UT1RBTERJR0lUUzoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0ZSQUNUSU9ORElHSVRTOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTjoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OOgogICAgICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRToKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0xFTkdUSDoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDoKICAgICAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSDoKICAgICAgICAgICAgICAgIHR5cGVEZWNsLT5jb250ZW50VHlwZSA9IFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU7CgkJaWYgKHR5cGVEZWNsLT5zdWJ0eXBlcyAhPSBOVUxMKQoJCSAgICB4bWxTY2hlbWFUeXBlRml4dXAodHlwZURlY2wtPnN1YnR5cGVzLCBjdHh0LCBOVUxMKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KI2lmZGVmIERFQlVHX1RZUEUKICAgIGlmICh0eXBlRGVjbC0+bm9kZSAhPSBOVUxMKSB7CiAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICJUeXBlIG9mICVzIDogJXM6JWQgOiIsIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVEZWNsLT5ub2RlLT5kb2MtPlVSTCwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sR2V0TGluZU5vKHR5cGVEZWNsLT5ub2RlKSk7CiAgICB9IGVsc2UgewogICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiVHlwZSBvZiAlcyA6IiwgbmFtZSk7CiAgICB9CiAgICBzd2l0Y2ggKHR5cGVEZWNsLT5jb250ZW50VHlwZSkgewogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRToKICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJzaW1wbGVcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzoKICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJlbGVtZW50c1xuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX1VOS05PV046CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAidW5rbm93biAhISFcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTVBUWToKICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICJlbXB0eVxuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9DT05URU5UX01JWEVEOgogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIm1peGVkXG4iKTsKICAgICAgICAgICAgYnJlYWs7CgkvKiBSZW1vdmVkLCBzaW5jZSBub3QgdXNlZC4gKi8KCS8qCiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfTUlYRURfT1JfRUxFTUVOVFM6CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAibWl4ZWQgb3IgZWxlbXNcbiIpOwogICAgICAgICAgICBicmVhazsKCSovCiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUM6CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LCAiYmFzaWNcbiIpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJub3QgcmVnaXN0ZXJlZCAhISFcbiIpOwogICAgICAgICAgICBicmVhazsKICAgIH0KI2VuZGlmCn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0ZhY2V0OgogKiBAZmFjZXQ6ICB0aGUgZmFjZXQKICogQHR5cGVEZWNsOiAgdGhlIHNjaGVtYSB0eXBlIGRlZmluaXRpb24KICogQGN0eHQ6ICB0aGUgc2NoZW1hIHBhcnNlciBjb250ZXh0IG9yIE5VTEwKICogQG5hbWU6IG5hbWUgb2YgdGhlIHR5cGUKICoKICogQ2hlY2tzIHRoZSBkZWZhdWx0IHZhbHVlcyB0eXBlcywgZXNwZWNpYWxseSBmb3IgZmFjZXRzIAogKgogKiBSZXR1cm5zIDAgaWYgb2theSBvciAtMSBpbiBjYWUgb2YgZXJyb3IKICovCmludAp4bWxTY2hlbWFDaGVja0ZhY2V0KHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0LAogICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZURlY2wsCiAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCBjb25zdCB4bWxDaGFyICogbmFtZSkKewogICAgc3RhdGljIHhtbFNjaGVtYVR5cGVQdHIgbm9uTmVnYXRpdmVJbnRlZ2VyVHlwZSA9IE5VTEw7CiAgICBpbnQgcmV0ID0gMDsKCiAgICBpZiAobm9uTmVnYXRpdmVJbnRlZ2VyVHlwZSA9PSBOVUxMKSB7CiAgICAgICAgbm9uTmVnYXRpdmVJbnRlZ2VyVHlwZSA9CiAgICAgICAgICAgIHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX05OSU5URUdFUik7CiAgICB9CiAgICBzd2l0Y2ggKGZhY2V0LT50eXBlKSB7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTklOQ0xVU0lWRToKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlORVhDTFVTSVZFOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhJTkNMVVNJVkU6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWEVYQ0xVU0lWRToKCWNhc2UgWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTjogewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIE9rYXkgd2UgbmVlZCB0byB2YWxpZGF0ZSB0aGUgdmFsdWUKICAgICAgICAgICAgICAgICAqIGF0IHRoYXQgcG9pbnQuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dDsKCQl4bWxTY2hlbWFUeXBlUHRyIGJhc2U7CgoJCS8qIDQuMy41LjUgQ29uc3RyYWludHMgb24gZW51bWVyYXRpb24gU2NoZW1hIENvbXBvbmVudHMKCQkqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogZW51bWVyYXRpb24gdmFsaWQgcmVzdHJpY3Rpb24KCQkqIEl0IGlzIGFuILdlcnJvcrcgaWYgYW55IG1lbWJlciBvZiB7dmFsdWV9IGlzIG5vdCBpbiB0aGUgCgkJKiC3dmFsdWUgc3BhY2W3IG9mIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0uIAoJCSoKCQkqIG1pbkluY2x1c2l2ZSwgbWF4SW5jbHVzaXZlLCBtaW5FeGNsdXNpdmUsIG1heEV4Y2x1c2l2ZToKCQkqIFRoZSB2YWx1ZSC3bXVzdLcgYmUgaW4gdGhlIAoJCSogt3ZhbHVlIHNwYWNltyBvZiB0aGUgt2Jhc2UgdHlwZbcuIAoJCSovCgkJLyoKCQkqIFRoaXMgZnVuY3Rpb24gaXMgaW50ZW5kZWQgdG8gZGVsaXZlciBhIGNvbXBpbGVkIHZhbHVlCgkJKiBvbiB0aGUgZmFjZXQuIEluIFhNTCBTY2hlbWFzIHRoZSB0eXBlIGhvbGRpbmcgYSBmYWNldCwgCgkJKiBjYW5ub3QgYmUgYSBidWlsdC1pbiB0eXBlLiBUaHVzIHRvIGVuc3VyZSB0aGF0IG90aGVyIEFQSQoJCSogY2FsbHMgKHJlbGF4bmcpIGRvIHdvcmssIGlmIHRoZSBnaXZlbiB0eXBlIGlzIGEgYnVpbHQtaW4gCgkJKiB0eXBlLCB3ZSB3aWxsIGFzc3VtZSB0aGF0IHRoZSBnaXZlbiBidWlsdC1pbiB0eXBlICppcwoJCSogYWxyZWFkeSogdGhlIGJhc2UgdHlwZS4JCQoJCSovCgkJaWYgKHR5cGVEZWNsLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgewoJCSAgICBiYXNlID0gdHlwZURlY2wtPmJhc2VUeXBlOwoJCSAgICBpZiAoYmFzZSA9PSBOVUxMKSB7CgkJCXhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZURlY2wtPm5vZGUsCgkJCSAgICBYTUxfU0NIRU1BU19FUlJfSU5URVJOQUwsCgkJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrRmFjZXQsICIKCQkJICAgICJ0aGUgdHlwZSBcIiVzXCIgaGFzIG5vIGJhc2UgdHlwZS5cbiIsCgkJCSAgICB0eXBlRGVjbC0+bmFtZSwgTlVMTCk7CgkJCXJldHVybiAoLTEpOwoJCSAgICB9CQkKCQl9IGVsc2UKCQkgICAgYmFzZSA9IHR5cGVEZWNsOwoJCS8qCgkJKiBUT0RPOiBUcnkgdG8gYXZvaWQgY3JlYXRpbmcgYSBuZXcgY29udGV4dC4KCQkqLwogICAgICAgICAgICAgICAgdmN0eHQgPSB4bWxTY2hlbWFOZXdWYWxpZEN0eHQoTlVMTCk7CiAgICAgICAgICAgICAgICBpZiAodmN0eHQgPT0gTlVMTCkgewoJCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIHR5cGVEZWNsLT5ub2RlLAoJCQlYTUxfU0NIRU1BU19FUlJfSU5URVJOQUwsCgkJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hQ2hlY2tGYWNldCwgIgoJCQkiY3JlYXRpbmcgYSBuZXcgdmFsaWRhdGlvbiBjb250ZXh0LlxuIiwKCQkJdHlwZURlY2wtPm5hbWUsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiAoLTEpOwkKCQl9CgkJdmN0eHQtPnR5cGUgPSBiYXNlOwoJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKHZjdHh0LCBmYWNldC0+dmFsdWUsIDAsIDEpOwoJCWZhY2V0LT52YWwgPSB2Y3R4dC0+dmFsdWU7CgkJdmN0eHQtPnZhbHVlID0gTlVMTDsJCQogICAgICAgICAgICAgICAgaWYgKHJldCA+IDApIHsKICAgICAgICAgICAgICAgICAgICAvKiBlcnJvciBjb2RlICovCiAgICAgICAgICAgICAgICAgICAgaWYgKGN0eHQgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQRXJyRXh0KGN0eHQsIGZhY2V0LT5ub2RlLAoJCQkgICAgWE1MX1NDSEVNQVBfSU5WQUxJRF9GQUNFVCwgCgkJCSAgICBOVUxMLCBOVUxMLCBOVUxMLAoJCQkgICAgIlR5cGUgXCIlc1wiOiB0aGUgdmFsdWUgXCIlc1wiIG9mIHRoZSAiCgkJCSAgICAiZmFjZXQgXCIlc1wiIGlzIGludmFsaWQuXG4iLAoJCQkgICAgbmFtZSwgZmFjZXQtPnZhbHVlLCAKCQkJICAgIEJBRF9DQVNUIHhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKGZhY2V0LT50eXBlKSwgCgkJCSAgICBOVUxMLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0ID0gLTE7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHJldCA8IDApIHsKCQkgICAgeG1sU2NoZW1hUEVyckV4dChjdHh0LCBmYWNldC0+bm9kZSwKCQkJWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCQlOVUxMLCBOVUxMLCBOVUxMLAoJCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYUNoZWNrRmFjZXQsICIKCQkJImZhaWxlZCB0byB2YWxpZGF0ZSB0aGUgdmFsdWUgXCIlc1wiIG5hbWUgb2YgdGhlICIKCQkJImZhY2V0IFwiJXNcIiBhZ2FpbnN0IHRoZSBiYXNlIHR5cGUgXCIlc1wiLlxuIiwKCQkJZmFjZXQtPnZhbHVlLCAKCQkJQkFEX0NBU1QgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoZmFjZXQtPnR5cGUpLAoJCQliYXNlLT5uYW1lLCBOVUxMLCBOVUxMKTsgCgkJICAgIHJldCA9IC0xOwoJCX0gICAgICAgICAgICAgICAgCQkJCQoJCXhtbFNjaGVtYUZyZWVWYWxpZEN0eHQodmN0eHQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCS8qCgkqIFJlbW92ZWQsIHNpbmNlIGFkZGVkIHRvIHRoZSBjYXNlIGFib3ZlLgoJKgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTjp7CiAgICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICAgKiBPa2F5IHdlIG5lZWQgdG8gdmFsaWRhdGUgdGhlIHZhbHVlCiAgICAgICAgICAgICAgICAgKiBhdCB0aGF0IHBvaW50LgogICAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciB2Y3R4dDsKICAgICAgICAgICAgICAgIGludCB0bXA7CgkJeG1sU2NoZW1hVHlwZVB0ciBiYXNlOwoKCQkqIDQuMy41LjUgQ29uc3RyYWludHMgb24gZW51bWVyYXRpb24gU2NoZW1hIENvbXBvbmVudHMKCQkqIFNjaGVtYSBDb21wb25lbnQgQ29uc3RyYWludDogZW51bWVyYXRpb24gdmFsaWQgcmVzdHJpY3Rpb24KCQkqIEl0IGlzIGFuILdlcnJvcrcgaWYgYW55IG1lbWJlciBvZiB7dmFsdWV9IGlzIG5vdCBpbiB0aGUgCgkJKiC3dmFsdWUgc3BhY2W3IG9mIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0uIAoJCSoKICAgICAgICAgICAgICAgIHZjdHh0ID0geG1sU2NoZW1hTmV3VmFsaWRDdHh0KE5VTEwpOwogICAgICAgICAgICAgICAgaWYgKHZjdHh0ID09IE5VTEwpCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgkJYmFzZSA9IHR5cGVEZWNsLT5iYXNlVHlwZTsKCQlpZiAoYmFzZSA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgdHlwZURlY2wtPm5vZGUsCgkJCVhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKCQkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFDaGVja0ZhY2V0LCAiCgkJCSJ0aGUgdHlwZSBcIiVzXCIgaGFzIG5vIGJhc2UgdHlwZS5cbiIsCgkJCXR5cGVEZWNsLT5uYW1lLCBOVUxMKTsKCQkgICAgcmV0dXJuICgtMSk7CgkJfQoJCXZjdHh0LT50eXBlID0gYmFzZTsKCQl0bXAgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSh2Y3R4dCwgZmFjZXQtPnZhbHVlLCAwLCAxKTsKICAgICAgICAgICAgICAgICogdG1wID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZSh2Y3R4dCwgdHlwZURlY2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY2V0LT52YWx1ZSk7CgkJKgogICAgICAgICAgICAgICAgaWYgKHRtcCAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGN0eHQgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGZhY2V0LT5ub2RlLAoJCQkgICAgWE1MX1NDSEVNQVBfSU5WQUxJRF9FTlVNLAoJCQkgICAgIlR5cGUgXCIlc1wiOiB0aGUgdmFsdWUgXCIlc1wiIG9mIHRoZSAiCgkJCSAgICAiZmFjZXQgXCJlbnVtZXJhdGlvblwiIGlzIGludmFsaWQuXG4iLAoJCQkgICAgbmFtZSwgZmFjZXQtPnZhbHVlKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgcmV0ID0gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFGcmVlVmFsaWRDdHh0KHZjdHh0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgkqLwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOOgogICAgICAgICAgICBmYWNldC0+cmVnZXhwID0geG1sUmVnZXhwQ29tcGlsZShmYWNldC0+dmFsdWUpOwogICAgICAgICAgICBpZiAoZmFjZXQtPnJlZ2V4cCA9PSBOVUxMKSB7CgkJeG1sU2NoZW1hUEVycihjdHh0LCB0eXBlRGVjbC0+bm9kZSwKCQkgICAgWE1MX1NDSEVNQVBfUkVHRVhQX0lOVkFMSUQsCgkJICAgICJUeXBlIFwiJXNcIjogdGhlIHZhbHVlIFwiJXNcIiBvZiB0aGUgIgoJCSAgICAiZmFjZXQgXCJwYXR0ZXJuXCIgaXMgaW52YWxpZC5cbiIsCgkJICAgIG5hbWUsIGZhY2V0LT52YWx1ZSk7CiAgICAgICAgICAgICAgICByZXQgPSAtMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfVE9UQUxESUdJVFM6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0ZSQUNUSU9ORElHSVRTOgogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWExFTkdUSDoKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlOTEVOR1RIOnsKICAgICAgICAgICAgICAgIGludCB0bXA7CgogICAgICAgICAgICAgICAgdG1wID0KICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGF0ZVByZWRlZmluZWRUeXBlKG5vbk5lZ2F0aXZlSW50ZWdlclR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYWNldC0+dmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZmFjZXQtPnZhbCk7CiAgICAgICAgICAgICAgICBpZiAodG1wICE9IDApIHsKICAgICAgICAgICAgICAgICAgICAvKiBlcnJvciBjb2RlICovCiAgICAgICAgICAgICAgICAgICAgaWYgKGN0eHQgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFQRXJyRXh0KGN0eHQsIGZhY2V0LT5ub2RlLAoJCQkgICAgWE1MX1NDSEVNQVBfSU5WQUxJRF9GQUNFVF9WQUxVRSwKCQkJICAgIE5VTEwsIE5VTEwsIE5VTEwsCgkJCSAgICAiVHlwZSBcIiVzXCI6IHRoZSB2YWx1ZSBcIiVzXCIgb2YgdGhlICIKCQkJICAgICJmYWNldCBcIiVzXCIgaXMgaW52YWxpZC5cbiIsCgkJCSAgICBuYW1lLCBmYWNldC0+dmFsdWUsIAoJCQkgICAgQkFEX0NBU1QgeG1sU2NoZW1hRmFjZXRUeXBlVG9TdHJpbmcoZmFjZXQtPnR5cGUpLAoJCQkgICAgTlVMTCwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldCA9IC0xOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRTp7CiAgICAgICAgICAgICAgICBpZiAoeG1sU3RyRXF1YWwoZmFjZXQtPnZhbHVlLCBCQURfQ0FTVCAicHJlc2VydmUiKSkgewogICAgICAgICAgICAgICAgICAgIGZhY2V0LT53aGl0ZXNwYWNlID0gWE1MX1NDSEVNQVNfRkFDRVRfUFJFU0VSVkU7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHhtbFN0ckVxdWFsKGZhY2V0LT52YWx1ZSwgQkFEX0NBU1QgInJlcGxhY2UiKSkgewogICAgICAgICAgICAgICAgICAgIGZhY2V0LT53aGl0ZXNwYWNlID0gWE1MX1NDSEVNQVNfRkFDRVRfUkVQTEFDRTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoeG1sU3RyRXF1YWwoZmFjZXQtPnZhbHVlLCBCQURfQ0FTVCAiY29sbGFwc2UiKSkgewogICAgICAgICAgICAgICAgICAgIGZhY2V0LT53aGl0ZXNwYWNlID0gWE1MX1NDSEVNQVNfRkFDRVRfQ09MTEFQU0U7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmIChjdHh0ICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBmYWNldC0+bm9kZSwKCQkJICAgIFhNTF9TQ0hFTUFQX0lOVkFMSURfV0hJVEVfU1BBQ0UsCgkJCSAgICAiVHlwZSBcIiVzXCI6IHRoZSB2YWx1ZSBcIiVzXCIgb2YgdGhlICIKCQkJICAgICJmYWNldCBcIndoaXRlU3BhY2VcIiBpcyBpbnZhbGlkLlxuIiwKCQkJICAgIG5hbWUsIGZhY2V0LT52YWx1ZSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHJldCA9IC0xOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0RlZmF1bHRzOgogKiBAdHlwZURlY2w6ICB0aGUgc2NoZW1hIHR5cGUgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICoKICogQ2hlY2tzIHRoZSBkZWZhdWx0IHZhbHVlcyB0eXBlcywgZXNwZWNpYWxseSBmb3IgZmFjZXRzIAogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQ2hlY2tEZWZhdWx0cyh4bWxTY2hlbWFUeXBlUHRyIHR5cGVEZWNsLAogICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgY29uc3QgeG1sQ2hhciAqIG5hbWUpCnsKICAgIGlmIChuYW1lID09IE5VTEwpCiAgICAgICAgbmFtZSA9IHR5cGVEZWNsLT5uYW1lOyAKICAgIC8qCiAgICAqIE5PVEU6IEl0IGlzIGludGVuZGVkIHRvIHVzZSB0aGUgZmFjZXRzIGxpc3QsIGluc3RlYWQKICAgICogb2YgZmFjZXRTZXQuCiAgICAqLwogICAgaWYgKHR5cGVEZWNsLT5mYWNldHMgIT0gTlVMTCkgewoJeG1sU2NoZW1hRmFjZXRQdHIgZmFjZXQgPSB0eXBlRGVjbC0+ZmFjZXRzOwoJCgl3aGlsZSAoZmFjZXQgIT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYUNoZWNrRmFjZXQoZmFjZXQsIHR5cGVEZWNsLCBjdHh0LCBuYW1lKTsKCSAgICBmYWNldCA9IGZhY2V0LT5uZXh0OwoJfQogICAgfSAgICAKfQoKLyoqCiAqIHhtbFNjaGVtYUF0dHJHcnBGaXh1cDoKICogQGF0dHJncnBEZWNsOiAgdGhlIHNjaGVtYSBhdHRyaWJ1dGUgZGVmaW5pdGlvbgogKiBAY3R4dDogIHRoZSBzY2hlbWEgcGFyc2VyIGNvbnRleHQKICogQG5hbWU6ICB0aGUgYXR0cmlidXRlIG5hbWUKICoKICogRml4ZXMgZmluaXNoIGRvaW5nIHRoZSBjb21wdXRhdGlvbnMgb24gdGhlIGF0dHJpYnV0ZXMgZGVmaW5pdGlvbnMKICovCnN0YXRpYyB2b2lkCnhtbFNjaGVtYUF0dHJHcnBGaXh1cCh4bWxTY2hlbWFBdHRyaWJ1dGVHcm91cFB0ciBhdHRyZ3JwLAogICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hUGFyc2VyQ3R4dFB0ciBjdHh0LCBjb25zdCB4bWxDaGFyICogbmFtZSkKewogICAgaWYgKG5hbWUgPT0gTlVMTCkKICAgICAgICBuYW1lID0gYXR0cmdycC0+bmFtZTsKICAgIGlmIChhdHRyZ3JwLT5hdHRyaWJ1dGVzICE9IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGF0dHJncnAtPnJlZiAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hQXR0cmlidXRlR3JvdXBQdHIgcmVmOwoKICAgICAgICByZWYgPSB4bWxTY2hlbWFHZXRBdHRyaWJ1dGVHcm91cChjdHh0LT5zY2hlbWEsIGF0dHJncnAtPnJlZiwgYXR0cmdycC0+cmVmTnMpOwogICAgICAgIGlmIChyZWYgPT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIGF0dHJncnAtPm5vZGUsCgkJWE1MX1NDSEVNQVBfU1JDX1JFU09MVkUsCgkJIkF0dHJpYnV0ZSBncm91cCBcIiVzXCI6IHRoZSBRTmFtZSBcIiVzXCIgb2YgdGhlIGF0dHJpYnV0ZSAiCgkJIlwicmVmXCIgZG9lcyBub3QgcmVzb2x2ZSB0byBhIHNjaGVtYSAiCgkJImNvbXBvbmVudC5cbiIsCgkJbmFtZSwgYXR0cmdycC0+cmVmKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICB4bWxTY2hlbWFBdHRyR3JwRml4dXAocmVmLCBjdHh0LCBOVUxMKTsKICAgICAgICBhdHRyZ3JwLT5hdHRyaWJ1dGVzID0gcmVmLT5hdHRyaWJ1dGVzOwoJYXR0cmdycC0+YXR0cmlidXRlV2lsZGNhcmQgPSByZWYtPmF0dHJpYnV0ZVdpbGRjYXJkOwogICAgfQogICAgLyogCiAgICAqIFJlbW92ZWQsIHNpbmNlIGEgZ2xvYmFsIGF0dHJpYnV0ZSBncm91cCBkb2VzIG5vdCBuZWVkIHRvIGhvbGQgYW55CiAgICAqIGF0dHJpYnV0ZXMgb3Igd2lsZGNhcmQgCiAgICAqLwogICAgLyoKICAgIGVsc2UgewogICAgICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgYXR0cmdycC0+bm9kZSwgWE1MX1NDSEVNQVBfTk9BVFRSX05PUkVGLAogICAgICAgICAgICAgICAgICAgICAgIlNjaGVtYXM6IGF0dHJpYnV0ZSBncm91cCAlcyBoYXMgbm8gYXR0cmlidXRlcyBub3IgcmVmZXJlbmNlXG4iLAogICAgICAgICAgICAgICAgICAgICAgbmFtZSwgTlVMTCk7CiAgICB9CiAgICAqLwp9CgovKioKICogeG1sU2NoZW1hQXR0ckZpeHVwOgogKiBAYXR0ckRlY2w6ICB0aGUgc2NoZW1hIGF0dHJpYnV0ZSBkZWZpbml0aW9uCiAqIEBjdHh0OiAgdGhlIHNjaGVtYSBwYXJzZXIgY29udGV4dAogKiBAbmFtZTogIHRoZSBhdHRyaWJ1dGUgbmFtZQogKgogKiBGaXhlcyBmaW5pc2ggZG9pbmcgdGhlIGNvbXB1dGF0aW9ucyBvbiB0aGUgYXR0cmlidXRlcyBkZWZpbml0aW9ucwogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hQXR0ckZpeHVwKHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyRGVjbCwKICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCwgY29uc3QgeG1sQ2hhciAqIG5hbWUpCnsKICAgIC8qCiAgICAqIFRoZSBzaW1wbGUgdHlwZSBkZWZpbml0aW9uIGNvcnJlc3BvbmRpbmcgdG8gdGhlIDxzaW1wbGVUeXBlPiBlbGVtZW50IAogICAgKiBpbmZvcm1hdGlvbiBpdGVtIGluIHRoZSBbY2hpbGRyZW5dLCBpZiBwcmVzZW50LCBvdGhlcndpc2UgdGhlIHNpbXBsZSAKICAgICogdHlwZSBkZWZpbml0aW9uILdyZXNvbHZlZLcgdG8gYnkgdGhlILdhY3R1YWwgdmFsdWW3IG9mIHRoZSB0eXBlIAogICAgKiBbYXR0cmlidXRlXSwgaWYgcHJlc2VudCwgb3RoZXJ3aXNlIHRoZSC3c2ltcGxlIHVyLXR5cGUgZGVmaW5pdGlvbrcuCiAgICAqLwogICAgaWYgKG5hbWUgPT0gTlVMTCkKICAgICAgICBuYW1lID0gYXR0ckRlY2wtPm5hbWU7CiAgICBpZiAoYXR0ckRlY2wtPnN1YnR5cGVzICE9IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGF0dHJEZWNsLT50eXBlTmFtZSAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwoKCXR5cGUgPSB4bWxTY2hlbWFHZXRUeXBlKGN0eHQtPnNjaGVtYSwgYXR0ckRlY2wtPnR5cGVOYW1lLAoJICAgIGF0dHJEZWNsLT50eXBlTnMpOwoJaWYgKHR5cGUgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVBFcnIoY3R4dCwgYXR0ckRlY2wtPm5vZGUsIAoJCVhNTF9TQ0hFTUFQX1NSQ19SRVNPTFZFLAoJCSJBdHRyaWJ1dGUgXCIlc1wiOiB0aGUgUU5hbWUgXCIlc1wiIG9mIHRoZSBhdHRyaWJ1dGUgIgoJCSJcInR5cGVcIiBkb2VzIG5vdCByZXNvbHZlIHRvIGEgc2NoZW1hICIKCQkiY29tcG9uZW50LlxuIiwKCQluYW1lLCBhdHRyRGVjbC0+dHlwZU5hbWUpOwoJfQogICAgICAgIGF0dHJEZWNsLT5zdWJ0eXBlcyA9IHR5cGU7CiAgICB9IGVsc2UgaWYgKGF0dHJEZWNsLT5yZWYgIT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciByZWY7CgoJcmVmID0geG1sU2NoZW1hR2V0QXR0cmlidXRlKGN0eHQtPnNjaGVtYSwgYXR0ckRlY2wtPnJlZiwgYXR0ckRlY2wtPnJlZk5zKTsKICAgICAgICBpZiAocmVmID09IE5VTEwpIHsKICAgICAgICAgICAgeG1sU2NoZW1hUEVycihjdHh0LCBhdHRyRGVjbC0+bm9kZSwgCgkJWE1MX1NDSEVNQVBfU1JDX1JFU09MVkUsCgkJIkF0dHJpYnV0ZSBcIiVzXCI6IHRoZSBRTmFtZSBcIiVzXCIgb2YgdGhlIGF0dHJpYnV0ZSAiCgkJIlwicmVmXCIgZG9lcyBub3QgcmVzb2x2ZSB0byBhIHNjaGVtYSAiCgkJImNvbXBvbmVudC5cbiIsCQkKCQluYW1lLCBhdHRyRGVjbC0+cmVmKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICB4bWxTY2hlbWFBdHRyRml4dXAocmVmLCBjdHh0LCBOVUxMKTsKICAgICAgICBhdHRyRGVjbC0+c3VidHlwZXMgPSByZWYtPnN1YnR5cGVzOwogICAgfSBlbHNlIHsKCWF0dHJEZWNsLT5zdWJ0eXBlcyA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVNJTVBMRVRZUEUpOyAgICAgICAgCiAgICB9Cn0KCi8qKgogKiB4bWxTY2hlbWFQYXJzZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICoKICogcGFyc2UgYSBzY2hlbWEgZGVmaW5pdGlvbiByZXNvdXJjZSBhbmQgYnVpbGQgYW4gaW50ZXJuYWwKICogWE1MIFNoZW1hIHN0cnV0dXJlIHdoaWNoIGNhbiBiZSB1c2VkIHRvIHZhbGlkYXRlIGluc3RhbmNlcy4KICogKldBUk5JTkcqIHRoaXMgaW50ZXJmYWNlIGlzIGhpZ2hseSBzdWJqZWN0IHRvIGNoYW5nZQogKgogKiBSZXR1cm5zIHRoZSBpbnRlcm5hbCBYTUwgU2NoZW1hIHN0cnVjdHVyZSBidWlsdCBmcm9tIHRoZSByZXNvdXJjZSBvcgogKiAgICAgICAgIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8KeG1sU2NoZW1hUHRyCnhtbFNjaGVtYVBhcnNlKHhtbFNjaGVtYVBhcnNlckN0eHRQdHIgY3R4dCkKewogICAgeG1sU2NoZW1hUHRyIHJldCA9IE5VTEw7CiAgICB4bWxEb2NQdHIgZG9jOwogICAgeG1sTm9kZVB0ciByb290OwogICAgaW50IG5iZXJyb3JzOwogICAgaW50IHByZXNlcnZlID0gMDsKCiAgICB4bWxTY2hlbWFJbml0VHlwZXMoKTsKCiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CgogICAgbmJlcnJvcnMgPSBjdHh0LT5uYmVycm9yczsKICAgIGN0eHQtPm5iZXJyb3JzID0gMDsKICAgIGN0eHQtPmNvdW50ZXIgPSAwOwogICAgY3R4dC0+Y29udGFpbmVyID0gTlVMTDsKCiAgICAvKgogICAgICogRmlyc3Qgc3RlcCBpcyB0byBwYXJzZSB0aGUgaW5wdXQgZG9jdW1lbnQgaW50byBhbiBET00vSW5mb3NldAogICAgICovCiAgICBpZiAoY3R4dC0+VVJMICE9IE5VTEwpIHsKICAgICAgICBkb2MgPSB4bWxSZWFkRmlsZSgoY29uc3QgY2hhciAqKSBjdHh0LT5VUkwsIE5VTEwsIAoJICAgICAgICAgICAgICAgICAgU0NIRU1BU19QQVJTRV9PUFRJT05TKTsKICAgICAgICBpZiAoZG9jID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIE5VTEwsCgkJCSAgWE1MX1NDSEVNQVBfRkFJTEVEX0xPQUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInhtbFNjaGVtYVBhcnNlOiBjb3VsZCBub3QgbG9hZCAlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5VUkwsIE5VTEwpOwogICAgICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgICAgIH0KICAgIH0gZWxzZSBpZiAoY3R4dC0+YnVmZmVyICE9IE5VTEwpIHsKICAgICAgICBkb2MgPSB4bWxSZWFkTWVtb3J5KGN0eHQtPmJ1ZmZlciwgY3R4dC0+c2l6ZSwgTlVMTCwgTlVMTCwKCSAgICAgICAgICAgICAgICAgICAgU0NIRU1BU19QQVJTRV9PUFRJT05TKTsKICAgICAgICBpZiAoZG9jID09IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFQRXJyKGN0eHQsIE5VTEwsCgkJCSAgWE1MX1NDSEVNQVBfRkFJTEVEX1BBUlNFLAogICAgICAgICAgICAgICAgICAgICAgICAgICJ4bWxTY2hlbWFQYXJzZTogY291bGQgbm90IHBhcnNlXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE5VTEwpOwogICAgICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgICAgIH0KICAgICAgICBkb2MtPlVSTCA9IHhtbFN0cmR1cChCQURfQ0FTVCAiaW5fbWVtb3J5X2J1ZmZlciIpOwogICAgICAgIGN0eHQtPlVSTCA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZGljdCwgQkFEX0NBU1QgImluX21lbW9yeV9idWZmZXIiLCAtMSk7CiAgICB9IGVsc2UgaWYgKGN0eHQtPmRvYyAhPSBOVUxMKSB7CiAgICAgICAgZG9jID0gY3R4dC0+ZG9jOwoJcHJlc2VydmUgPSAxOwogICAgfSBlbHNlIHsKCXhtbFNjaGVtYVBFcnIoY3R4dCwgTlVMTCwKCQkgICAgICBYTUxfU0NIRU1BUF9OT1RISU5HX1RPX1BBUlNFLAoJCSAgICAgICJ4bWxTY2hlbWFQYXJzZTogY291bGQgbm90IHBhcnNlXG4iLAoJCSAgICAgIE5VTEwsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CgogICAgLyoKICAgICAqIFRoZW4gZXh0cmFjdCB0aGUgcm9vdCBhbmQgU2NoZW1hIHBhcnNlIGl0CiAgICAgKi8KICAgIHJvb3QgPSB4bWxEb2NHZXRSb290RWxlbWVudChkb2MpOwogICAgaWYgKHJvb3QgPT0gTlVMTCkgewoJeG1sU2NoZW1hUEVycihjdHh0LCAoeG1sTm9kZVB0cikgZG9jLAoJCSAgICAgIFhNTF9TQ0hFTUFQX05PUk9PVCwKCQkgICAgICAic2NoZW1hcyBoYXMgbm8gcm9vdCIsIE5VTEwsIE5VTEwpOwoJaWYgKCFwcmVzZXJ2ZSkgewoJICAgIHhtbEZyZWVEb2MoZG9jKTsKCX0KICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQoKICAgIC8qCiAgICAgKiBSZW1vdmUgYWxsIHRoZSBibGFuayB0ZXh0IG5vZGVzCiAgICAgKi8KICAgIHhtbFNjaGVtYUNsZWFudXBEb2MoY3R4dCwgcm9vdCk7CgogICAgLyoKICAgICAqIFRoZW4gZG8gdGhlIHBhcnNpbmcgZm9yIGdvb2QKICAgICAqLwogICAgcmV0ID0geG1sU2NoZW1hUGFyc2VTY2hlbWEoY3R4dCwgcm9vdCk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICBpZiAoIXByZXNlcnZlKSB7CgkgICAgeG1sRnJlZURvYyhkb2MpOwoJfQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXQtPmRvYyA9IGRvYzsKICAgIHJldC0+cHJlc2VydmUgPSBwcmVzZXJ2ZTsKCiAgICAvKgogICAgICogVGhlbiBmaXggYWxsIHRoZSByZWZlcmVuY2VzLgogICAgICovCiAgICBjdHh0LT5zY2hlbWEgPSByZXQ7CiAgICB4bWxIYXNoU2NhbkZ1bGwocmV0LT5lbGVtRGVjbCwKICAgICAgICAgICAgICAgICAgICAoeG1sSGFzaFNjYW5uZXJGdWxsKSB4bWxTY2hlbWFSZWZGaXh1cENhbGxiYWNrLCBjdHh0KTsKCiAgICAvKgogICAgICogVGhlbiBmaXh1cCBhbGwgYXR0cmlidXRlcyBkZWNsYXJhdGlvbnMKICAgICAqLwogICAgeG1sSGFzaFNjYW4ocmV0LT5hdHRyRGVjbCwgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFBdHRyRml4dXAsIGN0eHQpOwoKICAgIC8qCiAgICAgKiBUaGVuIGZpeHVwIGFsbCBhdHRyaWJ1dGVzIGdyb3VwIGRlY2xhcmF0aW9ucwogICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPmF0dHJncnBEZWNsLCAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYUF0dHJHcnBGaXh1cCwKICAgICAgICAgICAgICAgIGN0eHQpOwoKICAgIC8qCiAgICAgKiBUaGVuIGZpeHVwIGFsbCB0eXBlcyBwcm9wZXJ0aWVzCiAgICAgKi8KICAgIGN0eHQtPmN0eHRUeXBlID0gTlVMTDsKICAgIGN0eHQtPnBhcmVudEl0ZW0gPSBOVUxMOwogICAgeG1sSGFzaFNjYW4ocmV0LT50eXBlRGVjbCwgKHhtbEhhc2hTY2FubmVyKSB4bWxTY2hlbWFUeXBlRml4dXAsIGN0eHQpOwoKICAgIC8qCiAgICAgKiBUaGVuIGJ1aWxkIHRoZSBjb250ZW50IG1vZGVsIGZvciBhbGwgZWxlbWVudHMKICAgICAqLwogICAgeG1sSGFzaFNjYW4ocmV0LT5lbGVtRGVjbCwKICAgICAgICAgICAgICAgICh4bWxIYXNoU2Nhbm5lcikgeG1sU2NoZW1hQnVpbGRDb250ZW50TW9kZWwsIGN0eHQpOwoKICAgIC8qCiAgICAgKiBUaGVuIGNoZWNrIHRoZSBkZWZhdWx0cyBwYXJ0IG9mIHRoZSB0eXBlIGxpa2UgZmFjZXRzIHZhbHVlcwogICAgICovCiAgICB4bWxIYXNoU2NhbihyZXQtPnR5cGVEZWNsLCAoeG1sSGFzaFNjYW5uZXIpIHhtbFNjaGVtYUNoZWNrRGVmYXVsdHMsCiAgICAgICAgICAgICAgICBjdHh0KTsKCiAgICBpZiAoY3R4dC0+bmJlcnJvcnMgIT0gMCkgewogICAgICAgIHhtbFNjaGVtYUZyZWUocmV0KTsKICAgICAgICByZXQgPSBOVUxMOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hU2V0UGFyc2VyRXJyb3JzOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZXJyOiAgdGhlIGVycm9yIGNhbGxiYWNrCiAqIEB3YXJuOiAgdGhlIHdhcm5pbmcgY2FsbGJhY2sKICogQGN0eDogIGNvbnRleHR1YWwgZGF0YSBmb3IgdGhlIGNhbGxiYWNrcwogKgogKiBTZXQgdGhlIGNhbGxiYWNrIGZ1bmN0aW9ucyB1c2VkIHRvIGhhbmRsZSBlcnJvcnMgZm9yIGEgdmFsaWRhdGlvbiBjb250ZXh0CiAqLwp2b2lkCnhtbFNjaGVtYVNldFBhcnNlckVycm9ycyh4bWxTY2hlbWFQYXJzZXJDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGl0eUVycm9yRnVuYyBlcnIsCiAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGl0eVdhcm5pbmdGdW5jIHdhcm4sIHZvaWQgKmN0eCkKewogICAgaWYgKGN0eHQgPT0gTlVMTCkKICAgICAgICByZXR1cm47CiAgICBjdHh0LT5lcnJvciA9IGVycjsKICAgIGN0eHQtPndhcm5pbmcgPSB3YXJuOwogICAgY3R4dC0+dXNlckRhdGEgPSBjdHg7Cn0KCi8qKgogKiB4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZzoKICogQHR5cGU6ICB0aGUgZmFjZXQgdHlwZQogKgogKiBDb252ZXJ0IHRoZSB4bWxTY2hlbWFUeXBlVHlwZSB0byBhIGNoYXIgc3RyaW5nLgogKgogKiBSZXR1cm5zIHRoZSBjaGFyIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgZmFjZXQgdHlwZSBpZiB0aGUKICogICAgIHR5cGUgaXMgYSBmYWNldCBhbmQgYW4gIkludGVybmFsIEVycm9yIiBzdHJpbmcgb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGNvbnN0IGNoYXIgKgp4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyh4bWxTY2hlbWFUeXBlVHlwZSB0eXBlKQp7CiAgICBzd2l0Y2ggKHR5cGUpIHsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTjoKICAgICAgICAgICAgcmV0dXJuICgicGF0dGVybiIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhFWENMVVNJVkU6CiAgICAgICAgICAgIHJldHVybiAoIm1heEV4Y2x1c2l2ZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhJTkNMVVNJVkU6CiAgICAgICAgICAgIHJldHVybiAoIm1heEluY2x1c2l2ZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5FWENMVVNJVkU6CiAgICAgICAgICAgIHJldHVybiAoIm1pbkV4Y2x1c2l2ZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5JTkNMVVNJVkU6CiAgICAgICAgICAgIHJldHVybiAoIm1pbkluY2x1c2l2ZSIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFOgogICAgICAgICAgICByZXR1cm4gKCJ3aGl0ZVNwYWNlIik7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OOgogICAgICAgICAgICByZXR1cm4gKCJlbnVtZXJhdGlvbiIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9MRU5HVEg6CiAgICAgICAgICAgIHJldHVybiAoImxlbmd0aCIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEg6CiAgICAgICAgICAgIHJldHVybiAoIm1heExlbmd0aCIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NSU5MRU5HVEg6CiAgICAgICAgICAgIHJldHVybiAoIm1pbkxlbmd0aCIpOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9UT1RBTERJR0lUUzoKICAgICAgICAgICAgcmV0dXJuICgidG90YWxEaWdpdHMiKTsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfRlJBQ1RJT05ESUdJVFM6CiAgICAgICAgICAgIHJldHVybiAoImZyYWN0aW9uRGlnaXRzIik7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gKCJJbnRlcm5hbCBFcnJvciIpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVGYWNldHNJbnRlcm5hbDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGJhc2U6ICB0aGUgYmFzZSB0eXBlCiAqIEBmYWNldHM6ICB0aGUgbGlzdCBvZiBmYWNldHMgdG8gY2hlY2sKICogQHZhbHVlOiAgdGhlIGxleGljYWwgcmVwciBvZiB0aGUgdmFsdWUgdG8gdmFsaWRhdGUKICogQHZhbDogIHRoZSBwcmVjb21wdXRlZCB2YWx1ZQogKiBAZmlyZUVycm9yczogIGlmIDAsIG9ubHkgaW50ZXJuYWwgZXJyb3JzIHdpbGwgYmUgZmlyZWQ7CiAqCQkgb3RoZXJ3aXNlIGFsbCBlcnJvcnMgd2lsbCBiZSBmaXJlZC4KICoKICogQ2hlY2sgYSB2YWx1ZSBhZ2FpbnN0IGFsbCBmYWNldCBjb25kaXRpb25zCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2UsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYUZhY2V0TGlua1B0ciBmYWNldHMsCgkJCWNvbnN0IHhtbENoYXIgKiB2YWx1ZSwgaW50IGZpcmVFcnJvcnMpCnsKICAgIGludCByZXQgPSAwOwogICAgaW50IHRtcCA9IDA7CiAgICB4bWxTY2hlbWFUeXBlVHlwZSB0eXBlOwogICAgeG1sU2NoZW1hRmFjZXRMaW5rUHRyIGZhY2V0TGluayA9IGZhY2V0czsKCiAgICB3aGlsZSAoZmFjZXRMaW5rICE9IE5VTEwpIHsKICAgICAgICB0eXBlID0gZmFjZXRMaW5rLT5mYWNldC0+dHlwZTsKICAgICAgICBpZiAodHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OKSB7CiAgICAgICAgICAgIHRtcCA9IDE7CgogICAgICAgICAgICB3aGlsZSAoZmFjZXRMaW5rICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIHRtcCA9CiAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRhdGVGYWNldChiYXNlLCBmYWNldExpbmstPmZhY2V0LCB2YWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eHQtPnZhbHVlKTsKICAgICAgICAgICAgICAgIGlmICh0bXAgPT0gMCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZmFjZXRMaW5rID0gZmFjZXRMaW5rLT5uZXh0OwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlCiAgICAgICAgICAgIHRtcCA9IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXQoYmFzZSwgZmFjZXRMaW5rLT5mYWNldCwgdmFsdWUsIAoJICAgIGN0eHQtPnZhbHVlKTsKCiAgICAgICAgaWYgKHRtcCAhPSAwKSB7CiAgICAgICAgICAgIHJldCA9IHRtcDsKICAgICAgICAgICAgaWYgKGZpcmVFcnJvcnMpIHsJCQoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgY3R4dC0+Y3VyLCB0bXAsCQkgICAgCgkJICAgICJUaGUgdmFsdWUgZmFpbGVkIHRvIHZhbGlkYXRlIGFnYWluc3QgdGhlIGZhY2V0IFwiJXNcIi5cbiIsCgkJICAgIChjb25zdCB4bWxDaGFyICopIHhtbFNjaGVtYUZhY2V0VHlwZVRvU3RyaW5nKHR5cGUpLCAKCQkgICAgTlVMTCk7CQkKCgkgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoZmFjZXRMaW5rICE9IE5VTEwpCiAgICAgICAgICAgIGZhY2V0TGluayA9IGZhY2V0TGluay0+bmV4dDsKICAgIH0KICAgIHJldHVybiAocmV0KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCVNpbXBsZSB0eXBlIHZhbGlkYXRpb24JCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiNpZiAwIC8qIE5vdCBjdXJyZW50bHkgdXNlZC4gKi8KLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVmFsdWVVbmlvbjoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHR5cGU6ICB0aGUgdHlwZSBkZWNsYXJhdGlvbgogKiBAdmFsdWU6ICB0aGUgdmFsdWUgdG8gdmFsaWRhdGUKICoKICogVmFsaWRhdGVzIGEgdmFsdWUgYWdhaW5zdCBhIHVuaW9uLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIHZhbHVlIGlzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVZhbHVlVW5pb24oeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlLCBjb25zdCB4bWxDaGFyICogdmFsdWUpCnsKICAgIGludCByZXQgPSAwOwogICAgY29uc3QgeG1sQ2hhciAqY3VyLCAqZW5kLCAqcHJlZml4LCAqbmNOYW1lOwogICAgeG1sQ2hhciAqdG1wOwogICAgeG1sU2NoZW1hVHlwZVB0ciBzdWJ0eXBlOwogICAgeG1sTnNQdHIgbnM7CiAgICBpbnQgbGVuOwogICAKCiAgICAvKiBQcm9jZXNzIHJlZmVyZW5jZWQgbWVtYmVyVHlwZXMuICovCiAgICBjdXIgPSB0eXBlLT5yZWY7CiAgICBkbyB7CiAgICAgICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQogICAgICAgICAgICBjdXIrKzsKICAgICAgICBlbmQgPSBjdXI7CiAgICAgICAgd2hpbGUgKCgqZW5kICE9IDApICYmICghKElTX0JMQU5LX0NIKCplbmQpKSkpCiAgICAgICAgICAgIGVuZCsrOwogICAgICAgIGlmIChlbmQgPT0gY3VyKQogICAgICAgICAgICBicmVhazsKICAgICAgICB0bXAgPSB4bWxTdHJuZHVwKGN1ciwgZW5kIC0gY3VyKTsKICAgICAgICAgbmNOYW1lID0geG1sU3BsaXRRTmFtZTModG1wLCAmbGVuKTsKICAgICAgICBpZiAobmNOYW1lICE9IE5VTEwpIHsKICAgICAgICAgICAgcHJlZml4ID0geG1sU3RybmR1cCh0bXAsIGxlbik7CiAgICAgICAgICAgIC8qIHByZWZpeCA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZG9jLT5kaWN0LCB0bXAsIGxlbik7ICovCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcHJlZml4ID0gTlVMTDsKICAgICAgICAgICAgbmNOYW1lID0gdG1wOwogICAgICAgIH0KICAgICAgICAvKiBXZSB3b24ndCBkbyBhZGRpdGlvbmFsIGNoZWNrcyBoZXJlLAoJICogc2luY2UgdGhleSBoYXZlIGJlZW4gcGVyZm9ybWVkIGR1cmluZyBwYXJzaW5nLiAqLwogICAgICAgIG5zID0geG1sU2VhcmNoTnModHlwZS0+bm9kZS0+ZG9jLCB0eXBlLT5ub2RlLCBwcmVmaXgpOwogICAgICAgIC8qIG5hbWVzcGFjZSA9IHhtbERpY3RMb29rdXAoY3R4dC0+ZG9jLT5kaWN0LCBucy0+aHJlZiwgLTEpOyAqLwogICAgICAgIHN1YnR5cGUgPSB4bWxTY2hlbWFHZXRUeXBlKGN0eHQtPnNjaGVtYSwgbmNOYW1lLCBucy0+aHJlZik7CglpZiAodG1wICE9IE5VTEwpCgkgICAgeG1sRnJlZSh0bXApOwoJaWYgKHByZWZpeCAhPSBOVUxMKQoJICAgIHhtbEZyZWUoKHZvaWQgKilwcmVmaXgpOwogICAgICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVmFsdWVJbnRlcm5hbChjdHh0LCBzdWJ0eXBlLCB2YWx1ZSwgMCk7CiAgICAgICAgaWYgKChyZXQgPT0gMCkgfHwgKHJldCA9PSAtMSkpIHsKICAgICAgICAgICAgcmV0dXJuIChyZXQpOwogICAgICAgIH0KICAgICAgICBjdXIgPSBlbmQ7CiAgICB9IHdoaWxlICgqY3VyICE9IDApOwoKICAgIGlmICh0eXBlLT5zdWJ0eXBlcyAhPSBOVUxMKSB7CiAgICAgICAgc3VidHlwZSA9IHR5cGUtPnN1YnR5cGVzOwogICAgICAgIGRvIHsKICAgICAgICAgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZUludGVybmFsKGN0eHQsIHN1YnR5cGUsIHZhbHVlLCAwKTsKICAgICAgICAgICAgaWYgKChyZXQgPT0gMCkgfHwgKHJldCA9PSAtMSkpIHsKICAgICAgICAgICAgICAgIHJldHVybiAocmV0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzdWJ0eXBlID0gc3VidHlwZS0+bmV4dDsKICAgICAgICB9IHdoaWxlIChzdWJ0eXBlICE9IE5VTEwpOwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQHR5cGU6ICB0aGUgdHlwZSBkZWNsYXJhdGlvbgogKiBAdmFsdWU6ICB0aGUgdmFsdWUgdG8gdmFsaWRhdGUKICoKICogVmFsaWRhdGUgYSB2YWx1ZSBhZ2FpbnN0IGEgc2ltcGxlIHR5cGUKICoKICogUmV0dXJucyAwIGlmIHRoZSB2YWx1ZSBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIGNvbnN0IHhtbENoYXIgKiB2YWx1ZSkKewogIHJldHVybiAoeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZUludGVybmFsKGN0eHQsIHR5cGUsIHZhbHVlLCAxKSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVZhbHVlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAdHlwZTogIHRoZSB0eXBlIGRlY2xhcmF0aW9uCiAqIEB2YWx1ZTogIHRoZSB2YWx1ZSB0byB2YWxpZGF0ZQogKiBAZmlyZUVycm9yczogIGlmIDAsIG9ubHkgaW50ZXJuYWwgZXJyb3JzIHdpbGwgYmUgZmlyZWQ7CiAqCQkgb3RoZXJ3aXNlIGFsbCBlcnJvcnMgd2lsbCBiZSBmaXJlZC4KICoKICogVmFsaWRhdGUgYSB2YWx1ZSBhZ2FpbnN0IGEgc2ltcGxlIHR5cGUKICoKICogUmV0dXJucyAwIGlmIHRoZSB2YWx1ZSBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZUludGVybmFsKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwKCQkJICAgICBjb25zdCB4bWxDaGFyICogdmFsdWUsCgkJCSAgICAgaW50IGZpcmVFcnJvcnMpCnsKICAgIGludCByZXQgPSAwOwoKICAgIC8qCiAgICAgKiBGaXJzdCBub3JtYWxpemUgdGhlIHZhbHVlIGFjY29yZGluZ2x5IHRvIFNjaGVtYSBEYXRhdHlwZQogICAgICogNC4zLjYgd2hpdGVTcGFjZSBkZWZpbml0aW9uIG9mIHRoZSB3aGl0ZVNwYWNlIGZhY2V0IG9mIHR5cGUKICAgICAqCiAgICAgKiBUaGVuIGNoZWNrIHRoZSBub3JtYWxpemVkIHZhbHVlIGFnYWluc3QgdGhlIGxleGljYWwgc3BhY2Ugb2YgdGhlCiAgICAgKiB0eXBlLgogICAgICovCiAgICBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpIHsKICAgICAgICBpZiAoY3R4dC0+dmFsdWUgIT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFGcmVlVmFsdWUoY3R4dC0+dmFsdWUpOwogICAgICAgICAgICBjdHh0LT52YWx1ZSA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIHJldCA9IHhtbFNjaGVtYVZhbFByZWRlZlR5cGVOb2RlKHR5cGUsIHZhbHVlLCAmKGN0eHQtPnZhbHVlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHh0LT5jdXIpOwogICAgICAgIGlmICgoZmlyZUVycm9ycykgJiYgKHJldCAhPSAwKSkgewogICAgICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGN0eHQtPmN1ciwgWE1MX1NDSEVNQVNfRVJSX1ZBTFVFLAoJICAgIAkJICAiRmFpbGVkIHRvIHZhbGlkYXRlIGJhc2ljIHR5cGUgJXNcbiIsCgkJCSAgdHlwZS0+bmFtZSwgTlVMTCk7CiAgICAgICAgfQogICAgfSBlbHNlIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9SRVNUUklDVElPTikgewogICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZTsKCiAgICAgICAgYmFzZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgICAgIGlmIChiYXNlICE9IE5VTEwpIHsKICAgICAgICAgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZUludGVybmFsKGN0eHQsIGJhc2UsCgkgICAgCQkJdmFsdWUsIGZpcmVFcnJvcnMpOwogICAgICAgIH0gZWxzZSBpZiAodHlwZS0+c3VidHlwZXMgIT0gTlVMTCkgewoJICAgIFRPRE8KICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogRG8gbm90IHZhbGlkYXRlIGZhY2V0cyBvciBhdHRyaWJ1dGVzIHdoZW4gd29ya2luZyBvbgoJICogYnVpbGRpbmcgdGhlIFNjaGVtYXMKICAgICAgICAgKi8KICAgICAgICBpZiAoY3R4dC0+c2NoZW1hICE9IE5VTEwpIHsKCSAgICB4bWxTY2hlbWFGYWNldExpbmtQdHIgZmFjZXRMaW5rOwoKICAgICAgICAgICAgaWYgKChyZXQgPT0gMCkgJiYgKHR5cGUtPmZhY2V0U2V0ICE9IE5VTEwpKSB7CiAgICAgICAgICAgICAgICBmYWNldExpbmsgPSB0eXBlLT5mYWNldFNldDsKICAgICAgICAgICAgICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWwoY3R4dCwgYmFzZSwgZmFjZXRMaW5rLAoJCQkJdmFsdWUsIGZpcmVFcnJvcnMpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSBlbHNlIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpIHsKICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2U7CgogICAgICAgIGJhc2UgPSB0eXBlLT5zdWJ0eXBlczsKICAgICAgICBpZiAoYmFzZSAhPSBOVUxMKSB7CiAgICAgICAgICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVmFsdWVJbnRlcm5hbChjdHh0LCBiYXNlLAoJICAgIAkJCXZhbHVlLCBmaXJlRXJyb3JzKTsKICAgICAgICB9IGVsc2UgewogICAgICAgIFRPRE99CiAgICB9IGVsc2UgaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0xJU1QpIHsKICAgICAgICB4bWxTY2hlbWFUeXBlUHRyIGJhc2U7CiAgICAgICAgY29uc3QgeG1sQ2hhciAqY3VyLCAqZW5kOwoJeG1sQ2hhciAqdG1wOwogICAgICAgIGludCByZXQyOwoKICAgICAgICBiYXNlID0gdHlwZS0+c3VidHlwZXM7CiAgICAgICAgaWYgKGJhc2UgPT0gTlVMTCkgewoJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgdHlwZS0+bm9kZSwgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCQkiSW50ZXJuYWw6IExpc3QgdHlwZSAlcyBoYXMgbm8gYmFzZSB0eXBlXG4iLAoJCQl0eXBlLT5uYW1lLCBOVUxMKTsKICAgICAgICAgICAgcmV0dXJuICgtMSk7CiAgICAgICAgfQogICAgICAgIGN1ciA9IHZhbHVlOwogICAgICAgIGRvIHsKICAgICAgICAgICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQogICAgICAgICAgICAgICAgY3VyKys7CiAgICAgICAgICAgIGVuZCA9IGN1cjsKICAgICAgICAgICAgd2hpbGUgKCgqZW5kICE9IDApICYmICghKElTX0JMQU5LX0NIKCplbmQpKSkpCiAgICAgICAgICAgICAgICBlbmQrKzsKICAgICAgICAgICAgaWYgKGVuZCA9PSBjdXIpCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgdG1wID0geG1sU3RybmR1cChjdXIsIGVuZCAtIGN1cik7CiAgICAgICAgICAgIHJldDIgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVZhbHVlSW50ZXJuYWwoY3R4dCwgYmFzZSwKCSAgICAJCQl0bXAsIGZpcmVFcnJvcnMpOwoJICAgIHhtbEZyZWUodG1wKTsKICAgICAgICAgICAgaWYgKHJldDIgIT0gMCkKICAgICAgICAgICAgICAgIHJldCA9IDE7CiAgICAgICAgICAgIGN1ciA9IGVuZDsKICAgICAgICB9IHdoaWxlICgqY3VyICE9IDApOwogICAgfSAgZWxzZSBpZiAodHlwZS0+dHlwZSA9PSBYTUxfU0NIRU1BX1RZUEVfVU5JT04pIHsKICAgICAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVZhbHVlVW5pb24oY3R4dCwgdHlwZSwgdmFsdWUpOwogICAgICAgIGlmICgoZmlyZUVycm9ycykgJiYgKHJldCAhPSAwKSkgewogICAgICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGN0eHQtPmN1ciwgWE1MX1NDSEVNQVNfRVJSX1ZBTFVFLAoJICAgIAkJICAiRmFpbGVkIHRvIHZhbGlkYXRlIHR5cGUgJXNcbiIsIHR5cGUtPm5hbWUsIE5VTEwpOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgVE9ETwogICAgfQogICAgcmV0dXJuIChyZXQpOwp9CiNlbmRpZgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAJCQkJCQkJCQkqCiAqIAkJCURPTSBWYWxpZGF0aW9uIGNvZGUJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgaW50IHhtbFNjaGVtYVZhbGlkYXRlQ29udGVudCh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKTsKc3RhdGljIGludCB4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgZWxlbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKTsKc3RhdGljIGludCB4bWxTY2hlbWFWYWxpZGF0ZVR5cGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbE5vZGVQdHIgZWxlbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKTsKCgovKioKICogeG1sU2NoZW1hRnJlZUF0dHJTdGF0ZXM6CiAqIEBzdGF0ZTogIGEgbGlzdCBvZiBhdHRyaWJ1dGUgc3RhdGVzCiAqCiAqIEZyZWUgdGhlIGdpdmVuIGxpc3Qgb2YgYXR0cmlidXRlIHN0YXRlcwogKgogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hRnJlZUF0dHJpYnV0ZVN0YXRlcyh4bWxTY2hlbWFBdHRyU3RhdGVQdHIgc3RhdGUpCnsKICAgIHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciB0bXA7CiAgICB3aGlsZSAoc3RhdGUgIT0gTlVMTCkgewoJdG1wID0gc3RhdGU7CglzdGF0ZSA9IHN0YXRlLT5uZXh0OwkKCXhtbEZyZWUodG1wKTsKICAgIH0KfQoKLyoqCiAqIHhtbFNjaGVtYVJlZ2lzdGVyQXR0cmlidXRlczoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGF0dHJzOiAgYSBsaXN0IG9mIGF0dHJpYnV0ZXMKICoKICogUmVnaXN0ZXIgdGhlIGxpc3Qgb2YgYXR0cmlidXRlcyBhcyB0aGUgc2V0IHRvIGJlIHZhbGlkYXRlZCBvbiB0aGF0IGVsZW1lbnQKICoKICogUmV0dXJucyAtMSBpbiBjYXNlIG9mIGVycm9yLCAwIG90aGVyd2lzZQogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFSZWdpc3RlckF0dHJpYnV0ZXMoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbEF0dHJQdHIgYXR0cnMpCnsKICAgIHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciB0bXA7CgogICAgY3R4dC0+YXR0ciA9IE5VTEw7CiAgICBjdHh0LT5hdHRyVG9wID0gTlVMTDsKICAgIHdoaWxlIChhdHRycyAhPSBOVUxMKSB7CiAgICAgICAgaWYgKChhdHRycy0+bnMgIT0gTlVMTCkgJiYKICAgICAgICAgICAgKHhtbFN0ckVxdWFsKGF0dHJzLT5ucy0+aHJlZiwgeG1sU2NoZW1hSW5zdGFuY2VOcykpKSB7CiAgICAgICAgICAgIGF0dHJzID0gYXR0cnMtPm5leHQ7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICAgICAgdG1wID0gKHhtbFNjaGVtYUF0dHJTdGF0ZVB0cikKCSAgICAgICB4bWxNYWxsb2Moc2l6ZW9mKHhtbFNjaGVtYUF0dHJTdGF0ZSkpOwogICAgICAgICAgICBpZiAodG1wID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZFcnJNZW1vcnkoY3R4dCwgInJlZ2lzdGVyaW5nIGF0dHJpYnV0ZXMiLCBOVUxMKTsKICAgICAgICAgICAgICAgIHJldHVybiAoLTEpOwogICAgICAgICAgICB9Cgl0bXAtPmF0dHIgPSBhdHRyczsKCXRtcC0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX1VOS05PV047Cgl0bXAtPm5leHQgPSBOVUxMOwoJaWYgKGN0eHQtPmF0dHIgPT0gTlVMTCkgCiAgICAgICAgICAgIGN0eHQtPmF0dHIgPSB0bXA7CgllbHNlCgkgICAgY3R4dC0+YXR0clRvcC0+bmV4dCA9IHRtcDsKCWN0eHQtPmF0dHJUb3AgPSB0bXA7CiAgICAgICAgYXR0cnMgPSBhdHRycy0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoMCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFDaGVja0F0dHJpYnV0ZXM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgdGhlIG5vZGUgY2FycnlpbmcgaXQuCiAqCiAqIENoZWNrIHRoYXQgdGhlIHJlZ2lzdGVyZWQgc2V0IG9mIGF0dHJpYnV0ZXMgb24gdGhlIGN1cnJlbnQgbm9kZQogKiBoYXMgYmVlbiBwcm9wZXJseSB2YWxpZGF0ZWQuCiAqCiAqIFJldHVybnMgMCBpZiB2YWxpZGl0eSBjb25zdHJhaW50cyBhcmUgbWV0LCAxIG90aGVyd2lzZS4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hQ2hlY2tBdHRyaWJ1dGVzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIGludCByZXQgPSAwOwogICAgeG1sU2NoZW1hQXR0clN0YXRlUHRyIGN1cjsgICAgCgogICAgY3VyID0gY3R4dC0+YXR0cjsKICAgIHdoaWxlICgoY3VyICE9IE5VTEwpICYmIChjdXIgIT0gY3R4dC0+YXR0clRvcC0+bmV4dCkpIHsKCWlmIChjdXItPnN0YXRlICE9IFhNTF9TQ0hFTUFTX0FUVFJfQ0hFQ0tFRCkgewkgICAgCSAgICAKICAgICAgICAgICAgcmV0ID0gMTsKCSAgICBpZiAoY3VyLT5zdGF0ZSA9PSBYTUxfU0NIRU1BU19BVFRSX1VOS05PV04pCiAgICAgICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX0FUVFJVTktOT1dOLAoJICAgIAkJICAiQXR0cmlidXRlIFwiJXNcIiBpcyBub3QgYWxsb3dlZC5cbiIsCgkJICAgIGN1ci0+YXR0ci0+bmFtZSwgTlVMTCk7CgkgICAgZWxzZSBpZiAoY3VyLT5zdGF0ZSA9PSBYTUxfU0NIRU1BU19BVFRSX1BST0hJQklURUQpCgkJLyoKCQkqIFRPRE86IFRoaXMgd29uJ3QgZXZlciBiZSB0b3VjaGVkIHNvIHJlbW92ZSBpdC4KCQkqLwoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX0FUVFJVTktOT1dOLAoJCSAgICAiQXR0cmlidXRlIFwiJXNcIiBpcyBwcm9oaWJpdGVkLlxuIiwKCQkgICAgY3VyLT5hdHRyLT5uYW1lLCBOVUxMKTsKCSAgICBlbHNlIGlmIChjdXItPnN0YXRlID09IFhNTF9TQ0hFTUFTX0FUVFJfSU5WQUxJRF9WQUxVRSkgewoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX0FUVFJJTlZBTElELAoJCSAgICAiQXR0cmlidXRlIFwiJXNcIjogdGhlIHZhbHVlIGlzIG5vdCB2YWxpZC5cbiIsCgkJICAgIGN1ci0+YXR0ci0+bmFtZSwgbm9kZS0+bmFtZSk7CgkgICAgfSBlbHNlIGlmIChjdXItPnN0YXRlID09IFhNTF9TQ0hFTUFTX0FUVFJfTUlTU0lORykgewoJCWlmIChjdXItPmRlY2wtPnJlZiAhPSBOVUxMKQoJCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9NSVNTSU5HLAoJCQkiQXR0cmlidXRlIFwiJXNcIiBpcyByZXF1aXJlZCBidXQgbWlzc2luZy5cbiIsIAoJCQljdXItPmRlY2wtPnJlZiwgTlVMTCk7CgkJZWxzZQoJCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9NSVNTSU5HLAoJCQkiQXR0cmlidXRlIFwiJXNcIiBpcyByZXF1aXJlZCBidXQgbWlzc2luZy5cbiIsIAoJCQljdXItPmRlY2wtPm5hbWUsIE5VTEwpOwogICAgICAgIH0KICAgIH0KCWN1ciA9IGN1ci0+bmV4dDsKICAgIH0KCiAgICByZXR1cm4gKHJldCk7Cn0KCiNpZiAwCQkvKiBOb3QgY3VycmVudGx5IHVzZWQgLSByZW1vdmUgaWYgZXZlciBuZWVkZWQgKi8KLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlQ29udGVudDoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVsZW06ICBhbiBlbGVtZW50CiAqIEB0eXBlOiAgdGhlIHR5cGUgZGVjbGFyYXRpb24KICoKICogVmFsaWRhdGUgdGhlIGNvbnRlbnQgb2YgYW4gZWxlbWVudCBleHBlY3RlZCB0byBiZSBhIHNpbXBsZSB0eXBlCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZUNvbnRlbnQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxOb2RlUHRyIG5vZGUgQVRUUklCVVRFX1VOVVNFRCkKewogICAgeG1sTm9kZVB0ciBjaGlsZDsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgYmFzZTsKICAgIHhtbENoYXIgKnZhbHVlOwogICAgaW50IHJldCA9IDA7CgogICAgY2hpbGQgPSBjdHh0LT5ub2RlOwogICAgdHlwZSA9IGN0eHQtPnR5cGU7CgogICAgLyoKICAgICAqIFZhbGlkYXRpb24gUnVsZTogRWxlbWVudCBMb2NhbGx5IFZhbGlkIChUeXBlKTogMy4xLjMKICAgICAqLwogICAgdmFsdWUgPSB4bWxOb2RlR2V0Q29udGVudChjaGlsZCk7CiAgICAvKiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVZhbHVlKGN0eHQsIHR5cGUsIHZhbHVlKTsgKi8KICAgIHN3aXRjaCAodHlwZS0+dHlwZSkgewogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1JFU1RSSUNUSU9OOnsKICAgICAgICAgICAgICAgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0OwoKICAgICAgICAgICAgICAgIGJhc2UgPSB0eXBlLT5iYXNlVHlwZTsKICAgICAgICAgICAgICAgIGlmIChiYXNlICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVZhbHVlKGN0eHQsIGJhc2UsIHZhbHVlKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBUT0RPfQogICAgICAgICAgICAgICAgaWYgKHJldCA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgZmFjZXQgPSB0eXBlLT5mYWNldHM7CiAgICAgICAgICAgICAgICAgICAgcmV0ID0KICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRhdGVGYWNldHMoY3R4dCwgYmFzZSwgZmFjZXQsIHZhbHVlKTsKICAgICAgICAgICAgICAgIH0KCQkvKiAKCQkgKiBUaGlzIHNob3VsZCBhdHRlbXB0IHRvIHZhbGlkYXRlIHRoZSBhdHRyaWJ1dGVzIGV2ZW4KCQkgKiB3aGVuIHZhbGlkYXRpb24gb2YgdGhlIHZhbHVlIGZhaWxlZC4KCQkgKi8KCQkvKgoJCWlmICh0eXBlLT5hdHRyaWJ1dGVzICE9IE5VTEwpIHsKCQkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVBdHRyaWJ1dGVzKGN0eHQsIG5vZGUsCgkJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLT5hdHRyaWJ1dGVzKTsKCQl9CgkJKi8KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRVhURU5TSU9OOnsKCSAgICAgICAgVE9ETwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICBkZWZhdWx0OgoJICAgIFRPRE8KICAgIH0KICAgIGlmICh2YWx1ZSAhPSBOVUxMKQogICAgICAgIHhtbEZyZWUodmFsdWUpOwoKICAgIHJldHVybiAocmV0KTsKfQojZW5kaWYKCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUNoZWNrTm9kZUxpc3QKICogQG5vZGVsaXN0OiB0aGUgbGlzdCBvZiBub2RlcwogKgogKiBDaGVjayB0aGUgbm9kZSBsaXN0IGlzIG9ubHkgbWFkZSBvZiB0ZXh0IG5vZGVzIGFuZCBlbnRpdGllcyBwb2ludGluZwogKiB0byB0ZXh0IG5vZGVzCiAqCiAqIFJldHVybnMgMSBpZiB0cnVlLCAwIGlmIGZhbHNlIGFuZCAtMSBpbiBjYXNlIG9mIGVycm9yCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlQ2hlY2tOb2RlTGlzdCh4bWxOb2RlUHRyIG5vZGVsaXN0KQp7CiAgICB3aGlsZSAobm9kZWxpc3QgIT0gTlVMTCkgewogICAgICAgIGlmIChub2RlbGlzdC0+dHlwZSA9PSBYTUxfRU5USVRZX1JFRl9OT0RFKSB7CiAgICAgICAgICAgIFRPRE8gICAgICAgICAgICAgICAgLyogaW1wbGVtZW50IHJlY3Vyc2lvbiBpbiB0aGUgZW50aXR5IGNvbnRlbnQgKi8KICAgICAgICB9CiAgICAgICAgaWYgKChub2RlbGlzdC0+dHlwZSAhPSBYTUxfVEVYVF9OT0RFKSAmJgogICAgICAgICAgICAobm9kZWxpc3QtPnR5cGUgIT0gWE1MX0NPTU1FTlRfTk9ERSkgJiYKICAgICAgICAgICAgKG5vZGVsaXN0LT50eXBlICE9IFhNTF9QSV9OT0RFKSAmJgogICAgICAgICAgICAobm9kZWxpc3QtPnR5cGUgIT0gWE1MX0NEQVRBX1NFQ1RJT05fTk9ERSkpIHsKICAgICAgICAgICAgcmV0dXJuICgwKTsKICAgICAgICB9CiAgICAgICAgbm9kZWxpc3QgPSBub2RlbGlzdC0+bmV4dDsKICAgIH0KICAgIHJldHVybiAoMSk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUNhbGxiYWNrOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbmFtZTogIHRoZSBuYW1lIG9mIHRoZSBlbGVtZW50IGRldGVjdGVkIChtaWdodCBiZSBOVUxMKQogKiBAdHlwZTogIHRoZSB0eXBlCiAqCiAqIEEgdHJhbnNpdGlvbiBoYXMgYmVlbiBtYWRlIGluIHRoZSBhdXRvbWF0YSBhc3NvY2lhdGVkIHRvIGFuIGVsZW1lbnQKICogY29udGVudCBtb2RlbAogKi8Kc3RhdGljIHZvaWQKeG1sU2NoZW1hVmFsaWRhdGVDYWxsYmFjayh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB4bWxDaGFyICogbmFtZSBBVFRSSUJVVEVfVU5VU0VELAogICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxTY2hlbWFUeXBlUHRyIG9sZHR5cGUgPSBjdHh0LT50eXBlOwogICAgeG1sTm9kZVB0ciBvbGRub2RlID0gY3R4dC0+bm9kZTsKCiNpZmRlZiBERUJVR19DT05URU5UCiAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAieG1sU2NoZW1hVmFsaWRhdGVDYWxsYmFjazogJXMsICVzLCAlc1xuIiwKICAgICAgICAgICAgICAgICAgICBuYW1lLCB0eXBlLT5uYW1lLCBub2RlLT5uYW1lKTsKI2VuZGlmCiAgICBjdHh0LT50eXBlID0gdHlwZTsKICAgIGN0eHQtPm5vZGUgPSBub2RlOwogICAgeG1sU2NoZW1hVmFsaWRhdGVDb250ZW50KGN0eHQsIG5vZGUpOwogICAgY3R4dC0+dHlwZSA9IG9sZHR5cGU7CiAgICBjdHh0LT5ub2RlID0gb2xkbm9kZTsKfQoKCiNpZiAwCgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVSZXN0cmljdGlvblR5cGU6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBub2RlOiAgdGhlIHRvcCBub2RlLgogKgogKiBWYWxpZGF0ZSB0aGUgY29udGVudCBvZiBhIHJlc3RyaWN0aW9uIHR5cGUuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVJlc3RyaWN0aW9uVHlwZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxOb2RlUHRyIGNoaWxkOwogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwogICAgaW50IHJldDsKCiAgICBjaGlsZCA9IGN0eHQtPm5vZGU7CiAgICB0eXBlID0gY3R4dC0+dHlwZTsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHR5cGUgPT0gTlVMTCkpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKCQkgICAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlUmVzdHJpY3Rpb25UeXBlICVzXG4iLAoJCSAgICAgIG5vZGUtPm5hbWUsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQogICAgLyoKICAgICAqIE9ubHkgdGV4dCBhbmQgdGV4dCBiYXNlZCBlbnRpdGllcyByZWZlcmVuY2VzIHNoYWxsIGJlIGZvdW5kIHRoZXJlCiAgICAgKi8KICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlQ2hlY2tOb2RlTGlzdChjaGlsZCk7CiAgICBpZiAocmV0IDwgMCkgewogICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCSAgICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVSZXN0cmljdGlvblR5cGUgJXMgY29udGVudFxuIiwKCQkgICAgICBub2RlLT5uYW1lLCBOVUxMKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0gZWxzZSBpZiAocmV0ID09IDApIHsKICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9OT1RTSU1QTEUsCgkJICAgICAgIkVsZW1lbnQgJXMgY29udGVudCBpcyBub3QgYSBzaW1wbGUgdHlwZVxuIiwKCQkgICAgICBub2RlLT5uYW1lLCBOVUxMKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KICAgIGN0eHQtPnR5cGUgPSB0eXBlLT5zdWJ0eXBlczsKICAgIHhtbFNjaGVtYVZhbGlkYXRlQ29udGVudChjdHh0LCBub2RlKTsKICAgIGN0eHQtPnR5cGUgPSB0eXBlOwogICAgcmV0dXJuIChyZXQpOwp9CiNlbmRpZgoKI2lmIDAgLyogTm90IHVzZWQgYW55IG1vcmUgKi8KLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICB0aGUgdG9wIG5vZGUuCiAqCiAqIFZhbGlkYXRlIHRoZSBjb250ZW50IG9mIGFuIHNpbXBsZSB0eXBlLgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbE5vZGVQdHIgY2hpbGQ7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGUsIGJhc2UsIHZhcmlldHk7CiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICBpbnQgcmV0OwogICAgeG1sQ2hhciAqdmFsdWU7CiAgICAKCiAgICBjaGlsZCA9IGN0eHQtPm5vZGU7CiAgICB0eXBlID0gY3R4dC0+dHlwZTsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHR5cGUgPT0gTlVMTCkpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKCQkgICAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZSAlc1xuIiwKCQkgICAgICBub2RlLT5uYW1lLCBOVUxMKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KICAgIC8qCiAgICAgKiBPbmx5IHRleHQgYW5kIHRleHQgYmFzZWQgZW50aXRpZXMgcmVmZXJlbmNlcyBzaGFsbCBiZSBmb3VuZCB0aGVyZQogICAgICovCiAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUNoZWNrTm9kZUxpc3QoY2hpbGQpOwogICAgaWYgKHJldCA8IDApIHsKICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKCQkgICAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZSAlcyBjb250ZW50XG4iLAoJCSAgICAgIG5vZGUtPm5hbWUsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfSBlbHNlIGlmIChyZXQgPT0gMCkgewogICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX05PVFNJTVBMRSwKCQkgICAgICAiRWxlbWVudCAlcyBjb250ZW50IGlzIG5vdCBhIHNpbXBsZSB0eXBlXG4iLAoJCSAgICAgIG5vZGUtPm5hbWUsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQogICAgLyoKICAgICAqIFZhbGlkYXRpb24gUnVsZTogRWxlbWVudCBMb2NhbGx5IFZhbGlkIChUeXBlKTogMy4xLjEKICAgICAqLyAgICAKICAgIAogICAgYXR0ciA9IG5vZGUtPnByb3BlcnRpZXM7CiAgICB3aGlsZSAoYXR0ciAhPSBOVUxMKSB7CiAgICAgICAgaWYgKChhdHRyLT5ucyA9PSBOVUxMKSB8fAogICAgICAgICAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5zLT5ocmVmLCB4bWxTY2hlbWFJbnN0YW5jZU5zKSkgfHwKICAgICAgICAgICAgKCgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgInR5cGUiKSkgJiYKICAgICAgICAgICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bmFtZSwgQkFEX0NBU1QgIm5pbCIpKSAmJgogICAgICAgICAgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAic2NoZW1hc0xvY2F0aW9uIikpICYmCiAgICAgICAgICAgICAoIXhtbFN0ckVxdWFsCiAgICAgICAgICAgICAgKGF0dHItPm5hbWUsIEJBRF9DQVNUICJub05hbWVzcGFjZVNjaGVtYUxvY2F0aW9uIikpKSkgewogICAgICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9JTlZBTElEQVRUUiwKCSAgICAJCSAgIkVsZW1lbnQgJXM6IGF0dHJpYnV0ZSAlcyBzaG91bGQgbm90IGJlIHByZXNlbnRcbiIsCgkJCSAgbm9kZS0+bmFtZSwgYXR0ci0+bmFtZSk7CiAgICAgICAgICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKICAgICAgICB9CiAgICB9CiAgICAvKiBUT0RPOgogICAgICogSWYge3ZhcmlldHl9IGlzILdhdG9taWO3IHRoZW4gdGhlIHt2YXJpZXR5fSBvZiB7YmFzZSB0eXBlIGRlZmluaXRpb259CiAgICAgKiBtdXN0IGJlILdhdG9taWO3LiAKICAgICAqIElmIHt2YXJpZXR5fSBpcyC3bGlzdLcgdGhlbiB0aGUge3ZhcmlldHl9IG9mIHtpdGVtIHR5cGUgZGVmaW5pdGlvbn0KICAgICAqIG11c3QgYmUgZWl0aGVyILdhdG9taWO3IG9yILd1bmlvbrcuIAogICAgICogSWYge3ZhcmlldHl9IGlzILd1bmlvbrcgdGhlbiB7bWVtYmVyIHR5cGUgZGVmaW5pdGlvbnN9IG11c3QgYmUgYSBsaXN0CiAgICAgKiBvZiBkYXRhdHlwZSBkZWZpbml0aW9ucy4gCiAgICAgKi8KICAgIGlmICh0eXBlLT5zdWJ0eXBlcyA9PSBOVUxMKSB7Cgl4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKCQkgICAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZTsgIgoJCSAgICAgICJzaW1wbGUgdHlwZSAlcyBkb2VzIG5vdCBkZWZpbmUgYSB2YXJpZXR5XG4iLAoJCSAgICAgIG5vZGUtPm5hbWUsIE5VTEwpOwoJcmV0dXJuIChjdHh0LT5lcnIpOwogICAgfQogICAgLyogVmFyaWV0aWVzOiBSZXN0cmljdGlvbiBvciBMaXN0IG9yIFVuaW9uLiAqLwogICAgdmFyaWV0eSA9IHR5cGUtPnN1YnR5cGVzOwogICAgY3R4dC0+dHlwZSA9IHZhcmlldHk7ICAgICAgICAKICAgIHZhbHVlID0geG1sTm9kZUdldENvbnRlbnQoY2hpbGQpOwogICAgc3dpdGNoICh2YXJpZXR5LT50eXBlKSB7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfUkVTVFJJQ1RJT046ewogICAgICAgICAgICAgICAgYmFzZSA9IHZhcmlldHktPmJhc2VUeXBlOwogICAgICAgICAgICAgICAgaWYgKGJhc2UgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVmFsdWUoY3R4dCwgYmFzZSwgdmFsdWUpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIFRPRE99CQkgCiAgICAgICAgICAgICAgICAKCQkvKiBSZW1vdmVkIGR1ZSB0byBjaGFuZ2VzIG9mIGF0dHJpYnV0ZSB2YWxpZGF0aW9uOgoJCWlmICgocmV0ID09IDApICYmICh2YXJpZXR5LT5hdHRyaWJ1dGVzICE9IE5VTEwpKSB7CgkJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlQXR0cmlidXRlcyhjdHh0LCBub2RlLAoJCSAgICAJCXZhcmlldHktPmF0dHJpYnV0ZXMpOwoJCX0KCQkqLwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9MSVNUOgoJY2FzZSBYTUxfU0NIRU1BX1RZUEVfVU5JT046IHsKCSAgICAgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVWYWx1ZShjdHh0LCB2YXJpZXR5LCB2YWx1ZSk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGRlZmF1bHQ6ewoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCQkgICAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZTsgIgoJCQkgICAgICAic2ltcGxlIHR5cGUgJXMgZGVmaW5lcyB1bmtub3duIGNvbnRlbnQ6ICVzXG4iLAoJCQkgICAgICB2YXJpZXR5LT5uYW1lLCBOVUxMKTsKCQlyZXQgPSBjdHh0LT5lcnI7CgkgICAgfQogICAgfQogICAgaWYgKChyZXQgPT0gMCkgJiYgKHZhcmlldHktPmZhY2V0U2V0ICE9IE5VTEwpKSB7CglyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0cyhjdHh0LCBiYXNlLCB2YXJpZXR5LT5mYWNldFNldCwgdmFsdWUpOwogICAgfQogICAgaWYgKHZhbHVlICE9IE5VTEwpCiAgICAgICAgeG1sRnJlZSh2YWx1ZSk7CgogICAgLyogVGhpcyB3YXMgcmVtb3ZlZCwgc2luY2UgYSBzaW1wbGUgY29udGVudCBpcyBub3QgYSBjb250ZW50IG9mIGEKICAgICAqIHNpbXBsZSB0eXBlLCBidXQgb2YgYSBjb21wbGV4IHR5cGUuCiAgICAgKiByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZUNvbnRlbnQoY3R4dCwgbm9kZSk7CiAgICAgKi8KICAgIGN0eHQtPnR5cGUgPSB0eXBlOwogICAgcmV0dXJuIChyZXQpOwp9CiNlbmRpZgoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAdmFsdWU6IHRoZSB2YWx1ZSB0byBiZSB2YWxpZGF0ZWQKICogQGZpcmVFcnJvcnM6IHNoYWxsIGVycm9ycyBiZSByZXBvcnRlZD8KICogQGFwcGx5RmFjZXRzOiBzaGFsbCBmYWNldHMgYmUgYXBwbGllZD8KICoKICogVmFsaWRhdGVzIGEgdmFsdWUgYnkgdGhlIGdpdmVuIHR5cGUgKHVzZXIgZGVyaXZlZCBvciBidWlsdC1pbikuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgdmFsdWUgaXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGFuIGludGVybmFsIG9yIEFQSSBlcnJvci4KICogTm90ZSBvbiByZXBvcnRlZCBlcnJvcnM6IEFsdGhvdWdoIGl0IG1pZ2h0IGJlIG5pY2UgdG8gcmVwb3J0CiAqIHRoZSBuYW1lIG9mIHRoZSBzaW1wbGUvY29tcGxleCB0eXBlLCB1c2VkIHRvIHZhbGlkYXRlIHRoZSBjb250ZW50CiAqIG9mIGEgbm9kZSwgaXQgaXMgcXVpdGUgdW5uZWNlc3Nhcnk6IGZvciBnbG9iYWwgZGVmaW5lZCB0eXBlcwogKiB0aGUgbG9jYWwgbmFtZSBvZiB0aGUgZWxlbWVudCBpcyBlcXVhbCB0byB0aGUgTkNOYW1lIG9mIHRoZSB0eXBlLAogKiBmb3IgbG9jYWwgZGVmaW5lZCB0eXBlcyBpdCBtYWtlcyBubyBzZW5zZSB0byBvdXRwdXQgdGhlIGludGVybmFsCiAqIGNvbXB1dGVkIG5hbWUgb2YgdGhlIHR5cGUuIFRPRE86IEluc3RlYWQsIG9uZSBzaG91bGQgYXR0YWNoIHRoZSAKICogc3RydWN0IG9mIHRoZSB0eXBlIGludm9sdmVkIHRvIHRoZSBlcnJvciBoYW5kbGVyIC0gdGhpcyBhbGxvd3MKICogdGhlIHJlcG9ydCBvZiBhbnkgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBieSB0aGUgdXNlci4KICogVE9ETzogQ29ycmVjdCBjaGFyYWN0ZXIgbm9ybWFsaXphdGlvbiBvZiB1bmlvbiBzaW1wbGUgdHlwZXMuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCAKCQkJCSBjb25zdCB4bWxDaGFyICp2YWx1ZSwKCQkJCSBpbnQgZmlyZUVycm9ycywJCQkJIAoJCQkJIGludCBhcHBseUZhY2V0cykKewogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwogICAgaW50IHJldCA9IDA7ICAgIAogICAgdHlwZSA9IGN0eHQtPnR5cGU7ICAgICAKICAgIAogICAgaWYgKHR5cGUtPnR5cGUgPT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSB7Cgl4bWxOb2RlUHRyIGNoaWxkOwoKCWlmIChjdHh0LT52YWx1ZSAhPSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hRnJlZVZhbHVlKGN0eHQtPnZhbHVlKTsKCSAgICBjdHh0LT52YWx1ZSA9IE5VTEw7Cgl9CgljaGlsZCA9IGN0eHQtPm5vZGU7Cgl3aGlsZSAoY2hpbGQgIT0gTlVMTCkgewoJICAgIHN3aXRjaCAoY2hpbGQtPnR5cGUpIHsKCSAgICBjYXNlIFhNTF9URVhUX05PREU6CgkgICAgY2FzZSBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFOgoJICAgIGNhc2UgWE1MX1BJX05PREU6CgkgICAgY2FzZSBYTUxfQ09NTUVOVF9OT0RFOgoJICAgIGNhc2UgWE1MX1hJTkNMVURFX1NUQVJUOgoJICAgIGNhc2UgWE1MX1hJTkNMVURFX0VORDoKCQlicmVhazsKCSAgICBjYXNlIFhNTF9FTlRJVFlfUkVGX05PREU6CgkgICAgY2FzZSBYTUxfRU5USVRZX05PREU6CgkJVE9ETyBicmVhazsKCSAgICBjYXNlIFhNTF9FTEVNRU5UX05PREU6CgkJeG1sU2NoZW1hVkVycihjdHh0LCBjdHh0LT5jdXIsIFhNTF9TQ0hFTUFTX0VSUl9JTlZBTElERUxFTSwKCQkgICAgIkVsZW1lbnQgXCIlc1wiOiBjaGlsZCBcIiVzXCIgc2hvdWxkIG5vdCBiZSBwcmVzZW50LlxuIiwKCQkgICAgY3R4dC0+Y3VyLT5uYW1lLCBjaGlsZC0+bmFtZSk7CgkJcmV0dXJuIChjdHh0LT5lcnIpOwoJICAgIGNhc2UgWE1MX0FUVFJJQlVURV9OT0RFOgoJICAgIGNhc2UgWE1MX0RPQ1VNRU5UX05PREU6CgkgICAgY2FzZSBYTUxfRE9DVU1FTlRfVFlQRV9OT0RFOgoJICAgIGNhc2UgWE1MX0RPQ1VNRU5UX0ZSQUdfTk9ERToKCSAgICBjYXNlIFhNTF9OT1RBVElPTl9OT0RFOgoJICAgIGNhc2UgWE1MX0hUTUxfRE9DVU1FTlRfTk9ERToKCSAgICBjYXNlIFhNTF9EVERfTk9ERToKCSAgICBjYXNlIFhNTF9FTEVNRU5UX0RFQ0w6CgkgICAgY2FzZSBYTUxfQVRUUklCVVRFX0RFQ0w6CgkgICAgY2FzZSBYTUxfRU5USVRZX0RFQ0w6CgkgICAgY2FzZSBYTUxfTkFNRVNQQUNFX0RFQ0w6CiNpZmRlZiBMSUJYTUxfRE9DQl9FTkFCTEVECgkgICAgY2FzZSBYTUxfRE9DQl9ET0NVTUVOVF9OT0RFOgojZW5kaWYKCQl4bWxTY2hlbWFWRXJyKGN0eHQsIGN0eHQtPmN1ciwgWE1MX1NDSEVNQVNfRVJSX0lOVkFMSURFTEVNLAoJCSAgICAiRWxlbWVudCBcIiVzXCI6IG5vZGUgdHlwZSBvZiBub2RlIHVuZXhwZWN0ZWQgaGVyZS5cbiIsCgkJICAgIGN0eHQtPmN1ci0+bmFtZSwgTlVMTCk7CgkJcmV0dXJuIChjdHh0LT5lcnIpOwoJICAgIH0KCSAgICBjaGlsZCA9IGNoaWxkLT5uZXh0OwoJfQoJcmV0ID0geG1sU2NoZW1hVmFsUHJlZGVmVHlwZU5vZGUodHlwZSwgdmFsdWUsICYoY3R4dC0+dmFsdWUpLAoJICAgIGN0eHQtPmN1cik7CglpZiAocmV0ID4gMCkgewoJICAgIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9MSVNUKSAKCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzI7CgkgICAgZWxzZQoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMTsJICAgIAoJICAgIGlmIChmaXJlRXJyb3JzKSB7CgkJaWYgKGN0eHQtPmN1ci0+dHlwZSA9PSBYTUxfQVRUUklCVVRFX05PREUpCgkJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgY3R4dC0+Y3VyLCAKCQkgICAgWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8xLAoJCSAgICAiVGhlIHZhbHVlIG9mIGF0dHJpYnV0ZSBcIiVzXCIgaXMgbm90IHZhbGlkLlxuIiwKCQkgICAgY3R4dC0+Y3VyLT5uYW1lLCBOVUxMKTsKCQllbHNlIAoJCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGN0eHQtPmN1ciwgCgkJICAgIFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMSwKCQkgICAgIlRoZSB2YWx1ZSBpcyBub3QgdmFsaWQuXG4iLAoJCSAgICBOVUxMLCBOVUxMKTsKCSAgICB9CSAgICAKCX0gZWxzZSBpZiAocmV0IDwgMCkgewoJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgY3R4dC0+Y3VyLCBYTUxfU0NIRU1BU19FUlJfSU5URVJOQUwsCgkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSJ2YWxpZGF0aW5nIGJ1aWx0LWluIHR5cGUgXCIlc1wiXG4iLAoJCXR5cGUtPm5hbWUsIE5VTEwpOwoJfQogICAgfSBlbHNlIGlmICh0eXBlLT5mbGFncyAmIFhNTF9TQ0hFTUFTX1RZUEVfVkFSSUVUWV9BVE9NSUMpIHsgICAgICAgIAoJLyogMS4yLjEgaWYge3ZhcmlldHl9IGlzILdhdG9taWO3IHRoZW4gdGhlIHN0cmluZyBtdXN0ILdtYXRjaLcgCgkqIGEgbGl0ZXJhbCBpbiB0aGUgt2xleGljYWwgc3BhY2W3IG9mIHtiYXNlIHR5cGUgZGVmaW5pdGlvbn0gCgkqLwkKCWN0eHQtPnR5cGUgPSB0eXBlLT5iYXNlVHlwZTsKCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKGN0eHQsIHZhbHVlLCAwLCAwKTsKCWlmIChyZXQgPCAwKSB7CgkgICAgeG1sU2NoZW1hVkVycihjdHh0LCBjdHh0LT5jdXIsIFhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlLCAiCgkJInZhbGlkYXRpbmcgYXRvbWljIHNpbXBsZSB0eXBlIFwiJXNcIlxuIiwKCQl0eXBlLT5uYW1lLCBOVUxMKTsKCX0gZWxzZSBpZiAocmV0ID4gMCkgewoJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMTsKCSAgICBpZiAoZmlyZUVycm9ycykgewoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgY3R4dC0+Y3VyLCAKCQkgICAgWE1MX1NDSEVNQVZfQ1ZDX0RBVEFUWVBFX1ZBTElEXzFfMl8xLAoJCSAgICAiVGhlIHZhbHVlIGlzIG5vdCB2YWxpZC5cbiIsCgkJICAgIE5VTEwsIE5VTEwpOwoJICAgIH0JCQoJICAgIAoJfSBlbHNlIGlmICgoYXBwbHlGYWNldHMpICYmICAKCSAgICAodHlwZS0+ZmFjZXRTZXQgIT0gTlVMTCkpIHsKCSAgICB4bWxTY2hlbWFUeXBlUHRyIGJ1aWx0SW47CgoJICAgIC8qIAoJICAgICogQ2hlY2sgZmFjZXRzLiBCZSBzdXJlIHRvIHBhc3MgdGhlIGJ1aWx0LWluIHR5cGUgdG8KCSAgICAqIHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWwuCgkgICAgKi8JICAgIAkgICAgCSAgICAKCSAgICBidWlsdEluID0gdHlwZS0+YmFzZVR5cGU7CgkgICAgd2hpbGUgKGJ1aWx0SW4tPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKQoJCWJ1aWx0SW4gPSBidWlsdEluLT5iYXNlVHlwZTsKCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsKGN0eHQsIGJ1aWx0SW4sIAoJCXR5cGUtPmZhY2V0U2V0LCB2YWx1ZSwgZmlyZUVycm9ycyk7CgkgICAgaWYgKHJldCA8IDApIHsKCQl4bWxTY2hlbWFWRXJyKGN0eHQsIGN0eHQtPmN1ciwgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlLCAiCgkJICAgICJ2YWxpZGF0aW5nIGZhY2V0cyBvZiBhdG9taWMgc2ltcGxlIHR5cGUgXCIlc1wiXG4iLAoJCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKCSAgICB9IGVsc2UgaWYgKHJldCA+IDApIHsKCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzE7CgkJaWYgKGZpcmVFcnJvcnMpIHsKCQkgICAgeG1sU2NoZW1hVkVycihjdHh0LCBjdHh0LT5jdXIsIAoJCQlYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzEsCgkJCSJUaGUgdmFsdWUgaXMgbm90IHZhbGlkLlxuIiwKCQkJTlVMTCwgTlVMTCk7CgkJfQoJICAgIH0JCgl9CiAgICB9IGVsc2UgaWYgKHR5cGUtPmZsYWdzICYgWE1MX1NDSEVNQVNfVFlQRV9WQVJJRVRZX0xJU1QpIHsKICAgICAgICAKCXhtbFNjaGVtYVR5cGVQdHIgdG1wVHlwZTsKCWNvbnN0IHhtbENoYXIgKmN1ciwgKmVuZDsKCXhtbENoYXIgKnRtcDsKCWludCBsZW4gPSAwOwoKCS8qIDEuMi4yIGlmIHt2YXJpZXR5fSBpcyC3bGlzdLcgdGhlbiB0aGUgc3RyaW5nIG11c3QgYmUgYSBzZXF1ZW5jZSAKCSogb2Ygd2hpdGUgc3BhY2Ugc2VwYXJhdGVkIHRva2VucywgZWFjaCBvZiB3aGljaCC3bWF0Y2i3ZXMgYSBsaXRlcmFsIAoJKiBpbiB0aGUgt2xleGljYWwgc3BhY2W3IG9mIHtpdGVtIHR5cGUgZGVmaW5pdGlvbn0gCgkqLwoJCgl0bXBUeXBlID0geG1sU2NoZW1hR2V0TGlzdFNpbXBsZVR5cGVJdGVtVHlwZSh0eXBlKTsJCQoJY3VyID0gdmFsdWU7CglkbyB7CgkgICAgd2hpbGUgKElTX0JMQU5LX0NIKCpjdXIpKQoJCWN1cisrOwoJICAgIGVuZCA9IGN1cjsKCSAgICB3aGlsZSAoKCplbmQgIT0gMCkgJiYgKCEoSVNfQkxBTktfQ0goKmVuZCkpKSkKCQllbmQrKzsKCSAgICBpZiAoZW5kID09IGN1cikKCQlicmVhazsKCSAgICB0bXAgPSB4bWxTdHJuZHVwKGN1ciwgZW5kIC0gY3VyKTsKCSAgICBsZW4rKzsKCSAgICBjdHh0LT50eXBlID0gdG1wVHlwZTsKCSAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZShjdHh0LCB0bXAsIDAsIDEpOwoJICAgIHhtbEZyZWUodG1wKTsKCSAgICBpZiAocmV0ID4gMCkgewoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMjsKCQlpZiAoZmlyZUVycm9ycykgewoJCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGN0eHQtPmN1ciwgCgkJCVhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMiwKCQkJIlRoZSB2YWx1ZSBpcyBub3QgdmFsaWQuXG4iLAoJCQlOVUxMLCBOVUxMKTsKCQl9CQkKCQlicmVhazsKCSAgICB9IGVsc2UgaWYgKHJldCA8IDApCgkJYnJlYWs7CgkgICAgY3VyID0gZW5kOwoJfSB3aGlsZSAoKmN1ciAhPSAwKTsKCS8qIAoJKiBDaGVjayBmYWNldHMuCgkqLwoJaWYgKHJldCA8IDApIHsKCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGN0eHQtPmN1ciwgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCSJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUsICIKCQkidmFsaWRhdGluZyBsaXN0IHNpbXBsZSB0eXBlIFwiJXNcIlxuIiwKCQl0eXBlLT5uYW1lLCBOVUxMKTsKCX0gZWxzZSBpZiAoKHJldCA9PSAwKSAmJiAoYXBwbHlGYWNldHMpICYmIAoJICAgICh0eXBlLT5mYWNldFNldCAhPSBOVUxMKSkgewoJICAgIGludCBva0ZhY2V0ID0gMCwgaGFzRmFjZXQgPSAwOwoJICAgIHVuc2lnbmVkIGxvbmcgZXhwTGVuOwoJICAgIHhtbFNjaGVtYUZhY2V0UHRyIGZhY2V0OwoJICAgIHhtbFNjaGVtYUZhY2V0TGlua1B0ciBmYWNldExpbms7CgkgICAgeG1sQ2hhciAqY29sbGFwc2VkVmFsdWUgPSBOVUxMOwoKCSAgICAvKgoJICAgICogVGhlIHZhbHVlIG9mILd3aGl0ZVNwYWNltyBpcyBmaXhlZCB0byB0aGUgdmFsdWUgY29sbGFwc2UuIAoJICAgICovCgkgICAgY29sbGFwc2VkVmFsdWUgPSB4bWxTY2hlbWFDb2xsYXBzZVN0cmluZygoY29uc3QgeG1sQ2hhciAqKSB2YWx1ZSk7CgkgICAgaWYgKGNvbGxhcHNlZFZhbHVlICE9IE5VTEwpCQkKCQl2YWx1ZSA9IChjb25zdCB4bWxDaGFyICopIGNvbGxhcHNlZFZhbHVlOwkJCgkgICAgZmFjZXRMaW5rID0gdHlwZS0+ZmFjZXRTZXQ7CgkgICAgZG8gewoJCWZhY2V0ID0gZmFjZXRMaW5rLT5mYWNldDsKCQkvKiAKCQkqIExpc3QgdHlwZXMgbmVlZCBhIHNwZWNpYWwgZmFjZXQgdHJlYXRtZW50LiAKCQkqIFNraXAgd2hpdGVTcGFjZSwgc2luY2UgaXQgaXMgZml4ZWQgdG8gImNvbGxhcHNlIi4KCQkqLwoJCWlmICgoZmFjZXQtPnR5cGUgIT0gWE1MX1NDSEVNQV9GQUNFVF9XSElURVNQQUNFKSAmJiAKCQkgICAgKGZhY2V0LT50eXBlICE9IFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTikpIHsKCQkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVMaXN0U2ltcGxlVHlwZUZhY2V0KGZhY2V0LCB2YWx1ZSwgCgkJCWxlbiwgJmV4cExlbik7CgkJICAgIGlmIChmYWNldC0+dHlwZSA9PSBYTUxfU0NIRU1BX0ZBQ0VUX0VOVU1FUkFUSU9OKSB7CgkJCWhhc0ZhY2V0ID0gMTsKCQkJaWYgKHJldCA9PSAwKQoJCQkgICAgb2tGYWNldCA9IDE7CQkgICAgCgkJICAgIH0gZWxzZSBpZiAoKHJldCA+IDApICYmIChmaXJlRXJyb3JzKSkgewkJCQoJCQljaGFyIGxbMjVdLCBmbFsyNV07CQkJCgkJCS8qIEZJWE1FOiBXaGF0IGlzIHRoZSBtYXggZXhwZWN0ZWQgc3RyaW5nIGxlbmd0aCBvZiB0aGUKCQkJKiBsZW5ndGggdmFsdWU/CgkJCSovCgkJCXNucHJpbnRmKGwsIDI0LCAiJWQiLCBsZW4pOwoJCQlzbnByaW50ZihmbCwgMjQsICIlbHUiLCBleHBMZW4pOwoJCQlpZiAocmV0ID09IFhNTF9TQ0hFTUFWX0NWQ19MRU5HVEhfVkFMSUQpIHsKCQkJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgY3R4dC0+Y3VyLCByZXQsCgkJCQkiVGhlIHZhbHVlIHdpdGggbGVuZ3RoIFwiJXNcIiBpcyBub3QgIgoJCQkJImZhY2V0LXZhbGlkIHdpdGggcmVzcGVjdCB0byBsZW5ndGggPSBcIiVzXCIuXG4iLAoJCQkJKGNvbnN0IHhtbENoYXIgKilsLCAoY29uc3QgeG1sQ2hhciAqKWZsKTsKCQkJfSBlbHNlIGlmIChyZXQgPT0gWE1MX1NDSEVNQVZfQ1ZDX01JTkxFTkdUSF9WQUxJRCkgewoJCQkgICAgeG1sU2NoZW1hVkVycihjdHh0LCBjdHh0LT5jdXIsIHJldCwKCQkJCSJUaGUgdmFsdWUgd2l0aCBsZW5ndGggXCIlc1wiIGlzIG5vdCAiCgkJCQkiZmFjZXQtdmFsaWQgd2l0aCByZXNwZWN0IHRvIG1pbkxlbmd0aCA9IFwiJXNcIi5cbiIsCgkJCQkoY29uc3QgeG1sQ2hhciAqKWwsIChjb25zdCB4bWxDaGFyICopZmwpOwoJCQl9IGVsc2UgaWYgKHJldCA9PSBYTUxfU0NIRU1BVl9DVkNfTUFYTEVOR1RIX1ZBTElEKSB7CgkJCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGN0eHQtPmN1ciwgcmV0LAoJCQkJIlRoZSB2YWx1ZSB3aXRoIGxlbmd0aCBcIiVzXCIgaXMgbm90ICIKCQkJCSJmYWNldC12YWxpZCB3aXRoIHJlc3BlY3QgdG8gbWF4TGVuZ3RoID0gXCIlc1wiLlxuIiwKCQkJCShjb25zdCB4bWxDaGFyICopbCwgKGNvbnN0IHhtbENoYXIgKilmbCk7CgkJCX0gZWxzZSB7CgkJCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGN0eHQtPmN1ciwgcmV0LAoJCQkJIlRoZSB2YWx1ZSBpcyBub3QgdmFsaWQgd2l0aCByZXNwZWN0ICIKCQkJCSJ0byB0aGUgZmFjZXQgXCIlc1wiLlxuIiwKCQkJCShjb25zdCB4bWxDaGFyICopCgkJCQl4bWxTY2hlbWFGYWNldFR5cGVUb1N0cmluZyhmYWNldC0+dHlwZSksIAoJCQkJTlVMTCk7CgkJCX0JCQkKCQkgICAgfSBlbHNlIGlmIChyZXQgPCAwKSB7CgkJCXhtbFNjaGVtYVZFcnIoY3R4dCwgY3R4dC0+Y3VyLCBYTUxfU0NIRU1BU19FUlJfSU5URVJOQUwsCgkJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlLCAiCgkJCSAgICAidmFsaWRhdGluZyBmYWNldHMgb2YgbGlzdCBzaW1wbGUgdHlwZSBcIiVzXCJcbiIsCgkJCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsJCgkJCWJyZWFrOwoJCSAgICB9CgkJfQoJCWZhY2V0TGluayA9IGZhY2V0TGluay0+bmV4dDsJCQoJICAgIH0gd2hpbGUgKGZhY2V0TGluayAhPSBOVUxMKTsKCSAgICBpZiAocmV0ID49IDApIHsKCQlpZiAoKGhhc0ZhY2V0KSAmJiAob2tGYWNldCA9PSAwKSkgewoJCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfRU5VTUVSQVRJT05fVkFMSUQ7CgkJICAgIGlmIChmaXJlRXJyb3JzKSB7CgkJICAgIC8qCgkJICAgICogVE9ETzogVHJ5IHRvIGNyZWF0ZSBhIHJlcG9ydCB0aGF0IG91dHB1dHMgYWxsIHRoZSBlbnVtZXJhdGlvbgoJCSAgICAqIHZhbHVlcyBpbiB1c2UuCgkJCSovCgkJCXhtbFNjaGVtYVZFcnIoY3R4dCwgY3R4dC0+Y3VyLCBYTUxfU0NIRU1BVl9DVkNfRU5VTUVSQVRJT05fVkFMSUQsCgkJCSAgICAiVGhlIHZhbHVlIGlzIG5vdCB2YWxpZCB3aXRoIHJlc3BlY3QgIgoJCQkgICAgInRvIHRoZSBcImVudW1lcmF0aW9uXCIgZmFjZXQocykuXG4iLAoJCQkgICAgTlVMTCwgTlVMTCk7CgkJICAgIH0KCQkgICAgCgkJfQoJCS8qCgkJKiBQYXR0ZXJuIGZhY2V0cyBhcmUgT1JlZCBhdCB0eXBlIGxldmVsIGFuZCBBTkRlZAoJCSogaWYgZGVyaXZlZC4gV2FsayB0aGUgYmFzZSBheGlzLgoJCSovCgkJaGFzRmFjZXQgPSAwOwoJCXRtcFR5cGUgPSB0eXBlOwoJCWRvIHsJCSAgICAKCQkgICAgb2tGYWNldCA9IDA7CgkJICAgIGZvciAoZmFjZXRMaW5rID0gdG1wVHlwZS0+ZmFjZXRTZXQ7IGZhY2V0TGluayAhPSBOVUxMOyAKCQkgICAgZmFjZXRMaW5rID0gZmFjZXRMaW5rLT5uZXh0KSB7CQkgICAgCgkJCWlmIChmYWNldExpbmstPmZhY2V0LT50eXBlICE9IFhNTF9TQ0hFTUFfRkFDRVRfUEFUVEVSTikKCQkJICAgIGNvbnRpbnVlOwkJCQoJCQlva0ZhY2V0ID0geG1sU2NoZW1hVmFsaWRhdGVMaXN0U2ltcGxlVHlwZUZhY2V0KAoJCQkgICAgZmFjZXRMaW5rLT5mYWNldCwgdmFsdWUsIGxlbiwgJmV4cExlbik7CQkgICAgCgkJCWlmIChva0ZhY2V0IDw9IDApCgkJCSAgICBicmVhazsKCQkgICAgfQoJCSAgICBpZiAob2tGYWNldCAhPSAwKQoJCQlicmVhazsJCSAgICAKCQkgICAgdG1wVHlwZSA9IHRtcFR5cGUtPmJhc2VUeXBlOwoJCX0gd2hpbGUgKCh0bXBUeXBlICE9IE5VTEwpICYmICh0bXBUeXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykpOwoJCWlmIChva0ZhY2V0IDwgMCkgewoJCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGN0eHQtPmN1ciwgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlLCAiCgkJCSJ2YWxpZGF0aW5nIFwicGF0dGVyblwiIGZhY2V0cyBvZiB0eXBlIFwiJXNcIlxuIiwKCQkJdHlwZS0+bmFtZSwgTlVMTCk7CgkJfSBlbHNlIGlmIChva0ZhY2V0ID4gMCkgewoJCSAgICByZXQgPSBYTUxfU0NIRU1BVl9DVkNfUEFUVEVSTl9WQUxJRDsKCQkgICAgaWYgKGZpcmVFcnJvcnMpIHsKCQkJeG1sU2NoZW1hVkVycihjdHh0LCBjdHh0LT5jdXIsIFhNTF9TQ0hFTUFWX0NWQ19FTlVNRVJBVElPTl9WQUxJRCwKCQkJICAgICJUaGUgdmFsdWUgaXMgbm90IHZhbGlkIHdpdGggcmVzcGVjdCAiCgkJCSAgICAidG8gdGhlIFwicGF0dGVyblwiIGZhY2V0KHMpIG9mIHR5cGUgIgoJCQkgICAgIlwiJXNcIi5cbiIsCgkJCSAgICB0bXBUeXBlLT5uYW1lLCBOVUxMKTsKCQkgICAgfQkJICAgIAoJCX0KCSAgICB9CgoJICAgIGlmIChjb2xsYXBzZWRWYWx1ZSAhPSBOVUxMKSAKCQl4bWxGcmVlKGNvbGxhcHNlZFZhbHVlKTsKCX0KICAgIH0gZWxzZSBpZiAodHlwZS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19UWVBFX1ZBUklFVFlfVU5JT04pIHsKCXhtbFNjaGVtYVR5cGVMaW5rUHRyIG1lbWJlckxpbms7CgoJLyoKCSogVE9ETzogRm9yIGFsbCBkYXRhdHlwZXMgt2Rlcml2ZWS3IGJ5ILd1bmlvbrcgIHdoaXRlU3BhY2UgZG9lcyAKCSogbm90IGFwcGx5IGRpcmVjdGx5OyBob3dldmVyLCB0aGUgbm9ybWFsaXphdGlvbiBiZWhhdmlvciBvZiC3dW5pb263IAoJKiB0eXBlcyBpcyBjb250cm9sbGVkIGJ5IHRoZSB2YWx1ZSBvZiB3aGl0ZVNwYWNlIG9uIHRoYXQgb25lIG9mIHRoZSAKCSogt21lbWJlclR5cGVztyBhZ2FpbnN0IHdoaWNoIHRoZSC3dW5pb263IGlzIHN1Y2Nlc3NmdWxseSB2YWxpZGF0ZWQuIAoJKgoJKiBUaGlzIG1lYW5zIHRoYXQgdGhlIHZhbHVlIGlzIG5vcm1hbGl6ZWQgYnkgdGhlIGZpcnN0IHZhbGlkYXRpbmcKCSogbWVtYmVyIHR5cGUsIHRoZW4gdGhlIGZhY2V0cyBvZiB0aGUgdW5pb24gdHlwZSBhcmUgYXBwbGllZC4gVGhpcwoJKiBuZWVkcyBjaGFuZ2luZyBvZiB0aGUgdmFsdWUhCgkqLwkKCQoJLyoKCSogMS4yLjMgaWYge3ZhcmlldHl9IGlzILd1bmlvbrcgdGhlbiB0aGUgc3RyaW5nIG11c3Qgt21hdGNotyBhIAoJKiBsaXRlcmFsIGluIHRoZSC3bGV4aWNhbCBzcGFjZbcgb2YgYXQgbGVhc3Qgb25lIG1lbWJlciBvZiAKCSoge21lbWJlciB0eXBlIGRlZmluaXRpb25zfSAKCSovCgltZW1iZXJMaW5rID0geG1sU2NoZW1hR2V0VW5pb25TaW1wbGVUeXBlTWVtYmVyVHlwZXModHlwZSk7CglpZiAobWVtYmVyTGluayA9PSBOVUxMKSB7CgkgICAgeG1sU2NoZW1hVkVycihjdHh0LCBjdHh0LT5jdXIsIFhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlLCAiCgkJInVuaW9uIHNpbXBsZSB0eXBlIFwiJXNcIiBoYXMgbm8gbWVtYmVyIHR5cGVzXG4iLAoJCXR5cGUtPm5hbWUsIE5VTEwpOwoJICAgIHJldCA9IC0xOwoJfSAKCWlmIChyZXQgPT0gMCkgewoJICAgIHdoaWxlIChtZW1iZXJMaW5rICE9IE5VTEwpIHsKCQljdHh0LT50eXBlID0gbWVtYmVyTGluay0+dHlwZTsKCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZShjdHh0LCB2YWx1ZSwgMCwgMSk7CgkJaWYgKChyZXQgPD0gMCkgfHwgKHJldCA9PSAwKSkKCQkgICAgYnJlYWs7CSAgICAKCQltZW1iZXJMaW5rID0gbWVtYmVyTGluay0+bmV4dDsKCSAgICB9ICAgICAKCSAgICBpZiAocmV0ID4gMCkgewoJCXJldCA9IFhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMzsKCQlpZiAoZmlyZUVycm9ycykgewoJCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGN0eHQtPmN1ciwgCgkJCVhNTF9TQ0hFTUFWX0NWQ19EQVRBVFlQRV9WQUxJRF8xXzJfMywKCQkJIlRoZSB2YWx1ZSBpcyBub3QgdmFsaWQuXG4iLAoJCQlOVUxMLCBOVUxMKTsKCQl9CQkJICAgIAoJICAgIH0gZWxzZSBpZiAocmV0IDwgMCkgewoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgY3R4dC0+Y3VyLCBYTUxfU0NIRU1BU19FUlJfSU5URVJOQUwsCgkJICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlVmFsdWUsICIKCQkgICAgInZhbGlkYXRpbmcgbWVtYmVycyBvZiB1bmlvbiBzaW1wbGUgdHlwZSBcIiVzXCJcbiIsCgkJICAgIHR5cGUtPm5hbWUsIE5VTEwpOwoJICAgIH0KCX0KCS8qCgkqIEFwcGx5IGZhY2V0cyAocGF0dGVybiwgZW51bWVyYXRpb24pLgoJKi8KCWlmICgocmV0ID09IDApICYmIChhcHBseUZhY2V0cykgJiYgCgkgICAgKHR5cGUtPmZhY2V0U2V0ICE9IE5VTEwpKSB7CgkgICAgeG1sU2NoZW1hVHlwZVB0ciBhbnlTaW1wbGVUeXBlOwoJICAgIC8qIAoJICAgICogQ2hlY2sgZmFjZXRzLiBCZSBzdXJlIHRvIHBhc3MgdGhlIGJ1aWx0LWluIHR5cGUgKHRoZQoJICAgICogc2ltcGxlIHVyLXR5cGUgaW4gdGhpcyBjYXNlKSB0byB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsLgoJICAgICovCSAgICAJICAgIAkgICAgCgkgICAgYW55U2ltcGxlVHlwZSA9IHR5cGUtPmJhc2VUeXBlOwoJICAgIHdoaWxlIChhbnlTaW1wbGVUeXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykKCQlhbnlTaW1wbGVUeXBlID0gYW55U2ltcGxlVHlwZS0+YmFzZVR5cGU7CgkgICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVGYWNldHNJbnRlcm5hbChjdHh0LCBhbnlTaW1wbGVUeXBlLCAKCQl0eXBlLT5mYWNldFNldCwgdmFsdWUsIGZpcmVFcnJvcnMpOwoJICAgIGlmIChyZXQgPCAwKSB7CgkJeG1sU2NoZW1hVkVycihjdHh0LCBjdHh0LT5jdXIsIFhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKCQkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVWYWx1ZSwgIgoJCSAgICAidmFsaWRhdGluZyBmYWNldHMgb2YgdW5pb24gc2ltcGxlIHR5cGUgXCIlc1wiXG4iLAoJCSAgICB0eXBlLT5uYW1lLCBOVUxMKTsKCSAgICB9IGVsc2UgaWYgKHJldCA+IDApIHsKCQlyZXQgPSBYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzM7CgkJaWYgKGZpcmVFcnJvcnMpIHsKCQkgICAgeG1sU2NoZW1hVkVycihjdHh0LCBjdHh0LT5jdXIsIAoJCQlYTUxfU0NIRU1BVl9DVkNfREFUQVRZUEVfVkFMSURfMV8yXzEsCgkJCSJUaGUgdmFsdWUgaXMgbm90IHZhbGlkLlxuIiwKCQkJTlVMTCwgTlVMTCk7CgkJfQoJICAgIH0JCgl9CiAgICB9ICAgIAogICAgY3R4dC0+dHlwZSA9IHR5cGU7CiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVFbGVtZW50OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIHRoZSBlbGVtZW50IG5vZGUgdG8gYmUgdmFsaWRhdGVkLgogKgogKiBWYWxpZGF0ZSB0aGUgZWxlbWVudCBhZ2FpbnN0IGEgc2ltcGxlIHR5cGUuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgYW4gaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZVNpbXBsZVR5cGVFbGVtZW50KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIG5vZGUpCnsKICAgIHhtbE5vZGVQdHIgY2hpbGQ7CiAgICB4bWxTY2hlbWFUeXBlUHRyIHR5cGU7CiAgICB4bWxBdHRyUHRyIGF0dHI7CiAgICBpbnQgcmV0OwogICAgeG1sQ2hhciAqdmFsdWU7CiAgICAKCiAgICBjaGlsZCA9IGN0eHQtPm5vZGU7CiAgICB0eXBlID0gY3R4dC0+dHlwZTsKCiAgICBpZiAoKGN0eHQgPT0gTlVMTCkgfHwgKHR5cGUgPT0gTlVMTCkpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKCQkgICAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZUVsZW1lbnQgJXNcbiIsCgkJICAgICAgbm9kZS0+bmFtZSwgTlVMTCk7CiAgICAgICAgcmV0dXJuICgtMSk7CiAgICB9CgogICAgLyoKICAgICogT25seSB0ZXh0IGFuZCB0ZXh0IGJhc2VkIGVudGl0aWVzIHJlZmVyZW5jZXMgc2hhbGwgYmUgZm91bmQgdGhlcmUKICAgICovCiAgICByZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUNoZWNrTm9kZUxpc3QoY2hpbGQpOwogICAgaWYgKHJldCA8IDApIHsKICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKCQkgICAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZUVsZW1lbnQgJXMgY29udGVudFxuIiwKCQkgICAgICBub2RlLT5uYW1lLCBOVUxMKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0gZWxzZSBpZiAocmV0ID09IDApIHsKCS8qIDMuMS4yIFRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gbXVzdCBoYXZlIG5vIGVsZW1lbnQgCgkqIGluZm9ybWF0aW9uIGl0ZW0gW2NoaWxkcmVuXS4KCSovCiAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9DVkNfVFlQRV8zXzFfMiwKCQkgICAgICAiRWxlbWVudCBcIiVzXCIgbXVzdCBoYXZlIG5vIGVsZW1lbnQgY2hpbGRyZW4uXG4iLAoJCSAgICAgIG5vZGUtPm5hbWUsIE5VTEwpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQogICAgLyoKICAgICAqIFZhbGlkYXRpb24gUnVsZTogRWxlbWVudCBMb2NhbGx5IFZhbGlkIChUeXBlKTogMy4xLjEKICAgICAqLyAgICAgICAgCiAgICBhdHRyID0gbm9kZS0+cHJvcGVydGllczsKICAgIHdoaWxlIChhdHRyICE9IE5VTEwpIHsKICAgICAgICBpZiAoKGF0dHItPm5zID09IE5VTEwpIHx8CiAgICAgICAgICAgICgheG1sU3RyRXF1YWwoYXR0ci0+bnMtPmhyZWYsIHhtbFNjaGVtYUluc3RhbmNlTnMpKSB8fAogICAgICAgICAgICAoKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAidHlwZSIpKSAmJgogICAgICAgICAgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibmlsIikpICYmCiAgICAgICAgICAgICAoIXhtbFN0ckVxdWFsKGF0dHItPm5hbWUsIEJBRF9DQVNUICJzY2hlbWFMb2NhdGlvbiIpKSAmJgogICAgICAgICAgICAgKCF4bWxTdHJFcXVhbAogICAgICAgICAgICAgIChhdHRyLT5uYW1lLCBCQURfQ0FTVCAibm9OYW1lc3BhY2VTY2hlbWFMb2NhdGlvbiIpKSkpIHsKICAgICAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCAKCQlYTUxfU0NIRU1BVl9DVkNfVFlQRV8zXzFfMSwKCQkiVGhlIGF0dHJpYnV0ZXMgb2YgZWxlbWVudCBcIiVzXCIgbXVzdCBiZSBlbXB0eSwgZXhjZXB0aW5nICIKCQkidGhvc2Ugd2hvc2UgbmFtZXNwYWNlIG5hbWUgaXMgaWRlbnRpY2FsIHRvICIKCQkiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UgYW5kIHdob3NlIGxvY2FsICIKCQkibmFtZSBpcyBvbmUgb2YgdHlwZSwgbmlsLCBzY2hlbWFMb2NhdGlvbiBvciAiCgkJIm5vTmFtZXNwYWNlU2NoZW1hTG9jYXRpb24uXG4iLAoJCW5vZGUtPm5hbWUsIGF0dHItPm5hbWUpOwogICAgICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICAgICAgfQoJYXR0ciA9IGF0dHItPm5leHQ7CiAgICB9CiAgICB2YWx1ZSA9IHhtbE5vZGVHZXRDb250ZW50KGNoaWxkKTsKICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKGN0eHQsIHZhbHVlLCAxLCAxKTsKICAgIGlmICh2YWx1ZSAhPSBOVUxMKQogICAgICAgIHhtbEZyZWUodmFsdWUpOwoKICAgIGN0eHQtPnR5cGUgPSB0eXBlOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50VHlwZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICB0aGUgdG9wIG5vZGUuCiAqCiAqIFZhbGlkYXRlIHRoZSBjb250ZW50IG9mIGFuIGVsZW1lbnQgdHlwZS4KICogVmFsaWRhdGlvbiBSdWxlOiBFbGVtZW50IExvY2FsbHkgVmFsaWQgKENvbXBsZXggVHlwZSkKICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRWxlbWVudFR5cGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sTm9kZVB0ciBjaGlsZDsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKICAgIHhtbFJlZ0V4ZWNDdHh0UHRyIG9sZHJlZ2V4cDsgICAgICAgIC8qIGNvbnQgbW9kZWwgb2YgdGhlIHBhcmVudCAqLwogICAgeG1sU2NoZW1hRWxlbWVudFB0ciBkZWNsOwogICAgaW50IHJldDsKICAgIHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciBhdHRycyA9IE5VTEwsIGF0dHJUb3AgPSBOVUxMOwoKICAgIC8qIFRoaXMgb25lIGlzIGNhbGxlZCBieSB4bWxTY2hlbWFWYWxpZGF0ZUNvbnRlbnQgb25seS4gKi8KICAgIC8qIAogICAgICogVE9ETzogTG9vayBpbnRvICJ4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnQiIGZvciBtaXNzaW5nIHBhcnRzLCB3aGljaCBzaG91bGQKICAgICAqIGdvIGluIGhlcmUgYXMgd2VsbC4KICAgICAqLwoKICAgIC8qIFRPRE86IElzIHRoaXMgb25lIGNhbGxlZCBhbHdheXMgd2l0aCBhbiBlbGVtZW50IGRlY2xhcmF0aW9uIGFzIHRoZSAKICAgICAqIGNvbnRleHQncyB0eXBlPwogICAgICovCgogICAgb2xkcmVnZXhwID0gY3R4dC0+cmVnZXhwOwoKICAgIGNoaWxkID0gY3R4dC0+bm9kZTsKICAgIHR5cGUgPSBjdHh0LT50eXBlOwoKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAodHlwZSA9PSBOVUxMKSkgewogICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCSAgICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50VHlwZVxuIiwKCQkgICAgICBub2RlLT5uYW1lLCBOVUxMKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KICAgIGlmIChjaGlsZCA9PSBOVUxMKSB7CiAgICAgICAgaWYgKHR5cGUtPm1pbk9jY3VycyA+IDApIHsKICAgICAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BU19FUlJfTUlTU0lORywKCSAgICAJCSAgIkVsZW1lbnQgJXM6IG1pc3NpbmcgY2hpbGQgJXNcbiIsCgkJCSAgbm9kZS0+bmFtZSwgdHlwZS0+bmFtZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKICAgIH0KCiAgICAvKgogICAgICogVmVyaWZ5IHRoZSBlbGVtZW50IG1hdGNoZXMKICAgICAqLwogICAgaWYgKCF4bWxTdHJFcXVhbChjaGlsZC0+bmFtZSwgdHlwZS0+bmFtZSkpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyMyhjdHh0LCBub2RlLCBYTUxfU0NIRU1BU19FUlJfV1JPTkdFTEVNLAoJCSAgICAgICAiRWxlbWVudCAlczogbWlzc2luZyBjaGlsZCAlcyBmb3VuZCAlc1xuIiwKCQkgICAgICAgbm9kZS0+bmFtZSwgdHlwZS0+bmFtZSwgY2hpbGQtPm5hbWUpOwogICAgICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKICAgIH0KICAgIC8qCiAgICAgKiBWZXJpZnkgdGhlIGF0dHJpYnV0ZXMKICAgICAqLwogICAgCiAgICBhdHRycyA9IGN0eHQtPmF0dHI7ICAgIAogICAgYXR0clRvcCA9IGN0eHQtPmF0dHJUb3A7CiAgICAKICAgIHhtbFNjaGVtYVJlZ2lzdGVyQXR0cmlidXRlcyhjdHh0LCBjaGlsZC0+cHJvcGVydGllcyk7ICAgICAgICAgICAgCgogICAgLyoKICAgICAqIFZlcmlmeSB0aGUgZWxlbWVudCBjb250ZW50IHJlY3Vyc2l2ZWx5CiAgICAgKi8KICAgIGRlY2wgPSAoeG1sU2NoZW1hRWxlbWVudFB0cikgdHlwZTsKICAgIG9sZHJlZ2V4cCA9IGN0eHQtPnJlZ2V4cDsKICAgIGlmIChkZWNsLT5jb250TW9kZWwgIT0gTlVMTCkgewogICAgICAgIGN0eHQtPnJlZ2V4cCA9IHhtbFJlZ05ld0V4ZWNDdHh0KGRlY2wtPmNvbnRNb2RlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoeG1sUmVnRXhlY0NhbGxiYWNrcykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGF0ZUNhbGxiYWNrLCBjdHh0KTsKI2lmZGVmIERFQlVHX0FVVE9NQVRBCiAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsICI9PT09PiAlc1xuIiwgbm9kZS0+bmFtZSk7CiNlbmRpZgogICAgfQogICAgeG1sU2NoZW1hVmFsaWRhdGVUeXBlKGN0eHQsIGNoaWxkLCAoeG1sU2NoZW1hRWxlbWVudFB0cikgdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLT5zdWJ0eXBlcyk7CgogICAgaWYgKGRlY2wtPmNvbnRNb2RlbCAhPSBOVUxMKSB7CiAgICAgICAgcmV0ID0geG1sUmVnRXhlY1B1c2hTdHJpbmcoY3R4dC0+cmVnZXhwLCBOVUxMLCBOVUxMKTsKI2lmZGVmIERFQlVHX0FVVE9NQVRBCiAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICI9PT09PiAlcyA6ICVkXG4iLCBub2RlLT5uYW1lLCByZXQpOwojZW5kaWYKICAgICAgICBpZiAocmV0ID09IDApIHsKICAgICAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BU19FUlJfRUxFTUNPTlQsCgkgICAgCQkgICJFbGVtZW50ICVzIGNvbnRlbnQgY2hlY2sgZmFpbGVkXG4iLAoJCQkgIG5vZGUtPm5hbWUsIE5VTEwpOwogICAgICAgIH0gZWxzZSBpZiAocmV0IDwgMCkgewogICAgICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9FTEVNQ09OVCwKCSAgICAJCSAgIkVsZW1lbnQgJXMgY29udGVudCBjaGVjayBmYWlsdXJlXG4iLAoJCQkgIG5vZGUtPm5hbWUsIE5VTEwpOwojaWZkZWYgREVCVUdfQ09OVEVOVAogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVsZW1lbnQgJXMgY29udGVudCBjaGVjayBzdWNjZWVkZWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBub2RlLT5uYW1lKTsKCiNlbmRpZgogICAgICAgIH0KICAgICAgICB4bWxSZWdGcmVlRXhlY0N0eHQoY3R4dC0+cmVnZXhwKTsKICAgIH0KICAgIC8qCiAgICAgKiBWZXJpZnkgdGhhdCBhbGwgYXR0cmlidXRlcyB3ZXJlIFNjaGVtYXMtdmFsaWRhdGVkCiAgICAgKi8KICAgIHhtbFNjaGVtYUNoZWNrQXR0cmlidXRlcyhjdHh0LCBub2RlKTsKICAgIGlmIChjdHh0LT5hdHRyICE9IE5VTEwpCgl4bWxTY2hlbWFGcmVlQXR0cmlidXRlU3RhdGVzKGN0eHQtPmF0dHIpOwogICAgY3R4dC0+YXR0ciA9IGF0dHJzOyAgICAKICAgIGN0eHQtPmF0dHJUb3AgPSBhdHRyVG9wOwogICAgY3R4dC0+cmVnZXhwID0gb2xkcmVnZXhwOwogICAgY3R4dC0+bm9kZSA9IGNoaWxkOwogICAgY3R4dC0+dHlwZSA9IHR5cGU7CiAgICByZXR1cm4gKGN0eHQtPmVycik7Cn0KCiNpZiAwIC8qIE5vdCBjdXJyZW50bHkgdXNlZC4gKi8KLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlQmFzaWNUeXBlOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAbm9kZTogIHRoZSB0b3Agbm9kZS4KICoKICogVmFsaWRhdGUgdGhlIGNvbnRlbnQgb2YgYW4gZWxlbWVudCBleHBlY3RlZCB0byBiZSBhIGJhc2ljIHR5cGUgdHlwZQogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVCYXNpY1R5cGUoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgaW50IHJldDsKICAgIHhtbE5vZGVQdHIgY2hpbGQsIGN1cjsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKICAgIHhtbENoYXIgKnZhbHVlOyAgICAgICAgICAgICAvKiBsZXhpY2FsIHJlcHJlc2VudGF0aW9uICovCgogICAgY2hpbGQgPSBjdHh0LT5ub2RlOwogICAgdHlwZSA9IGN0eHQtPnR5cGU7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8ICh0eXBlID09IE5VTEwpKSB7CiAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BU19FUlJfSU5URVJOQUwsCgkJICAgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUJhc2ljVHlwZVxuIiwKCQkgICAgICBub2RlLT5uYW1lLCBOVUxMKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KICAgIGlmICh0eXBlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykgewoJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BU19FUlJfSU5URVJOQUwsCgkgICAgIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUJhc2ljVHlwZSwgIgoJICAgICJ0aGUgZ2l2ZW4gdHlwZSBpcyBub3QgYSBidWlsdC1pbiB0eXBlLlxuIiwKCSAgICBub2RlLT5uYW1lLCBOVUxMKTsKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KICAgIC8qCiAgICAgKiBGaXJzdCBjaGVjayB0aGUgY29udGVudCBtb2RlbCBvZiB0aGUgbm9kZS4KICAgICAqLwogICAgY3VyID0gY2hpbGQ7CiAgICB3aGlsZSAoY3VyICE9IE5VTEwpIHsKICAgICAgICBzd2l0Y2ggKGN1ci0+dHlwZSkgewogICAgICAgICAgICBjYXNlIFhNTF9URVhUX05PREU6CiAgICAgICAgICAgIGNhc2UgWE1MX0NEQVRBX1NFQ1RJT05fTk9ERToKICAgICAgICAgICAgY2FzZSBYTUxfUElfTk9ERToKICAgICAgICAgICAgY2FzZSBYTUxfQ09NTUVOVF9OT0RFOgogICAgICAgICAgICBjYXNlIFhNTF9YSU5DTFVERV9TVEFSVDoKICAgICAgICAgICAgY2FzZSBYTUxfWElOQ0xVREVfRU5EOgogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgWE1MX0VOVElUWV9SRUZfTk9ERToKICAgICAgICAgICAgY2FzZSBYTUxfRU5USVRZX05PREU6CiAgICAgICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgICAgICBjYXNlIFhNTF9FTEVNRU5UX05PREU6CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9JTlZBTElERUxFTSwKCQkJICAgICAgIkVsZW1lbnQgJXM6IGNoaWxkICVzIHNob3VsZCBub3QgYmUgcHJlc2VudFxuIiwKCQkJICAgICAgbm9kZS0+bmFtZSwgY3VyLT5uYW1lKTsKICAgICAgICAgICAgICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKICAgICAgICAgICAgY2FzZSBYTUxfQVRUUklCVVRFX05PREU6CiAgICAgICAgICAgIGNhc2UgWE1MX0RPQ1VNRU5UX05PREU6CiAgICAgICAgICAgIGNhc2UgWE1MX0RPQ1VNRU5UX1RZUEVfTk9ERToKICAgICAgICAgICAgY2FzZSBYTUxfRE9DVU1FTlRfRlJBR19OT0RFOgogICAgICAgICAgICBjYXNlIFhNTF9OT1RBVElPTl9OT0RFOgogICAgICAgICAgICBjYXNlIFhNTF9IVE1MX0RPQ1VNRU5UX05PREU6CiAgICAgICAgICAgIGNhc2UgWE1MX0RURF9OT0RFOgogICAgICAgICAgICBjYXNlIFhNTF9FTEVNRU5UX0RFQ0w6CiAgICAgICAgICAgIGNhc2UgWE1MX0FUVFJJQlVURV9ERUNMOgogICAgICAgICAgICBjYXNlIFhNTF9FTlRJVFlfREVDTDoKICAgICAgICAgICAgY2FzZSBYTUxfTkFNRVNQQUNFX0RFQ0w6CiNpZmRlZiBMSUJYTUxfRE9DQl9FTkFCTEVECiAgICAgICAgICAgIGNhc2UgWE1MX0RPQ0JfRE9DVU1FTlRfTk9ERToKI2VuZGlmCiAgICAgICAgICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9JTlZBTElERUxFTSwKCQkJICAgICAgIkVsZW1lbnQgJXM6IG5vZGUgdHlwZSBvZiBub2RlIHVuZXhwZWN0ZWQgaGVyZVxuIiwKCQkJICAgICAgbm9kZS0+bmFtZSwgTlVMTCk7CiAgICAgICAgICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICAgICAgfQogICAgICAgIGN1ciA9IGN1ci0+bmV4dDsKICAgIH0KICAgIGlmIChjaGlsZCA9PSBOVUxMKQogICAgICAgIHZhbHVlID0gTlVMTDsKICAgIGVsc2UKICAgICAgICB2YWx1ZSA9IHhtbE5vZGVHZXRDb250ZW50KGNoaWxkLT5wYXJlbnQpOwoKICAgIGlmIChjdHh0LT52YWx1ZSAhPSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hRnJlZVZhbHVlKGN0eHQtPnZhbHVlKTsKICAgICAgICBjdHh0LT52YWx1ZSA9IE5VTEw7CiAgICB9CiAgIAogICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVQcmVkZWZpbmVkVHlwZSh0eXBlLCB2YWx1ZSwgJihjdHh0LT52YWx1ZSkpOwogICAgCiAgICBpZiAodmFsdWUgIT0gTlVMTCkKICAgICAgICB4bWxGcmVlKHZhbHVlKTsgICAgCiAgICBpZiAocmV0ICE9IDApIHsKICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9WQUxVRSwKCQkgICAgICAiRWxlbWVudCAlczogZmFpbGVkIHRvIHZhbGlkYXRlIGJhc2ljIHR5cGUgJXNcbiIsCgkJICAgICAgbm9kZS0+bmFtZSwgdHlwZS0+bmFtZSk7CiAgICB9CiAgICByZXR1cm4gKHJldCk7Cn0KI2VuZGlmCgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVDb21wbGV4VHlwZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQG5vZGU6ICB0aGUgdG9wIG5vZGUuCiAqCiAqIFZhbGlkYXRlIHRoZSBjb250ZW50IG9mIGFuIGVsZW1lbnQgZXhwZWN0ZWQgdG8gYmUgYSBjb21wbGV4IHR5cGUgdHlwZQogKiB4bWxzY2hlbWEtMS5odG1sI2N2Yy1jb21wbGV4LXR5cGUKICogVmFsaWRhdGlvbiBSdWxlOiBFbGVtZW50IExvY2FsbHkgVmFsaWQgKENvbXBsZXggVHlwZSkKICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICogTm90ZSBvbiByZXBvcnRlZCBlcnJvcnM6IEFsdGhvdWdoIGl0IG1pZ2h0IGJlIG5pY2UgdG8gcmVwb3J0CiAqIHRoZSBuYW1lIG9mIHRoZSBzaW1wbGUvY29tcGxleCB0eXBlLCB1c2VkIHRvIHZhbGlkYXRlIHRoZSBjb250ZW50CiAqIG9mIGEgbm9kZSwgaXQgaXMgcXVpdGUgdW5uZWNlc3Nhcnk6IGZvciBnbG9iYWwgZGVmaW5lZCB0eXBlcwogKiB0aGUgbG9jYWwgbmFtZSBvZiB0aGUgZWxlbWVudCBpcyBlcXVhbCB0byB0aGUgTkNOYW1lIG9mIHRoZSB0eXBlLAogKiBmb3IgbG9jYWwgZGVmaW5lZCB0eXBlcyBpdCBtYWtlcyBubyBzZW5zZSB0byBvdXRwdXQgdGhlIGludGVybmFsCiAqIGNvbXB1dGVkIG5hbWUgb2YgdGhlIHR5cGUuIFRPRE86IEluc3RlYWQsIG9uZSBzaG91bGQgYXR0YWNoIHRoZSAKICogc3RydWN0IG9mIHRoZSB0eXBlIGludm9sdmVkIHRvIHRoZSBlcnJvciBoYW5kbGVyIC0gdGhpcyBhbGxvd3MKICogdGhlIHJlcG9ydCBvZiBhbnkgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBieSB0aGUgdXNlci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVDb21wbGV4VHlwZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBub2RlKQp7CiAgICB4bWxOb2RlUHRyIGNoaWxkOwogICAgeG1sU2NoZW1hVHlwZVB0ciB0eXBlOwogICAgaW50IHJldCA9IDA7CgogICAgY2hpbGQgPSBjdHh0LT5ub2RlOwogICAgdHlwZSA9IGN0eHQtPnR5cGU7CiAgICBjdHh0LT5jdXIgPSBub2RlOwoKICAgIHN3aXRjaCAodHlwZS0+Y29udGVudFR5cGUpIHsKCWNhc2UgWE1MX1NDSEVNQV9DT05URU5UX0VNUFRZOiB7CgkgICAgLyoKCSAgICAqIDEgSWYgdGhlIHtjb250ZW50IHR5cGV9IGlzIGVtcHR5LCB0aGVuIHRoZSBlbGVtZW50IGluZm9ybWF0aW9uIAoJICAgICogaXRlbSBoYXMgbm8gY2hhcmFjdGVyIG9yIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBbY2hpbGRyZW5dLgoJICAgICovCgkgICAgLyogVE9ETzogSG1tLCBYZXJjZXMgcmVwb3J0cyBub2RlcyBsaWtlIENvbW1lbnQgdG8gYmUgaW52YWxpZCAKCSAgICAqIGNvbnRlbnQsIGJ1dCBYU1YgZG9lcyBub3QuCgkgICAgKi8JIAoJICAgIC8qCgkgICAgKiBUT0RPOiBJcyB0aGUgZW50aXR5IHN0dWZmIGNvcnJlY3Q/CgkgICAgKi8KCSAgICB3aGlsZSAoY2hpbGQgIT0gTlVMTCkgewoJCWlmICgoY2hpbGQtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgfHwKCQkgICAgIC8qIAoJCSAgICAqIFRPRE86IEFzayBEYW5pZWwgaWYgdGhpcyBhcmUgYWxsIGNoYXJhY3RlciBub2Rlcy4KCQkgICAgKi8KCQkgICAgKGNoaWxkLT50eXBlID09IFhNTF9URVhUX05PREUpIHx8CQkgICAgCgkJICAgIChjaGlsZC0+dHlwZSA9PSBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFKSB8fAoJCSAgICAoY2hpbGQtPnR5cGUgPT0gWE1MX0VOVElUWV9SRUZfTk9ERSkgfHwKCQkgICAgKGNoaWxkLT50eXBlID09IFhNTF9FTlRJVFlfTk9ERSkpIHsKCQkgICAgYnJlYWs7CgkJfQoJCWNoaWxkID0gY2hpbGQtPm5leHQ7CgkgICAgfQoJICAgIGlmIChjaGlsZCAhPSBOVUxMKSB7CgkJeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BVl9DVkNfQ09NUExFWF9UWVBFXzJfMSwKCQkgICAgIkNoYXJhY3RlciBvciBlbGVtZW50IGNoaWxkcmVuIGFyZSBub3QgYWxsb3dlZCwgIgoJCSAgICAiYmVjYXVzZSB0aGUgY29udGVudCB0eXBlIGlzIGVtcHR5LlxuIiwKCQkgICAgTlVMTCwgTlVMTCk7CiAgICAgICAgICAgIH0JIAogICAgICAgICAgICBicmVhazsKCX0KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9FTEVNRU5UUzoKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9NSVhFRDogICAgICAgICAgICAgIAoJICAgIHdoaWxlIChjaGlsZCAhPSBOVUxMKSB7CQkKCQlpZiAoY2hpbGQtPnR5cGUgPT0gWE1MX0VMRU1FTlRfTk9ERSkgewoJCSAgICByZXQgPSB4bWxSZWdFeGVjUHVzaFN0cmluZyhjdHh0LT5yZWdleHAsCgkJCWNoaWxkLT5uYW1lLCBjaGlsZCk7CiNpZmRlZiBERUJVR19BVVRPTUFUQQoJCSAgICBpZiAocmV0IDwgMCkKCQkJeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCgkJCSIgIC0tPiAlcyBFcnJvclxuIiwgY2hpbGQtPm5hbWUpOwoJCSAgICBlbHNlCgkJCXhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAoJCQkiICAtLT4gJXNcbiIsIGNoaWxkLT5uYW1lKTsKI2VuZGlmCgkJfSBlbHNlIGlmICgodHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX0VMRU1FTlRTKSAmJiAKCQkgICAgLyogCgkJICAgICogVE9ETzogQXNrIERhbmllbCBpZiB0aGlzIGFyZSBhbGwgY2hhcmFjdGVyIG5vZGVzLgoJCSAgICAqLwoJCSAgICAoKChjaGlsZC0+dHlwZSA9PSBYTUxfVEVYVF9OT0RFKSAmJiAoIUlTX0JMQU5LX05PREUoY2hpbGQpKSkgfHwKCQkgICAgIChjaGlsZC0+dHlwZSA9PSBYTUxfRU5USVRZX05PREUpIHx8CQkgICAgCQkgICAgCgkJICAgICAoY2hpbGQtPnR5cGUgPT0gWE1MX0VOVElUWV9SRUZfTk9ERSkgfHwJCSAgICAKCQkgICAgIChjaGlsZC0+dHlwZSA9PSBYTUxfQ0RBVEFfU0VDVElPTl9OT0RFKSkpIHsJCSAgICAKCQkgICAgLyogCgkJICAgICogMi4zIElmIHRoZSB7Y29udGVudCB0eXBlfSBpcyBlbGVtZW50LW9ubHksIHRoZW4gdGhlIAoJCSAgICAqIGVsZW1lbnQgaW5mb3JtYXRpb24gaXRlbSBoYXMgbm8gY2hhcmFjdGVyIGluZm9ybWF0aW9uIAoJCSAgICAqIGl0ZW0gW2NoaWxkcmVuXSBvdGhlciB0aGFuIHRob3NlIHdob3NlIFtjaGFyYWN0ZXIgCgkJICAgICogY29kZV0gaXMgZGVmaW5lZCBhcyBhIHdoaXRlIHNwYWNlIGluIFtYTUwgMS4wIChTZWNvbmQgCgkJICAgICogRWRpdGlvbildLgoJCSAgICAqLwkJCQoJCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8zLAoJCQkiQ2hhcmFjdGVyIGNoaWxkcmVuIGFyZSBub3QgYWxsb3dlZCwgIgoJCQkiYmVjYXVzZSB0aGUgY29udGVudCB0eXBlIGlzIGVsZW1lbnQtb25seS5cbiIsCgkJCU5VTEwsIE5VTEwpOwkJICAgIAoJCSAgICBicmVhazsKCQl9CgkJY2hpbGQgPSBjaGlsZC0+bmV4dDsJCSAgICAKCSAgICB9ICAgICAgICAgICAgCSAgICAKICAgICAgICAgICAgYnJlYWs7CgljYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU6CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0NPTlRFTlRfQkFTSUM6ewoJICAgIHhtbFNjaGVtYVR5cGVQdHIgYmFzZSwgYW55VHlwZTsKCSAgICB4bWxDaGFyICp2YWx1ZSA9IE5VTEw7CgkgICAgLyoKCSAgICAqIFdlIGhpdCBhIGNvbXBsZXhUeXBlIHdpdGggYSBzaW1wbGVDb250ZW50IHJlc29sdmluZwoJICAgICogdG8gYSB1c2VyIGRlcml2ZWQgb3IgYnVpbHQtaW4gc2ltcGxlIHR5cGUuCgkgICAgKi8JCgkgICAgYW55VHlwZSA9IHhtbFNjaGVtYUdldEJ1aWx0SW5UeXBlKFhNTF9TQ0hFTUFTX0FOWVRZUEUpOwoJICAgIC8qCgkgICAgKiBJbnRlcm5hbCBjaGVjayBmb3IgaW50ZWdyaXR5IG9mIHRoZSBiYXNlIHR5cGUuCgkgICAgKi8JIAoJICAgIGJhc2UgPSB0eXBlLT5iYXNlVHlwZTsKCSAgICB3aGlsZSAoKGJhc2UgIT0gTlVMTCkgJiYgCgkJICAgKGJhc2UtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX1NJTVBMRSkgJiYKCQkgICAgKGJhc2UtPnR5cGUgIT0gWE1MX1NDSEVNQV9UWVBFX0JBU0lDKSAmJgoJCSAgICAoYmFzZSAhPSBhbnlUeXBlKSkgewoJCWJhc2UgPSBiYXNlLT5iYXNlVHlwZTsKCSAgICB9CgkgICAgaWYgKChiYXNlID09IE5VTEwpIHx8CgkJKCgodHlwZS0+Y29udGVudFR5cGUgPT0gWE1MX1NDSEVNQV9DT05URU5UX1NJTVBMRSkgJiYKCQkgIChiYXNlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9TSU1QTEUpKSB8fAoJCSAoKHR5cGUtPmNvbnRlbnRUeXBlID09IFhNTF9TQ0hFTUFfQ09OVEVOVF9CQVNJQykgJiYKCQkgIChiYXNlLT50eXBlICE9IFhNTF9TQ0hFTUFfVFlQRV9CQVNJQykpKSkgewoJCXhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCSAgICAiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlQ29tcGxleFR5cGUsICIKCQkgICAgIkVsZW1lbnQgXCIlc1wiOiB0aGUgYmFzZSB0eXBlIG9mIHRoZSBjb3JyZXNwb25kaW5nICIKCQkgICAgImNvbXBsZXggdHlwZSBcIiVzXCIgaXMgbm90IGEgdXNlciBkZXJpdmVkIG9yIGEgIgoJCSAgICAiYnVpbHQtaW4gc2ltcGxlIHR5cGUuXG4iLAoJCSAgICBub2RlLT5uYW1lLCB0eXBlLT5uYW1lKTsKCQlyZXR1cm4gKC0xKTsKCSAgICB9IAoJICAgIC8qIAoJICAgICogMi4yIElmIHRoZSB7Y29udGVudCB0eXBlfSBpcyBhIHNpbXBsZSB0eXBlIGRlZmluaXRpb24sIAoJICAgICogdGhlbiB0aGUgZWxlbWVudCBpbmZvcm1hdGlvbiBpdGVtIGhhcyBubyBlbGVtZW50IAoJICAgICogaW5mb3JtYXRpb24gaXRlbSBbY2hpbGRyZW5dLCBhbmQgdGhlILdub3JtYWxpemVkIHZhbHVltyAKCSAgICAqIG9mIHRoZSBlbGVtZW50IGluZm9ybWF0aW9uIGl0ZW0gaXMgt3ZhbGlktyB3aXRoIHJlc3BlY3QgCgkgICAgKiB0byB0aGF0IHNpbXBsZSB0eXBlIGRlZmluaXRpb24gYXMgZGVmaW5lZCBieSBTdHJpbmcgCgkgICAgKiBWYWxpZCAopzMuMTQuNCkuCgkgICAgKi8JICAgIAoJICAgIGNoaWxkID0gbm9kZS0+Y2hpbGRyZW47CgkgICAgd2hpbGUgKGNoaWxkICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIGlmIChjaGlsZC0+dHlwZSA9PSBYTUxfRUxFTUVOVF9OT0RFKSB7CgkJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8yXzIsCgkJCSAgICAiRWxlbWVudCBjaGlsZHJlbiBhcmUgbm90IGFsbG93ZWQsIGJlY2F1c2UgIgoJCQkgICAgInRoZSBjb250ZW50IHR5cGUgaXMgYSBzaW1wbGUgdHlwZS5cbiIsCQkJICAgIAoJCQkgICAgTlVMTCwgTlVMTCk7CgkJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8yOwoJCSAgICBicmVhazsKCQl9CgkJY2hpbGQgPSBjaGlsZC0+bmV4dDsJCSAgICAKCSAgICB9CSAgICAKCSAgICBpZiAocmV0ID09IDApIHsKCQkvKgoJCSogVmFsaWRhdGUgdGhlIGNoYXJhY3RlciBjb250ZW50IGFnYWluc3QgYSBzaW1wbGUgdHlwZS4KCQkqLwoJCWlmIChjdHh0LT5ub2RlID09IE5VTEwpCgkJICAgIHZhbHVlID0gTlVMTDsKCQllbHNlCgkJICAgIHZhbHVlID0geG1sTm9kZUdldENvbnRlbnQobm9kZSk7IAoJCWN0eHQtPnR5cGUgPSBiYXNlOwoJCXJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKGN0eHQsIHZhbHVlLCAxLCAxKTsKCQljdHh0LT50eXBlID0gdHlwZTsJICAgIAoJCWlmIChyZXQgPiAwKSB7CgkJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8yXzIsCgkJCSJUaGUgY2hhcmFjdGVyIHZhbHVlICIKCQkJImlzIG5vdCB2YWxpZCB3aXRoIHJlc3BlY3QgdG8gdGhlIHNpbXBsZSB0eXBlLlxuIiwKCQkJTlVMTCwgTlVMTCk7CgkJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8yOwoJCX0gZWxzZSBpZiAocmV0IDwgMCkgewoJCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIG5vZGUsIFhNTF9TQ0hFTUFTX0VSUl9JTlRFUk5BTCwKCQkJIkludGVybmFsIGVycm9yOiB4bWxTY2hlbWFWYWxpZGF0ZUNvbXBsZXhUeXBlLCAiCgkJCSJFbGVtZW50IFwiJXNcIjogZXJyb3Igd2hpbGUgdmFsaWRhdGluZyBjaGFyYWN0ZXIgIgoJCQkiY29udGVudCBhZ2FpbnN0IGNvbXBsZXggdHlwZSBcIiVzXCIuXG4iLAoJCQlub2RlLT5uYW1lLCB0eXBlLT5uYW1lKTsKCQkgICAgcmV0dXJuICgtMSk7CgkJfQoJICAgIH0KCSAgICBpZiAocmV0ID09IDApIHsKCQkvKiAKCQkqIEFwcGx5IGZhY2V0cyBvZiB0aGUgY29tcGxleFR5cGUuIEJlIHN1cmUgdG8gcGFzcyB0aGUgCgkJKiBidWlsdC1pbiB0eXBlIHRvIHhtbFNjaGVtYVZhbGlkYXRlRmFjZXRzSW50ZXJuYWwuCgkJKi8JICAgIAoJCS8qIFRPRE86IEkgZG9uJ3Qga25vdyB5ZXQgaWYgdGhlIGZhY2V0cyBvZiB0aGUgc2ltcGxlIHR5cGUKCQkqIGFyZSB1c2VkLCBvciBpZiB0aGUgZmFjZXRzLCBkZWZpbmVkIGJ5IHRoaXMgY29tcGxleCB0eXBlLAoJCSogYXJlIHRvIGJlIHVzZWQgb25seS4gVGhpcyBoZXJlIGFwcGxpZXMgYm90aCBmYWNldCBzZXRzLgoJCSovCSAgICAKCQl3aGlsZSAoYmFzZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQkFTSUMpCgkJICAgIGJhc2UgPSBiYXNlLT5iYXNlVHlwZTsKCQlpZiAoYmFzZSA9PSBOVUxMKSB7CgkJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlQ29tcGxleFR5cGUsICIKCQkJIkVsZW1lbnQgXCIlc1wiOiBlcnJvciB3aGlsZSB2YWxpZGF0aW5nIGNoYXJhY3RlciAiCgkJCSJjb250ZW50IGFnYWluc3QgY29tcGxleCB0eXBlIFwiJXNcIjsgZmFpbGVkIHRvICIKCQkJImNvbXB1dGUgdGhlIGJ1aWx0LWluIHNpbXBsZSB0eXBlIGZvciBmYWNldCAiCgkJCSJ2YWxpZGF0aW9uLlxuIiwKCQkJbm9kZS0+bmFtZSwgdHlwZS0+bmFtZSk7CgkJICAgIHJldHVybiAoLTEpOwoJCX0KCQlyZXQgPSB4bWxTY2hlbWFWYWxpZGF0ZUZhY2V0c0ludGVybmFsKGN0eHQsIGJhc2UsIAoJCSAgICB0eXBlLT5mYWNldFNldCwgdmFsdWUsIDEpOwoJCWlmIChyZXQgPiAwKSB7CgkJICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgbm9kZSwgWE1MX1NDSEVNQVZfQ1ZDX0NPTVBMRVhfVFlQRV8yXzIsCgkJCSJUaGUgY2hhcmFjdGVyIHZhbHVlICIKCQkJImlzIG5vdCB2YWxpZCB3aXRoIHJlc3BlY3QgdG8gdGhlIHNpbXBsZSB0eXBlLlxuIiwKCQkJTlVMTCwgTlVMTCk7CgkJICAgIHJldCA9IFhNTF9TQ0hFTUFWX0NWQ19DT01QTEVYX1RZUEVfMl8yOwoJCX0gZWxzZSBpZiAocmV0IDwgMCkgewoJCSAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGN0eHQtPmN1ciwgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCQkiSW50ZXJuYWwgZXJyb3I6IHhtbFNjaGVtYVZhbGlkYXRlQ29tcGxleFR5cGUsICIKCQkJIkVsZW1lbnQgXCIlc1wiOiBlcnJvciB3aGlsZSB2YWxpZGF0aW5nIGNoYXJhY3RlciAiCgkJCSJjb250ZW50IGFnYWluc3QgY29tcGxleCB0eXBlIFwiJXNcIjsgZmFpbGVkIHRvICIKCQkJImFwcGx5IGZhY2V0cy5cbiIsCgkJCXR5cGUtPm5hbWUsIE5VTEwpOwoJCX0KCSAgICB9CgkgICAgaWYgKHZhbHVlICE9IE5VTEwpCgkJeG1sRnJlZSh2YWx1ZSk7ICAgIAoJICAgIC8qIFRPRE86IGZhY2V0cyAqLwoJICAgIGJyZWFrOwoJfQoJLyoKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfQ09OVEVOVF9TSU1QTEU6ewkJIAogICAgICAgICAgICAgICAgaWYgKHR5cGUtPnN1YnR5cGVzICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBjdHh0LT50eXBlID0gdHlwZS0+c3VidHlwZXM7CiAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRhdGVDb21wbGV4VHlwZShjdHh0LCBub2RlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICh0eXBlLT5iYXNlVHlwZSAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgY3R4dC0+dHlwZSA9IHR5cGUtPmJhc2VUeXBlOwogICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkYXRlQ29tcGxleFR5cGUoY3R4dCwgbm9kZSk7CiAgICAgICAgICAgICAgICB9CgkJKiBSZW1vdmVkIGR1ZSB0byBjaGFuZ2VzIG9mIGF0dHJpYnV0ZSB2YWxpZGF0aW9uOgogICAgICAgICAgICAgICAgaWYgKHR5cGUtPmF0dHJpYnV0ZXMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkYXRlQXR0cmlidXRlcyhjdHh0LCBub2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLT5hdHRyaWJ1dGVzKTsKICAgICAgICAgICAgICAgIH0KCQkqCiAgICAgICAgICAgICAgICBjdHh0LT50eXBlID0gdHlwZTsKICAgICAgICAgICAgICAgIGJyZWFrOwoJfQoJKi8KICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBUT0RPIHhtbEdlbmVyaWNFcnJvcih4bWxHZW5lcmljRXJyb3JDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidW5pbXBsZW1lbnRlZCBjb250ZW50IHR5cGUgJWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPmNvbnRlbnRUeXBlKTsKICAgIH0KICAgIGlmICh0eXBlLT50eXBlID09IFhNTF9TQ0hFTUFfVFlQRV9DT01QTEVYKSB7Cgl4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXMoY3R4dCwgbm9kZSwgdHlwZSk7CiAgICB9CiAgICBjdHh0LT5jdXIgPSBub2RlOwogICAgcmV0dXJuIChjdHh0LT5lcnIpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVDb250ZW50OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZWxlbTogIGFuIGVsZW1lbnQKICogQHR5cGU6ICB0aGUgdHlwZSBkZWNsYXJhdGlvbgogKgogKiBWYWxpZGF0ZSB0aGUgY29udGVudCBvZiBhbiBlbGVtZW50IGFnYWluc3QgdGhlIHR5cGUuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZWxlbWVudCBpcyBzY2hlbWFzIHZhbGlkLCBhIHBvc2l0aXZlIGVycm9yIGNvZGUKICogICAgIG51bWJlciBvdGhlcndpc2UgYW5kIC0xIGluIGNhc2Ugb2YgaW50ZXJuYWwgb3IgQVBJIGVycm9yLgogKi8Kc3RhdGljIGludAp4bWxTY2hlbWFWYWxpZGF0ZUNvbnRlbnQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbE5vZGVQdHIgbm9kZSkKewogICAgeG1sTm9kZVB0ciBjaGlsZDsKICAgIHhtbFNjaGVtYVR5cGVQdHIgdHlwZTsKCiAgICBjaGlsZCA9IGN0eHQtPm5vZGU7CiAgICB0eXBlID0gY3R4dC0+dHlwZTsKICAgIGN0eHQtPmN1ciA9IG5vZGU7CgogICAgY3R4dC0+Y3VyID0gbm9kZTsKCiAgICBzd2l0Y2ggKHR5cGUtPnR5cGUpIHsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTlk6CiAgICAgICAgICAgIC8qIEFueSB0eXBlIHdpbGwgZG8gaXQsIGZpbmUgKi8KICAgICAgICAgICAgVE9ETyAgICAgICAgICAgICAgICAvKiBoYW5kbGUgcmVjdXJzaXZpdHkgKi8KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVg6CiAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkYXRlQ29tcGxleFR5cGUoY3R4dCwgbm9kZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0VMRU1FTlQ6ewogICAgICAgICAgICAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBkZWNsID0gKHhtbFNjaGVtYUVsZW1lbnRQdHIpIHR5cGU7CgogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIEhhbmRsZSBlbGVtZW50IHJlZmVyZW5jZSBoZXJlCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmIChkZWNsLT5yZWYgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIGlmIChkZWNsLT5yZWZEZWNsID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBub2RlLCBYTUxfU0NIRU1BU19FUlJfSU5URVJOQUwsCgkJCQkgICAgICAiSW50ZXJuYWwgZXJyb3I6IGVsZW1lbnQgcmVmZXJlbmNlICVzICIKCQkJCSAgICAgICJub3QgcmVzb2x2ZWRcbiIsIGRlY2wtPnJlZiwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoLTEpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjdHh0LT50eXBlID0gKHhtbFNjaGVtYVR5cGVQdHIpIGRlY2wtPnJlZkRlY2w7CiAgICAgICAgICAgICAgICAgICAgZGVjbCA9IGRlY2wtPnJlZkRlY2w7CiAgICAgICAgICAgICAgICB9CgkJLyogVE9ETzogU2hvdWxkICJ4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnQiIGJlIGNhbGxlZCBpbnN0ZWFkPyAqLwogICAgICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50VHlwZShjdHh0LCBub2RlKTsKICAgICAgICAgICAgICAgIGN0eHQtPnR5cGUgPSB0eXBlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9CQVNJQzoKCWNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRToKICAgICAgICAgICAgeG1sU2NoZW1hVmFsaWRhdGVTaW1wbGVUeXBlRWxlbWVudChjdHh0LCBub2RlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfRkFDRVQ6CiAgICAgICAgICAgIFRPRE8gYnJlYWs7ICAgICAgICAKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9TRVFVRU5DRToKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9DSE9JQ0U6CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQUxMOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX1NJTVBMRV9DT05URU5UOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0NPTVBMRVhfQ09OVEVOVDoKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9VUjoKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9SRVNUUklDVElPTjoKICAgICAgICAgICAgLyp4bWxTY2hlbWFWYWxpZGF0ZVJlc3RyaWN0aW9uVHlwZShjdHh0LCBub2RlKTsgKi8KICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9FWFRFTlNJT046CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfQVRUUklCVVRFOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0dST1VQOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX05PVEFUSU9OOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9UWVBFX0xJU1Q6CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX1RZUEVfVU5JT046CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTklOQ0xVU0lWRToKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTUlORVhDTFVTSVZFOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhJTkNMVVNJVkU6CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01BWEVYQ0xVU0lWRToKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfVE9UQUxESUdJVFM6CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX0ZSQUNUSU9ORElHSVRTOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9QQVRURVJOOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9FTlVNRVJBVElPTjoKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfV0hJVEVTUEFDRToKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfRkFDRVRfTEVOR1RIOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgICAgIGNhc2UgWE1MX1NDSEVNQV9GQUNFVF9NQVhMRU5HVEg6CiAgICAgICAgICAgIFRPRE8gYnJlYWs7CiAgICAgICAgY2FzZSBYTUxfU0NIRU1BX0ZBQ0VUX01JTkxFTkdUSDoKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BVFRSSUJVVEVHUk9VUDoKICAgICAgICAgICAgVE9ETyBicmVhazsKICAgICAgICBjYXNlIFhNTF9TQ0hFTUFfVFlQRV9BTllfQVRUUklCVVRFOgogICAgICAgICAgICBUT0RPIGJyZWFrOwogICAgfQoKICAgIGlmIChjdHh0LT5ub2RlID09IE5VTEwpCiAgICAgICAgcmV0dXJuIChjdHh0LT5lcnIpOwogICAgY3R4dC0+bm9kZSA9IGN0eHQtPm5vZGUtPm5leHQ7CiAgICBjdHh0LT50eXBlID0gdHlwZS0+bmV4dDsKICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlVHlwZToKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVsZW06ICBhbiBlbGVtZW50CiAqIEB0eXBlOiAgdGhlIGxpc3Qgb2YgdHlwZSBkZWNsYXJhdGlvbnMKICoKICogVmFsaWRhdGUgdGhlIGNvbnRlbnQgb2YgYW4gZWxlbWVudCBhZ2FpbnN0IHRoZSB0eXBlcy4KICoKICogUmV0dXJucyAwIGlmIHRoZSBlbGVtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlVHlwZSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwgeG1sTm9kZVB0ciBlbGVtLAogICAgICAgICAgICAgICAgICAgICAgeG1sU2NoZW1hRWxlbWVudFB0ciBlbGVtRGVjbCwgeG1sU2NoZW1hVHlwZVB0ciB0eXBlKQp7CiAgICB4bWxDaGFyICpuaWw7CgogICAgaWYgKChlbGVtID09IE5VTEwpIHx8ICh0eXBlID09IE5VTEwpIHx8IChlbGVtRGVjbCA9PSBOVUxMKSkKICAgICAgICByZXR1cm4gKDApOwoKICAgIC8qIFRoaXMgb25lIGlzIGNhbGxlZCBieSAieG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50VHlwZSIgYW5kCiAgICAgKiAieG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50Ii4KICAgICAqLwoKICAgIC8qCiAgICAgKiAzLjMuNCA6IDIKICAgICAqLwogICAgaWYgKGVsZW1EZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fQUJTVFJBQ1QpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGVsZW0sIFhNTF9TQ0hFTUFTX0VSUl9JU0FCU1RSQUNULAoJCSAgICAgICJFbGVtZW50IGRlY2xhcmF0aW9uICVzIGlzIGFic3RyYWN0XG4iLAoJCSAgICAgIGVsZW1EZWNsLT5uYW1lLCBOVUxMKTsKCS8qIENoYW5nZWQsIHNpbmNlIHRoZSBlbGVtZW50IGRlY2xhcmF0aW9uIGlzIGFic3RyYWN0IGFuZCBub3QKCSAqIHRoZSBlbGVtZW50IGl0c2VsZi4gKi8KCS8qIHhtbFNjaGVtYVZFcnIoY3R4dCwgZWxlbSwgWE1MX1NDSEVNQVNfRVJSX0lTQUJTVFJBQ1QsCgkJCSAiRWxlbWVudCAlcyBpcyBhYnN0cmFjdFxuIiwgZWxlbS0+bmFtZSwgTlVMTCk7ICovCiAgICAgICAgcmV0dXJuIChjdHh0LT5lcnIpOwogICAgfQogICAgLyoKICAgICAqIDMuMy40OiAzCiAgICAgKi8KICAgIG5pbCA9IHhtbEdldE5zUHJvcChlbGVtLCBCQURfQ0FTVCAibmlsIiwgeG1sU2NoZW1hSW5zdGFuY2VOcyk7CiAgICBpZiAoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9OSUxMQUJMRSkgewogICAgICAgIC8qIDMuMy40OiAzLjIgKi8KICAgICAgICBpZiAoeG1sU3RyRXF1YWwobmlsLCBCQURfQ0FTVCAidHJ1ZSIpKSB7CiAgICAgICAgICAgIGlmIChlbGVtLT5jaGlsZHJlbiAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGVsZW0sIFhNTF9TQ0hFTUFTX0VSUl9OT1RFTVBUWSwKCQkJICAgICAgIkVsZW1lbnQgJXMgaXMgbm90IGVtcHR5XG4iLCBlbGVtLT5uYW1lLCBOVUxMKTsKICAgICAgICAgICAgICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoKGVsZW1EZWNsLT5mbGFncyAmIFhNTF9TQ0hFTUFTX0VMRU1fRklYRUQpICYmCiAgICAgICAgICAgICAgICAoZWxlbURlY2wtPnZhbHVlICE9IE5VTEwpKSB7CiAgICAgICAgICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGVsZW0sIFhNTF9TQ0hFTUFTX0VSUl9IQVZFREVGQVVMVCwKCQkJICAgICAgIkVtcHR5IGVsZW1lbnQgJXMgY2Fubm90IGdldCBhIGZpeGVkIHZhbHVlXG4iLAoJCQkgICAgICBlbGVtLT5uYW1lLCBOVUxMKTsKICAgICAgICAgICAgICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgLyogMy4zLjQ6IDMuMSAqLwogICAgICAgIGlmIChuaWwgIT0gTlVMTCkgewogICAgICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGVsZW0sIFhNTF9TQ0hFTUFTX0VSUl9OT1ROSUxMQUJMRSwKCSAgICAJCSAgIkVsZW1lbnQgJXMgd2l0aCB4czpuaWwgYnV0IG5vdCBuaWxsYWJsZVxuIiwKCQkJICBlbGVtLT5uYW1lLCBOVUxMKTsKICAgICAgICAgICAgeG1sRnJlZShuaWwpOwogICAgICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFRPRE8gMy4zLjQ6IDQgaWYgdGhlIGVsZW1lbnQgY2FycmllcyB4czp0eXBlICovCgogICAgY3R4dC0+dHlwZSA9IGVsZW1EZWNsLT5zdWJ0eXBlczsKICAgIGN0eHQtPm5vZGUgPSBlbGVtLT5jaGlsZHJlbjsKICAgIHhtbFNjaGVtYVZhbGlkYXRlQ29udGVudChjdHh0LCBlbGVtKTsgICAKICAgIHJldHVybiAoY3R4dC0+ZXJyKTsKfQoKCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUF0dHJpYnV0ZXM6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlbGVtOiAgYW4gZWxlbWVudAogKiBAdHlwZTogIHRoZSBjb21wbGV4VHlwZSBob2xkaW5nIHRoZSBhdHRyaWJ1dGUgdXNlcwogKgogKiBWYWxpZGF0ZSB0aGUgYXR0cmlidXRlcyBvZiBhbiBlbGVtZW50LgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVBdHRyaWJ1dGVzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIGVsZW0sIHhtbFNjaGVtYVR5cGVQdHIgdHlwZSkKewogICAgaW50IHJldDsKICAgIHhtbEF0dHJQdHIgYXR0cjsgLyogQW4gYXR0cmlidXRlIG9uIHRoZSBlbGVtZW50LiAqLwogICAgeG1sQ2hhciAqdmFsdWU7CiAgICBjb25zdCB4bWxDaGFyICpuc1VSSTsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZUxpbmtQdHIgYXR0clVzZTsKICAgIHhtbFNjaGVtYUF0dHJpYnV0ZVB0ciBhdHRyRGVjbDsKICAgIGludCBmb3VuZDsKICAgIHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciBjdXJTdGF0ZSwgcmVxQXR0clN0YXRlcyA9IE5VTEwsIHJlcUF0dHJTdGF0ZXNUb3AgPSBOVUxMOwojaWZkZWYgREVCVUdfQVRUUl9WQUxJREFUSU9OCiAgICBpbnQgcmVkdW5kYW50ID0gMDsKI2VuZGlmCiAgICBpZiAodHlwZS0+dHlwZSAhPSBYTUxfU0NIRU1BX1RZUEVfQ09NUExFWCkgewoJeG1sU2NoZW1hVkVycihjdHh0LCBlbGVtLCBYTUxfU0NIRU1BU19FUlJfSU5URVJOQUwsCgkJCSAgICAgICJJbnRlcm5hbCBlcnJvcjogeG1sU2NoZW1hVmFsaWRhdGVBdHRyaWJ1dGVzOiAiCgkJCSAgICAgICJnaXZlbiB0eXBlIFwiJXNcImlzIG5vdCBhIGNvbXBsZXhUeXBlXG4iLAoJCQkgICAgICB0eXBlLT5uYW1lLCBOVUxMKTsKCXJldHVybigtMSk7CiAgICB9ICAgIAoKICAgIGlmICgodHlwZS0+YXR0cmlidXRlVXNlcyA9PSBOVUxMKSAmJiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuICgwKTsKCiAgICBhdHRyVXNlID0gdHlwZS0+YXR0cmlidXRlVXNlczsKCiAgICB3aGlsZSAoYXR0clVzZSAhPSBOVUxMKSB7CiAgICAgICAgZm91bmQgPSAwOyAgICAKCWF0dHJEZWNsID0gYXR0clVzZS0+YXR0cjsKI2lmZGVmIERFQlVHX0FUVFJfVkFMSURBVElPTgoJcHJpbnRmKCJhdHRyIHVzZSAtIG5hbWU6ICVzXG4iLCB4bWxTY2hlbWFHZXRPbnltb3VzQXR0ck5hbWUoYXR0ckRlY2wpKTsKCXByaW50ZigiYXR0ciB1c2UgLSB1c2U6ICVkXG4iLCBhdHRyRGVjbC0+b2NjdXJzKTsKI2VuZGlmCiAgICAgICAgZm9yIChjdXJTdGF0ZSA9IGN0eHQtPmF0dHI7IGN1clN0YXRlICE9IE5VTEw7IGN1clN0YXRlID0gY3VyU3RhdGUtPm5leHQpIHsJCSAgICAKCgkgICAgaWYgKGN1clN0YXRlLT5kZWNsID09IGF0dHJVc2UtPmF0dHIpIHsKI2lmZGVmIERFQlVHX0FUVFJfVkFMSURBVElPTgoJCXJlZHVuZGFudCA9IDE7CiNlbmRpZgogICAgICAgIH0KCSAgICBhdHRyID0gY3VyU3RhdGUtPmF0dHI7CiNpZmRlZiBERUJVR19BVFRSX1ZBTElEQVRJT04KCSAgICBwcmludGYoImF0dHIgLSBuYW1lOiAlc1xuIiwgYXR0ci0+bmFtZSk7CgkgICAgaWYgKGF0dHItPm5zICE9IE5VTEwpCgkJcHJpbnRmKCJhdHRyIC0gbnM6ICVzXG4iLCBhdHRyLT5ucy0+aHJlZik7CgkgICAgZWxzZQoJCXByaW50ZigiYXR0ciAtIG5zOiBub25lXG4iKTsKI2VuZGlmCgkgICAgLyogVE9ETzogQ2FuIHRoaXMgZXZlciBoYXBwZW4/ICovCiAgICAgICAgICAgIGlmIChhdHRyID09IE5VTEwpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgaWYgKGF0dHJEZWNsLT5yZWYgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgaWYgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBhdHRyRGVjbC0+cmVmKSkKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIGlmIChhdHRyLT5ucyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKChhdHRyRGVjbC0+cmVmTnMgPT0gTlVMTCkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgKCF4bWxTdHJFcXVhbChhdHRyLT5ucy0+aHJlZiwgYXR0ckRlY2wtPnJlZk5zKSkpCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChhdHRyRGVjbC0+cmVmTnMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgaWYgKCF4bWxTdHJFcXVhbChhdHRyLT5uYW1lLCBhdHRyRGVjbC0+bmFtZSkpCiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogaGFuZGxlIHRoZSBuYW1lc3BhY2VzIGNoZWNrcyBoZXJlCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmIChhdHRyLT5ucyA9PSBOVUxMKSB7CgkJICAgIC8qCgkJICAgICAqIGFjY2VwdCBhbiB1bnF1YWxpZmllZCBhdHRyaWJ1dGUgb25seSBpZiB0aGUgdGFyZ2V0CgkJICAgICAqIG5hbWVzcGFjZSBvZiB0aGUgZGVjbGFyYXRpb24gaXMgYWJzZW50LgoJCSAgICAgKi8KCQkgICAgaWYgKGF0dHJEZWNsLT50YXJnZXROYW1lc3BhY2UgIT0gTlVMTCkKCQkJLyogCgkJCSAqIFRoaXMgY2hlY2sgd2FzIHJlbW92ZWQsIHNpbmNlIHRoZSB0YXJnZXQgbmFtZXNwYWNlCgkJCSAqIHdhcyBldmFsdWF0ZWQgZHVyaW5nIHBhcnNpbmcgYW5kIGFscmVhZHkgdG9vawoJCQkgKiAiYXR0cmlidXRlRm9ybURlZmF1bHQiIGludG8gYWNjb3VudC4KCQkJICovCgkJICAgICAgICAvKiAoKGF0dHJpYnV0ZXMtPmZsYWdzICYgWE1MX1NDSEVNQVNfQVRUUl9OU0RFRkFVTFQpID09IDApKSAqLwoJCSAgICAgICAgY29udGludWU7CgkJfSBlbHNlIHsKCQkgICAgaWYgKGF0dHJEZWNsLT50YXJnZXROYW1lc3BhY2UgPT0gTlVMTCkKCQkgICAgICAgIGNvbnRpbnVlOwoJCSAgICBpZiAoIXhtbFN0ckVxdWFsKGF0dHJEZWNsLT50YXJnZXROYW1lc3BhY2UsCgkJICAgICAgICAgICAgICAgICAgICAgYXR0ci0+bnMtPmhyZWYpKQoJCQljb250aW51ZTsKCQl9CiAgICAgICAgICAgIH0KI2lmZGVmIERFQlVHX0FUVFJfVkFMSURBVElPTgoJICAgIHByaW50ZigiZm91bmRcbiIpOwojZW5kaWYKICAgICAgICAgICAgZm91bmQgPSAxOwogICAgICAgICAgICBjdHh0LT5jdXIgPSAoeG1sTm9kZVB0cikgYXR0cjsKCSAgICBjdHh0LT5ub2RlID0gYXR0ci0+Y2hpbGRyZW47CgogICAgICAgICAgICBpZiAoYXR0ckRlY2wtPnN1YnR5cGVzID09IE5VTEwpIHsKCQljdXJTdGF0ZS0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX1RZUEVfTk9UX1JFU09MVkVEOwoJCWN1clN0YXRlLT5kZWNsID0gYXR0ckRlY2w7CgkJLyogCgkJICogVGhpcyBjb3VsZCBiZSBwdXQgaW50byAieG1sU2NoZW1hQ2hlY2tBdHRyaWJ1dGVzIiBhcyB3ZWxsLCBidXQKCQkgKiBzaW5jZSBpdCByZXBvcnRzIGFuIGludGVybmFsIGVycm9yLCBpdCBiZXR0ZXIgc3RheXMgaGVyZSB0byBlYXNlCgkJICogZGVidWdnaW5nLgoJCSAqLwogICAgICAgICAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCAoeG1sTm9kZVB0cikgYXR0ciwgWE1MX1NDSEVNQVNfRVJSX0lOVEVSTkFMLAoJCQkgICAgICAiSW50ZXJuYWwgZXJyb3I6IGF0dHJpYnV0ZSAlcyB0eXBlIG5vdCByZXNvbHZlZFxuIiwKCQkJICAgICAgYXR0ci0+bmFtZSwgTlVMTCk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YWx1ZSA9IHhtbE5vZGVMaXN0R2V0U3RyaW5nKGVsZW0tPmRvYywgYXR0ci0+Y2hpbGRyZW4sIDEpOwoJICAgIGN0eHQtPnR5cGUgPSBhdHRyRGVjbC0+c3VidHlwZXM7CiAgICAgICAgICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKGN0eHQsIHZhbHVlLCAwLCAxKTsKCSAgICBjdHh0LT50eXBlID0gdHlwZTsKICAgICAgICAgICAgaWYgKHJldCAhPSAwKSAKCQljdXJTdGF0ZS0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0lOVkFMSURfVkFMVUU7ICAgCQkJCQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBjdXJTdGF0ZS0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0NIRUNLRUQ7CgkgICAgY3VyU3RhdGUtPmRlY2wgPSBhdHRyRGVjbDsKICAgICAgICAgICAgaWYgKHZhbHVlICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIHhtbEZyZWUodmFsdWUpOwogICAgICAgICAgICB9CSAgICAKICAgICAgICB9CiAgICAgICAgaWYgKCghZm91bmQpICYmIChhdHRyRGVjbC0+b2NjdXJzID09IFhNTF9TQ0hFTUFTX0FUVFJfVVNFX1JFUVVJUkVEKSkgewoJICAgIHhtbFNjaGVtYUF0dHJTdGF0ZVB0ciB0bXA7CgojaWZkZWYgREVCVUdfQVRUUl9WQUxJREFUSU9OCgkgICAgcHJpbnRmKCJyZXF1aXJlZCBhdHRyIG5vdCBmb3VuZFxuIik7CiNlbmRpZgoJICAgIC8qCgkgICAgICogQWRkIGEgbmV3IGR1bW15IGF0dHJpYnV0ZSBzdGF0ZS4KCSAgICAgKi8JCgkgICAgdG1wID0gKHhtbFNjaGVtYUF0dHJTdGF0ZVB0cikgeG1sTWFsbG9jKHNpemVvZih4bWxTY2hlbWFBdHRyU3RhdGUpKTsKCSAgICBpZiAodG1wID09IE5VTEwpIHsKCQl4bWxTY2hlbWFWRXJyTWVtb3J5KGN0eHQsICJyZWdpc3RlcmluZyByZXF1aXJlZCBhdHRyaWJ1dGVzIiwgTlVMTCk7CgkJcmV0dXJuICgtMSk7CiAgICAgICAgICAgIH0gICAgICAgICAgICAKCSAgICB0bXAtPmF0dHIgPSBOVUxMOwoJICAgIHRtcC0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX01JU1NJTkc7CgkgICAgdG1wLT5kZWNsID0gYXR0ckRlY2w7CgkgICAgdG1wLT5uZXh0ID0gTlVMTDsKICAgICAgICAgCgkgICAgaWYgKHJlcUF0dHJTdGF0ZXMgPT0gTlVMTCkgewoJCXJlcUF0dHJTdGF0ZXMgPSB0bXA7CgkJcmVxQXR0clN0YXRlc1RvcCA9IHRtcDsKICAgICAgICAgICAgfSBlbHNlIHsKCQlyZXFBdHRyU3RhdGVzVG9wLT5uZXh0ID0gdG1wOwoJCXJlcUF0dHJTdGF0ZXNUb3AgPSB0bXA7CiAgICAgICAgICAgIH0KCQoJfQogICAgICAgIGF0dHJVc2UgPSBhdHRyVXNlLT5uZXh0OwogICAgfQogICAgLyoKICAgICAqIEFkZCByZXF1aXJlZCBhdHRyaWJ1dGVzIHRvIHRoZSBhdHRyaWJ1dGUgc3RhdGVzIG9mIHRoZSBjb250ZXh0LgogICAgICovCiAgICBpZiAocmVxQXR0clN0YXRlcyAhPSBOVUxMKSB7CglpZiAoY3R4dC0+YXR0ciA9PSBOVUxMKSB7CgkgICAgY3R4dC0+YXR0ciA9IHJlcUF0dHJTdGF0ZXM7Cgl9IGVsc2UgewkJCgkgICAgY3R4dC0+YXR0clRvcC0+bmV4dCA9IHJlcUF0dHJTdGF0ZXM7Cgl9CgljdHh0LT5hdHRyVG9wID0gcmVxQXR0clN0YXRlc1RvcDsKICAgICAgICAgICAgfQogICAgLyoKICAgICogUHJvY2VzcyB3aWxkY2FyZHMuCiAgICAqLwogICAgaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkICE9IE5VTEwpIHsJCiNpZmRlZiBERUJVR19BVFRSX1ZBTElEQVRJT04KCXhtbFNjaGVtYVdpbGRjYXJkTnNQdHIgbnM7CQoJcHJpbnRmKCJtYXRjaGluZyB3aWxkY2FyZDogWyVkXSBvZiBjb21wbGV4VHlwZTogJXNcbiIsIHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLCB0eXBlLT5uYW1lKTsKCWlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+cHJvY2Vzc0NvbnRlbnRzID09IAoJICAgIFhNTF9TQ0hFTUFTX0FOWV9MQVgpCgkgICAgcHJpbnRmKCJwcm9jZXNzQ29udGVudHM6IGxheFxuIik7CgllbHNlIGlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+cHJvY2Vzc0NvbnRlbnRzID09IAoJICAgIFhNTF9TQ0hFTUFTX0FOWV9TVFJJQ1QpCgkgICAgcHJpbnRmKCJwcm9jZXNzQ29udGVudHM6IHN0cmljdFxuIik7CgllbHNlCgkgICAgcHJpbnRmKCJwcm9jZXNzQ29udGVudHM6IHNraXBcbiIpOwoJaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5hbnkpCgkgICAgcHJpbnRmKCJ0eXBlOiBhbnlcbiIpOwoJZWxzZSBpZiAodHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPm5lZ05zU2V0ICE9IE5VTEwpIHsKCSAgICBwcmludGYoInR5cGU6IG5lZ2F0ZWRcbiIpOwoJICAgIGlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+bmVnTnNTZXQtPnZhbHVlID09IE5VTEwpCgkJcHJpbnRmKCJuczogKGFic2VudClcbiIpOwoJICAgIGVsc2UKCQlwcmludGYoIm5zOiAlc1xuIiwgdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPm5lZ05zU2V0LT52YWx1ZSk7Cgl9IGVsc2UgaWYgKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5uc1NldCAhPSBOVUxMKSB7CgkgICAgcHJpbnRmKCJ0eXBlOiBzZXRcbiIpOwoJICAgIG5zID0gdHlwZS0+YXR0cmlidXRlV2lsZGNhcmQtPm5zU2V0OwoJICAgIHdoaWxlIChucyAhPSBOVUxMKSB7CgkJaWYgKG5zLT52YWx1ZSA9PSBOVUxMKQoJCSAgICBwcmludGYoIm5zOiAoYWJzZW50KVxuIik7CgkJZWxzZQoJCSAgICBwcmludGYoIm5zOiAlc1xuIiwgbnMtPnZhbHVlKTsKCQlucyA9IG5zLT5uZXh0OwoJICAgIH0JICAgIAoJfSBlbHNlCgkgICAgcHJpbnRmKCJlbXB0eVxuIik7CgoKI2VuZGlmCQoJY3VyU3RhdGUgPSBjdHh0LT5hdHRyOwoJd2hpbGUgKGN1clN0YXRlICE9IE5VTEwpIHsKCSAgICBpZiAoY3VyU3RhdGUtPnN0YXRlID09IFhNTF9TQ0hFTUFTX0FUVFJfVU5LTk9XTikgewkJCgkJaWYgKGN1clN0YXRlLT5hdHRyLT5ucyAhPSBOVUxMKSAKCQkgICAgbnNVUkkgPSBjdXJTdGF0ZS0+YXR0ci0+bnMtPmhyZWY7CgkJZWxzZQoJCSAgICBuc1VSSSA9IE5VTEw7CQkKCQlpZiAoeG1sU2NoZW1hTWF0Y2hlc1dpbGRjYXJkTnModHlwZS0+YXR0cmlidXRlV2lsZGNhcmQsIAoJCSAgICBuc1VSSSkpIHsKCQkgICAgLyoKCQkgICAgKiBIYW5kbGUgcHJvY2Vzc0NvbnRlbnRzLgoJCSAgICAqLwoJCSAgICBpZiAoKHR5cGUtPmF0dHJpYnV0ZVdpbGRjYXJkLT5wcm9jZXNzQ29udGVudHMgPT0gCgkJCVhNTF9TQ0hFTUFTX0FOWV9MQVgpIHx8CgkJCSh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+cHJvY2Vzc0NvbnRlbnRzID09IAoJCQlYTUxfU0NIRU1BU19BTllfU1RSSUNUKSkgewoJCQkKCQkJYXR0ciA9IGN1clN0YXRlLT5hdHRyOwkJCQkJCQoJCQlhdHRyRGVjbCA9IHhtbFNjaGVtYUdldEF0dHJpYnV0ZShjdHh0LT5zY2hlbWEsIAoJCQkgICAgYXR0ci0+bmFtZSwgbnNVUkkpOwkJCgkJCWlmIChhdHRyRGVjbCAhPSBOVUxMKSB7CgkJCSAgICB2YWx1ZSA9IHhtbE5vZGVMaXN0R2V0U3RyaW5nKGVsZW0tPmRvYywgYXR0ci0+Y2hpbGRyZW4sIDEpOwoJCQkgICAgY3R4dC0+dHlwZSA9IGF0dHJEZWNsLT5zdWJ0eXBlczsKCQkJICAgIHJldCA9IHhtbFNjaGVtYVZhbGlkYXRlU2ltcGxlVHlwZVZhbHVlKGN0eHQsIHZhbHVlLCAxLCAxKTsKCQkJICAgIGN0eHQtPnR5cGUgPSB0eXBlOwoJCQkgICAgaWYgKHJldCAhPSAwKSAKCQkJCWN1clN0YXRlLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfSU5WQUxJRF9WQUxVRTsgICAJCQkJCgkJCSAgICBlbHNlCgkJCQljdXJTdGF0ZS0+c3RhdGUgPSBYTUxfU0NIRU1BU19BVFRSX0NIRUNLRUQ7CgkJCSAgICBjdXJTdGF0ZS0+ZGVjbCA9IGF0dHJEZWNsOwoJCQkgICAgaWYgKHZhbHVlICE9IE5VTEwpIHsKCQkJCXhtbEZyZWUodmFsdWUpOwoJCQkgICAgfQkgICAgCgkJCSAgICAKCQkJfSBlbHNlIGlmICh0eXBlLT5hdHRyaWJ1dGVXaWxkY2FyZC0+cHJvY2Vzc0NvbnRlbnRzID09IAoJCQkgICAgWE1MX1NDSEVNQVNfQU5ZX0xBWCkgewoJCQkgICAgY3VyU3RhdGUtPnN0YXRlID0gWE1MX1NDSEVNQVNfQVRUUl9DSEVDS0VEOwoJCQl9CQkJCQkJCQkJCQkKCQkgICAgfSBlbHNlCgkJCWN1clN0YXRlLT5zdGF0ZSA9IFhNTF9TQ0hFTUFTX0FUVFJfQ0hFQ0tFRDsKCQl9CQkKCSAgICB9CgkgICAgY3VyU3RhdGUgPSBjdXJTdGF0ZS0+bmV4dDsKICAgICAgICB9CiAgICB9CiNpZmRlZiBERUJVR19BVFRSX1ZBTElEQVRJT04KICAgIGlmIChyZWR1bmRhbnQpCgl4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwKCSAgICAgICAgICAgICAgICAieG1sU2NoZW1hVmFsaWRhdGVBdHRyaWJ1dGVzOiByZWR1bmRhbnQgY2FsbCBieSB0eXBlOiAlc1xuIiwKCSAgICAgICAgICAgICAgICB0eXBlLT5uYW1lKTsKI2VuZGlmCiAgICByZXR1cm4gKGN0eHQtPmVycik7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnQ6CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBlbGVtOiAgYW4gZWxlbWVudAogKgogKiBWYWxpZGF0ZSBhbiBlbGVtZW50IGluIGEgdHJlZQogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGVsZW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCnN0YXRpYyBpbnQKeG1sU2NoZW1hVmFsaWRhdGVFbGVtZW50KHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LCB4bWxOb2RlUHRyIGVsZW0pCnsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2w7CiAgICBpbnQgcmV0OwogICAgeG1sU2NoZW1hQXR0clN0YXRlUHRyIGF0dHJzLCBhdHRyVG9wOwoKICAgIGlmIChlbGVtLT5ucyAhPSBOVUxMKSB7CiAgICAgICAgZWxlbURlY2wgPSB4bWxIYXNoTG9va3VwMyhjdHh0LT5zY2hlbWEtPmVsZW1EZWNsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxlbS0+bmFtZSwgZWxlbS0+bnMtPmhyZWYsIE5VTEwpOwogICAgfSBlbHNlIHsKICAgICAgICBlbGVtRGVjbCA9IHhtbEhhc2hMb29rdXAzKGN0eHQtPnNjaGVtYS0+ZWxlbURlY2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtLT5uYW1lLCBOVUxMLCBOVUxMKTsKICAgIH0KICAgIC8qIFRoaXMgb25lIGlzIGNhbGxlZCBieSB4bWxTY2hlbWFWYWxpZGF0ZURvY3VtZW50IG9ubHkuICovCgogICAgLyoKICAgICAqIDMuMy40IDogMQogICAgICovCiAgICBpZiAoZWxlbURlY2wgPT0gTlVMTCkgewogICAgICAgIHhtbFNjaGVtYVZFcnIoY3R4dCwgZWxlbSwgWE1MX1NDSEVNQVNfRVJSX1VOREVDTEFSRURFTEVNLAoJCSAgICAgICJFbGVtZW50ICVzIG5vdCBkZWNsYXJlZFxuIiwgZWxlbS0+bmFtZSwgTlVMTCk7CiAgICAgICAgcmV0dXJuIChjdHh0LT5lcnIpOwogICAgfQogICAgaWYgKGVsZW1EZWNsLT5zdWJ0eXBlcyA9PSBOVUxMKSB7CiAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBlbGVtLCBYTUxfU0NIRU1BU19FUlJfTk9UWVBFLAoJCSAgICAgICJFbGVtZW50ICVzIGhhcyBubyB0eXBlXG4iLCBlbGVtLT5uYW1lLCBOVUxMKTsKICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICB9CiAgICAvKgogICAgICogVmVyaWZ5IHRoZSBhdHRyaWJ1dGVzCiAgICAgKi8KICAgIGF0dHJzID0gY3R4dC0+YXR0cjsKICAgIGF0dHJUb3AgPSBjdHh0LT5hdHRyVG9wOwogICAgeG1sU2NoZW1hUmVnaXN0ZXJBdHRyaWJ1dGVzKGN0eHQsIGVsZW0tPnByb3BlcnRpZXMpOwogICAgLyoKICAgICAqIFZlcmlmeSB0aGUgZWxlbWVudCBjb250ZW50IHJlY3Vyc2l2ZWx5CiAgICAgKi8KICAgIGlmIChlbGVtRGVjbC0+Y29udE1vZGVsICE9IE5VTEwpIHsKICAgICAgICBjdHh0LT5yZWdleHAgPSB4bWxSZWdOZXdFeGVjQ3R4dChlbGVtRGVjbC0+Y29udE1vZGVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh4bWxSZWdFeGVjQ2FsbGJhY2tzKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkYXRlQ2FsbGJhY2ssIGN0eHQpOwojaWZkZWYgREVCVUdfQVVUT01BVEEKICAgICAgICB4bWxHZW5lcmljRXJyb3IoeG1sR2VuZXJpY0Vycm9yQ29udGV4dCwgIj09PT0+ICVzXG4iLCBlbGVtLT5uYW1lKTsKI2VuZGlmCiAgICB9CiAgICB4bWxTY2hlbWFWYWxpZGF0ZVR5cGUoY3R4dCwgZWxlbSwgZWxlbURlY2wsIGVsZW1EZWNsLT5zdWJ0eXBlcyk7CiAgICBpZiAoZWxlbURlY2wtPmNvbnRNb2RlbCAhPSBOVUxMKSB7CiAgICAgICAgcmV0ID0geG1sUmVnRXhlY1B1c2hTdHJpbmcoY3R4dC0+cmVnZXhwLCBOVUxMLCBOVUxMKTsKI2lmZGVmIERFQlVHX0FVVE9NQVRBCiAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICI9PT09PiAlcyA6ICVkXG4iLCBlbGVtLT5uYW1lLCByZXQpOwojZW5kaWYKICAgICAgICBpZiAocmV0ID09IDApIHsKICAgICAgICAgICAgeG1sU2NoZW1hVkVycihjdHh0LCBlbGVtLCBYTUxfU0NIRU1BU19FUlJfRUxFTUNPTlQsCgkgICAgCQkgICJFbGVtZW50ICVzIGNvbnRlbnQgY2hlY2sgZmFpbGVkXG4iLAoJCQkgIGVsZW0tPm5hbWUsIE5VTEwpOwogICAgICAgIH0gZWxzZSBpZiAocmV0IDwgMCkgewogICAgICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIGVsZW0sIFhNTF9TQ0hFTUFTX0VSUl9FTEVNQ09OVCwKCSAgICAJCSAgIkVsZW1lbnQgJXMgY29udGVudCBjaGVjayBmYWlsZWRcbiIsCgkJCSAgZWxlbS0+bmFtZSwgTlVMTCk7CiNpZmRlZiBERUJVR19DT05URU5UCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgeG1sR2VuZXJpY0Vycm9yKHhtbEdlbmVyaWNFcnJvckNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRWxlbWVudCAlcyBjb250ZW50IGNoZWNrIHN1Y2NlZWRlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW0tPm5hbWUpOwoKI2VuZGlmCiAgICAgICAgfQogICAgICAgIHhtbFJlZ0ZyZWVFeGVjQ3R4dChjdHh0LT5yZWdleHApOwogICAgfQogICAgLyoKICAgICAqIFZlcmlmeSB0aGF0IGFsbCBhdHRyaWJ1dGVzIHdlcmUgU2NoZW1hcy12YWxpZGF0ZWQKICAgICAqLwogICAgeG1sU2NoZW1hQ2hlY2tBdHRyaWJ1dGVzKGN0eHQsIGVsZW0pOwogICAgaWYgKGN0eHQtPmF0dHIgIT0gTlVMTCkKCXhtbFNjaGVtYUZyZWVBdHRyaWJ1dGVTdGF0ZXMoY3R4dC0+YXR0cik7CiAgICBjdHh0LT5hdHRyID0gYXR0cnM7CiAgICBjdHh0LT5hdHRyVG9wID0gYXR0clRvcDsKCiAgICByZXR1cm4gKGN0eHQtPmVycik7Cn0KCi8qKgogKiB4bWxTY2hlbWFWYWxpZGF0ZURvY3VtZW50OgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZG9jOiAgYSBwYXJzZWQgZG9jdW1lbnQgdHJlZQogKgogKiBWYWxpZGF0ZSBhIGRvY3VtZW50IHRyZWUgaW4gbWVtb3J5LgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGRvY3VtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwpzdGF0aWMgaW50CnhtbFNjaGVtYVZhbGlkYXRlRG9jdW1lbnQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbERvY1B0ciBkb2MpCnsKICAgIHhtbE5vZGVQdHIgcm9vdDsKICAgIHhtbFNjaGVtYUVsZW1lbnRQdHIgZWxlbURlY2w7CiAgICAgCiAgICByb290ID0geG1sRG9jR2V0Um9vdEVsZW1lbnQoZG9jKTsKICAgIGlmIChyb290ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsICh4bWxOb2RlUHRyKSBkb2MsIFhNTF9TQ0hFTUFTX0VSUl9OT1JPT1QsCgkJICAgICAgImRvY3VtZW50IGhhcyBubyByb290XG4iLCBOVUxMLCBOVUxMKTsKICAgICAgICByZXR1cm4gKGN0eHQtPmVycik7CiAgICB9CiAgICAKICAgIGlmIChyb290LT5ucyAhPSBOVUxMKQogICAgICAgIGVsZW1EZWNsID0geG1sSGFzaExvb2t1cDMoY3R4dC0+c2NoZW1hLT5lbGVtRGVjbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvb3QtPm5hbWUsIHJvb3QtPm5zLT5ocmVmLCBOVUxMKTsKICAgIGVsc2UKICAgICAgICBlbGVtRGVjbCA9IHhtbEhhc2hMb29rdXAzKGN0eHQtPnNjaGVtYS0+ZWxlbURlY2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb290LT5uYW1lLCBOVUxMLCBOVUxMKTsKCiAgICAvKgogICAgICogc3BlY2lhbCBjYXNlIHdoZSBlbGVtZW50Rm9ybURlZmF1bHQgaXMgdW5xdWFsaWZpZWQgZm9yIHRvcC1sZXZlbCBlbGVtLgogICAgICovCiAgICAvKiBSZW1vdmVkLCBzaW5jZSBlbGVtZW50Rm9ybURlZmF1bHQgZG9lcyBub3QgYXBwbHkgdG8gdG9wIGxldmVsIAogICAgKiBlbGVtZW50cyAqLwogICAgLyoKICAgIGlmICgoZWxlbURlY2wgPT0gTlVMTCkgJiYgKHJvb3QtPm5zICE9IE5VTEwpICYmCiAgICAgICAgKHhtbFN0ckVxdWFsKGN0eHQtPnNjaGVtYS0+dGFyZ2V0TmFtZXNwYWNlLCByb290LT5ucy0+aHJlZikpICYmCgkoKGN0eHQtPnNjaGVtYS0+ZmxhZ3MgJiBYTUxfU0NIRU1BU19RVUFMSUZfRUxFTSkgPT0gMCkpIHsKICAgICAgICBlbGVtRGVjbCA9IHhtbEhhc2hMb29rdXAzKGN0eHQtPnNjaGVtYS0+ZWxlbURlY2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb290LT5uYW1lLCBOVUxMLCBOVUxMKTsKICAgIH0KICAgICovCgogICAgaWYgKGVsZW1EZWNsID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIHJvb3QsIFhNTF9TQ0hFTUFTX0VSUl9VTkRFQ0xBUkVERUxFTSwKCQkgICAgICAiRWxlbWVudCAlcyBub3QgZGVjbGFyZWRcbiIsIHJvb3QtPm5hbWUsIE5VTEwpOwogICAgfSBlbHNlIGlmICgoZWxlbURlY2wtPmZsYWdzICYgWE1MX1NDSEVNQVNfRUxFTV9HTE9CQUwpID09IDApIHsKICAgICAgICB4bWxTY2hlbWFWRXJyKGN0eHQsIHJvb3QsIFhNTF9TQ0hFTUFTX0VSUl9OT1RUT1BMRVZFTCwKCQkgICAgICAiUm9vdCBlbGVtZW50ICVzIG5vdCBnbG9iYWxcbiIsIHJvb3QtPm5hbWUsIE5VTEwpOwogICAgfQogICAgLyoKICAgICAqIE9rYXksIHN0YXJ0IHRoZSByZWN1cnNpdmUgdmFsaWRhdGlvbgogICAgICovCiAgICB4bWxTY2hlbWFWYWxpZGF0ZUVsZW1lbnQoY3R4dCwgcm9vdCk7CgogICAgcmV0dXJuIChjdHh0LT5lcnIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIAkJCQkJCQkJCSoKICogCQkJU0FYIFZhbGlkYXRpb24gY29kZQkJCQkqCiAqIAkJCQkJCQkJCSoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCQkJCQkJCQkJKgogKiAJCQlWYWxpZGF0aW9uIGludGVyZmFjZXMJCQkJKgogKiAJCQkJCQkJCQkqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioKICogeG1sU2NoZW1hTmV3VmFsaWRDdHh0OgogKiBAc2NoZW1hOiAgYSBwcmVjb21waWxlZCBYTUwgU2NoZW1hcwogKgogKiBDcmVhdGUgYW4gWE1MIFNjaGVtYXMgdmFsaWRhdGlvbiBjb250ZXh0IGJhc2VkIG9uIHRoZSBnaXZlbiBzY2hlbWEKICoKICogUmV0dXJucyB0aGUgdmFsaWRhdGlvbiBjb250ZXh0IG9yIE5VTEwgaW4gY2FzZSBvZiBlcnJvcgogKi8KeG1sU2NoZW1hVmFsaWRDdHh0UHRyCnhtbFNjaGVtYU5ld1ZhbGlkQ3R4dCh4bWxTY2hlbWFQdHIgc2NoZW1hKQp7CiAgICB4bWxTY2hlbWFWYWxpZEN0eHRQdHIgcmV0OwoKICAgIHJldCA9ICh4bWxTY2hlbWFWYWxpZEN0eHRQdHIpIHhtbE1hbGxvYyhzaXplb2YoeG1sU2NoZW1hVmFsaWRDdHh0KSk7CiAgICBpZiAocmV0ID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIHZhbGlkYXRpb24gY29udGV4dCIsIE5VTEwpOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICBtZW1zZXQocmV0LCAwLCBzaXplb2YoeG1sU2NoZW1hVmFsaWRDdHh0KSk7CiAgICByZXQtPnNjaGVtYSA9IHNjaGVtYTsKICAgIC8qIAogICAgICogUmVtb3ZlZCBkdWUgdG8gY2hhbmdlcyBvZiB0aGUgYXR0cmlidXRlIHN0YXRlIGxpc3QuCiAgICAqLwogICAgLyogcmV0LT5hdHRyTnIgPSAwOyAqLwogICAgLyogcmV0LT5hdHRyTWF4ID0gMTA7ICovCiAgICAvKiByZXQtPmF0dHJCYXNlID0gTlVMTDsgKi8KICAgIHJldC0+YXR0clRvcCA9IE5VTEw7CiAgICByZXQtPmF0dHIgPSBOVUxMOwogICAgLyogCiAgICAgKiBSZW1vdmVkIGR1ZSB0byBjaGFuZ2VzIG9mIHRoZSBhdHRyaWJ1dGUgc3RhdGUgbGlzdC4KICAgICAqCiAgICByZXQtPmF0dHIgPSAoeG1sU2NoZW1hQXR0clN0YXRlUHRyKSB4bWxNYWxsb2MocmV0LT5hdHRyTWF4ICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoeG1sU2NoZW1hQXR0clN0YXRlKSk7CiAgICBpZiAocmV0LT5hdHRyID09IE5VTEwpIHsKICAgICAgICB4bWxTY2hlbWFWRXJyTWVtb3J5KE5VTEwsICJhbGxvY2F0aW5nIHZhbGlkYXRpb24gY29udGV4dCIsIE5VTEwpOwogICAgICAgIGZyZWUocmV0KTsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgbWVtc2V0KHJldC0+YXR0ciwgMCwgcmV0LT5hdHRyTWF4ICogc2l6ZW9mKHhtbFNjaGVtYUF0dHJTdGF0ZSkpOwogICAgKi8KCiAgICByZXR1cm4gKHJldCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFGcmVlVmFsaWRDdHh0OgogKiBAY3R4dDogIHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqCiAqIEZyZWUgdGhlIHJlc291cmNlcyBhc3NvY2lhdGVkIHRvIHRoZSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqLwp2b2lkCnhtbFNjaGVtYUZyZWVWYWxpZEN0eHQoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQpCnsKICAgIGlmIChjdHh0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwogICAgaWYgKGN0eHQtPmF0dHIgIT0gTlVMTCkKICAgICAgICB4bWxTY2hlbWFGcmVlQXR0cmlidXRlU3RhdGVzKGN0eHQtPmF0dHIpOwogICAgaWYgKGN0eHQtPnZhbHVlICE9IE5VTEwpCiAgICAgICAgeG1sU2NoZW1hRnJlZVZhbHVlKGN0eHQtPnZhbHVlKTsKICAgIHhtbEZyZWUoY3R4dCk7Cn0KCi8qKgogKiB4bWxTY2hlbWFTZXRWYWxpZEVycm9yczoKICogQGN0eHQ6ICBhIHNjaGVtYSB2YWxpZGF0aW9uIGNvbnRleHQKICogQGVycjogIHRoZSBlcnJvciBmdW5jdGlvbgogKiBAd2FybjogdGhlIHdhcm5pbmcgZnVuY3Rpb24KICogQGN0eDogdGhlIGZ1bmN0aW9ucyBjb250ZXh0CiAqCiAqIFNldCB0aGUgZXJyb3IgYW5kIHdhcm5pbmcgY2FsbGJhY2sgaW5mb3JtYXRpb25zCiAqLwp2b2lkCnhtbFNjaGVtYVNldFZhbGlkRXJyb3JzKHhtbFNjaGVtYVZhbGlkQ3R4dFB0ciBjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICB4bWxTY2hlbWFWYWxpZGl0eUVycm9yRnVuYyBlcnIsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNjaGVtYVZhbGlkaXR5V2FybmluZ0Z1bmMgd2Fybiwgdm9pZCAqY3R4KQp7CiAgICBpZiAoY3R4dCA9PSBOVUxMKQogICAgICAgIHJldHVybjsKICAgIGN0eHQtPmVycm9yID0gZXJyOwogICAgY3R4dC0+d2FybmluZyA9IHdhcm47CiAgICBjdHh0LT51c2VyRGF0YSA9IGN0eDsKfQoKLyoqCiAqIHhtbFNjaGVtYVZhbGlkYXRlRG9jOgogKiBAY3R4dDogIGEgc2NoZW1hIHZhbGlkYXRpb24gY29udGV4dAogKiBAZG9jOiAgYSBwYXJzZWQgZG9jdW1lbnQgdHJlZQogKgogKiBWYWxpZGF0ZSBhIGRvY3VtZW50IHRyZWUgaW4gbWVtb3J5LgogKgogKiBSZXR1cm5zIDAgaWYgdGhlIGRvY3VtZW50IGlzIHNjaGVtYXMgdmFsaWQsIGEgcG9zaXRpdmUgZXJyb3IgY29kZQogKiAgICAgbnVtYmVyIG90aGVyd2lzZSBhbmQgLTEgaW4gY2FzZSBvZiBpbnRlcm5hbCBvciBBUEkgZXJyb3IuCiAqLwppbnQKeG1sU2NoZW1hVmFsaWRhdGVEb2MoeG1sU2NoZW1hVmFsaWRDdHh0UHRyIGN0eHQsIHhtbERvY1B0ciBkb2MpCnsKICAgIGludCByZXQ7CgogICAgaWYgKChjdHh0ID09IE5VTEwpIHx8IChkb2MgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuICgtMSk7CgogICAgY3R4dC0+ZG9jID0gZG9jOwogICAgcmV0ID0geG1sU2NoZW1hVmFsaWRhdGVEb2N1bWVudChjdHh0LCBkb2MpOwogICAgcmV0dXJuIChyZXQpOwp9CgovKioKICogeG1sU2NoZW1hVmFsaWRhdGVTdHJlYW06CiAqIEBjdHh0OiAgYSBzY2hlbWEgdmFsaWRhdGlvbiBjb250ZXh0CiAqIEBpbnB1dDogIHRoZSBpbnB1dCB0byB1c2UgZm9yIHJlYWRpbmcgdGhlIGRhdGEKICogQGVuYzogIGFuIG9wdGlvbmFsIGVuY29kaW5nIGluZm9ybWF0aW9uCiAqIEBzYXg6ICBhIFNBWCBoYW5kbGVyIGZvciB0aGUgcmVzdWx0aW5nIGV2ZW50cwogKiBAdXNlcl9kYXRhOiAgdGhlIGNvbnRleHQgdG8gcHJvdmlkZSB0byB0aGUgU0FYIGhhbmRsZXIuCiAqCiAqIFZhbGlkYXRlIGEgZG9jdW1lbnQgdHJlZSBpbiBtZW1vcnkuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgZG9jdW1lbnQgaXMgc2NoZW1hcyB2YWxpZCwgYSBwb3NpdGl2ZSBlcnJvciBjb2RlCiAqICAgICBudW1iZXIgb3RoZXJ3aXNlIGFuZCAtMSBpbiBjYXNlIG9mIGludGVybmFsIG9yIEFQSSBlcnJvci4KICovCmludAp4bWxTY2hlbWFWYWxpZGF0ZVN0cmVhbSh4bWxTY2hlbWFWYWxpZEN0eHRQdHIgY3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgeG1sUGFyc2VySW5wdXRCdWZmZXJQdHIgaW5wdXQsIHhtbENoYXJFbmNvZGluZyBlbmMsCiAgICAgICAgICAgICAgICAgICAgICAgIHhtbFNBWEhhbmRsZXJQdHIgc2F4LCB2b2lkICp1c2VyX2RhdGEpCnsKICAgIGlmICgoY3R4dCA9PSBOVUxMKSB8fCAoaW5wdXQgPT0gTlVMTCkpCiAgICAgICAgcmV0dXJuICgtMSk7CiAgICBjdHh0LT5pbnB1dCA9IGlucHV0OwogICAgY3R4dC0+ZW5jID0gZW5jOwogICAgY3R4dC0+c2F4ID0gc2F4OwogICAgY3R4dC0+dXNlcl9kYXRhID0gdXNlcl9kYXRhOwogICAgVE9ETyByZXR1cm4gKDApOwp9CgojZW5kaWYgLyogTElCWE1MX1NDSEVNQVNfRU5BQkxFRCAqLwo=