LyoKICogSVdpbmVEM0RTdXJmYWNlIEltcGxlbWVudGF0aW9uCiAqCiAqIENvcHlyaWdodCAxOTk4IExpb25lbCBVbG1lcgogKiBDb3B5cmlnaHQgMjAwMC0yMDAxIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcyBJbmMuCiAqIENvcHlyaWdodCAyMDAyLTIwMDUgSmFzb24gRWRtZWFkZXMKICogQ29weXJpZ2h0IDIwMDItMjAwMyBSYXBoYWVsIEp1bnF1ZWlyYQogKiBDb3B5cmlnaHQgMjAwNCBDaHJpc3RpYW4gQ29zdGEKICogQ29weXJpZ2h0IDIwMDUgT2xpdmVyIFN0aWViZXIKICogQ29weXJpZ2h0IDIwMDYtMjAwOCBTdGVmYW4gRPZzaW5nZXIgZm9yIENvZGVXZWF2ZXJzCiAqIENvcHlyaWdodCAyMDA3IEhlbnJpIFZlcmJlZXQKICogQ29weXJpZ2h0IDIwMDYtMjAwOCBSb2RlcmljayBDb2xlbmJyYW5kZXIKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCiNpbmNsdWRlICJ3aW5lZDNkX3ByaXZhdGUuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGQzZF9zdXJmYWNlKTsKI2RlZmluZSBHTElORk9fTE9DQVRJT04gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZS0+YWRhcHRlci0+Z2xfaW5mbwoKSFJFU1VMVCBkM2RmbXRfY29udmVydF9zdXJmYWNlKEJZVEUgKnNyYywgQllURSAqZHN0LCBVSU5UIHBpdGNoLCBVSU5UIHdpZHRoLCBVSU5UIGhlaWdodCwgVUlOVCBvdXRwaXRjaCwgQ09OVkVSVF9UWVBFUyBjb252ZXJ0LCBJV2luZUQzRFN1cmZhY2VJbXBsICpzdXJmKTsKc3RhdGljIHZvaWQgZDNkZm10X3A4X2luaXRfcGFsZXR0ZShJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBCWVRFIHRhYmxlWzI1Nl1bNF0sIEJPT0wgY29sb3JrZXkpOwpzdGF0aWMgdm9pZCBkM2RmbXRfcDhfdXBsb2FkX3BhbGV0dGUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgQ09OVkVSVF9UWVBFUyBjb252ZXJ0KTsKc3RhdGljIGlubGluZSB2b2lkIGNsZWFyX3VudXNlZF9jaGFubmVscyhJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzKTsKc3RhdGljIHZvaWQgc3VyZmFjZV9yZW1vdmVfcGJvKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMpOwoKc3RhdGljIHZvaWQgc3VyZmFjZV9iaW5kX2FuZF9kaXJ0aWZ5KElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMpIHsKICAgIEdMaW50IGFjdGl2ZV90ZXh0dXJlOwoKICAgIC8qIFdlIGRvbid0IG5lZWQgYSBzcGVjaWZpYyB0ZXh0dXJlIHVuaXQsIGJ1dCBhZnRlciBiaW5kaW5nIHRoZSB0ZXh0dXJlIHRoZSBjdXJyZW50IHVuaXQgaXMgZGlydHkuCiAgICAgKiBSZWFkIHRoZSB1bml0IGJhY2sgaW5zdGVhZCBvZiBzd2l0Y2hpbmcgdG8gMCwgdGhpcyBhdm9pZHMgbWVzc2luZyBhcm91bmQgd2l0aCB0aGUgc3RhdGUgbWFuYWdlcidzCiAgICAgKiBnbCBzdGF0ZXMuIFRoZSBjdXJyZW50IHRleHR1cmUgdW5pdCBzaG91bGQgYWx3YXlzIGJlIGEgdmFsaWQgb25lLgogICAgICoKICAgICAqIFRPRE86IFRyYWNrIHRoZSBjdXJyZW50IGFjdGl2ZSB0ZXh0dXJlIHBlciBHTCBjb250ZXh0IGluc3RlYWQgb2YgdXNpbmcgZ2xHZXQKICAgICAqLwogICAgaWYgKEdMX1NVUFBPUlQoQVJCX01VTFRJVEVYVFVSRSkpIHsKICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfQUNUSVZFX1RFWFRVUkUsICZhY3RpdmVfdGV4dHVyZSk7CiAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICBhY3RpdmVfdGV4dHVyZSAtPSBHTF9URVhUVVJFMF9BUkI7CiAgICB9IGVsc2UgewogICAgICAgIGFjdGl2ZV90ZXh0dXJlID0gMDsKICAgIH0KICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlLCBTVEFURV9TQU1QTEVSKGFjdGl2ZV90ZXh0dXJlKSk7CiAgICBJV2luZUQzRFN1cmZhY2VfQmluZFRleHR1cmUoKElXaW5lRDNEU3VyZmFjZSAqKVRoaXMpOwp9CgovKiBUaGlzIGZ1bmN0aW9uIGNoZWNrcyBpZiB0aGUgcHJpbWFyeSByZW5kZXIgdGFyZ2V0IHVzZXMgdGhlIDhiaXQgcGFsZXR0ZWQgZm9ybWF0LiAqLwpzdGF0aWMgQk9PTCBwcmltYXJ5X3JlbmRlcl90YXJnZXRfaXNfcDgoSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UpCnsKICAgIGlmIChkZXZpY2UtPnJlbmRlcl90YXJnZXRzICYmIGRldmljZS0+cmVuZGVyX3RhcmdldHNbMF0pIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VJbXBsKiByZW5kZXJfdGFyZ2V0ID0gKElXaW5lRDNEU3VyZmFjZUltcGwqKWRldmljZS0+cmVuZGVyX3RhcmdldHNbMF07CiAgICAgICAgaWYoKHJlbmRlcl90YXJnZXQtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgJiYgKHJlbmRlcl90YXJnZXQtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX1A4KSkKICAgICAgICAgICAgcmV0dXJuIFRSVUU7CiAgICB9CiAgICByZXR1cm4gRkFMU0U7Cn0KCi8qIFRoaXMgY2FsbCBqdXN0IGRvd25sb2FkcyBkYXRhLCB0aGUgY2FsbGVyIGlzIHJlc3BvbnNpYmxlIGZvciBhY3RpdmF0aW5nIHRoZQogKiByaWdodCBjb250ZXh0IGFuZCBiaW5kaW5nIHRoZSBjb3JyZWN0IHRleHR1cmUuICovCnN0YXRpYyB2b2lkIHN1cmZhY2VfZG93bmxvYWRfZGF0YShJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzKSB7CiAgICBpZiAoMCA9PSBUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKSB7CiAgICAgICAgRVJSKCJTdXJmYWNlIGRvZXMgbm90IGhhdmUgYSB0ZXh0dXJlLCBidXQgU0ZMQUdfSU5URVhUVVJFIGlzIHNldFxuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8qIE9ubHkgc3VwcG9ydCByZWFkIGJhY2sgb2YgY29udmVydGVkIFA4IHN1cmZhY2VzICovCiAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX0NPTlZFUlRFRCAmJiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ICE9IFdJTkVEM0RGTVRfUDgpKSB7CiAgICAgICAgRklYTUUoIlJlYWQgYmFjayBjb252ZXJ0ZWQgdGV4dHVyZXMgdW5zdXBwb3J0ZWQsIGZvcm1hdD0lc1xuIiwgZGVidWdfZDNkZm9ybWF0KFRoaXMtPnJlc291cmNlLmZvcm1hdCkpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBFTlRFUl9HTCgpOwoKICAgIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQxIHx8CiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDIgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMyB8fAogICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ0IHx8IFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDUpIHsKICAgICAgICBpZiAoIUdMX1NVUFBPUlQoRVhUX1RFWFRVUkVfQ09NUFJFU1NJT05fUzNUQykpIHsgLyogV2UgY2FuIGFzc3VtZSB0aGlzIGFzIHRoZSB0ZXh0dXJlIHdvdWxkIG5vdCBoYXZlIGJlZW4gY3JlYXRlZCBvdGhlcndpc2UgKi8KICAgICAgICAgICAgRklYTUUoIiglcCkgOiBBdHRlbXB0aW5nIHRvIGxvY2sgYSBjb21wcmVzc2VkIHRleHR1cmUgd2hlbiB0ZXh0dXJlIGNvbXByZXNzaW9uIGlzbid0IHN1cHBvcnRlZCBieSBvcGVuZ2xcbiIsIFRoaXMpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIDogQ2FsbGluZyBnbEdldENvbXByZXNzZWRUZXhJbWFnZUFSQiBsZXZlbCAlZCwgZm9ybWF0ICUjeCwgdHlwZSAlI3gsIGRhdGEgJXBcbiIsIFRoaXMsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsCiAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmdsVHlwZSwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKCiAgICAgICAgICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfUEJPKSB7CiAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9QSVhFTF9QQUNLX0JVRkZFUl9BUkIsIFRoaXMtPnBibykpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZEJ1ZmZlckFSQiIpOwogICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEdldENvbXByZXNzZWRUZXhJbWFnZUFSQihUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwgTlVMTCkpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsR2V0Q29tcHJlc3NlZFRleEltYWdlQVJCKCkiKTsKICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kQnVmZmVyQVJCKEdMX1BJWEVMX1BBQ0tfQlVGRkVSX0FSQiwgMCkpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZEJ1ZmZlckFSQiIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEdldENvbXByZXNzZWRUZXhJbWFnZUFSQihUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZXRDb21wcmVzc2VkVGV4SW1hZ2VBUkIoKSIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIExFQVZFX0dMKCk7CiAgICB9IGVsc2UgewogICAgICAgIHZvaWQgKm1lbTsKICAgICAgICBHTGVudW0gZm9ybWF0ID0gVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdDsKICAgICAgICBHTGVudW0gdHlwZSA9IFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xUeXBlOwogICAgICAgIGludCBzcmNfcGl0Y2ggPSAwOwogICAgICAgIGludCBkc3RfcGl0Y2ggPSAwOwoKICAgICAgICAvKiBJbiBjYXNlIG9mIFA4IHRoZSBpbmRleCBpcyBzdG9yZWQgaW4gdGhlIGFscGhhIGNvbXBvbmVudCBpZiB0aGUgcHJpbWFyeSByZW5kZXIgdGFyZ2V0IHVzZXMgUDggKi8KICAgICAgICBpZihUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9QOCAmJiBwcmltYXJ5X3JlbmRlcl90YXJnZXRfaXNfcDgoVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZSkpIHsKICAgICAgICAgICAgZm9ybWF0ID0gR0xfQUxQSEE7CiAgICAgICAgICAgIHR5cGUgPSBHTF9VTlNJR05FRF9CWVRFOwogICAgICAgIH0KCiAgICAgICAgaWYgKFRoaXMtPkZsYWdzICYgU0ZMQUdfTk9OUE9XMikgewogICAgICAgICAgICB1bnNpZ25lZCBjaGFyIGFsaWdubWVudCA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UtPnN1cmZhY2VfYWxpZ25tZW50OwogICAgICAgICAgICBzcmNfcGl0Y2ggPSBUaGlzLT5ieXRlc1BlclBpeGVsICogVGhpcy0+cG93MldpZHRoOwogICAgICAgICAgICBkc3RfcGl0Y2ggPSBJV2luZUQzRFN1cmZhY2VfR2V0UGl0Y2goKElXaW5lRDNEU3VyZmFjZSAqKSBUaGlzKTsKICAgICAgICAgICAgc3JjX3BpdGNoID0gKHNyY19waXRjaCArIGFsaWdubWVudCAtIDEpICYgfihhbGlnbm1lbnQgLSAxKTsKICAgICAgICAgICAgbWVtID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNyY19waXRjaCAqIFRoaXMtPnBvdzJIZWlnaHQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG1lbSA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICB9CgogICAgICAgIFRSQUNFKCIoJXApIDogQ2FsbGluZyBnbEdldFRleEltYWdlIGxldmVsICVkLCBmb3JtYXQgJSN4LCB0eXBlICUjeCwgZGF0YSAlcFxuIiwgVGhpcywgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwKICAgICAgICAgICAgICAgIGZvcm1hdCwgdHlwZSwgbWVtKTsKCiAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19QQk8pIHsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEJpbmRCdWZmZXJBUkIoR0xfUElYRUxfUEFDS19CVUZGRVJfQVJCLCBUaGlzLT5wYm8pKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZEJ1ZmZlckFSQiIpOwoKICAgICAgICAgICAgZ2xHZXRUZXhJbWFnZShUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwgZm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUsIE5VTEwpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZXRUZXhJbWFnZSgpIik7CgogICAgICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9QSVhFTF9QQUNLX0JVRkZFUl9BUkIsIDApKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZEJ1ZmZlckFSQiIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGdsR2V0VGV4SW1hZ2UoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIGZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLCBtZW0pOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZXRUZXhJbWFnZSgpIik7CiAgICAgICAgfQogICAgICAgIExFQVZFX0dMKCk7CgogICAgICAgIGlmIChUaGlzLT5GbGFncyAmIFNGTEFHX05PTlBPVzIpIHsKICAgICAgICAgICAgTFBCWVRFIHNyY19kYXRhLCBkc3RfZGF0YTsKICAgICAgICAgICAgaW50IHk7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFNvbWUgZ2FtZXMgKGUuZy4gd2FyaGFtbWVyIDQwaykgZG9uJ3Qgd29yayBwcm9wZXJseSB3aXRoIHRoZSBvZGQgcGl0Y2hlcywgcHJldmVudGluZwogICAgICAgICAgICAgKiB0aGUgc3VyZmFjZSBwaXRjaCBmcm9tIGJlaW5nIHVzZWQgdG8gYm94IG5vbi1wb3dlcjIgdGV4dHVyZXMuIEluc3RlYWQgd2UgaGF2ZSB0byB1c2UgYSBoYWNrIHRvCiAgICAgICAgICAgICAqIHJlcGFjayB0aGUgdGV4dHVyZSBzbyB0aGF0IHRoZSBicHAgKiB3aWR0aCBwaXRjaCBjYW4gYmUgdXNlZCBpbnN0ZWFkIG9mIGJwcCAqIHBvdzJ3aWR0aC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogV2UncmUgZG9pbmcgdGhpcy4uLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBpbnN0ZWFkIG9mIGJveGluZyB0aGUgdGV4dHVyZSA6CiAgICAgICAgICAgICAqIHw8LXRleHR1cmUgd2lkdGggLT58ICAtLT5wb3cyd2lkdGh8ICAgL1wKICAgICAgICAgICAgICogfDExMTExMTExMTExMTExMTExMXwgICAgICAgICAgICAgIHwgICB8CiAgICAgICAgICAgICAqIHwyMjIgVGV4dHVyZSAyMjIyMjJ8IGJveGVkIGVtcHR5ICB8IHRleHR1cmUgaGVpZ2h0CiAgICAgICAgICAgICAqIHwzMzMzIERhdGEgMzMzMzMzMzN8ICAgICAgICAgICAgICB8ICAgfAogICAgICAgICAgICAgKiB8NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0fCAgICAgICAgICAgICAgfCAgIFwvCiAgICAgICAgICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICAgfAogICAgICAgICAgICAgKiB8ICAgICBib3hlZCAgZW1wdHkgfCBib3hlZCBlbXB0eSAgfCBwb3cyaGVpZ2h0CiAgICAgICAgICAgICAqIHwgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICB8ICAgXC8KICAgICAgICAgICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICoKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogd2UncmUgcmVwYWNraW5nIHRoZSBkYXRhIHRvIHRoZSBleHBlY3RlZCB0ZXh0dXJlIHdpZHRoCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIHw8LXRleHR1cmUgd2lkdGggLT58ICAtLT5wb3cyd2lkdGh8ICAgL1wKICAgICAgICAgICAgICogfDExMTExMTExMTExMTExMTExMTIyMjIyMjIyMjIyMjIyMnwgICB8CiAgICAgICAgICAgICAqIHwyMjIzMzMzMzMzMzMzMzMzMzMzMzM0NDQ0NDQ0NDQ0NDR8IHRleHR1cmUgaGVpZ2h0CiAgICAgICAgICAgICAqIHw0NDQ0NDQgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgfAogICAgICAgICAgICAgKiB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIFwvCiAgICAgICAgICAgICAqIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgfAogICAgICAgICAgICAgKiB8ICAgICAgICAgICAgZW1wdHkgICAgICAgICAgICAgICAgfCBwb3cyaGVpZ2h0CiAgICAgICAgICAgICAqIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgXC8KICAgICAgICAgICAgICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogPT0gaXMgdGhlIHNhbWUgYXMKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogfDwtdGV4dHVyZSB3aWR0aCAtPnwgICAgL1wKICAgICAgICAgICAgICogfDExMTExMTExMTExMTExMTExMXwKICAgICAgICAgICAgICogfDIyMjIyMjIyMjIyMjIyMjIyMnx0ZXh0dXJlIGhlaWdodAogICAgICAgICAgICAgKiB8MzMzMzMzMzMzMzMzMzMzMzMzfAogICAgICAgICAgICAgKiB8NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0fCAgICBcLwogICAgICAgICAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiB0aGlzIGFsc28gbWVhbnMgdGhhdCBhbnkgcmVmZXJlbmNlcyB0byBhbGxvY2F0ZWRNZW1vcnkgc2hvdWxkIHdvcmsgd2l0aCB0aGUgZGF0YSBhcyBpZiB3ZXJlIGEKICAgICAgICAgICAgICogc3RhbmRhcmQgdGV4dHVyZSB3aXRoIGEgbm9uLXBvd2VyMiB3aWR0aCBpbnN0ZWFkIG9mIHRleHR1cmUgYm94ZWQgdXAgdG8gYmUgYSBwb3dlcjIgdGV4dHVyZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogaW50ZXJuYWxseSB0aGUgdGV4dHVyZSBpcyBzdGlsbCBzdG9yZWQgaW4gYSBib3hlZCBmb3JtYXQgc28gYW55IHJlZmVyZW5jZXMgdG8gdGV4dHVyZU5hbWUgd2lsbAogICAgICAgICAgICAgKiBnZXQgYSBib3hlZCB0ZXh0dXJlIHdpdGggd2lkdGggcG93MndpZHRoIGFuZCBub3QgYSB0ZXh0dXJlIG9mIHdpZHRoIGN1cnJlbnREZXNjLldpZHRoLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBQZXJmb3JtYW5jZSBzaG91bGQgbm90IGJlIGFuIGlzc3VlLCBiZWNhdXNlIGFwcGxpY2F0aW9ucyBub3JtYWxseSBkbyBub3QgbG9jayB0aGUgc3VyZmFjZXMgd2hlbgogICAgICAgICAgICAgKiByZW5kZXJpbmcuIElmIGFuIGFwcCBkb2VzLCB0aGUgU0ZMQUdfRFlOTE9DSyBmbGFnIHdpbGwga2ljayBpbiBhbmQgdGhlIG1lbW9yeSBjb3B5IHdvbid0IGJlIHJlbGVhc2VkLAogICAgICAgICAgICAgKiBhbmQgZG9lc24ndCBoYXZlIHRvIGJlIHJlLXJlYWQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzcmNfZGF0YSA9IG1lbTsKICAgICAgICAgICAgZHN0X2RhdGEgPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIDogUmVwYWNraW5nIHRoZSBzdXJmYWNlIGRhdGEgZnJvbSBwaXRjaCAlZCB0byBwaXRjaCAlZFxuIiwgVGhpcywgc3JjX3BpdGNoLCBkc3RfcGl0Y2gpOwogICAgICAgICAgICBmb3IgKHkgPSAxIDsgeSA8IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsgeSsrKSB7CiAgICAgICAgICAgICAgICAvKiBza2lwIHRoZSBmaXJzdCByb3cgKi8KICAgICAgICAgICAgICAgIHNyY19kYXRhICs9IHNyY19waXRjaDsKICAgICAgICAgICAgICAgIGRzdF9kYXRhICs9IGRzdF9waXRjaDsKICAgICAgICAgICAgICAgIG1lbWNweShkc3RfZGF0YSwgc3JjX2RhdGEsIGRzdF9waXRjaCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1lbSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFN1cmZhY2UgaGFzIG5vdyBiZWVuIGRvd25sb2FkZWQgKi8KICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0lOU1lTTUVNOwp9CgovKiBUaGlzIGNhbGwganVzdCB1cGxvYWRzIGRhdGEsIHRoZSBjYWxsZXIgaXMgcmVzcG9uc2libGUgZm9yIGFjdGl2YXRpbmcgdGhlCiAqIHJpZ2h0IGNvbnRleHQgYW5kIGJpbmRpbmcgdGhlIGNvcnJlY3QgdGV4dHVyZS4gKi8Kc3RhdGljIHZvaWQgc3VyZmFjZV91cGxvYWRfZGF0YShJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBHTGVudW0gaW50ZXJuYWwsIEdMc2l6ZWkgd2lkdGgsIEdMc2l6ZWkgaGVpZ2h0LCBHTGVudW0gZm9ybWF0LCBHTGVudW0gdHlwZSwgY29uc3QgR0x2b2lkICpkYXRhKSB7CiAgICBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMSB8fAogICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQyIHx8IFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDMgfHwKICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNCB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ1KSB7CiAgICAgICAgaWYgKCFHTF9TVVBQT1JUKEVYVF9URVhUVVJFX0NPTVBSRVNTSU9OX1MzVEMpKSB7CiAgICAgICAgICAgIEZJWE1FKCJVc2luZyBEWFQxLzMvNSB3aXRob3V0IGFkdmVydGl6ZWQgc3VwcG9ydFxuIik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyogZ2xDb21wcmVzc2VkVGV4U3ViSW1hZ2UyRCBmb3IgdXBsb2FkaW5nIGFuZCBnbFRleEltYWdlMkQgZm9yIGFsbG9jYXRpbmcgZG9lcyBub3Qgd29yayB3ZWxsIG9uIHNvbWUgZHJpdmVycyhyMjAwIGRyaSwgTWFjT1MgQVRJIGRyaXZlcikKICAgICAgICAgICAgICogZ2xDb21wcmVzc2VkVGV4SW1hZ2UyRCBkb2VzIG5vdCBhY2NlcHQgTlVMTCBwb2ludGVycy4gU28gZm9yIGNvbXByZXNzZWQgdGV4dHVyZXMgc3VyZmFjZV9hbGxvY2F0ZV9zdXJmYWNlIGRvZXMgbm90aGluZywgYW5kIHRoaXMKICAgICAgICAgICAgICogZnVuY3Rpb24gdXNlcyBnbENvbXByZXNzZWRUZXhJbWFnZTJEIGluc3RlYWQgb2YgdGhlIFN1YkltYWdlIGNhbGwKICAgICAgICAgICAgICovCiAgICAgICAgICAgIFRSQUNFKCIoJXApIDogQ2FsbGluZyBnbENvbXByZXNzZWRUZXhTdWJJbWFnZTJEIHcgJWQsIGggJWQsIGRhdGEgJXBcbiIsIFRoaXMsIHdpZHRoLCBoZWlnaHQsIGRhdGEpOwogICAgICAgICAgICBFTlRFUl9HTCgpOwoKICAgICAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19QQk8pIHsKICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kQnVmZmVyQVJCKEdMX1BJWEVMX1VOUEFDS19CVUZGRVJfQVJCLCBUaGlzLT5wYm8pKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRCdWZmZXJBUkIiKTsKICAgICAgICAgICAgICAgIFRSQUNFKCIoJXApIHBibzogJSN4LCBkYXRhOiAlcFxuIiwgVGhpcywgVGhpcy0+cGJvLCBkYXRhKTsKCiAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsQ29tcHJlc3NlZFRleEltYWdlMkRBUkIoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIGludGVybmFsLAogICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCwgaGVpZ2h0LCAwIC8qIGJvcmRlciAqLywgVGhpcy0+cmVzb3VyY2Uuc2l6ZSwgTlVMTCkpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQ29tcHJlc3NlZFRleFN1YkltYWdlMkQiKTsKCiAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9QSVhFTF9VTlBBQ0tfQlVGRkVSX0FSQiwgMCkpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZEJ1ZmZlckFSQiIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbENvbXByZXNzZWRUZXhJbWFnZTJEQVJCKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCBpbnRlcm5hbCwKICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGgsIGhlaWdodCwgMCAvKiBib3JkZXIgKi8sIFRoaXMtPnJlc291cmNlLnNpemUsIGRhdGEpKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbENvbXByZXNzZWRUZXhTdWJJbWFnZTJEIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIFRSQUNFKCIoJXApIDogQ2FsbGluZyBnbFRleFN1YkltYWdlMkQgdyAlZCwgIGggJWQsIGRhdGEsICVwXG4iLCBUaGlzLCB3aWR0aCwgaGVpZ2h0LCBkYXRhKTsKICAgICAgICBFTlRFUl9HTCgpOwoKICAgICAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX1BCTykgewogICAgICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9QSVhFTF9VTlBBQ0tfQlVGRkVSX0FSQiwgVGhpcy0+cGJvKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRCdWZmZXJBUkIiKTsKICAgICAgICAgICAgVFJBQ0UoIiglcCkgcGJvOiAlI3gsIGRhdGE6ICVwXG4iLCBUaGlzLCBUaGlzLT5wYm8sIGRhdGEpOwoKICAgICAgICAgICAgZ2xUZXhTdWJJbWFnZTJEKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCAwLCAwLCB3aWR0aCwgaGVpZ2h0LCBmb3JtYXQsIHR5cGUsIE5VTEwpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhTdWJJbWFnZTJEIik7CgogICAgICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9QSVhFTF9VTlBBQ0tfQlVGRkVSX0FSQiwgMCkpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kQnVmZmVyQVJCIik7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBnbFRleFN1YkltYWdlMkQoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIDAsIDAsIHdpZHRoLCBoZWlnaHQsIGZvcm1hdCwgdHlwZSwgZGF0YSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleFN1YkltYWdlMkQiKTsKICAgICAgICB9CgogICAgICAgIExFQVZFX0dMKCk7CiAgICB9Cn0KCi8qIFRoaXMgY2FsbCBqdXN0IGFsbG9jYXRlcyB0aGUgdGV4dHVyZSwgdGhlIGNhbGxlciBpcyByZXNwb25zaWJsZSBmb3IKICogYWN0aXZhdGluZyB0aGUgcmlnaHQgY29udGV4dCBhbmQgYmluZGluZyB0aGUgY29ycmVjdCB0ZXh0dXJlLiAqLwpzdGF0aWMgdm9pZCBzdXJmYWNlX2FsbG9jYXRlX3N1cmZhY2UoSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcywgR0xlbnVtIGludGVybmFsLCBHTHNpemVpIHdpZHRoLCBHTHNpemVpIGhlaWdodCwgR0xlbnVtIGZvcm1hdCwgR0xlbnVtIHR5cGUpIHsKICAgIEJPT0wgZW5hYmxlX2NsaWVudF9zdG9yYWdlID0gRkFMU0U7CiAgICBCWVRFICptZW0gPSBOVUxMOwoKICAgIFRSQUNFKCIoJXApIDogQ3JlYXRpbmcgc3VyZmFjZSAodGFyZ2V0ICUjeCkgIGxldmVsICVkLCBkM2QgZm9ybWF0ICVzLCBpbnRlcm5hbCBmb3JtYXQgJSN4LCB3aWR0aCAlZCwgaGVpZ2h0ICVkLCBnbCBmb3JtYXQgJSN4LCBnbCB0eXBlPSUjeFxuIiwgVGhpcywKICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIGRlYnVnX2QzZGZvcm1hdChUaGlzLT5yZXNvdXJjZS5mb3JtYXQpLCBpbnRlcm5hbCwgd2lkdGgsIGhlaWdodCwgZm9ybWF0LCB0eXBlKTsKCiAgICBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMSB8fAogICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQyIHx8IFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDMgfHwKICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNCB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ1KSB7CiAgICAgICAgLyogZ2xDb21wcmVzc2VkVGV4SW1hZ2UyRCBkb2VzIG5vdCBhY2NlcHQgTlVMTCBwb2ludGVycywgc28gd2UgY2Fubm90IGFsbG9jYXRlIGEgY29tcHJlc3NlZCB0ZXh0dXJlIHdpdGhvdXQgdXBsb2FkaW5nIGRhdGEgKi8KICAgICAgICBUUkFDRSgiTm90IGFsbG9jYXRpbmcgY29tcHJlc3NlZCBzdXJmYWNlcywgc3VyZmFjZV91cGxvYWRfZGF0YSB3aWxsIHNwZWNpZnkgdGhlbVxuIik7CgogICAgICAgIC8qIFdlIGhhdmUgdG8gcG9pbnQgR0wgdG8gdGhlIGNsaWVudCBzdG9yYWdlIG1lbW9yeSBoZXJlLCBiZWNhdXNlIHVwbG9hZF9kYXRhIG1pZ2h0IHVzZSBhIFBCTy4gVGhpcyBtZWFucyBhIGRvdWJsZSB1cGxvYWQKICAgICAgICAgKiBvbmNlLCB1bmZvcnR1bmF0ZWx5CiAgICAgICAgICovCiAgICAgICAgaWYoR0xfU1VQUE9SVChBUFBMRV9DTElFTlRfU1RPUkFHRSkpIHsKICAgICAgICAgICAgLyogTmVpdGhlciBOT05QT1cyLCBESUJTRUNUSU9OIG5vciBPVkVSU0laRSBmbGFncyBjYW4gYmUgc2V0IG9uIGNvbXByZXNzZWQgdGV4dHVyZXMgKi8KICAgICAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfQ0xJRU5UOwogICAgICAgICAgICBtZW0gPSAoQllURSAqKSgoKFVMT05HX1BUUikgVGhpcy0+cmVzb3VyY2UuaGVhcE1lbW9yeSArIChSRVNPVVJDRV9BTElHTk1FTlQgLSAxKSkgJiB+KFJFU09VUkNFX0FMSUdOTUVOVCAtIDEpKTsKICAgICAgICAgICAgRU5URVJfR0woKTsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbENvbXByZXNzZWRUZXhJbWFnZTJEQVJCKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCBpbnRlcm5hbCwKICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCwgaGVpZ2h0LCAwIC8qIGJvcmRlciAqLywgVGhpcy0+cmVzb3VyY2Uuc2l6ZSwgbWVtKSk7CiAgICAgICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm47CiAgICB9CgogICAgRU5URVJfR0woKTsKCiAgICBpZihHTF9TVVBQT1JUKEFQUExFX0NMSUVOVF9TVE9SQUdFKSkgewogICAgICAgIGlmKFRoaXMtPkZsYWdzICYgKFNGTEFHX05PTlBPVzIgfCBTRkxBR19ESUJTRUNUSU9OIHwgU0ZMQUdfT1ZFUlNJWkUgfCBTRkxBR19DT05WRVJURUQpIHx8IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9PSBOVUxMKSB7CiAgICAgICAgICAgIC8qIEluIHNvbWUgY2FzZXMgd2Ugd2FudCB0byBkaXNhYmxlIGNsaWVudCBzdG9yYWdlLgogICAgICAgICAgICAgKiBTRkxBR19OT05QT1cyIGhhcyBhIGJpZ2dlciBvcGVuZ2wgdGV4dHVyZSB0aGFuIHRoZSBjbGllbnQgbWVtb3J5LCBhbmQgZGlmZmVyZW50IHBpdGNoZXMKICAgICAgICAgICAgICogU0ZMQUdfRElCU0VDVElPTjogRGlic2VjdGlvbnMgbWF5IGhhdmUgcmVhZCAvIHdyaXRlIHByb3RlY3Rpb25zIG9uIHRoZSBtZW1vcnkuIEF2b2lkIGlzc3Vlcy4uLgogICAgICAgICAgICAgKiBTRkxBR19PVkVSU0laRTogVGhlIGdsIHRleHR1cmUgaXMgc21hbGxlciB0aGFuIHRoZSBhbGxvY2F0ZWQgbWVtb3J5CiAgICAgICAgICAgICAqIFNGTEFHX0NPTlZFUlRFRDogVGhlIGNvbnZlcnNpb24gZGVzdGluYXRpb24gbWVtb3J5IGlzIGZyZWVkIGFmdGVyIGxvYWRpbmcgdGhlIHN1cmZhY2UKICAgICAgICAgICAgICogYWxsb2NhdGVkTWVtb3J5ID09IE5VTEw6IE5vdCBkZWZpbmVkIGluIHRoZSBleHRlbnNpb24uIFNlZW1zIHRvIGRpc2FibGUgY2xpZW50IHN0b3JhZ2UgZWZmZWN0aXZlbHkKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGdsUGl4ZWxTdG9yZWkoR0xfVU5QQUNLX0NMSUVOVF9TVE9SQUdFX0FQUExFLCBHTF9GQUxTRSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFBpeGVsU3RvcmVpKEdMX1VOUEFDS19DTElFTlRfU1RPUkFHRV9BUFBMRSwgR0xfRkFMU0UpIik7CiAgICAgICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19DTElFTlQ7CiAgICAgICAgICAgIGVuYWJsZV9jbGllbnRfc3RvcmFnZSA9IFRSVUU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfQ0xJRU5UOwoKICAgICAgICAgICAgLyogUG9pbnQgb3BlbmdsIHRvIG91ciBhbGxvY2F0ZWQgdGV4dHVyZSBtZW1vcnkuIERvIG5vdCB1c2UgcmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5IGhlcmUgYmVjYXVzZQogICAgICAgICAgICAgKiBpdCBtaWdodCBwb2ludCBpbnRvIGEgcGJvLiBJbnN0ZWFkIHVzZSBoZWFwTWVtb3J5LCBidXQgZ2V0IHRoZSBhbGlnbm1lbnQgcmlnaHQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBtZW0gPSAoQllURSAqKSgoKFVMT05HX1BUUikgVGhpcy0+cmVzb3VyY2UuaGVhcE1lbW9yeSArIChSRVNPVVJDRV9BTElHTk1FTlQgLSAxKSkgJiB+KFJFU09VUkNFX0FMSUdOTUVOVCAtIDEpKTsKICAgICAgICB9CiAgICB9CiAgICBnbFRleEltYWdlMkQoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsIGludGVybmFsLCB3aWR0aCwgaGVpZ2h0LCAwLCBmb3JtYXQsIHR5cGUsIG1lbSk7CiAgICBjaGVja0dMY2FsbCgiZ2xUZXhJbWFnZTJEIik7CgogICAgaWYoZW5hYmxlX2NsaWVudF9zdG9yYWdlKSB7CiAgICAgICAgZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfQ0xJRU5UX1NUT1JBR0VfQVBQTEUsIEdMX1RSVUUpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFBpeGVsU3RvcmVpKEdMX1VOUEFDS19DTElFTlRfU1RPUkFHRV9BUFBMRSwgR0xfVFJVRSkiKTsKICAgIH0KICAgIExFQVZFX0dMKCk7CgogICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfQUxMT0NBVEVEOwp9CgovKiBJbiBEM0QgdGhlIGRlcHRoIHN0ZW5jaWwgZGltZW5zaW9ucyBoYXZlIHRvIGJlIGdyZWF0ZXIgdGhhbiBvciBlcXVhbCB0byB0aGUKICogcmVuZGVyIHRhcmdldCBkaW1lbnNpb25zLiBXaXRoIEZCT3MsIHRoZSBkaW1lbnNpb25zIGhhdmUgdG8gYmUgYW4gZXhhY3QgbWF0Y2guICovCi8qIFRPRE86IFdlIHNob3VsZCBzeW5jaHJvbml6ZSB0aGUgcmVuZGVyYnVmZmVyJ3MgY29udGVudCB3aXRoIHRoZSB0ZXh0dXJlJ3MgY29udGVudC4gKi8Kdm9pZCBzdXJmYWNlX3NldF9jb21wYXRpYmxlX3JlbmRlcmJ1ZmZlcihJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCB1bnNpZ25lZCBpbnQgd2lkdGgsIHVuc2lnbmVkIGludCBoZWlnaHQpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgcmVuZGVyYnVmZmVyX2VudHJ5X3QgKmVudHJ5OwogICAgR0x1aW50IHJlbmRlcmJ1ZmZlciA9IDA7CiAgICB1bnNpZ25lZCBpbnQgc3JjX3dpZHRoLCBzcmNfaGVpZ2h0OwoKICAgIHNyY193aWR0aCA9IFRoaXMtPnBvdzJXaWR0aDsKICAgIHNyY19oZWlnaHQgPSBUaGlzLT5wb3cySGVpZ2h0OwoKICAgIC8qIEEgZGVwdGggc3RlbmNpbCBzbWFsbGVyIHRoYW4gdGhlIHJlbmRlciB0YXJnZXQgaXMgbm90IHZhbGlkICovCiAgICBpZiAod2lkdGggPiBzcmNfd2lkdGggfHwgaGVpZ2h0ID4gc3JjX2hlaWdodCkgcmV0dXJuOwoKICAgIC8qIFJlbW92ZSBhbnkgcmVuZGVyYnVmZmVyIHNldCBpZiB0aGUgc2l6ZXMgbWF0Y2ggKi8KICAgIGlmICh3aWR0aCA9PSBzcmNfd2lkdGggJiYgaGVpZ2h0ID09IHNyY19oZWlnaHQpIHsKICAgICAgICBUaGlzLT5jdXJyZW50X3JlbmRlcmJ1ZmZlciA9IE5VTEw7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8qIExvb2sgaWYgd2UndmUgYWxyZWFkeSBnb3QgYSByZW5kZXJidWZmZXIgb2YgdGhlIGNvcnJlY3QgZGltZW5zaW9ucyAqLwogICAgTElTVF9GT1JfRUFDSF9FTlRSWShlbnRyeSwgJlRoaXMtPnJlbmRlcmJ1ZmZlcnMsIHJlbmRlcmJ1ZmZlcl9lbnRyeV90LCBlbnRyeSkgewogICAgICAgIGlmIChlbnRyeS0+d2lkdGggPT0gd2lkdGggJiYgZW50cnktPmhlaWdodCA9PSBoZWlnaHQpIHsKICAgICAgICAgICAgcmVuZGVyYnVmZmVyID0gZW50cnktPmlkOwogICAgICAgICAgICBUaGlzLT5jdXJyZW50X3JlbmRlcmJ1ZmZlciA9IGVudHJ5OwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgaWYgKCFyZW5kZXJidWZmZXIpIHsKICAgICAgICBjb25zdCBHbFBpeGVsRm9ybWF0RGVzYyAqZ2xEZXNjOwogICAgICAgIGdldEZvcm1hdERlc2NFbnRyeShUaGlzLT5yZXNvdXJjZS5mb3JtYXQsICZHTElORk9fTE9DQVRJT04sICZnbERlc2MpOwoKICAgICAgICBHTF9FWFRDQUxMKGdsR2VuUmVuZGVyYnVmZmVyc0VYVCgxLCAmcmVuZGVyYnVmZmVyKSk7CiAgICAgICAgR0xfRVhUQ0FMTChnbEJpbmRSZW5kZXJidWZmZXJFWFQoR0xfUkVOREVSQlVGRkVSX0VYVCwgcmVuZGVyYnVmZmVyKSk7CiAgICAgICAgR0xfRVhUQ0FMTChnbFJlbmRlcmJ1ZmZlclN0b3JhZ2VFWFQoR0xfUkVOREVSQlVGRkVSX0VYVCwgZ2xEZXNjLT5nbEZvcm1hdCwgd2lkdGgsIGhlaWdodCkpOwoKICAgICAgICBlbnRyeSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YocmVuZGVyYnVmZmVyX2VudHJ5X3QpKTsKICAgICAgICBlbnRyeS0+d2lkdGggPSB3aWR0aDsKICAgICAgICBlbnRyeS0+aGVpZ2h0ID0gaGVpZ2h0OwogICAgICAgIGVudHJ5LT5pZCA9IHJlbmRlcmJ1ZmZlcjsKICAgICAgICBsaXN0X2FkZF9oZWFkKCZUaGlzLT5yZW5kZXJidWZmZXJzLCAmZW50cnktPmVudHJ5KTsKCiAgICAgICAgVGhpcy0+Y3VycmVudF9yZW5kZXJidWZmZXIgPSBlbnRyeTsKICAgIH0KCiAgICBjaGVja0dMY2FsbCgic2V0X2NvbXBhdGlibGVfcmVuZGVyYnVmZmVyIik7Cn0KCkdMZW51bSBzdXJmYWNlX2dldF9nbF9idWZmZXIoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBjaGFpbikgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN3YXBDaGFpbkltcGwgKnN3YXBjaGFpbl9pbXBsID0gKElXaW5lRDNEU3dhcENoYWluSW1wbCAqKXN3YXBjaGFpbjsKCiAgICBUUkFDRSgiKCVwKSA6IHN3YXBjaGFpbiAlcFxuIiwgVGhpcywgc3dhcGNoYWluKTsKCiAgICBpZiAoc3dhcGNoYWluX2ltcGwtPmJhY2tCdWZmZXIgJiYgc3dhcGNoYWluX2ltcGwtPmJhY2tCdWZmZXJbMF0gPT0gaWZhY2UpIHsKICAgICAgICBUUkFDRSgiUmV0dXJuaW5nIEdMX0JBQ0tcbiIpOwogICAgICAgIHJldHVybiBHTF9CQUNLOwogICAgfSBlbHNlIGlmIChzd2FwY2hhaW5faW1wbC0+ZnJvbnRCdWZmZXIgPT0gaWZhY2UpIHsKICAgICAgICBUUkFDRSgiUmV0dXJuaW5nIEdMX0ZST05UXG4iKTsKICAgICAgICByZXR1cm4gR0xfRlJPTlQ7CiAgICB9CgogICAgRklYTUUoIkhpZ2hlciBiYWNrIGJ1ZmZlciwgcmV0dXJuaW5nIEdMX0JBQ0tcbiIpOwogICAgcmV0dXJuIEdMX0JBQ0s7Cn0KClVMT05HIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1JlbGVhc2UoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVzb3VyY2UucmVmKTsKICAgIFRSQUNFKCIoJXApIDogUmVsZWFzaW5nIGZyb20gJWRcbiIsIFRoaXMsIHJlZiArIDEpOwogICAgaWYgKHJlZiA9PSAwKSB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgICAgIHJlbmRlcmJ1ZmZlcl9lbnRyeV90ICplbnRyeSwgKmVudHJ5MjsKICAgICAgICBUUkFDRSgiKCVwKSA6IGNsZWFuaW5nIHVwXG4iLCBUaGlzKTsKCiAgICAgICAgLyogTmVlZCBhIGNvbnRleHQgdG8gZGVzdHJveSB0aGUgdGV4dHVyZS4gVXNlIHRoZSBjdXJyZW50bHkgYWN0aXZlIHJlbmRlciB0YXJnZXQsIGJ1dCBvbmx5IGlmCiAgICAgICAgICogdGhlIHByaW1hcnkgcmVuZGVyIHRhcmdldCBleGlzdHMuIE90aGVyd2lzZSBsYXN0QWN0aXZlUmVuZGVyVGFyZ2V0IGlzIGdhcmJhZ2UsIHNlZSBhYm92ZS4KICAgICAgICAgKiBXaGVuIGRlc3Ryb3lpbmcgdGhlIHByaW1hcnkgcnQsIFVuaW5pdDNEIHdpbGwgYWN0aXZhdGUgYSBjb250ZXh0IGJlZm9yZSBkb2luZyBhbnl0aGluZwogICAgICAgICAqLwogICAgICAgIGlmKGRldmljZS0+cmVuZGVyX3RhcmdldHMgJiYgZGV2aWNlLT5yZW5kZXJfdGFyZ2V0c1swXSkgewogICAgICAgICAgICBBY3RpdmF0ZUNvbnRleHQoZGV2aWNlLCBkZXZpY2UtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQsIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CiAgICAgICAgfQoKICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgIGlmIChUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lICE9IDApIHsgLyogcmVsZWFzZSB0aGUgb3BlbkdMIHRleHR1cmUuLiAqLwogICAgICAgICAgICBUUkFDRSgiRGVsZXRpbmcgdGV4dHVyZSAlZFxuIiwgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgICAgIGdsRGVsZXRlVGV4dHVyZXMoMSwgJlRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgIH0KCiAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19QQk8pIHsKICAgICAgICAgICAgLyogRGVsZXRlIHRoZSBQQk8gKi8KICAgICAgICAgICAgR0xfRVhUQ0FMTChnbERlbGV0ZUJ1ZmZlcnNBUkIoMSwgJlRoaXMtPnBibykpOwogICAgICAgIH0KCiAgICAgICAgTElTVF9GT1JfRUFDSF9FTlRSWV9TQUZFKGVudHJ5LCBlbnRyeTIsICZUaGlzLT5yZW5kZXJidWZmZXJzLCByZW5kZXJidWZmZXJfZW50cnlfdCwgZW50cnkpIHsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbERlbGV0ZVJlbmRlcmJ1ZmZlcnNFWFQoMSwgJmVudHJ5LT5pZCkpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBlbnRyeSk7CiAgICAgICAgfQogICAgICAgIExFQVZFX0dMKCk7CgogICAgICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfRElCU0VDVElPTikgewogICAgICAgICAgICAvKiBSZWxlYXNlIHRoZSBEQyAqLwogICAgICAgICAgICBTZWxlY3RPYmplY3QoVGhpcy0+aERDLCBUaGlzLT5kaWIuaG9sZGJpdG1hcCk7CiAgICAgICAgICAgIERlbGV0ZURDKFRoaXMtPmhEQyk7CiAgICAgICAgICAgIC8qIFJlbGVhc2UgdGhlIERJQiBzZWN0aW9uICovCiAgICAgICAgICAgIERlbGV0ZU9iamVjdChUaGlzLT5kaWIuRElCc2VjdGlvbik7CiAgICAgICAgICAgIFRoaXMtPmRpYi5iaXRtYXBfZGF0YSA9IE5VTEw7CiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfVVNFUlBUUikgSVdpbmVEM0RTdXJmYWNlX1NldE1lbShpZmFjZSwgTlVMTCk7CgogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnBhbGV0dGU5KTsKCiAgICAgICAgSVdpbmVEM0RSZXNvdXJjZUltcGxfQ2xlYW5VcCgoSVdpbmVEM0RSZXNvdXJjZSAqKWlmYWNlKTsKICAgICAgICBpZihpZmFjZSA9PSBkZXZpY2UtPmRkcmF3X3ByaW1hcnkpCiAgICAgICAgICAgIGRldmljZS0+ZGRyYXdfcHJpbWFyeSA9IE5VTEw7CgogICAgICAgIFRSQUNFKCIoJXApIFJlbGVhc2VkXG4iLCBUaGlzKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKCiAgICB9CiAgICByZXR1cm4gcmVmOwp9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgIElXaW5lRDNEU3VyZmFjZSBJV2luZUQzRFJlc291cmNlIHBhcnRzIGZvbGxvdwogICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovCgp2b2lkIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1ByZUxvYWQoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgLyogVE9ETzogY2hlY2sgZm9yIGxvY2tzICovCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEQmFzZVRleHR1cmUgKmJhc2VUZXh0dXJlID0gTlVMTDsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqZGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKCiAgICBUUkFDRSgiKCVwKUNoZWNraW5nIHRvIHNlZSBpZiB0aGUgY29udGFpbmVyIGlzIGEgYmFzZSB0ZXh0dXJlXG4iLCBUaGlzKTsKICAgIGlmIChJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKGlmYWNlLCAmSUlEX0lXaW5lRDNEQmFzZVRleHR1cmUsICh2b2lkICoqKSZiYXNlVGV4dHVyZSkgPT0gV0lORUQzRF9PSykgewogICAgICAgIFRSQUNFKCJQYXNzaW5nIHRvIGNvbnRhaW5lclxuIik7CiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9QcmVMb2FkKGJhc2VUZXh0dXJlKTsKICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX1JlbGVhc2UoYmFzZVRleHR1cmUpOwogICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgiKCVwKSA6IEFib3V0IHRvIGxvYWQgc3VyZmFjZVxuIiwgVGhpcyk7CgogICAgICAgIGlmKCFkZXZpY2UtPmlzSW5EcmF3KSB7CiAgICAgICAgICAgIEFjdGl2YXRlQ29udGV4dChkZXZpY2UsIGRldmljZS0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKICAgICAgICB9CgogICAgICAgIGlmIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9QOCB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9BOFA4KSB7CiAgICAgICAgICAgIGlmKHBhbGV0dGU5X2NoYW5nZWQoVGhpcykpIHsKICAgICAgICAgICAgICAgIFRSQUNFKCJSZWxvYWRpbmcgc3VyZmFjZSBiZWNhdXNlIHRoZSBkM2Q4LzkgcGFsZXR0ZSB3YXMgY2hhbmdlZFxuIik7CiAgICAgICAgICAgICAgICAvKiBUT0RPOiBUaGlzIGlzIG5vdCBuZWNlc3NhcmlseSBuZWVkZWQgd2l0aCBodyBwYWxldHRpemVkIHRleHR1cmUgc3VwcG9ydCAqLwogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvYWRMb2NhdGlvbihpZmFjZSwgU0ZMQUdfSU5TWVNNRU0sIE5VTEwpOwogICAgICAgICAgICAgICAgLyogTWFrZSBzdXJlIHRoZSB0ZXh0dXJlIGlzIHJlbG9hZGVkIGJlY2F1c2Ugb2YgdGhlIHBhbGV0dGUgY2hhbmdlLCB0aGlzIGtpbGxzIHBlcmZvcm1hbmNlIHRob3VnaCA6KCAqLwogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX01vZGlmeUxvY2F0aW9uKGlmYWNlLCBTRkxBR19JTlRFWFRVUkUsIEZBTFNFKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgIGdsRW5hYmxlKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0KTsvKiBtYWtlIHN1cmUgdGV4dHVyZSBzdXBwb3J0IGlzIGVuYWJsZWQgaW4gdGhpcyBjb250ZXh0ICovCiAgICAgICAgaWYgKCFUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsKSB7CiAgICAgICAgICAgIGlmICghVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSkgewogICAgICAgICAgICAgICAgZ2xHZW5UZXh0dXJlcygxLCAmVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZW5UZXh0dXJlcyIpOwogICAgICAgICAgICAgICAgVFJBQ0UoIlN1cmZhY2UgJXAgZ2l2ZW4gbmFtZSAlZFxuIiwgVGhpcywgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZ2xCaW5kVGV4dHVyZShUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRUZXh0dXJlIik7CiAgICAgICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9Mb2FkVGV4dHVyZShpZmFjZSwgRkFMU0UpOwogICAgICAgICAgICAvKiBUaGlzIGlzIHdoZXJlIHdlIHNob3VsZCBiZSByZWR1Y2luZyB0aGUgYW1vdW50IG9mIEdMTWVtb3J5VXNlZCAqLwogICAgICAgIH0gZWxzZSBpZiAoVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSkgeyAvKiBOT1RFOiB0aGUgbGV2ZWwgMCBzdXJmYWNlIG9mIGEgbXBtYXBwZWQgdGV4dHVyZSBtdXN0IGJlIGxvYWRlZCBmaXJzdCEgKi8KICAgICAgICAgICAgLyogYXNzdW1lIHRoaXMgaXMgYSBjb2RpbmcgZXJyb3Igbm90IGEgcmVhbCBlcnJvciBmb3Igbm93ICovCiAgICAgICAgICAgIEZJWE1FKCJNaXBtYXAgc3VyZmFjZSBoYXMgYSBnbFRleHR1cmUgYm91bmQgdG8gaXQhXG4iKTsKICAgICAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICB9CiAgICAgICAgaWYgKFRoaXMtPnJlc291cmNlLnBvb2wgPT0gV0lORUQzRFBPT0xfREVGQVVMVCkgewogICAgICAgICAgICAvKiBUZWxsIG9wZW5nbCB0byB0cnkgYW5kIGtlZXAgdGhpcyB0ZXh0dXJlIGluIHZpZGVvIHJhbSAod2VsbCBtb3N0bHkpICovCiAgICAgICAgICAgIEdMY2xhbXBmIHRtcDsKICAgICAgICAgICAgdG1wID0gMC45ZjsKICAgICAgICAgICAgRU5URVJfR0woKTsKICAgICAgICAgICAgZ2xQcmlvcml0aXplVGV4dHVyZXMoMSwgJlRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUsICZ0bXApOwogICAgICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybjsKfQoKc3RhdGljIHZvaWQgc3VyZmFjZV9yZW1vdmVfcGJvKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMpIHsKICAgIFRoaXMtPnJlc291cmNlLmhlYXBNZW1vcnkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSAsMCAsIFRoaXMtPnJlc291cmNlLnNpemUgKyBSRVNPVVJDRV9BTElHTk1FTlQpOwogICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0KICAgICAgICAgICAgKEJZVEUgKikoKChVTE9OR19QVFIpIFRoaXMtPnJlc291cmNlLmhlYXBNZW1vcnkgKyAoUkVTT1VSQ0VfQUxJR05NRU5UIC0gMSkpICYgfihSRVNPVVJDRV9BTElHTk1FTlQgLSAxKSk7CgogICAgRU5URVJfR0woKTsKICAgIEdMX0VYVENBTEwoZ2xCaW5kQnVmZmVyQVJCKEdMX1BJWEVMX1VOUEFDS19CVUZGRVJfQVJCLCBUaGlzLT5wYm8pKTsKICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRCdWZmZXIoR0xfUElYRUxfVU5QQUNLX0JVRkZFUiwgVGhpcy0+cGJvKSIpOwogICAgR0xfRVhUQ0FMTChnbEdldEJ1ZmZlclN1YkRhdGFBUkIoR0xfUElYRUxfVU5QQUNLX0JVRkZFUl9BUkIsIDAsIFRoaXMtPnJlc291cmNlLnNpemUsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkpOwogICAgY2hlY2tHTGNhbGwoImdsR2V0QnVmZmVyU3ViRGF0YSIpOwogICAgR0xfRVhUQ0FMTChnbERlbGV0ZUJ1ZmZlcnNBUkIoMSwgJlRoaXMtPnBibykpOwogICAgY2hlY2tHTGNhbGwoImdsRGVsZXRlQnVmZmVycyIpOwogICAgTEVBVkVfR0woKTsKCiAgICBUaGlzLT5wYm8gPSAwOwogICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX1BCTzsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfVW5Mb2FkKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIElXaW5lRDNEQmFzZVRleHR1cmUgKnRleHR1cmUgPSBOVUxMOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgcmVuZGVyYnVmZmVyX2VudHJ5X3QgKmVudHJ5LCAqZW50cnkyOwogICAgVFJBQ0UoIiglcClcbiIsIGlmYWNlKTsKCiAgICBpZihUaGlzLT5yZXNvdXJjZS5wb29sID09IFdJTkVEM0RQT09MX0RFRkFVTFQpIHsKICAgICAgICAvKiBEZWZhdWx0IHBvb2wgcmVzb3VyY2VzIGFyZSBzdXBwb3NlZCB0byBiZSBkZXN0cm95ZWQgYmVmb3JlIFJlc2V0IGlzIGNhbGxlZC4KICAgICAgICAgKiBJbXBsaWNpdCByZXNvdXJjZXMgc3RheSBob3dldmVyLiBTbyB0aGlzIG1lYW5zIHdlIGhhdmUgYW4gaW1wbGljaXQgcmVuZGVyIHRhcmdldAogICAgICAgICAqIG9yIGRlcHRoIHN0ZW5jaWwuIFRoZSBjb250ZW50IG1heSBiZSBkZXN0cm95ZWQsIGJ1dCB3ZSBzdGlsbCBoYXZlIHRvIHRlYXIgZG93bgogICAgICAgICAqIG9wZW5nbCByZXNvdXJjZXMsIHNvIHdlIGNhbm5vdCBsZWF2ZSBlYXJseS4KICAgICAgICAgKgogICAgICAgICAqIFB1dCB0aGUgbW9zdCB1cCB0byBkYXRlIHN1cmZhY2UgbG9jYXRpb24gaW50byB0aGUgZHJhd2FibGUuIEQzRC13aXNlIHRoaXMgY29udGVudAogICAgICAgICAqIGlzIHVuZGVmaW5lZCwgc28gaXQgd291bGQgYmUgbm93aGVyZSwgYnV0IHRoYXQgd291bGQgbWFrZSB0aGUgbG9jYXRpb24gbWFuYWdlbWVudAogICAgICAgICAqIG1vcmUgY29tcGxpY2F0ZWQuIFRoZSBkcmF3YWJsZSBpcyBhIHNhbmUgbG9jYXRpb24sIGJlY2F1c2UgaWYgd2UgbWFyayBzeXNtZW0gb3IKICAgICAgICAgKiB0ZXh0dXJlIHVwIHRvIGRhdGUsIGRyYXdQcmltIHdpbGwgY29weSB0aGUgdW5pbml0aWFsaXplZCB0ZXh0dXJlIG9yIHN5c21lbSB0byB0aGUKICAgICAgICAgKiB1bmluaXRpYWxpemVkIGRyYXdhYmxlLiBUaGF0J3MgcG9pbnRsZXNzIGFuZCB3ZSdkIGhhdmUgdG8gYWxsb2NhdGUgdGhlIHRleHR1cmUgLwogICAgICAgICAqIHN5c21lbSBjb3B5IGhlcmUuCiAgICAgICAgICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX01vZGlmeUxvY2F0aW9uKGlmYWNlLCBTRkxBR19JTkRSQVdBQkxFLCBUUlVFKTsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogTG9hZCB0aGUgc3VyZmFjZSBpbnRvIHN5c3RlbSBtZW1vcnkgKi8KICAgICAgICBJV2luZUQzRFN1cmZhY2VfTG9hZExvY2F0aW9uKGlmYWNlLCBTRkxBR19JTlNZU01FTSwgTlVMTCk7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX01vZGlmeUxvY2F0aW9uKGlmYWNlLCBTRkxBR19JTkRSQVdBQkxFLCBGQUxTRSk7CiAgICB9CiAgICBJV2luZUQzRFN1cmZhY2VfTW9kaWZ5TG9jYXRpb24oaWZhY2UsIFNGTEFHX0lOVEVYVFVSRSwgRkFMU0UpOwogICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0FMTE9DQVRFRDsKCiAgICAvKiBEZXN0cm95IFBCT3MsIGJ1dCBsb2FkIHRoZW0gaW50byByZWFsIHN5c21lbSBiZWZvcmUgKi8KICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfUEJPKSB7CiAgICAgICAgc3VyZmFjZV9yZW1vdmVfcGJvKFRoaXMpOwogICAgfQoKICAgIC8qIERlc3Ryb3kgZmJvIHJlbmRlciBidWZmZXJzLiBUaGlzIGlzIG5lZWRlZCBmb3IgaW1wbGljaXQgcmVuZGVyIHRhcmdldHMsIGZvcgogICAgICogYWxsIGFwcGxpY2F0aW9uLWNyZWF0ZWQgdGFyZ2V0cyB0aGUgYXBwbGljYXRpb24gaGFzIHRvIHJlbGVhc2UgdGhlIHN1cmZhY2UKICAgICAqIGJlZm9yZSBjYWxsaW5nIF9SZXNldAogICAgICovCiAgICBMSVNUX0ZPUl9FQUNIX0VOVFJZX1NBRkUoZW50cnksIGVudHJ5MiwgJlRoaXMtPnJlbmRlcmJ1ZmZlcnMsIHJlbmRlcmJ1ZmZlcl9lbnRyeV90LCBlbnRyeSkgewogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgR0xfRVhUQ0FMTChnbERlbGV0ZVJlbmRlcmJ1ZmZlcnNFWFQoMSwgJmVudHJ5LT5pZCkpOwogICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgbGlzdF9yZW1vdmUoJmVudHJ5LT5lbnRyeSk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZW50cnkpOwogICAgfQogICAgbGlzdF9pbml0KCZUaGlzLT5yZW5kZXJidWZmZXJzKTsKICAgIFRoaXMtPmN1cnJlbnRfcmVuZGVyYnVmZmVyID0gTlVMTDsKCiAgICAvKiBJZiB3ZSdyZSBpbiBhIHRleHR1cmUsIHRoZSB0ZXh0dXJlIG5hbWUgYmVsb25ncyB0byB0aGUgdGV4dHVyZS4gT3RoZXJ3aXNlLAogICAgICogZGVzdHJveSBpdAogICAgICovCiAgICBJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKGlmYWNlLCAmSUlEX0lXaW5lRDNEQmFzZVRleHR1cmUsICh2b2lkICoqKSAmdGV4dHVyZSk7CiAgICBpZighdGV4dHVyZSkgewogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgZ2xEZWxldGVUZXh0dXJlcygxLCAmVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSA9IDA7CiAgICAgICAgTEVBVkVfR0woKTsKICAgIH0gZWxzZSB7CiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9SZWxlYXNlKHRleHR1cmUpOwogICAgfQogICAgcmV0dXJuOwp9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgSVdpbmVEM0RTdXJmYWNlIElXaW5lRDNEU3VyZmFjZSBwYXJ0cyBmb2xsb3cKICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovCgp2b2lkIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NldEdsVGV4dHVyZURlc2MoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgVUlOVCB0ZXh0dXJlTmFtZSwgaW50IHRhcmdldCkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IHNldHRpbmcgdGV4dHVyZU5hbWUgJXUsIHRhcmdldCAlaVxuIiwgVGhpcywgdGV4dHVyZU5hbWUsIHRhcmdldCk7CiAgICBpZiAoVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSA9PSAwICYmIHRleHR1cmVOYW1lICE9IDApIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfTW9kaWZ5TG9jYXRpb24oaWZhY2UsIFNGTEFHX0lOVEVYVFVSRSwgRkFMU0UpOwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9BZGREaXJ0eVJlY3QoaWZhY2UsIE5VTEwpOwogICAgfQogICAgaWYodGFyZ2V0ID09IEdMX1RFWFRVUkVfUkVDVEFOR0xFX0FSQiAmJiBUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCAhPSB0YXJnZXQpIHsKICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfTk9STUNPT1JEOwogICAgfSBlbHNlIGlmKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0ID09IEdMX1RFWFRVUkVfUkVDVEFOR0xFX0FSQiAmJiB0YXJnZXQgIT0gR0xfVEVYVFVSRV9SRUNUQU5HTEVfQVJCKSB7CiAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfTk9STUNPT1JEOwogICAgfQogICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSA9IHRleHR1cmVOYW1lOwogICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQgICAgICA9IHRhcmdldDsKICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19BTExPQ0FURUQ7Cn0KCnZvaWQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0R2xEZXNjKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIGdsRGVzY3JpcHRvciAqKmdsRGVzY3JpcHRpb24pIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiByZXR1cm5pbmcgJXBcbiIsIFRoaXMsICZUaGlzLT5nbERlc2NyaXB0aW9uKTsKICAgICpnbERlc2NyaXB0aW9uID0gJlRoaXMtPmdsRGVzY3JpcHRpb247Cn0KCi8qIFRPRE86IHRoaW5rIGFib3V0IG1vdmluZyB0aGlzIGRvd24gdG8gcmVzb3VyY2U/ICovCmNvbnN0IHZvaWQgKldJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0dldERhdGEoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICAvKiBUaGlzIHNob3VsZCBvbmx5IGJlIGNhbGxlZCBmb3Igc3lzbWVtIHRleHR1cmVzLCBpdCBtYXkgYmUgYSBnb29kIGlkZWEgdG8gZXh0ZW5kIHRoaXMgdG8gYWxsIHBvb2xzIGF0IHNvbWUgcG9pbnQgaW4gdGhlIGZ1dHVyZSAgKi8KICAgIGlmIChUaGlzLT5yZXNvdXJjZS5wb29sICE9IFdJTkVEM0RQT09MX1NZU1RFTU1FTSkgewogICAgICAgIEZJWE1FKCIgKCVwKUF0dGVtcHRpbmcgdG8gZ2V0IHN5c3RlbSBtZW1vcnkgZm9yIGEgbm9uLXN5c3RlbSBtZW1vcnkgdGV4dHVyZVxuIiwgaWZhY2UpOwogICAgfQogICAgcmV0dXJuIChDT05TVCB2b2lkKikoVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKfQoKLyogUmVhZCB0aGUgZnJhbWVidWZmZXIgYmFjayBpbnRvIHRoZSBzdXJmYWNlICovCnN0YXRpYyB2b2lkIHJlYWRfZnJvbV9mcmFtZWJ1ZmZlcihJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBDT05TVCBSRUNUICpyZWN0LCB2b2lkICpkZXN0LCBVSU5UIHBpdGNoKSB7CiAgICBJV2luZUQzRFN3YXBDaGFpbkltcGwgKnN3YXBjaGFpbjsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqbXlEZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgQllURSAqbWVtOwogICAgR0xpbnQgZm10OwogICAgR0xpbnQgdHlwZTsKICAgIEJZVEUgKnJvdywgKnRvcCwgKmJvdHRvbTsKICAgIGludCBpOwogICAgQk9PTCBicHA7CiAgICBSRUNUIGxvY2FsX3JlY3Q7CiAgICBCT09MIHNyY0lzVXBzaWRlRG93bjsKCiAgICBpZih3aW5lZDNkX3NldHRpbmdzLnJlbmRlcnRhcmdldGxvY2tfbW9kZSA9PSBSVExfRElTQUJMRSkgewogICAgICAgIHN0YXRpYyBCT09MIHdhcm5lZCA9IEZBTFNFOwogICAgICAgIGlmKCF3YXJuZWQpIHsKICAgICAgICAgICAgRVJSKCJUaGUgYXBwbGljYXRpb24gdHJpZXMgdG8gbG9jayB0aGUgcmVuZGVyIHRhcmdldCwgYnV0IHJlbmRlciB0YXJnZXQgbG9ja2luZyBpcyBkaXNhYmxlZFxuIik7CiAgICAgICAgICAgIHdhcm5lZCA9IFRSVUU7CiAgICAgICAgfQogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKChJV2luZUQzRFN1cmZhY2UgKikgVGhpcywgJklJRF9JV2luZUQzRFN3YXBDaGFpbiwgKHZvaWQgKiopJnN3YXBjaGFpbik7CiAgICAvKiBBY3RpdmF0ZSB0aGUgc3VyZmFjZS4gU2V0IGl0IHVwIGZvciBibGl0dGluZyBub3csIGFsdGhvdWdoIG5vdCBuZWNlc3NhcmlseSBuZWVkZWQgZm9yIExvY2tSZWN0LgogICAgICogQ2VydGFpbiBncmFwaGljcyBkcml2ZXJzIHNlZW0gdG8gZGlzbGlrZSBzb21lIGVuYWJsZWQgc3RhdGVzIHdoZW4gcmVhZGluZyBmcm9tIG9wZW5nbCwgdGhlIGJsaXR0aW5nIHVzYWdlCiAgICAgKiBzaG91bGQgaGVscCBoZXJlLiBGdXJ0aGVybW9yZSB1bmxvY2tyZWN0IHdpbGwgbmVlZCB0aGUgY29udGV4dCBzZXQgdXAgZm9yIGJsaXR0aW5nLiBUaGUgY29udGV4dCBtYW5hZ2VyIHdpbGwgZmluZAogICAgICogY29udGV4dC0+bGFzdF93YXNfYmxpdCBzZXQgb24gdGhlIHVubG9jay4KICAgICAqLwogICAgQWN0aXZhdGVDb250ZXh0KG15RGV2aWNlLCAoSVdpbmVEM0RTdXJmYWNlICopIFRoaXMsIENUWFVTQUdFX0JMSVQpOwogICAgRU5URVJfR0woKTsKCiAgICAvKiBTZWxlY3QgdGhlIGNvcnJlY3QgcmVhZCBidWZmZXIsIGFuZCBnaXZlIHNvbWUgZGVidWcgb3V0cHV0LgogICAgICogVGhlcmUgaXMgbm8gbmVlZCB0byBrZWVwIHRyYWNrIG9mIHRoZSBjdXJyZW50IHJlYWQgYnVmZmVyIG9yIHJlc2V0IGl0LCBldmVyeSBwYXJ0IG9mIHRoZSBjb2RlCiAgICAgKiB0aGF0IHJlYWRzIHNldHMgdGhlIHJlYWQgYnVmZmVyIGFzIGRlc2lyZWQuCiAgICAgKi8KICAgIGlmKCFzd2FwY2hhaW4pIHsKICAgICAgICAvKiBMb2NraW5nIHRoZSBwcmltYXJ5IHJlbmRlciB0YXJnZXQgd2hpY2ggaXMgbm90IG9uIGEgc3dhcGNoYWluKD1vZmZzY3JlZW4gcmVuZGVyIHRhcmdldCkuCiAgICAgICAgICogUmVhZCBmcm9tIHRoZSBiYWNrIGJ1ZmZlcgogICAgICAgICAqLwogICAgICAgIFRSQUNFKCJMb2NraW5nIG9mZnNjcmVlbiByZW5kZXIgdGFyZ2V0XG4iKTsKICAgICAgICBnbFJlYWRCdWZmZXIobXlEZXZpY2UtPm9mZnNjcmVlbkJ1ZmZlcik7CiAgICAgICAgc3JjSXNVcHNpZGVEb3duID0gVFJVRTsKICAgIH0gZWxzZSB7CiAgICAgICAgR0xlbnVtIGJ1ZmZlciA9IHN1cmZhY2VfZ2V0X2dsX2J1ZmZlcigoSVdpbmVEM0RTdXJmYWNlICopIFRoaXMsIChJV2luZUQzRFN3YXBDaGFpbiAqKXN3YXBjaGFpbik7CiAgICAgICAgVFJBQ0UoIkxvY2tpbmcgJSN4IGJ1ZmZlclxuIiwgYnVmZmVyKTsKICAgICAgICBnbFJlYWRCdWZmZXIoYnVmZmVyKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xSZWFkQnVmZmVyIik7CgogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElXaW5lRDNEU3dhcENoYWluICopIHN3YXBjaGFpbik7CiAgICAgICAgc3JjSXNVcHNpZGVEb3duID0gRkFMU0U7CiAgICB9CgogICAgLyogVE9ETzogR2V0IHJpZCBvZiB0aGUgZXh0cmEgcmVjdGFuZ2xlIGNvbXBhcmlzb24gYW5kIGNvbnN0cnVjdGlvbiBvZiBhIGZ1bGwgc3VyZmFjZSByZWN0YW5nbGUgKi8KICAgIGlmKCFyZWN0KSB7CiAgICAgICAgbG9jYWxfcmVjdC5sZWZ0ID0gMDsKICAgICAgICBsb2NhbF9yZWN0LnRvcCA9IDA7CiAgICAgICAgbG9jYWxfcmVjdC5yaWdodCA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgIGxvY2FsX3JlY3QuYm90dG9tID0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgfSBlbHNlIHsKICAgICAgICBsb2NhbF9yZWN0ID0gKnJlY3Q7CiAgICB9CiAgICAvKiBUT0RPOiBHZXQgcmlkIG9mIHRoZSBleHRyYSBHZXRQaXRjaCBjYWxsLCBMb2NrUmVjdCBkb2VzIHRoYXQgdG9vLiBDYWNoZSB0aGUgcGl0Y2ggKi8KCiAgICBzd2l0Y2goVGhpcy0+cmVzb3VyY2UuZm9ybWF0KQogICAgewogICAgICAgIGNhc2UgV0lORUQzREZNVF9QODoKICAgICAgICB7CiAgICAgICAgICAgIGlmKHByaW1hcnlfcmVuZGVyX3RhcmdldF9pc19wOChteURldmljZSkpIHsKICAgICAgICAgICAgICAgIC8qIEluIGNhc2Ugb2YgUDggcmVuZGVyIHRhcmdldHMgdGhlIGluZGV4IGlzIHN0b3JlZCBpbiB0aGUgYWxwaGEgY29tcG9uZW50ICovCiAgICAgICAgICAgICAgICBmbXQgPSBHTF9BTFBIQTsKICAgICAgICAgICAgICAgIHR5cGUgPSBHTF9VTlNJR05FRF9CWVRFOwogICAgICAgICAgICAgICAgbWVtID0gZGVzdDsKICAgICAgICAgICAgICAgIGJwcCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvKiBHTCBjYW4ndCByZXR1cm4gcGFsZXR0aXplZCBkYXRhLCBzbyByZWFkIEFSR0IgcGl4ZWxzIGludG8gYQogICAgICAgICAgICAgICAgICogc2VwYXJhdGUgYmxvY2sgb2YgbWVtb3J5IGFuZCBjb252ZXJ0IHRoZW0gaW50byBwYWxldHRpemVkIGZvcm1hdAogICAgICAgICAgICAgICAgICogaW4gc29mdHdhcmUuIFNsb3csIGJ1dCBpZiB0aGUgYXBwIG1lYW5zIHRvIHVzZSBwYWxldHRpemVkIHJlbmRlcgogICAgICAgICAgICAgICAgICogdGFyZ2V0cyBhbmQgbG9ja3MgaXQuLi4KICAgICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICAgKiBVc2UgR0xfUkdCLCBHTF9VTlNJR05FRF9CWVRFIHRvIHJlYWQgdGhlIHN1cmZhY2UgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMKICAgICAgICAgICAgICAgICAqIERvbid0IHVzZSBHTF9CR1IgYXMgaW4gdGhlIFdJTkVEM0RGTVRfUjhHOEI4IGNhc2UsIGluc3RlYWQgd2F0Y2ggb3V0CiAgICAgICAgICAgICAgICAgKiBmb3IgdGhlIGNvbG9yIGNoYW5uZWxzIHdoZW4gcGFsZXR0aXppbmcgdGhlIGNvbG9ycy4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgZm10ID0gR0xfUkdCOwogICAgICAgICAgICAgICAgdHlwZSA9IEdMX1VOU0lHTkVEX0JZVEU7CiAgICAgICAgICAgICAgICBwaXRjaCAqPSAzOwogICAgICAgICAgICAgICAgbWVtID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnJlc291cmNlLnNpemUgKiAzKTsKICAgICAgICAgICAgICAgIGlmKCFtZW0pIHsKICAgICAgICAgICAgICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnlcbiIpOwogICAgICAgICAgICAgICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnBwID0gVGhpcy0+Ynl0ZXNQZXJQaXhlbCAqIDM7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIG1lbSA9IGRlc3Q7CiAgICAgICAgICAgIGZtdCA9IFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXQ7CiAgICAgICAgICAgIHR5cGUgPSBUaGlzLT5nbERlc2NyaXB0aW9uLmdsVHlwZTsKICAgICAgICAgICAgYnBwID0gVGhpcy0+Ynl0ZXNQZXJQaXhlbDsKICAgIH0KCiAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX1BCTykgewogICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kQnVmZmVyQVJCKEdMX1BJWEVMX1BBQ0tfQlVGRkVSX0FSQiwgVGhpcy0+cGJvKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZEJ1ZmZlckFSQiIpOwogICAgfQoKICAgIGdsUmVhZFBpeGVscyhsb2NhbF9yZWN0LmxlZnQsIGxvY2FsX3JlY3QudG9wLAogICAgICAgICAgICAgICAgIGxvY2FsX3JlY3QucmlnaHQgLSBsb2NhbF9yZWN0LmxlZnQsCiAgICAgICAgICAgICAgICAgbG9jYWxfcmVjdC5ib3R0b20gLSBsb2NhbF9yZWN0LnRvcCwKICAgICAgICAgICAgICAgICBmbXQsIHR5cGUsIG1lbSk7CiAgICB2Y2hlY2tHTGNhbGwoImdsUmVhZFBpeGVscyIpOwoKICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfUEJPKSB7CiAgICAgICAgR0xfRVhUQ0FMTChnbEJpbmRCdWZmZXJBUkIoR0xfUElYRUxfUEFDS19CVUZGRVJfQVJCLCAwKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZEJ1ZmZlckFSQiIpOwoKICAgICAgICAvKiBDaGVjayBpZiB3ZSBuZWVkIHRvIGZsaXAgdGhlIGltYWdlLiBJZiB3ZSBuZWVkIHRvIGZsaXAgdXNlIGdsTWFwQnVmZmVyQVJCCiAgICAgICAgICogdG8gZ2V0IGEgcG9pbnRlciB0byBpdCBhbmQgcGVyZm9ybSB0aGUgZmxpcHBpbmcgaW4gc29mdHdhcmUuIFRoaXMgaXMgYSBsb3QKICAgICAgICAgKiBmYXN0ZXIgdGhhbiBjYWxsaW5nIGdsUmVhZFBpeGVscyBmb3IgZWFjaCBsaW5lLiBJbiBjYXNlIHdlIHdhbnQgbW9yZSBzcGVlZAogICAgICAgICAqIHdlIHNob3VsZCByZXJlbmRlciBpdCBmbGlwcGVkIGluIGEgRkJPIGFuZCByZWFkIHRoZSBkYXRhIGJhY2sgZnJvbSB0aGUgRkJPLiAqLwogICAgICAgIGlmKCFzcmNJc1Vwc2lkZURvd24pIHsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEJpbmRCdWZmZXJBUkIoR0xfUElYRUxfVU5QQUNLX0JVRkZFUl9BUkIsIFRoaXMtPnBibykpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kQnVmZmVyQVJCIik7CgogICAgICAgICAgICBtZW0gPSBHTF9FWFRDQUxMKGdsTWFwQnVmZmVyQVJCKEdMX1BJWEVMX1VOUEFDS19CVUZGRVJfQVJCLCBHTF9SRUFEX1dSSVRFX0FSQikpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xNYXBCdWZmZXJBUkIiKTsKICAgICAgICB9CiAgICB9CgogICAgLyogVE9ETzogTWVyZ2UgdGhpcyB3aXRoIHRoZSBwYWxldHRpemF0aW9uIGxvb3AgYmVsb3cgZm9yIFA4IHRhcmdldHMgKi8KICAgIGlmKCFzcmNJc1Vwc2lkZURvd24pIHsKICAgICAgICBVSU5UIGxlbiwgb2ZmOwogICAgICAgIC8qIGdsUmVhZFBpeGVscyByZXR1cm5zIHRoZSBpbWFnZSB1cHNpZGUgZG93biwgYW5kIHRoZXJlIGlzIG5vIHdheSB0byBwcmV2ZW50IHRoaXMuCiAgICAgICAgICAgIEZsaXAgdGhlIGxpbmVzIGluIHNvZnR3YXJlICovCiAgICAgICAgbGVuID0gKGxvY2FsX3JlY3QucmlnaHQgLSBsb2NhbF9yZWN0LmxlZnQpICogYnBwOwogICAgICAgIG9mZiA9IGxvY2FsX3JlY3QubGVmdCAqIGJwcDsKCiAgICAgICAgcm93ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbik7CiAgICAgICAgaWYoIXJvdykgewogICAgICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnlcbiIpOwogICAgICAgICAgICBpZihUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9QOCkgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbWVtKTsKICAgICAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KCiAgICAgICAgdG9wID0gbWVtICsgcGl0Y2ggKiBsb2NhbF9yZWN0LnRvcDsKICAgICAgICBib3R0b20gPSBtZW0gKyBwaXRjaCAqICggbG9jYWxfcmVjdC5ib3R0b20gLSBsb2NhbF9yZWN0LnRvcCAtIDEpOwogICAgICAgIGZvcihpID0gMDsgaSA8IChsb2NhbF9yZWN0LmJvdHRvbSAtIGxvY2FsX3JlY3QudG9wKSAvIDI7IGkrKykgewogICAgICAgICAgICBtZW1jcHkocm93LCB0b3AgKyBvZmYsIGxlbik7CiAgICAgICAgICAgIG1lbWNweSh0b3AgKyBvZmYsIGJvdHRvbSArIG9mZiwgbGVuKTsKICAgICAgICAgICAgbWVtY3B5KGJvdHRvbSArIG9mZiwgcm93LCBsZW4pOwogICAgICAgICAgICB0b3AgKz0gcGl0Y2g7CiAgICAgICAgICAgIGJvdHRvbSAtPSBwaXRjaDsKICAgICAgICB9CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcm93KTsKCiAgICAgICAgLyogVW5tYXAgdGhlIHRlbXAgUEJPIGJ1ZmZlciAqLwogICAgICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfUEJPKSB7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xVbm1hcEJ1ZmZlckFSQihHTF9QSVhFTF9VTlBBQ0tfQlVGRkVSX0FSQikpOwogICAgICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9QSVhFTF9VTlBBQ0tfQlVGRkVSX0FSQiwgMCkpOwogICAgICAgIH0KICAgIH0KCiAgICBMRUFWRV9HTCgpOwoKICAgIC8qIEZvciBQOCB0ZXh0dXJlcyB3ZSBuZWVkIHRvIHBlcmZvcm0gYW4gaW52ZXJzZSBwYWxldHRlIGxvb2t1cC4gVGhpcyBpcyBkb25lIGJ5IHNlYXJjaGluZyBmb3IgYSBwYWxldHRlCiAgICAgKiBpbmRleCB3aGljaCBtYXRjaGVzIHRoZSBSR0IgdmFsdWUuIE5vdGUgdGhpcyBpc24ndCBndWFyYW50ZWVkIHRvIHdvcmsgd2hlbiB0aGVyZSBhcmUgbXVsdGlwbGUgZW50cmllcyBmb3IKICAgICAqIHRoZSBzYW1lIGNvbG9yIGJ1dCB3ZSBoYXZlIG5vIGNob2ljZS4KICAgICAqIEluIGNhc2Ugb2YgUDggcmVuZGVyIHRhcmdldHMsIHRoZSBpbmRleCBpcyBzdG9yZWQgaW4gdGhlIGFscGhhIGNvbXBvbmVudCBzbyBubyBjb252ZXJzaW9uIGlzIG5lZWRlZC4KICAgICAqLwogICAgaWYoKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX1A4KSAmJiAhcHJpbWFyeV9yZW5kZXJfdGFyZ2V0X2lzX3A4KG15RGV2aWNlKSkgewogICAgICAgIFBBTEVUVEVFTlRSWSAqcGFsID0gTlVMTDsKICAgICAgICBEV09SRCB3aWR0aCA9IHBpdGNoIC8gMzsKICAgICAgICBpbnQgeCwgeSwgYzsKCiAgICAgICAgaWYoVGhpcy0+cGFsZXR0ZSkgewogICAgICAgICAgICBwYWwgPSBUaGlzLT5wYWxldHRlLT5wYWxlbnRzOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIEVSUigiUGFsZXR0ZSBpcyBtaXNzaW5nLCBjYW5ub3QgcGVyZm9ybSBpbnZlcnNlIHBhbGV0dGUgbG9va3VwXG4iKTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbWVtKTsKICAgICAgICAgICAgcmV0dXJuIDsKICAgICAgICB9CgogICAgICAgIGZvcih5ID0gbG9jYWxfcmVjdC50b3A7IHkgPCBsb2NhbF9yZWN0LmJvdHRvbTsgeSsrKSB7CiAgICAgICAgICAgIGZvcih4ID0gbG9jYWxfcmVjdC5sZWZ0OyB4IDwgbG9jYWxfcmVjdC5yaWdodDsgeCsrKSB7CiAgICAgICAgICAgICAgICAvKiAgICAgICAgICAgICAgICAgICAgICBzdGFydCAgICAgICAgICAgICAgbGluZXMgICAgICAgICAgICBwaXhlbHMgICAgICAqLwogICAgICAgICAgICAgICAgQllURSAqYmx1ZSA9ICBtZW0gKyB5ICogcGl0Y2ggKyB4ICogKHNpemVvZihCWVRFKSAqIDMpOwogICAgICAgICAgICAgICAgQllURSAqZ3JlZW4gPSBibHVlICArIDE7CiAgICAgICAgICAgICAgICBCWVRFICpyZWQgPSAgIGdyZWVuICsgMTsKCiAgICAgICAgICAgICAgICBmb3IoYyA9IDA7IGMgPCAyNTY7IGMrKykgewogICAgICAgICAgICAgICAgICAgIGlmKCpyZWQgICA9PSBwYWxbY10ucGVSZWQgICAmJgogICAgICAgICAgICAgICAgICAgICAgICpncmVlbiA9PSBwYWxbY10ucGVHcmVlbiAmJgogICAgICAgICAgICAgICAgICAgICAgICpibHVlICA9PSBwYWxbY10ucGVCbHVlKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgKigoQllURSAqKSBkZXN0ICsgeSAqIHdpZHRoICsgeCkgPSBjOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbWVtKTsKICAgIH0KfQoKLyogUmVhZCB0aGUgZnJhbWVidWZmZXIgY29udGVudHMgaW50byBhIHRleHR1cmUgKi8Kc3RhdGljIHZvaWQgcmVhZF9mcm9tX2ZyYW1lYnVmZmVyX3RleHR1cmUoSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcykKewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICpzd2FwY2hhaW47CiAgICBpbnQgYnBwOwogICAgR0xlbnVtIGZvcm1hdCwgaW50ZXJuYWwsIHR5cGU7CiAgICBDT05WRVJUX1RZUEVTIGNvbnZlcnQ7CiAgICBHTGludCBwcmV2UmVhZDsKCiAgICBkM2RmbXRfZ2V0X2NvbnYoVGhpcywgVFJVRSAvKiBXZSBuZWVkIGNvbG9yIGtleWluZyAqLywgVFJVRSAvKiBXZSB3aWxsIHVzZSB0ZXh0dXJlcyAqLywgJmZvcm1hdCwgJmludGVybmFsLCAmdHlwZSwgJmNvbnZlcnQsICZicHAsIFRoaXMtPnNyZ2IpOwoKICAgIElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoKElXaW5lRDNEU3VyZmFjZSAqKSBUaGlzLCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikmc3dhcGNoYWluKTsKICAgIC8qIEFjdGl2YXRlIHRoZSBzdXJmYWNlLiBTZXQgaXQgdXAgZm9yIGJsaXR0aW5nIG5vdywgYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IG5lZWRlZCBmb3IgTG9ja1JlY3QuCiAgICAgKiBDZXJ0YWluIGdyYXBoaWNzIGRyaXZlcnMgc2VlbSB0byBkaXNsaWtlIHNvbWUgZW5hYmxlZCBzdGF0ZXMgd2hlbiByZWFkaW5nIGZyb20gb3BlbmdsLCB0aGUgYmxpdHRpbmcgdXNhZ2UKICAgICAqIHNob3VsZCBoZWxwIGhlcmUuIEZ1cnRoZXJtb3JlIHVubG9ja3JlY3Qgd2lsbCBuZWVkIHRoZSBjb250ZXh0IHNldCB1cCBmb3IgYmxpdHRpbmcuIFRoZSBjb250ZXh0IG1hbmFnZXIgd2lsbCBmaW5kCiAgICAgKiBjb250ZXh0LT5sYXN0X3dhc19ibGl0IHNldCBvbiB0aGUgdW5sb2NrLgogICAgICovCiAgICBBY3RpdmF0ZUNvbnRleHQoZGV2aWNlLCAoSVdpbmVEM0RTdXJmYWNlICopIFRoaXMsIENUWFVTQUdFX0JMSVQpOwogICAgc3VyZmFjZV9iaW5kX2FuZF9kaXJ0aWZ5KFRoaXMpOwogICAgRU5URVJfR0woKTsKCiAgICBnbEdldEludGVnZXJ2KEdMX1JFQURfQlVGRkVSLCAmcHJldlJlYWQpOwoKICAgIC8qIFNlbGVjdCB0aGUgY29ycmVjdCByZWFkIGJ1ZmZlciwgYW5kIGdpdmUgc29tZSBkZWJ1ZyBvdXRwdXQuCiAgICAgKiBUaGVyZSBpcyBubyBuZWVkIHRvIGtlZXAgdHJhY2sgb2YgdGhlIGN1cnJlbnQgcmVhZCBidWZmZXIgb3IgcmVzZXQgaXQsIGV2ZXJ5IHBhcnQgb2YgdGhlIGNvZGUKICAgICAqIHRoYXQgcmVhZHMgc2V0cyB0aGUgcmVhZCBidWZmZXIgYXMgZGVzaXJlZC4KICAgICAqLwogICAgaWYoIXN3YXBjaGFpbikgewogICAgICAgIC8qIExvY2tpbmcgdGhlIHByaW1hcnkgcmVuZGVyIHRhcmdldCB3aGljaCBpcyBub3Qgb24gYSBzd2FwY2hhaW4oPW9mZnNjcmVlbiByZW5kZXIgdGFyZ2V0KS4KICAgICAgICAgKiBSZWFkIGZyb20gdGhlIGJhY2sgYnVmZmVyCiAgICAgICAgICovCiAgICAgICAgVFJBQ0UoIkxvY2tpbmcgb2Zmc2NyZWVuIHJlbmRlciB0YXJnZXRcbiIpOwogICAgICAgIGdsUmVhZEJ1ZmZlcihkZXZpY2UtPm9mZnNjcmVlbkJ1ZmZlcik7CiAgICB9IGVsc2UgewogICAgICAgIEdMZW51bSBidWZmZXIgPSBzdXJmYWNlX2dldF9nbF9idWZmZXIoKElXaW5lRDNEU3VyZmFjZSAqKSBUaGlzLCAoSVdpbmVEM0RTd2FwQ2hhaW4gKilzd2FwY2hhaW4pOwogICAgICAgIFRSQUNFKCJMb2NraW5nICUjeCBidWZmZXJcbiIsIGJ1ZmZlcik7CiAgICAgICAgZ2xSZWFkQnVmZmVyKGJ1ZmZlcik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsUmVhZEJ1ZmZlciIpOwoKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKChJV2luZUQzRFN3YXBDaGFpbiAqKSBzd2FwY2hhaW4pOwogICAgfQoKICAgIGlmKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19BTExPQ0FURUQpKSB7CiAgICAgICAgc3VyZmFjZV9hbGxvY2F0ZV9zdXJmYWNlKFRoaXMsIGludGVybmFsLCBUaGlzLT5wb3cyV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPnBvdzJIZWlnaHQsIGZvcm1hdCwgdHlwZSk7CiAgICB9CgogICAgY2xlYXJfdW51c2VkX2NoYW5uZWxzKFRoaXMpOwoKICAgIC8qIElmICFTcmNJc1Vwc2lkZURvd24gd2Ugc2hvdWxkIGZsaXAgdGhlIHN1cmZhY2UuCiAgICAgKiBUaGlzIGNhbiBiZSBkb25lIHVzaW5nIGdsQ29weVRleFN1YkltYWdlMkQgYnV0IHRoaXMKICAgICAqIGlzIFZFUlkgc2xvdywgc28gZG9uJ3QgZG8gdGhhdC4gV2Ugc2hvdWxkIHByZXZlbnQKICAgICAqIHRoaXMgY29kZSBmcm9tIGdldHRpbmcgY2FsbGVkIGluIHN1Y2ggY2FzZXMgb3IgcGVyaGFwcwogICAgICogd2UgY2FuIHVzZSBGQk9zICovCgogICAgZ2xDb3B5VGV4U3ViSW1hZ2UyRChUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+Y3VycmVudERlc2MuV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCk7CiAgICBjaGVja0dMY2FsbCgiZ2xDb3B5VGV4U3ViSW1hZ2UyRCIpOwoKICAgIGdsUmVhZEJ1ZmZlcihwcmV2UmVhZCk7CiAgICB2Y2hlY2tHTGNhbGwoImdsUmVhZEJ1ZmZlciIpOwoKICAgIExFQVZFX0dMKCk7CiAgICBUUkFDRSgiVXBkYXRlZCB0YXJnZXQgJWRcbiIsIFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0KTsKfQoKc3RhdGljIHZvaWQgc3VyZmFjZV9wcmVwYXJlX3N5c3RlbV9tZW1vcnkoSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcykgewogICAgLyogUGVyZm9ybWFuY2Ugb3B0aW1pemF0aW9uOiBDb3VudCBob3cgb2Z0ZW4gYSBzdXJmYWNlIGlzIGxvY2tlZCwgaWYgaXQgaXMgbG9ja2VkIHJlZ3VsYXJseSBkbyBub3QgdGhyb3cgYXdheSB0aGUgc3lzdGVtIG1lbW9yeSBjb3B5LgogICAgICogVGhpcyBhdm9pZHMgdGhlIG5lZWQgdG8gZG93bmxvYWQgdGhlIHN1cmZhY2UgZnJvbSBvcGVuZ2wgYWxsIHRoZSB0aW1lLiBUaGUgc3VyZmFjZSBpcyBzdGlsbCBkb3dubG9hZGVkIGlmIHRoZSBvcGVuZ2wgdGV4dHVyZSBpcwogICAgICogY2hhbmdlZAogICAgICovCiAgICBpZighKFRoaXMtPkZsYWdzICYgU0ZMQUdfRFlOTE9DSykpIHsKICAgICAgICBUaGlzLT5sb2NrQ291bnQrKzsKICAgICAgICAvKiBNQVhMT0NLQ09VTlQgaXMgZGVmaW5lZCBpbiB3aW5lZDNkX3ByaXZhdGUuaCAqLwogICAgICAgIGlmKFRoaXMtPmxvY2tDb3VudCA+IE1BWExPQ0tDT1VOVCkgewogICAgICAgICAgICBUUkFDRSgiU3VyZmFjZSBpcyBsb2NrZWQgcmVndWxhcmx5LCBub3QgZnJlZWluZyB0aGUgc3lzdGVtIG1lbW9yeSBjb3B5IGFueSBtb3JlXG4iKTsKICAgICAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfRFlOTE9DSzsKICAgICAgICB9CiAgICB9CgogICAgLyogQ3JlYXRlIGEgUEJPIGZvciBkeW5hbWljYWxseSBsb2NrZWQgc3VyZmFjZXMgYnV0IGRvbid0IGRvIGl0IGZvciBjb252ZXJ0ZWQgb3Igbm9uLXBvdzIgc3VyZmFjZXMuCiAgICAgKiBBbHNvIGRvbid0IGNyZWF0ZSBhIFBCTyBmb3Igc3lzdGVtbWVtIHN1cmZhY2VzLgogICAgICovCiAgICBpZihHTF9TVVBQT1JUKEFSQl9QSVhFTF9CVUZGRVJfT0JKRUNUKSAmJiAoVGhpcy0+RmxhZ3MgJiBTRkxBR19EWU5MT0NLKSAmJiAhKFRoaXMtPkZsYWdzICYgKFNGTEFHX1BCTyB8IFNGTEFHX0NPTlZFUlRFRCB8IFNGTEFHX05PTlBPVzIpKSAmJiAoVGhpcy0+cmVzb3VyY2UucG9vbCAhPSBXSU5FRDNEUE9PTF9TWVNURU1NRU0pKSB7CiAgICAgICAgR0xlbnVtIGVycm9yOwogICAgICAgIEVOVEVSX0dMKCk7CgogICAgICAgIEdMX0VYVENBTEwoZ2xHZW5CdWZmZXJzQVJCKDEsICZUaGlzLT5wYm8pKTsKICAgICAgICBlcnJvciA9IGdsR2V0RXJyb3IoKTsKICAgICAgICBpZihUaGlzLT5wYm8gPT0gMCB8fCBlcnJvciAhPSBHTF9OT19FUlJPUikgewogICAgICAgICAgICBFUlIoIkZhaWxlZCB0byBiaW5kIHRoZSBQQk8gd2l0aCBlcnJvciAlcyAoJSN4KVxuIiwgZGVidWdfZ2xlcnJvcihlcnJvciksIGVycm9yKTsKICAgICAgICB9CgogICAgICAgIFRSQUNFKCJBdHRhY2hpbmcgcGJvPSUjeCB0byAoJXApXG4iLCBUaGlzLT5wYm8sIFRoaXMpOwoKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9QSVhFTF9VTlBBQ0tfQlVGRkVSX0FSQiwgVGhpcy0+cGJvKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZEJ1ZmZlckFSQiIpOwoKICAgICAgICBHTF9FWFRDQUxMKGdsQnVmZmVyRGF0YUFSQihHTF9QSVhFTF9VTlBBQ0tfQlVGRkVSX0FSQiwgVGhpcy0+cmVzb3VyY2Uuc2l6ZSArIDQsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwgR0xfU1RSRUFNX0RSQVdfQVJCKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQnVmZmVyRGF0YUFSQiIpOwoKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9QSVhFTF9VTlBBQ0tfQlVGRkVSX0FSQiwgMCkpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRCdWZmZXJBUkIiKTsKCiAgICAgICAgLyogV2UgZG9uJ3QgbmVlZCB0aGUgc3lzdGVtIG1lbW9yeSBhbnltb3JlIGFuZCB3ZSBjYW4ndCBldmVuIHVzZSBpdCBmb3IgUEJPcyAqLwogICAgICAgIGlmKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19DTElFTlQpKSB7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnJlc291cmNlLmhlYXBNZW1vcnkpOwogICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5oZWFwTWVtb3J5ID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gTlVMTDsKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19QQk87CiAgICAgICAgTEVBVkVfR0woKTsKICAgIH0gZWxzZSBpZighKFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSB8fCBUaGlzLT5GbGFncyAmIFNGTEFHX1BCTykpIHsKICAgICAgICAvKiBXaGF0ZXZlciBzdXJmYWNlIHdlIGhhdmUsIG1ha2Ugc3VyZSB0aGF0IHRoZXJlIGlzIG1lbW9yeSBhbGxvY2F0ZWQgZm9yIHRoZSBkb3dubG9hZGVkIGNvcHksCiAgICAgICAgICogb3IgYSBwYm8gdG8gbWFwCiAgICAgICAgICovCiAgICAgICAgaWYoIVRoaXMtPnJlc291cmNlLmhlYXBNZW1vcnkpIHsKICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuaGVhcE1lbW9yeSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpICwwICwgVGhpcy0+cmVzb3VyY2Uuc2l6ZSArIFJFU09VUkNFX0FMSUdOTUVOVCk7CiAgICAgICAgfQogICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9CiAgICAgICAgICAgICAgICAoQllURSAqKSgoKFVMT05HX1BUUikgVGhpcy0+cmVzb3VyY2UuaGVhcE1lbW9yeSArIChSRVNPVVJDRV9BTElHTk1FTlQgLSAxKSkgJiB+KFJFU09VUkNFX0FMSUdOTUVOVCAtIDEpKTsKICAgICAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX0lOU1lTTUVNKSB7CiAgICAgICAgICAgIEVSUigiU3VyZmFjZSB3aXRob3V0IG1lbW9yeSBvciBwYm8gaGFzIFNGTEFHX0lOU1lTTUVNIHNldCFcbiIpOwogICAgICAgIH0KICAgIH0KfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfTG9ja1JlY3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgV0lORUQzRExPQ0tFRF9SRUNUKiBwTG9ja2VkUmVjdCwgQ09OU1QgUkVDVCogcFJlY3QsIERXT1JEIEZsYWdzKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgKm15RGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIElXaW5lRDNEU3dhcENoYWluICpzd2FwY2hhaW4gPSBOVUxMOwoKICAgIFRSQUNFKCIoJXApIDogcmVjdEAlcCBmbGFncyglMDh4KSwgb3V0cHV0IGxvY2tlZFJlY3RAJXAsIG1lbW9yeUAlcFxuIiwgVGhpcywgcFJlY3QsIEZsYWdzLCBwTG9ja2VkUmVjdCwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKCiAgICAvKiBUaGlzIGlzIGFsc28gZG9uZSBpbiB0aGUgYmFzZSBjbGFzcywgYnV0IHdlIGhhdmUgdG8gdmVyaWZ5IHRoaXMgYmVmb3JlIGxvYWRpbmcgYW55IGRhdGEgZnJvbQogICAgICogZ2wgaW50byB0aGUgc3lzbWVtIGNvcHkuIFRoZSBQQk8gbWF5IGJlIG1hcHBlZCwgYSBkaWZmZXJlbnQgcmVjdGFuZ2xlIGxvY2tlZCwgdGhlIGRpc2NhcmQgZmxhZwogICAgICogbWF5IGludGVyZmVyZSwgYW5kIGFsbCBvdGhlciBiYWQgdGhpbmdzIG1heSBoYXBwZW4KICAgICAqLwogICAgaWYgKFRoaXMtPkZsYWdzICYgU0ZMQUdfTE9DS0VEKSB7CiAgICAgICAgV0FSTigiU3VyZmFjZSBpcyBhbHJlYWR5IGxvY2tlZCwgcmV0dXJuaW5nIEQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19MT0NLRUQ7CgogICAgaWYgKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19MT0NLQUJMRSkpCiAgICB7CiAgICAgICAgVFJBQ0UoIldhcm5pbmc6IHRyeWluZyB0byBsb2NrIHVubG9ja2FibGUgc3VyZkAlcFxuIiwgVGhpcyk7CiAgICB9CgogICAgaWYgKEZsYWdzICYgV0lORUQzRExPQ0tfRElTQ0FSRCkgewogICAgICAgIC8qIFNldCBTRkxBR19JTlNZU01FTSwgc28gd2UnbGwgbmV2ZXIgdHJ5IHRvIGRvd25sb2FkIHRoZSBkYXRhIGZyb20gdGhlIHRleHR1cmUuICovCiAgICAgICAgVFJBQ0UoIldJTkVEM0RMT0NLX0RJU0NBUkQgZmxhZyBwYXNzZWQsIG1hcmtpbmcgbG9jYWwgY29weSBhcyB1cCB0byBkYXRlXG4iKTsKICAgICAgICBzdXJmYWNlX3ByZXBhcmVfc3lzdGVtX21lbW9yeShUaGlzKTsgLyogTWFrZXMgc3VyZSBtZW1vcnkgaXMgYWxsb2NhdGVkICovCiAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfSU5TWVNNRU07CiAgICAgICAgZ290byBsb2NrX2VuZDsKICAgIH0KCiAgICBpZiAoVGhpcy0+RmxhZ3MgJiBTRkxBR19JTlNZU01FTSkgewogICAgICAgIFRSQUNFKCJMb2NhbCBjb3B5IGlzIHVwIHRvIGRhdGUsIG5vdCBkb3dubG9hZGluZyBkYXRhXG4iKTsKICAgICAgICBzdXJmYWNlX3ByZXBhcmVfc3lzdGVtX21lbW9yeShUaGlzKTsgLyogTWFrZXMgc3VyZSBtZW1vcnkgaXMgYWxsb2NhdGVkICovCiAgICAgICAgZ290byBsb2NrX2VuZDsKICAgIH0KCiAgICAvKiBOb3cgZG93bmxvYWQgdGhlIHN1cmZhY2UgY29udGVudCBmcm9tIG9wZW5nbAogICAgICogVXNlIHRoZSByZW5kZXIgdGFyZ2V0IHJlYWRiYWNrIGlmIHRoZSBzdXJmYWNlIGlzIG9uIGEgc3dhcGNoYWluKD1vbnNjcmVlbiByZW5kZXIgdGFyZ2V0KSBvciB0aGUgY3VycmVudCBwcmltYXJ5IHRhcmdldAogICAgICogT2Zmc2NyZWVuIHRhcmdldHMgd2hpY2ggYXJlIG5vdCBhY3RpdmUgYXQgdGhlIG1vbWVudCBvciBhcmUgaGlnaGVyIHRhcmdldHMoRkJPcykgY2FuIGJlIGxvY2tlZCB3aXRoIHRoZSB0ZXh0dXJlIHBhdGgKICAgICAqLwogICAgSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihpZmFjZSwgJklJRF9JV2luZUQzRFN3YXBDaGFpbiwgKHZvaWQgKiopJnN3YXBjaGFpbik7CiAgICBpZihzd2FwY2hhaW4gfHwgaWZhY2UgPT0gbXlEZXZpY2UtPnJlbmRlcl90YXJnZXRzWzBdKSB7CiAgICAgICAgY29uc3QgUkVDVCAqcGFzc19yZWN0ID0gcFJlY3Q7CgogICAgICAgIC8qIElXaW5lRDNEU3VyZmFjZV9Mb2FkTG9jYXRpb24gZG9lcyBub3QgY2hlY2sgaWYgdGhlIHJlY3RhbmdsZSBzcGVjaWZpZXMgdGhlIGZ1bGwgc3VyZmFjZXMKICAgICAgICAgKiBiZWNhdXNlIG1vc3QgY2FsbGVyIGZ1bmN0aW9ucyBkbyBub3QgbmVlZCB0aGF0LiBTbyBkbyB0aGF0IGhlcmUKICAgICAgICAgKi8KICAgICAgICBpZihwUmVjdCAmJgogICAgICAgICAgIHBSZWN0LT50b3AgICAgPT0gMCAmJgogICAgICAgICAgIHBSZWN0LT5sZWZ0ICAgPT0gMCAmJgogICAgICAgICAgIHBSZWN0LT5yaWdodCAgPT0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGggJiYKICAgICAgICAgICBwUmVjdC0+Ym90dG9tID09IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCkgewogICAgICAgICAgICBwYXNzX3JlY3QgPSBOVUxMOwogICAgICAgIH0KCiAgICAgICAgc3dpdGNoKHdpbmVkM2Rfc2V0dGluZ3MucmVuZGVydGFyZ2V0bG9ja19tb2RlKSB7CiAgICAgICAgICAgIGNhc2UgUlRMX1RFWERSQVc6CiAgICAgICAgICAgIGNhc2UgUlRMX1RFWFRFWDoKICAgICAgICAgICAgICAgIEZJWE1FKCJSZWFkaW5nIGZyb20gcmVuZGVyIHRhcmdldCB3aXRoIGEgdGV4dHVyZSBpc24ndCBpbXBsZW1lbnRlZCB5ZXQsIGZhbGxpbmcgYmFjayB0byBmcmFtZWJ1ZmZlciByZWFkaW5nXG4iKTsKI2lmIDAKICAgICAgICAgICAgICAgIC8qIERpc2FibGVkIGZvciBub3cuIExvYWRMb2NhdGlvbiBwcmVmZXJzIHRoZSB0ZXh0dXJlIG92ZXIgdGhlIGRyYXdhYmxlIGFzIHRoZSBzb3VyY2UuIFNvIGlmIHdlIGNvcHkgdG8gdGhlCiAgICAgICAgICAgICAgICAgKiB0ZXh0dXJlIGZpcnN0LCB0aGVuIHRvIHN5c21lbSwgd2UnbGwgYXZvaWQgZ2xSZWFkUGl4ZWxzIGFuZCB1c2UgZ2xDb3B5VGV4SW1hZ2UgYW5kIGdsR2V0VGV4SW1hZ2UyRCBpbnN0ZWFkLgogICAgICAgICAgICAgICAgICogVGhpcyBtYXkgYmUgZmFzdGVyIG9uIHNvbWUgY2FyZHMKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvYWRMb2NhdGlvbihpZmFjZSwgU0ZMQUdfSU5URVhUVVJFLCBOVUxMIC8qIE5vIHBhcnRpYWwgdGV4dHVyZSBjb3B5IHlldCAqLyk7CiNlbmRpZgogICAgICAgICAgICAgICAgLyogZHJvcCB0aHJvdWdoICovCgogICAgICAgICAgICBjYXNlIFJUTF9BVVRPOgogICAgICAgICAgICBjYXNlIFJUTF9SRUFERFJBVzoKICAgICAgICAgICAgY2FzZSBSVExfUkVBRFRFWDoKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9Mb2FkTG9jYXRpb24oaWZhY2UsIFNGTEFHX0lOU1lTTUVNLCBwUmVjdCk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgUlRMX0RJU0FCTEU6CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgaWYoc3dhcGNoYWluKSBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKHN3YXBjaGFpbik7CgogICAgfSBlbHNlIGlmKGlmYWNlID09IG15RGV2aWNlLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KSB7CiAgICAgICAgLyoqIHRoZSBkZXB0aCBzdGVuY2lsIGluIG9wZW5HTCBoYXMgYSBmb3JtYXQgb2YgR0xfRkxPQVQKICAgICAgICAgKiB3aGljaCBzaG91bGQgYmUgZ29vZCBmb3IgV0lORUQzREZNVF9EMTZfTE9DS0FCTEUKICAgICAgICAgKiBhbmQgV0lORUQzREZNVF9EMTYKICAgICAgICAgKiBpdCBpcyB1bmNsZWFyIHdoYXQgZm9ybWF0IHRoZSBzdGVuY2lsIGJ1ZmZlciBpcyBpbiBleGNlcHQuCiAgICAgICAgICogJ0VhY2ggaW5kZXggaXMgY29udmVydGVkIHRvIGZpeGVkIHBvaW50Li4uCiAgICAgICAgICogSWYgR0xfTUFQX1NURU5DSUwgaXMgR0xfVFJVRSwgaW5kaWNlcyBhcmUgcmVwbGFjZWQgYnkgdGhlaXIKICAgICAgICAgKiBtYXBwaW5ncyBpbiB0aGUgdGFibGUgR0xfUElYRUxfTUFQX1NfVE9fUy4KICAgICAgICAgKiBnbFJlYWRQaXhlbHMoVGhpcy0+bG9ja2VkUmVjdC5sZWZ0LAogICAgICAgICAqICAgICAgICAgICAgIFRoaXMtPmxvY2tlZFJlY3QuYm90dG9tIC0gaiAtIDEsCiAgICAgICAgICogICAgICAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5yaWdodCAtIFRoaXMtPmxvY2tlZFJlY3QubGVmdCwKICAgICAgICAgKiAgICAgICAgICAgICAxLAogICAgICAgICAqICAgICAgICAgICAgIEdMX0RFUFRIX0NPTVBPTkVOVCwKICAgICAgICAgKiAgICAgICAgICAgICB0eXBlLAogICAgICAgICAqICAgICAgICAgICAgIChjaGFyICopcExvY2tlZFJlY3QtPnBCaXRzICsgKHBMb2NrZWRSZWN0LT5QaXRjaCAqIChqLVRoaXMtPmxvY2tlZFJlY3QudG9wKSkpOwogICAgICAgICAqCiAgICAgICAgICogRGVwdGggU3RlbmNpbCBzdXJmYWNlcyB3aGljaCBhcmUgbm90IHRoZSBjdXJyZW50IGRlcHRoIHN0ZW5jaWwgdGFyZ2V0IHNob3VsZCBoYXZlIHRoZWlyIGRhdGEgaW4gYQogICAgICAgICAqIGdsIHRleHR1cmUobmV4dCBwYXRoKSwgb3IgaW4gbG9jYWwgbWVtb3J5KGVhcmx5IHJldHVybiBiZWNhdXNlIG9mIHNldCBTRkxBR19JTlNZU01FTSBhYm92ZSkuIElmCiAgICAgICAgICogbm9uZSBvZiB0aGF0IGlzIHRoZSBjYXNlIHRoZSBwcm9ibGVtIGlzIG5vdCBpbiB0aGlzIGZ1bmN0aW9uIDotKQogICAgICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgICAgICBGSVhNRSgiRGVwdGggc3RlbmNpbCBsb2NraW5nIG5vdCBzdXBwb3J0ZWQgeWV0XG4iKTsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogVGhpcyBwYXRoIGlzIGZvciBub3JtYWwgc3VyZmFjZXMsIG9mZnNjcmVlbiByZW5kZXIgdGFyZ2V0cyBhbmQgZXZlcnl0aGluZyBlbHNlIHRoYXQgaXMgaW4gYSBnbCB0ZXh0dXJlICovCiAgICAgICAgVFJBQ0UoImxvY2tpbmcgYW4gb3JkaW5hcnkgc3VyZmFjZVxuIik7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvYWRMb2NhdGlvbihpZmFjZSwgU0ZMQUdfSU5TWVNNRU0sIE5VTEwgLyogbm8gcGFydGlhbCBsb2NraW5nIGZvciB0ZXh0dXJlcyB5ZXQgKi8pOwogICAgfQoKbG9ja19lbmQ6CiAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX1BCTykgewogICAgICAgIEFjdGl2YXRlQ29udGV4dChteURldmljZSwgbXlEZXZpY2UtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQsIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9QSVhFTF9VTlBBQ0tfQlVGRkVSX0FSQiwgVGhpcy0+cGJvKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZEJ1ZmZlckFSQiIpOwoKICAgICAgICAvKiBUaGlzIHNob3VsZG4ndCBoYXBwZW4gYnV0IGNvdWxkIG9jY3VyIGlmIHNvbWUgb3RoZXIgZnVuY3Rpb24gZGlkbid0IGhhbmRsZSB0aGUgUEJPIHByb3Blcmx5ICovCiAgICAgICAgaWYoVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KSB7CiAgICAgICAgICAgIEVSUigiVGhlIHN1cmZhY2UgYWxyZWFkeSBoYXMgUEJPIG1lbW9yeSBhbGxvY2F0ZWQhXG4iKTsKICAgICAgICB9CgogICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IEdMX0VYVENBTEwoZ2xNYXBCdWZmZXJBUkIoR0xfUElYRUxfVU5QQUNLX0JVRkZFUl9BUkIsIEdMX1JFQURfV1JJVEVfQVJCKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsTWFwQnVmZmVyQVJCIik7CgogICAgICAgIC8qIE1ha2Ugc3VyZSB0aGUgcGJvIGlzbid0IHNldCBhbnltb3JlIGluIG9yZGVyIG5vdCB0byBicmVhayBub24tcGJvIGNhbGxzICovCiAgICAgICAgR0xfRVhUQ0FMTChnbEJpbmRCdWZmZXJBUkIoR0xfUElYRUxfVU5QQUNLX0JVRkZFUl9BUkIsIDApKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kQnVmZmVyQVJCIik7CgogICAgICAgIExFQVZFX0dMKCk7CiAgICB9CgogICAgaWYgKEZsYWdzICYgKFdJTkVEM0RMT0NLX05PX0RJUlRZX1VQREFURSB8IFdJTkVEM0RMT0NLX1JFQURPTkxZKSkgewogICAgICAgIC8qIERvbid0IGRpcnRpZnkgKi8KICAgIH0gZWxzZSB7CiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZSAqcEJhc2VUZXh0dXJlOwogICAgICAgIC8qKgogICAgICAgICAqIERpcnRpZnkgb24gbG9jawogICAgICAgICAqIGFzIHNlZW4gaW4gbXNkbiBkb2NzCiAgICAgICAgICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0FkZERpcnR5UmVjdChpZmFjZSwgcFJlY3QpOwoKICAgICAgICAvKiogRGlydGlmeSBDb250YWluZXIgaWYgbmVlZGVkICovCiAgICAgICAgaWYgKFdJTkVEM0RfT0sgPT0gSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihpZmFjZSwgJklJRF9JV2luZUQzREJhc2VUZXh0dXJlLCAodm9pZCAqKikmcEJhc2VUZXh0dXJlKSAmJiBwQmFzZVRleHR1cmUgIT0gTlVMTCkgewogICAgICAgICAgICBUUkFDRSgiTWFraW5nIGNvbnRhaW5lciBkaXJ0eVxuIik7CiAgICAgICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfU2V0RGlydHkocEJhc2VUZXh0dXJlLCBUUlVFKTsKICAgICAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9SZWxlYXNlKHBCYXNlVGV4dHVyZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVFJBQ0UoIlN1cmZhY2UgaXMgc3RhbmRhbG9uZSwgbm8gbmVlZCB0byBkaXJ0eSB0aGUgY29udGFpbmVyXG4iKTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0xvY2tSZWN0KGlmYWNlLCBwTG9ja2VkUmVjdCwgcFJlY3QsIEZsYWdzKTsKfQoKc3RhdGljIHZvaWQgZmx1c2hfdG9fZnJhbWVidWZmZXJfZHJhd3BpeGVscyhJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBHTGVudW0gZm10LCBHTGVudW0gdHlwZSwgVUlOVCBicHAsIGNvbnN0IEJZVEUgKm1lbSkgewogICAgR0xpbnQgIHByZXZfc3RvcmU7CiAgICBHTGludCAgcHJldl9yYXN0ZXJwb3NbNF07CiAgICBHTGludCBza2lwQnl0ZXMgPSAwOwogICAgVUlOVCBwaXRjaCA9IElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaCgoSVdpbmVEM0RTdXJmYWNlICopIFRoaXMpOyAgICAvKiB0YXJnZXQgaXMgYXJnYiwgNCBieXRlICovCiAgICBJV2luZUQzRERldmljZUltcGwgKm15RGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqc3dhcGNoYWluOwoKICAgIC8qIEFjdGl2YXRlIHRoZSBjb3JyZWN0IGNvbnRleHQgZm9yIHRoZSByZW5kZXIgdGFyZ2V0ICovCiAgICBBY3RpdmF0ZUNvbnRleHQobXlEZXZpY2UsIChJV2luZUQzRFN1cmZhY2UgKikgVGhpcywgQ1RYVVNBR0VfQkxJVCk7CiAgICBFTlRFUl9HTCgpOwoKICAgIElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoKElXaW5lRDNEU3VyZmFjZSAqKSBUaGlzLCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikmc3dhcGNoYWluKTsKICAgIGlmKCFzd2FwY2hhaW4pIHsKICAgICAgICAvKiBQcmltYXJ5IG9mZnNjcmVlbiByZW5kZXIgdGFyZ2V0ICovCiAgICAgICAgVFJBQ0UoIk9mZnNjcmVlbiByZW5kZXIgdGFyZ2V0XG4iKTsKICAgICAgICBnbERyYXdCdWZmZXIobXlEZXZpY2UtPm9mZnNjcmVlbkJ1ZmZlcik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcihteURldmljZS0+b2Zmc2NyZWVuQnVmZmVyKSIpOwogICAgfSBlbHNlIHsKICAgICAgICBHTGVudW0gYnVmZmVyID0gc3VyZmFjZV9nZXRfZ2xfYnVmZmVyKChJV2luZUQzRFN1cmZhY2UgKikgVGhpcywgKElXaW5lRDNEU3dhcENoYWluICopc3dhcGNoYWluKTsKICAgICAgICBUUkFDRSgiVW5sb2NraW5nICUjeCBidWZmZXJcbiIsIGJ1ZmZlcik7CiAgICAgICAgZ2xEcmF3QnVmZmVyKGJ1ZmZlcik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlciIpOwoKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKChJV2luZUQzRFN3YXBDaGFpbiAqKXN3YXBjaGFpbik7CiAgICB9CgogICAgZ2xGbHVzaCgpOwogICAgdmNoZWNrR0xjYWxsKCJnbEZsdXNoIik7CiAgICBnbEdldEludGVnZXJ2KEdMX1BBQ0tfU1dBUF9CWVRFUywgJnByZXZfc3RvcmUpOwogICAgdmNoZWNrR0xjYWxsKCJnbEludGVnZXJ2Iik7CiAgICBnbEdldEludGVnZXJ2KEdMX0NVUlJFTlRfUkFTVEVSX1BPU0lUSU9OLCAmcHJldl9yYXN0ZXJwb3NbMF0pOwogICAgdmNoZWNrR0xjYWxsKCJnbEludGVnZXJ2Iik7CiAgICBnbFBpeGVsWm9vbSgxLjAsIC0xLjApOwogICAgdmNoZWNrR0xjYWxsKCJnbFBpeGVsWm9vbSIpOwoKICAgIC8qIElmIG5vdCBmdWxsc2NyZWVuLCB3ZSBuZWVkIHRvIHNraXAgYSBudW1iZXIgb2YgYnl0ZXMgdG8gZmluZCB0aGUgbmV4dCByb3cgb2YgZGF0YSAqLwogICAgZ2xHZXRJbnRlZ2VydihHTF9VTlBBQ0tfUk9XX0xFTkdUSCwgJnNraXBCeXRlcyk7CiAgICBnbFBpeGVsU3RvcmVpKEdMX1VOUEFDS19ST1dfTEVOR1RILCBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCk7CgogICAgZ2xSYXN0ZXJQb3MzaShUaGlzLT5sb2NrZWRSZWN0LmxlZnQsIFRoaXMtPmxvY2tlZFJlY3QudG9wLCAxKTsKICAgIHZjaGVja0dMY2FsbCgiZ2xSYXN0ZXJQb3MyZiIpOwoKICAgIC8qIFNvbWUgZHJpdmVycyhyYWRlb24gZHJpLCBvdGhlcnM/KSBkb24ndCBsaWtlIGV4Y2VwdGlvbnMgZHVyaW5nCiAgICAgKiBnbERyYXdQaXhlbHMuIElmIHRoZSBzdXJmYWNlIGlzIGEgRElCIHNlY3Rpb24sIGl0IG1pZ2h0IGJlIGluIEdESU1vZGUKICAgICAqIGFmdGVyIFJlbGVhc2VEQy4gUmVhZGluZyBpdCB3aWxsIGNhdXNlIGFuIGV4Y2VwdGlvbiwgd2hpY2ggeDExZHJ2IHdpbGwKICAgICAqIGNhdGNoIHRvIHB1dCB0aGUgZGliIHNlY3Rpb24gaW4gSW5TeW5jIG1vZGUsIHdoaWNoIGxlYWRzIHRvIGEgY3Jhc2gKICAgICAqIGFuZCBhIGJsb2NrZWQgeCBzZXJ2ZXIgb24gbXkgcmFkZW9uIGNhcmQuCiAgICAgKgogICAgICogVGhlIGZvbGxvd2luZyBsaW5lcyByZWFkIHRoZSBkaWIgc2VjdGlvbiBzbyBpdCBpcyBwdXQgaW4gSW5TeW5jIG1vZGUKICAgICAqIGJlZm9yZSBnbERyYXdQaXhlbHMgaXMgY2FsbGVkIGFuZCB0aGUgY3Jhc2ggaXMgcHJldmVudGVkLiBUaGVyZSB3b24ndAogICAgICogYmUgYW55IGludGVyZmVyaW5nIGdkaSBhY2Nlc3NlcywgYmVjYXVzZSBVbmxvY2tSZWN0IGlzIGNhbGxlZCBmcm9tCiAgICAgKiBSZWxlYXNlREMsIGFuZCB0aGUgYXBwIHdvbid0IHVzZSB0aGUgZGMgYW55IG1vcmUgYWZ0ZXJ3YXJkcy4KICAgICAqLwogICAgaWYoKFRoaXMtPkZsYWdzICYgU0ZMQUdfRElCU0VDVElPTikgJiYgIShUaGlzLT5GbGFncyAmIFNGTEFHX1BCTykpIHsKICAgICAgICB2b2xhdGlsZSBCWVRFIHJlYWQ7CiAgICAgICAgcmVhZCA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeVswXTsKICAgIH0KCiAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX1BCTykgewogICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kQnVmZmVyQVJCKEdMX1BJWEVMX1VOUEFDS19CVUZGRVJfQVJCLCBUaGlzLT5wYm8pKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kQnVmZmVyQVJCIik7CiAgICB9CgogICAgLyogV2hlbiB0aGUgc3VyZmFjZSBpcyBsb2NrZWQgd2Ugb25seSBoYXZlIHRvIHJlZnJlc2ggdGhlIGxvY2tlZCBwYXJ0IGVsc2Ugd2UgbmVlZCB0byB1cGRhdGUgdGhlIHdob2xlIGltYWdlICovCiAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX0xPQ0tFRCkgewogICAgICAgIGdsRHJhd1BpeGVscyhUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0IC0gVGhpcy0+bG9ja2VkUmVjdC5sZWZ0LAogICAgICAgICAgICAgICAgICAgICAoVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20gLSBUaGlzLT5sb2NrZWRSZWN0LnRvcCktMSwKICAgICAgICAgICAgICAgICAgICAgZm10LCB0eXBlLAogICAgICAgICAgICAgICAgICAgICBtZW0gKyBicHAgKiBUaGlzLT5sb2NrZWRSZWN0LmxlZnQgKyBwaXRjaCAqIFRoaXMtPmxvY2tlZFJlY3QudG9wKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3UGl4ZWxzIik7CiAgICB9IGVsc2UgewogICAgICAgIGdsRHJhd1BpeGVscyhUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCwKICAgICAgICAgICAgICAgICAgICAgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICBmbXQsIHR5cGUsIG1lbSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd1BpeGVscyIpOwogICAgfQoKICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfUEJPKSB7CiAgICAgICAgR0xfRVhUQ0FMTChnbEJpbmRCdWZmZXJBUkIoR0xfUElYRUxfVU5QQUNLX0JVRkZFUl9BUkIsIDApKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kQnVmZmVyQVJCIik7CiAgICB9CgogICAgZ2xQaXhlbFpvb20oMS4wLDEuMCk7CiAgICB2Y2hlY2tHTGNhbGwoImdsUGl4ZWxab29tIik7CgogICAgZ2xSYXN0ZXJQb3MzaXYoJnByZXZfcmFzdGVycG9zWzBdKTsKICAgIHZjaGVja0dMY2FsbCgiZ2xSYXN0ZXJQb3MzaXYiKTsKCiAgICAvKiBSZXNldCB0byBwcmV2aW91cyBwYWNrIHJvdyBsZW5ndGggKi8KICAgIGdsUGl4ZWxTdG9yZWkoR0xfVU5QQUNLX1JPV19MRU5HVEgsIHNraXBCeXRlcyk7CiAgICB2Y2hlY2tHTGNhbGwoImdsUGl4ZWxTdG9yZWkgR0xfVU5QQUNLX1JPV19MRU5HVEgiKTsKCiAgICBpZighc3dhcGNoYWluKSB7CiAgICAgICAgZ2xEcmF3QnVmZmVyKG15RGV2aWNlLT5vZmZzY3JlZW5CdWZmZXIpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIobXlEZXZpY2UtPm9mZnNjcmVlbkJ1ZmZlcikiKTsKICAgIH0gZWxzZSBpZihzd2FwY2hhaW4tPmJhY2tCdWZmZXIpIHsKICAgICAgICBnbERyYXdCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcihHTF9CQUNLKSIpOwogICAgfSBlbHNlIHsKICAgICAgICBnbERyYXdCdWZmZXIoR0xfRlJPTlQpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoR0xfRlJPTlQpIik7CiAgICB9CiAgICBMRUFWRV9HTCgpOwoKICAgIHJldHVybjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfVW5sb2NrUmVjdChJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgKm15RGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqc3dhcGNoYWluID0gTlVMTDsKICAgIEJPT0wgZnVsbHN1cmZhY2U7CgogICAgaWYgKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19MT0NLRUQpKSB7CiAgICAgICAgV0FSTigidHJ5aW5nIHRvIFVubG9jayBhbiB1bmxvY2tlZCBzdXJmQCVwXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBpZiAoVGhpcy0+RmxhZ3MgJiBTRkxBR19QQk8pIHsKICAgICAgICBUUkFDRSgiRnJlZWluZyBQQk8gbWVtb3J5XG4iKTsKICAgICAgICBBY3RpdmF0ZUNvbnRleHQobXlEZXZpY2UsIG15RGV2aWNlLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0LCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgR0xfRVhUQ0FMTChnbEJpbmRCdWZmZXJBUkIoR0xfUElYRUxfVU5QQUNLX0JVRkZFUl9BUkIsIFRoaXMtPnBibykpOwogICAgICAgIEdMX0VYVENBTEwoZ2xVbm1hcEJ1ZmZlckFSQihHTF9QSVhFTF9VTlBBQ0tfQlVGRkVSX0FSQikpOwogICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kQnVmZmVyQVJCKEdMX1BJWEVMX1VOUEFDS19CVUZGRVJfQVJCLCAwKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsVW5tYXBCdWZmZXJBUkIiKTsKICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE5VTEw7CiAgICB9CgogICAgVFJBQ0UoIiglcCkgOiBkaXJ0eWZpZWQoJWQpXG4iLCBUaGlzLCBUaGlzLT5GbGFncyAmIChTRkxBR19JTkRSQVdBQkxFIHwgU0ZMQUdfSU5URVhUVVJFKSA/IDAgOiAxKTsKCiAgICBpZiAoVGhpcy0+RmxhZ3MgJiAoU0ZMQUdfSU5EUkFXQUJMRSB8IFNGTEFHX0lOVEVYVFVSRSkpIHsKICAgICAgICBUUkFDRSgiKCVwKSA6IE5vdCBEaXJ0aWZpZWQgc28gbm90aGluZyB0byBkbywgcmV0dXJuIG5vd1xuIiwgVGhpcyk7CiAgICAgICAgZ290byB1bmxvY2tfZW5kOwogICAgfQoKICAgIElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoaWZhY2UsICZJSURfSVdpbmVEM0RTd2FwQ2hhaW4sICh2b2lkICoqKSZzd2FwY2hhaW4pOwogICAgaWYoc3dhcGNoYWluIHx8IChteURldmljZS0+cmVuZGVyX3RhcmdldHMgJiYgaWZhY2UgPT0gbXlEZXZpY2UtPnJlbmRlcl90YXJnZXRzWzBdKSkgewogICAgICAgIGlmKHN3YXBjaGFpbikgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4gKikgc3dhcGNoYWluKTsKCiAgICAgICAgaWYod2luZWQzZF9zZXR0aW5ncy5yZW5kZXJ0YXJnZXRsb2NrX21vZGUgPT0gUlRMX0RJU0FCTEUpIHsKICAgICAgICAgICAgc3RhdGljIEJPT0wgd2FybmVkID0gRkFMU0U7CiAgICAgICAgICAgIGlmKCF3YXJuZWQpIHsKICAgICAgICAgICAgICAgIEVSUigiVGhlIGFwcGxpY2F0aW9uIHRyaWVzIHRvIHdyaXRlIHRvIHRoZSByZW5kZXIgdGFyZ2V0LCBidXQgcmVuZGVyIHRhcmdldCBsb2NraW5nIGlzIGRpc2FibGVkXG4iKTsKICAgICAgICAgICAgICAgIHdhcm5lZCA9IFRSVUU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZ290byB1bmxvY2tfZW5kOwogICAgICAgIH0KCiAgICAgICAgaWYoVGhpcy0+ZGlydHlSZWN0LmxlZnQgICA9PSAwICYmCiAgICAgICAgICAgVGhpcy0+ZGlydHlSZWN0LnRvcCAgICA9PSAwICYmCiAgICAgICAgICAgVGhpcy0+ZGlydHlSZWN0LnJpZ2h0ICA9PSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCAmJgogICAgICAgICAgIFRoaXMtPmRpcnR5UmVjdC5ib3R0b20gPT0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KSB7CiAgICAgICAgICAgIGZ1bGxzdXJmYWNlID0gVFJVRTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvKiBUT0RPOiBQcm9wZXIgcGFydGlhbCByZWN0YW5nbGUgdHJhY2tpbmcgKi8KICAgICAgICAgICAgZnVsbHN1cmZhY2UgPSBGQUxTRTsKICAgICAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfSU5TWVNNRU07CiAgICAgICAgfQoKICAgICAgICBzd2l0Y2god2luZWQzZF9zZXR0aW5ncy5yZW5kZXJ0YXJnZXRsb2NrX21vZGUpIHsKICAgICAgICAgICAgY2FzZSBSVExfUkVBRFRFWDoKICAgICAgICAgICAgY2FzZSBSVExfVEVYVEVYOgogICAgICAgICAgICAgICAgQWN0aXZhdGVDb250ZXh0KG15RGV2aWNlLCBpZmFjZSwgQ1RYVVNBR0VfQkxJVCk7CiAgICAgICAgICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgICAgICAgICAgaWYgKFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUgPT0gMCkgewogICAgICAgICAgICAgICAgICAgIGdsR2VuVGV4dHVyZXMoMSwgJlRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEdlblRleHR1cmVzIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBnbEJpbmRUZXh0dXJlKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRUZXh0dXJlKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKSIpOwogICAgICAgICAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9Mb2FkTG9jYXRpb24oaWZhY2UsIFNGTEFHX0lOVEVYVFVSRSwgTlVMTCAvKiBwYXJ0aWFsIHRleHR1cmUgbG9hZGluZyBub3Qgc3VwcG9ydGVkIHlldCAqLyk7CiAgICAgICAgICAgICAgICAvKiBkcm9wIHRocm91Z2ggKi8KCiAgICAgICAgICAgIGNhc2UgUlRMX0FVVE86CiAgICAgICAgICAgIGNhc2UgUlRMX1JFQUREUkFXOgogICAgICAgICAgICBjYXNlIFJUTF9URVhEUkFXOgogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvYWRMb2NhdGlvbihpZmFjZSwgU0ZMQUdfSU5EUkFXQUJMRSwgZnVsbHN1cmZhY2UgPyBOVUxMIDogJlRoaXMtPmRpcnR5UmVjdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGlmKCFmdWxsc3VyZmFjZSkgewogICAgICAgICAgICAvKiBQYXJ0aWFsIHJlY3RhbmdsZSB0cmFja2luZyBpcyBub3QgY29tbW9ubHkgaW1wbGVtZW50ZWQsIGl0IGlzIG9ubHkgZG9uZSBmb3IgcmVuZGVyIHRhcmdldHMuIE92ZXJ3cml0ZQogICAgICAgICAgICAgKiB0aGUgZmxhZ3MgdG8gYnJpbmcgdGhlbSBiYWNrIGludG8gYSBzYW5lIHN0YXRlLiBJTlNZU01FTSB3YXMgc2V0IGJlZm9yZSB0byB0ZWxsIExvYWRMb2NhdGlvbiB3aGVyZQogICAgICAgICAgICAgKiB0byByZWFkIHRoZSByZWN0YW5nbGUgZnJvbS4gSW5kcmF3YWJsZSBpcyBzZXQgYmVjYXVzZSBhbGwgbW9kaWZpY2F0aW9ucyBmcm9tIHRoZSBwYXJ0aWFsIHN5c21lbSBjb3B5CiAgICAgICAgICAgICAqIGFyZSB3cml0dGVuIGJhY2sgdG8gdGhlIGRyYXdhYmxlLCB0aHVzIHRoZSBzdXJmYWNlIGlzIG1lcmdlZCBhZ2FpbiBpbiB0aGUgZHJhd2FibGUuIFRoZSBzeXNtZW0gY29weSBpcwogICAgICAgICAgICAgKiBub3QgZnVsbHkgdXAgdG8gZGF0ZSBiZWNhdXNlIG9ubHkgYSBzdWJyZWN0YW5nbGUgd2FzIHJlYWQgaW4gTG9ja1JlY3QuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfSU5TWVNNRU07CiAgICAgICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0lORFJBV0FCTEU7CiAgICAgICAgfQoKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QubGVmdCAgID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgVGhpcy0+ZGlydHlSZWN0LnRvcCAgICA9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QucmlnaHQgID0gMDsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QuYm90dG9tID0gMDsKICAgIH0gZWxzZSBpZihpZmFjZSA9PSBteURldmljZS0+c3RlbmNpbEJ1ZmZlclRhcmdldCkgewogICAgICAgIEZJWE1FKCJEZXB0aCBTdGVuY2lsIGJ1ZmZlciBsb2NraW5nIGlzIG5vdCBpbXBsZW1lbnRlZFxuIik7CiAgICB9IGVsc2UgewogICAgICAgIC8qIFRoZSByZXN0IHNob3VsZCBiZSBhIG5vcm1hbCB0ZXh0dXJlICovCiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKmltcGw7CiAgICAgICAgLyogQ2hlY2sgaWYgdGhlIHRleHR1cmUgaXMgYm91bmQsIGlmIHllcyBkaXJ0aWZ5IHRoZSBzYW1wbGVyIHRvIGZvcmNlIGEgcmUtdXBsb2FkIG9mIHRoZSB0ZXh0dXJlCiAgICAgICAgICogQ2FuJ3QgbG9hZCB0aGUgdGV4dHVyZSBoZXJlIGJlY2F1c2UgUHJlTG9hZCBtYXkgZGVzdHJveSBhbmQgcmVjcmVhdGUgdGhlIGdsIHRleHR1cmUsIHNvIHNhbXBsZXIKICAgICAgICAgKiBzdGF0ZXMgbmVlZCByZXNldHRpbmcKICAgICAgICAgKi8KICAgICAgICBpZihJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKGlmYWNlLCAmSUlEX0lXaW5lRDNEQmFzZVRleHR1cmUsICh2b2lkICoqKSZpbXBsKSA9PSBXSU5FRDNEX09LKSB7CiAgICAgICAgICAgIGlmKGltcGwtPmJhc2VUZXh0dXJlLmJpbmRDb3VudCkgewogICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KG15RGV2aWNlLCBTVEFURV9TQU1QTEVSKGltcGwtPmJhc2VUZXh0dXJlLnNhbXBsZXIpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX1JlbGVhc2UoKElXaW5lRDNEQmFzZVRleHR1cmUgKikgaW1wbCk7CiAgICAgICAgfQogICAgfQoKICAgIHVubG9ja19lbmQ6CiAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfTE9DS0VEOwogICAgbWVtc2V0KCZUaGlzLT5sb2NrZWRSZWN0LCAwLCBzaXplb2YoUkVDVCkpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0REMoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSERDICpwSERDKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIFdJTkVEM0RMT0NLRURfUkVDVCBsb2NrOwogICAgSFJFU1VMVCBocjsKICAgIFJHQlFVQUQgY29sWzI1Nl07CgogICAgVFJBQ0UoIiglcCktPiglcClcbiIsVGhpcyxwSERDKTsKCiAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX1VTRVJQVFIpIHsKICAgICAgICBFUlIoIk5vdCBzdXBwb3J0ZWQgb24gc3VyZmFjZXMgd2l0aCBhbiBhcHBsaWNhdGlvbi1wcm92aWRlZCBzdXJmYWNlc1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEREVSUl9OT0RDOwogICAgfQoKICAgIC8qIEdpdmUgbW9yZSBkZXRhaWxlZCBpbmZvIGZvciBkZHJhdyAqLwogICAgaWYgKFRoaXMtPkZsYWdzICYgU0ZMQUdfRENJTlVTRSkKICAgICAgICByZXR1cm4gV0lORURERVJSX0RDQUxSRUFEWUNSRUFURUQ7CgogICAgLyogQ2FuJ3QgR2V0REMgaWYgdGhlIHN1cmZhY2UgaXMgbG9ja2VkICovCiAgICBpZiAoVGhpcy0+RmxhZ3MgJiBTRkxBR19MT0NLRUQpCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgLyogQWNjb3JkaW5nIHRvIERpcmVjdDNEOSBkb2NzLCBvbmx5IHRoZXNlIGZvcm1hdHMgYXJlIHN1cHBvcnRlZCAqLwogICAgaWYgKCgoSVdpbmVEM0RJbXBsICopVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZS0+d2luZUQzRCktPmR4VmVyc2lvbiA+IDcpIHsKICAgICAgICBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ICE9IFdJTkVEM0RGTVRfUjVHNkI1ICYmCiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCAhPSBXSU5FRDNERk1UX1gxUjVHNUI1ICYmCiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCAhPSBXSU5FRDNERk1UX1I4RzhCOCAmJgogICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgIT0gV0lORUQzREZNVF9YOFI4RzhCOCkgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgbWVtc2V0KCZsb2NrLCAwLCBzaXplb2YobG9jaykpOyAvKiBUbyBiZSBzdXJlICovCgogICAgLyogQ3JlYXRlIGEgRElCIHNlY3Rpb24gaWYgdGhlcmUgaXNuJ3QgYSBoZGMgeWV0ICovCiAgICBpZighVGhpcy0+aERDKSB7CiAgICAgICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfQ3JlYXRlRElCU2VjdGlvbihpZmFjZSk7CiAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19DTElFTlQpIHsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1ByZUxvYWQoaWZhY2UpOwogICAgICAgIH0KCiAgICAgICAgLyogVXNlIHRoZSBkaWIgc2VjdGlvbiBmcm9tIG5vdyBvbiBpZiB3ZSBhcmUgbm90IHVzaW5nIGEgUEJPICovCiAgICAgICAgaWYoIShUaGlzLT5GbGFncyAmIFNGTEFHX1BCTykpCiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IFRoaXMtPmRpYi5iaXRtYXBfZGF0YTsKICAgIH0KCiAgICAvKiBMb2NrIHRoZSBzdXJmYWNlICovCiAgICBociA9IElXaW5lRDNEU3VyZmFjZV9Mb2NrUmVjdChpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZsb2NrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApOwoKICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfUEJPKSB7CiAgICAgICAgLyogU3luYyB0aGUgRElCIHdpdGggdGhlIFBCTy4gVGhpcyBjYW4ndCBiZSBkb25lIGVhcmxpZXIgYmVjYXVzZSBMb2NrUmVjdCBhY3RpdmF0ZXMgdGhlIGFsbG9jYXRlZE1lbW9yeSAqLwogICAgICAgIG1lbWNweShUaGlzLT5kaWIuYml0bWFwX2RhdGEsIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwgVGhpcy0+ZGliLmJpdG1hcF9zaXplKTsKICAgIH0KCiAgICBpZihGQUlMRUQoaHIpKSB7CiAgICAgICAgRVJSKCJJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QgZmFpbGVkIHdpdGggaHIgPSAlMDh4XG4iLCBocik7CiAgICAgICAgLyoga2VlcCB0aGUgZGliIHNlY3Rpb24gKi8KICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgaWYoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUDggfHwKICAgICAgICBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9BOFA4KSB7CiAgICAgICAgLyogR2V0REMgb24gcGFsZXR0aXplZCBmb3JtYXRzIGlzIHVuc3VwcG9ydGVkIGluIEQzRDksIGFuZCB0aGUgbWV0aG9kIGlzIG1pc3NpbmcgaW4KICAgICAgICAgICAgRDNEOCwgc28gdGhpcyBzaG91bGQgb25seSBiZSB1c2VkIGZvciBEWCA8PTcgc3VyZmFjZXMgKHdpdGggbm9uLWRldmljZSBwYWxldHRlcykgKi8KICAgICAgICB1bnNpZ25lZCBpbnQgbjsKICAgICAgICBQQUxFVFRFRU5UUlkgKnBhbCA9IE5VTEw7CgogICAgICAgIGlmKFRoaXMtPnBhbGV0dGUpIHsKICAgICAgICAgICAgcGFsID0gVGhpcy0+cGFsZXR0ZS0+cGFsZW50czsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpkZHNfcHJpbWFyeSA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZS0+ZGRyYXdfcHJpbWFyeTsKICAgICAgICAgICAgaWYgKGRkc19wcmltYXJ5ICYmIGRkc19wcmltYXJ5LT5wYWxldHRlKQogICAgICAgICAgICAgICAgcGFsID0gZGRzX3ByaW1hcnktPnBhbGV0dGUtPnBhbGVudHM7CiAgICAgICAgfQoKICAgICAgICBpZiAocGFsKSB7CiAgICAgICAgICAgIGZvciAobj0wOyBuPDI1NjsgbisrKSB7CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiUmVkICAgPSBwYWxbbl0ucGVSZWQ7CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiR3JlZW4gPSBwYWxbbl0ucGVHcmVlbjsKICAgICAgICAgICAgICAgIGNvbFtuXS5yZ2JCbHVlICA9IHBhbFtuXS5wZUJsdWU7CiAgICAgICAgICAgICAgICBjb2xbbl0ucmdiUmVzZXJ2ZWQgPSAwOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFNldERJQkNvbG9yVGFibGUoVGhpcy0+aERDLCAwLCAyNTYsIGNvbCk7CiAgICAgICAgfQogICAgfQoKICAgICpwSERDID0gVGhpcy0+aERDOwogICAgVFJBQ0UoInJldHVybmluZyAlcFxuIiwqcEhEQyk7CiAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19EQ0lOVVNFOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1JlbGVhc2VEQyhJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBIREMgaERDKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIixUaGlzLGhEQyk7CgogICAgaWYgKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19EQ0lOVVNFKSkKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICBpZiAoVGhpcy0+aERDICE9aERDKSB7CiAgICAgICAgV0FSTigiQXBwbGljYXRpb24gdHJpZXMgdG8gcmVsZWFzZSBhbiBpbnZhbGlkIERDKCVwKSwgc3VyZmFjZSBkYyBpcyAlcFxuIiwgaERDLCBUaGlzLT5oREMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmKChUaGlzLT5GbGFncyAmIFNGTEFHX1BCTykgJiYgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KSB7CiAgICAgICAgLyogQ29weSB0aGUgY29udGVudHMgb2YgdGhlIERJQiBvdmVyIHRvIHRoZSBQQk8gKi8KICAgICAgICBtZW1jcHkoVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5LCBUaGlzLT5kaWIuYml0bWFwX2RhdGEsIFRoaXMtPmRpYi5iaXRtYXBfc2l6ZSk7CiAgICB9CgogICAgLyogd2UgbG9ja2VkIGZpcnN0LCBzbyB1bmxvY2sgbm93ICovCiAgICBJV2luZUQzRFN1cmZhY2VfVW5sb2NrUmVjdChpZmFjZSk7CgogICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0RDSU5VU0U7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICBJV2luZUQzRFN1cmZhY2UgSW50ZXJuYWwgKE5vIG1hcHBpbmcgdG8gZGlyZWN0eCBhcGkpIHBhcnRzIGZvbGxvdwogICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KCkhSRVNVTFQgZDNkZm10X2dldF9jb252KElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMsIEJPT0wgbmVlZF9hbHBoYV9jaywgQk9PTCB1c2VfdGV4dHVyaW5nLCBHTGVudW0gKmZvcm1hdCwgR0xlbnVtICppbnRlcm5hbCwgR0xlbnVtICp0eXBlLCBDT05WRVJUX1RZUEVTICpjb252ZXJ0LCBpbnQgKnRhcmdldF9icHAsIEJPT0wgc3JnYl9tb2RlKSB7CiAgICBCT09MIGNvbG9ya2V5X2FjdGl2ZSA9IG5lZWRfYWxwaGFfY2sgJiYgKFRoaXMtPkNLZXlGbGFncyAmIFdJTkVERFNEX0NLU1JDQkxUKTsKICAgIGNvbnN0IEdsUGl4ZWxGb3JtYXREZXNjICpnbERlc2M7CiAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICBnZXRGb3JtYXREZXNjRW50cnkoVGhpcy0+cmVzb3VyY2UuZm9ybWF0LCAmR0xJTkZPX0xPQ0FUSU9OLCAmZ2xEZXNjKTsKCiAgICAvKiBEZWZhdWx0IHZhbHVlczogRnJvbSB0aGUgc3VyZmFjZSAqLwogICAgKmZvcm1hdCA9IGdsRGVzYy0+Z2xGb3JtYXQ7CiAgICAqdHlwZSA9IGdsRGVzYy0+Z2xUeXBlOwogICAgKmNvbnZlcnQgPSBOT19DT05WRVJTSU9OOwogICAgKnRhcmdldF9icHAgPSBUaGlzLT5ieXRlc1BlclBpeGVsOwoKICAgIGlmKHNyZ2JfbW9kZSkgewogICAgICAgICppbnRlcm5hbCA9IGdsRGVzYy0+Z2xHYW1tYUludGVybmFsOwogICAgfSBlbHNlIGlmKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgewogICAgICAgICppbnRlcm5hbCA9IGdsRGVzYy0+cnRJbnRlcm5hbDsKICAgIH0gZWxzZSB7CiAgICAgICAgKmludGVybmFsID0gZ2xEZXNjLT5nbEludGVybmFsOwogICAgfQoKICAgIC8qIE9rLCBub3cgbG9vayBpZiB3ZSBoYXZlIHRvIGRvIGFueSBjb252ZXJzaW9uICovCiAgICBzd2l0Y2goVGhpcy0+cmVzb3VyY2UuZm9ybWF0KSB7CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1A4OgogICAgICAgICAgICAvKiAqKioqKioqKioqKioqKioqCiAgICAgICAgICAgICAgICBQYWxldHRlZCBUZXh0dXJlCiAgICAgICAgICAgICAgICAqKioqKioqKioqKioqKioqICovCgogICAgICAgICAgICAgLyogVXNlIGNvbnZlcnNpb24gd2hlbiB0aGUgcGFsZXR0ZWQgdGV4dHVyZSBleHRlbnNpb24gT1IgZnJhZ21lbnQgc2hhZGVycyBhcmUgYXZhaWxhYmxlLiBXaGVuIGVpdGhlcgogICAgICAgICAgICAgKiBvZiB0aGUgdHdvIGlzIGF2YWlsYWJsZSBtYWtlIHN1cmUgdGV4dHVyaW5nIGlzIHJlcXVlc3RlZCBhcyBuZWl0aGVyIG9mIHRoZSB0d28gd29ya3MgaW4KICAgICAgICAgICAgICogY29uanVuY3Rpb24gd2l0aCBjYWxscyBsaWtlIGdsRHJhdy0vZ2xSZWFkUGl4ZWxzLiBGdXJ0aGVyIGFsc28gdXNlIGNvbnZlcnNpb24gaW4gY2FzZSBvZiBjb2xvciBrZXlpbmcuCiAgICAgICAgICAgICAqIFBhbGV0dGVkIHRleHR1cmVzIGNhbiBiZSBlbXVsYXRlZCB1c2luZyBzaGFkZXJzIGJ1dCBvbmx5IGRvIHRoYXQgZm9yIDJEIHB1cnBvc2VzIGUuZy4gc2l0dWF0aW9ucwogICAgICAgICAgICAgKiBpbiB3aGljaCB0aGUgbWFpbiByZW5kZXIgdGFyZ2V0IHVzZXMgcDguIFNvbWUgZ2FtZXMgbGlrZSBHVEEgVmljZSBDaXR5IHVzZSBQOCBmb3IgdGV4dHVyaW5nIHdoaWNoCiAgICAgICAgICAgICAqIGNvbmZsaWN0cyB3aXRoIHRoaXMuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiggIShHTF9TVVBQT1JUKEVYVF9QQUxFVFRFRF9URVhUVVJFKSB8fCAoR0xfU1VQUE9SVChBUkJfRlJBR01FTlRfUFJPR1JBTSkgJiYgcHJpbWFyeV9yZW5kZXJfdGFyZ2V0X2lzX3A4KGRldmljZSkpKSB8fCBjb2xvcmtleV9hY3RpdmUgfHwgIXVzZV90ZXh0dXJpbmcgKSB7CiAgICAgICAgICAgICAgICAqZm9ybWF0ID0gR0xfUkdCQTsKICAgICAgICAgICAgICAgICppbnRlcm5hbCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqdHlwZSA9IEdMX1VOU0lHTkVEX0JZVEU7CiAgICAgICAgICAgICAgICAqdGFyZ2V0X2JwcCA9IDQ7CiAgICAgICAgICAgICAgICBpZihjb2xvcmtleV9hY3RpdmUpIHsKICAgICAgICAgICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfUEFMRVRURURfQ0s7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICpjb252ZXJ0ID0gQ09OVkVSVF9QQUxFVFRFRDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmKCFHTF9TVVBQT1JUKEVYVF9QQUxFVFRFRF9URVhUVVJFKSAmJiBHTF9TVVBQT1JUKEFSQl9GUkFHTUVOVF9QUk9HUkFNKSkgewogICAgICAgICAgICAgICAgKmZvcm1hdCA9IEdMX0FMUEhBOwogICAgICAgICAgICAgICAgKmludGVybmFsID0gR0xfUkdCQTsKICAgICAgICAgICAgICAgICp0eXBlID0gR0xfVU5TSUdORURfQllURTsKICAgICAgICAgICAgICAgICp0YXJnZXRfYnBwID0gMTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9SM0czQjI6CiAgICAgICAgICAgIC8qICoqKioqKioqKioqKioqKioqKioqKioKICAgICAgICAgICAgICAgIEdMX1VOU0lHTkVEX0JZVEVfM18zXzIKICAgICAgICAgICAgICAgICoqKioqKioqKioqKioqKioqKioqKiogKi8KICAgICAgICAgICAgaWYgKGNvbG9ya2V5X2FjdGl2ZSkgewogICAgICAgICAgICAgICAgLyogVGhpcyB0ZXh0dXJlIGZvcm1hdCB3aWxsIG5ldmVyIGJlIHVzZWQuLiBTbyBkbyBub3QgY2FyZSBhYm91dCBjb2xvciBrZXlpbmcKICAgICAgICAgICAgICAgICAgICB1cCB1bnRpbCB0aGUgcG9pbnQgaW4gdGltZSBpdCB3aWxsIGJlIG5lZWRlZCA6LSkgKi8KICAgICAgICAgICAgICAgIEZJWE1FKCIgQ29sb3JLZXlpbmcgbm90IHN1cHBvcnRlZCBpbiB0aGUgUkdCIDMzMiBmb3JtYXQgIVxuIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9SNUc2QjU6CiAgICAgICAgICAgIGlmIChjb2xvcmtleV9hY3RpdmUpIHsKICAgICAgICAgICAgICAgICpjb252ZXJ0ID0gQ09OVkVSVF9DS181NjU7CiAgICAgICAgICAgICAgICAqZm9ybWF0ID0gR0xfUkdCQTsKICAgICAgICAgICAgICAgICppbnRlcm5hbCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqdHlwZSA9IEdMX1VOU0lHTkVEX1NIT1JUXzVfNV81XzE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9YMVI1RzVCNToKICAgICAgICAgICAgaWYgKGNvbG9ya2V5X2FjdGl2ZSkgewogICAgICAgICAgICAgICAgKmNvbnZlcnQgPSBDT05WRVJUX0NLXzU1NTE7CiAgICAgICAgICAgICAgICAqZm9ybWF0ID0gR0xfQkdSQTsKICAgICAgICAgICAgICAgICppbnRlcm5hbCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqdHlwZSA9IEdMX1VOU0lHTkVEX1NIT1JUXzFfNV81XzVfUkVWOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjhHOEI4OgogICAgICAgICAgICBpZiAoY29sb3JrZXlfYWN0aXZlKSB7CiAgICAgICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfQ0tfUkdCMjQ7CiAgICAgICAgICAgICAgICAqZm9ybWF0ID0gR0xfUkdCQTsKICAgICAgICAgICAgICAgICppbnRlcm5hbCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqdHlwZSA9IEdMX1VOU0lHTkVEX0lOVF84XzhfOF84OwogICAgICAgICAgICAgICAgKnRhcmdldF9icHAgPSA0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDhSOEc4Qjg6CiAgICAgICAgICAgIGlmIChjb2xvcmtleV9hY3RpdmUpIHsKICAgICAgICAgICAgICAgICpjb252ZXJ0ID0gQ09OVkVSVF9SR0IzMl84ODg7CiAgICAgICAgICAgICAgICAqZm9ybWF0ID0gR0xfUkdCQTsKICAgICAgICAgICAgICAgICppbnRlcm5hbCA9IEdMX1JHQkE7CiAgICAgICAgICAgICAgICAqdHlwZSA9IEdMX1VOU0lHTkVEX0lOVF84XzhfOF84OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfVjhVODoKICAgICAgICAgICAgaWYoR0xfU1VQUE9SVChOVl9URVhUVVJFX1NIQURFUjMpKSBicmVhazsKICAgICAgICAgICAgZWxzZSBpZihHTF9TVVBQT1JUKEFUSV9FTlZNQVBfQlVNUE1BUCkpIHsKICAgICAgICAgICAgICAgICpmb3JtYXQgPSBHTF9EVURWX0FUSTsKICAgICAgICAgICAgICAgICppbnRlcm5hbCA9IEdMX0RVOERWOF9BVEk7CiAgICAgICAgICAgICAgICAqdHlwZSA9IEdMX0JZVEU7CiAgICAgICAgICAgICAgICAvKiBObyBjb252ZXJzaW9uIC0gSnVzdCBjaGFuZ2UgdGhlIGdsIHR5cGUgKi8KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgICpjb252ZXJ0ID0gQ09OVkVSVF9WOFU4OwogICAgICAgICAgICAqZm9ybWF0ID0gR0xfQkdSOwogICAgICAgICAgICAqaW50ZXJuYWwgPSBHTF9SR0I4OwogICAgICAgICAgICAqdHlwZSA9IEdMX1VOU0lHTkVEX0JZVEU7CiAgICAgICAgICAgICp0YXJnZXRfYnBwID0gMzsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9MNlY1VTU6CiAgICAgICAgICAgICpjb252ZXJ0ID0gQ09OVkVSVF9MNlY1VTU7CiAgICAgICAgICAgIGlmKEdMX1NVUFBPUlQoTlZfVEVYVFVSRV9TSEFERVIpKSB7CiAgICAgICAgICAgICAgICAqdGFyZ2V0X2JwcCA9IDM7CiAgICAgICAgICAgICAgICAvKiBVc2UgZm9ybWF0IGFuZCB0eXBlcyBmcm9tIHRhYmxlICovCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvKiBMb2FkIGl0IGludG8gdW5zaWduZWQgUjVHNkI1LCBzd2FwIEwgYW5kIFYgY2hhbm5lbHMsIGFuZCByZXZlcnQgdGhhdCBpbiB0aGUgc2hhZGVyICovCiAgICAgICAgICAgICAgICAqdGFyZ2V0X2JwcCA9IDI7CiAgICAgICAgICAgICAgICAqZm9ybWF0ID0gR0xfUkdCOwogICAgICAgICAgICAgICAgKmludGVybmFsID0gR0xfUkdCNTsKICAgICAgICAgICAgICAgICp0eXBlID0gR0xfVU5TSUdORURfU0hPUlRfNV82XzU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9YOEw4VjhVODoKICAgICAgICAgICAgKmNvbnZlcnQgPSBDT05WRVJUX1g4TDhWOFU4OwogICAgICAgICAgICAqdGFyZ2V0X2JwcCA9IDQ7CiAgICAgICAgICAgIGlmKEdMX1NVUFBPUlQoTlZfVEVYVFVSRV9TSEFERVIpKSB7CiAgICAgICAgICAgICAgICAvKiBVc2UgZm9ybWF0cyBmcm9tIGdsIHRhYmxlLiBJdCBpcyBhIGJpdCB1bmZvcnR1bmF0ZSwgYnV0IHRoZSBjb252ZXJzaW9uCiAgICAgICAgICAgICAgICAgKiBpcyBuZWVkZWQgdG8gc2V0IHRoZSBYIGZvcm1hdCB0byAyNTUgdG8gZ2V0IDEuMCBmb3IgYWxwaGEgd2hlbiBzYW1wbGluZwogICAgICAgICAgICAgICAgICogdGhlIHRleHR1cmUuIE9wZW5HTCBjYW4ndCB1c2UgR0xfRFNEVDhfTUFHOF9OViBhcyBpbnRlcm5hbCBmb3JtYXQgd2l0aAogICAgICAgICAgICAgICAgICogdGhlIG5lZWRlZCB0eXBlIGFuZCBmb3JtYXQgcGFyYW1ldGVyLCBzbyB0aGUgaW50ZXJuYWwgZm9ybWF0IGNvbnRhaW5zIGEKICAgICAgICAgICAgICAgICAqIDR0aCBjb21wb25lbnQsIHdoaWNoIGlzIHJldHVybmVkIGFzIGFscGhhCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8qIE5vdCBzdXBwb3J0ZWQgYnkgR0xfQVRJX2Vudm1hcF9idW1wbWFwICovCiAgICAgICAgICAgICAgICAqZm9ybWF0ID0gR0xfQkdSQTsKICAgICAgICAgICAgICAgICppbnRlcm5hbCA9IEdMX1JHQjg7CiAgICAgICAgICAgICAgICAqdHlwZSA9IEdMX1VOU0lHTkVEX0lOVF84XzhfOF84X1JFVjsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1E4VzhWOFU4OgogICAgICAgICAgICBpZihHTF9TVVBQT1JUKE5WX1RFWFRVUkVfU0hBREVSMykpIGJyZWFrOwogICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfUThXOFY4VTg7CiAgICAgICAgICAgICpmb3JtYXQgPSBHTF9CR1JBOwogICAgICAgICAgICAqaW50ZXJuYWwgPSBHTF9SR0JBODsKICAgICAgICAgICAgKnR5cGUgPSBHTF9VTlNJR05FRF9CWVRFOwogICAgICAgICAgICAqdGFyZ2V0X2JwcCA9IDQ7CiAgICAgICAgICAgIC8qIE5vdCBzdXBwb3J0ZWQgYnkgR0xfQVRJX2Vudm1hcF9idW1wbWFwICovCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfVjE2VTE2OgogICAgICAgICAgICBpZihHTF9TVVBQT1JUKE5WX1RFWFRVUkVfU0hBREVSMykpIGJyZWFrOwogICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfVjE2VTE2OwogICAgICAgICAgICAqZm9ybWF0ID0gR0xfQkdSOwogICAgICAgICAgICAqaW50ZXJuYWwgPSBHTF9SR0IxNl9FWFQ7CiAgICAgICAgICAgICp0eXBlID0gR0xfVU5TSUdORURfU0hPUlQ7CiAgICAgICAgICAgICp0YXJnZXRfYnBwID0gNjsKICAgICAgICAgICAgLyogV2hhdCBzaG91bGQgSSBkbyBoZXJlIGFib3V0IEdMX0FUSV9lbnZtYXBfYnVtcG1hcD8KICAgICAgICAgICAgICogQ29udmVydCBpdCBvciBhbGxvdyBkYXRhIGxvc3MgYnkgbG9hZGluZyBpdCBpbnRvIGEgOCBiaXQgLyBjaGFubmVsIHRleHR1cmU/CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX0E0TDQ6CiAgICAgICAgICAgIC8qIEE0TDQgZXhpc3RzIGFzIGFuIGludGVybmFsIGdsIGZvcm1hdCwgYnV0IGZvciBzb21lIHJlYXNvbiB0aGVyZSBpcyBub3QKICAgICAgICAgICAgICogZm9ybWF0K3R5cGUgY29tYmluYXRpb24gdG8gbG9hZCBpdC4gVGh1cyBjb252ZXJ0IGl0IHRvIEE4TDgsIHRoZW4gbG9hZCBpdAogICAgICAgICAgICAgKiB3aXRoIEE0TDQgaW50ZXJuYWwsIGJ1dCBBOEw4IGZvcm1hdCt0eXBlCiAgICAgICAgICAgICAqLwogICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfQTRMNDsKICAgICAgICAgICAgKmZvcm1hdCA9IEdMX0xVTUlOQU5DRV9BTFBIQTsKICAgICAgICAgICAgKmludGVybmFsID0gR0xfTFVNSU5BTkNFNF9BTFBIQTQ7CiAgICAgICAgICAgICp0eXBlID0gR0xfVU5TSUdORURfQllURTsKICAgICAgICAgICAgKnRhcmdldF9icHAgPSAyOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1IzMkY6CiAgICAgICAgICAgIC8qIENhbiBiZSBsb2FkZWQgaW4gdGhlb3J5IHdpdGggZm10PUdMX1JFRCwgdHlwZT1HTF9GTE9BVCwgYnV0IHRoaXMgZmFpbHMuIFRoZSByZWFzb24KICAgICAgICAgICAgICogaXMgdGhhdCBEM0QgZXhwZWN0cyB0aGUgdW5kZWZpbmVkIGdyZWVuLCBibHVlIGFuZCBhbHBoYSBjaGFubmVscyB0byByZXR1cm4gMS4wCiAgICAgICAgICAgICAqIHdoZW4gc2FtcGxpbmcsIGJ1dCBPcGVuR0wgc2V0cyBncmVlbiBhbmQgYmx1ZSB0byAwLjAgaW5zdGVhZC4gVGh1cyB3ZSBoYXZlIHRvIGluamVjdAogICAgICAgICAgICAgKiAxLjAgaW5zdGVhZC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogVGhlIGFscGhhIGNoYW5uZWwgZGVmYXVsdHMgdG8gMS4wIGluIG9wZW5nbCwgc28gbm90aGluZyBoYXMgdG8gYmUgZG9uZSBhYm91dCBpdC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgICpjb252ZXJ0ID0gQ09OVkVSVF9SMzJGOwogICAgICAgICAgICAqZm9ybWF0ID0gR0xfUkdCOwogICAgICAgICAgICAqaW50ZXJuYWwgPSBHTF9SR0IzMkZfQVJCOwogICAgICAgICAgICAqdHlwZSA9IEdMX0ZMT0FUOwogICAgICAgICAgICAqdGFyZ2V0X2JwcCA9IDEyOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1IxNkY6CiAgICAgICAgICAgIC8qIFNpbWlsYXIgdG8gUjMyRiAqLwogICAgICAgICAgICAqY29udmVydCA9IENPTlZFUlRfUjE2RjsKICAgICAgICAgICAgKmZvcm1hdCA9IEdMX1JHQjsKICAgICAgICAgICAgKmludGVybmFsID0gR0xfUkdCMTZGX0FSQjsKICAgICAgICAgICAgKnR5cGUgPSBHTF9IQUxGX0ZMT0FUX0FSQjsKICAgICAgICAgICAgKnRhcmdldF9icHAgPSA2OwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX0cxNlIxNjoKICAgICAgICAgICAgKmNvbnZlcnQgPSBDT05WRVJUX0cxNlIxNjsKICAgICAgICAgICAgKmZvcm1hdCA9IEdMX1JHQjsKICAgICAgICAgICAgKmludGVybmFsID0gR0xfUkdCMTZfRVhUOwogICAgICAgICAgICAqdHlwZSA9IEdMX1VOU0lHTkVEX1NIT1JUOwogICAgICAgICAgICAqdGFyZ2V0X2JwcCA9IDY7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBkM2RmbXRfY29udmVydF9zdXJmYWNlKEJZVEUgKnNyYywgQllURSAqZHN0LCBVSU5UIHBpdGNoLCBVSU5UIHdpZHRoLCBVSU5UIGhlaWdodCwgVUlOVCBvdXRwaXRjaCwgQ09OVkVSVF9UWVBFUyBjb252ZXJ0LCBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzKSB7CiAgICBCWVRFICpzb3VyY2UsICpkZXN0OwogICAgVFJBQ0UoIiglcCktPiglcCksKCVkLCVkLCVkLCVkLCVwKVxuIiwgc3JjLCBkc3QsIHBpdGNoLCBoZWlnaHQsIG91dHBpdGNoLCBjb252ZXJ0LFRoaXMpOwoKICAgIHN3aXRjaCAoY29udmVydCkgewogICAgICAgIGNhc2UgTk9fQ09OVkVSU0lPTjoKICAgICAgICB7CiAgICAgICAgICAgIG1lbWNweShkc3QsIHNyYywgcGl0Y2ggKiBoZWlnaHQpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY2FzZSBDT05WRVJUX1BBTEVUVEVEOgogICAgICAgIGNhc2UgQ09OVkVSVF9QQUxFVFRFRF9DSzoKICAgICAgICB7CiAgICAgICAgICAgIElXaW5lRDNEUGFsZXR0ZUltcGwqIHBhbCA9IFRoaXMtPnBhbGV0dGU7CiAgICAgICAgICAgIEJZVEUgdGFibGVbMjU2XVs0XTsKICAgICAgICAgICAgdW5zaWduZWQgaW50IHgsIHk7CgogICAgICAgICAgICBpZiggcGFsID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIC8qIFRPRE86IElmIHdlIGFyZSBhIHN1YmxldmVsLCB0cnkgdG8gZ2V0IHRoZSBwYWxldHRlIGZyb20gbGV2ZWwgMCAqLwogICAgICAgICAgICB9CgogICAgICAgICAgICBkM2RmbXRfcDhfaW5pdF9wYWxldHRlKFRoaXMsIHRhYmxlLCAoY29udmVydCA9PSBDT05WRVJUX1BBTEVUVEVEX0NLKSk7CgogICAgICAgICAgICBmb3IgKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHNvdXJjZSA9IHNyYyArIHBpdGNoICogeTsKICAgICAgICAgICAgICAgIGRlc3QgPSBkc3QgKyBvdXRwaXRjaCAqIHk7CiAgICAgICAgICAgICAgICAvKiBUaGlzIGlzIGFuIDEgYnBwIGZvcm1hdCwgdXNpbmcgdGhlIHdpZHRoIGhlcmUgaXMgZmluZSAqLwogICAgICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKICAgICAgICAgICAgICAgICAgICBCWVRFIGNvbG9yID0gKnNvdXJjZSsrOwogICAgICAgICAgICAgICAgICAgICpkZXN0KysgPSB0YWJsZVtjb2xvcl1bMF07CiAgICAgICAgICAgICAgICAgICAgKmRlc3QrKyA9IHRhYmxlW2NvbG9yXVsxXTsKICAgICAgICAgICAgICAgICAgICAqZGVzdCsrID0gdGFibGVbY29sb3JdWzJdOwogICAgICAgICAgICAgICAgICAgICpkZXN0KysgPSB0YWJsZVtjb2xvcl1bM107CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgQ09OVkVSVF9DS181NjU6CiAgICAgICAgewogICAgICAgICAgICAvKiBDb252ZXJ0aW5nIHRoZSA1NjUgZm9ybWF0IGluIDU1NTEgcGFja2VkIHRvIGVtdWxhdGUgY29sb3Ita2V5aW5nLgoKICAgICAgICAgICAgICBOb3RlIDogaW4gYWxsIHRoZXNlIGNvbnZlcnNpb24sIGl0IHdvdWxkIGJlIGJlc3QgdG8gYXZlcmFnZSB0aGUgYXZlcmFnaW5nCiAgICAgICAgICAgICAgICAgICAgICBwaXhlbHMgdG8gZ2V0IHRoZSBjb2xvciBvZiB0aGUgcGl4ZWwgdGhhdCB3aWxsIGJlIGNvbG9yLWtleWVkIHRvCiAgICAgICAgICAgICAgICAgICAgICBwcmV2ZW50ICdjb2xvciBibGVlZGluZycuIFRoaXMgd2lsbCBiZSBkb25lIGxhdGVyIG9uIGlmIGV2ZXIgaXQgaXMKICAgICAgICAgICAgICAgICAgICAgIHRvbyB2aXNpYmxlLgoKICAgICAgICAgICAgICBOb3RlMjogTnZpZGlhIGRvY3VtZW50cyBzYXkgdGhhdCB0aGVpciBkcml2ZXIgZG9lcyBub3Qgc3VwcG9ydCBhbHBoYSArIGNvbG9yIGtleWluZwogICAgICAgICAgICAgICAgICAgICBvbiB0aGUgc2FtZSBzdXJmYWNlIGFuZCBkaXNhYmxlcyBjb2xvciBrZXlpbmcgaW4gc3VjaCBhIGNhc2UKICAgICAgICAgICAgKi8KICAgICAgICAgICAgdW5zaWduZWQgaW50IHgsIHk7CiAgICAgICAgICAgIFdPUkQgKlNvdXJjZTsKICAgICAgICAgICAgV09SRCAqRGVzdDsKCiAgICAgICAgICAgIFRSQUNFKCJDb2xvciBrZXllZCA1NjVcbiIpOwoKICAgICAgICAgICAgZm9yICh5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CiAgICAgICAgICAgICAgICBTb3VyY2UgPSAoV09SRCAqKSAoc3JjICsgeSAqIHBpdGNoKTsKICAgICAgICAgICAgICAgIERlc3QgPSAoV09SRCAqKSAoZHN0ICsgeSAqIG91dHBpdGNoKTsKICAgICAgICAgICAgICAgIGZvciAoeCA9IDA7IHggPCB3aWR0aDsgeCsrICkgewogICAgICAgICAgICAgICAgICAgIFdPUkQgY29sb3IgPSAqU291cmNlKys7CiAgICAgICAgICAgICAgICAgICAgKkRlc3QgPSAoKGNvbG9yICYgMHhGRkMwKSB8ICgoY29sb3IgJiAweDFGKSA8PCAxKSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKChjb2xvciA8IFRoaXMtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWUpIHx8CiAgICAgICAgICAgICAgICAgICAgICAgIChjb2xvciA+IFRoaXMtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlKSkgewogICAgICAgICAgICAgICAgICAgICAgICAqRGVzdCB8PSAweDAwMDE7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIERlc3QrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBDT05WRVJUX0NLXzU1NTE6CiAgICAgICAgewogICAgICAgICAgICAvKiBDb252ZXJ0aW5nIFgxUjVHNUI1IGZvcm1hdCB0byBSNUc1QjVBMSB0byBlbXVsYXRlIGNvbG9yLWtleWluZy4gKi8KICAgICAgICAgICAgdW5zaWduZWQgaW50IHgsIHk7CiAgICAgICAgICAgIFdPUkQgKlNvdXJjZTsKICAgICAgICAgICAgV09SRCAqRGVzdDsKICAgICAgICAgICAgVFJBQ0UoIkNvbG9yIGtleWVkIDU1NTFcbiIpOwogICAgICAgICAgICBmb3IgKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKICAgICAgICAgICAgICAgIFNvdXJjZSA9IChXT1JEICopIChzcmMgKyB5ICogcGl0Y2gpOwogICAgICAgICAgICAgICAgRGVzdCA9IChXT1JEICopIChkc3QgKyB5ICogb3V0cGl0Y2gpOwogICAgICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KysgKSB7CiAgICAgICAgICAgICAgICAgICAgV09SRCBjb2xvciA9ICpTb3VyY2UrKzsKCQkgICAgKkRlc3QgPSBjb2xvcjsKICAgICAgICAgICAgICAgICAgICBpZiAoKGNvbG9yIDwgVGhpcy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZSkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgKGNvbG9yID4gVGhpcy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICpEZXN0IHw9ICgxIDw8IDE1KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICpEZXN0ICY9IH4oMSA8PCAxNSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIERlc3QrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBDT05WRVJUX1JHQjMyXzg4ODoKICAgICAgICB7CiAgICAgICAgICAgIC8qIENvbnZlcnRpbmcgWDhSOEc4QjggZm9ybWF0IHRvIFI4RzhCOEE4IHdpdGggY29sb3Ita2V5aW5nLiAqLwogICAgICAgICAgICB1bnNpZ25lZCBpbnQgeCwgeTsKICAgICAgICAgICAgZm9yICh5ID0gMDsgeSA8IGhlaWdodDsgeSsrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzb3VyY2UgPSBzcmMgKyBwaXRjaCAqIHk7CiAgICAgICAgICAgICAgICBkZXN0ID0gZHN0ICsgb3V0cGl0Y2ggKiB5OwogICAgICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKICAgICAgICAgICAgICAgICAgICBEV09SRCBjb2xvciA9IDB4ZmZmZmZmICYgKihEV09SRCopc291cmNlOwogICAgICAgICAgICAgICAgICAgIERXT1JEIGRzdGNvbG9yID0gY29sb3IgPDwgODsKICAgICAgICAgICAgICAgICAgICBpZiAoKGNvbG9yIDwgVGhpcy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZSkgfHwKICAgICAgICAgICAgICAgICAgICAgICAgKGNvbG9yID4gVGhpcy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWUpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGRzdGNvbG9yIHw9IDB4ZmY7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICooRFdPUkQqKWRlc3QgPSBkc3Rjb2xvcjsKICAgICAgICAgICAgICAgICAgICBzb3VyY2UgKz0gNDsKICAgICAgICAgICAgICAgICAgICBkZXN0ICs9IDQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgQ09OVkVSVF9WOFU4OgogICAgICAgIHsKICAgICAgICAgICAgdW5zaWduZWQgaW50IHgsIHk7CiAgICAgICAgICAgIHNob3J0ICpTb3VyY2U7CiAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgKkRlc3Q7CiAgICAgICAgICAgIGZvcih5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CiAgICAgICAgICAgICAgICBTb3VyY2UgPSAoc2hvcnQgKikgKHNyYyArIHkgKiBwaXRjaCk7CiAgICAgICAgICAgICAgICBEZXN0ID0gZHN0ICsgeSAqIG91dHBpdGNoOwogICAgICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KysgKSB7CiAgICAgICAgICAgICAgICAgICAgbG9uZyBjb2xvciA9ICgqU291cmNlKyspOwogICAgICAgICAgICAgICAgICAgIC8qIEIgKi8gRGVzdFswXSA9IDB4ZmY7CiAgICAgICAgICAgICAgICAgICAgLyogRyAqLyBEZXN0WzFdID0gKGNvbG9yID4+IDgpICsgMTI4OyAvKiBWICovCiAgICAgICAgICAgICAgICAgICAgLyogUiAqLyBEZXN0WzJdID0gKGNvbG9yKSArIDEyODsgICAgICAvKiBVICovCiAgICAgICAgICAgICAgICAgICAgRGVzdCArPSAzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBDT05WRVJUX1YxNlUxNjoKICAgICAgICB7CiAgICAgICAgICAgIHVuc2lnbmVkIGludCB4LCB5OwogICAgICAgICAgICBEV09SRCAqU291cmNlOwogICAgICAgICAgICB1bnNpZ25lZCBzaG9ydCAqRGVzdDsKICAgICAgICAgICAgZm9yKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKICAgICAgICAgICAgICAgIFNvdXJjZSA9IChEV09SRCAqKSAoc3JjICsgeSAqIHBpdGNoKTsKICAgICAgICAgICAgICAgIERlc3QgPSAodW5zaWduZWQgc2hvcnQgKikgKGRzdCArIHkgKiBvdXRwaXRjaCk7CiAgICAgICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKyApIHsKICAgICAgICAgICAgICAgICAgICBEV09SRCBjb2xvciA9ICgqU291cmNlKyspOwogICAgICAgICAgICAgICAgICAgIC8qIEIgKi8gRGVzdFswXSA9IDB4ZmZmZjsKICAgICAgICAgICAgICAgICAgICAvKiBHICovIERlc3RbMV0gPSAoY29sb3IgPj4gMTYpICsgMzI3Njg7IC8qIFYgKi8KICAgICAgICAgICAgICAgICAgICAvKiBSICovIERlc3RbMl0gPSAoY29sb3IgICAgICApICsgMzI3Njg7IC8qIFUgKi8KICAgICAgICAgICAgICAgICAgICBEZXN0ICs9IDM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBjYXNlIENPTlZFUlRfUThXOFY4VTg6CiAgICAgICAgewogICAgICAgICAgICB1bnNpZ25lZCBpbnQgeCwgeTsKICAgICAgICAgICAgRFdPUkQgKlNvdXJjZTsKICAgICAgICAgICAgdW5zaWduZWQgY2hhciAqRGVzdDsKICAgICAgICAgICAgZm9yKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKICAgICAgICAgICAgICAgIFNvdXJjZSA9IChEV09SRCAqKSAoc3JjICsgeSAqIHBpdGNoKTsKICAgICAgICAgICAgICAgIERlc3QgPSBkc3QgKyB5ICogb3V0cGl0Y2g7CiAgICAgICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKyApIHsKICAgICAgICAgICAgICAgICAgICBsb25nIGNvbG9yID0gKCpTb3VyY2UrKyk7CiAgICAgICAgICAgICAgICAgICAgLyogQiAqLyBEZXN0WzBdID0gKChjb2xvciA+PiAxNikgJiAweGZmKSArIDEyODsgLyogVyAqLwogICAgICAgICAgICAgICAgICAgIC8qIEcgKi8gRGVzdFsxXSA9ICgoY29sb3IgPj4gOCApICYgMHhmZikgKyAxMjg7IC8qIFYgKi8KICAgICAgICAgICAgICAgICAgICAvKiBSICovIERlc3RbMl0gPSAoY29sb3IgICAgICAgICAmIDB4ZmYpICsgMTI4OyAvKiBVICovCiAgICAgICAgICAgICAgICAgICAgLyogQSAqLyBEZXN0WzNdID0gKChjb2xvciA+PiAyNCkgJiAweGZmKSArIDEyODsgLyogUSAqLwogICAgICAgICAgICAgICAgICAgIERlc3QgKz0gNDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgQ09OVkVSVF9MNlY1VTU6CiAgICAgICAgewogICAgICAgICAgICB1bnNpZ25lZCBpbnQgeCwgeTsKICAgICAgICAgICAgV09SRCAqU291cmNlOwogICAgICAgICAgICB1bnNpZ25lZCBjaGFyICpEZXN0OwoKICAgICAgICAgICAgaWYoR0xfU1VQUE9SVChOVl9URVhUVVJFX1NIQURFUikpIHsKICAgICAgICAgICAgICAgIC8qIFRoaXMgbWFrZXMgdGhlIGdsIHN1cmZhY2UgYmlnZ2VyKDI0IGJpdCBpbnN0ZWFkIG9mIDE2KSwgYnV0IGl0IHdvcmtzIHdpdGgKICAgICAgICAgICAgICAgICAqIGZpeGVkIGZ1bmN0aW9uIGFuZCBzaGFkZXJzIHdpdGhvdXQgZnVydGhlciBjb252ZXJzaW9uIG9uY2UgdGhlIHN1cmZhY2UgaXMKICAgICAgICAgICAgICAgICAqIGxvYWRlZAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBmb3IoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewogICAgICAgICAgICAgICAgICAgIFNvdXJjZSA9IChXT1JEICopIChzcmMgKyB5ICogcGl0Y2gpOwogICAgICAgICAgICAgICAgICAgIERlc3QgPSBkc3QgKyB5ICogb3V0cGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KysgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNob3J0IGNvbG9yID0gKCpTb3VyY2UrKyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgbCA9ICgoY29sb3IgPj4gMTApICYgMHhmYyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyIHYgPSAoKGNvbG9yID4+ICA1KSAmIDB4M2UpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhciB1ID0gKChjb2xvciAgICAgICkgJiAweDFmKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8qIDggYml0cyBkZXN0aW5hdGlvbiwgNiBiaXRzIHNvdXJjZSwgOHRoIGJpdCBpcyB0aGUgc2lnbi4gZ2wgaWdub3JlcyB0aGUgc2lnbgogICAgICAgICAgICAgICAgICAgICAgICAgKiBhbmQgZG91YmxlcyB0aGUgcG9zaXRpdmUgcmFuZ2UuIFRodXMgc2hpZnQgbGVmdCBvbmx5IG9uY2UsIGdsIGRvZXMgdGhlIDJuZAogICAgICAgICAgICAgICAgICAgICAgICAgKiBzaGlmdC4gR0wgcmVhZHMgYSBzaWduZWQgdmFsdWUgYW5kIGNvbnZlcnRzIGl0IGludG8gYW4gdW5zaWduZWQgdmFsdWUuCiAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICAvKiBNICovIERlc3RbMl0gPSBsIDw8IDE7CgogICAgICAgICAgICAgICAgICAgICAgICAvKiBUaG9zZSBhcmUgcmVhZCBhcyBzaWduZWQsIGJ1dCBrZXB0IHNpZ25lZC4gSnVzdCBsZWZ0LXNoaWZ0IDMgdGltZXMgdG8gc2NhbGUKICAgICAgICAgICAgICAgICAgICAgICAgICogZnJvbSA1IGJpdCB2YWx1ZXMgdG8gOCBiaXQgdmFsdWVzLgogICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgLyogViAqLyBEZXN0WzFdID0gdiA8PCAzOwogICAgICAgICAgICAgICAgICAgICAgICAvKiBVICovIERlc3RbMF0gPSB1IDw8IDM7CiAgICAgICAgICAgICAgICAgICAgICAgIERlc3QgKz0gMzsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBmb3IoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewogICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIHNob3J0ICpEZXN0X3MgPSAodW5zaWduZWQgc2hvcnQgKikgKGRzdCArIHkgKiBvdXRwaXRjaCk7CiAgICAgICAgICAgICAgICAgICAgU291cmNlID0gKFdPUkQgKikgKHNyYyArIHkgKiBwaXRjaCk7CiAgICAgICAgICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KysgKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNob3J0IGNvbG9yID0gKCpTb3VyY2UrKyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgbCA9ICgoY29sb3IgPj4gMTApICYgMHhmYyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3J0IHYgPSAoKGNvbG9yID4+ICA1KSAmIDB4M2UpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG9ydCB1ID0gKChjb2xvciAgICAgICkgJiAweDFmKTsKICAgICAgICAgICAgICAgICAgICAgICAgc2hvcnQgdl9jb252ID0gdiArIDE2OwogICAgICAgICAgICAgICAgICAgICAgICBzaG9ydCB1X2NvbnYgPSB1ICsgMTY7CgogICAgICAgICAgICAgICAgICAgICAgICAqRGVzdF9zID0gKCh2X2NvbnYgPDwgMTEpICYgMHhmODAwKSB8ICgobCA8PCA1KSAmIDB4N2UwKSB8ICh1X2NvbnYgJiAweDFmKTsKICAgICAgICAgICAgICAgICAgICAgICAgRGVzdF9zICs9IDE7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgY2FzZSBDT05WRVJUX1g4TDhWOFU4OgogICAgICAgIHsKICAgICAgICAgICAgdW5zaWduZWQgaW50IHgsIHk7CiAgICAgICAgICAgIERXT1JEICpTb3VyY2U7CiAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgKkRlc3Q7CgogICAgICAgICAgICBpZihHTF9TVVBQT1JUKE5WX1RFWFRVUkVfU0hBREVSKSkgewogICAgICAgICAgICAgICAgLyogVGhpcyBpbXBsZW1lbnRhdGlvbiB3b3JrcyB3aXRoIHRoZSBmaXhlZCBmdW5jdGlvbiBwaXBlbGluZSBhbmQgc2hhZGVycwogICAgICAgICAgICAgICAgICogd2l0aG91dCBmdXJ0aGVyIG1vZGlmaWNhdGlvbiBhZnRlciBjb252ZXJ0aW5nIHRoZSBzdXJmYWNlLgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBmb3IoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewogICAgICAgICAgICAgICAgICAgIFNvdXJjZSA9IChEV09SRCAqKSAoc3JjICsgeSAqIHBpdGNoKTsKICAgICAgICAgICAgICAgICAgICBEZXN0ID0gZHN0ICsgeSAqIG91dHBpdGNoOwogICAgICAgICAgICAgICAgICAgIGZvciAoeCA9IDA7IHggPCB3aWR0aDsgeCsrICkgewogICAgICAgICAgICAgICAgICAgICAgICBsb25nIGNvbG9yID0gKCpTb3VyY2UrKyk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIEwgKi8gRGVzdFsyXSA9ICgoY29sb3IgPj4gMTYpICYgMHhmZik7ICAgLyogTCAqLwogICAgICAgICAgICAgICAgICAgICAgICAvKiBWICovIERlc3RbMV0gPSAoKGNvbG9yID4+IDggKSAmIDB4ZmYpOyAgIC8qIFYgKi8KICAgICAgICAgICAgICAgICAgICAgICAgLyogVSAqLyBEZXN0WzBdID0gKGNvbG9yICAgICAgICAgJiAweGZmKTsgICAvKiBVICovCiAgICAgICAgICAgICAgICAgICAgICAgIC8qIEkgKi8gRGVzdFszXSA9IDI1NTsgICAgICAgICAgICAgICAgICAgICAgLyogWCAqLwogICAgICAgICAgICAgICAgICAgICAgICBEZXN0ICs9IDQ7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLyogRG9lc24ndCB3b3JrIGNvcnJlY3RseSB3aXRoIHRoZSBmaXhlZCBmdW5jdGlvbiBwaXBlbGluZSwgYnV0IGNhbiB3b3JrIGluCiAgICAgICAgICAgICAgICAgKiBzaGFkZXJzIGlmIHRoZSBzaGFkZXIgaXMgYWRqdXN0ZWQuIChUaGVyZSdzIG5vIHVzZSBmb3IgdGhpcyBmb3JtYXQgaW4gZ2wncwogICAgICAgICAgICAgICAgICogc3RhbmRhcmQgZml4ZWQgZnVuY3Rpb24gcGlwZWxpbmUgYW55d2F5KS4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgZm9yKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKICAgICAgICAgICAgICAgICAgICBTb3VyY2UgPSAoRFdPUkQgKikgKHNyYyArIHkgKiBwaXRjaCk7CiAgICAgICAgICAgICAgICAgICAgRGVzdCA9IGRzdCArIHkgKiBvdXRwaXRjaDsKICAgICAgICAgICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKyApIHsKICAgICAgICAgICAgICAgICAgICAgICAgbG9uZyBjb2xvciA9ICgqU291cmNlKyspOwogICAgICAgICAgICAgICAgICAgICAgICAvKiBCICovIERlc3RbMF0gPSAoKGNvbG9yID4+IDE2KSAmIDB4ZmYpOyAgICAgICAvKiBMICovCiAgICAgICAgICAgICAgICAgICAgICAgIC8qIEcgKi8gRGVzdFsxXSA9ICgoY29sb3IgPj4gOCApICYgMHhmZikgKyAxMjg7IC8qIFYgKi8KICAgICAgICAgICAgICAgICAgICAgICAgLyogUiAqLyBEZXN0WzJdID0gKGNvbG9yICAgICAgICAgJiAweGZmKSArIDEyODsgIC8qIFUgKi8KICAgICAgICAgICAgICAgICAgICAgICAgRGVzdCArPSA0OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgQ09OVkVSVF9BNEw0OgogICAgICAgIHsKICAgICAgICAgICAgdW5zaWduZWQgaW50IHgsIHk7CiAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgKlNvdXJjZTsKICAgICAgICAgICAgdW5zaWduZWQgY2hhciAqRGVzdDsKICAgICAgICAgICAgZm9yKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKICAgICAgICAgICAgICAgIFNvdXJjZSA9IHNyYyArIHkgKiBwaXRjaDsKICAgICAgICAgICAgICAgIERlc3QgPSBkc3QgKyB5ICogb3V0cGl0Y2g7CiAgICAgICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKyApIHsKICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyIGNvbG9yID0gKCpTb3VyY2UrKyk7CiAgICAgICAgICAgICAgICAgICAgLyogQSAqLyBEZXN0WzFdID0gKGNvbG9yICYgMHhmMCkgPDwgMDsKICAgICAgICAgICAgICAgICAgICAvKiBMICovIERlc3RbMF0gPSAoY29sb3IgJiAweDBmKSA8PCA0OwogICAgICAgICAgICAgICAgICAgIERlc3QgKz0gMjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgQ09OVkVSVF9SMzJGOgogICAgICAgIHsKICAgICAgICAgICAgdW5zaWduZWQgaW50IHgsIHk7CiAgICAgICAgICAgIGZsb2F0ICpTb3VyY2U7CiAgICAgICAgICAgIGZsb2F0ICpEZXN0OwogICAgICAgICAgICBmb3IoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewogICAgICAgICAgICAgICAgU291cmNlID0gKGZsb2F0ICopIChzcmMgKyB5ICogcGl0Y2gpOwogICAgICAgICAgICAgICAgRGVzdCA9IChmbG9hdCAqKSAoZHN0ICsgeSAqIG91dHBpdGNoKTsKICAgICAgICAgICAgICAgIGZvciAoeCA9IDA7IHggPCB3aWR0aDsgeCsrICkgewogICAgICAgICAgICAgICAgICAgIGZsb2F0IGNvbG9yID0gKCpTb3VyY2UrKyk7CiAgICAgICAgICAgICAgICAgICAgRGVzdFswXSA9IGNvbG9yOwogICAgICAgICAgICAgICAgICAgIERlc3RbMV0gPSAxLjA7CiAgICAgICAgICAgICAgICAgICAgRGVzdFsyXSA9IDEuMDsKICAgICAgICAgICAgICAgICAgICBEZXN0ICs9IDM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBjYXNlIENPTlZFUlRfUjE2RjoKICAgICAgICB7CiAgICAgICAgICAgIHVuc2lnbmVkIGludCB4LCB5OwogICAgICAgICAgICBXT1JEICpTb3VyY2U7CiAgICAgICAgICAgIFdPUkQgKkRlc3Q7CiAgICAgICAgICAgIFdPUkQgb25lID0gMHgzYzAwOwogICAgICAgICAgICBmb3IoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewogICAgICAgICAgICAgICAgU291cmNlID0gKFdPUkQgKikgKHNyYyArIHkgKiBwaXRjaCk7CiAgICAgICAgICAgICAgICBEZXN0ID0gKFdPUkQgKikgKGRzdCArIHkgKiBvdXRwaXRjaCk7CiAgICAgICAgICAgICAgICBmb3IgKHggPSAwOyB4IDwgd2lkdGg7IHgrKyApIHsKICAgICAgICAgICAgICAgICAgICBXT1JEIGNvbG9yID0gKCpTb3VyY2UrKyk7CiAgICAgICAgICAgICAgICAgICAgRGVzdFswXSA9IGNvbG9yOwogICAgICAgICAgICAgICAgICAgIERlc3RbMV0gPSBvbmU7CiAgICAgICAgICAgICAgICAgICAgRGVzdFsyXSA9IG9uZTsKICAgICAgICAgICAgICAgICAgICBEZXN0ICs9IDM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBjYXNlIENPTlZFUlRfRzE2UjE2OgogICAgICAgIHsKICAgICAgICAgICAgdW5zaWduZWQgaW50IHgsIHk7CiAgICAgICAgICAgIFdPUkQgKlNvdXJjZTsKICAgICAgICAgICAgV09SRCAqRGVzdDsKCiAgICAgICAgICAgIGZvcih5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CiAgICAgICAgICAgICAgICBTb3VyY2UgPSAoV09SRCAqKSAoc3JjICsgeSAqIHBpdGNoKTsKICAgICAgICAgICAgICAgIERlc3QgPSAoV09SRCAqKSAoZHN0ICsgeSAqIG91dHBpdGNoKTsKICAgICAgICAgICAgICAgIGZvciAoeCA9IDA7IHggPCB3aWR0aDsgeCsrICkgewogICAgICAgICAgICAgICAgICAgIFdPUkQgZ3JlZW4gPSAoKlNvdXJjZSsrKTsKICAgICAgICAgICAgICAgICAgICBXT1JEIHJlZCA9ICgqU291cmNlKyspOwogICAgICAgICAgICAgICAgICAgIERlc3RbMF0gPSBncmVlbjsKICAgICAgICAgICAgICAgICAgICBEZXN0WzFdID0gcmVkOwogICAgICAgICAgICAgICAgICAgIERlc3RbMl0gPSAweGZmZmY7CiAgICAgICAgICAgICAgICAgICAgRGVzdCArPSAzOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJVbnN1cHBvcnRlZCBjb252ZXJzYXRpb24gdHlwZSAlZFxuIiwgY29udmVydCk7CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIHZvaWQgZDNkZm10X3A4X2luaXRfcGFsZXR0ZShJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBCWVRFIHRhYmxlWzI1Nl1bNF0sIEJPT0wgY29sb3JrZXkpIHsKICAgIElXaW5lRDNEUGFsZXR0ZUltcGwqIHBhbCA9IFRoaXMtPnBhbGV0dGU7CiAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICBCT09MIGluZGV4X2luX2FscGhhID0gRkFMU0U7CiAgICBpbnQgZHhWZXJzaW9uID0gKCAoSVdpbmVEM0RJbXBsICopIGRldmljZS0+d2luZUQzRCktPmR4VmVyc2lvbjsKICAgIGludCBpOwoKICAgIC8qIE9sZCBnYW1lcyBsaWtlIFN0YXJDcmFmdCwgQyZDLCBSZWQgQWxlcnQgYW5kIG90aGVycyB1c2UgUDggcmVuZGVyIHRhcmdldHMuCiAgICAqIFJlYWRpbmcgYmFjayB0aGUgUkdCIG91dHB1dCBlYWNoIGxvY2tyZWN0IChlYWNoIGZyYW1lIGFzIHRoZXkgbG9jayB0aGUgd2hvbGUgc2NyZWVuKQogICAgKiBpcyBzbG93LiBGdXJ0aGVyIFJHQi0+UDggY29udmVyc2lvbiBpcyBub3QgcG9zc2libGUgYmVjYXVzZSBwYWxldHRlcyBjYW4gaGF2ZQogICAgKiBkdXBsaWNhdGUgZW50cmllcy4gU3RvcmUgdGhlIGNvbG9yIGtleSBpbiB0aGUgdW51c2VkIGFscGhhIGNvbXBvbmVudCB0byBzcGVlZCB0aGUKICAgICogZG93bmxvYWQgdXAgYW5kIHRvIG1ha2UgY29udmVyc2lvbiB1bm5lZWRlZC4gKi8KICAgIGluZGV4X2luX2FscGhhID0gcHJpbWFyeV9yZW5kZXJfdGFyZ2V0X2lzX3A4KGRldmljZSk7CgogICAgaWYgKHBhbCA9PSBOVUxMKSB7CiAgICAgICAgLyogSW4gRGlyZWN0RHJhdyB0aGUgcGFsZXR0ZSBpcyBhIHByb3BlcnR5IG9mIHRoZSBzdXJmYWNlLCB0aGVyZSBhcmUgbm8gc3VjaCB0aGluZ3MgYXMgZGV2aWNlIHBhbGV0dGVzLiAqLwogICAgICAgIGlmKGR4VmVyc2lvbiA8PSA3KSB7CiAgICAgICAgICAgIEVSUigiVGhpcyBjb2RlIHNob3VsZCBuZXZlciBnZXQgZW50ZXJlZCBmb3IgRGlyZWN0RHJhdyEsIGV4cGVjdCBwcm9ibGVtc1xuIik7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8qICBEaXJlY3QzRCA+PSA4IHBhbGV0dGUgdXNhZ2Ugc3R5bGU6IFA4IHRleHR1cmVzIHVzZSBkZXZpY2UgcGFsZXR0ZXMsIHBhbGV0dGUgZW50cnkgZm9ybWF0IGlzIEE4UjhHOEI4LAogICAgICAgICAgICBhbHBoYSBpcyBzdG9yZWQgaW4gcGVGbGFncyBhbmQgbWF5IGJlIHVzZWQgYnkgdGhlIGFwcCBpZiBEM0RQVEVYVFVSRUNBUFNfQUxQSEFQQUxFVFRFIGRldmljZQogICAgICAgICAgICBjYXBhYmlsaXR5IGZsYWcgaXMgcHJlc2VudCAod2luZSBkb2VzIGFkdmVydGlzZSB0aGlzIGNhcGFiaWxpdHkpICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IDI1NjsgaSsrKSB7CiAgICAgICAgICAgIHRhYmxlW2ldWzBdID0gZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtpXS5wZVJlZDsKICAgICAgICAgICAgdGFibGVbaV1bMV0gPSBkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdW2ldLnBlR3JlZW47CiAgICAgICAgICAgIHRhYmxlW2ldWzJdID0gZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtpXS5wZUJsdWU7CiAgICAgICAgICAgIHRhYmxlW2ldWzNdID0gZGV2aWNlLT5wYWxldHRlc1tkZXZpY2UtPmN1cnJlbnRQYWxldHRlXVtpXS5wZUZsYWdzOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoIlVzaW5nIHN1cmZhY2UgcGFsZXR0ZSAlcFxuIiwgcGFsKTsKICAgICAgICAvKiBHZXQgdGhlIHN1cmZhY2UncyBwYWxldHRlICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IDI1NjsgaSsrKSB7CiAgICAgICAgICAgIHRhYmxlW2ldWzBdID0gcGFsLT5wYWxlbnRzW2ldLnBlUmVkOwogICAgICAgICAgICB0YWJsZVtpXVsxXSA9IHBhbC0+cGFsZW50c1tpXS5wZUdyZWVuOwogICAgICAgICAgICB0YWJsZVtpXVsyXSA9IHBhbC0+cGFsZW50c1tpXS5wZUJsdWU7CgogICAgICAgICAgICAvKiBXaGVuIGluZGV4X2luX2FscGhhIGlzIHRoZSBwYWxldHRlIGluZGV4IGlzIHN0b3JlZCBpbiB0aGUgYWxwaGEgY29tcG9uZW50LiBJbiBjYXNlIG9mIGEgcmVhZGJhY2sKICAgICAgICAgICAgICAgd2UgY2FuIHRoZW4gcmVhZCBHTF9BTFBIQS4gQ29sb3Iga2V5aW5nIGlzIGhhbmRsZWQgaW4gQmx0T3ZlcnJpZGUgdXNpbmcgYSBHTF9BTFBIQV9URVNUIHVzaW5nIEdMX05PVF9FUVVBTC4KICAgICAgICAgICAgICAgSW4gY2FzZSBvZiBpbmRleF9pbl9hbHBoYSB0aGUgY29sb3Iga2V5IGl0c2VsZiBpcyBwYXNzZWQgdG8gZ2xBbHBoYUZ1bmMgaW4gb3RoZXIgY2FzZXMgdGhlIGFscGhhIGNvbXBvbmVudAogICAgICAgICAgICAgICBvZiBwaXhlbHMgdGhhdCBzaG91bGQgYmUgbWFza2VkIGF3YXkgaXMgc2V0IHRvIDAuICovCiAgICAgICAgICAgIGlmKGluZGV4X2luX2FscGhhKSB7CiAgICAgICAgICAgICAgICB0YWJsZVtpXVszXSA9IGk7CiAgICAgICAgICAgIH0gZWxzZSBpZihjb2xvcmtleSAmJiAoaSA+PSBUaGlzLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlKSAmJiAgKGkgPD0gVGhpcy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWUpKSB7CiAgICAgICAgICAgICAgICB0YWJsZVtpXVszXSA9IDB4MDA7CiAgICAgICAgICAgIH0gZWxzZSBpZihwYWwtPkZsYWdzICYgV0lORUREUENBUFNfQUxQSEEpIHsKICAgICAgICAgICAgICAgIHRhYmxlW2ldWzNdID0gcGFsLT5wYWxlbnRzW2ldLnBlRmxhZ3M7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0YWJsZVtpXVszXSA9IDB4RkY7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCmNvbnN0IGNoYXIgKmZyYWdtZW50X3BhbGV0dGVfY29udmVyc2lvbiA9CiAgICAiISFBUkJmcDEuMFxuIgogICAgIlRFTVAgaW5kZXg7XG4iCiAgICAiUEFSQU0gY29uc3RhbnRzID0geyAwLjk5NiwgMC4wMDE5NSwgMCwgMCB9O1xuIiAvKiB7IDI1NS8yNTYsIDAuNS8yNTUqMjU1LzI1NiwgMCwgMCB9ICovCiAgICAiVEVYIGluZGV4LCBmcmFnbWVudC50ZXhjb29yZFswXSwgdGV4dHVyZVswXSwgMkQ7XG4iIC8qIFRoZSBhbHBoYS1jb21wb25lbnQgY29udGFpbnMgdGhlIHBhbGV0dGUgaW5kZXggKi8KICAgICJNQUQgaW5kZXguYSwgaW5kZXguYSwgY29uc3RhbnRzLngsIGNvbnN0YW50cy55O1xuIiAvKiBTY2FsZSB0aGUgaW5kZXggYnkgMjU1LzI1NiBhbmQgYWRkIGEgYmlhcyBvZiAnMC41JyBpbiBvcmRlciB0byBzYW1wbGUgaW4gdGhlIG1pZGRsZSAqLwogICAgIlRFWCByZXN1bHQuY29sb3IsIGluZGV4LmEsIHRleHR1cmVbMV0sIDFEO1xuIiAvKiB1c2UgdGhlIGFscGhhLWNvbXBvbmVudCBhcyBhIGluZGV4IGluIHRoZSBwYWxldHRlIHRvIGdldCB0aGUgZmluYWwgY29sb3IgKi8KICAgICJFTkQiOwoKLyogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIGluIGNhc2Ugb2YgOGJpdCBwYWxldHRlZCB0ZXh0dXJlcyB0byB1cGxvYWQgdGhlIHBhbGV0dGUuCiAgIEl0IHN1cHBvcnRzIEdMX0VYVF9wYWxldHRlZF90ZXh0dXJlIGFuZCBHTF9BUkJfZnJhZ21lbnRfcHJvZ3JhbSwgc3VwcG9ydCBmb3Igb3RoZXIKICAgZXh0ZW5zaW9ucyBsaWtlIEFUSV9mcmFnbWVudF9zaGFkZXJzIGlzIHBvc3NpYmxlLgoqLwpzdGF0aWMgdm9pZCBkM2RmbXRfcDhfdXBsb2FkX3BhbGV0dGUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgQ09OVkVSVF9UWVBFUyBjb252ZXJ0KSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIEJZVEUgdGFibGVbMjU2XVs0XTsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqZGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKCiAgICBkM2RmbXRfcDhfaW5pdF9wYWxldHRlKFRoaXMsIHRhYmxlLCAoY29udmVydCA9PSBDT05WRVJUX1BBTEVUVEVEX0NLKSk7CgogICAgLyogVHJ5IHRvIHVzZSB0aGUgcGFsZXR0ZWQgdGV4dHVyZSBleHRlbnNpb24gKi8KICAgIGlmKEdMX1NVUFBPUlQoRVhUX1BBTEVUVEVEX1RFWFRVUkUpKQogICAgewogICAgICAgIFRSQUNFKCJVc2luZyBHTF9FWFRfUEFMRVRURURfVEVYVFVSRSBmb3IgOC1iaXQgcGFsZXR0ZWQgdGV4dHVyZSBzdXBwb3J0XG4iKTsKICAgICAgICBHTF9FWFRDQUxMKGdsQ29sb3JUYWJsZUVYVChUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCxHTF9SR0JBLDI1NixHTF9SR0JBLEdMX1VOU0lHTkVEX0JZVEUsIHRhYmxlKSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgLyogTGV0IGEgZnJhZ21lbnQgc2hhZGVyIGRvIHRoZSBjb2xvciBjb252ZXJzaW9uIGJ5IHVwbG9hZGluZyB0aGUgcGFsZXR0ZSB0byBhIDFEIHRleHR1cmUuCiAgICAgICAgICogVGhlIDhiaXQgcGl4ZWwgZGF0YSB3aWxsIGJlIHVzZWQgYXMgYW4gaW5kZXggaW4gdGhpcyBwYWxldHRlIHRleHR1cmUgdG8gcmV0cmlldmUgdGhlIGZpbmFsIGNvbG9yLiAqLwogICAgICAgIFRSQUNFKCJVc2luZyBmcmFnbWVudCBzaGFkZXJzIGZvciBlbXVsYXRpbmcgOC1iaXQgcGFsZXR0ZWQgdGV4dHVyZSBzdXBwb3J0XG4iKTsKCiAgICAgICAgLyogQ3JlYXRlIHRoZSBmcmFnbWVudCBwcm9ncmFtIGlmIHdlIGRvbid0IGhhdmUgaXQgKi8KICAgICAgICBpZighZGV2aWNlLT5wYWxldHRlQ29udmVyc2lvblNoYWRlcikKICAgICAgICB7CiAgICAgICAgICAgIGdsRW5hYmxlKEdMX0ZSQUdNRU5UX1BST0dSQU1fQVJCKTsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEdlblByb2dyYW1zQVJCKDEsICZkZXZpY2UtPnBhbGV0dGVDb252ZXJzaW9uU2hhZGVyKSk7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kUHJvZ3JhbUFSQihHTF9GUkFHTUVOVF9QUk9HUkFNX0FSQiwgZGV2aWNlLT5wYWxldHRlQ29udmVyc2lvblNoYWRlcikpOwogICAgICAgICAgICBHTF9FWFRDQUxMKGdsUHJvZ3JhbVN0cmluZ0FSQihHTF9GUkFHTUVOVF9QUk9HUkFNX0FSQiwgR0xfUFJPR1JBTV9GT1JNQVRfQVNDSUlfQVJCLCBzdHJsZW4oZnJhZ21lbnRfcGFsZXR0ZV9jb252ZXJzaW9uKSwgKGNvbnN0IEdMYnl0ZSAqKWZyYWdtZW50X3BhbGV0dGVfY29udmVyc2lvbikpOwogICAgICAgICAgICBnbERpc2FibGUoR0xfRlJBR01FTlRfUFJPR1JBTV9BUkIpOwogICAgICAgIH0KCiAgICAgICAgZ2xFbmFibGUoR0xfRlJBR01FTlRfUFJPR1JBTV9BUkIpOwogICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kUHJvZ3JhbUFSQihHTF9GUkFHTUVOVF9QUk9HUkFNX0FSQiwgZGV2aWNlLT5wYWxldHRlQ29udmVyc2lvblNoYWRlcikpOwoKICAgICAgICBHTF9FWFRDQUxMKGdsQWN0aXZlVGV4dHVyZUFSQihHTF9URVhUVVJFMSkpOwogICAgICAgIGdsRW5hYmxlKEdMX1RFWFRVUkVfMUQpOwogICAgICAgIGdsVGV4RW52aShHTF9URVhUVVJFX0VOViwgR0xfVEVYVFVSRV9FTlZfTU9ERSwgR0xfUkVQTEFDRSk7CgogICAgICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzFELCBHTF9URVhUVVJFX01JTl9GSUxURVIsIEdMX05FQVJFU1QpOwogICAgICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzFELCBHTF9URVhUVVJFX01BR19GSUxURVIsIEdMX05FQVJFU1QpOyAvKiBNYWtlIHN1cmUgd2UgaGF2ZSBkaXNjcmV0ZSBjb2xvciBsZXZlbHMuICovCiAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMUQsIEdMX1RFWFRVUkVfV1JBUF9TLCBHTF9DTEFNUF9UT19FREdFKTsKICAgICAgICBnbFRleEltYWdlMUQoR0xfVEVYVFVSRV8xRCwgMCwgR0xfUkdCQSwgMjU2LCAwLCBHTF9SR0JBLCBHTF9VTlNJR05FRF9CWVRFLCB0YWJsZSk7IC8qIFVwbG9hZCB0aGUgcGFsZXR0ZSAqLwoKICAgICAgICAvKiBTd2l0Y2ggYmFjayB0byB1bml0IDAgaW4gd2hpY2ggdGhlIDJEIHRleHR1cmUgd2lsbCBiZSBzdG9yZWQuICovCiAgICAgICAgR0xfRVhUQ0FMTChnbEFjdGl2ZVRleHR1cmVBUkIoR0xfVEVYVFVSRTApKTsKCiAgICAgICAgLyogUmViaW5kIHRoZSB0ZXh0dXJlIGJlY2F1c2UgaXQgaXNuJ3QgYm91bmQgYW55bW9yZSAqLwogICAgICAgIGdsQmluZFRleHR1cmUoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgfQp9CgpCT09MIHBhbGV0dGU5X2NoYW5nZWQoSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwoKICAgIGlmKFRoaXMtPnBhbGV0dGUgfHwgKFRoaXMtPnJlc291cmNlLmZvcm1hdCAhPSBXSU5FRDNERk1UX1A4ICYmIFRoaXMtPnJlc291cmNlLmZvcm1hdCAhPSBXSU5FRDNERk1UX0E4UDgpKSB7CiAgICAgICAgLyogSWYgYSBkZHJhdy1zdHlsZSBwYWxldHRlIGlzIGF0dGFjaGVkIGFzc3VtZSBubyBkM2Q5IHBhbGV0dGUgY2hhbmdlLgogICAgICAgICAqIEFsc28gdGhlIHBhbGV0dGUgaXNuJ3QgaW50ZXJlc3RpbmcgaWYgdGhlIHN1cmZhY2UgZm9ybWF0IGlzbid0IFA4IG9yIEE4UDgKICAgICAgICAgKi8KICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYoVGhpcy0+cGFsZXR0ZTkpIHsKICAgICAgICBpZihtZW1jbXAoVGhpcy0+cGFsZXR0ZTksICZkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdLCBzaXplb2YoUEFMRVRURUVOVFJZKSAqIDI1NikgPT0gMCkgewogICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBUaGlzLT5wYWxldHRlOSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoUEFMRVRURUVOVFJZKSAqIDI1Nik7CiAgICB9CiAgICBtZW1jcHkoVGhpcy0+cGFsZXR0ZTksICZkZXZpY2UtPnBhbGV0dGVzW2RldmljZS0+Y3VycmVudFBhbGV0dGVdLCBzaXplb2YoUEFMRVRURUVOVFJZKSAqIDI1Nik7CiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIGlubGluZSB2b2lkIGNsZWFyX3VudXNlZF9jaGFubmVscyhJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzKSB7CiAgICBHTGJvb2xlYW4gb2xkd3JpdGVbNF07CgogICAgLyogU29tZSBmb3JtYXRzIGhhdmUgb25seSBzb21lIGNvbG9yIGNoYW5uZWxzLCBhbmQgdGhlIG90aGVycyBhcmUgMS4wLgogICAgICogc2luY2Ugb3VyIHJlbmRlcmluZyByZW5kZXJzIHRvIGFsbCBjaGFubmVscywgYW5kIHRob3NlIHBpeGVsIGZvcm1hdHMKICAgICAqIGFyZSBlbXVsYXRlZCBieSB1c2luZyBhIGZ1bGwgdGV4dHVyZSB3aXRoIHRoZSBvdGhlciBjaGFubmVscyBzZXQgdG8gMS4wCiAgICAgKiBtYW51YWxseSwgY2xlYXIgdGhlIHVudXNlZCBjaGFubmVscy4KICAgICAqCiAgICAgKiBUaGlzIGNvdWxkIGJlIGRvbmUgd2l0aCBoYWNraW5nIGNvbG9yd3JpdGVlbmFibGUgdG8gbWFzayB0aGUgY29sb3JzLAogICAgICogYnV0IGJlZm9yZSBkcmF3aW5nIHRoZSBidWZmZXIgd291bGQgaGF2ZSB0byBiZSBjbGVhcmVkIHRvbywgc28gdGhlcmUncwogICAgICogbm8gZ2FpbiBpbiB0aGF0CiAgICAgKi8KICAgIHN3aXRjaChUaGlzLT5yZXNvdXJjZS5mb3JtYXQpIHsKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjE2RjoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjMyRjoKICAgICAgICAgICAgVFJBQ0UoIlIxNkYgb3IgUjMyRiBmb3JtYXQsIGNsZWFyaW5nIGdyZWVuLCBibHVlIGFuZCBhbHBoYSB0byAxLjBcbiIpOwogICAgICAgICAgICAvKiBEbyBub3QgYWN0aXZhdGUgYSBjb250ZXh0LCB0aGUgY29ycmVjdCBkcmF3YWJsZSBpcyBhY3RpdmUgYWxyZWFkeQogICAgICAgICAgICAgKiB0aG91Z2gganVzdCB0aGUgcmVhZCBidWZmZXIgaXMgc2V0LCBtYWtlIHN1cmUgdG8gaGF2ZSB0aGUgY29ycmVjdCBkcmF3CiAgICAgICAgICAgICAqIGJ1ZmZlciB0b28KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlLT5vZmZzY3JlZW5CdWZmZXIpOwogICAgICAgICAgICBnbERpc2FibGUoR0xfU0NJU1NPUl9URVNUKTsKICAgICAgICAgICAgZ2xHZXRCb29sZWFudihHTF9DT0xPUl9XUklURU1BU0ssIG9sZHdyaXRlKTsKICAgICAgICAgICAgZ2xDb2xvck1hc2soR0xfRkFMU0UsIEdMX1RSVUUsIEdMX1RSVUUsIEdMX1RSVUUpOwogICAgICAgICAgICBnbENsZWFyQ29sb3IoMC4wLCAxLjAsIDEuMCwgMS4wKTsKICAgICAgICAgICAgZ2xDbGVhcihHTF9DT0xPUl9CVUZGRVJfQklUKTsKICAgICAgICAgICAgZ2xDb2xvck1hc2sob2xkd3JpdGVbMF0sIG9sZHdyaXRlWzFdLCBvbGR3cml0ZVsyXSwgb2xkd3JpdGVbM10pOwogICAgICAgICAgICBpZighVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZS0+cmVuZGVyX29mZnNjcmVlbikgZ2xEcmF3QnVmZmVyKEdMX0JBQ0spOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiVW51c2VkIGNoYW5uZWwgY2xlYXJcbiIpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDogYnJlYWs7CiAgICB9Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0xvYWRUZXh0dXJlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIEJPT0wgc3JnYl9tb2RlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKCiAgICBpZiAoIShUaGlzLT5GbGFncyAmIFNGTEFHX0lOVEVYVFVSRSkpIHsKICAgICAgICBUUkFDRSgiUmVsb2FkaW5nIGJlY2F1c2Ugc3VyZmFjZSBpcyBkaXJ0eVxuIik7CiAgICB9IGVsc2UgaWYoLyogUmVsb2FkOiBnbCB0ZXh0dXJlIGhhcyBjaywgbm93IG5vIGNrZXkgaXMgc2V0IE9SICovCiAgICAgICAgICAgICAgKChUaGlzLT5GbGFncyAmIFNGTEFHX0dMQ0tFWSkgJiYgKCEoVGhpcy0+Q0tleUZsYWdzICYgV0lORUREU0RfQ0tTUkNCTFQpKSkgfHwKICAgICAgICAgICAgICAvKiBSZWxvYWQ6IHZpY2UgdmVyc2EgIE9SICovCiAgICAgICAgICAgICAgKCghKFRoaXMtPkZsYWdzICYgU0ZMQUdfR0xDS0VZKSkgJiYgKFRoaXMtPkNLZXlGbGFncyAmIFdJTkVERFNEX0NLU1JDQkxUKSkgfHwKICAgICAgICAgICAgICAvKiBBbHNvIHJlbG9hZDogQ29sb3Iga2V5IGlzIGFjdGl2ZSBBTkQgdGhlIGNvbG9yIGtleSBoYXMgY2hhbmdlZCAqLwogICAgICAgICAgICAgICgoVGhpcy0+Q0tleUZsYWdzICYgV0lORUREU0RfQ0tTUkNCTFQpICYmICgKICAgICAgICAgICAgICAgIChUaGlzLT5nbENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWUgIT0gVGhpcy0+U3JjQmx0Q0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZSkgfHwKICAgICAgICAgICAgICAgIChUaGlzLT5nbENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlICE9IFRoaXMtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlKSkpKSB7CiAgICAgICAgVFJBQ0UoIlJlbG9hZGluZyBiZWNhdXNlIG9mIGNvbG9yIGtleWluZ1xuIik7CiAgICAgICAgLyogVG8gcGVyZm9ybSB0aGUgY29sb3Iga2V5IGNvbnZlcnNpb24gd2UgbmVlZCBhIHN5c21lbSBjb3B5IG9mCiAgICAgICAgICogdGhlIHN1cmZhY2UuIE1ha2Ugc3VyZSB3ZSBoYXZlIGl0CiAgICAgICAgICovCgogICAgICAgIElXaW5lRDNEU3VyZmFjZV9Mb2FkTG9jYXRpb24oaWZhY2UsIFNGTEFHX0lOU1lTTUVNLCBOVUxMKTsKICAgICAgICAvKiBNYWtlIHN1cmUgdGhlIHRleHR1cmUgaXMgcmVsb2FkZWQgYmVjYXVzZSBvZiB0aGUgY29sb3Iga2V5IGNoYW5nZSwgdGhpcyBraWxscyBwZXJmb3JtYW5jZSB0aG91Z2ggOiggKi8KICAgICAgICAvKiBUT0RPOiBUaGlzIGlzIG5vdCBuZWNlc3NhcmlseSBuZWVkZWQgd2l0aCBodyBwYWxldHRpemVkIHRleHR1cmUgc3VwcG9ydCAqLwogICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19JTlRFWFRVUkU7CiAgICB9IGVsc2UgewogICAgICAgIFRSQUNFKCJzdXJmYWNlIGlzIGFscmVhZHkgaW4gdGV4dHVyZVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgLyogUmVzb3VyY2VzIGFyZSBwbGFjZWQgaW4gc3lzdGVtIFJBTSBhbmQgZG8gbm90IG5lZWQgdG8gYmUgcmVjcmVhdGVkIHdoZW4gYSBkZXZpY2UgaXMgbG9zdC4KICAgICAqICBUaGVzZSByZXNvdXJjZXMgYXJlIG5vdCBib3VuZCBieSBkZXZpY2Ugc2l6ZSBvciBmb3JtYXQgcmVzdHJpY3Rpb25zLiBCZWNhdXNlIG9mIHRoaXMsCiAgICAgKiAgdGhlc2UgcmVzb3VyY2VzIGNhbm5vdCBiZSBhY2Nlc3NlZCBieSB0aGUgRGlyZWN0M0QgZGV2aWNlIG5vciBzZXQgYXMgdGV4dHVyZXMgb3IgcmVuZGVyIHRhcmdldHMuCiAgICAgKiAgSG93ZXZlciwgdGhlc2UgcmVzb3VyY2VzIGNhbiBhbHdheXMgYmUgY3JlYXRlZCwgbG9ja2VkLCBhbmQgY29waWVkLgogICAgICovCiAgICBpZiAoVGhpcy0+cmVzb3VyY2UucG9vbCA9PSBXSU5FRDNEUE9PTF9TQ1JBVENIICkKICAgIHsKICAgICAgICBGSVhNRSgiKCVwKSBPcGVyYXRpb24gbm90IHN1cHBvcnRlZCBmb3Igc2NyYXRjaCB0ZXh0dXJlc1xuIixUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBUaGlzLT5zcmdiID0gc3JnYl9tb2RlOwogICAgSVdpbmVEM0RTdXJmYWNlX0xvYWRMb2NhdGlvbihpZmFjZSwgU0ZMQUdfSU5URVhUVVJFLCBOVUxMIC8qIG5vIHBhcnRpYWwgbG9ja2luZyBmb3IgdGV4dHVyZXMgeWV0ICovKTsKCiNpZiAwCiAgICB7CiAgICAgICAgc3RhdGljIHVuc2lnbmVkIGludCBnZW4gPSAwOwogICAgICAgIGNoYXIgYnVmZmVyWzQwOTZdOwogICAgICAgICsrZ2VuOwogICAgICAgIGlmICgoZ2VuICUgMTApID09IDApIHsKICAgICAgICAgICAgc25wcmludGYoYnVmZmVyLCBzaXplb2YoYnVmZmVyKSwgIi90bXAvc3VyZmFjZSVwX3R5cGUldV9sZXZlbCV1XyV1LnBwbSIsIFRoaXMsIFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLCBnZW4pOwogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NhdmVTbmFwc2hvdChpZmFjZSwgYnVmZmVyKTsKICAgICAgICB9CiAgICAgICAgLyoKICAgICAgICAgKiBkZWJ1Z2dpbmcgY3Jhc2ggY29kZQogICAgICAgICBpZiAoZ2VuID09IDI1MCkgewogICAgICAgICB2b2lkKiogdGVzdCA9IE5VTEw7CiAgICAgICAgICp0ZXN0ID0gMDsKICAgICAgICAgfQogICAgICAgICAqLwogICAgfQojZW5kaWYKCiAgICBpZiAoIShUaGlzLT5GbGFncyAmIFNGTEFHX0RPTk9URlJFRSkpIHsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5yZXNvdXJjZS5oZWFwTWVtb3J5KTsKICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBOVUxMOwogICAgICAgIFRoaXMtPnJlc291cmNlLmhlYXBNZW1vcnkgPSBOVUxMOwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9Nb2RpZnlMb2NhdGlvbihpZmFjZSwgU0ZMQUdfSU5TWVNNRU0sIEZBTFNFKTsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfQmluZFRleHR1cmUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgLyogVE9ETzogY2hlY2sgZm9yIGxvY2tzICovCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEQmFzZVRleHR1cmUgKmJhc2VUZXh0dXJlID0gTlVMTDsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqZGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKCiAgICBUUkFDRSgiKCVwKUNoZWNraW5nIHRvIHNlZSBpZiB0aGUgY29udGFpbmVyIGlzIGEgYmFzZSB0ZXh0dXJlXG4iLCBUaGlzKTsKICAgIGlmIChJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKGlmYWNlLCAmSUlEX0lXaW5lRDNEQmFzZVRleHR1cmUsICh2b2lkICoqKSZiYXNlVGV4dHVyZSkgPT0gV0lORUQzRF9PSykgewogICAgICAgIFRSQUNFKCJQYXNzaW5nIHRvIGNvbnRhaW5lclxuIik7CiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9CaW5kVGV4dHVyZShiYXNlVGV4dHVyZSk7CiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9SZWxlYXNlKGJhc2VUZXh0dXJlKTsKICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoIiglcCkgOiBCaW5kaW5nIHN1cmZhY2VcbiIsIFRoaXMpOwoKICAgICAgICBpZighZGV2aWNlLT5pc0luRHJhdykgewogICAgICAgICAgICBBY3RpdmF0ZUNvbnRleHQoZGV2aWNlLCBkZXZpY2UtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQsIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CiAgICAgICAgfQogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgZ2xCaW5kVGV4dHVyZShUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgTEVBVkVfR0woKTsKICAgIH0KICAgIHJldHVybjsKfQoKI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzdGRpby5oPgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NhdmVTbmFwc2hvdChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBjb25zdCBjaGFyKiBmaWxlbmFtZSkgewogICAgRklMRSogZiA9IE5VTEw7CiAgICBVSU5UIGksIHk7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIGNoYXIgKmFsbG9jYXRlZE1lbW9yeTsKICAgIGNoYXIgKnRleHR1cmVSb3c7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcENoYWluID0gTlVMTDsKICAgIGludCB3aWR0aCwgaGVpZ2h0OwogICAgR0x1aW50IHRtcFRleHR1cmUgPSAwOwogICAgRFdPUkQgY29sb3I7CiAgICAvKkZJWE1FOgogICAgVGV4dHVyZXMgbWF5IG5vdCBiZSBzdG9yZWQgaW4gLT5hbGxvY2F0ZWRnTWVtb3J5IGFuZCBhIEdsVGV4dHVyZQogICAgc28gd2Ugc2hvdWxkIGxvY2sgdGhlIHN1cmZhY2UgYmVmb3JlIHNhdmluZyBhIHNuYXBzaG90LCBvciBhdCBsZWFzdCBjaGVjayB0aGF0CiAgICAqLwogICAgLyogVE9ETzogQ29tcHJlc3NlZCB0ZXh0dXJlIGltYWdlcyBjYW4gYmUgb2J0YWluZWQgZnJvbSB0aGUgR0wgaW4gdW5jb21wcmVzc2VkIGZvcm0KICAgIGJ5IGNhbGxpbmcgR2V0VGV4SW1hZ2UgYW5kIGluIGNvbXByZXNzZWQgZm9ybSBieSBjYWxsaW5nCiAgICBHZXRDb21wcmVzc2VkVGV4SW1hZ2VBUkIuICBRdWVyaWVkIGNvbXByZXNzZWQgaW1hZ2VzIGNhbiBiZSBzYXZlZCBhbmQKICAgIGxhdGVyIHJldXNlZCBieSBjYWxsaW5nIENvbXByZXNzZWRUZXhJbWFnZVsxMjNdREFSQi4gIFByZS1jb21wcmVzc2VkCiAgICB0ZXh0dXJlIGltYWdlcyBkbyBub3QgbmVlZCB0byBiZSBwcm9jZXNzZWQgYnkgdGhlIEdMIGFuZCBzaG91bGQKICAgIHNpZ25pZmljYW50bHkgaW1wcm92ZSB0ZXh0dXJlIGxvYWRpbmcgcGVyZm9ybWFuY2UgcmVsYXRpdmUgdG8gdW5jb21wcmVzc2VkCiAgICBpbWFnZXMuICovCgovKiBTZXR1cCB0aGUgd2lkdGggYW5kIGhlaWdodCB0byBiZSB0aGUgaW50ZXJuYWwgdGV4dHVyZSB3aWR0aCBhbmQgaGVpZ2h0LiAqLwogICAgd2lkdGggID0gVGhpcy0+cG93MldpZHRoOwogICAgaGVpZ2h0ID0gVGhpcy0+cG93MkhlaWdodDsKLyogY2hlY2sgdG8gc2VlIGlmIHdlJ3JlIGEgJ3ZpcnR1YWwnIHRleHR1cmUsIGUuZy4gd2UncmUgbm90IGEgcGJ1ZmZlciBvZiB0ZXh0dXJlLCB3ZSdyZSBhIGJhY2sgYnVmZmVyKi8KICAgIElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoaWZhY2UsICZJSURfSVdpbmVEM0RTd2FwQ2hhaW4sICh2b2lkICoqKSZzd2FwQ2hhaW4pOwoKICAgIGlmIChUaGlzLT5GbGFncyAmIFNGTEFHX0lORFJBV0FCTEUgJiYgIShUaGlzLT5GbGFncyAmIFNGTEFHX0lOVEVYVFVSRSkpIHsKICAgICAgICAvKiBpZiB3ZXJlIG5vdCBhIHJlYWwgdGV4dHVyZSB0aGVuIHJlYWQgdGhlIGJhY2sgYnVmZmVyIGludG8gYSByZWFsIHRleHR1cmUgKi8KICAgICAgICAvKiB3ZSBkb24ndCB3YW50IHRvIGludGVyZmVyZSB3aXRoIHRoZSBiYWNrIGJ1ZmZlciBzbyByZWFkIHRoZSBkYXRhIGludG8gYSB0ZW1wb3JhcnkKICAgICAgICAgKiB0ZXh0dXJlIGFuZCB0aGVuIHNhdmUgdGhlIGRhdGEgb3V0IG9mIHRoZSB0ZW1wb3JhcnkgdGV4dHVyZQogICAgICAgICAqLwogICAgICAgIEdMaW50IHByZXZSZWFkOwogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgVFJBQ0UoIiglcCkgUmVhZGluZyByZW5kZXIgdGFyZ2V0IGludG8gdGV4dHVyZVxuIiwgVGhpcyk7CiAgICAgICAgZ2xFbmFibGUoR0xfVEVYVFVSRV8yRCk7CgogICAgICAgIGdsR2VuVGV4dHVyZXMoMSwgJnRtcFRleHR1cmUpOwogICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgdG1wVGV4dHVyZSk7CgogICAgICAgIGdsVGV4SW1hZ2UyRChHTF9URVhUVVJFXzJELAogICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICBHTF9SR0JBLAogICAgICAgICAgICAgICAgICAgICAgICB3aWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAwLypib3JkZXIqLywKICAgICAgICAgICAgICAgICAgICAgICAgR0xfUkdCQSwKICAgICAgICAgICAgICAgICAgICAgICAgR0xfVU5TSUdORURfSU5UXzhfOF84XzhfUkVWLAogICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKCiAgICAgICAgZ2xHZXRJbnRlZ2VydihHTF9SRUFEX0JVRkZFUiwgJnByZXZSZWFkKTsKICAgICAgICB2Y2hlY2tHTGNhbGwoImdsR2V0SW50ZWdlcnYiKTsKICAgICAgICBnbFJlYWRCdWZmZXIoc3dhcENoYWluID8gR0xfQkFDSyA6IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2UtPm9mZnNjcmVlbkJ1ZmZlcik7CiAgICAgICAgdmNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIiKTsKICAgICAgICBnbENvcHlUZXhJbWFnZTJEKEdMX1RFWFRVUkVfMkQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgR0xfUkdCQSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKTsKCiAgICAgICAgY2hlY2tHTGNhbGwoImdsQ29weVRleEltYWdlMkQiKTsKICAgICAgICBnbFJlYWRCdWZmZXIocHJldlJlYWQpOwogICAgICAgIExFQVZFX0dMKCk7CgogICAgfSBlbHNlIHsgLyogYmluZCB0aGUgcmVhbCB0ZXh0dXJlLCBhbmQgbWFrZSBzdXJlIGl0IHVwIHRvIGRhdGUgKi8KICAgICAgICBJV2luZUQzRFN1cmZhY2VfUHJlTG9hZChpZmFjZSk7CiAgICB9CiAgICBhbGxvY2F0ZWRNZW1vcnkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgd2lkdGggICogaGVpZ2h0ICogNCk7CiAgICBFTlRFUl9HTCgpOwogICAgRklYTUUoIlNhdmluZyB0ZXh0dXJlIGxldmVsICVkIHdpZHRoICVkIGhlaWdodCAlZFxuIiwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5sZXZlbCwgd2lkdGgsIGhlaWdodCk7CiAgICBnbEdldFRleEltYWdlKEdMX1RFWFRVUkVfMkQsCiAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLAogICAgICAgICAgICAgICAgR0xfUkdCQSwKICAgICAgICAgICAgICAgIEdMX1VOU0lHTkVEX0lOVF84XzhfOF84X1JFViwKICAgICAgICAgICAgICAgIGFsbG9jYXRlZE1lbW9yeSk7CiAgICBjaGVja0dMY2FsbCgiZ2xUZXhJbWFnZTJEIik7CiAgICBpZiAodG1wVGV4dHVyZSkgewogICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgMCk7CiAgICAgICAgZ2xEZWxldGVUZXh0dXJlcygxLCAmdG1wVGV4dHVyZSk7CiAgICB9CiAgICBMRUFWRV9HTCgpOwoKICAgIGYgPSBmb3BlbihmaWxlbmFtZSwgIncrIik7CiAgICBpZiAoTlVMTCA9PSBmKSB7CiAgICAgICAgRVJSKCJvcGVuaW5nIG9mICVzIGZhaWxlZCB3aXRoOiAlc1xuIiwgZmlsZW5hbWUsIHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9Ci8qIFNhdmUgdGhlIGRhdGEgb3V0IHRvIGEgVEdBIGZpbGUgYmVjYXVzZSAxOiBpdCdzIGFuIGVhc3kgcmF3IGZvcm1hdCwgMjogaXQgc3VwcG9ydHMgYW4gYWxwaGEgY2hhbm5lbCAqLwogICAgVFJBQ0UoIiglcCkgb3BlbmVkICVzIHdpdGggZm9ybWF0ICVzXG4iLCBUaGlzLCBmaWxlbmFtZSwgZGVidWdfZDNkZm9ybWF0KFRoaXMtPnJlc291cmNlLmZvcm1hdCkpOwovKiBUR0EgaGVhZGVyICovCiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDIsZik7CiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDAsZik7CiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDAsZik7CiAgICBmcHV0YygwLGYpOwogICAgZnB1dGMoMCxmKTsKICAgIGZwdXRjKDAsZik7Ci8qIHNob3J0IHdpZHRoKi8KICAgIGZ3cml0ZSgmd2lkdGgsMiwxLGYpOwovKiBzaG9ydCBoZWlnaHQgKi8KICAgIGZ3cml0ZSgmaGVpZ2h0LDIsMSxmKTsKLyogZm9ybWF0IHJnYmEgKi8KICAgIGZwdXRjKDB4MjAsZik7CiAgICBmcHV0YygweDI4LGYpOwovKiByYXcgZGF0YSAqLwogICAgLyogaWYgdGhlIGRhdGEgaXMgdXBzaWRlIGRvd24gaWYgd2UndmUgZmV0Y2hlZCBpdCBmcm9tIGEgYmFjayBidWZmZXIsIHNvIGl0IG5lZWRzIGZsaXBwaW5nIGFnYWluIHRvIG1ha2UgaXQgdGhlIGNvcnJlY3Qgd2F5IHVwICovCiAgICBpZihzd2FwQ2hhaW4pCiAgICAgICAgdGV4dHVyZVJvdyA9IGFsbG9jYXRlZE1lbW9yeSArICh3aWR0aCAqIChoZWlnaHQgLSAxKSAqNCk7CiAgICBlbHNlCiAgICAgICAgdGV4dHVyZVJvdyA9IGFsbG9jYXRlZE1lbW9yeTsKICAgIGZvciAoeSA9IDAgOyB5IDwgaGVpZ2h0OyB5KyspIHsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgd2lkdGg7ICBpKyspIHsKICAgICAgICAgICAgY29sb3IgPSAqKChEV09SRCopdGV4dHVyZVJvdyk7CiAgICAgICAgICAgIGZwdXRjKChjb2xvciA+PiAxNikgJiAweEZGLCBmKTsgLyogQiAqLwogICAgICAgICAgICBmcHV0YygoY29sb3IgPj4gIDgpICYgMHhGRiwgZik7IC8qIEcgKi8KICAgICAgICAgICAgZnB1dGMoKGNvbG9yID4+ICAwKSAmIDB4RkYsIGYpOyAvKiBSICovCiAgICAgICAgICAgIGZwdXRjKChjb2xvciA+PiAyNCkgJiAweEZGLCBmKTsgLyogQSAqLwogICAgICAgICAgICB0ZXh0dXJlUm93ICs9IDQ7CiAgICAgICAgfQogICAgICAgIC8qIHRha2UgdHdvIHJvd3Mgb2YgdGhlIHBvaW50ZXIgdG8gdGhlIHRleHR1cmUgbWVtb3J5ICovCiAgICAgICAgaWYoc3dhcENoYWluKQogICAgICAgICAgICAodGV4dHVyZVJvdy09IHdpZHRoIDw8IDMpOwoKICAgIH0KICAgIFRSQUNFKCJDbG9zaW5nIGZpbGVcbiIpOwogICAgZmNsb3NlKGYpOwoKICAgIGlmKHN3YXBDaGFpbikgewogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2Uoc3dhcENoYWluKTsKICAgIH0KICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGFsbG9jYXRlZE1lbW9yeSk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqCiAqICAgU2xpZ2h0bHkgaW5lZmZpY2llbnQgd2F5IHRvIGhhbmRsZSBtdWx0aXBsZSBkaXJ0eSByZWN0cyBidXQgaXQgd29ya3MgOikKICovCmV4dGVybiBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0FkZERpcnR5UmVjdChJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBDT05TVCBSRUNUKiBwRGlydHlSZWN0KSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEQmFzZVRleHR1cmUgKmJhc2VUZXh0dXJlID0gTlVMTDsKCiAgICBpZiAoIShUaGlzLT5GbGFncyAmIFNGTEFHX0lOU1lTTUVNKSAmJiAoVGhpcy0+RmxhZ3MgJiBTRkxBR19JTlRFWFRVUkUpKQogICAgICAgIElXaW5lRDNEU3VyZmFjZV9Mb2FkTG9jYXRpb24oaWZhY2UsIFNGTEFHX0lOU1lTTUVNLCBOVUxMIC8qIG5vIHBhcnRpYWwgbG9ja2luZyBmb3IgdGV4dHVyZXMgeWV0ICovKTsKCiAgICBJV2luZUQzRFN1cmZhY2VfTW9kaWZ5TG9jYXRpb24oaWZhY2UsIFNGTEFHX0lOU1lTTUVNLCBUUlVFKTsKICAgIGlmIChOVUxMICE9IHBEaXJ0eVJlY3QpIHsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QubGVmdCAgID0gbWluKFRoaXMtPmRpcnR5UmVjdC5sZWZ0LCAgIHBEaXJ0eVJlY3QtPmxlZnQpOwogICAgICAgIFRoaXMtPmRpcnR5UmVjdC50b3AgICAgPSBtaW4oVGhpcy0+ZGlydHlSZWN0LnRvcCwgICAgcERpcnR5UmVjdC0+dG9wKTsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QucmlnaHQgID0gbWF4KFRoaXMtPmRpcnR5UmVjdC5yaWdodCwgIHBEaXJ0eVJlY3QtPnJpZ2h0KTsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QuYm90dG9tID0gbWF4KFRoaXMtPmRpcnR5UmVjdC5ib3R0b20sIHBEaXJ0eVJlY3QtPmJvdHRvbSk7CiAgICB9IGVsc2UgewogICAgICAgIFRoaXMtPmRpcnR5UmVjdC5sZWZ0ICAgPSAwOwogICAgICAgIFRoaXMtPmRpcnR5UmVjdC50b3AgICAgPSAwOwogICAgICAgIFRoaXMtPmRpcnR5UmVjdC5yaWdodCAgPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICBUaGlzLT5kaXJ0eVJlY3QuYm90dG9tID0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgfQogICAgVFJBQ0UoIiglcCkgOiBEaXJ0eTogeWVzLCBSZWN0OiglZCwlZCwlZCwlZClcbiIsIFRoaXMsIFRoaXMtPmRpcnR5UmVjdC5sZWZ0LAogICAgICAgICAgVGhpcy0+ZGlydHlSZWN0LnRvcCwgVGhpcy0+ZGlydHlSZWN0LnJpZ2h0LCBUaGlzLT5kaXJ0eVJlY3QuYm90dG9tKTsKICAgIC8qIGlmIHRoZSBjb250YWluZXIgaXMgYSBiYXNldGV4dHVyZSB0aGVuIG1hcmsgaXQgZGlydHkuICovCiAgICBpZiAoSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihpZmFjZSwgJklJRF9JV2luZUQzREJhc2VUZXh0dXJlLCAodm9pZCAqKikmYmFzZVRleHR1cmUpID09IFdJTkVEM0RfT0spIHsKICAgICAgICBUUkFDRSgiUGFzc2luZyB0byBjb250YWluZXJcbiIpOwogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfU2V0RGlydHkoYmFzZVRleHR1cmUsIFRSVUUpOwogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUmVsZWFzZShiYXNlVGV4dHVyZSk7CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRGb3JtYXQoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgV0lORUQzREZPUk1BVCBmb3JtYXQpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgSFJFU1VMVCBocjsKICAgIGNvbnN0IEdsUGl4ZWxGb3JtYXREZXNjICpnbERlc2M7CiAgICBnZXRGb3JtYXREZXNjRW50cnkoZm9ybWF0LCAmR0xJTkZPX0xPQ0FUSU9OLCAmZ2xEZXNjKTsKCiAgICBUUkFDRSgiKCVwKSA6IENhbGxpbmcgYmFzZSBmdW5jdGlvbiBmaXJzdFxuIiwgVGhpcyk7CiAgICBociA9IElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1NldEZvcm1hdChpZmFjZSwgZm9ybWF0KTsKICAgIGlmKFNVQ0NFRURFRChocikpIHsKICAgICAgICAvKiBTZXR1cCBzb21lIGdsZm9ybWF0IGRlZmF1bHRzICovCiAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdCAgICAgICAgID0gZ2xEZXNjLT5nbEZvcm1hdDsKICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0SW50ZXJuYWwgPSBnbERlc2MtPmdsSW50ZXJuYWw7CiAgICAgICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbFR5cGUgICAgICAgICAgID0gZ2xEZXNjLT5nbFR5cGU7CgogICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19BTExPQ0FURUQ7CiAgICAgICAgVFJBQ0UoIiglcCkgOiBnbEZvcm1hdCAlZCwgZ2xGb3RtYXRJbnRlcm5hbCAlZCwgZ2xUeXBlICVkXG4iLCBUaGlzLAogICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXQsIFRoaXMtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXRJbnRlcm5hbCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbFR5cGUpOwogICAgfQogICAgcmV0dXJuIGhyOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX1NldE1lbShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCB2b2lkICpNZW0pIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKCiAgICBpZihUaGlzLT5GbGFncyAmIChTRkxBR19MT0NLRUQgfCBTRkxBR19EQ0lOVVNFKSkgewogICAgICAgIFdBUk4oIlN1cmZhY2UgaXMgbG9ja2VkIG9yIHRoZSBIREMgaXMgaW4gdXNlXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBpZihNZW0gJiYgTWVtICE9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgewogICAgICAgIHZvaWQgKnJlbGVhc2UgPSBOVUxMOwoKICAgICAgICAvKiBEbyBJIGhhdmUgdG8gY29weSB0aGUgb2xkIHN1cmZhY2UgY29udGVudD8gKi8KICAgICAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX0RJQlNFQ1RJT04pIHsKICAgICAgICAgICAgICAgIC8qIFJlbGVhc2UgdGhlIERDLiBObyBuZWVkIHRvIGhvbGQgdGhlIGNyaXRpY2FsIHNlY3Rpb24gZm9yIHRoZSB1cGRhdGUKICAgICAgICAgICAgICAgICAqIFRocmVhZCBiZWNhdXNlIHRoaXMgdGhyZWFkIHJ1bnMgb25seSBvbiBmcm9udCBidWZmZXJzLCBidXQgdGhpcyBtZXRob2QKICAgICAgICAgICAgICAgICAqIGZhaWxzIGZvciByZW5kZXIgdGFyZ2V0cyBpbiB0aGUgY2hlY2sgYWJvdmUuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIFNlbGVjdE9iamVjdChUaGlzLT5oREMsIFRoaXMtPmRpYi5ob2xkYml0bWFwKTsKICAgICAgICAgICAgICAgIERlbGV0ZURDKFRoaXMtPmhEQyk7CiAgICAgICAgICAgICAgICAvKiBSZWxlYXNlIHRoZSBESUIgc2VjdGlvbiAqLwogICAgICAgICAgICAgICAgRGVsZXRlT2JqZWN0KFRoaXMtPmRpYi5ESUJzZWN0aW9uKTsKICAgICAgICAgICAgICAgIFRoaXMtPmRpYi5iaXRtYXBfZGF0YSA9IE5VTEw7CiAgICAgICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBOVUxMOwogICAgICAgICAgICAgICAgVGhpcy0+aERDID0gTlVMTDsKICAgICAgICAgICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19ESUJTRUNUSU9OOwogICAgICAgIH0gZWxzZSBpZighKFRoaXMtPkZsYWdzICYgU0ZMQUdfVVNFUlBUUikpIHsKICAgICAgICAgICAgcmVsZWFzZSA9IFRoaXMtPnJlc291cmNlLmhlYXBNZW1vcnk7CiAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmhlYXBNZW1vcnkgPSBOVUxMOwogICAgICAgIH0KICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBNZW07CiAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfVVNFUlBUUiB8IFNGTEFHX0lOU1lTTUVNOwoKICAgICAgICAvKiBOb3cgdGhlIHN1cmZhY2UgbWVtb3J5IGlzIG1vc3QgdXAgZG8gZGF0ZS4gSW52YWxpZGF0ZSBkcmF3YWJsZSBhbmQgdGV4dHVyZSAqLwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9Nb2RpZnlMb2NhdGlvbihpZmFjZSwgU0ZMQUdfSU5TWVNNRU0sIFRSVUUpOwoKICAgICAgICAvKiBGb3IgY2xpZW50IHRleHR1cmVzIG9wZW5nbCBoYXMgdG8gYmUgbm90aWZpZWQgKi8KICAgICAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX0NMSUVOVCkgewogICAgICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfQUxMT0NBVEVEOwogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUHJlTG9hZChpZmFjZSk7CiAgICAgICAgICAgIC8qIEFuZCBob3BlIHRoYXQgdGhlIGFwcCBiZWhhdmVzIGNvcnJlY3RseSBhbmQgZGlkIG5vdCBmcmVlIHRoZSBvbGQgc3VyZmFjZSBtZW1vcnkgYmVmb3JlIHNldHRpbmcgYSBuZXcgcG9pbnRlciAqLwogICAgICAgIH0KCiAgICAgICAgLyogTm93IGZyZWUgdGhlIG9sZCBtZW1vcnkgaWYgYW55ICovCiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcmVsZWFzZSk7CiAgICB9IGVsc2UgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19VU0VSUFRSKSB7CiAgICAgICAgLyogTG9ja1JlY3QgYW5kIEdldERDIHdpbGwgcmUtY3JlYXRlIHRoZSBkaWIgc2VjdGlvbiBhbmQgYWxsb2NhdGVkIG1lbW9yeSAqLwogICAgICAgIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IE5VTEw7CiAgICAgICAgLyogSGVhcE1lbW9yeSBzaG91bGQgYmUgTlVMTCBhbHJlYWR5ICovCiAgICAgICAgaWYoVGhpcy0+cmVzb3VyY2UuaGVhcE1lbW9yeSAhPSBOVUxMKSBFUlIoIlVzZXIgcG9pbnRlciBzdXJmYWNlIGhhcyBoZWFwIG1lbW9yeSBhbGxvY2F0ZWRcbiIpOwogICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19VU0VSUFRSOwoKICAgICAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX0NMSUVOVCkgewogICAgICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfQUxMT0NBVEVEOwogICAgICAgICAgICAvKiBUaGlzIHJlc3BlY2lmaWVzIGFuIGVtcHR5IHRleHR1cmUgYW5kIG9wZW5nbCBrbm93cyB0aGF0IHRoZSBvbGQgbWVtb3J5IGlzIGdvbmUgKi8KICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1ByZUxvYWQoaWZhY2UpOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9GbGlwKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIElXaW5lRDNEU3VyZmFjZSAqb3ZlcnJpZGUsIERXT1JEIEZsYWdzKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqc3dhcGNoYWluID0gTlVMTDsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCVwLCV4KVxuIiwgVGhpcywgb3ZlcnJpZGUsIEZsYWdzKTsKCiAgICAvKiBGbGlwcGluZyBpcyBvbmx5IHN1cHBvcnRlZCBvbiBSZW5kZXJUYXJnZXRzICovCiAgICBpZiggIShUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpICkgcmV0dXJuIFdJTkVEREVSUl9OT1RGTElQUEFCTEU7CgogICAgaWYob3ZlcnJpZGUpIHsKICAgICAgICAvKiBERHJhdyBzZXRzIHRoaXMgZm9yIHRoZSBYMTEgc3VyZmFjZXMsIHNvIGRvbid0IGNvbmZ1c2UgdGhlIHVzZXIgCiAgICAgICAgICogRklYTUUoIiglcCkgVGFyZ2V0IG92ZXJyaWRlIGlzIG5vdCBzdXBwb3J0ZWQgYnkgbm93XG4iLCBUaGlzKTsKICAgICAgICAgKiBBZGRpdGlvbmFsbHksIGl0IGlzbid0IHJlYWxseSBwb3NzaWJsZSB0byBzdXBwb3J0IHRyaXBsZS1idWZmZXJpbmcKICAgICAgICAgKiBwcm9wZXJseSBvbiBvcGVuZ2wgYXQgYWxsCiAgICAgICAgICovCiAgICB9CgogICAgSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihpZmFjZSwgJklJRF9JV2luZUQzRFN3YXBDaGFpbiwgKHZvaWQgKiopICZzd2FwY2hhaW4pOwogICAgaWYoIXN3YXBjaGFpbikgewogICAgICAgIEVSUigiRmxpcHBlZCBzdXJmYWNlIGlzIG5vdCBvbiBhIHN3YXBjaGFpblxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEREVSUl9OT1RGTElQUEFCTEU7CiAgICB9CgogICAgLyogSnVzdCBvdmVyd3JpdGUgdGhlIHN3YXBjaGFpbiBwcmVzZW50YXRpb24gaW50ZXJ2YWwuIFRoaXMgaXMgb2sgYmVjYXVzZSBvbmx5IGRkcmF3IGFwcHMgY2FuIGNhbGwgRmxpcCwKICAgICAqIGFuZCBvbmx5IGQzZDggYW5kIGQzZDkgYXBwcyBzcGVjaWZ5IHRoZSBwcmVzZW50YXRpb24gaW50ZXJ2YWwKICAgICAqLwogICAgaWYoKEZsYWdzICYgKFdJTkVEREZMSVBfTk9WU1lOQyB8IFdJTkVEREZMSVBfSU5URVJWQUwyIHwgV0lORURERkxJUF9JTlRFUlZBTDMgfCBXSU5FRERGTElQX0lOVEVSVkFMNCkpID09IDApIHsKICAgICAgICAvKiBNb3N0IGNvbW1vbiBjYXNlIGZpcnN0IHRvIGF2b2lkIHdhc3RpbmcgdGltZSBvbiBhbGwgdGhlIG90aGVyIGNhc2VzICovCiAgICAgICAgc3dhcGNoYWluLT5wcmVzZW50UGFybXMuUHJlc2VudGF0aW9uSW50ZXJ2YWwgPSBXSU5FRDNEUFJFU0VOVF9JTlRFUlZBTF9PTkU7CiAgICB9IGVsc2UgaWYoRmxhZ3MgJiBXSU5FRERGTElQX05PVlNZTkMpIHsKICAgICAgICBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5QcmVzZW50YXRpb25JbnRlcnZhbCA9IFdJTkVEM0RQUkVTRU5UX0lOVEVSVkFMX0lNTUVESUFURTsKICAgIH0gZWxzZSBpZihGbGFncyAmIFdJTkVEREZMSVBfSU5URVJWQUwyKSB7CiAgICAgICAgc3dhcGNoYWluLT5wcmVzZW50UGFybXMuUHJlc2VudGF0aW9uSW50ZXJ2YWwgPSBXSU5FRDNEUFJFU0VOVF9JTlRFUlZBTF9UV087CiAgICB9IGVsc2UgaWYoRmxhZ3MgJiBXSU5FRERGTElQX0lOVEVSVkFMMykgewogICAgICAgIHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLlByZXNlbnRhdGlvbkludGVydmFsID0gV0lORUQzRFBSRVNFTlRfSU5URVJWQUxfVEhSRUU7CiAgICB9IGVsc2UgewogICAgICAgIHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLlByZXNlbnRhdGlvbkludGVydmFsID0gV0lORUQzRFBSRVNFTlRfSU5URVJWQUxfRk9VUjsKICAgIH0KCiAgICAvKiBGbGlwcGluZyBhIE9wZW5HTCBzdXJmYWNlIC0+IFVzZSBXaW5lRDNERGV2aWNlOjpQcmVzZW50ICovCiAgICBociA9IElXaW5lRDNEU3dhcENoYWluX1ByZXNlbnQoKElXaW5lRDNEU3dhcENoYWluICopIHN3YXBjaGFpbiwgTlVMTCwgTlVMTCwgMCwgTlVMTCwgMCk7CiAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKChJV2luZUQzRFN3YXBDaGFpbiAqKSBzd2FwY2hhaW4pOwogICAgcmV0dXJuIGhyOwp9CgovKiBEb2VzIGEgZGlyZWN0IGZyYW1lIGJ1ZmZlciAtPiB0ZXh0dXJlIGNvcHkuIFN0cmV0Y2hpbmcgaXMgZG9uZQogKiB3aXRoIHNpbmdsZSBwaXhlbCBjb3B5IGNhbGxzCiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgZmJfY29weV90b190ZXh0dXJlX2RpcmVjdChJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBJV2luZUQzRFN1cmZhY2UgKlNyY1N1cmZhY2UsIElXaW5lRDNEU3dhcENoYWluSW1wbCAqc3dhcGNoYWluLCBXSU5FRDNEUkVDVCAqc3JlY3QsIFdJTkVEM0RSRUNUICpkcmVjdCwgQk9PTCB1cHNpZGVkb3duLCBXSU5FRDNEVEVYVFVSRUZJTFRFUlRZUEUgRmlsdGVyKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKm15RGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIGZsb2F0IHhyZWwsIHlyZWw7CiAgICBVSU5UIHJvdzsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlNyYyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFNyY1N1cmZhY2U7CgoKICAgIEFjdGl2YXRlQ29udGV4dChteURldmljZSwgU3JjU3VyZmFjZSwgQ1RYVVNBR0VfQkxJVCk7CiAgICBJV2luZUQzRFN1cmZhY2VfUHJlTG9hZCgoSVdpbmVEM0RTdXJmYWNlICopIFRoaXMpOwogICAgRU5URVJfR0woKTsKCiAgICAvKiBUT0RPOiBEbyB3ZSBuZWVkIEdMX1RFWFRVUkVfMkQgZW5hYmxlZCBmcHIgY29weXRleGltYWdlPyAqLwogICAgZ2xFbmFibGUoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQpOwogICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0KSIpOwoKICAgIC8qIEJpbmQgdGhlIHRhcmdldCB0ZXh0dXJlICovCiAgICBnbEJpbmRUZXh0dXJlKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRUZXh0dXJlIik7CiAgICBpZighc3dhcGNoYWluKSB7CiAgICAgICAgZ2xSZWFkQnVmZmVyKG15RGV2aWNlLT5vZmZzY3JlZW5CdWZmZXIpOwogICAgfSBlbHNlIHsKICAgICAgICBHTGVudW0gYnVmZmVyID0gc3VyZmFjZV9nZXRfZ2xfYnVmZmVyKFNyY1N1cmZhY2UsIChJV2luZUQzRFN3YXBDaGFpbiAqKXN3YXBjaGFpbik7CiAgICAgICAgZ2xSZWFkQnVmZmVyKGJ1ZmZlcik7CiAgICB9CiAgICBjaGVja0dMY2FsbCgiZ2xSZWFkQnVmZmVyIik7CgogICAgeHJlbCA9IChmbG9hdCkgKHNyZWN0LT54MiAtIHNyZWN0LT54MSkgLyAoZmxvYXQpIChkcmVjdC0+eDIgLSBkcmVjdC0+eDEpOwogICAgeXJlbCA9IChmbG9hdCkgKHNyZWN0LT55MiAtIHNyZWN0LT55MSkgLyAoZmxvYXQpIChkcmVjdC0+eTIgLSBkcmVjdC0+eTEpOwoKICAgIGlmKCAoeHJlbCAtIDEuMCA8IC1lcHMpIHx8ICh4cmVsIC0gMS4wID4gZXBzKSkgewogICAgICAgIEZJWE1FKCJEb2luZyBhIHBpeGVsIGJ5IHBpeGVsIGNvcHkgZnJvbSB0aGUgZnJhbWVidWZmZXIgdG8gYSB0ZXh0dXJlLCBleHBlY3QgbWFqb3IgcGVyZm9ybWFuY2UgaXNzdWVzXG4iKTsKCiAgICAgICAgaWYoRmlsdGVyICE9IFdJTkVEM0RURVhGX05PTkUgJiYgRmlsdGVyICE9IFdJTkVEM0RURVhGX1BPSU5UKSB7CiAgICAgICAgICAgIEVSUigiVGV4dHVyZSBmaWx0ZXJpbmcgbm90IHN1cHBvcnRlZCBpbiBkaXJlY3QgYmxpdFxuIik7CiAgICAgICAgfQogICAgfSBlbHNlIGlmKChGaWx0ZXIgIT0gV0lORUQzRFRFWEZfTk9ORSAmJiBGaWx0ZXIgIT0gV0lORUQzRFRFWEZfUE9JTlQpICYmICgoeXJlbCAtIDEuMCA8IC1lcHMpIHx8ICh5cmVsIC0gMS4wID4gZXBzKSkpIHsKICAgICAgICBFUlIoIlRleHR1cmUgZmlsdGVyaW5nIG5vdCBzdXBwb3J0ZWQgaW4gZGlyZWN0IGJsaXRcbiIpOwogICAgfQoKICAgIGlmKHVwc2lkZWRvd24gJiYKICAgICAgICEoKHhyZWwgLSAxLjAgPCAtZXBzKSB8fCAoeHJlbCAtIDEuMCA+IGVwcykpICYmCiAgICAgICAhKCh5cmVsIC0gMS4wIDwgLWVwcykgfHwgKHlyZWwgLSAxLjAgPiBlcHMpKSkgewogICAgICAgIC8qIFVwc2lkZSBkb3duIGNvcHkgd2l0aG91dCBzdHJldGNoaW5nIGlzIG5pY2UsIG9uZSBnbENvcHlUZXhTdWJJbWFnZSBjYWxsIHdpbGwgZG8gKi8KCiAgICAgICAgZ2xDb3B5VGV4U3ViSW1hZ2UyRChUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcmVjdC0+eDEsIGRyZWN0LT55MSwgLyogeG9mZnNldCwgeW9mZnNldCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JlY3QtPngxLCBTcmMtPmN1cnJlbnREZXNjLkhlaWdodCAtIHNyZWN0LT55MiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRyZWN0LT54MiAtIGRyZWN0LT54MSwgZHJlY3QtPnkyIC0gZHJlY3QtPnkxKTsKICAgIH0gZWxzZSB7CiAgICAgICAgVUlOVCB5b2Zmc2V0ID0gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQgLSBzcmVjdC0+eTEgKyBkcmVjdC0+eTEgLSAxOwogICAgICAgIC8qIEkgaGF2ZSB0byBwcm9jZXNzIHRoaXMgcm93IGJ5IHJvdyB0byBzd2FwIHRoZSBpbWFnZSwKICAgICAgICAgKiBvdGhlcndpc2UgaXQgd291bGQgYmUgdXBzaWRlIGRvd24sIHNvIHN0cmV0Y2hpbmcgaW4geSBkaXJlY3Rpb24KICAgICAgICAgKiBkb2Vzbid0IGNvc3QgZXh0cmEgdGltZQogICAgICAgICAqCiAgICAgICAgICogSG93ZXZlciwgc3RyZXRjaGluZyBpbiB4IGRpcmVjdGlvbiBjYW4gYmUgYXZvaWRlZCBpZiBub3QgbmVjZXNzYXJ5CiAgICAgICAgICovCiAgICAgICAgZm9yKHJvdyA9IGRyZWN0LT55MTsgcm93IDwgZHJlY3QtPnkyOyByb3crKykgewogICAgICAgICAgICBpZiggKHhyZWwgLSAxLjAgPCAtZXBzKSB8fCAoeHJlbCAtIDEuMCA+IGVwcykpIHsKICAgICAgICAgICAgICAgIC8qIFdlbGwsIHRoYXQgc3R1ZmYgd29ya3MsIGJ1dCBpdCdzIHZlcnkgc2xvdy4KICAgICAgICAgICAgICAgICAqIGZpbmQgYSBiZXR0ZXIgd2F5IGluc3RlYWQKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgVUlOVCBjb2w7CgogICAgICAgICAgICAgICAgZm9yKGNvbCA9IGRyZWN0LT54MTsgY29sIDwgZHJlY3QtPngyOyBjb2wrKykgewogICAgICAgICAgICAgICAgICAgIGdsQ29weVRleFN1YkltYWdlMkQoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmxldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJlY3QtPngxICsgY29sLCByb3csIC8qIHhvZmZzZXQsIHlvZmZzZXQgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyZWN0LT54MSArIGNvbCAqIHhyZWwsIHlvZmZzZXQgLSAoaW50KSAocm93ICogeXJlbCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAxKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGdsQ29weVRleFN1YkltYWdlMkQoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24ubGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRyZWN0LT54MSwgcm93LCAvKiB4b2Zmc2V0LCB5b2Zmc2V0ICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyZWN0LT54MSwgeW9mZnNldCAtIChpbnQpIChyb3cgKiB5cmVsKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHJlY3QtPngyLWRyZWN0LT54MSwgMSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICB2Y2hlY2tHTGNhbGwoImdsQ29weVRleFN1YkltYWdlMkQiKTsKCiAgICAvKiBMZWF2ZSB0aGUgb3BlbmdsIHN0YXRlIHZhbGlkIGZvciBibGl0dGluZyAqLwogICAgZ2xEaXNhYmxlKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0KTsKICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQpIik7CgogICAgTEVBVkVfR0woKTsKfQoKLyogVXNlcyB0aGUgaGFyZHdhcmUgdG8gc3RyZXRjaCBhbmQgZmxpcCB0aGUgaW1hZ2UgKi8Kc3RhdGljIGlubGluZSB2b2lkIGZiX2NvcHlfdG9fdGV4dHVyZV9od3N0cmV0Y2goSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcywgSVdpbmVEM0RTdXJmYWNlICpTcmNTdXJmYWNlLCBJV2luZUQzRFN3YXBDaGFpbkltcGwgKnN3YXBjaGFpbiwgV0lORUQzRFJFQ1QgKnNyZWN0LCBXSU5FRDNEUkVDVCAqZHJlY3QsIEJPT0wgdXBzaWRlZG93biwgV0lORUQzRFRFWFRVUkVGSUxURVJUWVBFIEZpbHRlcikgewogICAgR0x1aW50IHNyYywgYmFja3VwID0gMDsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqbXlEZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqU3JjID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgU3JjU3VyZmFjZTsKICAgIGZsb2F0IGxlZnQsIHJpZ2h0LCB0b3AsIGJvdHRvbTsgLyogVGV4dHVyZSBjb29yZGluYXRlcyAqLwogICAgVUlOVCBmYndpZHRoID0gU3JjLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgIFVJTlQgZmJoZWlnaHQgPSBTcmMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgIEdMZW51bSBkcmF3QnVmZmVyID0gR0xfQkFDSzsKICAgIEdMZW51bSB0ZXh0dXJlX3RhcmdldDsKICAgIEJPT0wgbm9CYWNrQnVmZmVyQmFja3VwOwoKICAgIFRSQUNFKCJVc2luZyBod3N0cmV0Y2ggYmxpdFxuIik7CiAgICAvKiBBY3RpdmF0ZSB0aGUgUHJvcGVyIGNvbnRleHQgZm9yIHJlYWRpbmcgZnJvbSB0aGUgc291cmNlIHN1cmZhY2UsIHNldCBpdCB1cCBmb3IgYmxpdHRpbmcgKi8KICAgIEFjdGl2YXRlQ29udGV4dChteURldmljZSwgU3JjU3VyZmFjZSwgQ1RYVVNBR0VfQkxJVCk7CiAgICBJV2luZUQzRFN1cmZhY2VfUHJlTG9hZCgoSVdpbmVEM0RTdXJmYWNlICopIFRoaXMpOwoKICAgIG5vQmFja0J1ZmZlckJhY2t1cCA9ICFzd2FwY2hhaW4gJiYgd2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUgPT0gT1JNX0ZCTzsKICAgIGlmKCFub0JhY2tCdWZmZXJCYWNrdXAgJiYgU3JjLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lID09IDApIHsKICAgICAgICAvKiBHZXQgaXQgYSBkZXNjcmlwdGlvbiAqLwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKFNyY1N1cmZhY2UpOwogICAgfQogICAgRU5URVJfR0woKTsKCiAgICAvKiBUcnkgdG8gdXNlIGFuIGF1eCBidWZmZXIgZm9yIGRyYXdpbmcgdGhlIHJlY3RhbmdsZS4gVGhpcyB3YXkgaXQgZG9lc24ndCBuZWVkIHJlc3RvcmluZy4KICAgICAqIFRoaXMgd2F5IHdlIGRvbid0IGhhdmUgdG8gd2FpdCBmb3IgdGhlIDJuZCByZWFkYmFjayB0byBmaW5pc2ggdG8gbGVhdmUgdGhpcyBmdW5jdGlvbi4KICAgICAqLwogICAgaWYobXlEZXZpY2UtPmFjdGl2ZUNvbnRleHQtPmF1eF9idWZmZXJzID49IDIpIHsKICAgICAgICAvKiBHb3QgbW9yZSB0aGFuIG9uZSBhdXggYnVmZmVyPyBVc2UgdGhlIDJuZCBhdXggYnVmZmVyICovCiAgICAgICAgZHJhd0J1ZmZlciA9IEdMX0FVWDE7CiAgICB9IGVsc2UgaWYoKHN3YXBjaGFpbiB8fCBteURldmljZS0+b2Zmc2NyZWVuQnVmZmVyID09IEdMX0JBQ0spICYmIG15RGV2aWNlLT5hY3RpdmVDb250ZXh0LT5hdXhfYnVmZmVycyA+PSAxKSB7CiAgICAgICAgLyogT25seSBvbmUgYXV4IGJ1ZmZlciwgYnV0IGl0IGlzbid0IHVzZWQgKE9uc2NyZWVuIHJlbmRlcmluZywgb3Igbm9uLWF1eCBvcm0pPyBVc2UgaXQhICovCiAgICAgICAgZHJhd0J1ZmZlciA9IEdMX0FVWDA7CiAgICB9CgogICAgaWYobm9CYWNrQnVmZmVyQmFja3VwKSB7CiAgICAgICAgZ2xHZW5UZXh0dXJlcygxLCAmYmFja3VwKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZW5UZXh0dXJlc1xuIik7CiAgICAgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCBiYWNrdXApOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRUZXh0dXJlKFNyYy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQsIFNyYy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSkiKTsKICAgICAgICB0ZXh0dXJlX3RhcmdldCA9IEdMX1RFWFRVUkVfMkQ7CiAgICB9IGVsc2UgewogICAgICAgIC8qIEJhY2t1cCB0aGUgYmFjayBidWZmZXIgYW5kIGNvcHkgdGhlIHNvdXJjZSBidWZmZXIgaW50byBhIHRleHR1cmUgdG8gZHJhdyBhbiB1cHNpZGUgZG93biBzdHJldGNoZWQgcXVhZC4gSWYKICAgICAgICAgKiB3ZSBhcmUgcmVhZGluZyBmcm9tIHRoZSBiYWNrIGJ1ZmZlciwgdGhlIGJhY2t1cCBjYW4gYmUgdXNlZCBhcyBzb3VyY2UgdGV4dHVyZQogICAgICAgICAqLwogICAgICAgIHRleHR1cmVfdGFyZ2V0ID0gU3JjLT5nbERlc2NyaXB0aW9uLnRhcmdldDsKICAgICAgICBnbEJpbmRUZXh0dXJlKHRleHR1cmVfdGFyZ2V0LCBTcmMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRUZXh0dXJlKHRleHR1cmVfdGFyZ2V0LCBTcmMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpIik7CiAgICAgICAgZ2xFbmFibGUodGV4dHVyZV90YXJnZXQpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZSh0ZXh0dXJlX3RhcmdldCkiKTsKCiAgICAgICAgLyogRm9yIG5vdyBpbnZhbGlkYXRlIHRoZSB0ZXh0dXJlIGNvcHkgb2YgdGhlIGJhY2sgYnVmZmVyLiBEcmF3YWJsZSBhbmQgc3lzbWVtIGNvcHkgYXJlIHVudG91Y2hlZCAqLwogICAgICAgIFNyYy0+RmxhZ3MgJj0gflNGTEFHX0lOVEVYVFVSRTsKICAgIH0KCiAgICBpZihzd2FwY2hhaW4pIHsKICAgICAgICBnbFJlYWRCdWZmZXIoc3VyZmFjZV9nZXRfZ2xfYnVmZmVyKFNyY1N1cmZhY2UsIChJV2luZUQzRFN3YXBDaGFpbiAqKXN3YXBjaGFpbikpOwogICAgfSBlbHNlIHsKICAgICAgICBnbFJlYWRCdWZmZXIobXlEZXZpY2UtPm9mZnNjcmVlbkJ1ZmZlcik7CiAgICB9CgogICAgLyogVE9ETzogT25seSBiYWNrIHVwIHRoZSBwYXJ0IHRoYXQgd2lsbCBiZSBvdmVyd3JpdHRlbiAqLwogICAgZ2xDb3B5VGV4U3ViSW1hZ2UyRCh0ZXh0dXJlX3RhcmdldCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCAvKiByZWFkIG9mZnNldHMgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgIGZid2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgIGZiaGVpZ2h0KTsKCiAgICBjaGVja0dMY2FsbCgiZ2xDb3B5VGV4U3ViSW1hZ2UyRCIpOwoKICAgIC8qIE5vIGlzc3VlIHdpdGggb3ZlcnJpZGluZyB0aGVzZSAtIHRoZSBzYW1wbGVyIGlzIGRpcnR5IGR1ZSB0byBibGl0IHVzYWdlICovCiAgICBnbFRleFBhcmFtZXRlcmkodGV4dHVyZV90YXJnZXQsIEdMX1RFWFRVUkVfTUFHX0ZJTFRFUiwKICAgICAgICAgICAgICAgICAgICBtYWdMb29rdXBbRmlsdGVyIC0gV0lORUQzRFRFWEZfTk9ORV0pOwogICAgY2hlY2tHTGNhbGwoImdsVGV4UGFyYW1ldGVyaSIpOwogICAgZ2xUZXhQYXJhbWV0ZXJpKHRleHR1cmVfdGFyZ2V0LCBHTF9URVhUVVJFX01JTl9GSUxURVIsCiAgICAgICAgICAgICAgICAgICAgbWluTWlwTG9va3VwW0ZpbHRlcl1bV0lORUQzRFRFWEZfTk9ORV0pOwogICAgY2hlY2tHTGNhbGwoImdsVGV4UGFyYW1ldGVyaSIpOwoKICAgIGlmKCFzd2FwY2hhaW4gfHwgKElXaW5lRDNEU3VyZmFjZSAqKSBTcmMgPT0gc3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdKSB7CiAgICAgICAgc3JjID0gYmFja3VwID8gYmFja3VwIDogU3JjLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lOwogICAgfSBlbHNlIHsKICAgICAgICBnbFJlYWRCdWZmZXIoR0xfRlJPTlQpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIoR0xfRlJPTlQpIik7CgogICAgICAgIGdsR2VuVGV4dHVyZXMoMSwgJnNyYyk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsR2VuVGV4dHVyZXMoMSwgJnNyYykiKTsKICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIHNyYyk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgc3JjKSIpOwoKICAgICAgICAvKiBUT0RPOiBPbmx5IGNvcHkgdGhlIHBhcnQgdGhhdCB3aWxsIGJlIHJlYWQuIFVzZSBzcmVjdC0+eDEsIHNyZWN0LT55MiBhcyBvcmlnaW4sIGJ1dCB3aXRoIHRoZSB3aWR0aCB3YXRjaAogICAgICAgICAqIG91dCBmb3IgcG93ZXIgb2YgMiBzaXplcwogICAgICAgICAqLwogICAgICAgIGdsVGV4SW1hZ2UyRChHTF9URVhUVVJFXzJELCAwLCBHTF9SR0JBLCBTcmMtPnBvdzJXaWR0aCwgU3JjLT5wb3cySGVpZ2h0LCAwLAogICAgICAgICAgICAgICAgICAgIEdMX1JHQkEsIEdMX1VOU0lHTkVEX0JZVEUsIE5VTEwpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleEltYWdlMkQiKTsKICAgICAgICBnbENvcHlUZXhTdWJJbWFnZTJEKEdMX1RFWFRVUkVfMkQsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwIC8qIHJlYWQgb2Zmc2V0cyAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmYndpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZmJoZWlnaHQpOwoKICAgICAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9NQUdfRklMVEVSLCBHTF9ORUFSRVNUKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhQYXJhbWV0ZXJpIik7CiAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfTUlOX0ZJTFRFUiwgR0xfTkVBUkVTVCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4UGFyYW1ldGVyaSIpOwoKICAgICAgICBnbFJlYWRCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsUmVhZEJ1ZmZlcihHTF9CQUNLKSIpOwoKICAgICAgICBpZih0ZXh0dXJlX3RhcmdldCAhPSBHTF9URVhUVVJFXzJEKSB7CiAgICAgICAgICAgIGdsRGlzYWJsZSh0ZXh0dXJlX3RhcmdldCk7CiAgICAgICAgICAgIGdsRW5hYmxlKEdMX1RFWFRVUkVfMkQpOwogICAgICAgICAgICB0ZXh0dXJlX3RhcmdldCA9IEdMX1RFWFRVUkVfMkQ7CiAgICAgICAgfQogICAgfQogICAgY2hlY2tHTGNhbGwoImdsRW5kIGFuZCBwcmV2aW91cyIpOwoKICAgIGxlZnQgPSBzcmVjdC0+eDE7CiAgICByaWdodCA9IHNyZWN0LT54MjsKCiAgICBpZih1cHNpZGVkb3duKSB7CiAgICAgICAgdG9wID0gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQgLSBzcmVjdC0+eTE7CiAgICAgICAgYm90dG9tID0gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQgLSBzcmVjdC0+eTI7CiAgICB9IGVsc2UgewogICAgICAgIHRvcCA9IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0IC0gc3JlY3QtPnkyOwogICAgICAgIGJvdHRvbSA9IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0IC0gc3JlY3QtPnkxOwogICAgfQoKICAgIGlmKFNyYy0+RmxhZ3MgJiBTRkxBR19OT1JNQ09PUkQpIHsKICAgICAgICBsZWZ0IC89IFNyYy0+cG93MldpZHRoOwogICAgICAgIHJpZ2h0IC89IFNyYy0+cG93MldpZHRoOwogICAgICAgIHRvcCAvPSBTcmMtPnBvdzJIZWlnaHQ7CiAgICAgICAgYm90dG9tIC89IFNyYy0+cG93MkhlaWdodDsKICAgIH0KCiAgICAvKiBkcmF3IHRoZSBzb3VyY2UgdGV4dHVyZSBzdHJldGNoZWQgYW5kIHVwc2lkZSBkb3duLiBUaGUgY29ycmVjdCBzdXJmYWNlIGlzIGJvdW5kIGFscmVhZHkgKi8KICAgIGdsVGV4UGFyYW1ldGVyaSh0ZXh0dXJlX3RhcmdldCwgR0xfVEVYVFVSRV9XUkFQX1MsIEdMX0NMQU1QKTsKICAgIGdsVGV4UGFyYW1ldGVyaSh0ZXh0dXJlX3RhcmdldCwgR0xfVEVYVFVSRV9XUkFQX1QsIEdMX0NMQU1QKTsKCiAgICBnbERyYXdCdWZmZXIoZHJhd0J1ZmZlcik7CiAgICBnbFJlYWRCdWZmZXIoZHJhd0J1ZmZlcik7CgogICAgZ2xCZWdpbihHTF9RVUFEUyk7CiAgICAgICAgLyogYm90dG9tIGxlZnQgKi8KICAgICAgICBnbFRleENvb3JkMmYobGVmdCwgYm90dG9tKTsKICAgICAgICBnbFZlcnRleDJpKDAsIGZiaGVpZ2h0KTsKCiAgICAgICAgLyogdG9wIGxlZnQgKi8KICAgICAgICBnbFRleENvb3JkMmYobGVmdCwgdG9wKTsKICAgICAgICBnbFZlcnRleDJpKDAsIGZiaGVpZ2h0IC0gZHJlY3QtPnkyIC0gZHJlY3QtPnkxKTsKCiAgICAgICAgLyogdG9wIHJpZ2h0ICovCiAgICAgICAgZ2xUZXhDb29yZDJmKHJpZ2h0LCB0b3ApOwogICAgICAgIGdsVmVydGV4MmkoZHJlY3QtPngyIC0gZHJlY3QtPngxLCBmYmhlaWdodCAtIGRyZWN0LT55MiAtIGRyZWN0LT55MSk7CgogICAgICAgIC8qIGJvdHRvbSByaWdodCAqLwogICAgICAgIGdsVGV4Q29vcmQyZihyaWdodCwgYm90dG9tKTsKICAgICAgICBnbFZlcnRleDJpKGRyZWN0LT54MiAtIGRyZWN0LT54MSwgZmJoZWlnaHQpOwogICAgZ2xFbmQoKTsKICAgIGNoZWNrR0xjYWxsKCJnbEVuZCBhbmQgcHJldmlvdXMiKTsKCiAgICBpZih0ZXh0dXJlX3RhcmdldCAhPSBUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCkgewogICAgICAgIGdsRGlzYWJsZSh0ZXh0dXJlX3RhcmdldCk7CiAgICAgICAgZ2xFbmFibGUoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQpOwogICAgICAgIHRleHR1cmVfdGFyZ2V0ID0gVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQ7CiAgICB9CgogICAgLyogTm93IHJlYWQgdGhlIHN0cmV0Y2hlZCBhbmQgdXBzaWRlIGRvd24gaW1hZ2UgaW50byB0aGUgZGVzdGluYXRpb24gdGV4dHVyZSAqLwogICAgZ2xCaW5kVGV4dHVyZSh0ZXh0dXJlX3RhcmdldCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICBjaGVja0dMY2FsbCgiZ2xCaW5kVGV4dHVyZSIpOwogICAgZ2xDb3B5VGV4U3ViSW1hZ2UyRCh0ZXh0dXJlX3RhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgZHJlY3QtPngxLCBkcmVjdC0+eTEsIC8qIHhvZmZzZXQsIHlvZmZzZXQgKi8KICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgLyogV2UgYmxpdHRlZCB0aGUgaW1hZ2UgdG8gdGhlIG9yaWdpbiAqLwogICAgICAgICAgICAgICAgICAgICAgICBkcmVjdC0+eDIgLSBkcmVjdC0+eDEsIGRyZWN0LT55MiAtIGRyZWN0LT55MSk7CiAgICBjaGVja0dMY2FsbCgiZ2xDb3B5VGV4U3ViSW1hZ2UyRCIpOwoKICAgIGlmKGRyYXdCdWZmZXIgPT0gR0xfQkFDSykgewogICAgICAgIC8qIFdyaXRlIHRoZSBiYWNrIGJ1ZmZlciBiYWNrdXAgYmFjayAqLwogICAgICAgIGlmKGJhY2t1cCkgewogICAgICAgICAgICBpZih0ZXh0dXJlX3RhcmdldCAhPSBHTF9URVhUVVJFXzJEKSB7CiAgICAgICAgICAgICAgICBnbERpc2FibGUodGV4dHVyZV90YXJnZXQpOwogICAgICAgICAgICAgICAgZ2xFbmFibGUoR0xfVEVYVFVSRV8yRCk7CiAgICAgICAgICAgICAgICB0ZXh0dXJlX3RhcmdldCA9IEdMX1RFWFRVUkVfMkQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCBiYWNrdXApOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCBiYWNrdXApIik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYodGV4dHVyZV90YXJnZXQgIT0gU3JjLT5nbERlc2NyaXB0aW9uLnRhcmdldCkgewogICAgICAgICAgICAgICAgZ2xEaXNhYmxlKHRleHR1cmVfdGFyZ2V0KTsKICAgICAgICAgICAgICAgIGdsRW5hYmxlKFNyYy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQpOwogICAgICAgICAgICAgICAgdGV4dHVyZV90YXJnZXQgPSBTcmMtPmdsRGVzY3JpcHRpb24udGFyZ2V0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGdsQmluZFRleHR1cmUoU3JjLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgU3JjLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZFRleHR1cmUoU3JjLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgU3JjLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKSIpOwogICAgICAgIH0KCiAgICAgICAgZ2xCZWdpbihHTF9RVUFEUyk7CiAgICAgICAgICAgIC8qIHRvcCBsZWZ0ICovCiAgICAgICAgICAgIGdsVGV4Q29vcmQyZigwLjAsIChmbG9hdCkgZmJoZWlnaHQgLyAoZmxvYXQpIFNyYy0+cG93MkhlaWdodCk7CiAgICAgICAgICAgIGdsVmVydGV4MmkoMCwgMCk7CgogICAgICAgICAgICAvKiBib3R0b20gbGVmdCAqLwogICAgICAgICAgICBnbFRleENvb3JkMmYoMC4wLCAwLjApOwogICAgICAgICAgICBnbFZlcnRleDJpKDAsIGZiaGVpZ2h0KTsKCiAgICAgICAgICAgIC8qIGJvdHRvbSByaWdodCAqLwogICAgICAgICAgICBnbFRleENvb3JkMmYoKGZsb2F0KSBmYndpZHRoIC8gKGZsb2F0KSBTcmMtPnBvdzJXaWR0aCwgMC4wKTsKICAgICAgICAgICAgZ2xWZXJ0ZXgyaShmYndpZHRoLCBTcmMtPmN1cnJlbnREZXNjLkhlaWdodCk7CgogICAgICAgICAgICAvKiB0b3AgcmlnaHQgKi8KICAgICAgICAgICAgZ2xUZXhDb29yZDJmKChmbG9hdCkgZmJ3aWR0aCAvIChmbG9hdCkgU3JjLT5wb3cyV2lkdGgsIChmbG9hdCkgZmJoZWlnaHQgLyAoZmxvYXQpIFNyYy0+cG93MkhlaWdodCk7CiAgICAgICAgICAgIGdsVmVydGV4MmkoZmJ3aWR0aCwgMCk7CiAgICAgICAgZ2xFbmQoKTsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogUmVzdG9yZSB0aGUgb2xkIGRyYXcgYnVmZmVyICovCiAgICAgICAgZ2xEcmF3QnVmZmVyKEdMX0JBQ0spOwogICAgfQogICAgZ2xEaXNhYmxlKHRleHR1cmVfdGFyZ2V0KTsKICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUodGV4dHVyZV90YXJnZXQpIik7CgogICAgLyogQ2xlYW51cCAqLwogICAgaWYoc3JjICE9IFNyYy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSAmJiBzcmMgIT0gYmFja3VwKSB7CiAgICAgICAgZ2xEZWxldGVUZXh0dXJlcygxLCAmc3JjKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEZWxldGVUZXh0dXJlcygxLCAmc3JjKSIpOwogICAgfQogICAgaWYoYmFja3VwKSB7CiAgICAgICAgZ2xEZWxldGVUZXh0dXJlcygxLCAmYmFja3VwKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEZWxldGVUZXh0dXJlcygxLCAmYmFja3VwKSIpOwogICAgfQoKICAgIExFQVZFX0dMKCk7Cn0KCi8qIE5vdCBjYWxsZWQgZnJvbSB0aGUgVlRhYmxlICovCnN0YXRpYyBIUkVTVUxUIElXaW5lRDNEU3VyZmFjZUltcGxfQmx0T3ZlcnJpZGUoSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcywgUkVDVCAqRGVzdFJlY3QsIElXaW5lRDNEU3VyZmFjZSAqU3JjU3VyZmFjZSwgUkVDVCAqU3JjUmVjdCwgRFdPUkQgRmxhZ3MsIFdJTkVEREJMVEZYICpEREJsdEZ4LCBXSU5FRDNEVEVYVFVSRUZJTFRFUlRZUEUgRmlsdGVyKSB7CiAgICBXSU5FRDNEUkVDVCByZWN0OwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpteURldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICBJV2luZUQzRFN3YXBDaGFpbkltcGwgKnNyY1N3YXBjaGFpbiA9IE5VTEwsICpkc3RTd2FwY2hhaW4gPSBOVUxMOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqU3JjID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgU3JjU3VyZmFjZTsKCiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwLCVwLCUwOHgsJXApXG4iLCBUaGlzLCBEZXN0UmVjdCwgU3JjU3VyZmFjZSwgU3JjUmVjdCwgRmxhZ3MsIEREQmx0RngpOwoKICAgIC8qIEdldCB0aGUgc3dhcGNoYWluLiBPbmUgb2YgdGhlIHN1cmZhY2VzIGhhcyB0byBiZSBhIHByaW1hcnkgc3VyZmFjZSAqLwogICAgaWYoVGhpcy0+cmVzb3VyY2UucG9vbCA9PSBXSU5FRDNEUE9PTF9TWVNURU1NRU0pIHsKICAgICAgICBXQVJOKCJEZXN0aW5hdGlvbiBpcyBpbiBzeXNtZW0sIHJlamVjdGluZyBnbCBibHRcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lciggKElXaW5lRDNEU3VyZmFjZSAqKSBUaGlzLCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikmZHN0U3dhcGNoYWluKTsKICAgIGlmKGRzdFN3YXBjaGFpbikgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4gKikgZHN0U3dhcGNoYWluKTsKICAgIGlmKFNyYykgewogICAgICAgIGlmKFNyYy0+cmVzb3VyY2UucG9vbCA9PSBXSU5FRDNEUE9PTF9TWVNURU1NRU0pIHsKICAgICAgICAgICAgV0FSTigiU3JjIGlzIGluIHN5c21lbSwgcmVqZWN0aW5nIGdsIGJsdFxuIik7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgIH0KICAgICAgICBJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKCAoSVdpbmVEM0RTdXJmYWNlICopIFNyYywgJklJRF9JV2luZUQzRFN3YXBDaGFpbiwgKHZvaWQgKiopJnNyY1N3YXBjaGFpbik7CiAgICAgICAgaWYoc3JjU3dhcGNoYWluKSBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKChJV2luZUQzRFN3YXBDaGFpbiAqKSBzcmNTd2FwY2hhaW4pOwogICAgfQoKICAgIC8qIEVhcmx5IHNvcnQgb3V0IG9mIGNhc2VzIHdoZXJlIG5vIHJlbmRlciB0YXJnZXQgaXMgdXNlZCAqLwogICAgaWYoIWRzdFN3YXBjaGFpbiAmJiAhc3JjU3dhcGNoYWluICYmCiAgICAgICAgU3JjU3VyZmFjZSAhPSBteURldmljZS0+cmVuZGVyX3RhcmdldHNbMF0gJiYgVGhpcyAhPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBteURldmljZS0+cmVuZGVyX3RhcmdldHNbMF0pIHsKICAgICAgICBUUkFDRSgiTm8gc3VyZmFjZSBpcyByZW5kZXIgdGFyZ2V0LCBub3QgdXNpbmcgaGFyZHdhcmUgYmxpdC4gU3JjID0gJXAsIGRzdCA9ICVwXG4iLCBTcmMsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIC8qIE5vIGRlc3RpbmF0aW9uIGNvbG9yIGtleWluZyBzdXBwb3J0ZWQgKi8KICAgIGlmKEZsYWdzICYgKFdJTkVEREJMVF9LRVlERVNUIHwgV0lORUREQkxUX0tFWURFU1RPVkVSUklERSkpIHsKICAgICAgICAvKiBDYW4gd2Ugc3VwcG9ydCB0aGF0IHdpdGggZ2xCbGVuZEZ1bmMgaWYgYmxpdHRpbmcgdG8gdGhlIGZyYW1lIGJ1ZmZlcj8gKi8KICAgICAgICBUUkFDRSgiRGVzdGluYXRpb24gY29sb3Iga2V5IG5vdCBzdXBwb3J0ZWQgaW4gYWNjZWxlcmF0ZWQgQmxpdCwgZmFsbGluZyBiYWNrIHRvIHNvZnR3YXJlXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBpZiAoRGVzdFJlY3QpIHsKICAgICAgICByZWN0LngxID0gRGVzdFJlY3QtPmxlZnQ7CiAgICAgICAgcmVjdC55MSA9IERlc3RSZWN0LT50b3A7CiAgICAgICAgcmVjdC54MiA9IERlc3RSZWN0LT5yaWdodDsKICAgICAgICByZWN0LnkyID0gRGVzdFJlY3QtPmJvdHRvbTsKICAgIH0gZWxzZSB7CiAgICAgICAgcmVjdC54MSA9IDA7CiAgICAgICAgcmVjdC55MSA9IDA7CiAgICAgICAgcmVjdC54MiA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgIHJlY3QueTIgPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICB9CgogICAgLyogVGhlIG9ubHkgY2FzZSB3aGVyZSBib3RoIHN1cmZhY2VzIG9uIGEgc3dhcGNoYWluIGFyZSBzdXBwb3J0ZWQgaXMgYSBiYWNrIGJ1ZmZlciAtPiBmcm9udCBidWZmZXIgYmxpdCBvbiB0aGUgc2FtZSBzd2FwY2hhaW4gKi8KICAgIGlmKGRzdFN3YXBjaGFpbiAmJiBkc3RTd2FwY2hhaW4gPT0gc3JjU3dhcGNoYWluICYmIGRzdFN3YXBjaGFpbi0+YmFja0J1ZmZlciAmJgogICAgICAgKChJV2luZUQzRFN1cmZhY2UgKikgVGhpcyA9PSBkc3RTd2FwY2hhaW4tPmZyb250QnVmZmVyKSAmJiBTcmNTdXJmYWNlID09IGRzdFN3YXBjaGFpbi0+YmFja0J1ZmZlclswXSkgewogICAgICAgIC8qIEhhbGYtbGlmZSBkb2VzIGEgQmx0IGZyb20gdGhlIGJhY2sgYnVmZmVyIHRvIHRoZSBmcm9udCBidWZmZXIsCiAgICAgICAgICogRnVsbCBzdXJmYWNlIHNpemUsIG5vIGZsYWdzLi4uIFVzZSBwcmVzZW50IGluc3RlYWQKICAgICAgICAgKgogICAgICAgICAqIFRoaXMgcGF0aCB3aWxsIG9ubHkgYmUgZW50ZXJlZCBmb3IgZDNkNyBhbmQgZGRyYXcgYXBwcywgYmVjYXVzZSBkM2Q4Lzkgb2ZmZXIgbm8gd2F5IHRvIGJsaXQgVE8gdGhlIGZyb250IGJ1ZmZlcgogICAgICAgICAqLwoKICAgICAgICAvKiBDaGVjayByZWN0cyAtIElXaW5lRDNERGV2aWNlX1ByZXNlbnQgZG9lc24ndCBoYW5kbGUgdGhlbSAqLwogICAgICAgIHdoaWxlKDEpCiAgICAgICAgewogICAgICAgICAgICBSRUNUIG15U3JjUmVjdDsKICAgICAgICAgICAgVFJBQ0UoIkxvb2tpbmcgaWYgYSBQcmVzZW50IGNhbiBiZSBkb25lLi4uXG4iKTsKICAgICAgICAgICAgLyogU291cmNlIFJlY3RhbmdsZSBtdXN0IGJlIGZ1bGwgc3VyZmFjZSAqLwogICAgICAgICAgICBpZiggU3JjUmVjdCApIHsKICAgICAgICAgICAgICAgIGlmKFNyY1JlY3QtPmxlZnQgIT0gMCB8fCBTcmNSZWN0LT50b3AgIT0gMCB8fAogICAgICAgICAgICAgICAgICAgU3JjUmVjdC0+cmlnaHQgIT0gU3JjLT5jdXJyZW50RGVzYy5XaWR0aCB8fCBTcmNSZWN0LT5ib3R0b20gIT0gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpIHsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiTm8sIFNvdXJjZSByZWN0YW5nbGUgZG9lc24ndCBtYXRjaFxuIik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbXlTcmNSZWN0LmxlZnQgPSAwOwogICAgICAgICAgICBteVNyY1JlY3QudG9wID0gMDsKICAgICAgICAgICAgbXlTcmNSZWN0LnJpZ2h0ID0gU3JjLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICAgICAgbXlTcmNSZWN0LmJvdHRvbSA9IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0OwoKICAgICAgICAgICAgLyogTm8gc3RyZXRjaGluZyBtYXkgb2NjdXIgKi8KICAgICAgICAgICAgaWYobXlTcmNSZWN0LnJpZ2h0ICE9IHJlY3QueDIgLSByZWN0LngxIHx8CiAgICAgICAgICAgICAgIG15U3JjUmVjdC5ib3R0b20gIT0gcmVjdC55MiAtIHJlY3QueTEpIHsKICAgICAgICAgICAgICAgIFRSQUNFKCJObywgc3RyZXRjaGluZyBpcyBkb25lXG4iKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBEZXN0aW5hdGlvbiBtdXN0IGJlIGZ1bGwgc3VyZmFjZSBvciBtYXRjaCB0aGUgY2xpcHBpbmcgcmVjdGFuZ2xlICovCiAgICAgICAgICAgIGlmKFRoaXMtPmNsaXBwZXIgJiYgKChJV2luZUQzRENsaXBwZXJJbXBsICopIFRoaXMtPmNsaXBwZXIpLT5oV25kKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBSRUNUIGNsaXByZWN0OwogICAgICAgICAgICAgICAgUE9JTlQgcG9zWzJdOwogICAgICAgICAgICAgICAgR2V0Q2xpZW50UmVjdCgoKElXaW5lRDNEQ2xpcHBlckltcGwgKikgVGhpcy0+Y2xpcHBlciktPmhXbmQsICZjbGlwcmVjdCk7CiAgICAgICAgICAgICAgICBwb3NbMF0ueCA9IHJlY3QueDE7CiAgICAgICAgICAgICAgICBwb3NbMF0ueSA9IHJlY3QueTE7CiAgICAgICAgICAgICAgICBwb3NbMV0ueCA9IHJlY3QueDI7CiAgICAgICAgICAgICAgICBwb3NbMV0ueSA9IHJlY3QueTI7CiAgICAgICAgICAgICAgICBNYXBXaW5kb3dQb2ludHMoR2V0RGVza3RvcFdpbmRvdygpLCAoKElXaW5lRDNEQ2xpcHBlckltcGwgKikgVGhpcy0+Y2xpcHBlciktPmhXbmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zLCAyKTsKCiAgICAgICAgICAgICAgICBpZihwb3NbMF0ueCAhPSBjbGlwcmVjdC5sZWZ0ICB8fCBwb3NbMF0ueSAhPSBjbGlwcmVjdC50b3AgICB8fAogICAgICAgICAgICAgICAgICAgcG9zWzFdLnggIT0gY2xpcHJlY3QucmlnaHQgfHwgcG9zWzFdLnkgIT0gY2xpcHJlY3QuYm90dG9tKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJObywgZGVzdCByZWN0YW5nbGUgZG9lc24ndCBtYXRjaChjbGlwcGVyKVxuIik7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIkNsaXAgcmVjdCBhdCAoJWQsJWQpLSglZCwlZClcbiIsIGNsaXByZWN0LmxlZnQsIGNsaXByZWN0LnRvcCwgY2xpcHJlY3QucmlnaHQsIGNsaXByZWN0LmJvdHRvbSk7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIkJsdCBkZXN0OiAoJWQsJWQpLSglZCwlZClcbiIsIHJlY3QueDEsIHJlY3QueTEsIHJlY3QueDIsIHJlY3QueTIpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYocmVjdC54MSAhPSAwIHx8IHJlY3QueTEgIT0gMCB8fAogICAgICAgICAgICAgICAgICAgcmVjdC54MiAhPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCB8fCByZWN0LnkyICE9IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCkgewogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJObywgZGVzdCByZWN0YW5nbGUgZG9lc24ndCBtYXRjaChzdXJmYWNlIHNpemUpXG4iKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgVFJBQ0UoIlllc1xuIik7CgogICAgICAgICAgICAvKiBUaGVzZSBmbGFncyBhcmUgdW5pbXBvcnRhbnQgZm9yIHRoZSBmbGFnIGNoZWNrLCByZW1vdmUgdGhlbSAqLwogICAgICAgICAgICBpZigoRmxhZ3MgJiB+KFdJTkVEREJMVF9ET05PVFdBSVQgfCBXSU5FRERCTFRfV0FJVCkpID09IDApIHsKICAgICAgICAgICAgICAgIFdJTkVEM0RTV0FQRUZGRUNUIG9yaWdfc3dhcCA9IGRzdFN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLlN3YXBFZmZlY3Q7CgogICAgICAgICAgICAgICAgLyogVGhlIGlkZWEgYmVoaW5kIHRoaXMgaXMgdGhhdCBhIGdsUmVhZFBpeGVscyBhbmQgYSBnbERyYXdQaXhlbHMgY2FsbAogICAgICAgICAgICAgICAgICAgICogdGFrZSB2ZXJ5IGxvbmcsIHdoaWxlIGEgZmxpcCBpcyBmYXN0LgogICAgICAgICAgICAgICAgICAgICogVGhpcyBhcHBsaWVzIHRvIEhhbGYtTGlmZSwgd2hpY2ggZG9lcyBzdWNoIEJsdHMgZXZlcnkgdGltZSBpdCBmaW5pc2hlZAogICAgICAgICAgICAgICAgICAgICogYSBmcmFtZSwgYW5kIHRvIFByaW5jZSBvZiBQZXJzaWEgM0QsIHdoaWNoIHVzZXMgdGhpcyB0byBkcmF3IGF0IGxlYXN0IHRoZSBtYWluCiAgICAgICAgICAgICAgICAgICAgKiBtZW51LiBUaGlzIGlzIGFsc28gdXNlZCBieSBhbGwgYXBwcyB3aGVuIHRoZXkgZG8gd2luZG93ZWQgcmVuZGVyaW5nCiAgICAgICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAgICAgICogVGhlIHByb2JsZW0gaXMgdGhhdCBmbGlwcGluZyBpcyBub3QgcmVhbGx5IHRoZSBzYW1lIGFzIGNvcHlpbmcuIEFmdGVyIGEKICAgICAgICAgICAgICAgICAgICAqIEJsdCB0aGUgZnJvbnQgYnVmZmVyIGlzIGEgY29weSBvZiB0aGUgYmFjayBidWZmZXIsIGFuZCB0aGUgYmFjayBidWZmZXIgaXMKICAgICAgICAgICAgICAgICAgICAqIHVudG91Y2hlZC4gVGhlcmVmb3JlIGl0J3MgbmVjZXNzYXJ5IHRvIG92ZXJyaWRlIHRoZSBzd2FwIGVmZmVjdAogICAgICAgICAgICAgICAgICAgICogYW5kIHRvIHNldCBpdCBiYWNrIGFmdGVyIHRoZSBmbGlwLgogICAgICAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgICAgICAqIFdpbmRvd2VkIERpcmVjdDNEIDwgNyBhcHBzIGRvIHRoZSBzYW1lLiBUaGUgRDNENyBzZGsgZGVtb3MgYXJlIG5pY2UKICAgICAgICAgICAgICAgICAgICAqIHRlc3RjYXNlcy4KICAgICAgICAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgICAgIGRzdFN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLlN3YXBFZmZlY3QgPSBXSU5FRDNEU1dBUEVGRkVDVF9DT1BZOwogICAgICAgICAgICAgICAgZHN0U3dhcGNoYWluLT5wcmVzZW50UGFybXMuUHJlc2VudGF0aW9uSW50ZXJ2YWwgPSBXSU5FRDNEUFJFU0VOVF9JTlRFUlZBTF9JTU1FRElBVEU7CgogICAgICAgICAgICAgICAgVFJBQ0UoIkZ1bGwgc2NyZWVuIGJhY2sgYnVmZmVyIC0+IGZyb250IGJ1ZmZlciBibHQsIHBlcmZvcm1pbmcgYSBmbGlwIGluc3RlYWRcbiIpOwogICAgICAgICAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUHJlc2VudCgoSVdpbmVEM0RTd2FwQ2hhaW4gKikgZHN0U3dhcGNoYWluLCBOVUxMLCBOVUxMLCAwLCBOVUxMLCAwKTsKCiAgICAgICAgICAgICAgICBkc3RTd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5Td2FwRWZmZWN0ID0gb3JpZ19zd2FwOwoKICAgICAgICAgICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgVFJBQ0UoIlVuc3VwcG9ydGVkIGJsaXQgYmV0d2VlbiBidWZmZXJzIG9uIHRoZSBzYW1lIHN3YXBjaGFpblxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9IGVsc2UgaWYoZHN0U3dhcGNoYWluICYmIGRzdFN3YXBjaGFpbiA9PSBzcmNTd2FwY2hhaW4pIHsKICAgICAgICBGSVhNRSgiSW1wbGVtZW50IGhhcmR3YXJlIGJsaXQgYmV0d2VlbiB0d28gc3VyZmFjZXMgb24gdGhlIHNhbWUgc3dhcGNoYWluXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0gZWxzZSBpZihkc3RTd2FwY2hhaW4gJiYgc3JjU3dhcGNoYWluKSB7CiAgICAgICAgRklYTUUoIkltcGxlbWVudCBoYXJkd2FyZSBibGl0IGJldHdlZW4gdHdvIGRpZmZlcmVudCBzd2FwY2hhaW5zXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0gZWxzZSBpZihkc3RTd2FwY2hhaW4pIHsKICAgICAgICBpZihTcmNTdXJmYWNlID09IG15RGV2aWNlLT5yZW5kZXJfdGFyZ2V0c1swXSkgewogICAgICAgICAgICBUUkFDRSgiQmxpdCBmcm9tIGFjdGl2ZSByZW5kZXIgdGFyZ2V0IHRvIGEgc3dhcGNoYWluXG4iKTsKICAgICAgICAgICAgLyogSGFuZGxlZCB3aXRoIHJlZ3VsYXIgdGV4dHVyZSAtPiBzd2FwY2hhaW4gYmxpdCAqLwogICAgICAgIH0KICAgIH0gZWxzZSBpZihzcmNTd2FwY2hhaW4gJiYgVGhpcyA9PSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBteURldmljZS0+cmVuZGVyX3RhcmdldHNbMF0pIHsKICAgICAgICBGSVhNRSgiSW1wbGVtZW50IGJsaXQgZnJvbSBhIHN3YXBjaGFpbiB0byB0aGUgYWN0aXZlIHJlbmRlciB0YXJnZXRcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmKChzcmNTd2FwY2hhaW4gfHwgU3JjU3VyZmFjZSA9PSBteURldmljZS0+cmVuZGVyX3RhcmdldHNbMF0pICYmICFkc3RTd2FwY2hhaW4pIHsKICAgICAgICAvKiBCbGl0IGZyb20gcmVuZGVyIHRhcmdldCB0byB0ZXh0dXJlICovCiAgICAgICAgV0lORUQzRFJFQ1Qgc3JlY3Q7CiAgICAgICAgQk9PTCB1cHNpZGVEb3duLCBzdHJldGNoeDsKICAgICAgICBCT09MIHBhbGV0dGVPdmVycmlkZSA9IEZBTFNFOwoKICAgICAgICBpZihGbGFncyAmIChXSU5FRERCTFRfS0VZU1JDIHwgV0lORUREQkxUX0tFWVNSQ09WRVJSSURFKSkgewogICAgICAgICAgICBUUkFDRSgiQ29sb3Iga2V5aW5nIG5vdCBzdXBwb3J0ZWQgYnkgZnJhbWUgYnVmZmVyIHRvIHRleHR1cmUgYmxpdFxuIik7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgICAgICAvKiBEZXN0aW5hdGlvbiBjb2xvciBrZXkgaXMgY2hlY2tlZCBhYm92ZSAqLwogICAgICAgIH0KCiAgICAgICAgLyogTWFrZSBzdXJlIHRoYXQgdGhlIHRvcCBwaXhlbCBpcyBhbHdheXMgYWJvdmUgdGhlIGJvdHRvbSBwaXhlbCwgYW5kIGtlZXAgYSBzZXBhcmF0ZSB1cHNpZGUgZG93biBmbGFnCiAgICAgICAgICogZ2xDb3B5VGV4U3ViSW1hZ2UgaXMgYSBiaXQgcGlja3kgYWJvdXQgdGhlIHBhcmFtZXRlcnMgd2UgcGFzcyB0byBpdAogICAgICAgICAqLwogICAgICAgIGlmKFNyY1JlY3QpIHsKICAgICAgICAgICAgaWYoU3JjUmVjdC0+dG9wIDwgU3JjUmVjdC0+Ym90dG9tKSB7CiAgICAgICAgICAgICAgICBzcmVjdC55MSA9IFNyY1JlY3QtPnRvcDsKICAgICAgICAgICAgICAgIHNyZWN0LnkyID0gU3JjUmVjdC0+Ym90dG9tOwogICAgICAgICAgICAgICAgdXBzaWRlRG93biA9IEZBTFNFOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc3JlY3QueTEgPSBTcmNSZWN0LT5ib3R0b207CiAgICAgICAgICAgICAgICBzcmVjdC55MiA9IFNyY1JlY3QtPnRvcDsKICAgICAgICAgICAgICAgIHVwc2lkZURvd24gPSBUUlVFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNyZWN0LngxID0gU3JjUmVjdC0+bGVmdDsKICAgICAgICAgICAgc3JlY3QueDIgPSBTcmNSZWN0LT5yaWdodDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzcmVjdC54MSA9IDA7CiAgICAgICAgICAgIHNyZWN0LnkxID0gMDsKICAgICAgICAgICAgc3JlY3QueDIgPSBTcmMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgICAgICBzcmVjdC55MiA9IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgICAgICAgICB1cHNpZGVEb3duID0gRkFMU0U7CiAgICAgICAgfQogICAgICAgIGlmKHJlY3QueDEgPiByZWN0LngyKSB7CiAgICAgICAgICAgIFVJTlQgdG1wID0gcmVjdC54MjsKICAgICAgICAgICAgcmVjdC54MiA9IHJlY3QueDE7CiAgICAgICAgICAgIHJlY3QueDEgPSB0bXA7CiAgICAgICAgICAgIHVwc2lkZURvd24gPSAhdXBzaWRlRG93bjsKICAgICAgICB9CiAgICAgICAgaWYoIXNyY1N3YXBjaGFpbikgewogICAgICAgICAgICBUUkFDRSgiUmVhZGluZyBmcm9tIGFuIG9mZnNjcmVlbiB0YXJnZXRcbiIpOwogICAgICAgICAgICB1cHNpZGVEb3duID0gIXVwc2lkZURvd247CiAgICAgICAgfQoKICAgICAgICBpZihyZWN0LngyIC0gcmVjdC54MSAhPSBzcmVjdC54MiAtIHNyZWN0LngxKSB7CiAgICAgICAgICAgIHN0cmV0Y2h4ID0gVFJVRTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdHJldGNoeCA9IEZBTFNFOwogICAgICAgIH0KCiAgICAgICAgLyogV2hlbiBibGl0dGluZyBmcm9tIGEgcmVuZGVyIHRhcmdldCBhIHRleHR1cmUsIHRoZSB0ZXh0dXJlIGlzbid0IHJlcXVpcmVkIHRvIGhhdmUgYSBwYWxldHRlLgogICAgICAgICAqIEluIHRoaXMgY2FzZSBncmFiIHRoZSBwYWxldHRlIGZyb20gdGhlIHJlbmRlciB0YXJnZXQuICovCiAgICAgICAgaWYoKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX1A4KSAmJiAoVGhpcy0+cGFsZXR0ZSA9PSBOVUxMKSkgewogICAgICAgICAgICBwYWxldHRlT3ZlcnJpZGUgPSBUUlVFOwogICAgICAgICAgICBUUkFDRSgiU291cmNlIHN1cmZhY2UgKCVwKSBsYWNrcyBwYWxldHRlLCBvdmVycmlkaW5nIHBhbGV0dGUgd2l0aCBwYWxldHRlICVwIG9mIGRlc3RpbmF0aW9uIHN1cmZhY2UgKCVwKVxuIiwgU3JjLCBUaGlzLT5wYWxldHRlLCBUaGlzKTsKICAgICAgICAgICAgVGhpcy0+cGFsZXR0ZSA9IFNyYy0+cGFsZXR0ZTsKICAgICAgICB9CgogICAgICAgIC8qIEJsdCBpcyBhIHByZXR0eSBwb3dlcmZ1bCBjYWxsLCB3aGlsZSBnbENvcHlUZXhTdWJJbWFnZTJEIGlzIG5vdC4gZ2xDb3B5VGV4U3ViSW1hZ2UgY2Fubm90CiAgICAgICAgICogZmxpcCB0aGUgaW1hZ2Ugbm9yIHNjYWxlIGl0LgogICAgICAgICAqCiAgICAgICAgICogLT4gSWYgdGhlIGFwcCBhc2tzIGZvciBhIHVuc2NhbGVkLCB1cHNpZGUgZG93biBjb3B5LCBqdXN0IHBlcmZvcm0gb25lIGdsQ29weVRleFN1YkltYWdlMkQgY2FsbAogICAgICAgICAqIC0+IElmIHRoZSBhcHAgd2FudHMgYSBpbWFnZSB3aWR0aCBhbiB1bnNjYWxlZCB3aWR0aCwgY29weSBpdCBsaW5lIHBlciBsaW5lCiAgICAgICAgICogLT4gSWYgdGhlIGFwcCB3YW50cyBhIGltYWdlIHRoYXQgaXMgc2NhbGVkIG9uIHRoZSB4IGF4aXMsIGFuZCB0aGUgZGVzdGluYXRpb24gcmVjdGFuZ2xlIGlzIHNtYWxsZXIKICAgICAgICAgKiAgICB0aGFuIHRoZSBmcmFtZSBidWZmZXIsIGRyYXcgYW4gdXBzaWRlIGRvd24gc2NhbGVkIGltYWdlIG9udG8gdGhlIGZiLCByZWFkIGl0IGJhY2sgYW5kIHJlc3RvcmUgdGhlCiAgICAgICAgICogICAgYmFjayBidWZmZXIuIFRoaXMgaXMgc2xvd2VyIHRoYW4gcmVhZGluZyBsaW5lIHBlciBsaW5lLCB0aHVzIG5vdCB1c2VkIGZvciBmbGlwcGluZwogICAgICAgICAqIC0+IElmIHRoZSBhcHAgd2FudHMgYSBzY2FsZWQgaW1hZ2Ugd2l0aCBhIGRlc3QgcmVjdCB0aGF0IGlzIGJpZ2dlciB0aGFuIHRoZSBmYiwgaXQgaGFzIHRvIGJlIGNvcGllZAogICAgICAgICAqICAgIHBpeGVsIGJ5IHBpeGVsCiAgICAgICAgICoKICAgICAgICAgKiBJZiBFWFRfZnJhbWVidWZmZXJfYmxpdCBpcyBzdXBwb3J0ZWQgdGhhdCBjYW4gYmUgdXNlZCBpbnN0ZWFkLiBOb3RlIHRoYXQgRVhUX2ZyYW1lYnVmZmVyX2JsaXQgaW1wbGllcwogICAgICAgICAqIEZCTyBzdXBwb3J0LCBzbyBpdCBkb2Vzbid0IHJlYWxseSBtYWtlIHNlbnNlIHRvIHRyeSBhbmQgbWFrZSBpdCB3b3JrIHdpdGggZGlmZmVyZW50IG9mZnNjcmVlbiByZW5kZXJpbmcKICAgICAgICAgKiBiYWNrZW5kcy4KICAgICAgICAgKi8KICAgICAgICBpZiAod2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUgPT0gT1JNX0ZCTyAmJiBHTF9TVVBQT1JUKEVYVF9GUkFNRUJVRkZFUl9CTElUKSkgewogICAgICAgICAgICBzdHJldGNoX3JlY3RfZmJvKChJV2luZUQzRERldmljZSAqKW15RGV2aWNlLCBTcmNTdXJmYWNlLCAmc3JlY3QsCiAgICAgICAgICAgICAgICAgICAgKElXaW5lRDNEU3VyZmFjZSAqKVRoaXMsICZyZWN0LCBGaWx0ZXIsIHVwc2lkZURvd24pOwogICAgICAgIH0gZWxzZSBpZigoIXN0cmV0Y2h4KSB8fCByZWN0LngyIC0gcmVjdC54MSA+IFNyYy0+Y3VycmVudERlc2MuV2lkdGggfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVjdC55MiAtIHJlY3QueTEgPiBTcmMtPmN1cnJlbnREZXNjLkhlaWdodCkgewogICAgICAgICAgICBUUkFDRSgiTm8gc3RyZXRjaGluZyBpbiB4IGRpcmVjdGlvbiwgdXNpbmcgZGlyZWN0IGZyYW1lYnVmZmVyIC0+IHRleHR1cmUgY29weVxuIik7CiAgICAgICAgICAgIGZiX2NvcHlfdG9fdGV4dHVyZV9kaXJlY3QoVGhpcywgU3JjU3VyZmFjZSwgc3JjU3dhcGNoYWluLCAmc3JlY3QsICZyZWN0LCB1cHNpZGVEb3duLCBGaWx0ZXIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFRSQUNFKCJVc2luZyBoYXJkd2FyZSBzdHJldGNoaW5nIHRvIGZsaXAgLyBzdHJldGNoIHRoZSB0ZXh0dXJlXG4iKTsKICAgICAgICAgICAgZmJfY29weV90b190ZXh0dXJlX2h3c3RyZXRjaChUaGlzLCBTcmNTdXJmYWNlLCBzcmNTd2FwY2hhaW4sICZzcmVjdCwgJnJlY3QsIHVwc2lkZURvd24sIEZpbHRlcik7CiAgICAgICAgfQoKICAgICAgICAvKiBDbGVhciB0aGUgcGFsZXR0ZSBhcyB0aGUgc3VyZmFjZSBkaWRuJ3QgaGF2ZSBhIHBhbGV0dGUgYXR0YWNoZWQsIGl0IHdvdWxkIGNvbmZ1c2UgR2V0UGFsZXR0ZSBhbmQgb3RoZXIgY2FsbHMgKi8KICAgICAgICBpZihwYWxldHRlT3ZlcnJpZGUpCiAgICAgICAgICAgIFRoaXMtPnBhbGV0dGUgPSBOVUxMOwoKICAgICAgICBpZighKFRoaXMtPkZsYWdzICYgU0ZMQUdfRE9OT1RGUkVFKSkgewogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5yZXNvdXJjZS5oZWFwTWVtb3J5KTsKICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gTlVMTDsKICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuaGVhcE1lbW9yeSA9IE5VTEw7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0lOU1lTTUVNOwogICAgICAgIH0KICAgICAgICAvKiBUaGUgdGV4dHVyZSBpcyBub3cgbW9zdCB1cCB0byBkYXRlIC0gSWYgdGhlIHN1cmZhY2UgaXMgYSByZW5kZXIgdGFyZ2V0IGFuZCBoYXMgYSBkcmF3YWJsZSwgdGhpcwogICAgICAgICAqIHBhdGggaXMgbmV2ZXIgZW50ZXJlZAogICAgICAgICAqLwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9Nb2RpZnlMb2NhdGlvbigoSVdpbmVEM0RTdXJmYWNlICopIFRoaXMsIFNGTEFHX0lOVEVYVFVSRSwgVFJVRSk7CgogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfSBlbHNlIGlmKFNyYykgewogICAgICAgIC8qIEJsaXQgZnJvbSBvZmZzY3JlZW4gc3VyZmFjZSB0byByZW5kZXIgdGFyZ2V0ICovCiAgICAgICAgZmxvYXQgZ2xUZXhDb29yZFs0XTsKICAgICAgICBEV09SRCBvbGRDS2V5RmxhZ3MgPSBTcmMtPkNLZXlGbGFnczsKICAgICAgICBXSU5FRERDT0xPUktFWSBvbGRCbHRDS2V5ID0gVGhpcy0+U3JjQmx0Q0tleTsKICAgICAgICBSRUNUIFNvdXJjZVJlY3RhbmdsZTsKICAgICAgICBCT09MIHBhbGV0dGVPdmVycmlkZSA9IEZBTFNFOwoKICAgICAgICBUUkFDRSgiQmx0IGZyb20gc3VyZmFjZSAlcCB0byByZW5kZXJ0YXJnZXQgJXBcbiIsIFNyYywgVGhpcyk7CgogICAgICAgIGlmKFNyY1JlY3QpIHsKICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLmxlZnQgPSBTcmNSZWN0LT5sZWZ0OwogICAgICAgICAgICBTb3VyY2VSZWN0YW5nbGUucmlnaHQgPSBTcmNSZWN0LT5yaWdodDsKICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLnRvcCA9IFNyY1JlY3QtPnRvcDsKICAgICAgICAgICAgU291cmNlUmVjdGFuZ2xlLmJvdHRvbSA9IFNyY1JlY3QtPmJvdHRvbTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBTb3VyY2VSZWN0YW5nbGUubGVmdCA9IDA7CiAgICAgICAgICAgIFNvdXJjZVJlY3RhbmdsZS5yaWdodCA9IFNyYy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgICAgIFNvdXJjZVJlY3RhbmdsZS50b3AgPSAwOwogICAgICAgICAgICBTb3VyY2VSZWN0YW5nbGUuYm90dG9tID0gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgfQogICAgICAgIGlmICh3aW5lZDNkX3NldHRpbmdzLm9mZnNjcmVlbl9yZW5kZXJpbmdfbW9kZSA9PSBPUk1fRkJPICYmIEdMX1NVUFBPUlQoRVhUX0ZSQU1FQlVGRkVSX0JMSVQpICYmCiAgICAgICAgICAgIChGbGFncyAmIChXSU5FRERCTFRfS0VZU1JDIHwgV0lORUREQkxUX0tFWVNSQ09WRVJSSURFKSkgPT0gMCkgewogICAgICAgICAgICBUUkFDRSgiVXNpbmcgc3RyZXRjaF9yZWN0X2Zib1xuIik7CiAgICAgICAgICAgIC8qIFRoZSBzb3VyY2UgaXMgYWx3YXlzIGEgdGV4dHVyZSwgYnV0IG5ldmVyIHRoZSBjdXJyZW50bHkgYWN0aXZlIHJlbmRlciB0YXJnZXQsIGFuZCB0aGUgdGV4dHVyZQogICAgICAgICAgICAgKiBjb250ZW50cyBhcmUgbmV2ZXIgdXBzaWRlIGRvd24KICAgICAgICAgICAgICovCiAgICAgICAgICAgIHN0cmV0Y2hfcmVjdF9mYm8oKElXaW5lRDNERGV2aWNlICopbXlEZXZpY2UsIFNyY1N1cmZhY2UsIChXSU5FRDNEUkVDVCAqKSAmU291cmNlUmVjdGFuZ2xlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSVdpbmVEM0RTdXJmYWNlICopVGhpcywgJnJlY3QsIEZpbHRlciwgRkFMU0UpOwogICAgICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgICAgICB9CgogICAgICAgIGlmKCFDYWxjdWxhdGVUZXhSZWN0KFNyYywgJlNvdXJjZVJlY3RhbmdsZSwgZ2xUZXhDb29yZCkpIHsKICAgICAgICAgICAgLyogRmFsbCBiYWNrIHRvIHNvZnR3YXJlICovCiAgICAgICAgICAgIFdBUk4oIiglcCkgU291cmNlIHRleHR1cmUgYXJlYSAoJWQsJWQpLSglZCwlZCkgaXMgdG9vIGJpZ1xuIiwgU3JjLAogICAgICAgICAgICAgICAgICAgIFNvdXJjZVJlY3RhbmdsZS5sZWZ0LCBTb3VyY2VSZWN0YW5nbGUudG9wLAogICAgICAgICAgICAgICAgICAgIFNvdXJjZVJlY3RhbmdsZS5yaWdodCwgU291cmNlUmVjdGFuZ2xlLmJvdHRvbSk7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgIH0KCiAgICAgICAgLyogQ29sb3Iga2V5aW5nOiBDaGVjayBpZiB3ZSBoYXZlIHRvIGRvIGEgY29sb3Iga2V5ZWQgYmx0LAogICAgICAgICAqIGFuZCBpZiBub3QgY2hlY2sgaWYgYSBjb2xvciBrZXkgaXMgYWN0aXZhdGVkLgogICAgICAgICAqCiAgICAgICAgICogSnVzdCBtb2RpZnkgdGhlIGNvbG9yIGtleWluZyBwYXJhbWV0ZXJzIGluIHRoZSBzdXJmYWNlIGFuZCByZXN0b3JlIHRoZW0gYWZ0ZXJ3YXJkcwogICAgICAgICAqIFRoZSBzdXJmYWNlIGtlZXBzIHRyYWNrIG9mIHRoZSBjb2xvciBrZXkgbGFzdCB1c2VkIHRvIGxvYWQgdGhlIG9wZW5nbCBzdXJmYWNlLgogICAgICAgICAqIFByZUxvYWQgd2lsbCBjYXRjaCB0aGUgY2hhbmdlIHRvIHRoZSBmbGFncyBhbmQgY29sb3Iga2V5IGFuZCByZWxvYWQgaWYgbmVjZXNzYXJ5LgogICAgICAgICAqLwogICAgICAgIGlmKEZsYWdzICYgV0lORUREQkxUX0tFWVNSQykgewogICAgICAgICAgICAvKiBVc2UgY29sb3Iga2V5IGZyb20gc3VyZmFjZSAqLwogICAgICAgIH0gZWxzZSBpZihGbGFncyAmIFdJTkVEREJMVF9LRVlTUkNPVkVSUklERSkgewogICAgICAgICAgICAvKiBVc2UgY29sb3Iga2V5IGZyb20gRERCbHRGeCAqLwogICAgICAgICAgICBTcmMtPkNLZXlGbGFncyB8PSBXSU5FRERTRF9DS1NSQ0JMVDsKICAgICAgICAgICAgVGhpcy0+U3JjQmx0Q0tleSA9IEREQmx0RngtPmRkY2tTcmNDb2xvcmtleTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvKiBEbyBub3QgdXNlIGNvbG9yIGtleSAqLwogICAgICAgICAgICBTcmMtPkNLZXlGbGFncyAmPSB+V0lORUREU0RfQ0tTUkNCTFQ7CiAgICAgICAgfQoKICAgICAgICAvKiBXaGVuIGJsaXR0aW5nIGZyb20gYW4gb2Zmc2NyZWVuIHN1cmZhY2UgdG8gYSByZW5kZXJ0YXJnZXQsIHRoZSBzb3VyY2UKICAgICAgICAgKiBzdXJmYWNlIGlzIG5vdCByZXF1aXJlZCB0byBoYXZlIGEgcGFsZXR0ZS4gT3VyIHJlbmRlcmluZyAvIGNvbnZlcnNpb24KICAgICAgICAgKiBjb2RlIGZ1cnRoZXIgZG93biB0aGUgcm9hZCByZXRyaWV2ZXMgdGhlIHBhbGV0dGUgZnJvbSB0aGUgc3VyZmFjZSwgc28KICAgICAgICAgKiBpdCBtdXN0IGhhdmUgYSBwYWxldHRlIHNldC4gKi8KICAgICAgICBpZigoU3JjLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9QOCkgJiYgKFNyYy0+cGFsZXR0ZSA9PSBOVUxMKSkgewogICAgICAgICAgICBwYWxldHRlT3ZlcnJpZGUgPSBUUlVFOwogICAgICAgICAgICBUUkFDRSgiU291cmNlIHN1cmZhY2UgKCVwKSBsYWNrcyBwYWxldHRlLCBvdmVycmlkaW5nIHBhbGV0dGUgd2l0aCBwYWxldHRlICVwIG9mIGRlc3RpbmF0aW9uIHN1cmZhY2UgKCVwKVxuIiwgU3JjLCBUaGlzLT5wYWxldHRlLCBUaGlzKTsKICAgICAgICAgICAgU3JjLT5wYWxldHRlID0gVGhpcy0+cGFsZXR0ZTsKICAgICAgICB9CgogICAgICAgIC8qIE5vdyBsb2FkIHRoZSBzdXJmYWNlICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1ByZUxvYWQoKElXaW5lRDNEU3VyZmFjZSAqKSBTcmMpOwoKCiAgICAgICAgLyogQWN0aXZhdGUgdGhlIGRlc3RpbmF0aW9uIGNvbnRleHQsIHNldCBpdCB1cCBmb3IgYmxpdHRpbmcgKi8KICAgICAgICBBY3RpdmF0ZUNvbnRleHQobXlEZXZpY2UsIChJV2luZUQzRFN1cmZhY2UgKikgVGhpcywgQ1RYVVNBR0VfQkxJVCk7CiAgICAgICAgRU5URVJfR0woKTsKCiAgICAgICAgZ2xFbmFibGUoU3JjLT5nbERlc2NyaXB0aW9uLnRhcmdldCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlKFNyYy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQpIik7CgogICAgICAgIGlmKCFkc3RTd2FwY2hhaW4pIHsKICAgICAgICAgICAgVFJBQ0UoIkRyYXdpbmcgdG8gb2Zmc2NyZWVuIGJ1ZmZlclxuIik7CiAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihteURldmljZS0+b2Zmc2NyZWVuQnVmZmVyKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlciIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIEdMZW51bSBidWZmZXIgPSBzdXJmYWNlX2dldF9nbF9idWZmZXIoKElXaW5lRDNEU3VyZmFjZSAqKVRoaXMsIChJV2luZUQzRFN3YXBDaGFpbiAqKWRzdFN3YXBjaGFpbik7CiAgICAgICAgICAgIFRSQUNFKCJEcmF3aW5nIHRvICUjeCBidWZmZXJcbiIsIGJ1ZmZlcik7CiAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihidWZmZXIpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyIik7CiAgICAgICAgfQoKICAgICAgICAvKiBCaW5kIHRoZSB0ZXh0dXJlICovCiAgICAgICAgZ2xCaW5kVGV4dHVyZShTcmMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBTcmMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRUZXh0dXJlIik7CgogICAgICAgIC8qIEZpbHRlcmluZyBmb3IgU3RyZXRjaFJlY3QgKi8KICAgICAgICBnbFRleFBhcmFtZXRlcmkoU3JjLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgR0xfVEVYVFVSRV9NQUdfRklMVEVSLAogICAgICAgICAgICAgICAgICAgICAgICBtYWdMb29rdXBbRmlsdGVyIC0gV0lORUQzRFRFWEZfTk9ORV0pOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleFBhcmFtZXRlcmkiKTsKICAgICAgICBnbFRleFBhcmFtZXRlcmkoU3JjLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgR0xfVEVYVFVSRV9NSU5fRklMVEVSLAogICAgICAgICAgICAgICAgICAgICAgICBtaW5NaXBMb29rdXBbRmlsdGVyXVtXSU5FRDNEVEVYRl9OT05FXSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4UGFyYW1ldGVyaSIpOwogICAgICAgIGdsVGV4UGFyYW1ldGVyaShTcmMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBHTF9URVhUVVJFX1dSQVBfUywgR0xfQ0xBTVApOwogICAgICAgIGdsVGV4UGFyYW1ldGVyaShTcmMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBHTF9URVhUVVJFX1dSQVBfVCwgR0xfQ0xBTVApOwogICAgICAgIGdsVGV4RW52aShHTF9URVhUVVJFX0VOViwgR0xfVEVYVFVSRV9FTlZfTU9ERSwgR0xfUkVQTEFDRSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4RW52aSIpOwoKICAgICAgICAvKiBUaGlzIGlzIGZvciBjb2xvciBrZXlpbmcgKi8KICAgICAgICBpZihGbGFncyAmIChXSU5FRERCTFRfS0VZU1JDIHwgV0lORUREQkxUX0tFWVNSQ09WRVJSSURFKSkgewogICAgICAgICAgICBnbEVuYWJsZShHTF9BTFBIQV9URVNUKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIEdMX0FMUEhBX1RFU1QiKTsKCiAgICAgICAgICAgIC8qIFdoZW4gdGhlIHByaW1hcnkgcmVuZGVyIHRhcmdldCB1c2VzIFA4LCB0aGUgYWxwaGEgY29tcG9uZW50IGNvbnRhaW5zIHRoZSBwYWxldHRlIGluZGV4LgogICAgICAgICAgICAgKiBXaGljaCBtZWFucyB0aGF0IHRoZSBjb2xvcmtleSBpcyBvbmUgb2YgdGhlIHBhbGV0dGUgZW50cmllcy4gSW4gb3RoZXIgY2FzZXMgcGl4ZWxzIHRoYXQKICAgICAgICAgICAgICogc2hvdWxkIGJlIG1hc2tlZCBhd2F5IGhhdmUgYWxwaGEgc2V0IHRvIDAuICovCiAgICAgICAgICAgIGlmKHByaW1hcnlfcmVuZGVyX3RhcmdldF9pc19wOChteURldmljZSkpCiAgICAgICAgICAgICAgICBnbEFscGhhRnVuYyhHTF9OT1RFUVVBTCwgKGZsb2F0KVRoaXMtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlTG93VmFsdWUgLyAyNTYuMCk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGdsQWxwaGFGdW5jKEdMX05PVEVRVUFMLCAwLjApOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xBbHBoYUZ1bmNcbiIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9BTFBIQV9URVNUKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9BTFBIQV9URVNUIik7CiAgICAgICAgfQoKICAgICAgICAvKiBEcmF3IGEgdGV4dHVyZWQgcXVhZAogICAgICAgICAqLwogICAgICAgIGdsQmVnaW4oR0xfUVVBRFMpOwoKICAgICAgICBnbENvbG9yM2QoMS4wZiwgMS4wZiwgMS4wZik7CiAgICAgICAgZ2xUZXhDb29yZDJmKGdsVGV4Q29vcmRbMF0sIGdsVGV4Q29vcmRbMl0pOwogICAgICAgIGdsVmVydGV4M2YocmVjdC54MSwKICAgICAgICAgICAgICAgICAgICByZWN0LnkxLAogICAgICAgICAgICAgICAgICAgIDAuMCk7CgogICAgICAgIGdsVGV4Q29vcmQyZihnbFRleENvb3JkWzBdLCBnbFRleENvb3JkWzNdKTsKICAgICAgICBnbFZlcnRleDNmKHJlY3QueDEsIHJlY3QueTIsIDAuMCk7CgogICAgICAgIGdsVGV4Q29vcmQyZihnbFRleENvb3JkWzFdLCBnbFRleENvb3JkWzNdKTsKICAgICAgICBnbFZlcnRleDNmKHJlY3QueDIsCiAgICAgICAgICAgICAgICAgICAgcmVjdC55MiwKICAgICAgICAgICAgICAgICAgICAwLjApOwoKICAgICAgICBnbFRleENvb3JkMmYoZ2xUZXhDb29yZFsxXSwgZ2xUZXhDb29yZFsyXSk7CiAgICAgICAgZ2xWZXJ0ZXgzZihyZWN0LngyLAogICAgICAgICAgICAgICAgICAgIHJlY3QueTEsCiAgICAgICAgICAgICAgICAgICAgMC4wKTsKICAgICAgICBnbEVuZCgpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuZCIpOwoKICAgICAgICBpZihGbGFncyAmIChXSU5FRERCTFRfS0VZU1JDIHwgV0lORUREQkxUX0tFWVNSQ09WRVJSSURFKSkgewogICAgICAgICAgICBnbERpc2FibGUoR0xfQUxQSEFfVEVTVCk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUoR0xfQUxQSEFfVEVTVCkiKTsKICAgICAgICB9CgogICAgICAgIC8qIEZsdXNoIGluIGNhc2UgdGhlIGRyYXdhYmxlIGlzIHVzZWQgYnkgbXVsdGlwbGUgR0wgY29udGV4dHMgKi8KICAgICAgICBpZihkc3RTd2FwY2hhaW4gJiYgKGRzdFN3YXBjaGFpbi0+bnVtX2NvbnRleHRzID49IDIpKQogICAgICAgICAgICBnbEZsdXNoKCk7CgogICAgICAgIGdsQmluZFRleHR1cmUoU3JjLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgMCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZFRleHR1cmUoU3JjLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgMCkiKTsKICAgICAgICAvKiBMZWF2ZSB0aGUgb3BlbmdsIHN0YXRlIHZhbGlkIGZvciBibGl0dGluZyAqLwogICAgICAgIGdsRGlzYWJsZShTcmMtPmdsRGVzY3JpcHRpb24udGFyZ2V0KTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKFNyYy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQpIik7CgogICAgICAgIC8qIFRoZSBkcmF3IGJ1ZmZlciBzaG91bGQgb25seSBuZWVkIHRvIGJlIHJlc3RvcmVkIGlmIHdlIHdlcmUgZHJhd2luZyB0byB0aGUgZnJvbnQgYnVmZmVyLCBhbmQgdGhlcmUgaXMgYSBiYWNrIGJ1ZmZlci4KICAgICAgICAgKiBvdGhlcndpc2UgdGhlIGNvbnRleHQgbWFuYWdlciBzaG91bGQgY2hvb3NlIGJldHdlZW4gR0xfQkFDSyAvIG9mZnNjcmVlbkRyYXdCdWZmZXIKICAgICAgICAgKi8KICAgICAgICBpZihkc3RTd2FwY2hhaW4gJiYgVGhpcyA9PSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBkc3RTd2FwY2hhaW4tPmZyb250QnVmZmVyICYmIGRzdFN3YXBjaGFpbi0+YmFja0J1ZmZlcikgewogICAgICAgICAgICBnbERyYXdCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIiKTsKICAgICAgICB9CiAgICAgICAgLyogUmVzdG9yZSB0aGUgY29sb3Iga2V5IHBhcmFtZXRlcnMgKi8KICAgICAgICBTcmMtPkNLZXlGbGFncyA9IG9sZENLZXlGbGFnczsKICAgICAgICBUaGlzLT5TcmNCbHRDS2V5ID0gb2xkQmx0Q0tleTsKCiAgICAgICAgLyogQ2xlYXIgdGhlIHBhbGV0dGUgYXMgdGhlIHN1cmZhY2UgZGlkbid0IGhhdmUgYSBwYWxldHRlIGF0dGFjaGVkLCBpdCB3b3VsZCBjb25mdXNlIEdldFBhbGV0dGUgYW5kIG90aGVyIGNhbGxzICovCiAgICAgICAgaWYocGFsZXR0ZU92ZXJyaWRlKQogICAgICAgICAgICBTcmMtPnBhbGV0dGUgPSBOVUxMOwoKICAgICAgICBMRUFWRV9HTCgpOwoKICAgICAgICAvKiBUT0RPOiBJZiB0aGUgc3VyZmFjZSBpcyBsb2NrZWQgb2Z0ZW4sIHBlcmZvcm0gdGhlIEJsdCBpbiBzb2Z0d2FyZSBvbiB0aGUgbWVtb3J5IGluc3RlYWQgKi8KICAgICAgICAvKiBUaGUgc3VyZmFjZSBpcyBub3cgaW4gdGhlIGRyYXdhYmxlLiBPbiBvbnNjcmVlbiBzdXJmYWNlcyBvciB3aXRob3V0IGZib3MgdGhlIHRleHR1cmUKICAgICAgICAgKiBpcyBvdXRkYXRlZCBub3cKICAgICAgICAgKi8KICAgICAgICBJV2luZUQzRFN1cmZhY2VfTW9kaWZ5TG9jYXRpb24oKElXaW5lRDNEU3VyZmFjZSAqKSBUaGlzLCBTRkxBR19JTkRSQVdBQkxFLCBUUlVFKTsKICAgICAgICAvKiBUT0RPOiBUaGlzIHNob3VsZCBiZSBtb3ZlZCB0byBNb2RpZnlMb2NhdGlvbigpICovCiAgICAgICAgaWYoIShkc3RTd2FwY2hhaW4gfHwgd2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUgIT0gT1JNX0ZCTykpIHsKICAgICAgICAgICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfSU5URVhUVVJFOwogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9IGVsc2UgewogICAgICAgIC8qIFNvdXJjZS1MZXNzIEJsaXQgdG8gcmVuZGVyIHRhcmdldCAqLwogICAgICAgIGlmIChGbGFncyAmIFdJTkVEREJMVF9DT0xPUkZJTEwpIHsKICAgICAgICAgICAgLyogVGhpcyBpcyBlYXN5IHRvIGhhbmRsZSBmb3IgdGhlIEQzRCBEZXZpY2UuLi4gKi8KICAgICAgICAgICAgRFdPUkQgY29sb3I7CgogICAgICAgICAgICBUUkFDRSgiQ29sb3JmaWxsXG4iKTsKCiAgICAgICAgICAgIC8qIFRoaXMgPT0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgbXlEZXZpY2UtPnJlbmRlcl90YXJnZXRzWzBdIHx8IGRzdFN3YXBjaGFpbgogICAgICAgICAgICAgICAgbXVzdCBiZSB0cnVlIGlmIHdlIGFyZSBoZXJlICovCiAgICAgICAgICAgIGlmIChUaGlzICE9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIG15RGV2aWNlLT5yZW5kZXJfdGFyZ2V0c1swXSAmJgogICAgICAgICAgICAgICAgICAgICEoVGhpcyA9PSAoSVdpbmVEM0RTdXJmYWNlSW1wbCopIGRzdFN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIgfHwKICAgICAgICAgICAgICAgICAgICAgIChkc3RTd2FwY2hhaW4tPmJhY2tCdWZmZXIgJiYgVGhpcyA9PSAoSVdpbmVEM0RTdXJmYWNlSW1wbCopIGRzdFN3YXBjaGFpbi0+YmFja0J1ZmZlclswXSkpKSB7CiAgICAgICAgICAgICAgICBUUkFDRSgiU3VyZmFjZSBpcyBoaWdoZXIgYmFjayBidWZmZXIsIGZhbGxpbmcgYmFjayB0byBzb2Z0d2FyZVxuIik7CiAgICAgICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogVGhlIGNvbG9yIGFzIGdpdmVuIGluIHRoZSBCbHQgZnVuY3Rpb24gaXMgaW4gdGhlIGZvcm1hdCBvZiB0aGUgZnJhbWUtYnVmZmVyLi4uCiAgICAgICAgICAgICAqICdjbGVhcicgZXhwZWN0IGl0IGluIEFSR0IgZm9ybWF0ID0+IHdlIG5lZWQgdG8gZG8gc29tZSBjb252ZXJzaW9uIDotKQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX1A4KSB7CiAgICAgICAgICAgICAgICBEV09SRCBhbHBoYTsKCiAgICAgICAgICAgICAgICBpZiAocHJpbWFyeV9yZW5kZXJfdGFyZ2V0X2lzX3A4KG15RGV2aWNlKSkgYWxwaGEgPSBEREJsdEZ4LT51NS5kd0ZpbGxDb2xvciA8PCAyNDsKICAgICAgICAgICAgICAgIGVsc2UgYWxwaGEgPSAweEZGMDAwMDAwOwoKICAgICAgICAgICAgICAgIGlmIChUaGlzLT5wYWxldHRlKSB7CiAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAoYWxwaGEgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKFRoaXMtPnBhbGV0dGUtPnBhbGVudHNbRERCbHRGeC0+dTUuZHdGaWxsQ29sb3JdLnBlUmVkIDw8IDE2KSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoVGhpcy0+cGFsZXR0ZS0+cGFsZW50c1tEREJsdEZ4LT51NS5kd0ZpbGxDb2xvcl0ucGVHcmVlbiA8PCA4KSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoVGhpcy0+cGFsZXR0ZS0+cGFsZW50c1tEREJsdEZ4LT51NS5kd0ZpbGxDb2xvcl0ucGVCbHVlKSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGNvbG9yID0gYWxwaGE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUjVHNkI1KSB7CiAgICAgICAgICAgICAgICBpZiAoRERCbHRGeC0+dTUuZHdGaWxsQ29sb3IgPT0gMHhGRkZGKSB7CiAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAweEZGRkZGRkZGOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICgoMHhGRjAwMDAwMCkgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKChEREJsdEZ4LT51NS5kd0ZpbGxDb2xvciAmIDB4RjgwMCkgPDwgOCkgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKChEREJsdEZ4LT51NS5kd0ZpbGxDb2xvciAmIDB4MDdFMCkgPDwgNSkgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKChEREJsdEZ4LT51NS5kd0ZpbGxDb2xvciAmIDB4MDAxRikgPDwgMykpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9SOEc4QjgpIHx8CiAgICAgICAgICAgICAgICAgICAgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX1g4UjhHOEI4KSApIHsKICAgICAgICAgICAgICAgIGNvbG9yID0gMHhGRjAwMDAwMCB8IEREQmx0RngtPnU1LmR3RmlsbENvbG9yOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0E4UjhHOEI4KSB7CiAgICAgICAgICAgICAgICBjb2xvciA9IEREQmx0RngtPnU1LmR3RmlsbENvbG9yOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgRVJSKCJXcm9uZyBzdXJmYWNlIHR5cGUgZm9yIEJMVCBvdmVycmlkZShGb3JtYXQgZG9lc24ndCBtYXRjaCkgIVxuIik7CiAgICAgICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgVFJBQ0UoIiglcCkgZXhlY3V0aW5nIFJlbmRlciBUYXJnZXQgb3ZlcnJpZGUsIGNvbG9yID0gJXhcbiIsIFRoaXMsIGNvbG9yKTsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX0NsZWFyU3VyZmFjZShteURldmljZSwgVGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAvKiBOdW1iZXIgb2YgcmVjdGFuZ2xlcyAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZyZWN0LCBXSU5FRDNEQ0xFQVJfVEFSR0VULCBjb2xvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLjAgLyogWiAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIFN0ZW5jaWwgKi8pOwogICAgICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgICAgICB9CiAgICB9CgogICAgLyogRGVmYXVsdDogRmFsbCBiYWNrIHRvIHRoZSBnZW5lcmljIGJsdC4gTm90IGFuIGVycm9yLCBhIFRSQUNFIGlzIGVub3VnaCAqLwogICAgVFJBQ0UoIkRpZG4ndCBmaW5kIGFueSB1c2FibGUgcmVuZGVyIHRhcmdldCBzZXR1cCBmb3IgaHcgYmxpdCwgZmFsbGluZyBiYWNrIHRvIHNvZnR3YXJlXG4iKTsKICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9CbHRaKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMsIFJFQ1QgKkRlc3RSZWN0LCBJV2luZUQzRFN1cmZhY2UgKlNyY1N1cmZhY2UsIFJFQ1QgKlNyY1JlY3QsIERXT1JEIEZsYWdzLCBXSU5FRERCTFRGWCAqRERCbHRGeCkKewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpteURldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICBmbG9hdCBkZXB0aDsKCiAgICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfREVQVEhGSUxMKSB7CiAgICAgICAgc3dpdGNoKFRoaXMtPnJlc291cmNlLmZvcm1hdCkgewogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfRDE2OgogICAgICAgICAgICAgICAgZGVwdGggPSAoZmxvYXQpIEREQmx0RngtPnU1LmR3RmlsbERlcHRoIC8gKGZsb2F0KSAweDAwMDBmZmZmOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9EMTVTMToKICAgICAgICAgICAgICAgIGRlcHRoID0gKGZsb2F0KSBEREJsdEZ4LT51NS5kd0ZpbGxEZXB0aCAvIChmbG9hdCkgMHgwMDAwZmZmZTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfRDI0Uzg6CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZNVF9EMjRYODoKICAgICAgICAgICAgICAgIGRlcHRoID0gKGZsb2F0KSBEREJsdEZ4LT51NS5kd0ZpbGxEZXB0aCAvIChmbG9hdCkgMHgwMGZmZmZmZjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFdJTkVEM0RGTVRfRDMyOgogICAgICAgICAgICAgICAgZGVwdGggPSAoZmxvYXQpIEREQmx0RngtPnU1LmR3RmlsbERlcHRoIC8gKGZsb2F0KSAweGZmZmZmZmZmOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBkZXB0aCA9IDAuMDsKICAgICAgICAgICAgICAgIEVSUigiVW5leHBlY3RlZCBmb3JtYXQgZm9yIGRlcHRoIGZpbGw6ICVzXG4iLCBkZWJ1Z19kM2Rmb3JtYXQoVGhpcy0+cmVzb3VyY2UuZm9ybWF0KSk7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gSVdpbmVEM0REZXZpY2VfQ2xlYXIoKElXaW5lRDNERGV2aWNlICopIG15RGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXN0UmVjdCA9PSBOVUxMID8gMCA6IDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChXSU5FRDNEUkVDVCAqKSBEZXN0UmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRENMRUFSX1pCVUZGRVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MDAwMDAwMDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDAwMDAwMDAwKTsKICAgIH0KCiAgICBGSVhNRSgiKCVwKTogVW5zdXBwIGRlcHRoc3RlbmNpbCBibGl0XG4iLCBUaGlzKTsKICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9CbHQoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgUkVDVCAqRGVzdFJlY3QsIElXaW5lRDNEU3VyZmFjZSAqU3JjU3VyZmFjZSwgUkVDVCAqU3JjUmVjdCwgRFdPUkQgRmxhZ3MsIFdJTkVEREJMVEZYICpEREJsdEZ4LCBXSU5FRDNEVEVYVFVSRUZJTFRFUlRZUEUgRmlsdGVyKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlNyYyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFNyY1N1cmZhY2U7CiAgICBJV2luZUQzRERldmljZUltcGwgKm15RGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIFRSQUNFKCIoJXApLT4oJXAsJXAsJXAsJXgsJXApXG4iLCBUaGlzLCBEZXN0UmVjdCwgU3JjU3VyZmFjZSwgU3JjUmVjdCwgRmxhZ3MsIEREQmx0RngpOwogICAgVFJBQ0UoIiglcCk6IFVzYWdlIGlzICVzXG4iLCBUaGlzLCBkZWJ1Z19kM2R1c2FnZShUaGlzLT5yZXNvdXJjZS51c2FnZSkpOwoKICAgIGlmICggKFRoaXMtPkZsYWdzICYgU0ZMQUdfTE9DS0VEKSB8fCAoKFNyYyAhPSBOVUxMKSAmJiAoU3JjLT5GbGFncyAmIFNGTEFHX0xPQ0tFRCkpKQogICAgewogICAgICAgIFdBUk4oIiBTdXJmYWNlIGlzIGJ1c3ksIHJldHVybmluZyBEREVSUl9TVVJGQUNFQlVTWVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEREVSUl9TVVJGQUNFQlVTWTsKICAgIH0KCiAgICAvKiBBY2Nlc3NpbmcgdGhlIGRlcHRoIHN0ZW5jaWwgaXMgc3VwcG9zZWQgdG8gZmFpbCBiZXR3ZWVuIGEgQmVnaW5TY2VuZSBhbmQgRW5kU2NlbmUgcGFpciwKICAgICAqIGV4Y2VwdCBkZXB0aCBibGl0cywgd2hpY2ggc2VlbSB0byB3b3JrCiAgICAgKi8KICAgIGlmKGlmYWNlID09IG15RGV2aWNlLT5zdGVuY2lsQnVmZmVyVGFyZ2V0IHx8IChTcmNTdXJmYWNlICYmIFNyY1N1cmZhY2UgPT0gbXlEZXZpY2UtPnN0ZW5jaWxCdWZmZXJUYXJnZXQpKSB7CiAgICAgICAgaWYobXlEZXZpY2UtPmluU2NlbmUgJiYgIShGbGFncyAmIFdJTkVEREJMVF9ERVBUSEZJTEwpKSB7CiAgICAgICAgICAgIFRSQUNFKCJBdHRlbXB0IHRvIGFjY2VzcyB0aGUgZGVwdGggc3RlbmNpbCBzdXJmYWNlIGluIGEgQmVnaW5TY2VuZSAvIEVuZFNjZW5lIHBhaXIsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfSBlbHNlIGlmKElXaW5lRDNEU3VyZmFjZUltcGxfQmx0WihUaGlzLCBEZXN0UmVjdCwgU3JjU3VyZmFjZSwgU3JjUmVjdCwgRmxhZ3MsIEREQmx0RngpID09IFdJTkVEM0RfT0spIHsKICAgICAgICAgICAgVFJBQ0UoIlogQmxpdCBvdmVycmlkZSBoYW5kbGVkIHRoZSBibGl0XG4iKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFNwZWNpYWwgY2FzZXMgZm9yIFJlbmRlclRhcmdldHMgKi8KICAgIGlmKCAoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSB8fAogICAgICAgICggU3JjICYmIChTcmMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgKSkgewogICAgICAgIGlmKElXaW5lRDNEU3VyZmFjZUltcGxfQmx0T3ZlcnJpZGUoVGhpcywgRGVzdFJlY3QsIFNyY1N1cmZhY2UsIFNyY1JlY3QsIEZsYWdzLCBEREJsdEZ4LCBGaWx0ZXIpID09IFdJTkVEM0RfT0spIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIC8qIEZvciB0aGUgcmVzdCBjYWxsIHRoZSBYMTEgc3VyZmFjZSBpbXBsZW1lbnRhdGlvbi4KICAgICAqIEZvciBSZW5kZXJUYXJnZXRzIHRoaXMgc2hvdWxkIGJlIGltcGxlbWVudGVkIE9wZW5HTCBhY2NlbGVyYXRlZCBpbiBCbHRPdmVycmlkZSwKICAgICAqIG90aGVyIEJsdHMgYXJlIHJhdGhlciByYXJlCiAgICAgKi8KICAgIHJldHVybiBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9CbHQoaWZhY2UsIERlc3RSZWN0LCBTcmNTdXJmYWNlLCBTcmNSZWN0LCBGbGFncywgRERCbHRGeCwgRmlsdGVyKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9CbHRGYXN0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIERXT1JEIGRzdHgsIERXT1JEIGRzdHksIElXaW5lRDNEU3VyZmFjZSAqU291cmNlLCBSRUNUICpyc3JjLCBEV09SRCB0cmFucykgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqc3JjSW1wbCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFNvdXJjZTsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqbXlEZXZpY2UgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgVFJBQ0UoIiglcCktPiglZCwgJWQsICVwLCAlcCwgJTA4eFxuIiwgaWZhY2UsIGRzdHgsIGRzdHksIFNvdXJjZSwgcnNyYywgdHJhbnMpOwoKICAgIGlmICggKFRoaXMtPkZsYWdzICYgU0ZMQUdfTE9DS0VEKSB8fCAoKHNyY0ltcGwgIT0gTlVMTCkgJiYgKHNyY0ltcGwtPkZsYWdzICYgU0ZMQUdfTE9DS0VEKSkpCiAgICB7CiAgICAgICAgV0FSTigiIFN1cmZhY2UgaXMgYnVzeSwgcmV0dXJuaW5nIERERVJSX1NVUkZBQ0VCVVNZXG4iKTsKICAgICAgICByZXR1cm4gV0lORURERVJSX1NVUkZBQ0VCVVNZOwogICAgfQoKICAgIGlmKG15RGV2aWNlLT5pblNjZW5lICYmCiAgICAgICAoaWZhY2UgPT0gbXlEZXZpY2UtPnN0ZW5jaWxCdWZmZXJUYXJnZXQgfHwKICAgICAgIChTb3VyY2UgJiYgU291cmNlID09IG15RGV2aWNlLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KSkpIHsKICAgICAgICBUUkFDRSgiQXR0ZW1wdCB0byBhY2Nlc3MgdGhlIGRlcHRoIHN0ZW5jaWwgc3VyZmFjZSBpbiBhIEJlZ2luU2NlbmUgLyBFbmRTY2VuZSBwYWlyLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogU3BlY2lhbCBjYXNlcyBmb3IgUmVuZGVyVGFyZ2V0cyAqLwogICAgaWYoIChUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpIHx8CiAgICAgICAgKCBzcmNJbXBsICYmIChzcmNJbXBsLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpICkpIHsKCiAgICAgICAgUkVDVCBTcmNSZWN0LCBEc3RSZWN0OwogICAgICAgIERXT1JEIEZsYWdzPTA7CgogICAgICAgIGlmKHJzcmMpIHsKICAgICAgICAgICAgU3JjUmVjdC5sZWZ0ID0gcnNyYy0+bGVmdDsKICAgICAgICAgICAgU3JjUmVjdC50b3A9IHJzcmMtPnRvcDsKICAgICAgICAgICAgU3JjUmVjdC5ib3R0b20gPSByc3JjLT5ib3R0b207CiAgICAgICAgICAgIFNyY1JlY3QucmlnaHQgPSByc3JjLT5yaWdodDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBTcmNSZWN0LmxlZnQgPSAwOwogICAgICAgICAgICBTcmNSZWN0LnRvcCA9IDA7CiAgICAgICAgICAgIFNyY1JlY3QucmlnaHQgPSBzcmNJbXBsLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICAgICAgU3JjUmVjdC5ib3R0b20gPSBzcmNJbXBsLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgfQoKICAgICAgICBEc3RSZWN0LmxlZnQgPSBkc3R4OwogICAgICAgIERzdFJlY3QudG9wPWRzdHk7CiAgICAgICAgRHN0UmVjdC5yaWdodCA9IGRzdHggKyBTcmNSZWN0LnJpZ2h0IC0gU3JjUmVjdC5sZWZ0OwogICAgICAgIERzdFJlY3QuYm90dG9tID0gZHN0eSArIFNyY1JlY3QuYm90dG9tIC0gU3JjUmVjdC50b3A7CgogICAgICAgIC8qIENvbnZlcnQgQmx0RmFzdCBmbGFncyBpbnRvIEJ0bCBvbmVzIGJlY2F1c2UgaXQgaXMgY2FsbGVkIGZyb20gU3VyZmFjZUltcGxfQmx0IGFzIHdlbGwgKi8KICAgICAgICBpZih0cmFucyAmIFdJTkVEREJMVEZBU1RfU1JDQ09MT1JLRVkpCiAgICAgICAgICAgIEZsYWdzIHw9IFdJTkVEREJMVF9LRVlTUkM7CiAgICAgICAgaWYodHJhbnMgJiBXSU5FRERCTFRGQVNUX0RFU1RDT0xPUktFWSkKICAgICAgICAgICAgRmxhZ3MgfD0gV0lORUREQkxUX0tFWURFU1Q7CiAgICAgICAgaWYodHJhbnMgJiBXSU5FRERCTFRGQVNUX1dBSVQpCiAgICAgICAgICAgIEZsYWdzIHw9IFdJTkVEREJMVF9XQUlUOwogICAgICAgIGlmKHRyYW5zICYgV0lORUREQkxURkFTVF9ET05PVFdBSVQpCiAgICAgICAgICAgIEZsYWdzIHw9IFdJTkVEREJMVF9ET05PVFdBSVQ7CgogICAgICAgIGlmKElXaW5lRDNEU3VyZmFjZUltcGxfQmx0T3ZlcnJpZGUoVGhpcywgJkRzdFJlY3QsIFNvdXJjZSwgJlNyY1JlY3QsIEZsYWdzLCBOVUxMLCBXSU5FRDNEVEVYRl9QT0lOVCkgPT0gV0lORUQzRF9PSykgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgoKICAgIHJldHVybiBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9CbHRGYXN0KGlmYWNlLCBkc3R4LCBkc3R5LCBTb3VyY2UsIHJzcmMsIHRyYW5zKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZWFsaXplUGFsZXR0ZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBSR0JRVUFEIGNvbFsyNTZdOwogICAgSVdpbmVEM0RQYWxldHRlSW1wbCAqcGFsID0gVGhpcy0+cGFsZXR0ZTsKICAgIHVuc2lnbmVkIGludCBuOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIGlmICghcGFsKSByZXR1cm4gV0lORUQzRF9PSzsKCiAgICBpZihUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9QOCB8fAogICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfQThQOCkKICAgIHsKICAgICAgICBpbnQgYnBwOwogICAgICAgIEdMZW51bSBmb3JtYXQsIGludGVybmFsLCB0eXBlOwogICAgICAgIENPTlZFUlRfVFlQRVMgY29udmVydDsKCiAgICAgICAgLyogQ2hlY2sgaWYgd2UgYXJlIHVzaW5nIGEgUlRMIG1vZGUgd2hpY2ggdXNlcyB0ZXh0dXJpbmcgZm9yIHVwbG9hZHMgKi8KICAgICAgICBCT09MIHVzZV90ZXh0dXJlID0gKHdpbmVkM2Rfc2V0dGluZ3MucmVuZGVydGFyZ2V0bG9ja19tb2RlID09IFJUTF9SRUFEVEVYIHx8IHdpbmVkM2Rfc2V0dGluZ3MucmVuZGVydGFyZ2V0bG9ja19tb2RlID09IFJUTF9URVhURVgpOwoKICAgICAgICAvKiBDaGVjayBpZiB3ZSBoYXZlIGhhcmR3YXJlIHBhbGV0dGUgY29udmVyc2lvbiBpZiB3ZSBoYXZlIGNvbnZlcnQgaXMgc2V0IHRvIE5PX0NPTlZFUlNJT04gKi8KICAgICAgICBkM2RmbXRfZ2V0X2NvbnYoVGhpcywgVFJVRSwgdXNlX3RleHR1cmUsICZmb3JtYXQsICZpbnRlcm5hbCwgJnR5cGUsICZjb252ZXJ0LCAmYnBwLCBUaGlzLT5zcmdiKTsKCiAgICAgICAgaWYoKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgJiYgKGNvbnZlcnQgPT0gTk9fQ09OVkVSU0lPTikpCiAgICAgICAgewogICAgICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgICAgICBpZiAoVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSA9PSAwKSB7CiAgICAgICAgICAgICAgICBnbEdlblRleHR1cmVzKDEsICZUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEdlblRleHR1cmVzIik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZ2xCaW5kVGV4dHVyZShUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRUZXh0dXJlKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0LCBUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKSIpOwogICAgICAgICAgICBMRUFWRV9HTCgpOwoKICAgICAgICAgICAgLyogTWFrZSBzdXJlIHRoZSB0ZXh0dXJlIGlzIHVwIHRvIGRhdGUuIFRoaXMgY2FsbCBkb2Vzbid0IGRvIGFueXRoaW5nIGlmIHRoZSB0ZXh0dXJlIGlzIGFscmVhZHkgdXAgdG8gZGF0ZS4gKi8KICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvYWRMb2NhdGlvbihpZmFjZSwgU0ZMQUdfSU5URVhUVVJFLCBOVUxMKTsKCiAgICAgICAgICAgIC8qIFdlIHdhbnQgdG8gZm9yY2UgYSBwYWxldHRlIHJlZnJlc2gsIHNvIG1hcmsgdGhlIGRyYXdhYmxlIGFzIG5vdCBiZWluZyB1cCB0byBkYXRlICovCiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9Nb2RpZnlMb2NhdGlvbihpZmFjZSwgU0ZMQUdfSU5EUkFXQUJMRSwgRkFMU0UpOwoKICAgICAgICAgICAgLyogUmUtdXBsb2FkIHRoZSBwYWxldHRlICovCiAgICAgICAgICAgIGQzZGZtdF9wOF91cGxvYWRfcGFsZXR0ZShpZmFjZSwgY29udmVydCk7CgogICAgICAgICAgICAvKiBXaXRob3V0IHRoaXMgc29tZSBwYWxldHRlIHVwZGF0ZXMgYXJlIG1pc3NlZC4gVGhpcyBhdCBsZWFzdCBoYXBwZW5zIG9uIE52aWRpYSBkcml2ZXJzIGJ1dAogICAgICAgICAgICAgKiBpdCB3b3JrcyBmaW5lIHVzaW5nIE1lc2EuICovCiAgICAgICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgICAgIGdsRmx1c2goKTsKICAgICAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZighKFRoaXMtPkZsYWdzICYgU0ZMQUdfSU5TWVNNRU0pKSB7CiAgICAgICAgICAgICAgICBUUkFDRSgiUGFsZXR0ZSBjaGFuZ2VkIHdpdGggc3VyZmFjZSB0aGF0IGRvZXMgbm90IGhhdmUgYW4gdXAgdG8gZGF0ZSBzeXN0ZW0gbWVtb3J5IGNvcHlcbiIpOwogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvYWRMb2NhdGlvbihpZmFjZSwgU0ZMQUdfSU5TWVNNRU0sIE5VTEwpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFRSQUNFKCJEaXJ0aWZ5aW5nIHN1cmZhY2VcbiIpOwogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfTW9kaWZ5TG9jYXRpb24oaWZhY2UsIFNGTEFHX0lOU1lTTUVNLCBUUlVFKTsKICAgICAgICB9CiAgICB9CgogICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19ESUJTRUNUSU9OKSB7CiAgICAgICAgVFJBQ0UoIiglcCk6IFVwZGF0aW5nIHRoZSBoZGMncyBwYWxldHRlXG4iLCBUaGlzKTsKICAgICAgICBmb3IgKG49MDsgbjwyNTY7IG4rKykgewogICAgICAgICAgICBjb2xbbl0ucmdiUmVkICAgPSBwYWwtPnBhbGVudHNbbl0ucGVSZWQ7CiAgICAgICAgICAgIGNvbFtuXS5yZ2JHcmVlbiA9IHBhbC0+cGFsZW50c1tuXS5wZUdyZWVuOwogICAgICAgICAgICBjb2xbbl0ucmdiQmx1ZSAgPSBwYWwtPnBhbGVudHNbbl0ucGVCbHVlOwogICAgICAgICAgICBjb2xbbl0ucmdiUmVzZXJ2ZWQgPSAwOwogICAgICAgIH0KICAgICAgICBTZXRESUJDb2xvclRhYmxlKFRoaXMtPmhEQywgMCwgMjU2LCBjb2wpOwogICAgfQoKICAgIC8qIFByb3BhZ2F0ZSB0aGUgY2hhbmdlcyB0byB0aGUgZHJhd2FibGUgd2hlbiB3ZSBoYXZlIGEgcGFsZXR0ZS4gKi8KICAgIGlmKFRoaXMtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkKICAgICAgICBJV2luZUQzRFN1cmZhY2VfTG9hZExvY2F0aW9uKGlmYWNlLCBTRkxBR19JTkRSQVdBQkxFLCBOVUxMKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfUHJpdmF0ZVNldHVwKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UpIHsKICAgIC8qKiBDaGVjayBhZ2FpbnN0IHRoZSBtYXhpbXVtIHRleHR1cmUgc2l6ZXMgc3VwcG9ydGVkIGJ5IHRoZSB2aWRlbyBjYXJkICoqLwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgdW5zaWduZWQgaW50IHBvdzJXaWR0aCwgcG93MkhlaWdodDsKICAgIGNvbnN0IEdsUGl4ZWxGb3JtYXREZXNjICpnbERlc2M7CgogICAgZ2V0Rm9ybWF0RGVzY0VudHJ5KFRoaXMtPnJlc291cmNlLmZvcm1hdCwgJkdMSU5GT19MT0NBVElPTiwgJmdsRGVzYyk7CiAgICAvKiBTZXR1cCBzb21lIGdsZm9ybWF0IGRlZmF1bHRzICovCiAgICBUaGlzLT5nbERlc2NyaXB0aW9uLmdsRm9ybWF0ICAgICAgICAgPSBnbERlc2MtPmdsRm9ybWF0OwogICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdEludGVybmFsID0gZ2xEZXNjLT5nbEludGVybmFsOwogICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi5nbFR5cGUgICAgICAgICAgID0gZ2xEZXNjLT5nbFR5cGU7CgogICAgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSAgICAgID0gMDsKICAgIFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0ICAgICAgICAgICA9IEdMX1RFWFRVUkVfMkQ7CgogICAgLyogTm9uLXBvd2VyMiBzdXBwb3J0ICovCiAgICBpZiAoR0xfU1VQUE9SVChBUkJfVEVYVFVSRV9OT05fUE9XRVJfT0ZfVFdPKSkgewogICAgICAgIHBvdzJXaWR0aCA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgIHBvdzJIZWlnaHQgPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICB9IGVsc2UgewogICAgICAgIC8qIEZpbmQgdGhlIG5lYXJlc3QgcG93MiBtYXRjaCAqLwogICAgICAgIHBvdzJXaWR0aCA9IHBvdzJIZWlnaHQgPSAxOwogICAgICAgIHdoaWxlIChwb3cyV2lkdGggPCBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCkgcG93MldpZHRoIDw8PSAxOwogICAgICAgIHdoaWxlIChwb3cySGVpZ2h0IDwgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KSBwb3cySGVpZ2h0IDw8PSAxOwogICAgfQogICAgVGhpcy0+cG93MldpZHRoICA9IHBvdzJXaWR0aDsKICAgIFRoaXMtPnBvdzJIZWlnaHQgPSBwb3cySGVpZ2h0OwoKICAgIGlmIChwb3cyV2lkdGggPiBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCB8fCBwb3cySGVpZ2h0ID4gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KSB7CiAgICAgICAgV0lORUQzREZPUk1BVCBGb3JtYXQgPSBUaGlzLT5yZXNvdXJjZS5mb3JtYXQ7CiAgICAgICAgLyoqIFRPRE86IGFkZCBzdXBwb3J0IGZvciBub24gcG93ZXIgdHdvIGNvbXByZXNzZWQgdGV4dHVyZXMgKiovCiAgICAgICAgaWYgKEZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEgfHwgRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fCBGb3JtYXQgPT0gV0lORUQzREZNVF9EWFQzCiAgICAgICAgICAgIHx8IEZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDQgfHwgRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNSkgewogICAgICAgICAgICBGSVhNRSgiKCVwKSBDb21wcmVzc2VkIG5vbi1wb3dlci10d28gdGV4dHVyZXMgYXJlIG5vdCBzdXBwb3J0ZWQgdyglZCkgaCglZClcbiIsCiAgICAgICAgICAgICAgICAgIFRoaXMsIFRoaXMtPmN1cnJlbnREZXNjLldpZHRoLCBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpOwogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9OT1RBVkFJTEFCTEU7CiAgICAgICAgfQogICAgfQoKICAgIGlmKHBvdzJXaWR0aCAhPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCB8fAogICAgICAgcG93MkhlaWdodCAhPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpIHsKICAgICAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19OT05QT1cyOwogICAgfQoKICAgIFRSQUNFKCIlcFxuIiwgVGhpcyk7CiAgICBpZiAoKFRoaXMtPnBvdzJXaWR0aCA+IEdMX0xJTUlUUyh0ZXh0dXJlX3NpemUpIHx8IFRoaXMtPnBvdzJIZWlnaHQgPiBHTF9MSU1JVFModGV4dHVyZV9zaXplKSkgJiYgIShUaGlzLT5yZXNvdXJjZS51c2FnZSAmIChXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUIHwgV0lORUQzRFVTQUdFX0RFUFRIU1RFTkNJTCkpKSB7CiAgICAgICAgLyogb25lIG9mIHRocmVlIG9wdGlvbnMKICAgICAgICAxOiBEbyB0aGUgc2FtZSBhcyB3ZSBkbyB3aXRoIG5vbnBvdyAyIGFuZCBzY2FsZSB0aGUgdGV4dHVyZSwgKGFueSB0ZXh0dXJlIG9wcyB3b3VsZCByZXF1aXJlIHRoZSB0ZXh0dXJlIHRvIGJlIHNjYWxlZCB3aGljaCBpcyBwb3RlbnRpYWxseSBzbG93KQogICAgICAgIDI6IFNldCB0aGUgdGV4dHVyZSB0byB0aGUgbWF4aW11bSBzaXplIChiYWQgaWRlYSkKICAgICAgICAzOiAgICBXQVJOIGFuZCByZXR1cm4gV0lORUQzREVSUl9OT1RBVkFJTEFCTEU7CiAgICAgICAgNDogQ3JlYXRlIHRoZSBzdXJmYWNlLCBidXQgYWxsb3cgaXQgdG8gYmUgdXNlZCBvbmx5IGZvciBEaXJlY3REcmF3IEJsdHMuIFNvbWUgYXBwcyhlLmcuIFN3YXQgMykgY3JlYXRlIHRleHR1cmVzIHdpdGggYSBIZWlnaHQgb2YgMTYgYW5kIGEgV2lkdGggPiAzMDAwIGFuZCBibHQgMTZ4MTYgbGV0dGVyIGFyZWFzIGZyb20gdGhlbSB0byB0aGUgcmVuZGVyIHRhcmdldC4KICAgICAgICAqLwogICAgICAgIFdBUk4oIiglcCkgQ3JlYXRpbmcgYW4gb3ZlcnNpemVkIHN1cmZhY2VcbiIsIFRoaXMpOwogICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX09WRVJTSVpFOwoKICAgICAgICAvKiBUaGlzIHdpbGwgYmUgaW5pdGlhbGl6ZWQgb24gdGhlIGZpcnN0IGJsdCAqLwogICAgICAgIFRoaXMtPmdsUmVjdC5sZWZ0ID0gMDsKICAgICAgICBUaGlzLT5nbFJlY3QudG9wID0gMDsKICAgICAgICBUaGlzLT5nbFJlY3QucmlnaHQgPSAwOwogICAgICAgIFRoaXMtPmdsUmVjdC5ib3R0b20gPSAwOwogICAgfSBlbHNlIHsKICAgICAgICAvKiBDaGVjayB0aGlzIGFmdGVyIHRoZSBvdmVyc2l6ZSBjaGVjayAtIGRvIG5vdCBtYWtlIGFuIG92ZXJzaXplZCBzdXJmYWNlIGEgdGV4dHVyZV9yZWN0YW5nbGUgb25lLgogICAgICAgICAgIFNlY29uZCBhbHNvIGRvbid0IHVzZSBBUkJfVEVYVFVSRV9SRUNUQU5HTEUgaW4gY2FzZSB0aGUgc3VyZmFjZSBmb3JtYXQgaXMgUDggYW5kIEVYVF9QQUxFVFRFRF9URVhUVVJFCiAgICAgICAgICAgaXMgdXNlZCBpbiBjb21iaW5hdGlvbiB3aXRoIHRleHR1cmUgdXBsb2FkcyAoUlRMX1JFQURURVgvUlRMX1RFWFRFWCkuIFRoZSByZWFzb24gaXMgdGhhdCBFWFRfUEFMRVRURURfVEVYVFVSRQogICAgICAgICAgIGRvZXNuJ3Qgd29yayBpbiBjb21iaW5hdGlvbiB3aXRoIEFSQl9URVhUVVJFX1JFQ1RBTkdMRS4KICAgICAgICAqLwogICAgICAgIGlmKFRoaXMtPkZsYWdzICYgU0ZMQUdfTk9OUE9XMiAmJiBHTF9TVVBQT1JUKEFSQl9URVhUVVJFX1JFQ1RBTkdMRSkgJiYKICAgICAgICAgICAhKChUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9QOCkgJiYgR0xfU1VQUE9SVChFWFRfUEFMRVRURURfVEVYVFVSRSkgJiYgKHdpbmVkM2Rfc2V0dGluZ3MucmVuZGVydGFyZ2V0bG9ja19tb2RlID09IFJUTF9SRUFEVEVYIHx8IHdpbmVkM2Rfc2V0dGluZ3MucmVuZGVydGFyZ2V0bG9ja19tb2RlID09IFJUTF9URVhURVgpKSkKICAgICAgICB7CiAgICAgICAgICAgIFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0ID0gR0xfVEVYVFVSRV9SRUNUQU5HTEVfQVJCOwogICAgICAgICAgICBUaGlzLT5wb3cyV2lkdGggID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgICAgIFRoaXMtPnBvdzJIZWlnaHQgPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgICAgIFRoaXMtPkZsYWdzICY9IH4oU0ZMQUdfTk9OUE9XMiB8IFNGTEFHX05PUk1DT09SRCk7CiAgICAgICAgfQoKICAgICAgICAvKiBObyBvdmVyc2l6ZSwgZ2wgcmVjdCBpcyB0aGUgZnVsbCB0ZXh0dXJlIHNpemUgKi8KICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfT1ZFUlNJWkU7CiAgICAgICAgVGhpcy0+Z2xSZWN0LmxlZnQgPSAwOwogICAgICAgIFRoaXMtPmdsUmVjdC50b3AgPSAwOwogICAgICAgIFRoaXMtPmdsUmVjdC5yaWdodCA9IFRoaXMtPnBvdzJXaWR0aDsKICAgICAgICBUaGlzLT5nbFJlY3QuYm90dG9tID0gVGhpcy0+cG93MkhlaWdodDsKICAgIH0KCiAgICBpZihUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpIHsKICAgICAgICBzd2l0Y2god2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUpIHsKICAgICAgICAgICAgY2FzZSBPUk1fRkJPOiAgICAgICAgVGhpcy0+Z2V0X2RyYXdhYmxlX3NpemUgPSBnZXRfZHJhd2FibGVfc2l6ZV9mYm87ICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBPUk1fUEJVRkZFUjogICAgVGhpcy0+Z2V0X2RyYXdhYmxlX3NpemUgPSBnZXRfZHJhd2FibGVfc2l6ZV9wYnVmZmVyOyAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBPUk1fQkFDS0JVRkZFUjogVGhpcy0+Z2V0X2RyYXdhYmxlX3NpemUgPSBnZXRfZHJhd2FibGVfc2l6ZV9iYWNrYnVmZmVyOyBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgVGhpcy0+RmxhZ3MgfD0gU0ZMQUdfSU5TWVNNRU07CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX01vZGlmeUxvY2F0aW9uKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIERXT1JEIGZsYWcsIEJPT0wgcGVyc2lzdGVudCkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RCYXNlVGV4dHVyZSAqdGV4dHVyZTsKCiAgICBUUkFDRSgiKCVwKS0+KCVzLCAlcylcbiIsIGlmYWNlLAogICAgICAgICAgZmxhZyA9PSBTRkxBR19JTlNZU01FTSA/ICJTRkxBR19JTlNZU01FTSIgOiBmbGFnID09IFNGTEFHX0lORFJBV0FCTEUgPyAiU0ZMQUdfSU5EUkFXQUJMRSIgOiAiU0ZMQUdfSU5URVhUVVJFIiwKICAgICAgICAgIHBlcnNpc3RlbnQgPyAiVFJVRSIgOiAiRkFMU0UiKTsKCiAgICBpZiAod2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUgPT0gT1JNX0ZCTykgewogICAgICAgIElXaW5lRDNEU3dhcENoYWluICpzd2FwY2hhaW4gPSBOVUxMOwoKICAgICAgICBpZiAoU1VDQ0VFREVEKElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIoaWZhY2UsICZJSURfSVdpbmVEM0RTd2FwQ2hhaW4sICh2b2lkICoqKSZzd2FwY2hhaW4pKSkgewogICAgICAgICAgICBUUkFDRSgiU3VyZmFjZSAlcCBpcyBhbiBvbnNjcmVlbiBzdXJmYWNlXG4iLCBpZmFjZSk7CgogICAgICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKHN3YXBjaGFpbik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyogV2l0aCBPUk1fRkJPLCBTRkxBR19JTlRFWFRVUkUgYW5kIFNGTEFHX0lORFJBV0FCTEUgYXJlIHRoZSBzYW1lIGZvciBvZmZzY3JlZW4gdGFyZ2V0cy4gKi8KICAgICAgICAgICAgaWYgKGZsYWcgJiAoU0ZMQUdfSU5URVhUVVJFIHwgU0ZMQUdfSU5EUkFXQUJMRSkpIGZsYWcgfD0gKFNGTEFHX0lOVEVYVFVSRSB8IFNGTEFHX0lORFJBV0FCTEUpOwogICAgICAgIH0KICAgIH0KCiAgICBpZihwZXJzaXN0ZW50KSB7CiAgICAgICAgaWYoKFRoaXMtPkZsYWdzICYgU0ZMQUdfSU5URVhUVVJFKSAmJiAhKGZsYWcgJiBTRkxBR19JTlRFWFRVUkUpKSB7CiAgICAgICAgICAgIGlmIChJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKGlmYWNlLCAmSUlEX0lXaW5lRDNEQmFzZVRleHR1cmUsICh2b2lkICoqKSZ0ZXh0dXJlKSA9PSBXSU5FRDNEX09LKSB7CiAgICAgICAgICAgICAgICBUUkFDRSgiUGFzc2luZyB0byBjb250YWluZXJcbiIpOwogICAgICAgICAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9TZXREaXJ0eSh0ZXh0dXJlLCBUUlVFKTsKICAgICAgICAgICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUmVsZWFzZSh0ZXh0dXJlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfTE9DQVRJT05TOwogICAgICAgIFRoaXMtPkZsYWdzIHw9IGZsYWc7CiAgICB9IGVsc2UgewogICAgICAgIGlmKChUaGlzLT5GbGFncyAmIFNGTEFHX0lOVEVYVFVSRSkgJiYgKGZsYWcgJiBTRkxBR19JTlRFWFRVUkUpKSB7CiAgICAgICAgICAgIGlmIChJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKGlmYWNlLCAmSUlEX0lXaW5lRDNEQmFzZVRleHR1cmUsICh2b2lkICoqKSZ0ZXh0dXJlKSA9PSBXSU5FRDNEX09LKSB7CiAgICAgICAgICAgICAgICBUUkFDRSgiUGFzc2luZyB0byBjb250YWluZXJcbiIpOwogICAgICAgICAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9TZXREaXJ0eSh0ZXh0dXJlLCBUUlVFKTsKICAgICAgICAgICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUmVsZWFzZSh0ZXh0dXJlKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBUaGlzLT5GbGFncyAmPSB+ZmxhZzsKICAgIH0KfQoKc3RydWN0IGNvb3JkcyB7CiAgICBHTGZsb2F0IHgsIHksIHo7Cn07CgpzdGF0aWMgaW5saW5lIHZvaWQgc3VyZmFjZV9ibHRfdG9fZHJhd2FibGUoSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcywgY29uc3QgUkVDVCAqcmVjdF9pbikgewogICAgc3RydWN0IGNvb3JkcyBjb29yZHNbNF07CiAgICBSRUNUIHJlY3Q7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcGNoYWluID0gTlVMTDsKICAgIElXaW5lRDNEQmFzZVRleHR1cmUgKnRleHR1cmUgPSBOVUxMOwogICAgSFJFU1VMVCBocjsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqZGV2aWNlID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKCiAgICBpZihyZWN0X2luKSB7CiAgICAgICAgcmVjdCA9ICpyZWN0X2luOwogICAgfSBlbHNlIHsKICAgICAgICByZWN0LmxlZnQgPSAwOwogICAgICAgIHJlY3QudG9wID0gMDsKICAgICAgICByZWN0LnJpZ2h0ID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgcmVjdC5ib3R0b20gPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICB9CgogICAgQWN0aXZhdGVDb250ZXh0KGRldmljZSwgZGV2aWNlLT5yZW5kZXJfdGFyZ2V0c1swXSwgQ1RYVVNBR0VfQkxJVCk7CiAgICBFTlRFUl9HTCgpOwoKICAgIGlmKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0ID09IEdMX1RFWFRVUkVfUkVDVEFOR0xFX0FSQikgewogICAgICAgIGdsRW5hYmxlKEdMX1RFWFRVUkVfUkVDVEFOR0xFX0FSQik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlKEdMX1RFWFRVUkVfUkVDVEFOR0xFX0FSQikiKTsKICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfUkVDVEFOR0xFX0FSQiwgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgY2hlY2tHTGNhbGwoIkdMX1RFWFRVUkVfUkVDVEFOR0xFX0FSQiwgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSkiKTsKICAgICAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV9SRUNUQU5HTEVfQVJCLCBHTF9URVhUVVJFX01BR19GSUxURVIsIEdMX05FQVJFU1QpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleFBhcmFtZXRlcmkiKTsKICAgICAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV9SRUNUQU5HTEVfQVJCLCBHTF9URVhUVVJFX01JTl9GSUxURVIsIEdMX05FQVJFU1QpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleFBhcmFtZXRlcmkiKTsKCiAgICAgICAgY29vcmRzWzBdLnggPSByZWN0LmxlZnQ7CiAgICAgICAgY29vcmRzWzBdLnogPSAwOwoKICAgICAgICBjb29yZHNbMV0ueCA9IHJlY3QubGVmdDsKICAgICAgICBjb29yZHNbMV0ueiA9IDA7CgogICAgICAgIGNvb3Jkc1syXS54ID0gcmVjdC5yaWdodDsKICAgICAgICBjb29yZHNbMl0ueiA9IDA7CgogICAgICAgIGNvb3Jkc1szXS54ID0gcmVjdC5yaWdodDsKICAgICAgICBjb29yZHNbM10ueiA9IDA7CgogICAgICAgIGNvb3Jkc1swXS55ID0gcmVjdC50b3A7CiAgICAgICAgY29vcmRzWzFdLnkgPSByZWN0LmJvdHRvbTsKICAgICAgICBjb29yZHNbMl0ueSA9IHJlY3QuYm90dG9tOwogICAgICAgIGNvb3Jkc1szXS55ID0gcmVjdC50b3A7CiAgICB9IGVsc2UgaWYoVGhpcy0+Z2xEZXNjcmlwdGlvbi50YXJnZXQgPT0gR0xfVEVYVFVSRV8yRCkgewogICAgICAgIGdsRW5hYmxlKEdMX1RFWFRVUkVfMkQpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEVuYWJsZShHTF9URVhUVVJFXzJEKSIpOwogICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgY2hlY2tHTGNhbGwoIkdMX1RFWFRVUkVfMkQsIFRoaXMtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUpIik7CiAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfTUFHX0ZJTFRFUiwgR0xfTkVBUkVTVCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4UGFyYW1ldGVyaSIpOwogICAgICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01JTl9GSUxURVIsIEdMX05FQVJFU1QpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleFBhcmFtZXRlcmkiKTsKCiAgICAgICAgY29vcmRzWzBdLnggPSAoZmxvYXQpcmVjdC5sZWZ0ICAgLyBUaGlzLT5wb3cyV2lkdGg7CiAgICAgICAgY29vcmRzWzBdLnogPSAwOwoKICAgICAgICBjb29yZHNbMV0ueCA9IChmbG9hdClyZWN0LmxlZnQgICAvIFRoaXMtPnBvdzJXaWR0aDsKICAgICAgICBjb29yZHNbMV0ueiA9IDA7CgogICAgICAgIGNvb3Jkc1syXS54ID0gKGZsb2F0KXJlY3QucmlnaHQgIC8gVGhpcy0+cG93MldpZHRoOwogICAgICAgIGNvb3Jkc1syXS56ID0gMDsKCiAgICAgICAgY29vcmRzWzNdLnggPSAoZmxvYXQpcmVjdC5yaWdodCAgLyBUaGlzLT5wb3cyV2lkdGg7CiAgICAgICAgY29vcmRzWzNdLnogPSAwOwoKICAgICAgICBjb29yZHNbMF0ueSA9IChmbG9hdClyZWN0LnRvcCAgICAvIFRoaXMtPnBvdzJIZWlnaHQ7CiAgICAgICAgY29vcmRzWzFdLnkgPSAoZmxvYXQpcmVjdC5ib3R0b20gLyBUaGlzLT5wb3cySGVpZ2h0OwogICAgICAgIGNvb3Jkc1syXS55ID0gKGZsb2F0KXJlY3QuYm90dG9tIC8gVGhpcy0+cG93MkhlaWdodDsKICAgICAgICBjb29yZHNbM10ueSA9IChmbG9hdClyZWN0LnRvcCAgICAvIFRoaXMtPnBvdzJIZWlnaHQ7CiAgICB9IGVsc2UgewogICAgICAgIC8qIE11c3QgYmUgYSBjdWJlIG1hcCAqLwogICAgICAgIGdsRW5hYmxlKEdMX1RFWFRVUkVfQ1VCRV9NQVBfQVJCKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoR0xfVEVYVFVSRV9DVUJFX01BUF9BUkIpIik7CiAgICAgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFX0NVQkVfTUFQX0FSQiwgVGhpcy0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgY2hlY2tHTGNhbGwoIkdMX1RFWFRVUkVfQ1VCRV9NQVBfQVJCLCBUaGlzLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKSIpOwogICAgICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFX0NVQkVfTUFQX0FSQiwgR0xfVEVYVFVSRV9NQUdfRklMVEVSLCBHTF9ORUFSRVNUKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhQYXJhbWV0ZXJpIik7CiAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfQ1VCRV9NQVBfQVJCLCBHTF9URVhUVVJFX01JTl9GSUxURVIsIEdMX05FQVJFU1QpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleFBhcmFtZXRlcmkiKTsKCiAgICAgICAgc3dpdGNoKFRoaXMtPmdsRGVzY3JpcHRpb24udGFyZ2V0KSB7CiAgICAgICAgICAgIGNhc2UgR0xfVEVYVFVSRV9DVUJFX01BUF9QT1NJVElWRV9YOgogICAgICAgICAgICAgICAgY29vcmRzWzBdLnggPSAgMTsgICBjb29yZHNbMF0ueSA9IC0xOyAgIGNvb3Jkc1swXS56ID0gIDE7CiAgICAgICAgICAgICAgICBjb29yZHNbMV0ueCA9ICAxOyAgIGNvb3Jkc1sxXS55ID0gIDE7ICAgY29vcmRzWzFdLnogPSAgMTsKICAgICAgICAgICAgICAgIGNvb3Jkc1syXS54ID0gIDE7ICAgY29vcmRzWzJdLnkgPSAgMTsgICBjb29yZHNbMl0ueiA9IC0xOwogICAgICAgICAgICAgICAgY29vcmRzWzNdLnggPSAgMTsgICBjb29yZHNbM10ueSA9IC0xOyAgIGNvb3Jkc1szXS56ID0gLTE7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgR0xfVEVYVFVSRV9DVUJFX01BUF9ORUdBVElWRV9YOgogICAgICAgICAgICAgICAgY29vcmRzWzBdLnggPSAtMTsgICBjb29yZHNbMF0ueSA9IC0xOyAgIGNvb3Jkc1swXS56ID0gIDE7CiAgICAgICAgICAgICAgICBjb29yZHNbMV0ueCA9IC0xOyAgIGNvb3Jkc1sxXS55ID0gIDE7ICAgY29vcmRzWzFdLnogPSAgMTsKICAgICAgICAgICAgICAgIGNvb3Jkc1syXS54ID0gLTE7ICAgY29vcmRzWzJdLnkgPSAgMTsgICBjb29yZHNbMl0ueiA9IC0xOwogICAgICAgICAgICAgICAgY29vcmRzWzNdLnggPSAtMTsgICBjb29yZHNbM10ueSA9IC0xOyAgIGNvb3Jkc1szXS56ID0gLTE7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgR0xfVEVYVFVSRV9DVUJFX01BUF9QT1NJVElWRV9ZOgogICAgICAgICAgICAgICAgY29vcmRzWzBdLnggPSAtMTsgICBjb29yZHNbMF0ueSA9ICAxOyAgIGNvb3Jkc1swXS56ID0gIDE7CiAgICAgICAgICAgICAgICBjb29yZHNbMV0ueCA9ICAxOyAgIGNvb3Jkc1sxXS55ID0gIDE7ICAgY29vcmRzWzFdLnogPSAgMTsKICAgICAgICAgICAgICAgIGNvb3Jkc1syXS54ID0gIDE7ICAgY29vcmRzWzJdLnkgPSAgMTsgICBjb29yZHNbMl0ueiA9IC0xOwogICAgICAgICAgICAgICAgY29vcmRzWzNdLnggPSAtMTsgICBjb29yZHNbM10ueSA9ICAxOyAgIGNvb3Jkc1szXS56ID0gLTE7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgR0xfVEVYVFVSRV9DVUJFX01BUF9ORUdBVElWRV9ZOgogICAgICAgICAgICAgICAgY29vcmRzWzBdLnggPSAtMTsgICBjb29yZHNbMF0ueSA9IC0xOyAgIGNvb3Jkc1swXS56ID0gIDE7CiAgICAgICAgICAgICAgICBjb29yZHNbMV0ueCA9ICAxOyAgIGNvb3Jkc1sxXS55ID0gLTE7ICAgY29vcmRzWzFdLnogPSAgMTsKICAgICAgICAgICAgICAgIGNvb3Jkc1syXS54ID0gIDE7ICAgY29vcmRzWzJdLnkgPSAtMTsgICBjb29yZHNbMl0ueiA9IC0xOwogICAgICAgICAgICAgICAgY29vcmRzWzNdLnggPSAtMTsgICBjb29yZHNbM10ueSA9IC0xOyAgIGNvb3Jkc1szXS56ID0gLTE7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgR0xfVEVYVFVSRV9DVUJFX01BUF9QT1NJVElWRV9aOgogICAgICAgICAgICAgICAgY29vcmRzWzBdLnggPSAtMTsgICBjb29yZHNbMF0ueSA9IC0xOyAgIGNvb3Jkc1swXS56ID0gIDE7CiAgICAgICAgICAgICAgICBjb29yZHNbMV0ueCA9ICAxOyAgIGNvb3Jkc1sxXS55ID0gLTE7ICAgY29vcmRzWzFdLnogPSAgMTsKICAgICAgICAgICAgICAgIGNvb3Jkc1syXS54ID0gIDE7ICAgY29vcmRzWzJdLnkgPSAtMTsgICBjb29yZHNbMl0ueiA9ICAxOwogICAgICAgICAgICAgICAgY29vcmRzWzNdLnggPSAtMTsgICBjb29yZHNbM10ueSA9IC0xOyAgIGNvb3Jkc1szXS56ID0gIDE7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgR0xfVEVYVFVSRV9DVUJFX01BUF9ORUdBVElWRV9aOgogICAgICAgICAgICAgICAgY29vcmRzWzBdLnggPSAtMTsgICBjb29yZHNbMF0ueSA9IC0xOyAgIGNvb3Jkc1swXS56ID0gLTE7CiAgICAgICAgICAgICAgICBjb29yZHNbMV0ueCA9ICAxOyAgIGNvb3Jkc1sxXS55ID0gLTE7ICAgY29vcmRzWzFdLnogPSAtMTsKICAgICAgICAgICAgICAgIGNvb3Jkc1syXS54ID0gIDE7ICAgY29vcmRzWzJdLnkgPSAtMTsgICBjb29yZHNbMl0ueiA9IC0xOwogICAgICAgICAgICAgICAgY29vcmRzWzNdLnggPSAtMTsgICBjb29yZHNbM10ueSA9IC0xOyAgIGNvb3Jkc1szXS56ID0gLTE7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBFUlIoIlVuZXhwZWN0ZWQgdGV4dHVyZSB0YXJnZXRcbiIpOwogICAgICAgICAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgZ2xCZWdpbihHTF9RVUFEUyk7CiAgICBnbFRleENvb3JkM2Z2KCZjb29yZHNbMF0ueCk7CiAgICBnbFZlcnRleDJpKHJlY3QubGVmdCwgZGV2aWNlLT5yZW5kZXJfb2Zmc2NyZWVuID8gcmVjdC5ib3R0b20gOiByZWN0LnRvcCk7CgogICAgZ2xUZXhDb29yZDNmdigmY29vcmRzWzFdLngpOwogICAgZ2xWZXJ0ZXgyaShyZWN0LmxlZnQsIGRldmljZS0+cmVuZGVyX29mZnNjcmVlbiA/IHJlY3QudG9wIDogcmVjdC5ib3R0b20pOwoKICAgIGdsVGV4Q29vcmQzZnYoJmNvb3Jkc1syXS54KTsKICAgIGdsVmVydGV4MmkocmVjdC5yaWdodCwgZGV2aWNlLT5yZW5kZXJfb2Zmc2NyZWVuID8gcmVjdC50b3AgOiByZWN0LmJvdHRvbSk7CgogICAgZ2xUZXhDb29yZDNmdigmY29vcmRzWzNdLngpOwogICAgZ2xWZXJ0ZXgyaShyZWN0LnJpZ2h0LCBkZXZpY2UtPnJlbmRlcl9vZmZzY3JlZW4gPyByZWN0LmJvdHRvbSA6IHJlY3QudG9wKTsKICAgIGdsRW5kKCk7CiAgICBjaGVja0dMY2FsbCgiZ2xFbmQiKTsKCiAgICBpZihUaGlzLT5nbERlc2NyaXB0aW9uLnRhcmdldCAhPSBHTF9URVhUVVJFXzJEKSB7CiAgICAgICAgZ2xEaXNhYmxlKEdMX1RFWFRVUkVfQ1VCRV9NQVBfQVJCKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKEdMX1RFWFRVUkVfQ1VCRV9NQVBfQVJCKSIpOwogICAgfSBlbHNlIHsKICAgICAgICBnbERpc2FibGUoR0xfVEVYVFVSRV8yRCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShHTF9URVhUVVJFXzJEKSIpOwogICAgfQoKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcigoSVdpbmVEM0RTdXJmYWNlKilUaGlzLCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikgJnN3YXBjaGFpbik7CiAgICBpZihociA9PSBXSU5FRDNEX09LICYmIHN3YXBjaGFpbikgewogICAgICAgIC8qIE1ha2Ugc3VyZSB0byBmbHVzaCB0aGUgYnVmZmVycy4gVGhpcyBpcyBuZWVkZWQgaW4gYXBwcyBsaWtlIFJlZCBBbGVydCBJSSBhbmQgVGliZXJpYW4gU1VOIHRoYXQgdXNlIG11bHRpcGxlIFdHTCBjb250ZXh0cy4gKi8KICAgICAgICBpZigoKElXaW5lRDNEU3dhcENoYWluSW1wbCopc3dhcGNoYWluKS0+bnVtX2NvbnRleHRzID49IDIpCiAgICAgICAgICAgIGdsRmx1c2goKTsKCiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwY2hhaW4pOwogICAgfSBlbHNlIHsKICAgICAgICAvKiBXZSBjaGFuZ2VkIHRoZSBmaWx0ZXJpbmcgc2V0dGluZ3Mgb24gdGhlIHRleHR1cmUuIEluZm9ybSB0aGUgY29udGFpbmVyIGFib3V0IHRoaXMgdG8gZ2V0IHRoZSBmaWx0ZXJzCiAgICAgICAgICogcmVzZXQgcHJvcGVybHkgbmV4dCBkcmF3CiAgICAgICAgICovCiAgICAgICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKChJV2luZUQzRFN1cmZhY2UqKVRoaXMsICZJSURfSVdpbmVEM0RCYXNlVGV4dHVyZSwgKHZvaWQgKiopICZ0ZXh0dXJlKTsKICAgICAgICBpZihociA9PSBXSU5FRDNEX09LICYmIHRleHR1cmUpIHsKICAgICAgICAgICAgKChJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqKSB0ZXh0dXJlKS0+YmFzZVRleHR1cmUuc3RhdGVzW1dJTkVEM0RURVhTVEFfTUFHRklMVEVSXSA9IFdJTkVEM0RURVhGX1BPSU5UOwogICAgICAgICAgICAoKElXaW5lRDNEQmFzZVRleHR1cmVJbXBsICopIHRleHR1cmUpLT5iYXNlVGV4dHVyZS5zdGF0ZXNbV0lORUQzRFRFWFNUQV9NSU5GSUxURVJdID0gV0lORUQzRFRFWEZfUE9JTlQ7CiAgICAgICAgICAgICgoSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKikgdGV4dHVyZSktPmJhc2VUZXh0dXJlLnN0YXRlc1tXSU5FRDNEVEVYU1RBX01JUEZJTFRFUl0gPSBXSU5FRDNEVEVYRl9OT05FOwogICAgICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX1JlbGVhc2UodGV4dHVyZSk7CiAgICAgICAgfQogICAgfQogICAgTEVBVkVfR0woKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElXaW5lRDNEU3VyZmFjZTo6TG9hZExvY2F0aW9uCiAqCiAqIENvcGllcyB0aGUgY3VycmVudCBzdXJmYWNlIGRhdGEgZnJvbSB3aGVyZXZlciBpdCBpcyB0byB0aGUgcmVxdWVzdGVkCiAqIGxvY2F0aW9uLiBUaGUgbG9jYXRpb24gaXMgb25lIG9mIHRoZSBzdXJmYWNlIGZsYWdzLCBTRkxBR19JTlNZU01FTSwKICogU0ZMQUdfSU5URVhUVVJFIGFuZCBTRkxBR19JTkRSQVdBQkxFLiBXaGVuIHRoZSBzdXJmYWNlIGlzIGN1cnJlbnQgaW4KICogbXVsdGlwbGUgbG9jYXRpb25zLCB0aGUgZ2wgdGV4dHVyZSBpcyBwcmVmZXJyZWQgb3ZlciB0aGUgZHJhd2FibGUsIHdoaWNoIGlzCiAqIHByZWZlcnJlZCBvdmVyIHN5c3RlbSBtZW1vcnkuIFRoZSBQQk8gY291bnRzIGFzIHN5c3RlbSBtZW1vcnkuIElmIHJlY3QgaXMKICogbm90IE5VTEwsIG9ubHkgdGhlIHNwZWNpZmllZCByZWN0YW5nbGUgaXMgY29waWVkIChvbmx5IHN1cHBvcnRlZCBmb3IKICogc3lzbWVtPC0+ZHJhd2FibGUgY29waWVzIGF0IHRoZSBtb21lbnQpLiBJZiByZWN0IGlzIE5VTEwsIHRoZSBkZXN0aW5hdGlvbgogKiBsb2NhdGlvbiBpcyBtYXJrZWQgdXAgdG8gZGF0ZSBhZnRlciB0aGUgY29weS4KICoKICogUGFyYW1ldGVyczoKICogIGZsYWc6IFN1cmZhY2UgbG9jYXRpb24gZmxhZyB0byBiZSB1cGRhdGVkCiAqICByZWN0OiByZWN0YW5nbGUgdG8gYmUgY29waWVkCiAqCiAqIFJldHVybnM6CiAqICBXSU5FRDNEX09LIG9uIHN1Y2Nlc3MKICogIFdJTkVEM0RFUlJfREVWSUNFTE9TVCBvbiBhbiBpbnRlcm5hbCBlcnJvcgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRFN1cmZhY2VJbXBsX0xvYWRMb2NhdGlvbihJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBEV09SRCBmbGFnLCBjb25zdCBSRUNUICpyZWN0KSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcGNoYWluID0gTlVMTDsKICAgIEdMZW51bSBmb3JtYXQsIGludGVybmFsLCB0eXBlOwogICAgQ09OVkVSVF9UWVBFUyBjb252ZXJ0OwogICAgaW50IGJwcDsKICAgIGludCB3aWR0aCwgcGl0Y2gsIG91dHBpdGNoOwogICAgQllURSAqbWVtOwoKICAgIGlmICh3aW5lZDNkX3NldHRpbmdzLm9mZnNjcmVlbl9yZW5kZXJpbmdfbW9kZSA9PSBPUk1fRkJPKSB7CiAgICAgICAgaWYgKFNVQ0NFRURFRChJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKGlmYWNlLCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikmc3dhcGNoYWluKSkpIHsKICAgICAgICAgICAgVFJBQ0UoIlN1cmZhY2UgJXAgaXMgYW4gb25zY3JlZW4gc3VyZmFjZVxuIiwgaWZhY2UpOwoKICAgICAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwY2hhaW4pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8qIFdpdGggT1JNX0ZCTywgU0ZMQUdfSU5URVhUVVJFIGFuZCBTRkxBR19JTkRSQVdBQkxFIGFyZSB0aGUgc2FtZSBmb3Igb2Zmc2NyZWVuIHRhcmdldHMuCiAgICAgICAgICAgICAqIFByZWZlciBTRkxBR19JTlRFWFRVUkUuICovCiAgICAgICAgICAgIGlmIChmbGFnID09IFNGTEFHX0lORFJBV0FCTEUpIGZsYWcgPSBTRkxBR19JTlRFWFRVUkU7CiAgICAgICAgfQogICAgfQoKICAgIFRSQUNFKCIoJXApLT4oJXMsICVwKVxuIiwgaWZhY2UsCiAgICAgICAgICBmbGFnID09IFNGTEFHX0lOU1lTTUVNID8gIlNGTEFHX0lOU1lTTUVNIiA6IGZsYWcgPT0gU0ZMQUdfSU5EUkFXQUJMRSA/ICJTRkxBR19JTkRSQVdBQkxFIiA6ICJTRkxBR19JTlRFWFRVUkUiLAogICAgICAgICAgcmVjdCk7CiAgICBpZihyZWN0KSB7CiAgICAgICAgVFJBQ0UoIlJlY3RhbmdsZTogKCVkLCVkKS0oJWQsJWQpXG4iLCByZWN0LT5sZWZ0LCByZWN0LT50b3AsIHJlY3QtPnJpZ2h0LCByZWN0LT5ib3R0b20pOwogICAgfQoKICAgIGlmKFRoaXMtPkZsYWdzICYgZmxhZykgewogICAgICAgIFRSQUNFKCJMb2NhdGlvbiBhbHJlYWR5IHVwIHRvIGRhdGVcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIGlmKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19MT0NBVElPTlMpKSB7CiAgICAgICAgRVJSKCJTdXJmYWNlIGRvZXMgbm90IGhhdmUgYW55IHVwIHRvIGRhdGUgbG9jYXRpb25cbiIpOwogICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0xPU1Q7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfREVWSUNFTE9TVDsKICAgIH0KCiAgICBpZihmbGFnID09IFNGTEFHX0lOU1lTTUVNKSB7CiAgICAgICAgc3VyZmFjZV9wcmVwYXJlX3N5c3RlbV9tZW1vcnkoVGhpcyk7CgogICAgICAgIC8qIERvd25sb2FkIHRoZSBzdXJmYWNlIHRvIHN5c3RlbSBtZW1vcnkgKi8KICAgICAgICBpZihUaGlzLT5GbGFncyAmIFNGTEFHX0lOVEVYVFVSRSkgewogICAgICAgICAgICBpZighZGV2aWNlLT5pc0luRHJhdykgQWN0aXZhdGVDb250ZXh0KGRldmljZSwgZGV2aWNlLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0LCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwogICAgICAgICAgICBzdXJmYWNlX2JpbmRfYW5kX2RpcnRpZnkoVGhpcyk7CgogICAgICAgICAgICBzdXJmYWNlX2Rvd25sb2FkX2RhdGEoVGhpcyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmVhZF9mcm9tX2ZyYW1lYnVmZmVyKFRoaXMsIHJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfR2V0UGl0Y2goaWZhY2UpKTsKICAgICAgICB9CiAgICB9IGVsc2UgaWYoZmxhZyA9PSBTRkxBR19JTkRSQVdBQkxFKSB7CiAgICAgICAgaWYoVGhpcy0+RmxhZ3MgJiBTRkxBR19JTlRFWFRVUkUpIHsKICAgICAgICAgICAgc3VyZmFjZV9ibHRfdG9fZHJhd2FibGUoVGhpcywgcmVjdCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZDNkZm10X2dldF9jb252KFRoaXMsIFRSVUUgLyogV2UgbmVlZCBjb2xvciBrZXlpbmcgKi8sIEZBTFNFIC8qIFdlIHdvbid0IHVzZSB0ZXh0dXJlcyAqLywgJmZvcm1hdCwgJmludGVybmFsLCAmdHlwZSwgJmNvbnZlcnQsICZicHAsIFRoaXMtPnNyZ2IpOwoKICAgICAgICAgICAgLyogVGhlIHdpZHRoIGlzIGluICdsZW5ndGgnIG5vdCBpbiBieXRlcyAqLwogICAgICAgICAgICB3aWR0aCA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgICAgICBwaXRjaCA9IElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaChpZmFjZSk7CgogICAgICAgICAgICAvKiBEb24ndCB1c2UgUEJPcyBmb3IgY29udmVydGVkIHN1cmZhY2VzLiBEdXJpbmcgUEJPIGNvbnZlcnNpb24gd2UgbG9vayBhdCBTRkxBR19DT05WRVJURUQKICAgICAgICAgICAgICogYnV0IGl0IGlzbid0IHNldCAoeWV0KSBpbiBhbGwgY2FzZXMgaXQgaXMgZ2V0dGluZyBjYWxsZWQuICovCiAgICAgICAgICAgIGlmKChjb252ZXJ0ICE9IE5PX0NPTlZFUlNJT04pICYmIChUaGlzLT5GbGFncyAmIFNGTEFHX1BCTykpIHsKICAgICAgICAgICAgICAgIFRSQUNFKCJSZW1vdmluZyB0aGUgcGJvIGF0dGFjaGVkIHRvIHN1cmZhY2UgJXBcbiIsIFRoaXMpOwogICAgICAgICAgICAgICAgc3VyZmFjZV9yZW1vdmVfcGJvKFRoaXMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZigoY29udmVydCAhPSBOT19DT05WRVJTSU9OKSAmJiBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpIHsKICAgICAgICAgICAgICAgIGludCBoZWlnaHQgPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CgogICAgICAgICAgICAgICAgLyogU3RpY2sgdG8gdGhlIGFsaWdubWVudCBmb3IgdGhlIGNvbnZlcnRlZCBzdXJmYWNlIHRvbywgbWFrZXMgaXQgZWFzaWVyIHRvIGxvYWQgdGhlIHN1cmZhY2UgKi8KICAgICAgICAgICAgICAgIG91dHBpdGNoID0gd2lkdGggKiBicHA7CiAgICAgICAgICAgICAgICBvdXRwaXRjaCA9IChvdXRwaXRjaCArIGRldmljZS0+c3VyZmFjZV9hbGlnbm1lbnQgLSAxKSAmIH4oZGV2aWNlLT5zdXJmYWNlX2FsaWdubWVudCAtIDEpOwoKICAgICAgICAgICAgICAgIG1lbSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBvdXRwaXRjaCAqIGhlaWdodCk7CiAgICAgICAgICAgICAgICBpZighbWVtKSB7CiAgICAgICAgICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5ICVkLCAlZCFcbiIsIG91dHBpdGNoLCBoZWlnaHQpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX09VVE9GVklERU9NRU1PUlk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBkM2RmbXRfY29udmVydF9zdXJmYWNlKFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwgbWVtLCBwaXRjaCwgd2lkdGgsIGhlaWdodCwgb3V0cGl0Y2gsIGNvbnZlcnQsIFRoaXMpOwoKICAgICAgICAgICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0NPTlZFUlRFRDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19DT05WRVJURUQ7CiAgICAgICAgICAgICAgICBtZW0gPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGZsdXNoX3RvX2ZyYW1lYnVmZmVyX2RyYXdwaXhlbHMoVGhpcywgZm9ybWF0LCB0eXBlLCBicHAsIG1lbSk7CgogICAgICAgICAgICAvKiBEb24ndCBkZWxldGUgUEJPIG1lbW9yeSAqLwogICAgICAgICAgICBpZigobWVtICE9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgJiYgIShUaGlzLT5GbGFncyAmIFNGTEFHX1BCTykpCiAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtZW0pOwogICAgICAgIH0KICAgIH0gZWxzZSAvKiBpZihmbGFnID09IFNGTEFHX0lOVEVYVFVSRSkgKi8gewogICAgICAgIGlmIChUaGlzLT5GbGFncyAmIFNGTEFHX0lORFJBV0FCTEUpIHsKICAgICAgICAgICAgcmVhZF9mcm9tX2ZyYW1lYnVmZmVyX3RleHR1cmUoVGhpcyk7CiAgICAgICAgfSBlbHNlIHsgLyogVXBsb2FkIGZyb20gc3lzdGVtIG1lbW9yeSAqLwogICAgICAgICAgICBkM2RmbXRfZ2V0X2NvbnYoVGhpcywgVFJVRSAvKiBXZSBuZWVkIGNvbG9yIGtleWluZyAqLywgVFJVRSAvKiBXZSB3aWxsIHVzZSB0ZXh0dXJlcyAqLywgJmZvcm1hdCwgJmludGVybmFsLCAmdHlwZSwgJmNvbnZlcnQsICZicHAsIFRoaXMtPnNyZ2IpOwoKICAgICAgICAgICAgaWYoIWRldmljZS0+aXNJbkRyYXcpIEFjdGl2YXRlQ29udGV4dChkZXZpY2UsIGRldmljZS0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKICAgICAgICAgICAgc3VyZmFjZV9iaW5kX2FuZF9kaXJ0aWZ5KFRoaXMpOwogICAgICAgICAgICBFTlRFUl9HTCgpOwoKICAgICAgICAgICAgLyogVGhlIG9ubHkgcGxhY2Ugd2hlcmUgTG9hZFRleHR1cmUoKSBtaWdodCBnZXQgY2FsbGVkIHdoZW4gaXNJbkRyYXc9MQogICAgICAgICAgICAgKiBpcyBBY3RpdmF0ZUNvbnRleHQgd2hlcmUgbGFzdEFjdGl2ZVJlbmRlclRhcmdldCBpcyBwcmVsb2FkZWQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZihpZmFjZSA9PSBkZXZpY2UtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQgJiYgZGV2aWNlLT5pc0luRHJhdykKICAgICAgICAgICAgICAgIEVSUigiUmVhZGluZyBiYWNrIHJlbmRlciB0YXJnZXQgYnV0IFNGTEFHX0lORFJBV0FCTEUgbm90IHNldFxuIik7CgogICAgICAgICAgICAvKiBPdGhlcndpc2U6IFN5c3RlbSBtZW1vcnkgY29weSBtdXN0IGJlIG1vc3QgdXAgdG8gZGF0ZSAqLwoKICAgICAgICAgICAgaWYoVGhpcy0+Q0tleUZsYWdzICYgV0lORUREU0RfQ0tTUkNCTFQpIHsKICAgICAgICAgICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0dMQ0tFWTsKICAgICAgICAgICAgICAgIFRoaXMtPmdsQ0tleSA9IFRoaXMtPlNyY0JsdENLZXk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfR0xDS0VZOwoKICAgICAgICAgICAgLyogVGhlIHdpZHRoIGlzIGluICdsZW5ndGgnIG5vdCBpbiBieXRlcyAqLwogICAgICAgICAgICB3aWR0aCA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgICAgICBwaXRjaCA9IElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaChpZmFjZSk7CgogICAgICAgICAgICAvKiBEb24ndCB1c2UgUEJPcyBmb3IgY29udmVydGVkIHN1cmZhY2VzLiBEdXJpbmcgUEJPIGNvbnZlcnNpb24gd2UgbG9vayBhdCBTRkxBR19DT05WRVJURUQKICAgICAgICAgICAgICogYnV0IGl0IGlzbid0IHNldCAoeWV0KSBpbiBhbGwgY2FzZXMgaXQgaXMgZ2V0dGluZyBjYWxsZWQuICovCiAgICAgICAgICAgIGlmKChjb252ZXJ0ICE9IE5PX0NPTlZFUlNJT04pICYmIChUaGlzLT5GbGFncyAmIFNGTEFHX1BCTykpIHsKICAgICAgICAgICAgICAgIFRSQUNFKCJSZW1vdmluZyB0aGUgcGJvIGF0dGFjaGVkIHRvIHN1cmZhY2UgJXBcbiIsIFRoaXMpOwogICAgICAgICAgICAgICAgc3VyZmFjZV9yZW1vdmVfcGJvKFRoaXMpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZigoY29udmVydCAhPSBOT19DT05WRVJTSU9OKSAmJiBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpIHsKICAgICAgICAgICAgICAgIGludCBoZWlnaHQgPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CgogICAgICAgICAgICAgICAgLyogU3RpY2sgdG8gdGhlIGFsaWdubWVudCBmb3IgdGhlIGNvbnZlcnRlZCBzdXJmYWNlIHRvbywgbWFrZXMgaXQgZWFzaWVyIHRvIGxvYWQgdGhlIHN1cmZhY2UgKi8KICAgICAgICAgICAgICAgIG91dHBpdGNoID0gd2lkdGggKiBicHA7CiAgICAgICAgICAgICAgICBvdXRwaXRjaCA9IChvdXRwaXRjaCArIGRldmljZS0+c3VyZmFjZV9hbGlnbm1lbnQgLSAxKSAmIH4oZGV2aWNlLT5zdXJmYWNlX2FsaWdubWVudCAtIDEpOwoKICAgICAgICAgICAgICAgIG1lbSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBvdXRwaXRjaCAqIGhlaWdodCk7CiAgICAgICAgICAgICAgICBpZighbWVtKSB7CiAgICAgICAgICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5ICVkLCAlZCFcbiIsIG91dHBpdGNoLCBoZWlnaHQpOwogICAgICAgICAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX09VVE9GVklERU9NRU1PUlk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBkM2RmbXRfY29udmVydF9zdXJmYWNlKFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwgbWVtLCBwaXRjaCwgd2lkdGgsIGhlaWdodCwgb3V0cGl0Y2gsIGNvbnZlcnQsIFRoaXMpOwoKICAgICAgICAgICAgICAgIFRoaXMtPkZsYWdzIHw9IFNGTEFHX0NPTlZFUlRFRDsKICAgICAgICAgICAgfSBlbHNlIGlmKCAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUDgpICYmIChHTF9TVVBQT1JUKEVYVF9QQUxFVFRFRF9URVhUVVJFKSB8fCBHTF9TVVBQT1JUKEFSQl9GUkFHTUVOVF9QUk9HUkFNKSkgKSB7CiAgICAgICAgICAgICAgICBkM2RmbXRfcDhfdXBsb2FkX3BhbGV0dGUoaWZhY2UsIGNvbnZlcnQpOwogICAgICAgICAgICAgICAgVGhpcy0+RmxhZ3MgJj0gflNGTEFHX0NPTlZFUlRFRDsKICAgICAgICAgICAgICAgIG1lbSA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19DT05WRVJURUQ7CiAgICAgICAgICAgICAgICBtZW0gPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIE1ha2Ugc3VyZSB0aGUgY29ycmVjdCBwaXRjaCBpcyB1c2VkICovCiAgICAgICAgICAgIGdsUGl4ZWxTdG9yZWkoR0xfVU5QQUNLX1JPV19MRU5HVEgsIHdpZHRoKTsKCiAgICAgICAgICAgIGlmICgoVGhpcy0+RmxhZ3MgJiBTRkxBR19OT05QT1cyKSAmJiAhKFRoaXMtPkZsYWdzICYgU0ZMQUdfT1ZFUlNJWkUpKSB7CiAgICAgICAgICAgICAgICBUUkFDRSgibm9uIHBvd2VyIG9mIHR3byBzdXBwb3J0XG4iKTsKICAgICAgICAgICAgICAgIGlmKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19BTExPQ0FURUQpKSB7CiAgICAgICAgICAgICAgICAgICAgc3VyZmFjZV9hbGxvY2F0ZV9zdXJmYWNlKFRoaXMsIGludGVybmFsLCBUaGlzLT5wb3cyV2lkdGgsIFRoaXMtPnBvdzJIZWlnaHQsIGZvcm1hdCwgdHlwZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAobWVtIHx8IChUaGlzLT5GbGFncyAmIFNGTEFHX1BCTykpIHsKICAgICAgICAgICAgICAgICAgICBzdXJmYWNlX3VwbG9hZF9kYXRhKFRoaXMsIGludGVybmFsLCBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCwgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0LCBmb3JtYXQsIHR5cGUsIG1lbSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvKiBXaGVuIG1ha2luZyB0aGUgcmVhbGxvYyBjb25kaXRpb25hbCwga2VlcCBpbiBtaW5kIHRoYXQgR0xfQVBQTEVfY2xpZW50X3N0b3JhZ2UgbWF5IGJlIGluIHVzZSwgYW5kIFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeQogICAgICAgICAgICAgICAgICogY2hhbmdlZC4gU28gYWxzbyBrZWVwIHRyYWNrIG9mIG1lbW9yeSBjaGFuZ2VzLiBJbiB0aGlzIGNhc2UgdGhlIHRleHR1cmUgaGFzIHRvIGJlIHJlYWxsb2NhdGVkCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmKCEoVGhpcy0+RmxhZ3MgJiBTRkxBR19BTExPQ0FURUQpKSB7CiAgICAgICAgICAgICAgICAgICAgc3VyZmFjZV9hbGxvY2F0ZV9zdXJmYWNlKFRoaXMsIGludGVybmFsLCBUaGlzLT5nbFJlY3QucmlnaHQgLSBUaGlzLT5nbFJlY3QubGVmdCwgVGhpcy0+Z2xSZWN0LmJvdHRvbSAtIFRoaXMtPmdsUmVjdC50b3AsIGZvcm1hdCwgdHlwZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAobWVtIHx8IChUaGlzLT5GbGFncyAmIFNGTEFHX1BCTykpIHsKICAgICAgICAgICAgICAgICAgICBzdXJmYWNlX3VwbG9hZF9kYXRhKFRoaXMsIGludGVybmFsLCBUaGlzLT5nbFJlY3QucmlnaHQgLSBUaGlzLT5nbFJlY3QubGVmdCwgVGhpcy0+Z2xSZWN0LmJvdHRvbSAtIFRoaXMtPmdsUmVjdC50b3AsIGZvcm1hdCwgdHlwZSwgbWVtKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogUmVzdG9yZSB0aGUgZGVmYXVsdCBwaXRjaCAqLwogICAgICAgICAgICBnbFBpeGVsU3RvcmVpKEdMX1VOUEFDS19ST1dfTEVOR1RILCAwKTsKICAgICAgICAgICAgTEVBVkVfR0woKTsKCiAgICAgICAgICAgIC8qIERvbid0IGRlbGV0ZSBQQk8gbWVtb3J5ICovCiAgICAgICAgICAgIGlmKChtZW0gIT0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KSAmJiAhKFRoaXMtPkZsYWdzICYgU0ZMQUdfUEJPKSkKICAgICAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1lbSk7CiAgICAgICAgfQogICAgfQoKICAgIGlmKHJlY3QgPT0gTlVMTCkgewogICAgICAgIFRoaXMtPkZsYWdzIHw9IGZsYWc7CiAgICB9CgogICAgaWYgKHdpbmVkM2Rfc2V0dGluZ3Mub2Zmc2NyZWVuX3JlbmRlcmluZ19tb2RlID09IE9STV9GQk8gJiYgIXN3YXBjaGFpbgogICAgICAgICAgICAmJiAoVGhpcy0+RmxhZ3MgJiAoU0ZMQUdfSU5URVhUVVJFIHwgU0ZMQUdfSU5EUkFXQUJMRSkpKSB7CiAgICAgICAgLyogV2l0aCBPUk1fRkJPLCBTRkxBR19JTlRFWFRVUkUgYW5kIFNGTEFHX0lORFJBV0FCTEUgYXJlIHRoZSBzYW1lIGZvciBvZmZzY3JlZW4gdGFyZ2V0cy4gKi8KICAgICAgICBUaGlzLT5GbGFncyB8PSAoU0ZMQUdfSU5URVhUVVJFIHwgU0ZMQUdfSU5EUkFXQUJMRSk7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0Q29udGFpbmVyKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIElXaW5lRDNEQmFzZSAqY29udGFpbmVyKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcGNoYWluID0gTlVMTDsKCiAgICAvKiBVcGRhdGUgdGhlIGRyYXdhYmxlIHNpemUgbWV0aG9kICovCiAgICBpZihjb250YWluZXIpIHsKICAgICAgICBJV2luZUQzREJhc2VfUXVlcnlJbnRlcmZhY2UoY29udGFpbmVyLCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikgJnN3YXBjaGFpbik7CiAgICB9CiAgICBpZihzd2FwY2hhaW4pIHsKICAgICAgICBUaGlzLT5nZXRfZHJhd2FibGVfc2l6ZSA9IGdldF9kcmF3YWJsZV9zaXplX3N3YXBjaGFpbjsKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKHN3YXBjaGFpbik7CiAgICB9IGVsc2UgaWYoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSB7CiAgICAgICAgc3dpdGNoKHdpbmVkM2Rfc2V0dGluZ3Mub2Zmc2NyZWVuX3JlbmRlcmluZ19tb2RlKSB7CiAgICAgICAgICAgIGNhc2UgT1JNX0ZCTzogICAgICAgIFRoaXMtPmdldF9kcmF3YWJsZV9zaXplID0gZ2V0X2RyYXdhYmxlX3NpemVfZmJvOyAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgT1JNX1BCVUZGRVI6ICAgIFRoaXMtPmdldF9kcmF3YWJsZV9zaXplID0gZ2V0X2RyYXdhYmxlX3NpemVfcGJ1ZmZlcjsgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgT1JNX0JBQ0tCVUZGRVI6IFRoaXMtPmdldF9kcmF3YWJsZV9zaXplID0gZ2V0X2RyYXdhYmxlX3NpemVfYmFja2J1ZmZlcjsgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9TZXRDb250YWluZXIoaWZhY2UsIGNvbnRhaW5lcik7Cn0KCnN0YXRpYyBXSU5FRDNEU1VSRlRZUEUgV0lOQVBJIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0SW1wbFR5cGUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgcmV0dXJuIFNVUkZBQ0VfT1BFTkdMOwp9Cgpjb25zdCBJV2luZUQzRFN1cmZhY2VWdGJsIElXaW5lRDNEU3VyZmFjZV9WdGJsID0KewogICAgLyogSVVua25vd24gKi8KICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1F1ZXJ5SW50ZXJmYWNlLAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfQWRkUmVmLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZWxlYXNlLAogICAgLyogSVdpbmVEM0RSZXNvdXJjZSAqLwogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0UGFyZW50LAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0RGV2aWNlLAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfU2V0UHJpdmF0ZURhdGEsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXRQcml2YXRlRGF0YSwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0ZyZWVQcml2YXRlRGF0YSwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1NldFByaW9yaXR5LAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0UHJpb3JpdHksCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1ByZUxvYWQsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1VuTG9hZCwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldFR5cGUsCiAgICAvKiBJV2luZUQzRFN1cmZhY2UgKi8KICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldENvbnRhaW5lciwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldERlc2MsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0xvY2tSZWN0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9VbmxvY2tSZWN0LAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREQywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfUmVsZWFzZURDLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9GbGlwLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9CbHQsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXRCbHRTdGF0dXMsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXRGbGlwU3RhdHVzLAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfSXNMb3N0LAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfUmVzdG9yZSwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfQmx0RmFzdCwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldFBhbGV0dGUsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9TZXRQYWxldHRlLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9SZWFsaXplUGFsZXR0ZSwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1NldENvbG9yS2V5LAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0UGl0Y2gsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldE1lbSwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1NldE92ZXJsYXlQb3NpdGlvbiwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldE92ZXJsYXlQb3NpdGlvbiwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1VwZGF0ZU92ZXJsYXlaT3JkZXIsCiAgICBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9VcGRhdGVPdmVybGF5LAogICAgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfU2V0Q2xpcHBlciwKICAgIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldENsaXBwZXIsCiAgICAvKiBJbnRlcm5hbCB1c2U6ICovCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0FkZERpcnR5UmVjdCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfTG9hZFRleHR1cmUsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0JpbmRUZXh0dXJlLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TYXZlU25hcHNob3QsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1NldENvbnRhaW5lciwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfU2V0R2xUZXh0dXJlRGVzYywKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0R2xEZXNjLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9HZXREYXRhLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbF9TZXRGb3JtYXQsCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX1ByaXZhdGVTZXR1cCwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfTW9kaWZ5TG9jYXRpb24sCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsX0xvYWRMb2NhdGlvbiwKICAgIElXaW5lRDNEU3VyZmFjZUltcGxfR2V0SW1wbFR5cGUKfTsK