LyoKICogSVdpbmVEM0REZXZpY2UgaW1wbGVtZW50YXRpb24KICoKICogQ29weXJpZ2h0IDIwMDIgTGlvbmVsIFVsbWVyCiAqIENvcHlyaWdodCAyMDAyLTIwMDUgSmFzb24gRWRtZWFkZXMKICogQ29weXJpZ2h0IDIwMDMtMjAwNCBSYXBoYWVsIEp1bnF1ZWlyYQogKiBDb3B5cmlnaHQgMjAwNCBDaHJpc3RpYW4gQ29zdGEKICogQ29weXJpZ2h0IDIwMDUgT2xpdmVyIFN0aWViZXIKICogQ29weXJpZ2h0IDIwMDYtMjAwNyBTdGVmYW4gRPZzaW5nZXIgZm9yIENvZGVXZWF2ZXJzCiAqIENvcHlyaWdodCAyMDA2LTIwMDcgSGVucmkgVmVyYmVldAogKiBDb3B5cmlnaHQgMjAwNyBBbmRyZXcgUmllZGkKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSA8c3RkaW8uaD4KI2lmZGVmIEhBVkVfRkxPQVRfSAojIGluY2x1ZGUgPGZsb2F0Lmg+CiNlbmRpZgojaW5jbHVkZSAid2luZWQzZF9wcml2YXRlLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkM2QpOwojZGVmaW5lIEdMSU5GT19MT0NBVElPTiBUaGlzLT5hZGFwdGVyLT5nbF9pbmZvCgovKiBEZWZpbmUgdGhlIGRlZmF1bHQgbGlnaHQgcGFyYW1ldGVycyBhcyBzcGVjaWZpZWQgYnkgTVNETiAqLwpjb25zdCBXSU5FRDNETElHSFQgV0lORUQzRF9kZWZhdWx0X2xpZ2h0ID0gewoKICAgIFdJTkVEM0RMSUdIVF9ESVJFQ1RJT05BTCwgLyogVHlwZSAqLwogICAgeyAxLjAsIDEuMCwgMS4wLCAwLjAgfSwgICAvKiBEaWZmdXNlIHIsZyxiLGEgKi8KICAgIHsgMC4wLCAwLjAsIDAuMCwgMC4wIH0sICAgLyogU3BlY3VsYXIgcixnLGIsYSAqLwogICAgeyAwLjAsIDAuMCwgMC4wLCAwLjAgfSwgICAvKiBBbWJpZW50IHIsZyxiLGEsICovCiAgICB7IDAuMCwgMC4wLCAwLjAgfSwgICAgICAgIC8qIFBvc2l0aW9uIHgseSx6ICovCiAgICB7IDAuMCwgMC4wLCAxLjAgfSwgICAgICAgIC8qIERpcmVjdGlvbiB4LHkseiAqLwogICAgMC4wLCAgICAgICAgICAgICAgICAgICAgICAvKiBSYW5nZSAqLwogICAgMC4wLCAgICAgICAgICAgICAgICAgICAgICAvKiBGYWxsb2ZmICovCiAgICAwLjAsIDAuMCwgMC4wLCAgICAgICAgICAgIC8qIEF0dGVudWF0aW9uIDAsMSwyICovCiAgICAwLjAsICAgICAgICAgICAgICAgICAgICAgIC8qIFRoZXRhICovCiAgICAwLjAgICAgICAgICAgICAgICAgICAgICAgIC8qIFBoaSAqLwp9OwoKLyogc3RhdGljIGZ1bmN0aW9uIGRlY2xhcmF0aW9ucyAqLwpzdGF0aWMgdm9pZCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0FkZFJlc291cmNlKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RSZXNvdXJjZSAqcmVzb3VyY2UpOwoKLyogaGVscGVyIG1hY3JvcyAqLwojZGVmaW5lIEQzRE1FTUNIRUNLKG9iamVjdCwgcHBSZXN1bHQpIGlmKE5VTEwgPT0gb2JqZWN0KSB7ICpwcFJlc3VsdCA9IE5VTEw7IFdBUk4oIk91dCBvZiBtZW1vcnlcbiIpOyByZXR1cm4gV0lORUQzREVSUl9PVVRPRlZJREVPTUVNT1JZO30KCiNkZWZpbmUgRDNEQ1JFQVRFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCB0eXBlKSB7IFwKICAgIG9iamVjdD1IZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElXaW5lRDNEIyN0eXBlIyNJbXBsKSk7IFwKICAgIEQzRE1FTUNIRUNLKG9iamVjdCwgcHAjI3R5cGUpOyBcCiAgICBvYmplY3QtPmxwVnRibCA9ICZJV2luZUQzRCMjdHlwZSMjX1Z0Ymw7ICBcCiAgICBvYmplY3QtPndpbmVEM0REZXZpY2UgPSBUaGlzOyBcCiAgICBvYmplY3QtPnBhcmVudCAgICAgICA9IHBhcmVudDsgXAogICAgb2JqZWN0LT5yZWYgICAgICAgICAgPSAxOyBcCiAgICAqcHAjI3R5cGUgPSAoSVdpbmVEM0QjI3R5cGUgKikgb2JqZWN0OyBcCn0KCiNkZWZpbmUgRDNEQ1JFQVRFU0hBREVST0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCB0eXBlKSB7IFwKICAgIG9iamVjdD1IZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElXaW5lRDNEIyN0eXBlIyNJbXBsKSk7IFwKICAgIEQzRE1FTUNIRUNLKG9iamVjdCwgcHAjI3R5cGUpOyBcCiAgICBvYmplY3QtPmxwVnRibCA9ICZJV2luZUQzRCMjdHlwZSMjX1Z0Ymw7ICBcCiAgICBvYmplY3QtPnBhcmVudCAgICAgICAgICA9IHBhcmVudDsgXAogICAgb2JqZWN0LT5iYXNlU2hhZGVyLnJlZiAgPSAxOyBcCiAgICBvYmplY3QtPmJhc2VTaGFkZXIuZGV2aWNlID0gKElXaW5lRDNERGV2aWNlKikgVGhpczsgXAogICAgbGlzdF9pbml0KCZvYmplY3QtPmJhc2VTaGFkZXIubGlua2VkX3Byb2dyYW1zKTsgXAogICAgKnBwIyN0eXBlID0gKElXaW5lRDNEIyN0eXBlICopIG9iamVjdDsgXAp9CgojZGVmaW5lICBEM0RDUkVBVEVSRVNPVVJDRU9CSkVDVElOU1RBTkNFKG9iamVjdCwgdHlwZSwgZDNkdHlwZSwgX3NpemUpeyBcCiAgICBvYmplY3Q9SGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJV2luZUQzRCMjdHlwZSMjSW1wbCkpOyBcCiAgICBEM0RNRU1DSEVDSyhvYmplY3QsIHBwIyN0eXBlKTsgXAogICAgb2JqZWN0LT5scFZ0YmwgPSAmSVdpbmVEM0QjI3R5cGUjI19WdGJsOyAgXAogICAgb2JqZWN0LT5yZXNvdXJjZS53aW5lRDNERGV2aWNlICAgPSBUaGlzOyBcCiAgICBvYmplY3QtPnJlc291cmNlLnBhcmVudCAgICAgICAgICA9IHBhcmVudDsgXAogICAgb2JqZWN0LT5yZXNvdXJjZS5yZXNvdXJjZVR5cGUgICAgPSBkM2R0eXBlOyBcCiAgICBvYmplY3QtPnJlc291cmNlLnJlZiAgICAgICAgICAgICA9IDE7IFwKICAgIG9iamVjdC0+cmVzb3VyY2UucG9vbCAgICAgICAgICAgID0gUG9vbDsgXAogICAgb2JqZWN0LT5yZXNvdXJjZS5mb3JtYXQgICAgICAgICAgPSBGb3JtYXQ7IFwKICAgIG9iamVjdC0+cmVzb3VyY2UudXNhZ2UgICAgICAgICAgID0gVXNhZ2U7IFwKICAgIG9iamVjdC0+cmVzb3VyY2Uuc2l6ZSAgICAgICAgICAgID0gX3NpemU7IFwKICAgIGxpc3RfaW5pdCgmb2JqZWN0LT5yZXNvdXJjZS5wcml2YXRlRGF0YSk7IFwKICAgIC8qIENoZWNrIHRoYXQgd2UgaGF2ZSBlbm91Z2ggdmlkZW8gcmFtIGxlZnQgKi8gXAogICAgaWYgKFBvb2wgPT0gV0lORUQzRFBPT0xfREVGQVVMVCkgeyBcCiAgICAgICAgaWYgKElXaW5lRDNERGV2aWNlX0dldEF2YWlsYWJsZVRleHR1cmVNZW0oaWZhY2UpIDw9IF9zaXplKSB7IFwKICAgICAgICAgICAgV0FSTigiT3V0IG9mICdib2d1cycgdmlkZW8gbWVtb3J5XG4iKTsgXAogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvYmplY3QpOyBcCiAgICAgICAgICAgICpwcCMjdHlwZSA9IE5VTEw7IFwKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfT1VUT0ZWSURFT01FTU9SWTsgXAogICAgICAgIH0gXAogICAgICAgIFdpbmVEM0RBZGFwdGVyQ2hhbmdlR0xSYW0oVGhpcywgX3NpemUpOyBcCiAgICB9IFwKICAgIG9iamVjdC0+cmVzb3VyY2UuaGVhcE1lbW9yeSA9ICgwID09IF9zaXplID8gTlVMTCA6IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBfc2l6ZSArIFJFU09VUkNFX0FMSUdOTUVOVCkpOyBcCiAgICBpZiAob2JqZWN0LT5yZXNvdXJjZS5oZWFwTWVtb3J5ID09IE5VTEwgJiYgX3NpemUgIT0gMCkgeyBcCiAgICAgICAgRklYTUUoIk91dCBvZiBtZW1vcnkhXG4iKTsgXAogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9iamVjdCk7IFwKICAgICAgICAqcHAjI3R5cGUgPSBOVUxMOyBcCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfT1VUT0ZWSURFT01FTU9SWTsgXAogICAgfSBcCiAgICBvYmplY3QtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IChCWVRFICopKCgoVUxPTkdfUFRSKSBvYmplY3QtPnJlc291cmNlLmhlYXBNZW1vcnkgKyAoUkVTT1VSQ0VfQUxJR05NRU5UIC0gMSkpICYgfihSRVNPVVJDRV9BTElHTk1FTlQgLSAxKSk7IFwKICAgICpwcCMjdHlwZSA9IChJV2luZUQzRCMjdHlwZSAqKSBvYmplY3Q7IFwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9BZGRSZXNvdXJjZShpZmFjZSwgKElXaW5lRDNEUmVzb3VyY2UgKilvYmplY3QpIDtcCiAgICBUUkFDRSgiKCVwKSA6IENyZWF0ZWQgcmVzb3VyY2UgJXBcbiIsIFRoaXMsIG9iamVjdCk7IFwKfQoKI2RlZmluZSBEM0RJTklUSUFMSVpFQkFTRVRFWFRVUkUoX2Jhc2V0ZXh0dXJlKSB7IFwKICAgIF9iYXNldGV4dHVyZS5sZXZlbHMgICAgID0gTGV2ZWxzOyBcCiAgICBfYmFzZXRleHR1cmUuZmlsdGVyVHlwZSA9IChVc2FnZSAmIFdJTkVEM0RVU0FHRV9BVVRPR0VOTUlQTUFQKSA/IFdJTkVEM0RURVhGX0xJTkVBUiA6IFdJTkVEM0RURVhGX05PTkU7IFwKICAgIF9iYXNldGV4dHVyZS5MT0QgICAgICAgID0gMDsgXAogICAgX2Jhc2V0ZXh0dXJlLmRpcnR5ICAgICAgPSBUUlVFOyBcCiAgICBfYmFzZXRleHR1cmUuaXNfc3JnYiA9IEZBTFNFOyBcCiAgICBfYmFzZXRleHR1cmUuc3JnYl9tb2RlX2NoYW5nZV9jb3VudCA9IDA7IFwKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogR2xvYmFsIHZhcmlhYmxlIC8gQ29uc3RhbnRzIGZvbGxvdwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KY29uc3QgZmxvYXQgaWRlbnRpdHlbMTZdID0gezEsMCwwLDAsIDAsMSwwLDAsIDAsMCwxLDAsIDAsMCwwLDF9OyAgLyogV2hlbiBuZWVkZWQgZm9yIGNvbXBhcmlzb25zICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJVW5rbm93biBwYXJ0cyBmb2xsb3dzCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9RdWVyeUludGVyZmFjZShJV2luZUQzRERldmljZSAqaWZhY2UsUkVGSUlEIHJpaWQsTFBWT0lEICpwcG9iaikKewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXApLT4oJXMsJXApXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxwcG9iaik7CiAgICBpZiAoSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JVW5rbm93bikKICAgICAgICB8fCBJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lXaW5lRDNEQmFzZSkKICAgICAgICB8fCBJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lXaW5lRDNERGV2aWNlKSkgewogICAgICAgIElVbmtub3duX0FkZFJlZihpZmFjZSk7CiAgICAgICAgKnBwb2JqID0gVGhpczsKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KICAgICpwcG9iaiA9IE5VTEw7CiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQWRkUmVmKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVUxPTkcgcmVmQ291bnQgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgICBUUkFDRSgiKCVwKSA6IEFkZFJlZiBpbmNyZWFzaW5nIGZyb20gJWRcbiIsIFRoaXMsIHJlZkNvdW50IC0gMSk7CiAgICByZXR1cm4gcmVmQ291bnQ7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1JlbGVhc2UoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBVTE9ORyByZWZDb3VudCA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwoKICAgIFRSQUNFKCIoJXApIDogUmVsZWFzaW5nIGZyb20gJWRcbiIsIFRoaXMsIHJlZkNvdW50ICsgMSk7CgogICAgaWYgKCFyZWZDb3VudCkgewogICAgICAgIGlmIChUaGlzLT5mYm8pIHsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbERlbGV0ZUZyYW1lYnVmZmVyc0VYVCgxLCAmVGhpcy0+ZmJvKSk7CiAgICAgICAgfQogICAgICAgIGlmIChUaGlzLT5zcmNfZmJvKSB7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xEZWxldGVGcmFtZWJ1ZmZlcnNFWFQoMSwgJlRoaXMtPnNyY19mYm8pKTsKICAgICAgICB9CiAgICAgICAgaWYgKFRoaXMtPmRzdF9mYm8pIHsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbERlbGV0ZUZyYW1lYnVmZmVyc0VYVCgxLCAmVGhpcy0+ZHN0X2ZibykpOwogICAgICAgIH0KCiAgICAgICAgaWYgKFRoaXMtPmdsc2xfcHJvZ3JhbV9sb29rdXApIGhhc2hfdGFibGVfZGVzdHJveShUaGlzLT5nbHNsX3Byb2dyYW1fbG9va3VwKTsKCiAgICAgICAgLyogVE9ETzogQ2xlYW4gdXAgYWxsIHRoZSBzdXJmYWNlcyBhbmQgdGV4dHVyZXMhICovCiAgICAgICAgLyogTk9URTogWW91IG11c3QgcmVsZWFzZSB0aGUgcGFyZW50IGlmIHRoZSBvYmplY3Qgd2FzIGNyZWF0ZWQgdmlhIGEgY2FsbGJhY2sKICAgICAgICAqKiAqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgICAgIGlmICghbGlzdF9lbXB0eSgmVGhpcy0+cmVzb3VyY2VzKSkgewogICAgICAgICAgICBGSVhNRSgiKCVwKSBEZXZpY2UgcmVsZWFzZWQgd2l0aCByZXNvdXJjZXMgc3RpbGwgYm91bmQsIGFjY2VwdGFibGUgYnV0IHVuZXhwZWN0ZWRcbiIsIFRoaXMpOwogICAgICAgICAgICBkdW1wUmVzb3VyY2VzKCZUaGlzLT5yZXNvdXJjZXMpOwogICAgICAgIH0KCiAgICAgICAgaWYoVGhpcy0+Y29udGV4dHMpIEVSUigiQ29udGV4dCBhcnJheSBub3QgZnJlZWQhXG4iKTsKICAgICAgICBpZiAoVGhpcy0+aGFyZHdhcmVDdXJzb3IpIERlc3Ryb3lDdXJzb3IoVGhpcy0+aGFyZHdhcmVDdXJzb3IpOwogICAgICAgIFRoaXMtPmhhdmVIYXJkd2FyZUN1cnNvciA9IEZBTFNFOwoKICAgICAgICBJV2luZUQzRF9SZWxlYXNlKFRoaXMtPndpbmVEM0QpOwogICAgICAgIFRoaXMtPndpbmVEM0QgPSBOVUxMOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMpOwogICAgICAgIFRSQUNFKCJGcmVlZCBkZXZpY2UgICVwXG4iLCBUaGlzKTsKICAgICAgICBUaGlzID0gTlVMTDsKICAgIH0KICAgIHJldHVybiByZWZDb3VudDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0REZXZpY2UgaW1wbGVtZW50YXRpb24gZm9sbG93cwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQYXJlbnQoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJVW5rbm93biAqKnBQYXJlbnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgICpwUGFyZW50ID0gVGhpcy0+cGFyZW50OwogICAgSVVua25vd25fQWRkUmVmKFRoaXMtPnBhcmVudCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIHZvaWQgQ3JlYXRlVkJPKElXaW5lRDNEVmVydGV4QnVmZmVySW1wbCAqb2JqZWN0KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSBvYmplY3QtPnJlc291cmNlLndpbmVEM0REZXZpY2U7ICAvKiBOZWVkZWQgZm9yIEdMX0VYVENBTEwgKi8KICAgIEdMZW51bSBlcnJvciwgZ2xVc2FnZTsKICAgIERXT1JEIHZib1VzYWdlID0gb2JqZWN0LT5yZXNvdXJjZS51c2FnZTsKICAgIGlmKG9iamVjdC0+RmxhZ3MgJiBWQkZMQUdfVkJPQ1JFQVRFRkFJTCkgewogICAgICAgIFdBUk4oIkNyZWF0aW5nIGEgdmJvIGZhaWxlZCBvbmNlLCBub3QgdHJ5aW5nIGFnYWluXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgVFJBQ0UoIkNyZWF0aW5nIGFuIE9wZW5HTCB2ZXJ0ZXggYnVmZmVyIG9iamVjdCBmb3IgSVdpbmVEM0RWZXJ0ZXhCdWZmZXIgJXAgIFVzYWdlKCVzKVxuIiwgb2JqZWN0LCBkZWJ1Z19kM2R1c2FnZSh2Ym9Vc2FnZSkpOwoKICAgIC8qIE1ha2Ugc3VyZSB0aGF0IGEgY29udGV4dCBpcyB0aGVyZS4gTmVlZGVkIGluIGEgbXVsdGl0aHJlYWRlZCBlbnZpcm9ubWVudC4gT3RoZXJ3aXNlIHRoaXMgY2FsbCBpcyBhIG5vcCAqLwogICAgQWN0aXZhdGVDb250ZXh0KFRoaXMsIFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQsIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CiAgICBFTlRFUl9HTCgpOwoKICAgIC8qIE1ha2Ugc3VyZSB0aGF0IHRoZSBnbCBlcnJvciBpcyBjbGVhcmVkLiBEbyBub3QgdXNlIGNoZWNrR0xjYWxsCiAgICAgICogaGVyZSBiZWNhdXNlIGNoZWNrR0xjYWxsIGp1c3QgcHJpbnRzIGEgZml4bWUgYW5kIGNvbnRpbnVlcy4gSG93ZXZlciwKICAgICAgKiBpZiBhbiBlcnJvciBkdXJpbmcgVkJPIGNyZWF0aW9uIG9jY3VycyB3ZSBjYW4gZmFsbCBiYWNrIHRvIG5vbi12Ym8gb3BlcmF0aW9uCiAgICAgICogd2l0aCBmdWxsIGZ1bmN0aW9uYWxpdHkoYnV0IHBlcmZvcm1hbmNlIGxvc3MpCiAgICAgICovCiAgICB3aGlsZShnbEdldEVycm9yKCkgIT0gR0xfTk9fRVJST1IpOwoKICAgIC8qIEJhc2ljYWxseSB0aGUgRlZGIHBhcmFtZXRlciBwYXNzZWQgdG8gQ3JlYXRlVmVydGV4QnVmZmVyIGlzIG5vIGdvb2QKICAgICAgKiBJdCBpcyB0aGUgRlZGIHNldCB3aXRoIElXaW5lRDNERGV2aWNlOjpTZXRGVkYgb3IgdGhlIFZlcnRleCBEZWNsYXJhdGlvbiBzZXQgd2l0aAogICAgICAqIElXaW5lRDNERGV2aWNlOjpTZXRWZXJ0ZXhEZWNsYXJhdGlvbiB0aGF0IGRlY2lkZXMgaG93IHRoZSB2ZXJ0aWNlcyBpbiB0aGUgYnVmZmVyCiAgICAgICogbG9vayBsaWtlLiBUaGlzIG1lYW5zIHRoYXQgb24gZWFjaCBEcmF3UHJpbWl0aXZlIGNhbGwgdGhlIHZlcnRleCBidWZmZXIgaGFzIHRvIGJlIHZlcmlmaWVkCiAgICAgICogdG8gY2hlY2sgaWYgdGhlIHJodyBhbmQgY29sb3IgdmFsdWVzIGFyZSBpbiB0aGUgY29ycmVjdCBmb3JtYXQuCiAgICAgICovCgogICAgR0xfRVhUQ0FMTChnbEdlbkJ1ZmZlcnNBUkIoMSwgJm9iamVjdC0+dmJvKSk7CiAgICBlcnJvciA9IGdsR2V0RXJyb3IoKTsKICAgIGlmKG9iamVjdC0+dmJvID09IDAgfHwgZXJyb3IgIT0gR0xfTk9fRVJST1IpIHsKICAgICAgICBXQVJOKCJGYWlsZWQgdG8gY3JlYXRlIGEgVkJPIHdpdGggZXJyb3IgJXMgKCUjeClcbiIsIGRlYnVnX2dsZXJyb3IoZXJyb3IpLCBlcnJvcik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9BUlJBWV9CVUZGRVJfQVJCLCBvYmplY3QtPnZibykpOwogICAgZXJyb3IgPSBnbEdldEVycm9yKCk7CiAgICBpZihlcnJvciAhPSBHTF9OT19FUlJPUikgewogICAgICAgIFdBUk4oIkZhaWxlZCB0byBiaW5kIHRoZSBWQk8gd2l0aCBlcnJvciAlcyAoJSN4KVxuIiwgZGVidWdfZ2xlcnJvcihlcnJvciksIGVycm9yKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIERvbid0IHVzZSBzdGF0aWMsIGJlY2F1c2UgZHggYXBwcyB0ZW5kIHRvIHVwZGF0ZSB0aGUgYnVmZmVyCiAgICAgKiBxdWl0ZSBvZnRlbiBldmVuIGlmIHRoZXkgc3BlY2lmeSAwIHVzYWdlLiBCZWNhdXNlIHdlIGFsd2F5cyBrZWVwIHRoZSBsb2NhbCBjb3B5CiAgICAgKiB3ZSBuZXZlciByZWFkIGZyb20gdGhlIHZibyBhbmQgY2FuIGNyZWF0ZSBhIHdyaXRlIG9ubHkgb3BlbmdsIGJ1ZmZlci4KICAgICAqLwogICAgc3dpdGNoKHZib1VzYWdlICYgKFdJTkVEM0RVU0FHRV9XUklURU9OTFkgfCBXSU5FRDNEVVNBR0VfRFlOQU1JQykgKSB7CiAgICAgICAgY2FzZSBXSU5FRDNEVVNBR0VfV1JJVEVPTkxZIHwgV0lORUQzRFVTQUdFX0RZTkFNSUM6CiAgICAgICAgY2FzZSBXSU5FRDNEVVNBR0VfRFlOQU1JQzoKICAgICAgICAgICAgVFJBQ0UoIkdsIHVzYWdlID0gR0xfU1RSRUFNX0RSQVdcbiIpOwogICAgICAgICAgICBnbFVzYWdlID0gR0xfU1RSRUFNX0RSQVdfQVJCOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RVU0FHRV9XUklURU9OTFk6CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgVFJBQ0UoIkdsIHVzYWdlID0gR0xfRFlOQU1JQ19EUkFXXG4iKTsKICAgICAgICAgICAgZ2xVc2FnZSA9IEdMX0RZTkFNSUNfRFJBV19BUkI7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQoKICAgIC8qIFJlc2VydmUgbWVtb3J5IGZvciB0aGUgYnVmZmVyLiBUaGUgYW1vdW50IG9mIGRhdGEgd29uJ3QgY2hhbmdlCiAgICAgKiBzbyB3ZSBhcmUgc2FmZSB3aXRoIGNhbGxpbmcgZ2xCdWZmZXJEYXRhIG9uY2Ugd2l0aCBhIE5VTEwgcHRyIGFuZAogICAgICogY2FsbGluZyBnbEJ1ZmZlclN1YkRhdGEgb24gdXBkYXRlcwogICAgICovCiAgICBHTF9FWFRDQUxMKGdsQnVmZmVyRGF0YUFSQihHTF9BUlJBWV9CVUZGRVJfQVJCLCBvYmplY3QtPnJlc291cmNlLnNpemUsIE5VTEwsIGdsVXNhZ2UpKTsKICAgIGVycm9yID0gZ2xHZXRFcnJvcigpOwogICAgaWYoZXJyb3IgIT0gR0xfTk9fRVJST1IpIHsKICAgICAgICBXQVJOKCJnbEJ1ZmZlckRhdGFBUkIgZmFpbGVkIHdpdGggZXJyb3IgJXMgKCUjeClcbiIsIGRlYnVnX2dsZXJyb3IoZXJyb3IpLCBlcnJvcik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KICAgIG9iamVjdC0+dmJvX3NpemUgPSBvYmplY3QtPnJlc291cmNlLnNpemU7CiAgICBvYmplY3QtPnZib191c2FnZSA9IGdsVXNhZ2U7CgogICAgTEVBVkVfR0woKTsKCiAgICByZXR1cm47CiAgICBlcnJvcjoKICAgIC8qIENsZWFuIHVwIGFsbCB2Ym8gaW5pdCwgYnV0IGNvbnRpbnVlIGJlY2F1c2Ugd2UgY2FuIHdvcmsgd2l0aG91dCBhIHZibyA6LSkgKi8KICAgIEZJWE1FKCJGYWlsZWQgdG8gY3JlYXRlIGEgdmVydGV4IGJ1ZmZlciBvYmplY3QuIENvbnRpbnVpbmcsIGJ1dCBwZXJmb3JtYW5jZSBpc3N1ZXMgY2FuIG9jY3VyXG4iKTsKICAgIGlmKG9iamVjdC0+dmJvKSBHTF9FWFRDQUxMKGdsRGVsZXRlQnVmZmVyc0FSQigxLCAmb2JqZWN0LT52Ym8pKTsKICAgIG9iamVjdC0+dmJvID0gMDsKICAgIG9iamVjdC0+RmxhZ3MgfD0gVkJGTEFHX1ZCT0NSRUFURUZBSUw7CiAgICBMRUFWRV9HTCgpOwogICAgcmV0dXJuOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZlcnRleEJ1ZmZlcihJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgU2l6ZSwgRFdPUkQgVXNhZ2UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZWRiwgV0lORUQzRFBPT0wgUG9vbCwgSVdpbmVEM0RWZXJ0ZXhCdWZmZXIqKiBwcFZlcnRleEJ1ZmZlciwgSEFORExFICpzaGFyZWRIYW5kbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVVua25vd24gKnBhcmVudCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RWZXJ0ZXhCdWZmZXJJbXBsICpvYmplY3Q7CiAgICBXSU5FRDNERk9STUFUIEZvcm1hdCA9IFdJTkVEM0RGTVRfVkVSVEVYREFUQTsgLyogRHVtbXkgZm9ybWF0IGZvciBub3cgKi8KICAgIGludCBkeFZlcnNpb24gPSAoIChJV2luZUQzREltcGwgKikgVGhpcy0+d2luZUQzRCktPmR4VmVyc2lvbjsKICAgIEJPT0wgY29udjsKCiAgICBpZihTaXplID09IDApIHsKICAgICAgICBXQVJOKCJTaXplIDAgcmVxdWVzdGVkLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgKnBwVmVydGV4QnVmZmVyID0gTlVMTDsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0gZWxzZSBpZihQb29sID09IFdJTkVEM0RQT09MX1NDUkFUQ0gpIHsKICAgICAgICAvKiBUaGUgZDNkOSB0ZXN0c3VpdCBzaG93cyB0aGF0IHRoaXMgaXMgbm90IGFsbG93ZWQuIEl0IGRvZXNuJ3QgbWFrZSBtdWNoIHNlbnNlCiAgICAgICAgICogYW55d2F5LCBTQ1JBVENIIHZlcnRleCBidWZmZXJzIGFyZW4ndCB1c2VhYmxlIGFueXdoZXJlCiAgICAgICAgICovCiAgICAgICAgV0FSTigiVmVydGV4IGJ1ZmZlciBpbiBEM0RQT09MX1NDUkFUQ0ggcmVxdWVzdGVkLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgKnBwVmVydGV4QnVmZmVyID0gTlVMTDsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBEM0RDUkVBVEVSRVNPVVJDRU9CSkVDVElOU1RBTkNFKG9iamVjdCwgVmVydGV4QnVmZmVyLCBXSU5FRDNEUlRZUEVfVkVSVEVYQlVGRkVSLCBTaXplKQoKICAgIFRSQUNFKCIoJXApIDogU2l6ZT0lZCwgVXNhZ2U9MHglMDh4LCBGVkY9JXgsIFBvb2w9JWQgLSBNZW1vcnlAJXAsIElmYWNlQCVwXG4iLCBUaGlzLCBTaXplLCBVc2FnZSwgRlZGLCBQb29sLCBvYmplY3QtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwgb2JqZWN0KTsKICAgICpwcFZlcnRleEJ1ZmZlciA9IChJV2luZUQzRFZlcnRleEJ1ZmZlciAqKW9iamVjdDsKCiAgICBvYmplY3QtPmZ2ZiA9IEZWRjsKCiAgICAvKiBPYnNlcnZhdGlvbnMgc2hvdyB0aGF0IGRyYXdTdHJpZGVkU2xvdyBpcyBmYXN0ZXIgb24gZHluYW1pYyBWQnMgdGhhbiBjb252ZXJ0aW5nICsKICAgICAqIGRyYXdTdHJpZGVkRmFzdCAoaGFsZi1saWZlIDIpLgogICAgICoKICAgICAqIEJhc2ljYWxseSBjb252ZXJ0aW5nIHRoZSB2ZXJ0aWNlcyBpbiB0aGUgYnVmZmVyIGlzIHF1aXRlIGV4cGVuc2l2ZSwgYW5kIG9ic2VydmF0aW9ucwogICAgICogc2hvdyB0aGF0IGRyYXdTdHJpZGVkU2xvdyBpcyBmYXN0ZXIgdGhhbiBjb252ZXJ0aW5nICsgdXBsb2FkaW5nICsgZHJhd1N0cmlkZWRGYXN0LgogICAgICogVGhlcmVmb3JlIGRvIG5vdCBjcmVhdGUgYSBWQk8gZm9yIFdJTkVEM0RVU0FHRV9EWU5BTUlDIGJ1ZmZlcnMuCiAgICAgKgogICAgICogRGlyZWN0M0Q3IGhhcyBhbm90aGVyIHByb2JsZW06IEl0cyB2ZXJ0ZXhidWZmZXIgYXBpIGRvZXNuJ3Qgb2ZmZXIgYSB3YXkgdG8gc3BlY2lmeQogICAgICogdGhlIHJhbmdlIG9mIHZlcnRpY2VzIGJlaW5nIGxvY2tlZCwgc28gZWFjaCBsb2NrIHdpbGwgcmVxdWlyZSB0aGUgd2hvbGUgYnVmZmVyIHRvIGJlIHRyYW5zZm9ybWVkLgogICAgICogTW9yZW92ZXIgZ2VvbWV0cnkgZGF0YSBpbiBkeDcgaXMgcXVpdGUgc2ltcGxlLCBzbyBkcmF3U3RyaWRlZFNsb3cgaXNuJ3QgYSBiaWcgaGl0LiBBIHBsdXMKICAgICAqIGlzIHRoYXQgdGhlIHZlcnRleCBidWZmZXJzIGZ2ZiBjYW4gYmUgdHJ1c3RlZCBpbiBkeDcuIFNvIG9ubHkgY3JlYXRlIG5vbi1jb252ZXJ0ZWQgdmJvcyBmb3IKICAgICAqIGR4NyBhcHBzLgogICAgICogVGhlcmUgaXMgYSBJRGlyZWN0M0RWZXJ0ZXhCdWZmZXI3OjpPcHRpbWl6ZSBjYWxsIGFmdGVyIHdoaWNoIHRoZSBidWZmZXIgY2FuJ3QgYmUgbG9ja2VkIGFueQogICAgICogbW9yZS4gSW4gdGhpcyBjYWxsIHdlIGNhbiBjb252ZXJ0IGR4NyBidWZmZXJzIHRvby4KICAgICAqLwogICAgY29udiA9ICgoRlZGICYgV0lORUQzREZWRl9QT1NJVElPTl9NQVNLKSA9PSBXSU5FRDNERlZGX1hZWlJIVyApIHx8IChGVkYgJiAoV0lORUQzREZWRl9ESUZGVVNFIHwgV0lORUQzREZWRl9TUEVDVUxBUikpOwogICAgaWYoIUdMX1NVUFBPUlQoQVJCX1ZFUlRFWF9CVUZGRVJfT0JKRUNUKSkgewogICAgICAgIFRSQUNFKCJOb3QgY3JlYXRpbmcgYSB2Ym8gYmVjYXVzZSBHTF9BUkJfdmVydGV4X2J1ZmZlciBpcyBub3Qgc3VwcG9ydGVkXG4iKTsKICAgIH0gZWxzZSBpZihQb29sID09IFdJTkVEM0RQT09MX1NZU1RFTU1FTSkgewogICAgICAgIFRSQUNFKCJOb3QgY3JlYXRpbmcgYSB2Ym8gYmVjYXVzZSB0aGUgdmVydGV4IGJ1ZmZlciBpcyBpbiBzeXN0ZW0gbWVtb3J5XG4iKTsKICAgIH0gZWxzZSBpZihVc2FnZSAmIFdJTkVEM0RVU0FHRV9EWU5BTUlDKSB7CiAgICAgICAgVFJBQ0UoIk5vdCBjcmVhdGluZyBhIHZibyBiZWNhdXNlIHRoZSBidWZmZXIgaGFzIGR5bmFtaWMgdXNhZ2VcbiIpOwogICAgfSBlbHNlIGlmKGR4VmVyc2lvbiA8PSA3ICYmIGNvbnYpIHsKICAgICAgICBUUkFDRSgiTm90IGNyZWF0aW5nIGEgdmJvIGJlY2F1c2UgZHhWZXJzaW9uIGlzIDcgYW5kIHRoZSBmdmYgbmVlZHMgY29udmVyc2lvblxuIik7CiAgICB9IGVsc2UgewogICAgICAgIENyZWF0ZVZCTyhvYmplY3QpOwogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyB2b2lkIENyZWF0ZUluZGV4QnVmZmVyVkJPKElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcywgSVdpbmVEM0RJbmRleEJ1ZmZlckltcGwgKm9iamVjdCkgewogICAgR0xlbnVtIGVycm9yLCBnbFVzYWdlOwogICAgVFJBQ0UoIkNyZWF0aW5nIFZCTyBmb3IgSW5kZXggQnVmZmVyICVwXG4iLCBvYmplY3QpOwoKICAgIC8qIFRoZSBmb2xsb3dpbmcgY29kZSB3aWxsIG1vZGlmeSB0aGUgRUxFTUVOVF9BUlJBWV9CVUZGRVIgYmluZGluZywgbWFrZSBzdXJlIGl0IGlzCiAgICAgKiByZXN0b3JlZCBvbiB0aGUgbmV4dCBkcmF3CiAgICAgKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9JTkRFWEJVRkZFUik7CgogICAgLyogTWFrZSBzdXJlIHRoYXQgYSBjb250ZXh0IGlzIHRoZXJlLiBOZWVkZWQgaW4gYSBtdWx0aXRocmVhZGVkIGVudmlyb25tZW50LiBPdGhlcndpc2UgdGhpcyBjYWxsIGlzIGEgbm9wICovCiAgICBBY3RpdmF0ZUNvbnRleHQoVGhpcywgVGhpcy0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKICAgIEVOVEVSX0dMKCk7CgogICAgd2hpbGUoZ2xHZXRFcnJvcigpKTsKCiAgICBHTF9FWFRDQUxMKGdsR2VuQnVmZmVyc0FSQigxLCAmb2JqZWN0LT52Ym8pKTsKICAgIGVycm9yID0gZ2xHZXRFcnJvcigpOwogICAgaWYoZXJyb3IgIT0gR0xfTk9fRVJST1IgfHwgb2JqZWN0LT52Ym8gPT0gMCkgewogICAgICAgIEVSUigiQ3JlYXRpbmcgYSB2Ym8gZmFpbGVkIHdpdGggZXJyb3IgJXMgKCUjeCksIGNvbnRpbnVpbmcgd2l0aG91dCB2Ym8gZm9yIHRoaXMgYnVmZmVyXG4iLCBkZWJ1Z19nbGVycm9yKGVycm9yKSwgZXJyb3IpOwogICAgICAgIGdvdG8gb3V0OwogICAgfQoKICAgIEdMX0VYVENBTEwoZ2xCaW5kQnVmZmVyQVJCKEdMX0VMRU1FTlRfQVJSQVlfQlVGRkVSX0FSQiwgb2JqZWN0LT52Ym8pKTsKICAgIGVycm9yID0gZ2xHZXRFcnJvcigpOwogICAgaWYoZXJyb3IgIT0gR0xfTk9fRVJST1IpIHsKICAgICAgICBFUlIoIkZhaWxlZCB0byBiaW5kIGluZGV4IGJ1ZmZlciB3aXRoIGVycm9yICVzICglI3gpLCBjb250aW51aW5nIHdpdGhvdXQgdmJvIGZvciB0aGlzIGJ1ZmZlclxuIiwgZGVidWdfZ2xlcnJvcihlcnJvciksIGVycm9yKTsKICAgICAgICBnb3RvIG91dDsKICAgIH0KCiAgICAvKiBVc2Ugc3RhdGljIHdyaXRlIG9ubHkgdXNhZ2UgZm9yIG5vdy4gRHluYW1pYyBpbmRleCBidWZmZXJzIHN0YXkgaW4gc3lzbWVtLCBhbmQgZHVlIHRvIHRoZSBzeXNtZW0KICAgICAgICAqIGNvcHkgbm8gcmVhZGJhY2sgd2lsbCBiZSBuZWVkZWQKICAgICAgICAqLwogICAgZ2xVc2FnZSA9IEdMX1NUQVRJQ19EUkFXX0FSQjsKICAgIEdMX0VYVENBTEwoZ2xCdWZmZXJEYXRhQVJCKEdMX0VMRU1FTlRfQVJSQVlfQlVGRkVSX0FSQiwgb2JqZWN0LT5yZXNvdXJjZS5zaXplLCBOVUxMLCBnbFVzYWdlKSk7CiAgICBlcnJvciA9IGdsR2V0RXJyb3IoKTsKICAgIGlmKGVycm9yICE9IEdMX05PX0VSUk9SKSB7CiAgICAgICAgRVJSKCJGYWlsZWQgdG8gaW5pdGlhbGl6ZSB0aGUgaW5kZXggYnVmZmVyIHdpdGggZXJyb3IgJXMgKCUjeClcbiIsIGRlYnVnX2dsZXJyb3IoZXJyb3IpLCBlcnJvcik7CiAgICAgICAgZ290byBvdXQ7CiAgICB9CiAgICBMRUFWRV9HTCgpOwogICAgVFJBQ0UoIlN1Y2Nlc3NmdWxseSBjcmVhdGVkIHZibyAlZCBmb3IgaW5kZXggYnVmZmVyICVwXG4iLCBvYmplY3QtPnZibywgb2JqZWN0KTsKICAgIHJldHVybjsKCm91dDoKICAgIEdMX0VYVENBTEwoZ2xCaW5kQnVmZmVyQVJCKEdMX0VMRU1FTlRfQVJSQVlfQlVGRkVSX0FSQiwgMCkpOwogICAgR0xfRVhUQ0FMTChnbERlbGV0ZUJ1ZmZlcnNBUkIoMSwgJm9iamVjdC0+dmJvKSk7CiAgICBMRUFWRV9HTCgpOwogICAgb2JqZWN0LT52Ym8gPSAwOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZUluZGV4QnVmZmVyKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBMZW5ndGgsIERXT1JEIFVzYWdlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RGT1JNQVQgRm9ybWF0LCBXSU5FRDNEUE9PTCBQb29sLCBJV2luZUQzREluZGV4QnVmZmVyKiogcHBJbmRleEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRSAqc2hhcmVkSGFuZGxlLCBJVW5rbm93biAqcGFyZW50KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzREluZGV4QnVmZmVySW1wbCAqb2JqZWN0OwogICAgVFJBQ0UoIiglcCkgQ3JlYXRpbmcgaW5kZXggYnVmZmVyXG4iLCBUaGlzKTsKCiAgICAvKiBBbGxvY2F0ZSB0aGUgc3RvcmFnZSBmb3IgdGhlIGRldmljZSAqLwogICAgRDNEQ1JFQVRFUkVTT1VSQ0VPQkpFQ1RJTlNUQU5DRShvYmplY3QsSW5kZXhCdWZmZXIsV0lORUQzRFJUWVBFX0lOREVYQlVGRkVSLCBMZW5ndGgpCgogICAgaWYoUG9vbCAhPSBXSU5FRDNEUE9PTF9TWVNURU1NRU0gJiYgIShVc2FnZSAmIFdJTkVEM0RVU0FHRV9EWU5BTUlDKSAmJiBHTF9TVVBQT1JUKEFSQl9WRVJURVhfQlVGRkVSX09CSkVDVCkpIHsKICAgICAgICBDcmVhdGVJbmRleEJ1ZmZlclZCTyhUaGlzLCBvYmplY3QpOwogICAgfQoKICAgIFRSQUNFKCIoJXApIDogTGVuPSVkLCBVc2U9JXgsIEZvcm1hdD0oJXUsJXMpLCBQb29sPSVkIC0gTWVtb3J5QCVwLCBJZmFjZUAlcFxuIiwgVGhpcywgTGVuZ3RoLCBVc2FnZSwgRm9ybWF0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVidWdfZDNkZm9ybWF0KEZvcm1hdCksIFBvb2wsIG9iamVjdCwgb2JqZWN0LT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgKnBwSW5kZXhCdWZmZXIgPSAoSVdpbmVEM0RJbmRleEJ1ZmZlciAqKSBvYmplY3Q7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlU3RhdGVCbG9jayhJV2luZUQzRERldmljZSogaWZhY2UsIFdJTkVEM0RTVEFURUJMT0NLVFlQRSBUeXBlLCBJV2luZUQzRFN0YXRlQmxvY2sqKiBwcFN0YXRlQmxvY2ssIElVbmtub3duICpwYXJlbnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgICAgICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RTdGF0ZUJsb2NrSW1wbCAqb2JqZWN0OwogICAgaW50IGksIGo7CiAgICBIUkVTVUxUIHRlbXBfcmVzdWx0OwoKICAgIEQzRENSRUFURU9CSkVDVElOU1RBTkNFKG9iamVjdCwgU3RhdGVCbG9jaykKICAgIG9iamVjdC0+YmxvY2tUeXBlICAgICA9IFR5cGU7CgogICAgZm9yKGkgPSAwOyBpIDwgTElHSFRNQVBfU0laRTsgaSsrKSB7CiAgICAgICAgbGlzdF9pbml0KCZvYmplY3QtPmxpZ2h0TWFwW2ldKTsKICAgIH0KCiAgICAvKiBTcGVjaWFsIGNhc2UgLSBVc2VkIGR1cmluZyBpbml0aWFsaXphdGlvbiB0byBwcm9kdWNlIGEgcGxhY2Vob2xkZXIgc3RhdGVibG9jawogICAgICAgICAgc28gb3RoZXIgZnVuY3Rpb25zIGNhbGxlZCBjYW4gdXBkYXRlIGEgc3RhdGUgYmxvY2sgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgIGlmIChUeXBlID09IFdJTkVEM0RTQlRfSU5JVCkgewogICAgICAgIC8qIERvbid0IGJvdGhlciBpbmNyZWFzaW5nIHRoZSByZWZlcmVuY2UgY291bnQgb3RoZXJ3aXNlIGEgZGV2aWNlIHdpbGwgbmV2ZXIKICAgICAgICAgICBiZSBmcmVlZCBkdWUgdG8gY2lyY3VsYXIgZGVwZW5kZW5jaWVzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQogICAgCiAgICB0ZW1wX3Jlc3VsdCA9IGFsbG9jYXRlX3NoYWRlcl9jb25zdGFudHMob2JqZWN0KTsKICAgIGlmIChXSU5FRDNEX09LICE9IHRlbXBfcmVzdWx0KQogICAgICAgIHJldHVybiB0ZW1wX3Jlc3VsdDsKCiAgICAvKiBPdGhlcndpc2UsIG1pZ2h0IGFzIHdlbGwgc2V0IHRoZSB3aG9sZSBzdGF0ZSBibG9jayB0byB0aGUgYXBwcm9wcmlhdGUgdmFsdWVzICAqLwogICAgaWYgKFRoaXMtPnN0YXRlQmxvY2sgIT0gTlVMTCkKICAgICAgICBzdGF0ZWJsb2NrX2NvcHkoKElXaW5lRDNEU3RhdGVCbG9jayopIG9iamVjdCwgKElXaW5lRDNEU3RhdGVCbG9jayopIFRoaXMtPnN0YXRlQmxvY2spOwogICAgZWxzZQogICAgICAgIG1lbXNldChvYmplY3QtPnN0cmVhbUZyZXEsIDEsIHNpemVvZihvYmplY3QtPnN0cmVhbUZyZXEpKTsKCiAgICAvKiBSZXNldCB0aGUgcmVmIGFuZCB0eXBlIGFmdGVyIGtsdWRnaW5nIGl0ICovCiAgICBvYmplY3QtPndpbmVEM0REZXZpY2UgPSBUaGlzOwogICAgb2JqZWN0LT5yZWYgICAgICAgICAgID0gMTsKICAgIG9iamVjdC0+YmxvY2tUeXBlICAgICA9IFR5cGU7CgogICAgVFJBQ0UoIlVwZGF0aW5nIGNoYW5nZWQgZmxhZ3MgYXBwcm9wcmlhdGUgZm9yIHR5cGUgJWRcbiIsIFR5cGUpOwoKICAgIGlmIChUeXBlID09IFdJTkVEM0RTQlRfQUxMKSB7CgogICAgICAgIFRSQUNFKCJBTEwgPT4gUHJldGVuZCBldmVyeXRoaW5nIGhhcyBjaGFuZ2VkXG4iKTsKICAgICAgICBzdGF0ZWJsb2NrX3NhdmVkc3RhdGVzX3NldCgoSVdpbmVEM0RTdGF0ZUJsb2NrKikgb2JqZWN0LCAmb2JqZWN0LT5jaGFuZ2VkLCBUUlVFKTsKCiAgICAgICAgLyogTGlnaHRzIGFyZSBub3QgcGFydCBvZiB0aGUgY2hhbmdlZCAvIHNldCBzdHJ1Y3R1cmUgKi8KICAgICAgICBmb3IoaiA9IDA7IGogPCBMSUdIVE1BUF9TSVpFOyBqKyspIHsKICAgICAgICAgICAgc3RydWN0IGxpc3QgKmU7CiAgICAgICAgICAgIExJU1RfRk9SX0VBQ0goZSwgJm9iamVjdC0+bGlnaHRNYXBbal0pIHsKICAgICAgICAgICAgICAgIFBMSUdIVElORk9FTCAqbGlnaHQgPSBMSVNUX0VOVFJZKGUsIFBMSUdIVElORk9FTCwgZW50cnkpOwogICAgICAgICAgICAgICAgbGlnaHQtPmNoYW5nZWQgPSBUUlVFOwogICAgICAgICAgICAgICAgbGlnaHQtPmVuYWJsZWRDaGFuZ2VkID0gVFJVRTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3IoaiA9IDE7IGogPD0gV0lORUhJR0hFU1RfUkVOREVSX1NUQVRFOyBqKyspIHsKICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfcmVuZGVyX3N0YXRlc1tqIC0gMV0gPSBqOwogICAgICAgIH0KICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfcmVuZGVyX3N0YXRlcyA9IFdJTkVISUdIRVNUX1JFTkRFUl9TVEFURTsKICAgICAgICAvKiBUT0RPOiBGaWx0ZXIgdW51c2VkIHRyYW5zZm9ybXMgYmV0d2VlbiBURVhUVVJFOCBhbmQgV09STEQwPyAqLwogICAgICAgIGZvcihqID0gMTsgaiA8PSBISUdIRVNUX1RSQU5TRk9STVNUQVRFOyBqKyspIHsKICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfdHJhbnNmb3JtX3N0YXRlc1tqIC0gMV0gPSBqOwogICAgICAgIH0KICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfdHJhbnNmb3JtX3N0YXRlcyA9IEhJR0hFU1RfVFJBTlNGT1JNU1RBVEU7CiAgICAgICAgZm9yKGogPSAwOyBqIDwgR0xfTElNSVRTKHZzaGFkZXJfY29uc3RhbnRzRik7IGorKykgewogICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF92c19jb25zdHNfZltqXSA9IGo7CiAgICAgICAgfQogICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF92c19jb25zdHNfZiA9IEdMX0xJTUlUUyh2c2hhZGVyX2NvbnN0YW50c0YpOwogICAgICAgIGZvcihqID0gMDsgaiA8IE1BWF9DT05TVF9JOyBqKyspIHsKICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfdnNfY29uc3RzX2lbal0gPSBqOwogICAgICAgIH0KICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfdnNfY29uc3RzX2kgPSBNQVhfQ09OU1RfSTsKICAgICAgICBmb3IoaiA9IDA7IGogPCBNQVhfQ09OU1RfQjsgaisrKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3ZzX2NvbnN0c19iW2pdID0gajsKICAgICAgICB9CiAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3ZzX2NvbnN0c19iID0gTUFYX0NPTlNUX0I7CiAgICAgICAgZm9yKGogPSAwOyBqIDwgR0xfTElNSVRTKHBzaGFkZXJfY29uc3RhbnRzRik7IGorKykgewogICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF9wc19jb25zdHNfZltqXSA9IGo7CiAgICAgICAgfQogICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF9wc19jb25zdHNfZiA9IEdMX0xJTUlUUyhwc2hhZGVyX2NvbnN0YW50c0YpOwogICAgICAgIGZvcihqID0gMDsgaiA8IE1BWF9DT05TVF9JOyBqKyspIHsKICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfcHNfY29uc3RzX2lbal0gPSBqOwogICAgICAgIH0KICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfcHNfY29uc3RzX2kgPSBNQVhfQ09OU1RfSTsKICAgICAgICBmb3IoaiA9IDA7IGogPCBNQVhfQ09OU1RfQjsgaisrKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3BzX2NvbnN0c19iW2pdID0gajsKICAgICAgICB9CiAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3BzX2NvbnN0c19iID0gTUFYX0NPTlNUX0I7CiAgICAgICAgZm9yKGkgPSAwOyBpIDwgTUFYX1RFWFRVUkVTOyBpKyspIHsKICAgICAgICAgICAgZm9yKGogPSAxOyBqIDw9IFdJTkVEM0RfSElHSEVTVF9URVhUVVJFX1NUQVRFOyBqKyspIHsKICAgICAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3Rzc19zdGF0ZXNbb2JqZWN0LT5udW1fY29udGFpbmVkX3Rzc19zdGF0ZXNdLnN0YWdlID0gaTsKICAgICAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3Rzc19zdGF0ZXNbb2JqZWN0LT5udW1fY29udGFpbmVkX3Rzc19zdGF0ZXNdLnN0YXRlID0gajsKICAgICAgICAgICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF90c3Nfc3RhdGVzKys7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yKGkgPSAwOyBpIDwgTUFYX0NPTUJJTkVEX1NBTVBMRVJTOyBpKyspIHsKICAgICAgICAgICAgZm9yKGogPSAxOyBqIDw9IFdJTkVEM0RfSElHSEVTVF9TQU1QTEVSX1NUQVRFOyBqKyspIHsKICAgICAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3NhbXBsZXJfc3RhdGVzW29iamVjdC0+bnVtX2NvbnRhaW5lZF9zYW1wbGVyX3N0YXRlc10uc3RhZ2UgPSBpOwogICAgICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfc2FtcGxlcl9zdGF0ZXNbb2JqZWN0LT5udW1fY29udGFpbmVkX3NhbXBsZXJfc3RhdGVzXS5zdGF0ZSA9IGo7CiAgICAgICAgICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfc2FtcGxlcl9zdGF0ZXMrKzsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZm9yKGkgPSAwOyBpIDwgTUFYX1NUUkVBTVM7IGkrKykgewogICAgICAgICAgICBpZihvYmplY3QtPnN0cmVhbVNvdXJjZVtpXSkgewogICAgICAgICAgICAgICAgSVdpbmVEM0RWZXJ0ZXhCdWZmZXJfQWRkUmVmKG9iamVjdC0+c3RyZWFtU291cmNlW2ldKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZihvYmplY3QtPnBJbmRleERhdGEpIHsKICAgICAgICAgICAgSVdpbmVEM0RJbmRleEJ1ZmZlcl9BZGRSZWYob2JqZWN0LT5wSW5kZXhEYXRhKTsKICAgICAgICB9CiAgICAgICAgaWYob2JqZWN0LT52ZXJ0ZXhTaGFkZXIpIHsKICAgICAgICAgICAgSVdpbmVEM0RWZXJ0ZXhTaGFkZXJfQWRkUmVmKG9iamVjdC0+dmVydGV4U2hhZGVyKTsKICAgICAgICB9CiAgICAgICAgaWYob2JqZWN0LT5waXhlbFNoYWRlcikgewogICAgICAgICAgICBJV2luZUQzRFBpeGVsU2hhZGVyX0FkZFJlZihvYmplY3QtPnBpeGVsU2hhZGVyKTsKICAgICAgICB9CgogICAgfSBlbHNlIGlmIChUeXBlID09IFdJTkVEM0RTQlRfUElYRUxTVEFURSkgewoKICAgICAgICBUUkFDRSgiUElYRUxTVEFURSA9PiBQcmV0ZW5kIGFsbCBwaXhlbCBzaGF0ZXMgaGF2ZSBjaGFuZ2VkXG4iKTsKICAgICAgICBzdGF0ZWJsb2NrX3NhdmVkc3RhdGVzX3NldCgoSVdpbmVEM0RTdGF0ZUJsb2NrKikgb2JqZWN0LCAmb2JqZWN0LT5jaGFuZ2VkLCBGQUxTRSk7CgogICAgICAgIG9iamVjdC0+Y2hhbmdlZC5waXhlbFNoYWRlciA9IFRSVUU7CgogICAgICAgIC8qIFBpeGVsIFNoYWRlciBDb25zdGFudHMgKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgR0xfTElNSVRTKHZzaGFkZXJfY29uc3RhbnRzRik7ICsraSkgewogICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF9wc19jb25zdHNfZltpXSA9IGk7CiAgICAgICAgICAgIG9iamVjdC0+Y2hhbmdlZC5waXhlbFNoYWRlckNvbnN0YW50c0ZbaV0gPSBUUlVFOwogICAgICAgIH0KICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfcHNfY29uc3RzX2YgPSBHTF9MSU1JVFModnNoYWRlcl9jb25zdGFudHNGKTsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgTUFYX0NPTlNUX0I7ICsraSkgewogICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF9wc19jb25zdHNfYltpXSA9IGk7CiAgICAgICAgICAgIG9iamVjdC0+Y2hhbmdlZC5waXhlbFNoYWRlckNvbnN0YW50c0JbaV0gPSBUUlVFOwogICAgICAgIH0KICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfcHNfY29uc3RzX2IgPSBNQVhfQ09OU1RfQjsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgTUFYX0NPTlNUX0k7ICsraSkgewogICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF9wc19jb25zdHNfaVtpXSA9IGk7CiAgICAgICAgICAgIG9iamVjdC0+Y2hhbmdlZC5waXhlbFNoYWRlckNvbnN0YW50c0lbaV0gPSBUUlVFOwogICAgICAgIH0KICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfcHNfY29uc3RzX2kgPSBNQVhfQ09OU1RfSTsKCiAgICAgICAgZm9yIChpID0gMDsgaSA8IE5VTV9TQVZFRFBJWEVMU1RBVEVTX1I7IGkrKykgewogICAgICAgICAgICBvYmplY3QtPmNoYW5nZWQucmVuZGVyU3RhdGVbU2F2ZWRQaXhlbFN0YXRlc19SW2ldXSA9IFRSVUU7CiAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3JlbmRlcl9zdGF0ZXNbaV0gPSBTYXZlZFBpeGVsU3RhdGVzX1JbaV07CiAgICAgICAgfQogICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF9yZW5kZXJfc3RhdGVzID0gTlVNX1NBVkVEUElYRUxTVEFURVNfUjsKICAgICAgICBmb3IgKGogPSAwOyBqIDwgTUFYX1RFWFRVUkVTOyBqKyspIHsKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IE5VTV9TQVZFRFBJWEVMU1RBVEVTX1Q7IGkrKykgewogICAgICAgICAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnRleHR1cmVTdGF0ZVtqXVtTYXZlZFBpeGVsU3RhdGVzX1RbaV1dID0gVFJVRTsKICAgICAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3Rzc19zdGF0ZXNbb2JqZWN0LT5udW1fY29udGFpbmVkX3Rzc19zdGF0ZXNdLnN0YWdlID0gajsKICAgICAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3Rzc19zdGF0ZXNbb2JqZWN0LT5udW1fY29udGFpbmVkX3Rzc19zdGF0ZXNdLnN0YXRlID0gU2F2ZWRQaXhlbFN0YXRlc19UW2ldOwogICAgICAgICAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3Rzc19zdGF0ZXMrKzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3IgKGogPSAwIDsgaiA8IE1BWF9DT01CSU5FRF9TQU1QTEVSUzsgaisrKSB7CiAgICAgICAgICAgIGZvciAoaSA9MDsgaSA8IE5VTV9TQVZFRFBJWEVMU1RBVEVTX1M7aSsrKSB7CiAgICAgICAgICAgICAgICBvYmplY3QtPmNoYW5nZWQuc2FtcGxlclN0YXRlW2pdW1NhdmVkUGl4ZWxTdGF0ZXNfU1tpXV0gPSBUUlVFOwogICAgICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfc2FtcGxlcl9zdGF0ZXNbb2JqZWN0LT5udW1fY29udGFpbmVkX3NhbXBsZXJfc3RhdGVzXS5zdGFnZSA9IGo7CiAgICAgICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF9zYW1wbGVyX3N0YXRlc1tvYmplY3QtPm51bV9jb250YWluZWRfc2FtcGxlcl9zdGF0ZXNdLnN0YXRlID0gU2F2ZWRQaXhlbFN0YXRlc19TW2ldOwogICAgICAgICAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3NhbXBsZXJfc3RhdGVzKys7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYob2JqZWN0LT5waXhlbFNoYWRlcikgewogICAgICAgICAgICBJV2luZUQzRFBpeGVsU2hhZGVyX0FkZFJlZihvYmplY3QtPnBpeGVsU2hhZGVyKTsKICAgICAgICB9CgogICAgICAgIC8qIFBpeGVsIHN0YXRlIGJsb2NrcyBkbyBub3QgY29udGFpbiB2ZXJ0ZXggYnVmZmVycy4gU2V0IHRoZW0gdG8gTlVMTCB0byBhdm9pZCB3cm9uZyByZWZjb3VudGluZwogICAgICAgICAqIG9uIHRoZW0uIFRoaXMgbWFrZXMgcmVsZWFzaW5nIHRoZSBidWZmZXIgZWFzaWVyCiAgICAgICAgICovCiAgICAgICAgZm9yKGkgPSAwOyBpIDwgTUFYX1NUUkVBTVM7IGkrKykgewogICAgICAgICAgICBvYmplY3QtPnN0cmVhbVNvdXJjZVtpXSA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIG9iamVjdC0+cEluZGV4RGF0YSA9IE5VTEw7CiAgICAgICAgb2JqZWN0LT52ZXJ0ZXhTaGFkZXIgPSBOVUxMOwoKICAgIH0gZWxzZSBpZiAoVHlwZSA9PSBXSU5FRDNEU0JUX1ZFUlRFWFNUQVRFKSB7CgogICAgICAgIFRSQUNFKCJWRVJURVhTVEFURSA9PiBQcmV0ZW5kIGFsbCB2ZXJ0ZXggc2hhdGVzIGhhdmUgY2hhbmdlZFxuIik7CiAgICAgICAgc3RhdGVibG9ja19zYXZlZHN0YXRlc19zZXQoKElXaW5lRDNEU3RhdGVCbG9jayopIG9iamVjdCwgJm9iamVjdC0+Y2hhbmdlZCwgRkFMU0UpOwoKICAgICAgICBvYmplY3QtPmNoYW5nZWQudmVydGV4U2hhZGVyID0gVFJVRTsKCiAgICAgICAgLyogVmVydGV4IFNoYWRlciBDb25zdGFudHMgKi8KICAgICAgICBmb3IgKGkgPSAwOyBpIDwgR0xfTElNSVRTKHZzaGFkZXJfY29uc3RhbnRzRik7ICsraSkgewogICAgICAgICAgICBvYmplY3QtPmNoYW5nZWQudmVydGV4U2hhZGVyQ29uc3RhbnRzRltpXSA9IFRSVUU7CiAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3ZzX2NvbnN0c19mW2ldID0gaTsKICAgICAgICB9CiAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3ZzX2NvbnN0c19mID0gR0xfTElNSVRTKHZzaGFkZXJfY29uc3RhbnRzRik7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IE1BWF9DT05TVF9COyArK2kpIHsKICAgICAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnZlcnRleFNoYWRlckNvbnN0YW50c0JbaV0gPSBUUlVFOwogICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF92c19jb25zdHNfYltpXSA9IGk7CiAgICAgICAgfQogICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF92c19jb25zdHNfYiA9IE1BWF9DT05TVF9COwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBNQVhfQ09OU1RfSTsgKytpKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y2hhbmdlZC52ZXJ0ZXhTaGFkZXJDb25zdGFudHNJW2ldID0gVFJVRTsKICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfdnNfY29uc3RzX2lbaV0gPSBpOwogICAgICAgIH0KICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfdnNfY29uc3RzX2kgPSBNQVhfQ09OU1RfSTsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgTlVNX1NBVkVEVkVSVEVYU1RBVEVTX1I7IGkrKykgewogICAgICAgICAgICBvYmplY3QtPmNoYW5nZWQucmVuZGVyU3RhdGVbU2F2ZWRWZXJ0ZXhTdGF0ZXNfUltpXV0gPSBUUlVFOwogICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF9yZW5kZXJfc3RhdGVzW2ldID0gU2F2ZWRWZXJ0ZXhTdGF0ZXNfUltpXTsKICAgICAgICB9CiAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3JlbmRlcl9zdGF0ZXMgPSBOVU1fU0FWRURWRVJURVhTVEFURVNfUjsKICAgICAgICBmb3IgKGogPSAwOyBqIDwgTUFYX1RFWFRVUkVTOyBqKyspIHsKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IE5VTV9TQVZFRFZFUlRFWFNUQVRFU19UOyBpKyspIHsKICAgICAgICAgICAgICAgIG9iamVjdC0+Y2hhbmdlZC50ZXh0dXJlU3RhdGVbal1bU2F2ZWRWZXJ0ZXhTdGF0ZXNfVFtpXV0gPSBUUlVFOwogICAgICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfdHNzX3N0YXRlc1tvYmplY3QtPm51bV9jb250YWluZWRfdHNzX3N0YXRlc10uc3RhZ2UgPSBqOwogICAgICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfdHNzX3N0YXRlc1tvYmplY3QtPm51bV9jb250YWluZWRfdHNzX3N0YXRlc10uc3RhdGUgPSBTYXZlZFZlcnRleFN0YXRlc19UW2ldOwogICAgICAgICAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3Rzc19zdGF0ZXMrKzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3IgKGogPSAwIDsgaiA8IE1BWF9DT01CSU5FRF9TQU1QTEVSUzsgaisrKXsKICAgICAgICAgICAgZm9yIChpID0wOyBpIDwgTlVNX1NBVkVEVkVSVEVYU1RBVEVTX1M7aSsrKSB7CiAgICAgICAgICAgICAgICBvYmplY3QtPmNoYW5nZWQuc2FtcGxlclN0YXRlW2pdW1NhdmVkVmVydGV4U3RhdGVzX1NbaV1dID0gVFJVRTsKICAgICAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3NhbXBsZXJfc3RhdGVzW29iamVjdC0+bnVtX2NvbnRhaW5lZF9zYW1wbGVyX3N0YXRlc10uc3RhZ2UgPSBqOwogICAgICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfc2FtcGxlcl9zdGF0ZXNbb2JqZWN0LT5udW1fY29udGFpbmVkX3NhbXBsZXJfc3RhdGVzXS5zdGF0ZSA9IFNhdmVkVmVydGV4U3RhdGVzX1NbaV07CiAgICAgICAgICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfc2FtcGxlcl9zdGF0ZXMrKzsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgZm9yKGogPSAwOyBqIDwgTElHSFRNQVBfU0laRTsgaisrKSB7CiAgICAgICAgICAgIHN0cnVjdCBsaXN0ICplOwogICAgICAgICAgICBMSVNUX0ZPUl9FQUNIKGUsICZvYmplY3QtPmxpZ2h0TWFwW2pdKSB7CiAgICAgICAgICAgICAgICBQTElHSFRJTkZPRUwgKmxpZ2h0ID0gTElTVF9FTlRSWShlLCBQTElHSFRJTkZPRUwsIGVudHJ5KTsKICAgICAgICAgICAgICAgIGxpZ2h0LT5jaGFuZ2VkID0gVFJVRTsKICAgICAgICAgICAgICAgIGxpZ2h0LT5lbmFibGVkQ2hhbmdlZCA9IFRSVUU7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvcihpID0gMDsgaSA8IE1BWF9TVFJFQU1TOyBpKyspIHsKICAgICAgICAgICAgaWYob2JqZWN0LT5zdHJlYW1Tb3VyY2VbaV0pIHsKICAgICAgICAgICAgICAgIElXaW5lRDNEVmVydGV4QnVmZmVyX0FkZFJlZihvYmplY3QtPnN0cmVhbVNvdXJjZVtpXSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYob2JqZWN0LT52ZXJ0ZXhTaGFkZXIpIHsKICAgICAgICAgICAgSVdpbmVEM0RWZXJ0ZXhTaGFkZXJfQWRkUmVmKG9iamVjdC0+dmVydGV4U2hhZGVyKTsKICAgICAgICB9CiAgICAgICAgb2JqZWN0LT5wSW5kZXhEYXRhID0gTlVMTDsKICAgICAgICBvYmplY3QtPnBpeGVsU2hhZGVyID0gTlVMTDsKICAgIH0gZWxzZSB7CiAgICAgICAgRklYTUUoIlVucmVjb2duaXplZCBzdGF0ZSBibG9jayB0eXBlICVkXG4iLCBUeXBlKTsKICAgIH0KCiAgICBUUkFDRSgiKCVwKSByZXR1cm5pbmcgdG9rZW4gKHB0ciB0byBzdGF0ZWJsb2NrKSBvZiAlcFxuIiwgVGhpcywgb2JqZWN0KTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKTVNETjoKW2luXSBSZW5kZXIgdGFyZ2V0cyBhcmUgbm90IGxvY2thYmxlIHVubGVzcyB0aGUgYXBwbGljYXRpb24gc3BlY2lmaWVzIFRSVUUgZm9yIExvY2thYmxlLiBOb3RlIHRoYXQgbG9ja2FibGUgcmVuZGVyIHRhcmdldHMgcmVkdWNlIHBlcmZvcm1hbmNlIG9uIHNvbWUgZ3JhcGhpY3MgaGFyZHdhcmUuCgpEaXNjYXJkCiBbaW5dIFNldCB0aGlzIGZsYWcgdG8gVFJVRSB0byBlbmFibGUgei1idWZmZXIgZGlzY2FyZGluZywgYW5kIEZBTFNFIG90aGVyd2lzZS4gCgpJZiB0aGlzIGZsYWcgaXMgc2V0LCB0aGUgY29udGVudHMgb2YgdGhlIGRlcHRoIHN0ZW5jaWwgYnVmZmVyIHdpbGwgYmUgaW52YWxpZCBhZnRlciBjYWxsaW5nIGVpdGhlciBJRGlyZWN0M0REZXZpY2U5OjpQcmVzZW50IG9yIElEaXJlY3QzRERldmljZTk6OlNldERlcHRoU3RlbmNpbFN1cmZhY2Ugd2l0aCBhIGRpZmZlcmVudCBkZXB0aCBzdXJmYWNlLgoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KIApzdGF0aWMgSFJFU1VMVCAgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVTdXJmYWNlKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBXaWR0aCwgVUlOVCBIZWlnaHQsIFdJTkVEM0RGT1JNQVQgRm9ybWF0LCBCT09MIExvY2thYmxlLCBCT09MIERpc2NhcmQsIFVJTlQgTGV2ZWwsIElXaW5lRDNEU3VyZmFjZSAqKnBwU3VyZmFjZSxXSU5FRDNEUkVTT1VSQ0VUWVBFIFR5cGUsIERXT1JEIFVzYWdlLCBXSU5FRDNEUE9PTCBQb29sLCBXSU5FRDNETVVMVElTQU1QTEVfVFlQRSBNdWx0aVNhbXBsZSAsRFdPUkQgTXVsdGlzYW1wbGVRdWFsaXR5LCBIQU5ETEUqIHBTaGFyZWRIYW5kbGUsIFdJTkVEM0RTVVJGVFlQRSBJbXBsLCBJVW5rbm93biAqcGFyZW50KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOyAgICAKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKm9iamVjdDsgLypOT1RFOiBpbXBsIHJlZiBhbGxvd2VkIHNpbmNlIHRoaXMgaXMgYSBjcmVhdGUgZnVuY3Rpb24gKi8KICAgIHVuc2lnbmVkIGludCBTaXplICAgICAgID0gMTsKICAgIGNvbnN0IFN0YXRpY1BpeGVsRm9ybWF0RGVzYyAqdGFibGVFbnRyeSA9IGdldEZvcm1hdERlc2NFbnRyeShGb3JtYXQsIE5VTEwsIE5VTEwpOwogICAgVFJBQ0UoIiglcCkgQ3JlYXRlIHN1cmZhY2VcbiIsVGhpcyk7CiAgICAKICAgIC8qKiBGSVhNRTogQ2hlY2sgcmFuZ2VzIG9uIHRoZSBpbnB1dHMgYXJlIHZhbGlkIAogICAgICogTVNETgogICAgICogICBNdWx0aXNhbXBsZVF1YWxpdHkKICAgICAqICAgIFtpbl0gUXVhbGl0eSBsZXZlbC4gVGhlIHZhbGlkIHJhbmdlIGlzIGJldHdlZW4gemVybyBhbmQgb25lIGxlc3MgdGhhbiB0aGUgbGV2ZWwKICAgICAqICAgIHJldHVybmVkIGJ5IHBRdWFsaXR5TGV2ZWxzIHVzZWQgYnkgSURpcmVjdDNEOTo6Q2hlY2tEZXZpY2VNdWx0aVNhbXBsZVR5cGUuIAogICAgICogICAgUGFzc2luZyBhIGxhcmdlciB2YWx1ZSByZXR1cm5zIHRoZSBlcnJvciBXSU5FRDNERVJSX0lOVkFMSURDQUxMLiBUaGUgTXVsdGlzYW1wbGVRdWFsaXR5CiAgICAgKiAgICB2YWx1ZXMgb2YgcGFpcmVkIHJlbmRlciB0YXJnZXRzLCBkZXB0aCBzdGVuY2lsIHN1cmZhY2VzLCBhbmQgdGhlIE11bHRpU2FtcGxlIHR5cGUKICAgICAqICAgIG11c3QgYWxsIG1hdGNoLgogICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKCiAgICAvKioKICAgICogVE9ETzogRGlzY2FyZCBNU0ROCiAgICAqIFtpbl0gU2V0IHRoaXMgZmxhZyB0byBUUlVFIHRvIGVuYWJsZSB6LWJ1ZmZlciBkaXNjYXJkaW5nLCBhbmQgRkFMU0Ugb3RoZXJ3aXNlLgogICAgKgogICAgKiBJZiB0aGlzIGZsYWcgaXMgc2V0LCB0aGUgY29udGVudHMgb2YgdGhlIGRlcHRoIHN0ZW5jaWwgYnVmZmVyIHdpbGwgYmUKICAgICogaW52YWxpZCBhZnRlciBjYWxsaW5nIGVpdGhlciBJRGlyZWN0M0REZXZpY2U5OjpQcmVzZW50IG9yICAqIElEaXJlY3QzRERldmljZTk6OlNldERlcHRoU3RlbmNpbFN1cmZhY2UKICAgICogd2l0aCBhIGRpZmZlcmVudCBkZXB0aCBzdXJmYWNlLgogICAgKgogICAgKlRoaXMgZmxhZyBoYXMgdGhlIHNhbWUgYmVoYXZpb3IgYXMgdGhlIGNvbnN0YW50LCBEM0RQUkVTRU5URkxBR19ESVNDQVJEX0RFUFRIU1RFTkNJTCwgaW4gRDNEUFJFU0VOVEZMQUcuCiAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgaWYoTXVsdGlzYW1wbGVRdWFsaXR5ID4gMCkgewogICAgICAgIEZJWE1FKCJNdWx0aXNhbXBsZVF1YWxpdHkgc2V0IHRvICVkLCBzdWJzdGl0dXRpbmcgMFxuIiwgTXVsdGlzYW1wbGVRdWFsaXR5KTsKICAgICAgICBNdWx0aXNhbXBsZVF1YWxpdHk9MDsKICAgIH0KCiAgICAvKiogRklYTUU6IENoZWNrIHRoYXQgdGhlIGZvcm1hdCBpcyBzdXBwb3J0ZWQKICAgICogICAgYnkgdGhlIGRldmljZS4KICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKiogRFhUbiBtaXBtYXBzIHVzZSB0aGUgc2FtZSBudW1iZXIgb2YgJ2xldmVscycgZG93biB0byBlZy4gOHgxLCBidXQgc2luY2UKICAgICAqICBpdCBpcyBiYXNlZCBhcm91bmQgNHg0IHBpeGVsIGJsb2NrcyBpdCByZXF1aXJlcyBwYWRkaW5nLCBzbyBhbGxvY2F0ZSBlbm91Z2gKICAgICAqICBzcGFjZSEKICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgaWYgKFdJTkVEM0RGTVRfVU5LTk9XTiA9PSBGb3JtYXQpIHsKICAgICAgICBTaXplID0gMDsKICAgIH0gZWxzZSBpZiAoRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMSkgewogICAgICAgIC8qIERYVDEgaXMgaGFsZiBieXRlIHBlciBwaXhlbCAqLwogICAgICAgU2l6ZSA9ICgobWF4KFdpZHRoLDQpICogdGFibGVFbnRyeS0+YnBwKSAqIG1heChIZWlnaHQsNCkpID4+IDE7CgogICAgfSBlbHNlIGlmIChGb3JtYXQgPT0gV0lORUQzREZNVF9EWFQyIHx8IEZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDMgfHwKICAgICAgICAgICAgICAgRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNCB8fCBGb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ1KSB7CiAgICAgICBTaXplID0gKChtYXgoV2lkdGgsNCkgKiB0YWJsZUVudHJ5LT5icHApICogbWF4KEhlaWdodCw0KSk7CiAgICB9IGVsc2UgewogICAgICAgLyogVGhlIHBpdGNoIGlzIGEgbXVsdGlwbGUgb2YgNCBieXRlcyAqLwogICAgICAgIFNpemUgPSAoKFdpZHRoICogdGFibGVFbnRyeS0+YnBwKSArIFRoaXMtPnN1cmZhY2VfYWxpZ25tZW50IC0gMSkgJiB+KFRoaXMtPnN1cmZhY2VfYWxpZ25tZW50IC0gMSk7CiAgICAgICBTaXplICo9IEhlaWdodDsKICAgIH0KCiAgICAvKiogQ3JlYXRlIGFuZCBpbml0aWFsaXNlIHRoZSBzdXJmYWNlIHJlc291cmNlICoqLwogICAgRDNEQ1JFQVRFUkVTT1VSQ0VPQkpFQ1RJTlNUQU5DRShvYmplY3QsU3VyZmFjZSxXSU5FRDNEUlRZUEVfU1VSRkFDRSwgU2l6ZSkKICAgIC8qICJTdGFuZGFsb25lIiBzdXJmYWNlICovCiAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29udGFpbmVyKChJV2luZUQzRFN1cmZhY2UgKilvYmplY3QsIE5VTEwpOwoKICAgIG9iamVjdC0+Y3VycmVudERlc2MuV2lkdGggICAgICA9IFdpZHRoOwogICAgb2JqZWN0LT5jdXJyZW50RGVzYy5IZWlnaHQgICAgID0gSGVpZ2h0OwogICAgb2JqZWN0LT5jdXJyZW50RGVzYy5NdWx0aVNhbXBsZVR5cGUgICAgPSBNdWx0aVNhbXBsZTsKICAgIG9iamVjdC0+Y3VycmVudERlc2MuTXVsdGlTYW1wbGVRdWFsaXR5ID0gTXVsdGlzYW1wbGVRdWFsaXR5OwogICAgb2JqZWN0LT5nbERlc2NyaXB0aW9uLmxldmVsICAgICAgICAgICAgPSBMZXZlbDsKCiAgICAvKiBGbGFncyAqLwogICAgb2JqZWN0LT5GbGFncyAgICAgID0gMDsKICAgIG9iamVjdC0+RmxhZ3MgICAgIHw9IERpc2NhcmQgPyBTRkxBR19ESVNDQVJEIDogMDsKICAgIG9iamVjdC0+RmxhZ3MgICAgIHw9IChXSU5FRDNERk1UX0QxNl9MT0NLQUJMRSA9PSBGb3JtYXQpID8gU0ZMQUdfTE9DS0FCTEUgOiAwOwogICAgb2JqZWN0LT5GbGFncyAgICAgfD0gTG9ja2FibGUgPyBTRkxBR19MT0NLQUJMRSA6IDA7CgoKICAgIGlmIChXSU5FRDNERk1UX1VOS05PV04gIT0gRm9ybWF0KSB7CiAgICAgICAgb2JqZWN0LT5ieXRlc1BlclBpeGVsID0gdGFibGVFbnRyeS0+YnBwOwogICAgfSBlbHNlIHsKICAgICAgICBvYmplY3QtPmJ5dGVzUGVyUGl4ZWwgPSAwOwogICAgfQoKICAgIC8qKiBUT0RPOiBjaGFuZ2UgdGhpcyBpbnRvIGEgdGV4dHVyZSB0cmFuc2Zvcm0gbWF0cml4IHNvIHRoYXQgaXQncyBwcm9jZXNzZWQgaW4gaGFyZHdhcmUgKiovCgogICAgVFJBQ0UoIlBvb2wgJWQgJWQgJWQgJWRcbiIsUG9vbCwgV0lORUQzRFBPT0xfREVGQVVMVCwgV0lORUQzRFBPT0xfTUFOQUdFRCwgV0lORUQzRFBPT0xfU1lTVEVNTUVNKTsKCiAgICAvKiogUXVpY2sgbG9ja2FibGUgc2FuaXR5IGNoZWNrIFRPRE86IHJlbW92ZSB0aGlzIGFmdGVyIHN1cmZhY2VzLCB1c2FnZSBhbmQgbG9ja2FiaWxpdHkgaGF2ZSBiZWVuIGRlYnVnZ2VkIHByb3Blcmx5CiAgICAqIHRoaXMgZnVuY3Rpb24gaXMgdG9vIGRlZXAgdG8gbmVlZCB0byBjYXJlIGFib3V0IHRoaW5ncyBsaWtlIHRoaXMuCiAgICAqIExldmVscyBuZWVkIHRvIGJlIGNoZWNrZWQgdG9vLCBhbmQgcG9zc2libHkgVHlwZSBzaW5jZSB0aGV5IGFsbCBhZmZlY3Qgd2hhdCBjYW4gYmUgZG9uZS4KICAgICogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgIHN3aXRjaChQb29sKSB7CiAgICBjYXNlIFdJTkVEM0RQT09MX1NDUkFUQ0g6CiAgICAgICAgaWYoIUxvY2thYmxlKQogICAgICAgICAgICBGSVhNRSgiQ3JlYXRlIHN1cmZhY2UgY2FsbGVkIHdpdGggYSBwb29sIG9mIFNDUkFUQ0ggYW5kIGEgTG9ja2FibGUgb2YgRkFMU0UgIgogICAgICAgICAgICAgICAgIndoaWNoIGFyZSBtdXR1YWxseSBleGNsdXNpdmUsIHNldHRpbmcgbG9ja2FibGUgdG8gVFJVRVxuIik7CiAgICAgICAgICAgICAgICBMb2NrYWJsZSA9IFRSVUU7CiAgICBicmVhazsKICAgIGNhc2UgV0lORUQzRFBPT0xfU1lTVEVNTUVNOgogICAgICAgIGlmKCFMb2NrYWJsZSkgRklYTUUoIkNyZWF0ZSBzdXJmYWNlIGNhbGxlZCB3aXRoIGEgcG9vbCBvZiBTWVNURU1NRU0gYW5kIGEgTG9ja2FibGUgb2YgRkFMU0UsICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRoaXMgaXMgYWNjZXB0YWJsZSBidXQgdW5leHBlY3RlZCAoSSBjYW4ndCBrbm93IGhvdyB0aGUgc3VyZmFjZSBjYW4gYmUgdXNhYmxlISlcbiIpOwogICAgY2FzZSBXSU5FRDNEUE9PTF9NQU5BR0VEOgogICAgICAgIGlmKFVzYWdlID09IFdJTkVEM0RVU0FHRV9EWU5BTUlDKSBGSVhNRSgiQ3JlYXRlIHN1cmZhY2UgY2FsbGVkIHdpdGggYSBwb29sIG9mIE1BTkFHRUQgYW5kIGEgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVXNhZ2Ugb2YgRFlOQU1JQyB3aGljaCBhcmUgbXV0dWFsbHkgZXhjbHVzaXZlLCBub3QgZG9pbmcgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYW55dGhpbmcganVzdCB0ZWxsaW5nIHlvdS5cbiIpOwogICAgYnJlYWs7CiAgICBjYXNlIFdJTkVEM0RQT09MX0RFRkFVTFQ6IC8qVE9ETzogQ3JlYXRlIG9mZnNjcmVlbiBwbGFpbiBjYW4gY2F1c2UgdGhpcyBjaGVjayB0byBmYWlsLi4uLCBmaW5kIG91dCBpZiBpdCBzaG91bGQgKi8KICAgICAgICBpZighKFVzYWdlICYgV0lORUQzRFVTQUdFX0RZTkFNSUMpICYmICEoVXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKQogICAgICAgICAgICYmICEoVXNhZ2UgJiYgV0lORUQzRFVTQUdFX0RFUFRIU1RFTkNJTCApICYmIExvY2thYmxlKQogICAgICAgICAgICBXQVJOKCJDcmVhdGluZyBhIHN1cmZhY2Ugd2l0aCBhIFBPT0wgb2YgREVGQVVMVCB3aXRoIExvY2thYmxlIHRydWUsIHRoYXQgZG9lc24ndCBzcGVjaWZ5IERZTkFNSUMgdXNhZ2UuXG4iKTsKICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBGSVhNRSgiKCVwKSBVbmtub3duIHBvb2wgJWRcbiIsIFRoaXMsIFBvb2wpOwogICAgYnJlYWs7CiAgICB9OwoKICAgIGlmIChVc2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQgJiYgUG9vbCAhPSBXSU5FRDNEUE9PTF9ERUZBVUxUKSB7CiAgICAgICAgRklYTUUoIlRyeWluZyB0byBjcmVhdGUgYSByZW5kZXIgdGFyZ2V0IHRoYXQgaXNuJ3QgaW4gdGhlIGRlZmF1bHQgcG9vbFxuIik7CiAgICB9CgogICAgLyogbWFyayB0aGUgdGV4dHVyZSBhcyBkaXJ0eSBzbyB0aGF0IGl0IGdldHMgbG9hZGVkIGZpcnN0IHRpbWUgYXJvdW5kKi8KICAgIElXaW5lRDNEU3VyZmFjZV9BZGREaXJ0eVJlY3QoKnBwU3VyZmFjZSwgTlVMTCk7CiAgICBUUkFDRSgiKCVwKSA6IHcoJWQpIGgoJWQpIGZtdCglZCwlcykgbG9ja2FibGUoJWQpIHN1cmZAJXAsIHN1cmZtZW1AJXAsICVkIGJ5dGVzXG4iLAogICAgICAgICAgIFRoaXMsIFdpZHRoLCBIZWlnaHQsIEZvcm1hdCwgZGVidWdfZDNkZm9ybWF0KEZvcm1hdCksCiAgICAgICAgICAgKFdJTkVEM0RGTVRfRDE2X0xPQ0tBQkxFID09IEZvcm1hdCksICpwcFN1cmZhY2UsIG9iamVjdC0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5LCBvYmplY3QtPnJlc291cmNlLnNpemUpOwoKICAgIC8qIFN0b3JlIHRoZSBEaXJlY3REcmF3IHByaW1hcnkgc3VyZmFjZS4gVGhpcyBpcyB0aGUgZmlyc3QgcmVuZGVydGFyZ2V0IHN1cmZhY2UgY3JlYXRlZCAqLwogICAgaWYoIChVc2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpICYmICghVGhpcy0+ZGRyYXdfcHJpbWFyeSkgKQogICAgICAgIFRoaXMtPmRkcmF3X3ByaW1hcnkgPSAoSVdpbmVEM0RTdXJmYWNlICopIG9iamVjdDsKCiAgICAvKiBMb29rIGF0IHRoZSBpbXBsZW1lbnRhdGlvbiBhbmQgc2V0IHRoZSBjb3JyZWN0IFZ0YWJsZSAqLwogICAgc3dpdGNoKEltcGwpIHsKICAgICAgICBjYXNlIFNVUkZBQ0VfT1BFTkdMOgogICAgICAgICAgICAvKiBDaGVjayBpZiBhIDNEIGFkYXB0ZXIgaXMgYXZhaWxhYmxlIHdoZW4gY3JlYXRpbmcgZ2wgc3VyZmFjZXMgKi8KICAgICAgICAgICAgaWYoIVRoaXMtPmFkYXB0ZXIpIHsKICAgICAgICAgICAgICAgIEVSUigiT3BlbkdMIHN1cmZhY2VzIGFyZSBub3QgYXZhaWxhYmxlIHdpdGhvdXQgb3BlbmdsXG4iKTsKICAgICAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9iamVjdC0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgICAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9iamVjdCk7CiAgICAgICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9OT1RBVkFJTEFCTEU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgU1VSRkFDRV9HREk6CiAgICAgICAgICAgIG9iamVjdC0+bHBWdGJsID0gJklXaW5lR0RJU3VyZmFjZV9WdGJsOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgLyogVG8gYmUgc3VyZSB0byBjYXRjaCB0aGlzICovCiAgICAgICAgICAgIEVSUigiVW5rbm93biByZXF1ZXN0ZWQgc3VyZmFjZSBpbXBsZW1lbnRhdGlvbiAlZCFcbiIsIEltcGwpOwogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZSgoSVdpbmVEM0RTdXJmYWNlICopIG9iamVjdCk7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGxpc3RfaW5pdCgmb2JqZWN0LT5yZW5kZXJidWZmZXJzKTsKCiAgICAvKiBDYWxsIHRoZSBwcml2YXRlIHNldHVwIHJvdXRpbmUgKi8KICAgIHJldHVybiBJV2luZUQzRFN1cmZhY2VfUHJpdmF0ZVNldHVwKCAoSVdpbmVEM0RTdXJmYWNlICopIG9iamVjdCApOwoKfQoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVGV4dHVyZShJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgV2lkdGgsIFVJTlQgSGVpZ2h0LCBVSU5UIExldmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFVzYWdlLCBXSU5FRDNERk9STUFUIEZvcm1hdCwgV0lORUQzRFBPT0wgUG9vbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEVGV4dHVyZSoqIHBwVGV4dHVyZSwgSEFORExFKiBwU2hhcmVkSGFuZGxlLCBJVW5rbm93biAqcGFyZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEQ0JfQ1JFQVRFU1VSRkFDRUZOIEQzRENCX0NyZWF0ZVN1cmZhY2UpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFRleHR1cmVJbXBsICpvYmplY3Q7CiAgICB1bnNpZ25lZCBpbnQgaTsKICAgIFVJTlQgdG1wVzsKICAgIFVJTlQgdG1wSDsKICAgIEhSRVNVTFQgaHI7CiAgICB1bnNpZ25lZCBpbnQgcG93MldpZHRoOwogICAgdW5zaWduZWQgaW50IHBvdzJIZWlnaHQ7CiAgICBjb25zdCBHbFBpeGVsRm9ybWF0RGVzYyAqZ2xEZXNjOwogICAgZ2V0Rm9ybWF0RGVzY0VudHJ5KEZvcm1hdCwgJkdMSU5GT19MT0NBVElPTiwgJmdsRGVzYyk7CgoKICAgIFRSQUNFKCIoJXApIDogV2lkdGggJWQsIEhlaWdodCAlZCwgTGV2ZWxzICVkLCBVc2FnZSAlI3hcbiIsIFRoaXMsIFdpZHRoLCBIZWlnaHQsIExldmVscywgVXNhZ2UpOwogICAgVFJBQ0UoIkZvcm1hdCAlI3ggKCVzKSwgUG9vbCAlI3gsIHBwVGV4dHVyZSAlcCwgcFNoYXJlZEhhbmRsZSAlcCwgcGFyZW50ICVwXG4iLAogICAgICAgICAgICBGb3JtYXQsIGRlYnVnX2QzZGZvcm1hdChGb3JtYXQpLCBQb29sLCBwcFRleHR1cmUsIHBTaGFyZWRIYW5kbGUsIHBhcmVudCk7CgogICAgLyogVE9ETzogSXQgc2hvdWxkIG9ubHkgYmUgcG9zc2libGUgdG8gY3JlYXRlIHRleHR1cmVzIGZvciBmb3JtYXRzIAogICAgICAgICAgICAgdGhhdCBhcmUgcmVwb3J0ZWQgYXMgc3VwcG9ydGVkICovCiAgICBpZiAoV0lORUQzREZNVF9VTktOT1dOID49IEZvcm1hdCkgewogICAgICAgIFdBUk4oIiglcCkgOiBUZXh0dXJlIGNhbm5vdCBiZSBjcmVhdGVkIHdpdGggYSBmb3JtYXQgb2YgV0lORUQzREZNVF9VTktOT1dOXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBEM0RDUkVBVEVSRVNPVVJDRU9CSkVDVElOU1RBTkNFKG9iamVjdCwgVGV4dHVyZSwgV0lORUQzRFJUWVBFX1RFWFRVUkUsIDApOwogICAgRDNESU5JVElBTElaRUJBU0VURVhUVVJFKG9iamVjdC0+YmFzZVRleHR1cmUpOyAgICAKICAgIG9iamVjdC0+d2lkdGggID0gV2lkdGg7CiAgICBvYmplY3QtPmhlaWdodCA9IEhlaWdodDsKCiAgICAvKiogTm9uLXBvd2VyMiBzdXBwb3J0ICoqLwogICAgaWYgKEdMX1NVUFBPUlQoQVJCX1RFWFRVUkVfTk9OX1BPV0VSX09GX1RXTykpIHsKICAgICAgICBwb3cyV2lkdGggPSBXaWR0aDsKICAgICAgICBwb3cySGVpZ2h0ID0gSGVpZ2h0OwogICAgfSBlbHNlIHsKICAgICAgICAvKiBGaW5kIHRoZSBuZWFyZXN0IHBvdzIgbWF0Y2ggKi8KICAgICAgICBwb3cyV2lkdGggPSBwb3cySGVpZ2h0ID0gMTsKICAgICAgICB3aGlsZSAocG93MldpZHRoIDwgV2lkdGgpIHBvdzJXaWR0aCA8PD0gMTsKICAgICAgICB3aGlsZSAocG93MkhlaWdodCA8IEhlaWdodCkgcG93MkhlaWdodCA8PD0gMTsKCiAgICAgICAgaWYocG93MldpZHRoICE9IFdpZHRoIHx8IHBvdzJIZWlnaHQgIT0gSGVpZ2h0KSB7CiAgICAgICAgICAgIGlmKExldmVscyA+IDEpIHsKICAgICAgICAgICAgICAgIFdBUk4oIkF0dGVtcHRlZCB0byBjcmVhdGUgYSBtaXBtYXBwZWQgbnAyIHRleHR1cmUgd2l0aG91dCB1bmNvbmRpdGlvbmFsIG5wMiBzdXBwb3J0XG4iKTsKICAgICAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9iamVjdCk7CiAgICAgICAgICAgICAgICAqcHBUZXh0dXJlID0gTlVMTDsKICAgICAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgTGV2ZWxzID0gMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiogRklYTUU6IGFkZCBzdXBwb3J0IGZvciByZWFsIG5vbi1wb3dlci10d28gaWYgaXQncyBwcm92aWRlZCBieSB0aGUgdmlkZW8gY2FyZCAqKi8KICAgIC8qIFByZWNhbGN1bGF0ZWQgc2NhbGluZyBmb3IgJ2Zha2VkJyBub24gcG93ZXIgb2YgdHdvIHRleHR1cmUgY29vcmRzICovCiAgICBpZihHTF9TVVBQT1JUKEFSQl9URVhUVVJFX1JFQ1RBTkdMRSkgJiYKICAgICAgIChXaWR0aCAhPSBwb3cyV2lkdGggfHwgSGVpZ2h0ICE9IHBvdzJIZWlnaHQpKSB7CiAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5wb3cyTWF0cml4WzBdID0gIChmbG9hdClXaWR0aDsKICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLnBvdzJNYXRyaXhbNV0gPSAgKGZsb2F0KUhlaWdodDsKICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLnBvdzJNYXRyaXhbMTBdID0gMS4wOwogICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUucG93Mk1hdHJpeFsxNV0gPSAxLjA7CiAgICAgICAgb2JqZWN0LT50YXJnZXQgPSBHTF9URVhUVVJFX1JFQ1RBTkdMRV9BUkI7CiAgICB9IGVsc2UgewogICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUucG93Mk1hdHJpeFswXSA9ICAoKChmbG9hdClXaWR0aCkgIC8gKChmbG9hdClwb3cyV2lkdGgpKTsKICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLnBvdzJNYXRyaXhbNV0gPSAgKCgoZmxvYXQpSGVpZ2h0KSAvICgoZmxvYXQpcG93MkhlaWdodCkpOwogICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUucG93Mk1hdHJpeFsxMF0gPSAxLjA7CiAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5wb3cyTWF0cml4WzE1XSA9IDEuMDsKICAgICAgICBvYmplY3QtPnRhcmdldCA9IEdMX1RFWFRVUkVfMkQ7CiAgICB9CiAgICBUUkFDRSgiIHhmKCVmKSB5ZiglZilcbiIsIG9iamVjdC0+YmFzZVRleHR1cmUucG93Mk1hdHJpeFswXSwgb2JqZWN0LT5iYXNlVGV4dHVyZS5wb3cyTWF0cml4WzVdKTsKCiAgICAvKiBDYWxjdWxhdGUgbGV2ZWxzIGZvciBtaXAgbWFwcGluZyAqLwogICAgaWYgKFVzYWdlICYgV0lORUQzRFVTQUdFX0FVVE9HRU5NSVBNQVApIHsKICAgICAgICBpZighR0xfU1VQUE9SVChTR0lTX0dFTkVSQVRFX01JUE1BUCkpIHsKICAgICAgICAgICAgV0FSTigiTm8gbWlwbWFwIGdlbmVyYXRpb24gc3VwcG9ydCwgcmV0dXJuaW5nIEQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgIH0KICAgICAgICBpZihMZXZlbHMgPiAxKSB7CiAgICAgICAgICAgIFdBUk4oIkQzRFVTQUdFX0FVVE9HRU5NSVBNQVAgaXMgc2V0LCBhbmQgbGV2ZWwgY291bnQgPiAxLCByZXR1cm5pbmcgRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfQogICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzID0gMTsKICAgIH0gZWxzZSBpZiAoTGV2ZWxzID09IDApIHsKICAgICAgICBUUkFDRSgiY2FsY3VsYXRpbmcgbGV2ZWxzICVkXG4iLCBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVscyk7CiAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5sZXZlbHMrKzsKICAgICAgICB0bXBXID0gV2lkdGg7CiAgICAgICAgdG1wSCA9IEhlaWdodDsKICAgICAgICB3aGlsZSAodG1wVyA+IDEgfHwgdG1wSCA+IDEpIHsKICAgICAgICAgICAgdG1wVyA9IG1heCgxLCB0bXBXID4+IDEpOwogICAgICAgICAgICB0bXBIID0gbWF4KDEsIHRtcEggPj4gMSk7CiAgICAgICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzKys7CiAgICAgICAgfQogICAgICAgIFRSQUNFKCJDYWxjdWxhdGVkIGxldmVscyA9ICVkXG4iLCBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVscyk7CiAgICB9CgogICAgLyogR2VuZXJhdGUgYWxsIHRoZSBzdXJmYWNlcyAqLwogICAgdG1wVyA9IFdpZHRoOwogICAgdG1wSCA9IEhlaWdodDsKICAgIGZvciAoaSA9IDA7IGkgPCBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVsczsgaSsrKQogICAgewogICAgICAgIC8qIHVzZSB0aGUgY2FsbGJhY2sgdG8gY3JlYXRlIHRoZSB0ZXh0dXJlIHN1cmZhY2UgKi8KICAgICAgICBociA9IEQzRENCX0NyZWF0ZVN1cmZhY2UoVGhpcy0+cGFyZW50LCBwYXJlbnQsIHRtcFcsIHRtcEgsIEZvcm1hdCwgVXNhZ2UsIFBvb2wsIGksIFdJTkVEM0RDVUJFTUFQX0ZBQ0VfUE9TSVRJVkVfWCwgJm9iamVjdC0+c3VyZmFjZXNbaV0sTlVMTCk7CiAgICAgICAgaWYgKGhyIT0gV0lORUQzRF9PSyB8fCAoIChJV2luZUQzRFN1cmZhY2VJbXBsICopIG9iamVjdC0+c3VyZmFjZXNbaV0pLT5GbGFncyAmIFNGTEFHX09WRVJTSVpFKSB7CiAgICAgICAgICAgIEZJWE1FKCJGYWlsZWQgdG8gY3JlYXRlIHN1cmZhY2UgICVwXG4iLCBvYmplY3QpOwogICAgICAgICAgICAvKiBjbGVhbiB1cCAqLwogICAgICAgICAgICBvYmplY3QtPnN1cmZhY2VzW2ldID0gTlVMTDsKICAgICAgICAgICAgSVdpbmVEM0RUZXh0dXJlX1JlbGVhc2UoKElXaW5lRDNEVGV4dHVyZSAqKW9iamVjdCk7CgogICAgICAgICAgICAqcHBUZXh0dXJlID0gTlVMTDsKICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgICAgIH0KCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbnRhaW5lcihvYmplY3QtPnN1cmZhY2VzW2ldLCAoSVdpbmVEM0RCYXNlICopb2JqZWN0KTsKICAgICAgICBUUkFDRSgiQ3JlYXRlZCBzdXJmYWNlIGxldmVsICVkIEAgJXBcbiIsIGksIG9iamVjdC0+c3VyZmFjZXNbaV0pOwogICAgICAgIC8qIGNhbGN1bGF0ZSB0aGUgbmV4dCBtaXBtYXAgbGV2ZWwgKi8KICAgICAgICB0bXBXID0gbWF4KDEsIHRtcFcgPj4gMSk7CiAgICAgICAgdG1wSCA9IG1heCgxLCB0bXBIID4+IDEpOwogICAgfQogICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5zaGFkZXJfY29udmVyc2lvbl9ncm91cCA9IGdsRGVzYy0+Y29udmVyc2lvbl9ncm91cDsKCiAgICBUUkFDRSgiKCVwKSA6IENyZWF0ZWQgIHRleHR1cmUgJXBcbiIsIFRoaXMsIG9iamVjdCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWb2x1bWVUZXh0dXJlKElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBXaWR0aCwgVUlOVCBIZWlnaHQsIFVJTlQgRGVwdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgTGV2ZWxzLCBEV09SRCBVc2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzREZPUk1BVCBGb3JtYXQsIFdJTkVEM0RQT09MIFBvb2wsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEVm9sdW1lVGV4dHVyZSAqKnBwVm9sdW1lVGV4dHVyZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFICpwU2hhcmVkSGFuZGxlLCBJVW5rbm93biAqcGFyZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RDQl9DUkVBVEVWT0xVTUVGTiBEM0RDQl9DcmVhdGVWb2x1bWUpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgICAgICAgICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RWb2x1bWVUZXh0dXJlSW1wbCAqb2JqZWN0OwogICAgdW5zaWduZWQgaW50ICAgICAgICAgICAgICAgaTsKICAgIFVJTlQgICAgICAgICAgICAgICAgICAgICAgIHRtcFc7CiAgICBVSU5UICAgICAgICAgICAgICAgICAgICAgICB0bXBIOwogICAgVUlOVCAgICAgICAgICAgICAgICAgICAgICAgdG1wRDsKICAgIGNvbnN0IEdsUGl4ZWxGb3JtYXREZXNjICpnbERlc2M7CgogICAgZ2V0Rm9ybWF0RGVzY0VudHJ5KEZvcm1hdCwgJkdMSU5GT19MT0NBVElPTiwgJmdsRGVzYyk7CgogICAgLyogVE9ETzogSXQgc2hvdWxkIG9ubHkgYmUgcG9zc2libGUgdG8gY3JlYXRlIHRleHR1cmVzIGZvciBmb3JtYXRzIAogICAgICAgICAgICAgdGhhdCBhcmUgcmVwb3J0ZWQgYXMgc3VwcG9ydGVkICovCiAgICBpZiAoV0lORUQzREZNVF9VTktOT1dOID49IEZvcm1hdCkgewogICAgICAgIFdBUk4oIiglcCkgOiBUZXh0dXJlIGNhbm5vdCBiZSBjcmVhdGVkIHdpdGggYSBmb3JtYXQgb2YgV0lORUQzREZNVF9VTktOT1dOXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIGlmKCFHTF9TVVBQT1JUKEVYVF9URVhUVVJFM0QpKSB7CiAgICAgICAgV0FSTigiKCVwKSA6IFRleHR1cmUgY2Fubm90IGJlIGNyZWF0ZWQgLSBubyB2b2x1bWUgdGV4dHVyZSBzdXBwb3J0XG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBEM0RDUkVBVEVSRVNPVVJDRU9CSkVDVElOU1RBTkNFKG9iamVjdCwgVm9sdW1lVGV4dHVyZSwgV0lORUQzRFJUWVBFX1ZPTFVNRVRFWFRVUkUsIDApOwogICAgRDNESU5JVElBTElaRUJBU0VURVhUVVJFKG9iamVjdC0+YmFzZVRleHR1cmUpOwoKICAgIFRSQUNFKCIoJXApIDogVyglZCkgSCglZCkgRCglZCksIEx2bCglZCkgVXNhZ2UoJWQpLCBGbXQoJXUsJXMpLCBQb29sKCVzKVxuIiwgVGhpcywgV2lkdGgsIEhlaWdodCwKICAgICAgICAgIERlcHRoLCBMZXZlbHMsIFVzYWdlLCBGb3JtYXQsIGRlYnVnX2QzZGZvcm1hdChGb3JtYXQpLCBkZWJ1Z19kM2Rwb29sKFBvb2wpKTsKCiAgICBvYmplY3QtPndpZHRoICA9IFdpZHRoOwogICAgb2JqZWN0LT5oZWlnaHQgPSBIZWlnaHQ7CiAgICBvYmplY3QtPmRlcHRoICA9IERlcHRoOwoKICAgIC8qIElzIE5QMiBzdXBwb3J0IGZvciB2b2x1bWVzIG5lZWRlZD8gKi8KICAgIG9iamVjdC0+YmFzZVRleHR1cmUucG93Mk1hdHJpeFsgMF0gPSAxLjA7CiAgICBvYmplY3QtPmJhc2VUZXh0dXJlLnBvdzJNYXRyaXhbIDVdID0gMS4wOwogICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5wb3cyTWF0cml4WzEwXSA9IDEuMDsKICAgIG9iamVjdC0+YmFzZVRleHR1cmUucG93Mk1hdHJpeFsxNV0gPSAxLjA7CgogICAgLyogQ2FsY3VsYXRlIGxldmVscyBmb3IgbWlwIG1hcHBpbmcgKi8KICAgIGlmIChVc2FnZSAmIFdJTkVEM0RVU0FHRV9BVVRPR0VOTUlQTUFQKSB7CiAgICAgICAgaWYoIUdMX1NVUFBPUlQoU0dJU19HRU5FUkFURV9NSVBNQVApKSB7CiAgICAgICAgICAgIFdBUk4oIk5vIG1pcG1hcCBnZW5lcmF0aW9uIHN1cHBvcnQsIHJldHVybmluZyBEM0RFUlJfSU5WQUxJRENBTExcbiIpOwogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICB9CiAgICAgICAgaWYoTGV2ZWxzID4gMSkgewogICAgICAgICAgICBXQVJOKCJEM0RVU0FHRV9BVVRPR0VOTUlQTUFQIGlzIHNldCwgYW5kIGxldmVsIGNvdW50ID4gMSwgcmV0dXJuaW5nIEQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgIH0KICAgICAgICBMZXZlbHMgPSAxOwogICAgfSBlbHNlIGlmIChMZXZlbHMgPT0gMCkgewogICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzKys7CiAgICAgICAgdG1wVyA9IFdpZHRoOwogICAgICAgIHRtcEggPSBIZWlnaHQ7CiAgICAgICAgdG1wRCA9IERlcHRoOwogICAgICAgIHdoaWxlICh0bXBXID4gMSB8fCB0bXBIID4gMSB8fCB0bXBEID4gMSkgewogICAgICAgICAgICB0bXBXID0gbWF4KDEsIHRtcFcgPj4gMSk7CiAgICAgICAgICAgIHRtcEggPSBtYXgoMSwgdG1wSCA+PiAxKTsKICAgICAgICAgICAgdG1wRCA9IG1heCgxLCB0bXBEID4+IDEpOwogICAgICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVscysrOwogICAgICAgIH0KICAgICAgICBUUkFDRSgiQ2FsY3VsYXRlZCBsZXZlbHMgPSAlZFxuIiwgb2JqZWN0LT5iYXNlVGV4dHVyZS5sZXZlbHMpOwogICAgfQoKICAgIC8qIEdlbmVyYXRlIGFsbCB0aGUgc3VyZmFjZXMgKi8KICAgIHRtcFcgPSBXaWR0aDsKICAgIHRtcEggPSBIZWlnaHQ7CiAgICB0bXBEID0gRGVwdGg7CgogICAgZm9yIChpID0gMDsgaSA8IG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzOyBpKyspCiAgICB7CiAgICAgICAgSFJFU1VMVCBocjsKICAgICAgICAvKiBDcmVhdGUgdGhlIHZvbHVtZSAqLwogICAgICAgIGhyID0gRDNEQ0JfQ3JlYXRlVm9sdW1lKFRoaXMtPnBhcmVudCwgcGFyZW50LCB0bXBXLCB0bXBILCB0bXBELCBGb3JtYXQsIFBvb2wsIFVzYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJV2luZUQzRFZvbHVtZSAqKikmb2JqZWN0LT52b2x1bWVzW2ldLCBwU2hhcmVkSGFuZGxlKTsKCiAgICAgICAgaWYoRkFJTEVEKGhyKSkgewogICAgICAgICAgICBFUlIoIkNyZWF0aW5nIGEgdm9sdW1lIGZvciB0aGUgdm9sdW1lIHRleHR1cmUgZmFpbGVkKCUwOHgpXG4iLCBocik7CiAgICAgICAgICAgIElXaW5lRDNEVm9sdW1lVGV4dHVyZV9SZWxlYXNlKChJV2luZUQzRFZvbHVtZVRleHR1cmUgKikgb2JqZWN0KTsKICAgICAgICAgICAgKnBwVm9sdW1lVGV4dHVyZSA9IE5VTEw7CiAgICAgICAgICAgIHJldHVybiBocjsKICAgICAgICB9CgogICAgICAgIC8qIFNldCBpdHMgY29udGFpbmVyIHRvIHRoaXMgb2JqZWN0ICovCiAgICAgICAgSVdpbmVEM0RWb2x1bWVfU2V0Q29udGFpbmVyKG9iamVjdC0+dm9sdW1lc1tpXSwgKElXaW5lRDNEQmFzZSAqKW9iamVjdCk7CgogICAgICAgIC8qIGNhbGN1YWx0ZSB0aGUgbmV4dCBtaXBtYXAgbGV2ZWwgKi8KICAgICAgICB0bXBXID0gbWF4KDEsIHRtcFcgPj4gMSk7CiAgICAgICAgdG1wSCA9IG1heCgxLCB0bXBIID4+IDEpOwogICAgICAgIHRtcEQgPSBtYXgoMSwgdG1wRCA+PiAxKTsKICAgIH0KICAgIG9iamVjdC0+YmFzZVRleHR1cmUuc2hhZGVyX2NvbnZlcnNpb25fZ3JvdXAgPSBnbERlc2MtPmNvbnZlcnNpb25fZ3JvdXA7CgogICAgKnBwVm9sdW1lVGV4dHVyZSA9IChJV2luZUQzRFZvbHVtZVRleHR1cmUgKikgb2JqZWN0OwogICAgVFJBQ0UoIiglcCkgOiBDcmVhdGVkIHZvbHVtZSB0ZXh0dXJlICVwXG4iLCBUaGlzLCBvYmplY3QpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVm9sdW1lKElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFdpZHRoLCBVSU5UIEhlaWdodCwgVUlOVCBEZXB0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBVc2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNERk9STUFUIEZvcm1hdCwgV0lORUQzRFBPT0wgUG9vbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFZvbHVtZSoqIHBwVm9sdW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRSogcFNoYXJlZEhhbmRsZSwgSVVua25vd24gKnBhcmVudCkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgICAgICAgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFZvbHVtZUltcGwgICAgICAgICpvYmplY3Q7IC8qKiBOT1RFOiBpbXBsIHJlZiBhbGxvd2VkIHNpbmNlIHRoaXMgaXMgYSBjcmVhdGUgZnVuY3Rpb24gKiovCiAgICBjb25zdCBTdGF0aWNQaXhlbEZvcm1hdERlc2MgKmZvcm1hdERlc2MgID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KEZvcm1hdCwgTlVMTCwgTlVMTCk7CgogICAgaWYoIUdMX1NVUFBPUlQoRVhUX1RFWFRVUkUzRCkpIHsKICAgICAgICBXQVJOKCIoJXApIDogVm9sdW1lIGNhbm5vdCBiZSBjcmVhdGVkIC0gbm8gdm9sdW1lIHRleHR1cmUgc3VwcG9ydFxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgRDNEQ1JFQVRFUkVTT1VSQ0VPQkpFQ1RJTlNUQU5DRShvYmplY3QsIFZvbHVtZSwgV0lORUQzRFJUWVBFX1ZPTFVNRSwgKChXaWR0aCAqIGZvcm1hdERlc2MtPmJwcCkgKiBIZWlnaHQgKiBEZXB0aCkpCgogICAgVFJBQ0UoIiglcCkgOiBXKCVkKSBIKCVkKSBEKCVkKSwgVXNhZ2UoJWQpLCBGbXQoJXUsJXMpLCBQb29sKCVzKVxuIiwgVGhpcywgV2lkdGgsIEhlaWdodCwKICAgICAgICAgIERlcHRoLCBVc2FnZSwgRm9ybWF0LCBkZWJ1Z19kM2Rmb3JtYXQoRm9ybWF0KSwgZGVidWdfZDNkcG9vbChQb29sKSk7CgogICAgb2JqZWN0LT5jdXJyZW50RGVzYy5XaWR0aCAgID0gV2lkdGg7CiAgICBvYmplY3QtPmN1cnJlbnREZXNjLkhlaWdodCAgPSBIZWlnaHQ7CiAgICBvYmplY3QtPmN1cnJlbnREZXNjLkRlcHRoICAgPSBEZXB0aDsKICAgIG9iamVjdC0+Ynl0ZXNQZXJQaXhlbCAgICAgICA9IGZvcm1hdERlc2MtPmJwcDsKCiAgICAvKiogTm90ZTogVm9sdW1lIHRleHR1cmVzIGNhbm5vdCBiZSBkeHRuLCBoZW5jZSBubyBuZWVkIHRvIGNoZWNrIGhlcmUgKiovCiAgICBvYmplY3QtPmxvY2thYmxlICAgICAgICAgICAgPSBUUlVFOwogICAgb2JqZWN0LT5sb2NrZWQgICAgICAgICAgICAgID0gRkFMU0U7CiAgICBtZW1zZXQoJm9iamVjdC0+bG9ja2VkQm94LCAwLCBzaXplb2YoV0lORUQzREJPWCkpOwogICAgb2JqZWN0LT5kaXJ0eSAgICAgICAgICAgICAgID0gVFJVRTsKCiAgICByZXR1cm4gSVdpbmVEM0RWb2x1bWVfQWRkRGlydHlCb3goKElXaW5lRDNEVm9sdW1lICopIG9iamVjdCwgTlVMTCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlQ3ViZVRleHR1cmUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIEVkZ2VMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIExldmVscywgRFdPUkQgVXNhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNERk9STUFUIEZvcm1hdCwgV0lORUQzRFBPT0wgUG9vbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEQ3ViZVRleHR1cmUgKipwcEN1YmVUZXh0dXJlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFICpwU2hhcmVkSGFuZGxlLCBJVW5rbm93biAqcGFyZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEQ0JfQ1JFQVRFU1VSRkFDRUZOIEQzRENCX0NyZWF0ZVN1cmZhY2UpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgICAgICAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEQ3ViZVRleHR1cmVJbXBsICpvYmplY3Q7IC8qKiBOT1RFOiBpbXBsIHJlZiBhbGxvd2VkIHNpbmNlIHRoaXMgaXMgYSBjcmVhdGUgZnVuY3Rpb24gKiovCiAgICB1bnNpZ25lZCBpbnQgICAgICAgICAgICAgaSwgajsKICAgIFVJTlQgICAgICAgICAgICAgICAgICAgICB0bXBXOwogICAgSFJFU1VMVCAgICAgICAgICAgICAgICAgIGhyOwogICAgdW5zaWduZWQgaW50IHBvdzJFZGdlTGVuZ3RoICA9IEVkZ2VMZW5ndGg7CiAgICBjb25zdCBHbFBpeGVsRm9ybWF0RGVzYyAqZ2xEZXNjOwogICAgZ2V0Rm9ybWF0RGVzY0VudHJ5KEZvcm1hdCwgJkdMSU5GT19MT0NBVElPTiwgJmdsRGVzYyk7CgogICAgLyogVE9ETzogSXQgc2hvdWxkIG9ubHkgYmUgcG9zc2libGUgdG8gY3JlYXRlIHRleHR1cmVzIGZvciBmb3JtYXRzIAogICAgICAgICAgICAgdGhhdCBhcmUgcmVwb3J0ZWQgYXMgc3VwcG9ydGVkICovCiAgICBpZiAoV0lORUQzREZNVF9VTktOT1dOID49IEZvcm1hdCkgewogICAgICAgIFdBUk4oIiglcCkgOiBUZXh0dXJlIGNhbm5vdCBiZSBjcmVhdGVkIHdpdGggYSBmb3JtYXQgb2YgV0lORUQzREZNVF9VTktOT1dOXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBpZiAoIUdMX1NVUFBPUlQoQVJCX1RFWFRVUkVfQ1VCRV9NQVApICYmIFBvb2wgIT0gV0lORUQzRFBPT0xfU0NSQVRDSCkgewogICAgICAgIFdBUk4oIiglcCkgOiBUcmllZCB0byBjcmVhdGUgbm90IHN1cHBvcnRlZCBjdWJlIHRleHR1cmVcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIEQzRENSRUFURVJFU09VUkNFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBDdWJlVGV4dHVyZSwgV0lORUQzRFJUWVBFX0NVQkVURVhUVVJFLCAwKTsKICAgIEQzRElOSVRJQUxJWkVCQVNFVEVYVFVSRShvYmplY3QtPmJhc2VUZXh0dXJlKTsKCiAgICBUUkFDRSgiKCVwKSBDcmVhdGUgQ3ViZSBUZXh0dXJlXG4iLCBUaGlzKTsKCiAgICAvKiogTm9uLXBvd2VyMiBzdXBwb3J0ICoqLwoKICAgIC8qIEZpbmQgdGhlIG5lYXJlc3QgcG93MiBtYXRjaCAqLwogICAgcG93MkVkZ2VMZW5ndGggPSAxOwogICAgd2hpbGUgKHBvdzJFZGdlTGVuZ3RoIDwgRWRnZUxlbmd0aCkgcG93MkVkZ2VMZW5ndGggPDw9IDE7CgogICAgb2JqZWN0LT5lZGdlTGVuZ3RoICAgICAgICAgICA9IEVkZ2VMZW5ndGg7CiAgICAvKiBUT0RPOiBzdXBwb3J0IGZvciBuYXRpdmUgbm9uLXBvd2VyIDIgKi8KICAgIC8qIFByZWNhbGN1bGF0ZWQgc2NhbGluZyBmb3IgJ2Zha2VkJyBub24gcG93ZXIgb2YgdHdvIHRleHR1cmUgY29vcmRzICovCiAgICBvYmplY3QtPmJhc2VUZXh0dXJlLnBvdzJNYXRyaXhbIDBdID0gKChmbG9hdClFZGdlTGVuZ3RoKSAvICgoZmxvYXQpcG93MkVkZ2VMZW5ndGgpOwogICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5wb3cyTWF0cml4WyA1XSA9ICgoZmxvYXQpRWRnZUxlbmd0aCkgLyAoKGZsb2F0KXBvdzJFZGdlTGVuZ3RoKTsKICAgIG9iamVjdC0+YmFzZVRleHR1cmUucG93Mk1hdHJpeFsxMF0gPSAoKGZsb2F0KUVkZ2VMZW5ndGgpIC8gKChmbG9hdClwb3cyRWRnZUxlbmd0aCk7CiAgICBvYmplY3QtPmJhc2VUZXh0dXJlLnBvdzJNYXRyaXhbMTVdID0gMS4wOwoKICAgIC8qIENhbGN1bGF0ZSBsZXZlbHMgZm9yIG1pcCBtYXBwaW5nICovCiAgICBpZiAoVXNhZ2UgJiBXSU5FRDNEVVNBR0VfQVVUT0dFTk1JUE1BUCkgewogICAgICAgIGlmKCFHTF9TVVBQT1JUKFNHSVNfR0VORVJBVEVfTUlQTUFQKSkgewogICAgICAgICAgICBXQVJOKCJObyBtaXBtYXAgZ2VuZXJhdGlvbiBzdXBwb3J0LCByZXR1cm5pbmcgRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2JqZWN0KTsKICAgICAgICAgICAgKnBwQ3ViZVRleHR1cmUgPSBOVUxMOwoKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfQogICAgICAgIGlmKExldmVscyA+IDEpIHsKICAgICAgICAgICAgV0FSTigiRDNEVVNBR0VfQVVUT0dFTk1JUE1BUCBpcyBzZXQsIGFuZCBsZXZlbCBjb3VudCA+IDEsIHJldHVybmluZyBEM0RFUlJfSU5WQUxJRENBTExcbiIpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvYmplY3QpOwogICAgICAgICAgICAqcHBDdWJlVGV4dHVyZSA9IE5VTEw7CgogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICB9CiAgICAgICAgTGV2ZWxzID0gMTsKICAgIH0gZWxzZSBpZiAoTGV2ZWxzID09IDApIHsKICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVscysrOwogICAgICAgIHRtcFcgPSBFZGdlTGVuZ3RoOwogICAgICAgIHdoaWxlICh0bXBXID4gMSkgewogICAgICAgICAgICB0bXBXID0gbWF4KDEsIHRtcFcgPj4gMSk7CiAgICAgICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzKys7CiAgICAgICAgfQogICAgICAgIFRSQUNFKCJDYWxjdWxhdGVkIGxldmVscyA9ICVkXG4iLCBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVscyk7CiAgICB9CgogICAgLyogR2VuZXJhdGUgYWxsIHRoZSBzdXJmYWNlcyAqLwogICAgdG1wVyA9IEVkZ2VMZW5ndGg7CiAgICBmb3IgKGkgPSAwOyBpIDwgb2JqZWN0LT5iYXNlVGV4dHVyZS5sZXZlbHM7IGkrKykgewoKICAgICAgICAvKiBDcmVhdGUgdGhlIDYgZmFjZXMgKi8KICAgICAgICBmb3IgKGogPSAwOyBqIDwgNjsgaisrKSB7CgogICAgICAgICAgICBocj1EM0RDQl9DcmVhdGVTdXJmYWNlKFRoaXMtPnBhcmVudCwgcGFyZW50LCB0bXBXLCB0bXBXLCBGb3JtYXQsIFVzYWdlLCBQb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgLyogTGV2ZWwgKi8sIGosICZvYmplY3QtPnN1cmZhY2VzW2pdW2ldLHBTaGFyZWRIYW5kbGUpOwoKICAgICAgICAgICAgaWYoaHIhPSBXSU5FRDNEX09LKSB7CiAgICAgICAgICAgICAgICAvKiBjbGVhbiB1cCAqLwogICAgICAgICAgICAgICAgaW50IGs7CiAgICAgICAgICAgICAgICBpbnQgbDsKICAgICAgICAgICAgICAgIGZvciAobCA9IDA7IGwgPCBqOyBsKyspIHsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShvYmplY3QtPnN1cmZhY2VzW2xdW2ldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZvciAoayA9IDA7IGsgPCBpOyBrKyspIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKGwgPSAwOyBsIDwgNjsgbCsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKG9iamVjdC0+c3VyZmFjZXNbbF1ba10pOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBGSVhNRSgiKCVwKSBGYWlsZWQgdG8gY3JlYXRlIHN1cmZhY2VcbiIsb2JqZWN0KTsKICAgICAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksMCxvYmplY3QpOwogICAgICAgICAgICAgICAgKnBwQ3ViZVRleHR1cmUgPSBOVUxMOwogICAgICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgICAgICAgICB9CiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb250YWluZXIob2JqZWN0LT5zdXJmYWNlc1tqXVtpXSwgKElXaW5lRDNEQmFzZSAqKW9iamVjdCk7CiAgICAgICAgICAgIFRSQUNFKCJDcmVhdGVkIHN1cmZhY2UgbGV2ZWwgJWQgQCAlcCxcbiIsIGksIG9iamVjdC0+c3VyZmFjZXNbal1baV0pOwogICAgICAgIH0KICAgICAgICB0bXBXID0gbWF4KDEsIHRtcFcgPj4gMSk7CiAgICB9CiAgICBvYmplY3QtPmJhc2VUZXh0dXJlLnNoYWRlcl9jb252ZXJzaW9uX2dyb3VwID0gZ2xEZXNjLT5jb252ZXJzaW9uX2dyb3VwOwoKICAgIFRSQUNFKCIoJXApIDogQ3JlYXRlZCBDdWJlIFRleHR1cmUgJXBcbiIsIFRoaXMsIG9iamVjdCk7CiAgICAqcHBDdWJlVGV4dHVyZSA9IChJV2luZUQzREN1YmVUZXh0dXJlICopIG9iamVjdDsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVF1ZXJ5KElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRFFVRVJZVFlQRSBUeXBlLCBJV2luZUQzRFF1ZXJ5ICoqcHBRdWVyeSwgSVVua25vd24qIHBhcmVudCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RRdWVyeUltcGwgKm9iamVjdDsgLypOT1RFOiBpbXBsIHJlZiBhbGxvd2VkIHNpbmNlIHRoaXMgaXMgYSBjcmVhdGUgZnVuY3Rpb24gKi8KICAgIEhSRVNVTFQgaHIgPSBXSU5FRDNERVJSX05PVEFWQUlMQUJMRTsKCiAgICAvKiBKdXN0IGEgY2hlY2sgdG8gc2VlIGlmIHdlIHN1cHBvcnQgdGhpcyB0eXBlIG9mIHF1ZXJ5ICovCiAgICBzd2l0Y2goVHlwZSkgewogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX09DQ0xVU0lPTjoKICAgICAgICBUUkFDRSgiKCVwKSBvY2NsdXNpb24gcXVlcnlcbiIsIFRoaXMpOwogICAgICAgIGlmIChHTF9TVVBQT1JUKEFSQl9PQ0NMVVNJT05fUVVFUlkpKQogICAgICAgICAgICBociA9IFdJTkVEM0RfT0s7CiAgICAgICAgZWxzZQogICAgICAgICAgICBXQVJOKCJVbnN1cHBvcnRlZCBpbiBsb2NhbCBPcGVuR0wgaW1wbGVtZW50YXRpb246IEFSQl9PQ0NMVVNJT05fUVVFUlkvTlZfT0NDTFVTSU9OX1FVRVJZXG4iKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfRVZFTlQ6CiAgICAgICAgaWYoIShHTF9TVVBQT1JUKE5WX0ZFTkNFKSB8fCBHTF9TVVBQT1JUKEFQUExFX0ZFTkNFKSApKSB7CiAgICAgICAgICAgIC8qIEhhbGYtTGlmZSAyIG5lZWRzIHRoaXMgcXVlcnkuIEl0IGRvZXMgbm90IHJlbmRlciB0aGUgbWFpbiBtZW51IGNvcnJlY3RseSBvdGhlcndpc2UKICAgICAgICAgICAgICogUHJldGVuZCB0byBzdXBwb3J0IGl0LCBmYWtpbmcgdGhpcyBxdWVyeSBkb2VzIG5vdCBkbyBtdWNoIGhhcm0gZXhjZXB0IHBvdGVudGlhbGx5IGxvd2VyaW5nIHBlcmZvcm1hbmNlCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBGSVhNRSgiKCVwKSBFdmVudCBxdWVyeTogVW5pbXBsZW1lbnRlZCwgYnV0IHByZXRlbmRpbmcgdG8gYmUgc3VwcG9ydGVkXG4iLCBUaGlzKTsKICAgICAgICB9CiAgICAgICAgaHIgPSBXSU5FRDNEX09LOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9WQ0FDSEU6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfUkVTT1VSQ0VNQU5BR0VSOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1ZFUlRFWFNUQVRTOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1RJTUVTVEFNUDoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9USU1FU1RBTVBESVNKT0lOVDoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9USU1FU1RBTVBGUkVROgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1BJUEVMSU5FVElNSU5HUzoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9JTlRFUkZBQ0VUSU1JTkdTOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1ZFUlRFWFRJTUlOR1M6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfUElYRUxUSU1JTkdTOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX0JBTkRXSURUSFRJTUlOR1M6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfQ0FDSEVVVElMSVpBVElPTjoKICAgIGRlZmF1bHQ6CiAgICAgICAgRklYTUUoIiglcCkgVW5oYW5kbGVkIHF1ZXJ5IHR5cGUgJWRcbiIsIFRoaXMsIFR5cGUpOwogICAgfQogICAgaWYoTlVMTCA9PSBwcFF1ZXJ5IHx8IGhyICE9IFdJTkVEM0RfT0spIHsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgRDNEQ1JFQVRFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBRdWVyeSkKICAgIG9iamVjdC0+dHlwZSAgICAgICAgID0gVHlwZTsKICAgIG9iamVjdC0+c3RhdGUgICAgICAgID0gUVVFUllfQ1JFQVRFRDsKICAgIC8qIGFsbG9jYXRlZCB0aGUgJ2V4dGVuZGVkJyBkYXRhIGJhc2VkIG9uIHRoZSB0eXBlIG9mIHF1ZXJ5IHJlcXVlc3RlZCAqLwogICAgc3dpdGNoKFR5cGUpewogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX09DQ0xVU0lPTjoKICAgICAgICBvYmplY3QtPmV4dGVuZGVkRGF0YSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoV2luZVF1ZXJ5T2NjbHVzaW9uRGF0YSkpOwogICAgICAgICgoV2luZVF1ZXJ5T2NjbHVzaW9uRGF0YSAqKShvYmplY3QtPmV4dGVuZGVkRGF0YSkpLT5jdHggPSBUaGlzLT5hY3RpdmVDb250ZXh0OwoKICAgICAgICBpZihHTF9TVVBQT1JUKEFSQl9PQ0NMVVNJT05fUVVFUlkpKSB7CiAgICAgICAgICAgIFRSQUNFKCIoJXApIEFsbG9jYXRpbmcgZGF0YSBmb3IgYW4gb2NjbHVzaW9uIHF1ZXJ5XG4iLCBUaGlzKTsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEdlblF1ZXJpZXNBUkIoMSwgJigoV2luZVF1ZXJ5T2NjbHVzaW9uRGF0YSAqKShvYmplY3QtPmV4dGVuZGVkRGF0YSkpLT5xdWVyeUlkKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9FVkVOVDoKICAgICAgICBvYmplY3QtPmV4dGVuZGVkRGF0YSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoV2luZVF1ZXJ5RXZlbnREYXRhKSk7CiAgICAgICAgKChXaW5lUXVlcnlFdmVudERhdGEgKikob2JqZWN0LT5leHRlbmRlZERhdGEpKS0+Y3R4ID0gVGhpcy0+YWN0aXZlQ29udGV4dDsKCiAgICAgICAgaWYoR0xfU1VQUE9SVChBUFBMRV9GRU5DRSkpIHsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbEdlbkZlbmNlc0FQUExFKDEsICYoKFdpbmVRdWVyeUV2ZW50RGF0YSAqKShvYmplY3QtPmV4dGVuZGVkRGF0YSkpLT5mZW5jZUlkKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEdlbkZlbmNlc0FQUExFIik7CiAgICAgICAgfSBlbHNlIGlmKEdMX1NVUFBPUlQoTlZfRkVOQ0UpKSB7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xHZW5GZW5jZXNOVigxLCAmKChXaW5lUXVlcnlFdmVudERhdGEgKikob2JqZWN0LT5leHRlbmRlZERhdGEpKS0+ZmVuY2VJZCkpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZW5GZW5jZXNOViIpOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfVkNBQ0hFOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1JFU09VUkNFTUFOQUdFUjoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9WRVJURVhTVEFUUzoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9USU1FU1RBTVA6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfVElNRVNUQU1QRElTSk9JTlQ6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfVElNRVNUQU1QRlJFUToKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9QSVBFTElORVRJTUlOR1M6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfSU5URVJGQUNFVElNSU5HUzoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9WRVJURVhUSU1JTkdTOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1BJWEVMVElNSU5HUzoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9CQU5EV0lEVEhUSU1JTkdTOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX0NBQ0hFVVRJTElaQVRJT046CiAgICBkZWZhdWx0OgogICAgICAgIG9iamVjdC0+ZXh0ZW5kZWREYXRhID0gMDsKICAgICAgICBGSVhNRSgiKCVwKSBVbmhhbmRsZWQgcXVlcnkgdHlwZSAlZFxuIixUaGlzICwgVHlwZSk7CiAgICB9CiAgICBUUkFDRSgiKCVwKSA6IENyZWF0ZWQgUXVlcnkgJXBcbiIsIFRoaXMsIG9iamVjdCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElXaW5lRDNERGV2aWNlSW1wbF9TZXR1cEZ1bGxzY3JlZW5XaW5kb3cKICoKICogSGVscGVyIGZ1bmN0aW9uIHRoYXQgbW9kaWZpZXMgYSBIV05EJ3MgU3R5bGUgYW5kIEV4U3R5bGUgZm9yIHByb3BlcgogKiBmdWxsc2NyZWVuIHVzZS4KICoKICogUGFyYW1zOgogKiAgaWZhY2U6IFBvaW50ZXIgdG8gdGhlIElXaW5lRDNERGV2aWNlIGludGVyZmFjZQogKiAgd2luZG93OiBXaW5kb3cgdG8gc2V0dXAKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldHVwRnVsbHNjcmVlbldpbmRvdyhJV2luZUQzRERldmljZSAqaWZhY2UsIEhXTkQgd2luZG93KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgTE9ORyBzdHlsZSwgZXhTdHlsZTsKICAgIC8qIERvbid0IGRvIGFueXRoaW5nIGlmIGFuIG9yaWdpbmFsIHN0eWxlIGlzIHN0b3JlZC4KICAgICAqIFRoYXQgc2hvdWxkbid0IGhhcHBlbgogICAgICovCiAgICBUUkFDRSgiKCVwKTogU2V0dGluZyB1cCB3aW5kb3cgJXAgZm9yIGV4Y2x1c2l2ZSBtb2RlXG4iLCBUaGlzLCB3aW5kb3cpOwogICAgaWYgKFRoaXMtPnN0eWxlIHx8IFRoaXMtPmV4U3R5bGUpIHsKICAgICAgICBFUlIoIiglcCk6IFdhbnQgdG8gY2hhbmdlIHRoZSB3aW5kb3cgcGFyYW1ldGVycyBvZiBIV05EICVwLCBidXQgIgogICAgICAgICAgICAiYW5vdGhlciBzdHlsZSBpcyBzdG9yZWQgZm9yIHJlc3RvcmF0aW9uIGFmdGVyd2FyZHNcbiIsIFRoaXMsIHdpbmRvdyk7CiAgICB9CgogICAgLyogR2V0IHRoZSBwYXJhbWV0ZXJzIGFuZCBzYXZlIHRoZW0gKi8KICAgIHN0eWxlID0gR2V0V2luZG93TG9uZ1cod2luZG93LCBHV0xfU1RZTEUpOwogICAgZXhTdHlsZSA9IEdldFdpbmRvd0xvbmdXKHdpbmRvdywgR1dMX0VYU1RZTEUpOwogICAgVGhpcy0+c3R5bGUgPSBzdHlsZTsKICAgIFRoaXMtPmV4U3R5bGUgPSBleFN0eWxlOwoKICAgIC8qIEZpbHRlciBvdXQgd2luZG93IGRlY29yYXRpb25zICovCiAgICBzdHlsZSAmPSB+V1NfQ0FQVElPTjsKICAgIHN0eWxlICY9IH5XU19USElDS0ZSQU1FOwogICAgZXhTdHlsZSAmPSB+V1NfRVhfV0lORE9XRURHRTsKICAgIGV4U3R5bGUgJj0gfldTX0VYX0NMSUVOVEVER0U7CgogICAgLyogTWFrZSBzdXJlIHRoZSB3aW5kb3cgaXMgbWFuYWdlZCwgb3RoZXJ3aXNlIHdlIHdvbid0IGdldCBrZXlib2FyZCBpbnB1dCAqLwogICAgc3R5bGUgfD0gV1NfUE9QVVAgfCBXU19TWVNNRU5VOwoKICAgIFRSQUNFKCJPbGQgc3R5bGUgd2FzICUwOHgsJTA4eCwgc2V0dGluZyB0byAlMDh4LCUwOHhcbiIsCiAgICAgICAgICBUaGlzLT5zdHlsZSwgVGhpcy0+ZXhTdHlsZSwgc3R5bGUsIGV4U3R5bGUpOwoKICAgIFNldFdpbmRvd0xvbmdXKHdpbmRvdywgR1dMX1NUWUxFLCBzdHlsZSk7CiAgICBTZXRXaW5kb3dMb25nVyh3aW5kb3csIEdXTF9FWFNUWUxFLCBleFN0eWxlKTsKCiAgICAvKiBJbmZvcm0gdGhlIHdpbmRvdyBhYm91dCB0aGUgdXBkYXRlLiAqLwogICAgU2V0V2luZG93UG9zKHdpbmRvdywgSFdORF9UT1AsIDAsIDAsCiAgICAgICAgICAgIFRoaXMtPmRkcmF3X3dpZHRoLCBUaGlzLT5kZHJhd19oZWlnaHQsIFNXUF9GUkFNRUNIQU5HRUQpOwogICAgU2hvd1dpbmRvdyh3aW5kb3csIFNXX05PUk1BTCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRERldmljZUltcGxfUmVzdG9yZVdpbmRvdwogKgogKiBIZWxwZXIgZnVuY3Rpb24gdGhhdCByZXN0b3JlcyBhIHdpbmRvd3MnIHByb3BlcnRpZXMgd2hlbiB0YWtpbmcgaXQgb3V0CiAqIG9mIGZ1bGxzY3JlZW4gbW9kZQogKgogKiBQYXJhbXM6CiAqICBpZmFjZTogUG9pbnRlciB0byB0aGUgSVdpbmVEM0REZXZpY2UgaW50ZXJmYWNlCiAqICB3aW5kb3c6IFdpbmRvdyB0byBzZXR1cAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyB2b2lkIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfUmVzdG9yZVdpbmRvdyhJV2luZUQzRERldmljZSAqaWZhY2UsIEhXTkQgd2luZG93KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgLyogVGhpcyBjb3VsZCBiZSBhIEREU0NMX05PUk1BTCAtPiBERFNDTF9OT1JNQUwKICAgICAqIHN3aXRjaCwgZG8gbm90aGluZwogICAgICovCiAgICBpZiAoIVRoaXMtPnN0eWxlICYmICFUaGlzLT5leFN0eWxlKSByZXR1cm47CgogICAgVFJBQ0UoIiglcCk6IFJlc3RvcmluZyB3aW5kb3cgc2V0dGluZ3Mgb2Ygd2luZG93ICVwIHRvICUwOHgsICUwOHhcbiIsCiAgICAgICAgICBUaGlzLCB3aW5kb3csIFRoaXMtPnN0eWxlLCBUaGlzLT5leFN0eWxlKTsKCiAgICBTZXRXaW5kb3dMb25nVyh3aW5kb3csIEdXTF9TVFlMRSwgVGhpcy0+c3R5bGUpOwogICAgU2V0V2luZG93TG9uZ1cod2luZG93LCBHV0xfRVhTVFlMRSwgVGhpcy0+ZXhTdHlsZSk7CgogICAgLyogRGVsZXRlIHRoZSBvbGQgdmFsdWVzICovCiAgICBUaGlzLT5zdHlsZSA9IDA7CiAgICBUaGlzLT5leFN0eWxlID0gMDsKCiAgICAvKiBJbmZvcm0gdGhlIHdpbmRvdyBhYm91dCB0aGUgdXBkYXRlICovCiAgICBTZXRXaW5kb3dQb3Mod2luZG93LCAwIC8qIEluc2VydEFmdGVyLCBpZ25vcmVkICovLAogICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsIC8qIFBvcywgU2l6ZSwgaWdub3JlZCAqLwogICAgICAgICAgICAgICAgIFNXUF9GUkFNRUNIQU5HRUQgfCBTV1BfTk9NT1ZFIHwgU1dQX05PU0laRSB8IFNXUF9OT1pPUkRFUik7Cn0KCi8qIGV4YW1wbGUgYXQgaHR0cDovL3d3dy5mYWlyeWVuZ2luZS5jb20vYXJ0aWNsZXMvZHhtdWx0aXZpZXdzLmh0bSAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZUFkZGl0aW9uYWxTd2FwQ2hhaW4oSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBXSU5FRDNEUFJFU0VOVF9QQVJBTUVURVJTKiAgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3dhcENoYWluKiogcHBTd2FwQ2hhaW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElVbmtub3duKiBwYXJlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRENCX0NSRUFURVJFTkRFUlRBUkdFVEZOIEQzRENCX0NyZWF0ZVJlbmRlclRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEQ0JfQ1JFQVRFREVQVEhTVEVOQ0lMU1VSRkFDRUZOIEQzRENCX0NyZWF0ZURlcHRoU3RlbmNpbCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICAgICAgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgSERDICAgICAgICAgICAgICAgICAgICAgaERjOwogICAgSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICAqb2JqZWN0OyAvKiogTk9URTogaW1wbCByZWYgYWxsb3dlZCBzaW5jZSB0aGlzIGlzIGEgY3JlYXRlIGZ1bmN0aW9uICoqLwogICAgSFJFU1VMVCAgICAgICAgICAgICAgICAgaHIgPSBXSU5FRDNEX09LOwogICAgSVVua25vd24gICAgICAgICAgICAgICAqYnVmZmVyUGFyZW50OwogICAgQk9PTCAgICAgICAgICAgICAgICAgICAgZGlzcGxheW1vZGVfc2V0ID0gRkFMU0U7CiAgICBXSU5FRDNERElTUExBWU1PREUgICAgICBNb2RlOwogICAgY29uc3QgU3RhdGljUGl4ZWxGb3JtYXREZXNjICpmb3JtYXREZXNjOwoKICAgIFRSQUNFKCIoJXApIDogQ3JlYXRlZCBBZGl0aW9uYWwgU3dhcCBDaGFpblxuIiwgVGhpcyk7CgogICAvKiogRklYTUU6IFRlc3QgdW5kZXIgd2luZG93cyB0byBmaW5kIG91dCB3aGF0IHRoZSBsaWZlIGN5Y2xlIG9mIGEgc3dhcCBjaGFpbiBpcywKICAgKiBkb2VzIGEgZGV2aWNlIGhvbGQgYSByZWZlcmVuY2UgdG8gYSBzd2FwIGNoYWluIGdpdmluZyB0aGVtIGEgbGlmZXRpbWUgb2YgdGhlIGRldmljZQogICAqIG9yIGRvZXMgdGhlIHN3YXAgY2hhaW4gbm90aWZ5IHRoZSBkZXZpY2Ugb2YgaXRzIGRlc3RydWN0aW9uLgogICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKiBDaGVjayB0aGUgcGFyYW1zICovCiAgICBpZihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckNvdW50ID4gV0lORUQzRFBSRVNFTlRfQkFDS19CVUZGRVJfTUFYKSB7CiAgICAgICAgRVJSKCJBcHAgcmVxdWVzdGVkICVkIGJhY2sgYnVmZmVycywgdGhpcyBpcyBub3Qgc3VwcG9ydGVkIGZvciBub3dcbiIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyQ291bnQpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfSBlbHNlIGlmIChwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckNvdW50ID4gMSkgewogICAgICAgIEZJWE1FKCJUaGUgYXBwIHJlcXVlc3RzIG1vcmUgdGhhbiBvbmUgYmFjayBidWZmZXIsIHRoaXMgY2FuJ3QgYmUgc3VwcG9ydGVkIHByb3Blcmx5LiBQbGVhc2UgY29uZmlndXJlIHRoZSBhcHBsaWNhdGlvbiB0byB1c2UgZG91YmxlIGJ1ZmZlcmluZyg9MSBiYWNrIGJ1ZmZlcikgaWYgcG9zc2libGVcbiIpOwogICAgfQoKICAgIEQzRENSRUFURU9CSkVDVElOU1RBTkNFKG9iamVjdCwgU3dhcENoYWluKQoKICAgIC8qKioqKioqKioqKioqKioqKioqKioKICAgICogTG9va3VwIHRoZSB3aW5kb3cgSGFuZGxlIGFuZCB0aGUgcmVsYXRpbmcgWCB3aW5kb3cgaGFuZGxlCiAgICAqKioqKioqKioqKioqKioqKioqKi8KCiAgICAvKiBTZXR1cCBod25kIHdlIGFyZSB1c2luZywgcGx1cyB3aGljaCBkaXNwbGF5IHRoaXMgZXF1YXRlcyB0byAqLwogICAgb2JqZWN0LT53aW5faGFuZGxlID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPmhEZXZpY2VXaW5kb3c7CiAgICBpZiAoIW9iamVjdC0+d2luX2hhbmRsZSkgewogICAgICAgIG9iamVjdC0+d2luX2hhbmRsZSA9IFRoaXMtPmNyZWF0ZVBhcm1zLmhGb2N1c1dpbmRvdzsKICAgIH0KICAgIGlmKCFUaGlzLT5kZHJhd193aW5kb3cpIElXaW5lRDNERGV2aWNlX1NldEhXTkQoaWZhY2UsIG9iamVjdC0+d2luX2hhbmRsZSk7CgogICAgaERjICAgICAgICAgICAgICAgID0gR2V0REMob2JqZWN0LT53aW5faGFuZGxlKTsKICAgIFRSQUNFKCJVc2luZyBoRGMgJXBcbiIsIGhEYyk7CgogICAgaWYgKE5VTEwgPT0gaERjKSB7CiAgICAgICAgV0FSTigiRmFpbGVkIHRvIGdldCBhIEhEYyBmb3IgV2luZG93ICVwXG4iLCBvYmplY3QtPndpbl9oYW5kbGUpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX05PVEFWQUlMQUJMRTsKICAgIH0KCiAgICAvKiBHZXQgaW5mbyBvbiB0aGUgY3VycmVudCBkaXNwbGF5IHNldHVwICovCiAgICBJV2luZUQzRF9HZXRBZGFwdGVyRGlzcGxheU1vZGUoVGhpcy0+d2luZUQzRCwgVGhpcy0+YWRhcHRlci0+bnVtLCAmTW9kZSk7CiAgICBvYmplY3QtPm9yaWdfd2lkdGggPSBNb2RlLldpZHRoOwogICAgb2JqZWN0LT5vcmlnX2hlaWdodCA9IE1vZGUuSGVpZ2h0OwogICAgb2JqZWN0LT5vcmlnX2ZtdCA9IE1vZGUuRm9ybWF0OwogICAgZm9ybWF0RGVzYyAgPSBnZXRGb3JtYXREZXNjRW50cnkoTW9kZS5Gb3JtYXQsIE5VTEwsIE5VTEwpOwoKICAgIC8qKiBNU0ROOiBJZiBXaW5kb3dlZCBpcyBUUlVFIGFuZCBlaXRoZXIgb2YgdGhlIEJhY2tCdWZmZXJXaWR0aC9IZWlnaHQgdmFsdWVzIGlzIHplcm8sCiAgICAgKiAgdGhlbiB0aGUgY29ycmVzcG9uZGluZyBkaW1lbnNpb24gb2YgdGhlIGNsaWVudCBhcmVhIG9mIHRoZSBoRGV2aWNlV2luZG93CiAgICAgKiAgKG9yIHRoZSBmb2N1cyB3aW5kb3csIGlmIGhEZXZpY2VXaW5kb3cgaXMgTlVMTCkgaXMgdGFrZW4uCiAgICAgICoqKioqKioqKioqKioqKioqKioqKiovCgogICAgaWYgKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5XaW5kb3dlZCAmJgogICAgICAgICgocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aCA9PSAwKSB8fAogICAgICAgICAocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQgPT0gMCkgfHwKICAgICAgICAgKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyRm9ybWF0ID09IFdJTkVEM0RGTVRfVU5LTk9XTikpKSB7CgogICAgICAgIFJFQ1QgUmVjdDsKICAgICAgICBHZXRDbGllbnRSZWN0KG9iamVjdC0+d2luX2hhbmRsZSwgJlJlY3QpOwoKICAgICAgICBpZiAocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aCA9PSAwKSB7CiAgICAgICAgICAgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aCA9IFJlY3QucmlnaHQ7CiAgICAgICAgICAgVFJBQ0UoIlVwZGF0aW5nIHdpZHRoIHRvICVkXG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoKTsKICAgICAgICB9CiAgICAgICAgaWYgKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0ID09IDApIHsKICAgICAgICAgICBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodCA9IFJlY3QuYm90dG9tOwogICAgICAgICAgIFRSQUNFKCJVcGRhdGluZyBoZWlnaHQgdG8gJWRcbiIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0KTsKICAgICAgICB9CiAgICAgICAgaWYgKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyRm9ybWF0ID09IFdJTkVEM0RGTVRfVU5LTk9XTikgewogICAgICAgICAgIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyRm9ybWF0ID0gb2JqZWN0LT5vcmlnX2ZtdDsKICAgICAgICAgICBUUkFDRSgiVXBkYXRpbmcgZm9ybWF0IHRvICVzXG4iLCBkZWJ1Z19kM2Rmb3JtYXQob2JqZWN0LT5vcmlnX2ZtdCkpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBQdXQgdGhlIGNvcnJlY3QgZmlndXJlcyBpbiB0aGUgcHJlc2VudGF0aW9uIHBhcmFtZXRlcnMgKi8KICAgIFRSQUNFKCJDb3B5aW5nIGFjcm9zcyBwcmVzZW50YXRpb24gcGFyYW1ldGVyc1xuIik7CiAgICBvYmplY3QtPnByZXNlbnRQYXJtcyA9ICpwUHJlc2VudGF0aW9uUGFyYW1ldGVyczsKCiAgICBUUkFDRSgiY2FsbGluZyByZW5kZXJ0YXJnZXQgQ0JcbiIpOwogICAgaHIgPSBEM0RDQl9DcmVhdGVSZW5kZXJUYXJnZXQoKElVbmtub3duICopIFRoaXMtPnBhcmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlcldpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJIZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckZvcm1hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5NdWx0aVNhbXBsZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuTXVsdGlTYW1wbGVRdWFsaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUgLyogTG9ja2FibGUgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm9iamVjdC0+ZnJvbnRCdWZmZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCAvKiBwU2hhcmVkIChhbHdheXMgbnVsbCkqLyk7CiAgICBpZiAob2JqZWN0LT5mcm9udEJ1ZmZlciAhPSBOVUxMKSB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX01vZGlmeUxvY2F0aW9uKG9iamVjdC0+ZnJvbnRCdWZmZXIsIFNGTEFHX0lORFJBV0FCTEUsIFRSVUUpOwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb250YWluZXIob2JqZWN0LT5mcm9udEJ1ZmZlciwgKElXaW5lRDNEQmFzZSAqKW9iamVjdCk7CiAgICB9IGVsc2UgewogICAgICAgIEVSUigiRmFpbGVkIHRvIGNyZWF0ZSB0aGUgZnJvbnQgYnVmZmVyXG4iKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgLyoqKioqKioqKioqKioqKioqKioqKgogICAqIFdpbmRvd2VkIC8gRnVsbHNjcmVlbgogICAqKioqKioqKioqKioqKioqKioqLwoKICAgLyoqCiAgICogVE9ETzogTVNETiBzYXlzIHRoYXQgd2UgYXJlIG9ubHkgYWxsb3dlZCBvbmUgZnVsbHNjcmVlbiBzd2FwY2hhaW4gcGVyIGRldmljZSwKICAgKiBzbyB3ZSBzaG91bGQgcmVhbGx5IGNoZWNrIHRvIHNlZSBpZiB0aGVyZSBpcyBhIGZ1bGxzY3JlZW4gc3dhcGNoYWluIGFscmVhZHkKICAgKiBJIHRoaW5rIFdpbmRvd3MgYW5kIFggaGF2ZSBkaWZmZXJlbnQgaWRlYXMgYWJvdXQgZnVsbHNjcmVlbiwgZG9lcyBhIHNpbmdsZSBoZWFkIGNvdW50IGFzIGZ1bGwgc2NyZWVuPwogICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICBpZiAoIXBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5XaW5kb3dlZCkgewogICAgICAgIFdJTkVEM0RESVNQTEFZTU9ERSBtb2RlOwoKCiAgICAgICAgLyogQ2hhbmdlIHRoZSBkaXNwbGF5IHNldHRpbmdzICovCiAgICAgICAgbW9kZS5XaWR0aCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGg7CiAgICAgICAgbW9kZS5IZWlnaHQgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodDsKICAgICAgICBtb2RlLkZvcm1hdCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyRm9ybWF0OwogICAgICAgIG1vZGUuUmVmcmVzaFJhdGUgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+RnVsbFNjcmVlbl9SZWZyZXNoUmF0ZUluSHo7CgogICAgICAgIElXaW5lRDNERGV2aWNlX1NldERpc3BsYXlNb2RlKGlmYWNlLCAwLCAmbW9kZSk7CiAgICAgICAgZGlzcGxheW1vZGVfc2V0ID0gVFJVRTsKICAgICAgICBJV2luZUQzRERldmljZV9TZXRGdWxsc2NyZWVuKGlmYWNlLCBUUlVFKTsKICAgIH0KCiAgICAgICAgLyoqCiAgICAgKiBDcmVhdGUgYW4gb3BlbmdsIGNvbnRleHQgZm9yIHRoZSBkaXNwbGF5IHZpc3VhbAogICAgICogIE5PVEU6IHRoZSB2aXN1YWwgaXMgY2hvc2VuIGFzIHRoZSB3aW5kb3cgaXMgY3JlYXRlZCBhbmQgdGhlIGdsY29udGV4dCBjYW5ub3QKICAgICAqICAgICB1c2UgZGlmZmVyZW50IHByb3BlcnRpZXMgYWZ0ZXIgdGhhdCBwb2ludCBpbiB0aW1lLiBGSVhNRTogSG93IHRvIGhhbmRsZSB3aGVuIHJlcXVlc3RlZCBmb3JtYXQKICAgICAqICAgICBkb2Vzbid0IG1hdGNoIGFjdHVhbCB2aXN1YWw/IENhbm5vdCBjaG9vc2Ugb25lIGhlcmUgLSBjb2RlIHJlbW92ZWQgYXMgaXQgT05MWSB3b3JrcyBpZiB0aGUgb25lCiAgICAgKiAgICAgaXQgY2hvb3NlcyBpcyBpZGVudGljYWwgdG8gdGhlIG9uZSBhbHJlYWR5IGJlaW5nIHVzZWQhCiAgICAgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAgICAvKiogRklYTUU6IEhhbmRsZSBzdGVuY2lsIGFwcHJvcHJpYXRlbHkgdmlhIEVuYWJsZUF1dG9EZXB0aFN0ZW5jaWwgLyBBdXRvRGVwdGhTdGVuY2lsRm9ybWF0ICoqLwoKICAgIG9iamVjdC0+Y29udGV4dCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2Yob2JqZWN0LT5jb250ZXh0KSk7CiAgICBpZighb2JqZWN0LT5jb250ZXh0KQogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwogICAgb2JqZWN0LT5udW1fY29udGV4dHMgPSAxOwoKICAgIG9iamVjdC0+Y29udGV4dFswXSA9IENyZWF0ZUNvbnRleHQoVGhpcywgKElXaW5lRDNEU3VyZmFjZUltcGwgKikgb2JqZWN0LT5mcm9udEJ1ZmZlciwgb2JqZWN0LT53aW5faGFuZGxlLCBGQUxTRSAvKiBwYnVmZmVyICovLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycyk7CiAgICBpZiAoIW9iamVjdC0+Y29udGV4dFswXSkgewogICAgICAgIEVSUigiRmFpbGVkIHRvIGNyZWF0ZSBhIG5ldyBjb250ZXh0XG4iKTsKICAgICAgICBociA9IFdJTkVEM0RFUlJfTk9UQVZBSUxBQkxFOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9IGVsc2UgewogICAgICAgIFRSQUNFKCJDb250ZXh0IGNyZWF0ZWQgKEhXTkQ9JXAsIGdsQ29udGV4dD0lcClcbiIsCiAgICAgICAgICAgICAgb2JqZWN0LT53aW5faGFuZGxlLCBvYmplY3QtPmNvbnRleHRbMF0tPmdsQ3R4KTsKICAgIH0KCiAgIC8qKioqKioqKioqKioqKioqKioqKioKICAgKiBDcmVhdGUgdGhlIGJhY2ssIGZyb250IGFuZCBzdGVuY2lsIGJ1ZmZlcnMKICAgKioqKioqKioqKioqKioqKioqKi8KICAgIGlmKG9iamVjdC0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJDb3VudCA+IDApIHsKICAgICAgICBpbnQgaTsKCiAgICAgICAgb2JqZWN0LT5iYWNrQnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihJV2luZUQzRFN1cmZhY2UgKikgKiBvYmplY3QtPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyQ291bnQpOwogICAgICAgIGlmKCFvYmplY3QtPmJhY2tCdWZmZXIpIHsKICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5XG4iKTsKICAgICAgICAgICAgaHIgPSBFX09VVE9GTUVNT1JZOwogICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgIH0KCiAgICAgICAgZm9yKGkgPSAwOyBpIDwgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckNvdW50OyBpKyspIHsKICAgICAgICAgICAgVFJBQ0UoImNhbGxpbmcgcmVuZGVydGFyZ2V0IENCXG4iKTsKICAgICAgICAgICAgaHIgPSBEM0RDQl9DcmVhdGVSZW5kZXJUYXJnZXQoKElVbmtub3duICopIFRoaXMtPnBhcmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJIZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLk11bHRpU2FtcGxlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuTXVsdGlTYW1wbGVRdWFsaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFIC8qIExvY2thYmxlICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmb2JqZWN0LT5iYWNrQnVmZmVyW2ldLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMIC8qIHBTaGFyZWQgKGFsd2F5cyBudWxsKSovKTsKICAgICAgICAgICAgaWYoaHIgPT0gV0lORUQzRF9PSyAmJiBvYmplY3QtPmJhY2tCdWZmZXJbaV0pIHsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb250YWluZXIob2JqZWN0LT5iYWNrQnVmZmVyW2ldLCAoSVdpbmVEM0RCYXNlICopb2JqZWN0KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIEVSUigiQ2Fubm90IGNyZWF0ZSBuZXcgYmFjayBidWZmZXJcbiIpOwogICAgICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICAgICAgfQogICAgICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgICAgICBnbERyYXdCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoR0xfQkFDSykiKTsKICAgICAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIG9iamVjdC0+YmFja0J1ZmZlciA9IE5VTEw7CgogICAgICAgIC8qIFNpbmdsZSBidWZmZXJpbmcgLSBkcmF3IHRvIGZyb250IGJ1ZmZlciAqLwogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgZ2xEcmF3QnVmZmVyKEdMX0ZST05UKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKEdMX0ZST05UKSIpOwogICAgICAgIExFQVZFX0dMKCk7CiAgICB9CgogICAgLyogVW5kZXIgZGlyZWN0WCBzd2FwY2hhaW5zIHNoYXJlIHRoZSBkZXB0aCBzdGVuY2lsLCBzbyBvbmx5IGNyZWF0ZSBvbmUgZGVwdGgtc3RlbmNpbCAqLwogICAgaWYgKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5FbmFibGVBdXRvRGVwdGhTdGVuY2lsICYmIGhyID09IFdJTkVEM0RfT0spIHsKICAgICAgICBUUkFDRSgiQ3JlYXRpbmcgZGVwdGggc3RlbmNpbCBidWZmZXJcbiIpOwogICAgICAgIGlmIChUaGlzLT5hdXRvX2RlcHRoX3N0ZW5jaWxfYnVmZmVyID09IE5VTEwgKSB7CiAgICAgICAgICAgIGhyID0gRDNEQ0JfQ3JlYXRlRGVwdGhTdGVuY2lsKChJVW5rbm93biAqKSBUaGlzLT5wYXJlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlcldpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVySGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5BdXRvRGVwdGhTdGVuY2lsRm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5NdWx0aVNhbXBsZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLk11bHRpU2FtcGxlUXVhbGl0eSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRkFMU0UgLyogRklYTUU6IERpc2NhcmQgKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZUaGlzLT5hdXRvX2RlcHRoX3N0ZW5jaWxfYnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMIC8qIHBTaGFyZWQgKGFsd2F5cyBudWxsKSovICApOwogICAgICAgICAgICBpZiAoVGhpcy0+YXV0b19kZXB0aF9zdGVuY2lsX2J1ZmZlciAhPSBOVUxMKQogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbnRhaW5lcihUaGlzLT5hdXRvX2RlcHRoX3N0ZW5jaWxfYnVmZmVyLCAwKTsKICAgICAgICB9CgogICAgICAgIC8qKiBUT0RPOiBBIGNoZWNrIG9uIHdpZHRoLCBoZWlnaHQgYW5kIG11bHRpc2FtcGxlIHR5cGVzCiAgICAgICAgKihzaW5jZSB0aGUgemJ1ZmZlciBtdXN0IGJlIGF0IGxlYXN0IGFzIGxhcmdlIGFzIHRoZSByZW5kZXIgdGFyZ2V0IGFuZCBoYXZlIHRoZSBzYW1lIG11bHRpc2FtcGxlIHBhcmFtZXRlcnMpCiAgICAgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAgICAgICAgb2JqZWN0LT53YW50c0RlcHRoU3RlbmNpbEJ1ZmZlciA9IFRSVUU7CiAgICB9IGVsc2UgewogICAgICAgIG9iamVjdC0+d2FudHNEZXB0aFN0ZW5jaWxCdWZmZXIgPSBGQUxTRTsKICAgIH0KCiAgICBUUkFDRSgiQ3JlYXRlZCBzd2FwY2hhaW4gJXBcbiIsIG9iamVjdCk7CiAgICBUUkFDRSgiRnJvbnRCdWYgQCAlcCwgQmFja0J1ZiBAICVwLCBEZXB0aFN0ZW5jaWwgJWRcbiIsb2JqZWN0LT5mcm9udEJ1ZmZlciwgb2JqZWN0LT5iYWNrQnVmZmVyID8gb2JqZWN0LT5iYWNrQnVmZmVyWzBdIDogTlVMTCwgb2JqZWN0LT53YW50c0RlcHRoU3RlbmNpbEJ1ZmZlcik7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKCmVycm9yOgogICAgaWYgKGRpc3BsYXltb2RlX3NldCkgewogICAgICAgIERFVk1PREVXIGRldm1vZGU7CiAgICAgICAgUkVDVCAgICAgY2xpcF9yYzsKCiAgICAgICAgU2V0UmVjdCgmY2xpcF9yYywgMCwgMCwgb2JqZWN0LT5vcmlnX3dpZHRoLCBvYmplY3QtPm9yaWdfaGVpZ2h0KTsKICAgICAgICBDbGlwQ3Vyc29yKE5VTEwpOwoKICAgICAgICAvKiBDaGFuZ2UgdGhlIGRpc3BsYXkgc2V0dGluZ3MgKi8KICAgICAgICBtZW1zZXQoJmRldm1vZGUsIDAsIHNpemVvZihkZXZtb2RlKSk7CiAgICAgICAgZGV2bW9kZS5kbVNpemUgICAgICAgPSBzaXplb2YoZGV2bW9kZSk7CiAgICAgICAgZGV2bW9kZS5kbUZpZWxkcyAgICAgPSBETV9CSVRTUEVSUEVMIHwgRE1fUEVMU1dJRFRIIHwgRE1fUEVMU0hFSUdIVDsKICAgICAgICBkZXZtb2RlLmRtQml0c1BlclBlbCA9IGZvcm1hdERlc2MtPmJwcCAqIDg7CiAgICAgICAgZGV2bW9kZS5kbVBlbHNXaWR0aCAgPSBvYmplY3QtPm9yaWdfd2lkdGg7CiAgICAgICAgZGV2bW9kZS5kbVBlbHNIZWlnaHQgPSBvYmplY3QtPm9yaWdfaGVpZ2h0OwogICAgICAgIENoYW5nZURpc3BsYXlTZXR0aW5nc0V4VyhUaGlzLT5hZGFwdGVyLT5EZXZpY2VOYW1lLCAmZGV2bW9kZSwgTlVMTCwgQ0RTX0ZVTExTQ1JFRU4sIE5VTEwpOwogICAgfQoKICAgIGlmIChvYmplY3QtPmJhY2tCdWZmZXIpIHsKICAgICAgICBpbnQgaTsKICAgICAgICBmb3IoaSA9IDA7IGkgPCBvYmplY3QtPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyQ291bnQ7IGkrKykgewogICAgICAgICAgICBpZihvYmplY3QtPmJhY2tCdWZmZXJbaV0pIHsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9HZXRQYXJlbnQob2JqZWN0LT5iYWNrQnVmZmVyW2ldLCAmYnVmZmVyUGFyZW50KTsKICAgICAgICAgICAgICAgIElVbmtub3duX1JlbGVhc2UoYnVmZmVyUGFyZW50KTsgLyogb25jZSBmb3IgdGhlIGdldCBwYXJlbnQgKi8KICAgICAgICAgICAgICAgIGlmIChJVW5rbm93bl9SZWxlYXNlKGJ1ZmZlclBhcmVudCkgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgRklYTUUoIiglcCkgU29tZXRoaW5nJ3Mgc3RpbGwgaG9sZGluZyB0aGUgYmFjayBidWZmZXJcbiIsVGhpcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2JqZWN0LT5iYWNrQnVmZmVyKTsKICAgICAgICBvYmplY3QtPmJhY2tCdWZmZXIgPSBOVUxMOwogICAgfQogICAgaWYob2JqZWN0LT5jb250ZXh0WzBdKQogICAgICAgIERlc3Ryb3lDb250ZXh0KFRoaXMsIG9iamVjdC0+Y29udGV4dFswXSk7CiAgICBpZihvYmplY3QtPmZyb250QnVmZmVyKSB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0dldFBhcmVudChvYmplY3QtPmZyb250QnVmZmVyLCAmYnVmZmVyUGFyZW50KTsKICAgICAgICBJVW5rbm93bl9SZWxlYXNlKGJ1ZmZlclBhcmVudCk7IC8qIG9uY2UgZm9yIHRoZSBnZXQgcGFyZW50ICovCiAgICAgICAgaWYgKElVbmtub3duX1JlbGVhc2UoYnVmZmVyUGFyZW50KSA+IDApIHsKICAgICAgICAgICAgRklYTUUoIiglcCkgU29tZXRoaW5nJ3Mgc3RpbGwgaG9sZGluZyB0aGUgZnJvbnQgYnVmZmVyXG4iLFRoaXMpOwogICAgICAgIH0KICAgIH0KICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9iamVjdCk7CiAgICByZXR1cm4gaHI7Cn0KCi8qKiBOT1RFOiBUaGVzZSBhcmUgYWhlYWQgb2YgdGhlIG90aGVyIGdldHRlcnMgYW5kIHNldHRlcnMgdG8gc2F2ZSB1c2luZyBhIGZvcndhcmQgZGVjbGFyYXRpb24gKiovCnN0YXRpYyBVSU5UICAgICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXROdW1iZXJPZlN3YXBDaGFpbnMoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgcmV0dXJuIFRoaXMtPk51bWJlck9mU3dhcENoYWluczsKfQoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFN3YXBDaGFpbihJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgaVN3YXBDaGFpbiwgSVdpbmVEM0RTd2FwQ2hhaW4gKipwU3dhcENoYWluKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IHN3YXBjaGFpbiAlZFxuIiwgVGhpcywgaVN3YXBDaGFpbik7CgogICAgaWYoaVN3YXBDaGFpbiA8IFRoaXMtPk51bWJlck9mU3dhcENoYWlucykgewogICAgICAgICpwU3dhcENoYWluID0gVGhpcy0+c3dhcGNoYWluc1tpU3dhcENoYWluXTsKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9BZGRSZWYoKnBTd2FwQ2hhaW4pOwogICAgICAgIFRSQUNFKCIoJXApIHJldHVybmluZyAlcFxuIiwgVGhpcywgKnBTd2FwQ2hhaW4pOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgiU3dhcGNoYWluIG91dCBvZiByYW5nZVxuIik7CiAgICAgICAgKnBTd2FwQ2hhaW4gPSBOVUxMOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQp9CgovKioqKioKICogVmVydGV4IERlY2xhcmF0aW9uCiAqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWZXJ0ZXhEZWNsYXJhdGlvbihJV2luZUQzRERldmljZSogaWZhY2UsIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb24qKiBwcFZlcnRleERlY2xhcmF0aW9uLAogICAgICAgIElVbmtub3duICpwYXJlbnQsIGNvbnN0IFdJTkVEM0RWRVJURVhFTEVNRU5UICplbGVtZW50cywgVUlOVCBlbGVtZW50X2NvdW50KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgICAgICAgICAgICAqVGhpcyAgID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RWZXJ0ZXhEZWNsYXJhdGlvbkltcGwgKm9iamVjdCA9IE5VTEw7CiAgICBIUkVTVUxUIGhyID0gV0lORUQzRF9PSzsKCiAgICBUUkFDRSgiKCVwKSA6IGRpcmVjdFhWZXJzaW9uICV1LCBlbGVtZW50cyAlcCwgZWxlbWVudF9jb3VudCAlZCwgcHBEZWNsPSVwXG4iLAogICAgICAgICAgICBUaGlzLCAoKElXaW5lRDNESW1wbCAqKVRoaXMtPndpbmVEM0QpLT5keFZlcnNpb24sIGVsZW1lbnRzLCBlbGVtZW50X2NvdW50LCBwcFZlcnRleERlY2xhcmF0aW9uKTsKCiAgICBEM0RDUkVBVEVPQkpFQ1RJTlNUQU5DRShvYmplY3QsIFZlcnRleERlY2xhcmF0aW9uKQoKICAgIGhyID0gSVdpbmVEM0RWZXJ0ZXhEZWNsYXJhdGlvbl9TZXREZWNsYXJhdGlvbigoSVdpbmVEM0RWZXJ0ZXhEZWNsYXJhdGlvbiAqKW9iamVjdCwgZWxlbWVudHMsIGVsZW1lbnRfY291bnQpOwogICAgaWYoRkFJTEVEKGhyKSkgewogICAgICAgICpwcFZlcnRleERlY2xhcmF0aW9uID0gTlVMTDsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvYmplY3QpOwogICAgfQoKICAgIHJldHVybiBocjsKfQoKc3RhdGljIHVuc2lnbmVkIGludCBDb252ZXJ0RnZmVG9EZWNsYXJhdGlvbihJV2luZUQzRERldmljZUltcGwgKlRoaXMsIC8qIEZvciB0aGUgR0wgaW5mbywgd2hpY2ggaGFzIHRoZSB0eXBlIHRhYmxlICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZnZmLCBXSU5FRDNEVkVSVEVYRUxFTUVOVCoqIHBwVmVydGV4RWxlbWVudHMpIHsKCiAgICB1bnNpZ25lZCBpbnQgaWR4LCBpZHgyOwogICAgdW5zaWduZWQgaW50IG9mZnNldDsKICAgIEJPT0wgaGFzX3BvcyA9IChmdmYgJiBXSU5FRDNERlZGX1BPU0lUSU9OX01BU0spICE9IDA7CiAgICBCT09MIGhhc19ibGVuZCA9IChmdmYgJiBXSU5FRDNERlZGX1hZWkI1KSA+IFdJTkVEM0RGVkZfWFlaUkhXOwogICAgQk9PTCBoYXNfYmxlbmRfaWR4ID0gaGFzX2JsZW5kICYmCiAgICAgICAoKChmdmYgJiBXSU5FRDNERlZGX1hZWkI1KSA9PSBXSU5FRDNERlZGX1hZWkI1KSB8fAogICAgICAgIChmdmYgJiBXSU5FRDNERlZGX0xBU1RCRVRBX0QzRENPTE9SKSB8fAogICAgICAgIChmdmYgJiBXSU5FRDNERlZGX0xBU1RCRVRBX1VCWVRFNCkpOwogICAgQk9PTCBoYXNfbm9ybWFsID0gKGZ2ZiAmIFdJTkVEM0RGVkZfTk9STUFMKSAhPSAwOwogICAgQk9PTCBoYXNfcHNpemUgPSAoZnZmICYgV0lORUQzREZWRl9QU0laRSkgIT0gMDsKICAgIEJPT0wgaGFzX2RpZmZ1c2UgPSAoZnZmICYgV0lORUQzREZWRl9ESUZGVVNFKSAhPSAwOwogICAgQk9PTCBoYXNfc3BlY3VsYXIgPSAoZnZmICYgV0lORUQzREZWRl9TUEVDVUxBUikgIT0wOwoKICAgIERXT1JEIG51bV90ZXh0dXJlcyA9IChmdmYgJiBXSU5FRDNERlZGX1RFWENPVU5UX01BU0spID4+IFdJTkVEM0RGVkZfVEVYQ09VTlRfU0hJRlQ7CiAgICBEV09SRCB0ZXhjb29yZHMgPSAoZnZmICYgMHgwMEZGMDAwMCkgPj4gMTY7CgogICAgV0lORUQzRFZFUlRFWEVMRU1FTlQgZW5kX2VsZW1lbnQgPSBXSU5FRDNEREVDTF9FTkQoKTsKICAgIFdJTkVEM0RWRVJURVhFTEVNRU5UICplbGVtZW50cyA9IE5VTEw7CgogICAgdW5zaWduZWQgaW50IHNpemU7CiAgICBEV09SRCBudW1fYmxlbmRzID0gMSArICgoKGZ2ZiAmIFdJTkVEM0RGVkZfWFlaQjUpIC0gV0lORUQzREZWRl9YWVpCMSkgPj4gMSk7CiAgICBpZiAoaGFzX2JsZW5kX2lkeCkgbnVtX2JsZW5kcy0tOwoKICAgIC8qIENvbXB1dGUgZGVjbGFyYXRpb24gc2l6ZSAqLwogICAgc2l6ZSA9IGhhc19wb3MgKyAoaGFzX2JsZW5kICYmIG51bV9ibGVuZHMgPiAwKSArIGhhc19ibGVuZF9pZHggKyBoYXNfbm9ybWFsICsKICAgICAgICAgICBoYXNfcHNpemUgKyBoYXNfZGlmZnVzZSArIGhhc19zcGVjdWxhciArIG51bV90ZXh0dXJlcyArIDE7CgogICAgLyogY29udmVydCB0aGUgZGVjbGFyYXRpb24gKi8KICAgIGVsZW1lbnRzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemUgKiBzaXplb2YoV0lORUQzRFZFUlRFWEVMRU1FTlQpKTsKICAgIGlmICghZWxlbWVudHMpCiAgICAgICAgcmV0dXJuIDA7CgogICAgbWVtY3B5KCZlbGVtZW50c1tzaXplLTFdLCAmZW5kX2VsZW1lbnQsIHNpemVvZihXSU5FRDNEVkVSVEVYRUxFTUVOVCkpOwogICAgaWR4ID0gMDsKICAgIGlmIChoYXNfcG9zKSB7CiAgICAgICAgaWYgKCFoYXNfYmxlbmQgJiYgKGZ2ZiAmIFdJTkVEM0RGVkZfWFlaUkhXKSkgewogICAgICAgICAgICBlbGVtZW50c1tpZHhdLlR5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQ0OwogICAgICAgICAgICBlbGVtZW50c1tpZHhdLlVzYWdlID0gV0lORUQzRERFQ0xVU0FHRV9QT1NJVElPTlQ7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBlbGVtZW50c1tpZHhdLlR5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQzOwogICAgICAgICAgICBlbGVtZW50c1tpZHhdLlVzYWdlID0gV0lORUQzRERFQ0xVU0FHRV9QT1NJVElPTjsKICAgICAgICB9CiAgICAgICAgZWxlbWVudHNbaWR4XS5Vc2FnZUluZGV4ID0gMDsKICAgICAgICBpZHgrKzsKICAgIH0KICAgIGlmIChoYXNfYmxlbmQgJiYgKG51bV9ibGVuZHMgPiAwKSkgewogICAgICAgIGlmICgoKGZ2ZiAmIFdJTkVEM0RGVkZfWFlaQjUpID09IFdJTkVEM0RGVkZfWFlaQjIpICYmIChmdmYgJiBXSU5FRDNERlZGX0xBU1RCRVRBX0QzRENPTE9SKSkKICAgICAgICAgICAgZWxlbWVudHNbaWR4XS5UeXBlID0gV0lORUQzRERFQ0xUWVBFX0QzRENPTE9SOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZWxlbWVudHNbaWR4XS5UeXBlID0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUMSArIG51bV9ibGVuZHMgLSAxOwogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2UgPSBXSU5FRDNEREVDTFVTQUdFX0JMRU5EV0VJR0hUOwogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2VJbmRleCA9IDA7CiAgICAgICAgaWR4Kys7CiAgICB9CiAgICBpZiAoaGFzX2JsZW5kX2lkeCkgewogICAgICAgIGlmIChmdmYgJiBXSU5FRDNERlZGX0xBU1RCRVRBX1VCWVRFNCB8fAogICAgICAgICAgICAoKChmdmYgJiBXSU5FRDNERlZGX1hZWkI1KSA9PSBXSU5FRDNERlZGX1hZWkIyKSAmJiAoZnZmICYgV0lORUQzREZWRl9MQVNUQkVUQV9EM0RDT0xPUikpKQogICAgICAgICAgICBlbGVtZW50c1tpZHhdLlR5cGUgPSBXSU5FRDNEREVDTFRZUEVfVUJZVEU0OwogICAgICAgIGVsc2UgaWYgKGZ2ZiAmIFdJTkVEM0RGVkZfTEFTVEJFVEFfRDNEQ09MT1IpCiAgICAgICAgICAgIGVsZW1lbnRzW2lkeF0uVHlwZSA9IFdJTkVEM0RERUNMVFlQRV9EM0RDT0xPUjsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGVsZW1lbnRzW2lkeF0uVHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDE7CiAgICAgICAgZWxlbWVudHNbaWR4XS5Vc2FnZSA9IFdJTkVEM0RERUNMVVNBR0VfQkxFTkRJTkRJQ0VTOwogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2VJbmRleCA9IDA7CiAgICAgICAgaWR4Kys7CiAgICB9CiAgICBpZiAoaGFzX25vcm1hbCkgewogICAgICAgIGVsZW1lbnRzW2lkeF0uVHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDM7CiAgICAgICAgZWxlbWVudHNbaWR4XS5Vc2FnZSA9IFdJTkVEM0RERUNMVVNBR0VfTk9STUFMOwogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2VJbmRleCA9IDA7CiAgICAgICAgaWR4Kys7CiAgICB9CiAgICBpZiAoaGFzX3BzaXplKSB7CiAgICAgICAgZWxlbWVudHNbaWR4XS5UeXBlID0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUMTsKICAgICAgICBlbGVtZW50c1tpZHhdLlVzYWdlID0gV0lORUQzRERFQ0xVU0FHRV9QU0laRTsKICAgICAgICBlbGVtZW50c1tpZHhdLlVzYWdlSW5kZXggPSAwOwogICAgICAgIGlkeCsrOwogICAgfQogICAgaWYgKGhhc19kaWZmdXNlKSB7CiAgICAgICAgZWxlbWVudHNbaWR4XS5UeXBlID0gV0lORUQzRERFQ0xUWVBFX0QzRENPTE9SOwogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2UgPSBXSU5FRDNEREVDTFVTQUdFX0NPTE9SOwogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2VJbmRleCA9IDA7CiAgICAgICAgaWR4Kys7CiAgICB9CiAgICBpZiAoaGFzX3NwZWN1bGFyKSB7CiAgICAgICAgZWxlbWVudHNbaWR4XS5UeXBlID0gV0lORUQzRERFQ0xUWVBFX0QzRENPTE9SOwogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2UgPSBXSU5FRDNEREVDTFVTQUdFX0NPTE9SOwogICAgICAgIGVsZW1lbnRzW2lkeF0uVXNhZ2VJbmRleCA9IDE7CiAgICAgICAgaWR4Kys7CiAgICB9CiAgICBmb3IgKGlkeDIgPSAwOyBpZHgyIDwgbnVtX3RleHR1cmVzOyBpZHgyKyspIHsKICAgICAgICB1bnNpZ25lZCBpbnQgbnVtY29vcmRzID0gKHRleGNvb3JkcyA+PiAoaWR4MioyKSkgJiAweDAzOwogICAgICAgIHN3aXRjaCAobnVtY29vcmRzKSB7CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZWRl9URVhUVVJFRk9STUFUMToKICAgICAgICAgICAgICAgIGVsZW1lbnRzW2lkeF0uVHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDE7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBXSU5FRDNERlZGX1RFWFRVUkVGT1JNQVQyOgogICAgICAgICAgICAgICAgZWxlbWVudHNbaWR4XS5UeXBlID0gV0lORUQzRERFQ0xUWVBFX0ZMT0FUMjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFdJTkVEM0RGVkZfVEVYVFVSRUZPUk1BVDM6CiAgICAgICAgICAgICAgICBlbGVtZW50c1tpZHhdLlR5cGUgPSBXSU5FRDNEREVDTFRZUEVfRkxPQVQzOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgV0lORUQzREZWRl9URVhUVVJFRk9STUFUNDoKICAgICAgICAgICAgICAgIGVsZW1lbnRzW2lkeF0uVHlwZSA9IFdJTkVEM0RERUNMVFlQRV9GTE9BVDQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgZWxlbWVudHNbaWR4XS5Vc2FnZSA9IFdJTkVEM0RERUNMVVNBR0VfVEVYQ09PUkQ7CiAgICAgICAgZWxlbWVudHNbaWR4XS5Vc2FnZUluZGV4ID0gaWR4MjsKICAgICAgICBpZHgrKzsKICAgIH0KCiAgICAvKiBOb3cgY29tcHV0ZSBvZmZzZXRzLCBhbmQgaW5pdGlhbGl6ZSB0aGUgcmVzdCBvZiB0aGUgZmllbGRzICovCiAgICBmb3IgKGlkeCA9IDAsIG9mZnNldCA9IDA7IGlkeCA8IHNpemUtMTsgaWR4KyspIHsKICAgICAgICBlbGVtZW50c1tpZHhdLlN0cmVhbSA9IDA7CiAgICAgICAgZWxlbWVudHNbaWR4XS5NZXRob2QgPSBXSU5FRDNEREVDTE1FVEhPRF9ERUZBVUxUOwogICAgICAgIGVsZW1lbnRzW2lkeF0uT2Zmc2V0ID0gb2Zmc2V0OwogICAgICAgIG9mZnNldCArPSBXSU5FRDNEX0FUUl9TSVpFKGVsZW1lbnRzW2lkeF0uVHlwZSkgKiBXSU5FRDNEX0FUUl9UWVBFU0laRShlbGVtZW50c1tpZHhdLlR5cGUpOwogICAgfQoKICAgICpwcFZlcnRleEVsZW1lbnRzID0gZWxlbWVudHM7CiAgICByZXR1cm4gc2l6ZTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWZXJ0ZXhEZWNsYXJhdGlvbkZyb21GVkYoSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uKiogcHBWZXJ0ZXhEZWNsYXJhdGlvbiwgSVVua25vd24gKlBhcmVudCwgRFdPUkQgRnZmKSB7CiAgICBXSU5FRDNEVkVSVEVYRUxFTUVOVCogZWxlbWVudHMgPSBOVUxMOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIHVuc2lnbmVkIGludCBzaXplOwogICAgRFdPUkQgaHI7CgogICAgc2l6ZSA9IENvbnZlcnRGdmZUb0RlY2xhcmF0aW9uKFRoaXMsIEZ2ZiwgJmVsZW1lbnRzKTsKICAgIGlmIChzaXplID09IDApIHJldHVybiBXSU5FRDNERVJSX09VVE9GVklERU9NRU1PUlk7CgogICAgaHIgPSBJV2luZUQzRERldmljZV9DcmVhdGVWZXJ0ZXhEZWNsYXJhdGlvbihpZmFjZSwgcHBWZXJ0ZXhEZWNsYXJhdGlvbiwgUGFyZW50LCBlbGVtZW50cywgc2l6ZSk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBlbGVtZW50cyk7CiAgICBpZiAoaHIgIT0gU19PSykgcmV0dXJuIGhyOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2FyY2hpdmUvZGVmYXVsdC5hc3A/dXJsPS9hcmNoaXZlL2VuLXVzL2RpcmVjdHg5X2MvZGlyZWN0eC9ncmFwaGljcy9wcm9ncmFtbWluZ2d1aWRlL3Byb2dyYW1tYWJsZS92ZXJ0ZXhzaGFkZXJzL3ZzY3JlYXRlLmFzcCAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZlcnRleFNoYWRlcihJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb24gKnZlcnRleF9kZWNsYXJhdGlvbiwgQ09OU1QgRFdPUkQgKnBGdW5jdGlvbiwgSVdpbmVEM0RWZXJ0ZXhTaGFkZXIgKipwcFZlcnRleFNoYWRlciwgSVVua25vd24gKnBhcmVudCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICAgICAgICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RWZXJ0ZXhTaGFkZXJJbXBsICpvYmplY3Q7ICAvKiBOT1RFOiBpbXBsIHVzYWdlIGlzIG9rLCB0aGlzIGlzIGEgY3JlYXRlICovCiAgICBIUkVTVUxUIGhyID0gV0lORUQzRF9PSzsKICAgIEQzRENSRUFURVNIQURFUk9CSkVDVElOU1RBTkNFKG9iamVjdCwgVmVydGV4U2hhZGVyKQogICAgb2JqZWN0LT5iYXNlU2hhZGVyLnNoYWRlcl9pbnMgPSBJV2luZUQzRFZlcnRleFNoYWRlckltcGxfc2hhZGVyX2luczsKCiAgICBUUkFDRSgiKCVwKSA6IENyZWF0ZWQgVmVydGV4IHNoYWRlciAlcFxuIiwgVGhpcywgKnBwVmVydGV4U2hhZGVyKTsKCiAgICBpZiAodmVydGV4X2RlY2xhcmF0aW9uKSB7CiAgICAgICAgSVdpbmVEM0RWZXJ0ZXhTaGFkZXJfRmFrZVNlbWFudGljcygqcHBWZXJ0ZXhTaGFkZXIsIHZlcnRleF9kZWNsYXJhdGlvbik7CiAgICB9CgogICAgaHIgPSBJV2luZUQzRFZlcnRleFNoYWRlcl9TZXRGdW5jdGlvbigqcHBWZXJ0ZXhTaGFkZXIsIHBGdW5jdGlvbik7CgogICAgaWYgKFdJTkVEM0RfT0sgIT0gaHIpIHsKICAgICAgICBGSVhNRSgiKCVwKSA6IEZhaWxlZCB0byBzZXQgdGhlIGZ1bmN0aW9uLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIiwgaWZhY2UpOwogICAgICAgIElXaW5lRDNEVmVydGV4U2hhZGVyX1JlbGVhc2UoKnBwVmVydGV4U2hhZGVyKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIGxpc3RfYWRkX2hlYWQoJlRoaXMtPnNoYWRlcnMsICZvYmplY3QtPmJhc2VTaGFkZXIuc2hhZGVyX2xpc3RfZW50cnkpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVBpeGVsU2hhZGVyKElXaW5lRDNERGV2aWNlICppZmFjZSwgQ09OU1QgRFdPUkQgKnBGdW5jdGlvbiwgSVdpbmVEM0RQaXhlbFNoYWRlciAqKnBwUGl4ZWxTaGFkZXIsIElVbmtub3duICpwYXJlbnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICpvYmplY3Q7IC8qIE5PVEU6IGltcGwgYWxsb3dlZCwgdGhpcyBpcyBhIGNyZWF0ZSAqLwogICAgSFJFU1VMVCBociA9IFdJTkVEM0RfT0s7CgogICAgRDNEQ1JFQVRFU0hBREVST0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBQaXhlbFNoYWRlcikKICAgIG9iamVjdC0+YmFzZVNoYWRlci5zaGFkZXJfaW5zID0gSVdpbmVEM0RQaXhlbFNoYWRlckltcGxfc2hhZGVyX2luczsKICAgIGhyID0gSVdpbmVEM0RQaXhlbFNoYWRlcl9TZXRGdW5jdGlvbigqcHBQaXhlbFNoYWRlciwgcEZ1bmN0aW9uKTsKICAgIGlmIChXSU5FRDNEX09LID09IGhyKSB7CiAgICAgICAgVFJBQ0UoIiglcCkgOiBDcmVhdGVkIFBpeGVsIHNoYWRlciAlcFxuIiwgVGhpcywgKnBwUGl4ZWxTaGFkZXIpOwogICAgICAgIGxpc3RfYWRkX2hlYWQoJlRoaXMtPnNoYWRlcnMsICZvYmplY3QtPmJhc2VTaGFkZXIuc2hhZGVyX2xpc3RfZW50cnkpOwogICAgfSBlbHNlIHsKICAgICAgICBXQVJOKCIoJXApIDogRmFpbGVkIHRvIGNyZWF0ZSBwaXhlbCBzaGFkZXJcbiIsIFRoaXMpOwogICAgfQoKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVQYWxldHRlKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgRmxhZ3MsIFBBTEVUVEVFTlRSWSAqUGFsRW50LCBJV2luZUQzRFBhbGV0dGUgKipQYWxldHRlLCBJVW5rbm93biAqUGFyZW50KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RQYWxldHRlSW1wbCAqb2JqZWN0OwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJXgsICVwLCAlcCwgJXApXG4iLCBUaGlzLCBGbGFncywgUGFsRW50LCBQYWxldHRlLCBQYXJlbnQpOwoKICAgIC8qIENyZWF0ZSB0aGUgbmV3IG9iamVjdCAqLwogICAgb2JqZWN0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJV2luZUQzRFBhbGV0dGVJbXBsKSk7CiAgICBpZighb2JqZWN0KSB7CiAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5IHdoZW4gYWxsb2NhdGluZyBtZW1vcnkgZm9yIGEgSVdpbmVEM0RQYWxldHRlIGltcGxlbWVudGF0aW9uXG4iKTsKICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgIH0KCiAgICBvYmplY3QtPmxwVnRibCA9ICZJV2luZUQzRFBhbGV0dGVfVnRibDsKICAgIG9iamVjdC0+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+ZnZmICAgICAgICAgICAgICA9IGZ2ZjsKICAgIFRSQUNFKCIoJXApIDogRlZGIFNoYWRlciBGVkYgc2V0IHRvICV4XG4iLCBUaGlzLCBmdmYpOwogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1ZERUNMKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRGVkYoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCAqcGZ2ZikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiBHZXRGVkYgcmV0dXJuaW5nICV4XG4iLCBUaGlzLCBUaGlzLT5zdGF0ZUJsb2NrLT5mdmYpOwogICAgKnBmdmYgPSBUaGlzLT5zdGF0ZUJsb2NrLT5mdmY7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBTdHJlYW0gU291cmNlCiAqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRTdHJlYW1Tb3VyY2UoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIFN0cmVhbU51bWJlcixJV2luZUQzRFZlcnRleEJ1ZmZlciogcFN0cmVhbURhdGEsIFVJTlQgT2Zmc2V0SW5CeXRlcywgVUlOVCBTdHJpZGUpIHsKICAgICAgICBJV2luZUQzRERldmljZUltcGwgICAgICAgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFZlcnRleEJ1ZmZlciAgICAgKm9sZFNyYzsKCiAgICBpZiAoU3RyZWFtTnVtYmVyID49IE1BWF9TVFJFQU1TKSB7CiAgICAgICAgV0FSTigiU3RyZWFtIG91dCBvZiByYW5nZSAlZFxuIiwgU3RyZWFtTnVtYmVyKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0gZWxzZSBpZihPZmZzZXRJbkJ5dGVzICYgMHgzKSB7CiAgICAgICAgV0FSTigiT2Zmc2V0SW5CeXRlcyBpcyBub3QgNCBieXRlIGFsaWduZWQ6ICVkXG4iLCBPZmZzZXRJbkJ5dGVzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBvbGRTcmMgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbU3RyZWFtTnVtYmVyXTsKICAgIFRSQUNFKCIoJXApIDogU3RyZWFtTm86ICV1LCBPbGRTdHJlYW0gKCVwKSwgTmV3U3RyZWFtICglcCksIE9mZnNldEluQnl0ZXMgJXUsIE5ld1N0cmlkZSAldVxuIiwgVGhpcywgU3RyZWFtTnVtYmVyLCBvbGRTcmMsIHBTdHJlYW1EYXRhLCBPZmZzZXRJbkJ5dGVzLCBTdHJpZGUpOwoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQuc3RyZWFtU291cmNlW1N0cmVhbU51bWJlcl0gPSBUUlVFOwoKICAgIGlmKG9sZFNyYyA9PSBwU3RyZWFtRGF0YSAmJgogICAgICAgVGhpcy0+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+c3RyZWFtSXNVUDsKICAgIFRSQUNFKCIoJXApLT4oJWQsJWQsJWQsJXAsJXAsJWRcbiIsIFRoaXMsIFNyY1N0YXJ0SW5kZXgsIERlc3RJbmRleCwgVmVydGV4Q291bnQsIHBEZXN0QnVmZmVyLCBwVmVydGV4RGVjbCwgRmxhZ3MpOwoKICAgIGlmKHBWZXJ0ZXhEZWNsKSB7CiAgICAgICAgRVJSKCJPdXRwdXQgdmVydGV4IGRlY2xhcmF0aW9uIG5vdCBpbXBsZW1lbnRlZCB5ZXRcbiIpOwogICAgfQoKICAgIC8qIE5lZWQgYW55IGNvbnRleHQgdG8gd3JpdGUgdG8gdGhlIHZiby4gKi8KICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0LCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwoKICAgIC8qIFByb2Nlc3NWZXJ0aWNlcyByZWFkcyBmcm9tIHZlcnRleCBidWZmZXJzLCB3aGljaCBoYXZlIHRvIGJlIGFzc2lnbmVkLiBEcmF3UHJpbWl0aXZlIGFuZCBEcmF3UHJpbWl0aXZlVVAKICAgICAqIGNvbnRyb2wgdGhlIHN0cmVhbUlzVVAgZmxhZywgdGh1cyByZXN0b3JlIGl0IGFmdGVyd2FyZHMuCiAgICAgKi8KICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbUlzVVAgPSBGQUxTRTsKICAgIG1lbXNldCgmc3RyaWRlZCwgMCwgc2l6ZW9mKHN0cmlkZWQpKTsKICAgIHByaW1pdGl2ZURlY2xhcmF0aW9uQ29udmVydFRvU3RyaWRlZERhdGEoaWZhY2UsIEZBTFNFLCAmc3RyaWRlZCwgJnZibyk7CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Jc1VQID0gc3RyZWFtV2FzVVA7CgogICAgaWYodmJvIHx8IFNyY1N0YXJ0SW5kZXgpIHsKICAgICAgICB1bnNpZ25lZCBpbnQgaTsKICAgICAgICAvKiBQcm9jZXNzVmVydGljZXMgY2FuJ3QgY29udmVydCBGUk9NIGEgdmJvLCBhbmQgdmVydGV4IGJ1ZmZlcnMgdXNlZCB0byBzb3VyY2UgaW50byBQcm9jZXNWZXJ0aWNzZSBhcmUKICAgICAgICAgKiB1bmxpa2VseSB0byBldmVyIGJlIHVzZWQgZm9yIGRyYXdpbmcuIFJlbGVhc2UgdmJvcyBpbiB0aG9zZSBidWZmZXJzIGFuZCBmaXggdXAgdGhlIHN0cmlkZWQgc3RydWN0dXJlCiAgICAgICAgICoKICAgICAgICAgKiBBbHNvIGdldCB0aGUgc3RhcnQgaW5kZXggaW4sIGJ1dCBvbmx5IGxvb3Agb3ZlciBhbGwgZWxlbWVudHMgaWYgdGhlcmUncyBzb21ldGhpbmcgdG8gYWRkIGF0IGFsbC4KICAgICAgICAgKi8KI2RlZmluZSBGSVhTUkModHlwZSkgXAogICAgICAgIGlmKHN0cmlkZWQudS5zLnR5cGUuVkJPKSB7IFwKICAgICAgICAgICAgSVdpbmVEM0RWZXJ0ZXhCdWZmZXJJbXBsICp2YiA9IChJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKikgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlW3N0cmlkZWQudS5zLnR5cGUuc3RyZWFtTm9dOyBcCiAgICAgICAgICAgIHN0cmlkZWQudS5zLnR5cGUuVkJPID0gMDsgXAogICAgICAgICAgICBzdHJpZGVkLnUucy50eXBlLmxwRGF0YSA9IChCWVRFICopICgodW5zaWduZWQgbG9uZykgc3RyaWRlZC51LnMudHlwZS5scERhdGEgKyAodW5zaWduZWQgbG9uZykgdmItPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSk7IFwKICAgICAgICAgICAgRU5URVJfR0woKTsgXAogICAgICAgICAgICBHTF9FWFRDQUxMKGdsRGVsZXRlQnVmZmVyc0FSQigxLCAmdmItPnZibykpOyBcCiAgICAgICAgICAgIHZiLT52Ym8gPSAwOyBcCiAgICAgICAgICAgIExFQVZFX0dMKCk7IFwKICAgICAgICB9IFwKICAgICAgICBpZihzdHJpZGVkLnUucy50eXBlLmxwRGF0YSkgeyBcCiAgICAgICAgICAgIHN0cmlkZWQudS5zLnR5cGUubHBEYXRhICs9IHN0cmlkZWQudS5zLnR5cGUuZHdTdHJpZGUgKiBTcmNTdGFydEluZGV4OyBcCiAgICAgICAgfQogICAgICAgIEZJWFNSQyhwb3NpdGlvbik7CiAgICAgICAgRklYU1JDKGJsZW5kV2VpZ2h0cyk7CiAgICAgICAgRklYU1JDKGJsZW5kTWF0cml4SW5kaWNlcyk7CiAgICAgICAgRklYU1JDKG5vcm1hbCk7CiAgICAgICAgRklYU1JDKHBTaXplKTsKICAgICAgICBGSVhTUkMoZGlmZnVzZSk7CiAgICAgICAgRklYU1JDKHNwZWN1bGFyKTsKICAgICAgICBmb3IoaSA9IDA7IGkgPCBXSU5FRDNERFBfTUFYVEVYQ09PUkQ7IGkrKykgewogICAgICAgICAgICBGSVhTUkModGV4Q29vcmRzW2ldKTsKICAgICAgICB9CiAgICAgICAgRklYU1JDKHBvc2l0aW9uMik7CiAgICAgICAgRklYU1JDKG5vcm1hbDIpOwogICAgICAgIEZJWFNSQyh0YW5nZW50KTsKICAgICAgICBGSVhTUkMoYmlub3JtYWwpOwogICAgICAgIEZJWFNSQyh0ZXNzRmFjdG9yKTsKICAgICAgICBGSVhTUkMoZm9nKTsKICAgICAgICBGSVhTUkMoZGVwdGgpOwogICAgICAgIEZJWFNSQyhzYW1wbGUpOwojdW5kZWYgRklYU1JDCiAgICB9CgogICAgcmV0dXJuIHByb2Nlc3NfdmVydGljZXNfc3RyaWRlZChUaGlzLCBEZXN0SW5kZXgsIFZlcnRleENvdW50LCAmc3RyaWRlZCwgKElXaW5lRDNEVmVydGV4QnVmZmVySW1wbCAqKSBwRGVzdEJ1ZmZlciwgRmxhZ3MpOwp9CgovKioqKioKICogR2V0IC8gU2V0IFRleHR1cmUgU3RhZ2UgU3RhdGVzCiAqIFRPRE86IFZlcmlmeSBhZ2FpbnN0IGR4OSBkZWZpbml0aW9ucwogKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0VGV4dHVyZVN0YWdlU3RhdGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBTdGFnZSwgV0lORUQzRFRFWFRVUkVTVEFHRVNUQVRFVFlQRSBUeXBlLCBEV09SRCBWYWx1ZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgRFdPUkQgb2xkVmFsdWUgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbU3RhZ2VdW1R5cGVdOwoKICAgIFRSQUNFKCIoJXApIDogU3RhZ2U9JWQsIFR5cGU9JXMoJWQpLCBWYWx1ZT0lZFxuIiwgVGhpcywgU3RhZ2UsIGRlYnVnX2QzZHRleHR1cmVzdGF0ZShUeXBlKSwgVHlwZSwgVmFsdWUpOwoKICAgIGlmIChTdGFnZSA+PSBNQVhfVEVYVFVSRVMpIHsKICAgICAgICBXQVJOKCJBdHRlbXB0aW5nIHRvIHNldCBzdGFnZSAldSB3aGljaCBpcyBoaWdoZXIgdGhhbiB0aGUgbWF4IHN0YWdlICV1LCBpZ25vcmluZ1xuIiwgU3RhZ2UsIE1BWF9URVhUVVJFUyAtIDEpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQudGV4dHVyZVN0YXRlW1N0YWdlXVtUeXBlXSA9IFRSVUU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbU3RhZ2VdW1R5cGVdICAgICAgICAgPSBWYWx1ZTsKCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIC8qIENoZWNrZWQgYWZ0ZXIgdGhlIGFzc2lnbm1lbnRzIHRvIGFsbG93IHByb3BlciBzdGF0ZWJsb2NrIHJlY29yZGluZyAqLwogICAgaWYob2xkVmFsdWUgPT0gVmFsdWUpIHsKICAgICAgICBUUkFDRSgiQXBwIGlzIHNldHRpbmcgdGhlIG9sZCB2YWx1ZSBvdmVyLCBub3RoaW5nIHRvIGRvXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBpZihTdGFnZSA+IFRoaXMtPnN0YXRlQmxvY2stPmxvd2VzdF9kaXNhYmxlZF9zdGFnZSAmJgogICAgICAgU3RhdGVUYWJsZVtTVEFURV9URVhUVVJFU1RBR0UoMCwgVHlwZSldLnJlcHJlc2VudGF0aXZlID09IFNUQVRFX1RFWFRVUkVTVEFHRSgwLCBXSU5FRDNEVFNTX0NPTE9ST1ApKSB7CiAgICAgICAgLyogQ29sb3JvcCBjaGFuZ2UgYWJvdmUgbG93ZXN0IGRpc2FibGVkIHN0YWdlPyBUaGF0IHdvbid0IGNoYW5nZSBhbnl0aGluZyBpbiB0aGUgZ2wgc2V0dXAKICAgICAgICAgKiBDaGFuZ2VzIGluIG90aGVyIHN0YXRlcyBhcmUgaW1wb3J0YW50IG9uIGRpc2FibGVkIHN0YWdlcyB0b28KICAgICAgICAgKi8KICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBpZihUeXBlID09IFdJTkVEM0RUU1NfQ09MT1JPUCkgewogICAgICAgIGludCBpOwoKICAgICAgICBpZihWYWx1ZSA9PSBXSU5FRDNEVE9QX0RJU0FCTEUgJiYgb2xkVmFsdWUgIT0gV0lORUQzRFRPUF9ESVNBQkxFKSB7CiAgICAgICAgICAgIC8qIFByZXZpb3VzbHkgZW5hYmxlZCBzdGFnZSBkaXNhYmxlZCBub3cuIE1ha2Ugc3VyZSB0byBkaXJ0aWZ5IGFsbCBlbmFibGVkIHN0YWdlcyBhYm92ZSBTdGFnZSwKICAgICAgICAgICAgICogdGhleSBoYXZlIHRvIGJlIGRpc2FibGVkCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIFRoZSBjdXJyZW50IHN0YWdlIGlzIGRpcnRpZmllZCBiZWxvdy4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGZvcihpID0gU3RhZ2UgKyAxOyBpIDwgVGhpcy0+c3RhdGVCbG9jay0+bG93ZXN0X2Rpc2FibGVkX3N0YWdlOyBpKyspIHsKICAgICAgICAgICAgICAgIFRSQUNFKCJBZGRpdGlvbmFsbHkgZGlydGlmeWluZyBzdGFnZSAlZFxuIiwgaSk7CiAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVEVYVFVSRVNUQUdFKGksIFdJTkVEM0RUU1NfQ09MT1JPUCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPmxvd2VzdF9kaXNhYmxlZF9zdGFnZSA9IFN0YWdlOwogICAgICAgICAgICBUUkFDRSgiTmV3IGxvd2VzdCBkaXNhYmxlZDogJWRcbiIsIFN0YWdlKTsKICAgICAgICB9IGVsc2UgaWYoVmFsdWUgIT0gV0lORUQzRFRPUF9ESVNBQkxFICYmIG9sZFZhbHVlID09IFdJTkVEM0RUT1BfRElTQUJMRSkgewogICAgICAgICAgICAvKiBQcmV2aW91c2x5IGRpc2FibGVkIHN0YWdlIGVuYWJsZWQuIFN0YWdlcyBhYm92ZSBpdCBtYXkgbmVlZCBlbmFibGluZwogICAgICAgICAgICAgKiBzdGFnZSBtdXN0IGJlIGxvd2VzdF9kaXNhYmxlZF9zdGFnZSBoZXJlLCBpZiBpdCdzIGJpZ2dlciBzdWNjZXNzIGlzIHJldHVybmVkIGFib3ZlLAogICAgICAgICAgICAgKiBhbmQgc3RhZ2VzIGJlbG93IHRoZSBsb3dlc3QgZGlzYWJsZWQgc3RhZ2UgY2FuJ3QgYmUgZW5hYmxlZChiZWNhdXNlIHRoZXkgYXJlIGVuYWJsZWQgYWxyZWFkeSkuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEFnYWluIHN0YWdlIFN0YWdlIGRvZXNuJ3QgbmVlZCB0byBiZSBkaXJ0aWZpZWQgaGVyZSwgaXQgaXMgaGFuZGxlZCBiZWxvdy4KICAgICAgICAgICAgICovCgogICAgICAgICAgICBmb3IoaSA9IFN0YWdlICsgMTsgaSA8IEdMX0xJTUlUUyh0ZXh0dXJlX3N0YWdlcyk7IGkrKykgewogICAgICAgICAgICAgICAgaWYoVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlW2ldW1dJTkVEM0RUU1NfQ09MT1JPUF0gPT0gV0lORUQzRFRPUF9ESVNBQkxFKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBUUkFDRSgiQWRkaXRpb25hbGx5IGRpcnRpZnlpbmcgc3RhZ2UgJWQgZHVlIHRvIGVuYWJsZVxuIiwgaSk7CiAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVEVYVFVSRVNUQUdFKGksIFdJTkVEM0RUU1NfQ09MT1JPUCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPmxvd2VzdF9kaXNhYmxlZF9zdGFnZSA9IGk7CiAgICAgICAgICAgIFRSQUNFKCJOZXcgbG93ZXN0IGRpc2FibGVkOiAlZFxuIiwgaSk7CiAgICAgICAgfQogICAgICAgIGlmKEdMX1NVUFBPUlQoTlZfUkVHSVNURVJfQ09NQklORVJTKSAmJiAhVGhpcy0+c3RhdGVCbG9jay0+cGl4ZWxTaGFkZXIpIHsKICAgICAgICAgICAgLyogVE9ETzogQnVpbHQgYSBzdGFnZSAtPiB0ZXh0dXJlIHVuaXQgbWFwcGluZyBmb3IgcmVnaXN0ZXIgY29tYmluZXJzICovCiAgICAgICAgfQogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9URVhUVVJFU1RBR0UoU3RhZ2UsIFR5cGUpKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRUZXh0dXJlU3RhZ2VTdGF0ZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIFN0YWdlLCBXSU5FRDNEVEVYVFVSRVNUQUdFU1RBVEVUWVBFIFR5cGUsIERXT1JEKiBwVmFsdWUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogcmVxdWVzdGluZyBTdGFnZSAlZCwgVHlwZSAlZCBnZXR0aW5nICVkXG4iLCBUaGlzLCBTdGFnZSwgVHlwZSwgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlW1N0YWdlXVtUeXBlXSk7CiAgICAqcFZhbHVlID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlW1N0YWdlXVtUeXBlXTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogR2V0IC8gU2V0IFRleHR1cmUKICoqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFRleHR1cmUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBTdGFnZSwgSVdpbmVEM0RCYXNlVGV4dHVyZSogcFRleHR1cmUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEQmFzZVRleHR1cmUgKm9sZFRleHR1cmU7CgogICAgVFJBQ0UoIiglcCkgOiBTdGFnZSAlI3gsIFRleHR1cmUgJXBcbiIsIFRoaXMsIFN0YWdlLCBwVGV4dHVyZSk7CgogICAgaWYgKFN0YWdlID49IFdJTkVEM0RWRVJURVhURVhUVVJFU0FNUExFUjAgJiYgU3RhZ2UgPD0gV0lORUQzRFZFUlRFWFRFWFRVUkVTQU1QTEVSMykgewogICAgICAgIFN0YWdlIC09IChXSU5FRDNEVkVSVEVYVEVYVFVSRVNBTVBMRVIwIC0gTUFYX0ZSQUdNRU5UX1NBTVBMRVJTKTsKICAgIH0KCiAgICBvbGRUZXh0dXJlID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZXNbU3RhZ2VdOwoKICAgIGlmKHBUZXh0dXJlICE9IE5VTEwpIHsKICAgICAgICAvKiBTZXRUZXh0dXJlIGlzbid0IGFsbG93ZWQgb24gdGV4dHVyZXMgaW4gV0lORUQzRFBPT0xfU0NSQVRDSDsgCiAgICAgICAgICovCiAgICAgICAgaWYoKChJV2luZUQzRFRleHR1cmVJbXBsKilwVGV4dHVyZSktPnJlc291cmNlLnBvb2wgPT0gV0lORUQzRFBPT0xfU0NSQVRDSCkgewogICAgICAgICAgICBXQVJOKCIoJXApIEF0dGVtcHQgdG8gc2V0IHNjcmF0Y2ggdGV4dHVyZSByZWplY3RlZFxuIiwgcFRleHR1cmUpOwogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICB9CiAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZURpbWVuc2lvbnNbU3RhZ2VdID0gSVdpbmVEM0RCYXNlVGV4dHVyZV9HZXRUZXh0dXJlRGltZW5zaW9ucyhwVGV4dHVyZSk7CiAgICB9CgogICAgVFJBQ0UoIkdMX0xJTUlUUyAlZFxuIixHTF9MSU1JVFMoc2FtcGxlcl9zdGFnZXMpKTsKICAgIFRSQUNFKCIoJXApIDogb2xkdGV4dHVyZSglcClcbiIsIFRoaXMsb2xkVGV4dHVyZSk7CgogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC50ZXh0dXJlc1tTdGFnZV0gPSBUUlVFOwogICAgVFJBQ0UoIiglcCkgOiBzZXR0aW5nIG5ldyB0ZXh0dXJlIHRvICVwXG4iLCBUaGlzLCBwVGV4dHVyZSk7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlc1tTdGFnZV0gICAgICAgICA9IHBUZXh0dXJlOwoKICAgIC8qIEhhbmRsZSByZWNvcmRpbmcgb2Ygc3RhdGUgYmxvY2tzICovCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIGlmKG9sZFRleHR1cmUgPT0gcFRleHR1cmUpIHsKICAgICAgICBUUkFDRSgiQXBwIGlzIHNldHRpbmcgdGhlIHNhbWUgdGV4dHVyZSBhZ2Fpbiwgbm90aGluZyB0byBkb1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgLyoqIE5PVEU6IE1TRE4gc2F5cyB0aGF0IHNldFRleHR1cmUgaW5jcmVhc2VzIHRoZSByZWZlcmVuY2UgY291bnQsCiAgICAqIGFuZCB0aGF0IHRoZSBhcHBsaWNhdGlvbiBtdXN0IHNldCB0aGUgdGV4dHVyZSBiYWNrIHRvIG51bGwgKG9yIGhhdmUgYSBsZWFreSBhcHBsaWNhdGlvbiksCiAgICAqIFRoaXMgbWVhbnMgd2Ugc2hvdWxkIHBhc3MgdGhlIHJlZmNvdW50IHVwIHRvIHRoZSBwYXJlbnQKICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgaWYgKE5VTEwgIT0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZXNbU3RhZ2VdKSB7CiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKm5ldyA9IChJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqKSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlc1tTdGFnZV07CiAgICAgICAgVUxPTkcgYmluZENvdW50ID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJm5ldy0+YmFzZVRleHR1cmUuYmluZENvdW50KTsKCiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9BZGRSZWYoVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZXNbU3RhZ2VdKTsKICAgICAgICBpZihvbGRUZXh0dXJlID09IE5VTEwgJiYgU3RhZ2UgPCBNQVhfVEVYVFVSRVMpIHsKICAgICAgICAgICAgLyogVGhlIHNvdXJjZSBhcmd1bWVudHMgZm9yIGNvbG9yIGFuZCBhbHBoYSBvcHMgaGF2ZSBkaWZmZXJlbnQgbWVhbmluZ3Mgd2hlbiBhIE5VTEwgdGV4dHVyZSBpcyBib3VuZCwKICAgICAgICAgICAgICogc28gdGhlIENPTE9ST1AgYW5kIEFMUEhBT1AgaGF2ZSB0byBiZSBkaXJ0aWZpZWQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVEVYVFVSRVNUQUdFKFN0YWdlLCBXSU5FRDNEVFNTX0NPTE9ST1ApKTsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1RFWFRVUkVTVEFHRShTdGFnZSwgV0lORUQzRFRTU19BTFBIQU9QKSk7CiAgICAgICAgfQogICAgICAgIGlmKGJpbmRDb3VudCA9PSAxKSB7CiAgICAgICAgICAgIG5ldy0+YmFzZVRleHR1cmUuc2FtcGxlciA9IFN0YWdlOwogICAgICAgIH0KICAgICAgICAvKiBNb3JlIHRoYW4gb25lIGFzc2lnbm1lbnQ/IERvZXNuJ3QgbWF0dGVyLCB3ZSBvbmx5IG5lZWQgb25lIGdsIHRleHR1cmUgdW5pdCB0byB1c2UgZm9yIHVwbG9hZGluZyAqLwoKICAgIH0KCiAgICBpZiAoTlVMTCAhPSBvbGRUZXh0dXJlKSB7CiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKm9sZCA9IChJV2luZUQzREJhc2VUZXh0dXJlSW1wbCAqKSBvbGRUZXh0dXJlOwogICAgICAgIExPTkcgYmluZENvdW50ID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJm9sZC0+YmFzZVRleHR1cmUuYmluZENvdW50KTsKCiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9SZWxlYXNlKG9sZFRleHR1cmUpOwogICAgICAgIGlmKHBUZXh0dXJlID09IE5VTEwgJiYgU3RhZ2UgPCBNQVhfVEVYVFVSRVMpIHsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1RFWFRVUkVTVEFHRShTdGFnZSwgV0lORUQzRFRTU19DT0xPUk9QKSk7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9URVhUVVJFU1RBR0UoU3RhZ2UsIFdJTkVEM0RUU1NfQUxQSEFPUCkpOwogICAgICAgIH0KCiAgICAgICAgaWYoYmluZENvdW50ICYmIG9sZC0+YmFzZVRleHR1cmUuc2FtcGxlciA9PSBTdGFnZSkgewogICAgICAgICAgICBpbnQgaTsKICAgICAgICAgICAgLyogSGF2ZSB0byBkbyBhIHNlYXJjaCBmb3IgdGhlIG90aGVyIHNhbXBsZXIocykgd2hlcmUgdGhlIHRleHR1cmUgaXMgYm91bmQgdG8KICAgICAgICAgICAgICogU2hvdWxkbid0IGhhcHBlbiBhcyBsb25nIGFzIGFwcHMgYmluZCBhIHRleHR1cmUgb25seSB0byBvbmUgc3RhZ2UKICAgICAgICAgICAgICovCiAgICAgICAgICAgIFRSQUNFKCJTZWFyY2luZyBmb3Igb3RoZXIgc2FtcGxlciAvIHN0YWdlIGlkIHdoZXJlIHRoZSB0ZXh0dXJlIGlzIGJvdW5kIHRvXG4iKTsKICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDwgTUFYX0NPTUJJTkVEX1NBTVBMRVJTOyBpKyspIHsKICAgICAgICAgICAgICAgIGlmKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRleHR1cmVzW2ldID09IG9sZFRleHR1cmUpIHsKICAgICAgICAgICAgICAgICAgICBvbGQtPmJhc2VUZXh0dXJlLnNhbXBsZXIgPSBpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TQU1QTEVSKFN0YWdlKSk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0VGV4dHVyZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIFN0YWdlLCBJV2luZUQzREJhc2VUZXh0dXJlKiogcHBUZXh0dXJlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCkgOiBTdGFnZSAlI3gsIHBwVGV4dHVyZSAlcFxuIiwgVGhpcywgU3RhZ2UsIHBwVGV4dHVyZSk7CgogICAgaWYgKFN0YWdlID49IFdJTkVEM0RWRVJURVhURVhUVVJFU0FNUExFUjAgJiYgU3RhZ2UgPD0gV0lORUQzRFZFUlRFWFRFWFRVUkVTQU1QTEVSMykgewogICAgICAgIFN0YWdlIC09IChXSU5FRDNEVkVSVEVYVEVYVFVSRVNBTVBMRVIwIC0gTUFYX0ZSQUdNRU5UX1NBTVBMRVJTKTsKICAgIH0KCiAgICAqcHBUZXh0dXJlPVRoaXMtPnN0YXRlQmxvY2stPnRleHR1cmVzW1N0YWdlXTsKICAgIGlmICgqcHBUZXh0dXJlKQogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfQWRkUmVmKCpwcFRleHR1cmUpOwoKICAgIFRSQUNFKCIoJXApIDogUmV0dXJuaW5nICVwXG4iLCBUaGlzLCAqcHBUZXh0dXJlKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCBCYWNrIEJ1ZmZlcgogKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0QmFja0J1ZmZlcihJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgaVN3YXBDaGFpbiwgVUlOVCBCYWNrQnVmZmVyLCBXSU5FRDNEQkFDS0JVRkZFUl9UWVBFIFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSAqKnBwQmFja0J1ZmZlcikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBDaGFpbjsKICAgIEhSRVNVTFQgaHI7CgogICAgVFJBQ0UoIiglcCkgOiBCYWNrQnVmICVkIFR5cGUgJWQgU3dhcENoYWluICVkIHJldHVybmluZyAlcFxuIiwgVGhpcywgQmFja0J1ZmZlciwgVHlwZSwgaVN3YXBDaGFpbiwgKnBwQmFja0J1ZmZlcik7CgogICAgaHIgPSBJV2luZUQzRERldmljZUltcGxfR2V0U3dhcENoYWluKGlmYWNlLCAgaVN3YXBDaGFpbiwgJnN3YXBDaGFpbik7CiAgICBpZiAoaHIgPT0gV0lORUQzRF9PSykgewogICAgICAgIGhyID0gSVdpbmVEM0RTd2FwQ2hhaW5fR2V0QmFja0J1ZmZlcihzd2FwQ2hhaW4sIEJhY2tCdWZmZXIsIFR5cGUsIHBwQmFja0J1ZmZlcik7CiAgICAgICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2Uoc3dhcENoYWluKTsKICAgIH0gZWxzZSB7CiAgICAgICAgKnBwQmFja0J1ZmZlciA9IE5VTEw7CiAgICB9CiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0RGV2aWNlQ2FwcyhJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RDQVBTKiBwQ2FwcykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgV0FSTigiKCVwKSA6IHN0dWIsIGNhbGxpbmcgaWRpcmVjdDNkIGZvciBub3dcbiIsIFRoaXMpOwogICAgcmV0dXJuIElXaW5lRDNEX0dldERldmljZUNhcHMoVGhpcy0+d2luZUQzRCwgVGhpcy0+YWRhcHRlck5vLCBUaGlzLT5kZXZUeXBlLCBwQ2Fwcyk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0RGlzcGxheU1vZGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIGlTd2FwQ2hhaW4sIFdJTkVEM0RESVNQTEFZTU9ERSogcE1vZGUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3dhcENoYWluICpzd2FwQ2hhaW47CiAgICBIUkVTVUxUIGhyOwoKICAgIGlmKGlTd2FwQ2hhaW4gPiAwKSB7CiAgICAgICAgaHIgPSBJV2luZUQzRERldmljZUltcGxfR2V0U3dhcENoYWluKGlmYWNlLCAgaVN3YXBDaGFpbiwgKElXaW5lRDNEU3dhcENoYWluICoqKSZzd2FwQ2hhaW4pOwogICAgICAgIGlmIChociA9PSBXSU5FRDNEX09LKSB7CiAgICAgICAgICAgIGhyID0gSVdpbmVEM0RTd2FwQ2hhaW5fR2V0RGlzcGxheU1vZGUoc3dhcENoYWluLCBwTW9kZSk7CiAgICAgICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2Uoc3dhcENoYWluKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBGSVhNRSgiKCVwKSBFcnJvciBnZXR0aW5nIGRpc3BsYXkgbW9kZVxuIiwgVGhpcyk7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICAvKiBEb24ndCByZWFkIHRoZSByZWFsIGRpc3BsYXkgbW9kZSwKICAgICAgICAgICBidXQgcmV0dXJuIHRoZSBzdG9yZWQgbW9kZSBpbnN0ZWFkLiBYMTEgY2FuJ3QgY2hhbmdlIHRoZSBjb2xvcgogICAgICAgICAgIGRlcHRoLCBhbmQgc29tZSBhcHBzIGFyZSBwcmV0dHkgYW5ncnkgaWYgdGhleSBTZXREaXNwbGF5TW9kZSBmcm9tCiAgICAgICAgICAgMjQgdG8gMTYgYnBwIGFuZCBmaW5kIG91dCB0aGF0IEdldERpc3BsYXlNb2RlIHN0aWxsIHJldHVybnMgMjQgYnBwCgogICAgICAgICAgIEFsc28gZG9uJ3QgcmVsYXkgdG8gdGhlIHN3YXBjaGFpbiBiZWNhdXNlIHdpdGggZGRyYXcgaXQncyBwb3NzaWJsZQogICAgICAgICAgIHRoYXQgdGhlcmUgaXNuJ3QgYSBzd2FwY2hhaW4gYXQgYWxsICovCiAgICAgICAgcE1vZGUtPldpZHRoID0gVGhpcy0+ZGRyYXdfd2lkdGg7CiAgICAgICAgcE1vZGUtPkhlaWdodCA9IFRoaXMtPmRkcmF3X2hlaWdodDsKICAgICAgICBwTW9kZS0+Rm9ybWF0ID0gVGhpcy0+ZGRyYXdfZm9ybWF0OwogICAgICAgIHBNb2RlLT5SZWZyZXNoUmF0ZSA9IDA7CiAgICAgICAgaHIgPSBXSU5FRDNEX09LOwogICAgfQoKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRIV05EKElXaW5lRDNERGV2aWNlICppZmFjZSwgSFdORCBoV25kKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgaFduZCk7CgogICAgaWYoVGhpcy0+ZGRyYXdfZnVsbHNjcmVlbikgewogICAgICAgIGlmKFRoaXMtPmRkcmF3X3dpbmRvdyAmJiBUaGlzLT5kZHJhd193aW5kb3cgIT0gaFduZCkgewogICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfUmVzdG9yZVdpbmRvdyhpZmFjZSwgVGhpcy0+ZGRyYXdfd2luZG93KTsKICAgICAgICB9CiAgICAgICAgaWYoaFduZCAmJiBUaGlzLT5kZHJhd193aW5kb3cgIT0gaFduZCkgewogICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfU2V0dXBGdWxsc2NyZWVuV2luZG93KGlmYWNlLCBoV25kKTsKICAgICAgICB9CiAgICB9CgogICAgVGhpcy0+ZGRyYXdfd2luZG93ID0gaFduZDsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldEhXTkQoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBIV05EICpoV25kKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgaFduZCk7CgogICAgKmhXbmQgPSBUaGlzLT5kZHJhd193aW5kb3c7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIFN0YXRlYmxvY2sgcmVsYXRlZCBmdW5jdGlvbnMKICoqKioqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9CZWdpblN0YXRlQmxvY2soSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN0YXRlQmxvY2tJbXBsICpvYmplY3Q7CiAgICBIUkVTVUxUIHRlbXBfcmVzdWx0OwogICAgaW50IGk7CgogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwogICAgCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgCiAgICBvYmplY3QgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElXaW5lRDNEU3RhdGVCbG9ja0ltcGwpKTsKICAgIGlmIChOVUxMID09IG9iamVjdCApIHsKICAgICAgICBGSVhNRSgiKCVwKUVycm9yIGFsbG9jYXRpbmcgbWVtb3J5IGZvciBzdGF0ZWJsb2NrXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgIH0KICAgIFRSQUNFKCIoJXApIGNyZWF0ZWQgb2JqZWN0ICVwXG4iLCBUaGlzLCBvYmplY3QpOwogICAgb2JqZWN0LT53aW5lRDNERGV2aWNlPSBUaGlzOwogICAgLyoqIEZJWE1FOiBvYmplY3QtPnBhcmVudCAgICAgICA9IHBhcmVudDsgKiovCiAgICBvYmplY3QtPnBhcmVudCAgICAgICA9IE5VTEw7CiAgICBvYmplY3QtPmJsb2NrVHlwZSAgICA9IFdJTkVEM0RTQlRfUkVDT1JERUQ7CiAgICBvYmplY3QtPnJlZiAgICAgICAgICA9IDE7CiAgICBvYmplY3QtPmxwVnRibCAgICAgICA9ICZJV2luZUQzRFN0YXRlQmxvY2tfVnRibDsKCiAgICBmb3IoaSA9IDA7IGkgPCBMSUdIVE1BUF9TSVpFOyBpKyspIHsKICAgICAgICBsaXN0X2luaXQoJm9iamVjdC0+bGlnaHRNYXBbaV0pOwogICAgfQoKICAgIHRlbXBfcmVzdWx0ID0gYWxsb2NhdGVfc2hhZGVyX2NvbnN0YW50cyhvYmplY3QpOwogICAgaWYgKFdJTkVEM0RfT0sgIT0gdGVtcF9yZXN1bHQpCiAgICAgICAgcmV0dXJuIHRlbXBfcmVzdWx0OwoKICAgIElXaW5lRDNEU3RhdGVCbG9ja19SZWxlYXNlKChJV2luZUQzRFN0YXRlQmxvY2sqKVRoaXMtPnVwZGF0ZVN0YXRlQmxvY2spOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jayA9IG9iamVjdDsKICAgIFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUgPSBUUlVFOwoKICAgIFRSQUNFKCIoJXApIHJlY29yZGluZyBzdGF0ZWJsb2NrICVwXG4iLFRoaXMgLCBvYmplY3QpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfRW5kU3RhdGVCbG9jayhJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEU3RhdGVCbG9jayoqIHBwU3RhdGVCbG9jaykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgdW5zaWduZWQgaW50IGksIGo7CiAgICBJV2luZUQzRFN0YXRlQmxvY2tJbXBsICpvYmplY3QgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrOwoKICAgIGlmICghVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIEZJWE1FKCIoJXApIG5vdCByZWNvcmRpbmchIHJldHVybmluZyBlcnJvclxuIiwgVGhpcyk7CiAgICAgICAgKnBwU3RhdGVCbG9jayA9IE5VTEw7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgZm9yKGkgPSAxOyBpIDw9IFdJTkVISUdIRVNUX1JFTkRFUl9TVEFURTsgaSsrKSB7CiAgICAgICAgaWYob2JqZWN0LT5jaGFuZ2VkLnJlbmRlclN0YXRlW2ldKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3JlbmRlcl9zdGF0ZXNbb2JqZWN0LT5udW1fY29udGFpbmVkX3JlbmRlcl9zdGF0ZXNdID0gaTsKICAgICAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3JlbmRlcl9zdGF0ZXMrKzsKICAgICAgICB9CiAgICB9CiAgICBmb3IoaSA9IDE7IGkgPD0gSElHSEVTVF9UUkFOU0ZPUk1TVEFURTsgaSsrKSB7CiAgICAgICAgaWYob2JqZWN0LT5jaGFuZ2VkLnRyYW5zZm9ybVtpXSkgewogICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF90cmFuc2Zvcm1fc3RhdGVzW29iamVjdC0+bnVtX2NvbnRhaW5lZF90cmFuc2Zvcm1fc3RhdGVzXSA9IGk7CiAgICAgICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF90cmFuc2Zvcm1fc3RhdGVzKys7CiAgICAgICAgfQogICAgfQogICAgZm9yKGkgPSAwOyBpIDwgR0xfTElNSVRTKHZzaGFkZXJfY29uc3RhbnRzRik7IGkrKykgewogICAgICAgIGlmKG9iamVjdC0+Y2hhbmdlZC52ZXJ0ZXhTaGFkZXJDb25zdGFudHNGW2ldKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3ZzX2NvbnN0c19mW29iamVjdC0+bnVtX2NvbnRhaW5lZF92c19jb25zdHNfZl0gPSBpOwogICAgICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfdnNfY29uc3RzX2YrKzsKICAgICAgICB9CiAgICB9CiAgICBmb3IoaSA9IDA7IGkgPCBNQVhfQ09OU1RfSTsgaSsrKSB7CiAgICAgICAgaWYob2JqZWN0LT5jaGFuZ2VkLnZlcnRleFNoYWRlckNvbnN0YW50c0lbaV0pIHsKICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfdnNfY29uc3RzX2lbb2JqZWN0LT5udW1fY29udGFpbmVkX3ZzX2NvbnN0c19pXSA9IGk7CiAgICAgICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF92c19jb25zdHNfaSsrOwogICAgICAgIH0KICAgIH0KICAgIGZvcihpID0gMDsgaSA8IE1BWF9DT05TVF9COyBpKyspIHsKICAgICAgICBpZihvYmplY3QtPmNoYW5nZWQudmVydGV4U2hhZGVyQ29uc3RhbnRzQltpXSkgewogICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF92c19jb25zdHNfYltvYmplY3QtPm51bV9jb250YWluZWRfdnNfY29uc3RzX2JdID0gaTsKICAgICAgICAgICAgb2JqZWN0LT5udW1fY29udGFpbmVkX3ZzX2NvbnN0c19iKys7CiAgICAgICAgfQogICAgfQogICAgZm9yKGkgPSAwOyBpIDwgTUFYX0NPTlNUX0k7IGkrKykgewogICAgICAgIGlmKG9iamVjdC0+Y2hhbmdlZC5waXhlbFNoYWRlckNvbnN0YW50c0lbaV0pIHsKICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfcHNfY29uc3RzX2lbb2JqZWN0LT5udW1fY29udGFpbmVkX3BzX2NvbnN0c19pXSA9IGk7CiAgICAgICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF9wc19jb25zdHNfaSsrOwogICAgICAgIH0KICAgIH0KICAgIGZvcihpID0gMDsgaSA8IE1BWF9DT05TVF9COyBpKyspIHsKICAgICAgICBpZihvYmplY3QtPmNoYW5nZWQucGl4ZWxTaGFkZXJDb25zdGFudHNCW2ldKSB7CiAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3BzX2NvbnN0c19iW29iamVjdC0+bnVtX2NvbnRhaW5lZF9wc19jb25zdHNfYl0gPSBpOwogICAgICAgICAgICBvYmplY3QtPm51bV9jb250YWluZWRfcHNfY29uc3RzX2IrKzsKICAgICAgICB9CiAgICB9CiAgICBmb3IoaSA9IDA7IGkgPCBNQVhfVEVYVFVSRVM7IGkrKykgewogICAgICAgIGZvcihqID0gMTsgaiA8PSBXSU5FRDNEX0hJR0hFU1RfVEVYVFVSRV9TVEFURTsgaisrKSB7CiAgICAgICAgICAgIGlmKG9iamVjdC0+Y2hhbmdlZC50ZXh0dXJlU3RhdGVbaV1bal0pIHsKICAgICAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3Rzc19zdGF0ZXNbb2JqZWN0LT5udW1fY29udGFpbmVkX3Rzc19zdGF0ZXNdLnN0YWdlID0gaTsKICAgICAgICAgICAgICAgIG9iamVjdC0+Y29udGFpbmVkX3Rzc19zdGF0ZXNbb2JqZWN0LT5udW1fY29udGFpbmVkX3Rzc19zdGF0ZXNdLnN0YXRlID0gajsKICAgICAgICAgICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF90c3Nfc3RhdGVzKys7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBmb3IoaSA9IDA7IGkgPCBNQVhfQ09NQklORURfU0FNUExFUlM7IGkrKyl7CiAgICAgICAgZm9yIChqID0gMTsgaiA8IFdJTkVEM0RfSElHSEVTVF9TQU1QTEVSX1NUQVRFOyBqKyspIHsKICAgICAgICAgICAgaWYob2JqZWN0LT5jaGFuZ2VkLnNhbXBsZXJTdGF0ZVtpXVtqXSkgewogICAgICAgICAgICAgICAgb2JqZWN0LT5jb250YWluZWRfc2FtcGxlcl9zdGF0ZXNbb2JqZWN0LT5udW1fY29udGFpbmVkX3NhbXBsZXJfc3RhdGVzXS5zdGFnZSA9IGk7CiAgICAgICAgICAgICAgICBvYmplY3QtPmNvbnRhaW5lZF9zYW1wbGVyX3N0YXRlc1tvYmplY3QtPm51bV9jb250YWluZWRfc2FtcGxlcl9zdGF0ZXNdLnN0YXRlID0gajsKICAgICAgICAgICAgICAgIG9iamVjdC0+bnVtX2NvbnRhaW5lZF9zYW1wbGVyX3N0YXRlcysrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgICpwcFN0YXRlQmxvY2sgPSAoSVdpbmVEM0RTdGF0ZUJsb2NrKikgb2JqZWN0OwogICAgVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSA9IEZBTFNFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jayA9IFRoaXMtPnN0YXRlQmxvY2s7CiAgICBJV2luZUQzRFN0YXRlQmxvY2tfQWRkUmVmKChJV2luZUQzRFN0YXRlQmxvY2sqKVRoaXMtPnVwZGF0ZVN0YXRlQmxvY2spOwogICAgLyogSVdpbmVEM0RTdGF0ZUJsb2NrX0FkZFJlZigqcHBTdGF0ZUJsb2NrKTsgZG9uJ3QgbmVlZCB0byBkbyB0aGlzLCBzaW5jZSB3ZSBzaG91bGQgcmVhbGx5IGp1c3QgcmVsZWFzZSBVcGRhdGVTdGF0ZUJsb2NrIGZpcnN0ICovCiAgICBUUkFDRSgiKCVwKSByZXR1cm5pbmcgdG9rZW4gKHB0ciB0byBzdGF0ZWJsb2NrKSBvZiAlcFxuIiwgVGhpcywgKnBwU3RhdGVCbG9jayk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIFNjZW5lIHJlbGF0ZWQgZnVuY3Rpb25zCiAqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9CZWdpblNjZW5lKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgLyogQXQgdGhlIG1vbWVudCB3ZSBoYXZlIG5vIG5lZWQgZm9yIGFueSBmdW5jdGlvbmFsaXR5IGF0IHRoZSBiZWdpbm5pbmcKICAgICAgIG9mIGEgc2NlbmUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICBpZihUaGlzLT5pblNjZW5lKSB7CiAgICAgICAgVFJBQ0UoIkFscmVhZHkgaW4gU2NlbmUsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIFRoaXMtPmluU2NlbmUgPSBUUlVFOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfRW5kU2NlbmUoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgaWYoIVRoaXMtPmluU2NlbmUpIHsKICAgICAgICBUUkFDRSgiTm90IGluIHNjZW5lLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgQWN0aXZhdGVDb250ZXh0KFRoaXMsIFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQsIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CiAgICAvKiBXZSBvbmx5IGhhdmUgdG8gZG8gdGhpcyBpZiB3ZSBuZWVkIHRvIHJlYWQgdGhlLCBzd2FwYnVmZmVycyBwZXJmb3JtcyBhIGZsdXNoIGZvciB1cyAqLwogICAgRU5URVJfR0woKTsKICAgIGdsRmx1c2goKTsKICAgIGNoZWNrR0xjYWxsKCJnbEZsdXNoIik7CiAgICBMRUFWRV9HTCgpOwoKICAgIFRoaXMtPmluU2NlbmUgPSBGQUxTRTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1ByZXNlbnQoSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT05TVCBSRUNUKiBwU291cmNlUmVjdCwgQ09OU1QgUkVDVCogcERlc3RSZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIV05EIGhEZXN0V2luZG93T3ZlcnJpZGUsIENPTlNUIFJHTkRBVEEqIHBEaXJ0eVJlZ2lvbikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBDaGFpbiA9IE5VTEw7CiAgICBpbnQgaTsKICAgIGludCBzd2FwY2hhaW5zID0gSVdpbmVEM0REZXZpY2VJbXBsX0dldE51bWJlck9mU3dhcENoYWlucyhpZmFjZSk7CgogICAgVFJBQ0UoIiglcCkgUHJlc2VudGluZyB0aGUgZnJhbWVcbiIsIFRoaXMpOwoKICAgIGZvcihpID0gMCA7IGkgPCBzd2FwY2hhaW5zIDsgaSArKykgewoKICAgICAgICBJV2luZUQzRERldmljZUltcGxfR2V0U3dhcENoYWluKGlmYWNlLCBpICwgKElXaW5lRDNEU3dhcENoYWluICoqKSZzd2FwQ2hhaW4pOwogICAgICAgIFRSQUNFKCJwcmVzZW50aW5uZyBjaGFpbiAlZCwgJXBcbiIsIGksIHN3YXBDaGFpbik7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUHJlc2VudChzd2FwQ2hhaW4sIHBTb3VyY2VSZWN0LCBwRGVzdFJlY3QsIGhEZXN0V2luZG93T3ZlcnJpZGUsIHBEaXJ0eVJlZ2lvbiwgMCk7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwQ2hhaW4pOwogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKiBOb3QgY2FsbGVkIGZyb20gdGhlIFZUYWJsZSAoaW50ZXJuYWwgc3Vicm91dGluZSkgKi8KSFJFU1VMVCBJV2luZUQzRERldmljZUltcGxfQ2xlYXJTdXJmYWNlKElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcywgIElXaW5lRDNEU3VyZmFjZUltcGwgKnRhcmdldCwgRFdPUkQgQ291bnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDT05TVCBXSU5FRDNEUkVDVCogcFJlY3RzLCBEV09SRCBGbGFncywgV0lORUQzRENPTE9SIENvbG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmxvYXQgWiwgRFdPUkQgU3RlbmNpbCkgewogICAgR0xiaXRmaWVsZCAgICAgZ2xNYXNrID0gMDsKICAgIHVuc2lnbmVkIGludCAgIGk7CiAgICBXSU5FRDNEUkVDVCBjdXJSZWN0OwogICAgUkVDVCB2cF9yZWN0OwogICAgV0lORUQzRFZJRVdQT1JUICp2cCA9ICZUaGlzLT5zdGF0ZUJsb2NrLT52aWV3cG9ydDsKICAgIFVJTlQgZHJhd2FibGVfd2lkdGgsIGRyYXdhYmxlX2hlaWdodDsKCiAgICAvKiBXaGVuIHdlJ3JlIGNsZWFyaW5nIHBhcnRzIG9mIHRoZSBkcmF3YWJsZSwgbWFrZSBzdXJlIHRoYXQgdGhlIHRhcmdldCBzdXJmYWNlIGlzIHdlbGwgdXAgdG8gZGF0ZSBpbiB0aGUKICAgICAqIGRyYXdhYmxlLiBBZnRlciB0aGUgY2xlYXIgd2UnbGwgbWFyayB0aGUgZHJhd2FibGUgdXAgdG8gZGF0ZSwgc28gd2UgaGF2ZSB0byBtYWtlIHN1cmUgdGhhdCB0aGlzIGlzIHRydWUKICAgICAqIGZvciB0aGUgY2xlYXJlZCBwYXJ0cywgYW5kIHRoZSB1bnRvdWNoZWQgcGFydHMuCiAgICAgKgogICAgICogSWYgd2UncmUgY2xlYXJpbmcgdGhlIHdob2xlIHRhcmdldCB0aGVyZSBpcyBubyBuZWVkIHRvIGNvcHkgaXQgaW50byB0aGUgZHJhd2FibGUsIGl0IHdpbGwgYmUgb3ZlcndyaXR0ZW4KICAgICAqIGFueXdheS4gSWYgd2UncmUgbm90IGNsZWFyaW5nIHRoZSBjb2xvciBidWZmZXIgd2UgZG9uJ3QgaGF2ZSB0byBjb3B5IGVpdGhlciBzaW5jZSB3ZSdyZSBub3QgZ29pbmcgdG8gc2V0CiAgICAgKiB0aGUgZHJhd2FibGUgdXAgdG8gZGF0ZS4gV2UgaGF2ZSB0byBjaGVjayBhbGwgc2V0dGluZ3MgdGhhdCBsaW1pdCB0aGUgY2xlYXIgYXJlYSB0aG91Z2guIERvIG5vdCBib3RoZXIKICAgICAqIGNoZWNraW5nIGFsbCB0aGlzIGlmIHRoZSBkZXN0IHN1cmZhY2UgaXMgaW4gdGhlIGRyYXdhYmxlIGFueXdheS4KICAgICAqLwogICAgaWYoKEZsYWdzICYgV0lORUQzRENMRUFSX1RBUkdFVCkgJiYgISh0YXJnZXQtPkZsYWdzICYgU0ZMQUdfSU5EUkFXQUJMRSkpIHsKICAgICAgICB3aGlsZSgxKSB7CiAgICAgICAgICAgIGlmKHZwLT5YICE9IDAgfHwgdnAtPlkgIT0gMCB8fAogICAgICAgICAgICAgICB2cC0+V2lkdGggPCB0YXJnZXQtPmN1cnJlbnREZXNjLldpZHRoIHx8IHZwLT5IZWlnaHQgPCB0YXJnZXQtPmN1cnJlbnREZXNjLkhlaWdodCkgewogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0xvYWRMb2NhdGlvbigoSVdpbmVEM0RTdXJmYWNlICopIHRhcmdldCwgU0ZMQUdfSU5EUkFXQUJMRSwgTlVMTCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZihUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfU0NJU1NPUlRFU1RFTkFCTEVdICYmICgKICAgICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+c2Npc3NvclJlY3QubGVmdCA+IDAgfHwgVGhpcy0+c3RhdGVCbG9jay0+c2Npc3NvclJlY3QudG9wID4gMCB8fAogICAgICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zY2lzc29yUmVjdC5yaWdodCA8IHRhcmdldC0+Y3VycmVudERlc2MuV2lkdGggfHwKICAgICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+c2Npc3NvclJlY3QuYm90dG9tIDwgdGFyZ2V0LT5jdXJyZW50RGVzYy5IZWlnaHQpKSB7CiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfTG9hZExvY2F0aW9uKChJV2luZUQzRFN1cmZhY2UgKikgdGFyZ2V0LCBTRkxBR19JTkRSQVdBQkxFLCBOVUxMKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKENvdW50ID4gMCAmJiBwUmVjdHMgJiYgKAogICAgICAgICAgICAgICBwUmVjdHNbMF0ueDEgPiAwIHx8IHBSZWN0c1swXS55MSA+IDAgfHwKICAgICAgICAgICAgICAgcFJlY3RzWzBdLngyIDwgdGFyZ2V0LT5jdXJyZW50RGVzYy5XaWR0aCB8fAogICAgICAgICAgICAgICBwUmVjdHNbMF0ueTIgPCB0YXJnZXQtPmN1cnJlbnREZXNjLkhlaWdodCkpIHsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9Mb2FkTG9jYXRpb24oKElXaW5lRDNEU3VyZmFjZSAqKSB0YXJnZXQsIFNGTEFHX0lORFJBV0FCTEUsIE5VTEwpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIHRhcmdldC0+Z2V0X2RyYXdhYmxlX3NpemUodGFyZ2V0LCAmZHJhd2FibGVfd2lkdGgsICZkcmF3YWJsZV9oZWlnaHQpOwoKICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCAoSVdpbmVEM0RTdXJmYWNlICopIHRhcmdldCwgQ1RYVVNBR0VfQ0xFQVIpOwogICAgRU5URVJfR0woKTsKCiAgICBpZiAod2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUgPT0gT1JNX0ZCTykgewogICAgICAgIGFwcGx5X2Zib19zdGF0ZSgoSVdpbmVEM0REZXZpY2UgKikgVGhpcyk7CiAgICB9CgogICAgLyogT25seSBzZXQgdGhlIHZhbHVlcyB1cCBvbmNlLCBhcyB0aGV5IGFyZSBub3QgY2hhbmdpbmcgKi8KICAgIGlmIChGbGFncyAmIFdJTkVEM0RDTEVBUl9TVEVOQ0lMKSB7CiAgICAgICAgZ2xDbGVhclN0ZW5jaWwoU3RlbmNpbCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQ2xlYXJTdGVuY2lsIik7CiAgICAgICAgZ2xNYXNrID0gZ2xNYXNrIHwgR0xfU1RFTkNJTF9CVUZGRVJfQklUOwogICAgICAgIGdsU3RlbmNpbE1hc2soMHhGRkZGRkZGRik7CiAgICB9CgogICAgaWYgKEZsYWdzICYgV0lORUQzRENMRUFSX1pCVUZGRVIpIHsKICAgICAgICBnbERlcHRoTWFzayhHTF9UUlVFKTsKICAgICAgICBnbENsZWFyRGVwdGgoWik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQ2xlYXJEZXB0aCIpOwogICAgICAgIGdsTWFzayA9IGdsTWFzayB8IEdMX0RFUFRIX0JVRkZFUl9CSVQ7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1JFTkRFUihXSU5FRDNEUlNfWldSSVRFRU5BQkxFKSk7CiAgICB9CgogICAgaWYgKEZsYWdzICYgV0lORUQzRENMRUFSX1RBUkdFVCkgewogICAgICAgIFRSQUNFKCJDbGVhcmluZyBzY3JlZW4gd2l0aCBnbENsZWFyIHRvIGNvbG9yICV4XG4iLCBDb2xvcik7CiAgICAgICAgZ2xDbGVhckNvbG9yKEQzRENPTE9SX1IoQ29sb3IpLAogICAgICAgICAgICAgICAgICAgICBEM0RDT0xPUl9HKENvbG9yKSwKICAgICAgICAgICAgICAgICAgICAgRDNEQ09MT1JfQihDb2xvciksCiAgICAgICAgICAgICAgICAgICAgIEQzRENPTE9SX0EoQ29sb3IpKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xDbGVhckNvbG9yIik7CgogICAgICAgIC8qIENsZWFyIEFMTCBjb2xvcnMhICovCiAgICAgICAgZ2xDb2xvck1hc2soR0xfVFJVRSwgR0xfVFJVRSwgR0xfVFJVRSwgR0xfVFJVRSk7CiAgICAgICAgZ2xNYXNrID0gZ2xNYXNrIHwgR0xfQ09MT1JfQlVGRkVSX0JJVDsKICAgIH0KCiAgICB2cF9yZWN0LmxlZnQgPSB2cC0+WDsKICAgIHZwX3JlY3QudG9wID0gdnAtPlk7CiAgICB2cF9yZWN0LnJpZ2h0ID0gdnAtPlggKyB2cC0+V2lkdGg7CiAgICB2cF9yZWN0LmJvdHRvbSA9IHZwLT5ZICsgdnAtPkhlaWdodDsKICAgIGlmICghKENvdW50ID4gMCAmJiBwUmVjdHMpKSB7CiAgICAgICAgaWYoVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbV0lORUQzRFJTX1NDSVNTT1JURVNURU5BQkxFXSkgewogICAgICAgICAgICBJbnRlcnNlY3RSZWN0KCZ2cF9yZWN0LCAmdnBfcmVjdCwgJlRoaXMtPnN0YXRlQmxvY2stPnNjaXNzb3JSZWN0KTsKICAgICAgICB9CiAgICAgICAgaWYoVGhpcy0+cmVuZGVyX29mZnNjcmVlbikgewogICAgICAgICAgICBnbFNjaXNzb3IodnBfcmVjdC5sZWZ0LCB2cF9yZWN0LnRvcCwKICAgICAgICAgICAgICAgICAgICAgICAgdnBfcmVjdC5yaWdodCAtIHZwX3JlY3QubGVmdCwgdnBfcmVjdC5ib3R0b20gLSB2cF9yZWN0LnRvcCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZ2xTY2lzc29yKHZwX3JlY3QubGVmdCwgZHJhd2FibGVfaGVpZ2h0IC0gdnBfcmVjdC5ib3R0b20sCiAgICAgICAgICAgICAgICAgICAgICAgIHZwX3JlY3QucmlnaHQgLSB2cF9yZWN0LmxlZnQsIHZwX3JlY3QuYm90dG9tIC0gdnBfcmVjdC50b3ApOwogICAgICAgIH0KICAgICAgICBjaGVja0dMY2FsbCgiZ2xTY2lzc29yIik7CiAgICAgICAgZ2xDbGVhcihnbE1hc2spOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbENsZWFyIik7CiAgICB9IGVsc2UgewogICAgICAgIC8qIE5vdyBwcm9jZXNzIGVhY2ggcmVjdCBpbiB0dXJuICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IENvdW50OyBpKyspIHsKICAgICAgICAgICAgLyogTm90ZSBnbCB1c2VzIGxvd2VyIGxlZnQsIHdpZHRoL2hlaWdodCAqLwogICAgICAgICAgICBJbnRlcnNlY3RSZWN0KChSRUNUICopICZjdXJSZWN0LCAmdnBfcmVjdCwgKFJFQ1QgKikgJnBSZWN0c1tpXSk7CiAgICAgICAgICAgIGlmKFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19TQ0lTU09SVEVTVEVOQUJMRV0pIHsKICAgICAgICAgICAgICAgIEludGVyc2VjdFJlY3QoKFJFQ1QgKikgJmN1clJlY3QsIChSRUNUICopICZjdXJSZWN0LCAmVGhpcy0+c3RhdGVCbG9jay0+c2Npc3NvclJlY3QpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFRSQUNFKCIoJXApIFJlY3Q9KCVkLCVkKS0+KCVkLCVkKSBnbFJlY3Q9KCVkLCVkKSwgbGVuPSVkLCBoZWk9JWRcbiIsIFRoaXMsCiAgICAgICAgICAgICAgICAgIHBSZWN0c1tpXS54MSwgcFJlY3RzW2ldLnkxLCBwUmVjdHNbaV0ueDIsIHBSZWN0c1tpXS55MiwKICAgICAgICAgICAgICAgICAgY3VyUmVjdC54MSwgKHRhcmdldC0+Y3VycmVudERlc2MuSGVpZ2h0IC0gY3VyUmVjdC55MiksCiAgICAgICAgICAgICAgICAgIGN1clJlY3QueDIgLSBjdXJSZWN0LngxLCBjdXJSZWN0LnkyIC0gY3VyUmVjdC55MSk7CgogICAgICAgICAgICAvKiBUZXN0cyBzaG93IHRoYXQgcmVjdGFuZ2xlcyB3aGVyZSB4MSA+IHgyIG9yIHkxID4geTIgYXJlIGlnbm9yZWQgc2lsZW50bHkuCiAgICAgICAgICAgICAqIFRoZSByZWN0YW5nbGUgaXMgbm90IGNsZWFyZWQsIG5vIGVycm9yIGlzIHJldHVybmVkLCBidXQgZnVydGhlciByZWN0YW5sZ2VzIGFyZQogICAgICAgICAgICAgKiBzdGlsbCBjbGVhcmVkIGlmIHRoZXkgYXJlIHZhbGlkCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZihjdXJSZWN0LngxID4gY3VyUmVjdC54MiB8fCBjdXJSZWN0LnkxID4gY3VyUmVjdC55MikgewogICAgICAgICAgICAgICAgVFJBQ0UoIlJlY3RhbmdsZSB3aXRoIG5lZ2F0aXZlIGRpbWVuc2lvbnMsIGlnbm9yaW5nXG4iKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZihUaGlzLT5yZW5kZXJfb2Zmc2NyZWVuKSB7CiAgICAgICAgICAgICAgICBnbFNjaXNzb3IoY3VyUmVjdC54MSwgY3VyUmVjdC55MSwKICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJSZWN0LngyIC0gY3VyUmVjdC54MSwgY3VyUmVjdC55MiAtIGN1clJlY3QueTEpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZ2xTY2lzc29yKGN1clJlY3QueDEsIGRyYXdhYmxlX2hlaWdodCAtIGN1clJlY3QueTIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY3VyUmVjdC54MiAtIGN1clJlY3QueDEsIGN1clJlY3QueTIgLSBjdXJSZWN0LnkxKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xTY2lzc29yIik7CgogICAgICAgICAgICBnbENsZWFyKGdsTWFzayk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbENsZWFyIik7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFJlc3RvcmUgdGhlIG9sZCB2YWx1ZXMgKHdoeS4uPykgKi8KICAgIGlmIChGbGFncyAmIFdJTkVEM0RDTEVBUl9TVEVOQ0lMKSB7CiAgICAgICAgZ2xTdGVuY2lsTWFzayhUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfU1RFTkNJTFdSSVRFTUFTS10pOwogICAgfQogICAgaWYgKEZsYWdzICYgV0lORUQzRENMRUFSX1RBUkdFVCkgewogICAgICAgIERXT1JEIG1hc2sgPSBUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfQ09MT1JXUklURUVOQUJMRV07CiAgICAgICAgZ2xDb2xvck1hc2sobWFzayAmIFdJTkVEM0RDT0xPUldSSVRFRU5BQkxFX1JFRCA/IEdMX1RSVUUgOiBHTF9GQUxTRSwKICAgICAgICAgICAgICAgICAgICBtYXNrICYgV0lORUQzRENPTE9SV1JJVEVFTkFCTEVfR1JFRU4gPyBHTF9UUlVFIDogR0xfRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgbWFzayAmIFdJTkVEM0RDT0xPUldSSVRFRU5BQkxFX0JMVUUgID8gR0xfVFJVRSA6IEdMX0ZBTFNFLAogICAgICAgICAgICAgICAgICAgIG1hc2sgJiBXSU5FRDNEQ09MT1JXUklURUVOQUJMRV9BTFBIQSA/IEdMX1RSVUUgOiBHTF9GQUxTRSk7CgogICAgICAgIC8qIERpcnRpZnkgdGhlIHRhcmdldCBzdXJmYWNlIGZvciBub3cuIElmIHRoZSBzdXJmYWNlIGlzIGxvY2tlZCByZWd1bGFybHksIGFuZCBhbiB1cCB0byBkYXRlIHN5c21lbSBjb3B5IGV4aXN0cywKICAgICAgICAgKiBpdCBpcyBtb3N0IGxpa2VseSBtb3JlIGVmZmljaWVudCB0byBwZXJmb3JtIGEgY2xlYXIgb24gdGhlIHN5c21lbSBjb3B5IHRvbyBpbnN0ZWFkIG9mIGRvd25sb2FkaW5nIGl0CiAgICAgICAgICovCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX01vZGlmeUxvY2F0aW9uKFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQsIFNGTEFHX0lORFJBV0FCTEUsIFRSVUUpOwogICAgICAgIC8qIFRPRE86IE1vdmUgdGhlIGZibyBsb2dpYyBpbnRvIE1vZGlmeUxvY2F0aW9uKCkgKi8KICAgICAgICBpZihUaGlzLT5yZW5kZXJfb2Zmc2NyZWVuICYmIHdpbmVkM2Rfc2V0dGluZ3Mub2Zmc2NyZWVuX3JlbmRlcmluZ19tb2RlID09IE9STV9GQk8pIHsKICAgICAgICAgICAgdGFyZ2V0LT5GbGFncyB8PSBTRkxBR19JTlRFWFRVUkU7CiAgICAgICAgfQogICAgfQogICAgTEVBVkVfR0woKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DbGVhcihJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIENvdW50LCBDT05TVCBXSU5FRDNEUkVDVCogcFJlY3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsIFdJTkVEM0RDT0xPUiBDb2xvciwgZmxvYXQgWiwgRFdPUkQgU3RlbmNpbCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqdGFyZ2V0ID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXTsKCiAgICBUUkFDRSgiKCVwKSBDb3VudCAoJWQpLCBwUmVjdHMgKCVwKSwgRmxhZ3MgKCV4KSwgQ29sb3IgKDB4JTA4eCksIFogKCVmKSwgU3RlbmNpbCAoJWQpXG4iLCBUaGlzLAogICAgICAgICAgQ291bnQsIHBSZWN0cywgRmxhZ3MsIENvbG9yLCBaLCBTdGVuY2lsKTsKCiAgICBpZihGbGFncyAmIChXSU5FRDNEQ0xFQVJfWkJVRkZFUiB8IFdJTkVEM0RDTEVBUl9TVEVOQ0lMKSAmJiBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0ID09IE5VTEwpIHsKICAgICAgICBXQVJOKCJDbGVhcmluZyBkZXB0aCBhbmQvb3Igc3RlbmNpbCB3aXRob3V0IGEgZGVwdGggc3RlbmNpbCBidWZmZXIgYXR0YWNoZWQsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICAvKiBUT0RPOiBXaGF0IGFib3V0IGRlcHRoIHN0ZW5jaWwgYnVmZmVycyB3aXRob3V0IHN0ZW5jaWwgYml0cz8gKi8KICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICByZXR1cm4gSVdpbmVEM0REZXZpY2VJbXBsX0NsZWFyU3VyZmFjZShUaGlzLCB0YXJnZXQsIENvdW50LCBwUmVjdHMsIEZsYWdzLCBDb2xvciwgWiwgU3RlbmNpbCk7Cn0KCi8qKioqKgogKiBEcmF3aW5nIGZ1bmN0aW9ucwogKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfRHJhd1ByaW1pdGl2ZShJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsIFVJTlQgU3RhcnRWZXJ0ZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgUHJpbWl0aXZlQ291bnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCkgOiBUeXBlPSglZCwlcyksIFN0YXJ0PSVkLCBDb3VudD0lZFxuIiwgVGhpcywgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlYnVnX2QzZHByaW1pdGl2ZXR5cGUoUHJpbWl0aXZlVHlwZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFydFZlcnRleCwgUHJpbWl0aXZlQ291bnQpOwoKICAgIC8qIFRoZSBpbmRleCBidWZmZXIgaXMgbm90IG5lZWRlZCBoZXJlLCBidXQgcmVzdG9yZSBpdCwgb3RoZXJ3aXNlIGl0IGlzIGhlbGwgdG8ga2VlcCB0cmFjayBvZiAqLwogICAgaWYoVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtSXNVUCkgewogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9JTkRFWEJVRkZFUik7CiAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtSXNVUCA9IEZBTFNFOwogICAgfQoKICAgIGlmKFRoaXMtPnN0YXRlQmxvY2stPmxvYWRCYXNlVmVydGV4SW5kZXggIT0gMCkgewogICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPmxvYWRCYXNlVmVydGV4SW5kZXggPSAwOwogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TVFJFQU1TUkMpOwogICAgfQogICAgLyogQWNjb3VudCBmb3IgdGhlIGxvYWRpbmcgb2Zmc2V0IGR1ZSB0byBpbmRleCBidWZmZXJzLiBJbnN0ZWFkIG9mIHJlbG9hZGluZyBhbGwgc291cmNlcyBjb3JyZWN0IGl0IHdpdGggdGhlIHN0YXJ0dmVydGV4IHBhcmFtZXRlciAqLwogICAgZHJhd1ByaW1pdGl2ZShpZmFjZSwgUHJpbWl0aXZlVHlwZSwgUHJpbWl0aXZlQ291bnQsIFN0YXJ0VmVydGV4LCAwLyogTnVtVmVydGljZXMgKi8sIC0xIC8qIGluZHhTdGFydCAqLywKICAgICAgICAgICAgICAgICAgMCAvKiBpbmR4U2l6ZSAqLywgTlVMTCAvKiBpbmR4RGF0YSAqLywgMCAvKiBtaW5JbmRleCAqLyk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyogVE9ETzogYmFzZVZJbmRleCBuZWVkcyB0byBiZSBwcm92aWRlZCBmcm9tIFRoaXMtPnN0YXRlQmxvY2stPmJhc2VWZXJ0ZXhJbmRleCB3aGVuIGNhbGxlZCBmcm9tIGQzZDggKi8Kc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdJbmRleGVkUHJpbWl0aXZlKElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgbWluSW5kZXgsIFVJTlQgTnVtVmVydGljZXMsIFVJTlQgc3RhcnRJbmRleCwgVUlOVCBwcmltQ291bnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVUlOVCAgICAgICAgICAgICAgICAgaWR4U3RyaWRlID0gMjsKICAgIElXaW5lRDNESW5kZXhCdWZmZXIgKnBJQjsKICAgIFdJTkVEM0RJTkRFWEJVRkZFUl9ERVNDICBJZHhCdWZEc2M7CiAgICBHTHVpbnQgdmJvOwoKICAgIHBJQiA9IFRoaXMtPnN0YXRlQmxvY2stPnBJbmRleERhdGE7CiAgICBpZiAoIXBJQikgewogICAgICAgIC8qIEQzRDkgcmV0dXJucyBEM0RFUlJfSU5WQUxJRENBTEwgd2hlbiBEcmF3SW5kZXhlZFByaW1pdGl2ZSBpcyBjYWxsZWQKICAgICAgICAgKiB3aXRob3V0IGFuIGluZGV4IGJ1ZmZlciBzZXQuIChUaGUgZmlyc3QgdGltZSBhdCBsZWFzdC4uLikKICAgICAgICAgKiBEM0Q4IHNpbXBseSBkaWVzLCBidXQgSSBkb3VidCBpdCBjYW4gZG8gbXVjaCBoYXJtIHRvIHJldHVybgogICAgICAgICAqIEQzREVSUl9JTlZBTElEQ0FMTCB0aGVyZSBhcyB3ZWxsLiAqLwogICAgICAgIEVSUigiKCVwKSA6IENhbGxlZCB3aXRob3V0IGEgdmFsaWQgaW5kZXggYnVmZmVyIHNldCwgcmV0dXJuaW5nIFdJTkVEM0RFUlJfSU5WQUxJRENBTExcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmKFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbUlzVVApIHsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfSU5ERVhCVUZGRVIpOwogICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbUlzVVAgPSBGQUxTRTsKICAgIH0KICAgIHZibyA9ICgoSVdpbmVEM0RJbmRleEJ1ZmZlckltcGwgKikgcElCKS0+dmJvOwoKICAgIFRSQUNFKCIoJXApIDogVHlwZT0oJWQsJXMpLCBtaW49JWQsIENvdW50Vj0lZCwgc3RhcnRJZHg9JWQsIGNvdW50UD0lZFxuIiwgVGhpcywKICAgICAgICAgIFByaW1pdGl2ZVR5cGUsIGRlYnVnX2QzZHByaW1pdGl2ZXR5cGUoUHJpbWl0aXZlVHlwZSksCiAgICAgICAgICBtaW5JbmRleCwgTnVtVmVydGljZXMsIHN0YXJ0SW5kZXgsIHByaW1Db3VudCk7CgogICAgSVdpbmVEM0RJbmRleEJ1ZmZlcl9HZXREZXNjKHBJQiwgJklkeEJ1ZkRzYyk7CiAgICBpZiAoSWR4QnVmRHNjLkZvcm1hdCA9PSBXSU5FRDNERk1UX0lOREVYMTYpIHsKICAgICAgICBpZHhTdHJpZGUgPSAyOwogICAgfSBlbHNlIHsKICAgICAgICBpZHhTdHJpZGUgPSA0OwogICAgfQoKICAgIGlmKFRoaXMtPnN0YXRlQmxvY2stPmxvYWRCYXNlVmVydGV4SW5kZXggIT0gVGhpcy0+c3RhdGVCbG9jay0+YmFzZVZlcnRleEluZGV4KSB7CiAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+bG9hZEJhc2VWZXJ0ZXhJbmRleCA9IFRoaXMtPnN0YXRlQmxvY2stPmJhc2VWZXJ0ZXhJbmRleDsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfU1RSRUFNU1JDKTsKICAgIH0KCiAgICBkcmF3UHJpbWl0aXZlKGlmYWNlLCBQcmltaXRpdmVUeXBlLCBwcmltQ291bnQsIDAsIE51bVZlcnRpY2VzLCBzdGFydEluZGV4LAogICAgICAgICAgICAgICAgICAgaWR4U3RyaWRlLCB2Ym8gPyBOVUxMIDogKChJV2luZUQzREluZGV4QnVmZmVySW1wbCAqKSBwSUIpLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnksIG1pbkluZGV4KTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3UHJpbWl0aXZlVVAoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBQcmltaXRpdmVDb3VudCwgQ09OU1Qgdm9pZCogcFZlcnRleFN0cmVhbVplcm9EYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBWZXJ0ZXhTdHJlYW1aZXJvU3RyaWRlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFZlcnRleEJ1ZmZlciAqdmI7CgogICAgVFJBQ0UoIiglcCkgOiBUeXBlPSglZCwlcyksIHBDb3VudD0lZCwgcFZ0eERhdGE9JXAsIFN0cmlkZT0lZFxuIiwgVGhpcywgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgIGRlYnVnX2QzZHByaW1pdGl2ZXR5cGUoUHJpbWl0aXZlVHlwZSksCiAgICAgICAgICAgICBQcmltaXRpdmVDb3VudCwgcFZlcnRleFN0cmVhbVplcm9EYXRhLCBWZXJ0ZXhTdHJlYW1aZXJvU3RyaWRlKTsKCiAgICAvKiBOb3RlIGluIHRoZSBmb2xsb3dpbmcsIGl0J3Mgbm90IHRoaXMgdHlwZSwgYnV0IHRoYXQncyB0aGUgcHVycG9zZSBvZiBzdHJlYW1Jc1VQICovCiAgICB2YiA9IFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVswXTsKICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVswXSA9IChJV2luZUQzRFZlcnRleEJ1ZmZlciAqKXBWZXJ0ZXhTdHJlYW1aZXJvRGF0YTsKICAgIGlmKHZiKSBJV2luZUQzRFZlcnRleEJ1ZmZlcl9SZWxlYXNlKHZiKTsKICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbU9mZnNldFswXSA9IDA7CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1TdHJpZGVbMF0gPSBWZXJ0ZXhTdHJlYW1aZXJvU3RyaWRlOwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtSXNVUCA9IFRSVUU7CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5sb2FkQmFzZVZlcnRleEluZGV4ID0gMDsKCiAgICAvKiBUT0RPOiBPbmx5IG1hcmsgZGlydHkgaWYgZHJhd2luZyBmcm9tIGEgZGlmZmVyZW50IFVQIGFkZHJlc3MgKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TVFJFQU1TUkMpOwoKICAgIGRyYXdQcmltaXRpdmUoaWZhY2UsIFByaW1pdGl2ZVR5cGUsIFByaW1pdGl2ZUNvdW50LCAwIC8qIHN0YXJ0IHZlcnRleCAqLywgMCAgLyogTnVtVmVydGljZXMgKi8sCiAgICAgICAgICAgICAgICAgIDAgLyogaW5keFN0YXJ0Ki8sIDAgLyogaW5keFNpemUqLywgTlVMTCAvKiBpbmR4RGF0YSAqLywgMCAvKiBpbmR4TWluICovKTsKCiAgICAvKiBNU0ROIHNwZWNpZmllcyBzdHJlYW0gemVybyBzZXR0aW5ncyBtdXN0IGJlIHNldCB0byBOVUxMICovCiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1TdHJpZGVbMF0gPSAwOwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlWzBdID0gTlVMTDsKCiAgICAvKiBzdHJlYW0gemVybyBzZXR0aW5ncyBzZXQgdG8gbnVsbCBhdCBlbmQsIGFzIHBlciB0aGUgbXNkbi4gTm8gbmVlZCB0byBtYXJrIGRpcnR5IGhlcmUsIHRoZSBhcHAgaGFzIHRvIHNldAogICAgICogdGhlIG5ldyBzdHJlYW0gc291cmNlcyBvciB1c2UgVVAgZHJhd2luZyBhZ2FpbgogICAgICovCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3SW5kZXhlZFByaW1pdGl2ZVVQKElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRFBSSU1JVElWRVRZUEUgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgTWluVmVydGV4SW5kZXgsIFVJTlQgTnVtVmVydGljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFByaW1pdGl2ZUNvdW50LCBDT05TVCB2b2lkKiBwSW5kZXhEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzREZPUk1BVCBJbmRleERhdGFGb3JtYXQsQ09OU1Qgdm9pZCogcFZlcnRleFN0cmVhbVplcm9EYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBWZXJ0ZXhTdHJlYW1aZXJvU3RyaWRlKSB7CiAgICBpbnQgICAgICAgICAgICAgICAgIGlkeFN0cmlkZTsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEVmVydGV4QnVmZmVyICp2YjsKICAgIElXaW5lRDNESW5kZXhCdWZmZXIgKmliOwoKICAgIFRSQUNFKCIoJXApIDogVHlwZT0oJWQsJXMpLCBNaW5WdHhJZHg9JWQsIE51bVZJZHg9JWQsIFBDb3VudD0lZCwgcGlkeGRhdGE9JXAsIElkeEZtdD0lZCwgcFZ0eGRhdGE9JXAsIHN0cmlkZT0lZFxuIiwKICAgICAgICAgICAgIFRoaXMsIFByaW1pdGl2ZVR5cGUsIGRlYnVnX2QzZHByaW1pdGl2ZXR5cGUoUHJpbWl0aXZlVHlwZSksCiAgICAgICAgICAgICBNaW5WZXJ0ZXhJbmRleCwgTnVtVmVydGljZXMsIFByaW1pdGl2ZUNvdW50LCBwSW5kZXhEYXRhLAogICAgICAgICAgICAgSW5kZXhEYXRhRm9ybWF0LCBwVmVydGV4U3RyZWFtWmVyb0RhdGEsIFZlcnRleFN0cmVhbVplcm9TdHJpZGUpOwoKICAgIGlmIChJbmRleERhdGFGb3JtYXQgPT0gV0lORUQzREZNVF9JTkRFWDE2KSB7CiAgICAgICAgaWR4U3RyaWRlID0gMjsKICAgIH0gZWxzZSB7CiAgICAgICAgaWR4U3RyaWRlID0gNDsKICAgIH0KCiAgICAvKiBOb3RlIGluIHRoZSBmb2xsb3dpbmcsIGl0J3Mgbm90IHRoaXMgdHlwZSwgYnV0IHRoYXQncyB0aGUgcHVycG9zZSBvZiBzdHJlYW1Jc1VQICovCiAgICB2YiA9IFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVswXTsKICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVswXSA9IChJV2luZUQzRFZlcnRleEJ1ZmZlciAqKXBWZXJ0ZXhTdHJlYW1aZXJvRGF0YTsKICAgIGlmKHZiKSBJV2luZUQzRFZlcnRleEJ1ZmZlcl9SZWxlYXNlKHZiKTsKICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbUlzVVAgPSBUUlVFOwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtT2Zmc2V0WzBdID0gMDsKICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVN0cmlkZVswXSA9IFZlcnRleFN0cmVhbVplcm9TdHJpZGU7CgogICAgLyogU2V0IHRvIDAgYXMgcGVyIG1zZG4uIERvIGl0IG5vdyBkdWUgdG8gdGhlIHN0cmVhbSBzb3VyY2UgbG9hZGluZyBkdXJpbmcgZHJhd1ByaW1pdGl2ZSAqLwogICAgVGhpcy0+c3RhdGVCbG9jay0+YmFzZVZlcnRleEluZGV4ID0gMDsKICAgIFRoaXMtPnN0YXRlQmxvY2stPmxvYWRCYXNlVmVydGV4SW5kZXggPSAwOwogICAgLyogTWFyayB0aGUgc3RhdGUgZGlydHkgdW50aWwgd2UgaGF2ZSBuaWNlciB0cmFja2luZyBvZiB0aGUgc3RyZWFtIHNvdXJjZSBwb2ludGVycyAqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1ZERUNMKTsKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9JTkRFWEJVRkZFUik7CgogICAgZHJhd1ByaW1pdGl2ZShpZmFjZSwgUHJpbWl0aXZlVHlwZSwgUHJpbWl0aXZlQ291bnQsIDAgLyogdmVydGV4U3RhcnQgKi8sIE51bVZlcnRpY2VzLCAwIC8qIGluZHhTdGFydCAqLywgaWR4U3RyaWRlLCBwSW5kZXhEYXRhLCBNaW5WZXJ0ZXhJbmRleCk7CgogICAgLyogTVNETiBzcGVjaWZpZXMgc3RyZWFtIHplcm8gc2V0dGluZ3MgYW5kIGluZGV4IGJ1ZmZlciBtdXN0IGJlIHNldCB0byBOVUxMICovCiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbMF0gPSBOVUxMOwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU3RyaWRlWzBdID0gMDsKICAgIGliID0gVGhpcy0+c3RhdGVCbG9jay0+cEluZGV4RGF0YTsKICAgIGlmKGliKSB7CiAgICAgICAgSVdpbmVEM0RJbmRleEJ1ZmZlcl9SZWxlYXNlKGliKTsKICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5wSW5kZXhEYXRhID0gTlVMTDsKICAgIH0KICAgIC8qIE5vIG5lZWQgdG8gbWFyayB0aGUgc3RyZWFtIHNvdXJjZSBzdGF0ZSBkaXJ0eSBoZXJlLiBFaXRoZXIgdGhlIGFwcCBjYWxscyBVUCBkcmF3aW5nIGFnYWluLCBvciBpdCBoYXMgdG8gY2FsbAogICAgICogU2V0U3RyZWFtU291cmNlIHRvIHNwZWNpZnkgYSB2ZXJ0ZXggYnVmZmVyCiAgICAgKi8KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3UHJpbWl0aXZlU3RyaWRlZCAoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLCBVSU5UIFByaW1pdGl2ZUNvdW50LCBXaW5lRGlyZWN0M0RWZXJ0ZXhTdHJpZGVkRGF0YSAqRHJhd1ByaW1TdHJpZGVEYXRhKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwoKICAgIC8qIE1hcmsgdGhlIHN0YXRlIGRpcnR5IHVudGlsIHdlIGhhdmUgbmljZXIgdHJhY2tpbmcKICAgICAqIGl0cyBmaW5lIHRvIGNoYW5nZSBiYXNlVmVydGV4SW5kZXggYmVjYXVzZSB0aGF0IGNhbGwgaXMgb25seSBjYWxsZWQgYnkgZGRyYXcgd2hpY2ggZG9lcyBub3QgbmVlZAogICAgICogdGhhdCB2YWx1ZS4KICAgICAqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1ZERUNMKTsKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9JTkRFWEJVRkZFUik7CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5iYXNlVmVydGV4SW5kZXggPSAwOwogICAgVGhpcy0+dXBfc3RyaWRlZCA9IERyYXdQcmltU3RyaWRlRGF0YTsKICAgIGRyYXdQcmltaXRpdmUoaWZhY2UsIFByaW1pdGl2ZVR5cGUsIFByaW1pdGl2ZUNvdW50LCAwLCAwLCAwLCAwLCBOVUxMLCAwKTsKICAgIFRoaXMtPnVwX3N0cmlkZWQgPSBOVUxMOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfRHJhd0luZGV4ZWRQcmltaXRpdmVTdHJpZGVkKElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRFBSSU1JVElWRVRZUEUgUHJpbWl0aXZlVHlwZSwgVUlOVCBQcmltaXRpdmVDb3VudCwgV2luZURpcmVjdDNEVmVydGV4U3RyaWRlZERhdGEgKkRyYXdQcmltU3RyaWRlRGF0YSwgVUlOVCBOdW1WZXJ0aWNlcywgQ09OU1Qgdm9pZCAqcEluZGV4RGF0YSwgV0lORUQzREZPUk1BVCBJbmRleERhdGFGb3JtYXQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBEV09SRCBpZHhTaXplID0gKEluZGV4RGF0YUZvcm1hdCA9PSBXSU5FRDNERk1UX0lOREVYMzIgPyA0IDogMik7CgogICAgLyogTWFyayB0aGUgc3RhdGUgZGlydHkgdW50aWwgd2UgaGF2ZSBuaWNlciB0cmFja2luZwogICAgICogaXRzIGZpbmUgdG8gY2hhbmdlIGJhc2VWZXJ0ZXhJbmRleCBiZWNhdXNlIHRoYXQgY2FsbCBpcyBvbmx5IGNhbGxlZCBieSBkZHJhdyB3aGljaCBkb2VzIG5vdCBuZWVkCiAgICAgKiB0aGF0IHZhbHVlLgogICAgICovCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVkRFQ0wpOwogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX0lOREVYQlVGRkVSKTsKICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbUlzVVAgPSBUUlVFOwogICAgVGhpcy0+c3RhdGVCbG9jay0+YmFzZVZlcnRleEluZGV4ID0gMDsKICAgIFRoaXMtPnVwX3N0cmlkZWQgPSBEcmF3UHJpbVN0cmlkZURhdGE7CiAgICBkcmF3UHJpbWl0aXZlKGlmYWNlLCBQcmltaXRpdmVUeXBlLCBQcmltaXRpdmVDb3VudCwgMCAvKiBzdGFydHZlcnRleGlkeCAqLywgMCAvKiBudW1pbmRpY2VzICovLCAwIC8qIHN0YXJ0aWR4ICovLCBpZHhTaXplLCBwSW5kZXhEYXRhLCAwIC8qIG1pbmluZGV4ICovKTsKICAgIFRoaXMtPnVwX3N0cmlkZWQgPSBOVUxMOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIElXaW5lRDNERGV2aWNlSW1wbF9VcGRhdGVWb2x1bWUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFZvbHVtZSAqcFNvdXJjZVZvbHVtZSwgSVdpbmVEM0RWb2x1bWUgKnBEZXN0aW5hdGlvblZvbHVtZSkgewogICAgLyogVGhpcyBpcyBhIGhlbHBlciBmdW5jdGlvbiBmb3IgVXBkYXRlVGV4dHVyZSwgdGhlcmUgaXMgbm8gcHVibGljIFVwZGF0ZVZvbHVtZSBtZXRob2QgaW4gZDNkLiBTaW5jZSBpdCdzCiAgICAgKiBub3QgY2FsbGFibGUgYnkgdGhlIGFwcCBkaXJlY3RseSBubyBwYXJhbWV0ZXIgdmFsaWRhdGlvbiBjaGVja3MgYXJlIG5lZWRlZCBoZXJlLgogICAgICovCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgV0lORUQzRExPQ0tFRF9CT1ggc3JjOwogICAgV0lORUQzRExPQ0tFRF9CT1ggZHN0OwogICAgSFJFU1VMVCBocjsKICAgIFRSQUNFKCIoJXApLT4oJXAsICVwKVxuIiwgVGhpcywgcFNvdXJjZVZvbHVtZSwgcERlc3RpbmF0aW9uVm9sdW1lKTsKCiAgICAvKiBUT0RPOiBJbXBsZW1lbnQgZGlyZWN0IGxvYWRpbmcgaW50byB0aGUgZ2wgdm9sdW1lIGluc3RlYWQgb2YgdXNpbmcgbWVtY3B5IGFuZAogICAgICogZGlydGlmaWNhdGlvbiB0byBpbXByb3ZlIGxvYWRpbmcgcGVyZm9ybWFuY2UuCiAgICAgKi8KICAgIGhyID0gSVdpbmVEM0RWb2x1bWVfTG9ja0JveChwU291cmNlVm9sdW1lLCAmc3JjLCBOVUxMLCBXSU5FRDNETE9DS19SRUFET05MWSk7CiAgICBpZihGQUlMRUQoaHIpKSByZXR1cm4gaHI7CiAgICBociA9IElXaW5lRDNEVm9sdW1lX0xvY2tCb3gocERlc3RpbmF0aW9uVm9sdW1lLCAmZHN0LCBOVUxMLCBXSU5FRDNETE9DS19ESVNDQVJEKTsKICAgIGlmKEZBSUxFRChocikpIHsKICAgIElXaW5lRDNEVm9sdW1lX1VubG9ja0JveChwU291cmNlVm9sdW1lKTsKICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIG1lbWNweShkc3QucEJpdHMsIHNyYy5wQml0cywgKChJV2luZUQzRFZvbHVtZUltcGwgKikgcERlc3RpbmF0aW9uVm9sdW1lKS0+cmVzb3VyY2Uuc2l6ZSk7CgogICAgaHIgPSBJV2luZUQzRFZvbHVtZV9VbmxvY2tCb3gocERlc3RpbmF0aW9uVm9sdW1lKTsKICAgIGlmKEZBSUxFRChocikpIHsKICAgICAgICBJV2luZUQzRFZvbHVtZV9VbmxvY2tCb3gocFNvdXJjZVZvbHVtZSk7CiAgICB9IGVsc2UgewogICAgICAgIGhyID0gSVdpbmVEM0RWb2x1bWVfVW5sb2NrQm94KHBTb3VyY2VWb2x1bWUpOwogICAgfQogICAgcmV0dXJuIGhyOwp9CgovKiBZZXQgYW5vdGhlciB3YXkgdG8gdXBkYXRlIGEgdGV4dHVyZSwgc29tZSBhcHBzIHVzZSB0aGlzIHRvIGxvYWQgZGVmYXVsdCB0ZXh0dXJlcyBpbnN0ZWFkIG9mIHVzaW5nIHN1cmZhY2UvdGV4dHVyZSBsb2NrL3VubG9jayAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1VwZGF0ZVRleHR1cmUgKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RCYXNlVGV4dHVyZSAqcFNvdXJjZVRleHR1cmUsICBJV2luZUQzREJhc2VUZXh0dXJlICpwRGVzdGluYXRpb25UZXh0dXJlKXsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIEhSRVNVTFQgaHIgPSBXSU5FRDNEX09LOwogICAgV0lORUQzRFJFU09VUkNFVFlQRSBzb3VyY2VUeXBlOwogICAgV0lORUQzRFJFU09VUkNFVFlQRSBkZXN0aW5hdGlvblR5cGU7CiAgICBpbnQgaSAsbGV2ZWxzOwoKICAgIC8qIFRPRE86IHRoaW5rIGFib3V0IG1vdmluZyB0aGUgY29kZSBpbnRvIElXaW5lRDNEQmFzZVRleHR1cmUgICovCgogICAgVFJBQ0UoIiglcCkgU291cmNlICVwIERlc3RpbmF0aW9uICVwXG4iLCBUaGlzLCBwU291cmNlVGV4dHVyZSwgcERlc3RpbmF0aW9uVGV4dHVyZSk7CgogICAgLyogdmVyaWZ5IHRoYXQgdGhlIHNvdXJjZSBhbmQgZGVzdGluYXRpb24gdGV4dHVyZXMgYXJlbid0IE5VTEwgKi8KICAgIGlmIChOVUxMID09IHBTb3VyY2VUZXh0dXJlIHx8IE5VTEwgPT0gcERlc3RpbmF0aW9uVGV4dHVyZSkgewogICAgICAgIFdBUk4oIiglcCkgOiBzb3VyY2UgKCVwKSBhbmQgZGVzdGluYXRpb24gKCVwKSB0ZXh0dXJlcyBtdXN0IG5vdCBiZSBOVUxMLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIiwKICAgICAgICAgICAgIFRoaXMsIHBTb3VyY2VUZXh0dXJlLCBwRGVzdGluYXRpb25UZXh0dXJlKTsKICAgICAgICBociA9IFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYgKHBTb3VyY2VUZXh0dXJlID09IHBEZXN0aW5hdGlvblRleHR1cmUpIHsKICAgICAgICBXQVJOKCIoJXApIDogc291cmNlICglcCkgYW5kIGRlc3RpbmF0aW9uICglcCkgdGV4dHVyZXMgbXVzdCBiZSBkaWZmZXJlbnQsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iLAogICAgICAgICAgICAgVGhpcywgcFNvdXJjZVRleHR1cmUsIHBEZXN0aW5hdGlvblRleHR1cmUpOwogICAgICAgIGhyID0gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIC8qIFZlcmlmeSB0aGF0IHRoZSBzb3VyY2UgYW5kIGRlc3RpbmF0aW9uIHRleHR1cmVzIGFyZSB0aGUgc2FtZSB0eXBlICovCiAgICBzb3VyY2VUeXBlICAgICAgPSBJV2luZUQzREJhc2VUZXh0dXJlX0dldFR5cGUocFNvdXJjZVRleHR1cmUpOwogICAgZGVzdGluYXRpb25UeXBlID0gSVdpbmVEM0RCYXNlVGV4dHVyZV9HZXRUeXBlKHBEZXN0aW5hdGlvblRleHR1cmUpOwoKICAgIGlmIChzb3VyY2VUeXBlICE9IGRlc3RpbmF0aW9uVHlwZSkgewogICAgICAgIFdBUk4oIiglcCkgU29yY2UgYW5kIGRlc3RpbmF0aW9uIHR5cGVzIG11c3QgbWF0Y2gsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iLAogICAgICAgICAgICAgVGhpcyk7CiAgICAgICAgaHIgPSBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIC8qIGNoZWNrIHRoYXQgYm90aCB0ZXh0dXJlcyBoYXZlIHRoZSBpZGVudGljYWwgbnVtYmVycyBvZiBsZXZlbHMgICovCiAgICBpZiAoSVdpbmVEM0RCYXNlVGV4dHVyZV9HZXRMZXZlbENvdW50KHBEZXN0aW5hdGlvblRleHR1cmUpICAhPSBJV2luZUQzREJhc2VUZXh0dXJlX0dldExldmVsQ291bnQocFNvdXJjZVRleHR1cmUpKSB7CiAgICAgICAgV0FSTigiKCVwKSA6IHNvdXJjZSAoJXApIGFuZCBkZXN0aW5hdGlvbiAoJXApIHRleHR1cmVzIG11c3QgaGF2ZSBpZGVudGljbGUgbnVtYmVycyBvZiBsZXZlbHMsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iLCBUaGlzLCBwU291cmNlVGV4dHVyZSwgcERlc3RpbmF0aW9uVGV4dHVyZSk7CiAgICAgICAgaHIgPSBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmIChXSU5FRDNEX09LID09IGhyKSB7CgogICAgICAgIC8qIE1ha2Ugc3VyZSB0aGF0IHRoZSBkZXN0aW5hdGlvbiB0ZXh0dXJlIGlzIGxvYWRlZCAqLwogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUHJlTG9hZChwRGVzdGluYXRpb25UZXh0dXJlKTsKCiAgICAgICAgLyogVXBkYXRlIGV2ZXJ5IHN1cmZhY2UgbGV2ZWwgb2YgdGhlIHRleHR1cmUgKi8KICAgICAgICBsZXZlbHMgPSBJV2luZUQzREJhc2VUZXh0dXJlX0dldExldmVsQ291bnQocERlc3RpbmF0aW9uVGV4dHVyZSk7CgogICAgICAgIHN3aXRjaCAoc291cmNlVHlwZSkgewogICAgICAgIGNhc2UgV0lORUQzRFJUWVBFX1RFWFRVUkU6CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSAqc3JjU3VyZmFjZTsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSAqZGVzdFN1cmZhY2U7CgogICAgICAgICAgICAgICAgZm9yIChpID0gMCA7IGkgPCBsZXZlbHMgOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFRleHR1cmVfR2V0U3VyZmFjZUxldmVsKChJV2luZUQzRFRleHR1cmUgKilwU291cmNlVGV4dHVyZSwgICAgICBpLCAmc3JjU3VyZmFjZSk7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RUZXh0dXJlX0dldFN1cmZhY2VMZXZlbCgoSVdpbmVEM0RUZXh0dXJlICopcERlc3RpbmF0aW9uVGV4dHVyZSwgaSwgJmRlc3RTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX1VwZGF0ZVN1cmZhY2UoaWZhY2UsIHNyY1N1cmZhY2UsIE5VTEwsIGRlc3RTdXJmYWNlLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShzcmNTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShkZXN0U3VyZmFjZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKFdJTkVEM0RfT0sgIT0gaHIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgV0FSTigiKCVwKSA6IENhbGwgdG8gdXBkYXRlIHN1cmZhY2UgZmFpbGVkXG4iLCBUaGlzKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9DVUJFVEVYVFVSRToKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlICpzcmNTdXJmYWNlOwogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlICpkZXN0U3VyZmFjZTsKICAgICAgICAgICAgICAgIFdJTkVEM0RDVUJFTUFQX0ZBQ0VTIGZhY2VUeXBlOwoKICAgICAgICAgICAgICAgIGZvciAoaSA9IDAgOyBpIDwgbGV2ZWxzIDsgKytpKSB7CiAgICAgICAgICAgICAgICAgICAgLyogVXBkYXRlIGVhY2ggY3ViZSBmYWNlICovCiAgICAgICAgICAgICAgICAgICAgZm9yIChmYWNlVHlwZSA9IFdJTkVEM0RDVUJFTUFQX0ZBQ0VfUE9TSVRJVkVfWDsgZmFjZVR5cGUgPD0gV0lORUQzRENVQkVNQVBfRkFDRV9ORUdBVElWRV9aOyArK2ZhY2VUeXBlKXsKICAgICAgICAgICAgICAgICAgICAgICAgaHIgPSBJV2luZUQzREN1YmVUZXh0dXJlX0dldEN1YmVNYXBTdXJmYWNlKChJV2luZUQzREN1YmVUZXh0dXJlICopcFNvdXJjZVRleHR1cmUsICAgICAgZmFjZVR5cGUsIGksICZzcmNTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFdJTkVEM0RfT0sgIT0gaHIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWE1FKCIoJXApIDogRmFpbGVkIHRvIGdldCBzcmMgY3ViZSBzdXJmYWNlIGZhY2V0eXBlICVkLCBsZXZlbCAlZFxuIiwgVGhpcywgZmFjZVR5cGUsIGkpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIkdvdCBzcmNTdXJmYWNlICVwXG4iLCBzcmNTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBociA9IElXaW5lRDNEQ3ViZVRleHR1cmVfR2V0Q3ViZU1hcFN1cmZhY2UoKElXaW5lRDNEQ3ViZVRleHR1cmUgKilwRGVzdGluYXRpb25UZXh0dXJlLCBmYWNlVHlwZSwgaSwgJmRlc3RTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFdJTkVEM0RfT0sgIT0gaHIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWE1FKCIoJXApIDogRmFpbGVkIHRvIGdldCBzcmMgY3ViZSBzdXJmYWNlIGZhY2V0eXBlICVkLCBsZXZlbCAlZFxuIiwgVGhpcywgZmFjZVR5cGUsIGkpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIkdvdCBkZXNyU3VyZmFjZSAlcFxuIiwgZGVzdFN1cmZhY2UpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGhyID0gSVdpbmVEM0REZXZpY2VfVXBkYXRlU3VyZmFjZShpZmFjZSwgc3JjU3VyZmFjZSwgTlVMTCwgZGVzdFN1cmZhY2UsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShzcmNTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2UoZGVzdFN1cmZhY2UpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoV0lORUQzRF9PSyAhPSBocikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgV0FSTigiKCVwKSA6IENhbGwgdG8gdXBkYXRlIHN1cmZhY2UgZmFpbGVkXG4iLCBUaGlzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBocjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNEUlRZUEVfVk9MVU1FVEVYVFVSRToKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSVdpbmVEM0RWb2x1bWUgICpzcmNWb2x1bWUgID0gTlVMTDsKICAgICAgICAgICAgICAgIElXaW5lRDNEVm9sdW1lICAqZGVzdFZvbHVtZSA9IE5VTEw7CgogICAgICAgICAgICAgICAgZm9yIChpID0gMCA7IGkgPCBsZXZlbHMgOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFZvbHVtZVRleHR1cmVfR2V0Vm9sdW1lTGV2ZWwoKElXaW5lRDNEVm9sdW1lVGV4dHVyZSAqKXBTb3VyY2VUZXh0dXJlLCAgICAgIGksICZzcmNWb2x1bWUpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNEVm9sdW1lVGV4dHVyZV9HZXRWb2x1bWVMZXZlbCgoSVdpbmVEM0RWb2x1bWVUZXh0dXJlICopcERlc3RpbmF0aW9uVGV4dHVyZSwgaSwgJmRlc3RWb2x1bWUpOwogICAgICAgICAgICAgICAgICAgIGhyID0gIElXaW5lRDNERGV2aWNlSW1wbF9VcGRhdGVWb2x1bWUoaWZhY2UsIHNyY1ZvbHVtZSwgZGVzdFZvbHVtZSk7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RWb2x1bWVfUmVsZWFzZShzcmNWb2x1bWUpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNEVm9sdW1lX1JlbGVhc2UoZGVzdFZvbHVtZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKFdJTkVEM0RfT0sgIT0gaHIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgV0FSTigiKCVwKSA6IENhbGwgdG8gdXBkYXRlIHZvbHVtZSBmYWlsZWRcbiIsIFRoaXMpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gaHI7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBGSVhNRSgiKCVwKSA6IFVuc3VwcG9ydGVkIHNvdXJjZSBhbmQgZGVzdGluYXRpb24gdHlwZVxuIiwgVGhpcyk7CiAgICAgICAgICAgIGhyID0gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfR2V0RnJvbnRCdWZmZXJEYXRhKElXaW5lRDNERGV2aWNlICppZmFjZSxVSU5UIGlTd2FwQ2hhaW4sIElXaW5lRDNEU3VyZmFjZSAqcERlc3RTdXJmYWNlKSB7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcENoYWluOwogICAgSFJFU1VMVCBocjsKICAgIGhyID0gSVdpbmVEM0REZXZpY2VJbXBsX0dldFN3YXBDaGFpbihpZmFjZSwgIGlTd2FwQ2hhaW4sIChJV2luZUQzRFN3YXBDaGFpbiAqKikmc3dhcENoYWluKTsKICAgIGlmKGhyID09IFdJTkVEM0RfT0spIHsKICAgICAgICBociA9IElXaW5lRDNEU3dhcENoYWluX0dldEZyb250QnVmZmVyRGF0YShzd2FwQ2hhaW4sIHBEZXN0U3VyZmFjZSk7CiAgICAgICAgICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKHN3YXBDaGFpbik7CiAgICB9CiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9WYWxpZGF0ZURldmljZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEKiBwTnVtUGFzc2VzKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICAvKiByZXR1cm4gYSBzZW5zaWJsZSBkZWZhdWx0ICovCiAgICAqcE51bVBhc3NlcyA9IDE7CiAgICAvKiBUT0RPOiBJZiB0aGUgd2luZG93IGlzIG1pbmltaXplZCB0aGVuIHZhbGlkYXRlIGRldmljZSBzaG91bGQgcmV0dXJuIHNvbWV0aGluZyBvdGhlciB0aGFuIFdJTkVEM0RfT0sgKi8KICAgIEZJWE1FKCIoJXApIDogc3R1YlxuIiwgVGhpcyk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFBhbGV0dGVFbnRyaWVzKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBQYWxldHRlTnVtYmVyLCBDT05TVCBQQUxFVFRFRU5UUlkqIHBFbnRyaWVzKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpbnQgajsKICAgIFRSQUNFKCIoJXApIDogUGFsZXR0ZU51bWJlciAldVxuIiwgVGhpcywgUGFsZXR0ZU51bWJlcik7CiAgICBpZiAoUGFsZXR0ZU51bWJlciA+PSBNQVhfUEFMRVRURVMpIHsKICAgICAgICBXQVJOKCIoJXApIDogKCV1KSBPdXQgb2YgcmFuZ2UgMC0ldSwgcmV0dXJuaW5nIEludmFsaWQgQ2FsbFxuIiwgVGhpcywgUGFsZXR0ZU51bWJlciwgTUFYX1BBTEVUVEVTKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIGZvciAoaiA9IDA7IGogPCAyNTY7ICsraikgewogICAgICAgIFRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdW2pdLnBlUmVkICAgPSBwRW50cmllc1tqXS5wZVJlZDsKICAgICAgICBUaGlzLT5wYWxldHRlc1tQYWxldHRlTnVtYmVyXVtqXS5wZUdyZWVuID0gcEVudHJpZXNbal0ucGVHcmVlbjsKICAgICAgICBUaGlzLT5wYWxldHRlc1tQYWxldHRlTnVtYmVyXVtqXS5wZUJsdWUgID0gcEVudHJpZXNbal0ucGVCbHVlOwogICAgICAgIFRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdW2pdLnBlRmxhZ3MgPSBwRW50cmllc1tqXS5wZUZsYWdzOwogICAgfQogICAgVFJBQ0UoIiglcCkgOiByZXR1cm5pbmdcbiIsIFRoaXMpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQYWxldHRlRW50cmllcyhJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgUGFsZXR0ZU51bWJlciwgUEFMRVRURUVOVFJZKiBwRW50cmllcykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaW50IGo7CiAgICBUUkFDRSgiKCVwKSA6IFBhbGV0dGVOdW1iZXIgJXVcbiIsIFRoaXMsIFBhbGV0dGVOdW1iZXIpOwogICAgaWYgKFBhbGV0dGVOdW1iZXIgPj0gTUFYX1BBTEVUVEVTKSB7CiAgICAgICAgV0FSTigiKCVwKSA6ICgldSkgT3V0IG9mIHJhbmdlIDAtJXUsIHJldHVybmluZyBJbnZhbGlkIENhbGxcbiIsIFRoaXMsIFBhbGV0dGVOdW1iZXIsIE1BWF9QQUxFVFRFUyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICBmb3IgKGogPSAwOyBqIDwgMjU2OyArK2opIHsKICAgICAgICBwRW50cmllc1tqXS5wZVJlZCAgID0gVGhpcy0+cGFsZXR0ZXNbUGFsZXR0ZU51bWJlcl1bal0ucGVSZWQ7CiAgICAgICAgcEVudHJpZXNbal0ucGVHcmVlbiA9IFRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdW2pdLnBlR3JlZW47CiAgICAgICAgcEVudHJpZXNbal0ucGVCbHVlICA9IFRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdW2pdLnBlQmx1ZTsKICAgICAgICBwRW50cmllc1tqXS5wZUZsYWdzID0gVGhpcy0+cGFsZXR0ZXNbUGFsZXR0ZU51bWJlcl1bal0ucGVGbGFnczsKICAgIH0KICAgIFRSQUNFKCIoJXApIDogcmV0dXJuaW5nXG4iLCBUaGlzKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfU2V0Q3VycmVudFRleHR1cmVQYWxldHRlKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBQYWxldHRlTnVtYmVyKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IFBhbGV0dGVOdW1iZXIgJXVcbiIsIFRoaXMsIFBhbGV0dGVOdW1iZXIpOwogICAgaWYgKFBhbGV0dGVOdW1iZXIgPj0gTUFYX1BBTEVUVEVTKSB7CiAgICAgICAgV0FSTigiKCVwKSA6ICgldSkgT3V0IG9mIHJhbmdlIDAtJXUsIHJldHVybmluZyBJbnZhbGlkIENhbGxcbiIsIFRoaXMsIFBhbGV0dGVOdW1iZXIsIE1BWF9QQUxFVFRFUyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICAvKlRPRE86IHN0YXRlYmxvY2tzICovCiAgICBUaGlzLT5jdXJyZW50UGFsZXR0ZSA9IFBhbGV0dGVOdW1iZXI7CiAgICBUUkFDRSgiKCVwKSA6IHJldHVybmluZ1xuIiwgVGhpcyk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEN1cnJlbnRUZXh0dXJlUGFsZXR0ZShJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQqIFBhbGV0dGVOdW1iZXIpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIGlmIChQYWxldHRlTnVtYmVyID09IE5VTEwpIHsKICAgICAgICBXQVJOKCIoJXApIDogcmV0dXJuaW5nIEludmFsaWQgQ2FsbFxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICAvKlRPRE86IHN0YXRlYmxvY2tzICovCiAgICAqUGFsZXR0ZU51bWJlciA9IFRoaXMtPmN1cnJlbnRQYWxldHRlOwogICAgVFJBQ0UoIiglcCkgOiByZXR1cm5pbmcgICV1XG4iLCBUaGlzLCAqUGFsZXR0ZU51bWJlcik7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFNvZnR3YXJlVmVydGV4UHJvY2Vzc2luZyhJV2luZUQzRERldmljZSAqaWZhY2UsIEJPT0wgYlNvZnR3YXJlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBzdGF0aWMgQk9PTCBzaG93Rml4bWVzID0gVFJVRTsKICAgIGlmIChzaG93Rml4bWVzKSB7CiAgICAgICAgRklYTUUoIiglcCkgOiBzdHViXG4iLCBUaGlzKTsKICAgICAgICBzaG93Rml4bWVzID0gRkFMU0U7CiAgICB9CgogICAgVGhpcy0+c29mdHdhcmVWZXJ0ZXhQcm9jZXNzaW5nID0gYlNvZnR3YXJlOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCgpzdGF0aWMgQk9PTCAgICAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfR2V0U29mdHdhcmVWZXJ0ZXhQcm9jZXNzaW5nKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgc3RhdGljIEJPT0wgc2hvd0ZpeG1lcyA9IFRSVUU7CiAgICBpZiAoc2hvd0ZpeG1lcykgewogICAgICAgIEZJWE1FKCIoJXApIDogc3R1YlxuIiwgVGhpcyk7CiAgICAgICAgc2hvd0ZpeG1lcyA9IEZBTFNFOwogICAgfQogICAgcmV0dXJuIFRoaXMtPnNvZnR3YXJlVmVydGV4UHJvY2Vzc2luZzsKfQoKCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRSYXN0ZXJTdGF0dXMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIGlTd2FwQ2hhaW4sIFdJTkVEM0RSQVNURVJfU1RBVFVTKiBwUmFzdGVyU3RhdHVzKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcENoYWluOwogICAgSFJFU1VMVCBocjsKCiAgICBUUkFDRSgiKCVwKSA6ICBTd2FwQ2hhaW4gJWQgcmV0dXJuaW5nICVwXG4iLCBUaGlzLCBpU3dhcENoYWluLCBwUmFzdGVyU3RhdHVzKTsKCiAgICBociA9IElXaW5lRDNERGV2aWNlSW1wbF9HZXRTd2FwQ2hhaW4oaWZhY2UsICBpU3dhcENoYWluLCAoSVdpbmVEM0RTd2FwQ2hhaW4gKiopJnN3YXBDaGFpbik7CiAgICBpZihociA9PSBXSU5FRDNEX09LKXsKICAgICAgICBociA9IElXaW5lRDNEU3dhcENoYWluX0dldFJhc3RlclN0YXR1cyhzd2FwQ2hhaW4sIHBSYXN0ZXJTdGF0dXMpOwogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2Uoc3dhcENoYWluKTsKICAgIH1lbHNlewogICAgICAgIEZJWE1FKCIoJXApIElXaW5lRDNEU3dhcENoYWluX0dldFJhc3RlclN0YXR1cyByZXR1cm5lZCBpbiBlcnJvclxuIiwgVGhpcyk7CiAgICB9CiAgICByZXR1cm4gaHI7Cn0KCgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfU2V0TlBhdGNoTW9kZShJV2luZUQzRERldmljZSAqaWZhY2UsIGZsb2F0IG5TZWdtZW50cykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgc3RhdGljIEJPT0wgc2hvd2ZpeG1lcyA9IFRSVUU7CiAgICBpZihuU2VnbWVudHMgIT0gMC4wZikgewogICAgICAgIGlmKCBzaG93Zml4bWVzKSB7CiAgICAgICAgICAgIEZJWE1FKCIoJXApIDogc3R1YiBuU2VnbWVudHMoJWYpXG4iLCBUaGlzLCBuU2VnbWVudHMpOwogICAgICAgICAgICBzaG93Zml4bWVzID0gRkFMU0U7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBmbG9hdCAgICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXROUGF0Y2hNb2RlKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgc3RhdGljIEJPT0wgc2hvd2ZpeG1lcyA9IFRSVUU7CiAgICBpZiggc2hvd2ZpeG1lcykgewogICAgICAgIEZJWE1FKCIoJXApIDogc3R1YiByZXR1cm5pbmcoJWYpXG4iLCBUaGlzLCAwLjBmKTsKICAgICAgICBzaG93Zml4bWVzID0gRkFMU0U7CiAgICB9CiAgICByZXR1cm4gMC4wZjsKfQoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX1VwZGF0ZVN1cmZhY2UoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFN1cmZhY2UgKnBTb3VyY2VTdXJmYWNlLCBDT05TVCBSRUNUKiBwU291cmNlUmVjdCwgSVdpbmVEM0RTdXJmYWNlICpwRGVzdGluYXRpb25TdXJmYWNlLCBDT05TVCBQT0lOVCogcERlc3RQb2ludCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICAqVGhpcyAgICAgICAgID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIC8qKiBUT0RPOiByZW1vdmUgY2FzdHMgdG8gSVdpbmVEM0RTdXJmYWNlSW1wbAogICAgICogICAgICAgTk9URTogbW92ZSBjb2RlIHRvIHN1cmZhY2UgdG8gYWNjb21wbGlzaCB0aGlzCiAgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpwU3JjU3VyZmFjZSAgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKXBTb3VyY2VTdXJmYWNlOwogICAgaW50IHNyY1dpZHRoLCBzcmNIZWlnaHQ7CiAgICB1bnNpZ25lZCBpbnQgIHNyY1N1cmZhY2VXaWR0aCwgc3JjU3VyZmFjZUhlaWdodCwgZGVzdFN1cmZhY2VXaWR0aCwgZGVzdFN1cmZhY2VIZWlnaHQ7CiAgICBXSU5FRDNERk9STUFUIGRlc3RGb3JtYXQsIHNyY0Zvcm1hdDsKICAgIFVJTlQgICAgICAgICAgZGVzdFNpemU7CiAgICBpbnQgc3JjTGVmdCwgZGVzdExlZnQsIGRlc3RUb3A7CiAgICBXSU5FRDNEUE9PTCAgICAgICBzcmNQb29sLCBkZXN0UG9vbDsKICAgIGludCBvZmZzZXQgICAgPSAwOwogICAgaW50IHJvd29mZnNldCA9IDA7IC8qIGhvdyBtYW55IGJ5dGVzIHRvIGFkZCBvbnRvIHRoZSBlbmQgb2YgYSByb3cgdG8gd3JhcGFyb3VuZCB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBuZXh0ICovCiAgICBnbERlc2NyaXB0b3IgKmdsRGVzY3JpcHRpb24gPSBOVUxMOwogICAgR0xlbnVtIGR1bW15OwogICAgaW50IGJwcDsKICAgIENPTlZFUlRfVFlQRVMgY29udmVydCA9IE5PX0NPTlZFUlNJT047CgogICAgV0lORUQzRFNVUkZBQ0VfREVTQyAgd2luZWRlc2M7CgogICAgVFJBQ0UoIiglcCkgOiBTb3VyY2UgKCVwKSAgUmVjdCAoJXApIERlc3RpbmF0aW9uICglcCkgUG9pbnQoJXApXG4iLCBUaGlzLCBwU291cmNlU3VyZmFjZSwgcFNvdXJjZVJlY3QsIHBEZXN0aW5hdGlvblN1cmZhY2UsIHBEZXN0UG9pbnQpOwogICAgbWVtc2V0KCZ3aW5lZGVzYywgMCwgc2l6ZW9mKHdpbmVkZXNjKSk7CiAgICB3aW5lZGVzYy5XaWR0aCAgPSAmc3JjU3VyZmFjZVdpZHRoOwogICAgd2luZWRlc2MuSGVpZ2h0ID0gJnNyY1N1cmZhY2VIZWlnaHQ7CiAgICB3aW5lZGVzYy5Qb29sICAgPSAmc3JjUG9vbDsKICAgIHdpbmVkZXNjLkZvcm1hdCA9ICZzcmNGb3JtYXQ7CgogICAgSVdpbmVEM0RTdXJmYWNlX0dldERlc2MocFNvdXJjZVN1cmZhY2UsICZ3aW5lZGVzYyk7CgogICAgd2luZWRlc2MuV2lkdGggID0gJmRlc3RTdXJmYWNlV2lkdGg7CiAgICB3aW5lZGVzYy5IZWlnaHQgPSAmZGVzdFN1cmZhY2VIZWlnaHQ7CiAgICB3aW5lZGVzYy5Qb29sICAgPSAmZGVzdFBvb2w7CiAgICB3aW5lZGVzYy5Gb3JtYXQgPSAmZGVzdEZvcm1hdDsKICAgIHdpbmVkZXNjLlNpemUgICA9ICZkZXN0U2l6ZTsKCiAgICBJV2luZUQzRFN1cmZhY2VfR2V0RGVzYyhwRGVzdGluYXRpb25TdXJmYWNlLCAmd2luZWRlc2MpOwoKICAgIGlmKHNyY1Bvb2wgIT0gV0lORUQzRFBPT0xfU1lTVEVNTUVNICB8fCBkZXN0UG9vbCAhPSBXSU5FRDNEUE9PTF9ERUZBVUxUKXsKICAgICAgICBXQVJOKCJzb3VyY2UgJXAgbXVzdCBiZSBTWVNURU1NRU0gYW5kIGRlc3QgJXAgbXVzdCBiZSBERUZBVUxULCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIiwgcFNvdXJjZVN1cmZhY2UsIHBEZXN0aW5hdGlvblN1cmZhY2UpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIC8qIFRoaXMgY2FsbCBsb2FkcyB0aGUgb3BlbmdsIHN1cmZhY2UgZGlyZWN0bHksIGluc3RlYWQgb2YgY29weWluZyB0aGUgc3VyZmFjZSB0byB0aGUKICAgICAqIGRlc3RpbmF0aW9uJ3Mgc3lzbWVtIGNvcHkuIElmIHN1cmZhY2UgY29udmVyc2lvbiBpcyBuZWVkZWQsIHVzZSBCbHRGYXN0IGluc3RlYWQgdG8KICAgICAqIGNvcHkgaW4gc3lzbWVtIGFuZCB1c2UgcmVndWxhciBzdXJmYWNlIGxvYWRpbmcuCiAgICAgKi8KICAgIGQzZGZtdF9nZXRfY29udigoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBwRGVzdGluYXRpb25TdXJmYWNlLCBGQUxTRSwgVFJVRSwKICAgICAgICAgICAgICAgICAgICAmZHVtbXksICZkdW1teSwgJmR1bW15LCAmY29udmVydCwgJmJwcCwgRkFMU0UpOwogICAgaWYoY29udmVydCAhPSBOT19DT05WRVJTSU9OKSB7CiAgICAgICAgcmV0dXJuIElXaW5lRDNEU3VyZmFjZV9CbHRGYXN0KHBEZXN0aW5hdGlvblN1cmZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwRGVzdFBvaW50ICA/IHBEZXN0UG9pbnQtPnggOiAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcERlc3RQb2ludCAgPyBwRGVzdFBvaW50LT55IDogMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTb3VyY2VTdXJmYWNlLCAoUkVDVCAqKSBwU291cmNlUmVjdCwgMCk7CiAgICB9CgogICAgaWYgKGRlc3RGb3JtYXQgPT0gV0lORUQzREZNVF9VTktOT1dOKSB7CiAgICAgICAgVFJBQ0UoIiglcCkgOiBDb252ZXJ0aW5nIGRlc3RpbmF0aW9uIHN1cmZhY2UgZnJvbSBXSU5FRDNERk1UX1VOS05PV04gdG8gdGhlIHNvdXJjZSBmb3JtYXRcbiIsIFRoaXMpOwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRGb3JtYXQocERlc3RpbmF0aW9uU3VyZmFjZSwgc3JjRm9ybWF0KTsKCiAgICAgICAgLyogR2V0IHRoZSB1cGRhdGUgc3VyZmFjZSBkZXNjcmlwdGlvbiAqLwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9HZXREZXNjKHBEZXN0aW5hdGlvblN1cmZhY2UsICZ3aW5lZGVzYyk7CiAgICB9CgogICAgQWN0aXZhdGVDb250ZXh0KFRoaXMsIFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQsIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CgogICAgRU5URVJfR0woKTsKCiAgICBpZiAoR0xfU1VQUE9SVChBUkJfTVVMVElURVhUVVJFKSkgewogICAgICAgIEdMX0VYVENBTEwoZ2xBY3RpdmVUZXh0dXJlQVJCKEdMX1RFWFRVUkUwX0FSQikpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEFjdGl2ZVRleHR1cmVBUkIiKTsKICAgIH0KCiAgICAvKiBNYWtlIHN1cmUgdGhlIHN1cmZhY2UgaXMgbG9hZGVkIGFuZCB1cCB0byBkYXRlICovCiAgICBJV2luZUQzRFN1cmZhY2VfUHJlTG9hZChwRGVzdGluYXRpb25TdXJmYWNlKTsKCiAgICBJV2luZUQzRFN1cmZhY2VfR2V0R2xEZXNjKHBEZXN0aW5hdGlvblN1cmZhY2UsICZnbERlc2NyaXB0aW9uKTsKCiAgICAvKiB0aGlzIG5lZWRzIHRvIGJlIGRvbmUgaW4gbGluZXMgaWYgdGhlIHNvdXJjZVJlY3QgIT0gdGhlIHNvdXJjZVdpZHRoICovCiAgICBzcmNXaWR0aCAgID0gcFNvdXJjZVJlY3QgPyBwU291cmNlUmVjdC0+cmlnaHQgLSBwU291cmNlUmVjdC0+bGVmdCAgIDogc3JjU3VyZmFjZVdpZHRoOwogICAgc3JjSGVpZ2h0ICA9IHBTb3VyY2VSZWN0ID8gcFNvdXJjZVJlY3QtPmJvdHRvbSAtIHBTb3VyY2VSZWN0LT50b3AgICA6IHNyY1N1cmZhY2VIZWlnaHQ7CiAgICBzcmNMZWZ0ICAgID0gcFNvdXJjZVJlY3QgPyBwU291cmNlUmVjdC0+bGVmdCA6IDA7CiAgICBkZXN0TGVmdCAgID0gcERlc3RQb2ludCAgPyBwRGVzdFBvaW50LT54IDogMDsKICAgIGRlc3RUb3AgICAgPSBwRGVzdFBvaW50ICA/IHBEZXN0UG9pbnQtPnkgOiAwOwoKCiAgICAvKiBUaGlzIGZ1bmN0aW9uIGRvZXNuJ3Qgc3VwcG9ydCBjb21wcmVzc2VkIHRleHR1cmVzCiAgICB0aGUgcGl0Y2ggaXMganVzdCBieXRlc1BlclBpeGVsICogd2lkdGggKi8KICAgIGlmKHNyY1dpZHRoICE9IHNyY1N1cmZhY2VXaWR0aCAgfHwgc3JjTGVmdCApewogICAgICAgIHJvd29mZnNldCA9IHNyY1N1cmZhY2VXaWR0aCAqIHBTcmNTdXJmYWNlLT5ieXRlc1BlclBpeGVsOwogICAgICAgIG9mZnNldCAgICs9IHNyY0xlZnQgKiBwU3JjU3VyZmFjZS0+Ynl0ZXNQZXJQaXhlbDsKICAgICAgICAvKiBUT0RPOiBkbyB3ZSBldmVyIGdldCAzYnBwPywgd291bGQgYSBzaGlmdCBhbmQgYW4gYWRkIGJlIHF1aWNrZXIgdGhhbiBhIG11bCAod2VsbCBtYXliZSBhIGN5Y2xlIG9yIHR3bykgKi8KICAgIH0KICAgIC8qIFRPRE8gRFhUIGZvcm1hdHMgKi8KCiAgICBpZihwU291cmNlUmVjdCAhPSBOVUxMICYmIHBTb3VyY2VSZWN0LT50b3AgIT0gMCl7CiAgICAgICBvZmZzZXQgKz0gIHBTb3VyY2VSZWN0LT50b3AgKiBzcmNTdXJmYWNlV2lkdGggKiBwU3JjU3VyZmFjZS0+Ynl0ZXNQZXJQaXhlbDsKICAgIH0KICAgIFRSQUNFKCIoJXApIGdsVGV4U3ViSW1hZ2UyRCwgTGV2ZWwgJWQsIGxlZnQgJWQsIHRvcCAlZCwgd2lkdGggJWQsIGhlaWdodCAlZCAsIGZ0bSAlZCwgdHlwZSAlZCwgbWVtb3J5ICVwXG4iCiAgICAsVGhpcwogICAgLGdsRGVzY3JpcHRpb24tPmxldmVsCiAgICAsZGVzdExlZnQKICAgICxkZXN0VG9wCiAgICAsc3JjV2lkdGgKICAgICxzcmNIZWlnaHQKICAgICxnbERlc2NyaXB0aW9uLT5nbEZvcm1hdAogICAgLGdsRGVzY3JpcHRpb24tPmdsVHlwZQogICAgLElXaW5lRDNEU3VyZmFjZV9HZXREYXRhKHBTb3VyY2VTdXJmYWNlKQogICAgKTsKCiAgICAvKiBTYW5pdHkgY2hlY2sgKi8KICAgIGlmIChJV2luZUQzRFN1cmZhY2VfR2V0RGF0YShwU291cmNlU3VyZmFjZSkgPT0gTlVMTCkgewoKICAgICAgICAvKiBuZWVkIHRvIGxvY2sgdGhlIHN1cmZhY2UgdG8gZ2V0IHRoZSBkYXRhICovCiAgICAgICAgRklYTUUoIlN1cmZhY2VzIGhhcyBubyBhbGxvY2F0ZWQgbWVtb3J5LCBidXQgc2hvdWxkIGJlIGFuIGluIG1lbW9yeSBvbmx5IHN1cmZhY2VcbiIpOwogICAgfQoKICAgIC8qIFRPRE86IEN1YmUgYW5kIHZvbHVtZSBzdXBwb3J0ICovCiAgICBpZihyb3dvZmZzZXQgIT0gMCl7CiAgICAgICAgLyogbm90IGEgd2hvbGUgcm93IHNvIHdlIGhhdmUgdG8gZG8gaXQgYSBsaW5lIGF0IGEgdGltZSAqLwogICAgICAgIGludCBqOwoKICAgICAgICAvKiBob3BlZnVsbHkgdXNpbmcgcG9pbnRlciBhZGR0aW9uIHdpbGwgYmUgcXVpY2tlciB0aGFuIHVzaW5nIGEgcG9pbnQgKyBqICogcm93b2Zmc2V0ICovCiAgICAgICAgY29uc3QgdW5zaWduZWQgY2hhciogZGF0YSA9KChjb25zdCB1bnNpZ25lZCBjaGFyICopSVdpbmVEM0RTdXJmYWNlX0dldERhdGEocFNvdXJjZVN1cmZhY2UpKSArIG9mZnNldDsKCiAgICAgICAgZm9yKGogPSBkZXN0VG9wIDsgaiA8IChzcmNIZWlnaHQgKyBkZXN0VG9wKSA7IGorKyl7CgogICAgICAgICAgICAgICAgZ2xUZXhTdWJJbWFnZTJEKGdsRGVzY3JpcHRpb24tPnRhcmdldAogICAgICAgICAgICAgICAgICAgICxnbERlc2NyaXB0aW9uLT5sZXZlbAogICAgICAgICAgICAgICAgICAgICxkZXN0TGVmdAogICAgICAgICAgICAgICAgICAgICxqCiAgICAgICAgICAgICAgICAgICAgLHNyY1dpZHRoCiAgICAgICAgICAgICAgICAgICAgLDEKICAgICAgICAgICAgICAgICAgICAsZ2xEZXNjcmlwdGlvbi0+Z2xGb3JtYXQKICAgICAgICAgICAgICAgICAgICAsZ2xEZXNjcmlwdGlvbi0+Z2xUeXBlCiAgICAgICAgICAgICAgICAgICAgLGRhdGEgLyogY291bGQgYmUgcXVpY2tlciB1c2luZyAqLwogICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgZGF0YSArPSByb3dvZmZzZXQ7CiAgICAgICAgfQoKICAgIH0gZWxzZSB7IC8qIEZ1bGwgd2lkdGgsIHNvIGp1c3Qgd3JpdGUgb3V0IHRoZSB3aG9sZSB0ZXh0dXJlICovCgogICAgICAgIGlmIChXSU5FRDNERk1UX0RYVDEgPT0gZGVzdEZvcm1hdCB8fAogICAgICAgICAgICBXSU5FRDNERk1UX0RYVDIgPT0gZGVzdEZvcm1hdCB8fAogICAgICAgICAgICBXSU5FRDNERk1UX0RYVDMgPT0gZGVzdEZvcm1hdCB8fAogICAgICAgICAgICBXSU5FRDNERk1UX0RYVDQgPT0gZGVzdEZvcm1hdCB8fAogICAgICAgICAgICBXSU5FRDNERk1UX0RYVDUgPT0gZGVzdEZvcm1hdCkgewogICAgICAgICAgICBpZiAoR0xfU1VQUE9SVChFWFRfVEVYVFVSRV9DT01QUkVTU0lPTl9TM1RDKSkgewogICAgICAgICAgICAgICAgaWYgKGRlc3RTdXJmYWNlSGVpZ2h0ICE9IHNyY0hlaWdodCB8fCBkZXN0U3VyZmFjZVdpZHRoICE9IHNyY1dpZHRoKSB7CiAgICAgICAgICAgICAgICAgICAgLyogRklYTUU6IFRoZSBlYXN5IHdheSB0byBkbyB0aGlzIGlzIHRvIGxvY2sgdGhlIGRlc3RpbmF0aW9uLCBhbmQgY29weSB0aGUgYml0cyBhY3Jvc3MgKi8KICAgICAgICAgICAgICAgICAgICBGSVhNRSgiVXBkYXRpbmcgcGFydCBvZiBhIGNvbXByZXNzZWQgdGV4dHVyZSBpcyBub3Qgc3VwcG9ydGVkIGF0IHRoZSBtb21lbnRcbiIpOwogICAgICAgICAgICAgICAgfSBpZiAoZGVzdEZvcm1hdCAhPSBzcmNGb3JtYXQpIHsKICAgICAgICAgICAgICAgICAgICBGSVhNRSgiVXBkYXRpbmcgbWl4ZWQgZm9ybWF0IGNvbXByZXNzZWQgdGV4dHVyZSBpcyBub3QgY3VycmV0bHkgc3VwcG9ydFxuIik7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xDb21wcmVzc2VkVGV4SW1hZ2UyREFSQikoZ2xEZXNjcmlwdGlvbi0+dGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdsRGVzY3JpcHRpb24tPmxldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdsRGVzY3JpcHRpb24tPmdsRm9ybWF0SW50ZXJuYWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JjV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JjSGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzdFNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0dldERhdGEocFNvdXJjZVN1cmZhY2UpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIEZJWE1FKCJBdHRlbXB0aW5nIHRvIHVwZGF0ZSBhIERYVCBjb21wcmVzc2VkIHRleHR1cmUgd2l0aG91dCBoYXJkd2FyZSBzdXBwb3J0XG4iKTsKICAgICAgICAgICAgfQoKCiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZ2xUZXhTdWJJbWFnZTJEKGdsRGVzY3JpcHRpb24tPnRhcmdldAogICAgICAgICAgICAgICAgICAgICxnbERlc2NyaXB0aW9uLT5sZXZlbAogICAgICAgICAgICAgICAgICAgICxkZXN0TGVmdAogICAgICAgICAgICAgICAgICAgICxkZXN0VG9wCiAgICAgICAgICAgICAgICAgICAgLHNyY1dpZHRoCiAgICAgICAgICAgICAgICAgICAgLHNyY0hlaWdodAogICAgICAgICAgICAgICAgICAgICxnbERlc2NyaXB0aW9uLT5nbEZvcm1hdAogICAgICAgICAgICAgICAgICAgICxnbERlc2NyaXB0aW9uLT5nbFR5cGUKICAgICAgICAgICAgICAgICAgICAsSVdpbmVEM0RTdXJmYWNlX0dldERhdGEocFNvdXJjZVN1cmZhY2UpCiAgICAgICAgICAgICAgICApOwogICAgICAgIH0KICAgICB9CiAgICBjaGVja0dMY2FsbCgiZ2xUZXhTdWJJbWFnZTJEIik7CgogICAgTEVBVkVfR0woKTsKCiAgICBJV2luZUQzRFN1cmZhY2VfTW9kaWZ5TG9jYXRpb24ocERlc3RpbmF0aW9uU3VyZmFjZSwgU0ZMQUdfSU5URVhUVVJFLCBUUlVFKTsKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TQU1QTEVSKDApKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3UmVjdFBhdGNoKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBIYW5kbGUsIENPTlNUIGZsb2F0KiBwTnVtU2VncywgQ09OU1QgV0lORUQzRFJFQ1RQQVRDSF9JTkZPKiBwUmVjdFBhdGNoSW5mbykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgc3RydWN0IFdpbmVEM0RSZWN0UGF0Y2ggKnBhdGNoOwogICAgdW5zaWduZWQgaW50IGk7CiAgICBzdHJ1Y3QgbGlzdCAqZTsKICAgIEJPT0wgZm91bmQ7CiAgICBUUkFDRSgiKCVwKSBIYW5kbGUoJWQpIG5vU2VncyglcCkgcmVjdHBhdGNoKCVwKVxuIiwgVGhpcywgSGFuZGxlLCBwTnVtU2VncywgcFJlY3RQYXRjaEluZm8pOwoKICAgIGlmKCEoSGFuZGxlIHx8IHBSZWN0UGF0Y2hJbmZvKSkgewogICAgICAgIC8qIFRPRE86IFdyaXRlIGEgdGVzdCBmb3IgdGhlIHJldHVybiB2YWx1ZSwgdGh1cyB0aGUgRklYTUUgKi8KICAgICAgICBGSVhNRSgiQm90aCBIYW5kbGUgYW5kIHBSZWN0UGF0Y2hJbmZvIGFyZSBOVUxMXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBpZihIYW5kbGUpIHsKICAgICAgICBpID0gUEFUQ0hNQVBfSEFTSEZVTkMoSGFuZGxlKTsKICAgICAgICBmb3VuZCA9IEZBTFNFOwogICAgICAgIExJU1RfRk9SX0VBQ0goZSwgJlRoaXMtPnBhdGNoZXNbaV0pIHsKICAgICAgICAgICAgcGF0Y2ggPSBMSVNUX0VOVFJZKGUsIHN0cnVjdCBXaW5lRDNEUmVjdFBhdGNoLCBlbnRyeSk7CiAgICAgICAgICAgIGlmKHBhdGNoLT5IYW5kbGUgPT0gSGFuZGxlKSB7CiAgICAgICAgICAgICAgICBmb3VuZCA9IFRSVUU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYoIWZvdW5kKSB7CiAgICAgICAgICAgIFRSQUNFKCJQYXRjaCBkb2VzIG5vdCBleGlzdC4gQ3JlYXRpbmcgYSBuZXcgb25lXG4iKTsKICAgICAgICAgICAgcGF0Y2ggPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKCpwYXRjaCkpOwogICAgICAgICAgICBwYXRjaC0+SGFuZGxlID0gSGFuZGxlOwogICAgICAgICAgICBsaXN0X2FkZF9oZWFkKCZUaGlzLT5wYXRjaGVzW2ldLCAmcGF0Y2gtPmVudHJ5KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBUUkFDRSgiRm91bmQgZXhpc3RpbmcgcGF0Y2ggJXBcbiIsIHBhdGNoKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIC8qIFNpbmNlIG9wZW5nbCBkb2VzIG5vdCBsb2FkIHRlc3NlbGF0ZWQgdmVydGV4IGF0dHJpYnV0ZXMgaW50byBudW1iZXJlZCB2ZXJ0ZXgKICAgICAgICAgKiBhdHRyaWJ1dGVzIHdlIGhhdmUgdG8gdGVzc2VsYXRlLCByZWFkIGJhY2ssIGFuZCBkcmF3LiBUaGlzIG5lZWRzIGEgcGF0Y2gKICAgICAgICAgKiBtYW5hZ2VtZW50IHN0cnVjdHVyZSBpbnN0YW5jZS4gQ3JlYXRlIG9uZS4KICAgICAgICAgKgogICAgICAgICAqIEEgcG9zc2libGUgaW1wcm92ZW1lbnQgaXMgdG8gY2hlY2sgaWYgYSB2ZXJ0ZXggc2hhZGVyIGlzIHVzZWQsIGFuZCBpZiBub3QgZGlyZWN0bHkKICAgICAgICAgKiBkcmF3IHRoZSBwYXRjaC4KICAgICAgICAgKi8KICAgICAgICBGSVhNRSgiRHJhd2luZyBhbiB1bmNhY2hlZCBwYXRjaC4gVGhpcyBpcyBzbG93XG4iKTsKICAgICAgICBwYXRjaCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoKnBhdGNoKSk7CiAgICB9CgogICAgaWYocE51bVNlZ3NbMF0gIT0gcGF0Y2gtPm51bVNlZ3NbMF0gfHwgcE51bVNlZ3NbMV0gIT0gcGF0Y2gtPm51bVNlZ3NbMV0gfHwKICAgICAgIHBOdW1TZWdzWzJdICE9IHBhdGNoLT5udW1TZWdzWzJdIHx8IHBOdW1TZWdzWzNdICE9IHBhdGNoLT5udW1TZWdzWzNdIHx8CiAgICAgICAocFJlY3RQYXRjaEluZm8gJiYgbWVtY21wKHBSZWN0UGF0Y2hJbmZvLCAmcGF0Y2gtPlJlY3RQYXRjaEluZm8sIHNpemVvZigqcFJlY3RQYXRjaEluZm8pKSAhPSAwKSApIHsKICAgICAgICBIUkVTVUxUIGhyOwogICAgICAgIFRSQUNFKCJUZXNzZWxhdGlvbiBkZW5zaXR5IG9yIHBhdGNoIGluZm8gY2hhbmdlZCwgcmV0ZXNzZWxhdGluZ1xuIik7CgogICAgICAgIGlmKHBSZWN0UGF0Y2hJbmZvKSB7CiAgICAgICAgICAgIG1lbWNweSgmcGF0Y2gtPlJlY3RQYXRjaEluZm8sIHBSZWN0UGF0Y2hJbmZvLCBzaXplb2YoKnBSZWN0UGF0Y2hJbmZvKSk7CiAgICAgICAgfQogICAgICAgIHBhdGNoLT5udW1TZWdzWzBdID0gcE51bVNlZ3NbMF07CiAgICAgICAgcGF0Y2gtPm51bVNlZ3NbMV0gPSBwTnVtU2Vnc1sxXTsKICAgICAgICBwYXRjaC0+bnVtU2Vnc1syXSA9IHBOdW1TZWdzWzJdOwogICAgICAgIHBhdGNoLT5udW1TZWdzWzNdID0gcE51bVNlZ3NbM107CgogICAgICAgIGhyID0gdGVzc2VsYXRlX3JlY3RwYXRjaChUaGlzLCBwYXRjaCk7CiAgICAgICAgaWYoRkFJTEVEKGhyKSkgewogICAgICAgICAgICBXQVJOKCJQYXRjaCB0ZXNzZWxhdGlvbiBmYWlsZWRcbiIpOwoKICAgICAgICAgICAgLyogRG8gbm90IHJlbGVhc2UgdGhlIGhhbmRsZSB0byBzdG9yZSB0aGUgcGFyYW1zIG9mIHRoZSBwYXRjaCAqLwogICAgICAgICAgICBpZighSGFuZGxlKSB7CiAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYXRjaCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgICAgIH0KICAgIH0KCiAgICBUaGlzLT5jdXJyZW50UGF0Y2ggPSBwYXRjaDsKICAgIElXaW5lRDNERGV2aWNlX0RyYXdQcmltaXRpdmVTdHJpZGVkKGlmYWNlLCBXSU5FRDNEUFRfVFJJQU5HTEVMSVNULCBwYXRjaC0+bnVtU2Vnc1swXSAqIHBhdGNoLT5udW1TZWdzWzFdICogMiwgJnBhdGNoLT5zdHJpZGVkKTsKICAgIFRoaXMtPmN1cnJlbnRQYXRjaCA9IE5VTEw7CgogICAgLyogRGVzdHJveSB1bmNhY2hlZCBwYXRjaGVzICovCiAgICBpZighSGFuZGxlKSB7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGF0Y2gtPm1lbSk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGF0Y2gpOwogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vbGlicmFyeS9kZWZhdWx0LmFzcD91cmw9L2xpYnJhcnkvZW4tdXMvZGlyZWN0eDlfYy9kaXJlY3R4L2dyYXBoaWNzL3JlZmVyZW5jZS9kM2QvaW50ZXJmYWNlcy9pZGlyZWN0M2RkZXZpY2U5L0RyYXdUcmlQYXRjaC5hc3AgKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3VHJpUGF0Y2goSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIEhhbmRsZSwgQ09OU1QgZmxvYXQqIHBOdW1TZWdzLCBDT05TVCBXSU5FRDNEVFJJUEFUQ0hfSU5GTyogcFRyaVBhdGNoSW5mbykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgSGFuZGxlKCVkKSBub1NlZ3MoJXApIHRyaXBhdGNoKCVwKVxuIiwgVGhpcywgSGFuZGxlLCBwTnVtU2VncywgcFRyaVBhdGNoSW5mbyk7CiAgICBGSVhNRSgiKCVwKSA6IFN0dWJcbiIsIFRoaXMpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfRGVsZXRlUGF0Y2goSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIEhhbmRsZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaW50IGk7CiAgICBzdHJ1Y3QgV2luZUQzRFJlY3RQYXRjaCAqcGF0Y2g7CiAgICBzdHJ1Y3QgbGlzdCAqZTsKICAgIFRSQUNFKCIoJXApIEhhbmRsZSglZClcbiIsIFRoaXMsIEhhbmRsZSk7CgogICAgaSA9IFBBVENITUFQX0hBU0hGVU5DKEhhbmRsZSk7CiAgICBMSVNUX0ZPUl9FQUNIKGUsICZUaGlzLT5wYXRjaGVzW2ldKSB7CiAgICAgICAgcGF0Y2ggPSBMSVNUX0VOVFJZKGUsIHN0cnVjdCBXaW5lRDNEUmVjdFBhdGNoLCBlbnRyeSk7CiAgICAgICAgaWYocGF0Y2gtPkhhbmRsZSA9PSBIYW5kbGUpIHsKICAgICAgICAgICAgVFJBQ0UoIkRlbGV0aW5nIHBhdGNoICVwXG4iLCBwYXRjaCk7CiAgICAgICAgICAgIGxpc3RfcmVtb3ZlKCZwYXRjaC0+ZW50cnkpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYXRjaC0+bWVtKTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGF0Y2gpOwogICAgICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgICAgICB9CiAgICB9CgogICAgLyogVE9ETzogV3JpdGUgYSB0ZXN0IGZvciB0aGUgcmV0dXJuIHZhbHVlICovCiAgICBGSVhNRSgiQXR0ZW1wdCB0byBkZXN0cm95IG5vbmV4aXN0ZW50IHBhdGNoXG4iKTsKICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwp9CgpzdGF0aWMgSVdpbmVEM0RTd2FwQ2hhaW4gKmdldF9zd2FwY2hhaW4oSVdpbmVEM0RTdXJmYWNlICp0YXJnZXQpIHsKICAgIEhSRVNVTFQgaHI7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcGNoYWluOwoKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcih0YXJnZXQsICZJSURfSVdpbmVEM0RTd2FwQ2hhaW4sICh2b2lkICoqKSZzd2FwY2hhaW4pOwogICAgaWYgKFNVQ0NFRURFRChocikpIHsKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKChJVW5rbm93biAqKXN3YXBjaGFpbik7CiAgICAgICAgcmV0dXJuIHN3YXBjaGFpbjsKICAgIH0KCiAgICByZXR1cm4gTlVMTDsKfQoKc3RhdGljIHZvaWQgYmluZF9mYm8oSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBHTGVudW0gdGFyZ2V0LCBHTHVpbnQgKmZibykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIGlmICghKmZibykgewogICAgICAgIEdMX0VYVENBTEwoZ2xHZW5GcmFtZWJ1ZmZlcnNFWFQoMSwgZmJvKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsR2VuRnJhbWVidWZmZXJzRVhUKCkiKTsKICAgIH0KICAgIEdMX0VYVENBTEwoZ2xCaW5kRnJhbWVidWZmZXJFWFQodGFyZ2V0LCAqZmJvKSk7CiAgICBjaGVja0dMY2FsbCgiZ2xCaW5kRnJhbWVidWZmZXIoKSIpOwp9CgpzdGF0aWMgdm9pZCBhdHRhY2hfc3VyZmFjZV9mYm8oSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzLCBHTGVudW0gZmJvX3RhcmdldCwgRFdPUkQgaWR4LCBJV2luZUQzRFN1cmZhY2UgKnN1cmZhY2UpIHsKICAgIGNvbnN0IElXaW5lRDNEU3VyZmFjZUltcGwgKnN1cmZhY2VfaW1wbCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopc3VyZmFjZTsKICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsICp0ZXh0dXJlX2ltcGw7CiAgICBHTGVudW0gdGV4dHRhcmdldCwgdGFyZ2V0OwogICAgR0xpbnQgb2xkX2JpbmRpbmc7CgogICAgdGV4dHRhcmdldCA9IHN1cmZhY2VfaW1wbC0+Z2xEZXNjcmlwdGlvbi50YXJnZXQ7CiAgICBpZih0ZXh0dGFyZ2V0ID09IEdMX1RFWFRVUkVfMkQpIHsKICAgICAgICB0YXJnZXQgPSBHTF9URVhUVVJFXzJEOwogICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfVEVYVFVSRV9CSU5ESU5HXzJELCAmb2xkX2JpbmRpbmcpOwogICAgfSBlbHNlIGlmKHRleHR0YXJnZXQgPT0gR0xfVEVYVFVSRV9SRUNUQU5HTEVfQVJCKSB7CiAgICAgICAgdGFyZ2V0ID0gR0xfVEVYVFVSRV9SRUNUQU5HTEVfQVJCOwogICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfVEVYVFVSRV9CSU5ESU5HX1JFQ1RBTkdMRV9BUkIsICZvbGRfYmluZGluZyk7CiAgICB9IGVsc2UgewogICAgICAgIHRhcmdldCA9IEdMX1RFWFRVUkVfQ1VCRV9NQVBfQVJCOwogICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfVEVYVFVSRV9CSU5ESU5HX0NVQkVfTUFQX0FSQiwgJm9sZF9iaW5kaW5nKTsKICAgIH0KCiAgICBJV2luZUQzRFN1cmZhY2VfUHJlTG9hZChzdXJmYWNlKTsKCiAgICBnbFRleFBhcmFtZXRlcmkodGFyZ2V0LCBHTF9URVhUVVJFX01JTl9GSUxURVIsIEdMX05FQVJFU1QpOwogICAgZ2xUZXhQYXJhbWV0ZXJpKHRhcmdldCwgR0xfVEVYVFVSRV9NQUdfRklMVEVSLCBHTF9ORUFSRVNUKTsKICAgIGdsQmluZFRleHR1cmUodGFyZ2V0LCBvbGRfYmluZGluZyk7CgogICAgLyogVXBkYXRlIGJhc2UgdGV4dHVyZSBzdGF0ZXMgYXJyYXkgKi8KICAgIGlmIChTVUNDRUVERUQoSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihzdXJmYWNlLCAmSUlEX0lXaW5lRDNEQmFzZVRleHR1cmUsICh2b2lkICoqKSZ0ZXh0dXJlX2ltcGwpKSkgewogICAgICAgIHRleHR1cmVfaW1wbC0+YmFzZVRleHR1cmUuc3RhdGVzW1dJTkVEM0RURVhTVEFfTUlORklMVEVSXSA9IFdJTkVEM0RURVhGX1BPSU5UOwogICAgICAgIHRleHR1cmVfaW1wbC0+YmFzZVRleHR1cmUuc3RhdGVzW1dJTkVEM0RURVhTVEFfTUFHRklMVEVSXSA9IFdJTkVEM0RURVhGX1BPSU5UOwogICAgICAgIGlmICh0ZXh0dXJlX2ltcGwtPmJhc2VUZXh0dXJlLmJpbmRDb3VudCkgewogICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfU0FNUExFUih0ZXh0dXJlX2ltcGwtPmJhc2VUZXh0dXJlLnNhbXBsZXIpKTsKICAgICAgICB9CgogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUmVsZWFzZSgoSVdpbmVEM0RCYXNlVGV4dHVyZSAqKXRleHR1cmVfaW1wbCk7CiAgICB9CgogICAgR0xfRVhUQ0FMTChnbEZyYW1lYnVmZmVyVGV4dHVyZTJERVhUKGZib190YXJnZXQsIEdMX0NPTE9SX0FUVEFDSE1FTlQwX0VYVCArIGlkeCwgdGV4dHRhcmdldCwKICAgICAgICAgICAgc3VyZmFjZV9pbXBsLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lLCBzdXJmYWNlX2ltcGwtPmdsRGVzY3JpcHRpb24ubGV2ZWwpKTsKCiAgICBjaGVja0dMY2FsbCgiYXR0YWNoX3N1cmZhY2VfZmJvIik7Cn0KCnN0YXRpYyB2b2lkIGNvbG9yX2ZpbGxfZmJvKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RTdXJmYWNlICpzdXJmYWNlLCBDT05TVCBXSU5FRDNEUkVDVCAqcmVjdCwgV0lORUQzRENPTE9SIGNvbG9yKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBjaGFpbjsKCiAgICBzd2FwY2hhaW4gPSBnZXRfc3dhcGNoYWluKHN1cmZhY2UpOwogICAgaWYgKHN3YXBjaGFpbikgewogICAgICAgIEdMZW51bSBidWZmZXI7CgogICAgICAgIFRSQUNFKCJTdXJmYWNlICVwIGlzIG9uc2NyZWVuXG4iLCBzdXJmYWNlKTsKCiAgICAgICAgR0xfRVhUQ0FMTChnbEJpbmRGcmFtZWJ1ZmZlckVYVChHTF9GUkFNRUJVRkZFUl9FWFQsIDApKTsKICAgICAgICBidWZmZXIgPSBzdXJmYWNlX2dldF9nbF9idWZmZXIoc3VyZmFjZSwgc3dhcGNoYWluKTsKICAgICAgICBnbERyYXdCdWZmZXIoYnVmZmVyKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKCkiKTsKICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoIlN1cmZhY2UgJXAgaXMgb2Zmc2NyZWVuXG4iLCBzdXJmYWNlKTsKICAgICAgICBiaW5kX2ZibyhpZmFjZSwgR0xfRlJBTUVCVUZGRVJfRVhULCAmVGhpcy0+ZHN0X2Zibyk7CiAgICAgICAgYXR0YWNoX3N1cmZhY2VfZmJvKFRoaXMsIEdMX0ZSQU1FQlVGRkVSX0VYVCwgMCwgc3VyZmFjZSk7CiAgICB9CgogICAgaWYgKHJlY3QpIHsKICAgICAgICBnbEVuYWJsZShHTF9TQ0lTU09SX1RFU1QpOwogICAgICAgIGlmKCFzd2FwY2hhaW4pIHsKICAgICAgICAgICAgZ2xTY2lzc29yKHJlY3QtPngxLCByZWN0LT55MSwgcmVjdC0+eDIgLSByZWN0LT54MSwgcmVjdC0+eTIgLSByZWN0LT55MSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZ2xTY2lzc29yKHJlY3QtPngxLCAoKElXaW5lRDNEU3VyZmFjZUltcGwgKilzdXJmYWNlKS0+Y3VycmVudERlc2MuSGVpZ2h0IC0gcmVjdC0+eTIsCiAgICAgICAgICAgICAgICAgICAgcmVjdC0+eDIgLSByZWN0LT54MSwgcmVjdC0+eTIgLSByZWN0LT55MSk7CiAgICAgICAgfQogICAgICAgIGNoZWNrR0xjYWxsKCJnbFNjaXNzb3IiKTsKICAgIH0gZWxzZSB7CiAgICAgICAgZ2xEaXNhYmxlKEdMX1NDSVNTT1JfVEVTVCk7CiAgICB9CiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19TQ0lTU09SVEVTVEVOQUJMRSkpOwoKICAgIGdsQ29sb3JNYXNrKEdMX1RSVUUsIEdMX1RSVUUsIEdMX1RSVUUsIEdMX1RSVUUpOwogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1JFTkRFUihXSU5FRDNEUlNfQ09MT1JXUklURUVOQUJMRSkpOwoKICAgIGdsQ2xlYXJDb2xvcihEM0RDT0xPUl9SKGNvbG9yKSwgRDNEQ09MT1JfRyhjb2xvciksIEQzRENPTE9SX0IoY29sb3IpLCBEM0RDT0xPUl9BKGNvbG9yKSk7CiAgICBnbENsZWFyKEdMX0NPTE9SX0JVRkZFUl9CSVQpOwogICAgY2hlY2tHTGNhbGwoImdsQ2xlYXIiKTsKCiAgICBpZiAoVGhpcy0+cmVuZGVyX29mZnNjcmVlbikgewogICAgICAgIGJpbmRfZmJvKGlmYWNlLCBHTF9GUkFNRUJVRkZFUl9FWFQsICZUaGlzLT5mYm8pOwogICAgfSBlbHNlIHsKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEZyYW1lYnVmZmVyRVhUKEdMX0ZSQU1FQlVGRkVSX0VYVCwgMCkpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRGcmFtZWJ1ZmZlcigpIik7CiAgICB9CgogICAgaWYgKHN3YXBjaGFpbiAmJiBzdXJmYWNlID09ICgoSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICopc3dhcGNoYWluKS0+ZnJvbnRCdWZmZXIKICAgICAgICAgICAgJiYgKChJV2luZUQzRFN3YXBDaGFpbkltcGwgKilzd2FwY2hhaW4pLT5iYWNrQnVmZmVyKSB7CiAgICAgICAgZ2xEcmF3QnVmZmVyKEdMX0JBQ0spOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoKSIpOwogICAgfQp9CgpzdGF0aWMgaW5saW5lIERXT1JEIGFyZ2JfdG9fZm10KERXT1JEIGNvbG9yLCBXSU5FRDNERk9STUFUIGRlc3RmbXQpIHsKICAgIHVuc2lnbmVkIGludCByLCBnLCBiLCBhOwogICAgRFdPUkQgcmV0OwoKICAgIGlmKGRlc3RmbXQgPT0gV0lORUQzREZNVF9BOFI4RzhCOCB8fCBkZXN0Zm10ID09IFdJTkVEM0RGTVRfWDhSOEc4QjggfHwKICAgICAgIGRlc3RmbXQgPT0gV0lORUQzREZNVF9SOEc4QjgpCiAgICAgICAgcmV0dXJuIGNvbG9yOwoKICAgIFRSQUNFKCJDb252ZXJ0aW5nIGNvbG9yICUwOHggdG8gZm9ybWF0ICVzXG4iLCBjb2xvciwgZGVidWdfZDNkZm9ybWF0KGRlc3RmbXQpKTsKCiAgICBhID0gKGNvbG9yICYgMHhmZjAwMDAwMCkgPj4gMjQ7CiAgICByID0gKGNvbG9yICYgMHgwMGZmMDAwMCkgPj4gMTY7CiAgICBnID0gKGNvbG9yICYgMHgwMDAwZmYwMCkgPj4gIDg7CiAgICBiID0gKGNvbG9yICYgMHgwMDAwMDBmZikgPj4gIDA7CgogICAgc3dpdGNoKGRlc3RmbXQpCiAgICB7CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1I1RzZCNToKICAgICAgICAgICAgaWYociA9PSAweGZmICYmIGcgPT0gMHhmZiAmJiBiID09IDB4ZmYpIHJldHVybiAweGZmZmY7CiAgICAgICAgICAgIHIgPSAociAqIDMyKSAvIDI1NjsKICAgICAgICAgICAgZyA9IChnICogNjQpIC8gMjU2OwogICAgICAgICAgICBiID0gKGIgKiAzMikgLyAyNTY7CiAgICAgICAgICAgIHJldCAgPSByIDw8IDExOwogICAgICAgICAgICByZXQgfD0gZyA8PCA1OwogICAgICAgICAgICByZXQgfD0gYjsKICAgICAgICAgICAgVFJBQ0UoIlJldHVybmluZyAlMDh4XG4iLCByZXQpOwogICAgICAgICAgICByZXR1cm4gcmV0OwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDFSNUc1QjU6CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX0ExUjVHNUI1OgogICAgICAgICAgICBhID0gKGEgKiAgMikgLyAyNTY7CiAgICAgICAgICAgIHIgPSAociAqIDMyKSAvIDI1NjsKICAgICAgICAgICAgZyA9IChnICogMzIpIC8gMjU2OwogICAgICAgICAgICBiID0gKGIgKiAzMikgLyAyNTY7CiAgICAgICAgICAgIHJldCAgPSBhIDw8IDE1OwogICAgICAgICAgICByZXQgfD0gciA8PCAxMDsKICAgICAgICAgICAgcmV0IHw9IGcgPDwgIDU7CiAgICAgICAgICAgIHJldCB8PSBiIDw8ICAwOwogICAgICAgICAgICBUUkFDRSgiUmV0dXJuaW5nICUwOHhcbiIsIHJldCk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9BODoKICAgICAgICAgICAgVFJBQ0UoIlJldHVybmluZyAlMDh4XG4iLCBhKTsKICAgICAgICAgICAgcmV0dXJuIGE7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9YNFI0RzRCNDoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQTRSNEc0QjQ6CiAgICAgICAgICAgIGEgPSAoYSAqIDE2KSAvIDI1NjsKICAgICAgICAgICAgciA9IChyICogMTYpIC8gMjU2OwogICAgICAgICAgICBnID0gKGcgKiAxNikgLyAyNTY7CiAgICAgICAgICAgIGIgPSAoYiAqIDE2KSAvIDI1NjsKICAgICAgICAgICAgcmV0ICA9IGEgPDwgMTI7CiAgICAgICAgICAgIHJldCB8PSByIDw8ICA4OwogICAgICAgICAgICByZXQgfD0gZyA8PCAgNDsKICAgICAgICAgICAgcmV0IHw9IGIgPDwgIDA7CiAgICAgICAgICAgIFRSQUNFKCJSZXR1cm5pbmcgJTA4eFxuIiwgcmV0KTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1IzRzNCMjoKICAgICAgICAgICAgciA9IChyICogOCkgLyAyNTY7CiAgICAgICAgICAgIGcgPSAoZyAqIDgpIC8gMjU2OwogICAgICAgICAgICBiID0gKGIgKiA0KSAvIDI1NjsKICAgICAgICAgICAgcmV0ICA9IHIgPDwgIDU7CiAgICAgICAgICAgIHJldCB8PSBnIDw8ICAyOwogICAgICAgICAgICByZXQgfD0gYiA8PCAgMDsKICAgICAgICAgICAgVFJBQ0UoIlJldHVybmluZyAlMDh4XG4iLCByZXQpOwogICAgICAgICAgICByZXR1cm4gcmV0OwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDhCOEc4Ujg6CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX0E4QjhHOFI4OgogICAgICAgICAgICByZXQgID0gYSA8PCAyNDsKICAgICAgICAgICAgcmV0IHw9IGIgPDwgMTY7CiAgICAgICAgICAgIHJldCB8PSBnIDw8ICA4OwogICAgICAgICAgICByZXQgfD0gciA8PCAgMDsKICAgICAgICAgICAgVFJBQ0UoIlJldHVybmluZyAlMDh4XG4iLCByZXQpOwogICAgICAgICAgICByZXR1cm4gcmV0OwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQTJSMTBHMTBCMTA6CiAgICAgICAgICAgIGEgPSAoYSAqICAgIDQpIC8gMjU2OwogICAgICAgICAgICByID0gKHIgKiAxMDI0KSAvIDI1NjsKICAgICAgICAgICAgZyA9IChnICogMTAyNCkgLyAyNTY7CiAgICAgICAgICAgIGIgPSAoYiAqIDEwMjQpIC8gMjU2OwogICAgICAgICAgICByZXQgID0gYSA8PCAzMDsKICAgICAgICAgICAgcmV0IHw9IHIgPDwgMjA7CiAgICAgICAgICAgIHJldCB8PSBnIDw8IDEwOwogICAgICAgICAgICByZXQgfD0gYiA8PCAgMDsKICAgICAgICAgICAgVFJBQ0UoIlJldHVybmluZyAlMDh4XG4iLCByZXQpOwogICAgICAgICAgICByZXR1cm4gcmV0OwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQTJCMTBHMTBSMTA6CiAgICAgICAgICAgIGEgPSAoYSAqICAgIDQpIC8gMjU2OwogICAgICAgICAgICByID0gKHIgKiAxMDI0KSAvIDI1NjsKICAgICAgICAgICAgZyA9IChnICogMTAyNCkgLyAyNTY7CiAgICAgICAgICAgIGIgPSAoYiAqIDEwMjQpIC8gMjU2OwogICAgICAgICAgICByZXQgID0gYSA8PCAzMDsKICAgICAgICAgICAgcmV0IHw9IGIgPDwgMjA7CiAgICAgICAgICAgIHJldCB8PSBnIDw8IDEwOwogICAgICAgICAgICByZXQgfD0gciA8PCAgMDsKICAgICAgICAgICAgVFJBQ0UoIlJldHVybmluZyAlMDh4XG4iLCByZXQpOwogICAgICAgICAgICByZXR1cm4gcmV0OwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBGSVhNRSgiQWRkIGEgQ09MT1JGSUxMIGNvbnZlcnNpb24gZm9yIGZvcm1hdCAlc1xuIiwgZGVidWdfZDNkZm9ybWF0KGRlc3RmbXQpKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICB9Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ29sb3JGaWxsKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RTdXJmYWNlICpwU3VyZmFjZSwgQ09OU1QgV0lORUQzRFJFQ1QqIHBSZWN0LCBXSU5FRDNEQ09MT1IgY29sb3IpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpzdXJmYWNlID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgcFN1cmZhY2U7CiAgICBXSU5FRERCTFRGWCBCbHRGeDsKICAgIFRSQUNFKCIoJXApIENvbG91ciBmaWxsIFN1cmZhY2U6ICVwIHJlY3Q6ICVwIGNvbG9yOiAweCUwOHhcbiIsIFRoaXMsIHBTdXJmYWNlLCBwUmVjdCwgY29sb3IpOwoKICAgIGlmIChzdXJmYWNlLT5yZXNvdXJjZS5wb29sICE9IFdJTkVEM0RQT09MX0RFRkFVTFQgJiYgc3VyZmFjZS0+cmVzb3VyY2UucG9vbCAhPSBXSU5FRDNEUE9PTF9TWVNURU1NRU0pIHsKICAgICAgICBGSVhNRSgiY2FsbCB0byBjb2xvcmZpbGwgd2l0aCBub24gV0lORUQzRFBPT0xfREVGQVVMVCBvciBXSU5FRDNEUE9PTF9TWVNURU1NRU0gc3VyZmFjZVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYgKHdpbmVkM2Rfc2V0dGluZ3Mub2Zmc2NyZWVuX3JlbmRlcmluZ19tb2RlID09IE9STV9GQk8pIHsKICAgICAgICBjb2xvcl9maWxsX2ZibyhpZmFjZSwgcFN1cmZhY2UsIHBSZWN0LCBjb2xvcik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9IGVsc2UgewogICAgICAgIC8qIEp1c3QgZm9yd2FyZCB0aGlzIHRvIHRoZSBEaXJlY3REcmF3IGJsaXR0aW5nIGVuZ2luZSAqLwogICAgICAgIG1lbXNldCgmQmx0RngsIDAsIHNpemVvZihCbHRGeCkpOwogICAgICAgIEJsdEZ4LmR3U2l6ZSA9IHNpemVvZihCbHRGeCk7CiAgICAgICAgQmx0RngudTUuZHdGaWxsQ29sb3IgPSBhcmdiX3RvX2ZtdChjb2xvciwgc3VyZmFjZS0+cmVzb3VyY2UuZm9ybWF0KTsKICAgICAgICByZXR1cm4gSVdpbmVEM0RTdXJmYWNlX0JsdChwU3VyZmFjZSwgKFJFQ1QgKikgcFJlY3QsIE5VTEwsIE5VTEwsIFdJTkVEREJMVF9DT0xPUkZJTEwsICZCbHRGeCwgV0lORUQzRFRFWEZfTk9ORSk7CiAgICB9Cn0KCi8qIHJlbmRlcnRhcmdldCBhbmQgZGVwdHRoIHN0ZW5jaWwgZnVuY3Rpb25zICovCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRSZW5kZXJUYXJnZXQoSVdpbmVEM0REZXZpY2UqIGlmYWNlLERXT1JEIFJlbmRlclRhcmdldEluZGV4LCBJV2luZUQzRFN1cmZhY2UgKipwcFJlbmRlclRhcmdldCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIGlmIChSZW5kZXJUYXJnZXRJbmRleCA+PSBHTF9MSU1JVFMoYnVmZmVycykpIHsKICAgICAgICBFUlIoIiglcCkgOiBPbmx5ICVkIHJlbmRlciB0YXJnZXRzIGFyZSBzdXBwb3J0ZWQuXG4iLCBUaGlzLCBHTF9MSU1JVFMoYnVmZmVycykpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgICpwcFJlbmRlclRhcmdldCA9IFRoaXMtPnJlbmRlcl90YXJnZXRzW1JlbmRlclRhcmdldEluZGV4XTsKICAgIFRSQUNFKCIoJXApIDogUmVuZGVyVGFyZ2V0ICVkIEluZGV4IHJldHVybmluZyAlcFxuIiwgVGhpcywgUmVuZGVyVGFyZ2V0SW5kZXgsICpwcFJlbmRlclRhcmdldCk7CiAgICAvKiBOb3RlIGluYyByZWYgb24gcmV0dXJuZWQgc3VyZmFjZSAqLwogICAgaWYoKnBwUmVuZGVyVGFyZ2V0ICE9IE5VTEwpCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0FkZFJlZigqcHBSZW5kZXJUYXJnZXQpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0RnJvbnRCYWNrQnVmZmVycyhJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEU3VyZmFjZSAqRnJvbnQsIElXaW5lRDNEU3VyZmFjZSAqQmFjaykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqRnJvbnRJbXBsID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgRnJvbnQ7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpCYWNrSW1wbCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIEJhY2s7CiAgICBJV2luZUQzRFN3YXBDaGFpbkltcGwgKlN3YXBjaGFpbjsKICAgIEhSRVNVTFQgaHI7CgogICAgVFJBQ0UoIiglcCktPiglcCwlcClcbiIsIFRoaXMsIEZyb250SW1wbCwgQmFja0ltcGwpOwoKICAgIGhyID0gSVdpbmVEM0REZXZpY2VfR2V0U3dhcENoYWluKGlmYWNlLCAwLCAoSVdpbmVEM0RTd2FwQ2hhaW4gKiopICZTd2FwY2hhaW4pOwogICAgaWYoaHIgIT0gV0lORUQzRF9PSykgewogICAgICAgIEVSUigiQ2FuJ3QgZ2V0IHRoZSBzd2FwY2hhaW5cbiIpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICAvKiBNYWtlIHN1cmUgdG8gcmVsZWFzZSB0aGUgc3dhcGNoYWluICovCiAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKChJV2luZUQzRFN3YXBDaGFpbiAqKSBTd2FwY2hhaW4pOwoKICAgIGlmKEZyb250SW1wbCAmJiAhKEZyb250SW1wbC0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSApIHsKICAgICAgICBFUlIoIlRyeWluZyB0byBzZXQgYSBmcm9udCBidWZmZXIgd2hpY2ggZG9lc24ndCBoYXZlIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQgdXNhZ2VcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgZWxzZSBpZihCYWNrSW1wbCAmJiAhKEJhY2tJbXBsLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpKSB7CiAgICAgICAgRVJSKCJUcnlpbmcgdG8gc2V0IGEgYmFjayBidWZmZXIgd2hpY2ggZG9lc24ndCBoYXZlIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQgdXNhZ2VcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmKFN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIgIT0gRnJvbnQpIHsKICAgICAgICBUUkFDRSgiQ2hhbmdpbmcgdGhlIGZyb250IGJ1ZmZlciBmcm9tICVwIHRvICVwXG4iLCBTd2FwY2hhaW4tPmZyb250QnVmZmVyLCBGcm9udCk7CgogICAgICAgIGlmKFN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIpCiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb250YWluZXIoU3dhcGNoYWluLT5mcm9udEJ1ZmZlciwgTlVMTCk7CiAgICAgICAgU3dhcGNoYWluLT5mcm9udEJ1ZmZlciA9IEZyb250OwoKICAgICAgICBpZihTd2FwY2hhaW4tPmZyb250QnVmZmVyKSB7CiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb250YWluZXIoU3dhcGNoYWluLT5mcm9udEJ1ZmZlciwgKElXaW5lRDNEQmFzZSAqKSBTd2FwY2hhaW4pOwogICAgICAgIH0KICAgIH0KCiAgICBpZihCYWNrICYmICFTd2FwY2hhaW4tPmJhY2tCdWZmZXIpIHsKICAgICAgICAvKiBXZSBuZWVkIG1lbW9yeSBmb3IgdGhlIGJhY2sgYnVmZmVyIGFycmF5IC0gb25seSBvbmUgYmFjayBidWZmZXIgdGhpcyB3YXkgKi8KICAgICAgICBTd2FwY2hhaW4tPmJhY2tCdWZmZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElXaW5lRDNEU3VyZmFjZSAqKSk7CiAgICAgICAgaWYoIVN3YXBjaGFpbi0+YmFja0J1ZmZlcikgewogICAgICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnlcbiIpOwogICAgICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgICAgICB9CiAgICB9CgogICAgaWYoU3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdICE9IEJhY2spIHsKICAgICAgICBUUkFDRSgiQ2hhbmdpbmcgdGhlIGJhY2sgYnVmZmVyIGZyb20gJXAgdG8gJXBcbiIsIFN3YXBjaGFpbi0+YmFja0J1ZmZlciwgQmFjayk7CgogICAgICAgIC8qIFdoYXQgdG8gZG8gYWJvdXQgdGhlIGNvbnRleHQgaGVyZSBpbiB0aGUgY2FzZSBvZiBtdWx0aXRocmVhZGluZz8gTm90IHN1cmUuCiAgICAgICAgICogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYnkgSURpcmVjdDNENzo6Q3JlYXRlRGV2aWNlIHNvIGluIHRoZW9yeSBpdHMgaW5pdGlhbGl6YXRpb24gY29kZQogICAgICAgICAqLwogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgaWYoIVN3YXBjaGFpbi0+YmFja0J1ZmZlclswXSkgewogICAgICAgICAgICAvKiBHTCB3YXMgdG9sZCB0byBkcmF3IHRvIHRoZSBmcm9udCBidWZmZXIgYXQgY3JlYXRpb24sCiAgICAgICAgICAgICAqIHVuZG8gdGhhdAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZ2xEcmF3QnVmZmVyKEdMX0JBQ0spOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKEdMX0JBQ0spIik7CiAgICAgICAgICAgIC8qIFNldCB0aGUgYmFja2J1ZmZlciBjb3VudCB0byAxIGJlY2F1c2Ugb3RoZXIgY29kZSB1c2VzIGl0IHRvIGZpbmcgdGhlIGJhY2sgYnVmZmVycyAqLwogICAgICAgICAgICBTd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyQ291bnQgPSAxOwogICAgICAgIH0gZWxzZSBpZiAoIUJhY2spIHsKICAgICAgICAgICAgLyogVGhhdCBtYWtlcyBwcm9ibGVtcyAtIGRpc2FibGUgZm9yIG5vdyAqLwogICAgICAgICAgICAvKiBnbERyYXdCdWZmZXIoR0xfRlJPTlQpOyAqLwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKEdMX0ZST05UKSIpOwogICAgICAgICAgICAvKiBXZSBoYXZlIGxvc3Qgb3VyIGJhY2sgYnVmZmVyLCBzZXQgdGhpcyB0byAwIHRvIGF2b2lkIGNvbmZ1c2luZyBvdGhlciBjb2RlICovCiAgICAgICAgICAgIFN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJDb3VudCA9IDA7CiAgICAgICAgfQogICAgICAgIExFQVZFX0dMKCk7CgogICAgICAgIGlmKFN3YXBjaGFpbi0+YmFja0J1ZmZlclswXSkKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbnRhaW5lcihTd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0sIE5VTEwpOwogICAgICAgIFN3YXBjaGFpbi0+YmFja0J1ZmZlclswXSA9IEJhY2s7CgogICAgICAgIGlmKFN3YXBjaGFpbi0+YmFja0J1ZmZlclswXSkgewogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29udGFpbmVyKFN3YXBjaGFpbi0+YmFja0J1ZmZlclswXSwgKElXaW5lRDNEQmFzZSAqKSBTd2FwY2hhaW4pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFN3YXBjaGFpbi0+YmFja0J1ZmZlcik7CiAgICAgICAgICAgIFN3YXBjaGFpbi0+YmFja0J1ZmZlciA9IE5VTEw7CiAgICAgICAgfQoKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0dldERlcHRoU3RlbmNpbFN1cmZhY2UoSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBJV2luZUQzRFN1cmZhY2UgKipwcFpTdGVuY2lsU3VyZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgKnBwWlN0ZW5jaWxTdXJmYWNlID0gVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldDsKICAgIFRSQUNFKCIoJXApIDogelN0ZW5jaWxTdXJmYWNlICByZXR1cm5pbmcgJXBcbiIsIFRoaXMsICAqcHBaU3RlbmNpbFN1cmZhY2UpOwoKICAgIGlmKCpwcFpTdGVuY2lsU3VyZmFjZSAhPSBOVUxMKSB7CiAgICAgICAgLyogTm90ZSBpbmMgcmVmIG9uIHJldHVybmVkIHN1cmZhY2UgKi8KICAgICAgICBJV2luZUQzRFN1cmZhY2VfQWRkUmVmKCpwcFpTdGVuY2lsU3VyZmFjZSk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBXSU5FRDNERVJSX05PVEZPVU5EOwogICAgfQp9CgovKiBUT0RPOiBIYW5kbGUgc3RlbmNpbCBhdHRhY2htZW50cyAqLwpzdGF0aWMgdm9pZCBzZXRfZGVwdGhfc3RlbmNpbF9mYm8oSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFN1cmZhY2UgKmRlcHRoX3N0ZW5jaWwpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKmRlcHRoX3N0ZW5jaWxfaW1wbCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopZGVwdGhfc3RlbmNpbDsKCiAgICBUUkFDRSgiU2V0IGRlcHRoIHN0ZW5jaWwgdG8gJXBcbiIsIGRlcHRoX3N0ZW5jaWwpOwoKICAgIGlmIChkZXB0aF9zdGVuY2lsX2ltcGwpIHsKICAgICAgICBpZiAoZGVwdGhfc3RlbmNpbF9pbXBsLT5jdXJyZW50X3JlbmRlcmJ1ZmZlcikgewogICAgICAgICAgICBHTF9FWFRDQUxMKGdsRnJhbWVidWZmZXJSZW5kZXJidWZmZXJFWFQoR0xfRlJBTUVCVUZGRVJfRVhULCBHTF9ERVBUSF9BVFRBQ0hNRU5UX0VYVCwgR0xfUkVOREVSQlVGRkVSX0VYVCwgZGVwdGhfc3RlbmNpbF9pbXBsLT5jdXJyZW50X3JlbmRlcmJ1ZmZlci0+aWQpKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRnJhbWVidWZmZXJSZW5kZXJidWZmZXJFWFQoKSIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsICp0ZXh0dXJlX2ltcGw7CiAgICAgICAgICAgIEdMZW51bSB0ZXh0dGFyZ2V0LCB0YXJnZXQ7CiAgICAgICAgICAgIEdMaW50IG9sZF9iaW5kaW5nID0gMDsKCiAgICAgICAgICAgIHRleHR0YXJnZXQgPSBkZXB0aF9zdGVuY2lsX2ltcGwtPmdsRGVzY3JpcHRpb24udGFyZ2V0OwogICAgICAgICAgICBpZih0ZXh0dGFyZ2V0ID09IEdMX1RFWFRVUkVfMkQpIHsKICAgICAgICAgICAgICAgIHRhcmdldCA9IEdMX1RFWFRVUkVfMkQ7CiAgICAgICAgICAgICAgICBnbEdldEludGVnZXJ2KEdMX1RFWFRVUkVfQklORElOR18yRCwgJm9sZF9iaW5kaW5nKTsKICAgICAgICAgICAgfSBlbHNlIGlmKHRleHR0YXJnZXQgPT0gR0xfVEVYVFVSRV9SRUNUQU5HTEVfQVJCKSB7CiAgICAgICAgICAgICAgICB0YXJnZXQgPSBHTF9URVhUVVJFX1JFQ1RBTkdMRV9BUkI7CiAgICAgICAgICAgICAgICBnbEdldEludGVnZXJ2KEdMX1RFWFRVUkVfQklORElOR19SRUNUQU5HTEVfQVJCLCAmb2xkX2JpbmRpbmcpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdGFyZ2V0ID0gR0xfVEVYVFVSRV9DVUJFX01BUF9BUkI7CiAgICAgICAgICAgICAgICBnbEdldEludGVnZXJ2KEdMX1RFWFRVUkVfQklORElOR19DVUJFX01BUF9BUkIsICZvbGRfYmluZGluZyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9QcmVMb2FkKGRlcHRoX3N0ZW5jaWwpOwoKICAgICAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKHRhcmdldCwgR0xfVEVYVFVSRV9NSU5fRklMVEVSLCBHTF9ORUFSRVNUKTsKICAgICAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKHRhcmdldCwgR0xfVEVYVFVSRV9NQUdfRklMVEVSLCBHTF9ORUFSRVNUKTsKICAgICAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKHRhcmdldCwgR0xfREVQVEhfVEVYVFVSRV9NT0RFX0FSQiwgR0xfTFVNSU5BTkNFKTsKICAgICAgICAgICAgZ2xCaW5kVGV4dHVyZSh0YXJnZXQsIG9sZF9iaW5kaW5nKTsKCiAgICAgICAgICAgIC8qIFVwZGF0ZSBiYXNlIHRleHR1cmUgc3RhdGVzIGFycmF5ICovCiAgICAgICAgICAgIGlmIChTVUNDRUVERUQoSVdpbmVEM0RTdXJmYWNlX0dldENvbnRhaW5lcihkZXB0aF9zdGVuY2lsLCAmSUlEX0lXaW5lRDNEQmFzZVRleHR1cmUsICh2b2lkICoqKSZ0ZXh0dXJlX2ltcGwpKSkgewogICAgICAgICAgICAgICAgdGV4dHVyZV9pbXBsLT5iYXNlVGV4dHVyZS5zdGF0ZXNbV0lORUQzRFRFWFNUQV9NSU5GSUxURVJdID0gV0lORUQzRFRFWEZfUE9JTlQ7CiAgICAgICAgICAgICAgICB0ZXh0dXJlX2ltcGwtPmJhc2VUZXh0dXJlLnN0YXRlc1tXSU5FRDNEVEVYU1RBX01BR0ZJTFRFUl0gPSBXSU5FRDNEVEVYRl9QT0lOVDsKICAgICAgICAgICAgICAgIGlmICh0ZXh0dXJlX2ltcGwtPmJhc2VUZXh0dXJlLmJpbmRDb3VudCkgewogICAgICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TQU1QTEVSKHRleHR1cmVfaW1wbC0+YmFzZVRleHR1cmUuc2FtcGxlcikpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUmVsZWFzZSgoSVdpbmVEM0RCYXNlVGV4dHVyZSAqKXRleHR1cmVfaW1wbCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xGcmFtZWJ1ZmZlclRleHR1cmUyREVYVChHTF9GUkFNRUJVRkZFUl9FWFQsIEdMX0RFUFRIX0FUVEFDSE1FTlRfRVhULCB0ZXh0dGFyZ2V0LAogICAgICAgICAgICAgICAgICAgIGRlcHRoX3N0ZW5jaWxfaW1wbC0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSwgZGVwdGhfc3RlbmNpbF9pbXBsLT5nbERlc2NyaXB0aW9uLmxldmVsKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEZyYW1lYnVmZmVyVGV4dHVyZTJERVhUKCkiKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIEdMX0VYVENBTEwoZ2xGcmFtZWJ1ZmZlclRleHR1cmUyREVYVChHTF9GUkFNRUJVRkZFUl9FWFQsIEdMX0RFUFRIX0FUVEFDSE1FTlRfRVhULCBHTF9URVhUVVJFXzJELCAwLCAwKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRnJhbWVidWZmZXJUZXh0dXJlMkRFWFQoKSIpOwogICAgfQp9CgpzdGF0aWMgdm9pZCBzZXRfcmVuZGVyX3RhcmdldF9mYm8oSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBpZHgsIElXaW5lRDNEU3VyZmFjZSAqcmVuZGVyX3RhcmdldCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqcnRpbXBsID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilyZW5kZXJfdGFyZ2V0OwoKICAgIFRSQUNFKCJTZXQgcmVuZGVyIHRhcmdldCAldSB0byAlcFxuIiwgaWR4LCByZW5kZXJfdGFyZ2V0KTsKCiAgICBpZiAocnRpbXBsKSB7CiAgICAgICAgYXR0YWNoX3N1cmZhY2VfZmJvKFRoaXMsIEdMX0ZSQU1FQlVGRkVSX0VYVCwgaWR4LCByZW5kZXJfdGFyZ2V0KTsKICAgICAgICBUaGlzLT5kcmF3X2J1ZmZlcnNbaWR4XSA9IEdMX0NPTE9SX0FUVEFDSE1FTlQwX0VYVCArIGlkeDsKICAgIH0gZWxzZSB7CiAgICAgICAgR0xfRVhUQ0FMTChnbEZyYW1lYnVmZmVyVGV4dHVyZTJERVhUKEdMX0ZSQU1FQlVGRkVSX0VYVCwgR0xfQ09MT1JfQVRUQUNITUVOVDBfRVhUICsgaWR4LCBHTF9URVhUVVJFXzJELCAwLCAwKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRnJhbWVidWZmZXJUZXh0dXJlMkRFWFQoKSIpOwoKICAgICAgICBUaGlzLT5kcmF3X2J1ZmZlcnNbaWR4XSA9IEdMX05PTkU7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIGNoZWNrX2Zib19zdGF0dXMoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBHTGVudW0gc3RhdHVzOwoKICAgIHN0YXR1cyA9IEdMX0VYVENBTEwoZ2xDaGVja0ZyYW1lYnVmZmVyU3RhdHVzRVhUKEdMX0ZSQU1FQlVGRkVSX0VYVCkpOwogICAgaWYgKHN0YXR1cyA9PSBHTF9GUkFNRUJVRkZFUl9DT01QTEVURV9FWFQpIHsKICAgICAgICBUUkFDRSgiRkJPIGNvbXBsZXRlXG4iKTsKICAgIH0gZWxzZSB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqYXR0YWNobWVudDsKICAgICAgICBpbnQgaTsKICAgICAgICBGSVhNRSgiRkJPIHN0YXR1cyAlcyAoJSN4KVxuIiwgZGVidWdfZmJvc3RhdHVzKHN0YXR1cyksIHN0YXR1cyk7CgogICAgICAgIC8qIER1bXAgdGhlIEZCTyBhdHRhY2htZW50cyAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBHTF9MSU1JVFMoYnVmZmVycyk7ICsraSkgewogICAgICAgICAgICBhdHRhY2htZW50ID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilUaGlzLT5mYm9fY29sb3JfYXR0YWNobWVudHNbaV07CiAgICAgICAgICAgIGlmIChhdHRhY2htZW50KSB7CiAgICAgICAgICAgICAgICBGSVhNRSgiXHRDb2xvciBhdHRhY2htZW50ICVkOiAoJXApICVzICV1eCV1XG4iLCBpLCBhdHRhY2htZW50LCBkZWJ1Z19kM2Rmb3JtYXQoYXR0YWNobWVudC0+cmVzb3VyY2UuZm9ybWF0KSwKICAgICAgICAgICAgICAgICAgICAgICAgYXR0YWNobWVudC0+cG93MldpZHRoLCBhdHRhY2htZW50LT5wb3cySGVpZ2h0KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBhdHRhY2htZW50ID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilUaGlzLT5mYm9fZGVwdGhfYXR0YWNobWVudDsKICAgICAgICBpZiAoYXR0YWNobWVudCkgewogICAgICAgICAgICBGSVhNRSgiXHREZXB0aCBhdHRhY2htZW50OiAoJXApICVzICV1eCV1XG4iLCBhdHRhY2htZW50LCBkZWJ1Z19kM2Rmb3JtYXQoYXR0YWNobWVudC0+cmVzb3VyY2UuZm9ybWF0KSwKICAgICAgICAgICAgICAgICAgICBhdHRhY2htZW50LT5wb3cyV2lkdGgsIGF0dGFjaG1lbnQtPnBvdzJIZWlnaHQpOwogICAgICAgIH0KICAgIH0KfQoKc3RhdGljIEJPT0wgZGVwdGhfbWlzbWF0Y2hfZmJvKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqcnRfaW1wbCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopVGhpcy0+cmVuZGVyX3RhcmdldHNbMF07CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpkc19pbXBsID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0OwoKICAgIGlmICghZHNfaW1wbCkgcmV0dXJuIEZBTFNFOwoKICAgIGlmIChkc19pbXBsLT5jdXJyZW50X3JlbmRlcmJ1ZmZlcikgewogICAgICAgIHJldHVybiAocnRfaW1wbC0+cG93MldpZHRoICE9IGRzX2ltcGwtPmN1cnJlbnRfcmVuZGVyYnVmZmVyLT53aWR0aCB8fAogICAgICAgICAgICAgICAgcnRfaW1wbC0+cG93MkhlaWdodCAhPSBkc19pbXBsLT5jdXJyZW50X3JlbmRlcmJ1ZmZlci0+aGVpZ2h0KTsKICAgIH0KCiAgICByZXR1cm4gKHJ0X2ltcGwtPnBvdzJXaWR0aCAhPSBkc19pbXBsLT5wb3cyV2lkdGggfHwKICAgICAgICAgICAgcnRfaW1wbC0+cG93MkhlaWdodCAhPSBkc19pbXBsLT5wb3cySGVpZ2h0KTsKfQoKdm9pZCBhcHBseV9mYm9fc3RhdGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICB1bnNpZ25lZCBpbnQgaTsKCiAgICBpZiAoVGhpcy0+cmVuZGVyX29mZnNjcmVlbikgewogICAgICAgIGJpbmRfZmJvKGlmYWNlLCBHTF9GUkFNRUJVRkZFUl9FWFQsICZUaGlzLT5mYm8pOwoKICAgICAgICAvKiBBcHBseSByZW5kZXIgdGFyZ2V0cyAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBHTF9MSU1JVFMoYnVmZmVycyk7ICsraSkgewogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2UgKnJlbmRlcl90YXJnZXQgPSBUaGlzLT5yZW5kZXJfdGFyZ2V0c1tpXTsKICAgICAgICAgICAgaWYgKFRoaXMtPmZib19jb2xvcl9hdHRhY2htZW50c1tpXSAhPSByZW5kZXJfdGFyZ2V0KSB7CiAgICAgICAgICAgICAgICBzZXRfcmVuZGVyX3RhcmdldF9mYm8oaWZhY2UsIGksIHJlbmRlcl90YXJnZXQpOwogICAgICAgICAgICAgICAgVGhpcy0+ZmJvX2NvbG9yX2F0dGFjaG1lbnRzW2ldID0gcmVuZGVyX3RhcmdldDsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyogQXBwbHkgZGVwdGggdGFyZ2V0cyAqLwogICAgICAgIGlmIChUaGlzLT5mYm9fZGVwdGhfYXR0YWNobWVudCAhPSBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0IHx8IGRlcHRoX21pc21hdGNoX2ZibyhpZmFjZSkpIHsKICAgICAgICAgICAgdW5zaWduZWQgaW50IHcgPSAoKElXaW5lRDNEU3VyZmFjZUltcGwgKilUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXSktPnBvdzJXaWR0aDsKICAgICAgICAgICAgdW5zaWduZWQgaW50IGggPSAoKElXaW5lRDNEU3VyZmFjZUltcGwgKilUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXSktPnBvdzJIZWlnaHQ7CgogICAgICAgICAgICBpZiAoVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCkgewogICAgICAgICAgICAgICAgc3VyZmFjZV9zZXRfY29tcGF0aWJsZV9yZW5kZXJidWZmZXIoVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCwgdywgaCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2V0X2RlcHRoX3N0ZW5jaWxfZmJvKGlmYWNlLCBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KTsKICAgICAgICAgICAgVGhpcy0+ZmJvX2RlcHRoX2F0dGFjaG1lbnQgPSBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0OwogICAgICAgIH0KCiAgICAgICAgaWYgKEdMX1NVUFBPUlQoQVJCX0RSQVdfQlVGRkVSUykpIHsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbERyYXdCdWZmZXJzQVJCKEdMX0xJTUlUUyhidWZmZXJzKSwgVGhpcy0+ZHJhd19idWZmZXJzKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXJzKCkiKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBnbERyYXdCdWZmZXIoVGhpcy0+ZHJhd19idWZmZXJzWzBdKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcigpIik7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEZyYW1lYnVmZmVyRVhUKEdMX0ZSQU1FQlVGRkVSX0VYVCwgMCkpOwogICAgfQoKICAgIGNoZWNrX2Zib19zdGF0dXMoaWZhY2UpOwp9Cgp2b2lkIHN0cmV0Y2hfcmVjdF9mYm8oSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFN1cmZhY2UgKnNyY19zdXJmYWNlLCBXSU5FRDNEUkVDVCAqc3JjX3JlY3QsCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlICpkc3Rfc3VyZmFjZSwgV0lORUQzRFJFQ1QgKmRzdF9yZWN0LCBjb25zdCBXSU5FRDNEVEVYVFVSRUZJTFRFUlRZUEUgZmlsdGVyLCBCT09MIGZsaXApIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIEdMYml0ZmllbGQgbWFzayA9IEdMX0NPTE9SX0JVRkZFUl9CSVQ7IC8qIFRPRE86IFN1cHBvcnQgYmxpdHRpbmcgZGVwdGgvc3RlbmNpbCBzdXJmYWNlcyAqLwogICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnNyY19zd2FwY2hhaW4sICpkc3Rfc3dhcGNoYWluOwogICAgR0xlbnVtIGdsX2ZpbHRlcjsKCiAgICBUUkFDRSgiKCVwKSA6IHNyY19zdXJmYWNlICVwLCBzcmNfcmVjdCAlcCwgZHN0X3N1cmZhY2UgJXAsIGRzdF9yZWN0ICVwLCBmaWx0ZXIgJXMgKDB4JTA4eCksIGZsaXAgJXVcbiIsCiAgICAgICAgICAgIFRoaXMsIHNyY19zdXJmYWNlLCBzcmNfcmVjdCwgZHN0X3N1cmZhY2UsIGRzdF9yZWN0LCBkZWJ1Z19kM2R0ZXh0dXJlZmlsdGVydHlwZShmaWx0ZXIpLCBmaWx0ZXIsIGZsaXApOwogICAgVFJBQ0UoInNyY19yZWN0IFsldSwgJXVdLT5bJXUsICV1XVxuIiwgc3JjX3JlY3QtPngxLCBzcmNfcmVjdC0+eTEsIHNyY19yZWN0LT54Miwgc3JjX3JlY3QtPnkyKTsKICAgIFRSQUNFKCJkc3RfcmVjdCBbJXUsICV1XS0+WyV1LCAldV1cbiIsIGRzdF9yZWN0LT54MSwgZHN0X3JlY3QtPnkxLCBkc3RfcmVjdC0+eDIsIGRzdF9yZWN0LT55Mik7CgogICAgc3dpdGNoIChmaWx0ZXIpIHsKICAgICAgICBjYXNlIFdJTkVEM0RURVhGX0xJTkVBUjoKICAgICAgICAgICAgZ2xfZmlsdGVyID0gR0xfTElORUFSOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRklYTUUoIlVuc3VwcG9ydGVkIGZpbHRlciBtb2RlICVzICgweCUwOHgpXG4iLCBkZWJ1Z19kM2R0ZXh0dXJlZmlsdGVydHlwZShmaWx0ZXIpLCBmaWx0ZXIpOwogICAgICAgIGNhc2UgV0lORUQzRFRFWEZfTk9ORToKICAgICAgICBjYXNlIFdJTkVEM0RURVhGX1BPSU5UOgogICAgICAgICAgICBnbF9maWx0ZXIgPSBHTF9ORUFSRVNUOwogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICAvKiBBdHRhY2ggc3JjIHN1cmZhY2UgdG8gc3JjIGZibyAqLwogICAgc3JjX3N3YXBjaGFpbiA9IGdldF9zd2FwY2hhaW4oc3JjX3N1cmZhY2UpOwogICAgaWYgKHNyY19zd2FwY2hhaW4pIHsKICAgICAgICBHTGVudW0gYnVmZmVyOwoKICAgICAgICBUUkFDRSgiU291cmNlIHN1cmZhY2UgJXAgaXMgb25zY3JlZW5cbiIsIHNyY19zdXJmYWNlKTsKICAgICAgICBBY3RpdmF0ZUNvbnRleHQoVGhpcywgc3JjX3N1cmZhY2UsIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CiAgICAgICAgLyogTWFrZSBzdXJlIHRoZSBkcmF3YWJsZSBpcyB1cCB0byBkYXRlLiBJbiB0aGUgb2Zmc2NyZWVuIGNhc2UKICAgICAgICAgKiBhdHRhY2hfc3VyZmFjZV9mYm8oKSBpbXBsaWNpdGx5IHRha2VzIGNhcmUgb2YgdGhpcy4gKi8KICAgICAgICBJV2luZUQzRFN1cmZhY2VfTG9hZExvY2F0aW9uKHNyY19zdXJmYWNlLCBTRkxBR19JTkRSQVdBQkxFLCBOVUxMKTsKCiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEZyYW1lYnVmZmVyRVhUKEdMX1JFQURfRlJBTUVCVUZGRVJfRVhULCAwKSk7CiAgICAgICAgYnVmZmVyID0gc3VyZmFjZV9nZXRfZ2xfYnVmZmVyKHNyY19zdXJmYWNlLCBzcmNfc3dhcGNoYWluKTsKICAgICAgICBnbFJlYWRCdWZmZXIoYnVmZmVyKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xSZWFkQnVmZmVyKCkiKTsKCiAgICAgICAgc3JjX3JlY3QtPnkxID0gKChJV2luZUQzRFN1cmZhY2VJbXBsICopc3JjX3N1cmZhY2UpLT5jdXJyZW50RGVzYy5IZWlnaHQgLSBzcmNfcmVjdC0+eTE7CiAgICAgICAgc3JjX3JlY3QtPnkyID0gKChJV2luZUQzRFN1cmZhY2VJbXBsICopc3JjX3N1cmZhY2UpLT5jdXJyZW50RGVzYy5IZWlnaHQgLSBzcmNfcmVjdC0+eTI7CiAgICB9IGVsc2UgewogICAgICAgIFRSQUNFKCJTb3VyY2Ugc3VyZmFjZSAlcCBpcyBvZmZzY3JlZW5cbiIsIHNyY19zdXJmYWNlKTsKICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgIGJpbmRfZmJvKGlmYWNlLCBHTF9SRUFEX0ZSQU1FQlVGRkVSX0VYVCwgJlRoaXMtPnNyY19mYm8pOwogICAgICAgIGF0dGFjaF9zdXJmYWNlX2ZibyhUaGlzLCBHTF9SRUFEX0ZSQU1FQlVGRkVSX0VYVCwgMCwgc3JjX3N1cmZhY2UpOwogICAgICAgIGdsUmVhZEJ1ZmZlcihHTF9DT0xPUl9BVFRBQ0hNRU5UMF9FWFQpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFJlYWRCdWZmZXIoKSIpOwogICAgfQogICAgTEVBVkVfR0woKTsKCiAgICAvKiBBdHRhY2ggZHN0IHN1cmZhY2UgdG8gZHN0IGZibyAqLwogICAgZHN0X3N3YXBjaGFpbiA9IGdldF9zd2FwY2hhaW4oZHN0X3N1cmZhY2UpOwogICAgaWYgKGRzdF9zd2FwY2hhaW4pIHsKICAgICAgICBHTGVudW0gYnVmZmVyOwoKICAgICAgICBUUkFDRSgiRGVzdGluYXRpb24gc3VyZmFjZSAlcCBpcyBvbnNjcmVlblxuIiwgZHN0X3N1cmZhY2UpOwogICAgICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBkc3Rfc3VyZmFjZSwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKICAgICAgICAvKiBNYWtlIHN1cmUgdGhlIGRyYXdhYmxlIGlzIHVwIHRvIGRhdGUuIEluIHRoZSBvZmZzY3JlZW4gY2FzZQogICAgICAgICAqIGF0dGFjaF9zdXJmYWNlX2ZibygpIGltcGxpY2l0bHkgdGFrZXMgY2FyZSBvZiB0aGlzLiAqLwogICAgICAgIElXaW5lRDNEU3VyZmFjZV9Mb2FkTG9jYXRpb24oZHN0X3N1cmZhY2UsIFNGTEFHX0lORFJBV0FCTEUsIE5VTEwpOwoKICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kRnJhbWVidWZmZXJFWFQoR0xfRFJBV19GUkFNRUJVRkZFUl9FWFQsIDApKTsKICAgICAgICBidWZmZXIgPSBzdXJmYWNlX2dldF9nbF9idWZmZXIoZHN0X3N1cmZhY2UsIGRzdF9zd2FwY2hhaW4pOwogICAgICAgIGdsRHJhd0J1ZmZlcihidWZmZXIpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoKSIpOwoKICAgICAgICBkc3RfcmVjdC0+eTEgPSAoKElXaW5lRDNEU3VyZmFjZUltcGwgKilkc3Rfc3VyZmFjZSktPmN1cnJlbnREZXNjLkhlaWdodCAtIGRzdF9yZWN0LT55MTsKICAgICAgICBkc3RfcmVjdC0+eTIgPSAoKElXaW5lRDNEU3VyZmFjZUltcGwgKilkc3Rfc3VyZmFjZSktPmN1cnJlbnREZXNjLkhlaWdodCAtIGRzdF9yZWN0LT55MjsKICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoIkRlc3RpbmF0aW9uIHN1cmZhY2UgJXAgaXMgb2Zmc2NyZWVuXG4iLCBkc3Rfc3VyZmFjZSk7CgogICAgICAgIC8qIE5vIHNyYyBvciBkc3Qgc3dhcGNoYWluPyBNYWtlIHN1cmUgc29tZSBjb250ZXh0IGlzIGFjdGl2ZShtdWx0aXRocmVhZGluZykgKi8KICAgICAgICBpZighc3JjX3N3YXBjaGFpbikgewogICAgICAgICAgICBBY3RpdmF0ZUNvbnRleHQoVGhpcywgVGhpcy0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKICAgICAgICB9CgogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgYmluZF9mYm8oaWZhY2UsIEdMX0RSQVdfRlJBTUVCVUZGRVJfRVhULCAmVGhpcy0+ZHN0X2Zibyk7CiAgICAgICAgYXR0YWNoX3N1cmZhY2VfZmJvKFRoaXMsIEdMX0RSQVdfRlJBTUVCVUZGRVJfRVhULCAwLCBkc3Rfc3VyZmFjZSk7CiAgICAgICAgZ2xEcmF3QnVmZmVyKEdMX0NPTE9SX0FUVEFDSE1FTlQwX0VYVCk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcigpIik7CiAgICB9CiAgICBnbERpc2FibGUoR0xfU0NJU1NPUl9URVNUKTsKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX1NDSVNTT1JURVNURU5BQkxFKSk7CgogICAgaWYgKGZsaXApIHsKICAgICAgICBHTF9FWFRDQUxMKGdsQmxpdEZyYW1lYnVmZmVyRVhUKHNyY19yZWN0LT54MSwgc3JjX3JlY3QtPnkxLCBzcmNfcmVjdC0+eDIsIHNyY19yZWN0LT55MiwKICAgICAgICAgICAgICAgIGRzdF9yZWN0LT54MSwgZHN0X3JlY3QtPnkyLCBkc3RfcmVjdC0+eDIsIGRzdF9yZWN0LT55MSwgbWFzaywgZ2xfZmlsdGVyKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQmxpdEZyYW1lYnVmZmVyKCkiKTsKICAgIH0gZWxzZSB7CiAgICAgICAgR0xfRVhUQ0FMTChnbEJsaXRGcmFtZWJ1ZmZlckVYVChzcmNfcmVjdC0+eDEsIHNyY19yZWN0LT55MSwgc3JjX3JlY3QtPngyLCBzcmNfcmVjdC0+eTIsCiAgICAgICAgICAgICAgICBkc3RfcmVjdC0+eDEsIGRzdF9yZWN0LT55MSwgZHN0X3JlY3QtPngyLCBkc3RfcmVjdC0+eTIsIG1hc2ssIGdsX2ZpbHRlcikpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJsaXRGcmFtZWJ1ZmZlcigpIik7CiAgICB9CgogICAgSVdpbmVEM0RTdXJmYWNlX01vZGlmeUxvY2F0aW9uKGRzdF9zdXJmYWNlLCBTRkxBR19JTkRSQVdBQkxFLCBUUlVFKTsKCiAgICBpZiAoVGhpcy0+cmVuZGVyX29mZnNjcmVlbikgewogICAgICAgIGJpbmRfZmJvKGlmYWNlLCBHTF9GUkFNRUJVRkZFUl9FWFQsICZUaGlzLT5mYm8pOwogICAgfSBlbHNlIHsKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEZyYW1lYnVmZmVyRVhUKEdMX0ZSQU1FQlVGRkVSX0VYVCwgMCkpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRGcmFtZWJ1ZmZlcigpIik7CiAgICB9CgogICAgLyogSWYgd2Ugc3dpdGNoZWQgZnJvbSBHTF9CQUNLIHRvIEdMX0ZST05UIGFib3ZlLCB3ZSBuZWVkIHRvIHN3aXRjaCBiYWNrIGhlcmUgKi8KICAgIGlmIChkc3Rfc3dhcGNoYWluICYmIGRzdF9zdXJmYWNlID09ICgoSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICopZHN0X3N3YXBjaGFpbiktPmZyb250QnVmZmVyCiAgICAgICAgICAgICYmICgoSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICopZHN0X3N3YXBjaGFpbiktPmJhY2tCdWZmZXIpIHsKICAgICAgICBnbERyYXdCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcigpIik7CiAgICB9CiAgICBMRUFWRV9HTCgpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFJlbmRlclRhcmdldChJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIFJlbmRlclRhcmdldEluZGV4LCBJV2luZUQzRFN1cmZhY2UgKnBSZW5kZXJUYXJnZXQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFdJTkVEM0RWSUVXUE9SVCB2aWV3cG9ydDsKCiAgICBUUkFDRSgiKCVwKSA6IFNldHRpbmcgcmVuZGVydGFyZ2V0ICVkIHRvICVwXG4iLCBUaGlzLCBSZW5kZXJUYXJnZXRJbmRleCwgcFJlbmRlclRhcmdldCk7CgogICAgaWYgKFJlbmRlclRhcmdldEluZGV4ID49IEdMX0xJTUlUUyhidWZmZXJzKSkgewogICAgICAgIFdBUk4oIiglcCkgOiBVbnN1cHBvcnRlZCB0YXJnZXQgJXUgc2V0LCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTChvbmx5ICV1IHN1cHBvcnRlZClcbiIsCiAgICAgICAgICAgICBUaGlzLCBSZW5kZXJUYXJnZXRJbmRleCwgR0xfTElNSVRTKGJ1ZmZlcnMpKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICAvKiBNU0ROIHNheXMgdGhhdCBudWxsIGRpc2FibGVzIHRoZSByZW5kZXIgdGFyZ2V0CiAgICBidXQgYSBkZXZpY2UgbXVzdCBhbHdheXMgYmUgYXNzb2NpYXRlZCB3aXRoIGEgcmVuZGVyIHRhcmdldAogICAgbm9wZSBNU0ROIHNheXMgdGhhdCB3ZSByZXR1cm4gaW52YWxpZCBjYWxsIHRvIGEgbnVsbCByZW5kZXJ0YXJnZXQgd2l0aCBhbiBpbmRleCBvZiAwCgogICAgc2VlIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vbGlicmFyeS9kZWZhdWx0LmFzcD91cmw9L2xpYnJhcnkvZW4tdXMvZGlyZWN0eDlfYy9kaXJlY3R4L2dyYXBoaWNzL3Byb2dyYW1taW5nZ3VpZGUvQWR2YW5jZWRUb3BpY3MvUGl4ZWxQaXBlL011bHRpcGxlUmVuZGVyVGFyZ2V0LmFzcAogICAgZm9yIG1vcmUgZGV0YWlscwogICAgKi8KICAgIGlmIChSZW5kZXJUYXJnZXRJbmRleCA9PSAwICYmIHBSZW5kZXJUYXJnZXQgPT0gTlVMTCkgewogICAgICAgIEZJWE1FKCJUcnlpbmcgdG8gc2V0IHJlbmRlciB0YXJnZXQgMCB0byBOVUxMXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIGlmIChwUmVuZGVyVGFyZ2V0ICYmICEoKChJV2luZUQzRFN1cmZhY2VJbXBsICopcFJlbmRlclRhcmdldCktPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkpIHsKICAgICAgICBGSVhNRSgiKCVwKVRyeWluZyB0byBzZXQgdGhlIHJlbmRlciB0YXJnZXQgdG8gYSBzdXJmYWNlKCVwKSB0aGF0IHdhc24ndCBjcmVhdGVkIHdpdGggYSB1c2FnZSBvZiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUXG4iLFRoaXMgLHBSZW5kZXJUYXJnZXQpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIC8qIElmIHdlIGFyZSB0cnlpbmcgdG8gc2V0IHdoYXQgd2UgYWxyZWFkeSBoYXZlLCBkb24ndCBib3RoZXIgKi8KICAgIGlmIChwUmVuZGVyVGFyZ2V0ID09IFRoaXMtPnJlbmRlcl90YXJnZXRzW1JlbmRlclRhcmdldEluZGV4XSkgewogICAgICAgIFRSQUNFKCJUcnlpbmcgdG8gZG8gYSBOT1AgU2V0UmVuZGVyVGFyZ2V0IG9wZXJhdGlvblxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CiAgICBpZihwUmVuZGVyVGFyZ2V0KSBJV2luZUQzRFN1cmZhY2VfQWRkUmVmKHBSZW5kZXJUYXJnZXQpOwogICAgaWYoVGhpcy0+cmVuZGVyX3RhcmdldHNbUmVuZGVyVGFyZ2V0SW5kZXhdKSBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShUaGlzLT5yZW5kZXJfdGFyZ2V0c1tSZW5kZXJUYXJnZXRJbmRleF0pOwogICAgVGhpcy0+cmVuZGVyX3RhcmdldHNbUmVuZGVyVGFyZ2V0SW5kZXhdID0gcFJlbmRlclRhcmdldDsKCiAgICAvKiBSZW5kZXIgdGFyZ2V0IDAgaXMgc3BlY2lhbCAqLwogICAgaWYoUmVuZGVyVGFyZ2V0SW5kZXggPT0gMCkgewogICAgICAgIC8qIEZpbmFsbHksIHJlc2V0IHRoZSB2aWV3cG9ydCBhcyB0aGUgTVNETiBzdGF0ZXMuICovCiAgICAgICAgdmlld3BvcnQuSGVpZ2h0ID0gKChJV2luZUQzRFN1cmZhY2VJbXBsICopVGhpcy0+cmVuZGVyX3RhcmdldHNbMF0pLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgdmlld3BvcnQuV2lkdGggID0gKChJV2luZUQzRFN1cmZhY2VJbXBsICopVGhpcy0+cmVuZGVyX3RhcmdldHNbMF0pLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICB2aWV3cG9ydC5YICAgICAgPSAwOwogICAgICAgIHZpZXdwb3J0LlkgICAgICA9IDA7CiAgICAgICAgdmlld3BvcnQuTWF4WiAgID0gMS4wZjsKICAgICAgICB2aWV3cG9ydC5NaW5aICAgPSAwLjBmOwogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWaWV3cG9ydChpZmFjZSwgJnZpZXdwb3J0KTsKICAgICAgICAvKiBNYWtlIHN1cmUgdGhlIHZpZXdwb3J0IHN0YXRlIGlzIGRpcnR5LCBiZWNhdXNlIHRoZSByZW5kZXJfb2Zmc2NyZWVuIHRoaW5nIGFmZmVjdHMgaXQuCiAgICAgICAgICogU2V0Vmlld3BvcnQgbWF5IGNhdGNoIE5PUCB2aWV3cG9ydCBjaGFuZ2VzLCB3aGljaCB3b3VsZCBvY2N1ciB3aGVuIHN3aXRjaGluZyBiZXR3ZWVuIGVxdWFsbHkgc2l6ZWQgdGFyZ2V0cwogICAgICAgICAqLwogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9WSUVXUE9SVCk7CgogICAgICAgIC8qIEFjdGl2YXRlIHRoZSBuZXcgcmVuZGVyIHRhcmdldCBmb3Igbm93LiBUaGlzIHNob3VsZG4ndCBzdGF5IGhlcmUsIGJ1dCBpcyBuZWVkZWQgdW50aWwgYWxsIG1ldGhvZHMgdXNpbmcgZ2wgYWN0aXZhdGUgdGhlCiAgICAgICAgICogY3R4IHByb3Blcmx5LgogICAgICAgICAqIFVzZSByZXNvdXJjZWxvYWQgdXNhZ2UsIHRoaXMgd2lsbCBqdXN0IHNldCB0aGUgZHJhd2FibGVzIGFuZCBjb250ZXh0IGJ1dCBub3QgYXBwbHkgYW55IHN0YXRlcy4gVGhlIHN0YXRlYmxvY2sgbWF5IGJlCiAgICAgICAgICogaW5jb21wbGV0ZSBvciBpbmNvcnJlY3Qgd2hlbiBTZXRSZW5kZXJUYXJnZXQgaXMgY2FsbGVkLiBEcmF3UHJpbSgpIHdpbGwgYXBwbHkgdGhlIHN0YXRlcyB3aGVuIGl0IGlzIGNhbGxlZC4KICAgICAgICAgKi8KICAgICAgICBBY3RpdmF0ZUNvbnRleHQoVGhpcywgVGhpcy0+cmVuZGVyX3RhcmdldHNbMF0sIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXREZXB0aFN0ZW5jaWxTdXJmYWNlKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RTdXJmYWNlICpwTmV3WlN0ZW5jaWwpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIEhSRVNVTFQgIGhyID0gV0lORUQzRF9PSzsKICAgIElXaW5lRDNEU3VyZmFjZSAqdG1wOwoKICAgIFRSQUNFKCIoJXApIFN3YXBwaW5nIHotYnVmZmVyLiBPbGQgPSAlcCwgbmV3ID0gJXBcbiIsVGhpcywgVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCwgcE5ld1pTdGVuY2lsKTsKCiAgICBpZiAocE5ld1pTdGVuY2lsID09IFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQpIHsKICAgICAgICBUUkFDRSgiVHJ5aW5nIHRvIGRvIGEgTk9QIFNldFJlbmRlclRhcmdldCBvcGVyYXRpb25cbiIpOwogICAgfSBlbHNlIHsKICAgICAgICAvKiogT3BlbkdMIGRvZXNuJ3Qgc3VwcG9ydCAnc2hhcmluZycgb2YgdGhlIHN0ZW5jaWxCdWZmZXIgc28gd2UgbWF5IGluY3VyZSBhbiBleHRyYSBtZW1vcnkgb3ZlcmhlYWQKICAgICAgICAqIGRlcGVuZGluZyBvbiB0aGUgcmVudGVyIHRhcmdldCBpbXBsZW1lbnRhdGlvbiBiZWluZyB1c2VkLgogICAgICAgICogQSBzaGFyZWQgY29udGV4dCBpbXBsZW1lbnRhdGlvbiB3aWxsIHNoYXJlIGFsbCBidWZmZXJzIGJldHdlZW4gYWxsIHJlbmRlcnRhcmdldHMgKGluY2x1ZGluZyBzd2FwY2hhaW5zKSwKICAgICAgICAqIGltcGxlbWVudGF0aW9ucyB0aGF0IHVzZSBzZXBhcmF0ZSBwYnVmZmVycyBmb3IgZGlmZmVyZW50IHN3YXBjaGFpbnMgb3IgcmVuZGVydGFyZ2V0cyB3aWxsIGhhdmUgdG8gZHVwbGljYXRlIHRoZQogICAgICAgICogc3RlbmNpbCBidWZmZXIgYW5kIGluY3VyZSBhbiBleHRyYSBtZW1vcnkgb3ZlcmhlYWQKICAgICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgICAgICB0bXAgPSBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0OwogICAgICAgIFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQgPSBwTmV3WlN0ZW5jaWw7CiAgICAgICAgVGhpcy0+ZGVwdGhfY29weV9zdGF0ZSA9IFdJTkVEM0RfRENTX05PX0NPUFk7CiAgICAgICAgLyogc2hvdWxkIHdlIGJlIGNhbGxpbmcgdGhlIHBhcmVudCBvciB0aGUgd2luZWQzZCBzdXJmYWNlPyAqLwogICAgICAgIGlmIChOVUxMICE9IFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQpIElXaW5lRDNEU3VyZmFjZV9BZGRSZWYoVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCk7CiAgICAgICAgaWYgKE5VTEwgIT0gdG1wKSBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZSh0bXApOwogICAgICAgIGhyID0gV0lORUQzRF9PSzsKCiAgICAgICAgaWYoKCF0bXAgJiYgcE5ld1pTdGVuY2lsKSB8fCAoIXBOZXdaU3RlbmNpbCAmJiB0bXApKSB7CiAgICAgICAgICAgIC8qIFN3YXBwaW5nIE5VTEwgLyBub24gTlVMTCBkZXB0aCBzdGVuY2lsIGFmZmVjdHMgdGhlIGRlcHRoIGFuZCB0ZXN0cyAqLwogICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19aRU5BQkxFKSk7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX1NURU5DSUxFTkFCTEUpKTsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1JFTkRFUihXSU5FRDNEUlNfU1RFTkNJTFdSSVRFTUFTSykpOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRDdXJzb3JQcm9wZXJ0aWVzKElXaW5lRDNERGV2aWNlKiBpZmFjZSwgVUlOVCBYSG90U3BvdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFlIb3RTcG90LCBJV2luZUQzRFN1cmZhY2UgKnBDdXJzb3JCaXRtYXApIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICAvKiBUT0RPOiB0aGUgdXNlIG9mIEltcGwgaXMgZGVwcmVjYXRlZC4gKi8KICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKiBwU3VyID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgcEN1cnNvckJpdG1hcDsKICAgIFdJTkVEM0RMT0NLRURfUkVDVCBsb2NrZWRSZWN0OwoKICAgIFRSQUNFKCIoJXApIDogU3BvdCBQb3MoJXUsJXUpXG4iLCBUaGlzLCBYSG90U3BvdCwgWUhvdFNwb3QpOwoKICAgIC8qIHNvbWUgYmFzaWMgdmFsaWRhdGlvbiBjaGVja3MgKi8KICAgIGlmKFRoaXMtPmN1cnNvclRleHR1cmUpIHsKICAgICAgICBBY3RpdmF0ZUNvbnRleHQoVGhpcywgVGhpcy0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgIGdsRGVsZXRlVGV4dHVyZXMoMSwgJlRoaXMtPmN1cnNvclRleHR1cmUpOwogICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgVGhpcy0+Y3Vyc29yVGV4dHVyZSA9IDA7CiAgICB9CgogICAgaWYgKCAocFN1ci0+Y3VycmVudERlc2MuV2lkdGggPT0gMzIpICYmIChwU3VyLT5jdXJyZW50RGVzYy5IZWlnaHQgPT0gMzIpICkKICAgICAgICBUaGlzLT5oYXZlSGFyZHdhcmVDdXJzb3IgPSBUUlVFOwogICAgZWxzZQogICAgICAgIFRoaXMtPmhhdmVIYXJkd2FyZUN1cnNvciA9IEZBTFNFOwoKICAgIGlmKHBDdXJzb3JCaXRtYXApIHsKICAgICAgICBXSU5FRDNETE9DS0VEX1JFQ1QgcmVjdDsKCiAgICAgICAgLyogTVNETjogQ3Vyc29yIG11c3QgYmUgQThSOEc4QjggKi8KICAgICAgICBpZiAoV0lORUQzREZNVF9BOFI4RzhCOCAhPSBwU3VyLT5yZXNvdXJjZS5mb3JtYXQpIHsKICAgICAgICAgICAgRVJSKCIoJXApIDogc3VyZmFjZSglcCkgaGFzIGFuIGludmFsaWQgZm9ybWF0XG4iLCBUaGlzLCBwQ3Vyc29yQml0bWFwKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfQoKICAgICAgICAvKiBNU0ROOiBDdXJzb3IgbXVzdCBiZSBzbWFsbGVyIHRoYW4gdGhlIGRpc3BsYXkgbW9kZSAqLwogICAgICAgIGlmKHBTdXItPmN1cnJlbnREZXNjLldpZHRoID4gVGhpcy0+ZGRyYXdfd2lkdGggfHwKICAgICAgICAgICBwU3VyLT5jdXJyZW50RGVzYy5IZWlnaHQgPiBUaGlzLT5kZHJhd19oZWlnaHQpIHsKICAgICAgICAgICAgRVJSKCIoJXApIDogU3VyZmFjZSglcCkgaXMgJWR4JWQgcGl4ZWxzLCBidXQgc2NyZWVuIHJlcyBpcyAlZHglZFxuIiwgVGhpcywgcFN1ciwgcFN1ci0+Y3VycmVudERlc2MuV2lkdGgsIHBTdXItPmN1cnJlbnREZXNjLkhlaWdodCwgVGhpcy0+ZGRyYXdfd2lkdGgsIFRoaXMtPmRkcmF3X2hlaWdodCk7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgIH0KCiAgICAgICAgaWYgKCFUaGlzLT5oYXZlSGFyZHdhcmVDdXJzb3IpIHsKICAgICAgICAgICAgLyogVE9ETzogTVNETjogQ3Vyc29yIHNpemVzIG11c3QgYmUgYSBwb3dlciBvZiAyICovCgogICAgICAgICAgICAvKiBEbyBub3Qgc3RvcmUgdGhlIHN1cmZhY2UncyBwb2ludGVyIGJlY2F1c2UgdGhlIGFwcGxpY2F0aW9uIG1heQogICAgICAgICAgICAgKiByZWxlYXNlIGl0IGFmdGVyIHNldHRpbmcgdGhlIGN1cnNvciBpbWFnZS4gV2luZG93cyBkb2Vzbid0CiAgICAgICAgICAgICAqIGFkZHJlZiB0aGUgc2V0IHN1cmZhY2UsIHNvIHdlIGNhbid0IGRvIHRoaXMgZWl0aGVyIHdpdGhvdXQKICAgICAgICAgICAgICogY3JlYXRpbmcgY2lyY3VsYXIgcmVmY291bnQgZGVwZW5kZW5jaWVzLiBDb3B5IG91dCB0aGUgZ2wgdGV4dHVyZQogICAgICAgICAgICAgKiBpbnN0ZWFkLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgVGhpcy0+Y3Vyc29yV2lkdGggPSBwU3VyLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICAgICAgVGhpcy0+Y3Vyc29ySGVpZ2h0ID0gcFN1ci0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgICAgICAgICBpZiAoU1VDQ0VFREVEKElXaW5lRDNEU3VyZmFjZV9Mb2NrUmVjdChwQ3Vyc29yQml0bWFwLCAmcmVjdCwgTlVMTCwgV0lORUQzRExPQ0tfUkVBRE9OTFkpKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY29uc3QgR2xQaXhlbEZvcm1hdERlc2MgKmdsRGVzYzsKICAgICAgICAgICAgICAgIGNvbnN0IFN0YXRpY1BpeGVsRm9ybWF0RGVzYyAqdGFibGVFbnRyeSA9IGdldEZvcm1hdERlc2NFbnRyeShXSU5FRDNERk1UX0E4UjhHOEI4LCAmR0xJTkZPX0xPQ0FUSU9OLCAmZ2xEZXNjKTsKICAgICAgICAgICAgICAgIGNoYXIgKm1lbSwgKmJpdHMgPSAoY2hhciAqKXJlY3QucEJpdHM7CiAgICAgICAgICAgICAgICBHTGludCBpbnRmbXQgPSBnbERlc2MtPmdsSW50ZXJuYWw7CiAgICAgICAgICAgICAgICBHTGludCBmb3JtYXQgPSBnbERlc2MtPmdsRm9ybWF0OwogICAgICAgICAgICAgICAgR0xpbnQgdHlwZSA9IGdsRGVzYy0+Z2xUeXBlOwogICAgICAgICAgICAgICAgSU5UIGhlaWdodCA9IFRoaXMtPmN1cnNvckhlaWdodDsKICAgICAgICAgICAgICAgIElOVCB3aWR0aCA9IFRoaXMtPmN1cnNvcldpZHRoOwogICAgICAgICAgICAgICAgSU5UIGJwcCA9IHRhYmxlRW50cnktPmJwcDsKICAgICAgICAgICAgICAgIElOVCBpOwoKICAgICAgICAgICAgICAgIC8qIFJlZm9ybWF0IHRoZSB0ZXh0dXJlIG1lbW9yeSAocGl0Y2ggYW5kIHdpZHRoIGNhbiBiZQogICAgICAgICAgICAgICAgICogZGlmZmVyZW50KSAqLwogICAgICAgICAgICAgICAgbWVtID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHdpZHRoICogaGVpZ2h0ICogYnBwKTsKICAgICAgICAgICAgICAgIGZvcihpID0gMDsgaSA8IGhlaWdodDsgaSsrKQogICAgICAgICAgICAgICAgICAgIG1lbWNweSgmbWVtW3dpZHRoICogYnBwICogaV0sICZiaXRzW3JlY3QuUGl0Y2ggKiBpXSwgd2lkdGggKiBicHApOwogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QocEN1cnNvckJpdG1hcCk7CiAgICAgICAgICAgICAgICBFTlRFUl9HTCgpOwoKICAgICAgICAgICAgICAgIGlmKEdMX1NVUFBPUlQoQVBQTEVfQ0xJRU5UX1NUT1JBR0UpKSB7CiAgICAgICAgICAgICAgICAgICAgZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfQ0xJRU5UX1NUT1JBR0VfQVBQTEUsIEdMX0ZBTFNFKTsKICAgICAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfQ0xJRU5UX1NUT1JBR0VfQVBQTEUsIEdMX0ZBTFNFKSIpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8qIE1ha2Ugc3VyZSB0aGF0IGEgcHJvcGVyIHRleHR1cmUgdW5pdCBpcyBzZWxlY3RlZCAqLwogICAgICAgICAgICAgICAgaWYgKEdMX1NVUFBPUlQoQVJCX01VTFRJVEVYVFVSRSkpIHsKICAgICAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsQWN0aXZlVGV4dHVyZUFSQihHTF9URVhUVVJFMF9BUkIpKTsKICAgICAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xBY3RpdmVUZXh0dXJlQVJCIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfU0FNUExFUigwKSk7CiAgICAgICAgICAgICAgICAvKiBDcmVhdGUgYSBuZXcgY3Vyc29yIHRleHR1cmUgKi8KICAgICAgICAgICAgICAgIGdsR2VuVGV4dHVyZXMoMSwgJlRoaXMtPmN1cnNvclRleHR1cmUpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsR2VuVGV4dHVyZXMiKTsKICAgICAgICAgICAgICAgIGdsQmluZFRleHR1cmUoR0xfVEVYVFVSRV8yRCwgVGhpcy0+Y3Vyc29yVGV4dHVyZSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kVGV4dHVyZSIpOwogICAgICAgICAgICAgICAgLyogQ29weSB0aGUgYml0bWFwIG1lbW9yeSBpbnRvIHRoZSBjdXJzb3IgdGV4dHVyZSAqLwogICAgICAgICAgICAgICAgZ2xUZXhJbWFnZTJEKEdMX1RFWFRVUkVfMkQsIDAsIGludGZtdCwgd2lkdGgsIGhlaWdodCwgMCwgZm9ybWF0LCB0eXBlLCBtZW0pOwogICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbWVtKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleEltYWdlMkQiKTsKCiAgICAgICAgICAgICAgICBpZihHTF9TVVBQT1JUKEFQUExFX0NMSUVOVF9TVE9SQUdFKSkgewogICAgICAgICAgICAgICAgICAgIGdsUGl4ZWxTdG9yZWkoR0xfVU5QQUNLX0NMSUVOVF9TVE9SQUdFX0FQUExFLCBHTF9UUlVFKTsKICAgICAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfQ0xJRU5UX1NUT1JBR0VfQVBQTEUsIEdMX1RSVUUpIik7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEZJWE1FKCJBIGN1cnNvciB0ZXh0dXJlIHdhcyBub3QgcmV0dXJuZWQuXG4iKTsKICAgICAgICAgICAgICAgIFRoaXMtPmN1cnNvclRleHR1cmUgPSAwOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8qIERyYXcgYSBoYXJkd2FyZSBjdXJzb3IgKi8KICAgICAgICAgICAgSUNPTklORk8gY3Vyc29ySW5mbzsKICAgICAgICAgICAgSENVUlNPUiBjdXJzb3I7CiAgICAgICAgICAgIC8qIENyZWF0ZSBhbmQgY2xlYXIgbWFza0JpdHMgYmVjYXVzZSBpdCBpcyBub3QgbmVlZGVkIGZvcgogICAgICAgICAgICAgKiAzMi1iaXQgY3Vyc29ycy4gIDMyeDMyIGJpdHMgc3BsaXQgaW50byAzMi1iaXQgY2h1bmtzID09IDMyCiAgICAgICAgICAgICAqIGNodW5rcy4gKi8KICAgICAgICAgICAgRFdPUkQgKm1hc2tCaXRzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksCiAgICAgICAgICAgICAgICAocFN1ci0+Y3VycmVudERlc2MuV2lkdGggKiBwU3VyLT5jdXJyZW50RGVzYy5IZWlnaHQgLyA4KSk7CiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9Mb2NrUmVjdChwQ3Vyc29yQml0bWFwLCAmbG9ja2VkUmVjdCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNETE9DS19OT19ESVJUWV9VUERBVEUgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RMT0NLX1JFQURPTkxZCiAgICAgICAgICAgICk7CiAgICAgICAgICAgIFRSQUNFKCJ3aWR0aDogJWkgaGVpZ2h0OiAlaVxuIiwgcFN1ci0+Y3VycmVudERlc2MuV2lkdGgsCiAgICAgICAgICAgICAgICAgIHBTdXItPmN1cnJlbnREZXNjLkhlaWdodCk7CgogICAgICAgICAgICBjdXJzb3JJbmZvLmZJY29uID0gRkFMU0U7CiAgICAgICAgICAgIGN1cnNvckluZm8ueEhvdHNwb3QgPSBYSG90U3BvdDsKICAgICAgICAgICAgY3Vyc29ySW5mby55SG90c3BvdCA9IFlIb3RTcG90OwogICAgICAgICAgICBjdXJzb3JJbmZvLmhibU1hc2sgPSBDcmVhdGVCaXRtYXAocFN1ci0+Y3VycmVudERlc2MuV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwU3VyLT5jdXJyZW50RGVzYy5IZWlnaHQsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLCAmbWFza0JpdHMpOwogICAgICAgICAgICBjdXJzb3JJbmZvLmhibUNvbG9yID0gQ3JlYXRlQml0bWFwKHBTdXItPmN1cnJlbnREZXNjLldpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTdXItPmN1cnJlbnREZXNjLkhlaWdodCwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAzMiwgbG9ja2VkUmVjdC5wQml0cyk7CiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9VbmxvY2tSZWN0KHBDdXJzb3JCaXRtYXApOwogICAgICAgICAgICAvKiBDcmVhdGUgb3VyIGN1cnNvciBhbmQgY2xlYW4gdXAuICovCiAgICAgICAgICAgIGN1cnNvciA9IENyZWF0ZUljb25JbmRpcmVjdCgmY3Vyc29ySW5mbyk7CiAgICAgICAgICAgIFNldEN1cnNvcihjdXJzb3IpOwogICAgICAgICAgICBpZiAoY3Vyc29ySW5mby5oYm1NYXNrKSBEZWxldGVPYmplY3QoY3Vyc29ySW5mby5oYm1NYXNrKTsKICAgICAgICAgICAgaWYgKGN1cnNvckluZm8uaGJtQ29sb3IpIERlbGV0ZU9iamVjdChjdXJzb3JJbmZvLmhibUNvbG9yKTsKICAgICAgICAgICAgaWYgKFRoaXMtPmhhcmR3YXJlQ3Vyc29yKSBEZXN0cm95Q3Vyc29yKFRoaXMtPmhhcmR3YXJlQ3Vyc29yKTsKICAgICAgICAgICAgVGhpcy0+aGFyZHdhcmVDdXJzb3IgPSBjdXJzb3I7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1hc2tCaXRzKTsKICAgICAgICB9CiAgICB9CgogICAgVGhpcy0+eEhvdFNwb3QgPSBYSG90U3BvdDsKICAgIFRoaXMtPnlIb3RTcG90ID0gWUhvdFNwb3Q7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIHZvaWQgICAgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEN1cnNvclBvc2l0aW9uKElXaW5lRDNERGV2aWNlKiBpZmFjZSwgaW50IFhTY3JlZW5TcGFjZSwgaW50IFlTY3JlZW5TcGFjZSwgRFdPUkQgRmxhZ3MpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IFNldFBvcyB0byAoJXUsJXUpXG4iLCBUaGlzLCBYU2NyZWVuU3BhY2UsIFlTY3JlZW5TcGFjZSk7CgogICAgVGhpcy0+eFNjcmVlblNwYWNlID0gWFNjcmVlblNwYWNlOwogICAgVGhpcy0+eVNjcmVlblNwYWNlID0gWVNjcmVlblNwYWNlOwoKICAgIHJldHVybjsKCn0KCnN0YXRpYyBCT09MICAgICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9TaG93Q3Vyc29yKElXaW5lRDNERGV2aWNlKiBpZmFjZSwgQk9PTCBiU2hvdykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIEJPT0wgb2xkVmlzaWJsZSA9IFRoaXMtPmJDdXJzb3JWaXNpYmxlOwogICAgUE9JTlQgcHQ7CgogICAgVFJBQ0UoIiglcCkgOiB2aXNpYmxlKCVkKVxuIiwgVGhpcywgYlNob3cpOwoKICAgIC8qCiAgICAgKiBXaGVuIFNob3dDdXJzb3IgaXMgZmlyc3QgY2FsbGVkIGl0IHNob3VsZCBtYWtlIHRoZSBjdXJzb3IgYXBwZWFyIGF0IHRoZSBPUydzIGxhc3QKICAgICAqIGtub3duIGN1cnNvciBwb3NpdGlvbi4gIEJlY2F1c2Ugb2YgdGhpcywgc29tZSBhcHBsaWNhdGlvbnMganVzdCByZXBldGl0aXZlbHkgY2FsbAogICAgICogU2hvd0N1cnNvciBpbiBvcmRlciB0byB1cGRhdGUgdGhlIGN1cnNvcidzIHBvc2l0aW9uLiAgVGhpcyBiZWhhdmlvciBpcyB1bmRvY3VtZW50ZWQuCiAgICAgKi8KICAgIEdldEN1cnNvclBvcygmcHQpOwogICAgVGhpcy0+eFNjcmVlblNwYWNlID0gcHQueDsKICAgIFRoaXMtPnlTY3JlZW5TcGFjZSA9IHB0Lnk7CgogICAgaWYgKFRoaXMtPmhhdmVIYXJkd2FyZUN1cnNvcikgewogICAgICAgIFRoaXMtPmJDdXJzb3JWaXNpYmxlID0gYlNob3c7CiAgICAgICAgaWYgKGJTaG93KQogICAgICAgICAgICBTZXRDdXJzb3IoVGhpcy0+aGFyZHdhcmVDdXJzb3IpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgU2V0Q3Vyc29yKE5VTEwpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGlmIChUaGlzLT5jdXJzb3JUZXh0dXJlKQogICAgICAgICAgICBUaGlzLT5iQ3Vyc29yVmlzaWJsZSA9IGJTaG93OwogICAgfQoKICAgIHJldHVybiBvbGRWaXNpYmxlOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfVGVzdENvb3BlcmF0aXZlTGV2ZWwoSVdpbmVEM0REZXZpY2UqIGlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RSZXNvdXJjZUltcGwgKnJlc291cmNlOwogICAgVFJBQ0UoIiglcCkgOiBzdGF0ZSAoJXUpXG4iLCBUaGlzLCBUaGlzLT5zdGF0ZSk7CgogICAgLyogVE9ETzogSW1wbGVtZW50IHdyYXBwaW5nIG9mIHRoZSBXbmRQcm9jIHNvIHRoYXQgbWltaW1pemUgYW5kIG1heGFtaXNlIGNhbiBiZSBtb25pdG9yZWQgYW5kIHRoZSBzdGF0ZXMgYWRqdXN0ZWQuICovCiAgICBzd2l0Y2ggKFRoaXMtPnN0YXRlKSB7CiAgICBjYXNlIFdJTkVEM0RfT0s6CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICBjYXNlIFdJTkVEM0RFUlJfREVWSUNFTE9TVDoKICAgICAgICB7CiAgICAgICAgICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkocmVzb3VyY2UsICZUaGlzLT5yZXNvdXJjZXMsIElXaW5lRDNEUmVzb3VyY2VJbXBsLCByZXNvdXJjZS5yZXNvdXJjZV9saXN0X2VudHJ5KSB7CiAgICAgICAgICAgICAgICBpZiAocmVzb3VyY2UtPnJlc291cmNlLnBvb2wgPT0gV0lORUQzRFBPT0xfREVGQVVMVCkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9ERVZJQ0VOT1RSRVNFVDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9ERVZJQ0VMT1NUOwogICAgICAgIH0KICAgIGNhc2UgV0lORUQzREVSUl9EUklWRVJJTlRFUk5BTEVSUk9SOgogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0RSSVZFUklOVEVSTkFMRVJST1I7CiAgICB9CgogICAgLyogVW5rbm93biBzdGF0ZSAqLwogICAgcmV0dXJuIFdJTkVEM0RFUlJfRFJJVkVSSU5URVJOQUxFUlJPUjsKfQoKCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9FdmljdE1hbmFnZWRSZXNvdXJjZXMoSVdpbmVEM0REZXZpY2UqIGlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgLyoqIEZJWE1FOiBSZXNvdXJjZSB0cmFja2luZyBuZWVkcyB0byBiZSBkb25lLAogICAgKiBUaGUgY2xvc2VzIHdlIGNhbiBkbyB0byB0aGlzIGlzIHNldCB0aGUgcHJpb3JpdGllcyBvZiBhbGwgbWFuYWdlZCB0ZXh0dXJlcyBsb3cKICAgICogYW5kIHRoZW4gcmVzZXQgdGhlbS4KICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgIEZJWE1FKCIoJXApIDogc3R1YlxuIiwgVGhpcyk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIHZvaWQgdXBkYXRlU3VyZmFjZURlc2MoSVdpbmVEM0RTdXJmYWNlSW1wbCAqc3VyZmFjZSwgV0lORUQzRFBSRVNFTlRfUEFSQU1FVEVSUyogcFByZXNlbnRhdGlvblBhcmFtZXRlcnMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IHN1cmZhY2UtPnJlc291cmNlLndpbmVEM0REZXZpY2U7IC8qIGZvciBHTF9TVVBQT1JUICovCgogICAgLyogUmVhbGxvY2F0ZSBwcm9wZXIgbWVtb3J5IGZvciB0aGUgZnJvbnQgYW5kIGJhY2sgYnVmZmVyIGFuZCBhZGp1c3QgdGhlaXIgc2l6ZXMgKi8KICAgIGlmKHN1cmZhY2UtPkZsYWdzICYgU0ZMQUdfRElCU0VDVElPTikgewogICAgICAgIC8qIFJlbGVhc2UgdGhlIERDICovCiAgICAgICAgU2VsZWN0T2JqZWN0KHN1cmZhY2UtPmhEQywgc3VyZmFjZS0+ZGliLmhvbGRiaXRtYXApOwogICAgICAgIERlbGV0ZURDKHN1cmZhY2UtPmhEQyk7CiAgICAgICAgLyogUmVsZWFzZSB0aGUgRElCIHNlY3Rpb24gKi8KICAgICAgICBEZWxldGVPYmplY3Qoc3VyZmFjZS0+ZGliLkRJQnNlY3Rpb24pOwogICAgICAgIHN1cmZhY2UtPmRpYi5iaXRtYXBfZGF0YSA9IE5VTEw7CiAgICAgICAgc3VyZmFjZS0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gTlVMTDsKICAgICAgICBzdXJmYWNlLT5GbGFncyAmPSB+U0ZMQUdfRElCU0VDVElPTjsKICAgIH0KICAgIHN1cmZhY2UtPmN1cnJlbnREZXNjLldpZHRoID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aDsKICAgIHN1cmZhY2UtPmN1cnJlbnREZXNjLkhlaWdodCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0OwogICAgaWYgKEdMX1NVUFBPUlQoQVJCX1RFWFRVUkVfTk9OX1BPV0VSX09GX1RXTykpIHsKICAgICAgICBzdXJmYWNlLT5wb3cyV2lkdGggPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoOwogICAgICAgIHN1cmZhY2UtPnBvdzJIZWlnaHQgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodDsKICAgIH0gZWxzZSB7CiAgICAgICAgc3VyZmFjZS0+cG93MldpZHRoID0gc3VyZmFjZS0+cG93MkhlaWdodCA9IDE7CiAgICAgICAgd2hpbGUgKHN1cmZhY2UtPnBvdzJXaWR0aCA8IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGgpIHN1cmZhY2UtPnBvdzJXaWR0aCA8PD0gMTsKICAgICAgICB3aGlsZSAoc3VyZmFjZS0+cG93MkhlaWdodCA8IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0KSBzdXJmYWNlLT5wb3cySGVpZ2h0IDw8PSAxOwogICAgfQogICAgaWYoc3VyZmFjZS0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSkgewogICAgICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0LCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgZ2xEZWxldGVUZXh0dXJlcygxLCAmc3VyZmFjZS0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICBzdXJmYWNlLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lID0gMDsKICAgICAgICBzdXJmYWNlLT5GbGFncyAmPSB+U0ZMQUdfQ0xJRU5UOwogICAgfQogICAgaWYoc3VyZmFjZS0+cG93MldpZHRoICE9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGggfHwKICAgICAgIHN1cmZhY2UtPnBvdzJIZWlnaHQgIT0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQpIHsKICAgICAgICBzdXJmYWNlLT5GbGFncyB8PSBTRkxBR19OT05QT1cyOwogICAgfSBlbHNlICB7CiAgICAgICAgc3VyZmFjZS0+RmxhZ3MgJj0gflNGTEFHX05PTlBPVzI7CiAgICB9CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdXJmYWNlLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgc3VyZmFjZS0+cmVzb3VyY2Uuc2l6ZSA9IElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaCgoSVdpbmVEM0RTdXJmYWNlICopIHN1cmZhY2UpICogc3VyZmFjZS0+cG93MldpZHRoOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgcmVzZXRfdW5sb2FkX3Jlc291cmNlcyhJV2luZUQzRFJlc291cmNlICpyZXNvdXJjZSwgdm9pZCAqZGF0YSkgewogICAgVFJBQ0UoIlVubG9hZGluZyByZXNvdXJjZSAlcFxuIiwgcmVzb3VyY2UpOwogICAgSVdpbmVEM0RSZXNvdXJjZV9VbkxvYWQocmVzb3VyY2UpOwogICAgSVdpbmVEM0RSZXNvdXJjZV9SZWxlYXNlKHJlc291cmNlKTsKICAgIHJldHVybiBTX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1Jlc2V0KElXaW5lRDNERGV2aWNlKiBpZmFjZSwgV0lORUQzRFBSRVNFTlRfUEFSQU1FVEVSUyogcFByZXNlbnRhdGlvblBhcmFtZXRlcnMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFN3YXBDaGFpbkltcGwgKnN3YXBjaGFpbjsKICAgIEhSRVNVTFQgaHI7CiAgICBCT09MIERpc3BsYXlNb2RlQ2hhbmdlZCA9IEZBTFNFOwogICAgV0lORUQzRERJU1BMQVlNT0RFIG1vZGU7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgaHIgPSBJV2luZUQzRERldmljZV9HZXRTd2FwQ2hhaW4oaWZhY2UsIDAsIChJV2luZUQzRFN3YXBDaGFpbiAqKikgJnN3YXBjaGFpbik7CiAgICBpZihGQUlMRUQoaHIpKSB7CiAgICAgICAgRVJSKCJGYWlsZWQgdG8gZ2V0IHRoZSBmaXJzdCBpbXBsaWNpdCBzd2FwY2hhaW5cbiIpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICAvKiBJcyBpdCBuZWNlc3NhcnkgdG8gcmVjcmVhdGUgdGhlIGdsIGNvbnRleHQ/IEFjdHVhbGx5IGV2ZXJ5IHNldHRpbmcgY2FuIGJlIGNoYW5nZWQKICAgICAqIG9uIGFuIGV4aXN0aW5nIGdsIGNvbnRleHQsIHNvIHRoZXJlJ3Mgbm8gcmVhbCBuZWVkIGZvciByZWNyZWF0aW9uLgogICAgICoKICAgICAqIFRPRE86IEZpZ3VyZSBvdXQgaG93IFJlc2V0IGluZmx1ZW5jZXMgcmVzb3VyY2VzIGluIEQzRFBPT0xfREVGQVVMVCwgRDNEUE9PTF9TWVNURU1NRU1PUlkgYW5kIEQzRFBPT0xfTUFOQUdFRAogICAgICoKICAgICAqIFRPRE86IEZpZ3VyZSBvdXQgd2hhdCBoYXBwZW5zIHRvIGV4cGxpY2l0IHN3YXBjaGFpbnMsIG9yIGlmIHdlIGhhdmUgbW9yZSB0aGFuIG9uZSBpbXBsaWNpdCBzd2FwY2hhaW4KICAgICAqLwogICAgVFJBQ0UoIk5ldyBwYXJhbXM6XG4iKTsKICAgIFRSQUNFKCJCYWNrQnVmZmVyV2lkdGggPSAlZFxuIiwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aCk7CiAgICBUUkFDRSgiQmFja0J1ZmZlckhlaWdodCA9ICVkXG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodCk7CiAgICBUUkFDRSgiQmFja0J1ZmZlckZvcm1hdCA9ICVzXG4iLCBkZWJ1Z19kM2Rmb3JtYXQocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJGb3JtYXQpKTsKICAgIFRSQUNFKCJCYWNrQnVmZmVyQ291bnQgPSAlZFxuIiwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJDb3VudCk7CiAgICBUUkFDRSgiTXVsdGlTYW1wbGVUeXBlID0gJWRcbiIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5NdWx0aVNhbXBsZVR5cGUpOwogICAgVFJBQ0UoIk11bHRpU2FtcGxlUXVhbGl0eSA9ICVkXG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+TXVsdGlTYW1wbGVRdWFsaXR5KTsKICAgIFRSQUNFKCJTd2FwRWZmZWN0ID0gJWRcbiIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5Td2FwRWZmZWN0KTsKICAgIFRSQUNFKCJoRGV2aWNlV2luZG93ID0gJXBcbiIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5oRGV2aWNlV2luZG93KTsKICAgIFRSQUNFKCJXaW5kb3dlZCA9ICVzXG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+V2luZG93ZWQgPyAidHJ1ZSIgOiAiZmFsc2UiKTsKICAgIFRSQUNFKCJFbmFibGVBdXRvRGVwdGhTdGVuY2lsID0gJXNcbiIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5FbmFibGVBdXRvRGVwdGhTdGVuY2lsID8gInRydWUiIDogImZhbHNlIik7CiAgICBUUkFDRSgiRmxhZ3MgPSAlMDh4XG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+RmxhZ3MpOwogICAgVFJBQ0UoIkZ1bGxTY3JlZW5fUmVmcmVzaFJhdGVJbkh6ID0gJWRcbiIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5GdWxsU2NyZWVuX1JlZnJlc2hSYXRlSW5Ieik7CiAgICBUUkFDRSgiUHJlc2VudGF0aW9uSW50ZXJ2YWwgPSAlZFxuIiwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPlByZXNlbnRhdGlvbkludGVydmFsKTsKCiAgICAvKiBObyBzcGVjaWFsIHRyZWF0bWVudCBvZiB0aGVzZSBwYXJhbWV0ZXJzLiBKdXN0IHN0b3JlIHRoZW0gKi8KICAgIHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLlN3YXBFZmZlY3QgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+U3dhcEVmZmVjdDsKICAgIHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLkZsYWdzID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkZsYWdzOwogICAgc3dhcGNoYWluLT5wcmVzZW50UGFybXMuUHJlc2VudGF0aW9uSW50ZXJ2YWwgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+UHJlc2VudGF0aW9uSW50ZXJ2YWw7CiAgICBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5GdWxsU2NyZWVuX1JlZnJlc2hSYXRlSW5IeiA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5GdWxsU2NyZWVuX1JlZnJlc2hSYXRlSW5IejsKCiAgICAvKiBXaGF0IHRvIGRvIGFib3V0IHRoZXNlPyAqLwogICAgaWYocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJDb3VudCAhPSAwICYmCiAgICAgICAgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJDb3VudCAhPSBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyQ291bnQpIHsKICAgICAgICBFUlIoIkNhbm5vdCBjaGFuZ2UgdGhlIGJhY2sgYnVmZmVyIGNvdW50IHlldFxuIik7CiAgICB9CiAgICBpZihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckZvcm1hdCAhPSBXSU5FRDNERk1UX1VOS05PV04gJiYKICAgICAgICBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckZvcm1hdCAhPSBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyRm9ybWF0KSB7CiAgICAgICAgRVJSKCJDYW5ub3QgY2hhbmdlIHRoZSBiYWNrIGJ1ZmZlciBmb3JtYXQgeWV0XG4iKTsKICAgIH0KICAgIGlmKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5oRGV2aWNlV2luZG93ICE9IE5VTEwgJiYKICAgICAgICBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+aERldmljZVdpbmRvdyAhPSBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5oRGV2aWNlV2luZG93KSB7CiAgICAgICAgRVJSKCJDYW5ub3QgY2hhbmdlIHRoZSBkZXZpY2Ugd2luZG93IHlldFxuIik7CiAgICB9CiAgICBpZihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+RW5hYmxlQXV0b0RlcHRoU3RlbmNpbCAhPSBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5FbmFibGVBdXRvRGVwdGhTdGVuY2lsKSB7CiAgICAgICAgRVJSKCJXaGF0IGRvIGRvIGFib3V0IGEgY2hhbmdlZCBhdXRvIGRlcHRoIHN0ZW5jaWwgcGFyYW1ldGVyP1xuIik7CiAgICB9CgogICAgSVdpbmVEM0REZXZpY2VfRW51bVJlc291cmNlcyhpZmFjZSwgcmVzZXRfdW5sb2FkX3Jlc291cmNlcywgTlVMTCk7CgogICAgaWYocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPldpbmRvd2VkKSB7CiAgICAgICAgbW9kZS5XaWR0aCA9IHN3YXBjaGFpbi0+b3JpZ193aWR0aDsKICAgICAgICBtb2RlLkhlaWdodCA9IHN3YXBjaGFpbi0+b3JpZ19oZWlnaHQ7CiAgICAgICAgbW9kZS5SZWZyZXNoUmF0ZSA9IDA7CiAgICAgICAgbW9kZS5Gb3JtYXQgPSBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyRm9ybWF0OwogICAgfSBlbHNlIHsKICAgICAgICBtb2RlLldpZHRoID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aDsKICAgICAgICBtb2RlLkhlaWdodCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0OwogICAgICAgIG1vZGUuUmVmcmVzaFJhdGUgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+RnVsbFNjcmVlbl9SZWZyZXNoUmF0ZUluSHo7CiAgICAgICAgbW9kZS5Gb3JtYXQgPSBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyRm9ybWF0OwogICAgfQoKICAgIC8qIFNob3VsZCBXaWR0aCA9PSA4MDAgJiYgSGVpZ2h0ID09IDAgc2V0IDgwMHg2MDA/ICovCiAgICBpZihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoICE9IDAgJiYgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQgIT0gMCAmJgogICAgICAgKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGggIT0gc3dhcGNoYWluLT5wcmVzZW50UGFybXMuQmFja0J1ZmZlcldpZHRoIHx8CiAgICAgICAgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQgIT0gc3dhcGNoYWluLT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckhlaWdodCkpCiAgICB7CiAgICAgICAgV0lORUQzRFZJRVdQT1JUIHZwOwogICAgICAgIGludCBpOwoKICAgICAgICB2cC5YID0gMDsKICAgICAgICB2cC5ZID0gMDsKICAgICAgICB2cC5XaWR0aCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGg7CiAgICAgICAgdnAuSGVpZ2h0ID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQ7CiAgICAgICAgdnAuTWluWiA9IDA7CiAgICAgICAgdnAuTWF4WiA9IDE7CgogICAgICAgIGlmKCFwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+V2luZG93ZWQpIHsKICAgICAgICAgICAgRGlzcGxheU1vZGVDaGFuZ2VkID0gVFJVRTsKICAgICAgICB9CiAgICAgICAgc3dhcGNoYWluLT5wcmVzZW50UGFybXMuQmFja0J1ZmZlcldpZHRoID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aDsKICAgICAgICBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVySGVpZ2h0ID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQ7CgogICAgICAgIHVwZGF0ZVN1cmZhY2VEZXNjKChJV2luZUQzRFN1cmZhY2VJbXBsICopc3dhcGNoYWluLT5mcm9udEJ1ZmZlciwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMpOwogICAgICAgIGZvcihpID0gMDsgaSA8IHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJDb3VudDsgaSsrKSB7CiAgICAgICAgICAgIHVwZGF0ZVN1cmZhY2VEZXNjKChJV2luZUQzRFN1cmZhY2VJbXBsICopc3dhcGNoYWluLT5iYWNrQnVmZmVyW2ldLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycyk7CiAgICAgICAgfQoKICAgICAgICAvKiBOb3cgc2V0IHRoZSBuZXcgdmlld3BvcnQgKi8KICAgICAgICBJV2luZUQzRERldmljZV9TZXRWaWV3cG9ydChpZmFjZSwgJnZwKTsKICAgIH0KCiAgICBpZigocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPldpbmRvd2VkICYmICFzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5XaW5kb3dlZCkgfHwKICAgICAgIChzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5XaW5kb3dlZCAmJiAhcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPldpbmRvd2VkKSB8fAogICAgICAgIERpc3BsYXlNb2RlQ2hhbmdlZCkgewoKICAgICAgICAvKiBTd2l0Y2hpbmcgdG8gZnVsbHNjcmVlbj8gQ2hhbmdlIHRvIGZ1bGxzY3JlZW4gbW9kZSwgVEhFTiBjaGFuZ2UgdGhlIHNjcmVlbiByZXMgKi8KICAgICAgICBpZighcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPldpbmRvd2VkKSB7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldEZ1bGxzY3JlZW4oaWZhY2UsIFRSVUUpOwogICAgICAgIH0KCiAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0RGlzcGxheU1vZGUoaWZhY2UsIDAsICZtb2RlKTsKCiAgICAgICAgLyogU3dpdGNoaW5nIG91dCBvZiBmdWxsc2NyZWVuIG1vZGU/IEZpcnN0IHNldCB0aGUgb3JpZ2luYWwgcmVzLCB0aGVuIGNoYW5nZSB0aGUgd2luZG93ICovCiAgICAgICAgaWYocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPldpbmRvd2VkKSB7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldEZ1bGxzY3JlZW4oaWZhY2UsIEZBTFNFKTsKICAgICAgICB9CiAgICAgICAgc3dhcGNoYWluLT5wcmVzZW50UGFybXMuV2luZG93ZWQgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+V2luZG93ZWQ7CiAgICB9CgogICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4gKikgc3dhcGNoYWluKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldERpYWxvZ0JveE1vZGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBCT09MIGJFbmFibGVEaWFsb2dzKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICAvKiogRklYTUU6IGFsd2F5cyB0cnVlIGF0IHRoZSBtb21lbnQgKiovCiAgICBpZighYkVuYWJsZURpYWxvZ3MpIHsKICAgICAgICBGSVhNRSgiKCVwKSBEaWFsb2dzIGNhbm5vdCBiZSBkaXNhYmxlZCB5ZXRcbiIsIFRoaXMpOwogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfR2V0Q3JlYXRpb25QYXJhbWV0ZXJzKElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRERFVklDRV9DUkVBVElPTl9QQVJBTUVURVJTICpwUGFyYW1ldGVycykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogcFBhcmFtZXRlcnMgJXBcbiIsIFRoaXMsIHBQYXJhbWV0ZXJzKTsKCiAgICAqcFBhcmFtZXRlcnMgPSBUaGlzLT5jcmVhdGVQYXJtczsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgdm9pZCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldEdhbW1hUmFtcChJV2luZUQzRERldmljZSAqIGlmYWNlLCBVSU5UIGlTd2FwQ2hhaW4sIERXT1JEIEZsYWdzLCBDT05TVCBXSU5FRDNER0FNTUFSQU1QKiBwUmFtcCkgewogICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBjaGFpbjsKICAgIEhSRVNVTFQgaHJjID0gV0lORUQzRF9PSzsKCiAgICBUUkFDRSgiUmVsYXlpbmcgIHRvIHN3YXBjaGFpblxuIik7CgogICAgaWYgKChocmMgPSBJV2luZUQzRERldmljZUltcGxfR2V0U3dhcENoYWluKGlmYWNlLCBpU3dhcENoYWluLCAmc3dhcGNoYWluKSkgPT0gV0lORUQzRF9PSykgewogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1NldEdhbW1hUmFtcChzd2FwY2hhaW4sIEZsYWdzLCAoV0lORUQzREdBTU1BUkFNUCAqKXBSYW1wKTsKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKHN3YXBjaGFpbik7CiAgICB9CiAgICByZXR1cm47Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0R2FtbWFSYW1wKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBpU3dhcENoYWluLCBXSU5FRDNER0FNTUFSQU1QKiBwUmFtcCkgewogICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBjaGFpbjsKICAgIEhSRVNVTFQgaHJjID0gV0lORUQzRF9PSzsKCiAgICBUUkFDRSgiUmVsYXlpbmcgIHRvIHN3YXBjaGFpblxuIik7CgogICAgaWYgKChocmMgPSBJV2luZUQzRERldmljZUltcGxfR2V0U3dhcENoYWluKGlmYWNlLCBpU3dhcENoYWluLCAmc3dhcGNoYWluKSkgPT0gV0lORUQzRF9PSykgewogICAgICAgIGhyYyA9SVdpbmVEM0RTd2FwQ2hhaW5fR2V0R2FtbWFSYW1wKHN3YXBjaGFpbiwgcFJhbXApOwogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2Uoc3dhcGNoYWluKTsKICAgIH0KICAgIHJldHVybjsKfQoKCi8qKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICAgTm90aWZpY2F0aW9uIGZ1bmN0aW9ucwoqKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqIFRoaXMgZnVuY3Rpb24gbXVzdCBiZSBjYWxsZWQgaW4gdGhlIHJlbGVhc2Ugb2YgYSByZXNvdXJjZSB3aGVuIHJlZiA9PSAwLAoqIHRoZSBjb250ZW50cyBvZiByZXNvdXJjZSBtdXN0IHN0aWxsIGJlIGNvcnJlY3QsCiogYW55IGhhbmRlbHMgdG8gb3RoZXIgcmVzb3VyY2UgaGVsZCBieSB0aGUgY2FsbGVyIG11c3QgYmUgY2xvc2VkCiogKGUuZy4gYSB0ZXh0dXJlIHNob3VsZCByZWxlYXNlIGFsbCBoZWxkIHN1cmZhY2VzIGJlY2F1c2UgdGVsbGluZyB0aGUgZGV2aWNlIHRoYXQgaXQncyBiZWVuIHJlbGVhc2VkLikKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0FkZFJlc291cmNlKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RSZXNvdXJjZSAqcmVzb3VyY2UpewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXApIDogQWRkaW5nIFJlc291cmNlICVwXG4iLCBUaGlzLCByZXNvdXJjZSk7CiAgICBsaXN0X2FkZF9oZWFkKCZUaGlzLT5yZXNvdXJjZXMsICYoKElXaW5lRDNEUmVzb3VyY2VJbXBsICopIHJlc291cmNlKS0+cmVzb3VyY2UucmVzb3VyY2VfbGlzdF9lbnRyeSk7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfUmVtb3ZlUmVzb3VyY2UoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFJlc291cmNlICpyZXNvdXJjZSl7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCkgOiBSZW1vdmluZyByZXNvdXJjZSAlcFxuIiwgVGhpcywgcmVzb3VyY2UpOwoKICAgIGxpc3RfcmVtb3ZlKCYoKElXaW5lRDNEUmVzb3VyY2VJbXBsICopIHJlc291cmNlKS0+cmVzb3VyY2UucmVzb3VyY2VfbGlzdF9lbnRyeSk7Cn0KCgpzdGF0aWMgdm9pZCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1Jlc291cmNlUmVsZWFzZWQoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFJlc291cmNlICpyZXNvdXJjZSl7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgaW50IGNvdW50ZXI7CgogICAgVFJBQ0UoIiglcCkgOiByZXNvdXJjZSAlcFxuIiwgVGhpcywgcmVzb3VyY2UpOwogICAgc3dpdGNoKElXaW5lRDNEUmVzb3VyY2VfR2V0VHlwZShyZXNvdXJjZSkpewogICAgICAgIC8qIFRPRE86IGNoZWNrIGZyb250IGFuZCBiYWNrIGJ1ZmZlcnMsIHJlbmRlcnRhcmdldHMgZXRjLi4gIHBvc3NpYmx5IHN3YXBjaGFpbnM/ICovCiAgICAgICAgY2FzZSBXSU5FRDNEUlRZUEVfU1VSRkFDRTogewogICAgICAgICAgICB1bnNpZ25lZCBpbnQgaTsKCiAgICAgICAgICAgIC8qIENsZWFudXAgYW55IEZCTyBhdHRhY2htZW50cyBpZiBkM2QgaXMgZW5hYmxlZCAqLwogICAgICAgICAgICBpZihUaGlzLT5kM2RfaW5pdGlhbGl6ZWQpIHsKICAgICAgICAgICAgICAgIGlmKChJV2luZUQzRFN1cmZhY2UgKilyZXNvdXJjZSA9PSBUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0KSB7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICpzd2FwY2hhaW4gPSBUaGlzLT5zd2FwY2hhaW5zID8gKElXaW5lRDNEU3dhcENoYWluSW1wbCAqKSBUaGlzLT5zd2FwY2hhaW5zWzBdIDogTlVMTDsKCiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIkxhc3QgYWN0aXZlIHJlbmRlciB0YXJnZXQgZGVzdHJveWVkXG4iKTsKICAgICAgICAgICAgICAgICAgICAvKiBGaW5kIGEgcmVwbGFjZW1lbnQgc3VyZmFjZSBmb3IgdGhlIGN1cnJlbnRseSBhY3RpdmUgYmFjayBidWZmZXIuIFRoZSBjb250ZXh0IG1hbmFnZXIgZG9lcyBub3QgZG8gTlVMTAogICAgICAgICAgICAgICAgICAgICAqIGNoZWNrcywgc28gc3dpdGNoIHRvIGEgdmFsaWQgdGFyZ2V0IGFzIGxvbmcgYXMgdGhlIGN1cnJlbnRseSBzZXQgc3VyZmFjZSBpcyBzdGlsbCB2YWxpZC4gVXNlIHRoZQogICAgICAgICAgICAgICAgICAgICAqIHN1cmZhY2Ugb2YgdGhlIGltcGxpY2l0IHN3cGNoYWluLiBJZiB0aGF0IGlzIHRoZSBzYW1lIGFzIHRoZSBkZXN0cm95ZWQgc3VyZmFjZSB0aGUgZGV2aWNlIGlzIGRlc3Ryb3llZAogICAgICAgICAgICAgICAgICAgICAqIGFuZCB0aGUgbGFzdEFjdGl2ZVJlbmRlclRhcmdldCBtZW1iZXIgc2hvdWxkbid0IG1hdHRlcgogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIGlmKHN3YXBjaGFpbikgewogICAgICAgICAgICAgICAgICAgICAgICBpZihzd2FwY2hhaW4tPmJhY2tCdWZmZXIgJiYgc3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdICE9IChJV2luZUQzRFN1cmZhY2UgKilyZXNvdXJjZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIkFjdGl2YXRpbmcgcHJpbWFyeSBiYWNrIGJ1ZmZlclxuIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBBY3RpdmF0ZUNvbnRleHQoVGhpcywgc3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdLCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYoIXN3YXBjaGFpbi0+YmFja0J1ZmZlciAmJiBzd2FwY2hhaW4tPmZyb250QnVmZmVyICE9IChJV2luZUQzRFN1cmZhY2UgKilyZXNvdXJjZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogU2luZ2xlIGJ1ZmZlcmluZyBlbnZpcm9ubWVudCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIkFjdGl2YXRpbmcgcHJpbWFyeSBmcm9udCBidWZmZXJcbiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgQWN0aXZhdGVDb250ZXh0KFRoaXMsIHN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIsIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUkFDRSgiRGV2aWNlIGlzIGJlaW5nIGRlc3Ryb3llZCwgc2V0dGluZyBsYXN0QWN0aXZlUmVuZGVyVGFyZ2V0ID0gMHhkZWFkYmFiZVxuIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBJbXBsaWNpdCByZW5kZXIgdGFyZ2V0IGRlc3Ryb3llZCwgdGhhdCBtZWFucyB0aGUgZGV2aWNlIGlzIGJlaW5nIGRlc3Ryb3llZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICogd2hhdGV2ZXIgd2Ugc2V0IGhlcmUsIGl0IHNob3VsZG4ndCBtYXR0ZXIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCA9IChJV2luZUQzRFN1cmZhY2UgKikgMHhkZWFkYmFiZTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIE1heSBoYXBwZW4gZHVyaW5nIGRkcmF3IHVuaW5pdGlhbGl6YXRpb24gKi8KICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlJlbmRlciB0YXJnZXQgc2V0LCBidXQgc3dhcGNoYWluIGRvZXMgbm90IGV4aXN0IVxuIik7CiAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQgPSAoSVdpbmVEM0RTdXJmYWNlICopIDB4ZGVhZGNhZmU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBHTF9MSU1JVFMoYnVmZmVycyk7ICsraSkgewogICAgICAgICAgICAgICAgICAgIGlmIChUaGlzLT5mYm9fY29sb3JfYXR0YWNobWVudHNbaV0gPT0gKElXaW5lRDNEU3VyZmFjZSAqKXJlc291cmNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJpbmRfZmJvKGlmYWNlLCBHTF9GUkFNRUJVRkZFUl9FWFQsICZUaGlzLT5mYm8pOwogICAgICAgICAgICAgICAgICAgICAgICBzZXRfcmVuZGVyX3RhcmdldF9mYm8oaWZhY2UsIGksIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5mYm9fY29sb3JfYXR0YWNobWVudHNbaV0gPSBOVUxMOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChUaGlzLT5mYm9fZGVwdGhfYXR0YWNobWVudCA9PSAoSVdpbmVEM0RTdXJmYWNlICopcmVzb3VyY2UpIHsKICAgICAgICAgICAgICAgICAgICBiaW5kX2ZibyhpZmFjZSwgR0xfRlJBTUVCVUZGRVJfRVhULCAmVGhpcy0+ZmJvKTsKICAgICAgICAgICAgICAgICAgICBzZXRfZGVwdGhfc3RlbmNpbF9mYm8oaWZhY2UsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgIFRoaXMtPmZib19kZXB0aF9hdHRhY2htZW50ID0gTlVMTDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGNhc2UgV0lORUQzRFJUWVBFX1RFWFRVUkU6CiAgICAgICAgY2FzZSBXSU5FRDNEUlRZUEVfQ1VCRVRFWFRVUkU6CiAgICAgICAgY2FzZSBXSU5FRDNEUlRZUEVfVk9MVU1FVEVYVFVSRToKICAgICAgICAgICAgICAgIGZvciAoY291bnRlciA9IDA7IGNvdW50ZXIgPCBNQVhfQ09NQklORURfU0FNUExFUlM7IGNvdW50ZXIrKykgewogICAgICAgICAgICAgICAgICAgIGlmIChUaGlzLT5zdGF0ZUJsb2NrICE9IE5VTEwgJiYgVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZXNbY291bnRlcl0gPT0gKElXaW5lRDNEQmFzZVRleHR1cmUgKilyZXNvdXJjZSkgewogICAgICAgICAgICAgICAgICAgICAgICBXQVJOKCJUZXh0dXJlIGJlaW5nIHJlbGVhc2VkIGlzIHN0aWxsIGJ5IGEgc3RhdGVibG9jaywgU3RhZ2UgPSAldSBUZXh0dXJlID0gJXBcbiIsIGNvdW50ZXIsIHJlc291cmNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZXNbY291bnRlcl0gPSBOVUxMOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoVGhpcy0+dXBkYXRlU3RhdGVCbG9jayAhPSBUaGlzLT5zdGF0ZUJsb2NrICl7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlc1tjb3VudGVyXSA9PSAoSVdpbmVEM0RCYXNlVGV4dHVyZSAqKXJlc291cmNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBXQVJOKCJUZXh0dXJlIGJlaW5nIHJlbGVhc2VkIGlzIHN0aWxsIGJ5IGEgc3RhdGVibG9jaywgU3RhZ2UgPSAldSBUZXh0dXJlID0gJXBcbiIsIGNvdW50ZXIsIHJlc291cmNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRleHR1cmVzW2NvdW50ZXJdID0gTlVMTDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9WT0xVTUU6CiAgICAgICAgLyogVE9ETzogbm90aGluZyByZWFsbHk/ICovCiAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEUlRZUEVfVkVSVEVYQlVGRkVSOgogICAgICAgIC8qIE1TRE46IFdoZW4gYW4gYXBwbGljYXRpb24gbm8gbG9uZ2VyIGhvbGRzIGEgcmVmZXJlbmNlcyB0byB0aGlzIGludGVyZmFjZSwgdGhlIGludGVyZmFjZSB3aWxsIGF1dG9tYXRpY2FsbHkgYmUgZnJlZWQuICovCiAgICAgICAgewogICAgICAgICAgICBpbnQgc3RyZWFtTnVtYmVyOwogICAgICAgICAgICBUUkFDRSgiQ2xlYW5pbmcgdXAgc3RyZWFtIHBvaW50ZXJzXG4iKTsKCiAgICAgICAgICAgIGZvcihzdHJlYW1OdW1iZXIgPSAwOyBzdHJlYW1OdW1iZXIgPCBNQVhfU1RSRUFNUzsgc3RyZWFtTnVtYmVyICsrKXsKICAgICAgICAgICAgICAgIC8qIEZJTkRPVVQ6IHNob3VsZCBhIHdhcm4gYmUgZ2VuZXJhdGVkIGlmIHdlcmUgcmVjb3JkaW5nIGFuZCB1cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2UgaXMgbG9zdD8KICAgICAgICAgICAgICAgIEZJTkRPVVQ6IHNob3VsZCBjaGFuZ2VzLnN0cmVhbVNvdXJjZVtTdHJlYW1OdW1iZXJdIGJlIHNldCA/CiAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYgKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2sgIT0gTlVMTCApIHsgLyogPT1OVUxMIHdoZW4gZGV2aWNlIGlzIGJlaW5nIGRlc3Ryb3llZCAqLwogICAgICAgICAgICAgICAgICAgIGlmICgoSVdpbmVEM0RSZXNvdXJjZSAqKVRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtzdHJlYW1OdW1iZXJdID09IHJlc291cmNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEZJWE1FKCJWZXJ0ZXggYnVmZmVyIHJlbGVhc2VkIHdoaWxlIGJvdW5kIHRvIGEgc3RhdGUgYmxvY2ssIHN0cmVhbSAlZFxuIiwgc3RyZWFtTnVtYmVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c3RyZWFtU291cmNlW3N0cmVhbU51bWJlcl0gPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAvKiBTZXQgY2hhbmdlZCBmbGFnPyAqLwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChUaGlzLT5zdGF0ZUJsb2NrICE9IE5VTEwgKSB7IC8qIG9ubHkgaGFwcGVucyBpZiB0aGVyZSBpcyBhbiBlcnJvciBpbiB0aGUgYXBwbGljYXRpb24sIG9yIG9uIHJlc2V0L3JlbGVhc2UgKGJlY2F1c2Ugd2UgZG9uJ3QgbWFuYWdlIGludGVybmFsIHRyYWNraW5nIHByb3Blcmx5KSAqLwogICAgICAgICAgICAgICAgICAgIGlmICgoSVdpbmVEM0RSZXNvdXJjZSAqKVRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtzdHJlYW1OdW1iZXJdID09IHJlc291cmNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFKCJWZXJ0ZXggYnVmZmVyIHJlbGVhc2VkIHdoaWxlIGJvdW5kIHRvIGEgc3RhdGUgYmxvY2ssIHN0cmVhbSAlZFxuIiwgc3RyZWFtTnVtYmVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlW3N0cmVhbU51bWJlcl0gPSAwOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KI2lmIDAgICAvKiBUT0RPOiBNYW5hZ2UgaW50ZXJuYWwgdHJhY2tpbmcgcHJvcGVybHkgc28gdGhhdCAndGhpcyBzaG91bGRuJ3QgaGFwcGVuJyAqLwogICAgICAgICAgICAgICAgIGVsc2UgeyAvKiBUaGlzIHNob3VsZG4ndCBoYXBwZW4gKi8KICAgICAgICAgICAgICAgICAgICBGSVhNRSgiQ2FsbGluZyBhcHBsaWNhdGlvbiBoYXMgcmVsZWFzZWQgdGhlIGRldmljZSBiZWZvcmUgcmVsYXNpbmcgYWxsIHRoZSByZXNvdXJjZXMgYm91bmQgdG8gdGhlIGRldmljZVxuIik7CiAgICAgICAgICAgICAgICB9CiNlbmRpZgoKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9JTkRFWEJVRkZFUjoKICAgICAgICAvKiBNU0ROOiBXaGVuIGFuIGFwcGxpY2F0aW9uIG5vIGxvbmdlciBob2xkcyBhIHJlZmVyZW5jZXMgdG8gdGhpcyBpbnRlcmZhY2UsIHRoZSBpbnRlcmZhY2Ugd2lsbCBhdXRvbWF0aWNhbGx5IGJlIGZyZWVkLiovCiAgICAgICAgaWYgKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2sgIT0gTlVMTCApIHsgLyogPT1OVUxMIHdoZW4gZGV2aWNlIGlzIGJlaW5nIGRlc3Ryb3llZCAqLwogICAgICAgICAgICBpZiAoVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+cEluZGV4RGF0YSA9PSAoSVdpbmVEM0RJbmRleEJ1ZmZlciAqKXJlc291cmNlKSB7CiAgICAgICAgICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5wSW5kZXhEYXRhID0gIE5VTEw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKFRoaXMtPnN0YXRlQmxvY2sgIT0gTlVMTCApIHsgLyogPT1OVUxMIHdoZW4gZGV2aWNlIGlzIGJlaW5nIGRlc3Ryb3llZCAqLwogICAgICAgICAgICBpZiAoVGhpcy0+c3RhdGVCbG9jay0+cEluZGV4RGF0YSA9PSAoSVdpbmVEM0RJbmRleEJ1ZmZlciAqKXJlc291cmNlKSB7CiAgICAgICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5wSW5kZXhEYXRhID0gIE5VTEw7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgRklYTUUoIiglcCkgdW5rbm93biByZXNvdXJjZSB0eXBlICVwICV1XG4iLCBUaGlzLCByZXNvdXJjZSwgSVdpbmVEM0RSZXNvdXJjZV9HZXRUeXBlKHJlc291cmNlKSk7CiAgICAgICAgYnJlYWs7CiAgICB9CgoKICAgIC8qIFJlbW92ZSB0aGUgcmVzb3J1Y2UgZnJvbSB0aGUgcmVzb3VyY2VTdG9yZSAqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX1JlbW92ZVJlc291cmNlKGlmYWNlLCByZXNvdXJjZSk7CgogICAgVFJBQ0UoIlJlc291cmNlIHJlbGVhc2VkXG4iKTsKCn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfRW51bVJlc291cmNlcyhJV2luZUQzRERldmljZSAqaWZhY2UsIEQzRENCX0VOVU1SRVNPVVJDRVMgcENhbGxiYWNrLCB2b2lkICpwRGF0YSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEUmVzb3VyY2VJbXBsICpyZXNvdXJjZSwgKmN1cnNvcjsKICAgIEhSRVNVTFQgcmV0OwogICAgVFJBQ0UoIiglcCktPiglcCwlcClcbiIsIFRoaXMsIHBDYWxsYmFjaywgcERhdGEpOwoKICAgIExJU1RfRk9SX0VBQ0hfRU5UUllfU0FGRShyZXNvdXJjZSwgY3Vyc29yLCAmVGhpcy0+cmVzb3VyY2VzLCBJV2luZUQzRFJlc291cmNlSW1wbCwgcmVzb3VyY2UucmVzb3VyY2VfbGlzdF9lbnRyeSkgewogICAgICAgIFRSQUNFKCJlbnVtZXJhdGluZyByZXNvdXJjZSAlcFxuIiwgcmVzb3VyY2UpOwogICAgICAgIElXaW5lRDNEUmVzb3VyY2VfQWRkUmVmKChJV2luZUQzRFJlc291cmNlICopIHJlc291cmNlKTsKICAgICAgICByZXQgPSBwQ2FsbGJhY2soKElXaW5lRDNEUmVzb3VyY2UgKikgcmVzb3VyY2UsIHBEYXRhKTsKICAgICAgICBpZihyZXQgPT0gU19GQUxTRSkgewogICAgICAgICAgICBUUkFDRSgiQ2FuY2VsaW5nIGVudW1lcmF0aW9uXG4iKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElXaW5lRDNERGV2aWNlIFZUYmwgZm9sbG93cwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCmNvbnN0IElXaW5lRDNERGV2aWNlVnRibCBJV2luZUQzRERldmljZV9WdGJsID0KewogICAgLyoqKiBJVW5rbm93biBtZXRob2RzICoqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9RdWVyeUludGVyZmFjZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9BZGRSZWYsCiAgICBJV2luZUQzRERldmljZUltcGxfUmVsZWFzZSwKICAgIC8qKiogSVdpbmVEM0REZXZpY2UgbWV0aG9kcyAqKiovCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UGFyZW50LAogICAgLyoqKiBDcmVhdGlvbiBtZXRob2RzKiovCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVmVydGV4QnVmZmVyLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZUluZGV4QnVmZmVyLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVN0YXRlQmxvY2ssCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlU3VyZmFjZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVUZXh0dXJlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZvbHVtZVRleHR1cmUsCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVm9sdW1lLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZUN1YmVUZXh0dXJlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVF1ZXJ5LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZUFkZGl0aW9uYWxTd2FwQ2hhaW4sCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVmVydGV4RGVjbGFyYXRpb24sCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVmVydGV4RGVjbGFyYXRpb25Gcm9tRlZGLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZlcnRleFNoYWRlciwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVQaXhlbFNoYWRlciwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVQYWxldHRlLAogICAgLyoqKiBPZGQgZnVuY3Rpb25zICoqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX0luaXQzRCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9VbmluaXQzRCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRGdWxsc2NyZWVuLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldE11bHRpdGhyZWFkZWQsCiAgICBJV2luZUQzRERldmljZUltcGxfRXZpY3RNYW5hZ2VkUmVzb3VyY2VzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEF2YWlsYWJsZVRleHR1cmVNZW0sCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0QmFja0J1ZmZlciwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRDcmVhdGlvblBhcmFtZXRlcnMsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0RGV2aWNlQ2FwcywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXREaXJlY3QzRCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXREaXNwbGF5TW9kZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXREaXNwbGF5TW9kZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRIV05ELAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEhXTkQsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0TnVtYmVyT2ZTd2FwQ2hhaW5zLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFJhc3RlclN0YXR1cywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTd2FwQ2hhaW4sCiAgICBJV2luZUQzRERldmljZUltcGxfUmVzZXQsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0RGlhbG9nQm94TW9kZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRDdXJzb3JQcm9wZXJ0aWVzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEN1cnNvclBvc2l0aW9uLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1Nob3dDdXJzb3IsCiAgICBJV2luZUQzRERldmljZUltcGxfVGVzdENvb3BlcmF0aXZlTGV2ZWwsCiAgICAvKioqIEdldHRlcnMgYW5kIHNldHRlcnMgKiovCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0Q2xpcFBsYW5lLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldENsaXBQbGFuZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRDbGlwU3RhdHVzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldENsaXBTdGF0dXMsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0Q3VycmVudFRleHR1cmVQYWxldHRlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEN1cnJlbnRUZXh0dXJlUGFsZXR0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXREZXB0aFN0ZW5jaWxTdXJmYWNlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldERlcHRoU3RlbmNpbFN1cmZhY2UsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0RlZGLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEZWRiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRHYW1tYVJhbXAsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0R2FtbWFSYW1wLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEluZGljZXMsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0SW5kaWNlcywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRCYXNlVmVydGV4SW5kZXgsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0QmFzZVZlcnRleEluZGV4LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldExpZ2h0LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldExpZ2h0LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldExpZ2h0RW5hYmxlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldExpZ2h0RW5hYmxlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldE1hdGVyaWFsLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldE1hdGVyaWFsLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldE5QYXRjaE1vZGUsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0TlBhdGNoTW9kZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRQYWxldHRlRW50cmllcywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQYWxldHRlRW50cmllcywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRQaXhlbFNoYWRlciwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQaXhlbFNoYWRlciwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRQaXhlbFNoYWRlckNvbnN0YW50QiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQaXhlbFNoYWRlckNvbnN0YW50QiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRQaXhlbFNoYWRlckNvbnN0YW50SSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQaXhlbFNoYWRlckNvbnN0YW50SSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRQaXhlbFNoYWRlckNvbnN0YW50RiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQaXhlbFNoYWRlckNvbnN0YW50RiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRSZW5kZXJTdGF0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRSZW5kZXJTdGF0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRSZW5kZXJUYXJnZXQsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UmVuZGVyVGFyZ2V0LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEZyb250QmFja0J1ZmZlcnMsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0U2FtcGxlclN0YXRlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFNhbXBsZXJTdGF0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRTY2lzc29yUmVjdCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTY2lzc29yUmVjdCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRTb2Z0d2FyZVZlcnRleFByb2Nlc3NpbmcsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0U29mdHdhcmVWZXJ0ZXhQcm9jZXNzaW5nLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFN0cmVhbVNvdXJjZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTdHJlYW1Tb3VyY2UsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0U3RyZWFtU291cmNlRnJlcSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTdHJlYW1Tb3VyY2VGcmVxLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFRleHR1cmUsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0VGV4dHVyZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRUZXh0dXJlU3RhZ2VTdGF0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRUZXh0dXJlU3RhZ2VTdGF0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRUcmFuc2Zvcm0sCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0VHJhbnNmb3JtLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZlcnRleERlY2xhcmF0aW9uLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZlcnRleERlY2xhcmF0aW9uLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZlcnRleFNoYWRlciwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWZXJ0ZXhTaGFkZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0VmVydGV4U2hhZGVyQ29uc3RhbnRCLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZlcnRleFNoYWRlckNvbnN0YW50QiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEksCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0VmVydGV4U2hhZGVyQ29uc3RhbnRJLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZlcnRleFNoYWRlckNvbnN0YW50RiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEYsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0Vmlld3BvcnQsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0Vmlld3BvcnQsCiAgICBJV2luZUQzRERldmljZUltcGxfTXVsdGlwbHlUcmFuc2Zvcm0sCiAgICBJV2luZUQzRERldmljZUltcGxfVmFsaWRhdGVEZXZpY2UsCiAgICBJV2luZUQzRERldmljZUltcGxfUHJvY2Vzc1ZlcnRpY2VzLAogICAgLyoqKiBTdGF0ZSBibG9jayAqKiovCiAgICBJV2luZUQzRERldmljZUltcGxfQmVnaW5TdGF0ZUJsb2NrLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0VuZFN0YXRlQmxvY2ssCiAgICAvKioqIFNjZW5lIG1hbmFnZW1lbnQgKioqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX0JlZ2luU2NlbmUsCiAgICBJV2luZUQzRERldmljZUltcGxfRW5kU2NlbmUsCiAgICBJV2luZUQzRERldmljZUltcGxfUHJlc2VudCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DbGVhciwKICAgIC8qKiogRHJhd2luZyAqKiovCiAgICBJV2luZUQzRERldmljZUltcGxfRHJhd1ByaW1pdGl2ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3SW5kZXhlZFByaW1pdGl2ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3UHJpbWl0aXZlVVAsCiAgICBJV2luZUQzRERldmljZUltcGxfRHJhd0luZGV4ZWRQcmltaXRpdmVVUCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3UHJpbWl0aXZlU3RyaWRlZCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3SW5kZXhlZFByaW1pdGl2ZVN0cmlkZWQsCiAgICBJV2luZUQzRERldmljZUltcGxfRHJhd1JlY3RQYXRjaCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3VHJpUGF0Y2gsCiAgICBJV2luZUQzRERldmljZUltcGxfRGVsZXRlUGF0Y2gsCiAgICBJV2luZUQzRERldmljZUltcGxfQ29sb3JGaWxsLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1VwZGF0ZVRleHR1cmUsCiAgICBJV2luZUQzRERldmljZUltcGxfVXBkYXRlU3VyZmFjZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRGcm9udEJ1ZmZlckRhdGEsCiAgICAvKioqIG9iamVjdCB0cmFja2luZyAqKiovCiAgICBJV2luZUQzRERldmljZUltcGxfUmVzb3VyY2VSZWxlYXNlZCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9FbnVtUmVzb3VyY2VzCn07CgoKY29uc3QgRFdPUkQgU2F2ZWRQaXhlbFN0YXRlc19SW05VTV9TQVZFRFBJWEVMU1RBVEVTX1JdID0gewogICAgV0lORUQzRFJTX0FMUEhBQkxFTkRFTkFCTEUgICAsCiAgICBXSU5FRDNEUlNfQUxQSEFGVU5DICAgICAgICAgICwKICAgIFdJTkVEM0RSU19BTFBIQVJFRiAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0FMUEhBVEVTVEVOQUJMRSAgICAsCiAgICBXSU5FRDNEUlNfQkxFTkRPUCAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19DT0xPUldSSVRFRU5BQkxFICAgLAogICAgV0lORUQzRFJTX0RFU1RCTEVORCAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRElUSEVSRU5BQkxFICAgICAgICwKICAgIFdJTkVEM0RSU19GSUxMTU9ERSAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0ZPR0RFTlNJVFkgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRk9HRU5EICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19GT0dTVEFSVCAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0xBU1RQSVhFTCAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfU0hBREVNT0RFICAgICAgICAgICwKICAgIFdJTkVEM0RSU19TUkNCTEVORCAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1NURU5DSUxFTkFCTEUgICAgICAsCiAgICBXSU5FRDNEUlNfU1RFTkNJTEZBSUwgICAgICAgICwKICAgIFdJTkVEM0RSU19TVEVOQ0lMRlVOQyAgICAgICAgLAogICAgV0lORUQzRFJTX1NURU5DSUxNQVNLICAgICAgICAsCiAgICBXSU5FRDNEUlNfU1RFTkNJTFBBU1MgICAgICAgICwKICAgIFdJTkVEM0RSU19TVEVOQ0lMUkVGICAgICAgICAgLAogICAgV0lORUQzRFJTX1NURU5DSUxXUklURU1BU0sgICAsCiAgICBXSU5FRDNEUlNfU1RFTkNJTFpGQUlMICAgICAgICwKICAgIFdJTkVEM0RSU19URVhUVVJFRkFDVE9SICAgICAgLAogICAgV0lORUQzRFJTX1dSQVAwICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfV1JBUDEgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19XUkFQMiAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1dSQVAzICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfV1JBUDQgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19XUkFQNSAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1dSQVA2ICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfV1JBUDcgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19aRU5BQkxFICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1pGVU5DICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfWldSSVRFRU5BQkxFCn07Cgpjb25zdCBEV09SRCBTYXZlZFBpeGVsU3RhdGVzX1RbTlVNX1NBVkVEUElYRUxTVEFURVNfVF0gPSB7CiAgICBXSU5FRDNEVFNTX0FERFJFU1NXICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0FMUEhBQVJHMCAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0FMUEhBQVJHMSAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0FMUEhBQVJHMiAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0FMUEhBT1AgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0JVTVBFTlZMT0ZGU0VUICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0JVTVBFTlZMU0NBTEUgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0JVTVBFTlZNQVQwMCAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0JVTVBFTlZNQVQwMSAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0JVTVBFTlZNQVQxMCAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0JVTVBFTlZNQVQxMSAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0NPTE9SQVJHMCAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0NPTE9SQVJHMSAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0NPTE9SQVJHMiAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX0NPTE9ST1AgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX1JFU1VMVEFSRyAgICAgICAgICAgICAsCiAgICBXSU5FRDNEVFNTX1RFWENPT1JESU5ERVggICAgICAgICAsCiAgICBXSU5FRDNEVFNTX1RFWFRVUkVUUkFOU0ZPUk1GTEFHUwp9OwoKY29uc3QgRFdPUkQgU2F2ZWRQaXhlbFN0YXRlc19TW05VTV9TQVZFRFBJWEVMU1RBVEVTX1NdID0gewogICAgV0lORUQzRFNBTVBfQUREUkVTU1UgICAgICAgICAsCiAgICBXSU5FRDNEU0FNUF9BRERSRVNTViAgICAgICAgICwKICAgIFdJTkVEM0RTQU1QX0FERFJFU1NXICAgICAgICAgLAogICAgV0lORUQzRFNBTVBfQk9SREVSQ09MT1IgICAgICAsCiAgICBXSU5FRDNEU0FNUF9NQUdGSUxURVIgICAgICAgICwKICAgIFdJTkVEM0RTQU1QX01JTkZJTFRFUiAgICAgICAgLAogICAgV0lORUQzRFNBTVBfTUlQRklMVEVSICAgICAgICAsCiAgICBXSU5FRDNEU0FNUF9NSVBNQVBMT0RCSUFTICAgICwKICAgIFdJTkVEM0RTQU1QX01BWE1JUExFVkVMICAgICAgLAogICAgV0lORUQzRFNBTVBfTUFYQU5JU09UUk9QWSAgICAsCiAgICBXSU5FRDNEU0FNUF9TUkdCVEVYVFVSRSAgICAgICwKICAgIFdJTkVEM0RTQU1QX0VMRU1FTlRJTkRFWAp9OwoKY29uc3QgRFdPUkQgU2F2ZWRWZXJ0ZXhTdGF0ZXNfUltOVU1fU0FWRURWRVJURVhTVEFURVNfUl0gPSB7CiAgICBXSU5FRDNEUlNfQU1CSUVOVCAgICAgICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0FNQklFTlRNQVRFUklBTFNPVVJDRSAgICAgICAgICwKICAgIFdJTkVEM0RSU19DTElQUElORyAgICAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfQ0xJUFBMQU5FRU5BQkxFICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0NPTE9SVkVSVEVYICAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19ESUZGVVNFTUFURVJJQUxTT1VSQ0UgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRU1JU1NJVkVNQVRFUklBTFNPVVJDRSAgICAgICAgLAogICAgV0lORUQzRFJTX0ZPR0RFTlNJVFkgICAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19GT0dFTkQgICAgICAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRk9HU1RBUlQgICAgICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0ZPR1RBQkxFTU9ERSAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19GT0dWRVJURVhNT0RFICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfSU5ERVhFRFZFUlRFWEJMRU5ERU5BQkxFICAgICAgLAogICAgV0lORUQzRFJTX0xJR0hUSU5HICAgICAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19MT0NBTFZJRVdFUiAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfTVVMVElTQU1QTEVBTlRJQUxJQVMgICAgICAgICAgLAogICAgV0lORUQzRFJTX01VTFRJU0FNUExFTUFTSyAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19OT1JNQUxJWkVOT1JNQUxTICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfUEFUQ0hFREdFU1RZTEUgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1BPSU5UU0NBTEVfQSAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19QT0lOVFNDQUxFX0IgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfUE9JTlRTQ0FMRV9DICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1BPSU5UU0NBTEVFTkFCTEUgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19QT0lOVFNJWkUgICAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfUE9JTlRTSVpFX01BWCAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1BPSU5UU0laRV9NSU4gICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19QT0lOVFNQUklURUVOQUJMRSAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfUkFOR0VGT0dFTkFCTEUgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1NQRUNVTEFSTUFURVJJQUxTT1VSQ0UgICAgICAgICwKICAgIFdJTkVEM0RSU19UV0VFTkZBQ1RPUiAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfVkVSVEVYQkxFTkQgICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0NVTExNT0RFICAgICAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19GT0dDT0xPUgp9OwoKY29uc3QgRFdPUkQgU2F2ZWRWZXJ0ZXhTdGF0ZXNfVFtOVU1fU0FWRURWRVJURVhTVEFURVNfVF0gPSB7CiAgICBXSU5FRDNEVFNTX1RFWENPT1JESU5ERVggICAgICAgICAsCiAgICBXSU5FRDNEVFNTX1RFWFRVUkVUUkFOU0ZPUk1GTEFHUwp9OwoKY29uc3QgRFdPUkQgU2F2ZWRWZXJ0ZXhTdGF0ZXNfU1tOVU1fU0FWRURWRVJURVhTVEFURVNfU10gPSB7CiAgICBXSU5FRDNEU0FNUF9ETUFQT0ZGU0VUCn07Cgp2b2lkIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShJV2luZUQzRERldmljZUltcGwgKlRoaXMsIERXT1JEIHN0YXRlKSB7CiAgICBEV09SRCByZXAgPSBTdGF0ZVRhYmxlW3N0YXRlXS5yZXByZXNlbnRhdGl2ZTsKICAgIERXT1JEIGlkeDsKICAgIEJZVEUgc2hpZnQ7CiAgICBVSU5UIGk7CiAgICBXaW5lRDNEQ29udGV4dCAqY29udGV4dDsKCiAgICBpZighcmVwKSByZXR1cm47CiAgICBmb3IoaSA9IDA7IGkgPCBUaGlzLT5udW1Db250ZXh0czsgaSsrKSB7CiAgICAgICAgY29udGV4dCA9IFRoaXMtPmNvbnRleHRzW2ldOwogICAgICAgIGlmKGlzU3RhdGVEaXJ0eShjb250ZXh0LCByZXApKSBjb250aW51ZTsKCiAgICAgICAgY29udGV4dC0+ZGlydHlBcnJheVtjb250ZXh0LT5udW1EaXJ0eUVudHJpZXMrK10gPSByZXA7CiAgICAgICAgaWR4ID0gcmVwID4+IDU7CiAgICAgICAgc2hpZnQgPSByZXAgJiAweDFmOwogICAgICAgIGNvbnRleHQtPmlzU3RhdGVEaXJ0eVtpZHhdIHw9ICgxIDw8IHNoaWZ0KTsKICAgIH0KfQoKdm9pZCBnZXRfZHJhd2FibGVfc2l6ZV9wYnVmZmVyKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMsIFVJTlQgKndpZHRoLCBVSU5UICpoZWlnaHQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqZGV2ID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZTsKICAgIC8qIFRoZSBkcmF3YWJsZSBzaXplIG9mIGEgcGJ1ZmZlciByZW5kZXIgdGFyZ2V0IGlzIHRoZSBjdXJyZW50IHBidWZmZXIgc2l6ZQogICAgICovCiAgICAqd2lkdGggPSBkZXYtPnBidWZmZXJXaWR0aDsKICAgICpoZWlnaHQgPSBkZXYtPnBidWZmZXJIZWlnaHQ7Cn0KCnZvaWQgZ2V0X2RyYXdhYmxlX3NpemVfZmJvKElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMsIFVJTlQgKndpZHRoLCBVSU5UICpoZWlnaHQpIHsKICAgIC8qIFRoZSBkcmF3YWJsZSBzaXplIG9mIGEgZmJvIHRhcmdldCBpcyB0aGUgb3BlbmdsIHRleHR1cmUgc2l6ZSwgd2hpY2ggaXMgdGhlIHBvd2VyIG9mIHR3byBzaXplCiAgICAgKi8KICAgICp3aWR0aCA9IFRoaXMtPnBvdzJXaWR0aDsKICAgICpoZWlnaHQgPSBUaGlzLT5wb3cySGVpZ2h0Owp9Cgp2b2lkIGdldF9kcmF3YWJsZV9zaXplX2JhY2tidWZmZXIoSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcywgVUlOVCAqd2lkdGgsIFVJTlQgKmhlaWdodCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXYgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOwogICAgLyogVGhlIGRyYXdhYmxlIHNpemUgb2YgYSBiYWNrYnVmZmVyIC8gYXV4IGJ1ZmZlciBvZmZzY3JlZW4gdGFyZ2V0IGlzIHRoZSBzaXplIG9mIHRoZQogICAgICogY3VycmVudCBjb250ZXh0J3MgZHJhd2FibGUsIHdoaWNoIGlzIHRoZSBzaXplIG9mIHRoZSBiYWNrIGJ1ZmZlciBvZiB0aGUgc3dhcGNoYWluCiAgICAgKiB0aGUgYWN0aXZlIGNvbnRleHQgYmVsb25ncyB0by4gVGhlIGJhY2sgYnVmZmVyIG9mIHRoZSBzd2FwY2hhaW4gaXMgc3RvcmVkIGFzIHRoZQogICAgICogc3VyZmFjZSB0aGUgY29udGV4dCBiZWxvbmdzIHRvLgogICAgICovCiAgICAqd2lkdGggPSAoKElXaW5lRDNEU3VyZmFjZUltcGwgKikgZGV2LT5hY3RpdmVDb250ZXh0LT5zdXJmYWNlKS0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAqaGVpZ2h0ID0gKChJV2luZUQzRFN1cmZhY2VJbXBsICopIGRldi0+YWN0aXZlQ29udGV4dC0+c3VyZmFjZSktPmN1cnJlbnREZXNjLkhlaWdodDsKfQo=