LyoKICogSVdpbmVEM0RTdXJmYWNlIEltcGxlbWVudGF0aW9uCiAqCiAqIENvcHlyaWdodCAxOTk4IExpb25lbCBVbG1lcgogKiBDb3B5cmlnaHQgMjAwMC0yMDAxIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcyBJbmMuCiAqIENvcHlyaWdodCAyMDAyLTIwMDUgSmFzb24gRWRtZWFkZXMKICogQ29weXJpZ2h0IDIwMDItMjAwMyBSYXBoYWVsIEp1bnF1ZWlyYQogKiBDb3B5cmlnaHQgMjAwNCBDaHJpc3RpYW4gQ29zdGEKICogQ29weXJpZ2h0IDIwMDUgT2xpdmVyIFN0aWViZXIKICogQ29weXJpZ2h0IDIwMDYtMjAwNyBTdGVmYW4gRPZzaW5nZXIgZm9yIENvZGVXZWF2ZXJzCiAqIENvcHlyaWdodCAyMDA3IEhlbnJpIFZlcmJlZXQKICogQ29weXJpZ2h0IDIwMDYtMjAwNyBSb2RlcmljayBDb2xlbmJyYW5kZXIKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCiNpbmNsdWRlICJ3aW5lZDNkX3ByaXZhdGUuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGQzZF9zdXJmYWNlKTsKI2RlZmluZSBHTElORk9fTE9DQVRJT04gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZS0+YWRhcHRlci0+Z2xfaW5mbwoKSFJFU1VMVCBkM2RmbXRfY29udmVydF9zdXJmYWNlKEJZVEUgKnNyYywgQllURSAqZHN0LCBVSU5UIHBpdGNoLCBVSU5UIHdpZHRoLCBVSU5UIGhlaWdodCwgVUlOVCBvdXRwaXRjaCwgQ09OVkVSVF9UWVBFUyBjb252ZXJ0LCBJV2luZUQzRFN1cmZhY2VJbXBsICpzdXJmKTsKc3RhdGljIHZvaWQgZDNkZm10X3A4X2luaXRfcGFsZXR0ZShJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBCWVRFIHRhYmxlWzI1Nl1bNF0sIEJPT0wgY29sb3JrZXkpOwoKc3RhdGljIHZvaWQgc3VyZmFjZV9kb3dubG9hZF9kYXRhKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqbXlEZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwoKICAgIGlmICgwID09IFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpIHsKICAgICAgICBFUlIoIlN1cmZhY2UgZG9lcyBub3QgaGF2ZSBhIHRleHR1cmUsIGJ1dCBTRkxBR19JTlRFWFRVUkUgaXMgc2V0XG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYobXlEZXZpY2UtPmNyZWF0ZVBhcm1zLkJlaGF2aW9yRmxhZ3MgJiBXSU5FRDNEQ1JFQVRFX01VTFRJVEhSRUFERUQpIHsKICAgICAgICBBY3RpdmF0ZUNvbnRleHQobXlEZXZpY2UsIG15RGV2aWNlLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0LCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwogICAgfQoKICAgIEVOVEVSX0dMKCk7CiAgICAgICAgICAgIC8qIE1ha2Ugc3VyZSB0aGF0IGEgcHJvcGVyIHRleHR1cmUgdW5pdCBpcyBzZWxlY3RlZCwgYmluZCB0aGUgdGV4dHVyZQogICAgKiBhbmQgZGlydGlmeSB0aGUgc2FtcGxlciB0byByZXN0b3JlIHRoZSB0ZXh0dXJlIG9uIHRoZSBuZXh0IGRyYXcKICAgICAgICAgICAgKi8KICAgIGlmIChHTF9TVVBQT1JUKEFSQl9NVUxUSVRFWFRVUkUpKSB7CiAgICAgICAgR0xfRVhUQ0FMTChnbEFjdGl2ZVRleHR1cmVBUkIoR0xfVEVYVFVSRTBfQVJCKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQWN0aXZlVGV4dHVyZUFSQiIpOwogICAgfQogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UsIFNUQVRFX1NBTVBMRVIoMCkpOwogICAgSVdpbmVEM0RTdXJmYWNlX0JpbmRUZXh0dXJlKChJV2luZUQzRFN1cmZhY2UgKikgVGhpcyk7CgogICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEgfHwKICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQzIHx8CiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDQgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNSkgewogICAgICAgIGlmICghR0xfU1VQUE9SVChFWFRfVEVYVFVSRV9DT01QUkVTU0lPTl9TM1RDKSkgeyAvKiBXZSBjYW4gYXNzdW1lIHRoaXMgYXMgdGhlIHRleHR1cmUgd291bGQgbm90IGhhdmUgYmVlbiBjcmVhdGVkIG90aGVyd2lzZSAqLwogICAgICAgICAgICBGSVhNRSgiKCVwKSA6IEF0dGVtcHRpbmcgdG8gbG9jayBhIGNvbXByZXNzZWQgdGV4dHVyZSB3aGVuIHRleHR1cmUgY29tcHJlc3Npb24gaXNuJ3Qgc3VwcG9ydGVkIGJ5IG9wZW5nbFxuIiwgVGhpcyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVFJBQ0UoIiglcCkgOiBDYWxsaW5nIGdsR2V0Q29tcHJlc3NlZFRleEltYWdlQVJCIGxldmVsICVkLCBmb3JtYXQgJSN4LCB0eXBlICUjeCwgZGF0YSAlcFxuIiwgVGhpcywgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwKICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXQsIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlLCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwoKICAgICAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19QQk8pIHsKICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kQnVmZmVyQVJCKEdMX1BJWEVMX1BBQ0tfQlVGRkVSX0FSQiwgVGhpcy0+cGJvKSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kQnVmZmVyQVJCIik7CiAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsR2V0Q29tcHJlc3NlZFRleEltYWdlQVJCKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCBOVUxMKSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZXRDb21wcmVzc2VkVGV4SW1hZ2VBUkIoKSIpOwogICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEJpbmRCdWZmZXJBUkIoR0xfUElYRUxfUEFDS19CVUZGRVJfQVJCLCAwKSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kQnVmZmVyQVJCIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsR2V0Q29tcHJlc3NlZFRleEltYWdlQVJCKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEdldENvbXByZXNzZWRUZXhJbWFnZUFSQigpIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgTEVBVkVfR0woKTsKICAgIH0gZWxzZSB7CiAgICAgICAgdm9pZCAqbWVtOwogICAgICAgIGludCBzcmNfcGl0Y2ggPSAwOwogICAgICAgIGludCBkc3RfcGl0Y2ggPSAwOwoKICAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19DT05WRVJURUQpIHsKICAgICAgICAgICAgIEZJWE1FKCJSZWFkIGJhY2sgY29udmVydGVkIHRleHR1cmVzIHVuc3VwcG9ydGVkXG4iKTsKICAgICAgICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgIH0KCiAgICAgICAgaWYgKFRoaXMtPkZsYWdzICYgU0ZMQUdfTk9OUE9XMikgewogICAgICAgICAgICB1bnNpZ25lZCBjaGFyIGFsaWdubWVudCA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UtPnN1cmZhY2VfYWxpZ25tZW50OwogICAgICAgICAgICBzcmNfcGl0Y2ggPSBUaGlzLT5ieXRlc1BlclBpeGVsICogVGhpcy0+cG93MldpZHRoOwogICAgICAgICAgICBkc3RfcGl0Y2ggPSBJV2luZUQzRFN1cmZhY2VfR2V0UGl0Y2goKElXaW5lRDNEU3VyZmFjZSAqKSBUaGlzKTsKICAgICAgICAgICAgc3JjX3BpdGNoID0gKHNyY19waXRjaCArIGFsaWdubWVudCAtIDEpICYgfihhbGlnbm1lbnQgLSAxKTsKICAgICAgICAgICAgbWVtID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNyY19waXRjaCAqIFRoaXMtPnBvdzJIZWlnaHQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG1lbSA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICB9CgogICAgICAgIFRSQUNFKCIoJXApIDogQ2FsbGluZyBnbEdldFRleEltYWdlIGxldmVsICVkLCBmb3JtYXQgJSN4LCB0eXBlICUjeCwgZGF0YSAlcFxuIiwgVGhpcywgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwKICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXQsIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlLCBtZW0pOwoKICAgICAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX1BCTykgewogICAgICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9QSVhFTF9QQUNLX0JVRkZFUl9BUkIsIFRoaXMtPnBibykpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kQnVmZmVyQVJCIik7CgogICAgICAgICAgICBnbEdldFRleEltYWdlKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlLCBOVUxMKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsR2V0VGV4SW1hZ2UoKSIpOwoKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEJpbmRCdWZmZXJBUkIoR0xfUElYRUxfUEFDS19CVUZGRVJfQVJCLCAwKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRCdWZmZXJBUkIiKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBnbEdldFRleEltYWdlKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlLCBtZW0pOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZXRUZXhJbWFnZSgpIik7CiAgICAgICAgfQogICAgICAgIExFQVZFX0dMKCk7CgogICAgICAgIGlmIChUaGlzLT5GbGFncyAmIFNGTEFHX05PTlBPVzIpIHsKICAgICAgICAgICAgTFBCWVRFIHNyY19kYXRhLCBkc3RfZGF0YTsKICAgICAgICAgICAgaW50IHk7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFNvbWUgZ2FtZXMgKGUuZy4gd2FyaGFtbWVyIDQwaykgZG9uJ3Qgd29yayBwcm9wZXJseSB3aXRoIHRoZSBvZGQgcGl0Y2hlcywgcHJldmVudGluZwogICAgICAgICAgICAgKiB0aGUgc3VyZmFjZSBwaXRjaCBmcm9tIGJlaW5nIHVzZWQgdG8gYm94IG5vbi1wb3dlcjIgdGV4dHVyZXMuIEluc3RlYWQgd2UgaGF2ZSB0byB1c2UgYSBoYWNrIHRvCiAgICAgICAgICAgICAqIHJlcGFjayB0aGUgdGV4dHVyZSBzbyB0aGF0IHRoZSBicHAgKiB3aWR0aCBwaXRjaCBjYW4gYmUgdXNlZCBpbnN0ZWFkIG9mIGJwcCAqIHBvdzJ3aWR0aC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogV2UncmUgZG9pbmcgdGhpcy4uLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBpbnN0ZWFkIG9mIGJveGluZyB0aGUgdGV4dHVyZSA6CiAgICAgICAgICAgICAqIHw8LXRleHR1cmUgd2lkdGggLT58ICAtLT5wb3cyd2lkdGh8ICAgL1wKICAgICAgICAgICAgICogfDExMTExMTExMTExMTExMTExMXwgICAgICAgICAgICAgIHwgICB8CiAgICAgICAgICAgICAqIHwyMjIgVGV4dHVyZSAyMjIyMjJ8IGJveGVkIGVtcHR5ICB8IHRleHR1cmUgaGVpZ2h0CiAgICAgICAgICAgICAqIHwzMzMzIERhdGEgMzMzMzMzMzN8ICAgICAgICAgICAgICB8ICAgfAogICAgICAgICAgICAgKiB8NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0fCAgICAgICAgICAgICAgfCAgIFwvCiAgICAgICAgICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICAgfAogICAgICAgICAgICAgKiB8ICAgICBib3hlZCAgZW1wdHkgfCBib3hlZCBlbXB0eSAgfCBwb3cyaGVpZ2h0CiAgICAgICAgICAgICAqIHwgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICB8ICAgXC8KICAgICAgICAgICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICoKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogd2UncmUgcmVwYWNraW5nIHRoZSBkYXRhIHRvIHRoZSBleHBlY3RlZCB0ZXh0dXJlIHdpZHRoCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIHw8LXRleHR1cmUgd2lkdGggLT58ICAtLT5wb3cyd2lkdGh8ICAgL1wKICAgICAgICAgICAgICogfDExMTExMTExMTExMTExMTExMTIyMjIyMjIyMjIyMjIyMnwgICB8CiAgICAgICAgICAgICAqIHwyMjIzMzMzMzMzMzMzMzMzMzMzMzM0NDQ0NDQ0NDQ0NDR8IHRleHR1cmUgaGVpZ2h0CiAgICAgICAgICAgICAqIHw0NDQ0NDQgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgfAogICAgICAgICAgICAgKiB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIFwvCiAgICAgICAgICAgICAqIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgfAogICAgICAgICAgICAgKiB8ICAgICAgICAgICAgZW1wdHkgICAgICAgICAgICAgICAgfCBwb3cyaGVpZ2h0CiAgICAgICAgICAgICAqIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgXC8KICAgICAgICAgICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogPT0gaXMgdGhlIHNhbWUgYXMKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogfDwtdGV4dHVyZSB3aWR0aCAtPnwgICAgL1wKICAgICAgICAgICAgICogfDExMTExMTExMTExMTExMTExMXwKICAgICAgICAgICAgICogfDIyMjIyMjIyMjIyMjIyMjIyMnx0ZXh0dXJlIGhlaWdodAogICAgICAgICAgICAgKiB8MzMzMzMzMzMzMzMzMzMzMzMzfAogICAgICAgICAgICAgKiB8NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0fCAgICBcLwogICAgICAgICAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiB0aGlzIGFsc28gbWVhbnMgdGhhdCBhbnkgcmVmZXJlbmNlcyB0byBhbGxvY2F0ZWRNZW1vcnkgc2hvdWxkIHdvcmsgd2l0aCB0aGUgZGF0YSBhcyBpZiB3ZXJlIGEKICAgICAgICAgICAgICogc3RhbmRhcmQgdGV4dHVyZSB3aXRoIGEgbm9uLXBvd2VyMiB3aWR0aCBpbnN0ZWFkIG9mIHRleHR1cmUgYm94ZWQgdXAgdG8gYmUgYSBwb3dlcjIgdGV4dHVyZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogaW50ZXJuYWxseSB0aGUgdGV4dHVyZSBpcyBzdGlsbCBzdG9yZWQgaW4gYSBib3hlZCBmb3JtYXQgc28gYW55IHJlZmVyZW5jZXMgdG8gdGV4dHVyZU5hbWUgd2lsbAogICAgICAgICAgICAgKiBnZXQgYSBib3hlZCB0ZXh0dXJlIHdpdGggd2lkdGggcG93MndpZHRoIGFuZCBub3QgYSB0ZXh0dXJlIG9mIHdpZHRoIGN1cnJlbnREZXNjLldpZHRoLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBQZXJmb3JtYW5jZSBzaG91bGQgbm90IGJlIGFuIGlzc3VlLCBiZWNhdXNlIGFwcGxpY2F0aW9ucyBub3JtYWxseSBkbyBub3QgbG9jayB0aGUgc3VyZmFjZXMgd2hlbgogICAgICAgICAgICAgKiByZW5kZXJpbmcuIElmIGFuIGFwcCBkb2VzLCB0aGUgU0ZMQUdfRFlOTE9DSyBmbGFnIHdpbGwga2ljayBpbiBhbmQgdGhlIG1lbW9yeSBjb3B5IHdvbid0IGJlIHJlbGVhc2VkLAogICAgICAgICAgICAgKiBhbmQgZG9lc24ndCBoYXZlIHRvIGJlIHJlLXJlYWQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzcmNfZGF0YSA9IG1lbTsKICAgICAgICAgICAgZHN0X2RhdGEgPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIDogUmVwYWNraW5nIHRoZSBzdXJmYWNlIGRhdGEgZnJvbSBwaXRjaCAlZCB0byBwaXRjaCAlZFxuIiwgVGhpcywgc3JjX3BpdGNoLCBkc3RfcGl0Y2gpOwogICAgICAgICAgICBmb3IgKHkgPSAxIDsgeSA8IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsgeSsrKSB7CiAgICAgICAgICAgICAgICAvKiBza2lwIHRoZSBmaXJzdCByb3cgKi8KICAgICAgICAgICAgICAgIHNyY19kYXRhICs9IHNyY19waXRjaDsKICAgICAgICAgICAgICAgIGRzdF9kYXRhICs9IGRzdF9waXRjaDsKICAgICAgICAgICAgICAgIG1lbWNweShkc3RfZGF0YSwgc3JjX2RhdGEsIGRzdF9waXRjaCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1lbSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFN1cmZhY2UgaGFzIG5vdyBiZWVuIGRvd25sb2FkZWQgKi8KICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0lOU1lTTUVNOwp9CgpzdGF0aWMgdm9pZCBzdXJmYWNlX3VwbG9hZF9kYXRhKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMsIEdMZW51bSBpbnRlcm5hbCwgR0xzaXplaSB3aWR0aCwgR0xzaXplaSBoZWlnaHQsIEdMZW51bSBmb3JtYXQsIEdMZW51bSB0eXBlLCBjb25zdCBHTHZvaWQgKmRhdGEpIHsKICAgIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQxIHx8CiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDIgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMyB8fAogICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ0IHx8IFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDUpIHsKICAgICAgICBpZiAoIUdMX1NVUFBPUlQoRVhUX1RFWFRVUkVfQ09NUFJFU1NJT05fUzNUQykpIHsKICAgICAgICAgICAgRklYTUUoIlVzaW5nIERYVDEvMy81IHdpdGhvdXQgYWR2ZXJ0aXplZCBzdXBwb3J0XG4iKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvKiBnbENvbXByZXNzZWRUZXhTdWJJbWFnZTJEIGZvciB1cGxvYWRpbmcgYW5kIGdsVGV4SW1hZ2UyRCBmb3IgYWxsb2NhdGluZyBkb2VzIG5vdCB3b3JrIHdlbGwgb24gc29tZSBkcml2ZXJzKHIyMDAgZHJpLCBNYWNPUyBBVEkgZHJpdmVyKQogICAgICAgICAgICAgKiBnbENvbXByZXNzZWRUZXhJbWFnZTJEIGRvZXMgbm90IGFjY2VwdCBOVUxMIHBvaW50ZXJzLiBTbyBmb3IgY29tcHJlc3NlZCB0ZXh0dXJlcyBzdXJmYWNlX2FsbG9jYXRlX3N1cmZhY2UgZG9lcyBub3RoaW5nLCBhbmQgdGhpcwogICAgICAgICAgICAgKiBmdW5jdGlvbiB1c2VzIGdsQ29tcHJlc3NlZFRleEltYWdlMkQgaW5zdGVhZCBvZiB0aGUgU3ViSW1hZ2UgY2FsbAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgVFJBQ0UoIiglcCkgOiBDYWxsaW5nIGdsQ29tcHJlc3NlZFRleFN1YkltYWdlMkQgdyAlZCwgaCAlZCwgZGF0YSAlcFxuIiwgVGhpcywgd2lkdGgsIGhlaWdodCwgZGF0YSk7CiAgICAgICAgICAgIEVOVEVSX0dMKCk7CgogICAgICAgICAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX1BCTykgewogICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEJpbmRCdWZmZXJBUkIoR0xfUElYRUxfVU5QQUNLX0JVRkZFUl9BUkIsIFRoaXMtPnBibykpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZEJ1ZmZlckFSQiIpOwogICAgICAgICAgICAgICAgVFJBQ0UoIiglcCkgcGJvOiAlI3gsIGRhdGE6ICVwXG4iLCBUaGlzLCBUaGlzLT5wYm8sIGRhdGEpOwoKICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xDb21wcmVzc2VkVGV4SW1hZ2UyREFSQihUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwgaW50ZXJuYWwsCiAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoLCBoZWlnaHQsIDAgLyogYm9yZGVyICovLCBUaGlzLT5yZXNvdXJjZS5zaXplLCBOVUxMKSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xDb21wcmVzc2VkVGV4U3ViSW1hZ2UyRCIpOwoKICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kQnVmZmVyQVJCKEdMX1BJWEVMX1VOUEFDS19CVUZGRVJfQVJCLCAwKSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kQnVmZmVyQVJCIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsQ29tcHJlc3NlZFRleEltYWdlMkRBUkIoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIGludGVybmFsLAogICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCwgaGVpZ2h0LCAwIC8qIGJvcmRlciAqLywgVGhpcy0+cmVzb3VyY2Uuc2l6ZSwgZGF0YSkpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQ29tcHJlc3NlZFRleFN1YkltYWdlMkQiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoIiglcCkgOiBDYWxsaW5nIGdsVGV4U3ViSW1hZ2UyRCB3ICVkLCAgaCAlZCwgZGF0YSwgJXBcbiIsIFRoaXMsIHdpZHRoLCBoZWlnaHQsIGRhdGEpOwogICAgICAgIEVOVEVSX0dMKCk7CgogICAgICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfUEJPKSB7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kQnVmZmVyQVJCKEdMX1BJWEVMX1VOUEFDS19CVUZGRVJfQVJCLCBUaGlzLT5wYm8pKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZEJ1ZmZlckFSQiIpOwogICAgICAgICAgICBUUkFDRSgiKCVwKSBwYm86ICUjeCwgZGF0YTogJXBcbiIsIFRoaXMsIFRoaXMtPnBibywgZGF0YSk7CgogICAgICAgICAgICBnbFRleFN1YkltYWdlMkQoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIDAsIDAsIHdpZHRoLCBoZWlnaHQsIGZvcm1hdCwgdHlwZSwgTlVMTCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleFN1YkltYWdlMkQiKTsKCiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kQnVmZmVyQVJCKEdMX1BJWEVMX1VOUEFDS19CVUZGRVJfQVJCLCAwKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRCdWZmZXJBUkIiKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGdsVGV4U3ViSW1hZ2UyRChUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwgMCwgMCwgd2lkdGgsIGhlaWdodCwgZm9ybWF0LCB0eXBlLCBkYXRhKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4U3ViSW1hZ2UyRCIpOwogICAgICAgIH0KCiAgICAgICAgTEVBVkVfR0woKTsKICAgIH0KfQoKc3RhdGljIHZvaWQgc3VyZmFjZV9hbGxvY2F0ZV9zdXJmYWNlKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMsIEdMZW51bSBpbnRlcm5hbCwgR0xzaXplaSB3aWR0aCwgR0xzaXplaSBoZWlnaHQsIEdMZW51bSBmb3JtYXQsIEdMZW51bSB0eXBlKSB7CiAgICBCT09MIGVuYWJsZV9jbGllbnRfc3RvcmFnZSA9IEZBTFNFOwogICAgQllURSAqbWVtID0gTlVMTDsKCiAgICBUUkFDRSgiKCVwKSA6IENyZWF0aW5nIHN1cmZhY2UgKHRhcmdldCAlI3gpICBsZXZlbCAlZCwgZDNkIGZvcm1hdCAlcywgaW50ZXJuYWwgZm9ybWF0ICUjeCwgd2lkdGggJWQsIGhlaWdodCAlZCwgZ2wgZm9ybWF0ICUjeCwgZ2wgdHlwZT0lI3hcbiIsIFRoaXMsCiAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCBkZWJ1Z19kM2Rmb3JtYXQoVGhpcy0+cmVzb3VyY2UuZm9ybWF0KSwgaW50ZXJuYWwsIHdpZHRoLCBoZWlnaHQsIGZvcm1hdCwgdHlwZSk7CgogICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEgfHwKICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQzIHx8CiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDQgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNSkgewogICAgICAgIC8qIGdsQ29tcHJlc3NlZFRleEltYWdlMkQgZG9lcyBub3QgYWNjZXB0IE5VTEwgcG9pbnRlcnMsIHNvIHdlIGNhbm5vdCBhbGxvY2F0ZSBhIGNvbXByZXNzZWQgdGV4dHVyZSB3aXRob3V0IHVwbG9hZGluZyBkYXRhICovCiAgICAgICAgVFJBQ0UoIk5vdCBhbGxvY2F0aW5nIGNvbXByZXNzZWQgc3VyZmFjZXMsIHN1cmZhY2VfdXBsb2FkX2RhdGEgd2lsbCBzcGVjaWZ5IHRoZW1cbiIpOwoKICAgICAgICAvKiBXZSBoYXZlIHRvIHBvaW50IEdMIHRvIHRoZSBjbGllbnQgc3RvcmFnZSBtZW1vcnkgaGVyZSwgYmVjYXVzZSB1cGxvYWRfZGF0YSBtaWdodCB1c2UgYSBQQk8uIFRoaXMgbWVhbnMgYSBkb3VibGUgdXBsb2FkCiAgICAgICAgICogb25jZSwgdW5mb3J0dW5hdGVseQogICAgICAgICAqLwogICAgICAgIGlmKEdMX1NVUFBPUlQoQVBQTEVfQ0xJRU5UX1NUT1JBR0UpKSB7CiAgICAgICAgICAgIC8qIE5laXRoZXIgTk9OUE9XMiwgRElCU0VDVElPTiBub3IgT1ZFUlNJWkUgZmxhZ3MgY2FuIGJlIHNldCBvbiBjb21wcmVzc2VkIHRleHR1cmVzICovCiAgICAgICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0NMSUVOVDsKICAgICAgICAgICAgbWVtID0gKEJZVEUgKikoKChVTE9OR19QVFIpIFRoaXMtPnJlc291cmNlLmhlYXBNZW1vcnkgKyAoUkVTT1VSQ0VfQUxJR05NRU5UIC0gMSkpICYgfihSRVNPVVJDRV9BTElHTk1FTlQgLSAxKSk7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xDb21wcmVzc2VkVGV4SW1hZ2UyREFSQihUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwgaW50ZXJuYWwsCiAgICAgICAgICAgICAgICAgICAgICAgd2lkdGgsIGhlaWdodCwgMCAvKiBib3JkZXIgKi8sIFRoaXMtPnJlc291cmNlLnNpemUsIG1lbSkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIEVOVEVSX0dMKCk7CgogICAgaWYoR0xfU1VQUE9SVChBUFBMRV9DTElFTlRfU1RPUkFHRSkpIHsKICAgICAgICBpZihUaGlzLT5GbGFncyAmIChTRkxBR19OT05QT1cyIHwgU0ZMQUdfRElCU0VDVElPTiB8IFNGTEFHX09WRVJTSVpFIHwgU0ZMQUdfQ09OVkVSVEVEKSB8fCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPT0gTlVMTCkgewogICAgICAgICAgICAvKiBJbiBzb21lIGNhc2VzIHdlIHdhbnQgdG8gZGlzYWJsZSBjbGllbnQgc3RvcmFnZS4KICAgICAgICAgICAgICogU0ZMQUdfTk9OUE9XMiBoYXMgYSBiaWdnZXIgb3BlbmdsIHRleHR1cmUgdGhhbiB0aGUgY2xpZW50IG1lbW9yeSwgYW5kIGRpZmZlcmVudCBwaXRjaGVzCiAgICAgICAgICAgICAqIFNGTEFHX0RJQlNFQ1RJT046IERpYnNlY3Rpb25zIG1heSBoYXZlIHJlYWQgLyB3cml0ZSBwcm90ZWN0aW9ucyBvbiB0aGUgbWVtb3J5LiBBdm9pZCBpc3N1ZXMuLi4KICAgICAgICAgICAgICogU0ZMQUdfT1ZFUlNJWkU6IFRoZSBnbCB0ZXh0dXJlIGlzIHNtYWxsZXIgdGhhbiB0aGUgYWxsb2NhdGVkIG1lbW9yeQogICAgICAgICAgICAgKiBTRkxBR19DT05WRVJURUQ6IFRoZSBjb252ZXJzaW9uIGRlc3RpbmF0aW9uIG1lbW9yeSBpcyBmcmVlZCBhZnRlciBsb2FkaW5nIHRoZSBzdXJmYWNlCiAgICAgICAgICAgICAqIGFsbG9jYXRlZE1lbW9yeSA9PSBOVUxMOiBOb3QgZGVmaW5lZCBpbiB0aGUgZXh0ZW5zaW9uLiBTZWVtcyB0byBkaXNhYmxlIGNsaWVudCBzdG9yYWdlIGVmZmVjdGl2ZWx5CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBnbFBpeGVsU3RvcmVpKEdMX1VOUEFDS19DTElFTlRfU1RPUkFHRV9BUFBMRSwgR0xfRkFMU0UpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfQ0xJRU5UX1NUT1JBR0VfQVBQTEUsIEdMX0ZBTFNFKSIpOwogICAgICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfQ0xJRU5UOwogICAgICAgICAgICBlbmFibGVfY2xpZW50X3N0b3JhZ2UgPSBUUlVFOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0NMSUVOVDsKCiAgICAgICAgICAgIC8qIFBvaW50IG9wZW5nbCB0byBvdXIgYWxsb2NhdGVkIHRleHR1cmUgbWVtb3J5LiBEbyBub3QgdXNlIHJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSBoZXJlIGJlY2F1c2UKICAgICAgICAgICAgICogaXQgbWlnaHQgcG9pbnQgaW50byBhIHBiby4gSW5zdGVhZCB1c2UgaGVhcE1lbW9yeSwgYnV0IGdldCB0aGUgYWxpZ25tZW50IHJpZ2h0LgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgbWVtID0gKEJZVEUgKikoKChVTE9OR19QVFIpIFRoaXMtPnJlc291cmNlLmhlYXBNZW1vcnkgKyAoUkVTT1VSQ0VfQUxJR05NRU5UIC0gMSkpICYgfihSRVNPVVJDRV9BTElHTk1FTlQgLSAxKSk7CiAgICAgICAgfQogICAgfQogICAgZ2xUZXhJbWFnZTJEKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCBpbnRlcm5hbCwgd2lkdGgsIGhlaWdodCwgMCwgZm9ybWF0LCB0eXBlLCBtZW0pOwogICAgY2hlY2tHTGNhbGwoImdsVGV4SW1hZ2UyRCIpOwoKICAgIGlmKGVuYWJsZV9jbGllbnRfc3RvcmFnZSkgewogICAgICAgIGdsUGl4ZWxTdG9yZWkoR0xfVU5QQUNLX0NMSUVOVF9TVE9SQUdFX0FQUExFLCBHTF9UUlVFKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfQ0xJRU5UX1NUT1JBR0VfQVBQTEUsIEdMX1RSVUUpIik7CiAgICB9CiAgICBMRUFWRV9HTCgpOwoKICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0FMTE9DQVRFRDsKfQoKLyogSW4gRDNEIHRoZSBkZXB0aCBzdGVuY2lsIGRpbWVuc2lvbnMgaGF2ZSB0byBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gdGhlCiAqIHJlbmRlciB0YXJnZXQgZGltZW5zaW9ucy4gV2l0aCBGQk9zLCB0aGUgZGltZW5zaW9ucyBoYXZlIHRvIGJlIGFuIGV4YWN0IG1hdGNoLiAqLwovKiBUT0RPOiBXZSBzaG91bGQgc3luY2hyb25pemUgdGhlIHJlbmRlcmJ1ZmZlcidzIGNvbnRlbnQgd2l0aCB0aGUgdGV4dHVyZSdzIGNvbnRlbnQuICovCnZvaWQgc3VyZmFjZV9zZXRfY29tcGF0aWJsZV9yZW5kZXJidWZmZXIoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgdW5zaWduZWQgaW50IHdpZHRoLCB1bnNpZ25lZCBpbnQgaGVpZ2h0KSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIHJlbmRlcmJ1ZmZlcl9lbnRyeV90ICplbnRyeTsKICAgIEdMdWludCByZW5kZXJidWZmZXIgPSAwOwogICAgdW5zaWduZWQgaW50IHNyY193aWR0aCwgc3JjX2hlaWdodDsKCiAgICBzcmNfd2lkdGggPSBUaGlzLT5wb3cyV2lkdGg7CiAgICBzcmNfaGVpZ2h0ID0gVGhpcy0+cG93MkhlaWdodDsKCiAgICAvKiBBIGRlcHRoIHN0ZW5jaWwgc21hbGxlciB0aGFuIHRoZSByZW5kZXIgdGFyZ2V0IGlzIG5vdCB2YWxpZCAqLwogICAgaWYgKHdpZHRoID4gc3JjX3dpZHRoIHx8IGhlaWdodCA+IHNyY19oZWlnaHQpIHJldHVybjsKCiAgICAvKiBSZW1vdmUgYW55IHJlbmRlcmJ1ZmZlciBzZXQgaWYgdGhlIHNpemVzIG1hdGNoICovCiAgICBpZiAod2lkdGggPT0gc3JjX3dpZHRoICYmIGhlaWdodCA9PSBzcmNfaGVpZ2h0KSB7CiAgICAgICAgVGhpcy0+Y3VycmVudF9yZW5kZXJidWZmZXIgPSBOVUxMOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvKiBMb29rIGlmIHdlJ3ZlIGFscmVhZHkgZ290IGEgcmVuZGVyYnVmZmVyIG9mIHRoZSBjb3JyZWN0IGRpbWVuc2lvbnMgKi8KICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkoZW50cnksICZUaGlzLT5yZW5kZXJidWZmZXJzLCByZW5kZXJidWZmZXJfZW50cnlfdCwgZW50cnkpIHsKICAgICAgICBpZiAoZW50cnktPndpZHRoID09IHdpZHRoICYmIGVudHJ5LT5oZWlnaHQgPT0gaGVpZ2h0KSB7CiAgICAgICAgICAgIHJlbmRlcmJ1ZmZlciA9IGVudHJ5LT5pZDsKICAgICAgICAgICAgVGhpcy0+Y3VycmVudF9yZW5kZXJidWZmZXIgPSBlbnRyeTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIGlmICghcmVuZGVyYnVmZmVyKSB7CiAgICAgICAgY29uc3QgR2xQaXhlbEZvcm1hdERlc2MgKmdsRGVzYzsKICAgICAgICBnZXRGb3JtYXREZXNjRW50cnkoVGhpcy0+cmVzb3VyY2UuZm9ybWF0LCAmR0xJTkZPX0xPQ0FUSU9OLCAmZ2xEZXNjKTsKCiAgICAgICAgR0xfRVhUQ0FMTChnbEdlblJlbmRlcmJ1ZmZlcnNFWFQoMSwgJnJlbmRlcmJ1ZmZlcikpOwogICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kUmVuZGVyYnVmZmVyRVhUKEdMX1JFTkRFUkJVRkZFUl9FWFQsIHJlbmRlcmJ1ZmZlcikpOwogICAgICAgIEdMX0VYVENBTEwoZ2xSZW5kZXJidWZmZXJTdG9yYWdlRVhUKEdMX1JFTkRFUkJVRkZFUl9FWFQsIGdsRGVzYy0+Z2xGb3JtYXQsIHdpZHRoLCBoZWlnaHQpKTsKCiAgICAgICAgZW50cnkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKHJlbmRlcmJ1ZmZlcl9lbnRyeV90KSk7CiAgICAgICAgZW50cnktPndpZHRoID0gd2lkdGg7CiAgICAgICAgZW50cnktPmhlaWdodCA9IGhlaWdodDsKICAgICAgICBlbnRyeS0+aWQgPSByZW5kZXJidWZmZXI7CiAgICAgICAgbGlzdF9hZGRfaGVhZCgmVGhpcy0+cmVuZGVyYnVmZmVycywgJmVudHJ5LT5lbnRyeSk7CgogICAgICAgIFRoaXMtPmN1cnJlbnRfcmVuZGVyYnVmZmVyID0gZW50cnk7CiAgICB9CgogICAgY2hlY2tHTGNhbGwoInNldF9jb21wYXRpYmxlX3JlbmRlcmJ1ZmZlciIpOwp9CgpHTGVudW0gc3VyZmFjZV9nZXRfZ2xfYnVmZmVyKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIElXaW5lRDNEU3dhcENoYWluICpzd2FwY2hhaW4pIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICpzd2FwY2hhaW5faW1wbCA9IChJV2luZUQzRFN3YXBDaGFpbkltcGwgKilzd2FwY2hhaW47CgogICAgVFJBQ0UoIiglcCkgOiBzd2FwY2hhaW4gJXBcbiIsIFRoaXMsIHN3YXBjaGFpbik7CgogICAgaWYgKHN3YXBjaGFpbl9pbXBsLT5iYWNrQnVmZmVyICYmIHN3YXBjaGFpbl9pbXBsLT5iYWNrQnVmZmVyWzBdID09IGlmYWNlKSB7CiAgICAgICAgVFJBQ0UoIlJldHVybmluZyBHTF9CQUNLXG4iKTsKICAgICAgICByZXR1cm4gR0xfQkFDSzsKICAgIH0gZWxzZSBpZiAoc3dhcGNoYWluX2ltcGwtPmZyb250QnVmZmVyID09IGlmYWNlKSB7CiAgICAgICAgVFJBQ0UoIlJldHVybmluZyBHTF9GUk9OVFxuIik7CiAgICAgICAgcmV0dXJuIEdMX0ZST05UOwogICAgfQoKICAgIEZJWE1FKCJIaWdoZXIgYmFjayBidWZmZXIsIHJldHVybmluZyBHTF9CQUNLXG4iKTsKICAgIHJldHVybiBHTF9CQUNLOwp9CgpVTE9ORyBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZWxlYXNlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlc291cmNlLnJlZik7CiAgICBUUkFDRSgiKCVwKSA6IFJlbGVhc2luZyBmcm9tICVkXG4iLCBUaGlzLCByZWYgKyAxKTsKICAgIGlmIChyZWYgPT0gMCkgewogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbCAqZGV2aWNlID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgICAgIHJlbmRlcmJ1ZmZlcl9lbnRyeV90ICplbnRyeSwgKmVudHJ5MjsKICAgICAgICBUUkFDRSgiKCVwKSA6IGNsZWFuaW5nIHVwXG4iLCBUaGlzKTsKCiAgICAgICAgaWYgKFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUgIT0gMCkgeyAvKiByZWxlYXNlIHRoZSBvcGVuR0wgdGV4dHVyZS4uICovCgogICAgICAgICAgICAvKiBOZWVkIGEgY29udGV4dCB0byBkZXN0cm95IHRoZSB0ZXh0dXJlLiBVc2UgdGhlIGN1cnJlbnRseSBhY3RpdmUgcmVuZGVyIHRhcmdldCwgYnV0IG9ubHkgaWYKICAgICAgICAgICAgICogdGhlIHByaW1hcnkgcmVuZGVyIHRhcmdldCBleGlzdHMuIE90aGVyd2lzZSBsYXN0QWN0aXZlUmVuZGVyVGFyZ2V0IGlzIGdhcmJhZ2UsIHNlZSBhYm92ZS4KICAgICAgICAgICAgICogV2hlbiBkZXN0cm95aW5nIHRoZSBwcmltYXJ5IHJ0LCBVbmluaXQzRCB3aWxsIGFjdGl2YXRlIGEgY29udGV4dCBiZWZvcmUgZG9pbmcgYW55dGhpbmcKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmKGRldmljZS0+cmVuZGVyX3RhcmdldHMgJiYgZGV2aWNlLT5yZW5kZXJfdGFyZ2V0c1swXSkgewogICAgICAgICAgICAgICAgQWN0aXZhdGVDb250ZXh0KGRldmljZSwgZGV2aWNlLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0LCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBUUkFDRSgiRGVsZXRpbmcgdGV4dHVyZSAlZFxuIiwgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgICAgIGdsRGVsZXRlVGV4dHVyZXMoMSwgJlRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgIH0KCiAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19QQk8pIHsKICAgICAgICAgICAgLyogRGVsZXRlIHRoZSBQQk8gKi8KICAgICAgICAgICAgR0xfRVhUQ0FMTChnbERlbGV0ZUJ1ZmZlcnNBUkIoMSwgJlRoaXMtPnBibykpOwogICAgICAgIH0KCiAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19ESUJTRUNUSU9OKSB7CiAgICAgICAgICAgIC8qIFJlbGVhc2UgdGhlIERDICovCiAgICAgICAgICAgIFNlbGVjdE9iamVjdChUaGlzLT5oREMsIFRoaXMtPmRpYi5ob2xkYml0bWFwKTsKICAgICAgICAgICAgRGVsZXRlREMoVGhpcy0+aERDKTsKICAgICAgICAgICAgLyogUmVsZWFzZSB0aGUgRElCIHNlY3Rpb24gKi8KICAgICAgICAgICAgRGVsZXRlT2JqZWN0KFRoaXMtPmRpYi5ESUJzZWN0aW9uKTsKICAgICAgICAgICAgVGhpcy0+ZGliLmJpdG1hcF9kYXRhID0gTlVMTDsKICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19VU0VSUFRSKSBJV2luZUQzRFN1cmZhY2VfU2V0TWVtKGlmYWNlLCBOVUxMKTsKCiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cGFsZXR0ZTkpOwoKICAgICAgICBJV2luZUQzRFJlc291cmNlSW1wbF9DbGVhblVwKChJV2luZUQzRFJlc291cmNlICopaWZhY2UpOwogICAgICAgIGlmKGlmYWNlID09IGRldmljZS0+ZGRyYXdfcHJpbWFyeSkKICAgICAgICAgICAgZGV2aWNlLT5kZHJhd19wcmltYXJ5ID0gTlVMTDsKCiAgICAgICAgTElTVF9GT1JfRUFDSF9FTlRSWV9TQUZFKGVudHJ5LCBlbnRyeTIsICZUaGlzLT5yZW5kZXJidWZmZXJzLCByZW5kZXJidWZmZXJfZW50cnlfdCwgZW50cnkpIHsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbERlbGV0ZVJlbmRlcmJ1ZmZlcnNFWFQoMSwgJmVudHJ5LT5pZCkpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBlbnRyeSk7CiAgICAgICAgfQoKICAgICAgICBUUkFDRSgiKCVwKSBSZWxlYXNlZFxuIiwgVGhpcyk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CgogICAgfQogICAgcmV0dXJuIHJlZjsKfQoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICBJV2luZUQzRFN1cmZhY2UgSVdpbmVEM0RSZXNvdXJjZSBwYXJ0cyBmb2xsb3cKICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLwoKdm9pZCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9QcmVMb2FkKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIC8qIFRPRE86IGNoZWNrIGZvciBsb2NrcyAqLwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzREJhc2VUZXh0dXJlICpiYXNlVGV4dHVyZSA9IE5VTEw7CiAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CgogICAgVFJBQ0UoIiglcClDaGVja2luZyB0byBzZWUgaWYgdGhlIGNvbnRhaW5lciBpcyBhIGJhc2UgdGV4dHVyZVxuIiwgVGhpcyk7CiAgICBpZiAoSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihpZmFjZSwgJklJRF9JV2luZUQzREJhc2VUZXh0dXJlLCAodm9pZCAqKikmYmFzZVRleHR1cmUpID09IFdJTkVEM0RfT0spIHsKICAgICAgICBUUkFDRSgiUGFzc2luZyB0byBjb250YWluZXJcbiIpOwogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUHJlTG9hZChiYXNlVGV4dHVyZSk7CiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9SZWxlYXNlKGJhc2VUZXh0dXJlKTsKICAgIH0gZWxzZSB7CiAgICBUUkFDRSgiKCVwKSA6IEFib3V0IHRvIGxvYWQgc3VyZmFjZVxuIiwgVGhpcyk7CgogICAgaWYoIWRldmljZS0+aXNJbkRyYXcpIHsKICAgICAgICBBY3RpdmF0ZUNvbnRleHQoZGV2aWNlLCBkZXZpY2UtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQsIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CiAgICB9CgogICAgRU5URVJfR0woKTsKICAgIGdsRW5hYmxlKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0KTsvKiBtYWtlIHN1cmUgdGV4dHVyZSBzdXBwb3J0IGlzIGVuYWJsZWQgaW4gdGhpcyBjb250ZXh0ICovCiAgICBpZiAoIVRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwpIHsKICAgICAgICBpZiAoIVRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpIHsKICAgICAgICAgICAgZ2xHZW5UZXh0dXJlcygxLCAmVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEdlblRleHR1cmVzIik7CiAgICAgICAgICAgIFRSQUNFKCJTdXJmYWNlICVwIGdpdmVuIG5hbWUgJWRcbiIsIFRoaXMsIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgIH0KICAgICAgICBnbEJpbmRUZXh0dXJlKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kVGV4dHVyZSIpOwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9Mb2FkVGV4dHVyZShpZmFjZSwgRkFMU0UpOwogICAgICAgIC8qIFRoaXMgaXMgd2hlcmUgd2Ugc2hvdWxkIGJlIHJlZHVjaW5nIHRoZSBhbW91bnQgb2YgR0xNZW1vcnlVc2VkICovCiAgICB9IGVsc2UgaWYgKFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpIHsgLyogTk9URTogdGhlIGxldmVsIDAgc3VyZmFjZSBvZiBhIG1wbWFwcGVkIHRleHR1cmUgbXVzdCBiZSBsb2FkZWQgZmlyc3QhICovCiAgICAgICAgLyogYXNzdW1lIHRoaXMgaXMgYSBjb2RpbmcgZXJyb3Igbm90IGEgcmVhbCBlcnJvciBmb3Igbm93ICovCiAgICAgICAgRklYTUUoIk1pcG1hcCBzdXJmYWNlIGhhcyBhIGdsVGV4dHVyZSBib3VuZCB0byBpdCFcbiIpOwogICAgfQogICAgaWYgKFRoaXMtPnJlc291cmNlLnBvb2wgPT0gV0lORUQzRFBPT0xfREVGQVVMVCkgewogICAgICAgLyogVGVsbCBvcGVuZ2wgdG8gdHJ5IGFuZCBrZWVwIHRoaXMgdGV4dHVyZSBpbiB2aWRlbyByYW0gKHdlbGwgbW9zdGx5KSAqLwogICAgICAgR0xjbGFtcGYgdG1wOwogICAgICAgdG1wID0gMC45ZjsKICAgICAgICBnbFByaW9yaXRpemVUZXh0dXJlcygxLCAmVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSwgJnRtcCk7CiAgICB9CiAgICBMRUFWRV9HTCgpOwogICAgfQogICAgcmV0dXJuOwp9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgSVdpbmVEM0RTdXJmYWNlIElXaW5lRDNEU3VyZmFjZSBwYXJ0cyBmb2xsb3cKICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovCgp2b2lkIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NldEdsVGV4dHVyZURlc2MoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgVUlOVCB0ZXh0dXJlTmFtZSwgaW50IHRhcmdldCkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IHNldHRpbmcgdGV4dHVyZU5hbWUgJXUsIHRhcmdldCAlaVxuIiwgVGhpcywgdGV4dHVyZU5hbWUsIHRhcmdldCk7CiAgICBpZiAoVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSA9PSAwICYmIHRleHR1cmVOYW1lICE9IDApIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfTW9kaWZ5TG9jYXRpb24oaWZhY2UsIFNGTEFHX0lOVEVYVFVSRSwgRkFMU0UpOwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9BZGREaXJ0eVJlY3QoaWZhY2UsIE5VTEwpOwogICAgfQogICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSA9IHRleHR1cmVOYW1lOwogICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQgICAgICA9IHRhcmdldDsKICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19BTExPQ0FURUQ7Cn0KCnZvaWQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0R2xEZXNjKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIGdsRGVzY3JpcHRvciAqKmdsRGVzY3JpcHRpb24pIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiByZXR1cm5pbmcgJXBcbiIsIFRoaXMsICZUaGlzLT5nbERlc2NyaXB0aW9uKTsKICAgICpnbERlc2NyaXB0aW9uID0gJlRoaXMtPmdsRGVzY3JpcHRpb247Cn0KCi8qIFRPRE86IHRoaW5rIGFib3V0IG1vdmluZyB0aGlzIGRvd24gdG8gcmVzb3VyY2U/ICovCmNvbnN0IHZvaWQgKldJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldERhdGEoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICAvKiBUaGlzIHNob3VsZCBvbmx5IGJlIGNhbGxlZCBmb3Igc3lzbWVtIHRleHR1cmVzLCBpdCBtYXkgYmUgYSBnb29kIGlkZWEgdG8gZXh0ZW5kIHRoaXMgdG8gYWxsIHBvb2xzIGF0IHNvbWUgcG9pbnQgaW4gdGhlIGZ1dHVyZSAgKi8KICAgIGlmIChUaGlzLT5yZXNvdXJjZS5wb29sICE9IFdJTkVEM0RQT09MX1NZU1RFTU1FTSkgewogICAgICAgIEZJWE1FKCIgKCVwKUF0dGVtcHRpbmcgdG8gZ2V0IHN5c3RlbSBtZW1vcnkgZm9yIGEgbm9uLXN5c3RlbSBtZW1vcnkgdGV4dHVyZVxuIiwgaWZhY2UpOwogICAgfQogICAgcmV0dXJuIChDT05TVCB2b2lkKikoVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKfQoKc3RhdGljIHZvaWQgcmVhZF9mcm9tX2ZyYW1lYnVmZmVyKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMsIENPTlNUIFJFQ1QgKnJlY3QsIHZvaWQgKmRlc3QsIFVJTlQgcGl0Y2gpIHsKICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqc3dhcGNoYWluOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpteURldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICBCWVRFICptZW07CiAgICBHTGludCBmbXQ7CiAgICBHTGludCB0eXBlOwogICAgQllURSAqcm93LCAqdG9wLCAqYm90dG9tOwogICAgaW50IGk7CiAgICBCT09MIGJwcDsKICAgIFJFQ1QgbG9jYWxfcmVjdDsKICAgIEJPT0wgc3JjSXNVcHNpZGVEb3duOwoKICAgIGlmKHdpbmVkM2Rfc2V0dGluZ3MucmVuZGVydGFyZ2V0bG9ja19tb2RlID09IFJUTF9ESVNBQkxFKSB7CiAgICAgICAgc3RhdGljIEJPT0wgd2FybmVkID0gRkFMU0U7CiAgICAgICAgaWYoIXdhcm5lZCkgewogICAgICAgICAgICBFUlIoIlRoZSBhcHBsaWNhdGlvbiB0cmllcyB0byBsb2NrIHRoZSByZW5kZXIgdGFyZ2V0LCBidXQgcmVuZGVyIHRhcmdldCBsb2NraW5nIGlzIGRpc2FibGVkXG4iKTsKICAgICAgICAgICAgd2FybmVkID0gVFJVRTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoKElXaW5lRDNEU3VyZmFjZSAqKSBUaGlzLCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikmc3dhcGNoYWluKTsKICAgIC8qIEFjdGl2YXRlIHRoZSBzdXJmYWNlLiBTZXQgaXQgdXAgZm9yIGJsaXR0aW5nIG5vdywgYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IG5lZWRlZCBmb3IgTG9ja1JlY3QuCiAgICAgKiBDZXJ0YWluIGdyYXBoaWNzIGRyaXZlcnMgc2VlbSB0byBkaXNsaWtlIHNvbWUgZW5hYmxlZCBzdGF0ZXMgd2hlbiByZWFkaW5nIGZyb20gb3BlbmdsLCB0aGUgYmxpdHRpbmcgdXNhZ2UKICAgICAqIHNob3VsZCBoZWxwIGhlcmUuIEZ1cnRoZXJtb3JlIHVubG9ja3JlY3Qgd2lsbCBuZWVkIHRoZSBjb250ZXh0IHNldCB1cCBmb3IgYmxpdHRpbmcuIFRoZSBjb250ZXh0IG1hbmFnZXIgd2lsbCBmaW5kCiAgICAgKiBjb250ZXh0LT5sYXN0X3dhc19ibGl0IHNldCBvbiB0aGUgdW5sb2NrLgogICAgICovCiAgICBBY3RpdmF0ZUNvbnRleHQobXlEZXZpY2UsIChJV2luZUQzRFN1cmZhY2UgKikgVGhpcywgQ1RYVVNBR0VfQkxJVCk7CiAgICBFTlRFUl9HTCgpOwoKICAgIC8qIFNlbGVjdCB0aGUgY29ycmVjdCByZWFkIGJ1ZmZlciwgYW5kIGdpdmUgc29tZSBkZWJ1ZyBvdXRwdXQuCiAgICAgKiBUaGVyZSBpcyBubyBuZWVkIHRvIGtlZXAgdHJhY2sgb2YgdGhlIGN1cnJlbnQgcmVhZCBidWZmZXIgb3IgcmVzZXQgaXQsIGV2ZXJ5IHBhcnQgb2YgdGhlIGNvZGUKICAgICAqIHRoYXQgcmVhZHMgc2V0cyB0aGUgcmVhZCBidWZmZXIgYXMgZGVzaXJlZC4KICAgICAqLwogICAgaWYoIXN3YXBjaGFpbikgewogICAgICAgIC8qIExvY2tpbmcgdGhlIHByaW1hcnkgcmVuZGVyIHRhcmdldCB3aGljaCBpcyBub3Qgb24gYSBzd2FwY2hhaW4oPW9mZnNjcmVlbiByZW5kZXIgdGFyZ2V0KS4KICAgICAgICAgKiBSZWFkIGZyb20gdGhlIGJhY2sgYnVmZmVyCiAgICAgICAgICovCiAgICAgICAgVFJBQ0UoIkxvY2tpbmcgb2Zmc2NyZWVuIHJlbmRlciB0YXJnZXRcbiIpOwogICAgICAgIGdsUmVhZEJ1ZmZlcihteURldmljZS0+b2Zmc2NyZWVuQnVmZmVyKTsKICAgICAgICBzcmNJc1Vwc2lkZURvd24gPSBUUlVFOwogICAgfSBlbHNlIHsKICAgICAgICBHTGVudW0gYnVmZmVyID0gc3VyZmFjZV9nZXRfZ2xfYnVmZmVyKChJV2luZUQzRFN1cmZhY2UgKikgVGhpcywgKElXaW5lRDNEU3dhcENoYWluICopc3dhcGNoYWluKTsKICAgICAgICBUUkFDRSgiTG9ja2luZyAlI3ggYnVmZmVyXG4iLCBidWZmZXIpOwogICAgICAgIGdsUmVhZEJ1ZmZlcihidWZmZXIpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIiKTsKCiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4gKikgc3dhcGNoYWluKTsKICAgICAgICBzcmNJc1Vwc2lkZURvd24gPSBGQUxTRTsKICAgIH0KCiAgICAvKiBUT0RPOiBHZXQgcmlkIG9mIHRoZSBleHRyYSByZWN0YW5nbGUgY29tcGFyaXNvbiBhbmQgY29uc3RydWN0aW9uIG9mIGEgZnVsbCBzdXJmYWNlIHJlY3RhbmdsZSAqLwogICAgaWYoIXJlY3QpIHsKICAgICAgICBsb2NhbF9yZWN0LmxlZnQgPSAwOwogICAgICAgIGxvY2FsX3JlY3QudG9wID0gMDsKICAgICAgICBsb2NhbF9yZWN0LnJpZ2h0ID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgbG9jYWxfcmVjdC5ib3R0b20gPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICB9IGVsc2UgewogICAgICAgIGxvY2FsX3JlY3QgPSAqcmVjdDsKICAgIH0KICAgIC8qIFRPRE86IEdldCByaWQgb2YgdGhlIGV4dHJhIEdldFBpdGNoIGNhbGwsIExvY2tSZWN0IGRvZXMgdGhhdCB0b28uIENhY2hlIHRoZSBwaXRjaCAqLwoKICAgIHN3aXRjaChUaGlzLT5yZXNvdXJjZS5mb3JtYXQpCiAgICB7CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1A4OgogICAgICAgIHsKICAgICAgICAgICAgaWYoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSB7CiAgICAgICAgICAgICAgICAvKiBJbiBjYXNlIG9mIFA4IHJlbmRlciB0YXJnZXRzIHRoZSBpbmRleCBpcyBzdG9yZWQgaW4gdGhlIGFscGhhIGNvbXBvbmVudCAqLwogICAgICAgICAgICAgICAgZm10ID0gR0xfQUxQSEE7CiAgICAgICAgICAgICAgICB0eXBlID0gR0xfVU5TSUdORURfQllURTsKICAgICAgICAgICAgICAgIG1lbSA9IGRlc3Q7CiAgICAgICAgICAgICAgICBicHAgPSBUaGlzLT5ieXRlc1BlclBpeGVsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLyogR0wgY2FuJ3QgcmV0dXJuIHBhbGV0dGl6ZWQgZGF0YSwgc28gcmVhZCBBUkdCIHBpeGVscyBpbnRvIGEKICAgICAgICAgICAgICAgICAqIHNlcGFyYXRlIGJsb2NrIG9mIG1lbW9yeSBhbmQgY29udmVydCB0aGVtIGludG8gcGFsZXR0aXplZCBmb3JtYXQKICAgICAgICAgICAgICAgICAqIGluIHNvZnR3YXJlLiBTbG93LCBidXQgaWYgdGhlIGFwcCBtZWFucyB0byB1c2UgcGFsZXR0aXplZCByZW5kZXIKICAgICAgICAgICAgICAgICAqIHRhcmdldHMgYW5kIGxvY2tzIGl0Li4uCiAgICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAgICogVXNlIEdMX1JHQiwgR0xfVU5TSUdORURfQllURSB0byByZWFkIHRoZSBzdXJmYWNlIGZvciBwZXJmb3JtYW5jZSByZWFzb25zCiAgICAgICAgICAgICAgICAgKiBEb24ndCB1c2UgR0xfQkdSIGFzIGluIHRoZSBXSU5FRDNERk1UX1I4RzhCOCBjYXNlLCBpbnN0ZWFkIHdhdGNoIG91dAogICAgICAgICAgICAgICAgICogZm9yIHRoZSBjb2xvciBjaGFubmVscyB3aGVuIHBhbGV0dGl6aW5nIHRoZSBjb2xvcnMuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGZtdCA9IEdMX1JHQjsKICAgICAgICAgICAgICAgIHR5cGUgPSBHTF9VTlNJR05FRF9CWVRFOwogICAgICAgICAgICAgICAgcGl0Y2ggKj0gMzsKICAgICAgICAgICAgICAgIG1lbSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5yZXNvdXJjZS5zaXplICogMyk7CiAgICAgICAgICAgICAgICBpZighbWVtKSB7CiAgICAgICAgICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5XG4iKTsKICAgICAgICAgICAgICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJwcCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWwgKiAzOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBtZW0gPSBkZXN0OwogICAgICAgICAgICBmbXQgPSBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0OwogICAgICAgICAgICB0eXBlID0gVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbFR5cGU7CiAgICAgICAgICAgIGJwcCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWw7CiAgICB9CgogICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19QQk8pIHsKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9QSVhFTF9QQUNLX0JVRkZFUl9BUkIsIFRoaXMtPnBibykpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRCdWZmZXJBUkIiKTsKICAgIH0KCiAgICBnbFJlYWRQaXhlbHMobG9jYWxfcmVjdC5sZWZ0LCBsb2NhbF9yZWN0LnRvcCwKICAgICAgICAgICAgICAgICBsb2NhbF9yZWN0LnJpZ2h0IC0gbG9jYWxfcmVjdC5sZWZ0LAogICAgICAgICAgICAgICAgIGxvY2FsX3JlY3QuYm90dG9tIC0gbG9jYWxfcmVjdC50b3AsCiAgICAgICAgICAgICAgICAgZm10LCB0eXBlLCBtZW0pOwogICAgdmNoZWNrR0xjYWxsKCJnbFJlYWRQaXhlbHMiKTsKCiAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX1BCTykgewogICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kQnVmZmVyQVJCKEdMX1BJWEVMX1BBQ0tfQlVGRkVSX0FSQiwgMCkpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRCdWZmZXJBUkIiKTsKCiAgICAgICAgLyogQ2hlY2sgaWYgd2UgbmVlZCB0byBmbGlwIHRoZSBpbWFnZS4gSWYgd2UgbmVlZCB0byBmbGlwIHVzZSBnbE1hcEJ1ZmZlckFSQgogICAgICAgICAqIHRvIGdldCBhIHBvaW50ZXIgdG8gaXQgYW5kIHBlcmZvcm0gdGhlIGZsaXBwaW5nIGluIHNvZnR3YXJlLiBUaGlzIGlzIGEgbG90CiAgICAgICAgICogZmFzdGVyIHRoYW4gY2FsbGluZyBnbFJlYWRQaXhlbHMgZm9yIGVhY2ggbGluZS4gSW4gY2FzZSB3ZSB3YW50IG1vcmUgc3BlZWQKICAgICAgICAgKiB3ZSBzaG91bGQgcmVyZW5kZXIgaXQgZmxpcHBlZCBpbiBhIEZCTyBhbmQgcmVhZCB0aGUgZGF0YSBiYWNrIGZyb20gdGhlIEZCTy4gKi8KICAgICAgICBpZighc3JjSXNVcHNpZGVEb3duKSB7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kQnVmZmVyQVJCKEdMX1BJWEVMX1VOUEFDS19CVUZGRVJfQVJCLCBUaGlzLT5wYm8pKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZEJ1ZmZlckFSQiIpOwoKICAgICAgICAgICAgbWVtID0gR0xfRVhUQ0FMTChnbE1hcEJ1ZmZlckFSQihHTF9QSVhFTF9VTlBBQ0tfQlVGRkVSX0FSQiwgR0xfUkVBRF9XUklURV9BUkIpKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsTWFwQnVmZmVyQVJCIik7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFRPRE86IE1lcmdlIHRoaXMgd2l0aCB0aGUgcGFsZXR0aXphdGlvbiBsb29wIGJlbG93IGZvciBQOCB0YXJnZXRzICovCiAgICBpZighc3JjSXNVcHNpZGVEb3duKSB7CiAgICAgICAgVUlOVCBsZW4sIG9mZjsKICAgICAgICAvKiBnbFJlYWRQaXhlbHMgcmV0dXJucyB0aGUgaW1hZ2UgdXBzaWRlIGRvd24sIGFuZCB0aGVyZSBpcyBubyB3YXkgdG8gcHJldmVudCB0aGlzLgogICAgICAgICAgICBGbGlwIHRoZSBsaW5lcyBpbiBzb2Z0d2FyZSAqLwogICAgICAgIGxlbiA9IChsb2NhbF9yZWN0LnJpZ2h0IC0gbG9jYWxfcmVjdC5sZWZ0KSAqIGJwcDsKICAgICAgICBvZmYgPSBsb2NhbF9yZWN0LmxlZnQgKiBicHA7CgogICAgICAgIHJvdyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4pOwogICAgICAgIGlmKCFyb3cpIHsKICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5XG4iKTsKICAgICAgICAgICAgaWYoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUDgpIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1lbSk7CiAgICAgICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIHRvcCA9IG1lbSArIHBpdGNoICogbG9jYWxfcmVjdC50b3A7CiAgICAgICAgYm90dG9tID0gKChCWVRFICopIG1lbSkgKyBwaXRjaCAqICggbG9jYWxfcmVjdC5ib3R0b20gLSBsb2NhbF9yZWN0LnRvcCAtIDEpOwogICAgICAgIGZvcihpID0gMDsgaSA8IChsb2NhbF9yZWN0LmJvdHRvbSAtIGxvY2FsX3JlY3QudG9wKSAvIDI7IGkrKykgewogICAgICAgICAgICBtZW1jcHkocm93LCB0b3AgKyBvZmYsIGxlbik7CiAgICAgICAgICAgIG1lbWNweSh0b3AgKyBvZmYsIGJvdHRvbSArIG9mZiwgbGVuKTsKICAgICAgICAgICAgbWVtY3B5KGJvdHRvbSArIG9mZiwgcm93LCBsZW4pOwogICAgICAgICAgICB0b3AgKz0gcGl0Y2g7CiAgICAgICAgICAgIGJvdHRvbSAtPSBwaXRjaDsKICAgICAgICB9CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcm93KTsKCiAgICAgICAgLyogVW5tYXAgdGhlIHRlbXAgUEJPIGJ1ZmZlciAqLwogICAgICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfUEJPKSB7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xVbm1hcEJ1ZmZlckFSQihHTF9QSVhFTF9VTlBBQ0tfQlVGRkVSX0FSQikpOwogICAgICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9QSVhFTF9VTlBBQ0tfQlVGRkVSX0FSQiwgMCkpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBGb3IgUDggdGV4dHVyZXMgd2UgbmVlZCB0byBwZXJmb3JtIGFuIGludmVyc2UgcGFsZXR0ZSBsb29rdXAuIFRoaXMgaXMgZG9uZSBieSBzZWFyY2hpbmcgZm9yIGEgcGFsZXR0ZQogICAgICogaW5kZXggd2hpY2ggbWF0Y2hlcyB0aGUgUkdCIHZhbHVlLiBOb3RlIHRoaXMgaXNuJ3QgZ3VhcmFudGVlZCB0byB3b3JrIHdoZW4gdGhlcmUgYXJlIG11bHRpcGxlIGVudHJpZXMgZm9yCiAgICAgKiB0aGUgc2FtZSBjb2xvciBidXQgd2UgaGF2ZSBubyBjaG9pY2UuCiAgICAgKiBJbiBjYXNlIG9mIHJlbmRlciB0YXJnZXRzLCB0aGUgaW5kZXggaXMgc3RvcmVkIGluIHRoZSBhbHBoYSBjb21wb25lbnQgc28gbm8gY29udmVyc2lvbiBpcyBuZWVkZWQuCiAgICAgKi8KICAgIGlmKChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9QOCkgJiYgIShUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpKSB7CiAgICAgICAgUEFMRVRURUVOVFJZICpwYWw7CiAgICAgICAgRFdPUkQgd2lkdGggPSBwaXRjaCAvIDM7CiAgICAgICAgaW50IHgsIHksIGM7CiAgICAgICAgaWYoVGhpcy0+cGFsZXR0ZSkgewogICAgICAgICAgICBwYWwgPSBUaGlzLT5wYWxldHRlLT5wYWxlbnRzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHBhbCA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UtPnBhbGV0dGVzW1RoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UtPmN1cnJlbnRQYWxldHRlXTsKICAgICAgICB9CgogICAgICAgIGZvcih5ID0gbG9jYWxfcmVjdC50b3A7IHkgPCBsb2NhbF9yZWN0LmJvdHRvbTsgeSsrKSB7CiAgICAgICAgICAgIGZvcih4ID0gbG9jYWxfcmVjdC5sZWZ0OyB4IDwgbG9jYWxfcmVjdC5yaWdodDsgeCsrKSB7CiAgICAgICAgICAgICAgICAvKiAgICAgICAgICAgICAgICAgICAgICBzdGFydCAgICAgICAgICAgICAgbGluZXMgICAgICAgICAgICBwaXhlbHMgICAgICAqLwogICAgICAgICAgICAgICAgQllURSAqYmx1ZSA9ICAoQllURSAqKSAoKEJZVEUgKikgbWVtKSArIHkgKiBwaXRjaCArIHggKiAoc2l6ZW9mKEJZVEUpICogMyk7CiAgICAgICAgICAgICAgICBCWVRFICpncmVlbiA9IGJsdWUgICsgMTsKICAgICAgICAgICAgICAgIEJZVEUgKnJlZCA9ICAgZ3JlZW4gKyAxOwoKICAgICAgICAgICAgICAgIGZvcihjID0gMDsgYyA8IDI1NjsgYysrKSB7CiAgICAgICAgICAgICAgICAgICAgaWYoKnJlZCAgID09IHBhbFtjXS5wZVJlZCAgICYmCiAgICAgICAgICAgICAgICAgICAgICAgKmdyZWVuID09IHBhbFtjXS5wZUdyZWVuICYmCiAgICAgICAgICAgICAgICAgICAgICAgKmJsdWUgID09IHBhbFtjXS5wZUJsdWUpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAqKChCWVRFICopIGRlc3QgKyB5ICogd2lkdGggKyB4KSA9IGM7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtZW0pOwogICAgfQogICAgTEVBVkVfR0woKTsKfQoKc3RhdGljIHZvaWQgc3VyZmFjZV9wcmVwYXJlX3N5c3RlbV9tZW1vcnkoSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcykgewogICAgLyogUGVyZm9ybWFuY2Ugb3B0aW1pemF0aW9uOiBDb3VudCBob3cgb2Z0ZW4gYSBzdXJmYWNlIGlzIGxvY2tlZCwgaWYgaXQgaXMgbG9ja2VkIHJlZ3VsYXJseSBkbyBub3QgdGhyb3cgYXdheSB0aGUgc3lzdGVtIG1lbW9yeSBjb3B5LgogICAgICogVGhpcyBhdm9pZHMgdGhlIG5lZWQgdG8gZG93bmxvYWQgdGhlIHN1cmZhY2UgZnJvbSBvcGVuZ2wgYWxsIHRoZSB0aW1lLiBUaGUgc3VyZmFjZSBpcyBzdGlsbCBkb3dubG9hZGVkIGlmIHRoZSBvcGVuZ2wgdGV4dHVyZSBpcwogICAgICogY2hhbmdlZAogICAgICovCiAgICBpZighKFRoaXMtPkZsYWdzICYgU0ZMQUdfRFlOTE9DSykpIHsKICAgICAgICBUaGlzLT5sb2NrQ291bnQrKzsKICAgICAgICAvKiBNQVhMT0NLQ09VTlQgaXMgZGVmaW5lZCBpbiB3aW5lZDNkX3ByaXZhdGUuaCAqLwogICAgICAgIGlmKFRoaXMtPmxvY2tDb3VudCA+IE1BWExPQ0tDT1VOVCkgewogICAgICAgICAgICBUUkFDRSgiU3VyZmFjZSBpcyBsb2NrZWQgcmVndWxhcmx5LCBub3QgZnJlZWluZyB0aGUgc3lzdGVtIG1lbW9yeSBjb3B5IGFueSBtb3JlXG4iKTsKICAgICAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfRFlOTE9DSzsKICAgICAgICB9CiAgICB9CgogICAgLyogQ3JlYXRlIGEgUEJPIGZvciBkeW5hbWljYWxseSBsb2NrZWQgc3VyZmFjZXMgYnV0IGRvbid0IGRvIGl0IGZvciBjb252ZXJ0ZWQgb3Igbm9uLXBvdzIgc3VyZmFjZXMuCiAgICAgKiBBbHNvIGRvbid0IGNyZWF0ZSBhIFBCTyBmb3Igc3lzdGVtbWVtIHN1cmZhY2VzLgogICAgICovCiAgICBpZihHTF9TVVBQT1JUKEFSQl9QSVhFTF9CVUZGRVJfT0JKRUNUKSAmJiAoVGhpcy0+RmxhZ3MgJiBTRkxBR19EWU5MT0NLKSAmJiAhKFRoaXMtPkZsYWdzICYgKFNGTEFHX1BCTyB8IFNGTEFHX0NPTlZFUlRFRCB8IFNGTEFHX05PTlBPVzIpKSAmJiAoVGhpcy0+cmVzb3VyY2UucG9vbCAhPSBXSU5FRDNEUE9PTF9TWVNURU1NRU0pKSB7CiAgICAgICAgR0xlbnVtIGVycm9yOwogICAgICAgIEVOVEVSX0dMKCk7CgogICAgICAgIEdMX0VYVENBTEwoZ2xHZW5CdWZmZXJzQVJCKDEsICZUaGlzLT5wYm8pKTsKICAgICAgICBlcnJvciA9IGdsR2V0RXJyb3IoKTsKICAgICAgICBpZihUaGlzLT5wYm8gPT0gMCB8fCBlcnJvciAhPSBHTF9OT19FUlJPUikgewogICAgICAgICAgICBFUlIoIkZhaWxlZCB0byBiaW5kIHRoZSBQQk8gd2l0aCBlcnJvciAlcyAoJSN4KVxuIiwgZGVidWdfZ2xlcnJvcihlcnJvciksIGVycm9yKTsKICAgICAgICB9CgogICAgICAgIFRSQUNFKCJBdHRhY2hpbmcgcGJvPSUjeCB0byAoJXApXG4iLCBUaGlzLT5wYm8sIFRoaXMpOwoKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9QSVhFTF9VTlBBQ0tfQlVGRkVSX0FSQiwgVGhpcy0+cGJvKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZEJ1ZmZlckFSQiIpOwoKICAgICAgICBHTF9FWFRDQUxMKGdsQnVmZmVyRGF0YUFSQihHTF9QSVhFTF9VTlBBQ0tfQlVGRkVSX0FSQiwgVGhpcy0+cmVzb3VyY2Uuc2l6ZSArIDQsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwgR0xfU1RSRUFNX0RSQVdfQVJCKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQnVmZmVyRGF0YUFSQiIpOwoKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9QSVhFTF9VTlBBQ0tfQlVGRkVSX0FSQiwgMCkpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRCdWZmZXJBUkIiKTsKCiAgICAgICAgLyogV2UgZG9uJ3QgbmVlZCB0aGUgc3lzdGVtIG1lbW9yeSBhbnltb3JlIGFuZCB3ZSBjYW4ndCBldmVuIHVzZSBpdCBmb3IgUEJPcyAqLwogICAgICAgIGlmKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19DTElFTlQpKSB7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnJlc291cmNlLmhlYXBNZW1vcnkpOwogICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5oZWFwTWVtb3J5ID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gTlVMTDsKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19QQk87CiAgICAgICAgTEVBVkVfR0woKTsKICAgIH0gZWxzZSBpZighKFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSB8fCBUaGlzLT5GbGFncyAmIFNGTEFHX1BCTykpIHsKICAgICAgICAvKiBXaGF0ZXZlciBzdXJmYWNlIHdlIGhhdmUsIG1ha2Ugc3VyZSB0aGF0IHRoZXJlIGlzIG1lbW9yeSBhbGxvY2F0ZWQgZm9yIHRoZSBkb3dubG9hZGVkIGNvcHksCiAgICAgICAgICogb3IgYSBwYm8gdG8gbWFwCiAgICAgICAgICovCiAgICAgICAgaWYoIVRoaXMtPnJlc291cmNlLmhlYXBNZW1vcnkpIHsKICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuaGVhcE1lbW9yeSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpICwwICwgVGhpcy0+cmVzb3VyY2Uuc2l6ZSArIFJFU09VUkNFX0FMSUdOTUVOVCk7CiAgICAgICAgfQogICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9CiAgICAgICAgICAgICAgICAoQllURSAqKSgoKFVMT05HX1BUUikgVGhpcy0+cmVzb3VyY2UuaGVhcE1lbW9yeSArIChSRVNPVVJDRV9BTElHTk1FTlQgLSAxKSkgJiB+KFJFU09VUkNFX0FMSUdOTUVOVCAtIDEpKTsKICAgICAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX0lOU1lTTUVNKSB7CiAgICAgICAgICAgIEVSUigiU3VyZmFjZSB3aXRob3V0IG1lbW9yeSBvciBwYm8gaGFzIFNGTEFHX0lOU1lTTUVNIHNldCFcbiIpOwogICAgICAgIH0KICAgIH0KfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfTG9ja1JlY3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgV0lORUQzRExPQ0tFRF9SRUNUKiBwTG9ja2VkUmVjdCwgQ09OU1QgUkVDVCogcFJlY3QsIERXT1JEIEZsYWdzKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgKm15RGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIElXaW5lRDNEU3dhcENoYWluICpzd2FwY2hhaW4gPSBOVUxMOwoKICAgIFRSQUNFKCIoJXApIDogcmVjdEAlcCBmbGFncyglMDh4KSwgb3V0cHV0IGxvY2tlZFJlY3RAJXAsIG1lbW9yeUAlcFxuIiwgVGhpcywgcFJlY3QsIEZsYWdzLCBwTG9ja2VkUmVjdCwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKCiAgICAvKiBUaGlzIGlzIGFsc28gZG9uZSBpbiB0aGUgYmFzZSBjbGFzcywgYnV0IHdlIGhhdmUgdG8gdmVyaWZ5IHRoaXMgYmVmb3JlIGxvYWRpbmcgYW55IGRhdGEgZnJvbQogICAgICogZ2wgaW50byB0aGUgc3lzbWVtIGNvcHkuIFRoZSBQQk8gbWF5IGJlIG1hcHBlZCwgYSBkaWZmZXJlbnQgcmVjdGFuZ2xlIGxvY2tlZCwgdGhlIGRpc2NhcmQgZmxhZwogICAgICogbWF5IGludGVyZmVyZSwgYW5kIGFsbCBvdGhlciBiYWQgdGhpbmdzIG1heSBoYXBwZW4KICAgICAqLwogICAgaWYgKFRoaXMtPkZsYWdzICYgU0ZMQUdfTE9DS0VEKSB7CiAgICAgICAgV0FSTigiU3VyZmFjZSBpcyBhbHJlYWR5IGxvY2tlZCwgcmV0dXJuaW5nIEQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19MT0NLRUQ7CgogICAgaWYgKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19MT0NLQUJMRSkpCiAgICB7CiAgICAgICAgVFJBQ0UoIldhcm5pbmc6IHRyeWluZyB0byBsb2NrIHVubG9ja2FibGUgc3VyZkAlcFxuIiwgVGhpcyk7CiAgICB9CgogICAgaWYgKEZsYWdzICYgV0lORUQzRExPQ0tfRElTQ0FSRCkgewogICAgICAgIC8qIFNldCBTRkxBR19JTlNZU01FTSwgc28gd2UnbGwgbmV2ZXIgdHJ5IHRvIGRvd25sb2FkIHRoZSBkYXRhIGZyb20gdGhlIHRleHR1cmUuICovCiAgICAgICAgVFJBQ0UoIldJTkVEM0RMT0NLX0RJU0NBUkQgZmxhZyBwYXNzZWQsIG1hcmtpbmcgbG9jYWwgY29weSBhcyB1cCB0byBkYXRlXG4iKTsKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19JTlNZU01FTTsKICAgIH0KCiAgICBpZiAoVGhpcy0+RmxhZ3MgJiBTRkxBR19JTlNZU01FTSkgewogICAgICAgIFRSQUNFKCJMb2NhbCBjb3B5IGlzIHVwIHRvIGRhdGUsIG5vdCBkb3dubG9hZGluZyBkYXRhXG4iKTsKICAgICAgICBzdXJmYWNlX3ByZXBhcmVfc3lzdGVtX21lbW9yeShUaGlzKTsgLyogTWFrZXMgc3VyZSBtZW1vcnkgaXMgYWxsb2NhdGVkICovCiAgICAgICAgZ290byBsb2NrX2VuZDsKICAgIH0KCiAgICAvKiBOb3cgZG93bmxvYWQgdGhlIHN1cmZhY2UgY29udGVudCBmcm9tIG9wZW5nbAogICAgICogVXNlIHRoZSByZW5kZXIgdGFyZ2V0IHJlYWRiYWNrIGlmIHRoZSBzdXJmYWNlIGlzIG9uIGEgc3dhcGNoYWluKD1vbnNjcmVlbiByZW5kZXIgdGFyZ2V0KSBvciB0aGUgY3VycmVudCBwcmltYXJ5IHRhcmdldAogICAgICogT2Zmc2NyZWVuIHRhcmdldHMgd2hpY2ggYXJlIG5vdCBhY3RpdmUgYXQgdGhlIG1vbWVudCBvciBhcmUgaGlnaGVyIHRhcmdldHMoZmJvcykgY2FuIGJlIGxvY2tlZCB3aXRoIHRoZSB0ZXh0dXJlIHBhdGgKICAgICAqLwogICAgSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihpZmFjZSwgJklJRF9JV2luZUQzRFN3YXBDaGFpbiwgKHZvaWQgKiopJnN3YXBjaGFpbik7CiAgICBpZihzd2FwY2hhaW4gfHwgaWZhY2UgPT0gbXlEZXZpY2UtPnJlbmRlcl90YXJnZXRzWzBdKSB7CiAgICAgICAgY29uc3QgUkVDVCAqcGFzc19yZWN0ID0gcFJlY3Q7CgogICAgICAgIC8qIElXaW5lRDNEU3VyZmFjZV9Mb2FkTG9jYXRpb24gZG9lcyBub3QgY2hlY2sgaWYgdGhlIHJlY3RhbmdsZSBzcGVjaWZpZXMgdGhlIGZ1bGwgc3VyZmFjZXMKICAgICAgICAgKiBiZWNhdXNlIG1vc3QgY2FsbGVyIGZ1bmN0aW9ucyBkbyBub3QgbmVlZCB0aGF0LiBTbyBkbyB0aGF0IGhlcmUKICAgICAgICAgKi8KICAgICAgICBpZihwUmVjdCAmJgogICAgICAgICAgIHBSZWN0LT50b3AgICAgPT0gMCAmJgogICAgICAgICAgIHBSZWN0LT5sZWZ0ICAgPT0gMCAmJgogICAgICAgICAgIHBSZWN0LT5yaWdodCAgPT0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGggJiYKICAgICAgICAgICBwUmVjdC0+Ym90dG9tID09IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCkgewogICAgICAgICAgICBwYXNzX3JlY3QgPSBOVUxMOwogICAgICAgIH0KCiAgICAgICAgc3dpdGNoKHdpbmVkM2Rfc2V0dGluZ3MucmVuZGVydGFyZ2V0bG9ja19tb2RlKSB7CiAgICAgICAgICAgIGNhc2UgUlRMX1RFWERSQVc6CiAgICAgICAgICAgIGNhc2UgUlRMX1RFWFRFWDoKICAgICAgICAgICAgICAgIEZJWE1FKCJSZWFkaW5nIGZyb20gcmVuZGVyIHRhcmdldCB3aXRoIGEgdGV4dHVyZSBpc24ndCBpbXBsZW1lbnRlZCB5ZXQsIGZhbGxpbmcgYmFjayB0byBmcmFtZWJ1ZmZlciByZWFkaW5nXG4iKTsKI2lmIDAKICAgICAgICAgICAgICAgIC8qIERpc2FibGVkIGZvciBub3cuIExvYWRMb2NhdGlvbiBwcmVmZXJzIHRoZSB0ZXh0dXJlIG92ZXIgdGhlIGRyYXdhYmxlIGFzIHRoZSBzb3VyY2UuIFNvIGlmIHdlIGNvcHkgdG8gdGhlCiAgICAgICAgICAgICAgICAgKiB0ZXh0dXJlIGZpcnN0LCB0aGVuIHRvIHN5c21lbSwgd2UnbGwgYXZvaWQgZ2xSZWFkUGl4ZWxzIGFuZCB1c2UgZ2xDb3B5VGV4SW1hZ2UgYW5kIGdsR2V0VGV4SW1hZ2UyRCBpbnN0ZWFkLgogICAgICAgICAgICAgICAgICogVGhpcyBtYXkgYmUgZmFzdGVyIG9uIHNvbWUgY2FyZHMKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvYWRMb2NhdGlvbihpZmFjZSwgU0ZMQUdfSU5URVhUVVJFLCBOVUxMIC8qIE5vIHBhcnRpYWwgdGV4dHVyZSBjb3B5IHlldCAqLyk7CiNlbmRpZgogICAgICAgICAgICAgICAgLyogZHJvcCB0aHJvdWdoICovCgogICAgICAgICAgICBjYXNlIFJUTF9BVVRPOgogICAgICAgICAgICBjYXNlIFJUTF9SRUFERFJBVzoKICAgICAgICAgICAgY2FzZSBSVExfUkVBRFRFWDoKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9Mb2FkTG9jYXRpb24oaWZhY2UsIFNGTEFHX0lOU1lTTUVNLCBwUmVjdCk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgUlRMX0RJU0FCTEU6CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgaWYoc3dhcGNoYWluKSBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKHN3YXBjaGFpbik7CgogICAgfSBlbHNlIGlmKGlmYWNlID09IG15RGV2aWNlLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KSB7CiAgICAgICAgLyoqIHRoZSBkZXB0aCBzdGVuY2lsIGluIG9wZW5HTCBoYXMgYSBmb3JtYXQgb2YgR0xfRkxPQVQKICAgICAgICAgKiB3aGljaCBzaG91bGQgYmUgZ29vZCBmb3IgV0lORUQzREZNVF9EMTZfTE9DS0FCTEUKICAgICAgICAgKiBhbmQgV0lORUQzREZNVF9EMTYKICAgICAgICAgKiBpdCBpcyB1bmNsZWFyIHdoYXQgZm9ybWF0IHRoZSBzdGVuY2lsIGJ1ZmZlciBpcyBpbiBleGNlcHQuCiAgICAgICAgICogJ0VhY2ggaW5kZXggaXMgY29udmVydGVkIHRvIGZpeGVkIHBvaW50Li4uCiAgICAgICAgICogSWYgR0xfTUFQX1NURU5DSUwgaXMgR0xfVFJVRSwgaW5kaWNlcyBhcmUgcmVwbGFjZWQgYnkgdGhlaXIKICAgICAgICAgKiBtYXBwaW5ncyBpbiB0aGUgdGFibGUgR0xfUElYRUxfTUFQX1NfVE9fUy4KICAgICAgICAgKiBnbFJlYWRQaXhlbHMoVGhpcy0+bG9ja2VkUmVjdC5sZWZ0LAogICAgICAgICAqICAgICAgICAgICAgIFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tIC0gaiAtIDEsCiAgICAgICAgICogICAgICAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5yaWdodCAtIFRoaXMtPmxvY2tlZFJlY3QubGVmdCwKICAgICAgICAgKiAgICAgICAgICAgICAxLAogICAgICAgICAqICAgICAgICAgICAgIEdMX0RFUFRIX0NPTVBPTkVOVCwKICAgICAgICAgKiAgICAgICAgICAgICB0eXBlLAogICAgICAgICAqICAgICAgICAgICAgIChjaGFyICopcExvY2tlZFJlY3QtPnBCaXRzICsgKHBMb2NrZWRSZWN0LT5QaXRjaCAqIChqLVRoaXMtPmxvY2tlZFJlY3QudG9wKSkpOwogICAgICAgICAqCiAgICAgICAgICogRGVwdGggU3RlbmNpbCBzdXJmYWNlcyB3aGljaCBhcmUgbm90IHRoZSBjdXJyZW50IGRlcHRoIHN0ZW5jaWwgdGFyZ2V0IHNob3VsZCBoYXZlIHRoZWlyIGRhdGEgaW4gYQogICAgICAgICAqIGdsIHRleHR1cmUobmV4dCBwYXRoKSwgb3IgaW4gbG9jYWwgbWVtb3J5KGVhcmx5IHJldHVybiBiZWNhdXNlIG9mIHNldCBTRkxBR19JTlNZU01FTSBhYm92ZSkuIElmCiAgICAgICAgICogbm9uZSBvZiB0aGF0IGlzIHRoZSBjYXNlIHRoZSBwcm9ibGVtIGlzIG5vdCBpbiB0aGlzIGZ1bmN0aW9uIDotKQogICAgICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgICAgICBGSVhNRSgiRGVwdGggc3RlbmNpbCBsb2NraW5nIG5vdCBzdXBwb3J0ZWQgeWV0XG4iKTsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogVGhpcyBwYXRoIGlzIGZvciBub3JtYWwgc3VyZmFjZXMsIG9mZnNjcmVlbiByZW5kZXIgdGFyZ2V0cyBhbmQgZXZlcnl0aGluZyBlbHNlIHRoYXQgaXMgaW4gYSBnbCB0ZXh0dXJlICovCiAgICAgICAgVFJBQ0UoImxvY2tpbmcgYW4gb3JkaW5hcnkgc3VyZmFjZVxuIik7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvYWRMb2NhdGlvbihpZmFjZSwgU0ZMQUdfSU5TWVNNRU0sIE5VTEwgLyogbm8gcGFydGlhbCBsb2NraW5nIGZvciB0ZXh0dXJlcyB5ZXQgKi8pOwogICAgfQoKbG9ja19lbmQ6CiAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX1BCTykgewogICAgICAgIEFjdGl2YXRlQ29udGV4dChteURldmljZSwgbXlEZXZpY2UtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQsIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9QSVhFTF9VTlBBQ0tfQlVGRkVSX0FSQiwgVGhpcy0+cGJvKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZEJ1ZmZlckFSQiIpOwoKICAgICAgICAvKiBUaGlzIHNob3VsZG4ndCBoYXBwZW4gYnV0IGNvdWxkIG9jY3VyIGlmIHNvbWUgb3RoZXIgZnVuY3Rpb24gZGlkbid0IGhhbmRsZSB0aGUgUEJPIHByb3Blcmx5ICovCiAgICAgICAgaWYoVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KSB7CiAgICAgICAgICAgIEVSUigiVGhlIHN1cmZhY2UgYWxyZWFkeSBoYXMgUEJPIG1lbW9yeSBhbGxvY2F0ZWQhXG4iKTsKICAgICAgICB9CgogICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IEdMX0VYVENBTEwoZ2xNYXBCdWZmZXJBUkIoR0xfUElYRUxfVU5QQUNLX0JVRkZFUl9BUkIsIEdMX1JFQURfV1JJVEVfQVJCKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsTWFwQnVmZmVyQVJCIik7CgogICAgICAgIC8qIE1ha2Ugc3VyZSB0aGUgcGJvIGlzbid0IHNldCBhbnltb3JlIGluIG9yZGVyIG5vdCB0byBicmVhayBub24tcGJvIGNhbGxzICovCiAgICAgICAgR0xfRVhUQ0FMTChnbEJpbmRCdWZmZXJBUkIoR0xfUElYRUxfVU5QQUNLX0JVRkZFUl9BUkIsIDApKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kQnVmZmVyQVJCIik7CgogICAgICAgIExFQVZFX0dMKCk7CiAgICB9CgogICAgaWYgKEZsYWdzICYgKFdJTkVEM0RMT0NLX05PX0RJUlRZX1VQREFURSB8IFdJTkVEM0RMT0NLX1JFQURPTkxZKSkgewogICAgICAgIC8qIERvbid0IGRpcnRpZnkgKi8KICAgIH0gZWxzZSB7CiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZSAqcEJhc2VUZXh0dXJlOwogICAgICAgIC8qKgogICAgICAgICAqIERpcnRpZnkgb24gbG9jawogICAgICAgICAqIGFzIHNlZW4gaW4gbXNkbiBkb2NzCiAgICAgICAgICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0FkZERpcnR5UmVjdChpZmFjZSwgcFJlY3QpOwoKICAgICAgICAvKiogRGlydGlmeSBDb250YWluZXIgaWYgbmVlZGVkICovCiAgICAgICAgaWYgKFdJTkVEM0RfT0sgPT0gSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihpZmFjZSwgJklJRF9JV2luZUQzREJhc2VUZXh0dXJlLCAodm9pZCAqKikmcEJhc2VUZXh0dXJlKSAmJiBwQmFzZVRleHR1cmUgIT0gTlVMTCkgewogICAgICAgICAgICBUUkFDRSgiTWFraW5nIGNvbnRhaW5lciBkaXJ0eVxuIik7CiAgICAgICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfU2V0RGlydHkocEJhc2VUZXh0dXJlLCBUUlVFKTsKICAgICAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9SZWxlYXNlKHBCYXNlVGV4dHVyZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVFJBQ0UoIlN1cmZhY2UgaXMgc3RhbmRhbG9uZSwgbm8gbmVlZCB0byBkaXJ0eSB0aGUgY29udGFpbmVyXG4iKTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0xvY2tSZWN0KGlmYWNlLCBwTG9ja2VkUmVjdCwgcFJlY3QsIEZsYWdzKTsKfQoKc3RhdGljIHZvaWQgZmx1c2hfdG9fZnJhbWVidWZmZXJfZHJhd3BpeGVscyhJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzKSB7CiAgICBHTGludCAgcHJldl9zdG9yZTsKICAgIEdMaW50ICBwcmV2X3Jhc3RlcnBvc1s0XTsKICAgIEdMaW50IHNraXBCeXRlcyA9IDA7CiAgICBCT09MIHN0b3JlY2hhbmdlZCA9IEZBTFNFLCBtZW1vcnlfYWxsb2NhdGVkID0gRkFMU0U7CiAgICBHTGludCBmbXQsIHR5cGU7CiAgICBCWVRFICptZW07CiAgICBVSU5UIGJwcDsKICAgIFVJTlQgcGl0Y2ggPSBJV2luZUQzRFN1cmZhY2VfR2V0UGl0Y2goKElXaW5lRDNEU3VyZmFjZSAqKSBUaGlzKTsgICAgLyogdGFyZ2V0IGlzIGFyZ2IsIDQgYnl0ZSAqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpteURldmljZSA9IChJV2luZUQzRERldmljZUltcGwgKikgVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqc3dhcGNoYWluOwoKICAgIC8qIEFjdGl2YXRlIHRoZSBjb3JyZWN0IGNvbnRleHQgZm9yIHRoZSByZW5kZXIgdGFyZ2V0ICovCiAgICBBY3RpdmF0ZUNvbnRleHQobXlEZXZpY2UsIChJV2luZUQzRFN1cmZhY2UgKikgVGhpcywgQ1RYVVNBR0VfQkxJVCk7CiAgICBFTlRFUl9HTCgpOwoKICAgIElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoKElXaW5lRDNEU3VyZmFjZSAqKSBUaGlzLCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikmc3dhcGNoYWluKTsKICAgIGlmKCFzd2FwY2hhaW4pIHsKICAgICAgICAvKiBQcmltYXJ5IG9mZnNjcmVlbiByZW5kZXIgdGFyZ2V0ICovCiAgICAgICAgVFJBQ0UoIk9mZnNjcmVlbiByZW5kZXIgdGFyZ2V0XG4iKTsKICAgICAgICBnbERyYXdCdWZmZXIobXlEZXZpY2UtPm9mZnNjcmVlbkJ1ZmZlcik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcihteURldmljZS0+b2Zmc2NyZWVuQnVmZmVyKSIpOwogICAgfSBlbHNlIHsKICAgICAgICBHTGVudW0gYnVmZmVyID0gc3VyZmFjZV9nZXRfZ2xfYnVmZmVyKChJV2luZUQzRFN1cmZhY2UgKikgVGhpcywgKElXaW5lRDNEU3dhcENoYWluICopc3dhcGNoYWluKTsKICAgICAgICBUUkFDRSgiVW5sb2NraW5nICUjeCBidWZmZXJcbiIsIGJ1ZmZlcik7CiAgICAgICAgZ2xEcmF3QnVmZmVyKGJ1ZmZlcik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlciIpOwoKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKChJV2luZUQzRFN3YXBDaGFpbiAqKXN3YXBjaGFpbik7CiAgICB9CgogICAgZ2xGbHVzaCgpOwogICAgdmNoZWNrR0xjYWxsKCJnbEZsdXNoIik7CiAgICBnbEdldEludGVnZXJ2KEdMX1BBQ0tfU1dBUF9CWVRFUywgJnByZXZfc3RvcmUpOwogICAgdmNoZWNrR0xjYWxsKCJnbEludGVnZXJ2Iik7CiAgICBnbEdldEludGVnZXJ2KEdMX0NVUlJFTlRfUkFTVEVSX1BPU0lUSU9OLCAmcHJldl9yYXN0ZXJwb3NbMF0pOwogICAgdmNoZWNrR0xjYWxsKCJnbEludGVnZXJ2Iik7CiAgICBnbFBpeGVsWm9vbSgxLjAsIC0xLjApOwogICAgdmNoZWNrR0xjYWxsKCJnbFBpeGVsWm9vbSIpOwoKICAgIC8qIElmIG5vdCBmdWxsc2NyZWVuLCB3ZSBuZWVkIHRvIHNraXAgYSBudW1iZXIgb2YgYnl0ZXMgdG8gZmluZCB0aGUgbmV4dCByb3cgb2YgZGF0YSAqLwogICAgZ2xHZXRJbnRlZ2VydihHTF9VTlBBQ0tfUk9XX0xFTkdUSCwgJnNraXBCeXRlcyk7CiAgICBnbFBpeGVsU3RvcmVpKEdMX1VOUEFDS19ST1dfTEVOR1RILCBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCk7CgogICAgZ2xSYXN0ZXJQb3MzaShUaGlzLT5sb2NrZWRSZWN0LmxlZnQsIFRoaXMtPmxvY2tlZFJlY3QudG9wLCAxKTsKICAgIHZjaGVja0dMY2FsbCgiZ2xSYXN0ZXJQb3MyZiIpOwoKICAgIC8qIFNvbWUgZHJpdmVycyhyYWRlb24gZHJpLCBvdGhlcnM/KSBkb24ndCBsaWtlIGV4Y2VwdGlvbnMgZHVyaW5nCiAgICAgKiBnbERyYXdQaXhlbHMuIElmIHRoZSBzdXJmYWNlIGlzIGEgRElCIHNlY3Rpb24sIGl0IG1pZ2h0IGJlIGluIEdESU1vZGUKICAgICAqIGFmdGVyIFJlbGVhc2VEQy4gUmVhZGluZyBpdCB3aWxsIGNhdXNlIGFuIGV4Y2VwdGlvbiwgd2hpY2ggeDExZHJ2IHdpbGwKICAgICAqIGNhdGNoIHRvIHB1dCB0aGUgZGliIHNlY3Rpb24gaW4gSW5TeW5jIG1vZGUsIHdoaWNoIGxlYWRzIHRvIGEgY3Jhc2gKICAgICAqIGFuZCBhIGJsb2NrZWQgeCBzZXJ2ZXIgb24gbXkgcmFkZW9uIGNhcmQuCiAgICAgKgogICAgICogVGhlIGZvbGxvd2luZyBsaW5lcyByZWFkIHRoZSBkaWIgc2VjdGlvbiBzbyBpdCBpcyBwdXQgaW4gaW5TeW5jIG1vZGUKICAgICAqIGJlZm9yZSBnbERyYXdQaXhlbHMgaXMgY2FsbGVkIGFuZCB0aGUgY3Jhc2ggaXMgcHJldmVudGVkLiBUaGVyZSB3b24ndAogICAgICogYmUgYW55IGludGVyZmVyaW5nIGdkaSBhY2Nlc3NlcywgYmVjYXVzZSBVbmxvY2tSZWN0IGlzIGNhbGxlZCBmcm9tCiAgICAgKiBSZWxlYXNlREMsIGFuZCB0aGUgYXBwIHdvbid0IHVzZSB0aGUgZGMgYW55IG1vcmUgYWZ0ZXJ3YXJkcy4KICAgICAqLwogICAgaWYoKFRoaXMtPkZsYWdzICYgU0ZMQUdfRElCU0VDVElPTikgJiYgIShUaGlzLT5GbGFncyAmIFNGTEFHX1BCTykpIHsKICAgICAgICB2b2xhdGlsZSBCWVRFIHJlYWQ7CiAgICAgICAgcmVhZCA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeVswXTsKICAgIH0KCiAgICBzd2l0Y2ggKFRoaXMtPnJlc291cmNlLmZvcm1hdCkgewogICAgICAgIC8qIE5vIHNwZWNpYWwgY2FyZSBuZWVkZWQgKi8KICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQTRSNEc0QjQ6CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1I1RzZCNToKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQTFSNUc1QjU6CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1I4RzhCODoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDRSNEc0QjQ6CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1gxUjVHNUI1OgogICAgICAgICAgICB0eXBlID0gVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbFR5cGU7CiAgICAgICAgICAgIGZtdCA9IFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXQ7CiAgICAgICAgICAgIG1lbSA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICAgICAgYnBwID0gVGhpcy0+Ynl0ZXNQZXJQaXhlbDsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIC8qIEluIHRoZSBwYXN0IHRpbWVzIHdlIHVzZWQgdG8gc2V0IHRoZSBYIGNoYW5uZWwgb2YgWDhSOEc4QjggYW5kIHRoZSBhYm92ZSBmb3JtYXRzIHRvCiAgICAgICAgICogMS4wIGJlY2F1c2UgaXQgaGFwcGVuZWQgdG8gZml4IHRoZSBpbnRybyBtb3ZpZSBpbiBQaXJhdGVzLiBIb3dldmVyLCB0aGlzIHNlZW1zIHdyb25nLgogICAgICAgICAqIElmIHRoZSBnYW1lIHVzZXMgYW4gWDhSOEc4QjggYmFjayBidWZmZXIgdGhlIEdMIGFscGhhIGNoYW5uZWwgc2hvdWxkIG5vdCBtYWtlIGFueSBkaWZmZXJlbmNlcywKICAgICAgICAgKiBhbmQgdGhlIGJ1ZyBtdXN0IGJlIHNvbWV3aGVyZSBlbHNlLiBJZiB3ZSByZWFsbHkgaGF2ZSB0byBzZXQgdGhlIGFscGhhIGNoYW5uZWwgdG8gMS4wIGluCiAgICAgICAgICogdGhpcyBjYXNlIGRvIGl0IGJ5IGNsZWFyaW5nIGl0IGFmdGVyIHRoZSBkcmF3IGluc3RlYWQgb2YgZml4aW5nIGl0IHVwIGluIHRoZSBDUFUuIEJsZW5kaW5nCiAgICAgICAgICogaXMgZGlzYWJsZWQgdmlhIENUWFVTQUdFX0JMSVQgY29udGV4dCBzZXR1cCwgc28gaW4gdGhlIGdsRHJhd1BpeGVscyBjYWxsIGl0IGRvZXMgbm90CiAgICAgICAgICogaGF2ZSBhbnkgZWZmZWN0cwogICAgICAgICAqLwogICAgICAgIGNhc2UgV0lORUQzREZNVF9YOFI4RzhCODoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQThSOEc4Qjg6CiAgICAgICAgewogICAgICAgICAgICBnbFBpeGVsU3RvcmVpKEdMX1BBQ0tfU1dBUF9CWVRFUywgVFJVRSk7CiAgICAgICAgICAgIHZjaGVja0dMY2FsbCgiZ2xQaXhlbFN0b3JlaSIpOwogICAgICAgICAgICBzdG9yZWNoYW5nZWQgPSBUUlVFOwogICAgICAgICAgICB0eXBlID0gVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbFR5cGU7CiAgICAgICAgICAgIGZtdCA9IFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXQ7CiAgICAgICAgICAgIG1lbSA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICAgICAgYnBwID0gVGhpcy0+Ynl0ZXNQZXJQaXhlbDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9BMlIxMEcxMEIxMDoKICAgICAgICB7CiAgICAgICAgICAgIGdsUGl4ZWxTdG9yZWkoR0xfUEFDS19TV0FQX0JZVEVTLCBUUlVFKTsKICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbFBpeGVsU3RvcmVpIik7CiAgICAgICAgICAgIHN0b3JlY2hhbmdlZCA9IFRSVUU7CiAgICAgICAgICAgIHR5cGUgPSBUaGlzLT5nbERlc2NyaXB0aW9uLmdsVHlwZTsKICAgICAgICAgICAgZm10ID0gVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdDsKICAgICAgICAgICAgbWVtID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwogICAgICAgICAgICBicHAgPSBUaGlzLT5ieXRlc1BlclBpeGVsOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1A4OgogICAgICAgIHsKICAgICAgICAgICAgaW50IGhlaWdodCA9IFRoaXMtPmdsUmVjdC5ib3R0b20gLSBUaGlzLT5nbFJlY3QudG9wOwogICAgICAgICAgICB0eXBlID0gR0xfVU5TSUdORURfQllURTsKICAgICAgICAgICAgZm10ID0gR0xfUkdCQTsKCiAgICAgICAgICAgIG1lbSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5yZXNvdXJjZS5zaXplICogc2l6ZW9mKERXT1JEKSk7CiAgICAgICAgICAgIGlmKCFtZW0pIHsKICAgICAgICAgICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeVxuIik7CiAgICAgICAgICAgICAgICBnb3RvIGNsZWFudXA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbWVtb3J5X2FsbG9jYXRlZCA9IFRSVUU7CiAgICAgICAgICAgIGQzZGZtdF9jb252ZXJ0X3N1cmZhY2UoVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXRjaCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaXRjaCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGl0Y2ggKiA0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTlZFUlRfUEFMRVRURUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcyk7CiAgICAgICAgICAgIGJwcCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWwgKiA0OwogICAgICAgICAgICBwaXRjaCAqPSA0OwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIEZvcm1hdCAldSBpbiBsb2NraW5nIGZ1bmNcbiIsIFRoaXMtPnJlc291cmNlLmZvcm1hdCk7CgogICAgICAgICAgICAvKiBHaXZlIGl0IGEgdHJ5ICovCiAgICAgICAgICAgIHR5cGUgPSBUaGlzLT5nbERlc2NyaXB0aW9uLmdsVHlwZTsKICAgICAgICAgICAgZm10ID0gVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdDsKICAgICAgICAgICAgbWVtID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwogICAgICAgICAgICBicHAgPSBUaGlzLT5ieXRlc1BlclBpeGVsOwogICAgfQoKICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfUEJPKSB7CiAgICAgICAgR0xfRVhUQ0FMTChnbEJpbmRCdWZmZXJBUkIoR0xfUElYRUxfVU5QQUNLX0JVRkZFUl9BUkIsIFRoaXMtPnBibykpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRCdWZmZXJBUkIiKTsKICAgIH0KCiAgICBnbERyYXdQaXhlbHMoVGhpcy0+bG9ja2VkUmVjdC5yaWdodCAtIFRoaXMtPmxvY2tlZFJlY3QubGVmdCwKICAgICAgICAgICAgICAgICAoVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20gLSBUaGlzLT5sb2NrZWRSZWN0LnRvcCktMSwKICAgICAgICAgICAgICAgICBmbXQsIHR5cGUsCiAgICAgICAgICAgICAgICAgbWVtICsgYnBwICogVGhpcy0+bG9ja2VkUmVjdC5sZWZ0ICsgcGl0Y2ggKiBUaGlzLT5sb2NrZWRSZWN0LnRvcCk7CiAgICBjaGVja0dMY2FsbCgiZ2xEcmF3UGl4ZWxzIik7CgpjbGVhbnVwOgogICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19QQk8pIHsKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9QSVhFTF9VTlBBQ0tfQlVGRkVSX0FSQiwgMCkpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRCdWZmZXJBUkIiKTsKICAgIH0KCiAgICBnbFBpeGVsWm9vbSgxLjAsMS4wKTsKICAgIHZjaGVja0dMY2FsbCgiZ2xQaXhlbFpvb20iKTsKCiAgICBnbFJhc3RlclBvczNpdigmcHJldl9yYXN0ZXJwb3NbMF0pOwogICAgdmNoZWNrR0xjYWxsKCJnbFJhc3RlclBvczNpdiIpOwoKICAgIC8qIFJlc2V0IHRvIHByZXZpb3VzIHBhY2sgcm93IGxlbmd0aCAqLwogICAgZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfUk9XX0xFTkdUSCwgc2tpcEJ5dGVzKTsKICAgIHZjaGVja0dMY2FsbCgiZ2xQaXhlbFN0b3JlaSBHTF9VTlBBQ0tfUk9XX0xFTkdUSCIpOwogICAgaWYoc3RvcmVjaGFuZ2VkKSB7CiAgICAgICAgZ2xQaXhlbFN0b3JlaShHTF9QQUNLX1NXQVBfQllURVMsIHByZXZfc3RvcmUpOwogICAgICAgIHZjaGVja0dMY2FsbCgiZ2xQaXhlbFN0b3JlaSBHTF9QQUNLX1NXQVBfQllURVMiKTsKICAgIH0KCiAgICBpZihtZW1vcnlfYWxsb2NhdGVkKSBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtZW0pOwoKICAgIGlmKCFzd2FwY2hhaW4pIHsKICAgICAgICBnbERyYXdCdWZmZXIobXlEZXZpY2UtPm9mZnNjcmVlbkJ1ZmZlcik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcihteURldmljZS0+b2Zmc2NyZWVuQnVmZmVyKSIpOwogICAgfSBlbHNlIGlmKHN3YXBjaGFpbi0+YmFja0J1ZmZlcikgewogICAgICAgIGdsRHJhd0J1ZmZlcihHTF9CQUNLKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKEdMX0JBQ0spIik7CiAgICB9IGVsc2UgewogICAgICAgIGdsRHJhd0J1ZmZlcihHTF9GUk9OVCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcihHTF9GUk9OVCkiKTsKICAgIH0KICAgIExFQVZFX0dMKCk7CgogICAgcmV0dXJuOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9VbmxvY2tSZWN0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICAqbXlEZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICpzd2FwY2hhaW4gPSBOVUxMOwogICAgQk9PTCBmdWxsc3VyZmFjZTsKCiAgICBpZiAoIShUaGlzLT5GbGFncyAmIFNGTEFHX0xPQ0tFRCkpIHsKICAgICAgICBXQVJOKCJ0cnlpbmcgdG8gVW5sb2NrIGFuIHVubG9ja2VkIHN1cmZAJXBcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmIChUaGlzLT5GbGFncyAmIFNGTEFHX1BCTykgewogICAgICAgIFRSQUNFKCJGcmVlaW5nIFBCTyBtZW1vcnlcbiIpOwogICAgICAgIEFjdGl2YXRlQ29udGV4dChteURldmljZSwgbXlEZXZpY2UtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQsIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9QSVhFTF9VTlBBQ0tfQlVGRkVSX0FSQiwgVGhpcy0+cGJvKSk7CiAgICAgICAgR0xfRVhUQ0FMTChnbFVubWFwQnVmZmVyQVJCKEdMX1BJWEVMX1VOUEFDS19CVUZGRVJfQVJCKSk7CiAgICAgICAgR0xfRVhUQ0FMTChnbEJpbmRCdWZmZXJBUkIoR0xfUElYRUxfVU5QQUNLX0JVRkZFUl9BUkIsIDApKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xVbm1hcEJ1ZmZlckFSQiIpOwogICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gTlVMTDsKICAgIH0KCiAgICBUUkFDRSgiKCVwKSA6IGRpcnR5ZmllZCglZClcbiIsIFRoaXMsIFRoaXMtPkZsYWdzICYgKFNGTEFHX0lORFJBV0FCTEUgfCBTRkxBR19JTlRFWFRVUkUpID8gMCA6IDEpOwoKICAgIGlmIChUaGlzLT5GbGFncyAmIChTRkxBR19JTkRSQVdBQkxFIHwgU0ZMQUdfSU5URVhUVVJFKSkgewogICAgICAgIFRSQUNFKCIoJXApIDogTm90IERpcnRpZmllZCBzbyBub3RoaW5nIHRvIGRvLCByZXR1cm4gbm93XG4iLCBUaGlzKTsKICAgICAgICBnb3RvIHVubG9ja19lbmQ7CiAgICB9CgogICAgSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihpZmFjZSwgJklJRF9JV2luZUQzRFN3YXBDaGFpbiwgKHZvaWQgKiopJnN3YXBjaGFpbik7CiAgICBpZihzd2FwY2hhaW4gfHwgKG15RGV2aWNlLT5yZW5kZXJfdGFyZ2V0cyAmJiBpZmFjZSA9PSBteURldmljZS0+cmVuZGVyX3RhcmdldHNbMF0pKSB7CiAgICAgICAgaWYod2luZWQzZF9zZXR0aW5ncy5yZW5kZXJ0YXJnZXRsb2NrX21vZGUgPT0gUlRMX0RJU0FCTEUpIHsKICAgICAgICAgICAgc3RhdGljIEJPT0wgd2FybmVkID0gRkFMU0U7CiAgICAgICAgICAgIGlmKCF3YXJuZWQpIHsKICAgICAgICAgICAgICAgIEVSUigiVGhlIGFwcGxpY2F0aW9uIHRyaWVzIHRvIHdyaXRlIHRvIHRoZSByZW5kZXIgdGFyZ2V0LCBidXQgcmVuZGVyIHRhcmdldCBsb2NraW5nIGlzIGRpc2FibGVkXG4iKTsKICAgICAgICAgICAgICAgIHdhcm5lZCA9IFRSVUU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoc3dhcGNoYWluKSBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKChJV2luZUQzRFN3YXBDaGFpbiAqKSBzd2FwY2hhaW4pOwogICAgICAgICAgICBnb3RvIHVubG9ja19lbmQ7CiAgICAgICAgfQoKICAgICAgICBpZihUaGlzLT5kaXJ0eVJlY3QubGVmdCAgID09IDAgJiYKICAgICAgICAgICBUaGlzLT5kaXJ0eVJlY3QudG9wICAgID09IDAgJiYKICAgICAgICAgICBUaGlzLT5kaXJ0eVJlY3QucmlnaHQgID09IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoICYmCiAgICAgICAgICAgVGhpcy0+ZGlydHlSZWN0LmJvdHRvbSA9PSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpIHsKICAgICAgICAgICAgZnVsbHN1cmZhY2UgPSBUUlVFOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8qIFRPRE86IFByb3BlciBwYXJ0aWFsIHJlY3RhbmdsZSB0cmFja2luZyAqLwogICAgICAgICAgICBmdWxsc3VyZmFjZSA9IEZBTFNFOwogICAgICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19JTlNZU01FTTsKICAgICAgICB9CgogICAgICAgIHN3aXRjaCh3aW5lZDNkX3NldHRpbmdzLnJlbmRlcnRhcmdldGxvY2tfbW9kZSkgewogICAgICAgICAgICBjYXNlIFJUTF9SRUFEVEVYOgogICAgICAgICAgICBjYXNlIFJUTF9URVhURVg6CiAgICAgICAgICAgICAgICBBY3RpdmF0ZUNvbnRleHQobXlEZXZpY2UsIGlmYWNlLCBDVFhVU0FHRV9CTElUKTsKICAgICAgICAgICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgICAgICAgICBpZiAoVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgZ2xHZW5UZXh0dXJlcygxLCAmVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsR2VuVGV4dHVyZXMiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGdsQmluZFRleHR1cmUoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZFRleHR1cmUoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpIik7CiAgICAgICAgICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvYWRMb2NhdGlvbihpZmFjZSwgU0ZMQUdfSU5URVhUVVJFLCBOVUxMIC8qIHBhcnRpYWwgdGV4dHVyZSBsb2FkaW5nIG5vdCBzdXBwb3J0ZWQgeWV0ICovKTsKICAgICAgICAgICAgICAgIC8qIGRyb3AgdGhyb3VnaCAqLwoKICAgICAgICAgICAgY2FzZSBSVExfQVVUTzoKICAgICAgICAgICAgY2FzZSBSVExfUkVBRERSQVc6CiAgICAgICAgICAgIGNhc2UgUlRMX1RFWERSQVc6CiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfTG9hZExvY2F0aW9uKGlmYWNlLCBTRkxBR19JTkRSQVdBQkxFLCBmdWxsc3VyZmFjZSA/IE5VTEwgOiAmVGhpcy0+ZGlydHlSZWN0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgaWYoIWZ1bGxzdXJmYWNlKSB7CiAgICAgICAgICAgIC8qIFBhcnRpYWwgcmVjdGFuZ2xlIHRyYWNraW5nIGlzIG5vdCBjb21tb25seSBpbXBsZW1lbnRlZCwgaXQgaXMgb25seSBkb25lIGZvciByZW5kZXIgdGFyZ2V0cy4gT3ZlcndyaXRlCiAgICAgICAgICAgICAqIHRoZSBmbGFncyB0byBicmluZyB0aGVtIGJhY2sgaW50byBhIHNhbmUgc3RhdGUuIElOU1lTTUVNIHdhcyBzZXQgYmVmb3JlIHRvIHRlbGwgTG9hZExvY2F0aW9uIHdoZXJlCiAgICAgICAgICAgICAqIHRvIHJlYWQgdGhlIHJlY3RhbmdsZSBmcm9tLiBJbmRyYXdhYmxlIGlzIHNldCBiZWNhdXNlIGFsbCBtb2RpZmljYXRpb25zIGZyb20gdGhlIHBhcnRpYWwgc3lzbWVtIGNvcHkKICAgICAgICAgICAgICogYXJlIHdyaXR0ZW4gYmFjayB0byB0aGUgZHJhd2FibGUsIHRodXMgdGhlIHN1cmZhY2UgaXMgbWVyZ2VkIGFnYWluIGluIHRoZSBkcmF3YWJsZS4gVGhlIHN5c21lbSBjb3B5IGlzCiAgICAgICAgICAgICAqIG5vdCBmdWxseSB1cCB0byBkYXRlIGJlY2F1c2Ugb25seSBhIHN1YnJlY3RhbmdsZSB3YXMgcmVhZCBpbiBMb2NrUmVjdC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19JTlNZU01FTTsKICAgICAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfSU5EUkFXQUJMRTsKICAgICAgICB9CgogICAgICAgIFRoaXMtPmRpcnR5UmVjdC5sZWZ0ICAgPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QudG9wICAgID0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgICAgIFRoaXMtPmRpcnR5UmVjdC5yaWdodCAgPSAwOwogICAgICAgIFRoaXMtPmRpcnR5UmVjdC5ib3R0b20gPSAwOwogICAgfSBlbHNlIGlmKGlmYWNlID09IG15RGV2aWNlLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KSB7CiAgICAgICAgRklYTUUoIkRlcHRoIFN0ZW5jaWwgYnVmZmVyIGxvY2tpbmcgaXMgbm90IGltcGxlbWVudGVkXG4iKTsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogVGhlIHJlc3Qgc2hvdWxkIGJlIGEgbm9ybWFsIHRleHR1cmUgKi8KICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqaW1wbDsKICAgICAgICAvKiBDaGVjayBpZiB0aGUgdGV4dHVyZSBpcyBib3VuZCwgaWYgeWVzIGRpcnRpZnkgdGhlIHNhbXBsZXIgdG8gZm9yY2UgYSByZS11cGxvYWQgb2YgdGhlIHRleHR1cmUKICAgICAgICAgKiBDYW4ndCBsb2FkIHRoZSB0ZXh0dXJlIGhlcmUgYmVjYXVzZSBQcmVMb2FkIG1heSBkZXN0cm95IGFuZCByZWNyZWF0ZSB0aGUgZ2wgdGV4dHVyZSwgc28gc2FtcGxlcgogICAgICAgICAqIHN0YXRlcyBuZWVkIHJlc2V0dGluZwogICAgICAgICAqLwogICAgICAgIGlmKElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoaWZhY2UsICZJSURfSVdpbmVEM0RCYXNlVGV4dHVyZSwgKHZvaWQgKiopJmltcGwpID09IFdJTkVEM0RfT0spIHsKICAgICAgICAgICAgaWYoaW1wbC0+YmFzZVRleHR1cmUuYmluZENvdW50KSB7CiAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkobXlEZXZpY2UsIFNUQVRFX1NBTVBMRVIoaW1wbC0+YmFzZVRleHR1cmUuc2FtcGxlcikpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUmVsZWFzZSgoSVdpbmVEM0RCYXNlVGV4dHVyZSAqKSBpbXBsKTsKICAgICAgICB9CiAgICB9CgogICAgdW5sb2NrX2VuZDoKICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19MT0NLRUQ7CiAgICBtZW1zZXQoJlRoaXMtPmxvY2tlZFJlY3QsIDAsIHNpemVvZihSRUNUKSk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREQyhJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBIREMgKnBIREMpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgV0lORUQzRExPQ0tFRF9SRUNUIGxvY2s7CiAgICBIUkVTVUxUIGhyOwogICAgUkdCUVVBRCBjb2xbMjU2XTsKCiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIixUaGlzLHBIREMpOwoKICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfVVNFUlBUUikgewogICAgICAgIEVSUigiTm90IHN1cHBvcnRlZCBvbiBzdXJmYWNlcyB3aXRoIGFuIGFwcGxpY2F0aW9uLXByb3ZpZGVkIHN1cmZhY2VzXG4iKTsKICAgICAgICByZXR1cm4gV0lORURERVJSX05PREM7CiAgICB9CgogICAgLyogR2l2ZSBtb3JlIGRldGFpbGVkIGluZm8gZm9yIGRkcmF3ICovCiAgICBpZiAoVGhpcy0+RmxhZ3MgJiBTRkxBR19EQ0lOVVNFKQogICAgICAgIHJldHVybiBXSU5FRERFUlJfRENBTFJFQURZQ1JFQVRFRDsKCiAgICAvKiBDYW4ndCBHZXREQyBpZiB0aGUgc3VyZmFjZSBpcyBsb2NrZWQgKi8KICAgIGlmIChUaGlzLT5GbGFncyAmIFNGTEFHX0xPQ0tFRCkKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICBtZW1zZXQoJmxvY2ssIDAsIHNpemVvZihsb2NrKSk7IC8qIFRvIGJlIHN1cmUgKi8KCiAgICAvKiBDcmVhdGUgYSBESUIgc2VjdGlvbiBpZiB0aGVyZSBpc24ndCBhIGhkYyB5ZXQgKi8KICAgIGlmKCFUaGlzLT5oREMpIHsKICAgICAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9DcmVhdGVESUJTZWN0aW9uKGlmYWNlKTsKICAgICAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX0NMSUVOVCkgewogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUHJlTG9hZChpZmFjZSk7CiAgICAgICAgfQoKICAgICAgICAvKiBVc2UgdGhlIGRpYiBzZWN0aW9uIGZyb20gbm93IG9uIGlmIHdlIGFyZSBub3QgdXNpbmcgYSBQQk8gKi8KICAgICAgICBpZighKFRoaXMtPkZsYWdzICYgU0ZMQUdfUEJPKSkKICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gVGhpcy0+ZGliLmJpdG1hcF9kYXRhOwogICAgfQoKICAgIC8qIExvY2sgdGhlIHN1cmZhY2UgKi8KICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmxvY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCk7CgogICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19QQk8pIHsKICAgICAgICAvKiBTeW5jIHRoZSBESUIgd2l0aCB0aGUgUEJPLiBUaGlzIGNhbid0IGJlIGRvbmUgZWFybGllciBiZWNhdXNlIExvY2tSZWN0IGFjdGl2YXRlcyB0aGUgYWxsb2NhdGVkTWVtb3J5ICovCiAgICAgICAgbWVtY3B5KFRoaXMtPmRpYi5iaXRtYXBfZGF0YSwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5LCBUaGlzLT5kaWIuYml0bWFwX3NpemUpOwogICAgfQoKICAgIGlmKEZBSUxFRChocikpIHsKICAgICAgICBFUlIoIklXaW5lRDNEU3VyZmFjZV9Mb2NrUmVjdCBmYWlsZWQgd2l0aCBociA9ICUwOHhcbiIsIGhyKTsKICAgICAgICAvKiBrZWVwIHRoZSBkaWIgc2VjdGlvbiAqLwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICBpZihUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9QOCB8fAogICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0E4UDgpIHsKICAgICAgICB1bnNpZ25lZCBpbnQgbjsKICAgICAgICBpZihUaGlzLT5wYWxldHRlKSB7CiAgICAgICAgICAgIFBBTEVUVEVFTlRSWSBlbnRbMjU2XTsKCiAgICAgICAgICAgIEdldFBhbGV0dGVFbnRyaWVzKFRoaXMtPnBhbGV0dGUtPmhwYWwsIDAsIDI1NiwgZW50KTsKICAgICAgICAgICAgZm9yIChuPTA7IG48MjU2OyBuKyspIHsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JSZWQgICA9IGVudFtuXS5wZVJlZDsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JHcmVlbiA9IGVudFtuXS5wZUdyZWVuOwogICAgICAgICAgICAgICAgY29sW25dLnJnYkJsdWUgID0gZW50W25dLnBlQmx1ZTsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JSZXNlcnZlZCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CgogICAgICAgICAgICBmb3IgKG49MDsgbjwyNTY7IG4rKykgewogICAgICAgICAgICAgICAgY29sW25dLnJnYlJlZCAgID0gZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtuXS5wZVJlZDsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JHcmVlbiA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1bbl0ucGVHcmVlbjsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JCbHVlICA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1bbl0ucGVCbHVlOwogICAgICAgICAgICAgICAgY29sW25dLnJnYlJlc2VydmVkID0gMDsKICAgICAgICAgICAgfQoKICAgICAgICB9CiAgICAgICAgU2V0RElCQ29sb3JUYWJsZShUaGlzLT5oREMsIDAsIDI1NiwgY29sKTsKICAgIH0KCiAgICAqcEhEQyA9IFRoaXMtPmhEQzsKICAgIFRSQUNFKCJyZXR1cm5pbmcgJXBcbiIsKnBIREMpOwogICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfRENJTlVTRTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZWxlYXNlREMoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSERDIGhEQykgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCktPiglcClcbiIsVGhpcyxoREMpOwoKICAgIGlmICghKFRoaXMtPkZsYWdzICYgU0ZMQUdfRENJTlVTRSkpCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgaWYgKFRoaXMtPmhEQyAhPWhEQykgewogICAgICAgIFdBUk4oIkFwcGxpY2F0aW9uIHRyaWVzIHRvIHJlbGVhc2UgYW4gaW52YWxpZCBEQyglcCksIHN1cmZhY2UgZGMgaXMgJXBcbiIsIGhEQywgVGhpcy0+aERDKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBpZigoVGhpcy0+RmxhZ3MgJiBTRkxBR19QQk8pICYmIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgewogICAgICAgIC8qIENvcHkgdGhlIGNvbnRlbnRzIG9mIHRoZSBESUIgb3ZlciB0byB0aGUgUEJPICovCiAgICAgICAgbWVtY3B5KFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwgVGhpcy0+ZGliLmJpdG1hcF9kYXRhLCBUaGlzLT5kaWIuYml0bWFwX3NpemUpOwogICAgfQoKICAgIC8qIHdlIGxvY2tlZCBmaXJzdCwgc28gdW5sb2NrIG5vdyAqLwogICAgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QoaWZhY2UpOwoKICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19EQ0lOVVNFOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgSVdpbmVEM0RTdXJmYWNlIEludGVybmFsIChObyBtYXBwaW5nIHRvIGRpcmVjdHggYXBpKSBwYXJ0cyBmb2xsb3cKICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovCgpIUkVTVUxUIGQzZGZtdF9nZXRfY29udihJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBCT09MIG5lZWRfYWxwaGFfY2ssIEJPT0wgdXNlX3RleHR1cmluZywgR0xlbnVtICpmb3JtYXQsIEdMZW51bSAqaW50ZXJuYWwsIEdMZW51bSAqdHlwZSwgQ09OVkVSVF9UWVBFUyAqY29udmVydCwgaW50ICp0YXJnZXRfYnBwLCBCT09MIHNyZ2JfbW9kZSkgewogICAgQk9PTCBjb2xvcmtleV9hY3RpdmUgPSBuZWVkX2FscGhhX2NrICYmIChUaGlzLT5DS2V5RmxhZ3MgJiBXSU5FRERTRF9DS1NSQ0JMVCk7CiAgICBjb25zdCBHbFBpeGVsRm9ybWF0RGVzYyAqZ2xEZXNjOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgQk9PTCBwOF9yZW5kZXJfdGFyZ2V0ID0gRkFMU0U7CiAgICBnZXRGb3JtYXREZXNjRW50cnkoVGhpcy0+cmVzb3VyY2UuZm9ybWF0LCAmR0xJTkZPX0xPQ0FUSU9OLCAmZ2xEZXNjKTsKCiAgICAvKiBEZWZhdWx0IHZhbHVlczogRnJvbSB0aGUgc3VyZmFjZSAqLwogICAgKmZvcm1hdCA9IGdsRGVzYy0+Z2xGb3JtYXQ7CiAgICAqdHlwZSA9IGdsRGVzYy0+Z2xUeXBlOwogICAgKmNvbnZlcnQgPSBOT19DT05WRVJTSU9OOwogICAgKnRhcmdldF9icHAgPSBUaGlzLT5ieXRlc1BlclBpeGVsOwoKICAgIGlmKHNyZ2JfbW9kZSkgewogICAgICAgICppbnRlcm5hbCA9IGdsRGVzYy0+Z2xHYW1tYUludGVybmFsOwogICAgfSBlbHNlIGlmKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgewogICAgICAgICppbnRlcm5hbCA9IGdsRGVzYy0+cnRJbnRlcm5hbDsKICAgIH0gZWxzZSB7CiAgICAgICAgKmludGVybmFsID0gZ2xEZXNjLT5nbEludGVybmFsOwogICAgfQoKICAgIC8qIE9rLCBub3cgbG9vayBpZiB3ZSBoYXZlIHRvIGRvIGFueSBjb252ZXJzaW9uICovCiAgICBzd2l0Y2goVGhpcy0+cmVzb3VyY2UuZm9ybWF0KSB7CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1A4OgogICAgICAgICAgICAvKiAqKioqKioqKioqKioqKioqCiAgICAgICAgICAgICAgICBQYWxldHRlZCBUZXh0dXJlCiAgICAgICAgICAgICAgICAqKioqKioqKioqKioqKioqICovCgogICAgICAgICAgICBpZiAoZGV2aWNlLT5yZW5kZXJfdGFyZ2V0cyAmJiBkZXZpY2UtPnJlbmRlcl90YXJnZXRzWzBdKSB7CiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VJbXBsKiByZW5kZXJfdGFyZ2V0ID0gKElXaW5lRDNEU3VyZmFjZUltcGwqKWRldmljZS0+cmVuZGVyX3RhcmdldHNbMF07CiAgICAgICAgICAgICAgICBpZigocmVuZGVyX3RhcmdldC0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSAmJiAocmVuZGVyX3RhcmdldC0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUDgpKQogICAgICAgICAgICAgICAgICAgIHA4X3JlbmRlcl90YXJnZXQgPSBUUlVFOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBVc2UgY29udmVyc2lvbiB3aGVuIHRoZSBwYWxldHRlZCB0ZXh0dXJlIGV4dGVuc2lvbiBpcyBub3QgYXZhaWxhYmxlLCBvciB3aGVuIGl0IGlzIGF2YWlsYWJsZSBtYWtlIHN1cmUgaXQgaXMgdXNlZAogICAgICAgICAgICAgKiBmb3IgdGV4dHVyaW5nIGFzIGl0IHdvbid0IHdvcmsgZm9yIGNhbGxzIGxpa2UgZ2xEcmF3LS9nbFJlYWRQaXhlbHMgYW5kIGZ1cnRoZXIgYWxzbyB1c2UgY29udmVyc2lvbiBpbiBjYXNlIG9mIGNvbG9yIGtleWluZy4KICAgICAgICAgICAgICogUGFsZXR0ZWQgdGV4dHVyZXMgY2FuIGJlIGVtdWxhdGVkIHVzaW5nIHNoYWRlcnMgYnV0IG9ubHkgZG8gdGhhdCBmb3IgMkQgcHVycG9zZXMgZS5nLiBzaXR1YXRpb25zIGluIHdoaWNoIHRoZSBtYWluIHJlbmRlciB0YXJnZXQgdXNlcyBwOC4gU29tZSBnYW1lcyBsaWtlIEdUQSBWaWNlIENpdHkgdXNlIFA4IGZvciB0ZXh0dXJpbmcgd2hpY2ggY29uZmxpY3RzIHdpdGggdGhpcy4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmKCAhKEdMX1NVUFBPUlQoRVhUX1BBTEVUVEVEX1RFWFRVUkUpIHx8IChHTF9TVVBQT1JUKEFSQl9GUkFHTUVOVF9QUk9HUkFNKSAmJiBwOF9yZW5kZXJfdGFyZ2V0KSkgIHx8IGNvbG9ya2V5X2FjdGl2ZSB8fCAoIXVzZV90ZXh0dXJpbmcgJiYgR0xfU1VQUE9SVChFWFRfUEFMRVRURURfVEVYVFVSRSkpICkgewogICAgICAgICAgICAgICAgKmZvcm1hdCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqaW50ZXJuYWwgPSBHTF9SR0JBOwogICAgICAgICAgICAgICAgKnR5cGUgPSBHTF9VTlNJR05FRF9CWVRFOwogICAgICAgICAgICAgICAgKnRhcmdldF9icHAgPSA0OwogICAgICAgICAgICAgICAgaWYoY29sb3JrZXlfYWN0aXZlKSB7CiAgICAgICAgICAgICAgICAgICAgKmNvbnZlcnQgPSBDT05WRVJUX1BBTEVUVEVEX0NLOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfUEFMRVRURUQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZihHTF9TVVBQT1JUKEFSQl9GUkFHTUVOVF9QUk9HUkFNKSkgewogICAgICAgICAgICAgICAgKmZvcm1hdCA9IEdMX1JFRDsKICAgICAgICAgICAgICAgICppbnRlcm5hbCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqdHlwZSA9IEdMX1VOU0lHTkVEX0JZVEU7CiAgICAgICAgICAgICAgICAqdGFyZ2V0X2JwcCA9IDE7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjNHM0IyOgogICAgICAgICAgICAvKiAqKioqKioqKioqKioqKioqKioqKioqCiAgICAgICAgICAgICAgICBHTF9VTlNJR05FRF9CWVRFXzNfM18yCiAgICAgICAgICAgICAgICAqKioqKioqKioqKioqKioqKioqKioqICovCiAgICAgICAgICAgIGlmIChjb2xvcmtleV9hY3RpdmUpIHsKICAgICAgICAgICAgICAgIC8qIFRoaXMgdGV4dHVyZSBmb3JtYXQgd2lsbCBuZXZlciBiZSB1c2VkLi4gU28gZG8gbm90IGNhcmUgYWJvdXQgY29sb3Iga2V5aW5nCiAgICAgICAgICAgICAgICAgICAgdXAgdW50aWwgdGhlIHBvaW50IGluIHRpbWUgaXQgd2lsbCBiZSBuZWVkZWQgOi0pICovCiAgICAgICAgICAgICAgICBGSVhNRSgiIENvbG9yS2V5aW5nIG5vdCBzdXBwb3J0ZWQgaW4gdGhlIFJHQiAzMzIgZm9ybWF0ICFcbiIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjVHNkI1OgogICAgICAgICAgICBpZiAoY29sb3JrZXlfYWN0aXZlKSB7CiAgICAgICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfQ0tfNTY1OwogICAgICAgICAgICAgICAgKmZvcm1hdCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqaW50ZXJuYWwgPSBHTF9SR0JBOwogICAgICAgICAgICAgICAgKnR5cGUgPSBHTF9VTlNJR05FRF9TSE9SVF81XzVfNV8xOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDFSNUc1QjU6CiAgICAgICAgICAgIGlmIChjb2xvcmtleV9hY3RpdmUpIHsKICAgICAgICAgICAgICAgICpjb252ZXJ0ID0gQ09OVkVSVF9DS181NTUxOwogICAgICAgICAgICAgICAgKmZvcm1hdCA9IEdMX0JHUkE7CiAgICAgICAgICAgICAgICAqaW50ZXJuYWwgPSBHTF9SR0JBOwogICAgICAgICAgICAgICAgKnR5cGUgPSBHTF9VTlNJR05FRF9TSE9SVF8xXzVfNV81X1JFVjsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1I4RzhCODoKICAgICAgICAgICAgaWYgKGNvbG9ya2V5X2FjdGl2ZSkgewogICAgICAgICAgICAgICAgKmNvbnZlcnQgPSBDT05WRVJUX0NLX1JHQjI0OwogICAgICAgICAgICAgICAgKmZvcm1hdCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqaW50ZXJuYWwgPSBHTF9SR0JBOwogICAgICAgICAgICAgICAgKnR5cGUgPSBHTF9VTlNJR05FRF9JTlRfOF84XzhfODsKICAgICAgICAgICAgICAgICp0YXJnZXRfYnBwID0gNDsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1g4UjhHOEI4OgogICAgICAgICAgICBpZiAoY29sb3JrZXlfYWN0aXZlKSB7CiAgICAgICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfUkdCMzJfODg4OwogICAgICAgICAgICAgICAgKmZvcm1hdCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqaW50ZXJuYWwgPSBHTF9SR0JBOwogICAgICAgICAgICAgICAgKnR5cGUgPSBHTF9VTlNJR05FRF9JTlRfOF84XzhfODsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1Y4VTg6CiAgICAgICAgICAgIGlmKEdMX1NVUFBPUlQoTlZfVEVYVFVSRV9TSEFERVIzKSkgYnJlYWs7CiAgICAgICAgICAgIGVsc2UgaWYoR0xfU1VQUE9SVChBVElfRU5WTUFQX0JVTVBNQVApKSB7CiAgICAgICAgICAgICAgICAqZm9ybWF0ID0gR0xfRFVEVl9BVEk7CiAgICAgICAgICAgICAgICAqaW50ZXJuYWwgPSBHTF9EVThEVjhfQVRJOwogICAgICAgICAgICAgICAgKnR5cGUgPSBHTF9CWVRFOwogICAgICAgICAgICAgICAgLyogTm8gY29udmVyc2lvbiAtIEp1c3QgY2hhbmdlIHRoZSBnbCB0eXBlICovCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfVjhVODsKICAgICAgICAgICAgKmZvcm1hdCA9IEdMX0JHUjsKICAgICAgICAgICAgKmludGVybmFsID0gR0xfUkdCODsKICAgICAgICAgICAgKnR5cGUgPSBHTF9VTlNJR05FRF9CWVRFOwogICAgICAgICAgICAqdGFyZ2V0X2JwcCA9IDM7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfTDZWNVU1OgogICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfTDZWNVU1OwogICAgICAgICAgICBpZihHTF9TVVBQT1JUKE5WX1RFWFRVUkVfU0hBREVSKSkgewogICAgICAgICAgICAgICAgKnRhcmdldF9icHAgPSAzOwogICAgICAgICAgICAgICAgLyogVXNlIGZvcm1hdCBhbmQgdHlwZXMgZnJvbSB0YWJsZSAqLwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLyogTG9hZCBpdCBpbnRvIHVuc2lnbmVkIFI1RzZCNSwgc3dhcCBMIGFuZCBWIGNoYW5uZWxzLCBhbmQgcmV2ZXJ0IHRoYXQgaW4gdGhlIHNoYWRlciAqLwogICAgICAgICAgICAgICAgKnRhcmdldF9icHAgPSAyOwogICAgICAgICAgICAgICAgKmZvcm1hdCA9IEdMX1JHQjsKICAgICAgICAgICAgICAgICppbnRlcm5hbCA9IEdMX1JHQjU7CiAgICAgICAgICAgICAgICAqdHlwZSA9IEdMX1VOU0lHTkVEX1NIT1JUXzVfNl81OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDhMOFY4VTg6CiAgICAgICAgICAgICpjb252ZXJ0ID0gQ09OVkVSVF9YOEw4VjhVODsKICAgICAgICAgICAgKnRhcmdldF9icHAgPSA0OwogICAgICAgICAgICBpZihHTF9TVVBQT1JUKE5WX1RFWFRVUkVfU0hBREVSKSkgewogICAgICAgICAgICAgICAgLyogVXNlIGZvcm1hdHMgZnJvbSBnbCB0YWJsZS4gSXQgaXMgYSBiaXQgdW5mb3J0dW5hdGUsIGJ1dCB0aGUgY29udmVyc2lvbgogICAgICAgICAgICAgICAgICogaXMgbmVlZGVkIHRvIHNldCB0aGUgWCBmb3JtYXQgdG8gMjU1IHRvIGdldCAxLjAgZm9yIGFscGhhIHdoZW4gc2FtcGxpbmcKICAgICAgICAgICAgICAgICAqIHRoZSB0ZXh0dXJlLiBPcGVuR0wgY2FuJ3QgdXNlIEdMX0RTRFQ4X01BRzhfTlYgYXMgaW50ZXJuYWwgZm9ybWF0IHdpdGgKICAgICAgICAgICAgICAgICAqIHRoZSBuZWVkZWQgdHlwZSBhbmQgZm9ybWF0IHBhcmFtZXRlciwgc28gdGhlIGludGVybmFsIGZvcm1hdCBjb250YWlucyBhCiAgICAgICAgICAgICAgICAgKiA0dGggY29tcG9uZW50LCB3aGljaCBpcyByZXR1cm5lZCBhcyBhbHBoYQogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvKiBOb3Qgc3VwcG9ydGVkIGJ5IEdMX0FUSV9lbnZtYXBfYnVtcG1hcCAqLwogICAgICAgICAgICAgICAgKmZvcm1hdCA9IEdMX0JHUkE7CiAgICAgICAgICAgICAgICAqaW50ZXJuYWwgPSBHTF9SR0I4OwogICAgICAgICAgICAgICAgKnR5cGUgPSBHTF9VTlNJR05FRF9JTlRfOF84XzhfOF9SRVY7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9ROFc4VjhVODoKICAgICAgICAgICAgaWYoR0xfU1VQUE9SVChOVl9URVhUVVJFX1NIQURFUjMpKSBicmVhazsKICAgICAgICAgICAgKmNvbnZlcnQgPSBDT05WRVJUX1E4VzhWOFU4OwogICAgICAgICAgICAqZm9ybWF0ID0gR0xfQkdSQTsKICAgICAgICAgICAgKmludGVybmFsID0gR0xfUkdCQTg7CiAgICAgICAgICAgICp0eXBlID0gR0xfVU5TSUdORURfQllURTsKICAgICAgICAgICAgKnRhcmdldF9icHAgPSA0OwogICAgICAgICAgICAvKiBOb3Qgc3VwcG9ydGVkIGJ5IEdMX0FUSV9lbnZtYXBfYnVtcG1hcCAqLwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1YxNlUxNjoKICAgICAgICAgICAgaWYoR0xfU1VQUE9SVChOVl9URVhUVVJFX1NIQURFUjMpKSBicmVhazsKICAgICAgICAgICAgKmNvbnZlcnQgPSBDT05WRVJUX1YxNlUxNjsKICAgICAgICAgICAgKmZvcm1hdCA9IEdMX0JHUjsKICAgICAgICAgICAgKmludGVybmFsID0gR0xfUkdCMTZfRVhUOwogICAgICAgICAgICAqdHlwZSA9IEdMX1VOU0lHTkVEX1NIT1JUOwogICAgICAgICAgICAqdGFyZ2V0X2JwcCA9IDY7CiAgICAgICAgICAgIC8qIFdoYXQgc2hvdWxkIEkgZG8gaGVyZSBhYm91dCBHTF9BVElfZW52bWFwX2J1bXBtYXA/CiAgICAgICAgICAgICAqIENvbnZlcnQgaXQgb3IgYWxsb3cgZGF0YSBsb3NzIGJ5IGxvYWRpbmcgaXQgaW50byBhIDggYml0IC8gY2hhbm5lbCB0ZXh0dXJlPwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9BNEw0OgogICAgICAgICAgICAvKiBBNEw0IGV4aXN0cyBhcyBhbiBpbnRlcm5hbCBnbCBmb3JtYXQsIGJ1dCBmb3Igc29tZSByZWFzb24gdGhlcmUgaXMgbm90CiAgICAgICAgICAgICAqIGZvcm1hdCt0eXBlIGNvbWJpbmF0aW9uIHRvIGxvYWQgaXQuIFRodXMgY29udmVydCBpdCB0byBBOEw4LCB0aGVuIGxvYWQgaXQKICAgICAgICAgICAgICogd2l0aCBBNEw0IGludGVybmFsLCBidXQgQThMOCBmb3JtYXQrdHlwZQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgKmNvbnZlcnQgPSBDT05WRVJUX0E0TDQ7CiAgICAgICAgICAgICpmb3JtYXQgPSBHTF9MVU1JTkFOQ0VfQUxQSEE7CiAgICAgICAgICAgICppbnRlcm5hbCA9IEdMX0xVTUlOQU5DRTRfQUxQSEE0OwogICAgICAgICAgICAqdHlwZSA9IEdMX1VOU0lHTkVEX0JZVEU7CiAgICAgICAgICAgICp0YXJnZXRfYnBwID0gMjsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9SMzJGOgogICAgICAgICAgICAvKiBDYW4gYmUgbG9hZGVkIGluIHRoZW9yeSB3aXRoIGZtdD1HTF9SRUQsIHR5cGU9R0xfRkxPQVQsIGJ1dCB0aGlzIGZhaWxzLiBUaGUgcmVhc29uCiAgICAgICAgICAgICAqIGlzIHRoYXQgRDNEIGV4cGVjdHMgdGhlIHVuZGVmaW5lZCBncmVlbiwgYmx1ZSBhbmQgYWxwaGEgY2hhbm5lbHMgdG8gcmV0dXJuIDEuMAogICAgICAgICAgICAgKiB3aGVuIHNhbXBsaW5nLCBidXQgT3BlbkdMIHNldHMgZ3JlZW4gYW5kIGJsdWUgdG8gMC4wIGluc3RlYWQuIFRodXMgd2UgaGF2ZSB0byBpbmplY3QKICAgICAgICAgICAgICogMS4wIGluc3RlYWQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIFRoZSBhbHBoYSBjaGFubmVsIGRlZmF1bHRzIHRvIDEuMCBpbiBvcGVuZ2wsIHNvIG5vdGhpbmcgaGFzIHRvIGJlIGRvbmUgYWJvdXQgaXQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfUjMyRjsKICAgICAgICAgICAgKmZvcm1hdCA9IEdMX1JHQjsKICAgICAgICAgICAgKmludGVybmFsID0gR0xfUkdCMzJGX0FSQjsKICAgICAgICAgICAgKnR5cGUgPSBHTF9GTE9BVDsKICAgICAgICAgICAgKnRhcmdldF9icHAgPSAxMjsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9SMTZGOgogICAgICAgICAgICAvKiBTaW1pbGFyIHRvIFIzMkYgKi8KICAgICAgICAgICAgKmNvbnZlcnQgPSBDT05WRVJUX1IxNkY7CiAgICAgICAgICAgICpmb3JtYXQgPSBHTF9SR0I7CiAgICAgICAgICAgICppbnRlcm5hbCA9IEdMX1JHQjE2Rl9BUkI7CiAgICAgICAgICAgICp0eXBlID0gR0xfSEFMRl9GTE9BVF9BUkI7CiAgICAgICAgICAgICp0YXJnZXRfYnBwID0gNjsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGJyZWFrOwogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIGQzZGZtdF9jb252ZXJ0X3N1cmZhY2UoQllURSAqc3JjLCBCWVRFICpkc3QsIFVJTlQgcGl0Y2gsIFVJTlQgd2lkdGgsIFVJTlQgaGVpZ2h0LCBVSU5UIG91dHBpdGNoLCBDT05WRVJUX1RZUEVTIGNvbnZlcnQsIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMpIHsKICAgIEJZVEUgKnNvdXJjZSwgKmRlc3Q7CiAgICBUUkFDRSgiKCVwKS0+KCVwKSwoJWQsJWQsJWQsJWQsJXApXG4iLCBzcmMsIGRzdCwgcGl0Y2gsIGhlaWdodCwgb3V0cGl0Y2gsIGNvbnZlcnQsVGhpcyk7CgogICAgc3dpdGNoIChjb252ZXJ0KSB7CiAgICAgICAgY2FzZSBOT19DT05WRVJTSU9OOgogICAgICAgIHsKICAgICAgICAgICAgbWVtY3B5KGRzdCwgc3JjLCBwaXRjaCAqIGhlaWdodCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIENPTlZFUlRfUEFMRVRURUQ6CiAgICAgICAgY2FzZSBDT05WRVJUX1BBTEVUVEVEX0NLOgogICAgICAgIHsKICAgICAgICAgICAgSVdpbmVEM0RQYWxldHRlSW1wbCogcGFsID0gVGhpcy0+cGFsZXR0ZTsKICAgICAgICAgICAgQllURSB0YWJsZVsyNTZdWzRdOwogICAgICAgICAgICB1bnNpZ25lZCBpbnQgeCwgeTsKCiAgICAgICAgICAgIGlmKCBwYWwgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgLyogVE9ETzogSWYgd2UgYXJlIGEgc3VibGV2ZWwsIHRyeSB0byBnZXQgdGhlIHBhbGV0dGUgZnJvbSBsZXZlbCAwICovCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGQzZGZtdF9wOF9pbml0X3BhbGV0dGUoVGhpcywgdGFibGUsIChjb252ZXJ0ID09IENPTlZFUlRfUEFMRVRURURfQ0spKTsKCiAgICAgICAgICAgIGZvciAoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgc291cmNlID0gc3JjICsgcGl0Y2ggKiB5OwogICAgICAgICAgICAgICAgZGVzdCA9IGRzdCArIG91dHBpdGNoICogeTsKICAgICAgICAgICAgICAgIC8qIFRoaXMgaXMgYW4gMSBicHAgZm9ybWF0LCB1c2luZyB0aGUgd2lkdGggaGVyZSBpcyBmaW5lICovCiAgICAgICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewogICAgICAgICAgICAgICAgICAgIEJZVEUgY29sb3IgPSAqc291cmNlKys7CiAgICAgICAgICAgICAgICAgICAgKmRlc3QrKyA9IHRhYmxlW2NvbG9yXVswXTsKICAgICAgICAgICAgICAgICAgICAqZGVzdCsrID0gdGFibGVbY29sb3JdWzFdOwogICAgICAgICAgICAgICAgICAgICpkZXN0KysgPSB0YWJsZVtjb2xvcl1bMl07CiAgICAgICAgICAgICAgICAgICAgKmRlc3QrKyA9IHRhYmxlW2NvbG9yXVszXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBDT05WRVJUX0NLXzU2NToKICAgICAgICB7CiAgICAgICAgICAgIC8qIENvbnZlcnRpbmcgdGhlIDU2NSBmb3JtYXQgaW4gNTU1MSBwYWNrZWQgdG8gZW11bGF0ZSBjb2xvci1rZXlpbmcuCgogICAgICAgICAgICAgIE5vdGUgOiBpbiBhbGwgdGhlc2UgY29udmVyc2lvbiwgaXQgd291bGQgYmUgYmVzdCB0byBhdmVyYWdlIHRoZSBhdmVyYWdpbmcKICAgICAgICAgICAgICAgICAgICAgIHBpeGVscyB0byBnZXQgdGhlIGNvbG9yIG9mIHRoZSBwaXhlbCB0aGF0IHdpbGwgYmUgY29sb3Ita2V5ZWQgdG8KICAgICAgICAgICAgICAgICAgICAgIHByZXZlbnQgJ2NvbG9yIGJsZWVkaW5nJy4gVGhpcyB3aWxsIGJlIGRvbmUgbGF0ZXIgb24gaWYgZXZlciBpdCBpcwogICAgICAgICAgICAgICAgICAgICAgdG9vIHZpc2libGUuCgogICAgICAgICAgICAgIE5vdGUyOiBOdmlkaWEgZG9jdW1lbnRzIHNheSB0aGF0IHRoZWlyIGRyaXZlciBkb2VzIG5vdCBzdXBwb3J0IGFscGhhICsgY29sb3Iga2V5aW5nCiAgICAgICAgICAgICAgICAgICAgIG9uIHRoZSBzYW1lIHN1cmZhY2UgYW5kIGRpc2FibGVzIGNvbG9yIGtleWluZyBpbiBzdWNoIGEgY2FzZQogICAgICAgICAgICAqLwogICAgICAgICAgICB1bnNpZ25lZCBpbnQgeCwgeTsKICAgICAgICAgICAgV09SRCAqU291cmNlOwogICAgICAgICAgICBXT1JEICpEZXN0OwoKICAgICAgICAgICAgVFJBQ0UoIkNvbG9yIGtleWVkIDU2NVxuIik7CgogICAgICAgICAgICBmb3IgKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKICAgICAgICAgICAgICAgIFNvdXJjZSA9IChXT1JEICopIChzcmMgKyB5ICogcGl0Y2gpOwogICAgICAgICAgICAgICAgRGVzdCA9IChXT1JEICopIChkc3QgKyB5ICogb3V0cGl0Y2gpOwogICAgICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KysgKSB7CiAgICAgICAgICAgICAgICAgICAgV09SRCBjb2xvciA9ICpTb3VyY2UrKzsKICAgICAgICAgICAgICAgICAgICAqRGVzdCA9ICgoY29sb3IgJiAweEZGQzApIHwgKChjb2xvciAmIDB4MUYpIDw8IDEpKTsKICAgICAgICAgICAgICAgICAgICBpZiAoKGNvbG9yIDwgVGhpcy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZSkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgKGNvbG9yID4gVGhpcy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICpEZXN0IHw9IDB4MDAwMTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgRGVzdCsrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIENPTlZFUlRfQ0tfNTU1MToKICAgICAgICB7CiAgICAgICAgICAgIC8qIENvbnZlcnRpbmcgWDFSNUc1QjUgZm9ybWF0IHRvIFI1RzVCNUExIHRvIGVtdWxhdGUgY29sb3Ita2V5aW5nLiAqLwogICAgICAgICAgICB1bnNpZ25lZCBpbnQgeCwgeTsKICAgICAgICAgICAgV09SRCAqU291cmNlOwogICAgICAgICAgICBXT1JEICpEZXN0OwogICAgICAgICAgICBUUkFDRSgiQ29sb3Iga2V5ZWQgNTU1MVxuIik7CiAgICAgICAgICAgIGZvciAoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewogICAgICAgICAgICAgICAgU291cmNlID0gKFdPUkQgKikgKHNyYyArIHkgKiBwaXRjaCk7CiAgICAgICAgICAgICAgICBEZXN0ID0gKFdPUkQgKikgKGRzdCArIHkgKiBvdXRwaXRjaCk7CiAgICAgICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKyApIHsKICAgICAgICAgICAgICAgICAgICBXT1JEIGNvbG9yID0gKlNvdXJjZSsrOwoJCSAgICAqRGVzdCA9IGNvbG9yOwogICAgICAgICAgICAgICAgICAgIGlmICgoY29sb3IgPCBUaGlzLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlKSB8fAogICAgICAgICAgICAgICAgICAgICAgICAoY29sb3IgPiBUaGlzLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgKkRlc3QgfD0gKDEgPDwgMTUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgKkRlc3QgJj0gfigxIDw8IDE1KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgRGVzdCsrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIENPTlZFUlRfVjhVODoKICAgICAgICB7CiAgICAgICAgICAgIHVuc2lnbmVkIGludCB4LCB5OwogICAgICAgICAgICBzaG9ydCAqU291cmNlOwogICAgICAgICAgICB1bnNpZ25lZCBjaGFyICpEZXN0OwogICAgICAgICAgICBmb3IoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewogICAgICAgICAgICAgICAgU291cmNlID0gKHNob3J0ICopIChzcmMgKyB5ICogcGl0Y2gpOwogICAgICAgICAgICAgICAgRGVzdCA9ICh1bnNpZ25lZCBjaGFyICopIChkc3QgKyB5ICogb3V0cGl0Y2gpOwogICAgICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KysgKSB7CiAgICAgICAgICAgICAgICAgICAgbG9uZyBjb2xvciA9ICgqU291cmNlKyspOwogICAgICAgICAgICAgICAgICAgIC8qIEIgKi8gRGVzdFswXSA9IDB4ZmY7CiAgICAgICAgICAgICAgICAgICAgLyogRyAqLyBEZXN0WzFdID0gKGNvbG9yID4+IDgpICsgMTI4OyAvKiBWICovCiAgICAgICAgICAgICAgICAgICAgLyogUiAqLyBEZXN0WzJdID0gKGNvbG9yKSArIDEyODsgICAgICAvKiBVICovCiAgICAgICAgICAgICAgICAgICAgRGVzdCArPSAzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBDT05WRVJUX1YxNlUxNjoKICAgICAgICB7CiAgICAgICAgICAgIHVuc2lnbmVkIGludCB4LCB5OwogICAgICAgICAgICBEV09SRCAqU291cmNlOwogICAgICAgICAgICB1bnNpZ25lZCBzaG9ydCAqRGVzdDsKICAgICAgICAgICAgZm9yKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKICAgICAgICAgICAgICAgIFNvdXJjZSA9IChEV09SRCAqKSAoc3JjICsgeSAqIHBpdGNoKTsKICAgICAgICAgICAgICAgIERlc3QgPSAodW5zaWduZWQgc2hvcnQgKikgKGRzdCArIHkgKiBvdXRwaXRjaCk7CiAgICAgICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKyApIHsKICAgICAgICAgICAgICAgICAgICBEV09SRCBjb2xvciA9ICgqU291cmNlKyspOwogICAgICAgICAgICAgICAgICAgIC8qIEIgKi8gRGVzdFswXSA9IDB4ZmZmZjsKICAgICAgICAgICAgICAgICAgICAvKiBHICovIERlc3RbMV0gPSAoY29sb3IgPj4gMTYpICsgMzI3Njg7IC8qIFYgKi8KICAgICAgICAgICAgICAgICAgICAvKiBSICovIERlc3RbMl0gPSAoY29sb3IgICAgICApICsgMzI3Njg7IC8qIFUgKi8KICAgICAgICAgICAgICAgICAgICBEZXN0ICs9IDM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBjYXNlIENPTlZFUlRfUThXOFY4VTg6CiAgICAgICAgewogICAgICAgICAgICB1bnNpZ25lZCBpbnQgeCwgeTsKICAgICAgICAgICAgRFdPUkQgKlNvdXJjZTsKICAgICAgICAgICAgdW5zaWduZWQgY2hhciAqRGVzdDsKICAgICAgICAgICAgZm9yKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKICAgICAgICAgICAgICAgIFNvdXJjZSA9IChEV09SRCAqKSAoc3JjICsgeSAqIHBpdGNoKTsKICAgICAgICAgICAgICAgIERlc3QgPSAodW5zaWduZWQgY2hhciAqKSAoZHN0ICsgeSAqIG91dHBpdGNoKTsKICAgICAgICAgICAgICAgIGZvciAoeCA9IDA7IHggPCB3aWR0aDsgeCsrICkgewogICAgICAgICAgICAgICAgICAgIGxvbmcgY29sb3IgPSAoKlNvdXJjZSsrKTsKICAgICAgICAgICAgICAgICAgICAvKiBCICovIERlc3RbMF0gPSAoKGNvbG9yID4+IDE2KSAmIDB4ZmYpICsgMTI4OyAvKiBXICovCiAgICAgICAgICAgICAgICAgICAgLyogRyAqLyBEZXN0WzFdID0gKChjb2xvciA+PiA4ICkgJiAweGZmKSArIDEyODsgLyogViAqLwogICAgICAgICAgICAgICAgICAgIC8qIFIgKi8gRGVzdFsyXSA9IChjb2xvciAgICAgICAgICYgMHhmZikgKyAxMjg7IC8qIFUgKi8KICAgICAgICAgICAgICAgICAgICAvKiBBICovIERlc3RbM10gPSAoKGNvbG9yID4+IDI0KSAmIDB4ZmYpICsgMTI4OyAvKiBRICovCiAgICAgICAgICAgICAgICAgICAgRGVzdCArPSA0OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBDT05WRVJUX0w2VjVVNToKICAgICAgICB7CiAgICAgICAgICAgIHVuc2lnbmVkIGludCB4LCB5OwogICAgICAgICAgICBXT1JEICpTb3VyY2U7CiAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgKkRlc3Q7CgogICAgICAgICAgICBpZihHTF9TVVBQT1JUKE5WX1RFWFRVUkVfU0hBREVSKSkgewogICAgICAgICAgICAgICAgLyogVGhpcyBtYWtlcyB0aGUgZ2wgc3VyZmFjZSBiaWdnZXIoMjQgYml0IGluc3RlYWQgb2YgMTYpLCBidXQgaXQgd29ya3Mgd2l0aAogICAgICAgICAgICAgICAgICogZml4ZWQgZnVuY3Rpb24gYW5kIHNoYWRlcnMgd2l0aG91dCBmdXJ0aGVyIGNvbnZlcnNpb24gb25jZSB0aGUgc3VyZmFjZSBpcwogICAgICAgICAgICAgICAgICogbG9hZGVkCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGZvcih5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CiAgICAgICAgICAgICAgICAgICAgU291cmNlID0gKFdPUkQgKikgKHNyYyArIHkgKiBwaXRjaCk7CiAgICAgICAgICAgICAgICAgICAgRGVzdCA9ICh1bnNpZ25lZCBjaGFyICopIChkc3QgKyB5ICogb3V0cGl0Y2gpOwogICAgICAgICAgICAgICAgICAgIGZvciAoeCA9IDA7IHggPCB3aWR0aDsgeCsrICkgewogICAgICAgICAgICAgICAgICAgICAgICBzaG9ydCBjb2xvciA9ICgqU291cmNlKyspOwogICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyIGwgPSAoKGNvbG9yID4+IDEwKSAmIDB4ZmMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhciB2ID0gKChjb2xvciA+PiAgNSkgJiAweDNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgdSA9ICgoY29sb3IgICAgICApICYgMHgxZik7CgogICAgICAgICAgICAgICAgICAgICAgICAvKiA4IGJpdHMgZGVzdGluYXRpb24sIDYgYml0cyBzb3VyY2UsIDh0aCBiaXQgaXMgdGhlIHNpZ24uIGdsIGlnbm9yZXMgdGhlIHNpZ24KICAgICAgICAgICAgICAgICAgICAgICAgICogYW5kIGRvdWJsZXMgdGhlIHBvc2l0aXZlIHJhbmdlLiBUaHVzIHNoaWZ0IGxlZnQgb25seSBvbmNlLCBnbCBkb2VzIHRoZSAybmQKICAgICAgICAgICAgICAgICAgICAgICAgICogc2hpZnQuIEdMIHJlYWRzIGEgc2lnbmVkIHZhbHVlIGFuZCBjb252ZXJ0cyBpdCBpbnRvIGFuIHVuc2lnbmVkIHZhbHVlLgogICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgLyogTSAqLyBEZXN0WzJdID0gbCA8PCAxOwoKICAgICAgICAgICAgICAgICAgICAgICAgLyogVGhvc2UgYXJlIHJlYWQgYXMgc2lnbmVkLCBidXQga2VwdCBzaWduZWQuIEp1c3QgbGVmdC1zaGlmdCAzIHRpbWVzIHRvIHNjYWxlCiAgICAgICAgICAgICAgICAgICAgICAgICAqIGZyb20gNSBiaXQgdmFsdWVzIHRvIDggYml0IHZhbHVlcy4KICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFYgKi8gRGVzdFsxXSA9IHYgPDwgMzsKICAgICAgICAgICAgICAgICAgICAgICAgLyogVSAqLyBEZXN0WzBdID0gdSA8PCAzOwogICAgICAgICAgICAgICAgICAgICAgICBEZXN0ICs9IDM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZm9yKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBzaG9ydCAqRGVzdF9zID0gKHVuc2lnbmVkIHNob3J0ICopIChkc3QgKyB5ICogb3V0cGl0Y2gpOwogICAgICAgICAgICAgICAgICAgIFNvdXJjZSA9IChXT1JEICopIChzcmMgKyB5ICogcGl0Y2gpOwogICAgICAgICAgICAgICAgICAgIGZvciAoeCA9IDA7IHggPCB3aWR0aDsgeCsrICkgewogICAgICAgICAgICAgICAgICAgICAgICBzaG9ydCBjb2xvciA9ICgqU291cmNlKyspOwogICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyIGwgPSAoKGNvbG9yID4+IDEwKSAmIDB4ZmMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG9ydCB2ID0gKChjb2xvciA+PiAgNSkgJiAweDNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hvcnQgdSA9ICgoY29sb3IgICAgICApICYgMHgxZik7CiAgICAgICAgICAgICAgICAgICAgICAgIHNob3J0IHZfY29udiA9IHYgKyAxNjsKICAgICAgICAgICAgICAgICAgICAgICAgc2hvcnQgdV9jb252ID0gdSArIDE2OwoKICAgICAgICAgICAgICAgICAgICAgICAgKkRlc3RfcyA9ICgodl9jb252IDw8IDExKSAmIDB4ZjgwMCkgfCAoKGwgPDwgNSkgJiAweDdlMCkgfCAodV9jb252ICYgMHgxZik7CiAgICAgICAgICAgICAgICAgICAgICAgIERlc3RfcyArPSAxOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgQ09OVkVSVF9YOEw4VjhVODoKICAgICAgICB7CiAgICAgICAgICAgIHVuc2lnbmVkIGludCB4LCB5OwogICAgICAgICAgICBEV09SRCAqU291cmNlOwogICAgICAgICAgICB1bnNpZ25lZCBjaGFyICpEZXN0OwoKICAgICAgICAgICAgaWYoR0xfU1VQUE9SVChOVl9URVhUVVJFX1NIQURFUikpIHsKICAgICAgICAgICAgICAgIC8qIFRoaXMgaW1wbGVtZW50YXRpb24gd29ya3Mgd2l0aCB0aGUgZml4ZWQgZnVuY3Rpb24gcGlwZWxpbmUgYW5kIHNoYWRlcnMKICAgICAgICAgICAgICAgICAqIHdpdGhvdXQgZnVydGhlciBtb2RpZmljYXRpb24gYWZ0ZXIgY29udmVydGluZyB0aGUgc3VyZmFjZS4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgZm9yKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKICAgICAgICAgICAgICAgICAgICBTb3VyY2UgPSAoRFdPUkQgKikgKHNyYyArIHkgKiBwaXRjaCk7CiAgICAgICAgICAgICAgICAgICAgRGVzdCA9ICh1bnNpZ25lZCBjaGFyICopIChkc3QgKyB5ICogb3V0cGl0Y2gpOwogICAgICAgICAgICAgICAgICAgIGZvciAoeCA9IDA7IHggPCB3aWR0aDsgeCsrICkgewogICAgICAgICAgICAgICAgICAgICAgICBsb25nIGNvbG9yID0gKCpTb3VyY2UrKyk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIEwgKi8gRGVzdFsyXSA9ICgoY29sb3IgPj4gMTYpICYgMHhmZik7ICAgLyogTCAqLwogICAgICAgICAgICAgICAgICAgICAgICAvKiBWICovIERlc3RbMV0gPSAoKGNvbG9yID4+IDggKSAmIDB4ZmYpOyAgIC8qIFYgKi8KICAgICAgICAgICAgICAgICAgICAgICAgLyogVSAqLyBEZXN0WzBdID0gKGNvbG9yICAgICAgICAgJiAweGZmKTsgICAvKiBVICovCiAgICAgICAgICAgICAgICAgICAgICAgIC8qIEkgKi8gRGVzdFszXSA9IDI1NTsgICAgICAgICAgICAgICAgICAgICAgLyogWCAqLwogICAgICAgICAgICAgICAgICAgICAgICBEZXN0ICs9IDQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLyogRG9lc24ndCB3b3JrIGNvcnJlY3RseSB3aXRoIHRoZSBmaXhlZCBmdW5jdGlvbiBwaXBlbGluZSwgYnV0IGNhbiB3b3JrIGluCiAgICAgICAgICAgICAgICAgKiBzaGFkZXJzIGlmIHRoZSBzaGFkZXIgaXMgYWRqdXN0ZWQuIChUaGVyZSdzIG5vIHVzZSBmb3IgdGhpcyBmb3JtYXQgaW4gZ2wncwogICAgICAgICAgICAgICAgICogc3RhbmRhcmQgZml4ZWQgZnVuY3Rpb24gcGlwZWxpbmUgYW55d2F5KS4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgZm9yKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKICAgICAgICAgICAgICAgICAgICBTb3VyY2UgPSAoRFdPUkQgKikgKHNyYyArIHkgKiBwaXRjaCk7CiAgICAgICAgICAgICAgICAgICAgRGVzdCA9ICh1bnNpZ25lZCBjaGFyICopIChkc3QgKyB5ICogb3V0cGl0Y2gpOwogICAgICAgICAgICAgICAgICAgIGZvciAoeCA9IDA7IHggPCB3aWR0aDsgeCsrICkgewogICAgICAgICAgICAgICAgICAgICAgICBsb25nIGNvbG9yID0gKCpTb3VyY2UrKyk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIEIgKi8gRGVzdFswXSA9ICgoY29sb3IgPj4gMTYpICYgMHhmZik7ICAgICAgIC8qIEwgKi8KICAgICAgICAgICAgICAgICAgICAgICAgLyogRyAqLyBEZXN0WzFdID0gKChjb2xvciA+PiA4ICkgJiAweGZmKSArIDEyODsgLyogViAqLwogICAgICAgICAgICAgICAgICAgICAgICAvKiBSICovIERlc3RbMl0gPSAoY29sb3IgICAgICAgICAmIDB4ZmYpICsgMTI4OyAgLyogVSAqLwogICAgICAgICAgICAgICAgICAgICAgICBEZXN0ICs9IDQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBDT05WRVJUX0E0TDQ6CiAgICAgICAgewogICAgICAgICAgICB1bnNpZ25lZCBpbnQgeCwgeTsKICAgICAgICAgICAgdW5zaWduZWQgY2hhciAqU291cmNlOwogICAgICAgICAgICB1bnNpZ25lZCBjaGFyICpEZXN0OwogICAgICAgICAgICBmb3IoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewogICAgICAgICAgICAgICAgU291cmNlID0gKHVuc2lnbmVkIGNoYXIgKikgKHNyYyArIHkgKiBwaXRjaCk7CiAgICAgICAgICAgICAgICBEZXN0ID0gKHVuc2lnbmVkIGNoYXIgKikgKGRzdCArIHkgKiBvdXRwaXRjaCk7CiAgICAgICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKyApIHsKICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyIGNvbG9yID0gKCpTb3VyY2UrKyk7CiAgICAgICAgICAgICAgICAgICAgLyogQSAqLyBEZXN0WzFdID0gKGNvbG9yICYgMHhmMCkgPDwgMDsKICAgICAgICAgICAgICAgICAgICAvKiBMICovIERlc3RbMF0gPSAoY29sb3IgJiAweDBmKSA8PCA0OwogICAgICAgICAgICAgICAgICAgIERlc3QgKz0gMjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgQ09OVkVSVF9SMzJGOgogICAgICAgIHsKICAgICAgICAgICAgdW5zaWduZWQgaW50IHgsIHk7CiAgICAgICAgICAgIGZsb2F0ICpTb3VyY2U7CiAgICAgICAgICAgIGZsb2F0ICpEZXN0OwogICAgICAgICAgICBmb3IoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewogICAgICAgICAgICAgICAgU291cmNlID0gKGZsb2F0ICopIChzcmMgKyB5ICogcGl0Y2gpOwogICAgICAgICAgICAgICAgRGVzdCA9IChmbG9hdCAqKSAoZHN0ICsgeSAqIG91dHBpdGNoKTsKICAgICAgICAgICAgICAgIGZvciAoeCA9IDA7IHggPCB3aWR0aDsgeCsrICkgewogICAgICAgICAgICAgICAgICAgIGZsb2F0IGNvbG9yID0gKCpTb3VyY2UrKyk7CiAgICAgICAgICAgICAgICAgICAgRGVzdFswXSA9IGNvbG9yOwogICAgICAgICAgICAgICAgICAgIERlc3RbMV0gPSAxLjA7CiAgICAgICAgICAgICAgICAgICAgRGVzdFsyXSA9IDEuMDsKICAgICAgICAgICAgICAgICAgICBEZXN0ICs9IDM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBjYXNlIENPTlZFUlRfUjE2RjoKICAgICAgICB7CiAgICAgICAgICAgIHVuc2lnbmVkIGludCB4LCB5OwogICAgICAgICAgICBXT1JEICpTb3VyY2U7CiAgICAgICAgICAgIFdPUkQgKkRlc3Q7CiAgICAgICAgICAgIFdPUkQgb25lID0gMHgzYzAwOwogICAgICAgICAgICBmb3IoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewogICAgICAgICAgICAgICAgU291cmNlID0gKFdPUkQgKikgKHNyYyArIHkgKiBwaXRjaCk7CiAgICAgICAgICAgICAgICBEZXN0ID0gKFdPUkQgKikgKGRzdCArIHkgKiBvdXRwaXRjaCk7CiAgICAgICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKyApIHsKICAgICAgICAgICAgICAgICAgICBXT1JEIGNvbG9yID0gKCpTb3VyY2UrKyk7CiAgICAgICAgICAgICAgICAgICAgRGVzdFswXSA9IGNvbG9yOwogICAgICAgICAgICAgICAgICAgIERlc3RbMV0gPSBvbmU7CiAgICAgICAgICAgICAgICAgICAgRGVzdFsyXSA9IG9uZTsKICAgICAgICAgICAgICAgICAgICBEZXN0ICs9IDM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEVSUigiVW5zdXBwb3J0ZWQgY29udmVyc2F0aW9uIHR5cGUgJWRcbiIsIGNvbnZlcnQpOwogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyB2b2lkIGQzZGZtdF9wOF9pbml0X3BhbGV0dGUoSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcywgQllURSB0YWJsZVsyNTZdWzRdLCBCT09MIGNvbG9ya2V5KSB7CiAgICBJV2luZUQzRFBhbGV0dGVJbXBsKiBwYWwgPSBUaGlzLT5wYWxldHRlOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgQk9PTCBpbmRleF9pbl9hbHBoYSA9IEZBTFNFOwogICAgaW50IGk7CgogICAgLyogT2xkIGdhbWVzIGxpa2UgU3RhckNyYWZ0LCBDJkMsIFJlZCBBbGVydCBhbmQgb3RoZXJzIHVzZSBQOCByZW5kZXIgdGFyZ2V0cy4KICAgICogUmVhZGluZyBiYWNrIHRoZSBSR0Igb3V0cHV0IGVhY2ggbG9ja3JlY3QgKGVhY2ggZnJhbWUgYXMgdGhleSBsb2NrIHRoZSB3aG9sZSBzY3JlZW4pCiAgICAqIGlzIHNsb3cuIEZ1cnRoZXIgUkdCLT5QOCBjb252ZXJzaW9uIGlzIG5vdCBwb3NzaWJsZSBiZWNhdXNlIHBhbGV0dGVzIGNhbiBoYXZlCiAgICAqIGR1cGxpY2F0ZSBlbnRyaWVzLiBTdG9yZSB0aGUgY29sb3Iga2V5IGluIHRoZSB1bnVzZWQgYWxwaGEgY29tcG9uZW50IHRvIHNwZWVkIHRoZQogICAgKiBkb3dubG9hZCB1cCBhbmQgdG8gbWFrZSBjb252ZXJzaW9uIHVubmVlZGVkLiAqLwogICAgaWYgKGRldmljZS0+cmVuZGVyX3RhcmdldHMgJiYgZGV2aWNlLT5yZW5kZXJfdGFyZ2V0c1swXSkgewogICAgICAgIElXaW5lRDNEU3VyZmFjZUltcGwqIHJlbmRlcl90YXJnZXQgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCopZGV2aWNlLT5yZW5kZXJfdGFyZ2V0c1swXTsKCiAgICAgICAgaWYocmVuZGVyX3RhcmdldC0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKQogICAgICAgICAgICBpbmRleF9pbl9hbHBoYSA9IFRSVUU7CiAgICB9CgogICAgaWYgKHBhbCA9PSBOVUxMKSB7CiAgICAgICAgLyogU3RpbGwgbm8gcGFsZXR0ZT8gVXNlIHRoZSBkZXZpY2UncyBwYWxldHRlICovCiAgICAgICAgLyogR2V0IHRoZSBzdXJmYWNlJ3MgcGFsZXR0ZSAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykgewogICAgICAgICAgICB0YWJsZVtpXVswXSA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1baV0ucGVSZWQ7CiAgICAgICAgICAgIHRhYmxlW2ldWzFdID0gZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtpXS5wZUdyZWVuOwogICAgICAgICAgICB0YWJsZVtpXVsyXSA9IGRldmljZS0+cGFsZXR0ZXNbZGV2aWNlLT5jdXJyZW50UGFsZXR0ZV1baV0ucGVCbHVlOwoKICAgICAgICAgICAgaWYoaW5kZXhfaW5fYWxwaGEpIHsKICAgICAgICAgICAgICAgIHRhYmxlW2ldWzNdID0gaTsKICAgICAgICAgICAgfSBlbHNlIGlmIChjb2xvcmtleSAmJgogICAgICAgICAgICAgICAgKGkgPj0gVGhpcy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZSkgJiYKICAgICAgICAgICAgICAgIChpIDw9IFRoaXMtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlKSkgewogICAgICAgICAgICAgICAgLyogV2Ugc2hvdWxkIG1heWJlIGhlcmUgcHV0IGEgbW9yZSAnbmV1dHJhbCcgY29sb3IgdGhhbiB0aGUgc3RhbmRhcmQgYnJpZ2h0IHB1cnBsZQogICAgICAgICAgICAgICAgICAgb25lIG9mdGVuIHVzZWQgYnkgYXBwbGljYXRpb24gdG8gcHJldmVudCB0aGUgbmljZSBwdXJwbGUgYm9yZGVycyB3aGVuIGJpLWxpbmVhcgogICAgICAgICAgICAgICAgICAgZmlsdGVyaW5nIGlzIG9uICovCiAgICAgICAgICAgICAgICB0YWJsZVtpXVszXSA9IDB4MDA7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0YWJsZVtpXVszXSA9IDB4RkY7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIFRSQUNFKCJVc2luZyBzdXJmYWNlIHBhbGV0dGUgJXBcbiIsIHBhbCk7CiAgICAgICAgLyogR2V0IHRoZSBzdXJmYWNlJ3MgcGFsZXR0ZSAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykgewogICAgICAgICAgICB0YWJsZVtpXVswXSA9IHBhbC0+cGFsZW50c1tpXS5wZVJlZDsKICAgICAgICAgICAgdGFibGVbaV1bMV0gPSBwYWwtPnBhbGVudHNbaV0ucGVHcmVlbjsKICAgICAgICAgICAgdGFibGVbaV1bMl0gPSBwYWwtPnBhbGVudHNbaV0ucGVCbHVlOwoKICAgICAgICAgICAgaWYoaW5kZXhfaW5fYWxwaGEpIHsKICAgICAgICAgICAgICAgIHRhYmxlW2ldWzNdID0gaTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChjb2xvcmtleSAmJgogICAgICAgICAgICAgICAgKGkgPj0gVGhpcy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZSkgJiYKICAgICAgICAgICAgICAgIChpIDw9IFRoaXMtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlKSkgewogICAgICAgICAgICAgICAgLyogV2Ugc2hvdWxkIG1heWJlIGhlcmUgcHV0IGEgbW9yZSAnbmV1dHJhbCcgY29sb3IgdGhhbiB0aGUgc3RhbmRhcmQgYnJpZ2h0IHB1cnBsZQogICAgICAgICAgICAgICAgICAgb25lIG9mdGVuIHVzZWQgYnkgYXBwbGljYXRpb24gdG8gcHJldmVudCB0aGUgbmljZSBwdXJwbGUgYm9yZGVycyB3aGVuIGJpLWxpbmVhcgogICAgICAgICAgICAgICAgICAgZmlsdGVyaW5nIGlzIG9uICovCiAgICAgICAgICAgICAgICB0YWJsZVtpXVszXSA9IDB4MDA7CiAgICAgICAgICAgIH0gZWxzZSBpZihwYWwtPkZsYWdzICYgV0lORUREUENBUFNfQUxQSEEpIHsKICAgICAgICAgICAgICAgIHRhYmxlW2ldWzNdID0gcGFsLT5wYWxlbnRzW2ldLnBlRmxhZ3M7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0YWJsZVtpXVszXSA9IDB4RkY7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCmNvbnN0IGNoYXIgKmZyYWdtZW50X3BhbGV0dGVfY29udmVyc2lvbiA9CiAgICAiISFBUkJmcDEuMFxuIgogICAgIlRFTVAgaW5kZXg7XG4iCiAgICAiUEFSQU0gY29uc3RhbnRzID0geyAwLjk5NiwgMC4wMDE5NSwgMCwgMCB9O1xuIiAvKiB7IDI1NS8yNTYsIDAuNS8yNTUqMjU1LzI1NiwgMCwgMCB9ICovCiAgICAiVEVYIGluZGV4LngsIGZyYWdtZW50LnRleGNvb3JkWzBdLCB0ZXh0dXJlWzBdLCAyRDtcbiIgLyogc3RvcmUgdGhlIHJlZC1jb21wb25lbnQgb2YgdGhlIGN1cnJlbnQgcGl4ZWwgKi8KICAgICJNQUQgaW5kZXgueCwgaW5kZXgueCwgY29uc3RhbnRzLngsIGNvbnN0YW50cy55O1xuIiAvKiBTY2FsZSB0aGUgaW5kZXggYnkgMjU1LzI1NiBhbmQgYWRkIGEgYmlhcyBvZiAnMC41JyBpbiBvcmRlciB0byBzYW1wbGUgaW4gdGhlIG1pZGRsZSAqLwogICAgIlRFWCByZXN1bHQuY29sb3IsIGluZGV4LCB0ZXh0dXJlWzFdLCAxRDtcbiIgLyogdXNlIHRoZSByZWQtY29tcG9uZW50IGFzIGEgaW5kZXggaW4gdGhlIHBhbGV0dGUgdG8gZ2V0IHRoZSBmaW5hbCBjb2xvciAqLwogICAgIkVORCI7CgovKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgaW4gY2FzZSBvZiA4Yml0IHBhbGV0dGVkIHRleHR1cmVzIHRvIHVwbG9hZCB0aGUgcGFsZXR0ZS4KICAgSXQgc3VwcG9ydHMgR0xfRVhUX3BhbGV0dGVkX3RleHR1cmUgYW5kIEdMX0FSQl9mcmFnbWVudF9wcm9ncmFtLCBzdXBwb3J0IGZvciBvdGhlcgogICBleHRlbnNpb25zIGxpa2UgQVRJX2ZyYWdtZW50X3NoYWRlcnMgaXMgcG9zc2libGUuCiovCnN0YXRpYyB2b2lkIGQzZGZtdF9wOF91cGxvYWRfcGFsZXR0ZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBDT05WRVJUX1RZUEVTIGNvbnZlcnQpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgQllURSB0YWJsZVsyNTZdWzRdOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwoKICAgIGQzZGZtdF9wOF9pbml0X3BhbGV0dGUoVGhpcywgdGFibGUsIChjb252ZXJ0ID09IENPTlZFUlRfUEFMRVRURURfQ0spKTsKCiAgICAvKiBUcnkgdG8gdXNlIHRoZSBwYWxldHRlZCB0ZXh0dXJlIGV4dGVuc2lvbiAqLwogICAgaWYoR0xfU1VQUE9SVChFWFRfUEFMRVRURURfVEVYVFVSRSkpCiAgICB7CiAgICAgICAgVFJBQ0UoIlVzaW5nIEdMX0VYVF9QQUxFVFRFRF9URVhUVVJFIGZvciA4LWJpdCBwYWxldHRlZCB0ZXh0dXJlIHN1cHBvcnRcbiIpOwogICAgICAgIEdMX0VYVENBTEwoZ2xDb2xvclRhYmxlRVhUKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LEdMX1JHQkEsMjU2LEdMX1JHQkEsR0xfVU5TSUdORURfQllURSwgdGFibGUpKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAvKiBMZXQgYSBmcmFnbWVudCBzaGFkZXIgZG8gdGhlIGNvbG9yIGNvbnZlcnNpb24gYnkgdXBsb2FkaW5nIHRoZSBwYWxldHRlIHRvIGEgMUQgdGV4dHVyZS4KICAgICAgICAgKiBUaGUgOGJpdCBwaXhlbCBkYXRhIHdpbGwgYmUgdXNlZCBhcyBhbiBpbmRleCBpbiB0aGlzIHBhbGV0dGUgdGV4dHVyZSB0byByZXRyaWV2ZSB0aGUgZmluYWwgY29sb3IuICovCiAgICAgICAgVFJBQ0UoIlVzaW5nIGZyYWdtZW50IHNoYWRlcnMgZm9yIGVtdWxhdGluZyA4LWJpdCBwYWxldHRlZCB0ZXh0dXJlIHN1cHBvcnRcbiIpOwoKICAgICAgICAvKiBDcmVhdGUgdGhlIGZyYWdtZW50IHByb2dyYW0gaWYgd2UgZG9uJ3QgaGF2ZSBpdCAqLwogICAgICAgIGlmKCFkZXZpY2UtPnBhbGV0dGVDb252ZXJzaW9uU2hhZGVyKQogICAgICAgIHsKICAgICAgICAgICAgZ2xFbmFibGUoR0xfRlJBR01FTlRfUFJPR1JBTV9BUkIpOwogICAgICAgICAgICBHTF9FWFRDQUxMKGdsR2VuUHJvZ3JhbXNBUkIoMSwgJmRldmljZS0+cGFsZXR0ZUNvbnZlcnNpb25TaGFkZXIpKTsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEJpbmRQcm9ncmFtQVJCKEdMX0ZSQUdNRU5UX1BST0dSQU1fQVJCLCBkZXZpY2UtPnBhbGV0dGVDb252ZXJzaW9uU2hhZGVyKSk7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xQcm9ncmFtU3RyaW5nQVJCKEdMX0ZSQUdNRU5UX1BST0dSQU1fQVJCLCBHTF9QUk9HUkFNX0ZPUk1BVF9BU0NJSV9BUkIsIHN0cmxlbihmcmFnbWVudF9wYWxldHRlX2NvbnZlcnNpb24pLCAoY29uc3QgR0xieXRlICopZnJhZ21lbnRfcGFsZXR0ZV9jb252ZXJzaW9uKSk7CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9GUkFHTUVOVF9QUk9HUkFNX0FSQik7CiAgICAgICAgfQoKICAgICAgICBnbEVuYWJsZShHTF9GUkFHTUVOVF9QUk9HUkFNX0FSQik7CiAgICAgICAgR0xfRVhUQ0FMTChnbEJpbmRQcm9ncmFtQVJCKEdMX0ZSQUdNRU5UX1BST0dSQU1fQVJCLCBkZXZpY2UtPnBhbGV0dGVDb252ZXJzaW9uU2hhZGVyKSk7CgogICAgICAgIEdMX0VYVENBTEwoZ2xBY3RpdmVUZXh0dXJlQVJCKEdMX1RFWFRVUkUxKSk7CiAgICAgICAgZ2xFbmFibGUoR0xfVEVYVFVSRV8xRCk7CiAgICAgICAgZ2xUZXhFbnZpKEdMX1RFWFRVUkVfRU5WLCBHTF9URVhUVVJFX0VOVl9NT0RFLCBHTF9SRVBMQUNFKTsKCiAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMUQsIEdMX1RFWFRVUkVfTUlOX0ZJTFRFUiwgR0xfTkVBUkVTVCk7CiAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMUQsIEdMX1RFWFRVUkVfTUFHX0ZJTFRFUiwgR0xfTkVBUkVTVCk7IC8qIE1ha2Ugc3VyZSB3ZSBoYXZlIGRpc2NyZXRlIGNvbG9yIGxldmVscy4gKi8KICAgICAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8xRCwgR0xfVEVYVFVSRV9XUkFQX1MsIEdMX0NMQU1QX1RPX0VER0UpOwogICAgICAgIGdsVGV4SW1hZ2UxRChHTF9URVhUVVJFXzFELCAwLCBHTF9SR0JBLCAyNTYsIDAsIEdMX1JHQkEsIEdMX1VOU0lHTkVEX0JZVEUsIHRhYmxlKTsgLyogVXBsb2FkIHRoZSBwYWxldHRlICovCgogICAgICAgIC8qIFN3aXRjaCBiYWNrIHRvIHVuaXQgMCBpbiB3aGljaCB0aGUgMkQgdGV4dHVyZSB3aWxsIGJlIHN0b3JlZC4gKi8KICAgICAgICBHTF9FWFRDQUxMKGdsQWN0aXZlVGV4dHVyZUFSQihHTF9URVhUVVJFMCkpOwoKICAgICAgICAvKiBSZWJpbmQgdGhlIHRleHR1cmUgYmVjYXVzZSBpdCBpc24ndCBib3VuZCBhbnltb3JlICovCiAgICAgICAgZ2xCaW5kVGV4dHVyZShUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICB9Cn0KCnN0YXRpYyBCT09MIHBhbGV0dGU5X2NoYW5nZWQoSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwoKICAgIGlmKFRoaXMtPnBhbGV0dGUgfHwgKFRoaXMtPnJlc291cmNlLmZvcm1hdCAhPSBXSU5FRDNERk1UX1A4ICYmIFRoaXMtPnJlc291cmNlLmZvcm1hdCAhPSBXSU5FRDNERk1UX0E4UDgpKSB7CiAgICAgICAgLyogSWYgYSBkZHJhdy1zdHlsZSBwYWxldHRlIGlzIGF0dGFjaGVkIGFzc3VtZSBubyBkM2Q5IHBhbGV0dGUgY2hhbmdlLgogICAgICAgICAqIEFsc28gdGhlIHBhbGV0dGUgaXNuJ3QgaW50ZXJlc3RpbmcgaWYgdGhlIHN1cmZhY2UgZm9ybWF0IGlzbid0IFA4IG9yIEE4UDgKICAgICAgICAgKi8KICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYoVGhpcy0+cGFsZXR0ZTkpIHsKICAgICAgICBpZihtZW1jbXAoVGhpcy0+cGFsZXR0ZTksICZkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdLCBzaXplb2YoUEFMRVRURUVOVFJZKSAqIDI1NikgPT0gMCkgewogICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBUaGlzLT5wYWxldHRlOSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoUEFMRVRURUVOVFJZKSAqIDI1Nik7CiAgICB9CiAgICBtZW1jcHkoVGhpcy0+cGFsZXR0ZTksICZkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdLCBzaXplb2YoUEFMRVRURUVOVFJZKSAqIDI1Nik7CiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIGlubGluZSB2b2lkIGNsZWFyX3VudXNlZF9jaGFubmVscyhJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzKSB7CiAgICBHTGJvb2xlYW4gb2xkd3JpdGVbNF07CgogICAgLyogU29tZSBmb3JtYXRzIGhhdmUgb25seSBzb21lIGNvbG9yIGNoYW5uZWxzLCBhbmQgdGhlIG90aGVycyBhcmUgMS4wLgogICAgICogc2luY2Ugb3VyIHJlbmRlcmluZyByZW5kZXJzIHRvIGFsbCBjaGFubmVscywgYW5kIHRob3NlIHBpeGVsIGZvcm1hdHMKICAgICAqIGFyZSBlbXVsYXRlZCBieSB1c2luZyBhIGZ1bGwgdGV4dHVyZSB3aXRoIHRoZSBvdGhlciBjaGFubmVscyBzZXQgdG8gMS4wCiAgICAgKiBtYW51YWxseSwgY2xlYXIgdGhlIHVudXNlZCBjaGFubmVscy4KICAgICAqCiAgICAgKiBUaGlzIGNvdWxkIGJlIGRvbmUgd2l0aCBoYWNraW5nIGNvbG9yd3JpdGVlbmFibGUgdG8gbWFzayB0aGUgY29sb3JzLAogICAgICogYnV0IGJlZm9yZSBkcmF3aW5nIHRoZSBidWZmZXIgd291bGQgaGF2ZSB0byBiZSBjbGVhcmVkIHRvbywgc28gdGhlcmUncwogICAgICogbm8gZ2FpbiBpbiB0aGF0CiAgICAgKi8KICAgIHN3aXRjaChUaGlzLT5yZXNvdXJjZS5mb3JtYXQpIHsKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjE2RjoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjMyRjoKICAgICAgICAgICAgVFJBQ0UoIlIxNkYgb3IgUjMyRiBmb3JtYXQsIGNsZWFyaW5nIGdyZWVuLCBibHVlIGFuZCBhbHBoYSB0byAxLjBcbiIpOwogICAgICAgICAgICAvKiBEbyBub3QgYWN0aXZhdGUgYSBjb250ZXh0LCB0aGUgY29ycmVjdCBkcmF3YWJsZSBpcyBhY3RpdmUgYWxyZWFkeQogICAgICAgICAgICAgKiB0aG91Z2gganVzdCB0aGUgcmVhZCBidWZmZXIgaXMgc2V0LCBtYWtlIHN1cmUgdG8gaGF2ZSB0aGUgY29ycmVjdCBkcmF3CiAgICAgICAgICAgICAqIGJ1ZmZlciB0b28KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlLT5vZmZzY3JlZW5CdWZmZXIpOwogICAgICAgICAgICBnbERpc2FibGUoR0xfU0NJU1NPUl9URVNUKTsKICAgICAgICAgICAgZ2xHZXRCb29sZWFudihHTF9DT0xPUl9XUklURU1BU0ssIG9sZHdyaXRlKTsKICAgICAgICAgICAgZ2xDb2xvck1hc2soR0xfRkFMU0UsIEdMX1RSVUUsIEdMX1RSVUUsIEdMX1RSVUUpOwogICAgICAgICAgICBnbENsZWFyQ29sb3IoMC4wLCAxLjAsIDEuMCwgMS4wKTsKICAgICAgICAgICAgZ2xDbGVhcihHTF9DT0xPUl9CVUZGRVJfQklUKTsKICAgICAgICAgICAgZ2xDb2xvck1hc2sob2xkd3JpdGVbMF0sIG9sZHdyaXRlWzFdLCBvbGR3cml0ZVsyXSwgb2xkd3JpdGVbM10pOwogICAgICAgICAgICBpZighVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZS0+cmVuZGVyX29mZnNjcmVlbikgZ2xEcmF3QnVmZmVyKEdMX0JBQ0spOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiVW51c2VkIGNoYW5uZWwgY2xlYXJcbiIpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDogYnJlYWs7CiAgICB9Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0xvYWRUZXh0dXJlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIEJPT0wgc3JnYl9tb2RlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKCiAgICBpZiAoIShUaGlzLT5GbGFncyAmIFNGTEFHX0lOVEVYVFVSRSkpIHsKICAgICAgICBUUkFDRSgiUmVsb2FkaW5nIGJlY2F1c2Ugc3VyZmFjZSBpcyBkaXJ0eVxuIik7CiAgICB9IGVsc2UgaWYoLyogUmVsb2FkOiBnbCB0ZXh0dXJlIGhhcyBjaywgbm93IG5vIGNrZXkgaXMgc2V0IE9SICovCiAgICAgICAgICAgICAgKChUaGlzLT5GbGFncyAmIFNGTEFHX0dMQ0tFWSkgJiYgKCEoVGhpcy0+Q0tleUZsYWdzICYgV0lORUREU0RfQ0tTUkNCTFQpKSkgfHwKICAgICAgICAgICAgICAvKiBSZWxvYWQ6IHZpY2UgdmVyc2EgIE9SICovCiAgICAgICAgICAgICAgKCghKFRoaXMtPkZsYWdzICYgU0ZMQUdfR0xDS0VZKSkgJiYgKFRoaXMtPkNLZXlGbGFncyAmIFdJTkVERFNEX0NLU1JDQkxUKSkgfHwKICAgICAgICAgICAgICAvKiBBbHNvIHJlbG9hZDogQ29sb3Iga2V5IGlzIGFjdGl2ZSBBTkQgdGhlIGNvbG9yIGtleSBoYXMgY2hhbmdlZCAqLwogICAgICAgICAgICAgICgoVGhpcy0+Q0tleUZsYWdzICYgV0lORUREU0RfQ0tTUkNCTFQpICYmICgKICAgICAgICAgICAgICAgIChUaGlzLT5nbENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWUgIT0gVGhpcy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZSkgfHwKICAgICAgICAgICAgICAgIChUaGlzLT5nbENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlICE9IFRoaXMtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlKSkpKSB7CiAgICAgICAgVFJBQ0UoIlJlbG9hZGluZyBiZWNhdXNlIG9mIGNvbG9yIGtleWluZ1xuIik7CiAgICAgICAgLyogVG8gcGVyZm9ybSB0aGUgY29sb3Iga2V5IGNvbnZlcnNpb24gd2UgbmVlZCBhIHN5c21lbSBjb3B5IG9mCiAgICAgICAgICogdGhlIHN1cmZhY2UuIE1ha2Ugc3VyZSB3ZSBoYXZlIGl0CiAgICAgICAgICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvYWRMb2NhdGlvbihpZmFjZSwgU0ZMQUdfSU5TWVNNRU0sIE5VTEwpOwogICAgfSBlbHNlIGlmKHBhbGV0dGU5X2NoYW5nZWQoVGhpcykpIHsKICAgICAgICBUUkFDRSgiUmVsb2FkaW5nIHN1cmZhY2UgYmVjYXVzZSB0aGUgZDNkOC85IHBhbGV0dGUgd2FzIGNoYW5nZWRcbiIpOwogICAgICAgIC8qIFRPRE86IFRoaXMgaXMgbm90IG5lY2Vzc2FyaWx5IG5lZWRlZCB3aXRoIGh3IHBhbGV0dGl6ZWQgdGV4dHVyZSBzdXBwb3J0ICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvYWRMb2NhdGlvbihpZmFjZSwgU0ZMQUdfSU5TWVNNRU0sIE5VTEwpOwogICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgic3VyZmFjZSBpcyBhbHJlYWR5IGluIHRleHR1cmVcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIC8qIFJlc291cmNlcyBhcmUgcGxhY2VkIGluIHN5c3RlbSBSQU0gYW5kIGRvIG5vdCBuZWVkIHRvIGJlIHJlY3JlYXRlZCB3aGVuIGEgZGV2aWNlIGlzIGxvc3QuCiAgICAgKiAgVGhlc2UgcmVzb3VyY2VzIGFyZSBub3QgYm91bmQgYnkgZGV2aWNlIHNpemUgb3IgZm9ybWF0IHJlc3RyaWN0aW9ucy4gQmVjYXVzZSBvZiB0aGlzLAogICAgICogIHRoZXNlIHJlc291cmNlcyBjYW5ub3QgYmUgYWNjZXNzZWQgYnkgdGhlIERpcmVjdDNEIGRldmljZSBub3Igc2V0IGFzIHRleHR1cmVzIG9yIHJlbmRlciB0YXJnZXRzLgogICAgICogIEhvd2V2ZXIsIHRoZXNlIHJlc291cmNlcyBjYW4gYWx3YXlzIGJlIGNyZWF0ZWQsIGxvY2tlZCwgYW5kIGNvcGllZC4KICAgICAqLwogICAgaWYgKFRoaXMtPnJlc291cmNlLnBvb2wgPT0gV0lORUQzRFBPT0xfU0NSQVRDSCApCiAgICB7CiAgICAgICAgRklYTUUoIiglcCkgT3BlcmF0aW9uIG5vdCBzdXBwb3J0ZWQgZm9yIHNjcmF0Y2ggdGV4dHVyZXNcbiIsVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgVGhpcy0+c3JnYiA9IHNyZ2JfbW9kZTsKICAgIElXaW5lRDNEU3VyZmFjZV9Mb2FkTG9jYXRpb24oaWZhY2UsIFNGTEFHX0lOVEVYVFVSRSwgTlVMTCAvKiBubyBwYXJ0aWFsIGxvY2tpbmcgZm9yIHRleHR1cmVzIHlldCAqLyk7CgojaWYgMAogICAgewogICAgICAgIHN0YXRpYyB1bnNpZ25lZCBpbnQgZ2VuID0gMDsKICAgICAgICBjaGFyIGJ1ZmZlcls0MDk2XTsKICAgICAgICArK2dlbjsKICAgICAgICBpZiAoKGdlbiAlIDEwKSA9PSAwKSB7CiAgICAgICAgICAgIHNucHJpbnRmKGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlciksICIvdG1wL3N1cmZhY2UlcF90eXBlJXVfbGV2ZWwldV8ldS5wcG0iLCBUaGlzLCBUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwgZ2VuKTsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TYXZlU25hcHNob3QoaWZhY2UsIGJ1ZmZlcik7CiAgICAgICAgfQogICAgICAgIC8qCiAgICAgICAgICogZGVidWdnaW5nIGNyYXNoIGNvZGUKICAgICAgICAgaWYgKGdlbiA9PSAyNTApIHsKICAgICAgICAgdm9pZCoqIHRlc3QgPSBOVUxMOwogICAgICAgICAqdGVzdCA9IDA7CiAgICAgICAgIH0KICAgICAgICAgKi8KICAgIH0KI2VuZGlmCgogICAgaWYgKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19ET05PVEZSRUUpKSB7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cmVzb3VyY2UuaGVhcE1lbW9yeSk7CiAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gTlVMTDsKICAgICAgICBUaGlzLT5yZXNvdXJjZS5oZWFwTWVtb3J5ID0gTlVMTDsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfTW9kaWZ5TG9jYXRpb24oaWZhY2UsIFNGTEFHX0lOU1lTTUVNLCBGQUxTRSk7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0JpbmRUZXh0dXJlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIC8qIFRPRE86IGNoZWNrIGZvciBsb2NrcyAqLwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzREJhc2VUZXh0dXJlICpiYXNlVGV4dHVyZSA9IE5VTEw7CiAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CgogICAgVFJBQ0UoIiglcClDaGVja2luZyB0byBzZWUgaWYgdGhlIGNvbnRhaW5lciBpcyBhIGJhc2UgdGV4dHVyZVxuIiwgVGhpcyk7CiAgICBpZiAoSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihpZmFjZSwgJklJRF9JV2luZUQzREJhc2VUZXh0dXJlLCAodm9pZCAqKikmYmFzZVRleHR1cmUpID09IFdJTkVEM0RfT0spIHsKICAgICAgICBUUkFDRSgiUGFzc2luZyB0byBjb250YWluZXJcbiIpOwogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfQmluZFRleHR1cmUoYmFzZVRleHR1cmUpOwogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUmVsZWFzZShiYXNlVGV4dHVyZSk7CiAgICB9IGVsc2UgewogICAgICAgIFRSQUNFKCIoJXApIDogQmluZGluZyBzdXJmYWNlXG4iLCBUaGlzKTsKCiAgICAgICAgaWYoIWRldmljZS0+aXNJbkRyYXcpIHsKICAgICAgICAgICAgQWN0aXZhdGVDb250ZXh0KGRldmljZSwgZGV2aWNlLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0LCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwogICAgICAgIH0KICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgIGdsQmluZFRleHR1cmUoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgIExFQVZFX0dMKCk7CiAgICB9CiAgICByZXR1cm47Cn0KCiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8c3RkaW8uaD4KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9TYXZlU25hcHNob3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgY29uc3QgY2hhciogZmlsZW5hbWUpIHsKICAgIEZJTEUqIGYgPSBOVUxMOwogICAgVUlOVCBpLCB5OwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBjaGFyICphbGxvY2F0ZWRNZW1vcnk7CiAgICBjaGFyICp0ZXh0dXJlUm93OwogICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBDaGFpbiA9IE5VTEw7CiAgICBpbnQgd2lkdGgsIGhlaWdodDsKICAgIEdMdWludCB0bXBUZXh0dXJlID0gMDsKICAgIERXT1JEIGNvbG9yOwogICAgLypGSVhNRToKICAgIFRleHR1cmVzIG1heSBub3QgYmUgc3RvcmVkIGluIC0+YWxsb2NhdGVkZ01lbW9yeSBhbmQgYSBHbFRleHR1cmUKICAgIHNvIHdlIHNob3VsZCBsb2NrIHRoZSBzdXJmYWNlIGJlZm9yZSBzYXZpbmcgYSBzbmFwc2hvdCwgb3IgYXQgbGVhc3QgY2hlY2sgdGhhdAogICAgKi8KICAgIC8qIFRPRE86IENvbXByZXNzZWQgdGV4dHVyZSBpbWFnZXMgY2FuIGJlIG9idGFpbmVkIGZyb20gdGhlIEdMIGluIHVuY29tcHJlc3NlZCBmb3JtCiAgICBieSBjYWxsaW5nIEdldFRleEltYWdlIGFuZCBpbiBjb21wcmVzc2VkIGZvcm0gYnkgY2FsbGluZwogICAgR2V0Q29tcHJlc3NlZFRleEltYWdlQVJCLiAgUXVlcmllZCBjb21wcmVzc2VkIGltYWdlcyBjYW4gYmUgc2F2ZWQgYW5kCiAgICBsYXRlciByZXVzZWQgYnkgY2FsbGluZyBDb21wcmVzc2VkVGV4SW1hZ2VbMTIzXURBUkIuICBQcmUtY29tcHJlc3NlZAogICAgdGV4dHVyZSBpbWFnZXMgZG8gbm90IG5lZWQgdG8gYmUgcHJvY2Vzc2VkIGJ5IHRoZSBHTCBhbmQgc2hvdWxkCiAgICBzaWduaWZpY2FudGx5IGltcHJvdmUgdGV4dHVyZSBsb2FkaW5nIHBlcmZvcm1hbmNlIHJlbGF0aXZlIHRvIHVuY29tcHJlc3NlZAogICAgaW1hZ2VzLiAqLwoKLyogU2V0dXAgdGhlIHdpZHRoIGFuZCBoZWlnaHQgdG8gYmUgdGhlIGludGVybmFsIHRleHR1cmUgd2lkdGggYW5kIGhlaWdodC4gKi8KICAgIHdpZHRoICA9IFRoaXMtPnBvdzJXaWR0aDsKICAgIGhlaWdodCA9IFRoaXMtPnBvdzJIZWlnaHQ7Ci8qIGNoZWNrIHRvIHNlZSBpZiB3ZSdyZSBhICd2aXJ0dWFsJyB0ZXh0dXJlLCBlLmcuIHdlJ3JlIG5vdCBhIHBidWZmZXIgb2YgdGV4dHVyZSwgd2UncmUgYSBiYWNrIGJ1ZmZlciovCiAgICBJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKGlmYWNlLCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikmc3dhcENoYWluKTsKCiAgICBpZiAoVGhpcy0+RmxhZ3MgJiBTRkxBR19JTkRSQVdBQkxFICYmICEoVGhpcy0+RmxhZ3MgJiBTRkxBR19JTlRFWFRVUkUpKSB7CiAgICAgICAgLyogaWYgd2VyZSBub3QgYSByZWFsIHRleHR1cmUgdGhlbiByZWFkIHRoZSBiYWNrIGJ1ZmZlciBpbnRvIGEgcmVhbCB0ZXh0dXJlICovCiAgICAgICAgLyogd2UgZG9uJ3Qgd2FudCB0byBpbnRlcmZlcmUgd2l0aCB0aGUgYmFjayBidWZmZXIgc28gcmVhZCB0aGUgZGF0YSBpbnRvIGEgdGVtcG9yYXJ5CiAgICAgICAgICogdGV4dHVyZSBhbmQgdGhlbiBzYXZlIHRoZSBkYXRhIG91dCBvZiB0aGUgdGVtcG9yYXJ5IHRleHR1cmUKICAgICAgICAgKi8KICAgICAgICBHTGludCBwcmV2UmVhZDsKICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgIFRSQUNFKCIoJXApIFJlYWRpbmcgcmVuZGVyIHRhcmdldCBpbnRvIHRleHR1cmVcbiIsIFRoaXMpOwogICAgICAgIGdsRW5hYmxlKEdMX1RFWFRVUkVfMkQpOwoKICAgICAgICBnbEdlblRleHR1cmVzKDEsICZ0bXBUZXh0dXJlKTsKICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIHRtcFRleHR1cmUpOwoKICAgICAgICBnbFRleEltYWdlMkQoR0xfVEVYVFVSRV8yRCwKICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgR0xfUkdCQSwKICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgMC8qYm9yZGVyKi8sCiAgICAgICAgICAgICAgICAgICAgICAgIEdMX1JHQkEsCiAgICAgICAgICAgICAgICAgICAgICAgIEdMX1VOU0lHTkVEX0lOVF84XzhfOF84X1JFViwKICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CgogICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfUkVBRF9CVUZGRVIsICZwcmV2UmVhZCk7CiAgICAgICAgdmNoZWNrR0xjYWxsKCJnbEdldEludGVnZXJ2Iik7CiAgICAgICAgZ2xSZWFkQnVmZmVyKHN3YXBDaGFpbiA/IEdMX0JBQ0sgOiBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlLT5vZmZzY3JlZW5CdWZmZXIpOwogICAgICAgIHZjaGVja0dMY2FsbCgiZ2xSZWFkQnVmZmVyIik7CiAgICAgICAgZ2xDb3B5VGV4SW1hZ2UyRChHTF9URVhUVVJFXzJELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdMX1JHQkEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgMCk7CgogICAgICAgIGNoZWNrR0xjYWxsKCJnbENvcHlUZXhJbWFnZTJEIik7CiAgICAgICAgZ2xSZWFkQnVmZmVyKHByZXZSZWFkKTsKICAgICAgICBMRUFWRV9HTCgpOwoKICAgIH0gZWxzZSB7IC8qIGJpbmQgdGhlIHJlYWwgdGV4dHVyZSwgYW5kIG1ha2Ugc3VyZSBpdCB1cCB0byBkYXRlICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1ByZUxvYWQoaWZhY2UpOwogICAgfQogICAgYWxsb2NhdGVkTWVtb3J5ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHdpZHRoICAqIGhlaWdodCAqIDQpOwogICAgRU5URVJfR0woKTsKICAgIEZJWE1FKCJTYXZpbmcgdGV4dHVyZSBsZXZlbCAlZCB3aWR0aCAlZCBoZWlnaHQgJWRcbiIsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIHdpZHRoLCBoZWlnaHQpOwogICAgZ2xHZXRUZXhJbWFnZShHTF9URVhUVVJFXzJELAogICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwKICAgICAgICAgICAgICAgIEdMX1JHQkEsCiAgICAgICAgICAgICAgICBHTF9VTlNJR05FRF9JTlRfOF84XzhfOF9SRVYsCiAgICAgICAgICAgICAgICBhbGxvY2F0ZWRNZW1vcnkpOwogICAgY2hlY2tHTGNhbGwoImdsVGV4SW1hZ2UyRCIpOwogICAgaWYgKHRtcFRleHR1cmUpIHsKICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIDApOwogICAgICAgIGdsRGVsZXRlVGV4dHVyZXMoMSwgJnRtcFRleHR1cmUpOwogICAgfQogICAgTEVBVkVfR0woKTsKCiAgICBmID0gZm9wZW4oZmlsZW5hbWUsICJ3KyIpOwogICAgaWYgKE5VTEwgPT0gZikgewogICAgICAgIEVSUigib3BlbmluZyBvZiAlcyBmYWlsZWQgd2l0aDogJXNcbiIsIGZpbGVuYW1lLCBzdHJlcnJvcihlcnJubykpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQovKiBTYXZlIHRoZSBkYXRhIG91dCB0byBhIFRHQSBmaWxlIGJlY2F1c2UgMTogaXQncyBhbiBlYXN5IHJhdyBmb3JtYXQsIDI6IGl0IHN1cHBvcnRzIGFuIGFscGhhIGNoYW5uZWwgKi8KICAgIFRSQUNFKCIoJXApIG9wZW5lZCAlcyB3aXRoIGZvcm1hdCAlc1xuIiwgVGhpcywgZmlsZW5hbWUsIGRlYnVnX2QzZGZvcm1hdChUaGlzLT5yZXNvdXJjZS5mb3JtYXQpKTsKLyogVEdBIGhlYWRlciAqLwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDAsZik7CiAgICBmcHV0YygyLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDAsZik7CiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDAsZik7CiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDAsZik7CiAgICBmcHV0YygwLGYpOwovKiBzaG9ydCB3aWR0aCovCiAgICBmd3JpdGUoJndpZHRoLDIsMSxmKTsKLyogc2hvcnQgaGVpZ2h0ICovCiAgICBmd3JpdGUoJmhlaWdodCwyLDEsZik7Ci8qIGZvcm1hdCByZ2JhICovCiAgICBmcHV0YygweDIwLGYpOwogICAgZnB1dGMoMHgyOCxmKTsKLyogcmF3IGRhdGEgKi8KICAgIC8qIGlmIHRoZSBkYXRhIGlzIHVwc2lkZSBkb3duIGlmIHdlJ3ZlIGZldGNoZWQgaXQgZnJvbSBhIGJhY2sgYnVmZmVyLCBzbyBpdCBuZWVkcyBmbGlwcGluZyBhZ2FpbiB0byBtYWtlIGl0IHRoZSBjb3JyZWN0IHdheSB1cCAqLwogICAgaWYoc3dhcENoYWluKQogICAgICAgIHRleHR1cmVSb3cgPSBhbGxvY2F0ZWRNZW1vcnkgKyAod2lkdGggKiAoaGVpZ2h0IC0gMSkgKjQpOwogICAgZWxzZQogICAgICAgIHRleHR1cmVSb3cgPSBhbGxvY2F0ZWRNZW1vcnk7CiAgICBmb3IgKHkgPSAwIDsgeSA8IGhlaWdodDsgeSsrKSB7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IHdpZHRoOyAgaSsrKSB7CiAgICAgICAgICAgIGNvbG9yID0gKigoRFdPUkQqKXRleHR1cmVSb3cpOwogICAgICAgICAgICBmcHV0YygoY29sb3IgPj4gMTYpICYgMHhGRiwgZik7IC8qIEIgKi8KICAgICAgICAgICAgZnB1dGMoKGNvbG9yID4+ICA4KSAmIDB4RkYsIGYpOyAvKiBHICovCiAgICAgICAgICAgIGZwdXRjKChjb2xvciA+PiAgMCkgJiAweEZGLCBmKTsgLyogUiAqLwogICAgICAgICAgICBmcHV0YygoY29sb3IgPj4gMjQpICYgMHhGRiwgZik7IC8qIEEgKi8KICAgICAgICAgICAgdGV4dHVyZVJvdyArPSA0OwogICAgICAgIH0KICAgICAgICAvKiB0YWtlIHR3byByb3dzIG9mIHRoZSBwb2ludGVyIHRvIHRoZSB0ZXh0dXJlIG1lbW9yeSAqLwogICAgICAgIGlmKHN3YXBDaGFpbikKICAgICAgICAgICAgKHRleHR1cmVSb3ctPSB3aWR0aCA8PCAzKTsKCiAgICB9CiAgICBUUkFDRSgiQ2xvc2luZyBmaWxlXG4iKTsKICAgIGZjbG9zZShmKTsKCiAgICBpZihzd2FwQ2hhaW4pIHsKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKHN3YXBDaGFpbik7CiAgICB9CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBhbGxvY2F0ZWRNZW1vcnkpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKgogKiAgIFNsaWdodGx5IGluZWZmaWNpZW50IHdheSB0byBoYW5kbGUgbXVsdGlwbGUgZGlydHkgcmVjdHMgYnV0IGl0IHdvcmtzIDopCiAqLwpleHRlcm4gSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9BZGREaXJ0eVJlY3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgQ09OU1QgUkVDVCogcERpcnR5UmVjdCkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzREJhc2VUZXh0dXJlICpiYXNlVGV4dHVyZSA9IE5VTEw7CgogICAgaWYgKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19JTlNZU01FTSkgJiYgKFRoaXMtPkZsYWdzICYgU0ZMQUdfSU5URVhUVVJFKSkKICAgICAgICBJV2luZUQzRFN1cmZhY2VfTG9hZExvY2F0aW9uKGlmYWNlLCBTRkxBR19JTlNZU01FTSwgTlVMTCAvKiBubyBwYXJ0aWFsIGxvY2tpbmcgZm9yIHRleHR1cmVzIHlldCAqLyk7CgogICAgSVdpbmVEM0RTdXJmYWNlX01vZGlmeUxvY2F0aW9uKGlmYWNlLCBTRkxBR19JTlNZU01FTSwgVFJVRSk7CiAgICBpZiAoTlVMTCAhPSBwRGlydHlSZWN0KSB7CiAgICAgICAgVGhpcy0+ZGlydHlSZWN0LmxlZnQgICA9IG1pbihUaGlzLT5kaXJ0eVJlY3QubGVmdCwgICBwRGlydHlSZWN0LT5sZWZ0KTsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QudG9wICAgID0gbWluKFRoaXMtPmRpcnR5UmVjdC50b3AsICAgIHBEaXJ0eVJlY3QtPnRvcCk7CiAgICAgICAgVGhpcy0+ZGlydHlSZWN0LnJpZ2h0ICA9IG1heChUaGlzLT5kaXJ0eVJlY3QucmlnaHQsICBwRGlydHlSZWN0LT5yaWdodCk7CiAgICAgICAgVGhpcy0+ZGlydHlSZWN0LmJvdHRvbSA9IG1heChUaGlzLT5kaXJ0eVJlY3QuYm90dG9tLCBwRGlydHlSZWN0LT5ib3R0b20pOwogICAgfSBlbHNlIHsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QubGVmdCAgID0gMDsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QudG9wICAgID0gMDsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QucmlnaHQgID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgVGhpcy0+ZGlydHlSZWN0LmJvdHRvbSA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgIH0KICAgIFRSQUNFKCIoJXApIDogRGlydHk6IHllcywgUmVjdDooJWQsJWQsJWQsJWQpXG4iLCBUaGlzLCBUaGlzLT5kaXJ0eVJlY3QubGVmdCwKICAgICAgICAgIFRoaXMtPmRpcnR5UmVjdC50b3AsIFRoaXMtPmRpcnR5UmVjdC5yaWdodCwgVGhpcy0+ZGlydHlSZWN0LmJvdHRvbSk7CiAgICAvKiBpZiB0aGUgY29udGFpbmVyIGlzIGEgYmFzZXRleHR1cmUgdGhlbiBtYXJrIGl0IGRpcnR5LiAqLwogICAgaWYgKElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoaWZhY2UsICZJSURfSVdpbmVEM0RCYXNlVGV4dHVyZSwgKHZvaWQgKiopJmJhc2VUZXh0dXJlKSA9PSBXSU5FRDNEX09LKSB7CiAgICAgICAgVFJBQ0UoIlBhc3NpbmcgdG8gY29udGFpbmVyXG4iKTsKICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX1NldERpcnR5KGJhc2VUZXh0dXJlLCBUUlVFKTsKICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX1JlbGVhc2UoYmFzZVRleHR1cmUpOwogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0Rm9ybWF0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFdJTkVEM0RGT1JNQVQgZm9ybWF0KSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIEhSRVNVTFQgaHI7CiAgICBjb25zdCBHbFBpeGVsRm9ybWF0RGVzYyAqZ2xEZXNjOwogICAgZ2V0Rm9ybWF0RGVzY0VudHJ5KGZvcm1hdCwgJkdMSU5GT19MT0NBVElPTiwgJmdsRGVzYyk7CgogICAgVFJBQ0UoIiglcCkgOiBDYWxsaW5nIGJhc2UgZnVuY3Rpb24gZmlyc3RcbiIsIFRoaXMpOwogICAgaHIgPSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9TZXRGb3JtYXQoaWZhY2UsIGZvcm1hdCk7CiAgICBpZihTVUNDRUVERUQoaHIpKSB7CiAgICAgICAgLyogU2V0dXAgc29tZSBnbGZvcm1hdCBkZWZhdWx0cyAqLwogICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXQgICAgICAgICA9IGdsRGVzYy0+Z2xGb3JtYXQ7CiAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdEludGVybmFsID0gZ2xEZXNjLT5nbEludGVybmFsOwogICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlICAgICAgICAgICA9IGdsRGVzYy0+Z2xUeXBlOwoKICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfQUxMT0NBVEVEOwogICAgICAgIFRSQUNFKCIoJXApIDogZ2xGb3JtYXQgJWQsIGdsRm90bWF0SW50ZXJuYWwgJWQsIGdsVHlwZSAlZFxuIiwgVGhpcywKICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0SW50ZXJuYWwsIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlKTsKICAgIH0KICAgIHJldHVybiBocjsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRNZW0oSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgdm9pZCAqTWVtKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CgogICAgaWYoVGhpcy0+RmxhZ3MgJiAoU0ZMQUdfTE9DS0VEIHwgU0ZMQUdfRENJTlVTRSkpIHsKICAgICAgICBXQVJOKCJTdXJmYWNlIGlzIGxvY2tlZCBvciB0aGUgSERDIGlzIGluIHVzZVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYoTWVtICYmIE1lbSAhPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpIHsKICAgICAgICB2b2lkICpyZWxlYXNlID0gTlVMTDsKCiAgICAgICAgLyogRG8gSSBoYXZlIHRvIGNvcHkgdGhlIG9sZCBzdXJmYWNlIGNvbnRlbnQ/ICovCiAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19ESUJTRUNUSU9OKSB7CiAgICAgICAgICAgICAgICAvKiBSZWxlYXNlIHRoZSBEQy4gTm8gbmVlZCB0byBob2xkIHRoZSBjcml0aWNhbCBzZWN0aW9uIGZvciB0aGUgdXBkYXRlCiAgICAgICAgICAgICAgICAgKiBUaHJlYWQgYmVjYXVzZSB0aGlzIHRocmVhZCBydW5zIG9ubHkgb24gZnJvbnQgYnVmZmVycywgYnV0IHRoaXMgbWV0aG9kCiAgICAgICAgICAgICAgICAgKiBmYWlscyBmb3IgcmVuZGVyIHRhcmdldHMgaW4gdGhlIGNoZWNrIGFib3ZlLgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBTZWxlY3RPYmplY3QoVGhpcy0+aERDLCBUaGlzLT5kaWIuaG9sZGJpdG1hcCk7CiAgICAgICAgICAgICAgICBEZWxldGVEQyhUaGlzLT5oREMpOwogICAgICAgICAgICAgICAgLyogUmVsZWFzZSB0aGUgRElCIHNlY3Rpb24gKi8KICAgICAgICAgICAgICAgIERlbGV0ZU9iamVjdChUaGlzLT5kaWIuRElCc2VjdGlvbik7CiAgICAgICAgICAgICAgICBUaGlzLT5kaWIuYml0bWFwX2RhdGEgPSBOVUxMOwogICAgICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gTlVMTDsKICAgICAgICAgICAgICAgIFRoaXMtPmhEQyA9IE5VTEw7CiAgICAgICAgICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfRElCU0VDVElPTjsKICAgICAgICB9IGVsc2UgaWYoIShUaGlzLT5GbGFncyAmIFNGTEFHX1VTRVJQVFIpKSB7CiAgICAgICAgICAgIHJlbGVhc2UgPSBUaGlzLT5yZXNvdXJjZS5oZWFwTWVtb3J5OwogICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5oZWFwTWVtb3J5ID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gTWVtOwogICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX1VTRVJQVFIgfCBTRkxBR19JTlNZU01FTTsKCiAgICAgICAgLyogTm93IHRoZSBzdXJmYWNlIG1lbW9yeSBpcyBtb3N0IHVwIGRvIGRhdGUuIEludmFsaWRhdGUgZHJhd2FibGUgYW5kIHRleHR1cmUgKi8KICAgICAgICBJV2luZUQzRFN1cmZhY2VfTW9kaWZ5TG9jYXRpb24oaWZhY2UsIFNGTEFHX0lOU1lTTUVNLCBUUlVFKTsKCiAgICAgICAgLyogRm9yIGNsaWVudCB0ZXh0dXJlcyBvcGVuZ2wgaGFzIHRvIGJlIG5vdGlmaWVkICovCiAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19DTElFTlQpIHsKICAgICAgICAgICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0FMTE9DQVRFRDsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1ByZUxvYWQoaWZhY2UpOwogICAgICAgICAgICAvKiBBbmQgaG9wZSB0aGF0IHRoZSBhcHAgYmVoYXZlcyBjb3JyZWN0bHkgYW5kIGRpZCBub3QgZnJlZSB0aGUgb2xkIHN1cmZhY2UgbWVtb3J5IGJlZm9yZSBzZXR0aW5nIGEgbmV3IHBvaW50ZXIgKi8KICAgICAgICB9CgogICAgICAgIC8qIE5vdyBmcmVlIHRoZSBvbGQgbWVtb3J5IGlmIGFueSAqLwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHJlbGVhc2UpOwogICAgfSBlbHNlIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfVVNFUlBUUikgewogICAgICAgIC8qIExvY2tyZWN0IGFuZCBHZXREQyB3aWxsIHJlLWNyZWF0ZSB0aGUgZGliIHNlY3Rpb24gYW5kIGFsbG9jYXRlZCBtZW1vcnkgKi8KICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBOVUxMOwogICAgICAgIC8qIEhlYXBNZW1vcnkgc2hvdWxkIGJlIE5VTEwgYWxyZWFkeSAqLwogICAgICAgIGlmKFRoaXMtPnJlc291cmNlLmhlYXBNZW1vcnkgIT0gTlVMTCkgRVJSKCJVc2VyIHBvaW50ZXIgc3VyZmFjZSBoYXMgaGVhcCBtZW1vcnkgYWxsb2NhdGVkXG4iKTsKICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfVVNFUlBUUjsKCiAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19DTElFTlQpIHsKICAgICAgICAgICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0FMTE9DQVRFRDsKICAgICAgICAgICAgLyogVGhpcyByZXNwZWNpZmllcyBhbiBlbXB0eSB0ZXh0dXJlIGFuZCBvcGVuZ2wga25vd3MgdGhhdCB0aGUgb2xkIG1lbW9yeSBpcyBnb25lICovCiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKGlmYWNlKTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfRmxpcChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBJV2luZUQzRFN1cmZhY2UgKm92ZXJyaWRlLCBEV09SRCBGbGFncykgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN3YXBDaGFpbkltcGwgKnN3YXBjaGFpbiA9IE5VTEw7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglcCwleClcbiIsIFRoaXMsIG92ZXJyaWRlLCBGbGFncyk7CgogICAgLyogRmxpcHBpbmcgaXMgb25seSBzdXBwb3J0ZWQgb24gUmVuZGVyVGFyZ2V0cyAqLwogICAgaWYoICEoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSApIHJldHVybiBXSU5FRERFUlJfTk9URkxJUFBBQkxFOwoKICAgIGlmKG92ZXJyaWRlKSB7CiAgICAgICAgLyogRERyYXcgc2V0cyB0aGlzIGZvciB0aGUgWDExIHN1cmZhY2VzLCBzbyBkb24ndCBjb25mdXNlIHRoZSB1c2VyIAogICAgICAgICAqIEZJWE1FKCIoJXApIFRhcmdldCBvdmVycmlkZSBpcyBub3Qgc3VwcG9ydGVkIGJ5IG5vd1xuIiwgVGhpcyk7CiAgICAgICAgICogQWRkaXRpb25hbGx5LCBpdCBpc24ndCByZWFsbHkgcG9zc2libGUgdG8gc3VwcG9ydCB0cmlwbGUtYnVmZmVyaW5nCiAgICAgICAgICogcHJvcGVybHkgb24gb3BlbmdsIGF0IGFsbAogICAgICAgICAqLwogICAgfQoKICAgIElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoaWZhY2UsICZJSURfSVdpbmVEM0RTd2FwQ2hhaW4sICh2b2lkICoqKSAmc3dhcGNoYWluKTsKICAgIGlmKCFzd2FwY2hhaW4pIHsKICAgICAgICBFUlIoIkZsaXBwZWQgc3VyZmFjZSBpcyBub3Qgb24gYSBzd2FwY2hhaW5cbiIpOwogICAgICAgIHJldHVybiBXSU5FRERFUlJfTk9URkxJUFBBQkxFOwogICAgfQoKICAgIC8qIEp1c3Qgb3ZlcndyaXRlIHRoZSBzd2FwY2hhaW4gcHJlc2VudGF0aW9uIGludGVydmFsLiBUaGlzIGlzIG9rIGJlY2F1c2Ugb25seSBkZHJhdyBhcHBzIGNhbiBjYWxsIEZsaXAsCiAgICAgKiBhbmQgb25seSBkM2Q4IGFuZCBkM2Q5IGFwcHMgc3BlY2lmeSB0aGUgcHJlc2VudGF0aW9uIGludGVydmFsCiAgICAgKi8KICAgIGlmKChGbGFncyAmIChXSU5FRERGTElQX05PVlNZTkMgfCBXSU5FRERGTElQX0lOVEVSVkFMMiB8IFdJTkVEREZMSVBfSU5URVJWQUwzIHwgV0lORURERkxJUF9JTlRFUlZBTDQpKSA9PSAwKSB7CiAgICAgICAgLyogTW9zdCBjb21tb24gY2FzZSBmaXJzdCB0byBhdm9pZCB3YXN0aW5nIHRpbWUgb24gYWxsIHRoZSBvdGhlciBjYXNlcyAqLwogICAgICAgIHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLlByZXNlbnRhdGlvbkludGVydmFsID0gV0lORUQzRFBSRVNFTlRfSU5URVJWQUxfT05FOwogICAgfSBlbHNlIGlmKEZsYWdzICYgV0lORURERkxJUF9OT1ZTWU5DKSB7CiAgICAgICAgc3dhcGNoYWluLT5wcmVzZW50UGFybXMuUHJlc2VudGF0aW9uSW50ZXJ2YWwgPSBXSU5FRDNEUFJFU0VOVF9JTlRFUlZBTF9JTU1FRElBVEU7CiAgICB9IGVsc2UgaWYoRmxhZ3MgJiBXSU5FRERGTElQX0lOVEVSVkFMMikgewogICAgICAgIHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLlByZXNlbnRhdGlvbkludGVydmFsID0gV0lORUQzRFBSRVNFTlRfSU5URVJWQUxfVFdPOwogICAgfSBlbHNlIGlmKEZsYWdzICYgV0lORURERkxJUF9JTlRFUlZBTDMpIHsKICAgICAgICBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5QcmVzZW50YXRpb25JbnRlcnZhbCA9IFdJTkVEM0RQUkVTRU5UX0lOVEVSVkFMX1RIUkVFOwogICAgfSBlbHNlIHsKICAgICAgICBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5QcmVzZW50YXRpb25JbnRlcnZhbCA9IFdJTkVEM0RQUkVTRU5UX0lOVEVSVkFMX0ZPVVI7CiAgICB9CgogICAgLyogRmxpcHBpbmcgYSBPcGVuR0wgc3VyZmFjZSAtPiBVc2UgV2luZUQzRERldmljZTo6UHJlc2VudCAqLwogICAgaHIgPSBJV2luZUQzRFN3YXBDaGFpbl9QcmVzZW50KChJV2luZUQzRFN3YXBDaGFpbiAqKSBzd2FwY2hhaW4sIE5VTEwsIE5VTEwsIDAsIE5VTEwsIDApOwogICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4gKikgc3dhcGNoYWluKTsKICAgIHJldHVybiBocjsKfQoKLyogRG9lcyBhIGRpcmVjdCBmcmFtZSBidWZmZXIgLT4gdGV4dHVyZSBjb3B5LiBTdHJldGNoaW5nIGlzIGRvbmUKICogd2l0aCBzaW5nbGUgcGl4ZWwgY29weSBjYWxscwogKi8Kc3RhdGljIGlubGluZSB2b2lkIGZiX2NvcHlfdG9fdGV4dHVyZV9kaXJlY3QoSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcywgSVdpbmVEM0RTdXJmYWNlICpTcmNTdXJmYWNlLCBJV2luZUQzRFN3YXBDaGFpbkltcGwgKnN3YXBjaGFpbiwgV0lORUQzRFJFQ1QgKnNyZWN0LCBXSU5FRDNEUkVDVCAqZHJlY3QsIEJPT0wgdXBzaWRlZG93biwgV0lORUQzRFRFWFRVUkVGSUxURVJUWVBFIEZpbHRlcikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpteURldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICBmbG9hdCB4cmVsLCB5cmVsOwogICAgVUlOVCByb3c7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpTcmMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBTcmNTdXJmYWNlOwoKCiAgICBBY3RpdmF0ZUNvbnRleHQobXlEZXZpY2UsIFNyY1N1cmZhY2UsIENUWFVTQUdFX0JMSVQpOwogICAgRU5URVJfR0woKTsKICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKChJV2luZUQzRFN1cmZhY2UgKikgVGhpcyk7CgogICAgLyogVE9ETzogRG8gd2UgbmVlZCBHTF9URVhUVVJFXzJEIGVuYWJsZWQgZnByIGNvcHl0ZXhpbWFnZT8gKi8KICAgIGdsRW5hYmxlKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0KTsKICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZShUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCkiKTsKCiAgICAvKiBCaW5kIHRoZSB0YXJnZXQgdGV4dHVyZSAqLwogICAgZ2xCaW5kVGV4dHVyZShUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICBjaGVja0dMY2FsbCgiZ2xCaW5kVGV4dHVyZSIpOwogICAgaWYoIXN3YXBjaGFpbikgewogICAgICAgIGdsUmVhZEJ1ZmZlcihteURldmljZS0+b2Zmc2NyZWVuQnVmZmVyKTsKICAgIH0gZWxzZSB7CiAgICAgICAgR0xlbnVtIGJ1ZmZlciA9IHN1cmZhY2VfZ2V0X2dsX2J1ZmZlcihTcmNTdXJmYWNlLCAoSVdpbmVEM0RTd2FwQ2hhaW4gKilzd2FwY2hhaW4pOwogICAgICAgIGdsUmVhZEJ1ZmZlcihidWZmZXIpOwogICAgfQogICAgY2hlY2tHTGNhbGwoImdsUmVhZEJ1ZmZlciIpOwoKICAgIHhyZWwgPSAoZmxvYXQpIChzcmVjdC0+eDIgLSBzcmVjdC0+eDEpIC8gKGZsb2F0KSAoZHJlY3QtPngyIC0gZHJlY3QtPngxKTsKICAgIHlyZWwgPSAoZmxvYXQpIChzcmVjdC0+eTIgLSBzcmVjdC0+eTEpIC8gKGZsb2F0KSAoZHJlY3QtPnkyIC0gZHJlY3QtPnkxKTsKCiAgICBpZiggKHhyZWwgLSAxLjAgPCAtZXBzKSB8fCAoeHJlbCAtIDEuMCA+IGVwcykpIHsKICAgICAgICBGSVhNRSgiRG9pbmcgYSBwaXhlbCBieSBwaXhlbCBjb3B5IGZyb20gdGhlIGZyYW1lYnVmZmVyIHRvIGEgdGV4dHVyZSwgZXhwZWN0IG1ham9yIHBlcmZvcm1hbmNlIGlzc3Vlc1xuIik7CgogICAgICAgIGlmKEZpbHRlciAhPSBXSU5FRDNEVEVYRl9OT05FICYmIEZpbHRlciAhPSBXSU5FRDNEVEVYRl9QT0lOVCkgewogICAgICAgICAgICBFUlIoIlRleHR1cmUgZmlsdGVyaW5nIG5vdCBzdXBwb3J0ZWQgaW4gZGlyZWN0IGJsaXRcbiIpOwogICAgICAgIH0KICAgIH0gZWxzZSBpZigoRmlsdGVyICE9IFdJTkVEM0RURVhGX05PTkUgJiYgRmlsdGVyICE9IFdJTkVEM0RURVhGX1BPSU5UKSAmJiAoKHlyZWwgLSAxLjAgPCAtZXBzKSB8fCAoeXJlbCAtIDEuMCA+IGVwcykpKSB7CiAgICAgICAgRVJSKCJUZXh0dXJlIGZpbHRlcmluZyBub3Qgc3VwcG9ydGVkIGluIGRpcmVjdCBibGl0XG4iKTsKICAgIH0KCiAgICBpZih1cHNpZGVkb3duICYmCiAgICAgICAhKCh4cmVsIC0gMS4wIDwgLWVwcykgfHwgKHhyZWwgLSAxLjAgPiBlcHMpKSAmJgogICAgICAgISgoeXJlbCAtIDEuMCA8IC1lcHMpIHx8ICh5cmVsIC0gMS4wID4gZXBzKSkpIHsKICAgICAgICAvKiBVcHNpZGUgZG93biBjb3B5IHdpdGhvdXQgc3RyZXRjaGluZyBpcyBuaWNlLCBvbmUgZ2xDb3B5VGV4U3ViSW1hZ2UgY2FsbCB3aWxsIGRvICovCgogICAgICAgIGdsQ29weVRleFN1YkltYWdlMkQoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJlY3QtPngxLCBkcmVjdC0+eTEsIC8qIHhvZmZzZXQsIHlvZmZzZXQgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyZWN0LT54MSwgU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQgLSBzcmVjdC0+eTIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcmVjdC0+eDIgLSBkcmVjdC0+eDEsIGRyZWN0LT55MiAtIGRyZWN0LT55MSk7CiAgICB9IGVsc2UgewogICAgICAgIFVJTlQgeW9mZnNldCA9IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0IC0gc3JlY3QtPnkxICsgZHJlY3QtPnkxIC0gMTsKICAgICAgICAvKiBJIGhhdmUgdG8gcHJvY2VzcyB0aGlzIHJvdyBieSByb3cgdG8gc3dhcCB0aGUgaW1hZ2UsCiAgICAgICAgICogb3RoZXJ3aXNlIGl0IHdvdWxkIGJlIHVwc2lkZSBkb3duLCBzbyBzdHJldGNoaW5nIGluIHkgZGlyZWN0aW9uCiAgICAgICAgICogZG9lc24ndCBjb3N0IGV4dHJhIHRpbWUKICAgICAgICAgKgogICAgICAgICAqIEhvd2V2ZXIsIHN0cmV0Y2hpbmcgaW4geCBkaXJlY3Rpb24gY2FuIGJlIGF2b2lkZWQgaWYgbm90IG5lY2Vzc2FyeQogICAgICAgICAqLwogICAgICAgIGZvcihyb3cgPSBkcmVjdC0+eTE7IHJvdyA8IGRyZWN0LT55Mjsgcm93KyspIHsKICAgICAgICAgICAgaWYoICh4cmVsIC0gMS4wIDwgLWVwcykgfHwgKHhyZWwgLSAxLjAgPiBlcHMpKSB7CiAgICAgICAgICAgICAgICAvKiBXZWxsLCB0aGF0IHN0dWZmIHdvcmtzLCBidXQgaXQncyB2ZXJ5IHNsb3cuCiAgICAgICAgICAgICAgICAgKiBmaW5kIGEgYmV0dGVyIHdheSBpbnN0ZWFkCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIFVJTlQgY29sOwoKICAgICAgICAgICAgICAgIGZvcihjb2wgPSBkcmVjdC0+eDE7IGNvbCA8IGRyZWN0LT54MjsgY29sKyspIHsKICAgICAgICAgICAgICAgICAgICBnbENvcHlUZXhTdWJJbWFnZTJEKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRyZWN0LT54MSArIGNvbCwgcm93LCAvKiB4b2Zmc2V0LCB5b2Zmc2V0ICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcmVjdC0+eDEgKyBjb2wgKiB4cmVsLCB5b2Zmc2V0IC0gKGludCkgKHJvdyAqIHlyZWwpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBnbENvcHlUZXhTdWJJbWFnZTJEKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcmVjdC0+eDEsIHJvdywgLyogeG9mZnNldCwgeW9mZnNldCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcmVjdC0+eDEsIHlvZmZzZXQgLSAoaW50KSAocm93ICogeXJlbCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRyZWN0LT54Mi1kcmVjdC0+eDEsIDEpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgdmNoZWNrR0xjYWxsKCJnbENvcHlUZXhTdWJJbWFnZTJEIik7CgogICAgLyogTGVhdmUgdGhlIG9wZW5nbCBzdGF0ZSB2YWxpZCBmb3IgYmxpdHRpbmcgKi8KICAgIGdsRGlzYWJsZShUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCk7CiAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0KSIpOwoKICAgIExFQVZFX0dMKCk7Cn0KCi8qIFVzZXMgdGhlIGhhcmR3YXJlIHRvIHN0cmV0Y2ggYW5kIGZsaXAgdGhlIGltYWdlICovCnN0YXRpYyBpbmxpbmUgdm9pZCBmYl9jb3B5X3RvX3RleHR1cmVfaHdzdHJldGNoKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMsIElXaW5lRDNEU3VyZmFjZSAqU3JjU3VyZmFjZSwgSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICpzd2FwY2hhaW4sIFdJTkVEM0RSRUNUICpzcmVjdCwgV0lORUQzRFJFQ1QgKmRyZWN0LCBCT09MIHVwc2lkZWRvd24sIFdJTkVEM0RURVhUVVJFRklMVEVSVFlQRSBGaWx0ZXIpIHsKICAgIEdMdWludCBzcmMsIGJhY2t1cCA9IDA7CiAgICBJV2luZUQzRERldmljZUltcGwgKm15RGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlNyYyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFNyY1N1cmZhY2U7CiAgICBmbG9hdCBsZWZ0LCByaWdodCwgdG9wLCBib3R0b207IC8qIFRleHR1cmUgY29vcmRpbmF0ZXMgKi8KICAgIFVJTlQgZmJ3aWR0aCA9IFNyYy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICBVSU5UIGZiaGVpZ2h0ID0gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICBHTGVudW0gZHJhd0J1ZmZlciA9IEdMX0JBQ0s7CiAgICBHTGVudW0gdGV4dHVyZV90YXJnZXQ7CgogICAgVFJBQ0UoIlVzaW5nIGh3c3RyZXRjaCBibGl0XG4iKTsKICAgIC8qIEFjdGl2YXRlIHRoZSBQcm9wZXIgY29udGV4dCBmb3IgcmVhZGluZyBmcm9tIHRoZSBzb3VyY2Ugc3VyZmFjZSwgc2V0IGl0IHVwIGZvciBibGl0dGluZyAqLwogICAgQWN0aXZhdGVDb250ZXh0KG15RGV2aWNlLCBTcmNTdXJmYWNlLCBDVFhVU0FHRV9CTElUKTsKICAgIEVOVEVSX0dMKCk7CgogICAgSVdpbmVEM0RTdXJmYWNlX1ByZUxvYWQoKElXaW5lRDNEU3VyZmFjZSAqKSBUaGlzKTsKCiAgICAvKiBUcnkgdG8gdXNlIGFuIGF1eCBidWZmZXIgZm9yIGRyYXdpbmcgdGhlIHJlY3RhbmdsZS4gVGhpcyB3YXkgaXQgZG9lc24ndCBuZWVkIHJlc3RvcmluZy4KICAgICAqIFRoaXMgd2F5IHdlIGRvbid0IGhhdmUgdG8gd2FpdCBmb3IgdGhlIDJuZCByZWFkYmFjayB0byBmaW5pc2ggdG8gbGVhdmUgdGhpcyBmdW5jdGlvbi4KICAgICAqLwogICAgaWYoR0xfTElNSVRTKGF1eF9idWZmZXJzKSA+PSAyKSB7CiAgICAgICAgLyogR290IG1vcmUgdGhhbiBvbmUgYXV4IGJ1ZmZlcj8gVXNlIHRoZSAybmQgYXV4IGJ1ZmZlciAqLwogICAgICAgIGRyYXdCdWZmZXIgPSBHTF9BVVgxOwogICAgfSBlbHNlIGlmKChzd2FwY2hhaW4gfHwgbXlEZXZpY2UtPm9mZnNjcmVlbkJ1ZmZlciA9PSBHTF9CQUNLKSAmJiBHTF9MSU1JVFMoYXV4X2J1ZmZlcnMpID49IDEpIHsKICAgICAgICAvKiBPbmx5IG9uZSBhdXggYnVmZmVyLCBidXQgaXQgaXNuJ3QgdXNlZCAoT25zY3JlZW4gcmVuZGVyaW5nLCBvciBub24tYXV4IG9ybSk/IFVzZSBpdCEgKi8KICAgICAgICBkcmF3QnVmZmVyID0gR0xfQVVYMDsKICAgIH0KCiAgICBpZighc3dhcGNoYWluICYmIHdpbmVkM2Rfc2V0dGluZ3Mub2Zmc2NyZWVuX3JlbmRlcmluZ19tb2RlID09IE9STV9GQk8pIHsKICAgICAgICBnbEdlblRleHR1cmVzKDEsICZiYWNrdXApOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEdlblRleHR1cmVzXG4iKTsKICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIGJhY2t1cCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZFRleHR1cmUoU3JjLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgU3JjLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKSIpOwogICAgICAgIHRleHR1cmVfdGFyZ2V0ID0gR0xfVEVYVFVSRV8yRDsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogQmFja3VwIHRoZSBiYWNrIGJ1ZmZlciBhbmQgY29weSB0aGUgc291cmNlIGJ1ZmZlciBpbnRvIGEgdGV4dHVyZSB0byBkcmF3IGFuIHVwc2lkZSBkb3duIHN0cmV0Y2hlZCBxdWFkLiBJZgogICAgICAgICAqIHdlIGFyZSByZWFkaW5nIGZyb20gdGhlIGJhY2sgYnVmZmVyLCB0aGUgYmFja3VwIGNhbiBiZSB1c2VkIGFzIHNvdXJjZSB0ZXh0dXJlCiAgICAgICAgICovCiAgICAgICAgaWYoU3JjLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lID09IDApIHsKICAgICAgICAgICAgLyogR2V0IGl0IGEgZGVzY3JpcHRpb24gKi8KICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1ByZUxvYWQoU3JjU3VyZmFjZSk7CiAgICAgICAgfQogICAgICAgIHRleHR1cmVfdGFyZ2V0ID0gU3JjLT5nbERlc2NyaXB0aW9uLnRhcmdldDsKICAgICAgICBnbEJpbmRUZXh0dXJlKHRleHR1cmVfdGFyZ2V0LCBTcmMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRUZXh0dXJlKHRleHR1cmVfdGFyZ2V0LCBTcmMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpIik7CiAgICAgICAgZ2xFbmFibGUodGV4dHVyZV90YXJnZXQpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSh0ZXh0dXJlX3RhcmdldCkiKTsKCiAgICAgICAgLyogRm9yIG5vdyBpbnZhbGlkYXRlIHRoZSB0ZXh0dXJlIGNvcHkgb2YgdGhlIGJhY2sgYnVmZmVyLiBEcmF3YWJsZSBhbmQgc3lzbWVtIGNvcHkgYXJlIHVudG91Y2hlZCAqLwogICAgICAgIFNyYy0+RmxhZ3MgJj0gflNGTEFHX0lOVEVYVFVSRTsKICAgIH0KCiAgICBnbFJlYWRCdWZmZXIoR0xfQkFDSyk7CiAgICBjaGVja0dMY2FsbCgiZ2xSZWFkQnVmZmVyKEdMX0JBQ0spIik7CgogICAgLyogVE9ETzogT25seSBiYWNrIHVwIHRoZSBwYXJ0IHRoYXQgd2lsbCBiZSBvdmVyd3JpdHRlbiAqLwogICAgZ2xDb3B5VGV4U3ViSW1hZ2UyRCh0ZXh0dXJlX3RhcmdldCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCAvKiByZWFkIG9mZnNldHMgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgIGZid2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgIGZiaGVpZ2h0KTsKCiAgICBjaGVja0dMY2FsbCgiZ2xDb3B5VGV4U3ViSW1hZ2UyRCIpOwoKICAgIC8qIE5vIGlzc3VlIHdpdGggb3ZlcnJpZGluZyB0aGVzZSAtIHRoZSBzYW1wbGVyIGlzIGRpcnR5IGR1ZSB0byBibGl0IHVzYWdlICovCiAgICBnbFRleFBhcmFtZXRlcmkodGV4dHVyZV90YXJnZXQsIEdMX1RFWFRVUkVfTUFHX0ZJTFRFUiwKICAgICAgICAgICAgICAgICAgICBzdGF0ZUxvb2t1cFtXSU5FTE9PS1VQX01BR0ZJTFRFUl1bRmlsdGVyIC0gbWluTG9va3VwW1dJTkVMT09LVVBfTUFHRklMVEVSXV0pOwogICAgY2hlY2tHTGNhbGwoImdsVGV4UGFyYW1ldGVyaSIpOwogICAgZ2xUZXhQYXJhbWV0ZXJpKHRleHR1cmVfdGFyZ2V0LCBHTF9URVhUVVJFX01JTl9GSUxURVIsCiAgICAgICAgICAgICAgICAgICAgbWluTWlwTG9va3VwW0ZpbHRlcl1bV0lORUQzRFRFWEZfTk9ORV0pOwogICAgY2hlY2tHTGNhbGwoImdsVGV4UGFyYW1ldGVyaSIpOwoKICAgIGlmKCFzd2FwY2hhaW4gfHwgKElXaW5lRDNEU3VyZmFjZSAqKSBTcmMgPT0gc3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdKSB7CiAgICAgICAgc3JjID0gYmFja3VwID8gYmFja3VwIDogU3JjLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lOwogICAgfSBlbHNlIHsKICAgICAgICBnbFJlYWRCdWZmZXIoR0xfRlJPTlQpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIoR0xfRlJPTlQpIik7CgogICAgICAgIGdsR2VuVGV4dHVyZXMoMSwgJnNyYyk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsR2VuVGV4dHVyZXMoMSwgJnNyYykiKTsKICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIHNyYyk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgc3JjKSIpOwoKICAgICAgICAvKiBUT0RPOiBPbmx5IGNvcHkgdGhlIHBhcnQgdGhhdCB3aWxsIGJlIHJlYWQuIFVzZSBzcmVjdC0+eDEsIHNyZWN0LT55MiBhcyBvcmlnaW4sIGJ1dCB3aXRoIHRoZSB3aWR0aCB3YXRjaAogICAgICAgICAqIG91dCBmb3IgcG93ZXIgb2YgMiBzaXplcwogICAgICAgICAqLwogICAgICAgIGdsVGV4SW1hZ2UyRChHTF9URVhUVVJFXzJELCAwLCBHTF9SR0JBLCBTcmMtPnBvdzJXaWR0aCwgU3JjLT5wb3cySGVpZ2h0LCAwLAogICAgICAgICAgICAgICAgICAgIEdMX1JHQkEsIEdMX1VOU0lHTkVEX0JZVEUsIE5VTEwpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleEltYWdlMkQiKTsKICAgICAgICBnbENvcHlUZXhTdWJJbWFnZTJEKEdMX1RFWFRVUkVfMkQsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwIC8qIHJlYWQgb2Zmc2V0cyAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYndpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmJoZWlnaHQpOwoKICAgICAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NQUdfRklMVEVSLCBHTF9ORUFSRVNUKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhQYXJhbWV0ZXJpIik7CiAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfTUlOX0ZJTFRFUiwgR0xfTkVBUkVTVCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4UGFyYW1ldGVyaSIpOwoKICAgICAgICBnbFJlYWRCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsUmVhZEJ1ZmZlcihHTF9CQUNLKSIpOwoKICAgICAgICBpZih0ZXh0dXJlX3RhcmdldCAhPSBHTF9URVhUVVJFXzJEKSB7CiAgICAgICAgICAgIGdsRGlzYWJsZSh0ZXh0dXJlX3RhcmdldCk7CiAgICAgICAgICAgIGdsRW5hYmxlKEdMX1RFWFRVUkVfMkQpOwogICAgICAgICAgICB0ZXh0dXJlX3RhcmdldCA9IEdMX1RFWFRVUkVfMkQ7CiAgICAgICAgfQogICAgfQogICAgY2hlY2tHTGNhbGwoImdsRW5kIGFuZCBwcmV2aW91cyIpOwoKICAgIGxlZnQgPSAoZmxvYXQpIHNyZWN0LT54MSAvIChmbG9hdCkgU3JjLT5wb3cyV2lkdGg7CiAgICByaWdodCA9IChmbG9hdCkgc3JlY3QtPngyIC8gKGZsb2F0KSBTcmMtPnBvdzJXaWR0aDsKCiAgICBpZih1cHNpZGVkb3duKSB7CiAgICAgICAgdG9wID0gKGZsb2F0KSAoU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQgLSBzcmVjdC0+eTEpIC8gKGZsb2F0KSBTcmMtPnBvdzJIZWlnaHQ7CiAgICAgICAgYm90dG9tID0gKGZsb2F0KSAoU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQgLSBzcmVjdC0+eTIpIC8gKGZsb2F0KSBTcmMtPnBvdzJIZWlnaHQ7CiAgICB9IGVsc2UgewogICAgICAgIHRvcCA9IChmbG9hdCkgKFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0IC0gc3JlY3QtPnkyKSAvIChmbG9hdCkgU3JjLT5wb3cySGVpZ2h0OwogICAgICAgIGJvdHRvbSA9IChmbG9hdCkgKFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0IC0gc3JlY3QtPnkxKSAvIChmbG9hdCkgU3JjLT5wb3cySGVpZ2h0OwogICAgfQoKICAgIC8qIGRyYXcgdGhlIHNvdXJjZSB0ZXh0dXJlIHN0cmV0Y2hlZCBhbmQgdXBzaWRlIGRvd24uIFRoZSBjb3JyZWN0IHN1cmZhY2UgaXMgYm91bmQgYWxyZWFkeSAqLwogICAgZ2xUZXhQYXJhbWV0ZXJpKHRleHR1cmVfdGFyZ2V0LCBHTF9URVhUVVJFX1dSQVBfUywgR0xfQ0xBTVApOwogICAgZ2xUZXhQYXJhbWV0ZXJpKHRleHR1cmVfdGFyZ2V0LCBHTF9URVhUVVJFX1dSQVBfVCwgR0xfQ0xBTVApOwoKICAgIGdsRHJhd0J1ZmZlcihkcmF3QnVmZmVyKTsKICAgIGdsUmVhZEJ1ZmZlcihkcmF3QnVmZmVyKTsKCiAgICBnbEJlZ2luKEdMX1FVQURTKTsKICAgICAgICAvKiBib3R0b20gbGVmdCAqLwogICAgICAgIGdsVGV4Q29vcmQyZihsZWZ0LCBib3R0b20pOwogICAgICAgIGdsVmVydGV4MmkoMCwgZmJoZWlnaHQpOwoKICAgICAgICAvKiB0b3AgbGVmdCAqLwogICAgICAgIGdsVGV4Q29vcmQyZihsZWZ0LCB0b3ApOwogICAgICAgIGdsVmVydGV4MmkoMCwgZmJoZWlnaHQgLSBkcmVjdC0+eTIgLSBkcmVjdC0+eTEpOwoKICAgICAgICAvKiB0b3AgcmlnaHQgKi8KICAgICAgICBnbFRleENvb3JkMmYocmlnaHQsIHRvcCk7CiAgICAgICAgZ2xWZXJ0ZXgyaShkcmVjdC0+eDIgLSBkcmVjdC0+eDEsIGZiaGVpZ2h0IC0gZHJlY3QtPnkyIC0gZHJlY3QtPnkxKTsKCiAgICAgICAgLyogYm90dG9tIHJpZ2h0ICovCiAgICAgICAgZ2xUZXhDb29yZDJmKHJpZ2h0LCBib3R0b20pOwogICAgICAgIGdsVmVydGV4MmkoZHJlY3QtPngyIC0gZHJlY3QtPngxLCBmYmhlaWdodCk7CiAgICBnbEVuZCgpOwogICAgY2hlY2tHTGNhbGwoImdsRW5kIGFuZCBwcmV2aW91cyIpOwoKICAgIGlmKHRleHR1cmVfdGFyZ2V0ICE9IFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0KSB7CiAgICAgICAgZ2xEaXNhYmxlKHRleHR1cmVfdGFyZ2V0KTsKICAgICAgICBnbEVuYWJsZShUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCk7CiAgICAgICAgdGV4dHVyZV90YXJnZXQgPSBUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldDsKICAgIH0KCiAgICAvKiBOb3cgcmVhZCB0aGUgc3RyZXRjaGVkIGFuZCB1cHNpZGUgZG93biBpbWFnZSBpbnRvIHRoZSBkZXN0aW5hdGlvbiB0ZXh0dXJlICovCiAgICBnbEJpbmRUZXh0dXJlKHRleHR1cmVfdGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRUZXh0dXJlIik7CiAgICBnbENvcHlUZXhTdWJJbWFnZTJEKHRleHR1cmVfdGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICBkcmVjdC0+eDEsIGRyZWN0LT55MSwgLyogeG9mZnNldCwgeW9mZnNldCAqLwogICAgICAgICAgICAgICAgICAgICAgICAwLCAwLCAvKiBXZSBibGl0dGVkIHRoZSBpbWFnZSB0byB0aGUgb3JpZ2luICovCiAgICAgICAgICAgICAgICAgICAgICAgIGRyZWN0LT54MiAtIGRyZWN0LT54MSwgZHJlY3QtPnkyIC0gZHJlY3QtPnkxKTsKICAgIGNoZWNrR0xjYWxsKCJnbENvcHlUZXhTdWJJbWFnZTJEIik7CgogICAgaWYoZHJhd0J1ZmZlciA9PSBHTF9CQUNLKSB7CiAgICAgICAgLyogV3JpdGUgdGhlIGJhY2sgYnVmZmVyIGJhY2t1cCBiYWNrICovCiAgICAgICAgaWYoYmFja3VwKSB7CiAgICAgICAgICAgIGlmKHRleHR1cmVfdGFyZ2V0ICE9IEdMX1RFWFRVUkVfMkQpIHsKICAgICAgICAgICAgICAgIGdsRGlzYWJsZSh0ZXh0dXJlX3RhcmdldCk7CiAgICAgICAgICAgICAgICBnbEVuYWJsZShHTF9URVhUVVJFXzJEKTsKICAgICAgICAgICAgICAgIHRleHR1cmVfdGFyZ2V0ID0gR0xfVEVYVFVSRV8yRDsKICAgICAgICAgICAgfQogICAgICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIGJhY2t1cCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIGJhY2t1cCkiKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZih0ZXh0dXJlX3RhcmdldCAhPSBTcmMtPmdsRGVzY3JpcHRpb24udGFyZ2V0KSB7CiAgICAgICAgICAgICAgICBnbERpc2FibGUodGV4dHVyZV90YXJnZXQpOwogICAgICAgICAgICAgICAgZ2xFbmFibGUoU3JjLT5nbERlc2NyaXB0aW9uLnRhcmdldCk7CiAgICAgICAgICAgICAgICB0ZXh0dXJlX3RhcmdldCA9IFNyYy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZ2xCaW5kVGV4dHVyZShTcmMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBTcmMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kVGV4dHVyZShTcmMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBTcmMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpIik7CiAgICAgICAgfQoKICAgICAgICBnbEJlZ2luKEdMX1FVQURTKTsKICAgICAgICAgICAgLyogdG9wIGxlZnQgKi8KICAgICAgICAgICAgZ2xUZXhDb29yZDJmKDAuMCwgKGZsb2F0KSBmYmhlaWdodCAvIChmbG9hdCkgU3JjLT5wb3cySGVpZ2h0KTsKICAgICAgICAgICAgZ2xWZXJ0ZXgyaSgwLCAwKTsKCiAgICAgICAgICAgIC8qIGJvdHRvbSBsZWZ0ICovCiAgICAgICAgICAgIGdsVGV4Q29vcmQyZigwLjAsIDAuMCk7CiAgICAgICAgICAgIGdsVmVydGV4MmkoMCwgZmJoZWlnaHQpOwoKICAgICAgICAgICAgLyogYm90dG9tIHJpZ2h0ICovCiAgICAgICAgICAgIGdsVGV4Q29vcmQyZigoZmxvYXQpIGZid2lkdGggLyAoZmxvYXQpIFNyYy0+cG93MldpZHRoLCAwLjApOwogICAgICAgICAgICBnbFZlcnRleDJpKGZid2lkdGgsIFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0KTsKCiAgICAgICAgICAgIC8qIHRvcCByaWdodCAqLwogICAgICAgICAgICBnbFRleENvb3JkMmYoKGZsb2F0KSBmYndpZHRoIC8gKGZsb2F0KSBTcmMtPnBvdzJXaWR0aCwgKGZsb2F0KSBmYmhlaWdodCAvIChmbG9hdCkgU3JjLT5wb3cySGVpZ2h0KTsKICAgICAgICAgICAgZ2xWZXJ0ZXgyaShmYndpZHRoLCAwKTsKICAgICAgICBnbEVuZCgpOwogICAgfSBlbHNlIHsKICAgICAgICAvKiBSZXN0b3JlIHRoZSBvbGQgZHJhdyBidWZmZXIgKi8KICAgICAgICBnbERyYXdCdWZmZXIoR0xfQkFDSyk7CiAgICB9CiAgICBnbERpc2FibGUodGV4dHVyZV90YXJnZXQpOwogICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSh0ZXh0dXJlX3RhcmdldCkiKTsKCiAgICAvKiBDbGVhbnVwICovCiAgICBpZihzcmMgIT0gU3JjLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lICYmIHNyYyAhPSBiYWNrdXApIHsKICAgICAgICBnbERlbGV0ZVRleHR1cmVzKDEsICZzcmMpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbERlbGV0ZVRleHR1cmVzKDEsICZzcmMpIik7CiAgICB9CiAgICBpZihiYWNrdXApIHsKICAgICAgICBnbERlbGV0ZVRleHR1cmVzKDEsICZiYWNrdXApOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbERlbGV0ZVRleHR1cmVzKDEsICZiYWNrdXApIik7CiAgICB9CgogICAgTEVBVkVfR0woKTsKfQoKLyogTm90IGNhbGxlZCBmcm9tIHRoZSBWVGFibGUgKi8Kc3RhdGljIEhSRVNVTFQgSVdpbmVEM0RTdXJmYWNlSW1wbF9CbHRPdmVycmlkZShJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBSRUNUICpEZXN0UmVjdCwgSVdpbmVEM0RTdXJmYWNlICpTcmNTdXJmYWNlLCBSRUNUICpTcmNSZWN0LCBEV09SRCBGbGFncywgV0lORUREQkxURlggKkREQmx0RngsIFdJTkVEM0RURVhUVVJFRklMVEVSVFlQRSBGaWx0ZXIpIHsKICAgIFdJTkVEM0RSRUNUIHJlY3Q7CiAgICBJV2luZUQzRERldmljZUltcGwgKm15RGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqc3JjU3dhcGNoYWluID0gTlVMTCwgKmRzdFN3YXBjaGFpbiA9IE5VTEw7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpTcmMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBTcmNTdXJmYWNlOwoKICAgIFRSQUNFKCIoJXApLT4oJXAsJXAsJXAsJTA4eCwlcClcbiIsIFRoaXMsIERlc3RSZWN0LCBTcmNTdXJmYWNlLCBTcmNSZWN0LCBGbGFncywgRERCbHRGeCk7CgogICAgLyogR2V0IHRoZSBzd2FwY2hhaW4uIE9uZSBvZiB0aGUgc3VyZmFjZXMgaGFzIHRvIGJlIGEgcHJpbWFyeSBzdXJmYWNlICovCiAgICBpZihUaGlzLT5yZXNvdXJjZS5wb29sID09IFdJTkVEM0RQT09MX1NZU1RFTU1FTSkgewogICAgICAgIFdBUk4oIkRlc3RpbmF0aW9uIGlzIGluIHN5c21lbSwgcmVqZWN0aW5nIGdsIGJsdFxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICBJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKCAoSVdpbmVEM0RTdXJmYWNlICopIFRoaXMsICZJSURfSVdpbmVEM0RTd2FwQ2hhaW4sICh2b2lkICoqKSZkc3RTd2FwY2hhaW4pOwogICAgaWYoZHN0U3dhcGNoYWluKSBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKChJV2luZUQzRFN3YXBDaGFpbiAqKSBkc3RTd2FwY2hhaW4pOwogICAgaWYoU3JjKSB7CiAgICAgICAgaWYoU3JjLT5yZXNvdXJjZS5wb29sID09IFdJTkVEM0RQT09MX1NZU1RFTU1FTSkgewogICAgICAgICAgICBXQVJOKCJTcmMgaXMgaW4gc3lzbWVtLCByZWplY3RpbmcgZ2wgYmx0XG4iKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfQogICAgICAgIElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoIChJV2luZUQzRFN1cmZhY2UgKikgU3JjLCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikmc3JjU3dhcGNoYWluKTsKICAgICAgICBpZihzcmNTd2FwY2hhaW4pIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElXaW5lRDNEU3dhcENoYWluICopIHNyY1N3YXBjaGFpbik7CiAgICB9CgogICAgLyogRWFybHkgc29ydCBvdXQgb2YgY2FzZXMgd2hlcmUgbm8gcmVuZGVyIHRhcmdldCBpcyB1c2VkICovCiAgICBpZighZHN0U3dhcGNoYWluICYmICFzcmNTd2FwY2hhaW4gJiYKICAgICAgICBTcmNTdXJmYWNlICE9IG15RGV2aWNlLT5yZW5kZXJfdGFyZ2V0c1swXSAmJiBUaGlzICE9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIG15RGV2aWNlLT5yZW5kZXJfdGFyZ2V0c1swXSkgewogICAgICAgIFRSQUNFKCJObyBzdXJmYWNlIGlzIHJlbmRlciB0YXJnZXQsIG5vdCB1c2luZyBoYXJkd2FyZSBibGl0LiBTcmMgPSAlcCwgZHN0ID0gJXBcbiIsIFNyYywgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogTm8gZGVzdGluYXRpb24gY29sb3Iga2V5aW5nIHN1cHBvcnRlZCAqLwogICAgaWYoRmxhZ3MgJiAoV0lORUREQkxUX0tFWURFU1QgfCBXSU5FRERCTFRfS0VZREVTVE9WRVJSSURFKSkgewogICAgICAgIC8qIENhbiB3ZSBzdXBwb3J0IHRoYXQgd2l0aCBnbEJsZW5kRnVuYyBpZiBibGl0dGluZyB0byB0aGUgZnJhbWUgYnVmZmVyPyAqLwogICAgICAgIFRSQUNFKCJEZXN0aW5hdGlvbiBjb2xvciBrZXkgbm90IHN1cHBvcnRlZCBpbiBhY2NlbGVyYXRlZCBCbGl0LCBmYWxsaW5nIGJhY2sgdG8gc29mdHdhcmVcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmIChEZXN0UmVjdCkgewogICAgICAgIHJlY3QueDEgPSBEZXN0UmVjdC0+bGVmdDsKICAgICAgICByZWN0LnkxID0gRGVzdFJlY3QtPnRvcDsKICAgICAgICByZWN0LngyID0gRGVzdFJlY3QtPnJpZ2h0OwogICAgICAgIHJlY3QueTIgPSBEZXN0UmVjdC0+Ym90dG9tOwogICAgfSBlbHNlIHsKICAgICAgICByZWN0LngxID0gMDsKICAgICAgICByZWN0LnkxID0gMDsKICAgICAgICByZWN0LngyID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgcmVjdC55MiA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgIH0KCiAgICAvKiBUaGUgb25seSBjYXNlIHdoZXJlIGJvdGggc3VyZmFjZXMgb24gYSBzd2FwY2hhaW4gYXJlIHN1cHBvcnRlZCBpcyBhIGJhY2sgYnVmZmVyIC0+IGZyb250IGJ1ZmZlciBibGl0IG9uIHRoZSBzYW1lIHN3YXBjaGFpbiAqLwogICAgaWYoZHN0U3dhcGNoYWluICYmIGRzdFN3YXBjaGFpbiA9PSBzcmNTd2FwY2hhaW4gJiYgZHN0U3dhcGNoYWluLT5iYWNrQnVmZmVyICYmCiAgICAgICAoKElXaW5lRDNEU3VyZmFjZSAqKSBUaGlzID09IGRzdFN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIpICYmIFNyY1N1cmZhY2UgPT0gZHN0U3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdKSB7CiAgICAgICAgLyogSGFsZi1saWZlIGRvZXMgYSBCbHQgZnJvbSB0aGUgYmFjayBidWZmZXIgdG8gdGhlIGZyb250IGJ1ZmZlciwKICAgICAgICAgKiBGdWxsIHN1cmZhY2Ugc2l6ZSwgbm8gZmxhZ3MuLi4gVXNlIHByZXNlbnQgaW5zdGVhZAogICAgICAgICAqCiAgICAgICAgICogVGhpcyBwYXRoIHdpbGwgb25seSBiZSBlbnRlcmVkIGZvciBkM2Q3IGFuZCBkZHJhdyBhcHBzLCBiZWNhdXNlIGQzZDgvOSBvZmZlciBubyB3YXkgdG8gYmxpdCBUTyB0aGUgZnJvbnQgYnVmZmVyCiAgICAgICAgICovCgogICAgICAgIC8qIENoZWNrIHJlY3RzIC0gSVdpbmVEM0REZXZpY2VfUHJlc2VudCBkb2Vzbid0IGhhbmRsZSB0aGVtICovCiAgICAgICAgd2hpbGUoMSkKICAgICAgICB7CiAgICAgICAgICAgIFJFQ1QgbXlTcmNSZWN0OwogICAgICAgICAgICBUUkFDRSgiTG9va2luZyBpZiBhIFByZXNlbnQgY2FuIGJlIGRvbmUuLi5cbiIpOwogICAgICAgICAgICAvKiBTb3VyY2UgUmVjdGFuZ2xlIG11c3QgYmUgZnVsbCBzdXJmYWNlICovCiAgICAgICAgICAgIGlmKCBTcmNSZWN0ICkgewogICAgICAgICAgICAgICAgaWYoU3JjUmVjdC0+bGVmdCAhPSAwIHx8IFNyY1JlY3QtPnRvcCAhPSAwIHx8CiAgICAgICAgICAgICAgICAgICBTcmNSZWN0LT5yaWdodCAhPSBTcmMtPmN1cnJlbnREZXNjLldpZHRoIHx8IFNyY1JlY3QtPmJvdHRvbSAhPSBTcmMtPmN1cnJlbnREZXNjLkhlaWdodCkgewogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJObywgU291cmNlIHJlY3RhbmdsZSBkb2Vzbid0IG1hdGNoXG4iKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBteVNyY1JlY3QubGVmdCA9IDA7CiAgICAgICAgICAgIG15U3JjUmVjdC50b3AgPSAwOwogICAgICAgICAgICBteVNyY1JlY3QucmlnaHQgPSBTcmMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgICAgICBteVNyY1JlY3QuYm90dG9tID0gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQ7CgogICAgICAgICAgICAvKiBObyBzdHJldGNoaW5nIG1heSBvY2N1ciAqLwogICAgICAgICAgICBpZihteVNyY1JlY3QucmlnaHQgIT0gcmVjdC54MiAtIHJlY3QueDEgfHwKICAgICAgICAgICAgICAgbXlTcmNSZWN0LmJvdHRvbSAhPSByZWN0LnkyIC0gcmVjdC55MSkgewogICAgICAgICAgICAgICAgVFJBQ0UoIk5vLCBzdHJldGNoaW5nIGlzIGRvbmVcbiIpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIERlc3RpbmF0aW9uIG11c3QgYmUgZnVsbCBzdXJmYWNlIG9yIG1hdGNoIHRoZSBjbGlwcGluZyByZWN0YW5nbGUgKi8KICAgICAgICAgICAgaWYoVGhpcy0+Y2xpcHBlciAmJiAoKElXaW5lRDNEQ2xpcHBlckltcGwgKikgVGhpcy0+Y2xpcHBlciktPmhXbmQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFJFQ1QgY2xpcHJlY3Q7CiAgICAgICAgICAgICAgICBQT0lOVCBwb3NbMl07CiAgICAgICAgICAgICAgICBHZXRDbGllbnRSZWN0KCgoSVdpbmVEM0RDbGlwcGVySW1wbCAqKSBUaGlzLT5jbGlwcGVyKS0+aFduZCwgJmNsaXByZWN0KTsKICAgICAgICAgICAgICAgIHBvc1swXS54ID0gcmVjdC54MTsKICAgICAgICAgICAgICAgIHBvc1swXS55ID0gcmVjdC55MTsKICAgICAgICAgICAgICAgIHBvc1sxXS54ID0gcmVjdC54MjsKICAgICAgICAgICAgICAgIHBvc1sxXS55ID0gcmVjdC55MjsKICAgICAgICAgICAgICAgIE1hcFdpbmRvd1BvaW50cyhHZXREZXNrdG9wV2luZG93KCksICgoSVdpbmVEM0RDbGlwcGVySW1wbCAqKSBUaGlzLT5jbGlwcGVyKS0+aFduZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb3MsIDIpOwoKICAgICAgICAgICAgICAgIGlmKHBvc1swXS54ICE9IGNsaXByZWN0LmxlZnQgIHx8IHBvc1swXS55ICE9IGNsaXByZWN0LnRvcCAgIHx8CiAgICAgICAgICAgICAgICAgICBwb3NbMV0ueCAhPSBjbGlwcmVjdC5yaWdodCB8fCBwb3NbMV0ueSAhPSBjbGlwcmVjdC5ib3R0b20pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIk5vLCBkZXN0IHJlY3RhbmdsZSBkb2Vzbid0IG1hdGNoKGNsaXBwZXIpXG4iKTsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiQ2xpcCByZWN0IGF0ICglZCwlZCktKCVkLCVkKVxuIiwgY2xpcHJlY3QubGVmdCwgY2xpcHJlY3QudG9wLCBjbGlwcmVjdC5yaWdodCwgY2xpcHJlY3QuYm90dG9tKTsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiQmx0IGRlc3Q6ICglZCwlZCktKCVkLCVkKVxuIiwgcmVjdC54MSwgcmVjdC55MSwgcmVjdC54MiwgcmVjdC55Mik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZihyZWN0LngxICE9IDAgfHwgcmVjdC55MSAhPSAwIHx8CiAgICAgICAgICAgICAgICAgICByZWN0LngyICE9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoIHx8IHJlY3QueTIgIT0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KSB7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIk5vLCBkZXN0IHJlY3RhbmdsZSBkb2Vzbid0IG1hdGNoKHN1cmZhY2Ugc2l6ZSlcbiIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBUUkFDRSgiWWVzXG4iKTsKCiAgICAgICAgICAgIC8qIFRoZXNlIGZsYWdzIGFyZSB1bmltcG9ydGFudCBmb3IgdGhlIGZsYWcgY2hlY2ssIHJlbW92ZSB0aGVtICovCiAgICAgICAgICAgIGlmKChGbGFncyAmIH4oV0lORUREQkxUX0RPTk9UV0FJVCB8IFdJTkVEREJMVF9XQUlUKSkgPT0gMCkgewogICAgICAgICAgICAgICAgV0lORUQzRFNXQVBFRkZFQ1Qgb3JpZ19zd2FwID0gZHN0U3dhcGNoYWluLT5wcmVzZW50UGFybXMuU3dhcEVmZmVjdDsKCiAgICAgICAgICAgICAgICAvKiBUaGUgaWRlYSBiZWhpbmQgdGhpcyBpcyB0aGF0IGEgZ2xSZWFkUGl4ZWxzIGFuZCBhIGdsRHJhd1BpeGVscyBjYWxsCiAgICAgICAgICAgICAgICAgICAgKiB0YWtlIHZlcnkgbG9uZywgd2hpbGUgYSBmbGlwIGlzIGZhc3QuCiAgICAgICAgICAgICAgICAgICAgKiBUaGlzIGFwcGxpZXMgdG8gSGFsZi1MaWZlLCB3aGljaCBkb2VzIHN1Y2ggQmx0cyBldmVyeSB0aW1lIGl0IGZpbmlzaGVkCiAgICAgICAgICAgICAgICAgICAgKiBhIGZyYW1lLCBhbmQgdG8gUHJpbmNlIG9mIFBlcnNpYSAzRCwgd2hpY2ggdXNlcyB0aGlzIHRvIGRyYXcgYXQgbGVhc3QgdGhlIG1haW4KICAgICAgICAgICAgICAgICAgICAqIG1lbnUuIFRoaXMgaXMgYWxzbyB1c2VkIGJ5IGFsbCBhcHBzIHdoZW4gdGhleSBkbyB3aW5kb3dlZCByZW5kZXJpbmcKICAgICAgICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICAgICAgKiBUaGUgcHJvYmxlbSBpcyB0aGF0IGZsaXBwaW5nIGlzIG5vdCByZWFsbHkgdGhlIHNhbWUgYXMgY29weWluZy4gQWZ0ZXIgYQogICAgICAgICAgICAgICAgICAgICogQmx0IHRoZSBmcm9udCBidWZmZXIgaXMgYSBjb3B5IG9mIHRoZSBiYWNrIGJ1ZmZlciwgYW5kIHRoZSBiYWNrIGJ1ZmZlciBpcwogICAgICAgICAgICAgICAgICAgICogdW50b3VjaGVkLiBUaGVyZWZvcmUgaXQncyBuZWNlc3NhcnkgdG8gb3ZlcnJpZGUgdGhlIHN3YXAgZWZmZWN0CiAgICAgICAgICAgICAgICAgICAgKiBhbmQgdG8gc2V0IGl0IGJhY2sgYWZ0ZXIgdGhlIGZsaXAuCiAgICAgICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAgICAgICogV2luZG93ZWQgRGlyZWN0M0QgPCA3IGFwcHMgZG8gdGhlIHNhbWUuIFRoZSBEM0Q3IHNkayBkZW1vcyBhcmUgbmljZQogICAgICAgICAgICAgICAgICAgICogdGVzdGNhc2VzLgogICAgICAgICAgICAgICAgICAgICovCgogICAgICAgICAgICAgICAgZHN0U3dhcGNoYWluLT5wcmVzZW50UGFybXMuU3dhcEVmZmVjdCA9IFdJTkVEM0RTV0FQRUZGRUNUX0NPUFk7CiAgICAgICAgICAgICAgICBkc3RTd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5QcmVzZW50YXRpb25JbnRlcnZhbCA9IFdJTkVEM0RQUkVTRU5UX0lOVEVSVkFMX0lNTUVESUFURTsKCiAgICAgICAgICAgICAgICBUUkFDRSgiRnVsbCBzY3JlZW4gYmFjayBidWZmZXIgLT4gZnJvbnQgYnVmZmVyIGJsdCwgcGVyZm9ybWluZyBhIGZsaXAgaW5zdGVhZFxuIik7CiAgICAgICAgICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9QcmVzZW50KChJV2luZUQzRFN3YXBDaGFpbiAqKSBkc3RTd2FwY2hhaW4sIE5VTEwsIE5VTEwsIDAsIE5VTEwsIDApOwoKICAgICAgICAgICAgICAgIGRzdFN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLlN3YXBFZmZlY3QgPSBvcmlnX3N3YXA7CgogICAgICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBUUkFDRSgiVW5zdXBwb3J0ZWQgYmxpdCBiZXR3ZWVuIGJ1ZmZlcnMgb24gdGhlIHNhbWUgc3dhcGNoYWluXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0gZWxzZSBpZigoZHN0U3dhcGNoYWluIHx8IFRoaXMgPT0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgbXlEZXZpY2UtPnJlbmRlcl90YXJnZXRzWzBdKSAmJgogICAgICAgICAgICAgIChzcmNTd2FwY2hhaW4gfHwgU3JjU3VyZmFjZSA9PSBteURldmljZS0+cmVuZGVyX3RhcmdldHNbMF0pICkgewogICAgICAgIEVSUigiQ2FuJ3QgcGVyZm9ybSBoYXJkd2FyZSBibGl0IGJldHdlZW4gMiBkaWZmZXJlbnQgc3dhcGNoYWlucywgZmFsbGluZyBiYWNrIHRvIHNvZnR3YXJlXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBpZihzcmNTd2FwY2hhaW4gfHwgU3JjU3VyZmFjZSA9PSBteURldmljZS0+cmVuZGVyX3RhcmdldHNbMF0pIHsKICAgICAgICAvKiBCbGl0IGZyb20gcmVuZGVyIHRhcmdldCB0byB0ZXh0dXJlICovCiAgICAgICAgV0lORUQzRFJFQ1Qgc3JlY3Q7CiAgICAgICAgQk9PTCB1cHNpZGVEb3duLCBzdHJldGNoeDsKCiAgICAgICAgaWYoRmxhZ3MgJiAoV0lORUREQkxUX0tFWVNSQyB8IFdJTkVEREJMVF9LRVlTUkNPVkVSUklERSkpIHsKICAgICAgICAgICAgVFJBQ0UoIkNvbG9yIGtleWluZyBub3Qgc3VwcG9ydGVkIGJ5IGZyYW1lIGJ1ZmZlciB0byB0ZXh0dXJlIGJsaXRcbiIpOwogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICAgICAgLyogRGVzdGluYXRpb24gY29sb3Iga2V5IGlzIGNoZWNrZWQgYWJvdmUgKi8KICAgICAgICB9CgogICAgICAgIC8qIE1ha2Ugc3VyZSB0aGF0IHRoZSB0b3AgcGl4ZWwgaXMgYWx3YXlzIGFib3ZlIHRoZSBib3R0b20gcGl4ZWwsIGFuZCBrZWVwIGEgc2VwYXJhdGUgdXBzaWRlIGRvd24gZmxhZwogICAgICAgICAqIGdsQ29weVRleFN1YkltYWdlIGlzIGEgYml0IHBpY2t5IGFib3V0IHRoZSBwYXJhbWV0ZXJzIHdlIHBhc3MgdG8gaXQKICAgICAgICAgKi8KICAgICAgICBpZihTcmNSZWN0KSB7CiAgICAgICAgICAgIGlmKFNyY1JlY3QtPnRvcCA8IFNyY1JlY3QtPmJvdHRvbSkgewogICAgICAgICAgICAgICAgc3JlY3QueTEgPSBTcmNSZWN0LT50b3A7CiAgICAgICAgICAgICAgICBzcmVjdC55MiA9IFNyY1JlY3QtPmJvdHRvbTsKICAgICAgICAgICAgICAgIHVwc2lkZURvd24gPSBGQUxTRTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNyZWN0LnkxID0gU3JjUmVjdC0+Ym90dG9tOwogICAgICAgICAgICAgICAgc3JlY3QueTIgPSBTcmNSZWN0LT50b3A7CiAgICAgICAgICAgICAgICB1cHNpZGVEb3duID0gVFJVRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzcmVjdC54MSA9IFNyY1JlY3QtPmxlZnQ7CiAgICAgICAgICAgIHNyZWN0LngyID0gU3JjUmVjdC0+cmlnaHQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3JlY3QueDEgPSAwOwogICAgICAgICAgICBzcmVjdC55MSA9IDA7CiAgICAgICAgICAgIHNyZWN0LngyID0gU3JjLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICAgICAgc3JlY3QueTIgPSBTcmMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICAgICAgdXBzaWRlRG93biA9IEZBTFNFOwogICAgICAgIH0KICAgICAgICBpZihyZWN0LngxID4gcmVjdC54MikgewogICAgICAgICAgICBVSU5UIHRtcCA9IHJlY3QueDI7CiAgICAgICAgICAgIHJlY3QueDIgPSByZWN0LngxOwogICAgICAgICAgICByZWN0LngxID0gdG1wOwogICAgICAgICAgICB1cHNpZGVEb3duID0gIXVwc2lkZURvd247CiAgICAgICAgfQogICAgICAgIGlmKCFzcmNTd2FwY2hhaW4pIHsKICAgICAgICAgICAgVFJBQ0UoIlJlYWRpbmcgZnJvbSBhbiBvZmZzY3JlZW4gdGFyZ2V0XG4iKTsKICAgICAgICAgICAgdXBzaWRlRG93biA9ICF1cHNpZGVEb3duOwogICAgICAgIH0KCiAgICAgICAgaWYocmVjdC54MiAtIHJlY3QueDEgIT0gc3JlY3QueDIgLSBzcmVjdC54MSkgewogICAgICAgICAgICBzdHJldGNoeCA9IFRSVUU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3RyZXRjaHggPSBGQUxTRTsKICAgICAgICB9CgogICAgICAgIC8qIEJsdCBpcyBhIHByZXR0eSBwb3dlcmZ1bCBjYWxsLCB3aGlsZSBnbENvcHlUZXhTdWJJbWFnZTJEIGlzIG5vdC4gZ2xDb3B5VGV4U3ViSW1hZ2UgY2Fubm90CiAgICAgICAgICogZmxpcCB0aGUgaW1hZ2Ugbm9yIHNjYWxlIGl0LgogICAgICAgICAqCiAgICAgICAgICogLT4gSWYgdGhlIGFwcCBhc2tzIGZvciBhIHVuc2NhbGVkLCB1cHNpZGUgZG93biBjb3B5LCBqdXN0IHBlcmZvcm0gb25lIGdsQ29weVRleFN1YkltYWdlMkQgY2FsbAogICAgICAgICAqIC0+IElmIHRoZSBhcHAgd2FudHMgYSBpbWFnZSB3aWR0aCBhbiB1bnNjYWxlZCB3aWR0aCwgY29weSBpdCBsaW5lIHBlciBsaW5lCiAgICAgICAgICogLT4gSWYgdGhlIGFwcCB3YW50cyBhIGltYWdlIHRoYXQgaXMgc2NhbGVkIG9uIHRoZSB4IGF4aXMsIGFuZCB0aGUgZGVzdGluYXRpb24gcmVjdGFuZ2xlIGlzIHNtYWxsZXIKICAgICAgICAgKiAgICB0aGFuIHRoZSBmcmFtZSBidWZmZXIsIGRyYXcgYW4gdXBzaWRlIGRvd24gc2NhbGVkIGltYWdlIG9udG8gdGhlIGZiLCByZWFkIGl0IGJhY2sgYW5kIHJlc3RvcmUgdGhlCiAgICAgICAgICogICAgYmFjayBidWZmZXIuIFRoaXMgaXMgc2xvd2VyIHRoYW4gcmVhZGluZyBsaW5lIHBlciBsaW5lLCB0aHVzIG5vdCB1c2VkIGZvciBmbGlwcGluZwogICAgICAgICAqIC0+IElmIHRoZSBhcHAgd2FudHMgYSBzY2FsZWQgaW1hZ2Ugd2l0aCBhIGRlc3QgcmVjdCB0aGF0IGlzIGJpZ2dlciB0aGFuIHRoZSBmYiwgaXQgaGFzIHRvIGJlIGNvcGllZAogICAgICAgICAqICAgIHBpeGVsIGJ5IHBpeGVsCiAgICAgICAgICoKICAgICAgICAgKiBJZiBFWFRfZnJhbWVidWZmZXJfYmxpdCBpcyBzdXBwb3J0ZWQgdGhhdCBjYW4gYmUgdXNlZCBpbnN0ZWFkLiBOb3RlIHRoYXQgRVhUX2ZyYW1lYnVmZmVyX2JsaXQgaW1wbGllcwogICAgICAgICAqIEZCTyBzdXBwb3J0LCBzbyBpdCBkb2Vzbid0IHJlYWxseSBtYWtlIHNlbnNlIHRvIHRyeSBhbmQgbWFrZSBpdCB3b3JrIHdpdGggZGlmZmVyZW50IG9mZnNjcmVlbiByZW5kZXJpbmcKICAgICAgICAgKiBiYWNrZW5kcy4KICAgICAgICAgKi8KICAgICAgICBpZiAod2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUgPT0gT1JNX0ZCTyAmJiBHTF9TVVBQT1JUKEVYVF9GUkFNRUJVRkZFUl9CTElUKSkgewogICAgICAgICAgICBzdHJldGNoX3JlY3RfZmJvKChJV2luZUQzRERldmljZSAqKW15RGV2aWNlLCBTcmNTdXJmYWNlLCAmc3JlY3QsCiAgICAgICAgICAgICAgICAgICAgKElXaW5lRDNEU3VyZmFjZSAqKVRoaXMsICZyZWN0LCBGaWx0ZXIsIHVwc2lkZURvd24pOwogICAgICAgIH0gZWxzZSBpZigoIXN0cmV0Y2h4KSB8fCByZWN0LngyIC0gcmVjdC54MSA+IFNyYy0+Y3VycmVudERlc2MuV2lkdGggfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjdC55MiAtIHJlY3QueTEgPiBTcmMtPmN1cnJlbnREZXNjLkhlaWdodCkgewogICAgICAgICAgICBUUkFDRSgiTm8gc3RyZXRjaGluZyBpbiB4IGRpcmVjdGlvbiwgdXNpbmcgZGlyZWN0IGZyYW1lYnVmZmVyIC0+IHRleHR1cmUgY29weVxuIik7CiAgICAgICAgICAgIGZiX2NvcHlfdG9fdGV4dHVyZV9kaXJlY3QoVGhpcywgU3JjU3VyZmFjZSwgc3JjU3dhcGNoYWluLCAmc3JlY3QsICZyZWN0LCB1cHNpZGVEb3duLCBGaWx0ZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFRSQUNFKCJVc2luZyBoYXJkd2FyZSBzdHJldGNoaW5nIHRvIGZsaXAgLyBzdHJldGNoIHRoZSB0ZXh0dXJlXG4iKTsKICAgICAgICAgICAgZmJfY29weV90b190ZXh0dXJlX2h3c3RyZXRjaChUaGlzLCBTcmNTdXJmYWNlLCBzcmNTd2FwY2hhaW4sICZzcmVjdCwgJnJlY3QsIHVwc2lkZURvd24sIEZpbHRlcik7CiAgICAgICAgfQoKICAgICAgICBpZighKFRoaXMtPkZsYWdzICYgU0ZMQUdfRE9OT1RGUkVFKSkgewogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5yZXNvdXJjZS5oZWFwTWVtb3J5KTsKICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gTlVMTDsKICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuaGVhcE1lbW9yeSA9IE5VTEw7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0lOU1lTTUVNOwogICAgICAgIH0KICAgICAgICAvKiBUaGUgdGV4dHVyZSBpcyBub3cgbW9zdCB1cCB0byBkYXRlIC0gSWYgdGhlIHN1cmZhY2UgaXMgYSByZW5kZXIgdGFyZ2V0IGFuZCBoYXMgYSBkcmF3YWJsZSwgdGhpcwogICAgICAgICAqIHBhdGggaXMgbmV2ZXIgZW50ZXJlZAogICAgICAgICAqLwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9Nb2RpZnlMb2NhdGlvbigoSVdpbmVEM0RTdXJmYWNlICopIFRoaXMsIFNGTEFHX0lOVEVYVFVSRSwgVFJVRSk7CgogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfSBlbHNlIGlmKFNyYykgewogICAgICAgIC8qIEJsaXQgZnJvbSBvZmZzY3JlZW4gc3VyZmFjZSB0byByZW5kZXIgdGFyZ2V0ICovCiAgICAgICAgZmxvYXQgZ2xUZXhDb29yZFs0XTsKICAgICAgICBEV09SRCBvbGRDS2V5RmxhZ3MgPSBTcmMtPkNLZXlGbGFnczsKICAgICAgICBXSU5FRERDT0xPUktFWSBvbGRCbHRDS2V5ID0gVGhpcy0+U3JjQmx0Q0tleTsKICAgICAgICBSRUNUIFNvdXJjZVJlY3RhbmdsZTsKCiAgICAgICAgVFJBQ0UoIkJsdCBmcm9tIHN1cmZhY2UgJXAgdG8gcmVuZGVydGFyZ2V0ICVwXG4iLCBTcmMsIFRoaXMpOwoKICAgICAgICBpZihTcmNSZWN0KSB7CiAgICAgICAgICAgIFNvdXJjZVJlY3RhbmdsZS5sZWZ0ID0gU3JjUmVjdC0+bGVmdDsKICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLnJpZ2h0ID0gU3JjUmVjdC0+cmlnaHQ7CiAgICAgICAgICAgIFNvdXJjZVJlY3RhbmdsZS50b3AgPSBTcmNSZWN0LT50b3A7CiAgICAgICAgICAgIFNvdXJjZVJlY3RhbmdsZS5ib3R0b20gPSBTcmNSZWN0LT5ib3R0b207CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLmxlZnQgPSAwOwogICAgICAgICAgICBTb3VyY2VSZWN0YW5nbGUucmlnaHQgPSBTcmMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgICAgICBTb3VyY2VSZWN0YW5nbGUudG9wID0gMDsKICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLmJvdHRvbSA9IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgICAgIH0KCiAgICAgICAgaWYoIUNhbGN1bGF0ZVRleFJlY3QoU3JjLCAmU291cmNlUmVjdGFuZ2xlLCBnbFRleENvb3JkKSkgewogICAgICAgICAgICAvKiBGYWxsIGJhY2sgdG8gc29mdHdhcmUgKi8KICAgICAgICAgICAgV0FSTigiKCVwKSBTb3VyY2UgdGV4dHVyZSBhcmVhICglZCwlZCktKCVkLCVkKSBpcyB0b28gYmlnXG4iLCBTcmMsCiAgICAgICAgICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLmxlZnQsIFNvdXJjZVJlY3RhbmdsZS50b3AsCiAgICAgICAgICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLnJpZ2h0LCBTb3VyY2VSZWN0YW5nbGUuYm90dG9tKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfQoKICAgICAgICAvKiBDb2xvciBrZXlpbmc6IENoZWNrIGlmIHdlIGhhdmUgdG8gZG8gYSBjb2xvciBrZXllZCBibHQsCiAgICAgICAgICogYW5kIGlmIG5vdCBjaGVjayBpZiBhIGNvbG9yIGtleSBpcyBhY3RpdmF0ZWQuCiAgICAgICAgICoKICAgICAgICAgKiBKdXN0IG1vZGlmeSB0aGUgY29sb3Iga2V5aW5nIHBhcmFtZXRlcnMgaW4gdGhlIHN1cmZhY2UgYW5kIHJlc3RvcmUgdGhlbSBhZnRlcndhcmRzCiAgICAgICAgICogVGhlIHN1cmZhY2Uga2VlcHMgdHJhY2sgb2YgdGhlIGNvbG9yIGtleSBsYXN0IHVzZWQgdG8gbG9hZCB0aGUgb3BlbmdsIHN1cmZhY2UuCiAgICAgICAgICogUHJlTG9hZCB3aWxsIGNhdGNoIHRoZSBjaGFuZ2UgdG8gdGhlIGZsYWdzIGFuZCBjb2xvciBrZXkgYW5kIHJlbG9hZCBpZiBuZWNlc3NhcnkuCiAgICAgICAgICovCiAgICAgICAgaWYoRmxhZ3MgJiBXSU5FRERCTFRfS0VZU1JDKSB7CiAgICAgICAgICAgIC8qIFVzZSBjb2xvciBrZXkgZnJvbSBzdXJmYWNlICovCiAgICAgICAgfSBlbHNlIGlmKEZsYWdzICYgV0lORUREQkxUX0tFWVNSQ09WRVJSSURFKSB7CiAgICAgICAgICAgIC8qIFVzZSBjb2xvciBrZXkgZnJvbSBEREJsdEZ4ICovCiAgICAgICAgICAgIFNyYy0+Q0tleUZsYWdzIHw9IFdJTkVERFNEX0NLU1JDQkxUOwogICAgICAgICAgICBUaGlzLT5TcmNCbHRDS2V5ID0gRERCbHRGeC0+ZGRja1NyY0NvbG9ya2V5OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8qIERvIG5vdCB1c2UgY29sb3Iga2V5ICovCiAgICAgICAgICAgIFNyYy0+Q0tleUZsYWdzICY9IH5XSU5FRERTRF9DS1NSQ0JMVDsKICAgICAgICB9CgogICAgICAgIC8qIE5vdyBsb2FkIHRoZSBzdXJmYWNlICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1ByZUxvYWQoKElXaW5lRDNEU3VyZmFjZSAqKSBTcmMpOwoKCiAgICAgICAgLyogQWN0aXZhdGUgdGhlIGRlc3RpbmF0aW9uIGNvbnRleHQsIHNldCBpdCB1cCBmb3IgYmxpdHRpbmcgKi8KICAgICAgICBBY3RpdmF0ZUNvbnRleHQobXlEZXZpY2UsIChJV2luZUQzRFN1cmZhY2UgKikgVGhpcywgQ1RYVVNBR0VfQkxJVCk7CiAgICAgICAgRU5URVJfR0woKTsKCiAgICAgICAgZ2xFbmFibGUoU3JjLT5nbERlc2NyaXB0aW9uLnRhcmdldCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlKFNyYy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQpIik7CgogICAgICAgIGlmKCFkc3RTd2FwY2hhaW4pIHsKICAgICAgICAgICAgVFJBQ0UoIkRyYXdpbmcgdG8gb2Zmc2NyZWVuIGJ1ZmZlclxuIik7CiAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihteURldmljZS0+b2Zmc2NyZWVuQnVmZmVyKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlciIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIEdMZW51bSBidWZmZXIgPSBzdXJmYWNlX2dldF9nbF9idWZmZXIoKElXaW5lRDNEU3VyZmFjZSAqKVRoaXMsIChJV2luZUQzRFN3YXBDaGFpbiAqKWRzdFN3YXBjaGFpbik7CiAgICAgICAgICAgIFRSQUNFKCJEcmF3aW5nIHRvICUjeCBidWZmZXJcbiIsIGJ1ZmZlcik7CiAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihidWZmZXIpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyIik7CiAgICAgICAgfQoKICAgICAgICAvKiBCaW5kIHRoZSB0ZXh0dXJlICovCiAgICAgICAgZ2xCaW5kVGV4dHVyZShTcmMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBTcmMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRUZXh0dXJlIik7CgogICAgICAgIC8qIEZpbHRlcmluZyBmb3IgU3RyZXRjaFJlY3QgKi8KICAgICAgICBnbFRleFBhcmFtZXRlcmkoU3JjLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgR0xfVEVYVFVSRV9NQUdfRklMVEVSLAogICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZUxvb2t1cFtXSU5FTE9PS1VQX01BR0ZJTFRFUl1bRmlsdGVyIC0gbWluTG9va3VwW1dJTkVMT09LVVBfTUFHRklMVEVSXV0pOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleFBhcmFtZXRlcmkiKTsKICAgICAgICBnbFRleFBhcmFtZXRlcmkoU3JjLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgR0xfVEVYVFVSRV9NSU5fRklMVEVSLAogICAgICAgICAgICAgICAgICAgICAgICBtaW5NaXBMb29rdXBbRmlsdGVyXVtXSU5FRDNEVEVYRl9OT05FXSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4UGFyYW1ldGVyaSIpOwogICAgICAgIGdsVGV4UGFyYW1ldGVyaShTcmMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBHTF9URVhUVVJFX1dSQVBfUywgR0xfQ0xBTVApOwogICAgICAgIGdsVGV4UGFyYW1ldGVyaShTcmMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBHTF9URVhUVVJFX1dSQVBfVCwgR0xfQ0xBTVApOwogICAgICAgIGdsVGV4RW52aShHTF9URVhUVVJFX0VOViwgR0xfVEVYVFVSRV9FTlZfTU9ERSwgR0xfUkVQTEFDRSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4RW52aSIpOwoKICAgICAgICAvKiBUaGlzIGlzIGZvciBjb2xvciBrZXlpbmcgKi8KICAgICAgICBpZihGbGFncyAmIChXSU5FRERCTFRfS0VZU1JDIHwgV0lORUREQkxUX0tFWVNSQ09WRVJSSURFKSkgewogICAgICAgICAgICBnbEVuYWJsZShHTF9BTFBIQV9URVNUKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIEdMX0FMUEhBX1RFU1QiKTsKICAgICAgICAgICAgZ2xBbHBoYUZ1bmMoR0xfTk9URVFVQUwsIDAuMCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEFscGhhRnVuY1xuIik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX0FMUEhBX1RFU1QpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX0FMUEhBX1RFU1QiKTsKICAgICAgICB9CgogICAgICAgIC8qIERyYXcgYSB0ZXh0dXJlZCBxdWFkCiAgICAgICAgICovCiAgICAgICAgZ2xCZWdpbihHTF9RVUFEUyk7CgogICAgICAgIGdsQ29sb3IzZCgxLjBmLCAxLjBmLCAxLjBmKTsKICAgICAgICBnbFRleENvb3JkMmYoZ2xUZXhDb29yZFswXSwgZ2xUZXhDb29yZFsyXSk7CiAgICAgICAgZ2xWZXJ0ZXgzZihyZWN0LngxLAogICAgICAgICAgICAgICAgICAgIHJlY3QueTEsCiAgICAgICAgICAgICAgICAgICAgMC4wKTsKCiAgICAgICAgZ2xUZXhDb29yZDJmKGdsVGV4Q29vcmRbMF0sIGdsVGV4Q29vcmRbM10pOwogICAgICAgIGdsVmVydGV4M2YocmVjdC54MSwgcmVjdC55MiwgMC4wKTsKCiAgICAgICAgZ2xUZXhDb29yZDJmKGdsVGV4Q29vcmRbMV0sIGdsVGV4Q29vcmRbM10pOwogICAgICAgIGdsVmVydGV4M2YocmVjdC54MiwKICAgICAgICAgICAgICAgICAgICByZWN0LnkyLAogICAgICAgICAgICAgICAgICAgIDAuMCk7CgogICAgICAgIGdsVGV4Q29vcmQyZihnbFRleENvb3JkWzFdLCBnbFRleENvb3JkWzJdKTsKICAgICAgICBnbFZlcnRleDNmKHJlY3QueDIsCiAgICAgICAgICAgICAgICAgICAgcmVjdC55MSwKICAgICAgICAgICAgICAgICAgICAwLjApOwogICAgICAgIGdsRW5kKCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5kIik7CgogICAgICAgIGlmKEZsYWdzICYgKFdJTkVEREJMVF9LRVlTUkMgfCBXSU5FRERCTFRfS0VZU1JDT1ZFUlJJREUpKSB7CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9BTFBIQV9URVNUKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShHTF9BTFBIQV9URVNUKSIpOwogICAgICAgIH0KCiAgICAgICAgLyogRmx1c2ggaW4gY2FzZSB0aGUgZHJhd2FibGUgaXMgdXNlZCBieSBtdWx0aXBsZSBHTCBjb250ZXh0cyAqLwogICAgICAgIGlmKGRzdFN3YXBjaGFpbiAmJiAoZHN0U3dhcGNoYWluLT5udW1fY29udGV4dHMgPj0gMikpCiAgICAgICAgICAgIGdsRmx1c2goKTsKCiAgICAgICAgZ2xCaW5kVGV4dHVyZShTcmMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCAwKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kVGV4dHVyZShTcmMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCAwKSIpOwogICAgICAgIC8qIExlYXZlIHRoZSBvcGVuZ2wgc3RhdGUgdmFsaWQgZm9yIGJsaXR0aW5nICovCiAgICAgICAgZ2xEaXNhYmxlKFNyYy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUoU3JjLT5nbERlc2NyaXB0aW9uLnRhcmdldCkiKTsKCiAgICAgICAgLyogVGhlIGRyYXcgYnVmZmVyIHNob3VsZCBvbmx5IG5lZWQgdG8gYmUgcmVzdG9yZWQgaWYgd2Ugd2VyZSBkcmF3aW5nIHRvIHRoZSBmcm9udCBidWZmZXIsIGFuZCB0aGVyZSBpcyBhIGJhY2sgYnVmZmVyLgogICAgICAgICAqIG90aGVyd2lzZSB0aGUgY29udGV4dCBtYW5hZ2VyIHNob3VsZCBjaG9vc2UgYmV0d2VlbiBHTF9CQUNLIC8gb2Zmc2NyZWVuRHJhd0J1ZmZlcgogICAgICAgICAqLwogICAgICAgIGlmKGRzdFN3YXBjaGFpbiAmJiBUaGlzID09IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGRzdFN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIgJiYgZHN0U3dhcGNoYWluLT5iYWNrQnVmZmVyKSB7CiAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlciIpOwogICAgICAgIH0KICAgICAgICAvKiBSZXN0b3JlIHRoZSBjb2xvciBrZXkgcGFyYW1ldGVycyAqLwogICAgICAgIFNyYy0+Q0tleUZsYWdzID0gb2xkQ0tleUZsYWdzOwogICAgICAgIFRoaXMtPlNyY0JsdENLZXkgPSBvbGRCbHRDS2V5OwoKICAgICAgICBMRUFWRV9HTCgpOwoKICAgICAgICAvKiBUT0RPOiBJZiB0aGUgc3VyZmFjZSBpcyBsb2NrZWQgb2Z0ZW4sIHBlcmZvcm0gdGhlIEJsdCBpbiBzb2Z0d2FyZSBvbiB0aGUgbWVtb3J5IGluc3RlYWQgKi8KICAgICAgICAvKiBUaGUgc3VyZmFjZSBpcyBub3cgaW4gdGhlIGRyYXdhYmxlLiBPbiBvbnNjcmVlbiBzdXJmYWNlcyBvciB3aXRob3V0IGZib3MgdGhlIHRleHR1cmUKICAgICAgICAgKiBpcyBvdXRkYXRlZCBub3cKICAgICAgICAgKi8KICAgICAgICBJV2luZUQzRFN1cmZhY2VfTW9kaWZ5TG9jYXRpb24oKElXaW5lRDNEU3VyZmFjZSAqKSBUaGlzLCBTRkxBR19JTkRSQVdBQkxFLCBUUlVFKTsKICAgICAgICAvKiBUT0RPOiBUaGlzIHNob3VsZCBiZSBtb3ZlZCB0byBNb2RpZnlMb2NhdGlvbigpICovCiAgICAgICAgaWYoIShkc3RTd2FwY2hhaW4gfHwgd2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUgIT0gT1JNX0ZCTykpIHsKICAgICAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfSU5URVhUVVJFOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9IGVsc2UgewogICAgICAgIC8qIFNvdXJjZS1MZXNzIEJsaXQgdG8gcmVuZGVyIHRhcmdldCAqLwogICAgICAgIGlmIChGbGFncyAmIFdJTkVEREJMVF9DT0xPUkZJTEwpIHsKICAgICAgICAgICAgLyogVGhpcyBpcyBlYXN5IHRvIGhhbmRsZSBmb3IgdGhlIEQzRCBEZXZpY2UuLi4gKi8KICAgICAgICAgICAgRFdPUkQgY29sb3I7CgogICAgICAgICAgICBUUkFDRSgiQ29sb3JmaWxsXG4iKTsKCiAgICAgICAgICAgIC8qIFRoZSBjb2xvciBhcyBnaXZlbiBpbiB0aGUgQmx0IGZ1bmN0aW9uIGlzIGluIHRoZSBmb3JtYXQgb2YgdGhlIGZyYW1lLWJ1ZmZlci4uLgogICAgICAgICAgICAgKiAnY2xlYXInIGV4cGVjdCBpdCBpbiBBUkdCIGZvcm1hdCA9PiB3ZSBuZWVkIHRvIGRvIHNvbWUgY29udmVyc2lvbiA6LSkKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9QOCkgewogICAgICAgICAgICAgICAgaWYgKFRoaXMtPnBhbGV0dGUpIHsKICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICgoMHhGRjAwMDAwMCkgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKFRoaXMtPnBhbGV0dGUtPnBhbGVudHNbRERCbHRGeC0+dTUuZHdGaWxsQ29sb3JdLnBlUmVkIDw8IDE2KSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoVGhpcy0+cGFsZXR0ZS0+cGFsZW50c1tEREJsdEZ4LT51NS5kd0ZpbGxDb2xvcl0ucGVHcmVlbiA8PCA4KSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoVGhpcy0+cGFsZXR0ZS0+cGFsZW50c1tEREJsdEZ4LT51NS5kd0ZpbGxDb2xvcl0ucGVCbHVlKSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGNvbG9yID0gMHhGRjAwMDAwMDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9SNUc2QjUpIHsKICAgICAgICAgICAgICAgIGlmIChEREJsdEZ4LT51NS5kd0ZpbGxDb2xvciA9PSAweEZGRkYpIHsKICAgICAgICAgICAgICAgICAgICBjb2xvciA9IDB4RkZGRkZGRkY7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGNvbG9yID0gKCgweEZGMDAwMDAwKSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKEREQmx0RngtPnU1LmR3RmlsbENvbG9yICYgMHhGODAwKSA8PCA4KSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKEREQmx0RngtPnU1LmR3RmlsbENvbG9yICYgMHgwN0UwKSA8PCA1KSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKEREQmx0RngtPnU1LmR3RmlsbENvbG9yICYgMHgwMDFGKSA8PCAzKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX1I4RzhCOCkgfHwKICAgICAgICAgICAgICAgICAgICAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfWDhSOEc4QjgpICkgewogICAgICAgICAgICAgICAgY29sb3IgPSAweEZGMDAwMDAwIHwgRERCbHRGeC0+dTUuZHdGaWxsQ29sb3I7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfQThSOEc4QjgpIHsKICAgICAgICAgICAgICAgIGNvbG9yID0gRERCbHRGeC0+dTUuZHdGaWxsQ29sb3I7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBFUlIoIldyb25nIHN1cmZhY2UgdHlwZSBmb3IgQkxUIG92ZXJyaWRlKEZvcm1hdCBkb2Vzbid0IG1hdGNoKSAhXG4iKTsKICAgICAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgICAgICB9CgogICAgICAgICAgICBBY3RpdmF0ZUNvbnRleHQobXlEZXZpY2UsIChJV2luZUQzRFN1cmZhY2UgKikgVGhpcywgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKICAgICAgICAgICAgRU5URVJfR0woKTsKCiAgICAgICAgICAgIFRSQUNFKCJDYWxsaW5nIEdldFN3YXBDaGFpbiB3aXRoIG15ZGV2aWNlID0gJXBcbiIsIG15RGV2aWNlKTsKICAgICAgICAgICAgaWYoZHN0U3dhcGNoYWluICYmIGRzdFN3YXBjaGFpbi0+YmFja0J1ZmZlciAmJiBUaGlzID09IChJV2luZUQzRFN1cmZhY2VJbXBsKikgZHN0U3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdKSB7CiAgICAgICAgICAgICAgICBnbERyYXdCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKEdMX0JBQ0spIik7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoZHN0U3dhcGNoYWluICYmIFRoaXMgPT0gKElXaW5lRDNEU3VyZmFjZUltcGwqKSBkc3RTd2FwY2hhaW4tPmZyb250QnVmZmVyKSB7CiAgICAgICAgICAgICAgICBnbERyYXdCdWZmZXIoR0xfRlJPTlQpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcihHTF9GUk9OVCkiKTsKICAgICAgICAgICAgfSBlbHNlIGlmKFRoaXMgPT0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgbXlEZXZpY2UtPnJlbmRlcl90YXJnZXRzWzBdKSB7CiAgICAgICAgICAgICAgICBnbERyYXdCdWZmZXIobXlEZXZpY2UtPm9mZnNjcmVlbkJ1ZmZlcik7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKG15RGV2aWNlLT5vZmZzY3JlZW5CdWZmZXIzKSIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICAgICAgICAgIFRSQUNFKCJTdXJmYWNlIGlzIGhpZ2hlciBiYWNrIGJ1ZmZlciwgZmFsbGluZyBiYWNrIHRvIHNvZnR3YXJlXG4iKTsKICAgICAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgICAgICB9CgogICAgICAgICAgICBUUkFDRSgiKCVwKSBleGVjdXRpbmcgUmVuZGVyIFRhcmdldCBvdmVycmlkZSwgY29sb3IgPSAleFxuIiwgVGhpcywgY29sb3IpOwoKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfQ2xlYXIoIChJV2luZUQzRERldmljZSAqKSBteURldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxIC8qIE51bWJlciBvZiByZWN0YW5nbGVzICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZyZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RDTEVBUl9UQVJHRVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMC4wIC8qIFogKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKiBTdGVuY2lsICovKTsKCiAgICAgICAgICAgIC8qIFJlc3RvcmUgdGhlIG9yaWdpbmFsIGRyYXcgYnVmZmVyICovCiAgICAgICAgICAgIGlmKCFkc3RTd2FwY2hhaW4pIHsKICAgICAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihteURldmljZS0+b2Zmc2NyZWVuQnVmZmVyKTsKICAgICAgICAgICAgfSBlbHNlIGlmKGRzdFN3YXBjaGFpbi0+YmFja0J1ZmZlciAmJiBkc3RTd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0pIHsKICAgICAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgfQogICAgICAgICAgICB2Y2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlciIpOwogICAgICAgICAgICBMRUFWRV9HTCgpOwoKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICAgICAgfQogICAgfQoKICAgIC8qIERlZmF1bHQ6IEZhbGwgYmFjayB0byB0aGUgZ2VuZXJpYyBibHQuIE5vdCBhbiBlcnJvciwgYSBUUkFDRSBpcyBlbm91Z2ggKi8KICAgIFRSQUNFKCJEaWRuJ3QgZmluZCBhbnkgdXNhYmxlIHJlbmRlciB0YXJnZXQgc2V0dXAgZm9yIGh3IGJsaXQsIGZhbGxpbmcgYmFjayB0byBzb2Z0d2FyZVxuIik7CiAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfQmx0WihJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBSRUNUICpEZXN0UmVjdCwgSVdpbmVEM0RTdXJmYWNlICpTcmNTdXJmYWNlLCBSRUNUICpTcmNSZWN0LCBEV09SRCBGbGFncywgV0lORUREQkxURlggKkREQmx0RngpCnsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqbXlEZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgZmxvYXQgZGVwdGg7CgogICAgaWYgKEZsYWdzICYgV0lORUREQkxUX0RFUFRIRklMTCkgewogICAgICAgIHN3aXRjaChUaGlzLT5yZXNvdXJjZS5mb3JtYXQpIHsKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX0QxNjoKICAgICAgICAgICAgICAgIGRlcHRoID0gKGZsb2F0KSBEREJsdEZ4LT51NS5kd0ZpbGxEZXB0aCAvIChmbG9hdCkgMHgwMDAwZmZmZjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfRDE1UzE6CiAgICAgICAgICAgICAgICBkZXB0aCA9IChmbG9hdCkgRERCbHRGeC0+dTUuZHdGaWxsRGVwdGggLyAoZmxvYXQpIDB4MDAwMGZmZmU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX0QyNFM4OgogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfRDI0WDg6CiAgICAgICAgICAgICAgICBkZXB0aCA9IChmbG9hdCkgRERCbHRGeC0+dTUuZHdGaWxsRGVwdGggLyAoZmxvYXQpIDB4MDBmZmZmZmY7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBXSU5FRDNERk1UX0QzMjoKICAgICAgICAgICAgICAgIGRlcHRoID0gKGZsb2F0KSBEREJsdEZ4LT51NS5kd0ZpbGxEZXB0aCAvIChmbG9hdCkgMHhmZmZmZmZmZjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgZGVwdGggPSAwLjA7CiAgICAgICAgICAgICAgICBFUlIoIlVuZXhwZWN0ZWQgZm9ybWF0IGZvciBkZXB0aCBmaWxsOiAlc1xuIiwgZGVidWdfZDNkZm9ybWF0KFRoaXMtPnJlc291cmNlLmZvcm1hdCkpOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIElXaW5lRDNERGV2aWNlX0NsZWFyKChJV2luZUQzRERldmljZSAqKSBteURldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVzdFJlY3QgPT0gTlVMTCA/IDAgOiAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoV0lORUQzRFJFQ1QgKikgRGVzdFJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RDTEVBUl9aQlVGRkVSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDAwMDAwMDAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXB0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwMDAwMDAwMCk7CiAgICB9CgogICAgRklYTUUoIiglcCk6IFVuc3VwcCBkZXB0aHN0ZW5jaWwgYmxpdFxuIiwgVGhpcyk7CiAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfQmx0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFJFQ1QgKkRlc3RSZWN0LCBJV2luZUQzRFN1cmZhY2UgKlNyY1N1cmZhY2UsIFJFQ1QgKlNyY1JlY3QsIERXT1JEIEZsYWdzLCBXSU5FRERCTFRGWCAqRERCbHRGeCwgV0lORUQzRFRFWFRVUkVGSUxURVJUWVBFIEZpbHRlcikgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpTcmMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBTcmNTdXJmYWNlOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpteURldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwLCVwLCV4LCVwKVxuIiwgVGhpcywgRGVzdFJlY3QsIFNyY1N1cmZhY2UsIFNyY1JlY3QsIEZsYWdzLCBEREJsdEZ4KTsKICAgIFRSQUNFKCIoJXApOiBVc2FnZSBpcyAlc1xuIiwgVGhpcywgZGVidWdfZDNkdXNhZ2UoVGhpcy0+cmVzb3VyY2UudXNhZ2UpKTsKCiAgICAvKiBBY2Nlc3NpbmcgdGhlIGRlcHRoIHN0ZW5jaWwgaXMgc3VwcG9zZWQgdG8gZmFpbCBiZXR3ZWVuIGEgQmVnaW5TY2VuZSBhbmQgRW5kU2NlbmUgcGFpciwKICAgICAqIGV4Y2VwdCBkZXB0aCBibGl0cywgd2hpY2ggc2VlbSB0byB3b3JrCiAgICAgKi8KICAgIGlmKGlmYWNlID09IG15RGV2aWNlLT5zdGVuY2lsQnVmZmVyVGFyZ2V0IHx8IChTcmNTdXJmYWNlICYmIFNyY1N1cmZhY2UgPT0gbXlEZXZpY2UtPnN0ZW5jaWxCdWZmZXJUYXJnZXQpKSB7CiAgICAgICAgaWYobXlEZXZpY2UtPmluU2NlbmUgJiYgIShGbGFncyAmIFdJTkVEREJMVF9ERVBUSEZJTEwpKSB7CiAgICAgICAgICAgIFRSQUNFKCJBdHRlbXB0IHRvIGFjY2VzcyB0aGUgZGVwdGggc3RlbmNpbCBzdXJmYWNlIGluIGEgQmVnaW5TY2VuZSAvIEVuZFNjZW5lIHBhaXIsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfSBlbHNlIGlmKElXaW5lRDNEU3VyZmFjZUltcGxfQmx0WihUaGlzLCBEZXN0UmVjdCwgU3JjU3VyZmFjZSwgU3JjUmVjdCwgRmxhZ3MsIEREQmx0RngpID09IFdJTkVEM0RfT0spIHsKICAgICAgICAgICAgVFJBQ0UoIlogQmxpdCBvdmVycmlkZSBoYW5kbGVkIHRoZSBibGl0XG4iKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFNwZWNpYWwgY2FzZXMgZm9yIFJlbmRlclRhcmdldHMgKi8KICAgIGlmKCAoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSB8fAogICAgICAgICggU3JjICYmIChTcmMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgKSkgewogICAgICAgIGlmKElXaW5lRDNEU3VyZmFjZUltcGxfQmx0T3ZlcnJpZGUoVGhpcywgRGVzdFJlY3QsIFNyY1N1cmZhY2UsIFNyY1JlY3QsIEZsYWdzLCBEREJsdEZ4LCBGaWx0ZXIpID09IFdJTkVEM0RfT0spIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIC8qIEZvciB0aGUgcmVzdCBjYWxsIHRoZSBYMTEgc3VyZmFjZSBpbXBsZW1lbnRhdGlvbi4KICAgICAqIEZvciBSZW5kZXJUYXJnZXRzIHRoaXMgc2hvdWxkIGJlIGltcGxlbWVudGVkIE9wZW5HTCBhY2NlbGVyYXRlZCBpbiBCbHRPdmVycmlkZSwKICAgICAqIG90aGVyIEJsdHMgYXJlIHJhdGhlciByYXJlCiAgICAgKi8KICAgIHJldHVybiBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9CbHQoaWZhY2UsIERlc3RSZWN0LCBTcmNTdXJmYWNlLCBTcmNSZWN0LCBGbGFncywgRERCbHRGeCwgRmlsdGVyKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9CbHRGYXN0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIERXT1JEIGRzdHgsIERXT1JEIGRzdHksIElXaW5lRDNEU3VyZmFjZSAqU291cmNlLCBSRUNUICpyc3JjLCBEV09SRCB0cmFucykgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqc3JjSW1wbCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFNvdXJjZTsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqbXlEZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgVFJBQ0UoIiglcCktPiglZCwgJWQsICVwLCAlcCwgJTA4eFxuIiwgaWZhY2UsIGRzdHgsIGRzdHksIFNvdXJjZSwgcnNyYywgdHJhbnMpOwoKICAgIGlmKG15RGV2aWNlLT5pblNjZW5lICYmCiAgICAgICAoaWZhY2UgPT0gbXlEZXZpY2UtPnN0ZW5jaWxCdWZmZXJUYXJnZXQgfHwKICAgICAgIChTb3VyY2UgJiYgU291cmNlID09IG15RGV2aWNlLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KSkpIHsKICAgICAgICBUUkFDRSgiQXR0ZW1wdCB0byBhY2Nlc3MgdGhlIGRlcHRoIHN0ZW5jaWwgc3VyZmFjZSBpbiBhIEJlZ2luU2NlbmUgLyBFbmRTY2VuZSBwYWlyLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogU3BlY2lhbCBjYXNlcyBmb3IgUmVuZGVyVGFyZ2V0cyAqLwogICAgaWYoIChUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpIHx8CiAgICAgICAgKCBzcmNJbXBsICYmIChzcmNJbXBsLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpICkpIHsKCiAgICAgICAgUkVDVCBTcmNSZWN0LCBEc3RSZWN0OwogICAgICAgIERXT1JEIEZsYWdzPTA7CgogICAgICAgIGlmKHJzcmMpIHsKICAgICAgICAgICAgU3JjUmVjdC5sZWZ0ID0gcnNyYy0+bGVmdDsKICAgICAgICAgICAgU3JjUmVjdC50b3A9IHJzcmMtPnRvcDsKICAgICAgICAgICAgU3JjUmVjdC5ib3R0b20gPSByc3JjLT5ib3R0b207CiAgICAgICAgICAgIFNyY1JlY3QucmlnaHQgPSByc3JjLT5yaWdodDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBTcmNSZWN0LmxlZnQgPSAwOwogICAgICAgICAgICBTcmNSZWN0LnRvcCA9IDA7CiAgICAgICAgICAgIFNyY1JlY3QucmlnaHQgPSBzcmNJbXBsLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICAgICAgU3JjUmVjdC5ib3R0b20gPSBzcmNJbXBsLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgfQoKICAgICAgICBEc3RSZWN0LmxlZnQgPSBkc3R4OwogICAgICAgIERzdFJlY3QudG9wPWRzdHk7CiAgICAgICAgRHN0UmVjdC5yaWdodCA9IGRzdHggKyBTcmNSZWN0LnJpZ2h0IC0gU3JjUmVjdC5sZWZ0OwogICAgICAgIERzdFJlY3QuYm90dG9tID0gZHN0eSArIFNyY1JlY3QuYm90dG9tIC0gU3JjUmVjdC50b3A7CgogICAgICAgIC8qIENvbnZlcnQgQmx0RmFzdCBmbGFncyBpbnRvIEJ0bCBvbmVzIGJlY2F1c2UgaXQgaXMgY2FsbGVkIGZyb20gU3VyZmFjZUltcGxfQmx0IGFzIHdlbGwgKi8KICAgICAgICBpZih0cmFucyAmIFdJTkVEREJMVEZBU1RfU1JDQ09MT1JLRVkpCiAgICAgICAgICAgIEZsYWdzIHw9IFdJTkVEREJMVF9LRVlTUkM7CiAgICAgICAgaWYodHJhbnMgJiBXSU5FRERCTFRGQVNUX0RFU1RDT0xPUktFWSkKICAgICAgICAgICAgRmxhZ3MgfD0gV0lORUREQkxUX0tFWURFU1Q7CiAgICAgICAgaWYodHJhbnMgJiBXSU5FRERCTFRGQVNUX1dBSVQpCiAgICAgICAgICAgIEZsYWdzIHw9IFdJTkVEREJMVF9XQUlUOwogICAgICAgIGlmKHRyYW5zICYgV0lORUREQkxURkFTVF9ET05PVFdBSVQpCiAgICAgICAgICAgIEZsYWdzIHw9IFdJTkVEREJMVF9ET05PVFdBSVQ7CgogICAgICAgIGlmKElXaW5lRDNEU3VyZmFjZUltcGxfQmx0T3ZlcnJpZGUoVGhpcywgJkRzdFJlY3QsIFNvdXJjZSwgJlNyY1JlY3QsIEZsYWdzLCBOVUxMLCBXSU5FRDNEVEVYRl9QT0lOVCkgPT0gV0lORUQzRF9PSykgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgoKICAgIHJldHVybiBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9CbHRGYXN0KGlmYWNlLCBkc3R4LCBkc3R5LCBTb3VyY2UsIHJzcmMsIHRyYW5zKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfUHJpdmF0ZVNldHVwKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIC8qKiBDaGVjayBhZ2FpbnN0IHRoZSBtYXhpbXVtIHRleHR1cmUgc2l6ZXMgc3VwcG9ydGVkIGJ5IHRoZSB2aWRlbyBjYXJkICoqLwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgdW5zaWduZWQgaW50IHBvdzJXaWR0aCwgcG93MkhlaWdodDsKICAgIGNvbnN0IEdsUGl4ZWxGb3JtYXREZXNjICpnbERlc2M7CgogICAgZ2V0Rm9ybWF0RGVzY0VudHJ5KFRoaXMtPnJlc291cmNlLmZvcm1hdCwgJkdMSU5GT19MT0NBVElPTiwgJmdsRGVzYyk7CiAgICAvKiBTZXR1cCBzb21lIGdsZm9ybWF0IGRlZmF1bHRzICovCiAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0ICAgICAgICAgPSBnbERlc2MtPmdsRm9ybWF0OwogICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdEludGVybmFsID0gZ2xEZXNjLT5nbEludGVybmFsOwogICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbFR5cGUgICAgICAgICAgID0gZ2xEZXNjLT5nbFR5cGU7CgogICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSAgICAgID0gMDsKICAgIFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0ICAgICAgICAgICA9IEdMX1RFWFRVUkVfMkQ7CgogICAgLyogTm9uLXBvd2VyMiBzdXBwb3J0ICovCiAgICBpZiAoR0xfU1VQUE9SVChBUkJfVEVYVFVSRV9OT05fUE9XRVJfT0ZfVFdPKSkgewogICAgICAgIHBvdzJXaWR0aCA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgIHBvdzJIZWlnaHQgPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICB9IGVsc2UgewogICAgICAgIC8qIEZpbmQgdGhlIG5lYXJlc3QgcG93MiBtYXRjaCAqLwogICAgICAgIHBvdzJXaWR0aCA9IHBvdzJIZWlnaHQgPSAxOwogICAgICAgIHdoaWxlIChwb3cyV2lkdGggPCBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCkgcG93MldpZHRoIDw8PSAxOwogICAgICAgIHdoaWxlIChwb3cySGVpZ2h0IDwgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KSBwb3cySGVpZ2h0IDw8PSAxOwogICAgfQogICAgVGhpcy0+cG93MldpZHRoICA9IHBvdzJXaWR0aDsKICAgIFRoaXMtPnBvdzJIZWlnaHQgPSBwb3cySGVpZ2h0OwoKICAgIGlmIChwb3cyV2lkdGggPiBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCB8fCBwb3cySGVpZ2h0ID4gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KSB7CiAgICAgICAgV0lORUQzREZPUk1BVCBGb3JtYXQgPSBUaGlzLT5yZXNvdXJjZS5mb3JtYXQ7CiAgICAgICAgLyoqIFRPRE86IGFkZCBzdXBwb3J0IGZvciBub24gcG93ZXIgdHdvIGNvbXByZXNzZWQgdGV4dHVyZXMgKiovCiAgICAgICAgaWYgKEZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEgfHwgRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fCBGb3JtYXQgPT0gV0lORUQzREZNVF9EWFQzCiAgICAgICAgICAgIHx8IEZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDQgfHwgRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNSkgewogICAgICAgICAgICBGSVhNRSgiKCVwKSBDb21wcmVzc2VkIG5vbi1wb3dlci10d28gdGV4dHVyZXMgYXJlIG5vdCBzdXBwb3J0ZWQgdyglZCkgaCglZClcbiIsCiAgICAgICAgICAgICAgICAgIFRoaXMsIFRoaXMtPmN1cnJlbnREZXNjLldpZHRoLCBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpOwogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9OT1RBVkFJTEFCTEU7CiAgICAgICAgfQogICAgfQoKICAgIGlmKHBvdzJXaWR0aCAhPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCB8fAogICAgICAgcG93MkhlaWdodCAhPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpIHsKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19OT05QT1cyOwogICAgfQoKICAgIFRSQUNFKCIlcFxuIiwgVGhpcyk7CiAgICBpZiAoKFRoaXMtPnBvdzJXaWR0aCA+IEdMX0xJTUlUUyh0ZXh0dXJlX3NpemUpIHx8IFRoaXMtPnBvdzJIZWlnaHQgPiBHTF9MSU1JVFModGV4dHVyZV9zaXplKSkgJiYgIShUaGlzLT5yZXNvdXJjZS51c2FnZSAmIChXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUIHwgV0lORUQzRFVTQUdFX0RFUFRIU1RFTkNJTCkpKSB7CiAgICAgICAgLyogb25lIG9mIHRocmVlIG9wdGlvbnMKICAgICAgICAxOiBEbyB0aGUgc2FtZSBhcyB3ZSBkbyB3aXRoIG5vbnBvdyAyIGFuZCBzY2FsZSB0aGUgdGV4dHVyZSwgKGFueSB0ZXh0dXJlIG9wcyB3b3VsZCByZXF1aXJlIHRoZSB0ZXh0dXJlIHRvIGJlIHNjYWxlZCB3aGljaCBpcyBwb3RlbnRpYWxseSBzbG93KQogICAgICAgIDI6IFNldCB0aGUgdGV4dHVyZSB0byB0aGUgbWF4aW11bSBzaXplIChiYWQgaWRlYSkKICAgICAgICAzOiAgICBXQVJOIGFuZCByZXR1cm4gV0lORUQzREVSUl9OT1RBVkFJTEFCTEU7CiAgICAgICAgNDogQ3JlYXRlIHRoZSBzdXJmYWNlLCBidXQgYWxsb3cgaXQgdG8gYmUgdXNlZCBvbmx5IGZvciBEaXJlY3REcmF3IEJsdHMuIFNvbWUgYXBwcyhlLmcuIFN3YXQgMykgY3JlYXRlIHRleHR1cmVzIHdpdGggYSBIZWlnaHQgb2YgMTYgYW5kIGEgV2lkdGggPiAzMDAwIGFuZCBibHQgMTZ4MTYgbGV0dGVyIGFyZWFzIGZyb20gdGhlbSB0byB0aGUgcmVuZGVyIHRhcmdldC4KICAgICAgICAqLwogICAgICAgIFdBUk4oIiglcCkgQ3JlYXRpbmcgYW4gb3ZlcnNpemVkIHN1cmZhY2VcbiIsIFRoaXMpOwogICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX09WRVJTSVpFOwoKICAgICAgICAvKiBUaGlzIHdpbGwgYmUgaW5pdGlhbGl6ZWQgb24gdGhlIGZpcnN0IGJsdCAqLwogICAgICAgIFRoaXMtPmdsUmVjdC5sZWZ0ID0gMDsKICAgICAgICBUaGlzLT5nbFJlY3QudG9wID0gMDsKICAgICAgICBUaGlzLT5nbFJlY3QucmlnaHQgPSAwOwogICAgICAgIFRoaXMtPmdsUmVjdC5ib3R0b20gPSAwOwogICAgfSBlbHNlIHsKICAgICAgICAvKiBDaGVjayB0aGlzIGFmdGVyIHRoZSBvdmVyc2l6ZSBjaGVjayAtIGRvIG5vdCBtYWtlIGFuIG92ZXJzaXplZCBzdXJmYWNlIGEgdGV4dHVyZV9yZWN0YW5nbGUgb25lICovCiAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19OT05QT1cyICYmIEdMX1NVUFBPUlQoQVJCX1RFWFRVUkVfUkVDVEFOR0xFKSkgewogICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCA9IEdMX1RFWFRVUkVfUkVDVEFOR0xFX0FSQjsKICAgICAgICAgICAgVGhpcy0+cG93MldpZHRoICA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgICAgICBUaGlzLT5wb3cySGVpZ2h0ID0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfTk9OUE9XMjsKICAgICAgICB9CgogICAgICAgIC8qIE5vIG92ZXJzaXplLCBnbCByZWN0IGlzIHRoZSBmdWxsIHRleHR1cmUgc2l6ZSAqLwogICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19PVkVSU0laRTsKICAgICAgICBUaGlzLT5nbFJlY3QubGVmdCA9IDA7CiAgICAgICAgVGhpcy0+Z2xSZWN0LnRvcCA9IDA7CiAgICAgICAgVGhpcy0+Z2xSZWN0LnJpZ2h0ID0gVGhpcy0+cG93MldpZHRoOwogICAgICAgIFRoaXMtPmdsUmVjdC5ib3R0b20gPSBUaGlzLT5wb3cySGVpZ2h0OwogICAgfQoKICAgIGlmKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgewogICAgICAgIHN3aXRjaCh3aW5lZDNkX3NldHRpbmdzLm9mZnNjcmVlbl9yZW5kZXJpbmdfbW9kZSkgewogICAgICAgICAgICBjYXNlIE9STV9GQk86ICAgICAgICBUaGlzLT5nZXRfZHJhd2FibGVfc2l6ZSA9IGdldF9kcmF3YWJsZV9zaXplX2ZibzsgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIE9STV9QQlVGRkVSOiAgICBUaGlzLT5nZXRfZHJhd2FibGVfc2l6ZSA9IGdldF9kcmF3YWJsZV9zaXplX3BidWZmZXI7ICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIE9STV9CQUNLQlVGRkVSOiBUaGlzLT5nZXRfZHJhd2FibGVfc2l6ZSA9IGdldF9kcmF3YWJsZV9zaXplX2JhY2tidWZmZXI7IGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19JTlNZU01FTTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfTW9kaWZ5TG9jYXRpb24oSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgRFdPUkQgZmxhZywgQk9PTCBwZXJzaXN0ZW50KSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzREJhc2VUZXh0dXJlICp0ZXh0dXJlOwoKICAgIFRSQUNFKCIoJXApLT4oJXMsICVzKVxuIiwgaWZhY2UsCiAgICAgICAgICBmbGFnID09IFNGTEFHX0lOU1lTTUVNID8gIlNGTEFHX0lOU1lTTUVNIiA6IGZsYWcgPT0gU0ZMQUdfSU5EUkFXQUJMRSA/ICJTRkxBR19JTkRSQVdBQkxFIiA6ICJTRkxBR19JTlRFWFRVUkUiLAogICAgICAgICAgcGVyc2lzdGVudCA/ICJUUlVFIiA6ICJGQUxTRSIpOwoKICAgIC8qIFRPRE86IEZvciBvZmZzY3JlZW4gdGV4dHVyZXMgd2l0aCBmYm8gb2Zmc2NyZWVuIHJlbmRlcmluZyB0aGUgZHJhd2FibGUgaXMgdGhlIHNhbWUgYXMgdGhlIHRleHR1cmUuKi8KICAgIGlmKHBlcnNpc3RlbnQpIHsKICAgICAgICBpZigoVGhpcy0+RmxhZ3MgJiBTRkxBR19JTlRFWFRVUkUpICYmICEoZmxhZyAmIFNGTEFHX0lOVEVYVFVSRSkpIHsKICAgICAgICAgICAgaWYgKElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoaWZhY2UsICZJSURfSVdpbmVEM0RCYXNlVGV4dHVyZSwgKHZvaWQgKiopJnRleHR1cmUpID09IFdJTkVEM0RfT0spIHsKICAgICAgICAgICAgICAgIFRSQUNFKCJQYXNzaW5nIHRvIGNvbnRhaW5lclxuIik7CiAgICAgICAgICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX1NldERpcnR5KHRleHR1cmUsIFRSVUUpOwogICAgICAgICAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9SZWxlYXNlKHRleHR1cmUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19MT0NBVElPTlM7CiAgICAgICAgVGhpcy0+RmxhZ3MgfD0gZmxhZzsKICAgIH0gZWxzZSB7CiAgICAgICAgaWYoKFRoaXMtPkZsYWdzICYgU0ZMQUdfSU5URVhUVVJFKSAmJiAoZmxhZyAmIFNGTEFHX0lOVEVYVFVSRSkpIHsKICAgICAgICAgICAgaWYgKElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoaWZhY2UsICZJSURfSVdpbmVEM0RCYXNlVGV4dHVyZSwgKHZvaWQgKiopJnRleHR1cmUpID09IFdJTkVEM0RfT0spIHsKICAgICAgICAgICAgICAgIFRSQUNFKCJQYXNzaW5nIHRvIGNvbnRhaW5lclxuIik7CiAgICAgICAgICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX1NldERpcnR5KHRleHR1cmUsIFRSVUUpOwogICAgICAgICAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9SZWxlYXNlKHRleHR1cmUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIFRoaXMtPkZsYWdzICY9IH5mbGFnOwogICAgfQp9CgpzdHJ1Y3QgY29vcmRzIHsKICAgIGludCB4LCB5LCB6Owp9OwoKc3RhdGljIGlubGluZSB2b2lkIHN1cmZhY2VfYmx0X3RvX2RyYXdhYmxlKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMsIGNvbnN0IFJFQ1QgKnJlY3RfaW4pIHsKICAgIHN0cnVjdCBjb29yZHMgY29vcmRzWzRdOwogICAgUkVDVCByZWN0OwogICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBjaGFpbiA9IE5VTEw7CiAgICBJV2luZUQzREJhc2VUZXh0dXJlICp0ZXh0dXJlID0gTlVMTDsKICAgIEhSRVNVTFQgaHI7CiAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CgogICAgaWYocmVjdF9pbikgewogICAgICAgIHJlY3QgPSAqcmVjdF9pbjsKICAgIH0gZWxzZSB7CiAgICAgICAgcmVjdC5sZWZ0ID0gMDsKICAgICAgICByZWN0LnRvcCA9IDA7CiAgICAgICAgcmVjdC5yaWdodCA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgIHJlY3QuYm90dG9tID0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgfQoKICAgIEFjdGl2YXRlQ29udGV4dChkZXZpY2UsIGRldmljZS0+cmVuZGVyX3RhcmdldHNbMF0sIENUWFVTQUdFX0JMSVQpOwogICAgRU5URVJfR0woKTsKCiAgICBpZihUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCA9PSBHTF9URVhUVVJFX1JFQ1RBTkdMRV9BUkIpIHsKICAgICAgICBnbEVuYWJsZShHTF9URVhUVVJFX1JFQ1RBTkdMRV9BUkIpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZShHTF9URVhUVVJFX1JFQ1RBTkdMRV9BUkIpIik7CiAgICAgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFX1JFQ1RBTkdMRV9BUkIsIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgIGNoZWNrR0xjYWxsKCJHTF9URVhUVVJFX1JFQ1RBTkdMRV9BUkIsIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpIik7CiAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfUkVDVEFOR0xFX0FSQiwgR0xfVEVYVFVSRV9NQUdfRklMVEVSLCBHTF9ORUFSRVNUKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhQYXJhbWV0ZXJpIik7CiAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfUkVDVEFOR0xFX0FSQiwgR0xfVEVYVFVSRV9NSU5fRklMVEVSLCBHTF9ORUFSRVNUKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhQYXJhbWV0ZXJpIik7CgogICAgICAgIGNvb3Jkc1swXS54ID0gcmVjdC5sZWZ0OwogICAgICAgIGNvb3Jkc1swXS56ID0gMDsKCiAgICAgICAgY29vcmRzWzFdLnggPSByZWN0LmxlZnQ7CiAgICAgICAgY29vcmRzWzFdLnogPSAwOwoKICAgICAgICBjb29yZHNbMl0ueCA9IHJlY3QucmlnaHQ7CiAgICAgICAgY29vcmRzWzJdLnogPSAwOwoKICAgICAgICBjb29yZHNbM10ueCA9IHJlY3QucmlnaHQ7CiAgICAgICAgY29vcmRzWzNdLnogPSAwOwoKICAgICAgICBjb29yZHNbMF0ueSA9IHJlY3QudG9wOwogICAgICAgIGNvb3Jkc1sxXS55ID0gcmVjdC5ib3R0b207CiAgICAgICAgY29vcmRzWzJdLnkgPSByZWN0LmJvdHRvbTsKICAgICAgICBjb29yZHNbM10ueSA9IHJlY3QudG9wOwogICAgfSBlbHNlIGlmKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0ID09IEdMX1RFWFRVUkVfMkQpIHsKICAgICAgICBnbEVuYWJsZShHTF9URVhUVVJFXzJEKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoR0xfVEVYVFVSRV8yRCkiKTsKICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgIGNoZWNrR0xjYWxsKCJHTF9URVhUVVJFXzJELCBUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKSIpOwogICAgICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01BR19GSUxURVIsIEdMX05FQVJFU1QpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleFBhcmFtZXRlcmkiKTsKICAgICAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NSU5fRklMVEVSLCBHTF9ORUFSRVNUKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhQYXJhbWV0ZXJpIik7CgogICAgICAgIGNvb3Jkc1swXS54ID0gcmVjdC5sZWZ0ICAgLyBUaGlzLT5wb3cyV2lkdGg7CiAgICAgICAgY29vcmRzWzBdLnogPSAwOwoKICAgICAgICBjb29yZHNbMV0ueCA9IHJlY3QubGVmdCAgIC8gVGhpcy0+cG93MldpZHRoOwogICAgICAgIGNvb3Jkc1sxXS56ID0gMDsKCiAgICAgICAgY29vcmRzWzJdLnggPSByZWN0LnJpZ2h0ICAvIFRoaXMtPnBvdzJXaWR0aDsKICAgICAgICBjb29yZHNbMl0ueiA9IDA7CgogICAgICAgIGNvb3Jkc1szXS54ID0gcmVjdC5yaWdodCAgLyBUaGlzLT5wb3cyV2lkdGg7CiAgICAgICAgY29vcmRzWzNdLnogPSAwOwoKICAgICAgICBjb29yZHNbMF0ueSA9IHJlY3QudG9wICAgIC8gVGhpcy0+cG93MkhlaWdodDsKICAgICAgICBjb29yZHNbMV0ueSA9IHJlY3QuYm90dG9tIC8gVGhpcy0+cG93MkhlaWdodDsKICAgICAgICBjb29yZHNbMl0ueSA9IHJlY3QuYm90dG9tIC8gVGhpcy0+cG93MkhlaWdodDsKICAgICAgICBjb29yZHNbM10ueSA9IHJlY3QudG9wICAgIC8gVGhpcy0+cG93MkhlaWdodDsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogTXVzdCBiZSBhIGN1YmUgbWFwICovCiAgICAgICAgZ2xFbmFibGUoR0xfVEVYVFVSRV9DVUJFX01BUF9BUkIpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZShHTF9URVhUVVJFX0NVQkVfTUFQX0FSQikiKTsKICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfQ1VCRV9NQVBfQVJCLCBUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgICAgICBjaGVja0dMY2FsbCgiR0xfVEVYVFVSRV9DVUJFX01BUF9BUkIsIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpIik7CiAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfQ1VCRV9NQVBfQVJCLCBHTF9URVhUVVJFX01BR19GSUxURVIsIEdMX05FQVJFU1QpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleFBhcmFtZXRlcmkiKTsKICAgICAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV9DVUJFX01BUF9BUkIsIEdMX1RFWFRVUkVfTUlOX0ZJTFRFUiwgR0xfTkVBUkVTVCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4UGFyYW1ldGVyaSIpOwoKICAgICAgICBzd2l0Y2goVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQpIHsKICAgICAgICAgICAgY2FzZSBHTF9URVhUVVJFX0NVQkVfTUFQX1BPU0lUSVZFX1g6CiAgICAgICAgICAgICAgICBjb29yZHNbMF0ueCA9ICAxOyAgIGNvb3Jkc1swXS55ID0gLTE7ICAgY29vcmRzWzBdLnogPSAgMTsKICAgICAgICAgICAgICAgIGNvb3Jkc1sxXS54ID0gIDE7ICAgY29vcmRzWzFdLnkgPSAgMTsgICBjb29yZHNbMV0ueiA9ICAxOwogICAgICAgICAgICAgICAgY29vcmRzWzJdLnggPSAgMTsgICBjb29yZHNbMl0ueSA9ICAxOyAgIGNvb3Jkc1syXS56ID0gLTE7CiAgICAgICAgICAgICAgICBjb29yZHNbM10ueCA9ICAxOyAgIGNvb3Jkc1szXS55ID0gLTE7ICAgY29vcmRzWzNdLnogPSAtMTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBHTF9URVhUVVJFX0NVQkVfTUFQX05FR0FUSVZFX1g6CiAgICAgICAgICAgICAgICBjb29yZHNbMF0ueCA9IC0xOyAgIGNvb3Jkc1swXS55ID0gLTE7ICAgY29vcmRzWzBdLnogPSAgMTsKICAgICAgICAgICAgICAgIGNvb3Jkc1sxXS54ID0gLTE7ICAgY29vcmRzWzFdLnkgPSAgMTsgICBjb29yZHNbMV0ueiA9ICAxOwogICAgICAgICAgICAgICAgY29vcmRzWzJdLnggPSAtMTsgICBjb29yZHNbMl0ueSA9ICAxOyAgIGNvb3Jkc1syXS56ID0gLTE7CiAgICAgICAgICAgICAgICBjb29yZHNbM10ueCA9IC0xOyAgIGNvb3Jkc1szXS55ID0gLTE7ICAgY29vcmRzWzNdLnogPSAtMTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBHTF9URVhUVVJFX0NVQkVfTUFQX1BPU0lUSVZFX1k6CiAgICAgICAgICAgICAgICBjb29yZHNbMF0ueCA9IC0xOyAgIGNvb3Jkc1swXS55ID0gIDE7ICAgY29vcmRzWzBdLnogPSAgMTsKICAgICAgICAgICAgICAgIGNvb3Jkc1sxXS54ID0gIDE7ICAgY29vcmRzWzFdLnkgPSAgMTsgICBjb29yZHNbMV0ueiA9ICAxOwogICAgICAgICAgICAgICAgY29vcmRzWzJdLnggPSAgMTsgICBjb29yZHNbMl0ueSA9ICAxOyAgIGNvb3Jkc1syXS56ID0gLTE7CiAgICAgICAgICAgICAgICBjb29yZHNbM10ueCA9IC0xOyAgIGNvb3Jkc1szXS55ID0gIDE7ICAgY29vcmRzWzNdLnogPSAtMTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBHTF9URVhUVVJFX0NVQkVfTUFQX05FR0FUSVZFX1k6CiAgICAgICAgICAgICAgICBjb29yZHNbMF0ueCA9IC0xOyAgIGNvb3Jkc1swXS55ID0gLTE7ICAgY29vcmRzWzBdLnogPSAgMTsKICAgICAgICAgICAgICAgIGNvb3Jkc1sxXS54ID0gIDE7ICAgY29vcmRzWzFdLnkgPSAtMTsgICBjb29yZHNbMV0ueiA9ICAxOwogICAgICAgICAgICAgICAgY29vcmRzWzJdLnggPSAgMTsgICBjb29yZHNbMl0ueSA9IC0xOyAgIGNvb3Jkc1syXS56ID0gLTE7CiAgICAgICAgICAgICAgICBjb29yZHNbM10ueCA9IC0xOyAgIGNvb3Jkc1szXS55ID0gLTE7ICAgY29vcmRzWzNdLnogPSAtMTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBHTF9URVhUVVJFX0NVQkVfTUFQX1BPU0lUSVZFX1o6CiAgICAgICAgICAgICAgICBjb29yZHNbMF0ueCA9IC0xOyAgIGNvb3Jkc1swXS55ID0gLTE7ICAgY29vcmRzWzBdLnogPSAgMTsKICAgICAgICAgICAgICAgIGNvb3Jkc1sxXS54ID0gIDE7ICAgY29vcmRzWzFdLnkgPSAtMTsgICBjb29yZHNbMV0ueiA9ICAxOwogICAgICAgICAgICAgICAgY29vcmRzWzJdLnggPSAgMTsgICBjb29yZHNbMl0ueSA9IC0xOyAgIGNvb3Jkc1syXS56ID0gIDE7CiAgICAgICAgICAgICAgICBjb29yZHNbM10ueCA9IC0xOyAgIGNvb3Jkc1szXS55ID0gLTE7ICAgY29vcmRzWzNdLnogPSAgMTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSBHTF9URVhUVVJFX0NVQkVfTUFQX05FR0FUSVZFX1o6CiAgICAgICAgICAgICAgICBjb29yZHNbMF0ueCA9IC0xOyAgIGNvb3Jkc1swXS55ID0gLTE7ICAgY29vcmRzWzBdLnogPSAtMTsKICAgICAgICAgICAgICAgIGNvb3Jkc1sxXS54ID0gIDE7ICAgY29vcmRzWzFdLnkgPSAtMTsgICBjb29yZHNbMV0ueiA9IC0xOwogICAgICAgICAgICAgICAgY29vcmRzWzJdLnggPSAgMTsgICBjb29yZHNbMl0ueSA9IC0xOyAgIGNvb3Jkc1syXS56ID0gLTE7CiAgICAgICAgICAgICAgICBjb29yZHNbM10ueCA9IC0xOyAgIGNvb3Jkc1szXS55ID0gLTE7ICAgY29vcmRzWzNdLnogPSAtMTsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBFUlIoIlVuZXhwZWN0ZWQgdGV4dHVyZSB0YXJnZXRcbiIpOwogICAgICAgICAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgZ2xCZWdpbihHTF9RVUFEUyk7CiAgICBnbFRleENvb3JkM2l2KChHTGludCAqKSAmY29vcmRzWzBdKTsKICAgIGdsVmVydGV4MmkocmVjdC5sZWZ0LCBkZXZpY2UtPnJlbmRlcl9vZmZzY3JlZW4gPyByZWN0LmJvdHRvbSA6IHJlY3QudG9wKTsKCiAgICBnbFRleENvb3JkM2l2KChHTGludCAqKSAmY29vcmRzWzFdKTsKICAgIGdsVmVydGV4MmkoMCwgZGV2aWNlLT5yZW5kZXJfb2Zmc2NyZWVuID8gcmVjdC50b3AgOiByZWN0LmJvdHRvbSk7CgogICAgZ2xUZXhDb29yZDNpdigoR0xpbnQgKikgJmNvb3Jkc1syXSk7CiAgICBnbFZlcnRleDJpKHJlY3QucmlnaHQsIGRldmljZS0+cmVuZGVyX29mZnNjcmVlbiA/IHJlY3QudG9wIDogcmVjdC5ib3R0b20pOwoKICAgIGdsVGV4Q29vcmQzaXYoKEdMaW50ICopICZjb29yZHNbM10pOwogICAgZ2xWZXJ0ZXgyaShyZWN0LnJpZ2h0LCBkZXZpY2UtPnJlbmRlcl9vZmZzY3JlZW4gPyByZWN0LmJvdHRvbSA6IHJlY3QudG9wKTsKICAgIGdsRW5kKCk7CiAgICBjaGVja0dMY2FsbCgiZ2xFbmQiKTsKCiAgICBpZihUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCAhPSBHTF9URVhUVVJFXzJEKSB7CiAgICAgICAgZ2xEaXNhYmxlKEdMX1RFWFRVUkVfQ1VCRV9NQVBfQVJCKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKEdMX1RFWFRVUkVfQ1VCRV9NQVBfQVJCKSIpOwogICAgfSBlbHNlIHsKICAgICAgICBnbERpc2FibGUoR0xfVEVYVFVSRV8yRCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShHTF9URVhUVVJFXzJEKSIpOwogICAgfQoKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcigoSVdpbmVEM0RTdXJmYWNlKilUaGlzLCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikgJnN3YXBjaGFpbik7CiAgICBpZihociA9PSBXSU5FRDNEX09LICYmIHN3YXBjaGFpbikgewogICAgICAgIC8qIE1ha2Ugc3VyZSB0byBmbHVzaCB0aGUgYnVmZmVycy4gVGhpcyBpcyBuZWVkZWQgaW4gYXBwcyBsaWtlIFJlZCBBbGVydCBJSSBhbmQgVGliZXJpYW4gU1VOIHRoYXQgdXNlIG11bHRpcGxlIFdHTCBjb250ZXh0cy4gKi8KICAgICAgICBpZigoKElXaW5lRDNEU3dhcENoYWluSW1wbCopc3dhcGNoYWluKS0+bnVtX2NvbnRleHRzID49IDIpCiAgICAgICAgICAgIGdsRmx1c2goKTsKCiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwY2hhaW4pOwogICAgfSBlbHNlIHsKICAgICAgICAvKiBXZSBjaGFuZ2VkIHRoZSBmaWx0ZXJpbmcgc2V0dGluZ3Mgb24gdGhlIHRleHR1cmUuIEluZm9ybSB0aGUgY29udGFpbmVyIGFib3V0IHRoaXMgdG8gZ2V0IHRoZSBmaWx0ZXJzCiAgICAgICAgICogcmVzZXQgcHJvcGVybHkgbmV4dCBkcmF3CiAgICAgICAgICovCiAgICAgICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKChJV2luZUQzRFN1cmZhY2UqKVRoaXMsICZJSURfSVdpbmVEM0RCYXNlVGV4dHVyZSwgKHZvaWQgKiopICZ0ZXh0dXJlKTsKICAgICAgICBpZihociA9PSBXSU5FRDNEX09LICYmIHRleHR1cmUpIHsKICAgICAgICAgICAgKChJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqKSB0ZXh0dXJlKS0+YmFzZVRleHR1cmUuc3RhdGVzW1dJTkVEM0RURVhTVEFfTUFHRklMVEVSXSA9IFdJTkVEM0RURVhGX1BPSU5UOwogICAgICAgICAgICAoKElXaW5lRDNEQmFzZVRleHR1cmVJbXBsICopIHRleHR1cmUpLT5iYXNlVGV4dHVyZS5zdGF0ZXNbV0lORUQzRFRFWFNUQV9NSU5GSUxURVJdID0gV0lORUQzRFRFWEZfUE9JTlQ7CiAgICAgICAgICAgICgoSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKikgdGV4dHVyZSktPmJhc2VUZXh0dXJlLnN0YXRlc1tXSU5FRDNEVEVYU1RBX01JUEZJTFRFUl0gPSBXSU5FRDNEVEVYRl9OT05FOwogICAgICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX1JlbGVhc2UodGV4dHVyZSk7CiAgICAgICAgfQogICAgfQogICAgTEVBVkVfR0woKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElXaW5lRDNEU3VyZmFjZTo6TG9hZExvY2F0aW9uCiAqCiAqIENvcGllcyB0aGUgY3VycmVudCBzdXJmYWNlIGRhdGEgZnJvbSB3aGVyZXZlciBpdCBpcyB0byB0aGUgcmVxdWVzdGVkCiAqIGxvY2F0aW9uLiBUaGUgbG9jYXRpb24gaXMgb25lIG9mIHRoZSBzdXJmYWNlIGZsYWdzLCBTRkxBR19JTlNZU01FTSwKICogU0ZMQUdfSU5URVhUVVJFIGFuZCBTRkxBR19JTkRSQVdBQkxFLiBXaGVuIHRoZSBzdXJmYWNlIGlzIGN1cnJlbnQgaW4KICogbXVsdGlwbGUgbG9jYXRpb25zLCB0aGUgZ2wgdGV4dHVyZSBpcyBwcmVmZXJyZWQgb3ZlciB0aGUgZHJhd2FibGUsIHdoaWNoIGlzCiAqIHByZWZlcnJlZCBvdmVyIHN5c3RlbSBtZW1vcnkuIFRoZSBQQk8gY291bnRzIGFzIHN5c3RlbSBtZW1vcnkuIElmIHJlY3QgaXMKICogbm90IE5VTEwsIG9ubHkgdGhlIHNwZWNpZmllZCByZWN0YW5nbGUgaXMgY29waWVkIChvbmx5IHN1cHBvcnRlZCBmb3IKICogc3lzbWVtPC0+ZHJhd2FibGUgY29waWVzIGF0IHRoZSBtb21lbnQpLiBJZiByZWN0IGlzIE5VTEwsIHRoZSBkZXN0aW5hdGlvbgogKiBsb2NhdGlvbiBpcyBtYXJrZWQgdXAgdG8gZGF0ZSBhZnRlciB0aGUgY29weS4KICoKICogUGFyYW1ldGVyczoKICogIGZsYWc6IFN1cmZhY2UgbG9jYXRpb24gZmxhZyB0byBiZSB1cGRhdGVkCiAqICByZWN0OiByZWN0YW5nbGUgdG8gYmUgY29waWVkCiAqCiAqIFJldHVybnM6CiAqICBXSU5FRDNEX09LIG9uIHN1Y2Nlc3MKICogIFdJTkVEM0RFUlJfREVWSUNFTE9TVCBvbiBhbiBpbnRlcm5hbCBlcnJvcgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0xvYWRMb2NhdGlvbihJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBEV09SRCBmbGFnLCBjb25zdCBSRUNUICpyZWN0KSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICBHTGVudW0gZm9ybWF0LCBpbnRlcm5hbCwgdHlwZTsKICAgIENPTlZFUlRfVFlQRVMgY29udmVydDsKICAgIGludCBicHA7CiAgICBpbnQgd2lkdGgsIHBpdGNoLCBvdXRwaXRjaDsKICAgIEJZVEUgKm1lbTsKCiAgICBUUkFDRSgiKCVwKS0+KCVzLCAlcClcbiIsIGlmYWNlLAogICAgICAgICAgZmxhZyA9PSBTRkxBR19JTlNZU01FTSA/ICJTRkxBR19JTlNZU01FTSIgOiBmbGFnID09IFNGTEFHX0lORFJBV0FCTEUgPyAiU0ZMQUdfSU5EUkFXQUJMRSIgOiAiU0ZMQUdfSU5URVhUVVJFIiwKICAgICAgICAgIHJlY3QpOwogICAgaWYocmVjdCkgewogICAgICAgIFRSQUNFKCJSZWN0YW5nbGU6ICglZCwlZCktKCVkLCVkKVxuIiwgcmVjdC0+bGVmdCwgcmVjdC0+dG9wLCByZWN0LT5yaWdodCwgcmVjdC0+Ym90dG9tKTsKICAgIH0KCiAgICAvKiBUT0RPOiBGb3IgZmJvIHRhcmdldHMsIHRleHR1cmUgPT0gZHJhd2FibGUgKi8KICAgIGlmKFRoaXMtPkZsYWdzICYgZmxhZykgewogICAgICAgIFRSQUNFKCJMb2NhdGlvbiBhbHJlYWR5IHVwIHRvIGRhdGVcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIGlmKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19MT0NBVElPTlMpKSB7CiAgICAgICAgRVJSKCJTdXJmYWNlIGRvZXMgbm90IGhhdmUgYW55IHVwIHRvIGRhdGUgbG9jYXRpb25cbiIpOwogICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0xPU1Q7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfREVWSUNFTE9TVDsKICAgIH0KCiAgICBpZihmbGFnID09IFNGTEFHX0lOU1lTTUVNKSB7CiAgICAgICAgc3VyZmFjZV9wcmVwYXJlX3N5c3RlbV9tZW1vcnkoVGhpcyk7CgogICAgICAgIC8qIERvd25sb2FkIHRoZSBzdXJmYWNlIHRvIHN5c3RlbSBtZW1vcnkgKi8KICAgICAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX0lOVEVYVFVSRSkgewogICAgICAgICAgICBzdXJmYWNlX2Rvd25sb2FkX2RhdGEoVGhpcyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmVhZF9mcm9tX2ZyYW1lYnVmZmVyKFRoaXMsIHJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfR2V0UGl0Y2goaWZhY2UpKTsKICAgICAgICB9CiAgICB9IGVsc2UgaWYoZmxhZyA9PSBTRkxBR19JTkRSQVdBQkxFKSB7CiAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19JTlRFWFRVUkUpIHsKICAgICAgICAgICAgc3VyZmFjZV9ibHRfdG9fZHJhd2FibGUoVGhpcywgcmVjdCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZmx1c2hfdG9fZnJhbWVidWZmZXJfZHJhd3BpeGVscyhUaGlzKTsKICAgICAgICB9CiAgICB9IGVsc2UgLyogaWYoZmxhZyA9PSBTRkxBR19JTlRFWFRVUkUpICovIHsKICAgICAgICBkM2RmbXRfZ2V0X2NvbnYoVGhpcywgVFJVRSAvKiBXZSBuZWVkIGNvbG9yIGtleWluZyAqLywgVFJVRSAvKiBXZSB3aWxsIHVzZSB0ZXh0dXJlcyAqLywgJmZvcm1hdCwgJmludGVybmFsLCAmdHlwZSwgJmNvbnZlcnQsICZicHAsIFRoaXMtPnNyZ2IpOwoKICAgICAgICBpZiAoVGhpcy0+RmxhZ3MgJiBTRkxBR19JTkRSQVdBQkxFKSB7CiAgICAgICAgICAgIEdMaW50IHByZXZSZWFkOwoKICAgICAgICAgICAgRU5URVJfR0woKTsKICAgICAgICAgICAgZ2xHZXRJbnRlZ2VydihHTF9SRUFEX0JVRkZFUiwgJnByZXZSZWFkKTsKICAgICAgICAgICAgdmNoZWNrR0xjYWxsKCJnbEdldEludGVnZXJ2Iik7CiAgICAgICAgICAgIGdsUmVhZEJ1ZmZlcihUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlLT5vZmZzY3JlZW5CdWZmZXIpOwogICAgICAgICAgICB2Y2hlY2tHTGNhbGwoImdsUmVhZEJ1ZmZlciIpOwoKICAgICAgICAgICAgaWYoIShUaGlzLT5GbGFncyAmIFNGTEFHX0FMTE9DQVRFRCkpIHsKICAgICAgICAgICAgICAgIHN1cmZhY2VfYWxsb2NhdGVfc3VyZmFjZShUaGlzLCBpbnRlcm5hbCwgVGhpcy0+cG93MldpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPnBvdzJIZWlnaHQsIGZvcm1hdCwgdHlwZSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNsZWFyX3VudXNlZF9jaGFubmVscyhUaGlzKTsKCiAgICAgICAgICAgIGdsQ29weVRleFN1YkltYWdlMkQoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLCAwLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmN1cnJlbnREZXNjLldpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbENvcHlUZXhTdWJJbWFnZTJEIik7CgogICAgICAgICAgICBnbFJlYWRCdWZmZXIocHJldlJlYWQpOwogICAgICAgICAgICB2Y2hlY2tHTGNhbGwoImdsUmVhZEJ1ZmZlciIpOwoKICAgICAgICAgICAgTEVBVkVfR0woKTsKCiAgICAgICAgICAgIFRSQUNFKCJVcGRhdGVkIHRhcmdldCAlZFxuIiwgVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8qIFRoZSBvbmx5IHBsYWNlIHdoZXJlIExvYWRUZXh0dXJlKCkgbWlnaHQgZ2V0IGNhbGxlZCB3aGVuIGlzSW5EcmF3PTEKICAgICAgICAgICAgICogaXMgQWN0aXZhdGVDb250ZXh0IHdoZXJlIGxhc3RBY3RpdmVSZW5kZXJUYXJnZXQgaXMgcHJlbG9hZGVkLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYoaWZhY2UgPT0gZGV2aWNlLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0ICYmIGRldmljZS0+aXNJbkRyYXcpCiAgICAgICAgICAgICAgICBFUlIoIlJlYWRpbmcgYmFjayByZW5kZXIgdGFyZ2V0IGJ1dCBTRkxBR19JTkRSQVdBQkxFIG5vdCBzZXRcbiIpOwoKICAgICAgICAgICAgLyogT3RoZXJ3aXNlOiBTeXN0ZW0gbWVtb3J5IGNvcHkgbXVzdCBiZSBtb3N0IHVwIHRvIGRhdGUgKi8KCiAgICAgICAgICAgIGlmKFRoaXMtPkNLZXlGbGFncyAmIFdJTkVERFNEX0NLU1JDQkxUKSB7CiAgICAgICAgICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19HTENLRVk7CiAgICAgICAgICAgICAgICBUaGlzLT5nbENLZXkgPSBUaGlzLT5TcmNCbHRDS2V5OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0dMQ0tFWTsKCiAgICAgICAgICAgIC8qIFRoZSB3aWR0aCBpcyBpbiAnbGVuZ3RoJyBub3QgaW4gYnl0ZXMgKi8KICAgICAgICAgICAgd2lkdGggPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICAgICAgcGl0Y2ggPSBJV2luZUQzRFN1cmZhY2VfR2V0UGl0Y2goaWZhY2UpOwoKICAgICAgICAgICAgaWYoKGNvbnZlcnQgIT0gTk9fQ09OVkVSU0lPTikgJiYgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KSB7CiAgICAgICAgICAgICAgICBpbnQgaGVpZ2h0ID0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0OwoKICAgICAgICAgICAgICAgIC8qIFN0aWNrIHRvIHRoZSBhbGlnbm1lbnQgZm9yIHRoZSBjb252ZXJ0ZWQgc3VyZmFjZSB0b28sIG1ha2VzIGl0IGVhc2llciB0byBsb2FkIHRoZSBzdXJmYWNlICovCiAgICAgICAgICAgICAgICBvdXRwaXRjaCA9IHdpZHRoICogYnBwOwogICAgICAgICAgICAgICAgb3V0cGl0Y2ggPSAob3V0cGl0Y2ggKyBkZXZpY2UtPnN1cmZhY2VfYWxpZ25tZW50IC0gMSkgJiB+KGRldmljZS0+c3VyZmFjZV9hbGlnbm1lbnQgLSAxKTsKCiAgICAgICAgICAgICAgICBtZW0gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb3V0cGl0Y2ggKiBoZWlnaHQpOwogICAgICAgICAgICAgICAgaWYoIW1lbSkgewogICAgICAgICAgICAgICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeSAlZCwgJWQhXG4iLCBvdXRwaXRjaCwgaGVpZ2h0KTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9PVVRPRlZJREVPTUVNT1JZOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZDNkZm10X2NvbnZlcnRfc3VyZmFjZShUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnksIG1lbSwgcGl0Y2gsIHdpZHRoLCBoZWlnaHQsIG91dHBpdGNoLCBjb252ZXJ0LCBUaGlzKTsKCiAgICAgICAgICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19DT05WRVJURUQ7CiAgICAgICAgICAgIH0gZWxzZSBpZiggKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX1A4KSAmJiAoR0xfU1VQUE9SVChFWFRfUEFMRVRURURfVEVYVFVSRSkgfHwgR0xfU1VQUE9SVChBUkJfRlJBR01FTlRfUFJPR1JBTSkpICkgewogICAgICAgICAgICAgICAgZDNkZm10X3A4X3VwbG9hZF9wYWxldHRlKGlmYWNlLCBjb252ZXJ0KTsKICAgICAgICAgICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19DT05WRVJURUQ7CiAgICAgICAgICAgICAgICBtZW0gPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfQ09OVkVSVEVEOwogICAgICAgICAgICAgICAgbWVtID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5OwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBNYWtlIHN1cmUgdGhlIGNvcnJlY3QgcGl0Y2ggaXMgdXNlZCAqLwogICAgICAgICAgICBnbFBpeGVsU3RvcmVpKEdMX1VOUEFDS19ST1dfTEVOR1RILCB3aWR0aCk7CgogICAgICAgICAgICBpZiAoKFRoaXMtPkZsYWdzICYgU0ZMQUdfTk9OUE9XMikgJiYgIShUaGlzLT5GbGFncyAmIFNGTEFHX09WRVJTSVpFKSkgewogICAgICAgICAgICAgICAgVFJBQ0UoIm5vbiBwb3dlciBvZiB0d28gc3VwcG9ydFxuIik7CiAgICAgICAgICAgICAgICBpZighKFRoaXMtPkZsYWdzICYgU0ZMQUdfQUxMT0NBVEVEKSkgewogICAgICAgICAgICAgICAgICAgIHN1cmZhY2VfYWxsb2NhdGVfc3VyZmFjZShUaGlzLCBpbnRlcm5hbCwgVGhpcy0+cG93MldpZHRoLCBUaGlzLT5wb3cySGVpZ2h0LCBmb3JtYXQsIHR5cGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKG1lbSB8fCAoVGhpcy0+RmxhZ3MgJiBTRkxBR19QQk8pKSB7CiAgICAgICAgICAgICAgICAgICAgc3VyZmFjZV91cGxvYWRfZGF0YShUaGlzLCBpbnRlcm5hbCwgVGhpcy0+Y3VycmVudERlc2MuV2lkdGgsIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCwgZm9ybWF0LCB0eXBlLCBtZW0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLyogV2hlbiBtYWtpbmcgdGhlIHJlYWxsb2MgY29uZGl0aW9uYWwsIGtlZXAgaW4gbWluZCB0aGF0IEdMX0FQUExFX2NsaWVudF9zdG9yYWdlIG1heSBiZSBpbiB1c2UsIGFuZCBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkKICAgICAgICAgICAgICAgICAqIGNoYW5nZWQuIFNvIGFsc28ga2VlcCB0cmFjayBvZiBtZW1vcnkgY2hhbmdlcy4gSW4gdGhpcyBjYXNlIHRoZSB0ZXh0dXJlIGhhcyB0byBiZSByZWFsbG9jYXRlZAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZighKFRoaXMtPkZsYWdzICYgU0ZMQUdfQUxMT0NBVEVEKSkgewogICAgICAgICAgICAgICAgICAgIHN1cmZhY2VfYWxsb2NhdGVfc3VyZmFjZShUaGlzLCBpbnRlcm5hbCwgVGhpcy0+Z2xSZWN0LnJpZ2h0IC0gVGhpcy0+Z2xSZWN0LmxlZnQsIFRoaXMtPmdsUmVjdC5ib3R0b20gLSBUaGlzLT5nbFJlY3QudG9wLCBmb3JtYXQsIHR5cGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKG1lbSB8fCAoVGhpcy0+RmxhZ3MgJiBTRkxBR19QQk8pKSB7CiAgICAgICAgICAgICAgICAgICAgc3VyZmFjZV91cGxvYWRfZGF0YShUaGlzLCBpbnRlcm5hbCwgVGhpcy0+Z2xSZWN0LnJpZ2h0IC0gVGhpcy0+Z2xSZWN0LmxlZnQsIFRoaXMtPmdsUmVjdC5ib3R0b20gLSBUaGlzLT5nbFJlY3QudG9wLCBmb3JtYXQsIHR5cGUsIG1lbSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIFJlc3RvcmUgdGhlIGRlZmF1bHQgcGl0Y2ggKi8KICAgICAgICAgICAgZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfUk9XX0xFTkdUSCwgMCk7CgogICAgICAgICAgICAvKiBEb24ndCBkZWxldGUgUEJPIG1lbW9yeSAqLwogICAgICAgICAgICBpZigobWVtICE9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgJiYgIShUaGlzLT5GbGFncyAmIFNGTEFHX1BCTykpCiAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtZW0pOwogICAgICAgIH0KICAgIH0KCiAgICBpZihyZWN0ID09IE5VTEwpIHsKICAgICAgICBUaGlzLT5GbGFncyB8PSBmbGFnOwogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NldENvbnRhaW5lcihJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBJV2luZUQzREJhc2UgKmNvbnRhaW5lcikgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBjaGFpbiA9IE5VTEw7CgogICAgLyogVXBkYXRlIHRoZSBkcmF3YWJsZSBzaXplIG1ldGhvZCAqLwogICAgaWYoY29udGFpbmVyKSB7CiAgICAgICAgSVdpbmVEM0RCYXNlX1F1ZXJ5SW50ZXJmYWNlKGNvbnRhaW5lciwgJklJRF9JV2luZUQzRFN3YXBDaGFpbiwgKHZvaWQgKiopICZzd2FwY2hhaW4pOwogICAgfQogICAgaWYoc3dhcGNoYWluKSB7CiAgICAgICAgVGhpcy0+Z2V0X2RyYXdhYmxlX3NpemUgPSBnZXRfZHJhd2FibGVfc2l6ZV9zd2FwY2hhaW47CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwY2hhaW4pOwogICAgfSBlbHNlIGlmKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgewogICAgICAgIHN3aXRjaCh3aW5lZDNkX3NldHRpbmdzLm9mZnNjcmVlbl9yZW5kZXJpbmdfbW9kZSkgewogICAgICAgICAgICBjYXNlIE9STV9GQk86ICAgICAgICBUaGlzLT5nZXRfZHJhd2FibGVfc2l6ZSA9IGdldF9kcmF3YWJsZV9zaXplX2ZibzsgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIE9STV9QQlVGRkVSOiAgICBUaGlzLT5nZXRfZHJhd2FibGVfc2l6ZSA9IGdldF9kcmF3YWJsZV9zaXplX3BidWZmZXI7ICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIE9STV9CQUNLQlVGRkVSOiBUaGlzLT5nZXRfZHJhd2FibGVfc2l6ZSA9IGdldF9kcmF3YWJsZV9zaXplX2JhY2tidWZmZXI7IGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfU2V0Q29udGFpbmVyKGlmYWNlLCBjb250YWluZXIpOwp9Cgpjb25zdCBJV2luZUQzRFN1cmZhY2VWdGJsIElXaW5lRDNEU3VyZmFjZV9WdGJsID0KewogICAgLyogSVVua25vd24gKi8KICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1F1ZXJ5SW50ZXJmYWNlLAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfQWRkUmVmLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZWxlYXNlLAogICAgLyogSVdpbmVEM0RSZXNvdXJjZSAqLwogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0UGFyZW50LAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0RGV2aWNlLAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfU2V0UHJpdmF0ZURhdGEsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXRQcml2YXRlRGF0YSwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0ZyZWVQcml2YXRlRGF0YSwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1NldFByaW9yaXR5LAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0UHJpb3JpdHksCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1ByZUxvYWQsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXRUeXBlLAogICAgLyogSVdpbmVEM0RTdXJmYWNlICovCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXRDb250YWluZXIsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXREZXNjLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9Mb2NrUmVjdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfVW5sb2NrUmVjdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0REMsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1JlbGVhc2VEQywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfRmxpcCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfQmx0LAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0Qmx0U3RhdHVzLAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0RmxpcFN0YXR1cywKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0lzTG9zdCwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1Jlc3RvcmUsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0JsdEZhc3QsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXRQYWxldHRlLAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfU2V0UGFsZXR0ZSwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1JlYWxpemVQYWxldHRlLAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfU2V0Q29sb3JLZXksCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXRQaXRjaCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0TWVtLAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfU2V0T3ZlcmxheVBvc2l0aW9uLAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0T3ZlcmxheVBvc2l0aW9uLAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfVXBkYXRlT3ZlcmxheVpPcmRlciwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1VwZGF0ZU92ZXJsYXksCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9TZXRDbGlwcGVyLAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0Q2xpcHBlciwKICAgIC8qIEludGVybmFsIHVzZTogKi8KICAgIElXaW5lRDNEU3VyZmFjZUltcGxfQWRkRGlydHlSZWN0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9Mb2FkVGV4dHVyZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfQmluZFRleHR1cmUsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NhdmVTbmFwc2hvdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0Q29udGFpbmVyLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRHbFRleHR1cmVEZXNjLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXRHbERlc2MsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0dldERhdGEsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldEZvcm1hdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfUHJpdmF0ZVNldHVwLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9Nb2RpZnlMb2NhdGlvbiwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfTG9hZExvY2F0aW9uCn07Cg==