LyoKICogSVdpbmVEM0REZXZpY2UgaW1wbGVtZW50YXRpb24KICoKICogQ29weXJpZ2h0IDIwMDIgTGlvbmVsIFVsbWVyCiAqIENvcHlyaWdodCAyMDAyLTIwMDUgSmFzb24gRWRtZWFkZXMKICogQ29weXJpZ2h0IDIwMDMtMjAwNCBSYXBoYWVsIEp1bnF1ZWlyYQogKiBDb3B5cmlnaHQgMjAwNCBDaHJpc3RpYW4gQ29zdGEKICogQ29weXJpZ2h0IDIwMDUgT2xpdmVyIFN0aWViZXIKICogQ29weXJpZ2h0IDIwMDYtMjAwNyBTdGVmYW4gRPZzaW5nZXIgZm9yIENvZGVXZWF2ZXJzCiAqIENvcHlyaWdodCAyMDA2LTIwMDcgSGVucmkgVmVyYmVldAogKiBDb3B5cmlnaHQgMjAwNyBBbmRyZXcgUmllZGkKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSA8c3RkaW8uaD4KI2lmZGVmIEhBVkVfRkxPQVRfSAojIGluY2x1ZGUgPGZsb2F0Lmg+CiNlbmRpZgojaW5jbHVkZSAid2luZWQzZF9wcml2YXRlLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkM2QpOwojZGVmaW5lIEdMSU5GT19MT0NBVElPTiBUaGlzLT5hZGFwdGVyLT5nbF9pbmZvCgovKiBEZWZpbmUgdGhlIGRlZmF1bHQgbGlnaHQgcGFyYW1ldGVycyBhcyBzcGVjaWZpZWQgYnkgTVNETiAqLwpjb25zdCBXSU5FRDNETElHSFQgV0lORUQzRF9kZWZhdWx0X2xpZ2h0ID0gewoKICAgIFdJTkVEM0RMSUdIVF9ESVJFQ1RJT05BTCwgLyogVHlwZSAqLwogICAgeyAxLjAsIDEuMCwgMS4wLCAwLjAgfSwgICAvKiBEaWZmdXNlIHIsZyxiLGEgKi8KICAgIHsgMC4wLCAwLjAsIDAuMCwgMC4wIH0sICAgLyogU3BlY3VsYXIgcixnLGIsYSAqLwogICAgeyAwLjAsIDAuMCwgMC4wLCAwLjAgfSwgICAvKiBBbWJpZW50IHIsZyxiLGEsICovCiAgICB7IDAuMCwgMC4wLCAwLjAgfSwgICAgICAgIC8qIFBvc2l0aW9uIHgseSx6ICovCiAgICB7IDAuMCwgMC4wLCAxLjAgfSwgICAgICAgIC8qIERpcmVjdGlvbiB4LHkseiAqLwogICAgMC4wLCAgICAgICAgICAgICAgICAgICAgICAvKiBSYW5nZSAqLwogICAgMC4wLCAgICAgICAgICAgICAgICAgICAgICAvKiBGYWxsb2ZmICovCiAgICAwLjAsIDAuMCwgMC4wLCAgICAgICAgICAgIC8qIEF0dGVudWF0aW9uIDAsMSwyICovCiAgICAwLjAsICAgICAgICAgICAgICAgICAgICAgIC8qIFRoZXRhICovCiAgICAwLjAgICAgICAgICAgICAgICAgICAgICAgIC8qIFBoaSAqLwp9OwoKLyogc3RhdGljIGZ1bmN0aW9uIGRlY2xhcmF0aW9ucyAqLwpzdGF0aWMgdm9pZCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0FkZFJlc291cmNlKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RSZXNvdXJjZSAqcmVzb3VyY2UpOwoKLyogaGVscGVyIG1hY3JvcyAqLwojZGVmaW5lIEQzRE1FTUNIRUNLKG9iamVjdCwgcHBSZXN1bHQpIGlmKE5VTEwgPT0gb2JqZWN0KSB7ICpwcFJlc3VsdCA9IE5VTEw7IFdBUk4oIk91dCBvZiBtZW1vcnlcbiIpOyByZXR1cm4gV0lORUQzREVSUl9PVVRPRlZJREVPTUVNT1JZO30KCiNkZWZpbmUgRDNEQ1JFQVRFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCB0eXBlKSB7IFwKICAgIG9iamVjdD1IZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElXaW5lRDNEIyN0eXBlIyNJbXBsKSk7IFwKICAgIEQzRE1FTUNIRUNLKG9iamVjdCwgcHAjI3R5cGUpOyBcCiAgICBvYmplY3QtPmxwVnRibCA9ICZJV2luZUQzRCMjdHlwZSMjX1Z0Ymw7ICBcCiAgICBvYmplY3QtPndpbmVEM0REZXZpY2UgPSBUaGlzOyBcCiAgICBvYmplY3QtPnBhcmVudCAgICAgICA9IHBhcmVudDsgXAogICAgb2JqZWN0LT5yZWYgICAgICAgICAgPSAxOyBcCiAgICAqcHAjI3R5cGUgPSAoSVdpbmVEM0QjI3R5cGUgKikgb2JqZWN0OyBcCn0KCiNkZWZpbmUgRDNEQ1JFQVRFU0hBREVST0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCB0eXBlKSB7IFwKICAgIG9iamVjdD1IZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElXaW5lRDNEIyN0eXBlIyNJbXBsKSk7IFwKICAgIEQzRE1FTUNIRUNLKG9iamVjdCwgcHAjI3R5cGUpOyBcCiAgICBvYmplY3QtPmxwVnRibCA9ICZJV2luZUQzRCMjdHlwZSMjX1Z0Ymw7ICBcCiAgICBvYmplY3QtPnBhcmVudCAgICAgICAgICA9IHBhcmVudDsgXAogICAgb2JqZWN0LT5iYXNlU2hhZGVyLnJlZiAgPSAxOyBcCiAgICBvYmplY3QtPmJhc2VTaGFkZXIuZGV2aWNlID0gKElXaW5lRDNERGV2aWNlKikgVGhpczsgXAogICAgbGlzdF9pbml0KCZvYmplY3QtPmJhc2VTaGFkZXIubGlua2VkX3Byb2dyYW1zKTsgXAogICAgKnBwIyN0eXBlID0gKElXaW5lRDNEIyN0eXBlICopIG9iamVjdDsgXAp9CgojZGVmaW5lICBEM0RDUkVBVEVSRVNPVVJDRU9CSkVDVElOU1RBTkNFKG9iamVjdCwgdHlwZSwgZDNkdHlwZSwgX3NpemUpeyBcCiAgICBvYmplY3Q9SGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJV2luZUQzRCMjdHlwZSMjSW1wbCkpOyBcCiAgICBEM0RNRU1DSEVDSyhvYmplY3QsIHBwIyN0eXBlKTsgXAogICAgb2JqZWN0LT5scFZ0YmwgPSAmSVdpbmVEM0QjI3R5cGUjI19WdGJsOyAgXAogICAgb2JqZWN0LT5yZXNvdXJjZS53aW5lRDNERGV2aWNlICAgPSBUaGlzOyBcCiAgICBvYmplY3QtPnJlc291cmNlLnBhcmVudCAgICAgICAgICA9IHBhcmVudDsgXAogICAgb2JqZWN0LT5yZXNvdXJjZS5yZXNvdXJjZVR5cGUgICAgPSBkM2R0eXBlOyBcCiAgICBvYmplY3QtPnJlc291cmNlLnJlZiAgICAgICAgICAgICA9IDE7IFwKICAgIG9iamVjdC0+cmVzb3VyY2UucG9vbCAgICAgICAgICAgID0gUG9vbDsgXAogICAgb2JqZWN0LT5yZXNvdXJjZS5mb3JtYXQgICAgICAgICAgPSBGb3JtYXQ7IFwKICAgIG9iamVjdC0+cmVzb3VyY2UudXNhZ2UgICAgICAgICAgID0gVXNhZ2U7IFwKICAgIG9iamVjdC0+cmVzb3VyY2Uuc2l6ZSAgICAgICAgICAgID0gX3NpemU7IFwKICAgIGxpc3RfaW5pdCgmb2JqZWN0LT5yZXNvdXJjZS5wcml2YXRlRGF0YSk7IFwKICAgIC8qIENoZWNrIHRoYXQgd2UgaGF2ZSBlbm91Z2ggdmlkZW8gcmFtIGxlZnQgKi8gXAogICAgaWYgKFBvb2wgPT0gV0lORUQzRFBPT0xfREVGQVVMVCkgeyBcCiAgICAgICAgaWYgKElXaW5lRDNERGV2aWNlX0dldEF2YWlsYWJsZVRleHR1cmVNZW0oaWZhY2UpIDw9IF9zaXplKSB7IFwKICAgICAgICAgICAgV0FSTigiT3V0IG9mICdib2d1cycgdmlkZW8gbWVtb3J5XG4iKTsgXAogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvYmplY3QpOyBcCiAgICAgICAgICAgICpwcCMjdHlwZSA9IE5VTEw7IFwKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfT1VUT0ZWSURFT01FTU9SWTsgXAogICAgICAgIH0gXAogICAgICAgIFdpbmVEM0RBZGFwdGVyQ2hhbmdlR0xSYW0oVGhpcywgX3NpemUpOyBcCiAgICB9IFwKICAgIG9iamVjdC0+cmVzb3VyY2UuaGVhcE1lbW9yeSA9ICgwID09IF9zaXplID8gTlVMTCA6IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBfc2l6ZSArIFJFU09VUkNFX0FMSUdOTUVOVCkpOyBcCiAgICBpZiAob2JqZWN0LT5yZXNvdXJjZS5oZWFwTWVtb3J5ID09IE5VTEwgJiYgX3NpemUgIT0gMCkgeyBcCiAgICAgICAgRklYTUUoIk91dCBvZiBtZW1vcnkhXG4iKTsgXAogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9iamVjdCk7IFwKICAgICAgICAqcHAjI3R5cGUgPSBOVUxMOyBcCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfT1VUT0ZWSURFT01FTU9SWTsgXAogICAgfSBcCiAgICBvYmplY3QtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IChCWVRFICopKCgoVUxPTkdfUFRSKSBvYmplY3QtPnJlc291cmNlLmhlYXBNZW1vcnkgKyAoUkVTT1VSQ0VfQUxJR05NRU5UIC0gMSkpICYgfihSRVNPVVJDRV9BTElHTk1FTlQgLSAxKSk7IFwKICAgICpwcCMjdHlwZSA9IChJV2luZUQzRCMjdHlwZSAqKSBvYmplY3Q7IFwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9BZGRSZXNvdXJjZShpZmFjZSwgKElXaW5lRDNEUmVzb3VyY2UgKilvYmplY3QpIDtcCiAgICBUUkFDRSgiKCVwKSA6IENyZWF0ZWQgcmVzb3VyY2UgJXBcbiIsIFRoaXMsIG9iamVjdCk7IFwKfQoKI2RlZmluZSBEM0RJTklUSUFMSVpFQkFTRVRFWFRVUkUoX2Jhc2V0ZXh0dXJlKSB7IFwKICAgIF9iYXNldGV4dHVyZS5sZXZlbHMgICAgID0gTGV2ZWxzOyBcCiAgICBfYmFzZXRleHR1cmUuZmlsdGVyVHlwZSA9IChVc2FnZSAmIFdJTkVEM0RVU0FHRV9BVVRPR0VOTUlQTUFQKSA/IFdJTkVEM0RURVhGX0xJTkVBUiA6IFdJTkVEM0RURVhGX05PTkU7IFwKICAgIF9iYXNldGV4dHVyZS5MT0QgICAgICAgID0gMDsgXAogICAgX2Jhc2V0ZXh0dXJlLmRpcnR5ICAgICAgPSBUUlVFOyBcCiAgICBfYmFzZXRleHR1cmUuaXNfc3JnYiA9IEZBTFNFOyBcCiAgICBfYmFzZXRleHR1cmUuc3JnYl9tb2RlX2NoYW5nZV9jb3VudCA9IDA7IFwKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogR2xvYmFsIHZhcmlhYmxlIC8gQ29uc3RhbnRzIGZvbGxvdwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KY29uc3QgZmxvYXQgaWRlbnRpdHlbMTZdID0gezEsMCwwLDAsIDAsMSwwLDAsIDAsMCwxLDAsIDAsMCwwLDF9OyAgLyogV2hlbiBuZWVkZWQgZm9yIGNvbXBhcmlzb25zICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJVW5rbm93biBwYXJ0cyBmb2xsb3dzCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9RdWVyeUludGVyZmFjZShJV2luZUQzRERldmljZSAqaWZhY2UsUkVGSUlEIHJpaWQsTFBWT0lEICpwcG9iaikKewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXApLT4oJXMsJXApXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxwcG9iaik7CiAgICBpZiAoSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JVW5rbm93bikKICAgICAgICB8fCBJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lXaW5lRDNEQmFzZSkKICAgICAgICB8fCBJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lXaW5lRDNERGV2aWNlKSkgewogICAgICAgIElVbmtub3duX0FkZFJlZihpZmFjZSk7CiAgICAgICAgKnBwb2JqID0gVGhpczsKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KICAgICpwcG9iaiA9IE5VTEw7CiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQWRkUmVmKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVUxPTkcgcmVmQ291bnQgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgICBUUkFDRSgiKCVwKSA6IEFkZFJlZiBpbmNyZWFzaW5nIGZyb20gJWRcbiIsIFRoaXMsIHJlZkNvdW50IC0gMSk7CiAgICByZXR1cm4gcmVmQ291bnQ7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1JlbGVhc2UoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBVTE9ORyByZWZDb3VudCA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwoKICAgIFRSQUNFKCIoJXApIDogUmVsZWFzaW5nIGZyb20gJWRcbiIsIFRoaXMsIHJlZkNvdW50ICsgMSk7CgogICAgaWYgKCFyZWZDb3VudCkgewogICAgICAgIGlmIChUaGlzLT5mYm8pIHsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbERlbGV0ZUZyYW1lYnVmZmVyc0VYVCgxLCAmVGhpcy0+ZmJvKSk7CiAgICAgICAgfQogICAgICAgIGlmIChUaGlzLT5zcmNfZmJvKSB7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xEZWxldGVGcmFtZWJ1ZmZlcnNFWFQoMSwgJlRoaXMtPnNyY19mYm8pKTsKICAgICAgICB9CiAgICAgICAgaWYgKFRoaXMtPmRzdF9mYm8pIHsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbERlbGV0ZUZyYW1lYnVmZmVyc0VYVCgxLCAmVGhpcy0+ZHN0X2ZibykpOwogICAgICAgIH0KCiAgICAgICAgaWYgKFRoaXMtPmdsc2xfcHJvZ3JhbV9sb29rdXApIGhhc2hfdGFibGVfZGVzdHJveShUaGlzLT5nbHNsX3Byb2dyYW1fbG9va3VwKTsKCiAgICAgICAgLyogVE9ETzogQ2xlYW4gdXAgYWxsIHRoZSBzdXJmYWNlcyBhbmQgdGV4dHVyZXMhICovCiAgICAgICAgLyogTk9URTogWW91IG11c3QgcmVsZWFzZSB0aGUgcGFyZW50IGlmIHRoZSBvYmplY3Qgd2FzIGNyZWF0ZWQgdmlhIGEgY2FsbGJhY2sKICAgICAgICAqKiAqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgICAgIGlmICghbGlzdF9lbXB0eSgmVGhpcy0+cmVzb3VyY2VzKSkgewogICAgICAgICAgICBGSVhNRSgiKCVwKSBEZXZpY2UgcmVsZWFzZWQgd2l0aCByZXNvdXJjZXMgc3RpbGwgYm91bmQsIGFjY2VwdGFibGUgYnV0IHVuZXhwZWN0ZWRcbiIsIFRoaXMpOwogICAgICAgICAgICBkdW1wUmVzb3VyY2VzKCZUaGlzLT5yZXNvdXJjZXMpOwogICAgICAgIH0KCiAgICAgICAgaWYoVGhpcy0+Y29udGV4dHMpIEVSUigiQ29udGV4dCBhcnJheSBub3QgZnJlZWQhXG4iKTsKICAgICAgICBpZiAoVGhpcy0+aGFyZHdhcmVDdXJzb3IpIERlc3Ryb3lDdXJzb3IoVGhpcy0+aGFyZHdhcmVDdXJzb3IpOwogICAgICAgIFRoaXMtPmhhdmVIYXJkd2FyZUN1cnNvciA9IEZBTFNFOwoKICAgICAgICBJV2luZUQzRF9SZWxlYXNlKFRoaXMtPndpbmVEM0QpOwogICAgICAgIFRoaXMtPndpbmVEM0QgPSBOVUxMOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMpOwogICAgICAgIFRSQUNFKCJGcmVlZCBkZXZpY2UgICVwXG4iLCBUaGlzKTsKICAgICAgICBUaGlzID0gTlVMTDsKICAgIH0KICAgIHJldHVybiByZWZDb3VudDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0REZXZpY2UgaW1wbGVtZW50YXRpb24gZm9sbG93cwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQYXJlbnQoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJVW5rbm93biAqKnBQYXJlbnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgICpwUGFyZW50ID0gVGhpcy0+cGFyZW50OwogICAgSVVua25vd25fQWRkUmVmKFRoaXMtPnBhcmVudCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIHZvaWQgQ3JlYXRlVkJPKElXaW5lRDNEVmVydGV4QnVmZmVySW1wbCAqb2JqZWN0KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSBvYmplY3QtPnJlc291cmNlLndpbmVEM0REZXZpY2U7ICAvKiBOZWVkZWQgZm9yIEdMX0VYVENBTEwgKi8KICAgIEdMZW51bSBlcnJvciwgZ2xVc2FnZTsKICAgIERXT1JEIHZib1VzYWdlID0gb2JqZWN0LT5yZXNvdXJjZS51c2FnZTsKICAgIGlmKG9iamVjdC0+RmxhZ3MgJiBWQkZMQUdfVkJPQ1JFQVRFRkFJTCkgewogICAgICAgIFdBUk4oIkNyZWF0aW5nIGEgdmJvIGZhaWxlZCBvbmNlLCBub3QgdHJ5aW5nIGFnYWluXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgVFJBQ0UoIkNyZWF0aW5nIGFuIE9wZW5HTCB2ZXJ0ZXggYnVmZmVyIG9iamVjdCBmb3IgSVdpbmVEM0RWZXJ0ZXhCdWZmZXIgJXAgIFVzYWdlKCVzKVxuIiwgb2JqZWN0LCBkZWJ1Z19kM2R1c2FnZSh2Ym9Vc2FnZSkpOwoKICAgIC8qIE1ha2Ugc3VyZSB0aGF0IGEgY29udGV4dCBpcyB0aGVyZS4gTmVlZGVkIGluIGEgbXVsdGl0aHJlYWRlZCBlbnZpcm9ubWVudC4gT3RoZXJ3aXNlIHRoaXMgY2FsbCBpcyBhIG5vcCAqLwogICAgQWN0aXZhdGVDb250ZXh0KFRoaXMsIFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQsIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CiAgICBFTlRFUl9HTCgpOwoKICAgIC8qIE1ha2Ugc3VyZSB0aGF0IHRoZSBnbCBlcnJvciBpcyBjbGVhcmVkLiBEbyBub3QgdXNlIGNoZWNrR0xjYWxsCiAgICAgICogaGVyZSBiZWNhdXNlIGNoZWNrR0xjYWxsIGp1c3QgcHJpbnRzIGEgZml4bWUgYW5kIGNvbnRpbnVlcy4gSG93ZXZlciwKICAgICAgKiBpZiBhbiBlcnJvciBkdXJpbmcgVkJPIGNyZWF0aW9uIG9jY3VycyB3ZSBjYW4gZmFsbCBiYWNrIHRvIG5vbi12Ym8gb3BlcmF0aW9uCiAgICAgICogd2l0aCBmdWxsIGZ1bmN0aW9uYWxpdHkoYnV0IHBlcmZvcm1hbmNlIGxvc3MpCiAgICAgICovCiAgICB3aGlsZShnbEdldEVycm9yKCkgIT0gR0xfTk9fRVJST1IpOwoKICAgIC8qIEJhc2ljYWxseSB0aGUgRlZGIHBhcmFtZXRlciBwYXNzZWQgdG8gQ3JlYXRlVmVydGV4QnVmZmVyIGlzIG5vIGdvb2QKICAgICAgKiBJdCBpcyB0aGUgRlZGIHNldCB3aXRoIElXaW5lRDNERGV2aWNlOjpTZXRGVkYgb3IgdGhlIFZlcnRleCBEZWNsYXJhdGlvbiBzZXQgd2l0aAogICAgICAqIElXaW5lRDNERGV2aWNlOjpTZXRWZXJ0ZXhEZWNsYXJhdGlvbiB0aGF0IGRlY2lkZXMgaG93IHRoZSB2ZXJ0aWNlcyBpbiB0aGUgYnVmZmVyCiAgICAgICogbG9vayBsaWtlLiBUaGlzIG1lYW5zIHRoYXQgb24gZWFjaCBEcmF3UHJpbWl0aXZlIGNhbGwgdGhlIHZlcnRleCBidWZmZXIgaGFzIHRvIGJlIHZlcmlmaWVkCiAgICAgICogdG8gY2hlY2sgaWYgdGhlIHJodyBhbmQgY29sb3IgdmFsdWVzIGFyZSBpbiB0aGUgY29ycmVjdCBmb3JtYXQuCiAgICAgICovCgogICAgR0xfRVhUQ0FMTChnbEdlbkJ1ZmZlcnNBUkIoMSwgJm9iamVjdC0+dmJvKSk7CiAgICBlcnJvciA9IGdsR2V0RXJyb3IoKTsKICAgIGlmKG9iamVjdC0+dmJvID09IDAgfHwgZXJyb3IgIT0gR0xfTk9fRVJST1IpIHsKICAgICAgICBXQVJOKCJGYWlsZWQgdG8gY3JlYXRlIGEgVkJPIHdpdGggZXJyb3IgJXMgKCUjeClcbiIsIGRlYnVnX2dsZXJyb3IoZXJyb3IpLCBlcnJvcik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9BUlJBWV9CVUZGRVJfQVJCLCBvYmplY3QtPnZibykpOwogICAgZXJyb3IgPSBnbEdldEVycm9yKCk7CiAgICBpZihlcnJvciAhPSBHTF9OT19FUlJPUikgewogICAgICAgIFdBUk4oIkZhaWxlZCB0byBiaW5kIHRoZSBWQk8gd2l0aCBlcnJvciAlcyAoJSN4KVxuIiwgZGVidWdfZ2xlcnJvcihlcnJvciksIGVycm9yKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIERvbid0IHVzZSBzdGF0aWMsIGJlY2F1c2UgZHggYXBwcyB0ZW5kIHRvIHVwZGF0ZSB0aGUgYnVmZmVyCiAgICAgKiBxdWl0ZSBvZnRlbiBldmVuIGlmIHRoZXkgc3BlY2lmeSAwIHVzYWdlLiBCZWNhdXNlIHdlIGFsd2F5cyBrZWVwIHRoZSBsb2NhbCBjb3B5CiAgICAgKiB3ZSBuZXZlciByZWFkIGZyb20gdGhlIHZibyBhbmQgY2FuIGNyZWF0ZSBhIHdyaXRlIG9ubHkgb3BlbmdsIGJ1ZmZlci4KICAgICAqLwogICAgc3dpdGNoKHZib1VzYWdlICYgKFdJTkVEM0RVU0FHRV9XUklURU9OTFkgfCBXSU5FRDNEVVNBR0VfRFlOQU1JQykgKSB7CiAgICAgICAgY2FzZSBXSU5FRDNEVVNBR0VfV1JJVEVPTkxZIHwgV0lORUQzRFVTQUdFX0RZTkFNSUM6CiAgICAgICAgY2FzZSBXSU5FRDNEVVNBR0VfRFlOQU1JQzoKICAgICAgICAgICAgVFJBQ0UoIkdsIHVzYWdlID0gR0xfU1RSRUFNX0RSQVdcbiIpOwogICAgICAgICAgICBnbFVzYWdlID0gR0xfU1RSRUFNX0RSQVdfQVJCOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RVU0FHRV9XUklURU9OTFk6CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgVFJBQ0UoIkdsIHVzYWdlID0gR0xfRFlOQU1JQ19EUkFXXG4iKTsKICAgICAgICAgICAgZ2xVc2FnZSA9IEdMX0RZTkFNSUNfRFJBV19BUkI7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQoKICAgIC8qIFJlc2VydmUgbWVtb3J5IGZvciB0aGUgYnVmZmVyLiBUaGUgYW1vdW50IG9mIGRhdGEgd29uJ3QgY2hhbmdlCiAgICAgKiBzbyB3ZSBhcmUgc2FmZSB3aXRoIGNhbGxpbmcgZ2xCdWZmZXJEYXRhIG9uY2Ugd2l0aCBhIE5VTEwgcHRyIGFuZAogICAgICogY2FsbGluZyBnbEJ1ZmZlclN1YkRhdGEgb24gdXBkYXRlcwogICAgICovCiAgICBHTF9FWFRDQUxMKGdsQnVmZmVyRGF0YUFSQihHTF9BUlJBWV9CVUZGRVJfQVJCLCBvYmplY3QtPnJlc291cmNlLnNpemUsIE5VTEwsIGdsVXNhZ2UpKTsKICAgIGVycm9yID0gZ2xHZXRFcnJvcigpOwogICAgaWYoZXJyb3IgIT0gR0xfTk9fRVJST1IpIHsKICAgICAgICBXQVJOKCJnbEJ1ZmZlckRhdGFBUkIgZmFpbGVkIHdpdGggZXJyb3IgJXMgKCUjeClcbiIsIGRlYnVnX2dsZXJyb3IoZXJyb3IpLCBlcnJvcik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBMRUFWRV9HTCgpOwoKICAgIHJldHVybjsKICAgIGVycm9yOgogICAgLyogQ2xlYW4gdXAgYWxsIHZibyBpbml0LCBidXQgY29udGludWUgYmVjYXVzZSB3ZSBjYW4gd29yayB3aXRob3V0IGEgdmJvIDotKSAqLwogICAgRklYTUUoIkZhaWxlZCB0byBjcmVhdGUgYSB2ZXJ0ZXggYnVmZmVyIG9iamVjdC4gQ29udGludWluZywgYnV0IHBlcmZvcm1hbmNlIGlzc3VlcyBjYW4gb2NjdXJcbiIpOwogICAgaWYob2JqZWN0LT52Ym8pIEdMX0VYVENBTEwoZ2xEZWxldGVCdWZmZXJzQVJCKDEsICZvYmplY3QtPnZibykpOwogICAgb2JqZWN0LT52Ym8gPSAwOwogICAgb2JqZWN0LT5GbGFncyB8PSBWQkZMQUdfVkJPQ1JFQVRFRkFJTDsKICAgIExFQVZFX0dMKCk7CiAgICByZXR1cm47Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVmVydGV4QnVmZmVyKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBTaXplLCBEV09SRCBVc2FnZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRlZGLCBXSU5FRDNEUE9PTCBQb29sLCBJV2luZUQzRFZlcnRleEJ1ZmZlcioqIHBwVmVydGV4QnVmZmVyLCBIQU5ETEUgKnNoYXJlZEhhbmRsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJVW5rbm93biAqcGFyZW50KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKm9iamVjdDsKICAgIFdJTkVEM0RGT1JNQVQgRm9ybWF0ID0gV0lORUQzREZNVF9WRVJURVhEQVRBOyAvKiBEdW1teSBmb3JtYXQgZm9yIG5vdyAqLwogICAgaW50IGR4VmVyc2lvbiA9ICggKElXaW5lRDNESW1wbCAqKSBUaGlzLT53aW5lRDNEKS0+ZHhWZXJzaW9uOwogICAgQk9PTCBjb252OwoKICAgIGlmKFNpemUgPT0gMCkgewogICAgICAgIFdBUk4oIlNpemUgMCByZXF1ZXN0ZWQsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICAqcHBWZXJ0ZXhCdWZmZXIgPSBOVUxMOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfSBlbHNlIGlmKFBvb2wgPT0gV0lORUQzRFBPT0xfU0NSQVRDSCkgewogICAgICAgIC8qIFRoZSBkM2Q5IHRlc3RzdWl0IHNob3dzIHRoYXQgdGhpcyBpcyBub3QgYWxsb3dlZC4gSXQgZG9lc24ndCBtYWtlIG11Y2ggc2Vuc2UKICAgICAgICAgKiBhbnl3YXksIFNDUkFUQ0ggdmVydGV4IGJ1ZmZlcnMgYXJlbid0IHVzZWFibGUgYW55d2hlcmUKICAgICAgICAgKi8KICAgICAgICBXQVJOKCJWZXJ0ZXggYnVmZmVyIGluIEQzRFBPT0xfU0NSQVRDSCByZXF1ZXN0ZWQsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICAqcHBWZXJ0ZXhCdWZmZXIgPSBOVUxMOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIEQzRENSRUFURVJFU09VUkNFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBWZXJ0ZXhCdWZmZXIsIFdJTkVEM0RSVFlQRV9WRVJURVhCVUZGRVIsIFNpemUpCgogICAgVFJBQ0UoIiglcCkgOiBTaXplPSVkLCBVc2FnZT0lZCwgRlZGPSV4LCBQb29sPSVkIC0gTWVtb3J5QCVwLCBJZmFjZUAlcFxuIiwgVGhpcywgU2l6ZSwgVXNhZ2UsIEZWRiwgUG9vbCwgb2JqZWN0LT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnksIG9iamVjdCk7CiAgICAqcHBWZXJ0ZXhCdWZmZXIgPSAoSVdpbmVEM0RWZXJ0ZXhCdWZmZXIgKilvYmplY3Q7CgogICAgb2JqZWN0LT5mdmYgPSBGVkY7CgogICAgLyogT2JzZXJ2YXRpb25zIHNob3cgdGhhdCBkcmF3U3RyaWRlZFNsb3cgaXMgZmFzdGVyIG9uIGR5bmFtaWMgVkJzIHRoYW4gY29udmVydGluZyArCiAgICAgKiBkcmF3U3RyaWRlZEZhc3QgKGhhbGYtbGlmZSAyKS4KICAgICAqCiAgICAgKiBCYXNpY2FsbHkgY29udmVydGluZyB0aGUgdmVydGljZXMgaW4gdGhlIGJ1ZmZlciBpcyBxdWl0ZSBleHBlbnNpdmUsIGFuZCBvYnNlcnZhdGlvbnMKICAgICAqIHNob3cgdGhhdCBkcmF3U3RyaWRlZFNsb3cgaXMgZmFzdGVyIHRoYW4gY29udmVydGluZyArIHVwbG9hZGluZyArIGRyYXdTdHJpZGVkRmFzdC4KICAgICAqIFRoZXJlZm9yZSBkbyBub3QgY3JlYXRlIGEgVkJPIGZvciBXSU5FRDNEVVNBR0VfRFlOQU1JQyBidWZmZXJzLgogICAgICoKICAgICAqIERpcmVjdDNENyBoYXMgYW5vdGhlciBwcm9ibGVtOiBJdHMgdmVydGV4YnVmZmVyIGFwaSBkb2Vzbid0IG9mZmVyIGEgd2F5IHRvIHNwZWNpZnkKICAgICAqIHRoZSByYW5nZSBvZiB2ZXJ0aWNlcyBiZWluZyBsb2NrZWQsIHNvIGVhY2ggbG9jayB3aWxsIHJlcXVpcmUgdGhlIHdob2xlIGJ1ZmZlciB0byBiZSB0cmFuc2Zvcm1lZC4KICAgICAqIE1vcmVvdmVyIGdlb21ldHJ5IGRhdGEgaW4gZHg3IGlzIHF1aXRlIHNpbXBsZSwgc28gZHJhd1N0cmlkZWRTbG93IGlzbid0IGEgYmlnIGhpdC4gQSBwbHVzCiAgICAgKiBpcyB0aGF0IHRoZSB2ZXJ0ZXggYnVmZmVycyBmdmYgY2FuIGJlIHRydXN0ZWQgaW4gZHg3LiBTbyBvbmx5IGNyZWF0ZSBub24tY29udmVydGVkIHZib3MgZm9yCiAgICAgKiBkeDcgYXBwcy4KICAgICAqIFRoZXJlIGlzIGEgSURpcmVjdDNEVmVydGV4QnVmZmVyNzo6T3B0aW1pemUgY2FsbCBhZnRlciB3aGljaCB0aGUgYnVmZmVyIGNhbid0IGJlIGxvY2tlZCBhbnkKICAgICAqIG1vcmUuIEluIHRoaXMgY2FsbCB3ZSBjYW4gY29udmVydCBkeDcgYnVmZmVycyB0b28uCiAgICAgKi8KICAgIGNvbnYgPSAoKEZWRiAmIFdJTkVEM0RGVkZfUE9TSVRJT05fTUFTSykgPT0gV0lORUQzREZWRl9YWVpSSFcgKSB8fCAoRlZGICYgKFdJTkVEM0RGVkZfRElGRlVTRSB8IFdJTkVEM0RGVkZfU1BFQ1VMQVIpKTsKICAgIGlmKCBHTF9TVVBQT1JUKEFSQl9WRVJURVhfQlVGRkVSX09CSkVDVCkgJiYgUG9vbCAhPSBXSU5FRDNEUE9PTF9TWVNURU1NRU0gJiYgIShVc2FnZSAmIFdJTkVEM0RVU0FHRV9EWU5BTUlDKSAmJiAKICAgICAgICAoZHhWZXJzaW9uID4gNyB8fCAhY29udikgKSB7CiAgICAgICAgQ3JlYXRlVkJPKG9iamVjdCk7CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIHZvaWQgQ3JlYXRlSW5kZXhCdWZmZXJWQk8oSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzLCBJV2luZUQzREluZGV4QnVmZmVySW1wbCAqb2JqZWN0KSB7CiAgICBHTGVudW0gZXJyb3IsIGdsVXNhZ2U7CiAgICBUUkFDRSgiQ3JlYXRpbmcgVkJPIGZvciBJbmRleCBCdWZmZXIgJXBcbiIsIG9iamVjdCk7CgogICAgLyogVGhlIGZvbGxvd2luZyBjb2RlIHdpbGwgbW9kaWZ5IHRoZSBFTEVNRU5UX0FSUkFZX0JVRkZFUiBiaW5kaW5nLCBtYWtlIHN1cmUgaXQgaXMKICAgICAqIHJlc3RvcmVkIG9uIHRoZSBuZXh0IGRyYXcKICAgICAqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX0lOREVYQlVGRkVSKTsKCiAgICAvKiBNYWtlIHN1cmUgdGhhdCBhIGNvbnRleHQgaXMgdGhlcmUuIE5lZWRlZCBpbiBhIG11bHRpdGhyZWFkZWQgZW52aXJvbm1lbnQuIE90aGVyd2lzZSB0aGlzIGNhbGwgaXMgYSBub3AgKi8KICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0LCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwogICAgRU5URVJfR0woKTsKCiAgICB3aGlsZShnbEdldEVycm9yKCkpOwoKICAgIEdMX0VYVENBTEwoZ2xHZW5CdWZmZXJzQVJCKDEsICZvYmplY3QtPnZibykpOwogICAgZXJyb3IgPSBnbEdldEVycm9yKCk7CiAgICBpZihlcnJvciAhPSBHTF9OT19FUlJPUiB8fCBvYmplY3QtPnZibyA9PSAwKSB7CiAgICAgICAgRVJSKCJDcmVhdGluZyBhIHZibyBmYWlsZWQgd2l0aCBlcnJvciAlcyAoJSN4KSwgY29udGludWluZyB3aXRob3V0IHZibyBmb3IgdGhpcyBidWZmZXJcbiIsIGRlYnVnX2dsZXJyb3IoZXJyb3IpLCBlcnJvcik7CiAgICAgICAgZ290byBvdXQ7CiAgICB9CgogICAgR0xfRVhUQ0FMTChnbEJpbmRCdWZmZXJBUkIoR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVJfQVJCLCBvYmplY3QtPnZibykpOwogICAgZXJyb3IgPSBnbEdldEVycm9yKCk7CiAgICBpZihlcnJvciAhPSBHTF9OT19FUlJPUikgewogICAgICAgIEVSUigiRmFpbGVkIHRvIGJpbmQgaW5kZXggYnVmZmVyIHdpdGggZXJyb3IgJXMgKCUjeCksIGNvbnRpbnVpbmcgd2l0aG91dCB2Ym8gZm9yIHRoaXMgYnVmZmVyXG4iLCBkZWJ1Z19nbGVycm9yKGVycm9yKSwgZXJyb3IpOwogICAgICAgIGdvdG8gb3V0OwogICAgfQoKICAgIC8qIFVzZSBzdGF0aWMgd3JpdGUgb25seSB1c2FnZSBmb3Igbm93LiBEeW5hbWljIGluZGV4IGJ1ZmZlcnMgc3RheSBpbiBzeXNtZW0sIGFuZCBkdWUgdG8gdGhlIHN5c21lbQogICAgICAgICogY29weSBubyByZWFkYmFjayB3aWxsIGJlIG5lZWRlZAogICAgICAgICovCiAgICBnbFVzYWdlID0gR0xfU1RBVElDX0RSQVdfQVJCOwogICAgR0xfRVhUQ0FMTChnbEJ1ZmZlckRhdGFBUkIoR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVJfQVJCLCBvYmplY3QtPnJlc291cmNlLnNpemUsIE5VTEwsIGdsVXNhZ2UpKTsKICAgIGVycm9yID0gZ2xHZXRFcnJvcigpOwogICAgaWYoZXJyb3IgIT0gR0xfTk9fRVJST1IpIHsKICAgICAgICBFUlIoIkZhaWxlZCB0byBpbml0aWFsaXplIHRoZSBpbmRleCBidWZmZXIgd2l0aCBlcnJvciAlcyAoJSN4KVxuIiwgZGVidWdfZ2xlcnJvcihlcnJvciksIGVycm9yKTsKICAgICAgICBnb3RvIG91dDsKICAgIH0KICAgIExFQVZFX0dMKCk7CiAgICBUUkFDRSgiU3VjY2Vzc2Z1bGx5IGNyZWF0ZWQgdmJvICVkIGZvciBpbmRleCBidWZmZXIgJXBcbiIsIG9iamVjdC0+dmJvLCBvYmplY3QpOwogICAgcmV0dXJuOwoKb3V0OgogICAgR0xfRVhUQ0FMTChnbEJpbmRCdWZmZXJBUkIoR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVJfQVJCLCAwKSk7CiAgICBHTF9FWFRDQUxMKGdsRGVsZXRlQnVmZmVyc0FSQigxLCAmb2JqZWN0LT52Ym8pKTsKICAgIExFQVZFX0dMKCk7CiAgICBvYmplY3QtPnZibyA9IDA7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlSW5kZXhCdWZmZXIoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIExlbmd0aCwgRFdPUkQgVXNhZ2UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzREZPUk1BVCBGb3JtYXQsIFdJTkVEM0RQT09MIFBvb2wsIElXaW5lRDNESW5kZXhCdWZmZXIqKiBwcEluZGV4QnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFICpzaGFyZWRIYW5kbGUsIElVbmtub3duICpwYXJlbnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNESW5kZXhCdWZmZXJJbXBsICpvYmplY3Q7CiAgICBUUkFDRSgiKCVwKSBDcmVhdGluZyBpbmRleCBidWZmZXJcbiIsIFRoaXMpOwoKICAgIC8qIEFsbG9jYXRlIHRoZSBzdG9yYWdlIGZvciB0aGUgZGV2aWNlICovCiAgICBEM0RDUkVBVEVSRVNPVVJDRU9CSkVDVElOU1RBTkNFKG9iamVjdCxJbmRleEJ1ZmZlcixXSU5FRDNEUlRZUEVfSU5ERVhCVUZGRVIsIExlbmd0aCkKCiAgICBpZihQb29sICE9IFdJTkVEM0RQT09MX1NZU1RFTU1FTSAmJiAhKFVzYWdlICYgV0lORUQzRFVTQUdFX0RZTkFNSUMpICYmIEdMX1NVUFBPUlQoQVJCX1ZFUlRFWF9CVUZGRVJfT0JKRUNUKSkgewogICAgICAgIENyZWF0ZUluZGV4QnVmZmVyVkJPKFRoaXMsIG9iamVjdCk7CiAgICB9CgogICAgVFJBQ0UoIiglcCkgOiBMZW49JWQsIFVzZT0leCwgRm9ybWF0PSgldSwlcyksIFBvb2w9JWQgLSBNZW1vcnlAJXAsIElmYWNlQCVwXG4iLCBUaGlzLCBMZW5ndGgsIFVzYWdlLCBGb3JtYXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBkZWJ1Z19kM2Rmb3JtYXQoRm9ybWF0KSwgUG9vbCwgb2JqZWN0LCBvYmplY3QtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICAqcHBJbmRleEJ1ZmZlciA9IChJV2luZUQzREluZGV4QnVmZmVyICopIG9iamVjdDsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVTdGF0ZUJsb2NrKElXaW5lRDNERGV2aWNlKiBpZmFjZSwgV0lORUQzRFNUQVRFQkxPQ0tUWVBFIFR5cGUsIElXaW5lRDNEU3RhdGVCbG9jayoqIHBwU3RhdGVCbG9jaywgSVVua25vd24gKnBhcmVudCkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgICAgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN0YXRlQmxvY2tJbXBsICpvYmplY3Q7CiAgICBpbnQgaSwgajsKICAgIEhSRVNVTFQgdGVtcF9yZXN1bHQ7CgogICAgRDNEQ1JFQVRFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBTdGF0ZUJsb2NrKQogICAgb2JqZWN0LT5ibG9ja1R5cGUgICAgID0gVHlwZTsKCiAgICBmb3IoaSA9IDA7IGkgPCBMSUdIVE1BUF9TSVpFOyBpKyspIHsKICAgICAgICBsaXN0X2luaXQoJm9iamVjdC0+bGlnaHRNYXBbaV0pOwogICAgfQoKICAgIC8qIFNwZWNpYWwgY2FzZSAtIFVzZWQgZHVyaW5nIGluaXRpYWxpemF0aW9uIHRvIHByb2R1Y2UgYSBwbGFjZWhvbGRlciBzdGF0ZWJsb2NrCiAgICAgICAgICBzbyBvdGhlciBmdW5jdGlvbnMgY2FsbGVkIGNhbiB1cGRhdGUgYSBzdGF0ZSBibG9jayAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgaWYgKFR5cGUgPT0gV0lORUQzRFNCVF9JTklUKSB7CiAgICAgICAgLyogRG9uJ3QgYm90aGVyIGluY3JlYXNpbmcgdGhlIHJlZmVyZW5jZSBjb3VudCBvdGhlcndpc2UgYSBkZXZpY2Ugd2lsbCBuZXZlcgogICAgICAgICAgIGJlIGZyZWVkIGR1ZSB0byBjaXJjdWxhciBkZXBlbmRlbmNpZXMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CiAgICAKICAgIHRlbXBfcmVzdWx0ID0gYWxsb2NhdGVfc2hhZGVyX2NvbnN0YW50cyhvYmplY3QpOwogICAgaWYgKFdJTkVEM0RfT0sgIT0gdGVtcF9yZXN1bHQpCiAgICAgICAgcmV0dXJuIHRlbXBfcmVzdWx0OwoKICAgIC8qIE90aGVyd2lzZSwgbWlnaHQgYXMgd2VsbCBzZXQgdGhlIHdob2xlIHN0YXRlIGJsb2NrIHRvIHRoZSBhcHByb3ByaWF0ZSB2YWx1ZXMgICovCiAgICBpZiAoVGhpcy0+c3RhdGVCbG9jayAhPSBOVUxMKQogICAgICAgIHN0YXRlYmxvY2tfY29weSgoSVdpbmVEM0RTdGF0ZUJsb2NrKikgb2JqZWN0LCAoSVdpbmVEM0RTdGF0ZUJsb2NrKikgVGhpcy0+c3RhdGVCbG9jayk7CiAgICBlbHNlCiAgICAgICAgbWVtc2V0KG9iamVjdC0+c3RyZWFtRnJlcSwgMSwgc2l6ZW9mKG9iamVjdC0+c3RyZWFtRnJlcSkpOwoKICAgIC8qIFJlc2V0IHRoZSByZWYgYW5kIHR5cGUgYWZ0ZXIga2x1ZGdpbmcgaXQgKi8KICAgIG9iamVjdC0+d2luZUQzRERldmljZSA9IFRoaXM7CiAgICBvYmplY3QtPnJlZiAgICAgICAgICAgPSAxOwogICAgb2JqZWN0LT5ibG9ja1R5cGUgICAgID0gVHlwZTsKCiAgICBUUkFDRSgiVXBkYXRpbmcgY2hhbmdlZCBmbGFncyBhcHByb3ByaWF0ZSBmb3IgdHlwZSAlZFxuIiwgVHlwZSk7CgogICAgaWYgKFR5cGUgPT0gV0lORUQzRFNCVF9BTEwpIHsKCiAgICAgICAgVFJBQ0UoIkFMTCA9PiBQcmV0ZW5kIGV2ZXJ5dGhpbmcgaGFzIGNoYW5nZWRcbiIpOwogICAgICAgIHN0YXRlYmxvY2tfc2F2ZWRzdGF0ZXNfc2V0KChJV2luZUQzRFN0YXRlQmxvY2sqKSBvYmplY3QsICZvYmplY3QtPmNoYW5nZWQsIFRSVUUpOwoKICAgICAgICAvKiBMaWdodHMgYXJlIG5vdCBwYXJ0IG9mIHRoZSBjaGFuZ2VkIC8gc2V0IHN0cnVjdHVyZSAqLwogICAgICAgIGZvcihqID0gMDsgaiA8IExJR0hUTUFQX1NJWkU7IGorKykgewogICAgICAgICAgICBzdHJ1Y3QgbGlzdCAqZTsKICAgICAgICAgICAgTElTVF9GT1JfRUFDSChlLCAmb2JqZWN0LT5saWdodE1hcFtqXSkgewogICAgICAgICAgICAgICAgUExJR0hUSU5GT0VMICpsaWdodCA9IExJU1RfRU5UUlkoZSwgUExJR0hUSU5GT0VMLCBlbnRyeSk7CiAgICAgICAgICAgICAgICBsaWdodC0+Y2hhbmdlZCA9IFRSVUU7CiAgICAgICAgICAgICAgICBsaWdodC0+ZW5hYmxlZENoYW5nZWQgPSBUUlVFOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZvcihqID0gMTsgaiA8PSBXSU5FSElHSEVTVF9SRU5ERVJfU1RBVEU7IGorKykgewogICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF9yZW5kZXJfc3RhdGVzW2ogLSAxXSA9IGo7CiAgICAgICAgfQogICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF9yZW5kZXJfc3RhdGVzID0gV0lORUhJR0hFU1RfUkVOREVSX1NUQVRFOwogICAgICAgIC8qIFRPRE86IEZpbHRlciB1bnVzZWQgdHJhbnNmb3JtcyBiZXR3ZWVuIFRFWFRVUkU4IGFuZCBXT1JMRDA/ICovCiAgICAgICAgZm9yKGogPSAxOyBqIDw9IEhJR0hFU1RfVFJBTlNGT1JNU1RBVEU7IGorKykgewogICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF90cmFuc2Zvcm1fc3RhdGVzW2ogLSAxXSA9IGo7CiAgICAgICAgfQogICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF90cmFuc2Zvcm1fc3RhdGVzID0gSElHSEVTVF9UUkFOU0ZPUk1TVEFURTsKICAgICAgICBmb3IoaiA9IDA7IGogPCBHTF9MSU1JVFModnNoYWRlcl9jb25zdGFudHNGKTsgaisrKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3ZzX2NvbnN0c19mW2pdID0gajsKICAgICAgICB9CiAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3ZzX2NvbnN0c19mID0gR0xfTElNSVRTKHZzaGFkZXJfY29uc3RhbnRzRik7CiAgICAgICAgZm9yKGogPSAwOyBqIDwgTUFYX0NPTlNUX0k7IGorKykgewogICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF92c19jb25zdHNfaVtqXSA9IGo7CiAgICAgICAgfQogICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF92c19jb25zdHNfaSA9IE1BWF9DT05TVF9JOwogICAgICAgIGZvcihqID0gMDsgaiA8IE1BWF9DT05TVF9COyBqKyspIHsKICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfdnNfY29uc3RzX2Jbal0gPSBqOwogICAgICAgIH0KICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfdnNfY29uc3RzX2IgPSBNQVhfQ09OU1RfQjsKICAgICAgICBmb3IoaiA9IDA7IGogPCBHTF9MSU1JVFMocHNoYWRlcl9jb25zdGFudHNGKTsgaisrKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3BzX2NvbnN0c19mW2pdID0gajsKICAgICAgICB9CiAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3BzX2NvbnN0c19mID0gR0xfTElNSVRTKHBzaGFkZXJfY29uc3RhbnRzRik7CiAgICAgICAgZm9yKGogPSAwOyBqIDwgTUFYX0NPTlNUX0k7IGorKykgewogICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF9wc19jb25zdHNfaVtqXSA9IGo7CiAgICAgICAgfQogICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF9wc19jb25zdHNfaSA9IE1BWF9DT05TVF9JOwogICAgICAgIGZvcihqID0gMDsgaiA8IE1BWF9DT05TVF9COyBqKyspIHsKICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfcHNfY29uc3RzX2Jbal0gPSBqOwogICAgICAgIH0KICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfcHNfY29uc3RzX2IgPSBNQVhfQ09OU1RfQjsKICAgICAgICBmb3IoaSA9IDA7IGkgPCBNQVhfVEVYVFVSRVM7IGkrKykgewogICAgICAgICAgICBmb3IoaiA9IDE7IGogPD0gV0lORUQzRF9ISUdIRVNUX1RFWFRVUkVfU1RBVEU7IGorKykgewogICAgICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfdHNzX3N0YXRlc1tvYmplY3QtPm51bV9jb250YWluZWRfdHNzX3N0YXRlc10uc3RhZ2UgPSBpOwogICAgICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfdHNzX3N0YXRlc1tvYmplY3QtPm51bV9jb250YWluZWRfdHNzX3N0YXRlc10uc3RhdGUgPSBqOwogICAgICAgICAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3Rzc19zdGF0ZXMrKzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3IoaSA9IDA7IGkgPCBNQVhfQ09NQklORURfU0FNUExFUlM7IGkrKykgewogICAgICAgICAgICBmb3IoaiA9IDE7IGogPD0gV0lORUQzRF9ISUdIRVNUX1NBTVBMRVJfU1RBVEU7IGorKykgewogICAgICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfc2FtcGxlcl9zdGF0ZXNbb2JqZWN0LT5udW1fY29udGFpbmVkX3NhbXBsZXJfc3RhdGVzXS5zdGFnZSA9IGk7CiAgICAgICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF9zYW1wbGVyX3N0YXRlc1tvYmplY3QtPm51bV9jb250YWluZWRfc2FtcGxlcl9zdGF0ZXNdLnN0YXRlID0gajsKICAgICAgICAgICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF9zYW1wbGVyX3N0YXRlcysrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3IoaSA9IDA7IGkgPCBNQVhfU1RSRUFNUzsgaSsrKSB7CiAgICAgICAgICAgIGlmKG9iamVjdC0+c3RyZWFtU291cmNlW2ldKSB7CiAgICAgICAgICAgICAgICBJV2luZUQzRFZlcnRleEJ1ZmZlcl9BZGRSZWYob2JqZWN0LT5zdHJlYW1Tb3VyY2VbaV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmKG9iamVjdC0+cEluZGV4RGF0YSkgewogICAgICAgICAgICBJV2luZUQzREluZGV4QnVmZmVyX0FkZFJlZihvYmplY3QtPnBJbmRleERhdGEpOwogICAgICAgIH0KICAgICAgICBpZihvYmplY3QtPnZlcnRleFNoYWRlcikgewogICAgICAgICAgICBJV2luZUQzRFZlcnRleFNoYWRlcl9BZGRSZWYob2JqZWN0LT52ZXJ0ZXhTaGFkZXIpOwogICAgICAgIH0KICAgICAgICBpZihvYmplY3QtPnBpeGVsU2hhZGVyKSB7CiAgICAgICAgICAgIElXaW5lRDNEUGl4ZWxTaGFkZXJfQWRkUmVmKG9iamVjdC0+cGl4ZWxTaGFkZXIpOwogICAgICAgIH0KCiAgICB9IGVsc2UgaWYgKFR5cGUgPT0gV0lORUQzRFNCVF9QSVhFTFNUQVRFKSB7CgogICAgICAgIFRSQUNFKCJQSVhFTFNUQVRFID0+IFByZXRlbmQgYWxsIHBpeGVsIHNoYXRlcyBoYXZlIGNoYW5nZWRcbiIpOwogICAgICAgIHN0YXRlYmxvY2tfc2F2ZWRzdGF0ZXNfc2V0KChJV2luZUQzRFN0YXRlQmxvY2sqKSBvYmplY3QsICZvYmplY3QtPmNoYW5nZWQsIEZBTFNFKTsKCiAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnBpeGVsU2hhZGVyID0gVFJVRTsKCiAgICAgICAgLyogUGl4ZWwgU2hhZGVyIENvbnN0YW50cyAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBHTF9MSU1JVFModnNoYWRlcl9jb25zdGFudHNGKTsgKytpKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3BzX2NvbnN0c19mW2ldID0gaTsKICAgICAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnBpeGVsU2hhZGVyQ29uc3RhbnRzRltpXSA9IFRSVUU7CiAgICAgICAgfQogICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF9wc19jb25zdHNfZiA9IEdMX0xJTUlUUyh2c2hhZGVyX2NvbnN0YW50c0YpOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBNQVhfQ09OU1RfQjsgKytpKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3BzX2NvbnN0c19iW2ldID0gaTsKICAgICAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnBpeGVsU2hhZGVyQ29uc3RhbnRzQltpXSA9IFRSVUU7CiAgICAgICAgfQogICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF9wc19jb25zdHNfYiA9IE1BWF9DT05TVF9COwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBNQVhfQ09OU1RfSTsgKytpKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3BzX2NvbnN0c19pW2ldID0gaTsKICAgICAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnBpeGVsU2hhZGVyQ29uc3RhbnRzSVtpXSA9IFRSVUU7CiAgICAgICAgfQogICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF9wc19jb25zdHNfaSA9IE1BWF9DT05TVF9JOwoKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgTlVNX1NBVkVEUElYRUxTVEFURVNfUjsgaSsrKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y2hhbmdlZC5yZW5kZXJTdGF0ZVtTYXZlZFBpeGVsU3RhdGVzX1JbaV1dID0gVFJVRTsKICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfcmVuZGVyX3N0YXRlc1tpXSA9IFNhdmVkUGl4ZWxTdGF0ZXNfUltpXTsKICAgICAgICB9CiAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3JlbmRlcl9zdGF0ZXMgPSBOVU1fU0FWRURQSVhFTFNUQVRFU19SOwogICAgICAgIGZvciAoaiA9IDA7IGogPCBNQVhfVEVYVFVSRVM7IGorKykgewogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgTlVNX1NBVkVEUElYRUxTVEFURVNfVDsgaSsrKSB7CiAgICAgICAgICAgICAgICBvYmplY3QtPmNoYW5nZWQudGV4dHVyZVN0YXRlW2pdW1NhdmVkUGl4ZWxTdGF0ZXNfVFtpXV0gPSBUUlVFOwogICAgICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfdHNzX3N0YXRlc1tvYmplY3QtPm51bV9jb250YWluZWRfdHNzX3N0YXRlc10uc3RhZ2UgPSBqOwogICAgICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfdHNzX3N0YXRlc1tvYmplY3QtPm51bV9jb250YWluZWRfdHNzX3N0YXRlc10uc3RhdGUgPSBTYXZlZFBpeGVsU3RhdGVzX1RbaV07CiAgICAgICAgICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfdHNzX3N0YXRlcysrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZvciAoaiA9IDAgOyBqIDwgTUFYX0NPTUJJTkVEX1NBTVBMRVJTOyBqKyspIHsKICAgICAgICAgICAgZm9yIChpID0wOyBpIDwgTlVNX1NBVkVEUElYRUxTVEFURVNfUztpKyspIHsKICAgICAgICAgICAgICAgIG9iamVjdC0+Y2hhbmdlZC5zYW1wbGVyU3RhdGVbal1bU2F2ZWRQaXhlbFN0YXRlc19TW2ldXSA9IFRSVUU7CiAgICAgICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF9zYW1wbGVyX3N0YXRlc1tvYmplY3QtPm51bV9jb250YWluZWRfc2FtcGxlcl9zdGF0ZXNdLnN0YWdlID0gajsKICAgICAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3NhbXBsZXJfc3RhdGVzW29iamVjdC0+bnVtX2NvbnRhaW5lZF9zYW1wbGVyX3N0YXRlc10uc3RhdGUgPSBTYXZlZFBpeGVsU3RhdGVzX1NbaV07CiAgICAgICAgICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfc2FtcGxlcl9zdGF0ZXMrKzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZihvYmplY3QtPnBpeGVsU2hhZGVyKSB7CiAgICAgICAgICAgIElXaW5lRDNEUGl4ZWxTaGFkZXJfQWRkUmVmKG9iamVjdC0+cGl4ZWxTaGFkZXIpOwogICAgICAgIH0KCiAgICAgICAgLyogUGl4ZWwgc3RhdGUgYmxvY2tzIGRvIG5vdCBjb250YWluIHZlcnRleCBidWZmZXJzLiBTZXQgdGhlbSB0byBOVUxMIHRvIGF2b2lkIHdyb25nIHJlZmNvdW50aW5nCiAgICAgICAgICogb24gdGhlbS4gVGhpcyBtYWtlcyByZWxlYXNpbmcgdGhlIGJ1ZmZlciBlYXNpZXIKICAgICAgICAgKi8KICAgICAgICBmb3IoaSA9IDA7IGkgPCBNQVhfU1RSRUFNUzsgaSsrKSB7CiAgICAgICAgICAgIG9iamVjdC0+c3RyZWFtU291cmNlW2ldID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgb2JqZWN0LT5wSW5kZXhEYXRhID0gTlVMTDsKICAgICAgICBvYmplY3QtPnZlcnRleFNoYWRlciA9IE5VTEw7CgogICAgfSBlbHNlIGlmIChUeXBlID09IFdJTkVEM0RTQlRfVkVSVEVYU1RBVEUpIHsKCiAgICAgICAgVFJBQ0UoIlZFUlRFWFNUQVRFID0+IFByZXRlbmQgYWxsIHZlcnRleCBzaGF0ZXMgaGF2ZSBjaGFuZ2VkXG4iKTsKICAgICAgICBzdGF0ZWJsb2NrX3NhdmVkc3RhdGVzX3NldCgoSVdpbmVEM0RTdGF0ZUJsb2NrKikgb2JqZWN0LCAmb2JqZWN0LT5jaGFuZ2VkLCBGQUxTRSk7CgogICAgICAgIG9iamVjdC0+Y2hhbmdlZC52ZXJ0ZXhTaGFkZXIgPSBUUlVFOwoKICAgICAgICAvKiBWZXJ0ZXggU2hhZGVyIENvbnN0YW50cyAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBHTF9MSU1JVFModnNoYWRlcl9jb25zdGFudHNGKTsgKytpKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y2hhbmdlZC52ZXJ0ZXhTaGFkZXJDb25zdGFudHNGW2ldID0gVFJVRTsKICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfdnNfY29uc3RzX2ZbaV0gPSBpOwogICAgICAgIH0KICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfdnNfY29uc3RzX2YgPSBHTF9MSU1JVFModnNoYWRlcl9jb25zdGFudHNGKTsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgTUFYX0NPTlNUX0I7ICsraSkgewogICAgICAgICAgICBvYmplY3QtPmNoYW5nZWQudmVydGV4U2hhZGVyQ29uc3RhbnRzQltpXSA9IFRSVUU7CiAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3ZzX2NvbnN0c19iW2ldID0gaTsKICAgICAgICB9CiAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3ZzX2NvbnN0c19iID0gTUFYX0NPTlNUX0I7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IE1BWF9DT05TVF9JOyArK2kpIHsKICAgICAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnZlcnRleFNoYWRlckNvbnN0YW50c0lbaV0gPSBUUlVFOwogICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF92c19jb25zdHNfaVtpXSA9IGk7CiAgICAgICAgfQogICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF92c19jb25zdHNfaSA9IE1BWF9DT05TVF9JOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBOVU1fU0FWRURWRVJURVhTVEFURVNfUjsgaSsrKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y2hhbmdlZC5yZW5kZXJTdGF0ZVtTYXZlZFZlcnRleFN0YXRlc19SW2ldXSA9IFRSVUU7CiAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3JlbmRlcl9zdGF0ZXNbaV0gPSBTYXZlZFZlcnRleFN0YXRlc19SW2ldOwogICAgICAgIH0KICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfcmVuZGVyX3N0YXRlcyA9IE5VTV9TQVZFRFZFUlRFWFNUQVRFU19SOwogICAgICAgIGZvciAoaiA9IDA7IGogPCBNQVhfVEVYVFVSRVM7IGorKykgewogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgTlVNX1NBVkVEVkVSVEVYU1RBVEVTX1Q7IGkrKykgewogICAgICAgICAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnRleHR1cmVTdGF0ZVtqXVtTYXZlZFZlcnRleFN0YXRlc19UW2ldXSA9IFRSVUU7CiAgICAgICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF90c3Nfc3RhdGVzW29iamVjdC0+bnVtX2NvbnRhaW5lZF90c3Nfc3RhdGVzXS5zdGFnZSA9IGo7CiAgICAgICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF90c3Nfc3RhdGVzW29iamVjdC0+bnVtX2NvbnRhaW5lZF90c3Nfc3RhdGVzXS5zdGF0ZSA9IFNhdmVkVmVydGV4U3RhdGVzX1RbaV07CiAgICAgICAgICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfdHNzX3N0YXRlcysrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGZvciAoaiA9IDAgOyBqIDwgTUFYX0NPTUJJTkVEX1NBTVBMRVJTOyBqKyspewogICAgICAgICAgICBmb3IgKGkgPTA7IGkgPCBOVU1fU0FWRURWRVJURVhTVEFURVNfUztpKyspIHsKICAgICAgICAgICAgICAgIG9iamVjdC0+Y2hhbmdlZC5zYW1wbGVyU3RhdGVbal1bU2F2ZWRWZXJ0ZXhTdGF0ZXNfU1tpXV0gPSBUUlVFOwogICAgICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfc2FtcGxlcl9zdGF0ZXNbb2JqZWN0LT5udW1fY29udGFpbmVkX3NhbXBsZXJfc3RhdGVzXS5zdGFnZSA9IGo7CiAgICAgICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF9zYW1wbGVyX3N0YXRlc1tvYmplY3QtPm51bV9jb250YWluZWRfc2FtcGxlcl9zdGF0ZXNdLnN0YXRlID0gU2F2ZWRWZXJ0ZXhTdGF0ZXNfU1tpXTsKICAgICAgICAgICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF9zYW1wbGVyX3N0YXRlcysrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3IoaiA9IDA7IGogPCBMSUdIVE1BUF9TSVpFOyBqKyspIHsKICAgICAgICAgICAgc3RydWN0IGxpc3QgKmU7CiAgICAgICAgICAgIExJU1RfRk9SX0VBQ0goZSwgJm9iamVjdC0+bGlnaHRNYXBbal0pIHsKICAgICAgICAgICAgICAgIFBMSUdIVElORk9FTCAqbGlnaHQgPSBMSVNUX0VOVFJZKGUsIFBMSUdIVElORk9FTCwgZW50cnkpOwogICAgICAgICAgICAgICAgbGlnaHQtPmNoYW5nZWQgPSBUUlVFOwogICAgICAgICAgICAgICAgbGlnaHQtPmVuYWJsZWRDaGFuZ2VkID0gVFJVRTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZm9yKGkgPSAwOyBpIDwgTUFYX1NUUkVBTVM7IGkrKykgewogICAgICAgICAgICBpZihvYmplY3QtPnN0cmVhbVNvdXJjZVtpXSkgewogICAgICAgICAgICAgICAgSVdpbmVEM0RWZXJ0ZXhCdWZmZXJfQWRkUmVmKG9iamVjdC0+c3RyZWFtU291cmNlW2ldKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZihvYmplY3QtPnZlcnRleFNoYWRlcikgewogICAgICAgICAgICBJV2luZUQzRFZlcnRleFNoYWRlcl9BZGRSZWYob2JqZWN0LT52ZXJ0ZXhTaGFkZXIpOwogICAgICAgIH0KICAgICAgICBvYmplY3QtPnBJbmRleERhdGEgPSBOVUxMOwogICAgICAgIG9iamVjdC0+cGl4ZWxTaGFkZXIgPSBOVUxMOwogICAgfSBlbHNlIHsKICAgICAgICBGSVhNRSgiVW5yZWNvZ25pemVkIHN0YXRlIGJsb2NrIHR5cGUgJWRcbiIsIFR5cGUpOwogICAgfQoKICAgIFRSQUNFKCIoJXApIHJldHVybmluZyB0b2tlbiAocHRyIHRvIHN0YXRlYmxvY2spIG9mICVwXG4iLCBUaGlzLCBvYmplY3QpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgpNU0ROOgpbaW5dIFJlbmRlciB0YXJnZXRzIGFyZSBub3QgbG9ja2FibGUgdW5sZXNzIHRoZSBhcHBsaWNhdGlvbiBzcGVjaWZpZXMgVFJVRSBmb3IgTG9ja2FibGUuIE5vdGUgdGhhdCBsb2NrYWJsZSByZW5kZXIgdGFyZ2V0cyByZWR1Y2UgcGVyZm9ybWFuY2Ugb24gc29tZSBncmFwaGljcyBoYXJkd2FyZS4KCkRpc2NhcmQKIFtpbl0gU2V0IHRoaXMgZmxhZyB0byBUUlVFIHRvIGVuYWJsZSB6LWJ1ZmZlciBkaXNjYXJkaW5nLCBhbmQgRkFMU0Ugb3RoZXJ3aXNlLiAKCklmIHRoaXMgZmxhZyBpcyBzZXQsIHRoZSBjb250ZW50cyBvZiB0aGUgZGVwdGggc3RlbmNpbCBidWZmZXIgd2lsbCBiZSBpbnZhbGlkIGFmdGVyIGNhbGxpbmcgZWl0aGVyIElEaXJlY3QzRERldmljZTk6OlByZXNlbnQgb3IgSURpcmVjdDNERGV2aWNlOTo6U2V0RGVwdGhTdGVuY2lsU3VyZmFjZSB3aXRoIGEgZGlmZmVyZW50IGRlcHRoIHN1cmZhY2UuCgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLwogCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVN1cmZhY2UoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIFdpZHRoLCBVSU5UIEhlaWdodCwgV0lORUQzREZPUk1BVCBGb3JtYXQsIEJPT0wgTG9ja2FibGUsIEJPT0wgRGlzY2FyZCwgVUlOVCBMZXZlbCwgSVdpbmVEM0RTdXJmYWNlICoqcHBTdXJmYWNlLFdJTkVEM0RSRVNPVVJDRVRZUEUgVHlwZSwgRFdPUkQgVXNhZ2UsIFdJTkVEM0RQT09MIFBvb2wsIFdJTkVEM0RNVUxUSVNBTVBMRV9UWVBFIE11bHRpU2FtcGxlICxEV09SRCBNdWx0aXNhbXBsZVF1YWxpdHksIEhBTkRMRSogcFNoYXJlZEhhbmRsZSwgV0lORUQzRFNVUkZUWVBFIEltcGwsIElVbmtub3duICpwYXJlbnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7ICAgIAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqb2JqZWN0OyAvKk5PVEU6IGltcGwgcmVmIGFsbG93ZWQgc2luY2UgdGhpcyBpcyBhIGNyZWF0ZSBmdW5jdGlvbiAqLwogICAgdW5zaWduZWQgaW50IFNpemUgICAgICAgPSAxOwogICAgY29uc3QgU3RhdGljUGl4ZWxGb3JtYXREZXNjICp0YWJsZUVudHJ5ID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KEZvcm1hdCwgTlVMTCwgTlVMTCk7CiAgICBUUkFDRSgiKCVwKSBDcmVhdGUgc3VyZmFjZVxuIixUaGlzKTsKICAgIAogICAgLyoqIEZJWE1FOiBDaGVjayByYW5nZXMgb24gdGhlIGlucHV0cyBhcmUgdmFsaWQgCiAgICAgKiBNU0ROCiAgICAgKiAgIE11bHRpc2FtcGxlUXVhbGl0eQogICAgICogICAgW2luXSBRdWFsaXR5IGxldmVsLiBUaGUgdmFsaWQgcmFuZ2UgaXMgYmV0d2VlbiB6ZXJvIGFuZCBvbmUgbGVzcyB0aGFuIHRoZSBsZXZlbAogICAgICogICAgcmV0dXJuZWQgYnkgcFF1YWxpdHlMZXZlbHMgdXNlZCBieSBJRGlyZWN0M0Q5OjpDaGVja0RldmljZU11bHRpU2FtcGxlVHlwZS4gCiAgICAgKiAgICBQYXNzaW5nIGEgbGFyZ2VyIHZhbHVlIHJldHVybnMgdGhlIGVycm9yIFdJTkVEM0RFUlJfSU5WQUxJRENBTEwuIFRoZSBNdWx0aXNhbXBsZVF1YWxpdHkKICAgICAqICAgIHZhbHVlcyBvZiBwYWlyZWQgcmVuZGVyIHRhcmdldHMsIGRlcHRoIHN0ZW5jaWwgc3VyZmFjZXMsIGFuZCB0aGUgTXVsdGlTYW1wbGUgdHlwZQogICAgICogICAgbXVzdCBhbGwgbWF0Y2guCiAgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKICAgIC8qKgogICAgKiBUT0RPOiBEaXNjYXJkIE1TRE4KICAgICogW2luXSBTZXQgdGhpcyBmbGFnIHRvIFRSVUUgdG8gZW5hYmxlIHotYnVmZmVyIGRpc2NhcmRpbmcsIGFuZCBGQUxTRSBvdGhlcndpc2UuCiAgICAqCiAgICAqIElmIHRoaXMgZmxhZyBpcyBzZXQsIHRoZSBjb250ZW50cyBvZiB0aGUgZGVwdGggc3RlbmNpbCBidWZmZXIgd2lsbCBiZQogICAgKiBpbnZhbGlkIGFmdGVyIGNhbGxpbmcgZWl0aGVyIElEaXJlY3QzRERldmljZTk6OlByZXNlbnQgb3IgICogSURpcmVjdDNERGV2aWNlOTo6U2V0RGVwdGhTdGVuY2lsU3VyZmFjZQogICAgKiB3aXRoIGEgZGlmZmVyZW50IGRlcHRoIHN1cmZhY2UuCiAgICAqCiAgICAqVGhpcyBmbGFnIGhhcyB0aGUgc2FtZSBiZWhhdmlvciBhcyB0aGUgY29uc3RhbnQsIEQzRFBSRVNFTlRGTEFHX0RJU0NBUkRfREVQVEhTVEVOQ0lMLCBpbiBEM0RQUkVTRU5URkxBRy4KICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICBpZihNdWx0aXNhbXBsZVF1YWxpdHkgPCAwKSB7CiAgICAgICAgRklYTUUoIkludmFsaWQgbXVsdGlzYW1wbGUgbGV2ZWwgJWRcbiIsIE11bHRpc2FtcGxlUXVhbGl0eSk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7IC8qIFRPRE86IENoZWNrIHRoYXQgdGhpcyBpcyB0aGUgY2FzZSEgKi8KICAgIH0KCiAgICBpZihNdWx0aXNhbXBsZVF1YWxpdHkgPiAwKSB7CiAgICAgICAgRklYTUUoIk11bHRpc2FtcGxlUXVhbGl0eSBzZXQgdG8gJWQsIHN1YnN0aXR1dGluZyAwXG4iLCBNdWx0aXNhbXBsZVF1YWxpdHkpOwogICAgICAgIE11bHRpc2FtcGxlUXVhbGl0eT0wOwogICAgfQoKICAgIC8qKiBGSVhNRTogQ2hlY2sgdGhhdCB0aGUgZm9ybWF0IGlzIHN1cHBvcnRlZAogICAgKiAgICBieSB0aGUgZGV2aWNlLgogICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qKiBEWFRuIG1pcG1hcHMgdXNlIHRoZSBzYW1lIG51bWJlciBvZiAnbGV2ZWxzJyBkb3duIHRvIGVnLiA4eDEsIGJ1dCBzaW5jZQogICAgICogIGl0IGlzIGJhc2VkIGFyb3VuZCA0eDQgcGl4ZWwgYmxvY2tzIGl0IHJlcXVpcmVzIHBhZGRpbmcsIHNvIGFsbG9jYXRlIGVub3VnaAogICAgICogIHNwYWNlIQogICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAgICBpZiAoV0lORUQzREZNVF9VTktOT1dOID09IEZvcm1hdCkgewogICAgICAgIFNpemUgPSAwOwogICAgfSBlbHNlIGlmIChGb3JtYXQgPT0gV0lORUQzREZNVF9EWFQxKSB7CiAgICAgICAgLyogRFhUMSBpcyBoYWxmIGJ5dGUgcGVyIHBpeGVsICovCiAgICAgICBTaXplID0gKChtYXgoV2lkdGgsNCkgKiB0YWJsZUVudHJ5LT5icHApICogbWF4KEhlaWdodCw0KSkgPj4gMTsKCiAgICB9IGVsc2UgaWYgKEZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDIgfHwgRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMyB8fAogICAgICAgICAgICAgICBGb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ0IHx8IEZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDUpIHsKICAgICAgIFNpemUgPSAoKG1heChXaWR0aCw0KSAqIHRhYmxlRW50cnktPmJwcCkgKiBtYXgoSGVpZ2h0LDQpKTsKICAgIH0gZWxzZSB7CiAgICAgICAvKiBUaGUgcGl0Y2ggaXMgYSBtdWx0aXBsZSBvZiA0IGJ5dGVzICovCiAgICAgICAgU2l6ZSA9ICgoV2lkdGggKiB0YWJsZUVudHJ5LT5icHApICsgVGhpcy0+c3VyZmFjZV9hbGlnbm1lbnQgLSAxKSAmIH4oVGhpcy0+c3VyZmFjZV9hbGlnbm1lbnQgLSAxKTsKICAgICAgIFNpemUgKj0gSGVpZ2h0OwogICAgfQoKICAgIC8qKiBDcmVhdGUgYW5kIGluaXRpYWxpc2UgdGhlIHN1cmZhY2UgcmVzb3VyY2UgKiovCiAgICBEM0RDUkVBVEVSRVNPVVJDRU9CSkVDVElOU1RBTkNFKG9iamVjdCxTdXJmYWNlLFdJTkVEM0RSVFlQRV9TVVJGQUNFLCBTaXplKQogICAgLyogIlN0YW5kYWxvbmUiIHN1cmZhY2UgKi8KICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb250YWluZXIoKElXaW5lRDNEU3VyZmFjZSAqKW9iamVjdCwgTlVMTCk7CgogICAgb2JqZWN0LT5jdXJyZW50RGVzYy5XaWR0aCAgICAgID0gV2lkdGg7CiAgICBvYmplY3QtPmN1cnJlbnREZXNjLkhlaWdodCAgICAgPSBIZWlnaHQ7CiAgICBvYmplY3QtPmN1cnJlbnREZXNjLk11bHRpU2FtcGxlVHlwZSAgICA9IE11bHRpU2FtcGxlOwogICAgb2JqZWN0LT5jdXJyZW50RGVzYy5NdWx0aVNhbXBsZVF1YWxpdHkgPSBNdWx0aXNhbXBsZVF1YWxpdHk7CiAgICBvYmplY3QtPmdsRGVzY3JpcHRpb24ubGV2ZWwgICAgICAgICAgICA9IExldmVsOwoKICAgIC8qIEZsYWdzICovCiAgICBvYmplY3QtPkZsYWdzICAgICAgPSAwOwogICAgb2JqZWN0LT5GbGFncyAgICAgfD0gRGlzY2FyZCA/IFNGTEFHX0RJU0NBUkQgOiAwOwogICAgb2JqZWN0LT5GbGFncyAgICAgfD0gKFdJTkVEM0RGTVRfRDE2X0xPQ0tBQkxFID09IEZvcm1hdCkgPyBTRkxBR19MT0NLQUJMRSA6IDA7CiAgICBvYmplY3QtPkZsYWdzICAgICB8PSBMb2NrYWJsZSA/IFNGTEFHX0xPQ0tBQkxFIDogMDsKCgogICAgaWYgKFdJTkVEM0RGTVRfVU5LTk9XTiAhPSBGb3JtYXQpIHsKICAgICAgICBvYmplY3QtPmJ5dGVzUGVyUGl4ZWwgPSB0YWJsZUVudHJ5LT5icHA7CiAgICB9IGVsc2UgewogICAgICAgIG9iamVjdC0+Ynl0ZXNQZXJQaXhlbCA9IDA7CiAgICB9CgogICAgLyoqIFRPRE86IGNoYW5nZSB0aGlzIGludG8gYSB0ZXh0dXJlIHRyYW5zZm9ybSBtYXRyaXggc28gdGhhdCBpdCdzIHByb2Nlc3NlZCBpbiBoYXJkd2FyZSAqKi8KCiAgICBUUkFDRSgiUG9vbCAlZCAlZCAlZCAlZFxuIixQb29sLCBXSU5FRDNEUE9PTF9ERUZBVUxULCBXSU5FRDNEUE9PTF9NQU5BR0VELCBXSU5FRDNEUE9PTF9TWVNURU1NRU0pOwoKICAgIC8qKiBRdWljayBsb2NrYWJsZSBzYW5pdHkgY2hlY2sgVE9ETzogcmVtb3ZlIHRoaXMgYWZ0ZXIgc3VyZmFjZXMsIHVzYWdlIGFuZCBsb2NrYWJpbGl0eSBoYXZlIGJlZW4gZGVidWdnZWQgcHJvcGVybHkKICAgICogdGhpcyBmdW5jdGlvbiBpcyB0b28gZGVlcCB0byBuZWVkIHRvIGNhcmUgYWJvdXQgdGhpbmdzIGxpa2UgdGhpcy4KICAgICogTGV2ZWxzIG5lZWQgdG8gYmUgY2hlY2tlZCB0b28sIGFuZCBwb3NzaWJseSBUeXBlIHNpbmNlIHRoZXkgYWxsIGFmZmVjdCB3aGF0IGNhbiBiZSBkb25lLgogICAgKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgc3dpdGNoKFBvb2wpIHsKICAgIGNhc2UgV0lORUQzRFBPT0xfU0NSQVRDSDoKICAgICAgICBpZighTG9ja2FibGUpCiAgICAgICAgICAgIEZJWE1FKCJDcmVhdGUgc3VyZmFjZSBjYWxsZWQgd2l0aCBhIHBvb2wgb2YgU0NSQVRDSCBhbmQgYSBMb2NrYWJsZSBvZiBGQUxTRSAiCiAgICAgICAgICAgICAgICAid2hpY2ggYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZSwgc2V0dGluZyBsb2NrYWJsZSB0byBUUlVFXG4iKTsKICAgICAgICAgICAgICAgIExvY2thYmxlID0gVFJVRTsKICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEUE9PTF9TWVNURU1NRU06CiAgICAgICAgaWYoIUxvY2thYmxlKSBGSVhNRSgiQ3JlYXRlIHN1cmZhY2UgY2FsbGVkIHdpdGggYSBwb29sIG9mIFNZU1RFTU1FTSBhbmQgYSBMb2NrYWJsZSBvZiBGQUxTRSwgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGhpcyBpcyBhY2NlcHRhYmxlIGJ1dCB1bmV4cGVjdGVkIChJIGNhbid0IGtub3cgaG93IHRoZSBzdXJmYWNlIGNhbiBiZSB1c2FibGUhKVxuIik7CiAgICBjYXNlIFdJTkVEM0RQT09MX01BTkFHRUQ6CiAgICAgICAgaWYoVXNhZ2UgPT0gV0lORUQzRFVTQUdFX0RZTkFNSUMpIEZJWE1FKCJDcmVhdGUgc3VyZmFjZSBjYWxsZWQgd2l0aCBhIHBvb2wgb2YgTUFOQUdFRCBhbmQgYSAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJVc2FnZSBvZiBEWU5BTUlDIHdoaWNoIGFyZSBtdXR1YWxseSBleGNsdXNpdmUsIG5vdCBkb2luZyAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhbnl0aGluZyBqdXN0IHRlbGxpbmcgeW91LlxuIik7CiAgICBicmVhazsKICAgIGNhc2UgV0lORUQzRFBPT0xfREVGQVVMVDogLypUT0RPOiBDcmVhdGUgb2Zmc2NyZWVuIHBsYWluIGNhbiBjYXVzZSB0aGlzIGNoZWNrIHRvIGZhaWwuLi4sIGZpbmQgb3V0IGlmIGl0IHNob3VsZCAqLwogICAgICAgIGlmKCEoVXNhZ2UgJiBXSU5FRDNEVVNBR0VfRFlOQU1JQykgJiYgIShVc2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpCiAgICAgICAgICAgJiYgIShVc2FnZSAmJiBXSU5FRDNEVVNBR0VfREVQVEhTVEVOQ0lMICkgJiYgTG9ja2FibGUpCiAgICAgICAgICAgIFdBUk4oIkNyZWF0aW5nIGEgc3VyZmFjZSB3aXRoIGEgUE9PTCBvZiBERUZBVUxUIHdpdGggTG9ja2FibGUgdHJ1ZSwgdGhhdCBkb2Vzbid0IHNwZWNpZnkgRFlOQU1JQyB1c2FnZS5cbiIpOwogICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAgIEZJWE1FKCIoJXApIFVua25vd24gcG9vbCAlZFxuIiwgVGhpcywgUG9vbCk7CiAgICBicmVhazsKICAgIH07CgogICAgaWYgKFVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCAmJiBQb29sICE9IFdJTkVEM0RQT09MX0RFRkFVTFQpIHsKICAgICAgICBGSVhNRSgiVHJ5aW5nIHRvIGNyZWF0ZSBhIHJlbmRlciB0YXJnZXQgdGhhdCBpc24ndCBpbiB0aGUgZGVmYXVsdCBwb29sXG4iKTsKICAgIH0KCiAgICAvKiBtYXJrIHRoZSB0ZXh0dXJlIGFzIGRpcnR5IHNvIHRoYXQgaXQgZ2V0cyBsb2FkZWQgZmlyc3QgdGltZSBhcm91bmQqLwogICAgSVdpbmVEM0RTdXJmYWNlX0FkZERpcnR5UmVjdCgqcHBTdXJmYWNlLCBOVUxMKTsKICAgIFRSQUNFKCIoJXApIDogdyglZCkgaCglZCkgZm10KCVkLCVzKSBsb2NrYWJsZSglZCkgc3VyZkAlcCwgc3VyZm1lbUAlcCwgJWQgYnl0ZXNcbiIsCiAgICAgICAgICAgVGhpcywgV2lkdGgsIEhlaWdodCwgRm9ybWF0LCBkZWJ1Z19kM2Rmb3JtYXQoRm9ybWF0KSwKICAgICAgICAgICAoV0lORUQzREZNVF9EMTZfTE9DS0FCTEUgPT0gRm9ybWF0KSwgKnBwU3VyZmFjZSwgb2JqZWN0LT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnksIG9iamVjdC0+cmVzb3VyY2Uuc2l6ZSk7CgogICAgLyogU3RvcmUgdGhlIERpcmVjdERyYXcgcHJpbWFyeSBzdXJmYWNlLiBUaGlzIGlzIHRoZSBmaXJzdCByZW5kZXJ0YXJnZXQgc3VyZmFjZSBjcmVhdGVkICovCiAgICBpZiggKFVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgJiYgKCFUaGlzLT5kZHJhd19wcmltYXJ5KSApCiAgICAgICAgVGhpcy0+ZGRyYXdfcHJpbWFyeSA9IChJV2luZUQzRFN1cmZhY2UgKikgb2JqZWN0OwoKICAgIC8qIExvb2sgYXQgdGhlIGltcGxlbWVudGF0aW9uIGFuZCBzZXQgdGhlIGNvcnJlY3QgVnRhYmxlICovCiAgICBzd2l0Y2goSW1wbCkgewogICAgICAgIGNhc2UgU1VSRkFDRV9PUEVOR0w6CiAgICAgICAgICAgIC8qIENoZWNrIGlmIGEgM0QgYWRhcHRlciBpcyBhdmFpbGFibGUgd2hlbiBjcmVhdGluZyBnbCBzdXJmYWNlcyAqLwogICAgICAgICAgICBpZighVGhpcy0+YWRhcHRlcikgewogICAgICAgICAgICAgICAgRVJSKCJPcGVuR0wgc3VyZmFjZXMgYXJlIG5vdCBhdmFpbGFibGUgd2l0aG91dCBvcGVuZ2xcbiIpOwogICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2JqZWN0LT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2JqZWN0KTsKICAgICAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX05PVEFWQUlMQUJMRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBTVVJGQUNFX0dESToKICAgICAgICAgICAgb2JqZWN0LT5scFZ0YmwgPSAmSVdpbmVHRElTdXJmYWNlX1Z0Ymw7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAvKiBUbyBiZSBzdXJlIHRvIGNhdGNoIHRoaXMgKi8KICAgICAgICAgICAgRVJSKCJVbmtub3duIHJlcXVlc3RlZCBzdXJmYWNlIGltcGxlbWVudGF0aW9uICVkIVxuIiwgSW1wbCk7CiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKChJV2luZUQzRFN1cmZhY2UgKikgb2JqZWN0KTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgbGlzdF9pbml0KCZvYmplY3QtPnJlbmRlcmJ1ZmZlcnMpOwoKICAgIC8qIENhbGwgdGhlIHByaXZhdGUgc2V0dXAgcm91dGluZSAqLwogICAgcmV0dXJuIElXaW5lRDNEU3VyZmFjZV9Qcml2YXRlU2V0dXAoIChJV2luZUQzRFN1cmZhY2UgKikgb2JqZWN0ICk7Cgp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVUZXh0dXJlKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBXaWR0aCwgVUlOVCBIZWlnaHQsIFVJTlQgTGV2ZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVXNhZ2UsIFdJTkVEM0RGT1JNQVQgRm9ybWF0LCBXSU5FRDNEUE9PTCBQb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RUZXh0dXJlKiogcHBUZXh0dXJlLCBIQU5ETEUqIHBTaGFyZWRIYW5kbGUsIElVbmtub3duICpwYXJlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RDQl9DUkVBVEVTVVJGQUNFRk4gRDNEQ0JfQ3JlYXRlU3VyZmFjZSkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEVGV4dHVyZUltcGwgKm9iamVjdDsKICAgIHVuc2lnbmVkIGludCBpOwogICAgVUlOVCB0bXBXOwogICAgVUlOVCB0bXBIOwogICAgSFJFU1VMVCBocjsKICAgIHVuc2lnbmVkIGludCBwb3cyV2lkdGg7CiAgICB1bnNpZ25lZCBpbnQgcG93MkhlaWdodDsKICAgIGNvbnN0IEdsUGl4ZWxGb3JtYXREZXNjICpnbERlc2M7CiAgICBnZXRGb3JtYXREZXNjRW50cnkoRm9ybWF0LCAmR0xJTkZPX0xPQ0FUSU9OLCAmZ2xEZXNjKTsKCgogICAgVFJBQ0UoIiglcCkgOiBXaWR0aCAlZCwgSGVpZ2h0ICVkLCBMZXZlbHMgJWQsIFVzYWdlICUjeFxuIiwgVGhpcywgV2lkdGgsIEhlaWdodCwgTGV2ZWxzLCBVc2FnZSk7CiAgICBUUkFDRSgiRm9ybWF0ICUjeCAoJXMpLCBQb29sICUjeCwgcHBUZXh0dXJlICVwLCBwU2hhcmVkSGFuZGxlICVwLCBwYXJlbnQgJXBcbiIsCiAgICAgICAgICAgIEZvcm1hdCwgZGVidWdfZDNkZm9ybWF0KEZvcm1hdCksIFBvb2wsIHBwVGV4dHVyZSwgcFNoYXJlZEhhbmRsZSwgcGFyZW50KTsKCiAgICAvKiBUT0RPOiBJdCBzaG91bGQgb25seSBiZSBwb3NzaWJsZSB0byBjcmVhdGUgdGV4dHVyZXMgZm9yIGZvcm1hdHMgCiAgICAgICAgICAgICB0aGF0IGFyZSByZXBvcnRlZCBhcyBzdXBwb3J0ZWQgKi8KICAgIGlmIChXSU5FRDNERk1UX1VOS05PV04gPj0gRm9ybWF0KSB7CiAgICAgICAgV0FSTigiKCVwKSA6IFRleHR1cmUgY2Fubm90IGJlIGNyZWF0ZWQgd2l0aCBhIGZvcm1hdCBvZiBXSU5FRDNERk1UX1VOS05PV05cbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIEQzRENSRUFURVJFU09VUkNFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBUZXh0dXJlLCBXSU5FRDNEUlRZUEVfVEVYVFVSRSwgMCk7CiAgICBEM0RJTklUSUFMSVpFQkFTRVRFWFRVUkUob2JqZWN0LT5iYXNlVGV4dHVyZSk7ICAgIAogICAgb2JqZWN0LT53aWR0aCAgPSBXaWR0aDsKICAgIG9iamVjdC0+aGVpZ2h0ID0gSGVpZ2h0OwoKICAgIC8qKiBOb24tcG93ZXIyIHN1cHBvcnQgKiovCiAgICBpZiAoR0xfU1VQUE9SVChBUkJfVEVYVFVSRV9OT05fUE9XRVJfT0ZfVFdPKSkgewogICAgICAgIHBvdzJXaWR0aCA9IFdpZHRoOwogICAgICAgIHBvdzJIZWlnaHQgPSBIZWlnaHQ7CiAgICB9IGVsc2UgewogICAgICAgIC8qIEZpbmQgdGhlIG5lYXJlc3QgcG93MiBtYXRjaCAqLwogICAgICAgIHBvdzJXaWR0aCA9IHBvdzJIZWlnaHQgPSAxOwogICAgICAgIHdoaWxlIChwb3cyV2lkdGggPCBXaWR0aCkgcG93MldpZHRoIDw8PSAxOwogICAgICAgIHdoaWxlIChwb3cySGVpZ2h0IDwgSGVpZ2h0KSBwb3cySGVpZ2h0IDw8PSAxOwoKICAgICAgICBpZihwb3cyV2lkdGggIT0gV2lkdGggfHwgcG93MkhlaWdodCAhPSBIZWlnaHQpIHsKICAgICAgICAgICAgaWYoTGV2ZWxzID4gMSkgewogICAgICAgICAgICAgICAgV0FSTigiQXR0ZW1wdGVkIHRvIGNyZWF0ZSBhIG1pcG1hcHBlZCBucDIgdGV4dHVyZSB3aXRob3V0IHVuY29uZGl0aW9uYWwgbnAyIHN1cHBvcnRcbiIpOwogICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2JqZWN0KTsKICAgICAgICAgICAgICAgICpwcFRleHR1cmUgPSBOVUxMOwogICAgICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBMZXZlbHMgPSAxOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qKiBGSVhNRTogYWRkIHN1cHBvcnQgZm9yIHJlYWwgbm9uLXBvd2VyLXR3byBpZiBpdCdzIHByb3ZpZGVkIGJ5IHRoZSB2aWRlbyBjYXJkICoqLwogICAgLyogUHJlY2FsY3VsYXRlZCBzY2FsaW5nIGZvciAnZmFrZWQnIG5vbiBwb3dlciBvZiB0d28gdGV4dHVyZSBjb29yZHMgKi8KICAgIGlmKEdMX1NVUFBPUlQoQVJCX1RFWFRVUkVfUkVDVEFOR0xFKSAmJgogICAgICAgKFdpZHRoICE9IHBvdzJXaWR0aCB8fCBIZWlnaHQgIT0gcG93MkhlaWdodCkpIHsKICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLnBvdzJNYXRyaXhbMF0gPSAgKGZsb2F0KVdpZHRoOwogICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUucG93Mk1hdHJpeFs1XSA9ICAoZmxvYXQpSGVpZ2h0OwogICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUucG93Mk1hdHJpeFsxMF0gPSAxLjA7CiAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5wb3cyTWF0cml4WzE1XSA9IDEuMDsKICAgICAgICBvYmplY3QtPnRhcmdldCA9IEdMX1RFWFRVUkVfUkVDVEFOR0xFX0FSQjsKICAgIH0gZWxzZSB7CiAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5wb3cyTWF0cml4WzBdID0gICgoKGZsb2F0KVdpZHRoKSAgLyAoKGZsb2F0KXBvdzJXaWR0aCkpOwogICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUucG93Mk1hdHJpeFs1XSA9ICAoKChmbG9hdClIZWlnaHQpIC8gKChmbG9hdClwb3cySGVpZ2h0KSk7CiAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5wb3cyTWF0cml4WzEwXSA9IDEuMDsKICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLnBvdzJNYXRyaXhbMTVdID0gMS4wOwogICAgICAgIG9iamVjdC0+dGFyZ2V0ID0gR0xfVEVYVFVSRV8yRDsKICAgIH0KICAgIFRSQUNFKCIgeGYoJWYpIHlmKCVmKVxuIiwgb2JqZWN0LT5iYXNlVGV4dHVyZS5wb3cyTWF0cml4WzBdLCBvYmplY3QtPmJhc2VUZXh0dXJlLnBvdzJNYXRyaXhbNV0pOwoKICAgIC8qIENhbGN1bGF0ZSBsZXZlbHMgZm9yIG1pcCBtYXBwaW5nICovCiAgICBpZiAoVXNhZ2UgJiBXSU5FRDNEVVNBR0VfQVVUT0dFTk1JUE1BUCkgewogICAgICAgIGlmKCFHTF9TVVBQT1JUKFNHSVNfR0VORVJBVEVfTUlQTUFQKSkgewogICAgICAgICAgICBXQVJOKCJObyBtaXBtYXAgZ2VuZXJhdGlvbiBzdXBwb3J0LCByZXR1cm5pbmcgRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfQogICAgICAgIGlmKExldmVscyA+IDEpIHsKICAgICAgICAgICAgV0FSTigiRDNEVVNBR0VfQVVUT0dFTk1JUE1BUCBpcyBzZXQsIGFuZCBsZXZlbCBjb3VudCA+IDEsIHJldHVybmluZyBEM0RFUlJfSU5WQUxJRENBTExcbiIpOwogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICB9CiAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5sZXZlbHMgPSAxOwogICAgfSBlbHNlIGlmIChMZXZlbHMgPT0gMCkgewogICAgICAgIFRSQUNFKCJjYWxjdWxhdGluZyBsZXZlbHMgJWRcbiIsIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzKTsKICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVscysrOwogICAgICAgIHRtcFcgPSBXaWR0aDsKICAgICAgICB0bXBIID0gSGVpZ2h0OwogICAgICAgIHdoaWxlICh0bXBXID4gMSB8fCB0bXBIID4gMSkgewogICAgICAgICAgICB0bXBXID0gbWF4KDEsIHRtcFcgPj4gMSk7CiAgICAgICAgICAgIHRtcEggPSBtYXgoMSwgdG1wSCA+PiAxKTsKICAgICAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5sZXZlbHMrKzsKICAgICAgICB9CiAgICAgICAgVFJBQ0UoIkNhbGN1bGF0ZWQgbGV2ZWxzID0gJWRcbiIsIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzKTsKICAgIH0KCiAgICAvKiBHZW5lcmF0ZSBhbGwgdGhlIHN1cmZhY2VzICovCiAgICB0bXBXID0gV2lkdGg7CiAgICB0bXBIID0gSGVpZ2h0OwogICAgZm9yIChpID0gMDsgaSA8IG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzOyBpKyspCiAgICB7CiAgICAgICAgLyogdXNlIHRoZSBjYWxsYmFjayB0byBjcmVhdGUgdGhlIHRleHR1cmUgc3VyZmFjZSAqLwogICAgICAgIGhyID0gRDNEQ0JfQ3JlYXRlU3VyZmFjZShUaGlzLT5wYXJlbnQsIHBhcmVudCwgdG1wVywgdG1wSCwgRm9ybWF0LCBVc2FnZSwgUG9vbCwgaSwgV0lORUQzRENVQkVNQVBfRkFDRV9QT1NJVElWRV9YLCAmb2JqZWN0LT5zdXJmYWNlc1tpXSxOVUxMKTsKICAgICAgICBpZiAoaHIhPSBXSU5FRDNEX09LIHx8ICggKElXaW5lRDNEU3VyZmFjZUltcGwgKikgb2JqZWN0LT5zdXJmYWNlc1tpXSktPkZsYWdzICYgU0ZMQUdfT1ZFUlNJWkUpIHsKICAgICAgICAgICAgRklYTUUoIkZhaWxlZCB0byBjcmVhdGUgc3VyZmFjZSAgJXBcbiIsIG9iamVjdCk7CiAgICAgICAgICAgIC8qIGNsZWFuIHVwICovCiAgICAgICAgICAgIG9iamVjdC0+c3VyZmFjZXNbaV0gPSBOVUxMOwogICAgICAgICAgICBJV2luZUQzRFRleHR1cmVfUmVsZWFzZSgoSVdpbmVEM0RUZXh0dXJlICopb2JqZWN0KTsKCiAgICAgICAgICAgICpwcFRleHR1cmUgPSBOVUxMOwogICAgICAgICAgICByZXR1cm4gaHI7CiAgICAgICAgfQoKICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29udGFpbmVyKG9iamVjdC0+c3VyZmFjZXNbaV0sIChJV2luZUQzREJhc2UgKilvYmplY3QpOwogICAgICAgIFRSQUNFKCJDcmVhdGVkIHN1cmZhY2UgbGV2ZWwgJWQgQCAlcFxuIiwgaSwgb2JqZWN0LT5zdXJmYWNlc1tpXSk7CiAgICAgICAgLyogY2FsY3VsYXRlIHRoZSBuZXh0IG1pcG1hcCBsZXZlbCAqLwogICAgICAgIHRtcFcgPSBtYXgoMSwgdG1wVyA+PiAxKTsKICAgICAgICB0bXBIID0gbWF4KDEsIHRtcEggPj4gMSk7CiAgICB9CiAgICBvYmplY3QtPmJhc2VUZXh0dXJlLnNoYWRlcl9jb252ZXJzaW9uX2dyb3VwID0gZ2xEZXNjLT5jb252ZXJzaW9uX2dyb3VwOwoKICAgIFRSQUNFKCIoJXApIDogQ3JlYXRlZCAgdGV4dHVyZSAlcFxuIiwgVGhpcywgb2JqZWN0KTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZvbHVtZVRleHR1cmUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFdpZHRoLCBVSU5UIEhlaWdodCwgVUlOVCBEZXB0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBMZXZlbHMsIERXT1JEIFVzYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNERk9STUFUIEZvcm1hdCwgV0lORUQzRFBPT0wgUG9vbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RWb2x1bWVUZXh0dXJlICoqcHBWb2x1bWVUZXh0dXJlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEUgKnBTaGFyZWRIYW5kbGUsIElVbmtub3duICpwYXJlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRENCX0NSRUFURVZPTFVNRUZOIEQzRENCX0NyZWF0ZVZvbHVtZSkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgICAgICAgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFZvbHVtZVRleHR1cmVJbXBsICpvYmplY3Q7CiAgICB1bnNpZ25lZCBpbnQgICAgICAgICAgICAgICBpOwogICAgVUlOVCAgICAgICAgICAgICAgICAgICAgICAgdG1wVzsKICAgIFVJTlQgICAgICAgICAgICAgICAgICAgICAgIHRtcEg7CiAgICBVSU5UICAgICAgICAgICAgICAgICAgICAgICB0bXBEOwogICAgY29uc3QgR2xQaXhlbEZvcm1hdERlc2MgKmdsRGVzYzsKCiAgICBnZXRGb3JtYXREZXNjRW50cnkoRm9ybWF0LCAmR0xJTkZPX0xPQ0FUSU9OLCAmZ2xEZXNjKTsKCiAgICAvKiBUT0RPOiBJdCBzaG91bGQgb25seSBiZSBwb3NzaWJsZSB0byBjcmVhdGUgdGV4dHVyZXMgZm9yIGZvcm1hdHMgCiAgICAgICAgICAgICB0aGF0IGFyZSByZXBvcnRlZCBhcyBzdXBwb3J0ZWQgKi8KICAgIGlmIChXSU5FRDNERk1UX1VOS05PV04gPj0gRm9ybWF0KSB7CiAgICAgICAgV0FSTigiKCVwKSA6IFRleHR1cmUgY2Fubm90IGJlIGNyZWF0ZWQgd2l0aCBhIGZvcm1hdCBvZiBXSU5FRDNERk1UX1VOS05PV05cbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgaWYoIUdMX1NVUFBPUlQoRVhUX1RFWFRVUkUzRCkpIHsKICAgICAgICBXQVJOKCIoJXApIDogVGV4dHVyZSBjYW5ub3QgYmUgY3JlYXRlZCAtIG5vIHZvbHVtZSB0ZXh0dXJlIHN1cHBvcnRcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIEQzRENSRUFURVJFU09VUkNFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBWb2x1bWVUZXh0dXJlLCBXSU5FRDNEUlRZUEVfVk9MVU1FVEVYVFVSRSwgMCk7CiAgICBEM0RJTklUSUFMSVpFQkFTRVRFWFRVUkUob2JqZWN0LT5iYXNlVGV4dHVyZSk7CgogICAgVFJBQ0UoIiglcCkgOiBXKCVkKSBIKCVkKSBEKCVkKSwgTHZsKCVkKSBVc2FnZSglZCksIEZtdCgldSwlcyksIFBvb2woJXMpXG4iLCBUaGlzLCBXaWR0aCwgSGVpZ2h0LAogICAgICAgICAgRGVwdGgsIExldmVscywgVXNhZ2UsIEZvcm1hdCwgZGVidWdfZDNkZm9ybWF0KEZvcm1hdCksIGRlYnVnX2QzZHBvb2woUG9vbCkpOwoKICAgIG9iamVjdC0+d2lkdGggID0gV2lkdGg7CiAgICBvYmplY3QtPmhlaWdodCA9IEhlaWdodDsKICAgIG9iamVjdC0+ZGVwdGggID0gRGVwdGg7CgogICAgLyogSXMgTlAyIHN1cHBvcnQgZm9yIHZvbHVtZXMgbmVlZGVkPyAqLwogICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5wb3cyTWF0cml4WyAwXSA9IDEuMDsKICAgIG9iamVjdC0+YmFzZVRleHR1cmUucG93Mk1hdHJpeFsgNV0gPSAxLjA7CiAgICBvYmplY3QtPmJhc2VUZXh0dXJlLnBvdzJNYXRyaXhbMTBdID0gMS4wOwogICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5wb3cyTWF0cml4WzE1XSA9IDEuMDsKCiAgICAvKiBDYWxjdWxhdGUgbGV2ZWxzIGZvciBtaXAgbWFwcGluZyAqLwogICAgaWYgKFVzYWdlICYgV0lORUQzRFVTQUdFX0FVVE9HRU5NSVBNQVApIHsKICAgICAgICBpZighR0xfU1VQUE9SVChTR0lTX0dFTkVSQVRFX01JUE1BUCkpIHsKICAgICAgICAgICAgV0FSTigiTm8gbWlwbWFwIGdlbmVyYXRpb24gc3VwcG9ydCwgcmV0dXJuaW5nIEQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgIH0KICAgICAgICBpZihMZXZlbHMgPiAxKSB7CiAgICAgICAgICAgIFdBUk4oIkQzRFVTQUdFX0FVVE9HRU5NSVBNQVAgaXMgc2V0LCBhbmQgbGV2ZWwgY291bnQgPiAxLCByZXR1cm5pbmcgRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfQogICAgICAgIExldmVscyA9IDE7CiAgICB9IGVsc2UgaWYgKExldmVscyA9PSAwKSB7CiAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5sZXZlbHMrKzsKICAgICAgICB0bXBXID0gV2lkdGg7CiAgICAgICAgdG1wSCA9IEhlaWdodDsKICAgICAgICB0bXBEID0gRGVwdGg7CiAgICAgICAgd2hpbGUgKHRtcFcgPiAxIHx8IHRtcEggPiAxIHx8IHRtcEQgPiAxKSB7CiAgICAgICAgICAgIHRtcFcgPSBtYXgoMSwgdG1wVyA+PiAxKTsKICAgICAgICAgICAgdG1wSCA9IG1heCgxLCB0bXBIID4+IDEpOwogICAgICAgICAgICB0bXBEID0gbWF4KDEsIHRtcEQgPj4gMSk7CiAgICAgICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzKys7CiAgICAgICAgfQogICAgICAgIFRSQUNFKCJDYWxjdWxhdGVkIGxldmVscyA9ICVkXG4iLCBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVscyk7CiAgICB9CgogICAgLyogR2VuZXJhdGUgYWxsIHRoZSBzdXJmYWNlcyAqLwogICAgdG1wVyA9IFdpZHRoOwogICAgdG1wSCA9IEhlaWdodDsKICAgIHRtcEQgPSBEZXB0aDsKCiAgICBmb3IgKGkgPSAwOyBpIDwgb2JqZWN0LT5iYXNlVGV4dHVyZS5sZXZlbHM7IGkrKykKICAgIHsKICAgICAgICBIUkVTVUxUIGhyOwogICAgICAgIC8qIENyZWF0ZSB0aGUgdm9sdW1lICovCiAgICAgICAgaHIgPSBEM0RDQl9DcmVhdGVWb2x1bWUoVGhpcy0+cGFyZW50LCBwYXJlbnQsIHRtcFcsIHRtcEgsIHRtcEQsIEZvcm1hdCwgUG9vbCwgVXNhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKElXaW5lRDNEVm9sdW1lICoqKSZvYmplY3QtPnZvbHVtZXNbaV0sIHBTaGFyZWRIYW5kbGUpOwoKICAgICAgICBpZihGQUlMRUQoaHIpKSB7CiAgICAgICAgICAgIEVSUigiQ3JlYXRpbmcgYSB2b2x1bWUgZm9yIHRoZSB2b2x1bWUgdGV4dHVyZSBmYWlsZWQoJTA4eClcbiIsIGhyKTsKICAgICAgICAgICAgSVdpbmVEM0RWb2x1bWVUZXh0dXJlX1JlbGVhc2UoKElXaW5lRDNEVm9sdW1lVGV4dHVyZSAqKSBvYmplY3QpOwogICAgICAgICAgICAqcHBWb2x1bWVUZXh0dXJlID0gTlVMTDsKICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgICAgIH0KCiAgICAgICAgLyogU2V0IGl0cyBjb250YWluZXIgdG8gdGhpcyBvYmplY3QgKi8KICAgICAgICBJV2luZUQzRFZvbHVtZV9TZXRDb250YWluZXIob2JqZWN0LT52b2x1bWVzW2ldLCAoSVdpbmVEM0RCYXNlICopb2JqZWN0KTsKCiAgICAgICAgLyogY2FsY3VhbHRlIHRoZSBuZXh0IG1pcG1hcCBsZXZlbCAqLwogICAgICAgIHRtcFcgPSBtYXgoMSwgdG1wVyA+PiAxKTsKICAgICAgICB0bXBIID0gbWF4KDEsIHRtcEggPj4gMSk7CiAgICAgICAgdG1wRCA9IG1heCgxLCB0bXBEID4+IDEpOwogICAgfQogICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5zaGFkZXJfY29udmVyc2lvbl9ncm91cCA9IGdsRGVzYy0+Y29udmVyc2lvbl9ncm91cDsKCiAgICAqcHBWb2x1bWVUZXh0dXJlID0gKElXaW5lRDNEVm9sdW1lVGV4dHVyZSAqKSBvYmplY3Q7CiAgICBUUkFDRSgiKCVwKSA6IENyZWF0ZWQgdm9sdW1lIHRleHR1cmUgJXBcbiIsIFRoaXMsIG9iamVjdCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWb2x1bWUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgV2lkdGgsIFVJTlQgSGVpZ2h0LCBVSU5UIERlcHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFVzYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RGT1JNQVQgRm9ybWF0LCBXSU5FRDNEUE9PTCBQb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEVm9sdW1lKiogcHBWb2x1bWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFKiBwU2hhcmVkSGFuZGxlLCBJVW5rbm93biAqcGFyZW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICAgICAgICAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEVm9sdW1lSW1wbCAgICAgICAgKm9iamVjdDsgLyoqIE5PVEU6IGltcGwgcmVmIGFsbG93ZWQgc2luY2UgdGhpcyBpcyBhIGNyZWF0ZSBmdW5jdGlvbiAqKi8KICAgIGNvbnN0IFN0YXRpY1BpeGVsRm9ybWF0RGVzYyAqZm9ybWF0RGVzYyAgPSBnZXRGb3JtYXREZXNjRW50cnkoRm9ybWF0LCBOVUxMLCBOVUxMKTsKCiAgICBpZighR0xfU1VQUE9SVChFWFRfVEVYVFVSRTNEKSkgewogICAgICAgIFdBUk4oIiglcCkgOiBWb2x1bWUgY2Fubm90IGJlIGNyZWF0ZWQgLSBubyB2b2x1bWUgdGV4dHVyZSBzdXBwb3J0XG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBEM0RDUkVBVEVSRVNPVVJDRU9CSkVDVElOU1RBTkNFKG9iamVjdCwgVm9sdW1lLCBXSU5FRDNEUlRZUEVfVk9MVU1FLCAoKFdpZHRoICogZm9ybWF0RGVzYy0+YnBwKSAqIEhlaWdodCAqIERlcHRoKSkKCiAgICBUUkFDRSgiKCVwKSA6IFcoJWQpIEgoJWQpIEQoJWQpLCBVc2FnZSglZCksIEZtdCgldSwlcyksIFBvb2woJXMpXG4iLCBUaGlzLCBXaWR0aCwgSGVpZ2h0LAogICAgICAgICAgRGVwdGgsIFVzYWdlLCBGb3JtYXQsIGRlYnVnX2QzZGZvcm1hdChGb3JtYXQpLCBkZWJ1Z19kM2Rwb29sKFBvb2wpKTsKCiAgICBvYmplY3QtPmN1cnJlbnREZXNjLldpZHRoICAgPSBXaWR0aDsKICAgIG9iamVjdC0+Y3VycmVudERlc2MuSGVpZ2h0ICA9IEhlaWdodDsKICAgIG9iamVjdC0+Y3VycmVudERlc2MuRGVwdGggICA9IERlcHRoOwogICAgb2JqZWN0LT5ieXRlc1BlclBpeGVsICAgICAgID0gZm9ybWF0RGVzYy0+YnBwOwoKICAgIC8qKiBOb3RlOiBWb2x1bWUgdGV4dHVyZXMgY2Fubm90IGJlIGR4dG4sIGhlbmNlIG5vIG5lZWQgdG8gY2hlY2sgaGVyZSAqKi8KICAgIG9iamVjdC0+bG9ja2FibGUgICAgICAgICAgICA9IFRSVUU7CiAgICBvYmplY3QtPmxvY2tlZCAgICAgICAgICAgICAgPSBGQUxTRTsKICAgIG1lbXNldCgmb2JqZWN0LT5sb2NrZWRCb3gsIDAsIHNpemVvZihXSU5FRDNEQk9YKSk7CiAgICBvYmplY3QtPmRpcnR5ICAgICAgICAgICAgICAgPSBUUlVFOwoKICAgIHJldHVybiBJV2luZUQzRFZvbHVtZV9BZGREaXJ0eUJveCgoSVdpbmVEM0RWb2x1bWUgKikgb2JqZWN0LCBOVUxMKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVDdWJlVGV4dHVyZShJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgRWRnZUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgTGV2ZWxzLCBEV09SRCBVc2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RGT1JNQVQgRm9ybWF0LCBXSU5FRDNEUE9PTCBQb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RDdWJlVGV4dHVyZSAqKnBwQ3ViZVRleHR1cmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEUgKnBTaGFyZWRIYW5kbGUsIElVbmtub3duICpwYXJlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RDQl9DUkVBVEVTVVJGQUNFRk4gRDNEQ0JfQ3JlYXRlU3VyZmFjZSkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgICAgICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RDdWJlVGV4dHVyZUltcGwgKm9iamVjdDsgLyoqIE5PVEU6IGltcGwgcmVmIGFsbG93ZWQgc2luY2UgdGhpcyBpcyBhIGNyZWF0ZSBmdW5jdGlvbiAqKi8KICAgIHVuc2lnbmVkIGludCAgICAgICAgICAgICBpLCBqOwogICAgVUlOVCAgICAgICAgICAgICAgICAgICAgIHRtcFc7CiAgICBIUkVTVUxUICAgICAgICAgICAgICAgICAgaHI7CiAgICB1bnNpZ25lZCBpbnQgcG93MkVkZ2VMZW5ndGggID0gRWRnZUxlbmd0aDsKICAgIGNvbnN0IEdsUGl4ZWxGb3JtYXREZXNjICpnbERlc2M7CiAgICBnZXRGb3JtYXREZXNjRW50cnkoRm9ybWF0LCAmR0xJTkZPX0xPQ0FUSU9OLCAmZ2xEZXNjKTsKCiAgICAvKiBUT0RPOiBJdCBzaG91bGQgb25seSBiZSBwb3NzaWJsZSB0byBjcmVhdGUgdGV4dHVyZXMgZm9yIGZvcm1hdHMgCiAgICAgICAgICAgICB0aGF0IGFyZSByZXBvcnRlZCBhcyBzdXBwb3J0ZWQgKi8KICAgIGlmIChXSU5FRDNERk1UX1VOS05PV04gPj0gRm9ybWF0KSB7CiAgICAgICAgV0FSTigiKCVwKSA6IFRleHR1cmUgY2Fubm90IGJlIGNyZWF0ZWQgd2l0aCBhIGZvcm1hdCBvZiBXSU5FRDNERk1UX1VOS05PV05cbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmICghR0xfU1VQUE9SVChBUkJfVEVYVFVSRV9DVUJFX01BUCkgJiYgUG9vbCAhPSBXSU5FRDNEUE9PTF9TQ1JBVENIKSB7CiAgICAgICAgV0FSTigiKCVwKSA6IFRyaWVkIHRvIGNyZWF0ZSBub3Qgc3VwcG9ydGVkIGN1YmUgdGV4dHVyZVxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgRDNEQ1JFQVRFUkVTT1VSQ0VPQkpFQ1RJTlNUQU5DRShvYmplY3QsIEN1YmVUZXh0dXJlLCBXSU5FRDNEUlRZUEVfQ1VCRVRFWFRVUkUsIDApOwogICAgRDNESU5JVElBTElaRUJBU0VURVhUVVJFKG9iamVjdC0+YmFzZVRleHR1cmUpOwoKICAgIFRSQUNFKCIoJXApIENyZWF0ZSBDdWJlIFRleHR1cmVcbiIsIFRoaXMpOwoKICAgIC8qKiBOb24tcG93ZXIyIHN1cHBvcnQgKiovCgogICAgLyogRmluZCB0aGUgbmVhcmVzdCBwb3cyIG1hdGNoICovCiAgICBwb3cyRWRnZUxlbmd0aCA9IDE7CiAgICB3aGlsZSAocG93MkVkZ2VMZW5ndGggPCBFZGdlTGVuZ3RoKSBwb3cyRWRnZUxlbmd0aCA8PD0gMTsKCiAgICBvYmplY3QtPmVkZ2VMZW5ndGggICAgICAgICAgID0gRWRnZUxlbmd0aDsKICAgIC8qIFRPRE86IHN1cHBvcnQgZm9yIG5hdGl2ZSBub24tcG93ZXIgMiAqLwogICAgLyogUHJlY2FsY3VsYXRlZCBzY2FsaW5nIGZvciAnZmFrZWQnIG5vbiBwb3dlciBvZiB0d28gdGV4dHVyZSBjb29yZHMgKi8KICAgIG9iamVjdC0+YmFzZVRleHR1cmUucG93Mk1hdHJpeFsgMF0gPSAoKGZsb2F0KUVkZ2VMZW5ndGgpIC8gKChmbG9hdClwb3cyRWRnZUxlbmd0aCk7CiAgICBvYmplY3QtPmJhc2VUZXh0dXJlLnBvdzJNYXRyaXhbIDVdID0gKChmbG9hdClFZGdlTGVuZ3RoKSAvICgoZmxvYXQpcG93MkVkZ2VMZW5ndGgpOwogICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5wb3cyTWF0cml4WzEwXSA9ICgoZmxvYXQpRWRnZUxlbmd0aCkgLyAoKGZsb2F0KXBvdzJFZGdlTGVuZ3RoKTsKICAgIG9iamVjdC0+YmFzZVRleHR1cmUucG93Mk1hdHJpeFsxNV0gPSAxLjA7CgogICAgLyogQ2FsY3VsYXRlIGxldmVscyBmb3IgbWlwIG1hcHBpbmcgKi8KICAgIGlmIChVc2FnZSAmIFdJTkVEM0RVU0FHRV9BVVRPR0VOTUlQTUFQKSB7CiAgICAgICAgaWYoIUdMX1NVUFBPUlQoU0dJU19HRU5FUkFURV9NSVBNQVApKSB7CiAgICAgICAgICAgIFdBUk4oIk5vIG1pcG1hcCBnZW5lcmF0aW9uIHN1cHBvcnQsIHJldHVybmluZyBEM0RFUlJfSU5WQUxJRENBTExcbiIpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvYmplY3QpOwogICAgICAgICAgICAqcHBDdWJlVGV4dHVyZSA9IE5VTEw7CgogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICB9CiAgICAgICAgaWYoTGV2ZWxzID4gMSkgewogICAgICAgICAgICBXQVJOKCJEM0RVU0FHRV9BVVRPR0VOTUlQTUFQIGlzIHNldCwgYW5kIGxldmVsIGNvdW50ID4gMSwgcmV0dXJuaW5nIEQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9iamVjdCk7CiAgICAgICAgICAgICpwcEN1YmVUZXh0dXJlID0gTlVMTDsKCiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgIH0KICAgICAgICBMZXZlbHMgPSAxOwogICAgfSBlbHNlIGlmIChMZXZlbHMgPT0gMCkgewogICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzKys7CiAgICAgICAgdG1wVyA9IEVkZ2VMZW5ndGg7CiAgICAgICAgd2hpbGUgKHRtcFcgPiAxKSB7CiAgICAgICAgICAgIHRtcFcgPSBtYXgoMSwgdG1wVyA+PiAxKTsKICAgICAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5sZXZlbHMrKzsKICAgICAgICB9CiAgICAgICAgVFJBQ0UoIkNhbGN1bGF0ZWQgbGV2ZWxzID0gJWRcbiIsIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzKTsKICAgIH0KCiAgICAvKiBHZW5lcmF0ZSBhbGwgdGhlIHN1cmZhY2VzICovCiAgICB0bXBXID0gRWRnZUxlbmd0aDsKICAgIGZvciAoaSA9IDA7IGkgPCBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVsczsgaSsrKSB7CgogICAgICAgIC8qIENyZWF0ZSB0aGUgNiBmYWNlcyAqLwogICAgICAgIGZvciAoaiA9IDA7IGogPCA2OyBqKyspIHsKCiAgICAgICAgICAgIGhyPUQzRENCX0NyZWF0ZVN1cmZhY2UoVGhpcy0+cGFyZW50LCBwYXJlbnQsIHRtcFcsIHRtcFcsIEZvcm1hdCwgVXNhZ2UsIFBvb2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaSAvKiBMZXZlbCAqLywgaiwgJm9iamVjdC0+c3VyZmFjZXNbal1baV0scFNoYXJlZEhhbmRsZSk7CgogICAgICAgICAgICBpZihociE9IFdJTkVEM0RfT0spIHsKICAgICAgICAgICAgICAgIC8qIGNsZWFuIHVwICovCiAgICAgICAgICAgICAgICBpbnQgazsKICAgICAgICAgICAgICAgIGludCBsOwogICAgICAgICAgICAgICAgZm9yIChsID0gMDsgbCA8IGo7IGwrKykgewogICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKG9iamVjdC0+c3VyZmFjZXNbbF1baV0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZm9yIChrID0gMDsgayA8IGk7IGsrKykgewogICAgICAgICAgICAgICAgICAgIGZvciAobCA9IDA7IGwgPCA2OyBsKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2Uob2JqZWN0LT5zdXJmYWNlc1tsXVtrXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEZJWE1FKCIoJXApIEZhaWxlZCB0byBjcmVhdGUgc3VyZmFjZVxuIixvYmplY3QpOwogICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLG9iamVjdCk7CiAgICAgICAgICAgICAgICAqcHBDdWJlVGV4dHVyZSA9IE5VTEw7CiAgICAgICAgICAgICAgICByZXR1cm4gaHI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbnRhaW5lcihvYmplY3QtPnN1cmZhY2VzW2pdW2ldLCAoSVdpbmVEM0RCYXNlICopb2JqZWN0KTsKICAgICAgICAgICAgVFJBQ0UoIkNyZWF0ZWQgc3VyZmFjZSBsZXZlbCAlZCBAICVwLFxuIiwgaSwgb2JqZWN0LT5zdXJmYWNlc1tqXVtpXSk7CiAgICAgICAgfQogICAgICAgIHRtcFcgPSBtYXgoMSwgdG1wVyA+PiAxKTsKICAgIH0KICAgIG9iamVjdC0+YmFzZVRleHR1cmUuc2hhZGVyX2NvbnZlcnNpb25fZ3JvdXAgPSBnbERlc2MtPmNvbnZlcnNpb25fZ3JvdXA7CgogICAgVFJBQ0UoIiglcCkgOiBDcmVhdGVkIEN1YmUgVGV4dHVyZSAlcFxuIiwgVGhpcywgb2JqZWN0KTsKICAgICpwcEN1YmVUZXh0dXJlID0gKElXaW5lRDNEQ3ViZVRleHR1cmUgKikgb2JqZWN0OwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlUXVlcnkoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEUVVFUllUWVBFIFR5cGUsIElXaW5lRDNEUXVlcnkgKipwcFF1ZXJ5LCBJVW5rbm93biogcGFyZW50KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFF1ZXJ5SW1wbCAqb2JqZWN0OyAvKk5PVEU6IGltcGwgcmVmIGFsbG93ZWQgc2luY2UgdGhpcyBpcyBhIGNyZWF0ZSBmdW5jdGlvbiAqLwogICAgSFJFU1VMVCBociA9IFdJTkVEM0RFUlJfTk9UQVZBSUxBQkxFOwoKICAgIC8qIEp1c3QgYSBjaGVjayB0byBzZWUgaWYgd2Ugc3VwcG9ydCB0aGlzIHR5cGUgb2YgcXVlcnkgKi8KICAgIHN3aXRjaChUeXBlKSB7CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfT0NDTFVTSU9OOgogICAgICAgIFRSQUNFKCIoJXApIG9jY2x1c2lvbiBxdWVyeVxuIiwgVGhpcyk7CiAgICAgICAgaWYgKEdMX1NVUFBPUlQoQVJCX09DQ0xVU0lPTl9RVUVSWSkpCiAgICAgICAgICAgIGhyID0gV0lORUQzRF9PSzsKICAgICAgICBlbHNlCiAgICAgICAgICAgIFdBUk4oIlVuc3VwcG9ydGVkIGluIGxvY2FsIE9wZW5HTCBpbXBsZW1lbnRhdGlvbjogQVJCX09DQ0xVU0lPTl9RVUVSWS9OVl9PQ0NMVVNJT05fUVVFUllcbiIpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9FVkVOVDoKICAgICAgICBpZighKEdMX1NVUFBPUlQoTlZfRkVOQ0UpIHx8IEdMX1NVUFBPUlQoQVBQTEVfRkVOQ0UpICkpIHsKICAgICAgICAgICAgLyogSGFsZi1MaWZlIDIgbmVlZHMgdGhpcyBxdWVyeS4gSXQgZG9lcyBub3QgcmVuZGVyIHRoZSBtYWluIG1lbnUgY29ycmVjdGx5IG90aGVyd2lzZQogICAgICAgICAgICAgKiBQcmV0ZW5kIHRvIHN1cHBvcnQgaXQsIGZha2luZyB0aGlzIHF1ZXJ5IGRvZXMgbm90IGRvIG11Y2ggaGFybSBleGNlcHQgcG90ZW50aWFsbHkgbG93ZXJpbmcgcGVyZm9ybWFuY2UKICAgICAgICAgICAgICovCiAgICAgICAgICAgIEZJWE1FKCIoJXApIEV2ZW50IHF1ZXJ5OiBVbmltcGxlbWVudGVkLCBidXQgcHJldGVuZGluZyB0byBiZSBzdXBwb3J0ZWRcbiIsIFRoaXMpOwogICAgICAgIH0KICAgICAgICBociA9IFdJTkVEM0RfT0s7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1ZDQUNIRToKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9SRVNPVVJDRU1BTkFHRVI6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfVkVSVEVYU1RBVFM6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfVElNRVNUQU1QOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1RJTUVTVEFNUERJU0pPSU5UOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1RJTUVTVEFNUEZSRVE6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfUElQRUxJTkVUSU1JTkdTOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX0lOVEVSRkFDRVRJTUlOR1M6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfVkVSVEVYVElNSU5HUzoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9QSVhFTFRJTUlOR1M6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfQkFORFdJRFRIVElNSU5HUzoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9DQUNIRVVUSUxJWkFUSU9OOgogICAgZGVmYXVsdDoKICAgICAgICBGSVhNRSgiKCVwKSBVbmhhbmRsZWQgcXVlcnkgdHlwZSAlZFxuIiwgVGhpcywgVHlwZSk7CiAgICB9CiAgICBpZihOVUxMID09IHBwUXVlcnkgfHwgaHIgIT0gV0lORUQzRF9PSykgewogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICBEM0RDUkVBVEVPQkpFQ1RJTlNUQU5DRShvYmplY3QsIFF1ZXJ5KQogICAgb2JqZWN0LT50eXBlICAgICAgICAgPSBUeXBlOwogICAgb2JqZWN0LT5zdGF0ZSAgICAgICAgPSBRVUVSWV9DUkVBVEVEOwogICAgLyogYWxsb2NhdGVkIHRoZSAnZXh0ZW5kZWQnIGRhdGEgYmFzZWQgb24gdGhlIHR5cGUgb2YgcXVlcnkgcmVxdWVzdGVkICovCiAgICBzd2l0Y2goVHlwZSl7CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfT0NDTFVTSU9OOgogICAgICAgIG9iamVjdC0+ZXh0ZW5kZWREYXRhID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihXaW5lUXVlcnlPY2NsdXNpb25EYXRhKSk7CiAgICAgICAgKChXaW5lUXVlcnlPY2NsdXNpb25EYXRhICopKG9iamVjdC0+ZXh0ZW5kZWREYXRhKSktPmN0eCA9IFRoaXMtPmFjdGl2ZUNvbnRleHQ7CgogICAgICAgIGlmKEdMX1NVUFBPUlQoQVJCX09DQ0xVU0lPTl9RVUVSWSkpIHsKICAgICAgICAgICAgVFJBQ0UoIiglcCkgQWxsb2NhdGluZyBkYXRhIGZvciBhbiBvY2NsdXNpb24gcXVlcnlcbiIsIFRoaXMpOwogICAgICAgICAgICBHTF9FWFRDQUxMKGdsR2VuUXVlcmllc0FSQigxLCAmKChXaW5lUXVlcnlPY2NsdXNpb25EYXRhICopKG9iamVjdC0+ZXh0ZW5kZWREYXRhKSktPnF1ZXJ5SWQpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX0VWRU5UOgogICAgICAgIG9iamVjdC0+ZXh0ZW5kZWREYXRhID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihXaW5lUXVlcnlFdmVudERhdGEpKTsKICAgICAgICAoKFdpbmVRdWVyeUV2ZW50RGF0YSAqKShvYmplY3QtPmV4dGVuZGVkRGF0YSkpLT5jdHggPSBUaGlzLT5hY3RpdmVDb250ZXh0OwoKICAgICAgICBpZihHTF9TVVBQT1JUKEFQUExFX0ZFTkNFKSkgewogICAgICAgICAgICBHTF9FWFRDQUxMKGdsR2VuRmVuY2VzQVBQTEUoMSwgJigoV2luZVF1ZXJ5RXZlbnREYXRhICopKG9iamVjdC0+ZXh0ZW5kZWREYXRhKSktPmZlbmNlSWQpKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsR2VuRmVuY2VzQVBQTEUiKTsKICAgICAgICB9IGVsc2UgaWYoR0xfU1VQUE9SVChOVl9GRU5DRSkpIHsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEdlbkZlbmNlc05WKDEsICYoKFdpbmVRdWVyeUV2ZW50RGF0YSAqKShvYmplY3QtPmV4dGVuZGVkRGF0YSkpLT5mZW5jZUlkKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEdlbkZlbmNlc05WIik7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9WQ0FDSEU6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfUkVTT1VSQ0VNQU5BR0VSOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1ZFUlRFWFNUQVRTOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1RJTUVTVEFNUDoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9USU1FU1RBTVBESVNKT0lOVDoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9USU1FU1RBTVBGUkVROgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1BJUEVMSU5FVElNSU5HUzoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9JTlRFUkZBQ0VUSU1JTkdTOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1ZFUlRFWFRJTUlOR1M6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfUElYRUxUSU1JTkdTOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX0JBTkRXSURUSFRJTUlOR1M6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfQ0FDSEVVVElMSVpBVElPTjoKICAgIGRlZmF1bHQ6CiAgICAgICAgb2JqZWN0LT5leHRlbmRlZERhdGEgPSAwOwogICAgICAgIEZJWE1FKCIoJXApIFVuaGFuZGxlZCBxdWVyeSB0eXBlICVkXG4iLFRoaXMgLCBUeXBlKTsKICAgIH0KICAgIFRSQUNFKCIoJXApIDogQ3JlYXRlZCBRdWVyeSAlcFxuIiwgVGhpcywgb2JqZWN0KTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0REZXZpY2VJbXBsX1NldHVwRnVsbHNjcmVlbldpbmRvdwogKgogKiBIZWxwZXIgZnVuY3Rpb24gdGhhdCBtb2RpZmllcyBhIEhXTkQncyBTdHlsZSBhbmQgRXhTdHlsZSBmb3IgcHJvcGVyCiAqIGZ1bGxzY3JlZW4gdXNlLgogKgogKiBQYXJhbXM6CiAqICBpZmFjZTogUG9pbnRlciB0byB0aGUgSVdpbmVEM0REZXZpY2UgaW50ZXJmYWNlCiAqICB3aW5kb3c6IFdpbmRvdyB0byBzZXR1cAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyB2b2lkIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0dXBGdWxsc2NyZWVuV2luZG93KElXaW5lRDNERGV2aWNlICppZmFjZSwgSFdORCB3aW5kb3cpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBMT05HIHN0eWxlLCBleFN0eWxlOwogICAgLyogRG9uJ3QgZG8gYW55dGhpbmcgaWYgYW4gb3JpZ2luYWwgc3R5bGUgaXMgc3RvcmVkLgogICAgICogVGhhdCBzaG91bGRuJ3QgaGFwcGVuCiAgICAgKi8KICAgIFRSQUNFKCIoJXApOiBTZXR0aW5nIHVwIHdpbmRvdyAlcCBmb3IgZXhjbHVzaXZlIG1vZGVcbiIsIFRoaXMsIHdpbmRvdyk7CiAgICBpZiAoVGhpcy0+c3R5bGUgfHwgVGhpcy0+ZXhTdHlsZSkgewogICAgICAgIEVSUigiKCVwKTogV2FudCB0byBjaGFuZ2UgdGhlIHdpbmRvdyBwYXJhbWV0ZXJzIG9mIEhXTkQgJXAsIGJ1dCAiCiAgICAgICAgICAgICJhbm90aGVyIHN0eWxlIGlzIHN0b3JlZCBmb3IgcmVzdG9yYXRpb24gYWZ0ZXJ3YXJkc1xuIiwgVGhpcywgd2luZG93KTsKICAgIH0KCiAgICAvKiBHZXQgdGhlIHBhcmFtZXRlcnMgYW5kIHNhdmUgdGhlbSAqLwogICAgc3R5bGUgPSBHZXRXaW5kb3dMb25nVyh3aW5kb3csIEdXTF9TVFlMRSk7CiAgICBleFN0eWxlID0gR2V0V2luZG93TG9uZ1cod2luZG93LCBHV0xfRVhTVFlMRSk7CiAgICBUaGlzLT5zdHlsZSA9IHN0eWxlOwogICAgVGhpcy0+ZXhTdHlsZSA9IGV4U3R5bGU7CgogICAgLyogRmlsdGVyIG91dCB3aW5kb3cgZGVjb3JhdGlvbnMgKi8KICAgIHN0eWxlICY9IH5XU19DQVBUSU9OOwogICAgc3R5bGUgJj0gfldTX1RISUNLRlJBTUU7CiAgICBleFN0eWxlICY9IH5XU19FWF9XSU5ET1dFREdFOwogICAgZXhTdHlsZSAmPSB+V1NfRVhfQ0xJRU5URURHRTsKCiAgICAvKiBNYWtlIHN1cmUgdGhlIHdpbmRvdyBpcyBtYW5hZ2VkLCBvdGhlcndpc2Ugd2Ugd29uJ3QgZ2V0IGtleWJvYXJkIGlucHV0ICovCiAgICBzdHlsZSB8PSBXU19QT1BVUCB8IFdTX1NZU01FTlU7CgogICAgVFJBQ0UoIk9sZCBzdHlsZSB3YXMgJTA4eCwlMDh4LCBzZXR0aW5nIHRvICUwOHgsJTA4eFxuIiwKICAgICAgICAgIFRoaXMtPnN0eWxlLCBUaGlzLT5leFN0eWxlLCBzdHlsZSwgZXhTdHlsZSk7CgogICAgU2V0V2luZG93TG9uZ1cod2luZG93LCBHV0xfU1RZTEUsIHN0eWxlKTsKICAgIFNldFdpbmRvd0xvbmdXKHdpbmRvdywgR1dMX0VYU1RZTEUsIGV4U3R5bGUpOwoKICAgIC8qIEluZm9ybSB0aGUgd2luZG93IGFib3V0IHRoZSB1cGRhdGUuICovCiAgICBTZXRXaW5kb3dQb3Mod2luZG93LCBIV05EX1RPUCwgMCwgMCwKICAgICAgICAgICAgVGhpcy0+ZGRyYXdfd2lkdGgsIFRoaXMtPmRkcmF3X2hlaWdodCwgU1dQX0ZSQU1FQ0hBTkdFRCk7CiAgICBTaG93V2luZG93KHdpbmRvdywgU1dfTk9STUFMKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElXaW5lRDNERGV2aWNlSW1wbF9SZXN0b3JlV2luZG93CiAqCiAqIEhlbHBlciBmdW5jdGlvbiB0aGF0IHJlc3RvcmVzIGEgd2luZG93cycgcHJvcGVydGllcyB3aGVuIHRha2luZyBpdCBvdXQKICogb2YgZnVsbHNjcmVlbiBtb2RlCiAqCiAqIFBhcmFtczoKICogIGlmYWNlOiBQb2ludGVyIHRvIHRoZSBJV2luZUQzRERldmljZSBpbnRlcmZhY2UKICogIHdpbmRvdzogV2luZG93IHRvIHNldHVwCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIHZvaWQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9SZXN0b3JlV2luZG93KElXaW5lRDNERGV2aWNlICppZmFjZSwgSFdORCB3aW5kb3cpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICAvKiBUaGlzIGNvdWxkIGJlIGEgRERTQ0xfTk9STUFMIC0+IEREU0NMX05PUk1BTAogICAgICogc3dpdGNoLCBkbyBub3RoaW5nCiAgICAgKi8KICAgIGlmICghVGhpcy0+c3R5bGUgJiYgIVRoaXMtPmV4U3R5bGUpIHJldHVybjsKCiAgICBUUkFDRSgiKCVwKTogUmVzdG9yaW5nIHdpbmRvdyBzZXR0aW5ncyBvZiB3aW5kb3cgJXAgdG8gJTA4eCwgJTA4eFxuIiwKICAgICAgICAgIFRoaXMsIHdpbmRvdywgVGhpcy0+c3R5bGUsIFRoaXMtPmV4U3R5bGUpOwoKICAgIFNldFdpbmRvd0xvbmdXKHdpbmRvdywgR1dMX1NUWUxFLCBUaGlzLT5zdHlsZSk7CiAgICBTZXRXaW5kb3dMb25nVyh3aW5kb3csIEdXTF9FWFNUWUxFLCBUaGlzLT5leFN0eWxlKTsKCiAgICAvKiBEZWxldGUgdGhlIG9sZCB2YWx1ZXMgKi8KICAgIFRoaXMtPnN0eWxlID0gMDsKICAgIFRoaXMtPmV4U3R5bGUgPSAwOwoKICAgIC8qIEluZm9ybSB0aGUgd2luZG93IGFib3V0IHRoZSB1cGRhdGUgKi8KICAgIFNldFdpbmRvd1Bvcyh3aW5kb3csIDAgLyogSW5zZXJ0QWZ0ZXIsIGlnbm9yZWQgKi8sCiAgICAgICAgICAgICAgICAgMCwgMCwgMCwgMCwgLyogUG9zLCBTaXplLCBpZ25vcmVkICovCiAgICAgICAgICAgICAgICAgU1dQX0ZSQU1FQ0hBTkdFRCB8IFNXUF9OT01PVkUgfCBTV1BfTk9TSVpFIHwgU1dQX05PWk9SREVSKTsKfQoKLyogZXhhbXBsZSBhdCBodHRwOi8vd3d3LmZhaXJ5ZW5naW5lLmNvbS9hcnRpY2xlcy9keG11bHRpdmlld3MuaHRtICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlQWRkaXRpb25hbFN3YXBDaGFpbihJV2luZUQzRERldmljZSogaWZhY2UsIFdJTkVEM0RQUkVTRU5UX1BBUkFNRVRFUlMqICBwUHJlc2VudGF0aW9uUGFyYW1ldGVycywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW4qKiBwcFN3YXBDaGFpbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVVua25vd24qIHBhcmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEQ0JfQ1JFQVRFUkVOREVSVEFSR0VURk4gRDNEQ0JfQ3JlYXRlUmVuZGVyVGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RDQl9DUkVBVEVERVBUSFNURU5DSUxTVVJGQUNFRk4gRDNEQ0JfQ3JlYXRlRGVwdGhTdGVuY2lsKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgICAgICAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBIREMgICAgICAgICAgICAgICAgICAgICBoRGM7CiAgICBJV2luZUQzRFN3YXBDaGFpbkltcGwgICpvYmplY3Q7IC8qKiBOT1RFOiBpbXBsIHJlZiBhbGxvd2VkIHNpbmNlIHRoaXMgaXMgYSBjcmVhdGUgZnVuY3Rpb24gKiovCiAgICBIUkVTVUxUICAgICAgICAgICAgICAgICBociA9IFdJTkVEM0RfT0s7CiAgICBJVW5rbm93biAgICAgICAgICAgICAgICpidWZmZXJQYXJlbnQ7CiAgICBCT09MICAgICAgICAgICAgICAgICAgICBkaXNwbGF5bW9kZV9zZXQgPSBGQUxTRTsKICAgIFdJTkVEM0RESVNQTEFZTU9ERSAgICAgIE1vZGU7CiAgICBjb25zdCBTdGF0aWNQaXhlbEZvcm1hdERlc2MgKmZvcm1hdERlc2M7CgogICAgVFJBQ0UoIiglcCkgOiBDcmVhdGVkIEFkaXRpb25hbCBTd2FwIENoYWluXG4iLCBUaGlzKTsKCiAgIC8qKiBGSVhNRTogVGVzdCB1bmRlciB3aW5kb3dzIHRvIGZpbmQgb3V0IHdoYXQgdGhlIGxpZmUgY3ljbGUgb2YgYSBzd2FwIGNoYWluIGlzLAogICAqIGRvZXMgYSBkZXZpY2UgaG9sZCBhIHJlZmVyZW5jZSB0byBhIHN3YXAgY2hhaW4gZ2l2aW5nIHRoZW0gYSBsaWZldGltZSBvZiB0aGUgZGV2aWNlCiAgICogb3IgZG9lcyB0aGUgc3dhcCBjaGFpbiBub3RpZnkgdGhlIGRldmljZSBvZiBpdHMgZGVzdHJ1Y3Rpb24uCiAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qIENoZWNrIHRoZSBwYXJhbXMgKi8KICAgIGlmKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyQ291bnQgPiBXSU5FRDNEUFJFU0VOVF9CQUNLX0JVRkZFUl9NQVgpIHsKICAgICAgICBFUlIoIkFwcCByZXF1ZXN0ZWQgJWQgYmFjayBidWZmZXJzLCB0aGlzIGlzIG5vdCBzdXBwb3J0ZWQgZm9yIG5vd1xuIiwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJDb3VudCk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9IGVsc2UgaWYgKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyQ291bnQgPiAxKSB7CiAgICAgICAgRklYTUUoIlRoZSBhcHAgcmVxdWVzdHMgbW9yZSB0aGFuIG9uZSBiYWNrIGJ1ZmZlciwgdGhpcyBjYW4ndCBiZSBzdXBwb3J0ZWQgcHJvcGVybHkuIFBsZWFzZSBjb25maWd1cmUgdGhlIGFwcGxpY2F0aW9uIHRvIHVzZSBkb3VibGUgYnVmZmVyaW5nKD0xIGJhY2sgYnVmZmVyKSBpZiBwb3NzaWJsZVxuIik7CiAgICB9CgogICAgRDNEQ1JFQVRFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBTd2FwQ2hhaW4pCgogICAgLyoqKioqKioqKioqKioqKioqKioqKgogICAgKiBMb29rdXAgdGhlIHdpbmRvdyBIYW5kbGUgYW5kIHRoZSByZWxhdGluZyBYIHdpbmRvdyBoYW5kbGUKICAgICoqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qIFNldHVwIGh3bmQgd2UgYXJlIHVzaW5nLCBwbHVzIHdoaWNoIGRpc3BsYXkgdGhpcyBlcXVhdGVzIHRvICovCiAgICBvYmplY3QtPndpbl9oYW5kbGUgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+aERldmljZVdpbmRvdzsKICAgIGlmICghb2JqZWN0LT53aW5faGFuZGxlKSB7CiAgICAgICAgb2JqZWN0LT53aW5faGFuZGxlID0gVGhpcy0+Y3JlYXRlUGFybXMuaEZvY3VzV2luZG93OwogICAgfQogICAgaWYoIVRoaXMtPmRkcmF3X3dpbmRvdykgSVdpbmVEM0REZXZpY2VfU2V0SFdORChpZmFjZSwgb2JqZWN0LT53aW5faGFuZGxlKTsKCiAgICBoRGMgICAgICAgICAgICAgICAgPSBHZXREQyhvYmplY3QtPndpbl9oYW5kbGUpOwogICAgVFJBQ0UoIlVzaW5nIGhEYyAlcFxuIiwgaERjKTsKCiAgICBpZiAoTlVMTCA9PSBoRGMpIHsKICAgICAgICBXQVJOKCJGYWlsZWQgdG8gZ2V0IGEgSERjIGZvciBXaW5kb3cgJXBcbiIsIG9iamVjdC0+d2luX2hhbmRsZSk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfTk9UQVZBSUxBQkxFOwogICAgfQoKICAgIC8qIEdldCBpbmZvIG9uIHRoZSBjdXJyZW50IGRpc3BsYXkgc2V0dXAgKi8KICAgIElXaW5lRDNEX0dldEFkYXB0ZXJEaXNwbGF5TW9kZShUaGlzLT53aW5lRDNELCBUaGlzLT5hZGFwdGVyLT5udW0sICZNb2RlKTsKICAgIG9iamVjdC0+b3JpZ193aWR0aCA9IE1vZGUuV2lkdGg7CiAgICBvYmplY3QtPm9yaWdfaGVpZ2h0ID0gTW9kZS5IZWlnaHQ7CiAgICBvYmplY3QtPm9yaWdfZm10ID0gTW9kZS5Gb3JtYXQ7CiAgICBmb3JtYXREZXNjICA9IGdldEZvcm1hdERlc2NFbnRyeShNb2RlLkZvcm1hdCwgTlVMTCwgTlVMTCk7CgogICAgLyoqIE1TRE46IElmIFdpbmRvd2VkIGlzIFRSVUUgYW5kIGVpdGhlciBvZiB0aGUgQmFja0J1ZmZlcldpZHRoL0hlaWdodCB2YWx1ZXMgaXMgemVybywKICAgICAqICB0aGVuIHRoZSBjb3JyZXNwb25kaW5nIGRpbWVuc2lvbiBvZiB0aGUgY2xpZW50IGFyZWEgb2YgdGhlIGhEZXZpY2VXaW5kb3cKICAgICAqICAob3IgdGhlIGZvY3VzIHdpbmRvdywgaWYgaERldmljZVdpbmRvdyBpcyBOVUxMKSBpcyB0YWtlbi4KICAgICAgKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICBpZiAocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPldpbmRvd2VkICYmCiAgICAgICAgKChwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoID09IDApIHx8CiAgICAgICAgIChwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodCA9PSAwKSB8fAogICAgICAgICAocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJGb3JtYXQgPT0gV0lORUQzREZNVF9VTktOT1dOKSkpIHsKCiAgICAgICAgUkVDVCBSZWN0OwogICAgICAgIEdldENsaWVudFJlY3Qob2JqZWN0LT53aW5faGFuZGxlLCAmUmVjdCk7CgogICAgICAgIGlmIChwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoID09IDApIHsKICAgICAgICAgICBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoID0gUmVjdC5yaWdodDsKICAgICAgICAgICBUUkFDRSgiVXBkYXRpbmcgd2lkdGggdG8gJWRcbiIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGgpOwogICAgICAgIH0KICAgICAgICBpZiAocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQgPT0gMCkgewogICAgICAgICAgIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0ID0gUmVjdC5ib3R0b207CiAgICAgICAgICAgVFJBQ0UoIlVwZGF0aW5nIGhlaWdodCB0byAlZFxuIiwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQpOwogICAgICAgIH0KICAgICAgICBpZiAocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJGb3JtYXQgPT0gV0lORUQzREZNVF9VTktOT1dOKSB7CiAgICAgICAgICAgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJGb3JtYXQgPSBvYmplY3QtPm9yaWdfZm10OwogICAgICAgICAgIFRSQUNFKCJVcGRhdGluZyBmb3JtYXQgdG8gJXNcbiIsIGRlYnVnX2QzZGZvcm1hdChvYmplY3QtPm9yaWdfZm10KSk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFB1dCB0aGUgY29ycmVjdCBmaWd1cmVzIGluIHRoZSBwcmVzZW50YXRpb24gcGFyYW1ldGVycyAqLwogICAgVFJBQ0UoIkNvcHlpbmcgYWNyb3NzIHByZXNlbnRhdGlvbiBwYXJhbWV0ZXJzXG4iKTsKICAgIG9iamVjdC0+cHJlc2VudFBhcm1zID0gKnBQcmVzZW50YXRpb25QYXJhbWV0ZXJzOwoKICAgIFRSQUNFKCJjYWxsaW5nIHJlbmRlcnRhcmdldCBDQlxuIik7CiAgICBociA9IEQzRENCX0NyZWF0ZVJlbmRlclRhcmdldCgoSVVua25vd24gKikgVGhpcy0+cGFyZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyRm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLk11bHRpU2FtcGxlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5NdWx0aVNhbXBsZVF1YWxpdHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSAvKiBMb2NrYWJsZSAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmb2JqZWN0LT5mcm9udEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMIC8qIHBTaGFyZWQgKGFsd2F5cyBudWxsKSovKTsKICAgIGlmIChvYmplY3QtPmZyb250QnVmZmVyICE9IE5VTEwpIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfTW9kaWZ5TG9jYXRpb24ob2JqZWN0LT5mcm9udEJ1ZmZlciwgU0ZMQUdfSU5EUkFXQUJMRSwgVFJVRSk7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbnRhaW5lcihvYmplY3QtPmZyb250QnVmZmVyLCAoSVdpbmVEM0RCYXNlICopb2JqZWN0KTsKICAgIH0gZWxzZSB7CiAgICAgICAgRVJSKCJGYWlsZWQgdG8gY3JlYXRlIHRoZSBmcm9udCBidWZmZXJcbiIpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAvKioqKioqKioqKioqKioqKioqKioqCiAgICogV2luZG93ZWQgLyBGdWxsc2NyZWVuCiAgICoqKioqKioqKioqKioqKioqKiovCgogICAvKioKICAgKiBUT0RPOiBNU0ROIHNheXMgdGhhdCB3ZSBhcmUgb25seSBhbGxvd2VkIG9uZSBmdWxsc2NyZWVuIHN3YXBjaGFpbiBwZXIgZGV2aWNlLAogICAqIHNvIHdlIHNob3VsZCByZWFsbHkgY2hlY2sgdG8gc2VlIGlmIHRoZXJlIGlzIGEgZnVsbHNjcmVlbiBzd2FwY2hhaW4gYWxyZWFkeQogICAqIEkgdGhpbmsgV2luZG93cyBhbmQgWCBoYXZlIGRpZmZlcmVudCBpZGVhcyBhYm91dCBmdWxsc2NyZWVuLCBkb2VzIGEgc2luZ2xlIGhlYWQgY291bnQgYXMgZnVsbCBzY3JlZW4/CiAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgIGlmICghcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPldpbmRvd2VkKSB7CiAgICAgICAgV0lORUQzRERJU1BMQVlNT0RFIG1vZGU7CgoKICAgICAgICAvKiBDaGFuZ2UgdGhlIGRpc3BsYXkgc2V0dGluZ3MgKi8KICAgICAgICBtb2RlLldpZHRoID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aDsKICAgICAgICBtb2RlLkhlaWdodCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0OwogICAgICAgIG1vZGUuRm9ybWF0ID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJGb3JtYXQ7CiAgICAgICAgbW9kZS5SZWZyZXNoUmF0ZSA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5GdWxsU2NyZWVuX1JlZnJlc2hSYXRlSW5IejsKCiAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0RGlzcGxheU1vZGUoaWZhY2UsIDAsICZtb2RlKTsKICAgICAgICBkaXNwbGF5bW9kZV9zZXQgPSBUUlVFOwogICAgICAgIElXaW5lRDNERGV2aWNlX1NldEZ1bGxzY3JlZW4oaWZhY2UsIFRSVUUpOwogICAgfQoKICAgICAgICAvKioKICAgICAqIENyZWF0ZSBhbiBvcGVuZ2wgY29udGV4dCBmb3IgdGhlIGRpc3BsYXkgdmlzdWFsCiAgICAgKiAgTk9URTogdGhlIHZpc3VhbCBpcyBjaG9zZW4gYXMgdGhlIHdpbmRvdyBpcyBjcmVhdGVkIGFuZCB0aGUgZ2xjb250ZXh0IGNhbm5vdAogICAgICogICAgIHVzZSBkaWZmZXJlbnQgcHJvcGVydGllcyBhZnRlciB0aGF0IHBvaW50IGluIHRpbWUuIEZJWE1FOiBIb3cgdG8gaGFuZGxlIHdoZW4gcmVxdWVzdGVkIGZvcm1hdAogICAgICogICAgIGRvZXNuJ3QgbWF0Y2ggYWN0dWFsIHZpc3VhbD8gQ2Fubm90IGNob29zZSBvbmUgaGVyZSAtIGNvZGUgcmVtb3ZlZCBhcyBpdCBPTkxZIHdvcmtzIGlmIHRoZSBvbmUKICAgICAqICAgICBpdCBjaG9vc2VzIGlzIGlkZW50aWNhbCB0byB0aGUgb25lIGFscmVhZHkgYmVpbmcgdXNlZCEKICAgICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgIC8qKiBGSVhNRTogSGFuZGxlIHN0ZW5jaWwgYXBwcm9wcmlhdGVseSB2aWEgRW5hYmxlQXV0b0RlcHRoU3RlbmNpbCAvIEF1dG9EZXB0aFN0ZW5jaWxGb3JtYXQgKiovCgogICAgb2JqZWN0LT5jb250ZXh0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihvYmplY3QtPmNvbnRleHQpKTsKICAgIGlmKCFvYmplY3QtPmNvbnRleHQpCiAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICBvYmplY3QtPm51bV9jb250ZXh0cyA9IDE7CgogICAgb2JqZWN0LT5jb250ZXh0WzBdID0gQ3JlYXRlQ29udGV4dChUaGlzLCAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBvYmplY3QtPmZyb250QnVmZmVyLCBvYmplY3QtPndpbl9oYW5kbGUsIEZBTFNFIC8qIHBidWZmZXIgKi8sIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzKTsKICAgIGlmICghb2JqZWN0LT5jb250ZXh0WzBdKSB7CiAgICAgICAgRVJSKCJGYWlsZWQgdG8gY3JlYXRlIGEgbmV3IGNvbnRleHRcbiIpOwogICAgICAgIGhyID0gV0lORUQzREVSUl9OT1RBVkFJTEFCTEU7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoIkNvbnRleHQgY3JlYXRlZCAoSFdORD0lcCwgZ2xDb250ZXh0PSVwKVxuIiwKICAgICAgICAgICAgICBvYmplY3QtPndpbl9oYW5kbGUsIG9iamVjdC0+Y29udGV4dFswXS0+Z2xDdHgpOwogICAgfQoKICAgLyoqKioqKioqKioqKioqKioqKioqKgogICAqIENyZWF0ZSB0aGUgYmFjaywgZnJvbnQgYW5kIHN0ZW5jaWwgYnVmZmVycwogICAqKioqKioqKioqKioqKioqKioqLwogICAgaWYob2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckNvdW50ID4gMCkgewogICAgICAgIGludCBpOwoKICAgICAgICBvYmplY3QtPmJhY2tCdWZmZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKElXaW5lRDNEU3VyZmFjZSAqKSAqIG9iamVjdC0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJDb3VudCk7CiAgICAgICAgaWYoIW9iamVjdC0+YmFja0J1ZmZlcikgewogICAgICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnlcbiIpOwogICAgICAgICAgICBociA9IEVfT1VUT0ZNRU1PUlk7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQoKICAgICAgICBmb3IoaSA9IDA7IGkgPCBvYmplY3QtPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyQ291bnQ7IGkrKykgewogICAgICAgICAgICBUUkFDRSgiY2FsbGluZyByZW5kZXJ0YXJnZXQgQ0JcbiIpOwogICAgICAgICAgICBociA9IEQzRENCX0NyZWF0ZVJlbmRlclRhcmdldCgoSVVua25vd24gKikgVGhpcy0+cGFyZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuTXVsdGlTYW1wbGVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5NdWx0aVNhbXBsZVF1YWxpdHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgLyogTG9ja2FibGUgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZvYmplY3QtPmJhY2tCdWZmZXJbaV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwgLyogcFNoYXJlZCAoYWx3YXlzIG51bGwpKi8pOwogICAgICAgICAgICBpZihociA9PSBXSU5FRDNEX09LICYmIG9iamVjdC0+YmFja0J1ZmZlcltpXSkgewogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbnRhaW5lcihvYmplY3QtPmJhY2tCdWZmZXJbaV0sIChJV2luZUQzREJhc2UgKilvYmplY3QpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgRVJSKCJDYW5ub3QgY3JlYXRlIG5ldyBiYWNrIGJ1ZmZlclxuIik7CiAgICAgICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcihHTF9CQUNLKSIpOwogICAgICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgb2JqZWN0LT5iYWNrQnVmZmVyID0gTlVMTDsKCiAgICAgICAgLyogU2luZ2xlIGJ1ZmZlcmluZyAtIGRyYXcgdG8gZnJvbnQgYnVmZmVyICovCiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICBnbERyYXdCdWZmZXIoR0xfRlJPTlQpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoR0xfRlJPTlQpIik7CiAgICAgICAgTEVBVkVfR0woKTsKICAgIH0KCiAgICAvKiBVbmRlciBkaXJlY3RYIHN3YXBjaGFpbnMgc2hhcmUgdGhlIGRlcHRoIHN0ZW5jaWwsIHNvIG9ubHkgY3JlYXRlIG9uZSBkZXB0aC1zdGVuY2lsICovCiAgICBpZiAocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkVuYWJsZUF1dG9EZXB0aFN0ZW5jaWwgJiYgaHIgPT0gV0lORUQzRF9PSykgewogICAgICAgIFRSQUNFKCJDcmVhdGluZyBkZXB0aCBzdGVuY2lsIGJ1ZmZlclxuIik7CiAgICAgICAgaWYgKFRoaXMtPmF1dG9fZGVwdGhfc3RlbmNpbF9idWZmZXIgPT0gTlVMTCApIHsKICAgICAgICAgICAgaHIgPSBEM0RDQl9DcmVhdGVEZXB0aFN0ZW5jaWwoKElVbmtub3duICopIFRoaXMtPnBhcmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJIZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLkF1dG9EZXB0aFN0ZW5jaWxGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLk11bHRpU2FtcGxlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuTXVsdGlTYW1wbGVRdWFsaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQUxTRSAvKiBGSVhNRTogRGlzY2FyZCAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlRoaXMtPmF1dG9fZGVwdGhfc3RlbmNpbF9idWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwgLyogcFNoYXJlZCAoYWx3YXlzIG51bGwpKi8gICk7CiAgICAgICAgICAgIGlmIChUaGlzLT5hdXRvX2RlcHRoX3N0ZW5jaWxfYnVmZmVyICE9IE5VTEwpCiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29udGFpbmVyKFRoaXMtPmF1dG9fZGVwdGhfc3RlbmNpbF9idWZmZXIsIDApOwogICAgICAgIH0KCiAgICAgICAgLyoqIFRPRE86IEEgY2hlY2sgb24gd2lkdGgsIGhlaWdodCBhbmQgbXVsdGlzYW1wbGUgdHlwZXMKICAgICAgICAqKHNpbmNlIHRoZSB6YnVmZmVyIG11c3QgYmUgYXQgbGVhc3QgYXMgbGFyZ2UgYXMgdGhlIHJlbmRlciB0YXJnZXQgYW5kIGhhdmUgdGhlIHNhbWUgbXVsdGlzYW1wbGUgcGFyYW1ldGVycykKICAgICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgICAgICBvYmplY3QtPndhbnRzRGVwdGhTdGVuY2lsQnVmZmVyID0gVFJVRTsKICAgIH0gZWxzZSB7CiAgICAgICAgb2JqZWN0LT53YW50c0RlcHRoU3RlbmNpbEJ1ZmZlciA9IEZBTFNFOwogICAgfQoKICAgIFRSQUNFKCJDcmVhdGVkIHN3YXBjaGFpbiAlcFxuIiwgb2JqZWN0KTsKICAgIFRSQUNFKCJGcm9udEJ1ZiBAICVwLCBCYWNrQnVmIEAgJXAsIERlcHRoU3RlbmNpbCAlZFxuIixvYmplY3QtPmZyb250QnVmZmVyLCBvYmplY3QtPmJhY2tCdWZmZXIgPyBvYmplY3QtPmJhY2tCdWZmZXJbMF0gOiBOVUxMLCBvYmplY3QtPndhbnRzRGVwdGhTdGVuY2lsQnVmZmVyKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwoKZXJyb3I6CiAgICBpZiAoZGlzcGxheW1vZGVfc2V0KSB7CiAgICAgICAgREVWTU9ERVcgZGV2bW9kZTsKICAgICAgICBSRUNUICAgICBjbGlwX3JjOwoKICAgICAgICBTZXRSZWN0KCZjbGlwX3JjLCAwLCAwLCBvYmplY3QtPm9yaWdfd2lkdGgsIG9iamVjdC0+b3JpZ19oZWlnaHQpOwogICAgICAgIENsaXBDdXJzb3IoTlVMTCk7CgogICAgICAgIC8qIENoYW5nZSB0aGUgZGlzcGxheSBzZXR0aW5ncyAqLwogICAgICAgIG1lbXNldCgmZGV2bW9kZSwgMCwgc2l6ZW9mKGRldm1vZGUpKTsKICAgICAgICBkZXZtb2RlLmRtU2l6ZSAgICAgICA9IHNpemVvZihkZXZtb2RlKTsKICAgICAgICBkZXZtb2RlLmRtRmllbGRzICAgICA9IERNX0JJVFNQRVJQRUwgfCBETV9QRUxTV0lEVEggfCBETV9QRUxTSEVJR0hUOwogICAgICAgIGRldm1vZGUuZG1CaXRzUGVyUGVsID0gZm9ybWF0RGVzYy0+YnBwICogODsKICAgICAgICBkZXZtb2RlLmRtUGVsc1dpZHRoICA9IG9iamVjdC0+b3JpZ193aWR0aDsKICAgICAgICBkZXZtb2RlLmRtUGVsc0hlaWdodCA9IG9iamVjdC0+b3JpZ19oZWlnaHQ7CiAgICAgICAgQ2hhbmdlRGlzcGxheVNldHRpbmdzRXhXKFRoaXMtPmFkYXB0ZXItPkRldmljZU5hbWUsICZkZXZtb2RlLCBOVUxMLCBDRFNfRlVMTFNDUkVFTiwgTlVMTCk7CiAgICB9CgogICAgaWYgKG9iamVjdC0+YmFja0J1ZmZlcikgewogICAgICAgIGludCBpOwogICAgICAgIGZvcihpID0gMDsgaSA8IG9iamVjdC0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJDb3VudDsgaSsrKSB7CiAgICAgICAgICAgIGlmKG9iamVjdC0+YmFja0J1ZmZlcltpXSkgewogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0dldFBhcmVudChvYmplY3QtPmJhY2tCdWZmZXJbaV0sICZidWZmZXJQYXJlbnQpOwogICAgICAgICAgICAgICAgSVVua25vd25fUmVsZWFzZShidWZmZXJQYXJlbnQpOyAvKiBvbmNlIGZvciB0aGUgZ2V0IHBhcmVudCAqLwogICAgICAgICAgICAgICAgaWYgKElVbmtub3duX1JlbGVhc2UoYnVmZmVyUGFyZW50KSA+IDApIHsKICAgICAgICAgICAgICAgICAgICBGSVhNRSgiKCVwKSBTb21ldGhpbmcncyBzdGlsbCBob2xkaW5nIHRoZSBiYWNrIGJ1ZmZlclxuIixUaGlzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvYmplY3QtPmJhY2tCdWZmZXIpOwogICAgICAgIG9iamVjdC0+YmFja0J1ZmZlciA9IE5VTEw7CiAgICB9CiAgICBpZihvYmplY3QtPmNvbnRleHRbMF0pCiAgICAgICAgRGVzdHJveUNvbnRleHQoVGhpcywgb2JqZWN0LT5jb250ZXh0WzBdKTsKICAgIGlmKG9iamVjdC0+ZnJvbnRCdWZmZXIpIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfR2V0UGFyZW50KG9iamVjdC0+ZnJvbnRCdWZmZXIsICZidWZmZXJQYXJlbnQpOwogICAgICAgIElVbmtub3duX1JlbGVhc2UoYnVmZmVyUGFyZW50KTsgLyogb25jZSBmb3IgdGhlIGdldCBwYXJlbnQgKi8KICAgICAgICBpZiAoSVVua25vd25fUmVsZWFzZShidWZmZXJQYXJlbnQpID4gMCkgewogICAgICAgICAgICBGSVhNRSgiKCVwKSBTb21ldGhpbmcncyBzdGlsbCBob2xkaW5nIHRoZSBmcm9udCBidWZmZXJcbiIsVGhpcyk7CiAgICAgICAgfQogICAgfQogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2JqZWN0KTsKICAgIHJldHVybiBocjsKfQoKLyoqIE5PVEU6IFRoZXNlIGFyZSBhaGVhZCBvZiB0aGUgb3RoZXIgZ2V0dGVycyBhbmQgc2V0dGVycyB0byBzYXZlIHVzaW5nIGEgZm9yd2FyZCBkZWNsYXJhdGlvbiAqKi8Kc3RhdGljIFVJTlQgICAgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0dldE51bWJlck9mU3dhcENoYWlucyhJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICByZXR1cm4gVGhpcy0+TnVtYmVyT2ZTd2FwQ2hhaW5zOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfR2V0U3dhcENoYWluKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBpU3dhcENoYWluLCBJV2luZUQzRFN3YXBDaGFpbiAqKnBTd2FwQ2hhaW4pIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogc3dhcGNoYWluICVkXG4iLCBUaGlzLCBpU3dhcENoYWluKTsKCiAgICBpZihpU3dhcENoYWluIDwgVGhpcy0+TnVtYmVyT2ZTd2FwQ2hhaW5zKSB7CiAgICAgICAgKnBTd2FwQ2hhaW4gPSBUaGlzLT5zd2FwY2hhaW5zW2lTd2FwQ2hhaW5dOwogICAgICAgIElXaW5lRDNEU3dhcENoYWluX0FkZFJlZigqcFN3YXBDaGFpbik7CiAgICAgICAgVFJBQ0UoIiglcCkgcmV0dXJuaW5nICVwXG4iLCBUaGlzLCAqcFN3YXBDaGFpbik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9IGVsc2UgewogICAgICAgIFRSQUNFKCJTd2FwY2hhaW4gb3V0IG9mIHJhbmdlXG4iKTsKICAgICAgICAqcFN3YXBDaGFpbiA9IE5VTEw7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9Cn0KCi8qKioqKgogKiBWZXJ0ZXggRGVjbGFyYXRpb24KICoqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZlcnRleERlY2xhcmF0aW9uKElXaW5lRDNERGV2aWNlKiBpZmFjZSwgSVdpbmVEM0RWZXJ0ZXhEZWNsYXJhdGlvbioqIHBwVmVydGV4RGVjbGFyYXRpb24sCiAgICAgICAgSVVua25vd24gKnBhcmVudCwgY29uc3QgV0lORUQzRFZFUlRFWEVMRU1FTlQgKmVsZW1lbnRzLCBzaXplX3QgZWxlbWVudF9jb3VudCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICAgICAgICAgICAgKlRoaXMgICA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb25JbXBsICpvYmplY3QgPSBOVUxMOwogICAgSFJFU1VMVCBociA9IFdJTkVEM0RfT0s7CgogICAgVFJBQ0UoIiglcCkgOiBkaXJlY3RYVmVyc2lvbiAldSwgZWxlbWVudHMgJXAsIGVsZW1lbnRfY291bnQgJWQsIHBwRGVjbD0lcFxuIiwKICAgICAgICAgICAgVGhpcywgKChJV2luZUQzREltcGwgKilUaGlzLT53aW5lRDNEKS0+ZHhWZXJzaW9uLCBlbGVtZW50cywgZWxlbWVudF9jb3VudCwgcHBWZXJ0ZXhEZWNsYXJhdGlvbik7CgogICAgRDNEQ1JFQVRFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBWZXJ0ZXhEZWNsYXJhdGlvbikKCiAgICBociA9IElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb25fU2V0RGVjbGFyYXRpb24oKElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb24gKilvYmplY3QsIGVsZW1lbnRzLCBlbGVtZW50X2NvdW50KTsKCiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBzaXplX3QgQ29udmVydEZ2ZlRvRGVjbGFyYXRpb24oRFdPUkQgZnZmLCBXSU5FRDNEVkVSVEVYRUxFTUVOVCoqIHBwVmVydGV4RWxlbWVudHMpIHsKCiAgICB1bnNpZ25lZCBpbnQgaWR4LCBpZHgyOwogICAgdW5zaWduZWQgaW50IG9mZnNldDsKICAgIEJPT0wgaGFzX3BvcyA9IChmdmYgJiBXSU5FRDNERlZGX1BPU0lUSU9OX01BU0spICE9IDA7CiAgICBCT09MIGhhc19ibGVuZCA9IChmdmYgJiBXSU5FRDNERlZGX1hZWkI1KSA+IFdJTkVEM0RGVkZfWFlaUkhXOwogICAgQk9PTCBoYXNfYmxlbmRfaWR4ID0gaGFzX2JsZW5kICYmCiAgICAgICAoKChmdmYgJiBXSU5FRDNERlZGX1hZWkI1KSA9PSBXSU5FRDNERlZGX1hZWkI1KSB8fAogICAgICAgIChmdmYgJiBXSU5FRDNERlZGX0xBU1RCRVRBX0QzRENPTE9SKSB8fAogICAgICAgIChmdmYgJiBXSU5FRDNERlZGX0xBU1RCRVRBX1VCWVRFNCkpOwogICAgQk9PTCBoYXNfbm9ybWFsID0gKGZ2ZiAmIFdJTkVEM0RGVkZfTk9STUFMKSAhPSAwOwogICAgQk9PTCBoYXNfcHNpemUgPSAoZnZmICYgV0lORUQzREZWRl9QU0laRSkgIT0gMDsKICAgIEJPT0wgaGFzX2RpZmZ1c2UgPSAoZnZmICYgV0lORUQzREZWRl9ESUZGVVNFKSAhPSAwOwogICAgQk9PTCBoYXNfc3BlY3VsYXIgPSAoZnZmICYgV0lORUQzREZWRl9TUEVDVUxBUikgIT0wOwoKICAgIERXT1JEIG51bV90ZXh0dXJlcyA9IChmdmYgJiBXSU5FRDNERlZGX1RFWENPVU5UX01BU0spID4+IFdJTkVEM0RGVkZfVEVYQ09VTlRfU0hJRlQ7CiAgICBEV09SRCB0ZXhjb29yZHMgPSAoZnZmICYgMHgwMEZGMDAwMCkgPj4gMTY7CgogICAgV0lORUQzRFZFUlRFWEVMRU1FTlQgZW5kX2VsZW1lbnQgPSBXSU5FRDNEREVDTF9FTkQoKTsKICAgIFdJTkVEM0RWRVJURVhFTEVNRU5UICplbGVtZW50cyA9IE5VTEw7CgogICAgdW5zaWduZWQgaW50IHNpemU7CiAgICBEV09SRCBudW1fYmxlbmRzID0gMSArICgoKGZ2ZiAmIFdJTkVEM0RGVkZfWFlaQjUpIC0gV0lORUQzREZWRl9YWVpCMSkgPj4gMSk7CiAgICBpZiAoaGFzX2JsZW5kX2lkeCkgbnVtX2JsZW5kcy0tOwoKICAgIC8qIENvbXB1dGUgZGVjbGFyYXRpb24gc2l6ZSAqLwogICAgc2l6ZSA9IGhhc19wb3MgKyAoaGFzX2JsZW5kICYmIG51bV9ibGVuZHMgPiAwKSArIGhhc19ibGVuZF9pZHggKyBoYXNfbm9ybWFsICsKICAgICAgICAgICBoYXNfcHNpemUgKyBoYXNfZGlmZnVzZSArIGhhc19zcGVjdWxhciArIG51bV90ZXh0dXJlcyArIDE7CgogICAgLyogY29udmVydCB0aGUgZGVjbGFyYXRpb24gKi8KICAgIGVsZW1lbnRzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemUgKiBzaXplb2YoV0lORUQzRFZFUlRFWEVMRU1FTlQpKTsKICAgIGlmICghZWxlbWVudHMpCiAgICAgICAgcmV0dXJuIDA7CgogICAgbWVtY3B5KCZlbGVtZW50c1tzaXplLTFdLCAmZW5kX2VsZW1lbnQsIHNpemVvZihXSU5FRDNEVkVSVEVYRUxFTUVOVCkpOwogICAgaWR4ID0gMDsKICAgIGlmIChoYXNfcG9zKSB7CiAgICAgICAgaWYgKCFoYXNfYmxlbmQgJiYgKGZ2ZiAmIFdJTkVEM0RGVkZfWFlaUkhXKSkgewogICAgICAgICAgICBlbGVtZW50c1tpZHhdLlR5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQ0OwogICAgICAgICAgICBlbGVtZW50c1tpZHhdLlVzYWdlID0gV0lORUQzRERFQ0xVU0FHRV9QT1NJVElPTlQ7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBlbGVtZW50c1tpZHhdLlR5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQzOwogICAgICAgICAgICBlbGVtZW50c1tpZHhdLlVzYWdlID0gV0lORUQzRERFQ0xVU0FHRV9QT1NJVElPTjsKICAgICAgICB9CiAgICAgICAgZWxlbWVudHNbaWR4XS5Vc2FnZUluZGV4ID0gMDsKICAgICAgICBpZHgrKzsKICAgIH0KICAgIGlmIChoYXNfYmxlbmQgJiYgKG51bV9ibGVuZHMgPiAwKSkgewogICAgICAgIGlmICgoKGZ2ZiAmIFdJTkVEM0RGVkZfWFlaQjUpID09IFdJTkVEM0RGVkZfWFlaQjIpICYmIChmdmYgJiBXSU5FRDNERlZGX0xBU1RCRVRBX0QzRENPTE9SKSkKICAgICAgICAgICAgZWxlbWVudHNbaWR4XS5UeXBlID0gV0lORUQzRERFQ0xUWVBFX0QzRENPTE9SOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZWxlbWVudHNbaWR4XS5UeXBlID0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUMSArIG51bV9ibGVuZHMgLSAxOwogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2UgPSBXSU5FRDNEREVDTFVTQUdFX0JMRU5EV0VJR0hUOwogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2VJbmRleCA9IDA7CiAgICAgICAgaWR4Kys7CiAgICB9CiAgICBpZiAoaGFzX2JsZW5kX2lkeCkgewogICAgICAgIGlmIChmdmYgJiBXSU5FRDNERlZGX0xBU1RCRVRBX1VCWVRFNCB8fAogICAgICAgICAgICAoKChmdmYgJiBXSU5FRDNERlZGX1hZWkI1KSA9PSBXSU5FRDNERlZGX1hZWkIyKSAmJiAoZnZmICYgV0lORUQzREZWRl9MQVNUQkVUQV9EM0RDT0xPUikpKQogICAgICAgICAgICBlbGVtZW50c1tpZHhdLlR5cGUgPSBXSU5FRDNEREVDTFRZUEVfVUJZVEU0OwogICAgICAgIGVsc2UgaWYgKGZ2ZiAmIFdJTkVEM0RGVkZfTEFTVEJFVEFfRDNEQ09MT1IpCiAgICAgICAgICAgIGVsZW1lbnRzW2lkeF0uVHlwZSA9IFdJTkVEM0RERUNMVFlQRV9EM0RDT0xPUjsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGVsZW1lbnRzW2lkeF0uVHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDE7CiAgICAgICAgZWxlbWVudHNbaWR4XS5Vc2FnZSA9IFdJTkVEM0RERUNMVVNBR0VfQkxFTkRJTkRJQ0VTOwogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2VJbmRleCA9IDA7CiAgICAgICAgaWR4Kys7CiAgICB9CiAgICBpZiAoaGFzX25vcm1hbCkgewogICAgICAgIGVsZW1lbnRzW2lkeF0uVHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDM7CiAgICAgICAgZWxlbWVudHNbaWR4XS5Vc2FnZSA9IFdJTkVEM0RERUNMVVNBR0VfTk9STUFMOwogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2VJbmRleCA9IDA7CiAgICAgICAgaWR4Kys7CiAgICB9CiAgICBpZiAoaGFzX3BzaXplKSB7CiAgICAgICAgZWxlbWVudHNbaWR4XS5UeXBlID0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUMTsKICAgICAgICBlbGVtZW50c1tpZHhdLlVzYWdlID0gV0lORUQzRERFQ0xVU0FHRV9QU0laRTsKICAgICAgICBlbGVtZW50c1tpZHhdLlVzYWdlSW5kZXggPSAwOwogICAgICAgIGlkeCsrOwogICAgfQogICAgaWYgKGhhc19kaWZmdXNlKSB7CiAgICAgICAgZWxlbWVudHNbaWR4XS5UeXBlID0gV0lORUQzRERFQ0xUWVBFX0QzRENPTE9SOwogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2UgPSBXSU5FRDNEREVDTFVTQUdFX0NPTE9SOwogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2VJbmRleCA9IDA7CiAgICAgICAgaWR4Kys7CiAgICB9CiAgICBpZiAoaGFzX3NwZWN1bGFyKSB7CiAgICAgICAgZWxlbWVudHNbaWR4XS5UeXBlID0gV0lORUQzRERFQ0xUWVBFX0QzRENPTE9SOwogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2UgPSBXSU5FRDNEREVDTFVTQUdFX0NPTE9SOwogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2VJbmRleCA9IDE7CiAgICAgICAgaWR4Kys7CiAgICB9CiAgICBmb3IgKGlkeDIgPSAwOyBpZHgyIDwgbnVtX3RleHR1cmVzOyBpZHgyKyspIHsKICAgICAgICB1bnNpZ25lZCBpbnQgbnVtY29vcmRzID0gKHRleGNvb3JkcyA+PiAoaWR4MioyKSkgJiAweDAzOwogICAgICAgIHN3aXRjaCAobnVtY29vcmRzKSB7CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZWRl9URVhUVVJFRk9STUFUMToKICAgICAgICAgICAgICAgIGVsZW1lbnRzW2lkeF0uVHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBXSU5FRDNERlZGX1RFWFRVUkVGT1JNQVQyOgogICAgICAgICAgICAgICAgZWxlbWVudHNbaWR4XS5UeXBlID0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFdJTkVEM0RGVkZfVEVYVFVSRUZPUk1BVDM6CiAgICAgICAgICAgICAgICBlbGVtZW50c1tpZHhdLlR5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQzOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZWRl9URVhUVVJFRk9STUFUNDoKICAgICAgICAgICAgICAgIGVsZW1lbnRzW2lkeF0uVHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgZWxlbWVudHNbaWR4XS5Vc2FnZSA9IFdJTkVEM0RERUNMVVNBR0VfVEVYQ09PUkQ7CiAgICAgICAgZWxlbWVudHNbaWR4XS5Vc2FnZUluZGV4ID0gaWR4MjsKICAgICAgICBpZHgrKzsKICAgIH0KCiAgICAvKiBOb3cgY29tcHV0ZSBvZmZzZXRzLCBhbmQgaW5pdGlhbGl6ZSB0aGUgcmVzdCBvZiB0aGUgZmllbGRzICovCiAgICBmb3IgKGlkeCA9IDAsIG9mZnNldCA9IDA7IGlkeCA8IHNpemUtMTsgaWR4KyspIHsKICAgICAgICBlbGVtZW50c1tpZHhdLlN0cmVhbSA9IDA7CiAgICAgICAgZWxlbWVudHNbaWR4XS5NZXRob2QgPSBXSU5FRDNEREVDTE1FVEhPRF9ERUZBVUxUOwogICAgICAgIGVsZW1lbnRzW2lkeF0uT2Zmc2V0ID0gb2Zmc2V0OwogICAgICAgIG9mZnNldCArPSBXSU5FRDNEX0FUUl9TSVpFKGVsZW1lbnRzW2lkeF0uVHlwZSkgKiBXSU5FRDNEX0FUUl9UWVBFU0laRShlbGVtZW50c1tpZHhdLlR5cGUpOwogICAgfQoKICAgICpwcFZlcnRleEVsZW1lbnRzID0gZWxlbWVudHM7CiAgICByZXR1cm4gc2l6ZTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWZXJ0ZXhEZWNsYXJhdGlvbkZyb21GVkYoSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uKiogcHBWZXJ0ZXhEZWNsYXJhdGlvbiwgSVVua25vd24gKlBhcmVudCwgRFdPUkQgRnZmKSB7CiAgICBXSU5FRDNEVkVSVEVYRUxFTUVOVCogZWxlbWVudHMgPSBOVUxMOwogICAgc2l6ZV90IHNpemU7CiAgICBEV09SRCBocjsKCiAgICBzaXplID0gQ29udmVydEZ2ZlRvRGVjbGFyYXRpb24oRnZmLCAmZWxlbWVudHMpOwogICAgaWYgKHNpemUgPT0gMCkgcmV0dXJuIFdJTkVEM0RFUlJfT1VUT0ZWSURFT01FTU9SWTsKCiAgICBociA9IElXaW5lRDNERGV2aWNlX0NyZWF0ZVZlcnRleERlY2xhcmF0aW9uKGlmYWNlLCBwcFZlcnRleERlY2xhcmF0aW9uLCBQYXJlbnQsIGVsZW1lbnRzLCBzaXplKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGVsZW1lbnRzKTsKICAgIGlmIChociAhPSBTX09LKSByZXR1cm4gaHI7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vYXJjaGl2ZS9kZWZhdWx0LmFzcD91cmw9L2FyY2hpdmUvZW4tdXMvZGlyZWN0eDlfYy9kaXJlY3R4L2dyYXBoaWNzL3Byb2dyYW1taW5nZ3VpZGUvcHJvZ3JhbW1hYmxlL3ZlcnRleHNoYWRlcnMvdnNjcmVhdGUuYXNwICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVmVydGV4U2hhZGVyKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RWZXJ0ZXhEZWNsYXJhdGlvbiAqdmVydGV4X2RlY2xhcmF0aW9uLCBDT05TVCBEV09SRCAqcEZ1bmN0aW9uLCBJV2luZUQzRFZlcnRleFNoYWRlciAqKnBwVmVydGV4U2hhZGVyLCBJVW5rbm93biAqcGFyZW50KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgICAgICAgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFZlcnRleFNoYWRlckltcGwgKm9iamVjdDsgIC8qIE5PVEU6IGltcGwgdXNhZ2UgaXMgb2ssIHRoaXMgaXMgYSBjcmVhdGUgKi8KICAgIEhSRVNVTFQgaHIgPSBXSU5FRDNEX09LOwogICAgRDNEQ1JFQVRFU0hBREVST0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBWZXJ0ZXhTaGFkZXIpCiAgICBvYmplY3QtPmJhc2VTaGFkZXIuc2hhZGVyX2lucyA9IElXaW5lRDNEVmVydGV4U2hhZGVySW1wbF9zaGFkZXJfaW5zOwoKICAgIFRSQUNFKCIoJXApIDogQ3JlYXRlZCBWZXJ0ZXggc2hhZGVyICVwXG4iLCBUaGlzLCAqcHBWZXJ0ZXhTaGFkZXIpOwoKICAgIGlmICh2ZXJ0ZXhfZGVjbGFyYXRpb24pIHsKICAgICAgICBJV2luZUQzRFZlcnRleFNoYWRlcl9GYWtlU2VtYW50aWNzKCpwcFZlcnRleFNoYWRlciwgdmVydGV4X2RlY2xhcmF0aW9uKTsKICAgIH0KCiAgICBociA9IElXaW5lRDNEVmVydGV4U2hhZGVyX1NldEZ1bmN0aW9uKCpwcFZlcnRleFNoYWRlciwgcEZ1bmN0aW9uKTsKCiAgICBpZiAoV0lORUQzRF9PSyAhPSBocikgewogICAgICAgIEZJWE1FKCIoJXApIDogRmFpbGVkIHRvIHNldCB0aGUgZnVuY3Rpb24sIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iLCBpZmFjZSk7CiAgICAgICAgSVdpbmVEM0RWZXJ0ZXhTaGFkZXJfUmVsZWFzZSgqcHBWZXJ0ZXhTaGFkZXIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVBpeGVsU2hhZGVyKElXaW5lRDNERGV2aWNlICppZmFjZSwgQ09OU1QgRFdPUkQgKnBGdW5jdGlvbiwgSVdpbmVEM0RQaXhlbFNoYWRlciAqKnBwUGl4ZWxTaGFkZXIsIElVbmtub3duICpwYXJlbnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICpvYmplY3Q7IC8qIE5PVEU6IGltcGwgYWxsb3dlZCwgdGhpcyBpcyBhIGNyZWF0ZSAqLwogICAgSFJFU1VMVCBociA9IFdJTkVEM0RfT0s7CgogICAgRDNEQ1JFQVRFU0hBREVST0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBQaXhlbFNoYWRlcikKICAgIG9iamVjdC0+YmFzZVNoYWRlci5zaGFkZXJfaW5zID0gSVdpbmVEM0RQaXhlbFNoYWRlckltcGxfc2hhZGVyX2luczsKICAgIGhyID0gSVdpbmVEM0RQaXhlbFNoYWRlcl9TZXRGdW5jdGlvbigqcHBQaXhlbFNoYWRlciwgcEZ1bmN0aW9uKTsKICAgIGlmIChXSU5FRDNEX09LID09IGhyKSB7CiAgICAgICAgVFJBQ0UoIiglcCkgOiBDcmVhdGVkIFBpeGVsIHNoYWRlciAlcFxuIiwgVGhpcywgKnBwUGl4ZWxTaGFkZXIpOwogICAgfSBlbHNlIHsKICAgICAgICBXQVJOKCIoJXApIDogRmFpbGVkIHRvIGNyZWF0ZSBwaXhlbCBzaGFkZXJcbiIsIFRoaXMpOwogICAgfQoKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVQYWxldHRlKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgRmxhZ3MsIFBBTEVUVEVFTlRSWSAqUGFsRW50LCBJV2luZUQzRFBhbGV0dGUgKipQYWxldHRlLCBJVW5rbm93biAqUGFyZW50KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RQYWxldHRlSW1wbCAqb2JqZWN0OwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJXgsICVwLCAlcCwgJXApXG4iLCBUaGlzLCBGbGFncywgUGFsRW50LCBQYWxldHRlLCBQYXJlbnQpOwoKICAgIC8qIENyZWF0ZSB0aGUgbmV3IG9iamVjdCAqLwogICAgb2JqZWN0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJV2luZUQzRFBhbGV0dGVJbXBsKSk7CiAgICBpZighb2JqZWN0KSB7CiAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5IHdoZW4gYWxsb2NhdGluZyBtZW1vcnkgZm9yIGEgSVdpbmVEM0RQYWxldHRlIGltcGxlbWVudGF0aW9uXG4iKTsKICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgIH0KCiAgICBvYmplY3QtPmxwVnRibCA9ICZJV2luZUQzRFBhbGV0dGVfVnRibDsKICAgIG9iamVjdC0+cmVmID0gMTsKICAgIG9iamVjdC0+RmxhZ3MgPSBGbGFnczsKICAgIG9iamVjdC0+cGFyZW50ID0gUGFyZW50OwogICAgb2JqZWN0LT53aW5lRDNERGV2aWNlID0gVGhpczsKICAgIG9iamVjdC0+cGFsTnVtRW50cmllcyA9IElXaW5lRDNEUGFsZXR0ZUltcGxfU2l6ZShGbGFncyk7CgkKICAgIG9iamVjdC0+aHBhbCA9IENyZWF0ZVBhbGV0dGUoKGNvbnN0IExPR1BBTEVUVEUqKSYob2JqZWN0LT5wYWxWZXJzaW9uKSk7CgogICAgaWYoIW9iamVjdC0+aHBhbCkgewogICAgICAgIEhlYXBGcmVlKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBvYmplY3QpOwogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwogICAgfQoKICAgIGhyID0gSVdpbmVEM0RQYWxldHRlX1NldEVudHJpZXMoKElXaW5lRDNEUGFsZXR0ZSAqKSBvYmplY3QsIDAsIDAsIElXaW5lRDNEUGFsZXR0ZUltcGxfU2l6ZShGbGFncyksIFBhbEVudCk7CiAgICBpZihGQUlMRUQoaHIpKSB7CiAgICAgICAgSVdpbmVEM0RQYWxldHRlX1JlbGVhc2UoKElXaW5lRDNEUGFsZXR0ZSAqKSBvYmplY3QpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICAqUGFsZXR0ZSA9IChJV2luZUQzRFBhbGV0dGUgKikgb2JqZWN0OwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgdm9pZCBJV2luZUQzRERldmljZUltcGxfTG9hZExvZ28oSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzLCBjb25zdCBjaGFyICpmaWxlbmFtZSkgewogICAgSEJJVE1BUCBoYm07CiAgICBCSVRNQVAgYm07CiAgICBIUkVTVUxUIGhyOwogICAgSERDIGRjYiA9IE5VTEwsIGRjcyA9IE5VTEw7CiAgICBXSU5FRERDT0xPUktFWSBjb2xvcmtleTsKCiAgICBoYm0gPSAoSEJJVE1BUCkgTG9hZEltYWdlQShOVUxMLCBmaWxlbmFtZSwgSU1BR0VfQklUTUFQLCAwLCAwLCBMUl9MT0FERlJPTUZJTEUgfCBMUl9DUkVBVEVESUJTRUNUSU9OKTsKICAgIGlmKGhibSkKICAgIHsKICAgICAgICBHZXRPYmplY3RBKGhibSwgc2l6ZW9mKEJJVE1BUCksICZibSk7CiAgICAgICAgZGNiID0gQ3JlYXRlQ29tcGF0aWJsZURDKE5VTEwpOwogICAgICAgIGlmKCFkY2IpIGdvdG8gb3V0OwogICAgICAgIFNlbGVjdE9iamVjdChkY2IsIGhibSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgLyogQ3JlYXRlIGEgMzJ4MzIgd2hpdGUgc3VyZmFjZSB0byBpbmRpY2F0ZSB0aGF0IHdpbmVkM2QgaXMgdXNlZCwgYnV0IHRoZSBzcGVjaWZpZWQgaW1hZ2UKICAgICAgICAgKiBjb3VsZG4ndCBiZSBsb2FkZWQKICAgICAgICAgKi8KICAgICAgICBtZW1zZXQoJmJtLCAwLCBzaXplb2YoYm0pKTsKICAgICAgICBibS5ibVdpZHRoID0gMzI7CiAgICAgICAgYm0uYm1IZWlnaHQgPSAzMjsKICAgIH0KCiAgICBociA9IElXaW5lRDNERGV2aWNlX0NyZWF0ZVN1cmZhY2UoKElXaW5lRDNERGV2aWNlICopIFRoaXMsIGJtLmJtV2lkdGgsIGJtLmJtSGVpZ2h0LCBXSU5FRDNERk1UX1I1RzZCNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFLCBGQUxTRSwgMCwgJlRoaXMtPmxvZ29fc3VyZmFjZSwgV0lORUQzRFJUWVBFX1NVUkZBQ0UsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFBPT0xfREVGQVVMVCwgV0lORUQzRE1VTFRJU0FNUExFX05PTkUsIDAsIE5VTEwsIFNVUkZBQ0VfT1BFTkdMLCBOVUxMKTsKICAgIGlmKEZBSUxFRChocikpIHsKICAgICAgICBFUlIoIldpbmUgbG9nbyByZXF1ZXN0ZWQsIGJ1dCBmYWlsZWQgdG8gY3JlYXRlIHN1cmZhY2VcbiIpOwogICAgICAgIGdvdG8gb3V0OwogICAgfQoKICAgIGlmKGRjYikgewogICAgICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0dldERDKFRoaXMtPmxvZ29fc3VyZmFjZSwgJmRjcyk7CiAgICAgICAgaWYoRkFJTEVEKGhyKSkgZ290byBvdXQ7CiAgICAgICAgQml0Qmx0KGRjcywgMCwgMCwgYm0uYm1XaWR0aCwgYm0uYm1IZWlnaHQsIGRjYiwgMCwgMCwgU1JDQ09QWSk7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2VEQyhUaGlzLT5sb2dvX3N1cmZhY2UsIGRjcyk7CgogICAgICAgIGNvbG9ya2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlID0gMDsKICAgICAgICBjb2xvcmtleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWUgPSAwOwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb2xvcktleShUaGlzLT5sb2dvX3N1cmZhY2UsIFdJTkVERENLRVlfU1JDQkxULCAmY29sb3JrZXkpOwogICAgfSBlbHNlIHsKICAgICAgICAvKiBGaWxsIHRoZSBzdXJmYWNlIHdpdGggYSB3aGl0ZSBjb2xvciB0byBzaG93IHRoYXQgd2luZWQzZCBpcyB0aGVyZSAqLwogICAgICAgIElXaW5lRDNERGV2aWNlX0NvbG9yRmlsbCgoSVdpbmVEM0REZXZpY2UgKikgVGhpcywgVGhpcy0+bG9nb19zdXJmYWNlLCBOVUxMLCAweGZmZmZmZmZmKTsKICAgIH0KCiAgICBvdXQ6CiAgICBpZihkY2IpIHsKICAgICAgICBEZWxldGVEQyhkY2IpOwogICAgfQogICAgaWYoaGJtKSB7CiAgICAgICAgRGVsZXRlT2JqZWN0KGhibSk7CiAgICB9CiAgICByZXR1cm47Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfSW5pdDNEKElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRFBSRVNFTlRfUEFSQU1FVEVSUyogcFByZXNlbnRhdGlvblBhcmFtZXRlcnMsIEQzRENCX0NSRUFURUFERElUSU9OQUxTV0FQQ0hBSU4gRDNEQ0JfQ3JlYXRlQWRkaXRpb25hbFN3YXBDaGFpbikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqc3dhcGNoYWluOwogICAgSFJFU1VMVCBocjsKICAgIERXT1JEIHN0YXRlOwoKICAgIFRSQUNFKCIoJXApLT4oJXAsJXApXG4iLCBUaGlzLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycywgRDNEQ0JfQ3JlYXRlQWRkaXRpb25hbFN3YXBDaGFpbik7CiAgICBpZihUaGlzLT5kM2RfaW5pdGlhbGl6ZWQpIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIC8qIFRPRE86IFRlc3QgaWYgT3BlbkdMIGlzIGNvbXBpbGVkIGluIGFuZCBsb2FkZWQgKi8KCiAgICBUUkFDRSgiKCVwKSA6IENyZWF0aW5nIHN0YXRlYmxvY2tcbiIsIFRoaXMpOwogICAgLyogQ3JlYXRpbmcgdGhlIHN0YXJ0dXAgc3RhdGVCbG9jayAtIE5vdGUgU3BlY2lhbCBDYXNlOiAwID0+IERvbid0IGZpbGwgaW4geWV0ISAqLwogICAgaHIgPSBJV2luZUQzRERldmljZV9DcmVhdGVTdGF0ZUJsb2NrKGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RTQlRfSU5JVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSVdpbmVEM0RTdGF0ZUJsb2NrICoqKSZUaGlzLT5zdGF0ZUJsb2NrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgaWYgKFdJTkVEM0RfT0sgIT0gaHIpIHsgICAvKiBOb3RlOiBObyBwYXJlbnQgbmVlZGVkIGZvciBpbml0aWFsIGludGVybmFsIHN0YXRlYmxvY2sgKi8KICAgICAgICBXQVJOKCJGYWlsZWQgdG8gY3JlYXRlIHN0YXRlYmxvY2tcbiIpOwogICAgICAgIGdvdG8gZXJyX291dDsKICAgIH0KICAgIFRSQUNFKCIoJXApIDogQ3JlYXRlZCBzdGF0ZWJsb2NrICglcClcbiIsIFRoaXMsIFRoaXMtPnN0YXRlQmxvY2spOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jayA9IFRoaXMtPnN0YXRlQmxvY2s7CiAgICBJV2luZUQzRFN0YXRlQmxvY2tfQWRkUmVmKChJV2luZUQzRFN0YXRlQmxvY2sqKVRoaXMtPnVwZGF0ZVN0YXRlQmxvY2spOwoKICAgIGhyID0gYWxsb2NhdGVfc2hhZGVyX2NvbnN0YW50cyhUaGlzLT51cGRhdGVTdGF0ZUJsb2NrKTsKICAgIGlmIChXSU5FRDNEX09LICE9IGhyKSB7CiAgICAgICAgZ290byBlcnJfb3V0OwogICAgfQoKICAgIFRoaXMtPnJlbmRlcl90YXJnZXRzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJV2luZUQzRFN1cmZhY2UgKikgKiBHTF9MSU1JVFMoYnVmZmVycykpOwogICAgVGhpcy0+ZmJvX2NvbG9yX2F0dGFjaG1lbnRzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJV2luZUQzRFN1cmZhY2UgKikgKiBHTF9MSU1JVFMoYnVmZmVycykpOwogICAgVGhpcy0+ZHJhd19idWZmZXJzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihHTGVudW0pICogR0xfTElNSVRTKGJ1ZmZlcnMpKTsKCiAgICAvKiBJbml0aWFsaXplIHRoZSB0ZXh0dXJlIHVuaXQgbWFwcGluZyB0byBhIDE6MSBtYXBwaW5nICovCiAgICBmb3IgKHN0YXRlID0gMDsgc3RhdGUgPCBNQVhfQ09NQklORURfU0FNUExFUlM7ICsrc3RhdGUpIHsKICAgICAgICBpZiAoc3RhdGUgPCBHTF9MSU1JVFMoZnJhZ21lbnRfc2FtcGxlcnMpKSB7CiAgICAgICAgICAgIFRoaXMtPnRleFVuaXRNYXBbc3RhdGVdID0gc3RhdGU7CiAgICAgICAgICAgIFRoaXMtPnJldl90ZXhfdW5pdF9tYXBbc3RhdGVdID0gc3RhdGU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVGhpcy0+dGV4VW5pdE1hcFtzdGF0ZV0gPSAtMTsKICAgICAgICAgICAgVGhpcy0+cmV2X3RleF91bml0X21hcFtzdGF0ZV0gPSAtMTsKICAgICAgICB9CiAgICB9CgogICAgLyogU2V0dXAgdGhlIGltcGxpY2l0IHN3YXBjaGFpbiAqLwogICAgVFJBQ0UoIkNyZWF0aW5nIGltcGxpY2l0IHN3YXBjaGFpblxuIik7CiAgICBocj1EM0RDQl9DcmVhdGVBZGRpdGlvbmFsU3dhcENoYWluKChJVW5rbm93biAqKSBUaGlzLT5wYXJlbnQsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLCAoSVdpbmVEM0RTd2FwQ2hhaW4gKiopJnN3YXBjaGFpbik7CiAgICBpZiAoRkFJTEVEKGhyKSB8fCAhc3dhcGNoYWluKSB7CiAgICAgICAgV0FSTigiRmFpbGVkIHRvIGNyZWF0ZSBpbXBsaWNpdCBzd2FwY2hhaW5cbiIpOwogICAgICAgIGdvdG8gZXJyX291dDsKICAgIH0KCiAgICBUaGlzLT5OdW1iZXJPZlN3YXBDaGFpbnMgPSAxOwogICAgVGhpcy0+c3dhcGNoYWlucyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5OdW1iZXJPZlN3YXBDaGFpbnMgKiBzaXplb2YoSVdpbmVEM0RTd2FwQ2hhaW4gKikpOwogICAgaWYoIVRoaXMtPnN3YXBjaGFpbnMpIHsKICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnkhXG4iKTsKICAgICAgICBnb3RvIGVycl9vdXQ7CiAgICB9CiAgICBUaGlzLT5zd2FwY2hhaW5zWzBdID0gKElXaW5lRDNEU3dhcENoYWluICopIHN3YXBjaGFpbjsKCiAgICBpZihzd2FwY2hhaW4tPmJhY2tCdWZmZXIgJiYgc3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdKSB7CiAgICAgICAgVFJBQ0UoIlNldHRpbmcgcmVuZGVydGFyZ2V0IHRvICVwXG4iLCBzd2FwY2hhaW4tPmJhY2tCdWZmZXIpOwogICAgICAgIFRoaXMtPnJlbmRlcl90YXJnZXRzWzBdID0gc3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdOwogICAgICAgIFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQgPSBzd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF07CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBUUkFDRSgiU2V0dGluZyByZW5kZXJ0YXJnZXQgdG8gJXBcbiIsIHN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIpOwogICAgICAgIFRoaXMtPnJlbmRlcl90YXJnZXRzWzBdID0gc3dhcGNoYWluLT5mcm9udEJ1ZmZlcjsKICAgICAgICBUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0ID0gc3dhcGNoYWluLT5mcm9udEJ1ZmZlcjsKICAgIH0KICAgIElXaW5lRDNEU3VyZmFjZV9BZGRSZWYoVGhpcy0+cmVuZGVyX3RhcmdldHNbMF0pOwogICAgVGhpcy0+YWN0aXZlQ29udGV4dCA9IHN3YXBjaGFpbi0+Y29udGV4dFswXTsKICAgIFRoaXMtPmxhc3RUaHJlYWQgPSBHZXRDdXJyZW50VGhyZWFkSWQoKTsKCiAgICAvKiBEZXB0aCBTdGVuY2lsIHN1cHBvcnQgKi8KICAgIFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQgPSBUaGlzLT5hdXRvX2RlcHRoX3N0ZW5jaWxfYnVmZmVyOwogICAgaWYgKE5VTEwgIT0gVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCkgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9BZGRSZWYoVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCk7CiAgICB9CgogICAgLyogU2V0IHVwIHNvbWUgc3RhcnRpbmcgR0wgc2V0dXAgKi8KICAgIEVOVEVSX0dMKCk7CgogICAgLyogU2V0dXAgYWxsIHRoZSBkZXZpY2VzIGRlZmF1bHRzICovCiAgICBJV2luZUQzRFN0YXRlQmxvY2tfSW5pdFN0YXJ0dXBTdGF0ZUJsb2NrKChJV2luZUQzRFN0YXRlQmxvY2sgKilUaGlzLT5zdGF0ZUJsb2NrKTsKI2lmIDAKICAgIElXaW5lRDNESW1wbF9DaGVja0dyYXBoaWNzTWVtb3J5KCk7CiNlbmRpZgoKICAgIHsgLyogU2V0IGEgZGVmYXVsdCB2aWV3cG9ydCAqLwogICAgICAgIFdJTkVEM0RWSUVXUE9SVCB2cDsKICAgICAgICB2cC5YICAgICAgPSAwOwogICAgICAgIHZwLlkgICAgICA9IDA7CiAgICAgICAgdnAuV2lkdGggID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aDsKICAgICAgICB2cC5IZWlnaHQgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodDsKICAgICAgICB2cC5NaW5aICAgPSAwLjBmOwogICAgICAgIHZwLk1heFogICA9IDEuMGY7CiAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0Vmlld3BvcnQoKElXaW5lRDNERGV2aWNlICopVGhpcywgJnZwKTsKICAgIH0KCiAgICAvKiBJbml0aWFsaXplIHRoZSBjdXJyZW50IHZpZXcgc3RhdGUgKi8KICAgIFRoaXMtPnZpZXdfaWRlbnQgPSAxOwogICAgVGhpcy0+Y29udGV4dHNbMF0tPmxhc3Rfd2FzX3JodyA9IDA7CiAgICBnbEdldEludGVnZXJ2KEdMX01BWF9MSUdIVFMsICZUaGlzLT5tYXhDb25jdXJyZW50TGlnaHRzKTsKICAgIGNoZWNrR0xjYWxsKCJnbEdldEludGVnZXJ2KEdMX01BWF9MSUdIVFMsICZUaGlzLT5tYXhDb25jdXJyZW50TGlnaHRzKSIpOwoKICAgIHN3aXRjaCh3aW5lZDNkX3NldHRpbmdzLm9mZnNjcmVlbl9yZW5kZXJpbmdfbW9kZSkgewogICAgICAgIGNhc2UgT1JNX0ZCTzoKICAgICAgICBjYXNlIE9STV9QQlVGRkVSOgogICAgICAgICAgICBUaGlzLT5vZmZzY3JlZW5CdWZmZXIgPSBHTF9CQUNLOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBPUk1fQkFDS0JVRkZFUjoKICAgICAgICB7CiAgICAgICAgICAgIGlmKEdMX0xJTUlUUyhhdXhfYnVmZmVycykgPiAwKSB7CiAgICAgICAgICAgICAgICBUUkFDRSgiVXNpbmcgYXV4aWxsaWFyeSBidWZmZXIgZm9yIG9mZnNjcmVlbiByZW5kZXJpbmdcbiIpOwogICAgICAgICAgICAgICAgVGhpcy0+b2Zmc2NyZWVuQnVmZmVyID0gR0xfQVVYMDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIFRSQUNFKCJVc2luZyBiYWNrIGJ1ZmZlciBmb3Igb2Zmc2NyZWVuIHJlbmRlcmluZ1xuIik7CiAgICAgICAgICAgICAgICBUaGlzLT5vZmZzY3JlZW5CdWZmZXIgPSBHTF9CQUNLOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIFRSQUNFKCIoJXApIEFsbCBkZWZhdWx0cyBub3cgc2V0IHVwLCBsZWF2aW5nIEluaXQzRCB3aXRoICVwXG4iLCBUaGlzLCBUaGlzKTsKICAgIExFQVZFX0dMKCk7CgogICAgLyogQ2xlYXIgdGhlIHNjcmVlbiAqLwogICAgSVdpbmVEM0REZXZpY2VfQ2xlYXIoKElXaW5lRDNERGV2aWNlICopIFRoaXMsIDAsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRENMRUFSX1RBUkdFVCB8IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5FbmFibGVBdXRvRGVwdGhTdGVuY2lsID8gV0lORUQzRENMRUFSX1pCVUZGRVIgfCBXSU5FRDNEQ0xFQVJfU1RFTkNJTCA6IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwMCwgMS4wLCAwKTsKCiAgICBUaGlzLT5kM2RfaW5pdGlhbGl6ZWQgPSBUUlVFOwoKICAgIGlmKHdpbmVkM2Rfc2V0dGluZ3MubG9nbykgewogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9Mb2FkTG9nbyhUaGlzLCB3aW5lZDNkX3NldHRpbmdzLmxvZ28pOwogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7CgogICAgZXJyX291dDoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnJlbmRlcl90YXJnZXRzKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmZib19jb2xvcl9hdHRhY2htZW50cyk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5kcmF3X2J1ZmZlcnMpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+c3dhcGNoYWlucyk7CiAgICBUaGlzLT5OdW1iZXJPZlN3YXBDaGFpbnMgPSAwOwogICAgaWYoc3dhcGNoYWluKSB7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSggKElXaW5lRDNEU3dhcENoYWluICopIHN3YXBjaGFpbik7CiAgICB9CiAgICBUaGlzLT5kcmF3X2J1ZmZlcnMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKEdMZW51bSkgKiBHTF9MSU1JVFMoYnVmZmVycykpOwogICAgaWYoVGhpcy0+c3RhdGVCbG9jaykgewogICAgICAgIElXaW5lRDNEU3RhdGVCbG9ja19SZWxlYXNlKChJV2luZUQzRFN0YXRlQmxvY2sgKikgVGhpcy0+c3RhdGVCbG9jayk7CiAgICAgICAgVGhpcy0+c3RhdGVCbG9jayA9IE5VTEw7CiAgICB9CiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfVW5pbml0M0QoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEM0RDQl9ERVNUUk9ZU1VSRkFDRUZOIEQzRENCX0Rlc3Ryb3lEZXB0aFN0ZW5jaWxTdXJmYWNlLCBEM0RDQl9ERVNUUk9ZU1dBUENIQUlORk4gRDNEQ0JfRGVzdHJveVN3YXBDaGFpbikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIGludCBzYW1wbGVyOwogICAgVUlOVCBpOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIGlmKCFUaGlzLT5kM2RfaW5pdGlhbGl6ZWQpIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIC8qIEkgZG9uJ3QgdGhpbmsgdGhhdCB0aGUgaW50ZXJmYWNlIGd1YXJhbnRzIHRoYXQgdGhlIGRldmljZSBpcyBkZXN0cm95ZWQgZnJvbSB0aGUgc2FtZSB0aHJlYWQKICAgICAqIGl0IHdhcyBjcmVhdGVkLiBUaHVzIG1ha2Ugc3VyZSBhIGNvbnRleHQgaXMgYWN0aXZlIGZvciB0aGUgZ2xEZWxldGUqIGNhbGxzCiAgICAgKi8KICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0LCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwoKICAgIGlmKFRoaXMtPmxvZ29fc3VyZmFjZSkgSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2UoVGhpcy0+bG9nb19zdXJmYWNlKTsKCiAgICBUUkFDRSgiRGVsZXRpbmcgaGlnaCBvcmRlciBwYXRjaGVzXG4iKTsKICAgIGZvcihpID0gMDsgaSA8IFBBVENITUFQX1NJWkU7IGkrKykgewogICAgICAgIHN0cnVjdCBsaXN0ICplMSwgKmUyOwogICAgICAgIHN0cnVjdCBXaW5lRDNEUmVjdFBhdGNoICpwYXRjaDsKICAgICAgICBMSVNUX0ZPUl9FQUNIX1NBRkUoZTEsIGUyLCAmVGhpcy0+cGF0Y2hlc1tpXSkgewogICAgICAgICAgICBwYXRjaCA9IExJU1RfRU5UUlkoZTEsIHN0cnVjdCBXaW5lRDNEUmVjdFBhdGNoLCBlbnRyeSk7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX0RlbGV0ZVBhdGNoKGlmYWNlLCBwYXRjaC0+SGFuZGxlKTsKICAgICAgICB9CiAgICB9CgogICAgLyogRGVsZXRlIHRoZSBwYWxldHRlIGNvbnZlcnNpb24gc2hhZGVyIGlmIGl0IGlzIGFyb3VuZCAqLwogICAgaWYoVGhpcy0+cGFsZXR0ZUNvbnZlcnNpb25TaGFkZXIpIHsKICAgICAgICBHTF9FWFRDQUxMKGdsRGVsZXRlUHJvZ3JhbXNBUkIoMSwgJlRoaXMtPnBhbGV0dGVDb252ZXJzaW9uU2hhZGVyKSk7CiAgICAgICAgVGhpcy0+cGFsZXR0ZUNvbnZlcnNpb25TaGFkZXIgPSAwOwogICAgfQoKICAgIC8qIERlbGV0ZSB0aGUgcGJ1ZmZlciBjb250ZXh0IGlmIHRoZXJlIGlzIGFueSAqLwogICAgaWYoVGhpcy0+cGJ1ZmZlckNvbnRleHQpIERlc3Ryb3lDb250ZXh0KFRoaXMsIFRoaXMtPnBidWZmZXJDb250ZXh0KTsKCiAgICAvKiBEZWxldGUgdGhlIG1vdXNlIGN1cnNvciB0ZXh0dXJlICovCiAgICBpZihUaGlzLT5jdXJzb3JUZXh0dXJlKSB7CiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICBnbERlbGV0ZVRleHR1cmVzKDEsICZUaGlzLT5jdXJzb3JUZXh0dXJlKTsKICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgIFRoaXMtPmN1cnNvclRleHR1cmUgPSAwOwogICAgfQoKICAgIGZvciAoc2FtcGxlciA9IDA7IHNhbXBsZXIgPCBNQVhfRlJBR01FTlRfU0FNUExFUlM7ICsrc2FtcGxlcikgewogICAgICAgIElXaW5lRDNERGV2aWNlX1NldFRleHR1cmUoaWZhY2UsIHNhbXBsZXIsIE5VTEwpOwogICAgfQogICAgZm9yIChzYW1wbGVyID0gMDsgc2FtcGxlciA8IE1BWF9WRVJURVhfU0FNUExFUlM7ICsrc2FtcGxlcikgewogICAgICAgIElXaW5lRDNERGV2aWNlX1NldFRleHR1cmUoaWZhY2UsIFdJTkVEM0RWRVJURVhURVhUVVJFU0FNUExFUjAgKyBzYW1wbGVyLCBOVUxMKTsKICAgIH0KCiAgICAvKiBSZWxlYXNlIHRoZSB1cGRhdGUgc3RhdGVibG9jayAqLwogICAgaWYoSVdpbmVEM0RTdGF0ZUJsb2NrX1JlbGVhc2UoKElXaW5lRDNEU3RhdGVCbG9jayAqKVRoaXMtPnVwZGF0ZVN0YXRlQmxvY2spID4gMCl7CiAgICAgICAgaWYoVGhpcy0+dXBkYXRlU3RhdGVCbG9jayAhPSBUaGlzLT5zdGF0ZUJsb2NrKQogICAgICAgICAgICBGSVhNRSgiKCVwKSBTb21ldGhpbmcncyBzdGlsbCBob2xkaW5nIHRoZSBVcGRhdGUgc3RhdGVibG9ja1xuIixUaGlzKTsKICAgIH0KICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2sgPSBOVUxMOwoKICAgIHsgLyogYmVjYXVzZSB3ZXJlIG5vdCBkb2luZyBwcm9wZXIgaW50ZXJuYWwgcmVmY291bnRzIHJlbGVhc2luZyB0aGUgcHJpbWFyeSBzdGF0ZSBibG9jawogICAgICAgIGNhdXNlcyByZWN1cnNpb24gd2l0aCB0aGUgZXh0cmEgY2hlY2tzIGluIFJlc291cmNlUmVsZWFzZWQsIHRvIGF2b2lkIHRoaXMgd2UgaGF2ZQogICAgICAgIHRvIHNldCB0aGlzLT5zdGF0ZUJsb2NrID0gTlVMTDsgZmlyc3QgKi8KICAgICAgICBJV2luZUQzRFN0YXRlQmxvY2sgKnN0YXRlQmxvY2sgPSAoSVdpbmVEM0RTdGF0ZUJsb2NrICopVGhpcy0+c3RhdGVCbG9jazsKICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrID0gTlVMTDsKCiAgICAgICAgLyogUmVsZWFzZSB0aGUgc3RhdGVibG9jayAqLwogICAgICAgIGlmKElXaW5lRDNEU3RhdGVCbG9ja19SZWxlYXNlKHN0YXRlQmxvY2spID4gMCl7CiAgICAgICAgICAgIEZJWE1FKCIoJXApIFNvbWV0aGluZydzIHN0aWxsIGhvbGRpbmcgdGhlIFVwZGF0ZSBzdGF0ZWJsb2NrXG4iLFRoaXMpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBSZWxlYXNlIHRoZSBidWZmZXJzICh3aXRoIHNhbml0eSBjaGVja3MpKi8KICAgIFRSQUNFKCJSZWxlYXNpbmcgdGhlIGRlcHRoIHN0ZW5jaWwgYnVmZmVyIGF0ICVwXG4iLCBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KTsKICAgIGlmKFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQgIT0gTlVMTCAmJiAoSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2UoVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCkgPjApKXsKICAgICAgICBpZihUaGlzLT5hdXRvX2RlcHRoX3N0ZW5jaWxfYnVmZmVyICE9IFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQpCiAgICAgICAgICAgIEZJWE1FKCIoJXApIFNvbWV0aGluZydzIHN0aWxsIGhvbGRpbmcgdGhlIHN0ZW5jaWxCdWZmZXJUYXJnZXRcbiIsVGhpcyk7CiAgICB9CiAgICBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0ID0gTlVMTDsKCiAgICBUUkFDRSgiUmVsZWFzaW5nIHRoZSByZW5kZXIgdGFyZ2V0IGF0ICVwXG4iLCBUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXSk7CiAgICBpZihJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXSkgPjApewogICAgICAgICAgLyogVGhpcyBjaGVjayBpcyBhIGJpdCBzaWxseSwgaXRzaG91bGQgYmUgaW4gc3dhcGNoYWluX3JlbGVhc2UgRklYTUUoIiglcCkgU29tZXRoaW5nJ3Mgc3RpbGwgaG9sZGluZyB0aGUgcmVuZGVyVGFyZ2V0XG4iLFRoaXMpOyAqLwogICAgfQogICAgVFJBQ0UoIlNldHRpbmcgcmVuZGVydGFyZ2V0IHRvIE5VTExcbiIpOwogICAgVGhpcy0+cmVuZGVyX3RhcmdldHNbMF0gPSBOVUxMOwoKICAgIGlmIChUaGlzLT5hdXRvX2RlcHRoX3N0ZW5jaWxfYnVmZmVyKSB7CiAgICAgICAgaWYoRDNEQ0JfRGVzdHJveURlcHRoU3RlbmNpbFN1cmZhY2UoVGhpcy0+YXV0b19kZXB0aF9zdGVuY2lsX2J1ZmZlcikgPiAwKSB7CiAgICAgICAgICAgIEZJWE1FKCIoJXApIFNvbWV0aGluZydzIHN0aWxsIGhvbGRpbmcgdGhlIGF1dG8gZGVwdGggc3RlbmNpbCBidWZmZXJcbiIsIFRoaXMpOwogICAgICAgIH0KICAgICAgICBUaGlzLT5hdXRvX2RlcHRoX3N0ZW5jaWxfYnVmZmVyID0gTlVMTDsKICAgIH0KCiAgICBmb3IoaT0wOyBpIDwgVGhpcy0+TnVtYmVyT2ZTd2FwQ2hhaW5zOyBpKyspIHsKICAgICAgICBUUkFDRSgiUmVsZWFzaW5nIHRoZSBpbXBsaWNpdCBzd2FwY2hhaW4gJWRcbiIsIGkpOwogICAgICAgIGlmIChEM0RDQl9EZXN0cm95U3dhcENoYWluKFRoaXMtPnN3YXBjaGFpbnNbaV0pICA+IDApIHsKICAgICAgICAgICAgRklYTUUoIiglcCkgU29tZXRoaW5nJ3Mgc3RpbGwgaG9sZGluZyB0aGUgaW1wbGljaXQgc3dhcGNoYWluXG4iLCBUaGlzKTsKICAgICAgICB9CiAgICB9CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+c3dhcGNoYWlucyk7CiAgICBUaGlzLT5zd2FwY2hhaW5zID0gTlVMTDsKICAgIFRoaXMtPk51bWJlck9mU3dhcENoYWlucyA9IDA7CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cmVuZGVyX3RhcmdldHMpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+ZmJvX2NvbG9yX2F0dGFjaG1lbnRzKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmRyYXdfYnVmZmVycyk7CiAgICBUaGlzLT5yZW5kZXJfdGFyZ2V0cyA9IE5VTEw7CiAgICBUaGlzLT5mYm9fY29sb3JfYXR0YWNobWVudHMgPSBOVUxMOwogICAgVGhpcy0+ZHJhd19idWZmZXJzID0gTlVMTDsKCgogICAgVGhpcy0+ZDNkX2luaXRpYWxpemVkID0gRkFMU0U7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRGdWxsc2NyZWVuKElXaW5lRDNERGV2aWNlICppZmFjZSwgQk9PTCBmdWxsc2NyZWVuKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgVFJBQ0UoIiglcCkgU2V0dGluZyBERHJhdyBmdWxsc2NyZWVuIG1vZGUgdG8gJXNcbiIsIFRoaXMsIGZ1bGxzY3JlZW4gPyAidHJ1ZSIgOiAiZmFsc2UiKTsKCiAgICAvKiBTZXR1cCB0aGUgd2luZG93IGZvciBmdWxsc2NyZWVuIG1vZGUgKi8KICAgIGlmKGZ1bGxzY3JlZW4gJiYgIVRoaXMtPmRkcmF3X2Z1bGxzY3JlZW4pIHsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfU2V0dXBGdWxsc2NyZWVuV2luZG93KGlmYWNlLCBUaGlzLT5kZHJhd193aW5kb3cpOwogICAgfSBlbHNlIGlmKCFmdWxsc2NyZWVuICYmIFRoaXMtPmRkcmF3X2Z1bGxzY3JlZW4pIHsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfUmVzdG9yZVdpbmRvdyhpZmFjZSwgVGhpcy0+ZGRyYXdfd2luZG93KTsKICAgIH0KCiAgICAvKiBEaXJlY3REcmF3IGFwcHMgY2FuIGNoYW5nZSBiZXR3ZWVuIGZ1bGxzY3JlZW4gYW5kIHdpbmRvd2VkIG1vZGUgYWZ0ZXIgZGV2aWNlIGNyZWF0aW9uIHdpdGgKICAgICAqIElEaXJlY3REcmF3Nzo6U2V0Q29vcGVyYXRpdmVMZXZlbC4gVGhlIEdESSBzdXJmYWNlIGltcGxlbWVudGF0aW9uIG5lZWRzIHRvIGtub3cgdGhpcy4KICAgICAqIEREcmF3IGRvZXNuJ3QgbmVjZXNzYXJpbHkgaGF2ZSBhIHN3YXBjaGFpbiwgc28gd2UgaGF2ZSB0byBzdG9yZSB0aGUgZnVsbHNjcmVlbiBmbGFnCiAgICAgKiBzZXBhcmF0ZWx5LgogICAgICovCiAgICBUaGlzLT5kZHJhd19mdWxsc2NyZWVuID0gZnVsbHNjcmVlbjsKfQoKLyogRW5hYmxlcyB0aHJlYWQgc2FmZXR5IGluIHRoZSB3aW5lZDNkIGRldmljZSBhbmQgaXRzIHJlc291cmNlcy4gQ2FsbGVkIGJ5IERpcmVjdERyYXcKICogZnJvbSBTZXRDb29wZXJhdGl2ZUxldmVsIGlmIEREU0NMX01VTFRJVEhSRUFERUQgaXMgc3BlY2lmaWVkLCBhbmQgYnkgZDNkOC85IGZyb20KICogQ3JlYXRlRGV2aWNlIGlmIEQzRENSRUFURV9NVUxUSVRIUkVBREVEIGlzIHBhc3NlZC4KICoKICogVGhlcmUgaXMgbm8gd2F5IHRvIGRlYWN0aXZhdGUgdGhyZWFkIHNhZmV0eSBvbmNlIGl0IGlzIGVuYWJsZWQuCiAqLwpzdGF0aWMgdm9pZCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldE11bHRpdGhyZWFkZWQoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwoKICAgIC8qRm9yIG5vdyBqdXN0IHN0b3JlIHRoZSBmbGFnKG5lZWRlZCBpbiBjYXNlIG9mIGRkcmF3KSAqLwogICAgVGhpcy0+Y3JlYXRlUGFybXMuQmVoYXZpb3JGbGFncyB8PSBXSU5FRDNEQ1JFQVRFX01VTFRJVEhSRUFERUQ7CgogICAgcmV0dXJuOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldERpc3BsYXlNb2RlKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBpU3dhcENoYWluLCBXSU5FRDNERElTUExBWU1PREUqIHBNb2RlKSB7CiAgICBERVZNT0RFVyBkZXZtb2RlOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgTE9ORyByZXQ7CiAgICBjb25zdCBTdGF0aWNQaXhlbEZvcm1hdERlc2MgKmZvcm1hdERlc2MgID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KHBNb2RlLT5Gb3JtYXQsIE5VTEwsIE5VTEwpOwogICAgUkVDVCBjbGlwX3JjOwoKICAgIFRSQUNFKCIoJXApLT4oJWQsJXApIE1vZGU9JWR4JWR4QCVkLCAlc1xuIiwgVGhpcywgaVN3YXBDaGFpbiwgcE1vZGUsIHBNb2RlLT5XaWR0aCwgcE1vZGUtPkhlaWdodCwgcE1vZGUtPlJlZnJlc2hSYXRlLCBkZWJ1Z19kM2Rmb3JtYXQocE1vZGUtPkZvcm1hdCkpOwoKICAgIC8qIFJlc2l6ZSB0aGUgc2NyZWVuIGV2ZW4gd2l0aG91dCBhIHdpbmRvdzoKICAgICAqIFRoZSBhcHAgY291bGQgaGF2ZSB1bnNldCBpdCB3aXRoIFNldENvb3BlcmF0aXZlTGV2ZWwsIGJ1dCBub3QgY2FsbGVkCiAgICAgKiBSZXN0b3JlRGlzcGxheU1vZGUgZmlyc3QuIFRoZW4gdGhlIHJlbGVhc2Ugd2lsbCBjYWxsIFJlc3RvcmVEaXNwbGF5TW9kZSwKICAgICAqIGJ1dCB3ZSBkb24ndCBoYXZlIGFueSBod25kCiAgICAgKi8KCiAgICBtZW1zZXQoJmRldm1vZGUsIDAsIHNpemVvZihkZXZtb2RlKSk7CiAgICBkZXZtb2RlLmRtU2l6ZSA9IHNpemVvZihkZXZtb2RlKTsKICAgIGRldm1vZGUuZG1GaWVsZHMgPSBETV9CSVRTUEVSUEVMIHwgRE1fUEVMU1dJRFRIIHwgRE1fUEVMU0hFSUdIVDsKICAgIGRldm1vZGUuZG1CaXRzUGVyUGVsID0gZm9ybWF0RGVzYy0+YnBwICogODsKICAgIGRldm1vZGUuZG1QZWxzV2lkdGggID0gcE1vZGUtPldpZHRoOwogICAgZGV2bW9kZS5kbVBlbHNIZWlnaHQgPSBwTW9kZS0+SGVpZ2h0OwoKICAgIGRldm1vZGUuZG1EaXNwbGF5RnJlcXVlbmN5ID0gcE1vZGUtPlJlZnJlc2hSYXRlOwogICAgaWYgKHBNb2RlLT5SZWZyZXNoUmF0ZSAhPSAwKSAgewogICAgICAgIGRldm1vZGUuZG1GaWVsZHMgfD0gRE1fRElTUExBWUZSRVFVRU5DWTsKICAgIH0KCiAgICAvKiBPbmx5IGNoYW5nZSB0aGUgbW9kZSBpZiBuZWNlc3NhcnkgKi8KICAgIGlmKCAoVGhpcy0+ZGRyYXdfd2lkdGggPT0gcE1vZGUtPldpZHRoKSAmJgogICAgICAgIChUaGlzLT5kZHJhd19oZWlnaHQgPT0gcE1vZGUtPkhlaWdodCkgJiYKICAgICAgICAoVGhpcy0+ZGRyYXdfZm9ybWF0ID09IHBNb2RlLT5Gb3JtYXQpICYmCiAgICAgICAgKHBNb2RlLT5SZWZyZXNoUmF0ZSA9PSAwKSApIHsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICByZXQgPSBDaGFuZ2VEaXNwbGF5U2V0dGluZ3NFeFcoTlVMTCwgJmRldm1vZGUsIE5VTEwsIENEU19GVUxMU0NSRUVOLCBOVUxMKTsKICAgIGlmIChyZXQgIT0gRElTUF9DSEFOR0VfU1VDQ0VTU0ZVTCkgewogICAgICAgIGlmKGRldm1vZGUuZG1EaXNwbGF5RnJlcXVlbmN5ICE9IDApIHsKICAgICAgICAgICAgV0FSTigiQ2hhbmdlRGlzcGxheVNldHRpbmdzRXhXIGZhaWxlZCwgdHJ5aW5nIHdpdGhvdXQgdGhlIHJlZnJlc2ggcmF0ZVxuIik7CiAgICAgICAgICAgIGRldm1vZGUuZG1GaWVsZHMgJj0gfkRNX0RJU1BMQVlGUkVRVUVOQ1k7CiAgICAgICAgICAgIGRldm1vZGUuZG1EaXNwbGF5RnJlcXVlbmN5ID0gMDsKICAgICAgICAgICAgcmV0ID0gQ2hhbmdlRGlzcGxheVNldHRpbmdzRXhXKE5VTEwsICZkZXZtb2RlLCBOVUxMLCBDRFNfRlVMTFNDUkVFTiwgTlVMTCkgIT0gRElTUF9DSEFOR0VfU1VDQ0VTU0ZVTDsKICAgICAgICB9CiAgICAgICAgaWYocmV0ICE9IERJU1BfQ0hBTkdFX1NVQ0NFU1NGVUwpIHsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfTk9UQVZBSUxBQkxFOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBTdG9yZSB0aGUgbmV3IHZhbHVlcyAqLwogICAgVGhpcy0+ZGRyYXdfd2lkdGggPSBwTW9kZS0+V2lkdGg7CiAgICBUaGlzLT5kZHJhd19oZWlnaHQgPSBwTW9kZS0+SGVpZ2h0OwogICAgVGhpcy0+ZGRyYXdfZm9ybWF0ID0gcE1vZGUtPkZvcm1hdDsKCiAgICAvKiBPbmx5IGRvIHRoaXMgd2l0aCBhIHdpbmRvdyBvZiBjb3Vyc2UgKi8KICAgIGlmKFRoaXMtPmRkcmF3X3dpbmRvdykKICAgICAgTW92ZVdpbmRvdyhUaGlzLT5kZHJhd193aW5kb3csIDAsIDAsIHBNb2RlLT5XaWR0aCwgcE1vZGUtPkhlaWdodCwgVFJVRSk7CgogICAgLyogQW5kIGZpbmFsbHkgY2xpcCBtb3VzZSB0byBvdXIgc2NyZWVuICovCiAgICBTZXRSZWN0KCZjbGlwX3JjLCAwLCAwLCBwTW9kZS0+V2lkdGgsIHBNb2RlLT5IZWlnaHQpOwogICAgQ2xpcEN1cnNvcigmY2xpcF9yYyk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0RGlyZWN0M0QoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRCAqKnBwRDNEKSB7CiAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgKnBwRDNEPSBUaGlzLT53aW5lRDNEOwogICBUUkFDRSgiKCVwKSA6IHdpbmVEM0QgcmV0dXJuaW5nICVwXG4iLCBUaGlzLCAgKnBwRDNEKTsKICAgSVdpbmVEM0RfQWRkUmVmKCpwcEQzRCk7CiAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgVUlOVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldEF2YWlsYWJsZVRleHR1cmVNZW0oSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCkgOiBzaW11bGF0aW5nICVkTUIsIHJldHVybmluZyAlZE1CIGxlZnRcbiIsICBUaGlzLAogICAgICAgICAoVGhpcy0+YWRhcHRlci0+VGV4dHVyZVJhbS8oMTAyNCoxMDI0KSksCiAgICAgICAgICgoVGhpcy0+YWRhcHRlci0+VGV4dHVyZVJhbSAtIFRoaXMtPmFkYXB0ZXItPlVzZWRUZXh0dXJlUmFtKSAvICgxMDI0KjEwMjQpKSk7CiAgICAvKiByZXR1cm4gc2ltdWxhdGVkIHRleHR1cmUgbWVtb3J5IGxlZnQgKi8KICAgIHJldHVybiAoVGhpcy0+YWRhcHRlci0+VGV4dHVyZVJhbSAtIFRoaXMtPmFkYXB0ZXItPlVzZWRUZXh0dXJlUmFtKTsKfQoKCgovKioqKioKICogR2V0IC8gU2V0IEZWRgogKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0RlZGKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgZnZmKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgLyogVXBkYXRlIHRoZSBjdXJyZW50IHN0YXRlIGJsb2NrICovCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLmZ2ZiAgICAgID0gVFJVRTsKCiAgICBpZihUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5mdmYgPT0gZnZmKSB7CiAgICAgICAgVFJBQ0UoIkFwcGxpY2F0aW9uIGlzIHNldHRpbmcgdGhlIG9sZCBmdmYgb3Zlciwgbm90aGluZyB0byBkb1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+ZnZmICAgICAgICAgICAgICA9IGZ2ZjsKICAgIFRSQUNFKCIoJXApIDogRlZGIFNoYWRlciBGVkYgc2V0IHRvICV4XG4iLCBUaGlzLCBmdmYpOwogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1ZERUNMKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRGVkYoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCAqcGZ2ZikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiBHZXRGVkYgcmV0dXJuaW5nICV4XG4iLCBUaGlzLCBUaGlzLT5zdGF0ZUJsb2NrLT5mdmYpOwogICAgKnBmdmYgPSBUaGlzLT5zdGF0ZUJsb2NrLT5mdmY7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBTdHJlYW0gU291cmNlCiAqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRTdHJlYW1Tb3VyY2UoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIFN0cmVhbU51bWJlcixJV2luZUQzRFZlcnRleEJ1ZmZlciogcFN0cmVhbURhdGEsIFVJTlQgT2Zmc2V0SW5CeXRlcywgVUlOVCBTdHJpZGUpIHsKICAgICAgICBJV2luZUQzRERldmljZUltcGwgICAgICAgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFZlcnRleEJ1ZmZlciAgICAgKm9sZFNyYzsKCiAgICBpZiAoU3RyZWFtTnVtYmVyID49IE1BWF9TVFJFQU1TKSB7CiAgICAgICAgV0FSTigiU3RyZWFtIG91dCBvZiByYW5nZSAlZFxuIiwgU3RyZWFtTnVtYmVyKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBvbGRTcmMgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbU3RyZWFtTnVtYmVyXTsKICAgIFRSQUNFKCIoJXApIDogU3RyZWFtTm86ICV1LCBPbGRTdHJlYW0gKCVwKSwgTmV3U3RyZWFtICglcCksIE9mZnNldEluQnl0ZXMgJXUsIE5ld1N0cmlkZSAldVxuIiwgVGhpcywgU3RyZWFtTnVtYmVyLCBvbGRTcmMsIHBTdHJlYW1EYXRhLCBPZmZzZXRJbkJ5dGVzLCBTdHJpZGUpOwoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQuc3RyZWFtU291cmNlW1N0cmVhbU51bWJlcl0gPSBUUlVFOwoKICAgIGlmKG9sZFNyYyA9PSBwU3RyZWFtRGF0YSAmJgogICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c3RyZWFtU3RyaWRlW1N0cmVhbU51bWJlcl0gPT0gU3RyaWRlICYmCiAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1PZmZzZXRbU3RyZWFtTnVtYmVyXSA9PSBPZmZzZXRJbkJ5dGVzKSB7CiAgICAgICBUUkFDRSgiQXBwbGljYXRpb24gaXMgc2V0dGluZyB0aGUgb2xkIHZhbHVlcyBvdmVyLCBub3RoaW5nIHRvIGRvXG4iKTsKICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtTdHJlYW1OdW1iZXJdICAgICAgICAgPSBwU3RyZWFtRGF0YTsKICAgIGlmIChwU3RyZWFtRGF0YSkgewogICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbVN0cmlkZVtTdHJlYW1OdW1iZXJdICAgICA9IFN0cmlkZTsKICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1PZmZzZXRbU3RyZWFtTnVtYmVyXSAgICAgPSBPZmZzZXRJbkJ5dGVzOwogICAgfQoKICAgIC8qIEhhbmRsZSByZWNvcmRpbmcgb2Ygc3RhdGUgYmxvY2tzICovCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgICAgIGlmKHBTdHJlYW1EYXRhKSBJV2luZUQzRFZlcnRleEJ1ZmZlcl9BZGRSZWYocFN0cmVhbURhdGEpOwogICAgICAgIGlmKG9sZFNyYykgSVdpbmVEM0RWZXJ0ZXhCdWZmZXJfUmVsZWFzZShvbGRTcmMpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIC8qIE5lZWQgdG8gZG8gYSBnZXRQYXJlbnQgYW5kIHBhc3MgdGhlIHJlZmZzIHVwICovCiAgICAvKiBNU0ROIHNheXMgLi4uLi4gV2hlbiBhbiBhcHBsaWNhdGlvbiBubyBsb25nZXIgaG9sZHMgYSByZWZlcmVuY2VzIHRvIHRoaXMgaW50ZXJmYWNlLCB0aGUgaW50ZXJmYWNlIHdpbGwgYXV0b21hdGljYWxseSBiZSBmcmVlZC4KICAgIHdoaWNoIHN1Z2dlc3RzIHRoYXQgd2Ugc2hvdWxkbid0IGJlIHJlZiBjb3VudGluZz8gYW5kIGRvIG5lZWQgYSBfcmVsZWFzZSBvbiB0aGUgc3RyZWFtIHNvdXJjZSB0byByZXNldCB0aGUgc3RyZWFtIHNvdXJjZQogICAgc28gZm9yIG5vdywganVzdCBjb3VudCBpbnRlcm5hbGx5ICAgKi8KICAgIGlmIChwU3RyZWFtRGF0YSAhPSBOVUxMKSB7CiAgICAgICAgSVdpbmVEM0RWZXJ0ZXhCdWZmZXJJbXBsICp2YkltcGwgPSAoSVdpbmVEM0RWZXJ0ZXhCdWZmZXJJbXBsICopIHBTdHJlYW1EYXRhOwogICAgICAgIEludGVybG9ja2VkSW5jcmVtZW50KCZ2YkltcGwtPmJpbmRDb3VudCk7CiAgICAgICAgSVdpbmVEM0RWZXJ0ZXhCdWZmZXJfQWRkUmVmKHBTdHJlYW1EYXRhKTsKICAgIH0KICAgIGlmIChvbGRTcmMgIT0gTlVMTCkgewogICAgICAgIEludGVybG9ja2VkRGVjcmVtZW50KCYoKElXaW5lRDNEVmVydGV4QnVmZmVySW1wbCAqKSBvbGRTcmMpLT5iaW5kQ291bnQpOwogICAgICAgIElXaW5lRDNEVmVydGV4QnVmZmVyX1JlbGVhc2Uob2xkU3JjKTsKICAgIH0KCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfU1RSRUFNU1JDKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTdHJlYW1Tb3VyY2UoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIFN0cmVhbU51bWJlcixJV2luZUQzRFZlcnRleEJ1ZmZlcioqIHBTdHJlYW0sIFVJTlQgKnBPZmZzZXQsIFVJTlQqIHBTdHJpZGUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKSA6IFN0cmVhbU5vOiAldSwgU3RyZWFtICglcCksIE9mZnNldCAldSwgU3RyaWRlICV1XG4iLCBUaGlzLCBTdHJlYW1OdW1iZXIsCiAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlW1N0cmVhbU51bWJlcl0sCiAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtT2Zmc2V0W1N0cmVhbU51bWJlcl0sCiAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU3RyaWRlW1N0cmVhbU51bWJlcl0pOwoKICAgIGlmIChTdHJlYW1OdW1iZXIgPj0gTUFYX1NUUkVBTVMpIHsKICAgICAgICBXQVJOKCJTdHJlYW0gb3V0IG9mIHJhbmdlICVkXG4iLCBTdHJlYW1OdW1iZXIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgKnBTdHJlYW0gPSBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbU3RyZWFtTnVtYmVyXTsKICAgICpwU3RyaWRlID0gVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU3RyaWRlW1N0cmVhbU51bWJlcl07CiAgICBpZiAocE9mZnNldCkgewogICAgICAgICpwT2Zmc2V0ID0gVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtT2Zmc2V0W1N0cmVhbU51bWJlcl07CiAgICB9CgogICAgaWYgKCpwU3RyZWFtICE9IE5VTEwpIHsKICAgICAgICBJV2luZUQzRFZlcnRleEJ1ZmZlcl9BZGRSZWYoKnBTdHJlYW0pOyAvKiBXZSBoYXZlIGNyZWF0ZWQgYSBuZXcgcmVmZXJlbmNlIHRvIHRoZSBWQiAqLwogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0U3RyZWFtU291cmNlRnJlcShJV2luZUQzRERldmljZSAqaWZhY2UsICBVSU5UIFN0cmVhbU51bWJlciwgVUlOVCBEaXZpZGVyKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBVSU5UIG9sZEZsYWdzID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c3RyZWFtRmxhZ3NbU3RyZWFtTnVtYmVyXTsKICAgIFVJTlQgb2xkRnJlcSA9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbUZyZXFbU3RyZWFtTnVtYmVyXTsKCiAgICBUUkFDRSgiKCVwKSBTdHJlYW1OdW1iZXIoJWQpLCBEaXZpZGVyKCVkKVxuIiwgVGhpcywgU3RyZWFtTnVtYmVyLCBEaXZpZGVyKTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbUZsYWdzW1N0cmVhbU51bWJlcl0gPSBEaXZpZGVyICYgKFdJTkVEM0RTVFJFQU1TT1VSQ0VfSU5TVEFOQ0VEQVRBICB8IFdJTkVEM0RTVFJFQU1TT1VSQ0VfSU5ERVhFRERBVEEgKTsKCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnN0cmVhbUZyZXFbU3RyZWFtTnVtYmVyXSAgPSBUUlVFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c3RyZWFtRnJlcVtTdHJlYW1OdW1iZXJdICAgICAgICAgID0gRGl2aWRlciAmIDB4N0ZGRkZGOwoKICAgIGlmKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbUZyZXFbU3RyZWFtTnVtYmVyXSAhPSBvbGRGcmVxIHx8CiAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1GbGFnc1tTdHJlYW1OdW1iZXJdICE9IG9sZEZsYWdzKSB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1NUUkVBTVNSQyk7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0U3RyZWFtU291cmNlRnJlcShJV2luZUQzRERldmljZSAqaWZhY2UsICBVSU5UIFN0cmVhbU51bWJlciwgVUlOVCogRGl2aWRlcikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXApIFN0cmVhbU51bWJlciglZCksIERpdmlkZXIoJXApXG4iLCBUaGlzLCBTdHJlYW1OdW1iZXIsIERpdmlkZXIpOwogICAgKkRpdmlkZXIgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1GcmVxW1N0cmVhbU51bWJlcl0gfCBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1GbGFnc1tTdHJlYW1OdW1iZXJdOwoKICAgIFRSQUNFKCIoJXApIDogcmV0dXJuaW5nICVkXG4iLCBUaGlzLCAqRGl2aWRlcik7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBHZXQgLyBTZXQgJiBNdWx0aXBseSBUcmFuc2Zvcm0KICoqKioqLwpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfU2V0VHJhbnNmb3JtKElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRFRSQU5TRk9STVNUQVRFVFlQRSBkM2R0cywgQ09OU1QgV0lORUQzRE1BVFJJWCogbHBtYXRyaXgpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICAvKiBNb3N0IG9mIHRoaXMgcm91dGluZSwgY29tbWVudHMgaW5jbHVkZWQgY29waWVkIGZyb20gZGRyYXcgdHJlZSBpbml0aWFsbHk6ICovCiAgICBUUkFDRSgiKCVwKSA6IFRyYW5zZm9ybSBTdGF0ZT0lc1xuIiwgVGhpcywgZGVidWdfZDNkdHN0eXBlKGQzZHRzKSk7CgogICAgLyogSGFuZGxlIHJlY29yZGluZyBvZiBzdGF0ZSBibG9ja3MgKi8KICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC50cmFuc2Zvcm1bZDNkdHNdID0gVFJVRTsKICAgICAgICBtZW1jcHkoJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRyYW5zZm9ybXNbZDNkdHNdLCBscG1hdHJpeCwgc2l6ZW9mKFdJTkVEM0RNQVRSSVgpKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICAvKgogICAgICogSWYgdGhlIG5ldyBtYXRyaXggaXMgdGhlIHNhbWUgYXMgdGhlIGN1cnJlbnQgb25lLAogICAgICogd2UgY3V0IG9mZiBhbnkgZnVydGhlciBwcm9jZXNzaW5nLiB0aGlzIHNlZW1zIHRvIGJlIGEgcmVhc29uYWJsZQogICAgICogb3B0aW1pemF0aW9uIGJlY2F1c2UgYXMgd2FzIG5vdGljZWQsIHNvbWUgYXBwcyAod2FyY3JhZnQzIGZvciBleGFtcGxlKQogICAgICogdGVuZCB0b3dhcmRzIHNldHRpbmcgdGhlIHNhbWUgbWF0cml4IHJlcGVhdGVkbHkgZm9yIHNvbWUgcmVhc29uLgogICAgICoKICAgICAqIEZyb20gaGVyZSBvbiB3ZSBhc3N1bWUgdGhhdCB0aGUgbmV3IG1hdHJpeCBpcyBkaWZmZXJlbnQsIHdoZXJldmVyIGl0IG1hdHRlcnMuCiAgICAgKi8KICAgIGlmICghbWVtY21wKCZUaGlzLT5zdGF0ZUJsb2NrLT50cmFuc2Zvcm1zW2QzZHRzXS51Lm1bMF1bMF0sIGxwbWF0cml4LCBzaXplb2YoV0lORUQzRE1BVFJJWCkpKSB7CiAgICAgICAgVFJBQ0UoIlRoZSBhcHAgaXMgc2V0dGluZyB0aGUgc2FtZSBtYXRyaXggb3ZlciBhZ2FpblxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9IGVsc2UgewogICAgICAgIGNvbnZfbWF0KGxwbWF0cml4LCAmVGhpcy0+c3RhdGVCbG9jay0+dHJhbnNmb3Jtc1tkM2R0c10udS5tWzBdWzBdKTsKICAgIH0KCiAgICAvKgogICAgICAgU2NyZWVuQ29vcmQgPSBQcm9qZWN0aW9uTWF0ICogVmlld01hdCAqIFdvcmxkTWF0ICogT2JqZWN0Q29vcmQKICAgICAgIHdoZXJlIFZpZXdNYXQgPSBDYW1lcmEgc3BhY2UsIFdvcmxkTWF0ID0gd29ybGQgc3BhY2UuCgogICAgICAgSW4gT3BlbkdMLCBjYW1lcmEgYW5kIHdvcmxkIHNwYWNlIGlzIGNvbWJpbmVkIGludG8gR0xfTU9ERUxWSUVXCiAgICAgICBtYXRyaXguICBUaGUgUHJvamVjdGlvbiBtYXRyaXggc3RheSBwcm9qZWN0aW9uIG1hdHJpeC4KICAgICAqLwoKICAgIC8qIENhcHR1cmUgdGhlIHRpbWVzIHdlIGNhbiBqdXN0IGlnbm9yZSB0aGUgY2hhbmdlIGZvciBub3cgKi8KICAgIGlmIChkM2R0cyA9PSBXSU5FRDNEVFNfVklFVykgeyAvKiBoYW5kbGUgdGhlIFZJRVcgbWF0cmljZSAqLwogICAgICAgIFRoaXMtPnZpZXdfaWRlbnQgPSAhbWVtY21wKGxwbWF0cml4LCBpZGVudGl0eSwgMTYgKiBzaXplb2YoZmxvYXQpKTsKICAgICAgICAvKiBIYW5kbGVkIGJ5IHRoZSBzdGF0ZSBtYW5hZ2VyICovCiAgICB9CgogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1RSQU5TRk9STShkM2R0cykpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cgp9CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0VHJhbnNmb3JtKElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRFRSQU5TRk9STVNUQVRFVFlQRSBTdGF0ZSwgV0lORUQzRE1BVFJJWCogcE1hdHJpeCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiBmb3IgVHJhbnNmb3JtIFN0YXRlICVzXG4iLCBUaGlzLCBkZWJ1Z19kM2R0c3R5cGUoU3RhdGUpKTsKICAgIG1lbWNweShwTWF0cml4LCAmVGhpcy0+c3RhdGVCbG9jay0+dHJhbnNmb3Jtc1tTdGF0ZV0sIHNpemVvZihXSU5FRDNETUFUUklYKSk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9NdWx0aXBseVRyYW5zZm9ybShJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RUUkFOU0ZPUk1TVEFURVRZUEUgU3RhdGUsIENPTlNUIFdJTkVEM0RNQVRSSVgqIHBNYXRyaXgpIHsKICAgIFdJTkVEM0RNQVRSSVggKm1hdCA9IE5VTEw7CiAgICBXSU5FRDNETUFUUklYIHRlbXA7CgogICAgLyogTm90ZTogVXNpbmcgJ3VwZGF0ZVN0YXRlQmxvY2snIHJhdGhlciB0aGFuICdzdGF0ZWJsb2NrJyBpbiB0aGUgY29kZQogICAgICogYmVsb3cgbWVhbnMgaXQgd2lsbCBiZSByZWNvcmRlZCBpbiBhIHN0YXRlIGJsb2NrIGNoYW5nZSwgYnV0IGl0CiAgICAgKiB3b3JrcyByZWdhcmRsZXNzIHdoZXJlIGl0IGlzIHJlY29yZGVkLgogICAgICogSWYgdGhpcyBpcyBmb3VuZCB0byBiZSB3cm9uZywgY2hhbmdlIHRvIFN0YXRlQmxvY2suCiAgICAgKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogRm9yIHN0YXRlICVzXG4iLCBUaGlzLCBkZWJ1Z19kM2R0c3R5cGUoU3RhdGUpKTsKCiAgICBpZiAoU3RhdGUgPCBISUdIRVNUX1RSQU5TRk9STVNUQVRFKQogICAgewogICAgICAgIG1hdCA9ICZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50cmFuc2Zvcm1zW1N0YXRlXTsKICAgIH0gZWxzZSB7CiAgICAgICAgRklYTUUoIlVuaGFuZGxlZCB0cmFuc2Zvcm0gc3RhdGUhIVxuIik7CiAgICB9CgogICAgbXVsdGlwbHlfbWF0cml4KCZ0ZW1wLCBtYXQsIChjb25zdCBXSU5FRDNETUFUUklYICopIHBNYXRyaXgpOwoKICAgIC8qIEFwcGx5IGNoYW5nZSB2aWEgc2V0IHRyYW5zZm9ybSAtIHdpbGwgcmVhcHBseSB0byBlZy4gbGlnaHRzIHRoaXMgd2F5ICovCiAgICByZXR1cm4gSVdpbmVEM0REZXZpY2VJbXBsX1NldFRyYW5zZm9ybShpZmFjZSwgU3RhdGUsICZ0ZW1wKTsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBMaWdodAogKioqKiovCi8qIE5vdGUgbGlnaHRzIGFyZSByZWFsIHNwZWNpYWwgY2FzZXMuIEFsdGhvdWdoIHRoZSBkZXZpY2UgY2FwcyBzdGF0ZSBvbmx5IGVnLiA4IGFyZSBzdXBwb3J0ZWQsCiAgIHlvdSBjYW4gcmVmZXJlbmNlIGFueSBpbmRleGVzIHlvdSB3YW50IGFzIGxvbmcgYXMgdGhhdCBudW1iZXIgbWF4IGFyZSBlbmFibGVkIGF0IGFueQogICBvbmUgcG9pbnQgaW4gdGltZSEgVGhlcmVmb3JlIHNpbmNlIHRoZSBpbmRleGVzIGNhbiBiZSBhbnl0aGluZywgd2UgbmVlZCBhIGhhc2htYXAgb2YgdGhlbS4KICAgSG93ZXZlciwgdGhpcyBjYXVzZXMgc3RhdGVibG9jayBwcm9ibGVtcy4gV2hlbiBjYXB0dXJpbmcgdGhlIHN0YXRlIGJsb2NrLCBJIGR1cGxpY2F0ZSB0aGUgaGFzaG1hcCwKICAgYnV0IHdoZW4gcmVjb3JkaW5nLCBqdXN0IGJ1aWxkIGEgY2hhaW4gcHJldHR5IG11Y2ggb2YgY29tbWFuZHMgdG8gYmUgcmVwbGF5ZWQuICAgICAgICAgICAgICAgICAgKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0TGlnaHQoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBJbmRleCwgQ09OU1QgV0lORUQzRExJR0hUKiBwTGlnaHQpIHsKICAgIGZsb2F0IHJobzsKICAgIFBMSUdIVElORk9FTCAqb2JqZWN0ID0gTlVMTDsKICAgIFVJTlQgSGkgPSBMSUdIVE1BUF9IQVNIRlVOQyhJbmRleCk7CiAgICBzdHJ1Y3QgbGlzdCAqZTsKCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IElkeCglZCksIHBMaWdodCglcCkuIEhhc2ggaW5kZXggaXMgJWRcbiIsIFRoaXMsIEluZGV4LCBwTGlnaHQsIEhpKTsKCiAgICAvKiBDaGVjayB0aGUgcGFyYW1ldGVyIHJhbmdlLiBOZWVkIGZvciBzcGVlZCBtb3N0IHdhbnRlZCBzZXRzIGp1bmsgbGlnaHRzIHdoaWNoIGNvbmZ1c2UKICAgICAqIHRoZSBnbCBkcml2ZXIuCiAgICAgKi8KICAgIGlmKCFwTGlnaHQpIHsKICAgICAgICBXQVJOKCJMaWdodCBwb2ludGVyID0gTlVMTCwgcmV0dXJuaW5nIFdJTkVEM0RFUlJfSU5WQUxJRENBTExcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIHN3aXRjaChwTGlnaHQtPlR5cGUpIHsKICAgICAgICBjYXNlIFdJTkVEM0RMSUdIVF9QT0lOVDoKICAgICAgICBjYXNlIFdJTkVEM0RMSUdIVF9TUE9UOgogICAgICAgIGNhc2UgV0lORUQzRExJR0hUX1BBUkFMTEVMUE9JTlQ6CiAgICAgICAgY2FzZSBXSU5FRDNETElHSFRfR0xTUE9UOgogICAgICAgICAgICAvKiBJbmNvcnJlY3QgYXR0ZW51YXRpb24gdmFsdWVzIGNhbiBjYXVzZSB0aGUgZ2wgZHJpdmVyIHRvIGNyYXNoLiBIYXBwZW5zIHdpdGggTmVlZCBmb3Igc3BlZWQKICAgICAgICAgICAgICogbW9zdCB3YW50ZWQKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmKHBMaWdodC0+QXR0ZW51YXRpb24wIDwgMC4wIHx8IHBMaWdodC0+QXR0ZW51YXRpb24xIDwgMC4wIHx8IHBMaWdodC0+QXR0ZW51YXRpb24yIDwgMC4wKSB7CiAgICAgICAgICAgICAgICBXQVJOKCJBdHRlbnVhdGlvbiBpcyBuZWdhdGl2ZSwgcmV0dXJuaW5nIFdJTkVEM0RFUlJfSU5WQUxJRENBTExcbiIpOwogICAgICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzRExJR0hUX0RJUkVDVElPTkFMOgogICAgICAgICAgICAvKiBJZ25vcmVzIGF0dGVudWF0aW9uICovCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgIFdBUk4oIkxpZ2h0IHR5cGUgb3V0IG9mIHJhbmdlLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgTElTVF9GT1JfRUFDSChlLCAmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+bGlnaHRNYXBbSGldKSB7CiAgICAgICAgb2JqZWN0ID0gTElTVF9FTlRSWShlLCBQTElHSFRJTkZPRUwsIGVudHJ5KTsKICAgICAgICBpZihvYmplY3QtPk9yaWdpbmFsSW5kZXggPT0gSW5kZXgpIGJyZWFrOwogICAgICAgIG9iamVjdCA9IE5VTEw7CiAgICB9CgogICAgaWYoIW9iamVjdCkgewogICAgICAgIFRSQUNFKCJBZGRpbmcgbmV3IGxpZ2h0XG4iKTsKICAgICAgICBvYmplY3QgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKCpvYmplY3QpKTsKICAgICAgICBpZighb2JqZWN0KSB7CiAgICAgICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeSBlcnJvciB3aGVuIGFsbG9jYXRpbmcgYSBsaWdodFxuIik7CiAgICAgICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwogICAgICAgIH0KICAgICAgICBsaXN0X2FkZF9oZWFkKCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5saWdodE1hcFtIaV0sICZvYmplY3QtPmVudHJ5KTsKICAgICAgICBvYmplY3QtPmdsSW5kZXggPSAtMTsKICAgICAgICBvYmplY3QtPk9yaWdpbmFsSW5kZXggPSBJbmRleDsKICAgICAgICBvYmplY3QtPmNoYW5nZWQgPSBUUlVFOwogICAgfQoKICAgIC8qIEluaXRpYWxpemUgdGhlIG9iamVjdCAqLwogICAgVFJBQ0UoIkxpZ2h0ICVkIHNldHRpbmcgdG8gdHlwZSAlZCwgRGlmZnVzZSglZiwlZiwlZiwlZiksIFNwZWN1bGFyKCVmLCVmLCVmLCVmKSwgQW1iaWVudCglZiwlZiwlZiwlZilcbiIsIEluZGV4LCBwTGlnaHQtPlR5cGUsCiAgICAgICAgICBwTGlnaHQtPkRpZmZ1c2UuciwgcExpZ2h0LT5EaWZmdXNlLmcsIHBMaWdodC0+RGlmZnVzZS5iLCBwTGlnaHQtPkRpZmZ1c2UuYSwKICAgICAgICAgIHBMaWdodC0+U3BlY3VsYXIuciwgcExpZ2h0LT5TcGVjdWxhci5nLCBwTGlnaHQtPlNwZWN1bGFyLmIsIHBMaWdodC0+U3BlY3VsYXIuYSwKICAgICAgICAgIHBMaWdodC0+QW1iaWVudC5yLCBwTGlnaHQtPkFtYmllbnQuZywgcExpZ2h0LT5BbWJpZW50LmIsIHBMaWdodC0+QW1iaWVudC5hKTsKICAgIFRSQUNFKCIuLi4gUG9zKCVmLCVmLCVmKSwgRGlybiglZiwlZiwlZilcbiIsIHBMaWdodC0+UG9zaXRpb24ueCwgcExpZ2h0LT5Qb3NpdGlvbi55LCBwTGlnaHQtPlBvc2l0aW9uLnosCiAgICAgICAgICBwTGlnaHQtPkRpcmVjdGlvbi54LCBwTGlnaHQtPkRpcmVjdGlvbi55LCBwTGlnaHQtPkRpcmVjdGlvbi56KTsKICAgIFRSQUNFKCIuLi4gUmFuZ2UoJWYpLCBGYWxsb2ZmKCVmKSwgVGhldGEoJWYpLCBQaGkoJWYpXG4iLCBwTGlnaHQtPlJhbmdlLCBwTGlnaHQtPkZhbGxvZmYsIHBMaWdodC0+VGhldGEsIHBMaWdodC0+UGhpKTsKCiAgICAvKiBTYXZlIGF3YXkgdGhlIGluZm9ybWF0aW9uICovCiAgICBtZW1jcHkoJm9iamVjdC0+T3JpZ2luYWxQYXJtcywgcExpZ2h0LCBzaXplb2YoV0lORUQzRExJR0hUKSk7CgogICAgc3dpdGNoIChwTGlnaHQtPlR5cGUpIHsKICAgIGNhc2UgV0lORUQzRExJR0hUX1BPSU5UOgogICAgICAgIC8qIFBvc2l0aW9uICovCiAgICAgICAgb2JqZWN0LT5saWdodFBvc25bMF0gPSBwTGlnaHQtPlBvc2l0aW9uLng7CiAgICAgICAgb2JqZWN0LT5saWdodFBvc25bMV0gPSBwTGlnaHQtPlBvc2l0aW9uLnk7CiAgICAgICAgb2JqZWN0LT5saWdodFBvc25bMl0gPSBwTGlnaHQtPlBvc2l0aW9uLno7CiAgICAgICAgb2JqZWN0LT5saWdodFBvc25bM10gPSAxLjBmOwogICAgICAgIG9iamVjdC0+Y3V0b2ZmID0gMTgwLjBmOwogICAgICAgIC8qIEZJWE1FOiBSYW5nZSAqLwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lORUQzRExJR0hUX0RJUkVDVElPTkFMOgogICAgICAgIC8qIERpcmVjdGlvbiAqLwogICAgICAgIG9iamVjdC0+bGlnaHRQb3NuWzBdID0gLXBMaWdodC0+RGlyZWN0aW9uLng7CiAgICAgICAgb2JqZWN0LT5saWdodFBvc25bMV0gPSAtcExpZ2h0LT5EaXJlY3Rpb24ueTsKICAgICAgICBvYmplY3QtPmxpZ2h0UG9zblsyXSA9IC1wTGlnaHQtPkRpcmVjdGlvbi56OwogICAgICAgIG9iamVjdC0+bGlnaHRQb3NuWzNdID0gMC4wOwogICAgICAgIG9iamVjdC0+ZXhwb25lbnQgICAgID0gMC4wZjsKICAgICAgICBvYmplY3QtPmN1dG9mZiAgICAgICA9IDE4MC4wZjsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RMSUdIVF9TUE9UOgogICAgICAgIC8qIFBvc2l0aW9uICovCiAgICAgICAgb2JqZWN0LT5saWdodFBvc25bMF0gPSBwTGlnaHQtPlBvc2l0aW9uLng7CiAgICAgICAgb2JqZWN0LT5saWdodFBvc25bMV0gPSBwTGlnaHQtPlBvc2l0aW9uLnk7CiAgICAgICAgb2JqZWN0LT5saWdodFBvc25bMl0gPSBwTGlnaHQtPlBvc2l0aW9uLno7CiAgICAgICAgb2JqZWN0LT5saWdodFBvc25bM10gPSAxLjA7CgogICAgICAgIC8qIERpcmVjdGlvbiAqLwogICAgICAgIG9iamVjdC0+bGlnaHREaXJuWzBdID0gcExpZ2h0LT5EaXJlY3Rpb24ueDsKICAgICAgICBvYmplY3QtPmxpZ2h0RGlyblsxXSA9IHBMaWdodC0+RGlyZWN0aW9uLnk7CiAgICAgICAgb2JqZWN0LT5saWdodERpcm5bMl0gPSBwTGlnaHQtPkRpcmVjdGlvbi56OwogICAgICAgIG9iamVjdC0+bGlnaHREaXJuWzNdID0gMS4wOwoKICAgICAgICAvKgogICAgICAgICAqIG9wZW5nbC1pc2ggYW5kIGQzZC1pc2ggc3BvdCBsaWdodHMgdXNlIHRvbyBkaWZmZXJlbnQgbW9kZWxzIGZvciB0aGUKICAgICAgICAgKiBsaWdodCAiaW50ZW5zaXR5IiBhcyBhIGZ1bmN0aW9uIG9mIHRoZSBhbmdsZSB0b3dhcmRzIHRoZSBtYWluIGxpZ2h0IGRpcmVjdGlvbiwKICAgICAgICAgKiBzbyB3ZSBvbmx5IGNhbiBhcHByb3hpbWF0ZSB2ZXJ5IHJvdWdobHkuCiAgICAgICAgICogaG93ZXZlciBzcG90IGxpZ2h0cyBhcmUgcmF0aGVyIHJhcmVseSB1c2VkIGluIGdhbWVzIChpZiBldmVyIHVzZWQgYXQgYWxsKS4KICAgICAgICAgKiBmdXJ0aGVybW9yZSBpZiBzdGlsbCB1c2VkLCBwcm9iYWJseSBub2JvZHkgcGF5cyBhdHRlbnRpb24gdG8gc3VjaCBkZXRhaWxzLgogICAgICAgICAqLwogICAgICAgIGlmIChwTGlnaHQtPkZhbGxvZmYgPT0gMCkgewogICAgICAgICAgICAvKiBGYWxsb2ZmID0gMCBpcyBlYXN5LCBiZWNhdXNlIGQzZCdzIGFuZCBvcGVuZ2wncyBzcG90IGxpZ2h0IGVxdWF0aW9ucyBoYXZlIHRoZQogICAgICAgICAgICAgKiBmYWxsb2ZmIHJlc3AuIGV4cG9uZW50IHBhcmFtZXRlciBhcyBhbiBleHBvbmVudCwgc28gdGhlIHNwb3QgbGlnaHQgbGlnaHRpbmcKICAgICAgICAgICAgICogd2lsbCBhbHdheXMgYmUgMS4wIGZvciBib3RoIG9mIHRoZW0sIGFuZCB3ZSBkb24ndCBoYXZlIHRvIGNhcmUgZm9yIHRoZQogICAgICAgICAgICAgKiByZXN0IG9mIHRoZSByYXRoZXIgY29tcGxleCBjYWxjdWxhdGlvbgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgb2JqZWN0LT5leHBvbmVudCA9IDA7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmhvID0gcExpZ2h0LT5UaGV0YSArIChwTGlnaHQtPlBoaSAtIHBMaWdodC0+VGhldGEpLygyKnBMaWdodC0+RmFsbG9mZik7CiAgICAgICAgICAgIGlmIChyaG8gPCAwLjAwMDEpIHJobyA9IDAuMDAwMWY7CiAgICAgICAgICAgIG9iamVjdC0+ZXhwb25lbnQgPSAtMC4zL2xvZyhjb3MocmhvLzIpKTsKICAgICAgICB9CglpZiAob2JqZWN0LT5leHBvbmVudCA+IDEyOC4wKSB7CgkJb2JqZWN0LT5leHBvbmVudCA9IDEyOC4wOwoJfQogICAgICAgIG9iamVjdC0+Y3V0b2ZmID0gcExpZ2h0LT5QaGkqOTAvTV9QSTsKCiAgICAgICAgLyogRklYTUU6IFJhbmdlICovCiAgICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgICBGSVhNRSgiVW5yZWNvZ25pemVkIGxpZ2h0IHR5cGUgJWRcbiIsIHBMaWdodC0+VHlwZSk7CiAgICB9CgogICAgLyogVXBkYXRlIHRoZSBsaXZlIGRlZmluaXRpb25zIGlmIHRoZSBsaWdodCBpcyBjdXJyZW50bHkgYXNzaWduZWQgYSBnbEluZGV4ICovCiAgICBpZiAob2JqZWN0LT5nbEluZGV4ICE9IC0xICYmICFUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX0FDVElWRUxJR0hUKG9iamVjdC0+Z2xJbmRleCkpOwogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0TGlnaHQoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBJbmRleCwgV0lORUQzRExJR0hUKiBwTGlnaHQpIHsKICAgIFBMSUdIVElORk9FTCAqbGlnaHRJbmZvID0gTlVMTDsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIERXT1JEIEhpID0gTElHSFRNQVBfSEFTSEZVTkMoSW5kZXgpOwogICAgc3RydWN0IGxpc3QgKmU7CiAgICBUUkFDRSgiKCVwKSA6IElkeCglZCksIHBMaWdodCglcClcbiIsIFRoaXMsIEluZGV4LCBwTGlnaHQpOwoKICAgIExJU1RfRk9SX0VBQ0goZSwgJlRoaXMtPnN0YXRlQmxvY2stPmxpZ2h0TWFwW0hpXSkgewogICAgICAgIGxpZ2h0SW5mbyA9IExJU1RfRU5UUlkoZSwgUExJR0hUSU5GT0VMLCBlbnRyeSk7CiAgICAgICAgaWYobGlnaHRJbmZvLT5PcmlnaW5hbEluZGV4ID09IEluZGV4KSBicmVhazsKICAgICAgICBsaWdodEluZm8gPSBOVUxMOwogICAgfQoKICAgIGlmIChsaWdodEluZm8gPT0gTlVMTCkgewogICAgICAgIFRSQUNFKCJMaWdodCBpbmZvcm1hdGlvbiByZXF1ZXN0ZWQgYnV0IGxpZ2h0IG5vdCBkZWZpbmVkXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBtZW1jcHkocExpZ2h0LCAmbGlnaHRJbmZvLT5PcmlnaW5hbFBhcm1zLCBzaXplb2YoV0lORUQzRExJR0hUKSk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBMaWdodCBFbmFibGUKICogICAoTm90ZSBmb3IgY29uc2lzdGVuY3ksIHJlbmFtZWQgZDNkeCBmdW5jdGlvbiBieSBhZGRpbmcgdGhlICdzZXQnIHByZWZpeCkKICoqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldExpZ2h0RW5hYmxlKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgSW5kZXgsIEJPT0wgRW5hYmxlKSB7CiAgICBQTElHSFRJTkZPRUwgKmxpZ2h0SW5mbyA9IE5VTEw7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBVSU5UIEhpID0gTElHSFRNQVBfSEFTSEZVTkMoSW5kZXgpOwogICAgc3RydWN0IGxpc3QgKmU7CiAgICBUUkFDRSgiKCVwKSA6IElkeCglZCksIGVuYWJsZT8gJWRcbiIsIFRoaXMsIEluZGV4LCBFbmFibGUpOwoKICAgIC8qIFRlc3RzIHNob3cgdHJ1ZSA9IDEyOC4uLm5vdCBjbGVhciB3aHkgKi8KICAgIEVuYWJsZSA9IEVuYWJsZT8gMTI4OiAwOwoKICAgIExJU1RfRk9SX0VBQ0goZSwgJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmxpZ2h0TWFwW0hpXSkgewogICAgICAgIGxpZ2h0SW5mbyA9IExJU1RfRU5UUlkoZSwgUExJR0hUSU5GT0VMLCBlbnRyeSk7CiAgICAgICAgaWYobGlnaHRJbmZvLT5PcmlnaW5hbEluZGV4ID09IEluZGV4KSBicmVhazsKICAgICAgICBsaWdodEluZm8gPSBOVUxMOwogICAgfQogICAgVFJBQ0UoIkZvdW5kIGxpZ2h0OiAlcFxuIiwgbGlnaHRJbmZvKTsKCiAgICAvKiBTcGVjaWFsIGNhc2UgLSBlbmFibGluZyBhbiB1bmRlZmluZWQgbGlnaHQgY3JlYXRlcyBvbmUgd2l0aCBhIHN0cmljdCBzZXQgb2YgcGFybXMhICovCiAgICBpZiAobGlnaHRJbmZvID09IE5VTEwpIHsKCiAgICAgICAgVFJBQ0UoIkxpZ2h0IGVuYWJsZWQgcmVxdWVzdGVkIGJ1dCBsaWdodCBub3QgZGVmaW5lZCwgc28gZGVmaW5pbmcgb25lIVxuIik7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldExpZ2h0KGlmYWNlLCBJbmRleCwgJldJTkVEM0RfZGVmYXVsdF9saWdodCk7CgogICAgICAgIC8qIFNlYXJjaCBmb3IgaXQgYWdhaW4hIFNob3VsZCBiZSBmYWlybHkgcXVpY2sgYXMgbmVhciBoZWFkIG9mIGxpc3QgKi8KICAgICAgICBMSVNUX0ZPUl9FQUNIKGUsICZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5saWdodE1hcFtIaV0pIHsKICAgICAgICAgICAgbGlnaHRJbmZvID0gTElTVF9FTlRSWShlLCBQTElHSFRJTkZPRUwsIGVudHJ5KTsKICAgICAgICAgICAgaWYobGlnaHRJbmZvLT5PcmlnaW5hbEluZGV4ID09IEluZGV4KSBicmVhazsKICAgICAgICAgICAgbGlnaHRJbmZvID0gTlVMTDsKICAgICAgICB9CiAgICAgICAgaWYgKGxpZ2h0SW5mbyA9PSBOVUxMKSB7CiAgICAgICAgICAgIEZJWE1FKCJBZGRpbmcgZGVmYXVsdCBsaWdodHMgaGFzIGZhaWxlZCBkaXNtYWxseVxuIik7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgIH0KICAgIH0KCiAgICBsaWdodEluZm8tPmVuYWJsZWRDaGFuZ2VkID0gVFJVRTsKICAgIGlmKCFFbmFibGUpIHsKICAgICAgICBpZihsaWdodEluZm8tPmdsSW5kZXggIT0gLTEpIHsKICAgICAgICAgICAgaWYoIVRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9BQ1RJVkVMSUdIVChsaWdodEluZm8tPmdsSW5kZXgpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+YWN0aXZlTGlnaHRzW2xpZ2h0SW5mby0+Z2xJbmRleF0gPSBOVUxMOwogICAgICAgICAgICBsaWdodEluZm8tPmdsSW5kZXggPSAtMTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBUUkFDRSgiTGlnaHQgYWxyZWFkeSBkaXNhYmxlZCwgbm90aGluZyB0byBkb1xuIik7CiAgICAgICAgfQogICAgICAgIGxpZ2h0SW5mby0+ZW5hYmxlZCA9IEZBTFNFOwogICAgfSBlbHNlIHsKICAgICAgICBsaWdodEluZm8tPmVuYWJsZWQgPSBUUlVFOwogICAgICAgIGlmIChsaWdodEluZm8tPmdsSW5kZXggIT0gLTEpIHsKICAgICAgICAgICAgLyogbm9wICovCiAgICAgICAgICAgIFRSQUNFKCJOb3RoaW5nIHRvIGRvIGFzIGxpZ2h0IHdhcyBlbmFibGVkXG4iKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpbnQgaTsKICAgICAgICAgICAgLyogRmluZCBhIGZyZWUgZ2wgbGlnaHQgKi8KICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDwgVGhpcy0+bWF4Q29uY3VycmVudExpZ2h0czsgaSsrKSB7CiAgICAgICAgICAgICAgICBpZihUaGlzLT5zdGF0ZUJsb2NrLT5hY3RpdmVMaWdodHNbaV0gPT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPmFjdGl2ZUxpZ2h0c1tpXSA9IGxpZ2h0SW5mbzsKICAgICAgICAgICAgICAgICAgICBsaWdodEluZm8tPmdsSW5kZXggPSBpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKGxpZ2h0SW5mby0+Z2xJbmRleCA9PSAtMSkgewogICAgICAgICAgICAgICAgLyogT3VyIHRlc3RzIHNob3cgdGhhdCBXaW5kb3dzIHJldHVybnMgRDNEX09LIGluIHRoaXMgc2l0dWF0aW9uLCBldmVuIHdpdGgKICAgICAgICAgICAgICAgICAqIEQzRENSRUFURV9IQVJEV0FSRV9WRVJURVhQUk9DRVNTSU5HIHwgRDNEQ1JFQVRFX1BVUkVERVZJQ0UgZGV2aWNlcy4gVGhpcwogICAgICAgICAgICAgICAgICogaXMgY29uc2lzdGVudCBhbW9uZyBkZHJhdywgZDNkOCBhbmQgZDNkOS4gR2V0TGlnaHRFbmFibGUgcmV0dXJucyBUUlVFCiAgICAgICAgICAgICAgICAgKiBhcyB3ZWxsIGZvciB0aG9zZSBsaWdodHMuCiAgICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAgICogVE9ETzogVGVzdCBob3cgdGhpcyBhZmZlY3RzIHJlbmRlcmluZwogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBGSVhNRSgiVG9vIG1hbnkgY29uY3VycmVudGx5IGFjdGl2ZSBsaWdodHNcbiIpOwogICAgICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIGkgPT0gbGlnaHRJbmZvLT5nbEluZGV4ICovCiAgICAgICAgICAgIGlmKCFUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfQUNUSVZFTElHSFQoaSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldExpZ2h0RW5hYmxlKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgSW5kZXgsQk9PTCogcEVuYWJsZSkgewoKICAgIFBMSUdIVElORk9FTCAqbGlnaHRJbmZvID0gTlVMTDsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIHN0cnVjdCBsaXN0ICplOwogICAgVUlOVCBIaSA9IExJR0hUTUFQX0hBU0hGVU5DKEluZGV4KTsKICAgIFRSQUNFKCIoJXApIDogZm9yIGlkeCglZClcbiIsIFRoaXMsIEluZGV4KTsKCiAgICBMSVNUX0ZPUl9FQUNIKGUsICZUaGlzLT5zdGF0ZUJsb2NrLT5saWdodE1hcFtIaV0pIHsKICAgICAgICBsaWdodEluZm8gPSBMSVNUX0VOVFJZKGUsIFBMSUdIVElORk9FTCwgZW50cnkpOwogICAgICAgIGlmKGxpZ2h0SW5mby0+T3JpZ2luYWxJbmRleCA9PSBJbmRleCkgYnJlYWs7CiAgICAgICAgbGlnaHRJbmZvID0gTlVMTDsKICAgIH0KCiAgICBpZiAobGlnaHRJbmZvID09IE5VTEwpIHsKICAgICAgICBUUkFDRSgiTGlnaHQgZW5hYmxlZCBzdGF0ZSByZXF1ZXN0ZWQgYnV0IGxpZ2h0IG5vdCBkZWZpbmVkXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIC8qIHRydWUgaXMgMTI4IGFjY29yZGluZyB0byBTZXRMaWdodEVuYWJsZSAqLwogICAgKnBFbmFibGUgPSBsaWdodEluZm8tPmVuYWJsZWQgPyAxMjggOiAwOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBHZXQgLyBTZXQgQ2xpcCBQbGFuZXMKICoqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldENsaXBQbGFuZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIEluZGV4LCBDT05TVCBmbG9hdCAqcFBsYW5lKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IGZvciBpZHggJWQsICVwXG4iLCBUaGlzLCBJbmRleCwgcFBsYW5lKTsKCiAgICAvKiBWYWxpZGF0ZSBJbmRleCAqLwogICAgaWYgKEluZGV4ID49IEdMX0xJTUlUUyhjbGlwcGxhbmVzKSkgewogICAgICAgIFRSQUNFKCJBcHBsaWNhdGlvbiBoYXMgcmVxdWVzdGVkIGNsaXBwbGFuZSB0aGlzIGRldmljZSBkb2Vzbid0IHN1cHBvcnRcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQuY2xpcHBsYW5lW0luZGV4XSA9IFRSVUU7CgogICAgaWYoVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2xpcHBsYW5lW0luZGV4XVswXSA9PSBwUGxhbmVbMF0gJiYKICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNsaXBwbGFuZVtJbmRleF1bMV0gPT0gcFBsYW5lWzFdICYmCiAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jbGlwcGxhbmVbSW5kZXhdWzJdID09IHBQbGFuZVsyXSAmJgogICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2xpcHBsYW5lW0luZGV4XVszXSA9PSBwUGxhbmVbM10pIHsKICAgICAgICBUUkFDRSgiQXBwbGljYXRpb24gaXMgc2V0dGluZyBvbGQgdmFsdWVzIG92ZXIsIG5vdGhpbmcgdG8gZG9cbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNsaXBwbGFuZVtJbmRleF1bMF0gPSBwUGxhbmVbMF07CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jbGlwcGxhbmVbSW5kZXhdWzFdID0gcFBsYW5lWzFdOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2xpcHBsYW5lW0luZGV4XVsyXSA9IHBQbGFuZVsyXTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNsaXBwbGFuZVtJbmRleF1bM10gPSBwUGxhbmVbM107CgogICAgLyogSGFuZGxlIHJlY29yZGluZyBvZiBzdGF0ZSBibG9ja3MgKi8KICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX0NMSVBQTEFORShJbmRleCkpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldENsaXBQbGFuZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIEluZGV4LCBmbG9hdCAqcFBsYW5lKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IGZvciBpZHggJWRcbiIsIFRoaXMsIEluZGV4KTsKCiAgICAvKiBWYWxpZGF0ZSBJbmRleCAqLwogICAgaWYgKEluZGV4ID49IEdMX0xJTUlUUyhjbGlwcGxhbmVzKSkgewogICAgICAgIFRSQUNFKCJBcHBsaWNhdGlvbiBoYXMgcmVxdWVzdGVkIGNsaXBwbGFuZSB0aGlzIGRldmljZSBkb2Vzbid0IHN1cHBvcnRcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIHBQbGFuZVswXSA9IFRoaXMtPnN0YXRlQmxvY2stPmNsaXBwbGFuZVtJbmRleF1bMF07CiAgICBwUGxhbmVbMV0gPSBUaGlzLT5zdGF0ZUJsb2NrLT5jbGlwcGxhbmVbSW5kZXhdWzFdOwogICAgcFBsYW5lWzJdID0gVGhpcy0+c3RhdGVCbG9jay0+Y2xpcHBsYW5lW0luZGV4XVsyXTsKICAgIHBQbGFuZVszXSA9IFRoaXMtPnN0YXRlQmxvY2stPmNsaXBwbGFuZVtJbmRleF1bM107CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBDbGlwIFBsYW5lIFN0YXR1cwogKiAgIFdBUk5JTkc6IFRoaXMgY29kZSByZWxpZXMgb24gdGhlIGZhY3QgdGhhdCBEM0RDTElQU1RBVFVTOCA9PSBEM0RDTElQU1RBVFVTOQogKioqKiovCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRDbGlwU3RhdHVzKElXaW5lRDNERGV2aWNlICppZmFjZSwgQ09OU1QgV0lORUQzRENMSVBTVEFUVVMqIHBDbGlwU3RhdHVzKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBGSVhNRSgiKCVwKSA6IHN0dWJcbiIsIFRoaXMpOwogICAgaWYgKE5VTEwgPT0gcENsaXBTdGF0dXMpIHsKICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jbGlwX3N0YXR1cy5DbGlwVW5pb24gPSBwQ2xpcFN0YXR1cy0+Q2xpcFVuaW9uOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2xpcF9zdGF0dXMuQ2xpcEludGVyc2VjdGlvbiA9IHBDbGlwU3RhdHVzLT5DbGlwSW50ZXJzZWN0aW9uOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRDbGlwU3RhdHVzKElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRENMSVBTVEFUVVMqIHBDbGlwU3RhdHVzKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBGSVhNRSgiKCVwKSA6IHN0dWJcbiIsIFRoaXMpOwogICAgaWYgKE5VTEwgPT0gcENsaXBTdGF0dXMpIHsKICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICBwQ2xpcFN0YXR1cy0+Q2xpcFVuaW9uID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2xpcF9zdGF0dXMuQ2xpcFVuaW9uOwogICAgcENsaXBTdGF0dXMtPkNsaXBJbnRlcnNlY3Rpb24gPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jbGlwX3N0YXR1cy5DbGlwSW50ZXJzZWN0aW9uOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBHZXQgLyBTZXQgTWF0ZXJpYWwKICoqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldE1hdGVyaWFsKElXaW5lRDNERGV2aWNlICppZmFjZSwgQ09OU1QgV0lORUQzRE1BVEVSSUFMKiBwTWF0ZXJpYWwpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLm1hdGVyaWFsID0gVFJVRTsKICAgIG1lbWNweSgmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+bWF0ZXJpYWwsIHBNYXRlcmlhbCwgc2l6ZW9mKFdJTkVEM0RNQVRFUklBTCkpOwoKICAgIC8qIEhhbmRsZSByZWNvcmRpbmcgb2Ygc3RhdGUgYmxvY2tzICovCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9NQVRFUklBTCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRNYXRlcmlhbChJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RNQVRFUklBTCogcE1hdGVyaWFsKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBtZW1jcHkocE1hdGVyaWFsLCAmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+bWF0ZXJpYWwsIHNpemVvZiAoV0lORUQzRE1BVEVSSUFMKSk7CiAgICBUUkFDRSgiKCVwKSA6IERpZmZ1c2UgKCVmLCVmLCVmLCVmKVxuIiwgVGhpcywgcE1hdGVyaWFsLT5EaWZmdXNlLnIsIHBNYXRlcmlhbC0+RGlmZnVzZS5nLAogICAgICAgIHBNYXRlcmlhbC0+RGlmZnVzZS5iLCBwTWF0ZXJpYWwtPkRpZmZ1c2UuYSk7CiAgICBUUkFDRSgiKCVwKSA6IEFtYmllbnQgKCVmLCVmLCVmLCVmKVxuIiwgVGhpcywgcE1hdGVyaWFsLT5BbWJpZW50LnIsIHBNYXRlcmlhbC0+QW1iaWVudC5nLAogICAgICAgIHBNYXRlcmlhbC0+QW1iaWVudC5iLCBwTWF0ZXJpYWwtPkFtYmllbnQuYSk7CiAgICBUUkFDRSgiKCVwKSA6IFNwZWN1bGFyICglZiwlZiwlZiwlZilcbiIsIFRoaXMsIHBNYXRlcmlhbC0+U3BlY3VsYXIuciwgcE1hdGVyaWFsLT5TcGVjdWxhci5nLAogICAgICAgIHBNYXRlcmlhbC0+U3BlY3VsYXIuYiwgcE1hdGVyaWFsLT5TcGVjdWxhci5hKTsKICAgIFRSQUNFKCIoJXApIDogRW1pc3NpdmUgKCVmLCVmLCVmLCVmKVxuIiwgVGhpcywgcE1hdGVyaWFsLT5FbWlzc2l2ZS5yLCBwTWF0ZXJpYWwtPkVtaXNzaXZlLmcsCiAgICAgICAgcE1hdGVyaWFsLT5FbWlzc2l2ZS5iLCBwTWF0ZXJpYWwtPkVtaXNzaXZlLmEpOwogICAgVFJBQ0UoIiglcCkgOiBQb3dlciAoJWYpXG4iLCBUaGlzLCBwTWF0ZXJpYWwtPlBvd2VyKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBJbmRpY2VzCiAqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRJbmRpY2VzKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RJbmRleEJ1ZmZlciogcEluZGV4RGF0YSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNESW5kZXhCdWZmZXIgKm9sZElkeHM7CgogICAgVFJBQ0UoIiglcCkgOiBTZXR0aW5nIHRvICVwXG4iLCBUaGlzLCBwSW5kZXhEYXRhKTsKICAgIG9sZElkeHMgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5wSW5kZXhEYXRhOwoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQuaW5kaWNlcyA9IFRSVUU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5wSW5kZXhEYXRhID0gcEluZGV4RGF0YTsKCiAgICAvKiBIYW5kbGUgcmVjb3JkaW5nIG9mIHN0YXRlIGJsb2NrcyAqLwogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICBpZihwSW5kZXhEYXRhKSBJV2luZUQzREluZGV4QnVmZmVyX0FkZFJlZihwSW5kZXhEYXRhKTsKICAgICAgICBpZihvbGRJZHhzKSBJV2luZUQzREluZGV4QnVmZmVyX1JlbGVhc2Uob2xkSWR4cyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgaWYob2xkSWR4cyAhPSBwSW5kZXhEYXRhKSB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX0lOREVYQlVGRkVSKTsKICAgICAgICBpZihwSW5kZXhEYXRhKSBJV2luZUQzREluZGV4QnVmZmVyX0FkZFJlZihwSW5kZXhEYXRhKTsKICAgICAgICBpZihvbGRJZHhzKSBJV2luZUQzREluZGV4QnVmZmVyX1JlbGVhc2Uob2xkSWR4cyk7CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRJbmRpY2VzKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RJbmRleEJ1ZmZlcioqIHBwSW5kZXhEYXRhKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgKnBwSW5kZXhEYXRhID0gVGhpcy0+c3RhdGVCbG9jay0+cEluZGV4RGF0YTsKCiAgICAvKiB1cCByZWYgY291bnQgb24gcHBpbmRleGRhdGEgKi8KICAgIGlmICgqcHBJbmRleERhdGEpIHsKICAgICAgICBJV2luZUQzREluZGV4QnVmZmVyX0FkZFJlZigqcHBJbmRleERhdGEpOwogICAgICAgIFRSQUNFKCIoJXApIGluZGV4IGRhdGEgc2V0IHRvICVwXG4iLCBUaGlzLCBwcEluZGV4RGF0YSk7CiAgICB9ZWxzZXsKICAgICAgICBUUkFDRSgiKCVwKSBObyBpbmRleCBkYXRhIHNldFxuIiwgVGhpcyk7CiAgICB9CiAgICBUUkFDRSgiUmV0dXJuaW5nICVwXG4iLCAqcHBJbmRleERhdGEpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKiBNZXRob2QgdG8gb2ZmZXIgZDNkOSBhIHNpbXBsZSB3YXkgdG8gc2V0IHRoZSBiYXNlIHZlcnRleCBpbmRleCB3aXRob3V0IG1lc3Npbmcgd2l0aCB0aGUgaW5kZXggYnVmZmVyICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0QmFzZVZlcnRleEluZGV4KElXaW5lRDNERGV2aWNlICppZmFjZSwgSU5UIEJhc2VJbmRleCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCktPiglZClcbiIsIFRoaXMsIEJhc2VJbmRleCk7CgogICAgaWYoVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+YmFzZVZlcnRleEluZGV4ID09IEJhc2VJbmRleCkgewogICAgICAgIFRSQUNFKCJBcHBsaWNhdGlvbiBpcyBzZXR0aW5nIHRoZSBvbGQgdmFsdWUgb3Zlciwgbm90aGluZyB0byBkb1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+YmFzZVZlcnRleEluZGV4ID0gQmFzZUluZGV4OwoKICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CiAgICAvKiBUaGUgYmFzZSB2ZXJ0ZXggaW5kZXggYWZmZWN0cyB0aGUgc3RyZWFtIHNvdXJjZXMgKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TVFJFQU1TUkMpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0QmFzZVZlcnRleEluZGV4KElXaW5lRDNERGV2aWNlICppZmFjZSwgSU5UKiBiYXNlX2luZGV4KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IGJhc2VfaW5kZXggJXBcbiIsIFRoaXMsIGJhc2VfaW5kZXgpOwoKICAgICpiYXNlX2luZGV4ID0gVGhpcy0+c3RhdGVCbG9jay0+YmFzZVZlcnRleEluZGV4OwoKICAgIFRSQUNFKCJSZXR1cm5pbmcgJXVcbiIsICpiYXNlX2luZGV4KTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBWaWV3cG9ydHMKICoqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZpZXdwb3J0KElXaW5lRDNERGV2aWNlICppZmFjZSwgQ09OU1QgV0lORUQzRFZJRVdQT1JUKiBwVmlld3BvcnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnZpZXdwb3J0ID0gVFJVRTsKICAgIG1lbWNweSgmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dmlld3BvcnQsIHBWaWV3cG9ydCwgc2l6ZW9mKFdJTkVEM0RWSUVXUE9SVCkpOwoKICAgIC8qIEhhbmRsZSByZWNvcmRpbmcgb2Ygc3RhdGUgYmxvY2tzICovCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIFRSQUNFKCIoJXApIDogeD0lZCwgeT0lZCwgd2lkPSVkLCBoZWk9JWQsIG1pbno9JWYsIG1heHo9JWZcbiIsIFRoaXMsCiAgICAgICAgICBwVmlld3BvcnQtPlgsIHBWaWV3cG9ydC0+WSwgcFZpZXdwb3J0LT5XaWR0aCwgcFZpZXdwb3J0LT5IZWlnaHQsIHBWaWV3cG9ydC0+TWluWiwgcFZpZXdwb3J0LT5NYXhaKTsKCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVklFV1BPUlQpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cgp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZpZXdwb3J0KElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRFZJRVdQT1JUKiBwVmlld3BvcnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKICAgIG1lbWNweShwVmlld3BvcnQsICZUaGlzLT5zdGF0ZUJsb2NrLT52aWV3cG9ydCwgc2l6ZW9mKFdJTkVEM0RWSUVXUE9SVCkpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBHZXQgLyBTZXQgUmVuZGVyIFN0YXRlcwogKiBUT0RPOiBWZXJpZnkgYWdhaW5zdCBkeDkgZGVmaW5pdGlvbnMKICoqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFJlbmRlclN0YXRlKElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRFJFTkRFUlNUQVRFVFlQRSBTdGF0ZSwgRFdPUkQgVmFsdWUpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgICpUaGlzICAgICA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIERXT1JEIG9sZFZhbHVlID0gVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbU3RhdGVdOwoKICAgIFRSQUNFKCIoJXApLT5zdGF0ZSA9ICVzKCVkKSwgdmFsdWUgPSAlZFxuIiwgVGhpcywgZGVidWdfZDNkcmVuZGVyc3RhdGUoU3RhdGUpLCBTdGF0ZSwgVmFsdWUpOwoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQucmVuZGVyU3RhdGVbU3RhdGVdID0gVFJVRTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1N0YXRlXSA9IFZhbHVlOwoKICAgIC8qIEhhbmRsZSByZWNvcmRpbmcgb2Ygc3RhdGUgYmxvY2tzICovCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIC8qIENvbXBhcmVkIGhlcmUgYW5kIG5vdCBiZWZvcmUgdGhlIGFzc2lnbm1lbnQgdG8gYWxsb3cgcHJvcGVyIHN0YXRlYmxvY2sgcmVjb3JkaW5nICovCiAgICBpZihWYWx1ZSA9PSBvbGRWYWx1ZSkgewogICAgICAgIFRSQUNFKCJBcHBsaWNhdGlvbiBpcyBzZXR0aW5nIHRoZSBvbGQgdmFsdWUgb3Zlciwgbm90aGluZyB0byBkb1xuIik7CiAgICB9IGVsc2UgewogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9SRU5ERVIoU3RhdGUpKTsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRSZW5kZXJTdGF0ZShJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RSRU5ERVJTVEFURVRZUEUgU3RhdGUsIERXT1JEICpwVmFsdWUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIGZvciBTdGF0ZSAlZCA9ICVkXG4iLCBUaGlzLCBTdGF0ZSwgVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbU3RhdGVdKTsKICAgICpwVmFsdWUgPSBUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtTdGF0ZV07CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBTYW1wbGVyIFN0YXRlcwogKiBUT0RPOiBWZXJpZnkgYWdhaW5zdCBkeDkgZGVmaW5pdGlvbnMKICoqKioqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRTYW1wbGVyU3RhdGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBTYW1wbGVyLCBXSU5FRDNEU0FNUExFUlNUQVRFVFlQRSBUeXBlLCBEV09SRCBWYWx1ZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgRFdPUkQgb2xkVmFsdWU7CgogICAgVFJBQ0UoIiglcCkgOiBTYW1wbGVyICUjeCwgVHlwZSAlcyAoJSN4KSwgVmFsdWUgJSN4XG4iLAogICAgICAgICAgICBUaGlzLCBTYW1wbGVyLCBkZWJ1Z19kM2RzYW1wbGVyc3RhdGUoVHlwZSksIFR5cGUsIFZhbHVlKTsKCiAgICBpZiAoU2FtcGxlciA+PSBXSU5FRDNEVkVSVEVYVEVYVFVSRVNBTVBMRVIwICYmIFNhbXBsZXIgPD0gV0lORUQzRFZFUlRFWFRFWFRVUkVTQU1QTEVSMykgewogICAgICAgIFNhbXBsZXIgLT0gKFdJTkVEM0RWRVJURVhURVhUVVJFU0FNUExFUjAgLSBNQVhfRlJBR01FTlRfU0FNUExFUlMpOwogICAgfQoKICAgIC8qKgogICAgKiBTZXRTYW1wbGVyIGlzIGRlc2lnbmVkIHRvIGFsbG93IGZvciBtb3JlIHRoYW4gdGhlIHN0YW5kYXJkIHVwIHRvIDggdGV4dHVyZXMKICAgICogIGFuZCBHZWZvcmNlIGhhcyBzdG9wcGVkIHN1cHBvcnRpbmcgbW9yZSB0aGFuIDYgc3RhbmRhcmQgdGV4dHVyZXMgaW4gb3BlbkdMLgogICAgKiBTbyBJIGhhdmUgdG8gdXNlIEFSQiBmb3IgR2ZvcmNlLiAobWF5YmUgaWYgdGhlIHNhbXBsZXIgPiA0IHRoZW4gdXNlIEFSQj8pCiAgICAqCiAgICAqIGh0dHA6Ly9kZXZlbG9wZXIubnZpZGlhLmNvbS9vYmplY3QvR2VuZXJhbF9GQVEuaHRtbCN0NgogICAgKgogICAgKiBUaGVyZSBhcmUgdHdvIG5ldyBzZXR0aW5ncyBmb3IgR0ZvcmNlCiAgICAqIHRoZSBzYW1wbGVyIG9uZToKICAgICogR0xfTUFYX1RFWFRVUkVfSU1BR0VfVU5JVFNfQVJCCiAgICAqIGFuZCB0aGUgdGV4dHVyZSBvbmU6CiAgICAqIEdMX01BWF9URVhUVVJFX0NPT1JEU19BUkIuCiAgICAqIE9rIEdGb3JjZSBzYXkgaXQncyBvayB0byB1c2UgZ2xUZXhQYXJhbWV0ZXIvZ2xHZXRUZXhQYXJhbWV0ZXIoLi4uKS4KICAgICAqKioqKioqKioqKioqKioqKiovCgogICAgb2xkVmFsdWUgPSBUaGlzLT5zdGF0ZUJsb2NrLT5zYW1wbGVyU3RhdGVbU2FtcGxlcl1bVHlwZV07CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zYW1wbGVyU3RhdGVbU2FtcGxlcl1bVHlwZV0gICAgICAgICA9IFZhbHVlOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC5zYW1wbGVyU3RhdGVbU2FtcGxlcl1bVHlwZV0gPSBWYWx1ZTsKCiAgICAvKiBIYW5kbGUgcmVjb3JkaW5nIG9mIHN0YXRlIGJsb2NrcyAqLwogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBpZihvbGRWYWx1ZSA9PSBWYWx1ZSkgewogICAgICAgIFRSQUNFKCJBcHBsaWNhdGlvbiBpcyBzZXR0aW5nIHRoZSBvbGQgdmFsdWUgb3Zlciwgbm90aGluZyB0byBkb1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1NBTVBMRVIoU2FtcGxlcikpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFNhbXBsZXJTdGF0ZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIFNhbXBsZXIsIFdJTkVEM0RTQU1QTEVSU1RBVEVUWVBFIFR5cGUsIERXT1JEKiBWYWx1ZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXApIDogU2FtcGxlciAlI3gsIFR5cGUgJXMgKCUjeClcbiIsCiAgICAgICAgICAgIFRoaXMsIFNhbXBsZXIsIGRlYnVnX2QzZHNhbXBsZXJzdGF0ZShUeXBlKSwgVHlwZSk7CgogICAgaWYgKFNhbXBsZXIgPj0gV0lORUQzRFZFUlRFWFRFWFRVUkVTQU1QTEVSMCAmJiBTYW1wbGVyIDw9IFdJTkVEM0RWRVJURVhURVhUVVJFU0FNUExFUjMpIHsKICAgICAgICBTYW1wbGVyIC09IChXSU5FRDNEVkVSVEVYVEVYVFVSRVNBTVBMRVIwIC0gTUFYX0ZSQUdNRU5UX1NBTVBMRVJTKTsKICAgIH0KCiAgICAqVmFsdWUgPSBUaGlzLT5zdGF0ZUJsb2NrLT5zYW1wbGVyU3RhdGVbU2FtcGxlcl1bVHlwZV07CiAgICBUUkFDRSgiKCVwKSA6IFJldHVybmluZyAlI3hcbiIsIFRoaXMsICpWYWx1ZSk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0U2Npc3NvclJlY3QoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBDT05TVCBSRUNUKiBwUmVjdCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQuc2Npc3NvclJlY3QgPSBUUlVFOwogICAgaWYoRXF1YWxSZWN0KCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zY2lzc29yUmVjdCwgcFJlY3QpKSB7CiAgICAgICAgVFJBQ0UoIkFwcCBpcyBzZXR0aW5nIHRoZSBvbGQgc2Npc3NvciByZWN0YW5nbGUgb3Zlciwgbm90aGluZyB0byBkb1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CiAgICBDb3B5UmVjdCgmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2Npc3NvclJlY3QsIHBSZWN0KTsKCiAgICBpZihUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1NDSVNTT1JSRUNUKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTY2lzc29yUmVjdChJV2luZUQzRERldmljZSAqaWZhY2UsIFJFQ1QqIHBSZWN0KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgbWVtY3B5KHBSZWN0LCAmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2Npc3NvclJlY3QsIHNpemVvZihwUmVjdCkpOwogICAgVFJBQ0UoIiglcClSZXR1cm5pbmcgYSBTY2lzc29yIFJlY3Qgb2YgJWQ6JWQtJWQ6JWRcbiIsIFRoaXMsIHBSZWN0LT5sZWZ0LCBwUmVjdC0+dG9wLCBwUmVjdC0+cmlnaHQsIHBSZWN0LT5ib3R0b20pOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0VmVydGV4RGVjbGFyYXRpb24oSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uKiBwRGVjbCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb24gKm9sZERlY2wgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT52ZXJ0ZXhEZWNsOwoKICAgIFRSQUNFKCIoJXApIDogcERlY2w9JXBcbiIsIFRoaXMsIHBEZWNsKTsKCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT52ZXJ0ZXhEZWNsID0gcERlY2w7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnZlcnRleERlY2wgPSBUUlVFOwoKICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9IGVsc2UgaWYocERlY2wgPT0gb2xkRGVjbCkgewogICAgICAgIC8qIENoZWNrZWQgYWZ0ZXIgdGhlIGFzc2lnbm1lbnQgdG8gYWxsb3cgcHJvcGVyIHN0YXRlYmxvY2sgcmVjb3JkaW5nICovCiAgICAgICAgVFJBQ0UoIkFwcGxpY2F0aW9uIGlzIHNldHRpbmcgdGhlIG9sZCBkZWNsYXJhdGlvbiBvdmVyLCBub3RoaW5nIHRvIGRvXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVkRFQ0wpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0VmVydGV4RGVjbGFyYXRpb24oSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uKiogcHBEZWNsKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCkgOiBwcERlY2w9JXBcbiIsIFRoaXMsIHBwRGVjbCk7CgogICAgKnBwRGVjbCA9IFRoaXMtPnN0YXRlQmxvY2stPnZlcnRleERlY2w7CiAgICBpZiAoTlVMTCAhPSAqcHBEZWNsKSBJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uX0FkZFJlZigqcHBEZWNsKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZlcnRleFNoYWRlcihJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEVmVydGV4U2hhZGVyKiBwU2hhZGVyKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgICAgICAgID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RWZXJ0ZXhTaGFkZXIqIG9sZFNoYWRlciA9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnZlcnRleFNoYWRlcjsKCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT52ZXJ0ZXhTaGFkZXIgICAgICAgICA9IHBTaGFkZXI7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnZlcnRleFNoYWRlciA9IFRSVUU7CgogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBpZihwU2hhZGVyKSBJV2luZUQzRFZlcnRleFNoYWRlcl9BZGRSZWYocFNoYWRlcik7CiAgICAgICAgaWYob2xkU2hhZGVyKSBJV2luZUQzRFZlcnRleFNoYWRlcl9SZWxlYXNlKG9sZFNoYWRlcik7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9IGVsc2UgaWYob2xkU2hhZGVyID09IHBTaGFkZXIpIHsKICAgICAgICAvKiBDaGVja2VkIGhlcmUgdG8gYWxsb3cgcHJvcGVyIHN0YXRlYmxvY2sgcmVjb3JkaW5nICovCiAgICAgICAgVFJBQ0UoIkFwcCBpcyBzZXR0aW5nIHRoZSBvbGQgc2hhZGVyIG92ZXIsIG5vdGhpbmcgdG8gZG9cbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIFRSQUNFKCIoJXApIDogc2V0dGluZyBwU2hhZGVyKCVwKVxuIiwgVGhpcywgcFNoYWRlcik7CiAgICBpZihwU2hhZGVyKSBJV2luZUQzRFZlcnRleFNoYWRlcl9BZGRSZWYocFNoYWRlcik7CiAgICBpZihvbGRTaGFkZXIpIElXaW5lRDNEVmVydGV4U2hhZGVyX1JlbGVhc2Uob2xkU2hhZGVyKTsKCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVlNIQURFUik7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0VmVydGV4U2hhZGVyKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RWZXJ0ZXhTaGFkZXIqKiBwcFNoYWRlcikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIGlmIChOVUxMID09IHBwU2hhZGVyKSB7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICAqcHBTaGFkZXIgPSBUaGlzLT5zdGF0ZUJsb2NrLT52ZXJ0ZXhTaGFkZXI7CiAgICBpZiggTlVMTCAhPSAqcHBTaGFkZXIpCiAgICAgICAgSVdpbmVEM0RWZXJ0ZXhTaGFkZXJfQWRkUmVmKCpwcFNoYWRlcik7CgogICAgVFJBQ0UoIiglcCkgOiByZXR1cm5pbmcgJXBcbiIsIFRoaXMsICpwcFNoYWRlcik7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEIoCiAgICBJV2luZUQzRERldmljZSAqaWZhY2UsCiAgICBVSU5UIHN0YXJ0LAogICAgQ09OU1QgQk9PTCAqc3JjRGF0YSwKICAgIFVJTlQgY291bnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpbnQgaSwgY250ID0gbWluKGNvdW50LCBNQVhfQ09OU1RfQiAtIHN0YXJ0KTsKCiAgICBUUkFDRSgiKGlmYWNlICVwLCBzcmNEYXRhICVwLCBzdGFydCAlZCwgY291bnQgJWQpXG4iLAogICAgICAgICAgICBpZmFjZSwgc3JjRGF0YSwgc3RhcnQsIGNvdW50KTsKCiAgICBpZiAoc3JjRGF0YSA9PSBOVUxMIHx8IGNudCA8IDApCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgbWVtY3B5KCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT52ZXJ0ZXhTaGFkZXJDb25zdGFudEJbc3RhcnRdLCBzcmNEYXRhLCBjbnQgKiBzaXplb2YoQk9PTCkpOwogICAgZm9yIChpID0gMDsgaSA8IGNudDsgaSsrKQogICAgICAgIFRSQUNFKCJTZXQgQk9PTCBjb25zdGFudCAldSB0byAlc1xuIiwgc3RhcnQgKyBpLCBzcmNEYXRhW2ldPyAidHJ1ZSI6ImZhbHNlIik7CgogICAgZm9yIChpID0gc3RhcnQ7IGkgPCBjbnQgKyBzdGFydDsgKytpKSB7CiAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC52ZXJ0ZXhTaGFkZXJDb25zdGFudHNCW2ldID0gVFJVRTsKICAgIH0KCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVkVSVEVYU0hBREVSQ09OU1RBTlQpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZlcnRleFNoYWRlckNvbnN0YW50QigKICAgIElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgIFVJTlQgc3RhcnQsCiAgICBCT09MICpkc3REYXRhLAogICAgVUlOVCBjb3VudCkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIGludCBjbnQgPSBtaW4oY291bnQsIE1BWF9DT05TVF9CIC0gc3RhcnQpOwoKICAgIFRSQUNFKCIoaWZhY2UgJXAsIGRzdERhdGEgJXAsIHN0YXJ0ICVkLCBjb3VudCAlZClcbiIsCiAgICAgICAgICAgIGlmYWNlLCBkc3REYXRhLCBzdGFydCwgY291bnQpOwoKICAgIGlmIChkc3REYXRhID09IE5VTEwgfHwgY250IDwgMCkKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICBtZW1jcHkoZHN0RGF0YSwgJlRoaXMtPnN0YXRlQmxvY2stPnZlcnRleFNoYWRlckNvbnN0YW50QltzdGFydF0sIGNudCAqIHNpemVvZihCT09MKSk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEkoCiAgICBJV2luZUQzRERldmljZSAqaWZhY2UsCiAgICBVSU5UIHN0YXJ0LAogICAgQ09OU1QgaW50ICpzcmNEYXRhLAogICAgVUlOVCBjb3VudCkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIGludCBpLCBjbnQgPSBtaW4oY291bnQsIE1BWF9DT05TVF9JIC0gc3RhcnQpOwoKICAgIFRSQUNFKCIoaWZhY2UgJXAsIHNyY0RhdGEgJXAsIHN0YXJ0ICVkLCBjb3VudCAlZClcbiIsCiAgICAgICAgICAgIGlmYWNlLCBzcmNEYXRhLCBzdGFydCwgY291bnQpOwoKICAgIGlmIChzcmNEYXRhID09IE5VTEwgfHwgY250IDwgMCkKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICBtZW1jcHkoJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnZlcnRleFNoYWRlckNvbnN0YW50SVtzdGFydCAqIDRdLCBzcmNEYXRhLCBjbnQgKiBzaXplb2YoaW50KSAqIDQpOwogICAgZm9yIChpID0gMDsgaSA8IGNudDsgaSsrKQogICAgICAgIFRSQUNFKCJTZXQgSU5UIGNvbnN0YW50ICV1IHRvIHsgJWQsICVkLCAlZCwgJWQgfVxuIiwgc3RhcnQgKyBpLAogICAgICAgICAgIHNyY0RhdGFbaSo0XSwgc3JjRGF0YVtpKjQrMV0sIHNyY0RhdGFbaSo0KzJdLCBzcmNEYXRhW2kqNCszXSk7CgogICAgZm9yIChpID0gc3RhcnQ7IGkgPCBjbnQgKyBzdGFydDsgKytpKSB7CiAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC52ZXJ0ZXhTaGFkZXJDb25zdGFudHNJW2ldID0gVFJVRTsKICAgIH0KCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVkVSVEVYU0hBREVSQ09OU1RBTlQpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZlcnRleFNoYWRlckNvbnN0YW50SSgKICAgIElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgIFVJTlQgc3RhcnQsCiAgICBpbnQgKmRzdERhdGEsCiAgICBVSU5UIGNvdW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaW50IGNudCA9IG1pbihjb3VudCwgTUFYX0NPTlNUX0kgLSBzdGFydCk7CgogICAgVFJBQ0UoIihpZmFjZSAlcCwgZHN0RGF0YSAlcCwgc3RhcnQgJWQsIGNvdW50ICVkKVxuIiwKICAgICAgICAgICAgaWZhY2UsIGRzdERhdGEsIHN0YXJ0LCBjb3VudCk7CgogICAgaWYgKGRzdERhdGEgPT0gTlVMTCB8fCAoKHNpZ25lZCBpbnQpIE1BWF9DT05TVF9JIC0gKHNpZ25lZCBpbnQpIHN0YXJ0KSA8PSAoc2lnbmVkIGludCkgMCkKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICBtZW1jcHkoZHN0RGF0YSwgJlRoaXMtPnN0YXRlQmxvY2stPnZlcnRleFNoYWRlckNvbnN0YW50SVtzdGFydCAqIDRdLCBjbnQgKiBzaXplb2YoaW50KSAqIDQpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0VmVydGV4U2hhZGVyQ29uc3RhbnRGKAogICAgSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgVUlOVCBzdGFydCwKICAgIENPTlNUIGZsb2F0ICpzcmNEYXRhLAogICAgVUlOVCBjb3VudCkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIGludCBpOwoKICAgIFRSQUNFKCIoaWZhY2UgJXAsIHNyY0RhdGEgJXAsIHN0YXJ0ICVkLCBjb3VudCAlZClcbiIsCiAgICAgICAgICAgIGlmYWNlLCBzcmNEYXRhLCBzdGFydCwgY291bnQpOwoKICAgIC8qIFNwZWNpZmljYWxseSB0ZXN0IHN0YXJ0ID4gbGltaXQgdG8gY2F0Y2ggTUFYX1VJTlQgb3ZlcmZsb3dzIHdoZW4gYWRkaW5nIHN0YXJ0ICsgY291bnQgKi8KICAgIGlmIChzcmNEYXRhID09IE5VTEwgfHwgc3RhcnQgKyBjb3VudCA+IEdMX0xJTUlUUyh2c2hhZGVyX2NvbnN0YW50c0YpIHx8IHN0YXJ0ID4gR0xfTElNSVRTKHZzaGFkZXJfY29uc3RhbnRzRikpCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgbWVtY3B5KCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT52ZXJ0ZXhTaGFkZXJDb25zdGFudEZbc3RhcnQgKiA0XSwgc3JjRGF0YSwgY291bnQgKiBzaXplb2YoZmxvYXQpICogNCk7CiAgICBpZihUUkFDRV9PTihkM2QpKSB7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspCiAgICAgICAgICAgIFRSQUNFKCJTZXQgRkxPQVQgY29uc3RhbnQgJXUgdG8geyAlZiwgJWYsICVmLCAlZiB9XG4iLCBzdGFydCArIGksCiAgICAgICAgICAgICAgICBzcmNEYXRhW2kqNF0sIHNyY0RhdGFbaSo0KzFdLCBzcmNEYXRhW2kqNCsyXSwgc3JjRGF0YVtpKjQrM10pOwogICAgfQoKICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgY291bnQgKyBzdGFydDsgKytpKSB7CiAgICAgICAgaWYgKCFUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnZlcnRleFNoYWRlckNvbnN0YW50c0ZbaV0pIHsKICAgICAgICAgICAgY29uc3RhbnRzX2VudHJ5ICpwdHIgPSBMSVNUX0VOVFJZKGxpc3RfaGVhZCgmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0X3Zjb25zdGFudHNGKSwgY29uc3RhbnRzX2VudHJ5LCBlbnRyeSk7CiAgICAgICAgICAgIGlmICghcHRyIHx8IHB0ci0+Y291bnQgPj0gc2l6ZW9mKHB0ci0+aWR4KSAvIHNpemVvZigqcHRyLT5pZHgpKSB7CiAgICAgICAgICAgICAgICBwdHIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKGNvbnN0YW50c19lbnRyeSkpOwogICAgICAgICAgICAgICAgbGlzdF9hZGRfaGVhZCgmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0X3Zjb25zdGFudHNGLCAmcHRyLT5lbnRyeSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHRyLT5pZHhbcHRyLT5jb3VudCsrXSA9IGk7CiAgICAgICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQudmVydGV4U2hhZGVyQ29uc3RhbnRzRltpXSA9IFRSVUU7CiAgICAgICAgfQogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9WRVJURVhTSEFERVJDT05TVEFOVCk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0VmVydGV4U2hhZGVyQ29uc3RhbnRGKAogICAgSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgVUlOVCBzdGFydCwKICAgIGZsb2F0ICpkc3REYXRhLAogICAgVUlOVCBjb3VudCkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIGludCBjbnQgPSBtaW4oY291bnQsIEdMX0xJTUlUUyh2c2hhZGVyX2NvbnN0YW50c0YpIC0gc3RhcnQpOwoKICAgIFRSQUNFKCIoaWZhY2UgJXAsIGRzdERhdGEgJXAsIHN0YXJ0ICVkLCBjb3VudCAlZClcbiIsCiAgICAgICAgICAgIGlmYWNlLCBkc3REYXRhLCBzdGFydCwgY291bnQpOwoKICAgIGlmIChkc3REYXRhID09IE5VTEwgfHwgY250IDwgMCkKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICBtZW1jcHkoZHN0RGF0YSwgJlRoaXMtPnN0YXRlQmxvY2stPnZlcnRleFNoYWRlckNvbnN0YW50RltzdGFydCAqIDRdLCBjbnQgKiBzaXplb2YoZmxvYXQpICogNCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIGlubGluZSB2b2lkIG1hcmtUZXh0dXJlU3RhZ2VzRGlydHkoSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzLCBEV09SRCBzdGFnZSkgewogICAgRFdPUkQgaTsKICAgIGZvcihpID0gMDsgaSA8IFdJTkVEM0RfSElHSEVTVF9URVhUVVJFX1NUQVRFOyBpKyspIHsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVEVYVFVSRVNUQUdFKHN0YWdlLCBpKSk7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIGRldmljZV9tYXBfc3RhZ2UoSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzLCBpbnQgc3RhZ2UsIGludCB1bml0KSB7CiAgICBpbnQgaSA9IFRoaXMtPnJldl90ZXhfdW5pdF9tYXBbdW5pdF07CiAgICBpbnQgaiA9IFRoaXMtPnRleFVuaXRNYXBbc3RhZ2VdOwoKICAgIFRoaXMtPnRleFVuaXRNYXBbc3RhZ2VdID0gdW5pdDsKICAgIGlmIChpICE9IC0xICYmIGkgIT0gc3RhZ2UpIHsKICAgICAgICBUaGlzLT50ZXhVbml0TWFwW2ldID0gLTE7CiAgICB9CgogICAgVGhpcy0+cmV2X3RleF91bml0X21hcFt1bml0XSA9IHN0YWdlOwogICAgaWYgKGogIT0gLTEgJiYgaiAhPSB1bml0KSB7CiAgICAgICAgVGhpcy0+cmV2X3RleF91bml0X21hcFtqXSA9IC0xOwogICAgfQp9CgpzdGF0aWMgdm9pZCBkZXZpY2VfdXBkYXRlX2ZpeGVkX2Z1bmN0aW9uX3VzYWdlX21hcChJV2luZUQzRERldmljZUltcGwgKlRoaXMpIHsKICAgIGludCBpOwoKICAgIGZvciAoaSA9IDA7IGkgPCBNQVhfVEVYVFVSRVM7ICsraSkgewogICAgICAgIFdJTkVEM0RURVhUVVJFT1AgY29sb3Jfb3AgPSBUaGlzLT5zdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbaV1bV0lORUQzRFRTU19DT0xPUk9QXTsKICAgICAgICBXSU5FRDNEVEVYVFVSRU9QIGFscGhhX29wID0gVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlW2ldW1dJTkVEM0RUU1NfQUxQSEFPUF07CiAgICAgICAgRFdPUkQgY29sb3JfYXJnMSA9IFRoaXMtPnN0YXRlQmxvY2stPnRleHR1cmVTdGF0ZVtpXVtXSU5FRDNEVFNTX0NPTE9SQVJHMV0gJiBXSU5FRDNEVEFfU0VMRUNUTUFTSzsKICAgICAgICBEV09SRCBjb2xvcl9hcmcyID0gVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlW2ldW1dJTkVEM0RUU1NfQ09MT1JBUkcyXSAmIFdJTkVEM0RUQV9TRUxFQ1RNQVNLOwogICAgICAgIERXT1JEIGNvbG9yX2FyZzMgPSBUaGlzLT5zdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbaV1bV0lORUQzRFRTU19DT0xPUkFSRzBdICYgV0lORUQzRFRBX1NFTEVDVE1BU0s7CiAgICAgICAgRFdPUkQgYWxwaGFfYXJnMSA9IFRoaXMtPnN0YXRlQmxvY2stPnRleHR1cmVTdGF0ZVtpXVtXSU5FRDNEVFNTX0FMUEhBQVJHMV0gJiBXSU5FRDNEVEFfU0VMRUNUTUFTSzsKICAgICAgICBEV09SRCBhbHBoYV9hcmcyID0gVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlW2ldW1dJTkVEM0RUU1NfQUxQSEFBUkcyXSAmIFdJTkVEM0RUQV9TRUxFQ1RNQVNLOwogICAgICAgIERXT1JEIGFscGhhX2FyZzMgPSBUaGlzLT5zdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbaV1bV0lORUQzRFRTU19BTFBIQUFSRzBdICYgV0lORUQzRFRBX1NFTEVDVE1BU0s7CgogICAgICAgIGlmIChjb2xvcl9vcCA9PSBXSU5FRDNEVE9QX0RJU0FCTEUpIHsKICAgICAgICAgICAgLyogTm90IHVzZWQsIGFuZCBkaXNhYmxlIGhpZ2hlciBzdGFnZXMgKi8KICAgICAgICAgICAgd2hpbGUgKGkgPCBNQVhfVEVYVFVSRVMpIHsKICAgICAgICAgICAgICAgIFRoaXMtPmZpeGVkX2Z1bmN0aW9uX3VzYWdlX21hcFtpXSA9IEZBTFNFOwogICAgICAgICAgICAgICAgKytpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgaWYgKCgoY29sb3JfYXJnMSA9PSBXSU5FRDNEVEFfVEVYVFVSRSkgJiYgY29sb3Jfb3AgIT0gV0lORUQzRFRPUF9TRUxFQ1RBUkcyKQogICAgICAgICAgICAgICAgfHwgKChjb2xvcl9hcmcyID09IFdJTkVEM0RUQV9URVhUVVJFKSAmJiBjb2xvcl9vcCAhPSBXSU5FRDNEVE9QX1NFTEVDVEFSRzEpCiAgICAgICAgICAgICAgICB8fCAoKGNvbG9yX2FyZzMgPT0gV0lORUQzRFRBX1RFWFRVUkUpICYmIChjb2xvcl9vcCA9PSBXSU5FRDNEVE9QX01VTFRJUExZQUREIHx8IGNvbG9yX29wID09IFdJTkVEM0RUT1BfTEVSUCkpCiAgICAgICAgICAgICAgICB8fCAoKGFscGhhX2FyZzEgPT0gV0lORUQzRFRBX1RFWFRVUkUpICYmIGFscGhhX29wICE9IFdJTkVEM0RUT1BfU0VMRUNUQVJHMikKICAgICAgICAgICAgICAgIHx8ICgoYWxwaGFfYXJnMiA9PSBXSU5FRDNEVEFfVEVYVFVSRSkgJiYgYWxwaGFfb3AgIT0gV0lORUQzRFRPUF9TRUxFQ1RBUkcxKQogICAgICAgICAgICAgICAgfHwgKChhbHBoYV9hcmczID09IFdJTkVEM0RUQV9URVhUVVJFKSAmJiAoYWxwaGFfb3AgPT0gV0lORUQzRFRPUF9NVUxUSVBMWUFERCB8fCBhbHBoYV9vcCA9PSBXSU5FRDNEVE9QX0xFUlApKSkgewogICAgICAgICAgICBUaGlzLT5maXhlZF9mdW5jdGlvbl91c2FnZV9tYXBbaV0gPSBUUlVFOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFRoaXMtPmZpeGVkX2Z1bmN0aW9uX3VzYWdlX21hcFtpXSA9IEZBTFNFOwogICAgICAgIH0KCiAgICAgICAgaWYgKChjb2xvcl9vcCA9PSBXSU5FRDNEVE9QX0JVTVBFTlZNQVAgfHwgY29sb3Jfb3AgPT0gV0lORUQzRFRPUF9CVU1QRU5WTUFQTFVNSU5BTkNFKSAmJiBpIDwgTUFYX1RFWFRVUkVTIC0gMSkgewogICAgICAgICAgICBUaGlzLT5maXhlZF9mdW5jdGlvbl91c2FnZV9tYXBbaSsxXSA9IFRSVUU7CiAgICAgICAgfQogICAgfQp9CgpzdGF0aWMgdm9pZCBkZXZpY2VfbWFwX2ZpeGVkX2Z1bmN0aW9uX3NhbXBsZXJzKElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcykgewogICAgaW50IGksIHRleDsKCiAgICBkZXZpY2VfdXBkYXRlX2ZpeGVkX2Z1bmN0aW9uX3VzYWdlX21hcChUaGlzKTsKCiAgICBpZiAoIUdMX1NVUFBPUlQoTlZfUkVHSVNURVJfQ09NQklORVJTKSB8fCBUaGlzLT5zdGF0ZUJsb2NrLT5sb3dlc3RfZGlzYWJsZWRfc3RhZ2UgPD0gR0xfTElNSVRTKHRleHR1cmVzKSkgewogICAgICAgIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5zdGF0ZUJsb2NrLT5sb3dlc3RfZGlzYWJsZWRfc3RhZ2U7ICsraSkgewogICAgICAgICAgICBpZiAoIVRoaXMtPmZpeGVkX2Z1bmN0aW9uX3VzYWdlX21hcFtpXSkgY29udGludWU7CgogICAgICAgICAgICBpZiAoVGhpcy0+dGV4VW5pdE1hcFtpXSAhPSBpKSB7CiAgICAgICAgICAgICAgICBkZXZpY2VfbWFwX3N0YWdlKFRoaXMsIGksIGkpOwogICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1NBTVBMRVIoaSkpOwogICAgICAgICAgICAgICAgbWFya1RleHR1cmVTdGFnZXNEaXJ0eShUaGlzLCBpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm47CiAgICB9CgogICAgLyogTm93IHdvcmsgb3V0IHRoZSBtYXBwaW5nICovCiAgICB0ZXggPSAwOwogICAgZm9yIChpID0gMDsgaSA8IFRoaXMtPnN0YXRlQmxvY2stPmxvd2VzdF9kaXNhYmxlZF9zdGFnZTsgKytpKSB7CiAgICAgICAgaWYgKCFUaGlzLT5maXhlZF9mdW5jdGlvbl91c2FnZV9tYXBbaV0pIGNvbnRpbnVlOwoKICAgICAgICBpZiAoVGhpcy0+dGV4VW5pdE1hcFtpXSAhPSB0ZXgpIHsKICAgICAgICAgICAgZGV2aWNlX21hcF9zdGFnZShUaGlzLCBpLCB0ZXgpOwogICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfU0FNUExFUihpKSk7CiAgICAgICAgICAgIG1hcmtUZXh0dXJlU3RhZ2VzRGlydHkoVGhpcywgaSk7CiAgICAgICAgfQoKICAgICAgICArK3RleDsKICAgIH0KfQoKc3RhdGljIHZvaWQgZGV2aWNlX21hcF9wc2FtcGxlcnMoSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzKSB7CiAgICBEV09SRCAqc2FtcGxlcl90b2tlbnMgPSAoKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICopVGhpcy0+c3RhdGVCbG9jay0+cGl4ZWxTaGFkZXIpLT5iYXNlU2hhZGVyLnJlZ19tYXBzLnNhbXBsZXJzOwogICAgaW50IGk7CgogICAgZm9yIChpID0gMDsgaSA8IE1BWF9GUkFHTUVOVF9TQU1QTEVSUzsgKytpKSB7CiAgICAgICAgaWYgKHNhbXBsZXJfdG9rZW5zW2ldICYmIFRoaXMtPnRleFVuaXRNYXBbaV0gIT0gaSkgewogICAgICAgICAgICBkZXZpY2VfbWFwX3N0YWdlKFRoaXMsIGksIGkpOwogICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfU0FNUExFUihpKSk7CiAgICAgICAgICAgIGlmIChpIDwgTUFYX1RFWFRVUkVTKSB7CiAgICAgICAgICAgICAgICBtYXJrVGV4dHVyZVN0YWdlc0RpcnR5KFRoaXMsIGkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CgpzdGF0aWMgQk9PTCBkZXZpY2VfdW5pdF9mcmVlX2Zvcl92cyhJV2luZUQzRERldmljZUltcGwgKlRoaXMsIERXT1JEICpwc2hhZGVyX3NhbXBsZXJfdG9rZW5zLCBEV09SRCAqdnNoYWRlcl9zYW1wbGVyX3Rva2VucywgaW50IHVuaXQpIHsKICAgIGludCBjdXJyZW50X21hcHBpbmcgPSBUaGlzLT5yZXZfdGV4X3VuaXRfbWFwW3VuaXRdOwoKICAgIGlmIChjdXJyZW50X21hcHBpbmcgPT0gLTEpIHsKICAgICAgICAvKiBOb3QgY3VycmVudGx5IHVzZWQgKi8KICAgICAgICByZXR1cm4gVFJVRTsKICAgIH0KCiAgICBpZiAoY3VycmVudF9tYXBwaW5nIDwgTUFYX0ZSQUdNRU5UX1NBTVBMRVJTKSB7CiAgICAgICAgLyogVXNlZCBieSBhIGZyYWdtZW50IHNhbXBsZXIgKi8KCiAgICAgICAgaWYgKCFwc2hhZGVyX3NhbXBsZXJfdG9rZW5zKSB7CiAgICAgICAgICAgIC8qIE5vIHBpeGVsIHNoYWRlciwgY2hlY2sgZml4ZWQgZnVuY3Rpb24gKi8KICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRfbWFwcGluZyA+PSBNQVhfVEVYVFVSRVMgfHwgIVRoaXMtPmZpeGVkX2Z1bmN0aW9uX3VzYWdlX21hcFtjdXJyZW50X21hcHBpbmddOwogICAgICAgIH0KCiAgICAgICAgLyogUGl4ZWwgc2hhZGVyLCBjaGVjayB0aGUgc2hhZGVyJ3Mgc2FtcGxlciBtYXAgKi8KICAgICAgICByZXR1cm4gIXBzaGFkZXJfc2FtcGxlcl90b2tlbnNbY3VycmVudF9tYXBwaW5nXTsKICAgIH0KCiAgICAvKiBVc2VkIGJ5IGEgdmVydGV4IHNhbXBsZXIgKi8KICAgIHJldHVybiAhdnNoYWRlcl9zYW1wbGVyX3Rva2Vuc1tjdXJyZW50X21hcHBpbmddOwp9CgpzdGF0aWMgdm9pZCBkZXZpY2VfbWFwX3ZzYW1wbGVycyhJV2luZUQzRERldmljZUltcGwgKlRoaXMsIEJPT0wgcHMpIHsKICAgIERXT1JEICp2c2hhZGVyX3NhbXBsZXJfdG9rZW5zID0gKChJV2luZUQzRFZlcnRleFNoYWRlckltcGwgKilUaGlzLT5zdGF0ZUJsb2NrLT52ZXJ0ZXhTaGFkZXIpLT5iYXNlU2hhZGVyLnJlZ19tYXBzLnNhbXBsZXJzOwogICAgRFdPUkQgKnBzaGFkZXJfc2FtcGxlcl90b2tlbnMgPSBOVUxMOwogICAgaW50IHN0YXJ0ID0gR0xfTElNSVRTKGNvbWJpbmVkX3NhbXBsZXJzKSAtIDE7CiAgICBpbnQgaTsKCiAgICBpZiAocHMpIHsKICAgICAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqcHNoYWRlciA9IChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqKVRoaXMtPnN0YXRlQmxvY2stPnBpeGVsU2hhZGVyOwoKICAgICAgICAvKiBNYWtlIHN1cmUgdGhlIHNoYWRlcidzIHJlZ19tYXBzIGFyZSB1cCB0byBkYXRlLiBUaGlzIGlzIG9ubHkgcmVsZXZhbnQgZm9yIDEueCBwaXhlbHNoYWRlcnMuICovCiAgICAgICAgSVdpbmVEM0RQaXhlbFNoYWRlcl9Db21waWxlU2hhZGVyKChJV2luZUQzRFBpeGVsU2hhZGVyICopcHNoYWRlcik7CiAgICAgICAgcHNoYWRlcl9zYW1wbGVyX3Rva2VucyA9IHBzaGFkZXItPmJhc2VTaGFkZXIucmVnX21hcHMuc2FtcGxlcnM7CiAgICB9CgogICAgZm9yIChpID0gMDsgaSA8IE1BWF9WRVJURVhfU0FNUExFUlM7ICsraSkgewogICAgICAgIGludCB2c2FtcGxlcl9pZHggPSBpICsgTUFYX0ZSQUdNRU5UX1NBTVBMRVJTOwogICAgICAgIGlmICh2c2hhZGVyX3NhbXBsZXJfdG9rZW5zW2ldKSB7CiAgICAgICAgICAgIGlmIChUaGlzLT50ZXhVbml0TWFwW3ZzYW1wbGVyX2lkeF0gIT0gLTEpIHsKICAgICAgICAgICAgICAgIC8qIEFscmVhZHkgbWFwcGVkIHNvbWV3aGVyZSAqLwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHdoaWxlIChzdGFydCA+PSAwKSB7CiAgICAgICAgICAgICAgICBpZiAoZGV2aWNlX3VuaXRfZnJlZV9mb3JfdnMoVGhpcywgcHNoYWRlcl9zYW1wbGVyX3Rva2VucywgdnNoYWRlcl9zYW1wbGVyX3Rva2Vucywgc3RhcnQpKSB7CiAgICAgICAgICAgICAgICAgICAgZGV2aWNlX21hcF9zdGFnZShUaGlzLCB2c2FtcGxlcl9pZHgsIHN0YXJ0KTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfU0FNUExFUih2c2FtcGxlcl9pZHgpKTsKCiAgICAgICAgICAgICAgICAgICAgLS1zdGFydDsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAtLXN0YXJ0OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9Cgp2b2lkIElXaW5lRDNERGV2aWNlSW1wbF9GaW5kVGV4VW5pdE1hcChJV2luZUQzRERldmljZUltcGwgKlRoaXMpIHsKICAgIEJPT0wgdnMgPSB1c2VfdnMoVGhpcyk7CiAgICBCT09MIHBzID0gdXNlX3BzKFRoaXMpOwogICAgLyoKICAgICAqIFJ1bGVzIGFyZToKICAgICAqIC0+IFBpeGVsIHNoYWRlcnMgbmVlZCBhIDE6MSBtYXAuIEluIHRoZW9yeSB0aGUgc2hhZGVyIGlucHV0IGNvdWxkIGJlIG1hcHBlZCB0b28sIGJ1dAogICAgICogdGhhdCB3b3VsZCBiZSByZWFsbHkgbWVzc3kgYW5kIHJlcXVpcmUgc2hhZGVyIHJlY29tcGlsYXRpb24KICAgICAqIC0+IFdoZW4gdGhlIG1hcHBpbmcgb2YgYSBzdGFnZSBpcyBjaGFuZ2VkLCBzYW1wbGVyIGFuZCBBTEwgdGV4dHVyZSBzdGFnZSBzdGF0ZXMgaGF2ZQogICAgICogdG8gYmUgcmVzZXQuIEJlY2F1c2Ugb2YgdGhhdCB0cnkgdG8gd29yayB3aXRoIGEgMToxIG1hcHBpbmcgYXMgbXVjaCBhcyBwb3NzaWJsZQogICAgICovCiAgICBpZiAocHMpIHsKICAgICAgICBkZXZpY2VfbWFwX3BzYW1wbGVycyhUaGlzKTsKICAgIH0gZWxzZSB7CiAgICAgICAgZGV2aWNlX21hcF9maXhlZF9mdW5jdGlvbl9zYW1wbGVycyhUaGlzKTsKICAgIH0KCiAgICBpZiAodnMpIHsKICAgICAgICBkZXZpY2VfbWFwX3ZzYW1wbGVycyhUaGlzLCBwcyk7CiAgICB9Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0UGl4ZWxTaGFkZXIoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFBpeGVsU2hhZGVyICpwU2hhZGVyKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgICAgICAgID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RQaXhlbFNoYWRlciAqb2xkU2hhZGVyICA9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnBpeGVsU2hhZGVyOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+cGl4ZWxTaGFkZXIgICAgICAgICA9IHBTaGFkZXI7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnBpeGVsU2hhZGVyID0gVFJVRTsKCiAgICAvKiBIYW5kbGUgcmVjb3JkaW5nIG9mIHN0YXRlIGJsb2NrcyAqLwogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgIH0KCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgICAgIGlmKHBTaGFkZXIpIElXaW5lRDNEUGl4ZWxTaGFkZXJfQWRkUmVmKHBTaGFkZXIpOwogICAgICAgIGlmKG9sZFNoYWRlcikgSVdpbmVEM0RQaXhlbFNoYWRlcl9SZWxlYXNlKG9sZFNoYWRlcik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgaWYocFNoYWRlciA9PSBvbGRTaGFkZXIpIHsKICAgICAgICBUUkFDRSgiQXBwIGlzIHNldHRpbmcgdGhlIG9sZCBwaXhlbCBzaGFkZXIgb3Zlciwgbm90aGluZyB0byBkb1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgaWYocFNoYWRlcikgSVdpbmVEM0RQaXhlbFNoYWRlcl9BZGRSZWYocFNoYWRlcik7CiAgICBpZihvbGRTaGFkZXIpIElXaW5lRDNEUGl4ZWxTaGFkZXJfUmVsZWFzZShvbGRTaGFkZXIpOwoKICAgIFRSQUNFKCIoJXApIDogc2V0dGluZyBwU2hhZGVyKCVwKVxuIiwgVGhpcywgcFNoYWRlcik7CiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfUElYRUxTSEFERVIpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFBpeGVsU2hhZGVyKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RQaXhlbFNoYWRlciAqKnBwU2hhZGVyKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgaWYgKE5VTEwgPT0gcHBTaGFkZXIpIHsKICAgICAgICBXQVJOKCIoJXApIDogUFNoYWRlciBpcyBOVUxMLCByZXR1cm5pbmcgSU5WQUxJRENBTExcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgICpwcFNoYWRlciA9ICBUaGlzLT5zdGF0ZUJsb2NrLT5waXhlbFNoYWRlcjsKICAgIGlmIChOVUxMICE9ICpwcFNoYWRlcikgewogICAgICAgIElXaW5lRDNEUGl4ZWxTaGFkZXJfQWRkUmVmKCpwcFNoYWRlcik7CiAgICB9CiAgICBUUkFDRSgiKCVwKSA6IHJldHVybmluZyAlcFxuIiwgVGhpcywgKnBwU2hhZGVyKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFBpeGVsU2hhZGVyQ29uc3RhbnRCKAogICAgSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgVUlOVCBzdGFydCwKICAgIENPTlNUIEJPT0wgKnNyY0RhdGEsCiAgICBVSU5UIGNvdW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaW50IGksIGNudCA9IG1pbihjb3VudCwgTUFYX0NPTlNUX0IgLSBzdGFydCk7CgogICAgVFJBQ0UoIihpZmFjZSAlcCwgc3JjRGF0YSAlcCwgc3RhcnQgJWQsIGNvdW50ICVkKVxuIiwKICAgICAgICAgICAgaWZhY2UsIHNyY0RhdGEsIHN0YXJ0LCBjb3VudCk7CgogICAgaWYgKHNyY0RhdGEgPT0gTlVMTCB8fCBjbnQgPCAwKQogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIG1lbWNweSgmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+cGl4ZWxTaGFkZXJDb25zdGFudEJbc3RhcnRdLCBzcmNEYXRhLCBjbnQgKiBzaXplb2YoQk9PTCkpOwogICAgZm9yIChpID0gMDsgaSA8IGNudDsgaSsrKQogICAgICAgIFRSQUNFKCJTZXQgQk9PTCBjb25zdGFudCAldSB0byAlc1xuIiwgc3RhcnQgKyBpLCBzcmNEYXRhW2ldPyAidHJ1ZSI6ImZhbHNlIik7CgogICAgZm9yIChpID0gc3RhcnQ7IGkgPCBjbnQgKyBzdGFydDsgKytpKSB7CiAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC5waXhlbFNoYWRlckNvbnN0YW50c0JbaV0gPSBUUlVFOwogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9QSVhFTFNIQURFUkNPTlNUQU5UKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQaXhlbFNoYWRlckNvbnN0YW50QigKICAgIElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgIFVJTlQgc3RhcnQsCiAgICBCT09MICpkc3REYXRhLAogICAgVUlOVCBjb3VudCkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIGludCBjbnQgPSBtaW4oY291bnQsIE1BWF9DT05TVF9CIC0gc3RhcnQpOwoKICAgIFRSQUNFKCIoaWZhY2UgJXAsIGRzdERhdGEgJXAsIHN0YXJ0ICVkLCBjb3VudCAlZClcbiIsCiAgICAgICAgICAgIGlmYWNlLCBkc3REYXRhLCBzdGFydCwgY291bnQpOwoKICAgIGlmIChkc3REYXRhID09IE5VTEwgfHwgY250IDwgMCkKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICBtZW1jcHkoZHN0RGF0YSwgJlRoaXMtPnN0YXRlQmxvY2stPnBpeGVsU2hhZGVyQ29uc3RhbnRCW3N0YXJ0XSwgY250ICogc2l6ZW9mKEJPT0wpKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFBpeGVsU2hhZGVyQ29uc3RhbnRJKAogICAgSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgVUlOVCBzdGFydCwKICAgIENPTlNUIGludCAqc3JjRGF0YSwKICAgIFVJTlQgY291bnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpbnQgaSwgY250ID0gbWluKGNvdW50LCBNQVhfQ09OU1RfSSAtIHN0YXJ0KTsKCiAgICBUUkFDRSgiKGlmYWNlICVwLCBzcmNEYXRhICVwLCBzdGFydCAlZCwgY291bnQgJWQpXG4iLAogICAgICAgICAgICBpZmFjZSwgc3JjRGF0YSwgc3RhcnQsIGNvdW50KTsKCiAgICBpZiAoc3JjRGF0YSA9PSBOVUxMIHx8IGNudCA8IDApCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgbWVtY3B5KCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5waXhlbFNoYWRlckNvbnN0YW50SVtzdGFydCAqIDRdLCBzcmNEYXRhLCBjbnQgKiBzaXplb2YoaW50KSAqIDQpOwogICAgZm9yIChpID0gMDsgaSA8IGNudDsgaSsrKQogICAgICAgIFRSQUNFKCJTZXQgSU5UIGNvbnN0YW50ICV1IHRvIHsgJWQsICVkLCAlZCwgJWQgfVxuIiwgc3RhcnQgKyBpLAogICAgICAgICAgIHNyY0RhdGFbaSo0XSwgc3JjRGF0YVtpKjQrMV0sIHNyY0RhdGFbaSo0KzJdLCBzcmNEYXRhW2kqNCszXSk7CgogICAgZm9yIChpID0gc3RhcnQ7IGkgPCBjbnQgKyBzdGFydDsgKytpKSB7CiAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC5waXhlbFNoYWRlckNvbnN0YW50c0lbaV0gPSBUUlVFOwogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9QSVhFTFNIQURFUkNPTlNUQU5UKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQaXhlbFNoYWRlckNvbnN0YW50SSgKICAgIElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgIFVJTlQgc3RhcnQsCiAgICBpbnQgKmRzdERhdGEsCiAgICBVSU5UIGNvdW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaW50IGNudCA9IG1pbihjb3VudCwgTUFYX0NPTlNUX0kgLSBzdGFydCk7CgogICAgVFJBQ0UoIihpZmFjZSAlcCwgZHN0RGF0YSAlcCwgc3RhcnQgJWQsIGNvdW50ICVkKVxuIiwKICAgICAgICAgICAgaWZhY2UsIGRzdERhdGEsIHN0YXJ0LCBjb3VudCk7CgogICAgaWYgKGRzdERhdGEgPT0gTlVMTCB8fCBjbnQgPCAwKQogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIG1lbWNweShkc3REYXRhLCAmVGhpcy0+c3RhdGVCbG9jay0+cGl4ZWxTaGFkZXJDb25zdGFudElbc3RhcnQgKiA0XSwgY250ICogc2l6ZW9mKGludCkgKiA0KTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFBpeGVsU2hhZGVyQ29uc3RhbnRGKAogICAgSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgVUlOVCBzdGFydCwKICAgIENPTlNUIGZsb2F0ICpzcmNEYXRhLAogICAgVUlOVCBjb3VudCkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIGludCBpOwoKICAgIFRSQUNFKCIoaWZhY2UgJXAsIHNyY0RhdGEgJXAsIHN0YXJ0ICVkLCBjb3VudCAlZClcbiIsCiAgICAgICAgICAgIGlmYWNlLCBzcmNEYXRhLCBzdGFydCwgY291bnQpOwoKICAgIC8qIFNwZWNpZmljYWxseSB0ZXN0IHN0YXJ0ID4gbGltaXQgdG8gY2F0Y2ggTUFYX1VJTlQgb3ZlcmZsb3dzIHdoZW4gYWRkaW5nIHN0YXJ0ICsgY291bnQgKi8KICAgIGlmIChzcmNEYXRhID09IE5VTEwgfHwgc3RhcnQgKyBjb3VudCA+IEdMX0xJTUlUUyhwc2hhZGVyX2NvbnN0YW50c0YpIHx8IHN0YXJ0ID4gR0xfTElNSVRTKHBzaGFkZXJfY29uc3RhbnRzRikpCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgbWVtY3B5KCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5waXhlbFNoYWRlckNvbnN0YW50RltzdGFydCAqIDRdLCBzcmNEYXRhLCBjb3VudCAqIHNpemVvZihmbG9hdCkgKiA0KTsKICAgIGlmKFRSQUNFX09OKGQzZCkpIHsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY291bnQ7IGkrKykKICAgICAgICAgICAgVFJBQ0UoIlNldCBGTE9BVCBjb25zdGFudCAldSB0byB7ICVmLCAlZiwgJWYsICVmIH1cbiIsIHN0YXJ0ICsgaSwKICAgICAgICAgICAgICAgIHNyY0RhdGFbaSo0XSwgc3JjRGF0YVtpKjQrMV0sIHNyY0RhdGFbaSo0KzJdLCBzcmNEYXRhW2kqNCszXSk7CiAgICB9CgogICAgZm9yIChpID0gc3RhcnQ7IGkgPCBjb3VudCArIHN0YXJ0OyArK2kpIHsKICAgICAgICBpZiAoIVRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQucGl4ZWxTaGFkZXJDb25zdGFudHNGW2ldKSB7CiAgICAgICAgICAgIGNvbnN0YW50c19lbnRyeSAqcHRyID0gTElTVF9FTlRSWShsaXN0X2hlYWQoJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnNldF9wY29uc3RhbnRzRiksIGNvbnN0YW50c19lbnRyeSwgZW50cnkpOwogICAgICAgICAgICBpZiAoIXB0ciB8fCBwdHItPmNvdW50ID49IHNpemVvZihwdHItPmlkeCkgLyBzaXplb2YoKnB0ci0+aWR4KSkgewogICAgICAgICAgICAgICAgcHRyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihjb25zdGFudHNfZW50cnkpKTsKICAgICAgICAgICAgICAgIGxpc3RfYWRkX2hlYWQoJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnNldF9wY29uc3RhbnRzRiwgJnB0ci0+ZW50cnkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHB0ci0+aWR4W3B0ci0+Y291bnQrK10gPSBpOwogICAgICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnBpeGVsU2hhZGVyQ29uc3RhbnRzRltpXSA9IFRSVUU7CiAgICAgICAgfQogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9QSVhFTFNIQURFUkNPTlNUQU5UKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQaXhlbFNoYWRlckNvbnN0YW50RigKICAgIElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgIFVJTlQgc3RhcnQsCiAgICBmbG9hdCAqZHN0RGF0YSwKICAgIFVJTlQgY291bnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpbnQgY250ID0gbWluKGNvdW50LCBHTF9MSU1JVFMocHNoYWRlcl9jb25zdGFudHNGKSAtIHN0YXJ0KTsKCiAgICBUUkFDRSgiKGlmYWNlICVwLCBkc3REYXRhICVwLCBzdGFydCAlZCwgY291bnQgJWQpXG4iLAogICAgICAgICAgICBpZmFjZSwgZHN0RGF0YSwgc3RhcnQsIGNvdW50KTsKCiAgICBpZiAoZHN0RGF0YSA9PSBOVUxMIHx8IGNudCA8IDApCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgbWVtY3B5KGRzdERhdGEsICZUaGlzLT5zdGF0ZUJsb2NrLT5waXhlbFNoYWRlckNvbnN0YW50RltzdGFydCAqIDRdLCBjbnQgKiBzaXplb2YoZmxvYXQpICogNCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKI2RlZmluZSBjb3B5X2FuZF9uZXh0KGRlc3QsIHNyYywgc2l6ZSkgbWVtY3B5KGRlc3QsIHNyYywgc2l6ZSk7IGRlc3QgKz0gKHNpemUpCnN0YXRpYyBIUkVTVUxUCnByb2Nlc3NfdmVydGljZXNfc3RyaWRlZChJV2luZUQzRERldmljZUltcGwgKlRoaXMsIERXT1JEIGR3RGVzdEluZGV4LCBEV09SRCBkd0NvdW50LCBXaW5lRGlyZWN0M0RWZXJ0ZXhTdHJpZGVkRGF0YSAqbHBTdHJpZGVEYXRhLCBJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKmRlc3QsIERXT1JEIGR3RmxhZ3MpIHsKICAgIGNoYXIgKmRlc3RfcHRyLCAqZGVzdF9jb252ID0gTlVMTCwgKmRlc3RfY29udl9hZGRyID0gTlVMTDsKICAgIHVuc2lnbmVkIGludCBpOwogICAgRFdPUkQgRGVzdEZWRiA9IGRlc3QtPmZ2ZjsKICAgIFdJTkVEM0RWSUVXUE9SVCB2cDsKICAgIFdJTkVEM0RNQVRSSVggbWF0LCBwcm9qX21hdCwgdmlld19tYXQsIHdvcmxkX21hdDsKICAgIEJPT0wgZG9DbGlwOwogICAgaW50IG51bVRleHR1cmVzOwoKICAgIGlmIChscFN0cmlkZURhdGEtPnUucy5ub3JtYWwubHBEYXRhKSB7CiAgICAgICAgV0FSTigiIGxpZ2h0aW5nIHN0YXRlIG5vdCBzYXZlZCB5ZXQuLi4gU29tZSBzdHJhbmdlIHN0dWZmIG1heSBoYXBwZW4gIVxuIik7CiAgICB9CgogICAgaWYgKGxwU3RyaWRlRGF0YS0+dS5zLnBvc2l0aW9uLmxwRGF0YSA9PSBOVUxMKSB7CiAgICAgICAgRVJSKCJTb3VyY2UgaGFzIG5vIHBvc2l0aW9uIG1hc2tcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIC8qIFdlIG1pZ2h0IGFjY2VzcyBWQk9zIGZyb20gdGhpcyBjb2RlLCBzbyBob2xkIHRoZSBsb2NrICovCiAgICBFTlRFUl9HTCgpOwoKICAgIGlmIChkZXN0LT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPT0gTlVMTCkgewogICAgICAgIC8qIFRoaXMgbWF5IGhhcHBlbiBpZiB3ZSBkbyBkaXJlY3QgbG9ja2luZyBpbnRvIGEgdmJvLiBVbmxpa2VseSwKICAgICAgICAgKiBidXQgdGhlb3JldGljYWxseSBwb3NzaWJsZShkZHJhdyBwcm9jZXNzdmVydGljZXMgdGVzdCkKICAgICAgICAgKi8KICAgICAgICBkZXN0LT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZGVzdC0+cmVzb3VyY2Uuc2l6ZSk7CiAgICAgICAgaWYoIWRlc3QtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgewogICAgICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnlcbiIpOwogICAgICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgICAgICB9CiAgICAgICAgaWYoZGVzdC0+dmJvKSB7CiAgICAgICAgICAgIHZvaWQgKnNyYzsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEJpbmRCdWZmZXJBUkIoR0xfQVJSQVlfQlVGRkVSX0FSQiwgZGVzdC0+dmJvKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRCdWZmZXJBUkIiKTsKICAgICAgICAgICAgc3JjID0gR0xfRVhUQ0FMTChnbE1hcEJ1ZmZlckFSQihHTF9BUlJBWV9CVUZGRVJfQVJCLCBHTF9SRUFEX09OTFlfQVJCKSk7CiAgICAgICAgICAgIGlmKHNyYykgewogICAgICAgICAgICAgICAgbWVtY3B5KGRlc3QtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwgc3JjLCBkZXN0LT5yZXNvdXJjZS5zaXplKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBHTF9FWFRDQUxMKGdsVW5tYXBCdWZmZXJBUkIoR0xfQVJSQVlfQlVGRkVSX0FSQikpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xVbm1hcEJ1ZmZlckFSQiIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBHZXQgYSBwb2ludGVyIGludG8gdGhlIGRlc3RpbmF0aW9uIHZibyhjcmVhdGUgb25lIGlmIG5vbmUgZXhpc3RzKSBhbmQKICAgICAqIHdyaXRlIGNvcnJlY3Qgb3BlbmdsIGRhdGEgaW50byBpdC4gSXQncyBjaGVhcCBhbmQgYWxsb3dzIHVzIHRvIHJ1biBkcmF3U3RyaWRlZEZhc3QKICAgICAqLwogICAgaWYoIWRlc3QtPnZibyAmJiBHTF9TVVBQT1JUKEFSQl9WRVJURVhfQlVGRkVSX09CSkVDVCkpIHsKICAgICAgICBDcmVhdGVWQk8oZGVzdCk7CiAgICB9CgogICAgaWYoZGVzdC0+dmJvKSB7CiAgICAgICAgdW5zaWduZWQgY2hhciBleHRyYWJ5dGVzID0gMDsKICAgICAgICAvKiBJZiB0aGUgZGVzdGluYXRpb24gdmVydGV4IGJ1ZmZlciBoYXMgRDNERlZGX1hZWiBwb3NpdGlvbihub24tcmh3KSwgbmF0aXZlIGQzZCB3cml0ZXMgUkhXIHBvc2l0aW9uLCB3aGVyZSB0aGUgUkhXCiAgICAgICAgICogZ2V0cyB3cml0dGVuIGludG8gdGhlIDQgYnl0ZXMgYWZ0ZXIgdGhlIFogcG9zaXRpb24uIEluIHRoZSBjYXNlIG9mIGEgZGVzdCBidWZmZXIgdGhhdCBvbmx5IGhhcyBEM0RGVkZfWFlaIGRhdGEsCiAgICAgICAgICogdGhpcyBtYXkgd3JpdGUgNCBleHRyYSBieXRlcyBiZXlvbmQgdGhlIGFyZWEgdGhhdCBzaG91bGQgYmUgd3JpdHRlbgogICAgICAgICAqLwogICAgICAgIGlmKERlc3RGVkYgPT0gV0lORUQzREZWRl9YWVopIGV4dHJhYnl0ZXMgPSA0OwogICAgICAgIGRlc3RfY29udl9hZGRyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIGR3Q291bnQgKiBnZXRfZmxleGlibGVfdmVydGV4X3NpemUoRGVzdEZWRikgKyBleHRyYWJ5dGVzKTsKICAgICAgICBpZighZGVzdF9jb252X2FkZHIpIHsKICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5XG4iKTsKICAgICAgICAgICAgLyogQ29udGludWUgd2l0aG91dCBzdG9yaW5nIGNvbnZlcnRlZCB2ZXJ0aWNlcyAqLwogICAgICAgIH0KICAgICAgICBkZXN0X2NvbnYgPSBkZXN0X2NvbnZfYWRkcjsKICAgIH0KCiAgICAvKiBTaG91bGQgSSBjbGlwPwogICAgICogYSkgV0lORUQzRFJTX0NMSVBQSU5HIGlzIGVuYWJsZWQKICAgICAqIGIpIFdJTkVEM0RWT1BfQ0xJUCBpcyBwYXNzZWQKICAgICAqLwogICAgaWYoVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbV0lORUQzRFJTX0NMSVBQSU5HXSkgewogICAgICAgIHN0YXRpYyBCT09MIHdhcm5lZCA9IEZBTFNFOwogICAgICAgIC8qCiAgICAgICAgICogVGhlIGNsaXBwaW5nIGNvZGUgaXMgbm90IHF1aXRlIGNvcnJlY3QuIFNvbWUgdGhpbmdzIG5lZWQKICAgICAgICAgKiB0byBiZSBjaGVja2VkIGFnYWluc3QgSURpcmVjdDNERGV2aWNlMyAoISksIGQzZDggYW5kIGQzZDksCiAgICAgICAgICogc28gZGlzYWJsZSBjbGlwcGluZyBmb3Igbm93LgogICAgICAgICAqIChUaGUgZ3JhcGhpY3MgaW4gSGFsZi1MaWZlIGFyZSBicm9rZW4sIGFuZCBteSBwcm9jZXNzdmVydGljZXMKICAgICAgICAgKiAgdGVzdCBjcmFzaGVzIHdpdGggSURpcmVjdDNERGV2aWNlMykKICAgICAgICBkb0NsaXAgPSBUUlVFOwogICAgICAgICAqLwogICAgICAgIGRvQ2xpcCA9IEZBTFNFOwogICAgICAgIGlmKCF3YXJuZWQpIHsKICAgICAgICAgICB3YXJuZWQgPSBUUlVFOwogICAgICAgICAgIEZJWE1FKCJDbGlwcGluZyBpcyBicm9rZW4gYW5kIGRpc2FibGVkIGZvciBub3dcbiIpOwogICAgICAgIH0KICAgIH0gZWxzZSBkb0NsaXAgPSBGQUxTRTsKICAgIGRlc3RfcHRyID0gKChjaGFyICopIGRlc3QtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgKyBkd0Rlc3RJbmRleCAqIGdldF9mbGV4aWJsZV92ZXJ0ZXhfc2l6ZShEZXN0RlZGKTsKCiAgICBJV2luZUQzRERldmljZV9HZXRUcmFuc2Zvcm0oIChJV2luZUQzRERldmljZSAqKSBUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNEVFNfVklFVywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnZpZXdfbWF0KTsKICAgIElXaW5lRDNERGV2aWNlX0dldFRyYW5zZm9ybSggKElXaW5lRDNERGV2aWNlICopIFRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RUU19QUk9KRUNUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcHJval9tYXQpOwogICAgSVdpbmVEM0REZXZpY2VfR2V0VHJhbnNmb3JtKCAoSVdpbmVEM0REZXZpY2UgKikgVGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFRTX1dPUkxETUFUUklYKDApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmd29ybGRfbWF0KTsKCiAgICBUUkFDRSgiVmlldyBtYXQ6XG4iKTsKICAgIFRSQUNFKCIlZiAlZiAlZiAlZlxuIiwgdmlld19tYXQudS5zLl8xMSwgdmlld19tYXQudS5zLl8xMiwgdmlld19tYXQudS5zLl8xMywgdmlld19tYXQudS5zLl8xNCk7CiAgICBUUkFDRSgiJWYgJWYgJWYgJWZcbiIsIHZpZXdfbWF0LnUucy5fMjEsIHZpZXdfbWF0LnUucy5fMjIsIHZpZXdfbWF0LnUucy5fMjMsIHZpZXdfbWF0LnUucy5fMjQpOwogICAgVFJBQ0UoIiVmICVmICVmICVmXG4iLCB2aWV3X21hdC51LnMuXzMxLCB2aWV3X21hdC51LnMuXzMyLCB2aWV3X21hdC51LnMuXzMzLCB2aWV3X21hdC51LnMuXzM0KTsKICAgIFRSQUNFKCIlZiAlZiAlZiAlZlxuIiwgdmlld19tYXQudS5zLl80MSwgdmlld19tYXQudS5zLl80Miwgdmlld19tYXQudS5zLl80Mywgdmlld19tYXQudS5zLl80NCk7CgogICAgVFJBQ0UoIlByb2ogbWF0OlxuIik7CiAgICBUUkFDRSgiJWYgJWYgJWYgJWZcbiIsIHByb2pfbWF0LnUucy5fMTEsIHByb2pfbWF0LnUucy5fMTIsIHByb2pfbWF0LnUucy5fMTMsIHByb2pfbWF0LnUucy5fMTQpOwogICAgVFJBQ0UoIiVmICVmICVmICVmXG4iLCBwcm9qX21hdC51LnMuXzIxLCBwcm9qX21hdC51LnMuXzIyLCBwcm9qX21hdC51LnMuXzIzLCBwcm9qX21hdC51LnMuXzI0KTsKICAgIFRSQUNFKCIlZiAlZiAlZiAlZlxuIiwgcHJval9tYXQudS5zLl8zMSwgcHJval9tYXQudS5zLl8zMiwgcHJval9tYXQudS5zLl8zMywgcHJval9tYXQudS5zLl8zNCk7CiAgICBUUkFDRSgiJWYgJWYgJWYgJWZcbiIsIHByb2pfbWF0LnUucy5fNDEsIHByb2pfbWF0LnUucy5fNDIsIHByb2pfbWF0LnUucy5fNDMsIHByb2pfbWF0LnUucy5fNDQpOwoKICAgIFRSQUNFKCJXb3JsZCBtYXQ6XG4iKTsKICAgIFRSQUNFKCIlZiAlZiAlZiAlZlxuIiwgd29ybGRfbWF0LnUucy5fMTEsIHdvcmxkX21hdC51LnMuXzEyLCB3b3JsZF9tYXQudS5zLl8xMywgd29ybGRfbWF0LnUucy5fMTQpOwogICAgVFJBQ0UoIiVmICVmICVmICVmXG4iLCB3b3JsZF9tYXQudS5zLl8yMSwgd29ybGRfbWF0LnUucy5fMjIsIHdvcmxkX21hdC51LnMuXzIzLCB3b3JsZF9tYXQudS5zLl8yNCk7CiAgICBUUkFDRSgiJWYgJWYgJWYgJWZcbiIsIHdvcmxkX21hdC51LnMuXzMxLCB3b3JsZF9tYXQudS5zLl8zMiwgd29ybGRfbWF0LnUucy5fMzMsIHdvcmxkX21hdC51LnMuXzM0KTsKICAgIFRSQUNFKCIlZiAlZiAlZiAlZlxuIiwgd29ybGRfbWF0LnUucy5fNDEsIHdvcmxkX21hdC51LnMuXzQyLCB3b3JsZF9tYXQudS5zLl80Mywgd29ybGRfbWF0LnUucy5fNDQpOwoKICAgIC8qIEdldCB0aGUgdmlld3BvcnQgKi8KICAgIElXaW5lRDNERGV2aWNlX0dldFZpZXdwb3J0KCAoSVdpbmVEM0REZXZpY2UgKikgVGhpcywgJnZwKTsKICAgIFRSQUNFKCJWaWV3cG9ydDogWD0lZCwgWT0lZCwgV2lkdGg9JWQsIEhlaWdodD0lZCwgTWluWj0lZiwgTWF4Wj0lZlxuIiwKICAgICAgICAgIHZwLlgsIHZwLlksIHZwLldpZHRoLCB2cC5IZWlnaHQsIHZwLk1pblosIHZwLk1heFopOwoKICAgIG11bHRpcGx5X21hdHJpeCgmbWF0LCZ2aWV3X21hdCwmd29ybGRfbWF0KTsKICAgIG11bHRpcGx5X21hdHJpeCgmbWF0LCZwcm9qX21hdCwmbWF0KTsKCiAgICBudW1UZXh0dXJlcyA9IChEZXN0RlZGICYgV0lORUQzREZWRl9URVhDT1VOVF9NQVNLKSA+PiBXSU5FRDNERlZGX1RFWENPVU5UX1NISUZUOwoKICAgIGZvciAoaSA9IDA7IGkgPCBkd0NvdW50OyBpKz0gMSkgewogICAgICAgIHVuc2lnbmVkIGludCB0ZXhfaW5kZXg7CgogICAgICAgIGlmICggKChEZXN0RlZGICYgV0lORUQzREZWRl9QT1NJVElPTl9NQVNLKSA9PSBXSU5FRDNERlZGX1hZWiApIHx8CiAgICAgICAgICAgICAoKERlc3RGVkYgJiBXSU5FRDNERlZGX1BPU0lUSU9OX01BU0spID09IFdJTkVEM0RGVkZfWFlaUkhXICkgKSB7CiAgICAgICAgICAgIC8qIFRoZSBwb3NpdGlvbiBmaXJzdCAqLwogICAgICAgICAgICBmbG9hdCAqcCA9CiAgICAgICAgICAgICAgKGZsb2F0ICopICgoKGNoYXIgKikgbHBTdHJpZGVEYXRhLT51LnMucG9zaXRpb24ubHBEYXRhKSArIGkgKiBscFN0cmlkZURhdGEtPnUucy5wb3NpdGlvbi5kd1N0cmlkZSk7CiAgICAgICAgICAgIGZsb2F0IHgsIHksIHosIHJodzsKICAgICAgICAgICAgVFJBQ0UoIkluOiAoICUwNi4yZiAlMDYuMmYgJTA2LjJmIClcbiIsIHBbMF0sIHBbMV0sIHBbMl0pOwoKICAgICAgICAgICAgLyogTXVsdGlwbGljYXRpb24gd2l0aCB3b3JsZCwgdmlldyBhbmQgcHJvamVjdGlvbiBtYXRyaXggKi8KICAgICAgICAgICAgeCA9ICAgKHBbMF0gKiBtYXQudS5zLl8xMSkgKyAocFsxXSAqIG1hdC51LnMuXzIxKSArIChwWzJdICogbWF0LnUucy5fMzEpICsgKDEuMCAqIG1hdC51LnMuXzQxKTsKICAgICAgICAgICAgeSA9ICAgKHBbMF0gKiBtYXQudS5zLl8xMikgKyAocFsxXSAqIG1hdC51LnMuXzIyKSArIChwWzJdICogbWF0LnUucy5fMzIpICsgKDEuMCAqIG1hdC51LnMuXzQyKTsKICAgICAgICAgICAgeiA9ICAgKHBbMF0gKiBtYXQudS5zLl8xMykgKyAocFsxXSAqIG1hdC51LnMuXzIzKSArIChwWzJdICogbWF0LnUucy5fMzMpICsgKDEuMCAqIG1hdC51LnMuXzQzKTsKICAgICAgICAgICAgcmh3ID0gKHBbMF0gKiBtYXQudS5zLl8xNCkgKyAocFsxXSAqIG1hdC51LnMuXzI0KSArIChwWzJdICogbWF0LnUucy5fMzQpICsgKDEuMCAqIG1hdC51LnMuXzQ0KTsKCiAgICAgICAgICAgIFRSQUNFKCJ4PSVmIHk9JWYgej0lZiByaHc9JWZcbiIsIHgsIHksIHosIHJodyk7CgogICAgICAgICAgICAvKiBXQVJOSU5HOiBUaGUgZm9sbG93aW5nIHRoaW5ncyBhcmUgdGFrZW4gZnJvbSBkM2Q3IGFuZCB3ZXJlIG5vdCB5ZXQgY2hlY2tlZAogICAgICAgICAgICAgKiBhZ2FpbnN0IGQzZDggb3IgZDNkOSEKICAgICAgICAgICAgICovCgogICAgICAgICAgICAvKiBDbGlwcGluZyBjb25kaXRpb25zOiBGcm9tCiAgICAgICAgICAgICAqIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vYXJjaGl2ZS9kZWZhdWx0LmFzcD91cmw9L2FyY2hpdmUvZW4tdXMvZGlyZWN0eDlfYy9kaXJlY3R4L2dyYXBoaWNzL3Byb2dyYW1taW5nZ3VpZGUvZml4ZWRmdW5jdGlvbi92aWV3cG9ydHNjbGlwcGluZy9jbGlwcGluZ3ZvbHVtZXMuYXNwCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEEgdmVydGV4IGlzIGNsaXBwZWQgaWYgaXQgZG9lcyBub3QgbWF0Y2ggdGhlIGZvbGxvd2luZyByZXF1aXJlbWVudHMKICAgICAgICAgICAgICogLXJodyA8IHggPD0gcmh3CiAgICAgICAgICAgICAqIC1yaHcgPCB5IDw9IHJodwogICAgICAgICAgICAgKiAgICAwIDwgeiA8PSByaHcKICAgICAgICAgICAgICogICAgMCA8IHJodyAoIE5vdCBpbiBkM2Q3LCBidXQgdGVzdGVkIGluIGQzZDcpCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIElmIGNsaXBwaW5nIGlzIG9uIGlzIGRldGVybWluZWQgYnkgdGhlIEQzRFZPUF9DTElQIGZsYWcgaW4gRDNENywgYW5kCiAgICAgICAgICAgICAqIGJ5IHRoZSBEM0RSU19DTElQUElORyBpbiBEM0Q5KGFjY29yZGluZyB0byB0aGUgbXNkbiwgbm90IGNoZWNrZWQpCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgaWYoICFkb0NsaXAgfHwKICAgICAgICAgICAgICAgICggKC1yaHcgLWVwcyA8IHgpICYmICgtcmh3IC1lcHMgPCB5KSAmJiAoIC1lcHMgPCB6KSAmJgogICAgICAgICAgICAgICAgICAoeCA8PSByaHcgKyBlcHMpICYmICh5IDw9IHJodyArIGVwcyApICYmICh6IDw9IHJodyArIGVwcykgJiYgCiAgICAgICAgICAgICAgICAgICggcmh3ID4gZXBzICkgKSApIHsKCiAgICAgICAgICAgICAgICAvKiAiTm9ybWFsIiB2aWV3cG9ydCB0cmFuc2Zvcm1hdGlvbiAobm90IGNsaXBwZWQpCiAgICAgICAgICAgICAgICAgKiAxKSBUaGUgdmFsdWVzIGFyZSBkaXZpZGVkIGJ5IHJodwogICAgICAgICAgICAgICAgICogMikgVGhlIHkgYXhpcyBpcyBuZWdhdGl2ZSwgc28gbXVsdGlwbHkgaXQgd2l0aCAtMQogICAgICAgICAgICAgICAgICogMykgU2NyZWVuIGNvb3JkaW5hdGVzIGdvIGZyb20gLShXaWR0aC8yKSB0byArKFdpZHRoLzIpIGFuZAogICAgICAgICAgICAgICAgICogICAgLShIZWlnaHQvMikgdG8gKyhIZWlnaHQvMikuIFRoZSB6IHJhbmdlIGlzIE1pblogdG8gTWF4WgogICAgICAgICAgICAgICAgICogNCkgTXVsdGlwbHkgeCB3aXRoIFdpZHRoLzIgYW5kIGFkZCBXaWR0aC8yCiAgICAgICAgICAgICAgICAgKiA1KSBUaGUgc2FtZSBmb3IgdGhlIGhlaWdodAogICAgICAgICAgICAgICAgICogNikgQWRkIHRoZSB2aWV3cG9pbnQgWCBhbmQgWSB0byB0aGUgMkQgY29vcmRpbmF0ZXMgYW5kCiAgICAgICAgICAgICAgICAgKiAgICBUaGUgbWluaW11bSBaIHZhbHVlIHRvIHoKICAgICAgICAgICAgICAgICAqIDcpIHJodyA9IDEgLyByaHcgUmVjaXByb2NhbCBvZiBIb21vZ2VuZW91cyBXLi4uLgogICAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgICAqIFdlbGwsIGJhc2ljYWxseSBpdCdzIHNpbXBseSBhIGxpbmVhciB0cmFuc2Zvcm1hdGlvbiBpbnRvIHZpZXdwb3J0CiAgICAgICAgICAgICAgICAgKiBjb29yZGluYXRlcwogICAgICAgICAgICAgICAgICovCgogICAgICAgICAgICAgICAgeCAvPSByaHc7CiAgICAgICAgICAgICAgICB5IC89IHJodzsKICAgICAgICAgICAgICAgIHogLz0gcmh3OwoKICAgICAgICAgICAgICAgIHkgKj0gLTE7CgogICAgICAgICAgICAgICAgeCAqPSB2cC5XaWR0aCAvIDI7CiAgICAgICAgICAgICAgICB5ICo9IHZwLkhlaWdodCAvIDI7CiAgICAgICAgICAgICAgICB6ICo9IHZwLk1heFogLSB2cC5NaW5aOwoKICAgICAgICAgICAgICAgIHggKz0gdnAuV2lkdGggLyAyICsgdnAuWDsKICAgICAgICAgICAgICAgIHkgKz0gdnAuSGVpZ2h0IC8gMiArIHZwLlk7CiAgICAgICAgICAgICAgICB6ICs9IHZwLk1pblo7CgogICAgICAgICAgICAgICAgcmh3ID0gMSAvIHJodzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8qIFRoYXQgdmVydGV4IGdvdCBjbGlwcGVkCiAgICAgICAgICAgICAgICAgKiBDb250cmFyeSB0byBPcGVuR0wgaXQgaXMgbm90IGRyb3BwZWQgY29tcGxldGVseSwgaXQganVzdAogICAgICAgICAgICAgICAgICogdW5kZXJnb2VzIGEgZGlmZmVyZW50IGNhbGN1bGF0aW9uLgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBUUkFDRSgiVmVydGV4IGdvdCBjbGlwcGVkXG4iKTsKICAgICAgICAgICAgICAgIHggKz0gcmh3OwogICAgICAgICAgICAgICAgeSArPSByaHc7CgogICAgICAgICAgICAgICAgeCAgLz0gMjsKICAgICAgICAgICAgICAgIHkgIC89IDI7CgogICAgICAgICAgICAgICAgLyogTXNkbiBtZW50aW9ucyB0aGF0IERpcmVjdDNEOSBrZWVwcyBhIGxpc3Qgb2YgY2xpcHBlZCB2ZXJ0aWNlcwogICAgICAgICAgICAgICAgICogb3V0c2lkZSBvZiB0aGUgbWFpbiB2ZXJ0ZXggYnVmZmVyIG1lbW9yeS4gVGhhdCBuZWVkcyBzb21lIG1vcmUKICAgICAgICAgICAgICAgICAqIGludmVzdGlnYXRpb24uLi4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICB9CgogICAgICAgICAgICBUUkFDRSgiV3JpdGluZyAoJWYgJWYgJWYpICVmXG4iLCB4LCB5LCB6LCByaHcpOwoKCiAgICAgICAgICAgICggKGZsb2F0ICopIGRlc3RfcHRyKVswXSA9IHg7CiAgICAgICAgICAgICggKGZsb2F0ICopIGRlc3RfcHRyKVsxXSA9IHk7CiAgICAgICAgICAgICggKGZsb2F0ICopIGRlc3RfcHRyKVsyXSA9IHo7CiAgICAgICAgICAgICggKGZsb2F0ICopIGRlc3RfcHRyKVszXSA9IHJodzsgLyogU0lDLCBzZWUgZGRyYXcgdGVzdCEgKi8KCiAgICAgICAgICAgIGRlc3RfcHRyICs9IDMgKiBzaXplb2YoZmxvYXQpOwoKICAgICAgICAgICAgaWYoKERlc3RGVkYgJiBXSU5FRDNERlZGX1BPU0lUSU9OX01BU0spID09IFdJTkVEM0RGVkZfWFlaUkhXKSB7CiAgICAgICAgICAgICAgICBkZXN0X3B0ciArPSBzaXplb2YoZmxvYXQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZihkZXN0X2NvbnYpIHsKICAgICAgICAgICAgICAgIGZsb2F0IHcgPSAxIC8gcmh3OwogICAgICAgICAgICAgICAgKCAoZmxvYXQgKikgZGVzdF9jb252KVswXSA9IHggKiB3OwogICAgICAgICAgICAgICAgKCAoZmxvYXQgKikgZGVzdF9jb252KVsxXSA9IHkgKiB3OwogICAgICAgICAgICAgICAgKCAoZmxvYXQgKikgZGVzdF9jb252KVsyXSA9IHogKiB3OwogICAgICAgICAgICAgICAgKCAoZmxvYXQgKikgZGVzdF9jb252KVszXSA9IHc7CgogICAgICAgICAgICAgICAgZGVzdF9jb252ICs9IDMgKiBzaXplb2YoZmxvYXQpOwoKICAgICAgICAgICAgICAgIGlmKChEZXN0RlZGICYgV0lORUQzREZWRl9QT1NJVElPTl9NQVNLKSA9PSBXSU5FRDNERlZGX1hZWlJIVykgewogICAgICAgICAgICAgICAgICAgIGRlc3RfY29udiArPSBzaXplb2YoZmxvYXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChEZXN0RlZGICYgV0lORUQzREZWRl9QU0laRSkgewogICAgICAgICAgICBkZXN0X3B0ciArPSBzaXplb2YoRFdPUkQpOwogICAgICAgICAgICBpZihkZXN0X2NvbnYpIGRlc3RfY29udiArPSBzaXplb2YoRFdPUkQpOwogICAgICAgIH0KICAgICAgICBpZiAoRGVzdEZWRiAmIFdJTkVEM0RGVkZfTk9STUFMKSB7CiAgICAgICAgICAgIGZsb2F0ICpub3JtYWwgPQogICAgICAgICAgICAgIChmbG9hdCAqKSAoKChmbG9hdCAqKSBscFN0cmlkZURhdGEtPnUucy5ub3JtYWwubHBEYXRhKSArIGkgKiBscFN0cmlkZURhdGEtPnUucy5ub3JtYWwuZHdTdHJpZGUpOwogICAgICAgICAgICAvKiBBRkFJSyB0aGlzIHNob3VsZCBnbyBpbnRvIHRoZSBsaWdodGluZyBpbmZvcm1hdGlvbiAqLwogICAgICAgICAgICBGSVhNRSgiRGlkbid0IGV4cGVjdCB0aGUgZGVzdGluYXRpb24gdG8gaGF2ZSBhIG5vcm1hbFxuIik7CiAgICAgICAgICAgIGNvcHlfYW5kX25leHQoZGVzdF9wdHIsIG5vcm1hbCwgMyAqIHNpemVvZihmbG9hdCkpOwogICAgICAgICAgICBpZihkZXN0X2NvbnYpIHsKICAgICAgICAgICAgICAgIGNvcHlfYW5kX25leHQoZGVzdF9jb252LCBub3JtYWwsIDMgKiBzaXplb2YoZmxvYXQpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKERlc3RGVkYgJiBXSU5FRDNERlZGX0RJRkZVU0UpIHsKICAgICAgICAgICAgRFdPUkQgKmNvbG9yX2QgPSAKICAgICAgICAgICAgICAoRFdPUkQgKikgKCgoY2hhciAqKSBscFN0cmlkZURhdGEtPnUucy5kaWZmdXNlLmxwRGF0YSkgKyBpICogbHBTdHJpZGVEYXRhLT51LnMuZGlmZnVzZS5kd1N0cmlkZSk7CiAgICAgICAgICAgIGlmKCFjb2xvcl9kKSB7CiAgICAgICAgICAgICAgICBzdGF0aWMgQk9PTCB3YXJuZWQgPSBGQUxTRTsKCiAgICAgICAgICAgICAgICBpZighd2FybmVkKSB7CiAgICAgICAgICAgICAgICAgICAgRVJSKCJObyBkaWZmdXNlIGNvbG9yIGluIHNvdXJjZSwgYnV0IGRlc3RpbmF0aW9uIGhhcyBvbmVcbiIpOwogICAgICAgICAgICAgICAgICAgIHdhcm5lZCA9IFRSVUU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgKiggKERXT1JEICopIGRlc3RfcHRyKSA9IDB4ZmZmZmZmZmY7CiAgICAgICAgICAgICAgICBkZXN0X3B0ciArPSBzaXplb2YoRFdPUkQpOwoKICAgICAgICAgICAgICAgIGlmKGRlc3RfY29udikgewogICAgICAgICAgICAgICAgICAgICooIChEV09SRCAqKSBkZXN0X2NvbnYpID0gMHhmZmZmZmZmZjsKICAgICAgICAgICAgICAgICAgICBkZXN0X2NvbnYgKz0gc2l6ZW9mKERXT1JEKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIGNvcHlfYW5kX25leHQoZGVzdF9wdHIsIGNvbG9yX2QsIHNpemVvZihEV09SRCkpOwogICAgICAgICAgICAgICAgaWYoZGVzdF9jb252KSB7CiAgICAgICAgICAgICAgICAgICAgKiggKERXT1JEICopIGRlc3RfY29udikgID0gKCpjb2xvcl9kICYgMHhmZjAwZmYwMCkgICAgICA7IC8qIEFscGhhICsgZ3JlZW4gKi8KICAgICAgICAgICAgICAgICAgICAqKCAoRFdPUkQgKikgZGVzdF9jb252KSB8PSAoKmNvbG9yX2QgJiAweDAwZmYwMDAwKSA+PiAxNjsgLyogUmVkICovCiAgICAgICAgICAgICAgICAgICAgKiggKERXT1JEICopIGRlc3RfY29udikgfD0gKCpjb2xvcl9kICYgMHhmZjAwMDBmZikgPDwgMTY7IC8qIEJsdWUgKi8KICAgICAgICAgICAgICAgICAgICBkZXN0X2NvbnYgKz0gc2l6ZW9mKERXT1JEKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKERlc3RGVkYgJiBXSU5FRDNERlZGX1NQRUNVTEFSKSB7IAogICAgICAgICAgICAvKiBXaGF0J3MgdGhlIGNvbG9yIHZhbHVlIGluIHRoZSBmZWVkYmFjayBidWZmZXI/ICovCiAgICAgICAgICAgIERXT1JEICpjb2xvcl9zID0gCiAgICAgICAgICAgICAgKERXT1JEICopICgoKGNoYXIgKikgbHBTdHJpZGVEYXRhLT51LnMuc3BlY3VsYXIubHBEYXRhKSArIGkgKiBscFN0cmlkZURhdGEtPnUucy5zcGVjdWxhci5kd1N0cmlkZSk7CiAgICAgICAgICAgIGlmKCFjb2xvcl9zKSB7CiAgICAgICAgICAgICAgICBzdGF0aWMgQk9PTCB3YXJuZWQgPSBGQUxTRTsKCiAgICAgICAgICAgICAgICBpZighd2FybmVkKSB7CiAgICAgICAgICAgICAgICAgICAgRVJSKCJObyBzcGVjdWxhciBjb2xvciBpbiBzb3VyY2UsIGJ1dCBkZXN0aW5hdGlvbiBoYXMgb25lXG4iKTsKICAgICAgICAgICAgICAgICAgICB3YXJuZWQgPSBUUlVFOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICooIChEV09SRCAqKSBkZXN0X3B0cikgPSAweEZGMDAwMDAwOwogICAgICAgICAgICAgICAgZGVzdF9wdHIgKz0gc2l6ZW9mKERXT1JEKTsKCiAgICAgICAgICAgICAgICBpZihkZXN0X2NvbnYpIHsKICAgICAgICAgICAgICAgICAgICAqKCAoRFdPUkQgKikgZGVzdF9jb252KSA9IDB4RkYwMDAwMDA7CiAgICAgICAgICAgICAgICAgICAgZGVzdF9jb252ICs9IHNpemVvZihEV09SRCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBjb3B5X2FuZF9uZXh0KGRlc3RfcHRyLCBjb2xvcl9zLCBzaXplb2YoRFdPUkQpKTsKICAgICAgICAgICAgICAgIGlmKGRlc3RfY29udikgewogICAgICAgICAgICAgICAgICAgICooIChEV09SRCAqKSBkZXN0X2NvbnYpICA9ICgqY29sb3JfcyAmIDB4ZmYwMGZmMDApICAgICAgOyAvKiBBbHBoYSArIGdyZWVuICovCiAgICAgICAgICAgICAgICAgICAgKiggKERXT1JEICopIGRlc3RfY29udikgfD0gKCpjb2xvcl9zICYgMHgwMGZmMDAwMCkgPj4gMTY7IC8qIFJlZCAqLwogICAgICAgICAgICAgICAgICAgICooIChEV09SRCAqKSBkZXN0X2NvbnYpIHw9ICgqY29sb3JfcyAmIDB4ZmYwMDAwZmYpIDw8IDE2OyAvKiBCbHVlICovCiAgICAgICAgICAgICAgICAgICAgZGVzdF9jb252ICs9IHNpemVvZihEV09SRCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvciAodGV4X2luZGV4ID0gMDsgdGV4X2luZGV4IDwgbnVtVGV4dHVyZXM7IHRleF9pbmRleCsrKSB7CiAgICAgICAgICAgIGZsb2F0ICp0ZXhfY29vcmQgPQogICAgICAgICAgICAgIChmbG9hdCAqKSAoKChjaGFyICopIGxwU3RyaWRlRGF0YS0+dS5zLnRleENvb3Jkc1t0ZXhfaW5kZXhdLmxwRGF0YSkgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgKiBscFN0cmlkZURhdGEtPnUucy50ZXhDb29yZHNbdGV4X2luZGV4XS5kd1N0cmlkZSk7CiAgICAgICAgICAgIGlmKCF0ZXhfY29vcmQpIHsKICAgICAgICAgICAgICAgIEVSUigiTm8gc291cmNlIHRleHR1cmUsIGJ1dCBkZXN0aW5hdGlvbiByZXF1ZXN0cyBvbmVcbiIpOwogICAgICAgICAgICAgICAgZGVzdF9wdHIrPUdFVF9URVhDT09SRF9TSVpFX0ZST01fRlZGKERlc3RGVkYsIHRleF9pbmRleCkgKiBzaXplb2YoZmxvYXQpOwogICAgICAgICAgICAgICAgaWYoZGVzdF9jb252KSBkZXN0X2NvbnYgKz0gR0VUX1RFWENPT1JEX1NJWkVfRlJPTV9GVkYoRGVzdEZWRiwgdGV4X2luZGV4KSAqIHNpemVvZihmbG9hdCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBjb3B5X2FuZF9uZXh0KGRlc3RfcHRyLCB0ZXhfY29vcmQsIEdFVF9URVhDT09SRF9TSVpFX0ZST01fRlZGKERlc3RGVkYsIHRleF9pbmRleCkgKiBzaXplb2YoZmxvYXQpKTsKICAgICAgICAgICAgICAgIGlmKGRlc3RfY29udikgewogICAgICAgICAgICAgICAgICAgIGNvcHlfYW5kX25leHQoZGVzdF9jb252LCB0ZXhfY29vcmQsIEdFVF9URVhDT09SRF9TSVpFX0ZST01fRlZGKERlc3RGVkYsIHRleF9pbmRleCkgKiBzaXplb2YoZmxvYXQpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBpZihkZXN0X2NvbnYpIHsKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9BUlJBWV9CVUZGRVJfQVJCLCBkZXN0LT52Ym8pKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kQnVmZmVyQVJCKEdMX0FSUkFZX0JVRkZFUl9BUkIpIik7CiAgICAgICAgR0xfRVhUQ0FMTChnbEJ1ZmZlclN1YkRhdGFBUkIoR0xfQVJSQVlfQlVGRkVSX0FSQiwgZHdEZXN0SW5kZXggKiBnZXRfZmxleGlibGVfdmVydGV4X3NpemUoRGVzdEZWRiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHdDb3VudCAqIGdldF9mbGV4aWJsZV92ZXJ0ZXhfc2l6ZShEZXN0RlZGKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXN0X2NvbnZfYWRkcikpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJ1ZmZlclN1YkRhdGFBUkIoR0xfQVJSQVlfQlVGRkVSX0FSQikiKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkZXN0X2NvbnZfYWRkcik7CiAgICB9CgogICAgTEVBVkVfR0woKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQojdW5kZWYgY29weV9hbmRfbmV4dAoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9Qcm9jZXNzVmVydGljZXMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIFNyY1N0YXJ0SW5kZXgsIFVJTlQgRGVzdEluZGV4LCBVSU5UIFZlcnRleENvdW50LCBJV2luZUQzRFZlcnRleEJ1ZmZlciogcERlc3RCdWZmZXIsIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb24qIHBWZXJ0ZXhEZWNsLCBEV09SRCBGbGFncykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgV2luZURpcmVjdDNEVmVydGV4U3RyaWRlZERhdGEgc3RyaWRlZDsKICAgIEJPT0wgdmJvID0gRkFMU0UsIHN0cmVhbVdhc1VQID0gVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtSXNVUDsKICAgIFRSQUNFKCIoJXApLT4oJWQsJWQsJWQsJXAsJXAsJWRcbiIsIFRoaXMsIFNyY1N0YXJ0SW5kZXgsIERlc3RJbmRleCwgVmVydGV4Q291bnQsIHBEZXN0QnVmZmVyLCBwVmVydGV4RGVjbCwgRmxhZ3MpOwoKICAgIGlmKHBWZXJ0ZXhEZWNsKSB7CiAgICAgICAgRVJSKCJPdXRwdXQgdmVydGV4IGRlY2xhcmF0aW9uIG5vdCBpbXBsZW1lbnRlZCB5ZXRcbiIpOwogICAgfQoKICAgIC8qIE5lZWQgYW55IGNvbnRleHQgdG8gd3JpdGUgdG8gdGhlIHZiby4gSW4gYSBub24tbXVsdGl0aHJlYWRlZCBlbnZpcm9ubWVudCBhIGNvbnRleHQgaXMgdGhlcmUgYW55d2F5LAogICAgICogYW5kIHRoaXMgY2FsbCBpcyBxdWl0ZSBwZXJmb3JtYW5jZSBjcml0aWNhbCwgc28gZG9uJ3QgY2FsbCBuZWVkbGVzc2x5CiAgICAgKi8KICAgIGlmKFRoaXMtPmNyZWF0ZVBhcm1zLkJlaGF2aW9yRmxhZ3MgJiBXSU5FRDNEQ1JFQVRFX01VTFRJVEhSRUFERUQpIHsKICAgICAgICBBY3RpdmF0ZUNvbnRleHQoVGhpcywgVGhpcy0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKICAgIH0KCiAgICAvKiBQcm9jZXNzVmVydGljZXMgcmVhZHMgZnJvbSB2ZXJ0ZXggYnVmZmVycywgd2hpY2ggaGF2ZSB0byBiZSBhc3NpZ25lZC4gRHJhd1ByaW1pdGl2ZSBhbmQgRHJhd1ByaW1pdGl2ZVVQCiAgICAgKiBjb250cm9sIHRoZSBzdHJlYW1Jc1VQIGZsYWcsIHRodXMgcmVzdG9yZSBpdCBhZnRlcndhcmRzLgogICAgICovCiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Jc1VQID0gRkFMU0U7CiAgICBtZW1zZXQoJnN0cmlkZWQsIDAsIHNpemVvZihzdHJpZGVkKSk7CiAgICBwcmltaXRpdmVEZWNsYXJhdGlvbkNvbnZlcnRUb1N0cmlkZWREYXRhKGlmYWNlLCBGQUxTRSwgJnN0cmlkZWQsICZ2Ym8pOwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtSXNVUCA9IHN0cmVhbVdhc1VQOwoKICAgIGlmKHZibyB8fCBTcmNTdGFydEluZGV4KSB7CiAgICAgICAgdW5zaWduZWQgaW50IGk7CiAgICAgICAgLyogUHJvY2Vzc1ZlcnRpY2VzIGNhbid0IGNvbnZlcnQgRlJPTSBhIHZibywgYW5kIHZlcnRleCBidWZmZXJzIHVzZWQgdG8gc291cmNlIGludG8gUHJvY2VzVmVydGljc2UgYXJlCiAgICAgICAgICogdW5saWtlbHkgdG8gZXZlciBiZSB1c2VkIGZvciBkcmF3aW5nLiBSZWxlYXNlIHZib3MgaW4gdGhvc2UgYnVmZmVycyBhbmQgZml4IHVwIHRoZSBzdHJpZGVkIHN0cnVjdHVyZQogICAgICAgICAqCiAgICAgICAgICogQWxzbyBnZXQgdGhlIHN0YXJ0IGluZGV4IGluLCBidXQgb25seSBsb29wIG92ZXIgYWxsIGVsZW1lbnRzIGlmIHRoZXJlJ3Mgc29tZXRoaW5nIHRvIGFkZCBhdCBhbGwuCiAgICAgICAgICovCiNkZWZpbmUgRklYU1JDKHR5cGUpIFwKICAgICAgICBpZihzdHJpZGVkLnUucy50eXBlLlZCTykgeyBcCiAgICAgICAgICAgIElXaW5lRDNEVmVydGV4QnVmZmVySW1wbCAqdmIgPSAoSVdpbmVEM0RWZXJ0ZXhCdWZmZXJJbXBsICopIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtzdHJpZGVkLnUucy50eXBlLnN0cmVhbU5vXTsgXAogICAgICAgICAgICBzdHJpZGVkLnUucy50eXBlLlZCTyA9IDA7IFwKICAgICAgICAgICAgc3RyaWRlZC51LnMudHlwZS5scERhdGEgPSAoQllURSAqKSAoKHVuc2lnbmVkIGxvbmcpIHN0cmlkZWQudS5zLnR5cGUubHBEYXRhICsgKHVuc2lnbmVkIGxvbmcpIHZiLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOyBcCiAgICAgICAgICAgIEVOVEVSX0dMKCk7IFwKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbERlbGV0ZUJ1ZmZlcnNBUkIoMSwgJnZiLT52Ym8pKTsgXAogICAgICAgICAgICB2Yi0+dmJvID0gMDsgXAogICAgICAgICAgICBMRUFWRV9HTCgpOyBcCiAgICAgICAgfSBcCiAgICAgICAgaWYoc3RyaWRlZC51LnMudHlwZS5scERhdGEpIHsgXAogICAgICAgICAgICBzdHJpZGVkLnUucy50eXBlLmxwRGF0YSArPSBzdHJpZGVkLnUucy50eXBlLmR3U3RyaWRlICogU3JjU3RhcnRJbmRleDsgXAogICAgICAgIH0KICAgICAgICBGSVhTUkMocG9zaXRpb24pOwogICAgICAgIEZJWFNSQyhibGVuZFdlaWdodHMpOwogICAgICAgIEZJWFNSQyhibGVuZE1hdHJpeEluZGljZXMpOwogICAgICAgIEZJWFNSQyhub3JtYWwpOwogICAgICAgIEZJWFNSQyhwU2l6ZSk7CiAgICAgICAgRklYU1JDKGRpZmZ1c2UpOwogICAgICAgIEZJWFNSQyhzcGVjdWxhcik7CiAgICAgICAgZm9yKGkgPSAwOyBpIDwgV0lORUQzRERQX01BWFRFWENPT1JEOyBpKyspIHsKICAgICAgICAgICAgRklYU1JDKHRleENvb3Jkc1tpXSk7CiAgICAgICAgfQogICAgICAgIEZJWFNSQyhwb3NpdGlvbjIpOwogICAgICAgIEZJWFNSQyhub3JtYWwyKTsKICAgICAgICBGSVhTUkModGFuZ2VudCk7CiAgICAgICAgRklYU1JDKGJpbm9ybWFsKTsKICAgICAgICBGSVhTUkModGVzc0ZhY3Rvcik7CiAgICAgICAgRklYU1JDKGZvZyk7CiAgICAgICAgRklYU1JDKGRlcHRoKTsKICAgICAgICBGSVhTUkMoc2FtcGxlKTsKI3VuZGVmIEZJWFNSQwogICAgfQoKICAgIHJldHVybiBwcm9jZXNzX3ZlcnRpY2VzX3N0cmlkZWQoVGhpcywgRGVzdEluZGV4LCBWZXJ0ZXhDb3VudCwgJnN0cmlkZWQsIChJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKikgcERlc3RCdWZmZXIsIEZsYWdzKTsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBUZXh0dXJlIFN0YWdlIFN0YXRlcwogKiBUT0RPOiBWZXJpZnkgYWdhaW5zdCBkeDkgZGVmaW5pdGlvbnMKICoqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFRleHR1cmVTdGFnZVN0YXRlKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgU3RhZ2UsIFdJTkVEM0RURVhUVVJFU1RBR0VTVEFURVRZUEUgVHlwZSwgRFdPUkQgVmFsdWUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIERXT1JEIG9sZFZhbHVlID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlW1N0YWdlXVtUeXBlXTsKCiAgICBUUkFDRSgiKCVwKSA6IFN0YWdlPSVkLCBUeXBlPSVzKCVkKSwgVmFsdWU9JWRcbiIsIFRoaXMsIFN0YWdlLCBkZWJ1Z19kM2R0ZXh0dXJlc3RhdGUoVHlwZSksIFR5cGUsIFZhbHVlKTsKCiAgICBpZiAoU3RhZ2UgPj0gTUFYX1RFWFRVUkVTKSB7CiAgICAgICAgV0FSTigiQXR0ZW1wdGluZyB0byBzZXQgc3RhZ2UgJXUgd2hpY2ggaXMgaGlnaGVyIHRoYW4gdGhlIG1heCBzdGFnZSAldSwgaWdub3JpbmdcbiIsIFN0YWdlLCBNQVhfVEVYVFVSRVMgLSAxKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnRleHR1cmVTdGF0ZVtTdGFnZV1bVHlwZV0gPSBUUlVFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlW1N0YWdlXVtUeXBlXSAgICAgICAgID0gVmFsdWU7CgogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICAvKiBDaGVja2VkIGFmdGVyIHRoZSBhc3NpZ25tZW50cyB0byBhbGxvdyBwcm9wZXIgc3RhdGVibG9jayByZWNvcmRpbmcgKi8KICAgIGlmKG9sZFZhbHVlID09IFZhbHVlKSB7CiAgICAgICAgVFJBQ0UoIkFwcCBpcyBzZXR0aW5nIHRoZSBvbGQgdmFsdWUgb3Zlciwgbm90aGluZyB0byBkb1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgaWYoU3RhZ2UgPiBUaGlzLT5zdGF0ZUJsb2NrLT5sb3dlc3RfZGlzYWJsZWRfc3RhZ2UgJiYKICAgICAgIFN0YXRlVGFibGVbU1RBVEVfVEVYVFVSRVNUQUdFKDAsIFR5cGUpXS5yZXByZXNlbnRhdGl2ZSA9PSBTVEFURV9URVhUVVJFU1RBR0UoMCwgV0lORUQzRFRTU19DT0xPUk9QKSkgewogICAgICAgIC8qIENvbG9yb3AgY2hhbmdlIGFib3ZlIGxvd2VzdCBkaXNhYmxlZCBzdGFnZT8gVGhhdCB3b24ndCBjaGFuZ2UgYW55dGhpbmcgaW4gdGhlIGdsIHNldHVwCiAgICAgICAgICogQ2hhbmdlcyBpbiBvdGhlciBzdGF0ZXMgYXJlIGltcG9ydGFudCBvbiBkaXNhYmxlZCBzdGFnZXMgdG9vCiAgICAgICAgICovCiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgaWYoVHlwZSA9PSBXSU5FRDNEVFNTX0NPTE9ST1ApIHsKICAgICAgICBpbnQgaTsKCiAgICAgICAgaWYoVmFsdWUgPT0gV0lORUQzRFRPUF9ESVNBQkxFICYmIG9sZFZhbHVlICE9IFdJTkVEM0RUT1BfRElTQUJMRSkgewogICAgICAgICAgICAvKiBQcmV2aW91c2x5IGVuYWJsZWQgc3RhZ2UgZGlzYWJsZWQgbm93LiBNYWtlIHN1cmUgdG8gZGlydGlmeSBhbGwgZW5hYmxlZCBzdGFnZXMgYWJvdmUgU3RhZ2UsCiAgICAgICAgICAgICAqIHRoZXkgaGF2ZSB0byBiZSBkaXNhYmxlZAogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBUaGUgY3VycmVudCBzdGFnZSBpcyBkaXJ0aWZpZWQgYmVsb3cuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBmb3IoaSA9IFN0YWdlICsgMTsgaSA8IFRoaXMtPnN0YXRlQmxvY2stPmxvd2VzdF9kaXNhYmxlZF9zdGFnZTsgaSsrKSB7CiAgICAgICAgICAgICAgICBUUkFDRSgiQWRkaXRpb25hbGx5IGRpcnRpZnlpbmcgc3RhZ2UgJWRcbiIsIGkpOwogICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1RFWFRVUkVTVEFHRShpLCBXSU5FRDNEVFNTX0NPTE9ST1ApKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5sb3dlc3RfZGlzYWJsZWRfc3RhZ2UgPSBTdGFnZTsKICAgICAgICAgICAgVFJBQ0UoIk5ldyBsb3dlc3QgZGlzYWJsZWQ6ICVkXG4iLCBTdGFnZSk7CiAgICAgICAgfSBlbHNlIGlmKFZhbHVlICE9IFdJTkVEM0RUT1BfRElTQUJMRSAmJiBvbGRWYWx1ZSA9PSBXSU5FRDNEVE9QX0RJU0FCTEUpIHsKICAgICAgICAgICAgLyogUHJldmlvdXNseSBkaXNhYmxlZCBzdGFnZSBlbmFibGVkLiBTdGFnZXMgYWJvdmUgaXQgbWF5IG5lZWQgZW5hYmxpbmcKICAgICAgICAgICAgICogc3RhZ2UgbXVzdCBiZSBsb3dlc3RfZGlzYWJsZWRfc3RhZ2UgaGVyZSwgaWYgaXQncyBiaWdnZXIgc3VjY2VzcyBpcyByZXR1cm5lZCBhYm92ZSwKICAgICAgICAgICAgICogYW5kIHN0YWdlcyBiZWxvdyB0aGUgbG93ZXN0IGRpc2FibGVkIHN0YWdlIGNhbid0IGJlIGVuYWJsZWQoYmVjYXVzZSB0aGV5IGFyZSBlbmFibGVkIGFscmVhZHkpLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBBZ2FpbiBzdGFnZSBTdGFnZSBkb2Vzbid0IG5lZWQgdG8gYmUgZGlydGlmaWVkIGhlcmUsIGl0IGlzIGhhbmRsZWQgYmVsb3cuCiAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgZm9yKGkgPSBTdGFnZSArIDE7IGkgPCBHTF9MSU1JVFModGV4dHVyZV9zdGFnZXMpOyBpKyspIHsKICAgICAgICAgICAgICAgIGlmKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRleHR1cmVTdGF0ZVtpXVtXSU5FRDNEVFNTX0NPTE9ST1BdID09IFdJTkVEM0RUT1BfRElTQUJMRSkgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgVFJBQ0UoIkFkZGl0aW9uYWxseSBkaXJ0aWZ5aW5nIHN0YWdlICVkIGR1ZSB0byBlbmFibGVcbiIsIGkpOwogICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1RFWFRVUkVTVEFHRShpLCBXSU5FRDNEVFNTX0NPTE9ST1ApKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5sb3dlc3RfZGlzYWJsZWRfc3RhZ2UgPSBpOwogICAgICAgICAgICBUUkFDRSgiTmV3IGxvd2VzdCBkaXNhYmxlZDogJWRcbiIsIGkpOwogICAgICAgIH0KICAgICAgICBpZihHTF9TVVBQT1JUKE5WX1JFR0lTVEVSX0NPTUJJTkVSUykgJiYgIVRoaXMtPnN0YXRlQmxvY2stPnBpeGVsU2hhZGVyKSB7CiAgICAgICAgICAgIC8qIFRPRE86IEJ1aWx0IGEgc3RhZ2UgLT4gdGV4dHVyZSB1bml0IG1hcHBpbmcgZm9yIHJlZ2lzdGVyIGNvbWJpbmVycyAqLwogICAgICAgIH0KICAgIH0KCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVEVYVFVSRVNUQUdFKFN0YWdlLCBUeXBlKSk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0VGV4dHVyZVN0YWdlU3RhdGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBTdGFnZSwgV0lORUQzRFRFWFRVUkVTVEFHRVNUQVRFVFlQRSBUeXBlLCBEV09SRCogcFZhbHVlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IHJlcXVlc3RpbmcgU3RhZ2UgJWQsIFR5cGUgJWQgZ2V0dGluZyAlZFxuIiwgVGhpcywgU3RhZ2UsIFR5cGUsIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRleHR1cmVTdGF0ZVtTdGFnZV1bVHlwZV0pOwogICAgKnBWYWx1ZSA9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRleHR1cmVTdGF0ZVtTdGFnZV1bVHlwZV07CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBUZXh0dXJlCiAqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRUZXh0dXJlKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgU3RhZ2UsIElXaW5lRDNEQmFzZVRleHR1cmUqIHBUZXh0dXJlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzREJhc2VUZXh0dXJlICpvbGRUZXh0dXJlOwoKICAgIFRSQUNFKCIoJXApIDogU3RhZ2UgJSN4LCBUZXh0dXJlICVwXG4iLCBUaGlzLCBTdGFnZSwgcFRleHR1cmUpOwoKICAgIGlmIChTdGFnZSA+PSBXSU5FRDNEVkVSVEVYVEVYVFVSRVNBTVBMRVIwICYmIFN0YWdlIDw9IFdJTkVEM0RWRVJURVhURVhUVVJFU0FNUExFUjMpIHsKICAgICAgICBTdGFnZSAtPSAoV0lORUQzRFZFUlRFWFRFWFRVUkVTQU1QTEVSMCAtIE1BWF9GUkFHTUVOVF9TQU1QTEVSUyk7CiAgICB9CgogICAgb2xkVGV4dHVyZSA9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRleHR1cmVzW1N0YWdlXTsKCiAgICBpZihwVGV4dHVyZSAhPSBOVUxMKSB7CiAgICAgICAgLyogU2V0VGV4dHVyZSBpc24ndCBhbGxvd2VkIG9uIHRleHR1cmVzIGluIFdJTkVEM0RQT09MX1NDUkFUQ0g7IAogICAgICAgICAqLwogICAgICAgIGlmKCgoSVdpbmVEM0RUZXh0dXJlSW1wbCopcFRleHR1cmUpLT5yZXNvdXJjZS5wb29sID09IFdJTkVEM0RQT09MX1NDUkFUQ0gpIHsKICAgICAgICAgICAgV0FSTigiKCVwKSBBdHRlbXB0IHRvIHNldCBzY3JhdGNoIHRleHR1cmUgcmVqZWN0ZWRcbiIsIHBUZXh0dXJlKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfQogICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPnRleHR1cmVEaW1lbnNpb25zW1N0YWdlXSA9IElXaW5lRDNEQmFzZVRleHR1cmVfR2V0VGV4dHVyZURpbWVuc2lvbnMocFRleHR1cmUpOwogICAgfQoKICAgIFRSQUNFKCJHTF9MSU1JVFMgJWRcbiIsR0xfTElNSVRTKHNhbXBsZXJfc3RhZ2VzKSk7CiAgICBUUkFDRSgiKCVwKSA6IG9sZHRleHR1cmUoJXApXG4iLCBUaGlzLG9sZFRleHR1cmUpOwoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQudGV4dHVyZXNbU3RhZ2VdID0gVFJVRTsKICAgIFRSQUNFKCIoJXApIDogc2V0dGluZyBuZXcgdGV4dHVyZSB0byAlcFxuIiwgVGhpcywgcFRleHR1cmUpOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZXNbU3RhZ2VdICAgICAgICAgPSBwVGV4dHVyZTsKCiAgICAvKiBIYW5kbGUgcmVjb3JkaW5nIG9mIHN0YXRlIGJsb2NrcyAqLwogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBpZihvbGRUZXh0dXJlID09IHBUZXh0dXJlKSB7CiAgICAgICAgVFJBQ0UoIkFwcCBpcyBzZXR0aW5nIHRoZSBzYW1lIHRleHR1cmUgYWdhaW4sIG5vdGhpbmcgdG8gZG9cbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIC8qKiBOT1RFOiBNU0ROIHNheXMgdGhhdCBzZXRUZXh0dXJlIGluY3JlYXNlcyB0aGUgcmVmZXJlbmNlIGNvdW50LAogICAgKiBhbmQgdGhhdCB0aGUgYXBwbGljYXRpb24gbXVzdCBzZXQgdGhlIHRleHR1cmUgYmFjayB0byBudWxsIChvciBoYXZlIGEgbGVha3kgYXBwbGljYXRpb24pLAogICAgKiBUaGlzIG1lYW5zIHdlIHNob3VsZCBwYXNzIHRoZSByZWZjb3VudCB1cCB0byB0aGUgcGFyZW50CiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgIGlmIChOVUxMICE9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRleHR1cmVzW1N0YWdlXSkgewogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsICpuZXcgPSAoSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKikgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZXNbU3RhZ2VdOwogICAgICAgIFVMT05HIGJpbmRDb3VudCA9IEludGVybG9ja2VkSW5jcmVtZW50KCZuZXctPmJhc2VUZXh0dXJlLmJpbmRDb3VudCk7CgogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfQWRkUmVmKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRleHR1cmVzW1N0YWdlXSk7CiAgICAgICAgaWYob2xkVGV4dHVyZSA9PSBOVUxMICYmIFN0YWdlIDwgTUFYX1RFWFRVUkVTKSB7CiAgICAgICAgICAgIC8qIFRoZSBzb3VyY2UgYXJndW1lbnRzIGZvciBjb2xvciBhbmQgYWxwaGEgb3BzIGhhdmUgZGlmZmVyZW50IG1lYW5pbmdzIHdoZW4gYSBOVUxMIHRleHR1cmUgaXMgYm91bmQsCiAgICAgICAgICAgICAqIHNvIHRoZSBDT0xPUk9QIGFuZCBBTFBIQU9QIGhhdmUgdG8gYmUgZGlydGlmaWVkLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1RFWFRVUkVTVEFHRShTdGFnZSwgV0lORUQzRFRTU19DT0xPUk9QKSk7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9URVhUVVJFU1RBR0UoU3RhZ2UsIFdJTkVEM0RUU1NfQUxQSEFPUCkpOwogICAgICAgIH0KICAgICAgICBpZihiaW5kQ291bnQgPT0gMSkgewogICAgICAgICAgICBuZXctPmJhc2VUZXh0dXJlLnNhbXBsZXIgPSBTdGFnZTsKICAgICAgICB9CiAgICAgICAgLyogTW9yZSB0aGFuIG9uZSBhc3NpZ25tZW50PyBEb2Vzbid0IG1hdHRlciwgd2Ugb25seSBuZWVkIG9uZSBnbCB0ZXh0dXJlIHVuaXQgdG8gdXNlIGZvciB1cGxvYWRpbmcgKi8KCiAgICB9CgogICAgaWYgKE5VTEwgIT0gb2xkVGV4dHVyZSkgewogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsICpvbGQgPSAoSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKikgb2xkVGV4dHVyZTsKICAgICAgICBMT05HIGJpbmRDb3VudCA9IEludGVybG9ja2VkRGVjcmVtZW50KCZvbGQtPmJhc2VUZXh0dXJlLmJpbmRDb3VudCk7CgogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUmVsZWFzZShvbGRUZXh0dXJlKTsKICAgICAgICBpZihwVGV4dHVyZSA9PSBOVUxMICYmIFN0YWdlIDwgTUFYX1RFWFRVUkVTKSB7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9URVhUVVJFU1RBR0UoU3RhZ2UsIFdJTkVEM0RUU1NfQ09MT1JPUCkpOwogICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVEVYVFVSRVNUQUdFKFN0YWdlLCBXSU5FRDNEVFNTX0FMUEhBT1ApKTsKICAgICAgICB9CgogICAgICAgIGlmKGJpbmRDb3VudCAmJiBvbGQtPmJhc2VUZXh0dXJlLnNhbXBsZXIgPT0gU3RhZ2UpIHsKICAgICAgICAgICAgaW50IGk7CiAgICAgICAgICAgIC8qIEhhdmUgdG8gZG8gYSBzZWFyY2ggZm9yIHRoZSBvdGhlciBzYW1wbGVyKHMpIHdoZXJlIHRoZSB0ZXh0dXJlIGlzIGJvdW5kIHRvCiAgICAgICAgICAgICAqIFNob3VsZG4ndCBoYXBwZW4gYXMgbG9uZyBhcyBhcHBzIGJpbmQgYSB0ZXh0dXJlIG9ubHkgdG8gb25lIHN0YWdlCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBUUkFDRSgiU2VhcmNpbmcgZm9yIG90aGVyIHNhbXBsZXIgLyBzdGFnZSBpZCB3aGVyZSB0aGUgdGV4dHVyZSBpcyBib3VuZCB0b1xuIik7CiAgICAgICAgICAgIGZvcihpID0gMDsgaSA8IE1BWF9DT01CSU5FRF9TQU1QTEVSUzsgaSsrKSB7CiAgICAgICAgICAgICAgICBpZihUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlc1tpXSA9PSBvbGRUZXh0dXJlKSB7CiAgICAgICAgICAgICAgICAgICAgb2xkLT5iYXNlVGV4dHVyZS5zYW1wbGVyID0gaTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfU0FNUExFUihTdGFnZSkpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFRleHR1cmUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBTdGFnZSwgSVdpbmVEM0RCYXNlVGV4dHVyZSoqIHBwVGV4dHVyZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXApIDogU3RhZ2UgJSN4LCBwcFRleHR1cmUgJXBcbiIsIFRoaXMsIFN0YWdlLCBwcFRleHR1cmUpOwoKICAgIGlmIChTdGFnZSA+PSBXSU5FRDNEVkVSVEVYVEVYVFVSRVNBTVBMRVIwICYmIFN0YWdlIDw9IFdJTkVEM0RWRVJURVhURVhUVVJFU0FNUExFUjMpIHsKICAgICAgICBTdGFnZSAtPSAoV0lORUQzRFZFUlRFWFRFWFRVUkVTQU1QTEVSMCAtIE1BWF9GUkFHTUVOVF9TQU1QTEVSUyk7CiAgICB9CgogICAgKnBwVGV4dHVyZT1UaGlzLT5zdGF0ZUJsb2NrLT50ZXh0dXJlc1tTdGFnZV07CiAgICBpZiAoKnBwVGV4dHVyZSkKICAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX0FkZFJlZigqcHBUZXh0dXJlKTsKCiAgICBUUkFDRSgiKCVwKSA6IFJldHVybmluZyAlcFxuIiwgVGhpcywgKnBwVGV4dHVyZSk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBHZXQgQmFjayBCdWZmZXIKICoqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldEJhY2tCdWZmZXIoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIGlTd2FwQ2hhaW4sIFVJTlQgQmFja0J1ZmZlciwgV0lORUQzREJBQ0tCVUZGRVJfVFlQRSBUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2UgKipwcEJhY2tCdWZmZXIpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3dhcENoYWluICpzd2FwQ2hhaW47CiAgICBIUkVTVUxUIGhyOwoKICAgIFRSQUNFKCIoJXApIDogQmFja0J1ZiAlZCBUeXBlICVkIFN3YXBDaGFpbiAlZCByZXR1cm5pbmcgJXBcbiIsIFRoaXMsIEJhY2tCdWZmZXIsIFR5cGUsIGlTd2FwQ2hhaW4sICpwcEJhY2tCdWZmZXIpOwoKICAgIGhyID0gSVdpbmVEM0REZXZpY2VJbXBsX0dldFN3YXBDaGFpbihpZmFjZSwgIGlTd2FwQ2hhaW4sICZzd2FwQ2hhaW4pOwogICAgaWYgKGhyID09IFdJTkVEM0RfT0spIHsKICAgICAgICBociA9IElXaW5lRDNEU3dhcENoYWluX0dldEJhY2tCdWZmZXIoc3dhcENoYWluLCBCYWNrQnVmZmVyLCBUeXBlLCBwcEJhY2tCdWZmZXIpOwogICAgICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKHN3YXBDaGFpbik7CiAgICB9IGVsc2UgewogICAgICAgICpwcEJhY2tCdWZmZXIgPSBOVUxMOwogICAgfQogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldERldmljZUNhcHMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEQ0FQUyogcENhcHMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFdBUk4oIiglcCkgOiBzdHViLCBjYWxsaW5nIGlkaXJlY3QzZCBmb3Igbm93XG4iLCBUaGlzKTsKICAgIHJldHVybiBJV2luZUQzRF9HZXREZXZpY2VDYXBzKFRoaXMtPndpbmVEM0QsIFRoaXMtPmFkYXB0ZXJObywgVGhpcy0+ZGV2VHlwZSwgcENhcHMpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldERpc3BsYXlNb2RlKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBpU3dhcENoYWluLCBXSU5FRDNERElTUExBWU1PREUqIHBNb2RlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcENoYWluOwogICAgSFJFU1VMVCBocjsKCiAgICBpZihpU3dhcENoYWluID4gMCkgewogICAgICAgIGhyID0gSVdpbmVEM0REZXZpY2VJbXBsX0dldFN3YXBDaGFpbihpZmFjZSwgIGlTd2FwQ2hhaW4sIChJV2luZUQzRFN3YXBDaGFpbiAqKikmc3dhcENoYWluKTsKICAgICAgICBpZiAoaHIgPT0gV0lORUQzRF9PSykgewogICAgICAgICAgICBociA9IElXaW5lRDNEU3dhcENoYWluX0dldERpc3BsYXlNb2RlKHN3YXBDaGFpbiwgcE1vZGUpOwogICAgICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKHN3YXBDaGFpbik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgRklYTUUoIiglcCkgRXJyb3IgZ2V0dGluZyBkaXNwbGF5IG1vZGVcbiIsIFRoaXMpOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgLyogRG9uJ3QgcmVhZCB0aGUgcmVhbCBkaXNwbGF5IG1vZGUsCiAgICAgICAgICAgYnV0IHJldHVybiB0aGUgc3RvcmVkIG1vZGUgaW5zdGVhZC4gWDExIGNhbid0IGNoYW5nZSB0aGUgY29sb3IKICAgICAgICAgICBkZXB0aCwgYW5kIHNvbWUgYXBwcyBhcmUgcHJldHR5IGFuZ3J5IGlmIHRoZXkgU2V0RGlzcGxheU1vZGUgZnJvbQogICAgICAgICAgIDI0IHRvIDE2IGJwcCBhbmQgZmluZCBvdXQgdGhhdCBHZXREaXNwbGF5TW9kZSBzdGlsbCByZXR1cm5zIDI0IGJwcAoKICAgICAgICAgICBBbHNvIGRvbid0IHJlbGF5IHRvIHRoZSBzd2FwY2hhaW4gYmVjYXVzZSB3aXRoIGRkcmF3IGl0J3MgcG9zc2libGUKICAgICAgICAgICB0aGF0IHRoZXJlIGlzbid0IGEgc3dhcGNoYWluIGF0IGFsbCAqLwogICAgICAgIHBNb2RlLT5XaWR0aCA9IFRoaXMtPmRkcmF3X3dpZHRoOwogICAgICAgIHBNb2RlLT5IZWlnaHQgPSBUaGlzLT5kZHJhd19oZWlnaHQ7CiAgICAgICAgcE1vZGUtPkZvcm1hdCA9IFRoaXMtPmRkcmF3X2Zvcm1hdDsKICAgICAgICBwTW9kZS0+UmVmcmVzaFJhdGUgPSAwOwogICAgICAgIGhyID0gV0lORUQzRF9PSzsKICAgIH0KCiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0SFdORChJV2luZUQzRERldmljZSAqaWZhY2UsIEhXTkQgaFduZCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIGhXbmQpOwoKICAgIGlmKFRoaXMtPmRkcmF3X2Z1bGxzY3JlZW4pIHsKICAgICAgICBpZihUaGlzLT5kZHJhd193aW5kb3cgJiYgVGhpcy0+ZGRyYXdfd2luZG93ICE9IGhXbmQpIHsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX1Jlc3RvcmVXaW5kb3coaWZhY2UsIFRoaXMtPmRkcmF3X3dpbmRvdyk7CiAgICAgICAgfQogICAgICAgIGlmKGhXbmQgJiYgVGhpcy0+ZGRyYXdfd2luZG93ICE9IGhXbmQpIHsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldHVwRnVsbHNjcmVlbldpbmRvdyhpZmFjZSwgaFduZCk7CiAgICAgICAgfQogICAgfQoKICAgIFRoaXMtPmRkcmF3X3dpbmRvdyA9IGhXbmQ7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRIV05EKElXaW5lRDNERGV2aWNlICppZmFjZSwgSFdORCAqaFduZCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIGhXbmQpOwoKICAgICpoV25kID0gVGhpcy0+ZGRyYXdfd2luZG93OwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBTdGF0ZWJsb2NrIHJlbGF0ZWQgZnVuY3Rpb25zCiAqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQmVnaW5TdGF0ZUJsb2NrKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RTdGF0ZUJsb2NrSW1wbCAqb2JqZWN0OwogICAgSFJFU1VMVCB0ZW1wX3Jlc3VsdDsKICAgIGludCBpOwoKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKICAgIAogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIAogICAgb2JqZWN0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJV2luZUQzRFN0YXRlQmxvY2tJbXBsKSk7CiAgICBpZiAoTlVMTCA9PSBvYmplY3QgKSB7CiAgICAgICAgRklYTUUoIiglcClFcnJvciBhbGxvY2F0aW5nIG1lbW9yeSBmb3Igc3RhdGVibG9ja1xuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICB9CiAgICBUUkFDRSgiKCVwKSBjcmVhdGVkIG9iamVjdCAlcFxuIiwgVGhpcywgb2JqZWN0KTsKICAgIG9iamVjdC0+d2luZUQzRERldmljZT0gVGhpczsKICAgIC8qKiBGSVhNRTogb2JqZWN0LT5wYXJlbnQgICAgICAgPSBwYXJlbnQ7ICoqLwogICAgb2JqZWN0LT5wYXJlbnQgICAgICAgPSBOVUxMOwogICAgb2JqZWN0LT5ibG9ja1R5cGUgICAgPSBXSU5FRDNEU0JUX1JFQ09SREVEOwogICAgb2JqZWN0LT5yZWYgICAgICAgICAgPSAxOwogICAgb2JqZWN0LT5scFZ0YmwgICAgICAgPSAmSVdpbmVEM0RTdGF0ZUJsb2NrX1Z0Ymw7CgogICAgZm9yKGkgPSAwOyBpIDwgTElHSFRNQVBfU0laRTsgaSsrKSB7CiAgICAgICAgbGlzdF9pbml0KCZvYmplY3QtPmxpZ2h0TWFwW2ldKTsKICAgIH0KCiAgICB0ZW1wX3Jlc3VsdCA9IGFsbG9jYXRlX3NoYWRlcl9jb25zdGFudHMob2JqZWN0KTsKICAgIGlmIChXSU5FRDNEX09LICE9IHRlbXBfcmVzdWx0KQogICAgICAgIHJldHVybiB0ZW1wX3Jlc3VsdDsKCiAgICBJV2luZUQzRFN0YXRlQmxvY2tfUmVsZWFzZSgoSVdpbmVEM0RTdGF0ZUJsb2NrKilUaGlzLT51cGRhdGVTdGF0ZUJsb2NrKTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2sgPSBvYmplY3Q7CiAgICBUaGlzLT5pc1JlY29yZGluZ1N0YXRlID0gVFJVRTsKCiAgICBUUkFDRSgiKCVwKSByZWNvcmRpbmcgc3RhdGVibG9jayAlcFxuIixUaGlzICwgb2JqZWN0KTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0VuZFN0YXRlQmxvY2soSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFN0YXRlQmxvY2sqKiBwcFN0YXRlQmxvY2spIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIHVuc2lnbmVkIGludCBpLCBqOwogICAgSVdpbmVEM0RTdGF0ZUJsb2NrSW1wbCAqb2JqZWN0ID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jazsKCiAgICBpZiAoIVRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBGSVhNRSgiKCVwKSBub3QgcmVjb3JkaW5nISByZXR1cm5pbmcgZXJyb3JcbiIsIFRoaXMpOwogICAgICAgICpwcFN0YXRlQmxvY2sgPSBOVUxMOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGZvcihpID0gMTsgaSA8PSBXSU5FSElHSEVTVF9SRU5ERVJfU1RBVEU7IGkrKykgewogICAgICAgIGlmKG9iamVjdC0+Y2hhbmdlZC5yZW5kZXJTdGF0ZVtpXSkgewogICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF9yZW5kZXJfc3RhdGVzW29iamVjdC0+bnVtX2NvbnRhaW5lZF9yZW5kZXJfc3RhdGVzXSA9IGk7CiAgICAgICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF9yZW5kZXJfc3RhdGVzKys7CiAgICAgICAgfQogICAgfQogICAgZm9yKGkgPSAxOyBpIDw9IEhJR0hFU1RfVFJBTlNGT1JNU1RBVEU7IGkrKykgewogICAgICAgIGlmKG9iamVjdC0+Y2hhbmdlZC50cmFuc2Zvcm1baV0pIHsKICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfdHJhbnNmb3JtX3N0YXRlc1tvYmplY3QtPm51bV9jb250YWluZWRfdHJhbnNmb3JtX3N0YXRlc10gPSBpOwogICAgICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfdHJhbnNmb3JtX3N0YXRlcysrOwogICAgICAgIH0KICAgIH0KICAgIGZvcihpID0gMDsgaSA8IEdMX0xJTUlUUyh2c2hhZGVyX2NvbnN0YW50c0YpOyBpKyspIHsKICAgICAgICBpZihvYmplY3QtPmNoYW5nZWQudmVydGV4U2hhZGVyQ29uc3RhbnRzRltpXSkgewogICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF92c19jb25zdHNfZltvYmplY3QtPm51bV9jb250YWluZWRfdnNfY29uc3RzX2ZdID0gaTsKICAgICAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3ZzX2NvbnN0c19mKys7CiAgICAgICAgfQogICAgfQogICAgZm9yKGkgPSAwOyBpIDwgTUFYX0NPTlNUX0k7IGkrKykgewogICAgICAgIGlmKG9iamVjdC0+Y2hhbmdlZC52ZXJ0ZXhTaGFkZXJDb25zdGFudHNJW2ldKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3ZzX2NvbnN0c19pW29iamVjdC0+bnVtX2NvbnRhaW5lZF92c19jb25zdHNfaV0gPSBpOwogICAgICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfdnNfY29uc3RzX2krKzsKICAgICAgICB9CiAgICB9CiAgICBmb3IoaSA9IDA7IGkgPCBNQVhfQ09OU1RfQjsgaSsrKSB7CiAgICAgICAgaWYob2JqZWN0LT5jaGFuZ2VkLnZlcnRleFNoYWRlckNvbnN0YW50c0JbaV0pIHsKICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfdnNfY29uc3RzX2Jbb2JqZWN0LT5udW1fY29udGFpbmVkX3ZzX2NvbnN0c19iXSA9IGk7CiAgICAgICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF92c19jb25zdHNfYisrOwogICAgICAgIH0KICAgIH0KICAgIGZvcihpID0gMDsgaSA8IE1BWF9DT05TVF9JOyBpKyspIHsKICAgICAgICBpZihvYmplY3QtPmNoYW5nZWQucGl4ZWxTaGFkZXJDb25zdGFudHNJW2ldKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3BzX2NvbnN0c19pW29iamVjdC0+bnVtX2NvbnRhaW5lZF9wc19jb25zdHNfaV0gPSBpOwogICAgICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfcHNfY29uc3RzX2krKzsKICAgICAgICB9CiAgICB9CiAgICBmb3IoaSA9IDA7IGkgPCBNQVhfQ09OU1RfQjsgaSsrKSB7CiAgICAgICAgaWYob2JqZWN0LT5jaGFuZ2VkLnBpeGVsU2hhZGVyQ29uc3RhbnRzQltpXSkgewogICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF9wc19jb25zdHNfYltvYmplY3QtPm51bV9jb250YWluZWRfcHNfY29uc3RzX2JdID0gaTsKICAgICAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3BzX2NvbnN0c19iKys7CiAgICAgICAgfQogICAgfQogICAgZm9yKGkgPSAwOyBpIDwgTUFYX1RFWFRVUkVTOyBpKyspIHsKICAgICAgICBmb3IoaiA9IDE7IGogPD0gV0lORUQzRF9ISUdIRVNUX1RFWFRVUkVfU1RBVEU7IGorKykgewogICAgICAgICAgICBpZihvYmplY3QtPmNoYW5nZWQudGV4dHVyZVN0YXRlW2ldW2pdKSB7CiAgICAgICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF90c3Nfc3RhdGVzW29iamVjdC0+bnVtX2NvbnRhaW5lZF90c3Nfc3RhdGVzXS5zdGFnZSA9IGk7CiAgICAgICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF90c3Nfc3RhdGVzW29iamVjdC0+bnVtX2NvbnRhaW5lZF90c3Nfc3RhdGVzXS5zdGF0ZSA9IGo7CiAgICAgICAgICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfdHNzX3N0YXRlcysrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgZm9yKGkgPSAwOyBpIDwgTUFYX0NPTUJJTkVEX1NBTVBMRVJTOyBpKyspewogICAgICAgIGZvciAoaiA9IDE7IGogPCBXSU5FRDNEX0hJR0hFU1RfU0FNUExFUl9TVEFURTsgaisrKSB7CiAgICAgICAgICAgIGlmKG9iamVjdC0+Y2hhbmdlZC5zYW1wbGVyU3RhdGVbaV1bal0pIHsKICAgICAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3NhbXBsZXJfc3RhdGVzW29iamVjdC0+bnVtX2NvbnRhaW5lZF9zYW1wbGVyX3N0YXRlc10uc3RhZ2UgPSBpOwogICAgICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfc2FtcGxlcl9zdGF0ZXNbb2JqZWN0LT5udW1fY29udGFpbmVkX3NhbXBsZXJfc3RhdGVzXS5zdGF0ZSA9IGo7CiAgICAgICAgICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfc2FtcGxlcl9zdGF0ZXMrKzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAqcHBTdGF0ZUJsb2NrID0gKElXaW5lRDNEU3RhdGVCbG9jayopIG9iamVjdDsKICAgIFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUgPSBGQUxTRTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2sgPSBUaGlzLT5zdGF0ZUJsb2NrOwogICAgSVdpbmVEM0RTdGF0ZUJsb2NrX0FkZFJlZigoSVdpbmVEM0RTdGF0ZUJsb2NrKilUaGlzLT51cGRhdGVTdGF0ZUJsb2NrKTsKICAgIC8qIElXaW5lRDNEU3RhdGVCbG9ja19BZGRSZWYoKnBwU3RhdGVCbG9jayk7IGRvbid0IG5lZWQgdG8gZG8gdGhpcywgc2luY2Ugd2Ugc2hvdWxkIHJlYWxseSBqdXN0IHJlbGVhc2UgVXBkYXRlU3RhdGVCbG9jayBmaXJzdCAqLwogICAgVFJBQ0UoIiglcCkgcmV0dXJuaW5nIHRva2VuIChwdHIgdG8gc3RhdGVibG9jaykgb2YgJXBcbiIsIFRoaXMsICpwcFN0YXRlQmxvY2spOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBTY2VuZSByZWxhdGVkIGZ1bmN0aW9ucwogKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQmVnaW5TY2VuZShJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIC8qIEF0IHRoZSBtb21lbnQgd2UgaGF2ZSBubyBuZWVkIGZvciBhbnkgZnVuY3Rpb25hbGl0eSBhdCB0aGUgYmVnaW5uaW5nCiAgICAgICBvZiBhIHNjZW5lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgaWYoVGhpcy0+aW5TY2VuZSkgewogICAgICAgIFRSQUNFKCJBbHJlYWR5IGluIFNjZW5lLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICBUaGlzLT5pblNjZW5lID0gVFJVRTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0VuZFNjZW5lKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIGlmKCFUaGlzLT5pblNjZW5lKSB7CiAgICAgICAgVFJBQ0UoIk5vdCBpbiBzY2VuZSwgcmV0dXJuaW5nIFdJTkVEM0RFUlJfSU5WQUxJRENBTExcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmKFRoaXMtPmNyZWF0ZVBhcm1zLkJlaGF2aW9yRmxhZ3MgJiBXSU5FRDNEQ1JFQVRFX01VTFRJVEhSRUFERUQpIHsKICAgICAgICBBY3RpdmF0ZUNvbnRleHQoVGhpcywgVGhpcy0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKICAgIH0KICAgIC8qIFdlIG9ubHkgaGF2ZSB0byBkbyB0aGlzIGlmIHdlIG5lZWQgdG8gcmVhZCB0aGUsIHN3YXBidWZmZXJzIHBlcmZvcm1zIGEgZmx1c2ggZm9yIHVzICovCiAgICBFTlRFUl9HTCgpOwogICAgZ2xGbHVzaCgpOwogICAgY2hlY2tHTGNhbGwoImdsRmx1c2giKTsKICAgIExFQVZFX0dMKCk7CgogICAgVGhpcy0+aW5TY2VuZSA9IEZBTFNFOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfUHJlc2VudChJV2luZUQzRERldmljZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTlNUIFJFQ1QqIHBTb3VyY2VSZWN0LCBDT05TVCBSRUNUKiBwRGVzdFJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhXTkQgaERlc3RXaW5kb3dPdmVycmlkZSwgQ09OU1QgUkdOREFUQSogcERpcnR5UmVnaW9uKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcENoYWluID0gTlVMTDsKICAgIGludCBpOwogICAgaW50IHN3YXBjaGFpbnMgPSBJV2luZUQzRERldmljZUltcGxfR2V0TnVtYmVyT2ZTd2FwQ2hhaW5zKGlmYWNlKTsKCiAgICBUUkFDRSgiKCVwKSBQcmVzZW50aW5nIHRoZSBmcmFtZVxuIiwgVGhpcyk7CgogICAgZm9yKGkgPSAwIDsgaSA8IHN3YXBjaGFpbnMgOyBpICsrKSB7CgogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTd2FwQ2hhaW4oaWZhY2UsIGkgLCAoSVdpbmVEM0RTd2FwQ2hhaW4gKiopJnN3YXBDaGFpbik7CiAgICAgICAgVFJBQ0UoInByZXNlbnRpbm5nIGNoYWluICVkLCAlcFxuIiwgaSwgc3dhcENoYWluKTsKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9QcmVzZW50KHN3YXBDaGFpbiwgcFNvdXJjZVJlY3QsIHBEZXN0UmVjdCwgaERlc3RXaW5kb3dPdmVycmlkZSwgcERpcnR5UmVnaW9uLCAwKTsKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKHN3YXBDaGFpbik7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ2xlYXIoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBDb3VudCwgQ09OU1QgV0lORUQzRFJFQ1QqIHBSZWN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzLCBXSU5FRDNEQ09MT1IgQ29sb3IsIGZsb2F0IFosIERXT1JEIFN0ZW5jaWwpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKnRhcmdldCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopVGhpcy0+cmVuZGVyX3RhcmdldHNbMF07CgogICAgR0xiaXRmaWVsZCAgICAgZ2xNYXNrID0gMDsKICAgIHVuc2lnbmVkIGludCAgIGk7CiAgICBXSU5FRDNEUkVDVCBjdXJSZWN0OwogICAgUkVDVCB2cF9yZWN0OwogICAgV0lORUQzRFZJRVdQT1JUICp2cCA9ICZUaGlzLT5zdGF0ZUJsb2NrLT52aWV3cG9ydDsKICAgIFVJTlQgZHJhd2FibGVfd2lkdGgsIGRyYXdhYmxlX2hlaWdodDsKCiAgICBUUkFDRSgiKCVwKSBDb3VudCAoJWQpLCBwUmVjdHMgKCVwKSwgRmxhZ3MgKCV4KSwgQ29sb3IgKDB4JTA4eCksIFogKCVmKSwgU3RlbmNpbCAoJWQpXG4iLCBUaGlzLAogICAgICAgICAgQ291bnQsIHBSZWN0cywgRmxhZ3MsIENvbG9yLCBaLCBTdGVuY2lsKTsKCiAgICBpZihGbGFncyAmIChXSU5FRDNEQ0xFQVJfWkJVRkZFUiB8IFdJTkVEM0RDTEVBUl9TVEVOQ0lMKSAmJiBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0ID09IE5VTEwpIHsKICAgICAgICBXQVJOKCJDbGVhcmluZyBkZXB0aCBhbmQvb3Igc3RlbmNpbCB3aXRob3V0IGEgZGVwdGggc3RlbmNpbCBidWZmZXIgYXR0YWNoZWQsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICAvKiBUT0RPOiBXaGF0IGFib3V0IGRlcHRoIHN0ZW5jaWwgYnVmZmVycyB3aXRob3V0IHN0ZW5jaWwgYml0cz8gKi8KICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICAvKiBXaGVuIHdlJ3JlIGNsZWFyaW5nIHBhcnRzIG9mIHRoZSBkcmF3YWJsZSwgbWFrZSBzdXJlIHRoYXQgdGhlIHRhcmdldCBzdXJmYWNlIGlzIHdlbGwgdXAgdG8gZGF0ZSBpbiB0aGUKICAgICAqIGRyYXdhYmxlLiBBZnRlciB0aGUgY2xlYXIgd2UnbGwgbWFyayB0aGUgZHJhd2FibGUgdXAgdG8gZGF0ZSwgc28gd2UgaGF2ZSB0byBtYWtlIHN1cmUgdGhhdCB0aGlzIGlzIHRydWUKICAgICAqIGZvciB0aGUgY2xlYXJlZCBwYXJ0cywgYW5kIHRoZSB1bnRvdWNoZWQgcGFydHMuCiAgICAgKgogICAgICogSWYgd2UncmUgY2xlYXJpbmcgdGhlIHdob2xlIHRhcmdldCB0aGVyZSBpcyBubyBuZWVkIHRvIGNvcHkgaXQgaW50byB0aGUgZHJhd2FibGUsIGl0IHdpbGwgYmUgb3ZlcndyaXR0ZW4KICAgICAqIGFueXdheS4gSWYgd2UncmUgbm90IGNsZWFyaW5nIHRoZSBjb2xvciBidWZmZXIgd2UgZG9uJ3QgaGF2ZSB0byBjb3B5IGVpdGhlciBzaW5jZSB3ZSdyZSBub3QgZ29pbmcgdG8gc2V0CiAgICAgKiB0aGUgZHJhd2FibGUgdXAgdG8gZGF0ZS4gV2UgaGF2ZSB0byBjaGVjayBhbGwgc2V0dGluZ3MgdGhhdCBsaW1pdCB0aGUgY2xlYXIgYXJlYSB0aG91Z2guIERvIG5vdCBib3RoZXIKICAgICAqIGNoZWNraW5nIGFsbCB0aGlzIGlmIHRoZSBkZXN0IHN1cmZhY2UgaXMgaW4gdGhlIGRyYXdhYmxlIGFueXdheS4KICAgICAqLwogICAgaWYoKEZsYWdzICYgV0lORUQzRENMRUFSX1RBUkdFVCkgJiYgISh0YXJnZXQtPkZsYWdzICYgU0ZMQUdfSU5EUkFXQUJMRSkpIHsKICAgICAgICB3aGlsZSgxKSB7CiAgICAgICAgICAgIGlmKHZwLT5YICE9IDAgfHwgdnAtPlkgIT0gMCB8fAogICAgICAgICAgICAgICB2cC0+V2lkdGggPCB0YXJnZXQtPmN1cnJlbnREZXNjLldpZHRoIHx8IHZwLT5IZWlnaHQgPCB0YXJnZXQtPmN1cnJlbnREZXNjLkhlaWdodCkgewogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvYWRMb2NhdGlvbigoSVdpbmVEM0RTdXJmYWNlICopIHRhcmdldCwgU0ZMQUdfSU5EUkFXQUJMRSwgTlVMTCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZihUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfU0NJU1NPUlRFU1RFTkFCTEVdICYmICgKICAgICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+c2Npc3NvclJlY3QubGVmdCA+IDAgfHwgVGhpcy0+c3RhdGVCbG9jay0+c2Npc3NvclJlY3QudG9wID4gMCB8fAogICAgICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zY2lzc29yUmVjdC5yaWdodCA8IHRhcmdldC0+Y3VycmVudERlc2MuV2lkdGggfHwKICAgICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+c2Npc3NvclJlY3QuYm90dG9tIDwgdGFyZ2V0LT5jdXJyZW50RGVzYy5IZWlnaHQpKSB7CiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfTG9hZExvY2F0aW9uKChJV2luZUQzRFN1cmZhY2UgKikgdGFyZ2V0LCBTRkxBR19JTkRSQVdBQkxFLCBOVUxMKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKENvdW50ID4gMCAmJiBwUmVjdHMgJiYgKAogICAgICAgICAgICAgICBwUmVjdHNbMF0ueDEgPiAwIHx8IHBSZWN0c1swXS55MSA+IDAgfHwKICAgICAgICAgICAgICAgcFJlY3RzWzBdLngyIDwgdGFyZ2V0LT5jdXJyZW50RGVzYy5XaWR0aCB8fAogICAgICAgICAgICAgICBwUmVjdHNbMF0ueTIgPCB0YXJnZXQtPmN1cnJlbnREZXNjLkhlaWdodCkpIHsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9Mb2FkTG9jYXRpb24oKElXaW5lRDNEU3VyZmFjZSAqKSB0YXJnZXQsIFNGTEFHX0lORFJBV0FCTEUsIE5VTEwpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIHRhcmdldC0+Z2V0X2RyYXdhYmxlX3NpemUodGFyZ2V0LCAmZHJhd2FibGVfd2lkdGgsICZkcmF3YWJsZV9oZWlnaHQpOwoKICAgIC8qIFRoaXMgaXMgZm9yIG9mZnNjcmVlbiByZW5kZXJpbmcgYXMgd2VsbCBhcyBmb3IgbXVsdGl0aHJlYWRpbmcsIHRodXMgYWN0aXZhdGUgdGhlIHNldCByZW5kZXIgdGFyZ2V0CiAgICAgKiBhbmQgbm90IHRoZSBsYXN0IGFjdGl2ZSBvbmUuCiAgICAgKi8KICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXSwgQ1RYVVNBR0VfQ0xFQVIpOwogICAgRU5URVJfR0woKTsKCiAgICBpZiAod2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUgPT0gT1JNX0ZCTykgewogICAgICAgIGFwcGx5X2Zib19zdGF0ZShpZmFjZSk7CiAgICB9CgogICAgLyogT25seSBzZXQgdGhlIHZhbHVlcyB1cCBvbmNlLCBhcyB0aGV5IGFyZSBub3QgY2hhbmdpbmcgKi8KICAgIGlmIChGbGFncyAmIFdJTkVEM0RDTEVBUl9TVEVOQ0lMKSB7CiAgICAgICAgZ2xDbGVhclN0ZW5jaWwoU3RlbmNpbCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQ2xlYXJTdGVuY2lsIik7CiAgICAgICAgZ2xNYXNrID0gZ2xNYXNrIHwgR0xfU1RFTkNJTF9CVUZGRVJfQklUOwogICAgICAgIGdsU3RlbmNpbE1hc2soMHhGRkZGRkZGRik7CiAgICB9CgogICAgaWYgKEZsYWdzICYgV0lORUQzRENMRUFSX1pCVUZGRVIpIHsKICAgICAgICBnbERlcHRoTWFzayhHTF9UUlVFKTsKICAgICAgICBnbENsZWFyRGVwdGgoWik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQ2xlYXJEZXB0aCIpOwogICAgICAgIGdsTWFzayA9IGdsTWFzayB8IEdMX0RFUFRIX0JVRkZFUl9CSVQ7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1JFTkRFUihXSU5FRDNEUlNfWldSSVRFRU5BQkxFKSk7CiAgICB9CgogICAgaWYgKEZsYWdzICYgV0lORUQzRENMRUFSX1RBUkdFVCkgewogICAgICAgIFRSQUNFKCJDbGVhcmluZyBzY3JlZW4gd2l0aCBnbENsZWFyIHRvIGNvbG9yICV4XG4iLCBDb2xvcik7CiAgICAgICAgZ2xDbGVhckNvbG9yKEQzRENPTE9SX1IoQ29sb3IpLAogICAgICAgICAgICAgICAgICAgICBEM0RDT0xPUl9HKENvbG9yKSwKICAgICAgICAgICAgICAgICAgICAgRDNEQ09MT1JfQihDb2xvciksCiAgICAgICAgICAgICAgICAgICAgIEQzRENPTE9SX0EoQ29sb3IpKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xDbGVhckNvbG9yIik7CgogICAgICAgIC8qIENsZWFyIEFMTCBjb2xvcnMhICovCiAgICAgICAgZ2xDb2xvck1hc2soR0xfVFJVRSwgR0xfVFJVRSwgR0xfVFJVRSwgR0xfVFJVRSk7CiAgICAgICAgZ2xNYXNrID0gZ2xNYXNrIHwgR0xfQ09MT1JfQlVGRkVSX0JJVDsKICAgIH0KCiAgICB2cF9yZWN0LmxlZnQgPSB2cC0+WDsKICAgIHZwX3JlY3QudG9wID0gdnAtPlk7CiAgICB2cF9yZWN0LnJpZ2h0ID0gdnAtPlggKyB2cC0+V2lkdGg7CiAgICB2cF9yZWN0LmJvdHRvbSA9IHZwLT5ZICsgdnAtPkhlaWdodDsKICAgIGlmICghKENvdW50ID4gMCAmJiBwUmVjdHMpKSB7CiAgICAgICAgaWYoVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbV0lORUQzRFJTX1NDSVNTT1JURVNURU5BQkxFXSkgewogICAgICAgICAgICBJbnRlcnNlY3RSZWN0KCZ2cF9yZWN0LCAmdnBfcmVjdCwgJlRoaXMtPnN0YXRlQmxvY2stPnNjaXNzb3JSZWN0KTsKICAgICAgICB9CiAgICAgICAgaWYoVGhpcy0+cmVuZGVyX29mZnNjcmVlbikgewogICAgICAgICAgICBnbFNjaXNzb3IodnBfcmVjdC5sZWZ0LCB2cF9yZWN0LnRvcCwKICAgICAgICAgICAgICAgICAgICAgICAgdnBfcmVjdC5yaWdodCAtIHZwX3JlY3QubGVmdCwgdnBfcmVjdC5ib3R0b20gLSB2cF9yZWN0LnRvcCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZ2xTY2lzc29yKHZwX3JlY3QubGVmdCwgZHJhd2FibGVfaGVpZ2h0IC0gdnBfcmVjdC5ib3R0b20sCiAgICAgICAgICAgICAgICAgICAgICAgIHZwX3JlY3QucmlnaHQgLSB2cF9yZWN0LmxlZnQsIHZwX3JlY3QuYm90dG9tIC0gdnBfcmVjdC50b3ApOwogICAgICAgIH0KICAgICAgICBjaGVja0dMY2FsbCgiZ2xTY2lzc29yIik7CiAgICAgICAgZ2xDbGVhcihnbE1hc2spOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbENsZWFyIik7CiAgICB9IGVsc2UgewogICAgICAgIC8qIE5vdyBwcm9jZXNzIGVhY2ggcmVjdCBpbiB0dXJuICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IENvdW50OyBpKyspIHsKICAgICAgICAgICAgLyogTm90ZSBnbCB1c2VzIGxvd2VyIGxlZnQsIHdpZHRoL2hlaWdodCAqLwogICAgICAgICAgICBJbnRlcnNlY3RSZWN0KChSRUNUICopICZjdXJSZWN0LCAmdnBfcmVjdCwgKFJFQ1QgKikgJnBSZWN0c1tpXSk7CiAgICAgICAgICAgIGlmKFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19TQ0lTU09SVEVTVEVOQUJMRV0pIHsKICAgICAgICAgICAgICAgIEludGVyc2VjdFJlY3QoKFJFQ1QgKikgJmN1clJlY3QsIChSRUNUICopICZjdXJSZWN0LCAmVGhpcy0+c3RhdGVCbG9jay0+c2Npc3NvclJlY3QpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFRSQUNFKCIoJXApIFJlY3Q9KCVkLCVkKS0+KCVkLCVkKSBnbFJlY3Q9KCVkLCVkKSwgbGVuPSVkLCBoZWk9JWRcbiIsIFRoaXMsCiAgICAgICAgICAgICAgICAgIHBSZWN0c1tpXS54MSwgcFJlY3RzW2ldLnkxLCBwUmVjdHNbaV0ueDIsIHBSZWN0c1tpXS55MiwKICAgICAgICAgICAgICAgICAgY3VyUmVjdC54MSwgKHRhcmdldC0+Y3VycmVudERlc2MuSGVpZ2h0IC0gY3VyUmVjdC55MiksCiAgICAgICAgICAgICAgICAgIGN1clJlY3QueDIgLSBjdXJSZWN0LngxLCBjdXJSZWN0LnkyIC0gY3VyUmVjdC55MSk7CgogICAgICAgICAgICAvKiBUZXN0cyBzaG93IHRoYXQgcmVjdGFuZ2xlcyB3aGVyZSB4MSA+IHgyIG9yIHkxID4geTIgYXJlIGlnbm9yZWQgc2lsZW50bHkuCiAgICAgICAgICAgICAqIFRoZSByZWN0YW5nbGUgaXMgbm90IGNsZWFyZWQsIG5vIGVycm9yIGlzIHJldHVybmVkLCBidXQgZnVydGhlciByZWN0YW5sZ2VzIGFyZQogICAgICAgICAgICAgKiBzdGlsbCBjbGVhcmVkIGlmIHRoZXkgYXJlIHZhbGlkCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZihjdXJSZWN0LngxID4gY3VyUmVjdC54MiB8fCBjdXJSZWN0LnkxID4gY3VyUmVjdC55MikgewogICAgICAgICAgICAgICAgVFJBQ0UoIlJlY3RhbmdsZSB3aXRoIG5lZ2F0aXZlIGRpbWVuc2lvbnMsIGlnbm9yaW5nXG4iKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZihUaGlzLT5yZW5kZXJfb2Zmc2NyZWVuKSB7CiAgICAgICAgICAgICAgICBnbFNjaXNzb3IoY3VyUmVjdC54MSwgY3VyUmVjdC55MSwKICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJSZWN0LngyIC0gY3VyUmVjdC54MSwgY3VyUmVjdC55MiAtIGN1clJlY3QueTEpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZ2xTY2lzc29yKGN1clJlY3QueDEsIGRyYXdhYmxlX2hlaWdodCAtIGN1clJlY3QueTIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyUmVjdC54MiAtIGN1clJlY3QueDEsIGN1clJlY3QueTIgLSBjdXJSZWN0LnkxKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xTY2lzc29yIik7CgogICAgICAgICAgICBnbENsZWFyKGdsTWFzayk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbENsZWFyIik7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFJlc3RvcmUgdGhlIG9sZCB2YWx1ZXMgKHdoeS4uPykgKi8KICAgIGlmIChGbGFncyAmIFdJTkVEM0RDTEVBUl9TVEVOQ0lMKSB7CiAgICAgICAgZ2xTdGVuY2lsTWFzayhUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfU1RFTkNJTFdSSVRFTUFTS10pOwogICAgfQogICAgaWYgKEZsYWdzICYgV0lORUQzRENMRUFSX1RBUkdFVCkgewogICAgICAgIERXT1JEIG1hc2sgPSBUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfQ09MT1JXUklURUVOQUJMRV07CiAgICAgICAgZ2xDb2xvck1hc2sobWFzayAmIFdJTkVEM0RDT0xPUldSSVRFRU5BQkxFX1JFRCA/IEdMX1RSVUUgOiBHTF9GQUxTRSwKICAgICAgICAgICAgICAgICAgICBtYXNrICYgV0lORUQzRENPTE9SV1JJVEVFTkFCTEVfR1JFRU4gPyBHTF9UUlVFIDogR0xfRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgbWFzayAmIFdJTkVEM0RDT0xPUldSSVRFRU5BQkxFX0JMVUUgID8gR0xfVFJVRSA6IEdMX0ZBTFNFLAogICAgICAgICAgICAgICAgICAgIG1hc2sgJiBXSU5FRDNEQ09MT1JXUklURUVOQUJMRV9BTFBIQSA/IEdMX1RSVUUgOiBHTF9GQUxTRSk7CgogICAgICAgIC8qIERpcnRpZnkgdGhlIHRhcmdldCBzdXJmYWNlIGZvciBub3cuIElmIHRoZSBzdXJmYWNlIGlzIGxvY2tlZCByZWd1bGFybHksIGFuZCBhbiB1cCB0byBkYXRlIHN5c21lbSBjb3B5IGV4aXN0cywKICAgICAgICAgKiBpdCBpcyBtb3N0IGxpa2VseSBtb3JlIGVmZmljaWVudCB0byBwZXJmb3JtIGEgY2xlYXIgb24gdGhlIHN5c21lbSBjb3B5IHRvbyBpbnN0ZWFkIG9mIGRvd25sb2FkaW5nIGl0CiAgICAgICAgICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX01vZGlmeUxvY2F0aW9uKFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQsIFNGTEFHX0lORFJBV0FCTEUsIFRSVUUpOwogICAgICAgIC8qIFRPRE86IE1vdmUgdGhlIGZibyBsb2dpYyBpbnRvIE1vZGlmeUxvY2F0aW9uKCkgKi8KICAgICAgICBpZihUaGlzLT5yZW5kZXJfb2Zmc2NyZWVuICYmIHdpbmVkM2Rfc2V0dGluZ3Mub2Zmc2NyZWVuX3JlbmRlcmluZ19tb2RlID09IE9STV9GQk8pIHsKICAgICAgICAgICAgdGFyZ2V0LT5GbGFncyB8PSBTRkxBR19JTlRFWFRVUkU7CiAgICAgICAgfQogICAgfQogICAgTEVBVkVfR0woKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIERyYXdpbmcgZnVuY3Rpb25zCiAqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3UHJpbWl0aXZlKElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRFBSSU1JVElWRVRZUEUgUHJpbWl0aXZlVHlwZSwgVUlOVCBTdGFydFZlcnRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBQcmltaXRpdmVDb3VudCkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKSA6IFR5cGU9KCVkLCVzKSwgU3RhcnQ9JWQsIENvdW50PSVkXG4iLCBUaGlzLCBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWdfZDNkcHJpbWl0aXZldHlwZShQcmltaXRpdmVUeXBlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YXJ0VmVydGV4LCBQcmltaXRpdmVDb3VudCk7CgogICAgLyogVGhlIGluZGV4IGJ1ZmZlciBpcyBub3QgbmVlZGVkIGhlcmUsIGJ1dCByZXN0b3JlIGl0LCBvdGhlcndpc2UgaXQgaXMgaGVsbCB0byBrZWVwIHRyYWNrIG9mICovCiAgICBpZihUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Jc1VQKSB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX0lOREVYQlVGRkVSKTsKICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Jc1VQID0gRkFMU0U7CiAgICB9CgogICAgaWYoVGhpcy0+c3RhdGVCbG9jay0+bG9hZEJhc2VWZXJ0ZXhJbmRleCAhPSAwKSB7CiAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+bG9hZEJhc2VWZXJ0ZXhJbmRleCA9IDA7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1NUUkVBTVNSQyk7CiAgICB9CiAgICAvKiBBY2NvdW50IGZvciB0aGUgbG9hZGluZyBvZmZzZXQgZHVlIHRvIGluZGV4IGJ1ZmZlcnMuIEluc3RlYWQgb2YgcmVsb2FkaW5nIGFsbCBzb3VyY2VzIGNvcnJlY3QgaXQgd2l0aCB0aGUgc3RhcnR2ZXJ0ZXggcGFyYW1ldGVyICovCiAgICBkcmF3UHJpbWl0aXZlKGlmYWNlLCBQcmltaXRpdmVUeXBlLCBQcmltaXRpdmVDb3VudCwgU3RhcnRWZXJ0ZXgsIDAvKiBOdW1WZXJ0aWNlcyAqLywgLTEgLyogaW5keFN0YXJ0ICovLAogICAgICAgICAgICAgICAgICAwIC8qIGluZHhTaXplICovLCBOVUxMIC8qIGluZHhEYXRhICovLCAwIC8qIG1pbkluZGV4ICovKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKiBUT0RPOiBiYXNlVkluZGV4IG5lZWRzIHRvIGJlIHByb3ZpZGVkIGZyb20gVGhpcy0+c3RhdGVCbG9jay0+YmFzZVZlcnRleEluZGV4IHdoZW4gY2FsbGVkIGZyb20gZDNkOCAqLwpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfRHJhd0luZGV4ZWRQcmltaXRpdmUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBtaW5JbmRleCwgVUlOVCBOdW1WZXJ0aWNlcywgVUlOVCBzdGFydEluZGV4LCBVSU5UIHByaW1Db3VudCkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBVSU5UICAgICAgICAgICAgICAgICBpZHhTdHJpZGUgPSAyOwogICAgSVdpbmVEM0RJbmRleEJ1ZmZlciAqcElCOwogICAgV0lORUQzRElOREVYQlVGRkVSX0RFU0MgIElkeEJ1ZkRzYzsKICAgIEdMdWludCB2Ym87CgogICAgcElCID0gVGhpcy0+c3RhdGVCbG9jay0+cEluZGV4RGF0YTsKICAgIGlmICghcElCKSB7CiAgICAgICAgLyogRDNEOSByZXR1cm5zIEQzREVSUl9JTlZBTElEQ0FMTCB3aGVuIERyYXdJbmRleGVkUHJpbWl0aXZlIGlzIGNhbGxlZAogICAgICAgICAqIHdpdGhvdXQgYW4gaW5kZXggYnVmZmVyIHNldC4gKFRoZSBmaXJzdCB0aW1lIGF0IGxlYXN0Li4uKQogICAgICAgICAqIEQzRDggc2ltcGx5IGRpZXMsIGJ1dCBJIGRvdWJ0IGl0IGNhbiBkbyBtdWNoIGhhcm0gdG8gcmV0dXJuCiAgICAgICAgICogRDNERVJSX0lOVkFMSURDQUxMIHRoZXJlIGFzIHdlbGwuICovCiAgICAgICAgRVJSKCIoJXApIDogQ2FsbGVkIHdpdGhvdXQgYSB2YWxpZCBpbmRleCBidWZmZXIgc2V0LCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYoVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtSXNVUCkgewogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9JTkRFWEJVRkZFUik7CiAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtSXNVUCA9IEZBTFNFOwogICAgfQogICAgdmJvID0gKChJV2luZUQzREluZGV4QnVmZmVySW1wbCAqKSBwSUIpLT52Ym87CgogICAgVFJBQ0UoIiglcCkgOiBUeXBlPSglZCwlcyksIG1pbj0lZCwgQ291bnRWPSVkLCBzdGFydElkeD0lZCwgY291bnRQPSVkXG4iLCBUaGlzLAogICAgICAgICAgUHJpbWl0aXZlVHlwZSwgZGVidWdfZDNkcHJpbWl0aXZldHlwZShQcmltaXRpdmVUeXBlKSwKICAgICAgICAgIG1pbkluZGV4LCBOdW1WZXJ0aWNlcywgc3RhcnRJbmRleCwgcHJpbUNvdW50KTsKCiAgICBJV2luZUQzREluZGV4QnVmZmVyX0dldERlc2MocElCLCAmSWR4QnVmRHNjKTsKICAgIGlmIChJZHhCdWZEc2MuRm9ybWF0ID09IFdJTkVEM0RGTVRfSU5ERVgxNikgewogICAgICAgIGlkeFN0cmlkZSA9IDI7CiAgICB9IGVsc2UgewogICAgICAgIGlkeFN0cmlkZSA9IDQ7CiAgICB9CgogICAgaWYoVGhpcy0+c3RhdGVCbG9jay0+bG9hZEJhc2VWZXJ0ZXhJbmRleCAhPSBUaGlzLT5zdGF0ZUJsb2NrLT5iYXNlVmVydGV4SW5kZXgpIHsKICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5sb2FkQmFzZVZlcnRleEluZGV4ID0gVGhpcy0+c3RhdGVCbG9jay0+YmFzZVZlcnRleEluZGV4OwogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TVFJFQU1TUkMpOwogICAgfQoKICAgIGRyYXdQcmltaXRpdmUoaWZhY2UsIFByaW1pdGl2ZVR5cGUsIHByaW1Db3VudCwgMCwgTnVtVmVydGljZXMsIHN0YXJ0SW5kZXgsCiAgICAgICAgICAgICAgICAgICBpZHhTdHJpZGUsIHZibyA/IE5VTEwgOiAoKElXaW5lRDNESW5kZXhCdWZmZXJJbXBsICopIHBJQiktPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwgbWluSW5kZXgpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdQcmltaXRpdmVVUChJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFByaW1pdGl2ZUNvdW50LCBDT05TVCB2b2lkKiBwVmVydGV4U3RyZWFtWmVyb0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFZlcnRleFN0cmVhbVplcm9TdHJpZGUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEVmVydGV4QnVmZmVyICp2YjsKCiAgICBUUkFDRSgiKCVwKSA6IFR5cGU9KCVkLCVzKSwgcENvdW50PSVkLCBwVnR4RGF0YT0lcCwgU3RyaWRlPSVkXG4iLCBUaGlzLCBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgZGVidWdfZDNkcHJpbWl0aXZldHlwZShQcmltaXRpdmVUeXBlKSwKICAgICAgICAgICAgIFByaW1pdGl2ZUNvdW50LCBwVmVydGV4U3RyZWFtWmVyb0RhdGEsIFZlcnRleFN0cmVhbVplcm9TdHJpZGUpOwoKICAgIC8qIE5vdGUgaW4gdGhlIGZvbGxvd2luZywgaXQncyBub3QgdGhpcyB0eXBlLCBidXQgdGhhdCdzIHRoZSBwdXJwb3NlIG9mIHN0cmVhbUlzVVAgKi8KICAgIHZiID0gVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlWzBdOwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlWzBdID0gKElXaW5lRDNEVmVydGV4QnVmZmVyICopcFZlcnRleFN0cmVhbVplcm9EYXRhOwogICAgaWYodmIpIElXaW5lRDNEVmVydGV4QnVmZmVyX1JlbGVhc2UodmIpOwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtT2Zmc2V0WzBdID0gMDsKICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVN0cmlkZVswXSA9IFZlcnRleFN0cmVhbVplcm9TdHJpZGU7CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Jc1VQID0gVFJVRTsKICAgIFRoaXMtPnN0YXRlQmxvY2stPmxvYWRCYXNlVmVydGV4SW5kZXggPSAwOwoKICAgIC8qIFRPRE86IE9ubHkgbWFyayBkaXJ0eSBpZiBkcmF3aW5nIGZyb20gYSBkaWZmZXJlbnQgVVAgYWRkcmVzcyAqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1NUUkVBTVNSQyk7CgogICAgZHJhd1ByaW1pdGl2ZShpZmFjZSwgUHJpbWl0aXZlVHlwZSwgUHJpbWl0aXZlQ291bnQsIDAgLyogc3RhcnQgdmVydGV4ICovLCAwICAvKiBOdW1WZXJ0aWNlcyAqLywKICAgICAgICAgICAgICAgICAgMCAvKiBpbmR4U3RhcnQqLywgMCAvKiBpbmR4U2l6ZSovLCBOVUxMIC8qIGluZHhEYXRhICovLCAwIC8qIGluZHhNaW4gKi8pOwoKICAgIC8qIE1TRE4gc3BlY2lmaWVzIHN0cmVhbSB6ZXJvIHNldHRpbmdzIG11c3QgYmUgc2V0IHRvIE5VTEwgKi8KICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVN0cmlkZVswXSA9IDA7CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbMF0gPSBOVUxMOwoKICAgIC8qIHN0cmVhbSB6ZXJvIHNldHRpbmdzIHNldCB0byBudWxsIGF0IGVuZCwgYXMgcGVyIHRoZSBtc2RuLiBObyBuZWVkIHRvIG1hcmsgZGlydHkgaGVyZSwgdGhlIGFwcCBoYXMgdG8gc2V0CiAgICAgKiB0aGUgbmV3IHN0cmVhbSBzb3VyY2VzIG9yIHVzZSBVUCBkcmF3aW5nIGFnYWluCiAgICAgKi8KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdJbmRleGVkUHJpbWl0aXZlVVAoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBNaW5WZXJ0ZXhJbmRleCwgVUlOVCBOdW1WZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgUHJpbWl0aXZlQ291bnQsIENPTlNUIHZvaWQqIHBJbmRleERhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNERk9STUFUIEluZGV4RGF0YUZvcm1hdCxDT05TVCB2b2lkKiBwVmVydGV4U3RyZWFtWmVyb0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFZlcnRleFN0cmVhbVplcm9TdHJpZGUpIHsKICAgIGludCAgICAgICAgICAgICAgICAgaWR4U3RyaWRlOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RWZXJ0ZXhCdWZmZXIgKnZiOwogICAgSVdpbmVEM0RJbmRleEJ1ZmZlciAqaWI7CgogICAgVFJBQ0UoIiglcCkgOiBUeXBlPSglZCwlcyksIE1pblZ0eElkeD0lZCwgTnVtVklkeD0lZCwgUENvdW50PSVkLCBwaWR4ZGF0YT0lcCwgSWR4Rm10PSVkLCBwVnR4ZGF0YT0lcCwgc3RyaWRlPSVkXG4iLAogICAgICAgICAgICAgVGhpcywgUHJpbWl0aXZlVHlwZSwgZGVidWdfZDNkcHJpbWl0aXZldHlwZShQcmltaXRpdmVUeXBlKSwKICAgICAgICAgICAgIE1pblZlcnRleEluZGV4LCBOdW1WZXJ0aWNlcywgUHJpbWl0aXZlQ291bnQsIHBJbmRleERhdGEsCiAgICAgICAgICAgICBJbmRleERhdGFGb3JtYXQsIHBWZXJ0ZXhTdHJlYW1aZXJvRGF0YSwgVmVydGV4U3RyZWFtWmVyb1N0cmlkZSk7CgogICAgaWYgKEluZGV4RGF0YUZvcm1hdCA9PSBXSU5FRDNERk1UX0lOREVYMTYpIHsKICAgICAgICBpZHhTdHJpZGUgPSAyOwogICAgfSBlbHNlIHsKICAgICAgICBpZHhTdHJpZGUgPSA0OwogICAgfQoKICAgIC8qIE5vdGUgaW4gdGhlIGZvbGxvd2luZywgaXQncyBub3QgdGhpcyB0eXBlLCBidXQgdGhhdCdzIHRoZSBwdXJwb3NlIG9mIHN0cmVhbUlzVVAgKi8KICAgIHZiID0gVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlWzBdOwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlWzBdID0gKElXaW5lRDNEVmVydGV4QnVmZmVyICopcFZlcnRleFN0cmVhbVplcm9EYXRhOwogICAgaWYodmIpIElXaW5lRDNEVmVydGV4QnVmZmVyX1JlbGVhc2UodmIpOwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtSXNVUCA9IFRSVUU7CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1PZmZzZXRbMF0gPSAwOwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU3RyaWRlWzBdID0gVmVydGV4U3RyZWFtWmVyb1N0cmlkZTsKCiAgICAvKiBTZXQgdG8gMCBhcyBwZXIgbXNkbi4gRG8gaXQgbm93IGR1ZSB0byB0aGUgc3RyZWFtIHNvdXJjZSBsb2FkaW5nIGR1cmluZyBkcmF3UHJpbWl0aXZlICovCiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5iYXNlVmVydGV4SW5kZXggPSAwOwogICAgVGhpcy0+c3RhdGVCbG9jay0+bG9hZEJhc2VWZXJ0ZXhJbmRleCA9IDA7CiAgICAvKiBNYXJrIHRoZSBzdGF0ZSBkaXJ0eSB1bnRpbCB3ZSBoYXZlIG5pY2VyIHRyYWNraW5nIG9mIHRoZSBzdHJlYW0gc291cmNlIHBvaW50ZXJzICovCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVkRFQ0wpOwogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX0lOREVYQlVGRkVSKTsKCiAgICBkcmF3UHJpbWl0aXZlKGlmYWNlLCBQcmltaXRpdmVUeXBlLCBQcmltaXRpdmVDb3VudCwgMCAvKiB2ZXJ0ZXhTdGFydCAqLywgTnVtVmVydGljZXMsIDAgLyogaW5keFN0YXJ0ICovLCBpZHhTdHJpZGUsIHBJbmRleERhdGEsIE1pblZlcnRleEluZGV4KTsKCiAgICAvKiBNU0ROIHNwZWNpZmllcyBzdHJlYW0gemVybyBzZXR0aW5ncyBhbmQgaW5kZXggYnVmZmVyIG11c3QgYmUgc2V0IHRvIE5VTEwgKi8KICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVswXSA9IE5VTEw7CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1TdHJpZGVbMF0gPSAwOwogICAgaWIgPSBUaGlzLT5zdGF0ZUJsb2NrLT5wSW5kZXhEYXRhOwogICAgaWYoaWIpIHsKICAgICAgICBJV2luZUQzREluZGV4QnVmZmVyX1JlbGVhc2UoaWIpOwogICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPnBJbmRleERhdGEgPSBOVUxMOwogICAgfQogICAgLyogTm8gbmVlZCB0byBtYXJrIHRoZSBzdHJlYW0gc291cmNlIHN0YXRlIGRpcnR5IGhlcmUuIEVpdGhlciB0aGUgYXBwIGNhbGxzIFVQIGRyYXdpbmcgYWdhaW4sIG9yIGl0IGhhcyB0byBjYWxsCiAgICAgKiBTZXRTdHJlYW1Tb3VyY2UgdG8gc3BlY2lmeSBhIHZlcnRleCBidWZmZXIKICAgICAqLwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdQcmltaXRpdmVTdHJpZGVkIChJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsIFVJTlQgUHJpbWl0aXZlQ291bnQsIFdpbmVEaXJlY3QzRFZlcnRleFN0cmlkZWREYXRhICpEcmF3UHJpbVN0cmlkZURhdGEpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CgogICAgLyogTWFyayB0aGUgc3RhdGUgZGlydHkgdW50aWwgd2UgaGF2ZSBuaWNlciB0cmFja2luZwogICAgICogaXRzIGZpbmUgdG8gY2hhbmdlIGJhc2VWZXJ0ZXhJbmRleCBiZWNhdXNlIHRoYXQgY2FsbCBpcyBvbmx5IGNhbGxlZCBieSBkZHJhdyB3aGljaCBkb2VzIG5vdCBuZWVkCiAgICAgKiB0aGF0IHZhbHVlLgogICAgICovCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVkRFQ0wpOwogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX0lOREVYQlVGRkVSKTsKICAgIFRoaXMtPnN0YXRlQmxvY2stPmJhc2VWZXJ0ZXhJbmRleCA9IDA7CiAgICBUaGlzLT51cF9zdHJpZGVkID0gRHJhd1ByaW1TdHJpZGVEYXRhOwogICAgZHJhd1ByaW1pdGl2ZShpZmFjZSwgUHJpbWl0aXZlVHlwZSwgUHJpbWl0aXZlQ291bnQsIDAsIDAsIDAsIDAsIE5VTEwsIDApOwogICAgVGhpcy0+dXBfc3RyaWRlZCA9IE5VTEw7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3SW5kZXhlZFByaW1pdGl2ZVN0cmlkZWQoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLCBVSU5UIFByaW1pdGl2ZUNvdW50LCBXaW5lRGlyZWN0M0RWZXJ0ZXhTdHJpZGVkRGF0YSAqRHJhd1ByaW1TdHJpZGVEYXRhLCBVSU5UIE51bVZlcnRpY2VzLCBDT05TVCB2b2lkICpwSW5kZXhEYXRhLCBXSU5FRDNERk9STUFUIEluZGV4RGF0YUZvcm1hdCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIERXT1JEIGlkeFNpemUgPSAoSW5kZXhEYXRhRm9ybWF0ID09IFdJTkVEM0RGTVRfSU5ERVgzMiA/IDQgOiAyKTsKCiAgICAvKiBNYXJrIHRoZSBzdGF0ZSBkaXJ0eSB1bnRpbCB3ZSBoYXZlIG5pY2VyIHRyYWNraW5nCiAgICAgKiBpdHMgZmluZSB0byBjaGFuZ2UgYmFzZVZlcnRleEluZGV4IGJlY2F1c2UgdGhhdCBjYWxsIGlzIG9ubHkgY2FsbGVkIGJ5IGRkcmF3IHdoaWNoIGRvZXMgbm90IG5lZWQKICAgICAqIHRoYXQgdmFsdWUuCiAgICAgKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9WREVDTCk7CiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfSU5ERVhCVUZGRVIpOwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtSXNVUCA9IFRSVUU7CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5iYXNlVmVydGV4SW5kZXggPSAwOwogICAgVGhpcy0+dXBfc3RyaWRlZCA9IERyYXdQcmltU3RyaWRlRGF0YTsKICAgIGRyYXdQcmltaXRpdmUoaWZhY2UsIFByaW1pdGl2ZVR5cGUsIFByaW1pdGl2ZUNvdW50LCAwIC8qIHN0YXJ0dmVydGV4aWR4ICovLCAwIC8qIG51bWluZGljZXMgKi8sIDAgLyogc3RhcnRpZHggKi8sIGlkeFNpemUsIHBJbmRleERhdGEsIDAgLyogbWluaW5kZXggKi8pOwogICAgVGhpcy0+dXBfc3RyaWRlZCA9IE5VTEw7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgSVdpbmVEM0REZXZpY2VJbXBsX1VwZGF0ZVZvbHVtZShJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEVm9sdW1lICpwU291cmNlVm9sdW1lLCBJV2luZUQzRFZvbHVtZSAqcERlc3RpbmF0aW9uVm9sdW1lKSB7CiAgICAvKiBUaGlzIGlzIGEgaGVscGVyIGZ1bmN0aW9uIGZvciBVcGRhdGVUZXh0dXJlLCB0aGVyZSBpcyBubyBwdWJsaWMgVXBkYXRlVm9sdW1lIG1ldGhvZCBpbiBkM2QuIFNpbmNlIGl0J3MKICAgICAqIG5vdCBjYWxsYWJsZSBieSB0aGUgYXBwIGRpcmVjdGx5IG5vIHBhcmFtZXRlciB2YWxpZGF0aW9uIGNoZWNrcyBhcmUgbmVlZGVkIGhlcmUuCiAgICAgKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBXSU5FRDNETE9DS0VEX0JPWCBzcmM7CiAgICBXSU5FRDNETE9DS0VEX0JPWCBkc3Q7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcCktPiglcCwgJXApXG4iLCBUaGlzLCBwU291cmNlVm9sdW1lLCBwRGVzdGluYXRpb25Wb2x1bWUpOwoKICAgIC8qIFRPRE86IEltcGxlbWVudCBkaXJlY3QgbG9hZGluZyBpbnRvIHRoZSBnbCB2b2x1bWUgaW5zdGVhZCBvZiB1c2luZyBtZW1jcHkgYW5kCiAgICAgKiBkaXJ0aWZpY2F0aW9uIHRvIGltcHJvdmUgbG9hZGluZyBwZXJmb3JtYW5jZS4KICAgICAqLwogICAgaHIgPSBJV2luZUQzRFZvbHVtZV9Mb2NrQm94KHBTb3VyY2VWb2x1bWUsICZzcmMsIE5VTEwsIFdJTkVEM0RMT0NLX1JFQURPTkxZKTsKICAgIGlmKEZBSUxFRChocikpIHJldHVybiBocjsKICAgIGhyID0gSVdpbmVEM0RWb2x1bWVfTG9ja0JveChwRGVzdGluYXRpb25Wb2x1bWUsICZkc3QsIE5VTEwsIFdJTkVEM0RMT0NLX0RJU0NBUkQpOwogICAgaWYoRkFJTEVEKGhyKSkgewogICAgSVdpbmVEM0RWb2x1bWVfVW5sb2NrQm94KHBTb3VyY2VWb2x1bWUpOwogICAgICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgbWVtY3B5KGRzdC5wQml0cywgc3JjLnBCaXRzLCAoKElXaW5lRDNEVm9sdW1lSW1wbCAqKSBwRGVzdGluYXRpb25Wb2x1bWUpLT5yZXNvdXJjZS5zaXplKTsKCiAgICBociA9IElXaW5lRDNEVm9sdW1lX1VubG9ja0JveChwRGVzdGluYXRpb25Wb2x1bWUpOwogICAgaWYoRkFJTEVEKGhyKSkgewogICAgICAgIElXaW5lRDNEVm9sdW1lX1VubG9ja0JveChwU291cmNlVm9sdW1lKTsKICAgIH0gZWxzZSB7CiAgICAgICAgaHIgPSBJV2luZUQzRFZvbHVtZV9VbmxvY2tCb3gocFNvdXJjZVZvbHVtZSk7CiAgICB9CiAgICByZXR1cm4gaHI7Cn0KCi8qIFlldCBhbm90aGVyIHdheSB0byB1cGRhdGUgYSB0ZXh0dXJlLCBzb21lIGFwcHMgdXNlIHRoaXMgdG8gbG9hZCBkZWZhdWx0IHRleHR1cmVzIGluc3RlYWQgb2YgdXNpbmcgc3VyZmFjZS90ZXh0dXJlIGxvY2svdW5sb2NrICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfVXBkYXRlVGV4dHVyZSAoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzREJhc2VUZXh0dXJlICpwU291cmNlVGV4dHVyZSwgIElXaW5lRDNEQmFzZVRleHR1cmUgKnBEZXN0aW5hdGlvblRleHR1cmUpewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSFJFU1VMVCBociA9IFdJTkVEM0RfT0s7CiAgICBXSU5FRDNEUkVTT1VSQ0VUWVBFIHNvdXJjZVR5cGU7CiAgICBXSU5FRDNEUkVTT1VSQ0VUWVBFIGRlc3RpbmF0aW9uVHlwZTsKICAgIGludCBpICxsZXZlbHM7CgogICAgLyogVE9ETzogdGhpbmsgYWJvdXQgbW92aW5nIHRoZSBjb2RlIGludG8gSVdpbmVEM0RCYXNlVGV4dHVyZSAgKi8KCiAgICBUUkFDRSgiKCVwKSBTb3VyY2UgJXAgRGVzdGluYXRpb24gJXBcbiIsIFRoaXMsIHBTb3VyY2VUZXh0dXJlLCBwRGVzdGluYXRpb25UZXh0dXJlKTsKCiAgICAvKiB2ZXJpZnkgdGhhdCB0aGUgc291cmNlIGFuZCBkZXN0aW5hdGlvbiB0ZXh0dXJlcyBhcmVuJ3QgTlVMTCAqLwogICAgaWYgKE5VTEwgPT0gcFNvdXJjZVRleHR1cmUgfHwgTlVMTCA9PSBwRGVzdGluYXRpb25UZXh0dXJlKSB7CiAgICAgICAgV0FSTigiKCVwKSA6IHNvdXJjZSAoJXApIGFuZCBkZXN0aW5hdGlvbiAoJXApIHRleHR1cmVzIG11c3Qgbm90IGJlIE5VTEwsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iLAogICAgICAgICAgICAgVGhpcywgcFNvdXJjZVRleHR1cmUsIHBEZXN0aW5hdGlvblRleHR1cmUpOwogICAgICAgIGhyID0gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBpZiAocFNvdXJjZVRleHR1cmUgPT0gcERlc3RpbmF0aW9uVGV4dHVyZSkgewogICAgICAgIFdBUk4oIiglcCkgOiBzb3VyY2UgKCVwKSBhbmQgZGVzdGluYXRpb24gKCVwKSB0ZXh0dXJlcyBtdXN0IGJlIGRpZmZlcmVudCwgcmV0dXJuaW5nIFdJTkVEM0RFUlJfSU5WQUxJRENBTExcbiIsCiAgICAgICAgICAgICBUaGlzLCBwU291cmNlVGV4dHVyZSwgcERlc3RpbmF0aW9uVGV4dHVyZSk7CiAgICAgICAgaHIgPSBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgLyogVmVyaWZ5IHRoYXQgdGhlIHNvdXJjZSBhbmQgZGVzdGluYXRpb24gdGV4dHVyZXMgYXJlIHRoZSBzYW1lIHR5cGUgKi8KICAgIHNvdXJjZVR5cGUgICAgICA9IElXaW5lRDNEQmFzZVRleHR1cmVfR2V0VHlwZShwU291cmNlVGV4dHVyZSk7CiAgICBkZXN0aW5hdGlvblR5cGUgPSBJV2luZUQzREJhc2VUZXh0dXJlX0dldFR5cGUocERlc3RpbmF0aW9uVGV4dHVyZSk7CgogICAgaWYgKHNvdXJjZVR5cGUgIT0gZGVzdGluYXRpb25UeXBlKSB7CiAgICAgICAgV0FSTigiKCVwKSBTb3JjZSBhbmQgZGVzdGluYXRpb24gdHlwZXMgbXVzdCBtYXRjaCwgcmV0dXJuaW5nIFdJTkVEM0RFUlJfSU5WQUxJRENBTExcbiIsCiAgICAgICAgICAgICBUaGlzKTsKICAgICAgICBociA9IFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogY2hlY2sgdGhhdCBib3RoIHRleHR1cmVzIGhhdmUgdGhlIGlkZW50aWNhbCBudW1iZXJzIG9mIGxldmVscyAgKi8KICAgIGlmIChJV2luZUQzREJhc2VUZXh0dXJlX0dldExldmVsQ291bnQocERlc3RpbmF0aW9uVGV4dHVyZSkgICE9IElXaW5lRDNEQmFzZVRleHR1cmVfR2V0TGV2ZWxDb3VudChwU291cmNlVGV4dHVyZSkpIHsKICAgICAgICBXQVJOKCIoJXApIDogc291cmNlICglcCkgYW5kIGRlc3RpbmF0aW9uICglcCkgdGV4dHVyZXMgbXVzdCBoYXZlIGlkZW50aWNsZSBudW1iZXJzIG9mIGxldmVscywgcmV0dXJuaW5nIFdJTkVEM0RFUlJfSU5WQUxJRENBTExcbiIsIFRoaXMsIHBTb3VyY2VUZXh0dXJlLCBwRGVzdGluYXRpb25UZXh0dXJlKTsKICAgICAgICBociA9IFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYgKFdJTkVEM0RfT0sgPT0gaHIpIHsKCiAgICAgICAgLyogTWFrZSBzdXJlIHRoYXQgdGhlIGRlc3RpbmF0aW9uIHRleHR1cmUgaXMgbG9hZGVkICovCiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9QcmVMb2FkKHBEZXN0aW5hdGlvblRleHR1cmUpOwoKICAgICAgICAvKiBVcGRhdGUgZXZlcnkgc3VyZmFjZSBsZXZlbCBvZiB0aGUgdGV4dHVyZSAqLwogICAgICAgIGxldmVscyA9IElXaW5lRDNEQmFzZVRleHR1cmVfR2V0TGV2ZWxDb3VudChwRGVzdGluYXRpb25UZXh0dXJlKTsKCiAgICAgICAgc3dpdGNoIChzb3VyY2VUeXBlKSB7CiAgICAgICAgY2FzZSBXSU5FRDNEUlRZUEVfVEVYVFVSRToKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlICpzcmNTdXJmYWNlOwogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlICpkZXN0U3VyZmFjZTsKCiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwIDsgaSA8IGxldmVscyA7ICsraSkgewogICAgICAgICAgICAgICAgICAgIElXaW5lRDNEVGV4dHVyZV9HZXRTdXJmYWNlTGV2ZWwoKElXaW5lRDNEVGV4dHVyZSAqKXBTb3VyY2VUZXh0dXJlLCAgICAgIGksICZzcmNTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFRleHR1cmVfR2V0U3VyZmFjZUxldmVsKChJV2luZUQzRFRleHR1cmUgKilwRGVzdGluYXRpb25UZXh0dXJlLCBpLCAmZGVzdFN1cmZhY2UpOwogICAgICAgICAgICAgICAgICAgIGhyID0gSVdpbmVEM0REZXZpY2VfVXBkYXRlU3VyZmFjZShpZmFjZSwgc3JjU3VyZmFjZSwgTlVMTCwgZGVzdFN1cmZhY2UsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKHNyY1N1cmZhY2UpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKGRlc3RTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICBpZiAoV0lORUQzRF9PSyAhPSBocikgewogICAgICAgICAgICAgICAgICAgICAgICBXQVJOKCIoJXApIDogQ2FsbCB0byB1cGRhdGUgc3VyZmFjZSBmYWlsZWRcbiIsIFRoaXMpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaHI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgV0lORUQzRFJUWVBFX0NVQkVURVhUVVJFOgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2UgKnNyY1N1cmZhY2U7CiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2UgKmRlc3RTdXJmYWNlOwogICAgICAgICAgICAgICAgV0lORUQzRENVQkVNQVBfRkFDRVMgZmFjZVR5cGU7CgogICAgICAgICAgICAgICAgZm9yIChpID0gMCA7IGkgPCBsZXZlbHMgOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICAvKiBVcGRhdGUgZWFjaCBjdWJlIGZhY2UgKi8KICAgICAgICAgICAgICAgICAgICBmb3IgKGZhY2VUeXBlID0gV0lORUQzRENVQkVNQVBfRkFDRV9QT1NJVElWRV9YOyBmYWNlVHlwZSA8PSBXSU5FRDNEQ1VCRU1BUF9GQUNFX05FR0FUSVZFX1o7ICsrZmFjZVR5cGUpewogICAgICAgICAgICAgICAgICAgICAgICBociA9IElXaW5lRDNEQ3ViZVRleHR1cmVfR2V0Q3ViZU1hcFN1cmZhY2UoKElXaW5lRDNEQ3ViZVRleHR1cmUgKilwU291cmNlVGV4dHVyZSwgICAgICBmYWNlVHlwZSwgaSwgJnNyY1N1cmZhY2UpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoV0lORUQzRF9PSyAhPSBocikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYTUUoIiglcCkgOiBGYWlsZWQgdG8gZ2V0IHNyYyBjdWJlIHN1cmZhY2UgZmFjZXR5cGUgJWQsIGxldmVsICVkXG4iLCBUaGlzLCBmYWNlVHlwZSwgaSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUkFDRSgiR290IHNyY1N1cmZhY2UgJXBcbiIsIHNyY1N1cmZhY2UpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGhyID0gSVdpbmVEM0RDdWJlVGV4dHVyZV9HZXRDdWJlTWFwU3VyZmFjZSgoSVdpbmVEM0RDdWJlVGV4dHVyZSAqKXBEZXN0aW5hdGlvblRleHR1cmUsIGZhY2VUeXBlLCBpLCAmZGVzdFN1cmZhY2UpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoV0lORUQzRF9PSyAhPSBocikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgRklYTUUoIiglcCkgOiBGYWlsZWQgdG8gZ2V0IHNyYyBjdWJlIHN1cmZhY2UgZmFjZXR5cGUgJWQsIGxldmVsICVkXG4iLCBUaGlzLCBmYWNlVHlwZSwgaSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUkFDRSgiR290IGRlc3JTdXJmYWNlICVwXG4iLCBkZXN0U3VyZmFjZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaHIgPSBJV2luZUQzRERldmljZV9VcGRhdGVTdXJmYWNlKGlmYWNlLCBzcmNTdXJmYWNlLCBOVUxMLCBkZXN0U3VyZmFjZSwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKHNyY1N1cmZhY2UpOwogICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShkZXN0U3VyZmFjZSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChXSU5FRDNEX09LICE9IGhyKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBXQVJOKCIoJXApIDogQ2FsbCB0byB1cGRhdGUgc3VyZmFjZSBmYWlsZWRcbiIsIFRoaXMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9WT0xVTUVURVhUVVJFOgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBJV2luZUQzRFZvbHVtZSAgKnNyY1ZvbHVtZSAgPSBOVUxMOwogICAgICAgICAgICAgICAgSVdpbmVEM0RWb2x1bWUgICpkZXN0Vm9sdW1lID0gTlVMTDsKCiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwIDsgaSA8IGxldmVscyA7ICsraSkgewogICAgICAgICAgICAgICAgICAgIElXaW5lRDNEVm9sdW1lVGV4dHVyZV9HZXRWb2x1bWVMZXZlbCgoSVdpbmVEM0RWb2x1bWVUZXh0dXJlICopcFNvdXJjZVRleHR1cmUsICAgICAgaSwgJnNyY1ZvbHVtZSk7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RWb2x1bWVUZXh0dXJlX0dldFZvbHVtZUxldmVsKChJV2luZUQzRFZvbHVtZVRleHR1cmUgKilwRGVzdGluYXRpb25UZXh0dXJlLCBpLCAmZGVzdFZvbHVtZSk7CiAgICAgICAgICAgICAgICAgICAgaHIgPSAgSVdpbmVEM0REZXZpY2VJbXBsX1VwZGF0ZVZvbHVtZShpZmFjZSwgc3JjVm9sdW1lLCBkZXN0Vm9sdW1lKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFZvbHVtZV9SZWxlYXNlKHNyY1ZvbHVtZSk7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RWb2x1bWVfUmVsZWFzZShkZXN0Vm9sdW1lKTsKICAgICAgICAgICAgICAgICAgICBpZiAoV0lORUQzRF9PSyAhPSBocikgewogICAgICAgICAgICAgICAgICAgICAgICBXQVJOKCIoJXApIDogQ2FsbCB0byB1cGRhdGUgdm9sdW1lIGZhaWxlZFxuIiwgVGhpcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBocjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEZJWE1FKCIoJXApIDogVW5zdXBwb3J0ZWQgc291cmNlIGFuZCBkZXN0aW5hdGlvbiB0eXBlXG4iLCBUaGlzKTsKICAgICAgICAgICAgaHIgPSBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRGcm9udEJ1ZmZlckRhdGEoSVdpbmVEM0REZXZpY2UgKmlmYWNlLFVJTlQgaVN3YXBDaGFpbiwgSVdpbmVEM0RTdXJmYWNlICpwRGVzdFN1cmZhY2UpIHsKICAgIElXaW5lRDNEU3dhcENoYWluICpzd2FwQ2hhaW47CiAgICBIUkVTVUxUIGhyOwogICAgaHIgPSBJV2luZUQzRERldmljZUltcGxfR2V0U3dhcENoYWluKGlmYWNlLCAgaVN3YXBDaGFpbiwgKElXaW5lRDNEU3dhcENoYWluICoqKSZzd2FwQ2hhaW4pOwogICAgaWYoaHIgPT0gV0lORUQzRF9PSykgewogICAgICAgIGhyID0gSVdpbmVEM0RTd2FwQ2hhaW5fR2V0RnJvbnRCdWZmZXJEYXRhKHN3YXBDaGFpbiwgcERlc3RTdXJmYWNlKTsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2Uoc3dhcENoYWluKTsKICAgIH0KICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX1ZhbGlkYXRlRGV2aWNlKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQqIHBOdW1QYXNzZXMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIC8qIHJldHVybiBhIHNlbnNpYmxlIGRlZmF1bHQgKi8KICAgICpwTnVtUGFzc2VzID0gMTsKICAgIC8qIFRPRE86IElmIHRoZSB3aW5kb3cgaXMgbWluaW1pemVkIHRoZW4gdmFsaWRhdGUgZGV2aWNlIHNob3VsZCByZXR1cm4gc29tZXRoaW5nIG90aGVyIHRoYW4gV0lORUQzRF9PSyAqLwogICAgRklYTUUoIiglcCkgOiBzdHViXG4iLCBUaGlzKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfU2V0UGFsZXR0ZUVudHJpZXMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIFBhbGV0dGVOdW1iZXIsIENPTlNUIFBBTEVUVEVFTlRSWSogcEVudHJpZXMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIGludCBqOwogICAgVFJBQ0UoIiglcCkgOiBQYWxldHRlTnVtYmVyICV1XG4iLCBUaGlzLCBQYWxldHRlTnVtYmVyKTsKICAgIGlmICggUGFsZXR0ZU51bWJlciA8IDAgfHwgUGFsZXR0ZU51bWJlciA+PSBNQVhfUEFMRVRURVMpIHsKICAgICAgICBXQVJOKCIoJXApIDogKCV1KSBPdXQgb2YgcmFuZ2UgMC0ldSwgcmV0dXJuaW5nIEludmFsaWQgQ2FsbFxuIiwgVGhpcywgUGFsZXR0ZU51bWJlciwgTUFYX1BBTEVUVEVTKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIGZvciAoaiA9IDA7IGogPCAyNTY7ICsraikgewogICAgICAgIFRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdW2pdLnBlUmVkICAgPSBwRW50cmllc1tqXS5wZVJlZDsKICAgICAgICBUaGlzLT5wYWxldHRlc1tQYWxldHRlTnVtYmVyXVtqXS5wZUdyZWVuID0gcEVudHJpZXNbal0ucGVHcmVlbjsKICAgICAgICBUaGlzLT5wYWxldHRlc1tQYWxldHRlTnVtYmVyXVtqXS5wZUJsdWUgID0gcEVudHJpZXNbal0ucGVCbHVlOwogICAgICAgIFRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdW2pdLnBlRmxhZ3MgPSBwRW50cmllc1tqXS5wZUZsYWdzOwogICAgfQogICAgVFJBQ0UoIiglcCkgOiByZXR1cm5pbmdcbiIsIFRoaXMpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQYWxldHRlRW50cmllcyhJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgUGFsZXR0ZU51bWJlciwgUEFMRVRURUVOVFJZKiBwRW50cmllcykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaW50IGo7CiAgICBUUkFDRSgiKCVwKSA6IFBhbGV0dGVOdW1iZXIgJXVcbiIsIFRoaXMsIFBhbGV0dGVOdW1iZXIpOwogICAgaWYgKCBQYWxldHRlTnVtYmVyIDwgMCB8fCBQYWxldHRlTnVtYmVyID49IE1BWF9QQUxFVFRFUykgewogICAgICAgIFdBUk4oIiglcCkgOiAoJXUpIE91dCBvZiByYW5nZSAwLSV1LCByZXR1cm5pbmcgSW52YWxpZCBDYWxsXG4iLCBUaGlzLCBQYWxldHRlTnVtYmVyLCBNQVhfUEFMRVRURVMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgZm9yIChqID0gMDsgaiA8IDI1NjsgKytqKSB7CiAgICAgICAgcEVudHJpZXNbal0ucGVSZWQgICA9IFRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdW2pdLnBlUmVkOwogICAgICAgIHBFbnRyaWVzW2pdLnBlR3JlZW4gPSBUaGlzLT5wYWxldHRlc1tQYWxldHRlTnVtYmVyXVtqXS5wZUdyZWVuOwogICAgICAgIHBFbnRyaWVzW2pdLnBlQmx1ZSAgPSBUaGlzLT5wYWxldHRlc1tQYWxldHRlTnVtYmVyXVtqXS5wZUJsdWU7CiAgICAgICAgcEVudHJpZXNbal0ucGVGbGFncyA9IFRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdW2pdLnBlRmxhZ3M7CiAgICB9CiAgICBUUkFDRSgiKCVwKSA6IHJldHVybmluZ1xuIiwgVGhpcyk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEN1cnJlbnRUZXh0dXJlUGFsZXR0ZShJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgUGFsZXR0ZU51bWJlcikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiBQYWxldHRlTnVtYmVyICV1XG4iLCBUaGlzLCBQYWxldHRlTnVtYmVyKTsKICAgIGlmICggUGFsZXR0ZU51bWJlciA8IDAgfHwgUGFsZXR0ZU51bWJlciA+PSBNQVhfUEFMRVRURVMpIHsKICAgICAgICBXQVJOKCIoJXApIDogKCV1KSBPdXQgb2YgcmFuZ2UgMC0ldSwgcmV0dXJuaW5nIEludmFsaWQgQ2FsbFxuIiwgVGhpcywgUGFsZXR0ZU51bWJlciwgTUFYX1BBTEVUVEVTKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIC8qVE9ETzogc3RhdGVibG9ja3MgKi8KICAgIFRoaXMtPmN1cnJlbnRQYWxldHRlID0gUGFsZXR0ZU51bWJlcjsKICAgIFRSQUNFKCIoJXApIDogcmV0dXJuaW5nXG4iLCBUaGlzKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfR2V0Q3VycmVudFRleHR1cmVQYWxldHRlKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCogUGFsZXR0ZU51bWJlcikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaWYgKFBhbGV0dGVOdW1iZXIgPT0gTlVMTCkgewogICAgICAgIFdBUk4oIiglcCkgOiByZXR1cm5pbmcgSW52YWxpZCBDYWxsXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIC8qVE9ETzogc3RhdGVibG9ja3MgKi8KICAgICpQYWxldHRlTnVtYmVyID0gVGhpcy0+Y3VycmVudFBhbGV0dGU7CiAgICBUUkFDRSgiKCVwKSA6IHJldHVybmluZyAgJXVcbiIsIFRoaXMsICpQYWxldHRlTnVtYmVyKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfU2V0U29mdHdhcmVWZXJ0ZXhQcm9jZXNzaW5nKElXaW5lRDNERGV2aWNlICppZmFjZSwgQk9PTCBiU29mdHdhcmUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIHN0YXRpYyBCT09MIHNob3dGaXhtZXMgPSBUUlVFOwogICAgaWYgKHNob3dGaXhtZXMpIHsKICAgICAgICBGSVhNRSgiKCVwKSA6IHN0dWJcbiIsIFRoaXMpOwogICAgICAgIHNob3dGaXhtZXMgPSBGQUxTRTsKICAgIH0KCiAgICBUaGlzLT5zb2Z0d2FyZVZlcnRleFByb2Nlc3NpbmcgPSBiU29mdHdhcmU7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKCnN0YXRpYyBCT09MICAgICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTb2Z0d2FyZVZlcnRleFByb2Nlc3NpbmcoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBzdGF0aWMgQk9PTCBzaG93Rml4bWVzID0gVFJVRTsKICAgIGlmIChzaG93Rml4bWVzKSB7CiAgICAgICAgRklYTUUoIiglcCkgOiBzdHViXG4iLCBUaGlzKTsKICAgICAgICBzaG93Rml4bWVzID0gRkFMU0U7CiAgICB9CiAgICByZXR1cm4gVGhpcy0+c29mdHdhcmVWZXJ0ZXhQcm9jZXNzaW5nOwp9CgoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFJhc3RlclN0YXR1cyhJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgaVN3YXBDaGFpbiwgV0lORUQzRFJBU1RFUl9TVEFUVVMqIHBSYXN0ZXJTdGF0dXMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3dhcENoYWluICpzd2FwQ2hhaW47CiAgICBIUkVTVUxUIGhyOwoKICAgIFRSQUNFKCIoJXApIDogIFN3YXBDaGFpbiAlZCByZXR1cm5pbmcgJXBcbiIsIFRoaXMsIGlTd2FwQ2hhaW4sIHBSYXN0ZXJTdGF0dXMpOwoKICAgIGhyID0gSVdpbmVEM0REZXZpY2VJbXBsX0dldFN3YXBDaGFpbihpZmFjZSwgIGlTd2FwQ2hhaW4sIChJV2luZUQzRFN3YXBDaGFpbiAqKikmc3dhcENoYWluKTsKICAgIGlmKGhyID09IFdJTkVEM0RfT0spewogICAgICAgIGhyID0gSVdpbmVEM0RTd2FwQ2hhaW5fR2V0UmFzdGVyU3RhdHVzKHN3YXBDaGFpbiwgcFJhc3RlclN0YXR1cyk7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwQ2hhaW4pOwogICAgfWVsc2V7CiAgICAgICAgRklYTUUoIiglcCkgSVdpbmVEM0RTd2FwQ2hhaW5fR2V0UmFzdGVyU3RhdHVzIHJldHVybmVkIGluIGVycm9yXG4iLCBUaGlzKTsKICAgIH0KICAgIHJldHVybiBocjsKfQoKCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9TZXROUGF0Y2hNb2RlKElXaW5lRDNERGV2aWNlICppZmFjZSwgZmxvYXQgblNlZ21lbnRzKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBzdGF0aWMgQk9PTCBzaG93Zml4bWVzID0gVFJVRTsKICAgIGlmKG5TZWdtZW50cyAhPSAwLjBmKSB7CiAgICAgICAgaWYoIHNob3dmaXhtZXMpIHsKICAgICAgICAgICAgRklYTUUoIiglcCkgOiBzdHViIG5TZWdtZW50cyglZilcbiIsIFRoaXMsIG5TZWdtZW50cyk7CiAgICAgICAgICAgIHNob3dmaXhtZXMgPSBGQUxTRTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIGZsb2F0ICAgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0dldE5QYXRjaE1vZGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBzdGF0aWMgQk9PTCBzaG93Zml4bWVzID0gVFJVRTsKICAgIGlmKCBzaG93Zml4bWVzKSB7CiAgICAgICAgRklYTUUoIiglcCkgOiBzdHViIHJldHVybmluZyglZilcbiIsIFRoaXMsIDAuMGYpOwogICAgICAgIHNob3dmaXhtZXMgPSBGQUxTRTsKICAgIH0KICAgIHJldHVybiAwLjBmOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfVXBkYXRlU3VyZmFjZShJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEU3VyZmFjZSAqcFNvdXJjZVN1cmZhY2UsIENPTlNUIFJFQ1QqIHBTb3VyY2VSZWN0LCBJV2luZUQzRFN1cmZhY2UgKnBEZXN0aW5hdGlvblN1cmZhY2UsIENPTlNUIFBPSU5UKiBwRGVzdFBvaW50KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgICpUaGlzICAgICAgICAgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgLyoqIFRPRE86IHJlbW92ZSBjYXN0cyB0byBJV2luZUQzRFN1cmZhY2VJbXBsCiAgICAgKiAgICAgICBOT1RFOiBtb3ZlIGNvZGUgdG8gc3VyZmFjZSB0byBhY2NvbXBsaXNoIHRoaXMKICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKnBTcmNTdXJmYWNlICA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopcFNvdXJjZVN1cmZhY2U7CiAgICBpbnQgc3JjV2lkdGgsIHNyY0hlaWdodDsKICAgIHVuc2lnbmVkIGludCAgc3JjU3VyZmFjZVdpZHRoLCBzcmNTdXJmYWNlSGVpZ2h0LCBkZXN0U3VyZmFjZVdpZHRoLCBkZXN0U3VyZmFjZUhlaWdodDsKICAgIFdJTkVEM0RGT1JNQVQgZGVzdEZvcm1hdCwgc3JjRm9ybWF0OwogICAgVUlOVCAgICAgICAgICBkZXN0U2l6ZTsKICAgIGludCBzcmNMZWZ0LCBkZXN0TGVmdCwgZGVzdFRvcDsKICAgIFdJTkVEM0RQT09MICAgICAgIHNyY1Bvb2wsIGRlc3RQb29sOwogICAgaW50IG9mZnNldCAgICA9IDA7CiAgICBpbnQgcm93b2Zmc2V0ID0gMDsgLyogaG93IG1hbnkgYnl0ZXMgdG8gYWRkIG9udG8gdGhlIGVuZCBvZiBhIHJvdyB0byB3cmFwYXJvdW5kIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIG5leHQgKi8KICAgIGdsRGVzY3JpcHRvciAqZ2xEZXNjcmlwdGlvbiA9IE5VTEw7CiAgICBHTGVudW0gZHVtbXk7CiAgICBpbnQgYnBwOwogICAgQ09OVkVSVF9UWVBFUyBjb252ZXJ0ID0gTk9fQ09OVkVSU0lPTjsKCiAgICBXSU5FRDNEU1VSRkFDRV9ERVNDICB3aW5lZGVzYzsKCiAgICBUUkFDRSgiKCVwKSA6IFNvdXJjZSAoJXApICBSZWN0ICglcCkgRGVzdGluYXRpb24gKCVwKSBQb2ludCglcClcbiIsIFRoaXMsIHBTb3VyY2VTdXJmYWNlLCBwU291cmNlUmVjdCwgcERlc3RpbmF0aW9uU3VyZmFjZSwgcERlc3RQb2ludCk7CiAgICBtZW1zZXQoJndpbmVkZXNjLCAwLCBzaXplb2Yod2luZWRlc2MpKTsKICAgIHdpbmVkZXNjLldpZHRoICA9ICZzcmNTdXJmYWNlV2lkdGg7CiAgICB3aW5lZGVzYy5IZWlnaHQgPSAmc3JjU3VyZmFjZUhlaWdodDsKICAgIHdpbmVkZXNjLlBvb2wgICA9ICZzcmNQb29sOwogICAgd2luZWRlc2MuRm9ybWF0ID0gJnNyY0Zvcm1hdDsKCiAgICBJV2luZUQzRFN1cmZhY2VfR2V0RGVzYyhwU291cmNlU3VyZmFjZSwgJndpbmVkZXNjKTsKCiAgICB3aW5lZGVzYy5XaWR0aCAgPSAmZGVzdFN1cmZhY2VXaWR0aDsKICAgIHdpbmVkZXNjLkhlaWdodCA9ICZkZXN0U3VyZmFjZUhlaWdodDsKICAgIHdpbmVkZXNjLlBvb2wgICA9ICZkZXN0UG9vbDsKICAgIHdpbmVkZXNjLkZvcm1hdCA9ICZkZXN0Rm9ybWF0OwogICAgd2luZWRlc2MuU2l6ZSAgID0gJmRlc3RTaXplOwoKICAgIElXaW5lRDNEU3VyZmFjZV9HZXREZXNjKHBEZXN0aW5hdGlvblN1cmZhY2UsICZ3aW5lZGVzYyk7CgogICAgaWYoc3JjUG9vbCAhPSBXSU5FRDNEUE9PTF9TWVNURU1NRU0gIHx8IGRlc3RQb29sICE9IFdJTkVEM0RQT09MX0RFRkFVTFQpewogICAgICAgIFdBUk4oInNvdXJjZSAlcCBtdXN0IGJlIFNZU1RFTU1FTSBhbmQgZGVzdCAlcCBtdXN0IGJlIERFRkFVTFQsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iLCBwU291cmNlU3VyZmFjZSwgcERlc3RpbmF0aW9uU3VyZmFjZSk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogVGhpcyBjYWxsIGxvYWRzIHRoZSBvcGVuZ2wgc3VyZmFjZSBkaXJlY3RseSwgaW5zdGVhZCBvZiBjb3B5aW5nIHRoZSBzdXJmYWNlIHRvIHRoZQogICAgICogZGVzdGluYXRpb24ncyBzeXNtZW0gY29weS4gSWYgc3VyZmFjZSBjb252ZXJzaW9uIGlzIG5lZWRlZCwgdXNlIEJsdEZhc3QgaW5zdGVhZCB0bwogICAgICogY29weSBpbiBzeXNtZW0gYW5kIHVzZSByZWd1bGFyIHN1cmZhY2UgbG9hZGluZy4KICAgICAqLwogICAgZDNkZm10X2dldF9jb252KChJV2luZUQzRFN1cmZhY2VJbXBsICopIHBEZXN0aW5hdGlvblN1cmZhY2UsIEZBTFNFLCBUUlVFLAogICAgICAgICAgICAgICAgICAgICZkdW1teSwgJmR1bW15LCAmZHVtbXksICZjb252ZXJ0LCAmYnBwLCBGQUxTRSk7CiAgICBpZihjb252ZXJ0ICE9IE5PX0NPTlZFUlNJT04pIHsKICAgICAgICByZXR1cm4gSVdpbmVEM0RTdXJmYWNlX0JsdEZhc3QocERlc3RpbmF0aW9uU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBEZXN0UG9pbnQgID8gcERlc3RQb2ludC0+eCA6IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwRGVzdFBvaW50ICA/IHBEZXN0UG9pbnQtPnkgOiAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFNvdXJjZVN1cmZhY2UsIChSRUNUICopIHBTb3VyY2VSZWN0LCAwKTsKICAgIH0KCiAgICBpZiAoZGVzdEZvcm1hdCA9PSBXSU5FRDNERk1UX1VOS05PV04pIHsKICAgICAgICBUUkFDRSgiKCVwKSA6IENvbnZlcnRpbmcgZGVzdGluYXRpb24gc3VyZmFjZSBmcm9tIFdJTkVEM0RGTVRfVU5LTk9XTiB0byB0aGUgc291cmNlIGZvcm1hdFxuIiwgVGhpcyk7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldEZvcm1hdChwRGVzdGluYXRpb25TdXJmYWNlLCBzcmNGb3JtYXQpOwoKICAgICAgICAvKiBHZXQgdGhlIHVwZGF0ZSBzdXJmYWNlIGRlc2NyaXB0aW9uICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0dldERlc2MocERlc3RpbmF0aW9uU3VyZmFjZSwgJndpbmVkZXNjKTsKICAgIH0KCiAgICBBY3RpdmF0ZUNvbnRleHQoVGhpcywgVGhpcy0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKCiAgICBFTlRFUl9HTCgpOwoKICAgIGlmIChHTF9TVVBQT1JUKEFSQl9NVUxUSVRFWFRVUkUpKSB7CiAgICAgICAgR0xfRVhUQ0FMTChnbEFjdGl2ZVRleHR1cmVBUkIoR0xfVEVYVFVSRTBfQVJCKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQWN0aXZlVGV4dHVyZUFSQiIpOwogICAgfQoKICAgIC8qIE1ha2Ugc3VyZSB0aGUgc3VyZmFjZSBpcyBsb2FkZWQgYW5kIHVwIHRvIGRhdGUgKi8KICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKHBEZXN0aW5hdGlvblN1cmZhY2UpOwoKICAgIElXaW5lRDNEU3VyZmFjZV9HZXRHbERlc2MocERlc3RpbmF0aW9uU3VyZmFjZSwgJmdsRGVzY3JpcHRpb24pOwoKICAgIC8qIHRoaXMgbmVlZHMgdG8gYmUgZG9uZSBpbiBsaW5lcyBpZiB0aGUgc291cmNlUmVjdCAhPSB0aGUgc291cmNlV2lkdGggKi8KICAgIHNyY1dpZHRoICAgPSBwU291cmNlUmVjdCA/IHBTb3VyY2VSZWN0LT5yaWdodCAtIHBTb3VyY2VSZWN0LT5sZWZ0ICAgOiBzcmNTdXJmYWNlV2lkdGg7CiAgICBzcmNIZWlnaHQgID0gcFNvdXJjZVJlY3QgPyBwU291cmNlUmVjdC0+Ym90dG9tIC0gcFNvdXJjZVJlY3QtPnRvcCAgIDogc3JjU3VyZmFjZUhlaWdodDsKICAgIHNyY0xlZnQgICAgPSBwU291cmNlUmVjdCA/IHBTb3VyY2VSZWN0LT5sZWZ0IDogMDsKICAgIGRlc3RMZWZ0ICAgPSBwRGVzdFBvaW50ICA/IHBEZXN0UG9pbnQtPnggOiAwOwogICAgZGVzdFRvcCAgICA9IHBEZXN0UG9pbnQgID8gcERlc3RQb2ludC0+eSA6IDA7CgoKICAgIC8qIFRoaXMgZnVuY3Rpb24gZG9lc24ndCBzdXBwb3J0IGNvbXByZXNzZWQgdGV4dHVyZXMKICAgIHRoZSBwaXRjaCBpcyBqdXN0IGJ5dGVzUGVyUGl4ZWwgKiB3aWR0aCAqLwogICAgaWYoc3JjV2lkdGggIT0gc3JjU3VyZmFjZVdpZHRoICB8fCBzcmNMZWZ0ICl7CiAgICAgICAgcm93b2Zmc2V0ID0gc3JjU3VyZmFjZVdpZHRoICogcFNyY1N1cmZhY2UtPmJ5dGVzUGVyUGl4ZWw7CiAgICAgICAgb2Zmc2V0ICAgKz0gc3JjTGVmdCAqIHBTcmNTdXJmYWNlLT5ieXRlc1BlclBpeGVsOwogICAgICAgIC8qIFRPRE86IGRvIHdlIGV2ZXIgZ2V0IDNicHA/LCB3b3VsZCBhIHNoaWZ0IGFuZCBhbiBhZGQgYmUgcXVpY2tlciB0aGFuIGEgbXVsICh3ZWxsIG1heWJlIGEgY3ljbGUgb3IgdHdvKSAqLwogICAgfQogICAgLyogVE9ETyBEWFQgZm9ybWF0cyAqLwoKICAgIGlmKHBTb3VyY2VSZWN0ICE9IE5VTEwgJiYgcFNvdXJjZVJlY3QtPnRvcCAhPSAwKXsKICAgICAgIG9mZnNldCArPSAgcFNvdXJjZVJlY3QtPnRvcCAqIHNyY1N1cmZhY2VXaWR0aCAqIHBTcmNTdXJmYWNlLT5ieXRlc1BlclBpeGVsOwogICAgfQogICAgVFJBQ0UoIiglcCkgZ2xUZXhTdWJJbWFnZTJELCBMZXZlbCAlZCwgbGVmdCAlZCwgdG9wICVkLCB3aWR0aCAlZCwgaGVpZ2h0ICVkICwgZnRtICVkLCB0eXBlICVkLCBtZW1vcnkgJXBcbiIKICAgICxUaGlzCiAgICAsZ2xEZXNjcmlwdGlvbi0+bGV2ZWwKICAgICxkZXN0TGVmdAogICAgLGRlc3RUb3AKICAgICxzcmNXaWR0aAogICAgLHNyY0hlaWdodAogICAgLGdsRGVzY3JpcHRpb24tPmdsRm9ybWF0CiAgICAsZ2xEZXNjcmlwdGlvbi0+Z2xUeXBlCiAgICAsSVdpbmVEM0RTdXJmYWNlX0dldERhdGEocFNvdXJjZVN1cmZhY2UpCiAgICApOwoKICAgIC8qIFNhbml0eSBjaGVjayAqLwogICAgaWYgKElXaW5lRDNEU3VyZmFjZV9HZXREYXRhKHBTb3VyY2VTdXJmYWNlKSA9PSBOVUxMKSB7CgogICAgICAgIC8qIG5lZWQgdG8gbG9jayB0aGUgc3VyZmFjZSB0byBnZXQgdGhlIGRhdGEgKi8KICAgICAgICBGSVhNRSgiU3VyZmFjZXMgaGFzIG5vIGFsbG9jYXRlZCBtZW1vcnksIGJ1dCBzaG91bGQgYmUgYW4gaW4gbWVtb3J5IG9ubHkgc3VyZmFjZVxuIik7CiAgICB9CgogICAgLyogVE9ETzogQ3ViZSBhbmQgdm9sdW1lIHN1cHBvcnQgKi8KICAgIGlmKHJvd29mZnNldCAhPSAwKXsKICAgICAgICAvKiBub3QgYSB3aG9sZSByb3cgc28gd2UgaGF2ZSB0byBkbyBpdCBhIGxpbmUgYXQgYSB0aW1lICovCiAgICAgICAgaW50IGo7CgogICAgICAgIC8qIGhvcGVmdWxseSB1c2luZyBwb2ludGVyIGFkZHRpb24gd2lsbCBiZSBxdWlja2VyIHRoYW4gdXNpbmcgYSBwb2ludCArIGogKiByb3dvZmZzZXQgKi8KICAgICAgICBjb25zdCB1bnNpZ25lZCBjaGFyKiBkYXRhID0oKGNvbnN0IHVuc2lnbmVkIGNoYXIgKilJV2luZUQzRFN1cmZhY2VfR2V0RGF0YShwU291cmNlU3VyZmFjZSkpICsgb2Zmc2V0OwoKICAgICAgICBmb3IoaiA9IGRlc3RUb3AgOyBqIDwgKHNyY0hlaWdodCArIGRlc3RUb3ApIDsgaisrKXsKCiAgICAgICAgICAgICAgICBnbFRleFN1YkltYWdlMkQoZ2xEZXNjcmlwdGlvbi0+dGFyZ2V0CiAgICAgICAgICAgICAgICAgICAgLGdsRGVzY3JpcHRpb24tPmxldmVsCiAgICAgICAgICAgICAgICAgICAgLGRlc3RMZWZ0CiAgICAgICAgICAgICAgICAgICAgLGoKICAgICAgICAgICAgICAgICAgICAsc3JjV2lkdGgKICAgICAgICAgICAgICAgICAgICAsMQogICAgICAgICAgICAgICAgICAgICxnbERlc2NyaXB0aW9uLT5nbEZvcm1hdAogICAgICAgICAgICAgICAgICAgICxnbERlc2NyaXB0aW9uLT5nbFR5cGUKICAgICAgICAgICAgICAgICAgICAsZGF0YSAvKiBjb3VsZCBiZSBxdWlja2VyIHVzaW5nICovCiAgICAgICAgICAgICAgICApOwogICAgICAgICAgICBkYXRhICs9IHJvd29mZnNldDsKICAgICAgICB9CgogICAgfSBlbHNlIHsgLyogRnVsbCB3aWR0aCwgc28ganVzdCB3cml0ZSBvdXQgdGhlIHdob2xlIHRleHR1cmUgKi8KCiAgICAgICAgaWYgKFdJTkVEM0RGTVRfRFhUMSA9PSBkZXN0Rm9ybWF0IHx8CiAgICAgICAgICAgIFdJTkVEM0RGTVRfRFhUMiA9PSBkZXN0Rm9ybWF0IHx8CiAgICAgICAgICAgIFdJTkVEM0RGTVRfRFhUMyA9PSBkZXN0Rm9ybWF0IHx8CiAgICAgICAgICAgIFdJTkVEM0RGTVRfRFhUNCA9PSBkZXN0Rm9ybWF0IHx8CiAgICAgICAgICAgIFdJTkVEM0RGTVRfRFhUNSA9PSBkZXN0Rm9ybWF0KSB7CiAgICAgICAgICAgIGlmIChHTF9TVVBQT1JUKEVYVF9URVhUVVJFX0NPTVBSRVNTSU9OX1MzVEMpKSB7CiAgICAgICAgICAgICAgICBpZiAoZGVzdFN1cmZhY2VIZWlnaHQgIT0gc3JjSGVpZ2h0IHx8IGRlc3RTdXJmYWNlV2lkdGggIT0gc3JjV2lkdGgpIHsKICAgICAgICAgICAgICAgICAgICAvKiBGSVhNRTogVGhlIGVhc3kgd2F5IHRvIGRvIHRoaXMgaXMgdG8gbG9jayB0aGUgZGVzdGluYXRpb24sIGFuZCBjb3B5IHRoZSBiaXRzIGFjcm9zcyAqLwogICAgICAgICAgICAgICAgICAgIEZJWE1FKCJVcGRhdGluZyBwYXJ0IG9mIGEgY29tcHJlc3NlZCB0ZXh0dXJlIGlzIG5vdCBzdXBwb3J0ZWQgYXQgdGhlIG1vbWVudFxuIik7CiAgICAgICAgICAgICAgICB9IGlmIChkZXN0Rm9ybWF0ICE9IHNyY0Zvcm1hdCkgewogICAgICAgICAgICAgICAgICAgIEZJWE1FKCJVcGRhdGluZyBtaXhlZCBmb3JtYXQgY29tcHJlc3NlZCB0ZXh0dXJlIGlzIG5vdCBjdXJyZXRseSBzdXBwb3J0XG4iKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbENvbXByZXNzZWRUZXhJbWFnZTJEQVJCKShnbERlc2NyaXB0aW9uLT50YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2xEZXNjcmlwdGlvbi0+bGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2xEZXNjcmlwdGlvbi0+Z2xGb3JtYXRJbnRlcm5hbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcmNXaWR0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcmNIZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXN0U2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfR2V0RGF0YShwU291cmNlU3VyZmFjZSkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgRklYTUUoIkF0dGVtcHRpbmcgdG8gdXBkYXRlIGEgRFhUIGNvbXByZXNzZWQgdGV4dHVyZSB3aXRob3V0IGhhcmR3YXJlIHN1cHBvcnRcbiIpOwogICAgICAgICAgICB9CgoKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBnbFRleFN1YkltYWdlMkQoZ2xEZXNjcmlwdGlvbi0+dGFyZ2V0CiAgICAgICAgICAgICAgICAgICAgLGdsRGVzY3JpcHRpb24tPmxldmVsCiAgICAgICAgICAgICAgICAgICAgLGRlc3RMZWZ0CiAgICAgICAgICAgICAgICAgICAgLGRlc3RUb3AKICAgICAgICAgICAgICAgICAgICAsc3JjV2lkdGgKICAgICAgICAgICAgICAgICAgICAsc3JjSGVpZ2h0CiAgICAgICAgICAgICAgICAgICAgLGdsRGVzY3JpcHRpb24tPmdsRm9ybWF0CiAgICAgICAgICAgICAgICAgICAgLGdsRGVzY3JpcHRpb24tPmdsVHlwZQogICAgICAgICAgICAgICAgICAgICxJV2luZUQzRFN1cmZhY2VfR2V0RGF0YShwU291cmNlU3VyZmFjZSkKICAgICAgICAgICAgICAgICk7CiAgICAgICAgfQogICAgIH0KICAgIGNoZWNrR0xjYWxsKCJnbFRleFN1YkltYWdlMkQiKTsKCiAgICBMRUFWRV9HTCgpOwoKICAgIElXaW5lRDNEU3VyZmFjZV9Nb2RpZnlMb2NhdGlvbihwRGVzdGluYXRpb25TdXJmYWNlLCBTRkxBR19JTlRFWFRVUkUsIFRSVUUpOwogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1NBTVBMRVIoMCkpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdSZWN0UGF0Y2goSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIEhhbmRsZSwgQ09OU1QgZmxvYXQqIHBOdW1TZWdzLCBDT05TVCBXSU5FRDNEUkVDVFBBVENIX0lORk8qIHBSZWN0UGF0Y2hJbmZvKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBzdHJ1Y3QgV2luZUQzRFJlY3RQYXRjaCAqcGF0Y2g7CiAgICB1bnNpZ25lZCBpbnQgaTsKICAgIHN0cnVjdCBsaXN0ICplOwogICAgQk9PTCBmb3VuZDsKICAgIFRSQUNFKCIoJXApIEhhbmRsZSglZCkgbm9TZWdzKCVwKSByZWN0cGF0Y2goJXApXG4iLCBUaGlzLCBIYW5kbGUsIHBOdW1TZWdzLCBwUmVjdFBhdGNoSW5mbyk7CgogICAgaWYoIShIYW5kbGUgfHwgcFJlY3RQYXRjaEluZm8pKSB7CiAgICAgICAgLyogVE9ETzogV3JpdGUgYSB0ZXN0IGZvciB0aGUgcmV0dXJuIHZhbHVlLCB0aHVzIHRoZSBGSVhNRSAqLwogICAgICAgIEZJWE1FKCJCb3RoIEhhbmRsZSBhbmQgcFJlY3RQYXRjaEluZm8gYXJlIE5VTExcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmKEhhbmRsZSkgewogICAgICAgIGkgPSBQQVRDSE1BUF9IQVNIRlVOQyhIYW5kbGUpOwogICAgICAgIGZvdW5kID0gRkFMU0U7CiAgICAgICAgTElTVF9GT1JfRUFDSChlLCAmVGhpcy0+cGF0Y2hlc1tpXSkgewogICAgICAgICAgICBwYXRjaCA9IExJU1RfRU5UUlkoZSwgc3RydWN0IFdpbmVEM0RSZWN0UGF0Y2gsIGVudHJ5KTsKICAgICAgICAgICAgaWYocGF0Y2gtPkhhbmRsZSA9PSBIYW5kbGUpIHsKICAgICAgICAgICAgICAgIGZvdW5kID0gVFJVRTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZighZm91bmQpIHsKICAgICAgICAgICAgVFJBQ0UoIlBhdGNoIGRvZXMgbm90IGV4aXN0LiBDcmVhdGluZyBhIG5ldyBvbmVcbiIpOwogICAgICAgICAgICBwYXRjaCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoKnBhdGNoKSk7CiAgICAgICAgICAgIHBhdGNoLT5IYW5kbGUgPSBIYW5kbGU7CiAgICAgICAgICAgIGxpc3RfYWRkX2hlYWQoJlRoaXMtPnBhdGNoZXNbaV0sICZwYXRjaC0+ZW50cnkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFRSQUNFKCJGb3VuZCBleGlzdGluZyBwYXRjaCAlcFxuIiwgcGF0Y2gpOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgLyogU2luY2Ugb3BlbmdsIGRvZXMgbm90IGxvYWQgdGVzc2VsYXRlZCB2ZXJ0ZXggYXR0cmlidXRlcyBpbnRvIG51bWJlcmVkIHZlcnRleAogICAgICAgICAqIGF0dHJpYnV0ZXMgd2UgaGF2ZSB0byB0ZXNzZWxhdGUsIHJlYWQgYmFjaywgYW5kIGRyYXcuIFRoaXMgbmVlZHMgYSBwYXRjaAogICAgICAgICAqIG1hbmFnZW1lbnQgc3RydWN0dXJlIGluc3RhbmNlLiBDcmVhdGUgb25lLgogICAgICAgICAqCiAgICAgICAgICogQSBwb3NzaWJsZSBpbXByb3ZlbWVudCBpcyB0byBjaGVjayBpZiBhIHZlcnRleCBzaGFkZXIgaXMgdXNlZCwgYW5kIGlmIG5vdCBkaXJlY3RseQogICAgICAgICAqIGRyYXcgdGhlIHBhdGNoLgogICAgICAgICAqLwogICAgICAgIEZJWE1FKCJEcmF3aW5nIGFuIHVuY2FjaGVkIHBhdGNoLiBUaGlzIGlzIHNsb3dcbiIpOwogICAgICAgIHBhdGNoID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZigqcGF0Y2gpKTsKICAgIH0KCiAgICBpZihwTnVtU2Vnc1swXSAhPSBwYXRjaC0+bnVtU2Vnc1swXSB8fCBwTnVtU2Vnc1sxXSAhPSBwYXRjaC0+bnVtU2Vnc1sxXSB8fAogICAgICAgcE51bVNlZ3NbMl0gIT0gcGF0Y2gtPm51bVNlZ3NbMl0gfHwgcE51bVNlZ3NbM10gIT0gcGF0Y2gtPm51bVNlZ3NbM10gfHwKICAgICAgIChwUmVjdFBhdGNoSW5mbyAmJiBtZW1jbXAocFJlY3RQYXRjaEluZm8sICZwYXRjaC0+UmVjdFBhdGNoSW5mbywgc2l6ZW9mKCpwUmVjdFBhdGNoSW5mbykpICE9IDApICkgewogICAgICAgIEhSRVNVTFQgaHI7CiAgICAgICAgVFJBQ0UoIlRlc3NlbGF0aW9uIGRlbnNpdHkgb3IgcGF0Y2ggaW5mbyBjaGFuZ2VkLCByZXRlc3NlbGF0aW5nXG4iKTsKCiAgICAgICAgaWYocFJlY3RQYXRjaEluZm8pIHsKICAgICAgICAgICAgbWVtY3B5KCZwYXRjaC0+UmVjdFBhdGNoSW5mbywgcFJlY3RQYXRjaEluZm8sIHNpemVvZigqcFJlY3RQYXRjaEluZm8pKTsKICAgICAgICB9CiAgICAgICAgcGF0Y2gtPm51bVNlZ3NbMF0gPSBwTnVtU2Vnc1swXTsKICAgICAgICBwYXRjaC0+bnVtU2Vnc1sxXSA9IHBOdW1TZWdzWzFdOwogICAgICAgIHBhdGNoLT5udW1TZWdzWzJdID0gcE51bVNlZ3NbMl07CiAgICAgICAgcGF0Y2gtPm51bVNlZ3NbM10gPSBwTnVtU2Vnc1szXTsKCiAgICAgICAgaHIgPSB0ZXNzZWxhdGVfcmVjdHBhdGNoKFRoaXMsIHBhdGNoKTsKICAgICAgICBpZihGQUlMRUQoaHIpKSB7CiAgICAgICAgICAgIFdBUk4oIlBhdGNoIHRlc3NlbGF0aW9uIGZhaWxlZFxuIik7CgogICAgICAgICAgICAvKiBEbyBub3QgcmVsZWFzZSB0aGUgaGFuZGxlIHRvIHN0b3JlIHRoZSBwYXJhbXMgb2YgdGhlIHBhdGNoICovCiAgICAgICAgICAgIGlmKCFIYW5kbGUpIHsKICAgICAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBhdGNoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gaHI7CiAgICAgICAgfQogICAgfQoKICAgIFRoaXMtPmN1cnJlbnRQYXRjaCA9IHBhdGNoOwogICAgSVdpbmVEM0REZXZpY2VfRHJhd1ByaW1pdGl2ZVN0cmlkZWQoaWZhY2UsIFdJTkVEM0RQVF9UUklBTkdMRUxJU1QsIHBhdGNoLT5udW1TZWdzWzBdICogcGF0Y2gtPm51bVNlZ3NbMV0gKiAyLCAmcGF0Y2gtPnN0cmlkZWQpOwogICAgVGhpcy0+Y3VycmVudFBhdGNoID0gTlVMTDsKCiAgICAvKiBEZXN0cm95IHVuY2FjaGVkIHBhdGNoZXMgKi8KICAgIGlmKCFIYW5kbGUpIHsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYXRjaC0+bWVtKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYXRjaCk7CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyogaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9saWJyYXJ5L2RlZmF1bHQuYXNwP3VybD0vbGlicmFyeS9lbi11cy9kaXJlY3R4OV9jL2RpcmVjdHgvZ3JhcGhpY3MvcmVmZXJlbmNlL2QzZC9pbnRlcmZhY2VzL2lkaXJlY3QzZGRldmljZTkvRHJhd1RyaVBhdGNoLmFzcCAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdUcmlQYXRjaChJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgSGFuZGxlLCBDT05TVCBmbG9hdCogcE51bVNlZ3MsIENPTlNUIFdJTkVEM0RUUklQQVRDSF9JTkZPKiBwVHJpUGF0Y2hJbmZvKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSBIYW5kbGUoJWQpIG5vU2VncyglcCkgdHJpcGF0Y2goJXApXG4iLCBUaGlzLCBIYW5kbGUsIHBOdW1TZWdzLCBwVHJpUGF0Y2hJbmZvKTsKICAgIEZJWE1FKCIoJXApIDogU3R1YlxuIiwgVGhpcyk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9EZWxldGVQYXRjaChJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgSGFuZGxlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpbnQgaTsKICAgIHN0cnVjdCBXaW5lRDNEUmVjdFBhdGNoICpwYXRjaDsKICAgIHN0cnVjdCBsaXN0ICplOwogICAgVFJBQ0UoIiglcCkgSGFuZGxlKCVkKVxuIiwgVGhpcywgSGFuZGxlKTsKCiAgICBpID0gUEFUQ0hNQVBfSEFTSEZVTkMoSGFuZGxlKTsKICAgIExJU1RfRk9SX0VBQ0goZSwgJlRoaXMtPnBhdGNoZXNbaV0pIHsKICAgICAgICBwYXRjaCA9IExJU1RfRU5UUlkoZSwgc3RydWN0IFdpbmVEM0RSZWN0UGF0Y2gsIGVudHJ5KTsKICAgICAgICBpZihwYXRjaC0+SGFuZGxlID09IEhhbmRsZSkgewogICAgICAgICAgICBUUkFDRSgiRGVsZXRpbmcgcGF0Y2ggJXBcbiIsIHBhdGNoKTsKICAgICAgICAgICAgbGlzdF9yZW1vdmUoJnBhdGNoLT5lbnRyeSk7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBhdGNoLT5tZW0pOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYXRjaCk7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBUT0RPOiBXcml0ZSBhIHRlc3QgZm9yIHRoZSByZXR1cm4gdmFsdWUgKi8KICAgIEZJWE1FKCJBdHRlbXB0IHRvIGRlc3Ryb3kgbm9uZXhpc3RlbnQgcGF0Y2hcbiIpOwogICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7Cn0KCnN0YXRpYyBJV2luZUQzRFN3YXBDaGFpbiAqZ2V0X3N3YXBjaGFpbihJV2luZUQzRFN1cmZhY2UgKnRhcmdldCkgewogICAgSFJFU1VMVCBocjsKICAgIElXaW5lRDNEU3dhcENoYWluICpzd2FwY2hhaW47CgogICAgaHIgPSBJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKHRhcmdldCwgJklJRF9JV2luZUQzRFN3YXBDaGFpbiwgKHZvaWQgKiopJnN3YXBjaGFpbik7CiAgICBpZiAoU1VDQ0VFREVEKGhyKSkgewogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElVbmtub3duICopc3dhcGNoYWluKTsKICAgICAgICByZXR1cm4gc3dhcGNoYWluOwogICAgfQoKICAgIHJldHVybiBOVUxMOwp9CgpzdGF0aWMgdm9pZCBiaW5kX2ZibyhJV2luZUQzRERldmljZSAqaWZhY2UsIEdMZW51bSB0YXJnZXQsIEdMdWludCAqZmJvKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgaWYgKCEqZmJvKSB7CiAgICAgICAgR0xfRVhUQ0FMTChnbEdlbkZyYW1lYnVmZmVyc0VYVCgxLCBmYm8pKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZW5GcmFtZWJ1ZmZlcnNFWFQoKSIpOwogICAgfQogICAgR0xfRVhUQ0FMTChnbEJpbmRGcmFtZWJ1ZmZlckVYVCh0YXJnZXQsICpmYm8pKTsKICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRGcmFtZWJ1ZmZlcigpIik7Cn0KCnN0YXRpYyB2b2lkIGF0dGFjaF9zdXJmYWNlX2ZibyhJV2luZUQzRERldmljZUltcGwgKlRoaXMsIEdMZW51bSBmYm9fdGFyZ2V0LCBEV09SRCBpZHgsIElXaW5lRDNEU3VyZmFjZSAqc3VyZmFjZSkgewogICAgY29uc3QgSVdpbmVEM0RTdXJmYWNlSW1wbCAqc3VyZmFjZV9pbXBsID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilzdXJmYWNlOwogICAgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKnRleHR1cmVfaW1wbDsKICAgIEdMZW51bSB0ZXh0dGFyZ2V0LCB0YXJnZXQ7CiAgICBHTGludCBvbGRfYmluZGluZzsKCiAgICB0ZXh0dGFyZ2V0ID0gc3VyZmFjZV9pbXBsLT5nbERlc2NyaXB0aW9uLnRhcmdldDsKICAgIGlmKHRleHR0YXJnZXQgPT0gR0xfVEVYVFVSRV8yRCkgewogICAgICAgIHRhcmdldCA9IEdMX1RFWFRVUkVfMkQ7CiAgICAgICAgZ2xHZXRJbnRlZ2VydihHTF9URVhUVVJFX0JJTkRJTkdfMkQsICZvbGRfYmluZGluZyk7CiAgICB9IGVsc2UgaWYodGV4dHRhcmdldCA9PSBHTF9URVhUVVJFX1JFQ1RBTkdMRV9BUkIpIHsKICAgICAgICB0YXJnZXQgPSBHTF9URVhUVVJFX1JFQ1RBTkdMRV9BUkI7CiAgICAgICAgZ2xHZXRJbnRlZ2VydihHTF9URVhUVVJFX0JJTkRJTkdfUkVDVEFOR0xFX0FSQiwgJm9sZF9iaW5kaW5nKTsKICAgIH0gZWxzZSB7CiAgICAgICAgdGFyZ2V0ID0gR0xfVEVYVFVSRV9DVUJFX01BUF9BUkI7CiAgICAgICAgZ2xHZXRJbnRlZ2VydihHTF9URVhUVVJFX0JJTkRJTkdfQ1VCRV9NQVBfQVJCLCAmb2xkX2JpbmRpbmcpOwogICAgfQoKICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKHN1cmZhY2UpOwoKICAgIGdsVGV4UGFyYW1ldGVyaSh0YXJnZXQsIEdMX1RFWFRVUkVfTUlOX0ZJTFRFUiwgR0xfTkVBUkVTVCk7CiAgICBnbFRleFBhcmFtZXRlcmkodGFyZ2V0LCBHTF9URVhUVVJFX01BR19GSUxURVIsIEdMX05FQVJFU1QpOwogICAgZ2xCaW5kVGV4dHVyZSh0YXJnZXQsIG9sZF9iaW5kaW5nKTsKCiAgICAvKiBVcGRhdGUgYmFzZSB0ZXh0dXJlIHN0YXRlcyBhcnJheSAqLwogICAgaWYgKFNVQ0NFRURFRChJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKHN1cmZhY2UsICZJSURfSVdpbmVEM0RCYXNlVGV4dHVyZSwgKHZvaWQgKiopJnRleHR1cmVfaW1wbCkpKSB7CiAgICAgICAgdGV4dHVyZV9pbXBsLT5iYXNlVGV4dHVyZS5zdGF0ZXNbV0lORUQzRFRFWFNUQV9NSU5GSUxURVJdID0gV0lORUQzRFRFWEZfUE9JTlQ7CiAgICAgICAgdGV4dHVyZV9pbXBsLT5iYXNlVGV4dHVyZS5zdGF0ZXNbV0lORUQzRFRFWFNUQV9NQUdGSUxURVJdID0gV0lORUQzRFRFWEZfUE9JTlQ7CiAgICAgICAgaWYgKHRleHR1cmVfaW1wbC0+YmFzZVRleHR1cmUuYmluZENvdW50KSB7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TQU1QTEVSKHRleHR1cmVfaW1wbC0+YmFzZVRleHR1cmUuc2FtcGxlcikpOwogICAgICAgIH0KCiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9SZWxlYXNlKChJV2luZUQzREJhc2VUZXh0dXJlICopdGV4dHVyZV9pbXBsKTsKICAgIH0KCiAgICBHTF9FWFRDQUxMKGdsRnJhbWVidWZmZXJUZXh0dXJlMkRFWFQoZmJvX3RhcmdldCwgR0xfQ09MT1JfQVRUQUNITUVOVDBfRVhUICsgaWR4LCB0ZXh0dGFyZ2V0LAogICAgICAgICAgICBzdXJmYWNlX2ltcGwtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUsIHN1cmZhY2VfaW1wbC0+Z2xEZXNjcmlwdGlvbi5sZXZlbCkpOwoKICAgIGNoZWNrR0xjYWxsKCJhdHRhY2hfc3VyZmFjZV9mYm8iKTsKfQoKc3RhdGljIHZvaWQgY29sb3JfZmlsbF9mYm8oSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFN1cmZhY2UgKnN1cmZhY2UsIENPTlNUIFdJTkVEM0RSRUNUICpyZWN0LCBXSU5FRDNEQ09MT1IgY29sb3IpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcGNoYWluOwoKICAgIHN3YXBjaGFpbiA9IGdldF9zd2FwY2hhaW4oc3VyZmFjZSk7CiAgICBpZiAoc3dhcGNoYWluKSB7CiAgICAgICAgR0xlbnVtIGJ1ZmZlcjsKCiAgICAgICAgVFJBQ0UoIlN1cmZhY2UgJXAgaXMgb25zY3JlZW5cbiIsIHN1cmZhY2UpOwoKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEZyYW1lYnVmZmVyRVhUKEdMX0ZSQU1FQlVGRkVSX0VYVCwgMCkpOwogICAgICAgIGJ1ZmZlciA9IHN1cmZhY2VfZ2V0X2dsX2J1ZmZlcihzdXJmYWNlLCBzd2FwY2hhaW4pOwogICAgICAgIGdsRHJhd0J1ZmZlcihidWZmZXIpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoKSIpOwogICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgiU3VyZmFjZSAlcCBpcyBvZmZzY3JlZW5cbiIsIHN1cmZhY2UpOwogICAgICAgIGJpbmRfZmJvKGlmYWNlLCBHTF9GUkFNRUJVRkZFUl9FWFQsICZUaGlzLT5kc3RfZmJvKTsKICAgICAgICBhdHRhY2hfc3VyZmFjZV9mYm8oVGhpcywgR0xfRlJBTUVCVUZGRVJfRVhULCAwLCBzdXJmYWNlKTsKICAgIH0KCiAgICBpZiAocmVjdCkgewogICAgICAgIGdsRW5hYmxlKEdMX1NDSVNTT1JfVEVTVCk7CiAgICAgICAgaWYoIXN3YXBjaGFpbikgewogICAgICAgICAgICBnbFNjaXNzb3IocmVjdC0+eDEsIHJlY3QtPnkxLCByZWN0LT54MiAtIHJlY3QtPngxLCByZWN0LT55MiAtIHJlY3QtPnkxKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBnbFNjaXNzb3IocmVjdC0+eDEsICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKXN1cmZhY2UpLT5jdXJyZW50RGVzYy5IZWlnaHQgLSByZWN0LT55MiwKICAgICAgICAgICAgICAgICAgICByZWN0LT54MiAtIHJlY3QtPngxLCByZWN0LT55MiAtIHJlY3QtPnkxKTsKICAgICAgICB9CiAgICAgICAgY2hlY2tHTGNhbGwoImdsU2Npc3NvciIpOwogICAgfSBlbHNlIHsKICAgICAgICBnbERpc2FibGUoR0xfU0NJU1NPUl9URVNUKTsKICAgIH0KICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX1NDSVNTT1JURVNURU5BQkxFKSk7CgogICAgZ2xDb2xvck1hc2soR0xfVFJVRSwgR0xfVFJVRSwgR0xfVFJVRSwgR0xfVFJVRSk7CiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19DT0xPUldSSVRFRU5BQkxFKSk7CgogICAgZ2xDbGVhckNvbG9yKEQzRENPTE9SX1IoY29sb3IpLCBEM0RDT0xPUl9HKGNvbG9yKSwgRDNEQ09MT1JfQihjb2xvciksIEQzRENPTE9SX0EoY29sb3IpKTsKICAgIGdsQ2xlYXIoR0xfQ09MT1JfQlVGRkVSX0JJVCk7CiAgICBjaGVja0dMY2FsbCgiZ2xDbGVhciIpOwoKICAgIGlmIChUaGlzLT5yZW5kZXJfb2Zmc2NyZWVuKSB7CiAgICAgICAgYmluZF9mYm8oaWZhY2UsIEdMX0ZSQU1FQlVGRkVSX0VYVCwgJlRoaXMtPmZibyk7CiAgICB9IGVsc2UgewogICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kRnJhbWVidWZmZXJFWFQoR0xfRlJBTUVCVUZGRVJfRVhULCAwKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZEZyYW1lYnVmZmVyKCkiKTsKICAgIH0KCiAgICBpZiAoc3dhcGNoYWluICYmIHN1cmZhY2UgPT0gKChJV2luZUQzRFN3YXBDaGFpbkltcGwgKilzd2FwY2hhaW4pLT5mcm9udEJ1ZmZlcgogICAgICAgICAgICAmJiAoKElXaW5lRDNEU3dhcENoYWluSW1wbCAqKXN3YXBjaGFpbiktPmJhY2tCdWZmZXIpIHsKICAgICAgICBnbERyYXdCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcigpIik7CiAgICB9Cn0KCnN0YXRpYyBpbmxpbmUgRFdPUkQgYXJnYl90b19mbXQoRFdPUkQgY29sb3IsIFdJTkVEM0RGT1JNQVQgZGVzdGZtdCkgewogICAgdW5zaWduZWQgaW50IHIsIGcsIGIsIGE7CiAgICBEV09SRCByZXQ7CgogICAgaWYoZGVzdGZtdCA9PSBXSU5FRDNERk1UX0E4UjhHOEI4IHx8IGRlc3RmbXQgPT0gV0lORUQzREZNVF9YOFI4RzhCOCB8fAogICAgICAgZGVzdGZtdCA9PSBXSU5FRDNERk1UX1I4RzhCOCkKICAgICAgICByZXR1cm4gY29sb3I7CgogICAgVFJBQ0UoIkNvbnZlcnRpbmcgY29sb3IgJTA4eCB0byBmb3JtYXQgJXNcbiIsIGNvbG9yLCBkZWJ1Z19kM2Rmb3JtYXQoZGVzdGZtdCkpOwoKICAgIGEgPSAoY29sb3IgJiAweGZmMDAwMDAwKSA+PiAyNDsKICAgIHIgPSAoY29sb3IgJiAweDAwZmYwMDAwKSA+PiAxNjsKICAgIGcgPSAoY29sb3IgJiAweDAwMDBmZjAwKSA+PiAgODsKICAgIGIgPSAoY29sb3IgJiAweDAwMDAwMGZmKSA+PiAgMDsKCiAgICBzd2l0Y2goZGVzdGZtdCkKICAgIHsKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjVHNkI1OgogICAgICAgICAgICBpZihyID09IDB4ZmYgJiYgZyA9PSAweGZmICYmIGIgPT0gMHhmZikgcmV0dXJuIDB4ZmZmZjsKICAgICAgICAgICAgciA9IChyICogMzIpIC8gMjU2OwogICAgICAgICAgICBnID0gKGcgKiA2NCkgLyAyNTY7CiAgICAgICAgICAgIGIgPSAoYiAqIDMyKSAvIDI1NjsKICAgICAgICAgICAgcmV0ICA9IHIgPDwgMTE7CiAgICAgICAgICAgIHJldCB8PSBnIDw8IDU7CiAgICAgICAgICAgIHJldCB8PSBiOwogICAgICAgICAgICBUUkFDRSgiUmV0dXJuaW5nICUwOHhcbiIsIHJldCk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9YMVI1RzVCNToKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQTFSNUc1QjU6CiAgICAgICAgICAgIGEgPSAoYSAqICAyKSAvIDI1NjsKICAgICAgICAgICAgciA9IChyICogMzIpIC8gMjU2OwogICAgICAgICAgICBnID0gKGcgKiAzMikgLyAyNTY7CiAgICAgICAgICAgIGIgPSAoYiAqIDMyKSAvIDI1NjsKICAgICAgICAgICAgcmV0ICA9IGEgPDwgMTU7CiAgICAgICAgICAgIHJldCB8PSByIDw8IDEwOwogICAgICAgICAgICByZXQgfD0gZyA8PCAgNTsKICAgICAgICAgICAgcmV0IHw9IGIgPDwgIDA7CiAgICAgICAgICAgIFRSQUNFKCJSZXR1cm5pbmcgJTA4eFxuIiwgcmV0KTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX0E4OgogICAgICAgICAgICBUUkFDRSgiUmV0dXJuaW5nICUwOHhcbiIsIGEpOwogICAgICAgICAgICByZXR1cm4gYTsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1g0UjRHNEI0OgogICAgICAgIGNhc2UgV0lORUQzREZNVF9BNFI0RzRCNDoKICAgICAgICAgICAgYSA9IChhICogMTYpIC8gMjU2OwogICAgICAgICAgICByID0gKHIgKiAxNikgLyAyNTY7CiAgICAgICAgICAgIGcgPSAoZyAqIDE2KSAvIDI1NjsKICAgICAgICAgICAgYiA9IChiICogMTYpIC8gMjU2OwogICAgICAgICAgICByZXQgID0gYSA8PCAxMjsKICAgICAgICAgICAgcmV0IHw9IHIgPDwgIDg7CiAgICAgICAgICAgIHJldCB8PSBnIDw8ICA0OwogICAgICAgICAgICByZXQgfD0gYiA8PCAgMDsKICAgICAgICAgICAgVFJBQ0UoIlJldHVybmluZyAlMDh4XG4iLCByZXQpOwogICAgICAgICAgICByZXR1cm4gcmV0OwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjNHM0IyOgogICAgICAgICAgICByID0gKHIgKiA4KSAvIDI1NjsKICAgICAgICAgICAgZyA9IChnICogOCkgLyAyNTY7CiAgICAgICAgICAgIGIgPSAoYiAqIDQpIC8gMjU2OwogICAgICAgICAgICByZXQgID0gciA8PCAgNTsKICAgICAgICAgICAgcmV0IHw9IGcgPDwgIDI7CiAgICAgICAgICAgIHJldCB8PSBiIDw8ICAwOwogICAgICAgICAgICBUUkFDRSgiUmV0dXJuaW5nICUwOHhcbiIsIHJldCk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9YOEI4RzhSODoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQThCOEc4Ujg6CiAgICAgICAgICAgIHJldCAgPSBhIDw8IDI0OwogICAgICAgICAgICByZXQgfD0gYiA8PCAxNjsKICAgICAgICAgICAgcmV0IHw9IGcgPDwgIDg7CiAgICAgICAgICAgIHJldCB8PSByIDw8ICAwOwogICAgICAgICAgICBUUkFDRSgiUmV0dXJuaW5nICUwOHhcbiIsIHJldCk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9BMlIxMEcxMEIxMDoKICAgICAgICAgICAgYSA9IChhICogICAgNCkgLyAyNTY7CiAgICAgICAgICAgIHIgPSAociAqIDEwMjQpIC8gMjU2OwogICAgICAgICAgICBnID0gKGcgKiAxMDI0KSAvIDI1NjsKICAgICAgICAgICAgYiA9IChiICogMTAyNCkgLyAyNTY7CiAgICAgICAgICAgIHJldCAgPSBhIDw8IDMwOwogICAgICAgICAgICByZXQgfD0gciA8PCAyMDsKICAgICAgICAgICAgcmV0IHw9IGcgPDwgMTA7CiAgICAgICAgICAgIHJldCB8PSBiIDw8ICAwOwogICAgICAgICAgICBUUkFDRSgiUmV0dXJuaW5nICUwOHhcbiIsIHJldCk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9BMkIxMEcxMFIxMDoKICAgICAgICAgICAgYSA9IChhICogICAgNCkgLyAyNTY7CiAgICAgICAgICAgIHIgPSAociAqIDEwMjQpIC8gMjU2OwogICAgICAgICAgICBnID0gKGcgKiAxMDI0KSAvIDI1NjsKICAgICAgICAgICAgYiA9IChiICogMTAyNCkgLyAyNTY7CiAgICAgICAgICAgIHJldCAgPSBhIDw8IDMwOwogICAgICAgICAgICByZXQgfD0gYiA8PCAyMDsKICAgICAgICAgICAgcmV0IHw9IGcgPDwgMTA7CiAgICAgICAgICAgIHJldCB8PSByIDw8ICAwOwogICAgICAgICAgICBUUkFDRSgiUmV0dXJuaW5nICUwOHhcbiIsIHJldCk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEZJWE1FKCJBZGQgYSBDT0xPUkZJTEwgY29udmVyc2lvbiBmb3IgZm9ybWF0ICVzXG4iLCBkZWJ1Z19kM2Rmb3JtYXQoZGVzdGZtdCkpOwogICAgICAgICAgICByZXR1cm4gMDsKICAgIH0KfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9Db2xvckZpbGwoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFN1cmZhY2UgKnBTdXJmYWNlLCBDT05TVCBXSU5FRDNEUkVDVCogcFJlY3QsIFdJTkVEM0RDT0xPUiBjb2xvcikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKnN1cmZhY2UgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBwU3VyZmFjZTsKICAgIFdJTkVEREJMVEZYIEJsdEZ4OwogICAgVFJBQ0UoIiglcCkgQ29sb3VyIGZpbGwgU3VyZmFjZTogJXAgcmVjdDogJXAgY29sb3I6IDB4JTA4eFxuIiwgVGhpcywgcFN1cmZhY2UsIHBSZWN0LCBjb2xvcik7CgogICAgaWYgKHN1cmZhY2UtPnJlc291cmNlLnBvb2wgIT0gV0lORUQzRFBPT0xfREVGQVVMVCAmJiBzdXJmYWNlLT5yZXNvdXJjZS5wb29sICE9IFdJTkVEM0RQT09MX1NZU1RFTU1FTSkgewogICAgICAgIEZJWE1FKCJjYWxsIHRvIGNvbG9yZmlsbCB3aXRoIG5vbiBXSU5FRDNEUE9PTF9ERUZBVUxUIG9yIFdJTkVEM0RQT09MX1NZU1RFTU1FTSBzdXJmYWNlXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBpZiAod2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUgPT0gT1JNX0ZCTykgewogICAgICAgIGNvbG9yX2ZpbGxfZmJvKGlmYWNlLCBwU3VyZmFjZSwgcFJlY3QsIGNvbG9yKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogSnVzdCBmb3J3YXJkIHRoaXMgdG8gdGhlIERpcmVjdERyYXcgYmxpdHRpbmcgZW5naW5lICovCiAgICAgICAgbWVtc2V0KCZCbHRGeCwgMCwgc2l6ZW9mKEJsdEZ4KSk7CiAgICAgICAgQmx0RnguZHdTaXplID0gc2l6ZW9mKEJsdEZ4KTsKICAgICAgICBCbHRGeC51NS5kd0ZpbGxDb2xvciA9IGFyZ2JfdG9fZm10KGNvbG9yLCBzdXJmYWNlLT5yZXNvdXJjZS5mb3JtYXQpOwogICAgICAgIHJldHVybiBJV2luZUQzRFN1cmZhY2VfQmx0KHBTdXJmYWNlLCAoUkVDVCAqKSBwUmVjdCwgTlVMTCwgTlVMTCwgV0lORUREQkxUX0NPTE9SRklMTCwgJkJsdEZ4LCBXSU5FRDNEVEVYRl9OT05FKTsKICAgIH0KfQoKLyogcmVuZGVydGFyZ2V0IGFuZCBkZXB0dGggc3RlbmNpbCBmdW5jdGlvbnMgKi8Kc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFJlbmRlclRhcmdldChJV2luZUQzRERldmljZSogaWZhY2UsRFdPUkQgUmVuZGVyVGFyZ2V0SW5kZXgsIElXaW5lRDNEU3VyZmFjZSAqKnBwUmVuZGVyVGFyZ2V0KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgaWYgKFJlbmRlclRhcmdldEluZGV4ID49IEdMX0xJTUlUUyhidWZmZXJzKSkgewogICAgICAgIEVSUigiKCVwKSA6IE9ubHkgJWQgcmVuZGVyIHRhcmdldHMgYXJlIHN1cHBvcnRlZC5cbiIsIFRoaXMsIEdMX0xJTUlUUyhidWZmZXJzKSk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgKnBwUmVuZGVyVGFyZ2V0ID0gVGhpcy0+cmVuZGVyX3RhcmdldHNbUmVuZGVyVGFyZ2V0SW5kZXhdOwogICAgVFJBQ0UoIiglcCkgOiBSZW5kZXJUYXJnZXQgJWQgSW5kZXggcmV0dXJuaW5nICVwXG4iLCBUaGlzLCBSZW5kZXJUYXJnZXRJbmRleCwgKnBwUmVuZGVyVGFyZ2V0KTsKICAgIC8qIE5vdGUgaW5jIHJlZiBvbiByZXR1cm5lZCBzdXJmYWNlICovCiAgICBpZigqcHBSZW5kZXJUYXJnZXQgIT0gTlVMTCkKICAgICAgICBJV2luZUQzRFN1cmZhY2VfQWRkUmVmKCpwcFJlbmRlclRhcmdldCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRGcm9udEJhY2tCdWZmZXJzKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RTdXJmYWNlICpGcm9udCwgSVdpbmVEM0RTdXJmYWNlICpCYWNrKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpGcm9udEltcGwgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBGcm9udDsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKkJhY2tJbXBsID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgQmFjazsKICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqU3dhcGNoYWluOwogICAgSFJFU1VMVCBocjsKCiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwKVxuIiwgVGhpcywgRnJvbnRJbXBsLCBCYWNrSW1wbCk7CgogICAgaHIgPSBJV2luZUQzRERldmljZV9HZXRTd2FwQ2hhaW4oaWZhY2UsIDAsIChJV2luZUQzRFN3YXBDaGFpbiAqKikgJlN3YXBjaGFpbik7CiAgICBpZihociAhPSBXSU5FRDNEX09LKSB7CiAgICAgICAgRVJSKCJDYW4ndCBnZXQgdGhlIHN3YXBjaGFpblxuIik7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIC8qIE1ha2Ugc3VyZSB0byByZWxlYXNlIHRoZSBzd2FwY2hhaW4gKi8KICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoKElXaW5lRDNEU3dhcENoYWluICopIFN3YXBjaGFpbik7CgogICAgaWYoRnJvbnRJbXBsICYmICEoRnJvbnRJbXBsLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpICkgewogICAgICAgIEVSUigiVHJ5aW5nIHRvIHNldCBhIGZyb250IGJ1ZmZlciB3aGljaCBkb2Vzbid0IGhhdmUgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCB1c2FnZVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICBlbHNlIGlmKEJhY2tJbXBsICYmICEoQmFja0ltcGwtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkpIHsKICAgICAgICBFUlIoIlRyeWluZyB0byBzZXQgYSBiYWNrIGJ1ZmZlciB3aGljaCBkb2Vzbid0IGhhdmUgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCB1c2FnZVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYoU3dhcGNoYWluLT5mcm9udEJ1ZmZlciAhPSBGcm9udCkgewogICAgICAgIFRSQUNFKCJDaGFuZ2luZyB0aGUgZnJvbnQgYnVmZmVyIGZyb20gJXAgdG8gJXBcbiIsIFN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIsIEZyb250KTsKCiAgICAgICAgaWYoU3dhcGNoYWluLT5mcm9udEJ1ZmZlcikKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbnRhaW5lcihTd2FwY2hhaW4tPmZyb250QnVmZmVyLCBOVUxMKTsKICAgICAgICBTd2FwY2hhaW4tPmZyb250QnVmZmVyID0gRnJvbnQ7CgogICAgICAgIGlmKFN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIpIHsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbnRhaW5lcihTd2FwY2hhaW4tPmZyb250QnVmZmVyLCAoSVdpbmVEM0RCYXNlICopIFN3YXBjaGFpbik7CiAgICAgICAgfQogICAgfQoKICAgIGlmKEJhY2sgJiYgIVN3YXBjaGFpbi0+YmFja0J1ZmZlcikgewogICAgICAgIC8qIFdlIG5lZWQgbWVtb3J5IGZvciB0aGUgYmFjayBidWZmZXIgYXJyYXkgLSBvbmx5IG9uZSBiYWNrIGJ1ZmZlciB0aGlzIHdheSAqLwogICAgICAgIFN3YXBjaGFpbi0+YmFja0J1ZmZlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSVdpbmVEM0RTdXJmYWNlICopKTsKICAgICAgICBpZighU3dhcGNoYWluLT5iYWNrQnVmZmVyKSB7CiAgICAgICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeVxuIik7CiAgICAgICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwogICAgICAgIH0KICAgIH0KCiAgICBpZihTd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0gIT0gQmFjaykgewogICAgICAgIFRSQUNFKCJDaGFuZ2luZyB0aGUgYmFjayBidWZmZXIgZnJvbSAlcCB0byAlcFxuIiwgU3dhcGNoYWluLT5iYWNrQnVmZmVyLCBCYWNrKTsKCiAgICAgICAgLyogV2hhdCB0byBkbyBhYm91dCB0aGUgY29udGV4dCBoZXJlIGluIHRoZSBjYXNlIG9mIG11bHRpdGhyZWFkaW5nPyBOb3Qgc3VyZS4KICAgICAgICAgKiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBieSBJRGlyZWN0M0Q3OjpDcmVhdGVEZXZpY2Ugc28gaW4gdGhlb3J5IGl0cyBpbml0aWFsaXphdGlvbiBjb2RlCiAgICAgICAgICovCiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICBpZighU3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdKSB7CiAgICAgICAgICAgIC8qIEdMIHdhcyB0b2xkIHRvIGRyYXcgdG8gdGhlIGZyb250IGJ1ZmZlciBhdCBjcmVhdGlvbiwKICAgICAgICAgICAgICogdW5kbyB0aGF0CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBnbERyYXdCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoR0xfQkFDSykiKTsKICAgICAgICAgICAgLyogU2V0IHRoZSBiYWNrYnVmZmVyIGNvdW50IHRvIDEgYmVjYXVzZSBvdGhlciBjb2RlIHVzZXMgaXQgdG8gZmluZyB0aGUgYmFjayBidWZmZXJzICovCiAgICAgICAgICAgIFN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJDb3VudCA9IDE7CiAgICAgICAgfSBlbHNlIGlmICghQmFjaykgewogICAgICAgICAgICAvKiBUaGF0IG1ha2VzIHByb2JsZW1zIC0gZGlzYWJsZSBmb3Igbm93ICovCiAgICAgICAgICAgIC8qIGdsRHJhd0J1ZmZlcihHTF9GUk9OVCk7ICovCiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoR0xfRlJPTlQpIik7CiAgICAgICAgICAgIC8qIFdlIGhhdmUgbG9zdCBvdXIgYmFjayBidWZmZXIsIHNldCB0aGlzIHRvIDAgdG8gYXZvaWQgY29uZnVzaW5nIG90aGVyIGNvZGUgKi8KICAgICAgICAgICAgU3dhcGNoYWluLT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckNvdW50ID0gMDsKICAgICAgICB9CiAgICAgICAgTEVBVkVfR0woKTsKCiAgICAgICAgaWYoU3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdKQogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29udGFpbmVyKFN3YXBjaGFpbi0+YmFja0J1ZmZlclswXSwgTlVMTCk7CiAgICAgICAgU3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdID0gQmFjazsKCiAgICAgICAgaWYoU3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdKSB7CiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb250YWluZXIoU3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdLCAoSVdpbmVEM0RCYXNlICopIFN3YXBjaGFpbik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgU3dhcGNoYWluLT5iYWNrQnVmZmVyKTsKICAgICAgICAgICAgU3dhcGNoYWluLT5iYWNrQnVmZmVyID0gTlVMTDsKICAgICAgICB9CgogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfR2V0RGVwdGhTdGVuY2lsU3VyZmFjZShJV2luZUQzRERldmljZSogaWZhY2UsIElXaW5lRDNEU3VyZmFjZSAqKnBwWlN0ZW5jaWxTdXJmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICAqcHBaU3RlbmNpbFN1cmZhY2UgPSBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0OwogICAgVFJBQ0UoIiglcCkgOiB6U3RlbmNpbFN1cmZhY2UgIHJldHVybmluZyAlcFxuIiwgVGhpcywgICpwcFpTdGVuY2lsU3VyZmFjZSk7CgogICAgaWYoKnBwWlN0ZW5jaWxTdXJmYWNlICE9IE5VTEwpIHsKICAgICAgICAvKiBOb3RlIGluYyByZWYgb24gcmV0dXJuZWQgc3VyZmFjZSAqLwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9BZGRSZWYoKnBwWlN0ZW5jaWxTdXJmYWNlKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfTk9URk9VTkQ7CiAgICB9Cn0KCi8qIFRPRE86IEhhbmRsZSBzdGVuY2lsIGF0dGFjaG1lbnRzICovCnN0YXRpYyB2b2lkIHNldF9kZXB0aF9zdGVuY2lsX2ZibyhJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEU3VyZmFjZSAqZGVwdGhfc3RlbmNpbCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqZGVwdGhfc3RlbmNpbF9pbXBsID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilkZXB0aF9zdGVuY2lsOwoKICAgIFRSQUNFKCJTZXQgZGVwdGggc3RlbmNpbCB0byAlcFxuIiwgZGVwdGhfc3RlbmNpbCk7CgogICAgaWYgKGRlcHRoX3N0ZW5jaWxfaW1wbCkgewogICAgICAgIGlmIChkZXB0aF9zdGVuY2lsX2ltcGwtPmN1cnJlbnRfcmVuZGVyYnVmZmVyKSB7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xGcmFtZWJ1ZmZlclJlbmRlcmJ1ZmZlckVYVChHTF9GUkFNRUJVRkZFUl9FWFQsIEdMX0RFUFRIX0FUVEFDSE1FTlRfRVhULCBHTF9SRU5ERVJCVUZGRVJfRVhULCBkZXB0aF9zdGVuY2lsX2ltcGwtPmN1cnJlbnRfcmVuZGVyYnVmZmVyLT5pZCkpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xGcmFtZWJ1ZmZlclJlbmRlcmJ1ZmZlckVYVCgpIik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKnRleHR1cmVfaW1wbDsKICAgICAgICAgICAgR0xlbnVtIHRleHR0YXJnZXQsIHRhcmdldDsKICAgICAgICAgICAgR0xpbnQgb2xkX2JpbmRpbmcgPSAwOwoKICAgICAgICAgICAgdGV4dHRhcmdldCA9IGRlcHRoX3N0ZW5jaWxfaW1wbC0+Z2xEZXNjcmlwdGlvbi50YXJnZXQ7CiAgICAgICAgICAgIGlmKHRleHR0YXJnZXQgPT0gR0xfVEVYVFVSRV8yRCkgewogICAgICAgICAgICAgICAgdGFyZ2V0ID0gR0xfVEVYVFVSRV8yRDsKICAgICAgICAgICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfVEVYVFVSRV9CSU5ESU5HXzJELCAmb2xkX2JpbmRpbmcpOwogICAgICAgICAgICB9IGVsc2UgaWYodGV4dHRhcmdldCA9PSBHTF9URVhUVVJFX1JFQ1RBTkdMRV9BUkIpIHsKICAgICAgICAgICAgICAgIHRhcmdldCA9IEdMX1RFWFRVUkVfUkVDVEFOR0xFX0FSQjsKICAgICAgICAgICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfVEVYVFVSRV9CSU5ESU5HX1JFQ1RBTkdMRV9BUkIsICZvbGRfYmluZGluZyk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0YXJnZXQgPSBHTF9URVhUVVJFX0NVQkVfTUFQX0FSQjsKICAgICAgICAgICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfVEVYVFVSRV9CSU5ESU5HX0NVQkVfTUFQX0FSQiwgJm9sZF9iaW5kaW5nKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1ByZUxvYWQoZGVwdGhfc3RlbmNpbCk7CgogICAgICAgICAgICBnbFRleFBhcmFtZXRlcmkodGFyZ2V0LCBHTF9URVhUVVJFX01JTl9GSUxURVIsIEdMX05FQVJFU1QpOwogICAgICAgICAgICBnbFRleFBhcmFtZXRlcmkodGFyZ2V0LCBHTF9URVhUVVJFX01BR19GSUxURVIsIEdMX05FQVJFU1QpOwogICAgICAgICAgICBnbFRleFBhcmFtZXRlcmkodGFyZ2V0LCBHTF9ERVBUSF9URVhUVVJFX01PREVfQVJCLCBHTF9MVU1JTkFOQ0UpOwogICAgICAgICAgICBnbEJpbmRUZXh0dXJlKHRhcmdldCwgb2xkX2JpbmRpbmcpOwoKICAgICAgICAgICAgLyogVXBkYXRlIGJhc2UgdGV4dHVyZSBzdGF0ZXMgYXJyYXkgKi8KICAgICAgICAgICAgaWYgKFNVQ0NFRURFRChJV2luZUQzRFN1cmZhY2VfR2V0Q29udGFpbmVyKGRlcHRoX3N0ZW5jaWwsICZJSURfSVdpbmVEM0RCYXNlVGV4dHVyZSwgKHZvaWQgKiopJnRleHR1cmVfaW1wbCkpKSB7CiAgICAgICAgICAgICAgICB0ZXh0dXJlX2ltcGwtPmJhc2VUZXh0dXJlLnN0YXRlc1tXSU5FRDNEVEVYU1RBX01JTkZJTFRFUl0gPSBXSU5FRDNEVEVYRl9QT0lOVDsKICAgICAgICAgICAgICAgIHRleHR1cmVfaW1wbC0+YmFzZVRleHR1cmUuc3RhdGVzW1dJTkVEM0RURVhTVEFfTUFHRklMVEVSXSA9IFdJTkVEM0RURVhGX1BPSU5UOwogICAgICAgICAgICAgICAgaWYgKHRleHR1cmVfaW1wbC0+YmFzZVRleHR1cmUuYmluZENvdW50KSB7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1NBTVBMRVIodGV4dHVyZV9pbXBsLT5iYXNlVGV4dHVyZS5zYW1wbGVyKSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9SZWxlYXNlKChJV2luZUQzREJhc2VUZXh0dXJlICopdGV4dHVyZV9pbXBsKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEZyYW1lYnVmZmVyVGV4dHVyZTJERVhUKEdMX0ZSQU1FQlVGRkVSX0VYVCwgR0xfREVQVEhfQVRUQUNITUVOVF9FWFQsIHRleHR0YXJnZXQsCiAgICAgICAgICAgICAgICAgICAgZGVwdGhfc3RlbmNpbF9pbXBsLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lLCBkZXB0aF9zdGVuY2lsX2ltcGwtPmdsRGVzY3JpcHRpb24ubGV2ZWwpKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRnJhbWVidWZmZXJUZXh0dXJlMkRFWFQoKSIpOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgR0xfRVhUQ0FMTChnbEZyYW1lYnVmZmVyVGV4dHVyZTJERVhUKEdMX0ZSQU1FQlVGRkVSX0VYVCwgR0xfREVQVEhfQVRUQUNITUVOVF9FWFQsIEdMX1RFWFRVUkVfMkQsIDAsIDApKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xGcmFtZWJ1ZmZlclRleHR1cmUyREVYVCgpIik7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIHNldF9yZW5kZXJfdGFyZ2V0X2ZibyhJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIGlkeCwgSVdpbmVEM0RTdXJmYWNlICpyZW5kZXJfdGFyZ2V0KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpydGltcGwgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKXJlbmRlcl90YXJnZXQ7CgogICAgVFJBQ0UoIlNldCByZW5kZXIgdGFyZ2V0ICV1IHRvICVwXG4iLCBpZHgsIHJlbmRlcl90YXJnZXQpOwoKICAgIGlmIChydGltcGwpIHsKICAgICAgICBhdHRhY2hfc3VyZmFjZV9mYm8oVGhpcywgR0xfRlJBTUVCVUZGRVJfRVhULCBpZHgsIHJlbmRlcl90YXJnZXQpOwogICAgICAgIFRoaXMtPmRyYXdfYnVmZmVyc1tpZHhdID0gR0xfQ09MT1JfQVRUQUNITUVOVDBfRVhUICsgaWR4OwogICAgfSBlbHNlIHsKICAgICAgICBHTF9FWFRDQUxMKGdsRnJhbWVidWZmZXJUZXh0dXJlMkRFWFQoR0xfRlJBTUVCVUZGRVJfRVhULCBHTF9DT0xPUl9BVFRBQ0hNRU5UMF9FWFQgKyBpZHgsIEdMX1RFWFRVUkVfMkQsIDAsIDApKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xGcmFtZWJ1ZmZlclRleHR1cmUyREVYVCgpIik7CgogICAgICAgIFRoaXMtPmRyYXdfYnVmZmVyc1tpZHhdID0gR0xfTk9ORTsKICAgIH0KfQoKc3RhdGljIHZvaWQgY2hlY2tfZmJvX3N0YXR1cyhJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIEdMZW51bSBzdGF0dXM7CgogICAgc3RhdHVzID0gR0xfRVhUQ0FMTChnbENoZWNrRnJhbWVidWZmZXJTdGF0dXNFWFQoR0xfRlJBTUVCVUZGRVJfRVhUKSk7CiAgICBpZiAoc3RhdHVzID09IEdMX0ZSQU1FQlVGRkVSX0NPTVBMRVRFX0VYVCkgewogICAgICAgIFRSQUNFKCJGQk8gY29tcGxldGVcbiIpOwogICAgfSBlbHNlIHsKICAgICAgICBGSVhNRSgiRkJPIHN0YXR1cyAlcyAoJSN4KVxuIiwgZGVidWdfZmJvc3RhdHVzKHN0YXR1cyksIHN0YXR1cyk7CgogICAgICAgIC8qIER1bXAgdGhlIEZCTyBhdHRhY2htZW50cyAqLwogICAgICAgIGlmIChzdGF0dXMgPT0gR0xfRlJBTUVCVUZGRVJfVU5TVVBQT1JURURfRVhUKSB7CiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKmF0dGFjaG1lbnQ7CiAgICAgICAgICAgIGludCBpOwoKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IEdMX0xJTUlUUyhidWZmZXJzKTsgKytpKSB7CiAgICAgICAgICAgICAgICBhdHRhY2htZW50ID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilUaGlzLT5mYm9fY29sb3JfYXR0YWNobWVudHNbaV07CiAgICAgICAgICAgICAgICBpZiAoYXR0YWNobWVudCkgewogICAgICAgICAgICAgICAgICAgIEZJWE1FKCJcdENvbG9yIGF0dGFjaG1lbnQgJWQ6ICglcCkgJXMgJXV4JXVcbiIsIGksIGF0dGFjaG1lbnQsIGRlYnVnX2QzZGZvcm1hdChhdHRhY2htZW50LT5yZXNvdXJjZS5mb3JtYXQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0YWNobWVudC0+cG93MldpZHRoLCBhdHRhY2htZW50LT5wb3cySGVpZ2h0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBhdHRhY2htZW50ID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilUaGlzLT5mYm9fZGVwdGhfYXR0YWNobWVudDsKICAgICAgICAgICAgaWYgKGF0dGFjaG1lbnQpIHsKICAgICAgICAgICAgICAgIEZJWE1FKCJcdERlcHRoIGF0dGFjaG1lbnQ6ICglcCkgJXMgJXV4JXVcbiIsIGF0dGFjaG1lbnQsIGRlYnVnX2QzZGZvcm1hdChhdHRhY2htZW50LT5yZXNvdXJjZS5mb3JtYXQpLAogICAgICAgICAgICAgICAgICAgICAgICBhdHRhY2htZW50LT5wb3cyV2lkdGgsIGF0dGFjaG1lbnQtPnBvdzJIZWlnaHQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CgpzdGF0aWMgQk9PTCBkZXB0aF9taXNtYXRjaF9mYm8oSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpydF9pbXBsID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKmRzX2ltcGwgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKVRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQ7CgogICAgaWYgKCFkc19pbXBsKSByZXR1cm4gRkFMU0U7CgogICAgaWYgKGRzX2ltcGwtPmN1cnJlbnRfcmVuZGVyYnVmZmVyKSB7CiAgICAgICAgcmV0dXJuIChydF9pbXBsLT5wb3cyV2lkdGggIT0gZHNfaW1wbC0+Y3VycmVudF9yZW5kZXJidWZmZXItPndpZHRoIHx8CiAgICAgICAgICAgICAgICBydF9pbXBsLT5wb3cySGVpZ2h0ICE9IGRzX2ltcGwtPmN1cnJlbnRfcmVuZGVyYnVmZmVyLT5oZWlnaHQpOwogICAgfQoKICAgIHJldHVybiAocnRfaW1wbC0+cG93MldpZHRoICE9IGRzX2ltcGwtPnBvdzJXaWR0aCB8fAogICAgICAgICAgICBydF9pbXBsLT5wb3cySGVpZ2h0ICE9IGRzX2ltcGwtPnBvdzJIZWlnaHQpOwp9Cgp2b2lkIGFwcGx5X2Zib19zdGF0ZShJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIHVuc2lnbmVkIGludCBpOwoKICAgIGlmIChUaGlzLT5yZW5kZXJfb2Zmc2NyZWVuKSB7CiAgICAgICAgYmluZF9mYm8oaWZhY2UsIEdMX0ZSQU1FQlVGRkVSX0VYVCwgJlRoaXMtPmZibyk7CgogICAgICAgIC8qIEFwcGx5IHJlbmRlciB0YXJnZXRzICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IEdMX0xJTUlUUyhidWZmZXJzKTsgKytpKSB7CiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSAqcmVuZGVyX3RhcmdldCA9IFRoaXMtPnJlbmRlcl90YXJnZXRzW2ldOwogICAgICAgICAgICBpZiAoVGhpcy0+ZmJvX2NvbG9yX2F0dGFjaG1lbnRzW2ldICE9IHJlbmRlcl90YXJnZXQpIHsKICAgICAgICAgICAgICAgIHNldF9yZW5kZXJfdGFyZ2V0X2ZibyhpZmFjZSwgaSwgcmVuZGVyX3RhcmdldCk7CiAgICAgICAgICAgICAgICBUaGlzLT5mYm9fY29sb3JfYXR0YWNobWVudHNbaV0gPSByZW5kZXJfdGFyZ2V0OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiBBcHBseSBkZXB0aCB0YXJnZXRzICovCiAgICAgICAgaWYgKFRoaXMtPmZib19kZXB0aF9hdHRhY2htZW50ICE9IFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQgfHwgZGVwdGhfbWlzbWF0Y2hfZmJvKGlmYWNlKSkgewogICAgICAgICAgICB1bnNpZ25lZCBpbnQgdyA9ICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKVRoaXMtPnJlbmRlcl90YXJnZXRzWzBdKS0+cG93MldpZHRoOwogICAgICAgICAgICB1bnNpZ25lZCBpbnQgaCA9ICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKVRoaXMtPnJlbmRlcl90YXJnZXRzWzBdKS0+cG93MkhlaWdodDsKCiAgICAgICAgICAgIGlmIChUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KSB7CiAgICAgICAgICAgICAgICBzdXJmYWNlX3NldF9jb21wYXRpYmxlX3JlbmRlcmJ1ZmZlcihUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0LCB3LCBoKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBzZXRfZGVwdGhfc3RlbmNpbF9mYm8oaWZhY2UsIFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQpOwogICAgICAgICAgICBUaGlzLT5mYm9fZGVwdGhfYXR0YWNobWVudCA9IFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQ7CiAgICAgICAgfQoKICAgICAgICBpZiAoR0xfU1VQUE9SVChBUkJfRFJBV19CVUZGRVJTKSkgewogICAgICAgICAgICBHTF9FWFRDQUxMKGdsRHJhd0J1ZmZlcnNBUkIoR0xfTElNSVRTKGJ1ZmZlcnMpLCBUaGlzLT5kcmF3X2J1ZmZlcnMpKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcnMoKSIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihUaGlzLT5kcmF3X2J1ZmZlcnNbMF0pOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKCkiKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kRnJhbWVidWZmZXJFWFQoR0xfRlJBTUVCVUZGRVJfRVhULCAwKSk7CiAgICB9CgogICAgY2hlY2tfZmJvX3N0YXR1cyhpZmFjZSk7Cn0KCnZvaWQgc3RyZXRjaF9yZWN0X2ZibyhJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEU3VyZmFjZSAqc3JjX3N1cmZhY2UsIFdJTkVEM0RSRUNUICpzcmNfcmVjdCwKICAgICAgICBJV2luZUQzRFN1cmZhY2UgKmRzdF9zdXJmYWNlLCBXSU5FRDNEUkVDVCAqZHN0X3JlY3QsIGNvbnN0IFdJTkVEM0RURVhUVVJFRklMVEVSVFlQRSBmaWx0ZXIsIEJPT0wgZmxpcCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgR0xiaXRmaWVsZCBtYXNrID0gR0xfQ09MT1JfQlVGRkVSX0JJVDsgLyogVE9ETzogU3VwcG9ydCBibGl0dGluZyBkZXB0aC9zdGVuY2lsIHN1cmZhY2VzICovCiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3JjX3N3YXBjaGFpbiwgKmRzdF9zd2FwY2hhaW47CiAgICBHTGVudW0gZ2xfZmlsdGVyOwoKICAgIFRSQUNFKCIoJXApIDogc3JjX3N1cmZhY2UgJXAsIHNyY19yZWN0ICVwLCBkc3Rfc3VyZmFjZSAlcCwgZHN0X3JlY3QgJXAsIGZpbHRlciAlcyAoMHglMDh4KSwgZmxpcCAldVxuIiwKICAgICAgICAgICAgVGhpcywgc3JjX3N1cmZhY2UsIHNyY19yZWN0LCBkc3Rfc3VyZmFjZSwgZHN0X3JlY3QsIGRlYnVnX2QzZHRleHR1cmVmaWx0ZXJ0eXBlKGZpbHRlciksIGZpbHRlciwgZmxpcCk7CiAgICBUUkFDRSgic3JjX3JlY3QgWyV1LCAldV0tPlsldSwgJXVdXG4iLCBzcmNfcmVjdC0+eDEsIHNyY19yZWN0LT55MSwgc3JjX3JlY3QtPngyLCBzcmNfcmVjdC0+eTIpOwogICAgVFJBQ0UoImRzdF9yZWN0IFsldSwgJXVdLT5bJXUsICV1XVxuIiwgZHN0X3JlY3QtPngxLCBkc3RfcmVjdC0+eTEsIGRzdF9yZWN0LT54MiwgZHN0X3JlY3QtPnkyKTsKCiAgICBzd2l0Y2ggKGZpbHRlcikgewogICAgICAgIGNhc2UgV0lORUQzRFRFWEZfTElORUFSOgogICAgICAgICAgICBnbF9maWx0ZXIgPSBHTF9MSU5FQVI7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBGSVhNRSgiVW5zdXBwb3J0ZWQgZmlsdGVyIG1vZGUgJXMgKDB4JTA4eClcbiIsIGRlYnVnX2QzZHRleHR1cmVmaWx0ZXJ0eXBlKGZpbHRlciksIGZpbHRlcik7CiAgICAgICAgY2FzZSBXSU5FRDNEVEVYRl9OT05FOgogICAgICAgIGNhc2UgV0lORUQzRFRFWEZfUE9JTlQ6CiAgICAgICAgICAgIGdsX2ZpbHRlciA9IEdMX05FQVJFU1Q7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQoKICAgIC8qIEF0dGFjaCBzcmMgc3VyZmFjZSB0byBzcmMgZmJvICovCiAgICBzcmNfc3dhcGNoYWluID0gZ2V0X3N3YXBjaGFpbihzcmNfc3VyZmFjZSk7CiAgICBpZiAoc3JjX3N3YXBjaGFpbikgewogICAgICAgIEdMZW51bSBidWZmZXI7CgogICAgICAgIFRSQUNFKCJTb3VyY2Ugc3VyZmFjZSAlcCBpcyBvbnNjcmVlblxuIiwgc3JjX3N1cmZhY2UpOwogICAgICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBzcmNfc3VyZmFjZSwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKCiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEZyYW1lYnVmZmVyRVhUKEdMX1JFQURfRlJBTUVCVUZGRVJfRVhULCAwKSk7CiAgICAgICAgYnVmZmVyID0gc3VyZmFjZV9nZXRfZ2xfYnVmZmVyKHNyY19zdXJmYWNlLCBzcmNfc3dhcGNoYWluKTsKICAgICAgICBnbFJlYWRCdWZmZXIoYnVmZmVyKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xSZWFkQnVmZmVyKCkiKTsKCiAgICAgICAgc3JjX3JlY3QtPnkxID0gKChJV2luZUQzRFN1cmZhY2VJbXBsICopc3JjX3N1cmZhY2UpLT5jdXJyZW50RGVzYy5IZWlnaHQgLSBzcmNfcmVjdC0+eTE7CiAgICAgICAgc3JjX3JlY3QtPnkyID0gKChJV2luZUQzRFN1cmZhY2VJbXBsICopc3JjX3N1cmZhY2UpLT5jdXJyZW50RGVzYy5IZWlnaHQgLSBzcmNfcmVjdC0+eTI7CiAgICB9IGVsc2UgewogICAgICAgIFRSQUNFKCJTb3VyY2Ugc3VyZmFjZSAlcCBpcyBvZmZzY3JlZW5cbiIsIHNyY19zdXJmYWNlKTsKICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgIGJpbmRfZmJvKGlmYWNlLCBHTF9SRUFEX0ZSQU1FQlVGRkVSX0VYVCwgJlRoaXMtPnNyY19mYm8pOwogICAgICAgIGF0dGFjaF9zdXJmYWNlX2ZibyhUaGlzLCBHTF9SRUFEX0ZSQU1FQlVGRkVSX0VYVCwgMCwgc3JjX3N1cmZhY2UpOwogICAgICAgIGdsUmVhZEJ1ZmZlcihHTF9DT0xPUl9BVFRBQ0hNRU5UMF9FWFQpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIoKSIpOwogICAgfQogICAgTEVBVkVfR0woKTsKCiAgICAvKiBBdHRhY2ggZHN0IHN1cmZhY2UgdG8gZHN0IGZibyAqLwogICAgZHN0X3N3YXBjaGFpbiA9IGdldF9zd2FwY2hhaW4oZHN0X3N1cmZhY2UpOwogICAgaWYgKGRzdF9zd2FwY2hhaW4pIHsKICAgICAgICBHTGVudW0gYnVmZmVyOwoKICAgICAgICBUUkFDRSgiRGVzdGluYXRpb24gc3VyZmFjZSAlcCBpcyBvbnNjcmVlblxuIiwgZHN0X3N1cmZhY2UpOwogICAgICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBkc3Rfc3VyZmFjZSwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKCiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEZyYW1lYnVmZmVyRVhUKEdMX0RSQVdfRlJBTUVCVUZGRVJfRVhULCAwKSk7CiAgICAgICAgYnVmZmVyID0gc3VyZmFjZV9nZXRfZ2xfYnVmZmVyKGRzdF9zdXJmYWNlLCBkc3Rfc3dhcGNoYWluKTsKICAgICAgICBnbERyYXdCdWZmZXIoYnVmZmVyKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKCkiKTsKCiAgICAgICAgZHN0X3JlY3QtPnkxID0gKChJV2luZUQzRFN1cmZhY2VJbXBsICopZHN0X3N1cmZhY2UpLT5jdXJyZW50RGVzYy5IZWlnaHQgLSBkc3RfcmVjdC0+eTE7CiAgICAgICAgZHN0X3JlY3QtPnkyID0gKChJV2luZUQzRFN1cmZhY2VJbXBsICopZHN0X3N1cmZhY2UpLT5jdXJyZW50RGVzYy5IZWlnaHQgLSBkc3RfcmVjdC0+eTI7CiAgICB9IGVsc2UgewogICAgICAgIFRSQUNFKCJEZXN0aW5hdGlvbiBzdXJmYWNlICVwIGlzIG9mZnNjcmVlblxuIiwgZHN0X3N1cmZhY2UpOwoKICAgICAgICAvKiBObyBzcmMgb3IgZHN0IHN3YXBjaGFpbj8gTWFrZSBzdXJlIHNvbWUgY29udGV4dCBpcyBhY3RpdmUobXVsdGl0aHJlYWRpbmcpICovCiAgICAgICAgaWYoIXNyY19zd2FwY2hhaW4pIHsKICAgICAgICAgICAgQWN0aXZhdGVDb250ZXh0KFRoaXMsIFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQsIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CiAgICAgICAgfQoKICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgIGJpbmRfZmJvKGlmYWNlLCBHTF9EUkFXX0ZSQU1FQlVGRkVSX0VYVCwgJlRoaXMtPmRzdF9mYm8pOwogICAgICAgIGF0dGFjaF9zdXJmYWNlX2ZibyhUaGlzLCBHTF9EUkFXX0ZSQU1FQlVGRkVSX0VYVCwgMCwgZHN0X3N1cmZhY2UpOwogICAgICAgIGdsRHJhd0J1ZmZlcihHTF9DT0xPUl9BVFRBQ0hNRU5UMF9FWFQpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoKSIpOwogICAgfQogICAgZ2xEaXNhYmxlKEdMX1NDSVNTT1JfVEVTVCk7CiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19TQ0lTU09SVEVTVEVOQUJMRSkpOwoKICAgIGlmIChmbGlwKSB7CiAgICAgICAgR0xfRVhUQ0FMTChnbEJsaXRGcmFtZWJ1ZmZlckVYVChzcmNfcmVjdC0+eDEsIHNyY19yZWN0LT55MSwgc3JjX3JlY3QtPngyLCBzcmNfcmVjdC0+eTIsCiAgICAgICAgICAgICAgICBkc3RfcmVjdC0+eDEsIGRzdF9yZWN0LT55MiwgZHN0X3JlY3QtPngyLCBkc3RfcmVjdC0+eTEsIG1hc2ssIGdsX2ZpbHRlcikpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJsaXRGcmFtZWJ1ZmZlcigpIik7CiAgICB9IGVsc2UgewogICAgICAgIEdMX0VYVENBTEwoZ2xCbGl0RnJhbWVidWZmZXJFWFQoc3JjX3JlY3QtPngxLCBzcmNfcmVjdC0+eTEsIHNyY19yZWN0LT54Miwgc3JjX3JlY3QtPnkyLAogICAgICAgICAgICAgICAgZHN0X3JlY3QtPngxLCBkc3RfcmVjdC0+eTEsIGRzdF9yZWN0LT54MiwgZHN0X3JlY3QtPnkyLCBtYXNrLCBnbF9maWx0ZXIpKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xCbGl0RnJhbWVidWZmZXIoKSIpOwogICAgfQoKICAgIGlmIChUaGlzLT5yZW5kZXJfb2Zmc2NyZWVuKSB7CiAgICAgICAgYmluZF9mYm8oaWZhY2UsIEdMX0ZSQU1FQlVGRkVSX0VYVCwgJlRoaXMtPmZibyk7CiAgICB9IGVsc2UgewogICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kRnJhbWVidWZmZXJFWFQoR0xfRlJBTUVCVUZGRVJfRVhULCAwKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZEZyYW1lYnVmZmVyKCkiKTsKICAgIH0KCiAgICAvKiBJZiB3ZSBzd2l0Y2hlZCBmcm9tIEdMX0JBQ0sgdG8gR0xfRlJPTlQgYWJvdmUsIHdlIG5lZWQgdG8gc3dpdGNoIGJhY2sgaGVyZSAqLwogICAgaWYgKGRzdF9zd2FwY2hhaW4gJiYgZHN0X3N1cmZhY2UgPT0gKChJV2luZUQzRFN3YXBDaGFpbkltcGwgKilkc3Rfc3dhcGNoYWluKS0+ZnJvbnRCdWZmZXIKICAgICAgICAgICAgJiYgKChJV2luZUQzRFN3YXBDaGFpbkltcGwgKilkc3Rfc3dhcGNoYWluKS0+YmFja0J1ZmZlcikgewogICAgICAgIGdsRHJhd0J1ZmZlcihHTF9CQUNLKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKCkiKTsKICAgIH0KICAgIExFQVZFX0dMKCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0UmVuZGVyVGFyZ2V0KElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgUmVuZGVyVGFyZ2V0SW5kZXgsIElXaW5lRDNEU3VyZmFjZSAqcFJlbmRlclRhcmdldCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgV0lORUQzRFZJRVdQT1JUIHZpZXdwb3J0OwoKICAgIFRSQUNFKCIoJXApIDogU2V0dGluZyByZW5kZXJ0YXJnZXQgJWQgdG8gJXBcbiIsIFRoaXMsIFJlbmRlclRhcmdldEluZGV4LCBwUmVuZGVyVGFyZ2V0KTsKCiAgICBpZiAoUmVuZGVyVGFyZ2V0SW5kZXggPj0gR0xfTElNSVRTKGJ1ZmZlcnMpKSB7CiAgICAgICAgV0FSTigiKCVwKSA6IFVuc3VwcG9ydGVkIHRhcmdldCAldSBzZXQsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMKG9ubHkgJXUgc3VwcG9ydGVkKVxuIiwKICAgICAgICAgICAgIFRoaXMsIFJlbmRlclRhcmdldEluZGV4LCBHTF9MSU1JVFMoYnVmZmVycykpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIC8qIE1TRE4gc2F5cyB0aGF0IG51bGwgZGlzYWJsZXMgdGhlIHJlbmRlciB0YXJnZXQKICAgIGJ1dCBhIGRldmljZSBtdXN0IGFsd2F5cyBiZSBhc3NvY2lhdGVkIHdpdGggYSByZW5kZXIgdGFyZ2V0CiAgICBub3BlIE1TRE4gc2F5cyB0aGF0IHdlIHJldHVybiBpbnZhbGlkIGNhbGwgdG8gYSBudWxsIHJlbmRlcnRhcmdldCB3aXRoIGFuIGluZGV4IG9mIDAKCiAgICBzZWUgaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9saWJyYXJ5L2RlZmF1bHQuYXNwP3VybD0vbGlicmFyeS9lbi11cy9kaXJlY3R4OV9jL2RpcmVjdHgvZ3JhcGhpY3MvcHJvZ3JhbW1pbmdndWlkZS9BZHZhbmNlZFRvcGljcy9QaXhlbFBpcGUvTXVsdGlwbGVSZW5kZXJUYXJnZXQuYXNwCiAgICBmb3IgbW9yZSBkZXRhaWxzCiAgICAqLwogICAgaWYgKFJlbmRlclRhcmdldEluZGV4ID09IDAgJiYgcFJlbmRlclRhcmdldCA9PSBOVUxMKSB7CiAgICAgICAgRklYTUUoIlRyeWluZyB0byBzZXQgcmVuZGVyIHRhcmdldCAwIHRvIE5VTExcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgaWYgKHBSZW5kZXJUYXJnZXQgJiYgISgoKElXaW5lRDNEU3VyZmFjZUltcGwgKilwUmVuZGVyVGFyZ2V0KS0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSkgewogICAgICAgIEZJWE1FKCIoJXApVHJ5aW5nIHRvIHNldCB0aGUgcmVuZGVyIHRhcmdldCB0byBhIHN1cmZhY2UoJXApIHRoYXQgd2Fzbid0IGNyZWF0ZWQgd2l0aCBhIHVzYWdlIG9mIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVRcbiIsVGhpcyAscFJlbmRlclRhcmdldCk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogSWYgd2UgYXJlIHRyeWluZyB0byBzZXQgd2hhdCB3ZSBhbHJlYWR5IGhhdmUsIGRvbid0IGJvdGhlciAqLwogICAgaWYgKHBSZW5kZXJUYXJnZXQgPT0gVGhpcy0+cmVuZGVyX3RhcmdldHNbUmVuZGVyVGFyZ2V0SW5kZXhdKSB7CiAgICAgICAgVFJBQ0UoIlRyeWluZyB0byBkbyBhIE5PUCBTZXRSZW5kZXJUYXJnZXQgb3BlcmF0aW9uXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KICAgIGlmKHBSZW5kZXJUYXJnZXQpIElXaW5lRDNEU3VyZmFjZV9BZGRSZWYocFJlbmRlclRhcmdldCk7CiAgICBpZihUaGlzLT5yZW5kZXJfdGFyZ2V0c1tSZW5kZXJUYXJnZXRJbmRleF0pIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKFRoaXMtPnJlbmRlcl90YXJnZXRzW1JlbmRlclRhcmdldEluZGV4XSk7CiAgICBUaGlzLT5yZW5kZXJfdGFyZ2V0c1tSZW5kZXJUYXJnZXRJbmRleF0gPSBwUmVuZGVyVGFyZ2V0OwoKICAgIC8qIFJlbmRlciB0YXJnZXQgMCBpcyBzcGVjaWFsICovCiAgICBpZihSZW5kZXJUYXJnZXRJbmRleCA9PSAwKSB7CiAgICAgICAgLyogRmluYWxseSwgcmVzZXQgdGhlIHZpZXdwb3J0IGFzIHRoZSBNU0ROIHN0YXRlcy4gKi8KICAgICAgICB2aWV3cG9ydC5IZWlnaHQgPSAoKElXaW5lRDNEU3VyZmFjZUltcGwgKilUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXSktPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICB2aWV3cG9ydC5XaWR0aCAgPSAoKElXaW5lRDNEU3VyZmFjZUltcGwgKilUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXSktPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgIHZpZXdwb3J0LlggICAgICA9IDA7CiAgICAgICAgdmlld3BvcnQuWSAgICAgID0gMDsKICAgICAgICB2aWV3cG9ydC5NYXhaICAgPSAxLjBmOwogICAgICAgIHZpZXdwb3J0Lk1pblogICA9IDAuMGY7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZpZXdwb3J0KGlmYWNlLCAmdmlld3BvcnQpOwogICAgICAgIC8qIE1ha2Ugc3VyZSB0aGUgdmlld3BvcnQgc3RhdGUgaXMgZGlydHksIGJlY2F1c2UgdGhlIHJlbmRlcl9vZmZzY3JlZW4gdGhpbmcgYWZmZWN0cyBpdC4KICAgICAgICAgKiBTZXRWaWV3cG9ydCBtYXkgY2F0Y2ggTk9QIHZpZXdwb3J0IGNoYW5nZXMsIHdoaWNoIHdvdWxkIG9jY3VyIHdoZW4gc3dpdGNoaW5nIGJldHdlZW4gZXF1YWxseSBzaXplZCB0YXJnZXRzCiAgICAgICAgICovCiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1ZJRVdQT1JUKTsKCiAgICAgICAgLyogQWN0aXZhdGUgdGhlIG5ldyByZW5kZXIgdGFyZ2V0IGZvciBub3cuIFRoaXMgc2hvdWxkbid0IHN0YXkgaGVyZSwgYnV0IGlzIG5lZWRlZCB1bnRpbCBhbGwgbWV0aG9kcyB1c2luZyBnbCBhY3RpdmF0ZSB0aGUKICAgICAgICAgKiBjdHggcHJvcGVybHkuCiAgICAgICAgICogVXNlIHJlc291cmNlbG9hZCB1c2FnZSwgdGhpcyB3aWxsIGp1c3Qgc2V0IHRoZSBkcmF3YWJsZXMgYW5kIGNvbnRleHQgYnV0IG5vdCBhcHBseSBhbnkgc3RhdGVzLiBUaGUgc3RhdGVibG9jayBtYXkgYmUKICAgICAgICAgKiBpbmNvbXBsZXRlIG9yIGluY29ycmVjdCB3aGVuIFNldFJlbmRlclRhcmdldCBpcyBjYWxsZWQuIERyYXdQcmltKCkgd2lsbCBhcHBseSB0aGUgc3RhdGVzIHdoZW4gaXQgaXMgY2FsbGVkLgogICAgICAgICAqLwogICAgICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXSwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldERlcHRoU3RlbmNpbFN1cmZhY2UoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFN1cmZhY2UgKnBOZXdaU3RlbmNpbCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSFJFU1VMVCAgaHIgPSBXSU5FRDNEX09LOwogICAgSVdpbmVEM0RTdXJmYWNlICp0bXA7CgogICAgVFJBQ0UoIiglcCkgU3dhcHBpbmcgei1idWZmZXIuIE9sZCA9ICVwLCBuZXcgPSAlcFxuIixUaGlzLCBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0LCBwTmV3WlN0ZW5jaWwpOwoKICAgIGlmIChwTmV3WlN0ZW5jaWwgPT0gVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCkgewogICAgICAgIFRSQUNFKCJUcnlpbmcgdG8gZG8gYSBOT1AgU2V0UmVuZGVyVGFyZ2V0IG9wZXJhdGlvblxuIik7CiAgICB9IGVsc2UgewogICAgICAgIC8qKiBPcGVuR0wgZG9lc24ndCBzdXBwb3J0ICdzaGFyaW5nJyBvZiB0aGUgc3RlbmNpbEJ1ZmZlciBzbyB3ZSBtYXkgaW5jdXJlIGFuIGV4dHJhIG1lbW9yeSBvdmVyaGVhZAogICAgICAgICogZGVwZW5kaW5nIG9uIHRoZSByZW50ZXIgdGFyZ2V0IGltcGxlbWVudGF0aW9uIGJlaW5nIHVzZWQuCiAgICAgICAgKiBBIHNoYXJlZCBjb250ZXh0IGltcGxlbWVudGF0aW9uIHdpbGwgc2hhcmUgYWxsIGJ1ZmZlcnMgYmV0d2VlbiBhbGwgcmVuZGVydGFyZ2V0cyAoaW5jbHVkaW5nIHN3YXBjaGFpbnMpLAogICAgICAgICogaW1wbGVtZW50YXRpb25zIHRoYXQgdXNlIHNlcGFyYXRlIHBidWZmZXJzIGZvciBkaWZmZXJlbnQgc3dhcGNoYWlucyBvciByZW5kZXJ0YXJnZXRzIHdpbGwgaGF2ZSB0byBkdXBsaWNhdGUgdGhlCiAgICAgICAgKiBzdGVuY2lsIGJ1ZmZlciBhbmQgaW5jdXJlIGFuIGV4dHJhIG1lbW9yeSBvdmVyaGVhZAogICAgICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgICAgIHRtcCA9IFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQ7CiAgICAgICAgVGhpcy0+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+YkN1cnNvclZpc2libGUgPSBiU2hvdzsKICAgICAgICBpZiAoYlNob3cpCiAgICAgICAgICAgIFNldEN1cnNvcihUaGlzLT5oYXJkd2FyZUN1cnNvcik7CiAgICAgICAgZWxzZQogICAgICAgICAgICBTZXRDdXJzb3IoTlVMTCk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaWYgKFRoaXMtPmN1cnNvclRleHR1cmUpCiAgICAgICAgICAgIFRoaXMtPmJDdXJzb3JWaXNpYmxlID0gYlNob3c7CiAgICB9CgogICAgcmV0dXJuIG9sZFZpc2libGU7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9UZXN0Q29vcGVyYXRpdmVMZXZlbChJV2luZUQzRERldmljZSogaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFJlc291cmNlSW1wbCAqcmVzb3VyY2U7CiAgICBUUkFDRSgiKCVwKSA6IHN0YXRlICgldSlcbiIsIFRoaXMsIFRoaXMtPnN0YXRlKTsKCiAgICAvKiBUT0RPOiBJbXBsZW1lbnQgd3JhcHBpbmcgb2YgdGhlIFduZFByb2Mgc28gdGhhdCBtaW1pbWl6ZSBhbmQgbWF4YW1pc2UgY2FuIGJlIG1vbml0b3JlZCBhbmQgdGhlIHN0YXRlcyBhZGp1c3RlZC4gKi8KICAgIHN3aXRjaCAoVGhpcy0+c3RhdGUpIHsKICAgIGNhc2UgV0lORUQzRF9PSzoKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIGNhc2UgV0lORUQzREVSUl9ERVZJQ0VMT1NUOgogICAgICAgIHsKICAgICAgICAgICAgTElTVF9GT1JfRUFDSF9FTlRSWShyZXNvdXJjZSwgJlRoaXMtPnJlc291cmNlcywgSVdpbmVEM0RSZXNvdXJjZUltcGwsIHJlc291cmNlLnJlc291cmNlX2xpc3RfZW50cnkpIHsKICAgICAgICAgICAgICAgIGlmIChyZXNvdXJjZS0+cmVzb3VyY2UucG9vbCA9PSBXSU5FRDNEUE9PTF9ERUZBVUxUKQogICAgICAgICAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0RFVklDRU5PVFJFU0VUOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0RFVklDRUxPU1Q7CiAgICAgICAgfQogICAgY2FzZSBXSU5FRDNERVJSX0RSSVZFUklOVEVSTkFMRVJST1I6CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfRFJJVkVSSU5URVJOQUxFUlJPUjsKICAgIH0KCiAgICAvKiBVbmtub3duIHN0YXRlICovCiAgICByZXR1cm4gV0lORUQzREVSUl9EUklWRVJJTlRFUk5BTEVSUk9SOwp9CgoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0V2aWN0TWFuYWdlZFJlc291cmNlcyhJV2luZUQzRERldmljZSogaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICAvKiogRklYTUU6IFJlc291cmNlIHRyYWNraW5nIG5lZWRzIHRvIGJlIGRvbmUsCiAgICAqIFRoZSBjbG9zZXMgd2UgY2FuIGRvIHRvIHRoaXMgaXMgc2V0IHRoZSBwcmlvcml0aWVzIG9mIGFsbCBtYW5hZ2VkIHRleHR1cmVzIGxvdwogICAgKiBhbmQgdGhlbiByZXNldCB0aGVtLgogICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgRklYTUUoIiglcCkgOiBzdHViXG4iLCBUaGlzKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgdm9pZCB1cGRhdGVTdXJmYWNlRGVzYyhJV2luZUQzRFN1cmZhY2VJbXBsICpzdXJmYWNlLCBXSU5FRDNEUFJFU0VOVF9QQVJBTUVURVJTKiBwUHJlc2VudGF0aW9uUGFyYW1ldGVycykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gc3VyZmFjZS0+cmVzb3VyY2Uud2luZUQzRERldmljZTsgLyogZm9yIEdMX1NVUFBPUlQgKi8KCiAgICAvKiBSZWFsbG9jYXRlIHByb3BlciBtZW1vcnkgZm9yIHRoZSBmcm9udCBhbmQgYmFjayBidWZmZXIgYW5kIGFkanVzdCB0aGVpciBzaXplcyAqLwogICAgaWYoc3VyZmFjZS0+RmxhZ3MgJiBTRkxBR19ESUJTRUNUSU9OKSB7CiAgICAgICAgLyogUmVsZWFzZSB0aGUgREMgKi8KICAgICAgICBTZWxlY3RPYmplY3Qoc3VyZmFjZS0+aERDLCBzdXJmYWNlLT5kaWIuaG9sZGJpdG1hcCk7CiAgICAgICAgRGVsZXRlREMoc3VyZmFjZS0+aERDKTsKICAgICAgICAvKiBSZWxlYXNlIHRoZSBESUIgc2VjdGlvbiAqLwogICAgICAgIERlbGV0ZU9iamVjdChzdXJmYWNlLT5kaWIuRElCc2VjdGlvbik7CiAgICAgICAgc3VyZmFjZS0+ZGliLmJpdG1hcF9kYXRhID0gTlVMTDsKICAgICAgICBzdXJmYWNlLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBOVUxMOwogICAgICAgIHN1cmZhY2UtPkZsYWdzICY9IH5TRkxBR19ESUJTRUNUSU9OOwogICAgfQogICAgc3VyZmFjZS0+Y3VycmVudERlc2MuV2lkdGggPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoOwogICAgc3VyZmFjZS0+Y3VycmVudERlc2MuSGVpZ2h0ID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQ7CiAgICBpZiAoR0xfU1VQUE9SVChBUkJfVEVYVFVSRV9OT05fUE9XRVJfT0ZfVFdPKSkgewogICAgICAgIHN1cmZhY2UtPnBvdzJXaWR0aCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGg7CiAgICAgICAgc3VyZmFjZS0+cG93MkhlaWdodCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0OwogICAgfSBlbHNlIHsKICAgICAgICBzdXJmYWNlLT5wb3cyV2lkdGggPSBzdXJmYWNlLT5wb3cySGVpZ2h0ID0gMTsKICAgICAgICB3aGlsZSAoc3VyZmFjZS0+cG93MldpZHRoIDwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aCkgc3VyZmFjZS0+cG93MldpZHRoIDw8PSAxOwogICAgICAgIHdoaWxlIChzdXJmYWNlLT5wb3cySGVpZ2h0IDwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQpIHN1cmZhY2UtPnBvdzJIZWlnaHQgPDw9IDE7CiAgICB9CiAgICBpZihzdXJmYWNlLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKSB7CiAgICAgICAgQWN0aXZhdGVDb250ZXh0KFRoaXMsIFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQsIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICBnbERlbGV0ZVRleHR1cmVzKDEsICZzdXJmYWNlLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgIHN1cmZhY2UtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUgPSAwOwogICAgICAgIHN1cmZhY2UtPkZsYWdzICY9IH5TRkxBR19DTElFTlQ7CiAgICB9CiAgICBpZihzdXJmYWNlLT5wb3cyV2lkdGggIT0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aCB8fAogICAgICAgc3VyZmFjZS0+cG93MkhlaWdodCAhPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodCkgewogICAgICAgIHN1cmZhY2UtPkZsYWdzIHw9IFNGTEFHX05PTlBPVzI7CiAgICB9IGVsc2UgIHsKICAgICAgICBzdXJmYWNlLT5GbGFncyAmPSB+U0ZMQUdfTk9OUE9XMjsKICAgIH0KICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHN1cmZhY2UtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7CiAgICBzdXJmYWNlLT5yZXNvdXJjZS5zaXplID0gSVdpbmVEM0RTdXJmYWNlX0dldFBpdGNoKChJV2luZUQzRFN1cmZhY2UgKikgc3VyZmFjZSkgKiBzdXJmYWNlLT5wb3cyV2lkdGg7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfUmVzZXQoSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBXSU5FRDNEUFJFU0VOVF9QQVJBTUVURVJTKiBwUHJlc2VudGF0aW9uUGFyYW1ldGVycykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEU3dhcENoYWluSW1wbCAqc3dhcGNoYWluOwogICAgSFJFU1VMVCBocjsKICAgIEJPT0wgRGlzcGxheU1vZGVDaGFuZ2VkID0gRkFMU0U7CiAgICBXSU5FRDNERElTUExBWU1PREUgbW9kZTsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICBociA9IElXaW5lRDNERGV2aWNlX0dldFN3YXBDaGFpbihpZmFjZSwgMCwgKElXaW5lRDNEU3dhcENoYWluICoqKSAmc3dhcGNoYWluKTsKICAgIGlmKEZBSUxFRChocikpIHsKICAgICAgICBFUlIoIkZhaWxlZCB0byBnZXQgdGhlIGZpcnN0IGltcGxpY2l0IHN3YXBjaGFpblxuIik7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIC8qIElzIGl0IG5lY2Vzc2FyeSB0byByZWNyZWF0ZSB0aGUgZ2wgY29udGV4dD8gQWN0dWFsbHkgZXZlcnkgc2V0dGluZyBjYW4gYmUgY2hhbmdlZAogICAgICogb24gYW4gZXhpc3RpbmcgZ2wgY29udGV4dCwgc28gdGhlcmUncyBubyByZWFsIG5lZWQgZm9yIHJlY3JlYXRpb24uCiAgICAgKgogICAgICogVE9ETzogRmlndXJlIG91dCBob3cgUmVzZXQgaW5mbHVlbmNlcyByZXNvdXJjZXMgaW4gRDNEUE9PTF9ERUZBVUxULCBEM0RQT09MX1NZU1RFTU1FTU9SWSBhbmQgRDNEUE9PTF9NQU5BR0VECiAgICAgKgogICAgICogVE9ETzogRmlndXJlIG91dCB3aGF0IGhhcHBlbnMgdG8gZXhwbGljaXQgc3dhcGNoYWlucywgb3IgaWYgd2UgaGF2ZSBtb3JlIHRoYW4gb25lIGltcGxpY2l0IHN3YXBjaGFpbgogICAgICovCiAgICBUUkFDRSgiTmV3IHBhcmFtczpcbiIpOwogICAgVFJBQ0UoIkJhY2tCdWZmZXJXaWR0aCA9ICVkXG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoKTsKICAgIFRSQUNFKCJCYWNrQnVmZmVySGVpZ2h0ID0gJWRcbiIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0KTsKICAgIFRSQUNFKCJCYWNrQnVmZmVyRm9ybWF0ID0gJXNcbiIsIGRlYnVnX2QzZGZvcm1hdChwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckZvcm1hdCkpOwogICAgVFJBQ0UoIkJhY2tCdWZmZXJDb3VudCA9ICVkXG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckNvdW50KTsKICAgIFRSQUNFKCJNdWx0aVNhbXBsZVR5cGUgPSAlZFxuIiwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPk11bHRpU2FtcGxlVHlwZSk7CiAgICBUUkFDRSgiTXVsdGlTYW1wbGVRdWFsaXR5ID0gJWRcbiIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5NdWx0aVNhbXBsZVF1YWxpdHkpOwogICAgVFJBQ0UoIlN3YXBFZmZlY3QgPSAlZFxuIiwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPlN3YXBFZmZlY3QpOwogICAgVFJBQ0UoImhEZXZpY2VXaW5kb3cgPSAlcFxuIiwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPmhEZXZpY2VXaW5kb3cpOwogICAgVFJBQ0UoIldpbmRvd2VkID0gJXNcbiIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5XaW5kb3dlZCA/ICJ0cnVlIiA6ICJmYWxzZSIpOwogICAgVFJBQ0UoIkVuYWJsZUF1dG9EZXB0aFN0ZW5jaWwgPSAlc1xuIiwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkVuYWJsZUF1dG9EZXB0aFN0ZW5jaWwgPyAidHJ1ZSIgOiAiZmFsc2UiKTsKICAgIFRSQUNFKCJGbGFncyA9ICUwOHhcbiIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5GbGFncyk7CiAgICBUUkFDRSgiRnVsbFNjcmVlbl9SZWZyZXNoUmF0ZUluSHogPSAlZFxuIiwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkZ1bGxTY3JlZW5fUmVmcmVzaFJhdGVJbkh6KTsKICAgIFRSQUNFKCJQcmVzZW50YXRpb25JbnRlcnZhbCA9ICVkXG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+UHJlc2VudGF0aW9uSW50ZXJ2YWwpOwoKICAgIC8qIE5vIHNwZWNpYWwgdHJlYXRtZW50IG9mIHRoZXNlIHBhcmFtZXRlcnMuIEp1c3Qgc3RvcmUgdGhlbSAqLwogICAgc3dhcGNoYWluLT5wcmVzZW50UGFybXMuU3dhcEVmZmVjdCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5Td2FwRWZmZWN0OwogICAgc3dhcGNoYWluLT5wcmVzZW50UGFybXMuRmxhZ3MgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+RmxhZ3M7CiAgICBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5QcmVzZW50YXRpb25JbnRlcnZhbCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5QcmVzZW50YXRpb25JbnRlcnZhbDsKICAgIHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLkZ1bGxTY3JlZW5fUmVmcmVzaFJhdGVJbkh6ID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkZ1bGxTY3JlZW5fUmVmcmVzaFJhdGVJbkh6OwoKICAgIC8qIFdoYXQgdG8gZG8gYWJvdXQgdGhlc2U/ICovCiAgICBpZihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckNvdW50ICE9IDAgJiYKICAgICAgICBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckNvdW50ICE9IHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJDb3VudCkgewogICAgICAgIEVSUigiQ2Fubm90IGNoYW5nZSB0aGUgYmFjayBidWZmZXIgY291bnQgeWV0XG4iKTsKICAgIH0KICAgIGlmKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyRm9ybWF0ICE9IFdJTkVEM0RGTVRfVU5LTk9XTiAmJgogICAgICAgIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyRm9ybWF0ICE9IHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJGb3JtYXQpIHsKICAgICAgICBFUlIoIkNhbm5vdCBjaGFuZ2UgdGhlIGJhY2sgYnVmZmVyIGZvcm1hdCB5ZXRcbiIpOwogICAgfQogICAgaWYocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPmhEZXZpY2VXaW5kb3cgIT0gTlVMTCAmJgogICAgICAgIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5oRGV2aWNlV2luZG93ICE9IHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLmhEZXZpY2VXaW5kb3cpIHsKICAgICAgICBFUlIoIkNhbm5vdCBjaGFuZ2UgdGhlIGRldmljZSB3aW5kb3cgeWV0XG4iKTsKICAgIH0KICAgIGlmKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5FbmFibGVBdXRvRGVwdGhTdGVuY2lsICE9IHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLkVuYWJsZUF1dG9EZXB0aFN0ZW5jaWwpIHsKICAgICAgICBFUlIoIldoYXQgZG8gZG8gYWJvdXQgYSBjaGFuZ2VkIGF1dG8gZGVwdGggc3RlbmNpbCBwYXJhbWV0ZXI/XG4iKTsKICAgIH0KCiAgICBpZihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+V2luZG93ZWQpIHsKICAgICAgICBtb2RlLldpZHRoID0gc3dhcGNoYWluLT5vcmlnX3dpZHRoOwogICAgICAgIG1vZGUuSGVpZ2h0ID0gc3dhcGNoYWluLT5vcmlnX2hlaWdodDsKICAgICAgICBtb2RlLlJlZnJlc2hSYXRlID0gMDsKICAgICAgICBtb2RlLkZvcm1hdCA9IHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJGb3JtYXQ7CiAgICB9IGVsc2UgewogICAgICAgIG1vZGUuV2lkdGggPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoOwogICAgICAgIG1vZGUuSGVpZ2h0ID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQ7CiAgICAgICAgbW9kZS5SZWZyZXNoUmF0ZSA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5GdWxsU2NyZWVuX1JlZnJlc2hSYXRlSW5IejsKICAgICAgICBtb2RlLkZvcm1hdCA9IHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJGb3JtYXQ7CiAgICB9CgogICAgLyogU2hvdWxkIFdpZHRoID09IDgwMCAmJiBIZWlnaHQgPT0gMCBzZXQgODAweDYwMD8gKi8KICAgIGlmKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGggIT0gMCAmJiBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodCAhPSAwICYmCiAgICAgICAocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aCAhPSBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyV2lkdGggfHwKICAgICAgICBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodCAhPSBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVySGVpZ2h0KSkKICAgIHsKICAgICAgICBXSU5FRDNEVklFV1BPUlQgdnA7CiAgICAgICAgaW50IGk7CgogICAgICAgIHZwLlggPSAwOwogICAgICAgIHZwLlkgPSAwOwogICAgICAgIHZwLldpZHRoID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aDsKICAgICAgICB2cC5IZWlnaHQgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodDsKICAgICAgICB2cC5NaW5aID0gMDsKICAgICAgICB2cC5NYXhaID0gMTsKCiAgICAgICAgaWYoIXBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5XaW5kb3dlZCkgewogICAgICAgICAgICBEaXNwbGF5TW9kZUNoYW5nZWQgPSBUUlVFOwogICAgICAgIH0KICAgICAgICBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyV2lkdGggPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoOwogICAgICAgIHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJIZWlnaHQgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodDsKCiAgICAgICAgdXBkYXRlU3VyZmFjZURlc2MoKElXaW5lRDNEU3VyZmFjZUltcGwgKilzd2FwY2hhaW4tPmZyb250QnVmZmVyLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycyk7CiAgICAgICAgZm9yKGkgPSAwOyBpIDwgc3dhcGNoYWluLT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckNvdW50OyBpKyspIHsKICAgICAgICAgICAgdXBkYXRlU3VyZmFjZURlc2MoKElXaW5lRDNEU3VyZmFjZUltcGwgKilzd2FwY2hhaW4tPmJhY2tCdWZmZXJbaV0sIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzKTsKICAgICAgICB9CgogICAgICAgIC8qIE5vdyBzZXQgdGhlIG5ldyB2aWV3cG9ydCAqLwogICAgICAgIElXaW5lRDNERGV2aWNlX1NldFZpZXdwb3J0KGlmYWNlLCAmdnApOwogICAgfQoKICAgIGlmKChwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+V2luZG93ZWQgJiYgIXN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLldpbmRvd2VkKSB8fAogICAgICAgKHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLldpbmRvd2VkICYmICFwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+V2luZG93ZWQpIHx8CiAgICAgICAgRGlzcGxheU1vZGVDaGFuZ2VkKSB7CgogICAgICAgIC8qIFN3aXRjaGluZyB0byBmdWxsc2NyZWVuPyBDaGFuZ2UgdG8gZnVsbHNjcmVlbiBtb2RlLCBUSEVOIGNoYW5nZSB0aGUgc2NyZWVuIHJlcyAqLwogICAgICAgIGlmKCFwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+V2luZG93ZWQpIHsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0RnVsbHNjcmVlbihpZmFjZSwgVFJVRSk7CiAgICAgICAgfQoKICAgICAgICBJV2luZUQzRERldmljZV9TZXREaXNwbGF5TW9kZShpZmFjZSwgMCwgJm1vZGUpOwoKICAgICAgICAvKiBTd2l0Y2hpbmcgb3V0IG9mIGZ1bGxzY3JlZW4gbW9kZT8gRmlyc3Qgc2V0IHRoZSBvcmlnaW5hbCByZXMsIHRoZW4gY2hhbmdlIHRoZSB3aW5kb3cgKi8KICAgICAgICBpZihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+V2luZG93ZWQpIHsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0RnVsbHNjcmVlbihpZmFjZSwgRkFMU0UpOwogICAgICAgIH0KICAgICAgICBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5XaW5kb3dlZCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5XaW5kb3dlZDsKICAgIH0KCiAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKChJV2luZUQzRFN3YXBDaGFpbiAqKSBzd2FwY2hhaW4pOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0RGlhbG9nQm94TW9kZShJV2luZUQzRERldmljZSAqaWZhY2UsIEJPT0wgYkVuYWJsZURpYWxvZ3MpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIC8qKiBGSVhNRTogYWx3YXlzIHRydWUgYXQgdGhlIG1vbWVudCAqKi8KICAgIGlmKCFiRW5hYmxlRGlhbG9ncykgewogICAgICAgIEZJWE1FKCIoJXApIERpYWxvZ3MgY2Fubm90IGJlIGRpc2FibGVkIHlldFxuIiwgVGhpcyk7CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRDcmVhdGlvblBhcmFtZXRlcnMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEREVWSUNFX0NSRUFUSU9OX1BBUkFNRVRFUlMgKnBQYXJhbWV0ZXJzKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiBwUGFyYW1ldGVycyAlcFxuIiwgVGhpcywgcFBhcmFtZXRlcnMpOwoKICAgICpwUGFyYW1ldGVycyA9IFRoaXMtPmNyZWF0ZVBhcm1zOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0R2FtbWFSYW1wKElXaW5lRDNERGV2aWNlICogaWZhY2UsIFVJTlQgaVN3YXBDaGFpbiwgRFdPUkQgRmxhZ3MsIENPTlNUIFdJTkVEM0RHQU1NQVJBTVAqIHBSYW1wKSB7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcGNoYWluOwogICAgSFJFU1VMVCBocmMgPSBXSU5FRDNEX09LOwoKICAgIFRSQUNFKCJSZWxheWluZyAgdG8gc3dhcGNoYWluXG4iKTsKCiAgICBpZiAoKGhyYyA9IElXaW5lRDNERGV2aWNlSW1wbF9HZXRTd2FwQ2hhaW4oaWZhY2UsIGlTd2FwQ2hhaW4sICZzd2FwY2hhaW4pKSA9PSBXSU5FRDNEX09LKSB7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fU2V0R2FtbWFSYW1wKHN3YXBjaGFpbiwgRmxhZ3MsIChXSU5FRDNER0FNTUFSQU1QICopcFJhbXApOwogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2Uoc3dhcGNoYWluKTsKICAgIH0KICAgIHJldHVybjsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRHYW1tYVJhbXAoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIGlTd2FwQ2hhaW4sIFdJTkVEM0RHQU1NQVJBTVAqIHBSYW1wKSB7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcGNoYWluOwogICAgSFJFU1VMVCBocmMgPSBXSU5FRDNEX09LOwoKICAgIFRSQUNFKCJSZWxheWluZyAgdG8gc3dhcGNoYWluXG4iKTsKCiAgICBpZiAoKGhyYyA9IElXaW5lRDNERGV2aWNlSW1wbF9HZXRTd2FwQ2hhaW4oaWZhY2UsIGlTd2FwQ2hhaW4sICZzd2FwY2hhaW4pKSA9PSBXSU5FRDNEX09LKSB7CiAgICAgICAgaHJjID1JV2luZUQzRFN3YXBDaGFpbl9HZXRHYW1tYVJhbXAoc3dhcGNoYWluLCBwUmFtcCk7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwY2hhaW4pOwogICAgfQogICAgcmV0dXJuOwp9CgoKLyoqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiogICBOb3RpZmljYXRpb24gZnVuY3Rpb25zCioqICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKiogVGhpcyBmdW5jdGlvbiBtdXN0IGJlIGNhbGxlZCBpbiB0aGUgcmVsZWFzZSBvZiBhIHJlc291cmNlIHdoZW4gcmVmID09IDAsCiogdGhlIGNvbnRlbnRzIG9mIHJlc291cmNlIG11c3Qgc3RpbGwgYmUgY29ycmVjdCwKKiBhbnkgaGFuZGVscyB0byBvdGhlciByZXNvdXJjZSBoZWxkIGJ5IHRoZSBjYWxsZXIgbXVzdCBiZSBjbG9zZWQKKiAoZS5nLiBhIHRleHR1cmUgc2hvdWxkIHJlbGVhc2UgYWxsIGhlbGQgc3VyZmFjZXMgYmVjYXVzZSB0ZWxsaW5nIHRoZSBkZXZpY2UgdGhhdCBpdCdzIGJlZW4gcmVsZWFzZWQuKQogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyB2b2lkIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQWRkUmVzb3VyY2UoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFJlc291cmNlICpyZXNvdXJjZSl7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCkgOiBBZGRpbmcgUmVzb3VyY2UgJXBcbiIsIFRoaXMsIHJlc291cmNlKTsKICAgIGxpc3RfYWRkX2hlYWQoJlRoaXMtPnJlc291cmNlcywgJigoSVdpbmVEM0RSZXNvdXJjZUltcGwgKikgcmVzb3VyY2UpLT5yZXNvdXJjZS5yZXNvdXJjZV9saXN0X2VudHJ5KTsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9SZW1vdmVSZXNvdXJjZShJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEUmVzb3VyY2UgKnJlc291cmNlKXsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKSA6IFJlbW92aW5nIHJlc291cmNlICVwXG4iLCBUaGlzLCByZXNvdXJjZSk7CgogICAgbGlzdF9yZW1vdmUoJigoSVdpbmVEM0RSZXNvdXJjZUltcGwgKikgcmVzb3VyY2UpLT5yZXNvdXJjZS5yZXNvdXJjZV9saXN0X2VudHJ5KTsKfQoKCnN0YXRpYyB2b2lkIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfUmVzb3VyY2VSZWxlYXNlZChJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEUmVzb3VyY2UgKnJlc291cmNlKXsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBpbnQgY291bnRlcjsKCiAgICBUUkFDRSgiKCVwKSA6IHJlc291cmNlICVwXG4iLCBUaGlzLCByZXNvdXJjZSk7CiAgICBzd2l0Y2goSVdpbmVEM0RSZXNvdXJjZV9HZXRUeXBlKHJlc291cmNlKSl7CiAgICAgICAgLyogVE9ETzogY2hlY2sgZnJvbnQgYW5kIGJhY2sgYnVmZmVycywgcmVuZGVydGFyZ2V0cyBldGMuLiAgcG9zc2libHkgc3dhcGNoYWlucz8gKi8KICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9TVVJGQUNFOiB7CiAgICAgICAgICAgIHVuc2lnbmVkIGludCBpOwoKICAgICAgICAgICAgLyogQ2xlYW51cCBhbnkgRkJPIGF0dGFjaG1lbnRzIGlmIGQzZCBpcyBlbmFibGVkICovCiAgICAgICAgICAgIGlmKFRoaXMtPmQzZF9pbml0aWFsaXplZCkgewogICAgICAgICAgICAgICAgaWYoKElXaW5lRDNEU3VyZmFjZSAqKXJlc291cmNlID09IFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQpIHsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN3YXBDaGFpbkltcGwgKnN3YXBjaGFpbiA9IFRoaXMtPnN3YXBjaGFpbnMgPyAoSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICopIFRoaXMtPnN3YXBjaGFpbnNbMF0gOiBOVUxMOwoKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiTGFzdCBhY3RpdmUgcmVuZGVyIHRhcmdldCBkZXN0cm95ZWRcbiIpOwogICAgICAgICAgICAgICAgICAgIC8qIEZpbmQgYSByZXBsYWNlbWVudCBzdXJmYWNlIGZvciB0aGUgY3VycmVudGx5IGFjdGl2ZSBiYWNrIGJ1ZmZlci4gVGhlIGNvbnRleHQgbWFuYWdlciBkb2VzIG5vdCBkbyBOVUxMCiAgICAgICAgICAgICAgICAgICAgICogY2hlY2tzLCBzbyBzd2l0Y2ggdG8gYSB2YWxpZCB0YXJnZXQgYXMgbG9uZyBhcyB0aGUgY3VycmVudGx5IHNldCBzdXJmYWNlIGlzIHN0aWxsIHZhbGlkLiBVc2UgdGhlCiAgICAgICAgICAgICAgICAgICAgICogc3VyZmFjZSBvZiB0aGUgaW1wbGljaXQgc3dwY2hhaW4uIElmIHRoYXQgaXMgdGhlIHNhbWUgYXMgdGhlIGRlc3Ryb3llZCBzdXJmYWNlIHRoZSBkZXZpY2UgaXMgZGVzdHJveWVkCiAgICAgICAgICAgICAgICAgICAgICogYW5kIHRoZSBsYXN0QWN0aXZlUmVuZGVyVGFyZ2V0IG1lbWJlciBzaG91bGRuJ3QgbWF0dGVyCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgaWYoc3dhcGNoYWluKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKHN3YXBjaGFpbi0+YmFja0J1ZmZlciAmJiBzd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0gIT0gKElXaW5lRDNEU3VyZmFjZSAqKXJlc291cmNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUkFDRSgiQWN0aXZhdGluZyBwcmltYXJ5IGJhY2sgYnVmZmVyXG4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBzd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0sIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZighc3dhcGNoYWluLT5iYWNrQnVmZmVyICYmIHN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIgIT0gKElXaW5lRDNEU3VyZmFjZSAqKXJlc291cmNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBTaW5nbGUgYnVmZmVyaW5nIGVudmlyb25tZW50ICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUkFDRSgiQWN0aXZhdGluZyBwcmltYXJ5IGZyb250IGJ1ZmZlclxuIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBBY3RpdmF0ZUNvbnRleHQoVGhpcywgc3dhcGNoYWluLT5mcm9udEJ1ZmZlciwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFKCJEZXZpY2UgaXMgYmVpbmcgZGVzdHJveWVkLCBzZXR0aW5nIGxhc3RBY3RpdmVSZW5kZXJUYXJnZXQgPSAweGRlYWRiYWJlXG4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIEltcGxpY2l0IHJlbmRlciB0YXJnZXQgZGVzdHJveWVkLCB0aGF0IG1lYW5zIHRoZSBkZXZpY2UgaXMgYmVpbmcgZGVzdHJveWVkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiB3aGF0ZXZlciB3ZSBzZXQgaGVyZSwgaXQgc2hvdWxkbid0IG1hdHRlcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0ID0gKElXaW5lRDNEU3VyZmFjZSAqKSAweGRlYWRiYWJlOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogTWF5IGhhcHBlbiBkdXJpbmcgZGRyYXcgdW5pbml0aWFsaXphdGlvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICBUUkFDRSgiUmVuZGVyIHRhcmdldCBzZXQsIGJ1dCBzd2FwY2hhaW4gZG9lcyBub3QgZXhpc3QhXG4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCA9IChJV2luZUQzRFN1cmZhY2UgKikgMHhkZWFkY2FmZTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IEdMX0xJTUlUUyhidWZmZXJzKTsgKytpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKFRoaXMtPmZib19jb2xvcl9hdHRhY2htZW50c1tpXSA9PSAoSVdpbmVEM0RTdXJmYWNlICopcmVzb3VyY2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgYmluZF9mYm8oaWZhY2UsIEdMX0ZSQU1FQlVGRkVSX0VYVCwgJlRoaXMtPmZibyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHNldF9yZW5kZXJfdGFyZ2V0X2ZibyhpZmFjZSwgaSwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmZib19jb2xvcl9hdHRhY2htZW50c1tpXSA9IE5VTEw7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKFRoaXMtPmZib19kZXB0aF9hdHRhY2htZW50ID09IChJV2luZUQzRFN1cmZhY2UgKilyZXNvdXJjZSkgewogICAgICAgICAgICAgICAgICAgIGJpbmRfZmJvKGlmYWNlLCBHTF9GUkFNRUJVRkZFUl9FWFQsICZUaGlzLT5mYm8pOwogICAgICAgICAgICAgICAgICAgIHNldF9kZXB0aF9zdGVuY2lsX2ZibyhpZmFjZSwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgVGhpcy0+ZmJvX2RlcHRoX2F0dGFjaG1lbnQgPSBOVUxMOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY2FzZSBXSU5FRDNEUlRZUEVfVEVYVFVSRToKICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9DVUJFVEVYVFVSRToKICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9WT0xVTUVURVhUVVJFOgogICAgICAgICAgICAgICAgZm9yIChjb3VudGVyID0gMDsgY291bnRlciA8IE1BWF9DT01CSU5FRF9TQU1QTEVSUzsgY291bnRlcisrKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKFRoaXMtPnN0YXRlQmxvY2sgIT0gTlVMTCAmJiBUaGlzLT5zdGF0ZUJsb2NrLT50ZXh0dXJlc1tjb3VudGVyXSA9PSAoSVdpbmVEM0RCYXNlVGV4dHVyZSAqKXJlc291cmNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFdBUk4oIlRleHR1cmUgYmVpbmcgcmVsZWFzZWQgaXMgc3RpbGwgYnkgYSBzdGF0ZWJsb2NrLCBTdGFnZSA9ICV1IFRleHR1cmUgPSAlcFxuIiwgY291bnRlciwgcmVzb3VyY2UpOwogICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT50ZXh0dXJlc1tjb3VudGVyXSA9IE5VTEw7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChUaGlzLT51cGRhdGVTdGF0ZUJsb2NrICE9IFRoaXMtPnN0YXRlQmxvY2sgKXsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRleHR1cmVzW2NvdW50ZXJdID09IChJV2luZUQzREJhc2VUZXh0dXJlICopcmVzb3VyY2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdBUk4oIlRleHR1cmUgYmVpbmcgcmVsZWFzZWQgaXMgc3RpbGwgYnkgYSBzdGF0ZWJsb2NrLCBTdGFnZSA9ICV1IFRleHR1cmUgPSAlcFxuIiwgY291bnRlciwgcmVzb3VyY2UpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZXNbY291bnRlcl0gPSBOVUxMOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgV0lORUQzRFJUWVBFX1ZPTFVNRToKICAgICAgICAvKiBUT0RPOiBub3RoaW5nIHJlYWxseT8gKi8KICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9WRVJURVhCVUZGRVI6CiAgICAgICAgLyogTVNETjogV2hlbiBhbiBhcHBsaWNhdGlvbiBubyBsb25nZXIgaG9sZHMgYSByZWZlcmVuY2VzIHRvIHRoaXMgaW50ZXJmYWNlLCB0aGUgaW50ZXJmYWNlIHdpbGwgYXV0b21hdGljYWxseSBiZSBmcmVlZC4gKi8KICAgICAgICB7CiAgICAgICAgICAgIGludCBzdHJlYW1OdW1iZXI7CiAgICAgICAgICAgIFRSQUNFKCJDbGVhbmluZyB1cCBzdHJlYW0gcG9pbnRlcnNcbiIpOwoKICAgICAgICAgICAgZm9yKHN0cmVhbU51bWJlciA9IDA7IHN0cmVhbU51bWJlciA8IE1BWF9TVFJFQU1TOyBzdHJlYW1OdW1iZXIgKyspewogICAgICAgICAgICAgICAgLyogRklORE9VVDogc2hvdWxkIGEgd2FybiBiZSBnZW5lcmF0ZWQgaWYgd2VyZSByZWNvcmRpbmcgYW5kIHVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZSBpcyBsb3N0PwogICAgICAgICAgICAgICAgRklORE9VVDogc2hvdWxkIGNoYW5nZXMuc3RyZWFtU291cmNlW1N0cmVhbU51bWJlcl0gYmUgc2V0ID8KICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAoVGhpcy0+dXBkYXRlU3RhdGVCbG9jayAhPSBOVUxMICkgeyAvKiA9PU5VTEwgd2hlbiBkZXZpY2UgaXMgYmVpbmcgZGVzdHJveWVkICovCiAgICAgICAgICAgICAgICAgICAgaWYgKChJV2luZUQzRFJlc291cmNlICopVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c3RyZWFtU291cmNlW3N0cmVhbU51bWJlcl0gPT0gcmVzb3VyY2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgRklYTUUoIlZlcnRleCBidWZmZXIgcmVsZWFzZWQgd2hpbGUgYm91bmQgdG8gYSBzdGF0ZSBibG9jaywgc3RyZWFtICVkXG4iLCBzdHJlYW1OdW1iZXIpOwogICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2Vbc3RyZWFtTnVtYmVyXSA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFNldCBjaGFuZ2VkIGZsYWc/ICovCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKFRoaXMtPnN0YXRlQmxvY2sgIT0gTlVMTCApIHsgLyogb25seSBoYXBwZW5zIGlmIHRoZXJlIGlzIGFuIGVycm9yIGluIHRoZSBhcHBsaWNhdGlvbiwgb3Igb24gcmVzZXQvcmVsZWFzZSAoYmVjYXVzZSB3ZSBkb24ndCBtYW5hZ2UgaW50ZXJuYWwgdHJhY2tpbmcgcHJvcGVybHkpICovCiAgICAgICAgICAgICAgICAgICAgaWYgKChJV2luZUQzRFJlc291cmNlICopVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlW3N0cmVhbU51bWJlcl0gPT0gcmVzb3VyY2UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlZlcnRleCBidWZmZXIgcmVsZWFzZWQgd2hpbGUgYm91bmQgdG8gYSBzdGF0ZSBibG9jaywgc3RyZWFtICVkXG4iLCBzdHJlYW1OdW1iZXIpOwogICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2Vbc3RyZWFtTnVtYmVyXSA9IDA7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQojaWYgMCAgIC8qIFRPRE86IE1hbmFnZSBpbnRlcm5hbCB0cmFja2luZyBwcm9wZXJseSBzbyB0aGF0ICd0aGlzIHNob3VsZG4ndCBoYXBwZW4nICovCiAgICAgICAgICAgICAgICAgZWxzZSB7IC8qIFRoaXMgc2hvdWxkbid0IGhhcHBlbiAqLwogICAgICAgICAgICAgICAgICAgIEZJWE1FKCJDYWxsaW5nIGFwcGxpY2F0aW9uIGhhcyByZWxlYXNlZCB0aGUgZGV2aWNlIGJlZm9yZSByZWxhc2luZyBhbGwgdGhlIHJlc291cmNlcyBib3VuZCB0byB0aGUgZGV2aWNlXG4iKTsKICAgICAgICAgICAgICAgIH0KI2VuZGlmCgogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgV0lORUQzRFJUWVBFX0lOREVYQlVGRkVSOgogICAgICAgIC8qIE1TRE46IFdoZW4gYW4gYXBwbGljYXRpb24gbm8gbG9uZ2VyIGhvbGRzIGEgcmVmZXJlbmNlcyB0byB0aGlzIGludGVyZmFjZSwgdGhlIGludGVyZmFjZSB3aWxsIGF1dG9tYXRpY2FsbHkgYmUgZnJlZWQuKi8KICAgICAgICBpZiAoVGhpcy0+dXBkYXRlU3RhdGVCbG9jayAhPSBOVUxMICkgeyAvKiA9PU5VTEwgd2hlbiBkZXZpY2UgaXMgYmVpbmcgZGVzdHJveWVkICovCiAgICAgICAgICAgIGlmIChUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5wSW5kZXhEYXRhID09IChJV2luZUQzREluZGV4QnVmZmVyICopcmVzb3VyY2UpIHsKICAgICAgICAgICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnBJbmRleERhdGEgPSAgTlVMTDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoVGhpcy0+c3RhdGVCbG9jayAhPSBOVUxMICkgeyAvKiA9PU5VTEwgd2hlbiBkZXZpY2UgaXMgYmVpbmcgZGVzdHJveWVkICovCiAgICAgICAgICAgIGlmIChUaGlzLT5zdGF0ZUJsb2NrLT5wSW5kZXhEYXRhID09IChJV2luZUQzREluZGV4QnVmZmVyICopcmVzb3VyY2UpIHsKICAgICAgICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPnBJbmRleERhdGEgPSAgTlVMTDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICBGSVhNRSgiKCVwKSB1bmtub3duIHJlc291cmNlIHR5cGUgJXAgJXVcbiIsIFRoaXMsIHJlc291cmNlLCBJV2luZUQzRFJlc291cmNlX0dldFR5cGUocmVzb3VyY2UpKTsKICAgICAgICBicmVhazsKICAgIH0KCgogICAgLyogUmVtb3ZlIHRoZSByZXNvcnVjZSBmcm9tIHRoZSByZXNvdXJjZVN0b3JlICovCiAgICBJV2luZUQzRERldmljZUltcGxfUmVtb3ZlUmVzb3VyY2UoaWZhY2UsIHJlc291cmNlKTsKCiAgICBUUkFDRSgiUmVzb3VyY2UgcmVsZWFzZWRcbiIpOwoKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0REZXZpY2UgVlRibCBmb2xsb3dzCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKY29uc3QgSVdpbmVEM0REZXZpY2VWdGJsIElXaW5lRDNERGV2aWNlX1Z0YmwgPQp7CiAgICAvKioqIElVbmtub3duIG1ldGhvZHMgKioqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX1F1ZXJ5SW50ZXJmYWNlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0FkZFJlZiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9SZWxlYXNlLAogICAgLyoqKiBJV2luZUQzRERldmljZSBtZXRob2RzICoqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQYXJlbnQsCiAgICAvKioqIENyZWF0aW9uIG1ldGhvZHMqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWZXJ0ZXhCdWZmZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlSW5kZXhCdWZmZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlU3RhdGVCbG9jaywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVTdXJmYWNlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVRleHR1cmUsCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVm9sdW1lVGV4dHVyZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWb2x1bWUsCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlQ3ViZVRleHR1cmUsCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlUXVlcnksCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlQWRkaXRpb25hbFN3YXBDaGFpbiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWZXJ0ZXhEZWNsYXJhdGlvbiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWZXJ0ZXhEZWNsYXJhdGlvbkZyb21GVkYsCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVmVydGV4U2hhZGVyLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVBpeGVsU2hhZGVyLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVBhbGV0dGUsCiAgICAvKioqIE9kZCBmdW5jdGlvbnMgKiovCiAgICBJV2luZUQzRERldmljZUltcGxfSW5pdDNELAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1VuaW5pdDNELAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEZ1bGxzY3JlZW4sCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0TXVsdGl0aHJlYWRlZCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9FdmljdE1hbmFnZWRSZXNvdXJjZXMsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0QXZhaWxhYmxlVGV4dHVyZU1lbSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRCYWNrQnVmZmVyLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldENyZWF0aW9uUGFyYW1ldGVycywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXREZXZpY2VDYXBzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldERpcmVjdDNELAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldERpc3BsYXlNb2RlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldERpc3BsYXlNb2RlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEhXTkQsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0SFdORCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXROdW1iZXJPZlN3YXBDaGFpbnMsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UmFzdGVyU3RhdHVzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFN3YXBDaGFpbiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9SZXNldCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXREaWFsb2dCb3hNb2RlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEN1cnNvclByb3BlcnRpZXMsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0Q3Vyc29yUG9zaXRpb24sCiAgICBJV2luZUQzRERldmljZUltcGxfU2hvd0N1cnNvciwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9UZXN0Q29vcGVyYXRpdmVMZXZlbCwKICAgIC8qKiogR2V0dGVycyBhbmQgc2V0dGVycyAqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRDbGlwUGxhbmUsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0Q2xpcFBsYW5lLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldENsaXBTdGF0dXMsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0Q2xpcFN0YXR1cywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRDdXJyZW50VGV4dHVyZVBhbGV0dGUsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0Q3VycmVudFRleHR1cmVQYWxldHRlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldERlcHRoU3RlbmNpbFN1cmZhY2UsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0RGVwdGhTdGVuY2lsU3VyZmFjZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRGVkYsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0RlZGLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEdhbW1hUmFtcCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRHYW1tYVJhbXAsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0SW5kaWNlcywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRJbmRpY2VzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEJhc2VWZXJ0ZXhJbmRleCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRCYXNlVmVydGV4SW5kZXgsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0TGlnaHQsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0TGlnaHQsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0TGlnaHRFbmFibGUsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0TGlnaHRFbmFibGUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0TWF0ZXJpYWwsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0TWF0ZXJpYWwsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0TlBhdGNoTW9kZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXROUGF0Y2hNb2RlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFBhbGV0dGVFbnRyaWVzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFBhbGV0dGVFbnRyaWVzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFBpeGVsU2hhZGVyLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFBpeGVsU2hhZGVyLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFBpeGVsU2hhZGVyQ29uc3RhbnRCLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFBpeGVsU2hhZGVyQ29uc3RhbnRCLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFBpeGVsU2hhZGVyQ29uc3RhbnRJLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFBpeGVsU2hhZGVyQ29uc3RhbnRJLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFBpeGVsU2hhZGVyQ29uc3RhbnRGLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFBpeGVsU2hhZGVyQ29uc3RhbnRGLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFJlbmRlclN0YXRlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFJlbmRlclN0YXRlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFJlbmRlclRhcmdldCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRSZW5kZXJUYXJnZXQsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0RnJvbnRCYWNrQnVmZmVycywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRTYW1wbGVyU3RhdGUsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0U2FtcGxlclN0YXRlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFNjaXNzb3JSZWN0LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFNjaXNzb3JSZWN0LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFNvZnR3YXJlVmVydGV4UHJvY2Vzc2luZywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTb2Z0d2FyZVZlcnRleFByb2Nlc3NpbmcsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0U3RyZWFtU291cmNlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFN0cmVhbVNvdXJjZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRTdHJlYW1Tb3VyY2VGcmVxLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFN0cmVhbVNvdXJjZUZyZXEsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0VGV4dHVyZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRUZXh0dXJlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFRleHR1cmVTdGFnZVN0YXRlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFRleHR1cmVTdGFnZVN0YXRlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFRyYW5zZm9ybSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRUcmFuc2Zvcm0sCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0VmVydGV4RGVjbGFyYXRpb24sCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0VmVydGV4RGVjbGFyYXRpb24sCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0VmVydGV4U2hhZGVyLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZlcnRleFNoYWRlciwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEIsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0VmVydGV4U2hhZGVyQ29uc3RhbnRCLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZlcnRleFNoYWRlckNvbnN0YW50SSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEksCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0VmVydGV4U2hhZGVyQ29uc3RhbnRGLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZlcnRleFNoYWRlckNvbnN0YW50RiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWaWV3cG9ydCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWaWV3cG9ydCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NdWx0aXBseVRyYW5zZm9ybSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9WYWxpZGF0ZURldmljZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9Qcm9jZXNzVmVydGljZXMsCiAgICAvKioqIFN0YXRlIGJsb2NrICoqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9CZWdpblN0YXRlQmxvY2ssCiAgICBJV2luZUQzRERldmljZUltcGxfRW5kU3RhdGVCbG9jaywKICAgIC8qKiogU2NlbmUgbWFuYWdlbWVudCAqKiovCiAgICBJV2luZUQzRERldmljZUltcGxfQmVnaW5TY2VuZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9FbmRTY2VuZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9QcmVzZW50LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NsZWFyLAogICAgLyoqKiBEcmF3aW5nICoqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3UHJpbWl0aXZlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdJbmRleGVkUHJpbWl0aXZlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdQcmltaXRpdmVVUCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3SW5kZXhlZFByaW1pdGl2ZVVQLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdQcmltaXRpdmVTdHJpZGVkLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdJbmRleGVkUHJpbWl0aXZlU3RyaWRlZCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3UmVjdFBhdGNoLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdUcmlQYXRjaCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9EZWxldGVQYXRjaCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9Db2xvckZpbGwsCiAgICBJV2luZUQzRERldmljZUltcGxfVXBkYXRlVGV4dHVyZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9VcGRhdGVTdXJmYWNlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEZyb250QnVmZmVyRGF0YSwKICAgIC8qKiogb2JqZWN0IHRyYWNraW5nICoqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9SZXNvdXJjZVJlbGVhc2VkCn07CgoKY29uc3QgRFdPUkQgU2F2ZWRQaXhlbFN0YXRlc19SW05VTV9TQVZFRFBJWEVMU1RBVEVTX1JdID0gewogICAgV0lORUQzRFJTX0FMUEhBQkxFTkRFTkFCTEUgICAsCiAgICBXSU5FRDNEUlNfQUxQSEFGVU5DICAgICAgICAgICwKICAgIFdJTkVEM0RSU19BTFBIQVJFRiAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0FMUEhBVEVTVEVOQUJMRSAgICAsCiAgICBXSU5FRDNEUlNfQkxFTkRPUCAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19DT0xPUldSSVRFRU5BQkxFICAgLAogICAgV0lORUQzRFJTX0RFU1RCTEVORCAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRElUSEVSRU5BQkxFICAgICAgICwKICAgIFdJTkVEM0RSU19GSUxMTU9ERSAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0ZPR0RFTlNJVFkgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRk9HRU5EICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19GT0dTVEFSVCAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0xBU1RQSVhFTCAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfU0hBREVNT0RFICAgICAgICAgICwKICAgIFdJTkVEM0RSU19TUkNCTEVORCAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1NURU5DSUxFTkFCTEUgICAgICAsCiAgICBXSU5FRDNEUlNfU1RFTkNJTEZBSUwgICAgICAgICwKICAgIFdJTkVEM0RSU19TVEVOQ0lMRlVOQyAgICAgICAgLAogICAgV0lORUQzRFJTX1NURU5DSUxNQVNLICAgICAgICAsCiAgICBXSU5FRDNEUlNfU1RFTkNJTFBBU1MgICAgICAgICwKICAgIFdJTkVEM0RSU19TVEVOQ0lMUkVGICAgICAgICAgLAogICAgV0lORUQzRFJTX1NURU5DSUxXUklURU1BU0sgICAsCiAgICBXSU5FRDNEUlNfU1RFTkNJTFpGQUlMICAgICAgICwKICAgIFdJTkVEM0RSU19URVhUVVJFRkFDVE9SICAgICAgLAogICAgV0lORUQzRFJTX1dSQVAwICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfV1JBUDEgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19XUkFQMiAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1dSQVAzICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfV1JBUDQgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19XUkFQNSAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1dSQVA2ICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfV1JBUDcgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19aRU5BQkxFICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1pGVU5DICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfWldSSVRFRU5BQkxFCn07Cgpjb25zdCBEV09SRCBTYXZlZFBpeGVsU3RhdGVzX1RbTlVNX1NBVkVEUElYRUxTVEFURVNfVF0gPSB7CiAgICBXSU5FRDNEVFNTX0FERFJFU1NXICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0FMUEhBQVJHMCAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0FMUEhBQVJHMSAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0FMUEhBQVJHMiAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0FMUEhBT1AgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0JVTVBFTlZMT0ZGU0VUICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0JVTVBFTlZMU0NBTEUgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0JVTVBFTlZNQVQwMCAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0JVTVBFTlZNQVQwMSAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0JVTVBFTlZNQVQxMCAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0JVTVBFTlZNQVQxMSAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0NPTE9SQVJHMCAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0NPTE9SQVJHMSAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0NPTE9SQVJHMiAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0NPTE9ST1AgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX1JFU1VMVEFSRyAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX1RFWENPT1JESU5ERVggICAgICAgICAsCiAgICBXSU5FRDNEVFNTX1RFWFRVUkVUUkFOU0ZPUk1GTEFHUwp9OwoKY29uc3QgRFdPUkQgU2F2ZWRQaXhlbFN0YXRlc19TW05VTV9TQVZFRFBJWEVMU1RBVEVTX1NdID0gewogICAgV0lORUQzRFNBTVBfQUREUkVTU1UgICAgICAgICAsCiAgICBXSU5FRDNEU0FNUF9BRERSRVNTViAgICAgICAgICwKICAgIFdJTkVEM0RTQU1QX0FERFJFU1NXICAgICAgICAgLAogICAgV0lORUQzRFNBTVBfQk9SREVSQ09MT1IgICAgICAsCiAgICBXSU5FRDNEU0FNUF9NQUdGSUxURVIgICAgICAgICwKICAgIFdJTkVEM0RTQU1QX01JTkZJTFRFUiAgICAgICAgLAogICAgV0lORUQzRFNBTVBfTUlQRklMVEVSICAgICAgICAsCiAgICBXSU5FRDNEU0FNUF9NSVBNQVBMT0RCSUFTICAgICwKICAgIFdJTkVEM0RTQU1QX01BWE1JUExFVkVMICAgICAgLAogICAgV0lORUQzRFNBTVBfTUFYQU5JU09UUk9QWSAgICAsCiAgICBXSU5FRDNEU0FNUF9TUkdCVEVYVFVSRSAgICAgICwKICAgIFdJTkVEM0RTQU1QX0VMRU1FTlRJTkRFWAp9OwoKY29uc3QgRFdPUkQgU2F2ZWRWZXJ0ZXhTdGF0ZXNfUltOVU1fU0FWRURWRVJURVhTVEFURVNfUl0gPSB7CiAgICBXSU5FRDNEUlNfQU1CSUVOVCAgICAgICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0FNQklFTlRNQVRFUklBTFNPVVJDRSAgICAgICAgICwKICAgIFdJTkVEM0RSU19DTElQUElORyAgICAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfQ0xJUFBMQU5FRU5BQkxFICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0NPTE9SVkVSVEVYICAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19ESUZGVVNFTUFURVJJQUxTT1VSQ0UgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRU1JU1NJVkVNQVRFUklBTFNPVVJDRSAgICAgICAgLAogICAgV0lORUQzRFJTX0ZPR0RFTlNJVFkgICAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19GT0dFTkQgICAgICAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRk9HU1RBUlQgICAgICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0ZPR1RBQkxFTU9ERSAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19GT0dWRVJURVhNT0RFICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfSU5ERVhFRFZFUlRFWEJMRU5ERU5BQkxFICAgICAgLAogICAgV0lORUQzRFJTX0xJR0hUSU5HICAgICAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19MT0NBTFZJRVdFUiAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfTVVMVElTQU1QTEVBTlRJQUxJQVMgICAgICAgICAgLAogICAgV0lORUQzRFJTX01VTFRJU0FNUExFTUFTSyAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19OT1JNQUxJWkVOT1JNQUxTICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfUEFUQ0hFREdFU1RZTEUgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1BPSU5UU0NBTEVfQSAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19QT0lOVFNDQUxFX0IgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfUE9JTlRTQ0FMRV9DICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1BPSU5UU0NBTEVFTkFCTEUgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19QT0lOVFNJWkUgICAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfUE9JTlRTSVpFX01BWCAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1BPSU5UU0laRV9NSU4gICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19QT0lOVFNQUklURUVOQUJMRSAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfUkFOR0VGT0dFTkFCTEUgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1NQRUNVTEFSTUFURVJJQUxTT1VSQ0UgICAgICAgICwKICAgIFdJTkVEM0RSU19UV0VFTkZBQ1RPUiAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfVkVSVEVYQkxFTkQgICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0NVTExNT0RFICAgICAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19GT0dDT0xPUgp9OwoKY29uc3QgRFdPUkQgU2F2ZWRWZXJ0ZXhTdGF0ZXNfVFtOVU1fU0FWRURWRVJURVhTVEFURVNfVF0gPSB7CiAgICBXSU5FRDNEVFNTX1RFWENPT1JESU5ERVggICAgICAgICAsCiAgICBXSU5FRDNEVFNTX1RFWFRVUkVUUkFOU0ZPUk1GTEFHUwp9OwoKY29uc3QgRFdPUkQgU2F2ZWRWZXJ0ZXhTdGF0ZXNfU1tOVU1fU0FWRURWRVJURVhTVEFURVNfU10gPSB7CiAgICBXSU5FRDNEU0FNUF9ETUFQT0ZGU0VUCn07Cgp2b2lkIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShJV2luZUQzRERldmljZUltcGwgKlRoaXMsIERXT1JEIHN0YXRlKSB7CiAgICBEV09SRCByZXAgPSBTdGF0ZVRhYmxlW3N0YXRlXS5yZXByZXNlbnRhdGl2ZTsKICAgIERXT1JEIGlkeDsKICAgIEJZVEUgc2hpZnQ7CiAgICBVSU5UIGk7CiAgICBXaW5lRDNEQ29udGV4dCAqY29udGV4dDsKCiAgICBpZighcmVwKSByZXR1cm47CiAgICBmb3IoaSA9IDA7IGkgPCBUaGlzLT5udW1Db250ZXh0czsgaSsrKSB7CiAgICAgICAgY29udGV4dCA9IFRoaXMtPmNvbnRleHRzW2ldOwogICAgICAgIGlmKGlzU3RhdGVEaXJ0eShjb250ZXh0LCByZXApKSBjb250aW51ZTsKCiAgICAgICAgY29udGV4dC0+ZGlydHlBcnJheVtjb250ZXh0LT5udW1EaXJ0eUVudHJpZXMrK10gPSByZXA7CiAgICAgICAgaWR4ID0gcmVwID4+IDU7CiAgICAgICAgc2hpZnQgPSByZXAgJiAweDFmOwogICAgICAgIGNvbnRleHQtPmlzU3RhdGVEaXJ0eVtpZHhdIHw9ICgxIDw8IHNoaWZ0KTsKICAgIH0KfQoKdm9pZCBnZXRfZHJhd2FibGVfc2l6ZV9wYnVmZmVyKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMsIFVJTlQgKndpZHRoLCBVSU5UICpoZWlnaHQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqZGV2ID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIC8qIFRoZSBkcmF3YWJsZSBzaXplIG9mIGEgcGJ1ZmZlciByZW5kZXIgdGFyZ2V0IGlzIHRoZSBjdXJyZW50IHBidWZmZXIgc2l6ZQogICAgICovCiAgICAqd2lkdGggPSBkZXYtPnBidWZmZXJXaWR0aDsKICAgICpoZWlnaHQgPSBkZXYtPnBidWZmZXJIZWlnaHQ7Cn0KCnZvaWQgZ2V0X2RyYXdhYmxlX3NpemVfZmJvKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMsIFVJTlQgKndpZHRoLCBVSU5UICpoZWlnaHQpIHsKICAgIC8qIFRoZSBkcmF3YWJsZSBzaXplIG9mIGEgZmJvIHRhcmdldCBpcyB0aGUgb3BlbmdsIHRleHR1cmUgc2l6ZSwgd2hpY2ggaXMgdGhlIHBvd2VyIG9mIHR3byBzaXplCiAgICAgKi8KICAgICp3aWR0aCA9IFRoaXMtPnBvdzJXaWR0aDsKICAgICpoZWlnaHQgPSBUaGlzLT5wb3cySGVpZ2h0Owp9Cgp2b2lkIGdldF9kcmF3YWJsZV9zaXplX2JhY2tidWZmZXIoSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcywgVUlOVCAqd2lkdGgsIFVJTlQgKmhlaWdodCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXYgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgLyogVGhlIGRyYXdhYmxlIHNpemUgb2YgYSBiYWNrYnVmZmVyIC8gYXV4IGJ1ZmZlciBvZmZzY3JlZW4gdGFyZ2V0IGlzIHRoZSBzaXplIG9mIHRoZQogICAgICogY3VycmVudCBjb250ZXh0J3MgZHJhd2FibGUsIHdoaWNoIGlzIHRoZSBzaXplIG9mIHRoZSBiYWNrIGJ1ZmZlciBvZiB0aGUgc3dhcGNoYWluCiAgICAgKiB0aGUgYWN0aXZlIGNvbnRleHQgYmVsb25ncyB0by4gVGhlIGJhY2sgYnVmZmVyIG9mIHRoZSBzd2FwY2hhaW4gaXMgc3RvcmVkIGFzIHRoZQogICAgICogc3VyZmFjZSB0aGUgY29udGV4dCBiZWxvbmdzIHRvLgogICAgICovCiAgICAqd2lkdGggPSAoKElXaW5lRDNEU3VyZmFjZUltcGwgKikgZGV2LT5hY3RpdmVDb250ZXh0LT5zdXJmYWNlKS0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAqaGVpZ2h0ID0gKChJV2luZUQzRFN1cmZhY2VJbXBsICopIGRldi0+YWN0aXZlQ29udGV4dC0+c3VyZmFjZSktPmN1cnJlbnREZXNjLkhlaWdodDsKfQo=