LyoKICogSVdpbmVEM0REZXZpY2UgaW1wbGVtZW50YXRpb24KICoKICogQ29weXJpZ2h0IDIwMDIgTGlvbmVsIFVsbWVyCiAqIENvcHlyaWdodCAyMDAyLTIwMDUgSmFzb24gRWRtZWFkZXMKICogQ29weXJpZ2h0IDIwMDMtMjAwNCBSYXBoYWVsIEp1bnF1ZWlyYQogKiBDb3B5cmlnaHQgMjAwNCBDaHJpc3RpYW4gQ29zdGEKICogQ29weXJpZ2h0IDIwMDUgT2xpdmVyIFN0aWViZXIKICogQ29weXJpZ2h0IDIwMDYgU3RlZmFuIET2c2luZ2VyIGZvciBDb2RlV2VhdmVycwogKiBDb3B5cmlnaHQgMjAwNiBIZW5yaSBWZXJiZWV0CiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpZmRlZiBIQVZFX0ZMT0FUX0gKIyBpbmNsdWRlIDxmbG9hdC5oPgojZW5kaWYKI2luY2x1ZGUgIndpbmVkM2RfcHJpdmF0ZS5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoZDNkKTsKI2RlZmluZSBHTElORk9fTE9DQVRJT04gKChJV2luZUQzREltcGwgKikoVGhpcy0+d2luZUQzRCkpLT5nbF9pbmZvCgovKiBEZWZpbmUgdGhlIGRlZmF1bHQgbGlnaHQgcGFyYW1ldGVycyBhcyBzcGVjaWZpZWQgYnkgTVNETiAqLwpjb25zdCBXSU5FRDNETElHSFQgV0lORUQzRF9kZWZhdWx0X2xpZ2h0ID0gewoKICAgIFdJTkVEM0RMSUdIVF9ESVJFQ1RJT05BTCwgLyogVHlwZSAqLwogICAgeyAxLjAsIDEuMCwgMS4wLCAwLjAgfSwgICAvKiBEaWZmdXNlIHIsZyxiLGEgKi8KICAgIHsgMC4wLCAwLjAsIDAuMCwgMC4wIH0sICAgLyogU3BlY3VsYXIgcixnLGIsYSAqLwogICAgeyAwLjAsIDAuMCwgMC4wLCAwLjAgfSwgICAvKiBBbWJpZW50IHIsZyxiLGEsICovCiAgICB7IDAuMCwgMC4wLCAwLjAgfSwgICAgICAgIC8qIFBvc2l0aW9uIHgseSx6ICovCiAgICB7IDAuMCwgMC4wLCAxLjAgfSwgICAgICAgIC8qIERpcmVjdGlvbiB4LHkseiAqLwogICAgMC4wLCAgICAgICAgICAgICAgICAgICAgICAvKiBSYW5nZSAqLwogICAgMC4wLCAgICAgICAgICAgICAgICAgICAgICAvKiBGYWxsb2ZmICovCiAgICAwLjAsIDAuMCwgMC4wLCAgICAgICAgICAgIC8qIEF0dGVudWF0aW9uIDAsMSwyICovCiAgICAwLjAsICAgICAgICAgICAgICAgICAgICAgIC8qIFRoZXRhICovCiAgICAwLjAgICAgICAgICAgICAgICAgICAgICAgIC8qIFBoaSAqLwp9OwoKLyogeDExZHJ2IEdESSBlc2NhcGVzICovCiNkZWZpbmUgWDExRFJWX0VTQ0FQRSA2Nzg5CmVudW0geDExZHJ2X2VzY2FwZV9jb2Rlcwp7CiAgICBYMTFEUlZfR0VUX0RJU1BMQVksICAgLyogZ2V0IFgxMSBkaXNwbGF5IGZvciBhIERDICovCiAgICBYMTFEUlZfR0VUX0RSQVdBQkxFLCAgLyogZ2V0IGN1cnJlbnQgZHJhd2FibGUgZm9yIGEgREMgKi8KICAgIFgxMURSVl9HRVRfRk9OVCwgICAgICAvKiBnZXQgY3VycmVudCBYIGZvbnQgZm9yIGEgREMgKi8KfTsKCi8qIHJldHJpZXZlIHRoZSBYIGRpc3BsYXkgdG8gdXNlIG9uIGEgZ2l2ZW4gREMgKi8Kc3RhdGljIGlubGluZSBEaXNwbGF5ICpnZXRfZGlzcGxheSggSERDIGhkYyApCnsKICAgIERpc3BsYXkgKmRpc3BsYXk7CiAgICBlbnVtIHgxMWRydl9lc2NhcGVfY29kZXMgZXNjYXBlID0gWDExRFJWX0dFVF9ESVNQTEFZOwoKICAgIGlmICghRXh0RXNjYXBlKCBoZGMsIFgxMURSVl9FU0NBUEUsIHNpemVvZihlc2NhcGUpLCAoTFBDU1RSKSZlc2NhcGUsCiAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGRpc3BsYXkpLCAoTFBTVFIpJmRpc3BsYXkgKSkgZGlzcGxheSA9IE5VTEw7CiAgICByZXR1cm4gZGlzcGxheTsKfQoKLyogc3RhdGljIGZ1bmN0aW9uIGRlY2xhcmF0aW9ucyAqLwpzdGF0aWMgdm9pZCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0FkZFJlc291cmNlKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RSZXNvdXJjZSAqcmVzb3VyY2UpOwoKc3RhdGljIHZvaWQgc2V0X2RlcHRoX3N0ZW5jaWxfZmJvKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RTdXJmYWNlICpkZXB0aF9zdGVuY2lsKTsKCi8qIGhlbHBlciBtYWNyb3MgKi8KI2RlZmluZSBEM0RNRU1DSEVDSyhvYmplY3QsIHBwUmVzdWx0KSBpZihOVUxMID09IG9iamVjdCkgeyAqcHBSZXN1bHQgPSBOVUxMOyBXQVJOKCJPdXQgb2YgbWVtb3J5XG4iKTsgcmV0dXJuIFdJTkVEM0RFUlJfT1VUT0ZWSURFT01FTU9SWTt9CgojZGVmaW5lIEQzRENSRUFURU9CSkVDVElOU1RBTkNFKG9iamVjdCwgdHlwZSkgeyBcCiAgICBvYmplY3Q9SGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJV2luZUQzRCMjdHlwZSMjSW1wbCkpOyBcCiAgICBEM0RNRU1DSEVDSyhvYmplY3QsIHBwIyN0eXBlKTsgXAogICAgb2JqZWN0LT5scFZ0YmwgPSAmSVdpbmVEM0QjI3R5cGUjI19WdGJsOyAgXAogICAgb2JqZWN0LT53aW5lRDNERGV2aWNlID0gVGhpczsgXAogICAgb2JqZWN0LT5wYXJlbnQgICAgICAgPSBwYXJlbnQ7IFwKICAgIG9iamVjdC0+cmVmICAgICAgICAgID0gMTsgXAogICAgKnBwIyN0eXBlID0gKElXaW5lRDNEIyN0eXBlICopIG9iamVjdDsgXAp9CgojZGVmaW5lIEQzRENSRUFURVNIQURFUk9CSkVDVElOU1RBTkNFKG9iamVjdCwgdHlwZSkgeyBcCiAgICBvYmplY3Q9SGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJV2luZUQzRCMjdHlwZSMjSW1wbCkpOyBcCiAgICBEM0RNRU1DSEVDSyhvYmplY3QsIHBwIyN0eXBlKTsgXAogICAgb2JqZWN0LT5scFZ0YmwgPSAmSVdpbmVEM0QjI3R5cGUjI19WdGJsOyAgXAogICAgb2JqZWN0LT5wYXJlbnQgICAgICAgPSBwYXJlbnQ7IFwKICAgIG9iamVjdC0+cmVmICAgICAgICAgID0gMTsgXAogICAgb2JqZWN0LT5iYXNlU2hhZGVyLmRldmljZSA9IChJV2luZUQzRERldmljZSopIFRoaXM7IFwKICAgIGxpc3RfaW5pdCgmb2JqZWN0LT5iYXNlU2hhZGVyLmxpbmtlZF9wcm9ncmFtcyk7IFwKICAgICpwcCMjdHlwZSA9IChJV2luZUQzRCMjdHlwZSAqKSBvYmplY3Q7IFwKfQoKI2RlZmluZSAgRDNEQ1JFQVRFUkVTT1VSQ0VPQkpFQ1RJTlNUQU5DRShvYmplY3QsIHR5cGUsIGQzZHR5cGUsIF9zaXplKXsgXAogICAgb2JqZWN0PUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSVdpbmVEM0QjI3R5cGUjI0ltcGwpKTsgXAogICAgRDNETUVNQ0hFQ0sob2JqZWN0LCBwcCMjdHlwZSk7IFwKICAgIG9iamVjdC0+bHBWdGJsID0gJklXaW5lRDNEIyN0eXBlIyNfVnRibDsgIFwKICAgIG9iamVjdC0+cmVzb3VyY2Uud2luZUQzRERldmljZSAgID0gVGhpczsgXAogICAgb2JqZWN0LT5yZXNvdXJjZS5wYXJlbnQgICAgICAgICAgPSBwYXJlbnQ7IFwKICAgIG9iamVjdC0+cmVzb3VyY2UucmVzb3VyY2VUeXBlICAgID0gZDNkdHlwZTsgXAogICAgb2JqZWN0LT5yZXNvdXJjZS5yZWYgICAgICAgICAgICAgPSAxOyBcCiAgICBvYmplY3QtPnJlc291cmNlLnBvb2wgICAgICAgICAgICA9IFBvb2w7IFwKICAgIG9iamVjdC0+cmVzb3VyY2UuZm9ybWF0ICAgICAgICAgID0gRm9ybWF0OyBcCiAgICBvYmplY3QtPnJlc291cmNlLnVzYWdlICAgICAgICAgICA9IFVzYWdlOyBcCiAgICBvYmplY3QtPnJlc291cmNlLnNpemUgICAgICAgICAgICA9IF9zaXplOyBcCiAgICAvKiBDaGVjayB0aGF0IHdlIGhhdmUgZW5vdWdoIHZpZGVvIHJhbSBsZWZ0ICovIFwKICAgIGlmIChQb29sID09IFdJTkVEM0RQT09MX0RFRkFVTFQpIHsgXAogICAgICAgIGlmIChJV2luZUQzRERldmljZV9HZXRBdmFpbGFibGVUZXh0dXJlTWVtKGlmYWNlKSA8PSBfc2l6ZSkgeyBcCiAgICAgICAgICAgIFdBUk4oIk91dCBvZiAnYm9ndXMnIHZpZGVvIG1lbW9yeVxuIik7IFwKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2JqZWN0KTsgXAogICAgICAgICAgICAqcHAjI3R5cGUgPSBOVUxMOyBcCiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX09VVE9GVklERU9NRU1PUlk7IFwKICAgICAgICB9IFwKICAgICAgICBnbG9iYWxDaGFuZ2VHbFJhbShfc2l6ZSk7IFwKICAgIH0gXAogICAgb2JqZWN0LT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSAoMCA9PSBfc2l6ZSA/IE5VTEwgOiBQb29sID09IFdJTkVEM0RQT09MX0RFRkFVTFQgPyBOVUxMIDogSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIF9zaXplKSk7IFwKICAgIGlmIChvYmplY3QtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9PSBOVUxMICYmIF9zaXplICE9IDAgJiYgUG9vbCAhPSBXSU5FRDNEUE9PTF9ERUZBVUxUKSB7IFwKICAgICAgICBGSVhNRSgiT3V0IG9mIG1lbW9yeSFcbiIpOyBcCiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2JqZWN0KTsgXAogICAgICAgICpwcCMjdHlwZSA9IE5VTEw7IFwKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9PVVRPRlZJREVPTUVNT1JZOyBcCiAgICB9IFwKICAgICpwcCMjdHlwZSA9IChJV2luZUQzRCMjdHlwZSAqKSBvYmplY3Q7IFwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9BZGRSZXNvdXJjZShpZmFjZSwgKElXaW5lRDNEUmVzb3VyY2UgKilvYmplY3QpIDtcCiAgICBUUkFDRSgiKCVwKSA6IENyZWF0ZWQgcmVzb3VyY2UgJXBcbiIsIFRoaXMsIG9iamVjdCk7IFwKfQoKI2RlZmluZSBEM0RJTklUSUFMSVpFQkFTRVRFWFRVUkUoX2Jhc2V0ZXh0dXJlKSB7IFwKICAgIF9iYXNldGV4dHVyZS5sZXZlbHMgICAgID0gTGV2ZWxzOyBcCiAgICBfYmFzZXRleHR1cmUuZmlsdGVyVHlwZSA9IChVc2FnZSAmIFdJTkVEM0RVU0FHRV9BVVRPR0VOTUlQTUFQKSA/IFdJTkVEM0RURVhGX0xJTkVBUiA6IFdJTkVEM0RURVhGX05PTkU7IFwKICAgIF9iYXNldGV4dHVyZS5MT0QgICAgICAgID0gMDsgXAogICAgX2Jhc2V0ZXh0dXJlLmRpcnR5ICAgICAgPSBUUlVFOyBcCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEdsb2JhbCB2YXJpYWJsZSAvIENvbnN0YW50cyBmb2xsb3cKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCmNvbnN0IGZsb2F0IGlkZW50aXR5WzE2XSA9IHsxLDAsMCwwLCAwLDEsMCwwLCAwLDAsMSwwLCAwLDAsMCwxfTsgIC8qIFdoZW4gbmVlZGVkIGZvciBjb21wYXJpc29ucyAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVVua25vd24gcGFydHMgZm9sbG93cwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfUXVlcnlJbnRlcmZhY2UoSVdpbmVEM0REZXZpY2UgKmlmYWNlLFJFRklJRCByaWlkLExQVk9JRCAqcHBvYmopCnsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKS0+KCVzLCVwKVxuIixUaGlzLGRlYnVnc3RyX2d1aWQocmlpZCkscHBvYmopOwogICAgaWYgKElzRXF1YWxHVUlEKHJpaWQsICZJSURfSVVua25vd24pCiAgICAgICAgfHwgSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JV2luZUQzREJhc2UpCiAgICAgICAgfHwgSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JV2luZUQzRERldmljZSkpIHsKICAgICAgICBJVW5rbm93bl9BZGRSZWYoaWZhY2UpOwogICAgICAgICpwcG9iaiA9IFRoaXM7CiAgICAgICAgcmV0dXJuIFNfT0s7CiAgICB9CiAgICAqcHBvYmogPSBOVUxMOwogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0FkZFJlZihJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFVMT05HIHJlZkNvdW50ID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZik7CgogICAgVFJBQ0UoIiglcCkgOiBBZGRSZWYgaW5jcmVhc2luZyBmcm9tICVkXG4iLCBUaGlzLCByZWZDb3VudCAtIDEpOwogICAgcmV0dXJuIHJlZkNvdW50Owp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9SZWxlYXNlKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVUxPTkcgcmVmQ291bnQgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgICBUUkFDRSgiKCVwKSA6IFJlbGVhc2luZyBmcm9tICVkXG4iLCBUaGlzLCByZWZDb3VudCArIDEpOwoKICAgIGlmICghcmVmQ291bnQpIHsKICAgICAgICBpZiAoVGhpcy0+ZmJvKSB7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xEZWxldGVGcmFtZWJ1ZmZlcnNFWFQoMSwgJlRoaXMtPmZibykpOwogICAgICAgIH0KCiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cmVuZGVyX3RhcmdldHMpOwoKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5kcmF3X2J1ZmZlcnMpOwoKICAgICAgICBpZiAoVGhpcy0+Z2xzbF9wcm9ncmFtX2xvb2t1cCkgaGFzaF90YWJsZV9kZXN0cm95KFRoaXMtPmdsc2xfcHJvZ3JhbV9sb29rdXApOwoKICAgICAgICAvKiBUT0RPOiBDbGVhbiB1cCBhbGwgdGhlIHN1cmZhY2VzIGFuZCB0ZXh0dXJlcyEgKi8KICAgICAgICAvKiBOT1RFOiBZb3UgbXVzdCByZWxlYXNlIHRoZSBwYXJlbnQgaWYgdGhlIG9iamVjdCB3YXMgY3JlYXRlZCB2aWEgYSBjYWxsYmFjawogICAgICAgICoqICoqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICAgICAgLyogUmVsZWFzZSB0aGUgdXBkYXRlIHN0YXRlYmxvY2sgKi8KICAgICAgICBpZihJV2luZUQzRFN0YXRlQmxvY2tfUmVsZWFzZSgoSVdpbmVEM0RTdGF0ZUJsb2NrICopVGhpcy0+dXBkYXRlU3RhdGVCbG9jaykgPiAwKXsKICAgICAgICAgICAgaWYoVGhpcy0+dXBkYXRlU3RhdGVCbG9jayAhPSBUaGlzLT5zdGF0ZUJsb2NrKQogICAgICAgICAgICAgICAgRklYTUUoIiglcCkgU29tZXRoaW5nJ3Mgc3RpbGwgaG9sZGluZyB0aGUgVXBkYXRlIHN0YXRlYmxvY2tcbiIsVGhpcyk7CiAgICAgICAgfQogICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2sgPSBOVUxMOwogICAgICAgIHsgLyogYmVjYXVzZSB3ZXJlIG5vdCBkb2luZyBwcm9wZXIgaW50ZXJuYWwgcmVmY291bnRzIHJlbGVhc2luZyB0aGUgcHJpbWFyeSBzdGF0ZSBibG9jawogICAgICAgICAgICBjYXVzZXMgcmVjdXJzaW9uIHdpdGggdGhlIGV4dHJhIGNoZWNrcyBpbiBSZXNvdXJjZVJlbGVhc2VkLCB0byBhdm9pZCB0aGlzIHdlIGhhdmUKICAgICAgICAgICAgdG8gc2V0IHRoaXMtPnN0YXRlQmxvY2sgPSBOVUxMOyBmaXJzdCAqLwogICAgICAgICAgICBJV2luZUQzRFN0YXRlQmxvY2sgKnN0YXRlQmxvY2sgPSAoSVdpbmVEM0RTdGF0ZUJsb2NrICopVGhpcy0+c3RhdGVCbG9jazsKICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jayA9IE5VTEw7CgogICAgICAgICAgICAvKiBSZWxlYXNlIHRoZSBzdGF0ZWJsb2NrICovCiAgICAgICAgICAgIGlmKElXaW5lRDNEU3RhdGVCbG9ja19SZWxlYXNlKHN0YXRlQmxvY2spID4gMCl7CiAgICAgICAgICAgICAgICAgICAgRklYTUUoIiglcCkgU29tZXRoaW5nJ3Mgc3RpbGwgaG9sZGluZyB0aGUgVXBkYXRlIHN0YXRlYmxvY2tcbiIsVGhpcyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChUaGlzLT5yZXNvdXJjZXMgIT0gTlVMTCApIHsKICAgICAgICAgICAgRklYTUUoIiglcCkgRGV2aWNlIHJlbGVhc2VkIHdpdGggcmVzb3VyY2VzIHN0aWxsIGJvdW5kLCBhY2NlcHRhYmxlIGJ1dCB1bmV4cGVjdGVkXG4iLCBUaGlzKTsKICAgICAgICAgICAgZHVtcFJlc291cmNlcyhUaGlzLT5yZXNvdXJjZXMpOwogICAgICAgIH0KCiAgICAgICAgaWYoVGhpcy0+Y29udGV4dHMpIEVSUigiQ29udGV4dCBhcnJheSBub3QgZnJlZWQhXG4iKTsKCiAgICAgICAgSVdpbmVEM0RfUmVsZWFzZShUaGlzLT53aW5lRDNEKTsKICAgICAgICBUaGlzLT53aW5lRDNEID0gTlVMTDsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKICAgICAgICBUUkFDRSgiRnJlZWQgZGV2aWNlICAlcFxuIiwgVGhpcyk7CiAgICAgICAgVGhpcyA9IE5VTEw7CiAgICB9CiAgICByZXR1cm4gcmVmQ291bnQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElXaW5lRDNERGV2aWNlIGltcGxlbWVudGF0aW9uIGZvbGxvd3MKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0UGFyZW50KElXaW5lRDNERGV2aWNlICppZmFjZSwgSVVua25vd24gKipwUGFyZW50KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICAqcFBhcmVudCA9IFRoaXMtPnBhcmVudDsKICAgIElVbmtub3duX0FkZFJlZihUaGlzLT5wYXJlbnQpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyB2b2lkIENyZWF0ZVZCTyhJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKm9iamVjdCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gb2JqZWN0LT5yZXNvdXJjZS53aW5lRDNERGV2aWNlOyAgLyogTmVlZGVkIGZvciBHTF9FWFRDQUxMICovCiAgICBHTGVudW0gZXJyb3IsIGdsVXNhZ2U7CiAgICBEV09SRCB2Ym9Vc2FnZSA9IG9iamVjdC0+cmVzb3VyY2UudXNhZ2U7CiAgICBpZihvYmplY3QtPkZsYWdzICYgVkJGTEFHX1ZCT0NSRUFURUZBSUwpIHsKICAgICAgICBXQVJOKCJDcmVhdGluZyBhIHZibyBmYWlsZWQgb25jZSwgbm90IHRyeWluZyBhZ2FpblxuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIFRSQUNFKCJDcmVhdGluZyBhbiBPcGVuR0wgdmVydGV4IGJ1ZmZlciBvYmplY3QgZm9yIElXaW5lRDNEVmVydGV4QnVmZmVyICVwICBVc2FnZSglcylcbiIsIG9iamVjdCwgZGVidWdfZDNkdXNhZ2UodmJvVXNhZ2UpKTsKCiAgICBFTlRFUl9HTCgpOwogICAgLyogTWFrZSBzdXJlIHRoYXQgYSBjb250ZXh0IGlzIHRoZXJlLiBOZWVkZWQgaW4gYSBtdWx0aXRocmVhZGVkIGVudmlyb25tZW50LiBPdGhlcndpc2UgdGhpcyBjYWxsIGlzIGEgbm9wICovCiAgICBBY3RpdmF0ZUNvbnRleHQoVGhpcywgVGhpcy0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKCiAgICAvKiBNYWtlIHN1cmUgdGhhdCB0aGUgZ2wgZXJyb3IgaXMgY2xlYXJlZC4gRG8gbm90IHVzZSBjaGVja0dMY2FsbAogICAgICAqIGhlcmUgYmVjYXVzZSBjaGVja0dMY2FsbCBqdXN0IHByaW50cyBhIGZpeG1lIGFuZCBjb250aW51ZXMuIEhvd2V2ZXIsCiAgICAgICogaWYgYW4gZXJyb3IgZHVyaW5nIFZCTyBjcmVhdGlvbiBvY2N1cnMgd2UgY2FuIGZhbGwgYmFjayB0byBub24tdmJvIG9wZXJhdGlvbgogICAgICAqIHdpdGggZnVsbCBmdW5jdGlvbmFsaXR5KGJ1dCBwZXJmb3JtYW5jZSBsb3NzKQogICAgICAqLwogICAgd2hpbGUoZ2xHZXRFcnJvcigpICE9IEdMX05PX0VSUk9SKTsKCiAgICAvKiBCYXNpY2FsbHkgdGhlIEZWRiBwYXJhbWV0ZXIgcGFzc2VkIHRvIENyZWF0ZVZlcnRleEJ1ZmZlciBpcyBubyBnb29kCiAgICAgICogSXQgaXMgdGhlIEZWRiBzZXQgd2l0aCBJV2luZUQzRERldmljZTo6U2V0RlZGIG9yIHRoZSBWZXJ0ZXggRGVjbGFyYXRpb24gc2V0IHdpdGgKICAgICAgKiBJV2luZUQzRERldmljZTo6U2V0VmVydGV4RGVjbGFyYXRpb24gdGhhdCBkZWNpZGVzIGhvdyB0aGUgdmVydGljZXMgaW4gdGhlIGJ1ZmZlcgogICAgICAqIGxvb2sgbGlrZS4gVGhpcyBtZWFucyB0aGF0IG9uIGVhY2ggRHJhd1ByaW1pdGl2ZSBjYWxsIHRoZSB2ZXJ0ZXggYnVmZmVyIGhhcyB0byBiZSB2ZXJpZmllZAogICAgICAqIHRvIGNoZWNrIGlmIHRoZSByaHcgYW5kIGNvbG9yIHZhbHVlcyBhcmUgaW4gdGhlIGNvcnJlY3QgZm9ybWF0LgogICAgICAqLwoKICAgIEdMX0VYVENBTEwoZ2xHZW5CdWZmZXJzQVJCKDEsICZvYmplY3QtPnZibykpOwogICAgZXJyb3IgPSBnbEdldEVycm9yKCk7CiAgICBpZihvYmplY3QtPnZibyA9PSAwIHx8IGVycm9yICE9IEdMX05PX0VSUk9SKSB7CiAgICAgICAgV0FSTigiRmFpbGVkIHRvIGNyZWF0ZSBhIFZCTyB3aXRoIGVycm9yICVkXG4iLCBlcnJvcik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9BUlJBWV9CVUZGRVJfQVJCLCBvYmplY3QtPnZibykpOwogICAgZXJyb3IgPSBnbEdldEVycm9yKCk7CiAgICBpZihlcnJvciAhPSBHTF9OT19FUlJPUikgewogICAgICAgIFdBUk4oIkZhaWxlZCB0byBiaW5kIHRoZSBWQk8sIGVycm9yICVkXG4iLCBlcnJvcik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKiBEb24ndCB1c2Ugc3RhdGljLCBiZWNhdXNlIGR4IGFwcHMgdGVuZCB0byB1cGRhdGUgdGhlIGJ1ZmZlcgogICAgICogcXVpdGUgb2Z0ZW4gZXZlbiBpZiB0aGV5IHNwZWNpZnkgMCB1c2FnZS4gQmVjYXVzZSB3ZSBhbHdheXMga2VlcCB0aGUgbG9jYWwgY29weQogICAgICogd2UgbmV2ZXIgcmVhZCBmcm9tIHRoZSB2Ym8gYW5kIGNhbiBjcmVhdGUgYSB3cml0ZSBvbmx5IG9wZW5nbCBidWZmZXIuCiAgICAgKi8KICAgIHN3aXRjaCh2Ym9Vc2FnZSAmIChXSU5FRDNEVVNBR0VfV1JJVEVPTkxZIHwgV0lORUQzRFVTQUdFX0RZTkFNSUMpICkgewogICAgICAgIGNhc2UgV0lORUQzRFVTQUdFX1dSSVRFT05MWSB8IFdJTkVEM0RVU0FHRV9EWU5BTUlDOgogICAgICAgIGNhc2UgV0lORUQzRFVTQUdFX0RZTkFNSUM6CiAgICAgICAgICAgIFRSQUNFKCJHbCB1c2FnZSA9IEdMX1NUUkVBTV9EUkFXXG4iKTsKICAgICAgICAgICAgZ2xVc2FnZSA9IEdMX1NUUkVBTV9EUkFXX0FSQjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEVVNBR0VfV1JJVEVPTkxZOgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIFRSQUNFKCJHbCB1c2FnZSA9IEdMX0RZTkFNSUNfRFJBV1xuIik7CiAgICAgICAgICAgIGdsVXNhZ2UgPSBHTF9EWU5BTUlDX0RSQVdfQVJCOwogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICAvKiBSZXNlcnZlIG1lbW9yeSBmb3IgdGhlIGJ1ZmZlci4gVGhlIGFtb3VudCBvZiBkYXRhIHdvbid0IGNoYW5nZQogICAgICogc28gd2UgYXJlIHNhZmUgd2l0aCBjYWxsaW5nIGdsQnVmZmVyRGF0YSBvbmNlIHdpdGggYSBOVUxMIHB0ciBhbmQKICAgICAqIGNhbGxpbmcgZ2xCdWZmZXJTdWJEYXRhIG9uIHVwZGF0ZXMKICAgICAqLwogICAgR0xfRVhUQ0FMTChnbEJ1ZmZlckRhdGFBUkIoR0xfQVJSQVlfQlVGRkVSX0FSQiwgb2JqZWN0LT5yZXNvdXJjZS5zaXplLCBOVUxMLCBnbFVzYWdlKSk7CiAgICBlcnJvciA9IGdsR2V0RXJyb3IoKTsKICAgIGlmKGVycm9yICE9IEdMX05PX0VSUk9SKSB7CiAgICAgICAgV0FSTigiZ2xCdWZmZXJEYXRhQVJCIGZhaWxlZCB3aXRoIGVycm9yICVkXG4iLCBlcnJvcik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBMRUFWRV9HTCgpOwoKICAgIHJldHVybjsKICAgIGVycm9yOgogICAgLyogQ2xlYW4gdXAgYWxsIHZibyBpbml0LCBidXQgY29udGludWUgYmVjYXVzZSB3ZSBjYW4gd29yayB3aXRob3V0IGEgdmJvIDotKSAqLwogICAgRklYTUUoIkZhaWxlZCB0byBjcmVhdGUgYSB2ZXJ0ZXggYnVmZmVyIG9iamVjdC4gQ29udGludWluZywgYnV0IHBlcmZvcm1hbmNlIGlzc3VlcyBjYW4gb2NjdXJcbiIpOwogICAgaWYob2JqZWN0LT52Ym8pIEdMX0VYVENBTEwoZ2xEZWxldGVCdWZmZXJzQVJCKDEsICZvYmplY3QtPnZibykpOwogICAgb2JqZWN0LT52Ym8gPSAwOwogICAgb2JqZWN0LT5GbGFncyB8PSBWQkZMQUdfVkJPQ1JFQVRFRkFJTDsKICAgIExFQVZFX0dMKCk7CiAgICByZXR1cm47Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVmVydGV4QnVmZmVyKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBTaXplLCBEV09SRCBVc2FnZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRlZGLCBXSU5FRDNEUE9PTCBQb29sLCBJV2luZUQzRFZlcnRleEJ1ZmZlcioqIHBwVmVydGV4QnVmZmVyLCBIQU5ETEUgKnNoYXJlZEhhbmRsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJVW5rbm93biAqcGFyZW50KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKm9iamVjdDsKICAgIFdJTkVEM0RGT1JNQVQgRm9ybWF0ID0gV0lORUQzREZNVF9WRVJURVhEQVRBOyAvKiBEdW1teSBmb3JtYXQgZm9yIG5vdyAqLwogICAgaW50IGR4VmVyc2lvbiA9ICggKElXaW5lRDNESW1wbCAqKSBUaGlzLT53aW5lRDNEKS0+ZHhWZXJzaW9uOwogICAgQk9PTCBjb252OwoKICAgIGlmKFNpemUgPT0gMCkgewogICAgICAgIFdBUk4oIlNpemUgMCByZXF1ZXN0ZWQsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICAqcHBWZXJ0ZXhCdWZmZXIgPSBOVUxMOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIEQzRENSRUFURVJFU09VUkNFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBWZXJ0ZXhCdWZmZXIsIFdJTkVEM0RSVFlQRV9WRVJURVhCVUZGRVIsIFNpemUpCgogICAgVFJBQ0UoIiglcCkgOiBTaXplPSVkLCBVc2FnZT0lZCwgRlZGPSV4LCBQb29sPSVkIC0gTWVtb3J5QCVwLCBJZmFjZUAlcFxuIiwgVGhpcywgU2l6ZSwgVXNhZ2UsIEZWRiwgUG9vbCwgb2JqZWN0LT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnksIG9iamVjdCk7CiAgICAqcHBWZXJ0ZXhCdWZmZXIgPSAoSVdpbmVEM0RWZXJ0ZXhCdWZmZXIgKilvYmplY3Q7CgogICAgaWYgKFBvb2wgPT0gV0lORUQzRFBPT0xfREVGQVVMVCApIHsgLyogQWxsb2NhdGUgc29tZSBzeXN0ZW0gbWVtb3J5IGZvciBub3cgKi8KICAgICAgICBvYmplY3QtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSAgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgb2JqZWN0LT5yZXNvdXJjZS5zaXplKTsKICAgIH0KICAgIG9iamVjdC0+ZnZmID0gRlZGOwoKICAgIC8qIE9ic2VydmF0aW9ucyBzaG93IHRoYXQgZHJhd1N0cmlkZWRTbG93IGlzIGZhc3RlciBvbiBkeW5hbWljIFZCcyB0aGFuIGNvbnZlcnRpbmcgKwogICAgICogZHJhd1N0cmlkZWRGYXN0IChoYWxmLWxpZmUgMikuCiAgICAgKgogICAgICogQmFzaWNhbGx5IGNvbnZlcnRpbmcgdGhlIHZlcnRpY2VzIGluIHRoZSBidWZmZXIgaXMgcXVpdGUgZXhwZW5zaXZlLCBhbmQgb2JzZXJ2YXRpb25zCiAgICAgKiBzaG93IHRoYXQgZHJhd1N0cmlkZWRTbG93IGlzIGZhc3RlciB0aGFuIGNvbnZlcnRpbmcgKyB1cGxvYWRpbmcgKyBkcmF3U3RyaWRlZEZhc3QuCiAgICAgKiBUaGVyZWZvcmUgZG8gbm90IGNyZWF0ZSBhIFZCTyBmb3IgV0lORUQzRFVTQUdFX0RZTkFNSUMgYnVmZmVycy4KICAgICAqCiAgICAgKiBEaXJlY3QzRDcgaGFzIGFub3RoZXIgcHJvYmxlbTogSXRzIHZlcnRleGJ1ZmZlciBhcGkgZG9lc24ndCBvZmZlciBhIHdheSB0byBzcGVjaWZ5CiAgICAgKiB0aGUgcmFuZ2Ugb2YgdmVydGljZXMgYmVpbmcgbG9ja2VkLCBzbyBlYWNoIGxvY2sgd2lsbCByZXF1aXJlIHRoZSB3aG9sZSBidWZmZXIgdG8gYmUgdHJhbnNmb3JtZWQuCiAgICAgKiBNb3Jlb3ZlciBnZW9tZXRyeSBkYXRhIGluIGR4NyBpcyBxdWl0ZSBzaW1wbGUsIHNvIGRyYXdTdHJpZGVkU2xvdyBpc24ndCBhIGJpZyBoaXQuIEEgcGx1cwogICAgICogaXMgdGhhdCB0aGUgdmVydGV4IGJ1ZmZlcnMgZnZmIGNhbiBiZSB0cnVzdGVkIGluIGR4Ny4gU28gb25seSBjcmVhdGUgbm9uLWNvbnZlcnRlZCB2Ym9zIGZvcgogICAgICogZHg3IGFwcHMuCiAgICAgKiBUaGVyZSBpcyBhIElEaXJlY3QzRFZlcnRleEJ1ZmZlcjc6Ok9wdGltaXplIGNhbGwgYWZ0ZXIgd2hpY2ggdGhlIGJ1ZmZlciBjYW4ndCBiZSBsb2NrZWQgYW55CiAgICAgKiBtb3JlLiBJbiB0aGlzIGNhbGwgd2UgY2FuIGNvbnZlcnQgZHg3IGJ1ZmZlcnMgdG9vLgogICAgICovCiAgICBjb252ID0gKChGVkYgJiBXSU5FRDNERlZGX1BPU0lUSU9OX01BU0spID09IFdJTkVEM0RGVkZfWFlaUkhXICkgfHwgKEZWRiAmIChXSU5FRDNERlZGX0RJRkZVU0UgfCBXSU5FRDNERlZGX1NQRUNVTEFSKSk7CiAgICBpZiggR0xfU1VQUE9SVChBUkJfVkVSVEVYX0JVRkZFUl9PQkpFQ1QpICYmIFBvb2wgIT0gV0lORUQzRFBPT0xfU1lTVEVNTUVNICYmICEoVXNhZ2UgJiBXSU5FRDNEVVNBR0VfRFlOQU1JQykgJiYgCiAgICAgICAgKGR4VmVyc2lvbiA+IDcgfHwgIWNvbnYpICkgewogICAgICAgIENyZWF0ZVZCTyhvYmplY3QpOwogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyB2b2lkIENyZWF0ZUluZGV4QnVmZmVyVkJPKElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcywgSVdpbmVEM0RJbmRleEJ1ZmZlckltcGwgKm9iamVjdCkgewogICAgR0xlbnVtIGVycm9yLCBnbFVzYWdlOwogICAgVFJBQ0UoIkNyZWF0aW5nIFZCTyBmb3IgSW5kZXggQnVmZmVyICVwXG4iLCBvYmplY3QpOwoKICAgIC8qIFRoZSBmb2xsb3dpbmcgY29kZSB3aWxsIG1vZGlmeSB0aGUgRUxFTUVOVF9BUlJBWV9CVUZGRVIgYmluZGluZywgbWFrZSBzdXJlIGl0IGlzCiAgICAgKiByZXN0b3JlZCBvbiB0aGUgbmV4dCBkcmF3CiAgICAgKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9JTkRFWEJVRkZFUik7CgogICAgRU5URVJfR0woKTsKICAgIC8qIE1ha2Ugc3VyZSB0aGF0IGEgY29udGV4dCBpcyB0aGVyZS4gTmVlZGVkIGluIGEgbXVsdGl0aHJlYWRlZCBlbnZpcm9ubWVudC4gT3RoZXJ3aXNlIHRoaXMgY2FsbCBpcyBhIG5vcCAqLwogICAgQWN0aXZhdGVDb250ZXh0KFRoaXMsIFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQsIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CgogICAgd2hpbGUoZ2xHZXRFcnJvcigpKTsKCiAgICBHTF9FWFRDQUxMKGdsR2VuQnVmZmVyc0FSQigxLCAmb2JqZWN0LT52Ym8pKTsKICAgIGVycm9yID0gZ2xHZXRFcnJvcigpOwogICAgaWYoZXJyb3IgIT0gR0xfTk9fRVJST1IgfHwgb2JqZWN0LT52Ym8gPT0gMCkgewogICAgICAgIEVSUigiQ3JlYXRpbmcgYSB2Ym8gZmFpbGVkLCBjb250aW51ZWluZyB3aXRob3V0IHZibyBmb3IgdGhpcyBidWZmZXJcbiIpOwogICAgICAgIGdvdG8gb3V0OwogICAgfQoKICAgIEdMX0VYVENBTEwoZ2xCaW5kQnVmZmVyQVJCKEdMX0VMRU1FTlRfQVJSQVlfQlVGRkVSX0FSQiwgb2JqZWN0LT52Ym8pKTsKICAgIGVycm9yID0gZ2xHZXRFcnJvcigpOwogICAgaWYoZXJyb3IgIT0gR0xfTk9fRVJST1IpIHsKICAgICAgICBFUlIoIkZhaWxlZCB0byBiaW5kIGluZGV4IGJ1ZmZlciwgY29udGludWVpbmcgd2l0aG91dCB2Ym8gZm9yIHRoaXMgYnVmZmVyXG4iKTsKICAgICAgICBnb3RvIG91dDsKICAgIH0KCiAgICAvKiBVc2Ugc3RhdGljIHdyaXRlIG9ubHkgdXNhZ2UgZm9yIG5vdy4gRHluYW1pYyBpbmRleCBidWZmZXJzIHN0YXkgaW4gc3lzbWVtLCBhbmQgZHVlIHRvIHRoZSBzeXNtZW0KICAgICAgICAqIGNvcHkgbm8gcmVhZGJhY2sgd2lsbCBiZSBuZWVkZWQKICAgICAgICAqLwogICAgZ2xVc2FnZSA9IEdMX1NUQVRJQ19EUkFXX0FSQjsKICAgIEdMX0VYVENBTEwoZ2xCdWZmZXJEYXRhQVJCKEdMX0VMRU1FTlRfQVJSQVlfQlVGRkVSX0FSQiwgb2JqZWN0LT5yZXNvdXJjZS5zaXplLCBOVUxMLCBnbFVzYWdlKSk7CiAgICBlcnJvciA9IGdsR2V0RXJyb3IoKTsKICAgIGlmKGVycm9yICE9IEdMX05PX0VSUk9SKSB7CiAgICAgICAgRVJSKCJGYWlsZWQgdG8gaW5pdGlhbGl6ZSB0aGUgaW5kZXggYnVmZmVyXG4iKTsKICAgICAgICBnb3RvIG91dDsKICAgIH0KICAgIExFQVZFX0dMKCk7CiAgICBUUkFDRSgiU3VjY2Vzc2Z1bGx5IGNyZWF0ZWQgdmJvICVkIGZvciBpbmRleCBidWZmZXIgJXBcbiIsIG9iamVjdC0+dmJvLCBvYmplY3QpOwogICAgcmV0dXJuOwoKb3V0OgogICAgR0xfRVhUQ0FMTChnbEJpbmRCdWZmZXJBUkIoR0xfRUxFTUVOVF9BUlJBWV9CVUZGRVJfQVJCLCAwKSk7CiAgICBHTF9FWFRDQUxMKGdsRGVsZXRlQnVmZmVyc0FSQigxLCAmb2JqZWN0LT52Ym8pKTsKICAgIExFQVZFX0dMKCk7CiAgICBvYmplY3QtPnZibyA9IDA7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlSW5kZXhCdWZmZXIoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIExlbmd0aCwgRFdPUkQgVXNhZ2UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzREZPUk1BVCBGb3JtYXQsIFdJTkVEM0RQT09MIFBvb2wsIElXaW5lRDNESW5kZXhCdWZmZXIqKiBwcEluZGV4QnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFICpzaGFyZWRIYW5kbGUsIElVbmtub3duICpwYXJlbnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNESW5kZXhCdWZmZXJJbXBsICpvYmplY3Q7CiAgICBUUkFDRSgiKCVwKSBDcmVhdGluZyBpbmRleCBidWZmZXJcbiIsIFRoaXMpOwoKICAgIC8qIEFsbG9jYXRlIHRoZSBzdG9yYWdlIGZvciB0aGUgZGV2aWNlICovCiAgICBEM0RDUkVBVEVSRVNPVVJDRU9CSkVDVElOU1RBTkNFKG9iamVjdCxJbmRleEJ1ZmZlcixXSU5FRDNEUlRZUEVfSU5ERVhCVUZGRVIsIExlbmd0aCkKCiAgICBpZiAoUG9vbCA9PSBXSU5FRDNEUE9PTF9ERUZBVUxUICkgeyAvKiBXZSBuZWVkIGEgbG9jYWwgY29weSBmb3IgZHJhd1N0cmlkZWRTbG93ICovCiAgICAgICAgb2JqZWN0LT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSxvYmplY3QtPnJlc291cmNlLnNpemUpOwogICAgfQoKICAgIGlmKFBvb2wgIT0gV0lORUQzRFBPT0xfU1lTVEVNTUVNICYmICEoVXNhZ2UgJiBXSU5FRDNEVVNBR0VfRFlOQU1JQykgJiYgR0xfU1VQUE9SVChBUkJfVkVSVEVYX0JVRkZFUl9PQkpFQ1QpKSB7CiAgICAgICAgQ3JlYXRlSW5kZXhCdWZmZXJWQk8oVGhpcywgb2JqZWN0KTsKICAgIH0KCiAgICBUUkFDRSgiKCVwKSA6IExlbj0lZCwgVXNlPSV4LCBGb3JtYXQ9KCV1LCVzKSwgUG9vbD0lZCAtIE1lbW9yeUAlcCwgSWZhY2VAJXBcbiIsIFRoaXMsIExlbmd0aCwgVXNhZ2UsIEZvcm1hdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlYnVnX2QzZGZvcm1hdChGb3JtYXQpLCBQb29sLCBvYmplY3QsIG9iamVjdC0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKICAgICpwcEluZGV4QnVmZmVyID0gKElXaW5lRDNESW5kZXhCdWZmZXIgKikgb2JqZWN0OwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVN0YXRlQmxvY2soSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBXSU5FRDNEU1RBVEVCTE9DS1RZUEUgVHlwZSwgSVdpbmVEM0RTdGF0ZUJsb2NrKiogcHBTdGF0ZUJsb2NrLCBJVW5rbm93biAqcGFyZW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICAgICAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3RhdGVCbG9ja0ltcGwgKm9iamVjdDsKICAgIGludCBpLCBqOwogICAgSFJFU1VMVCB0ZW1wX3Jlc3VsdDsKCiAgICBEM0RDUkVBVEVPQkpFQ1RJTlNUQU5DRShvYmplY3QsIFN0YXRlQmxvY2spCiAgICBvYmplY3QtPmJsb2NrVHlwZSAgICAgPSBUeXBlOwoKICAgIGZvcihpID0gMDsgaSA8IExJR0hUTUFQX1NJWkU7IGkrKykgewogICAgICAgIGxpc3RfaW5pdCgmb2JqZWN0LT5saWdodE1hcFtpXSk7CiAgICB9CgogICAgLyogU3BlY2lhbCBjYXNlIC0gVXNlZCBkdXJpbmcgaW5pdGlhbGl6YXRpb24gdG8gcHJvZHVjZSBhIHBsYWNlaG9sZGVyIHN0YXRlYmxvY2sKICAgICAgICAgIHNvIG90aGVyIGZ1bmN0aW9ucyBjYWxsZWQgY2FuIHVwZGF0ZSBhIHN0YXRlIGJsb2NrICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICBpZiAoVHlwZSA9PSBXSU5FRDNEU0JUX0lOSVQpIHsKICAgICAgICAvKiBEb24ndCBib3RoZXIgaW5jcmVhc2luZyB0aGUgcmVmZXJlbmNlIGNvdW50IG90aGVyd2lzZSBhIGRldmljZSB3aWxsIG5ldmVyCiAgICAgICAgICAgYmUgZnJlZWQgZHVlIHRvIGNpcmN1bGFyIGRlcGVuZGVuY2llcyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KICAgIAogICAgdGVtcF9yZXN1bHQgPSBhbGxvY2F0ZV9zaGFkZXJfY29uc3RhbnRzKG9iamVjdCk7CiAgICBpZiAoV0lORUQzRF9PSyAhPSB0ZW1wX3Jlc3VsdCkKICAgICAgICByZXR1cm4gdGVtcF9yZXN1bHQ7CgogICAgLyogT3RoZXJ3aXNlLCBtaWdodCBhcyB3ZWxsIHNldCB0aGUgd2hvbGUgc3RhdGUgYmxvY2sgdG8gdGhlIGFwcHJvcHJpYXRlIHZhbHVlcyAgKi8KICAgIGlmIChUaGlzLT5zdGF0ZUJsb2NrICE9IE5VTEwpCiAgICAgICAgc3RhdGVibG9ja19jb3B5KChJV2luZUQzRFN0YXRlQmxvY2sqKSBvYmplY3QsIChJV2luZUQzRFN0YXRlQmxvY2sqKSBUaGlzLT5zdGF0ZUJsb2NrKTsKICAgIGVsc2UKICAgICAgICBtZW1zZXQob2JqZWN0LT5zdHJlYW1GcmVxLCAxLCBzaXplb2Yob2JqZWN0LT5zdHJlYW1GcmVxKSk7CgogICAgLyogUmVzZXQgdGhlIHJlZiBhbmQgdHlwZSBhZnRlciBrbHVkZ2luZyBpdCAqLwogICAgb2JqZWN0LT53aW5lRDNERGV2aWNlID0gVGhpczsKICAgIG9iamVjdC0+cmVmICAgICAgICAgICA9IDE7CiAgICBvYmplY3QtPmJsb2NrVHlwZSAgICAgPSBUeXBlOwoKICAgIFRSQUNFKCJVcGRhdGluZyBjaGFuZ2VkIGZsYWdzIGFwcHJvcHJpYXRlIGZvciB0eXBlICVkXG4iLCBUeXBlKTsKCiAgICBpZiAoVHlwZSA9PSBXSU5FRDNEU0JUX0FMTCkgewoKICAgICAgICBUUkFDRSgiQUxMID0+IFByZXRlbmQgZXZlcnl0aGluZyBoYXMgY2hhbmdlZFxuIik7CiAgICAgICAgc3RhdGVibG9ja19zYXZlZHN0YXRlc19zZXQoKElXaW5lRDNEU3RhdGVCbG9jayopIG9iamVjdCwgJm9iamVjdC0+Y2hhbmdlZCwgVFJVRSk7CgogICAgICAgIC8qIExpZ2h0cyBhcmUgbm90IHBhcnQgb2YgdGhlIGNoYW5nZWQgLyBzZXQgc3RydWN0dXJlICovCiAgICAgICAgZm9yKGogPSAwOyBqIDwgTElHSFRNQVBfU0laRTsgaisrKSB7CiAgICAgICAgICAgIHN0cnVjdCBsaXN0ICplOwogICAgICAgICAgICBMSVNUX0ZPUl9FQUNIKGUsICZvYmplY3QtPmxpZ2h0TWFwW2pdKSB7CiAgICAgICAgICAgICAgICBQTElHSFRJTkZPRUwgKmxpZ2h0ID0gTElTVF9FTlRSWShlLCBQTElHSFRJTkZPRUwsIGVudHJ5KTsKICAgICAgICAgICAgICAgIGxpZ2h0LT5jaGFuZ2VkID0gVFJVRTsKICAgICAgICAgICAgICAgIGxpZ2h0LT5lbmFibGVkQ2hhbmdlZCA9IFRSVUU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGVsc2UgaWYgKFR5cGUgPT0gV0lORUQzRFNCVF9QSVhFTFNUQVRFKSB7CgogICAgICAgIFRSQUNFKCJQSVhFTFNUQVRFID0+IFByZXRlbmQgYWxsIHBpeGVsIHNoYXRlcyBoYXZlIGNoYW5nZWRcbiIpOwogICAgICAgIHN0YXRlYmxvY2tfc2F2ZWRzdGF0ZXNfc2V0KChJV2luZUQzRFN0YXRlQmxvY2sqKSBvYmplY3QsICZvYmplY3QtPmNoYW5nZWQsIEZBTFNFKTsKCiAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnBpeGVsU2hhZGVyID0gVFJVRTsKCiAgICAgICAgLyogUGl4ZWwgU2hhZGVyIENvbnN0YW50cyAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBHTF9MSU1JVFMocHNoYWRlcl9jb25zdGFudHNGKTsgKytpKQogICAgICAgICAgICBvYmplY3QtPmNoYW5nZWQucGl4ZWxTaGFkZXJDb25zdGFudHNGW2ldID0gVFJVRTsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgTUFYX0NPTlNUX0I7ICsraSkKICAgICAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnBpeGVsU2hhZGVyQ29uc3RhbnRzQltpXSA9IFRSVUU7CiAgICAgICAgZm9yIChpID0gMDsgaSA8IE1BWF9DT05TVF9JOyArK2kpCiAgICAgICAgICAgIG9iamVjdC0+Y2hhbmdlZC5waXhlbFNoYWRlckNvbnN0YW50c0lbaV0gPSBUUlVFOwogICAgICAgIAogICAgICAgIGZvciAoaSA9IDA7IGkgPCBOVU1fU0FWRURQSVhFTFNUQVRFU19SOyBpKyspIHsKICAgICAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnJlbmRlclN0YXRlW1NhdmVkUGl4ZWxTdGF0ZXNfUltpXV0gPSBUUlVFOwogICAgICAgIH0KICAgICAgICBmb3IgKGogPSAwOyBqIDwgR0xfTElNSVRTKHRleHR1cmVfc3RhZ2VzKTsgaisrKSB7CiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBOVU1fU0FWRURQSVhFTFNUQVRFU19UOyBpKyspIHsKICAgICAgICAgICAgICAgIG9iamVjdC0+Y2hhbmdlZC50ZXh0dXJlU3RhdGVbal1bU2F2ZWRQaXhlbFN0YXRlc19UW2ldXSA9IFRSVUU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yIChqID0gMCA7IGogPCAxNjsgaisrKSB7CiAgICAgICAgICAgIGZvciAoaSA9MDsgaSA8IE5VTV9TQVZFRFBJWEVMU1RBVEVTX1M7aSsrKSB7CgogICAgICAgICAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnNhbXBsZXJTdGF0ZVtqXVtTYXZlZFBpeGVsU3RhdGVzX1NbaV1dID0gVFJVRTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICB9IGVsc2UgaWYgKFR5cGUgPT0gV0lORUQzRFNCVF9WRVJURVhTVEFURSkgewoKICAgICAgICBUUkFDRSgiVkVSVEVYU1RBVEUgPT4gUHJldGVuZCBhbGwgdmVydGV4IHNoYXRlcyBoYXZlIGNoYW5nZWRcbiIpOwogICAgICAgIHN0YXRlYmxvY2tfc2F2ZWRzdGF0ZXNfc2V0KChJV2luZUQzRFN0YXRlQmxvY2sqKSBvYmplY3QsICZvYmplY3QtPmNoYW5nZWQsIEZBTFNFKTsKCiAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnZlcnRleFNoYWRlciA9IFRSVUU7CgogICAgICAgIC8qIFZlcnRleCBTaGFkZXIgQ29uc3RhbnRzICovCiAgICAgICAgZm9yIChpID0gMDsgaSA8IEdMX0xJTUlUUyh2c2hhZGVyX2NvbnN0YW50c0YpOyArK2kpCiAgICAgICAgICAgIG9iamVjdC0+Y2hhbmdlZC52ZXJ0ZXhTaGFkZXJDb25zdGFudHNGW2ldID0gVFJVRTsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgTUFYX0NPTlNUX0I7ICsraSkKICAgICAgICAgICAgb2JqZWN0LT5jaGFuZ2VkLnZlcnRleFNoYWRlckNvbnN0YW50c0JbaV0gPSBUUlVFOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBNQVhfQ09OU1RfSTsgKytpKQogICAgICAgICAgICBvYmplY3QtPmNoYW5nZWQudmVydGV4U2hhZGVyQ29uc3RhbnRzSVtpXSA9IFRSVUU7CiAKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgTlVNX1NBVkVEVkVSVEVYU1RBVEVTX1I7IGkrKykgewogICAgICAgICAgICBvYmplY3QtPmNoYW5nZWQucmVuZGVyU3RhdGVbU2F2ZWRWZXJ0ZXhTdGF0ZXNfUltpXV0gPSBUUlVFOwogICAgICAgIH0KICAgICAgICBmb3IgKGogPSAwOyBqIDwgR0xfTElNSVRTKHRleHR1cmVfc3RhZ2VzKTsgaisrKSB7CiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBOVU1fU0FWRURWRVJURVhTVEFURVNfVDsgaSsrKSB7CiAgICAgICAgICAgICAgICBvYmplY3QtPmNoYW5nZWQudGV4dHVyZVN0YXRlW2pdW1NhdmVkVmVydGV4U3RhdGVzX1RbaV1dID0gVFJVRTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBmb3IgKGogPSAwIDsgaiA8IDE2OyBqKyspewogICAgICAgICAgICBmb3IgKGkgPTA7IGkgPCBOVU1fU0FWRURWRVJURVhTVEFURVNfUztpKyspIHsKICAgICAgICAgICAgICAgIG9iamVjdC0+Y2hhbmdlZC5zYW1wbGVyU3RhdGVbal1bU2F2ZWRWZXJ0ZXhTdGF0ZXNfU1tpXV0gPSBUUlVFOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3IoaiA9IDA7IGogPCBMSUdIVE1BUF9TSVpFOyBqKyspIHsKICAgICAgICAgICAgc3RydWN0IGxpc3QgKmU7CiAgICAgICAgICAgIExJU1RfRk9SX0VBQ0goZSwgJm9iamVjdC0+bGlnaHRNYXBbal0pIHsKICAgICAgICAgICAgICAgIFBMSUdIVElORk9FTCAqbGlnaHQgPSBMSVNUX0VOVFJZKGUsIFBMSUdIVElORk9FTCwgZW50cnkpOwogICAgICAgICAgICAgICAgbGlnaHQtPmNoYW5nZWQgPSBUUlVFOwogICAgICAgICAgICAgICAgbGlnaHQtPmVuYWJsZWRDaGFuZ2VkID0gVFJVRTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgRklYTUUoIlVucmVjb2duaXplZCBzdGF0ZSBibG9jayB0eXBlICVkXG4iLCBUeXBlKTsKICAgIH0KCiAgICBUUkFDRSgiKCVwKSByZXR1cm5pbmcgdG9rZW4gKHB0ciB0byBzdGF0ZWJsb2NrKSBvZiAlcFxuIiwgVGhpcywgb2JqZWN0KTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCk1TRE46Cltpbl0gUmVuZGVyIHRhcmdldHMgYXJlIG5vdCBsb2NrYWJsZSB1bmxlc3MgdGhlIGFwcGxpY2F0aW9uIHNwZWNpZmllcyBUUlVFIGZvciBMb2NrYWJsZS4gTm90ZSB0aGF0IGxvY2thYmxlIHJlbmRlciB0YXJnZXRzIHJlZHVjZSBwZXJmb3JtYW5jZSBvbiBzb21lIGdyYXBoaWNzIGhhcmR3YXJlLgoKRGlzY2FyZAogW2luXSBTZXQgdGhpcyBmbGFnIHRvIFRSVUUgdG8gZW5hYmxlIHotYnVmZmVyIGRpc2NhcmRpbmcsIGFuZCBGQUxTRSBvdGhlcndpc2UuIAoKSWYgdGhpcyBmbGFnIGlzIHNldCwgdGhlIGNvbnRlbnRzIG9mIHRoZSBkZXB0aCBzdGVuY2lsIGJ1ZmZlciB3aWxsIGJlIGludmFsaWQgYWZ0ZXIgY2FsbGluZyBlaXRoZXIgSURpcmVjdDNERGV2aWNlOTo6UHJlc2VudCBvciBJRGlyZWN0M0REZXZpY2U5OjpTZXREZXB0aFN0ZW5jaWxTdXJmYWNlIHdpdGggYSBkaWZmZXJlbnQgZGVwdGggc3VyZmFjZS4KCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovCiAKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlU3VyZmFjZShJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgV2lkdGgsIFVJTlQgSGVpZ2h0LCBXSU5FRDNERk9STUFUIEZvcm1hdCwgQk9PTCBMb2NrYWJsZSwgQk9PTCBEaXNjYXJkLCBVSU5UIExldmVsLCBJV2luZUQzRFN1cmZhY2UgKipwcFN1cmZhY2UsV0lORUQzRFJFU09VUkNFVFlQRSBUeXBlLCBEV09SRCBVc2FnZSwgV0lORUQzRFBPT0wgUG9vbCwgV0lORUQzRE1VTFRJU0FNUExFX1RZUEUgTXVsdGlTYW1wbGUgLERXT1JEIE11bHRpc2FtcGxlUXVhbGl0eSwgSEFORExFKiBwU2hhcmVkSGFuZGxlLCBXSU5FRDNEU1VSRlRZUEUgSW1wbCwgSVVua25vd24gKnBhcmVudCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsgICAgCiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpvYmplY3Q7IC8qTk9URTogaW1wbCByZWYgYWxsb3dlZCBzaW5jZSB0aGlzIGlzIGEgY3JlYXRlIGZ1bmN0aW9uICovCiAgICB1bnNpZ25lZCBpbnQgcG93MldpZHRoLCBwb3cySGVpZ2h0OwogICAgdW5zaWduZWQgaW50IFNpemUgICAgICAgPSAxOwogICAgY29uc3QgUGl4ZWxGb3JtYXREZXNjICp0YWJsZUVudHJ5ID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KEZvcm1hdCk7CiAgICBUUkFDRSgiKCVwKSBDcmVhdGUgc3VyZmFjZVxuIixUaGlzKTsKICAgIAogICAgLyoqIEZJWE1FOiBDaGVjayByYW5nZXMgb24gdGhlIGlucHV0cyBhcmUgdmFsaWQgCiAgICAgKiBNU0ROCiAgICAgKiAgIE11bHRpc2FtcGxlUXVhbGl0eQogICAgICogICAgW2luXSBRdWFsaXR5IGxldmVsLiBUaGUgdmFsaWQgcmFuZ2UgaXMgYmV0d2VlbiB6ZXJvIGFuZCBvbmUgbGVzcyB0aGFuIHRoZSBsZXZlbAogICAgICogICAgcmV0dXJuZWQgYnkgcFF1YWxpdHlMZXZlbHMgdXNlZCBieSBJRGlyZWN0M0Q5OjpDaGVja0RldmljZU11bHRpU2FtcGxlVHlwZS4gCiAgICAgKiAgICBQYXNzaW5nIGEgbGFyZ2VyIHZhbHVlIHJldHVybnMgdGhlIGVycm9yIFdJTkVEM0RFUlJfSU5WQUxJRENBTEwuIFRoZSBNdWx0aXNhbXBsZVF1YWxpdHkKICAgICAqICAgIHZhbHVlcyBvZiBwYWlyZWQgcmVuZGVyIHRhcmdldHMsIGRlcHRoIHN0ZW5jaWwgc3VyZmFjZXMsIGFuZCB0aGUgTXVsdGlTYW1wbGUgdHlwZQogICAgICogICAgbXVzdCBhbGwgbWF0Y2guCiAgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKICAgIC8qKgogICAgKiBUT0RPOiBEaXNjYXJkIE1TRE4KICAgICogW2luXSBTZXQgdGhpcyBmbGFnIHRvIFRSVUUgdG8gZW5hYmxlIHotYnVmZmVyIGRpc2NhcmRpbmcsIGFuZCBGQUxTRSBvdGhlcndpc2UuCiAgICAqCiAgICAqIElmIHRoaXMgZmxhZyBpcyBzZXQsIHRoZSBjb250ZW50cyBvZiB0aGUgZGVwdGggc3RlbmNpbCBidWZmZXIgd2lsbCBiZQogICAgKiBpbnZhbGlkIGFmdGVyIGNhbGxpbmcgZWl0aGVyIElEaXJlY3QzRERldmljZTk6OlByZXNlbnQgb3IgICogSURpcmVjdDNERGV2aWNlOTo6U2V0RGVwdGhTdGVuY2lsU3VyZmFjZQogICAgKiB3aXRoIGEgZGlmZmVyZW50IGRlcHRoIHN1cmZhY2UuCiAgICAqCiAgICAqVGhpcyBmbGFnIGhhcyB0aGUgc2FtZSBiZWhhdmlvciBhcyB0aGUgY29uc3RhbnQsIEQzRFBSRVNFTlRGTEFHX0RJU0NBUkRfREVQVEhTVEVOQ0lMLCBpbiBEM0RQUkVTRU5URkxBRy4KICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgICBpZihNdWx0aXNhbXBsZVF1YWxpdHkgPCAwKSB7CiAgICAgICAgRklYTUUoIkludmFsaWQgbXVsdGlzYW1wbGUgbGV2ZWwgJWRcbiIsIE11bHRpc2FtcGxlUXVhbGl0eSk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7IC8qIFRPRE86IENoZWNrIHRoYXQgdGhpcyBpcyB0aGUgY2FzZSEgKi8KICAgIH0KCiAgICBpZihNdWx0aXNhbXBsZVF1YWxpdHkgPiAwKSB7CiAgICAgICAgRklYTUUoIk11bHRpc2FtcGxlUXVhbGl0eSBzZXQgdG8gJWQsIHN1YnN0aXR1dGluZyAwXG4iLCBNdWx0aXNhbXBsZVF1YWxpdHkpOwogICAgICAgIE11bHRpc2FtcGxlUXVhbGl0eT0wOwogICAgfQoKICAgIC8qKiBGSVhNRTogQ2hlY2sgdGhhdCB0aGUgZm9ybWF0IGlzIHN1cHBvcnRlZAogICAgKiAgICBieSB0aGUgZGV2aWNlLgogICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIC8qIE5vbi1wb3dlcjIgc3VwcG9ydCAqLwogICAgaWYgKEdMX1NVUFBPUlQoQVJCX1RFWFRVUkVfTk9OX1BPV0VSX09GX1RXTykpIHsKICAgICAgICBwb3cyV2lkdGggPSBXaWR0aDsKICAgICAgICBwb3cySGVpZ2h0ID0gSGVpZ2h0OwogICAgfSBlbHNlIHsKICAgICAgICAvKiBGaW5kIHRoZSBuZWFyZXN0IHBvdzIgbWF0Y2ggKi8KICAgICAgICBwb3cyV2lkdGggPSBwb3cySGVpZ2h0ID0gMTsKICAgICAgICB3aGlsZSAocG93MldpZHRoIDwgV2lkdGgpIHBvdzJXaWR0aCA8PD0gMTsKICAgICAgICB3aGlsZSAocG93MkhlaWdodCA8IEhlaWdodCkgcG93MkhlaWdodCA8PD0gMTsKICAgIH0KCiAgICBpZiAocG93MldpZHRoID4gV2lkdGggfHwgcG93MkhlaWdodCA+IEhlaWdodCkgewogICAgICAgICAvKiogVE9ETzogYWRkIHN1cHBvcnQgZm9yIG5vbiBwb3dlciB0d28gY29tcHJlc3NlZCB0ZXh0dXJlcyAoT3BlbkdMIDIgcHJvdmljZXMgc3VwcG9ydCBmb3IgKiBub24tcG93ZXItdHdvIHRleHR1cmVzIGdyYXRpcykgKiovCiAgICAgICAgaWYgKEZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEgfHwgRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fCBGb3JtYXQgPT0gV0lORUQzREZNVF9EWFQzCiAgICAgICAgICAgICAgIHx8IEZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDQgfHwgRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNSkgewogICAgICAgICAgICBGSVhNRSgiKCVwKSBDb21wcmVzc2VkIG5vbi1wb3dlci10d28gdGV4dHVyZXMgYXJlIG5vdCBzdXBwb3J0ZWQgdyglZCkgaCglZClcbiIsCiAgICAgICAgICAgICAgICAgICAgVGhpcywgV2lkdGgsIEhlaWdodCk7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX05PVEFWQUlMQUJMRTsKICAgICAgICB9CiAgICB9CgogICAgLyoqIERYVG4gbWlwbWFwcyB1c2UgdGhlIHNhbWUgbnVtYmVyIG9mICdsZXZlbHMnIGRvd24gdG8gZWcuIDh4MSwgYnV0IHNpbmNlCiAgICAgKiAgaXQgaXMgYmFzZWQgYXJvdW5kIDR4NCBwaXhlbCBibG9ja3MgaXQgcmVxdWlyZXMgcGFkZGluZywgc28gYWxsb2NhdGUgZW5vdWdoCiAgICAgKiAgc3BhY2UhCiAgICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgIGlmIChXSU5FRDNERk1UX1VOS05PV04gPT0gRm9ybWF0KSB7CiAgICAgICAgU2l6ZSA9IDA7CiAgICB9IGVsc2UgaWYgKEZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEpIHsKICAgICAgICAvKiBEWFQxIGlzIGhhbGYgYnl0ZSBwZXIgcGl4ZWwgKi8KICAgICAgIFNpemUgPSAoKG1heChXaWR0aCw0KSAqIHRhYmxlRW50cnktPmJwcCkgKiBtYXgoSGVpZ2h0LDQpKSA+PiAxOwoKICAgIH0gZWxzZSBpZiAoRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMiB8fCBGb3JtYXQgPT0gV0lORUQzREZNVF9EWFQzIHx8CiAgICAgICAgICAgICAgIEZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDQgfHwgRm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNSkgewogICAgICAgU2l6ZSA9ICgobWF4KFdpZHRoLDQpICogdGFibGVFbnRyeS0+YnBwKSAqIG1heChIZWlnaHQsNCkpOwogICAgfSBlbHNlIHsKICAgICAgIC8qIFRoZSBwaXRjaCBpcyBhIG11bHRpcGxlIG9mIDQgYnl0ZXMgKi8KICAgICAgIFNpemUgPSAoKFdpZHRoICogdGFibGVFbnRyeS0+YnBwKSArIFNVUkZBQ0VfQUxJR05NRU5UIC0gMSkgJiB+KFNVUkZBQ0VfQUxJR05NRU5UIC0gMSk7CiAgICAgICBTaXplICo9IEhlaWdodDsKICAgIH0KCiAgICAvKiogQ3JlYXRlIGFuZCBpbml0aWFsaXNlIHRoZSBzdXJmYWNlIHJlc291cmNlICoqLwogICAgRDNEQ1JFQVRFUkVTT1VSQ0VPQkpFQ1RJTlNUQU5DRShvYmplY3QsU3VyZmFjZSxXSU5FRDNEUlRZUEVfU1VSRkFDRSwgU2l6ZSkKICAgIC8qICJTdGFuZGFsb25lIiBzdXJmYWNlICovCiAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29udGFpbmVyKChJV2luZUQzRFN1cmZhY2UgKilvYmplY3QsIE5VTEwpOwoKICAgIG9iamVjdC0+Y3VycmVudERlc2MuV2lkdGggICAgICA9IFdpZHRoOwogICAgb2JqZWN0LT5jdXJyZW50RGVzYy5IZWlnaHQgICAgID0gSGVpZ2h0OwogICAgb2JqZWN0LT5jdXJyZW50RGVzYy5NdWx0aVNhbXBsZVR5cGUgICAgPSBNdWx0aVNhbXBsZTsKICAgIG9iamVjdC0+Y3VycmVudERlc2MuTXVsdGlTYW1wbGVRdWFsaXR5ID0gTXVsdGlzYW1wbGVRdWFsaXR5OwoKICAgIC8qIFNldHVwIHNvbWUgZ2xmb3JtYXQgZGVmYXVsdHMgKi8KICAgIG9iamVjdC0+Z2xEZXNjcmlwdGlvbi5nbEZvcm1hdCAgICAgICAgID0gdGFibGVFbnRyeS0+Z2xGb3JtYXQ7CiAgICBvYmplY3QtPmdsRGVzY3JpcHRpb24uZ2xGb3JtYXRJbnRlcm5hbCA9IHRhYmxlRW50cnktPmdsSW50ZXJuYWw7CiAgICBvYmplY3QtPmdsRGVzY3JpcHRpb24uZ2xUeXBlICAgICAgICAgICA9IHRhYmxlRW50cnktPmdsVHlwZTsKCiAgICBvYmplY3QtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUgICAgICA9IDA7CiAgICBvYmplY3QtPmdsRGVzY3JpcHRpb24ubGV2ZWwgICAgICAgICAgICA9IExldmVsOwogICAgb2JqZWN0LT5nbERlc2NyaXB0aW9uLnRhcmdldCAgICAgICAgICAgPSBHTF9URVhUVVJFXzJEOwoKICAgIC8qIEludGVybmFsIGRhdGEgKi8KICAgIG9iamVjdC0+cG93MldpZHRoICA9IHBvdzJXaWR0aDsKICAgIG9iamVjdC0+cG93MkhlaWdodCA9IHBvdzJIZWlnaHQ7CgogICAgLyogRmxhZ3MgKi8KICAgIG9iamVjdC0+RmxhZ3MgICAgICA9IFNGTEFHX0RZTkxPQ0s7CiAgICBvYmplY3QtPkZsYWdzICAgICB8PSAocG93MldpZHRoICE9IFdpZHRoIHx8IHBvdzJIZWlnaHQgIT0gSGVpZ2h0KSA/IFNGTEFHX05PTlBPVzIgOiAwOwogICAgb2JqZWN0LT5GbGFncyAgICAgfD0gRGlzY2FyZCA/IFNGTEFHX0RJU0NBUkQgOiAwOwogICAgb2JqZWN0LT5GbGFncyAgICAgfD0gKFdJTkVEM0RGTVRfRDE2X0xPQ0tBQkxFID09IEZvcm1hdCkgPyBTRkxBR19MT0NLQUJMRSA6IDA7CiAgICBvYmplY3QtPkZsYWdzICAgICB8PSBMb2NrYWJsZSA/IFNGTEFHX0xPQ0tBQkxFIDogMDsKCgogICAgaWYgKFdJTkVEM0RGTVRfVU5LTk9XTiAhPSBGb3JtYXQpIHsKICAgICAgICBvYmplY3QtPmJ5dGVzUGVyUGl4ZWwgPSB0YWJsZUVudHJ5LT5icHA7CiAgICB9IGVsc2UgewogICAgICAgIG9iamVjdC0+Ynl0ZXNQZXJQaXhlbCA9IDA7CiAgICB9CgogICAgLyoqIFRPRE86IGNoYW5nZSB0aGlzIGludG8gYSB0ZXh0dXJlIHRyYW5zZm9ybSBtYXRyaXggc28gdGhhdCBpdCdzIHByb2Nlc3NlZCBpbiBoYXJkd2FyZSAqKi8KCiAgICBUUkFDRSgiUG9vbCAlZCAlZCAlZCAlZFxuIixQb29sLCBXSU5FRDNEUE9PTF9ERUZBVUxULCBXSU5FRDNEUE9PTF9NQU5BR0VELCBXSU5FRDNEUE9PTF9TWVNURU1NRU0pOwoKICAgIC8qKiBRdWljayBsb2NrYWJsZSBzYW5pdHkgY2hlY2sgVE9ETzogcmVtb3ZlIHRoaXMgYWZ0ZXIgc3VyZmFjZXMsIHVzYWdlIGFuZCBsb2NrYWJpbGl0eSBoYXZlIGJlZW4gZGVidWdnZWQgcHJvcGVybHkKICAgICogdGhpcyBmdW5jdGlvbiBpcyB0b28gZGVlcCB0byBuZWVkIHRvIGNhcmUgYWJvdXQgdGhpbmdzIGxpa2UgdGhpcy4KICAgICogTGV2ZWxzIG5lZWQgdG8gYmUgY2hlY2tlZCB0b28sIGFuZCBwb3NzaWJseSBUeXBlIHNpbmNlIHRoZXkgYWxsIGFmZmVjdCB3aGF0IGNhbiBiZSBkb25lLgogICAgKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgc3dpdGNoKFBvb2wpIHsKICAgIGNhc2UgV0lORUQzRFBPT0xfU0NSQVRDSDoKICAgICAgICBpZighTG9ja2FibGUpCiAgICAgICAgICAgIEZJWE1FKCJDcmVhdGUgc3VyZmFjZSBjYWxsZWQgd2l0aCBhIHBvb2wgb2YgU0NSQVRDSCBhbmQgYSBMb2NrYWJsZSBvZiBGQUxTRSAiCiAgICAgICAgICAgICAgICAid2hpY2ggYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZSwgc2V0dGluZyBsb2NrYWJsZSB0byBUUlVFXG4iKTsKICAgICAgICAgICAgICAgIExvY2thYmxlID0gVFJVRTsKICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEUE9PTF9TWVNURU1NRU06CiAgICAgICAgaWYoIUxvY2thYmxlKSBGSVhNRSgiQ3JlYXRlIHN1cmZhY2UgY2FsbGVkIHdpdGggYSBwb29sIG9mIFNZU1RFTU1FTSBhbmQgYSBMb2NrYWJsZSBvZiBGQUxTRSwgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGhpcyBpcyBhY2NlcHRhYmxlIGJ1dCB1bmV4cGVjdGVkIChJIGNhbid0IGtub3cgaG93IHRoZSBzdXJmYWNlIGNhbiBiZSB1c2FibGUhKVxuIik7CiAgICBjYXNlIFdJTkVEM0RQT09MX01BTkFHRUQ6CiAgICAgICAgaWYoVXNhZ2UgPT0gV0lORUQzRFVTQUdFX0RZTkFNSUMpIEZJWE1FKCJDcmVhdGUgc3VyZmFjZSBjYWxsZWQgd2l0aCBhIHBvb2wgb2YgTUFOQUdFRCBhbmQgYSAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJVc2FnZSBvZiBEWU5BTUlDIHdoaWNoIGFyZSBtdXR1YWxseSBleGNsdXNpdmUsIG5vdCBkb2luZyAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhbnl0aGluZyBqdXN0IHRlbGxpbmcgeW91LlxuIik7CiAgICBicmVhazsKICAgIGNhc2UgV0lORUQzRFBPT0xfREVGQVVMVDogLypUT0RPOiBDcmVhdGUgb2Zmc2NyZWVuIHBsYWluIGNhbiBjYXVzZSB0aGlzIGNoZWNrIHRvIGZhaWwuLi4sIGZpbmQgb3V0IGlmIGl0IHNob3VsZCAqLwogICAgICAgIGlmKCEoVXNhZ2UgJiBXSU5FRDNEVVNBR0VfRFlOQU1JQykgJiYgIShVc2FnZSAmIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVQpCiAgICAgICAgICAgJiYgIShVc2FnZSAmJiBXSU5FRDNEVVNBR0VfREVQVEhTVEVOQ0lMICkgJiYgTG9ja2FibGUpCiAgICAgICAgICAgIFdBUk4oIkNyZWF0aW5nIGEgc3VyZmFjZSB3aXRoIGEgUE9PTCBvZiBERUZBVUxUIHdpdGggTG9ja2FibGUgdHJ1ZSwgdGhhdCBkb2Vzbid0IHNwZWNpZnkgRFlOQU1JQyB1c2FnZS5cbiIpOwogICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAgIEZJWE1FKCIoJXApIFVua25vd24gcG9vbCAlZFxuIiwgVGhpcywgUG9vbCk7CiAgICBicmVhazsKICAgIH07CgogICAgaWYgKFVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCAmJiBQb29sICE9IFdJTkVEM0RQT09MX0RFRkFVTFQpIHsKICAgICAgICBGSVhNRSgiVHJ5aW5nIHRvIGNyZWF0ZSBhIHJlbmRlciB0YXJnZXQgdGhhdCBpc24ndCBpbiB0aGUgZGVmYXVsdCBwb29sXG4iKTsKICAgIH0KCiAgICAvKiBtYXJrIHRoZSB0ZXh0dXJlIGFzIGRpcnR5IHNvIHRoYXQgaXQgZ2V0cyBsb2FkZWQgZmlyc3QgdGltZSBhcm91bmQqLwogICAgSVdpbmVEM0RTdXJmYWNlX0FkZERpcnR5UmVjdCgqcHBTdXJmYWNlLCBOVUxMKTsKICAgIFRSQUNFKCIoJXApIDogdyglZCkgaCglZCkgZm10KCVkLCVzKSBsb2NrYWJsZSglZCkgc3VyZkAlcCwgc3VyZm1lbUAlcCwgJWQgYnl0ZXNcbiIsCiAgICAgICAgICAgVGhpcywgV2lkdGgsIEhlaWdodCwgRm9ybWF0LCBkZWJ1Z19kM2Rmb3JtYXQoRm9ybWF0KSwKICAgICAgICAgICAoV0lORUQzREZNVF9EMTZfTE9DS0FCTEUgPT0gRm9ybWF0KSwgKnBwU3VyZmFjZSwgb2JqZWN0LT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnksIG9iamVjdC0+cmVzb3VyY2Uuc2l6ZSk7CgogICAgLyogU3RvcmUgdGhlIERpcmVjdERyYXcgcHJpbWFyeSBzdXJmYWNlLiBUaGlzIGlzIHRoZSBmaXJzdCByZW5kZXJ0YXJnZXQgc3VyZmFjZSBjcmVhdGVkICovCiAgICBpZiggKFVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgJiYgKCFUaGlzLT5kZHJhd19wcmltYXJ5KSApCiAgICAgICAgVGhpcy0+ZGRyYXdfcHJpbWFyeSA9IChJV2luZUQzRFN1cmZhY2UgKikgb2JqZWN0OwoKICAgIC8qIExvb2sgYXQgdGhlIGltcGxlbWVudGF0aW9uIGFuZCBzZXQgdGhlIGNvcnJlY3QgVnRhYmxlICovCiAgICBzd2l0Y2goSW1wbCkgewogICAgICAgIGNhc2UgU1VSRkFDRV9PUEVOR0w6CiAgICAgICAgICAgIC8qIE5vdGhpbmcgdG8gZG8sIGl0J3Mgc2V0IGFscmVhZHkgKi8KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgU1VSRkFDRV9HREk6CiAgICAgICAgICAgIG9iamVjdC0+bHBWdGJsID0gJklXaW5lR0RJU3VyZmFjZV9WdGJsOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgLyogVG8gYmUgc3VyZSB0byBjYXRjaCB0aGlzICovCiAgICAgICAgICAgIEVSUigiVW5rbm93biByZXF1ZXN0ZWQgc3VyZmFjZSBpbXBsZW1lbnRhdGlvbiAlZCFcbiIsIEltcGwpOwogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZSgoSVdpbmVEM0RTdXJmYWNlICopIG9iamVjdCk7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIC8qIENhbGwgdGhlIHByaXZhdGUgc2V0dXAgcm91dGluZSAqLwogICAgcmV0dXJuIElXaW5lRDNEU3VyZmFjZV9Qcml2YXRlU2V0dXAoIChJV2luZUQzRFN1cmZhY2UgKikgb2JqZWN0ICk7Cgp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVUZXh0dXJlKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBXaWR0aCwgVUlOVCBIZWlnaHQsIFVJTlQgTGV2ZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgVXNhZ2UsIFdJTkVEM0RGT1JNQVQgRm9ybWF0LCBXSU5FRDNEUE9PTCBQb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RUZXh0dXJlKiogcHBUZXh0dXJlLCBIQU5ETEUqIHBTaGFyZWRIYW5kbGUsIElVbmtub3duICpwYXJlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RDQl9DUkVBVEVTVVJGQUNFRk4gRDNEQ0JfQ3JlYXRlU3VyZmFjZSkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEVGV4dHVyZUltcGwgKm9iamVjdDsKICAgIHVuc2lnbmVkIGludCBpOwogICAgVUlOVCB0bXBXOwogICAgVUlOVCB0bXBIOwogICAgSFJFU1VMVCBocjsKICAgIHVuc2lnbmVkIGludCBwb3cyV2lkdGg7CiAgICB1bnNpZ25lZCBpbnQgcG93MkhlaWdodDsKCgogICAgVFJBQ0UoIiglcCkgOiBXaWR0aCAlZCwgSGVpZ2h0ICVkLCBMZXZlbHMgJWQsIFVzYWdlICUjeFxuIiwgVGhpcywgV2lkdGgsIEhlaWdodCwgTGV2ZWxzLCBVc2FnZSk7CiAgICBUUkFDRSgiRm9ybWF0ICUjeCAoJXMpLCBQb29sICUjeCwgcHBUZXh0dXJlICVwLCBwU2hhcmVkSGFuZGxlICVwLCBwYXJlbnQgJXBcbiIsCiAgICAgICAgICAgIEZvcm1hdCwgZGVidWdfZDNkZm9ybWF0KEZvcm1hdCksIFBvb2wsIHBwVGV4dHVyZSwgcFNoYXJlZEhhbmRsZSwgcGFyZW50KTsKCiAgICAvKiBUT0RPOiBJdCBzaG91bGQgb25seSBiZSBwb3NzaWJsZSB0byBjcmVhdGUgdGV4dHVyZXMgZm9yIGZvcm1hdHMgCiAgICAgICAgICAgICB0aGF0IGFyZSByZXBvcnRlZCBhcyBzdXBwb3J0ZWQgKi8KICAgIGlmIChXSU5FRDNERk1UX1VOS05PV04gPj0gRm9ybWF0KSB7CiAgICAgICAgV0FSTigiKCVwKSA6IFRleHR1cmUgY2Fubm90IGJlIGNyZWF0ZWQgd2l0aCBhIGZvcm1hdCBvZiBXSU5FRDNERk1UX1VOS05PV05cbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIEQzRENSRUFURVJFU09VUkNFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBUZXh0dXJlLCBXSU5FRDNEUlRZUEVfVEVYVFVSRSwgMCk7CiAgICBEM0RJTklUSUFMSVpFQkFTRVRFWFRVUkUob2JqZWN0LT5iYXNlVGV4dHVyZSk7ICAgIAogICAgb2JqZWN0LT53aWR0aCAgPSBXaWR0aDsKICAgIG9iamVjdC0+aGVpZ2h0ID0gSGVpZ2h0OwoKICAgIC8qKiBOb24tcG93ZXIyIHN1cHBvcnQgKiovCiAgICBpZiAoR0xfU1VQUE9SVChBUkJfVEVYVFVSRV9OT05fUE9XRVJfT0ZfVFdPKSkgewogICAgICAgIHBvdzJXaWR0aCA9IFdpZHRoOwogICAgICAgIHBvdzJIZWlnaHQgPSBIZWlnaHQ7CiAgICB9IGVsc2UgewogICAgICAgIC8qIEZpbmQgdGhlIG5lYXJlc3QgcG93MiBtYXRjaCAqLwogICAgICAgIHBvdzJXaWR0aCA9IHBvdzJIZWlnaHQgPSAxOwogICAgICAgIHdoaWxlIChwb3cyV2lkdGggPCBXaWR0aCkgcG93MldpZHRoIDw8PSAxOwogICAgICAgIHdoaWxlIChwb3cySGVpZ2h0IDwgSGVpZ2h0KSBwb3cySGVpZ2h0IDw8PSAxOwogICAgfQoKICAgIC8qKiBGSVhNRTogYWRkIHN1cHBvcnQgZm9yIHJlYWwgbm9uLXBvd2VyLXR3byBpZiBpdCdzIHByb3ZpZGVkIGJ5IHRoZSB2aWRlbyBjYXJkICoqLwogICAgLyogUHJlY2FsY3VsYXRlZCBzY2FsaW5nIGZvciAnZmFrZWQnIG5vbiBwb3dlciBvZiB0d28gdGV4dHVyZSBjb29yZHMgKi8KICAgIG9iamVjdC0+cG93MnNjYWxpbmdGYWN0b3JYICA9ICAoKChmbG9hdClXaWR0aCkgIC8gKChmbG9hdClwb3cyV2lkdGgpKTsKICAgIG9iamVjdC0+cG93MnNjYWxpbmdGYWN0b3JZICA9ICAoKChmbG9hdClIZWlnaHQpIC8gKChmbG9hdClwb3cySGVpZ2h0KSk7CiAgICBUUkFDRSgiIHhmKCVmKSB5ZiglZilcbiIsIG9iamVjdC0+cG93MnNjYWxpbmdGYWN0b3JYLCBvYmplY3QtPnBvdzJzY2FsaW5nRmFjdG9yWSk7CgogICAgLyogQ2FsY3VsYXRlIGxldmVscyBmb3IgbWlwIG1hcHBpbmcgKi8KICAgIGlmIChMZXZlbHMgPT0gMCkgewogICAgICAgIFRSQUNFKCJjYWxjdWxhdGluZyBsZXZlbHMgJWRcbiIsIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzKTsKICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVscysrOwogICAgICAgIHRtcFcgPSBXaWR0aDsKICAgICAgICB0bXBIID0gSGVpZ2h0OwogICAgICAgIHdoaWxlICh0bXBXID4gMSB8fCB0bXBIID4gMSkgewogICAgICAgICAgICB0bXBXID0gbWF4KDEsIHRtcFcgPj4gMSk7CiAgICAgICAgICAgIHRtcEggPSBtYXgoMSwgdG1wSCA+PiAxKTsKICAgICAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5sZXZlbHMrKzsKICAgICAgICB9CiAgICAgICAgVFJBQ0UoIkNhbGN1bGF0ZWQgbGV2ZWxzID0gJWRcbiIsIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzKTsKICAgIH0KCiAgICAvKiBHZW5lcmF0ZSBhbGwgdGhlIHN1cmZhY2VzICovCiAgICB0bXBXID0gV2lkdGg7CiAgICB0bXBIID0gSGVpZ2h0OwogICAgZm9yIChpID0gMDsgaSA8IG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzOyBpKyspCiAgICB7CiAgICAgICAgLyogdXNlIHRoZSBjYWxsYmFjayB0byBjcmVhdGUgdGhlIHRleHR1cmUgc3VyZmFjZSAqLwogICAgICAgIGhyID0gRDNEQ0JfQ3JlYXRlU3VyZmFjZShUaGlzLT5wYXJlbnQsIHBhcmVudCwgdG1wVywgdG1wSCwgRm9ybWF0LCBVc2FnZSwgUG9vbCwgaSwgJm9iamVjdC0+c3VyZmFjZXNbaV0sTlVMTCk7CiAgICAgICAgaWYgKGhyIT0gV0lORUQzRF9PSyB8fCAoIChJV2luZUQzRFN1cmZhY2VJbXBsICopIG9iamVjdC0+c3VyZmFjZXNbaV0pLT5GbGFncyAmIFNGTEFHX09WRVJTSVpFKSB7CiAgICAgICAgICAgIEZJWE1FKCJGYWlsZWQgdG8gY3JlYXRlIHN1cmZhY2UgICVwXG4iLCBvYmplY3QpOwogICAgICAgICAgICAvKiBjbGVhbiB1cCAqLwogICAgICAgICAgICBvYmplY3QtPnN1cmZhY2VzW2ldID0gTlVMTDsKICAgICAgICAgICAgSVdpbmVEM0RUZXh0dXJlX1JlbGVhc2UoKElXaW5lRDNEVGV4dHVyZSAqKW9iamVjdCk7CgogICAgICAgICAgICAqcHBUZXh0dXJlID0gTlVMTDsKICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgICAgIH0KCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbnRhaW5lcihvYmplY3QtPnN1cmZhY2VzW2ldLCAoSVdpbmVEM0RCYXNlICopb2JqZWN0KTsKICAgICAgICBUUkFDRSgiQ3JlYXRlZCBzdXJmYWNlIGxldmVsICVkIEAgJXBcbiIsIGksIG9iamVjdC0+c3VyZmFjZXNbaV0pOwogICAgICAgIC8qIGNhbGN1bGF0ZSB0aGUgbmV4dCBtaXBtYXAgbGV2ZWwgKi8KICAgICAgICB0bXBXID0gbWF4KDEsIHRtcFcgPj4gMSk7CiAgICAgICAgdG1wSCA9IG1heCgxLCB0bXBIID4+IDEpOwogICAgfQoKICAgIFRSQUNFKCIoJXApIDogQ3JlYXRlZCAgdGV4dHVyZSAlcFxuIiwgVGhpcywgb2JqZWN0KTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZvbHVtZVRleHR1cmUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFdpZHRoLCBVSU5UIEhlaWdodCwgVUlOVCBEZXB0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBMZXZlbHMsIERXT1JEIFVzYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNERk9STUFUIEZvcm1hdCwgV0lORUQzRFBPT0wgUG9vbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RWb2x1bWVUZXh0dXJlICoqcHBWb2x1bWVUZXh0dXJlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEUgKnBTaGFyZWRIYW5kbGUsIElVbmtub3duICpwYXJlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRENCX0NSRUFURVZPTFVNRUZOIEQzRENCX0NyZWF0ZVZvbHVtZSkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgICAgICAgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFZvbHVtZVRleHR1cmVJbXBsICpvYmplY3Q7CiAgICB1bnNpZ25lZCBpbnQgICAgICAgICAgICAgICBpOwogICAgVUlOVCAgICAgICAgICAgICAgICAgICAgICAgdG1wVzsKICAgIFVJTlQgICAgICAgICAgICAgICAgICAgICAgIHRtcEg7CiAgICBVSU5UICAgICAgICAgICAgICAgICAgICAgICB0bXBEOwoKICAgIC8qIFRPRE86IEl0IHNob3VsZCBvbmx5IGJlIHBvc3NpYmxlIHRvIGNyZWF0ZSB0ZXh0dXJlcyBmb3IgZm9ybWF0cyAKICAgICAgICAgICAgIHRoYXQgYXJlIHJlcG9ydGVkIGFzIHN1cHBvcnRlZCAqLwogICAgaWYgKFdJTkVEM0RGTVRfVU5LTk9XTiA+PSBGb3JtYXQpIHsKICAgICAgICBXQVJOKCIoJXApIDogVGV4dHVyZSBjYW5ub3QgYmUgY3JlYXRlZCB3aXRoIGEgZm9ybWF0IG9mIFdJTkVEM0RGTVRfVU5LTk9XTlxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgRDNEQ1JFQVRFUkVTT1VSQ0VPQkpFQ1RJTlNUQU5DRShvYmplY3QsIFZvbHVtZVRleHR1cmUsIFdJTkVEM0RSVFlQRV9WT0xVTUVURVhUVVJFLCAwKTsKICAgIEQzRElOSVRJQUxJWkVCQVNFVEVYVFVSRShvYmplY3QtPmJhc2VUZXh0dXJlKTsKCiAgICBUUkFDRSgiKCVwKSA6IFcoJWQpIEgoJWQpIEQoJWQpLCBMdmwoJWQpIFVzYWdlKCVkKSwgRm10KCV1LCVzKSwgUG9vbCglcylcbiIsIFRoaXMsIFdpZHRoLCBIZWlnaHQsCiAgICAgICAgICBEZXB0aCwgTGV2ZWxzLCBVc2FnZSwgRm9ybWF0LCBkZWJ1Z19kM2Rmb3JtYXQoRm9ybWF0KSwgZGVidWdfZDNkcG9vbChQb29sKSk7CgogICAgb2JqZWN0LT53aWR0aCAgPSBXaWR0aDsKICAgIG9iamVjdC0+aGVpZ2h0ID0gSGVpZ2h0OwogICAgb2JqZWN0LT5kZXB0aCAgPSBEZXB0aDsKCiAgICAvKiBDYWxjdWxhdGUgbGV2ZWxzIGZvciBtaXAgbWFwcGluZyAqLwogICAgaWYgKExldmVscyA9PSAwKSB7CiAgICAgICAgb2JqZWN0LT5iYXNlVGV4dHVyZS5sZXZlbHMrKzsKICAgICAgICB0bXBXID0gV2lkdGg7CiAgICAgICAgdG1wSCA9IEhlaWdodDsKICAgICAgICB0bXBEID0gRGVwdGg7CiAgICAgICAgd2hpbGUgKHRtcFcgPiAxIHx8IHRtcEggPiAxIHx8IHRtcEQgPiAxKSB7CiAgICAgICAgICAgIHRtcFcgPSBtYXgoMSwgdG1wVyA+PiAxKTsKICAgICAgICAgICAgdG1wSCA9IG1heCgxLCB0bXBIID4+IDEpOwogICAgICAgICAgICB0bXBEID0gbWF4KDEsIHRtcEQgPj4gMSk7CiAgICAgICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzKys7CiAgICAgICAgfQogICAgICAgIFRSQUNFKCJDYWxjdWxhdGVkIGxldmVscyA9ICVkXG4iLCBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVscyk7CiAgICB9CgogICAgLyogR2VuZXJhdGUgYWxsIHRoZSBzdXJmYWNlcyAqLwogICAgdG1wVyA9IFdpZHRoOwogICAgdG1wSCA9IEhlaWdodDsKICAgIHRtcEQgPSBEZXB0aDsKCiAgICBmb3IgKGkgPSAwOyBpIDwgb2JqZWN0LT5iYXNlVGV4dHVyZS5sZXZlbHM7IGkrKykKICAgIHsKICAgICAgICBIUkVTVUxUIGhyOwogICAgICAgIC8qIENyZWF0ZSB0aGUgdm9sdW1lICovCiAgICAgICAgaHIgPSBEM0RDQl9DcmVhdGVWb2x1bWUoVGhpcy0+cGFyZW50LCBwYXJlbnQsIFdpZHRoLCBIZWlnaHQsIERlcHRoLCBGb3JtYXQsIFBvb2wsIFVzYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJV2luZUQzRFZvbHVtZSAqKikmb2JqZWN0LT52b2x1bWVzW2ldLCBwU2hhcmVkSGFuZGxlKTsKCiAgICAgICAgaWYoRkFJTEVEKGhyKSkgewogICAgICAgICAgICBFUlIoIkNyZWF0aW5nIGEgdm9sdW1lIGZvciB0aGUgdm9sdW1lIHRleHR1cmUgZmFpbGVkKCUwOHgpXG4iLCBocik7CiAgICAgICAgICAgIElXaW5lRDNEVm9sdW1lVGV4dHVyZV9SZWxlYXNlKChJV2luZUQzRFZvbHVtZVRleHR1cmUgKikgb2JqZWN0KTsKICAgICAgICAgICAgKnBwVm9sdW1lVGV4dHVyZSA9IE5VTEw7CiAgICAgICAgICAgIHJldHVybiBocjsKICAgICAgICB9CgogICAgICAgIC8qIFNldCBpdHMgY29udGFpbmVyIHRvIHRoaXMgb2JqZWN0ICovCiAgICAgICAgSVdpbmVEM0RWb2x1bWVfU2V0Q29udGFpbmVyKG9iamVjdC0+dm9sdW1lc1tpXSwgKElXaW5lRDNEQmFzZSAqKW9iamVjdCk7CgogICAgICAgIC8qIGNhbGN1YWx0ZSB0aGUgbmV4dCBtaXBtYXAgbGV2ZWwgKi8KICAgICAgICB0bXBXID0gbWF4KDEsIHRtcFcgPj4gMSk7CiAgICAgICAgdG1wSCA9IG1heCgxLCB0bXBIID4+IDEpOwogICAgICAgIHRtcEQgPSBtYXgoMSwgdG1wRCA+PiAxKTsKICAgIH0KCiAgICAqcHBWb2x1bWVUZXh0dXJlID0gKElXaW5lRDNEVm9sdW1lVGV4dHVyZSAqKSBvYmplY3Q7CiAgICBUUkFDRSgiKCVwKSA6IENyZWF0ZWQgdm9sdW1lIHRleHR1cmUgJXBcbiIsIFRoaXMsIG9iamVjdCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWb2x1bWUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgV2lkdGgsIFVJTlQgSGVpZ2h0LCBVSU5UIERlcHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIFVzYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RGT1JNQVQgRm9ybWF0LCBXSU5FRDNEUE9PTCBQb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEVm9sdW1lKiogcHBWb2x1bWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFKiBwU2hhcmVkSGFuZGxlLCBJVW5rbm93biAqcGFyZW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICAgICAgICAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEVm9sdW1lSW1wbCAgICAgICAgKm9iamVjdDsgLyoqIE5PVEU6IGltcGwgcmVmIGFsbG93ZWQgc2luY2UgdGhpcyBpcyBhIGNyZWF0ZSBmdW5jdGlvbiAqKi8KICAgIGNvbnN0IFBpeGVsRm9ybWF0RGVzYyAqZm9ybWF0RGVzYyAgPSBnZXRGb3JtYXREZXNjRW50cnkoRm9ybWF0KTsKCiAgICBEM0RDUkVBVEVSRVNPVVJDRU9CSkVDVElOU1RBTkNFKG9iamVjdCwgVm9sdW1lLCBXSU5FRDNEUlRZUEVfVk9MVU1FLCAoKFdpZHRoICogZm9ybWF0RGVzYy0+YnBwKSAqIEhlaWdodCAqIERlcHRoKSkKCiAgICBUUkFDRSgiKCVwKSA6IFcoJWQpIEgoJWQpIEQoJWQpLCBVc2FnZSglZCksIEZtdCgldSwlcyksIFBvb2woJXMpXG4iLCBUaGlzLCBXaWR0aCwgSGVpZ2h0LAogICAgICAgICAgRGVwdGgsIFVzYWdlLCBGb3JtYXQsIGRlYnVnX2QzZGZvcm1hdChGb3JtYXQpLCBkZWJ1Z19kM2Rwb29sKFBvb2wpKTsKCiAgICBvYmplY3QtPmN1cnJlbnREZXNjLldpZHRoICAgPSBXaWR0aDsKICAgIG9iamVjdC0+Y3VycmVudERlc2MuSGVpZ2h0ICA9IEhlaWdodDsKICAgIG9iamVjdC0+Y3VycmVudERlc2MuRGVwdGggICA9IERlcHRoOwogICAgb2JqZWN0LT5ieXRlc1BlclBpeGVsICAgICAgID0gZm9ybWF0RGVzYy0+YnBwOwoKICAgIC8qKiBOb3RlOiBWb2x1bWUgdGV4dHVyZXMgY2Fubm90IGJlIGR4dG4sIGhlbmNlIG5vIG5lZWQgdG8gY2hlY2sgaGVyZSAqKi8KICAgIG9iamVjdC0+bG9ja2FibGUgICAgICAgICAgICA9IFRSVUU7CiAgICBvYmplY3QtPmxvY2tlZCAgICAgICAgICAgICAgPSBGQUxTRTsKICAgIG1lbXNldCgmb2JqZWN0LT5sb2NrZWRCb3gsIDAsIHNpemVvZihXSU5FRDNEQk9YKSk7CiAgICBvYmplY3QtPmRpcnR5ICAgICAgICAgICAgICAgPSBUUlVFOwoKICAgIHJldHVybiBJV2luZUQzRFZvbHVtZV9BZGREaXJ0eUJveCgoSVdpbmVEM0RWb2x1bWUgKikgb2JqZWN0LCBOVUxMKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVDdWJlVGV4dHVyZShJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgRWRnZUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgTGV2ZWxzLCBEV09SRCBVc2FnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RGT1JNQVQgRm9ybWF0LCBXSU5FRDNEUE9PTCBQb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RDdWJlVGV4dHVyZSAqKnBwQ3ViZVRleHR1cmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEUgKnBTaGFyZWRIYW5kbGUsIElVbmtub3duICpwYXJlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEM0RDQl9DUkVBVEVTVVJGQUNFRk4gRDNEQ0JfQ3JlYXRlU3VyZmFjZSkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgICAgICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RDdWJlVGV4dHVyZUltcGwgKm9iamVjdDsgLyoqIE5PVEU6IGltcGwgcmVmIGFsbG93ZWQgc2luY2UgdGhpcyBpcyBhIGNyZWF0ZSBmdW5jdGlvbiAqKi8KICAgIHVuc2lnbmVkIGludCAgICAgICAgICAgICBpLCBqOwogICAgVUlOVCAgICAgICAgICAgICAgICAgICAgIHRtcFc7CiAgICBIUkVTVUxUICAgICAgICAgICAgICAgICAgaHI7CiAgICB1bnNpZ25lZCBpbnQgcG93MkVkZ2VMZW5ndGggID0gRWRnZUxlbmd0aDsKCiAgICAvKiBUT0RPOiBJdCBzaG91bGQgb25seSBiZSBwb3NzaWJsZSB0byBjcmVhdGUgdGV4dHVyZXMgZm9yIGZvcm1hdHMgCiAgICAgICAgICAgICB0aGF0IGFyZSByZXBvcnRlZCBhcyBzdXBwb3J0ZWQgKi8KICAgIGlmIChXSU5FRDNERk1UX1VOS05PV04gPj0gRm9ybWF0KSB7CiAgICAgICAgV0FSTigiKCVwKSA6IFRleHR1cmUgY2Fubm90IGJlIGNyZWF0ZWQgd2l0aCBhIGZvcm1hdCBvZiBXSU5FRDNERk1UX1VOS05PV05cbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIEQzRENSRUFURVJFU09VUkNFT0JKRUNUSU5TVEFOQ0Uob2JqZWN0LCBDdWJlVGV4dHVyZSwgV0lORUQzRFJUWVBFX0NVQkVURVhUVVJFLCAwKTsKICAgIEQzRElOSVRJQUxJWkVCQVNFVEVYVFVSRShvYmplY3QtPmJhc2VUZXh0dXJlKTsKCiAgICBUUkFDRSgiKCVwKSBDcmVhdGUgQ3ViZSBUZXh0dXJlXG4iLCBUaGlzKTsKCiAgICAvKiogTm9uLXBvd2VyMiBzdXBwb3J0ICoqLwoKICAgIC8qIEZpbmQgdGhlIG5lYXJlc3QgcG93MiBtYXRjaCAqLwogICAgcG93MkVkZ2VMZW5ndGggPSAxOwogICAgd2hpbGUgKHBvdzJFZGdlTGVuZ3RoIDwgRWRnZUxlbmd0aCkgcG93MkVkZ2VMZW5ndGggPDw9IDE7CgogICAgb2JqZWN0LT5lZGdlTGVuZ3RoICAgICAgICAgICA9IEVkZ2VMZW5ndGg7CiAgICAvKiBUT0RPOiBzdXBwb3J0IGZvciBuYXRpdmUgbm9uLXBvd2VyIDIgKi8KICAgIC8qIFByZWNhbGN1bGF0ZWQgc2NhbGluZyBmb3IgJ2Zha2VkJyBub24gcG93ZXIgb2YgdHdvIHRleHR1cmUgY29vcmRzICovCiAgICBvYmplY3QtPnBvdzJzY2FsaW5nRmFjdG9yICAgID0gKChmbG9hdClFZGdlTGVuZ3RoKSAvICgoZmxvYXQpcG93MkVkZ2VMZW5ndGgpOwoKICAgIC8qIENhbGN1bGF0ZSBsZXZlbHMgZm9yIG1pcCBtYXBwaW5nICovCiAgICBpZiAoTGV2ZWxzID09IDApIHsKICAgICAgICBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVscysrOwogICAgICAgIHRtcFcgPSBFZGdlTGVuZ3RoOwogICAgICAgIHdoaWxlICh0bXBXID4gMSkgewogICAgICAgICAgICB0bXBXID0gbWF4KDEsIHRtcFcgPj4gMSk7CiAgICAgICAgICAgIG9iamVjdC0+YmFzZVRleHR1cmUubGV2ZWxzKys7CiAgICAgICAgfQogICAgICAgIFRSQUNFKCJDYWxjdWxhdGVkIGxldmVscyA9ICVkXG4iLCBvYmplY3QtPmJhc2VUZXh0dXJlLmxldmVscyk7CiAgICB9CgogICAgLyogR2VuZXJhdGUgYWxsIHRoZSBzdXJmYWNlcyAqLwogICAgdG1wVyA9IEVkZ2VMZW5ndGg7CiAgICBmb3IgKGkgPSAwOyBpIDwgb2JqZWN0LT5iYXNlVGV4dHVyZS5sZXZlbHM7IGkrKykgewoKICAgICAgICAvKiBDcmVhdGUgdGhlIDYgZmFjZXMgKi8KICAgICAgICBmb3IgKGogPSAwOyBqIDwgNjsgaisrKSB7CgogICAgICAgICAgICBocj1EM0RDQl9DcmVhdGVTdXJmYWNlKFRoaXMtPnBhcmVudCwgcGFyZW50LCB0bXBXLCB0bXBXLCBGb3JtYXQsIFVzYWdlLCBQb29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgLyogTGV2ZWwgKi8sICZvYmplY3QtPnN1cmZhY2VzW2pdW2ldLHBTaGFyZWRIYW5kbGUpOwoKICAgICAgICAgICAgaWYoaHIhPSBXSU5FRDNEX09LKSB7CiAgICAgICAgICAgICAgICAvKiBjbGVhbiB1cCAqLwogICAgICAgICAgICAgICAgaW50IGs7CiAgICAgICAgICAgICAgICBpbnQgbDsKICAgICAgICAgICAgICAgIGZvciAobCA9IDA7IGwgPCBqOyBsKyspIHsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShvYmplY3QtPnN1cmZhY2VzW2pdW2ldKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZvciAoayA9IDA7IGsgPCBpOyBrKyspIHsKICAgICAgICAgICAgICAgICAgICBmb3IgKGwgPSAwOyBsIDwgNjsgbCsrKSB7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2Uob2JqZWN0LT5zdXJmYWNlc1tsXVtqXSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIEZJWE1FKCIoJXApIEZhaWxlZCB0byBjcmVhdGUgc3VyZmFjZVxuIixvYmplY3QpOwogICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLG9iamVjdCk7CiAgICAgICAgICAgICAgICAqcHBDdWJlVGV4dHVyZSA9IE5VTEw7CiAgICAgICAgICAgICAgICByZXR1cm4gaHI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbnRhaW5lcihvYmplY3QtPnN1cmZhY2VzW2pdW2ldLCAoSVdpbmVEM0RCYXNlICopb2JqZWN0KTsKICAgICAgICAgICAgVFJBQ0UoIkNyZWF0ZWQgc3VyZmFjZSBsZXZlbCAlZCBAICVwLFxuIiwgaSwgb2JqZWN0LT5zdXJmYWNlc1tqXVtpXSk7CiAgICAgICAgfQogICAgICAgIHRtcFcgPSBtYXgoMSwgdG1wVyA+PiAxKTsKICAgIH0KCiAgICBUUkFDRSgiKCVwKSA6IENyZWF0ZWQgQ3ViZSBUZXh0dXJlICVwXG4iLCBUaGlzLCBvYmplY3QpOwogICAgKnBwQ3ViZVRleHR1cmUgPSAoSVdpbmVEM0RDdWJlVGV4dHVyZSAqKSBvYmplY3Q7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVRdWVyeShJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RRVUVSWVRZUEUgVHlwZSwgSVdpbmVEM0RRdWVyeSAqKnBwUXVlcnksIElVbmtub3duKiBwYXJlbnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEUXVlcnlJbXBsICpvYmplY3Q7IC8qTk9URTogaW1wbCByZWYgYWxsb3dlZCBzaW5jZSB0aGlzIGlzIGEgY3JlYXRlIGZ1bmN0aW9uICovCiAgICBIUkVTVUxUIGhyID0gV0lORUQzREVSUl9OT1RBVkFJTEFCTEU7CgogICAgLyogSnVzdCBhIGNoZWNrIHRvIHNlZSBpZiB3ZSBzdXBwb3J0IHRoaXMgdHlwZSBvZiBxdWVyeSAqLwogICAgc3dpdGNoKFR5cGUpIHsKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9PQ0NMVVNJT046CiAgICAgICAgVFJBQ0UoIiglcCkgb2NjbHVzaW9uIHF1ZXJ5XG4iLCBUaGlzKTsKICAgICAgICBpZiAoR0xfU1VQUE9SVChBUkJfT0NDTFVTSU9OX1FVRVJZKSkKICAgICAgICAgICAgaHIgPSBXSU5FRDNEX09LOwogICAgICAgIGVsc2UKICAgICAgICAgICAgV0FSTigiVW5zdXBwb3J0ZWQgaW4gbG9jYWwgT3BlbkdMIGltcGxlbWVudGF0aW9uOiBBUkJfT0NDTFVTSU9OX1FVRVJZL05WX09DQ0xVU0lPTl9RVUVSWVxuIik7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX0VWRU5UOgogICAgICAgIGlmKCEoR0xfU1VQUE9SVChOVl9GRU5DRSkgfHwgR0xfU1VQUE9SVChBUFBMRV9GRU5DRSkgKSkgewogICAgICAgICAgICAvKiBIYWxmLUxpZmUgMiBuZWVkcyB0aGlzIHF1ZXJ5LiBJdCBkb2VzIG5vdCByZW5kZXIgdGhlIG1haW4gbWVudSBjb3JyZWN0bHkgb3RoZXJ3aXNlCiAgICAgICAgICAgICAqIFByZXRlbmQgdG8gc3VwcG9ydCBpdCwgZmFraW5nIHRoaXMgcXVlcnkgZG9lcyBub3QgZG8gbXVjaCBoYXJtIGV4Y2VwdCBwb3RlbnRpYWxseSBsb3dlcmluZyBwZXJmb3JtYW5jZQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgRklYTUUoIiglcCkgRXZlbnQgcXVlcnk6IFVuaW1wbGVtZW50ZWQsIGJ1dCBwcmV0ZW5kaW5nIHRvIGJlIHN1cHBvcnRlZFxuIiwgVGhpcyk7CiAgICAgICAgfQogICAgICAgIGhyID0gV0lORUQzRF9PSzsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfVkNBQ0hFOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1JFU09VUkNFTUFOQUdFUjoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9WRVJURVhTVEFUUzoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9USU1FU1RBTVA6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfVElNRVNUQU1QRElTSk9JTlQ6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfVElNRVNUQU1QRlJFUToKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9QSVBFTElORVRJTUlOR1M6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfSU5URVJGQUNFVElNSU5HUzoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9WRVJURVhUSU1JTkdTOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1BJWEVMVElNSU5HUzoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9CQU5EV0lEVEhUSU1JTkdTOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX0NBQ0hFVVRJTElaQVRJT046CiAgICBkZWZhdWx0OgogICAgICAgIEZJWE1FKCIoJXApIFVuaGFuZGxlZCBxdWVyeSB0eXBlICVkXG4iLCBUaGlzLCBUeXBlKTsKICAgIH0KICAgIGlmKE5VTEwgPT0gcHBRdWVyeSB8fCBociAhPSBXSU5FRDNEX09LKSB7CiAgICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIEQzRENSRUFURU9CSkVDVElOU1RBTkNFKG9iamVjdCwgUXVlcnkpCiAgICBvYmplY3QtPnR5cGUgICAgICAgICA9IFR5cGU7CiAgICAvKiBhbGxvY2F0ZWQgdGhlICdleHRlbmRlZCcgZGF0YSBiYXNlZCBvbiB0aGUgdHlwZSBvZiBxdWVyeSByZXF1ZXN0ZWQgKi8KICAgIHN3aXRjaChUeXBlKXsKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9PQ0NMVVNJT046CiAgICAgICAgaWYoR0xfU1VQUE9SVChBUkJfT0NDTFVTSU9OX1FVRVJZKSkgewogICAgICAgICAgICBUUkFDRSgiKCVwKSBBbGxvY2F0aW5nIGRhdGEgZm9yIGFuIG9jY2x1c2lvbiBxdWVyeVxuIiwgVGhpcyk7CiAgICAgICAgICAgIG9iamVjdC0+ZXh0ZW5kZWREYXRhID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihXaW5lUXVlcnlPY2NsdXNpb25EYXRhKSk7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xHZW5RdWVyaWVzQVJCKDEsICYoKFdpbmVRdWVyeU9jY2x1c2lvbkRhdGEgKikob2JqZWN0LT5leHRlbmRlZERhdGEpKS0+cXVlcnlJZCkpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfRVZFTlQ6CiAgICAgICAgLyogVE9ETzogR0xfQVBQTEVfZmVuY2UgKi8KICAgICAgICBpZihHTF9TVVBQT1JUKEFQUExFX0ZFTkNFKSkgewogICAgICAgICAgICBvYmplY3QtPmV4dGVuZGVkRGF0YSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoV2luZVF1ZXJ5RXZlbnREYXRhKSk7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xHZW5GZW5jZXNBUFBMRSgxLCAmKChXaW5lUXVlcnlFdmVudERhdGEgKikob2JqZWN0LT5leHRlbmRlZERhdGEpKS0+ZmVuY2VJZCkpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZW5GZW5jZXNBUFBMRSIpOwogICAgICAgIH0gZWxzZSBpZihHTF9TVVBQT1JUKE5WX0ZFTkNFKSkgewogICAgICAgICAgICBvYmplY3QtPmV4dGVuZGVkRGF0YSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoV2luZVF1ZXJ5RXZlbnREYXRhKSk7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xHZW5GZW5jZXNOVigxLCAmKChXaW5lUXVlcnlFdmVudERhdGEgKikob2JqZWN0LT5leHRlbmRlZERhdGEpKS0+ZmVuY2VJZCkpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZW5GZW5jZXNOViIpOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfVkNBQ0hFOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1JFU09VUkNFTUFOQUdFUjoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9WRVJURVhTVEFUUzoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9USU1FU1RBTVA6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfVElNRVNUQU1QRElTSk9JTlQ6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfVElNRVNUQU1QRlJFUToKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9QSVBFTElORVRJTUlOR1M6CiAgICBjYXNlIFdJTkVEM0RRVUVSWVRZUEVfSU5URVJGQUNFVElNSU5HUzoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9WRVJURVhUSU1JTkdTOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX1BJWEVMVElNSU5HUzoKICAgIGNhc2UgV0lORUQzRFFVRVJZVFlQRV9CQU5EV0lEVEhUSU1JTkdTOgogICAgY2FzZSBXSU5FRDNEUVVFUllUWVBFX0NBQ0hFVVRJTElaQVRJT046CiAgICBkZWZhdWx0OgogICAgICAgIG9iamVjdC0+ZXh0ZW5kZWREYXRhID0gMDsKICAgICAgICBGSVhNRSgiKCVwKSBVbmhhbmRsZWQgcXVlcnkgdHlwZSAlZFxuIixUaGlzICwgVHlwZSk7CiAgICB9CiAgICBUUkFDRSgiKCVwKSA6IENyZWF0ZWQgUXVlcnkgJXBcbiIsIFRoaXMsIG9iamVjdCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElXaW5lRDNERGV2aWNlSW1wbF9TZXR1cEZ1bGxzY3JlZW5XaW5kb3cKICoKICogSGVscGVyIGZ1bmN0aW9uIHRoYXQgbW9kaWZpZXMgYSBIV05EJ3MgU3R5bGUgYW5kIEV4U3R5bGUgZm9yIHByb3BlcgogKiBmdWxsc2NyZWVuIHVzZS4KICoKICogUGFyYW1zOgogKiAgaWZhY2U6IFBvaW50ZXIgdG8gdGhlIElXaW5lRDNERGV2aWNlIGludGVyZmFjZQogKiAgd2luZG93OiBXaW5kb3cgdG8gc2V0dXAKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldHVwRnVsbHNjcmVlbldpbmRvdyhJV2luZUQzRERldmljZSAqaWZhY2UsIEhXTkQgd2luZG93KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgTE9ORyBzdHlsZSwgZXhTdHlsZTsKICAgIC8qIERvbid0IGRvIGFueXRoaW5nIGlmIGFuIG9yaWdpbmFsIHN0eWxlIGlzIHN0b3JlZC4KICAgICAqIFRoYXQgc2hvdWxkbid0IGhhcHBlbgogICAgICovCiAgICBUUkFDRSgiKCVwKTogU2V0dGluZyB1cCB3aW5kb3cgJXAgZm9yIGV4Y2x1c2l2ZSBtb2RlXG4iLCBUaGlzLCB3aW5kb3cpOwogICAgaWYgKFRoaXMtPnN0eWxlIHx8IFRoaXMtPmV4U3R5bGUpIHsKICAgICAgICBFUlIoIiglcCk6IFdhbnQgdG8gY2hhbmdlIHRoZSB3aW5kb3cgcGFyYW1ldGVycyBvZiBIV05EICVwLCBidXQgIgogICAgICAgICAgICAiYW5vdGhlciBzdHlsZSBpcyBzdG9yZWQgZm9yIHJlc3RvcmF0aW9uIGFmdGVyd2FyZHNcbiIsIFRoaXMsIHdpbmRvdyk7CiAgICB9CgogICAgLyogR2V0IHRoZSBwYXJhbWV0ZXJzIGFuZCBzYXZlIHRoZW0gKi8KICAgIHN0eWxlID0gR2V0V2luZG93TG9uZ1cod2luZG93LCBHV0xfU1RZTEUpOwogICAgZXhTdHlsZSA9IEdldFdpbmRvd0xvbmdXKHdpbmRvdywgR1dMX0VYU1RZTEUpOwogICAgVGhpcy0+c3R5bGUgPSBzdHlsZTsKICAgIFRoaXMtPmV4U3R5bGUgPSBleFN0eWxlOwoKICAgIC8qIEZpbHRlciBvdXQgd2luZG93IGRlY29yYXRpb25zICovCiAgICBzdHlsZSAmPSB+V1NfQ0FQVElPTjsKICAgIHN0eWxlICY9IH5XU19USElDS0ZSQU1FOwogICAgZXhTdHlsZSAmPSB+V1NfRVhfV0lORE9XRURHRTsKICAgIGV4U3R5bGUgJj0gfldTX0VYX0NMSUVOVEVER0U7CgogICAgLyogTWFrZSBzdXJlIHRoZSB3aW5kb3cgaXMgbWFuYWdlZCwgb3RoZXJ3aXNlIHdlIHdvbid0IGdldCBrZXlib2FyZCBpbnB1dCAqLwogICAgc3R5bGUgfD0gV1NfUE9QVVAgfCBXU19TWVNNRU5VOwoKICAgIFRSQUNFKCJPbGQgc3R5bGUgd2FzICUwOHgsJTA4eCwgc2V0dGluZyB0byAlMDh4LCUwOHhcbiIsCiAgICAgICAgICBUaGlzLT5zdHlsZSwgVGhpcy0+ZXhTdHlsZSwgc3R5bGUsIGV4U3R5bGUpOwoKICAgIFNldFdpbmRvd0xvbmdXKHdpbmRvdywgR1dMX1NUWUxFLCBzdHlsZSk7CiAgICBTZXRXaW5kb3dMb25nVyh3aW5kb3csIEdXTF9FWFNUWUxFLCBleFN0eWxlKTsKCiAgICAvKiBJbmZvcm0gdGhlIHdpbmRvdyBhYm91dCB0aGUgdXBkYXRlLiAqLwogICAgU2V0V2luZG93UG9zKHdpbmRvdywgSFdORF9UT1AsIDAsIDAsCiAgICAgICAgICAgIFRoaXMtPmRkcmF3X3dpZHRoLCBUaGlzLT5kZHJhd19oZWlnaHQsIFNXUF9GUkFNRUNIQU5HRUQpOwogICAgU2hvd1dpbmRvdyh3aW5kb3csIFNXX05PUk1BTCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJV2luZUQzRERldmljZUltcGxfUmVzdG9yZVdpbmRvdwogKgogKiBIZWxwZXIgZnVuY3Rpb24gdGhhdCByZXN0b3JlcyBhIHdpbmRvd3MnIHByb3BlcnRpZXMgd2hlbiB0YWtpbmcgaXQgb3V0CiAqIG9mIGZ1bGxzY3JlZW4gbW9kZQogKgogKiBQYXJhbXM6CiAqICBpZmFjZTogUG9pbnRlciB0byB0aGUgSVdpbmVEM0REZXZpY2UgaW50ZXJmYWNlCiAqICB3aW5kb3c6IFdpbmRvdyB0byBzZXR1cAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyB2b2lkIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfUmVzdG9yZVdpbmRvdyhJV2luZUQzRERldmljZSAqaWZhY2UsIEhXTkQgd2luZG93KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgLyogVGhpcyBjb3VsZCBiZSBhIEREU0NMX05PUk1BTCAtPiBERFNDTF9OT1JNQUwKICAgICAqIHN3aXRjaCwgZG8gbm90aGluZwogICAgICovCiAgICBpZiAoIVRoaXMtPnN0eWxlICYmICFUaGlzLT5leFN0eWxlKSByZXR1cm47CgogICAgVFJBQ0UoIiglcCk6IFJlc3RvcmluZyB3aW5kb3cgc2V0dGluZ3Mgb2Ygd2luZG93ICVwIHRvICUwOHgsICUwOHhcbiIsCiAgICAgICAgICBUaGlzLCB3aW5kb3csIFRoaXMtPnN0eWxlLCBUaGlzLT5leFN0eWxlKTsKCiAgICBTZXRXaW5kb3dMb25nVyh3aW5kb3csIEdXTF9TVFlMRSwgVGhpcy0+c3R5bGUpOwogICAgU2V0V2luZG93TG9uZ1cod2luZG93LCBHV0xfRVhTVFlMRSwgVGhpcy0+ZXhTdHlsZSk7CgogICAgLyogRGVsZXRlIHRoZSBvbGQgdmFsdWVzICovCiAgICBUaGlzLT5zdHlsZSA9IDA7CiAgICBUaGlzLT5leFN0eWxlID0gMDsKCiAgICAvKiBJbmZvcm0gdGhlIHdpbmRvdyBhYm91dCB0aGUgdXBkYXRlICovCiAgICBTZXRXaW5kb3dQb3Mod2luZG93LCAwIC8qIEluc2VydEFmdGVyLCBpZ25vcmVkICovLAogICAgICAgICAgICAgICAgIDAsIDAsIDAsIDAsIC8qIFBvcywgU2l6ZSwgaWdub3JlZCAqLwogICAgICAgICAgICAgICAgIFNXUF9GUkFNRUNIQU5HRUQgfCBTV1BfTk9NT1ZFIHwgU1dQX05PU0laRSB8IFNXUF9OT1pPUkRFUik7Cn0KCi8qIGV4YW1wbGUgYXQgaHR0cDovL3d3dy5mYWlyeWVuZ2luZS5jb20vYXJ0aWNsZXMvZHhtdWx0aXZpZXdzLmh0bSAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZUFkZGl0aW9uYWxTd2FwQ2hhaW4oSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBXSU5FRDNEUFJFU0VOVF9QQVJBTUVURVJTKiAgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3dhcENoYWluKiogcHBTd2FwQ2hhaW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElVbmtub3duKiBwYXJlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEQzRENCX0NSRUFURVJFTkRFUlRBUkdFVEZOIEQzRENCX0NyZWF0ZVJlbmRlclRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEQ0JfQ1JFQVRFREVQVEhTVEVOQ0lMU1VSRkFDRUZOIEQzRENCX0NyZWF0ZURlcHRoU3RlbmNpbCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICAgICAgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgSERDICAgICAgICAgICAgICAgICAgICAgaERjOwogICAgSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICAqb2JqZWN0OyAvKiogTk9URTogaW1wbCByZWYgYWxsb3dlZCBzaW5jZSB0aGlzIGlzIGEgY3JlYXRlIGZ1bmN0aW9uICoqLwogICAgSFJFU1VMVCAgICAgICAgICAgICAgICAgaHIgPSBXSU5FRDNEX09LOwogICAgSVVua25vd24gICAgICAgICAgICAgICAqYnVmZmVyUGFyZW50OwogICAgRGlzcGxheSAgICAgICAgICAgICAgICAqZGlzcGxheTsKCiAgICBUUkFDRSgiKCVwKSA6IENyZWF0ZWQgQWRpdGlvbmFsIFN3YXAgQ2hhaW5cbiIsIFRoaXMpOwoKICAgLyoqIEZJWE1FOiBUZXN0IHVuZGVyIHdpbmRvd3MgdG8gZmluZCBvdXQgd2hhdCB0aGUgbGlmZSBjeWNsZSBvZiBhIHN3YXAgY2hhaW4gaXMsCiAgICogZG9lcyBhIGRldmljZSBob2xkIGEgcmVmZXJlbmNlIHRvIGEgc3dhcCBjaGFpbiBnaXZpbmcgdGhlbSBhIGxpZmV0aW1lIG9mIHRoZSBkZXZpY2UKICAgKiBvciBkb2VzIHRoZSBzd2FwIGNoYWluIG5vdGlmeSB0aGUgZGV2aWNlIG9mIGl0cyBkZXN0cnVjdGlvbi4KICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgLyogQ2hlY2sgdGhlIHBhcmFtcyAqLwogICAgaWYocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJDb3VudCA+IFdJTkVEM0RQUkVTRU5UX0JBQ0tfQlVGRkVSX01BWCkgewogICAgICAgIEVSUigiQXBwIHJlcXVlc3RlZCAlZCBiYWNrIGJ1ZmZlcnMsIHRoaXMgaXMgbm90IHN1cHBvcnRlZCBmb3Igbm93XG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckNvdW50KTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0gZWxzZSBpZiAocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJDb3VudCA+IDEpIHsKICAgICAgICBGSVhNRSgiVGhlIGFwcCByZXF1ZXN0cyBtb3JlIHRoYW4gb25lIGJhY2sgYnVmZmVyLCB0aGlzIGNhbid0IGJlIHN1cHBvcnRlZCBwcm9wZXJseS4gUGxlYXNlIGNvbmZpZ3VyZSB0aGUgYXBwbGljYXRpb24gdG8gdXNlIGRvdWJsZSBidWZmZXJpbmcoPTEgYmFjayBidWZmZXIpIGlmIHBvc3NpYmxlXG4iKTsKICAgIH0KCiAgICBEM0RDUkVBVEVPQkpFQ1RJTlNUQU5DRShvYmplY3QsIFN3YXBDaGFpbikKCiAgICAvKioqKioqKioqKioqKioqKioqKioqCiAgICAqIExvb2t1cCB0aGUgd2luZG93IEhhbmRsZSBhbmQgdGhlIHJlbGF0aW5nIFggd2luZG93IGhhbmRsZQogICAgKioqKioqKioqKioqKioqKioqKiovCgogICAgLyogU2V0dXAgaHduZCB3ZSBhcmUgdXNpbmcsIHBsdXMgd2hpY2ggZGlzcGxheSB0aGlzIGVxdWF0ZXMgdG8gKi8KICAgIG9iamVjdC0+d2luX2hhbmRsZSA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5oRGV2aWNlV2luZG93OwogICAgaWYgKCFvYmplY3QtPndpbl9oYW5kbGUpIHsKICAgICAgICBvYmplY3QtPndpbl9oYW5kbGUgPSBUaGlzLT5jcmVhdGVQYXJtcy5oRm9jdXNXaW5kb3c7CiAgICB9CgogICAgb2JqZWN0LT53aW5faGFuZGxlID0gR2V0QW5jZXN0b3Iob2JqZWN0LT53aW5faGFuZGxlLCBHQV9ST09UKTsKICAgIGlmICggISggb2JqZWN0LT53aW4gPSAoV2luZG93KUdldFByb3BBKG9iamVjdC0+d2luX2hhbmRsZSwgIl9fd2luZV94MTFfd2hvbGVfd2luZG93IikgKSApIHsKICAgICAgICBFUlIoIkNhbid0IGdldCBkcmF3YWJsZSAod2luZG93KSwgSFdORDolcCBkb2Vzbid0IGhhdmUgdGhlIHByb3BlcnR5IF9fd2luZV94MTFfd2hvbGVfd2luZG93XG4iLCBvYmplY3QtPndpbl9oYW5kbGUpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX05PVEFWQUlMQUJMRTsKICAgIH0KICAgIGhEYyAgICAgICAgICAgICAgICA9IEdldERDKG9iamVjdC0+d2luX2hhbmRsZSk7CiAgICBkaXNwbGF5ICAgICAgICAgICAgPSBnZXRfZGlzcGxheShoRGMpOwogICAgUmVsZWFzZURDKG9iamVjdC0+d2luX2hhbmRsZSwgaERjKTsKICAgIFRSQUNFKCJVc2luZyBhIGRpc3BsYXkgb2YgJXAgJXBcbiIsIGRpc3BsYXksIGhEYyk7CgogICAgaWYgKE5VTEwgPT0gZGlzcGxheSB8fCBOVUxMID09IGhEYykgewogICAgICAgIFdBUk4oIkZhaWxlZCB0byBnZXQgYSBkaXNwbGF5IGFuZCBIRGMgZm9yIFdpbmRvdyAlcFxuIiwgb2JqZWN0LT53aW5faGFuZGxlKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9OT1RBVkFJTEFCTEU7CiAgICB9CgogICAgaWYgKG9iamVjdC0+d2luID09IDApIHsKICAgICAgICBXQVJOKCJGYWlsZWQgdG8gZ2V0IGEgdmFsaWQgWFZpc3VpYWwgSUQgZm9yIHRoZSB3aW5kb3cgJXBcbiIsIG9iamVjdC0+d2luX2hhbmRsZSk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfTk9UQVZBSUxBQkxFOwogICAgfQoKICAgIG9iamVjdC0+b3JpZ193aWR0aCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTQ1JFRU4pOwogICAgb2JqZWN0LT5vcmlnX2hlaWdodCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTQ1JFRU4pOwogICAgb2JqZWN0LT5vcmlnX2ZtdCA9IHBpeGVsZm9ybWF0X2Zvcl9kZXB0aChHZXREZXZpY2VDYXBzKGhEYywgQklUU1BJWEVMKSAqIEdldERldmljZUNhcHMoaERjLCBQTEFORVMpKTsKCiAgICAvKiogTVNETjogSWYgV2luZG93ZWQgaXMgVFJVRSBhbmQgZWl0aGVyIG9mIHRoZSBCYWNrQnVmZmVyV2lkdGgvSGVpZ2h0IHZhbHVlcyBpcyB6ZXJvLAogICAgICogIHRoZW4gdGhlIGNvcnJlc3BvbmRpbmcgZGltZW5zaW9uIG9mIHRoZSBjbGllbnQgYXJlYSBvZiB0aGUgaERldmljZVdpbmRvdwogICAgICogIChvciB0aGUgZm9jdXMgd2luZG93LCBpZiBoRGV2aWNlV2luZG93IGlzIE5VTEwpIGlzIHRha2VuLgogICAgICAqKioqKioqKioqKioqKioqKioqKioqLwoKICAgIGlmIChwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+V2luZG93ZWQgJiYKICAgICAgICAoKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGggPT0gMCkgfHwKICAgICAgICAgKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0ID09IDApKSkgewoKICAgICAgICBSRUNUIFJlY3Q7CiAgICAgICAgR2V0Q2xpZW50UmVjdChvYmplY3QtPndpbl9oYW5kbGUsICZSZWN0KTsKCiAgICAgICAgaWYgKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGggPT0gMCkgewogICAgICAgICAgIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGggPSBSZWN0LnJpZ2h0OwogICAgICAgICAgIFRSQUNFKCJVcGRhdGluZyB3aWR0aCB0byAlZFxuIiwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aCk7CiAgICAgICAgfQogICAgICAgIGlmIChwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodCA9PSAwKSB7CiAgICAgICAgICAgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQgPSBSZWN0LmJvdHRvbTsKICAgICAgICAgICBUUkFDRSgiVXBkYXRpbmcgaGVpZ2h0IHRvICVkXG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIFB1dCB0aGUgY29ycmVjdCBmaWd1cmVzIGluIHRoZSBwcmVzZW50YXRpb24gcGFyYW1ldGVycyAqLwogICAgVFJBQ0UoIkNvcHlpbmcgYWNyb3NzIHByZXNlbnRhdGlvbiBwYXJhbWV0ZXJzXG4iKTsKICAgIG9iamVjdC0+cHJlc2VudFBhcm1zID0gKnBQcmVzZW50YXRpb25QYXJhbWV0ZXJzOwoKICAgIFRSQUNFKCJjYWxsaW5nIHJlbmRlcnRhcmdldCBDQlxuIik7CiAgICBociA9IEQzRENCX0NyZWF0ZVJlbmRlclRhcmdldCgoSVVua25vd24gKikgVGhpcy0+cGFyZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckhlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyRm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLk11bHRpU2FtcGxlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5NdWx0aVNhbXBsZVF1YWxpdHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJVRSAvKiBMb2NrYWJsZSAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmb2JqZWN0LT5mcm9udEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMIC8qIHBTaGFyZWQgKGFsd2F5cyBudWxsKSovKTsKICAgIGlmIChvYmplY3QtPmZyb250QnVmZmVyICE9IE5VTEwpIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29udGFpbmVyKG9iamVjdC0+ZnJvbnRCdWZmZXIsIChJV2luZUQzREJhc2UgKilvYmplY3QpOwogICAgfSBlbHNlIHsKICAgICAgICBFUlIoIkZhaWxlZCB0byBjcmVhdGUgdGhlIGZyb250IGJ1ZmZlclxuIik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKioKICAgICogQ3JlYXRlIGFuIG9wZW5nbCBjb250ZXh0IGZvciB0aGUgZGlzcGxheSB2aXN1YWwKICAgICogIE5PVEU6IHRoZSB2aXN1YWwgaXMgY2hvc2VuIGFzIHRoZSB3aW5kb3cgaXMgY3JlYXRlZCBhbmQgdGhlIGdsY29udGV4dCBjYW5ub3QKICAgICogICAgIHVzZSBkaWZmZXJlbnQgcHJvcGVydGllcyBhZnRlciB0aGF0IHBvaW50IGluIHRpbWUuIEZJWE1FOiBIb3cgdG8gaGFuZGxlIHdoZW4gcmVxdWVzdGVkIGZvcm1hdAogICAgKiAgICAgZG9lc24ndCBtYXRjaCBhY3R1YWwgdmlzdWFsPyBDYW5ub3QgY2hvb3NlIG9uZSBoZXJlIC0gY29kZSByZW1vdmVkIGFzIGl0IE9OTFkgd29ya3MgaWYgdGhlIG9uZQogICAgKiAgICAgaXQgY2hvb3NlcyBpcyBpZGVudGljYWwgdG8gdGhlIG9uZSBhbHJlYWR5IGJlaW5nIHVzZWQhCiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgIC8qKiBGSVhNRTogSGFuZGxlIHN0ZW5jaWwgYXBwcm9wcmlhdGVseSB2aWEgRW5hYmxlQXV0b0RlcHRoU3RlbmNpbCAvIEF1dG9EZXB0aFN0ZW5jaWxGb3JtYXQgKiovCgogICAgb2JqZWN0LT5jb250ZXh0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihvYmplY3QtPmNvbnRleHQpKTsKICAgIGlmKCFvYmplY3QtPmNvbnRleHQpIHsKICAgIH0KICAgIG9iamVjdC0+bnVtX2NvbnRleHRzID0gMTsKCiAgICBFTlRFUl9HTCgpOwogICAgb2JqZWN0LT5jb250ZXh0WzBdID0gQ3JlYXRlQ29udGV4dChUaGlzLCAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBvYmplY3QtPmZyb250QnVmZmVyLCBkaXNwbGF5LCBvYmplY3QtPndpbik7CiAgICBMRUFWRV9HTCgpOwoKICAgIGlmICghb2JqZWN0LT5jb250ZXh0KSB7CiAgICAgICAgRVJSKCJGYWlsZWQgdG8gY3JlYXRlIGEgbmV3IGNvbnRleHRcbiIpOwogICAgICAgIGhyID0gV0lORUQzREVSUl9OT1RBVkFJTEFCTEU7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0gZWxzZSB7CiAgICAgICAgVFJBQ0UoIkNvbnRleHQgY3JlYXRlZCAoSFdORD0lcCwgZ2xDb250ZXh0PSVwLCBXaW5kb3c9JWxkKVxuIiwKICAgICAgICAgICAgICAgb2JqZWN0LT53aW5faGFuZGxlLCBvYmplY3QtPmNvbnRleHRbMF0tPmdsQ3R4LCBvYmplY3QtPndpbik7CiAgICB9CgogICAvKioqKioqKioqKioqKioqKioqKioqCiAgICogV2luZG93ZWQgLyBGdWxsc2NyZWVuCiAgICoqKioqKioqKioqKioqKioqKiovCgogICAvKioKICAgKiBUT0RPOiBNU0ROIHNheXMgdGhhdCB3ZSBhcmUgb25seSBhbGxvd2VkIG9uZSBmdWxsc2NyZWVuIHN3YXBjaGFpbiBwZXIgZGV2aWNlLAogICAqIHNvIHdlIHNob3VsZCByZWFsbHkgY2hlY2sgdG8gc2VlIGlmIHRoZXJlIGlzIGEgZnVsbHNjcmVlbiBzd2FwY2hhaW4gYWxyZWFkeQogICAqIEkgdGhpbmsgV2luZG93cyBhbmQgWCBoYXZlIGRpZmZlcmVudCBpZGVhcyBhYm91dCBmdWxsc2NyZWVuLCBkb2VzIGEgc2luZ2xlIGhlYWQgY291bnQgYXMgZnVsbCBzY3JlZW4/CiAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiAgIGlmICghcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPldpbmRvd2VkKSB7CgogICAgICAgIERFVk1PREVXIGRldm1vZGU7CiAgICAgICAgSERDICAgICAgaGRjOwogICAgICAgIGludCAgICAgIGJwcCA9IDA7CiAgICAgICAgUkVDVCAgICAgY2xpcF9yYzsKCiAgICAgICAgLyogR2V0IGluZm8gb24gdGhlIGN1cnJlbnQgZGlzcGxheSBzZXR1cCAqLwogICAgICAgIGhkYyA9IEdldERDKDApOwogICAgICAgIGJwcCA9IEdldERldmljZUNhcHMoaGRjLCBCSVRTUElYRUwpOwogICAgICAgIFJlbGVhc2VEQygwLCBoZGMpOwoKICAgICAgICAvKiBDaGFuZ2UgdGhlIGRpc3BsYXkgc2V0dGluZ3MgKi8KICAgICAgICBtZW1zZXQoJmRldm1vZGUsIDAsIHNpemVvZihERVZNT0RFVykpOwogICAgICAgIGRldm1vZGUuZG1GaWVsZHMgICAgID0gRE1fQklUU1BFUlBFTCB8IERNX1BFTFNXSURUSCB8IERNX1BFTFNIRUlHSFQ7CiAgICAgICAgZGV2bW9kZS5kbUJpdHNQZXJQZWwgPSAoYnBwID49IDI0KSA/IDMyIDogYnBwOyAvKiBTdHVwaWQgWFZpZE1vZGUgY2Fubm90IGNoYW5nZSBicHAgKi8KICAgICAgICBkZXZtb2RlLmRtUGVsc1dpZHRoICA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGg7CiAgICAgICAgZGV2bW9kZS5kbVBlbHNIZWlnaHQgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodDsKICAgICAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgIkdhbWVycyBDRyIsIC0xLCBkZXZtb2RlLmRtRGV2aWNlTmFtZSwgQ0NIREVWSUNFTkFNRSk7CiAgICAgICAgQ2hhbmdlRGlzcGxheVNldHRpbmdzRXhXKGRldm1vZGUuZG1EZXZpY2VOYW1lLCAmZGV2bW9kZSwgb2JqZWN0LT53aW5faGFuZGxlLCBDRFNfRlVMTFNDUkVFTiwgTlVMTCk7CgogICAgICAgIC8qIEZvciBHZXREaXNwbGF5TW9kZSAqLwogICAgICAgIFRoaXMtPmRkcmF3X3dpZHRoID0gZGV2bW9kZS5kbVBlbHNXaWR0aDsKICAgICAgICBUaGlzLT5kZHJhd19oZWlnaHQgPSBkZXZtb2RlLmRtUGVsc0hlaWdodDsKICAgICAgICBUaGlzLT5kZHJhd19mb3JtYXQgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckZvcm1hdDsKCiAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0RnVsbHNjcmVlbihpZmFjZSwgVFJVRSk7CgogICAgICAgIC8qIEFuZCBmaW5hbGx5IGNsaXAgbW91c2UgdG8gb3VyIHNjcmVlbiAqLwogICAgICAgIFNldFJlY3QoJmNsaXBfcmMsIDAsIDAsIGRldm1vZGUuZG1QZWxzV2lkdGgsIGRldm1vZGUuZG1QZWxzSGVpZ2h0KTsKICAgICAgICBDbGlwQ3Vyc29yKCZjbGlwX3JjKTsKICAgIH0KCiAgIC8qKioqKioqKioqKioqKioqKioqKioKICAgKiBDcmVhdGUgdGhlIGJhY2ssIGZyb250IGFuZCBzdGVuY2lsIGJ1ZmZlcnMKICAgKioqKioqKioqKioqKioqKioqKi8KICAgIGlmKG9iamVjdC0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJDb3VudCA+IDApIHsKICAgICAgICBpbnQgaTsKCiAgICAgICAgb2JqZWN0LT5iYWNrQnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihJV2luZUQzRFN1cmZhY2UgKikgKiBvYmplY3QtPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyQ291bnQpOwogICAgICAgIGlmKCFvYmplY3QtPmJhY2tCdWZmZXIpIHsKICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5XG4iKTsKICAgICAgICAgICAgaHIgPSBFX09VVE9GTUVNT1JZOwogICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgIH0KCiAgICAgICAgZm9yKGkgPSAwOyBpIDwgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckNvdW50OyBpKyspIHsKICAgICAgICAgICAgVFJBQ0UoImNhbGxpbmcgcmVuZGVydGFyZ2V0IENCXG4iKTsKICAgICAgICAgICAgaHIgPSBEM0RDQl9DcmVhdGVSZW5kZXJUYXJnZXQoKElVbmtub3duICopIFRoaXMtPnBhcmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJIZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLk11bHRpU2FtcGxlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuTXVsdGlTYW1wbGVRdWFsaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFIC8qIExvY2thYmxlICovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmb2JqZWN0LT5iYWNrQnVmZmVyW2ldLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMIC8qIHBTaGFyZWQgKGFsd2F5cyBudWxsKSovKTsKICAgICAgICAgICAgaWYoaHIgPT0gV0lORUQzRF9PSyAmJiBvYmplY3QtPmJhY2tCdWZmZXJbaV0pIHsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb250YWluZXIob2JqZWN0LT5iYWNrQnVmZmVyW2ldLCAoSVdpbmVEM0RCYXNlICopb2JqZWN0KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIEVSUigiQ2Fubm90IGNyZWF0ZSBuZXcgYmFjayBidWZmZXJcbiIpOwogICAgICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICAgICAgfQogICAgICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgICAgICBnbERyYXdCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoR0xfQkFDSykiKTsKICAgICAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIG9iamVjdC0+YmFja0J1ZmZlciA9IE5VTEw7CgogICAgICAgIC8qIFNpbmdsZSBidWZmZXJpbmcgLSBkcmF3IHRvIGZyb250IGJ1ZmZlciAqLwogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgZ2xEcmF3QnVmZmVyKEdMX0ZST05UKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVyKEdMX0ZST05UKSIpOwogICAgICAgIExFQVZFX0dMKCk7CiAgICB9CgogICAgLyogVW5kZXIgZGlyZWN0WCBzd2FwY2hhaW5zIHNoYXJlIHRoZSBkZXB0aCBzdGVuY2lsLCBzbyBvbmx5IGNyZWF0ZSBvbmUgZGVwdGgtc3RlbmNpbCAqLwogICAgaWYgKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5FbmFibGVBdXRvRGVwdGhTdGVuY2lsICYmIGhyID09IFdJTkVEM0RfT0spIHsKICAgICAgICBUUkFDRSgiQ3JlYXRpbmcgZGVwdGggc3RlbmNpbCBidWZmZXJcbiIpOwogICAgICAgIGlmIChUaGlzLT5kZXB0aFN0ZW5jaWxCdWZmZXIgPT0gTlVMTCApIHsKICAgICAgICAgICAgaHIgPSBEM0RDQl9DcmVhdGVEZXB0aFN0ZW5jaWwoKElVbmtub3duICopIFRoaXMtPnBhcmVudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QtPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJIZWlnaHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLkF1dG9EZXB0aFN0ZW5jaWxGb3JtYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdC0+cHJlc2VudFBhcm1zLk11bHRpU2FtcGxlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0LT5wcmVzZW50UGFybXMuTXVsdGlTYW1wbGVRdWFsaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQUxTRSAvKiBGSVhNRTogRGlzY2FyZCAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlRoaXMtPmRlcHRoU3RlbmNpbEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCAvKiBwU2hhcmVkIChhbHdheXMgbnVsbCkqLyAgKTsKICAgICAgICAgICAgaWYgKFRoaXMtPmRlcHRoU3RlbmNpbEJ1ZmZlciAhPSBOVUxMKQogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbnRhaW5lcihUaGlzLT5kZXB0aFN0ZW5jaWxCdWZmZXIsIDApOwogICAgICAgIH0KCiAgICAgICAgLyoqIFRPRE86IEEgY2hlY2sgb24gd2lkdGgsIGhlaWdodCBhbmQgbXVsdGlzYW1wbGUgdHlwZXMKICAgICAgICAqKHNpbmNlIHRoZSB6YnVmZmVyIG11c3QgYmUgYXQgbGVhc3QgYXMgbGFyZ2UgYXMgdGhlIHJlbmRlciB0YXJnZXQgYW5kIGhhdmUgdGhlIHNhbWUgbXVsdGlzYW1wbGUgcGFyYW1ldGVycykKICAgICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgICAgICBvYmplY3QtPndhbnRzRGVwdGhTdGVuY2lsQnVmZmVyID0gVFJVRTsKICAgIH0gZWxzZSB7CiAgICAgICAgb2JqZWN0LT53YW50c0RlcHRoU3RlbmNpbEJ1ZmZlciA9IEZBTFNFOwogICAgfQoKICAgIFRSQUNFKCJDcmVhdGVkIHN3YXBjaGFpbiAlcFxuIiwgb2JqZWN0KTsKICAgIFRSQUNFKCJGcm9udEJ1ZiBAICVwLCBCYWNrQnVmIEAgJXAsIERlcHRoU3RlbmNpbCAlZFxuIixvYmplY3QtPmZyb250QnVmZmVyLCBvYmplY3QtPmJhY2tCdWZmZXIgPyBvYmplY3QtPmJhY2tCdWZmZXJbMF0gOiBOVUxMLCBvYmplY3QtPndhbnRzRGVwdGhTdGVuY2lsQnVmZmVyKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwoKZXJyb3I6CiAgICBpZiAob2JqZWN0LT5iYWNrQnVmZmVyKSB7CiAgICAgICAgaW50IGk7CiAgICAgICAgZm9yKGkgPSAwOyBpIDwgb2JqZWN0LT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckNvdW50OyBpKyspIHsKICAgICAgICAgICAgaWYob2JqZWN0LT5iYWNrQnVmZmVyW2ldKSB7CiAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfR2V0UGFyZW50KG9iamVjdC0+YmFja0J1ZmZlcltpXSwgJmJ1ZmZlclBhcmVudCk7CiAgICAgICAgICAgICAgICBJVW5rbm93bl9SZWxlYXNlKGJ1ZmZlclBhcmVudCk7IC8qIG9uY2UgZm9yIHRoZSBnZXQgcGFyZW50ICovCiAgICAgICAgICAgICAgICBpZiAoSVVua25vd25fUmVsZWFzZShidWZmZXJQYXJlbnQpID4gMCkgewogICAgICAgICAgICAgICAgICAgIEZJWE1FKCIoJXApIFNvbWV0aGluZydzIHN0aWxsIGhvbGRpbmcgdGhlIGJhY2sgYnVmZmVyXG4iLFRoaXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9iamVjdC0+YmFja0J1ZmZlcik7CiAgICAgICAgb2JqZWN0LT5iYWNrQnVmZmVyID0gTlVMTDsKICAgIH0KICAgIGlmKG9iamVjdC0+Y29udGV4dCkgewogICAgICAgIERlc3Ryb3lDb250ZXh0KFRoaXMsIG9iamVjdC0+Y29udGV4dFswXSk7CiAgICB9CiAgICBpZihvYmplY3QtPmZyb250QnVmZmVyKSB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX0dldFBhcmVudChvYmplY3QtPmZyb250QnVmZmVyLCAmYnVmZmVyUGFyZW50KTsKICAgICAgICBJVW5rbm93bl9SZWxlYXNlKGJ1ZmZlclBhcmVudCk7IC8qIG9uY2UgZm9yIHRoZSBnZXQgcGFyZW50ICovCiAgICAgICAgaWYgKElVbmtub3duX1JlbGVhc2UoYnVmZmVyUGFyZW50KSA+IDApIHsKICAgICAgICAgICAgRklYTUUoIiglcCkgU29tZXRoaW5nJ3Mgc3RpbGwgaG9sZGluZyB0aGUgZnJvbnQgYnVmZmVyXG4iLFRoaXMpOwogICAgICAgIH0KICAgIH0KICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9iamVjdCk7CiAgICByZXR1cm4gaHI7Cn0KCi8qKiBOT1RFOiBUaGVzZSBhcmUgYWhlYWQgb2YgdGhlIG90aGVyIGdldHRlcnMgYW5kIHNldHRlcnMgdG8gc2F2ZSB1c2luZyBhIGZvcndhcmQgZGVjbGFyYXRpb24gKiovCnN0YXRpYyBVSU5UICAgICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXROdW1iZXJPZlN3YXBDaGFpbnMoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgcmV0dXJuIFRoaXMtPk51bWJlck9mU3dhcENoYWluczsKfQoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFN3YXBDaGFpbihJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgaVN3YXBDaGFpbiwgSVdpbmVEM0RTd2FwQ2hhaW4gKipwU3dhcENoYWluKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IHN3YXBjaGFpbiAlZFxuIiwgVGhpcywgaVN3YXBDaGFpbik7CgogICAgaWYoaVN3YXBDaGFpbiA8IFRoaXMtPk51bWJlck9mU3dhcENoYWlucykgewogICAgICAgICpwU3dhcENoYWluID0gVGhpcy0+c3dhcGNoYWluc1tpU3dhcENoYWluXTsKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9BZGRSZWYoKnBTd2FwQ2hhaW4pOwogICAgICAgIFRSQUNFKCIoJXApIHJldHVybmluZyAlcFxuIiwgVGhpcywgKnBTd2FwQ2hhaW4pOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfSBlbHNlIHsKICAgICAgICBUUkFDRSgiU3dhcGNoYWluIG91dCBvZiByYW5nZVxuIik7CiAgICAgICAgKnBTd2FwQ2hhaW4gPSBOVUxMOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQp9CgovKioqKioKICogVmVydGV4IERlY2xhcmF0aW9uCiAqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVWZXJ0ZXhEZWNsYXJhdGlvbihJV2luZUQzRERldmljZSogaWZhY2UsIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb24qKiBwcFZlcnRleERlY2xhcmF0aW9uLAogICAgICAgIElVbmtub3duICpwYXJlbnQsIGNvbnN0IFdJTkVEM0RWRVJURVhFTEVNRU5UICplbGVtZW50cywgc2l6ZV90IGVsZW1lbnRfY291bnQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgICAgICAgICAgICpUaGlzICAgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uSW1wbCAqb2JqZWN0ID0gTlVMTDsKICAgIEhSRVNVTFQgaHIgPSBXSU5FRDNEX09LOwoKICAgIFRSQUNFKCIoJXApIDogZGlyZWN0WFZlcnNpb24gJXUsIGVsZW1lbnRzICVwLCBlbGVtZW50X2NvdW50ICVkLCBwcERlY2w9JXBcbiIsCiAgICAgICAgICAgIFRoaXMsICgoSVdpbmVEM0RJbXBsICopVGhpcy0+d2luZUQzRCktPmR4VmVyc2lvbiwgZWxlbWVudHMsIGVsZW1lbnRfY291bnQsIHBwVmVydGV4RGVjbGFyYXRpb24pOwoKICAgIEQzRENSRUFURU9CSkVDVElOU1RBTkNFKG9iamVjdCwgVmVydGV4RGVjbGFyYXRpb24pCgogICAgaHIgPSBJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uX1NldERlY2xhcmF0aW9uKChJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uICopb2JqZWN0LCBlbGVtZW50cywgZWxlbWVudF9jb3VudCk7CgogICAgcmV0dXJuIGhyOwp9CgovKiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2FyY2hpdmUvZGVmYXVsdC5hc3A/dXJsPS9hcmNoaXZlL2VuLXVzL2RpcmVjdHg5X2MvZGlyZWN0eC9ncmFwaGljcy9wcm9ncmFtbWluZ2d1aWRlL3Byb2dyYW1tYWJsZS92ZXJ0ZXhzaGFkZXJzL3ZzY3JlYXRlLmFzcCAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZlcnRleFNoYWRlcihJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb24gKnZlcnRleF9kZWNsYXJhdGlvbiwgQ09OU1QgRFdPUkQgKnBGdW5jdGlvbiwgSVdpbmVEM0RWZXJ0ZXhTaGFkZXIgKipwcFZlcnRleFNoYWRlciwgSVVua25vd24gKnBhcmVudCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICAgICAgICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RWZXJ0ZXhTaGFkZXJJbXBsICpvYmplY3Q7ICAvKiBOT1RFOiBpbXBsIHVzYWdlIGlzIG9rLCB0aGlzIGlzIGEgY3JlYXRlICovCiAgICBIUkVTVUxUIGhyID0gV0lORUQzRF9PSzsKICAgIEQzRENSRUFURVNIQURFUk9CSkVDVElOU1RBTkNFKG9iamVjdCwgVmVydGV4U2hhZGVyKQogICAgb2JqZWN0LT5iYXNlU2hhZGVyLnNoYWRlcl9pbnMgPSBJV2luZUQzRFZlcnRleFNoYWRlckltcGxfc2hhZGVyX2luczsKCiAgICBUUkFDRSgiKCVwKSA6IENyZWF0ZWQgVmVydGV4IHNoYWRlciAlcFxuIiwgVGhpcywgKnBwVmVydGV4U2hhZGVyKTsKCiAgICBpZiAodmVydGV4X2RlY2xhcmF0aW9uKSB7CiAgICAgICAgSVdpbmVEM0RWZXJ0ZXhTaGFkZXJfRmFrZVNlbWFudGljcygqcHBWZXJ0ZXhTaGFkZXIsIHZlcnRleF9kZWNsYXJhdGlvbik7CiAgICB9CgogICAgaHIgPSBJV2luZUQzRFZlcnRleFNoYWRlcl9TZXRGdW5jdGlvbigqcHBWZXJ0ZXhTaGFkZXIsIHBGdW5jdGlvbik7CgogICAgaWYgKFdJTkVEM0RfT0sgIT0gaHIpIHsKICAgICAgICBGSVhNRSgiKCVwKSA6IEZhaWxlZCB0byBzZXQgdGhlIGZ1bmN0aW9uLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIiwgaWZhY2UpOwogICAgICAgIElXaW5lRDNEVmVydGV4U2hhZGVyX1JlbGVhc2UoKnBwVmVydGV4U2hhZGVyKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVQaXhlbFNoYWRlcihJV2luZUQzRERldmljZSAqaWZhY2UsIENPTlNUIERXT1JEICpwRnVuY3Rpb24sIElXaW5lRDNEUGl4ZWxTaGFkZXIgKipwcFBpeGVsU2hhZGVyLCBJVW5rbm93biAqcGFyZW50KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqb2JqZWN0OyAvKiBOT1RFOiBpbXBsIGFsbG93ZWQsIHRoaXMgaXMgYSBjcmVhdGUgKi8KICAgIEhSRVNVTFQgaHIgPSBXSU5FRDNEX09LOwoKICAgIEQzRENSRUFURVNIQURFUk9CSkVDVElOU1RBTkNFKG9iamVjdCwgUGl4ZWxTaGFkZXIpCiAgICBvYmplY3QtPmJhc2VTaGFkZXIuc2hhZGVyX2lucyA9IElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsX3NoYWRlcl9pbnM7CiAgICBociA9IElXaW5lRDNEUGl4ZWxTaGFkZXJfU2V0RnVuY3Rpb24oKnBwUGl4ZWxTaGFkZXIsIHBGdW5jdGlvbik7CiAgICBpZiAoV0lORUQzRF9PSyA9PSBocikgewogICAgICAgIFRSQUNFKCIoJXApIDogQ3JlYXRlZCBQaXhlbCBzaGFkZXIgJXBcbiIsIFRoaXMsICpwcFBpeGVsU2hhZGVyKTsKICAgIH0gZWxzZSB7CiAgICAgICAgV0FSTigiKCVwKSA6IEZhaWxlZCB0byBjcmVhdGUgcGl4ZWwgc2hhZGVyXG4iLCBUaGlzKTsKICAgIH0KCiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlUGFsZXR0ZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIEZsYWdzLCBQQUxFVFRFRU5UUlkgKlBhbEVudCwgSVdpbmVEM0RQYWxldHRlICoqUGFsZXR0ZSwgSVVua25vd24gKlBhcmVudCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEUGFsZXR0ZUltcGwgKm9iamVjdDsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVwKS0+KCV4LCAlcCwgJXAsICVwKVxuIiwgVGhpcywgRmxhZ3MsIFBhbEVudCwgUGFsZXR0ZSwgUGFyZW50KTsKCiAgICAvKiBDcmVhdGUgdGhlIG5ldyBvYmplY3QgKi8KICAgIG9iamVjdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSVdpbmVEM0RQYWxldHRlSW1wbCkpOwogICAgaWYoIW9iamVjdCkgewogICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeSB3aGVuIGFsbG9jYXRpbmcgbWVtb3J5IGZvciBhIElXaW5lRDNEUGFsZXR0ZSBpbXBsZW1lbnRhdGlvblxuIik7CiAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICB9CgogICAgb2JqZWN0LT5scFZ0YmwgPSAmSVdpbmVEM0RQYWxldHRlX1Z0Ymw7CiAgICBvYmplY3QtPnJlZiA9IDE7CiAgICBvYmplY3QtPkZsYWdzID0gRmxhZ3M7CiAgICBvYmplY3QtPnBhcmVudCA9IFBhcmVudDsKICAgIG9iamVjdC0+d2luZUQzRERldmljZSA9IFRoaXM7CiAgICBvYmplY3QtPnBhbE51bUVudHJpZXMgPSBJV2luZUQzRFBhbGV0dGVJbXBsX1NpemUoRmxhZ3MpOwoJCiAgICBvYmplY3QtPmhwYWwgPSBDcmVhdGVQYWxldHRlKChjb25zdCBMT0dQQUxFVFRFKikmKG9iamVjdC0+cGFsVmVyc2lvbikpOwoKICAgIGlmKCFvYmplY3QtPmhwYWwpIHsKICAgICAgICBIZWFwRnJlZSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2JqZWN0KTsKICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgIH0KCiAgICBociA9IElXaW5lRDNEUGFsZXR0ZV9TZXRFbnRyaWVzKChJV2luZUQzRFBhbGV0dGUgKikgb2JqZWN0LCAwLCAwLCBJV2luZUQzRFBhbGV0dGVJbXBsX1NpemUoRmxhZ3MpLCBQYWxFbnQpOwogICAgaWYoRkFJTEVEKGhyKSkgewogICAgICAgIElXaW5lRDNEUGFsZXR0ZV9SZWxlYXNlKChJV2luZUQzRFBhbGV0dGUgKikgb2JqZWN0KTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgKlBhbGV0dGUgPSAoSVdpbmVEM0RQYWxldHRlICopIG9iamVjdDsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9Jbml0M0QoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEUFJFU0VOVF9QQVJBTUVURVJTKiBwUHJlc2VudGF0aW9uUGFyYW1ldGVycywgRDNEQ0JfQ1JFQVRFQURESVRJT05BTFNXQVBDSEFJTiBEM0RDQl9DcmVhdGVBZGRpdGlvbmFsU3dhcENoYWluKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICpzd2FwY2hhaW47CiAgICBEV09SRCBzdGF0ZTsKCiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwKVxuIiwgVGhpcywgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMsIEQzRENCX0NyZWF0ZUFkZGl0aW9uYWxTd2FwQ2hhaW4pOwogICAgaWYoVGhpcy0+ZDNkX2luaXRpYWxpemVkKSByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICAvKiBUT0RPOiBUZXN0IGlmIE9wZW5HTCBpcyBjb21waWxlZCBpbiBhbmQgbG9hZGVkICovCgogICAgLyogSW5pdGlhbGl6ZSB0aGUgdGV4dHVyZSB1bml0IG1hcHBpbmcgdG8gYSAxOjEgbWFwcGluZyAqLwogICAgZm9yKHN0YXRlID0gMDsgc3RhdGUgPCBNQVhfU0FNUExFUlM7IHN0YXRlKyspIHsKICAgICAgICBUaGlzLT50ZXhVbml0TWFwW3N0YXRlXSA9IHN0YXRlOwogICAgfQogICAgVGhpcy0+b25lVG9PbmVUZXhVbml0TWFwID0gVFJVRTsKCiAgICAvKiBTZXR1cCB0aGUgaW1wbGljaXQgc3dhcGNoYWluICovCiAgICBUUkFDRSgiQ3JlYXRpbmcgaW1wbGljaXQgc3dhcGNoYWluXG4iKTsKICAgIGlmIChGQUlMRUQoRDNEQ0JfQ3JlYXRlQWRkaXRpb25hbFN3YXBDaGFpbigoSVVua25vd24gKikgVGhpcy0+cGFyZW50LCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycywgKElXaW5lRDNEU3dhcENoYWluICoqKSZzd2FwY2hhaW4pKSB8fCAhc3dhcGNoYWluKSB7CiAgICAgICAgV0FSTigiRmFpbGVkIHRvIGNyZWF0ZSBpbXBsaWNpdCBzd2FwY2hhaW5cbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIFRoaXMtPk51bWJlck9mU3dhcENoYWlucyA9IDE7CiAgICBUaGlzLT5zd2FwY2hhaW5zID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPk51bWJlck9mU3dhcENoYWlucyAqIHNpemVvZihJV2luZUQzRFN3YXBDaGFpbiAqKSk7CiAgICBpZighVGhpcy0+c3dhcGNoYWlucykgewogICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeSFcbiIpOwogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2UoIChJV2luZUQzRFN3YXBDaGFpbiAqKSBzd2FwY2hhaW4pOwogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwogICAgfQogICAgVGhpcy0+c3dhcGNoYWluc1swXSA9IChJV2luZUQzRFN3YXBDaGFpbiAqKSBzd2FwY2hhaW47CgogICAgaWYoIVRoaXMtPmRkcmF3X3dpbmRvdykgSVdpbmVEM0REZXZpY2VfU2V0SFdORChpZmFjZSwgc3dhcGNoYWluLT53aW5faGFuZGxlKTsKCiAgICBpZihzd2FwY2hhaW4tPmJhY2tCdWZmZXIgJiYgc3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdKSB7CiAgICAgICAgVFJBQ0UoIlNldHRpbmcgcmVuZGVydGFyZ2V0IHRvICVwXG4iLCBzd2FwY2hhaW4tPmJhY2tCdWZmZXIpOwogICAgICAgIFRoaXMtPnJlbmRlcl90YXJnZXRzWzBdID0gc3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdOwogICAgICAgIFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQgPSBzd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF07CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBUUkFDRSgiU2V0dGluZyByZW5kZXJ0YXJnZXQgdG8gJXBcbiIsIHN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIpOwogICAgICAgIFRoaXMtPnJlbmRlcl90YXJnZXRzWzBdID0gc3dhcGNoYWluLT5mcm9udEJ1ZmZlcjsKICAgICAgICBUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0ID0gc3dhcGNoYWluLT5mcm9udEJ1ZmZlcjsKICAgIH0KICAgIElXaW5lRDNEU3VyZmFjZV9BZGRSZWYoVGhpcy0+cmVuZGVyX3RhcmdldHNbMF0pOwogICAgVGhpcy0+YWN0aXZlQ29udGV4dCA9IHN3YXBjaGFpbi0+Y29udGV4dFswXTsKCiAgICAvKiBEZXB0aCBTdGVuY2lsIHN1cHBvcnQgKi8KICAgIFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQgPSBUaGlzLT5kZXB0aFN0ZW5jaWxCdWZmZXI7CiAgICBpZiAod2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUgPT0gT1JNX0ZCTykgewogICAgICAgIHNldF9kZXB0aF9zdGVuY2lsX2ZibyhpZmFjZSwgVGhpcy0+ZGVwdGhTdGVuY2lsQnVmZmVyKTsKICAgIH0KICAgIGlmIChOVUxMICE9IFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQpIHsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfQWRkUmVmKFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQpOwogICAgfQoKICAgIC8qIFNldCB1cCBzb21lIHN0YXJ0aW5nIEdMIHNldHVwICovCiAgICBFTlRFUl9HTCgpOwogICAgLyoKICAgICogSW5pdGlhbGl6ZSBvcGVuR0wgZXh0ZW5zaW9uIHJlbGF0ZWQgdmFyaWFibGVzCiAgICAqICB3aXRoIERlZmF1bHQgdmFsdWVzCiAgICAqLwoKICAgICgoSVdpbmVEM0RJbXBsICopIFRoaXMtPndpbmVEM0QpLT5pc0dMSW5mb1ZhbGlkID0gSVdpbmVEM0RJbXBsX0ZpbGxHTENhcHMoVGhpcy0+d2luZUQzRCwgc3dhcGNoYWluLT5jb250ZXh0WzBdLT5kaXNwbGF5KTsKICAgIC8qIFNldHVwIGFsbCB0aGUgZGV2aWNlcyBkZWZhdWx0cyAqLwogICAgSVdpbmVEM0RTdGF0ZUJsb2NrX0luaXRTdGFydHVwU3RhdGVCbG9jaygoSVdpbmVEM0RTdGF0ZUJsb2NrICopVGhpcy0+c3RhdGVCbG9jayk7CiNpZiAwCiAgICBJV2luZUQzREltcGxfQ2hlY2tHcmFwaGljc01lbW9yeSgpOwojZW5kaWYKCiAgICB7IC8qIFNldCBhIGRlZmF1bHQgdmlld3BvcnQgKi8KICAgICAgICBXSU5FRDNEVklFV1BPUlQgdnA7CiAgICAgICAgdnAuWCAgICAgID0gMDsKICAgICAgICB2cC5ZICAgICAgPSAwOwogICAgICAgIHZwLldpZHRoICA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGg7CiAgICAgICAgdnAuSGVpZ2h0ID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQ7CiAgICAgICAgdnAuTWluWiAgID0gMC4wZjsKICAgICAgICB2cC5NYXhaICAgPSAxLjBmOwogICAgICAgIElXaW5lRDNERGV2aWNlX1NldFZpZXdwb3J0KChJV2luZUQzRERldmljZSAqKVRoaXMsICZ2cCk7CiAgICB9CgogICAgLyogSW5pdGlhbGl6ZSB0aGUgY3VycmVudCB2aWV3IHN0YXRlICovCiAgICBUaGlzLT52aWV3X2lkZW50ID0gMTsKICAgIFRoaXMtPmNvbnRleHRzWzBdLT5sYXN0X3dhc19yaHcgPSAwOwogICAgZ2xHZXRJbnRlZ2VydihHTF9NQVhfTElHSFRTLCAmVGhpcy0+bWF4Q29uY3VycmVudExpZ2h0cyk7CiAgICBjaGVja0dMY2FsbCgiZ2xHZXRJbnRlZ2VydihHTF9NQVhfTElHSFRTLCAmVGhpcy0+bWF4Q29uY3VycmVudExpZ2h0cykiKTsKCiAgICBzd2l0Y2god2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUpIHsKICAgICAgICBjYXNlIE9STV9GQk86CiAgICAgICAgY2FzZSBPUk1fUEJVRkZFUjoKICAgICAgICAgICAgVGhpcy0+b2Zmc2NyZWVuQnVmZmVyID0gR0xfQkFDSzsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgT1JNX0JBQ0tCVUZGRVI6CiAgICAgICAgewogICAgICAgICAgICBpZihHTF9MSU1JVFMoYXV4X2J1ZmZlcnMpID4gMCkgewogICAgICAgICAgICAgICAgVFJBQ0UoIlVzaW5nIGF1eGlsbGlhcnkgYnVmZmVyIGZvciBvZmZzY3JlZW4gcmVuZGVyaW5nXG4iKTsKICAgICAgICAgICAgICAgIFRoaXMtPm9mZnNjcmVlbkJ1ZmZlciA9IEdMX0FVWDA7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBUUkFDRSgiVXNpbmcgYmFjayBidWZmZXIgZm9yIG9mZnNjcmVlbiByZW5kZXJpbmdcbiIpOwogICAgICAgICAgICAgICAgVGhpcy0+b2Zmc2NyZWVuQnVmZmVyID0gR0xfQkFDSzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBUUkFDRSgiKCVwKSBBbGwgZGVmYXVsdHMgbm93IHNldCB1cCwgbGVhdmluZyBJbml0M0Qgd2l0aCAlcFxuIiwgVGhpcywgVGhpcyk7CiAgICBMRUFWRV9HTCgpOwoKICAgIC8qIENsZWFyIHRoZSBzY3JlZW4gKi8KICAgIElXaW5lRDNERGV2aWNlX0NsZWFyKChJV2luZUQzRERldmljZSAqKSBUaGlzLCAwLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RDTEVBUl9UQVJHRVQgfCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+RW5hYmxlQXV0b0RlcHRoU3RlbmNpbCA/IFdJTkVEM0RDTEVBUl9aQlVGRkVSIHwgV0lORUQzRENMRUFSX1NURU5DSUwgOiAwLAogICAgICAgICAgICAgICAgICAgICAgICAgIDB4MDAsIDEuMCwgMCk7CgogICAgVGhpcy0+ZDNkX2luaXRpYWxpemVkID0gVFJVRTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1VuaW5pdDNEKElXaW5lRDNERGV2aWNlICppZmFjZSwgRDNEQ0JfREVTVFJPWVNVUkZBQ0VGTiBEM0RDQl9EZXN0cm95RGVwdGhTdGVuY2lsU3VyZmFjZSwgRDNEQ0JfREVTVFJPWVNXQVBDSEFJTkZOIEQzRENCX0Rlc3Ryb3lTd2FwQ2hhaW4pIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBpbnQgc2FtcGxlcjsKICAgIHVpbnQgaTsKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICBpZighVGhpcy0+ZDNkX2luaXRpYWxpemVkKSByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICBFTlRFUl9HTCgpOwogICAgLyogSSBkb24ndCB0aGluayB0aGF0IHRoZSBpbnRlcmZhY2UgZ3VhcmFudHMgdGhhdCB0aGUgZGV2aWNlIGlzIGRlc3Ryb3llZCBmcm9tIHRoZSBzYW1lIHRocmVhZAogICAgICogaXQgd2FzIGNyZWF0ZWQuIFRodXMgbWFrZSBzdXJlIGEgY29udGV4dCBpcyBhY3RpdmUgZm9yIHRoZSBnbERlbGV0ZSogY2FsbHMKICAgICAqLwogICAgQWN0aXZhdGVDb250ZXh0KFRoaXMsIFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQsIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CiAgICBMRUFWRV9HTCgpOwoKICAgIC8qIERlbGV0ZSB0aGUgcGJ1ZmZlciBjb250ZXh0IGlmIHRoZXJlIGlzIGFueSAqLwogICAgaWYoVGhpcy0+cGJ1ZmZlckNvbnRleHQpIERlc3Ryb3lDb250ZXh0KFRoaXMsIFRoaXMtPnBidWZmZXJDb250ZXh0KTsKCiAgICAvKiBEZWxldGUgdGhlIG1vdXNlIGN1cnNvciB0ZXh0dXJlICovCiAgICBpZihUaGlzLT5jdXJzb3JUZXh0dXJlKSB7CiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICBnbERlbGV0ZVRleHR1cmVzKDEsICZUaGlzLT5jdXJzb3JUZXh0dXJlKTsKICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgIFRoaXMtPmN1cnNvclRleHR1cmUgPSAwOwogICAgfQoKICAgIGZvcihzYW1wbGVyID0gMDsgc2FtcGxlciA8IEdMX0xJTUlUUyhzYW1wbGVyX3N0YWdlcyk7ICsrc2FtcGxlcikgewogICAgICAgIElXaW5lRDNERGV2aWNlX1NldFRleHR1cmUoaWZhY2UsIHNhbXBsZXIsIE5VTEwpOwogICAgfQoKICAgIC8qIFJlbGVhc2UgdGhlIGJ1ZmZlcnMgKHdpdGggc2FuaXR5IGNoZWNrcykqLwogICAgVFJBQ0UoIlJlbGVhc2luZyB0aGUgZGVwdGggc3RlbmNpbCBidWZmZXIgYXQgJXBcbiIsIFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQpOwogICAgaWYoVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCAhPSBOVUxMICYmIChJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KSA+MCkpewogICAgICAgIGlmKFRoaXMtPmRlcHRoU3RlbmNpbEJ1ZmZlciAhPSBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KQogICAgICAgICAgICBGSVhNRSgiKCVwKSBTb21ldGhpbmcncyBzdGlsbCBob2xkaW5nIHRoZSBkZXB0aFN0ZW5jaWxCdWZmZXJcbiIsVGhpcyk7CiAgICB9CiAgICBUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0ID0gTlVMTDsKCiAgICBUUkFDRSgiUmVsZWFzaW5nIHRoZSByZW5kZXIgdGFyZ2V0IGF0ICVwXG4iLCBUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXSk7CiAgICBpZihJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXSkgPjApewogICAgICAgICAgLyogVGhpcyBjaGVjayBpcyBhIGJpdCBzaWxseSwgaXRzaG91bGQgYmUgaW4gc3dhcGNoYWluX3JlbGVhc2UgRklYTUUoIiglcCkgU29tZXRoaW5nJ3Mgc3RpbGwgaG9sZGluZyB0aGUgcmVuZGVyVGFyZ2V0XG4iLFRoaXMpOyAqLwogICAgfQogICAgVFJBQ0UoIlNldHRpbmcgcmVuZGVydGFyZ2V0IHRvIE5VTExcbiIpOwogICAgVGhpcy0+cmVuZGVyX3RhcmdldHNbMF0gPSBOVUxMOwoKICAgIGlmIChUaGlzLT5kZXB0aFN0ZW5jaWxCdWZmZXIpIHsKICAgICAgICBpZihEM0RDQl9EZXN0cm95RGVwdGhTdGVuY2lsU3VyZmFjZShUaGlzLT5kZXB0aFN0ZW5jaWxCdWZmZXIpID4gMCkgewogICAgICAgICAgICBGSVhNRSgiKCVwKSBTb21ldGhpbmcncyBzdGlsbCBob2xkaW5nIHRoZSBkZXB0aFN0ZW5jaWxCdWZmZXJcbiIsIFRoaXMpOwogICAgICAgIH0KICAgICAgICBUaGlzLT5kZXB0aFN0ZW5jaWxCdWZmZXIgPSBOVUxMOwogICAgfQoKICAgIGZvcihpPTA7IGkgPCBUaGlzLT5OdW1iZXJPZlN3YXBDaGFpbnM7IGkrKykgewogICAgICAgIFRSQUNFKCJSZWxlYXNpbmcgdGhlIGltcGxpY2l0IHN3YXBjaGFpbiAlZFxuIiwgaSk7CiAgICAgICAgaWYgKEQzRENCX0Rlc3Ryb3lTd2FwQ2hhaW4oVGhpcy0+c3dhcGNoYWluc1tpXSkgID4gMCkgewogICAgICAgICAgICBGSVhNRSgiKCVwKSBTb21ldGhpbmcncyBzdGlsbCBob2xkaW5nIHRoZSBpbXBsaWNpdCBzd2FwY2hhaW5cbiIsIFRoaXMpOwogICAgICAgIH0KICAgIH0KCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5zd2FwY2hhaW5zKTsKICAgIFRoaXMtPnN3YXBjaGFpbnMgPSBOVUxMOwogICAgVGhpcy0+TnVtYmVyT2ZTd2FwQ2hhaW5zID0gMDsKCiAgICBUaGlzLT5kM2RfaW5pdGlhbGl6ZWQgPSBGQUxTRTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgdm9pZCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldEZ1bGxzY3JlZW4oSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBCT09MIGZ1bGxzY3JlZW4pIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBUUkFDRSgiKCVwKSBTZXR0aW5nIEREcmF3IGZ1bGxzY3JlZW4gbW9kZSB0byAlc1xuIiwgVGhpcywgZnVsbHNjcmVlbiA/ICJ0cnVlIiA6ICJmYWxzZSIpOwoKICAgIC8qIFNldHVwIHRoZSB3aW5kb3cgZm9yIGZ1bGxzY3JlZW4gbW9kZSAqLwogICAgaWYoZnVsbHNjcmVlbiAmJiAhVGhpcy0+ZGRyYXdfZnVsbHNjcmVlbikgewogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXR1cEZ1bGxzY3JlZW5XaW5kb3coaWZhY2UsIFRoaXMtPmRkcmF3X3dpbmRvdyk7CiAgICB9IGVsc2UgaWYoIWZ1bGxzY3JlZW4gJiYgVGhpcy0+ZGRyYXdfZnVsbHNjcmVlbikgewogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9SZXN0b3JlV2luZG93KGlmYWNlLCBUaGlzLT5kZHJhd193aW5kb3cpOwogICAgfQoKICAgIC8qIERpcmVjdERyYXcgYXBwcyBjYW4gY2hhbmdlIGJldHdlZW4gZnVsbHNjcmVlbiBhbmQgd2luZG93ZWQgbW9kZSBhZnRlciBkZXZpY2UgY3JlYXRpb24gd2l0aAogICAgICogSURpcmVjdERyYXc3OjpTZXRDb29wZXJhdGl2ZUxldmVsLiBUaGUgR0RJIHN1cmZhY2UgaW1wbGVtZW50YXRpb24gbmVlZHMgdG8ga25vdyB0aGlzLgogICAgICogRERyYXcgZG9lc24ndCBuZWNlc3NhcmlseSBoYXZlIGEgc3dhcGNoYWluLCBzbyB3ZSBoYXZlIHRvIHN0b3JlIHRoZSBmdWxsc2NyZWVuIGZsYWcKICAgICAqIHNlcGFyYXRlbHkuCiAgICAgKi8KICAgIFRoaXMtPmRkcmF3X2Z1bGxzY3JlZW4gPSBmdWxsc2NyZWVuOwp9CgovKiBFbmFibGVzIHRoZWFkIHNhZmV0eSBpbiB0aGUgd2luZWQzZCBkZXZpY2UgYW5kIGl0cyByZXNvdXJjZXMuIENhbGxlZCBieSBEaXJlY3REcmF3CiAqIGZyb20gU2V0Q29vcGVyYXRpdmVMZXZlbiBpZiBERFNDTF9NVUxUSVRIUkVBREVEIGlzIHNwZWNpZmllZCwgYW5kIGJ5IGQzZDgvOSBmcm9tCiAqIENyZWF0ZURldmljZSBpZiBEM0RDUkVBVEVfTVVMVElUSFJFQURFRCBpcyBwYXNzZWQuCiAqCiAqIFRoZXJlIGlzIG5vIHdheSB0byBkZWFjdGl2YXRlIHRocmVhZCBzYWZldHkgb25jZSBpdCBpcyBlbmFibGVkCiAqLwpzdGF0aWMgdm9pZCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldE11bHRpdGhyZWFkZWQoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgRklYTUUoIk5vIHRocmVhZCBzYWZldHkgaW4gd2luZWQzZCB5ZXRcbiIpOwoKICAgIC8qRm9yIG5vdyBqdXN0IHN0b3JlIHRoZSBmbGFnKG5lZWRlZCBpbiBjYXNlIG9mIGRkcmF3KSAqLwogICAgVGhpcy0+Y3JlYXRlUGFybXMuQmVoYXZpb3JGbGFncyB8PSBXSU5FRDNEQ1JFQVRFX01VTFRJVEhSRUFERUQ7CgogICAgcmV0dXJuOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldERpc3BsYXlNb2RlKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBpU3dhcENoYWluLCBXSU5FRDNERElTUExBWU1PREUqIHBNb2RlKSB7CiAgICBERVZNT0RFVyBkZXZtb2RlOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgTE9ORyByZXQ7CiAgICBjb25zdCBQaXhlbEZvcm1hdERlc2MgKmZvcm1hdERlc2MgID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KHBNb2RlLT5Gb3JtYXQpOwogICAgUkVDVCBjbGlwX3JjOwoKICAgIFRSQUNFKCIoJXApLT4oJWQsJXApIE1vZGU9JWR4JWR4QCVkLCAlc1xuIiwgVGhpcywgaVN3YXBDaGFpbiwgcE1vZGUsIHBNb2RlLT5XaWR0aCwgcE1vZGUtPkhlaWdodCwgcE1vZGUtPlJlZnJlc2hSYXRlLCBkZWJ1Z19kM2Rmb3JtYXQocE1vZGUtPkZvcm1hdCkpOwoKICAgIC8qIFJlc2l6ZSB0aGUgc2NyZWVuIGV2ZW4gd2l0aG91dCBhIHdpbmRvdzoKICAgICAqIFRoZSBhcHAgY291bGQgaGF2ZSB1bnNldCBpdCB3aXRoIFNldENvb3BlcmF0aXZlTGV2ZWwsIGJ1dCBub3QgY2FsbGVkCiAgICAgKiBSZXN0b3JlRGlzcGxheU1vZGUgZmlyc3QuIFRoZW4gdGhlIHJlbGVhc2Ugd2lsbCBjYWxsIFJlc3RvcmVEaXNwbGF5TW9kZSwKICAgICAqIGJ1dCB3ZSBkb24ndCBoYXZlIGFueSBod25kCiAgICAgKi8KCiAgICBkZXZtb2RlLmRtRmllbGRzID0gRE1fQklUU1BFUlBFTCB8IERNX1BFTFNXSURUSCB8IERNX1BFTFNIRUlHSFQ7CiAgICBkZXZtb2RlLmRtQml0c1BlclBlbCA9IGZvcm1hdERlc2MtPmJwcCAqIDg7CiAgICBpZihkZXZtb2RlLmRtQml0c1BlclBlbCA9PSAyNCkgZGV2bW9kZS5kbUJpdHNQZXJQZWwgPSAzMjsKICAgIGRldm1vZGUuZG1QZWxzV2lkdGggID0gcE1vZGUtPldpZHRoOwogICAgZGV2bW9kZS5kbVBlbHNIZWlnaHQgPSBwTW9kZS0+SGVpZ2h0OwoKICAgIGRldm1vZGUuZG1EaXNwbGF5RnJlcXVlbmN5ID0gcE1vZGUtPlJlZnJlc2hSYXRlOwogICAgaWYgKHBNb2RlLT5SZWZyZXNoUmF0ZSAhPSAwKSAgewogICAgICAgIGRldm1vZGUuZG1GaWVsZHMgfD0gRE1fRElTUExBWUZSRVFVRU5DWTsKICAgIH0KCiAgICAvKiBPbmx5IGNoYW5nZSB0aGUgbW9kZSBpZiBuZWNlc3NhcnkgKi8KICAgIGlmKCAoVGhpcy0+ZGRyYXdfd2lkdGggPT0gcE1vZGUtPldpZHRoKSAmJgogICAgICAgIChUaGlzLT5kZHJhd19oZWlnaHQgPT0gcE1vZGUtPkhlaWdodCkgJiYKICAgICAgICAoVGhpcy0+ZGRyYXdfZm9ybWF0ID09IHBNb2RlLT5Gb3JtYXQpICYmCiAgICAgICAgKHBNb2RlLT5SZWZyZXNoUmF0ZSA9PSAwKSApIHsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICByZXQgPSBDaGFuZ2VEaXNwbGF5U2V0dGluZ3NFeFcoTlVMTCwgJmRldm1vZGUsIE5VTEwsIENEU19GVUxMU0NSRUVOLCBOVUxMKTsKICAgIGlmIChyZXQgIT0gRElTUF9DSEFOR0VfU1VDQ0VTU0ZVTCkgewogICAgICAgIGlmKGRldm1vZGUuZG1EaXNwbGF5RnJlcXVlbmN5ICE9IDApIHsKICAgICAgICAgICAgV0FSTigiQ2hhbmdlRGlzcGxheVNldHRpbmdzRXhXIGZhaWxlZCwgdHJ5aW5nIHdpdGhvdXQgdGhlIHJlZnJlc2ggcmF0ZVxuIik7CiAgICAgICAgICAgIGRldm1vZGUuZG1GaWVsZHMgJj0gfkRNX0RJU1BMQVlGUkVRVUVOQ1k7CiAgICAgICAgICAgIGRldm1vZGUuZG1EaXNwbGF5RnJlcXVlbmN5ID0gMDsKICAgICAgICAgICAgcmV0ID0gQ2hhbmdlRGlzcGxheVNldHRpbmdzRXhXKE5VTEwsICZkZXZtb2RlLCBOVUxMLCBDRFNfRlVMTFNDUkVFTiwgTlVMTCkgIT0gRElTUF9DSEFOR0VfU1VDQ0VTU0ZVTDsKICAgICAgICB9CiAgICAgICAgaWYocmV0ICE9IERJU1BfQ0hBTkdFX1NVQ0NFU1NGVUwpIHsKICAgICAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURNT0RFOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBTdG9yZSB0aGUgbmV3IHZhbHVlcyAqLwogICAgVGhpcy0+ZGRyYXdfd2lkdGggPSBwTW9kZS0+V2lkdGg7CiAgICBUaGlzLT5kZHJhd19oZWlnaHQgPSBwTW9kZS0+SGVpZ2h0OwogICAgVGhpcy0+ZGRyYXdfZm9ybWF0ID0gcE1vZGUtPkZvcm1hdDsKCiAgICAvKiBPbmx5IGRvIHRoaXMgd2l0aCBhIHdpbmRvdyBvZiBjb3Vyc2UgKi8KICAgIGlmKFRoaXMtPmRkcmF3X3dpbmRvdykKICAgICAgTW92ZVdpbmRvdyhUaGlzLT5kZHJhd193aW5kb3csIDAsIDAsIHBNb2RlLT5XaWR0aCwgcE1vZGUtPkhlaWdodCwgVFJVRSk7CgogICAgLyogQW5kIGZpbmFsbHkgY2xpcCBtb3VzZSB0byBvdXIgc2NyZWVuICovCiAgICBTZXRSZWN0KCZjbGlwX3JjLCAwLCAwLCBwTW9kZS0+V2lkdGgsIHBNb2RlLT5IZWlnaHQpOwogICAgQ2xpcEN1cnNvcigmY2xpcF9yYyk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0RGlyZWN0M0QoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRCAqKnBwRDNEKSB7CiAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgKnBwRDNEPSBUaGlzLT53aW5lRDNEOwogICBUUkFDRSgiKCVwKSA6IHdpbmVEM0QgcmV0dXJuaW5nICVwXG4iLCBUaGlzLCAgKnBwRDNEKTsKICAgSVdpbmVEM0RfQWRkUmVmKCpwcEQzRCk7CiAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgVUlOVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldEF2YWlsYWJsZVRleHR1cmVNZW0oSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICAvKiogTk9URTogVGhlcmUncyBhIHByb2JhYmx5ICBhIGhhY2stYXJvdW5kIGZvciB0aGlzIG9uZSBieSBwdXR0aW5nIGFzIG1hbnkgcGJ1ZmZlcnMsIFZCT3MgKG9yIHdoYXRldmVyKQogICAgKiBpbnRvIHRoZSB2aWRlbyByYW0gYXMgcG9zc2libGUgYW5kIHNlZWluZyBob3cgbWFueSBmaXQKICAgICogeW91IGNhbiBhbHNvIGdldCB0aGUgY29ycmVjdCBpbml0aWFsIHZhbHVlIGZyb20gbnZpZGlhIGFuZCBBVEkncyBkcml2ZXIgdmlhIFgKICAgICogdGV4dHVyZSBtZW1vcnkgaXMgdmlkZW8gbWVtb3J5ICsgQUdQIG1lbW9yeQogICAgKioqKioqKioqKioqKioqKioqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIHN0YXRpYyBCT09MIHNob3dmaXhtZXMgPSBUUlVFOwogICAgaWYgKHNob3dmaXhtZXMpIHsKICAgICAgICBGSVhNRSgiKCVwKSA6IHN0dWIsIHNpbXVsYXRpbmcgJWRNQiBmb3Igbm93LCByZXR1cm5pbmcgJWRNQiBsZWZ0XG4iLCBUaGlzLAogICAgICAgICAod2luZWQzZF9zZXR0aW5ncy5lbXVsYXRlZF90ZXh0dXJlcmFtLygxMDI0KjEwMjQpKSwKICAgICAgICAgKCh3aW5lZDNkX3NldHRpbmdzLmVtdWxhdGVkX3RleHR1cmVyYW0gLSB3aW5lRDNER2xvYmFsU3RhdGlzdGljcy0+Z2xzdXJmYWNlcmFtKSAvICgxMDI0KjEwMjQpKSk7CiAgICAgICAgIHNob3dmaXhtZXMgPSBGQUxTRTsKICAgIH0KICAgIFRSQUNFKCIoJXApIDogc2ltdWxhdGluZyAlZE1CLCByZXR1cm5pbmcgJWRNQiBsZWZ0XG4iLCAgVGhpcywKICAgICAgICAgKHdpbmVkM2Rfc2V0dGluZ3MuZW11bGF0ZWRfdGV4dHVyZXJhbS8oMTAyNCoxMDI0KSksCiAgICAgICAgICgod2luZWQzZF9zZXR0aW5ncy5lbXVsYXRlZF90ZXh0dXJlcmFtIC0gd2luZUQzREdsb2JhbFN0YXRpc3RpY3MtPmdsc3VyZmFjZXJhbSkgLyAoMTAyNCoxMDI0KSkpOwogICAgLyogcmV0dXJuIHNpbXVsYXRlZCB0ZXh0dXJlIG1lbW9yeSBsZWZ0ICovCiAgICByZXR1cm4gKHdpbmVkM2Rfc2V0dGluZ3MuZW11bGF0ZWRfdGV4dHVyZXJhbSAtIHdpbmVEM0RHbG9iYWxTdGF0aXN0aWNzLT5nbHN1cmZhY2VyYW0pOwp9CgoKCi8qKioqKgogKiBHZXQgLyBTZXQgRlZGCiAqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRGVkYoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBmdmYpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICAvKiBVcGRhdGUgdGhlIGN1cnJlbnQgc3RhdGUgYmxvY2sgKi8KICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQuZnZmICAgICAgPSBUUlVFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0LmZ2ZiAgICAgICAgICA9IFRSVUU7CgogICAgaWYoVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+ZnZmID09IGZ2ZikgewogICAgICAgIFRSQUNFKCJBcHBsaWNhdGlvbiBpcyBzZXR0aW5nIHRoZSBvbGQgZnZmIG92ZXIsIG5vdGhpbmcgdG8gZG9cbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmZ2ZiAgICAgICAgICAgICAgPSBmdmY7CiAgICBUUkFDRSgiKCVwKSA6IEZWRiBTaGFkZXIgRlZGIHNldCB0byAleFxuIiwgVGhpcywgZnZmKTsKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9WREVDTCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0RlZGKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgKnBmdmYpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogR2V0RlZGIHJldHVybmluZyAleFxuIiwgVGhpcywgVGhpcy0+c3RhdGVCbG9jay0+ZnZmKTsKICAgICpwZnZmID0gVGhpcy0+c3RhdGVCbG9jay0+ZnZmOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBHZXQgLyBTZXQgU3RyZWFtIFNvdXJjZQogKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0U3RyZWFtU291cmNlKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBTdHJlYW1OdW1iZXIsSVdpbmVEM0RWZXJ0ZXhCdWZmZXIqIHBTdHJlYW1EYXRhLCBVSU5UIE9mZnNldEluQnl0ZXMsIFVJTlQgU3RyaWRlKSB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsICAgICAgICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RWZXJ0ZXhCdWZmZXIgICAgICpvbGRTcmM7CgogICAgaWYgKFN0cmVhbU51bWJlciA+PSBNQVhfU1RSRUFNUykgewogICAgICAgIFdBUk4oIlN0cmVhbSBvdXQgb2YgcmFuZ2UgJWRcbiIsIFN0cmVhbU51bWJlcik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgb2xkU3JjID0gVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlW1N0cmVhbU51bWJlcl07CiAgICBUUkFDRSgiKCVwKSA6IFN0cmVhbU5vOiAlZCwgT2xkU3RyZWFtICglcCksIE5ld1N0cmVhbSAoJXApLCBOZXdTdHJpZGUgJWRcbiIsIFRoaXMsIFN0cmVhbU51bWJlciwgb2xkU3JjLCBwU3RyZWFtRGF0YSwgU3RyaWRlKTsKCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnN0cmVhbVNvdXJjZVtTdHJlYW1OdW1iZXJdID0gVFJVRTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnNldC5zdHJlYW1Tb3VyY2VbU3RyZWFtTnVtYmVyXSAgICAgPSBUUlVFOwoKICAgIGlmKG9sZFNyYyA9PSBwU3RyZWFtRGF0YSAmJgogICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c3RyZWFtU3RyaWRlW1N0cmVhbU51bWJlcl0gPT0gU3RyaWRlICYmCiAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1PZmZzZXRbU3RyZWFtTnVtYmVyXSA9PSBPZmZzZXRJbkJ5dGVzKSB7CiAgICAgICBUUkFDRSgiQXBwbGljYXRpb24gaXMgc2V0dGluZyB0aGUgb2xkIHZhbHVlcyBvdmVyLCBub3RoaW5nIHRvIGRvXG4iKTsKICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtTdHJlYW1OdW1iZXJdICAgICAgICAgPSBwU3RyZWFtRGF0YTsKICAgIGlmIChwU3RyZWFtRGF0YSkgewogICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbVN0cmlkZVtTdHJlYW1OdW1iZXJdICAgICA9IFN0cmlkZTsKICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1PZmZzZXRbU3RyZWFtTnVtYmVyXSAgICAgPSBPZmZzZXRJbkJ5dGVzOwogICAgfQoKICAgIC8qIEhhbmRsZSByZWNvcmRpbmcgb2Ygc3RhdGUgYmxvY2tzICovCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIC8qIE5lZWQgdG8gZG8gYSBnZXRQYXJlbnQgYW5kIHBhc3MgdGhlIHJlZmZzIHVwICovCiAgICAvKiBNU0ROIHNheXMgLi4uLi4gV2hlbiBhbiBhcHBsaWNhdGlvbiBubyBsb25nZXIgaG9sZHMgYSByZWZlcmVuY2VzIHRvIHRoaXMgaW50ZXJmYWNlLCB0aGUgaW50ZXJmYWNlIHdpbGwgYXV0b21hdGljYWxseSBiZSBmcmVlZC4KICAgIHdoaWNoIHN1Z2dlc3RzIHRoYXQgd2Ugc2hvdWxkbid0IGJlIHJlZiBjb3VudGluZz8gYW5kIGRvIG5lZWQgYSBfcmVsZWFzZSBvbiB0aGUgc3RyZWFtIHNvdXJjZSB0byByZXNldCB0aGUgc3RyZWFtIHNvdXJjZQogICAgc28gZm9yIG5vdywganVzdCBjb3VudCBpbnRlcm5hbGx5ICAgKi8KICAgIGlmIChwU3RyZWFtRGF0YSAhPSBOVUxMKSB7CiAgICAgICAgSVdpbmVEM0RWZXJ0ZXhCdWZmZXJJbXBsICp2YkltcGwgPSAoSVdpbmVEM0RWZXJ0ZXhCdWZmZXJJbXBsICopIHBTdHJlYW1EYXRhOwogICAgICAgIEludGVybG9ja2VkSW5jcmVtZW50KCZ2YkltcGwtPmJpbmRDb3VudCk7CiAgICB9CiAgICBpZiAob2xkU3JjICE9IE5VTEwpIHsKICAgICAgICBJbnRlcmxvY2tlZERlY3JlbWVudCgmKChJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKikgb2xkU3JjKS0+YmluZENvdW50KTsKICAgIH0KCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfU1RSRUFNU1JDKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTdHJlYW1Tb3VyY2UoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIFN0cmVhbU51bWJlcixJV2luZUQzRFZlcnRleEJ1ZmZlcioqIHBTdHJlYW0sIFVJTlQgKnBPZmZzZXQsIFVJTlQqIHBTdHJpZGUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKSA6IFN0cmVhbU5vOiAlZCwgU3RyZWFtICglcCksIFN0cmlkZSAlZFxuIiwgVGhpcywgU3RyZWFtTnVtYmVyLAogICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtTdHJlYW1OdW1iZXJdLCBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1TdHJpZGVbU3RyZWFtTnVtYmVyXSk7CgogICAgaWYgKFN0cmVhbU51bWJlciA+PSBNQVhfU1RSRUFNUykgewogICAgICAgIFdBUk4oIlN0cmVhbSBvdXQgb2YgcmFuZ2UgJWRcbiIsIFN0cmVhbU51bWJlcik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICAqcFN0cmVhbSA9IFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtTdHJlYW1OdW1iZXJdOwogICAgKnBTdHJpZGUgPSBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1TdHJpZGVbU3RyZWFtTnVtYmVyXTsKICAgIGlmIChwT2Zmc2V0KSB7CiAgICAgICAgKnBPZmZzZXQgPSBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1PZmZzZXRbU3RyZWFtTnVtYmVyXTsKICAgIH0KCiAgICBpZiAoKnBTdHJlYW0gIT0gTlVMTCkgewogICAgICAgIElXaW5lRDNEVmVydGV4QnVmZmVyX0FkZFJlZigqcFN0cmVhbSk7IC8qIFdlIGhhdmUgY3JlYXRlZCBhIG5ldyByZWZlcmVuY2UgdG8gdGhlIFZCICovCiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRTdHJlYW1Tb3VyY2VGcmVxKElXaW5lRDNERGV2aWNlICppZmFjZSwgIFVJTlQgU3RyZWFtTnVtYmVyLCBVSU5UIERpdmlkZXIpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFVJTlQgb2xkRmxhZ3MgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1GbGFnc1tTdHJlYW1OdW1iZXJdOwogICAgVUlOVCBvbGRGcmVxID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c3RyZWFtRnJlcVtTdHJlYW1OdW1iZXJdOwoKICAgIFRSQUNFKCIoJXApIFN0cmVhbU51bWJlciglZCksIERpdmlkZXIoJWQpXG4iLCBUaGlzLCBTdHJlYW1OdW1iZXIsIERpdmlkZXIpOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c3RyZWFtRmxhZ3NbU3RyZWFtTnVtYmVyXSA9IERpdmlkZXIgJiAoV0lORUQzRFNUUkVBTVNPVVJDRV9JTlNUQU5DRURBVEEgIHwgV0lORUQzRFNUUkVBTVNPVVJDRV9JTkRFWEVEREFUQSApOwoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQuc3RyZWFtRnJlcVtTdHJlYW1OdW1iZXJdICA9IFRSVUU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQuc3RyZWFtRnJlcVtTdHJlYW1OdW1iZXJdICAgICAgPSBUUlVFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c3RyZWFtRnJlcVtTdHJlYW1OdW1iZXJdICAgICAgICAgID0gRGl2aWRlciAmIDB4N0ZGRkZGOwoKICAgIGlmKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbUZyZXFbU3RyZWFtTnVtYmVyXSAhPSBvbGRGcmVxIHx8CiAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1GbGFnc1tTdHJlYW1OdW1iZXJdICE9IG9sZEZsYWdzKSB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1NUUkVBTVNSQyk7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0U3RyZWFtU291cmNlRnJlcShJV2luZUQzRERldmljZSAqaWZhY2UsICBVSU5UIFN0cmVhbU51bWJlciwgVUlOVCogRGl2aWRlcikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXApIFN0cmVhbU51bWJlciglZCksIERpdmlkZXIoJXApXG4iLCBUaGlzLCBTdHJlYW1OdW1iZXIsIERpdmlkZXIpOwogICAgKkRpdmlkZXIgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1GcmVxW1N0cmVhbU51bWJlcl0gfCBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1GbGFnc1tTdHJlYW1OdW1iZXJdOwoKICAgIFRSQUNFKCIoJXApIDogcmV0dXJuaW5nICVkXG4iLCBUaGlzLCAqRGl2aWRlcik7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBHZXQgLyBTZXQgJiBNdWx0aXBseSBUcmFuc2Zvcm0KICoqKioqLwpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfU2V0VHJhbnNmb3JtKElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRFRSQU5TRk9STVNUQVRFVFlQRSBkM2R0cywgQ09OU1QgV0lORUQzRE1BVFJJWCogbHBtYXRyaXgpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICAvKiBNb3N0IG9mIHRoaXMgcm91dGluZSwgY29tbWVudHMgaW5jbHVkZWQgY29waWVkIGZyb20gZGRyYXcgdHJlZSBpbml0aWFsbHk6ICovCiAgICBUUkFDRSgiKCVwKSA6IFRyYW5zZm9ybSBTdGF0ZT0lc1xuIiwgVGhpcywgZGVidWdfZDNkdHN0eXBlKGQzZHRzKSk7CgogICAgLyogSGFuZGxlIHJlY29yZGluZyBvZiBzdGF0ZSBibG9ja3MgKi8KICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC50cmFuc2Zvcm1bZDNkdHNdID0gVFJVRTsKICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQudHJhbnNmb3JtW2QzZHRzXSAgICAgPSBUUlVFOwogICAgICAgIG1lbWNweSgmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dHJhbnNmb3Jtc1tkM2R0c10sIGxwbWF0cml4LCBzaXplb2YoV0lORUQzRE1BVFJJWCkpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIC8qCiAgICAgKiBJZiB0aGUgbmV3IG1hdHJpeCBpcyB0aGUgc2FtZSBhcyB0aGUgY3VycmVudCBvbmUsCiAgICAgKiB3ZSBjdXQgb2ZmIGFueSBmdXJ0aGVyIHByb2Nlc3NpbmcuIHRoaXMgc2VlbXMgdG8gYmUgYSByZWFzb25hYmxlCiAgICAgKiBvcHRpbWl6YXRpb24gYmVjYXVzZSBhcyB3YXMgbm90aWNlZCwgc29tZSBhcHBzICh3YXJjcmFmdDMgZm9yIGV4YW1wbGUpCiAgICAgKiB0ZW5kIHRvd2FyZHMgc2V0dGluZyB0aGUgc2FtZSBtYXRyaXggcmVwZWF0ZWRseSBmb3Igc29tZSByZWFzb24uCiAgICAgKgogICAgICogRnJvbSBoZXJlIG9uIHdlIGFzc3VtZSB0aGF0IHRoZSBuZXcgbWF0cml4IGlzIGRpZmZlcmVudCwgd2hlcmV2ZXIgaXQgbWF0dGVycy4KICAgICAqLwogICAgaWYgKCFtZW1jbXAoJlRoaXMtPnN0YXRlQmxvY2stPnRyYW5zZm9ybXNbZDNkdHNdLnUubVswXVswXSwgbHBtYXRyaXgsIHNpemVvZihXSU5FRDNETUFUUklYKSkpIHsKICAgICAgICBUUkFDRSgiVGhlIGFwcCBpcyBzZXR0aW5nIHRoZSBzYW1lIG1hdHJpeCBvdmVyIGFnYWluXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0gZWxzZSB7CiAgICAgICAgY29udl9tYXQobHBtYXRyaXgsICZUaGlzLT5zdGF0ZUJsb2NrLT50cmFuc2Zvcm1zW2QzZHRzXS51Lm1bMF1bMF0pOwogICAgfQoKICAgIC8qCiAgICAgICBTY3JlZW5Db29yZCA9IFByb2plY3Rpb25NYXQgKiBWaWV3TWF0ICogV29ybGRNYXQgKiBPYmplY3RDb29yZAogICAgICAgd2hlcmUgVmlld01hdCA9IENhbWVyYSBzcGFjZSwgV29ybGRNYXQgPSB3b3JsZCBzcGFjZS4KCiAgICAgICBJbiBPcGVuR0wsIGNhbWVyYSBhbmQgd29ybGQgc3BhY2UgaXMgY29tYmluZWQgaW50byBHTF9NT0RFTFZJRVcKICAgICAgIG1hdHJpeC4gIFRoZSBQcm9qZWN0aW9uIG1hdHJpeCBzdGF5IHByb2plY3Rpb24gbWF0cml4LgogICAgICovCgogICAgLyogQ2FwdHVyZSB0aGUgdGltZXMgd2UgY2FuIGp1c3QgaWdub3JlIHRoZSBjaGFuZ2UgZm9yIG5vdyAqLwogICAgaWYgKGQzZHRzID09IFdJTkVEM0RUU19WSUVXKSB7IC8qIGhhbmRsZSB0aGUgVklFVyBtYXRyaWNlICovCiAgICAgICAgVGhpcy0+dmlld19pZGVudCA9ICFtZW1jbXAobHBtYXRyaXgsIGlkZW50aXR5LCAxNiAqIHNpemVvZihmbG9hdCkpOwogICAgICAgIC8qIEhhbmRsZWQgYnkgdGhlIHN0YXRlIG1hbmFnZXIgKi8KICAgIH0KCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVFJBTlNGT1JNKGQzZHRzKSk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKCn0Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRUcmFuc2Zvcm0oSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEVFJBTlNGT1JNU1RBVEVUWVBFIFN0YXRlLCBXSU5FRDNETUFUUklYKiBwTWF0cml4KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSA6IGZvciBUcmFuc2Zvcm0gU3RhdGUgJXNcbiIsIFRoaXMsIGRlYnVnX2QzZHRzdHlwZShTdGF0ZSkpOwogICAgbWVtY3B5KHBNYXRyaXgsICZUaGlzLT5zdGF0ZUJsb2NrLT50cmFuc2Zvcm1zW1N0YXRlXSwgc2l6ZW9mKFdJTkVEM0RNQVRSSVgpKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX011bHRpcGx5VHJhbnNmb3JtKElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRFRSQU5TRk9STVNUQVRFVFlQRSBTdGF0ZSwgQ09OU1QgV0lORUQzRE1BVFJJWCogcE1hdHJpeCkgewogICAgV0lORUQzRE1BVFJJWCAqbWF0ID0gTlVMTDsKICAgIFdJTkVEM0RNQVRSSVggdGVtcDsKCiAgICAvKiBOb3RlOiBVc2luZyAndXBkYXRlU3RhdGVCbG9jaycgcmF0aGVyIHRoYW4gJ3N0YXRlYmxvY2snIGluIHRoZSBjb2RlCiAgICAgKiBiZWxvdyBtZWFucyBpdCB3aWxsIGJlIHJlY29yZGVkIGluIGEgc3RhdGUgYmxvY2sgY2hhbmdlLCBidXQgaXQKICAgICAqIHdvcmtzIHJlZ2FyZGxlc3Mgd2hlcmUgaXQgaXMgcmVjb3JkZWQuCiAgICAgKiBJZiB0aGlzIGlzIGZvdW5kIHRvIGJlIHdyb25nLCBjaGFuZ2UgdG8gU3RhdGVCbG9jay4KICAgICAqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiBGb3Igc3RhdGUgJXNcbiIsIFRoaXMsIGRlYnVnX2QzZHRzdHlwZShTdGF0ZSkpOwoKICAgIGlmIChTdGF0ZSA8IEhJR0hFU1RfVFJBTlNGT1JNU1RBVEUpCiAgICB7CiAgICAgICAgbWF0ID0gJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRyYW5zZm9ybXNbU3RhdGVdOwogICAgfSBlbHNlIHsKICAgICAgICBGSVhNRSgiVW5oYW5kbGVkIHRyYW5zZm9ybSBzdGF0ZSEhXG4iKTsKICAgIH0KCiAgICBtdWx0aXBseV9tYXRyaXgoJnRlbXAsIG1hdCwgKGNvbnN0IFdJTkVEM0RNQVRSSVggKikgcE1hdHJpeCk7CgogICAgLyogQXBwbHkgY2hhbmdlIHZpYSBzZXQgdHJhbnNmb3JtIC0gd2lsbCByZWFwcGx5IHRvIGVnLiBsaWdodHMgdGhpcyB3YXkgKi8KICAgIHJldHVybiBJV2luZUQzRERldmljZUltcGxfU2V0VHJhbnNmb3JtKGlmYWNlLCBTdGF0ZSwgJnRlbXApOwp9CgovKioqKioKICogR2V0IC8gU2V0IExpZ2h0CiAqKioqKi8KLyogTm90ZSBsaWdodHMgYXJlIHJlYWwgc3BlY2lhbCBjYXNlcy4gQWx0aG91Z2ggdGhlIGRldmljZSBjYXBzIHN0YXRlIG9ubHkgZWcuIDggYXJlIHN1cHBvcnRlZCwKICAgeW91IGNhbiByZWZlcmVuY2UgYW55IGluZGV4ZXMgeW91IHdhbnQgYXMgbG9uZyBhcyB0aGF0IG51bWJlciBtYXggYXJlIGVuYWJsZWQgYXQgYW55CiAgIG9uZSBwb2ludCBpbiB0aW1lISBUaGVyZWZvcmUgc2luY2UgdGhlIGluZGV4ZXMgY2FuIGJlIGFueXRoaW5nLCB3ZSBuZWVkIGEgaGFzaG1hcCBvZiB0aGVtLgogICBIb3dldmVyLCB0aGlzIGNhdXNlcyBzdGF0ZWJsb2NrIHByb2JsZW1zLiBXaGVuIGNhcHR1cmluZyB0aGUgc3RhdGUgYmxvY2ssIEkgZHVwbGljYXRlIHRoZSBoYXNobWFwLAogICBidXQgd2hlbiByZWNvcmRpbmcsIGp1c3QgYnVpbGQgYSBjaGFpbiBwcmV0dHkgbXVjaCBvZiBjb21tYW5kcyB0byBiZSByZXBsYXllZC4gICAgICAgICAgICAgICAgICAqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRMaWdodChJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIEluZGV4LCBDT05TVCBXSU5FRDNETElHSFQqIHBMaWdodCkgewogICAgZmxvYXQgcmhvOwogICAgUExJR0hUSU5GT0VMICpvYmplY3QgPSBOVUxMOwogICAgVUlOVCBIaSA9IExJR0hUTUFQX0hBU0hGVU5DKEluZGV4KTsKICAgIHN0cnVjdCBsaXN0ICplOwoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogSWR4KCVkKSwgcExpZ2h0KCVwKS4gSGFzaCBpbmRleCBpcyAlZFxuIiwgVGhpcywgSW5kZXgsIHBMaWdodCwgSGkpOwoKICAgIC8qIENoZWNrIHRoZSBwYXJhbWV0ZXIgcmFuZ2UuIE5lZWQgZm9yIHNwZWVkIG1vc3Qgd2FudGVkIHNldHMganVuayBsaWdodHMgd2hpY2ggY29uZnVzZQogICAgICogdGhlIGdsIGRyaXZlci4KICAgICAqLwogICAgaWYoIXBMaWdodCkgewogICAgICAgIFdBUk4oIkxpZ2h0IHBvaW50ZXIgPSBOVUxMLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgc3dpdGNoKHBMaWdodC0+VHlwZSkgewogICAgICAgIGNhc2UgV0lORUQzRExJR0hUX1BPSU5UOgogICAgICAgIGNhc2UgV0lORUQzRExJR0hUX1NQT1Q6CiAgICAgICAgY2FzZSBXSU5FRDNETElHSFRfUEFSQUxMRUxQT0lOVDoKICAgICAgICBjYXNlIFdJTkVEM0RMSUdIVF9HTFNQT1Q6CiAgICAgICAgICAgIC8qIEluY29ycmVjdCBhdHRlbnVhdGlvbiB2YWx1ZXMgY2FuIGNhdXNlIHRoZSBnbCBkcml2ZXIgdG8gY3Jhc2guIEhhcHBlbnMgd2l0aCBOZWVkIGZvciBzcGVlZAogICAgICAgICAgICAgKiBtb3N0IHdhbnRlZAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYocExpZ2h0LT5BdHRlbnVhdGlvbjAgPCAwLjAgfHwgcExpZ2h0LT5BdHRlbnVhdGlvbjEgPCAwLjAgfHwgcExpZ2h0LT5BdHRlbnVhdGlvbjIgPCAwLjApIHsKICAgICAgICAgICAgICAgIFdBUk4oIkF0dGVudWF0aW9uIGlzIG5lZ2F0aXZlLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNETElHSFRfRElSRUNUSU9OQUw6CiAgICAgICAgICAgIC8qIElnbm9yZXMgYXR0ZW51YXRpb24gKi8KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgV0FSTigiTGlnaHQgdHlwZSBvdXQgb2YgcmFuZ2UsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBMSVNUX0ZPUl9FQUNIKGUsICZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5saWdodE1hcFtIaV0pIHsKICAgICAgICBvYmplY3QgPSBMSVNUX0VOVFJZKGUsIFBMSUdIVElORk9FTCwgZW50cnkpOwogICAgICAgIGlmKG9iamVjdC0+T3JpZ2luYWxJbmRleCA9PSBJbmRleCkgYnJlYWs7CiAgICAgICAgb2JqZWN0ID0gTlVMTDsKICAgIH0KCiAgICBpZighb2JqZWN0KSB7CiAgICAgICAgVFJBQ0UoIkFkZGluZyBuZXcgbGlnaHRcbiIpOwogICAgICAgIG9iamVjdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoKm9iamVjdCkpOwogICAgICAgIGlmKCFvYmplY3QpIHsKICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5IGVycm9yIHdoZW4gYWxsb2NhdGluZyBhIGxpZ2h0XG4iKTsKICAgICAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICAgICAgfQogICAgICAgIGxpc3RfYWRkX2hlYWQoJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmxpZ2h0TWFwW0hpXSwgJm9iamVjdC0+ZW50cnkpOwogICAgICAgIG9iamVjdC0+Z2xJbmRleCA9IC0xOwogICAgICAgIG9iamVjdC0+T3JpZ2luYWxJbmRleCA9IEluZGV4OwogICAgICAgIG9iamVjdC0+Y2hhbmdlZCA9IFRSVUU7CiAgICB9CgogICAgLyogSW5pdGlhbGl6ZSB0aGUgb2JqZWN0ICovCiAgICBUUkFDRSgiTGlnaHQgJWQgc2V0dGluZyB0byB0eXBlICVkLCBEaWZmdXNlKCVmLCVmLCVmLCVmKSwgU3BlY3VsYXIoJWYsJWYsJWYsJWYpLCBBbWJpZW50KCVmLCVmLCVmLCVmKVxuIiwgSW5kZXgsIHBMaWdodC0+VHlwZSwKICAgICAgICAgIHBMaWdodC0+RGlmZnVzZS5yLCBwTGlnaHQtPkRpZmZ1c2UuZywgcExpZ2h0LT5EaWZmdXNlLmIsIHBMaWdodC0+RGlmZnVzZS5hLAogICAgICAgICAgcExpZ2h0LT5TcGVjdWxhci5yLCBwTGlnaHQtPlNwZWN1bGFyLmcsIHBMaWdodC0+U3BlY3VsYXIuYiwgcExpZ2h0LT5TcGVjdWxhci5hLAogICAgICAgICAgcExpZ2h0LT5BbWJpZW50LnIsIHBMaWdodC0+QW1iaWVudC5nLCBwTGlnaHQtPkFtYmllbnQuYiwgcExpZ2h0LT5BbWJpZW50LmEpOwogICAgVFJBQ0UoIi4uLiBQb3MoJWYsJWYsJWYpLCBEaXJuKCVmLCVmLCVmKVxuIiwgcExpZ2h0LT5Qb3NpdGlvbi54LCBwTGlnaHQtPlBvc2l0aW9uLnksIHBMaWdodC0+UG9zaXRpb24ueiwKICAgICAgICAgIHBMaWdodC0+RGlyZWN0aW9uLngsIHBMaWdodC0+RGlyZWN0aW9uLnksIHBMaWdodC0+RGlyZWN0aW9uLnopOwogICAgVFJBQ0UoIi4uLiBSYW5nZSglZiksIEZhbGxvZmYoJWYpLCBUaGV0YSglZiksIFBoaSglZilcbiIsIHBMaWdodC0+UmFuZ2UsIHBMaWdodC0+RmFsbG9mZiwgcExpZ2h0LT5UaGV0YSwgcExpZ2h0LT5QaGkpOwoKICAgIC8qIFNhdmUgYXdheSB0aGUgaW5mb3JtYXRpb24gKi8KICAgIG1lbWNweSgmb2JqZWN0LT5PcmlnaW5hbFBhcm1zLCBwTGlnaHQsIHNpemVvZihXSU5FRDNETElHSFQpKTsKCiAgICBzd2l0Y2ggKHBMaWdodC0+VHlwZSkgewogICAgY2FzZSBXSU5FRDNETElHSFRfUE9JTlQ6CiAgICAgICAgLyogUG9zaXRpb24gKi8KICAgICAgICBvYmplY3QtPmxpZ2h0UG9zblswXSA9IHBMaWdodC0+UG9zaXRpb24ueDsKICAgICAgICBvYmplY3QtPmxpZ2h0UG9zblsxXSA9IHBMaWdodC0+UG9zaXRpb24ueTsKICAgICAgICBvYmplY3QtPmxpZ2h0UG9zblsyXSA9IHBMaWdodC0+UG9zaXRpb24uejsKICAgICAgICBvYmplY3QtPmxpZ2h0UG9zblszXSA9IDEuMGY7CiAgICAgICAgb2JqZWN0LT5jdXRvZmYgPSAxODAuMGY7CiAgICAgICAgLyogRklYTUU6IFJhbmdlICovCiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBXSU5FRDNETElHSFRfRElSRUNUSU9OQUw6CiAgICAgICAgLyogRGlyZWN0aW9uICovCiAgICAgICAgb2JqZWN0LT5saWdodFBvc25bMF0gPSAtcExpZ2h0LT5EaXJlY3Rpb24ueDsKICAgICAgICBvYmplY3QtPmxpZ2h0UG9zblsxXSA9IC1wTGlnaHQtPkRpcmVjdGlvbi55OwogICAgICAgIG9iamVjdC0+bGlnaHRQb3NuWzJdID0gLXBMaWdodC0+RGlyZWN0aW9uLno7CiAgICAgICAgb2JqZWN0LT5saWdodFBvc25bM10gPSAwLjA7CiAgICAgICAgb2JqZWN0LT5leHBvbmVudCAgICAgPSAwLjBmOwogICAgICAgIG9iamVjdC0+Y3V0b2ZmICAgICAgID0gMTgwLjBmOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgV0lORUQzRExJR0hUX1NQT1Q6CiAgICAgICAgLyogUG9zaXRpb24gKi8KICAgICAgICBvYmplY3QtPmxpZ2h0UG9zblswXSA9IHBMaWdodC0+UG9zaXRpb24ueDsKICAgICAgICBvYmplY3QtPmxpZ2h0UG9zblsxXSA9IHBMaWdodC0+UG9zaXRpb24ueTsKICAgICAgICBvYmplY3QtPmxpZ2h0UG9zblsyXSA9IHBMaWdodC0+UG9zaXRpb24uejsKICAgICAgICBvYmplY3QtPmxpZ2h0UG9zblszXSA9IDEuMDsKCiAgICAgICAgLyogRGlyZWN0aW9uICovCiAgICAgICAgb2JqZWN0LT5saWdodERpcm5bMF0gPSBwTGlnaHQtPkRpcmVjdGlvbi54OwogICAgICAgIG9iamVjdC0+bGlnaHREaXJuWzFdID0gcExpZ2h0LT5EaXJlY3Rpb24ueTsKICAgICAgICBvYmplY3QtPmxpZ2h0RGlyblsyXSA9IHBMaWdodC0+RGlyZWN0aW9uLno7CiAgICAgICAgb2JqZWN0LT5saWdodERpcm5bM10gPSAxLjA7CgogICAgICAgIC8qCiAgICAgICAgICogb3BlbmdsLWlzaCBhbmQgZDNkLWlzaCBzcG90IGxpZ2h0cyB1c2UgdG9vIGRpZmZlcmVudCBtb2RlbHMgZm9yIHRoZQogICAgICAgICAqIGxpZ2h0ICJpbnRlbnNpdHkiIGFzIGEgZnVuY3Rpb24gb2YgdGhlIGFuZ2xlIHRvd2FyZHMgdGhlIG1haW4gbGlnaHQgZGlyZWN0aW9uLAogICAgICAgICAqIHNvIHdlIG9ubHkgY2FuIGFwcHJveGltYXRlIHZlcnkgcm91Z2hseS4KICAgICAgICAgKiBob3dldmVyIHNwb3QgbGlnaHRzIGFyZSByYXRoZXIgcmFyZWx5IHVzZWQgaW4gZ2FtZXMgKGlmIGV2ZXIgdXNlZCBhdCBhbGwpLgogICAgICAgICAqIGZ1cnRoZXJtb3JlIGlmIHN0aWxsIHVzZWQsIHByb2JhYmx5IG5vYm9keSBwYXlzIGF0dGVudGlvbiB0byBzdWNoIGRldGFpbHMuCiAgICAgICAgICovCiAgICAgICAgaWYgKHBMaWdodC0+RmFsbG9mZiA9PSAwKSB7CiAgICAgICAgICAgIHJobyA9IDYuMjhmOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJobyA9IHBMaWdodC0+VGhldGEgKyAocExpZ2h0LT5QaGkgLSBwTGlnaHQtPlRoZXRhKS8oMipwTGlnaHQtPkZhbGxvZmYpOwogICAgICAgIH0KICAgICAgICBpZiAocmhvIDwgMC4wMDAxKSByaG8gPSAwLjAwMDFmOwogICAgICAgIG9iamVjdC0+ZXhwb25lbnQgPSAtMC4zL2xvZyhjb3MocmhvLzIpKTsKCWlmIChvYmplY3QtPmV4cG9uZW50ID4gMTI4LjApIHsKCQlvYmplY3QtPmV4cG9uZW50ID0gMTI4LjA7Cgl9CiAgICAgICAgb2JqZWN0LT5jdXRvZmYgPSBwTGlnaHQtPlBoaSo5MC9NX1BJOwoKICAgICAgICAvKiBGSVhNRTogUmFuZ2UgKi8KICAgICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICAgIEZJWE1FKCJVbnJlY29nbml6ZWQgbGlnaHQgdHlwZSAlZFxuIiwgcExpZ2h0LT5UeXBlKTsKICAgIH0KCiAgICAvKiBVcGRhdGUgdGhlIGxpdmUgZGVmaW5pdGlvbnMgaWYgdGhlIGxpZ2h0IGlzIGN1cnJlbnRseSBhc3NpZ25lZCBhIGdsSW5kZXggKi8KICAgIGlmIChvYmplY3QtPmdsSW5kZXggIT0gLTEgJiYgIVRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfQUNUSVZFTElHSFQob2JqZWN0LT5nbEluZGV4KSk7CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRMaWdodChJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIEluZGV4LCBXSU5FRDNETElHSFQqIHBMaWdodCkgewogICAgUExJR0hUSU5GT0VMICpsaWdodEluZm8gPSBOVUxMOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgRFdPUkQgSGkgPSBMSUdIVE1BUF9IQVNIRlVOQyhJbmRleCk7CiAgICBzdHJ1Y3QgbGlzdCAqZTsKICAgIFRSQUNFKCIoJXApIDogSWR4KCVkKSwgcExpZ2h0KCVwKVxuIiwgVGhpcywgSW5kZXgsIHBMaWdodCk7CgogICAgTElTVF9GT1JfRUFDSChlLCAmVGhpcy0+c3RhdGVCbG9jay0+bGlnaHRNYXBbSGldKSB7CiAgICAgICAgbGlnaHRJbmZvID0gTElTVF9FTlRSWShlLCBQTElHSFRJTkZPRUwsIGVudHJ5KTsKICAgICAgICBpZihsaWdodEluZm8tPk9yaWdpbmFsSW5kZXggPT0gSW5kZXgpIGJyZWFrOwogICAgICAgIGxpZ2h0SW5mbyA9IE5VTEw7CiAgICB9CgogICAgaWYgKGxpZ2h0SW5mbyA9PSBOVUxMKSB7CiAgICAgICAgVFJBQ0UoIkxpZ2h0IGluZm9ybWF0aW9uIHJlcXVlc3RlZCBidXQgbGlnaHQgbm90IGRlZmluZWRcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIG1lbWNweShwTGlnaHQsICZsaWdodEluZm8tPk9yaWdpbmFsUGFybXMsIHNpemVvZihXSU5FRDNETElHSFQpKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogR2V0IC8gU2V0IExpZ2h0IEVuYWJsZQogKiAgIChOb3RlIGZvciBjb25zaXN0ZW5jeSwgcmVuYW1lZCBkM2R4IGZ1bmN0aW9uIGJ5IGFkZGluZyB0aGUgJ3NldCcgcHJlZml4KQogKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0TGlnaHRFbmFibGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBJbmRleCwgQk9PTCBFbmFibGUpIHsKICAgIFBMSUdIVElORk9FTCAqbGlnaHRJbmZvID0gTlVMTDsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFVJTlQgSGkgPSBMSUdIVE1BUF9IQVNIRlVOQyhJbmRleCk7CiAgICBzdHJ1Y3QgbGlzdCAqZTsKICAgIFRSQUNFKCIoJXApIDogSWR4KCVkKSwgZW5hYmxlPyAlZFxuIiwgVGhpcywgSW5kZXgsIEVuYWJsZSk7CgogICAgLyogVGVzdHMgc2hvdyB0cnVlID0gMTI4Li4ubm90IGNsZWFyIHdoeSAqLwogICAgRW5hYmxlID0gRW5hYmxlPyAxMjg6IDA7CgogICAgTElTVF9GT1JfRUFDSChlLCAmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+bGlnaHRNYXBbSGldKSB7CiAgICAgICAgbGlnaHRJbmZvID0gTElTVF9FTlRSWShlLCBQTElHSFRJTkZPRUwsIGVudHJ5KTsKICAgICAgICBpZihsaWdodEluZm8tPk9yaWdpbmFsSW5kZXggPT0gSW5kZXgpIGJyZWFrOwogICAgICAgIGxpZ2h0SW5mbyA9IE5VTEw7CiAgICB9CiAgICBUUkFDRSgiRm91bmQgbGlnaHQ6ICVwXG4iLCBsaWdodEluZm8pOwoKICAgIC8qIFNwZWNpYWwgY2FzZSAtIGVuYWJsaW5nIGFuIHVuZGVmaW5lZCBsaWdodCBjcmVhdGVzIG9uZSB3aXRoIGEgc3RyaWN0IHNldCBvZiBwYXJtcyEgKi8KICAgIGlmIChsaWdodEluZm8gPT0gTlVMTCkgewoKICAgICAgICBUUkFDRSgiTGlnaHQgZW5hYmxlZCByZXF1ZXN0ZWQgYnV0IGxpZ2h0IG5vdCBkZWZpbmVkLCBzbyBkZWZpbmluZyBvbmUhXG4iKTsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfU2V0TGlnaHQoaWZhY2UsIEluZGV4LCAmV0lORUQzRF9kZWZhdWx0X2xpZ2h0KTsKCiAgICAgICAgLyogU2VhcmNoIGZvciBpdCBhZ2FpbiEgU2hvdWxkIGJlIGZhaXJseSBxdWljayBhcyBuZWFyIGhlYWQgb2YgbGlzdCAqLwogICAgICAgIExJU1RfRk9SX0VBQ0goZSwgJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmxpZ2h0TWFwW0hpXSkgewogICAgICAgICAgICBsaWdodEluZm8gPSBMSVNUX0VOVFJZKGUsIFBMSUdIVElORk9FTCwgZW50cnkpOwogICAgICAgICAgICBpZihsaWdodEluZm8tPk9yaWdpbmFsSW5kZXggPT0gSW5kZXgpIGJyZWFrOwogICAgICAgICAgICBsaWdodEluZm8gPSBOVUxMOwogICAgICAgIH0KICAgICAgICBpZiAobGlnaHRJbmZvID09IE5VTEwpIHsKICAgICAgICAgICAgRklYTUUoIkFkZGluZyBkZWZhdWx0IGxpZ2h0cyBoYXMgZmFpbGVkIGRpc21hbGx5XG4iKTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfQogICAgfQoKICAgIGxpZ2h0SW5mby0+ZW5hYmxlZENoYW5nZWQgPSBUUlVFOwogICAgaWYoIUVuYWJsZSkgewogICAgICAgIGlmKGxpZ2h0SW5mby0+Z2xJbmRleCAhPSAtMSkgewogICAgICAgICAgICBpZighVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX0FDVElWRUxJR0hUKGxpZ2h0SW5mby0+Z2xJbmRleCkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5hY3RpdmVMaWdodHNbbGlnaHRJbmZvLT5nbEluZGV4XSA9IE5VTEw7CiAgICAgICAgICAgIGxpZ2h0SW5mby0+Z2xJbmRleCA9IC0xOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFRSQUNFKCJMaWdodCBhbHJlYWR5IGRpc2FibGVkLCBub3RoaW5nIHRvIGRvXG4iKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIGlmIChsaWdodEluZm8tPmdsSW5kZXggIT0gLTEpIHsKICAgICAgICAgICAgLyogbm9wICovCiAgICAgICAgICAgIFRSQUNFKCJOb3RoaW5nIHRvIGRvIGFzIGxpZ2h0IHdhcyBlbmFibGVkXG4iKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpbnQgaTsKICAgICAgICAgICAgLyogRmluZCBhIGZyZWUgZ2wgbGlnaHQgKi8KICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDwgVGhpcy0+bWF4Q29uY3VycmVudExpZ2h0czsgaSsrKSB7CiAgICAgICAgICAgICAgICBpZihUaGlzLT5zdGF0ZUJsb2NrLT5hY3RpdmVMaWdodHNbaV0gPT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPmFjdGl2ZUxpZ2h0c1tpXSA9IGxpZ2h0SW5mbzsKICAgICAgICAgICAgICAgICAgICBsaWdodEluZm8tPmdsSW5kZXggPSBpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKGxpZ2h0SW5mby0+Z2xJbmRleCA9PSAtMSkgewogICAgICAgICAgICAgICAgRVJSKCJUb28gbWFueSBjb25jdXJyZW50bHkgYWN0aXZlIGxpZ2h0c1xuIik7CiAgICAgICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogaSA9PSBsaWdodEluZm8tPmdsSW5kZXggKi8KICAgICAgICAgICAgaWYoIVRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9BQ1RJVkVMSUdIVChpKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0TGlnaHRFbmFibGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBJbmRleCxCT09MKiBwRW5hYmxlKSB7CgogICAgUExJR0hUSU5GT0VMICpsaWdodEluZm8gPSBOVUxMOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgc3RydWN0IGxpc3QgKmU7CiAgICBVSU5UIEhpID0gTElHSFRNQVBfSEFTSEZVTkMoSW5kZXgpOwogICAgVFJBQ0UoIiglcCkgOiBmb3IgaWR4KCVkKVxuIiwgVGhpcywgSW5kZXgpOwoKICAgIExJU1RfRk9SX0VBQ0goZSwgJlRoaXMtPnN0YXRlQmxvY2stPmxpZ2h0TWFwW0hpXSkgewogICAgICAgIGxpZ2h0SW5mbyA9IExJU1RfRU5UUlkoZSwgUExJR0hUSU5GT0VMLCBlbnRyeSk7CiAgICAgICAgaWYobGlnaHRJbmZvLT5PcmlnaW5hbEluZGV4ID09IEluZGV4KSBicmVhazsKICAgICAgICBsaWdodEluZm8gPSBOVUxMOwogICAgfQoKICAgIGlmIChsaWdodEluZm8gPT0gTlVMTCkgewogICAgICAgIFRSQUNFKCJMaWdodCBlbmFibGVkIHN0YXRlIHJlcXVlc3RlZCBidXQgbGlnaHQgbm90IGRlZmluZWRcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgLyogdHJ1ZSBpcyAxMjggYWNjb3JkaW5nIHRvIFNldExpZ2h0RW5hYmxlICovCiAgICAqcEVuYWJsZSA9IGxpZ2h0SW5mby0+Z2xJbmRleCAhPSAtMSA/IDEyOCA6IDA7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBDbGlwIFBsYW5lcwogKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0Q2xpcFBsYW5lKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgSW5kZXgsIENPTlNUIGZsb2F0ICpwUGxhbmUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogZm9yIGlkeCAlZCwgJXBcbiIsIFRoaXMsIEluZGV4LCBwUGxhbmUpOwoKICAgIC8qIFZhbGlkYXRlIEluZGV4ICovCiAgICBpZiAoSW5kZXggPj0gR0xfTElNSVRTKGNsaXBwbGFuZXMpKSB7CiAgICAgICAgVFJBQ0UoIkFwcGxpY2F0aW9uIGhhcyByZXF1ZXN0ZWQgY2xpcHBsYW5lIHRoaXMgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydFxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC5jbGlwcGxhbmVbSW5kZXhdID0gVFJVRTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnNldC5jbGlwcGxhbmVbSW5kZXhdID0gVFJVRTsKCiAgICBpZihUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jbGlwcGxhbmVbSW5kZXhdWzBdID09IHBQbGFuZVswXSAmJgogICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2xpcHBsYW5lW0luZGV4XVsxXSA9PSBwUGxhbmVbMV0gJiYKICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNsaXBwbGFuZVtJbmRleF1bMl0gPT0gcFBsYW5lWzJdICYmCiAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jbGlwcGxhbmVbSW5kZXhdWzNdID09IHBQbGFuZVszXSkgewogICAgICAgIFRSQUNFKCJBcHBsaWNhdGlvbiBpcyBzZXR0aW5nIG9sZCB2YWx1ZXMgb3Zlciwgbm90aGluZyB0byBkb1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2xpcHBsYW5lW0luZGV4XVswXSA9IHBQbGFuZVswXTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNsaXBwbGFuZVtJbmRleF1bMV0gPSBwUGxhbmVbMV07CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jbGlwcGxhbmVbSW5kZXhdWzJdID0gcFBsYW5lWzJdOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2xpcHBsYW5lW0luZGV4XVszXSA9IHBQbGFuZVszXTsKCiAgICAvKiBIYW5kbGUgcmVjb3JkaW5nIG9mIHN0YXRlIGJsb2NrcyAqLwogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfQ0xJUFBMQU5FKEluZGV4KSk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0Q2xpcFBsYW5lKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgSW5kZXgsIGZsb2F0ICpwUGxhbmUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogZm9yIGlkeCAlZFxuIiwgVGhpcywgSW5kZXgpOwoKICAgIC8qIFZhbGlkYXRlIEluZGV4ICovCiAgICBpZiAoSW5kZXggPj0gR0xfTElNSVRTKGNsaXBwbGFuZXMpKSB7CiAgICAgICAgVFJBQ0UoIkFwcGxpY2F0aW9uIGhhcyByZXF1ZXN0ZWQgY2xpcHBsYW5lIHRoaXMgZGV2aWNlIGRvZXNuJ3Qgc3VwcG9ydFxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgcFBsYW5lWzBdID0gVGhpcy0+c3RhdGVCbG9jay0+Y2xpcHBsYW5lW0luZGV4XVswXTsKICAgIHBQbGFuZVsxXSA9IFRoaXMtPnN0YXRlQmxvY2stPmNsaXBwbGFuZVtJbmRleF1bMV07CiAgICBwUGxhbmVbMl0gPSBUaGlzLT5zdGF0ZUJsb2NrLT5jbGlwcGxhbmVbSW5kZXhdWzJdOwogICAgcFBsYW5lWzNdID0gVGhpcy0+c3RhdGVCbG9jay0+Y2xpcHBsYW5lW0luZGV4XVszXTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogR2V0IC8gU2V0IENsaXAgUGxhbmUgU3RhdHVzCiAqICAgV0FSTklORzogVGhpcyBjb2RlIHJlbGllcyBvbiB0aGUgZmFjdCB0aGF0IEQzRENMSVBTVEFUVVM4ID09IEQzRENMSVBTVEFUVVM5CiAqKioqKi8Kc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX1NldENsaXBTdGF0dXMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBDT05TVCBXSU5FRDNEQ0xJUFNUQVRVUyogcENsaXBTdGF0dXMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIEZJWE1FKCIoJXApIDogc3R1YlxuIiwgVGhpcyk7CiAgICBpZiAoTlVMTCA9PSBwQ2xpcFN0YXR1cykgewogICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNsaXBfc3RhdHVzLkNsaXBVbmlvbiA9IHBDbGlwU3RhdHVzLT5DbGlwVW5pb247CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jbGlwX3N0YXR1cy5DbGlwSW50ZXJzZWN0aW9uID0gcENsaXBTdGF0dXMtPkNsaXBJbnRlcnNlY3Rpb247CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0dldENsaXBTdGF0dXMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEQ0xJUFNUQVRVUyogcENsaXBTdGF0dXMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIEZJWE1FKCIoJXApIDogc3R1YlxuIiwgVGhpcyk7CiAgICBpZiAoTlVMTCA9PSBwQ2xpcFN0YXR1cykgewogICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIHBDbGlwU3RhdHVzLT5DbGlwVW5pb24gPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jbGlwX3N0YXR1cy5DbGlwVW5pb247CiAgICBwQ2xpcFN0YXR1cy0+Q2xpcEludGVyc2VjdGlvbiA9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNsaXBfc3RhdHVzLkNsaXBJbnRlcnNlY3Rpb247CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBNYXRlcmlhbAogKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0TWF0ZXJpYWwoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBDT05TVCBXSU5FRDNETUFURVJJQUwqIHBNYXRlcmlhbCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQubWF0ZXJpYWwgPSBUUlVFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0Lm1hdGVyaWFsID0gVFJVRTsKICAgIG1lbWNweSgmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+bWF0ZXJpYWwsIHBNYXRlcmlhbCwgc2l6ZW9mKFdJTkVEM0RNQVRFUklBTCkpOwoKICAgIC8qIEhhbmRsZSByZWNvcmRpbmcgb2Ygc3RhdGUgYmxvY2tzICovCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIEVOVEVSX0dMKCk7CiAgICBUUkFDRSgiKCVwKSA6IERpZmZ1c2UgKCVmLCVmLCVmLCVmKVxuIiwgVGhpcywgcE1hdGVyaWFsLT5EaWZmdXNlLnIsIHBNYXRlcmlhbC0+RGlmZnVzZS5nLAogICAgICAgIHBNYXRlcmlhbC0+RGlmZnVzZS5iLCBwTWF0ZXJpYWwtPkRpZmZ1c2UuYSk7CiAgICBUUkFDRSgiKCVwKSA6IEFtYmllbnQgKCVmLCVmLCVmLCVmKVxuIiwgVGhpcywgcE1hdGVyaWFsLT5BbWJpZW50LnIsIHBNYXRlcmlhbC0+QW1iaWVudC5nLAogICAgICAgIHBNYXRlcmlhbC0+QW1iaWVudC5iLCBwTWF0ZXJpYWwtPkFtYmllbnQuYSk7CiAgICBUUkFDRSgiKCVwKSA6IFNwZWN1bGFyICglZiwlZiwlZiwlZilcbiIsIFRoaXMsIHBNYXRlcmlhbC0+U3BlY3VsYXIuciwgcE1hdGVyaWFsLT5TcGVjdWxhci5nLAogICAgICAgIHBNYXRlcmlhbC0+U3BlY3VsYXIuYiwgcE1hdGVyaWFsLT5TcGVjdWxhci5hKTsKICAgIFRSQUNFKCIoJXApIDogRW1pc3NpdmUgKCVmLCVmLCVmLCVmKVxuIiwgVGhpcywgcE1hdGVyaWFsLT5FbWlzc2l2ZS5yLCBwTWF0ZXJpYWwtPkVtaXNzaXZlLmcsCiAgICAgICAgcE1hdGVyaWFsLT5FbWlzc2l2ZS5iLCBwTWF0ZXJpYWwtPkVtaXNzaXZlLmEpOwogICAgVFJBQ0UoIiglcCkgOiBQb3dlciAoJWYpXG4iLCBUaGlzLCBwTWF0ZXJpYWwtPlBvd2VyKTsKCiAgICBnbE1hdGVyaWFsZnYoR0xfRlJPTlRfQU5EX0JBQ0ssIEdMX0FNQklFTlQsIChmbG9hdCopICZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5tYXRlcmlhbC5BbWJpZW50KTsKICAgIGNoZWNrR0xjYWxsKCJnbE1hdGVyaWFsZnYoR0xfQU1CSUVOVCkiKTsKICAgIGdsTWF0ZXJpYWxmdihHTF9GUk9OVF9BTkRfQkFDSywgR0xfRElGRlVTRSwgKGZsb2F0KikgJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPm1hdGVyaWFsLkRpZmZ1c2UpOwogICAgY2hlY2tHTGNhbGwoImdsTWF0ZXJpYWxmdihHTF9ESUZGVVNFKSIpOwoKICAgIC8qIE9ubHkgY2hhbmdlIG1hdGVyaWFsIGNvbG9yIGlmIHNwZWN1bGFyIGlzIGVuYWJsZWQsIG90aGVyd2lzZSBpdCBpcyBzZXQgdG8gYmxhY2sgKi8KICAgIGlmIChUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtXSU5FRDNEUlNfU1BFQ1VMQVJFTkFCTEVdKSB7CiAgICAgICBnbE1hdGVyaWFsZnYoR0xfRlJPTlRfQU5EX0JBQ0ssIEdMX1NQRUNVTEFSLCAoZmxvYXQqKSAmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+bWF0ZXJpYWwuU3BlY3VsYXIpOwogICAgICAgY2hlY2tHTGNhbGwoImdsTWF0ZXJpYWxmdihHTF9TUEVDVUxBUiIpOwogICAgfSBlbHNlIHsKICAgICAgIGZsb2F0IGJsYWNrWzRdID0gezAuMGYsIDAuMGYsIDAuMGYsIDAuMGZ9OwogICAgICAgZ2xNYXRlcmlhbGZ2KEdMX0ZST05UX0FORF9CQUNLLCBHTF9TUEVDVUxBUiwgJmJsYWNrWzBdKTsKICAgICAgIGNoZWNrR0xjYWxsKCJnbE1hdGVyaWFsZnYoR0xfU1BFQ1VMQVIiKTsKICAgIH0KICAgIGdsTWF0ZXJpYWxmdihHTF9GUk9OVF9BTkRfQkFDSywgR0xfRU1JU1NJT04sIChmbG9hdCopICZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5tYXRlcmlhbC5FbWlzc2l2ZSk7CiAgICBjaGVja0dMY2FsbCgiZ2xNYXRlcmlhbGZ2KEdMX0VNSVNTSU9OKSIpOwogICAgZ2xNYXRlcmlhbGYoR0xfRlJPTlRfQU5EX0JBQ0ssIEdMX1NISU5JTkVTUywgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+bWF0ZXJpYWwuUG93ZXIpOwogICAgY2hlY2tHTGNhbGwoImdsTWF0ZXJpYWxmKEdMX1NISU5JTkVTUyIpOwoKICAgIExFQVZFX0dMKCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRNYXRlcmlhbChJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RNQVRFUklBTCogcE1hdGVyaWFsKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBtZW1jcHkocE1hdGVyaWFsLCAmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+bWF0ZXJpYWwsIHNpemVvZiAoV0lORUQzRE1BVEVSSUFMKSk7CiAgICBUUkFDRSgiKCVwKSA6IERpZmZ1c2UgKCVmLCVmLCVmLCVmKVxuIiwgVGhpcywgcE1hdGVyaWFsLT5EaWZmdXNlLnIsIHBNYXRlcmlhbC0+RGlmZnVzZS5nLAogICAgICAgIHBNYXRlcmlhbC0+RGlmZnVzZS5iLCBwTWF0ZXJpYWwtPkRpZmZ1c2UuYSk7CiAgICBUUkFDRSgiKCVwKSA6IEFtYmllbnQgKCVmLCVmLCVmLCVmKVxuIiwgVGhpcywgcE1hdGVyaWFsLT5BbWJpZW50LnIsIHBNYXRlcmlhbC0+QW1iaWVudC5nLAogICAgICAgIHBNYXRlcmlhbC0+QW1iaWVudC5iLCBwTWF0ZXJpYWwtPkFtYmllbnQuYSk7CiAgICBUUkFDRSgiKCVwKSA6IFNwZWN1bGFyICglZiwlZiwlZiwlZilcbiIsIFRoaXMsIHBNYXRlcmlhbC0+U3BlY3VsYXIuciwgcE1hdGVyaWFsLT5TcGVjdWxhci5nLAogICAgICAgIHBNYXRlcmlhbC0+U3BlY3VsYXIuYiwgcE1hdGVyaWFsLT5TcGVjdWxhci5hKTsKICAgIFRSQUNFKCIoJXApIDogRW1pc3NpdmUgKCVmLCVmLCVmLCVmKVxuIiwgVGhpcywgcE1hdGVyaWFsLT5FbWlzc2l2ZS5yLCBwTWF0ZXJpYWwtPkVtaXNzaXZlLmcsCiAgICAgICAgcE1hdGVyaWFsLT5FbWlzc2l2ZS5iLCBwTWF0ZXJpYWwtPkVtaXNzaXZlLmEpOwogICAgVFJBQ0UoIiglcCkgOiBQb3dlciAoJWYpXG4iLCBUaGlzLCBwTWF0ZXJpYWwtPlBvd2VyKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBJbmRpY2VzCiAqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRJbmRpY2VzKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RJbmRleEJ1ZmZlciogcEluZGV4RGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBCYXNlVmVydGV4SW5kZXgpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzREluZGV4QnVmZmVyICpvbGRJZHhzOwogICAgVUlOVCBvbGRCYXNlSW5kZXggPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5iYXNlVmVydGV4SW5kZXg7CgogICAgVFJBQ0UoIiglcCkgOiBTZXR0aW5nIHRvICVwLCBiYXNlICVkXG4iLCBUaGlzLCBwSW5kZXhEYXRhLCBCYXNlVmVydGV4SW5kZXgpOwogICAgb2xkSWR4cyA9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnBJbmRleERhdGE7CgogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC5pbmRpY2VzID0gVFJVRTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnNldC5pbmRpY2VzID0gVFJVRTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnBJbmRleERhdGEgPSBwSW5kZXhEYXRhOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+YmFzZVZlcnRleEluZGV4ID0gQmFzZVZlcnRleEluZGV4OwoKICAgIC8qIEhhbmRsZSByZWNvcmRpbmcgb2Ygc3RhdGUgYmxvY2tzICovCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIC8qIFRoZSBiYXNlIHZlcnRleCBpbmRleCBhZmZlY3RzIHRoZSBzdHJlYW0gc291cmNlcywgd2hpbGUKICAgICAqIFRoZSBpbmRleCBidWZmZXIgaXMgYSBzZXBlcmF0ZSBpbmRleCBidWZmZXIgc3RhdGUKICAgICAqLwogICAgaWYoQmFzZVZlcnRleEluZGV4ICE9IG9sZEJhc2VJbmRleCkgewogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TVFJFQU1TUkMpOwogICAgfQogICAgaWYob2xkSWR4cyAhPSBwSW5kZXhEYXRhKSB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX0lOREVYQlVGRkVSKTsKICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldEluZGljZXMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzREluZGV4QnVmZmVyKiogcHBJbmRleERhdGEsIFVJTlQqIHBCYXNlVmVydGV4SW5kZXgpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICAqcHBJbmRleERhdGEgPSBUaGlzLT5zdGF0ZUJsb2NrLT5wSW5kZXhEYXRhOwoKICAgIC8qIHVwIHJlZiBjb3VudCBvbiBwcGluZGV4ZGF0YSAqLwogICAgaWYgKCpwcEluZGV4RGF0YSkgewogICAgICAgIElXaW5lRDNESW5kZXhCdWZmZXJfQWRkUmVmKCpwcEluZGV4RGF0YSk7CiAgICAgICAgKnBCYXNlVmVydGV4SW5kZXggPSBUaGlzLT5zdGF0ZUJsb2NrLT5iYXNlVmVydGV4SW5kZXg7CiAgICAgICAgVFJBQ0UoIiglcCkgaW5kZXggZGF0YSBzZXQgdG8gJXAgKyAldVxuIiwgVGhpcywgcHBJbmRleERhdGEsIFRoaXMtPnN0YXRlQmxvY2stPmJhc2VWZXJ0ZXhJbmRleCk7CiAgICB9ZWxzZXsKICAgICAgICBUUkFDRSgiKCVwKSBObyBpbmRleCBkYXRhIHNldFxuIiwgVGhpcyk7CiAgICB9CiAgICBUUkFDRSgiUmV0dXJuaW5nICVwICVkXG4iLCAqcHBJbmRleERhdGEsICpwQmFzZVZlcnRleEluZGV4KTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyogTWV0aG9kIHRvIG9mZmVyIGQzZDkgYSBzaW1wbGUgd2F5IHRvIHNldCB0aGUgYmFzZSB2ZXJ0ZXggaW5kZXggd2l0aG91dCBtZXNzaW5nIHdpdGggdGhlIGluZGV4IGJ1ZmZlciAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldEJhc2V2ZXJ0ZXhJbmRleChJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgQmFzZUluZGV4KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKS0+KCVkKVxuIiwgVGhpcywgQmFzZUluZGV4KTsKCiAgICBpZihUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5iYXNlVmVydGV4SW5kZXggPT0gQmFzZUluZGV4KSB7CiAgICAgICAgVFJBQ0UoIkFwcGxpY2F0aW9uIGlzIHNldHRpbmcgdGhlIG9sZCB2YWx1ZSBvdmVyLCBub3RoaW5nIHRvIGRvXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5iYXNlVmVydGV4SW5kZXggPSBCYXNlSW5kZXg7CgogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TVFJFQU1TUkMpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBHZXQgLyBTZXQgVmlld3BvcnRzCiAqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWaWV3cG9ydChJV2luZUQzRERldmljZSAqaWZhY2UsIENPTlNUIFdJTkVEM0RWSUVXUE9SVCogcFZpZXdwb3J0KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC52aWV3cG9ydCA9IFRSVUU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQudmlld3BvcnQgPSBUUlVFOwogICAgbWVtY3B5KCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT52aWV3cG9ydCwgcFZpZXdwb3J0LCBzaXplb2YoV0lORUQzRFZJRVdQT1JUKSk7CgogICAgLyogSGFuZGxlIHJlY29yZGluZyBvZiBzdGF0ZSBibG9ja3MgKi8KICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgVFJBQ0UoIiglcCkgOiB4PSVkLCB5PSVkLCB3aWQ9JWQsIGhlaT0lZCwgbWluej0lZiwgbWF4ej0lZlxuIiwgVGhpcywKICAgICAgICAgIHBWaWV3cG9ydC0+WCwgcFZpZXdwb3J0LT5ZLCBwVmlld3BvcnQtPldpZHRoLCBwVmlld3BvcnQtPkhlaWdodCwgcFZpZXdwb3J0LT5NaW5aLCBwVmlld3BvcnQtPk1heFopOwoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9WSUVXUE9SVCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKCn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0Vmlld3BvcnQoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEVklFV1BPUlQqIHBWaWV3cG9ydCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwogICAgbWVtY3B5KHBWaWV3cG9ydCwgJlRoaXMtPnN0YXRlQmxvY2stPnZpZXdwb3J0LCBzaXplb2YoV0lORUQzRFZJRVdQT1JUKSk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqCiAqIEdldCAvIFNldCBSZW5kZXIgU3RhdGVzCiAqIFRPRE86IFZlcmlmeSBhZ2FpbnN0IGR4OSBkZWZpbml0aW9ucwogKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0UmVuZGVyU3RhdGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEUkVOREVSU1RBVEVUWVBFIFN0YXRlLCBEV09SRCBWYWx1ZSkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAgKlRoaXMgICAgID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgRFdPUkQgb2xkVmFsdWUgPSBUaGlzLT5zdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtTdGF0ZV07CgogICAgVFJBQ0UoIiglcCktPnN0YXRlID0gJXMoJWQpLCB2YWx1ZSA9ICVkXG4iLCBUaGlzLCBkZWJ1Z19kM2RyZW5kZXJzdGF0ZShTdGF0ZSksIFN0YXRlLCBWYWx1ZSk7CgogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC5yZW5kZXJTdGF0ZVtTdGF0ZV0gPSBUUlVFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0LnJlbmRlclN0YXRlW1N0YXRlXSA9IFRSVUU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5yZW5kZXJTdGF0ZVtTdGF0ZV0gPSBWYWx1ZTsKCiAgICAvKiBIYW5kbGUgcmVjb3JkaW5nIG9mIHN0YXRlIGJsb2NrcyAqLwogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICAvKiBDb21wYXJlZCBoZXJlIGFuZCBub3QgYmVmb3JlIHRoZSBhc3NpZ25tZW50IHRvIGFsbG93IHByb3BlciBzdGF0ZWJsb2NrIHJlY29yZGluZyAqLwogICAgaWYoVmFsdWUgPT0gb2xkVmFsdWUpIHsKICAgICAgICBUUkFDRSgiQXBwbGljYXRpb24gaXMgc2V0dGluZyB0aGUgb2xkIHZhbHVlIG92ZXIsIG5vdGhpbmcgdG8gZG9cbiIpOwogICAgfSBlbHNlIHsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfUkVOREVSKFN0YXRlKSk7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0UmVuZGVyU3RhdGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEUkVOREVSU1RBVEVUWVBFIFN0YXRlLCBEV09SRCAqcFZhbHVlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKSBmb3IgU3RhdGUgJWQgPSAlZFxuIiwgVGhpcywgU3RhdGUsIFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1N0YXRlXSk7CiAgICAqcFZhbHVlID0gVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbU3RhdGVdOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBHZXQgLyBTZXQgU2FtcGxlciBTdGF0ZXMKICogVE9ETzogVmVyaWZ5IGFnYWluc3QgZHg5IGRlZmluaXRpb25zCiAqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0U2FtcGxlclN0YXRlKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgU2FtcGxlciwgV0lORUQzRFNBTVBMRVJTVEFURVRZUEUgVHlwZSwgRFdPUkQgVmFsdWUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIERXT1JEIG9sZFZhbHVlID0gVGhpcy0+c3RhdGVCbG9jay0+c2FtcGxlclN0YXRlW1NhbXBsZXJdW1R5cGVdOwoKICAgIC8qKgogICAgKiBTZXRTYW1wbGVyIGlzIGRlc2lnbmVkIHRvIGFsbG93IGZvciBtb3JlIHRoYW4gdGhlIHN0YW5kYXJkIHVwIHRvIDggdGV4dHVyZXMKICAgICogIGFuZCBHZWZvcmNlIGhhcyBzdG9wcGVkIHN1cHBvcnRpbmcgbW9yZSB0aGFuIDYgc3RhbmRhcmQgdGV4dHVyZXMgaW4gb3BlbkdMLgogICAgKiBTbyBJIGhhdmUgdG8gdXNlIEFSQiBmb3IgR2ZvcmNlLiAobWF5YmUgaWYgdGhlIHNhbXBsZXIgPiA0IHRoZW4gdXNlIEFSQj8pCiAgICAqCiAgICAqIGh0dHA6Ly9kZXZlbG9wZXIubnZpZGlhLmNvbS9vYmplY3QvR2VuZXJhbF9GQVEuaHRtbCN0NgogICAgKgogICAgKiBUaGVyZSBhcmUgdHdvIG5ldyBzZXR0aW5ncyBmb3IgR0ZvcmNlCiAgICAqIHRoZSBzYW1wbGVyIG9uZToKICAgICogR0xfTUFYX1RFWFRVUkVfSU1BR0VfVU5JVFNfQVJCCiAgICAqIGFuZCB0aGUgdGV4dHVyZSBvbmU6CiAgICAqIEdMX01BWF9URVhUVVJFX0NPT1JEU19BUkIuCiAgICAqIE9rIEdGb3JjZSBzYXkgaXQncyBvayB0byB1c2UgZ2xUZXhQYXJhbWV0ZXIvZ2xHZXRUZXhQYXJhbWV0ZXIoLi4uKS4KICAgICAqKioqKioqKioqKioqKioqKiovCgogICAgVFJBQ0UoIiglcCkgOiBTYW1wbGVyPSVkLCBUeXBlPSVzKCVkKSwgVmFsdWU9JWRcbiIsIFRoaXMsIFNhbXBsZXIsCiAgICAgICAgZGVidWdfZDNkc2FtcGxlcnN0YXRlKFR5cGUpLCBUeXBlLCBWYWx1ZSk7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zYW1wbGVyU3RhdGVbU2FtcGxlcl1bVHlwZV0gICAgICAgICA9IFZhbHVlOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0LnNhbXBsZXJTdGF0ZVtTYW1wbGVyXVtUeXBlXSAgICAgPSBWYWx1ZTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQuc2FtcGxlclN0YXRlW1NhbXBsZXJdW1R5cGVdID0gVmFsdWU7CgogICAgLyogSGFuZGxlIHJlY29yZGluZyBvZiBzdGF0ZSBibG9ja3MgKi8KICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgaWYob2xkVmFsdWUgPT0gVmFsdWUpIHsKICAgICAgICBUUkFDRSgiQXBwbGljYXRpb24gaXMgc2V0dGluZyB0aGUgb2xkIHZhbHVlIG92ZXIsIG5vdGhpbmcgdG8gZG9cbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TQU1QTEVSKFNhbXBsZXIpKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTYW1wbGVyU3RhdGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBTYW1wbGVyLCBXSU5FRDNEU0FNUExFUlNUQVRFVFlQRSBUeXBlLCBEV09SRCogVmFsdWUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgICpWYWx1ZSA9IFRoaXMtPnN0YXRlQmxvY2stPnNhbXBsZXJTdGF0ZVtTYW1wbGVyXVtUeXBlXTsKICAgIFRSQUNFKCIoJXApIDogU2FtcGxlciAlZCBUeXBlICV1IFJldHVybmluZyAlZFxuIiwgVGhpcywgU2FtcGxlciwgVHlwZSwgKlZhbHVlKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRTY2lzc29yUmVjdChJV2luZUQzRERldmljZSAqaWZhY2UsIENPTlNUIFJFQ1QqIHBSZWN0KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0LnNjaXNzb3JSZWN0ID0gVFJVRTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQuc2Npc3NvclJlY3QgPSBUUlVFOwogICAgaWYoRXF1YWxSZWN0KCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zY2lzc29yUmVjdCwgcFJlY3QpKSB7CiAgICAgICAgVFJBQ0UoIkFwcCBpcyBzZXR0aW5nIHRoZSBvbGQgc2Npc3NvciByZWN0YW5nbGUgb3Zlciwgbm90aGluZyB0byBkb1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CiAgICBDb3B5UmVjdCgmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2Npc3NvclJlY3QsIHBSZWN0KTsKCiAgICBpZihUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1NDSVNTT1JSRUNUKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTY2lzc29yUmVjdChJV2luZUQzRERldmljZSAqaWZhY2UsIFJFQ1QqIHBSZWN0KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgbWVtY3B5KHBSZWN0LCAmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2Npc3NvclJlY3QsIHNpemVvZihwUmVjdCkpOwogICAgVFJBQ0UoIiglcClSZXR1cm5pbmcgYSBTY2lzc29yIFJlY3Qgb2YgJWQ6JWQtJWQ6JWRcbiIsIFRoaXMsIHBSZWN0LT5sZWZ0LCBwUmVjdC0+dG9wLCBwUmVjdC0+cmlnaHQsIHBSZWN0LT5ib3R0b20pOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0VmVydGV4RGVjbGFyYXRpb24oSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uKiBwRGVjbCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEVmVydGV4RGVjbGFyYXRpb24gKm9sZERlY2wgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT52ZXJ0ZXhEZWNsOwoKICAgIFRSQUNFKCIoJXApIDogcERlY2w9JXBcbiIsIFRoaXMsIHBEZWNsKTsKCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT52ZXJ0ZXhEZWNsID0gcERlY2w7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnZlcnRleERlY2wgPSBUUlVFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0LnZlcnRleERlY2wgPSBUUlVFOwoKICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9IGVsc2UgaWYocERlY2wgPT0gb2xkRGVjbCkgewogICAgICAgIC8qIENoZWNrZWQgYWZ0ZXIgdGhlIGFzc2lnbm1lbnQgdG8gYWxsb3cgcHJvcGVyIHN0YXRlYmxvY2sgcmVjb3JkaW5nICovCiAgICAgICAgVFJBQ0UoIkFwcGxpY2F0aW9uIGlzIHNldHRpbmcgdGhlIG9sZCBkZWNsYXJhdGlvbiBvdmVyLCBub3RoaW5nIHRvIGRvXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVkRFQ0wpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0VmVydGV4RGVjbGFyYXRpb24oSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uKiogcHBEZWNsKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCkgOiBwcERlY2w9JXBcbiIsIFRoaXMsIHBwRGVjbCk7CgogICAgKnBwRGVjbCA9IFRoaXMtPnN0YXRlQmxvY2stPnZlcnRleERlY2w7CiAgICBpZiAoTlVMTCAhPSAqcHBEZWNsKSBJV2luZUQzRFZlcnRleERlY2xhcmF0aW9uX0FkZFJlZigqcHBEZWNsKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZlcnRleFNoYWRlcihJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEVmVydGV4U2hhZGVyKiBwU2hhZGVyKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgICAgICAgID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RWZXJ0ZXhTaGFkZXIqIG9sZFNoYWRlciA9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnZlcnRleFNoYWRlcjsKCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT52ZXJ0ZXhTaGFkZXIgICAgICAgICA9IHBTaGFkZXI7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnZlcnRleFNoYWRlciA9IFRSVUU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQudmVydGV4U2hhZGVyICAgICA9IFRSVUU7CgogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0gZWxzZSBpZihvbGRTaGFkZXIgPT0gcFNoYWRlcikgewogICAgICAgIC8qIENoZWNrZWQgaGVyZSB0byBhbGxvdyBwcm9wZXIgc3RhdGVibG9jayByZWNvcmRpbmcgKi8KICAgICAgICBUUkFDRSgiQXBwIGlzIHNldHRpbmcgdGhlIG9sZCBzaGFkZXIgb3Zlciwgbm90aGluZyB0byBkb1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgVFJBQ0UoIiglcCkgOiBzZXR0aW5nIHBTaGFkZXIoJXApXG4iLCBUaGlzLCBwU2hhZGVyKTsKCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVlNIQURFUik7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0VmVydGV4U2hhZGVyKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RWZXJ0ZXhTaGFkZXIqKiBwcFNoYWRlcikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIGlmIChOVUxMID09IHBwU2hhZGVyKSB7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICAqcHBTaGFkZXIgPSBUaGlzLT5zdGF0ZUJsb2NrLT52ZXJ0ZXhTaGFkZXI7CiAgICBpZiggTlVMTCAhPSAqcHBTaGFkZXIpCiAgICAgICAgSVdpbmVEM0RWZXJ0ZXhTaGFkZXJfQWRkUmVmKCpwcFNoYWRlcik7CgogICAgVFJBQ0UoIiglcCkgOiByZXR1cm5pbmcgJXBcbiIsIFRoaXMsICpwcFNoYWRlcik7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEIoCiAgICBJV2luZUQzRERldmljZSAqaWZhY2UsCiAgICBVSU5UIHN0YXJ0LAogICAgQ09OU1QgQk9PTCAqc3JjRGF0YSwKICAgIFVJTlQgY291bnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpbnQgaSwgY250ID0gbWluKGNvdW50LCBNQVhfQ09OU1RfQiAtIHN0YXJ0KTsKCiAgICBUUkFDRSgiKGlmYWNlICVwLCBzcmNEYXRhICVwLCBzdGFydCAlZCwgY291bnQgJWQpXG4iLAogICAgICAgICAgICBpZmFjZSwgc3JjRGF0YSwgc3RhcnQsIGNvdW50KTsKCiAgICBpZiAoc3JjRGF0YSA9PSBOVUxMIHx8IGNudCA8IDApCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgbWVtY3B5KCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT52ZXJ0ZXhTaGFkZXJDb25zdGFudEJbc3RhcnRdLCBzcmNEYXRhLCBjbnQgKiBzaXplb2YoQk9PTCkpOwogICAgZm9yIChpID0gMDsgaSA8IGNudDsgaSsrKQogICAgICAgIFRSQUNFKCJTZXQgQk9PTCBjb25zdGFudCAldSB0byAlc1xuIiwgc3RhcnQgKyBpLCBzcmNEYXRhW2ldPyAidHJ1ZSI6ImZhbHNlIik7CgogICAgZm9yIChpID0gc3RhcnQ7IGkgPCBjbnQgKyBzdGFydDsgKytpKSB7CiAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC52ZXJ0ZXhTaGFkZXJDb25zdGFudHNCW2ldID0gVFJVRTsKICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQudmVydGV4U2hhZGVyQ29uc3RhbnRzQltpXSAgICAgPSBUUlVFOwogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9WRVJURVhTSEFERVJDT05TVEFOVCk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0VmVydGV4U2hhZGVyQ29uc3RhbnRCKAogICAgSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgVUlOVCBzdGFydCwKICAgIEJPT0wgKmRzdERhdGEsCiAgICBVSU5UIGNvdW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaW50IGNudCA9IG1pbihjb3VudCwgTUFYX0NPTlNUX0IgLSBzdGFydCk7CgogICAgVFJBQ0UoIihpZmFjZSAlcCwgZHN0RGF0YSAlcCwgc3RhcnQgJWQsIGNvdW50ICVkKVxuIiwKICAgICAgICAgICAgaWZhY2UsIGRzdERhdGEsIHN0YXJ0LCBjb3VudCk7CgogICAgaWYgKGRzdERhdGEgPT0gTlVMTCB8fCBjbnQgPCAwKQogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIG1lbWNweShkc3REYXRhLCAmVGhpcy0+c3RhdGVCbG9jay0+dmVydGV4U2hhZGVyQ29uc3RhbnRCW3N0YXJ0XSwgY250ICogc2l6ZW9mKEJPT0wpKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZlcnRleFNoYWRlckNvbnN0YW50SSgKICAgIElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgIFVJTlQgc3RhcnQsCiAgICBDT05TVCBpbnQgKnNyY0RhdGEsCiAgICBVSU5UIGNvdW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaW50IGksIGNudCA9IG1pbihjb3VudCwgTUFYX0NPTlNUX0kgLSBzdGFydCk7CgogICAgVFJBQ0UoIihpZmFjZSAlcCwgc3JjRGF0YSAlcCwgc3RhcnQgJWQsIGNvdW50ICVkKVxuIiwKICAgICAgICAgICAgaWZhY2UsIHNyY0RhdGEsIHN0YXJ0LCBjb3VudCk7CgogICAgaWYgKHNyY0RhdGEgPT0gTlVMTCB8fCBjbnQgPCAwKQogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIG1lbWNweSgmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dmVydGV4U2hhZGVyQ29uc3RhbnRJW3N0YXJ0ICogNF0sIHNyY0RhdGEsIGNudCAqIHNpemVvZihpbnQpICogNCk7CiAgICBmb3IgKGkgPSAwOyBpIDwgY250OyBpKyspCiAgICAgICAgVFJBQ0UoIlNldCBJTlQgY29uc3RhbnQgJXUgdG8geyAlZCwgJWQsICVkLCAlZCB9XG4iLCBzdGFydCArIGksCiAgICAgICAgICAgc3JjRGF0YVtpKjRdLCBzcmNEYXRhW2kqNCsxXSwgc3JjRGF0YVtpKjQrMl0sIHNyY0RhdGFbaSo0KzNdKTsKCiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGNudCArIHN0YXJ0OyArK2kpIHsKICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnZlcnRleFNoYWRlckNvbnN0YW50c0lbaV0gPSBUUlVFOwogICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnNldC52ZXJ0ZXhTaGFkZXJDb25zdGFudHNJW2ldICAgICA9IFRSVUU7CiAgICB9CgogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1ZFUlRFWFNIQURFUkNPTlNUQU5UKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEkoCiAgICBJV2luZUQzRERldmljZSAqaWZhY2UsCiAgICBVSU5UIHN0YXJ0LAogICAgaW50ICpkc3REYXRhLAogICAgVUlOVCBjb3VudCkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIGludCBjbnQgPSBtaW4oY291bnQsIE1BWF9DT05TVF9JIC0gc3RhcnQpOwoKICAgIFRSQUNFKCIoaWZhY2UgJXAsIGRzdERhdGEgJXAsIHN0YXJ0ICVkLCBjb3VudCAlZClcbiIsCiAgICAgICAgICAgIGlmYWNlLCBkc3REYXRhLCBzdGFydCwgY291bnQpOwoKICAgIGlmIChkc3REYXRhID09IE5VTEwgfHwgKChzaWduZWQgaW50KSBNQVhfQ09OU1RfSSAtIChzaWduZWQgaW50KSBzdGFydCkgPD0gKHNpZ25lZCBpbnQpIDApCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgbWVtY3B5KGRzdERhdGEsICZUaGlzLT5zdGF0ZUJsb2NrLT52ZXJ0ZXhTaGFkZXJDb25zdGFudElbc3RhcnQgKiA0XSwgY250ICogc2l6ZW9mKGludCkgKiA0KTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZlcnRleFNoYWRlckNvbnN0YW50RigKICAgIElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgIFVJTlQgc3RhcnQsCiAgICBDT05TVCBmbG9hdCAqc3JjRGF0YSwKICAgIFVJTlQgY291bnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpbnQgaTsKCiAgICBUUkFDRSgiKGlmYWNlICVwLCBzcmNEYXRhICVwLCBzdGFydCAlZCwgY291bnQgJWQpXG4iLAogICAgICAgICAgICBpZmFjZSwgc3JjRGF0YSwgc3RhcnQsIGNvdW50KTsKCiAgICAvKiBTcGVjaWZpY2FsbHkgdGVzdCBzdGFydCA+IGxpbWl0IHRvIGNhdGNoIE1BWF9VSU5UIG92ZXJmbG93cyB3aGVuIGFkZGluZyBzdGFydCArIGNvdW50ICovCiAgICBpZiAoc3JjRGF0YSA9PSBOVUxMIHx8IHN0YXJ0ICsgY291bnQgPiBHTF9MSU1JVFModnNoYWRlcl9jb25zdGFudHNGKSB8fCBzdGFydCA+IEdMX0xJTUlUUyh2c2hhZGVyX2NvbnN0YW50c0YpKQogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIG1lbWNweSgmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dmVydGV4U2hhZGVyQ29uc3RhbnRGW3N0YXJ0ICogNF0sIHNyY0RhdGEsIGNvdW50ICogc2l6ZW9mKGZsb2F0KSAqIDQpOwogICAgaWYoVFJBQ0VfT04oZDNkKSkgewogICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb3VudDsgaSsrKQogICAgICAgICAgICBUUkFDRSgiU2V0IEZMT0FUIGNvbnN0YW50ICV1IHRvIHsgJWYsICVmLCAlZiwgJWYgfVxuIiwgc3RhcnQgKyBpLAogICAgICAgICAgICAgICAgc3JjRGF0YVtpKjRdLCBzcmNEYXRhW2kqNCsxXSwgc3JjRGF0YVtpKjQrMl0sIHNyY0RhdGFbaSo0KzNdKTsKICAgIH0KCiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGNvdW50ICsgc3RhcnQ7ICsraSkgewogICAgICAgIGlmICghVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0LnZlcnRleFNoYWRlckNvbnN0YW50c0ZbaV0pIHsKICAgICAgICAgICAgY29uc3RhbnRzX2VudHJ5ICpwdHIgPSBMSVNUX0VOVFJZKGxpc3RfaGVhZCgmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0X3Zjb25zdGFudHNGKSwgY29uc3RhbnRzX2VudHJ5LCBlbnRyeSk7CiAgICAgICAgICAgIGlmICghcHRyIHx8IHB0ci0+Y291bnQgPj0gc2l6ZW9mKHB0ci0+aWR4KSAvIHNpemVvZigqcHRyLT5pZHgpKSB7CiAgICAgICAgICAgICAgICBwdHIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKGNvbnN0YW50c19lbnRyeSkpOwogICAgICAgICAgICAgICAgbGlzdF9hZGRfaGVhZCgmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0X3Zjb25zdGFudHNGLCAmcHRyLT5lbnRyeSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHRyLT5pZHhbcHRyLT5jb3VudCsrXSA9IGk7CiAgICAgICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnNldC52ZXJ0ZXhTaGFkZXJDb25zdGFudHNGW2ldID0gVFJVRTsKICAgICAgICB9CiAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC52ZXJ0ZXhTaGFkZXJDb25zdGFudHNGW2ldID0gVFJVRTsKICAgIH0KCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVkVSVEVYU0hBREVSQ09OU1RBTlQpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZlcnRleFNoYWRlckNvbnN0YW50RigKICAgIElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgIFVJTlQgc3RhcnQsCiAgICBmbG9hdCAqZHN0RGF0YSwKICAgIFVJTlQgY291bnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpbnQgY250ID0gbWluKGNvdW50LCBHTF9MSU1JVFModnNoYWRlcl9jb25zdGFudHNGKSAtIHN0YXJ0KTsKCiAgICBUUkFDRSgiKGlmYWNlICVwLCBkc3REYXRhICVwLCBzdGFydCAlZCwgY291bnQgJWQpXG4iLAogICAgICAgICAgICBpZmFjZSwgZHN0RGF0YSwgc3RhcnQsIGNvdW50KTsKCiAgICBpZiAoZHN0RGF0YSA9PSBOVUxMIHx8IGNudCA8IDApCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgbWVtY3B5KGRzdERhdGEsICZUaGlzLT5zdGF0ZUJsb2NrLT52ZXJ0ZXhTaGFkZXJDb25zdGFudEZbc3RhcnQgKiA0XSwgY250ICogc2l6ZW9mKGZsb2F0KSAqIDQpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBtYXJrVGV4dHVyZVN0YWdlc0RpcnR5KElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcywgRFdPUkQgc3RhZ2UpIHsKICAgIERXT1JEIGk7CiAgICBmb3IoaSA9IDA7IGkgPCBXSU5FRDNEX0hJR0hFU1RfVEVYVFVSRV9TVEFURTsgaSsrKSB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1RFWFRVUkVTVEFHRShzdGFnZSwgaSkpOwogICAgfQp9CgpzdGF0aWMgdm9pZCBJV2luZUQzRERldmljZUltcGxfRmluZFRleFVuaXRNYXAoSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzKSB7CiAgICBEV09SRCBpLCB0ZXg7CiAgICAvKiBUaGlzIGNvZGUgY2FuIGFzc3VtZSB0aGF0IEdMX05WX3JlZ2lzdGVyX2NvbWJpbmVycyBhcmUgc3VwcG9ydGVkLCBvdGhlcndpc2UKICAgICAqIGl0IGlzIG5ldmVyIGNhbGxlZC4KICAgICAqCiAgICAgKiBSdWxlcyBhcmU6CiAgICAgKiAtPiBQaXhlbCBzaGFkZXJzIG5lZWQgYSAxOjEgbWFwLiBJbiB0aGVvcnkgdGhlIHNoYWRlciBpbnB1dCBjb3VsZCBiZSBtYXBwZWQgdG9vLCBidXQKICAgICAqIHRoYXQgd291bGQgYmUgcmVhbGx5IG1lc3N5IGFuZCByZXF1aXJlIHNoYWRlciByZWNvbXBpbGF0aW9uCiAgICAgKiAtPiBXaGVuIHRoZSBtYXBwaW5nIG9mIGEgc3RhZ2UgaXMgY2hhbmdlZCwgc2FtcGxlciBhbmQgQUxMIHRleHR1cmUgc3RhZ2Ugc3RhdGVzIGhhdmUKICAgICAqIHRvIGJlIHJlc2V0LiBCZWNhdXNlIG9mIHRoYXQgdHJ5IHRvIHdvcmsgd2l0aCBhIDE6MSBtYXBwaW5nIGFzIG11Y2ggYXMgcG9zc2libGUKICAgICAqIC0+IFdoaXRoIGEgMToxIG1hcHBpbmcgb25lVG9PbmVUZXhVbml0TWFwIGlzIHNldCB0byBhdm9pZCBjaGVja2luZyBNQVhfU0FNUExFUlMgYXJyYXkKICAgICAqIGVudHJpZXMgdG8gbWFrZSBwaXhlbCBzaGFkZXJzIGNoZWFwZXIuIE1BWF9TQU1QTEVSUyB3aWxsIGJlIDEyOCBpbiBkeDEwCiAgICAgKi8KICAgIGlmKFRoaXMtPnN0YXRlQmxvY2stPnBpeGVsU2hhZGVyIHx8IFRoaXMtPnN0YXRlQmxvY2stPmxvd2VzdF9kaXNhYmxlZF9zdGFnZSA8PSBHTF9MSU1JVFModGV4dHVyZXMpKSB7CiAgICAgICAgaWYoVGhpcy0+b25lVG9PbmVUZXhVbml0TWFwKSB7CiAgICAgICAgICAgIFRSQUNFKCJOb3QgdG91Y2hpbmcgMToxIG1hcFxuIik7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgVFJBQ0UoIlJlc3RvcmluZyAxOjEgdGV4dHVyZSB1bml0IG1hcHBpbmdcbiIpOwogICAgICAgIC8qIFJlc3RvcmUgYSAxOjEgbWFwcGluZyAqLwogICAgICAgIGZvcihpID0gMDsgaSA8IE1BWF9TQU1QTEVSUzsgaSsrKSB7CiAgICAgICAgICAgIGlmKFRoaXMtPnRleFVuaXRNYXBbaV0gIT0gaSkgewogICAgICAgICAgICAgICAgVGhpcy0+dGV4VW5pdE1hcFtpXSA9IGk7CiAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfU0FNUExFUihpKSk7CiAgICAgICAgICAgICAgICBtYXJrVGV4dHVyZVN0YWdlc0RpcnR5KFRoaXMsIGkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIFRoaXMtPm9uZVRvT25lVGV4VW5pdE1hcCA9IFRSVUU7CiAgICAgICAgcmV0dXJuOwogICAgfSBlbHNlIHsKICAgICAgICAvKiBObyBwaXhlbCBzaGFkZXIsIGFuZCB3ZSBkbyBub3QgaGF2ZSBlbm91Z2ggdGV4dHVyZSB1bml0cyBhdmFpbGFibGUuIFRyeSB0byBza2lwIE5VTEwgdGV4dHVyZXMKICAgICAgICAgKiBGaXJzdCwgc2VlIGlmIHdlIGNhbiBzdWNjZWVkIGF0IGFsbAogICAgICAgICAqLwogICAgICAgIHRleCA9IDA7CiAgICAgICAgZm9yKGkgPSAwOyBpIDwgVGhpcy0+c3RhdGVCbG9jay0+bG93ZXN0X2Rpc2FibGVkX3N0YWdlOyBpKyspIHsKICAgICAgICAgICAgaWYoVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZXNbaV0gPT0gTlVMTCkgdGV4Kys7CiAgICAgICAgfQoKICAgICAgICBpZihHTF9MSU1JVFModGV4dHVyZXMpICsgdGV4IDwgVGhpcy0+c3RhdGVCbG9jay0+bG93ZXN0X2Rpc2FibGVkX3N0YWdlKSB7CiAgICAgICAgICAgIEZJWE1FKCJUb28gbWFueSBib3VuZCB0ZXh0dXJlcyB0byBzdXBwb3J0IHRoZSBjb21iaW5lciBzZXR0aW5nc1xuIik7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIC8qIE5vdyB3b3JrIG91dCB0aGUgbWFwcGluZyAqLwogICAgICAgIHRleCA9IDA7CiAgICAgICAgVGhpcy0+b25lVG9PbmVUZXhVbml0TWFwID0gRkFMU0U7CiAgICAgICAgV0FSTigiTm9uIDE6MSBtYXBwaW5nIFVOVEVTVEVEIVxuIik7CiAgICAgICAgZm9yKGkgPSAwOyBpIDwgVGhpcy0+c3RhdGVCbG9jay0+bG93ZXN0X2Rpc2FibGVkX3N0YWdlOyBpKyspIHsKICAgICAgICAgICAgLyogU2tpcCBOVUxMIHRleHR1cmVzICovCiAgICAgICAgICAgIGlmICghVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZXNbaV0pIHsKICAgICAgICAgICAgICAgIC8qIE1hcCB0byAtMSwgc28gdGhlIGNoZWNrIGJlbG93IGRvZXNuJ3QgZmFpbCBpZiBhIG5vbi1OVUxMCiAgICAgICAgICAgICAgICAgKiB0ZXh0dXJlIGlzIHNldCBvbiB0aGlzIHN0YWdlICovCiAgICAgICAgICAgICAgICBUUkFDRSgiTWFwcGluZyB0ZXh0dXJlIHN0YWdlICVkIHRvIC0xXG4iLCBpKTsKICAgICAgICAgICAgICAgIFRoaXMtPnRleFVuaXRNYXBbaV0gPSAtMTsKCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgVFJBQ0UoIk1hcHBpbmcgdGV4dHVyZSBzdGFnZSAlZCB0byB1bml0ICVkXG4iLCBpLCB0ZXgpOwogICAgICAgICAgICBpZihUaGlzLT50ZXhVbml0TWFwW2ldICE9IHRleCkgewogICAgICAgICAgICAgICAgVGhpcy0+dGV4VW5pdE1hcFtpXSA9IHRleDsKICAgICAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TQU1QTEVSKGkpKTsKICAgICAgICAgICAgICAgIG1hcmtUZXh0dXJlU3RhZ2VzRGlydHkoVGhpcywgaSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgICsrdGV4OwogICAgICAgIH0KICAgIH0KfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRQaXhlbFNoYWRlcihJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEUGl4ZWxTaGFkZXIgKnBTaGFkZXIpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyAgICAgICAgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFBpeGVsU2hhZGVyICpvbGRTaGFkZXIgID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+cGl4ZWxTaGFkZXI7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5waXhlbFNoYWRlciAgICAgICAgID0gcFNoYWRlcjsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQucGl4ZWxTaGFkZXIgPSBUUlVFOwogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0LnBpeGVsU2hhZGVyICAgICA9IFRSVUU7CgogICAgLyogSGFuZGxlIHJlY29yZGluZyBvZiBzdGF0ZSBibG9ja3MgKi8KICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICB9CgogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICBUUkFDRSgiUmVjb3JkaW5nLi4uIG5vdCBwZXJmb3JtaW5nIGFueXRoaW5nXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBpZihwU2hhZGVyID09IG9sZFNoYWRlcikgewogICAgICAgIFRSQUNFKCJBcHAgaXMgc2V0dGluZyB0aGUgb2xkIHBpeGVsIHNoYWRlciBvdmVyLCBub3RoaW5nIHRvIGRvXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBUUkFDRSgiKCVwKSA6IHNldHRpbmcgcFNoYWRlciglcClcbiIsIFRoaXMsIHBTaGFkZXIpOwogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1BJWEVMU0hBREVSKTsKCiAgICAvKiBSZWJ1aWxkIHRoZSB0ZXh0dXJlIHVuaXQgbWFwcGluZyBpZiBudnJjJ3MgYXJlIHN1cHBvcnRlZCAqLwogICAgaWYoR0xfU1VQUE9SVChOVl9SRUdJU1RFUl9DT01CSU5FUlMpKSB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX0ZpbmRUZXhVbml0TWFwKFRoaXMpOwogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFBpeGVsU2hhZGVyKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RQaXhlbFNoYWRlciAqKnBwU2hhZGVyKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgaWYgKE5VTEwgPT0gcHBTaGFkZXIpIHsKICAgICAgICBXQVJOKCIoJXApIDogUFNoYWRlciBpcyBOVUxMLCByZXR1cm5pbmcgSU5WQUxJRENBTExcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgICpwcFNoYWRlciA9ICBUaGlzLT5zdGF0ZUJsb2NrLT5waXhlbFNoYWRlcjsKICAgIGlmIChOVUxMICE9ICpwcFNoYWRlcikgewogICAgICAgIElXaW5lRDNEUGl4ZWxTaGFkZXJfQWRkUmVmKCpwcFNoYWRlcik7CiAgICB9CiAgICBUUkFDRSgiKCVwKSA6IHJldHVybmluZyAlcFxuIiwgVGhpcywgKnBwU2hhZGVyKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFBpeGVsU2hhZGVyQ29uc3RhbnRCKAogICAgSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgVUlOVCBzdGFydCwKICAgIENPTlNUIEJPT0wgKnNyY0RhdGEsCiAgICBVSU5UIGNvdW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaW50IGksIGNudCA9IG1pbihjb3VudCwgTUFYX0NPTlNUX0IgLSBzdGFydCk7CgogICAgVFJBQ0UoIihpZmFjZSAlcCwgc3JjRGF0YSAlcCwgc3RhcnQgJWQsIGNvdW50ICVkKVxuIiwKICAgICAgICAgICAgaWZhY2UsIHNyY0RhdGEsIHN0YXJ0LCBjb3VudCk7CgogICAgaWYgKHNyY0RhdGEgPT0gTlVMTCB8fCBjbnQgPCAwKQogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIG1lbWNweSgmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+cGl4ZWxTaGFkZXJDb25zdGFudEJbc3RhcnRdLCBzcmNEYXRhLCBjbnQgKiBzaXplb2YoQk9PTCkpOwogICAgZm9yIChpID0gMDsgaSA8IGNudDsgaSsrKQogICAgICAgIFRSQUNFKCJTZXQgQk9PTCBjb25zdGFudCAldSB0byAlc1xuIiwgc3RhcnQgKyBpLCBzcmNEYXRhW2ldPyAidHJ1ZSI6ImZhbHNlIik7CgogICAgZm9yIChpID0gc3RhcnQ7IGkgPCBjbnQgKyBzdGFydDsgKytpKSB7CiAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC5waXhlbFNoYWRlckNvbnN0YW50c0JbaV0gPSBUUlVFOwogICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnNldC5waXhlbFNoYWRlckNvbnN0YW50c0JbaV0gICAgID0gVFJVRTsKICAgIH0KCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfUElYRUxTSEFERVJDT05TVEFOVCk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0UGl4ZWxTaGFkZXJDb25zdGFudEIoCiAgICBJV2luZUQzRERldmljZSAqaWZhY2UsCiAgICBVSU5UIHN0YXJ0LAogICAgQk9PTCAqZHN0RGF0YSwKICAgIFVJTlQgY291bnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpbnQgY250ID0gbWluKGNvdW50LCBNQVhfQ09OU1RfQiAtIHN0YXJ0KTsKCiAgICBUUkFDRSgiKGlmYWNlICVwLCBkc3REYXRhICVwLCBzdGFydCAlZCwgY291bnQgJWQpXG4iLAogICAgICAgICAgICBpZmFjZSwgZHN0RGF0YSwgc3RhcnQsIGNvdW50KTsKCiAgICBpZiAoZHN0RGF0YSA9PSBOVUxMIHx8IGNudCA8IDApCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgbWVtY3B5KGRzdERhdGEsICZUaGlzLT5zdGF0ZUJsb2NrLT5waXhlbFNoYWRlckNvbnN0YW50QltzdGFydF0sIGNudCAqIHNpemVvZihCT09MKSk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRQaXhlbFNoYWRlckNvbnN0YW50SSgKICAgIElXaW5lRDNERGV2aWNlICppZmFjZSwKICAgIFVJTlQgc3RhcnQsCiAgICBDT05TVCBpbnQgKnNyY0RhdGEsCiAgICBVSU5UIGNvdW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaW50IGksIGNudCA9IG1pbihjb3VudCwgTUFYX0NPTlNUX0kgLSBzdGFydCk7CgogICAgVFJBQ0UoIihpZmFjZSAlcCwgc3JjRGF0YSAlcCwgc3RhcnQgJWQsIGNvdW50ICVkKVxuIiwKICAgICAgICAgICAgaWZhY2UsIHNyY0RhdGEsIHN0YXJ0LCBjb3VudCk7CgogICAgaWYgKHNyY0RhdGEgPT0gTlVMTCB8fCBjbnQgPCAwKQogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIG1lbWNweSgmVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+cGl4ZWxTaGFkZXJDb25zdGFudElbc3RhcnQgKiA0XSwgc3JjRGF0YSwgY250ICogc2l6ZW9mKGludCkgKiA0KTsKICAgIGZvciAoaSA9IDA7IGkgPCBjbnQ7IGkrKykKICAgICAgICBUUkFDRSgiU2V0IElOVCBjb25zdGFudCAldSB0byB7ICVkLCAlZCwgJWQsICVkIH1cbiIsIHN0YXJ0ICsgaSwKICAgICAgICAgICBzcmNEYXRhW2kqNF0sIHNyY0RhdGFbaSo0KzFdLCBzcmNEYXRhW2kqNCsyXSwgc3JjRGF0YVtpKjQrM10pOwoKICAgIGZvciAoaSA9IHN0YXJ0OyBpIDwgY250ICsgc3RhcnQ7ICsraSkgewogICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQucGl4ZWxTaGFkZXJDb25zdGFudHNJW2ldID0gVFJVRTsKICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQucGl4ZWxTaGFkZXJDb25zdGFudHNJW2ldICAgICA9IFRSVUU7CiAgICB9CgogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1BJWEVMU0hBREVSQ09OU1RBTlQpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFBpeGVsU2hhZGVyQ29uc3RhbnRJKAogICAgSVdpbmVEM0REZXZpY2UgKmlmYWNlLAogICAgVUlOVCBzdGFydCwKICAgIGludCAqZHN0RGF0YSwKICAgIFVJTlQgY291bnQpIHsKCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBpbnQgY250ID0gbWluKGNvdW50LCBNQVhfQ09OU1RfSSAtIHN0YXJ0KTsKCiAgICBUUkFDRSgiKGlmYWNlICVwLCBkc3REYXRhICVwLCBzdGFydCAlZCwgY291bnQgJWQpXG4iLAogICAgICAgICAgICBpZmFjZSwgZHN0RGF0YSwgc3RhcnQsIGNvdW50KTsKCiAgICBpZiAoZHN0RGF0YSA9PSBOVUxMIHx8IGNudCA8IDApCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CgogICAgbWVtY3B5KGRzdERhdGEsICZUaGlzLT5zdGF0ZUJsb2NrLT5waXhlbFNoYWRlckNvbnN0YW50SVtzdGFydCAqIDRdLCBjbnQgKiBzaXplb2YoaW50KSAqIDQpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0UGl4ZWxTaGFkZXJDb25zdGFudEYoCiAgICBJV2luZUQzRERldmljZSAqaWZhY2UsCiAgICBVSU5UIHN0YXJ0LAogICAgQ09OU1QgZmxvYXQgKnNyY0RhdGEsCiAgICBVSU5UIGNvdW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaW50IGk7CgogICAgVFJBQ0UoIihpZmFjZSAlcCwgc3JjRGF0YSAlcCwgc3RhcnQgJWQsIGNvdW50ICVkKVxuIiwKICAgICAgICAgICAgaWZhY2UsIHNyY0RhdGEsIHN0YXJ0LCBjb3VudCk7CgogICAgLyogU3BlY2lmaWNhbGx5IHRlc3Qgc3RhcnQgPiBsaW1pdCB0byBjYXRjaCBNQVhfVUlOVCBvdmVyZmxvd3Mgd2hlbiBhZGRpbmcgc3RhcnQgKyBjb3VudCAqLwogICAgaWYgKHNyY0RhdGEgPT0gTlVMTCB8fCBzdGFydCArIGNvdW50ID4gR0xfTElNSVRTKHBzaGFkZXJfY29uc3RhbnRzRikgfHwgc3RhcnQgPiBHTF9MSU1JVFMocHNoYWRlcl9jb25zdGFudHNGKSkKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKCiAgICBtZW1jcHkoJlRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnBpeGVsU2hhZGVyQ29uc3RhbnRGW3N0YXJ0ICogNF0sIHNyY0RhdGEsIGNvdW50ICogc2l6ZW9mKGZsb2F0KSAqIDQpOwogICAgaWYoVFJBQ0VfT04oZDNkKSkgewogICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb3VudDsgaSsrKQogICAgICAgICAgICBUUkFDRSgiU2V0IEZMT0FUIGNvbnN0YW50ICV1IHRvIHsgJWYsICVmLCAlZiwgJWYgfVxuIiwgc3RhcnQgKyBpLAogICAgICAgICAgICAgICAgc3JjRGF0YVtpKjRdLCBzcmNEYXRhW2kqNCsxXSwgc3JjRGF0YVtpKjQrMl0sIHNyY0RhdGFbaSo0KzNdKTsKICAgIH0KCiAgICBmb3IgKGkgPSBzdGFydDsgaSA8IGNvdW50ICsgc3RhcnQ7ICsraSkgewogICAgICAgIGlmICghVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0LnBpeGVsU2hhZGVyQ29uc3RhbnRzRltpXSkgewogICAgICAgICAgICBjb25zdGFudHNfZW50cnkgKnB0ciA9IExJU1RfRU5UUlkobGlzdF9oZWFkKCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXRfcGNvbnN0YW50c0YpLCBjb25zdGFudHNfZW50cnksIGVudHJ5KTsKICAgICAgICAgICAgaWYgKCFwdHIgfHwgcHRyLT5jb3VudCA+PSBzaXplb2YocHRyLT5pZHgpIC8gc2l6ZW9mKCpwdHItPmlkeCkpIHsKICAgICAgICAgICAgICAgIHB0ciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoY29uc3RhbnRzX2VudHJ5KSk7CiAgICAgICAgICAgICAgICBsaXN0X2FkZF9oZWFkKCZUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXRfcGNvbnN0YW50c0YsICZwdHItPmVudHJ5KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwdHItPmlkeFtwdHItPmNvdW50KytdID0gaTsKICAgICAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c2V0LnBpeGVsU2hhZGVyQ29uc3RhbnRzRltpXSA9IFRSVUU7CiAgICAgICAgfQogICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPmNoYW5nZWQucGl4ZWxTaGFkZXJDb25zdGFudHNGW2ldID0gVFJVRTsKICAgIH0KCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfUElYRUxTSEFERVJDT05TVEFOVCk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0UGl4ZWxTaGFkZXJDb25zdGFudEYoCiAgICBJV2luZUQzRERldmljZSAqaWZhY2UsCiAgICBVSU5UIHN0YXJ0LAogICAgZmxvYXQgKmRzdERhdGEsCiAgICBVSU5UIGNvdW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaW50IGNudCA9IG1pbihjb3VudCwgR0xfTElNSVRTKHBzaGFkZXJfY29uc3RhbnRzRikgLSBzdGFydCk7CgogICAgVFJBQ0UoIihpZmFjZSAlcCwgZHN0RGF0YSAlcCwgc3RhcnQgJWQsIGNvdW50ICVkKVxuIiwKICAgICAgICAgICAgaWZhY2UsIGRzdERhdGEsIHN0YXJ0LCBjb3VudCk7CgogICAgaWYgKGRzdERhdGEgPT0gTlVMTCB8fCBjbnQgPCAwKQogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIG1lbWNweShkc3REYXRhLCAmVGhpcy0+c3RhdGVCbG9jay0+cGl4ZWxTaGFkZXJDb25zdGFudEZbc3RhcnQgKiA0XSwgY250ICogc2l6ZW9mKGZsb2F0KSAqIDQpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCiNkZWZpbmUgY29weV9hbmRfbmV4dChkZXN0LCBzcmMsIHNpemUpIG1lbWNweShkZXN0LCBzcmMsIHNpemUpOyBkZXN0ICs9IChzaXplKQpzdGF0aWMgSFJFU1VMVApwcm9jZXNzX3ZlcnRpY2VzX3N0cmlkZWQoSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzLCBEV09SRCBkd0Rlc3RJbmRleCwgRFdPUkQgZHdDb3VudCwgV2luZURpcmVjdDNEVmVydGV4U3RyaWRlZERhdGEgKmxwU3RyaWRlRGF0YSwgRFdPUkQgU3JjRlZGLCBJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKmRlc3QsIERXT1JEIGR3RmxhZ3MpIHsKICAgIGNoYXIgKmRlc3RfcHRyLCAqZGVzdF9jb252ID0gTlVMTCwgKmRlc3RfY29udl9hZGRyID0gTlVMTDsKICAgIHVuc2lnbmVkIGludCBpOwogICAgRFdPUkQgRGVzdEZWRiA9IGRlc3QtPmZ2ZjsKICAgIFdJTkVEM0RWSUVXUE9SVCB2cDsKICAgIFdJTkVEM0RNQVRSSVggbWF0LCBwcm9qX21hdCwgdmlld19tYXQsIHdvcmxkX21hdDsKICAgIEJPT0wgZG9DbGlwOwogICAgaW50IG51bVRleHR1cmVzOwoKICAgIGlmIChTcmNGVkYgJiBXSU5FRDNERlZGX05PUk1BTCkgewogICAgICAgIFdBUk4oIiBsaWdodGluZyBzdGF0ZSBub3Qgc2F2ZWQgeWV0Li4uIFNvbWUgc3RyYW5nZSBzdHVmZiBtYXkgaGFwcGVuICFcbiIpOwogICAgfQoKICAgIGlmICggKFNyY0ZWRiAmIFdJTkVEM0RGVkZfUE9TSVRJT05fTUFTSykgIT0gV0lORUQzREZWRl9YWVopIHsKICAgICAgICBFUlIoIlNvdXJjZSBoYXMgbm8gcG9zaXRpb24gbWFza1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogV2UgbWlnaHQgYWNjZXNzIFZCT3MgZnJvbSB0aGlzIGNvZGUsIHNvIGhvbGQgdGhlIGxvY2sgKi8KICAgIEVOVEVSX0dMKCk7CgogICAgaWYgKGRlc3QtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9PSBOVUxMKSB7CiAgICAgICAgLyogVGhpcyBtYXkgaGFwcGVuIGlmIHdlIGRvIGRpcmVjdCBsb2NraW5nIGludG8gYSB2Ym8uIFVubGlrZWx5LAogICAgICAgICAqIGJ1dCB0aGVvcmV0aWNhbGx5IHBvc3NpYmxlKGRkcmF3IHByb2Nlc3N2ZXJ0aWNlcyB0ZXN0KQogICAgICAgICAqLwogICAgICAgIGRlc3QtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBkZXN0LT5yZXNvdXJjZS5zaXplKTsKICAgICAgICBpZighZGVzdC0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KSB7CiAgICAgICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeVxuIik7CiAgICAgICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwogICAgICAgIH0KICAgICAgICBpZihkZXN0LT52Ym8pIHsKICAgICAgICAgICAgdm9pZCAqc3JjOwogICAgICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9BUlJBWV9CVUZGRVJfQVJCLCBkZXN0LT52Ym8pKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZEJ1ZmZlckFSQiIpOwogICAgICAgICAgICBzcmMgPSBHTF9FWFRDQUxMKGdsTWFwQnVmZmVyQVJCKEdMX0FSUkFZX0JVRkZFUl9BUkIsIEdMX1JFQURfT05MWV9BUkIpKTsKICAgICAgICAgICAgaWYoc3JjKSB7CiAgICAgICAgICAgICAgICBtZW1jcHkoZGVzdC0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5LCBzcmMsIGRlc3QtPnJlc291cmNlLnNpemUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xVbm1hcEJ1ZmZlckFSQihHTF9BUlJBWV9CVUZGRVJfQVJCKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFVubWFwQnVmZmVyQVJCIik7CiAgICAgICAgfQogICAgfQoKICAgIC8qIEdldCBhIHBvaW50ZXIgaW50byB0aGUgZGVzdGluYXRpb24gdmJvKGNyZWF0ZSBvbmUgaWYgbm9uZSBleGlzdHMpIGFuZAogICAgICogd3JpdGUgY29ycmVjdCBvcGVuZ2wgZGF0YSBpbnRvIGl0LiBJdCdzIGNoZWFwIGFuZCBhbGxvd3MgdXMgdG8gcnVuIGRyYXdTdHJpZGVkRmFzdAogICAgICovCiAgICBpZighZGVzdC0+dmJvICYmIEdMX1NVUFBPUlQoQVJCX1ZFUlRFWF9CVUZGRVJfT0JKRUNUKSkgewogICAgICAgIENyZWF0ZVZCTyhkZXN0KTsKICAgIH0KCiAgICBpZihkZXN0LT52Ym8pIHsKICAgICAgICBkZXN0X2NvbnZfYWRkciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBkd0NvdW50ICogZ2V0X2ZsZXhpYmxlX3ZlcnRleF9zaXplKERlc3RGVkYpKTsKICAgICAgICBpZighZGVzdF9jb252X2FkZHIpIHsKICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5XG4iKTsKICAgICAgICAgICAgLyogQ29udGludWUgd2l0aG91dCBzdG9yaW5nIGNvbnZlcnRlZCB2ZXJ0aWNlcyAqLwogICAgICAgIH0KICAgICAgICBkZXN0X2NvbnYgPSBkZXN0X2NvbnZfYWRkcjsKICAgIH0KCiAgICAvKiBTaG91bGQgSSBjbGlwPwogICAgICogYSkgV0lORUQzRFJTX0NMSVBQSU5HIGlzIGVuYWJsZWQKICAgICAqIGIpIFdJTkVEM0RWT1BfQ0xJUCBpcyBwYXNzZWQKICAgICAqLwogICAgaWYoVGhpcy0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbV0lORUQzRFJTX0NMSVBQSU5HXSkgewogICAgICAgIHN0YXRpYyBCT09MIHdhcm5lZCA9IEZBTFNFOwogICAgICAgIC8qCiAgICAgICAgICogVGhlIGNsaXBwaW5nIGNvZGUgaXMgbm90IHF1aXRlIGNvcnJlY3QuIFNvbWUgdGhpbmdzIG5lZWQKICAgICAgICAgKiB0byBiZSBjaGVja2VkIGFnYWluc3QgSURpcmVjdDNERGV2aWNlMyAoISksIGQzZDggYW5kIGQzZDksCiAgICAgICAgICogc28gZGlzYWJsZSBjbGlwcGluZyBmb3Igbm93LgogICAgICAgICAqIChUaGUgZ3JhcGhpY3MgaW4gSGFsZi1MaWZlIGFyZSBicm9rZW4sIGFuZCBteSBwcm9jZXNzdmVydGljZXMKICAgICAgICAgKiAgdGVzdCBjcmFzaGVzIHdpdGggSURpcmVjdDNERGV2aWNlMykKICAgICAgICBkb0NsaXAgPSBUUlVFOwogICAgICAgICAqLwogICAgICAgIGRvQ2xpcCA9IEZBTFNFOwogICAgICAgIGlmKCF3YXJuZWQpIHsKICAgICAgICAgICB3YXJuZWQgPSBUUlVFOwogICAgICAgICAgIEZJWE1FKCJDbGlwcGluZyBpcyBicm9rZW4gYW5kIGRpc2FibGVkIGZvciBub3dcbiIpOwogICAgICAgIH0KICAgIH0gZWxzZSBkb0NsaXAgPSBGQUxTRTsKICAgIGRlc3RfcHRyID0gKChjaGFyICopIGRlc3QtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgKyBkd0Rlc3RJbmRleCAqIGdldF9mbGV4aWJsZV92ZXJ0ZXhfc2l6ZShEZXN0RlZGKTsKCiAgICBJV2luZUQzRERldmljZV9HZXRUcmFuc2Zvcm0oIChJV2luZUQzRERldmljZSAqKSBUaGlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNEVFNfVklFVywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnZpZXdfbWF0KTsKICAgIElXaW5lRDNERGV2aWNlX0dldFRyYW5zZm9ybSggKElXaW5lRDNERGV2aWNlICopIFRoaXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RUU19QUk9KRUNUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcHJval9tYXQpOwogICAgSVdpbmVEM0REZXZpY2VfR2V0VHJhbnNmb3JtKCAoSVdpbmVEM0REZXZpY2UgKikgVGhpcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFRTX1dPUkxETUFUUklYKDApLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmd29ybGRfbWF0KTsKCiAgICBUUkFDRSgiVmlldyBtYXQ6XG4iKTsKICAgIFRSQUNFKCIlZiAlZiAlZiAlZlxuIiwgdmlld19tYXQudS5zLl8xMSwgdmlld19tYXQudS5zLl8xMiwgdmlld19tYXQudS5zLl8xMywgdmlld19tYXQudS5zLl8xNCk7CiAgICBUUkFDRSgiJWYgJWYgJWYgJWZcbiIsIHZpZXdfbWF0LnUucy5fMjEsIHZpZXdfbWF0LnUucy5fMjIsIHZpZXdfbWF0LnUucy5fMjMsIHZpZXdfbWF0LnUucy5fMjQpOwogICAgVFJBQ0UoIiVmICVmICVmICVmXG4iLCB2aWV3X21hdC51LnMuXzMxLCB2aWV3X21hdC51LnMuXzMyLCB2aWV3X21hdC51LnMuXzMzLCB2aWV3X21hdC51LnMuXzM0KTsKICAgIFRSQUNFKCIlZiAlZiAlZiAlZlxuIiwgdmlld19tYXQudS5zLl80MSwgdmlld19tYXQudS5zLl80Miwgdmlld19tYXQudS5zLl80Mywgdmlld19tYXQudS5zLl80NCk7CgogICAgVFJBQ0UoIlByb2ogbWF0OlxuIik7CiAgICBUUkFDRSgiJWYgJWYgJWYgJWZcbiIsIHByb2pfbWF0LnUucy5fMTEsIHByb2pfbWF0LnUucy5fMTIsIHByb2pfbWF0LnUucy5fMTMsIHByb2pfbWF0LnUucy5fMTQpOwogICAgVFJBQ0UoIiVmICVmICVmICVmXG4iLCBwcm9qX21hdC51LnMuXzIxLCBwcm9qX21hdC51LnMuXzIyLCBwcm9qX21hdC51LnMuXzIzLCBwcm9qX21hdC51LnMuXzI0KTsKICAgIFRSQUNFKCIlZiAlZiAlZiAlZlxuIiwgcHJval9tYXQudS5zLl8zMSwgcHJval9tYXQudS5zLl8zMiwgcHJval9tYXQudS5zLl8zMywgcHJval9tYXQudS5zLl8zNCk7CiAgICBUUkFDRSgiJWYgJWYgJWYgJWZcbiIsIHByb2pfbWF0LnUucy5fNDEsIHByb2pfbWF0LnUucy5fNDIsIHByb2pfbWF0LnUucy5fNDMsIHByb2pfbWF0LnUucy5fNDQpOwoKICAgIFRSQUNFKCJXb3JsZCBtYXQ6XG4iKTsKICAgIFRSQUNFKCIlZiAlZiAlZiAlZlxuIiwgd29ybGRfbWF0LnUucy5fMTEsIHdvcmxkX21hdC51LnMuXzEyLCB3b3JsZF9tYXQudS5zLl8xMywgd29ybGRfbWF0LnUucy5fMTQpOwogICAgVFJBQ0UoIiVmICVmICVmICVmXG4iLCB3b3JsZF9tYXQudS5zLl8yMSwgd29ybGRfbWF0LnUucy5fMjIsIHdvcmxkX21hdC51LnMuXzIzLCB3b3JsZF9tYXQudS5zLl8yNCk7CiAgICBUUkFDRSgiJWYgJWYgJWYgJWZcbiIsIHdvcmxkX21hdC51LnMuXzMxLCB3b3JsZF9tYXQudS5zLl8zMiwgd29ybGRfbWF0LnUucy5fMzMsIHdvcmxkX21hdC51LnMuXzM0KTsKICAgIFRSQUNFKCIlZiAlZiAlZiAlZlxuIiwgd29ybGRfbWF0LnUucy5fNDEsIHdvcmxkX21hdC51LnMuXzQyLCB3b3JsZF9tYXQudS5zLl80Mywgd29ybGRfbWF0LnUucy5fNDQpOwoKICAgIC8qIEdldCB0aGUgdmlld3BvcnQgKi8KICAgIElXaW5lRDNERGV2aWNlX0dldFZpZXdwb3J0KCAoSVdpbmVEM0REZXZpY2UgKikgVGhpcywgJnZwKTsKICAgIFRSQUNFKCJWaWV3cG9ydDogWD0lZCwgWT0lZCwgV2lkdGg9JWQsIEhlaWdodD0lZCwgTWluWj0lZiwgTWF4Wj0lZlxuIiwKICAgICAgICAgIHZwLlgsIHZwLlksIHZwLldpZHRoLCB2cC5IZWlnaHQsIHZwLk1pblosIHZwLk1heFopOwoKICAgIG11bHRpcGx5X21hdHJpeCgmbWF0LCZ2aWV3X21hdCwmd29ybGRfbWF0KTsKICAgIG11bHRpcGx5X21hdHJpeCgmbWF0LCZwcm9qX21hdCwmbWF0KTsKCiAgICBudW1UZXh0dXJlcyA9IChEZXN0RlZGICYgV0lORUQzREZWRl9URVhDT1VOVF9NQVNLKSA+PiBXSU5FRDNERlZGX1RFWENPVU5UX1NISUZUOwoKICAgIGZvciAoaSA9IDA7IGkgPCBkd0NvdW50OyBpKz0gMSkgewogICAgICAgIHVuc2lnbmVkIGludCB0ZXhfaW5kZXg7CgogICAgICAgIGlmICggKChEZXN0RlZGICYgV0lORUQzREZWRl9QT1NJVElPTl9NQVNLKSA9PSBXSU5FRDNERlZGX1hZWiApIHx8CiAgICAgICAgICAgICAoKERlc3RGVkYgJiBXSU5FRDNERlZGX1BPU0lUSU9OX01BU0spID09IFdJTkVEM0RGVkZfWFlaUkhXICkgKSB7CiAgICAgICAgICAgIC8qIFRoZSBwb3NpdGlvbiBmaXJzdCAqLwogICAgICAgICAgICBmbG9hdCAqcCA9CiAgICAgICAgICAgICAgKGZsb2F0ICopICgoKGNoYXIgKikgbHBTdHJpZGVEYXRhLT51LnMucG9zaXRpb24ubHBEYXRhKSArIGkgKiBscFN0cmlkZURhdGEtPnUucy5wb3NpdGlvbi5kd1N0cmlkZSk7CiAgICAgICAgICAgIGZsb2F0IHgsIHksIHosIHJodzsKICAgICAgICAgICAgVFJBQ0UoIkluOiAoICUwNi4yZiAlMDYuMmYgJTA2LjJmIClcbiIsIHBbMF0sIHBbMV0sIHBbMl0pOwoKICAgICAgICAgICAgLyogTXVsdGlwbGljYXRpb24gd2l0aCB3b3JsZCwgdmlldyBhbmQgcHJvamVjdGlvbiBtYXRyaXggKi8KICAgICAgICAgICAgeCA9ICAgKHBbMF0gKiBtYXQudS5zLl8xMSkgKyAocFsxXSAqIG1hdC51LnMuXzIxKSArIChwWzJdICogbWF0LnUucy5fMzEpICsgKDEuMCAqIG1hdC51LnMuXzQxKTsKICAgICAgICAgICAgeSA9ICAgKHBbMF0gKiBtYXQudS5zLl8xMikgKyAocFsxXSAqIG1hdC51LnMuXzIyKSArIChwWzJdICogbWF0LnUucy5fMzIpICsgKDEuMCAqIG1hdC51LnMuXzQyKTsKICAgICAgICAgICAgeiA9ICAgKHBbMF0gKiBtYXQudS5zLl8xMykgKyAocFsxXSAqIG1hdC51LnMuXzIzKSArIChwWzJdICogbWF0LnUucy5fMzMpICsgKDEuMCAqIG1hdC51LnMuXzQzKTsKICAgICAgICAgICAgcmh3ID0gKHBbMF0gKiBtYXQudS5zLl8xNCkgKyAocFsxXSAqIG1hdC51LnMuXzI0KSArIChwWzJdICogbWF0LnUucy5fMzQpICsgKDEuMCAqIG1hdC51LnMuXzQ0KTsKCiAgICAgICAgICAgIFRSQUNFKCJ4PSVmIHk9JWYgej0lZiByaHc9JWZcbiIsIHgsIHksIHosIHJodyk7CgogICAgICAgICAgICAvKiBXQVJOSU5HOiBUaGUgZm9sbG93aW5nIHRoaW5ncyBhcmUgdGFrZW4gZnJvbSBkM2Q3IGFuZCB3ZXJlIG5vdCB5ZXQgY2hlY2tlZAogICAgICAgICAgICAgKiBhZ2FpbnN0IGQzZDggb3IgZDNkOSEKICAgICAgICAgICAgICovCgogICAgICAgICAgICAvKiBDbGlwcGluZyBjb25kaXRpb25zOiBGcm9tCiAgICAgICAgICAgICAqIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vYXJjaGl2ZS9kZWZhdWx0LmFzcD91cmw9L2FyY2hpdmUvZW4tdXMvZGlyZWN0eDlfYy9kaXJlY3R4L2dyYXBoaWNzL3Byb2dyYW1taW5nZ3VpZGUvZml4ZWRmdW5jdGlvbi92aWV3cG9ydHNjbGlwcGluZy9jbGlwcGluZ3ZvbHVtZXMuYXNwCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEEgdmVydGV4IGlzIGNsaXBwZWQgaWYgaXQgZG9lcyBub3QgbWF0Y2ggdGhlIGZvbGxvd2luZyByZXF1aXJlbWVudHMKICAgICAgICAgICAgICogLXJodyA8IHggPD0gcmh3CiAgICAgICAgICAgICAqIC1yaHcgPCB5IDw9IHJodwogICAgICAgICAgICAgKiAgICAwIDwgeiA8PSByaHcKICAgICAgICAgICAgICogICAgMCA8IHJodyAoIE5vdCBpbiBkM2Q3LCBidXQgdGVzdGVkIGluIGQzZDcpCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIElmIGNsaXBwaW5nIGlzIG9uIGlzIGRldGVybWluZWQgYnkgdGhlIEQzRFZPUF9DTElQIGZsYWcgaW4gRDNENywgYW5kCiAgICAgICAgICAgICAqIGJ5IHRoZSBEM0RSU19DTElQUElORyBpbiBEM0Q5KGFjY29yZGluZyB0byB0aGUgbXNkbiwgbm90IGNoZWNrZWQpCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgaWYoICFkb0NsaXAgfHwKICAgICAgICAgICAgICAgICggKC1yaHcgLWVwcyA8IHgpICYmICgtcmh3IC1lcHMgPCB5KSAmJiAoIC1lcHMgPCB6KSAmJgogICAgICAgICAgICAgICAgICAoeCA8PSByaHcgKyBlcHMpICYmICh5IDw9IHJodyArIGVwcyApICYmICh6IDw9IHJodyArIGVwcykgJiYgCiAgICAgICAgICAgICAgICAgICggcmh3ID4gZXBzICkgKSApIHsKCiAgICAgICAgICAgICAgICAvKiAiTm9ybWFsIiB2aWV3cG9ydCB0cmFuc2Zvcm1hdGlvbiAobm90IGNsaXBwZWQpCiAgICAgICAgICAgICAgICAgKiAxKSBUaGUgdmFsdWVzIGFyZSBkaXZpZGVkIGJ5IHJodwogICAgICAgICAgICAgICAgICogMikgVGhlIHkgYXhpcyBpcyBuZWdhdGl2ZSwgc28gbXVsdGlwbHkgaXQgd2l0aCAtMQogICAgICAgICAgICAgICAgICogMykgU2NyZWVuIGNvb3JkaW5hdGVzIGdvIGZyb20gLShXaWR0aC8yKSB0byArKFdpZHRoLzIpIGFuZAogICAgICAgICAgICAgICAgICogICAgLShIZWlnaHQvMikgdG8gKyhIZWlnaHQvMikuIFRoZSB6IHJhbmdlIGlzIE1pblogdG8gTWF4WgogICAgICAgICAgICAgICAgICogNCkgTXVsdGlwbHkgeCB3aXRoIFdpZHRoLzIgYW5kIGFkZCBXaWR0aC8yCiAgICAgICAgICAgICAgICAgKiA1KSBUaGUgc2FtZSBmb3IgdGhlIGhlaWdodAogICAgICAgICAgICAgICAgICogNikgQWRkIHRoZSB2aWV3cG9pbnQgWCBhbmQgWSB0byB0aGUgMkQgY29vcmRpbmF0ZXMgYW5kCiAgICAgICAgICAgICAgICAgKiAgICBUaGUgbWluaW11bSBaIHZhbHVlIHRvIHoKICAgICAgICAgICAgICAgICAqIDcpIHJodyA9IDEgLyByaHcgUmVjaXByb2NhbCBvZiBIb21vZ2VuZW91cyBXLi4uLgogICAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgICAqIFdlbGwsIGJhc2ljYWxseSBpdCdzIHNpbXBseSBhIGxpbmVhciB0cmFuc2Zvcm1hdGlvbiBpbnRvIHZpZXdwb3J0CiAgICAgICAgICAgICAgICAgKiBjb29yZGluYXRlcwogICAgICAgICAgICAgICAgICovCgogICAgICAgICAgICAgICAgeCAvPSByaHc7CiAgICAgICAgICAgICAgICB5IC89IHJodzsKICAgICAgICAgICAgICAgIHogLz0gcmh3OwoKICAgICAgICAgICAgICAgIHkgKj0gLTE7CgogICAgICAgICAgICAgICAgeCAqPSB2cC5XaWR0aCAvIDI7CiAgICAgICAgICAgICAgICB5ICo9IHZwLkhlaWdodCAvIDI7CiAgICAgICAgICAgICAgICB6ICo9IHZwLk1heFogLSB2cC5NaW5aOwoKICAgICAgICAgICAgICAgIHggKz0gdnAuV2lkdGggLyAyICsgdnAuWDsKICAgICAgICAgICAgICAgIHkgKz0gdnAuSGVpZ2h0IC8gMiArIHZwLlk7CiAgICAgICAgICAgICAgICB6ICs9IHZwLk1pblo7CgogICAgICAgICAgICAgICAgcmh3ID0gMSAvIHJodzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8qIFRoYXQgdmVydGV4IGdvdCBjbGlwcGVkCiAgICAgICAgICAgICAgICAgKiBDb250cmFyeSB0byBPcGVuR0wgaXQgaXMgbm90IGRyb3BwZWQgY29tcGxldGVseSwgaXQganVzdAogICAgICAgICAgICAgICAgICogdW5kZXJnb2VzIGEgZGlmZmVyZW50IGNhbGN1bGF0aW9uLgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBUUkFDRSgiVmVydGV4IGdvdCBjbGlwcGVkXG4iKTsKICAgICAgICAgICAgICAgIHggKz0gcmh3OwogICAgICAgICAgICAgICAgeSArPSByaHc7CgogICAgICAgICAgICAgICAgeCAgLz0gMjsKICAgICAgICAgICAgICAgIHkgIC89IDI7CgogICAgICAgICAgICAgICAgLyogTXNkbiBtZW50aW9ucyB0aGF0IERpcmVjdDNEOSBrZWVwcyBhIGxpc3Qgb2YgY2xpcHBlZCB2ZXJ0aWNlcwogICAgICAgICAgICAgICAgICogb3V0c2lkZSBvZiB0aGUgbWFpbiB2ZXJ0ZXggYnVmZmVyIG1lbW9yeS4gVGhhdCBuZWVkcyBzb21lIG1vcmUKICAgICAgICAgICAgICAgICAqIGludmVzdGlnYXRpb24uLi4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICB9CgogICAgICAgICAgICBUUkFDRSgiV3JpdGluZyAoJWYgJWYgJWYpICVmXG4iLCB4LCB5LCB6LCByaHcpOwoKCiAgICAgICAgICAgICggKGZsb2F0ICopIGRlc3RfcHRyKVswXSA9IHg7CiAgICAgICAgICAgICggKGZsb2F0ICopIGRlc3RfcHRyKVsxXSA9IHk7CiAgICAgICAgICAgICggKGZsb2F0ICopIGRlc3RfcHRyKVsyXSA9IHo7CiAgICAgICAgICAgICggKGZsb2F0ICopIGRlc3RfcHRyKVszXSA9IHJodzsgLyogU0lDLCBzZWUgZGRyYXcgdGVzdCEgKi8KCiAgICAgICAgICAgIGRlc3RfcHRyICs9IDMgKiBzaXplb2YoZmxvYXQpOwoKICAgICAgICAgICAgaWYoKERlc3RGVkYgJiBXSU5FRDNERlZGX1BPU0lUSU9OX01BU0spID09IFdJTkVEM0RGVkZfWFlaUkhXKSB7CiAgICAgICAgICAgICAgICBkZXN0X3B0ciArPSBzaXplb2YoZmxvYXQpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZihkZXN0X2NvbnYpIHsKICAgICAgICAgICAgICAgIGZsb2F0IHcgPSAxIC8gcmh3OwogICAgICAgICAgICAgICAgKCAoZmxvYXQgKikgZGVzdF9jb252KVswXSA9IHggKiB3OwogICAgICAgICAgICAgICAgKCAoZmxvYXQgKikgZGVzdF9jb252KVsxXSA9IHkgKiB3OwogICAgICAgICAgICAgICAgKCAoZmxvYXQgKikgZGVzdF9jb252KVsyXSA9IHogKiB3OwogICAgICAgICAgICAgICAgKCAoZmxvYXQgKikgZGVzdF9jb252KVszXSA9IHc7CgogICAgICAgICAgICAgICAgZGVzdF9jb252ICs9IDMgKiBzaXplb2YoZmxvYXQpOwoKICAgICAgICAgICAgICAgIGlmKChEZXN0RlZGICYgV0lORUQzREZWRl9QT1NJVElPTl9NQVNLKSA9PSBXSU5FRDNERlZGX1hZWlJIVykgewogICAgICAgICAgICAgICAgICAgIGRlc3RfY29udiArPSBzaXplb2YoZmxvYXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChEZXN0RlZGICYgV0lORUQzREZWRl9QU0laRSkgewogICAgICAgICAgICBkZXN0X3B0ciArPSBzaXplb2YoRFdPUkQpOwogICAgICAgICAgICBpZihkZXN0X2NvbnYpIGRlc3RfY29udiArPSBzaXplb2YoRFdPUkQpOwogICAgICAgIH0KICAgICAgICBpZiAoRGVzdEZWRiAmIFdJTkVEM0RGVkZfTk9STUFMKSB7CiAgICAgICAgICAgIGZsb2F0ICpub3JtYWwgPQogICAgICAgICAgICAgIChmbG9hdCAqKSAoKChmbG9hdCAqKSBscFN0cmlkZURhdGEtPnUucy5ub3JtYWwubHBEYXRhKSArIGkgKiBscFN0cmlkZURhdGEtPnUucy5ub3JtYWwuZHdTdHJpZGUpOwogICAgICAgICAgICAvKiBBRkFJSyB0aGlzIHNob3VsZCBnbyBpbnRvIHRoZSBsaWdodGluZyBpbmZvcm1hdGlvbiAqLwogICAgICAgICAgICBGSVhNRSgiRGlkbid0IGV4cGVjdCB0aGUgZGVzdGluYXRpb24gdG8gaGF2ZSBhIG5vcm1hbFxuIik7CiAgICAgICAgICAgIGNvcHlfYW5kX25leHQoZGVzdF9wdHIsIG5vcm1hbCwgMyAqIHNpemVvZihmbG9hdCkpOwogICAgICAgICAgICBpZihkZXN0X2NvbnYpIHsKICAgICAgICAgICAgICAgIGNvcHlfYW5kX25leHQoZGVzdF9jb252LCBub3JtYWwsIDMgKiBzaXplb2YoZmxvYXQpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKERlc3RGVkYgJiBXSU5FRDNERlZGX0RJRkZVU0UpIHsKICAgICAgICAgICAgRFdPUkQgKmNvbG9yX2QgPSAKICAgICAgICAgICAgICAoRFdPUkQgKikgKCgoY2hhciAqKSBscFN0cmlkZURhdGEtPnUucy5kaWZmdXNlLmxwRGF0YSkgKyBpICogbHBTdHJpZGVEYXRhLT51LnMuZGlmZnVzZS5kd1N0cmlkZSk7CiAgICAgICAgICAgIGlmKCFjb2xvcl9kKSB7CiAgICAgICAgICAgICAgICBzdGF0aWMgQk9PTCB3YXJuZWQgPSBGQUxTRTsKCiAgICAgICAgICAgICAgICBpZighd2FybmVkKSB7CiAgICAgICAgICAgICAgICAgICAgRVJSKCJObyBkaWZmdXNlIGNvbG9yIGluIHNvdXJjZSwgYnV0IGRlc3RpbmF0aW9uIGhhcyBvbmVcbiIpOwogICAgICAgICAgICAgICAgICAgIHdhcm5lZCA9IFRSVUU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgKiggKERXT1JEICopIGRlc3RfcHRyKSA9IDB4ZmZmZmZmZmY7CiAgICAgICAgICAgICAgICBkZXN0X3B0ciArPSBzaXplb2YoRFdPUkQpOwoKICAgICAgICAgICAgICAgIGlmKGRlc3RfY29udikgewogICAgICAgICAgICAgICAgICAgICooIChEV09SRCAqKSBkZXN0X2NvbnYpID0gMHhmZmZmZmZmZjsKICAgICAgICAgICAgICAgICAgICBkZXN0X2NvbnYgKz0gc2l6ZW9mKERXT1JEKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgIGNvcHlfYW5kX25leHQoZGVzdF9wdHIsIGNvbG9yX2QsIHNpemVvZihEV09SRCkpOwogICAgICAgICAgICAgICAgaWYoZGVzdF9jb252KSB7CiAgICAgICAgICAgICAgICAgICAgKiggKERXT1JEICopIGRlc3RfY29udikgID0gKCpjb2xvcl9kICYgMHhmZjAwZmYwMCkgICAgICA7IC8qIEFscGhhICsgZ3JlZW4gKi8KICAgICAgICAgICAgICAgICAgICAqKCAoRFdPUkQgKikgZGVzdF9jb252KSB8PSAoKmNvbG9yX2QgJiAweDAwZmYwMDAwKSA+PiAxNjsgLyogUmVkICovCiAgICAgICAgICAgICAgICAgICAgKiggKERXT1JEICopIGRlc3RfY29udikgfD0gKCpjb2xvcl9kICYgMHhmZjAwMDBmZikgPDwgMTY7IC8qIEJsdWUgKi8KICAgICAgICAgICAgICAgICAgICBkZXN0X2NvbnYgKz0gc2l6ZW9mKERXT1JEKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKERlc3RGVkYgJiBXSU5FRDNERlZGX1NQRUNVTEFSKSB7IAogICAgICAgICAgICAvKiBXaGF0J3MgdGhlIGNvbG9yIHZhbHVlIGluIHRoZSBmZWVkYmFjayBidWZmZXI/ICovCiAgICAgICAgICAgIERXT1JEICpjb2xvcl9zID0gCiAgICAgICAgICAgICAgKERXT1JEICopICgoKGNoYXIgKikgbHBTdHJpZGVEYXRhLT51LnMuc3BlY3VsYXIubHBEYXRhKSArIGkgKiBscFN0cmlkZURhdGEtPnUucy5zcGVjdWxhci5kd1N0cmlkZSk7CiAgICAgICAgICAgIGlmKCFjb2xvcl9zKSB7CiAgICAgICAgICAgICAgICBzdGF0aWMgQk9PTCB3YXJuZWQgPSBGQUxTRTsKCiAgICAgICAgICAgICAgICBpZighd2FybmVkKSB7CiAgICAgICAgICAgICAgICAgICAgRVJSKCJObyBzcGVjdWxhciBjb2xvciBpbiBzb3VyY2UsIGJ1dCBkZXN0aW5hdGlvbiBoYXMgb25lXG4iKTsKICAgICAgICAgICAgICAgICAgICB3YXJuZWQgPSBUUlVFOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICooIChEV09SRCAqKSBkZXN0X3B0cikgPSAweEZGMDAwMDAwOwogICAgICAgICAgICAgICAgZGVzdF9wdHIgKz0gc2l6ZW9mKERXT1JEKTsKCiAgICAgICAgICAgICAgICBpZihkZXN0X2NvbnYpIHsKICAgICAgICAgICAgICAgICAgICAqKCAoRFdPUkQgKikgZGVzdF9jb252KSA9IDB4RkYwMDAwMDA7CiAgICAgICAgICAgICAgICAgICAgZGVzdF9jb252ICs9IHNpemVvZihEV09SRCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBjb3B5X2FuZF9uZXh0KGRlc3RfcHRyLCBjb2xvcl9zLCBzaXplb2YoRFdPUkQpKTsKICAgICAgICAgICAgICAgIGlmKGRlc3RfY29udikgewogICAgICAgICAgICAgICAgICAgICooIChEV09SRCAqKSBkZXN0X2NvbnYpICA9ICgqY29sb3JfcyAmIDB4ZmYwMGZmMDApICAgICAgOyAvKiBBbHBoYSArIGdyZWVuICovCiAgICAgICAgICAgICAgICAgICAgKiggKERXT1JEICopIGRlc3RfY29udikgfD0gKCpjb2xvcl9zICYgMHgwMGZmMDAwMCkgPj4gMTY7IC8qIFJlZCAqLwogICAgICAgICAgICAgICAgICAgICooIChEV09SRCAqKSBkZXN0X2NvbnYpIHw9ICgqY29sb3JfcyAmIDB4ZmYwMDAwZmYpIDw8IDE2OyAvKiBCbHVlICovCiAgICAgICAgICAgICAgICAgICAgZGVzdF9jb252ICs9IHNpemVvZihEV09SRCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGZvciAodGV4X2luZGV4ID0gMDsgdGV4X2luZGV4IDwgbnVtVGV4dHVyZXM7IHRleF9pbmRleCsrKSB7CiAgICAgICAgICAgIGZsb2F0ICp0ZXhfY29vcmQgPQogICAgICAgICAgICAgIChmbG9hdCAqKSAoKChjaGFyICopIGxwU3RyaWRlRGF0YS0+dS5zLnRleENvb3Jkc1t0ZXhfaW5kZXhdLmxwRGF0YSkgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgKiBscFN0cmlkZURhdGEtPnUucy50ZXhDb29yZHNbdGV4X2luZGV4XS5kd1N0cmlkZSk7CiAgICAgICAgICAgIGlmKCF0ZXhfY29vcmQpIHsKICAgICAgICAgICAgICAgIEVSUigiTm8gc291cmNlIHRleHR1cmUsIGJ1dCBkZXN0aW5hdGlvbiByZXF1ZXN0cyBvbmVcbiIpOwogICAgICAgICAgICAgICAgZGVzdF9wdHIrPUdFVF9URVhDT09SRF9TSVpFX0ZST01fRlZGKERlc3RGVkYsIHRleF9pbmRleCkgKiBzaXplb2YoZmxvYXQpOwogICAgICAgICAgICAgICAgaWYoZGVzdF9jb252KSBkZXN0X2NvbnYgKz0gR0VUX1RFWENPT1JEX1NJWkVfRlJPTV9GVkYoRGVzdEZWRiwgdGV4X2luZGV4KSAqIHNpemVvZihmbG9hdCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBjb3B5X2FuZF9uZXh0KGRlc3RfcHRyLCB0ZXhfY29vcmQsIEdFVF9URVhDT09SRF9TSVpFX0ZST01fRlZGKERlc3RGVkYsIHRleF9pbmRleCkgKiBzaXplb2YoZmxvYXQpKTsKICAgICAgICAgICAgICAgIGlmKGRlc3RfY29udikgewogICAgICAgICAgICAgICAgICAgIGNvcHlfYW5kX25leHQoZGVzdF9jb252LCB0ZXhfY29vcmQsIEdFVF9URVhDT09SRF9TSVpFX0ZST01fRlZGKERlc3RGVkYsIHRleF9pbmRleCkgKiBzaXplb2YoZmxvYXQpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBpZihkZXN0X2NvbnYpIHsKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9BUlJBWV9CVUZGRVJfQVJCLCBkZXN0LT52Ym8pKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kQnVmZmVyQVJCKEdMX0FSUkFZX0JVRkZFUl9BUkIpIik7CiAgICAgICAgR0xfRVhUQ0FMTChnbEJ1ZmZlclN1YkRhdGFBUkIoR0xfQVJSQVlfQlVGRkVSX0FSQiwgZHdEZXN0SW5kZXggKiBnZXRfZmxleGlibGVfdmVydGV4X3NpemUoRGVzdEZWRiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHdDb3VudCAqIGdldF9mbGV4aWJsZV92ZXJ0ZXhfc2l6ZShEZXN0RlZGKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXN0X2NvbnZfYWRkcikpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJ1ZmZlclN1YkRhdGFBUkIoR0xfQVJSQVlfQlVGRkVSX0FSQikiKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkZXN0X2NvbnZfYWRkcik7CiAgICB9CgogICAgTEVBVkVfR0woKTsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQojdW5kZWYgY29weV9hbmRfbmV4dAoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9Qcm9jZXNzVmVydGljZXMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIFNyY1N0YXJ0SW5kZXgsIFVJTlQgRGVzdEluZGV4LCBVSU5UIFZlcnRleENvdW50LCBJV2luZUQzRFZlcnRleEJ1ZmZlciogcERlc3RCdWZmZXIsIElXaW5lRDNEVmVydGV4QnVmZmVyKiBwVmVydGV4RGVjbCwgRFdPUkQgRmxhZ3MpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEVmVydGV4QnVmZmVySW1wbCAqU3JjSW1wbCA9IChJV2luZUQzRFZlcnRleEJ1ZmZlckltcGwgKikgcFZlcnRleERlY2w7CiAgICBXaW5lRGlyZWN0M0RWZXJ0ZXhTdHJpZGVkRGF0YSBzdHJpZGVkOwogICAgVFJBQ0UoIiglcCktPiglZCwlZCwlZCwlcCwlcCwlZFxuIiwgVGhpcywgU3JjU3RhcnRJbmRleCwgRGVzdEluZGV4LCBWZXJ0ZXhDb3VudCwgcERlc3RCdWZmZXIsIHBWZXJ0ZXhEZWNsLCBGbGFncyk7CgogICAgaWYgKCFTcmNJbXBsKSB7CiAgICAgICAgV0FSTigiTlVMTCBzb3VyY2UgdmVydGV4IGJ1ZmZlclxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogTmVlZCBhbnkgY29udGV4dCB0byB3cml0ZSB0byB0aGUgdmJvLiBJbiBhIG5vbi1tdWx0aXRocmVhZGVkIGVudmlyb25tZW50IGEgY29udGV4dCBpcyB0aGVyZSBhbnl3YXksCiAgICAgKiBhbmQgdGhpcyBjYWxsIGlzIHF1aXRlIHBlcmZvcm1hbmNlIGNyaXRpY2FsLCBzbyBkb24ndCBjYWxsIG5lZWRsZXNzbHkKICAgICAqLwogICAgaWYoVGhpcy0+Y3JlYXRlUGFybXMuQmVoYXZpb3JGbGFncyAmIFdJTkVEM0RDUkVBVEVfTVVMVElUSFJFQURFRCkgewogICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgQWN0aXZhdGVDb250ZXh0KFRoaXMsIFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQsIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CiAgICAgICAgTEVBVkVfR0woKTsKICAgIH0KCiAgICAvKiBXZSBkb24ndCBuZWVkIHRoZSBzb3VyY2UgdmJvIGJlY2F1c2UgdGhpcyBidWZmZXIgaXMgb25seSB1c2VkIGFzCiAgICAgKiBhIHNvdXJjZSBmb3IgUHJvY2Vzc1ZlcnRpY2VzLiBBdm9pZCB3YXN0aW5nIHJlc291cmNlcyBieSBjb252ZXJ0aW5nIHRoZQogICAgICogYnVmZmVyIGFuZCBsb2FkaW5nIHRoZSBWQk8KICAgICAqLwogICAgaWYoU3JjSW1wbC0+dmJvKSB7CiAgICAgICAgVFJBQ0UoIlJlbGVhc2luZyB0aGUgc291cmNlIHZibywgaXQgd29uJ3QgYmUgbmVlZGVkXG4iKTsKCiAgICAgICAgaWYoIVNyY0ltcGwtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSkgewogICAgICAgICAgICAvKiBSZXNjdWUgdGhlIGRhdGEgZnJvbSB0aGUgYnVmZmVyICovCiAgICAgICAgICAgIHZvaWQgKnNyYzsKICAgICAgICAgICAgU3JjSW1wbC0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIFNyY0ltcGwtPnJlc291cmNlLnNpemUpOwogICAgICAgICAgICBpZighU3JjSW1wbC0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KSB7CiAgICAgICAgICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnlcbiIpOwogICAgICAgICAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kQnVmZmVyQVJCKEdMX0FSUkFZX0JVRkZFUl9BUkIsIFNyY0ltcGwtPnZibykpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kQnVmZmVyQVJCIik7CgogICAgICAgICAgICBzcmMgPSBHTF9FWFRDQUxMKGdsTWFwQnVmZmVyQVJCKEdMX0FSUkFZX0JVRkZFUl9BUkIsIEdMX1JFQURfT05MWV9BUkIpKTsKICAgICAgICAgICAgaWYoc3JjKSB7CiAgICAgICAgICAgICAgICBtZW1jcHkoU3JjSW1wbC0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5LCBzcmMsIFNyY0ltcGwtPnJlc291cmNlLnNpemUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBHTF9FWFRDQUxMKGdsVW5tYXBCdWZmZXJBUkIoR0xfQVJSQVlfQlVGRkVSX0FSQikpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xVbm1hcEJ1ZmZlckFSQiIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIEVOVEVSX0dMKCk7CiAgICAgICAgfQoKICAgICAgICBHTF9FWFRDQUxMKGdsQmluZEJ1ZmZlckFSQihHTF9BUlJBWV9CVUZGRVJfQVJCLCAwKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZEJ1ZmZlckFSQiIpOwogICAgICAgIEdMX0VYVENBTEwoZ2xEZWxldGVCdWZmZXJzQVJCKDEsICZTcmNJbXBsLT52Ym8pKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEZWxldGVCdWZmZXJzQVJCIik7CiAgICAgICAgTEVBVkVfR0woKTsKCiAgICAgICAgU3JjSW1wbC0+dmJvID0gMDsKICAgIH0KCiAgICBtZW1zZXQoJnN0cmlkZWQsIDAsIHNpemVvZihzdHJpZGVkKSk7CiAgICBwcmltaXRpdmVDb252ZXJ0RlZGdG9PZmZzZXQoU3JjSW1wbC0+ZnZmLCBnZXRfZmxleGlibGVfdmVydGV4X3NpemUoU3JjSW1wbC0+ZnZmKSwgU3JjSW1wbC0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICsgZ2V0X2ZsZXhpYmxlX3ZlcnRleF9zaXplKFNyY0ltcGwtPmZ2ZikgKiBTcmNTdGFydEluZGV4LCAmc3RyaWRlZCwgMCwgMCk7CgogICAgcmV0dXJuIHByb2Nlc3NfdmVydGljZXNfc3RyaWRlZChUaGlzLCBEZXN0SW5kZXgsIFZlcnRleENvdW50LCAmc3RyaWRlZCwgU3JjSW1wbC0+ZnZmLCAoSVdpbmVEM0RWZXJ0ZXhCdWZmZXJJbXBsICopIHBEZXN0QnVmZmVyLCBGbGFncyk7Cn0KCi8qKioqKgogKiBHZXQgLyBTZXQgVGV4dHVyZSBTdGFnZSBTdGF0ZXMKICogVE9ETzogVmVyaWZ5IGFnYWluc3QgZHg5IGRlZmluaXRpb25zCiAqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXRUZXh0dXJlU3RhZ2VTdGF0ZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIFN0YWdlLCBXSU5FRDNEVEVYVFVSRVNUQUdFU1RBVEVUWVBFIFR5cGUsIERXT1JEIFZhbHVlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBEV09SRCBvbGRWYWx1ZSA9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRleHR1cmVTdGF0ZVtTdGFnZV1bVHlwZV07CgogICAgLyogRklYTUU6IEhhbmRsZSAzZCB0ZXh0dXJlcz8gV2hhdCBpZiBUU1MgdmFsdWUgc2V0IGJlZm9yZSBzZXQgdGV4dHVyZT8gTmVlZCB0byByZWFwcGx5IGFsbCB2YWx1ZXM/ICovCgogICAgVFJBQ0UoIiglcCkgOiBTdGFnZT0lZCwgVHlwZT0lcyglZCksIFZhbHVlPSVkXG4iLCBUaGlzLCBTdGFnZSwgZGVidWdfZDNkdGV4dHVyZXN0YXRlKFR5cGUpLCBUeXBlLCBWYWx1ZSk7CgogICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+Y2hhbmdlZC50ZXh0dXJlU3RhdGVbU3RhZ2VdW1R5cGVdID0gVFJVRTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnNldC50ZXh0dXJlU3RhdGVbU3RhZ2VdW1R5cGVdICAgICA9IFRSVUU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbU3RhZ2VdW1R5cGVdICAgICAgICAgPSBWYWx1ZTsKCiAgICBpZiAoVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSkgewogICAgICAgIFRSQUNFKCJSZWNvcmRpbmcuLi4gbm90IHBlcmZvcm1pbmcgYW55dGhpbmdcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNEX09LOwogICAgfQoKICAgIC8qIENoZWNrZWQgYWZ0ZXIgdGhlIGFzc2lnbm1lbnRzIHRvIGFsbG93IHByb3BlciBzdGF0ZWJsb2NrIHJlY29yZGluZyAqLwogICAgaWYob2xkVmFsdWUgPT0gVmFsdWUpIHsKICAgICAgICBUUkFDRSgiQXBwIGlzIHNldHRpbmcgdGhlIG9sZCB2YWx1ZSBvdmVyLCBub3RoaW5nIHRvIGRvXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBpZihTdGFnZSA+IFRoaXMtPnN0YXRlQmxvY2stPmxvd2VzdF9kaXNhYmxlZF9zdGFnZSAmJgogICAgICAgU3RhdGVUYWJsZVtTVEFURV9URVhUVVJFU1RBR0UoMCwgVHlwZSldLnJlcHJlc2VudGF0aXZlID09IFNUQVRFX1RFWFRVUkVTVEFHRSgwLCBXSU5FRDNEVFNTX0NPTE9ST1ApKSB7CiAgICAgICAgLyogQ29sb3JvcCBjaGFuZ2UgYWJvdmUgbG93ZXN0IGRpc2FibGVkIHN0YWdlPyBUaGF0IHdvbid0IGNoYW5nZSBhbnl0aGluZyBpbiB0aGUgZ2wgc2V0dXAKICAgICAgICAgKiBDaGFuZ2VzIGluIG90aGVyIHN0YXRlcyBhcmUgaW1wb3J0YW50IG9uIGRpc2FibGVkIHN0YWdlcyB0b28KICAgICAgICAgKi8KICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBpZihUeXBlID09IFdJTkVEM0RUU1NfQ09MT1JPUCkgewogICAgICAgIGludCBpOwoKICAgICAgICBpZihWYWx1ZSA9PSBXSU5FRDNEVE9QX0RJU0FCTEUgJiYgb2xkVmFsdWUgIT0gV0lORUQzRFRPUF9ESVNBQkxFKSB7CiAgICAgICAgICAgIC8qIFByZXZpb3VzbHkgZW5hYmxlZCBzdGFnZSBkaXNhYmxlZCBub3cuIE1ha2Ugc3VyZSB0byBkaXJ0aWZ5IGFsbCBlbmFibGVkIHN0YWdlcyBhYm92ZSBTdGFnZSwKICAgICAgICAgICAgICogdGhleSBoYXZlIHRvIGJlIGRpc2FibGVkCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIFRoZSBjdXJyZW50IHN0YWdlIGlzIGRpcnRpZmllZCBiZWxvdy4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGZvcihpID0gU3RhZ2UgKyAxOyBpIDwgVGhpcy0+c3RhdGVCbG9jay0+bG93ZXN0X2Rpc2FibGVkX3N0YWdlOyBpKyspIHsKICAgICAgICAgICAgICAgIFRSQUNFKCJBZGRpdGlvbmFsbHkgZGlydGlmeWluZyBzdGFnZSAlZFxuIiwgaSk7CiAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVEVYVFVSRVNUQUdFKGksIFdJTkVEM0RUU1NfQ09MT1JPUCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPmxvd2VzdF9kaXNhYmxlZF9zdGFnZSA9IFN0YWdlOwogICAgICAgICAgICBUUkFDRSgiTmV3IGxvd2VzdCBkaXNhYmxlZDogJWRcbiIsIFN0YWdlKTsKICAgICAgICB9IGVsc2UgaWYoVmFsdWUgIT0gV0lORUQzRFRPUF9ESVNBQkxFICYmIG9sZFZhbHVlID09IFdJTkVEM0RUT1BfRElTQUJMRSkgewogICAgICAgICAgICAvKiBQcmV2aW91c2x5IGRpc2FibGVkIHN0YWdlIGVuYWJsZWQuIFN0YWdlcyBhYm92ZSBpdCBtYXkgbmVlZCBlbmFibGluZwogICAgICAgICAgICAgKiBzdGFnZSBtdXN0IGJlIGxvd2VzdF9kaXNhYmxlZF9zdGFnZSBoZXJlLCBpZiBpdCdzIGJpZ2dlciBzdWNjZXNzIGlzIHJldHVybmVkIGFib3ZlLAogICAgICAgICAgICAgKiBhbmQgc3RhZ2VzIGJlbG93IHRoZSBsb3dlc3QgZGlzYWJsZWQgc3RhZ2UgY2FuJ3QgYmUgZW5hYmxlZChiZWNhdXNlIHRoZXkgYXJlIGVuYWJsZWQgYWxyZWFkeSkuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEFnYWluIHN0YWdlIFN0YWdlIGRvZXNuJ3QgbmVlZCB0byBiZSBkaXJ0aWZpZWQgaGVyZSwgaXQgaXMgaGFuZGxlZCBiZWxvdy4KICAgICAgICAgICAgICovCgogICAgICAgICAgICBmb3IoaSA9IFN0YWdlICsgMTsgaSA8IEdMX0xJTUlUUyh0ZXh0dXJlX3N0YWdlcyk7IGkrKykgewogICAgICAgICAgICAgICAgaWYoVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlW2ldW1dJTkVEM0RUU1NfQ09MT1JPUF0gPT0gV0lORUQzRFRPUF9ESVNBQkxFKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBUUkFDRSgiQWRkaXRpb25hbGx5IGRpcnRpZnlpbmcgc3RhZ2UgJWQgZHVlIHRvIGVuYWJsZVxuIiwgaSk7CiAgICAgICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVEVYVFVSRVNUQUdFKGksIFdJTkVEM0RUU1NfQ09MT1JPUCkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPmxvd2VzdF9kaXNhYmxlZF9zdGFnZSA9IGk7CiAgICAgICAgICAgIFRSQUNFKCJOZXcgbG93ZXN0IGRpc2FibGVkOiAlZFxuIiwgaSk7CiAgICAgICAgfQogICAgICAgIGlmKEdMX1NVUFBPUlQoTlZfUkVHSVNURVJfQ09NQklORVJTKSAmJiAhVGhpcy0+c3RhdGVCbG9jay0+cGl4ZWxTaGFkZXIpIHsKICAgICAgICAgICAgLyogVE9ETzogQnVpbHQgYSBzdGFnZSAtPiB0ZXh0dXJlIHVuaXQgbWFwcGluZyBmb3IgcmVnaXN0ZXIgY29tYmluZXJzICovCiAgICAgICAgfQogICAgfQoKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9URVhUVVJFU1RBR0UoU3RhZ2UsIFR5cGUpKTsKCiAgICAvKiBSZWJ1aWxkIHRoZSBzdGFnZSAtPiBnbCB0ZXh0dXJlIHVuaXQgbWFwcGluZyBpZiByZWdpc3RlciBjb21iaW5lcnMgYXJlIHN1cHBvcnRlZAogICAgICogSWYgdGhlcmUgaXMgYSBwaXhlbCBzaGFkZXIgdGhlcmUgd2lsbCBiZSBhIDE6MSBtYXBwaW5nLCBubyBuZWVkIHRvIHRvdWNoIGl0LiBTZXRQaXhlbFNoYWRlcgogICAgICogd2lsbCBjYWxsIEZpbmRUZXhVbml0TWFwIHRvby4KICAgICAqLwogICAgaWYoR0xfU1VQUE9SVChOVl9SRUdJU1RFUl9DT01CSU5FUlMpICYmICFUaGlzLT5zdGF0ZUJsb2NrLT5waXhlbFNoYWRlcikgewogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9GaW5kVGV4VW5pdE1hcChUaGlzKTsKICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldFRleHR1cmVTdGFnZVN0YXRlKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgU3RhZ2UsIFdJTkVEM0RURVhUVVJFU1RBR0VTVEFURVRZUEUgVHlwZSwgRFdPUkQqIHBWYWx1ZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiByZXF1ZXN0aW5nIFN0YWdlICVkLCBUeXBlICVkIGdldHRpbmcgJWRcbiIsIFRoaXMsIFN0YWdlLCBUeXBlLCBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbU3RhZ2VdW1R5cGVdKTsKICAgICpwVmFsdWUgPSBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbU3RhZ2VdW1R5cGVdOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBHZXQgLyBTZXQgVGV4dHVyZQogKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0VGV4dHVyZShJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIFN0YWdlLCBJV2luZUQzREJhc2VUZXh0dXJlKiBwVGV4dHVyZSkgewoKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEQmFzZVRleHR1cmUgICAqb2xkVGV4dHVyZTsKCiAgICBvbGRUZXh0dXJlID0gVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZXNbU3RhZ2VdOwogICAgVFJBQ0UoIiglcCkgOiBTdGFnZSglZCksIFRleHR1cmUgKCVwKVxuIiwgVGhpcywgU3RhZ2UsIHBUZXh0dXJlKTsKCiNpZiAwIC8qIFRPRE86IGNoZWNrIHNvIHZlcnRleCB0ZXh0dXJlcyAqLwogICAgaWYgKFN0YWdlID49IEQzRFZFUlRFWFRFWFRVUkVTQU1QTEVSICYmIFN0YWdlIDw9IEQzRFZFUlRFWFRFWFRVUkVTQU1QTEVSMyl7CiAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dmVydGV4VGV4dHVyZXNbU3RhZ2UgLSBEM0RWRVJURVhURVhUVVJFU0FNUExFUl0gPSBwVGV4dHVyZTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KI2VuZGlmCgogICAgaWYocFRleHR1cmUgIT0gTlVMTCkgewogICAgICAgIC8qIFNldFRleHR1cmUgaXNuJ3QgYWxsb3dlZCBvbiB0ZXh0dXJlcyBpbiBXSU5FRDNEUE9PTF9TQ1JBVENIOyAKICAgICAgICAgKi8KICAgICAgICBpZigoKElXaW5lRDNEVGV4dHVyZUltcGwqKXBUZXh0dXJlKS0+cmVzb3VyY2UucG9vbCA9PSBXSU5FRDNEUE9PTF9TQ1JBVENIKSB7CiAgICAgICAgICAgIFdBUk4oIiglcCkgQXR0ZW1wdCB0byBzZXQgc2NyYXRjaCB0ZXh0dXJlIHJlamVjdGVkXG4iLCBwVGV4dHVyZSk7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgIH0KICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT50ZXh0dXJlRGltZW5zaW9uc1tTdGFnZV0gPSBJV2luZUQzREJhc2VUZXh0dXJlX0dldFRleHR1cmVEaW1lbnNpb25zKHBUZXh0dXJlKTsKICAgIH0KCiAgICBUUkFDRSgiR0xfTElNSVRTICVkXG4iLEdMX0xJTUlUUyhzYW1wbGVyX3N0YWdlcykpOwogICAgVFJBQ0UoIiglcCkgOiBvbGR0ZXh0dXJlKCVwKVxuIiwgVGhpcyxvbGRUZXh0dXJlKTsKCiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5zZXQudGV4dHVyZXNbU3RhZ2VdICAgICA9IFRSVUU7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5jaGFuZ2VkLnRleHR1cmVzW1N0YWdlXSA9IFRSVUU7CiAgICBUUkFDRSgiKCVwKSA6IHNldHRpbmcgbmV3IHRleHR1cmUgdG8gJXBcbiIsIFRoaXMsIHBUZXh0dXJlKTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRleHR1cmVzW1N0YWdlXSAgICAgICAgID0gcFRleHR1cmU7CgogICAgLyogSGFuZGxlIHJlY29yZGluZyBvZiBzdGF0ZSBibG9ja3MgKi8KICAgIGlmIChUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgVFJBQ0UoIlJlY29yZGluZy4uLiBub3QgcGVyZm9ybWluZyBhbnl0aGluZ1xuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CiAgICB9CgogICAgaWYob2xkVGV4dHVyZSA9PSBwVGV4dHVyZSkgewogICAgICAgIFRSQUNFKCJBcHAgaXMgc2V0dGluZyB0aGUgc2FtZSB0ZXh0dXJlIGFnYWluLCBub3RoaW5nIHRvIGRvXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICAvKiogTk9URTogTVNETiBzYXlzIHRoYXQgc2V0VGV4dHVyZSBpbmNyZWFzZXMgdGhlIHJlZmVyZW5jZSBjb3VudCwKICAgICogYW5kIHRoZSB0aGUgYXBwbGljYXRpb24gbnVzdCBzZXQgdGhlIHRleHR1cmUgYmFjayB0byBudWxsIChvciBoYXZlIGEgbGVha3kgYXBwbGljYXRpb24pLAogICAgKiBUaGlzIG1lYW5zIHdlIHNob3VsZCBwYXNzIHRoZSByZWZjb3VudCB1cCB0byB0aGUgcGFyZW50CiAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgIGlmIChOVUxMICE9IFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRleHR1cmVzW1N0YWdlXSkgewogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsICpuZXcgPSAoSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKikgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZXNbU3RhZ2VdOwogICAgICAgIFVMT05HIGJpbmRDb3VudCA9IEludGVybG9ja2VkSW5jcmVtZW50KCZuZXctPmJhc2VUZXh0dXJlLmJpbmRDb3VudCk7CgogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfQWRkUmVmKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRleHR1cmVzW1N0YWdlXSk7CiAgICAgICAgaWYob2xkVGV4dHVyZSA9PSBOVUxMICYmIFN0YWdlIDwgTUFYX1RFWFRVUkVTKSB7CiAgICAgICAgICAgIC8qIFRoZSBzb3VyY2UgYXJndW1lbnRzIGZvciBjb2xvciBhbmQgYWxwaGEgb3BzIGhhdmUgZGlmZmVyZW50IG1lYW5pbmdzIHdoZW4gYSBOVUxMIHRleHR1cmUgaXMgYm91bmQsCiAgICAgICAgICAgICAqIHNvIHRoZSBDT0xPUk9QIGFuZCBBTFBIQU9QIGhhdmUgdG8gYmUgZGlydGlmaWVkLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1RFWFRVUkVTVEFHRShTdGFnZSwgV0lORUQzRFRTU19DT0xPUk9QKSk7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9URVhUVVJFU1RBR0UoU3RhZ2UsIFdJTkVEM0RUU1NfQUxQSEFPUCkpOwogICAgICAgIH0KICAgICAgICBpZihiaW5kQ291bnQgPT0gMSkgewogICAgICAgICAgICBuZXctPmJhc2VUZXh0dXJlLnNhbXBsZXIgPSBTdGFnZTsKICAgICAgICB9CiAgICAgICAgLyogTW9yZSB0aGFuIG9uZSBhc3NpZ25tZW50PyBEb2Vzbid0IG1hdHRlciwgd2Ugb25seSBuZWVkIG9uZSBnbCB0ZXh0dXJlIHVuaXQgdG8gdXNlIGZvciB1cGxvYWRpbmcgKi8KCiAgICB9CgogICAgaWYgKE5VTEwgIT0gb2xkVGV4dHVyZSkgewogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsICpvbGQgPSAoSVdpbmVEM0RCYXNlVGV4dHVyZUltcGwgKikgb2xkVGV4dHVyZTsKICAgICAgICBMT05HIGJpbmRDb3VudCA9IEludGVybG9ja2VkRGVjcmVtZW50KCZvbGQtPmJhc2VUZXh0dXJlLmJpbmRDb3VudCk7CgogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUmVsZWFzZShvbGRUZXh0dXJlKTsKICAgICAgICBpZihwVGV4dHVyZSA9PSBOVUxMICYmIFN0YWdlIDwgTUFYX1RFWFRVUkVTKSB7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9URVhUVVJFU1RBR0UoU3RhZ2UsIFdJTkVEM0RUU1NfQ09MT1JPUCkpOwogICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVEVYVFVSRVNUQUdFKFN0YWdlLCBXSU5FRDNEVFNTX0FMUEhBT1ApKTsKICAgICAgICB9CgogICAgICAgIGlmKGJpbmRDb3VudCAmJiBvbGQtPmJhc2VUZXh0dXJlLnNhbXBsZXIgPT0gU3RhZ2UpIHsKICAgICAgICAgICAgaW50IGk7CiAgICAgICAgICAgIC8qIEhhdmUgdG8gZG8gYSBzZWFyY2ggZm9yIHRoZSBvdGhlciBzYW1wbGVyKHMpIHdoZXJlIHRoZSB0ZXh0dXJlIGlzIGJvdW5kIHRvCiAgICAgICAgICAgICAqIFNob3VsZG4ndCBoYXBwZW4gYXMgbG9uZyBhcyBhcHBzIGJpbmQgYSB0ZXh0dXJlIG9ubHkgdG8gb25lIHN0YWdlCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBUUkFDRSgiU2VhcmNpbmcgZm9yIG90aGVyIHNhbXBsZXIgLyBzdGFnZSBpZCB3aGVyZSB0aGUgdGV4dHVyZSBpcyBib3VuZCB0b1xuIik7CiAgICAgICAgICAgIGZvcihpID0gMDsgaSA8IEdMX0xJTUlUUyhzYW1wbGVyX3N0YWdlcyk7IGkrKykgewogICAgICAgICAgICAgICAgaWYoVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+dGV4dHVyZXNbaV0gPT0gb2xkVGV4dHVyZSkgewogICAgICAgICAgICAgICAgICAgIG9sZC0+YmFzZVRleHR1cmUuc2FtcGxlciA9IGk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1NBTVBMRVIoU3RhZ2UpKTsKCiAgICAvKiBWZXJpZnkgdGhlIHRleHR1cmUgdW5pdCBtYXBwaW5nKGFuZCByZWJ1aWxkIGl0IGlmIG5lZWRlZCkgaWYgd2UgdXNlIG52cmNzIGFuZCBubwogICAgICogcGl4ZWwgc2hhZGVyIGlzIHVzZWQKICAgICAqLwogICAgaWYoR0xfU1VQUE9SVChOVl9SRUdJU1RFUl9DT01CSU5FUlMpICYmICFUaGlzLT5zdGF0ZUJsb2NrLT5waXhlbFNoYWRlcikgewogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9GaW5kVGV4VW5pdE1hcChUaGlzKTsKICAgIH0KCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRUZXh0dXJlKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQgU3RhZ2UsIElXaW5lRDNEQmFzZVRleHR1cmUqKiBwcFRleHR1cmUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogKCVkIC8qIFN0YWdlICovLCVwIC8qIHBwVGV4dHVyZSAqLylcbiIsIFRoaXMsIFN0YWdlLCBwcFRleHR1cmUpOwoKICAgICpwcFRleHR1cmU9VGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZXNbU3RhZ2VdOwogICAgaWYgKCpwcFRleHR1cmUpCiAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9BZGRSZWYoKnBwVGV4dHVyZSk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBHZXQgQmFjayBCdWZmZXIKICoqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldEJhY2tCdWZmZXIoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIGlTd2FwQ2hhaW4sIFVJTlQgQmFja0J1ZmZlciwgV0lORUQzREJBQ0tCVUZGRVJfVFlQRSBUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2UgKipwcEJhY2tCdWZmZXIpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3dhcENoYWluICpzd2FwQ2hhaW47CiAgICBIUkVTVUxUIGhyOwoKICAgIFRSQUNFKCIoJXApIDogQmFja0J1ZiAlZCBUeXBlICVkIFN3YXBDaGFpbiAlZCByZXR1cm5pbmcgJXBcbiIsIFRoaXMsIEJhY2tCdWZmZXIsIFR5cGUsIGlTd2FwQ2hhaW4sICpwcEJhY2tCdWZmZXIpOwoKICAgIGhyID0gSVdpbmVEM0REZXZpY2VJbXBsX0dldFN3YXBDaGFpbihpZmFjZSwgIGlTd2FwQ2hhaW4sICZzd2FwQ2hhaW4pOwogICAgaWYgKGhyID09IFdJTkVEM0RfT0spIHsKICAgICAgICBociA9IElXaW5lRDNEU3dhcENoYWluX0dldEJhY2tCdWZmZXIoc3dhcENoYWluLCBCYWNrQnVmZmVyLCBUeXBlLCBwcEJhY2tCdWZmZXIpOwogICAgICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKHN3YXBDaGFpbik7CiAgICB9IGVsc2UgewogICAgICAgICpwcEJhY2tCdWZmZXIgPSBOVUxMOwogICAgfQogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldERldmljZUNhcHMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEQ0FQUyogcENhcHMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFdBUk4oIiglcCkgOiBzdHViLCBjYWxsaW5nIGlkaXJlY3QzZCBmb3Igbm93XG4iLCBUaGlzKTsKICAgIHJldHVybiBJV2luZUQzRF9HZXREZXZpY2VDYXBzKFRoaXMtPndpbmVEM0QsIFRoaXMtPmFkYXB0ZXJObywgVGhpcy0+ZGV2VHlwZSwgcENhcHMpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0dldERpc3BsYXlNb2RlKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBpU3dhcENoYWluLCBXSU5FRDNERElTUExBWU1PREUqIHBNb2RlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcENoYWluOwogICAgSFJFU1VMVCBocjsKCiAgICBpZihpU3dhcENoYWluID4gMCkgewogICAgICAgIGhyID0gSVdpbmVEM0REZXZpY2VJbXBsX0dldFN3YXBDaGFpbihpZmFjZSwgIGlTd2FwQ2hhaW4sIChJV2luZUQzRFN3YXBDaGFpbiAqKikmc3dhcENoYWluKTsKICAgICAgICBpZiAoaHIgPT0gV0lORUQzRF9PSykgewogICAgICAgICAgICBociA9IElXaW5lRDNEU3dhcENoYWluX0dldERpc3BsYXlNb2RlKHN3YXBDaGFpbiwgcE1vZGUpOwogICAgICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKHN3YXBDaGFpbik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgRklYTUUoIiglcCkgRXJyb3IgZ2V0dGluZyBkaXNwbGF5IG1vZGVcbiIsIFRoaXMpOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgLyogRG9uJ3QgcmVhZCB0aGUgcmVhbCBkaXNwbGF5IG1vZGUsCiAgICAgICAgICAgYnV0IHJldHVybiB0aGUgc3RvcmVkIG1vZGUgaW5zdGVhZC4gWDExIGNhbid0IGNoYW5nZSB0aGUgY29sb3IKICAgICAgICAgICBkZXB0aCwgYW5kIHNvbWUgYXBwcyBhcmUgcHJldHR5IGFuZ3J5IGlmIHRoZXkgU2V0RGlzcGxheU1vZGUgZnJvbQogICAgICAgICAgIDI0IHRvIDE2IGJwcCBhbmQgZmluZCBvdXQgdGhhdCBHZXREaXNwbGF5TW9kZSBzdGlsbCByZXR1cm5zIDI0IGJwcAoKICAgICAgICAgICBBbHNvIGRvbid0IHJlbGF5IHRvIHRoZSBzd2FwY2hhaW4gYmVjYXVzZSB3aXRoIGRkcmF3IGl0J3MgcG9zc2libGUKICAgICAgICAgICB0aGF0IHRoZXJlIGlzbid0IGEgc3dhcGNoYWluIGF0IGFsbCAqLwogICAgICAgIHBNb2RlLT5XaWR0aCA9IFRoaXMtPmRkcmF3X3dpZHRoOwogICAgICAgIHBNb2RlLT5IZWlnaHQgPSBUaGlzLT5kZHJhd19oZWlnaHQ7CiAgICAgICAgcE1vZGUtPkZvcm1hdCA9IFRoaXMtPmRkcmF3X2Zvcm1hdDsKICAgICAgICBwTW9kZS0+UmVmcmVzaFJhdGUgPSAwOwogICAgICAgIGhyID0gV0lORUQzRF9PSzsKICAgIH0KCiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfU2V0SFdORChJV2luZUQzRERldmljZSAqaWZhY2UsIEhXTkQgaFduZCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIGhXbmQpOwoKICAgIGlmKFRoaXMtPmRkcmF3X2Z1bGxzY3JlZW4pIHsKICAgICAgICBpZihUaGlzLT5kZHJhd193aW5kb3cgJiYgVGhpcy0+ZGRyYXdfd2luZG93ICE9IGhXbmQpIHsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX1Jlc3RvcmVXaW5kb3coaWZhY2UsIFRoaXMtPmRkcmF3X3dpbmRvdyk7CiAgICAgICAgfQogICAgICAgIGlmKGhXbmQgJiYgVGhpcy0+ZGRyYXdfd2luZG93ICE9IGhXbmQpIHsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldHVwRnVsbHNjcmVlbldpbmRvdyhpZmFjZSwgaFduZCk7CiAgICAgICAgfQogICAgfQoKICAgIFRoaXMtPmRkcmF3X3dpbmRvdyA9IGhXbmQ7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9HZXRIV05EKElXaW5lRDNERGV2aWNlICppZmFjZSwgSFdORCAqaFduZCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIGhXbmQpOwoKICAgICpoV25kID0gVGhpcy0+ZGRyYXdfd2luZG93OwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBTdGF0ZWJsb2NrIHJlbGF0ZWQgZnVuY3Rpb25zCiAqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQmVnaW5TdGF0ZUJsb2NrKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgSVdpbmVEM0RTdGF0ZUJsb2NrSW1wbCAqb2JqZWN0OwogICAgSFJFU1VMVCB0ZW1wX3Jlc3VsdDsKICAgIGludCBpOwoKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKICAgIAogICAgaWYgKFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUpIHsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIAogICAgb2JqZWN0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJV2luZUQzRFN0YXRlQmxvY2tJbXBsKSk7CiAgICBpZiAoTlVMTCA9PSBvYmplY3QgKSB7CiAgICAgICAgRklYTUUoIiglcClFcnJvciBhbGxvY2F0aW5nIG1lbW9yeSBmb3Igc3RhdGVibG9ja1xuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICB9CiAgICBUUkFDRSgiKCVwKSBjcmVhdGVkIG9iamVjdCAlcFxuIiwgVGhpcywgb2JqZWN0KTsKICAgIG9iamVjdC0+d2luZUQzRERldmljZT0gVGhpczsKICAgIC8qKiBGSVhNRTogb2JqZWN0LT5wYXJlbnQgICAgICAgPSBwYXJlbnQ7ICoqLwogICAgb2JqZWN0LT5wYXJlbnQgICAgICAgPSBOVUxMOwogICAgb2JqZWN0LT5ibG9ja1R5cGUgICAgPSBXSU5FRDNEU0JUX0FMTDsKICAgIG9iamVjdC0+cmVmICAgICAgICAgID0gMTsKICAgIG9iamVjdC0+bHBWdGJsICAgICAgID0gJklXaW5lRDNEU3RhdGVCbG9ja19WdGJsOwoKICAgIGZvcihpID0gMDsgaSA8IExJR0hUTUFQX1NJWkU7IGkrKykgewogICAgICAgIGxpc3RfaW5pdCgmb2JqZWN0LT5saWdodE1hcFtpXSk7CiAgICB9CgogICAgdGVtcF9yZXN1bHQgPSBhbGxvY2F0ZV9zaGFkZXJfY29uc3RhbnRzKG9iamVjdCk7CiAgICBpZiAoV0lORUQzRF9PSyAhPSB0ZW1wX3Jlc3VsdCkKICAgICAgICByZXR1cm4gdGVtcF9yZXN1bHQ7CgogICAgSVdpbmVEM0RTdGF0ZUJsb2NrX1JlbGVhc2UoKElXaW5lRDNEU3RhdGVCbG9jayopVGhpcy0+dXBkYXRlU3RhdGVCbG9jayk7CiAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrID0gb2JqZWN0OwogICAgVGhpcy0+aXNSZWNvcmRpbmdTdGF0ZSA9IFRSVUU7CgogICAgVFJBQ0UoIiglcCkgcmVjb3JkaW5nIHN0YXRlYmxvY2sgJXBcbiIsVGhpcyAsIG9iamVjdCk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9FbmRTdGF0ZUJsb2NrKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RTdGF0ZUJsb2NrKiogcHBTdGF0ZUJsb2NrKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgaWYgKCFUaGlzLT5pc1JlY29yZGluZ1N0YXRlKSB7CiAgICAgICAgRklYTUUoIiglcCkgbm90IHJlY29yZGluZyEgcmV0dXJuaW5nIGVycm9yXG4iLCBUaGlzKTsKICAgICAgICAqcHBTdGF0ZUJsb2NrID0gTlVMTDsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICAqcHBTdGF0ZUJsb2NrID0gKElXaW5lRDNEU3RhdGVCbG9jayopVGhpcy0+dXBkYXRlU3RhdGVCbG9jazsKICAgIFRoaXMtPmlzUmVjb3JkaW5nU3RhdGUgPSBGQUxTRTsKICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2sgPSBUaGlzLT5zdGF0ZUJsb2NrOwogICAgSVdpbmVEM0RTdGF0ZUJsb2NrX0FkZFJlZigoSVdpbmVEM0RTdGF0ZUJsb2NrKilUaGlzLT51cGRhdGVTdGF0ZUJsb2NrKTsKICAgIC8qIElXaW5lRDNEU3RhdGVCbG9ja19BZGRSZWYoKnBwU3RhdGVCbG9jayk7IGRvbid0IG5lZWQgdG8gZG8gdGhpcywgc2luY2Ugd2Ugc2hvdWxkIHJlYWxseSBqdXN0IHJlbGVhc2UgVXBkYXRlU3RhdGVCbG9jayBmaXJzdCAqLwogICAgVFJBQ0UoIiglcCkgcmV0dXJuaW5nIHRva2VuIChwdHIgdG8gc3RhdGVibG9jaykgb2YgJXBcbiIsIFRoaXMsICpwcFN0YXRlQmxvY2spOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qKioqKgogKiBTY2VuZSByZWxhdGVkIGZ1bmN0aW9ucwogKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQmVnaW5TY2VuZShJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIC8qIEF0IHRoZSBtb21lbnQgd2UgaGF2ZSBubyBuZWVkIGZvciBhbnkgZnVuY3Rpb25hbGl0eSBhdCB0aGUgYmVnaW5uaW5nCiAgICAgICBvZiBhIHNjZW5lICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgaWYoVGhpcy0+aW5TY2VuZSkgewogICAgICAgIFRSQUNFKCJBbHJlYWR5IGluIFNjZW5lLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICBUaGlzLT5pblNjZW5lID0gVFJVRTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0VuZFNjZW5lKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIGlmKCFUaGlzLT5pblNjZW5lKSB7CiAgICAgICAgVFJBQ0UoIk5vdCBpbiBzY2VuZSwgcmV0dXJuaW5nIFdJTkVEM0RFUlJfSU5WQUxJRENBTExcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIEVOVEVSX0dMKCk7CiAgICBpZihUaGlzLT5jcmVhdGVQYXJtcy5CZWhhdmlvckZsYWdzICYgV0lORUQzRENSRUFURV9NVUxUSVRIUkVBREVEKSB7CiAgICAgICAgQWN0aXZhdGVDb250ZXh0KFRoaXMsIFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQsIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CiAgICB9CiAgICAvKiBXZSBvbmx5IGhhdmUgdG8gZG8gdGhpcyBpZiB3ZSBuZWVkIHRvIHJlYWQgdGhlLCBzd2FwYnVmZmVycyBwZXJmb3JtcyBhIGZsdXNoIGZvciB1cyAqLwogICAgZ2xGbHVzaCgpOwogICAgY2hlY2tHTGNhbGwoImdsRmx1c2giKTsKICAgIExFQVZFX0dMKCk7CgogICAgVGhpcy0+aW5TY2VuZSA9IEZBTFNFOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfUHJlc2VudChJV2luZUQzRERldmljZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTlNUIFJFQ1QqIHBTb3VyY2VSZWN0LCBDT05TVCBSRUNUKiBwRGVzdFJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhXTkQgaERlc3RXaW5kb3dPdmVycmlkZSwgQ09OU1QgUkdOREFUQSogcERpcnR5UmVnaW9uKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN3YXBDaGFpbiAqc3dhcENoYWluID0gTlVMTDsKICAgIGludCBpOwogICAgaW50IHN3YXBjaGFpbnMgPSBJV2luZUQzRERldmljZUltcGxfR2V0TnVtYmVyT2ZTd2FwQ2hhaW5zKGlmYWNlKTsKCiAgICBUUkFDRSgiKCVwKSBQcmVzZW50aW5nIHRoZSBmcmFtZVxuIiwgVGhpcyk7CgogICAgZm9yKGkgPSAwIDsgaSA8IHN3YXBjaGFpbnMgOyBpICsrKSB7CgogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTd2FwQ2hhaW4oaWZhY2UsIGkgLCAoSVdpbmVEM0RTd2FwQ2hhaW4gKiopJnN3YXBDaGFpbik7CiAgICAgICAgVFJBQ0UoInByZXNlbnRpbm5nIGNoYWluICVkLCAlcFxuIiwgaSwgc3dhcENoYWluKTsKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9QcmVzZW50KHN3YXBDaGFpbiwgcFNvdXJjZVJlY3QsIHBEZXN0UmVjdCwgaERlc3RXaW5kb3dPdmVycmlkZSwgcERpcnR5UmVnaW9uLCAwKTsKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKHN3YXBDaGFpbik7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ2xlYXIoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBEV09SRCBDb3VudCwgQ09OU1QgV0lORUQzRFJFQ1QqIHBSZWN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzLCBXSU5FRDNEQ09MT1IgQ29sb3IsIGZsb2F0IFosIERXT1JEIFN0ZW5jaWwpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKnRhcmdldCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopVGhpcy0+cmVuZGVyX3RhcmdldHNbMF07CgogICAgR0xiaXRmaWVsZCAgICAgZ2xNYXNrID0gMDsKICAgIHVuc2lnbmVkIGludCAgIGk7CiAgICBDT05TVCBXSU5FRDNEUkVDVCogY3VyUmVjdDsKCiAgICBUUkFDRSgiKCVwKSBDb3VudCAoJWQpLCBwUmVjdHMgKCVwKSwgRmxhZ3MgKCV4KSwgWiAoJWYpLCBTdGVuY2lsICglZClcbiIsIFRoaXMsCiAgICAgICAgICBDb3VudCwgcFJlY3RzLCBGbGFncywgWiwgU3RlbmNpbCk7CgogICAgaWYoRmxhZ3MgJiAoV0lORUQzRENMRUFSX1pCVUZGRVIgfCBXSU5FRDNEQ0xFQVJfU1RFTkNJTCkgJiYgVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCA9PSBOVUxMKSB7CiAgICAgICAgV0FSTigiQ2xlYXJpbmcgZGVwdGggYW5kL29yIHN0ZW5jaWwgd2l0aG91dCBhIGRlcHRoIHN0ZW5jaWwgYnVmZmVyIGF0dGFjaGVkLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIik7CiAgICAgICAgLyogVE9ETzogV2hhdCBhYm91dCBkZXB0aCBzdGVuY2lsIGJ1ZmZlcnMgd2l0aG91dCBzdGVuY2lsIGJpdHM/ICovCiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgRU5URVJfR0woKTsKICAgIC8qIFRoaXMgaXMgZm9yIG9mZnNjcmVlbiByZW5kZXJpbmcgYXMgd2VsbCBhcyBmb3IgbXVsdGl0aHJlYWRpbmcsIHRodXMgYWN0aXZhdGUgdGhlIHNldCByZW5kZXIgdGFyZ2V0CiAgICAgKiBhbmQgbm90IHRoZSBsYXN0IGFjdGl2ZSBvbmUuCiAgICAgKi8KICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXSwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKCiAgICBnbEVuYWJsZShHTF9TQ0lTU09SX1RFU1QpOwogICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIEdMX1NDSVNTT1JfVEVTVCIpOwogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1NDSVNTT1JSRUNUKTsKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX1NDSVNTT1JURVNURU5BQkxFKSk7CgogICAgaWYgKENvdW50ID4gMCAmJiBwUmVjdHMpIHsKICAgICAgICBjdXJSZWN0ID0gcFJlY3RzOwogICAgfSBlbHNlIHsKICAgICAgICBjdXJSZWN0ID0gTlVMTDsKICAgIH0KCiAgICAvKiBPbmx5IHNldCB0aGUgdmFsdWVzIHVwIG9uY2UsIGFzIHRoZXkgYXJlIG5vdCBjaGFuZ2luZyAqLwogICAgaWYgKEZsYWdzICYgV0lORUQzRENMRUFSX1NURU5DSUwpIHsKICAgICAgICBnbENsZWFyU3RlbmNpbChTdGVuY2lsKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xDbGVhclN0ZW5jaWwiKTsKICAgICAgICBnbE1hc2sgPSBnbE1hc2sgfCBHTF9TVEVOQ0lMX0JVRkZFUl9CSVQ7CiAgICAgICAgZ2xTdGVuY2lsTWFzaygweEZGRkZGRkZGKTsKICAgIH0KCiAgICBpZiAoRmxhZ3MgJiBXSU5FRDNEQ0xFQVJfWkJVRkZFUikgewogICAgICAgIGdsRGVwdGhNYXNrKEdMX1RSVUUpOwogICAgICAgIGdsQ2xlYXJEZXB0aChaKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xDbGVhckRlcHRoIik7CiAgICAgICAgZ2xNYXNrID0gZ2xNYXNrIHwgR0xfREVQVEhfQlVGRkVSX0JJVDsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19aV1JJVEVFTkFCTEUpKTsKICAgIH0KCiAgICBpZiAoRmxhZ3MgJiBXSU5FRDNEQ0xFQVJfVEFSR0VUKSB7CiAgICAgICAgVFJBQ0UoIkNsZWFyaW5nIHNjcmVlbiB3aXRoIGdsQ2xlYXIgdG8gY29sb3IgJXhcbiIsIENvbG9yKTsKICAgICAgICBnbENsZWFyQ29sb3IoRDNEQ09MT1JfUihDb2xvciksCiAgICAgICAgICAgICAgICAgICAgIEQzRENPTE9SX0coQ29sb3IpLAogICAgICAgICAgICAgICAgICAgICBEM0RDT0xPUl9CKENvbG9yKSwKICAgICAgICAgICAgICAgICAgICAgRDNEQ09MT1JfQShDb2xvcikpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbENsZWFyQ29sb3IiKTsKCiAgICAgICAgLyogQ2xlYXIgQUxMIGNvbG9ycyEgKi8KICAgICAgICBnbENvbG9yTWFzayhHTF9UUlVFLCBHTF9UUlVFLCBHTF9UUlVFLCBHTF9UUlVFKTsKICAgICAgICBnbE1hc2sgPSBnbE1hc2sgfCBHTF9DT0xPUl9CVUZGRVJfQklUOwogICAgfQoKICAgIGlmICghY3VyUmVjdCkgewogICAgICAgIC8qIEluIGRyYXdhYmxlIGZsYWcgaXMgc2V0IGJlbG93ICovCgogICAgICAgIGdsU2Npc3NvcihUaGlzLT5zdGF0ZUJsb2NrLT52aWV3cG9ydC5YLAogICAgICAgICAgICAgICAgICAoKChJV2luZUQzRFN1cmZhY2VJbXBsICopVGhpcy0+cmVuZGVyX3RhcmdldHNbMF0pLT5jdXJyZW50RGVzYy5IZWlnaHQgLQogICAgICAgICAgICAgICAgICAoVGhpcy0+c3RhdGVCbG9jay0+dmlld3BvcnQuWSArIFRoaXMtPnN0YXRlQmxvY2stPnZpZXdwb3J0LkhlaWdodCkpLAogICAgICAgICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+dmlld3BvcnQuV2lkdGgsCiAgICAgICAgICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT52aWV3cG9ydC5IZWlnaHQpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFNjaXNzb3IiKTsKICAgICAgICBnbENsZWFyKGdsTWFzayk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQ2xlYXIiKTsKICAgIH0gZWxzZSB7CiAgICAgICAgaWYoISh0YXJnZXQtPkZsYWdzICYgU0ZMQUdfSU5EUkFXQUJMRSkgJiYKICAgICAgICAgICAhKHdpbmVkM2Rfc2V0dGluZ3Mub2Zmc2NyZWVuX3JlbmRlcmluZ19tb2RlID09IE9STV9GQk8gJiYgVGhpcy0+cmVuZGVyX29mZnNjcmVlbiAmJiB0YXJnZXQtPkZsYWdzICYgU0ZMQUdfSU5URVhUVVJFKSkgewoKICAgICAgICAgICAgaWYoY3VyUmVjdFswXS54MSA+IDAgfHwgY3VyUmVjdFswXS55MSA+IDAgfHwKICAgICAgICAgICAgICAgY3VyUmVjdFswXS54MiA8IHRhcmdldC0+Y3VycmVudERlc2MuV2lkdGggfHwKICAgICAgICAgICAgICAgY3VyUmVjdFswXS55MiA8IHRhcmdldC0+Y3VycmVudERlc2MuSGVpZ2h0KSB7CiAgICAgICAgICAgICAgICBUUkFDRSgiUGFydGlhbCBjbGVhciwgYW5kIHN1cmZhY2Ugbm90IGluIGRyYXdhYmxlLiBCbGl0dGluZyB0ZXh0dXJlIHRvIGRyYXdhYmxlXG4iKTsKICAgICAgICAgICAgICAgIGJsdF90b19kcmF3YWJsZShUaGlzLCB0YXJnZXQpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiBOb3cgcHJvY2VzcyBlYWNoIHJlY3QgaW4gdHVybiAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBDb3VudDsgaSsrKSB7CiAgICAgICAgICAgIC8qIE5vdGUgZ2wgdXNlcyBsb3dlciBsZWZ0LCB3aWR0aC9oZWlnaHQgKi8KICAgICAgICAgICAgVFJBQ0UoIiglcCkgJXAgUmVjdD0oJWQsJWQpLT4oJWQsJWQpIGdsUmVjdD0oJWQsJWQpLCBsZW49JWQsIGhlaT0lZFxuIiwgVGhpcywgY3VyUmVjdCwKICAgICAgICAgICAgICAgICAgY3VyUmVjdFtpXS54MSwgY3VyUmVjdFtpXS55MSwgY3VyUmVjdFtpXS54MiwgY3VyUmVjdFtpXS55MiwKICAgICAgICAgICAgICAgICAgY3VyUmVjdFtpXS54MSwgKHRhcmdldC0+Y3VycmVudERlc2MuSGVpZ2h0IC0gY3VyUmVjdFtpXS55MiksCiAgICAgICAgICAgICAgICAgIGN1clJlY3RbaV0ueDIgLSBjdXJSZWN0W2ldLngxLCBjdXJSZWN0W2ldLnkyIC0gY3VyUmVjdFtpXS55MSk7CgogICAgICAgICAgICAvKiBUZXN0cyBzaG93IHRoYXQgcmVjdGFuZ2xlcyB3aGVyZSB4MSA+IHgyIG9yIHkxID4geTIgYXJlIGlnbm9yZWQgc2lsZW50bHkuCiAgICAgICAgICAgICAqIFRoZSByZWN0YW5nbGUgaXMgbm90IGNsZWFyZWQsIG5vIGVycm9yIGlzIHJldHVybmVkLCBidXQgZnVydGhlciByZWN0YW5sZ2VzIGFyZQogICAgICAgICAgICAgKiBzdGlsbCBjbGVhcmVkIGlmIHRoZXkgYXJlIHZhbGlkCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZihjdXJSZWN0W2ldLngxID4gY3VyUmVjdFtpXS54MiB8fCBjdXJSZWN0W2ldLnkxID4gY3VyUmVjdFtpXS55MikgewogICAgICAgICAgICAgICAgVFJBQ0UoIlJlY3RhbmdsZSB3aXRoIG5lZ2F0aXZlIGRpbWVuc2lvbnMsIGlnbm9yaW5nXG4iKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZihUaGlzLT5yZW5kZXJfb2Zmc2NyZWVuKSB7CiAgICAgICAgICAgICAgICBnbFNjaXNzb3IoY3VyUmVjdFtpXS54MSwgY3VyUmVjdFtpXS55MSwKICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJSZWN0W2ldLngyIC0gY3VyUmVjdFtpXS54MSwgY3VyUmVjdFtpXS55MiAtIGN1clJlY3RbaV0ueTEpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZ2xTY2lzc29yKGN1clJlY3RbaV0ueDEsIHRhcmdldC0+Y3VycmVudERlc2MuSGVpZ2h0IC0gY3VyUmVjdFtpXS55MiwKICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJSZWN0W2ldLngyIC0gY3VyUmVjdFtpXS54MSwgY3VyUmVjdFtpXS55MiAtIGN1clJlY3RbaV0ueTEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFNjaXNzb3IiKTsKCiAgICAgICAgICAgIGdsQ2xlYXIoZ2xNYXNrKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQ2xlYXIiKTsKICAgICAgICB9CiAgICB9CgogICAgLyogUmVzdG9yZSB0aGUgb2xkIHZhbHVlcyAod2h5Li4/KSAqLwogICAgaWYgKEZsYWdzICYgV0lORUQzRENMRUFSX1NURU5DSUwpIHsKICAgICAgICBnbFN0ZW5jaWxNYXNrKFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19TVEVOQ0lMV1JJVEVNQVNLXSk7CiAgICB9CiAgICBpZiAoRmxhZ3MgJiBXSU5FRDNEQ0xFQVJfVEFSR0VUKSB7CiAgICAgICAgRFdPUkQgbWFzayA9IFRoaXMtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19DT0xPUldSSVRFRU5BQkxFXTsKICAgICAgICBnbENvbG9yTWFzayhtYXNrICYgV0lORUQzRENPTE9SV1JJVEVFTkFCTEVfUkVEID8gR0xfVFJVRSA6IEdMX0ZBTFNFLAogICAgICAgICAgICAgICAgICAgIG1hc2sgJiBXSU5FRDNEQ09MT1JXUklURUVOQUJMRV9HUkVFTiA/IEdMX1RSVUUgOiBHTF9GQUxTRSwKICAgICAgICAgICAgICAgICAgICBtYXNrICYgV0lORUQzRENPTE9SV1JJVEVFTkFCTEVfQkxVRSAgPyBHTF9UUlVFIDogR0xfRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgbWFzayAmIFdJTkVEM0RDT0xPUldSSVRFRU5BQkxFX0FMUEhBID8gR0xfVFJVRSA6IEdMX0ZBTFNFKTsKICAgIH0KCiAgICBMRUFWRV9HTCgpOwoKICAgIC8qIERpcnRpZnkgdGhlIHRhcmdldCBzdXJmYWNlIGZvciBub3cuIElmIHRoZSBzdXJmYWNlIGlzIGxvY2tlZCByZWd1bGFyaWx5LCBhbmQgYW4gdXAgdG8gZGF0ZSBzeXNtZW0gY29weSBleGlzdHMsCiAgICAgKiBpdCBpcyBtb3N0IGxpa2VseSBtb3JlIGVmZmljaWVudCB0byBwZXJmb3JtIGEgY2xlYXIgb24gdGhlIHN5c21lbSBjb3B5IHRvbyBpc250ZWFkIG9mIGRvd25sb2FkaW5nIGl0CiAgICAgKi8KICAgIGlmKFRoaXMtPnJlbmRlcl9vZmZzY3JlZW4gJiYgd2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUgPT0gT1JNX0ZCTykgewogICAgICAgIHRhcmdldC0+RmxhZ3MgfD0gU0ZMQUdfSU5URVhUVVJFOwogICAgICAgIHRhcmdldC0+RmxhZ3MgJj0gflNGTEFHX0lOU1lTTUVNOwogICAgfSBlbHNlIHsKICAgICAgICB0YXJnZXQtPkZsYWdzIHw9IFNGTEFHX0lORFJBV0FCTEU7CiAgICAgICAgdGFyZ2V0LT5GbGFncyAmPSB+KFNGTEFHX0lOVEVYVFVSRSB8IFNGTEFHX0lOU1lTTUVNKTsKICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgovKioqKioKICogRHJhd2luZyBmdW5jdGlvbnMKICoqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdQcmltaXRpdmUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLCBVSU5UIFN0YXJ0VmVydGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFByaW1pdGl2ZUNvdW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXApIDogVHlwZT0oJWQsJXMpLCBTdGFydD0lZCwgQ291bnQ9JWRcbiIsIFRoaXMsIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWJ1Z19kM2RwcmltaXRpdmV0eXBlKFByaW1pdGl2ZVR5cGUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhcnRWZXJ0ZXgsIFByaW1pdGl2ZUNvdW50KTsKCiAgICAvKiBUaGUgaW5kZXggYnVmZmVyIGlzIG5vdCBuZWVkZWQgaGVyZSwgYnV0IHJlc3RvcmUgaXQsIG90aGVyd2lzZSBpdCBpcyBoZWxsIHRvIGtlZXAgdHJhY2sgb2YgKi8KICAgIGlmKFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbUlzVVApIHsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfSU5ERVhCVUZGRVIpOwogICAgICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbUlzVVAgPSBGQUxTRTsKICAgIH0KCiAgICBpZihUaGlzLT5zdGF0ZUJsb2NrLT5sb2FkQmFzZVZlcnRleEluZGV4ICE9IDApIHsKICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5sb2FkQmFzZVZlcnRleEluZGV4ID0gMDsKICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfU1RSRUFNU1JDKTsKICAgIH0KICAgIC8qIEFjY291bnQgZm9yIHRoZSBsb2FkaW5nIG9mZnNldCBkdWUgdG8gaW5kZXggYnVmZmVycy4gSW5zdGVhZCBvZiByZWxvYWRpbmcgYWxsIHNvdXJjZXMgY29ycmVjdCBpdCB3aXRoIHRoZSBzdGFydHZlcnRleCBwYXJhbWV0ZXIgKi8KICAgIGRyYXdQcmltaXRpdmUoaWZhY2UsIFByaW1pdGl2ZVR5cGUsIFByaW1pdGl2ZUNvdW50LCBTdGFydFZlcnRleCwgMC8qIE51bVZlcnRpY2VzICovLCAtMSAvKiBpbmR4U3RhcnQgKi8sCiAgICAgICAgICAgICAgICAgIDAgLyogaW5keFNpemUgKi8sIE5VTEwgLyogaW5keERhdGEgKi8sIDAgLyogbWluSW5kZXggKi8pOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qIFRPRE86IGJhc2VWSW5kZXggbmVlZHMgdG8gYmUgcHJvdmlkZWQgZnJvbSBUaGlzLT5zdGF0ZUJsb2NrLT5iYXNlVmVydGV4SW5kZXggd2hlbiBjYWxsZWQgZnJvbSBkM2Q4ICovCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3SW5kZXhlZFByaW1pdGl2ZShJV2luZUQzRERldmljZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFBSSU1JVElWRVRZUEUgUHJpbWl0aXZlVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIG1pbkluZGV4LCBVSU5UIE51bVZlcnRpY2VzLCBVSU5UIHN0YXJ0SW5kZXgsIFVJTlQgcHJpbUNvdW50KSB7CgogICAgSVdpbmVEM0REZXZpY2VJbXBsICAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFVJTlQgICAgICAgICAgICAgICAgIGlkeFN0cmlkZSA9IDI7CiAgICBJV2luZUQzREluZGV4QnVmZmVyICpwSUI7CiAgICBXSU5FRDNESU5ERVhCVUZGRVJfREVTQyAgSWR4QnVmRHNjOwogICAgR0x1aW50IHZibzsKCiAgICBpZihUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Jc1VQKSB7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX0lOREVYQlVGRkVSKTsKICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Jc1VQID0gRkFMU0U7CiAgICB9CiAgICBwSUIgPSBUaGlzLT5zdGF0ZUJsb2NrLT5wSW5kZXhEYXRhOwogICAgdmJvID0gKChJV2luZUQzREluZGV4QnVmZmVySW1wbCAqKSBwSUIpLT52Ym87CgogICAgVFJBQ0UoIiglcCkgOiBUeXBlPSglZCwlcyksIG1pbj0lZCwgQ291bnRWPSVkLCBzdGFydElkeD0lZCwgY291bnRQPSVkXG4iLCBUaGlzLAogICAgICAgICAgUHJpbWl0aXZlVHlwZSwgZGVidWdfZDNkcHJpbWl0aXZldHlwZShQcmltaXRpdmVUeXBlKSwKICAgICAgICAgIG1pbkluZGV4LCBOdW1WZXJ0aWNlcywgc3RhcnRJbmRleCwgcHJpbUNvdW50KTsKCiAgICBJV2luZUQzREluZGV4QnVmZmVyX0dldERlc2MocElCLCAmSWR4QnVmRHNjKTsKICAgIGlmIChJZHhCdWZEc2MuRm9ybWF0ID09IFdJTkVEM0RGTVRfSU5ERVgxNikgewogICAgICAgIGlkeFN0cmlkZSA9IDI7CiAgICB9IGVsc2UgewogICAgICAgIGlkeFN0cmlkZSA9IDQ7CiAgICB9CgogICAgaWYoVGhpcy0+c3RhdGVCbG9jay0+bG9hZEJhc2VWZXJ0ZXhJbmRleCAhPSBUaGlzLT5zdGF0ZUJsb2NrLT5iYXNlVmVydGV4SW5kZXgpIHsKICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5sb2FkQmFzZVZlcnRleEluZGV4ID0gVGhpcy0+c3RhdGVCbG9jay0+YmFzZVZlcnRleEluZGV4OwogICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9TVFJFQU1TUkMpOwogICAgfQoKICAgIGRyYXdQcmltaXRpdmUoaWZhY2UsIFByaW1pdGl2ZVR5cGUsIHByaW1Db3VudCwgMCwgTnVtVmVydGljZXMsIHN0YXJ0SW5kZXgsCiAgICAgICAgICAgICAgICAgICBpZHhTdHJpZGUsIHZibyA/IE5VTEwgOiAoKElXaW5lRDNESW5kZXhCdWZmZXJJbXBsICopIHBJQiktPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSwgbWluSW5kZXgpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdQcmltaXRpdmVVUChJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFByaW1pdGl2ZUNvdW50LCBDT05TVCB2b2lkKiBwVmVydGV4U3RyZWFtWmVyb0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFZlcnRleFN0cmVhbVplcm9TdHJpZGUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKSA6IFR5cGU9KCVkLCVzKSwgcENvdW50PSVkLCBwVnR4RGF0YT0lcCwgU3RyaWRlPSVkXG4iLCBUaGlzLCBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgZGVidWdfZDNkcHJpbWl0aXZldHlwZShQcmltaXRpdmVUeXBlKSwKICAgICAgICAgICAgIFByaW1pdGl2ZUNvdW50LCBwVmVydGV4U3RyZWFtWmVyb0RhdGEsIFZlcnRleFN0cmVhbVplcm9TdHJpZGUpOwoKICAgIC8qIE5vdGUgaW4gdGhlIGZvbGxvd2luZywgaXQncyBub3QgdGhpcyB0eXBlLCBidXQgdGhhdCdzIHRoZSBwdXJwb3NlIG9mIHN0cmVhbUlzVVAgKi8KICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVswXSA9IChJV2luZUQzRFZlcnRleEJ1ZmZlciAqKXBWZXJ0ZXhTdHJlYW1aZXJvRGF0YTsKICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVN0cmlkZVswXSA9IFZlcnRleFN0cmVhbVplcm9TdHJpZGU7CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Jc1VQID0gVFJVRTsKICAgIFRoaXMtPnN0YXRlQmxvY2stPmxvYWRCYXNlVmVydGV4SW5kZXggPSAwOwoKICAgIC8qIFRPRE86IE9ubHkgbWFyayBkaXJ0eSBpZiBkcmF3aW5nIGZyb20gYSBkaWZmZXJlbnQgVVAgYWRkcmVzcyAqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1NUUkVBTVNSQyk7CgogICAgZHJhd1ByaW1pdGl2ZShpZmFjZSwgUHJpbWl0aXZlVHlwZSwgUHJpbWl0aXZlQ291bnQsIDAgLyogc3RhcnQgdmVydGV4ICovLCAwICAvKiBOdW1WZXJ0aWNlcyAqLywKICAgICAgICAgICAgICAgICAgMCAvKiBpbmR4U3RhcnQqLywgMCAvKiBpbmR4U2l6ZSovLCBOVUxMIC8qIGluZHhEYXRhICovLCAwIC8qIGluZHhNaW4gKi8pOwoKICAgIC8qIE1TRE4gc3BlY2lmaWVzIHN0cmVhbSB6ZXJvIHNldHRpbmdzIG11c3QgYmUgc2V0IHRvIE5VTEwgKi8KICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVN0cmlkZVswXSA9IDA7CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbMF0gPSBOVUxMOwoKICAgIC8qIHN0cmVhbSB6ZXJvIHNldHRpbmdzIHNldCB0byBudWxsIGF0IGVuZCwgYXMgcGVyIHRoZSBtc2RuLiBObyBuZWVkIHRvIG1hcmsgZGlydHkgaGVyZSwgdGhlIGFwcCBoYXMgdG8gc2V0CiAgICAgKiB0aGUgbmV3IHN0cmVhbSBzb3VyY2VzIG9yIHVzZSBVUCBkcmF3aW5nIGFnYWluCiAgICAgKi8KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdJbmRleGVkUHJpbWl0aXZlVVAoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBXSU5FRDNEUFJJTUlUSVZFVFlQRSBQcmltaXRpdmVUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBNaW5WZXJ0ZXhJbmRleCwgVUlOVCBOdW1WZXJ0aWNlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgUHJpbWl0aXZlQ291bnQsIENPTlNUIHZvaWQqIHBJbmRleERhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNERk9STUFUIEluZGV4RGF0YUZvcm1hdCxDT05TVCB2b2lkKiBwVmVydGV4U3RyZWFtWmVyb0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UIFZlcnRleFN0cmVhbVplcm9TdHJpZGUpIHsKICAgIGludCAgICAgICAgICAgICAgICAgaWR4U3RyaWRlOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCIoJXApIDogVHlwZT0oJWQsJXMpLCBNaW5WdHhJZHg9JWQsIE51bVZJZHg9JWQsIFBDb3VudD0lZCwgcGlkeGRhdGE9JXAsIElkeEZtdD0lZCwgcFZ0eGRhdGE9JXAsIHN0cmlkZT0lZFxuIiwKICAgICAgICAgICAgIFRoaXMsIFByaW1pdGl2ZVR5cGUsIGRlYnVnX2QzZHByaW1pdGl2ZXR5cGUoUHJpbWl0aXZlVHlwZSksCiAgICAgICAgICAgICBNaW5WZXJ0ZXhJbmRleCwgTnVtVmVydGljZXMsIFByaW1pdGl2ZUNvdW50LCBwSW5kZXhEYXRhLAogICAgICAgICAgICAgSW5kZXhEYXRhRm9ybWF0LCBwVmVydGV4U3RyZWFtWmVyb0RhdGEsIFZlcnRleFN0cmVhbVplcm9TdHJpZGUpOwoKICAgIGlmIChJbmRleERhdGFGb3JtYXQgPT0gV0lORUQzREZNVF9JTkRFWDE2KSB7CiAgICAgICAgaWR4U3RyaWRlID0gMjsKICAgIH0gZWxzZSB7CiAgICAgICAgaWR4U3RyaWRlID0gNDsKICAgIH0KCiAgICAvKiBOb3RlIGluIHRoZSBmb2xsb3dpbmcsIGl0J3Mgbm90IHRoaXMgdHlwZSwgYnV0IHRoYXQncyB0aGUgcHVycG9zZSBvZiBzdHJlYW1Jc1VQICovCiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbMF0gPSAoSVdpbmVEM0RWZXJ0ZXhCdWZmZXIgKilwVmVydGV4U3RyZWFtWmVyb0RhdGE7CiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Jc1VQID0gVFJVRTsKICAgIFRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVN0cmlkZVswXSA9IFZlcnRleFN0cmVhbVplcm9TdHJpZGU7CgogICAgLyogU2V0IHRvIDAgYXMgcGVyIG1zZG4uIERvIGl0IG5vdyBkdWUgdG8gdGhlIHN0cmVhbSBzb3VyY2UgbG9hZGluZyBkdXJpbmcgZHJhd1ByaW1pdGl2ZSAqLwogICAgVGhpcy0+c3RhdGVCbG9jay0+YmFzZVZlcnRleEluZGV4ID0gMDsKICAgIFRoaXMtPnN0YXRlQmxvY2stPmxvYWRCYXNlVmVydGV4SW5kZXggPSAwOwogICAgLyogTWFyayB0aGUgc3RhdGUgZGlydHkgdW50aWwgd2UgaGF2ZSBuaWNlciB0cmFja2luZyBvZiB0aGUgc3RyZWFtIHNvdXJjZSBwb2ludGVycyAqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1ZERUNMKTsKICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9JTkRFWEJVRkZFUik7CgogICAgZHJhd1ByaW1pdGl2ZShpZmFjZSwgUHJpbWl0aXZlVHlwZSwgUHJpbWl0aXZlQ291bnQsIDAgLyogdmVydGV4U3RhcnQgKi8sIE51bVZlcnRpY2VzLCAwIC8qIGluZHhTdGFydCAqLywgaWR4U3RyaWRlLCBwSW5kZXhEYXRhLCBNaW5WZXJ0ZXhJbmRleCk7CgogICAgLyogTVNETiBzcGVjaWZpZXMgc3RyZWFtIHplcm8gc2V0dGluZ3MgYW5kIGluZGV4IGJ1ZmZlciBtdXN0IGJlIHNldCB0byBOVUxMICovCiAgICBUaGlzLT5zdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2VbMF0gPSBOVUxMOwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU3RyaWRlWzBdID0gMDsKICAgIFRoaXMtPnN0YXRlQmxvY2stPnBJbmRleERhdGEgPSBOVUxMOwogICAgLyogTm8gbmVlZCB0byBtYXJrIHRoZSBzdHJlYW0gc291cmNlIHN0YXRlIGRpcnR5IGhlcmUuIEVpdGhlciB0aGUgYXBwIGNhbGxzIFVQIGRyYXdpbmcgYWdhaW4sIG9yIGl0IGhhcyB0byBjYWxsCiAgICAgKiBTZXRTdHJlYW1Tb3VyY2UgdG8gc3BlY2lmeSBhIHZlcnRleCBidWZmZXIKICAgICAqLwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdQcmltaXRpdmVTdHJpZGVkIChJV2luZUQzRERldmljZSAqaWZhY2UsIFdJTkVEM0RQUklNSVRJVkVUWVBFIFByaW1pdGl2ZVR5cGUsIFVJTlQgUHJpbWl0aXZlQ291bnQsIFdpbmVEaXJlY3QzRFZlcnRleFN0cmlkZWREYXRhICpEcmF3UHJpbVN0cmlkZURhdGEpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CgogICAgLyogTWFyayB0aGUgc3RhdGUgZGlydHkgdW50aWwgd2UgaGF2ZSBuaWNlciB0cmFja2luZwogICAgICogaXRzIGZpbmUgdG8gY2hhbmdlIGJhc2VWZXJ0ZXhJbmRleCBiZWNhdXNlIHRoYXQgY2FsbCBpcyBvbmx5IGNhbGxlZCBieSBkZHJhdyB3aGljaCBkb2VzIG5vdCBuZWVkCiAgICAgKiB0aGF0IHZhbHVlLgogICAgICovCiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfVkRFQ0wpOwogICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX0lOREVYQlVGRkVSKTsKICAgIFRoaXMtPnN0YXRlQmxvY2stPmJhc2VWZXJ0ZXhJbmRleCA9IDA7CiAgICBUaGlzLT51cF9zdHJpZGVkID0gRHJhd1ByaW1TdHJpZGVEYXRhOwogICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtSXNVUCA9IFRSVUU7CiAgICBkcmF3UHJpbWl0aXZlKGlmYWNlLCBQcmltaXRpdmVUeXBlLCBQcmltaXRpdmVDb3VudCwgMCwgMCwgMCwgMCwgTlVMTCwgMCk7CiAgICBUaGlzLT51cF9zdHJpZGVkID0gTlVMTDsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CiAvKiBZZXQgYW5vdGhlciB3YXkgdG8gdXBkYXRlIGEgdGV4dHVyZSwgc29tZSBhcHBzIHVzZSB0aGlzIHRvIGxvYWQgZGVmYXVsdCB0ZXh0dXJlcyBpbnN0ZWFkIG9mIHVzaW5nIHN1cmZhY2UvdGV4dHVyZSBsb2NrL3VubG9jayAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1VwZGF0ZVRleHR1cmUgKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RCYXNlVGV4dHVyZSAqcFNvdXJjZVRleHR1cmUsICBJV2luZUQzREJhc2VUZXh0dXJlICpwRGVzdGluYXRpb25UZXh0dXJlKXsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIEhSRVNVTFQgaHIgPSBXSU5FRDNEX09LOwogICAgV0lORUQzRFJFU09VUkNFVFlQRSBzb3VyY2VUeXBlOwogICAgV0lORUQzRFJFU09VUkNFVFlQRSBkZXN0aW5hdGlvblR5cGU7CiAgICBpbnQgaSAsbGV2ZWxzOwoKICAgIC8qIFRPRE86IHRoaW5rIGFib3V0IG1vdmluZyB0aGUgY29kZSBpbnRvIElXaW5lRDNEQmFzZVRleHR1cmUgICovCgogICAgVFJBQ0UoIiglcCkgU291cmNlICVwIERlc3RpbmF0aW9uICVwXG4iLCBUaGlzLCBwU291cmNlVGV4dHVyZSwgcERlc3RpbmF0aW9uVGV4dHVyZSk7CgogICAgLyogdmVyaWZ5IHRoYXQgdGhlIHNvdXJjZSBhbmQgZGVzdGluYXRpb24gdGV4dHVyZXMgYXJlbid0IE5VTEwgKi8KICAgIGlmIChOVUxMID09IHBTb3VyY2VUZXh0dXJlIHx8IE5VTEwgPT0gcERlc3RpbmF0aW9uVGV4dHVyZSkgewogICAgICAgIFdBUk4oIiglcCkgOiBzb3VyY2UgKCVwKSBhbmQgZGVzdGluYXRpb24gKCVwKSB0ZXh0dXJlcyBtdXN0IG5vdCBiZSBOVUxMLCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIiwKICAgICAgICAgICAgIFRoaXMsIHBTb3VyY2VUZXh0dXJlLCBwRGVzdGluYXRpb25UZXh0dXJlKTsKICAgICAgICBociA9IFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgaWYgKHBTb3VyY2VUZXh0dXJlID09IHBEZXN0aW5hdGlvblRleHR1cmUpIHsKICAgICAgICBXQVJOKCIoJXApIDogc291cmNlICglcCkgYW5kIGRlc3RpbmF0aW9uICglcCkgdGV4dHVyZXMgbXVzdCBiZSBkaWZmZXJlbnQsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iLAogICAgICAgICAgICAgVGhpcywgcFNvdXJjZVRleHR1cmUsIHBEZXN0aW5hdGlvblRleHR1cmUpOwogICAgICAgIGhyID0gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIC8qIFZlcmlmeSB0aGF0IHRoZSBzb3VyY2UgYW5kIGRlc3RpbmF0aW9uIHRleHR1cmVzIGFyZSB0aGUgc2FtZSB0eXBlICovCiAgICBzb3VyY2VUeXBlICAgICAgPSBJV2luZUQzREJhc2VUZXh0dXJlX0dldFR5cGUocFNvdXJjZVRleHR1cmUpOwogICAgZGVzdGluYXRpb25UeXBlID0gSVdpbmVEM0RCYXNlVGV4dHVyZV9HZXRUeXBlKHBEZXN0aW5hdGlvblRleHR1cmUpOwoKICAgIGlmIChzb3VyY2VUeXBlICE9IGRlc3RpbmF0aW9uVHlwZSkgewogICAgICAgIFdBUk4oIiglcCkgU29yY2UgYW5kIGRlc3RpbmF0aW9uIHR5cGVzIG11c3QgbWF0Y2gsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iLAogICAgICAgICAgICAgVGhpcyk7CiAgICAgICAgaHIgPSBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIC8qIGNoZWNrIHRoYXQgYm90aCB0ZXh0dXJlcyBoYXZlIHRoZSBpZGVudGljYWwgbnVtYmVycyBvZiBsZXZlbHMgICovCiAgICBpZiAoSVdpbmVEM0RCYXNlVGV4dHVyZV9HZXRMZXZlbENvdW50KHBEZXN0aW5hdGlvblRleHR1cmUpICAhPSBJV2luZUQzREJhc2VUZXh0dXJlX0dldExldmVsQ291bnQocFNvdXJjZVRleHR1cmUpKSB7CiAgICAgICAgV0FSTigiKCVwKSA6IHNvdXJjZSAoJXApIGFuZCBkZXN0aW5hdGlvbiAoJXApIHRleHR1cmVzIG11c3QgaGF2ZSBpZGVudGljbGUgbnVtYmVycyBvZiBsZXZlbHMsIHJldHVybmluZyBXSU5FRDNERVJSX0lOVkFMSURDQUxMXG4iLCBUaGlzLCBwU291cmNlVGV4dHVyZSwgcERlc3RpbmF0aW9uVGV4dHVyZSk7CiAgICAgICAgaHIgPSBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmIChXSU5FRDNEX09LID09IGhyKSB7CgogICAgICAgIC8qIE1ha2Ugc3VyZSB0aGF0IHRoZSBkZXN0aW5hdGlvbiB0ZXh0dXJlIGlzIGxvYWRlZCAqLwogICAgICAgIElXaW5lRDNEQmFzZVRleHR1cmVfUHJlTG9hZChwRGVzdGluYXRpb25UZXh0dXJlKTsKCiAgICAgICAgLyogVXBkYXRlIGV2ZXJ5IHN1cmZhY2UgbGV2ZWwgb2YgdGhlIHRleHR1cmUgKi8KICAgICAgICBsZXZlbHMgPSBJV2luZUQzREJhc2VUZXh0dXJlX0dldExldmVsQ291bnQocERlc3RpbmF0aW9uVGV4dHVyZSk7CgogICAgICAgIHN3aXRjaCAoc291cmNlVHlwZSkgewogICAgICAgIGNhc2UgV0lORUQzRFJUWVBFX1RFWFRVUkU6CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSAqc3JjU3VyZmFjZTsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSAqZGVzdFN1cmZhY2U7CgogICAgICAgICAgICAgICAgZm9yIChpID0gMCA7IGkgPCBsZXZlbHMgOyArK2kpIHsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFRleHR1cmVfR2V0U3VyZmFjZUxldmVsKChJV2luZUQzRFRleHR1cmUgKilwU291cmNlVGV4dHVyZSwgICAgICBpLCAmc3JjU3VyZmFjZSk7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RUZXh0dXJlX0dldFN1cmZhY2VMZXZlbCgoSVdpbmVEM0RUZXh0dXJlICopcERlc3RpbmF0aW9uVGV4dHVyZSwgaSwgJmRlc3RTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICBociA9IElXaW5lRDNERGV2aWNlX1VwZGF0ZVN1cmZhY2UoaWZhY2UsIHNyY1N1cmZhY2UsIE5VTEwsIGRlc3RTdXJmYWNlLCBOVUxMKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShzcmNTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShkZXN0U3VyZmFjZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKFdJTkVEM0RfT0sgIT0gaHIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgV0FSTigiKCVwKSA6IENhbGwgdG8gdXBkYXRlIHN1cmZhY2UgZmFpbGVkXG4iLCBUaGlzKTsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGhyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9DVUJFVEVYVFVSRToKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlICpzcmNTdXJmYWNlOwogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlICpkZXN0U3VyZmFjZTsKICAgICAgICAgICAgICAgIFdJTkVEM0RDVUJFTUFQX0ZBQ0VTIGZhY2VUeXBlOwoKICAgICAgICAgICAgICAgIGZvciAoaSA9IDAgOyBpIDwgbGV2ZWxzIDsgKytpKSB7CiAgICAgICAgICAgICAgICAgICAgLyogVXBkYXRlIGVhY2ggY3ViZSBmYWNlICovCiAgICAgICAgICAgICAgICAgICAgZm9yIChmYWNlVHlwZSA9IFdJTkVEM0RDVUJFTUFQX0ZBQ0VfUE9TSVRJVkVfWDsgZmFjZVR5cGUgPD0gV0lORUQzRENVQkVNQVBfRkFDRV9ORUdBVElWRV9aOyArK2ZhY2VUeXBlKXsKICAgICAgICAgICAgICAgICAgICAgICAgaHIgPSBJV2luZUQzREN1YmVUZXh0dXJlX0dldEN1YmVNYXBTdXJmYWNlKChJV2luZUQzREN1YmVUZXh0dXJlICopcFNvdXJjZVRleHR1cmUsICAgICAgZmFjZVR5cGUsIGksICZzcmNTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFdJTkVEM0RfT0sgIT0gaHIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWE1FKCIoJXApIDogRmFpbGVkIHRvIGdldCBzcmMgY3ViZSBzdXJmYWNlIGZhY2V0eXBlICVkLCBsZXZlbCAlZFxuIiwgVGhpcywgZmFjZVR5cGUsIGkpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIkdvdCBzcmNTdXJmYWNlICVwXG4iLCBzcmNTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBociA9IElXaW5lRDNEQ3ViZVRleHR1cmVfR2V0Q3ViZU1hcFN1cmZhY2UoKElXaW5lRDNEQ3ViZVRleHR1cmUgKilwRGVzdGluYXRpb25UZXh0dXJlLCBmYWNlVHlwZSwgaSwgJmRlc3RTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFdJTkVEM0RfT0sgIT0gaHIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWE1FKCIoJXApIDogRmFpbGVkIHRvIGdldCBzcmMgY3ViZSBzdXJmYWNlIGZhY2V0eXBlICVkLCBsZXZlbCAlZFxuIiwgVGhpcywgZmFjZVR5cGUsIGkpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIkdvdCBkZXNyU3VyZmFjZSAlcFxuIiwgZGVzdFN1cmZhY2UpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGhyID0gSVdpbmVEM0REZXZpY2VfVXBkYXRlU3VyZmFjZShpZmFjZSwgc3JjU3VyZmFjZSwgTlVMTCwgZGVzdFN1cmZhY2UsIE5VTEwpOwogICAgICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZShzcmNTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2UoZGVzdFN1cmZhY2UpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoV0lORUQzRF9PSyAhPSBocikgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgV0FSTigiKCVwKSA6IENhbGwgdG8gdXBkYXRlIHN1cmZhY2UgZmFpbGVkXG4iLCBUaGlzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBocjsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKI2lmIDAgLyogVE9ETzogQWRkIHN1cHBvcnQgZm9yIHZvbHVtZSB0ZXh0dXJlcyAqLwogICAgICAgIGNhc2UgV0lORUQzRFJUWVBFX1ZPTFVNRVRFWFRVUkU6CiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIElXaW5lRDNEVm9sdW1lICBzcmNWb2x1bWUgID0gTlVMTDsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSBkZXN0Vm9sdW1lID0gTlVMTDsKCiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwIDsgaSA8IGxldmVscyA7ICsraSkgewogICAgICAgICAgICAgICAgICAgIElXaW5lRDNEVm9sdW1lVGV4dHVyZV9HZXRWb2x1bWUoKElXaW5lRDNEVm9sdW1lVGV4dHVyZSAqKXBTb3VyY2VUZXh0dXJlLCAgICAgIGksICZzcmNWb2x1bWUpOwogICAgICAgICAgICAgICAgICAgIElXaW5lRDNEVm9sdW1lVGV4dHVyZV9HZXRWb2x1bWUoKElXaW5lRDNEVm9sdW1lVGV4dHVyZSAqKXBEZXN0aW5hdGlvblRleHR1cmUsIGksICZkZXN0Vm9sdW1lKTsKICAgICAgICAgICAgICAgICAgICBociA9ICBJV2luZUQzREZvb19VcGRhdGVWb2x1bWUoaWZhY2UsIHNyY1ZvbHVtZSwgTlVMTCwgZGVzdFZvbHVtZSwgTlVMTCk7CiAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RWb2x1bWVfUmVsZWFzZShzcmNTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFZvbHVtZV9SZWxlYXNlKGRlc3RTdXJmYWNlKTsKICAgICAgICAgICAgICAgICAgICBpZiAoV0lORUQzRF9PSyAhPSBocikgewogICAgICAgICAgICAgICAgICAgICAgICBXQVJOKCIoJXApIDogQ2FsbCB0byB1cGRhdGUgdm9sdW1lIGZhaWxlZFxuIiwgVGhpcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBocjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiNlbmRpZgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEZJWE1FKCIoJXApIDogVW5zdXBwb3J0ZWQgc291cmNlIGFuZCBkZXN0aW5hdGlvbiB0eXBlXG4iLCBUaGlzKTsKICAgICAgICAgICAgaHIgPSBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRGcm9udEJ1ZmZlckRhdGEoSVdpbmVEM0REZXZpY2UgKmlmYWNlLFVJTlQgaVN3YXBDaGFpbiwgSVdpbmVEM0RTdXJmYWNlICpwRGVzdFN1cmZhY2UpIHsKICAgIElXaW5lRDNEU3dhcENoYWluICpzd2FwQ2hhaW47CiAgICBIUkVTVUxUIGhyOwogICAgaHIgPSBJV2luZUQzRERldmljZUltcGxfR2V0U3dhcENoYWluKGlmYWNlLCAgaVN3YXBDaGFpbiwgKElXaW5lRDNEU3dhcENoYWluICoqKSZzd2FwQ2hhaW4pOwogICAgaWYoaHIgPT0gV0lORUQzRF9PSykgewogICAgICAgIGhyID0gSVdpbmVEM0RTd2FwQ2hhaW5fR2V0RnJvbnRCdWZmZXJEYXRhKHN3YXBDaGFpbiwgcERlc3RTdXJmYWNlKTsKICAgICAgICAgICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2Uoc3dhcENoYWluKTsKICAgIH0KICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX1ZhbGlkYXRlRGV2aWNlKElXaW5lRDNERGV2aWNlICppZmFjZSwgRFdPUkQqIHBOdW1QYXNzZXMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIC8qIHJldHVybiBhIHNlbnNpYmxlIGRlZmF1bHQgKi8KICAgICpwTnVtUGFzc2VzID0gMTsKICAgIC8qIFRPRE86IElmIHRoZSB3aW5kb3cgaXMgbWluaW1pemVkIHRoZW4gdmFsaWRhdGUgZGV2aWNlIHNob3VsZCByZXR1cm4gc29tZXRoaW5nIG90aGVyIHRoYW4gV0lORUQzRF9PSyAqLwogICAgRklYTUUoIiglcCkgOiBzdHViXG4iLCBUaGlzKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfU2V0UGFsZXR0ZUVudHJpZXMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBVSU5UIFBhbGV0dGVOdW1iZXIsIENPTlNUIFBBTEVUVEVFTlRSWSogcEVudHJpZXMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIGludCBqOwogICAgVFJBQ0UoIiglcCkgOiBQYWxldHRlTnVtYmVyICV1XG4iLCBUaGlzLCBQYWxldHRlTnVtYmVyKTsKICAgIGlmICggUGFsZXR0ZU51bWJlciA8IDAgfHwgUGFsZXR0ZU51bWJlciA+PSBNQVhfUEFMRVRURVMpIHsKICAgICAgICBXQVJOKCIoJXApIDogKCV1KSBPdXQgb2YgcmFuZ2UgMC0ldSwgcmV0dXJuaW5nIEludmFsaWQgQ2FsbFxuIiwgVGhpcywgUGFsZXR0ZU51bWJlciwgTUFYX1BBTEVUVEVTKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIGZvciAoaiA9IDA7IGogPCAyNTY7ICsraikgewogICAgICAgIFRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdW2pdLnBlUmVkICAgPSBwRW50cmllc1tqXS5wZVJlZDsKICAgICAgICBUaGlzLT5wYWxldHRlc1tQYWxldHRlTnVtYmVyXVtqXS5wZUdyZWVuID0gcEVudHJpZXNbal0ucGVHcmVlbjsKICAgICAgICBUaGlzLT5wYWxldHRlc1tQYWxldHRlTnVtYmVyXVtqXS5wZUJsdWUgID0gcEVudHJpZXNbal0ucGVCbHVlOwogICAgICAgIFRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdW2pdLnBlRmxhZ3MgPSBwRW50cmllc1tqXS5wZUZsYWdzOwogICAgfQogICAgVFJBQ0UoIiglcCkgOiByZXR1cm5pbmdcbiIsIFRoaXMpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRQYWxldHRlRW50cmllcyhJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgUGFsZXR0ZU51bWJlciwgUEFMRVRURUVOVFJZKiBwRW50cmllcykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaW50IGo7CiAgICBUUkFDRSgiKCVwKSA6IFBhbGV0dGVOdW1iZXIgJXVcbiIsIFRoaXMsIFBhbGV0dGVOdW1iZXIpOwogICAgaWYgKCBQYWxldHRlTnVtYmVyIDwgMCB8fCBQYWxldHRlTnVtYmVyID49IE1BWF9QQUxFVFRFUykgewogICAgICAgIFdBUk4oIiglcCkgOiAoJXUpIE91dCBvZiByYW5nZSAwLSV1LCByZXR1cm5pbmcgSW52YWxpZCBDYWxsXG4iLCBUaGlzLCBQYWxldHRlTnVtYmVyLCBNQVhfUEFMRVRURVMpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQogICAgZm9yIChqID0gMDsgaiA8IDI1NjsgKytqKSB7CiAgICAgICAgcEVudHJpZXNbal0ucGVSZWQgICA9IFRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdW2pdLnBlUmVkOwogICAgICAgIHBFbnRyaWVzW2pdLnBlR3JlZW4gPSBUaGlzLT5wYWxldHRlc1tQYWxldHRlTnVtYmVyXVtqXS5wZUdyZWVuOwogICAgICAgIHBFbnRyaWVzW2pdLnBlQmx1ZSAgPSBUaGlzLT5wYWxldHRlc1tQYWxldHRlTnVtYmVyXVtqXS5wZUJsdWU7CiAgICAgICAgcEVudHJpZXNbal0ucGVGbGFncyA9IFRoaXMtPnBhbGV0dGVzW1BhbGV0dGVOdW1iZXJdW2pdLnBlRmxhZ3M7CiAgICB9CiAgICBUUkFDRSgiKCVwKSA6IHJldHVybmluZ1xuIiwgVGhpcyk7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEN1cnJlbnRUZXh0dXJlUGFsZXR0ZShJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgUGFsZXR0ZU51bWJlcikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiBQYWxldHRlTnVtYmVyICV1XG4iLCBUaGlzLCBQYWxldHRlTnVtYmVyKTsKICAgIGlmICggUGFsZXR0ZU51bWJlciA8IDAgfHwgUGFsZXR0ZU51bWJlciA+PSBNQVhfUEFMRVRURVMpIHsKICAgICAgICBXQVJOKCIoJXApIDogKCV1KSBPdXQgb2YgcmFuZ2UgMC0ldSwgcmV0dXJuaW5nIEludmFsaWQgQ2FsbFxuIiwgVGhpcywgUGFsZXR0ZU51bWJlciwgTUFYX1BBTEVUVEVTKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIC8qVE9ETzogc3RhdGVibG9ja3MgKi8KICAgIFRoaXMtPmN1cnJlbnRQYWxldHRlID0gUGFsZXR0ZU51bWJlcjsKICAgIFRSQUNFKCIoJXApIDogcmV0dXJuaW5nXG4iLCBUaGlzKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfR2V0Q3VycmVudFRleHR1cmVQYWxldHRlKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCogUGFsZXR0ZU51bWJlcikgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgaWYgKFBhbGV0dGVOdW1iZXIgPT0gTlVMTCkgewogICAgICAgIFdBUk4oIiglcCkgOiByZXR1cm5pbmcgSW52YWxpZCBDYWxsXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIC8qVE9ETzogc3RhdGVibG9ja3MgKi8KICAgICpQYWxldHRlTnVtYmVyID0gVGhpcy0+Y3VycmVudFBhbGV0dGU7CiAgICBUUkFDRSgiKCVwKSA6IHJldHVybmluZyAgJXVcbiIsIFRoaXMsICpQYWxldHRlTnVtYmVyKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfU2V0U29mdHdhcmVWZXJ0ZXhQcm9jZXNzaW5nKElXaW5lRDNERGV2aWNlICppZmFjZSwgQk9PTCBiU29mdHdhcmUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIHN0YXRpYyBCT09MIHNob3dGaXhtZXMgPSBUUlVFOwogICAgaWYgKHNob3dGaXhtZXMpIHsKICAgICAgICBGSVhNRSgiKCVwKSA6IHN0dWJcbiIsIFRoaXMpOwogICAgICAgIHNob3dGaXhtZXMgPSBGQUxTRTsKICAgIH0KCiAgICBUaGlzLT5zb2Z0d2FyZVZlcnRleFByb2Nlc3NpbmcgPSBiU29mdHdhcmU7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKCnN0YXRpYyBCT09MICAgICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTb2Z0d2FyZVZlcnRleFByb2Nlc3NpbmcoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBzdGF0aWMgQk9PTCBzaG93Rml4bWVzID0gVFJVRTsKICAgIGlmIChzaG93Rml4bWVzKSB7CiAgICAgICAgRklYTUUoIiglcCkgOiBzdHViXG4iLCBUaGlzKTsKICAgICAgICBzaG93Rml4bWVzID0gRkFMU0U7CiAgICB9CiAgICByZXR1cm4gVGhpcy0+c29mdHdhcmVWZXJ0ZXhQcm9jZXNzaW5nOwp9CgoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFJhc3RlclN0YXR1cyhJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgaVN3YXBDaGFpbiwgV0lORUQzRFJBU1RFUl9TVEFUVVMqIHBSYXN0ZXJTdGF0dXMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3dhcENoYWluICpzd2FwQ2hhaW47CiAgICBIUkVTVUxUIGhyOwoKICAgIFRSQUNFKCIoJXApIDogIFN3YXBDaGFpbiAlZCByZXR1cm5pbmcgJXBcbiIsIFRoaXMsIGlTd2FwQ2hhaW4sIHBSYXN0ZXJTdGF0dXMpOwoKICAgIGhyID0gSVdpbmVEM0REZXZpY2VJbXBsX0dldFN3YXBDaGFpbihpZmFjZSwgIGlTd2FwQ2hhaW4sIChJV2luZUQzRFN3YXBDaGFpbiAqKikmc3dhcENoYWluKTsKICAgIGlmKGhyID09IFdJTkVEM0RfT0spewogICAgICAgIGhyID0gSVdpbmVEM0RTd2FwQ2hhaW5fR2V0UmFzdGVyU3RhdHVzKHN3YXBDaGFpbiwgcFJhc3RlclN0YXR1cyk7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwQ2hhaW4pOwogICAgfWVsc2V7CiAgICAgICAgRklYTUUoIiglcCkgSVdpbmVEM0RTd2FwQ2hhaW5fR2V0UmFzdGVyU3RhdHVzIHJldHVybmVkIGluIGVycm9yXG4iLCBUaGlzKTsKICAgIH0KICAgIHJldHVybiBocjsKfQoKCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9TZXROUGF0Y2hNb2RlKElXaW5lRDNERGV2aWNlICppZmFjZSwgZmxvYXQgblNlZ21lbnRzKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBzdGF0aWMgQk9PTCBzaG93Zml4bWVzID0gVFJVRTsKICAgIGlmKG5TZWdtZW50cyAhPSAwLjBmKSB7CiAgICAgICAgaWYoIHNob3dmaXhtZXMpIHsKICAgICAgICAgICAgRklYTUUoIiglcCkgOiBzdHViIG5TZWdtZW50cyglZilcbiIsIFRoaXMsIG5TZWdtZW50cyk7CiAgICAgICAgICAgIHNob3dmaXhtZXMgPSBGQUxTRTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIGZsb2F0ICAgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0dldE5QYXRjaE1vZGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBzdGF0aWMgQk9PTCBzaG93Zml4bWVzID0gVFJVRTsKICAgIGlmKCBzaG93Zml4bWVzKSB7CiAgICAgICAgRklYTUUoIiglcCkgOiBzdHViIHJldHVybmluZyglZilcbiIsIFRoaXMsIDAuMGYpOwogICAgICAgIHNob3dmaXhtZXMgPSBGQUxTRTsKICAgIH0KICAgIHJldHVybiAwLjBmOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfVXBkYXRlU3VyZmFjZShJV2luZUQzRERldmljZSAqaWZhY2UsIElXaW5lRDNEU3VyZmFjZSAqcFNvdXJjZVN1cmZhY2UsIENPTlNUIFJFQ1QqIHBTb3VyY2VSZWN0LCBJV2luZUQzRFN1cmZhY2UgKnBEZXN0aW5hdGlvblN1cmZhY2UsIENPTlNUIFBPSU5UKiBwRGVzdFBvaW50KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgICpUaGlzICAgICAgICAgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgLyoqIFRPRE86IHJlbW92ZSBjYXN0cyB0byBJV2luZUQzRFN1cmZhY2VJbXBsCiAgICAgKiAgICAgICBOT1RFOiBtb3ZlIGNvZGUgdG8gc3VyZmFjZSB0byBhY2NvbXBsaXNoIHRoaXMKICAgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKnBTcmNTdXJmYWNlICA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopcFNvdXJjZVN1cmZhY2U7CiAgICBpbnQgc3JjV2lkdGgsIHNyY0hlaWdodDsKICAgIHVuc2lnbmVkIGludCAgc3JjU3VyZmFjZVdpZHRoLCBzcmNTdXJmYWNlSGVpZ2h0LCBkZXN0U3VyZmFjZVdpZHRoLCBkZXN0U3VyZmFjZUhlaWdodDsKICAgIFdJTkVEM0RGT1JNQVQgZGVzdEZvcm1hdCwgc3JjRm9ybWF0OwogICAgVUlOVCAgICAgICAgICBkZXN0U2l6ZTsKICAgIGludCBzcmNMZWZ0LCBkZXN0TGVmdCwgZGVzdFRvcDsKICAgIFdJTkVEM0RQT09MICAgICAgIHNyY1Bvb2wsIGRlc3RQb29sOwogICAgaW50IG9mZnNldCAgICA9IDA7CiAgICBpbnQgcm93b2Zmc2V0ID0gMDsgLyogaG93IG1hbnkgYnl0ZXMgdG8gYWRkIG9udG8gdGhlIGVuZCBvZiBhIHJvdyB0byB3cmFwYXJvdW5kIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIG5leHQgKi8KICAgIGdsRGVzY3JpcHRvciAqZ2xEZXNjcmlwdGlvbiA9IE5VTEw7CgogICAgV0lORUQzRFNVUkZBQ0VfREVTQyAgd2luZWRlc2M7CgogICAgVFJBQ0UoIiglcCkgOiBTb3VyY2UgKCVwKSAgUmVjdCAoJXApIERlc3RpbmF0aW9uICglcCkgUG9pbnQoJXApXG4iLCBUaGlzLCBwU291cmNlU3VyZmFjZSwgcFNvdXJjZVJlY3QsIHBEZXN0aW5hdGlvblN1cmZhY2UsIHBEZXN0UG9pbnQpOwogICAgbWVtc2V0KCZ3aW5lZGVzYywgMCwgc2l6ZW9mKHdpbmVkZXNjKSk7CiAgICB3aW5lZGVzYy5XaWR0aCAgPSAmc3JjU3VyZmFjZVdpZHRoOwogICAgd2luZWRlc2MuSGVpZ2h0ID0gJnNyY1N1cmZhY2VIZWlnaHQ7CiAgICB3aW5lZGVzYy5Qb29sICAgPSAmc3JjUG9vbDsKICAgIHdpbmVkZXNjLkZvcm1hdCA9ICZzcmNGb3JtYXQ7CgogICAgSVdpbmVEM0RTdXJmYWNlX0dldERlc2MocFNvdXJjZVN1cmZhY2UsICZ3aW5lZGVzYyk7CgogICAgd2luZWRlc2MuV2lkdGggID0gJmRlc3RTdXJmYWNlV2lkdGg7CiAgICB3aW5lZGVzYy5IZWlnaHQgPSAmZGVzdFN1cmZhY2VIZWlnaHQ7CiAgICB3aW5lZGVzYy5Qb29sICAgPSAmZGVzdFBvb2w7CiAgICB3aW5lZGVzYy5Gb3JtYXQgPSAmZGVzdEZvcm1hdDsKICAgIHdpbmVkZXNjLlNpemUgICA9ICZkZXN0U2l6ZTsKCiAgICBJV2luZUQzRFN1cmZhY2VfR2V0RGVzYyhwRGVzdGluYXRpb25TdXJmYWNlLCAmd2luZWRlc2MpOwoKICAgIGlmKHNyY1Bvb2wgIT0gV0lORUQzRFBPT0xfU1lTVEVNTUVNICB8fCBkZXN0UG9vbCAhPSBXSU5FRDNEUE9PTF9ERUZBVUxUKXsKICAgICAgICBXQVJOKCJzb3VyY2UgJXAgbXVzdCBiZSBTWVNURU1NRU0gYW5kIGRlc3QgJXAgbXVzdCBiZSBERUZBVUxULCByZXR1cm5pbmcgV0lORUQzREVSUl9JTlZBTElEQ0FMTFxuIiwgcFNvdXJjZVN1cmZhY2UsIHBEZXN0aW5hdGlvblN1cmZhY2UpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIGlmIChkZXN0Rm9ybWF0ID09IFdJTkVEM0RGTVRfVU5LTk9XTikgewogICAgICAgIFRSQUNFKCIoJXApIDogQ29udmVydGluZyBkZXN0aW5hdGlvbiBzdXJmYWNlIGZyb20gV0lORUQzREZNVF9VTktOT1dOIHRvIHRoZSBzb3VyY2UgZm9ybWF0XG4iLCBUaGlzKTsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Rm9ybWF0KHBEZXN0aW5hdGlvblN1cmZhY2UsIHNyY0Zvcm1hdCk7CgogICAgICAgIC8qIEdldCB0aGUgdXBkYXRlIHN1cmZhY2UgZGVzY3JpcHRpb24gKi8KICAgICAgICBJV2luZUQzRFN1cmZhY2VfR2V0RGVzYyhwRGVzdGluYXRpb25TdXJmYWNlLCAmd2luZWRlc2MpOwogICAgfQoKICAgIEVOVEVSX0dMKCk7CgogICAgQWN0aXZhdGVDb250ZXh0KFRoaXMsIFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQsIENUWFVTQUdFX1JFU09VUkNFTE9BRCk7CgogICAgaWYgKEdMX1NVUFBPUlQoQVJCX01VTFRJVEVYVFVSRSkpIHsKICAgICAgICBHTF9FWFRDQUxMKGdsQWN0aXZlVGV4dHVyZUFSQihHTF9URVhUVVJFMF9BUkIpKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xBY3RpdmVUZXh0dXJlQVJCIik7CiAgICB9CgogICAgLyogTWFrZSBzdXJlIHRoZSBzdXJmYWNlIGlzIGxvYWRlZCBhbmQgdXAgdG8gZGF0ZSAqLwogICAgSVdpbmVEM0RTdXJmYWNlX1ByZUxvYWQocERlc3RpbmF0aW9uU3VyZmFjZSk7CgogICAgSVdpbmVEM0RTdXJmYWNlX0dldEdsRGVzYyhwRGVzdGluYXRpb25TdXJmYWNlLCAmZ2xEZXNjcmlwdGlvbik7CgogICAgLyogdGhpcyBuZWVkcyB0byBiZSBkb25lIGluIGxpbmVzIGlmIHRoZSBzb3VyY2VSZWN0ICE9IHRoZSBzb3VyY2VXaWR0aCAqLwogICAgc3JjV2lkdGggICA9IHBTb3VyY2VSZWN0ID8gcFNvdXJjZVJlY3QtPnJpZ2h0IC0gcFNvdXJjZVJlY3QtPmxlZnQgICA6IHNyY1N1cmZhY2VXaWR0aDsKICAgIHNyY0hlaWdodCAgPSBwU291cmNlUmVjdCA/IHBTb3VyY2VSZWN0LT5ib3R0b20gLSBwU291cmNlUmVjdC0+dG9wICAgOiBzcmNTdXJmYWNlSGVpZ2h0OwogICAgc3JjTGVmdCAgICA9IHBTb3VyY2VSZWN0ID8gcFNvdXJjZVJlY3QtPmxlZnQgOiAwOwogICAgZGVzdExlZnQgICA9IHBEZXN0UG9pbnQgID8gcERlc3RQb2ludC0+eCA6IDA7CiAgICBkZXN0VG9wICAgID0gcERlc3RQb2ludCAgPyBwRGVzdFBvaW50LT55IDogMDsKCgogICAgLyogVGhpcyBmdW5jdGlvbiBkb2Vzbid0IHN1cHBvcnQgY29tcHJlc3NlZCB0ZXh0dXJlcwogICAgdGhlIHBpdGNoIGlzIGp1c3QgYnl0ZXNQZXJQaXhlbCAqIHdpZHRoICovCiAgICBpZihzcmNXaWR0aCAhPSBzcmNTdXJmYWNlV2lkdGggIHx8IHNyY0xlZnQgKXsKICAgICAgICByb3dvZmZzZXQgPSAoc3JjU3VyZmFjZVdpZHRoIC0gc3JjV2lkdGgpICogcFNyY1N1cmZhY2UtPmJ5dGVzUGVyUGl4ZWw7CiAgICAgICAgb2Zmc2V0ICAgKz0gc3JjTGVmdCAqIHBTcmNTdXJmYWNlLT5ieXRlc1BlclBpeGVsOwogICAgICAgIC8qIFRPRE86IGRvIHdlIGV2ZXIgZ2V0IDNicHA/LCB3b3VsZCBhIHNoaWZ0IGFuZCBhbiBhZGQgYmUgcXVpY2tlciB0aGFuIGEgbXVsICh3ZWxsIG1heWJlIGEgY3ljbGUgb3IgdHdvKSAqLwogICAgfQogICAgLyogVE9ETyBEWFQgZm9ybWF0cyAqLwoKICAgIGlmKHBTb3VyY2VSZWN0ICE9IE5VTEwgJiYgcFNvdXJjZVJlY3QtPnRvcCAhPSAwKXsKICAgICAgIG9mZnNldCArPSAgcFNvdXJjZVJlY3QtPnRvcCAqIHNyY1dpZHRoICogcFNyY1N1cmZhY2UtPmJ5dGVzUGVyUGl4ZWw7CiAgICB9CiAgICBUUkFDRSgiKCVwKSBnbFRleFN1YkltYWdlMkQsIExldmVsICVkLCBsZWZ0ICVkLCB0b3AgJWQsIHdpZHRoICVkLCBoZWlnaHQgJWQgLCBmdG0gJWQsIHR5cGUgJWQsIG1lbW9yeSAlcFxuIgogICAgLFRoaXMKICAgICxnbERlc2NyaXB0aW9uLT5sZXZlbAogICAgLGRlc3RMZWZ0CiAgICAsZGVzdFRvcAogICAgLHNyY1dpZHRoCiAgICAsc3JjSGVpZ2h0CiAgICAsZ2xEZXNjcmlwdGlvbi0+Z2xGb3JtYXQKICAgICxnbERlc2NyaXB0aW9uLT5nbFR5cGUKICAgICxJV2luZUQzRFN1cmZhY2VfR2V0RGF0YShwU291cmNlU3VyZmFjZSkKICAgICk7CgogICAgLyogU2FuaXR5IGNoZWNrICovCiAgICBpZiAoSVdpbmVEM0RTdXJmYWNlX0dldERhdGEocFNvdXJjZVN1cmZhY2UpID09IE5VTEwpIHsKCiAgICAgICAgLyogbmVlZCB0byBsb2NrIHRoZSBzdXJmYWNlIHRvIGdldCB0aGUgZGF0YSAqLwogICAgICAgIEZJWE1FKCJTdXJmYWNlcyBoYXMgbm8gYWxsb2NhdGVkIG1lbW9yeSwgYnV0IHNob3VsZCBiZSBhbiBpbiBtZW1vcnkgb25seSBzdXJmYWNlXG4iKTsKICAgIH0KCiAgICAvKiBUT0RPOiBDdWJlIGFuZCB2b2x1bWUgc3VwcG9ydCAqLwogICAgaWYocm93b2Zmc2V0ICE9IDApewogICAgICAgIC8qIG5vdCBhIHdob2xlIHJvdyBzbyB3ZSBoYXZlIHRvIGRvIGl0IGEgbGluZSBhdCBhIHRpbWUgKi8KICAgICAgICBpbnQgajsKCiAgICAgICAgLyogaG9wZWZ1bGx5IHVzaW5nIHBvaW50ZXIgYWRkdGlvbiB3aWxsIGJlIHF1aWNrZXIgdGhhbiB1c2luZyBhIHBvaW50ICsgaiAqIHJvd29mZnNldCAqLwogICAgICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIqIGRhdGEgPSgoY29uc3QgdW5zaWduZWQgY2hhciAqKUlXaW5lRDNEU3VyZmFjZV9HZXREYXRhKHBTb3VyY2VTdXJmYWNlKSkgKyBvZmZzZXQ7CgogICAgICAgIGZvcihqID0gZGVzdFRvcCA7IGogPCAoc3JjSGVpZ2h0ICsgZGVzdFRvcCkgOyBqKyspewoKICAgICAgICAgICAgICAgIGdsVGV4U3ViSW1hZ2UyRChnbERlc2NyaXB0aW9uLT50YXJnZXQKICAgICAgICAgICAgICAgICAgICAsZ2xEZXNjcmlwdGlvbi0+bGV2ZWwKICAgICAgICAgICAgICAgICAgICAsZGVzdExlZnQKICAgICAgICAgICAgICAgICAgICAsagogICAgICAgICAgICAgICAgICAgICxzcmNXaWR0aAogICAgICAgICAgICAgICAgICAgICwxCiAgICAgICAgICAgICAgICAgICAgLGdsRGVzY3JpcHRpb24tPmdsRm9ybWF0CiAgICAgICAgICAgICAgICAgICAgLGdsRGVzY3JpcHRpb24tPmdsVHlwZQogICAgICAgICAgICAgICAgICAgICxkYXRhIC8qIGNvdWxkIGJlIHF1aWNrZXIgdXNpbmcgKi8KICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIGRhdGEgKz0gcm93b2Zmc2V0OwogICAgICAgIH0KCiAgICB9IGVsc2UgeyAvKiBGdWxsIHdpZHRoLCBzbyBqdXN0IHdyaXRlIG91dCB0aGUgd2hvbGUgdGV4dHVyZSAqLwoKICAgICAgICBpZiAoV0lORUQzREZNVF9EWFQxID09IGRlc3RGb3JtYXQgfHwKICAgICAgICAgICAgV0lORUQzREZNVF9EWFQyID09IGRlc3RGb3JtYXQgfHwKICAgICAgICAgICAgV0lORUQzREZNVF9EWFQzID09IGRlc3RGb3JtYXQgfHwKICAgICAgICAgICAgV0lORUQzREZNVF9EWFQ0ID09IGRlc3RGb3JtYXQgfHwKICAgICAgICAgICAgV0lORUQzREZNVF9EWFQ1ID09IGRlc3RGb3JtYXQpIHsKICAgICAgICAgICAgaWYgKEdMX1NVUFBPUlQoRVhUX1RFWFRVUkVfQ09NUFJFU1NJT05fUzNUQykpIHsKICAgICAgICAgICAgICAgIGlmIChkZXN0U3VyZmFjZUhlaWdodCAhPSBzcmNIZWlnaHQgfHwgZGVzdFN1cmZhY2VXaWR0aCAhPSBzcmNXaWR0aCkgewogICAgICAgICAgICAgICAgICAgIC8qIEZJWE1FOiBUaGUgZWFzeSB3YXkgdG8gZG8gdGhpcyBpcyB0byBsb2NrIHRoZSBkZXN0aW5hdGlvbiwgYW5kIGNvcHkgdGhlIGJpdHMgYWNyb3NzICovCiAgICAgICAgICAgICAgICAgICAgRklYTUUoIlVwZGF0aW5nIHBhcnQgb2YgYSBjb21wcmVzc2VkIHRleHR1cmUgaXMgbm90IHN1cHBvcnRlZCBhdCB0aGUgbW9tZW50XG4iKTsKICAgICAgICAgICAgICAgIH0gaWYgKGRlc3RGb3JtYXQgIT0gc3JjRm9ybWF0KSB7CiAgICAgICAgICAgICAgICAgICAgRklYTUUoIlVwZGF0aW5nIG1peGVkIGZvcm1hdCBjb21wcmVzc2VkIHRleHR1cmUgaXMgbm90IGN1cnJldGx5IHN1cHBvcnRcbiIpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsQ29tcHJlc3NlZFRleEltYWdlMkRBUkIpKGdsRGVzY3JpcHRpb24tPnRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbERlc2NyaXB0aW9uLT5sZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbERlc2NyaXB0aW9uLT5nbEZvcm1hdEludGVybmFsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyY1dpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyY0hlaWdodCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc3RTaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9HZXREYXRhKHBTb3VyY2VTdXJmYWNlKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBGSVhNRSgiQXR0ZW1wdGluZyB0byB1cGRhdGUgYSBEWFQgY29tcHJlc3NlZCB0ZXh0dXJlIHdpdGhvdXQgaGFyZHdhcmUgc3VwcG9ydFxuIik7CiAgICAgICAgICAgIH0KCgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGdsVGV4U3ViSW1hZ2UyRChnbERlc2NyaXB0aW9uLT50YXJnZXQKICAgICAgICAgICAgICAgICAgICAsZ2xEZXNjcmlwdGlvbi0+bGV2ZWwKICAgICAgICAgICAgICAgICAgICAsZGVzdExlZnQKICAgICAgICAgICAgICAgICAgICAsZGVzdFRvcAogICAgICAgICAgICAgICAgICAgICxzcmNXaWR0aAogICAgICAgICAgICAgICAgICAgICxzcmNIZWlnaHQKICAgICAgICAgICAgICAgICAgICAsZ2xEZXNjcmlwdGlvbi0+Z2xGb3JtYXQKICAgICAgICAgICAgICAgICAgICAsZ2xEZXNjcmlwdGlvbi0+Z2xUeXBlCiAgICAgICAgICAgICAgICAgICAgLElXaW5lRDNEU3VyZmFjZV9HZXREYXRhKHBTb3VyY2VTdXJmYWNlKQogICAgICAgICAgICAgICAgKTsKICAgICAgICB9CiAgICAgfQogICAgY2hlY2tHTGNhbGwoImdsVGV4U3ViSW1hZ2UyRCIpOwoKICAgIExFQVZFX0dMKCk7CgogICAgKChJV2luZUQzRFN1cmZhY2VJbXBsICopcERlc3RpbmF0aW9uU3VyZmFjZSktPkZsYWdzICY9IH5TRkxBR19JTlNZU01FTTsKICAgICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKXBEZXN0aW5hdGlvblN1cmZhY2UpLT5GbGFncyB8PSBTRkxBR19JTlRFWFRVUkU7CiAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfU0FNUExFUigwKSk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCi8qIEltcGxlbWVudGF0aW9uIGRldGFpbHMgYXQgaHR0cDovL2RldmVsb3Blci5udmlkaWEuY29tL2F0dGFjaC82NDk0CmFuZApodHRwOi8vb3NzLnNnaS5jb20vcHJvamVjdHMvb2dsLXNhbXBsZS9yZWdpc3RyeS9OVi9ldmFsdWF0b3JzLnR4dApobW0uLiBubyBsb25nZXIgc3VwcG9ydGVkIHVzZQpPcGVuR0wgZXZhbHVhdG9ycyBvciAgdGVzc2VsbGF0ZSBzdXJmYWNlcyB3aXRoaW4geW91ciBhcHBsaWNhdGlvbi4KKi8KCi8qIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vbGlicmFyeS9kZWZhdWx0LmFzcD91cmw9L2xpYnJhcnkvZW4tdXMvZGlyZWN0eDlfYy9kaXJlY3R4L2dyYXBoaWNzL3JlZmVyZW5jZS9kM2QvaW50ZXJmYWNlcy9pZGlyZWN0M2RkZXZpY2U5L0RyYXdSZWN0UGF0Y2guYXNwICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfRHJhd1JlY3RQYXRjaChJV2luZUQzRERldmljZSAqaWZhY2UsIFVJTlQgSGFuZGxlLCBDT05TVCBmbG9hdCogcE51bVNlZ3MsIENPTlNUIFdJTkVEM0RSRUNUUEFUQ0hfSU5GTyogcFJlY3RQYXRjaEluZm8pIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIEhhbmRsZSglZCkgbm9TZWdzKCVwKSByZWN0cGF0Y2goJXApXG4iLCBUaGlzLCBIYW5kbGUsIHBOdW1TZWdzLCBwUmVjdFBhdGNoSW5mbyk7CiAgICBGSVhNRSgiKCVwKSA6IFN0dWJcbiIsIFRoaXMpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cgp9CgovKiBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZGVmYXVsdC5hc3A/dXJsPS9saWJyYXJ5L2VuLXVzL2RpcmVjdHg5X2MvZGlyZWN0eC9ncmFwaGljcy9yZWZlcmVuY2UvZDNkL2ludGVyZmFjZXMvaWRpcmVjdDNkZGV2aWNlOS9EcmF3VHJpUGF0Y2guYXNwICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfRHJhd1RyaVBhdGNoKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBIYW5kbGUsIENPTlNUIGZsb2F0KiBwTnVtU2VncywgQ09OU1QgV0lORUQzRFRSSVBBVENIX0lORk8qIHBUcmlQYXRjaEluZm8pIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIEhhbmRsZSglZCkgbm9TZWdzKCVwKSB0cmlwYXRjaCglcClcbiIsIFRoaXMsIEhhbmRsZSwgcE51bVNlZ3MsIHBUcmlQYXRjaEluZm8pOwogICAgRklYTUUoIiglcCkgOiBTdHViXG4iLCBUaGlzKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0RlbGV0ZVBhdGNoKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBIYW5kbGUpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApIEhhbmRsZSglZClcbiIsIFRoaXMsIEhhbmRsZSk7CiAgICBGSVhNRSgiKCVwKSA6IFN0dWJcbiIsIFRoaXMpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfQ29sb3JGaWxsKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RTdXJmYWNlICpwU3VyZmFjZSwgQ09OU1QgV0lORUQzRFJFQ1QqIHBSZWN0LCBXSU5FRDNEQ09MT1IgY29sb3IpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpzdXJmYWNlID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgcFN1cmZhY2U7CiAgICBEREJMVEZYIEJsdEZ4OwogICAgVFJBQ0UoIiglcCkgQ29sb3VyIGZpbGwgU3VyZmFjZTogJXAgcmVjdDogJXAgY29sb3I6ICVkXG4iLCBUaGlzLCBwU3VyZmFjZSwgcFJlY3QsIGNvbG9yKTsKCiAgICBpZiAoc3VyZmFjZS0+cmVzb3VyY2UucG9vbCAhPSBXSU5FRDNEUE9PTF9ERUZBVUxUICYmIHN1cmZhY2UtPnJlc291cmNlLnBvb2wgIT0gV0lORUQzRFBPT0xfU1lTVEVNTUVNKSB7CiAgICAgICAgRklYTUUoImNhbGwgdG8gY29sb3JmaWxsIHdpdGggbm9uIFdJTkVEM0RQT09MX0RFRkFVTFQgb3IgV0lORUQzRFBPT0xfU1lTVEVNTUVNIHN1cmZhY2VcbiIpOwogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQoKICAgIC8qIEp1c3QgZm9yd2FyZCB0aGlzIHRvIHRoZSBEaXJlY3REcmF3IGJsaXR0aW5nIGVuZ2luZSAqLwogICAgbWVtc2V0KCZCbHRGeCwgMCwgc2l6ZW9mKEJsdEZ4KSk7CiAgICBCbHRGeC5kd1NpemUgPSBzaXplb2YoQmx0RngpOwogICAgQmx0RngudTUuZHdGaWxsQ29sb3IgPSBjb2xvcjsKICAgIHJldHVybiBJV2luZUQzRFN1cmZhY2VfQmx0KHBTdXJmYWNlLCAoUkVDVCAqKSBwUmVjdCwgTlVMTCwgTlVMTCwgRERCTFRfQ09MT1JGSUxMLCAmQmx0RngpOwp9CgovKiByZW5kZXJ0YXJnZXQgYW5kIGRlcHR0aCBzdGVuY2lsIGZ1bmN0aW9ucyAqLwpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfR2V0UmVuZGVyVGFyZ2V0KElXaW5lRDNERGV2aWNlKiBpZmFjZSxEV09SRCBSZW5kZXJUYXJnZXRJbmRleCwgSVdpbmVEM0RTdXJmYWNlICoqcHBSZW5kZXJUYXJnZXQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKCiAgICBpZiAoUmVuZGVyVGFyZ2V0SW5kZXggPj0gR0xfTElNSVRTKGJ1ZmZlcnMpKSB7CiAgICAgICAgRVJSKCIoJXApIDogT25seSAlZCByZW5kZXIgdGFyZ2V0cyBhcmUgc3VwcG9ydGVkLlxuIiwgVGhpcywgR0xfTElNSVRTKGJ1ZmZlcnMpKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICAqcHBSZW5kZXJUYXJnZXQgPSBUaGlzLT5yZW5kZXJfdGFyZ2V0c1tSZW5kZXJUYXJnZXRJbmRleF07CiAgICBUUkFDRSgiKCVwKSA6IFJlbmRlclRhcmdldCAlZCBJbmRleCByZXR1cm5pbmcgJXBcbiIsIFRoaXMsIFJlbmRlclRhcmdldEluZGV4LCAqcHBSZW5kZXJUYXJnZXQpOwogICAgLyogTm90ZSBpbmMgcmVmIG9uIHJldHVybmVkIHN1cmZhY2UgKi8KICAgIGlmKCpwcFJlbmRlclRhcmdldCAhPSBOVUxMKQogICAgICAgIElXaW5lRDNEU3VyZmFjZV9BZGRSZWYoKnBwUmVuZGVyVGFyZ2V0KTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldEZyb250QmFja0J1ZmZlcnMoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBJV2luZUQzRFN1cmZhY2UgKkZyb250LCBJV2luZUQzRFN1cmZhY2UgKkJhY2spIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKkZyb250SW1wbCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIEZyb250OwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqQmFja0ltcGwgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBCYWNrOwogICAgSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICpTd2FwY2hhaW47CiAgICBIUkVTVUxUIGhyOwoKICAgIFRSQUNFKCIoJXApLT4oJXAsJXApXG4iLCBUaGlzLCBGcm9udEltcGwsIEJhY2tJbXBsKTsKCiAgICBociA9IElXaW5lRDNERGV2aWNlX0dldFN3YXBDaGFpbihpZmFjZSwgMCwgKElXaW5lRDNEU3dhcENoYWluICoqKSAmU3dhcGNoYWluKTsKICAgIGlmKGhyICE9IFdJTkVEM0RfT0spIHsKICAgICAgICBFUlIoIkNhbid0IGdldCB0aGUgc3dhcGNoYWluXG4iKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgLyogTWFrZSBzdXJlIHRvIHJlbGVhc2UgdGhlIHN3YXBjaGFpbiAqLwogICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4gKikgU3dhcGNoYWluKTsKCiAgICBpZihGcm9udEltcGwgJiYgIShGcm9udEltcGwtPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgKSB7CiAgICAgICAgRVJSKCJUcnlpbmcgdG8gc2V0IGEgZnJvbnQgYnVmZmVyIHdoaWNoIGRvZXNuJ3QgaGF2ZSBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUIHVzYWdlXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KICAgIGVsc2UgaWYoQmFja0ltcGwgJiYgIShCYWNrSW1wbC0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSkgewogICAgICAgIEVSUigiVHJ5aW5nIHRvIHNldCBhIGJhY2sgYnVmZmVyIHdoaWNoIGRvZXNuJ3QgaGF2ZSBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUIHVzYWdlXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICBpZihTd2FwY2hhaW4tPmZyb250QnVmZmVyICE9IEZyb250KSB7CiAgICAgICAgVFJBQ0UoIkNoYW5naW5nIHRoZSBmcm9udCBidWZmZXIgZnJvbSAlcCB0byAlcFxuIiwgU3dhcGNoYWluLT5mcm9udEJ1ZmZlciwgRnJvbnQpOwoKICAgICAgICBpZihTd2FwY2hhaW4tPmZyb250QnVmZmVyKQogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29udGFpbmVyKFN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIsIE5VTEwpOwogICAgICAgIFN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIgPSBGcm9udDsKCiAgICAgICAgaWYoU3dhcGNoYWluLT5mcm9udEJ1ZmZlcikgewogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfU2V0Q29udGFpbmVyKFN3YXBjaGFpbi0+ZnJvbnRCdWZmZXIsIChJV2luZUQzREJhc2UgKikgU3dhcGNoYWluKTsKICAgICAgICB9CiAgICB9CgogICAgaWYoQmFjayAmJiAhU3dhcGNoYWluLT5iYWNrQnVmZmVyKSB7CiAgICAgICAgLyogV2UgbmVlZCBtZW1vcnkgZm9yIHRoZSBiYWNrIGJ1ZmZlciBhcnJheSAtIG9ubHkgb25lIGJhY2sgYnVmZmVyIHRoaXMgd2F5ICovCiAgICAgICAgU3dhcGNoYWluLT5iYWNrQnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJV2luZUQzRFN1cmZhY2UgKikpOwogICAgICAgIGlmKCFTd2FwY2hhaW4tPmJhY2tCdWZmZXIpIHsKICAgICAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5XG4iKTsKICAgICAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICAgICAgfQogICAgfQoKICAgIGlmKFN3YXBjaGFpbi0+YmFja0J1ZmZlclswXSAhPSBCYWNrKSB7CiAgICAgICAgVFJBQ0UoIkNoYW5naW5nIHRoZSBiYWNrIGJ1ZmZlciBmcm9tICVwIHRvICVwXG4iLCBTd2FwY2hhaW4tPmJhY2tCdWZmZXIsIEJhY2spOwoKICAgICAgICAvKiBXaGF0IHRvIGRvIGFib3V0IHRoZSBjb250ZXh0IGhlcmUgaW4gdGhlIGNhc2Ugb2YgbXVsdGl0aHJlYWRpbmc/IE5vdCBzdXJlLgogICAgICAgICAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGJ5IElEaXJlY3QzRDc6OkNyZWF0ZURldmljZSBzbyBpbiB0aGVvcnkgaXRzIGluaXRpYWxpemF0aW9uIGNvZGUKICAgICAgICAgKi8KICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgIGlmKCFTd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0pIHsKICAgICAgICAgICAgLyogR0wgd2FzIHRvbGQgdG8gZHJhdyB0byB0aGUgZnJvbnQgYnVmZmVyIGF0IGNyZWF0aW9uLAogICAgICAgICAgICAgKiB1bmRvIHRoYXQKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGdsRHJhd0J1ZmZlcihHTF9CQUNLKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcihHTF9CQUNLKSIpOwogICAgICAgICAgICAvKiBTZXQgdGhlIGJhY2tidWZmZXIgY291bnQgdG8gMSBiZWNhdXNlIG90aGVyIGNvZGUgdXNlcyBpdCB0byBmaW5nIHRoZSBiYWNrIGJ1ZmZlcnMgKi8KICAgICAgICAgICAgU3dhcGNoYWluLT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckNvdW50ID0gMTsKICAgICAgICB9IGVsc2UgaWYgKCFCYWNrKSB7CiAgICAgICAgICAgIC8qIFRoYXQgbWFrZXMgcHJvYmxlbXMgLSBkaXNhYmxlIGZvciBub3cgKi8KICAgICAgICAgICAgLyogZ2xEcmF3QnVmZmVyKEdMX0ZST05UKTsgKi8KICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcihHTF9GUk9OVCkiKTsKICAgICAgICAgICAgLyogV2UgaGF2ZSBsb3N0IG91ciBiYWNrIGJ1ZmZlciwgc2V0IHRoaXMgdG8gMCB0byBhdm9pZCBjb25mdXNpbmcgb3RoZXIgY29kZSAqLwogICAgICAgICAgICBTd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyQ291bnQgPSAwOwogICAgICAgIH0KICAgICAgICBMRUFWRV9HTCgpOwoKICAgICAgICBpZihTd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0pCiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9TZXRDb250YWluZXIoU3dhcGNoYWluLT5iYWNrQnVmZmVyWzBdLCBOVUxMKTsKICAgICAgICBTd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0gPSBCYWNrOwoKICAgICAgICBpZihTd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0pIHsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1NldENvbnRhaW5lcihTd2FwY2hhaW4tPmJhY2tCdWZmZXJbMF0sIChJV2luZUQzREJhc2UgKikgU3dhcGNoYWluKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBTd2FwY2hhaW4tPmJhY2tCdWZmZXIpOwogICAgICAgIH0KCiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9HZXREZXB0aFN0ZW5jaWxTdXJmYWNlKElXaW5lRDNERGV2aWNlKiBpZmFjZSwgSVdpbmVEM0RTdXJmYWNlICoqcHBaU3RlbmNpbFN1cmZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgICpwcFpTdGVuY2lsU3VyZmFjZSA9IFRoaXMtPmRlcHRoU3RlbmNpbEJ1ZmZlcjsKICAgIFRSQUNFKCIoJXApIDogelN0ZW5jaWxTdXJmYWNlICByZXR1cm5pbmcgJXBcbiIsIFRoaXMsICAqcHBaU3RlbmNpbFN1cmZhY2UpOwoKICAgIGlmKCpwcFpTdGVuY2lsU3VyZmFjZSAhPSBOVUxMKSB7CiAgICAgICAgLyogTm90ZSBpbmMgcmVmIG9uIHJldHVybmVkIHN1cmZhY2UgKi8KICAgICAgICBJV2luZUQzRFN1cmZhY2VfQWRkUmVmKCpwcFpTdGVuY2lsU3VyZmFjZSk7CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIHZvaWQgYmluZF9mYm8oSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CgogICAgaWYgKCFUaGlzLT5mYm8pIHsKICAgICAgICBHTF9FWFRDQUxMKGdsR2VuRnJhbWVidWZmZXJzRVhUKDEsICZUaGlzLT5mYm8pKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xHZW5GcmFtZWJ1ZmZlcnNFWFQoKSIpOwogICAgfQogICAgR0xfRVhUQ0FMTChnbEJpbmRGcmFtZWJ1ZmZlckVYVChHTF9GUkFNRUJVRkZFUl9FWFQsIFRoaXMtPmZibykpOwogICAgY2hlY2tHTGNhbGwoImdsQmluZEZyYW1lYnVmZmVyKCkiKTsKfQoKLyogVE9ETzogSGFuZGxlIHN0ZW5jaWwgYXR0YWNobWVudHMgKi8Kc3RhdGljIHZvaWQgc2V0X2RlcHRoX3N0ZW5jaWxfZmJvKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RTdXJmYWNlICpkZXB0aF9zdGVuY2lsKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpkZXB0aF9zdGVuY2lsX2ltcGwgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWRlcHRoX3N0ZW5jaWw7CgogICAgVGhpcy0+ZGVwdGhfY29weV9zdGF0ZSA9IFdJTkVEM0RfRENTX05PX0NPUFk7CgogICAgYmluZF9mYm8oaWZhY2UpOwoKICAgIGlmIChkZXB0aF9zdGVuY2lsX2ltcGwpIHsKICAgICAgICBHTGVudW0gdGV4dHRhcmdldCwgdGFyZ2V0OwogICAgICAgIEdMaW50IG9sZF9iaW5kaW5nID0gMDsKCiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1ByZUxvYWQoZGVwdGhfc3RlbmNpbCk7CiAgICAgICAgdGV4dHRhcmdldCA9IGRlcHRoX3N0ZW5jaWxfaW1wbC0+Z2xEZXNjcmlwdGlvbi50YXJnZXQ7CiAgICAgICAgdGFyZ2V0ID0gdGV4dHRhcmdldCA9PSBHTF9URVhUVVJFXzJEID8gR0xfVEVYVFVSRV8yRCA6IEdMX1RFWFRVUkVfQ1VCRV9NQVBfQVJCOwoKICAgICAgICBnbEdldEludGVnZXJ2KHRleHR0YXJnZXQgPT0gR0xfVEVYVFVSRV8yRCA/IEdMX1RFWFRVUkVfQklORElOR18yRCA6IEdMX1RFWFRVUkVfQklORElOR19DVUJFX01BUF9BUkIsICZvbGRfYmluZGluZyk7CiAgICAgICAgZ2xCaW5kVGV4dHVyZSh0YXJnZXQsIGRlcHRoX3N0ZW5jaWxfaW1wbC0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSk7CiAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKHRhcmdldCwgR0xfVEVYVFVSRV9NSU5fRklMVEVSLCBHTF9ORUFSRVNUKTsKICAgICAgICBnbFRleFBhcmFtZXRlcmkodGFyZ2V0LCBHTF9URVhUVVJFX01BR19GSUxURVIsIEdMX05FQVJFU1QpOwogICAgICAgIGdsVGV4UGFyYW1ldGVyaSh0YXJnZXQsIEdMX0RFUFRIX1RFWFRVUkVfTU9ERV9BUkIsIEdMX0xVTUlOQU5DRSk7CiAgICAgICAgZ2xCaW5kVGV4dHVyZSh0YXJnZXQsIG9sZF9iaW5kaW5nKTsKCiAgICAgICAgR0xfRVhUQ0FMTChnbEZyYW1lYnVmZmVyVGV4dHVyZTJERVhUKEdMX0ZSQU1FQlVGRkVSX0VYVCwgR0xfREVQVEhfQVRUQUNITUVOVF9FWFQsIHRleHR0YXJnZXQsIGRlcHRoX3N0ZW5jaWxfaW1wbC0+Z2xEZXNjcmlwdGlvbi50ZXh0dXJlTmFtZSwgMCkpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEZyYW1lYnVmZmVyVGV4dHVyZTJERVhUKCkiKTsKICAgIH0gZWxzZSB7CiAgICAgICAgR0xfRVhUQ0FMTChnbEZyYW1lYnVmZmVyVGV4dHVyZTJERVhUKEdMX0ZSQU1FQlVGRkVSX0VYVCwgR0xfREVQVEhfQVRUQUNITUVOVF9FWFQsIEdMX1RFWFRVUkVfMkQsIDAsIDApKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xGcmFtZWJ1ZmZlclRleHR1cmUyREVYVCgpIik7CiAgICB9CgogICAgaWYgKCFUaGlzLT5yZW5kZXJfb2Zmc2NyZWVuKSB7CiAgICAgICAgR0xfRVhUQ0FMTChnbEJpbmRGcmFtZWJ1ZmZlckVYVChHTF9GUkFNRUJVRkZFUl9FWFQsIDApKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kRnJhbWVidWZmZXIoKSIpOwogICAgfQp9Cgp2b2lkIHNldF9yZW5kZXJfdGFyZ2V0X2ZibyhJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIGlkeCwgSVdpbmVEM0RTdXJmYWNlICpyZW5kZXJfdGFyZ2V0KSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpydGltcGwgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKXJlbmRlcl90YXJnZXQ7CgogICAgaWYgKGlkeCA+PSBHTF9MSU1JVFMoYnVmZmVycykpIHsKICAgICAgICBFUlIoIiVwIDogVHJ5aW5nIHRvIHNldCByZW5kZXIgdGFyZ2V0ICVkLCBidXQgb25seSAlZCBzdXBwb3J0ZWRcbiIsIFRoaXMsIGlkeCwgR0xfTElNSVRTKGJ1ZmZlcnMpKTsKICAgIH0KCiAgICBiaW5kX2ZibyhpZmFjZSk7CgogICAgaWYgKHJ0aW1wbCkgewogICAgICAgIEdMZW51bSB0ZXh0dGFyZ2V0LCB0YXJnZXQ7CiAgICAgICAgR0xpbnQgb2xkX2JpbmRpbmcgPSAwOwoKICAgICAgICBJV2luZUQzRFN1cmZhY2VfUHJlTG9hZChyZW5kZXJfdGFyZ2V0KTsKICAgICAgICB0ZXh0dGFyZ2V0ID0gcnRpbXBsLT5nbERlc2NyaXB0aW9uLnRhcmdldDsKICAgICAgICB0YXJnZXQgPSB0ZXh0dGFyZ2V0ID09IEdMX1RFWFRVUkVfMkQgPyBHTF9URVhUVVJFXzJEIDogR0xfVEVYVFVSRV9DVUJFX01BUF9BUkI7CgogICAgICAgIGdsR2V0SW50ZWdlcnYodGV4dHRhcmdldCA9PSBHTF9URVhUVVJFXzJEID8gR0xfVEVYVFVSRV9CSU5ESU5HXzJEIDogR0xfVEVYVFVSRV9CSU5ESU5HX0NVQkVfTUFQX0FSQiwgJm9sZF9iaW5kaW5nKTsKICAgICAgICBnbEJpbmRUZXh0dXJlKHRhcmdldCwgcnRpbXBsLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgICAgICBnbFRleFBhcmFtZXRlcmkodGFyZ2V0LCBHTF9URVhUVVJFX01JTl9GSUxURVIsIEdMX0xJTkVBUik7CiAgICAgICAgZ2xUZXhQYXJhbWV0ZXJpKHRhcmdldCwgR0xfVEVYVFVSRV9NQUdfRklMVEVSLCBHTF9MSU5FQVIpOwogICAgICAgIGdsQmluZFRleHR1cmUodGFyZ2V0LCBvbGRfYmluZGluZyk7CgogICAgICAgIEdMX0VYVENBTEwoZ2xGcmFtZWJ1ZmZlclRleHR1cmUyREVYVChHTF9GUkFNRUJVRkZFUl9FWFQsIEdMX0NPTE9SX0FUVEFDSE1FTlQwX0VYVCArIGlkeCwgdGV4dHRhcmdldCwgcnRpbXBsLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lLCAwKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRnJhbWVidWZmZXJUZXh0dXJlMkRFWFQoKSIpOwoKICAgICAgICBUaGlzLT5kcmF3X2J1ZmZlcnNbaWR4XSA9IEdMX0NPTE9SX0FUVEFDSE1FTlQwX0VYVCArIGlkeDsKICAgIH0gZWxzZSB7CiAgICAgICAgR0xfRVhUQ0FMTChnbEZyYW1lYnVmZmVyVGV4dHVyZTJERVhUKEdMX0ZSQU1FQlVGRkVSX0VYVCwgR0xfQ09MT1JfQVRUQUNITUVOVDBfRVhUICsgaWR4LCBHTF9URVhUVVJFXzJELCAwLCAwKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRnJhbWVidWZmZXJUZXh0dXJlMkRFWFQoKSIpOwoKICAgICAgICBUaGlzLT5kcmF3X2J1ZmZlcnNbaWR4XSA9IEdMX05PTkU7CiAgICB9CgogICAgaWYgKEdMX1NVUFBPUlQoQVJCX0RSQVdfQlVGRkVSUykpIHsKICAgICAgICBHTF9FWFRDQUxMKGdsRHJhd0J1ZmZlcnNBUkIoR0xfTElNSVRTKGJ1ZmZlcnMpLCBUaGlzLT5kcmF3X2J1ZmZlcnMpKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEcmF3QnVmZmVycygpIik7CiAgICB9CgogICAgaWYgKCFUaGlzLT5yZW5kZXJfb2Zmc2NyZWVuKSB7CiAgICAgICAgR0xfRVhUQ0FMTChnbEJpbmRGcmFtZWJ1ZmZlckVYVChHTF9GUkFNRUJVRkZFUl9FWFQsIDApKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kRnJhbWVidWZmZXIoKSIpOwogICAgfQp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldFJlbmRlclRhcmdldChJV2luZUQzRERldmljZSAqaWZhY2UsIERXT1JEIFJlbmRlclRhcmdldEluZGV4LCBJV2luZUQzRFN1cmZhY2UgKnBSZW5kZXJUYXJnZXQpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFdJTkVEM0RWSUVXUE9SVCB2aWV3cG9ydDsKCiAgICBUUkFDRSgiKCVwKSA6IFNldHRpbmcgcmVuZGVydGFyZ2V0ICVkIHRvICVwXG4iLCBUaGlzLCBSZW5kZXJUYXJnZXRJbmRleCwgcFJlbmRlclRhcmdldCk7CgogICAgaWYgKFJlbmRlclRhcmdldEluZGV4ID49IEdMX0xJTUlUUyhidWZmZXJzKSkgewogICAgICAgIEVSUigiKCVwKSA6IE9ubHkgJWQgcmVuZGVyIHRhcmdldHMgYXJlIHN1cHBvcnRlZC5cbiIsIFRoaXMsIEdMX0xJTUlUUyhidWZmZXJzKSk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogTVNETiBzYXlzIHRoYXQgbnVsbCBkaXNhYmxlcyB0aGUgcmVuZGVyIHRhcmdldAogICAgYnV0IGEgZGV2aWNlIG11c3QgYWx3YXlzIGJlIGFzc29jaWF0ZWQgd2l0aCBhIHJlbmRlciB0YXJnZXQKICAgIG5vcGUgTVNETiBzYXlzIHRoYXQgd2UgcmV0dXJuIGludmFsaWQgY2FsbCB0byBhIG51bGwgcmVuZGVydGFyZ2V0IHdpdGggYW4gaW5kZXggb2YgMAoKICAgIHNlZSBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2xpYnJhcnkvZGVmYXVsdC5hc3A/dXJsPS9saWJyYXJ5L2VuLXVzL2RpcmVjdHg5X2MvZGlyZWN0eC9ncmFwaGljcy9wcm9ncmFtbWluZ2d1aWRlL0FkdmFuY2VkVG9waWNzL1BpeGVsUGlwZS9NdWx0aXBsZVJlbmRlclRhcmdldC5hc3AKICAgIGZvciBtb3JlIGRldGFpbHMKICAgICovCiAgICBpZiAoUmVuZGVyVGFyZ2V0SW5kZXggPT0gMCAmJiBwUmVuZGVyVGFyZ2V0ID09IE5VTEwpIHsKICAgICAgICBGSVhNRSgiVHJ5aW5nIHRvIHNldCByZW5kZXIgdGFyZ2V0IDAgdG8gTlVMTFxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CiAgICBpZiAocFJlbmRlclRhcmdldCAmJiAhKChJV2luZUQzRFN1cmZhY2VJbXBsICopcFJlbmRlclRhcmdldCktPnJlc291cmNlLnVzYWdlICYgV0lORUQzRFVTQUdFX1JFTkRFUlRBUkdFVCkgewogICAgICAgIEZJWE1FKCIoJXApVHJ5aW5nIHRvIHNldCB0aGUgcmVuZGVyIHRhcmdldCB0byBhIHN1cmZhY2UoJXApIHRoYXQgd2Fzbid0IGNyZWF0ZWQgd2l0aCBhIHVzYWdlIG9mIFdJTkVEM0RVU0FHRV9SRU5ERVJUQVJHRVRcbiIsVGhpcyAscFJlbmRlclRhcmdldCk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgLyogSWYgd2UgYXJlIHRyeWluZyB0byBzZXQgd2hhdCB3ZSBhbHJlYWR5IGhhdmUsIGRvbid0IGJvdGhlciAqLwogICAgaWYgKHBSZW5kZXJUYXJnZXQgPT0gVGhpcy0+cmVuZGVyX3RhcmdldHNbUmVuZGVyVGFyZ2V0SW5kZXhdKSB7CiAgICAgICAgVFJBQ0UoIlRyeWluZyB0byBkbyBhIE5PUCBTZXRSZW5kZXJUYXJnZXQgb3BlcmF0aW9uXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KICAgIGlmKHBSZW5kZXJUYXJnZXQpIElXaW5lRDNEU3VyZmFjZV9BZGRSZWYocFJlbmRlclRhcmdldCk7CiAgICBpZihUaGlzLT5yZW5kZXJfdGFyZ2V0c1tSZW5kZXJUYXJnZXRJbmRleF0pIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKFRoaXMtPnJlbmRlcl90YXJnZXRzW1JlbmRlclRhcmdldEluZGV4XSk7CiAgICBUaGlzLT5yZW5kZXJfdGFyZ2V0c1tSZW5kZXJUYXJnZXRJbmRleF0gPSBwUmVuZGVyVGFyZ2V0OwoKICAgIC8qIFJlbmRlciB0YXJnZXQgMCBpcyBzcGVjaWFsICovCiAgICBpZihSZW5kZXJUYXJnZXRJbmRleCA9PSAwKSB7CiAgICAgICAgLyogRmluYWxseSwgcmVzZXQgdGhlIHZpZXdwb3J0IGFzIHRoZSBNU0ROIHN0YXRlcy4gKi8KICAgICAgICB2aWV3cG9ydC5IZWlnaHQgPSAoKElXaW5lRDNEU3VyZmFjZUltcGwgKilUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXSktPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICB2aWV3cG9ydC5XaWR0aCAgPSAoKElXaW5lRDNEU3VyZmFjZUltcGwgKilUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXSktPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgIHZpZXdwb3J0LlggICAgICA9IDA7CiAgICAgICAgdmlld3BvcnQuWSAgICAgID0gMDsKICAgICAgICB2aWV3cG9ydC5NYXhaICAgPSAxLjBmOwogICAgICAgIHZpZXdwb3J0Lk1pblogICA9IDAuMGY7CiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZpZXdwb3J0KGlmYWNlLCAmdmlld3BvcnQpOwogICAgICAgIC8qIE1ha2Ugc3VyZSB0aGUgdmlld3BvcnQgc3RhdGUgaXMgZGlydHksIGJlY2F1c2UgdGhlIHJlbmRlcl9vZmZzY3JlZW4gdGhpbmcgYWZmZWN0cyBpdC4KICAgICAgICAgKiBTZXRWaWV3cG9ydCBtYXkgY2F0Y2ggTk9QIHZpZXdwb3J0IGNoYW5nZXMsIHdoaWNoIHdvdWxkIG9jY3VyIHdoZW4gc3dpdGNoaW5nIGJldHdlZW4gZXF1YWxseSBzaXplZCB0YXJnZXRzCiAgICAgICAgICovCiAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1ZJRVdQT1JUKTsKCiAgICAgICAgLyogQWN0aXZhdGUgdGhlIG5ldyByZW5kZXIgdGFyZ2V0IGZvciBub3cuIFRoaXMgc2hvdWxkbid0IHN0YXkgaGVyZSwgYnV0IGlzIG5lZWRlZCB1bnRpbCBhbGwgbWV0aG9kcyB1c2luZyBnbCBhY3RpdmF0ZSB0aGUKICAgICAgICAgKiBjdHggcHJvcGVybHkuCiAgICAgICAgICogVXNlIHJlc291cmNlbG9hZCB1c2FnZSwgdGhpcyB3aWxsIGp1c3Qgc2V0IHRoZSBkcmF3YWJsZXMgYW5kIGNvbnRleHQgYnV0IG5vdCBhcHBseSBhbnkgc3RhdGVzLiBUaGUgc3RhdGVibG9jayBtYXkgYmUKICAgICAgICAgKiBpbmNvbXBsZXRlIG9yIGluY29ycmVjdCB3aGVuIFNldFJlbmRlclRhcmdldCBpcyBjYWxsZWQuIERyYXdQcmltKCkgd2lsbCBhcHBseSB0aGUgc3RhdGVzIHdoZW4gaXQgaXMgY2FsbGVkLgogICAgICAgICAqLwogICAgICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBUaGlzLT5yZW5kZXJfdGFyZ2V0c1swXSwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogV2Ugb25seSBnZXQgbW9yZSB0aGFuIDEgcmVuZGVyIHRhcmdldCB3aXRoIGZib3MsIHNvIG5vIG5lZWQgdG8gY2hlY2sgdGhlIG9mZnNjcmVlbiByZW5kZXJpbmcgbWV0aG9kICovCiAgICAgICAgc2V0X3JlbmRlcl90YXJnZXRfZmJvKGlmYWNlLCBSZW5kZXJUYXJnZXRJbmRleCwgcFJlbmRlclRhcmdldCk7CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9TZXREZXB0aFN0ZW5jaWxTdXJmYWNlKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RTdXJmYWNlICpwTmV3WlN0ZW5jaWwpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIEhSRVNVTFQgIGhyID0gV0lORUQzRF9PSzsKICAgIElXaW5lRDNEU3VyZmFjZSAqdG1wOwoKICAgIFRSQUNFKCIoJXApIFN3YXBwaW5nIHotYnVmZmVyXG4iLFRoaXMpOwoKICAgIGlmIChwTmV3WlN0ZW5jaWwgPT0gVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCkgewogICAgICAgIFRSQUNFKCJUcnlpbmcgdG8gZG8gYSBOT1AgU2V0UmVuZGVyVGFyZ2V0IG9wZXJhdGlvblxuIik7CiAgICB9IGVsc2UgewogICAgICAgIC8qKiBPcGVuR0wgZG9lc24ndCBzdXBwb3J0ICdzaGFyaW5nJyBvZiB0aGUgc3RlbmNpbEJ1ZmZlciBzbyB3ZSBtYXkgaW5jdXJlIGFuIGV4dHJhIG1lbW9yeSBvdmVyaGVhZAogICAgICAgICogZGVwZW5kaW5nIG9uIHRoZSByZW50ZXIgdGFyZ2V0IGltcGxlbWVudGF0aW9uIGJlaW5nIHVzZWQuCiAgICAgICAgKiBBIHNoYXJlZCBjb250ZXh0IGltcGxlbWVudGF0aW9uIHdpbGwgc2hhcmUgYWxsIGJ1ZmZlcnMgYmV0d2VlbiBhbGwgcmVuZGVydGFyZ2V0cyAoaW5jbHVkaW5nIHN3YXBjaGFpbnMpLAogICAgICAgICogaW1wbGVtZW50YXRpb25zIHRoYXQgdXNlIHNlcGFyYXRlIHBidWZmZXJzIGZvciBkaWZmZXJlbnQgc3dhcGNoYWlucyBvciByZW5kZXJ0YXJnZXRzIHdpbGwgaGF2ZSB0byBkdXBsaWNhdGUgdGhlCiAgICAgICAgKiBzdGVuY2lsIGJ1ZmZlciBhbmQgaW5jdXJlIGFuIGV4dHJhIG1lbW9yeSBvdmVyaGVhZAogICAgICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgogICAgICAgIHRtcCA9IFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQ7CiAgICAgICAgVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCA9IHBOZXdaU3RlbmNpbDsKICAgICAgICAvKiBzaG91bGQgd2UgYmUgY2FsbGluZyB0aGUgcGFyZW50IG9yIHRoZSB3aW5lZDNkIHN1cmZhY2U/ICovCiAgICAgICAgaWYgKE5VTEwgIT0gVGhpcy0+c3RlbmNpbEJ1ZmZlclRhcmdldCkgSVdpbmVEM0RTdXJmYWNlX0FkZFJlZihUaGlzLT5zdGVuY2lsQnVmZmVyVGFyZ2V0KTsKICAgICAgICBpZiAoTlVMTCAhPSB0bXApIElXaW5lRDNEU3VyZmFjZV9SZWxlYXNlKHRtcCk7CiAgICAgICAgaHIgPSBXSU5FRDNEX09LOwoKICAgICAgICBpZiAod2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUgPT0gT1JNX0ZCTykgewogICAgICAgICAgICBzZXRfZGVwdGhfc3RlbmNpbF9mYm8oaWZhY2UsIHBOZXdaU3RlbmNpbCk7CiAgICAgICAgfQoKICAgICAgICBpZigoIXRtcCAmJiBwTmV3WlN0ZW5jaWwpIHx8ICghcE5ld1pTdGVuY2lsICYmIHRtcCkpIHsKICAgICAgICAgICAgLyogU3dhcHBpbmcgTlVMTCAvIG5vbiBOVUxMIGRlcHRoIHN0ZW5jaWwgYWZmZWN0cyB0aGUgZGVwdGggYW5kIHRlc3RzICovCiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eShUaGlzLCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX1pFTkFCTEUpKTsKICAgICAgICAgICAgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KFRoaXMsIFNUQVRFX1JFTkRFUihXSU5FRDNEUlNfU1RFTkNJTEVOQUJMRSkpOwogICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19TVEVOQ0lMV1JJVEVNQVNLKSk7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEN1cnNvclByb3BlcnRpZXMoSVdpbmVEM0REZXZpY2UqIGlmYWNlLCBVSU5UIFhIb3RTcG90LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgWUhvdFNwb3QsIElXaW5lRDNEU3VyZmFjZSAqcEN1cnNvckJpdG1hcCkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIC8qIFRPRE86IHRoZSB1c2Ugb2YgSW1wbCBpcyBkZXByZWNhdGVkLiAqLwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqIHBTdXIgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBwQ3Vyc29yQml0bWFwOwoKICAgIFRSQUNFKCIoJXApIDogU3BvdCBQb3MoJXUsJXUpXG4iLCBUaGlzLCBYSG90U3BvdCwgWUhvdFNwb3QpOwoKICAgIC8qIHNvbWUgYmFzaWMgdmFsaWRhdGlvbiBjaGVja3MgKi8KICAgIGlmKFRoaXMtPmN1cnNvclRleHR1cmUpIHsKICAgICAgICBFTlRFUl9HTCgpOwogICAgICAgIEFjdGl2YXRlQ29udGV4dChUaGlzLCBUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0LCBDVFhVU0FHRV9SRVNPVVJDRUxPQUQpOwogICAgICAgIGdsRGVsZXRlVGV4dHVyZXMoMSwgJlRoaXMtPmN1cnNvclRleHR1cmUpOwogICAgICAgIExFQVZFX0dMKCk7CiAgICAgICAgVGhpcy0+Y3Vyc29yVGV4dHVyZSA9IDA7CiAgICB9CgogICAgaWYocEN1cnNvckJpdG1hcCkgewogICAgICAgIFdJTkVEM0RMT0NLRURfUkVDVCByZWN0OwoKICAgICAgICAvKiBNU0ROOiBDdXJzb3IgbXVzdCBiZSBBOFI4RzhCOCAqLwogICAgICAgIGlmIChXSU5FRDNERk1UX0E4UjhHOEI4ICE9IHBTdXItPnJlc291cmNlLmZvcm1hdCkgewogICAgICAgICAgICBFUlIoIiglcCkgOiBzdXJmYWNlKCVwKSBoYXMgYW4gaW52YWxpZCBmb3JtYXRcbiIsIFRoaXMsIHBDdXJzb3JCaXRtYXApOwogICAgICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgICAgICB9CgogICAgICAgIC8qIE1TRE46IEN1cnNvciBtdXN0IGJlIHNtYWxsZXIgdGhhbiB0aGUgZGlzcGxheSBtb2RlICovCiAgICAgICAgaWYocFN1ci0+Y3VycmVudERlc2MuV2lkdGggPiBUaGlzLT5kZHJhd193aWR0aCB8fAogICAgICAgICAgIHBTdXItPmN1cnJlbnREZXNjLkhlaWdodCA+IFRoaXMtPmRkcmF3X2hlaWdodCkgewogICAgICAgICAgICBFUlIoIiglcCkgOiBTdXJmYWNlKCVwKSBpcyAlZHglZCBwaXhlbHMsIGJ1dCBzY3JlZW4gcmVzIGlzICVkeCVkXG4iLCBUaGlzLCBwU3VyLCBwU3VyLT5jdXJyZW50RGVzYy5XaWR0aCwgcFN1ci0+Y3VycmVudERlc2MuSGVpZ2h0LCBUaGlzLT5kZHJhd193aWR0aCwgVGhpcy0+ZGRyYXdfaGVpZ2h0KTsKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICAgICAgfQoKICAgICAgICAvKiBUT0RPOiBNU0ROOiBDdXJzb3Igc2l6ZXMgbXVzdCBiZSBhIHBvd2VyIG9mIDIgKi8KCiAgICAgICAgLyogRG8gbm90IHN0b3JlIHRoZSBzdXJmYWNlJ3MgcG9pbnRlciBiZWNhdXNlIHRoZSBhcHBsaWNhdGlvbiBtYXkgcmVsZWFzZQogICAgICAgICAqIGl0IGFmdGVyIHNldHRpbmcgdGhlIGN1cnNvciBpbWFnZS4gV2luZG93cyBkb2Vzbid0IGFkZHJlZiB0aGUgc2V0IHN1cmZhY2UsIHNvIHdlIGNhbid0CiAgICAgICAgICogZG8gdGhpcyBlaXRoZXIgd2l0aG91dCBjcmVhdGluZyBjaXJjdWxhciByZWZjb3VudCBkZXBlbmRlbmNpZXMuIENvcHkgb3V0IHRoZSBnbCB0ZXh0dXJlIGluc3RlYWQuCiAgICAgICAgICovCiAgICAgICAgVGhpcy0+Y3Vyc29yV2lkdGggPSBwU3VyLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICBUaGlzLT5jdXJzb3JIZWlnaHQgPSBwU3VyLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgaWYgKFNVQ0NFRURFRChJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QocEN1cnNvckJpdG1hcCwgJnJlY3QsIE5VTEwsIFdJTkVEM0RMT0NLX1JFQURPTkxZKSkpCiAgICAgICAgewogICAgICAgICAgICBjb25zdCBQaXhlbEZvcm1hdERlc2MgKnRhYmxlRW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoV0lORUQzREZNVF9BOFI4RzhCOCk7CiAgICAgICAgICAgIGNoYXIgKm1lbSwgKmJpdHMgPSAoY2hhciAqKXJlY3QucEJpdHM7CiAgICAgICAgICAgIEdMaW50IGludGZtdCA9IHRhYmxlRW50cnktPmdsSW50ZXJuYWw7CiAgICAgICAgICAgIEdMaW50IGZvcm1hdCA9IHRhYmxlRW50cnktPmdsRm9ybWF0OwogICAgICAgICAgICBHTGludCB0eXBlID0gdGFibGVFbnRyeS0+Z2xUeXBlOwogICAgICAgICAgICBJTlQgaGVpZ2h0ID0gVGhpcy0+Y3Vyc29ySGVpZ2h0OwogICAgICAgICAgICBJTlQgd2lkdGggPSBUaGlzLT5jdXJzb3JXaWR0aDsKICAgICAgICAgICAgSU5UIGJwcCA9IHRhYmxlRW50cnktPmJwcDsKICAgICAgICAgICAgSU5UIGk7CgogICAgICAgICAgICAvKiBSZWZvcm1hdCB0aGUgdGV4dHVyZSBtZW1vcnkgKHBpdGNoIGFuZCB3aWR0aCBjYW4gYmUgZGlmZmVyZW50KSAqLwogICAgICAgICAgICBtZW0gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgd2lkdGggKiBoZWlnaHQgKiBicHApOwogICAgICAgICAgICBmb3IoaSA9IDA7IGkgPCBoZWlnaHQ7IGkrKykKICAgICAgICAgICAgICAgIG1lbWNweSgmbWVtW3dpZHRoICogYnBwICogaV0sICZiaXRzW3JlY3QuUGl0Y2ggKiBpXSwgd2lkdGggKiBicHApOwogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfVW5sb2NrUmVjdChwQ3Vyc29yQml0bWFwKTsKICAgICAgICAgICAgRU5URVJfR0woKTsKICAgICAgICAgICAgLyogTWFrZSBzdXJlIHRoYXQgYSBwcm9wZXIgdGV4dHVyZSB1bml0IGlzIHNlbGVjdGVkICovCiAgICAgICAgICAgIGlmIChHTF9TVVBQT1JUKEFSQl9NVUxUSVRFWFRVUkUpKSB7CiAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsQWN0aXZlVGV4dHVyZUFSQihHTF9URVhUVVJFMF9BUkIpKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEFjdGl2ZVRleHR1cmVBUkIiKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBJV2luZUQzRERldmljZUltcGxfTWFya1N0YXRlRGlydHkoVGhpcywgU1RBVEVfU0FNUExFUigwKSk7CiAgICAgICAgICAgIC8qIENyZWF0ZSBhIG5ldyBjdXJzb3IgdGV4dHVyZSAqLwogICAgICAgICAgICBnbEdlblRleHR1cmVzKDEsICZUaGlzLT5jdXJzb3JUZXh0dXJlKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsR2VuVGV4dHVyZXMiKTsKICAgICAgICAgICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCBUaGlzLT5jdXJzb3JUZXh0dXJlKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsQmluZFRleHR1cmUiKTsKICAgICAgICAgICAgLyogQ29weSB0aGUgYml0bWFwIG1lbW9yeSBpbnRvIHRoZSBjdXJzb3IgdGV4dHVyZSAqLwogICAgICAgICAgICBnbFRleEltYWdlMkQoR0xfVEVYVFVSRV8yRCwgMCwgaW50Zm10LCB3aWR0aCwgaGVpZ2h0LCAwLCBmb3JtYXQsIHR5cGUsIG1lbSk7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1lbSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleEltYWdlMkQiKTsKICAgICAgICAgICAgTEVBVkVfR0woKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgRklYTUUoIkEgY3Vyc29yIHRleHR1cmUgd2FzIG5vdCByZXR1cm5lZC5cbiIpOwogICAgICAgICAgICBUaGlzLT5jdXJzb3JUZXh0dXJlID0gMDsKICAgICAgICB9CgogICAgfQoKICAgIFRoaXMtPnhIb3RTcG90ID0gWEhvdFNwb3Q7CiAgICBUaGlzLT55SG90U3BvdCA9IFlIb3RTcG90OwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyB2b2lkICAgICBXSU5BUEkgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRDdXJzb3JQb3NpdGlvbihJV2luZUQzRERldmljZSogaWZhY2UsIGludCBYU2NyZWVuU3BhY2UsIGludCBZU2NyZWVuU3BhY2UsIERXT1JEIEZsYWdzKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiBTZXRQb3MgdG8gKCV1LCV1KVxuIiwgVGhpcywgWFNjcmVlblNwYWNlLCBZU2NyZWVuU3BhY2UpOwoKICAgIFRoaXMtPnhTY3JlZW5TcGFjZSA9IFhTY3JlZW5TcGFjZTsKICAgIFRoaXMtPnlTY3JlZW5TcGFjZSA9IFlTY3JlZW5TcGFjZTsKCiAgICByZXR1cm47Cgp9CgpzdGF0aWMgQk9PTCAgICAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfU2hvd0N1cnNvcihJV2luZUQzRERldmljZSogaWZhY2UsIEJPT0wgYlNob3cpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBCT09MIG9sZFZpc2libGUgPSBUaGlzLT5iQ3Vyc29yVmlzaWJsZTsKICAgIFBPSU5UIHB0OwoKICAgIFRSQUNFKCIoJXApIDogdmlzaWJsZSglZClcbiIsIFRoaXMsIGJTaG93KTsKCiAgICBpZihUaGlzLT5jdXJzb3JUZXh0dXJlKQogICAgICAgIFRoaXMtPmJDdXJzb3JWaXNpYmxlID0gYlNob3c7CiAgICAvKgogICAgICogV2hlbiBTaG93Q3Vyc29yIGlzIGZpcnN0IGNhbGxlZCBpdCBzaG91bGQgbWFrZSB0aGUgY3Vyc29yIGFwcGVhciBhdCB0aGUgT1MncyBsYXN0CiAgICAgKiBrbm93biBjdXJzb3IgcG9zaXRpb24uICBCZWNhdXNlIG9mIHRoaXMsIHNvbWUgYXBwbGljYXRpb25zIGp1c3QgcmVwZXRpdGl2ZWx5IGNhbGwKICAgICAqIFNob3dDdXJzb3IgaW4gb3JkZXIgdG8gdXBkYXRlIHRoZSBjdXJzb3IncyBwb3NpdGlvbi4gIFRoaXMgYmVoYXZpb3IgaXMgdW5kb2N1bWVudGVkLgogICAgICovCiAgICBHZXRDdXJzb3JQb3MoJnB0KTsKICAgIFRoaXMtPnhTY3JlZW5TcGFjZSA9IHB0Lng7CiAgICBUaGlzLT55U2NyZWVuU3BhY2UgPSBwdC55OwoKICAgIHJldHVybiBvbGRWaXNpYmxlOwp9CgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfVGVzdENvb3BlcmF0aXZlTGV2ZWwoSVdpbmVEM0REZXZpY2UqIGlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIGlmYWNlOwogICAgVFJBQ0UoIiglcCkgOiBzdGF0ZSAoJXUpXG4iLCBUaGlzLCBUaGlzLT5zdGF0ZSk7CiAgICAvKiBUT0RPOiBJbXBsZW1lbnQgd3JhcHBpbmcgb2YgdGhlIFduZFByb2Mgc28gdGhhdCBtaW1pbWl6ZSBhbmQgbWF4YW1pc2UgY2FuIGJlIG1vbml0b3JlZCBhbmQgdGhlIHN0YXRlcyBhZGp1c3RlZC4gKi8KICAgIHN3aXRjaCAoVGhpcy0+c3RhdGUpIHsKICAgIGNhc2UgV0lORUQzRF9PSzoKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIGNhc2UgV0lORUQzREVSUl9ERVZJQ0VMT1NUOgogICAgICAgIHsKICAgICAgICAgICAgUmVzb3VyY2VMaXN0ICpyZXNvdXJjZUxpc3QgID0gVGhpcy0+cmVzb3VyY2VzOwogICAgICAgICAgICB3aGlsZSAoTlVMTCAhPSByZXNvdXJjZUxpc3QpIHsKICAgICAgICAgICAgICAgIGlmICgoKElXaW5lRDNEUmVzb3VyY2VJbXBsICopcmVzb3VyY2VMaXN0LT5yZXNvdXJjZSktPnJlc291cmNlLnBvb2wgPT0gV0lORUQzRFBPT0xfREVGQVVMVCAvKiBUT0RPOiBJV2luZUQzRFJlc291cmNlX0dldFBvb2wocmVzb3VyY2VMaXN0LT5yZXNvdXJjZSkqLykKICAgICAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0RFVklDRU5PVFJFU0VUOwogICAgICAgICAgICAgICAgcmVzb3VyY2VMaXN0ID0gcmVzb3VyY2VMaXN0LT5uZXh0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0RFVklDRUxPU1Q7CiAgICAgICAgfQogICAgY2FzZSBXSU5FRDNERVJSX0RSSVZFUklOVEVSTkFMRVJST1I6CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfRFJJVkVSSU5URVJOQUxFUlJPUjsKICAgIH0KCiAgICAvKiBVbmtub3duIHN0YXRlICovCiAgICByZXR1cm4gV0lORUQzREVSUl9EUklWRVJJTlRFUk5BTEVSUk9SOwp9CgoKc3RhdGljIEhSRVNVTFQgIFdJTkFQSSAgSVdpbmVEM0REZXZpY2VJbXBsX0V2aWN0TWFuYWdlZFJlc291cmNlcyhJV2luZUQzRERldmljZSogaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICAvKiogRklYTUU6IFJlc291cmNlIHRyYWNraW5nIG5lZWRzIHRvIGJlIGRvbmUsCiAgICAqIFRoZSBjbG9zZXMgd2UgY2FuIGRvIHRvIHRoaXMgaXMgc2V0IHRoZSBwcmlvcml0aWVzIG9mIGFsbCBtYW5hZ2VkIHRleHR1cmVzIGxvdwogICAgKiBhbmQgdGhlbiByZXNldCB0aGVtLgogICAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwogICAgRklYTUUoIiglcCkgOiBzdHViXG4iLCBUaGlzKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgdm9pZCB1cGRhdGVTdXJmYWNlRGVzYyhJV2luZUQzRFN1cmZhY2VJbXBsICpzdXJmYWNlLCBXSU5FRDNEUFJFU0VOVF9QQVJBTUVURVJTKiBwUHJlc2VudGF0aW9uUGFyYW1ldGVycykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gc3VyZmFjZS0+cmVzb3VyY2Uud2luZUQzRERldmljZTsgLyogZm9yIEdMX1NVUFBPUlQgKi8KCiAgICAvKiBSZWFsbG9jYXRlIHByb3BlciBtZW1vcnkgZm9yIHRoZSBmcm9udCBhbmQgYmFjayBidWZmZXIgYW5kIGFkanVzdCB0aGVpciBzaXplcyAqLwogICAgaWYoc3VyZmFjZS0+RmxhZ3MgJiBTRkxBR19ESUJTRUNUSU9OKSB7CiAgICAgICAgLyogUmVsZWFzZSB0aGUgREMgKi8KICAgICAgICBTZWxlY3RPYmplY3Qoc3VyZmFjZS0+aERDLCBzdXJmYWNlLT5kaWIuaG9sZGJpdG1hcCk7CiAgICAgICAgRGVsZXRlREMoc3VyZmFjZS0+aERDKTsKICAgICAgICAvKiBSZWxlYXNlIHRoZSBESUIgc2VjdGlvbiAqLwogICAgICAgIERlbGV0ZU9iamVjdChzdXJmYWNlLT5kaWIuRElCc2VjdGlvbik7CiAgICAgICAgc3VyZmFjZS0+ZGliLmJpdG1hcF9kYXRhID0gTlVMTDsKICAgICAgICBzdXJmYWNlLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgPSBOVUxMOwogICAgICAgIHN1cmZhY2UtPkZsYWdzICY9IH5TRkxBR19ESUJTRUNUSU9OOwogICAgfQogICAgc3VyZmFjZS0+Y3VycmVudERlc2MuV2lkdGggPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoOwogICAgc3VyZmFjZS0+Y3VycmVudERlc2MuSGVpZ2h0ID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQ7CiAgICBpZiAoR0xfU1VQUE9SVChBUkJfVEVYVFVSRV9OT05fUE9XRVJfT0ZfVFdPKSkgewogICAgICAgIHN1cmZhY2UtPnBvdzJXaWR0aCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGg7CiAgICAgICAgc3VyZmFjZS0+cG93MkhlaWdodCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0OwogICAgfSBlbHNlIHsKICAgICAgICBzdXJmYWNlLT5wb3cyV2lkdGggPSBzdXJmYWNlLT5wb3cySGVpZ2h0ID0gMTsKICAgICAgICB3aGlsZSAoc3VyZmFjZS0+cG93MldpZHRoIDwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aCkgc3VyZmFjZS0+cG93MldpZHRoIDw8PSAxOwogICAgICAgIHdoaWxlIChzdXJmYWNlLT5wb3cySGVpZ2h0IDwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQpIHN1cmZhY2UtPnBvdzJIZWlnaHQgPDw9IDE7CiAgICB9CiAgICBpZihzdXJmYWNlLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKSB7CiAgICAgICAgRU5URVJfR0woKTsKICAgICAgICBBY3RpdmF0ZUNvbnRleHQoVGhpcywgVGhpcy0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCwgQ1RYVVNBR0VfUkVTT1VSQ0VMT0FEKTsKICAgICAgICBnbERlbGV0ZVRleHR1cmVzKDEsICZzdXJmYWNlLT5nbERlc2NyaXB0aW9uLnRleHR1cmVOYW1lKTsKICAgICAgICBMRUFWRV9HTCgpOwogICAgICAgIHN1cmZhY2UtPmdsRGVzY3JpcHRpb24udGV4dHVyZU5hbWUgPSAwOwogICAgfQogICAgaWYoc3VyZmFjZS0+cG93MldpZHRoICE9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGggfHwKICAgICAgIHN1cmZhY2UtPnBvdzJIZWlnaHQgIT0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQpIHsKICAgICAgICBzdXJmYWNlLT5GbGFncyB8PSBTRkxBR19OT05QT1cyOwogICAgfSBlbHNlICB7CiAgICAgICAgc3VyZmFjZS0+RmxhZ3MgJj0gflNGTEFHX05PTlBPVzI7CiAgICB9CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdXJmYWNlLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkpOwogICAgc3VyZmFjZS0+cmVzb3VyY2Uuc2l6ZSA9IElXaW5lRDNEU3VyZmFjZV9HZXRQaXRjaCgoSVdpbmVEM0RTdXJmYWNlICopIHN1cmZhY2UpICogc3VyZmFjZS0+cG93MldpZHRoOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1Jlc2V0KElXaW5lRDNERGV2aWNlKiBpZmFjZSwgV0lORUQzRFBSRVNFTlRfUEFSQU1FVEVSUyogcFByZXNlbnRhdGlvblBhcmFtZXRlcnMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKikgaWZhY2U7CiAgICBJV2luZUQzRFN3YXBDaGFpbkltcGwgKnN3YXBjaGFpbjsKICAgIEhSRVNVTFQgaHI7CiAgICBCT09MIERpc3BsYXlNb2RlQ2hhbmdlZCA9IEZBTFNFOwogICAgV0lORUQzRERJU1BMQVlNT0RFIG1vZGU7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgaHIgPSBJV2luZUQzRERldmljZV9HZXRTd2FwQ2hhaW4oaWZhY2UsIDAsIChJV2luZUQzRFN3YXBDaGFpbiAqKikgJnN3YXBjaGFpbik7CiAgICBpZihGQUlMRUQoaHIpKSB7CiAgICAgICAgRVJSKCJGYWlsZWQgdG8gZ2V0IHRoZSBmaXJzdCBpbXBsaWNpdCBzd2FwY2hhaW5cbiIpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICAvKiBJcyBpdCBuZWNlc3NhcnkgdG8gcmVjcmVhdGUgdGhlIGdsIGNvbnRleHQ/IEFjdHVhbGx5IGV2ZXJ5IHNldHRpbmcgY2FuIGJlIGNoYW5nZWQKICAgICAqIG9uIGFuIGV4aXN0aW5nIGdsIGNvbnRleHQsIHNvIHRoZXJlJ3Mgbm8gcmVhbCBuZWVkIGZvciByZWNyZWF0aW9uLgogICAgICoKICAgICAqIFRPRE86IEZpZ3VyZSBvdXQgaG93IFJlc2V0IGluZmx1ZW5jZXMgcmVzb3VyY2VzIGluIEQzRFBPT0xfREVGQVVMVCwgRDNEUE9PTF9TWVNURU1NRU1PUlkgYW5kIEQzRFBPT0xfTUFOQUdFRAogICAgICoKICAgICAqIFRPRE86IEZpZ3VyZSBvdXQgd2hhdCBoYXBwZW5zIHRvIGV4cGxpY2l0IHN3YXBjaGFpbnMsIG9yIGlmIHdlIGhhdmUgbW9yZSB0aGFuIG9uZSBpbXBsaWNpdCBzd2FwY2hhaW4KICAgICAqLwogICAgVFJBQ0UoIk5ldyBwYXJhbXM6XG4iKTsKICAgIFRSQUNFKCJCYWNrQnVmZmVyV2lkdGggPSAlZFxuIiwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aCk7CiAgICBUUkFDRSgiQmFja0J1ZmZlckhlaWdodCA9ICVkXG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckhlaWdodCk7CiAgICBUUkFDRSgiQmFja0J1ZmZlckZvcm1hdCA9ICVzXG4iLCBkZWJ1Z19kM2Rmb3JtYXQocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJGb3JtYXQpKTsKICAgIFRSQUNFKCJCYWNrQnVmZmVyQ291bnQgPSAlZFxuIiwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJDb3VudCk7CiAgICBUUkFDRSgiTXVsdGlTYW1wbGVUeXBlID0gJWRcbiIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5NdWx0aVNhbXBsZVR5cGUpOwogICAgVFJBQ0UoIk11bHRpU2FtcGxlUXVhbGl0eSA9ICVkXG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+TXVsdGlTYW1wbGVRdWFsaXR5KTsKICAgIFRSQUNFKCJTd2FwRWZmZWN0ID0gJWRcbiIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5Td2FwRWZmZWN0KTsKICAgIFRSQUNFKCJoRGV2aWNlV2luZG93ID0gJXBcbiIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5oRGV2aWNlV2luZG93KTsKICAgIFRSQUNFKCJXaW5kb3dlZCA9ICVzXG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+V2luZG93ZWQgPyAidHJ1ZSIgOiAiZmFsc2UiKTsKICAgIFRSQUNFKCJFbmFibGVBdXRvRGVwdGhTdGVuY2lsID0gJXNcbiIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5FbmFibGVBdXRvRGVwdGhTdGVuY2lsID8gInRydWUiIDogImZhbHNlIik7CiAgICBUUkFDRSgiRmxhZ3MgPSAlMDh4XG4iLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+RmxhZ3MpOwogICAgVFJBQ0UoIkZ1bGxTY3JlZW5fUmVmcmVzaFJhdGVJbkh6ID0gJWRcbiIsIHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5GdWxsU2NyZWVuX1JlZnJlc2hSYXRlSW5Ieik7CiAgICBUUkFDRSgiUHJlc2VudGF0aW9uSW50ZXJ2YWwgPSAlZFxuIiwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPlByZXNlbnRhdGlvbkludGVydmFsKTsKCiAgICAvKiBObyBzcGVjaWFsIHRyZWF0bWVudCBvZiB0aGVzZSBwYXJhbWV0ZXJzLiBKdXN0IHN0b3JlIHRoZW0gKi8KICAgIHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLlN3YXBFZmZlY3QgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+U3dhcEVmZmVjdDsKICAgIHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLkZsYWdzID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkZsYWdzOwogICAgc3dhcGNoYWluLT5wcmVzZW50UGFybXMuUHJlc2VudGF0aW9uSW50ZXJ2YWwgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+UHJlc2VudGF0aW9uSW50ZXJ2YWw7CiAgICBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5GdWxsU2NyZWVuX1JlZnJlc2hSYXRlSW5IeiA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5GdWxsU2NyZWVuX1JlZnJlc2hSYXRlSW5IejsKCiAgICAvKiBXaGF0IHRvIGRvIGFib3V0IHRoZXNlPyAqLwogICAgaWYocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJDb3VudCAhPSAwICYmCiAgICAgICAgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJDb3VudCAhPSBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyQ291bnQpIHsKICAgICAgICBFUlIoIkNhbm5vdCBjaGFuZ2UgdGhlIGJhY2sgYnVmZmVyIGNvdW50IHlldFxuIik7CiAgICB9CiAgICBpZihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckZvcm1hdCAhPSBXSU5FRDNERk1UX1VOS05PV04gJiYKICAgICAgICBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlckZvcm1hdCAhPSBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyRm9ybWF0KSB7CiAgICAgICAgRVJSKCJDYW5ub3QgY2hhbmdlIHRoZSBiYWNrIGJ1ZmZlciBmb3JtYXQgeWV0XG4iKTsKICAgIH0KICAgIGlmKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5oRGV2aWNlV2luZG93ICE9IE5VTEwgJiYKICAgICAgICBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+aERldmljZVdpbmRvdyAhPSBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5oRGV2aWNlV2luZG93KSB7CiAgICAgICAgRVJSKCJDYW5ub3QgY2hhbmdlIHRoZSBkZXZpY2Ugd2luZG93IHlldFxuIik7CiAgICB9CiAgICBpZihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+RW5hYmxlQXV0b0RlcHRoU3RlbmNpbCAhPSBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5FbmFibGVBdXRvRGVwdGhTdGVuY2lsKSB7CiAgICAgICAgRVJSKCJXaGF0IGRvIGRvIGFib3V0IGEgY2hhbmdlZCBhdXRvIGRlcHRoIHN0ZW5jaWwgcGFyYW1ldGVyP1xuIik7CiAgICB9CgogICAgaWYocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPldpbmRvd2VkKSB7CiAgICAgICAgbW9kZS5XaWR0aCA9IHN3YXBjaGFpbi0+b3JpZ193aWR0aDsKICAgICAgICBtb2RlLkhlaWdodCA9IHN3YXBjaGFpbi0+b3JpZ19oZWlnaHQ7CiAgICAgICAgbW9kZS5SZWZyZXNoUmF0ZSA9IDA7CiAgICAgICAgbW9kZS5Gb3JtYXQgPSBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyRm9ybWF0OwogICAgfSBlbHNlIHsKICAgICAgICBtb2RlLldpZHRoID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aDsKICAgICAgICBtb2RlLkhlaWdodCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVySGVpZ2h0OwogICAgICAgIG1vZGUuUmVmcmVzaFJhdGUgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+RnVsbFNjcmVlbl9SZWZyZXNoUmF0ZUluSHo7CiAgICAgICAgbW9kZS5Gb3JtYXQgPSBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVyRm9ybWF0OwogICAgfQoKICAgIC8qIFNob3VsZCBXaWR0aCA9PSA4MDAgJiYgSGVpZ2h0ID09IDAgc2V0IDgwMHg2MDA/ICovCiAgICBpZihwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+QmFja0J1ZmZlcldpZHRoICE9IDAgJiYgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQgIT0gMCAmJgogICAgICAgKHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGggIT0gc3dhcGNoYWluLT5wcmVzZW50UGFybXMuQmFja0J1ZmZlcldpZHRoIHx8CiAgICAgICAgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQgIT0gc3dhcGNoYWluLT5wcmVzZW50UGFybXMuQmFja0J1ZmZlckhlaWdodCkpCiAgICB7CiAgICAgICAgV0lORUQzRFZJRVdQT1JUIHZwOwogICAgICAgIGludCBpOwoKICAgICAgICB2cC5YID0gMDsKICAgICAgICB2cC5ZID0gMDsKICAgICAgICB2cC5XaWR0aCA9IHBQcmVzZW50YXRpb25QYXJhbWV0ZXJzLT5CYWNrQnVmZmVyV2lkdGg7CiAgICAgICAgdnAuSGVpZ2h0ID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQ7CiAgICAgICAgdnAuTWluWiA9IDA7CiAgICAgICAgdnAuTWF4WiA9IDE7CgogICAgICAgIGlmKCFwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+V2luZG93ZWQpIHsKICAgICAgICAgICAgRGlzcGxheU1vZGVDaGFuZ2VkID0gVFJVRTsKICAgICAgICB9CiAgICAgICAgc3dhcGNoYWluLT5wcmVzZW50UGFybXMuQmFja0J1ZmZlcldpZHRoID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJXaWR0aDsKICAgICAgICBzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5CYWNrQnVmZmVySGVpZ2h0ID0gcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPkJhY2tCdWZmZXJIZWlnaHQ7CgogICAgICAgIHVwZGF0ZVN1cmZhY2VEZXNjKChJV2luZUQzRFN1cmZhY2VJbXBsICopc3dhcGNoYWluLT5mcm9udEJ1ZmZlciwgcFByZXNlbnRhdGlvblBhcmFtZXRlcnMpOwogICAgICAgIGZvcihpID0gMDsgaSA8IHN3YXBjaGFpbi0+cHJlc2VudFBhcm1zLkJhY2tCdWZmZXJDb3VudDsgaSsrKSB7CiAgICAgICAgICAgIHVwZGF0ZVN1cmZhY2VEZXNjKChJV2luZUQzRFN1cmZhY2VJbXBsICopc3dhcGNoYWluLT5iYWNrQnVmZmVyW2ldLCBwUHJlc2VudGF0aW9uUGFyYW1ldGVycyk7CiAgICAgICAgfQoKICAgICAgICAvKiBOb3cgc2V0IHRoZSBuZXcgdmlld3BvcnQgKi8KICAgICAgICBJV2luZUQzRERldmljZV9TZXRWaWV3cG9ydChpZmFjZSwgJnZwKTsKICAgIH0KCiAgICBpZigocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPldpbmRvd2VkICYmICFzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5XaW5kb3dlZCkgfHwKICAgICAgIChzd2FwY2hhaW4tPnByZXNlbnRQYXJtcy5XaW5kb3dlZCAmJiAhcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPldpbmRvd2VkKSB8fAogICAgICAgIERpc3BsYXlNb2RlQ2hhbmdlZCkgewoKICAgICAgICAvKiBTd2l0Y2hpbmcgdG8gZnVsbHNjcmVlbj8gQ2hhbmdlIHRvIGZ1bGxzY3JlZW4gbW9kZSwgVEhFTiBjaGFuZ2UgdGhlIHNjcmVlbiByZXMgKi8KICAgICAgICBpZighcFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPldpbmRvd2VkKSB7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldEZ1bGxzY3JlZW4oaWZhY2UsIFRSVUUpOwogICAgICAgIH0KCiAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0RGlzcGxheU1vZGUoaWZhY2UsIDAsICZtb2RlKTsKCiAgICAgICAgLyogU3dpdGNoaW5nIG91dCBvZiBmdWxsc2NyZWVuIG1vZGU/IEZpcnN0IHNldCB0aGUgb3JpZ2luYWwgcmVzLCB0aGVuIGNoYW5nZSB0aGUgd2luZG93ICovCiAgICAgICAgaWYocFByZXNlbnRhdGlvblBhcmFtZXRlcnMtPldpbmRvd2VkKSB7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlX1NldEZ1bGxzY3JlZW4oaWZhY2UsIEZBTFNFKTsKICAgICAgICB9CiAgICAgICAgc3dhcGNoYWluLT5wcmVzZW50UGFybXMuV2luZG93ZWQgPSBwUHJlc2VudGF0aW9uUGFyYW1ldGVycy0+V2luZG93ZWQ7CiAgICB9CgogICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZSgoSVdpbmVEM0RTd2FwQ2hhaW4gKikgc3dhcGNoYWluKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldERpYWxvZ0JveE1vZGUoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBCT09MIGJFbmFibGVEaWFsb2dzKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICAvKiogRklYTUU6IGFsd2F5cyB0cnVlIGF0IHRoZSBtb21lbnQgKiovCiAgICBpZighYkVuYWJsZURpYWxvZ3MpIHsKICAgICAgICBGSVhNRSgiKCVwKSBEaWFsb2dzIGNhbm5vdCBiZSBkaXNhYmxlZCB5ZXRcbiIsIFRoaXMpOwogICAgfQogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJICBJV2luZUQzRERldmljZUltcGxfR2V0Q3JlYXRpb25QYXJhbWV0ZXJzKElXaW5lRDNERGV2aWNlICppZmFjZSwgV0lORUQzRERFVklDRV9DUkVBVElPTl9QQVJBTUVURVJTICpwUGFyYW1ldGVycykgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIFRSQUNFKCIoJXApIDogcFBhcmFtZXRlcnMgJXBcbiIsIFRoaXMsIHBQYXJhbWV0ZXJzKTsKCiAgICAqcFBhcmFtZXRlcnMgPSBUaGlzLT5jcmVhdGVQYXJtczsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgdm9pZCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1NldEdhbW1hUmFtcChJV2luZUQzRERldmljZSAqIGlmYWNlLCBVSU5UIGlTd2FwQ2hhaW4sIERXT1JEIEZsYWdzLCBDT05TVCBXSU5FRDNER0FNTUFSQU1QKiBwUmFtcCkgewogICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBjaGFpbjsKICAgIEhSRVNVTFQgaHJjID0gV0lORUQzRF9PSzsKCiAgICBUUkFDRSgiUmVsYXlpbmcgIHRvIHN3YXBjaGFpblxuIik7CgogICAgaWYgKChocmMgPSBJV2luZUQzRERldmljZUltcGxfR2V0U3dhcENoYWluKGlmYWNlLCBpU3dhcENoYWluLCAmc3dhcGNoYWluKSkgPT0gV0lORUQzRF9PSykgewogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1NldEdhbW1hUmFtcChzd2FwY2hhaW4sIEZsYWdzLCAoV0lORUQzREdBTU1BUkFNUCAqKXBSYW1wKTsKICAgICAgICBJV2luZUQzRFN3YXBDaGFpbl9SZWxlYXNlKHN3YXBjaGFpbik7CiAgICB9CiAgICByZXR1cm47Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBJV2luZUQzRERldmljZUltcGxfR2V0R2FtbWFSYW1wKElXaW5lRDNERGV2aWNlICppZmFjZSwgVUlOVCBpU3dhcENoYWluLCBXSU5FRDNER0FNTUFSQU1QKiBwUmFtcCkgewogICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBjaGFpbjsKICAgIEhSRVNVTFQgaHJjID0gV0lORUQzRF9PSzsKCiAgICBUUkFDRSgiUmVsYXlpbmcgIHRvIHN3YXBjaGFpblxuIik7CgogICAgaWYgKChocmMgPSBJV2luZUQzRERldmljZUltcGxfR2V0U3dhcENoYWluKGlmYWNlLCBpU3dhcENoYWluLCAmc3dhcGNoYWluKSkgPT0gV0lORUQzRF9PSykgewogICAgICAgIGhyYyA9SVdpbmVEM0RTd2FwQ2hhaW5fR2V0R2FtbWFSYW1wKHN3YXBjaGFpbiwgcFJhbXApOwogICAgICAgIElXaW5lRDNEU3dhcENoYWluX1JlbGVhc2Uoc3dhcGNoYWluKTsKICAgIH0KICAgIHJldHVybjsKfQoKCi8qKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqICAgTm90aWZpY2F0aW9uIGZ1bmN0aW9ucwoqKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoqIFRoaXMgZnVuY3Rpb24gbXVzdCBiZSBjYWxsZWQgaW4gdGhlIHJlbGVhc2Ugb2YgYSByZXNvdXJjZSB3aGVuIHJlZiA9PSAwLAoqIHRoZSBjb250ZW50cyBvZiByZXNvdXJjZSBtdXN0IHN0aWxsIGJlIGNvcnJlY3QsCiogYW55IGhhbmRlbHMgdG8gb3RoZXIgcmVzb3VyY2UgaGVsZCBieSB0aGUgY2FsbGVyIG11c3QgYmUgY2xvc2VkCiogKGUuZy4gYSB0ZXh0dXJlIHNob3VsZCByZWxlYXNlIGFsbCBoZWxkIHN1cmZhY2VzIGJlY2F1c2UgdGVsbGluZyB0aGUgZGV2aWNlIHRoYXQgaXQncyBiZWVuIHJlbGVhc2VkLikKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgdm9pZCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX0FkZFJlc291cmNlKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RSZXNvdXJjZSAqcmVzb3VyY2UpewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgUmVzb3VyY2VMaXN0KiByZXNvdXJjZUxpc3Q7CgogICAgVFJBQ0UoIiglcCkgOiByZXNvdXJjZSAlcFxuIiwgVGhpcywgcmVzb3VyY2UpOwojaWYgMAogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnJlc291cmNlU3RvcmVDcml0aWNhbFNlY3Rpb24pOwojZW5kaWYKICAgIC8qIGFkZCBhIG5ldyB0ZXh0dXJlIHRvIHRoZSBmcm90IG9mIHRoZSBsaW5rZWQgbGlzdCAqLwogICAgcmVzb3VyY2VMaXN0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihSZXNvdXJjZUxpc3QpKTsKICAgIHJlc291cmNlTGlzdC0+cmVzb3VyY2UgPSByZXNvdXJjZTsKCiAgICAvKiBHZXQgdGhlIG9sZCBoZWFkICovCiAgICByZXNvdXJjZUxpc3QtPm5leHQgPSBUaGlzLT5yZXNvdXJjZXM7CgogICAgVGhpcy0+cmVzb3VyY2VzID0gcmVzb3VyY2VMaXN0OwogICAgVFJBQ0UoIkFkZGVkIHJlc291cmNlICVwIHdpdGggZWxlbWVudCAlcCBwb2ludGluZyB0byAlcFxuIiwgcmVzb3VyY2UsIHJlc291cmNlTGlzdCwgcmVzb3VyY2VMaXN0LT5uZXh0KTsKCiNpZiAwCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmcmVzb3VyY2VTdG9yZUNyaXRpY2FsU2VjdGlvbik7CiNlbmRpZgogICAgcmV0dXJuOwp9CgpzdGF0aWMgdm9pZCBXSU5BUEkgSVdpbmVEM0REZXZpY2VJbXBsX1JlbW92ZVJlc291cmNlKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RSZXNvdXJjZSAqcmVzb3VyY2UpewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgUmVzb3VyY2VMaXN0KiByZXNvdXJjZUxpc3QgPSBOVUxMOwogICAgUmVzb3VyY2VMaXN0KiBwcmV2aW91c1Jlc291cmNlTGlzdCA9IE5VTEw7CiAgICAKICAgIFRSQUNFKCIoJXApIDogcmVzb3VyY2UgJXBcbiIsIFRoaXMsIHJlc291cmNlKTsKCiNpZiAwCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmcmVzb3VyY2VTdG9yZUNyaXRpY2FsU2VjdGlvbik7CiNlbmRpZgogICAgcmVzb3VyY2VMaXN0ID0gVGhpcy0+cmVzb3VyY2VzOwoKICAgIHdoaWxlIChyZXNvdXJjZUxpc3QgIT0gTlVMTCkgewogICAgICAgIGlmKHJlc291cmNlTGlzdC0+cmVzb3VyY2UgPT0gcmVzb3VyY2UpIGJyZWFrOwogICAgICAgIHByZXZpb3VzUmVzb3VyY2VMaXN0ID0gcmVzb3VyY2VMaXN0OwogICAgICAgIHJlc291cmNlTGlzdCA9IHJlc291cmNlTGlzdC0+bmV4dDsKICAgIH0KCiAgICBpZiAocmVzb3VyY2VMaXN0ID09IE5VTEwpIHsKICAgICAgICBGSVhNRSgiQXR0ZW1wdGVkIHRvIHJlbW92ZSByZXNvdXJjZSAlcCB0aGF0IGhhc24ndCBiZWVuIHN0b3JlZFxuIiwgcmVzb3VyY2UpOwojaWYgMAogICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZyZXNvdXJjZVN0b3JlQ3JpdGljYWxTZWN0aW9uKTsKI2VuZGlmCiAgICAgICAgcmV0dXJuOwogICAgfSBlbHNlIHsKICAgICAgICAgICAgVFJBQ0UoIkZvdW5kIHJlc291cmNlICAlcCB3aXRoIGVsZW1lbnQgJXAgcG9pbnRpbmcgdG8gJXAgKHByZXZpb3VzICVwKVxuIiwgcmVzb3VyY2VMaXN0LT5yZXNvdXJjZSwgcmVzb3VyY2VMaXN0LCByZXNvdXJjZUxpc3QtPm5leHQsIHByZXZpb3VzUmVzb3VyY2VMaXN0KTsKICAgIH0KICAgIC8qIG1ha2Ugc3VyZSB3ZSBkb24ndCBsZWF2ZSBhIGhvbGUgaW4gdGhlIGxpc3QgKi8KICAgIGlmIChwcmV2aW91c1Jlc291cmNlTGlzdCAhPSBOVUxMKSB7CiAgICAgICAgcHJldmlvdXNSZXNvdXJjZUxpc3QtPm5leHQgPSByZXNvdXJjZUxpc3QtPm5leHQ7CiAgICB9IGVsc2UgewogICAgICAgIFRoaXMtPnJlc291cmNlcyA9IHJlc291cmNlTGlzdC0+bmV4dDsKICAgIH0KCiNpZiAwCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmcmVzb3VyY2VTdG9yZUNyaXRpY2FsU2VjdGlvbik7CiNlbmRpZgogICAgcmV0dXJuOwp9CgoKc3RhdGljIHZvaWQgV0lOQVBJIElXaW5lRDNERGV2aWNlSW1wbF9SZXNvdXJjZVJlbGVhc2VkKElXaW5lRDNERGV2aWNlICppZmFjZSwgSVdpbmVEM0RSZXNvdXJjZSAqcmVzb3VyY2UpewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBpZmFjZTsKICAgIGludCBjb3VudGVyOwoKICAgIFRSQUNFKCIoJXApIDogcmVzb3VyY2UgJXBcbiIsIFRoaXMsIHJlc291cmNlKTsKICAgIHN3aXRjaChJV2luZUQzRFJlc291cmNlX0dldFR5cGUocmVzb3VyY2UpKXsKICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9TVVJGQUNFOgogICAgICAgIC8qIFRPRE86IGNoZWNrIGZyb250IGFuZCBiYWNrIGJ1ZmZlcnMsIHJlbmRlcnRhcmdldHMgZXRjLi4gIHBvc3NpYmx5IHN3YXBjaGFpbnM/ICovCiAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEUlRZUEVfVEVYVFVSRToKICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9DVUJFVEVYVFVSRToKICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9WT0xVTUVURVhUVVJFOgogICAgICAgICAgICAgICAgZm9yIChjb3VudGVyID0gMDsgY291bnRlciA8IEdMX0xJTUlUUyhzYW1wbGVyX3N0YWdlcyk7IGNvdW50ZXIrKykgewogICAgICAgICAgICAgICAgICAgIGlmIChUaGlzLT5zdGF0ZUJsb2NrICE9IE5VTEwgJiYgVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZXNbY291bnRlcl0gPT0gKElXaW5lRDNEQmFzZVRleHR1cmUgKilyZXNvdXJjZSkgewogICAgICAgICAgICAgICAgICAgICAgICBXQVJOKCJUZXh0dXJlIGJlaW5nIHJlbGVhc2VkIGlzIHN0aWxsIGJ5IGEgc3RhdGVibG9jaywgU3RhZ2UgPSAldSBUZXh0dXJlID0gJXBcbiIsIGNvdW50ZXIsIHJlc291cmNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+dGV4dHVyZXNbY291bnRlcl0gPSBOVUxMOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoVGhpcy0+dXBkYXRlU3RhdGVCbG9jayAhPSBUaGlzLT5zdGF0ZUJsb2NrICl7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT50ZXh0dXJlc1tjb3VudGVyXSA9PSAoSVdpbmVEM0RCYXNlVGV4dHVyZSAqKXJlc291cmNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBXQVJOKCJUZXh0dXJlIGJlaW5nIHJlbGVhc2VkIGlzIHN0aWxsIGJ5IGEgc3RhdGVibG9jaywgU3RhZ2UgPSAldSBUZXh0dXJlID0gJXBcbiIsIGNvdW50ZXIsIHJlc291cmNlKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnRleHR1cmVzW2NvdW50ZXJdID0gTlVMTDsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9WT0xVTUU6CiAgICAgICAgLyogVE9ETzogbm90aGluZyByZWFsbHk/ICovCiAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEUlRZUEVfVkVSVEVYQlVGRkVSOgogICAgICAgIC8qIE1TRE46IFdoZW4gYW4gYXBwbGljYXRpb24gbm8gbG9uZ2VyIGhvbGRzIGEgcmVmZXJlbmNlcyB0byB0aGlzIGludGVyZmFjZSwgdGhlIGludGVyZmFjZSB3aWxsIGF1dG9tYXRpY2FsbHkgYmUgZnJlZWQuICovCiAgICAgICAgewogICAgICAgICAgICBpbnQgc3RyZWFtTnVtYmVyOwogICAgICAgICAgICBUUkFDRSgiQ2xlYW5pbmcgdXAgc3RyZWFtIHBvaW50ZXJzXG4iKTsKCiAgICAgICAgICAgIGZvcihzdHJlYW1OdW1iZXIgPSAwOyBzdHJlYW1OdW1iZXIgPCBNQVhfU1RSRUFNUzsgc3RyZWFtTnVtYmVyICsrKXsKICAgICAgICAgICAgICAgIC8qIEZJTkRPVVQ6IHNob3VsZCBhIHdhcm4gYmUgZ2VuZXJhdGVkIGlmIHdlcmUgcmVjb3JkaW5nIGFuZCB1cGRhdGVTdGF0ZUJsb2NrLT5zdHJlYW1Tb3VyY2UgaXMgbG9zdD8KICAgICAgICAgICAgICAgIEZJTkRPVVQ6IHNob3VsZCBjaGFuZ2VzLnN0cmVhbVNvdXJjZVtTdHJlYW1OdW1iZXJdIGJlIHNldCA/CiAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYgKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2sgIT0gTlVMTCApIHsgLyogPT1OVUxMIHdoZW4gZGV2aWNlIGlzIGJlaW5nIGRlc3Ryb3llZCAqLwogICAgICAgICAgICAgICAgICAgIGlmICgoSVdpbmVEM0RSZXNvdXJjZSAqKVRoaXMtPnVwZGF0ZVN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtzdHJlYW1OdW1iZXJdID09IHJlc291cmNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEZJWE1FKCJWZXJ0ZXggYnVmZmVyIHJlbGVhc2VkIHdoaWxlIGJvdW5kIHRvIGEgc3RhdGUgYmxvY2ssIHN0cmVhbSAlZFxuIiwgc3RyZWFtTnVtYmVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+c3RyZWFtU291cmNlW3N0cmVhbU51bWJlcl0gPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAvKiBTZXQgY2hhbmdlZCBmbGFnPyAqLwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChUaGlzLT5zdGF0ZUJsb2NrICE9IE5VTEwgKSB7IC8qIG9ubHkgaGFwcGVucyBpZiB0aGVyZSBpcyBhbiBlcnJvciBpbiB0aGUgYXBwbGljYXRpb24sIG9yIG9uIHJlc2V0L3JlbGVhc2UgKGJlY2F1c2Ugd2UgZG9uJ3QgbWFuYWdlIGludGVybmFsIHRyYWNraW5nIHByb3Blcmx5KSAqLwogICAgICAgICAgICAgICAgICAgIGlmICgoSVdpbmVEM0RSZXNvdXJjZSAqKVRoaXMtPnN0YXRlQmxvY2stPnN0cmVhbVNvdXJjZVtzdHJlYW1OdW1iZXJdID09IHJlc291cmNlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFKCJWZXJ0ZXggYnVmZmVyIHJlbGVhc2VkIHdoaWxlIGJvdW5kIHRvIGEgc3RhdGUgYmxvY2ssIHN0cmVhbSAlZFxuIiwgc3RyZWFtTnVtYmVyKTsKICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+c3RyZWFtU291cmNlW3N0cmVhbU51bWJlcl0gPSAwOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KI2lmIDAgICAvKiBUT0RPOiBNYW5hZ2UgaW50ZXJuYWwgdHJhY2tpbmcgcHJvcGVybHkgc28gdGhhdCAndGhpcyBzaG91bGRuJ3QgaGFwcGVuJyAqLwogICAgICAgICAgICAgICAgIGVsc2UgeyAvKiBUaGlzIHNob3VsZG4ndCBoYXBwZW4gKi8KICAgICAgICAgICAgICAgICAgICBGSVhNRSgiQ2FsbGluZyBhcHBsaWNhdGlvbiBoYXMgcmVsZWFzZWQgdGhlIGRldmljZSBiZWZvcmUgcmVsYXNpbmcgYWxsIHRoZSByZXNvdXJjZXMgYm91bmQgdG8gdGhlIGRldmljZVxuIik7CiAgICAgICAgICAgICAgICB9CiNlbmRpZgoKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RSVFlQRV9JTkRFWEJVRkZFUjoKICAgICAgICAvKiBNU0ROOiBXaGVuIGFuIGFwcGxpY2F0aW9uIG5vIGxvbmdlciBob2xkcyBhIHJlZmVyZW5jZXMgdG8gdGhpcyBpbnRlcmZhY2UsIHRoZSBpbnRlcmZhY2Ugd2lsbCBhdXRvbWF0aWNhbGx5IGJlIGZyZWVkLiovCiAgICAgICAgaWYgKFRoaXMtPnVwZGF0ZVN0YXRlQmxvY2sgIT0gTlVMTCApIHsgLyogPT1OVUxMIHdoZW4gZGV2aWNlIGlzIGJlaW5nIGRlc3Ryb3llZCAqLwogICAgICAgICAgICBpZiAoVGhpcy0+dXBkYXRlU3RhdGVCbG9jay0+cEluZGV4RGF0YSA9PSAoSVdpbmVEM0RJbmRleEJ1ZmZlciAqKXJlc291cmNlKSB7CiAgICAgICAgICAgICAgICBUaGlzLT51cGRhdGVTdGF0ZUJsb2NrLT5wSW5kZXhEYXRhID0gIE5VTEw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKFRoaXMtPnN0YXRlQmxvY2sgIT0gTlVMTCApIHsgLyogPT1OVUxMIHdoZW4gZGV2aWNlIGlzIGJlaW5nIGRlc3Ryb3llZCAqLwogICAgICAgICAgICBpZiAoVGhpcy0+c3RhdGVCbG9jay0+cEluZGV4RGF0YSA9PSAoSVdpbmVEM0RJbmRleEJ1ZmZlciAqKXJlc291cmNlKSB7CiAgICAgICAgICAgICAgICBUaGlzLT5zdGF0ZUJsb2NrLT5wSW5kZXhEYXRhID0gIE5VTEw7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgRklYTUUoIiglcCkgdW5rbm93biByZXNvdXJjZSB0eXBlICVwICV1XG4iLCBUaGlzLCByZXNvdXJjZSwgSVdpbmVEM0RSZXNvdXJjZV9HZXRUeXBlKHJlc291cmNlKSk7CiAgICAgICAgYnJlYWs7CiAgICB9CgoKICAgIC8qIFJlbW92ZSB0aGUgcmVzb3J1Y2UgZnJvbSB0aGUgcmVzb3VyY2VTdG9yZSAqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX1JlbW92ZVJlc291cmNlKGlmYWNlLCByZXNvdXJjZSk7CgogICAgVFJBQ0UoIlJlc291cmNlIHJlbGVhc2VkXG4iKTsKCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElXaW5lRDNERGV2aWNlIFZUYmwgZm9sbG93cwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCmNvbnN0IElXaW5lRDNERGV2aWNlVnRibCBJV2luZUQzRERldmljZV9WdGJsID0KewogICAgLyoqKiBJVW5rbm93biBtZXRob2RzICoqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9RdWVyeUludGVyZmFjZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9BZGRSZWYsCiAgICBJV2luZUQzRERldmljZUltcGxfUmVsZWFzZSwKICAgIC8qKiogSVdpbmVEM0REZXZpY2UgbWV0aG9kcyAqKiovCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UGFyZW50LAogICAgLyoqKiBDcmVhdGlvbiBtZXRob2RzKiovCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVmVydGV4QnVmZmVyLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZUluZGV4QnVmZmVyLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVN0YXRlQmxvY2ssCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlU3VyZmFjZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9DcmVhdGVUZXh0dXJlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVZvbHVtZVRleHR1cmUsCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVm9sdW1lLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZUN1YmVUZXh0dXJlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVF1ZXJ5LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZUFkZGl0aW9uYWxTd2FwQ2hhaW4sCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVmVydGV4RGVjbGFyYXRpb24sCiAgICBJV2luZUQzRERldmljZUltcGxfQ3JlYXRlVmVydGV4U2hhZGVyLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVBpeGVsU2hhZGVyLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0NyZWF0ZVBhbGV0dGUsCiAgICAvKioqIE9kZCBmdW5jdGlvbnMgKiovCiAgICBJV2luZUQzRERldmljZUltcGxfSW5pdDNELAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1VuaW5pdDNELAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEZ1bGxzY3JlZW4sCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0TXVsdGl0aHJlYWRlZCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9FdmljdE1hbmFnZWRSZXNvdXJjZXMsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0QXZhaWxhYmxlVGV4dHVyZU1lbSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRCYWNrQnVmZmVyLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldENyZWF0aW9uUGFyYW1ldGVycywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXREZXZpY2VDYXBzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldERpcmVjdDNELAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldERpc3BsYXlNb2RlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldERpc3BsYXlNb2RlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldEhXTkQsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0SFdORCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXROdW1iZXJPZlN3YXBDaGFpbnMsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UmFzdGVyU3RhdHVzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFN3YXBDaGFpbiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9SZXNldCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXREaWFsb2dCb3hNb2RlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEN1cnNvclByb3BlcnRpZXMsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0Q3Vyc29yUG9zaXRpb24sCiAgICBJV2luZUQzRERldmljZUltcGxfU2hvd0N1cnNvciwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9UZXN0Q29vcGVyYXRpdmVMZXZlbCwKICAgIC8qKiogR2V0dGVycyBhbmQgc2V0dGVycyAqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRDbGlwUGxhbmUsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0Q2xpcFBsYW5lLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldENsaXBTdGF0dXMsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0Q2xpcFN0YXR1cywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRDdXJyZW50VGV4dHVyZVBhbGV0dGUsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0Q3VycmVudFRleHR1cmVQYWxldHRlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldERlcHRoU3RlbmNpbFN1cmZhY2UsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0RGVwdGhTdGVuY2lsU3VyZmFjZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRGVkYsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0RlZGLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEdhbW1hUmFtcCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRHYW1tYVJhbXAsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0SW5kaWNlcywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRJbmRpY2VzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldEJhc2V2ZXJ0ZXhJbmRleCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRMaWdodCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRMaWdodCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRMaWdodEVuYWJsZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRMaWdodEVuYWJsZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRNYXRlcmlhbCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRNYXRlcmlhbCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXROUGF0Y2hNb2RlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldE5QYXRjaE1vZGUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0UGFsZXR0ZUVudHJpZXMsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UGFsZXR0ZUVudHJpZXMsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0UGl4ZWxTaGFkZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UGl4ZWxTaGFkZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0UGl4ZWxTaGFkZXJDb25zdGFudEIsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UGl4ZWxTaGFkZXJDb25zdGFudEIsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0UGl4ZWxTaGFkZXJDb25zdGFudEksCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UGl4ZWxTaGFkZXJDb25zdGFudEksCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0UGl4ZWxTaGFkZXJDb25zdGFudEYsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UGl4ZWxTaGFkZXJDb25zdGFudEYsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0UmVuZGVyU3RhdGUsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0UmVuZGVyU3RhdGUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0UmVuZGVyVGFyZ2V0LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFJlbmRlclRhcmdldCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRGcm9udEJhY2tCdWZmZXJzLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFNhbXBsZXJTdGF0ZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRTYW1wbGVyU3RhdGUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0U2Npc3NvclJlY3QsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0U2Npc3NvclJlY3QsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0U29mdHdhcmVWZXJ0ZXhQcm9jZXNzaW5nLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFNvZnR3YXJlVmVydGV4UHJvY2Vzc2luZywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRTdHJlYW1Tb3VyY2UsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0U3RyZWFtU291cmNlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFN0cmVhbVNvdXJjZUZyZXEsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0U3RyZWFtU291cmNlRnJlcSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRUZXh0dXJlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFRleHR1cmUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0VGV4dHVyZVN0YWdlU3RhdGUsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0VGV4dHVyZVN0YWdlU3RhdGUsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0VHJhbnNmb3JtLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFRyYW5zZm9ybSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWZXJ0ZXhEZWNsYXJhdGlvbiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWZXJ0ZXhEZWNsYXJhdGlvbiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWZXJ0ZXhTaGFkZXIsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0VmVydGV4U2hhZGVyLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZlcnRleFNoYWRlckNvbnN0YW50QiwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEIsCiAgICBJV2luZUQzRERldmljZUltcGxfU2V0VmVydGV4U2hhZGVyQ29uc3RhbnRJLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZlcnRleFNoYWRlckNvbnN0YW50SSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9TZXRWZXJ0ZXhTaGFkZXJDb25zdGFudEYsCiAgICBJV2luZUQzRERldmljZUltcGxfR2V0VmVydGV4U2hhZGVyQ29uc3RhbnRGLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1NldFZpZXdwb3J0LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0dldFZpZXdwb3J0LAogICAgSVdpbmVEM0REZXZpY2VJbXBsX011bHRpcGx5VHJhbnNmb3JtLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1ZhbGlkYXRlRGV2aWNlLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1Byb2Nlc3NWZXJ0aWNlcywKICAgIC8qKiogU3RhdGUgYmxvY2sgKioqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX0JlZ2luU3RhdGVCbG9jaywKICAgIElXaW5lRDNERGV2aWNlSW1wbF9FbmRTdGF0ZUJsb2NrLAogICAgLyoqKiBTY2VuZSBtYW5hZ2VtZW50ICoqKi8KICAgIElXaW5lRDNERGV2aWNlSW1wbF9CZWdpblNjZW5lLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0VuZFNjZW5lLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1ByZXNlbnQsCiAgICBJV2luZUQzRERldmljZUltcGxfQ2xlYXIsCiAgICAvKioqIERyYXdpbmcgKioqLwogICAgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdQcmltaXRpdmUsCiAgICBJV2luZUQzRERldmljZUltcGxfRHJhd0luZGV4ZWRQcmltaXRpdmUsCiAgICBJV2luZUQzRERldmljZUltcGxfRHJhd1ByaW1pdGl2ZVVQLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX0RyYXdJbmRleGVkUHJpbWl0aXZlVVAsCiAgICBJV2luZUQzRERldmljZUltcGxfRHJhd1ByaW1pdGl2ZVN0cmlkZWQsCiAgICBJV2luZUQzRERldmljZUltcGxfRHJhd1JlY3RQYXRjaCwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9EcmF3VHJpUGF0Y2gsCiAgICBJV2luZUQzRERldmljZUltcGxfRGVsZXRlUGF0Y2gsCiAgICBJV2luZUQzRERldmljZUltcGxfQ29sb3JGaWxsLAogICAgSVdpbmVEM0REZXZpY2VJbXBsX1VwZGF0ZVRleHR1cmUsCiAgICBJV2luZUQzRERldmljZUltcGxfVXBkYXRlU3VyZmFjZSwKICAgIElXaW5lRDNERGV2aWNlSW1wbF9HZXRGcm9udEJ1ZmZlckRhdGEsCiAgICAvKioqIG9iamVjdCB0cmFja2luZyAqKiovCiAgICBJV2luZUQzRERldmljZUltcGxfUmVzb3VyY2VSZWxlYXNlZAp9OwoKCmNvbnN0IERXT1JEIFNhdmVkUGl4ZWxTdGF0ZXNfUltOVU1fU0FWRURQSVhFTFNUQVRFU19SXSA9IHsKICAgIFdJTkVEM0RSU19BTFBIQUJMRU5ERU5BQkxFICAgLAogICAgV0lORUQzRFJTX0FMUEhBRlVOQyAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfQUxQSEFSRUYgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19BTFBIQVRFU1RFTkFCTEUgICAgLAogICAgV0lORUQzRFJTX0JMRU5ET1AgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfQ09MT1JXUklURUVOQUJMRSAgICwKICAgIFdJTkVEM0RSU19ERVNUQkxFTkQgICAgICAgICAgLAogICAgV0lORUQzRFJTX0RJVEhFUkVOQUJMRSAgICAgICAsCiAgICBXSU5FRDNEUlNfRklMTE1PREUgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19GT0dERU5TSVRZICAgICAgICAgLAogICAgV0lORUQzRFJTX0ZPR0VORCAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRk9HU1RBUlQgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19MQVNUUElYRUwgICAgICAgICAgLAogICAgV0lORUQzRFJTX1NIQURFTU9ERSAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfU1JDQkxFTkQgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19TVEVOQ0lMRU5BQkxFICAgICAgLAogICAgV0lORUQzRFJTX1NURU5DSUxGQUlMICAgICAgICAsCiAgICBXSU5FRDNEUlNfU1RFTkNJTEZVTkMgICAgICAgICwKICAgIFdJTkVEM0RSU19TVEVOQ0lMTUFTSyAgICAgICAgLAogICAgV0lORUQzRFJTX1NURU5DSUxQQVNTICAgICAgICAsCiAgICBXSU5FRDNEUlNfU1RFTkNJTFJFRiAgICAgICAgICwKICAgIFdJTkVEM0RSU19TVEVOQ0lMV1JJVEVNQVNLICAgLAogICAgV0lORUQzRFJTX1NURU5DSUxaRkFJTCAgICAgICAsCiAgICBXSU5FRDNEUlNfVEVYVFVSRUZBQ1RPUiAgICAgICwKICAgIFdJTkVEM0RSU19XUkFQMCAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1dSQVAxICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfV1JBUDIgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19XUkFQMyAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1dSQVA0ICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfV1JBUDUgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19XUkFQNiAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1dSQVA3ICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfWkVOQUJMRSAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19aRlVOQyAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1pXUklURUVOQUJMRQp9OwoKY29uc3QgRFdPUkQgU2F2ZWRQaXhlbFN0YXRlc19UW05VTV9TQVZFRFBJWEVMU1RBVEVTX1RdID0gewogICAgV0lORUQzRFRTU19BRERSRVNTVyAgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19BTFBIQUFSRzAgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19BTFBIQUFSRzEgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19BTFBIQUFSRzIgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19BTFBIQU9QICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19CVU1QRU5WTE9GRlNFVCAgICAgICAgLAogICAgV0lORUQzRFRTU19CVU1QRU5WTFNDQUxFICAgICAgICAgLAogICAgV0lORUQzRFRTU19CVU1QRU5WTUFUMDAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19CVU1QRU5WTUFUMDEgICAgICAgICAgLAogICAgV0lORUQzRFRTU19CVU1QRU5WTUFUMTAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19CVU1QRU5WTUFUMTEgICAgICAgICAgLAogICAgV0lORUQzRFRTU19DT0xPUkFSRzAgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19DT0xPUkFSRzEgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19DT0xPUkFSRzIgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19DT0xPUk9QICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19SRVNVTFRBUkcgICAgICAgICAgICAgLAogICAgV0lORUQzRFRTU19URVhDT09SRElOREVYICAgICAgICAgLAogICAgV0lORUQzRFRTU19URVhUVVJFVFJBTlNGT1JNRkxBR1MKfTsKCmNvbnN0IERXT1JEIFNhdmVkUGl4ZWxTdGF0ZXNfU1tOVU1fU0FWRURQSVhFTFNUQVRFU19TXSA9IHsKICAgIFdJTkVEM0RTQU1QX0FERFJFU1NVICAgICAgICAgLAogICAgV0lORUQzRFNBTVBfQUREUkVTU1YgICAgICAgICAsCiAgICBXSU5FRDNEU0FNUF9BRERSRVNTVyAgICAgICAgICwKICAgIFdJTkVEM0RTQU1QX0JPUkRFUkNPTE9SICAgICAgLAogICAgV0lORUQzRFNBTVBfTUFHRklMVEVSICAgICAgICAsCiAgICBXSU5FRDNEU0FNUF9NSU5GSUxURVIgICAgICAgICwKICAgIFdJTkVEM0RTQU1QX01JUEZJTFRFUiAgICAgICAgLAogICAgV0lORUQzRFNBTVBfTUlQTUFQTE9EQklBUyAgICAsCiAgICBXSU5FRDNEU0FNUF9NQVhNSVBMRVZFTCAgICAgICwKICAgIFdJTkVEM0RTQU1QX01BWEFOSVNPVFJPUFkgICAgLAogICAgV0lORUQzRFNBTVBfU1JHQlRFWFRVUkUgICAgICAsCiAgICBXSU5FRDNEU0FNUF9FTEVNRU5USU5ERVgKfTsKCmNvbnN0IERXT1JEIFNhdmVkVmVydGV4U3RhdGVzX1JbTlVNX1NBVkVEVkVSVEVYU1RBVEVTX1JdID0gewogICAgV0lORUQzRFJTX0FNQklFTlQgICAgICAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19BTUJJRU5UTUFURVJJQUxTT1VSQ0UgICAgICAgICAsCiAgICBXSU5FRDNEUlNfQ0xJUFBJTkcgICAgICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0NMSVBQTEFORUVOQUJMRSAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19DT0xPUlZFUlRFWCAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRElGRlVTRU1BVEVSSUFMU09VUkNFICAgICAgICAgLAogICAgV0lORUQzRFJTX0VNSVNTSVZFTUFURVJJQUxTT1VSQ0UgICAgICAgICwKICAgIFdJTkVEM0RSU19GT0dERU5TSVRZICAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRk9HRU5EICAgICAgICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0ZPR1NUQVJUICAgICAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19GT0dUQUJMRU1PREUgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfRk9HVkVSVEVYTU9ERSAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX0lOREVYRURWRVJURVhCTEVOREVOQUJMRSAgICAgICwKICAgIFdJTkVEM0RSU19MSUdIVElORyAgICAgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfTE9DQUxWSUVXRVIgICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX01VTFRJU0FNUExFQU5USUFMSUFTICAgICAgICAgICwKICAgIFdJTkVEM0RSU19NVUxUSVNBTVBMRU1BU0sgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfTk9STUFMSVpFTk9STUFMUyAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1BBVENIRURHRVNUWUxFICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19QT0lOVFNDQUxFX0EgICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfUE9JTlRTQ0FMRV9CICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1BPSU5UU0NBTEVfQyAgICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19QT0lOVFNDQUxFRU5BQkxFICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfUE9JTlRTSVpFICAgICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1BPSU5UU0laRV9NQVggICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19QT0lOVFNJWkVfTUlOICAgICAgICAgICAgICAgICAsCiAgICBXSU5FRDNEUlNfUE9JTlRTUFJJVEVFTkFCTEUgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1JBTkdFRk9HRU5BQkxFICAgICAgICAgICAgICAgICwKICAgIFdJTkVEM0RSU19TUEVDVUxBUk1BVEVSSUFMU09VUkNFICAgICAgICAsCiAgICBXSU5FRDNEUlNfVFdFRU5GQUNUT1IgICAgICAgICAgICAgICAgICAgLAogICAgV0lORUQzRFJTX1ZFUlRFWEJMRU5ECn07Cgpjb25zdCBEV09SRCBTYXZlZFZlcnRleFN0YXRlc19UW05VTV9TQVZFRFZFUlRFWFNUQVRFU19UXSA9IHsKICAgIFdJTkVEM0RUU1NfVEVYQ09PUkRJTkRFWCAgICAgICAgICwKICAgIFdJTkVEM0RUU1NfVEVYVFVSRVRSQU5TRk9STUZMQUdTCn07Cgpjb25zdCBEV09SRCBTYXZlZFZlcnRleFN0YXRlc19TW05VTV9TQVZFRFZFUlRFWFNUQVRFU19TXSA9IHsKICAgIFdJTkVEM0RTQU1QX0RNQVBPRkZTRVQKfTsKCnZvaWQgSVdpbmVEM0REZXZpY2VJbXBsX01hcmtTdGF0ZURpcnR5KElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcywgRFdPUkQgc3RhdGUpIHsKICAgIERXT1JEIHJlcCA9IFN0YXRlVGFibGVbc3RhdGVdLnJlcHJlc2VudGF0aXZlOwogICAgRFdPUkQgaWR4OwogICAgQllURSBzaGlmdDsKICAgIFVJTlQgaTsKICAgIFdpbmVEM0RDb250ZXh0ICpjb250ZXh0OwoKICAgIGlmKCFyZXApIHJldHVybjsKICAgIGZvcihpID0gMDsgaSA8IFRoaXMtPm51bUNvbnRleHRzOyBpKyspIHsKICAgICAgICBjb250ZXh0ID0gVGhpcy0+Y29udGV4dHNbaV07CiAgICAgICAgaWYoaXNTdGF0ZURpcnR5KGNvbnRleHQsIHJlcCkpIGNvbnRpbnVlOwoKICAgICAgICBjb250ZXh0LT5kaXJ0eUFycmF5W2NvbnRleHQtPm51bURpcnR5RW50cmllcysrXSA9IHJlcDsKICAgICAgICBpZHggPSByZXAgPj4gNTsKICAgICAgICBzaGlmdCA9IHJlcCAmIDB4MWY7CiAgICAgICAgY29udGV4dC0+aXNTdGF0ZURpcnR5W2lkeF0gfD0gKDEgPDwgc2hpZnQpOwogICAgfQp9Cg==