LyoKICogSVdpbmVEM0REZXZpY2UgaW1wbGVtZW50YXRpb24KICoKICogQ29weXJpZ2h0IDIwMDIgTGlvbmVsIFVsbWVyCiAqIENvcHlyaWdodCAyMDAyLTIwMDUgSmFzb24gRWRtZWFkZXMKICogQ29weXJpZ2h0IDIwMDMtMjAwNCBSYXBoYWVsIEp1bnF1ZWlyYQogKiBDb3B5cmlnaHQgMjAwNCBDaHJpc3RpYW4gQ29zdGEKICogQ29weXJpZ2h0IDIwMDUgT2xpdmVyIFN0aWViZXIKICogQ29weXJpZ2h0IDIwMDYtMjAwOCBTdGVmYW4gRPZzaW5nZXIgZm9yIENvZGVXZWF2ZXJzCiAqIENvcHlyaWdodCAyMDA2LTIwMDcgSGVucmkgVmVyYmVldAogKiBDb3B5cmlnaHQgMjAwNyBBbmRyZXcgUmllZGkKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSA8c3RkaW8uaD4KI2lmZGVmIEhBVkVfRkxPQVRfSAojIGluY2x1ZGUgPGZsb2F0Lmg+CiNlbmRpZgojaW5jbHVkZSAid2luZWQzZF9wcml2YXRlLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkM2QpOwojZGVmaW5lIEdMSU5GT19MT0NBVElPTiBUaGlzLT5hZGFwdGVyLT5nbF9pbmZvCgovKiBEZWZpbmUgdGhlIGRlZmF1bHQgbGlnaHQgcGFyYW1ldGVycyBhcyBzcGVjaWZpZWQgYnkgTVNETiAqLwpjb25zdCBXSU5FRDNETElHSFQgV0lORUQzRF9kZWZhdWx0X2xpZ2h0ID0gewoKICAgIFdJTkVEM0RMSUdIVF9ESVJFQ1RJT05BTCwgLyogVHlwZSAqLwogICAgeyAxLjAsIDEuMCwgMS4wLCAwLjAgfSwgICAvKiBEaWZmdXNlIHIsZyxiLGEgKi8KICAgIHsgMC4wLCAwLjAsIDAuMCwgMC4wIH0sICAgLyogU3BlY3VsYXIgcixnLGIsYSAqLwogICAgeyAwLjAsIDAuMCwgMC4wLCAwLjAgfSwgICAvKiBBbWJpZW50IHIsZyxiLGEsICovCiAgICB7IDAuMCwgMC4wLCAwLjAgfSwgICAgICAgIC8qIFBvc2l0aW9uIHgseSx6ICovCiAgICB7IDAuMCwgMC4wLCAxLjAgfSwgICAgICAgIC8qIERpcmVjdGlvbiB4LHkseiAqLwogICAgMC4wLCAgICAgICAgICAgICAgICAgICAgICAvKiBSYW5nZSAqLwogICAgMC4wLCAgICAgICAgICAgICAgICAgICAgICAvKiBGYWxsb2ZmICovCiAgICAwLjAsIDAuMCwgMC4wLCAgICAgICAgICAgIC8qIEF0dGVudWF0aW9uIDAsMSwyICovCiAgICAwLjAsICAgICAgICAgICAgICAgICAgICAgIC8qIFRoZXRhICovCiAgICAwLjAgICAgICAgICAgICAgICAgICAgICAgIC8qIFBoaSAqLwp9OwoKLyogc3RhdGljIGZ1bmN0aW9uIGRlY2xhcmF0aW9ucyAqLwpzdGF0aWMgdm9pZCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0FkZFJlc291cmNlKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RSZXNvdXJjZSAqcmVzb3VyY2UpOwoKLyogaGVscGVyIG1hY3JvcyAqLwojZGVmaW5lIEQzRE1FTUNIRUNLKG9iamVjdCwgcHBSZXN1bHQpIGlmKE5VTEwgPT0gb2JqZWN0KSB7ICpwcFJlc3VsdCA9IE5VTEw7IFdBUk4oIk91dCBvZiBtZW1vcnlcbiIpOyByZXR1cm4gV0lORUQzREVSUl9PVVRPRlZJREVPTUVNT1JZO30KCiNkZWZpbmUgRDNEQ1JFQVRFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCB0eXBlKSB7IFwKICAgIG9iamVjdD1IZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElXaW5lRDNEIyN0eXBlIyNJbXBsKSk7IFwKICAgIEQzRE1FTUNIRUNLKG9iamVjdCwgcHAjI3R5cGUpOyBcCiAgICBvYmplY3QtPmxwVnRibCA9ICZJV2luZUQzRCMjdHlwZSMjX1Z0Ymw7ICBcCiAgICBvYmplY3QtPndpbmVEM0REZXZpY2UgPSBUaGlzOyBcCiAgICBvYmplY3QtPnBhcmVudCAgICAgICA9IHBhcmVudDsgXAogICAgb2JqZWN0LT5yZWYgICAgICAgICAgPSAxOyBcCiAgICAqcHAjI3R5cGUgPSAoSVdpbmVEM0QjI3R5cGUgKikgb2JqZWN0OyBcCn0KCiNkZWZpbmUgRDNEQ1JFQVRFU0hBREVST0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCB0eXBlKSB7IFwKICAgIG9iamVjdD1IZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElXaW5lRDNEIyN0eXBlIyNJbXBsKSk7IFwKICAgIEQzRE1FTUNIRUNLKG9iamVjdCwgcHAjI3R5cGUpOyBcCiAgICBvYmplY3QtPmxwVnRibCA9ICZJV2luZUQzRCMjdHlwZSMjX1Z0Ymw7ICBcCiAgICBvYmplY3QtPnBhcmVudCAgICAgICAgICA9IHBhcmVudDsgXAogICAgb2JqZWN0LT5iYXNlU2hhZGVyLnJlZiAgPSAxOyBcCiAgICBvYmplY3QtPmJhc2VTaGFkZXIuZGV2aWNlID0gKElXaW5lRDNERGV2aWNlKikgVGhpczsgXAogICAgbGlzdF9pbml0KCZvYmplY3QtPmJhc2VTaGFkZXIubGlua2VkX3Byb2dyYW1zKTsgXAogICAgKnBwIyN0eXBlID0gKElXaW5lRDNEIyN0eXBlICopIG9iamVjdDsgXAp9CgojZGVmaW5lICBEM0RDUkVBVEVSRVNPVVJDRU9CSkVDVElOU1RBTkNFKG9iamVjdCwgdHlwZSwgZDNkdHlwZSwgX3NpemUpeyBcCiAgICBvYmplY3Q9SGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJV2luZUQzRCMjdHlwZSMjSW1wbCkpOyBcCiAgICBEM0RNRU1DSEVDSyhvYmplY3QsIHBwIyN0eXBlKTsgXAogICAgb2JqZWN0LT5scFZ0YmwgPSAmSVdpbmVEM0QjI3R5cGUjI19WdGJsOyAgXAogICAgb2JqZWN0LT5yZXNvdXJjZS53aW5lRDNERGV2aWNlICAgPSBUaGlzOyBcCiAgICBvYmplY3QtPnJlc291cmNlLnBhcmVudCAgICAgICAgICA9IHBhcmVudDsgXAogICAgb2JqZWN0LT5yZXNvdXJjZS5yZXNvdXJjZVR5cGUgICAgPSBkM2R0eXBlOyBcCiAgICBvYmplY3QtPnJlc291cmNlLnJlZiAgICAgICAgICAgICA9IDE7IFwKICAgIG9iamVjdC0+cmVzb3VyY2UucG9vbCAgICAgICAgICAgID0gUG9vbDsgXAogICAgb2JqZWN0LT5yZXNvdXJjZS5mb3JtYXQgICAgICAgICAgPSBGb3JtYXQ7IFwKICAgIG9iamVjdC0+cmVzb3VyY2UudXNhZ2UgICAgICAgICAgID0gVXNhZ2U7IFwKICAgIG9iamVjdC0+cmVzb3VyY2Uuc2l6ZSAgICAgICAgICAgID0gX3NpemU7IFwKICAgIGxpc3RfaW5pdCgmb2JqZWN0LT5yZXNvdXJjZS5wcml2YXRlRGF0YSk7IFwKICAgIC8qIENoZWNrIHRoYXQgd2UgaGF2ZSBlbm91Z2ggdmlkZW8gcmFtIGxlZnQgKi8gXAogICAgaWYgKFBvb2wgPT0gV0lORUQzRFBPT0xfREVGQVVMVCkgeyBcCiAgICAgICAgaWYgKElXaW5lRDNERGV2aWNlX0dldEF2YWlsYWJsZVRleHR1cmVNZW0oaWZhY2UpIDw9IF9zaXplKSB7IFwKICAgICAgICAgICAgV0FSTigiT3V0IG9mICdib2d1cycgdmlkZW8gbWVtb3J5XG4iKTsgXAogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvYmplY3QpOyBcCiAgICAgICAgICAgICpwcCMjdHlwZSA9IE5VTEw7IFwKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfT1VUT0ZWSURFT01FTU9SWTsgXAogICAgICAgIH0gXAogICAgICAgIFdpbmVEM0RBZGFwdGVyQ2hhbmdlR0xSYW0oVGhpcywgX3NpemUpOyBcCiAgICB9IFwKICAgIG9iamVjdC0+cmVzb3VyY2UuaGVhcE1lbW9yeSA9ICgwID09IF9zaXplID8gTlVMTCA6IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBfc2l6ZSArIFJFU09VUkNFX0FMSUdOTUVOVCkpOyBcCiAgICBpZiAob2JqZWN0LT5yZXNvdXJjZS5oZWFwTWVtb3J5ID09IE5VTEwgJiYgX3NpemUgIT0gMCkgeyBcCiAgICAgICAgRklYTUUoIk91dCBvZiBtZW1vcnkhXG4iKTsgXAogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9iamVjdCk7IFwKICAgICAgICAqcHAjI3R5cGUgPSBOVUxMOyBcCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfT1VUT0ZWSURFT01FTU9SWTsgXAogICAgfSBcCiAgICBvYmplY3QtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IChCWVRFICopKCgoVUxPTkdfUFRSKSBvYmplY3QtPnJlc291cmNlLmhlYXBNZW1vcnkgKyAoUkVTT1VSQ0VfQUxJR05NRU5UIC0gMSkpICYgfihSRVNPVVJDRV9BTElHTk1FTlQgLSAxKSk7IFwKICAgICpwcCMjdHlwZSA9IChJV2luZUQzRCMjdHlwZSAqKSBvYmplY3Q7IFwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9BZGRSZXNvdXJjZShpZmFjZSwgKElXaW5lRDNEUmVzb3VyY2UgKilvYmplY3QpIDtcCiAgICBUUkFDRSgiKCVwKSA6IENyZWF0ZWQgcmVzb3VyY2UgJXBcbiIsIFRoaXMsIG9iamVjdCk7IFwKfQoKI2RlZmluZSBEM0RJTklUSUFMSVpFQkFTRVRFWFRVUkUoX2Jhc2V0ZXh0dXJlKSB7IFwKICAgIF9iYXNldGV4dHVyZS5sZXZlbHMgICAgID0gTGV2ZWxzOyBcCiAgICBfYmFzZXRleHR1cmUuZmlsdGVyVHlwZSA9IChVc2FnZSAmIFdJTkVEM0RVU0FHRV9BVVRPR0VOTUlQTUFQKSA/IFdJTkVEM0RURVhGX0xJTkVBUiA6IFdJTkVEM0RURVhGX05PTkU7IFwKICAgIF9iYXNldGV4dHVyZS5MT0QgICAgICAgID0gMDsgXAogICAgX2Jhc2V0ZXh0dXJlLmRpcnR5ICAgICAgPSBUUlVFOyBcCiAgICBfYmFzZXRleHR1cmUuaXNfc3JnYiA9IEZBTFNFOyBcCiAgICBfYmFzZXRleHR1cmUuc3JnYl9tb2RlX2NoYW5nZV9jb3VudCA9IDA7IFwKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogR2xvYmFsIHZhcmlhYmxlIC8gQ29uc3RhbnRzIGZvbGxvdwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KY29uc3QgZmxvYXQgaWRlbnRpdHlbMTZdID0gezEsMCwwLDAsIDAsMSwwLDAsIDAsMCwxLDAsIDAsMCwwLDF9OyAgLyogV2hlbiBuZWVkZWQgZm9yIGNvbXBhcmlzb25zICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJVW5rbm93biBwYXJ0cyBmb2xsb3dzCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9RdWVyeUludGVyZmFjZShJV2luZUQzRERldmljZSAqaWZhY2UsUkVGSUlEIHJpaWQsTFBWT0lEICpwcG9iaikKewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXApLT4oJXMsJXApXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxwcG9iaik7CiAgICBpZiAoSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JVW5rbm93bikKICAgICAgICB8fCBJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lXaW5lRDNEQmFzZSkKICAgICAgICB8fCBJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lXaW5lRDNERGV2aWNlKSkgewogICAgICAgIElVbmtub3duX0FkZFJlZihpZmFjZSk7CiAgICAgICAgKnBwb2JqID0gVGhpczsKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KICAgICpwcG9iaiA9IE5VTEw7CiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQWRkUmVmKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVUxPTkcgcmVmQ291bnQgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgICBUUkFDRSgiKCVwKSA6IEFkZFJlZiBpbmNyZWFzaW5nIGZyb20gJWRcbiIsIFRoaXMsIHJlZkNvdW50IC0gMSk7CiAgICByZXR1cm4gcmVmQ291bnQ7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1JlbGVhc2UoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBVTE9ORyByZWZDb3VudCA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwoKICAgIFRSQUNFKCIoJXApIDogUmVsZWFzaW5nIGZyb20gJWRcbiIsIFRoaXMsIHJlZkNvdW50ICsgMSk7CgogICAgaWYgKCFyZWZDb3VudCkgewogICAgICAgIGlmIChUaGlzLT5mYm8pIHsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbERlbGV0ZUZyYW1lYnVmZmVyc0VYVCgxLCAmVGhpcy0+ZmJvKSk7CiAgICAgICAgfQogICAgICAgIGlmIChUaGlzLT5zcmNfZmJvKSB7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xEZWxldGVGcmFtZWJ1ZmZlcnNFWFQoMSwgJlRoaXMtPnNyY19mYm8pKTsKICAgICAgICB9CiAgICAgICAgaWYgKFRoaXMtPmRzdF9mYm8pIHsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbERlbGV0ZUZyYW1lYnVmZmVyc0VYVCgxLCAmVGhpcy0+ZHN0X2ZibykpOwogICAgICAgIH0KCiAgICAgICAgaWYgKFRoaXMtPmdsc2xfcHJvZ3JhbV9sb29rdXApIGhhc2hfdGFibGVfZGVzdHJveShUaGlzLT5nbHNsX3Byb2dyYW1fbG9va3VwKTsKCiAgICAgICAgLyogVE9ETzogQ2xlYW4gdXAgYWxsIHRoZSBzdXJmYWNlcyBhbmQgdGV4dHVyZXMhICovCiAgICAgICAgLyogTk9URTogWW91IG11c3QgcmVsZWFzZSB0aGUgcGFyZW50IGlmIHRoZSBvYmplY3Qgd2FzIGNyZWF0ZWQgdmlhIGEgY2FsbGJhY2sKICAgICAgICAqKiAqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgICAgIGlmICghbGlzdF9lbXB0eSgmVGhpcy0+cmVzb3VyY2VzKSkgewogICAgICAgICAgICBGSVhNRSgiKCVwKSBEZXZpY2UgcmVsZWFzZWQgd2l0aCByZXNvdXJjZXMgc3RpbGwgYm91bmQsIGFjY2VwdGFibGUgYnV0IHVuZXhwZWN0ZWRcbiIsIFRoaXMpOwogICAgICAgICAgICBkdW1wUmVzb3VyY2VzKCZUaGlzLT5yZXNvdXJjZXMpOwogICAgICAgIH0KCiAgICAgICAgaWYoVGhpcy0+Y29udGV4dHMpIEVSUigiQ29udGV4dCBhcnJheSBub3QgZnJlZWQhXG4iKTsKICAgICAgICBpZiAoVGhpcy0+aGFyZHdhcmVDdXJzb3IpIERlc3Ryb3lDdXJzb3IoVGhpcy0+aGFyZHdhcmVDdXJzb3IpOwogICAgICAgIFRoaXMtPmhhdmVIYXJkd2FyZUN1cnNvciA9IEZBTFNFOwoKICAgICAgICBJV2luZUQzRF9SZWxlYXNlKFRoaXMtPndpbmVEM0QpOwogICAgICAgIFRoaXMtPndpbmVEM0QgPSBOVUxMOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMpOwogICAgICAgIFRSQUNFKCJGcmVlZCBkZXZpY2UgICVwXG4iLCBUaGlzKTsKICAgICAgICBUaGlzID0gTlVMTDsKICAgIH0KICAgIHJldHVybiByZWZDb3VudDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0REZXZpY2UgaW1wbGVtZW50YXRpb24gZm9sbG93cwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQYXJlbnQoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJVW5rbm93biAqKnBQYXJlbnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgICpwUGFyZW50ID0gVGhpcy0+cGFyZW50OwogICAgSVVua25vd25fQWRkUmVmKFRoaXMtPnBhcmVudCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWZXJ0ZXhCdWZmZXIoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIFNpemUsIERXT1JEIFVzYWdlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGVkYsIFdJTkVEM0RQT09MIFBvb2wsIElXaW5lRDNEVmVydGV4QnVmZmVyKiogcHBWZXJ0ZXhCdWZmZXIsIEhBTkRMRSAqc2hhcmVkSGFuZGxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIElVbmtub3duICpwYXJlbnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEVmVydGV4QnVmZmVySW1wbCAqb2JqZWN0OwogICAgV0lORUQzREZPUk1BVCBGb3JtYXQgPSBXSU5FRDNERk1UX1ZFUlRFWERBVEE7IC8qIER1bW15IGZvcm1hdCBmb3Igbm93ICovCiAgICBpbnQgZHhWZXJzaW9uID0gKCAoSVdpbmVEM0RJbXBsICopIFRoaXMtPndpbmVEM0QpLT5keFZlcnNpb247CiAgICBCT09MIGNvbnY7CgogICAgaWYoU2l6ZSA9PSAwKSB7CiAgICAgICAgV0FSTigiU2l6ZSAwIHJlcXVlc3RlZCwgcmV0dXJuaW5nIFdJTkVEM0RFUlJfSU5WQUxJRENBTExcbiIpOwogICAgICAgICpwcFZlcnRleEJ1ZmZlciA9IE5VTEw7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9IGVsc2UgaWYoUG9vbCA9PSBXSU5FRDNEUE9PTF9TQ1JBVENIKSB7CiAgICAgICAgLyogVGhlIGQzZDkgdGVzdHN1aXQgc2hvd3MgdGhhdCB0aGlzIGlzIG5vdCBhbGxvd2VkLiBJdCBkb2Vzbid0IG1ha2UgbXVjaCBzZW5zZQogICAgICAgICAqIGFueXdheSwgU0NSQVRDSCB2ZXJ0ZXggYnVmZmVycyBhcmVuJ3QgdXNhYmxlIGFueXdoZXJlCiAgICAgICAgICovCiAgICAgICAgV0FSTigiVmVydGV4IGJ1ZmZlciBpbiBEM0RQT09MX1NDUkFUQ0ggcmVxdWVzdGVkLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgKnBwVmVydGV4QnVmZmVyID0gTlVMTDsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBEM0RDUkVBVEVSRVNPVVJDRU9CSkVDVElOU1RBTkNFKG9iamVjdCwgVmVydGV4QnVmZmVyLCBXSU5FRDNEUlRZUEVfVkVSVEVYQlVGRkVSLCBTaXplKQoKICAgIFRSQUNFKCIoJXApIDogU2l6ZT0lZCwgVXNhZ2U9MHglMDh4LCBGVkY9JXgsIFBvb2w9JWQgLSBNZW1vcnlAJXAsIElmYWNlQCVwXG4iLCBUaGlzLCBTaXplLCBVc2FnZSwgRlZGLCBQb29sLCBvYmplY3QtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwgb2JqZWN0KTsKICAgICpwcFZlcnRleEJ1ZmZlciA9IChJV2luZUQzRFZlcnRleEJ1ZmZlciAqKW9iamVjdDsKCiAgICBvYmplY3QtPmZ2ZiA9IEZWRjsKCiAgICAvKiBPYnNlcnZhdGlvbnMgc2hvdyB0aGF0IGRyYXdTdHJpZGVkU2xvdyBpcyBmYXN0ZXIgb24gZHluYW1pYyBWQnMgdGhhbiBjb252ZXJ0aW5nICsKICAgICAqIGRyYXdTdHJpZGVkRmFzdCAoaGFsZi1saWZlIDIpLgogICAgICoKICAgICAqIEJhc2ljYWxseSBjb252ZXJ0aW5nIHRoZSB2ZXJ0aWNlcyBpbiB0aGUgYnVmZmVyIGlzIHF1aXRlIGV4cGVuc2l2ZSwgYW5kIG9ic2VydmF0aW9ucwogICAgICogc2hvdyB0aGF0IGRyYXdTdHJpZGVkU2xvdyBpcyBmYXN0ZXIgdGhhbiBjb252ZXJ0aW5nICsgdXBsb2FkaW5nICsgZHJhd1N0cmlkZWRGYXN0LgogICAgICogVGhlcmVmb3JlIGRvIG5vdCBjcmVhdGUgYSBWQk8gZm9yIFdJTkVEM0RVU0FHRV9EWU5BTUlDIGJ1ZmZlcnMuCiAgICAgKgogICAgICogRGlyZWN0M0Q3IGhhcyBhbm90aGVyIHByb2JsZW06IEl0cyB2ZXJ0ZXhidWZmZXIgYXBpIGRvZXNuJ3Qgb2ZmZXIgYSB3YXkgdG8gc3BlY2lmeQogICAgICogdGhlIHJhbmdlIG9mIHZlcnRpY2VzIGJlaW5nIGxvY2tlZCwgc28gZWFjaCBsb2NrIHdpbGwgcmVxdWlyZSB0aGUgd2hvbGUgYnVmZmVyIHRvIGJlIHRyYW5zZm9ybWVkLgogICAgICogTW9yZW92ZXIgZ2VvbWV0cnkgZGF0YSBpbiBkeDcgaXMgcXVpdGUgc2ltcGxlLCBzbyBkcmF3U3RyaWRlZFNsb3cgaXNuJ3QgYSBiaWcgaGl0LiBBIHBsdXMKICAgICAqIGlzIHRoYXQgdGhlIHZlcnRleCBidWZmZXJzIGZ2ZiBjYW4gYmUgdHJ1c3RlZCBpbiBkeDcuIFNvIG9ubHkgY3JlYXRlIG5vbi1jb252ZXJ0ZWQgdmJvcyBmb3IKICAgICAqIGR4NyBhcHBzLgogICAgICogVGhlcmUgaXMgYSBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3OjpPcHRpbWl6ZSBjYWxsIGFmdGVyIHdoaWNoIHRoZSBidWZmZXIgY2FuJ3QgYmUgbG9ja2VkIGFueQogICAgICogbW9yZS4gSW4gdGhpcyBjYWxsIHdlIGNhbiBjb252ZXJ0IGR4NyBidWZmZXJzIHRvby4KICAgICAqLwogICAgY29udiA9ICgoRlZGICYgV0lORUQzREZWRl9QT1NJVElPTl9NQVNLKSA9PSBXSU5FRDNERlZGX1hZWlJIVyApIHx8IChGVkYgJiAoV0lORUQzREZWRl9ESUZGVVNFIHwgV0lORUQzREZWRl9TUEVDVUxBUikpOwogICAgaWYoIUdMX1NVUFBPUlQoQVJCX1ZFUlRFWF9CVUZGRVJfT0JKRUNUKSkgewogICAgICAgIFRSQUNFKCJOb3QgY3JlYXRpbmcgYSB2Ym8gYmVjYXVzZSBHTF9BUkJfdmVydGV4X2J1ZmZlciBpcyBub3Qgc3VwcG9ydGVkXG4iKTsKICAgIH0gZWxzZSBpZihQb29sID09IFdJTkVEM0RQT09MX1NZU1RFTU1FTSkgewogICAgICAgIFRSQUNFKCJOb3QgY3JlYXRpbmcgYSB2Ym8gYmVjYXVzZSB0aGUgdmVydGV4IGJ1ZmZlciBpcyBpbiBzeXN0ZW0gbWVtb3J5XG4iKTsKICAgIH0gZWxzZSBpZihVc2FnZSAmIFdJTkVEM0RVU0FHRV9EWU5BTUlDKSB7CiAgICAgICAgVFJBQ0UoIk5vdCBjcmVhdGluZyBhIHZibyBiZWNhdXNlIHRoZSBidWZmZXIgaGFzIGR5bmFtaWMgdXNhZ2VcbiIpOwogICAgfSBlbHNlIGlmKGR4VmVyc2lvbiA8PSA3ICYmIGNvbnYpIHsKICAgICAgICBUUkFDRSgiTm90IGNyZWF0aW5nIGEgdmJvIGJlY2F1c2UgZHhWZXJzaW9uIGlzIDcgYW5kIHRoZSBmdmYgbmVlZHMgY29udmVyc2lvblxuIik7CiAgICB9IGVsc2UgewogICAgICAgIG9iamVjdC0+RmxhZ3MgfD0gVkJGTEFHX0NSRUFURVZCTzsKICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgdm9pZCBDcmVhdGVJbmRleEJ1ZmZlclZCTyhJV2luZUQzRERldmljZUltcGwgKlRoaXMsIElXaW5lRDNESW5kZXhCdWZmZXJJbXBsICpvYmplY3QpIHsKICAgIEdMZW51bSBlcnJvciwgZ2xVc2FnZTsKICAgIFRSQUNFKCJDcmVhdGluZyBWQk8gZm9yIEluZGV4IEJ1ZmZlciAlcFxuIiwgb2JqZWN0KTsKCiAgICAvKiBUaGUgZm9sbG93aW5nIGNvZGUgd2lsbCBtb2RpZnkgdGhlIEVMRU1FTlRfQVJSQVlfQlVGRkVSIGJpbmRpbmcsIG1ha2Ugc3VyZSBpdCBpcwogICAgICogcmVzdG9yZWQgb24gdGhlIG5leHQgZHJhdwogICAgICovCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfSU5ERVhCVUZGRVIpOwoKICAgIC8qIE1ha2Ugc3VyZSB0aGF0IGEgY29udGV4dCBpcyB0aGVyZS4gTmVlZGVkIGluIGEgbXVsdGl0aHJlYWRlZCBlbnZpcm9ubWVudC4gT3RoZXJ3aXNlIHRoaXMgY2FsbCBpcyBhIG5vcCAqLwogICAgQWN0aXZhdGVDb250ZXh0KFRoaXMsIFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQsIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CiAgICBFTlRFUl9HTCgpOwoKICAgIHdoaWxlKGdsR2V0RXJyb3IoKSk7CgogICAgR0xfRVhUQ0FMTChnbEdlbkJ1ZmZlcnNBUkIoMSwgJm9iamVjdC0+dmJvKSk7CiAgICBlcnJvciA9IGdsR2V0RXJyb3IoKTsKICAgIGlmKGVycm9yICE9IEdMX05PX0VSUk9SIHx8IG9iamVjdC0+dmJvID09IDApIHsKICAgICAgICBFUlIoIkNyZWF0aW5nIGEgdmJvIGZhaWxlZCB3aXRoIGVycm9yICVzICglI3gpLCBjb250aW51aW5nIHdpdGhvdXQgdmJvIGZvciB0aGlzIGJ1ZmZlclxuIiwgZGVidWdfZ2xlcnJvcihlcnJvciksIGVycm9yKTsKICAgICAgICBnb3RvIG91dDsKICAgIH0KCiAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUl9BUkIsIG9iamVjdC0+dmJvKSk7CiAgICBlcnJvciA9IGdsR2V0RXJyb3IoKTsKICAgIGlmKGVycm9yICE9IEdMX05PX0VSUk9SKSB7CiAgICAgICAgRVJSKCJGYWlsZWQgdG8gYmluZCBpbmRleCBidWZmZXIgd2l0aCBlcnJvciAlcyAoJSN4KSwgY29udGludWluZyB3aXRob3V0IHZibyBmb3IgdGhpcyBidWZmZXJcbiIsIGRlYnVnX2dsZXJyb3IoZXJyb3IpLCBlcnJvcik7CiAgICAgICAgZ290byBvdXQ7CiAgICB9CgogICAgLyogVXNlIHN0YXRpYyB3cml0ZSBvbmx5IHVzYWdlIGZvciBub3cuIER5bmFtaWMgaW5kZXggYnVmZmVycyBzdGF5IGluIHN5c21lbSwgYW5kIGR1ZSB0byB0aGUgc3lzbWVtCiAgICAgICAgKiBjb3B5IG5vIHJlYWRiYWNrIHdpbGwgYmUgbmVlZGVkCiAgICAgICAgKi8KICAgIGdsVXNhZ2UgPSBHTF9TVEFUSUNfRFJBV19BUkI7CiAgICBHTF9FWFRDQUxMKGdsQnVmZmVyRGF0YUFSQihHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUl9BUkIsIG9iamVjdC0+cmVzb3VyY2Uuc2l6ZSwgTlVMTCwgZ2xVc2FnZSkpOwogICAgZXJyb3IgPSBnbEdldEVycm9yKCk7CiAgICBpZihlcnJvciAhPSBHTF9OT19FUlJPUikgewogICAgICAgIEVSUigiRmFpbGVkIHRvIGluaXRpYWxpemUgdGhlIGluZGV4IGJ1ZmZlciB3aXRoIGVycm9yICVzICglI3gpXG4iLCBkZWJ1Z19nbGVycm9yKGVycm9yKSwgZXJyb3IpOwogICAgICAgIGdvdG8gb3V0OwogICAgfQogICAgTEVBVkVfR0woKTsKICAgIFRSQUNFKCJTdWNjZXNzZnVsbHkgY3JlYXRlZCB2Ym8gJWQgZm9yIGluZGV4IGJ1ZmZlciAlcFxuIiwgb2JqZWN0LT52Ym8sIG9iamVjdCk7CiAgICByZXR1cm47CgpvdXQ6CiAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9FTEVNRU5UX0FSUkFZX0JVRkZFUl9BUkIsIDApKTsKICAgIEdMX0VYVENBTEwoZ2xEZWxldGVCdWZmZXJzQVJCKDEsICZvYmplY3QtPnZibykpOwogICAgTEVBVkVfR0woKTsKICAgIG9iamVjdC0+dmJvID0gMDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVJbmRleEJ1ZmZlcihJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgTGVuZ3RoLCBEV09SRCBVc2FnZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNERk9STUFUIEZvcm1hdCwgV0lORUQzRFBPT0wgUG9vbCwgSVdpbmVEM0RJbmRleEJ1ZmZlcioqIHBwSW5kZXhCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEUgKnNoYXJlZEhhbmRsZSwgSVVua25vd24gKnBhcmVudCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RJbmRleEJ1ZmZlckltcGwgKm9iamVjdDsKICAgIFRSQUNFKCIoJXApIENyZWF0aW5nIGluZGV4IGJ1ZmZlclxuIiwgVGhpcyk7CgogICAgLyogQWxsb2NhdGUgdGhlIHN0b3JhZ2UgZm9yIHRoZSBkZXZpY2UgKi8KICAgIEQzRENSRUFURVJFU09VUkNFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LEluZGV4QnVmZmVyLFdJTkVEM0RSVFlQRV9JTkRFWEJVRkZFUiwgTGVuZ3RoKQoKICAgIGlmKFBvb2wgIT0gV0lORUQzRFBPT0xfU1lTVEVNTUVNICYmICEoVXNhZ2UgJiBXSU5FRDNEVVNBR0VfRFlOQU1JQykgJiYgR0xfU1VQUE9SVChBUkJfVkVSVEVYX0JVRkZFUl9PQkpFQ1QpKSB7CiAgICAgICAgQ3JlYXRlSW5kZXhCdWZmZXJWQk8oVGhpcywgb2JqZWN0KTsKICAgIH0KCiAgICBUUkFDRSgiKCVwKSA6IExlbj0lZCwgVXNlPSV4LCBGb3JtYXQ9KCV1LCVzKSwgUG9vbD0lZCAtIE1lbW9yeUAlcCwgSWZhY2VAJXBcbiIsIFRoaXMsIExlbmd0aCwgVXNhZ2UsIEZvcm1hdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlYnVnX2QzZGZvcm1hdChGb3JtYXQpLCBQb29sLCBvYmplY3QsIG9iamVjdC0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgICpwcEluZGV4QnVmZmVyID0gKElXaW5lRDNESW5kZXhCdWZmZXIgKikgb2JqZWN0OwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVN0YXRlQmxvY2soSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBXSU5FRDNEU1RBVEVCTE9DS1RZUEUgVHlwZSwgSVdpbmVEM0RTdGF0ZUJsb2NrKiogcHBTdGF0ZUJsb2NrLCBJVW5rbm93biAqcGFyZW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICAgICAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3RhdGVCbG9ja0ltcGwgKm9iamVjdDsKICAgIGludCBpLCBqOwogICAgSFJFU1VMVCB0ZW1wX3Jlc3VsdDsKCiAgICBEM0RDUkVBVEVPQkpFQ1RJTlNUQU5DRShvYmplY3QsIFN0YXRlQmxvY2spCiAgICBvYmplY3QtPmJsb2NrVHlwZSAgICAgPSBUeXBlOwoKICAgIGZvcihpID0gMDsgaSA8IExJR0hUTUFQX1NJWkU7IGkrKykgewogICAgICAgIGxpc3RfaW5pdCgmb2JqZWN0LT5saWdodE1hcFtpXSk7CiAgICB9CgogICAgLyogU3BlY2lhbCBjYXNlIC0gVXNlZCBkdXJpbmcgaW5pdGlhbGl6YXRpb24gdG8gcHJvZHVjZSBhIHBsYWNlaG9sZGVyIHN0YXRlYmxvY2sKICAgICAgICAgIHNvIG90aGVyIGZ1bmN0aW9ucyBjYWxsZWQgY2FuIHVwZGF0ZSBhIHN0YXRlIGJsb2NrICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICBpZiAoVHlwZSA9PSBXSU5FRDNEU0JUX0lOSVQpIHsKICAgICAgICAvKiBEb24ndCBib3RoZXIgaW5jcmVhc2luZyB0aGUgcmVmZXJlbmNlIGNvdW50IG90aGVyd2lzZSBhIGRldmljZSB3aWxsIG5ldmVyCiAgICAgICAgICAgYmUgZnJlZWQgZHVlIHRvIGNpcmN1bGFyIGRlcGVuZGVuY2llcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KICAgIAogICAgdGVtcF9yZXN1bHQgPSBhbGxvY2F0ZV9zaGFkZXJfY29uc3RhbnRzKG9iamVjdCk7CiAgICBpZiAoV0lORUQzRF9PSyAhPSB0ZW1wX3Jlc3VsdCkKICAgICAgICByZXR1cm4gdGVtcF9yZXN1bHQ7CgogICAgLyogT3RoZXJ3aXNlLCBtaWdodCBhcyB3ZWxsIHNldCB0aGUgd2hvbGUgc3RhdGUgYmxvY2sgdG8gdGhlIGFwcHJvcHJpYXRlIHZhbHVlcyAgKi8KICAgIGlmIChUaGlzLT5zdGF0ZUJsb2NrICE9IE5VTEwpCiAgICAgICAgc3RhdGVibG9ja19jb3B5KChJV2luZUQzRFN0YXRlQmxvY2sqKSBvYmplY3QsIChJV2luZUQzRFN0YXRlQmxvY2sqKSBUaGlzLT5zdGF0ZUJsb2NrKTsKICAgIGVsc2UKICAgICAgICBtZW1zZXQob2JqZWN0LT5zdHJlYW1GcmVxLCAxLCBzaXplb2Yob2JqZWN0LT5zdHJlYW1GcmVxKSk7CgogICAgLyogUmVzZXQgdGhlIHJlZiBhbmQgdHlwZSBhZnRlciBrbHVkZ2luZyBpdCAqLwogICAgb2JqZWN0LT53aW5lRDNERGV2aWNlID0gVGhpczsKICAgIG9iamVjdC0+cmVmICAgICAgICAgICA9IDE7CiAgICBvYmplY3QtPmJsb2NrVHlwZSAgICAgPSBUeXBlOwoKICAgIFRSQUNFKCJVcGRhdGluZyBjaGFuZ2VkIGZsYWdzIGFwcHJvcHJpYXRlIGZvciB0eXBlICVkXG4iLCBUeXBlKTsKCiAgICBpZiAoVHlwZSA9PSBXSU5FRDNEU0JUX0FMTCkgewoKICAgICAgICBUUkFDRSgiQUxMID0+IFByZXRlbmQgZXZlcnl0aGluZyBoYXMgY2hhbmdlZFxuIik7CiAgICAgICAgc3RhdGVibG9ja19zYXZlZHN0YXRlc19zZXQoKElXaW5lRDNEU3RhdGVCbG9jayopIG9iamVjdCwgJm9iamVjdC0+Y2hhbmdlZCwgVFJVRSk7CgogICAgICAgIC8qIExpZ2h0cyBhcmUgbm90IHBhcnQgb2YgdGhlIGNoYW5nZWQgLyBzZXQgc3RydWN0dXJlICovCiAgICAgICAgZm9yKGogPSAwOyBqIDwgTElHSFRNQVBfU0laRTsgaisrKSB7CiAgICAgICAgICAgIHN0cnVjdCBsaXN0ICplOwogICAgICAgICAgICBMSVNUX0ZPUl9FQUNIKGUsICZvYmplY3QtPmxpZ2h0TWFwW2pdKSB7CiAgICAgICAgICAgICAgICBQTElHSFRJTkZPRUwgKmxpZ2h0ID0gTElTVF9FTlRSWShlLCBQTElHSFRJTkZPRUwsIGVudHJ5KTsKICAgICAgICAgICAgICAgIGxpZ2h0LT5jaGFuZ2VkID0gVFJVRTsKICAgICAgICAgICAgICAgIGxpZ2h0LT5lbmFibGVkQ2hhbmdlZCA9IFRSVUU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yKGogPSAxOyBqIDw9IFdJTkVISUdIRVNUX1JFTkRFUl9TVEFURTsgaisrKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3JlbmRlcl9zdGF0ZXNbaiAtIDFdID0gajsKICAgICAgICB9CiAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3JlbmRlcl9zdGF0ZXMgPSBXSU5FSElHSEVTVF9SRU5ERVJfU1RBVEU7CiAgICAgICAgLyogVE9ETzogRmlsdGVyIHVudXNlZCB0cmFuc2Zvcm1zIGJldHdlZW4gVEVYVFVSRTggYW5kIFdPUkxEMD8gKi8KICAgICAgICBmb3IoaiA9IDE7IGogPD0gSElHSEVTVF9UUkFOU0ZPUk1TVEFURTsgaisrKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3RyYW5zZm9ybV9zdGF0ZXNbaiAtIDFdID0gajsKICAgICAgICB9CiAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3RyYW5zZm9ybV9zdGF0ZXMgPSBISUdIRVNUX1RSQU5TRk9STVNUQVRFOwogICAgICAgIGZvcihqID0gMDsgaiA8IEdMX0xJTUlUUyh2c2hhZGVyX2NvbnN0YW50c0YpOyBqKyspIHsKICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfdnNfY29uc3RzX2Zbal0gPSBqOwogICAgICAgIH0KICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfdnNfY29uc3RzX2YgPSBHTF9MSU1JVFModnNoYWRlcl9jb25zdGFudHNGKTsKICAgICAgICBmb3IoaiA9IDA7IGogPCBNQVhfQ09OU1RfSTsgaisrKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3ZzX2NvbnN0c19pW2pdID0gajsKICAgICAgICB9CiAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3ZzX2NvbnN0c19pID0gTUFYX0NPTlNUX0k7CiAgICAgICAgZm9yKGogPSAwOyBqIDwgTUFYX0NPTlNUX0I7IGorKykgewogICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF92c19jb25zdHNfYltqXSA9IGo7CiAgICAgICAgfQogICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF92c19jb25zdHNfYiA9IE1BWF9DT05TVF9COwogICAgICAgIGZvcihqID0gMDsgaiA8IEdMX0xJTUlUUyhwc2hhZGVyX2NvbnN0YW50c0YpOyBqKyspIHsKICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfcHNfY29uc3RzX2Zbal0gPSBqOwogICAgICAgIH0KICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfcHNfY29uc3RzX2YgPSBHTF9MSU1JVFMocHNoYWRlcl9jb25zdGFudHNGKTsKICAgICAgICBmb3IoaiA9IDA7IGogPCBNQVhfQ09OU1RfSTsgaisrKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3BzX2NvbnN0c19pW2pdID0gajsKICAgICAgICB9CiAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3BzX2NvbnN0c19pID0gTUFYX0NPTlNUX0k7CiAgICAgICAgZm9yKGogPSAwOyBqIDwgTUFYX0NPTlNUX0I7IGorKykgewogICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF9wc19jb25zdHNfYltqXSA9IGo7CiAgICAgICAgfQogICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF9wc19jb25zdHNfYiA9IE1BWF9DT05TVF9COwogICAgICAgIGZvcihpID0gMDsgaSA8IE1BWF9URVhUVVJFUzsgaSsrKSB7CiAgICAgICAgICAgIGZvcihqID0gMTsgaiA8PSBXSU5FRDNEX0hJR0hFU1RfVEVYVFVSRV9TVEFURTsgaisrKSB7CiAgICAgICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF90c3Nfc3RhdGVzW29iamVjdC0+bnVtX2NvbnRhaW5lZF90c3Nfc3RhdGVzXS5zdGFnZSA9IGk7CiAgICAgICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF90c3Nfc3RhdGVzW29iamVjdC0+bnVtX2NvbnRhaW5lZF90c3Nfc3RhdGVzXS5zdGF0ZSA9IGo7CiAgICAgICAgICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfdHNzX3N0YXRlcysrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZvcihpID0gMDsgaSA8IE1BWF9DT01CSU5FRF9TQU1QTEVSUzsgaSsrKSB7CiAgICAgICAgICAgIGZvcihqID0gMTsgaiA8PSBXSU5FRDNEX0hJR0hFU1RfU0FNUExFUl9TVEFURTsgaisrKSB7CiAgICAgICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF9zYW1wbGVyX3N0YXRlc1tvYmplY3QtPm51bV9jb250YWluZWRfc2FtcGxlcl9zdGF0ZXNdLnN0YWdlID0gaTsKICAgICAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3NhbXBsZXJfc3RhdGVzW29iamVjdC0+bnVtX2NvbnRhaW5lZF9zYW1wbGVyX3N0YXRlc10uc3RhdGUgPSBqOwogICAgICAgICAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3NhbXBsZXJfc3RhdGVzKys7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvcihpID0gMDsgaSA8IE1BWF9TVFJFQU1TOyBpKyspIHsKICAgICAgICAgICAgaWYob2JqZWN0LT5zdHJlYW1Tb3VyY2VbaV0pIHsKICAgICAgICAgICAgICAgIElXaW5lRDNEVmVydGV4QnVmZmVyX0FkZFJlZihvYmplY3QtPnN0cmVhbVNvdXJjZVtpXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYob2JqZWN0LT5wSW5kZXhEYXRhKSB7CiAgICAgICAgICAgIElXaW5lRDNESW5kZXhCdWZmZXJfQWRkUmVmKG9iamVjdC0+cEluZGV4RGF0YSk7CiAgICAgICAgfQogICAgICAgIGlmKG9iamVjdC0+dmVydGV4U2hhZGVyKSB7CiAgICAgICAgICAgIElXaW5lRDNEVmVydGV4U2hhZGVyX0FkZFJlZihvYmplY3QtPnZlcnRleFNoYWRlcik7CiAgICAgICAgfQogICAgICAgIGlmKG9iamVjdC0+cGl4ZWxTaGFkZXIpIHsKICAgICAgICAgICAgSVdpbmVEM0RQaXhlbFNoYWRlcl9BZGRSZWYob2JqZWN0LT5waXhlbFNoYWRlcik7CiAgICAgICAgfQoKICAgIH0gZWxzZSBpZiAoVHlwZSA9PSBXSU5FRDNEU0JUX1BJWEVMU1RBVEUpIHsKCiAgICAgICAgVFJBQ0UoIlBJWEVMU1RBVEUgPT4gUHJldGVuZCBhbGwgcGl4ZWwgc2hhdGVzIGhhdmUgY2hhbmdlZFxuIik7CiAgICAgICAgc3RhdGVibG9ja19zYXZlZHN0YXRlc19zZXQoKElXaW5lRDNEU3RhdGVCbG9jayopIG9iamVjdCwgJm9iamVjdC0+Y2hhbmdlZCwgRkFMU0UpOwoKICAgICAgICBvYmplY3QtPmNoYW5nZWQucGl4ZWxTaGFkZXIgPSBUUlVFOwoKICAgICAgICAvKiBQaXhlbCBTaGFkZXIgQ29uc3RhbnRzICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IEdMX0xJTUlUUyh2c2hhZGVyX2NvbnN0YW50c0YpOyArK2kpIHsKICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfcHNfY29uc3RzX2ZbaV0gPSBpOwogICAgICAgICAgICBvYmplY3QtPmNoYW5nZWQucGl4ZWxTaGFkZXJDb25zdGFudHNGW2ldID0gVFJVRTsKICAgICAgICB9CiAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3BzX2NvbnN0c19mID0gR0xfTElNSVRTKHZzaGFkZXJfY29uc3RhbnRzRik7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IE1BWF9DT05TVF9COyArK2kpIHsKICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfcHNfY29uc3RzX2JbaV0gPSBpOwogICAgICAgICAgICBvYmplY3QtPmNoYW5nZWQucGl4ZWxTaGFkZXJDb25zdGFudHNCW2ldID0gVFJVRTsKICAgICAgICB9CiAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3BzX2NvbnN0c19iID0gTUFYX0NPTlNUX0I7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IE1BWF9DT05TVF9JOyArK2kpIHsKICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfcHNfY29uc3RzX2lbaV0gPSBpOwogICAgICAgICAgICBvYmplY3QtPmNoYW5nZWQucGl4ZWxTaGFkZXJDb25zdGFudHNJW2ldID0gVFJVRTsKICAgICAgICB9CiAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3BzX2NvbnN0c19pID0gTUFYX0NPTlNUX0k7CgogICAgICAgIGZvciAoaSA9IDA7IGkgPCBOVU1fU0FWRURQSVhFTFNUQVRFU19SOyBpKyspIHsKICAgICAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnJlbmRlclN0YXRlW1NhdmVkUGl4ZWxTdGF0ZXNfUltpXV0gPSBUUlVFOwogICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF9yZW5kZXJfc3RhdGVzW2ldID0gU2F2ZWRQaXhlbFN0YXRlc19SW2ldOwogICAgICAgIH0KICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfcmVuZGVyX3N0YXRlcyA9IE5VTV9TQVZFRFBJWEVMU1RBVEVTX1I7CiAgICAgICAgZm9yIChqID0gMDsgaiA8IE1BWF9URVhUVVJFUzsgaisrKSB7CiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBOVU1fU0FWRURQSVhFTFNUQVRFU19UOyBpKyspIHsKICAgICAgICAgICAgICAgIG9iamVjdC0+Y2hhbmdlZC50ZXh0dXJlU3RhdGVbal1bU2F2ZWRQaXhlbFN0YXRlc19UW2ldXSA9IFRSVUU7CiAgICAgICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF90c3Nfc3RhdGVzW29iamVjdC0+bnVtX2NvbnRhaW5lZF90c3Nfc3RhdGVzXS5zdGFnZSA9IGo7CiAgICAgICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF90c3Nfc3RhdGVzW29iamVjdC0+bnVtX2NvbnRhaW5lZF90c3Nfc3RhdGVzXS5zdGF0ZSA9IFNhdmVkUGl4ZWxTdGF0ZXNfVFtpXTsKICAgICAgICAgICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF90c3Nfc3RhdGVzKys7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yIChqID0gMCA7IGogPCBNQVhfQ09NQklORURfU0FNUExFUlM7IGorKykgewogICAgICAgICAgICBmb3IgKGkgPTA7IGkgPCBOVU1fU0FWRURQSVhFTFNUQVRFU19TO2krKykgewogICAgICAgICAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnNhbXBsZXJTdGF0ZVtqXVtTYXZlZFBpeGVsU3RhdGVzX1NbaV1dID0gVFJVRTsKICAgICAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3NhbXBsZXJfc3RhdGVzW29iamVjdC0+bnVtX2NvbnRhaW5lZF9zYW1wbGVyX3N0YXRlc10uc3RhZ2UgPSBqOwogICAgICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfc2FtcGxlcl9zdGF0ZXNbb2JqZWN0LT5udW1fY29udGFpbmVkX3NhbXBsZXJfc3RhdGVzXS5zdGF0ZSA9IFNhdmVkUGl4ZWxTdGF0ZXNfU1tpXTsKICAgICAgICAgICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF9zYW1wbGVyX3N0YXRlcysrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmKG9iamVjdC0+cGl4ZWxTaGFkZXIpIHsKICAgICAgICAgICAgSVdpbmVEM0RQaXhlbFNoYWRlcl9BZGRSZWYob2JqZWN0LT5waXhlbFNoYWRlcik7CiAgICAgICAgfQoKICAgICAgICAvKiBQaXhlbCBzdGF0ZSBibG9ja3MgZG8gbm90IGNvbnRhaW4gdmVydGV4IGJ1ZmZlcnMuIFNldCB0aGVtIHRvIE5VTEwgdG8gYXZvaWQgd3JvbmcgcmVmY291bnRpbmcKICAgICAgICAgKiBvbiB0aGVtLiBUaGlzIG1ha2VzIHJlbGVhc2luZyB0aGUgYnVmZmVyIGVhc2llcgogICAgICAgICAqLwogICAgICAgIGZvcihpID0gMDsgaSA8IE1BWF9TVFJFQU1TOyBpKyspIHsKICAgICAgICAgICAgb2JqZWN0LT5zdHJlYW1Tb3VyY2VbaV0gPSBOVUxMOwogICAgICAgIH0KICAgICAgICBvYmplY3QtPnBJbmRleERhdGEgPSBOVUxMOwogICAgICAgIG9iamVjdC0+dmVydGV4U2hhZGVyID0gTlVMTDsKCiAgICB9IGVsc2UgaWYgKFR5cGUgPT0gV0lORUQzRFNCVF9WRVJURVhTVEFURSkgewoKICAgICAgICBUUkFDRSgiVkVSVEVYU1RBVEUgPT4gUHJldGVuZCBhbGwgdmVydGV4IHNoYXRlcyBoYXZlIGNoYW5nZWRcbiIpOwogICAgICAgIHN0YXRlYmxvY2tfc2F2ZWRzdGF0ZXNfc2V0KChJV2luZUQzRFN0YXRlQmxvY2sqKSBvYmplY3QsICZvYmplY3QtPmNoYW5nZWQsIEZBTFNFKTsKCiAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnZlcnRleFNoYWRlciA9IFRSVUU7CgogICAgICAgIC8qIFZlcnRleCBTaGFkZXIgQ29uc3RhbnRzICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IEdMX0xJTUlUUyh2c2hhZGVyX2NvbnN0YW50c0YpOyArK2kpIHsKICAgICAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnZlcnRleFNoYWRlckNvbnN0YW50c0ZbaV0gPSBUUlVFOwogICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF92c19jb25zdHNfZltpXSA9IGk7CiAgICAgICAgfQogICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF92c19jb25zdHNfZiA9IEdMX0xJTUlUUyh2c2hhZGVyX2NvbnN0YW50c0YpOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBNQVhfQ09OU1RfQjsgKytpKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y2hhbmdlZC52ZXJ0ZXhTaGFkZXJDb25zdGFudHNCW2ldID0gVFJVRTsKICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfdnNfY29uc3RzX2JbaV0gPSBpOwogICAgICAgIH0KICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfdnNfY29uc3RzX2IgPSBNQVhfQ09OU1RfQjsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgTUFYX0NPTlNUX0k7ICsraSkgewogICAgICAgICAgICBvYmplY3QtPmNoYW5nZWQudmVydGV4U2hhZGVyQ29uc3RhbnRzSVtpXSA9IFRSVUU7CiAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3ZzX2NvbnN0c19pW2ldID0gaTsKICAgICAgICB9CiAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3ZzX2NvbnN0c19pID0gTUFYX0NPTlNUX0k7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IE5VTV9TQVZFRFZFUlRFWFNUQVRFU19SOyBpKyspIHsKICAgICAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnJlbmRlclN0YXRlW1NhdmVkVmVydGV4U3RhdGVzX1JbaV1dID0gVFJVRTsKICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfcmVuZGVyX3N0YXRlc1tpXSA9IFNhdmVkVmVydGV4U3RhdGVzX1JbaV07CiAgICAgICAgfQogICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF9yZW5kZXJfc3RhdGVzID0gTlVNX1NBVkVEVkVSVEVYU1RBVEVTX1I7CiAgICAgICAgZm9yIChqID0gMDsgaiA8IE1BWF9URVhUVVJFUzsgaisrKSB7CiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBOVU1fU0FWRURWRVJURVhTVEFURVNfVDsgaSsrKSB7CiAgICAgICAgICAgICAgICBvYmplY3QtPmNoYW5nZWQudGV4dHVyZVN0YXRlW2pdW1NhdmVkVmVydGV4U3RhdGVzX1RbaV1dID0gVFJVRTsKICAgICAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3Rzc19zdGF0ZXNbb2JqZWN0LT5udW1fY29udGFpbmVkX3Rzc19zdGF0ZXNdLnN0YWdlID0gajsKICAgICAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3Rzc19zdGF0ZXNbb2JqZWN0LT5udW1fY29udGFpbmVkX3Rzc19zdGF0ZXNdLnN0YXRlID0gU2F2ZWRWZXJ0ZXhTdGF0ZXNfVFtpXTsKICAgICAgICAgICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF90c3Nfc3RhdGVzKys7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yIChqID0gMCA7IGogPCBNQVhfQ09NQklORURfU0FNUExFUlM7IGorKyl7CiAgICAgICAgICAgIGZvciAoaSA9MDsgaSA8IE5VTV9TQVZFRFZFUlRFWFNUQVRFU19TO2krKykgewogICAgICAgICAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnNhbXBsZXJTdGF0ZVtqXVtTYXZlZFZlcnRleFN0YXRlc19TW2ldXSA9IFRSVUU7CiAgICAgICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF9zYW1wbGVyX3N0YXRlc1tvYmplY3QtPm51bV9jb250YWluZWRfc2FtcGxlcl9zdGF0ZXNdLnN0YWdlID0gajsKICAgICAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3NhbXBsZXJfc3RhdGVzW29iamVjdC0+bnVtX2NvbnRhaW5lZF9zYW1wbGVyX3N0YXRlc10uc3RhdGUgPSBTYXZlZFZlcnRleFN0YXRlc19TW2ldOwogICAgICAgICAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3NhbXBsZXJfc3RhdGVzKys7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvcihqID0gMDsgaiA8IExJR0hUTUFQX1NJWkU7IGorKykgewogICAgICAgICAgICBzdHJ1Y3QgbGlzdCAqZTsKICAgICAgICAgICAgTElTVF9GT1JfRUFDSChlLCAmb2JqZWN0LT5saWdodE1hcFtqXSkgewogICAgICAgICAgICAgICAgUExJR0hUSU5GT0VMICpsaWdodCA9IExJU1RfRU5UUlkoZSwgUExJR0hUSU5GT0VMLCBlbnRyeSk7CiAgICAgICAgICAgICAgICBsaWdodC0+Y2hhbmdlZCA9IFRSVUU7CiAgICAgICAgICAgICAgICBsaWdodC0+ZW5hYmxlZENoYW5nZWQgPSBUUlVFOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3IoaSA9IDA7IGkgPCBNQVhfU1RSRUFNUzsgaSsrKSB7CiAgICAgICAgICAgIGlmKG9iamVjdC0+c3RyZWFtU291cmNlW2ldKSB7CiAgICAgICAgICAgICAgICBJV2luZUQzRFZlcnRleEJ1ZmZlcl9BZGRSZWYob2JqZWN0LT5zdHJlYW1Tb3VyY2VbaV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmKG9iamVjdC0+dmVydGV4U2hhZGVyKSB7CiAgICAgICAgICAgIElXaW5lRDNEVmVydGV4U2hhZGVyX0FkZFJlZihvYmplY3QtPnZlcnRleFNoYWRlcik7CiAgICAgICAgfQogICAgICAgIG9iamVjdC0+cEluZGV4RGF0YSA9IE5VTEw7CiAgICAgICAgb2JqZWN0LT5waXhlbFNoYWRlciA9IE5VTEw7CiAgICB9IGVsc2UgewogICAgICAgIEZJWE1FKCJVbnJlY29nbml6ZWQgc3RhdGUgYmxvY2sgdHlwZSAlZFxuIiwgVHlwZSk7CiAgICB9CgogICAgVFJBQ0UoIiglcCkgcmV0dXJuaW5nIHRva2VuIChwdHIgdG8gc3RhdGVibG9jaykgb2YgJXBcbiIsIFRoaXMsIG9iamVjdCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCk1TRE46Cltpbl0gUmVuZGVyIHRhcmdldHMgYXJlIG5vdCBsb2NrYWJsZSB1bmxlc3MgdGhlIGFwcGxpY2F0aW9uIHNwZWNpZmllcyBUUlVFIGZvciBMb2NrYWJsZS4gTm90ZSB0aGF0IGxvY2thYmxlIHJlbmRlciB0YXJnZXRzIHJlZHVjZSBwZXJmb3JtYW5jZSBvbiBzb21lIGdyYXBoaWNzIGhhcmR3YXJlLgoKRGlzY2FyZAogW2luXSBTZXQgdGhpcyBmbGFnIHRvIFRSVUUgdG8gZW5hYmxlIHotYnVmZmVyIGRpc2NhcmRpbmcsIGFuZCBGQUxTRSBvdGhlcndpc2UuIAoKSWYgdGhpcyBmbGFnIGlzIHNldCwgdGhlIGNvbnRlbnRzIG9mIHRoZSBkZXB0aCBzdGVuY2lsIGJ1ZmZlciB3aWxsIGJlIGludmFsaWQgYWZ0ZXIgY2FsbGluZyBlaXRoZXIgSURpcmVjdDNERGV2aWNlOTo6UHJlc2VudCBvciBJRGlyZWN0M0REZXZpY2U5OjpTZXREZXB0aFN0ZW5jaWxTdXJmYWNlIHdpdGggYSBkaWZmZXJlbnQgZGVwdGggc3VyZmFjZS4KCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovCiAKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlU3VyZmFjZShJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgV2lkdGgsIFVJTlQgSGVpZ2h0LCBXSU5FRDNERk9STUFUIEZvcm1hdCwgQk9PTCBMb2NrYWJsZSwgQk9PTCBEaXNjYXJkLCBVSU5UIExldmVsLCBJV2luZUQzRFN1cmZhY2UgKipwcFN1cmZhY2UsV0lORUQzRFJFU09VUkNFVFlQRSBUeXBlLCBEV09SRCBVc2FnZSwgV0lORUQzRFBPT0wgUG9vbCwgV0lORUQzRE1VTFRJU0FNUExFX1RZUEUgTXVsdGlTYW1wbGUgLERXT1JEIE11bHRpc2FtcGxlUXVhbGl0eSwgSEFORExFKiBwU2hhcmVkSGFuZGxlLCBXSU5FRDNEU1VSRlRZUEUgSW1wbCwgSVVua25vd24gKnBhcmVudCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsgICAgCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpvYmplY3Q7IC8qTk9URTogaW1wbCByZWYgYWxsb3dlZCBzaW5jZSB0aGlzIGlzIGEgY3JlYXRlIGZ1bmN0aW9uICovCiAgICB1bnNpZ25lZCBpbnQgU2l6ZSAgICAgICA9IDE7CiAgICBjb25zdCBTdGF0aWNQaXhlbEZvcm1hdERlc2MgKnRhYmxlRW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoRm9ybWF0LCBOVUxMLCBOVUxMKTsKICAgIFRSQUNFKCIoJXApIENyZWF0ZSBzdXJmYWNlXG4iLFRoaXMpOwogICAgCiAgICAvKiogRklYTUU6IENoZWNrIHJhbmdlcyBvbiB0aGUgaW5wdXRzIGFyZSB2YWxpZCAKICAgICAqIE1TRE4KICAgICAqICAgTXVsdGlzYW1wbGVRdWFsaXR5CiAgICAgKiAgICBbaW5dIFF1YWxpdHkgbGV2ZWwuIFRoZSB2YWxpZCByYW5nZSBpcyBiZXR3ZWVuIHplcm8gYW5kIG9uZSBsZXNzIHRoYW4gdGhlIGxldmVsCiAgICAgKiAgICByZXR1cm5lZCBieSBwUXVhbGl0eUxldmVscyB1c2VkIGJ5IElEaXJlY3QzRDk6OkNoZWNrRGV2aWNlTXVsdGlTYW1wbGVUeXBlLiAKICAgICAqICAgIFBhc3NpbmcgYSBsYXJnZXIgdmFsdWUgcmV0dXJucyB0aGUgZXJyb3IgV0lORUQzREVSUl9JTlZBTElEQ0FMTC4gVGhlIE11bHRpc2FtcGxlUXVhbGl0eQogICAgICogICAgdmFsdWVzIG9mIHBhaXJlZCByZW5kZXIgdGFyZ2V0cywgZGVwdGggc3RlbmNpbCBzdXJmYWNlcywgYW5kIHRoZSBNdWx0aVNhbXBsZSB0eXBlCiAgICAgKiAgICBtdXN0IGFsbCBtYXRjaC4KICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCgogICAgLyoqCiAgICAqIFRPRE86IERpc2NhcmQgTVNETgogICAgKiBbaW5dIFNldCB0aGlzIGZsYWcgdG8gVFJVRSB0byBlbmFibGUgei1idWZmZXIgZGlzY2FyZGluZywgYW5kIEZBTFNFIG90aGVyd2lzZS4KICAgICoKICAgICogSWYgdGhpcyBmbGFnIGlzIHNldCwgdGhlIGNvbnRlbnRzIG9mIHRoZSBkZXB0aCBzdGVuY2lsIGJ1ZmZlciB3aWxsIGJlCiAgICAqIGludmFsaWQgYWZ0ZXIgY2FsbGluZyBlaXRoZXIgSURpcmVjdDNERGV2aWNlOTo6UHJlc2VudCBvciAgKiBJRGlyZWN0M0REZXZpY2U5OjpTZXREZXB0aFN0ZW5jaWxTdXJmYWNlCiAgICAqIHdpdGggYSBkaWZmZXJlbnQgZGVwdGggc3VyZmFjZS4KICAgICoKICAgICpUaGlzIGZsYWcgaGFzIHRoZSBzYW1lIGJlaGF2aW9yIGFzIHRoZSBjb25zdGFudCwgRDNEUFJFU0VOVEZMQUdfRElTQ0FSRF9ERVBUSFNURU5DSUwsIGluIEQzRFBSRVNFTlRGTEFHLgogICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIGlmKE11bHRpc2FtcGxlUXVhbGl0eSA+IDApIHsKICAgICAgICBGSVhNRSgiTXVsdGlzYW1wbGVRdWFsaXR5IHNldCB0byAlZCwgc3Vic3RpdHV0aW5nIDBcbiIsIE11bHRpc2FtcGxlUXVhbGl0eSk7CiAgICAgICAgTXVsdGlzYW1wbGVRdWFsaXR5PTA7CiAgICB9CgogICAgLyoqIEZJWE1FOiBDaGVjayB0aGF0IHRoZSBmb3JtYXQgaXMgc3VwcG9ydGVkCiAgICAqICAgIGJ5IHRoZSBkZXZpY2UuCiAgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyoqIERYVG4gbWlwbWFwcyB1c2UgdGhlIHNhbWUgbnVtYmVyIG9mICdsZXZlbHMnIGRvd24gdG8gZWcuIDh4MSwgYnV0IHNpbmNlCiAgICAgKiAgaXQgaXMgYmFzZWQgYXJvdW5kIDR4NCBwaXhlbCBibG9ja3MgaXQgcmVxdWlyZXMgcGFkZGluZywgc28gYWxsb2NhdGUgZW5vdWdoCiAgICAgKiAgc3BhY2UhCiAgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgIGlmIChXSU5FRDNERk1UX1VOS05PV04gPT0gRm9ybWF0KSB7CiAgICAgICAgU2l6ZSA9IDA7CiAgICB9IGVsc2UgaWYgKEZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEpIHsKICAgICAgICAvKiBEWFQxIGlzIGhhbGYgYnl0ZSBwZXIgcGl4ZWwgKi8KICAgICAgIFNpemUgPSAoKG1heChXaWR0aCw0KSAqIHRhYmxlRW50cnktPmJwcCkgKiBtYXgoSGVpZ2h0LDQpKSA+PiAxOwoKICAgIH0gZWxzZSBpZiAoRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fCBGb3JtYXQgPT0gV0lORUQzREZNVF9EWFQzIHx8CiAgICAgICAgICAgICAgIEZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDQgfHwgRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNSkgewogICAgICAgU2l6ZSA9ICgobWF4KFdpZHRoLDQpICogdGFibGVFbnRyeS0+YnBwKSAqIG1heChIZWlnaHQsNCkpOwogICAgfSBlbHNlIHsKICAgICAgIC8qIFRoZSBwaXRjaCBpcyBhIG11bHRpcGxlIG9mIDQgYnl0ZXMgKi8KICAgICAgICBTaXplID0gKChXaWR0aCAqIHRhYmxlRW50cnktPmJwcCkgKyBUaGlzLT5zdXJmYWNlX2FsaWdubWVudCAtIDEpICYgfihUaGlzLT5zdXJmYWNlX2FsaWdubWVudCAtIDEpOwogICAgICAgU2l6ZSAqPSBIZWlnaHQ7CiAgICB9CgogICAgLyoqIENyZWF0ZSBhbmQgaW5pdGlhbGlzZSB0aGUgc3VyZmFjZSByZXNvdXJjZSAqKi8KICAgIEQzRENSRUFURVJFU09VUkNFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LFN1cmZhY2UsV0lORUQzRFJUWVBFX1NVUkZBQ0UsIFNpemUpCiAgICAvKiAiU3RhbmRhbG9uZSIgc3VyZmFjZSAqLwogICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbnRhaW5lcigoSVdpbmVEM0RTdXJmYWNlICopb2JqZWN0LCBOVUxMKTsKCiAgICBvYmplY3QtPmN1cnJlbnREZXNjLldpZHRoICAgICAgPSBXaWR0aDsKICAgIG9iamVjdC0+Y3VycmVudERlc2MuSGVpZ2h0ICAgICA9IEhlaWdodDsKICAgIG9iamVjdC0+Y3VycmVudERlc2MuTXVsdGlTYW1wbGVUeXBlICAgID0gTXVsdGlTYW1wbGU7CiAgICBvYmplY3QtPmN1cnJlbnREZXNjLk11bHRpU2FtcGxlUXVhbGl0eSA9IE11bHRpc2FtcGxlUXVhbGl0eTsKICAgIG9iamVjdC0+Z2xEZXNjcmlwdGlvbi5sZXZlbCAgICAgICAgICAgID0gTGV2ZWw7CgogICAgLyogRmxhZ3MgKi8KICAgIG9iamVjdC0+RmxhZ3MgICAgICA9IFNGTEFHX05PUk1DT09SRDsgLyogRGVmYXVsdCB0byBub3JtYWxpemVkIGNvb3JkcyAqLwogICAgb2JqZWN0LT5GbGFncyAgICAgfD0gRGlzY2FyZCA/IFNGTEFHX0RJU0NBUkQgOiAwOwogICAgb2JqZWN0LT5GbGFncyAgICAgfD0gKFdJTkVEM0RGTVRfRDE2X0xPQ0tBQkxFID09IEZvcm1hdCkgPyBTRkxBR19MT0NLQUJMRSA6IDA7CiAgICBvYmplY3QtPkZsYWdzICAgICB8PSBMb2NrYWJsZSA/IFNGTEFHX0xPQ0tBQkxFIDogMDsKCgogICAgaWYgKFdJTkVEM0RGTVRfVU5LTk9XTiAhPSBGb3JtYXQpIHsKICAgICAgICBvYmplY3QtPmJ5dGVzUGVyUGl4ZWwgPSB0YWJsZUVudHJ5LT5icHA7CiAgICB9IGVsc2UgewogICAgICAgIG9iamVjdC0+Ynl0ZXNQZXJQaXhlbCA9IDA7CiAgICB9CgogICAgLyoqIFRPRE86IGNoYW5nZSB0aGlzIGludG8gYSB0ZXh0dXJlIHRyYW5zZm9ybSBtYXRyaXggc28gdGhhdCBpdCdzIHByb2Nlc3NlZCBpbiBoYXJkd2FyZSAqKi8KCiAgICBUUkFDRSgiUG9vbCAlZCAlZCAlZCAlZFxuIixQb29sLCBXSU5FRDNEUE9PTF9ERUZBVUxULCBXSU5FRDNEUE9PTF9NQU5BR0VELCBXSU5FRDNEUE9PTF9TWVNURU1NRU0pOwoKICAgIC8qKiBRdWljayBsb2NrYWJsZSBzYW5pdHkgY2hlY2sgVE9ETzogcmVtb3ZlIHRoaXMgYWZ0ZXIgc3VyZmFjZXMsIHVzYWdlIGFuZCBsb2NrYWJpbGl0eSBoYXZlIGJlZW4gZGVidWdnZWQgcHJvcGVybHkKICAgICogdGhpcyBmdW5jdGlvbiBpcyB0b28gZGVlcCB0byBuZWVkIHRvIGNhcmUgYWJvdXQgdGhpbmdzIGxpa2UgdGhpcy4KICAgICogTGV2ZWxzIG5lZWQgdG8gYmUgY2hlY2tlZCB0b28sIGFuZCBwb3NzaWJseSBUeXBlIHNpbmNlIHRoZXkgYWxsIGFmZmVjdCB3aGF0IGNhbiBiZSBkb25lLgogICAgKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgc3dpdGNoKFBvb2wpIHsKICAgIGNhc2UgV0lORUQzRFBPT0xfU0NSQVRDSDoKICAgICAgICBpZighTG9ja2FibGUpCiAgICAgICAgICAgIEZJWE1FKCJDcmVhdGUgc3VyZmFjZSBjYWxsZWQgd2l0aCBhIHBvb2wgb2YgU0NSQVRDSCBhbmQgYSBMb2NrYWJsZSBvZiBGQUxTRSAiCiAgICAgICAgICAgICAgICAid2hpY2ggYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZSwgc2V0dGluZyBsb2NrYWJsZSB0byBUUlVFXG4iKTsKICAgICAgICAgICAgICAgIExvY2thYmxlID0gVFJVRTsKICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEUE9PTF9TWVNURU1NRU06CiAgICAgICAgaWYoIUxvY2thYmxlKSBGSVhNRSgiQ3JlYXRlIHN1cmZhY2UgY2FsbGVkIHdpdGggYSBwb29sIG9mIFNZU1RFTU1FTSBhbmQgYSBMb2NrYWJsZSBvZiBGQUxTRSwgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGhpcyBpcyBhY2NlcHRhYmxlIGJ1dCB1bmV4cGVjdGVkIChJIGNhbid0IGtub3cgaG93IHRoZSBzdXJmYWNlIGNhbiBiZSB1c2FibGUhKVxuIik7CiAgICBjYXNlIFdJTkVEM0RQT09MX01BTkFHRUQ6CiAgICAgICAgaWYoVXNhZ2UgPT0gV0lORUQzRFVTQUdFX0RZTkFNSUMpIEZJWE1FKCJDcmVhdGUgc3VyZmFjZSBjYWxsZWQgd2l0aCBhIHBvb2wgb2YgTUFOQUdFRCBhbmQgYSAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJVc2FnZSBvZiBEWU5BTUlDIHdoaWNoIGFyZSBtdXR1YWxseSBleGNsdXNpdmUsIG5vdCBkb2luZyAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhbnl0aGluZyBqdXN0IHRlbGxpbmcgeW91LlxuIik7CiAgICBicmVhazsKICAgIGNhc2UgV0lORUQzRFBPT0xfREVGQVVMVDogLypUT0RPOiBDcmVhdGUgb2Zmc2NyZWVuIHBsYWluIGNhbiBjYXVzZSB0aGlzIGNoZWNrIHRvIGZhaWwuLi4sIGZpbmQgb3V0IGlmIGl0IHNob3VsZCAqLwogICAgICAgIGlmKCEoVXNhZ2UgJiBXSU5FRDNEVVNBR0VfRFlOQU1JQykgJiYgIShVc2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpCiAgICAgICAgICAgJiYgIShVc2FnZSAmJiBXSU5FRDNEVVNBR0VfREVQVEhTVEVOQ0lMICkgJiYgTG9ja2FibGUpCiAgICAgICAgICAgIFdBUk4oIkNyZWF0aW5nIGEgc3VyZmFjZSB3aXRoIGEgUE9PTCBvZiBERUZBVUxUIHdpdGggTG9ja2FibGUgdHJ1ZSwgdGhhdCBkb2Vzbid0IHNwZWNpZnkgRFlOQU1JQyB1c2FnZS5cbiIpOwogICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAgIEZJWE1FKCIoJXApIFVua25vd24gcG9vbCAlZFxuIiwgVGhpcywgUG9vbCk7CiAgICBicmVhazsKICAgIH07CgogICAgaWYgKFVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCAmJiBQb29sICE9IFdJTkVEM0RQT09MX0RFRkFVTFQpIHsKICAgICAgICBGSVhNRSgiVHJ5aW5nIHRvIGNyZWF0ZSBhIHJlbmRlciB0YXJnZXQgdGhhdCBpc24ndCBpbiB0aGUgZGVmYXVsdCBwb29sXG4iKTsKICAgIH0KCiAgICAvKiBtYXJrIHRoZSB0ZXh0dXJlIGFzIGRpcnR5IHNvIHRoYXQgaXQgZ2V0cyBsb2FkZWQgZmlyc3QgdGltZSBhcm91bmQqLwogICAgSVdpbmVEM0RTdXJmYWNlX0FkZERpcnR5UmVjdCgqcHBTdXJmYWNlLCBOVUxMKTsKICAgIFRSQUNFKCIoJXApIDogdyglZCkgaCglZCkgZm10KCVkLCVzKSBsb2NrYWJsZSglZCkgc3VyZkAlcCwgc3VyZm1lbUAlcCwgJWQgYnl0ZXNcbiIsCiAgICAgICAgICAgVGhpcywgV2lkdGgsIEhlaWdodCwgRm9ybWF0LCBkZWJ1Z19kM2Rmb3JtYXQoRm9ybWF0KSwKICAgICAgICAgICAoV0lORUQzREZNVF9EMTZfTE9DS0FCTEUgPT0gRm9ybWF0KSwgKnBwU3VyZmFjZSwgb2JqZWN0LT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnksIG9iamVjdC0+cmVzb3VyY2Uuc2l6ZSk7CgogICAgLyogU3RvcmUgdGhlIERpcmVjdERyYXcgcHJpbWFyeSBzdXJmYWNlLiBUaGlzIGlzIHRoZSBmaXJzdCByZW5kZXJ0YXJnZXQgc3VyZmFjZSBjcmVhdGVkICovCiAgICBpZiggKFVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgJiYgKCFUaGlzLT5kZHJhd19wcmltYXJ5KSApCiAgICAgICAgVGhpcy0+ZGRyYXdfcHJpbWFyeSA9IChJV2luZUQzRFN1cmZhY2UgKikgb2JqZWN0OwoKICAgIC8qIExvb2sgYXQgdGhlIGltcGxlbWVudGF0aW9uIGFuZCBzZXQgdGhlIGNvcnJlY3QgVnRhYmxlICovCiAgICBzd2l0Y2goSW1wbCkgewogICAgICAgIGNhc2UgU1VSRkFDRV9PUEVOR0w6CiAgICAgICAgICAgIC8qIENoZWNrIGlmIGEgM0QgYWRhcHRlciBpcyBhdmFpbGFibGUgd2hlbiBjcmVhdGluZyBnbCBzdXJmYWNlcyAqLwogICAgICAgICAgICBpZighVGhpcy0+YWRhcHRlcikgewogICAgICAgICAgICAgICAgRVJSKCJPcGVuR0wgc3VyZmFjZXMgYXJlIG5vdCBhdmFpbGFibGUgd2l0aG91dCBvcGVuZ2xcbiIpOwogICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2JqZWN0LT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2JqZWN0KTsKICAgICAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX05PVEFWQUlMQUJMRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBTVVJGQUNFX0dESToKICAgICAgICAgICAgb2JqZWN0LT5scFZ0YmwgPSAmSVdpbmVHRElTdXJmYWNlX1Z0Ymw7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAvKiBUbyBiZSBzdXJlIHRvIGNhdGNoIHRoaXMgKi8KICAgICAgICAgICAgRVJSKCJVbmtub3duIHJlcXVlc3RlZCBzdXJmYWNlIGltcGxlbWVudGF0aW9uICVkIVxuIiwgSW1wbCk7CiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKChJV2luZUQzRFN1cmZhY2UgKikgb2JqZWN0KTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgbGlzdF9pbml0KCZvYmplY3QtPnJlbmRlcmJ1ZmZlcnMpOwoKICAgIC8qIENhbGwgdGhlIHByaXZhdGUgc2V0dXAgcm91dGluZSAqLwogICAgcmV0dXJuIElXaW5lRDNEU3VyZmFjZV9Qcml2YXRlU2V0dXAoIChJV2luZUQzRFN1cmZhY2UgKikgb2JqZWN0ICk7Cgp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVUZXh0dXJlKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBXaWR0aCwgVUlOVCBIZWlnaHQsIFVJTlQgTGV2ZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVXNhZ2UsIFdJTkVEM0RGT1JNQVQgRm9ybWF0LCBXSU5FRDNEUE9PTCBQb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RUZXh0dXJlKiogcHBUZXh0dXJlLCBIQU5ETEUqIHBTaGFyZWRIYW5kbGUsIElVbmtub3duICpwYXJlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RDQl9DUkVBVEVTVVJGQUNFRk4gRDNEQ0JfQ3JlYXRlU3VyZmFjZSkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEVGV4dHVyZUltcGwgKm9iamVjdDsKICAgIHVuc2lnbmVkIGludCBpOwogICAgVUlOVCB0bXBXOwogICAgVUlOVCB0bXBIOwogICAgSFJFU1VMVCBocjsKICAgIHVuc2lnbmVkIGludCBwb3cyV2lkdGg7CiAgICB1bnNpZ25lZCBpbnQgcG93MkhlaWdodDsKICAgIGNvbnN0IEdsUGl4ZWxGb3JtYXREZXNjICpnbERlc2M7CiAgICBnZXRGb3JtYXREZXNjRW50cnkoRm9ybWF0LCAmR0xJTkZPX0xPQ0FUSU9OLCAmZ2xEZXNjKTsKCiAgICBUUkFDRSgiKCVwKSA6IFdpZHRoICVkLCBIZWlnaHQgJWQsIExldmVscyAlZCwgVXNhZ2UgJSN4XG4iLCBUaGlzLCBXaWR0aCwgSGVpZ2h0LCBMZXZlbHMsIFVzYWdlKTsKICAgIFRSQUNFKCJGb3JtYXQgJSN4ICglcyksIFBvb2wgJSN4LCBwcFRleHR1cmUgJXAsIHBTaGFyZWRIYW5kbGUgJXAsIHBhcmVudCAlcFxuIiwKICAgICAgICAgICAgRm9ybWF0LCBkZWJ1Z19kM2Rmb3JtYXQoRm9ybWF0KSwgUG9vbCwgcHBUZXh0dXJlLCBwU2hhcmVkSGFuZGxlLCBwYXJlbnQpOwoKICAgIGlmKChVc2FnZSAmIChXSU5FRDNEVVNBR0VfQVVUT0dFTk1JUE1BUCB8IFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpKSA9PQogICAgICAgICAgICAgICAgKFdJTkVEM0RVU0FHRV9BVVRPR0VOTUlQTUFQIHwgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkpIHsKICAgICAgICBXQVJOKCJBcHBsaWNhdGlvbiByZXF1ZXN0cyBib3RoIEQzRFVTQUdFX0FVVE9HRU5NSVBNQVAgYW5kIEQzRFVTQUdFX1JFTkRFUlRBUkdFVCwgd2hpY2ggYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogVE9ETzogSXQgc2hvdWxkIG9ubHkgYmUgcG9zc2libGUgdG8gY3JlYXRlIHRleHR1cmVzIGZvciBmb3JtYXRzIAogICAgICAgICAgICAgdGhhdCBhcmUgcmVwb3J0ZWQgYXMgc3VwcG9ydGVkICovCiAgICBpZiAoV0lORUQzREZNVF9VTktOT1dOID49IEZvcm1hdCkgewogICAgICAgIFdBUk4oIiglcCkgOiBUZXh0dXJlIGNhbm5vdCBiZSBjcmVhdGVkIHdpdGggYSBmb3JtYXQgb2YgV0lORUQzREZNVF9VTktOT1dOXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBEM0RDUkVBVEVSRVNPVVJDRU9CSkVDVElOU1RBTkNFKG9iamVjdCwgVGV4dHVyZSwgV0lORUQzRFJUWVBFX1RFWFRVUkUsIDApOwogICAgRDNESU5JVElBTElaRUJBU0VURVhUVVJFKG9iamVjdC0+YmFzZVRleHR1cmUpOyAgICAKICAgIG9iamVjdC0+d2lkdGggID0gV2lkdGg7CiAgICBvYmplY3QtPmhlaWdodCA9IEhlaWdodDsKCiAgICBpZihnbERlc2MtPkZsYWdzICYgV0lORUQzREZNVF9GTEFHX0ZJTFRFUklORykgewogICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUubWluTWlwTG9va3VwID0gJm1pbk1pcExvb2t1cDsKICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLm1hZ0xvb2t1cCAgICA9ICZtYWdMb29rdXA7CiAgICB9IGVsc2UgewogICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUubWluTWlwTG9va3VwID0gJm1pbk1pcExvb2t1cF9ub0ZpbHRlcjsKICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLm1hZ0xvb2t1cCAgICA9ICZtYWdMb29rdXBfbm9GaWx0ZXI7CiAgICB9CgogICAgLyoqIE5vbi1wb3dlcjIgc3VwcG9ydCAqKi8KICAgIGlmIChHTF9TVVBQT1JUKEFSQl9URVhUVVJFX05PTl9QT1dFUl9PRl9UV08pKSB7CiAgICAgICAgcG93MldpZHRoID0gV2lkdGg7CiAgICAgICAgcG93MkhlaWdodCA9IEhlaWdodDsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogRmluZCB0aGUgbmVhcmVzdCBwb3cyIG1hdGNoICovCiAgICAgICAgcG93MldpZHRoID0gcG93MkhlaWdodCA9IDE7CiAgICAgICAgd2hpbGUgKHBvdzJXaWR0aCA8IFdpZHRoKSBwb3cyV2lkdGggPDw9IDE7CiAgICAgICAgd2hpbGUgKHBvdzJIZWlnaHQgPCBIZWlnaHQpIHBvdzJIZWlnaHQgPDw9IDE7CgogICAgICAgIGlmKHBvdzJXaWR0aCAhPSBXaWR0aCB8fCBwb3cySGVpZ2h0ICE9IEhlaWdodCkgewogICAgICAgICAgICBpZihMZXZlbHMgPiAxKSB7CiAgICAgICAgICAgICAgICBXQVJOKCJBdHRlbXB0ZWQgdG8gY3JlYXRlIGEgbWlwbWFwcGVkIG5wMiB0ZXh0dXJlIHdpdGhvdXQgdW5jb25kaXRpb25hbCBucDIgc3VwcG9ydFxuIik7CiAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvYmplY3QpOwogICAgICAgICAgICAgICAgKnBwVGV4dHVyZSA9IE5VTEw7CiAgICAgICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIExldmVscyA9IDE7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyoqIEZJWE1FOiBhZGQgc3VwcG9ydCBmb3IgcmVhbCBub24tcG93ZXItdHdvIGlmIGl0J3MgcHJvdmlkZWQgYnkgdGhlIHZpZGVvIGNhcmQgKiovCiAgICAvKiBQcmVjYWxjdWxhdGVkIHNjYWxpbmcgZm9yICdmYWtlZCcgbm9uIHBvd2VyIG9mIHR3byB0ZXh0dXJlIGNvb3Jkcy4KICAgICAgIFNlY29uZCBhbHNvIGRvbid0IHVzZSBBUkJfVEVYVFVSRV9SRUNUQU5HTEUgaW4gY2FzZSB0aGUgc3VyZmFjZSBmb3JtYXQgaXMgUDggYW5kIEVYVF9QQUxFVFRFRF9URVhUVVJFCiAgICAgICBpcyB1c2VkIGluIGNvbWJpbmF0aW9uIHdpdGggdGV4dHVyZSB1cGxvYWRzIChSVExfUkVBRFRFWC9SVExfVEVYVEVYKS4gVGhlIHJlYXNvbiBpcyB0aGF0IEVYVF9QQUxFVFRFRF9URVhUVVJFCiAgICAgICBkb2Vzbid0IHdvcmsgaW4gY29tYmluYXRpb24gd2l0aCBBUkJfVEVYVFVSRV9SRUNUQU5HTEUuCiAgICAqLwogICAgaWYoR0xfU1VQUE9SVChBUkJfVEVYVFVSRV9SRUNUQU5HTEUpICYmCiAgICAgICAoV2lkdGggIT0gcG93MldpZHRoIHx8IEhlaWdodCAhPSBwb3cySGVpZ2h0KSAmJgogICAgICAgISgoRm9ybWF0ID09IFdJTkVEM0RGTVRfUDgpICYmIEdMX1NVUFBPUlQoRVhUX1BBTEVUVEVEX1RFWFRVUkUpICYmICh3aW5lZDNkX3NldHRpbmdzLnJlbmRlcnRhcmdldGxvY2tfbW9kZSA9PSBSVExfUkVBRFRFWCB8fCB3aW5lZDNkX3NldHRpbmdzLnJlbmRlcnRhcmdldGxvY2tfbW9kZSA9PSBSVExfVEVYVEVYKSkpCiAgICB7CiAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5wb3cyTWF0cml4WzBdID0gIChmbG9hdClXaWR0aDsKICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLnBvdzJNYXRyaXhbNV0gPSAgKGZsb2F0KUhlaWdodDsKICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLnBvdzJNYXRyaXhbMTBdID0gMS4wOwogICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUucG93Mk1hdHJpeFsxNV0gPSAxLjA7CiAgICAgICAgb2JqZWN0LT50YXJnZXQgPSBHTF9URVhUVVJFX1JFQ1RBTkdMRV9BUkI7CiAgICB9IGVsc2UgewogICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUucG93Mk1hdHJpeFswXSA9ICAoKChmbG9hdClXaWR0aCkgIC8gKChmbG9hdClwb3cyV2lkdGgpKTsKICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLnBvdzJNYXRyaXhbNV0gPSAgKCgoZmxvYXQpSGVpZ2h0KSAvICgoZmxvYXQpcG93MkhlaWdodCkpOwogICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUucG93Mk1hdHJpeFsxMF0gPSAxLjA7CiAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5wb3cyTWF0cml4WzE1XSA9IDEuMDsKICAgICAgICBvYmplY3QtPnRhcmdldCA9IEdMX1RFWFRVUkVfMkQ7CiAgICB9CiAgICBUUkFDRSgiIHhmKCVmKSB5ZiglZilcbiIsIG9iamVjdC0+YmFzZVRleHR1cmUucG93Mk1hdHJpeFswXSwgb2JqZWN0LT5iYXNlVGV4dHVyZS5wb3cyTWF0cml4WzVdKTsKCiAgICAvKiBDYWxjdWxhdGUgbGV2ZWxzIGZvciBtaXAgbWFwcGluZyAqLwogICAgaWYgKFVzYWdlICYgV0lORUQzRFVTQUdFX0FVVE9HRU5NSVBNQVApIHsKICAgICAgICBpZighR0xfU1VQUE9SVChTR0lTX0dFTkVSQVRFX01JUE1BUCkpIHsKICAgICAgICAgICAgV0FSTigiTm8gbWlwbWFwIGdlbmVyYXRpb24gc3VwcG9ydCwgcmV0dXJuaW5nIEQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgIH0KICAgICAgICBpZihMZXZlbHMgPiAxKSB7CiAgICAgICAgICAgIFdBUk4oIkQzRFVTQUdFX0FVVE9HRU5NSVBNQVAgaXMgc2V0LCBhbmQgbGV2ZWwgY291bnQgPiAxLCByZXR1cm5pbmcgRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfQogICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzID0gMTsKICAgIH0gZWxzZSBpZiAoTGV2ZWxzID09IDApIHsKICAgICAgICBUUkFDRSgiY2FsY3VsYXRpbmcgbGV2ZWxzICVkXG4iLCBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVscyk7CiAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5sZXZlbHMrKzsKICAgICAgICB0bXBXID0gV2lkdGg7CiAgICAgICAgdG1wSCA9IEhlaWdodDsKICAgICAgICB3aGlsZSAodG1wVyA+IDEgfHwgdG1wSCA+IDEpIHsKICAgICAgICAgICAgdG1wVyA9IG1heCgxLCB0bXBXID4+IDEpOwogICAgICAgICAgICB0bXBIID0gbWF4KDEsIHRtcEggPj4gMSk7CiAgICAgICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzKys7CiAgICAgICAgfQogICAgICAgIFRSQUNFKCJDYWxjdWxhdGVkIGxldmVscyA9ICVkXG4iLCBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVscyk7CiAgICB9CgogICAgLyogR2VuZXJhdGUgYWxsIHRoZSBzdXJmYWNlcyAqLwogICAgdG1wVyA9IFdpZHRoOwogICAgdG1wSCA9IEhlaWdodDsKICAgIGZvciAoaSA9IDA7IGkgPCBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVsczsgaSsrKQogICAgewogICAgICAgIC8qIHVzZSB0aGUgY2FsbGJhY2sgdG8gY3JlYXRlIHRoZSB0ZXh0dXJlIHN1cmZhY2UgKi8KICAgICAgICBociA9IEQzRENCX0NyZWF0ZVN1cmZhY2UoVGhpcy0+cGFyZW50LCBwYXJlbnQsIHRtcFcsIHRtcEgsIEZvcm1hdCwgVXNhZ2UsIFBvb2wsIGksIFdJTkVEM0RDVUJFTUFQX0ZBQ0VfUE9TSVRJVkVfWCwgJm9iamVjdC0+c3VyZmFjZXNbaV0sTlVMTCk7CiAgICAgICAgaWYgKGhyIT0gV0lORUQzRF9PSyB8fCAoIChJV2luZUQzRFN1cmZhY2VJbXBsICopIG9iamVjdC0+c3VyZmFjZXNbaV0pLT5GbGFncyAmIFNGTEFHX09WRVJTSVpFKSB7CiAgICAgICAgICAgIEZJWE1FKCJGYWlsZWQgdG8gY3JlYXRlIHN1cmZhY2UgICVwXG4iLCBvYmplY3QpOwogICAgICAgICAgICAvKiBjbGVhbiB1cCAqLwogICAgICAgICAgICBvYmplY3QtPnN1cmZhY2VzW2ldID0gTlVMTDsKICAgICAgICAgICAgSVdpbmVEM0RUZXh0dXJlX1JlbGVhc2UoKElXaW5lRDNEVGV4dHVyZSAqKW9iamVjdCk7CgogICAgICAgICAgICAqcHBUZXh0dXJlID0gTlVMTDsKICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgICAgIH0KCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbnRhaW5lcihvYmplY3QtPnN1cmZhY2VzW2ldLCAoSVdpbmVEM0RCYXNlICopb2JqZWN0KTsKICAgICAgICBUUkFDRSgiQ3JlYXRlZCBzdXJmYWNlIGxldmVsICVkIEAgJXBcbiIsIGksIG9iamVjdC0+c3VyZmFjZXNbaV0pOwogICAgICAgIC8qIGNhbGN1bGF0ZSB0aGUgbmV4dCBtaXBtYXAgbGV2ZWwgKi8KICAgICAgICB0bXBXID0gbWF4KDEsIHRtcFcgPj4gMSk7CiAgICAgICAgdG1wSCA9IG1heCgxLCB0bXBIID4+IDEpOwogICAgfQogICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5zaGFkZXJfY29udmVyc2lvbl9ncm91cCA9IGdsRGVzYy0+Y29udmVyc2lvbl9ncm91cDsKCiAgICBUUkFDRSgiKCVwKSA6IENyZWF0ZWQgIHRleHR1cmUgJXBcbiIsIFRoaXMsIG9iamVjdCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWb2x1bWVUZXh0dXJlKElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBXaWR0aCwgVUlOVCBIZWlnaHQsIFVJTlQgRGVwdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgTGV2ZWxzLCBEV09SRCBVc2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzREZPUk1BVCBGb3JtYXQsIFdJTkVEM0RQT09MIFBvb2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEVm9sdW1lVGV4dHVyZSAqKnBwVm9sdW1lVGV4dHVyZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFICpwU2hhcmVkSGFuZGxlLCBJVW5rbm93biAqcGFyZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RDQl9DUkVBVEVWT0xVTUVGTiBEM0RDQl9DcmVhdGVWb2x1bWUpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgICAgICAgICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RWb2x1bWVUZXh0dXJlSW1wbCAqb2JqZWN0OwogICAgdW5zaWduZWQgaW50ICAgICAgICAgICAgICAgaTsKICAgIFVJTlQgICAgICAgICAgICAgICAgICAgICAgIHRtcFc7CiAgICBVSU5UICAgICAgICAgICAgICAgICAgICAgICB0bXBIOwogICAgVUlOVCAgICAgICAgICAgICAgICAgICAgICAgdG1wRDsKICAgIGNvbnN0IEdsUGl4ZWxGb3JtYXREZXNjICpnbERlc2M7CgogICAgZ2V0Rm9ybWF0RGVzY0VudHJ5KEZvcm1hdCwgJkdMSU5GT19MT0NBVElPTiwgJmdsRGVzYyk7CgogICAgLyogVE9ETzogSXQgc2hvdWxkIG9ubHkgYmUgcG9zc2libGUgdG8gY3JlYXRlIHRleHR1cmVzIGZvciBmb3JtYXRzIAogICAgICAgICAgICAgdGhhdCBhcmUgcmVwb3J0ZWQgYXMgc3VwcG9ydGVkICovCiAgICBpZiAoV0lORUQzREZNVF9VTktOT1dOID49IEZvcm1hdCkgewogICAgICAgIFdBUk4oIiglcCkgOiBUZXh0dXJlIGNhbm5vdCBiZSBjcmVhdGVkIHdpdGggYSBmb3JtYXQgb2YgV0lORUQzREZNVF9VTktOT1dOXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIGlmKCFHTF9TVVBQT1JUKEVYVF9URVhUVVJFM0QpKSB7CiAgICAgICAgV0FSTigiKCVwKSA6IFRleHR1cmUgY2Fubm90IGJlIGNyZWF0ZWQgLSBubyB2b2x1bWUgdGV4dHVyZSBzdXBwb3J0XG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBEM0RDUkVBVEVSRVNPVVJDRU9CSkVDVElOU1RBTkNFKG9iamVjdCwgVm9sdW1lVGV4dHVyZSwgV0lORUQzRFJUWVBFX1ZPTFVNRVRFWFRVUkUsIDApOwogICAgRDNESU5JVElBTElaRUJBU0VURVhUVVJFKG9iamVjdC0+YmFzZVRleHR1cmUpOwoKICAgIFRSQUNFKCIoJXApIDogVyglZCkgSCglZCkgRCglZCksIEx2bCglZCkgVXNhZ2UoJWQpLCBGbXQoJXUsJXMpLCBQb29sKCVzKVxuIiwgVGhpcywgV2lkdGgsIEhlaWdodCwKICAgICAgICAgIERlcHRoLCBMZXZlbHMsIFVzYWdlLCBGb3JtYXQsIGRlYnVnX2QzZGZvcm1hdChGb3JtYXQpLCBkZWJ1Z19kM2Rwb29sKFBvb2wpKTsKCiAgICBvYmplY3QtPndpZHRoICA9IFdpZHRoOwogICAgb2JqZWN0LT5oZWlnaHQgPSBIZWlnaHQ7CiAgICBvYmplY3QtPmRlcHRoICA9IERlcHRoOwoKICAgIC8qIElzIE5QMiBzdXBwb3J0IGZvciB2b2x1bWVzIG5lZWRlZD8gKi8KICAgIG9iamVjdC0+YmFzZVRleHR1cmUucG93Mk1hdHJpeFsgMF0gPSAxLjA7CiAgICBvYmplY3QtPmJhc2VUZXh0dXJlLnBvdzJNYXRyaXhbIDVdID0gMS4wOwogICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5wb3cyTWF0cml4WzEwXSA9IDEuMDsKICAgIG9iamVjdC0+YmFzZVRleHR1cmUucG93Mk1hdHJpeFsxNV0gPSAxLjA7CgogICAgaWYoZ2xEZXNjLT5GbGFncyAmIFdJTkVEM0RGTVRfRkxBR19GSUxURVJJTkcpIHsKICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLm1pbk1pcExvb2t1cCA9ICZtaW5NaXBMb29rdXA7CiAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5tYWdMb29rdXAgICAgPSAmbWFnTG9va3VwOwogICAgfSBlbHNlIHsKICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLm1pbk1pcExvb2t1cCA9ICZtaW5NaXBMb29rdXBfbm9GaWx0ZXI7CiAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5tYWdMb29rdXAgICAgPSAmbWFnTG9va3VwX25vRmlsdGVyOwogICAgfQoKICAgIC8qIENhbGN1bGF0ZSBsZXZlbHMgZm9yIG1pcCBtYXBwaW5nICovCiAgICBpZiAoVXNhZ2UgJiBXSU5FRDNEVVNBR0VfQVVUT0dFTk1JUE1BUCkgewogICAgICAgIGlmKCFHTF9TVVBQT1JUKFNHSVNfR0VORVJBVEVfTUlQTUFQKSkgewogICAgICAgICAgICBXQVJOKCJObyBtaXBtYXAgZ2VuZXJhdGlvbiBzdXBwb3J0LCByZXR1cm5pbmcgRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfQogICAgICAgIGlmKExldmVscyA+IDEpIHsKICAgICAgICAgICAgV0FSTigiRDNEVVNBR0VfQVVUT0dFTk1JUE1BUCBpcyBzZXQsIGFuZCBsZXZlbCBjb3VudCA+IDEsIHJldHVybmluZyBEM0RFUlJfSU5WQUxJRENBTExcbiIpOwogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICB9CiAgICAgICAgTGV2ZWxzID0gMTsKICAgIH0gZWxzZSBpZiAoTGV2ZWxzID09IDApIHsKICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVscysrOwogICAgICAgIHRtcFcgPSBXaWR0aDsKICAgICAgICB0bXBIID0gSGVpZ2h0OwogICAgICAgIHRtcEQgPSBEZXB0aDsKICAgICAgICB3aGlsZSAodG1wVyA+IDEgfHwgdG1wSCA+IDEgfHwgdG1wRCA+IDEpIHsKICAgICAgICAgICAgdG1wVyA9IG1heCgxLCB0bXBXID4+IDEpOwogICAgICAgICAgICB0bXBIID0gbWF4KDEsIHRtcEggPj4gMSk7CiAgICAgICAgICAgIHRtcEQgPSBtYXgoMSwgdG1wRCA+PiAxKTsKICAgICAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5sZXZlbHMrKzsKICAgICAgICB9CiAgICAgICAgVFJBQ0UoIkNhbGN1bGF0ZWQgbGV2ZWxzID0gJWRcbiIsIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzKTsKICAgIH0KCiAgICAvKiBHZW5lcmF0ZSBhbGwgdGhlIHN1cmZhY2VzICovCiAgICB0bXBXID0gV2lkdGg7CiAgICB0bXBIID0gSGVpZ2h0OwogICAgdG1wRCA9IERlcHRoOwoKICAgIGZvciAoaSA9IDA7IGkgPCBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVsczsgaSsrKQogICAgewogICAgICAgIEhSRVNVTFQgaHI7CiAgICAgICAgLyogQ3JlYXRlIHRoZSB2b2x1bWUgKi8KICAgICAgICBociA9IEQzRENCX0NyZWF0ZVZvbHVtZShUaGlzLT5wYXJlbnQsIHBhcmVudCwgdG1wVywgdG1wSCwgdG1wRCwgRm9ybWF0LCBQb29sLCBVc2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmb2JqZWN0LT52b2x1bWVzW2ldLCBwU2hhcmVkSGFuZGxlKTsKCiAgICAgICAgaWYoRkFJTEVEKGhyKSkgewogICAgICAgICAgICBFUlIoIkNyZWF0aW5nIGEgdm9sdW1lIGZvciB0aGUgdm9sdW1lIHRleHR1cmUgZmFpbGVkKCUwOHgpXG4iLCBocik7CiAgICAgICAgICAgIElXaW5lRDNEVm9sdW1lVGV4dHVyZV9SZWxlYXNlKChJV2luZUQzRFZvbHVtZVRleHR1cmUgKikgb2JqZWN0KTsKICAgICAgICAgICAgKnBwVm9sdW1lVGV4dHVyZSA9IE5VTEw7CiAgICAgICAgICAgIHJldHVybiBocjsKICAgICAgICB9CgogICAgICAgIC8qIFNldCBpdHMgY29udGFpbmVyIHRvIHRoaXMgb2JqZWN0ICovCiAgICAgICAgSVdpbmVEM0RWb2x1bWVfU2V0Q29udGFpbmVyKG9iamVjdC0+dm9sdW1lc1tpXSwgKElXaW5lRDNEQmFzZSAqKW9iamVjdCk7CgogICAgICAgIC8qIGNhbGN1bGF0ZSB0aGUgbmV4dCBtaXBtYXAgbGV2ZWwgKi8KICAgICAgICB0bXBXID0gbWF4KDEsIHRtcFcgPj4gMSk7CiAgICAgICAgdG1wSCA9IG1heCgxLCB0bXBIID4+IDEpOwogICAgICAgIHRtcEQgPSBtYXgoMSwgdG1wRCA+PiAxKTsKICAgIH0KICAgIG9iamVjdC0+YmFzZVRleHR1cmUuc2hhZGVyX2NvbnZlcnNpb25fZ3JvdXAgPSBnbERlc2MtPmNvbnZlcnNpb25fZ3JvdXA7CgogICAgKnBwVm9sdW1lVGV4dHVyZSA9IChJV2luZUQzRFZvbHVtZVRleHR1cmUgKikgb2JqZWN0OwogICAgVFJBQ0UoIiglcCkgOiBDcmVhdGVkIHZvbHVtZSB0ZXh0dXJlICVwXG4iLCBUaGlzLCBvYmplY3QpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVm9sdW1lKElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFdpZHRoLCBVSU5UIEhlaWdodCwgVUlOVCBEZXB0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBVc2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNERk9STUFUIEZvcm1hdCwgV0lORUQzRFBPT0wgUG9vbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFZvbHVtZSoqIHBwVm9sdW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRSogcFNoYXJlZEhhbmRsZSwgSVVua25vd24gKnBhcmVudCkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgICAgICAgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFZvbHVtZUltcGwgICAgICAgICpvYmplY3Q7IC8qKiBOT1RFOiBpbXBsIHJlZiBhbGxvd2VkIHNpbmNlIHRoaXMgaXMgYSBjcmVhdGUgZnVuY3Rpb24gKiovCiAgICBjb25zdCBTdGF0aWNQaXhlbEZvcm1hdERlc2MgKmZvcm1hdERlc2MgID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KEZvcm1hdCwgTlVMTCwgTlVMTCk7CgogICAgaWYoIUdMX1NVUFBPUlQoRVhUX1RFWFRVUkUzRCkpIHsKICAgICAgICBXQVJOKCIoJXApIDogVm9sdW1lIGNhbm5vdCBiZSBjcmVhdGVkIC0gbm8gdm9sdW1lIHRleHR1cmUgc3VwcG9ydFxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgRDNEQ1JFQVRFUkVTT1VSQ0VPQkpFQ1RJTlNUQU5DRShvYmplY3QsIFZvbHVtZSwgV0lORUQzRFJUWVBFX1ZPTFVNRSwgKChXaWR0aCAqIGZvcm1hdERlc2MtPmJwcCkgKiBIZWlnaHQgKiBEZXB0aCkpCgogICAgVFJBQ0UoIiglcCkgOiBXKCVkKSBIKCVkKSBEKCVkKSwgVXNhZ2UoJWQpLCBGbXQoJXUsJXMpLCBQb29sKCVzKVxuIiwgVGhpcywgV2lkdGgsIEhlaWdodCwKICAgICAgICAgIERlcHRoLCBVc2FnZSwgRm9ybWF0LCBkZWJ1Z19kM2Rmb3JtYXQoRm9ybWF0KSwgZGVidWdfZDNkcG9vbChQb29sKSk7CgogICAgb2JqZWN0LT5jdXJyZW50RGVzYy5XaWR0aCAgID0gV2lkdGg7CiAgICBvYmplY3QtPmN1cnJlbnREZXNjLkhlaWdodCAgPSBIZWlnaHQ7CiAgICBvYmplY3QtPmN1cnJlbnREZXNjLkRlcHRoICAgPSBEZXB0aDsKICAgIG9iamVjdC0+Ynl0ZXNQZXJQaXhlbCAgICAgICA9IGZvcm1hdERlc2MtPmJwcDsKCiAgICAvKiogTm90ZTogVm9sdW1lIHRleHR1cmVzIGNhbm5vdCBiZSBkeHRuLCBoZW5jZSBubyBuZWVkIHRvIGNoZWNrIGhlcmUgKiovCiAgICBvYmplY3QtPmxvY2thYmxlICAgICAgICAgICAgPSBUUlVFOwogICAgb2JqZWN0LT5sb2NrZWQgICAgICAgICAgICAgID0gRkFMU0U7CiAgICBtZW1zZXQoJm9iamVjdC0+bG9ja2VkQm94LCAwLCBzaXplb2YoV0lORUQzREJPWCkpOwogICAgb2JqZWN0LT5kaXJ0eSAgICAgICAgICAgICAgID0gVFJVRTsKCiAgICByZXR1cm4gSVdpbmVEM0RWb2x1bWVfQWRkRGlydHlCb3goKElXaW5lRDNEVm9sdW1lICopIG9iamVjdCwgTlVMTCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlQ3ViZVRleHR1cmUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIEVkZ2VMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIExldmVscywgRFdPUkQgVXNhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNERk9STUFUIEZvcm1hdCwgV0lORUQzRFBPT0wgUG9vbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEQ3ViZVRleHR1cmUgKipwcEN1YmVUZXh0dXJlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFICpwU2hhcmVkSGFuZGxlLCBJVW5rbm93biAqcGFyZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEQ0JfQ1JFQVRFU1VSRkFDRUZOIEQzRENCX0NyZWF0ZVN1cmZhY2UpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgICAgICAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEQ3ViZVRleHR1cmVJbXBsICpvYmplY3Q7IC8qKiBOT1RFOiBpbXBsIHJlZiBhbGxvd2VkIHNpbmNlIHRoaXMgaXMgYSBjcmVhdGUgZnVuY3Rpb24gKiovCiAgICB1bnNpZ25lZCBpbnQgICAgICAgICAgICAgaSwgajsKICAgIFVJTlQgICAgICAgICAgICAgICAgICAgICB0bXBXOwogICAgSFJFU1VMVCAgICAgICAgICAgICAgICAgIGhyOwogICAgdW5zaWduZWQgaW50IHBvdzJFZGdlTGVuZ3RoICA9IEVkZ2VMZW5ndGg7CiAgICBjb25zdCBHbFBpeGVsRm9ybWF0RGVzYyAqZ2xEZXNjOwogICAgZ2V0Rm9ybWF0RGVzY0VudHJ5KEZvcm1hdCwgJkdMSU5GT19MT0NBVElPTiwgJmdsRGVzYyk7CgogICAgaWYoKFVzYWdlICYgKFdJTkVEM0RVU0FHRV9BVVRPR0VOTUlQTUFQIHwgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkpID09CiAgICAgICAgICAgICAgICAoV0lORUQzRFVTQUdFX0FVVE9HRU5NSVBNQVAgfCBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSkgewogICAgICAgIFdBUk4oIkFwcGxpY2F0aW9uIHJlcXVlc3RzIGJvdGggRDNEVVNBR0VfQVVUT0dFTk1JUE1BUCBhbmQgRDNEVVNBR0VfUkVOREVSVEFSR0VULCB3aGljaCBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICAvKiBUT0RPOiBJdCBzaG91bGQgb25seSBiZSBwb3NzaWJsZSB0byBjcmVhdGUgdGV4dHVyZXMgZm9yIGZvcm1hdHMgCiAgICAgICAgICAgICB0aGF0IGFyZSByZXBvcnRlZCBhcyBzdXBwb3J0ZWQgKi8KICAgIGlmIChXSU5FRDNERk1UX1VOS05PV04gPj0gRm9ybWF0KSB7CiAgICAgICAgV0FSTigiKCVwKSA6IFRleHR1cmUgY2Fubm90IGJlIGNyZWF0ZWQgd2l0aCBhIGZvcm1hdCBvZiBXSU5FRDNERk1UX1VOS05PV05cbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmICghR0xfU1VQUE9SVChBUkJfVEVYVFVSRV9DVUJFX01BUCkgJiYgUG9vbCAhPSBXSU5FRDNEUE9PTF9TQ1JBVENIKSB7CiAgICAgICAgV0FSTigiKCVwKSA6IFRyaWVkIHRvIGNyZWF0ZSBub3Qgc3VwcG9ydGVkIGN1YmUgdGV4dHVyZVxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgRDNEQ1JFQVRFUkVTT1VSQ0VPQkpFQ1RJTlNUQU5DRShvYmplY3QsIEN1YmVUZXh0dXJlLCBXSU5FRDNEUlRZUEVfQ1VCRVRFWFRVUkUsIDApOwogICAgRDNESU5JVElBTElaRUJBU0VURVhUVVJFKG9iamVjdC0+YmFzZVRleHR1cmUpOwoKICAgIFRSQUNFKCIoJXApIENyZWF0ZSBDdWJlIFRleHR1cmVcbiIsIFRoaXMpOwoKICAgIC8qKiBOb24tcG93ZXIyIHN1cHBvcnQgKiovCgogICAgLyogRmluZCB0aGUgbmVhcmVzdCBwb3cyIG1hdGNoICovCiAgICBwb3cyRWRnZUxlbmd0aCA9IDE7CiAgICB3aGlsZSAocG93MkVkZ2VMZW5ndGggPCBFZGdlTGVuZ3RoKSBwb3cyRWRnZUxlbmd0aCA8PD0gMTsKCiAgICBvYmplY3QtPmVkZ2VMZW5ndGggICAgICAgICAgID0gRWRnZUxlbmd0aDsKICAgIC8qIFRPRE86IHN1cHBvcnQgZm9yIG5hdGl2ZSBub24tcG93ZXIgMiAqLwogICAgLyogUHJlY2FsY3VsYXRlZCBzY2FsaW5nIGZvciAnZmFrZWQnIG5vbiBwb3dlciBvZiB0d28gdGV4dHVyZSBjb29yZHMgKi8KICAgIG9iamVjdC0+YmFzZVRleHR1cmUucG93Mk1hdHJpeFsgMF0gPSAoKGZsb2F0KUVkZ2VMZW5ndGgpIC8gKChmbG9hdClwb3cyRWRnZUxlbmd0aCk7CiAgICBvYmplY3QtPmJhc2VUZXh0dXJlLnBvdzJNYXRyaXhbIDVdID0gKChmbG9hdClFZGdlTGVuZ3RoKSAvICgoZmxvYXQpcG93MkVkZ2VMZW5ndGgpOwogICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5wb3cyTWF0cml4WzEwXSA9ICgoZmxvYXQpRWRnZUxlbmd0aCkgLyAoKGZsb2F0KXBvdzJFZGdlTGVuZ3RoKTsKICAgIG9iamVjdC0+YmFzZVRleHR1cmUucG93Mk1hdHJpeFsxNV0gPSAxLjA7CgogICAgaWYoZ2xEZXNjLT5GbGFncyAmIFdJTkVEM0RGTVRfRkxBR19GSUxURVJJTkcpIHsKICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLm1pbk1pcExvb2t1cCA9ICZtaW5NaXBMb29rdXA7CiAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5tYWdMb29rdXAgICAgPSAmbWFnTG9va3VwOwogICAgfSBlbHNlIHsKICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLm1pbk1pcExvb2t1cCA9ICZtaW5NaXBMb29rdXBfbm9GaWx0ZXI7CiAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5tYWdMb29rdXAgICAgPSAmbWFnTG9va3VwX25vRmlsdGVyOwogICAgfQoKICAgIC8qIENhbGN1bGF0ZSBsZXZlbHMgZm9yIG1pcCBtYXBwaW5nICovCiAgICBpZiAoVXNhZ2UgJiBXSU5FRDNEVVNBR0VfQVVUT0dFTk1JUE1BUCkgewogICAgICAgIGlmKCFHTF9TVVBQT1JUKFNHSVNfR0VORVJBVEVfTUlQTUFQKSkgewogICAgICAgICAgICBXQVJOKCJObyBtaXBtYXAgZ2VuZXJhdGlvbiBzdXBwb3J0LCByZXR1cm5pbmcgRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2JqZWN0KTsKICAgICAgICAgICAgKnBwQ3ViZVRleHR1cmUgPSBOVUxMOwoKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfQogICAgICAgIGlmKExldmVscyA+IDEpIHsKICAgICAgICAgICAgV0FSTigiRDNEVVNBR0VfQVVUT0dFTk1JUE1BUCBpcyBzZXQsIGFuZCBsZXZlbCBjb3VudCA+IDEsIHJldHVybmluZyBEM0RFUlJfSU5WQUxJRENBTExcbiIpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvYmplY3QpOwogICAgICAgICAgICAqcHBDdWJlVGV4dHVyZSA9IE5VTEw7CgogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICB9CiAgICAgICAgTGV2ZWxzID0gMTsKICAgIH0gZWxzZSBpZiAoTGV2ZWxzID09IDApIHsKICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVscysrOwogICAgICAgIHRtcFcgPSBFZGdlTGVuZ3RoOwogICAgICAgIHdoaWxlICh0bXBXID4gMSkgewogICAgICAgICAgICB0bXBXID0gbWF4KDEsIHRtcFcgPj4gMSk7CiAgICAgICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzKys7CiAgICAgICAgfQogICAgICAgIFRSQUNFKCJDYWxjdWxhdGVkIGxldmVscyA9ICVkXG4iLCBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVscyk7CiAgICB9CgogICAgLyogR2VuZXJhdGUgYWxsIHRoZSBzdXJmYWNlcyAqLwogICAgdG1wVyA9IEVkZ2VMZW5ndGg7CiAgICBmb3IgKGkgPSAwOyBpIDwgb2JqZWN0LT5iYXNlVGV4dHVyZS5sZXZlbHM7IGkrKykgewoKICAgICAgICAvKiBDcmVhdGUgdGhlIDYgZmFjZXMgKi8KICAgICAgICBmb3IgKGogPSAwOyBqIDwgNjsgaisrKSB7CgogICAgICAgICAgICBocj1EM0RDQl9DcmVhdGVTdXJmYWNlKFRoaXMtPnBhcmVudCwgcGFyZW50LCB0bXBXLCB0bXBXLCBGb3JtYXQsIFVzYWdlLCBQb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgLyogTGV2ZWwgKi8sIGosICZvYmplY3QtPnN1cmZhY2VzW2pdW2ldLHBTaGFyZWRIYW5kbGUpOwoKICAgICAgICAgICAgaWYoaHIhPSBXSU5FRDNEX09LKSB7CiAgICAgICAgICAgICAgICAvKiBjbGVhbiB1cCAqLwogICAgICAgICAgICAgICAgaW50IGs7CiAgICAgICAgICAgICAgICBpbnQgbDsKICAgICAgICAgICAgICAgIGZvciAobCA9IDA7IGwgPCBqOyBsKyspIHsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShvYmplY3QtPnN1cmZhY2VzW2xdW2ldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZvciAoayA9IDA7IGsgPCBpOyBrKyspIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKGwgPSAwOyBsIDwgNjsgbCsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKG9iamVjdC0+c3VyZmFjZXNbbF1ba10pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBGSVhNRSgiKCVwKSBGYWlsZWQgdG8gY3JlYXRlIHN1cmZhY2VcbiIsb2JqZWN0KTsKICAgICAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxvYmplY3QpOwogICAgICAgICAgICAgICAgKnBwQ3ViZVRleHR1cmUgPSBOVUxMOwogICAgICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgICAgICAgICB9CiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb250YWluZXIob2JqZWN0LT5zdXJmYWNlc1tqXVtpXSwgKElXaW5lRDNEQmFzZSAqKW9iamVjdCk7CiAgICAgICAgICAgIFRSQUNFKCJDcmVhdGVkIHN1cmZhY2UgbGV2ZWwgJWQgQCAlcCxcbiIsIGksIG9iamVjdC0+c3VyZmFjZXNbal1baV0pOwogICAgICAgIH0KICAgICAgICB0bXBXID0gbWF4KDEsIHRtcFcgPj4gMSk7CiAgICB9CiAgICBvYmplY3QtPmJhc2VUZXh0dXJlLnNoYWRlcl9jb252ZXJzaW9uX2dyb3VwID0gZ2xEZXNjLT5jb252ZXJzaW9uX2dyb3VwOwoKICAgIFRSQUNFKCIoJXApIDogQ3JlYXRlZCBDdWJlIFRleHR1cmUgJXBcbiIsIFRoaXMsIG9iamVjdCk7CiAgICAqcHBDdWJlVGV4dHVyZSA9IChJV2luZUQzREN1YmVUZXh0dXJlICopIG9iamVjdDsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVF1ZXJ5KElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRFFVRVJZVFlQRSBUeXBlLCBJV2luZUQzRFF1ZXJ5ICoqcHBRdWVyeSwgSVVua25vd24qIHBhcmVudCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RRdWVyeUltcGwgKm9iamVjdDsgLypOT1RFOiBpbXBsIHJlZiBhbGxvd2VkIHNpbmNlIHRoaXMgaXMgYSBjcmVhdGUgZnVuY3Rpb24gKi8KICAgIEhSRVNVTFQgaHIgPSBXSU5FRDNERVJSX05PVEFWQUlMQUJMRTsKICAgIGNvbnN0IElXaW5lRDNEUXVlcnlWdGJsICp2dGFibGU7CgogICAgLyogSnVzdCBhIGNoZWNrIHRvIHNlZSBpZiB3ZSBzdXBwb3J0IHRoaXMgdHlwZSBvZiBxdWVyeSAqLwogICAgc3dpdGNoKFR5cGUpIHsKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9PQ0NMVVNJT046CiAgICAgICAgVFJBQ0UoIiglcCkgb2NjbHVzaW9uIHF1ZXJ5XG4iLCBUaGlzKTsKICAgICAgICBpZiAoR0xfU1VQUE9SVChBUkJfT0NDTFVTSU9OX1FVRVJZKSkKICAgICAgICAgICAgaHIgPSBXSU5FRDNEX09LOwogICAgICAgIGVsc2UKICAgICAgICAgICAgV0FSTigiVW5zdXBwb3J0ZWQgaW4gbG9jYWwgT3BlbkdMIGltcGxlbWVudGF0aW9uOiBBUkJfT0NDTFVTSU9OX1FVRVJZL05WX09DQ0xVU0lPTl9RVUVSWVxuIik7CgogICAgICAgIHZ0YWJsZSA9ICZJV2luZUQzRE9jY2x1c2lvblF1ZXJ5X1Z0Ymw7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX0VWRU5UOgogICAgICAgIGlmKCEoR0xfU1VQUE9SVChOVl9GRU5DRSkgfHwgR0xfU1VQUE9SVChBUFBMRV9GRU5DRSkgKSkgewogICAgICAgICAgICAvKiBIYWxmLUxpZmUgMiBuZWVkcyB0aGlzIHF1ZXJ5LiBJdCBkb2VzIG5vdCByZW5kZXIgdGhlIG1haW4gbWVudSBjb3JyZWN0bHkgb3RoZXJ3aXNlCiAgICAgICAgICAgICAqIFByZXRlbmQgdG8gc3VwcG9ydCBpdCwgZmFraW5nIHRoaXMgcXVlcnkgZG9lcyBub3QgZG8gbXVjaCBoYXJtIGV4Y2VwdCBwb3RlbnRpYWxseSBsb3dlcmluZyBwZXJmb3JtYW5jZQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgRklYTUUoIiglcCkgRXZlbnQgcXVlcnk6IFVuaW1wbGVtZW50ZWQsIGJ1dCBwcmV0ZW5kaW5nIHRvIGJlIHN1cHBvcnRlZFxuIiwgVGhpcyk7CiAgICAgICAgfQogICAgICAgIHZ0YWJsZSA9ICZJV2luZUQzREV2ZW50UXVlcnlfVnRibDsKICAgICAgICBociA9IFdJTkVEM0RfT0s7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1ZDQUNIRToKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9SRVNPVVJDRU1BTkFHRVI6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfVkVSVEVYU1RBVFM6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfVElNRVNUQU1QOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1RJTUVTVEFNUERJU0pPSU5UOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1RJTUVTVEFNUEZSRVE6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfUElQRUxJTkVUSU1JTkdTOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX0lOVEVSRkFDRVRJTUlOR1M6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfVkVSVEVYVElNSU5HUzoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9QSVhFTFRJTUlOR1M6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfQkFORFdJRFRIVElNSU5HUzoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9DQUNIRVVUSUxJWkFUSU9OOgogICAgZGVmYXVsdDoKICAgICAgICAvKiBVc2UgdGhlIGJhc2UgUXVlcnkgdnRhYmxlIHVudGlsIHdlIGhhdmUgYSBzcGVjaWFsIG9uZSBmb3IgZWFjaCBxdWVyeSAqLwogICAgICAgIHZ0YWJsZSA9ICZJV2luZUQzRFF1ZXJ5X1Z0Ymw7CiAgICAgICAgRklYTUUoIiglcCkgVW5oYW5kbGVkIHF1ZXJ5IHR5cGUgJWRcbiIsIFRoaXMsIFR5cGUpOwogICAgfQogICAgaWYoTlVMTCA9PSBwcFF1ZXJ5IHx8IGhyICE9IFdJTkVEM0RfT0spIHsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgRDNEQ1JFQVRFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBRdWVyeSkKICAgIG9iamVjdC0+bHBWdGJsICAgICAgID0gdnRhYmxlOwogICAgb2JqZWN0LT50eXBlICAgICAgICAgPSBUeXBlOwogICAgb2JqZWN0LT5zdGF0ZSAgICAgICAgPSBRVUVSWV9DUkVBVEVEOwogICAgLyogYWxsb2NhdGVkIHRoZSAnZXh0ZW5kZWQnIGRhdGEgYmFzZWQgb24gdGhlIHR5cGUgb2YgcXVlcnkgcmVxdWVzdGVkICovCiAgICBzd2l0Y2goVHlwZSl7CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfT0NDTFVTSU9OOgogICAgICAgIG9iamVjdC0+ZXh0ZW5kZWREYXRhID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihXaW5lUXVlcnlPY2NsdXNpb25EYXRhKSk7CiAgICAgICAgKChXaW5lUXVlcnlPY2NsdXNpb25EYXRhICopKG9iamVjdC0+ZXh0ZW5kZWREYXRhKSktPmN0eCA9IFRoaXMtPmFjdGl2ZUNvbnRleHQ7CgogICAgICAgIGlmKEdMX1NVUFBPUlQoQVJCX09DQ0xVU0lPTl9RVUVSWSkpIHsKICAgICAgICAgICAgVFJBQ0UoIiglcCkgQWxsb2NhdGluZyBkYXRhIGZvciBhbiBvY2NsdXNpb24gcXVlcnlcbiIsIFRoaXMpOwogICAgICAgICAgICBHTF9FWFRDQUxMKGdsR2VuUXVlcmllc0FSQigxLCAmKChXaW5lUXVlcnlPY2NsdXNpb25EYXRhICopKG9iamVjdC0+ZXh0ZW5kZWREYXRhKSktPnF1ZXJ5SWQpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX0VWRU5UOgogICAgICAgIG9iamVjdC0+ZXh0ZW5kZWREYXRhID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihXaW5lUXVlcnlFdmVudERhdGEpKTsKICAgICAgICAoKFdpbmVRdWVyeUV2ZW50RGF0YSAqKShvYmplY3QtPmV4dGVuZGVkRGF0YSkpLT5jdHggPSBUaGlzLT5hY3RpdmVDb250ZXh0OwoKICAgICAgICBpZihHTF9TVVBQT1JUKEFQUExFX0ZFTkNFKSkgewogICAgICAgICAgICBHTF9FWFRDQUxMKGdsR2VuRmVuY2VzQVBQTEUoMSwgJigoV2luZVF1ZXJ5RXZlbnREYXRhICopKG9iamVjdC0+ZXh0ZW5kZWREYXRhKSktPmZlbmNlSWQpKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsR2VuRmVuY2VzQVBQTEUiKTsKICAgICAgICB9IGVsc2UgaWYoR0xfU1VQUE9SVChOVl9GRU5DRSkpIHsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEdlbkZlbmNlc05WKDEsICYoKFdpbmVRdWVyeUV2ZW50RGF0YSAqKShvYmplY3QtPmV4dGVuZGVkRGF0YSkpLT5mZW5jZUlkKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEdlbkZlbmNlc05WIik7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9WQ0FDSEU6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfUkVTT1VSQ0VNQU5BR0VSOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1ZFUlRFWFNUQVRTOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1RJTUVTVEFNUDoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9USU1FU1RBTVBESVNKT0lOVDoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9USU1FU1RBTVBGUkVROgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1BJUEVMSU5FVElNSU5HUzoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9JTlRFUkZBQ0VUSU1JTkdTOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1ZFUlRFWFRJTUlOR1M6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfUElYRUxUSU1JTkdTOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX0JBTkRXSURUSFRJTUlOR1M6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfQ0FDSEVVVElMSVpBVElPTjoKICAgIGRlZmF1bHQ6CiAgICAgICAgb2JqZWN0LT5leHRlbmRlZERhdGEgPSAwOwogICAgICAgIEZJWE1FKCIoJXApIFVuaGFuZGxlZCBxdWVyeSB0eXBlICVkXG4iLFRoaXMgLCBUeXBlKTsKICAgIH0KICAgIFRSQUNFKCIoJXApIDogQ3JlYXRlZCBRdWVyeSAlcFxuIiwgVGhpcywgb2JqZWN0KTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0REZXZpY2VJbXBsX1NldHVwRnVsbHNjcmVlbldpbmRvdwogKgogKiBIZWxwZXIgZnVuY3Rpb24gdGhhdCBtb2RpZmllcyBhIEhXTkQncyBTdHlsZSBhbmQgRXhTdHlsZSBmb3IgcHJvcGVyCiAqIGZ1bGxzY3JlZW4gdXNlLgogKgogKiBQYXJhbXM6CiAqICBpZmFjZTogUG9pbnRlciB0byB0aGUgSVdpbmVEM0REZXZpY2UgaW50ZXJmYWNlCiAqICB3aW5kb3c6IFdpbmRvdyB0byBzZXR1cAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBMT05HIGZ1bGxzY3JlZW5fc3R5bGUoTE9ORyBvcmlnX3N0eWxlKSB7CiAgICBMT05HIHN0eWxlID0gb3JpZ19zdHlsZTsKICAgIHN0eWxlICY9IH5XU19DQVBUSU9OOwogICAgc3R5bGUgJj0gfldTX1RISUNLRlJBTUU7CgogICAgLyogTWFrZSBzdXJlIHRoZSB3aW5kb3cgaXMgbWFuYWdlZCwgb3RoZXJ3aXNlIHdlIHdvbid0IGdldCBrZXlib2FyZCBpbnB1dCAqLwogICAgc3R5bGUgfD0gV1NfUE9QVVAgfCBXU19TWVNNRU5VOwoKICAgIHJldHVybiBzdHlsZTsKfQoKc3RhdGljIExPTkcgZnVsbHNjcmVlbl9leFN0eWxlKExPTkcgb3JpZ19leFN0eWxlKSB7CiAgICBMT05HIGV4U3R5bGUgPSBvcmlnX2V4U3R5bGU7CgogICAgLyogRmlsdGVyIG91dCB3aW5kb3cgZGVjb3JhdGlvbnMgKi8KICAgIGV4U3R5bGUgJj0gfldTX0VYX1dJTkRPV0VER0U7CiAgICBleFN0eWxlICY9IH5XU19FWF9DTElFTlRFREdFOwoKICAgIHJldHVybiBleFN0eWxlOwp9CgpzdGF0aWMgdm9pZCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldHVwRnVsbHNjcmVlbldpbmRvdyhJV2luZUQzRERldmljZSAqaWZhY2UsIEhXTkQgd2luZG93KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgTE9ORyBzdHlsZSwgZXhTdHlsZTsKICAgIC8qIERvbid0IGRvIGFueXRoaW5nIGlmIGFuIG9yaWdpbmFsIHN0eWxlIGlzIHN0b3JlZC4KICAgICAqIFRoYXQgc2hvdWxkbid0IGhhcHBlbgogICAgICovCiAgICBUUkFDRSgiKCVwKTogU2V0dGluZyB1cCB3aW5kb3cgJXAgZm9yIGV4Y2x1c2l2ZSBtb2RlXG4iLCBUaGlzLCB3aW5kb3cpOwogICAgaWYgKFRoaXMtPnN0eWxlIHx8IFRoaXMtPmV4U3R5bGUpIHsKICAgICAgICBFUlIoIiglcCk6IFdhbnQgdG8gY2hhbmdlIHRoZSB3aW5kb3cgcGFyYW1ldGVycyBvZiBIV05EICVwLCBidXQgIgogICAgICAgICAgICAiYW5vdGhlciBzdHlsZSBpcyBzdG9yZWQgZm9yIHJlc3RvcmF0aW9uIGFmdGVyd2FyZHNcbiIsIFRoaXMsIHdpbmRvdyk7CiAgICB9CgogICAgLyogR2V0IHRoZSBwYXJhbWV0ZXJzIGFuZCBzYXZlIHRoZW0gKi8KICAgIHN0eWxlID0gR2V0V2luZG93TG9uZ1cod2luZG93LCBHV0xfU1RZTEUpOwogICAgZXhTdHlsZSA9IEdldFdpbmRvd0xvbmdXKHdpbmRvdywgR1dMX0VYU1RZTEUpOwogICAgVGhpcy0+c3R5bGUgPSBzdHlsZTsKICAgIFRoaXMtPmV4U3R5bGUgPSBleFN0eWxlOwoKICAgIHN0eWxlID0gZnVsbHNjcmVlbl9zdHlsZShzdHlsZSk7CiAgICBleFN0eWxlID0gZnVsbHNjcmVlbl9leFN0eWxlKGV4U3R5bGUpOwoKICAgIFRSQUNFKCJPbGQgc3R5bGUgd2FzICUwOHgsJTA4eCwgc2V0dGluZyB0byAlMDh4LCUwOHhcbiIsCiAgICAgICAgICBUaGlzLT5zdHlsZSwgVGhpcy0+ZXhTdHlsZSwgc3R5bGUsIGV4U3R5bGUpOwoKICAgIFNldFdpbmRvd0xvbmdXKHdpbmRvdywgR1dMX1NUWUxFLCBzdHlsZSk7CiAgICBTZXRXaW5kb3dMb25nVyh3aW5kb3csIEdXTF9FWFNUWUxFLCBleFN0eWxlKTsKCiAgICAvKiBJbmZvcm0gdGhlIHdpbmRvdyBhYm91dCB0aGUgdXBkYXRlLiAqLwogICAgU2V0V2luZG93UG9zKHdpbmRvdywgSFdORF9UT1AsIDAsIDAsCiAgICAgICAgICAgIFRoaXMtPmRkcmF3X3dpZHRoLCBUaGlzLT5kZHJhd19oZWlnaHQsIFNXUF9GUkFNRUNIQU5HRUQpOwogICAgU2hvd1dpbmRvdyh3aW5kb3csIFNXX05PUk1BTCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRERldmljZUltcGxfUmVzdG9yZVdpbmRvdwogKgogKiBIZWxwZXIgZnVuY3Rpb24gdGhhdCByZXN0b3JlcyBhIHdpbmRvd3MnIHByb3BlcnRpZXMgd2hlbiB0YWtpbmcgaXQgb3V0CiAqIG9mIGZ1bGxzY3JlZW4gbW9kZQogKgogKiBQYXJhbXM6CiAqICBpZmFjZTogUG9pbnRlciB0byB0aGUgSVdpbmVEM0REZXZpY2UgaW50ZXJmYWNlCiAqICB3aW5kb3c6IFdpbmRvdyB0byBzZXR1cAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyB2b2lkIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfUmVzdG9yZVdpbmRvdyhJV2luZUQzRERldmljZSAqaWZhY2UsIEhXTkQgd2luZG93KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBMT05HIHN0eWxlLCBleFN0eWxlOwoKICAgIC8qIFRoaXMgY291bGQgYmUgYSBERFNDTF9OT1JNQUwgLT4gRERTQ0xfTk9STUFMCiAgICAgKiBzd2l0Y2gsIGRvIG5vdGhpbmcKICAgICAqLwogICAgaWYgKCFUaGlzLT5zdHlsZSAmJiAhVGhpcy0+ZXhTdHlsZSkgcmV0dXJuOwoKICAgIFRSQUNFKCIoJXApOiBSZXN0b3Jpbmcgd2luZG93IHNldHRpbmdzIG9mIHdpbmRvdyAlcCB0byAlMDh4LCAlMDh4XG4iLAogICAgICAgICAgVGhpcywgd2luZG93LCBUaGlzLT5zdHlsZSwgVGhpcy0+ZXhTdHlsZSk7CgogICAgc3R5bGUgPSBHZXRXaW5kb3dMb25nVyh3aW5kb3csIEdXTF9TVFlMRSk7CiAgICBleFN0eWxlID0gR2V0V2luZG93TG9uZ1cod2luZG93LCBHV0xfRVhTVFlMRSk7CgogICAgLyogT25seSByZXN0b3JlIHRoZSBzdHlsZSBpZiB0aGUgYXBwbGljYXRpb24gZGlkbid0IG1vZGlmeSBpdCBkdXJpbmcgdGhlIGZ1bGxzY3JlZW4gcGhhc2UuCiAgICAgKiBTb21lIGFwcGxpY2F0aW9ucyBjaGFuZ2UgaXQgYmVmb3JlIGNhbGxpbmcgUmVzZXQoKSB3aGVuIHN3aXRjaGluZyBiZXR3ZWVuIHdpbmRvd2VkIGFuZAogICAgICogZnVsbHNjcmVlbiBtb2RlcyhITDIpLCBzb21lIGRlcGVuZCBvbiB0aGUgb3JpZ2luYWwgc3R5bGUoRXZlIE9ubGluZSkKICAgICAqLwogICAgaWYoc3R5bGUgPT0gZnVsbHNjcmVlbl9zdHlsZShUaGlzLT5zdHlsZSkgJiYKICAgICAgIGV4U3R5bGUgPT0gZnVsbHNjcmVlbl9zdHlsZShUaGlzLT5leFN0eWxlKSkgewogICAgICAgIFNldFdpbmRvd0xvbmdXKHdpbmRvdywgR1dMX1NUWUxFLCBUaGlzLT5zdHlsZSk7CiAgICAgICAgU2V0V2luZG93TG9uZ1cod2luZG93LCBHV0xfRVhTVFlMRSwgVGhpcy0+ZXhTdHlsZSk7CiAgICB9CgogICAgLyogRGVsZXRlIHRoZSBvbGQgdmFsdWVzICovCiAgICBUaGlzLT5zdHlsZSA9IDA7CiAgICBUaGlzLT5leFN0eWxlID0gMDsKCiAgICAvKiBJbmZvcm0gdGhlIHdpbmRvdyBhYm91dCB0aGUgdXBkYXRlICovCiAgICBTZXRXaW5kb3dQb3Mod2luZG93LCAwIC8qIEluc2VydEFmdGVyLCBpZ25vcmVkICovLAogICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsIC8qIFBvcywgU2l6ZSwgaWdub3JlZCAqLwogICAgICAgICAgICAgICAgIFNXUF9GUkFNRUNIQU5HRUQgfCBTV1BfTk9NT1ZFIHwgU1dQX05PU0laRSB8IFNXUF9OT1pPUkRFUik7Cn0KCi8qIGV4YW1wbGUgYXQgaHR0cDovL3d3dy5mYWlyeWVuZ2luZS5jb20vYXJ0aWNsZXMvZHhtdWx0aXZpZXdzLmh0bSAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZUFkZGl0aW9uYWxTd2FwQ2hhaW4oSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBXSU5FRDNEUFJFU0VOVF9QQVJBTUVURVJTKiAgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3dhcENoYWluKiogcHBTd2FwQ2hhaW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElVbmtub3duKiBwYXJlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRENCX0NSRUFURVJFTkRFUlRBUkdFVEZOIEQzRENCX0NyZWF0ZVJlbmRlclRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEQ0JfQ1JFQVRFREVQVEhTVEVOQ0lMU1VSRkFDRUZOIEQzRENCX0NyZWF0ZURlcHRoU3RlbmNpbCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICAgICAgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgSERDICAgICAgICAgICAgICAgICAgICAgaERjOwogICAgSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICAqb2JqZWN0OyAvKiogTk9URTogaW1wbCByZWYgYWxsb3dlZCBzaW5jZSB0aGlzIGlzIGEgY3JlYXRlIGZ1bmN0aW9uICoqLwogICAgSFJFU1VMVCAgICAgICAgICAgICAgICAgaHIgPSBXSU5FRDNEX09LOwogICAgSVVua25vd24gICAgICAgICAgICAgICAqYnVmZmVyUGFyZW50OwogICAgQk9PTCAgICAgICAgICAgICAgICAgICAgZGlzcGxheW1vZGVfc2V0ID0gRkFMU0U7CiAgICBXSU5FRDNERElTUExBWU1PREUgICAgICBNb2RlOwogICAgY29uc3QgU3RhdGljUGl4ZWxGb3JtYXREZXNjICpmb3JtYXREZXNjOwoKICAgIFRSQUNFKCIoJXApIDogQ3JlYXRlZCBBZGRpdGlvbmFsIFN3YXAgQ2hhaW5cbiIsIFRoaXMpOwoKICAgLyoqIEZJWE1FOiBUZXN0IHVuZGVyIHdpbmRvd3MgdG8gZmluZCBvdXQgd2hhdCB0aGUgbGlmZSBjeWNsZSBvZiBhIHN3YXAgY2hhaW4gaXMsCiAgICogZG9lcyBhIGRldmljZSBob2xkIGEgcmVmZXJlbmNlIHRvIGEgc3dhcCBjaGFpbiBnaXZpbmcgdGhlbSBhIGxpZmV0aW1lIG9mIHRoZSBkZXZpY2UKICAgKiBvciBkb2VzIHRoZSBzd2FwIGNoYWluIG5vdGlmeSB0aGUgZGV2aWNlIG9mIGl0cyBkZXN0cnVjdGlvbi4KICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyogQ2hlY2sgdGhlIHBhcmFtcyAqLwogICAgaWYocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJDb3VudCA+IFdJTkVEM0RQUkVTRU5UX0JBQ0tfQlVGRkVSX01BWCkgewogICAgICAgIEVSUigiQXBwIHJlcXVlc3RlZCAlZCBiYWNrIGJ1ZmZlcnMsIHRoaXMgaXMgbm90IHN1cHBvcnRlZCBmb3Igbm93XG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckNvdW50KTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0gZWxzZSBpZiAocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJDb3VudCA+IDEpIHsKICAgICAgICBGSVhNRSgiVGhlIGFwcCByZXF1ZXN0cyBtb3JlIHRoYW4gb25lIGJhY2sgYnVmZmVyLCB0aGlzIGNhbid0IGJlIHN1cHBvcnRlZCBwcm9wZXJseS4gUGxlYXNlIGNvbmZpZ3VyZSB0aGUgYXBwbGljYXRpb24gdG8gdXNlIGRvdWJsZSBidWZmZXJpbmcoPTEgYmFjayBidWZmZXIpIGlmIHBvc3NpYmxlXG4iKTsKICAgIH0KCiAgICBEM0RDUkVBVEVPQkpFQ1RJTlNUQU5DRShvYmplY3QsIFN3YXBDaGFpbikKCiAgICAvKioqKioqKioqKioqKioqKioqKioqCiAgICAqIExvb2t1cCB0aGUgd2luZG93IEhhbmRsZSBhbmQgdGhlIHJlbGF0aW5nIFggd2luZG93IGhhbmRsZQogICAgKioqKioqKioqKioqKioqKioqKiovCgogICAgLyogU2V0dXAgaHduZCB3ZSBhcmUgdXNpbmcsIHBsdXMgd2hpY2ggZGlzcGxheSB0aGlzIGVxdWF0ZXMgdG8gKi8KICAgIG9iamVjdC0+d2luX2hhbmRsZSA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5oRGV2aWNlV2luZG93OwogICAgaWYgKCFvYmplY3QtPndpbl9oYW5kbGUpIHsKICAgICAgICBvYmplY3QtPndpbl9oYW5kbGUgPSBUaGlzLT5jcmVhdGVQYXJtcy5oRm9jdXNXaW5kb3c7CiAgICB9CiAgICBpZighVGhpcy0+ZGRyYXdfd2luZG93KSBJV2luZUQzRERldmljZV9TZXRIV05EKGlmYWNlLCBvYmplY3QtPndpbl9oYW5kbGUpOwoKICAgIGhEYyAgICAgICAgICAgICAgICA9IEdldERDKG9iamVjdC0+d2luX2hhbmRsZSk7CiAgICBUUkFDRSgiVXNpbmcgaERjICVwXG4iLCBoRGMpOwoKICAgIGlmIChOVUxMID09IGhEYykgewogICAgICAgIFdBUk4oIkZhaWxlZCB0byBnZXQgYSBIRGMgZm9yIFdpbmRvdyAlcFxuIiwgb2JqZWN0LT53aW5faGFuZGxlKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9OT1RBVkFJTEFCTEU7CiAgICB9CgogICAgLyogR2V0IGluZm8gb24gdGhlIGN1cnJlbnQgZGlzcGxheSBzZXR1cCAqLwogICAgSVdpbmVEM0RfR2V0QWRhcHRlckRpc3BsYXlNb2RlKFRoaXMtPndpbmVEM0QsIFRoaXMtPmFkYXB0ZXItPm51bSwgJk1vZGUpOwogICAgb2JqZWN0LT5vcmlnX3dpZHRoID0gTW9kZS5XaWR0aDsKICAgIG9iamVjdC0+b3JpZ19oZWlnaHQgPSBNb2RlLkhlaWdodDsKICAgIG9iamVjdC0+b3JpZ19mbXQgPSBNb2RlLkZvcm1hdDsKICAgIGZvcm1hdERlc2MgID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KE1vZGUuRm9ybWF0LCBOVUxMLCBOVUxMKTsKCiAgICAvKiogTVNETjogSWYgV2luZG93ZWQgaXMgVFJVRSBhbmQgZWl0aGVyIG9mIHRoZSBCYWNrQnVmZmVyV2lkdGgvSGVpZ2h0IHZhbHVlcyBpcyB6ZXJvLAogICAgICogIHRoZW4gdGhlIGNvcnJlc3BvbmRpbmcgZGltZW5zaW9uIG9mIHRoZSBjbGllbnQgYXJlYSBvZiB0aGUgaERldmljZVdpbmRvdwogICAgICogIChvciB0aGUgZm9jdXMgd2luZG93LCBpZiBoRGV2aWNlV2luZG93IGlzIE5VTEwpIGlzIHRha2VuLgogICAgICAqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIGlmIChwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+V2luZG93ZWQgJiYKICAgICAgICAoKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGggPT0gMCkgfHwKICAgICAgICAgKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0ID09IDApIHx8CiAgICAgICAgIChwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckZvcm1hdCA9PSBXSU5FRDNERk1UX1VOS05PV04pKSkgewoKICAgICAgICBSRUNUIFJlY3Q7CiAgICAgICAgR2V0Q2xpZW50UmVjdChvYmplY3QtPndpbl9oYW5kbGUsICZSZWN0KTsKCiAgICAgICAgaWYgKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGggPT0gMCkgewogICAgICAgICAgIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGggPSBSZWN0LnJpZ2h0OwogICAgICAgICAgIFRSQUNFKCJVcGRhdGluZyB3aWR0aCB0byAlZFxuIiwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aCk7CiAgICAgICAgfQogICAgICAgIGlmIChwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodCA9PSAwKSB7CiAgICAgICAgICAgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQgPSBSZWN0LmJvdHRvbTsKICAgICAgICAgICBUUkFDRSgiVXBkYXRpbmcgaGVpZ2h0IHRvICVkXG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodCk7CiAgICAgICAgfQogICAgICAgIGlmIChwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckZvcm1hdCA9PSBXSU5FRDNERk1UX1VOS05PV04pIHsKICAgICAgICAgICBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckZvcm1hdCA9IG9iamVjdC0+b3JpZ19mbXQ7CiAgICAgICAgICAgVFJBQ0UoIlVwZGF0aW5nIGZvcm1hdCB0byAlc1xuIiwgZGVidWdfZDNkZm9ybWF0KG9iamVjdC0+b3JpZ19mbXQpKTsKICAgICAgICB9CiAgICB9CgogICAgLyogUHV0IHRoZSBjb3JyZWN0IGZpZ3VyZXMgaW4gdGhlIHByZXNlbnRhdGlvbiBwYXJhbWV0ZXJzICovCiAgICBUUkFDRSgiQ29weWluZyBhY3Jvc3MgcHJlc2VudGF0aW9uIHBhcmFtZXRlcnNcbiIpOwogICAgb2JqZWN0LT5wcmVzZW50UGFybXMgPSAqcFByZXNlbnRhdGlvblBhcmFtZXRlcnM7CgogICAgVFJBQ0UoImNhbGxpbmcgcmVuZGVydGFyZ2V0IENCXG4iKTsKICAgIGhyID0gRDNEQ0JfQ3JlYXRlUmVuZGVyVGFyZ2V0KFRoaXMtPnBhcmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlcldpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJIZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5NdWx0aVNhbXBsZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuTXVsdGlTYW1wbGVRdWFsaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgLyogTG9ja2FibGUgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm9iamVjdC0+ZnJvbnRCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCAvKiBwU2hhcmVkIChhbHdheXMgbnVsbCkqLyk7CiAgICBpZiAob2JqZWN0LT5mcm9udEJ1ZmZlciAhPSBOVUxMKSB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbnRhaW5lcihvYmplY3QtPmZyb250QnVmZmVyLCAoSVdpbmVEM0RCYXNlICopb2JqZWN0KTsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfTW9kaWZ5TG9jYXRpb24ob2JqZWN0LT5mcm9udEJ1ZmZlciwgU0ZMQUdfSU5EUkFXQUJMRSwgVFJVRSk7CiAgICB9IGVsc2UgewogICAgICAgIEVSUigiRmFpbGVkIHRvIGNyZWF0ZSB0aGUgZnJvbnQgYnVmZmVyXG4iKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgLyoqKioqKioqKioqKioqKioqKioqKgogICAqIFdpbmRvd2VkIC8gRnVsbHNjcmVlbgogICAqKioqKioqKioqKioqKioqKioqLwoKICAgLyoqCiAgICogVE9ETzogTVNETiBzYXlzIHRoYXQgd2UgYXJlIG9ubHkgYWxsb3dlZCBvbmUgZnVsbHNjcmVlbiBzd2FwY2hhaW4gcGVyIGRldmljZSwKICAgKiBzbyB3ZSBzaG91bGQgcmVhbGx5IGNoZWNrIHRvIHNlZSBpZiB0aGVyZSBpcyBhIGZ1bGxzY3JlZW4gc3dhcGNoYWluIGFscmVhZHkKICAgKiBJIHRoaW5rIFdpbmRvd3MgYW5kIFggaGF2ZSBkaWZmZXJlbnQgaWRlYXMgYWJvdXQgZnVsbHNjcmVlbiwgZG9lcyBhIHNpbmdsZSBoZWFkIGNvdW50IGFzIGZ1bGwgc2NyZWVuPwogICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICBpZiAoIXBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5XaW5kb3dlZCkgewogICAgICAgIFdJTkVEM0RESVNQTEFZTU9ERSBtb2RlOwoKCiAgICAgICAgLyogQ2hhbmdlIHRoZSBkaXNwbGF5IHNldHRpbmdzICovCiAgICAgICAgbW9kZS5XaWR0aCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGg7CiAgICAgICAgbW9kZS5IZWlnaHQgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodDsKICAgICAgICBtb2RlLkZvcm1hdCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyRm9ybWF0OwogICAgICAgIG1vZGUuUmVmcmVzaFJhdGUgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+RnVsbFNjcmVlbl9SZWZyZXNoUmF0ZUluSHo7CgogICAgICAgIElXaW5lRDNERGV2aWNlX1NldERpc3BsYXlNb2RlKGlmYWNlLCAwLCAmbW9kZSk7CiAgICAgICAgZGlzcGxheW1vZGVfc2V0ID0gVFJVRTsKICAgICAgICBJV2luZUQzRERldmljZV9TZXRGdWxsc2NyZWVuKGlmYWNlLCBUUlVFKTsKICAgIH0KCiAgICAgICAgLyoqCiAgICAgKiBDcmVhdGUgYW4gb3BlbmdsIGNvbnRleHQgZm9yIHRoZSBkaXNwbGF5IHZpc3VhbAogICAgICogIE5PVEU6IHRoZSB2aXN1YWwgaXMgY2hvc2VuIGFzIHRoZSB3aW5kb3cgaXMgY3JlYXRlZCBhbmQgdGhlIGdsY29udGV4dCBjYW5ub3QKICAgICAqICAgICB1c2UgZGlmZmVyZW50IHByb3BlcnRpZXMgYWZ0ZXIgdGhhdCBwb2ludCBpbiB0aW1lLiBGSVhNRTogSG93IHRvIGhhbmRsZSB3aGVuIHJlcXVlc3RlZCBmb3JtYXQKICAgICAqICAgICBkb2Vzbid0IG1hdGNoIGFjdHVhbCB2aXN1YWw/IENhbm5vdCBjaG9vc2Ugb25lIGhlcmUgLSBjb2RlIHJlbW92ZWQgYXMgaXQgT05MWSB3b3JrcyBpZiB0aGUgb25lCiAgICAgKiAgICAgaXQgY2hvb3NlcyBpcyBpZGVudGljYWwgdG8gdGhlIG9uZSBhbHJlYWR5IGJlaW5nIHVzZWQhCiAgICAgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAgICAvKiogRklYTUU6IEhhbmRsZSBzdGVuY2lsIGFwcHJvcHJpYXRlbHkgdmlhIEVuYWJsZUF1dG9EZXB0aFN0ZW5jaWwgLyBBdXRvRGVwdGhTdGVuY2lsRm9ybWF0ICoqLwoKICAgIG9iamVjdC0+Y29udGV4dCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2Yob2JqZWN0LT5jb250ZXh0KSk7CiAgICBpZighb2JqZWN0LT5jb250ZXh0KQogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwogICAgb2JqZWN0LT5udW1fY29udGV4dHMgPSAxOwoKICAgIG9iamVjdC0+Y29udGV4dFswXSA9IENyZWF0ZUNvbnRleHQoVGhpcywgKElXaW5lRDNEU3VyZmFjZUltcGwgKikgb2JqZWN0LT5mcm9udEJ1ZmZlciwgb2JqZWN0LT53aW5faGFuZGxlLCBGQUxTRSAvKiBwYnVmZmVyICovLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycyk7CiAgICBpZiAoIW9iamVjdC0+Y29udGV4dFswXSkgewogICAgICAgIEVSUigiRmFpbGVkIHRvIGNyZWF0ZSBhIG5ldyBjb250ZXh0XG4iKTsKICAgICAgICBociA9IFdJTkVEM0RFUlJfTk9UQVZBSUxBQkxFOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9IGVsc2UgewogICAgICAgIFRSQUNFKCJDb250ZXh0IGNyZWF0ZWQgKEhXTkQ9JXAsIGdsQ29udGV4dD0lcClcbiIsCiAgICAgICAgICAgICAgb2JqZWN0LT53aW5faGFuZGxlLCBvYmplY3QtPmNvbnRleHRbMF0tPmdsQ3R4KTsKICAgIH0KCiAgIC8qKioqKioqKioqKioqKioqKioqKioKICAgKiBDcmVhdGUgdGhlIGJhY2ssIGZyb250IGFuZCBzdGVuY2lsIGJ1ZmZlcnMKICAgKioqKioqKioqKioqKioqKioqKi8KICAgIGlmKG9iamVjdC0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJDb3VudCA+IDApIHsKICAgICAgICBpbnQgaTsKCiAgICAgICAgb2JqZWN0LT5iYWNrQnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihJV2luZUQzRFN1cmZhY2UgKikgKiBvYmplY3QtPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyQ291bnQpOwogICAgICAgIGlmKCFvYmplY3QtPmJhY2tCdWZmZXIpIHsKICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5XG4iKTsKICAgICAgICAgICAgaHIgPSBFX09VVE9GTUVNT1JZOwogICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgIH0KCiAgICAgICAgZm9yKGkgPSAwOyBpIDwgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckNvdW50OyBpKyspIHsKICAgICAgICAgICAgVFJBQ0UoImNhbGxpbmcgcmVuZGVydGFyZ2V0IENCXG4iKTsKICAgICAgICAgICAgaHIgPSBEM0RDQl9DcmVhdGVSZW5kZXJUYXJnZXQoVGhpcy0+cGFyZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuTXVsdGlTYW1wbGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5NdWx0aVNhbXBsZVF1YWxpdHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgLyogTG9ja2FibGUgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZvYmplY3QtPmJhY2tCdWZmZXJbaV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwgLyogcFNoYXJlZCAoYWx3YXlzIG51bGwpKi8pOwogICAgICAgICAgICBpZihociA9PSBXSU5FRDNEX09LICYmIG9iamVjdC0+YmFja0J1ZmZlcltpXSkgewogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbnRhaW5lcihvYmplY3QtPmJhY2tCdWZmZXJbaV0sIChJV2luZUQzREJhc2UgKilvYmplY3QpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgRVJSKCJDYW5ub3QgY3JlYXRlIG5ldyBiYWNrIGJ1ZmZlclxuIik7CiAgICAgICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcihHTF9CQUNLKSIpOwogICAgICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgb2JqZWN0LT5iYWNrQnVmZmVyID0gTlVMTDsKCiAgICAgICAgLyogU2luZ2xlIGJ1ZmZlcmluZyAtIGRyYXcgdG8gZnJvbnQgYnVmZmVyICovCiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICBnbERyYXdCdWZmZXIoR0xfRlJPTlQpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoR0xfRlJPTlQpIik7CiAgICAgICAgTEVBVkVfR0woKTsKICAgIH0KCiAgICAvKiBVbmRlciBkaXJlY3RYIHN3YXBjaGFpbnMgc2hhcmUgdGhlIGRlcHRoIHN0ZW5jaWwsIHNvIG9ubHkgY3JlYXRlIG9uZSBkZXB0aC1zdGVuY2lsICovCiAgICBpZiAocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkVuYWJsZUF1dG9EZXB0aFN0ZW5jaWwgJiYgaHIgPT0gV0lORUQzRF9PSykgewogICAgICAgIFRSQUNFKCJDcmVhdGluZyBkZXB0aCBzdGVuY2lsIGJ1ZmZlclxuIik7CiAgICAgICAgaWYgKFRoaXMtPmF1dG9fZGVwdGhfc3RlbmNpbF9idWZmZXIgPT0gTlVMTCApIHsKICAgICAgICAgICAgaHIgPSBEM0RDQl9DcmVhdGVEZXB0aFN0ZW5jaWwoVGhpcy0+cGFyZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuQXV0b0RlcHRoU3RlbmNpbEZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuTXVsdGlTYW1wbGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5NdWx0aVNhbXBsZVF1YWxpdHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZBTFNFIC8qIEZJWE1FOiBEaXNjYXJkICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmVGhpcy0+YXV0b19kZXB0aF9zdGVuY2lsX2J1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCAvKiBwU2hhcmVkIChhbHdheXMgbnVsbCkqLyAgKTsKICAgICAgICAgICAgaWYgKFRoaXMtPmF1dG9fZGVwdGhfc3RlbmNpbF9idWZmZXIgIT0gTlVMTCkKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb250YWluZXIoVGhpcy0+YXV0b19kZXB0aF9zdGVuY2lsX2J1ZmZlciwgMCk7CiAgICAgICAgfQoKICAgICAgICAvKiogVE9ETzogQSBjaGVjayBvbiB3aWR0aCwgaGVpZ2h0IGFuZCBtdWx0aXNhbXBsZSB0eXBlcwogICAgICAgICooc2luY2UgdGhlIHpidWZmZXIgbXVzdCBiZSBhdCBsZWFzdCBhcyBsYXJnZSBhcyB0aGUgcmVuZGVyIHRhcmdldCBhbmQgaGF2ZSB0aGUgc2FtZSBtdWx0aXNhbXBsZSBwYXJhbWV0ZXJzKQogICAgICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgICAgIG9iamVjdC0+d2FudHNEZXB0aFN0ZW5jaWxCdWZmZXIgPSBUUlVFOwogICAgfSBlbHNlIHsKICAgICAgICBvYmplY3QtPndhbnRzRGVwdGhTdGVuY2lsQnVmZmVyID0gRkFMU0U7CiAgICB9CgogICAgVFJBQ0UoIkNyZWF0ZWQgc3dhcGNoYWluICVwXG4iLCBvYmplY3QpOwogICAgVFJBQ0UoIkZyb250QnVmIEAgJXAsIEJhY2tCdWYgQCAlcCwgRGVwdGhTdGVuY2lsICVkXG4iLG9iamVjdC0+ZnJvbnRCdWZmZXIsIG9iamVjdC0+YmFja0J1ZmZlciA/IG9iamVjdC0+YmFja0J1ZmZlclswXSA6IE5VTEwsIG9iamVjdC0+d2FudHNEZXB0aFN0ZW5jaWxCdWZmZXIpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7CgplcnJvcjoKICAgIGlmIChkaXNwbGF5bW9kZV9zZXQpIHsKICAgICAgICBERVZNT0RFVyBkZXZtb2RlOwogICAgICAgIFJFQ1QgICAgIGNsaXBfcmM7CgogICAgICAgIFNldFJlY3QoJmNsaXBfcmMsIDAsIDAsIG9iamVjdC0+b3JpZ193aWR0aCwgb2JqZWN0LT5vcmlnX2hlaWdodCk7CiAgICAgICAgQ2xpcEN1cnNvcihOVUxMKTsKCiAgICAgICAgLyogQ2hhbmdlIHRoZSBkaXNwbGF5IHNldHRpbmdzICovCiAgICAgICAgbWVtc2V0KCZkZXZtb2RlLCAwLCBzaXplb2YoZGV2bW9kZSkpOwogICAgICAgIGRldm1vZGUuZG1TaXplICAgICAgID0gc2l6ZW9mKGRldm1vZGUpOwogICAgICAgIGRldm1vZGUuZG1GaWVsZHMgICAgID0gRE1fQklUU1BFUlBFTCB8IERNX1BFTFNXSURUSCB8IERNX1BFTFNIRUlHSFQ7CiAgICAgICAgZGV2bW9kZS5kbUJpdHNQZXJQZWwgPSBmb3JtYXREZXNjLT5icHAgKiA4OwogICAgICAgIGRldm1vZGUuZG1QZWxzV2lkdGggID0gb2JqZWN0LT5vcmlnX3dpZHRoOwogICAgICAgIGRldm1vZGUuZG1QZWxzSGVpZ2h0ID0gb2JqZWN0LT5vcmlnX2hlaWdodDsKICAgICAgICBDaGFuZ2VEaXNwbGF5U2V0dGluZ3NFeFcoVGhpcy0+YWRhcHRlci0+RGV2aWNlTmFtZSwgJmRldm1vZGUsIE5VTEwsIENEU19GVUxMU0NSRUVOLCBOVUxMKTsKICAgIH0KCiAgICBpZiAob2JqZWN0LT5iYWNrQnVmZmVyKSB7CiAgICAgICAgaW50IGk7CiAgICAgICAgZm9yKGkgPSAwOyBpIDwgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckNvdW50OyBpKyspIHsKICAgICAgICAgICAgaWYob2JqZWN0LT5iYWNrQnVmZmVyW2ldKSB7CiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfR2V0UGFyZW50KG9iamVjdC0+YmFja0J1ZmZlcltpXSwgJmJ1ZmZlclBhcmVudCk7CiAgICAgICAgICAgICAgICBJVW5rbm93bl9SZWxlYXNlKGJ1ZmZlclBhcmVudCk7IC8qIG9uY2UgZm9yIHRoZSBnZXQgcGFyZW50ICovCiAgICAgICAgICAgICAgICBpZiAoSVVua25vd25fUmVsZWFzZShidWZmZXJQYXJlbnQpID4gMCkgewogICAgICAgICAgICAgICAgICAgIEZJWE1FKCIoJXApIFNvbWV0aGluZydzIHN0aWxsIGhvbGRpbmcgdGhlIGJhY2sgYnVmZmVyXG4iLFRoaXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9iamVjdC0+YmFja0J1ZmZlcik7CiAgICAgICAgb2JqZWN0LT5iYWNrQnVmZmVyID0gTlVMTDsKICAgIH0KICAgIGlmKG9iamVjdC0+Y29udGV4dFswXSkKICAgICAgICBEZXN0cm95Q29udGV4dChUaGlzLCBvYmplY3QtPmNvbnRleHRbMF0pOwogICAgaWYob2JqZWN0LT5mcm9udEJ1ZmZlcikgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9HZXRQYXJlbnQob2JqZWN0LT5mcm9udEJ1ZmZlciwgJmJ1ZmZlclBhcmVudCk7CiAgICAgICAgSVVua25vd25fUmVsZWFzZShidWZmZXJQYXJlbnQpOyAvKiBvbmNlIGZvciB0aGUgZ2V0IHBhcmVudCAqLwogICAgICAgIGlmIChJVW5rbm93bl9SZWxlYXNlKGJ1ZmZlclBhcmVudCkgPiAwKSB7CiAgICAgICAgICAgIEZJWE1FKCIoJXApIFNvbWV0aGluZydzIHN0aWxsIGhvbGRpbmcgdGhlIGZyb250IGJ1ZmZlclxuIixUaGlzKTsKICAgICAgICB9CiAgICB9CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvYmplY3QpOwogICAgcmV0dXJuIGhyOwp9CgovKiogTk9URTogVGhlc2UgYXJlIGFoZWFkIG9mIHRoZSBvdGhlciBnZXR0ZXJzIGFuZCBzZXR0ZXJzIHRvIHNhdmUgdXNpbmcgYSBmb3J3YXJkIGRlY2xhcmF0aW9uICoqLwpzdGF0aWMgVUlOVCAgICAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfR2V0TnVtYmVyT2ZTd2FwQ2hhaW5zKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIHJldHVybiBUaGlzLT5OdW1iZXJPZlN3YXBDaGFpbnM7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTd2FwQ2hhaW4oSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIGlTd2FwQ2hhaW4sIElXaW5lRDNEU3dhcENoYWluICoqcFN3YXBDaGFpbikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiBzd2FwY2hhaW4gJWRcbiIsIFRoaXMsIGlTd2FwQ2hhaW4pOwoKICAgIGlmKGlTd2FwQ2hhaW4gPCBUaGlzLT5OdW1iZXJPZlN3YXBDaGFpbnMpIHsKICAgICAgICAqcFN3YXBDaGFpbiA9IFRoaXMtPnN3YXBjaGFpbnNbaVN3YXBDaGFpbl07CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fQWRkUmVmKCpwU3dhcENoYWluKTsKICAgICAgICBUUkFDRSgiKCVwKSByZXR1cm5pbmcgJXBcbiIsIFRoaXMsICpwU3dhcENoYWluKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoIlN3YXBjaGFpbiBvdXQgb2YgcmFuZ2VcbiIpOwogICAgICAgICpwU3dhcENoYWluID0gTlVMTDsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KfQoKLyoqKioqCiAqIFZlcnRleCBEZWNsYXJhdGlvbgogKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVmVydGV4RGVjbGFyYXRpb24oSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uKiogcHBWZXJ0ZXhEZWNsYXJhdGlvbiwKICAgICAgICBJVW5rbm93biAqcGFyZW50LCBjb25zdCBXSU5FRDNEVkVSVEVYRUxFTUVOVCAqZWxlbWVudHMsIFVJTlQgZWxlbWVudF9jb3VudCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICAgICAgICAgICAgKlRoaXMgICA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb25JbXBsICpvYmplY3QgPSBOVUxMOwogICAgSFJFU1VMVCBociA9IFdJTkVEM0RfT0s7CgogICAgVFJBQ0UoIiglcCkgOiBkaXJlY3RYVmVyc2lvbiAldSwgZWxlbWVudHMgJXAsIGVsZW1lbnRfY291bnQgJWQsIHBwRGVjbD0lcFxuIiwKICAgICAgICAgICAgVGhpcywgKChJV2luZUQzREltcGwgKilUaGlzLT53aW5lRDNEKS0+ZHhWZXJzaW9uLCBlbGVtZW50cywgZWxlbWVudF9jb3VudCwgcHBWZXJ0ZXhEZWNsYXJhdGlvbik7CgogICAgRDNEQ1JFQVRFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBWZXJ0ZXhEZWNsYXJhdGlvbikKCiAgICBociA9IElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb25fU2V0RGVjbGFyYXRpb24oKElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb24gKilvYmplY3QsIGVsZW1lbnRzLCBlbGVtZW50X2NvdW50KTsKICAgIGlmKEZBSUxFRChocikpIHsKICAgICAgICAqcHBWZXJ0ZXhEZWNsYXJhdGlvbiA9IE5VTEw7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2JqZWN0KTsKICAgIH0KCiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyB1bnNpZ25lZCBpbnQgQ29udmVydEZ2ZlRvRGVjbGFyYXRpb24oSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzLCAvKiBGb3IgdGhlIEdMIGluZm8sIHdoaWNoIGhhcyB0aGUgdHlwZSB0YWJsZSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGZ2ZiwgV0lORUQzRFZFUlRFWEVMRU1FTlQqKiBwcFZlcnRleEVsZW1lbnRzKSB7CgogICAgdW5zaWduZWQgaW50IGlkeCwgaWR4MjsKICAgIHVuc2lnbmVkIGludCBvZmZzZXQ7CiAgICBCT09MIGhhc19wb3MgPSAoZnZmICYgV0lORUQzREZWRl9QT1NJVElPTl9NQVNLKSAhPSAwOwogICAgQk9PTCBoYXNfYmxlbmQgPSAoZnZmICYgV0lORUQzREZWRl9YWVpCNSkgPiBXSU5FRDNERlZGX1hZWlJIVzsKICAgIEJPT0wgaGFzX2JsZW5kX2lkeCA9IGhhc19ibGVuZCAmJgogICAgICAgKCgoZnZmICYgV0lORUQzREZWRl9YWVpCNSkgPT0gV0lORUQzREZWRl9YWVpCNSkgfHwKICAgICAgICAoZnZmICYgV0lORUQzREZWRl9MQVNUQkVUQV9EM0RDT0xPUikgfHwKICAgICAgICAoZnZmICYgV0lORUQzREZWRl9MQVNUQkVUQV9VQllURTQpKTsKICAgIEJPT0wgaGFzX25vcm1hbCA9IChmdmYgJiBXSU5FRDNERlZGX05PUk1BTCkgIT0gMDsKICAgIEJPT0wgaGFzX3BzaXplID0gKGZ2ZiAmIFdJTkVEM0RGVkZfUFNJWkUpICE9IDA7CiAgICBCT09MIGhhc19kaWZmdXNlID0gKGZ2ZiAmIFdJTkVEM0RGVkZfRElGRlVTRSkgIT0gMDsKICAgIEJPT0wgaGFzX3NwZWN1bGFyID0gKGZ2ZiAmIFdJTkVEM0RGVkZfU1BFQ1VMQVIpICE9MDsKCiAgICBEV09SRCBudW1fdGV4dHVyZXMgPSAoZnZmICYgV0lORUQzREZWRl9URVhDT1VOVF9NQVNLKSA+PiBXSU5FRDNERlZGX1RFWENPVU5UX1NISUZUOwogICAgRFdPUkQgdGV4Y29vcmRzID0gKGZ2ZiAmIDB4MDBGRjAwMDApID4+IDE2OwoKICAgIFdJTkVEM0RWRVJURVhFTEVNRU5UIGVuZF9lbGVtZW50ID0gV0lORUQzRERFQ0xfRU5EKCk7CiAgICBXSU5FRDNEVkVSVEVYRUxFTUVOVCAqZWxlbWVudHMgPSBOVUxMOwoKICAgIHVuc2lnbmVkIGludCBzaXplOwogICAgRFdPUkQgbnVtX2JsZW5kcyA9IDEgKyAoKChmdmYgJiBXSU5FRDNERlZGX1hZWkI1KSAtIFdJTkVEM0RGVkZfWFlaQjEpID4+IDEpOwogICAgaWYgKGhhc19ibGVuZF9pZHgpIG51bV9ibGVuZHMtLTsKCiAgICAvKiBDb21wdXRlIGRlY2xhcmF0aW9uIHNpemUgKi8KICAgIHNpemUgPSBoYXNfcG9zICsgKGhhc19ibGVuZCAmJiBudW1fYmxlbmRzID4gMCkgKyBoYXNfYmxlbmRfaWR4ICsgaGFzX25vcm1hbCArCiAgICAgICAgICAgaGFzX3BzaXplICsgaGFzX2RpZmZ1c2UgKyBoYXNfc3BlY3VsYXIgKyBudW1fdGV4dHVyZXMgKyAxOwoKICAgIC8qIGNvbnZlcnQgdGhlIGRlY2xhcmF0aW9uICovCiAgICBlbGVtZW50cyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplICogc2l6ZW9mKFdJTkVEM0RWRVJURVhFTEVNRU5UKSk7CiAgICBpZiAoIWVsZW1lbnRzKQogICAgICAgIHJldHVybiAwOwoKICAgIGVsZW1lbnRzW3NpemUtMV0gPSBlbmRfZWxlbWVudDsKICAgIGlkeCA9IDA7CiAgICBpZiAoaGFzX3BvcykgewogICAgICAgIGlmICghaGFzX2JsZW5kICYmIChmdmYgJiBXSU5FRDNERlZGX1hZWlJIVykpIHsKICAgICAgICAgICAgZWxlbWVudHNbaWR4XS5UeXBlID0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUNDsKICAgICAgICAgICAgZWxlbWVudHNbaWR4XS5Vc2FnZSA9IFdJTkVEM0RERUNMVVNBR0VfUE9TSVRJT05UOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgZWxlbWVudHNbaWR4XS5UeXBlID0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUMzsKICAgICAgICAgICAgZWxlbWVudHNbaWR4XS5Vc2FnZSA9IFdJTkVEM0RERUNMVVNBR0VfUE9TSVRJT047CiAgICAgICAgfQogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2VJbmRleCA9IDA7CiAgICAgICAgaWR4Kys7CiAgICB9CiAgICBpZiAoaGFzX2JsZW5kICYmIChudW1fYmxlbmRzID4gMCkpIHsKICAgICAgICBpZiAoKChmdmYgJiBXSU5FRDNERlZGX1hZWkI1KSA9PSBXSU5FRDNERlZGX1hZWkIyKSAmJiAoZnZmICYgV0lORUQzREZWRl9MQVNUQkVUQV9EM0RDT0xPUikpCiAgICAgICAgICAgIGVsZW1lbnRzW2lkeF0uVHlwZSA9IFdJTkVEM0RERUNMVFlQRV9EM0RDT0xPUjsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGVsZW1lbnRzW2lkeF0uVHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDEgKyBudW1fYmxlbmRzIC0gMTsKICAgICAgICBlbGVtZW50c1tpZHhdLlVzYWdlID0gV0lORUQzRERFQ0xVU0FHRV9CTEVORFdFSUdIVDsKICAgICAgICBlbGVtZW50c1tpZHhdLlVzYWdlSW5kZXggPSAwOwogICAgICAgIGlkeCsrOwogICAgfQogICAgaWYgKGhhc19ibGVuZF9pZHgpIHsKICAgICAgICBpZiAoZnZmICYgV0lORUQzREZWRl9MQVNUQkVUQV9VQllURTQgfHwKICAgICAgICAgICAgKCgoZnZmICYgV0lORUQzREZWRl9YWVpCNSkgPT0gV0lORUQzREZWRl9YWVpCMikgJiYgKGZ2ZiAmIFdJTkVEM0RGVkZfTEFTVEJFVEFfRDNEQ09MT1IpKSkKICAgICAgICAgICAgZWxlbWVudHNbaWR4XS5UeXBlID0gV0lORUQzRERFQ0xUWVBFX1VCWVRFNDsKICAgICAgICBlbHNlIGlmIChmdmYgJiBXSU5FRDNERlZGX0xBU1RCRVRBX0QzRENPTE9SKQogICAgICAgICAgICBlbGVtZW50c1tpZHhdLlR5cGUgPSBXSU5FRDNEREVDTFRZUEVfRDNEQ09MT1I7CiAgICAgICAgZWxzZQogICAgICAgICAgICBlbGVtZW50c1tpZHhdLlR5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQxOwogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2UgPSBXSU5FRDNEREVDTFVTQUdFX0JMRU5ESU5ESUNFUzsKICAgICAgICBlbGVtZW50c1tpZHhdLlVzYWdlSW5kZXggPSAwOwogICAgICAgIGlkeCsrOwogICAgfQogICAgaWYgKGhhc19ub3JtYWwpIHsKICAgICAgICBlbGVtZW50c1tpZHhdLlR5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQzOwogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2UgPSBXSU5FRDNEREVDTFVTQUdFX05PUk1BTDsKICAgICAgICBlbGVtZW50c1tpZHhdLlVzYWdlSW5kZXggPSAwOwogICAgICAgIGlkeCsrOwogICAgfQogICAgaWYgKGhhc19wc2l6ZSkgewogICAgICAgIGVsZW1lbnRzW2lkeF0uVHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDE7CiAgICAgICAgZWxlbWVudHNbaWR4XS5Vc2FnZSA9IFdJTkVEM0RERUNMVVNBR0VfUFNJWkU7CiAgICAgICAgZWxlbWVudHNbaWR4XS5Vc2FnZUluZGV4ID0gMDsKICAgICAgICBpZHgrKzsKICAgIH0KICAgIGlmIChoYXNfZGlmZnVzZSkgewogICAgICAgIGVsZW1lbnRzW2lkeF0uVHlwZSA9IFdJTkVEM0RERUNMVFlQRV9EM0RDT0xPUjsKICAgICAgICBlbGVtZW50c1tpZHhdLlVzYWdlID0gV0lORUQzRERFQ0xVU0FHRV9DT0xPUjsKICAgICAgICBlbGVtZW50c1tpZHhdLlVzYWdlSW5kZXggPSAwOwogICAgICAgIGlkeCsrOwogICAgfQogICAgaWYgKGhhc19zcGVjdWxhcikgewogICAgICAgIGVsZW1lbnRzW2lkeF0uVHlwZSA9IFdJTkVEM0RERUNMVFlQRV9EM0RDT0xPUjsKICAgICAgICBlbGVtZW50c1tpZHhdLlVzYWdlID0gV0lORUQzRERFQ0xVU0FHRV9DT0xPUjsKICAgICAgICBlbGVtZW50c1tpZHhdLlVzYWdlSW5kZXggPSAxOwogICAgICAgIGlkeCsrOwogICAgfQogICAgZm9yIChpZHgyID0gMDsgaWR4MiA8IG51bV90ZXh0dXJlczsgaWR4MisrKSB7CiAgICAgICAgdW5zaWduZWQgaW50IG51bWNvb3JkcyA9ICh0ZXhjb29yZHMgPj4gKGlkeDIqMikpICYgMHgwMzsKICAgICAgICBzd2l0Y2ggKG51bWNvb3JkcykgewogICAgICAgICAgICBjYXNlIFdJTkVEM0RGVkZfVEVYVFVSRUZPUk1BVDE6CiAgICAgICAgICAgICAgICBlbGVtZW50c1tpZHhdLlR5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZWRl9URVhUVVJFRk9STUFUMjoKICAgICAgICAgICAgICAgIGVsZW1lbnRzW2lkeF0uVHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBXSU5FRDNERlZGX1RFWFRVUkVGT1JNQVQzOgogICAgICAgICAgICAgICAgZWxlbWVudHNbaWR4XS5UeXBlID0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUMzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFdJTkVEM0RGVkZfVEVYVFVSRUZPUk1BVDQ6CiAgICAgICAgICAgICAgICBlbGVtZW50c1tpZHhdLlR5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQ0OwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2UgPSBXSU5FRDNEREVDTFVTQUdFX1RFWENPT1JEOwogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2VJbmRleCA9IGlkeDI7CiAgICAgICAgaWR4Kys7CiAgICB9CgogICAgLyogTm93IGNvbXB1dGUgb2Zmc2V0cywgYW5kIGluaXRpYWxpemUgdGhlIHJlc3Qgb2YgdGhlIGZpZWxkcyAqLwogICAgZm9yIChpZHggPSAwLCBvZmZzZXQgPSAwOyBpZHggPCBzaXplLTE7IGlkeCsrKSB7CiAgICAgICAgZWxlbWVudHNbaWR4XS5TdHJlYW0gPSAwOwogICAgICAgIGVsZW1lbnRzW2lkeF0uTWV0aG9kID0gV0lORUQzRERFQ0xNRVRIT0RfREVGQVVMVDsKICAgICAgICBlbGVtZW50c1tpZHhdLk9mZnNldCA9IG9mZnNldDsKICAgICAgICBvZmZzZXQgKz0gV0lORUQzRF9BVFJfU0laRShlbGVtZW50c1tpZHhdLlR5cGUpICogV0lORUQzRF9BVFJfVFlQRVNJWkUoZWxlbWVudHNbaWR4XS5UeXBlKTsKICAgIH0KCiAgICAqcHBWZXJ0ZXhFbGVtZW50cyA9IGVsZW1lbnRzOwogICAgcmV0dXJuIHNpemU7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVmVydGV4RGVjbGFyYXRpb25Gcm9tRlZGKElXaW5lRDNERGV2aWNlKiBpZmFjZSwgSVdpbmVEM0RWZXJ0ZXhEZWNsYXJhdGlvbioqIHBwVmVydGV4RGVjbGFyYXRpb24sIElVbmtub3duICpQYXJlbnQsIERXT1JEIEZ2ZikgewogICAgV0lORUQzRFZFUlRFWEVMRU1FTlQqIGVsZW1lbnRzID0gTlVMTDsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICB1bnNpZ25lZCBpbnQgc2l6ZTsKICAgIERXT1JEIGhyOwoKICAgIHNpemUgPSBDb252ZXJ0RnZmVG9EZWNsYXJhdGlvbihUaGlzLCBGdmYsICZlbGVtZW50cyk7CiAgICBpZiAoc2l6ZSA9PSAwKSByZXR1cm4gV0lORUQzREVSUl9PVVRPRlZJREVPTUVNT1JZOwoKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfQ3JlYXRlVmVydGV4RGVjbGFyYXRpb24oaWZhY2UsIHBwVmVydGV4RGVjbGFyYXRpb24sIFBhcmVudCwgZWxlbWVudHMsIHNpemUpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZWxlbWVudHMpOwogICAgaWYgKGhyICE9IFNfT0spIHJldHVybiBocjsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWZXJ0ZXhTaGFkZXIoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uICp2ZXJ0ZXhfZGVjbGFyYXRpb24sIENPTlNUIERXT1JEICpwRnVuY3Rpb24sIElXaW5lRDNEVmVydGV4U2hhZGVyICoqcHBWZXJ0ZXhTaGFkZXIsIElVbmtub3duICpwYXJlbnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgICAgICAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEVmVydGV4U2hhZGVySW1wbCAqb2JqZWN0OyAgLyogTk9URTogaW1wbCB1c2FnZSBpcyBvaywgdGhpcyBpcyBhIGNyZWF0ZSAqLwogICAgSFJFU1VMVCBociA9IFdJTkVEM0RfT0s7CiAgICBEM0RDUkVBVEVTSEFERVJPQkpFQ1RJTlNUQU5DRShvYmplY3QsIFZlcnRleFNoYWRlcikKICAgIG9iamVjdC0+YmFzZVNoYWRlci5zaGFkZXJfaW5zID0gSVdpbmVEM0RWZXJ0ZXhTaGFkZXJJbXBsX3NoYWRlcl9pbnM7CgogICAgVFJBQ0UoIiglcCkgOiBDcmVhdGVkIFZlcnRleCBzaGFkZXIgJXBcbiIsIFRoaXMsICpwcFZlcnRleFNoYWRlcik7CgogICAgaWYgKHZlcnRleF9kZWNsYXJhdGlvbikgewogICAgICAgIElXaW5lRDNEVmVydGV4U2hhZGVyX0Zha2VTZW1hbnRpY3MoKnBwVmVydGV4U2hhZGVyLCB2ZXJ0ZXhfZGVjbGFyYXRpb24pOwogICAgfQoKICAgIGhyID0gSVdpbmVEM0RWZXJ0ZXhTaGFkZXJfU2V0RnVuY3Rpb24oKnBwVmVydGV4U2hhZGVyLCBwRnVuY3Rpb24pOwoKICAgIGlmIChXSU5FRDNEX09LICE9IGhyKSB7CiAgICAgICAgRklYTUUoIiglcCkgOiBGYWlsZWQgdG8gc2V0IHRoZSBmdW5jdGlvbiwgcmV0dXJuaW5nIFdJTkVEM0RFUlJfSU5WQUxJRENBTExcbiIsIGlmYWNlKTsKICAgICAgICBJV2luZUQzRFZlcnRleFNoYWRlcl9SZWxlYXNlKCpwcFZlcnRleFNoYWRlcik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICBsaXN0X2FkZF9oZWFkKCZUaGlzLT5zaGFkZXJzLCAmb2JqZWN0LT5iYXNlU2hhZGVyLnNoYWRlcl9saXN0X2VudHJ5KTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVQaXhlbFNoYWRlcihJV2luZUQzRERldmljZSAqaWZhY2UsIENPTlNUIERXT1JEICpwRnVuY3Rpb24sIElXaW5lRDNEUGl4ZWxTaGFkZXIgKipwcFBpeGVsU2hhZGVyLCBJVW5rbm93biAqcGFyZW50KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqb2JqZWN0OyAvKiBOT1RFOiBpbXBsIGFsbG93ZWQsIHRoaXMgaXMgYSBjcmVhdGUgKi8KICAgIEhSRVNVTFQgaHIgPSBXSU5FRDNEX09LOwoKICAgIEQzRENSRUFURVNIQURFUk9CSkVDVElOU1RBTkNFKG9iamVjdCwgUGl4ZWxTaGFkZXIpCiAgICBvYmplY3QtPmJhc2VTaGFkZXIuc2hhZGVyX2lucyA9IElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsX3NoYWRlcl9pbnM7CiAgICBociA9IElXaW5lRDNEUGl4ZWxTaGFkZXJfU2V0RnVuY3Rpb24oKnBwUGl4ZWxTaGFkZXIsIHBGdW5jdGlvbik7CiAgICBpZiAoV0lORUQzRF9PSyA9PSBocikgewogICAgICAgIFRSQUNFKCIoJXApIDogQ3JlYXRlZCBQaXhlbCBzaGFkZXIgJXBcbiIsIFRoaXMsICpwcFBpeGVsU2hhZGVyKTsKICAgICAgICBsaXN0X2FkZF9oZWFkKCZUaGlzLT5zaGFkZXJzLCAmb2JqZWN0LT5iYXNlU2hhZGVyLnNoYWRlcl9saXN0X2VudHJ5KTsKICAgIH0gZWxzZSB7CiAgICAgICAgV0FSTigiKCVwKSA6IEZhaWxlZCB0byBjcmVhdGUgcGl4ZWwgc2hhZGVyXG4iLCBUaGlzKTsKICAgIH0KCiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlUGFsZXR0ZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIEZsYWdzLCBQQUxFVFRFRU5UUlkgKlBhbEVudCwgSVdpbmVEM0RQYWxldHRlICoqUGFsZXR0ZSwgSVVua25vd24gKlBhcmVudCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEUGFsZXR0ZUltcGwgKm9iamVjdDsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCV4LCAlcCwgJXAsICVwKVxuIiwgVGhpcywgRmxhZ3MsIFBhbEVudCwgUGFsZXR0ZSwgUGFyZW50KTsKCiAgICAvKiBDcmVhdGUgdGhlIG5ldyBvYmplY3QgKi8KICAgIG9iamVjdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSVdpbmVEM0RQYWxldHRlSW1wbCkpOwogICAgaWYoIW9iamVjdCkgewogICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeSB3aGVuIGFsbG9jYXRpbmcgbWVtb3J5IGZvciBhIElXaW5lRDNEUGFsZXR0ZSBpbXBsZW1lbnRhdGlvblxuIik7CiAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICB9CgogICAgb2JqZWN0LT5scFZ0YmwgPSAmSVdpbmVEM0RQYWxldHRlX1Z0Ymw7CiAgICBvYmplY3QtPnJlZiA9IDE7CiAgICBvYmplY3QtPkZsYWdzID0gRmxhZ3M7CiAgICBvYmplY3QtPnBhcmVudCA9IFBhcmVudDsKICAgIG9iamVjdC0+d2luZUQzRERldmljZSA9IFRoaXM7CiAgICBvYmplY3QtPnBhbE51bUVudHJpZXMgPSBJV2luZUQzRFBhbGV0dGVJbXBsX1NpemUoRmxhZ3MpOwoJCiAgICBvYmplY3QtPmhwYWwgPSBDcmVhdGVQYWxldHRlKChjb25zdCBMT0dQQUxFVFRFKikmKG9iamVjdC0+cGFsVmVyc2lvbikpOwoKICAgIGlmKCFvYmplY3QtPmhwYWwpIHsKICAgICAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2JqZWN0KTsKICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgIH0KCiAgICBociA9IElXaW5lRDNEUGFsZXR0ZV9TZXRFbnRyaWVzKChJV2luZUQzRFBhbGV0dGUgKikgb2JqZWN0LCAwLCAwLCBJV2luZUQzRFBhbGV0dGVJbXBsX1NpemUoRmxhZ3MpLCBQYWxFbnQpOwogICAgaWYoRkFJTEVEKGhyKSkgewogICAgICAgIElXaW5lRDNEUGFsZXR0ZV9SZWxlYXNlKChJV2luZUQzRFBhbGV0dGUgKikgb2JqZWN0KTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgKlBhbGV0dGUgPSAoSVdpbmVEM0RQYWxldHRlICopIG9iamVjdDsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIHZvaWQgSVdpbmVEM0REZXZpY2VJbXBsX0xvYWRMb2dvKElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcywgY29uc3QgY2hhciAqZmlsZW5hbWUpIHsKICAgIEhCSVRNQVAgaGJtOwogICAgQklUTUFQIGJtOwogICAgSFJFU1VMVCBocjsKICAgIEhEQyBkY2IgPSBOVUxMLCBkY3MgPSBOVUxMOwogICAgV0lORUREQ09MT1JLRVkgY29sb3JrZXk7CgogICAgaGJtID0gKEhCSVRNQVApIExvYWRJbWFnZUEoTlVMTCwgZmlsZW5hbWUsIElNQUdFX0JJVE1BUCwgMCwgMCwgTFJfTE9BREZST01GSUxFIHwgTFJfQ1JFQVRFRElCU0VDVElPTik7CiAgICBpZihoYm0pCiAgICB7CiAgICAgICAgR2V0T2JqZWN0QShoYm0sIHNpemVvZihCSVRNQVApLCAmYm0pOwogICAgICAgIGRjYiA9IENyZWF0ZUNvbXBhdGlibGVEQyhOVUxMKTsKICAgICAgICBpZighZGNiKSBnb3RvIG91dDsKICAgICAgICBTZWxlY3RPYmplY3QoZGNiLCBoYm0pOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIC8qIENyZWF0ZSBhIDMyeDMyIHdoaXRlIHN1cmZhY2UgdG8gaW5kaWNhdGUgdGhhdCB3aW5lZDNkIGlzIHVzZWQsIGJ1dCB0aGUgc3BlY2lmaWVkIGltYWdlCiAgICAgICAgICogY291bGRuJ3QgYmUgbG9hZGVkCiAgICAgICAgICovCiAgICAgICAgbWVtc2V0KCZibSwgMCwgc2l6ZW9mKGJtKSk7CiAgICAgICAgYm0uYm1XaWR0aCA9IDMyOwogICAgICAgIGJtLmJtSGVpZ2h0ID0gMzI7CiAgICB9CgogICAgaHIgPSBJV2luZUQzRERldmljZV9DcmVhdGVTdXJmYWNlKChJV2luZUQzRERldmljZSAqKSBUaGlzLCBibS5ibVdpZHRoLCBibS5ibUhlaWdodCwgV0lORUQzREZNVF9SNUc2QjUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSwgRkFMU0UsIDAsICZUaGlzLT5sb2dvX3N1cmZhY2UsIFdJTkVEM0RSVFlQRV9TVVJGQUNFLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RQT09MX0RFRkFVTFQsIFdJTkVEM0RNVUxUSVNBTVBMRV9OT05FLCAwLCBOVUxMLCBTVVJGQUNFX09QRU5HTCwgTlVMTCk7CiAgICBpZihGQUlMRUQoaHIpKSB7CiAgICAgICAgRVJSKCJXaW5lIGxvZ28gcmVxdWVzdGVkLCBidXQgZmFpbGVkIHRvIGNyZWF0ZSBzdXJmYWNlXG4iKTsKICAgICAgICBnb3RvIG91dDsKICAgIH0KCiAgICBpZihkY2IpIHsKICAgICAgICBociA9IElXaW5lRDNEU3VyZmFjZV9HZXREQyhUaGlzLT5sb2dvX3N1cmZhY2UsICZkY3MpOwogICAgICAgIGlmKEZBSUxFRChocikpIGdvdG8gb3V0OwogICAgICAgIEJpdEJsdChkY3MsIDAsIDAsIGJtLmJtV2lkdGgsIGJtLmJtSGVpZ2h0LCBkY2IsIDAsIDAsIFNSQ0NPUFkpOwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlREMoVGhpcy0+bG9nb19zdXJmYWNlLCBkY3MpOwoKICAgICAgICBjb2xvcmtleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZSA9IDA7CiAgICAgICAgY29sb3JrZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlID0gMDsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29sb3JLZXkoVGhpcy0+bG9nb19zdXJmYWNlLCBXSU5FRERDS0VZX1NSQ0JMVCwgJmNvbG9ya2V5KTsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogRmlsbCB0aGUgc3VyZmFjZSB3aXRoIGEgd2hpdGUgY29sb3IgdG8gc2hvdyB0aGF0IHdpbmVkM2QgaXMgdGhlcmUgKi8KICAgICAgICBJV2luZUQzRERldmljZV9Db2xvckZpbGwoKElXaW5lRDNERGV2aWNlICopIFRoaXMsIFRoaXMtPmxvZ29fc3VyZmFjZSwgTlVMTCwgMHhmZmZmZmZmZik7CiAgICB9CgogICAgb3V0OgogICAgaWYoZGNiKSB7CiAgICAgICAgRGVsZXRlREMoZGNiKTsKICAgIH0KICAgIGlmKGhibSkgewogICAgICAgIERlbGV0ZU9iamVjdChoYm0pOwogICAgfQogICAgcmV0dXJuOwp9CgpzdGF0aWMgdm9pZCBjcmVhdGVfZHVtbXlfdGV4dHVyZXMoSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzKSB7CiAgICB1bnNpZ25lZCBpbnQgaTsKICAgIC8qIFVuZGVyIERpcmVjdFggeW91IGNhbiBoYXZlIHRleHR1cmUgc3RhZ2Ugb3BlcmF0aW9ucyBldmVuIGlmIG5vIHRleHR1cmUgaXMKICAgIGJvdW5kLCB3aGVyZWFzIG9wZW5nbCB3aWxsIG9ubHkgZG8gdGV4dHVyZSBvcGVyYXRpb25zIHdoZW4gYSB2YWxpZCB0ZXh0dXJlIGlzCiAgICBib3VuZC4gV2UgZW11bGF0ZSB0aGlzIGJ5IGNyZWF0aW5nIGR1bW15IHRleHR1cmVzIGFuZCBiaW5kaW5nIHRoZW0gdG8gZWFjaAogICAgdGV4dHVyZSBzdGFnZSwgYnV0IGRpc2FibGUgYWxsIHN0YWdlcyBieSBkZWZhdWx0LiBIZW5jZSBpZiBhIHN0YWdlIGlzIGVuYWJsZWQKICAgIHRoZW4gdGhlIGRlZmF1bHQgdGV4dHVyZSB3aWxsIGtpY2sgaW4gdW50aWwgcmVwbGFjZWQgYnkgYSBTZXRUZXh0dXJlIGNhbGwgICAgICovCiAgICBFTlRFUl9HTCgpOwoKICAgIGlmKEdMX1NVUFBPUlQoQVBQTEVfQ0xJRU5UX1NUT1JBR0UpKSB7CiAgICAgICAgLyogVGhlIGR1bW15IHRleHR1cmUgZG9lcyBub3QgaGF2ZSBjbGllbnQgc3RvcmFnZSBiYWNraW5nICovCiAgICAgICAgZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfQ0xJRU5UX1NUT1JBR0VfQVBQTEUsIEdMX0ZBTFNFKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfQ0xJRU5UX1NUT1JBR0VfQVBQTEUsIEdMX0ZBTFNFKSIpOwogICAgfQogICAgZm9yIChpID0gMDsgaSA8IEdMX0xJTUlUUyh0ZXh0dXJlcyk7IGkrKykgewogICAgICAgIEdMdWJ5dGUgd2hpdGUgPSAyNTU7CgogICAgICAgIC8qIE1ha2UgYXBwcm9wcmlhdGUgdGV4dHVyZSBhY3RpdmUgKi8KICAgICAgICBpZiAoR0xfU1VQUE9SVChBUkJfTVVMVElURVhUVVJFKSkgewogICAgICAgICAgICBHTF9FWFRDQUxMKGdsQWN0aXZlVGV4dHVyZUFSQihHTF9URVhUVVJFMF9BUkIgKyBpKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEFjdGl2ZVRleHR1cmVBUkIiKTsKICAgICAgICB9IGVsc2UgaWYgKGkgPiAwKSB7CiAgICAgICAgICAgIEZJWE1FKCJQcm9ncmFtIHVzaW5nIG11bHRpcGxlIGNvbmN1cnJlbnQgdGV4dHVyZXMgd2hpY2ggdGhpcyBvcGVuZ2wgaW1wbGVtZW50YXRpb24gZG9lc24ndCBzdXBwb3J0XG4iKTsKICAgICAgICB9CgogICAgICAgIC8qIEdlbmVyYXRlIGFuIG9wZW5nbCB0ZXh0dXJlIG5hbWUgKi8KICAgICAgICBnbEdlblRleHR1cmVzKDEsICZUaGlzLT5kdW1teVRleHR1cmVOYW1lW2ldKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZW5UZXh0dXJlcyIpOwogICAgICAgIFRSQUNFKCJEdW1teSBUZXh0dXJlICVkIGdpdmVuIG5hbWUgJWRcbiIsIGksIFRoaXMtPmR1bW15VGV4dHVyZU5hbWVbaV0pOwoKICAgICAgICAvKiBHZW5lcmF0ZSBhIGR1bW15IDJkIHRleHR1cmUgKG5vdCB1c2luZyAxZCBiZWNhdXNlIHRoZXkgY2F1c2UgbWFueQogICAgICAgICogRFJJIGRyaXZlcnMgZmFsbCBiYWNrIHRvIHN3KSAqLwogICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPnRleHR1cmVEaW1lbnNpb25zW2ldID0gR0xfVEVYVFVSRV8yRDsKICAgICAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIFRoaXMtPmR1bW15VGV4dHVyZU5hbWVbaV0pOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRUZXh0dXJlIik7CgogICAgICAgIGdsVGV4SW1hZ2UyRChHTF9URVhUVVJFXzJELCAwLCBHTF9MVU1JTkFOQ0UsIDEsIDEsIDAsIEdMX0xVTUlOQU5DRSwgR0xfVU5TSUdORURfQllURSwgJndoaXRlKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xUZXhJbWFnZTJEIik7CiAgICB9CiAgICBpZihHTF9TVVBQT1JUKEFQUExFX0NMSUVOVF9TVE9SQUdFKSkgewogICAgICAgIC8qIFJlZW5hYmxlIGJlY2F1c2UgaWYgc3VwcG9ydGVkIGl0IGlzIGVuYWJsZWQgYnkgZGVmYXVsdCAqLwogICAgICAgIGdsUGl4ZWxTdG9yZWkoR0xfVU5QQUNLX0NMSUVOVF9TVE9SQUdFX0FQUExFLCBHTF9UUlVFKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfQ0xJRU5UX1NUT1JBR0VfQVBQTEUsIEdMX1RSVUUpIik7CiAgICB9CgogICAgTEVBVkVfR0woKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9Jbml0M0QoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEUFJFU0VOVF9QQVJBTUVURVJTKiBwUHJlc2VudGF0aW9uUGFyYW1ldGVycywgRDNEQ0JfQ1JFQVRFQURESVRJT05BTFNXQVBDSEFJTiBEM0RDQl9DcmVhdGVBZGRpdGlvbmFsU3dhcENoYWluKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICpzd2FwY2hhaW4gPSBOVUxMOwogICAgSFJFU1VMVCBocjsKICAgIERXT1JEIHN0YXRlOwogICAgdW5zaWduZWQgaW50IGk7CgogICAgVFJBQ0UoIiglcCktPiglcCwlcClcbiIsIFRoaXMsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLCBEM0RDQl9DcmVhdGVBZGRpdGlvbmFsU3dhcENoYWluKTsKICAgIGlmKFRoaXMtPmQzZF9pbml0aWFsaXplZCkgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICBpZighVGhpcy0+YWRhcHRlci0+b3BlbmdsKSByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICAvKiBUT0RPOiBUZXN0IGlmIE9wZW5HTCBpcyBjb21waWxlZCBpbiBhbmQgbG9hZGVkICovCgogICAgVFJBQ0UoIiglcCkgOiBDcmVhdGluZyBzdGF0ZWJsb2NrXG4iLCBUaGlzKTsKICAgIC8qIENyZWF0aW5nIHRoZSBzdGFydHVwIHN0YXRlQmxvY2sgLSBOb3RlIFNwZWNpYWwgQ2FzZTogMCA9PiBEb24ndCBmaWxsIGluIHlldCEgKi8KICAgIGhyID0gSVdpbmVEM0REZXZpY2VfQ3JlYXRlU3RhdGVCbG9jayhpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNEU0JUX0lOSVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKElXaW5lRDNEU3RhdGVCbG9jayAqKikmVGhpcy0+c3RhdGVCbG9jaywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKICAgIGlmIChXSU5FRDNEX09LICE9IGhyKSB7ICAgLyogTm90ZTogTm8gcGFyZW50IG5lZWRlZCBmb3IgaW5pdGlhbCBpbnRlcm5hbCBzdGF0ZWJsb2NrICovCiAgICAgICAgV0FSTigiRmFpbGVkIHRvIGNyZWF0ZSBzdGF0ZWJsb2NrXG4iKTsKICAgICAgICBnb3RvIGVycl9vdXQ7CiAgICB9CiAgICBUUkFDRSgiKCVwKSA6IENyZWF0ZWQgc3RhdGVibG9jayAoJXApXG4iLCBUaGlzLCBUaGlzLT5zdGF0ZUJsb2NrKTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2sgPSBUaGlzLT5zdGF0ZUJsb2NrOwogICAgSVdpbmVEM0RTdGF0ZUJsb2NrX0FkZFJlZigoSVdpbmVEM0RTdGF0ZUJsb2NrKilUaGlzLT51cGRhdGVTdGF0ZUJsb2NrKTsKCiAgICBociA9IGFsbG9jYXRlX3NoYWRlcl9jb25zdGFudHMoVGhpcy0+dXBkYXRlU3RhdGVCbG9jayk7CiAgICBpZiAoV0lORUQzRF9PSyAhPSBocikgewogICAgICAgIGdvdG8gZXJyX291dDsKICAgIH0KCiAgICBUaGlzLT5yZW5kZXJfdGFyZ2V0cyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSVdpbmVEM0RTdXJmYWNlICopICogR0xfTElNSVRTKGJ1ZmZlcnMpKTsKICAgIFRoaXMtPmZib19jb2xvcl9hdHRhY2htZW50cyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSVdpbmVEM0RTdXJmYWNlICopICogR0xfTElNSVRTKGJ1ZmZlcnMpKTsKICAgIFRoaXMtPmRyYXdfYnVmZmVycyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoR0xlbnVtKSAqIEdMX0xJTUlUUyhidWZmZXJzKSk7CgogICAgVGhpcy0+TnVtYmVyT2ZQYWxldHRlcyA9IDE7CiAgICBUaGlzLT5wYWxldHRlcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoUEFMRVRURUVOVFJZKikpOwogICAgaWYoIVRoaXMtPnBhbGV0dGVzIHx8ICFUaGlzLT5yZW5kZXJfdGFyZ2V0cyB8fCAhVGhpcy0+ZmJvX2NvbG9yX2F0dGFjaG1lbnRzIHx8ICFUaGlzLT5kcmF3X2J1ZmZlcnMpIHsKICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnkhXG4iKTsKICAgICAgICBnb3RvIGVycl9vdXQ7CiAgICB9CiAgICBUaGlzLT5wYWxldHRlc1swXSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoUEFMRVRURUVOVFJZKSAqIDI1Nik7CiAgICBpZighVGhpcy0+cGFsZXR0ZXNbMF0pIHsKICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnkhXG4iKTsKICAgICAgICBnb3RvIGVycl9vdXQ7CiAgICB9CiAgICBmb3IgKGkgPSAwOyBpIDwgMjU2OyArK2kpIHsKICAgICAgICBUaGlzLT5wYWxldHRlc1swXVtpXS5wZVJlZCAgID0gMHhGRjsKICAgICAgICBUaGlzLT5wYWxldHRlc1swXVtpXS5wZUdyZWVuID0gMHhGRjsKICAgICAgICBUaGlzLT5wYWxldHRlc1swXVtpXS5wZUJsdWUgID0gMHhGRjsKICAgICAgICBUaGlzLT5wYWxldHRlc1swXVtpXS5wZUZsYWdzID0gMHhGRjsKICAgIH0KICAgIFRoaXMtPmN1cnJlbnRQYWxldHRlID0gMDsKCiAgICAvKiBJbml0aWFsaXplIHRoZSB0ZXh0dXJlIHVuaXQgbWFwcGluZyB0byBhIDE6MSBtYXBwaW5nICovCiAgICBmb3IgKHN0YXRlID0gMDsgc3RhdGUgPCBNQVhfQ09NQklORURfU0FNUExFUlM7ICsrc3RhdGUpIHsKICAgICAgICBpZiAoc3RhdGUgPCBHTF9MSU1JVFMoZnJhZ21lbnRfc2FtcGxlcnMpKSB7CiAgICAgICAgICAgIFRoaXMtPnRleFVuaXRNYXBbc3RhdGVdID0gc3RhdGU7CiAgICAgICAgICAgIFRoaXMtPnJldl90ZXhfdW5pdF9tYXBbc3RhdGVdID0gc3RhdGU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVGhpcy0+dGV4VW5pdE1hcFtzdGF0ZV0gPSAtMTsKICAgICAgICAgICAgVGhpcy0+cmV2X3RleF91bml0X21hcFtzdGF0ZV0gPSAtMTsKICAgICAgICB9CiAgICB9CgogICAgLyogU2V0dXAgdGhlIGltcGxpY2l0IHN3YXBjaGFpbiAqLwogICAgVFJBQ0UoIkNyZWF0aW5nIGltcGxpY2l0IHN3YXBjaGFpblxuIik7CiAgICBocj1EM0RDQl9DcmVhdGVBZGRpdGlvbmFsU3dhcENoYWluKFRoaXMtPnBhcmVudCwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMsIChJV2luZUQzRFN3YXBDaGFpbiAqKikmc3dhcGNoYWluKTsKICAgIGlmIChGQUlMRUQoaHIpIHx8ICFzd2FwY2hhaW4pIHsKICAgICAgICBXQVJOKCJGYWlsZWQgdG8gY3JlYXRlIGltcGxpY2l0IHN3YXBjaGFpblxuIik7CiAgICAgICAgZ290byBlcnJfb3V0OwogICAgfQoKICAgIFRoaXMtPk51bWJlck9mU3dhcENoYWlucyA9IDE7CiAgICBUaGlzLT5zd2FwY2hhaW5zID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPk51bWJlck9mU3dhcENoYWlucyAqIHNpemVvZihJV2luZUQzRFN3YXBDaGFpbiAqKSk7CiAgICBpZighVGhpcy0+c3dhcGNoYWlucykgewogICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeSFcbiIpOwogICAgICAgIGdvdG8gZXJyX291dDsKICAgIH0KICAgIFRoaXMtPnN3YXBjaGFpbnNbMF0gPSAoSVdpbmVEM0RTd2FwQ2hhaW4gKikgc3dhcGNoYWluOwoKICAgIGlmKHN3YXBjaGFpbi0+YmFja0J1ZmZlciAmJiBzd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0pIHsKICAgICAgICBUUkFDRSgiU2V0dGluZyByZW5kZXJ0YXJnZXQgdG8gJXBcbiIsIHN3YXBjaGFpbi0+YmFja0J1ZmZlcik7CiAgICAgICAgVGhpcy0+cmVuZGVyX3RhcmdldHNbMF0gPSBzd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF07CiAgICAgICAgVGhpcy0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCA9IHN3YXBjaGFpbi0+YmFja0J1ZmZlclswXTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIFRSQUNFKCJTZXR0aW5nIHJlbmRlcnRhcmdldCB0byAlcFxuIiwgc3dhcGNoYWluLT5mcm9udEJ1ZmZlcik7CiAgICAgICAgVGhpcy0+cmVuZGVyX3RhcmdldHNbMF0gPSBzd2FwY2hhaW4tPmZyb250QnVmZmVyOwogICAgICAgIFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQgPSBzd2FwY2hhaW4tPmZyb250QnVmZmVyOwogICAgfQogICAgSVdpbmVEM0RTdXJmYWNlX0FkZFJlZihUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXSk7CiAgICBUaGlzLT5hY3RpdmVDb250ZXh0ID0gc3dhcGNoYWluLT5jb250ZXh0WzBdOwogICAgVGhpcy0+bGFzdFRocmVhZCA9IEdldEN1cnJlbnRUaHJlYWRJZCgpOwoKICAgIC8qIERlcHRoIFN0ZW5jaWwgc3VwcG9ydCAqLwogICAgVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCA9IFRoaXMtPmF1dG9fZGVwdGhfc3RlbmNpbF9idWZmZXI7CiAgICBpZiAoTlVMTCAhPSBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KSB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0FkZFJlZihUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KTsKICAgIH0KCiAgICBociA9IFRoaXMtPnNoYWRlcl9iYWNrZW5kLT5zaGFkZXJfYWxsb2NfcHJpdmF0ZShpZmFjZSk7CiAgICBpZihGQUlMRUQoaHIpKSB7CiAgICAgICAgVFJBQ0UoIlNoYWRlciBwcml2YXRlIGRhdGEgY291bGRuJ3QgYmUgYWxsb2NhdGVkXG4iKTsKICAgICAgICBnb3RvIGVycl9vdXQ7CiAgICB9CgogICAgLyogU2V0IHVwIHNvbWUgc3RhcnRpbmcgR0wgc2V0dXAgKi8KCiAgICAvKiBTZXR1cCBhbGwgdGhlIGRldmljZXMgZGVmYXVsdHMgKi8KICAgIElXaW5lRDNEU3RhdGVCbG9ja19Jbml0U3RhcnR1cFN0YXRlQmxvY2soKElXaW5lRDNEU3RhdGVCbG9jayAqKVRoaXMtPnN0YXRlQmxvY2spOwogICAgY3JlYXRlX2R1bW15X3RleHR1cmVzKFRoaXMpOwoKICAgIEVOVEVSX0dMKCk7CgojaWYgMAogICAgSVdpbmVEM0RJbXBsX0NoZWNrR3JhcGhpY3NNZW1vcnkoKTsKI2VuZGlmCgogICAgeyAvKiBTZXQgYSBkZWZhdWx0IHZpZXdwb3J0ICovCiAgICAgICAgV0lORUQzRFZJRVdQT1JUIHZwOwogICAgICAgIHZwLlggICAgICA9IDA7CiAgICAgICAgdnAuWSAgICAgID0gMDsKICAgICAgICB2cC5XaWR0aCAgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoOwogICAgICAgIHZwLkhlaWdodCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0OwogICAgICAgIHZwLk1pblogICA9IDAuMGY7CiAgICAgICAgdnAuTWF4WiAgID0gMS4wZjsKICAgICAgICBJV2luZUQzRERldmljZV9TZXRWaWV3cG9ydCgoSVdpbmVEM0REZXZpY2UgKilUaGlzLCAmdnApOwogICAgfQoKICAgIC8qIEluaXRpYWxpemUgdGhlIGN1cnJlbnQgdmlldyBzdGF0ZSAqLwogICAgVGhpcy0+dmlld19pZGVudCA9IDE7CiAgICBUaGlzLT5jb250ZXh0c1swXS0+bGFzdF93YXNfcmh3ID0gMDsKICAgIGdsR2V0SW50ZWdlcnYoR0xfTUFYX0xJR0hUUywgJlRoaXMtPm1heENvbmN1cnJlbnRMaWdodHMpOwogICAgY2hlY2tHTGNhbGwoImdsR2V0SW50ZWdlcnYoR0xfTUFYX0xJR0hUUywgJlRoaXMtPm1heENvbmN1cnJlbnRMaWdodHMpIik7CgogICAgc3dpdGNoKHdpbmVkM2Rfc2V0dGluZ3Mub2Zmc2NyZWVuX3JlbmRlcmluZ19tb2RlKSB7CiAgICAgICAgY2FzZSBPUk1fRkJPOgogICAgICAgIGNhc2UgT1JNX1BCVUZGRVI6CiAgICAgICAgICAgIFRoaXMtPm9mZnNjcmVlbkJ1ZmZlciA9IEdMX0JBQ0s7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIE9STV9CQUNLQlVGRkVSOgogICAgICAgIHsKICAgICAgICAgICAgaWYoVGhpcy0+YWN0aXZlQ29udGV4dC0+YXV4X2J1ZmZlcnMgPiAwKSB7CiAgICAgICAgICAgICAgICBUUkFDRSgiVXNpbmcgYXV4aWxsaWFyeSBidWZmZXIgZm9yIG9mZnNjcmVlbiByZW5kZXJpbmdcbiIpOwogICAgICAgICAgICAgICAgVGhpcy0+b2Zmc2NyZWVuQnVmZmVyID0gR0xfQVVYMDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIFRSQUNFKCJVc2luZyBiYWNrIGJ1ZmZlciBmb3Igb2Zmc2NyZWVuIHJlbmRlcmluZ1xuIik7CiAgICAgICAgICAgICAgICBUaGlzLT5vZmZzY3JlZW5CdWZmZXIgPSBHTF9CQUNLOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIFRSQUNFKCIoJXApIEFsbCBkZWZhdWx0cyBub3cgc2V0IHVwLCBsZWF2aW5nIEluaXQzRCB3aXRoICVwXG4iLCBUaGlzLCBUaGlzKTsKICAgIExFQVZFX0dMKCk7CgogICAgLyogQ2xlYXIgdGhlIHNjcmVlbiAqLwogICAgSVdpbmVEM0REZXZpY2VfQ2xlYXIoKElXaW5lRDNERGV2aWNlICopIFRoaXMsIDAsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRENMRUFSX1RBUkdFVCB8IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5FbmFibGVBdXRvRGVwdGhTdGVuY2lsID8gV0lORUQzRENMRUFSX1pCVUZGRVIgfCBXSU5FRDNEQ0xFQVJfU1RFTkNJTCA6IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwMCwgMS4wLCAwKTsKCiAgICBUaGlzLT5kM2RfaW5pdGlhbGl6ZWQgPSBUUlVFOwoKICAgIGlmKHdpbmVkM2Rfc2V0dGluZ3MubG9nbykgewogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9Mb2FkTG9nbyhUaGlzLCB3aW5lZDNkX3NldHRpbmdzLmxvZ28pOwogICAgfQogICAgVGhpcy0+aGlnaGVzdF9kaXJ0eV9wc19jb25zdCA9IDA7CiAgICBUaGlzLT5oaWdoZXN0X2RpcnR5X3ZzX2NvbnN0ID0gMDsKICAgIHJldHVybiBXSU5FRDNEX09LOwoKZXJyX291dDoKICAgIFRoaXMtPnNoYWRlcl9iYWNrZW5kLT5zaGFkZXJfZnJlZV9wcml2YXRlKGlmYWNlKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnJlbmRlcl90YXJnZXRzKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmZib19jb2xvcl9hdHRhY2htZW50cyk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5kcmF3X2J1ZmZlcnMpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+c3dhcGNoYWlucyk7CiAgICBUaGlzLT5OdW1iZXJPZlN3YXBDaGFpbnMgPSAwOwogICAgaWYoVGhpcy0+cGFsZXR0ZXMpIHsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5wYWxldHRlc1swXSk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cGFsZXR0ZXMpOwogICAgfQogICAgVGhpcy0+TnVtYmVyT2ZQYWxldHRlcyA9IDA7CiAgICBpZihzd2FwY2hhaW4pIHsKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKCAoSVdpbmVEM0RTd2FwQ2hhaW4gKikgc3dhcGNoYWluKTsKICAgIH0KICAgIFRoaXMtPmRyYXdfYnVmZmVycyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoR0xlbnVtKSAqIEdMX0xJTUlUUyhidWZmZXJzKSk7CiAgICBpZihUaGlzLT5zdGF0ZUJsb2NrKSB7CiAgICAgICAgSVdpbmVEM0RTdGF0ZUJsb2NrX1JlbGVhc2UoKElXaW5lRDNEU3RhdGVCbG9jayAqKSBUaGlzLT5zdGF0ZUJsb2NrKTsKICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrID0gTlVMTDsKICAgIH0KICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9VbmluaXQzRChJV2luZUQzRERldmljZSAqaWZhY2UsIEQzRENCX0RFU1RST1lTVVJGQUNFRk4gRDNEQ0JfRGVzdHJveURlcHRoU3RlbmNpbFN1cmZhY2UsIEQzRENCX0RFU1RST1lTV0FQQ0hBSU5GTiBEM0RDQl9EZXN0cm95U3dhcENoYWluKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgaW50IHNhbXBsZXI7CiAgICBVSU5UIGk7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgaWYoIVRoaXMtPmQzZF9pbml0aWFsaXplZCkgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgLyogSSBkb24ndCB0aGluayB0aGF0IHRoZSBpbnRlcmZhY2UgZ3VhcmFudGVlcyB0aGF0IHRoZSBkZXZpY2UgaXMgZGVzdHJveWVkIGZyb20gdGhlIHNhbWUgdGhyZWFkCiAgICAgKiBpdCB3YXMgY3JlYXRlZC4gVGh1cyBtYWtlIHN1cmUgYSBjb250ZXh0IGlzIGFjdGl2ZSBmb3IgdGhlIGdsRGVsZXRlKiBjYWxscwogICAgICovCiAgICBBY3RpdmF0ZUNvbnRleHQoVGhpcywgVGhpcy0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKCiAgICBpZihUaGlzLT5sb2dvX3N1cmZhY2UpIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKFRoaXMtPmxvZ29fc3VyZmFjZSk7CgogICAgVFJBQ0UoIkRlbGV0aW5nIGhpZ2ggb3JkZXIgcGF0Y2hlc1xuIik7CiAgICBmb3IoaSA9IDA7IGkgPCBQQVRDSE1BUF9TSVpFOyBpKyspIHsKICAgICAgICBzdHJ1Y3QgbGlzdCAqZTEsICplMjsKICAgICAgICBzdHJ1Y3QgV2luZUQzRFJlY3RQYXRjaCAqcGF0Y2g7CiAgICAgICAgTElTVF9GT1JfRUFDSF9TQUZFKGUxLCBlMiwgJlRoaXMtPnBhdGNoZXNbaV0pIHsKICAgICAgICAgICAgcGF0Y2ggPSBMSVNUX0VOVFJZKGUxLCBzdHJ1Y3QgV2luZUQzRFJlY3RQYXRjaCwgZW50cnkpOwogICAgICAgICAgICBJV2luZUQzRERldmljZV9EZWxldGVQYXRjaChpZmFjZSwgcGF0Y2gtPkhhbmRsZSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIERlbGV0ZSB0aGUgcGFsZXR0ZSBjb252ZXJzaW9uIHNoYWRlciBpZiBpdCBpcyBhcm91bmQgKi8KICAgIGlmKFRoaXMtPnBhbGV0dGVDb252ZXJzaW9uU2hhZGVyKSB7CiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICBHTF9FWFRDQUxMKGdsRGVsZXRlUHJvZ3JhbXNBUkIoMSwgJlRoaXMtPnBhbGV0dGVDb252ZXJzaW9uU2hhZGVyKSk7CiAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICBUaGlzLT5wYWxldHRlQ29udmVyc2lvblNoYWRlciA9IDA7CiAgICB9CgogICAgLyogRGVsZXRlIHRoZSBwYnVmZmVyIGNvbnRleHQgaWYgdGhlcmUgaXMgYW55ICovCiAgICBpZihUaGlzLT5wYnVmZmVyQ29udGV4dCkgRGVzdHJveUNvbnRleHQoVGhpcywgVGhpcy0+cGJ1ZmZlckNvbnRleHQpOwoKICAgIC8qIERlbGV0ZSB0aGUgbW91c2UgY3Vyc29yIHRleHR1cmUgKi8KICAgIGlmKFRoaXMtPmN1cnNvclRleHR1cmUpIHsKICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgIGdsRGVsZXRlVGV4dHVyZXMoMSwgJlRoaXMtPmN1cnNvclRleHR1cmUpOwogICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgVGhpcy0+Y3Vyc29yVGV4dHVyZSA9IDA7CiAgICB9CgogICAgZm9yIChzYW1wbGVyID0gMDsgc2FtcGxlciA8IE1BWF9GUkFHTUVOVF9TQU1QTEVSUzsgKytzYW1wbGVyKSB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0VGV4dHVyZShpZmFjZSwgc2FtcGxlciwgTlVMTCk7CiAgICB9CiAgICBmb3IgKHNhbXBsZXIgPSAwOyBzYW1wbGVyIDwgTUFYX1ZFUlRFWF9TQU1QTEVSUzsgKytzYW1wbGVyKSB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0VGV4dHVyZShpZmFjZSwgV0lORUQzRFZFUlRFWFRFWFRVUkVTQU1QTEVSMCArIHNhbXBsZXIsIE5VTEwpOwogICAgfQoKICAgIC8qIERlc3Ryb3kgdGhlIGRlcHRoIGJsdCByZXNvdXJjZXMsIHRoZXkgd2lsbCBiZSBpbnZhbGlkIGFmdGVyIHRoZSByZXNldC4gQWxzbyBmcmVlIHNoYWRlcgogICAgICogcHJpdmF0ZSBkYXRhLCBpdCBtaWdodCBjb250YWluIG9wZW5nbCBwb2ludGVycwogICAgICovCiAgICBUaGlzLT5zaGFkZXJfYmFja2VuZC0+c2hhZGVyX2Rlc3Ryb3lfZGVwdGhfYmx0KGlmYWNlKTsKICAgIFRoaXMtPnNoYWRlcl9iYWNrZW5kLT5zaGFkZXJfZnJlZV9wcml2YXRlKGlmYWNlKTsKCiAgICAvKiBSZWxlYXNlIHRoZSB1cGRhdGUgc3RhdGVibG9jayAqLwogICAgaWYoSVdpbmVEM0RTdGF0ZUJsb2NrX1JlbGVhc2UoKElXaW5lRDNEU3RhdGVCbG9jayAqKVRoaXMtPnVwZGF0ZVN0YXRlQmxvY2spID4gMCl7CiAgICAgICAgaWYoVGhpcy0+dXBkYXRlU3RhdGVCbG9jayAhPSBUaGlzLT5zdGF0ZUJsb2NrKQogICAgICAgICAgICBGSVhNRSgiKCVwKSBTb21ldGhpbmcncyBzdGlsbCBob2xkaW5nIHRoZSBVcGRhdGUgc3RhdGVibG9ja1xuIixUaGlzKTsKICAgIH0KICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2sgPSBOVUxMOwoKICAgIHsgLyogYmVjYXVzZSB3ZXJlIG5vdCBkb2luZyBwcm9wZXIgaW50ZXJuYWwgcmVmY291bnRzIHJlbGVhc2luZyB0aGUgcHJpbWFyeSBzdGF0ZSBibG9jawogICAgICAgIGNhdXNlcyByZWN1cnNpb24gd2l0aCB0aGUgZXh0cmEgY2hlY2tzIGluIFJlc291cmNlUmVsZWFzZWQsIHRvIGF2b2lkIHRoaXMgd2UgaGF2ZQogICAgICAgIHRvIHNldCB0aGlzLT5zdGF0ZUJsb2NrID0gTlVMTDsgZmlyc3QgKi8KICAgICAgICBJV2luZUQzRFN0YXRlQmxvY2sgKnN0YXRlQmxvY2sgPSAoSVdpbmVEM0RTdGF0ZUJsb2NrICopVGhpcy0+c3RhdGVCbG9jazsKICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrID0gTlVMTDsKCiAgICAgICAgLyogUmVsZWFzZSB0aGUgc3RhdGVibG9jayAqLwogICAgICAgIGlmKElXaW5lRDNEU3RhdGVCbG9ja19SZWxlYXNlKHN0YXRlQmxvY2spID4gMCl7CiAgICAgICAgICAgIEZJWE1FKCIoJXApIFNvbWV0aGluZydzIHN0aWxsIGhvbGRpbmcgdGhlIFVwZGF0ZSBzdGF0ZWJsb2NrXG4iLFRoaXMpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBSZWxlYXNlIHRoZSBidWZmZXJzICh3aXRoIHNhbml0eSBjaGVja3MpKi8KICAgIFRSQUNFKCJSZWxlYXNpbmcgdGhlIGRlcHRoIHN0ZW5jaWwgYnVmZmVyIGF0ICVwXG4iLCBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KTsKICAgIGlmKFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQgIT0gTlVMTCAmJiAoSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2UoVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCkgPjApKXsKICAgICAgICBpZihUaGlzLT5hdXRvX2RlcHRoX3N0ZW5jaWxfYnVmZmVyICE9IFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQpCiAgICAgICAgICAgIEZJWE1FKCIoJXApIFNvbWV0aGluZydzIHN0aWxsIGhvbGRpbmcgdGhlIHN0ZW5jaWxCdWZmZXJUYXJnZXRcbiIsVGhpcyk7CiAgICB9CiAgICBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0ID0gTlVMTDsKCiAgICBUUkFDRSgiUmVsZWFzaW5nIHRoZSByZW5kZXIgdGFyZ2V0IGF0ICVwXG4iLCBUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXSk7CiAgICBpZihJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXSkgPjApewogICAgICAgICAgLyogVGhpcyBjaGVjayBpcyBhIGJpdCBzaWxseSwgaXQgc2hvdWxkIGJlIGluIHN3YXBjaGFpbl9yZWxlYXNlIEZJWE1FKCIoJXApIFNvbWV0aGluZydzIHN0aWxsIGhvbGRpbmcgdGhlIHJlbmRlclRhcmdldFxuIixUaGlzKTsgKi8KICAgIH0KICAgIFRSQUNFKCJTZXR0aW5nIHJlbmRlcnRhcmdldCB0byBOVUxMXG4iKTsKICAgIFRoaXMtPnJlbmRlcl90YXJnZXRzWzBdID0gTlVMTDsKCiAgICBpZiAoVGhpcy0+YXV0b19kZXB0aF9zdGVuY2lsX2J1ZmZlcikgewogICAgICAgIGlmKEQzRENCX0Rlc3Ryb3lEZXB0aFN0ZW5jaWxTdXJmYWNlKFRoaXMtPmF1dG9fZGVwdGhfc3RlbmNpbF9idWZmZXIpID4gMCkgewogICAgICAgICAgICBGSVhNRSgiKCVwKSBTb21ldGhpbmcncyBzdGlsbCBob2xkaW5nIHRoZSBhdXRvIGRlcHRoIHN0ZW5jaWwgYnVmZmVyXG4iLCBUaGlzKTsKICAgICAgICB9CiAgICAgICAgVGhpcy0+YXV0b19kZXB0aF9zdGVuY2lsX2J1ZmZlciA9IE5VTEw7CiAgICB9CgogICAgZm9yKGk9MDsgaSA8IFRoaXMtPk51bWJlck9mU3dhcENoYWluczsgaSsrKSB7CiAgICAgICAgVFJBQ0UoIlJlbGVhc2luZyB0aGUgaW1wbGljaXQgc3dhcGNoYWluICVkXG4iLCBpKTsKICAgICAgICBpZiAoRDNEQ0JfRGVzdHJveVN3YXBDaGFpbihUaGlzLT5zd2FwY2hhaW5zW2ldKSAgPiAwKSB7CiAgICAgICAgICAgIEZJWE1FKCIoJXApIFNvbWV0aGluZydzIHN0aWxsIGhvbGRpbmcgdGhlIGltcGxpY2l0IHN3YXBjaGFpblxuIiwgVGhpcyk7CiAgICAgICAgfQogICAgfQoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnN3YXBjaGFpbnMpOwogICAgVGhpcy0+c3dhcGNoYWlucyA9IE5VTEw7CiAgICBUaGlzLT5OdW1iZXJPZlN3YXBDaGFpbnMgPSAwOwoKICAgIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5OdW1iZXJPZlBhbGV0dGVzOyBpKyspIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnBhbGV0dGVzW2ldKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnBhbGV0dGVzKTsKICAgIFRoaXMtPnBhbGV0dGVzID0gTlVMTDsKICAgIFRoaXMtPk51bWJlck9mUGFsZXR0ZXMgPSAwOwoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnJlbmRlcl90YXJnZXRzKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmZib19jb2xvcl9hdHRhY2htZW50cyk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5kcmF3X2J1ZmZlcnMpOwogICAgVGhpcy0+cmVuZGVyX3RhcmdldHMgPSBOVUxMOwogICAgVGhpcy0+ZmJvX2NvbG9yX2F0dGFjaG1lbnRzID0gTlVMTDsKICAgIFRoaXMtPmRyYXdfYnVmZmVycyA9IE5VTEw7CgogICAgVGhpcy0+ZDNkX2luaXRpYWxpemVkID0gRkFMU0U7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRGdWxsc2NyZWVuKElXaW5lRDNERGV2aWNlICppZmFjZSwgQk9PTCBmdWxsc2NyZWVuKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgVFJBQ0UoIiglcCkgU2V0dGluZyBERHJhdyBmdWxsc2NyZWVuIG1vZGUgdG8gJXNcbiIsIFRoaXMsIGZ1bGxzY3JlZW4gPyAidHJ1ZSIgOiAiZmFsc2UiKTsKCiAgICAvKiBTZXR1cCB0aGUgd2luZG93IGZvciBmdWxsc2NyZWVuIG1vZGUgKi8KICAgIGlmKGZ1bGxzY3JlZW4gJiYgIVRoaXMtPmRkcmF3X2Z1bGxzY3JlZW4pIHsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfU2V0dXBGdWxsc2NyZWVuV2luZG93KGlmYWNlLCBUaGlzLT5kZHJhd193aW5kb3cpOwogICAgfSBlbHNlIGlmKCFmdWxsc2NyZWVuICYmIFRoaXMtPmRkcmF3X2Z1bGxzY3JlZW4pIHsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfUmVzdG9yZVdpbmRvdyhpZmFjZSwgVGhpcy0+ZGRyYXdfd2luZG93KTsKICAgIH0KCiAgICAvKiBEaXJlY3REcmF3IGFwcHMgY2FuIGNoYW5nZSBiZXR3ZWVuIGZ1bGxzY3JlZW4gYW5kIHdpbmRvd2VkIG1vZGUgYWZ0ZXIgZGV2aWNlIGNyZWF0aW9uIHdpdGgKICAgICAqIElEaXJlY3REcmF3Nzo6U2V0Q29vcGVyYXRpdmVMZXZlbC4gVGhlIEdESSBzdXJmYWNlIGltcGxlbWVudGF0aW9uIG5lZWRzIHRvIGtub3cgdGhpcy4KICAgICAqIEREcmF3IGRvZXNuJ3QgbmVjZXNzYXJpbHkgaGF2ZSBhIHN3YXBjaGFpbiwgc28gd2UgaGF2ZSB0byBzdG9yZSB0aGUgZnVsbHNjcmVlbiBmbGFnCiAgICAgKiBzZXBhcmF0ZWx5LgogICAgICovCiAgICBUaGlzLT5kZHJhd19mdWxsc2NyZWVuID0gZnVsbHNjcmVlbjsKfQoKLyogRW5hYmxlcyB0aHJlYWQgc2FmZXR5IGluIHRoZSB3aW5lZDNkIGRldmljZSBhbmQgaXRzIHJlc291cmNlcy4gQ2FsbGVkIGJ5IERpcmVjdERyYXcKICogZnJvbSBTZXRDb29wZXJhdGl2ZUxldmVsIGlmIEREU0NMX01VTFRJVEhSRUFERUQgaXMgc3BlY2lmaWVkLCBhbmQgYnkgZDNkOC85IGZyb20KICogQ3JlYXRlRGV2aWNlIGlmIEQzRENSRUFURV9NVUxUSVRIUkVBREVEIGlzIHBhc3NlZC4KICoKICogVGhlcmUgaXMgbm8gd2F5IHRvIGRlYWN0aXZhdGUgdGhyZWFkIHNhZmV0eSBvbmNlIGl0IGlzIGVuYWJsZWQuCiAqLwpzdGF0aWMgdm9pZCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldE11bHRpdGhyZWFkZWQoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwoKICAgIC8qRm9yIG5vdyBqdXN0IHN0b3JlIHRoZSBmbGFnKG5lZWRlZCBpbiBjYXNlIG9mIGRkcmF3KSAqLwogICAgVGhpcy0+Y3JlYXRlUGFybXMuQmVoYXZpb3JGbGFncyB8PSBXSU5FRDNEQ1JFQVRFX01VTFRJVEhSRUFERUQ7CgogICAgcmV0dXJuOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldERpc3BsYXlNb2RlKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBpU3dhcENoYWluLCBXSU5FRDNERElTUExBWU1PREUqIHBNb2RlKSB7CiAgICBERVZNT0RFVyBkZXZtb2RlOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgTE9ORyByZXQ7CiAgICBjb25zdCBTdGF0aWNQaXhlbEZvcm1hdERlc2MgKmZvcm1hdERlc2MgID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KHBNb2RlLT5Gb3JtYXQsIE5VTEwsIE5VTEwpOwogICAgUkVDVCBjbGlwX3JjOwoKICAgIFRSQUNFKCIoJXApLT4oJWQsJXApIE1vZGU9JWR4JWR4QCVkLCAlc1xuIiwgVGhpcywgaVN3YXBDaGFpbiwgcE1vZGUsIHBNb2RlLT5XaWR0aCwgcE1vZGUtPkhlaWdodCwgcE1vZGUtPlJlZnJlc2hSYXRlLCBkZWJ1Z19kM2Rmb3JtYXQocE1vZGUtPkZvcm1hdCkpOwoKICAgIC8qIFJlc2l6ZSB0aGUgc2NyZWVuIGV2ZW4gd2l0aG91dCBhIHdpbmRvdzoKICAgICAqIFRoZSBhcHAgY291bGQgaGF2ZSB1bnNldCBpdCB3aXRoIFNldENvb3BlcmF0aXZlTGV2ZWwsIGJ1dCBub3QgY2FsbGVkCiAgICAgKiBSZXN0b3JlRGlzcGxheU1vZGUgZmlyc3QuIFRoZW4gdGhlIHJlbGVhc2Ugd2lsbCBjYWxsIFJlc3RvcmVEaXNwbGF5TW9kZSwKICAgICAqIGJ1dCB3ZSBkb24ndCBoYXZlIGFueSBod25kCiAgICAgKi8KCiAgICBtZW1zZXQoJmRldm1vZGUsIDAsIHNpemVvZihkZXZtb2RlKSk7CiAgICBkZXZtb2RlLmRtU2l6ZSA9IHNpemVvZihkZXZtb2RlKTsKICAgIGRldm1vZGUuZG1GaWVsZHMgPSBETV9CSVRTUEVSUEVMIHwgRE1fUEVMU1dJRFRIIHwgRE1fUEVMU0hFSUdIVDsKICAgIGRldm1vZGUuZG1CaXRzUGVyUGVsID0gZm9ybWF0RGVzYy0+YnBwICogODsKICAgIGRldm1vZGUuZG1QZWxzV2lkdGggID0gcE1vZGUtPldpZHRoOwogICAgZGV2bW9kZS5kbVBlbHNIZWlnaHQgPSBwTW9kZS0+SGVpZ2h0OwoKICAgIGRldm1vZGUuZG1EaXNwbGF5RnJlcXVlbmN5ID0gcE1vZGUtPlJlZnJlc2hSYXRlOwogICAgaWYgKHBNb2RlLT5SZWZyZXNoUmF0ZSAhPSAwKSAgewogICAgICAgIGRldm1vZGUuZG1GaWVsZHMgfD0gRE1fRElTUExBWUZSRVFVRU5DWTsKICAgIH0KCiAgICAvKiBPbmx5IGNoYW5nZSB0aGUgbW9kZSBpZiBuZWNlc3NhcnkgKi8KICAgIGlmKCAoVGhpcy0+ZGRyYXdfd2lkdGggPT0gcE1vZGUtPldpZHRoKSAmJgogICAgICAgIChUaGlzLT5kZHJhd19oZWlnaHQgPT0gcE1vZGUtPkhlaWdodCkgJiYKICAgICAgICAoVGhpcy0+ZGRyYXdfZm9ybWF0ID09IHBNb2RlLT5Gb3JtYXQpICYmCiAgICAgICAgKHBNb2RlLT5SZWZyZXNoUmF0ZSA9PSAwKSApIHsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICByZXQgPSBDaGFuZ2VEaXNwbGF5U2V0dGluZ3NFeFcoTlVMTCwgJmRldm1vZGUsIE5VTEwsIENEU19GVUxMU0NSRUVOLCBOVUxMKTsKICAgIGlmIChyZXQgIT0gRElTUF9DSEFOR0VfU1VDQ0VTU0ZVTCkgewogICAgICAgIGlmKGRldm1vZGUuZG1EaXNwbGF5RnJlcXVlbmN5ICE9IDApIHsKICAgICAgICAgICAgV0FSTigiQ2hhbmdlRGlzcGxheVNldHRpbmdzRXhXIGZhaWxlZCwgdHJ5aW5nIHdpdGhvdXQgdGhlIHJlZnJlc2ggcmF0ZVxuIik7CiAgICAgICAgICAgIGRldm1vZGUuZG1GaWVsZHMgJj0gfkRNX0RJU1BMQVlGUkVRVUVOQ1k7CiAgICAgICAgICAgIGRldm1vZGUuZG1EaXNwbGF5RnJlcXVlbmN5ID0gMDsKICAgICAgICAgICAgcmV0ID0gQ2hhbmdlRGlzcGxheVNldHRpbmdzRXhXKE5VTEwsICZkZXZtb2RlLCBOVUxMLCBDRFNfRlVMTFNDUkVFTiwgTlVMTCkgIT0gRElTUF9DSEFOR0VfU1VDQ0VTU0ZVTDsKICAgICAgICB9CiAgICAgICAgaWYocmV0ICE9IERJU1BfQ0hBTkdFX1NVQ0NFU1NGVUwpIHsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfTk9UQVZBSUxBQkxFOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBTdG9yZSB0aGUgbmV3IHZhbHVlcyAqLwogICAgVGhpcy0+ZGRyYXdfd2lkdGggPSBwTW9kZS0+V2lkdGg7CiAgICBUaGlzLT5kZHJhd19oZWlnaHQgPSBwTW9kZS0+SGVpZ2h0OwogICAgVGhpcy0+ZGRyYXdfZm9ybWF0ID0gcE1vZGUtPkZvcm1hdDsKCiAgICAvKiBPbmx5IGRvIHRoaXMgd2l0aCBhIHdpbmRvdyBvZiBjb3Vyc2UsIGFuZCBvbmx5IGlmIHdlJ3JlIGZ1bGxzY3JlZW5lZCAqLwogICAgaWYoVGhpcy0+ZGRyYXdfd2luZG93ICYmIFRoaXMtPmRkcmF3X2Z1bGxzY3JlZW4pCiAgICAgIE1vdmVXaW5kb3coVGhpcy0+ZGRyYXdfd2luZG93LCAwLCAwLCBwTW9kZS0+V2lkdGgsIHBNb2RlLT5IZWlnaHQsIFRSVUUpOwoKICAgIC8qIEFuZCBmaW5hbGx5IGNsaXAgbW91c2UgdG8gb3VyIHNjcmVlbiAqLwogICAgU2V0UmVjdCgmY2xpcF9yYywgMCwgMCwgcE1vZGUtPldpZHRoLCBwTW9kZS0+SGVpZ2h0KTsKICAgIENsaXBDdXJzb3IoJmNsaXBfcmMpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldERpcmVjdDNEKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0QgKipwcEQzRCkgewogICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICpwcEQzRD0gVGhpcy0+d2luZUQzRDsKICAgVFJBQ0UoIiglcCkgOiB3aW5lRDNEIHJldHVybmluZyAlcFxuIiwgVGhpcywgICpwcEQzRCk7CiAgIElXaW5lRDNEX0FkZFJlZigqcHBEM0QpOwogICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIFVJTlQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRBdmFpbGFibGVUZXh0dXJlTWVtKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXApIDogc2ltdWxhdGluZyAlZE1CLCByZXR1cm5pbmcgJWRNQiBsZWZ0XG4iLCAgVGhpcywKICAgICAgICAgKFRoaXMtPmFkYXB0ZXItPlRleHR1cmVSYW0vKDEwMjQqMTAyNCkpLAogICAgICAgICAoKFRoaXMtPmFkYXB0ZXItPlRleHR1cmVSYW0gLSBUaGlzLT5hZGFwdGVyLT5Vc2VkVGV4dHVyZVJhbSkgLyAoMTAyNCoxMDI0KSkpOwogICAgLyogcmV0dXJuIHNpbXVsYXRlZCB0ZXh0dXJlIG1lbW9yeSBsZWZ0ICovCiAgICByZXR1cm4gKFRoaXMtPmFkYXB0ZXItPlRleHR1cmVSYW0gLSBUaGlzLT5hZGFwdGVyLT5Vc2VkVGV4dHVyZVJhbSk7Cn0KCgoKLyoqKioqCiAqIEdldCAvIFNldCBGVkYKICoqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldEZWRihJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIGZ2ZikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIC8qIFVwZGF0ZSB0aGUgY3VycmVudCBzdGF0ZSBibG9jayAqLwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC5mdmYgICAgICA9IFRSVUU7CgogICAgaWYoVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+ZnZmID09IGZ2ZikgewogICAgICAgIFRSQUNFKCJBcHBsaWNhdGlvbiBpcyBzZXR0aW5nIHRoZSBvbGQgZnZmIG92ZXIsIG5vdGhpbmcgdG8gZG9cbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmZ2ZiAgICAgICAgICAgICAgPSBmdmY7CiAgICBUUkFDRSgiKCVwKSA6IEZWRiBTaGFkZXIgRlZGIHNldCB0byAleFxuIiwgVGhpcywgZnZmKTsKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9WREVDTCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0RlZGKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgKnBmdmYpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogR2V0RlZGIHJldHVybmluZyAleFxuIiwgVGhpcywgVGhpcy0+c3RhdGVCbG9jay0+ZnZmKTsKICAgICpwZnZmID0gVGhpcy0+c3RhdGVCbG9jay0+ZnZmOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBHZXQgLyBTZXQgU3RyZWFtIFNvdXJjZQogKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0U3RyZWFtU291cmNlKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBTdHJlYW1OdW1iZXIsSVdpbmVEM0RWZXJ0ZXhCdWZmZXIqIHBTdHJlYW1EYXRhLCBVSU5UIE9mZnNldEluQnl0ZXMsIFVJTlQgU3RyaWRlKSB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsICAgICAgICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RWZXJ0ZXhCdWZmZXIgICAgICpvbGRTcmM7CgogICAgaWYgKFN0cmVhbU51bWJlciA+PSBNQVhfU1RSRUFNUykgewogICAgICAgIFdBUk4oIlN0cmVhbSBvdXQgb2YgcmFuZ2UgJWRcbiIsIFN0cmVhbU51bWJlcik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9IGVsc2UgaWYoT2Zmc2V0SW5CeXRlcyAmIDB4MykgewogICAgICAgIFdBUk4oIk9mZnNldEluQnl0ZXMgaXMgbm90IDQgYnl0ZSBhbGlnbmVkOiAlZFxuIiwgT2Zmc2V0SW5CeXRlcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgb2xkU3JjID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c3RyZWFtU291cmNlW1N0cmVhbU51bWJlcl07CiAgICBUUkFDRSgiKCVwKSA6IFN0cmVhbU5vOiAldSwgT2xkU3RyZWFtICglcCksIE5ld1N0cmVhbSAoJXApLCBPZmZzZXRJbkJ5dGVzICV1LCBOZXdTdHJpZGUgJXVcbiIsIFRoaXMsIFN0cmVhbU51bWJlciwgb2xkU3JjLCBwU3RyZWFtRGF0YSwgT2Zmc2V0SW5CeXRlcywgU3RyaWRlKTsKCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnN0cmVhbVNvdXJjZVtTdHJlYW1OdW1iZXJdID0gVFJVRTsKCiAgICBpZihvbGRTcmMgPT0gcFN0cmVhbURhdGEgJiYKICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbVN0cmlkZVtTdHJlYW1OdW1iZXJdID09IFN0cmlkZSAmJgogICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c3RyZWFtT2Zmc2V0W1N0cmVhbU51bWJlcl0gPT0gT2Zmc2V0SW5CeXRlcykgewogICAgICAgVFJBQ0UoIkFwcGxpY2F0aW9uIGlzIHNldHRpbmcgdGhlIG9sZCB2YWx1ZXMgb3Zlciwgbm90aGluZyB0byBkb1xuIik7CiAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbU3RyZWFtTnVtYmVyXSAgICAgICAgID0gcFN0cmVhbURhdGE7CiAgICBpZiAocFN0cmVhbURhdGEpIHsKICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1TdHJpZGVbU3RyZWFtTnVtYmVyXSAgICAgPSBTdHJpZGU7CiAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c3RyZWFtT2Zmc2V0W1N0cmVhbU51bWJlcl0gICAgID0gT2Zmc2V0SW5CeXRlczsKICAgIH0KCiAgICAvKiBIYW5kbGUgcmVjb3JkaW5nIG9mIHN0YXRlIGJsb2NrcyAqLwogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICBpZihwU3RyZWFtRGF0YSkgSVdpbmVEM0RWZXJ0ZXhCdWZmZXJfQWRkUmVmKHBTdHJlYW1EYXRhKTsKICAgICAgICBpZihvbGRTcmMpIElXaW5lRDNEVmVydGV4QnVmZmVyX1JlbGVhc2Uob2xkU3JjKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICAvKiBOZWVkIHRvIGRvIGEgZ2V0UGFyZW50IGFuZCBwYXNzIHRoZSByZWZlcmVuY2VzIHVwICovCiAgICAvKiBNU0ROIHNheXMgLi4uLi4gV2hlbiBhbiBhcHBsaWNhdGlvbiBubyBsb25nZXIgaG9sZHMgYSByZWZlcmVuY2UgdG8gdGhpcyBpbnRlcmZhY2UsIHRoZSBpbnRlcmZhY2Ugd2lsbCBhdXRvbWF0aWNhbGx5IGJlIGZyZWVkLgogICAgd2hpY2ggc3VnZ2VzdHMgdGhhdCB3ZSBzaG91bGRuJ3QgYmUgcmVmIGNvdW50aW5nPyBhbmQgZG8gbmVlZCBhIF9yZWxlYXNlIG9uIHRoZSBzdHJlYW0gc291cmNlIHRvIHJlc2V0IHRoZSBzdHJlYW0gc291cmNlCiAgICBzbyBmb3Igbm93LCBqdXN0IGNvdW50IGludGVybmFsbHkgICAqLwogICAgaWYgKHBTdHJlYW1EYXRhICE9IE5VTEwpIHsKICAgICAgICBJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKnZiSW1wbCA9IChJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKikgcFN0cmVhbURhdGE7CiAgICAgICAgSW50ZXJsb2NrZWRJbmNyZW1lbnQoJnZiSW1wbC0+YmluZENvdW50KTsKICAgICAgICBJV2luZUQzRFZlcnRleEJ1ZmZlcl9BZGRSZWYocFN0cmVhbURhdGEpOwogICAgfQogICAgaWYgKG9sZFNyYyAhPSBOVUxMKSB7CiAgICAgICAgSW50ZXJsb2NrZWREZWNyZW1lbnQoJigoSVdpbmVEM0RWZXJ0ZXhCdWZmZXJJbXBsICopIG9sZFNyYyktPmJpbmRDb3VudCk7CiAgICAgICAgSVdpbmVEM0RWZXJ0ZXhCdWZmZXJfUmVsZWFzZShvbGRTcmMpOwogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TVFJFQU1TUkMpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFN0cmVhbVNvdXJjZShJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgU3RyZWFtTnVtYmVyLElXaW5lRDNEVmVydGV4QnVmZmVyKiogcFN0cmVhbSwgVUlOVCAqcE9mZnNldCwgVUlOVCogcFN0cmlkZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXApIDogU3RyZWFtTm86ICV1LCBTdHJlYW0gKCVwKSwgT2Zmc2V0ICV1LCBTdHJpZGUgJXVcbiIsIFRoaXMsIFN0cmVhbU51bWJlciwKICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbU3RyZWFtTnVtYmVyXSwKICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1PZmZzZXRbU3RyZWFtTnVtYmVyXSwKICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1TdHJpZGVbU3RyZWFtTnVtYmVyXSk7CgogICAgaWYgKFN0cmVhbU51bWJlciA+PSBNQVhfU1RSRUFNUykgewogICAgICAgIFdBUk4oIlN0cmVhbSBvdXQgb2YgcmFuZ2UgJWRcbiIsIFN0cmVhbU51bWJlcik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICAqcFN0cmVhbSA9IFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtTdHJlYW1OdW1iZXJdOwogICAgKnBTdHJpZGUgPSBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1TdHJpZGVbU3RyZWFtTnVtYmVyXTsKICAgIGlmIChwT2Zmc2V0KSB7CiAgICAgICAgKnBPZmZzZXQgPSBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1PZmZzZXRbU3RyZWFtTnVtYmVyXTsKICAgIH0KCiAgICBpZiAoKnBTdHJlYW0gIT0gTlVMTCkgewogICAgICAgIElXaW5lRDNEVmVydGV4QnVmZmVyX0FkZFJlZigqcFN0cmVhbSk7IC8qIFdlIGhhdmUgY3JlYXRlZCBhIG5ldyByZWZlcmVuY2UgdG8gdGhlIFZCICovCiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRTdHJlYW1Tb3VyY2VGcmVxKElXaW5lRDNERGV2aWNlICppZmFjZSwgIFVJTlQgU3RyZWFtTnVtYmVyLCBVSU5UIERpdmlkZXIpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFVJTlQgb2xkRmxhZ3MgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1GbGFnc1tTdHJlYW1OdW1iZXJdOwogICAgVUlOVCBvbGRGcmVxID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c3RyZWFtRnJlcVtTdHJlYW1OdW1iZXJdOwoKICAgIC8qIFZlcmlmeSBpbnB1dCBhdCBsZWFzdCBpbiBkM2Q5IHRoaXMgaXMgaW52YWxpZCovCiAgICBpZiggKERpdmlkZXIgJiBXSU5FRDNEU1RSRUFNU09VUkNFX0lOU1RBTkNFREFUQSkgJiYgKERpdmlkZXIgJiBXSU5FRDNEU1RSRUFNU09VUkNFX0lOREVYRUREQVRBKSl7CiAgICAgICAgV0FSTigiSU5TVEFOQ0VEQVRBIGFuZCBJTkRFWEVEREFUQSB3ZXJlIHNldCwgcmV0dXJuaW5nIEQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICBpZiggKERpdmlkZXIgJiBXSU5FRDNEU1RSRUFNU09VUkNFX0lOU1RBTkNFREFUQSkgJiYgU3RyZWFtTnVtYmVyID09IDAgKXsKICAgICAgICBXQVJOKCJJTlNUQU5DRURBVEEgdXNlZCBvbiBzdHJlYW0gMCwgcmV0dXJuaW5nIEQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICBpZiggRGl2aWRlciA9PSAwICl7CiAgICAgICAgV0FSTigiRGl2aWRlciBpcyAwLCByZXR1cm5pbmcgRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBUUkFDRSgiKCVwKSBTdHJlYW1OdW1iZXIoJWQpLCBEaXZpZGVyKCVkKVxuIiwgVGhpcywgU3RyZWFtTnVtYmVyLCBEaXZpZGVyKTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbUZsYWdzW1N0cmVhbU51bWJlcl0gPSBEaXZpZGVyICYgKFdJTkVEM0RTVFJFQU1TT1VSQ0VfSU5TVEFOQ0VEQVRBICB8IFdJTkVEM0RTVFJFQU1TT1VSQ0VfSU5ERVhFRERBVEEgKTsKCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnN0cmVhbUZyZXFbU3RyZWFtTnVtYmVyXSAgPSBUUlVFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c3RyZWFtRnJlcVtTdHJlYW1OdW1iZXJdICAgICAgICAgID0gRGl2aWRlciAmIDB4N0ZGRkZGOwoKICAgIGlmKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbUZyZXFbU3RyZWFtTnVtYmVyXSAhPSBvbGRGcmVxIHx8CiAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1GbGFnc1tTdHJlYW1OdW1iZXJdICE9IG9sZEZsYWdzKSB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1NUUkVBTVNSQyk7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0U3RyZWFtU291cmNlRnJlcShJV2luZUQzRERldmljZSAqaWZhY2UsICBVSU5UIFN0cmVhbU51bWJlciwgVUlOVCogRGl2aWRlcikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXApIFN0cmVhbU51bWJlciglZCksIERpdmlkZXIoJXApXG4iLCBUaGlzLCBTdHJlYW1OdW1iZXIsIERpdmlkZXIpOwogICAgKkRpdmlkZXIgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1GcmVxW1N0cmVhbU51bWJlcl0gfCBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1GbGFnc1tTdHJlYW1OdW1iZXJdOwoKICAgIFRSQUNFKCIoJXApIDogcmV0dXJuaW5nICVkXG4iLCBUaGlzLCAqRGl2aWRlcik7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBHZXQgLyBTZXQgJiBNdWx0aXBseSBUcmFuc2Zvcm0KICoqKioqLwpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfU2V0VHJhbnNmb3JtKElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRFRSQU5TRk9STVNUQVRFVFlQRSBkM2R0cywgQ09OU1QgV0lORUQzRE1BVFJJWCogbHBtYXRyaXgpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICAvKiBNb3N0IG9mIHRoaXMgcm91dGluZSwgY29tbWVudHMgaW5jbHVkZWQgY29waWVkIGZyb20gZGRyYXcgdHJlZSBpbml0aWFsbHk6ICovCiAgICBUUkFDRSgiKCVwKSA6IFRyYW5zZm9ybSBTdGF0ZT0lc1xuIiwgVGhpcywgZGVidWdfZDNkdHN0eXBlKGQzZHRzKSk7CgogICAgLyogSGFuZGxlIHJlY29yZGluZyBvZiBzdGF0ZSBibG9ja3MgKi8KICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC50cmFuc2Zvcm1bZDNkdHNdID0gVFJVRTsKICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50cmFuc2Zvcm1zW2QzZHRzXSA9ICpscG1hdHJpeDsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICAvKgogICAgICogSWYgdGhlIG5ldyBtYXRyaXggaXMgdGhlIHNhbWUgYXMgdGhlIGN1cnJlbnQgb25lLAogICAgICogd2UgY3V0IG9mZiBhbnkgZnVydGhlciBwcm9jZXNzaW5nLiB0aGlzIHNlZW1zIHRvIGJlIGEgcmVhc29uYWJsZQogICAgICogb3B0aW1pemF0aW9uIGJlY2F1c2UgYXMgd2FzIG5vdGljZWQsIHNvbWUgYXBwcyAod2FyY3JhZnQzIGZvciBleGFtcGxlKQogICAgICogdGVuZCB0b3dhcmRzIHNldHRpbmcgdGhlIHNhbWUgbWF0cml4IHJlcGVhdGVkbHkgZm9yIHNvbWUgcmVhc29uLgogICAgICoKICAgICAqIEZyb20gaGVyZSBvbiB3ZSBhc3N1bWUgdGhhdCB0aGUgbmV3IG1hdHJpeCBpcyBkaWZmZXJlbnQsIHdoZXJldmVyIGl0IG1hdHRlcnMuCiAgICAgKi8KICAgIGlmICghbWVtY21wKCZUaGlzLT5zdGF0ZUJsb2NrLT50cmFuc2Zvcm1zW2QzZHRzXS51Lm1bMF1bMF0sIGxwbWF0cml4LCBzaXplb2YoV0lORUQzRE1BVFJJWCkpKSB7CiAgICAgICAgVFJBQ0UoIlRoZSBhcHAgaXMgc2V0dGluZyB0aGUgc2FtZSBtYXRyaXggb3ZlciBhZ2FpblxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9IGVsc2UgewogICAgICAgIGNvbnZfbWF0KGxwbWF0cml4LCAmVGhpcy0+c3RhdGVCbG9jay0+dHJhbnNmb3Jtc1tkM2R0c10udS5tWzBdWzBdKTsKICAgIH0KCiAgICAvKgogICAgICAgU2NyZWVuQ29vcmQgPSBQcm9qZWN0aW9uTWF0ICogVmlld01hdCAqIFdvcmxkTWF0ICogT2JqZWN0Q29vcmQKICAgICAgIHdoZXJlIFZpZXdNYXQgPSBDYW1lcmEgc3BhY2UsIFdvcmxkTWF0ID0gd29ybGQgc3BhY2UuCgogICAgICAgSW4gT3BlbkdMLCBjYW1lcmEgYW5kIHdvcmxkIHNwYWNlIGlzIGNvbWJpbmVkIGludG8gR0xfTU9ERUxWSUVXCiAgICAgICBtYXRyaXguICBUaGUgUHJvamVjdGlvbiBtYXRyaXggc3RheSBwcm9qZWN0aW9uIG1hdHJpeC4KICAgICAqLwoKICAgIC8qIENhcHR1cmUgdGhlIHRpbWVzIHdlIGNhbiBqdXN0IGlnbm9yZSB0aGUgY2hhbmdlIGZvciBub3cgKi8KICAgIGlmIChkM2R0cyA9PSBXSU5FRDNEVFNfVklFVykgeyAvKiBoYW5kbGUgdGhlIFZJRVcgbWF0cml4ICovCiAgICAgICAgVGhpcy0+dmlld19pZGVudCA9ICFtZW1jbXAobHBtYXRyaXgsIGlkZW50aXR5LCAxNiAqIHNpemVvZihmbG9hdCkpOwogICAgICAgIC8qIEhhbmRsZWQgYnkgdGhlIHN0YXRlIG1hbmFnZXIgKi8KICAgIH0KCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVFJBTlNGT1JNKGQzZHRzKSk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKCn0Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRUcmFuc2Zvcm0oSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEVFJBTlNGT1JNU1RBVEVUWVBFIFN0YXRlLCBXSU5FRDNETUFUUklYKiBwTWF0cml4KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IGZvciBUcmFuc2Zvcm0gU3RhdGUgJXNcbiIsIFRoaXMsIGRlYnVnX2QzZHRzdHlwZShTdGF0ZSkpOwogICAgKnBNYXRyaXggPSBUaGlzLT5zdGF0ZUJsb2NrLT50cmFuc2Zvcm1zW1N0YXRlXTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX011bHRpcGx5VHJhbnNmb3JtKElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRFRSQU5TRk9STVNUQVRFVFlQRSBTdGF0ZSwgQ09OU1QgV0lORUQzRE1BVFJJWCogcE1hdHJpeCkgewogICAgV0lORUQzRE1BVFJJWCAqbWF0ID0gTlVMTDsKICAgIFdJTkVEM0RNQVRSSVggdGVtcDsKCiAgICAvKiBOb3RlOiBVc2luZyAndXBkYXRlU3RhdGVCbG9jaycgcmF0aGVyIHRoYW4gJ3N0YXRlYmxvY2snIGluIHRoZSBjb2RlCiAgICAgKiBiZWxvdyBtZWFucyBpdCB3aWxsIGJlIHJlY29yZGVkIGluIGEgc3RhdGUgYmxvY2sgY2hhbmdlLCBidXQgaXQKICAgICAqIHdvcmtzIHJlZ2FyZGxlc3Mgd2hlcmUgaXQgaXMgcmVjb3JkZWQuCiAgICAgKiBJZiB0aGlzIGlzIGZvdW5kIHRvIGJlIHdyb25nLCBjaGFuZ2UgdG8gU3RhdGVCbG9jay4KICAgICAqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiBGb3Igc3RhdGUgJXNcbiIsIFRoaXMsIGRlYnVnX2QzZHRzdHlwZShTdGF0ZSkpOwoKICAgIGlmIChTdGF0ZSA8IEhJR0hFU1RfVFJBTlNGT1JNU1RBVEUpCiAgICB7CiAgICAgICAgbWF0ID0gJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRyYW5zZm9ybXNbU3RhdGVdOwogICAgfSBlbHNlIHsKICAgICAgICBGSVhNRSgiVW5oYW5kbGVkIHRyYW5zZm9ybSBzdGF0ZSEhXG4iKTsKICAgIH0KCiAgICBtdWx0aXBseV9tYXRyaXgoJnRlbXAsIG1hdCwgcE1hdHJpeCk7CgogICAgLyogQXBwbHkgY2hhbmdlIHZpYSBzZXQgdHJhbnNmb3JtIC0gd2lsbCByZWFwcGx5IHRvIGVnLiBsaWdodHMgdGhpcyB3YXkgKi8KICAgIHJldHVybiBJV2luZUQzRERldmljZUltcGxfU2V0VHJhbnNmb3JtKGlmYWNlLCBTdGF0ZSwgJnRlbXApOwp9CgovKioqKioKICogR2V0IC8gU2V0IExpZ2h0CiAqKioqKi8KLyogTm90ZSBsaWdodHMgYXJlIHJlYWwgc3BlY2lhbCBjYXNlcy4gQWx0aG91Z2ggdGhlIGRldmljZSBjYXBzIHN0YXRlIG9ubHkgZWcuIDggYXJlIHN1cHBvcnRlZCwKICAgeW91IGNhbiByZWZlcmVuY2UgYW55IGluZGV4ZXMgeW91IHdhbnQgYXMgbG9uZyBhcyB0aGF0IG51bWJlciBtYXggYXJlIGVuYWJsZWQgYXQgYW55CiAgIG9uZSBwb2ludCBpbiB0aW1lISBUaGVyZWZvcmUgc2luY2UgdGhlIGluZGV4ZXMgY2FuIGJlIGFueXRoaW5nLCB3ZSBuZWVkIGEgaGFzaG1hcCBvZiB0aGVtLgogICBIb3dldmVyLCB0aGlzIGNhdXNlcyBzdGF0ZWJsb2NrIHByb2JsZW1zLiBXaGVuIGNhcHR1cmluZyB0aGUgc3RhdGUgYmxvY2ssIEkgZHVwbGljYXRlIHRoZSBoYXNobWFwLAogICBidXQgd2hlbiByZWNvcmRpbmcsIGp1c3QgYnVpbGQgYSBjaGFpbiBwcmV0dHkgbXVjaCBvZiBjb21tYW5kcyB0byBiZSByZXBsYXllZC4gICAgICAgICAgICAgICAgICAqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRMaWdodChJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIEluZGV4LCBDT05TVCBXSU5FRDNETElHSFQqIHBMaWdodCkgewogICAgZmxvYXQgcmhvOwogICAgUExJR0hUSU5GT0VMICpvYmplY3QgPSBOVUxMOwogICAgVUlOVCBIaSA9IExJR0hUTUFQX0hBU0hGVU5DKEluZGV4KTsKICAgIHN0cnVjdCBsaXN0ICplOwoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogSWR4KCVkKSwgcExpZ2h0KCVwKS4gSGFzaCBpbmRleCBpcyAlZFxuIiwgVGhpcywgSW5kZXgsIHBMaWdodCwgSGkpOwoKICAgIC8qIENoZWNrIHRoZSBwYXJhbWV0ZXIgcmFuZ2UuIE5lZWQgZm9yIHNwZWVkIG1vc3Qgd2FudGVkIHNldHMganVuayBsaWdodHMgd2hpY2ggY29uZnVzZQogICAgICogdGhlIGdsIGRyaXZlci4KICAgICAqLwogICAgaWYoIXBMaWdodCkgewogICAgICAgIFdBUk4oIkxpZ2h0IHBvaW50ZXIgPSBOVUxMLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgc3dpdGNoKHBMaWdodC0+VHlwZSkgewogICAgICAgIGNhc2UgV0lORUQzRExJR0hUX1BPSU5UOgogICAgICAgIGNhc2UgV0lORUQzRExJR0hUX1NQT1Q6CiAgICAgICAgY2FzZSBXSU5FRDNETElHSFRfUEFSQUxMRUxQT0lOVDoKICAgICAgICBjYXNlIFdJTkVEM0RMSUdIVF9HTFNQT1Q6CiAgICAgICAgICAgIC8qIEluY29ycmVjdCBhdHRlbnVhdGlvbiB2YWx1ZXMgY2FuIGNhdXNlIHRoZSBnbCBkcml2ZXIgdG8gY3Jhc2guIEhhcHBlbnMgd2l0aCBOZWVkIGZvciBzcGVlZAogICAgICAgICAgICAgKiBtb3N0IHdhbnRlZAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYocExpZ2h0LT5BdHRlbnVhdGlvbjAgPCAwLjAgfHwgcExpZ2h0LT5BdHRlbnVhdGlvbjEgPCAwLjAgfHwgcExpZ2h0LT5BdHRlbnVhdGlvbjIgPCAwLjApIHsKICAgICAgICAgICAgICAgIFdBUk4oIkF0dGVudWF0aW9uIGlzIG5lZ2F0aXZlLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNETElHSFRfRElSRUNUSU9OQUw6CiAgICAgICAgICAgIC8qIElnbm9yZXMgYXR0ZW51YXRpb24gKi8KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgV0FSTigiTGlnaHQgdHlwZSBvdXQgb2YgcmFuZ2UsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBMSVNUX0ZPUl9FQUNIKGUsICZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5saWdodE1hcFtIaV0pIHsKICAgICAgICBvYmplY3QgPSBMSVNUX0VOVFJZKGUsIFBMSUdIVElORk9FTCwgZW50cnkpOwogICAgICAgIGlmKG9iamVjdC0+T3JpZ2luYWxJbmRleCA9PSBJbmRleCkgYnJlYWs7CiAgICAgICAgb2JqZWN0ID0gTlVMTDsKICAgIH0KCiAgICBpZighb2JqZWN0KSB7CiAgICAgICAgVFJBQ0UoIkFkZGluZyBuZXcgbGlnaHRcbiIpOwogICAgICAgIG9iamVjdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoKm9iamVjdCkpOwogICAgICAgIGlmKCFvYmplY3QpIHsKICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5IGVycm9yIHdoZW4gYWxsb2NhdGluZyBhIGxpZ2h0XG4iKTsKICAgICAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICAgICAgfQogICAgICAgIGxpc3RfYWRkX2hlYWQoJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmxpZ2h0TWFwW0hpXSwgJm9iamVjdC0+ZW50cnkpOwogICAgICAgIG9iamVjdC0+Z2xJbmRleCA9IC0xOwogICAgICAgIG9iamVjdC0+T3JpZ2luYWxJbmRleCA9IEluZGV4OwogICAgICAgIG9iamVjdC0+Y2hhbmdlZCA9IFRSVUU7CiAgICB9CgogICAgLyogSW5pdGlhbGl6ZSB0aGUgb2JqZWN0ICovCiAgICBUUkFDRSgiTGlnaHQgJWQgc2V0dGluZyB0byB0eXBlICVkLCBEaWZmdXNlKCVmLCVmLCVmLCVmKSwgU3BlY3VsYXIoJWYsJWYsJWYsJWYpLCBBbWJpZW50KCVmLCVmLCVmLCVmKVxuIiwgSW5kZXgsIHBMaWdodC0+VHlwZSwKICAgICAgICAgIHBMaWdodC0+RGlmZnVzZS5yLCBwTGlnaHQtPkRpZmZ1c2UuZywgcExpZ2h0LT5EaWZmdXNlLmIsIHBMaWdodC0+RGlmZnVzZS5hLAogICAgICAgICAgcExpZ2h0LT5TcGVjdWxhci5yLCBwTGlnaHQtPlNwZWN1bGFyLmcsIHBMaWdodC0+U3BlY3VsYXIuYiwgcExpZ2h0LT5TcGVjdWxhci5hLAogICAgICAgICAgcExpZ2h0LT5BbWJpZW50LnIsIHBMaWdodC0+QW1iaWVudC5nLCBwTGlnaHQtPkFtYmllbnQuYiwgcExpZ2h0LT5BbWJpZW50LmEpOwogICAgVFJBQ0UoIi4uLiBQb3MoJWYsJWYsJWYpLCBEaXJuKCVmLCVmLCVmKVxuIiwgcExpZ2h0LT5Qb3NpdGlvbi54LCBwTGlnaHQtPlBvc2l0aW9uLnksIHBMaWdodC0+UG9zaXRpb24ueiwKICAgICAgICAgIHBMaWdodC0+RGlyZWN0aW9uLngsIHBMaWdodC0+RGlyZWN0aW9uLnksIHBMaWdodC0+RGlyZWN0aW9uLnopOwogICAgVFJBQ0UoIi4uLiBSYW5nZSglZiksIEZhbGxvZmYoJWYpLCBUaGV0YSglZiksIFBoaSglZilcbiIsIHBMaWdodC0+UmFuZ2UsIHBMaWdodC0+RmFsbG9mZiwgcExpZ2h0LT5UaGV0YSwgcExpZ2h0LT5QaGkpOwoKICAgIC8qIFNhdmUgYXdheSB0aGUgaW5mb3JtYXRpb24gKi8KICAgIG9iamVjdC0+T3JpZ2luYWxQYXJtcyA9ICpwTGlnaHQ7CgogICAgc3dpdGNoIChwTGlnaHQtPlR5cGUpIHsKICAgIGNhc2UgV0lORUQzRExJR0hUX1BPSU5UOgogICAgICAgIC8qIFBvc2l0aW9uICovCiAgICAgICAgb2JqZWN0LT5saWdodFBvc25bMF0gPSBwTGlnaHQtPlBvc2l0aW9uLng7CiAgICAgICAgb2JqZWN0LT5saWdodFBvc25bMV0gPSBwTGlnaHQtPlBvc2l0aW9uLnk7CiAgICAgICAgb2JqZWN0LT5saWdodFBvc25bMl0gPSBwTGlnaHQtPlBvc2l0aW9uLno7CiAgICAgICAgb2JqZWN0LT5saWdodFBvc25bM10gPSAxLjBmOwogICAgICAgIG9iamVjdC0+Y3V0b2ZmID0gMTgwLjBmOwogICAgICAgIC8qIEZJWE1FOiBSYW5nZSAqLwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lORUQzRExJR0hUX0RJUkVDVElPTkFMOgogICAgICAgIC8qIERpcmVjdGlvbiAqLwogICAgICAgIG9iamVjdC0+bGlnaHRQb3NuWzBdID0gLXBMaWdodC0+RGlyZWN0aW9uLng7CiAgICAgICAgb2JqZWN0LT5saWdodFBvc25bMV0gPSAtcExpZ2h0LT5EaXJlY3Rpb24ueTsKICAgICAgICBvYmplY3QtPmxpZ2h0UG9zblsyXSA9IC1wTGlnaHQtPkRpcmVjdGlvbi56OwogICAgICAgIG9iamVjdC0+bGlnaHRQb3NuWzNdID0gMC4wOwogICAgICAgIG9iamVjdC0+ZXhwb25lbnQgICAgID0gMC4wZjsKICAgICAgICBvYmplY3QtPmN1dG9mZiAgICAgICA9IDE4MC4wZjsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RMSUdIVF9TUE9UOgogICAgICAgIC8qIFBvc2l0aW9uICovCiAgICAgICAgb2JqZWN0LT5saWdodFBvc25bMF0gPSBwTGlnaHQtPlBvc2l0aW9uLng7CiAgICAgICAgb2JqZWN0LT5saWdodFBvc25bMV0gPSBwTGlnaHQtPlBvc2l0aW9uLnk7CiAgICAgICAgb2JqZWN0LT5saWdodFBvc25bMl0gPSBwTGlnaHQtPlBvc2l0aW9uLno7CiAgICAgICAgb2JqZWN0LT5saWdodFBvc25bM10gPSAxLjA7CgogICAgICAgIC8qIERpcmVjdGlvbiAqLwogICAgICAgIG9iamVjdC0+bGlnaHREaXJuWzBdID0gcExpZ2h0LT5EaXJlY3Rpb24ueDsKICAgICAgICBvYmplY3QtPmxpZ2h0RGlyblsxXSA9IHBMaWdodC0+RGlyZWN0aW9uLnk7CiAgICAgICAgb2JqZWN0LT5saWdodERpcm5bMl0gPSBwTGlnaHQtPkRpcmVjdGlvbi56OwogICAgICAgIG9iamVjdC0+bGlnaHREaXJuWzNdID0gMS4wOwoKICAgICAgICAvKgogICAgICAgICAqIG9wZW5nbC1pc2ggYW5kIGQzZC1pc2ggc3BvdCBsaWdodHMgdXNlIHRvbyBkaWZmZXJlbnQgbW9kZWxzIGZvciB0aGUKICAgICAgICAgKiBsaWdodCAiaW50ZW5zaXR5IiBhcyBhIGZ1bmN0aW9uIG9mIHRoZSBhbmdsZSB0b3dhcmRzIHRoZSBtYWluIGxpZ2h0IGRpcmVjdGlvbiwKICAgICAgICAgKiBzbyB3ZSBvbmx5IGNhbiBhcHByb3hpbWF0ZSB2ZXJ5IHJvdWdobHkuCiAgICAgICAgICogaG93ZXZlciBzcG90IGxpZ2h0cyBhcmUgcmF0aGVyIHJhcmVseSB1c2VkIGluIGdhbWVzIChpZiBldmVyIHVzZWQgYXQgYWxsKS4KICAgICAgICAgKiBmdXJ0aGVybW9yZSBpZiBzdGlsbCB1c2VkLCBwcm9iYWJseSBub2JvZHkgcGF5cyBhdHRlbnRpb24gdG8gc3VjaCBkZXRhaWxzLgogICAgICAgICAqLwogICAgICAgIGlmIChwTGlnaHQtPkZhbGxvZmYgPT0gMCkgewogICAgICAgICAgICAvKiBGYWxsb2ZmID0gMCBpcyBlYXN5LCBiZWNhdXNlIGQzZCdzIGFuZCBvcGVuZ2wncyBzcG90IGxpZ2h0IGVxdWF0aW9ucyBoYXZlIHRoZQogICAgICAgICAgICAgKiBmYWxsb2ZmIHJlc3AuIGV4cG9uZW50IHBhcmFtZXRlciBhcyBhbiBleHBvbmVudCwgc28gdGhlIHNwb3QgbGlnaHQgbGlnaHRpbmcKICAgICAgICAgICAgICogd2lsbCBhbHdheXMgYmUgMS4wIGZvciBib3RoIG9mIHRoZW0sIGFuZCB3ZSBkb24ndCBoYXZlIHRvIGNhcmUgZm9yIHRoZQogICAgICAgICAgICAgKiByZXN0IG9mIHRoZSByYXRoZXIgY29tcGxleCBjYWxjdWxhdGlvbgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgb2JqZWN0LT5leHBvbmVudCA9IDA7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmhvID0gcExpZ2h0LT5UaGV0YSArIChwTGlnaHQtPlBoaSAtIHBMaWdodC0+VGhldGEpLygyKnBMaWdodC0+RmFsbG9mZik7CiAgICAgICAgICAgIGlmIChyaG8gPCAwLjAwMDEpIHJobyA9IDAuMDAwMWY7CiAgICAgICAgICAgIG9iamVjdC0+ZXhwb25lbnQgPSAtMC4zL2xvZyhjb3MocmhvLzIpKTsKICAgICAgICB9CglpZiAob2JqZWN0LT5leHBvbmVudCA+IDEyOC4wKSB7CgkJb2JqZWN0LT5leHBvbmVudCA9IDEyOC4wOwoJfQogICAgICAgIG9iamVjdC0+Y3V0b2ZmID0gcExpZ2h0LT5QaGkqOTAvTV9QSTsKCiAgICAgICAgLyogRklYTUU6IFJhbmdlICovCiAgICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgICBGSVhNRSgiVW5yZWNvZ25pemVkIGxpZ2h0IHR5cGUgJWRcbiIsIHBMaWdodC0+VHlwZSk7CiAgICB9CgogICAgLyogVXBkYXRlIHRoZSBsaXZlIGRlZmluaXRpb25zIGlmIHRoZSBsaWdodCBpcyBjdXJyZW50bHkgYXNzaWduZWQgYSBnbEluZGV4ICovCiAgICBpZiAob2JqZWN0LT5nbEluZGV4ICE9IC0xICYmICFUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX0FDVElWRUxJR0hUKG9iamVjdC0+Z2xJbmRleCkpOwogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0TGlnaHQoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBJbmRleCwgV0lORUQzRExJR0hUKiBwTGlnaHQpIHsKICAgIFBMSUdIVElORk9FTCAqbGlnaHRJbmZvID0gTlVMTDsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIERXT1JEIEhpID0gTElHSFRNQVBfSEFTSEZVTkMoSW5kZXgpOwogICAgc3RydWN0IGxpc3QgKmU7CiAgICBUUkFDRSgiKCVwKSA6IElkeCglZCksIHBMaWdodCglcClcbiIsIFRoaXMsIEluZGV4LCBwTGlnaHQpOwoKICAgIExJU1RfRk9SX0VBQ0goZSwgJlRoaXMtPnN0YXRlQmxvY2stPmxpZ2h0TWFwW0hpXSkgewogICAgICAgIGxpZ2h0SW5mbyA9IExJU1RfRU5UUlkoZSwgUExJR0hUSU5GT0VMLCBlbnRyeSk7CiAgICAgICAgaWYobGlnaHRJbmZvLT5PcmlnaW5hbEluZGV4ID09IEluZGV4KSBicmVhazsKICAgICAgICBsaWdodEluZm8gPSBOVUxMOwogICAgfQoKICAgIGlmIChsaWdodEluZm8gPT0gTlVMTCkgewogICAgICAgIFRSQUNFKCJMaWdodCBpbmZvcm1hdGlvbiByZXF1ZXN0ZWQgYnV0IGxpZ2h0IG5vdCBkZWZpbmVkXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICAqcExpZ2h0ID0gbGlnaHRJbmZvLT5PcmlnaW5hbFBhcm1zOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBHZXQgLyBTZXQgTGlnaHQgRW5hYmxlCiAqICAgKE5vdGUgZm9yIGNvbnNpc3RlbmN5LCByZW5hbWVkIGQzZHggZnVuY3Rpb24gYnkgYWRkaW5nIHRoZSAnc2V0JyBwcmVmaXgpCiAqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRMaWdodEVuYWJsZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIEluZGV4LCBCT09MIEVuYWJsZSkgewogICAgUExJR0hUSU5GT0VMICpsaWdodEluZm8gPSBOVUxMOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVUlOVCBIaSA9IExJR0hUTUFQX0hBU0hGVU5DKEluZGV4KTsKICAgIHN0cnVjdCBsaXN0ICplOwogICAgVFJBQ0UoIiglcCkgOiBJZHgoJWQpLCBlbmFibGU/ICVkXG4iLCBUaGlzLCBJbmRleCwgRW5hYmxlKTsKCiAgICAvKiBUZXN0cyBzaG93IHRydWUgPSAxMjguLi5ub3QgY2xlYXIgd2h5ICovCiAgICBFbmFibGUgPSBFbmFibGU/IDEyODogMDsKCiAgICBMSVNUX0ZPUl9FQUNIKGUsICZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5saWdodE1hcFtIaV0pIHsKICAgICAgICBsaWdodEluZm8gPSBMSVNUX0VOVFJZKGUsIFBMSUdIVElORk9FTCwgZW50cnkpOwogICAgICAgIGlmKGxpZ2h0SW5mby0+T3JpZ2luYWxJbmRleCA9PSBJbmRleCkgYnJlYWs7CiAgICAgICAgbGlnaHRJbmZvID0gTlVMTDsKICAgIH0KICAgIFRSQUNFKCJGb3VuZCBsaWdodDogJXBcbiIsIGxpZ2h0SW5mbyk7CgogICAgLyogU3BlY2lhbCBjYXNlIC0gZW5hYmxpbmcgYW4gdW5kZWZpbmVkIGxpZ2h0IGNyZWF0ZXMgb25lIHdpdGggYSBzdHJpY3Qgc2V0IG9mIHBhcm1zISAqLwogICAgaWYgKGxpZ2h0SW5mbyA9PSBOVUxMKSB7CgogICAgICAgIFRSQUNFKCJMaWdodCBlbmFibGVkIHJlcXVlc3RlZCBidXQgbGlnaHQgbm90IGRlZmluZWQsIHNvIGRlZmluaW5nIG9uZSFcbiIpOwogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRMaWdodChpZmFjZSwgSW5kZXgsICZXSU5FRDNEX2RlZmF1bHRfbGlnaHQpOwoKICAgICAgICAvKiBTZWFyY2ggZm9yIGl0IGFnYWluISBTaG91bGQgYmUgZmFpcmx5IHF1aWNrIGFzIG5lYXIgaGVhZCBvZiBsaXN0ICovCiAgICAgICAgTElTVF9GT1JfRUFDSChlLCAmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+bGlnaHRNYXBbSGldKSB7CiAgICAgICAgICAgIGxpZ2h0SW5mbyA9IExJU1RfRU5UUlkoZSwgUExJR0hUSU5GT0VMLCBlbnRyeSk7CiAgICAgICAgICAgIGlmKGxpZ2h0SW5mby0+T3JpZ2luYWxJbmRleCA9PSBJbmRleCkgYnJlYWs7CiAgICAgICAgICAgIGxpZ2h0SW5mbyA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGlmIChsaWdodEluZm8gPT0gTlVMTCkgewogICAgICAgICAgICBGSVhNRSgiQWRkaW5nIGRlZmF1bHQgbGlnaHRzIGhhcyBmYWlsZWQgZGlzbWFsbHlcbiIpOwogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICB9CiAgICB9CgogICAgbGlnaHRJbmZvLT5lbmFibGVkQ2hhbmdlZCA9IFRSVUU7CiAgICBpZighRW5hYmxlKSB7CiAgICAgICAgaWYobGlnaHRJbmZvLT5nbEluZGV4ICE9IC0xKSB7CiAgICAgICAgICAgIGlmKCFUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfQUNUSVZFTElHSFQobGlnaHRJbmZvLT5nbEluZGV4KSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPmFjdGl2ZUxpZ2h0c1tsaWdodEluZm8tPmdsSW5kZXhdID0gTlVMTDsKICAgICAgICAgICAgbGlnaHRJbmZvLT5nbEluZGV4ID0gLTE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVFJBQ0UoIkxpZ2h0IGFscmVhZHkgZGlzYWJsZWQsIG5vdGhpbmcgdG8gZG9cbiIpOwogICAgICAgIH0KICAgICAgICBsaWdodEluZm8tPmVuYWJsZWQgPSBGQUxTRTsKICAgIH0gZWxzZSB7CiAgICAgICAgbGlnaHRJbmZvLT5lbmFibGVkID0gVFJVRTsKICAgICAgICBpZiAobGlnaHRJbmZvLT5nbEluZGV4ICE9IC0xKSB7CiAgICAgICAgICAgIC8qIG5vcCAqLwogICAgICAgICAgICBUUkFDRSgiTm90aGluZyB0byBkbyBhcyBsaWdodCB3YXMgZW5hYmxlZFxuIik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaW50IGk7CiAgICAgICAgICAgIC8qIEZpbmQgYSBmcmVlIGdsIGxpZ2h0ICovCiAgICAgICAgICAgIGZvcihpID0gMDsgaSA8IFRoaXMtPm1heENvbmN1cnJlbnRMaWdodHM7IGkrKykgewogICAgICAgICAgICAgICAgaWYoVGhpcy0+c3RhdGVCbG9jay0+YWN0aXZlTGlnaHRzW2ldID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5hY3RpdmVMaWdodHNbaV0gPSBsaWdodEluZm87CiAgICAgICAgICAgICAgICAgICAgbGlnaHRJbmZvLT5nbEluZGV4ID0gaTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZihsaWdodEluZm8tPmdsSW5kZXggPT0gLTEpIHsKICAgICAgICAgICAgICAgIC8qIE91ciB0ZXN0cyBzaG93IHRoYXQgV2luZG93cyByZXR1cm5zIEQzRF9PSyBpbiB0aGlzIHNpdHVhdGlvbiwgZXZlbiB3aXRoCiAgICAgICAgICAgICAgICAgKiBEM0RDUkVBVEVfSEFSRFdBUkVfVkVSVEVYUFJPQ0VTU0lORyB8IEQzRENSRUFURV9QVVJFREVWSUNFIGRldmljZXMuIFRoaXMKICAgICAgICAgICAgICAgICAqIGlzIGNvbnNpc3RlbnQgYW1vbmcgZGRyYXcsIGQzZDggYW5kIGQzZDkuIEdldExpZ2h0RW5hYmxlIHJldHVybnMgVFJVRQogICAgICAgICAgICAgICAgICogYXMgd2VsbCBmb3IgdGhvc2UgbGlnaHRzLgogICAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgICAqIFRPRE86IFRlc3QgaG93IHRoaXMgYWZmZWN0cyByZW5kZXJpbmcKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgRklYTUUoIlRvbyBtYW55IGNvbmN1cnJlbnRseSBhY3RpdmUgbGlnaHRzXG4iKTsKICAgICAgICAgICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBpID09IGxpZ2h0SW5mby0+Z2xJbmRleCAqLwogICAgICAgICAgICBpZighVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX0FDVElWRUxJR0hUKGkpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRMaWdodEVuYWJsZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIEluZGV4LEJPT0wqIHBFbmFibGUpIHsKCiAgICBQTElHSFRJTkZPRUwgKmxpZ2h0SW5mbyA9IE5VTEw7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBzdHJ1Y3QgbGlzdCAqZTsKICAgIFVJTlQgSGkgPSBMSUdIVE1BUF9IQVNIRlVOQyhJbmRleCk7CiAgICBUUkFDRSgiKCVwKSA6IGZvciBpZHgoJWQpXG4iLCBUaGlzLCBJbmRleCk7CgogICAgTElTVF9GT1JfRUFDSChlLCAmVGhpcy0+c3RhdGVCbG9jay0+bGlnaHRNYXBbSGldKSB7CiAgICAgICAgbGlnaHRJbmZvID0gTElTVF9FTlRSWShlLCBQTElHSFRJTkZPRUwsIGVudHJ5KTsKICAgICAgICBpZihsaWdodEluZm8tPk9yaWdpbmFsSW5kZXggPT0gSW5kZXgpIGJyZWFrOwogICAgICAgIGxpZ2h0SW5mbyA9IE5VTEw7CiAgICB9CgogICAgaWYgKGxpZ2h0SW5mbyA9PSBOVUxMKSB7CiAgICAgICAgVFJBQ0UoIkxpZ2h0IGVuYWJsZWQgc3RhdGUgcmVxdWVzdGVkIGJ1dCBsaWdodCBub3QgZGVmaW5lZFxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICAvKiB0cnVlIGlzIDEyOCBhY2NvcmRpbmcgdG8gU2V0TGlnaHRFbmFibGUgKi8KICAgICpwRW5hYmxlID0gbGlnaHRJbmZvLT5lbmFibGVkID8gMTI4IDogMDsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogR2V0IC8gU2V0IENsaXAgUGxhbmVzCiAqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRDbGlwUGxhbmUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBJbmRleCwgQ09OU1QgZmxvYXQgKnBQbGFuZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiBmb3IgaWR4ICVkLCAlcFxuIiwgVGhpcywgSW5kZXgsIHBQbGFuZSk7CgogICAgLyogVmFsaWRhdGUgSW5kZXggKi8KICAgIGlmIChJbmRleCA+PSBHTF9MSU1JVFMoY2xpcHBsYW5lcykpIHsKICAgICAgICBUUkFDRSgiQXBwbGljYXRpb24gaGFzIHJlcXVlc3RlZCBjbGlwcGxhbmUgdGhpcyBkZXZpY2UgZG9lc24ndCBzdXBwb3J0XG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLmNsaXBwbGFuZVtJbmRleF0gPSBUUlVFOwoKICAgIGlmKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNsaXBwbGFuZVtJbmRleF1bMF0gPT0gcFBsYW5lWzBdICYmCiAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jbGlwcGxhbmVbSW5kZXhdWzFdID09IHBQbGFuZVsxXSAmJgogICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2xpcHBsYW5lW0luZGV4XVsyXSA9PSBwUGxhbmVbMl0gJiYKICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNsaXBwbGFuZVtJbmRleF1bM10gPT0gcFBsYW5lWzNdKSB7CiAgICAgICAgVFJBQ0UoIkFwcGxpY2F0aW9uIGlzIHNldHRpbmcgb2xkIHZhbHVlcyBvdmVyLCBub3RoaW5nIHRvIGRvXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jbGlwcGxhbmVbSW5kZXhdWzBdID0gcFBsYW5lWzBdOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2xpcHBsYW5lW0luZGV4XVsxXSA9IHBQbGFuZVsxXTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNsaXBwbGFuZVtJbmRleF1bMl0gPSBwUGxhbmVbMl07CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jbGlwcGxhbmVbSW5kZXhdWzNdID0gcFBsYW5lWzNdOwoKICAgIC8qIEhhbmRsZSByZWNvcmRpbmcgb2Ygc3RhdGUgYmxvY2tzICovCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9DTElQUExBTkUoSW5kZXgpKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRDbGlwUGxhbmUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBJbmRleCwgZmxvYXQgKnBQbGFuZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiBmb3IgaWR4ICVkXG4iLCBUaGlzLCBJbmRleCk7CgogICAgLyogVmFsaWRhdGUgSW5kZXggKi8KICAgIGlmIChJbmRleCA+PSBHTF9MSU1JVFMoY2xpcHBsYW5lcykpIHsKICAgICAgICBUUkFDRSgiQXBwbGljYXRpb24gaGFzIHJlcXVlc3RlZCBjbGlwcGxhbmUgdGhpcyBkZXZpY2UgZG9lc24ndCBzdXBwb3J0XG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBwUGxhbmVbMF0gPSBUaGlzLT5zdGF0ZUJsb2NrLT5jbGlwcGxhbmVbSW5kZXhdWzBdOwogICAgcFBsYW5lWzFdID0gVGhpcy0+c3RhdGVCbG9jay0+Y2xpcHBsYW5lW0luZGV4XVsxXTsKICAgIHBQbGFuZVsyXSA9IFRoaXMtPnN0YXRlQmxvY2stPmNsaXBwbGFuZVtJbmRleF1bMl07CiAgICBwUGxhbmVbM10gPSBUaGlzLT5zdGF0ZUJsb2NrLT5jbGlwcGxhbmVbSW5kZXhdWzNdOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBHZXQgLyBTZXQgQ2xpcCBQbGFuZSBTdGF0dXMKICogICBXQVJOSU5HOiBUaGlzIGNvZGUgcmVsaWVzIG9uIHRoZSBmYWN0IHRoYXQgRDNEQ0xJUFNUQVRVUzggPT0gRDNEQ0xJUFNUQVRVUzkKICoqKioqLwpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfU2V0Q2xpcFN0YXR1cyhJV2luZUQzRERldmljZSAqaWZhY2UsIENPTlNUIFdJTkVEM0RDTElQU1RBVFVTKiBwQ2xpcFN0YXR1cykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgRklYTUUoIiglcCkgOiBzdHViXG4iLCBUaGlzKTsKICAgIGlmIChOVUxMID09IHBDbGlwU3RhdHVzKSB7CiAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2xpcF9zdGF0dXMuQ2xpcFVuaW9uID0gcENsaXBTdGF0dXMtPkNsaXBVbmlvbjsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNsaXBfc3RhdHVzLkNsaXBJbnRlcnNlY3Rpb24gPSBwQ2xpcFN0YXR1cy0+Q2xpcEludGVyc2VjdGlvbjsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfR2V0Q2xpcFN0YXR1cyhJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RDTElQU1RBVFVTKiBwQ2xpcFN0YXR1cykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgRklYTUUoIiglcCkgOiBzdHViXG4iLCBUaGlzKTsKICAgIGlmIChOVUxMID09IHBDbGlwU3RhdHVzKSB7CiAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgcENsaXBTdGF0dXMtPkNsaXBVbmlvbiA9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNsaXBfc3RhdHVzLkNsaXBVbmlvbjsKICAgIHBDbGlwU3RhdHVzLT5DbGlwSW50ZXJzZWN0aW9uID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2xpcF9zdGF0dXMuQ2xpcEludGVyc2VjdGlvbjsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogR2V0IC8gU2V0IE1hdGVyaWFsCiAqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRNYXRlcmlhbChJV2luZUQzRERldmljZSAqaWZhY2UsIENPTlNUIFdJTkVEM0RNQVRFUklBTCogcE1hdGVyaWFsKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgaWYgKCFwTWF0ZXJpYWwpIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQubWF0ZXJpYWwgPSBUUlVFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+bWF0ZXJpYWwgPSAqcE1hdGVyaWFsOwoKICAgIC8qIEhhbmRsZSByZWNvcmRpbmcgb2Ygc3RhdGUgYmxvY2tzICovCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9NQVRFUklBTCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRNYXRlcmlhbChJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RNQVRFUklBTCogcE1hdGVyaWFsKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICAqcE1hdGVyaWFsID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+bWF0ZXJpYWw7CiAgICBUUkFDRSgiKCVwKSA6IERpZmZ1c2UgKCVmLCVmLCVmLCVmKVxuIiwgVGhpcywgcE1hdGVyaWFsLT5EaWZmdXNlLnIsIHBNYXRlcmlhbC0+RGlmZnVzZS5nLAogICAgICAgIHBNYXRlcmlhbC0+RGlmZnVzZS5iLCBwTWF0ZXJpYWwtPkRpZmZ1c2UuYSk7CiAgICBUUkFDRSgiKCVwKSA6IEFtYmllbnQgKCVmLCVmLCVmLCVmKVxuIiwgVGhpcywgcE1hdGVyaWFsLT5BbWJpZW50LnIsIHBNYXRlcmlhbC0+QW1iaWVudC5nLAogICAgICAgIHBNYXRlcmlhbC0+QW1iaWVudC5iLCBwTWF0ZXJpYWwtPkFtYmllbnQuYSk7CiAgICBUUkFDRSgiKCVwKSA6IFNwZWN1bGFyICglZiwlZiwlZiwlZilcbiIsIFRoaXMsIHBNYXRlcmlhbC0+U3BlY3VsYXIuciwgcE1hdGVyaWFsLT5TcGVjdWxhci5nLAogICAgICAgIHBNYXRlcmlhbC0+U3BlY3VsYXIuYiwgcE1hdGVyaWFsLT5TcGVjdWxhci5hKTsKICAgIFRSQUNFKCIoJXApIDogRW1pc3NpdmUgKCVmLCVmLCVmLCVmKVxuIiwgVGhpcywgcE1hdGVyaWFsLT5FbWlzc2l2ZS5yLCBwTWF0ZXJpYWwtPkVtaXNzaXZlLmcsCiAgICAgICAgcE1hdGVyaWFsLT5FbWlzc2l2ZS5iLCBwTWF0ZXJpYWwtPkVtaXNzaXZlLmEpOwogICAgVFJBQ0UoIiglcCkgOiBQb3dlciAoJWYpXG4iLCBUaGlzLCBwTWF0ZXJpYWwtPlBvd2VyKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBJbmRpY2VzCiAqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRJbmRpY2VzKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RJbmRleEJ1ZmZlciogcEluZGV4RGF0YSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNESW5kZXhCdWZmZXIgKm9sZElkeHM7CgogICAgVFJBQ0UoIiglcCkgOiBTZXR0aW5nIHRvICVwXG4iLCBUaGlzLCBwSW5kZXhEYXRhKTsKICAgIG9sZElkeHMgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5wSW5kZXhEYXRhOwoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQuaW5kaWNlcyA9IFRSVUU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5wSW5kZXhEYXRhID0gcEluZGV4RGF0YTsKCiAgICAvKiBIYW5kbGUgcmVjb3JkaW5nIG9mIHN0YXRlIGJsb2NrcyAqLwogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICBpZihwSW5kZXhEYXRhKSBJV2luZUQzREluZGV4QnVmZmVyX0FkZFJlZihwSW5kZXhEYXRhKTsKICAgICAgICBpZihvbGRJZHhzKSBJV2luZUQzREluZGV4QnVmZmVyX1JlbGVhc2Uob2xkSWR4cyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgaWYob2xkSWR4cyAhPSBwSW5kZXhEYXRhKSB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX0lOREVYQlVGRkVSKTsKICAgICAgICBpZihwSW5kZXhEYXRhKSBJV2luZUQzREluZGV4QnVmZmVyX0FkZFJlZihwSW5kZXhEYXRhKTsKICAgICAgICBpZihvbGRJZHhzKSBJV2luZUQzREluZGV4QnVmZmVyX1JlbGVhc2Uob2xkSWR4cyk7CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRJbmRpY2VzKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RJbmRleEJ1ZmZlcioqIHBwSW5kZXhEYXRhKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgKnBwSW5kZXhEYXRhID0gVGhpcy0+c3RhdGVCbG9jay0+cEluZGV4RGF0YTsKCiAgICAvKiB1cCByZWYgY291bnQgb24gcHBpbmRleGRhdGEgKi8KICAgIGlmICgqcHBJbmRleERhdGEpIHsKICAgICAgICBJV2luZUQzREluZGV4QnVmZmVyX0FkZFJlZigqcHBJbmRleERhdGEpOwogICAgICAgIFRSQUNFKCIoJXApIGluZGV4IGRhdGEgc2V0IHRvICVwXG4iLCBUaGlzLCBwcEluZGV4RGF0YSk7CiAgICB9ZWxzZXsKICAgICAgICBUUkFDRSgiKCVwKSBObyBpbmRleCBkYXRhIHNldFxuIiwgVGhpcyk7CiAgICB9CiAgICBUUkFDRSgiUmV0dXJuaW5nICVwXG4iLCAqcHBJbmRleERhdGEpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKiBNZXRob2QgdG8gb2ZmZXIgZDNkOSBhIHNpbXBsZSB3YXkgdG8gc2V0IHRoZSBiYXNlIHZlcnRleCBpbmRleCB3aXRob3V0IG1lc3Npbmcgd2l0aCB0aGUgaW5kZXggYnVmZmVyICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0QmFzZVZlcnRleEluZGV4KElXaW5lRDNERGV2aWNlICppZmFjZSwgSU5UIEJhc2VJbmRleCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCktPiglZClcbiIsIFRoaXMsIEJhc2VJbmRleCk7CgogICAgaWYoVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+YmFzZVZlcnRleEluZGV4ID09IEJhc2VJbmRleCkgewogICAgICAgIFRSQUNFKCJBcHBsaWNhdGlvbiBpcyBzZXR0aW5nIHRoZSBvbGQgdmFsdWUgb3Zlciwgbm90aGluZyB0byBkb1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+YmFzZVZlcnRleEluZGV4ID0gQmFzZUluZGV4OwoKICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CiAgICAvKiBUaGUgYmFzZSB2ZXJ0ZXggaW5kZXggYWZmZWN0cyB0aGUgc3RyZWFtIHNvdXJjZXMgKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TVFJFQU1TUkMpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0QmFzZVZlcnRleEluZGV4KElXaW5lRDNERGV2aWNlICppZmFjZSwgSU5UKiBiYXNlX2luZGV4KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IGJhc2VfaW5kZXggJXBcbiIsIFRoaXMsIGJhc2VfaW5kZXgpOwoKICAgICpiYXNlX2luZGV4ID0gVGhpcy0+c3RhdGVCbG9jay0+YmFzZVZlcnRleEluZGV4OwoKICAgIFRSQUNFKCJSZXR1cm5pbmcgJXVcbiIsICpiYXNlX2luZGV4KTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBWaWV3cG9ydHMKICoqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZpZXdwb3J0KElXaW5lRDNERGV2aWNlICppZmFjZSwgQ09OU1QgV0lORUQzRFZJRVdQT1JUKiBwVmlld3BvcnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnZpZXdwb3J0ID0gVFJVRTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnZpZXdwb3J0ID0gKnBWaWV3cG9ydDsKCiAgICAvKiBIYW5kbGUgcmVjb3JkaW5nIG9mIHN0YXRlIGJsb2NrcyAqLwogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBUUkFDRSgiKCVwKSA6IHg9JWQsIHk9JWQsIHdpZD0lZCwgaGVpPSVkLCBtaW56PSVmLCBtYXh6PSVmXG4iLCBUaGlzLAogICAgICAgICAgcFZpZXdwb3J0LT5YLCBwVmlld3BvcnQtPlksIHBWaWV3cG9ydC0+V2lkdGgsIHBWaWV3cG9ydC0+SGVpZ2h0LCBwVmlld3BvcnQtPk1pblosIHBWaWV3cG9ydC0+TWF4Wik7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1ZJRVdQT1JUKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwoKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWaWV3cG9ydChJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RWSUVXUE9SVCogcFZpZXdwb3J0KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CiAgICAqcFZpZXdwb3J0ID0gVGhpcy0+c3RhdGVCbG9jay0+dmlld3BvcnQ7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBSZW5kZXIgU3RhdGVzCiAqIFRPRE86IFZlcmlmeSBhZ2FpbnN0IGR4OSBkZWZpbml0aW9ucwogKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0UmVuZGVyU3RhdGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEUkVOREVSU1RBVEVUWVBFIFN0YXRlLCBEV09SRCBWYWx1ZSkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgKlRoaXMgICAgID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgRFdPUkQgb2xkVmFsdWUgPSBUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtTdGF0ZV07CgogICAgVFJBQ0UoIiglcCktPnN0YXRlID0gJXMoJWQpLCB2YWx1ZSA9ICVkXG4iLCBUaGlzLCBkZWJ1Z19kM2RyZW5kZXJzdGF0ZShTdGF0ZSksIFN0YXRlLCBWYWx1ZSk7CgogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC5yZW5kZXJTdGF0ZVtTdGF0ZV0gPSBUUlVFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbU3RhdGVdID0gVmFsdWU7CgogICAgLyogSGFuZGxlIHJlY29yZGluZyBvZiBzdGF0ZSBibG9ja3MgKi8KICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgLyogQ29tcGFyZWQgaGVyZSBhbmQgbm90IGJlZm9yZSB0aGUgYXNzaWdubWVudCB0byBhbGxvdyBwcm9wZXIgc3RhdGVibG9jayByZWNvcmRpbmcgKi8KICAgIGlmKFZhbHVlID09IG9sZFZhbHVlKSB7CiAgICAgICAgVFJBQ0UoIkFwcGxpY2F0aW9uIGlzIHNldHRpbmcgdGhlIG9sZCB2YWx1ZSBvdmVyLCBub3RoaW5nIHRvIGRvXG4iKTsKICAgIH0gZWxzZSB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1JFTkRFUihTdGF0ZSkpOwogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFJlbmRlclN0YXRlKElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRFJFTkRFUlNUQVRFVFlQRSBTdGF0ZSwgRFdPUkQgKnBWYWx1ZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgZm9yIFN0YXRlICVkID0gJWRcbiIsIFRoaXMsIFN0YXRlLCBUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtTdGF0ZV0pOwogICAgKnBWYWx1ZSA9IFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1N0YXRlXTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogR2V0IC8gU2V0IFNhbXBsZXIgU3RhdGVzCiAqIFRPRE86IFZlcmlmeSBhZ2FpbnN0IGR4OSBkZWZpbml0aW9ucwogKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFNhbXBsZXJTdGF0ZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIFNhbXBsZXIsIFdJTkVEM0RTQU1QTEVSU1RBVEVUWVBFIFR5cGUsIERXT1JEIFZhbHVlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBEV09SRCBvbGRWYWx1ZTsKCiAgICBUUkFDRSgiKCVwKSA6IFNhbXBsZXIgJSN4LCBUeXBlICVzICglI3gpLCBWYWx1ZSAlI3hcbiIsCiAgICAgICAgICAgIFRoaXMsIFNhbXBsZXIsIGRlYnVnX2QzZHNhbXBsZXJzdGF0ZShUeXBlKSwgVHlwZSwgVmFsdWUpOwoKICAgIGlmIChTYW1wbGVyID49IFdJTkVEM0RWRVJURVhURVhUVVJFU0FNUExFUjAgJiYgU2FtcGxlciA8PSBXSU5FRDNEVkVSVEVYVEVYVFVSRVNBTVBMRVIzKSB7CiAgICAgICAgU2FtcGxlciAtPSAoV0lORUQzRFZFUlRFWFRFWFRVUkVTQU1QTEVSMCAtIE1BWF9GUkFHTUVOVF9TQU1QTEVSUyk7CiAgICB9CgogICAgaWYgKFNhbXBsZXIgPj0gc2l6ZW9mKFRoaXMtPnN0YXRlQmxvY2stPnNhbXBsZXJTdGF0ZSkvc2l6ZW9mKFRoaXMtPnN0YXRlQmxvY2stPnNhbXBsZXJTdGF0ZVswXSkpIHsKICAgICAgICBFUlIoIkN1cnJlbnQgU2FtcGxlciBvdmVyZmxvd3Mgc2FtcGxlU3RhdGUwIGFycmF5IChzYW1wbGVyICVkKVxuIiwgU2FtcGxlcik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7IC8qIFdpbmRvd3MgYWNjZXB0cyBvdmVyZmxvd2luZyB0aGlzIGFycmF5IC4uLiB3ZSBkbyBub3QuICovCiAgICB9CiAgICAvKioKICAgICogU2V0U2FtcGxlciBpcyBkZXNpZ25lZCB0byBhbGxvdyBmb3IgbW9yZSB0aGFuIHRoZSBzdGFuZGFyZCB1cCB0byA4IHRleHR1cmVzCiAgICAqICBhbmQgR2Vmb3JjZSBoYXMgc3RvcHBlZCBzdXBwb3J0aW5nIG1vcmUgdGhhbiA2IHN0YW5kYXJkIHRleHR1cmVzIGluIG9wZW5HTC4KICAgICogU28gSSBoYXZlIHRvIHVzZSBBUkIgZm9yIEdmb3JjZS4gKG1heWJlIGlmIHRoZSBzYW1wbGVyID4gNCB0aGVuIHVzZSBBUkI/KQogICAgKgogICAgKiBodHRwOi8vZGV2ZWxvcGVyLm52aWRpYS5jb20vb2JqZWN0L0dlbmVyYWxfRkFRLmh0bWwjdDYKICAgICoKICAgICogVGhlcmUgYXJlIHR3byBuZXcgc2V0dGluZ3MgZm9yIEdGb3JjZQogICAgKiB0aGUgc2FtcGxlciBvbmU6CiAgICAqIEdMX01BWF9URVhUVVJFX0lNQUdFX1VOSVRTX0FSQgogICAgKiBhbmQgdGhlIHRleHR1cmUgb25lOgogICAgKiBHTF9NQVhfVEVYVFVSRV9DT09SRFNfQVJCLgogICAgKiBPayBHRm9yY2Ugc2F5IGl0J3Mgb2sgdG8gdXNlIGdsVGV4UGFyYW1ldGVyL2dsR2V0VGV4UGFyYW1ldGVyKC4uLikuCiAgICAgKioqKioqKioqKioqKioqKioqLwoKICAgIG9sZFZhbHVlID0gVGhpcy0+c3RhdGVCbG9jay0+c2FtcGxlclN0YXRlW1NhbXBsZXJdW1R5cGVdOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2FtcGxlclN0YXRlW1NhbXBsZXJdW1R5cGVdICAgICAgICAgPSBWYWx1ZTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQuc2FtcGxlclN0YXRlW1NhbXBsZXJdW1R5cGVdID0gVmFsdWU7CgogICAgLyogSGFuZGxlIHJlY29yZGluZyBvZiBzdGF0ZSBibG9ja3MgKi8KICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgaWYob2xkVmFsdWUgPT0gVmFsdWUpIHsKICAgICAgICBUUkFDRSgiQXBwbGljYXRpb24gaXMgc2V0dGluZyB0aGUgb2xkIHZhbHVlIG92ZXIsIG5vdGhpbmcgdG8gZG9cbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TQU1QTEVSKFNhbXBsZXIpKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTYW1wbGVyU3RhdGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBTYW1wbGVyLCBXSU5FRDNEU0FNUExFUlNUQVRFVFlQRSBUeXBlLCBEV09SRCogVmFsdWUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKSA6IFNhbXBsZXIgJSN4LCBUeXBlICVzICglI3gpXG4iLAogICAgICAgICAgICBUaGlzLCBTYW1wbGVyLCBkZWJ1Z19kM2RzYW1wbGVyc3RhdGUoVHlwZSksIFR5cGUpOwoKICAgIGlmIChTYW1wbGVyID49IFdJTkVEM0RWRVJURVhURVhUVVJFU0FNUExFUjAgJiYgU2FtcGxlciA8PSBXSU5FRDNEVkVSVEVYVEVYVFVSRVNBTVBMRVIzKSB7CiAgICAgICAgU2FtcGxlciAtPSAoV0lORUQzRFZFUlRFWFRFWFRVUkVTQU1QTEVSMCAtIE1BWF9GUkFHTUVOVF9TQU1QTEVSUyk7CiAgICB9CgogICAgaWYgKFNhbXBsZXIgPj0gc2l6ZW9mKFRoaXMtPnN0YXRlQmxvY2stPnNhbXBsZXJTdGF0ZSkvc2l6ZW9mKFRoaXMtPnN0YXRlQmxvY2stPnNhbXBsZXJTdGF0ZVswXSkpIHsKICAgICAgICBFUlIoIkN1cnJlbnQgU2FtcGxlciBvdmVyZmxvd3Mgc2FtcGxlU3RhdGUwIGFycmF5IChzYW1wbGVyICVkKVxuIiwgU2FtcGxlcik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7IC8qIFdpbmRvd3MgYWNjZXB0cyBvdmVyZmxvd2luZyB0aGlzIGFycmF5IC4uLiB3ZSBkbyBub3QuICovCiAgICB9CiAgICAqVmFsdWUgPSBUaGlzLT5zdGF0ZUJsb2NrLT5zYW1wbGVyU3RhdGVbU2FtcGxlcl1bVHlwZV07CiAgICBUUkFDRSgiKCVwKSA6IFJldHVybmluZyAlI3hcbiIsIFRoaXMsICpWYWx1ZSk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0U2Npc3NvclJlY3QoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBDT05TVCBSRUNUKiBwUmVjdCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQuc2Npc3NvclJlY3QgPSBUUlVFOwogICAgaWYoRXF1YWxSZWN0KCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zY2lzc29yUmVjdCwgcFJlY3QpKSB7CiAgICAgICAgVFJBQ0UoIkFwcCBpcyBzZXR0aW5nIHRoZSBvbGQgc2Npc3NvciByZWN0YW5nbGUgb3Zlciwgbm90aGluZyB0byBkb1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CiAgICBDb3B5UmVjdCgmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2Npc3NvclJlY3QsIHBSZWN0KTsKCiAgICBpZihUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1NDSVNTT1JSRUNUKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTY2lzc29yUmVjdChJV2luZUQzRERldmljZSAqaWZhY2UsIFJFQ1QqIHBSZWN0KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgKnBSZWN0ID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2Npc3NvclJlY3Q7CiAgICBUUkFDRSgiKCVwKVJldHVybmluZyBhIFNjaXNzb3IgUmVjdCBvZiAlZDolZC0lZDolZFxuIiwgVGhpcywgcFJlY3QtPmxlZnQsIHBSZWN0LT50b3AsIHBSZWN0LT5yaWdodCwgcFJlY3QtPmJvdHRvbSk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWZXJ0ZXhEZWNsYXJhdGlvbihJV2luZUQzRERldmljZSogaWZhY2UsIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb24qIHBEZWNsKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RWZXJ0ZXhEZWNsYXJhdGlvbiAqb2xkRGVjbCA9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnZlcnRleERlY2w7CgogICAgVFJBQ0UoIiglcCkgOiBwRGVjbD0lcFxuIiwgVGhpcywgcERlY2wpOwoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnZlcnRleERlY2wgPSBwRGVjbDsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQudmVydGV4RGVjbCA9IFRSVUU7CgogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0gZWxzZSBpZihwRGVjbCA9PSBvbGREZWNsKSB7CiAgICAgICAgLyogQ2hlY2tlZCBhZnRlciB0aGUgYXNzaWdubWVudCB0byBhbGxvdyBwcm9wZXIgc3RhdGVibG9jayByZWNvcmRpbmcgKi8KICAgICAgICBUUkFDRSgiQXBwbGljYXRpb24gaXMgc2V0dGluZyB0aGUgb2xkIGRlY2xhcmF0aW9uIG92ZXIsIG5vdGhpbmcgdG8gZG9cbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9WREVDTCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWZXJ0ZXhEZWNsYXJhdGlvbihJV2luZUQzRERldmljZSogaWZhY2UsIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb24qKiBwcERlY2wpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKSA6IHBwRGVjbD0lcFxuIiwgVGhpcywgcHBEZWNsKTsKCiAgICAqcHBEZWNsID0gVGhpcy0+c3RhdGVCbG9jay0+dmVydGV4RGVjbDsKICAgIGlmIChOVUxMICE9ICpwcERlY2wpIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb25fQWRkUmVmKCpwcERlY2wpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0VmVydGV4U2hhZGVyKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RWZXJ0ZXhTaGFkZXIqIHBTaGFkZXIpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyAgICAgICAgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFZlcnRleFNoYWRlciogb2xkU2hhZGVyID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dmVydGV4U2hhZGVyOwoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnZlcnRleFNoYWRlciAgICAgICAgID0gcFNoYWRlcjsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQudmVydGV4U2hhZGVyID0gVFJVRTsKCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIGlmKHBTaGFkZXIpIElXaW5lRDNEVmVydGV4U2hhZGVyX0FkZFJlZihwU2hhZGVyKTsKICAgICAgICBpZihvbGRTaGFkZXIpIElXaW5lRDNEVmVydGV4U2hhZGVyX1JlbGVhc2Uob2xkU2hhZGVyKTsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0gZWxzZSBpZihvbGRTaGFkZXIgPT0gcFNoYWRlcikgewogICAgICAgIC8qIENoZWNrZWQgaGVyZSB0byBhbGxvdyBwcm9wZXIgc3RhdGVibG9jayByZWNvcmRpbmcgKi8KICAgICAgICBUUkFDRSgiQXBwIGlzIHNldHRpbmcgdGhlIG9sZCBzaGFkZXIgb3Zlciwgbm90aGluZyB0byBkb1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgVFJBQ0UoIiglcCkgOiBzZXR0aW5nIHBTaGFkZXIoJXApXG4iLCBUaGlzLCBwU2hhZGVyKTsKICAgIGlmKHBTaGFkZXIpIElXaW5lRDNEVmVydGV4U2hhZGVyX0FkZFJlZihwU2hhZGVyKTsKICAgIGlmKG9sZFNoYWRlcikgSVdpbmVEM0RWZXJ0ZXhTaGFkZXJfUmVsZWFzZShvbGRTaGFkZXIpOwoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9WU0hBREVSKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWZXJ0ZXhTaGFkZXIoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFZlcnRleFNoYWRlcioqIHBwU2hhZGVyKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgaWYgKE5VTEwgPT0gcHBTaGFkZXIpIHsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgICpwcFNoYWRlciA9IFRoaXMtPnN0YXRlQmxvY2stPnZlcnRleFNoYWRlcjsKICAgIGlmKCBOVUxMICE9ICpwcFNoYWRlcikKICAgICAgICBJV2luZUQzRFZlcnRleFNoYWRlcl9BZGRSZWYoKnBwU2hhZGVyKTsKCiAgICBUUkFDRSgiKCVwKSA6IHJldHVybmluZyAlcFxuIiwgVGhpcywgKnBwU2hhZGVyKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZlcnRleFNoYWRlckNvbnN0YW50QigKICAgIElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgIFVJTlQgc3RhcnQsCiAgICBDT05TVCBCT09MICpzcmNEYXRhLAogICAgVUlOVCBjb3VudCkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIGludCBpLCBjbnQgPSBtaW4oY291bnQsIE1BWF9DT05TVF9CIC0gc3RhcnQpOwoKICAgIFRSQUNFKCIoaWZhY2UgJXAsIHNyY0RhdGEgJXAsIHN0YXJ0ICVkLCBjb3VudCAlZClcbiIsCiAgICAgICAgICAgIGlmYWNlLCBzcmNEYXRhLCBzdGFydCwgY291bnQpOwoKICAgIGlmIChzcmNEYXRhID09IE5VTEwgfHwgY250IDwgMCkKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICBtZW1jcHkoJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnZlcnRleFNoYWRlckNvbnN0YW50QltzdGFydF0sIHNyY0RhdGEsIGNudCAqIHNpemVvZihCT09MKSk7CiAgICBmb3IgKGkgPSAwOyBpIDwgY250OyBpKyspCiAgICAgICAgVFJBQ0UoIlNldCBCT09MIGNvbnN0YW50ICV1IHRvICVzXG4iLCBzdGFydCArIGksIHNyY0RhdGFbaV0/ICJ0cnVlIjoiZmFsc2UiKTsKCiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGNudCArIHN0YXJ0OyArK2kpIHsKICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnZlcnRleFNoYWRlckNvbnN0YW50c0JbaV0gPSBUUlVFOwogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9WRVJURVhTSEFERVJDT05TVEFOVCk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0VmVydGV4U2hhZGVyQ29uc3RhbnRCKAogICAgSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgVUlOVCBzdGFydCwKICAgIEJPT0wgKmRzdERhdGEsCiAgICBVSU5UIGNvdW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaW50IGNudCA9IG1pbihjb3VudCwgTUFYX0NPTlNUX0IgLSBzdGFydCk7CgogICAgVFJBQ0UoIihpZmFjZSAlcCwgZHN0RGF0YSAlcCwgc3RhcnQgJWQsIGNvdW50ICVkKVxuIiwKICAgICAgICAgICAgaWZhY2UsIGRzdERhdGEsIHN0YXJ0LCBjb3VudCk7CgogICAgaWYgKGRzdERhdGEgPT0gTlVMTCB8fCBjbnQgPCAwKQogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIG1lbWNweShkc3REYXRhLCAmVGhpcy0+c3RhdGVCbG9jay0+dmVydGV4U2hhZGVyQ29uc3RhbnRCW3N0YXJ0XSwgY250ICogc2l6ZW9mKEJPT0wpKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZlcnRleFNoYWRlckNvbnN0YW50SSgKICAgIElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgIFVJTlQgc3RhcnQsCiAgICBDT05TVCBpbnQgKnNyY0RhdGEsCiAgICBVSU5UIGNvdW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaW50IGksIGNudCA9IG1pbihjb3VudCwgTUFYX0NPTlNUX0kgLSBzdGFydCk7CgogICAgVFJBQ0UoIihpZmFjZSAlcCwgc3JjRGF0YSAlcCwgc3RhcnQgJWQsIGNvdW50ICVkKVxuIiwKICAgICAgICAgICAgaWZhY2UsIHNyY0RhdGEsIHN0YXJ0LCBjb3VudCk7CgogICAgaWYgKHNyY0RhdGEgPT0gTlVMTCB8fCBjbnQgPCAwKQogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIG1lbWNweSgmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dmVydGV4U2hhZGVyQ29uc3RhbnRJW3N0YXJ0ICogNF0sIHNyY0RhdGEsIGNudCAqIHNpemVvZihpbnQpICogNCk7CiAgICBmb3IgKGkgPSAwOyBpIDwgY250OyBpKyspCiAgICAgICAgVFJBQ0UoIlNldCBJTlQgY29uc3RhbnQgJXUgdG8geyAlZCwgJWQsICVkLCAlZCB9XG4iLCBzdGFydCArIGksCiAgICAgICAgICAgc3JjRGF0YVtpKjRdLCBzcmNEYXRhW2kqNCsxXSwgc3JjRGF0YVtpKjQrMl0sIHNyY0RhdGFbaSo0KzNdKTsKCiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGNudCArIHN0YXJ0OyArK2kpIHsKICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnZlcnRleFNoYWRlckNvbnN0YW50c0lbaV0gPSBUUlVFOwogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9WRVJURVhTSEFERVJDT05TVEFOVCk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0VmVydGV4U2hhZGVyQ29uc3RhbnRJKAogICAgSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgVUlOVCBzdGFydCwKICAgIGludCAqZHN0RGF0YSwKICAgIFVJTlQgY291bnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpbnQgY250ID0gbWluKGNvdW50LCBNQVhfQ09OU1RfSSAtIHN0YXJ0KTsKCiAgICBUUkFDRSgiKGlmYWNlICVwLCBkc3REYXRhICVwLCBzdGFydCAlZCwgY291bnQgJWQpXG4iLAogICAgICAgICAgICBpZmFjZSwgZHN0RGF0YSwgc3RhcnQsIGNvdW50KTsKCiAgICBpZiAoZHN0RGF0YSA9PSBOVUxMIHx8ICgoc2lnbmVkIGludCkgTUFYX0NPTlNUX0kgLSAoc2lnbmVkIGludCkgc3RhcnQpIDw9IChzaWduZWQgaW50KSAwKQogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIG1lbWNweShkc3REYXRhLCAmVGhpcy0+c3RhdGVCbG9jay0+dmVydGV4U2hhZGVyQ29uc3RhbnRJW3N0YXJ0ICogNF0sIGNudCAqIHNpemVvZihpbnQpICogNCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEYoCiAgICBJV2luZUQzRERldmljZSAqaWZhY2UsCiAgICBVSU5UIHN0YXJ0LAogICAgQ09OU1QgZmxvYXQgKnNyY0RhdGEsCiAgICBVSU5UIGNvdW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaW50IGk7CgogICAgVFJBQ0UoIihpZmFjZSAlcCwgc3JjRGF0YSAlcCwgc3RhcnQgJWQsIGNvdW50ICVkKVxuIiwKICAgICAgICAgICAgaWZhY2UsIHNyY0RhdGEsIHN0YXJ0LCBjb3VudCk7CgogICAgLyogU3BlY2lmaWNhbGx5IHRlc3Qgc3RhcnQgPiBsaW1pdCB0byBjYXRjaCBNQVhfVUlOVCBvdmVyZmxvd3Mgd2hlbiBhZGRpbmcgc3RhcnQgKyBjb3VudCAqLwogICAgaWYgKHNyY0RhdGEgPT0gTlVMTCB8fCBzdGFydCArIGNvdW50ID4gR0xfTElNSVRTKHZzaGFkZXJfY29uc3RhbnRzRikgfHwgc3RhcnQgPiBHTF9MSU1JVFModnNoYWRlcl9jb25zdGFudHNGKSkKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICBtZW1jcHkoJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnZlcnRleFNoYWRlckNvbnN0YW50RltzdGFydCAqIDRdLCBzcmNEYXRhLCBjb3VudCAqIHNpemVvZihmbG9hdCkgKiA0KTsKICAgIGlmKFRSQUNFX09OKGQzZCkpIHsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY291bnQ7IGkrKykKICAgICAgICAgICAgVFJBQ0UoIlNldCBGTE9BVCBjb25zdGFudCAldSB0byB7ICVmLCAlZiwgJWYsICVmIH1cbiIsIHN0YXJ0ICsgaSwKICAgICAgICAgICAgICAgIHNyY0RhdGFbaSo0XSwgc3JjRGF0YVtpKjQrMV0sIHNyY0RhdGFbaSo0KzJdLCBzcmNEYXRhW2kqNCszXSk7CiAgICB9CgogICAgZm9yIChpID0gc3RhcnQ7IGkgPCBjb3VudCArIHN0YXJ0OyArK2kpIHsKICAgICAgICBpZiAoIVRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQudmVydGV4U2hhZGVyQ29uc3RhbnRzRltpXSkgewogICAgICAgICAgICBjb25zdGFudHNfZW50cnkgKnB0ciA9IExJU1RfRU5UUlkobGlzdF9oZWFkKCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXRfdmNvbnN0YW50c0YpLCBjb25zdGFudHNfZW50cnksIGVudHJ5KTsKICAgICAgICAgICAgaWYgKCFwdHIgfHwgcHRyLT5jb3VudCA+PSBzaXplb2YocHRyLT5pZHgpIC8gc2l6ZW9mKCpwdHItPmlkeCkpIHsKICAgICAgICAgICAgICAgIHB0ciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoY29uc3RhbnRzX2VudHJ5KSk7CiAgICAgICAgICAgICAgICBsaXN0X2FkZF9oZWFkKCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXRfdmNvbnN0YW50c0YsICZwdHItPmVudHJ5KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwdHItPmlkeFtwdHItPmNvdW50KytdID0gaTsKICAgICAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC52ZXJ0ZXhTaGFkZXJDb25zdGFudHNGW2ldID0gVFJVRTsKICAgICAgICB9CiAgICB9CgogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1ZFUlRFWFNIQURFUkNPTlNUQU5UKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEZfRGlydHlDb25zdCgKSVdpbmVEM0REZXZpY2UgKmlmYWNlLApVSU5UIHN0YXJ0LApDT05TVCBmbG9hdCAqc3JjRGF0YSwKVUlOVCBjb3VudCkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIGludCBpOwoKICAgIFRSQUNFKCIoaWZhY2UgJXAsIHNyY0RhdGEgJXAsIHN0YXJ0ICVkLCBjb3VudCAlZClcbiIsCiAgICAgICAgICAgIGlmYWNlLCBzcmNEYXRhLCBzdGFydCwgY291bnQpOwoKICAgIC8qIFNwZWNpZmljYWxseSB0ZXN0IHN0YXJ0ID4gbGltaXQgdG8gY2F0Y2ggTUFYX1VJTlQgb3ZlcmZsb3dzIHdoZW4gYWRkaW5nIHN0YXJ0ICsgY291bnQgKi8KICAgIGlmIChzcmNEYXRhID09IE5VTEwgfHwgc3RhcnQgKyBjb3VudCA+IEdMX0xJTUlUUyh2c2hhZGVyX2NvbnN0YW50c0YpIHx8IHN0YXJ0ID4gR0xfTElNSVRTKHZzaGFkZXJfY29uc3RhbnRzRikpCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgbWVtY3B5KCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT52ZXJ0ZXhTaGFkZXJDb25zdGFudEZbc3RhcnQgKiA0XSwgc3JjRGF0YSwgY291bnQgKiBzaXplb2YoZmxvYXQpICogNCk7CiAgICBpZihUUkFDRV9PTihkM2QpKSB7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspCiAgICAgICAgICAgIFRSQUNFKCJTZXQgRkxPQVQgY29uc3RhbnQgJXUgdG8geyAlZiwgJWYsICVmLCAlZiB9XG4iLCBzdGFydCArIGksCiAgICAgICAgICAgICAgICAgICAgc3JjRGF0YVtpKjRdLCBzcmNEYXRhW2kqNCsxXSwgc3JjRGF0YVtpKjQrMl0sIHNyY0RhdGFbaSo0KzNdKTsKICAgIH0KCiAgICAvKiBXZSBkb24ndCB3YW50IHNoYWRlciBjb25zdGFudCBkaXJ0aWZpY2F0aW9uIHRvIGJlIGFuIE8oY29udGV4dHMpLCBzbyBqdXN0IGRpcnRpZnkgdGhlIGFjdGl2ZQogICAgICogY29udGV4dC4gT24gYSBjb250ZXh0IHN3aXRjaCB0aGUgb2xkIGNvbnRleHQgd2lsbCBiZSBmdWxseSBkaXJ0aWZpZWQKICAgICAqLwogICAgbWVtc2V0KFRoaXMtPmFjdGl2ZUNvbnRleHQtPnZzaGFkZXJfY29uc3RfZGlydHkgKyBzdGFydCwgMSwKICAgICAgICAgICBzaXplb2YoKlRoaXMtPmFjdGl2ZUNvbnRleHQtPnZzaGFkZXJfY29uc3RfZGlydHkpICogY291bnQpOwogICAgVGhpcy0+aGlnaGVzdF9kaXJ0eV92c19jb25zdCA9IG1heChUaGlzLT5oaWdoZXN0X2RpcnR5X3ZzX2NvbnN0LCBzdGFydCtjb3VudCk7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1ZFUlRFWFNIQURFUkNPTlNUQU5UKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEYoCiAgICBJV2luZUQzRERldmljZSAqaWZhY2UsCiAgICBVSU5UIHN0YXJ0LAogICAgZmxvYXQgKmRzdERhdGEsCiAgICBVSU5UIGNvdW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaW50IGNudCA9IG1pbihjb3VudCwgR0xfTElNSVRTKHZzaGFkZXJfY29uc3RhbnRzRikgLSBzdGFydCk7CgogICAgVFJBQ0UoIihpZmFjZSAlcCwgZHN0RGF0YSAlcCwgc3RhcnQgJWQsIGNvdW50ICVkKVxuIiwKICAgICAgICAgICAgaWZhY2UsIGRzdERhdGEsIHN0YXJ0LCBjb3VudCk7CgogICAgaWYgKGRzdERhdGEgPT0gTlVMTCB8fCBjbnQgPCAwKQogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIG1lbWNweShkc3REYXRhLCAmVGhpcy0+c3RhdGVCbG9jay0+dmVydGV4U2hhZGVyQ29uc3RhbnRGW3N0YXJ0ICogNF0sIGNudCAqIHNpemVvZihmbG9hdCkgKiA0KTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgbWFya1RleHR1cmVTdGFnZXNEaXJ0eShJV2luZUQzRERldmljZUltcGwgKlRoaXMsIERXT1JEIHN0YWdlKSB7CiAgICBEV09SRCBpOwogICAgZm9yKGkgPSAwOyBpIDwgV0lORUQzRF9ISUdIRVNUX1RFWFRVUkVfU1RBVEU7IGkrKykgewogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9URVhUVVJFU1RBR0Uoc3RhZ2UsIGkpKTsKICAgIH0KfQoKc3RhdGljIHZvaWQgZGV2aWNlX21hcF9zdGFnZShJV2luZUQzRERldmljZUltcGwgKlRoaXMsIGludCBzdGFnZSwgaW50IHVuaXQpIHsKICAgIGludCBpID0gVGhpcy0+cmV2X3RleF91bml0X21hcFt1bml0XTsKICAgIGludCBqID0gVGhpcy0+dGV4VW5pdE1hcFtzdGFnZV07CgogICAgVGhpcy0+dGV4VW5pdE1hcFtzdGFnZV0gPSB1bml0OwogICAgaWYgKGkgIT0gLTEgJiYgaSAhPSBzdGFnZSkgewogICAgICAgIFRoaXMtPnRleFVuaXRNYXBbaV0gPSAtMTsKICAgIH0KCiAgICBUaGlzLT5yZXZfdGV4X3VuaXRfbWFwW3VuaXRdID0gc3RhZ2U7CiAgICBpZiAoaiAhPSAtMSAmJiBqICE9IHVuaXQpIHsKICAgICAgICBUaGlzLT5yZXZfdGV4X3VuaXRfbWFwW2pdID0gLTE7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIGRldmljZV91cGRhdGVfZml4ZWRfZnVuY3Rpb25fdXNhZ2VfbWFwKElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcykgewogICAgaW50IGk7CgogICAgZm9yIChpID0gMDsgaSA8IE1BWF9URVhUVVJFUzsgKytpKSB7CiAgICAgICAgV0lORUQzRFRFWFRVUkVPUCBjb2xvcl9vcCA9IFRoaXMtPnN0YXRlQmxvY2stPnRleHR1cmVTdGF0ZVtpXVtXSU5FRDNEVFNTX0NPTE9ST1BdOwogICAgICAgIFdJTkVEM0RURVhUVVJFT1AgYWxwaGFfb3AgPSBUaGlzLT5zdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbaV1bV0lORUQzRFRTU19BTFBIQU9QXTsKICAgICAgICBEV09SRCBjb2xvcl9hcmcxID0gVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlW2ldW1dJTkVEM0RUU1NfQ09MT1JBUkcxXSAmIFdJTkVEM0RUQV9TRUxFQ1RNQVNLOwogICAgICAgIERXT1JEIGNvbG9yX2FyZzIgPSBUaGlzLT5zdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbaV1bV0lORUQzRFRTU19DT0xPUkFSRzJdICYgV0lORUQzRFRBX1NFTEVDVE1BU0s7CiAgICAgICAgRFdPUkQgY29sb3JfYXJnMyA9IFRoaXMtPnN0YXRlQmxvY2stPnRleHR1cmVTdGF0ZVtpXVtXSU5FRDNEVFNTX0NPTE9SQVJHMF0gJiBXSU5FRDNEVEFfU0VMRUNUTUFTSzsKICAgICAgICBEV09SRCBhbHBoYV9hcmcxID0gVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlW2ldW1dJTkVEM0RUU1NfQUxQSEFBUkcxXSAmIFdJTkVEM0RUQV9TRUxFQ1RNQVNLOwogICAgICAgIERXT1JEIGFscGhhX2FyZzIgPSBUaGlzLT5zdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbaV1bV0lORUQzRFRTU19BTFBIQUFSRzJdICYgV0lORUQzRFRBX1NFTEVDVE1BU0s7CiAgICAgICAgRFdPUkQgYWxwaGFfYXJnMyA9IFRoaXMtPnN0YXRlQmxvY2stPnRleHR1cmVTdGF0ZVtpXVtXSU5FRDNEVFNTX0FMUEhBQVJHMF0gJiBXSU5FRDNEVEFfU0VMRUNUTUFTSzsKCiAgICAgICAgaWYgKGNvbG9yX29wID09IFdJTkVEM0RUT1BfRElTQUJMRSkgewogICAgICAgICAgICAvKiBOb3QgdXNlZCwgYW5kIGRpc2FibGUgaGlnaGVyIHN0YWdlcyAqLwogICAgICAgICAgICB3aGlsZSAoaSA8IE1BWF9URVhUVVJFUykgewogICAgICAgICAgICAgICAgVGhpcy0+Zml4ZWRfZnVuY3Rpb25fdXNhZ2VfbWFwW2ldID0gRkFMU0U7CiAgICAgICAgICAgICAgICArK2k7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBpZiAoKChjb2xvcl9hcmcxID09IFdJTkVEM0RUQV9URVhUVVJFKSAmJiBjb2xvcl9vcCAhPSBXSU5FRDNEVE9QX1NFTEVDVEFSRzIpCiAgICAgICAgICAgICAgICB8fCAoKGNvbG9yX2FyZzIgPT0gV0lORUQzRFRBX1RFWFRVUkUpICYmIGNvbG9yX29wICE9IFdJTkVEM0RUT1BfU0VMRUNUQVJHMSkKICAgICAgICAgICAgICAgIHx8ICgoY29sb3JfYXJnMyA9PSBXSU5FRDNEVEFfVEVYVFVSRSkgJiYgKGNvbG9yX29wID09IFdJTkVEM0RUT1BfTVVMVElQTFlBREQgfHwgY29sb3Jfb3AgPT0gV0lORUQzRFRPUF9MRVJQKSkKICAgICAgICAgICAgICAgIHx8ICgoYWxwaGFfYXJnMSA9PSBXSU5FRDNEVEFfVEVYVFVSRSkgJiYgYWxwaGFfb3AgIT0gV0lORUQzRFRPUF9TRUxFQ1RBUkcyKQogICAgICAgICAgICAgICAgfHwgKChhbHBoYV9hcmcyID09IFdJTkVEM0RUQV9URVhUVVJFKSAmJiBhbHBoYV9vcCAhPSBXSU5FRDNEVE9QX1NFTEVDVEFSRzEpCiAgICAgICAgICAgICAgICB8fCAoKGFscGhhX2FyZzMgPT0gV0lORUQzRFRBX1RFWFRVUkUpICYmIChhbHBoYV9vcCA9PSBXSU5FRDNEVE9QX01VTFRJUExZQUREIHx8IGFscGhhX29wID09IFdJTkVEM0RUT1BfTEVSUCkpKSB7CiAgICAgICAgICAgIFRoaXMtPmZpeGVkX2Z1bmN0aW9uX3VzYWdlX21hcFtpXSA9IFRSVUU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVGhpcy0+Zml4ZWRfZnVuY3Rpb25fdXNhZ2VfbWFwW2ldID0gRkFMU0U7CiAgICAgICAgfQoKICAgICAgICBpZiAoKGNvbG9yX29wID09IFdJTkVEM0RUT1BfQlVNUEVOVk1BUCB8fCBjb2xvcl9vcCA9PSBXSU5FRDNEVE9QX0JVTVBFTlZNQVBMVU1JTkFOQ0UpICYmIGkgPCBNQVhfVEVYVFVSRVMgLSAxKSB7CiAgICAgICAgICAgIFRoaXMtPmZpeGVkX2Z1bmN0aW9uX3VzYWdlX21hcFtpKzFdID0gVFJVRTsKICAgICAgICB9CiAgICB9Cn0KCnN0YXRpYyB2b2lkIGRldmljZV9tYXBfZml4ZWRfZnVuY3Rpb25fc2FtcGxlcnMoSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzKSB7CiAgICBpbnQgaSwgdGV4OwoKICAgIGRldmljZV91cGRhdGVfZml4ZWRfZnVuY3Rpb25fdXNhZ2VfbWFwKFRoaXMpOwoKICAgIGlmICghR0xfU1VQUE9SVChOVl9SRUdJU1RFUl9DT01CSU5FUlMpIHx8IFRoaXMtPnN0YXRlQmxvY2stPmxvd2VzdF9kaXNhYmxlZF9zdGFnZSA8PSBHTF9MSU1JVFModGV4dHVyZXMpKSB7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IFRoaXMtPnN0YXRlQmxvY2stPmxvd2VzdF9kaXNhYmxlZF9zdGFnZTsgKytpKSB7CiAgICAgICAgICAgIGlmICghVGhpcy0+Zml4ZWRfZnVuY3Rpb25fdXNhZ2VfbWFwW2ldKSBjb250aW51ZTsKCiAgICAgICAgICAgIGlmIChUaGlzLT50ZXhVbml0TWFwW2ldICE9IGkpIHsKICAgICAgICAgICAgICAgIGRldmljZV9tYXBfc3RhZ2UoVGhpcywgaSwgaSk7CiAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfU0FNUExFUihpKSk7CiAgICAgICAgICAgICAgICBtYXJrVGV4dHVyZVN0YWdlc0RpcnR5KFRoaXMsIGkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvKiBOb3cgd29yayBvdXQgdGhlIG1hcHBpbmcgKi8KICAgIHRleCA9IDA7CiAgICBmb3IgKGkgPSAwOyBpIDwgVGhpcy0+c3RhdGVCbG9jay0+bG93ZXN0X2Rpc2FibGVkX3N0YWdlOyArK2kpIHsKICAgICAgICBpZiAoIVRoaXMtPmZpeGVkX2Z1bmN0aW9uX3VzYWdlX21hcFtpXSkgY29udGludWU7CgogICAgICAgIGlmIChUaGlzLT50ZXhVbml0TWFwW2ldICE9IHRleCkgewogICAgICAgICAgICBkZXZpY2VfbWFwX3N0YWdlKFRoaXMsIGksIHRleCk7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TQU1QTEVSKGkpKTsKICAgICAgICAgICAgbWFya1RleHR1cmVTdGFnZXNEaXJ0eShUaGlzLCBpKTsKICAgICAgICB9CgogICAgICAgICsrdGV4OwogICAgfQp9CgpzdGF0aWMgdm9pZCBkZXZpY2VfbWFwX3BzYW1wbGVycyhJV2luZUQzRERldmljZUltcGwgKlRoaXMpIHsKICAgIERXT1JEICpzYW1wbGVyX3Rva2VucyA9ICgoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwgKilUaGlzLT5zdGF0ZUJsb2NrLT5waXhlbFNoYWRlciktPmJhc2VTaGFkZXIucmVnX21hcHMuc2FtcGxlcnM7CiAgICBpbnQgaTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgTUFYX0ZSQUdNRU5UX1NBTVBMRVJTOyArK2kpIHsKICAgICAgICBpZiAoc2FtcGxlcl90b2tlbnNbaV0gJiYgVGhpcy0+dGV4VW5pdE1hcFtpXSAhPSBpKSB7CiAgICAgICAgICAgIGRldmljZV9tYXBfc3RhZ2UoVGhpcywgaSwgaSk7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TQU1QTEVSKGkpKTsKICAgICAgICAgICAgaWYgKGkgPCBNQVhfVEVYVFVSRVMpIHsKICAgICAgICAgICAgICAgIG1hcmtUZXh0dXJlU3RhZ2VzRGlydHkoVGhpcywgaSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCnN0YXRpYyBCT09MIGRldmljZV91bml0X2ZyZWVfZm9yX3ZzKElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcywgRFdPUkQgKnBzaGFkZXJfc2FtcGxlcl90b2tlbnMsIERXT1JEICp2c2hhZGVyX3NhbXBsZXJfdG9rZW5zLCBpbnQgdW5pdCkgewogICAgaW50IGN1cnJlbnRfbWFwcGluZyA9IFRoaXMtPnJldl90ZXhfdW5pdF9tYXBbdW5pdF07CgogICAgaWYgKGN1cnJlbnRfbWFwcGluZyA9PSAtMSkgewogICAgICAgIC8qIE5vdCBjdXJyZW50bHkgdXNlZCAqLwogICAgICAgIHJldHVybiBUUlVFOwogICAgfQoKICAgIGlmIChjdXJyZW50X21hcHBpbmcgPCBNQVhfRlJBR01FTlRfU0FNUExFUlMpIHsKICAgICAgICAvKiBVc2VkIGJ5IGEgZnJhZ21lbnQgc2FtcGxlciAqLwoKICAgICAgICBpZiAoIXBzaGFkZXJfc2FtcGxlcl90b2tlbnMpIHsKICAgICAgICAgICAgLyogTm8gcGl4ZWwgc2hhZGVyLCBjaGVjayBmaXhlZCBmdW5jdGlvbiAqLwogICAgICAgICAgICByZXR1cm4gY3VycmVudF9tYXBwaW5nID49IE1BWF9URVhUVVJFUyB8fCAhVGhpcy0+Zml4ZWRfZnVuY3Rpb25fdXNhZ2VfbWFwW2N1cnJlbnRfbWFwcGluZ107CiAgICAgICAgfQoKICAgICAgICAvKiBQaXhlbCBzaGFkZXIsIGNoZWNrIHRoZSBzaGFkZXIncyBzYW1wbGVyIG1hcCAqLwogICAgICAgIHJldHVybiAhcHNoYWRlcl9zYW1wbGVyX3Rva2Vuc1tjdXJyZW50X21hcHBpbmddOwogICAgfQoKICAgIC8qIFVzZWQgYnkgYSB2ZXJ0ZXggc2FtcGxlciAqLwogICAgcmV0dXJuICF2c2hhZGVyX3NhbXBsZXJfdG9rZW5zW2N1cnJlbnRfbWFwcGluZ107Cn0KCnN0YXRpYyB2b2lkIGRldmljZV9tYXBfdnNhbXBsZXJzKElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcywgQk9PTCBwcykgewogICAgRFdPUkQgKnZzaGFkZXJfc2FtcGxlcl90b2tlbnMgPSAoKElXaW5lRDNEVmVydGV4U2hhZGVySW1wbCAqKVRoaXMtPnN0YXRlQmxvY2stPnZlcnRleFNoYWRlciktPmJhc2VTaGFkZXIucmVnX21hcHMuc2FtcGxlcnM7CiAgICBEV09SRCAqcHNoYWRlcl9zYW1wbGVyX3Rva2VucyA9IE5VTEw7CiAgICBpbnQgc3RhcnQgPSBHTF9MSU1JVFMoY29tYmluZWRfc2FtcGxlcnMpIC0gMTsKICAgIGludCBpOwoKICAgIGlmIChwcykgewogICAgICAgIElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICpwc2hhZGVyID0gKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICopVGhpcy0+c3RhdGVCbG9jay0+cGl4ZWxTaGFkZXI7CgogICAgICAgIC8qIE1ha2Ugc3VyZSB0aGUgc2hhZGVyJ3MgcmVnX21hcHMgYXJlIHVwIHRvIGRhdGUuIFRoaXMgaXMgb25seSByZWxldmFudCBmb3IgMS54IHBpeGVsc2hhZGVycy4gKi8KICAgICAgICBJV2luZUQzRFBpeGVsU2hhZGVyX0NvbXBpbGVTaGFkZXIoKElXaW5lRDNEUGl4ZWxTaGFkZXIgKilwc2hhZGVyKTsKICAgICAgICBwc2hhZGVyX3NhbXBsZXJfdG9rZW5zID0gcHNoYWRlci0+YmFzZVNoYWRlci5yZWdfbWFwcy5zYW1wbGVyczsKICAgIH0KCiAgICBmb3IgKGkgPSAwOyBpIDwgTUFYX1ZFUlRFWF9TQU1QTEVSUzsgKytpKSB7CiAgICAgICAgaW50IHZzYW1wbGVyX2lkeCA9IGkgKyBNQVhfRlJBR01FTlRfU0FNUExFUlM7CiAgICAgICAgaWYgKHZzaGFkZXJfc2FtcGxlcl90b2tlbnNbaV0pIHsKICAgICAgICAgICAgaWYgKFRoaXMtPnRleFVuaXRNYXBbdnNhbXBsZXJfaWR4XSAhPSAtMSkgewogICAgICAgICAgICAgICAgLyogQWxyZWFkeSBtYXBwZWQgc29tZXdoZXJlICovCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgd2hpbGUgKHN0YXJ0ID49IDApIHsKICAgICAgICAgICAgICAgIGlmIChkZXZpY2VfdW5pdF9mcmVlX2Zvcl92cyhUaGlzLCBwc2hhZGVyX3NhbXBsZXJfdG9rZW5zLCB2c2hhZGVyX3NhbXBsZXJfdG9rZW5zLCBzdGFydCkpIHsKICAgICAgICAgICAgICAgICAgICBkZXZpY2VfbWFwX3N0YWdlKFRoaXMsIHZzYW1wbGVyX2lkeCwgc3RhcnQpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TQU1QTEVSKHZzYW1wbGVyX2lkeCkpOwoKICAgICAgICAgICAgICAgICAgICAtLXN0YXJ0OwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC0tc3RhcnQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCnZvaWQgSVdpbmVEM0REZXZpY2VJbXBsX0ZpbmRUZXhVbml0TWFwKElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcykgewogICAgQk9PTCB2cyA9IHVzZV92cyhUaGlzKTsKICAgIEJPT0wgcHMgPSB1c2VfcHMoVGhpcyk7CiAgICAvKgogICAgICogUnVsZXMgYXJlOgogICAgICogLT4gUGl4ZWwgc2hhZGVycyBuZWVkIGEgMToxIG1hcC4gSW4gdGhlb3J5IHRoZSBzaGFkZXIgaW5wdXQgY291bGQgYmUgbWFwcGVkIHRvbywgYnV0CiAgICAgKiB0aGF0IHdvdWxkIGJlIHJlYWxseSBtZXNzeSBhbmQgcmVxdWlyZSBzaGFkZXIgcmVjb21waWxhdGlvbgogICAgICogLT4gV2hlbiB0aGUgbWFwcGluZyBvZiBhIHN0YWdlIGlzIGNoYW5nZWQsIHNhbXBsZXIgYW5kIEFMTCB0ZXh0dXJlIHN0YWdlIHN0YXRlcyBoYXZlCiAgICAgKiB0byBiZSByZXNldC4gQmVjYXVzZSBvZiB0aGF0IHRyeSB0byB3b3JrIHdpdGggYSAxOjEgbWFwcGluZyBhcyBtdWNoIGFzIHBvc3NpYmxlCiAgICAgKi8KICAgIGlmIChwcykgewogICAgICAgIGRldmljZV9tYXBfcHNhbXBsZXJzKFRoaXMpOwogICAgfSBlbHNlIHsKICAgICAgICBkZXZpY2VfbWFwX2ZpeGVkX2Z1bmN0aW9uX3NhbXBsZXJzKFRoaXMpOwogICAgfQoKICAgIGlmICh2cykgewogICAgICAgIGRldmljZV9tYXBfdnNhbXBsZXJzKFRoaXMsIHBzKTsKICAgIH0KfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRQaXhlbFNoYWRlcihJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEUGl4ZWxTaGFkZXIgKnBTaGFkZXIpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyAgICAgICAgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFBpeGVsU2hhZGVyICpvbGRTaGFkZXIgID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+cGl4ZWxTaGFkZXI7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5waXhlbFNoYWRlciAgICAgICAgID0gcFNoYWRlcjsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQucGl4ZWxTaGFkZXIgPSBUUlVFOwoKICAgIC8qIEhhbmRsZSByZWNvcmRpbmcgb2Ygc3RhdGUgYmxvY2tzICovCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgfQoKICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICAgICAgaWYocFNoYWRlcikgSVdpbmVEM0RQaXhlbFNoYWRlcl9BZGRSZWYocFNoYWRlcik7CiAgICAgICAgaWYob2xkU2hhZGVyKSBJV2luZUQzRFBpeGVsU2hhZGVyX1JlbGVhc2Uob2xkU2hhZGVyKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBpZihwU2hhZGVyID09IG9sZFNoYWRlcikgewogICAgICAgIFRSQUNFKCJBcHAgaXMgc2V0dGluZyB0aGUgb2xkIHBpeGVsIHNoYWRlciBvdmVyLCBub3RoaW5nIHRvIGRvXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBpZihwU2hhZGVyKSBJV2luZUQzRFBpeGVsU2hhZGVyX0FkZFJlZihwU2hhZGVyKTsKICAgIGlmKG9sZFNoYWRlcikgSVdpbmVEM0RQaXhlbFNoYWRlcl9SZWxlYXNlKG9sZFNoYWRlcik7CgogICAgVFJBQ0UoIiglcCkgOiBzZXR0aW5nIHBTaGFkZXIoJXApXG4iLCBUaGlzLCBwU2hhZGVyKTsKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9QSVhFTFNIQURFUik7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0UGl4ZWxTaGFkZXIoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFBpeGVsU2hhZGVyICoqcHBTaGFkZXIpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBpZiAoTlVMTCA9PSBwcFNoYWRlcikgewogICAgICAgIFdBUk4oIiglcCkgOiBQU2hhZGVyIGlzIE5VTEwsIHJldHVybmluZyBJTlZBTElEQ0FMTFxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgKnBwU2hhZGVyID0gIFRoaXMtPnN0YXRlQmxvY2stPnBpeGVsU2hhZGVyOwogICAgaWYgKE5VTEwgIT0gKnBwU2hhZGVyKSB7CiAgICAgICAgSVdpbmVEM0RQaXhlbFNoYWRlcl9BZGRSZWYoKnBwU2hhZGVyKTsKICAgIH0KICAgIFRSQUNFKCIoJXApIDogcmV0dXJuaW5nICVwXG4iLCBUaGlzLCAqcHBTaGFkZXIpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0UGl4ZWxTaGFkZXJDb25zdGFudEIoCiAgICBJV2luZUQzRERldmljZSAqaWZhY2UsCiAgICBVSU5UIHN0YXJ0LAogICAgQ09OU1QgQk9PTCAqc3JjRGF0YSwKICAgIFVJTlQgY291bnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpbnQgaSwgY250ID0gbWluKGNvdW50LCBNQVhfQ09OU1RfQiAtIHN0YXJ0KTsKCiAgICBUUkFDRSgiKGlmYWNlICVwLCBzcmNEYXRhICVwLCBzdGFydCAlZCwgY291bnQgJWQpXG4iLAogICAgICAgICAgICBpZmFjZSwgc3JjRGF0YSwgc3RhcnQsIGNvdW50KTsKCiAgICBpZiAoc3JjRGF0YSA9PSBOVUxMIHx8IGNudCA8IDApCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgbWVtY3B5KCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5waXhlbFNoYWRlckNvbnN0YW50QltzdGFydF0sIHNyY0RhdGEsIGNudCAqIHNpemVvZihCT09MKSk7CiAgICBmb3IgKGkgPSAwOyBpIDwgY250OyBpKyspCiAgICAgICAgVFJBQ0UoIlNldCBCT09MIGNvbnN0YW50ICV1IHRvICVzXG4iLCBzdGFydCArIGksIHNyY0RhdGFbaV0/ICJ0cnVlIjoiZmFsc2UiKTsKCiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGNudCArIHN0YXJ0OyArK2kpIHsKICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnBpeGVsU2hhZGVyQ29uc3RhbnRzQltpXSA9IFRSVUU7CiAgICB9CgogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1BJWEVMU0hBREVSQ09OU1RBTlQpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFBpeGVsU2hhZGVyQ29uc3RhbnRCKAogICAgSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgVUlOVCBzdGFydCwKICAgIEJPT0wgKmRzdERhdGEsCiAgICBVSU5UIGNvdW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaW50IGNudCA9IG1pbihjb3VudCwgTUFYX0NPTlNUX0IgLSBzdGFydCk7CgogICAgVFJBQ0UoIihpZmFjZSAlcCwgZHN0RGF0YSAlcCwgc3RhcnQgJWQsIGNvdW50ICVkKVxuIiwKICAgICAgICAgICAgaWZhY2UsIGRzdERhdGEsIHN0YXJ0LCBjb3VudCk7CgogICAgaWYgKGRzdERhdGEgPT0gTlVMTCB8fCBjbnQgPCAwKQogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIG1lbWNweShkc3REYXRhLCAmVGhpcy0+c3RhdGVCbG9jay0+cGl4ZWxTaGFkZXJDb25zdGFudEJbc3RhcnRdLCBjbnQgKiBzaXplb2YoQk9PTCkpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0UGl4ZWxTaGFkZXJDb25zdGFudEkoCiAgICBJV2luZUQzRERldmljZSAqaWZhY2UsCiAgICBVSU5UIHN0YXJ0LAogICAgQ09OU1QgaW50ICpzcmNEYXRhLAogICAgVUlOVCBjb3VudCkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIGludCBpLCBjbnQgPSBtaW4oY291bnQsIE1BWF9DT05TVF9JIC0gc3RhcnQpOwoKICAgIFRSQUNFKCIoaWZhY2UgJXAsIHNyY0RhdGEgJXAsIHN0YXJ0ICVkLCBjb3VudCAlZClcbiIsCiAgICAgICAgICAgIGlmYWNlLCBzcmNEYXRhLCBzdGFydCwgY291bnQpOwoKICAgIGlmIChzcmNEYXRhID09IE5VTEwgfHwgY250IDwgMCkKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICBtZW1jcHkoJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnBpeGVsU2hhZGVyQ29uc3RhbnRJW3N0YXJ0ICogNF0sIHNyY0RhdGEsIGNudCAqIHNpemVvZihpbnQpICogNCk7CiAgICBmb3IgKGkgPSAwOyBpIDwgY250OyBpKyspCiAgICAgICAgVFJBQ0UoIlNldCBJTlQgY29uc3RhbnQgJXUgdG8geyAlZCwgJWQsICVkLCAlZCB9XG4iLCBzdGFydCArIGksCiAgICAgICAgICAgc3JjRGF0YVtpKjRdLCBzcmNEYXRhW2kqNCsxXSwgc3JjRGF0YVtpKjQrMl0sIHNyY0RhdGFbaSo0KzNdKTsKCiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGNudCArIHN0YXJ0OyArK2kpIHsKICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnBpeGVsU2hhZGVyQ29uc3RhbnRzSVtpXSA9IFRSVUU7CiAgICB9CgogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1BJWEVMU0hBREVSQ09OU1RBTlQpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFBpeGVsU2hhZGVyQ29uc3RhbnRJKAogICAgSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgVUlOVCBzdGFydCwKICAgIGludCAqZHN0RGF0YSwKICAgIFVJTlQgY291bnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpbnQgY250ID0gbWluKGNvdW50LCBNQVhfQ09OU1RfSSAtIHN0YXJ0KTsKCiAgICBUUkFDRSgiKGlmYWNlICVwLCBkc3REYXRhICVwLCBzdGFydCAlZCwgY291bnQgJWQpXG4iLAogICAgICAgICAgICBpZmFjZSwgZHN0RGF0YSwgc3RhcnQsIGNvdW50KTsKCiAgICBpZiAoZHN0RGF0YSA9PSBOVUxMIHx8IGNudCA8IDApCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgbWVtY3B5KGRzdERhdGEsICZUaGlzLT5zdGF0ZUJsb2NrLT5waXhlbFNoYWRlckNvbnN0YW50SVtzdGFydCAqIDRdLCBjbnQgKiBzaXplb2YoaW50KSAqIDQpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0UGl4ZWxTaGFkZXJDb25zdGFudEYoCiAgICBJV2luZUQzRERldmljZSAqaWZhY2UsCiAgICBVSU5UIHN0YXJ0LAogICAgQ09OU1QgZmxvYXQgKnNyY0RhdGEsCiAgICBVSU5UIGNvdW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaW50IGk7CgogICAgVFJBQ0UoIihpZmFjZSAlcCwgc3JjRGF0YSAlcCwgc3RhcnQgJWQsIGNvdW50ICVkKVxuIiwKICAgICAgICAgICAgaWZhY2UsIHNyY0RhdGEsIHN0YXJ0LCBjb3VudCk7CgogICAgLyogU3BlY2lmaWNhbGx5IHRlc3Qgc3RhcnQgPiBsaW1pdCB0byBjYXRjaCBNQVhfVUlOVCBvdmVyZmxvd3Mgd2hlbiBhZGRpbmcgc3RhcnQgKyBjb3VudCAqLwogICAgaWYgKHNyY0RhdGEgPT0gTlVMTCB8fCBzdGFydCArIGNvdW50ID4gR0xfTElNSVRTKHBzaGFkZXJfY29uc3RhbnRzRikgfHwgc3RhcnQgPiBHTF9MSU1JVFMocHNoYWRlcl9jb25zdGFudHNGKSkKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICBtZW1jcHkoJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnBpeGVsU2hhZGVyQ29uc3RhbnRGW3N0YXJ0ICogNF0sIHNyY0RhdGEsIGNvdW50ICogc2l6ZW9mKGZsb2F0KSAqIDQpOwogICAgaWYoVFJBQ0VfT04oZDNkKSkgewogICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb3VudDsgaSsrKQogICAgICAgICAgICBUUkFDRSgiU2V0IEZMT0FUIGNvbnN0YW50ICV1IHRvIHsgJWYsICVmLCAlZiwgJWYgfVxuIiwgc3RhcnQgKyBpLAogICAgICAgICAgICAgICAgc3JjRGF0YVtpKjRdLCBzcmNEYXRhW2kqNCsxXSwgc3JjRGF0YVtpKjQrMl0sIHNyY0RhdGFbaSo0KzNdKTsKICAgIH0KCiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGNvdW50ICsgc3RhcnQ7ICsraSkgewogICAgICAgIGlmICghVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC5waXhlbFNoYWRlckNvbnN0YW50c0ZbaV0pIHsKICAgICAgICAgICAgY29uc3RhbnRzX2VudHJ5ICpwdHIgPSBMSVNUX0VOVFJZKGxpc3RfaGVhZCgmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0X3Bjb25zdGFudHNGKSwgY29uc3RhbnRzX2VudHJ5LCBlbnRyeSk7CiAgICAgICAgICAgIGlmICghcHRyIHx8IHB0ci0+Y291bnQgPj0gc2l6ZW9mKHB0ci0+aWR4KSAvIHNpemVvZigqcHRyLT5pZHgpKSB7CiAgICAgICAgICAgICAgICBwdHIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKGNvbnN0YW50c19lbnRyeSkpOwogICAgICAgICAgICAgICAgbGlzdF9hZGRfaGVhZCgmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0X3Bjb25zdGFudHNGLCAmcHRyLT5lbnRyeSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHRyLT5pZHhbcHRyLT5jb3VudCsrXSA9IGk7CiAgICAgICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQucGl4ZWxTaGFkZXJDb25zdGFudHNGW2ldID0gVFJVRTsKICAgICAgICB9CiAgICB9CgogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1BJWEVMU0hBREVSQ09OU1RBTlQpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFBpeGVsU2hhZGVyQ29uc3RhbnRGX0RpcnR5Q29uc3QoCiAgICBJV2luZUQzRERldmljZSAqaWZhY2UsCiAgICBVSU5UIHN0YXJ0LAogICAgQ09OU1QgZmxvYXQgKnNyY0RhdGEsCiAgICBVSU5UIGNvdW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaW50IGk7CgogICAgVFJBQ0UoIihpZmFjZSAlcCwgc3JjRGF0YSAlcCwgc3RhcnQgJWQsIGNvdW50ICVkKVxuIiwKICAgICAgICAgICAgaWZhY2UsIHNyY0RhdGEsIHN0YXJ0LCBjb3VudCk7CgogICAgLyogU3BlY2lmaWNhbGx5IHRlc3Qgc3RhcnQgPiBsaW1pdCB0byBjYXRjaCBNQVhfVUlOVCBvdmVyZmxvd3Mgd2hlbiBhZGRpbmcgc3RhcnQgKyBjb3VudCAqLwogICAgaWYgKHNyY0RhdGEgPT0gTlVMTCB8fCBzdGFydCArIGNvdW50ID4gR0xfTElNSVRTKHBzaGFkZXJfY29uc3RhbnRzRikgfHwgc3RhcnQgPiBHTF9MSU1JVFMocHNoYWRlcl9jb25zdGFudHNGKSkKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICBtZW1jcHkoJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnBpeGVsU2hhZGVyQ29uc3RhbnRGW3N0YXJ0ICogNF0sIHNyY0RhdGEsIGNvdW50ICogc2l6ZW9mKGZsb2F0KSAqIDQpOwogICAgaWYoVFJBQ0VfT04oZDNkKSkgewogICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb3VudDsgaSsrKQogICAgICAgICAgICBUUkFDRSgiU2V0IEZMT0FUIGNvbnN0YW50ICV1IHRvIHsgJWYsICVmLCAlZiwgJWYgfVxuIiwgc3RhcnQgKyBpLAogICAgICAgICAgICAgICAgICAgIHNyY0RhdGFbaSo0XSwgc3JjRGF0YVtpKjQrMV0sIHNyY0RhdGFbaSo0KzJdLCBzcmNEYXRhW2kqNCszXSk7CiAgICB9CgogICAgLyogV2UgZG9uJ3Qgd2FudCBzaGFkZXIgY29uc3RhbnQgZGlydGlmaWNhdGlvbiB0byBiZSBhbiBPKGNvbnRleHRzKSwgc28ganVzdCBkaXJ0aWZ5IHRoZSBhY3RpdmUKICAgICAqIGNvbnRleHQuIE9uIGEgY29udGV4dCBzd2l0Y2ggdGhlIG9sZCBjb250ZXh0IHdpbGwgYmUgZnVsbHkgZGlydGlmaWVkCiAgICAgKi8KICAgIG1lbXNldChUaGlzLT5hY3RpdmVDb250ZXh0LT5wc2hhZGVyX2NvbnN0X2RpcnR5ICsgc3RhcnQsIDEsCiAgICAgICAgICAgc2l6ZW9mKCpUaGlzLT5hY3RpdmVDb250ZXh0LT5wc2hhZGVyX2NvbnN0X2RpcnR5KSAqIGNvdW50KTsKICAgIFRoaXMtPmhpZ2hlc3RfZGlydHlfcHNfY29uc3QgPSBtYXgoVGhpcy0+aGlnaGVzdF9kaXJ0eV9wc19jb25zdCwgc3RhcnQrY291bnQpOwoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9QSVhFTFNIQURFUkNPTlNUQU5UKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQaXhlbFNoYWRlckNvbnN0YW50RigKICAgIElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgIFVJTlQgc3RhcnQsCiAgICBmbG9hdCAqZHN0RGF0YSwKICAgIFVJTlQgY291bnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpbnQgY250ID0gbWluKGNvdW50LCBHTF9MSU1JVFMocHNoYWRlcl9jb25zdGFudHNGKSAtIHN0YXJ0KTsKCiAgICBUUkFDRSgiKGlmYWNlICVwLCBkc3REYXRhICVwLCBzdGFydCAlZCwgY291bnQgJWQpXG4iLAogICAgICAgICAgICBpZmFjZSwgZHN0RGF0YSwgc3RhcnQsIGNvdW50KTsKCiAgICBpZiAoZHN0RGF0YSA9PSBOVUxMIHx8IGNudCA8IDApCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgbWVtY3B5KGRzdERhdGEsICZUaGlzLT5zdGF0ZUJsb2NrLT5waXhlbFNoYWRlckNvbnN0YW50RltzdGFydCAqIDRdLCBjbnQgKiBzaXplb2YoZmxvYXQpICogNCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKI2RlZmluZSBjb3B5X2FuZF9uZXh0KGRlc3QsIHNyYywgc2l6ZSkgbWVtY3B5KGRlc3QsIHNyYywgc2l6ZSk7IGRlc3QgKz0gKHNpemUpCnN0YXRpYyBIUkVTVUxUCnByb2Nlc3NfdmVydGljZXNfc3RyaWRlZChJV2luZUQzRERldmljZUltcGwgKlRoaXMsIERXT1JEIGR3RGVzdEluZGV4LCBEV09SRCBkd0NvdW50LCBXaW5lRGlyZWN0M0RWZXJ0ZXhTdHJpZGVkRGF0YSAqbHBTdHJpZGVEYXRhLCBJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKmRlc3QsIERXT1JEIGR3RmxhZ3MpIHsKICAgIGNoYXIgKmRlc3RfcHRyLCAqZGVzdF9jb252ID0gTlVMTCwgKmRlc3RfY29udl9hZGRyID0gTlVMTDsKICAgIHVuc2lnbmVkIGludCBpOwogICAgRFdPUkQgRGVzdEZWRiA9IGRlc3QtPmZ2ZjsKICAgIFdJTkVEM0RWSUVXUE9SVCB2cDsKICAgIFdJTkVEM0RNQVRSSVggbWF0LCBwcm9qX21hdCwgdmlld19tYXQsIHdvcmxkX21hdDsKICAgIEJPT0wgZG9DbGlwOwogICAgaW50IG51bVRleHR1cmVzOwoKICAgIGlmIChscFN0cmlkZURhdGEtPnUucy5ub3JtYWwubHBEYXRhKSB7CiAgICAgICAgV0FSTigiIGxpZ2h0aW5nIHN0YXRlIG5vdCBzYXZlZCB5ZXQuLi4gU29tZSBzdHJhbmdlIHN0dWZmIG1heSBoYXBwZW4gIVxuIik7CiAgICB9CgogICAgaWYgKGxwU3RyaWRlRGF0YS0+dS5zLnBvc2l0aW9uLmxwRGF0YSA9PSBOVUxMKSB7CiAgICAgICAgRVJSKCJTb3VyY2UgaGFzIG5vIHBvc2l0aW9uIG1hc2tcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIC8qIFdlIG1pZ2h0IGFjY2VzcyBWQk9zIGZyb20gdGhpcyBjb2RlLCBzbyBob2xkIHRoZSBsb2NrICovCiAgICBFTlRFUl9HTCgpOwoKICAgIGlmIChkZXN0LT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPT0gTlVMTCkgewogICAgICAgIC8qIFRoaXMgbWF5IGhhcHBlbiBpZiB3ZSBkbyBkaXJlY3QgbG9ja2luZyBpbnRvIGEgdmJvLiBVbmxpa2VseSwKICAgICAgICAgKiBidXQgdGhlb3JldGljYWxseSBwb3NzaWJsZShkZHJhdyBwcm9jZXNzdmVydGljZXMgdGVzdCkKICAgICAgICAgKi8KICAgICAgICBkZXN0LT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZGVzdC0+cmVzb3VyY2Uuc2l6ZSk7CiAgICAgICAgaWYoIWRlc3QtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgewogICAgICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnlcbiIpOwogICAgICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgICAgICB9CiAgICAgICAgaWYoZGVzdC0+dmJvKSB7CiAgICAgICAgICAgIHZvaWQgKnNyYzsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEJpbmRCdWZmZXJBUkIoR0xfQVJSQVlfQlVGRkVSX0FSQiwgZGVzdC0+dmJvKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRCdWZmZXJBUkIiKTsKICAgICAgICAgICAgc3JjID0gR0xfRVhUQ0FMTChnbE1hcEJ1ZmZlckFSQihHTF9BUlJBWV9CVUZGRVJfQVJCLCBHTF9SRUFEX09OTFlfQVJCKSk7CiAgICAgICAgICAgIGlmKHNyYykgewogICAgICAgICAgICAgICAgbWVtY3B5KGRlc3QtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwgc3JjLCBkZXN0LT5yZXNvdXJjZS5zaXplKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBHTF9FWFRDQUxMKGdsVW5tYXBCdWZmZXJBUkIoR0xfQVJSQVlfQlVGRkVSX0FSQikpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xVbm1hcEJ1ZmZlckFSQiIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBHZXQgYSBwb2ludGVyIGludG8gdGhlIGRlc3RpbmF0aW9uIHZibyhjcmVhdGUgb25lIGlmIG5vbmUgZXhpc3RzKSBhbmQKICAgICAqIHdyaXRlIGNvcnJlY3Qgb3BlbmdsIGRhdGEgaW50byBpdC4gSXQncyBjaGVhcCBhbmQgYWxsb3dzIHVzIHRvIHJ1biBkcmF3U3RyaWRlZEZhc3QKICAgICAqLwogICAgaWYoIWRlc3QtPnZibyAmJiBHTF9TVVBQT1JUKEFSQl9WRVJURVhfQlVGRkVSX09CSkVDVCkpIHsKICAgICAgICBkZXN0LT5GbGFncyB8PSBWQkZMQUdfQ1JFQVRFVkJPOwogICAgICAgIElXaW5lRDNEVmVydGV4QnVmZmVyX1ByZUxvYWQoKElXaW5lRDNEVmVydGV4QnVmZmVyICopIGRlc3QpOwogICAgfQoKICAgIGlmKGRlc3QtPnZibykgewogICAgICAgIHVuc2lnbmVkIGNoYXIgZXh0cmFieXRlcyA9IDA7CiAgICAgICAgLyogSWYgdGhlIGRlc3RpbmF0aW9uIHZlcnRleCBidWZmZXIgaGFzIEQzREZWRl9YWVogcG9zaXRpb24obm9uLXJodyksIG5hdGl2ZSBkM2Qgd3JpdGVzIFJIVyBwb3NpdGlvbiwgd2hlcmUgdGhlIFJIVwogICAgICAgICAqIGdldHMgd3JpdHRlbiBpbnRvIHRoZSA0IGJ5dGVzIGFmdGVyIHRoZSBaIHBvc2l0aW9uLiBJbiB0aGUgY2FzZSBvZiBhIGRlc3QgYnVmZmVyIHRoYXQgb25seSBoYXMgRDNERlZGX1hZWiBkYXRhLAogICAgICAgICAqIHRoaXMgbWF5IHdyaXRlIDQgZXh0cmEgYnl0ZXMgYmV5b25kIHRoZSBhcmVhIHRoYXQgc2hvdWxkIGJlIHdyaXR0ZW4KICAgICAgICAgKi8KICAgICAgICBpZihEZXN0RlZGID09IFdJTkVEM0RGVkZfWFlaKSBleHRyYWJ5dGVzID0gNDsKICAgICAgICBkZXN0X2NvbnZfYWRkciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBkd0NvdW50ICogZ2V0X2ZsZXhpYmxlX3ZlcnRleF9zaXplKERlc3RGVkYpICsgZXh0cmFieXRlcyk7CiAgICAgICAgaWYoIWRlc3RfY29udl9hZGRyKSB7CiAgICAgICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeVxuIik7CiAgICAgICAgICAgIC8qIENvbnRpbnVlIHdpdGhvdXQgc3RvcmluZyBjb252ZXJ0ZWQgdmVydGljZXMgKi8KICAgICAgICB9CiAgICAgICAgZGVzdF9jb252ID0gZGVzdF9jb252X2FkZHI7CiAgICB9CgogICAgLyogU2hvdWxkIEkgY2xpcD8KICAgICAqIGEpIFdJTkVEM0RSU19DTElQUElORyBpcyBlbmFibGVkCiAgICAgKiBiKSBXSU5FRDNEVk9QX0NMSVAgaXMgcGFzc2VkCiAgICAgKi8KICAgIGlmKFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19DTElQUElOR10pIHsKICAgICAgICBzdGF0aWMgQk9PTCB3YXJuZWQgPSBGQUxTRTsKICAgICAgICAvKgogICAgICAgICAqIFRoZSBjbGlwcGluZyBjb2RlIGlzIG5vdCBxdWl0ZSBjb3JyZWN0LiBTb21lIHRoaW5ncyBuZWVkCiAgICAgICAgICogdG8gYmUgY2hlY2tlZCBhZ2FpbnN0IElEaXJlY3QzRERldmljZTMgKCEpLCBkM2Q4IGFuZCBkM2Q5LAogICAgICAgICAqIHNvIGRpc2FibGUgY2xpcHBpbmcgZm9yIG5vdy4KICAgICAgICAgKiAoVGhlIGdyYXBoaWNzIGluIEhhbGYtTGlmZSBhcmUgYnJva2VuLCBhbmQgbXkgcHJvY2Vzc3ZlcnRpY2VzCiAgICAgICAgICogIHRlc3QgY3Jhc2hlcyB3aXRoIElEaXJlY3QzRERldmljZTMpCiAgICAgICAgZG9DbGlwID0gVFJVRTsKICAgICAgICAgKi8KICAgICAgICBkb0NsaXAgPSBGQUxTRTsKICAgICAgICBpZighd2FybmVkKSB7CiAgICAgICAgICAgd2FybmVkID0gVFJVRTsKICAgICAgICAgICBGSVhNRSgiQ2xpcHBpbmcgaXMgYnJva2VuIGFuZCBkaXNhYmxlZCBmb3Igbm93XG4iKTsKICAgICAgICB9CiAgICB9IGVsc2UgZG9DbGlwID0gRkFMU0U7CiAgICBkZXN0X3B0ciA9ICgoY2hhciAqKSBkZXN0LT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpICsgZHdEZXN0SW5kZXggKiBnZXRfZmxleGlibGVfdmVydGV4X3NpemUoRGVzdEZWRik7CgogICAgSVdpbmVEM0REZXZpY2VfR2V0VHJhbnNmb3JtKCAoSVdpbmVEM0REZXZpY2UgKikgVGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFRTX1ZJRVcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ2aWV3X21hdCk7CiAgICBJV2luZUQzRERldmljZV9HZXRUcmFuc2Zvcm0oIChJV2luZUQzRERldmljZSAqKSBUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNEVFNfUFJPSkVDVElPTiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnByb2pfbWF0KTsKICAgIElXaW5lRDNERGV2aWNlX0dldFRyYW5zZm9ybSggKElXaW5lRDNERGV2aWNlICopIFRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RUU19XT1JMRE1BVFJJWCgwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJndvcmxkX21hdCk7CgogICAgVFJBQ0UoIlZpZXcgbWF0OlxuIik7CiAgICBUUkFDRSgiJWYgJWYgJWYgJWZcbiIsIHZpZXdfbWF0LnUucy5fMTEsIHZpZXdfbWF0LnUucy5fMTIsIHZpZXdfbWF0LnUucy5fMTMsIHZpZXdfbWF0LnUucy5fMTQpOwogICAgVFJBQ0UoIiVmICVmICVmICVmXG4iLCB2aWV3X21hdC51LnMuXzIxLCB2aWV3X21hdC51LnMuXzIyLCB2aWV3X21hdC51LnMuXzIzLCB2aWV3X21hdC51LnMuXzI0KTsKICAgIFRSQUNFKCIlZiAlZiAlZiAlZlxuIiwgdmlld19tYXQudS5zLl8zMSwgdmlld19tYXQudS5zLl8zMiwgdmlld19tYXQudS5zLl8zMywgdmlld19tYXQudS5zLl8zNCk7CiAgICBUUkFDRSgiJWYgJWYgJWYgJWZcbiIsIHZpZXdfbWF0LnUucy5fNDEsIHZpZXdfbWF0LnUucy5fNDIsIHZpZXdfbWF0LnUucy5fNDMsIHZpZXdfbWF0LnUucy5fNDQpOwoKICAgIFRSQUNFKCJQcm9qIG1hdDpcbiIpOwogICAgVFJBQ0UoIiVmICVmICVmICVmXG4iLCBwcm9qX21hdC51LnMuXzExLCBwcm9qX21hdC51LnMuXzEyLCBwcm9qX21hdC51LnMuXzEzLCBwcm9qX21hdC51LnMuXzE0KTsKICAgIFRSQUNFKCIlZiAlZiAlZiAlZlxuIiwgcHJval9tYXQudS5zLl8yMSwgcHJval9tYXQudS5zLl8yMiwgcHJval9tYXQudS5zLl8yMywgcHJval9tYXQudS5zLl8yNCk7CiAgICBUUkFDRSgiJWYgJWYgJWYgJWZcbiIsIHByb2pfbWF0LnUucy5fMzEsIHByb2pfbWF0LnUucy5fMzIsIHByb2pfbWF0LnUucy5fMzMsIHByb2pfbWF0LnUucy5fMzQpOwogICAgVFJBQ0UoIiVmICVmICVmICVmXG4iLCBwcm9qX21hdC51LnMuXzQxLCBwcm9qX21hdC51LnMuXzQyLCBwcm9qX21hdC51LnMuXzQzLCBwcm9qX21hdC51LnMuXzQ0KTsKCiAgICBUUkFDRSgiV29ybGQgbWF0OlxuIik7CiAgICBUUkFDRSgiJWYgJWYgJWYgJWZcbiIsIHdvcmxkX21hdC51LnMuXzExLCB3b3JsZF9tYXQudS5zLl8xMiwgd29ybGRfbWF0LnUucy5fMTMsIHdvcmxkX21hdC51LnMuXzE0KTsKICAgIFRSQUNFKCIlZiAlZiAlZiAlZlxuIiwgd29ybGRfbWF0LnUucy5fMjEsIHdvcmxkX21hdC51LnMuXzIyLCB3b3JsZF9tYXQudS5zLl8yMywgd29ybGRfbWF0LnUucy5fMjQpOwogICAgVFJBQ0UoIiVmICVmICVmICVmXG4iLCB3b3JsZF9tYXQudS5zLl8zMSwgd29ybGRfbWF0LnUucy5fMzIsIHdvcmxkX21hdC51LnMuXzMzLCB3b3JsZF9tYXQudS5zLl8zNCk7CiAgICBUUkFDRSgiJWYgJWYgJWYgJWZcbiIsIHdvcmxkX21hdC51LnMuXzQxLCB3b3JsZF9tYXQudS5zLl80Miwgd29ybGRfbWF0LnUucy5fNDMsIHdvcmxkX21hdC51LnMuXzQ0KTsKCiAgICAvKiBHZXQgdGhlIHZpZXdwb3J0ICovCiAgICBJV2luZUQzRERldmljZV9HZXRWaWV3cG9ydCggKElXaW5lRDNERGV2aWNlICopIFRoaXMsICZ2cCk7CiAgICBUUkFDRSgiVmlld3BvcnQ6IFg9JWQsIFk9JWQsIFdpZHRoPSVkLCBIZWlnaHQ9JWQsIE1pblo9JWYsIE1heFo9JWZcbiIsCiAgICAgICAgICB2cC5YLCB2cC5ZLCB2cC5XaWR0aCwgdnAuSGVpZ2h0LCB2cC5NaW5aLCB2cC5NYXhaKTsKCiAgICBtdWx0aXBseV9tYXRyaXgoJm1hdCwmdmlld19tYXQsJndvcmxkX21hdCk7CiAgICBtdWx0aXBseV9tYXRyaXgoJm1hdCwmcHJval9tYXQsJm1hdCk7CgogICAgbnVtVGV4dHVyZXMgPSAoRGVzdEZWRiAmIFdJTkVEM0RGVkZfVEVYQ09VTlRfTUFTSykgPj4gV0lORUQzREZWRl9URVhDT1VOVF9TSElGVDsKCiAgICBmb3IgKGkgPSAwOyBpIDwgZHdDb3VudDsgaSs9IDEpIHsKICAgICAgICB1bnNpZ25lZCBpbnQgdGV4X2luZGV4OwoKICAgICAgICBpZiAoICgoRGVzdEZWRiAmIFdJTkVEM0RGVkZfUE9TSVRJT05fTUFTSykgPT0gV0lORUQzREZWRl9YWVogKSB8fAogICAgICAgICAgICAgKChEZXN0RlZGICYgV0lORUQzREZWRl9QT1NJVElPTl9NQVNLKSA9PSBXSU5FRDNERlZGX1hZWlJIVyApICkgewogICAgICAgICAgICAvKiBUaGUgcG9zaXRpb24gZmlyc3QgKi8KICAgICAgICAgICAgZmxvYXQgKnAgPQogICAgICAgICAgICAgIChmbG9hdCAqKSAoKChjaGFyICopIGxwU3RyaWRlRGF0YS0+dS5zLnBvc2l0aW9uLmxwRGF0YSkgKyBpICogbHBTdHJpZGVEYXRhLT51LnMucG9zaXRpb24uZHdTdHJpZGUpOwogICAgICAgICAgICBmbG9hdCB4LCB5LCB6LCByaHc7CiAgICAgICAgICAgIFRSQUNFKCJJbjogKCAlMDYuMmYgJTA2LjJmICUwNi4yZiApXG4iLCBwWzBdLCBwWzFdLCBwWzJdKTsKCiAgICAgICAgICAgIC8qIE11bHRpcGxpY2F0aW9uIHdpdGggd29ybGQsIHZpZXcgYW5kIHByb2plY3Rpb24gbWF0cml4ICovCiAgICAgICAgICAgIHggPSAgIChwWzBdICogbWF0LnUucy5fMTEpICsgKHBbMV0gKiBtYXQudS5zLl8yMSkgKyAocFsyXSAqIG1hdC51LnMuXzMxKSArICgxLjAgKiBtYXQudS5zLl80MSk7CiAgICAgICAgICAgIHkgPSAgIChwWzBdICogbWF0LnUucy5fMTIpICsgKHBbMV0gKiBtYXQudS5zLl8yMikgKyAocFsyXSAqIG1hdC51LnMuXzMyKSArICgxLjAgKiBtYXQudS5zLl80Mik7CiAgICAgICAgICAgIHogPSAgIChwWzBdICogbWF0LnUucy5fMTMpICsgKHBbMV0gKiBtYXQudS5zLl8yMykgKyAocFsyXSAqIG1hdC51LnMuXzMzKSArICgxLjAgKiBtYXQudS5zLl80Myk7CiAgICAgICAgICAgIHJodyA9IChwWzBdICogbWF0LnUucy5fMTQpICsgKHBbMV0gKiBtYXQudS5zLl8yNCkgKyAocFsyXSAqIG1hdC51LnMuXzM0KSArICgxLjAgKiBtYXQudS5zLl80NCk7CgogICAgICAgICAgICBUUkFDRSgieD0lZiB5PSVmIHo9JWYgcmh3PSVmXG4iLCB4LCB5LCB6LCByaHcpOwoKICAgICAgICAgICAgLyogV0FSTklORzogVGhlIGZvbGxvd2luZyB0aGluZ3MgYXJlIHRha2VuIGZyb20gZDNkNyBhbmQgd2VyZSBub3QgeWV0IGNoZWNrZWQKICAgICAgICAgICAgICogYWdhaW5zdCBkM2Q4IG9yIGQzZDkhCiAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgLyogQ2xpcHBpbmcgY29uZGl0aW9uczogRnJvbSBtc2RuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEEgdmVydGV4IGlzIGNsaXBwZWQgaWYgaXQgZG9lcyBub3QgbWF0Y2ggdGhlIGZvbGxvd2luZyByZXF1aXJlbWVudHMKICAgICAgICAgICAgICogLXJodyA8IHggPD0gcmh3CiAgICAgICAgICAgICAqIC1yaHcgPCB5IDw9IHJodwogICAgICAgICAgICAgKiAgICAwIDwgeiA8PSByaHcKICAgICAgICAgICAgICogICAgMCA8IHJodyAoIE5vdCBpbiBkM2Q3LCBidXQgdGVzdGVkIGluIGQzZDcpCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIElmIGNsaXBwaW5nIGlzIG9uIGlzIGRldGVybWluZWQgYnkgdGhlIEQzRFZPUF9DTElQIGZsYWcgaW4gRDNENywgYW5kCiAgICAgICAgICAgICAqIGJ5IHRoZSBEM0RSU19DTElQUElORyBpbiBEM0Q5KGFjY29yZGluZyB0byB0aGUgbXNkbiwgbm90IGNoZWNrZWQpCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgaWYoICFkb0NsaXAgfHwKICAgICAgICAgICAgICAgICggKC1yaHcgLWVwcyA8IHgpICYmICgtcmh3IC1lcHMgPCB5KSAmJiAoIC1lcHMgPCB6KSAmJgogICAgICAgICAgICAgICAgICAoeCA8PSByaHcgKyBlcHMpICYmICh5IDw9IHJodyArIGVwcyApICYmICh6IDw9IHJodyArIGVwcykgJiYgCiAgICAgICAgICAgICAgICAgICggcmh3ID4gZXBzICkgKSApIHsKCiAgICAgICAgICAgICAgICAvKiAiTm9ybWFsIiB2aWV3cG9ydCB0cmFuc2Zvcm1hdGlvbiAobm90IGNsaXBwZWQpCiAgICAgICAgICAgICAgICAgKiAxKSBUaGUgdmFsdWVzIGFyZSBkaXZpZGVkIGJ5IHJodwogICAgICAgICAgICAgICAgICogMikgVGhlIHkgYXhpcyBpcyBuZWdhdGl2ZSwgc28gbXVsdGlwbHkgaXQgd2l0aCAtMQogICAgICAgICAgICAgICAgICogMykgU2NyZWVuIGNvb3JkaW5hdGVzIGdvIGZyb20gLShXaWR0aC8yKSB0byArKFdpZHRoLzIpIGFuZAogICAgICAgICAgICAgICAgICogICAgLShIZWlnaHQvMikgdG8gKyhIZWlnaHQvMikuIFRoZSB6IHJhbmdlIGlzIE1pblogdG8gTWF4WgogICAgICAgICAgICAgICAgICogNCkgTXVsdGlwbHkgeCB3aXRoIFdpZHRoLzIgYW5kIGFkZCBXaWR0aC8yCiAgICAgICAgICAgICAgICAgKiA1KSBUaGUgc2FtZSBmb3IgdGhlIGhlaWdodAogICAgICAgICAgICAgICAgICogNikgQWRkIHRoZSB2aWV3cG9pbnQgWCBhbmQgWSB0byB0aGUgMkQgY29vcmRpbmF0ZXMgYW5kCiAgICAgICAgICAgICAgICAgKiAgICBUaGUgbWluaW11bSBaIHZhbHVlIHRvIHoKICAgICAgICAgICAgICAgICAqIDcpIHJodyA9IDEgLyByaHcgUmVjaXByb2NhbCBvZiBIb21vZ2VuZW91cyBXLi4uLgogICAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgICAqIFdlbGwsIGJhc2ljYWxseSBpdCdzIHNpbXBseSBhIGxpbmVhciB0cmFuc2Zvcm1hdGlvbiBpbnRvIHZpZXdwb3J0CiAgICAgICAgICAgICAgICAgKiBjb29yZGluYXRlcwogICAgICAgICAgICAgICAgICovCgogICAgICAgICAgICAgICAgeCAvPSByaHc7CiAgICAgICAgICAgICAgICB5IC89IHJodzsKICAgICAgICAgICAgICAgIHogLz0gcmh3OwoKICAgICAgICAgICAgICAgIHkgKj0gLTE7CgogICAgICAgICAgICAgICAgeCAqPSB2cC5XaWR0aCAvIDI7CiAgICAgICAgICAgICAgICB5ICo9IHZwLkhlaWdodCAvIDI7CiAgICAgICAgICAgICAgICB6ICo9IHZwLk1heFogLSB2cC5NaW5aOwoKICAgICAgICAgICAgICAgIHggKz0gdnAuV2lkdGggLyAyICsgdnAuWDsKICAgICAgICAgICAgICAgIHkgKz0gdnAuSGVpZ2h0IC8gMiArIHZwLlk7CiAgICAgICAgICAgICAgICB6ICs9IHZwLk1pblo7CgogICAgICAgICAgICAgICAgcmh3ID0gMSAvIHJodzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8qIFRoYXQgdmVydGV4IGdvdCBjbGlwcGVkCiAgICAgICAgICAgICAgICAgKiBDb250cmFyeSB0byBPcGVuR0wgaXQgaXMgbm90IGRyb3BwZWQgY29tcGxldGVseSwgaXQganVzdAogICAgICAgICAgICAgICAgICogdW5kZXJnb2VzIGEgZGlmZmVyZW50IGNhbGN1bGF0aW9uLgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBUUkFDRSgiVmVydGV4IGdvdCBjbGlwcGVkXG4iKTsKICAgICAgICAgICAgICAgIHggKz0gcmh3OwogICAgICAgICAgICAgICAgeSArPSByaHc7CgogICAgICAgICAgICAgICAgeCAgLz0gMjsKICAgICAgICAgICAgICAgIHkgIC89IDI7CgogICAgICAgICAgICAgICAgLyogTXNkbiBtZW50aW9ucyB0aGF0IERpcmVjdDNEOSBrZWVwcyBhIGxpc3Qgb2YgY2xpcHBlZCB2ZXJ0aWNlcwogICAgICAgICAgICAgICAgICogb3V0c2lkZSBvZiB0aGUgbWFpbiB2ZXJ0ZXggYnVmZmVyIG1lbW9yeS4gVGhhdCBuZWVkcyBzb21lIG1vcmUKICAgICAgICAgICAgICAgICAqIGludmVzdGlnYXRpb24uLi4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICB9CgogICAgICAgICAgICBUUkFDRSgiV3JpdGluZyAoJWYgJWYgJWYpICVmXG4iLCB4LCB5LCB6LCByaHcpOwoKCiAgICAgICAgICAgICggKGZsb2F0ICopIGRlc3RfcHRyKVswXSA9IHg7CiAgICAgICAgICAgICggKGZsb2F0ICopIGRlc3RfcHRyKVsxXSA9IHk7CiAgICAgICAgICAgICggKGZsb2F0ICopIGRlc3RfcHRyKVsyXSA9IHo7CiAgICAgICAgICAgICggKGZsb2F0ICopIGRlc3RfcHRyKVszXSA9IHJodzsgLyogU0lDLCBzZWUgZGRyYXcgdGVzdCEgKi8KCiAgICAgICAgICAgIGRlc3RfcHRyICs9IDMgKiBzaXplb2YoZmxvYXQpOwoKICAgICAgICAgICAgaWYoKERlc3RGVkYgJiBXSU5FRDNERlZGX1BPU0lUSU9OX01BU0spID09IFdJTkVEM0RGVkZfWFlaUkhXKSB7CiAgICAgICAgICAgICAgICBkZXN0X3B0ciArPSBzaXplb2YoZmxvYXQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZihkZXN0X2NvbnYpIHsKICAgICAgICAgICAgICAgIGZsb2F0IHcgPSAxIC8gcmh3OwogICAgICAgICAgICAgICAgKCAoZmxvYXQgKikgZGVzdF9jb252KVswXSA9IHggKiB3OwogICAgICAgICAgICAgICAgKCAoZmxvYXQgKikgZGVzdF9jb252KVsxXSA9IHkgKiB3OwogICAgICAgICAgICAgICAgKCAoZmxvYXQgKikgZGVzdF9jb252KVsyXSA9IHogKiB3OwogICAgICAgICAgICAgICAgKCAoZmxvYXQgKikgZGVzdF9jb252KVszXSA9IHc7CgogICAgICAgICAgICAgICAgZGVzdF9jb252ICs9IDMgKiBzaXplb2YoZmxvYXQpOwoKICAgICAgICAgICAgICAgIGlmKChEZXN0RlZGICYgV0lORUQzREZWRl9QT1NJVElPTl9NQVNLKSA9PSBXSU5FRDNERlZGX1hZWlJIVykgewogICAgICAgICAgICAgICAgICAgIGRlc3RfY29udiArPSBzaXplb2YoZmxvYXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChEZXN0RlZGICYgV0lORUQzREZWRl9QU0laRSkgewogICAgICAgICAgICBkZXN0X3B0ciArPSBzaXplb2YoRFdPUkQpOwogICAgICAgICAgICBpZihkZXN0X2NvbnYpIGRlc3RfY29udiArPSBzaXplb2YoRFdPUkQpOwogICAgICAgIH0KICAgICAgICBpZiAoRGVzdEZWRiAmIFdJTkVEM0RGVkZfTk9STUFMKSB7CiAgICAgICAgICAgIGZsb2F0ICpub3JtYWwgPQogICAgICAgICAgICAgIChmbG9hdCAqKSAoKChmbG9hdCAqKSBscFN0cmlkZURhdGEtPnUucy5ub3JtYWwubHBEYXRhKSArIGkgKiBscFN0cmlkZURhdGEtPnUucy5ub3JtYWwuZHdTdHJpZGUpOwogICAgICAgICAgICAvKiBBRkFJSyB0aGlzIHNob3VsZCBnbyBpbnRvIHRoZSBsaWdodGluZyBpbmZvcm1hdGlvbiAqLwogICAgICAgICAgICBGSVhNRSgiRGlkbid0IGV4cGVjdCB0aGUgZGVzdGluYXRpb24gdG8gaGF2ZSBhIG5vcm1hbFxuIik7CiAgICAgICAgICAgIGNvcHlfYW5kX25leHQoZGVzdF9wdHIsIG5vcm1hbCwgMyAqIHNpemVvZihmbG9hdCkpOwogICAgICAgICAgICBpZihkZXN0X2NvbnYpIHsKICAgICAgICAgICAgICAgIGNvcHlfYW5kX25leHQoZGVzdF9jb252LCBub3JtYWwsIDMgKiBzaXplb2YoZmxvYXQpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKERlc3RGVkYgJiBXSU5FRDNERlZGX0RJRkZVU0UpIHsKICAgICAgICAgICAgRFdPUkQgKmNvbG9yX2QgPSAKICAgICAgICAgICAgICAoRFdPUkQgKikgKCgoY2hhciAqKSBscFN0cmlkZURhdGEtPnUucy5kaWZmdXNlLmxwRGF0YSkgKyBpICogbHBTdHJpZGVEYXRhLT51LnMuZGlmZnVzZS5kd1N0cmlkZSk7CiAgICAgICAgICAgIGlmKCFjb2xvcl9kKSB7CiAgICAgICAgICAgICAgICBzdGF0aWMgQk9PTCB3YXJuZWQgPSBGQUxTRTsKCiAgICAgICAgICAgICAgICBpZighd2FybmVkKSB7CiAgICAgICAgICAgICAgICAgICAgRVJSKCJObyBkaWZmdXNlIGNvbG9yIGluIHNvdXJjZSwgYnV0IGRlc3RpbmF0aW9uIGhhcyBvbmVcbiIpOwogICAgICAgICAgICAgICAgICAgIHdhcm5lZCA9IFRSVUU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgKiggKERXT1JEICopIGRlc3RfcHRyKSA9IDB4ZmZmZmZmZmY7CiAgICAgICAgICAgICAgICBkZXN0X3B0ciArPSBzaXplb2YoRFdPUkQpOwoKICAgICAgICAgICAgICAgIGlmKGRlc3RfY29udikgewogICAgICAgICAgICAgICAgICAgICooIChEV09SRCAqKSBkZXN0X2NvbnYpID0gMHhmZmZmZmZmZjsKICAgICAgICAgICAgICAgICAgICBkZXN0X2NvbnYgKz0gc2l6ZW9mKERXT1JEKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIGNvcHlfYW5kX25leHQoZGVzdF9wdHIsIGNvbG9yX2QsIHNpemVvZihEV09SRCkpOwogICAgICAgICAgICAgICAgaWYoZGVzdF9jb252KSB7CiAgICAgICAgICAgICAgICAgICAgKiggKERXT1JEICopIGRlc3RfY29udikgID0gKCpjb2xvcl9kICYgMHhmZjAwZmYwMCkgICAgICA7IC8qIEFscGhhICsgZ3JlZW4gKi8KICAgICAgICAgICAgICAgICAgICAqKCAoRFdPUkQgKikgZGVzdF9jb252KSB8PSAoKmNvbG9yX2QgJiAweDAwZmYwMDAwKSA+PiAxNjsgLyogUmVkICovCiAgICAgICAgICAgICAgICAgICAgKiggKERXT1JEICopIGRlc3RfY29udikgfD0gKCpjb2xvcl9kICYgMHhmZjAwMDBmZikgPDwgMTY7IC8qIEJsdWUgKi8KICAgICAgICAgICAgICAgICAgICBkZXN0X2NvbnYgKz0gc2l6ZW9mKERXT1JEKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKERlc3RGVkYgJiBXSU5FRDNERlZGX1NQRUNVTEFSKSB7IAogICAgICAgICAgICAvKiBXaGF0J3MgdGhlIGNvbG9yIHZhbHVlIGluIHRoZSBmZWVkYmFjayBidWZmZXI/ICovCiAgICAgICAgICAgIERXT1JEICpjb2xvcl9zID0gCiAgICAgICAgICAgICAgKERXT1JEICopICgoKGNoYXIgKikgbHBTdHJpZGVEYXRhLT51LnMuc3BlY3VsYXIubHBEYXRhKSArIGkgKiBscFN0cmlkZURhdGEtPnUucy5zcGVjdWxhci5kd1N0cmlkZSk7CiAgICAgICAgICAgIGlmKCFjb2xvcl9zKSB7CiAgICAgICAgICAgICAgICBzdGF0aWMgQk9PTCB3YXJuZWQgPSBGQUxTRTsKCiAgICAgICAgICAgICAgICBpZighd2FybmVkKSB7CiAgICAgICAgICAgICAgICAgICAgRVJSKCJObyBzcGVjdWxhciBjb2xvciBpbiBzb3VyY2UsIGJ1dCBkZXN0aW5hdGlvbiBoYXMgb25lXG4iKTsKICAgICAgICAgICAgICAgICAgICB3YXJuZWQgPSBUUlVFOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICooIChEV09SRCAqKSBkZXN0X3B0cikgPSAweEZGMDAwMDAwOwogICAgICAgICAgICAgICAgZGVzdF9wdHIgKz0gc2l6ZW9mKERXT1JEKTsKCiAgICAgICAgICAgICAgICBpZihkZXN0X2NvbnYpIHsKICAgICAgICAgICAgICAgICAgICAqKCAoRFdPUkQgKikgZGVzdF9jb252KSA9IDB4RkYwMDAwMDA7CiAgICAgICAgICAgICAgICAgICAgZGVzdF9jb252ICs9IHNpemVvZihEV09SRCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBjb3B5X2FuZF9uZXh0KGRlc3RfcHRyLCBjb2xvcl9zLCBzaXplb2YoRFdPUkQpKTsKICAgICAgICAgICAgICAgIGlmKGRlc3RfY29udikgewogICAgICAgICAgICAgICAgICAgICooIChEV09SRCAqKSBkZXN0X2NvbnYpICA9ICgqY29sb3JfcyAmIDB4ZmYwMGZmMDApICAgICAgOyAvKiBBbHBoYSArIGdyZWVuICovCiAgICAgICAgICAgICAgICAgICAgKiggKERXT1JEICopIGRlc3RfY29udikgfD0gKCpjb2xvcl9zICYgMHgwMGZmMDAwMCkgPj4gMTY7IC8qIFJlZCAqLwogICAgICAgICAgICAgICAgICAgICooIChEV09SRCAqKSBkZXN0X2NvbnYpIHw9ICgqY29sb3JfcyAmIDB4ZmYwMDAwZmYpIDw8IDE2OyAvKiBCbHVlICovCiAgICAgICAgICAgICAgICAgICAgZGVzdF9jb252ICs9IHNpemVvZihEV09SRCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvciAodGV4X2luZGV4ID0gMDsgdGV4X2luZGV4IDwgbnVtVGV4dHVyZXM7IHRleF9pbmRleCsrKSB7CiAgICAgICAgICAgIGZsb2F0ICp0ZXhfY29vcmQgPQogICAgICAgICAgICAgIChmbG9hdCAqKSAoKChjaGFyICopIGxwU3RyaWRlRGF0YS0+dS5zLnRleENvb3Jkc1t0ZXhfaW5kZXhdLmxwRGF0YSkgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgKiBscFN0cmlkZURhdGEtPnUucy50ZXhDb29yZHNbdGV4X2luZGV4XS5kd1N0cmlkZSk7CiAgICAgICAgICAgIGlmKCF0ZXhfY29vcmQpIHsKICAgICAgICAgICAgICAgIEVSUigiTm8gc291cmNlIHRleHR1cmUsIGJ1dCBkZXN0aW5hdGlvbiByZXF1ZXN0cyBvbmVcbiIpOwogICAgICAgICAgICAgICAgZGVzdF9wdHIrPUdFVF9URVhDT09SRF9TSVpFX0ZST01fRlZGKERlc3RGVkYsIHRleF9pbmRleCkgKiBzaXplb2YoZmxvYXQpOwogICAgICAgICAgICAgICAgaWYoZGVzdF9jb252KSBkZXN0X2NvbnYgKz0gR0VUX1RFWENPT1JEX1NJWkVfRlJPTV9GVkYoRGVzdEZWRiwgdGV4X2luZGV4KSAqIHNpemVvZihmbG9hdCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBjb3B5X2FuZF9uZXh0KGRlc3RfcHRyLCB0ZXhfY29vcmQsIEdFVF9URVhDT09SRF9TSVpFX0ZST01fRlZGKERlc3RGVkYsIHRleF9pbmRleCkgKiBzaXplb2YoZmxvYXQpKTsKICAgICAgICAgICAgICAgIGlmKGRlc3RfY29udikgewogICAgICAgICAgICAgICAgICAgIGNvcHlfYW5kX25leHQoZGVzdF9jb252LCB0ZXhfY29vcmQsIEdFVF9URVhDT09SRF9TSVpFX0ZST01fRlZGKERlc3RGVkYsIHRleF9pbmRleCkgKiBzaXplb2YoZmxvYXQpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBpZihkZXN0X2NvbnYpIHsKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9BUlJBWV9CVUZGRVJfQVJCLCBkZXN0LT52Ym8pKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kQnVmZmVyQVJCKEdMX0FSUkFZX0JVRkZFUl9BUkIpIik7CiAgICAgICAgR0xfRVhUQ0FMTChnbEJ1ZmZlclN1YkRhdGFBUkIoR0xfQVJSQVlfQlVGRkVSX0FSQiwgZHdEZXN0SW5kZXggKiBnZXRfZmxleGlibGVfdmVydGV4X3NpemUoRGVzdEZWRiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHdDb3VudCAqIGdldF9mbGV4aWJsZV92ZXJ0ZXhfc2l6ZShEZXN0RlZGKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXN0X2NvbnZfYWRkcikpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJ1ZmZlclN1YkRhdGFBUkIoR0xfQVJSQVlfQlVGRkVSX0FSQikiKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkZXN0X2NvbnZfYWRkcik7CiAgICB9CgogICAgTEVBVkVfR0woKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQojdW5kZWYgY29weV9hbmRfbmV4dAoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9Qcm9jZXNzVmVydGljZXMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIFNyY1N0YXJ0SW5kZXgsIFVJTlQgRGVzdEluZGV4LCBVSU5UIFZlcnRleENvdW50LCBJV2luZUQzRFZlcnRleEJ1ZmZlciogcERlc3RCdWZmZXIsIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb24qIHBWZXJ0ZXhEZWNsLCBEV09SRCBGbGFncykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgV2luZURpcmVjdDNEVmVydGV4U3RyaWRlZERhdGEgc3RyaWRlZDsKICAgIEJPT0wgdmJvID0gRkFMU0UsIHN0cmVhbVdhc1VQID0gVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtSXNVUDsKICAgIFRSQUNFKCIoJXApLT4oJWQsJWQsJWQsJXAsJXAsJWRcbiIsIFRoaXMsIFNyY1N0YXJ0SW5kZXgsIERlc3RJbmRleCwgVmVydGV4Q291bnQsIHBEZXN0QnVmZmVyLCBwVmVydGV4RGVjbCwgRmxhZ3MpOwoKICAgIGlmKHBWZXJ0ZXhEZWNsKSB7CiAgICAgICAgRVJSKCJPdXRwdXQgdmVydGV4IGRlY2xhcmF0aW9uIG5vdCBpbXBsZW1lbnRlZCB5ZXRcbiIpOwogICAgfQoKICAgIC8qIE5lZWQgYW55IGNvbnRleHQgdG8gd3JpdGUgdG8gdGhlIHZiby4gKi8KICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0LCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwoKICAgIC8qIFByb2Nlc3NWZXJ0aWNlcyByZWFkcyBmcm9tIHZlcnRleCBidWZmZXJzLCB3aGljaCBoYXZlIHRvIGJlIGFzc2lnbmVkLiBEcmF3UHJpbWl0aXZlIGFuZCBEcmF3UHJpbWl0aXZlVVAKICAgICAqIGNvbnRyb2wgdGhlIHN0cmVhbUlzVVAgZmxhZywgdGh1cyByZXN0b3JlIGl0IGFmdGVyd2FyZHMuCiAgICAgKi8KICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbUlzVVAgPSBGQUxTRTsKICAgIG1lbXNldCgmc3RyaWRlZCwgMCwgc2l6ZW9mKHN0cmlkZWQpKTsKICAgIHByaW1pdGl2ZURlY2xhcmF0aW9uQ29udmVydFRvU3RyaWRlZERhdGEoaWZhY2UsIEZBTFNFLCAmc3RyaWRlZCwgJnZibyk7CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Jc1VQID0gc3RyZWFtV2FzVVA7CgogICAgaWYodmJvIHx8IFNyY1N0YXJ0SW5kZXgpIHsKICAgICAgICB1bnNpZ25lZCBpbnQgaTsKICAgICAgICAvKiBQcm9jZXNzVmVydGljZXMgY2FuJ3QgY29udmVydCBGUk9NIGEgdmJvLCBhbmQgdmVydGV4IGJ1ZmZlcnMgdXNlZCB0byBzb3VyY2UgaW50byBQcm9jZXNzVmVydGljZXMgYXJlCiAgICAgICAgICogdW5saWtlbHkgdG8gZXZlciBiZSB1c2VkIGZvciBkcmF3aW5nLiBSZWxlYXNlIHZib3MgaW4gdGhvc2UgYnVmZmVycyBhbmQgZml4IHVwIHRoZSBzdHJpZGVkIHN0cnVjdHVyZQogICAgICAgICAqCiAgICAgICAgICogQWxzbyBnZXQgdGhlIHN0YXJ0IGluZGV4IGluLCBidXQgb25seSBsb29wIG92ZXIgYWxsIGVsZW1lbnRzIGlmIHRoZXJlJ3Mgc29tZXRoaW5nIHRvIGFkZCBhdCBhbGwuCiAgICAgICAgICovCiNkZWZpbmUgRklYU1JDKHR5cGUpIFwKICAgICAgICBpZihzdHJpZGVkLnUucy50eXBlLlZCTykgeyBcCiAgICAgICAgICAgIElXaW5lRDNEVmVydGV4QnVmZmVySW1wbCAqdmIgPSAoSVdpbmVEM0RWZXJ0ZXhCdWZmZXJJbXBsICopIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtzdHJpZGVkLnUucy50eXBlLnN0cmVhbU5vXTsgXAogICAgICAgICAgICBzdHJpZGVkLnUucy50eXBlLlZCTyA9IDA7IFwKICAgICAgICAgICAgc3RyaWRlZC51LnMudHlwZS5scERhdGEgPSAoQllURSAqKSAoKHVuc2lnbmVkIGxvbmcpIHN0cmlkZWQudS5zLnR5cGUubHBEYXRhICsgKHVuc2lnbmVkIGxvbmcpIHZiLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOyBcCiAgICAgICAgICAgIEVOVEVSX0dMKCk7IFwKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbERlbGV0ZUJ1ZmZlcnNBUkIoMSwgJnZiLT52Ym8pKTsgXAogICAgICAgICAgICB2Yi0+dmJvID0gMDsgXAogICAgICAgICAgICBMRUFWRV9HTCgpOyBcCiAgICAgICAgfSBcCiAgICAgICAgaWYoc3RyaWRlZC51LnMudHlwZS5scERhdGEpIHsgXAogICAgICAgICAgICBzdHJpZGVkLnUucy50eXBlLmxwRGF0YSArPSBzdHJpZGVkLnUucy50eXBlLmR3U3RyaWRlICogU3JjU3RhcnRJbmRleDsgXAogICAgICAgIH0KICAgICAgICBGSVhTUkMocG9zaXRpb24pOwogICAgICAgIEZJWFNSQyhibGVuZFdlaWdodHMpOwogICAgICAgIEZJWFNSQyhibGVuZE1hdHJpeEluZGljZXMpOwogICAgICAgIEZJWFNSQyhub3JtYWwpOwogICAgICAgIEZJWFNSQyhwU2l6ZSk7CiAgICAgICAgRklYU1JDKGRpZmZ1c2UpOwogICAgICAgIEZJWFNSQyhzcGVjdWxhcik7CiAgICAgICAgZm9yKGkgPSAwOyBpIDwgV0lORUQzRERQX01BWFRFWENPT1JEOyBpKyspIHsKICAgICAgICAgICAgRklYU1JDKHRleENvb3Jkc1tpXSk7CiAgICAgICAgfQogICAgICAgIEZJWFNSQyhwb3NpdGlvbjIpOwogICAgICAgIEZJWFNSQyhub3JtYWwyKTsKICAgICAgICBGSVhTUkModGFuZ2VudCk7CiAgICAgICAgRklYU1JDKGJpbm9ybWFsKTsKICAgICAgICBGSVhTUkModGVzc0ZhY3Rvcik7CiAgICAgICAgRklYU1JDKGZvZyk7CiAgICAgICAgRklYU1JDKGRlcHRoKTsKICAgICAgICBGSVhTUkMoc2FtcGxlKTsKI3VuZGVmIEZJWFNSQwogICAgfQoKICAgIHJldHVybiBwcm9jZXNzX3ZlcnRpY2VzX3N0cmlkZWQoVGhpcywgRGVzdEluZGV4LCBWZXJ0ZXhDb3VudCwgJnN0cmlkZWQsIChJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKikgcERlc3RCdWZmZXIsIEZsYWdzKTsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBUZXh0dXJlIFN0YWdlIFN0YXRlcwogKiBUT0RPOiBWZXJpZnkgYWdhaW5zdCBkeDkgZGVmaW5pdGlvbnMKICoqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFRleHR1cmVTdGFnZVN0YXRlKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgU3RhZ2UsIFdJTkVEM0RURVhUVVJFU1RBR0VTVEFURVRZUEUgVHlwZSwgRFdPUkQgVmFsdWUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIERXT1JEIG9sZFZhbHVlID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlW1N0YWdlXVtUeXBlXTsKCiAgICBUUkFDRSgiKCVwKSA6IFN0YWdlPSVkLCBUeXBlPSVzKCVkKSwgVmFsdWU9JWRcbiIsIFRoaXMsIFN0YWdlLCBkZWJ1Z19kM2R0ZXh0dXJlc3RhdGUoVHlwZSksIFR5cGUsIFZhbHVlKTsKCiAgICBpZiAoU3RhZ2UgPj0gTUFYX1RFWFRVUkVTKSB7CiAgICAgICAgV0FSTigiQXR0ZW1wdGluZyB0byBzZXQgc3RhZ2UgJXUgd2hpY2ggaXMgaGlnaGVyIHRoYW4gdGhlIG1heCBzdGFnZSAldSwgaWdub3JpbmdcbiIsIFN0YWdlLCBNQVhfVEVYVFVSRVMgLSAxKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnRleHR1cmVTdGF0ZVtTdGFnZV1bVHlwZV0gPSBUUlVFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlW1N0YWdlXVtUeXBlXSAgICAgICAgID0gVmFsdWU7CgogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICAvKiBDaGVja2VkIGFmdGVyIHRoZSBhc3NpZ25tZW50cyB0byBhbGxvdyBwcm9wZXIgc3RhdGVibG9jayByZWNvcmRpbmcgKi8KICAgIGlmKG9sZFZhbHVlID09IFZhbHVlKSB7CiAgICAgICAgVFJBQ0UoIkFwcCBpcyBzZXR0aW5nIHRoZSBvbGQgdmFsdWUgb3Zlciwgbm90aGluZyB0byBkb1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgaWYoU3RhZ2UgPiBUaGlzLT5zdGF0ZUJsb2NrLT5sb3dlc3RfZGlzYWJsZWRfc3RhZ2UgJiYKICAgICAgIFRoaXMtPnNoYWRlcl9iYWNrZW5kLT5TdGF0ZVRhYmxlW1NUQVRFX1RFWFRVUkVTVEFHRSgwLCBUeXBlKV0ucmVwcmVzZW50YXRpdmUgPT0gU1RBVEVfVEVYVFVSRVNUQUdFKDAsIFdJTkVEM0RUU1NfQ09MT1JPUCkpIHsKICAgICAgICAvKiBDb2xvcm9wIGNoYW5nZSBhYm92ZSBsb3dlc3QgZGlzYWJsZWQgc3RhZ2U/IFRoYXQgd29uJ3QgY2hhbmdlIGFueXRoaW5nIGluIHRoZSBnbCBzZXR1cAogICAgICAgICAqIENoYW5nZXMgaW4gb3RoZXIgc3RhdGVzIGFyZSBpbXBvcnRhbnQgb24gZGlzYWJsZWQgc3RhZ2VzIHRvbwogICAgICAgICAqLwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIGlmKFR5cGUgPT0gV0lORUQzRFRTU19DT0xPUk9QKSB7CiAgICAgICAgaW50IGk7CgogICAgICAgIGlmKFZhbHVlID09IFdJTkVEM0RUT1BfRElTQUJMRSAmJiBvbGRWYWx1ZSAhPSBXSU5FRDNEVE9QX0RJU0FCTEUpIHsKICAgICAgICAgICAgLyogUHJldmlvdXNseSBlbmFibGVkIHN0YWdlIGRpc2FibGVkIG5vdy4gTWFrZSBzdXJlIHRvIGRpcnRpZnkgYWxsIGVuYWJsZWQgc3RhZ2VzIGFib3ZlIFN0YWdlLAogICAgICAgICAgICAgKiB0aGV5IGhhdmUgdG8gYmUgZGlzYWJsZWQKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogVGhlIGN1cnJlbnQgc3RhZ2UgaXMgZGlydGlmaWVkIGJlbG93LgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZm9yKGkgPSBTdGFnZSArIDE7IGkgPCBUaGlzLT5zdGF0ZUJsb2NrLT5sb3dlc3RfZGlzYWJsZWRfc3RhZ2U7IGkrKykgewogICAgICAgICAgICAgICAgVFJBQ0UoIkFkZGl0aW9uYWxseSBkaXJ0aWZ5aW5nIHN0YWdlICVkXG4iLCBpKTsKICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9URVhUVVJFU1RBR0UoaSwgV0lORUQzRFRTU19DT0xPUk9QKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+bG93ZXN0X2Rpc2FibGVkX3N0YWdlID0gU3RhZ2U7CiAgICAgICAgICAgIFRSQUNFKCJOZXcgbG93ZXN0IGRpc2FibGVkOiAlZFxuIiwgU3RhZ2UpOwogICAgICAgIH0gZWxzZSBpZihWYWx1ZSAhPSBXSU5FRDNEVE9QX0RJU0FCTEUgJiYgb2xkVmFsdWUgPT0gV0lORUQzRFRPUF9ESVNBQkxFKSB7CiAgICAgICAgICAgIC8qIFByZXZpb3VzbHkgZGlzYWJsZWQgc3RhZ2UgZW5hYmxlZC4gU3RhZ2VzIGFib3ZlIGl0IG1heSBuZWVkIGVuYWJsaW5nCiAgICAgICAgICAgICAqIHN0YWdlIG11c3QgYmUgbG93ZXN0X2Rpc2FibGVkX3N0YWdlIGhlcmUsIGlmIGl0J3MgYmlnZ2VyIHN1Y2Nlc3MgaXMgcmV0dXJuZWQgYWJvdmUsCiAgICAgICAgICAgICAqIGFuZCBzdGFnZXMgYmVsb3cgdGhlIGxvd2VzdCBkaXNhYmxlZCBzdGFnZSBjYW4ndCBiZSBlbmFibGVkKGJlY2F1c2UgdGhleSBhcmUgZW5hYmxlZCBhbHJlYWR5KS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQWdhaW4gc3RhZ2UgU3RhZ2UgZG9lc24ndCBuZWVkIHRvIGJlIGRpcnRpZmllZCBoZXJlLCBpdCBpcyBoYW5kbGVkIGJlbG93LgogICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIGZvcihpID0gU3RhZ2UgKyAxOyBpIDwgR0xfTElNSVRTKHRleHR1cmVfc3RhZ2VzKTsgaSsrKSB7CiAgICAgICAgICAgICAgICBpZihUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbaV1bV0lORUQzRFRTU19DT0xPUk9QXSA9PSBXSU5FRDNEVE9QX0RJU0FCTEUpIHsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIFRSQUNFKCJBZGRpdGlvbmFsbHkgZGlydGlmeWluZyBzdGFnZSAlZCBkdWUgdG8gZW5hYmxlXG4iLCBpKTsKICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9URVhUVVJFU1RBR0UoaSwgV0lORUQzRFRTU19DT0xPUk9QKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+bG93ZXN0X2Rpc2FibGVkX3N0YWdlID0gaTsKICAgICAgICAgICAgVFJBQ0UoIk5ldyBsb3dlc3QgZGlzYWJsZWQ6ICVkXG4iLCBpKTsKICAgICAgICB9CiAgICAgICAgaWYoR0xfU1VQUE9SVChOVl9SRUdJU1RFUl9DT01CSU5FUlMpICYmICFUaGlzLT5zdGF0ZUJsb2NrLT5waXhlbFNoYWRlcikgewogICAgICAgICAgICAvKiBUT0RPOiBCdWlsdCBhIHN0YWdlIC0+IHRleHR1cmUgdW5pdCBtYXBwaW5nIGZvciByZWdpc3RlciBjb21iaW5lcnMgKi8KICAgICAgICB9CiAgICB9CgogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1RFWFRVUkVTVEFHRShTdGFnZSwgVHlwZSkpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFRleHR1cmVTdGFnZVN0YXRlKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgU3RhZ2UsIFdJTkVEM0RURVhUVVJFU1RBR0VTVEFURVRZUEUgVHlwZSwgRFdPUkQqIHBWYWx1ZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiByZXF1ZXN0aW5nIFN0YWdlICVkLCBUeXBlICVkIGdldHRpbmcgJWRcbiIsIFRoaXMsIFN0YWdlLCBUeXBlLCBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbU3RhZ2VdW1R5cGVdKTsKICAgICpwVmFsdWUgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbU3RhZ2VdW1R5cGVdOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBHZXQgLyBTZXQgVGV4dHVyZQogKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0VGV4dHVyZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIFN0YWdlLCBJV2luZUQzREJhc2VUZXh0dXJlKiBwVGV4dHVyZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RCYXNlVGV4dHVyZSAqb2xkVGV4dHVyZTsKCiAgICBUUkFDRSgiKCVwKSA6IFN0YWdlICUjeCwgVGV4dHVyZSAlcFxuIiwgVGhpcywgU3RhZ2UsIHBUZXh0dXJlKTsKCiAgICBpZiAoU3RhZ2UgPj0gV0lORUQzRFZFUlRFWFRFWFRVUkVTQU1QTEVSMCAmJiBTdGFnZSA8PSBXSU5FRDNEVkVSVEVYVEVYVFVSRVNBTVBMRVIzKSB7CiAgICAgICAgU3RhZ2UgLT0gKFdJTkVEM0RWRVJURVhURVhUVVJFU0FNUExFUjAgLSBNQVhfRlJBR01FTlRfU0FNUExFUlMpOwogICAgfQoKICAgIGlmIChTdGFnZSA+PSBzaXplb2YoVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZXMpL3NpemVvZihUaGlzLT5zdGF0ZUJsb2NrLT50ZXh0dXJlc1swXSkpIHsKICAgICAgICBFUlIoIkN1cnJlbnQgc3RhZ2Ugb3ZlcmZsb3dzIHRleHR1cmVzIGFycmF5IChzdGFnZSAlZClcbiIsIFN0YWdlKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsgLyogV2luZG93cyBhY2NlcHRzIG92ZXJmbG93aW5nIHRoaXMgYXJyYXkgLi4uIHdlIGRvIG5vdC4gKi8KICAgIH0KCiAgICBvbGRUZXh0dXJlID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZXNbU3RhZ2VdOwoKICAgIGlmKHBUZXh0dXJlICE9IE5VTEwpIHsKICAgICAgICAvKiBTZXRUZXh0dXJlIGlzbid0IGFsbG93ZWQgb24gdGV4dHVyZXMgaW4gV0lORUQzRFBPT0xfU0NSQVRDSDsgCiAgICAgICAgICovCiAgICAgICAgaWYoKChJV2luZUQzRFRleHR1cmVJbXBsKilwVGV4dHVyZSktPnJlc291cmNlLnBvb2wgPT0gV0lORUQzRFBPT0xfU0NSQVRDSCkgewogICAgICAgICAgICBXQVJOKCIoJXApIEF0dGVtcHQgdG8gc2V0IHNjcmF0Y2ggdGV4dHVyZSByZWplY3RlZFxuIiwgcFRleHR1cmUpOwogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICB9CiAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZURpbWVuc2lvbnNbU3RhZ2VdID0gSVdpbmVEM0RCYXNlVGV4dHVyZV9HZXRUZXh0dXJlRGltZW5zaW9ucyhwVGV4dHVyZSk7CiAgICB9CgogICAgVFJBQ0UoIkdMX0xJTUlUUyAlZFxuIixHTF9MSU1JVFMoc2FtcGxlcl9zdGFnZXMpKTsKICAgIFRSQUNFKCIoJXApIDogb2xkdGV4dHVyZSglcClcbiIsIFRoaXMsb2xkVGV4dHVyZSk7CgogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC50ZXh0dXJlc1tTdGFnZV0gPSBUUlVFOwogICAgVFJBQ0UoIiglcCkgOiBzZXR0aW5nIG5ldyB0ZXh0dXJlIHRvICVwXG4iLCBUaGlzLCBwVGV4dHVyZSk7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlc1tTdGFnZV0gICAgICAgICA9IHBUZXh0dXJlOwoKICAgIC8qIEhhbmRsZSByZWNvcmRpbmcgb2Ygc3RhdGUgYmxvY2tzICovCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIGlmKG9sZFRleHR1cmUgPT0gcFRleHR1cmUpIHsKICAgICAgICBUUkFDRSgiQXBwIGlzIHNldHRpbmcgdGhlIHNhbWUgdGV4dHVyZSBhZ2Fpbiwgbm90aGluZyB0byBkb1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgLyoqIE5PVEU6IE1TRE4gc2F5cyB0aGF0IHNldFRleHR1cmUgaW5jcmVhc2VzIHRoZSByZWZlcmVuY2UgY291bnQsCiAgICAqIGFuZCB0aGF0IHRoZSBhcHBsaWNhdGlvbiBtdXN0IHNldCB0aGUgdGV4dHVyZSBiYWNrIHRvIG51bGwgKG9yIGhhdmUgYSBsZWFreSBhcHBsaWNhdGlvbiksCiAgICAqIFRoaXMgbWVhbnMgd2Ugc2hvdWxkIHBhc3MgdGhlIHJlZmNvdW50IHVwIHRvIHRoZSBwYXJlbnQKICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgaWYgKE5VTEwgIT0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZXNbU3RhZ2VdKSB7CiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKm5ldyA9IChJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqKSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlc1tTdGFnZV07CiAgICAgICAgVUxPTkcgYmluZENvdW50ID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJm5ldy0+YmFzZVRleHR1cmUuYmluZENvdW50KTsKCiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9BZGRSZWYoVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZXNbU3RhZ2VdKTsKICAgICAgICBpZihvbGRUZXh0dXJlID09IE5VTEwgJiYgU3RhZ2UgPCBNQVhfVEVYVFVSRVMpIHsKICAgICAgICAgICAgLyogVGhlIHNvdXJjZSBhcmd1bWVudHMgZm9yIGNvbG9yIGFuZCBhbHBoYSBvcHMgaGF2ZSBkaWZmZXJlbnQgbWVhbmluZ3Mgd2hlbiBhIE5VTEwgdGV4dHVyZSBpcyBib3VuZCwKICAgICAgICAgICAgICogc28gdGhlIENPTE9ST1AgYW5kIEFMUEhBT1AgaGF2ZSB0byBiZSBkaXJ0aWZpZWQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVEVYVFVSRVNUQUdFKFN0YWdlLCBXSU5FRDNEVFNTX0NPTE9ST1ApKTsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1RFWFRVUkVTVEFHRShTdGFnZSwgV0lORUQzRFRTU19BTFBIQU9QKSk7CiAgICAgICAgfQogICAgICAgIGlmKGJpbmRDb3VudCA9PSAxKSB7CiAgICAgICAgICAgIG5ldy0+YmFzZVRleHR1cmUuc2FtcGxlciA9IFN0YWdlOwogICAgICAgIH0KICAgICAgICAvKiBNb3JlIHRoYW4gb25lIGFzc2lnbm1lbnQ/IERvZXNuJ3QgbWF0dGVyLCB3ZSBvbmx5IG5lZWQgb25lIGdsIHRleHR1cmUgdW5pdCB0byB1c2UgZm9yIHVwbG9hZGluZyAqLwoKICAgIH0KCiAgICBpZiAoTlVMTCAhPSBvbGRUZXh0dXJlKSB7CiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKm9sZCA9IChJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqKSBvbGRUZXh0dXJlOwogICAgICAgIExPTkcgYmluZENvdW50ID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJm9sZC0+YmFzZVRleHR1cmUuYmluZENvdW50KTsKCiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9SZWxlYXNlKG9sZFRleHR1cmUpOwogICAgICAgIGlmKHBUZXh0dXJlID09IE5VTEwgJiYgU3RhZ2UgPCBNQVhfVEVYVFVSRVMpIHsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1RFWFRVUkVTVEFHRShTdGFnZSwgV0lORUQzRFRTU19DT0xPUk9QKSk7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9URVhUVVJFU1RBR0UoU3RhZ2UsIFdJTkVEM0RUU1NfQUxQSEFPUCkpOwogICAgICAgIH0KCiAgICAgICAgaWYoYmluZENvdW50ICYmIG9sZC0+YmFzZVRleHR1cmUuc2FtcGxlciA9PSBTdGFnZSkgewogICAgICAgICAgICBpbnQgaTsKICAgICAgICAgICAgLyogSGF2ZSB0byBkbyBhIHNlYXJjaCBmb3IgdGhlIG90aGVyIHNhbXBsZXIocykgd2hlcmUgdGhlIHRleHR1cmUgaXMgYm91bmQgdG8KICAgICAgICAgICAgICogU2hvdWxkbid0IGhhcHBlbiBhcyBsb25nIGFzIGFwcHMgYmluZCBhIHRleHR1cmUgb25seSB0byBvbmUgc3RhZ2UKICAgICAgICAgICAgICovCiAgICAgICAgICAgIFRSQUNFKCJTZWFyY2luZyBmb3Igb3RoZXIgc2FtcGxlciAvIHN0YWdlIGlkIHdoZXJlIHRoZSB0ZXh0dXJlIGlzIGJvdW5kIHRvXG4iKTsKICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDwgTUFYX0NPTUJJTkVEX1NBTVBMRVJTOyBpKyspIHsKICAgICAgICAgICAgICAgIGlmKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRleHR1cmVzW2ldID09IG9sZFRleHR1cmUpIHsKICAgICAgICAgICAgICAgICAgICBvbGQtPmJhc2VUZXh0dXJlLnNhbXBsZXIgPSBpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TQU1QTEVSKFN0YWdlKSk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0VGV4dHVyZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIFN0YWdlLCBJV2luZUQzREJhc2VUZXh0dXJlKiogcHBUZXh0dXJlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCkgOiBTdGFnZSAlI3gsIHBwVGV4dHVyZSAlcFxuIiwgVGhpcywgU3RhZ2UsIHBwVGV4dHVyZSk7CgogICAgaWYgKFN0YWdlID49IFdJTkVEM0RWRVJURVhURVhUVVJFU0FNUExFUjAgJiYgU3RhZ2UgPD0gV0lORUQzRFZFUlRFWFRFWFRVUkVTQU1QTEVSMykgewogICAgICAgIFN0YWdlIC09IChXSU5FRDNEVkVSVEVYVEVYVFVSRVNBTVBMRVIwIC0gTUFYX0ZSQUdNRU5UX1NBTVBMRVJTKTsKICAgIH0KCiAgICBpZiAoU3RhZ2UgPj0gc2l6ZW9mKFRoaXMtPnN0YXRlQmxvY2stPnRleHR1cmVzKS9zaXplb2YoVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZXNbMF0pKSB7CiAgICAgICAgRVJSKCJDdXJyZW50IHN0YWdlIG92ZXJmbG93cyB0ZXh0dXJlcyBhcnJheSAoc3RhZ2UgJWQpXG4iLCBTdGFnZSk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7IC8qIFdpbmRvd3MgYWNjZXB0cyBvdmVyZmxvd2luZyB0aGlzIGFycmF5IC4uLiB3ZSBkbyBub3QuICovCiAgICB9CgogICAgKnBwVGV4dHVyZT1UaGlzLT5zdGF0ZUJsb2NrLT50ZXh0dXJlc1tTdGFnZV07CiAgICBpZiAoKnBwVGV4dHVyZSkKICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX0FkZFJlZigqcHBUZXh0dXJlKTsKCiAgICBUUkFDRSgiKCVwKSA6IFJldHVybmluZyAlcFxuIiwgVGhpcywgKnBwVGV4dHVyZSk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBHZXQgQmFjayBCdWZmZXIKICoqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldEJhY2tCdWZmZXIoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIGlTd2FwQ2hhaW4sIFVJTlQgQmFja0J1ZmZlciwgV0lORUQzREJBQ0tCVUZGRVJfVFlQRSBUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2UgKipwcEJhY2tCdWZmZXIpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3dhcENoYWluICpzd2FwQ2hhaW47CiAgICBIUkVTVUxUIGhyOwoKICAgIFRSQUNFKCIoJXApIDogQmFja0J1ZiAlZCBUeXBlICVkIFN3YXBDaGFpbiAlZCByZXR1cm5pbmcgJXBcbiIsIFRoaXMsIEJhY2tCdWZmZXIsIFR5cGUsIGlTd2FwQ2hhaW4sICpwcEJhY2tCdWZmZXIpOwoKICAgIGhyID0gSVdpbmVEM0REZXZpY2VJbXBsX0dldFN3YXBDaGFpbihpZmFjZSwgIGlTd2FwQ2hhaW4sICZzd2FwQ2hhaW4pOwogICAgaWYgKGhyID09IFdJTkVEM0RfT0spIHsKICAgICAgICBociA9IElXaW5lRDNEU3dhcENoYWluX0dldEJhY2tCdWZmZXIoc3dhcENoYWluLCBCYWNrQnVmZmVyLCBUeXBlLCBwcEJhY2tCdWZmZXIpOwogICAgICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKHN3YXBDaGFpbik7CiAgICB9IGVsc2UgewogICAgICAgICpwcEJhY2tCdWZmZXIgPSBOVUxMOwogICAgfQogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldERldmljZUNhcHMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEQ0FQUyogcENhcHMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFdBUk4oIiglcCkgOiBzdHViLCBjYWxsaW5nIGlkaXJlY3QzZCBmb3Igbm93XG4iLCBUaGlzKTsKICAgIHJldHVybiBJV2luZUQzRF9HZXREZXZpY2VDYXBzKFRoaXMtPndpbmVEM0QsIFRoaXMtPmFkYXB0ZXJObywgVGhpcy0+ZGV2VHlwZSwgcENhcHMpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldERpc3BsYXlNb2RlKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBpU3dhcENoYWluLCBXSU5FRDNERElTUExBWU1PREUqIHBNb2RlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcENoYWluOwogICAgSFJFU1VMVCBocjsKCiAgICBpZihpU3dhcENoYWluID4gMCkgewogICAgICAgIGhyID0gSVdpbmVEM0REZXZpY2VJbXBsX0dldFN3YXBDaGFpbihpZmFjZSwgaVN3YXBDaGFpbiwgJnN3YXBDaGFpbik7CiAgICAgICAgaWYgKGhyID09IFdJTkVEM0RfT0spIHsKICAgICAgICAgICAgaHIgPSBJV2luZUQzRFN3YXBDaGFpbl9HZXREaXNwbGF5TW9kZShzd2FwQ2hhaW4sIHBNb2RlKTsKICAgICAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwQ2hhaW4pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIEZJWE1FKCIoJXApIEVycm9yIGdldHRpbmcgZGlzcGxheSBtb2RlXG4iLCBUaGlzKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIC8qIERvbid0IHJlYWQgdGhlIHJlYWwgZGlzcGxheSBtb2RlLAogICAgICAgICAgIGJ1dCByZXR1cm4gdGhlIHN0b3JlZCBtb2RlIGluc3RlYWQuIFgxMSBjYW4ndCBjaGFuZ2UgdGhlIGNvbG9yCiAgICAgICAgICAgZGVwdGgsIGFuZCBzb21lIGFwcHMgYXJlIHByZXR0eSBhbmdyeSBpZiB0aGV5IFNldERpc3BsYXlNb2RlIGZyb20KICAgICAgICAgICAyNCB0byAxNiBicHAgYW5kIGZpbmQgb3V0IHRoYXQgR2V0RGlzcGxheU1vZGUgc3RpbGwgcmV0dXJucyAyNCBicHAKCiAgICAgICAgICAgQWxzbyBkb24ndCByZWxheSB0byB0aGUgc3dhcGNoYWluIGJlY2F1c2Ugd2l0aCBkZHJhdyBpdCdzIHBvc3NpYmxlCiAgICAgICAgICAgdGhhdCB0aGVyZSBpc24ndCBhIHN3YXBjaGFpbiBhdCBhbGwgKi8KICAgICAgICBwTW9kZS0+V2lkdGggPSBUaGlzLT5kZHJhd193aWR0aDsKICAgICAgICBwTW9kZS0+SGVpZ2h0ID0gVGhpcy0+ZGRyYXdfaGVpZ2h0OwogICAgICAgIHBNb2RlLT5Gb3JtYXQgPSBUaGlzLT5kZHJhd19mb3JtYXQ7CiAgICAgICAgcE1vZGUtPlJlZnJlc2hSYXRlID0gMDsKICAgICAgICBociA9IFdJTkVEM0RfT0s7CiAgICB9CgogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldEhXTkQoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBIV05EIGhXbmQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLCBUaGlzLCBoV25kKTsKCiAgICBpZihUaGlzLT5kZHJhd19mdWxsc2NyZWVuKSB7CiAgICAgICAgaWYoVGhpcy0+ZGRyYXdfd2luZG93ICYmIFRoaXMtPmRkcmF3X3dpbmRvdyAhPSBoV25kKSB7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9SZXN0b3JlV2luZG93KGlmYWNlLCBUaGlzLT5kZHJhd193aW5kb3cpOwogICAgICAgIH0KICAgICAgICBpZihoV25kICYmIFRoaXMtPmRkcmF3X3dpbmRvdyAhPSBoV25kKSB7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXR1cEZ1bGxzY3JlZW5XaW5kb3coaWZhY2UsIGhXbmQpOwogICAgICAgIH0KICAgIH0KCiAgICBUaGlzLT5kZHJhd193aW5kb3cgPSBoV25kOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0SFdORChJV2luZUQzRERldmljZSAqaWZhY2UsIEhXTkQgKmhXbmQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLCBUaGlzLCBoV25kKTsKCiAgICAqaFduZCA9IFRoaXMtPmRkcmF3X3dpbmRvdzsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogU3RhdGVibG9jayByZWxhdGVkIGZ1bmN0aW9ucwogKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0JlZ2luU3RhdGVCbG9jayhJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3RhdGVCbG9ja0ltcGwgKm9iamVjdDsKICAgIEhSRVNVTFQgdGVtcF9yZXN1bHQ7CiAgICBpbnQgaTsKCiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CiAgICAKICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICAKICAgIG9iamVjdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSVdpbmVEM0RTdGF0ZUJsb2NrSW1wbCkpOwogICAgaWYgKE5VTEwgPT0gb2JqZWN0ICkgewogICAgICAgIEZJWE1FKCIoJXApRXJyb3IgYWxsb2NhdGluZyBtZW1vcnkgZm9yIHN0YXRlYmxvY2tcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwogICAgfQogICAgVFJBQ0UoIiglcCkgY3JlYXRlZCBvYmplY3QgJXBcbiIsIFRoaXMsIG9iamVjdCk7CiAgICBvYmplY3QtPndpbmVEM0REZXZpY2U9IFRoaXM7CiAgICAvKiogRklYTUU6IG9iamVjdC0+cGFyZW50ICAgICAgID0gcGFyZW50OyAqKi8KICAgIG9iamVjdC0+cGFyZW50ICAgICAgID0gTlVMTDsKICAgIG9iamVjdC0+YmxvY2tUeXBlICAgID0gV0lORUQzRFNCVF9SRUNPUkRFRDsKICAgIG9iamVjdC0+cmVmICAgICAgICAgID0gMTsKICAgIG9iamVjdC0+bHBWdGJsICAgICAgID0gJklXaW5lRDNEU3RhdGVCbG9ja19WdGJsOwoKICAgIGZvcihpID0gMDsgaSA8IExJR0hUTUFQX1NJWkU7IGkrKykgewogICAgICAgIGxpc3RfaW5pdCgmb2JqZWN0LT5saWdodE1hcFtpXSk7CiAgICB9CgogICAgdGVtcF9yZXN1bHQgPSBhbGxvY2F0ZV9zaGFkZXJfY29uc3RhbnRzKG9iamVjdCk7CiAgICBpZiAoV0lORUQzRF9PSyAhPSB0ZW1wX3Jlc3VsdCkKICAgICAgICByZXR1cm4gdGVtcF9yZXN1bHQ7CgogICAgSVdpbmVEM0RTdGF0ZUJsb2NrX1JlbGVhc2UoKElXaW5lRDNEU3RhdGVCbG9jayopVGhpcy0+dXBkYXRlU3RhdGVCbG9jayk7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrID0gb2JqZWN0OwogICAgVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSA9IFRSVUU7CgogICAgVFJBQ0UoIiglcCkgcmVjb3JkaW5nIHN0YXRlYmxvY2sgJXBcbiIsVGhpcyAsIG9iamVjdCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9FbmRTdGF0ZUJsb2NrKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RTdGF0ZUJsb2NrKiogcHBTdGF0ZUJsb2NrKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICB1bnNpZ25lZCBpbnQgaSwgajsKICAgIElXaW5lRDNEU3RhdGVCbG9ja0ltcGwgKm9iamVjdCA9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2s7CgogICAgaWYgKCFUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgRklYTUUoIiglcCkgbm90IHJlY29yZGluZyEgcmV0dXJuaW5nIGVycm9yXG4iLCBUaGlzKTsKICAgICAgICAqcHBTdGF0ZUJsb2NrID0gTlVMTDsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBmb3IoaSA9IDE7IGkgPD0gV0lORUhJR0hFU1RfUkVOREVSX1NUQVRFOyBpKyspIHsKICAgICAgICBpZihvYmplY3QtPmNoYW5nZWQucmVuZGVyU3RhdGVbaV0pIHsKICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfcmVuZGVyX3N0YXRlc1tvYmplY3QtPm51bV9jb250YWluZWRfcmVuZGVyX3N0YXRlc10gPSBpOwogICAgICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfcmVuZGVyX3N0YXRlcysrOwogICAgICAgIH0KICAgIH0KICAgIGZvcihpID0gMTsgaSA8PSBISUdIRVNUX1RSQU5TRk9STVNUQVRFOyBpKyspIHsKICAgICAgICBpZihvYmplY3QtPmNoYW5nZWQudHJhbnNmb3JtW2ldKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3RyYW5zZm9ybV9zdGF0ZXNbb2JqZWN0LT5udW1fY29udGFpbmVkX3RyYW5zZm9ybV9zdGF0ZXNdID0gaTsKICAgICAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3RyYW5zZm9ybV9zdGF0ZXMrKzsKICAgICAgICB9CiAgICB9CiAgICBmb3IoaSA9IDA7IGkgPCBHTF9MSU1JVFModnNoYWRlcl9jb25zdGFudHNGKTsgaSsrKSB7CiAgICAgICAgaWYob2JqZWN0LT5jaGFuZ2VkLnZlcnRleFNoYWRlckNvbnN0YW50c0ZbaV0pIHsKICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfdnNfY29uc3RzX2Zbb2JqZWN0LT5udW1fY29udGFpbmVkX3ZzX2NvbnN0c19mXSA9IGk7CiAgICAgICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF92c19jb25zdHNfZisrOwogICAgICAgIH0KICAgIH0KICAgIGZvcihpID0gMDsgaSA8IE1BWF9DT05TVF9JOyBpKyspIHsKICAgICAgICBpZihvYmplY3QtPmNoYW5nZWQudmVydGV4U2hhZGVyQ29uc3RhbnRzSVtpXSkgewogICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF92c19jb25zdHNfaVtvYmplY3QtPm51bV9jb250YWluZWRfdnNfY29uc3RzX2ldID0gaTsKICAgICAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3ZzX2NvbnN0c19pKys7CiAgICAgICAgfQogICAgfQogICAgZm9yKGkgPSAwOyBpIDwgTUFYX0NPTlNUX0I7IGkrKykgewogICAgICAgIGlmKG9iamVjdC0+Y2hhbmdlZC52ZXJ0ZXhTaGFkZXJDb25zdGFudHNCW2ldKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3ZzX2NvbnN0c19iW29iamVjdC0+bnVtX2NvbnRhaW5lZF92c19jb25zdHNfYl0gPSBpOwogICAgICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfdnNfY29uc3RzX2IrKzsKICAgICAgICB9CiAgICB9CiAgICBmb3IoaSA9IDA7IGkgPCBNQVhfQ09OU1RfSTsgaSsrKSB7CiAgICAgICAgaWYob2JqZWN0LT5jaGFuZ2VkLnBpeGVsU2hhZGVyQ29uc3RhbnRzSVtpXSkgewogICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF9wc19jb25zdHNfaVtvYmplY3QtPm51bV9jb250YWluZWRfcHNfY29uc3RzX2ldID0gaTsKICAgICAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3BzX2NvbnN0c19pKys7CiAgICAgICAgfQogICAgfQogICAgZm9yKGkgPSAwOyBpIDwgTUFYX0NPTlNUX0I7IGkrKykgewogICAgICAgIGlmKG9iamVjdC0+Y2hhbmdlZC5waXhlbFNoYWRlckNvbnN0YW50c0JbaV0pIHsKICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfcHNfY29uc3RzX2Jbb2JqZWN0LT5udW1fY29udGFpbmVkX3BzX2NvbnN0c19iXSA9IGk7CiAgICAgICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF9wc19jb25zdHNfYisrOwogICAgICAgIH0KICAgIH0KICAgIGZvcihpID0gMDsgaSA8IE1BWF9URVhUVVJFUzsgaSsrKSB7CiAgICAgICAgZm9yKGogPSAxOyBqIDw9IFdJTkVEM0RfSElHSEVTVF9URVhUVVJFX1NUQVRFOyBqKyspIHsKICAgICAgICAgICAgaWYob2JqZWN0LT5jaGFuZ2VkLnRleHR1cmVTdGF0ZVtpXVtqXSkgewogICAgICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfdHNzX3N0YXRlc1tvYmplY3QtPm51bV9jb250YWluZWRfdHNzX3N0YXRlc10uc3RhZ2UgPSBpOwogICAgICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfdHNzX3N0YXRlc1tvYmplY3QtPm51bV9jb250YWluZWRfdHNzX3N0YXRlc10uc3RhdGUgPSBqOwogICAgICAgICAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3Rzc19zdGF0ZXMrKzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGZvcihpID0gMDsgaSA8IE1BWF9DT01CSU5FRF9TQU1QTEVSUzsgaSsrKXsKICAgICAgICBmb3IgKGogPSAxOyBqIDwgV0lORUQzRF9ISUdIRVNUX1NBTVBMRVJfU1RBVEU7IGorKykgewogICAgICAgICAgICBpZihvYmplY3QtPmNoYW5nZWQuc2FtcGxlclN0YXRlW2ldW2pdKSB7CiAgICAgICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF9zYW1wbGVyX3N0YXRlc1tvYmplY3QtPm51bV9jb250YWluZWRfc2FtcGxlcl9zdGF0ZXNdLnN0YWdlID0gaTsKICAgICAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3NhbXBsZXJfc3RhdGVzW29iamVjdC0+bnVtX2NvbnRhaW5lZF9zYW1wbGVyX3N0YXRlc10uc3RhdGUgPSBqOwogICAgICAgICAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3NhbXBsZXJfc3RhdGVzKys7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgKnBwU3RhdGVCbG9jayA9IChJV2luZUQzRFN0YXRlQmxvY2sqKSBvYmplY3Q7CiAgICBUaGlzLT5pc1JlY29yZGluZ1N0YXRlID0gRkFMU0U7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrID0gVGhpcy0+c3RhdGVCbG9jazsKICAgIElXaW5lRDNEU3RhdGVCbG9ja19BZGRSZWYoKElXaW5lRDNEU3RhdGVCbG9jayopVGhpcy0+dXBkYXRlU3RhdGVCbG9jayk7CiAgICAvKiBJV2luZUQzRFN0YXRlQmxvY2tfQWRkUmVmKCpwcFN0YXRlQmxvY2spOyBkb24ndCBuZWVkIHRvIGRvIHRoaXMsIHNpbmNlIHdlIHNob3VsZCByZWFsbHkganVzdCByZWxlYXNlIFVwZGF0ZVN0YXRlQmxvY2sgZmlyc3QgKi8KICAgIFRSQUNFKCIoJXApIHJldHVybmluZyB0b2tlbiAocHRyIHRvIHN0YXRlYmxvY2spIG9mICVwXG4iLCBUaGlzLCAqcHBTdGF0ZUJsb2NrKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogU2NlbmUgcmVsYXRlZCBmdW5jdGlvbnMKICoqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0JlZ2luU2NlbmUoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICAvKiBBdCB0aGUgbW9tZW50IHdlIGhhdmUgbm8gbmVlZCBmb3IgYW55IGZ1bmN0aW9uYWxpdHkgYXQgdGhlIGJlZ2lubmluZwogICAgICAgb2YgYSBzY2VuZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIGlmKFRoaXMtPmluU2NlbmUpIHsKICAgICAgICBUUkFDRSgiQWxyZWFkeSBpbiBTY2VuZSwgcmV0dXJuaW5nIFdJTkVEM0RFUlJfSU5WQUxJRENBTExcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgVGhpcy0+aW5TY2VuZSA9IFRSVUU7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9FbmRTY2VuZShJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICBpZighVGhpcy0+aW5TY2VuZSkgewogICAgICAgIFRSQUNFKCJOb3QgaW4gc2NlbmUsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBBY3RpdmF0ZUNvbnRleHQoVGhpcywgVGhpcy0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKICAgIC8qIFdlIG9ubHkgaGF2ZSB0byBkbyB0aGlzIGlmIHdlIG5lZWQgdG8gcmVhZCB0aGUsIHN3YXBidWZmZXJzIHBlcmZvcm1zIGEgZmx1c2ggZm9yIHVzICovCiAgICBFTlRFUl9HTCgpOwogICAgZ2xGbHVzaCgpOwogICAgY2hlY2tHTGNhbGwoImdsRmx1c2giKTsKICAgIExFQVZFX0dMKCk7CgogICAgVGhpcy0+aW5TY2VuZSA9IEZBTFNFOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfUHJlc2VudChJV2luZUQzRERldmljZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTlNUIFJFQ1QqIHBTb3VyY2VSZWN0LCBDT05TVCBSRUNUKiBwRGVzdFJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhXTkQgaERlc3RXaW5kb3dPdmVycmlkZSwgQ09OU1QgUkdOREFUQSogcERpcnR5UmVnaW9uKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcENoYWluID0gTlVMTDsKICAgIGludCBpOwogICAgaW50IHN3YXBjaGFpbnMgPSBJV2luZUQzRERldmljZUltcGxfR2V0TnVtYmVyT2ZTd2FwQ2hhaW5zKGlmYWNlKTsKCiAgICBUUkFDRSgiKCVwKSBQcmVzZW50aW5nIHRoZSBmcmFtZVxuIiwgVGhpcyk7CgogICAgZm9yKGkgPSAwIDsgaSA8IHN3YXBjaGFpbnMgOyBpICsrKSB7CgogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTd2FwQ2hhaW4oaWZhY2UsIGksICZzd2FwQ2hhaW4pOwogICAgICAgIFRSQUNFKCJwcmVzZW50aW5uZyBjaGFpbiAlZCwgJXBcbiIsIGksIHN3YXBDaGFpbik7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUHJlc2VudChzd2FwQ2hhaW4sIHBTb3VyY2VSZWN0LCBwRGVzdFJlY3QsIGhEZXN0V2luZG93T3ZlcnJpZGUsIHBEaXJ0eVJlZ2lvbiwgMCk7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwQ2hhaW4pOwogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKiBOb3QgY2FsbGVkIGZyb20gdGhlIFZUYWJsZSAoaW50ZXJuYWwgc3Vicm91dGluZSkgKi8KSFJFU1VMVCBJV2luZUQzRERldmljZUltcGxfQ2xlYXJTdXJmYWNlKElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcywgIElXaW5lRDNEU3VyZmFjZUltcGwgKnRhcmdldCwgRFdPUkQgQ291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT05TVCBXSU5FRDNEUkVDVCogcFJlY3RzLCBEV09SRCBGbGFncywgV0lORUQzRENPTE9SIENvbG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgWiwgRFdPUkQgU3RlbmNpbCkgewogICAgR0xiaXRmaWVsZCAgICAgZ2xNYXNrID0gMDsKICAgIHVuc2lnbmVkIGludCAgIGk7CiAgICBXSU5FRDNEUkVDVCBjdXJSZWN0OwogICAgUkVDVCB2cF9yZWN0OwogICAgV0lORUQzRFZJRVdQT1JUICp2cCA9ICZUaGlzLT5zdGF0ZUJsb2NrLT52aWV3cG9ydDsKICAgIFVJTlQgZHJhd2FibGVfd2lkdGgsIGRyYXdhYmxlX2hlaWdodDsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKmRlcHRoX3N0ZW5jaWwgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0OwoKICAgIC8qIFdoZW4gd2UncmUgY2xlYXJpbmcgcGFydHMgb2YgdGhlIGRyYXdhYmxlLCBtYWtlIHN1cmUgdGhhdCB0aGUgdGFyZ2V0IHN1cmZhY2UgaXMgd2VsbCB1cCB0byBkYXRlIGluIHRoZQogICAgICogZHJhd2FibGUuIEFmdGVyIHRoZSBjbGVhciB3ZSdsbCBtYXJrIHRoZSBkcmF3YWJsZSB1cCB0byBkYXRlLCBzbyB3ZSBoYXZlIHRvIG1ha2Ugc3VyZSB0aGF0IHRoaXMgaXMgdHJ1ZQogICAgICogZm9yIHRoZSBjbGVhcmVkIHBhcnRzLCBhbmQgdGhlIHVudG91Y2hlZCBwYXJ0cy4KICAgICAqCiAgICAgKiBJZiB3ZSdyZSBjbGVhcmluZyB0aGUgd2hvbGUgdGFyZ2V0IHRoZXJlIGlzIG5vIG5lZWQgdG8gY29weSBpdCBpbnRvIHRoZSBkcmF3YWJsZSwgaXQgd2lsbCBiZSBvdmVyd3JpdHRlbgogICAgICogYW55d2F5LiBJZiB3ZSdyZSBub3QgY2xlYXJpbmcgdGhlIGNvbG9yIGJ1ZmZlciB3ZSBkb24ndCBoYXZlIHRvIGNvcHkgZWl0aGVyIHNpbmNlIHdlJ3JlIG5vdCBnb2luZyB0byBzZXQKICAgICAqIHRoZSBkcmF3YWJsZSB1cCB0byBkYXRlLiBXZSBoYXZlIHRvIGNoZWNrIGFsbCBzZXR0aW5ncyB0aGF0IGxpbWl0IHRoZSBjbGVhciBhcmVhIHRob3VnaC4gRG8gbm90IGJvdGhlcgogICAgICogY2hlY2tpbmcgYWxsIHRoaXMgaWYgdGhlIGRlc3Qgc3VyZmFjZSBpcyBpbiB0aGUgZHJhd2FibGUgYW55d2F5LgogICAgICovCiAgICBpZigoRmxhZ3MgJiBXSU5FRDNEQ0xFQVJfVEFSR0VUKSAmJiAhKHRhcmdldC0+RmxhZ3MgJiBTRkxBR19JTkRSQVdBQkxFKSkgewogICAgICAgIHdoaWxlKDEpIHsKICAgICAgICAgICAgaWYodnAtPlggIT0gMCB8fCB2cC0+WSAhPSAwIHx8CiAgICAgICAgICAgICAgIHZwLT5XaWR0aCA8IHRhcmdldC0+Y3VycmVudERlc2MuV2lkdGggfHwgdnAtPkhlaWdodCA8IHRhcmdldC0+Y3VycmVudERlc2MuSGVpZ2h0KSB7CiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfTG9hZExvY2F0aW9uKChJV2luZUQzRFN1cmZhY2UgKikgdGFyZ2V0LCBTRkxBR19JTkRSQVdBQkxFLCBOVUxMKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19TQ0lTU09SVEVTVEVOQUJMRV0gJiYgKAogICAgICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zY2lzc29yUmVjdC5sZWZ0ID4gMCB8fCBUaGlzLT5zdGF0ZUJsb2NrLT5zY2lzc29yUmVjdC50b3AgPiAwIHx8CiAgICAgICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPnNjaXNzb3JSZWN0LnJpZ2h0IDwgdGFyZ2V0LT5jdXJyZW50RGVzYy5XaWR0aCB8fAogICAgICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zY2lzc29yUmVjdC5ib3R0b20gPCB0YXJnZXQtPmN1cnJlbnREZXNjLkhlaWdodCkpIHsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9Mb2FkTG9jYXRpb24oKElXaW5lRDNEU3VyZmFjZSAqKSB0YXJnZXQsIFNGTEFHX0lORFJBV0FCTEUsIE5VTEwpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoQ291bnQgPiAwICYmIHBSZWN0cyAmJiAoCiAgICAgICAgICAgICAgIHBSZWN0c1swXS54MSA+IDAgfHwgcFJlY3RzWzBdLnkxID4gMCB8fAogICAgICAgICAgICAgICBwUmVjdHNbMF0ueDIgPCB0YXJnZXQtPmN1cnJlbnREZXNjLldpZHRoIHx8CiAgICAgICAgICAgICAgIHBSZWN0c1swXS55MiA8IHRhcmdldC0+Y3VycmVudERlc2MuSGVpZ2h0KSkgewogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvYWRMb2NhdGlvbigoSVdpbmVEM0RTdXJmYWNlICopIHRhcmdldCwgU0ZMQUdfSU5EUkFXQUJMRSwgTlVMTCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgdGFyZ2V0LT5nZXRfZHJhd2FibGVfc2l6ZSh0YXJnZXQsICZkcmF3YWJsZV93aWR0aCwgJmRyYXdhYmxlX2hlaWdodCk7CgogICAgQWN0aXZhdGVDb250ZXh0KFRoaXMsIChJV2luZUQzRFN1cmZhY2UgKikgdGFyZ2V0LCBDVFhVU0FHRV9DTEVBUik7CiAgICBFTlRFUl9HTCgpOwoKICAgIGlmICh3aW5lZDNkX3NldHRpbmdzLm9mZnNjcmVlbl9yZW5kZXJpbmdfbW9kZSA9PSBPUk1fRkJPKSB7CiAgICAgICAgYXBwbHlfZmJvX3N0YXRlKChJV2luZUQzRERldmljZSAqKSBUaGlzKTsKICAgIH0KCiAgICAvKiBPbmx5IHNldCB0aGUgdmFsdWVzIHVwIG9uY2UsIGFzIHRoZXkgYXJlIG5vdCBjaGFuZ2luZyAqLwogICAgaWYgKEZsYWdzICYgV0lORUQzRENMRUFSX1NURU5DSUwpIHsKICAgICAgICBnbENsZWFyU3RlbmNpbChTdGVuY2lsKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xDbGVhclN0ZW5jaWwiKTsKICAgICAgICBnbE1hc2sgPSBnbE1hc2sgfCBHTF9TVEVOQ0lMX0JVRkZFUl9CSVQ7CiAgICAgICAgZ2xTdGVuY2lsTWFzaygweEZGRkZGRkZGKTsKICAgIH0KCiAgICBpZiAoRmxhZ3MgJiBXSU5FRDNEQ0xFQVJfWkJVRkZFUikgewogICAgICAgIGdsRGVwdGhNYXNrKEdMX1RSVUUpOwogICAgICAgIGdsQ2xlYXJEZXB0aChaKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xDbGVhckRlcHRoIik7CiAgICAgICAgZ2xNYXNrID0gZ2xNYXNrIHwgR0xfREVQVEhfQlVGRkVSX0JJVDsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19aV1JJVEVFTkFCTEUpKTsKCiAgICAgICAgaWYoVGhpcy0+ZGVwdGhfY29weV9zdGF0ZSA9PSBXSU5FRDNEX0RDU19DT1BZKSB7CiAgICAgICAgICAgIGlmKHZwLT5YICE9IDAgfHwgdnAtPlkgIT0gMCB8fAogICAgICAgICAgICAgICB2cC0+V2lkdGggPCBkZXB0aF9zdGVuY2lsLT5jdXJyZW50RGVzYy5XaWR0aCB8fCB2cC0+SGVpZ2h0IDwgZGVwdGhfc3RlbmNpbC0+Y3VycmVudERlc2MuSGVpZ2h0KSB7CiAgICAgICAgICAgICAgICBkZXB0aF9jb3B5KChJV2luZUQzRERldmljZSAqKSBUaGlzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIGlmKFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19TQ0lTU09SVEVTVEVOQUJMRV0gJiYgKAogICAgICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zY2lzc29yUmVjdC5sZWZ0ID4gMCB8fCBUaGlzLT5zdGF0ZUJsb2NrLT5zY2lzc29yUmVjdC50b3AgPiAwIHx8CiAgICAgICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPnNjaXNzb3JSZWN0LnJpZ2h0IDwgZGVwdGhfc3RlbmNpbC0+Y3VycmVudERlc2MuV2lkdGggfHwKICAgICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+c2Npc3NvclJlY3QuYm90dG9tIDwgZGVwdGhfc3RlbmNpbC0+Y3VycmVudERlc2MuSGVpZ2h0KSkgewogICAgICAgICAgICAgICAgZGVwdGhfY29weSgoSVdpbmVEM0REZXZpY2UgKikgVGhpcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZihDb3VudCA+IDAgJiYgcFJlY3RzICYmICgKICAgICAgICAgICAgICAgcFJlY3RzWzBdLngxID4gMCB8fCBwUmVjdHNbMF0ueTEgPiAwIHx8CiAgICAgICAgICAgICAgIHBSZWN0c1swXS54MiA8IGRlcHRoX3N0ZW5jaWwtPmN1cnJlbnREZXNjLldpZHRoIHx8CiAgICAgICAgICAgICAgIHBSZWN0c1swXS55MiA8IGRlcHRoX3N0ZW5jaWwtPmN1cnJlbnREZXNjLkhlaWdodCkpIHsKICAgICAgICAgICAgICAgIGRlcHRoX2NvcHkoKElXaW5lRDNERGV2aWNlICopIFRoaXMpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIFRoaXMtPmRlcHRoX2NvcHlfc3RhdGUgPSBXSU5FRDNEX0RDU19JTklUSUFMOwogICAgfQoKICAgIGlmIChGbGFncyAmIFdJTkVEM0RDTEVBUl9UQVJHRVQpIHsKICAgICAgICBUUkFDRSgiQ2xlYXJpbmcgc2NyZWVuIHdpdGggZ2xDbGVhciB0byBjb2xvciAleFxuIiwgQ29sb3IpOwogICAgICAgIGdsQ2xlYXJDb2xvcihEM0RDT0xPUl9SKENvbG9yKSwKICAgICAgICAgICAgICAgICAgICAgRDNEQ09MT1JfRyhDb2xvciksCiAgICAgICAgICAgICAgICAgICAgIEQzRENPTE9SX0IoQ29sb3IpLAogICAgICAgICAgICAgICAgICAgICBEM0RDT0xPUl9BKENvbG9yKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQ2xlYXJDb2xvciIpOwoKICAgICAgICAvKiBDbGVhciBBTEwgY29sb3JzISAqLwogICAgICAgIGdsQ29sb3JNYXNrKEdMX1RSVUUsIEdMX1RSVUUsIEdMX1RSVUUsIEdMX1RSVUUpOwogICAgICAgIGdsTWFzayA9IGdsTWFzayB8IEdMX0NPTE9SX0JVRkZFUl9CSVQ7CiAgICB9CgogICAgdnBfcmVjdC5sZWZ0ID0gdnAtPlg7CiAgICB2cF9yZWN0LnRvcCA9IHZwLT5ZOwogICAgdnBfcmVjdC5yaWdodCA9IHZwLT5YICsgdnAtPldpZHRoOwogICAgdnBfcmVjdC5ib3R0b20gPSB2cC0+WSArIHZwLT5IZWlnaHQ7CiAgICBpZiAoIShDb3VudCA+IDAgJiYgcFJlY3RzKSkgewogICAgICAgIGlmKFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19TQ0lTU09SVEVTVEVOQUJMRV0pIHsKICAgICAgICAgICAgSW50ZXJzZWN0UmVjdCgmdnBfcmVjdCwgJnZwX3JlY3QsICZUaGlzLT5zdGF0ZUJsb2NrLT5zY2lzc29yUmVjdCk7CiAgICAgICAgfQogICAgICAgIGlmKFRoaXMtPnJlbmRlcl9vZmZzY3JlZW4pIHsKICAgICAgICAgICAgZ2xTY2lzc29yKHZwX3JlY3QubGVmdCwgdnBfcmVjdC50b3AsCiAgICAgICAgICAgICAgICAgICAgICAgIHZwX3JlY3QucmlnaHQgLSB2cF9yZWN0LmxlZnQsIHZwX3JlY3QuYm90dG9tIC0gdnBfcmVjdC50b3ApOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGdsU2Npc3Nvcih2cF9yZWN0LmxlZnQsIGRyYXdhYmxlX2hlaWdodCAtIHZwX3JlY3QuYm90dG9tLAogICAgICAgICAgICAgICAgICAgICAgICB2cF9yZWN0LnJpZ2h0IC0gdnBfcmVjdC5sZWZ0LCB2cF9yZWN0LmJvdHRvbSAtIHZwX3JlY3QudG9wKTsKICAgICAgICB9CiAgICAgICAgY2hlY2tHTGNhbGwoImdsU2Npc3NvciIpOwogICAgICAgIGdsQ2xlYXIoZ2xNYXNrKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xDbGVhciIpOwogICAgfSBlbHNlIHsKICAgICAgICAvKiBOb3cgcHJvY2VzcyBlYWNoIHJlY3QgaW4gdHVybiAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBDb3VudDsgaSsrKSB7CiAgICAgICAgICAgIC8qIE5vdGUgZ2wgdXNlcyBsb3dlciBsZWZ0LCB3aWR0aC9oZWlnaHQgKi8KICAgICAgICAgICAgSW50ZXJzZWN0UmVjdCgoUkVDVCAqKSAmY3VyUmVjdCwgJnZwX3JlY3QsIChSRUNUICopICZwUmVjdHNbaV0pOwogICAgICAgICAgICBpZihUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfU0NJU1NPUlRFU1RFTkFCTEVdKSB7CiAgICAgICAgICAgICAgICBJbnRlcnNlY3RSZWN0KChSRUNUICopICZjdXJSZWN0LCAoUkVDVCAqKSAmY3VyUmVjdCwgJlRoaXMtPnN0YXRlQmxvY2stPnNjaXNzb3JSZWN0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBUUkFDRSgiKCVwKSBSZWN0PSglZCwlZCktPiglZCwlZCkgZ2xSZWN0PSglZCwlZCksIGxlbj0lZCwgaGVpPSVkXG4iLCBUaGlzLAogICAgICAgICAgICAgICAgICBwUmVjdHNbaV0ueDEsIHBSZWN0c1tpXS55MSwgcFJlY3RzW2ldLngyLCBwUmVjdHNbaV0ueTIsCiAgICAgICAgICAgICAgICAgIGN1clJlY3QueDEsICh0YXJnZXQtPmN1cnJlbnREZXNjLkhlaWdodCAtIGN1clJlY3QueTIpLAogICAgICAgICAgICAgICAgICBjdXJSZWN0LngyIC0gY3VyUmVjdC54MSwgY3VyUmVjdC55MiAtIGN1clJlY3QueTEpOwoKICAgICAgICAgICAgLyogVGVzdHMgc2hvdyB0aGF0IHJlY3RhbmdsZXMgd2hlcmUgeDEgPiB4MiBvciB5MSA+IHkyIGFyZSBpZ25vcmVkIHNpbGVudGx5LgogICAgICAgICAgICAgKiBUaGUgcmVjdGFuZ2xlIGlzIG5vdCBjbGVhcmVkLCBubyBlcnJvciBpcyByZXR1cm5lZCwgYnV0IGZ1cnRoZXIgcmVjdGFubGdlcyBhcmUKICAgICAgICAgICAgICogc3RpbGwgY2xlYXJlZCBpZiB0aGV5IGFyZSB2YWxpZAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYoY3VyUmVjdC54MSA+IGN1clJlY3QueDIgfHwgY3VyUmVjdC55MSA+IGN1clJlY3QueTIpIHsKICAgICAgICAgICAgICAgIFRSQUNFKCJSZWN0YW5nbGUgd2l0aCBuZWdhdGl2ZSBkaW1lbnNpb25zLCBpZ25vcmluZ1xuIik7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYoVGhpcy0+cmVuZGVyX29mZnNjcmVlbikgewogICAgICAgICAgICAgICAgZ2xTY2lzc29yKGN1clJlY3QueDEsIGN1clJlY3QueTEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyUmVjdC54MiAtIGN1clJlY3QueDEsIGN1clJlY3QueTIgLSBjdXJSZWN0LnkxKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGdsU2Npc3NvcihjdXJSZWN0LngxLCBkcmF3YWJsZV9oZWlnaHQgLSBjdXJSZWN0LnkyLAogICAgICAgICAgICAgICAgICAgICAgICAgIGN1clJlY3QueDIgLSBjdXJSZWN0LngxLCBjdXJSZWN0LnkyIC0gY3VyUmVjdC55MSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsU2Npc3NvciIpOwoKICAgICAgICAgICAgZ2xDbGVhcihnbE1hc2spOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xDbGVhciIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBSZXN0b3JlIHRoZSBvbGQgdmFsdWVzICh3aHkuLj8pICovCiAgICBpZiAoRmxhZ3MgJiBXSU5FRDNEQ0xFQVJfU1RFTkNJTCkgewogICAgICAgIGdsU3RlbmNpbE1hc2soVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbV0lORUQzRFJTX1NURU5DSUxXUklURU1BU0tdKTsKICAgIH0KICAgIGlmIChGbGFncyAmIFdJTkVEM0RDTEVBUl9UQVJHRVQpIHsKICAgICAgICBEV09SRCBtYXNrID0gVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbV0lORUQzRFJTX0NPTE9SV1JJVEVFTkFCTEVdOwogICAgICAgIGdsQ29sb3JNYXNrKG1hc2sgJiBXSU5FRDNEQ09MT1JXUklURUVOQUJMRV9SRUQgPyBHTF9UUlVFIDogR0xfRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgbWFzayAmIFdJTkVEM0RDT0xPUldSSVRFRU5BQkxFX0dSRUVOID8gR0xfVFJVRSA6IEdMX0ZBTFNFLAogICAgICAgICAgICAgICAgICAgIG1hc2sgJiBXSU5FRDNEQ09MT1JXUklURUVOQUJMRV9CTFVFICA/IEdMX1RSVUUgOiBHTF9GQUxTRSwKICAgICAgICAgICAgICAgICAgICBtYXNrICYgV0lORUQzRENPTE9SV1JJVEVFTkFCTEVfQUxQSEEgPyBHTF9UUlVFIDogR0xfRkFMU0UpOwoKICAgICAgICAvKiBEaXJ0aWZ5IHRoZSB0YXJnZXQgc3VyZmFjZSBmb3Igbm93LiBJZiB0aGUgc3VyZmFjZSBpcyBsb2NrZWQgcmVndWxhcmx5LCBhbmQgYW4gdXAgdG8gZGF0ZSBzeXNtZW0gY29weSBleGlzdHMsCiAgICAgICAgICogaXQgaXMgbW9zdCBsaWtlbHkgbW9yZSBlZmZpY2llbnQgdG8gcGVyZm9ybSBhIGNsZWFyIG9uIHRoZSBzeXNtZW0gY29weSB0b28gaW5zdGVhZCBvZiBkb3dubG9hZGluZyBpdAogICAgICAgICAqLwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9Nb2RpZnlMb2NhdGlvbihUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0LCBTRkxBR19JTkRSQVdBQkxFLCBUUlVFKTsKICAgICAgICAvKiBUT0RPOiBNb3ZlIHRoZSBmYm8gbG9naWMgaW50byBNb2RpZnlMb2NhdGlvbigpICovCiAgICAgICAgaWYoVGhpcy0+cmVuZGVyX29mZnNjcmVlbiAmJiB3aW5lZDNkX3NldHRpbmdzLm9mZnNjcmVlbl9yZW5kZXJpbmdfbW9kZSA9PSBPUk1fRkJPKSB7CiAgICAgICAgICAgIHRhcmdldC0+RmxhZ3MgfD0gU0ZMQUdfSU5URVhUVVJFOwogICAgICAgIH0KICAgIH0KICAgIExFQVZFX0dMKCk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ2xlYXIoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBDb3VudCwgQ09OU1QgV0lORUQzRFJFQ1QqIHBSZWN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzLCBXSU5FRDNEQ09MT1IgQ29sb3IsIGZsb2F0IFosIERXT1JEIFN0ZW5jaWwpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKnRhcmdldCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopVGhpcy0+cmVuZGVyX3RhcmdldHNbMF07CgogICAgVFJBQ0UoIiglcCkgQ291bnQgKCVkKSwgcFJlY3RzICglcCksIEZsYWdzICgleCksIENvbG9yICgweCUwOHgpLCBaICglZiksIFN0ZW5jaWwgKCVkKVxuIiwgVGhpcywKICAgICAgICAgIENvdW50LCBwUmVjdHMsIEZsYWdzLCBDb2xvciwgWiwgU3RlbmNpbCk7CgogICAgaWYoRmxhZ3MgJiAoV0lORUQzRENMRUFSX1pCVUZGRVIgfCBXSU5FRDNEQ0xFQVJfU1RFTkNJTCkgJiYgVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCA9PSBOVUxMKSB7CiAgICAgICAgV0FSTigiQ2xlYXJpbmcgZGVwdGggYW5kL29yIHN0ZW5jaWwgd2l0aG91dCBhIGRlcHRoIHN0ZW5jaWwgYnVmZmVyIGF0dGFjaGVkLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgLyogVE9ETzogV2hhdCBhYm91dCBkZXB0aCBzdGVuY2lsIGJ1ZmZlcnMgd2l0aG91dCBzdGVuY2lsIGJpdHM/ICovCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgcmV0dXJuIElXaW5lRDNERGV2aWNlSW1wbF9DbGVhclN1cmZhY2UoVGhpcywgdGFyZ2V0LCBDb3VudCwgcFJlY3RzLCBGbGFncywgQ29sb3IsIFosIFN0ZW5jaWwpOwp9CgovKioqKioKICogRHJhd2luZyBmdW5jdGlvbnMKICoqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdQcmltaXRpdmUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLCBVSU5UIFN0YXJ0VmVydGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFByaW1pdGl2ZUNvdW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXApIDogVHlwZT0oJWQsJXMpLCBTdGFydD0lZCwgQ291bnQ9JWRcbiIsIFRoaXMsIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWJ1Z19kM2RwcmltaXRpdmV0eXBlKFByaW1pdGl2ZVR5cGUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhcnRWZXJ0ZXgsIFByaW1pdGl2ZUNvdW50KTsKCiAgICBpZighVGhpcy0+c3RhdGVCbG9jay0+dmVydGV4RGVjbCkgewogICAgICAgIFdBUk4oIiglcCkgOiBDYWxsZWQgd2l0aG91dCBhIHZhbGlkIHZlcnRleCBkZWNsYXJhdGlvbiBzZXRcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIC8qIFRoZSBpbmRleCBidWZmZXIgaXMgbm90IG5lZWRlZCBoZXJlLCBidXQgcmVzdG9yZSBpdCwgb3RoZXJ3aXNlIGl0IGlzIGhlbGwgdG8ga2VlcCB0cmFjayBvZiAqLwogICAgaWYoVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtSXNVUCkgewogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9JTkRFWEJVRkZFUik7CiAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtSXNVUCA9IEZBTFNFOwogICAgfQoKICAgIGlmKFRoaXMtPnN0YXRlQmxvY2stPmxvYWRCYXNlVmVydGV4SW5kZXggIT0gMCkgewogICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPmxvYWRCYXNlVmVydGV4SW5kZXggPSAwOwogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TVFJFQU1TUkMpOwogICAgfQogICAgLyogQWNjb3VudCBmb3IgdGhlIGxvYWRpbmcgb2Zmc2V0IGR1ZSB0byBpbmRleCBidWZmZXJzLiBJbnN0ZWFkIG9mIHJlbG9hZGluZyBhbGwgc291cmNlcyBjb3JyZWN0IGl0IHdpdGggdGhlIHN0YXJ0dmVydGV4IHBhcmFtZXRlciAqLwogICAgZHJhd1ByaW1pdGl2ZShpZmFjZSwgUHJpbWl0aXZlVHlwZSwgUHJpbWl0aXZlQ291bnQsIFN0YXJ0VmVydGV4LCAwLyogTnVtVmVydGljZXMgKi8sIC0xIC8qIGluZHhTdGFydCAqLywKICAgICAgICAgICAgICAgICAgMCAvKiBpbmR4U2l6ZSAqLywgTlVMTCAvKiBpbmR4RGF0YSAqLywgMCAvKiBtaW5JbmRleCAqLyk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyogVE9ETzogYmFzZVZJbmRleCBuZWVkcyB0byBiZSBwcm92aWRlZCBmcm9tIFRoaXMtPnN0YXRlQmxvY2stPmJhc2VWZXJ0ZXhJbmRleCB3aGVuIGNhbGxlZCBmcm9tIGQzZDggKi8Kc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdJbmRleGVkUHJpbWl0aXZlKElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgbWluSW5kZXgsIFVJTlQgTnVtVmVydGljZXMsIFVJTlQgc3RhcnRJbmRleCwgVUlOVCBwcmltQ291bnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVUlOVCAgICAgICAgICAgICAgICAgaWR4U3RyaWRlID0gMjsKICAgIElXaW5lRDNESW5kZXhCdWZmZXIgKnBJQjsKICAgIFdJTkVEM0RJTkRFWEJVRkZFUl9ERVNDICBJZHhCdWZEc2M7CiAgICBHTHVpbnQgdmJvOwoKICAgIHBJQiA9IFRoaXMtPnN0YXRlQmxvY2stPnBJbmRleERhdGE7CiAgICBpZiAoIXBJQikgewogICAgICAgIC8qIEQzRDkgcmV0dXJucyBEM0RFUlJfSU5WQUxJRENBTEwgd2hlbiBEcmF3SW5kZXhlZFByaW1pdGl2ZSBpcyBjYWxsZWQKICAgICAgICAgKiB3aXRob3V0IGFuIGluZGV4IGJ1ZmZlciBzZXQuIChUaGUgZmlyc3QgdGltZSBhdCBsZWFzdC4uLikKICAgICAgICAgKiBEM0Q4IHNpbXBseSBkaWVzLCBidXQgSSBkb3VidCBpdCBjYW4gZG8gbXVjaCBoYXJtIHRvIHJldHVybgogICAgICAgICAqIEQzREVSUl9JTlZBTElEQ0FMTCB0aGVyZSBhcyB3ZWxsLiAqLwogICAgICAgIEVSUigiKCVwKSA6IENhbGxlZCB3aXRob3V0IGEgdmFsaWQgaW5kZXggYnVmZmVyIHNldCwgcmV0dXJuaW5nIFdJTkVEM0RFUlJfSU5WQUxJRENBTExcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmKCFUaGlzLT5zdGF0ZUJsb2NrLT52ZXJ0ZXhEZWNsKSB7CiAgICAgICAgV0FSTigiKCVwKSA6IENhbGxlZCB3aXRob3V0IGEgdmFsaWQgdmVydGV4IGRlY2xhcmF0aW9uIHNldFxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYoVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtSXNVUCkgewogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9JTkRFWEJVRkZFUik7CiAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtSXNVUCA9IEZBTFNFOwogICAgfQogICAgdmJvID0gKChJV2luZUQzREluZGV4QnVmZmVySW1wbCAqKSBwSUIpLT52Ym87CgogICAgVFJBQ0UoIiglcCkgOiBUeXBlPSglZCwlcyksIG1pbj0lZCwgQ291bnRWPSVkLCBzdGFydElkeD0lZCwgY291bnRQPSVkXG4iLCBUaGlzLAogICAgICAgICAgUHJpbWl0aXZlVHlwZSwgZGVidWdfZDNkcHJpbWl0aXZldHlwZShQcmltaXRpdmVUeXBlKSwKICAgICAgICAgIG1pbkluZGV4LCBOdW1WZXJ0aWNlcywgc3RhcnRJbmRleCwgcHJpbUNvdW50KTsKCiAgICBJV2luZUQzREluZGV4QnVmZmVyX0dldERlc2MocElCLCAmSWR4QnVmRHNjKTsKICAgIGlmIChJZHhCdWZEc2MuRm9ybWF0ID09IFdJTkVEM0RGTVRfSU5ERVgxNikgewogICAgICAgIGlkeFN0cmlkZSA9IDI7CiAgICB9IGVsc2UgewogICAgICAgIGlkeFN0cmlkZSA9IDQ7CiAgICB9CgogICAgaWYoVGhpcy0+c3RhdGVCbG9jay0+bG9hZEJhc2VWZXJ0ZXhJbmRleCAhPSBUaGlzLT5zdGF0ZUJsb2NrLT5iYXNlVmVydGV4SW5kZXgpIHsKICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5sb2FkQmFzZVZlcnRleEluZGV4ID0gVGhpcy0+c3RhdGVCbG9jay0+YmFzZVZlcnRleEluZGV4OwogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TVFJFQU1TUkMpOwogICAgfQoKICAgIGRyYXdQcmltaXRpdmUoaWZhY2UsIFByaW1pdGl2ZVR5cGUsIHByaW1Db3VudCwgMCwgTnVtVmVydGljZXMsIHN0YXJ0SW5kZXgsCiAgICAgICAgICAgICAgICAgICBpZHhTdHJpZGUsIHZibyA/IE5VTEwgOiAoKElXaW5lRDNESW5kZXhCdWZmZXJJbXBsICopIHBJQiktPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwgbWluSW5kZXgpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdQcmltaXRpdmVVUChJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFByaW1pdGl2ZUNvdW50LCBDT05TVCB2b2lkKiBwVmVydGV4U3RyZWFtWmVyb0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFZlcnRleFN0cmVhbVplcm9TdHJpZGUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEVmVydGV4QnVmZmVyICp2YjsKCiAgICBUUkFDRSgiKCVwKSA6IFR5cGU9KCVkLCVzKSwgcENvdW50PSVkLCBwVnR4RGF0YT0lcCwgU3RyaWRlPSVkXG4iLCBUaGlzLCBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgZGVidWdfZDNkcHJpbWl0aXZldHlwZShQcmltaXRpdmVUeXBlKSwKICAgICAgICAgICAgIFByaW1pdGl2ZUNvdW50LCBwVmVydGV4U3RyZWFtWmVyb0RhdGEsIFZlcnRleFN0cmVhbVplcm9TdHJpZGUpOwoKICAgIGlmKCFUaGlzLT5zdGF0ZUJsb2NrLT52ZXJ0ZXhEZWNsKSB7CiAgICAgICAgV0FSTigiKCVwKSA6IENhbGxlZCB3aXRob3V0IGEgdmFsaWQgdmVydGV4IGRlY2xhcmF0aW9uIHNldFxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogTm90ZSBpbiB0aGUgZm9sbG93aW5nLCBpdCdzIG5vdCB0aGlzIHR5cGUsIGJ1dCB0aGF0J3MgdGhlIHB1cnBvc2Ugb2Ygc3RyZWFtSXNVUCAqLwogICAgdmIgPSBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbMF07CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbMF0gPSAoSVdpbmVEM0RWZXJ0ZXhCdWZmZXIgKilwVmVydGV4U3RyZWFtWmVyb0RhdGE7CiAgICBpZih2YikgSVdpbmVEM0RWZXJ0ZXhCdWZmZXJfUmVsZWFzZSh2Yik7CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1PZmZzZXRbMF0gPSAwOwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU3RyaWRlWzBdID0gVmVydGV4U3RyZWFtWmVyb1N0cmlkZTsKICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbUlzVVAgPSBUUlVFOwogICAgVGhpcy0+c3RhdGVCbG9jay0+bG9hZEJhc2VWZXJ0ZXhJbmRleCA9IDA7CgogICAgLyogVE9ETzogT25seSBtYXJrIGRpcnR5IGlmIGRyYXdpbmcgZnJvbSBhIGRpZmZlcmVudCBVUCBhZGRyZXNzICovCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfU1RSRUFNU1JDKTsKCiAgICBkcmF3UHJpbWl0aXZlKGlmYWNlLCBQcmltaXRpdmVUeXBlLCBQcmltaXRpdmVDb3VudCwgMCAvKiBzdGFydCB2ZXJ0ZXggKi8sIDAgIC8qIE51bVZlcnRpY2VzICovLAogICAgICAgICAgICAgICAgICAwIC8qIGluZHhTdGFydCovLCAwIC8qIGluZHhTaXplKi8sIE5VTEwgLyogaW5keERhdGEgKi8sIDAgLyogaW5keE1pbiAqLyk7CgogICAgLyogTVNETiBzcGVjaWZpZXMgc3RyZWFtIHplcm8gc2V0dGluZ3MgbXVzdCBiZSBzZXQgdG8gTlVMTCAqLwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU3RyaWRlWzBdID0gMDsKICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVswXSA9IE5VTEw7CgogICAgLyogc3RyZWFtIHplcm8gc2V0dGluZ3Mgc2V0IHRvIG51bGwgYXQgZW5kLCBhcyBwZXIgdGhlIG1zZG4uIE5vIG5lZWQgdG8gbWFyayBkaXJ0eSBoZXJlLCB0aGUgYXBwIGhhcyB0byBzZXQKICAgICAqIHRoZSBuZXcgc3RyZWFtIHNvdXJjZXMgb3IgdXNlIFVQIGRyYXdpbmcgYWdhaW4KICAgICAqLwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfRHJhd0luZGV4ZWRQcmltaXRpdmVVUChJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIE1pblZlcnRleEluZGV4LCBVSU5UIE51bVZlcnRpY2VzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBQcmltaXRpdmVDb3VudCwgQ09OU1Qgdm9pZCogcEluZGV4RGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RGT1JNQVQgSW5kZXhEYXRhRm9ybWF0LENPTlNUIHZvaWQqIHBWZXJ0ZXhTdHJlYW1aZXJvRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgVmVydGV4U3RyZWFtWmVyb1N0cmlkZSkgewogICAgaW50ICAgICAgICAgICAgICAgICBpZHhTdHJpZGU7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFZlcnRleEJ1ZmZlciAqdmI7CiAgICBJV2luZUQzREluZGV4QnVmZmVyICppYjsKCiAgICBUUkFDRSgiKCVwKSA6IFR5cGU9KCVkLCVzKSwgTWluVnR4SWR4PSVkLCBOdW1WSWR4PSVkLCBQQ291bnQ9JWQsIHBpZHhkYXRhPSVwLCBJZHhGbXQ9JWQsIHBWdHhkYXRhPSVwLCBzdHJpZGU9JWRcbiIsCiAgICAgICAgICAgICBUaGlzLCBQcmltaXRpdmVUeXBlLCBkZWJ1Z19kM2RwcmltaXRpdmV0eXBlKFByaW1pdGl2ZVR5cGUpLAogICAgICAgICAgICAgTWluVmVydGV4SW5kZXgsIE51bVZlcnRpY2VzLCBQcmltaXRpdmVDb3VudCwgcEluZGV4RGF0YSwKICAgICAgICAgICAgIEluZGV4RGF0YUZvcm1hdCwgcFZlcnRleFN0cmVhbVplcm9EYXRhLCBWZXJ0ZXhTdHJlYW1aZXJvU3RyaWRlKTsKCiAgICBpZighVGhpcy0+c3RhdGVCbG9jay0+dmVydGV4RGVjbCkgewogICAgICAgIFdBUk4oIiglcCkgOiBDYWxsZWQgd2l0aG91dCBhIHZhbGlkIHZlcnRleCBkZWNsYXJhdGlvbiBzZXRcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmIChJbmRleERhdGFGb3JtYXQgPT0gV0lORUQzREZNVF9JTkRFWDE2KSB7CiAgICAgICAgaWR4U3RyaWRlID0gMjsKICAgIH0gZWxzZSB7CiAgICAgICAgaWR4U3RyaWRlID0gNDsKICAgIH0KCiAgICAvKiBOb3RlIGluIHRoZSBmb2xsb3dpbmcsIGl0J3Mgbm90IHRoaXMgdHlwZSwgYnV0IHRoYXQncyB0aGUgcHVycG9zZSBvZiBzdHJlYW1Jc1VQICovCiAgICB2YiA9IFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVswXTsKICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVswXSA9IChJV2luZUQzRFZlcnRleEJ1ZmZlciAqKXBWZXJ0ZXhTdHJlYW1aZXJvRGF0YTsKICAgIGlmKHZiKSBJV2luZUQzRFZlcnRleEJ1ZmZlcl9SZWxlYXNlKHZiKTsKICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbUlzVVAgPSBUUlVFOwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtT2Zmc2V0WzBdID0gMDsKICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVN0cmlkZVswXSA9IFZlcnRleFN0cmVhbVplcm9TdHJpZGU7CgogICAgLyogU2V0IHRvIDAgYXMgcGVyIG1zZG4uIERvIGl0IG5vdyBkdWUgdG8gdGhlIHN0cmVhbSBzb3VyY2UgbG9hZGluZyBkdXJpbmcgZHJhd1ByaW1pdGl2ZSAqLwogICAgVGhpcy0+c3RhdGVCbG9jay0+YmFzZVZlcnRleEluZGV4ID0gMDsKICAgIFRoaXMtPnN0YXRlQmxvY2stPmxvYWRCYXNlVmVydGV4SW5kZXggPSAwOwogICAgLyogTWFyayB0aGUgc3RhdGUgZGlydHkgdW50aWwgd2UgaGF2ZSBuaWNlciB0cmFja2luZyBvZiB0aGUgc3RyZWFtIHNvdXJjZSBwb2ludGVycyAqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1ZERUNMKTsKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9JTkRFWEJVRkZFUik7CgogICAgZHJhd1ByaW1pdGl2ZShpZmFjZSwgUHJpbWl0aXZlVHlwZSwgUHJpbWl0aXZlQ291bnQsIDAgLyogdmVydGV4U3RhcnQgKi8sIE51bVZlcnRpY2VzLCAwIC8qIGluZHhTdGFydCAqLywgaWR4U3RyaWRlLCBwSW5kZXhEYXRhLCBNaW5WZXJ0ZXhJbmRleCk7CgogICAgLyogTVNETiBzcGVjaWZpZXMgc3RyZWFtIHplcm8gc2V0dGluZ3MgYW5kIGluZGV4IGJ1ZmZlciBtdXN0IGJlIHNldCB0byBOVUxMICovCiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbMF0gPSBOVUxMOwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU3RyaWRlWzBdID0gMDsKICAgIGliID0gVGhpcy0+c3RhdGVCbG9jay0+cEluZGV4RGF0YTsKICAgIGlmKGliKSB7CiAgICAgICAgSVdpbmVEM0RJbmRleEJ1ZmZlcl9SZWxlYXNlKGliKTsKICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5wSW5kZXhEYXRhID0gTlVMTDsKICAgIH0KICAgIC8qIE5vIG5lZWQgdG8gbWFyayB0aGUgc3RyZWFtIHNvdXJjZSBzdGF0ZSBkaXJ0eSBoZXJlLiBFaXRoZXIgdGhlIGFwcCBjYWxscyBVUCBkcmF3aW5nIGFnYWluLCBvciBpdCBoYXMgdG8gY2FsbAogICAgICogU2V0U3RyZWFtU291cmNlIHRvIHNwZWNpZnkgYSB2ZXJ0ZXggYnVmZmVyCiAgICAgKi8KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3UHJpbWl0aXZlU3RyaWRlZCAoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLCBVSU5UIFByaW1pdGl2ZUNvdW50LCBXaW5lRGlyZWN0M0RWZXJ0ZXhTdHJpZGVkRGF0YSAqRHJhd1ByaW1TdHJpZGVEYXRhKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwoKICAgIC8qIE1hcmsgdGhlIHN0YXRlIGRpcnR5IHVudGlsIHdlIGhhdmUgbmljZXIgdHJhY2tpbmcKICAgICAqIGl0cyBmaW5lIHRvIGNoYW5nZSBiYXNlVmVydGV4SW5kZXggYmVjYXVzZSB0aGF0IGNhbGwgaXMgb25seSBjYWxsZWQgYnkgZGRyYXcgd2hpY2ggZG9lcyBub3QgbmVlZAogICAgICogdGhhdCB2YWx1ZS4KICAgICAqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1ZERUNMKTsKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9JTkRFWEJVRkZFUik7CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5iYXNlVmVydGV4SW5kZXggPSAwOwogICAgVGhpcy0+dXBfc3RyaWRlZCA9IERyYXdQcmltU3RyaWRlRGF0YTsKICAgIGRyYXdQcmltaXRpdmUoaWZhY2UsIFByaW1pdGl2ZVR5cGUsIFByaW1pdGl2ZUNvdW50LCAwLCAwLCAwLCAwLCBOVUxMLCAwKTsKICAgIFRoaXMtPnVwX3N0cmlkZWQgPSBOVUxMOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfRHJhd0luZGV4ZWRQcmltaXRpdmVTdHJpZGVkKElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRFBSSU1JVElWRVRZUEUgUHJpbWl0aXZlVHlwZSwgVUlOVCBQcmltaXRpdmVDb3VudCwgV2luZURpcmVjdDNEVmVydGV4U3RyaWRlZERhdGEgKkRyYXdQcmltU3RyaWRlRGF0YSwgVUlOVCBOdW1WZXJ0aWNlcywgQ09OU1Qgdm9pZCAqcEluZGV4RGF0YSwgV0lORUQzREZPUk1BVCBJbmRleERhdGFGb3JtYXQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBEV09SRCBpZHhTaXplID0gKEluZGV4RGF0YUZvcm1hdCA9PSBXSU5FRDNERk1UX0lOREVYMzIgPyA0IDogMik7CgogICAgLyogTWFyayB0aGUgc3RhdGUgZGlydHkgdW50aWwgd2UgaGF2ZSBuaWNlciB0cmFja2luZwogICAgICogaXRzIGZpbmUgdG8gY2hhbmdlIGJhc2VWZXJ0ZXhJbmRleCBiZWNhdXNlIHRoYXQgY2FsbCBpcyBvbmx5IGNhbGxlZCBieSBkZHJhdyB3aGljaCBkb2VzIG5vdCBuZWVkCiAgICAgKiB0aGF0IHZhbHVlLgogICAgICovCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVkRFQ0wpOwogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX0lOREVYQlVGRkVSKTsKICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbUlzVVAgPSBUUlVFOwogICAgVGhpcy0+c3RhdGVCbG9jay0+YmFzZVZlcnRleEluZGV4ID0gMDsKICAgIFRoaXMtPnVwX3N0cmlkZWQgPSBEcmF3UHJpbVN0cmlkZURhdGE7CiAgICBkcmF3UHJpbWl0aXZlKGlmYWNlLCBQcmltaXRpdmVUeXBlLCBQcmltaXRpdmVDb3VudCwgMCAvKiBzdGFydHZlcnRleGlkeCAqLywgMCAvKiBudW1pbmRpY2VzICovLCAwIC8qIHN0YXJ0aWR4ICovLCBpZHhTaXplLCBwSW5kZXhEYXRhLCAwIC8qIG1pbmluZGV4ICovKTsKICAgIFRoaXMtPnVwX3N0cmlkZWQgPSBOVUxMOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIElXaW5lRDNERGV2aWNlSW1wbF9VcGRhdGVWb2x1bWUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFZvbHVtZSAqcFNvdXJjZVZvbHVtZSwgSVdpbmVEM0RWb2x1bWUgKnBEZXN0aW5hdGlvblZvbHVtZSkgewogICAgLyogVGhpcyBpcyBhIGhlbHBlciBmdW5jdGlvbiBmb3IgVXBkYXRlVGV4dHVyZSwgdGhlcmUgaXMgbm8gcHVibGljIFVwZGF0ZVZvbHVtZSBtZXRob2QgaW4gZDNkLiBTaW5jZSBpdCdzCiAgICAgKiBub3QgY2FsbGFibGUgYnkgdGhlIGFwcCBkaXJlY3RseSBubyBwYXJhbWV0ZXIgdmFsaWRhdGlvbiBjaGVja3MgYXJlIG5lZWRlZCBoZXJlLgogICAgICovCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgV0lORUQzRExPQ0tFRF9CT1ggc3JjOwogICAgV0lORUQzRExPQ0tFRF9CT1ggZHN0OwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJXAsICVwKVxuIiwgVGhpcywgcFNvdXJjZVZvbHVtZSwgcERlc3RpbmF0aW9uVm9sdW1lKTsKCiAgICAvKiBUT0RPOiBJbXBsZW1lbnQgZGlyZWN0IGxvYWRpbmcgaW50byB0aGUgZ2wgdm9sdW1lIGluc3RlYWQgb2YgdXNpbmcgbWVtY3B5IGFuZAogICAgICogZGlydGlmaWNhdGlvbiB0byBpbXByb3ZlIGxvYWRpbmcgcGVyZm9ybWFuY2UuCiAgICAgKi8KICAgIGhyID0gSVdpbmVEM0RWb2x1bWVfTG9ja0JveChwU291cmNlVm9sdW1lLCAmc3JjLCBOVUxMLCBXSU5FRDNETE9DS19SRUFET05MWSk7CiAgICBpZihGQUlMRUQoaHIpKSByZXR1cm4gaHI7CiAgICBociA9IElXaW5lRDNEVm9sdW1lX0xvY2tCb3gocERlc3RpbmF0aW9uVm9sdW1lLCAmZHN0LCBOVUxMLCBXSU5FRDNETE9DS19ESVNDQVJEKTsKICAgIGlmKEZBSUxFRChocikpIHsKICAgIElXaW5lRDNEVm9sdW1lX1VubG9ja0JveChwU291cmNlVm9sdW1lKTsKICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIG1lbWNweShkc3QucEJpdHMsIHNyYy5wQml0cywgKChJV2luZUQzRFZvbHVtZUltcGwgKikgcERlc3RpbmF0aW9uVm9sdW1lKS0+cmVzb3VyY2Uuc2l6ZSk7CgogICAgaHIgPSBJV2luZUQzRFZvbHVtZV9VbmxvY2tCb3gocERlc3RpbmF0aW9uVm9sdW1lKTsKICAgIGlmKEZBSUxFRChocikpIHsKICAgICAgICBJV2luZUQzRFZvbHVtZV9VbmxvY2tCb3gocFNvdXJjZVZvbHVtZSk7CiAgICB9IGVsc2UgewogICAgICAgIGhyID0gSVdpbmVEM0RWb2x1bWVfVW5sb2NrQm94KHBTb3VyY2VWb2x1bWUpOwogICAgfQogICAgcmV0dXJuIGhyOwp9CgovKiBZZXQgYW5vdGhlciB3YXkgdG8gdXBkYXRlIGEgdGV4dHVyZSwgc29tZSBhcHBzIHVzZSB0aGlzIHRvIGxvYWQgZGVmYXVsdCB0ZXh0dXJlcyBpbnN0ZWFkIG9mIHVzaW5nIHN1cmZhY2UvdGV4dHVyZSBsb2NrL3VubG9jayAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1VwZGF0ZVRleHR1cmUgKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RCYXNlVGV4dHVyZSAqcFNvdXJjZVRleHR1cmUsICBJV2luZUQzREJhc2VUZXh0dXJlICpwRGVzdGluYXRpb25UZXh0dXJlKXsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIEhSRVNVTFQgaHIgPSBXSU5FRDNEX09LOwogICAgV0lORUQzRFJFU09VUkNFVFlQRSBzb3VyY2VUeXBlOwogICAgV0lORUQzRFJFU09VUkNFVFlQRSBkZXN0aW5hdGlvblR5cGU7CiAgICBpbnQgaSAsbGV2ZWxzOwoKICAgIC8qIFRPRE86IHRoaW5rIGFib3V0IG1vdmluZyB0aGUgY29kZSBpbnRvIElXaW5lRDNEQmFzZVRleHR1cmUgICovCgogICAgVFJBQ0UoIiglcCkgU291cmNlICVwIERlc3RpbmF0aW9uICVwXG4iLCBUaGlzLCBwU291cmNlVGV4dHVyZSwgcERlc3RpbmF0aW9uVGV4dHVyZSk7CgogICAgLyogdmVyaWZ5IHRoYXQgdGhlIHNvdXJjZSBhbmQgZGVzdGluYXRpb24gdGV4dHVyZXMgYXJlbid0IE5VTEwgKi8KICAgIGlmIChOVUxMID09IHBTb3VyY2VUZXh0dXJlIHx8IE5VTEwgPT0gcERlc3RpbmF0aW9uVGV4dHVyZSkgewogICAgICAgIFdBUk4oIiglcCkgOiBzb3VyY2UgKCVwKSBhbmQgZGVzdGluYXRpb24gKCVwKSB0ZXh0dXJlcyBtdXN0IG5vdCBiZSBOVUxMLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIiwKICAgICAgICAgICAgIFRoaXMsIHBTb3VyY2VUZXh0dXJlLCBwRGVzdGluYXRpb25UZXh0dXJlKTsKICAgICAgICBociA9IFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYgKHBTb3VyY2VUZXh0dXJlID09IHBEZXN0aW5hdGlvblRleHR1cmUpIHsKICAgICAgICBXQVJOKCIoJXApIDogc291cmNlICglcCkgYW5kIGRlc3RpbmF0aW9uICglcCkgdGV4dHVyZXMgbXVzdCBiZSBkaWZmZXJlbnQsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iLAogICAgICAgICAgICAgVGhpcywgcFNvdXJjZVRleHR1cmUsIHBEZXN0aW5hdGlvblRleHR1cmUpOwogICAgICAgIGhyID0gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIC8qIFZlcmlmeSB0aGF0IHRoZSBzb3VyY2UgYW5kIGRlc3RpbmF0aW9uIHRleHR1cmVzIGFyZSB0aGUgc2FtZSB0eXBlICovCiAgICBzb3VyY2VUeXBlICAgICAgPSBJV2luZUQzREJhc2VUZXh0dXJlX0dldFR5cGUocFNvdXJjZVRleHR1cmUpOwogICAgZGVzdGluYXRpb25UeXBlID0gSVdpbmVEM0RCYXNlVGV4dHVyZV9HZXRUeXBlKHBEZXN0aW5hdGlvblRleHR1cmUpOwoKICAgIGlmIChzb3VyY2VUeXBlICE9IGRlc3RpbmF0aW9uVHlwZSkgewogICAgICAgIFdBUk4oIiglcCkgU29yY2UgYW5kIGRlc3RpbmF0aW9uIHR5cGVzIG11c3QgbWF0Y2gsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iLAogICAgICAgICAgICAgVGhpcyk7CiAgICAgICAgaHIgPSBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIC8qIGNoZWNrIHRoYXQgYm90aCB0ZXh0dXJlcyBoYXZlIHRoZSBpZGVudGljYWwgbnVtYmVycyBvZiBsZXZlbHMgICovCiAgICBpZiAoSVdpbmVEM0RCYXNlVGV4dHVyZV9HZXRMZXZlbENvdW50KHBEZXN0aW5hdGlvblRleHR1cmUpICAhPSBJV2luZUQzREJhc2VUZXh0dXJlX0dldExldmVsQ291bnQocFNvdXJjZVRleHR1cmUpKSB7CiAgICAgICAgV0FSTigiKCVwKSA6IHNvdXJjZSAoJXApIGFuZCBkZXN0aW5hdGlvbiAoJXApIHRleHR1cmVzIG11c3QgaGF2ZSBpZGVudGljYWwgbnVtYmVycyBvZiBsZXZlbHMsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iLCBUaGlzLCBwU291cmNlVGV4dHVyZSwgcERlc3RpbmF0aW9uVGV4dHVyZSk7CiAgICAgICAgaHIgPSBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmIChXSU5FRDNEX09LID09IGhyKSB7CgogICAgICAgIC8qIE1ha2Ugc3VyZSB0aGF0IHRoZSBkZXN0aW5hdGlvbiB0ZXh0dXJlIGlzIGxvYWRlZCAqLwogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUHJlTG9hZChwRGVzdGluYXRpb25UZXh0dXJlKTsKCiAgICAgICAgLyogVXBkYXRlIGV2ZXJ5IHN1cmZhY2UgbGV2ZWwgb2YgdGhlIHRleHR1cmUgKi8KICAgICAgICBsZXZlbHMgPSBJV2luZUQzREJhc2VUZXh0dXJlX0dldExldmVsQ291bnQocERlc3RpbmF0aW9uVGV4dHVyZSk7CgogICAgICAgIHN3aXRjaCAoc291cmNlVHlwZSkgewogICAgICAgIGNhc2UgV0lORUQzRFJUWVBFX1RFWFRVUkU6CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSAqc3JjU3VyZmFjZTsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSAqZGVzdFN1cmZhY2U7CgogICAgICAgICAgICAgICAgZm9yIChpID0gMCA7IGkgPCBsZXZlbHMgOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFRleHR1cmVfR2V0U3VyZmFjZUxldmVsKChJV2luZUQzRFRleHR1cmUgKilwU291cmNlVGV4dHVyZSwgICAgICBpLCAmc3JjU3VyZmFjZSk7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RUZXh0dXJlX0dldFN1cmZhY2VMZXZlbCgoSVdpbmVEM0RUZXh0dXJlICopcERlc3RpbmF0aW9uVGV4dHVyZSwgaSwgJmRlc3RTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX1VwZGF0ZVN1cmZhY2UoaWZhY2UsIHNyY1N1cmZhY2UsIE5VTEwsIGRlc3RTdXJmYWNlLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShzcmNTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShkZXN0U3VyZmFjZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKFdJTkVEM0RfT0sgIT0gaHIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgV0FSTigiKCVwKSA6IENhbGwgdG8gdXBkYXRlIHN1cmZhY2UgZmFpbGVkXG4iLCBUaGlzKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9DVUJFVEVYVFVSRToKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlICpzcmNTdXJmYWNlOwogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlICpkZXN0U3VyZmFjZTsKICAgICAgICAgICAgICAgIFdJTkVEM0RDVUJFTUFQX0ZBQ0VTIGZhY2VUeXBlOwoKICAgICAgICAgICAgICAgIGZvciAoaSA9IDAgOyBpIDwgbGV2ZWxzIDsgKytpKSB7CiAgICAgICAgICAgICAgICAgICAgLyogVXBkYXRlIGVhY2ggY3ViZSBmYWNlICovCiAgICAgICAgICAgICAgICAgICAgZm9yIChmYWNlVHlwZSA9IFdJTkVEM0RDVUJFTUFQX0ZBQ0VfUE9TSVRJVkVfWDsgZmFjZVR5cGUgPD0gV0lORUQzRENVQkVNQVBfRkFDRV9ORUdBVElWRV9aOyArK2ZhY2VUeXBlKXsKICAgICAgICAgICAgICAgICAgICAgICAgaHIgPSBJV2luZUQzREN1YmVUZXh0dXJlX0dldEN1YmVNYXBTdXJmYWNlKChJV2luZUQzREN1YmVUZXh0dXJlICopcFNvdXJjZVRleHR1cmUsICAgICAgZmFjZVR5cGUsIGksICZzcmNTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFdJTkVEM0RfT0sgIT0gaHIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWE1FKCIoJXApIDogRmFpbGVkIHRvIGdldCBzcmMgY3ViZSBzdXJmYWNlIGZhY2V0eXBlICVkLCBsZXZlbCAlZFxuIiwgVGhpcywgZmFjZVR5cGUsIGkpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIkdvdCBzcmNTdXJmYWNlICVwXG4iLCBzcmNTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBociA9IElXaW5lRDNEQ3ViZVRleHR1cmVfR2V0Q3ViZU1hcFN1cmZhY2UoKElXaW5lRDNEQ3ViZVRleHR1cmUgKilwRGVzdGluYXRpb25UZXh0dXJlLCBmYWNlVHlwZSwgaSwgJmRlc3RTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFdJTkVEM0RfT0sgIT0gaHIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWE1FKCIoJXApIDogRmFpbGVkIHRvIGdldCBzcmMgY3ViZSBzdXJmYWNlIGZhY2V0eXBlICVkLCBsZXZlbCAlZFxuIiwgVGhpcywgZmFjZVR5cGUsIGkpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIkdvdCBkZXNyU3VyZmFjZSAlcFxuIiwgZGVzdFN1cmZhY2UpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGhyID0gSVdpbmVEM0REZXZpY2VfVXBkYXRlU3VyZmFjZShpZmFjZSwgc3JjU3VyZmFjZSwgTlVMTCwgZGVzdFN1cmZhY2UsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShzcmNTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2UoZGVzdFN1cmZhY2UpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoV0lORUQzRF9PSyAhPSBocikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgV0FSTigiKCVwKSA6IENhbGwgdG8gdXBkYXRlIHN1cmZhY2UgZmFpbGVkXG4iLCBUaGlzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBocjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNEUlRZUEVfVk9MVU1FVEVYVFVSRToKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSVdpbmVEM0RWb2x1bWUgICpzcmNWb2x1bWUgID0gTlVMTDsKICAgICAgICAgICAgICAgIElXaW5lRDNEVm9sdW1lICAqZGVzdFZvbHVtZSA9IE5VTEw7CgogICAgICAgICAgICAgICAgZm9yIChpID0gMCA7IGkgPCBsZXZlbHMgOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFZvbHVtZVRleHR1cmVfR2V0Vm9sdW1lTGV2ZWwoKElXaW5lRDNEVm9sdW1lVGV4dHVyZSAqKXBTb3VyY2VUZXh0dXJlLCAgICAgIGksICZzcmNWb2x1bWUpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNEVm9sdW1lVGV4dHVyZV9HZXRWb2x1bWVMZXZlbCgoSVdpbmVEM0RWb2x1bWVUZXh0dXJlICopcERlc3RpbmF0aW9uVGV4dHVyZSwgaSwgJmRlc3RWb2x1bWUpOwogICAgICAgICAgICAgICAgICAgIGhyID0gIElXaW5lRDNERGV2aWNlSW1wbF9VcGRhdGVWb2x1bWUoaWZhY2UsIHNyY1ZvbHVtZSwgZGVzdFZvbHVtZSk7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RWb2x1bWVfUmVsZWFzZShzcmNWb2x1bWUpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNEVm9sdW1lX1JlbGVhc2UoZGVzdFZvbHVtZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKFdJTkVEM0RfT0sgIT0gaHIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgV0FSTigiKCVwKSA6IENhbGwgdG8gdXBkYXRlIHZvbHVtZSBmYWlsZWRcbiIsIFRoaXMpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaHI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBGSVhNRSgiKCVwKSA6IFVuc3VwcG9ydGVkIHNvdXJjZSBhbmQgZGVzdGluYXRpb24gdHlwZVxuIiwgVGhpcyk7CiAgICAgICAgICAgIGhyID0gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfR2V0RnJvbnRCdWZmZXJEYXRhKElXaW5lRDNERGV2aWNlICppZmFjZSxVSU5UIGlTd2FwQ2hhaW4sIElXaW5lRDNEU3VyZmFjZSAqcERlc3RTdXJmYWNlKSB7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcENoYWluOwogICAgSFJFU1VMVCBocjsKICAgIGhyID0gSVdpbmVEM0REZXZpY2VJbXBsX0dldFN3YXBDaGFpbihpZmFjZSwgaVN3YXBDaGFpbiwgJnN3YXBDaGFpbik7CiAgICBpZihociA9PSBXSU5FRDNEX09LKSB7CiAgICAgICAgaHIgPSBJV2luZUQzRFN3YXBDaGFpbl9HZXRGcm9udEJ1ZmZlckRhdGEoc3dhcENoYWluLCBwRGVzdFN1cmZhY2UpOwogICAgICAgICAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwQ2hhaW4pOwogICAgfQogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfVmFsaWRhdGVEZXZpY2UoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCogcE51bVBhc3NlcykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgLyogcmV0dXJuIGEgc2Vuc2libGUgZGVmYXVsdCAqLwogICAgKnBOdW1QYXNzZXMgPSAxOwogICAgLyogVE9ETzogSWYgdGhlIHdpbmRvdyBpcyBtaW5pbWl6ZWQgdGhlbiB2YWxpZGF0ZSBkZXZpY2Ugc2hvdWxkIHJldHVybiBzb21ldGhpbmcgb3RoZXIgdGhhbiBXSU5FRDNEX09LICovCiAgICBGSVhNRSgiKCVwKSA6IHN0dWJcbiIsIFRoaXMpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyB2b2lkIGRpcnRpZnlfcDhfdGV4dHVyZV9zYW1wbGVycyhJV2luZUQzRERldmljZUltcGwgKmRldmljZSkKewogICAgaW50IGk7CgogICAgZm9yIChpID0gMDsgaSA8IE1BWF9DT01CSU5FRF9TQU1QTEVSUzsgaSsrKSB7CiAgICAgICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsICp0ZXh0dXJlID0gKElXaW5lRDNEQmFzZVRleHR1cmVJbXBsKilkZXZpY2UtPnN0YXRlQmxvY2stPnRleHR1cmVzW2ldOwogICAgICAgICAgICBpZiAodGV4dHVyZSAmJiAodGV4dHVyZS0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfUDggfHwgdGV4dHVyZS0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfQThQOCkpIHsKICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShkZXZpY2UsIFNUQVRFX1NBTVBMRVIoaSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfU2V0UGFsZXR0ZUVudHJpZXMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIFBhbGV0dGVOdW1iZXIsIENPTlNUIFBBTEVUVEVFTlRSWSogcEVudHJpZXMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIGludCBqOwogICAgVUlOVCBOZXdTaXplOwogICAgUEFMRVRURUVOVFJZICoqcGFsZXR0ZXM7CgogICAgVFJBQ0UoIiglcCkgOiBQYWxldHRlTnVtYmVyICV1XG4iLCBUaGlzLCBQYWxldHRlTnVtYmVyKTsKCiAgICBpZiAoUGFsZXR0ZU51bWJlciA+PSBNQVhfUEFMRVRURVMpIHsKICAgICAgICBFUlIoIiglcCkgOiAoJXUpIE91dCBvZiByYW5nZSAwLSV1LCByZXR1cm5pbmcgSW52YWxpZCBDYWxsXG4iLCBUaGlzLCBQYWxldHRlTnVtYmVyLCBNQVhfUEFMRVRURVMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmIChQYWxldHRlTnVtYmVyID49IFRoaXMtPk51bWJlck9mUGFsZXR0ZXMpIHsKICAgICAgICBOZXdTaXplID0gVGhpcy0+TnVtYmVyT2ZQYWxldHRlczsKICAgICAgICBkbyB7CiAgICAgICAgICAgTmV3U2l6ZSAqPSAyOwogICAgICAgIH0gd2hpbGUoUGFsZXR0ZU51bWJlciA+PSBOZXdTaXplKTsKICAgICAgICBwYWxldHRlcyA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIFRoaXMtPnBhbGV0dGVzLCBzaXplb2YoUEFMRVRURUVOVFJZKikgKiBOZXdTaXplKTsKICAgICAgICBpZiAoIXBhbGV0dGVzKSB7CiAgICAgICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeSFcbiIpOwogICAgICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgICAgICB9CiAgICAgICAgVGhpcy0+cGFsZXR0ZXMgPSBwYWxldHRlczsKICAgICAgICBUaGlzLT5OdW1iZXJPZlBhbGV0dGVzID0gTmV3U2l6ZTsKICAgIH0KCiAgICBpZiAoIVRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdKSB7CiAgICAgICAgVGhpcy0+cGFsZXR0ZXNbUGFsZXR0ZU51bWJlcl0gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgIDAsIHNpemVvZihQQUxFVFRFRU5UUlkpICogMjU2KTsKICAgICAgICBpZiAoIVRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdKSB7CiAgICAgICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeSFcbiIpOwogICAgICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgICAgICB9CiAgICB9CgogICAgZm9yIChqID0gMDsgaiA8IDI1NjsgKytqKSB7CiAgICAgICAgVGhpcy0+cGFsZXR0ZXNbUGFsZXR0ZU51bWJlcl1bal0ucGVSZWQgICA9IHBFbnRyaWVzW2pdLnBlUmVkOwogICAgICAgIFRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdW2pdLnBlR3JlZW4gPSBwRW50cmllc1tqXS5wZUdyZWVuOwogICAgICAgIFRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdW2pdLnBlQmx1ZSAgPSBwRW50cmllc1tqXS5wZUJsdWU7CiAgICAgICAgVGhpcy0+cGFsZXR0ZXNbUGFsZXR0ZU51bWJlcl1bal0ucGVGbGFncyA9IHBFbnRyaWVzW2pdLnBlRmxhZ3M7CiAgICB9CiAgICBpZiAoUGFsZXR0ZU51bWJlciA9PSBUaGlzLT5jdXJyZW50UGFsZXR0ZSkgZGlydGlmeV9wOF90ZXh0dXJlX3NhbXBsZXJzKFRoaXMpOwogICAgVFJBQ0UoIiglcCkgOiByZXR1cm5pbmdcbiIsIFRoaXMpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQYWxldHRlRW50cmllcyhJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgUGFsZXR0ZU51bWJlciwgUEFMRVRURUVOVFJZKiBwRW50cmllcykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaW50IGo7CiAgICBUUkFDRSgiKCVwKSA6IFBhbGV0dGVOdW1iZXIgJXVcbiIsIFRoaXMsIFBhbGV0dGVOdW1iZXIpOwogICAgaWYgKFBhbGV0dGVOdW1iZXIgPj0gVGhpcy0+TnVtYmVyT2ZQYWxldHRlcyB8fCAhVGhpcy0+cGFsZXR0ZXNbUGFsZXR0ZU51bWJlcl0pIHsKICAgICAgICAvKiBXaGF0IGhhcHBlbnMgaW4gc3VjaCBzaXR1YXRpb24gaXNuJ3QgZG9jdW1lbnRlZDsgTmF0aXZlIHNlZW1zIHRvIHNpbGVudGx5IGFib3J0CiAgICAgICAgICAgb24gc3VjaCBjb25kaXRpb25zLiBSZXR1cm4gSW52YWxpZCBDYWxsLiAqLwogICAgICAgIEVSUigiKCVwKSA6ICgldSkgTm9uZXhpc3RlbnQgcGFsZXR0ZS4gTnVtYmVyT2ZQYWxldHRlcyAldVxuIiwgVGhpcywgUGFsZXR0ZU51bWJlciwgVGhpcy0+TnVtYmVyT2ZQYWxldHRlcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICBmb3IgKGogPSAwOyBqIDwgMjU2OyArK2opIHsKICAgICAgICBwRW50cmllc1tqXS5wZVJlZCAgID0gVGhpcy0+cGFsZXR0ZXNbUGFsZXR0ZU51bWJlcl1bal0ucGVSZWQ7CiAgICAgICAgcEVudHJpZXNbal0ucGVHcmVlbiA9IFRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdW2pdLnBlR3JlZW47CiAgICAgICAgcEVudHJpZXNbal0ucGVCbHVlICA9IFRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdW2pdLnBlQmx1ZTsKICAgICAgICBwRW50cmllc1tqXS5wZUZsYWdzID0gVGhpcy0+cGFsZXR0ZXNbUGFsZXR0ZU51bWJlcl1bal0ucGVGbGFnczsKICAgIH0KICAgIFRSQUNFKCIoJXApIDogcmV0dXJuaW5nXG4iLCBUaGlzKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfU2V0Q3VycmVudFRleHR1cmVQYWxldHRlKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBQYWxldHRlTnVtYmVyKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IFBhbGV0dGVOdW1iZXIgJXVcbiIsIFRoaXMsIFBhbGV0dGVOdW1iZXIpOwogICAgLyogTmF0aXZlIGFwcGVhcnMgdG8gc2lsZW50bHkgYWJvcnQgb24gYXR0ZW1wdCB0byBtYWtlIGFuIHVuaW5pdGlhbGl6ZWQgcGFsZXR0ZSBjdXJyZW50IGFuZCByZW5kZXIuCiAgICAgICAodGVzdGVkIHdpdGggcmVmZXJlbmNlIHJhc3Rlcml6ZXIpLiBSZXR1cm4gSW52YWxpZCBDYWxsLiAqLwogICAgaWYgKFBhbGV0dGVOdW1iZXIgPj0gVGhpcy0+TnVtYmVyT2ZQYWxldHRlcyB8fCAhVGhpcy0+cGFsZXR0ZXNbUGFsZXR0ZU51bWJlcl0pIHsKICAgICAgICBFUlIoIiglcCkgOiAoJXUpIE5vbmV4aXN0ZW50IHBhbGV0dGUuIE51bWJlck9mUGFsZXR0ZXMgJXVcbiIsIFRoaXMsIFBhbGV0dGVOdW1iZXIsIFRoaXMtPk51bWJlck9mUGFsZXR0ZXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgLypUT0RPOiBzdGF0ZWJsb2NrcyAqLwogICAgaWYgKFRoaXMtPmN1cnJlbnRQYWxldHRlICE9IFBhbGV0dGVOdW1iZXIpIHsKICAgICAgICBUaGlzLT5jdXJyZW50UGFsZXR0ZSA9IFBhbGV0dGVOdW1iZXI7CiAgICAgICAgZGlydGlmeV9wOF90ZXh0dXJlX3NhbXBsZXJzKFRoaXMpOwogICAgfQogICAgVFJBQ0UoIiglcCkgOiByZXR1cm5pbmdcbiIsIFRoaXMpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRDdXJyZW50VGV4dHVyZVBhbGV0dGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UKiBQYWxldHRlTnVtYmVyKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpZiAoUGFsZXR0ZU51bWJlciA9PSBOVUxMKSB7CiAgICAgICAgV0FSTigiKCVwKSA6IHJldHVybmluZyBJbnZhbGlkIENhbGxcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgLypUT0RPOiBzdGF0ZWJsb2NrcyAqLwogICAgKlBhbGV0dGVOdW1iZXIgPSBUaGlzLT5jdXJyZW50UGFsZXR0ZTsKICAgIFRSQUNFKCIoJXApIDogcmV0dXJuaW5nICAldVxuIiwgVGhpcywgKlBhbGV0dGVOdW1iZXIpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRTb2Z0d2FyZVZlcnRleFByb2Nlc3NpbmcoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBCT09MIGJTb2Z0d2FyZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgc3RhdGljIEJPT0wgc2hvd0ZpeG1lcyA9IFRSVUU7CiAgICBpZiAoc2hvd0ZpeG1lcykgewogICAgICAgIEZJWE1FKCIoJXApIDogc3R1YlxuIiwgVGhpcyk7CiAgICAgICAgc2hvd0ZpeG1lcyA9IEZBTFNFOwogICAgfQoKICAgIFRoaXMtPnNvZnR3YXJlVmVydGV4UHJvY2Vzc2luZyA9IGJTb2Z0d2FyZTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgoKc3RhdGljIEJPT0wgICAgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFNvZnR3YXJlVmVydGV4UHJvY2Vzc2luZyhJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIHN0YXRpYyBCT09MIHNob3dGaXhtZXMgPSBUUlVFOwogICAgaWYgKHNob3dGaXhtZXMpIHsKICAgICAgICBGSVhNRSgiKCVwKSA6IHN0dWJcbiIsIFRoaXMpOwogICAgICAgIHNob3dGaXhtZXMgPSBGQUxTRTsKICAgIH0KICAgIHJldHVybiBUaGlzLT5zb2Z0d2FyZVZlcnRleFByb2Nlc3Npbmc7Cn0KCgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfR2V0UmFzdGVyU3RhdHVzKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBpU3dhcENoYWluLCBXSU5FRDNEUkFTVEVSX1NUQVRVUyogcFJhc3RlclN0YXR1cykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBDaGFpbjsKICAgIEhSRVNVTFQgaHI7CgogICAgVFJBQ0UoIiglcCkgOiAgU3dhcENoYWluICVkIHJldHVybmluZyAlcFxuIiwgVGhpcywgaVN3YXBDaGFpbiwgcFJhc3RlclN0YXR1cyk7CgogICAgaHIgPSBJV2luZUQzRERldmljZUltcGxfR2V0U3dhcENoYWluKGlmYWNlLCBpU3dhcENoYWluLCAmc3dhcENoYWluKTsKICAgIGlmKGhyID09IFdJTkVEM0RfT0spewogICAgICAgIGhyID0gSVdpbmVEM0RTd2FwQ2hhaW5fR2V0UmFzdGVyU3RhdHVzKHN3YXBDaGFpbiwgcFJhc3RlclN0YXR1cyk7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwQ2hhaW4pOwogICAgfWVsc2V7CiAgICAgICAgRklYTUUoIiglcCkgSVdpbmVEM0RTd2FwQ2hhaW5fR2V0UmFzdGVyU3RhdHVzIHJldHVybmVkIGluIGVycm9yXG4iLCBUaGlzKTsKICAgIH0KICAgIHJldHVybiBocjsKfQoKCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9TZXROUGF0Y2hNb2RlKElXaW5lRDNERGV2aWNlICppZmFjZSwgZmxvYXQgblNlZ21lbnRzKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBzdGF0aWMgQk9PTCBzaG93Zml4bWVzID0gVFJVRTsKICAgIGlmKG5TZWdtZW50cyAhPSAwLjBmKSB7CiAgICAgICAgaWYoIHNob3dmaXhtZXMpIHsKICAgICAgICAgICAgRklYTUUoIiglcCkgOiBzdHViIG5TZWdtZW50cyglZilcbiIsIFRoaXMsIG5TZWdtZW50cyk7CiAgICAgICAgICAgIHNob3dmaXhtZXMgPSBGQUxTRTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIGZsb2F0ICAgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0dldE5QYXRjaE1vZGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBzdGF0aWMgQk9PTCBzaG93Zml4bWVzID0gVFJVRTsKICAgIGlmKCBzaG93Zml4bWVzKSB7CiAgICAgICAgRklYTUUoIiglcCkgOiBzdHViIHJldHVybmluZyglZilcbiIsIFRoaXMsIDAuMGYpOwogICAgICAgIHNob3dmaXhtZXMgPSBGQUxTRTsKICAgIH0KICAgIHJldHVybiAwLjBmOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfVXBkYXRlU3VyZmFjZShJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEU3VyZmFjZSAqcFNvdXJjZVN1cmZhY2UsIENPTlNUIFJFQ1QqIHBTb3VyY2VSZWN0LCBJV2luZUQzRFN1cmZhY2UgKnBEZXN0aW5hdGlvblN1cmZhY2UsIENPTlNUIFBPSU5UKiBwRGVzdFBvaW50KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgICpUaGlzICAgICAgICAgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgLyoqIFRPRE86IHJlbW92ZSBjYXN0cyB0byBJV2luZUQzRFN1cmZhY2VJbXBsCiAgICAgKiAgICAgICBOT1RFOiBtb3ZlIGNvZGUgdG8gc3VyZmFjZSB0byBhY2NvbXBsaXNoIHRoaXMKICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKnBTcmNTdXJmYWNlICA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopcFNvdXJjZVN1cmZhY2U7CiAgICBpbnQgc3JjV2lkdGgsIHNyY0hlaWdodDsKICAgIHVuc2lnbmVkIGludCAgc3JjU3VyZmFjZVdpZHRoLCBzcmNTdXJmYWNlSGVpZ2h0LCBkZXN0U3VyZmFjZVdpZHRoLCBkZXN0U3VyZmFjZUhlaWdodDsKICAgIFdJTkVEM0RGT1JNQVQgZGVzdEZvcm1hdCwgc3JjRm9ybWF0OwogICAgVUlOVCAgICAgICAgICBkZXN0U2l6ZTsKICAgIGludCBzcmNMZWZ0LCBkZXN0TGVmdCwgZGVzdFRvcDsKICAgIFdJTkVEM0RQT09MICAgICAgIHNyY1Bvb2wsIGRlc3RQb29sOwogICAgaW50IG9mZnNldCAgICA9IDA7CiAgICBpbnQgcm93b2Zmc2V0ID0gMDsgLyogaG93IG1hbnkgYnl0ZXMgdG8gYWRkIG9udG8gdGhlIGVuZCBvZiBhIHJvdyB0byB3cmFwYXJvdW5kIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIG5leHQgKi8KICAgIGdsRGVzY3JpcHRvciAqZ2xEZXNjcmlwdGlvbiA9IE5VTEw7CiAgICBHTGVudW0gZHVtbXk7CiAgICBpbnQgYnBwOwogICAgQ09OVkVSVF9UWVBFUyBjb252ZXJ0ID0gTk9fQ09OVkVSU0lPTjsKCiAgICBXSU5FRDNEU1VSRkFDRV9ERVNDICB3aW5lZGVzYzsKCiAgICBUUkFDRSgiKCVwKSA6IFNvdXJjZSAoJXApICBSZWN0ICglcCkgRGVzdGluYXRpb24gKCVwKSBQb2ludCglcClcbiIsIFRoaXMsIHBTb3VyY2VTdXJmYWNlLCBwU291cmNlUmVjdCwgcERlc3RpbmF0aW9uU3VyZmFjZSwgcERlc3RQb2ludCk7CiAgICBtZW1zZXQoJndpbmVkZXNjLCAwLCBzaXplb2Yod2luZWRlc2MpKTsKICAgIHdpbmVkZXNjLldpZHRoICA9ICZzcmNTdXJmYWNlV2lkdGg7CiAgICB3aW5lZGVzYy5IZWlnaHQgPSAmc3JjU3VyZmFjZUhlaWdodDsKICAgIHdpbmVkZXNjLlBvb2wgICA9ICZzcmNQb29sOwogICAgd2luZWRlc2MuRm9ybWF0ID0gJnNyY0Zvcm1hdDsKCiAgICBJV2luZUQzRFN1cmZhY2VfR2V0RGVzYyhwU291cmNlU3VyZmFjZSwgJndpbmVkZXNjKTsKCiAgICB3aW5lZGVzYy5XaWR0aCAgPSAmZGVzdFN1cmZhY2VXaWR0aDsKICAgIHdpbmVkZXNjLkhlaWdodCA9ICZkZXN0U3VyZmFjZUhlaWdodDsKICAgIHdpbmVkZXNjLlBvb2wgICA9ICZkZXN0UG9vbDsKICAgIHdpbmVkZXNjLkZvcm1hdCA9ICZkZXN0Rm9ybWF0OwogICAgd2luZWRlc2MuU2l6ZSAgID0gJmRlc3RTaXplOwoKICAgIElXaW5lRDNEU3VyZmFjZV9HZXREZXNjKHBEZXN0aW5hdGlvblN1cmZhY2UsICZ3aW5lZGVzYyk7CgogICAgaWYoc3JjUG9vbCAhPSBXSU5FRDNEUE9PTF9TWVNURU1NRU0gIHx8IGRlc3RQb29sICE9IFdJTkVEM0RQT09MX0RFRkFVTFQpewogICAgICAgIFdBUk4oInNvdXJjZSAlcCBtdXN0IGJlIFNZU1RFTU1FTSBhbmQgZGVzdCAlcCBtdXN0IGJlIERFRkFVTFQsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iLCBwU291cmNlU3VyZmFjZSwgcERlc3RpbmF0aW9uU3VyZmFjZSk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogVGhpcyBjYWxsIGxvYWRzIHRoZSBvcGVuZ2wgc3VyZmFjZSBkaXJlY3RseSwgaW5zdGVhZCBvZiBjb3B5aW5nIHRoZSBzdXJmYWNlIHRvIHRoZQogICAgICogZGVzdGluYXRpb24ncyBzeXNtZW0gY29weS4gSWYgc3VyZmFjZSBjb252ZXJzaW9uIGlzIG5lZWRlZCwgdXNlIEJsdEZhc3QgaW5zdGVhZCB0bwogICAgICogY29weSBpbiBzeXNtZW0gYW5kIHVzZSByZWd1bGFyIHN1cmZhY2UgbG9hZGluZy4KICAgICAqLwogICAgZDNkZm10X2dldF9jb252KChJV2luZUQzRFN1cmZhY2VJbXBsICopIHBEZXN0aW5hdGlvblN1cmZhY2UsIEZBTFNFLCBUUlVFLAogICAgICAgICAgICAgICAgICAgICZkdW1teSwgJmR1bW15LCAmZHVtbXksICZjb252ZXJ0LCAmYnBwLCBGQUxTRSk7CiAgICBpZihjb252ZXJ0ICE9IE5PX0NPTlZFUlNJT04pIHsKICAgICAgICByZXR1cm4gSVdpbmVEM0RTdXJmYWNlX0JsdEZhc3QocERlc3RpbmF0aW9uU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBEZXN0UG9pbnQgID8gcERlc3RQb2ludC0+eCA6IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwRGVzdFBvaW50ICA/IHBEZXN0UG9pbnQtPnkgOiAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFNvdXJjZVN1cmZhY2UsIChSRUNUICopIHBTb3VyY2VSZWN0LCAwKTsKICAgIH0KCiAgICBpZiAoZGVzdEZvcm1hdCA9PSBXSU5FRDNERk1UX1VOS05PV04pIHsKICAgICAgICBUUkFDRSgiKCVwKSA6IENvbnZlcnRpbmcgZGVzdGluYXRpb24gc3VyZmFjZSBmcm9tIFdJTkVEM0RGTVRfVU5LTk9XTiB0byB0aGUgc291cmNlIGZvcm1hdFxuIiwgVGhpcyk7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldEZvcm1hdChwRGVzdGluYXRpb25TdXJmYWNlLCBzcmNGb3JtYXQpOwoKICAgICAgICAvKiBHZXQgdGhlIHVwZGF0ZSBzdXJmYWNlIGRlc2NyaXB0aW9uICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0dldERlc2MocERlc3RpbmF0aW9uU3VyZmFjZSwgJndpbmVkZXNjKTsKICAgIH0KCiAgICBBY3RpdmF0ZUNvbnRleHQoVGhpcywgVGhpcy0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKCiAgICBFTlRFUl9HTCgpOwoKICAgIGlmIChHTF9TVVBQT1JUKEFSQl9NVUxUSVRFWFRVUkUpKSB7CiAgICAgICAgR0xfRVhUQ0FMTChnbEFjdGl2ZVRleHR1cmVBUkIoR0xfVEVYVFVSRTBfQVJCKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQWN0aXZlVGV4dHVyZUFSQiIpOwogICAgfQoKICAgIC8qIE1ha2Ugc3VyZSB0aGUgc3VyZmFjZSBpcyBsb2FkZWQgYW5kIHVwIHRvIGRhdGUgKi8KICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKHBEZXN0aW5hdGlvblN1cmZhY2UpOwoKICAgIElXaW5lRDNEU3VyZmFjZV9HZXRHbERlc2MocERlc3RpbmF0aW9uU3VyZmFjZSwgJmdsRGVzY3JpcHRpb24pOwoKICAgIC8qIHRoaXMgbmVlZHMgdG8gYmUgZG9uZSBpbiBsaW5lcyBpZiB0aGUgc291cmNlUmVjdCAhPSB0aGUgc291cmNlV2lkdGggKi8KICAgIHNyY1dpZHRoICAgPSBwU291cmNlUmVjdCA/IHBTb3VyY2VSZWN0LT5yaWdodCAtIHBTb3VyY2VSZWN0LT5sZWZ0ICAgOiBzcmNTdXJmYWNlV2lkdGg7CiAgICBzcmNIZWlnaHQgID0gcFNvdXJjZVJlY3QgPyBwU291cmNlUmVjdC0+Ym90dG9tIC0gcFNvdXJjZVJlY3QtPnRvcCAgIDogc3JjU3VyZmFjZUhlaWdodDsKICAgIHNyY0xlZnQgICAgPSBwU291cmNlUmVjdCA/IHBTb3VyY2VSZWN0LT5sZWZ0IDogMDsKICAgIGRlc3RMZWZ0ICAgPSBwRGVzdFBvaW50ICA/IHBEZXN0UG9pbnQtPnggOiAwOwogICAgZGVzdFRvcCAgICA9IHBEZXN0UG9pbnQgID8gcERlc3RQb2ludC0+eSA6IDA7CgoKICAgIC8qIFRoaXMgZnVuY3Rpb24gZG9lc24ndCBzdXBwb3J0IGNvbXByZXNzZWQgdGV4dHVyZXMKICAgIHRoZSBwaXRjaCBpcyBqdXN0IGJ5dGVzUGVyUGl4ZWwgKiB3aWR0aCAqLwogICAgaWYoc3JjV2lkdGggIT0gc3JjU3VyZmFjZVdpZHRoICB8fCBzcmNMZWZ0ICl7CiAgICAgICAgcm93b2Zmc2V0ID0gc3JjU3VyZmFjZVdpZHRoICogcFNyY1N1cmZhY2UtPmJ5dGVzUGVyUGl4ZWw7CiAgICAgICAgb2Zmc2V0ICAgKz0gc3JjTGVmdCAqIHBTcmNTdXJmYWNlLT5ieXRlc1BlclBpeGVsOwogICAgICAgIC8qIFRPRE86IGRvIHdlIGV2ZXIgZ2V0IDNicHA/LCB3b3VsZCBhIHNoaWZ0IGFuZCBhbiBhZGQgYmUgcXVpY2tlciB0aGFuIGEgbXVsICh3ZWxsIG1heWJlIGEgY3ljbGUgb3IgdHdvKSAqLwogICAgfQogICAgLyogVE9ETyBEWFQgZm9ybWF0cyAqLwoKICAgIGlmKHBTb3VyY2VSZWN0ICE9IE5VTEwgJiYgcFNvdXJjZVJlY3QtPnRvcCAhPSAwKXsKICAgICAgIG9mZnNldCArPSAgcFNvdXJjZVJlY3QtPnRvcCAqIHNyY1N1cmZhY2VXaWR0aCAqIHBTcmNTdXJmYWNlLT5ieXRlc1BlclBpeGVsOwogICAgfQogICAgVFJBQ0UoIiglcCkgZ2xUZXhTdWJJbWFnZTJELCBMZXZlbCAlZCwgbGVmdCAlZCwgdG9wICVkLCB3aWR0aCAlZCwgaGVpZ2h0ICVkICwgZnRtICVkLCB0eXBlICVkLCBtZW1vcnkgJXBcbiIKICAgICxUaGlzCiAgICAsZ2xEZXNjcmlwdGlvbi0+bGV2ZWwKICAgICxkZXN0TGVmdAogICAgLGRlc3RUb3AKICAgICxzcmNXaWR0aAogICAgLHNyY0hlaWdodAogICAgLGdsRGVzY3JpcHRpb24tPmdsRm9ybWF0CiAgICAsZ2xEZXNjcmlwdGlvbi0+Z2xUeXBlCiAgICAsSVdpbmVEM0RTdXJmYWNlX0dldERhdGEocFNvdXJjZVN1cmZhY2UpCiAgICApOwoKICAgIC8qIFNhbml0eSBjaGVjayAqLwogICAgaWYgKElXaW5lRDNEU3VyZmFjZV9HZXREYXRhKHBTb3VyY2VTdXJmYWNlKSA9PSBOVUxMKSB7CgogICAgICAgIC8qIG5lZWQgdG8gbG9jayB0aGUgc3VyZmFjZSB0byBnZXQgdGhlIGRhdGEgKi8KICAgICAgICBGSVhNRSgiU3VyZmFjZXMgaGFzIG5vIGFsbG9jYXRlZCBtZW1vcnksIGJ1dCBzaG91bGQgYmUgYW4gaW4gbWVtb3J5IG9ubHkgc3VyZmFjZVxuIik7CiAgICB9CgogICAgLyogVE9ETzogQ3ViZSBhbmQgdm9sdW1lIHN1cHBvcnQgKi8KICAgIGlmKHJvd29mZnNldCAhPSAwKXsKICAgICAgICAvKiBub3QgYSB3aG9sZSByb3cgc28gd2UgaGF2ZSB0byBkbyBpdCBhIGxpbmUgYXQgYSB0aW1lICovCiAgICAgICAgaW50IGo7CgogICAgICAgIC8qIGhvcGVmdWxseSB1c2luZyBwb2ludGVyIGFkZGl0aW9uIHdpbGwgYmUgcXVpY2tlciB0aGFuIHVzaW5nIGEgcG9pbnQgKyBqICogcm93b2Zmc2V0ICovCiAgICAgICAgY29uc3QgdW5zaWduZWQgY2hhciogZGF0YSA9KChjb25zdCB1bnNpZ25lZCBjaGFyICopSVdpbmVEM0RTdXJmYWNlX0dldERhdGEocFNvdXJjZVN1cmZhY2UpKSArIG9mZnNldDsKCiAgICAgICAgZm9yKGogPSBkZXN0VG9wIDsgaiA8IChzcmNIZWlnaHQgKyBkZXN0VG9wKSA7IGorKyl7CgogICAgICAgICAgICAgICAgZ2xUZXhTdWJJbWFnZTJEKGdsRGVzY3JpcHRpb24tPnRhcmdldAogICAgICAgICAgICAgICAgICAgICxnbERlc2NyaXB0aW9uLT5sZXZlbAogICAgICAgICAgICAgICAgICAgICxkZXN0TGVmdAogICAgICAgICAgICAgICAgICAgICxqCiAgICAgICAgICAgICAgICAgICAgLHNyY1dpZHRoCiAgICAgICAgICAgICAgICAgICAgLDEKICAgICAgICAgICAgICAgICAgICAsZ2xEZXNjcmlwdGlvbi0+Z2xGb3JtYXQKICAgICAgICAgICAgICAgICAgICAsZ2xEZXNjcmlwdGlvbi0+Z2xUeXBlCiAgICAgICAgICAgICAgICAgICAgLGRhdGEgLyogY291bGQgYmUgcXVpY2tlciB1c2luZyAqLwogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgZGF0YSArPSByb3dvZmZzZXQ7CiAgICAgICAgfQoKICAgIH0gZWxzZSB7IC8qIEZ1bGwgd2lkdGgsIHNvIGp1c3Qgd3JpdGUgb3V0IHRoZSB3aG9sZSB0ZXh0dXJlICovCgogICAgICAgIGlmIChXSU5FRDNERk1UX0RYVDEgPT0gZGVzdEZvcm1hdCB8fAogICAgICAgICAgICBXSU5FRDNERk1UX0RYVDIgPT0gZGVzdEZvcm1hdCB8fAogICAgICAgICAgICBXSU5FRDNERk1UX0RYVDMgPT0gZGVzdEZvcm1hdCB8fAogICAgICAgICAgICBXSU5FRDNERk1UX0RYVDQgPT0gZGVzdEZvcm1hdCB8fAogICAgICAgICAgICBXSU5FRDNERk1UX0RYVDUgPT0gZGVzdEZvcm1hdCkgewogICAgICAgICAgICBpZiAoR0xfU1VQUE9SVChFWFRfVEVYVFVSRV9DT01QUkVTU0lPTl9TM1RDKSkgewogICAgICAgICAgICAgICAgaWYgKGRlc3RTdXJmYWNlSGVpZ2h0ICE9IHNyY0hlaWdodCB8fCBkZXN0U3VyZmFjZVdpZHRoICE9IHNyY1dpZHRoKSB7CiAgICAgICAgICAgICAgICAgICAgLyogRklYTUU6IFRoZSBlYXN5IHdheSB0byBkbyB0aGlzIGlzIHRvIGxvY2sgdGhlIGRlc3RpbmF0aW9uLCBhbmQgY29weSB0aGUgYml0cyBhY3Jvc3MgKi8KICAgICAgICAgICAgICAgICAgICBGSVhNRSgiVXBkYXRpbmcgcGFydCBvZiBhIGNvbXByZXNzZWQgdGV4dHVyZSBpcyBub3Qgc3VwcG9ydGVkIGF0IHRoZSBtb21lbnRcbiIpOwogICAgICAgICAgICAgICAgfSBpZiAoZGVzdEZvcm1hdCAhPSBzcmNGb3JtYXQpIHsKICAgICAgICAgICAgICAgICAgICBGSVhNRSgiVXBkYXRpbmcgbWl4ZWQgZm9ybWF0IGNvbXByZXNzZWQgdGV4dHVyZSBpcyBub3QgY3VycmV0bHkgc3VwcG9ydFxuIik7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xDb21wcmVzc2VkVGV4SW1hZ2UyREFSQikoZ2xEZXNjcmlwdGlvbi0+dGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdsRGVzY3JpcHRpb24tPmxldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdsRGVzY3JpcHRpb24tPmdsRm9ybWF0SW50ZXJuYWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JjV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JjSGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzdFNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0dldERhdGEocFNvdXJjZVN1cmZhY2UpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIEZJWE1FKCJBdHRlbXB0aW5nIHRvIHVwZGF0ZSBhIERYVCBjb21wcmVzc2VkIHRleHR1cmUgd2l0aG91dCBoYXJkd2FyZSBzdXBwb3J0XG4iKTsKICAgICAgICAgICAgfQoKCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZ2xUZXhTdWJJbWFnZTJEKGdsRGVzY3JpcHRpb24tPnRhcmdldAogICAgICAgICAgICAgICAgICAgICxnbERlc2NyaXB0aW9uLT5sZXZlbAogICAgICAgICAgICAgICAgICAgICxkZXN0TGVmdAogICAgICAgICAgICAgICAgICAgICxkZXN0VG9wCiAgICAgICAgICAgICAgICAgICAgLHNyY1dpZHRoCiAgICAgICAgICAgICAgICAgICAgLHNyY0hlaWdodAogICAgICAgICAgICAgICAgICAgICxnbERlc2NyaXB0aW9uLT5nbEZvcm1hdAogICAgICAgICAgICAgICAgICAgICxnbERlc2NyaXB0aW9uLT5nbFR5cGUKICAgICAgICAgICAgICAgICAgICAsSVdpbmVEM0RTdXJmYWNlX0dldERhdGEocFNvdXJjZVN1cmZhY2UpCiAgICAgICAgICAgICAgICApOwogICAgICAgIH0KICAgICB9CiAgICBjaGVja0dMY2FsbCgiZ2xUZXhTdWJJbWFnZTJEIik7CgogICAgTEVBVkVfR0woKTsKCiAgICBJV2luZUQzRFN1cmZhY2VfTW9kaWZ5TG9jYXRpb24ocERlc3RpbmF0aW9uU3VyZmFjZSwgU0ZMQUdfSU5URVhUVVJFLCBUUlVFKTsKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TQU1QTEVSKDApKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3UmVjdFBhdGNoKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBIYW5kbGUsIENPTlNUIGZsb2F0KiBwTnVtU2VncywgQ09OU1QgV0lORUQzRFJFQ1RQQVRDSF9JTkZPKiBwUmVjdFBhdGNoSW5mbykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgc3RydWN0IFdpbmVEM0RSZWN0UGF0Y2ggKnBhdGNoOwogICAgdW5zaWduZWQgaW50IGk7CiAgICBzdHJ1Y3QgbGlzdCAqZTsKICAgIEJPT0wgZm91bmQ7CiAgICBUUkFDRSgiKCVwKSBIYW5kbGUoJWQpIG5vU2VncyglcCkgcmVjdHBhdGNoKCVwKVxuIiwgVGhpcywgSGFuZGxlLCBwTnVtU2VncywgcFJlY3RQYXRjaEluZm8pOwoKICAgIGlmKCEoSGFuZGxlIHx8IHBSZWN0UGF0Y2hJbmZvKSkgewogICAgICAgIC8qIFRPRE86IFdyaXRlIGEgdGVzdCBmb3IgdGhlIHJldHVybiB2YWx1ZSwgdGh1cyB0aGUgRklYTUUgKi8KICAgICAgICBGSVhNRSgiQm90aCBIYW5kbGUgYW5kIHBSZWN0UGF0Y2hJbmZvIGFyZSBOVUxMXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBpZihIYW5kbGUpIHsKICAgICAgICBpID0gUEFUQ0hNQVBfSEFTSEZVTkMoSGFuZGxlKTsKICAgICAgICBmb3VuZCA9IEZBTFNFOwogICAgICAgIExJU1RfRk9SX0VBQ0goZSwgJlRoaXMtPnBhdGNoZXNbaV0pIHsKICAgICAgICAgICAgcGF0Y2ggPSBMSVNUX0VOVFJZKGUsIHN0cnVjdCBXaW5lRDNEUmVjdFBhdGNoLCBlbnRyeSk7CiAgICAgICAgICAgIGlmKHBhdGNoLT5IYW5kbGUgPT0gSGFuZGxlKSB7CiAgICAgICAgICAgICAgICBmb3VuZCA9IFRSVUU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYoIWZvdW5kKSB7CiAgICAgICAgICAgIFRSQUNFKCJQYXRjaCBkb2VzIG5vdCBleGlzdC4gQ3JlYXRpbmcgYSBuZXcgb25lXG4iKTsKICAgICAgICAgICAgcGF0Y2ggPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKCpwYXRjaCkpOwogICAgICAgICAgICBwYXRjaC0+SGFuZGxlID0gSGFuZGxlOwogICAgICAgICAgICBsaXN0X2FkZF9oZWFkKCZUaGlzLT5wYXRjaGVzW2ldLCAmcGF0Y2gtPmVudHJ5KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBUUkFDRSgiRm91bmQgZXhpc3RpbmcgcGF0Y2ggJXBcbiIsIHBhdGNoKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIC8qIFNpbmNlIG9wZW5nbCBkb2VzIG5vdCBsb2FkIHRlc3NlbGF0ZWQgdmVydGV4IGF0dHJpYnV0ZXMgaW50byBudW1iZXJlZCB2ZXJ0ZXgKICAgICAgICAgKiBhdHRyaWJ1dGVzIHdlIGhhdmUgdG8gdGVzc2VsYXRlLCByZWFkIGJhY2ssIGFuZCBkcmF3LiBUaGlzIG5lZWRzIGEgcGF0Y2gKICAgICAgICAgKiBtYW5hZ2VtZW50IHN0cnVjdHVyZSBpbnN0YW5jZS4gQ3JlYXRlIG9uZS4KICAgICAgICAgKgogICAgICAgICAqIEEgcG9zc2libGUgaW1wcm92ZW1lbnQgaXMgdG8gY2hlY2sgaWYgYSB2ZXJ0ZXggc2hhZGVyIGlzIHVzZWQsIGFuZCBpZiBub3QgZGlyZWN0bHkKICAgICAgICAgKiBkcmF3IHRoZSBwYXRjaC4KICAgICAgICAgKi8KICAgICAgICBGSVhNRSgiRHJhd2luZyBhbiB1bmNhY2hlZCBwYXRjaC4gVGhpcyBpcyBzbG93XG4iKTsKICAgICAgICBwYXRjaCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoKnBhdGNoKSk7CiAgICB9CgogICAgaWYocE51bVNlZ3NbMF0gIT0gcGF0Y2gtPm51bVNlZ3NbMF0gfHwgcE51bVNlZ3NbMV0gIT0gcGF0Y2gtPm51bVNlZ3NbMV0gfHwKICAgICAgIHBOdW1TZWdzWzJdICE9IHBhdGNoLT5udW1TZWdzWzJdIHx8IHBOdW1TZWdzWzNdICE9IHBhdGNoLT5udW1TZWdzWzNdIHx8CiAgICAgICAocFJlY3RQYXRjaEluZm8gJiYgbWVtY21wKHBSZWN0UGF0Y2hJbmZvLCAmcGF0Y2gtPlJlY3RQYXRjaEluZm8sIHNpemVvZigqcFJlY3RQYXRjaEluZm8pKSAhPSAwKSApIHsKICAgICAgICBIUkVTVUxUIGhyOwogICAgICAgIFRSQUNFKCJUZXNzZWxhdGlvbiBkZW5zaXR5IG9yIHBhdGNoIGluZm8gY2hhbmdlZCwgcmV0ZXNzZWxhdGluZ1xuIik7CgogICAgICAgIGlmKHBSZWN0UGF0Y2hJbmZvKSB7CiAgICAgICAgICAgIHBhdGNoLT5SZWN0UGF0Y2hJbmZvID0gKnBSZWN0UGF0Y2hJbmZvOwogICAgICAgIH0KICAgICAgICBwYXRjaC0+bnVtU2Vnc1swXSA9IHBOdW1TZWdzWzBdOwogICAgICAgIHBhdGNoLT5udW1TZWdzWzFdID0gcE51bVNlZ3NbMV07CiAgICAgICAgcGF0Y2gtPm51bVNlZ3NbMl0gPSBwTnVtU2Vnc1syXTsKICAgICAgICBwYXRjaC0+bnVtU2Vnc1szXSA9IHBOdW1TZWdzWzNdOwoKICAgICAgICBociA9IHRlc3NlbGF0ZV9yZWN0cGF0Y2goVGhpcywgcGF0Y2gpOwogICAgICAgIGlmKEZBSUxFRChocikpIHsKICAgICAgICAgICAgV0FSTigiUGF0Y2ggdGVzc2VsYXRpb24gZmFpbGVkXG4iKTsKCiAgICAgICAgICAgIC8qIERvIG5vdCByZWxlYXNlIHRoZSBoYW5kbGUgdG8gc3RvcmUgdGhlIHBhcmFtcyBvZiB0aGUgcGF0Y2ggKi8KICAgICAgICAgICAgaWYoIUhhbmRsZSkgewogICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGF0Y2gpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBocjsKICAgICAgICB9CiAgICB9CgogICAgVGhpcy0+Y3VycmVudFBhdGNoID0gcGF0Y2g7CiAgICBJV2luZUQzRERldmljZV9EcmF3UHJpbWl0aXZlU3RyaWRlZChpZmFjZSwgV0lORUQzRFBUX1RSSUFOR0xFTElTVCwgcGF0Y2gtPm51bVNlZ3NbMF0gKiBwYXRjaC0+bnVtU2Vnc1sxXSAqIDIsICZwYXRjaC0+c3RyaWRlZCk7CiAgICBUaGlzLT5jdXJyZW50UGF0Y2ggPSBOVUxMOwoKICAgIC8qIERlc3Ryb3kgdW5jYWNoZWQgcGF0Y2hlcyAqLwogICAgaWYoIUhhbmRsZSkgewogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBhdGNoLT5tZW0pOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBhdGNoKTsKICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdUcmlQYXRjaChJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgSGFuZGxlLCBDT05TVCBmbG9hdCogcE51bVNlZ3MsIENPTlNUIFdJTkVEM0RUUklQQVRDSF9JTkZPKiBwVHJpUGF0Y2hJbmZvKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSBIYW5kbGUoJWQpIG5vU2VncyglcCkgdHJpcGF0Y2goJXApXG4iLCBUaGlzLCBIYW5kbGUsIHBOdW1TZWdzLCBwVHJpUGF0Y2hJbmZvKTsKICAgIEZJWE1FKCIoJXApIDogU3R1YlxuIiwgVGhpcyk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9EZWxldGVQYXRjaChJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgSGFuZGxlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpbnQgaTsKICAgIHN0cnVjdCBXaW5lRDNEUmVjdFBhdGNoICpwYXRjaDsKICAgIHN0cnVjdCBsaXN0ICplOwogICAgVFJBQ0UoIiglcCkgSGFuZGxlKCVkKVxuIiwgVGhpcywgSGFuZGxlKTsKCiAgICBpID0gUEFUQ0hNQVBfSEFTSEZVTkMoSGFuZGxlKTsKICAgIExJU1RfRk9SX0VBQ0goZSwgJlRoaXMtPnBhdGNoZXNbaV0pIHsKICAgICAgICBwYXRjaCA9IExJU1RfRU5UUlkoZSwgc3RydWN0IFdpbmVEM0RSZWN0UGF0Y2gsIGVudHJ5KTsKICAgICAgICBpZihwYXRjaC0+SGFuZGxlID09IEhhbmRsZSkgewogICAgICAgICAgICBUUkFDRSgiRGVsZXRpbmcgcGF0Y2ggJXBcbiIsIHBhdGNoKTsKICAgICAgICAgICAgbGlzdF9yZW1vdmUoJnBhdGNoLT5lbnRyeSk7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBhdGNoLT5tZW0pOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYXRjaCk7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBUT0RPOiBXcml0ZSBhIHRlc3QgZm9yIHRoZSByZXR1cm4gdmFsdWUgKi8KICAgIEZJWE1FKCJBdHRlbXB0IHRvIGRlc3Ryb3kgbm9uZXhpc3RlbnQgcGF0Y2hcbiIpOwogICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7Cn0KCnN0YXRpYyBJV2luZUQzRFN3YXBDaGFpbiAqZ2V0X3N3YXBjaGFpbihJV2luZUQzRFN1cmZhY2UgKnRhcmdldCkgewogICAgSFJFU1VMVCBocjsKICAgIElXaW5lRDNEU3dhcENoYWluICpzd2FwY2hhaW47CgogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKHRhcmdldCwgJklJRF9JV2luZUQzRFN3YXBDaGFpbiwgKHZvaWQgKiopJnN3YXBjaGFpbik7CiAgICBpZiAoU1VDQ0VFREVEKGhyKSkgewogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElVbmtub3duICopc3dhcGNoYWluKTsKICAgICAgICByZXR1cm4gc3dhcGNoYWluOwogICAgfQoKICAgIHJldHVybiBOVUxMOwp9CgpzdGF0aWMgdm9pZCBiaW5kX2ZibyhJV2luZUQzRERldmljZSAqaWZhY2UsIEdMZW51bSB0YXJnZXQsIEdMdWludCAqZmJvKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgaWYgKCEqZmJvKSB7CiAgICAgICAgR0xfRVhUQ0FMTChnbEdlbkZyYW1lYnVmZmVyc0VYVCgxLCBmYm8pKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZW5GcmFtZWJ1ZmZlcnNFWFQoKSIpOwogICAgfQogICAgR0xfRVhUQ0FMTChnbEJpbmRGcmFtZWJ1ZmZlckVYVCh0YXJnZXQsICpmYm8pKTsKICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRGcmFtZWJ1ZmZlcigpIik7Cn0KCnN0YXRpYyB2b2lkIGF0dGFjaF9zdXJmYWNlX2ZibyhJV2luZUQzRERldmljZUltcGwgKlRoaXMsIEdMZW51bSBmYm9fdGFyZ2V0LCBEV09SRCBpZHgsIElXaW5lRDNEU3VyZmFjZSAqc3VyZmFjZSkgewogICAgY29uc3QgSVdpbmVEM0RTdXJmYWNlSW1wbCAqc3VyZmFjZV9pbXBsID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilzdXJmYWNlOwogICAgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKnRleHR1cmVfaW1wbDsKICAgIEdMZW51bSB0ZXh0dGFyZ2V0LCB0YXJnZXQ7CiAgICBHTGludCBvbGRfYmluZGluZzsKCiAgICB0ZXh0dGFyZ2V0ID0gc3VyZmFjZV9pbXBsLT5nbERlc2NyaXB0aW9uLnRhcmdldDsKICAgIGlmKHRleHR0YXJnZXQgPT0gR0xfVEVYVFVSRV8yRCkgewogICAgICAgIHRhcmdldCA9IEdMX1RFWFRVUkVfMkQ7CiAgICAgICAgZ2xHZXRJbnRlZ2VydihHTF9URVhUVVJFX0JJTkRJTkdfMkQsICZvbGRfYmluZGluZyk7CiAgICB9IGVsc2UgaWYodGV4dHRhcmdldCA9PSBHTF9URVhUVVJFX1JFQ1RBTkdMRV9BUkIpIHsKICAgICAgICB0YXJnZXQgPSBHTF9URVhUVVJFX1JFQ1RBTkdMRV9BUkI7CiAgICAgICAgZ2xHZXRJbnRlZ2VydihHTF9URVhUVVJFX0JJTkRJTkdfUkVDVEFOR0xFX0FSQiwgJm9sZF9iaW5kaW5nKTsKICAgIH0gZWxzZSB7CiAgICAgICAgdGFyZ2V0ID0gR0xfVEVYVFVSRV9DVUJFX01BUF9BUkI7CiAgICAgICAgZ2xHZXRJbnRlZ2VydihHTF9URVhUVVJFX0JJTkRJTkdfQ1VCRV9NQVBfQVJCLCAmb2xkX2JpbmRpbmcpOwogICAgfQoKICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKHN1cmZhY2UpOwoKICAgIGdsVGV4UGFyYW1ldGVyaSh0YXJnZXQsIEdMX1RFWFRVUkVfTUlOX0ZJTFRFUiwgR0xfTkVBUkVTVCk7CiAgICBnbFRleFBhcmFtZXRlcmkodGFyZ2V0LCBHTF9URVhUVVJFX01BR19GSUxURVIsIEdMX05FQVJFU1QpOwogICAgZ2xCaW5kVGV4dHVyZSh0YXJnZXQsIG9sZF9iaW5kaW5nKTsKCiAgICAvKiBVcGRhdGUgYmFzZSB0ZXh0dXJlIHN0YXRlcyBhcnJheSAqLwogICAgaWYgKFNVQ0NFRURFRChJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKHN1cmZhY2UsICZJSURfSVdpbmVEM0RCYXNlVGV4dHVyZSwgKHZvaWQgKiopJnRleHR1cmVfaW1wbCkpKSB7CiAgICAgICAgdGV4dHVyZV9pbXBsLT5iYXNlVGV4dHVyZS5zdGF0ZXNbV0lORUQzRFRFWFNUQV9NSU5GSUxURVJdID0gV0lORUQzRFRFWEZfUE9JTlQ7CiAgICAgICAgdGV4dHVyZV9pbXBsLT5iYXNlVGV4dHVyZS5zdGF0ZXNbV0lORUQzRFRFWFNUQV9NQUdGSUxURVJdID0gV0lORUQzRFRFWEZfUE9JTlQ7CiAgICAgICAgaWYgKHRleHR1cmVfaW1wbC0+YmFzZVRleHR1cmUuYmluZENvdW50KSB7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TQU1QTEVSKHRleHR1cmVfaW1wbC0+YmFzZVRleHR1cmUuc2FtcGxlcikpOwogICAgICAgIH0KCiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9SZWxlYXNlKChJV2luZUQzREJhc2VUZXh0dXJlICopdGV4dHVyZV9pbXBsKTsKICAgIH0KCiAgICBHTF9FWFRDQUxMKGdsRnJhbWVidWZmZXJUZXh0dXJlMkRFWFQoZmJvX3RhcmdldCwgR0xfQ09MT1JfQVRUQUNITUVOVDBfRVhUICsgaWR4LCB0ZXh0dGFyZ2V0LAogICAgICAgICAgICBzdXJmYWNlX2ltcGwtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUsIHN1cmZhY2VfaW1wbC0+Z2xEZXNjcmlwdGlvbi5sZXZlbCkpOwoKICAgIGNoZWNrR0xjYWxsKCJhdHRhY2hfc3VyZmFjZV9mYm8iKTsKfQoKc3RhdGljIHZvaWQgY29sb3JfZmlsbF9mYm8oSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFN1cmZhY2UgKnN1cmZhY2UsIENPTlNUIFdJTkVEM0RSRUNUICpyZWN0LCBXSU5FRDNEQ09MT1IgY29sb3IpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcGNoYWluOwoKICAgIHN3YXBjaGFpbiA9IGdldF9zd2FwY2hhaW4oc3VyZmFjZSk7CiAgICBpZiAoc3dhcGNoYWluKSB7CiAgICAgICAgR0xlbnVtIGJ1ZmZlcjsKCiAgICAgICAgVFJBQ0UoIlN1cmZhY2UgJXAgaXMgb25zY3JlZW5cbiIsIHN1cmZhY2UpOwoKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEZyYW1lYnVmZmVyRVhUKEdMX0ZSQU1FQlVGRkVSX0VYVCwgMCkpOwogICAgICAgIGJ1ZmZlciA9IHN1cmZhY2VfZ2V0X2dsX2J1ZmZlcihzdXJmYWNlLCBzd2FwY2hhaW4pOwogICAgICAgIGdsRHJhd0J1ZmZlcihidWZmZXIpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoKSIpOwogICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgiU3VyZmFjZSAlcCBpcyBvZmZzY3JlZW5cbiIsIHN1cmZhY2UpOwogICAgICAgIGJpbmRfZmJvKGlmYWNlLCBHTF9GUkFNRUJVRkZFUl9FWFQsICZUaGlzLT5kc3RfZmJvKTsKICAgICAgICBhdHRhY2hfc3VyZmFjZV9mYm8oVGhpcywgR0xfRlJBTUVCVUZGRVJfRVhULCAwLCBzdXJmYWNlKTsKICAgIH0KCiAgICBpZiAocmVjdCkgewogICAgICAgIGdsRW5hYmxlKEdMX1NDSVNTT1JfVEVTVCk7CiAgICAgICAgaWYoIXN3YXBjaGFpbikgewogICAgICAgICAgICBnbFNjaXNzb3IocmVjdC0+eDEsIHJlY3QtPnkxLCByZWN0LT54MiAtIHJlY3QtPngxLCByZWN0LT55MiAtIHJlY3QtPnkxKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBnbFNjaXNzb3IocmVjdC0+eDEsICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKXN1cmZhY2UpLT5jdXJyZW50RGVzYy5IZWlnaHQgLSByZWN0LT55MiwKICAgICAgICAgICAgICAgICAgICByZWN0LT54MiAtIHJlY3QtPngxLCByZWN0LT55MiAtIHJlY3QtPnkxKTsKICAgICAgICB9CiAgICAgICAgY2hlY2tHTGNhbGwoImdsU2Npc3NvciIpOwogICAgfSBlbHNlIHsKICAgICAgICBnbERpc2FibGUoR0xfU0NJU1NPUl9URVNUKTsKICAgIH0KICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX1NDSVNTT1JURVNURU5BQkxFKSk7CgogICAgZ2xDb2xvck1hc2soR0xfVFJVRSwgR0xfVFJVRSwgR0xfVFJVRSwgR0xfVFJVRSk7CiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19DT0xPUldSSVRFRU5BQkxFKSk7CgogICAgZ2xDbGVhckNvbG9yKEQzRENPTE9SX1IoY29sb3IpLCBEM0RDT0xPUl9HKGNvbG9yKSwgRDNEQ09MT1JfQihjb2xvciksIEQzRENPTE9SX0EoY29sb3IpKTsKICAgIGdsQ2xlYXIoR0xfQ09MT1JfQlVGRkVSX0JJVCk7CiAgICBjaGVja0dMY2FsbCgiZ2xDbGVhciIpOwoKICAgIGlmIChUaGlzLT5yZW5kZXJfb2Zmc2NyZWVuKSB7CiAgICAgICAgYmluZF9mYm8oaWZhY2UsIEdMX0ZSQU1FQlVGRkVSX0VYVCwgJlRoaXMtPmZibyk7CiAgICB9IGVsc2UgewogICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kRnJhbWVidWZmZXJFWFQoR0xfRlJBTUVCVUZGRVJfRVhULCAwKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZEZyYW1lYnVmZmVyKCkiKTsKICAgIH0KCiAgICBpZiAoc3dhcGNoYWluICYmIHN1cmZhY2UgPT0gKChJV2luZUQzRFN3YXBDaGFpbkltcGwgKilzd2FwY2hhaW4pLT5mcm9udEJ1ZmZlcgogICAgICAgICAgICAmJiAoKElXaW5lRDNEU3dhcENoYWluSW1wbCAqKXN3YXBjaGFpbiktPmJhY2tCdWZmZXIpIHsKICAgICAgICBnbERyYXdCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcigpIik7CiAgICB9Cn0KCnN0YXRpYyBpbmxpbmUgRFdPUkQgYXJnYl90b19mbXQoRFdPUkQgY29sb3IsIFdJTkVEM0RGT1JNQVQgZGVzdGZtdCkgewogICAgdW5zaWduZWQgaW50IHIsIGcsIGIsIGE7CiAgICBEV09SRCByZXQ7CgogICAgaWYoZGVzdGZtdCA9PSBXSU5FRDNERk1UX0E4UjhHOEI4IHx8IGRlc3RmbXQgPT0gV0lORUQzREZNVF9YOFI4RzhCOCB8fAogICAgICAgZGVzdGZtdCA9PSBXSU5FRDNERk1UX1I4RzhCOCkKICAgICAgICByZXR1cm4gY29sb3I7CgogICAgVFJBQ0UoIkNvbnZlcnRpbmcgY29sb3IgJTA4eCB0byBmb3JtYXQgJXNcbiIsIGNvbG9yLCBkZWJ1Z19kM2Rmb3JtYXQoZGVzdGZtdCkpOwoKICAgIGEgPSAoY29sb3IgJiAweGZmMDAwMDAwKSA+PiAyNDsKICAgIHIgPSAoY29sb3IgJiAweDAwZmYwMDAwKSA+PiAxNjsKICAgIGcgPSAoY29sb3IgJiAweDAwMDBmZjAwKSA+PiAgODsKICAgIGIgPSAoY29sb3IgJiAweDAwMDAwMGZmKSA+PiAgMDsKCiAgICBzd2l0Y2goZGVzdGZtdCkKICAgIHsKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjVHNkI1OgogICAgICAgICAgICBpZihyID09IDB4ZmYgJiYgZyA9PSAweGZmICYmIGIgPT0gMHhmZikgcmV0dXJuIDB4ZmZmZjsKICAgICAgICAgICAgciA9IChyICogMzIpIC8gMjU2OwogICAgICAgICAgICBnID0gKGcgKiA2NCkgLyAyNTY7CiAgICAgICAgICAgIGIgPSAoYiAqIDMyKSAvIDI1NjsKICAgICAgICAgICAgcmV0ICA9IHIgPDwgMTE7CiAgICAgICAgICAgIHJldCB8PSBnIDw8IDU7CiAgICAgICAgICAgIHJldCB8PSBiOwogICAgICAgICAgICBUUkFDRSgiUmV0dXJuaW5nICUwOHhcbiIsIHJldCk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9YMVI1RzVCNToKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQTFSNUc1QjU6CiAgICAgICAgICAgIGEgPSAoYSAqICAyKSAvIDI1NjsKICAgICAgICAgICAgciA9IChyICogMzIpIC8gMjU2OwogICAgICAgICAgICBnID0gKGcgKiAzMikgLyAyNTY7CiAgICAgICAgICAgIGIgPSAoYiAqIDMyKSAvIDI1NjsKICAgICAgICAgICAgcmV0ICA9IGEgPDwgMTU7CiAgICAgICAgICAgIHJldCB8PSByIDw8IDEwOwogICAgICAgICAgICByZXQgfD0gZyA8PCAgNTsKICAgICAgICAgICAgcmV0IHw9IGIgPDwgIDA7CiAgICAgICAgICAgIFRSQUNFKCJSZXR1cm5pbmcgJTA4eFxuIiwgcmV0KTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX0E4OgogICAgICAgICAgICBUUkFDRSgiUmV0dXJuaW5nICUwOHhcbiIsIGEpOwogICAgICAgICAgICByZXR1cm4gYTsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1g0UjRHNEI0OgogICAgICAgIGNhc2UgV0lORUQzREZNVF9BNFI0RzRCNDoKICAgICAgICAgICAgYSA9IChhICogMTYpIC8gMjU2OwogICAgICAgICAgICByID0gKHIgKiAxNikgLyAyNTY7CiAgICAgICAgICAgIGcgPSAoZyAqIDE2KSAvIDI1NjsKICAgICAgICAgICAgYiA9IChiICogMTYpIC8gMjU2OwogICAgICAgICAgICByZXQgID0gYSA8PCAxMjsKICAgICAgICAgICAgcmV0IHw9IHIgPDwgIDg7CiAgICAgICAgICAgIHJldCB8PSBnIDw8ICA0OwogICAgICAgICAgICByZXQgfD0gYiA8PCAgMDsKICAgICAgICAgICAgVFJBQ0UoIlJldHVybmluZyAlMDh4XG4iLCByZXQpOwogICAgICAgICAgICByZXR1cm4gcmV0OwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjNHM0IyOgogICAgICAgICAgICByID0gKHIgKiA4KSAvIDI1NjsKICAgICAgICAgICAgZyA9IChnICogOCkgLyAyNTY7CiAgICAgICAgICAgIGIgPSAoYiAqIDQpIC8gMjU2OwogICAgICAgICAgICByZXQgID0gciA8PCAgNTsKICAgICAgICAgICAgcmV0IHw9IGcgPDwgIDI7CiAgICAgICAgICAgIHJldCB8PSBiIDw8ICAwOwogICAgICAgICAgICBUUkFDRSgiUmV0dXJuaW5nICUwOHhcbiIsIHJldCk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9YOEI4RzhSODoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQThCOEc4Ujg6CiAgICAgICAgICAgIHJldCAgPSBhIDw8IDI0OwogICAgICAgICAgICByZXQgfD0gYiA8PCAxNjsKICAgICAgICAgICAgcmV0IHw9IGcgPDwgIDg7CiAgICAgICAgICAgIHJldCB8PSByIDw8ICAwOwogICAgICAgICAgICBUUkFDRSgiUmV0dXJuaW5nICUwOHhcbiIsIHJldCk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9BMlIxMEcxMEIxMDoKICAgICAgICAgICAgYSA9IChhICogICAgNCkgLyAyNTY7CiAgICAgICAgICAgIHIgPSAociAqIDEwMjQpIC8gMjU2OwogICAgICAgICAgICBnID0gKGcgKiAxMDI0KSAvIDI1NjsKICAgICAgICAgICAgYiA9IChiICogMTAyNCkgLyAyNTY7CiAgICAgICAgICAgIHJldCAgPSBhIDw8IDMwOwogICAgICAgICAgICByZXQgfD0gciA8PCAyMDsKICAgICAgICAgICAgcmV0IHw9IGcgPDwgMTA7CiAgICAgICAgICAgIHJldCB8PSBiIDw8ICAwOwogICAgICAgICAgICBUUkFDRSgiUmV0dXJuaW5nICUwOHhcbiIsIHJldCk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9BMkIxMEcxMFIxMDoKICAgICAgICAgICAgYSA9IChhICogICAgNCkgLyAyNTY7CiAgICAgICAgICAgIHIgPSAociAqIDEwMjQpIC8gMjU2OwogICAgICAgICAgICBnID0gKGcgKiAxMDI0KSAvIDI1NjsKICAgICAgICAgICAgYiA9IChiICogMTAyNCkgLyAyNTY7CiAgICAgICAgICAgIHJldCAgPSBhIDw8IDMwOwogICAgICAgICAgICByZXQgfD0gYiA8PCAyMDsKICAgICAgICAgICAgcmV0IHw9IGcgPDwgMTA7CiAgICAgICAgICAgIHJldCB8PSByIDw8ICAwOwogICAgICAgICAgICBUUkFDRSgiUmV0dXJuaW5nICUwOHhcbiIsIHJldCk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEZJWE1FKCJBZGQgYSBDT0xPUkZJTEwgY29udmVyc2lvbiBmb3IgZm9ybWF0ICVzXG4iLCBkZWJ1Z19kM2Rmb3JtYXQoZGVzdGZtdCkpOwogICAgICAgICAgICByZXR1cm4gMDsKICAgIH0KfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9Db2xvckZpbGwoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFN1cmZhY2UgKnBTdXJmYWNlLCBDT05TVCBXSU5FRDNEUkVDVCogcFJlY3QsIFdJTkVEM0RDT0xPUiBjb2xvcikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKnN1cmZhY2UgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBwU3VyZmFjZTsKICAgIFdJTkVEREJMVEZYIEJsdEZ4OwogICAgVFJBQ0UoIiglcCkgQ29sb3VyIGZpbGwgU3VyZmFjZTogJXAgcmVjdDogJXAgY29sb3I6IDB4JTA4eFxuIiwgVGhpcywgcFN1cmZhY2UsIHBSZWN0LCBjb2xvcik7CgogICAgaWYgKHN1cmZhY2UtPnJlc291cmNlLnBvb2wgIT0gV0lORUQzRFBPT0xfREVGQVVMVCAmJiBzdXJmYWNlLT5yZXNvdXJjZS5wb29sICE9IFdJTkVEM0RQT09MX1NZU1RFTU1FTSkgewogICAgICAgIEZJWE1FKCJjYWxsIHRvIGNvbG9yZmlsbCB3aXRoIG5vbiBXSU5FRDNEUE9PTF9ERUZBVUxUIG9yIFdJTkVEM0RQT09MX1NZU1RFTU1FTSBzdXJmYWNlXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBpZiAod2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUgPT0gT1JNX0ZCTykgewogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgY29sb3JfZmlsbF9mYm8oaWZhY2UsIHBTdXJmYWNlLCBwUmVjdCwgY29sb3IpOwogICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9IGVsc2UgewogICAgICAgIC8qIEp1c3QgZm9yd2FyZCB0aGlzIHRvIHRoZSBEaXJlY3REcmF3IGJsaXR0aW5nIGVuZ2luZSAqLwogICAgICAgIG1lbXNldCgmQmx0RngsIDAsIHNpemVvZihCbHRGeCkpOwogICAgICAgIEJsdEZ4LmR3U2l6ZSA9IHNpemVvZihCbHRGeCk7CiAgICAgICAgQmx0RngudTUuZHdGaWxsQ29sb3IgPSBhcmdiX3RvX2ZtdChjb2xvciwgc3VyZmFjZS0+cmVzb3VyY2UuZm9ybWF0KTsKICAgICAgICByZXR1cm4gSVdpbmVEM0RTdXJmYWNlX0JsdChwU3VyZmFjZSwgKFJFQ1QgKikgcFJlY3QsIE5VTEwsIE5VTEwsIFdJTkVEREJMVF9DT0xPUkZJTEwsICZCbHRGeCwgV0lORUQzRFRFWEZfTk9ORSk7CiAgICB9Cn0KCi8qIHJlbmRlcnRhcmdldCBhbmQgZGVwdGggc3RlbmNpbCBmdW5jdGlvbnMgKi8Kc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFJlbmRlclRhcmdldChJV2luZUQzRERldmljZSogaWZhY2UsRFdPUkQgUmVuZGVyVGFyZ2V0SW5kZXgsIElXaW5lRDNEU3VyZmFjZSAqKnBwUmVuZGVyVGFyZ2V0KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgaWYgKFJlbmRlclRhcmdldEluZGV4ID49IEdMX0xJTUlUUyhidWZmZXJzKSkgewogICAgICAgIEVSUigiKCVwKSA6IE9ubHkgJWQgcmVuZGVyIHRhcmdldHMgYXJlIHN1cHBvcnRlZC5cbiIsIFRoaXMsIEdMX0xJTUlUUyhidWZmZXJzKSk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgKnBwUmVuZGVyVGFyZ2V0ID0gVGhpcy0+cmVuZGVyX3RhcmdldHNbUmVuZGVyVGFyZ2V0SW5kZXhdOwogICAgVFJBQ0UoIiglcCkgOiBSZW5kZXJUYXJnZXQgJWQgSW5kZXggcmV0dXJuaW5nICVwXG4iLCBUaGlzLCBSZW5kZXJUYXJnZXRJbmRleCwgKnBwUmVuZGVyVGFyZ2V0KTsKICAgIC8qIE5vdGUgaW5jIHJlZiBvbiByZXR1cm5lZCBzdXJmYWNlICovCiAgICBpZigqcHBSZW5kZXJUYXJnZXQgIT0gTlVMTCkKICAgICAgICBJV2luZUQzRFN1cmZhY2VfQWRkUmVmKCpwcFJlbmRlclRhcmdldCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRGcm9udEJhY2tCdWZmZXJzKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RTdXJmYWNlICpGcm9udCwgSVdpbmVEM0RTdXJmYWNlICpCYWNrKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpGcm9udEltcGwgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBGcm9udDsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKkJhY2tJbXBsID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgQmFjazsKICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqU3dhcGNoYWluOwogICAgSFJFU1VMVCBocjsKCiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwKVxuIiwgVGhpcywgRnJvbnRJbXBsLCBCYWNrSW1wbCk7CgogICAgaHIgPSBJV2luZUQzRERldmljZV9HZXRTd2FwQ2hhaW4oaWZhY2UsIDAsIChJV2luZUQzRFN3YXBDaGFpbiAqKikgJlN3YXBjaGFpbik7CiAgICBpZihociAhPSBXSU5FRDNEX09LKSB7CiAgICAgICAgRVJSKCJDYW4ndCBnZXQgdGhlIHN3YXBjaGFpblxuIik7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIC8qIE1ha2Ugc3VyZSB0byByZWxlYXNlIHRoZSBzd2FwY2hhaW4gKi8KICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElXaW5lRDNEU3dhcENoYWluICopIFN3YXBjaGFpbik7CgogICAgaWYoRnJvbnRJbXBsICYmICEoRnJvbnRJbXBsLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpICkgewogICAgICAgIEVSUigiVHJ5aW5nIHRvIHNldCBhIGZyb250IGJ1ZmZlciB3aGljaCBkb2Vzbid0IGhhdmUgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCB1c2FnZVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICBlbHNlIGlmKEJhY2tJbXBsICYmICEoQmFja0ltcGwtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkpIHsKICAgICAgICBFUlIoIlRyeWluZyB0byBzZXQgYSBiYWNrIGJ1ZmZlciB3aGljaCBkb2Vzbid0IGhhdmUgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCB1c2FnZVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYoU3dhcGNoYWluLT5mcm9udEJ1ZmZlciAhPSBGcm9udCkgewogICAgICAgIFRSQUNFKCJDaGFuZ2luZyB0aGUgZnJvbnQgYnVmZmVyIGZyb20gJXAgdG8gJXBcbiIsIFN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIsIEZyb250KTsKCiAgICAgICAgaWYoU3dhcGNoYWluLT5mcm9udEJ1ZmZlcikKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbnRhaW5lcihTd2FwY2hhaW4tPmZyb250QnVmZmVyLCBOVUxMKTsKICAgICAgICBTd2FwY2hhaW4tPmZyb250QnVmZmVyID0gRnJvbnQ7CgogICAgICAgIGlmKFN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIpIHsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbnRhaW5lcihTd2FwY2hhaW4tPmZyb250QnVmZmVyLCAoSVdpbmVEM0RCYXNlICopIFN3YXBjaGFpbik7CiAgICAgICAgfQogICAgfQoKICAgIGlmKEJhY2sgJiYgIVN3YXBjaGFpbi0+YmFja0J1ZmZlcikgewogICAgICAgIC8qIFdlIG5lZWQgbWVtb3J5IGZvciB0aGUgYmFjayBidWZmZXIgYXJyYXkgLSBvbmx5IG9uZSBiYWNrIGJ1ZmZlciB0aGlzIHdheSAqLwogICAgICAgIFN3YXBjaGFpbi0+YmFja0J1ZmZlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSVdpbmVEM0RTdXJmYWNlICopKTsKICAgICAgICBpZighU3dhcGNoYWluLT5iYWNrQnVmZmVyKSB7CiAgICAgICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeVxuIik7CiAgICAgICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwogICAgICAgIH0KICAgIH0KCiAgICBpZihTd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0gIT0gQmFjaykgewogICAgICAgIFRSQUNFKCJDaGFuZ2luZyB0aGUgYmFjayBidWZmZXIgZnJvbSAlcCB0byAlcFxuIiwgU3dhcGNoYWluLT5iYWNrQnVmZmVyLCBCYWNrKTsKCiAgICAgICAgLyogV2hhdCB0byBkbyBhYm91dCB0aGUgY29udGV4dCBoZXJlIGluIHRoZSBjYXNlIG9mIG11bHRpdGhyZWFkaW5nPyBOb3Qgc3VyZS4KICAgICAgICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBieSBJRGlyZWN0M0Q3OjpDcmVhdGVEZXZpY2Ugc28gaW4gdGhlb3J5IGl0cyBpbml0aWFsaXphdGlvbiBjb2RlCiAgICAgICAgICovCiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICBpZighU3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdKSB7CiAgICAgICAgICAgIC8qIEdMIHdhcyB0b2xkIHRvIGRyYXcgdG8gdGhlIGZyb250IGJ1ZmZlciBhdCBjcmVhdGlvbiwKICAgICAgICAgICAgICogdW5kbyB0aGF0CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBnbERyYXdCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoR0xfQkFDSykiKTsKICAgICAgICAgICAgLyogU2V0IHRoZSBiYWNrYnVmZmVyIGNvdW50IHRvIDEgYmVjYXVzZSBvdGhlciBjb2RlIHVzZXMgaXQgdG8gZmluZyB0aGUgYmFjayBidWZmZXJzICovCiAgICAgICAgICAgIFN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJDb3VudCA9IDE7CiAgICAgICAgfSBlbHNlIGlmICghQmFjaykgewogICAgICAgICAgICAvKiBUaGF0IG1ha2VzIHByb2JsZW1zIC0gZGlzYWJsZSBmb3Igbm93ICovCiAgICAgICAgICAgIC8qIGdsRHJhd0J1ZmZlcihHTF9GUk9OVCk7ICovCiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoR0xfRlJPTlQpIik7CiAgICAgICAgICAgIC8qIFdlIGhhdmUgbG9zdCBvdXIgYmFjayBidWZmZXIsIHNldCB0aGlzIHRvIDAgdG8gYXZvaWQgY29uZnVzaW5nIG90aGVyIGNvZGUgKi8KICAgICAgICAgICAgU3dhcGNoYWluLT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckNvdW50ID0gMDsKICAgICAgICB9CiAgICAgICAgTEVBVkVfR0woKTsKCiAgICAgICAgaWYoU3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdKQogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29udGFpbmVyKFN3YXBjaGFpbi0+YmFja0J1ZmZlclswXSwgTlVMTCk7CiAgICAgICAgU3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdID0gQmFjazsKCiAgICAgICAgaWYoU3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdKSB7CiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb250YWluZXIoU3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdLCAoSVdpbmVEM0RCYXNlICopIFN3YXBjaGFpbik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgU3dhcGNoYWluLT5iYWNrQnVmZmVyKTsKICAgICAgICAgICAgU3dhcGNoYWluLT5iYWNrQnVmZmVyID0gTlVMTDsKICAgICAgICB9CgogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfR2V0RGVwdGhTdGVuY2lsU3VyZmFjZShJV2luZUQzRERldmljZSogaWZhY2UsIElXaW5lRDNEU3VyZmFjZSAqKnBwWlN0ZW5jaWxTdXJmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICAqcHBaU3RlbmNpbFN1cmZhY2UgPSBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0OwogICAgVFJBQ0UoIiglcCkgOiB6U3RlbmNpbFN1cmZhY2UgIHJldHVybmluZyAlcFxuIiwgVGhpcywgICpwcFpTdGVuY2lsU3VyZmFjZSk7CgogICAgaWYoKnBwWlN0ZW5jaWxTdXJmYWNlICE9IE5VTEwpIHsKICAgICAgICAvKiBOb3RlIGluYyByZWYgb24gcmV0dXJuZWQgc3VyZmFjZSAqLwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9BZGRSZWYoKnBwWlN0ZW5jaWxTdXJmYWNlKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfTk9URk9VTkQ7CiAgICB9Cn0KCi8qIFRPRE86IEhhbmRsZSBzdGVuY2lsIGF0dGFjaG1lbnRzICovCnN0YXRpYyB2b2lkIHNldF9kZXB0aF9zdGVuY2lsX2ZibyhJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEU3VyZmFjZSAqZGVwdGhfc3RlbmNpbCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqZGVwdGhfc3RlbmNpbF9pbXBsID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilkZXB0aF9zdGVuY2lsOwoKICAgIFRSQUNFKCJTZXQgZGVwdGggc3RlbmNpbCB0byAlcFxuIiwgZGVwdGhfc3RlbmNpbCk7CgogICAgaWYgKGRlcHRoX3N0ZW5jaWxfaW1wbCkgewogICAgICAgIGlmIChkZXB0aF9zdGVuY2lsX2ltcGwtPmN1cnJlbnRfcmVuZGVyYnVmZmVyKSB7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xGcmFtZWJ1ZmZlclJlbmRlcmJ1ZmZlckVYVChHTF9GUkFNRUJVRkZFUl9FWFQsIEdMX0RFUFRIX0FUVEFDSE1FTlRfRVhULCBHTF9SRU5ERVJCVUZGRVJfRVhULCBkZXB0aF9zdGVuY2lsX2ltcGwtPmN1cnJlbnRfcmVuZGVyYnVmZmVyLT5pZCkpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xGcmFtZWJ1ZmZlclJlbmRlcmJ1ZmZlckVYVCgpIik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKnRleHR1cmVfaW1wbDsKICAgICAgICAgICAgR0xlbnVtIHRleHR0YXJnZXQsIHRhcmdldDsKICAgICAgICAgICAgR0xpbnQgb2xkX2JpbmRpbmcgPSAwOwoKICAgICAgICAgICAgdGV4dHRhcmdldCA9IGRlcHRoX3N0ZW5jaWxfaW1wbC0+Z2xEZXNjcmlwdGlvbi50YXJnZXQ7CiAgICAgICAgICAgIGlmKHRleHR0YXJnZXQgPT0gR0xfVEVYVFVSRV8yRCkgewogICAgICAgICAgICAgICAgdGFyZ2V0ID0gR0xfVEVYVFVSRV8yRDsKICAgICAgICAgICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfVEVYVFVSRV9CSU5ESU5HXzJELCAmb2xkX2JpbmRpbmcpOwogICAgICAgICAgICB9IGVsc2UgaWYodGV4dHRhcmdldCA9PSBHTF9URVhUVVJFX1JFQ1RBTkdMRV9BUkIpIHsKICAgICAgICAgICAgICAgIHRhcmdldCA9IEdMX1RFWFRVUkVfUkVDVEFOR0xFX0FSQjsKICAgICAgICAgICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfVEVYVFVSRV9CSU5ESU5HX1JFQ1RBTkdMRV9BUkIsICZvbGRfYmluZGluZyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0YXJnZXQgPSBHTF9URVhUVVJFX0NVQkVfTUFQX0FSQjsKICAgICAgICAgICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfVEVYVFVSRV9CSU5ESU5HX0NVQkVfTUFQX0FSQiwgJm9sZF9iaW5kaW5nKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1ByZUxvYWQoZGVwdGhfc3RlbmNpbCk7CgogICAgICAgICAgICBnbFRleFBhcmFtZXRlcmkodGFyZ2V0LCBHTF9URVhUVVJFX01JTl9GSUxURVIsIEdMX05FQVJFU1QpOwogICAgICAgICAgICBnbFRleFBhcmFtZXRlcmkodGFyZ2V0LCBHTF9URVhUVVJFX01BR19GSUxURVIsIEdMX05FQVJFU1QpOwogICAgICAgICAgICBnbFRleFBhcmFtZXRlcmkodGFyZ2V0LCBHTF9ERVBUSF9URVhUVVJFX01PREVfQVJCLCBHTF9MVU1JTkFOQ0UpOwogICAgICAgICAgICBnbEJpbmRUZXh0dXJlKHRhcmdldCwgb2xkX2JpbmRpbmcpOwoKICAgICAgICAgICAgLyogVXBkYXRlIGJhc2UgdGV4dHVyZSBzdGF0ZXMgYXJyYXkgKi8KICAgICAgICAgICAgaWYgKFNVQ0NFRURFRChJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKGRlcHRoX3N0ZW5jaWwsICZJSURfSVdpbmVEM0RCYXNlVGV4dHVyZSwgKHZvaWQgKiopJnRleHR1cmVfaW1wbCkpKSB7CiAgICAgICAgICAgICAgICB0ZXh0dXJlX2ltcGwtPmJhc2VUZXh0dXJlLnN0YXRlc1tXSU5FRDNEVEVYU1RBX01JTkZJTFRFUl0gPSBXSU5FRDNEVEVYRl9QT0lOVDsKICAgICAgICAgICAgICAgIHRleHR1cmVfaW1wbC0+YmFzZVRleHR1cmUuc3RhdGVzW1dJTkVEM0RURVhTVEFfTUFHRklMVEVSXSA9IFdJTkVEM0RURVhGX1BPSU5UOwogICAgICAgICAgICAgICAgaWYgKHRleHR1cmVfaW1wbC0+YmFzZVRleHR1cmUuYmluZENvdW50KSB7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1NBTVBMRVIodGV4dHVyZV9pbXBsLT5iYXNlVGV4dHVyZS5zYW1wbGVyKSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9SZWxlYXNlKChJV2luZUQzREJhc2VUZXh0dXJlICopdGV4dHVyZV9pbXBsKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEZyYW1lYnVmZmVyVGV4dHVyZTJERVhUKEdMX0ZSQU1FQlVGRkVSX0VYVCwgR0xfREVQVEhfQVRUQUNITUVOVF9FWFQsIHRleHR0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgZGVwdGhfc3RlbmNpbF9pbXBsLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lLCBkZXB0aF9zdGVuY2lsX2ltcGwtPmdsRGVzY3JpcHRpb24ubGV2ZWwpKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRnJhbWVidWZmZXJUZXh0dXJlMkRFWFQoKSIpOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgR0xfRVhUQ0FMTChnbEZyYW1lYnVmZmVyVGV4dHVyZTJERVhUKEdMX0ZSQU1FQlVGRkVSX0VYVCwgR0xfREVQVEhfQVRUQUNITUVOVF9FWFQsIEdMX1RFWFRVUkVfMkQsIDAsIDApKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xGcmFtZWJ1ZmZlclRleHR1cmUyREVYVCgpIik7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIHNldF9yZW5kZXJfdGFyZ2V0X2ZibyhJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIGlkeCwgSVdpbmVEM0RTdXJmYWNlICpyZW5kZXJfdGFyZ2V0KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpydGltcGwgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKXJlbmRlcl90YXJnZXQ7CgogICAgVFJBQ0UoIlNldCByZW5kZXIgdGFyZ2V0ICV1IHRvICVwXG4iLCBpZHgsIHJlbmRlcl90YXJnZXQpOwoKICAgIGlmIChydGltcGwpIHsKICAgICAgICBhdHRhY2hfc3VyZmFjZV9mYm8oVGhpcywgR0xfRlJBTUVCVUZGRVJfRVhULCBpZHgsIHJlbmRlcl90YXJnZXQpOwogICAgICAgIFRoaXMtPmRyYXdfYnVmZmVyc1tpZHhdID0gR0xfQ09MT1JfQVRUQUNITUVOVDBfRVhUICsgaWR4OwogICAgfSBlbHNlIHsKICAgICAgICBHTF9FWFRDQUxMKGdsRnJhbWVidWZmZXJUZXh0dXJlMkRFWFQoR0xfRlJBTUVCVUZGRVJfRVhULCBHTF9DT0xPUl9BVFRBQ0hNRU5UMF9FWFQgKyBpZHgsIEdMX1RFWFRVUkVfMkQsIDAsIDApKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xGcmFtZWJ1ZmZlclRleHR1cmUyREVYVCgpIik7CgogICAgICAgIFRoaXMtPmRyYXdfYnVmZmVyc1tpZHhdID0gR0xfTk9ORTsKICAgIH0KfQoKc3RhdGljIHZvaWQgY2hlY2tfZmJvX3N0YXR1cyhJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIEdMZW51bSBzdGF0dXM7CgogICAgc3RhdHVzID0gR0xfRVhUQ0FMTChnbENoZWNrRnJhbWVidWZmZXJTdGF0dXNFWFQoR0xfRlJBTUVCVUZGRVJfRVhUKSk7CiAgICBpZiAoc3RhdHVzID09IEdMX0ZSQU1FQlVGRkVSX0NPTVBMRVRFX0VYVCkgewogICAgICAgIFRSQUNFKCJGQk8gY29tcGxldGVcbiIpOwogICAgfSBlbHNlIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VJbXBsICphdHRhY2htZW50OwogICAgICAgIGludCBpOwogICAgICAgIEZJWE1FKCJGQk8gc3RhdHVzICVzICglI3gpXG4iLCBkZWJ1Z19mYm9zdGF0dXMoc3RhdHVzKSwgc3RhdHVzKTsKCiAgICAgICAgLyogRHVtcCB0aGUgRkJPIGF0dGFjaG1lbnRzICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IEdMX0xJTUlUUyhidWZmZXJzKTsgKytpKSB7CiAgICAgICAgICAgIGF0dGFjaG1lbnQgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKVRoaXMtPmZib19jb2xvcl9hdHRhY2htZW50c1tpXTsKICAgICAgICAgICAgaWYgKGF0dGFjaG1lbnQpIHsKICAgICAgICAgICAgICAgIEZJWE1FKCJcdENvbG9yIGF0dGFjaG1lbnQgJWQ6ICglcCkgJXMgJXV4JXVcbiIsIGksIGF0dGFjaG1lbnQsIGRlYnVnX2QzZGZvcm1hdChhdHRhY2htZW50LT5yZXNvdXJjZS5mb3JtYXQpLAogICAgICAgICAgICAgICAgICAgICAgICBhdHRhY2htZW50LT5wb3cyV2lkdGgsIGF0dGFjaG1lbnQtPnBvdzJIZWlnaHQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGF0dGFjaG1lbnQgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKVRoaXMtPmZib19kZXB0aF9hdHRhY2htZW50OwogICAgICAgIGlmIChhdHRhY2htZW50KSB7CiAgICAgICAgICAgIEZJWE1FKCJcdERlcHRoIGF0dGFjaG1lbnQ6ICglcCkgJXMgJXV4JXVcbiIsIGF0dGFjaG1lbnQsIGRlYnVnX2QzZGZvcm1hdChhdHRhY2htZW50LT5yZXNvdXJjZS5mb3JtYXQpLAogICAgICAgICAgICAgICAgICAgIGF0dGFjaG1lbnQtPnBvdzJXaWR0aCwgYXR0YWNobWVudC0+cG93MkhlaWdodCk7CiAgICAgICAgfQogICAgfQp9CgpzdGF0aWMgQk9PTCBkZXB0aF9taXNtYXRjaF9mYm8oSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpydF9pbXBsID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKmRzX2ltcGwgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKVRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQ7CgogICAgaWYgKCFkc19pbXBsKSByZXR1cm4gRkFMU0U7CgogICAgaWYgKGRzX2ltcGwtPmN1cnJlbnRfcmVuZGVyYnVmZmVyKSB7CiAgICAgICAgcmV0dXJuIChydF9pbXBsLT5wb3cyV2lkdGggIT0gZHNfaW1wbC0+Y3VycmVudF9yZW5kZXJidWZmZXItPndpZHRoIHx8CiAgICAgICAgICAgICAgICBydF9pbXBsLT5wb3cySGVpZ2h0ICE9IGRzX2ltcGwtPmN1cnJlbnRfcmVuZGVyYnVmZmVyLT5oZWlnaHQpOwogICAgfQoKICAgIHJldHVybiAocnRfaW1wbC0+cG93MldpZHRoICE9IGRzX2ltcGwtPnBvdzJXaWR0aCB8fAogICAgICAgICAgICBydF9pbXBsLT5wb3cySGVpZ2h0ICE9IGRzX2ltcGwtPnBvdzJIZWlnaHQpOwp9Cgp2b2lkIGFwcGx5X2Zib19zdGF0ZShJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIHVuc2lnbmVkIGludCBpOwoKICAgIGlmIChUaGlzLT5yZW5kZXJfb2Zmc2NyZWVuKSB7CiAgICAgICAgYmluZF9mYm8oaWZhY2UsIEdMX0ZSQU1FQlVGRkVSX0VYVCwgJlRoaXMtPmZibyk7CgogICAgICAgIC8qIEFwcGx5IHJlbmRlciB0YXJnZXRzICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IEdMX0xJTUlUUyhidWZmZXJzKTsgKytpKSB7CiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSAqcmVuZGVyX3RhcmdldCA9IFRoaXMtPnJlbmRlcl90YXJnZXRzW2ldOwogICAgICAgICAgICBpZiAoVGhpcy0+ZmJvX2NvbG9yX2F0dGFjaG1lbnRzW2ldICE9IHJlbmRlcl90YXJnZXQpIHsKICAgICAgICAgICAgICAgIHNldF9yZW5kZXJfdGFyZ2V0X2ZibyhpZmFjZSwgaSwgcmVuZGVyX3RhcmdldCk7CiAgICAgICAgICAgICAgICBUaGlzLT5mYm9fY29sb3JfYXR0YWNobWVudHNbaV0gPSByZW5kZXJfdGFyZ2V0OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiBBcHBseSBkZXB0aCB0YXJnZXRzICovCiAgICAgICAgaWYgKFRoaXMtPmZib19kZXB0aF9hdHRhY2htZW50ICE9IFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQgfHwgZGVwdGhfbWlzbWF0Y2hfZmJvKGlmYWNlKSkgewogICAgICAgICAgICB1bnNpZ25lZCBpbnQgdyA9ICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKVRoaXMtPnJlbmRlcl90YXJnZXRzWzBdKS0+cG93MldpZHRoOwogICAgICAgICAgICB1bnNpZ25lZCBpbnQgaCA9ICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKVRoaXMtPnJlbmRlcl90YXJnZXRzWzBdKS0+cG93MkhlaWdodDsKCiAgICAgICAgICAgIGlmIChUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KSB7CiAgICAgICAgICAgICAgICBzdXJmYWNlX3NldF9jb21wYXRpYmxlX3JlbmRlcmJ1ZmZlcihUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0LCB3LCBoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzZXRfZGVwdGhfc3RlbmNpbF9mYm8oaWZhY2UsIFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQpOwogICAgICAgICAgICBUaGlzLT5mYm9fZGVwdGhfYXR0YWNobWVudCA9IFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQ7CiAgICAgICAgfQoKICAgICAgICBpZiAoR0xfU1VQUE9SVChBUkJfRFJBV19CVUZGRVJTKSkgewogICAgICAgICAgICBHTF9FWFRDQUxMKGdsRHJhd0J1ZmZlcnNBUkIoR0xfTElNSVRTKGJ1ZmZlcnMpLCBUaGlzLT5kcmF3X2J1ZmZlcnMpKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcnMoKSIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihUaGlzLT5kcmF3X2J1ZmZlcnNbMF0pOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKCkiKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kRnJhbWVidWZmZXJFWFQoR0xfRlJBTUVCVUZGRVJfRVhULCAwKSk7CiAgICB9CgogICAgY2hlY2tfZmJvX3N0YXR1cyhpZmFjZSk7Cn0KCnZvaWQgc3RyZXRjaF9yZWN0X2ZibyhJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEU3VyZmFjZSAqc3JjX3N1cmZhY2UsIFdJTkVEM0RSRUNUICpzcmNfcmVjdCwKICAgICAgICBJV2luZUQzRFN1cmZhY2UgKmRzdF9zdXJmYWNlLCBXSU5FRDNEUkVDVCAqZHN0X3JlY3QsIGNvbnN0IFdJTkVEM0RURVhUVVJFRklMVEVSVFlQRSBmaWx0ZXIsIEJPT0wgZmxpcCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgR0xiaXRmaWVsZCBtYXNrID0gR0xfQ09MT1JfQlVGRkVSX0JJVDsgLyogVE9ETzogU3VwcG9ydCBibGl0dGluZyBkZXB0aC9zdGVuY2lsIHN1cmZhY2VzICovCiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3JjX3N3YXBjaGFpbiwgKmRzdF9zd2FwY2hhaW47CiAgICBHTGVudW0gZ2xfZmlsdGVyOwoKICAgIFRSQUNFKCIoJXApIDogc3JjX3N1cmZhY2UgJXAsIHNyY19yZWN0ICVwLCBkc3Rfc3VyZmFjZSAlcCwgZHN0X3JlY3QgJXAsIGZpbHRlciAlcyAoMHglMDh4KSwgZmxpcCAldVxuIiwKICAgICAgICAgICAgVGhpcywgc3JjX3N1cmZhY2UsIHNyY19yZWN0LCBkc3Rfc3VyZmFjZSwgZHN0X3JlY3QsIGRlYnVnX2QzZHRleHR1cmVmaWx0ZXJ0eXBlKGZpbHRlciksIGZpbHRlciwgZmxpcCk7CiAgICBUUkFDRSgic3JjX3JlY3QgWyV1LCAldV0tPlsldSwgJXVdXG4iLCBzcmNfcmVjdC0+eDEsIHNyY19yZWN0LT55MSwgc3JjX3JlY3QtPngyLCBzcmNfcmVjdC0+eTIpOwogICAgVFJBQ0UoImRzdF9yZWN0IFsldSwgJXVdLT5bJXUsICV1XVxuIiwgZHN0X3JlY3QtPngxLCBkc3RfcmVjdC0+eTEsIGRzdF9yZWN0LT54MiwgZHN0X3JlY3QtPnkyKTsKCiAgICBzd2l0Y2ggKGZpbHRlcikgewogICAgICAgIGNhc2UgV0lORUQzRFRFWEZfTElORUFSOgogICAgICAgICAgICBnbF9maWx0ZXIgPSBHTF9MSU5FQVI7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBGSVhNRSgiVW5zdXBwb3J0ZWQgZmlsdGVyIG1vZGUgJXMgKDB4JTA4eClcbiIsIGRlYnVnX2QzZHRleHR1cmVmaWx0ZXJ0eXBlKGZpbHRlciksIGZpbHRlcik7CiAgICAgICAgY2FzZSBXSU5FRDNEVEVYRl9OT05FOgogICAgICAgIGNhc2UgV0lORUQzRFRFWEZfUE9JTlQ6CiAgICAgICAgICAgIGdsX2ZpbHRlciA9IEdMX05FQVJFU1Q7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQoKICAgIC8qIEF0dGFjaCBzcmMgc3VyZmFjZSB0byBzcmMgZmJvICovCiAgICBzcmNfc3dhcGNoYWluID0gZ2V0X3N3YXBjaGFpbihzcmNfc3VyZmFjZSk7CiAgICBpZiAoc3JjX3N3YXBjaGFpbikgewogICAgICAgIEdMZW51bSBidWZmZXI7CgogICAgICAgIFRSQUNFKCJTb3VyY2Ugc3VyZmFjZSAlcCBpcyBvbnNjcmVlblxuIiwgc3JjX3N1cmZhY2UpOwogICAgICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBzcmNfc3VyZmFjZSwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKICAgICAgICAvKiBNYWtlIHN1cmUgdGhlIGRyYXdhYmxlIGlzIHVwIHRvIGRhdGUuIEluIHRoZSBvZmZzY3JlZW4gY2FzZQogICAgICAgICAqIGF0dGFjaF9zdXJmYWNlX2ZibygpIGltcGxpY2l0bHkgdGFrZXMgY2FyZSBvZiB0aGlzLiAqLwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9Mb2FkTG9jYXRpb24oc3JjX3N1cmZhY2UsIFNGTEFHX0lORFJBV0FCTEUsIE5VTEwpOwoKICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kRnJhbWVidWZmZXJFWFQoR0xfUkVBRF9GUkFNRUJVRkZFUl9FWFQsIDApKTsKICAgICAgICBidWZmZXIgPSBzdXJmYWNlX2dldF9nbF9idWZmZXIoc3JjX3N1cmZhY2UsIHNyY19zd2FwY2hhaW4pOwogICAgICAgIGdsUmVhZEJ1ZmZlcihidWZmZXIpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIoKSIpOwoKICAgICAgICBzcmNfcmVjdC0+eTEgPSAoKElXaW5lRDNEU3VyZmFjZUltcGwgKilzcmNfc3VyZmFjZSktPmN1cnJlbnREZXNjLkhlaWdodCAtIHNyY19yZWN0LT55MTsKICAgICAgICBzcmNfcmVjdC0+eTIgPSAoKElXaW5lRDNEU3VyZmFjZUltcGwgKilzcmNfc3VyZmFjZSktPmN1cnJlbnREZXNjLkhlaWdodCAtIHNyY19yZWN0LT55MjsKICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoIlNvdXJjZSBzdXJmYWNlICVwIGlzIG9mZnNjcmVlblxuIiwgc3JjX3N1cmZhY2UpOwogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgYmluZF9mYm8oaWZhY2UsIEdMX1JFQURfRlJBTUVCVUZGRVJfRVhULCAmVGhpcy0+c3JjX2Zibyk7CiAgICAgICAgYXR0YWNoX3N1cmZhY2VfZmJvKFRoaXMsIEdMX1JFQURfRlJBTUVCVUZGRVJfRVhULCAwLCBzcmNfc3VyZmFjZSk7CiAgICAgICAgZ2xSZWFkQnVmZmVyKEdMX0NPTE9SX0FUVEFDSE1FTlQwX0VYVCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsUmVhZEJ1ZmZlcigpIik7CiAgICB9CiAgICBMRUFWRV9HTCgpOwoKICAgIC8qIEF0dGFjaCBkc3Qgc3VyZmFjZSB0byBkc3QgZmJvICovCiAgICBkc3Rfc3dhcGNoYWluID0gZ2V0X3N3YXBjaGFpbihkc3Rfc3VyZmFjZSk7CiAgICBpZiAoZHN0X3N3YXBjaGFpbikgewogICAgICAgIEdMZW51bSBidWZmZXI7CgogICAgICAgIFRSQUNFKCJEZXN0aW5hdGlvbiBzdXJmYWNlICVwIGlzIG9uc2NyZWVuXG4iLCBkc3Rfc3VyZmFjZSk7CiAgICAgICAgQWN0aXZhdGVDb250ZXh0KFRoaXMsIGRzdF9zdXJmYWNlLCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwogICAgICAgIC8qIE1ha2Ugc3VyZSB0aGUgZHJhd2FibGUgaXMgdXAgdG8gZGF0ZS4gSW4gdGhlIG9mZnNjcmVlbiBjYXNlCiAgICAgICAgICogYXR0YWNoX3N1cmZhY2VfZmJvKCkgaW1wbGljaXRseSB0YWtlcyBjYXJlIG9mIHRoaXMuICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvYWRMb2NhdGlvbihkc3Rfc3VyZmFjZSwgU0ZMQUdfSU5EUkFXQUJMRSwgTlVMTCk7CgogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgR0xfRVhUQ0FMTChnbEJpbmRGcmFtZWJ1ZmZlckVYVChHTF9EUkFXX0ZSQU1FQlVGRkVSX0VYVCwgMCkpOwogICAgICAgIGJ1ZmZlciA9IHN1cmZhY2VfZ2V0X2dsX2J1ZmZlcihkc3Rfc3VyZmFjZSwgZHN0X3N3YXBjaGFpbik7CiAgICAgICAgZ2xEcmF3QnVmZmVyKGJ1ZmZlcik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcigpIik7CgogICAgICAgIGRzdF9yZWN0LT55MSA9ICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWRzdF9zdXJmYWNlKS0+Y3VycmVudERlc2MuSGVpZ2h0IC0gZHN0X3JlY3QtPnkxOwogICAgICAgIGRzdF9yZWN0LT55MiA9ICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWRzdF9zdXJmYWNlKS0+Y3VycmVudERlc2MuSGVpZ2h0IC0gZHN0X3JlY3QtPnkyOwogICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgiRGVzdGluYXRpb24gc3VyZmFjZSAlcCBpcyBvZmZzY3JlZW5cbiIsIGRzdF9zdXJmYWNlKTsKCiAgICAgICAgLyogTm8gc3JjIG9yIGRzdCBzd2FwY2hhaW4/IE1ha2Ugc3VyZSBzb21lIGNvbnRleHQgaXMgYWN0aXZlKG11bHRpdGhyZWFkaW5nKSAqLwogICAgICAgIGlmKCFzcmNfc3dhcGNoYWluKSB7CiAgICAgICAgICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0LCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwogICAgICAgIH0KCiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICBiaW5kX2ZibyhpZmFjZSwgR0xfRFJBV19GUkFNRUJVRkZFUl9FWFQsICZUaGlzLT5kc3RfZmJvKTsKICAgICAgICBhdHRhY2hfc3VyZmFjZV9mYm8oVGhpcywgR0xfRFJBV19GUkFNRUJVRkZFUl9FWFQsIDAsIGRzdF9zdXJmYWNlKTsKICAgICAgICBnbERyYXdCdWZmZXIoR0xfQ09MT1JfQVRUQUNITUVOVDBfRVhUKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKCkiKTsKICAgIH0KICAgIGdsRGlzYWJsZShHTF9TQ0lTU09SX1RFU1QpOwogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1JFTkRFUihXSU5FRDNEUlNfU0NJU1NPUlRFU1RFTkFCTEUpKTsKCiAgICBpZiAoZmxpcCkgewogICAgICAgIEdMX0VYVENBTEwoZ2xCbGl0RnJhbWVidWZmZXJFWFQoc3JjX3JlY3QtPngxLCBzcmNfcmVjdC0+eTEsIHNyY19yZWN0LT54Miwgc3JjX3JlY3QtPnkyLAogICAgICAgICAgICAgICAgZHN0X3JlY3QtPngxLCBkc3RfcmVjdC0+eTIsIGRzdF9yZWN0LT54MiwgZHN0X3JlY3QtPnkxLCBtYXNrLCBnbF9maWx0ZXIpKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xCbGl0RnJhbWVidWZmZXIoKSIpOwogICAgfSBlbHNlIHsKICAgICAgICBHTF9FWFRDQUxMKGdsQmxpdEZyYW1lYnVmZmVyRVhUKHNyY19yZWN0LT54MSwgc3JjX3JlY3QtPnkxLCBzcmNfcmVjdC0+eDIsIHNyY19yZWN0LT55MiwKICAgICAgICAgICAgICAgIGRzdF9yZWN0LT54MSwgZHN0X3JlY3QtPnkxLCBkc3RfcmVjdC0+eDIsIGRzdF9yZWN0LT55MiwgbWFzaywgZ2xfZmlsdGVyKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQmxpdEZyYW1lYnVmZmVyKCkiKTsKICAgIH0KCiAgICBJV2luZUQzRFN1cmZhY2VfTW9kaWZ5TG9jYXRpb24oZHN0X3N1cmZhY2UsIFNGTEFHX0lORFJBV0FCTEUsIFRSVUUpOwoKICAgIGlmIChUaGlzLT5yZW5kZXJfb2Zmc2NyZWVuKSB7CiAgICAgICAgYmluZF9mYm8oaWZhY2UsIEdMX0ZSQU1FQlVGRkVSX0VYVCwgJlRoaXMtPmZibyk7CiAgICB9IGVsc2UgewogICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kRnJhbWVidWZmZXJFWFQoR0xfRlJBTUVCVUZGRVJfRVhULCAwKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZEZyYW1lYnVmZmVyKCkiKTsKICAgIH0KCiAgICAvKiBJZiB3ZSBzd2l0Y2hlZCBmcm9tIEdMX0JBQ0sgdG8gR0xfRlJPTlQgYWJvdmUsIHdlIG5lZWQgdG8gc3dpdGNoIGJhY2sgaGVyZSAqLwogICAgaWYgKGRzdF9zd2FwY2hhaW4gJiYgZHN0X3N1cmZhY2UgPT0gKChJV2luZUQzRFN3YXBDaGFpbkltcGwgKilkc3Rfc3dhcGNoYWluKS0+ZnJvbnRCdWZmZXIKICAgICAgICAgICAgJiYgKChJV2luZUQzRFN3YXBDaGFpbkltcGwgKilkc3Rfc3dhcGNoYWluKS0+YmFja0J1ZmZlcikgewogICAgICAgIGdsRHJhd0J1ZmZlcihHTF9CQUNLKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKCkiKTsKICAgIH0KICAgIExFQVZFX0dMKCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0UmVuZGVyVGFyZ2V0KElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgUmVuZGVyVGFyZ2V0SW5kZXgsIElXaW5lRDNEU3VyZmFjZSAqcFJlbmRlclRhcmdldCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgV0lORUQzRFZJRVdQT1JUIHZpZXdwb3J0OwoKICAgIFRSQUNFKCIoJXApIDogU2V0dGluZyByZW5kZXJ0YXJnZXQgJWQgdG8gJXBcbiIsIFRoaXMsIFJlbmRlclRhcmdldEluZGV4LCBwUmVuZGVyVGFyZ2V0KTsKCiAgICBpZiAoUmVuZGVyVGFyZ2V0SW5kZXggPj0gR0xfTElNSVRTKGJ1ZmZlcnMpKSB7CiAgICAgICAgV0FSTigiKCVwKSA6IFVuc3VwcG9ydGVkIHRhcmdldCAldSBzZXQsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMKG9ubHkgJXUgc3VwcG9ydGVkKVxuIiwKICAgICAgICAgICAgIFRoaXMsIFJlbmRlclRhcmdldEluZGV4LCBHTF9MSU1JVFMoYnVmZmVycykpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIC8qIE1TRE4gc2F5cyB0aGF0IG51bGwgZGlzYWJsZXMgdGhlIHJlbmRlciB0YXJnZXQKICAgIGJ1dCBhIGRldmljZSBtdXN0IGFsd2F5cyBiZSBhc3NvY2lhdGVkIHdpdGggYSByZW5kZXIgdGFyZ2V0CiAgICBub3BlIE1TRE4gc2F5cyB0aGF0IHdlIHJldHVybiBpbnZhbGlkIGNhbGwgdG8gYSBudWxsIHJlbmRlcnRhcmdldCB3aXRoIGFuIGluZGV4IG9mIDAKICAgICovCiAgICBpZiAoUmVuZGVyVGFyZ2V0SW5kZXggPT0gMCAmJiBwUmVuZGVyVGFyZ2V0ID09IE5VTEwpIHsKICAgICAgICBGSVhNRSgiVHJ5aW5nIHRvIHNldCByZW5kZXIgdGFyZ2V0IDAgdG8gTlVMTFxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICBpZiAocFJlbmRlclRhcmdldCAmJiAhKCgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKXBSZW5kZXJUYXJnZXQpLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpKSB7CiAgICAgICAgRklYTUUoIiglcClUcnlpbmcgdG8gc2V0IHRoZSByZW5kZXIgdGFyZ2V0IHRvIGEgc3VyZmFjZSglcCkgdGhhdCB3YXNuJ3QgY3JlYXRlZCB3aXRoIGEgdXNhZ2Ugb2YgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVFxuIixUaGlzICxwUmVuZGVyVGFyZ2V0KTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICAvKiBJZiB3ZSBhcmUgdHJ5aW5nIHRvIHNldCB3aGF0IHdlIGFscmVhZHkgaGF2ZSwgZG9uJ3QgYm90aGVyICovCiAgICBpZiAocFJlbmRlclRhcmdldCA9PSBUaGlzLT5yZW5kZXJfdGFyZ2V0c1tSZW5kZXJUYXJnZXRJbmRleF0pIHsKICAgICAgICBUUkFDRSgiVHJ5aW5nIHRvIGRvIGEgTk9QIFNldFJlbmRlclRhcmdldCBvcGVyYXRpb25cbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQogICAgaWYocFJlbmRlclRhcmdldCkgSVdpbmVEM0RTdXJmYWNlX0FkZFJlZihwUmVuZGVyVGFyZ2V0KTsKICAgIGlmKFRoaXMtPnJlbmRlcl90YXJnZXRzW1JlbmRlclRhcmdldEluZGV4XSkgSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2UoVGhpcy0+cmVuZGVyX3RhcmdldHNbUmVuZGVyVGFyZ2V0SW5kZXhdKTsKICAgIFRoaXMtPnJlbmRlcl90YXJnZXRzW1JlbmRlclRhcmdldEluZGV4XSA9IHBSZW5kZXJUYXJnZXQ7CgogICAgLyogUmVuZGVyIHRhcmdldCAwIGlzIHNwZWNpYWwgKi8KICAgIGlmKFJlbmRlclRhcmdldEluZGV4ID09IDApIHsKICAgICAgICAvKiBGaW5hbGx5LCByZXNldCB0aGUgdmlld3BvcnQgYXMgdGhlIE1TRE4gc3RhdGVzLiAqLwogICAgICAgIHZpZXdwb3J0LkhlaWdodCA9ICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKVRoaXMtPnJlbmRlcl90YXJnZXRzWzBdKS0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgICAgIHZpZXdwb3J0LldpZHRoICA9ICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKVRoaXMtPnJlbmRlcl90YXJnZXRzWzBdKS0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgdmlld3BvcnQuWCAgICAgID0gMDsKICAgICAgICB2aWV3cG9ydC5ZICAgICAgPSAwOwogICAgICAgIHZpZXdwb3J0Lk1heFogICA9IDEuMGY7CiAgICAgICAgdmlld3BvcnQuTWluWiAgID0gMC4wZjsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfU2V0Vmlld3BvcnQoaWZhY2UsICZ2aWV3cG9ydCk7CiAgICAgICAgLyogTWFrZSBzdXJlIHRoZSB2aWV3cG9ydCBzdGF0ZSBpcyBkaXJ0eSwgYmVjYXVzZSB0aGUgcmVuZGVyX29mZnNjcmVlbiB0aGluZyBhZmZlY3RzIGl0LgogICAgICAgICAqIFNldFZpZXdwb3J0IG1heSBjYXRjaCBOT1Agdmlld3BvcnQgY2hhbmdlcywgd2hpY2ggd291bGQgb2NjdXIgd2hlbiBzd2l0Y2hpbmcgYmV0d2VlbiBlcXVhbGx5IHNpemVkIHRhcmdldHMKICAgICAgICAgKi8KICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVklFV1BPUlQpOwoKICAgICAgICAvKiBBY3RpdmF0ZSB0aGUgbmV3IHJlbmRlciB0YXJnZXQgZm9yIG5vdy4gVGhpcyBzaG91bGRuJ3Qgc3RheSBoZXJlLCBidXQgaXMgbmVlZGVkIHVudGlsIGFsbCBtZXRob2RzIHVzaW5nIGdsIGFjdGl2YXRlIHRoZQogICAgICAgICAqIGN0eCBwcm9wZXJseS4KICAgICAgICAgKiBVc2UgcmVzb3VyY2Vsb2FkIHVzYWdlLCB0aGlzIHdpbGwganVzdCBzZXQgdGhlIGRyYXdhYmxlcyBhbmQgY29udGV4dCBidXQgbm90IGFwcGx5IGFueSBzdGF0ZXMuIFRoZSBzdGF0ZWJsb2NrIG1heSBiZQogICAgICAgICAqIGluY29tcGxldGUgb3IgaW5jb3JyZWN0IHdoZW4gU2V0UmVuZGVyVGFyZ2V0IGlzIGNhbGxlZC4gRHJhd1ByaW0oKSB3aWxsIGFwcGx5IHRoZSBzdGF0ZXMgd2hlbiBpdCBpcyBjYWxsZWQuCiAgICAgICAgICovCiAgICAgICAgQWN0aXZhdGVDb250ZXh0KFRoaXMsIFRoaXMtPnJlbmRlcl90YXJnZXRzWzBdLCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0RGVwdGhTdGVuY2lsU3VyZmFjZShJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEU3VyZmFjZSAqcE5ld1pTdGVuY2lsKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBIUkVTVUxUICBociA9IFdJTkVEM0RfT0s7CiAgICBJV2luZUQzRFN1cmZhY2UgKnRtcDsKCiAgICBUUkFDRSgiKCVwKSBTd2FwcGluZyB6LWJ1ZmZlci4gT2xkID0gJXAsIG5ldyA9ICVwXG4iLFRoaXMsIFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQsIHBOZXdaU3RlbmNpbCk7CgogICAgaWYgKHBOZXdaU3RlbmNpbCA9PSBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KSB7CiAgICAgICAgVFJBQ0UoIlRyeWluZyB0byBkbyBhIE5PUCBTZXRSZW5kZXJUYXJnZXQgb3BlcmF0aW9uXG4iKTsKICAgIH0gZWxzZSB7CiAgICAgICAgLyoqIE9wZW5HTCBkb2Vzbid0IHN1cHBvcnQgJ3NoYXJpbmcnIG9mIHRoZSBzdGVuY2lsQnVmZmVyIHNvIHdlIG1heSBpbmN1ciBhbiBleHRyYSBtZW1vcnkgb3ZlcmhlYWQKICAgICAgICAqIGRlcGVuZGluZyBvbiB0aGUgcmVudGVyIHRhcmdldCBpbXBsZW1lbnRhdGlvbiBiZWluZyB1c2VkLgogICAgICAgICogQSBzaGFyZWQgY29udGV4dCBpbXBsZW1lbnRhdGlvbiB3aWxsIHNoYXJlIGFsbCBidWZmZXJzIGJldHdlZW4gYWxsIHJlbmRlcnRhcmdldHMgKGluY2x1ZGluZyBzd2FwY2hhaW5zKSwKICAgICAgICAqIGltcGxlbWVudGF0aW9ucyB0aGF0IHVzZSBzZXBhcmF0ZSBwYnVmZmVycyBmb3IgZGlmZmVyZW50IHN3YXBjaGFpbnMgb3IgcmVuZGVydGFyZ2V0cyB3aWxsIGhhdmUgdG8gZHVwbGljYXRlIHRoZQogICAgICAgICogc3RlbmNpbCBidWZmZXIgYW5kIGluY3VyIGFuIGV4dHJhIG1lbW9yeSBvdmVyaGVhZAogICAgICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgICAgIHRtcCA9IFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQ7CiAgICAgICAgVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCA9IHBOZXdaU3RlbmNpbDsKICAgICAgICBUaGlzLT5kZXB0aF9jb3B5X3N0YXRlID0gV0lORUQzRF9EQ1NfTk9fQ09QWTsKICAgICAgICAvKiBzaG91bGQgd2UgYmUgY2FsbGluZyB0aGUgcGFyZW50IG9yIHRoZSB3aW5lZDNkIHN1cmZhY2U/ICovCiAgICAgICAgaWYgKE5VTEwgIT0gVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCkgSVdpbmVEM0RTdXJmYWNlX0FkZFJlZihUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KTsKICAgICAgICBpZiAoTlVMTCAhPSB0bXApIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKHRtcCk7CiAgICAgICAgaHIgPSBXSU5FRDNEX09LOwoKICAgICAgICBpZigoIXRtcCAmJiBwTmV3WlN0ZW5jaWwpIHx8ICghcE5ld1pTdGVuY2lsICYmIHRtcCkpIHsKICAgICAgICAgICAgLyogU3dhcHBpbmcgTlVMTCAvIG5vbiBOVUxMIGRlcHRoIHN0ZW5jaWwgYWZmZWN0cyB0aGUgZGVwdGggYW5kIHRlc3RzICovCiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX1pFTkFCTEUpKTsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1JFTkRFUihXSU5FRDNEUlNfU1RFTkNJTEVOQUJMRSkpOwogICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19TVEVOQ0lMV1JJVEVNQVNLKSk7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEN1cnNvclByb3BlcnRpZXMoSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBVSU5UIFhIb3RTcG90LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgWUhvdFNwb3QsIElXaW5lRDNEU3VyZmFjZSAqcEN1cnNvckJpdG1hcCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIC8qIFRPRE86IHRoZSB1c2Ugb2YgSW1wbCBpcyBkZXByZWNhdGVkLiAqLwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqIHBTdXIgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBwQ3Vyc29yQml0bWFwOwogICAgV0lORUQzRExPQ0tFRF9SRUNUIGxvY2tlZFJlY3Q7CgogICAgVFJBQ0UoIiglcCkgOiBTcG90IFBvcygldSwldSlcbiIsIFRoaXMsIFhIb3RTcG90LCBZSG90U3BvdCk7CgogICAgLyogc29tZSBiYXNpYyB2YWxpZGF0aW9uIGNoZWNrcyAqLwogICAgaWYoVGhpcy0+Y3Vyc29yVGV4dHVyZSkgewogICAgICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0LCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgZ2xEZWxldGVUZXh0dXJlcygxLCAmVGhpcy0+Y3Vyc29yVGV4dHVyZSk7CiAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICBUaGlzLT5jdXJzb3JUZXh0dXJlID0gMDsKICAgIH0KCiAgICBpZiAoIChwU3VyLT5jdXJyZW50RGVzYy5XaWR0aCA9PSAzMikgJiYgKHBTdXItPmN1cnJlbnREZXNjLkhlaWdodCA9PSAzMikgKQogICAgICAgIFRoaXMtPmhhdmVIYXJkd2FyZUN1cnNvciA9IFRSVUU7CiAgICBlbHNlCiAgICAgICAgVGhpcy0+aGF2ZUhhcmR3YXJlQ3Vyc29yID0gRkFMU0U7CgogICAgaWYocEN1cnNvckJpdG1hcCkgewogICAgICAgIFdJTkVEM0RMT0NLRURfUkVDVCByZWN0OwoKICAgICAgICAvKiBNU0ROOiBDdXJzb3IgbXVzdCBiZSBBOFI4RzhCOCAqLwogICAgICAgIGlmIChXSU5FRDNERk1UX0E4UjhHOEI4ICE9IHBTdXItPnJlc291cmNlLmZvcm1hdCkgewogICAgICAgICAgICBFUlIoIiglcCkgOiBzdXJmYWNlKCVwKSBoYXMgYW4gaW52YWxpZCBmb3JtYXRcbiIsIFRoaXMsIHBDdXJzb3JCaXRtYXApOwogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICB9CgogICAgICAgIC8qIE1TRE46IEN1cnNvciBtdXN0IGJlIHNtYWxsZXIgdGhhbiB0aGUgZGlzcGxheSBtb2RlICovCiAgICAgICAgaWYocFN1ci0+Y3VycmVudERlc2MuV2lkdGggPiBUaGlzLT5kZHJhd193aWR0aCB8fAogICAgICAgICAgIHBTdXItPmN1cnJlbnREZXNjLkhlaWdodCA+IFRoaXMtPmRkcmF3X2hlaWdodCkgewogICAgICAgICAgICBFUlIoIiglcCkgOiBTdXJmYWNlKCVwKSBpcyAlZHglZCBwaXhlbHMsIGJ1dCBzY3JlZW4gcmVzIGlzICVkeCVkXG4iLCBUaGlzLCBwU3VyLCBwU3VyLT5jdXJyZW50RGVzYy5XaWR0aCwgcFN1ci0+Y3VycmVudERlc2MuSGVpZ2h0LCBUaGlzLT5kZHJhd193aWR0aCwgVGhpcy0+ZGRyYXdfaGVpZ2h0KTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfQoKICAgICAgICBpZiAoIVRoaXMtPmhhdmVIYXJkd2FyZUN1cnNvcikgewogICAgICAgICAgICAvKiBUT0RPOiBNU0ROOiBDdXJzb3Igc2l6ZXMgbXVzdCBiZSBhIHBvd2VyIG9mIDIgKi8KCiAgICAgICAgICAgIC8qIERvIG5vdCBzdG9yZSB0aGUgc3VyZmFjZSdzIHBvaW50ZXIgYmVjYXVzZSB0aGUgYXBwbGljYXRpb24gbWF5CiAgICAgICAgICAgICAqIHJlbGVhc2UgaXQgYWZ0ZXIgc2V0dGluZyB0aGUgY3Vyc29yIGltYWdlLiBXaW5kb3dzIGRvZXNuJ3QKICAgICAgICAgICAgICogYWRkcmVmIHRoZSBzZXQgc3VyZmFjZSwgc28gd2UgY2FuJ3QgZG8gdGhpcyBlaXRoZXIgd2l0aG91dAogICAgICAgICAgICAgKiBjcmVhdGluZyBjaXJjdWxhciByZWZjb3VudCBkZXBlbmRlbmNpZXMuIENvcHkgb3V0IHRoZSBnbCB0ZXh0dXJlCiAgICAgICAgICAgICAqIGluc3RlYWQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBUaGlzLT5jdXJzb3JXaWR0aCA9IHBTdXItPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgICAgICBUaGlzLT5jdXJzb3JIZWlnaHQgPSBwU3VyLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgICAgIGlmIChTVUNDRUVERUQoSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KHBDdXJzb3JCaXRtYXAsICZyZWN0LCBOVUxMLCBXSU5FRDNETE9DS19SRUFET05MWSkpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjb25zdCBHbFBpeGVsRm9ybWF0RGVzYyAqZ2xEZXNjOwogICAgICAgICAgICAgICAgY29uc3QgU3RhdGljUGl4ZWxGb3JtYXREZXNjICp0YWJsZUVudHJ5ID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KFdJTkVEM0RGTVRfQThSOEc4QjgsICZHTElORk9fTE9DQVRJT04sICZnbERlc2MpOwogICAgICAgICAgICAgICAgY2hhciAqbWVtLCAqYml0cyA9IChjaGFyICopcmVjdC5wQml0czsKICAgICAgICAgICAgICAgIEdMaW50IGludGZtdCA9IGdsRGVzYy0+Z2xJbnRlcm5hbDsKICAgICAgICAgICAgICAgIEdMaW50IGZvcm1hdCA9IGdsRGVzYy0+Z2xGb3JtYXQ7CiAgICAgICAgICAgICAgICBHTGludCB0eXBlID0gZ2xEZXNjLT5nbFR5cGU7CiAgICAgICAgICAgICAgICBJTlQgaGVpZ2h0ID0gVGhpcy0+Y3Vyc29ySGVpZ2h0OwogICAgICAgICAgICAgICAgSU5UIHdpZHRoID0gVGhpcy0+Y3Vyc29yV2lkdGg7CiAgICAgICAgICAgICAgICBJTlQgYnBwID0gdGFibGVFbnRyeS0+YnBwOwogICAgICAgICAgICAgICAgSU5UIGk7CgogICAgICAgICAgICAgICAgLyogUmVmb3JtYXQgdGhlIHRleHR1cmUgbWVtb3J5IChwaXRjaCBhbmQgd2lkdGggY2FuIGJlCiAgICAgICAgICAgICAgICAgKiBkaWZmZXJlbnQpICovCiAgICAgICAgICAgICAgICBtZW0gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgd2lkdGggKiBoZWlnaHQgKiBicHApOwogICAgICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDwgaGVpZ2h0OyBpKyspCiAgICAgICAgICAgICAgICAgICAgbWVtY3B5KCZtZW1bd2lkdGggKiBicHAgKiBpXSwgJmJpdHNbcmVjdC5QaXRjaCAqIGldLCB3aWR0aCAqIGJwcCk7CiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfVW5sb2NrUmVjdChwQ3Vyc29yQml0bWFwKTsKICAgICAgICAgICAgICAgIEVOVEVSX0dMKCk7CgogICAgICAgICAgICAgICAgaWYoR0xfU1VQUE9SVChBUFBMRV9DTElFTlRfU1RPUkFHRSkpIHsKICAgICAgICAgICAgICAgICAgICBnbFBpeGVsU3RvcmVpKEdMX1VOUEFDS19DTElFTlRfU1RPUkFHRV9BUFBMRSwgR0xfRkFMU0UpOwogICAgICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFBpeGVsU3RvcmVpKEdMX1VOUEFDS19DTElFTlRfU1RPUkFHRV9BUFBMRSwgR0xfRkFMU0UpIik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLyogTWFrZSBzdXJlIHRoYXQgYSBwcm9wZXIgdGV4dHVyZSB1bml0IGlzIHNlbGVjdGVkICovCiAgICAgICAgICAgICAgICBpZiAoR0xfU1VQUE9SVChBUkJfTVVMVElURVhUVVJFKSkgewogICAgICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xBY3RpdmVUZXh0dXJlQVJCKEdMX1RFWFRVUkUwX0FSQikpOwogICAgICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEFjdGl2ZVRleHR1cmVBUkIiKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TQU1QTEVSKDApKTsKICAgICAgICAgICAgICAgIC8qIENyZWF0ZSBhIG5ldyBjdXJzb3IgdGV4dHVyZSAqLwogICAgICAgICAgICAgICAgZ2xHZW5UZXh0dXJlcygxLCAmVGhpcy0+Y3Vyc29yVGV4dHVyZSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZW5UZXh0dXJlcyIpOwogICAgICAgICAgICAgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCBUaGlzLT5jdXJzb3JUZXh0dXJlKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRUZXh0dXJlIik7CiAgICAgICAgICAgICAgICAvKiBDb3B5IHRoZSBiaXRtYXAgbWVtb3J5IGludG8gdGhlIGN1cnNvciB0ZXh0dXJlICovCiAgICAgICAgICAgICAgICBnbFRleEltYWdlMkQoR0xfVEVYVFVSRV8yRCwgMCwgaW50Zm10LCB3aWR0aCwgaGVpZ2h0LCAwLCBmb3JtYXQsIHR5cGUsIG1lbSk7CiAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtZW0pOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsVGV4SW1hZ2UyRCIpOwoKICAgICAgICAgICAgICAgIGlmKEdMX1NVUFBPUlQoQVBQTEVfQ0xJRU5UX1NUT1JBR0UpKSB7CiAgICAgICAgICAgICAgICAgICAgZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfQ0xJRU5UX1NUT1JBR0VfQVBQTEUsIEdMX1RSVUUpOwogICAgICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFBpeGVsU3RvcmVpKEdMX1VOUEFDS19DTElFTlRfU1RPUkFHRV9BUFBMRSwgR0xfVFJVRSkiKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRklYTUUoIkEgY3Vyc29yIHRleHR1cmUgd2FzIG5vdCByZXR1cm5lZC5cbiIpOwogICAgICAgICAgICAgICAgVGhpcy0+Y3Vyc29yVGV4dHVyZSA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgLyogRHJhdyBhIGhhcmR3YXJlIGN1cnNvciAqLwogICAgICAgICAgICBJQ09OSU5GTyBjdXJzb3JJbmZvOwogICAgICAgICAgICBIQ1VSU09SIGN1cnNvcjsKICAgICAgICAgICAgLyogQ3JlYXRlIGFuZCBjbGVhciBtYXNrQml0cyBiZWNhdXNlIGl0IGlzIG5vdCBuZWVkZWQgZm9yCiAgICAgICAgICAgICAqIDMyLWJpdCBjdXJzb3JzLiAgMzJ4MzIgYml0cyBzcGxpdCBpbnRvIDMyLWJpdCBjaHVua3MgPT0gMzIKICAgICAgICAgICAgICogY2h1bmtzLiAqLwogICAgICAgICAgICBEV09SRCAqbWFza0JpdHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwKICAgICAgICAgICAgICAgIChwU3VyLT5jdXJyZW50RGVzYy5XaWR0aCAqIHBTdXItPmN1cnJlbnREZXNjLkhlaWdodCAvIDgpKTsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KHBDdXJzb3JCaXRtYXAsICZsb2NrZWRSZWN0LCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RMT0NLX05PX0RJUlRZX1VQREFURSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRExPQ0tfUkVBRE9OTFkKICAgICAgICAgICAgKTsKICAgICAgICAgICAgVFJBQ0UoIndpZHRoOiAlaSBoZWlnaHQ6ICVpXG4iLCBwU3VyLT5jdXJyZW50RGVzYy5XaWR0aCwKICAgICAgICAgICAgICAgICAgcFN1ci0+Y3VycmVudERlc2MuSGVpZ2h0KTsKCiAgICAgICAgICAgIGN1cnNvckluZm8uZkljb24gPSBGQUxTRTsKICAgICAgICAgICAgY3Vyc29ySW5mby54SG90c3BvdCA9IFhIb3RTcG90OwogICAgICAgICAgICBjdXJzb3JJbmZvLnlIb3RzcG90ID0gWUhvdFNwb3Q7CiAgICAgICAgICAgIGN1cnNvckluZm8uaGJtTWFzayA9IENyZWF0ZUJpdG1hcChwU3VyLT5jdXJyZW50RGVzYy5XaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTdXItPmN1cnJlbnREZXNjLkhlaWdodCwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsICZtYXNrQml0cyk7CiAgICAgICAgICAgIGN1cnNvckluZm8uaGJtQ29sb3IgPSBDcmVhdGVCaXRtYXAocFN1ci0+Y3VycmVudERlc2MuV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFN1ci0+Y3VycmVudERlc2MuSGVpZ2h0LCAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDMyLCBsb2NrZWRSZWN0LnBCaXRzKTsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QocEN1cnNvckJpdG1hcCk7CiAgICAgICAgICAgIC8qIENyZWF0ZSBvdXIgY3Vyc29yIGFuZCBjbGVhbiB1cC4gKi8KICAgICAgICAgICAgY3Vyc29yID0gQ3JlYXRlSWNvbkluZGlyZWN0KCZjdXJzb3JJbmZvKTsKICAgICAgICAgICAgU2V0Q3Vyc29yKGN1cnNvcik7CiAgICAgICAgICAgIGlmIChjdXJzb3JJbmZvLmhibU1hc2spIERlbGV0ZU9iamVjdChjdXJzb3JJbmZvLmhibU1hc2spOwogICAgICAgICAgICBpZiAoY3Vyc29ySW5mby5oYm1Db2xvcikgRGVsZXRlT2JqZWN0KGN1cnNvckluZm8uaGJtQ29sb3IpOwogICAgICAgICAgICBpZiAoVGhpcy0+aGFyZHdhcmVDdXJzb3IpIERlc3Ryb3lDdXJzb3IoVGhpcy0+aGFyZHdhcmVDdXJzb3IpOwogICAgICAgICAgICBUaGlzLT5oYXJkd2FyZUN1cnNvciA9IGN1cnNvcjsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbWFza0JpdHMpOwogICAgICAgIH0KICAgIH0KCiAgICBUaGlzLT54SG90U3BvdCA9IFhIb3RTcG90OwogICAgVGhpcy0+eUhvdFNwb3QgPSBZSG90U3BvdDsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgdm9pZCAgICAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfU2V0Q3Vyc29yUG9zaXRpb24oSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBpbnQgWFNjcmVlblNwYWNlLCBpbnQgWVNjcmVlblNwYWNlLCBEV09SRCBGbGFncykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogU2V0UG9zIHRvICgldSwldSlcbiIsIFRoaXMsIFhTY3JlZW5TcGFjZSwgWVNjcmVlblNwYWNlKTsKCiAgICBUaGlzLT54U2NyZWVuU3BhY2UgPSBYU2NyZWVuU3BhY2U7CiAgICBUaGlzLT55U2NyZWVuU3BhY2UgPSBZU2NyZWVuU3BhY2U7CgogICAgcmV0dXJuOwoKfQoKc3RhdGljIEJPT0wgICAgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX1Nob3dDdXJzb3IoSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBCT09MIGJTaG93KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgQk9PTCBvbGRWaXNpYmxlID0gVGhpcy0+YkN1cnNvclZpc2libGU7CiAgICBQT0lOVCBwdDsKCiAgICBUUkFDRSgiKCVwKSA6IHZpc2libGUoJWQpXG4iLCBUaGlzLCBiU2hvdyk7CgogICAgLyoKICAgICAqIFdoZW4gU2hvd0N1cnNvciBpcyBmaXJzdCBjYWxsZWQgaXQgc2hvdWxkIG1ha2UgdGhlIGN1cnNvciBhcHBlYXIgYXQgdGhlIE9TJ3MgbGFzdAogICAgICoga25vd24gY3Vyc29yIHBvc2l0aW9uLiAgQmVjYXVzZSBvZiB0aGlzLCBzb21lIGFwcGxpY2F0aW9ucyBqdXN0IHJlcGV0aXRpdmVseSBjYWxsCiAgICAgKiBTaG93Q3Vyc29yIGluIG9yZGVyIHRvIHVwZGF0ZSB0aGUgY3Vyc29yJ3MgcG9zaXRpb24uICBUaGlzIGJlaGF2aW9yIGlzIHVuZG9jdW1lbnRlZC4KICAgICAqLwogICAgR2V0Q3Vyc29yUG9zKCZwdCk7CiAgICBUaGlzLT54U2NyZWVuU3BhY2UgPSBwdC54OwogICAgVGhpcy0+eVNjcmVlblNwYWNlID0gcHQueTsKCiAgICBpZiAoVGhpcy0+aGF2ZUhhcmR3YXJlQ3Vyc29yKSB7CiAgICAgICAgVGhpcy0+YkN1cnNvclZpc2libGUgPSBiU2hvdzsKICAgICAgICBpZiAoYlNob3cpCiAgICAgICAgICAgIFNldEN1cnNvcihUaGlzLT5oYXJkd2FyZUN1cnNvcik7CiAgICAgICAgZWxzZQogICAgICAgICAgICBTZXRDdXJzb3IoTlVMTCk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaWYgKFRoaXMtPmN1cnNvclRleHR1cmUpCiAgICAgICAgICAgIFRoaXMtPmJDdXJzb3JWaXNpYmxlID0gYlNob3c7CiAgICB9CgogICAgcmV0dXJuIG9sZFZpc2libGU7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9UZXN0Q29vcGVyYXRpdmVMZXZlbChJV2luZUQzRERldmljZSogaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFJlc291cmNlSW1wbCAqcmVzb3VyY2U7CiAgICBUUkFDRSgiKCVwKSA6IHN0YXRlICgldSlcbiIsIFRoaXMsIFRoaXMtPnN0YXRlKTsKCiAgICAvKiBUT0RPOiBJbXBsZW1lbnQgd3JhcHBpbmcgb2YgdGhlIFduZFByb2Mgc28gdGhhdCBtaW1pbWl6ZSBhbmQgbWF4aW1pemUgY2FuIGJlIG1vbml0b3JlZCBhbmQgdGhlIHN0YXRlcyBhZGp1c3RlZC4gKi8KICAgIHN3aXRjaCAoVGhpcy0+c3RhdGUpIHsKICAgIGNhc2UgV0lORUQzRF9PSzoKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIGNhc2UgV0lORUQzREVSUl9ERVZJQ0VMT1NUOgogICAgICAgIHsKICAgICAgICAgICAgTElTVF9GT1JfRUFDSF9FTlRSWShyZXNvdXJjZSwgJlRoaXMtPnJlc291cmNlcywgSVdpbmVEM0RSZXNvdXJjZUltcGwsIHJlc291cmNlLnJlc291cmNlX2xpc3RfZW50cnkpIHsKICAgICAgICAgICAgICAgIGlmIChyZXNvdXJjZS0+cmVzb3VyY2UucG9vbCA9PSBXSU5FRDNEUE9PTF9ERUZBVUxUKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0RFVklDRU5PVFJFU0VUOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0RFVklDRUxPU1Q7CiAgICAgICAgfQogICAgY2FzZSBXSU5FRDNERVJSX0RSSVZFUklOVEVSTkFMRVJST1I6CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfRFJJVkVSSU5URVJOQUxFUlJPUjsKICAgIH0KCiAgICAvKiBVbmtub3duIHN0YXRlICovCiAgICByZXR1cm4gV0lORUQzREVSUl9EUklWRVJJTlRFUk5BTEVSUk9SOwp9CgoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0V2aWN0TWFuYWdlZFJlc291cmNlcyhJV2luZUQzRERldmljZSogaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICAvKiogRklYTUU6IFJlc291cmNlIHRyYWNraW5nIG5lZWRzIHRvIGJlIGRvbmUsCiAgICAqIFRoZSBjbG9zZXMgd2UgY2FuIGRvIHRvIHRoaXMgaXMgc2V0IHRoZSBwcmlvcml0aWVzIG9mIGFsbCBtYW5hZ2VkIHRleHR1cmVzIGxvdwogICAgKiBhbmQgdGhlbiByZXNldCB0aGVtLgogICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgRklYTUUoIiglcCkgOiBzdHViXG4iLCBUaGlzKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgdm9pZCB1cGRhdGVTdXJmYWNlRGVzYyhJV2luZUQzRFN1cmZhY2VJbXBsICpzdXJmYWNlLCBXSU5FRDNEUFJFU0VOVF9QQVJBTUVURVJTKiBwUHJlc2VudGF0aW9uUGFyYW1ldGVycykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gc3VyZmFjZS0+cmVzb3VyY2Uud2luZUQzRERldmljZTsgLyogZm9yIEdMX1NVUFBPUlQgKi8KCiAgICAvKiBSZWFsbG9jYXRlIHByb3BlciBtZW1vcnkgZm9yIHRoZSBmcm9udCBhbmQgYmFjayBidWZmZXIgYW5kIGFkanVzdCB0aGVpciBzaXplcyAqLwogICAgaWYoc3VyZmFjZS0+RmxhZ3MgJiBTRkxBR19ESUJTRUNUSU9OKSB7CiAgICAgICAgLyogUmVsZWFzZSB0aGUgREMgKi8KICAgICAgICBTZWxlY3RPYmplY3Qoc3VyZmFjZS0+aERDLCBzdXJmYWNlLT5kaWIuaG9sZGJpdG1hcCk7CiAgICAgICAgRGVsZXRlREMoc3VyZmFjZS0+aERDKTsKICAgICAgICAvKiBSZWxlYXNlIHRoZSBESUIgc2VjdGlvbiAqLwogICAgICAgIERlbGV0ZU9iamVjdChzdXJmYWNlLT5kaWIuRElCc2VjdGlvbik7CiAgICAgICAgc3VyZmFjZS0+ZGliLmJpdG1hcF9kYXRhID0gTlVMTDsKICAgICAgICBzdXJmYWNlLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBOVUxMOwogICAgICAgIHN1cmZhY2UtPkZsYWdzICY9IH5TRkxBR19ESUJTRUNUSU9OOwogICAgfQogICAgc3VyZmFjZS0+Y3VycmVudERlc2MuV2lkdGggPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoOwogICAgc3VyZmFjZS0+Y3VycmVudERlc2MuSGVpZ2h0ID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQ7CiAgICBpZiAoR0xfU1VQUE9SVChBUkJfVEVYVFVSRV9OT05fUE9XRVJfT0ZfVFdPKSB8fCBHTF9TVVBQT1JUKEFSQl9URVhUVVJFX1JFQ1RBTkdMRSkpIHsKICAgICAgICBzdXJmYWNlLT5wb3cyV2lkdGggPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoOwogICAgICAgIHN1cmZhY2UtPnBvdzJIZWlnaHQgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodDsKICAgIH0gZWxzZSB7CiAgICAgICAgc3VyZmFjZS0+cG93MldpZHRoID0gc3VyZmFjZS0+cG93MkhlaWdodCA9IDE7CiAgICAgICAgd2hpbGUgKHN1cmZhY2UtPnBvdzJXaWR0aCA8IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGgpIHN1cmZhY2UtPnBvdzJXaWR0aCA8PD0gMTsKICAgICAgICB3aGlsZSAoc3VyZmFjZS0+cG93MkhlaWdodCA8IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0KSBzdXJmYWNlLT5wb3cySGVpZ2h0IDw8PSAxOwogICAgfQogICAgc3VyZmFjZS0+Z2xSZWN0LmxlZnQgPSAwOwogICAgc3VyZmFjZS0+Z2xSZWN0LnRvcCA9IDA7CiAgICBzdXJmYWNlLT5nbFJlY3QucmlnaHQgPSBzdXJmYWNlLT5wb3cyV2lkdGg7CiAgICBzdXJmYWNlLT5nbFJlY3QuYm90dG9tID0gc3VyZmFjZS0+cG93MkhlaWdodDsKCiAgICBpZihzdXJmYWNlLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKSB7CiAgICAgICAgQWN0aXZhdGVDb250ZXh0KFRoaXMsIFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQsIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICBnbERlbGV0ZVRleHR1cmVzKDEsICZzdXJmYWNlLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgIHN1cmZhY2UtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUgPSAwOwogICAgICAgIHN1cmZhY2UtPkZsYWdzICY9IH5TRkxBR19DTElFTlQ7CiAgICB9CiAgICBpZihzdXJmYWNlLT5wb3cyV2lkdGggIT0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aCB8fAogICAgICAgc3VyZmFjZS0+cG93MkhlaWdodCAhPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodCkgewogICAgICAgIHN1cmZhY2UtPkZsYWdzIHw9IFNGTEFHX05PTlBPVzI7CiAgICB9IGVsc2UgIHsKICAgICAgICBzdXJmYWNlLT5GbGFncyAmPSB+U0ZMQUdfTk9OUE9XMjsKICAgIH0KICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHN1cmZhY2UtPnJlc291cmNlLmhlYXBNZW1vcnkpOwogICAgc3VyZmFjZS0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gTlVMTDsKICAgIHN1cmZhY2UtPnJlc291cmNlLmhlYXBNZW1vcnkgPSBOVUxMOwogICAgc3VyZmFjZS0+cmVzb3VyY2Uuc2l6ZSA9IElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaCgoSVdpbmVEM0RTdXJmYWNlICopIHN1cmZhY2UpICogc3VyZmFjZS0+cG93MldpZHRoOwogICAgLyogSU5EUkFXQUJMRSBpcyBhIHNhbmUgcGxhY2UgZm9yIGltcGxpY2l0IHRhcmdldHMgYWZ0ZXIgdGhlIHJlc2V0LCBJTlNZU01FTSBpcyBtb3JlIGFwcHJvcHJpYXRlIGZvciBkZXB0aCBzdGVuY2lscy4gKi8KICAgIGlmIChzdXJmYWNlLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9ERVBUSFNURU5DSUwpIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfTW9kaWZ5TG9jYXRpb24oKElXaW5lRDNEU3VyZmFjZSAqKSBzdXJmYWNlLCBTRkxBR19JTlNZU01FTSwgVFJVRSk7CiAgICB9IGVsc2UgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9Nb2RpZnlMb2NhdGlvbigoSVdpbmVEM0RTdXJmYWNlICopIHN1cmZhY2UsIFNGTEFHX0lORFJBV0FCTEUsIFRSVUUpOwogICAgfQp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgcmVzZXRfdW5sb2FkX3Jlc291cmNlcyhJV2luZUQzRFJlc291cmNlICpyZXNvdXJjZSwgdm9pZCAqZGF0YSkgewogICAgVFJBQ0UoIlVubG9hZGluZyByZXNvdXJjZSAlcFxuIiwgcmVzb3VyY2UpOwogICAgSVdpbmVEM0RSZXNvdXJjZV9VbkxvYWQocmVzb3VyY2UpOwogICAgSVdpbmVEM0RSZXNvdXJjZV9SZWxlYXNlKHJlc291cmNlKTsKICAgIHJldHVybiBTX09LOwp9CgpzdGF0aWMgdm9pZCByZXNldF9mYm9fc3RhdGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgdW5zaWduZWQgaW50IGk7CgogICAgRU5URVJfR0woKTsKICAgIEdMX0VYVENBTEwoZ2xCaW5kRnJhbWVidWZmZXJFWFQoR0xfRlJBTUVCVUZGRVJfRVhULCAwKSk7CiAgICBjaGVja0dMY2FsbCgiZ2xCaW5kRnJhbWVidWZmZXJFWFQoR0xfRlJBTUVCVUZGRVJfRVhULCAwKSIpOwoKICAgIGlmIChUaGlzLT5mYm8pIHsKICAgICAgICBHTF9FWFRDQUxMKGdsRGVsZXRlRnJhbWVidWZmZXJzRVhUKDEsICZUaGlzLT5mYm8pKTsKICAgICAgICBUaGlzLT5mYm8gPSAwOwogICAgfQogICAgaWYgKFRoaXMtPnNyY19mYm8pIHsKICAgICAgICBHTF9FWFRDQUxMKGdsRGVsZXRlRnJhbWVidWZmZXJzRVhUKDEsICZUaGlzLT5zcmNfZmJvKSk7CiAgICAgICAgVGhpcy0+c3JjX2ZibyA9IDA7CiAgICB9CiAgICBpZiAoVGhpcy0+ZHN0X2ZibykgewogICAgICAgIEdMX0VYVENBTEwoZ2xEZWxldGVGcmFtZWJ1ZmZlcnNFWFQoMSwgJlRoaXMtPmRzdF9mYm8pKTsKICAgICAgICBUaGlzLT5kc3RfZmJvID0gMDsKICAgIH0KICAgIGNoZWNrR0xjYWxsKCJUZWFyIGRvd24gRkJPc1xuIik7CiAgICBMRUFWRV9HTCgpOwoKICAgIGZvciAoaSA9IDA7IGkgPCBHTF9MSU1JVFMoYnVmZmVycyk7ICsraSkgewogICAgICAgIFRoaXMtPmZib19jb2xvcl9hdHRhY2htZW50c1tpXSA9IE5VTEw7CiAgICB9CiAgICBUaGlzLT5mYm9fZGVwdGhfYXR0YWNobWVudCA9IE5VTEw7Cn0KCnN0YXRpYyBCT09MIGlzX2Rpc3BsYXlfbW9kZV9zdXBwb3J0ZWQoSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzLCBXSU5FRDNEUFJFU0VOVF9QQVJBTUVURVJTICpwcCkgewogICAgVUlOVCBpLCBjb3VudDsKICAgIFdJTkVEM0RESVNQTEFZTU9ERSBtOwogICAgSFJFU1VMVCBocjsKCiAgICAvKiBBbGwgV2luZG93ZWQgbW9kZXMgYXJlIHN1cHBvcnRlZCwgYXMgaXMgbGVhdmluZyB0aGUgY3VycmVudCBtb2RlICovCiAgICBpZihwcC0+V2luZG93ZWQpIHJldHVybiBUUlVFOwogICAgaWYoIXBwLT5CYWNrQnVmZmVyV2lkdGgpIHJldHVybiBUUlVFOwogICAgaWYoIXBwLT5CYWNrQnVmZmVySGVpZ2h0KSByZXR1cm4gVFJVRTsKCiAgICBjb3VudCA9IElXaW5lRDNEX0dldEFkYXB0ZXJNb2RlQ291bnQoVGhpcy0+d2luZUQzRCwgVGhpcy0+YWRhcHRlci0+bnVtLCBXSU5FRDNERk1UX1VOS05PV04pOwogICAgZm9yKGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewogICAgICAgIG1lbXNldCgmbSwgMCwgc2l6ZW9mKG0pKTsKICAgICAgICBociA9IElXaW5lRDNEX0VudW1BZGFwdGVyTW9kZXMoVGhpcy0+d2luZUQzRCwgVGhpcy0+YWRhcHRlci0+bnVtLCBXSU5FRDNERk1UX1VOS05PV04sIGksICZtKTsKICAgICAgICBpZihGQUlMRUQoaHIpKSB7CiAgICAgICAgICAgIEVSUigiRW51bUFkYXB0ZXJNb2RlcyBmYWlsZWRcbiIpOwogICAgICAgIH0KICAgICAgICBpZihtLldpZHRoID09IHBwLT5CYWNrQnVmZmVyV2lkdGggJiYgbS5IZWlnaHQgPT0gcHAtPkJhY2tCdWZmZXJIZWlnaHQpIHsKICAgICAgICAgICAgLyogTW9kZSBmb3VuZCwgaXQgaXMgc3VwcG9ydGVkICovCiAgICAgICAgICAgIHJldHVybiBUUlVFOwogICAgICAgIH0KICAgIH0KICAgIC8qIE1vZGUgbm90IGZvdW5kIC0+IG5vdCBzdXBwb3J0ZWQgKi8KICAgIHJldHVybiBGQUxTRTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9SZXNldChJV2luZUQzRERldmljZSogaWZhY2UsIFdJTkVEM0RQUkVTRU5UX1BBUkFNRVRFUlMqIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICpzd2FwY2hhaW47CiAgICBIUkVTVUxUIGhyOwogICAgQk9PTCBEaXNwbGF5TW9kZUNoYW5nZWQgPSBGQUxTRTsKICAgIFdJTkVEM0RESVNQTEFZTU9ERSBtb2RlOwogICAgSVdpbmVEM0RCYXNlU2hhZGVySW1wbCAqc2hhZGVyOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqdGFyZ2V0OwogICAgVUlOVCBpOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfR2V0U3dhcENoYWluKGlmYWNlLCAwLCAoSVdpbmVEM0RTd2FwQ2hhaW4gKiopICZzd2FwY2hhaW4pOwogICAgaWYoRkFJTEVEKGhyKSkgewogICAgICAgIEVSUigiRmFpbGVkIHRvIGdldCB0aGUgZmlyc3QgaW1wbGljaXQgc3dhcGNoYWluXG4iKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgaWYoIWlzX2Rpc3BsYXlfbW9kZV9zdXBwb3J0ZWQoVGhpcywgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMpKSB7CiAgICAgICAgV0FSTigiUmVqZWN0aW5nIFJlc2V0KCkgY2FsbCBiZWNhdXNlIHRoZSByZXF1ZXN0ZWQgZGlzcGxheSBtb2RlIGlzIG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgICAgIFdBUk4oIlJlcXVlc3RlZCBtb2RlOiAlZCwgJWRcbiIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGgsCiAgICAgICAgICAgICBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodCk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogSXMgaXQgbmVjZXNzYXJ5IHRvIHJlY3JlYXRlIHRoZSBnbCBjb250ZXh0PyBBY3R1YWxseSBldmVyeSBzZXR0aW5nIGNhbiBiZSBjaGFuZ2VkCiAgICAgKiBvbiBhbiBleGlzdGluZyBnbCBjb250ZXh0LCBzbyB0aGVyZSdzIG5vIHJlYWwgbmVlZCBmb3IgcmVjcmVhdGlvbi4KICAgICAqCiAgICAgKiBUT0RPOiBGaWd1cmUgb3V0IGhvdyBSZXNldCBpbmZsdWVuY2VzIHJlc291cmNlcyBpbiBEM0RQT09MX0RFRkFVTFQsIEQzRFBPT0xfU1lTVEVNTUVNT1JZIGFuZCBEM0RQT09MX01BTkFHRUQKICAgICAqCiAgICAgKiBUT0RPOiBGaWd1cmUgb3V0IHdoYXQgaGFwcGVucyB0byBleHBsaWNpdCBzd2FwY2hhaW5zLCBvciBpZiB3ZSBoYXZlIG1vcmUgdGhhbiBvbmUgaW1wbGljaXQgc3dhcGNoYWluCiAgICAgKi8KICAgIFRSQUNFKCJOZXcgcGFyYW1zOlxuIik7CiAgICBUUkFDRSgiQmFja0J1ZmZlcldpZHRoID0gJWRcbiIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGgpOwogICAgVFJBQ0UoIkJhY2tCdWZmZXJIZWlnaHQgPSAlZFxuIiwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQpOwogICAgVFJBQ0UoIkJhY2tCdWZmZXJGb3JtYXQgPSAlc1xuIiwgZGVidWdfZDNkZm9ybWF0KHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyRm9ybWF0KSk7CiAgICBUUkFDRSgiQmFja0J1ZmZlckNvdW50ID0gJWRcbiIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyQ291bnQpOwogICAgVFJBQ0UoIk11bHRpU2FtcGxlVHlwZSA9ICVkXG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+TXVsdGlTYW1wbGVUeXBlKTsKICAgIFRSQUNFKCJNdWx0aVNhbXBsZVF1YWxpdHkgPSAlZFxuIiwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPk11bHRpU2FtcGxlUXVhbGl0eSk7CiAgICBUUkFDRSgiU3dhcEVmZmVjdCA9ICVkXG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+U3dhcEVmZmVjdCk7CiAgICBUUkFDRSgiaERldmljZVdpbmRvdyA9ICVwXG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+aERldmljZVdpbmRvdyk7CiAgICBUUkFDRSgiV2luZG93ZWQgPSAlc1xuIiwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPldpbmRvd2VkID8gInRydWUiIDogImZhbHNlIik7CiAgICBUUkFDRSgiRW5hYmxlQXV0b0RlcHRoU3RlbmNpbCA9ICVzXG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+RW5hYmxlQXV0b0RlcHRoU3RlbmNpbCA/ICJ0cnVlIiA6ICJmYWxzZSIpOwogICAgVFJBQ0UoIkZsYWdzID0gJTA4eFxuIiwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkZsYWdzKTsKICAgIFRSQUNFKCJGdWxsU2NyZWVuX1JlZnJlc2hSYXRlSW5IeiA9ICVkXG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+RnVsbFNjcmVlbl9SZWZyZXNoUmF0ZUluSHopOwogICAgVFJBQ0UoIlByZXNlbnRhdGlvbkludGVydmFsID0gJWRcbiIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5QcmVzZW50YXRpb25JbnRlcnZhbCk7CgogICAgLyogTm8gc3BlY2lhbCB0cmVhdG1lbnQgb2YgdGhlc2UgcGFyYW1ldGVycy4gSnVzdCBzdG9yZSB0aGVtICovCiAgICBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5Td2FwRWZmZWN0ID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPlN3YXBFZmZlY3Q7CiAgICBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5GbGFncyA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5GbGFnczsKICAgIHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLlByZXNlbnRhdGlvbkludGVydmFsID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPlByZXNlbnRhdGlvbkludGVydmFsOwogICAgc3dhcGNoYWluLT5wcmVzZW50UGFybXMuRnVsbFNjcmVlbl9SZWZyZXNoUmF0ZUluSHogPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+RnVsbFNjcmVlbl9SZWZyZXNoUmF0ZUluSHo7CgogICAgLyogV2hhdCB0byBkbyBhYm91dCB0aGVzZT8gKi8KICAgIGlmKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyQ291bnQgIT0gMCAmJgogICAgICAgIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyQ291bnQgIT0gc3dhcGNoYWluLT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckNvdW50KSB7CiAgICAgICAgRVJSKCJDYW5ub3QgY2hhbmdlIHRoZSBiYWNrIGJ1ZmZlciBjb3VudCB5ZXRcbiIpOwogICAgfQogICAgaWYocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJGb3JtYXQgIT0gV0lORUQzREZNVF9VTktOT1dOICYmCiAgICAgICAgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJGb3JtYXQgIT0gc3dhcGNoYWluLT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckZvcm1hdCkgewogICAgICAgIEVSUigiQ2Fubm90IGNoYW5nZSB0aGUgYmFjayBidWZmZXIgZm9ybWF0IHlldFxuIik7CiAgICB9CiAgICBpZihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+aERldmljZVdpbmRvdyAhPSBOVUxMICYmCiAgICAgICAgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPmhEZXZpY2VXaW5kb3cgIT0gc3dhcGNoYWluLT5wcmVzZW50UGFybXMuaERldmljZVdpbmRvdykgewogICAgICAgIEVSUigiQ2Fubm90IGNoYW5nZSB0aGUgZGV2aWNlIHdpbmRvdyB5ZXRcbiIpOwogICAgfQogICAgaWYocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkVuYWJsZUF1dG9EZXB0aFN0ZW5jaWwgIT0gc3dhcGNoYWluLT5wcmVzZW50UGFybXMuRW5hYmxlQXV0b0RlcHRoU3RlbmNpbCkgewogICAgICAgIEVSUigiV2hhdCBkbyBkbyBhYm91dCBhIGNoYW5nZWQgYXV0byBkZXB0aCBzdGVuY2lsIHBhcmFtZXRlcj9cbiIpOwogICAgfQoKICAgIGlmICh3aW5lZDNkX3NldHRpbmdzLm9mZnNjcmVlbl9yZW5kZXJpbmdfbW9kZSA9PSBPUk1fRkJPKSB7CiAgICAgICAgcmVzZXRfZmJvX3N0YXRlKChJV2luZUQzRERldmljZSAqKSBUaGlzKTsKICAgIH0KCiAgICBJV2luZUQzRERldmljZV9FbnVtUmVzb3VyY2VzKGlmYWNlLCByZXNldF91bmxvYWRfcmVzb3VyY2VzLCBOVUxMKTsKICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkoc2hhZGVyLCAmVGhpcy0+c2hhZGVycywgSVdpbmVEM0RCYXNlU2hhZGVySW1wbCwgYmFzZVNoYWRlci5zaGFkZXJfbGlzdF9lbnRyeSkgewogICAgICAgIFRoaXMtPnNoYWRlcl9iYWNrZW5kLT5zaGFkZXJfZGVzdHJveSgoSVdpbmVEM0RCYXNlU2hhZGVyICopIHNoYWRlcik7CiAgICB9CgogICAgRU5URVJfR0woKTsKICAgIGlmKFRoaXMtPmRlcHRoX2JsdF90ZXh0dXJlKSB7CiAgICAgICAgZ2xEZWxldGVUZXh0dXJlcygxLCAmVGhpcy0+ZGVwdGhfYmx0X3RleHR1cmUpOwogICAgICAgIFRoaXMtPmRlcHRoX2JsdF90ZXh0dXJlID0gMDsKICAgIH0KICAgIFRoaXMtPnNoYWRlcl9iYWNrZW5kLT5zaGFkZXJfZGVzdHJveV9kZXB0aF9ibHQoaWZhY2UpOwogICAgVGhpcy0+c2hhZGVyX2JhY2tlbmQtPnNoYWRlcl9mcmVlX3ByaXZhdGUoaWZhY2UpOwoKICAgIGZvciAoaSA9IDA7IGkgPCBHTF9MSU1JVFModGV4dHVyZXMpOyBpKyspIHsKICAgICAgICAvKiBUZXh0dXJlcyBhcmUgcmVjcmVhdGVkIGJlbG93ICovCiAgICAgICAgZ2xEZWxldGVUZXh0dXJlcygxLCAmVGhpcy0+ZHVtbXlUZXh0dXJlTmFtZVtpXSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRGVsZXRlVGV4dHVyZXMoMSwgJlRoaXMtPmR1bW15VGV4dHVyZU5hbWVbaV0pIik7CiAgICAgICAgVGhpcy0+ZHVtbXlUZXh0dXJlTmFtZVtpXSA9IDA7CiAgICB9CiAgICBMRUFWRV9HTCgpOwoKICAgIHdoaWxlKFRoaXMtPm51bUNvbnRleHRzKSB7CiAgICAgICAgRGVzdHJveUNvbnRleHQoVGhpcywgVGhpcy0+Y29udGV4dHNbMF0pOwogICAgfQogICAgVGhpcy0+YWN0aXZlQ29udGV4dCA9IE5VTEw7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzd2FwY2hhaW4tPmNvbnRleHQpOwogICAgc3dhcGNoYWluLT5jb250ZXh0ID0gTlVMTDsKICAgIHN3YXBjaGFpbi0+bnVtX2NvbnRleHRzID0gMDsKCiAgICAgaWYocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPldpbmRvd2VkKSB7CiAgICAgICAgbW9kZS5XaWR0aCA9IHN3YXBjaGFpbi0+b3JpZ193aWR0aDsKICAgICAgICBtb2RlLkhlaWdodCA9IHN3YXBjaGFpbi0+b3JpZ19oZWlnaHQ7CiAgICAgICAgbW9kZS5SZWZyZXNoUmF0ZSA9IDA7CiAgICAgICAgbW9kZS5Gb3JtYXQgPSBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyRm9ybWF0OwogICAgfSBlbHNlIHsKICAgICAgICBtb2RlLldpZHRoID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aDsKICAgICAgICBtb2RlLkhlaWdodCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0OwogICAgICAgIG1vZGUuUmVmcmVzaFJhdGUgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+RnVsbFNjcmVlbl9SZWZyZXNoUmF0ZUluSHo7CiAgICAgICAgbW9kZS5Gb3JtYXQgPSBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyRm9ybWF0OwogICAgfQoKICAgIC8qIFNob3VsZCBXaWR0aCA9PSA4MDAgJiYgSGVpZ2h0ID09IDAgc2V0IDgwMHg2MDA/ICovCiAgICBpZihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoICE9IDAgJiYgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQgIT0gMCAmJgogICAgICAgKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGggIT0gc3dhcGNoYWluLT5wcmVzZW50UGFybXMuQmFja0J1ZmZlcldpZHRoIHx8CiAgICAgICAgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQgIT0gc3dhcGNoYWluLT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckhlaWdodCkpCiAgICB7CiAgICAgICAgV0lORUQzRFZJRVdQT1JUIHZwOwogICAgICAgIGludCBpOwoKICAgICAgICB2cC5YID0gMDsKICAgICAgICB2cC5ZID0gMDsKICAgICAgICB2cC5XaWR0aCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGg7CiAgICAgICAgdnAuSGVpZ2h0ID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQ7CiAgICAgICAgdnAuTWluWiA9IDA7CiAgICAgICAgdnAuTWF4WiA9IDE7CgogICAgICAgIGlmKCFwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+V2luZG93ZWQpIHsKICAgICAgICAgICAgRGlzcGxheU1vZGVDaGFuZ2VkID0gVFJVRTsKICAgICAgICB9CiAgICAgICAgc3dhcGNoYWluLT5wcmVzZW50UGFybXMuQmFja0J1ZmZlcldpZHRoID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aDsKICAgICAgICBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVySGVpZ2h0ID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQ7CgogICAgICAgIHVwZGF0ZVN1cmZhY2VEZXNjKChJV2luZUQzRFN1cmZhY2VJbXBsICopc3dhcGNoYWluLT5mcm9udEJ1ZmZlciwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMpOwogICAgICAgIGZvcihpID0gMDsgaSA8IHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJDb3VudDsgaSsrKSB7CiAgICAgICAgICAgIHVwZGF0ZVN1cmZhY2VEZXNjKChJV2luZUQzRFN1cmZhY2VJbXBsICopc3dhcGNoYWluLT5iYWNrQnVmZmVyW2ldLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycyk7CiAgICAgICAgfQogICAgICAgIGlmKFRoaXMtPmF1dG9fZGVwdGhfc3RlbmNpbF9idWZmZXIpIHsKICAgICAgICAgICAgdXBkYXRlU3VyZmFjZURlc2MoKElXaW5lRDNEU3VyZmFjZUltcGwgKilUaGlzLT5hdXRvX2RlcHRoX3N0ZW5jaWxfYnVmZmVyLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycyk7CiAgICAgICAgfQoKCiAgICAgICAgLyogTm93IHNldCB0aGUgbmV3IHZpZXdwb3J0ICovCiAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0Vmlld3BvcnQoaWZhY2UsICZ2cCk7CiAgICB9CgogICAgaWYoKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5XaW5kb3dlZCAmJiAhc3dhcGNoYWluLT5wcmVzZW50UGFybXMuV2luZG93ZWQpIHx8CiAgICAgICAoc3dhcGNoYWluLT5wcmVzZW50UGFybXMuV2luZG93ZWQgJiYgIXBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5XaW5kb3dlZCkgfHwKICAgICAgICBEaXNwbGF5TW9kZUNoYW5nZWQpIHsKCiAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0RnVsbHNjcmVlbihpZmFjZSwgIXBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5XaW5kb3dlZCk7CiAgICAgICAgc3dhcGNoYWluLT5wcmVzZW50UGFybXMuV2luZG93ZWQgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+V2luZG93ZWQ7CiAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0RGlzcGxheU1vZGUoaWZhY2UsIDAsICZtb2RlKTsKICAgIH0gZWxzZSBpZighcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPldpbmRvd2VkKSB7CiAgICAgICAgRFdPUkQgc3R5bGUgPSBUaGlzLT5zdHlsZSwgZXhTdHlsZSA9IFRoaXMtPmV4U3R5bGU7CiAgICAgICAgLyogSWYgd2UncmUgaW4gZnVsbHNjcmVlbiwgYW5kIHRoZSBtb2RlIHdhc24ndCBjaGFuZ2VkLCB3ZSBoYXZlIHRvIGdldCB0aGUgd2luZG93IGJhY2sgaW50bwogICAgICAgICAqIHRoZSByaWdodCBwb3NpdGlvbi4gU29tZSBhcHBsaWNhdGlvbnMoQmF0dGxlZmllbGQgMiwgR3VpbGQgV2FycykgbW92ZSBpdCBhbmQgdGhlbiBjYWxsCiAgICAgICAgICogUmVzZXQgdG8gY2xlYXIgdXAgdGhlaXIgbWVzcy4gR3VpbGQgV2FycyBhbHNvIGxvc2VzIHRoZSBkZXZpY2UgZHVyaW5nIHRoYXQuCiAgICAgICAgICovCiAgICAgICAgVGhpcy0+c3R5bGUgPSAwOwogICAgICAgIFRoaXMtPmV4U3R5bGUgPSAwOwogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXR1cEZ1bGxzY3JlZW5XaW5kb3coaWZhY2UsIFRoaXMtPmRkcmF3X3dpbmRvdyk7CiAgICAgICAgVGhpcy0+c3R5bGUgPSBzdHlsZTsKICAgICAgICBUaGlzLT5leFN0eWxlID0gZXhTdHlsZTsKICAgIH0KCiAgICAvKiBSZWNyZWF0ZSB0aGUgcHJpbWFyeSBzd2FwY2hhaW4ncyBjb250ZXh0ICovCiAgICBzd2FwY2hhaW4tPmNvbnRleHQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKCpzd2FwY2hhaW4tPmNvbnRleHQpKTsKICAgIGlmKHN3YXBjaGFpbi0+YmFja0J1ZmZlcikgewogICAgICAgIHRhcmdldCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIHN3YXBjaGFpbi0+YmFja0J1ZmZlclswXTsKICAgIH0gZWxzZSB7CiAgICAgICAgdGFyZ2V0ID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgc3dhcGNoYWluLT5mcm9udEJ1ZmZlcjsKICAgIH0KICAgIHN3YXBjaGFpbi0+Y29udGV4dFswXSA9IENyZWF0ZUNvbnRleHQoVGhpcywgdGFyZ2V0LCBzd2FwY2hhaW4tPndpbl9oYW5kbGUsIEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc3dhcGNoYWluLT5wcmVzZW50UGFybXMpOwogICAgc3dhcGNoYWluLT5udW1fY29udGV4dHMgPSAxOwogICAgVGhpcy0+YWN0aXZlQ29udGV4dCA9IHN3YXBjaGFpbi0+Y29udGV4dFswXTsKICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElXaW5lRDNEU3dhcENoYWluICopIHN3YXBjaGFpbik7CgogICAgaHIgPSBJV2luZUQzRFN0YXRlQmxvY2tfSW5pdFN0YXJ0dXBTdGF0ZUJsb2NrKChJV2luZUQzRFN0YXRlQmxvY2sgKikgVGhpcy0+c3RhdGVCbG9jayk7CiAgICBpZihGQUlMRUQoaHIpKSB7CiAgICAgICAgRVJSKCJSZXNldHRpbmcgdGhlIHN0YXRlYmxvY2sgZmFpbGVkIHdpdGggZXJyb3IgMHglMDh4XG4iLCBocik7CiAgICB9CiAgICBjcmVhdGVfZHVtbXlfdGV4dHVyZXMoVGhpcyk7CgoKICAgIGhyID0gVGhpcy0+c2hhZGVyX2JhY2tlbmQtPnNoYWRlcl9hbGxvY19wcml2YXRlKGlmYWNlKTsKICAgIGlmKEZBSUxFRChocikpIHsKICAgICAgICBFUlIoIkZhaWxlZCB0byByZWNyZWF0ZSBzaGFkZXIgcHJpdmF0ZSBkYXRhXG4iKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgLyogQWxsIGRvbmUuIFRoZXJlIGlzIG5vIG5lZWQgdG8gcmVsb2FkIHJlc291cmNlcyBvciBzaGFkZXJzLCB0aGlzIHdpbGwgaGFwcGVuIGF1dG9tYXRpY2FsbHkgb24gdGhlCiAgICAgKiBmaXJzdCB1c2UKICAgICAqLwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0RGlhbG9nQm94TW9kZShJV2luZUQzRERldmljZSAqaWZhY2UsIEJPT0wgYkVuYWJsZURpYWxvZ3MpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIC8qKiBGSVhNRTogYWx3YXlzIHRydWUgYXQgdGhlIG1vbWVudCAqKi8KICAgIGlmKCFiRW5hYmxlRGlhbG9ncykgewogICAgICAgIEZJWE1FKCIoJXApIERpYWxvZ3MgY2Fubm90IGJlIGRpc2FibGVkIHlldFxuIiwgVGhpcyk7CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRDcmVhdGlvblBhcmFtZXRlcnMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEREVWSUNFX0NSRUFUSU9OX1BBUkFNRVRFUlMgKnBQYXJhbWV0ZXJzKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiBwUGFyYW1ldGVycyAlcFxuIiwgVGhpcywgcFBhcmFtZXRlcnMpOwoKICAgICpwUGFyYW1ldGVycyA9IFRoaXMtPmNyZWF0ZVBhcm1zOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0R2FtbWFSYW1wKElXaW5lRDNERGV2aWNlICogaWZhY2UsIFVJTlQgaVN3YXBDaGFpbiwgRFdPUkQgRmxhZ3MsIENPTlNUIFdJTkVEM0RHQU1NQVJBTVAqIHBSYW1wKSB7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcGNoYWluOwoKICAgIFRSQUNFKCJSZWxheWluZyAgdG8gc3dhcGNoYWluXG4iKTsKCiAgICBpZiAoSVdpbmVEM0REZXZpY2VJbXBsX0dldFN3YXBDaGFpbihpZmFjZSwgaVN3YXBDaGFpbiwgJnN3YXBjaGFpbikgPT0gV0lORUQzRF9PSykgewogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1NldEdhbW1hUmFtcChzd2FwY2hhaW4sIEZsYWdzLCAoV0lORUQzREdBTU1BUkFNUCAqKXBSYW1wKTsKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKHN3YXBjaGFpbik7CiAgICB9CiAgICByZXR1cm47Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0R2FtbWFSYW1wKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBpU3dhcENoYWluLCBXSU5FRDNER0FNTUFSQU1QKiBwUmFtcCkgewogICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBjaGFpbjsKCiAgICBUUkFDRSgiUmVsYXlpbmcgIHRvIHN3YXBjaGFpblxuIik7CgogICAgaWYgKElXaW5lRDNERGV2aWNlSW1wbF9HZXRTd2FwQ2hhaW4oaWZhY2UsIGlTd2FwQ2hhaW4sICZzd2FwY2hhaW4pID09IFdJTkVEM0RfT0spIHsKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9HZXRHYW1tYVJhbXAoc3dhcGNoYWluLCBwUmFtcCk7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwY2hhaW4pOwogICAgfQogICAgcmV0dXJuOwp9CgoKLyoqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogICBOb3RpZmljYXRpb24gZnVuY3Rpb25zCioqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiogVGhpcyBmdW5jdGlvbiBtdXN0IGJlIGNhbGxlZCBpbiB0aGUgcmVsZWFzZSBvZiBhIHJlc291cmNlIHdoZW4gcmVmID09IDAsCiogdGhlIGNvbnRlbnRzIG9mIHJlc291cmNlIG11c3Qgc3RpbGwgYmUgY29ycmVjdCwKKiBhbnkgaGFuZGxlcyB0byBvdGhlciByZXNvdXJjZSBoZWxkIGJ5IHRoZSBjYWxsZXIgbXVzdCBiZSBjbG9zZWQKKiAoZS5nLiBhIHRleHR1cmUgc2hvdWxkIHJlbGVhc2UgYWxsIGhlbGQgc3VyZmFjZXMgYmVjYXVzZSB0ZWxsaW5nIHRoZSBkZXZpY2UgdGhhdCBpdCdzIGJlZW4gcmVsZWFzZWQuKQogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyB2b2lkIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQWRkUmVzb3VyY2UoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFJlc291cmNlICpyZXNvdXJjZSl7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCkgOiBBZGRpbmcgUmVzb3VyY2UgJXBcbiIsIFRoaXMsIHJlc291cmNlKTsKICAgIGxpc3RfYWRkX2hlYWQoJlRoaXMtPnJlc291cmNlcywgJigoSVdpbmVEM0RSZXNvdXJjZUltcGwgKikgcmVzb3VyY2UpLT5yZXNvdXJjZS5yZXNvdXJjZV9saXN0X2VudHJ5KTsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9SZW1vdmVSZXNvdXJjZShJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEUmVzb3VyY2UgKnJlc291cmNlKXsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKSA6IFJlbW92aW5nIHJlc291cmNlICVwXG4iLCBUaGlzLCByZXNvdXJjZSk7CgogICAgbGlzdF9yZW1vdmUoJigoSVdpbmVEM0RSZXNvdXJjZUltcGwgKikgcmVzb3VyY2UpLT5yZXNvdXJjZS5yZXNvdXJjZV9saXN0X2VudHJ5KTsKfQoKCnN0YXRpYyB2b2lkIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfUmVzb3VyY2VSZWxlYXNlZChJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEUmVzb3VyY2UgKnJlc291cmNlKXsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBpbnQgY291bnRlcjsKCiAgICBUUkFDRSgiKCVwKSA6IHJlc291cmNlICVwXG4iLCBUaGlzLCByZXNvdXJjZSk7CiAgICBzd2l0Y2goSVdpbmVEM0RSZXNvdXJjZV9HZXRUeXBlKHJlc291cmNlKSl7CiAgICAgICAgLyogVE9ETzogY2hlY2sgZnJvbnQgYW5kIGJhY2sgYnVmZmVycywgcmVuZGVydGFyZ2V0cyBldGMuLiAgcG9zc2libHkgc3dhcGNoYWlucz8gKi8KICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9TVVJGQUNFOiB7CiAgICAgICAgICAgIHVuc2lnbmVkIGludCBpOwoKICAgICAgICAgICAgLyogQ2xlYW51cCBhbnkgRkJPIGF0dGFjaG1lbnRzIGlmIGQzZCBpcyBlbmFibGVkICovCiAgICAgICAgICAgIGlmKFRoaXMtPmQzZF9pbml0aWFsaXplZCkgewogICAgICAgICAgICAgICAgaWYoKElXaW5lRDNEU3VyZmFjZSAqKXJlc291cmNlID09IFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQpIHsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN3YXBDaGFpbkltcGwgKnN3YXBjaGFpbiA9IFRoaXMtPnN3YXBjaGFpbnMgPyAoSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICopIFRoaXMtPnN3YXBjaGFpbnNbMF0gOiBOVUxMOwoKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiTGFzdCBhY3RpdmUgcmVuZGVyIHRhcmdldCBkZXN0cm95ZWRcbiIpOwogICAgICAgICAgICAgICAgICAgIC8qIEZpbmQgYSByZXBsYWNlbWVudCBzdXJmYWNlIGZvciB0aGUgY3VycmVudGx5IGFjdGl2ZSBiYWNrIGJ1ZmZlci4gVGhlIGNvbnRleHQgbWFuYWdlciBkb2VzIG5vdCBkbyBOVUxMCiAgICAgICAgICAgICAgICAgICAgICogY2hlY2tzLCBzbyBzd2l0Y2ggdG8gYSB2YWxpZCB0YXJnZXQgYXMgbG9uZyBhcyB0aGUgY3VycmVudGx5IHNldCBzdXJmYWNlIGlzIHN0aWxsIHZhbGlkLiBVc2UgdGhlCiAgICAgICAgICAgICAgICAgICAgICogc3VyZmFjZSBvZiB0aGUgaW1wbGljaXQgc3dwY2hhaW4uIElmIHRoYXQgaXMgdGhlIHNhbWUgYXMgdGhlIGRlc3Ryb3llZCBzdXJmYWNlIHRoZSBkZXZpY2UgaXMgZGVzdHJveWVkCiAgICAgICAgICAgICAgICAgICAgICogYW5kIHRoZSBsYXN0QWN0aXZlUmVuZGVyVGFyZ2V0IG1lbWJlciBzaG91bGRuJ3QgbWF0dGVyCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgaWYoc3dhcGNoYWluKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHN3YXBjaGFpbi0+YmFja0J1ZmZlciAmJiBzd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0gIT0gKElXaW5lRDNEU3VyZmFjZSAqKXJlc291cmNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUkFDRSgiQWN0aXZhdGluZyBwcmltYXJ5IGJhY2sgYnVmZmVyXG4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBzd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0sIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZighc3dhcGNoYWluLT5iYWNrQnVmZmVyICYmIHN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIgIT0gKElXaW5lRDNEU3VyZmFjZSAqKXJlc291cmNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBTaW5nbGUgYnVmZmVyaW5nIGVudmlyb25tZW50ICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUkFDRSgiQWN0aXZhdGluZyBwcmltYXJ5IGZyb250IGJ1ZmZlclxuIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBBY3RpdmF0ZUNvbnRleHQoVGhpcywgc3dhcGNoYWluLT5mcm9udEJ1ZmZlciwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFKCJEZXZpY2UgaXMgYmVpbmcgZGVzdHJveWVkLCBzZXR0aW5nIGxhc3RBY3RpdmVSZW5kZXJUYXJnZXQgPSAweGRlYWRiYWJlXG4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIEltcGxpY2l0IHJlbmRlciB0YXJnZXQgZGVzdHJveWVkLCB0aGF0IG1lYW5zIHRoZSBkZXZpY2UgaXMgYmVpbmcgZGVzdHJveWVkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiB3aGF0ZXZlciB3ZSBzZXQgaGVyZSwgaXQgc2hvdWxkbid0IG1hdHRlcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0ID0gKElXaW5lRDNEU3VyZmFjZSAqKSAweGRlYWRiYWJlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogTWF5IGhhcHBlbiBkdXJpbmcgZGRyYXcgdW5pbml0aWFsaXphdGlvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICBUUkFDRSgiUmVuZGVyIHRhcmdldCBzZXQsIGJ1dCBzd2FwY2hhaW4gZG9lcyBub3QgZXhpc3QhXG4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCA9IChJV2luZUQzRFN1cmZhY2UgKikgMHhkZWFkY2FmZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgRU5URVJfR0woKTsKICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBHTF9MSU1JVFMoYnVmZmVycyk7ICsraSkgewogICAgICAgICAgICAgICAgICAgIGlmIChUaGlzLT5mYm9fY29sb3JfYXR0YWNobWVudHNbaV0gPT0gKElXaW5lRDNEU3VyZmFjZSAqKXJlc291cmNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJpbmRfZmJvKGlmYWNlLCBHTF9GUkFNRUJVRkZFUl9FWFQsICZUaGlzLT5mYm8pOwogICAgICAgICAgICAgICAgICAgICAgICBzZXRfcmVuZGVyX3RhcmdldF9mYm8oaWZhY2UsIGksIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5mYm9fY29sb3JfYXR0YWNobWVudHNbaV0gPSBOVUxMOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChUaGlzLT5mYm9fZGVwdGhfYXR0YWNobWVudCA9PSAoSVdpbmVEM0RTdXJmYWNlICopcmVzb3VyY2UpIHsKICAgICAgICAgICAgICAgICAgICBiaW5kX2ZibyhpZmFjZSwgR0xfRlJBTUVCVUZGRVJfRVhULCAmVGhpcy0+ZmJvKTsKICAgICAgICAgICAgICAgICAgICBzZXRfZGVwdGhfc3RlbmNpbF9mYm8oaWZhY2UsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgIFRoaXMtPmZib19kZXB0aF9hdHRhY2htZW50ID0gTlVMTDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9URVhUVVJFOgogICAgICAgIGNhc2UgV0lORUQzRFJUWVBFX0NVQkVURVhUVVJFOgogICAgICAgIGNhc2UgV0lORUQzRFJUWVBFX1ZPTFVNRVRFWFRVUkU6CiAgICAgICAgICAgICAgICBmb3IgKGNvdW50ZXIgPSAwOyBjb3VudGVyIDwgTUFYX0NPTUJJTkVEX1NBTVBMRVJTOyBjb3VudGVyKyspIHsKICAgICAgICAgICAgICAgICAgICBpZiAoVGhpcy0+c3RhdGVCbG9jayAhPSBOVUxMICYmIFRoaXMtPnN0YXRlQmxvY2stPnRleHR1cmVzW2NvdW50ZXJdID09IChJV2luZUQzREJhc2VUZXh0dXJlICopcmVzb3VyY2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgV0FSTigiVGV4dHVyZSBiZWluZyByZWxlYXNlZCBpcyBzdGlsbCBieSBhIHN0YXRlYmxvY2ssIFN0YWdlID0gJXUgVGV4dHVyZSA9ICVwXG4iLCBjb3VudGVyLCByZXNvdXJjZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPnRleHR1cmVzW2NvdW50ZXJdID0gTlVMTDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaWYgKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2sgIT0gVGhpcy0+c3RhdGVCbG9jayApewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZXNbY291bnRlcl0gPT0gKElXaW5lRDNEQmFzZVRleHR1cmUgKilyZXNvdXJjZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgV0FSTigiVGV4dHVyZSBiZWluZyByZWxlYXNlZCBpcyBzdGlsbCBieSBhIHN0YXRlYmxvY2ssIFN0YWdlID0gJXUgVGV4dHVyZSA9ICVwXG4iLCBjb3VudGVyLCByZXNvdXJjZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlc1tjb3VudGVyXSA9IE5VTEw7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEUlRZUEVfVk9MVU1FOgogICAgICAgIC8qIFRPRE86IG5vdGhpbmcgcmVhbGx5PyAqLwogICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgV0lORUQzRFJUWVBFX1ZFUlRFWEJVRkZFUjoKICAgICAgICAvKiBNU0ROOiBXaGVuIGFuIGFwcGxpY2F0aW9uIG5vIGxvbmdlciBob2xkcyBhIHJlZmVyZW5jZXMgdG8gdGhpcyBpbnRlcmZhY2UsIHRoZSBpbnRlcmZhY2Ugd2lsbCBhdXRvbWF0aWNhbGx5IGJlIGZyZWVkLiAqLwogICAgICAgIHsKICAgICAgICAgICAgaW50IHN0cmVhbU51bWJlcjsKICAgICAgICAgICAgVFJBQ0UoIkNsZWFuaW5nIHVwIHN0cmVhbSBwb2ludGVyc1xuIik7CgogICAgICAgICAgICBmb3Ioc3RyZWFtTnVtYmVyID0gMDsgc3RyZWFtTnVtYmVyIDwgTUFYX1NUUkVBTVM7IHN0cmVhbU51bWJlciArKyl7CiAgICAgICAgICAgICAgICAvKiBGSU5ET1VUOiBzaG91bGQgYSB3YXJuIGJlIGdlbmVyYXRlZCBpZiB3ZXJlIHJlY29yZGluZyBhbmQgdXBkYXRlU3RhdGVCbG9jay0+c3RyZWFtU291cmNlIGlzIGxvc3Q/CiAgICAgICAgICAgICAgICBGSU5ET1VUOiBzaG91bGQgY2hhbmdlcy5zdHJlYW1Tb3VyY2VbU3RyZWFtTnVtYmVyXSBiZSBzZXQgPwogICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmIChUaGlzLT51cGRhdGVTdGF0ZUJsb2NrICE9IE5VTEwgKSB7IC8qID09TlVMTCB3aGVuIGRldmljZSBpcyBiZWluZyBkZXN0cm95ZWQgKi8KICAgICAgICAgICAgICAgICAgICBpZiAoKElXaW5lRDNEUmVzb3VyY2UgKilUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2Vbc3RyZWFtTnVtYmVyXSA9PSByZXNvdXJjZSkgewogICAgICAgICAgICAgICAgICAgICAgICBGSVhNRSgiVmVydGV4IGJ1ZmZlciByZWxlYXNlZCB3aGlsZSBib3VuZCB0byBhIHN0YXRlIGJsb2NrLCBzdHJlYW0gJWRcbiIsIHN0cmVhbU51bWJlcik7CiAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtzdHJlYW1OdW1iZXJdID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgLyogU2V0IGNoYW5nZWQgZmxhZz8gKi8KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoVGhpcy0+c3RhdGVCbG9jayAhPSBOVUxMICkgeyAvKiBvbmx5IGhhcHBlbnMgaWYgdGhlcmUgaXMgYW4gZXJyb3IgaW4gdGhlIGFwcGxpY2F0aW9uLCBvciBvbiByZXNldC9yZWxlYXNlIChiZWNhdXNlIHdlIGRvbid0IG1hbmFnZSBpbnRlcm5hbCB0cmFja2luZyBwcm9wZXJseSkgKi8KICAgICAgICAgICAgICAgICAgICBpZiAoKElXaW5lRDNEUmVzb3VyY2UgKilUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2Vbc3RyZWFtTnVtYmVyXSA9PSByZXNvdXJjZSkgewogICAgICAgICAgICAgICAgICAgICAgICBUUkFDRSgiVmVydGV4IGJ1ZmZlciByZWxlYXNlZCB3aGlsZSBib3VuZCB0byBhIHN0YXRlIGJsb2NrLCBzdHJlYW0gJWRcbiIsIHN0cmVhbU51bWJlcik7CiAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtzdHJlYW1OdW1iZXJdID0gMDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiNpZiAwICAgLyogVE9ETzogTWFuYWdlIGludGVybmFsIHRyYWNraW5nIHByb3Blcmx5IHNvIHRoYXQgJ3RoaXMgc2hvdWxkbid0IGhhcHBlbicgKi8KICAgICAgICAgICAgICAgICBlbHNlIHsgLyogVGhpcyBzaG91bGRuJ3QgaGFwcGVuICovCiAgICAgICAgICAgICAgICAgICAgRklYTUUoIkNhbGxpbmcgYXBwbGljYXRpb24gaGFzIHJlbGVhc2VkIHRoZSBkZXZpY2UgYmVmb3JlIHJlbGFzaW5nIGFsbCB0aGUgcmVzb3VyY2VzIGJvdW5kIHRvIHRoZSBkZXZpY2VcbiIpOwogICAgICAgICAgICAgICAgfQojZW5kaWYKCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEUlRZUEVfSU5ERVhCVUZGRVI6CiAgICAgICAgLyogTVNETjogV2hlbiBhbiBhcHBsaWNhdGlvbiBubyBsb25nZXIgaG9sZHMgYSByZWZlcmVuY2VzIHRvIHRoaXMgaW50ZXJmYWNlLCB0aGUgaW50ZXJmYWNlIHdpbGwgYXV0b21hdGljYWxseSBiZSBmcmVlZC4qLwogICAgICAgIGlmIChUaGlzLT51cGRhdGVTdGF0ZUJsb2NrICE9IE5VTEwgKSB7IC8qID09TlVMTCB3aGVuIGRldmljZSBpcyBiZWluZyBkZXN0cm95ZWQgKi8KICAgICAgICAgICAgaWYgKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnBJbmRleERhdGEgPT0gKElXaW5lRDNESW5kZXhCdWZmZXIgKilyZXNvdXJjZSkgewogICAgICAgICAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+cEluZGV4RGF0YSA9ICBOVUxMOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChUaGlzLT5zdGF0ZUJsb2NrICE9IE5VTEwgKSB7IC8qID09TlVMTCB3aGVuIGRldmljZSBpcyBiZWluZyBkZXN0cm95ZWQgKi8KICAgICAgICAgICAgaWYgKFRoaXMtPnN0YXRlQmxvY2stPnBJbmRleERhdGEgPT0gKElXaW5lRDNESW5kZXhCdWZmZXIgKilyZXNvdXJjZSkgewogICAgICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+cEluZGV4RGF0YSA9ICBOVUxMOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgIEZJWE1FKCIoJXApIHVua25vd24gcmVzb3VyY2UgdHlwZSAlcCAldVxuIiwgVGhpcywgcmVzb3VyY2UsIElXaW5lRDNEUmVzb3VyY2VfR2V0VHlwZShyZXNvdXJjZSkpOwogICAgICAgIGJyZWFrOwogICAgfQoKCiAgICAvKiBSZW1vdmUgdGhlIHJlc291cmNlIGZyb20gdGhlIHJlc291cmNlU3RvcmUgKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9SZW1vdmVSZXNvdXJjZShpZmFjZSwgcmVzb3VyY2UpOwoKICAgIFRSQUNFKCJSZXNvdXJjZSByZWxlYXNlZFxuIik7Cgp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0VudW1SZXNvdXJjZXMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEM0RDQl9FTlVNUkVTT1VSQ0VTIHBDYWxsYmFjaywgdm9pZCAqcERhdGEpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFJlc291cmNlSW1wbCAqcmVzb3VyY2UsICpjdXJzb3I7CiAgICBIUkVTVUxUIHJldDsKICAgIFRSQUNFKCIoJXApLT4oJXAsJXApXG4iLCBUaGlzLCBwQ2FsbGJhY2ssIHBEYXRhKTsKCiAgICBMSVNUX0ZPUl9FQUNIX0VOVFJZX1NBRkUocmVzb3VyY2UsIGN1cnNvciwgJlRoaXMtPnJlc291cmNlcywgSVdpbmVEM0RSZXNvdXJjZUltcGwsIHJlc291cmNlLnJlc291cmNlX2xpc3RfZW50cnkpIHsKICAgICAgICBUUkFDRSgiZW51bWVyYXRpbmcgcmVzb3VyY2UgJXBcbiIsIHJlc291cmNlKTsKICAgICAgICBJV2luZUQzRFJlc291cmNlX0FkZFJlZigoSVdpbmVEM0RSZXNvdXJjZSAqKSByZXNvdXJjZSk7CiAgICAgICAgcmV0ID0gcENhbGxiYWNrKChJV2luZUQzRFJlc291cmNlICopIHJlc291cmNlLCBwRGF0YSk7CiAgICAgICAgaWYocmV0ID09IFNfRkFMU0UpIHsKICAgICAgICAgICAgVFJBQ0UoIkNhbmNlbGluZyBlbnVtZXJhdGlvblxuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRERldmljZSBWVGJsIGZvbGxvd3MKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpjb25zdCBJV2luZUQzRERldmljZVZ0YmwgSVdpbmVEM0REZXZpY2VfVnRibCA9CnsKICAgIC8qKiogSVVua25vd24gbWV0aG9kcyAqKiovCiAgICBJV2luZUQzRERldmljZUltcGxfUXVlcnlJbnRlcmZhY2UsCiAgICBJV2luZUQzRERldmljZUltcGxfQWRkUmVmLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1JlbGVhc2UsCiAgICAvKioqIElXaW5lRDNERGV2aWNlIG1ldGhvZHMgKioqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFBhcmVudCwKICAgIC8qKiogQ3JlYXRpb24gbWV0aG9kcyoqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZlcnRleEJ1ZmZlciwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVJbmRleEJ1ZmZlciwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVTdGF0ZUJsb2NrLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVN1cmZhY2UsCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVGV4dHVyZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWb2x1bWVUZXh0dXJlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZvbHVtZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVDdWJlVGV4dHVyZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVRdWVyeSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVBZGRpdGlvbmFsU3dhcENoYWluLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZlcnRleERlY2xhcmF0aW9uLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZlcnRleERlY2xhcmF0aW9uRnJvbUZWRiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWZXJ0ZXhTaGFkZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlUGl4ZWxTaGFkZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlUGFsZXR0ZSwKICAgIC8qKiogT2RkIGZ1bmN0aW9ucyAqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9Jbml0M0QsCiAgICBJV2luZUQzRERldmljZUltcGxfVW5pbml0M0QsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0RnVsbHNjcmVlbiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRNdWx0aXRocmVhZGVkLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0V2aWN0TWFuYWdlZFJlc291cmNlcywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRBdmFpbGFibGVUZXh0dXJlTWVtLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEJhY2tCdWZmZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0Q3JlYXRpb25QYXJhbWV0ZXJzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldERldmljZUNhcHMsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0RGlyZWN0M0QsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0RGlzcGxheU1vZGUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0RGlzcGxheU1vZGUsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0SFdORCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRIV05ELAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldE51bWJlck9mU3dhcENoYWlucywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRSYXN0ZXJTdGF0dXMsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0U3dhcENoYWluLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1Jlc2V0LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldERpYWxvZ0JveE1vZGUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0Q3Vyc29yUHJvcGVydGllcywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRDdXJzb3JQb3NpdGlvbiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TaG93Q3Vyc29yLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1Rlc3RDb29wZXJhdGl2ZUxldmVsLAogICAgLyoqKiBHZXR0ZXJzIGFuZCBzZXR0ZXJzICoqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldENsaXBQbGFuZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRDbGlwUGxhbmUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0Q2xpcFN0YXR1cywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRDbGlwU3RhdHVzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEN1cnJlbnRUZXh0dXJlUGFsZXR0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRDdXJyZW50VGV4dHVyZVBhbGV0dGUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0RGVwdGhTdGVuY2lsU3VyZmFjZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXREZXB0aFN0ZW5jaWxTdXJmYWNlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEZWRiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRGVkYsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0R2FtbWFSYW1wLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEdhbW1hUmFtcCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRJbmRpY2VzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEluZGljZXMsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0QmFzZVZlcnRleEluZGV4LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEJhc2VWZXJ0ZXhJbmRleCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRMaWdodCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRMaWdodCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRMaWdodEVuYWJsZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRMaWdodEVuYWJsZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRNYXRlcmlhbCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRNYXRlcmlhbCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXROUGF0Y2hNb2RlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldE5QYXRjaE1vZGUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0UGFsZXR0ZUVudHJpZXMsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UGFsZXR0ZUVudHJpZXMsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0UGl4ZWxTaGFkZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UGl4ZWxTaGFkZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0UGl4ZWxTaGFkZXJDb25zdGFudEIsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UGl4ZWxTaGFkZXJDb25zdGFudEIsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0UGl4ZWxTaGFkZXJDb25zdGFudEksCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UGl4ZWxTaGFkZXJDb25zdGFudEksCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0UGl4ZWxTaGFkZXJDb25zdGFudEYsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UGl4ZWxTaGFkZXJDb25zdGFudEYsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0UmVuZGVyU3RhdGUsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UmVuZGVyU3RhdGUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0UmVuZGVyVGFyZ2V0LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFJlbmRlclRhcmdldCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRGcm9udEJhY2tCdWZmZXJzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFNhbXBsZXJTdGF0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTYW1wbGVyU3RhdGUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0U2Npc3NvclJlY3QsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0U2Npc3NvclJlY3QsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0U29mdHdhcmVWZXJ0ZXhQcm9jZXNzaW5nLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFNvZnR3YXJlVmVydGV4UHJvY2Vzc2luZywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRTdHJlYW1Tb3VyY2UsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0U3RyZWFtU291cmNlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFN0cmVhbVNvdXJjZUZyZXEsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0U3RyZWFtU291cmNlRnJlcSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRUZXh0dXJlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFRleHR1cmUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0VGV4dHVyZVN0YWdlU3RhdGUsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0VGV4dHVyZVN0YWdlU3RhdGUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0VHJhbnNmb3JtLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFRyYW5zZm9ybSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWZXJ0ZXhEZWNsYXJhdGlvbiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWZXJ0ZXhEZWNsYXJhdGlvbiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWZXJ0ZXhTaGFkZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0VmVydGV4U2hhZGVyLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZlcnRleFNoYWRlckNvbnN0YW50QiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEIsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0VmVydGV4U2hhZGVyQ29uc3RhbnRJLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZlcnRleFNoYWRlckNvbnN0YW50SSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEYsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0VmVydGV4U2hhZGVyQ29uc3RhbnRGLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZpZXdwb3J0LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZpZXdwb3J0LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX011bHRpcGx5VHJhbnNmb3JtLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1ZhbGlkYXRlRGV2aWNlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1Byb2Nlc3NWZXJ0aWNlcywKICAgIC8qKiogU3RhdGUgYmxvY2sgKioqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX0JlZ2luU3RhdGVCbG9jaywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9FbmRTdGF0ZUJsb2NrLAogICAgLyoqKiBTY2VuZSBtYW5hZ2VtZW50ICoqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9CZWdpblNjZW5lLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0VuZFNjZW5lLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1ByZXNlbnQsCiAgICBJV2luZUQzRERldmljZUltcGxfQ2xlYXIsCiAgICAvKioqIERyYXdpbmcgKioqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdQcmltaXRpdmUsCiAgICBJV2luZUQzRERldmljZUltcGxfRHJhd0luZGV4ZWRQcmltaXRpdmUsCiAgICBJV2luZUQzRERldmljZUltcGxfRHJhd1ByaW1pdGl2ZVVQLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdJbmRleGVkUHJpbWl0aXZlVVAsCiAgICBJV2luZUQzRERldmljZUltcGxfRHJhd1ByaW1pdGl2ZVN0cmlkZWQsCiAgICBJV2luZUQzRERldmljZUltcGxfRHJhd0luZGV4ZWRQcmltaXRpdmVTdHJpZGVkLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdSZWN0UGF0Y2gsCiAgICBJV2luZUQzRERldmljZUltcGxfRHJhd1RyaVBhdGNoLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0RlbGV0ZVBhdGNoLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NvbG9yRmlsbCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9VcGRhdGVUZXh0dXJlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1VwZGF0ZVN1cmZhY2UsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0RnJvbnRCdWZmZXJEYXRhLAogICAgLyoqKiBvYmplY3QgdHJhY2tpbmcgKioqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX1Jlc291cmNlUmVsZWFzZWQsCiAgICBJV2luZUQzRERldmljZUltcGxfRW51bVJlc291cmNlcwp9OwoKY29uc3QgSVdpbmVEM0REZXZpY2VWdGJsIElXaW5lRDNERGV2aWNlX0RpcnR5Q29uc3RfVnRibCA9CnsKICAgIC8qKiogSVVua25vd24gbWV0aG9kcyAqKiovCiAgICBJV2luZUQzRERldmljZUltcGxfUXVlcnlJbnRlcmZhY2UsCiAgICBJV2luZUQzRERldmljZUltcGxfQWRkUmVmLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1JlbGVhc2UsCiAgICAvKioqIElXaW5lRDNERGV2aWNlIG1ldGhvZHMgKioqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFBhcmVudCwKICAgIC8qKiogQ3JlYXRpb24gbWV0aG9kcyoqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZlcnRleEJ1ZmZlciwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVJbmRleEJ1ZmZlciwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVTdGF0ZUJsb2NrLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVN1cmZhY2UsCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVGV4dHVyZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWb2x1bWVUZXh0dXJlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZvbHVtZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVDdWJlVGV4dHVyZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVRdWVyeSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVBZGRpdGlvbmFsU3dhcENoYWluLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZlcnRleERlY2xhcmF0aW9uLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZlcnRleERlY2xhcmF0aW9uRnJvbUZWRiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWZXJ0ZXhTaGFkZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlUGl4ZWxTaGFkZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlUGFsZXR0ZSwKICAgIC8qKiogT2RkIGZ1bmN0aW9ucyAqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9Jbml0M0QsCiAgICBJV2luZUQzRERldmljZUltcGxfVW5pbml0M0QsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0RnVsbHNjcmVlbiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRNdWx0aXRocmVhZGVkLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0V2aWN0TWFuYWdlZFJlc291cmNlcywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRBdmFpbGFibGVUZXh0dXJlTWVtLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEJhY2tCdWZmZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0Q3JlYXRpb25QYXJhbWV0ZXJzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldERldmljZUNhcHMsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0RGlyZWN0M0QsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0RGlzcGxheU1vZGUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0RGlzcGxheU1vZGUsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0SFdORCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRIV05ELAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldE51bWJlck9mU3dhcENoYWlucywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRSYXN0ZXJTdGF0dXMsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0U3dhcENoYWluLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1Jlc2V0LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldERpYWxvZ0JveE1vZGUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0Q3Vyc29yUHJvcGVydGllcywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRDdXJzb3JQb3NpdGlvbiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TaG93Q3Vyc29yLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1Rlc3RDb29wZXJhdGl2ZUxldmVsLAogICAgLyoqKiBHZXR0ZXJzIGFuZCBzZXR0ZXJzICoqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldENsaXBQbGFuZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRDbGlwUGxhbmUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0Q2xpcFN0YXR1cywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRDbGlwU3RhdHVzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEN1cnJlbnRUZXh0dXJlUGFsZXR0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRDdXJyZW50VGV4dHVyZVBhbGV0dGUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0RGVwdGhTdGVuY2lsU3VyZmFjZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXREZXB0aFN0ZW5jaWxTdXJmYWNlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEZWRiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRGVkYsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0R2FtbWFSYW1wLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEdhbW1hUmFtcCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRJbmRpY2VzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEluZGljZXMsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0QmFzZVZlcnRleEluZGV4LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEJhc2VWZXJ0ZXhJbmRleCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRMaWdodCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRMaWdodCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRMaWdodEVuYWJsZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRMaWdodEVuYWJsZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRNYXRlcmlhbCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRNYXRlcmlhbCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXROUGF0Y2hNb2RlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldE5QYXRjaE1vZGUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0UGFsZXR0ZUVudHJpZXMsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UGFsZXR0ZUVudHJpZXMsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0UGl4ZWxTaGFkZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UGl4ZWxTaGFkZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0UGl4ZWxTaGFkZXJDb25zdGFudEIsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UGl4ZWxTaGFkZXJDb25zdGFudEIsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0UGl4ZWxTaGFkZXJDb25zdGFudEksCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UGl4ZWxTaGFkZXJDb25zdGFudEksCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0UGl4ZWxTaGFkZXJDb25zdGFudEZfRGlydHlDb25zdCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQaXhlbFNoYWRlckNvbnN0YW50RiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRSZW5kZXJTdGF0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRSZW5kZXJTdGF0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRSZW5kZXJUYXJnZXQsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UmVuZGVyVGFyZ2V0LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEZyb250QmFja0J1ZmZlcnMsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0U2FtcGxlclN0YXRlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFNhbXBsZXJTdGF0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRTY2lzc29yUmVjdCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTY2lzc29yUmVjdCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRTb2Z0d2FyZVZlcnRleFByb2Nlc3NpbmcsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0U29mdHdhcmVWZXJ0ZXhQcm9jZXNzaW5nLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFN0cmVhbVNvdXJjZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTdHJlYW1Tb3VyY2UsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0U3RyZWFtU291cmNlRnJlcSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTdHJlYW1Tb3VyY2VGcmVxLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFRleHR1cmUsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0VGV4dHVyZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRUZXh0dXJlU3RhZ2VTdGF0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRUZXh0dXJlU3RhZ2VTdGF0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRUcmFuc2Zvcm0sCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0VHJhbnNmb3JtLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZlcnRleERlY2xhcmF0aW9uLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZlcnRleERlY2xhcmF0aW9uLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZlcnRleFNoYWRlciwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWZXJ0ZXhTaGFkZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0VmVydGV4U2hhZGVyQ29uc3RhbnRCLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZlcnRleFNoYWRlckNvbnN0YW50QiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEksCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0VmVydGV4U2hhZGVyQ29uc3RhbnRJLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZlcnRleFNoYWRlckNvbnN0YW50Rl9EaXJ0eUNvbnN0LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZlcnRleFNoYWRlckNvbnN0YW50RiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWaWV3cG9ydCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWaWV3cG9ydCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NdWx0aXBseVRyYW5zZm9ybSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9WYWxpZGF0ZURldmljZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9Qcm9jZXNzVmVydGljZXMsCiAgICAvKioqIFN0YXRlIGJsb2NrICoqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9CZWdpblN0YXRlQmxvY2ssCiAgICBJV2luZUQzRERldmljZUltcGxfRW5kU3RhdGVCbG9jaywKICAgIC8qKiogU2NlbmUgbWFuYWdlbWVudCAqKiovCiAgICBJV2luZUQzRERldmljZUltcGxfQmVnaW5TY2VuZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9FbmRTY2VuZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9QcmVzZW50LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NsZWFyLAogICAgLyoqKiBEcmF3aW5nICoqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3UHJpbWl0aXZlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdJbmRleGVkUHJpbWl0aXZlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdQcmltaXRpdmVVUCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3SW5kZXhlZFByaW1pdGl2ZVVQLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdQcmltaXRpdmVTdHJpZGVkLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdJbmRleGVkUHJpbWl0aXZlU3RyaWRlZCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3UmVjdFBhdGNoLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdUcmlQYXRjaCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9EZWxldGVQYXRjaCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9Db2xvckZpbGwsCiAgICBJV2luZUQzRERldmljZUltcGxfVXBkYXRlVGV4dHVyZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9VcGRhdGVTdXJmYWNlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEZyb250QnVmZmVyRGF0YSwKICAgIC8qKiogb2JqZWN0IHRyYWNraW5nICoqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9SZXNvdXJjZVJlbGVhc2VkLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0VudW1SZXNvdXJjZXMKfTsKCmNvbnN0IERXT1JEIFNhdmVkUGl4ZWxTdGF0ZXNfUltOVU1fU0FWRURQSVhFTFNUQVRFU19SXSA9IHsKICAgIFdJTkVEM0RSU19BTFBIQUJMRU5ERU5BQkxFICAgLAogICAgV0lORUQzRFJTX0FMUEhBRlVOQyAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfQUxQSEFSRUYgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19BTFBIQVRFU1RFTkFCTEUgICAgLAogICAgV0lORUQzRFJTX0JMRU5ET1AgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfQ09MT1JXUklURUVOQUJMRSAgICwKICAgIFdJTkVEM0RSU19ERVNUQkxFTkQgICAgICAgICAgLAogICAgV0lORUQzRFJTX0RJVEhFUkVOQUJMRSAgICAgICAsCiAgICBXSU5FRDNEUlNfRklMTE1PREUgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19GT0dERU5TSVRZICAgICAgICAgLAogICAgV0lORUQzRFJTX0ZPR0VORCAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRk9HU1RBUlQgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19MQVNUUElYRUwgICAgICAgICAgLAogICAgV0lORUQzRFJTX1NIQURFTU9ERSAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfU1JDQkxFTkQgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19TVEVOQ0lMRU5BQkxFICAgICAgLAogICAgV0lORUQzRFJTX1NURU5DSUxGQUlMICAgICAgICAsCiAgICBXSU5FRDNEUlNfU1RFTkNJTEZVTkMgICAgICAgICwKICAgIFdJTkVEM0RSU19TVEVOQ0lMTUFTSyAgICAgICAgLAogICAgV0lORUQzRFJTX1NURU5DSUxQQVNTICAgICAgICAsCiAgICBXSU5FRDNEUlNfU1RFTkNJTFJFRiAgICAgICAgICwKICAgIFdJTkVEM0RSU19TVEVOQ0lMV1JJVEVNQVNLICAgLAogICAgV0lORUQzRFJTX1NURU5DSUxaRkFJTCAgICAgICAsCiAgICBXSU5FRDNEUlNfVEVYVFVSRUZBQ1RPUiAgICAgICwKICAgIFdJTkVEM0RSU19XUkFQMCAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1dSQVAxICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfV1JBUDIgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19XUkFQMyAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1dSQVA0ICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfV1JBUDUgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19XUkFQNiAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1dSQVA3ICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfWkVOQUJMRSAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19aRlVOQyAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1pXUklURUVOQUJMRQp9OwoKY29uc3QgRFdPUkQgU2F2ZWRQaXhlbFN0YXRlc19UW05VTV9TQVZFRFBJWEVMU1RBVEVTX1RdID0gewogICAgV0lORUQzRFRTU19BRERSRVNTVyAgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19BTFBIQUFSRzAgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19BTFBIQUFSRzEgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19BTFBIQUFSRzIgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19BTFBIQU9QICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19CVU1QRU5WTE9GRlNFVCAgICAgICAgLAogICAgV0lORUQzRFRTU19CVU1QRU5WTFNDQUxFICAgICAgICAgLAogICAgV0lORUQzRFRTU19CVU1QRU5WTUFUMDAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19CVU1QRU5WTUFUMDEgICAgICAgICAgLAogICAgV0lORUQzRFRTU19CVU1QRU5WTUFUMTAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19CVU1QRU5WTUFUMTEgICAgICAgICAgLAogICAgV0lORUQzRFRTU19DT0xPUkFSRzAgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19DT0xPUkFSRzEgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19DT0xPUkFSRzIgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19DT0xPUk9QICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19SRVNVTFRBUkcgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19URVhDT09SRElOREVYICAgICAgICAgLAogICAgV0lORUQzRFRTU19URVhUVVJFVFJBTlNGT1JNRkxBR1MKfTsKCmNvbnN0IERXT1JEIFNhdmVkUGl4ZWxTdGF0ZXNfU1tOVU1fU0FWRURQSVhFTFNUQVRFU19TXSA9IHsKICAgIFdJTkVEM0RTQU1QX0FERFJFU1NVICAgICAgICAgLAogICAgV0lORUQzRFNBTVBfQUREUkVTU1YgICAgICAgICAsCiAgICBXSU5FRDNEU0FNUF9BRERSRVNTVyAgICAgICAgICwKICAgIFdJTkVEM0RTQU1QX0JPUkRFUkNPTE9SICAgICAgLAogICAgV0lORUQzRFNBTVBfTUFHRklMVEVSICAgICAgICAsCiAgICBXSU5FRDNEU0FNUF9NSU5GSUxURVIgICAgICAgICwKICAgIFdJTkVEM0RTQU1QX01JUEZJTFRFUiAgICAgICAgLAogICAgV0lORUQzRFNBTVBfTUlQTUFQTE9EQklBUyAgICAsCiAgICBXSU5FRDNEU0FNUF9NQVhNSVBMRVZFTCAgICAgICwKICAgIFdJTkVEM0RTQU1QX01BWEFOSVNPVFJPUFkgICAgLAogICAgV0lORUQzRFNBTVBfU1JHQlRFWFRVUkUgICAgICAsCiAgICBXSU5FRDNEU0FNUF9FTEVNRU5USU5ERVgKfTsKCmNvbnN0IERXT1JEIFNhdmVkVmVydGV4U3RhdGVzX1JbTlVNX1NBVkVEVkVSVEVYU1RBVEVTX1JdID0gewogICAgV0lORUQzRFJTX0FNQklFTlQgICAgICAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19BTUJJRU5UTUFURVJJQUxTT1VSQ0UgICAgICAgICAsCiAgICBXSU5FRDNEUlNfQ0xJUFBJTkcgICAgICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0NMSVBQTEFORUVOQUJMRSAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19DT0xPUlZFUlRFWCAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRElGRlVTRU1BVEVSSUFMU09VUkNFICAgICAgICAgLAogICAgV0lORUQzRFJTX0VNSVNTSVZFTUFURVJJQUxTT1VSQ0UgICAgICAgICwKICAgIFdJTkVEM0RSU19GT0dERU5TSVRZICAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRk9HRU5EICAgICAgICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0ZPR1NUQVJUICAgICAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19GT0dUQUJMRU1PREUgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRk9HVkVSVEVYTU9ERSAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0lOREVYRURWRVJURVhCTEVOREVOQUJMRSAgICAgICwKICAgIFdJTkVEM0RSU19MSUdIVElORyAgICAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfTE9DQUxWSUVXRVIgICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX01VTFRJU0FNUExFQU5USUFMSUFTICAgICAgICAgICwKICAgIFdJTkVEM0RSU19NVUxUSVNBTVBMRU1BU0sgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfTk9STUFMSVpFTk9STUFMUyAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1BBVENIRURHRVNUWUxFICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19QT0lOVFNDQUxFX0EgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfUE9JTlRTQ0FMRV9CICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1BPSU5UU0NBTEVfQyAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19QT0lOVFNDQUxFRU5BQkxFICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfUE9JTlRTSVpFICAgICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1BPSU5UU0laRV9NQVggICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19QT0lOVFNJWkVfTUlOICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfUE9JTlRTUFJJVEVFTkFCTEUgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1JBTkdFRk9HRU5BQkxFICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19TUEVDVUxBUk1BVEVSSUFMU09VUkNFICAgICAgICAsCiAgICBXSU5FRDNEUlNfVFdFRU5GQUNUT1IgICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1ZFUlRFWEJMRU5EICAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19DVUxMTU9ERSAgICAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRk9HQ09MT1IKfTsKCmNvbnN0IERXT1JEIFNhdmVkVmVydGV4U3RhdGVzX1RbTlVNX1NBVkVEVkVSVEVYU1RBVEVTX1RdID0gewogICAgV0lORUQzRFRTU19URVhDT09SRElOREVYICAgICAgICAgLAogICAgV0lORUQzRFRTU19URVhUVVJFVFJBTlNGT1JNRkxBR1MKfTsKCmNvbnN0IERXT1JEIFNhdmVkVmVydGV4U3RhdGVzX1NbTlVNX1NBVkVEVkVSVEVYU1RBVEVTX1NdID0gewogICAgV0lORUQzRFNBTVBfRE1BUE9GRlNFVAp9OwoKdm9pZCBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzLCBEV09SRCBzdGF0ZSkgewogICAgRFdPUkQgcmVwID0gVGhpcy0+c2hhZGVyX2JhY2tlbmQtPlN0YXRlVGFibGVbc3RhdGVdLnJlcHJlc2VudGF0aXZlOwogICAgRFdPUkQgaWR4OwogICAgQllURSBzaGlmdDsKICAgIFVJTlQgaTsKICAgIFdpbmVEM0RDb250ZXh0ICpjb250ZXh0OwoKICAgIGlmKCFyZXApIHJldHVybjsKICAgIGZvcihpID0gMDsgaSA8IFRoaXMtPm51bUNvbnRleHRzOyBpKyspIHsKICAgICAgICBjb250ZXh0ID0gVGhpcy0+Y29udGV4dHNbaV07CiAgICAgICAgaWYoaXNTdGF0ZURpcnR5KGNvbnRleHQsIHJlcCkpIGNvbnRpbnVlOwoKICAgICAgICBjb250ZXh0LT5kaXJ0eUFycmF5W2NvbnRleHQtPm51bURpcnR5RW50cmllcysrXSA9IHJlcDsKICAgICAgICBpZHggPSByZXAgPj4gNTsKICAgICAgICBzaGlmdCA9IHJlcCAmIDB4MWY7CiAgICAgICAgY29udGV4dC0+aXNTdGF0ZURpcnR5W2lkeF0gfD0gKDEgPDwgc2hpZnQpOwogICAgfQp9Cgp2b2lkIGdldF9kcmF3YWJsZV9zaXplX3BidWZmZXIoSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcywgVUlOVCAqd2lkdGgsIFVJTlQgKmhlaWdodCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXYgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgLyogVGhlIGRyYXdhYmxlIHNpemUgb2YgYSBwYnVmZmVyIHJlbmRlciB0YXJnZXQgaXMgdGhlIGN1cnJlbnQgcGJ1ZmZlciBzaXplCiAgICAgKi8KICAgICp3aWR0aCA9IGRldi0+cGJ1ZmZlcldpZHRoOwogICAgKmhlaWdodCA9IGRldi0+cGJ1ZmZlckhlaWdodDsKfQoKdm9pZCBnZXRfZHJhd2FibGVfc2l6ZV9mYm8oSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcywgVUlOVCAqd2lkdGgsIFVJTlQgKmhlaWdodCkgewogICAgLyogVGhlIGRyYXdhYmxlIHNpemUgb2YgYSBmYm8gdGFyZ2V0IGlzIHRoZSBvcGVuZ2wgdGV4dHVyZSBzaXplLCB3aGljaCBpcyB0aGUgcG93ZXIgb2YgdHdvIHNpemUKICAgICAqLwogICAgKndpZHRoID0gVGhpcy0+cG93MldpZHRoOwogICAgKmhlaWdodCA9IFRoaXMtPnBvdzJIZWlnaHQ7Cn0KCnZvaWQgZ2V0X2RyYXdhYmxlX3NpemVfYmFja2J1ZmZlcihJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzLCBVSU5UICp3aWR0aCwgVUlOVCAqaGVpZ2h0KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKmRldiA9IFRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICAvKiBUaGUgZHJhd2FibGUgc2l6ZSBvZiBhIGJhY2tidWZmZXIgLyBhdXggYnVmZmVyIG9mZnNjcmVlbiB0YXJnZXQgaXMgdGhlIHNpemUgb2YgdGhlCiAgICAgKiBjdXJyZW50IGNvbnRleHQncyBkcmF3YWJsZSwgd2hpY2ggaXMgdGhlIHNpemUgb2YgdGhlIGJhY2sgYnVmZmVyIG9mIHRoZSBzd2FwY2hhaW4KICAgICAqIHRoZSBhY3RpdmUgY29udGV4dCBiZWxvbmdzIHRvLiBUaGUgYmFjayBidWZmZXIgb2YgdGhlIHN3YXBjaGFpbiBpcyBzdG9yZWQgYXMgdGhlCiAgICAgKiBzdXJmYWNlIHRoZSBjb250ZXh0IGJlbG9uZ3MgdG8uCiAgICAgKi8KICAgICp3aWR0aCA9ICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBkZXYtPmFjdGl2ZUNvbnRleHQtPnN1cmZhY2UpLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICpoZWlnaHQgPSAoKElXaW5lRDNEU3VyZmFjZUltcGwgKikgZGV2LT5hY3RpdmVDb250ZXh0LT5zdXJmYWNlKS0+Y3VycmVudERlc2MuSGVpZ2h0Owp9Cg==