Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDE1IEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUctNCBBQUMgRGVjb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgIEF1dGhvcihzKTogICBKb3NlZiBIb2VwZmwKICAgRGVzY3JpcHRpb246CgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKLyohCiAgXHBhZ2UgZGVmYXVsdCBHZW5lcmFsIE92ZXJ2aWV3IG9mIHRoZSBBQUMgRGVjb2RlciBJbXBsZW1lbnRhdGlvbgoKICBUaGUgbWFpbiBlbnRyeSBwb2ludCB0byBkZWNvZGUgYSBBQUMgZnJhbWUgaXMgQ0FhY0RlY29kZXJfRGVjb2RlRnJhbWUoKS4gSXQgaGFuZGxlcyB0aGUgZGlmZmVyZW50CiAgdHJhbnNwb3J0IG11bHRpcGxleGVzIGFuZCBiaXRzdHJlYW0gZm9ybWF0cyBzdXBwb3J0ZWQgYnkgdGhpcyBpbXBsZW1lbnRhdGlvbi4gSXQgZXh0cmFjdHMgdGhlCiAgQUFDX3Jhd19kYXRhX2Jsb2NrcyBmcm9tIHRoZXNlIGJpdHN0cmVhbXMgdG8gZnVydGhlciBwcm9jZXNzIHRoZW4gaW4gdGhlIGFjdHVhbCBkZWNvZGluZyBzdGFnZXMuCgogIE5vdGU6IENsaWNrIG9uIGEgZnVuY3Rpb24gb2YgZmlsZSBpbiB0aGUgYWJvdmUgaW1hZ2UgdG8gc2VlIGRldGFpbHMgYWJvdXQgdGhlIGZ1bmN0aW9uLiBBbHNvIG5vdGUsIHRoYXQKICB0aGlzIGlzIGp1c3QgYW4gb3ZlcnZpZXcgb2YgdGhlIG1vc3QgaW1wb3J0YW50IGZ1bmN0aW9ucyBhbmQgbm90IGEgY29tcGxldGUgY2FsbCBncmFwaC4KCiAgPGgyPjEgQml0c3RyZWFtIGRlZm9ybWF0dGVyPC9oMj4KICBUaGUgYmFzaWMgYml0IHN0cmVhbSBwYXJzZXIgZnVuY3Rpb24gQ0NoYW5uZWxFbGVtZW50X1JlYWQoKSBpcyBjYWxsZWQuIEl0IHVzZXMgb3RoZXIgc3ViY2FsbHMgaW4gb3JkZXIKICB0byBwYXJzZSBhbmQgdW5wYWNrIHRoZSBiaXRzdHJlYW1zLiBOb3RlLCB0aGF0IHRoaXMgaW5jbHVkZXMgaHVmZm1hbm4gZGVjb2Rpbmcgb2YgdGhlIGNvZGVkIHNwZWN0cmFsIGRhdGEuCiAgVGhpcyBvcGVyYXRpb24gY2FuIGJlIGNvbXB1dGF0aW9uYWwgc2lnbmlmaWNhbnQgc3BlY2lmaWNhbGx5IGF0IGhpZ2hlciBiaXRyYXRlcy4gT3B0aW1pemF0aW9uIGlzIGxpa2VseSBpbgogIENCbG9ja19SZWFkU3BlY3RyYWxEYXRhKCkuCgogIFRoZSBiaXRzdHJlYW0gZGVmb3JtYXR0ZXIgYWxzbyBpbmNsdWRlcyBtYW55IGJpdGZpZWxkIG9wZXJhdGlvbnMuIFByb2ZpbGluZyBvbiB0aGUgdGFyZ2V0IHdpbGwgZGV0ZXJtaW5lCiAgcmVxdWlyZWQgb3B0aW1pemF0aW9ucy4KCiAgPGgyPjIgQWN0dWFsIGRlY29kaW5nIHRvIHJldGFpbiB0aGUgdGltZSBkb21haW4gb3V0cHV0PC9oMj4KICBUaGUgYmFzaWMgYml0c3RyZWFtIGRlZm9ybWF0dGVyIGZ1bmN0aW9uIENDaGFubmVsRWxlbWVudF9EZWNvZGUoKSBmb3IgQ1BFIGVsZW1lbnRzIGFuZCBTQ0UgZWxlbWVudHMgYXJlIGNhbGxlZC4KICBFeGNlcHQgZm9yIHRoZSBzdGVyZW8gcHJvY2Vzc2luZyAoMi4xKSB3aGljaCBpcyBvbmx5IHVzZWQgZm9yIENQRSBlbGVtZW50cywgdGhlIGZ1bmN0aW9uIGNhbGxzIGZvciBDUEUgb3IgU0NFCiAgYXJlIHNpbWlsYXIsIGV4Y2VwdCB0aGF0IENQRSBhbHdheXMgcHJvY2Vzc2VzIHRvIGluZGVwZW5kZW50IGNoYW5uZWxzIHdoaWxlIFNDRSBvbmx5IHByb2Nlc3NlcyBvbmUgY2hhbm5lbC4KCiAgT2Z0ZW4gdGhlcmUgaXMgdGhlIGRpc3RpbmN0aW9uIGJldHdlZW4gbG9uZyBibG9ja3MgYW5kIHNob3J0IGJsb2Nrcy4gSG93ZXZlciwgY29tcHV0YXRpb25hbCBleHBlbnNpdmUgZnVuY3Rpb25zCiAgdGhhdCB1c3VzYWxseSByZXF1aXJlIG9wdGltaXphdGlvbiBhcmUgYmVpbmcgc2hhcmVkIGJ5IHRoZXNlIHR3byBncm91cHMsCgogIDxoMz4yLjEgU3RlcmVvIHByb2Nlc3NpbmcgZm9yIENQRSBlbGVtZW50czwvaDM+CiAgQ0NoYW5uZWxQYWlyRWxlbWVudF9EZWNvZGUoKSBmaXJzdCBjYWxsZXMgdGhlIGpvaW50IHN0ZXJlbyAgdG9vbHMgaW4gc3RlcmVvLmNwcCB3aGVuIHJlcXVpcmVkLgoKICA8aDM+Mi4yIFNjYWxpbmcgb2Ygc3BlY3RyYWwgZGF0YTwvaDM+CiAgQ0Jsb2NrX1NjYWxlU3BlY3RyYWxEYXRhKCkuCgogIDxoMz4yLjMgQXBwbHkgYWRkaXRpb25hbCBjb2RpbmcgdG9vbHM8L2gzPgogIEFwcGx5VG9vbHMoKSBjYWxsZXMgdGhlIFBOUyB0b29scyBpbiBjYXNlIG9mIE1QRUctNCBiaXRzdHJlYW1zLCBhbmQgVE5TIGZpbHRlcmluZyBDVG5zX0FwcGx5KCkgZm9yIE1QRUctMiBhbmQgTVBFRy00IGJpdHN0cmVhbXMuCiAgVGhlIGZ1bmN0aW9uIFRuc0ZpbHRlcklJUigpIHdoaWNoIGlzIGNhbGxlZCBieSBDVG5zX0FwcGx5KCkgKDIuMy4xKSBtaWdodCByZXF1aXJlIHNvbWUgb3B0aW1pemF0aW9uLgoKICA8aDI+MyBGcmVxdWVuY3ktVG8tVGltZSBjb252ZXJzaW9uPC9oMz4KICBUaGUgZmlsdGVyYmFuayBpcyBjYWxsZWQgdXNpbmcgQ0Jsb2NrX0ZyZXF1ZW5jeVRvVGltZSgpIHVzaW5nIHRoZSBNRENUIG1vZHVsZSBmcm9tIHRoZSBGREsgVG9vbHMKCiovCgoKCiNpbmNsdWRlICJhYWNkZWNvZGVyLmgiCgojaW5jbHVkZSAiYWFjX3JvbS5oIgojaW5jbHVkZSAiYWFjX3JhbS5oIgojaW5jbHVkZSAiY2hhbm5lbC5oIgojaW5jbHVkZSAiRkRLX2F1ZGlvLmgiCgojaW5jbHVkZSAiRkRLX3Rvb2xzX3JvbS5oIgoKICAjaW5jbHVkZSAiYWFjZGVjX3Bucy5oIgoKICAjaW5jbHVkZSAic2JyZGVjb2Rlci5oIgoKCgoKICAjaW5jbHVkZSAiYWFjZGVjX2hjci5oIgogICNpbmNsdWRlICJydmxjLmgiCgoKI2luY2x1ZGUgInRwZGVjX2xpYi5oIgoKI2luY2x1ZGUgImNvbmNlYWwuaCIKCiAgI2luY2x1ZGUgIkZES19jcmMuaCIKCgp2b2lkIENBYWNEZWNvZGVyX1N5bmNRbWZNb2RlKEhBTkRMRV9BQUNERUNPREVSIHNlbGYpCnsKCiAgLyogQXNzaWduIHVzZXIgcmVxdWVzdGVkIG1vZGUgKi8KICBzZWxmLT5xbWZNb2RlQ3VyciA9IHNlbGYtPnFtZk1vZGVVc2VyOwoKICBpZiAoIHNlbGYtPnFtZk1vZGVDdXJyID09IE5PVF9ERUZJTkVEICkKICB7CiAgICBpZiAoIChJU19MT1dERUxBWShzZWxmLT5zdHJlYW1JbmZvLmFvdCkgJiYgKHNlbGYtPmZsYWdzICYgQUNfTVBTX1BSRVNFTlQpKQogICAgICB8fCAoIChzZWxmLT5zdHJlYW1JbmZvLmFhY051bUNoYW5uZWxzID09IDEpCiAgICAgICAgJiYgKCAoQ0FOX0RPX1BTKHNlbGYtPnN0cmVhbUluZm8uYW90KSAmJiAhKHNlbGYtPmZsYWdzICYgQUNfTVBTX1BSRVNFTlQpKQogICAgICAgICAgfHwgKCAgSVNfVVNBQyhzZWxmLT5zdHJlYW1JbmZvLmFvdCkgJiYgIChzZWxmLT5mbGFncyAmIEFDX01QU19QUkVTRU5UKSkgKSApICkKICAgIHsKICAgICAgc2VsZi0+cW1mTW9kZUN1cnIgPSBNT0RFX0hROwogICAgfSBlbHNlIHsKICAgICAgc2VsZi0+cW1mTW9kZUN1cnIgPSBNT0RFX0xQOwogICAgfQogIH0KCgogIC8qIFNldCBTQlIgdG8gY3VycmVudCBRTUYgbW9kZS4gRXJyb3IgZG9lcyBub3QgbWF0dGVyLiAqLwogIHNickRlY29kZXJfU2V0UGFyYW0oc2VsZi0+aFNickRlY29kZXIsIFNCUl9RTUZfTU9ERSwgKHNlbGYtPnFtZk1vZGVDdXJyID09IE1PREVfTFApKTsKICBzZWxmLT5wc1Bvc3NpYmxlID0gKChDQU5fRE9fUFMoc2VsZi0+c3RyZWFtSW5mby5hb3QpICYmIHNlbGYtPnN0cmVhbUluZm8uYWFjTnVtQ2hhbm5lbHMgPT0gMSAmJiAhIChzZWxmLT5mbGFncyAmIEFDX01QU19QUkVTRU5UKSkpICYmIHNlbGYtPnFtZk1vZGVDdXJyID09IE1PREVfSFEgOwogIEZES19BU1NFUlQoICEgKCAoc2VsZi0+ZmxhZ3MgJiBBQ19NUFNfUFJFU0VOVCkgJiYgc2VsZi0+cHNQb3NzaWJsZSApICk7Cn0KCnZvaWQgQ0FhY0RlY29kZXJfU2lnbmFsSW50ZXJydXB0aW9uKEhBTkRMRV9BQUNERUNPREVSIHNlbGYpCnsKfQoKLyohCiAgXGJyaWVmIFJlc2V0IGFuY2lsbGFyeSBkYXRhIHN0cnVjdC4gQ2FsbCBiZWZvcmUgcGFyc2luZyBhIG5ldyBmcmFtZS4KCiAgXGFuY0RhdGEgUG9pbnRlciB0byBhbmNpbGxhcnkgZGF0YSBzdHJ1Y3R1cmUKCiAgXHJldHVybiAgRXJyb3IgY29kZQoqLwpzdGF0aWMgQUFDX0RFQ09ERVJfRVJST1IgQ0FhY0RlY29kZXJfQW5jRGF0YVJlc2V0KENBbmNEYXRhICphbmNEYXRhKQp7CiAgaW50IGk7CiAgZm9yIChpPTA7IGk8ODsgaSsrKQogIHsKICAgIGFuY0RhdGEtPm9mZnNldFtpXSA9IDA7CiAgfQogIGFuY0RhdGEtPm5yRWxlbWVudHMgPSAwOwoKICByZXR1cm4gQUFDX0RFQ19PSzsKfQoKLyohCiAgXGJyaWVmIEluaXRpYWxpemUgYW5jaWxsYXJ5IGJ1ZmZlcgoKICBcYW5jRGF0YSBQb2ludGVyIHRvIGFuY2lsbGFyeSBkYXRhIHN0cnVjdHVyZQogIFxidWZmZXIgUG9pbnRlciB0byAoZXh0ZXJuYWwpIGFuYyBkYXRhIGJ1ZmZlcgogIFxzaXplIFNpemUgb2YgdGhlIGJ1ZmZlciBwb2ludGVkIG9uIGJ5IGJ1ZmZlciBpbiBieXRlcwoKICBccmV0dXJuICBFcnJvciBjb2RlCiovCkFBQ19ERUNPREVSX0VSUk9SIENBYWNEZWNvZGVyX0FuY0RhdGFJbml0KENBbmNEYXRhICphbmNEYXRhLCB1bnNpZ25lZCBjaGFyICpidWZmZXIsIGludCBzaXplKQp7CiAgaWYgKHNpemUgPj0gMCkgewogICAgYW5jRGF0YS0+YnVmZmVyID0gYnVmZmVyOwogICAgYW5jRGF0YS0+YnVmZmVyU2l6ZSA9IHNpemU7CgogICAgQ0FhY0RlY29kZXJfQW5jRGF0YVJlc2V0KGFuY0RhdGEpOwoKICAgIHJldHVybiBBQUNfREVDX09LOwogIH0KCiAgcmV0dXJuIEFBQ19ERUNfQU5DX0RBVEFfRVJST1I7Cn0KCi8qIQogIFxicmllZiBHZXQgb25lIGFuY2lsbGFyeSBkYXRhIGVsZW1lbnQKCiAgXGFuY0RhdGEgUG9pbnRlciB0byBhbmNpbGxhcnkgZGF0YSBzdHJ1Y3R1cmUKICBcaW5kZXggSW5kZXggb2YgdGhlIGFuYyBkYXRhIGVsZW1lbnQgdG8gZ2V0CiAgXHB0ciBQb2ludGVyIHRvIGEgYnVmZmVyIHJlY2VpdmluZyBhIHBvaW50ZXIgdG8gdGhlIHJlcXVlc3RlZCBhbmMgZGF0YSBlbGVtZW50CiAgXHNpemUgUG9pbnRlciB0byBhIGJ1ZmZlciByZWNlaXZpbmcgdGhlIGxlbmd0aCBvZiB0aGUgcmVxdWVzdGVkIGFuYyBkYXRhIGVsZW1lbnQgaW4gYnl0ZXMKCiAgXHJldHVybiAgRXJyb3IgY29kZQoqLwpBQUNfREVDT0RFUl9FUlJPUiBDQWFjRGVjb2Rlcl9BbmNEYXRhR2V0KENBbmNEYXRhICphbmNEYXRhLCBpbnQgaW5kZXgsIHVuc2lnbmVkIGNoYXIgKipwdHIsIGludCAqc2l6ZSkKewogIEFBQ19ERUNPREVSX0VSUk9SIGVycm9yID0gQUFDX0RFQ19PSzsKCiAgKnB0ciAgPSBOVUxMOwogICpzaXplID0gMDsKCiAgaWYgKGluZGV4ID49IDAgJiYgaW5kZXggPCA4ICYmIGluZGV4IDwgYW5jRGF0YS0+bnJFbGVtZW50cykKICB7CiAgICAqcHRyICA9ICZhbmNEYXRhLT5idWZmZXJbYW5jRGF0YS0+b2Zmc2V0W2luZGV4XV07CiAgICAqc2l6ZSA9IGFuY0RhdGEtPm9mZnNldFtpbmRleCsxXSAtIGFuY0RhdGEtPm9mZnNldFtpbmRleF07CiAgfQoKICByZXR1cm4gZXJyb3I7Cn0KCgovKiEKICBcYnJpZWYgUGFyc2UgYW5jaWxsYXJ5IGRhdGEKCiAgXGFuY0RhdGEgUG9pbnRlciB0byBhbmNpbGxhcnkgZGF0YSBzdHJ1Y3R1cmUKICBcaEJzIEhhbmRsZSB0byBGREsgYml0c3RyZWFtCiAgXGFuY0J5dGVzIExlbmd0aCBvZiBhbmNpbGxhcnkgZGF0YSB0byByZWFkIGZyb20gdGhlIGJpdHN0cmVhbQoKICBccmV0dXJuICBFcnJvciBjb2RlCiovCnN0YXRpYwpBQUNfREVDT0RFUl9FUlJPUiBDQWFjRGVjb2Rlcl9BbmNEYXRhUGFyc2UgKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDQW5jRGF0YSAqYW5jRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gaEJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnQgYW5jQnl0ZXMgKQp7CiAgQUFDX0RFQ09ERVJfRVJST1IgZXJyb3IgPSBBQUNfREVDX09LOwogIGludCByZWFkQnl0ZXMgPSAwOwoKICBpZiAoYW5jRGF0YS0+YnVmZmVyICE9IE5VTEwpCiAgewogICAgaWYgKGFuY0J5dGVzID4gMCkgewogICAgICAvKiB3cml0ZSBhbmNpbGxhcnkgZGF0YSB0byBleHRlcm5hbCBidWZmZXIgKi8KICAgICAgaW50IG9mZnNldCA9IGFuY0RhdGEtPm9mZnNldFthbmNEYXRhLT5uckVsZW1lbnRzXTsKCiAgICAgIGlmICgob2Zmc2V0ICsgYW5jQnl0ZXMpID4gYW5jRGF0YS0+YnVmZmVyU2l6ZSkKICAgICAgewogICAgICAgIGVycm9yID0gQUFDX0RFQ19UT09fU01BTExfQU5DX0JVRkZFUjsKICAgICAgfQogICAgICBlbHNlIGlmIChhbmNEYXRhLT5uckVsZW1lbnRzID49IDgtMSkKICAgICAgewogICAgICAgIGVycm9yID0gQUFDX0RFQ19UT09fTUFOWV9BTkNfRUxFTUVOVFM7CiAgICAgIH0KICAgICAgZWxzZQogICAgICB7CiAgICAgICAgaW50IGk7CgogICAgICAgIGZvciAoaSA9IDA7IGkgPCBhbmNCeXRlczsgaSsrKSB7CiAgICAgICAgICBhbmNEYXRhLT5idWZmZXJbaStvZmZzZXRdID0gRkRLcmVhZEJpdHMoaEJzLCA4KTsKICAgICAgICAgIHJlYWRCeXRlcysrOwogICAgICAgIH0KCiAgICAgICAgYW5jRGF0YS0+bnJFbGVtZW50cysrOwogICAgICAgIGFuY0RhdGEtPm9mZnNldFthbmNEYXRhLT5uckVsZW1lbnRzXSA9IGFuY0J5dGVzICsgYW5jRGF0YS0+b2Zmc2V0W2FuY0RhdGEtPm5yRWxlbWVudHMtMV07CiAgICAgIH0KICAgIH0KICB9CgogIHJlYWRCeXRlcyA9IGFuY0J5dGVzIC0gcmVhZEJ5dGVzOwoKICBpZiAocmVhZEJ5dGVzID4gMCkgewogICAgLyogc2tpcCBkYXRhICovCiAgICBGREtwdXNoRm9yKGhCcywgcmVhZEJ5dGVzPDwzKTsKICB9CgogIHJldHVybiBlcnJvcjsKfQoKLyohCiAgXGJyaWVmIFJlYWQgU3RyZWFtIERhdGEgRWxlbWVudAoKICBcYnMgQml0c3RyZWFtIEhhbmRsZQoKICBccmV0dXJuICBFcnJvciBjb2RlCiovCnN0YXRpYyBBQUNfREVDT0RFUl9FUlJPUiBDRGF0YVN0cmVhbUVsZW1lbnRfUmVhZCAoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX0FBQ0RFQ09ERVIgICAgc2VsZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBicywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVQ0hBUiAgICAqZWxlbWVudEluc3RhbmNlVGFnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgICAgICBhbGlnbm1lbnRBbmNob3IgKQp7CiAgSEFORExFX1RSQU5TUE9SVERFQyAgcFRwOwogIENBbmNEYXRhICphbmNEYXRhOwogIEFBQ19ERUNPREVSX0VSUk9SIGVycm9yID0gQUFDX0RFQ19PSzsKICBVSU5UIGRhdGFTdGFydCwgZHNlQml0czsKICBpbnQgZGF0YUJ5dGVBbGlnbkZsYWcsIGNvdW50OwoKICBGREtfQVNTRVJUKHNlbGYgIT0gTlVMTCk7CgogIGFuY0RhdGEgPSAmc2VsZi0+YW5jRGF0YTsKICBwVHAgPSBzZWxmLT5oSW5wdXQ7CgogIGludCBjcmNSZWcgPSB0cmFuc3BvcnREZWNfQ3JjU3RhcnRSZWcocFRwLCAwKTsKCiAgLyogRWxlbWVudCBJbnN0YW5jZSBUYWcgKi8KICAqZWxlbWVudEluc3RhbmNlVGFnID0gRkRLcmVhZEJpdHMoYnMsNCk7CiAgLyogRGF0YSBCeXRlIEFsaWduIEZsYWcgKi8KICBkYXRhQnl0ZUFsaWduRmxhZyA9IEZES3JlYWRCaXRzKGJzLDEpOwoKICBjb3VudCA9IEZES3JlYWRCaXRzKGJzLDgpOwoKICBpZiAoY291bnQgPT0gMjU1KSB7CiAgICBjb3VudCArPSBGREtyZWFkQml0cyhicyw4KTsgLyogRXNjQ291bnQgKi8KICB9CiAgZHNlQml0cyA9IGNvdW50Kjg7CgogIGlmIChkYXRhQnl0ZUFsaWduRmxhZykgewogICAgRkRLYnl0ZUFsaWduKGJzLCBhbGlnbm1lbnRBbmNob3IpOwogIH0KCiAgZGF0YVN0YXJ0ID0gRkRLZ2V0VmFsaWRCaXRzKGJzKTsKCiAgZXJyb3IgPSBDQWFjRGVjb2Rlcl9BbmNEYXRhUGFyc2UoYW5jRGF0YSwgYnMsIGNvdW50KTsKICB0cmFuc3BvcnREZWNfQ3JjRW5kUmVnKHBUcCwgY3JjUmVnKTsKCiAgewogICAgLyogTW92ZSB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBkYXRhIGp1bmsgKi8KICAgIEZES3B1c2hCYWNrKGJzLCBkYXRhU3RhcnQtRkRLZ2V0VmFsaWRCaXRzKGJzKSk7CgogICAgLyogUmVhZCBBbmMgZGF0YSBpZiBhdmFpbGFibGUgKi8KICAgIGFhY0RlY29kZXJfZHJjTWFya1BheWxvYWQoIHNlbGYtPmhEcmNJbmZvLCBicywgRFZCX0RSQ19BTkNfREFUQSApOwogIH0KCiAgewogICAgUENNRE1YX0VSUk9SIGRteEVyciA9IFBDTURNWF9PSzsKCiAgICAvKiBNb3ZlIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGRhdGEganVuayAqLwogICAgRkRLcHVzaEJhY2soYnMsIGRhdGFTdGFydC1GREtnZXRWYWxpZEJpdHMoYnMpKTsKCiAgICAvKiBSZWFkIERNWCBtZXRhLWRhdGEgKi8KICAgIGRteEVyciA9IHBjbURteF9QYXJzZSAoCiAgICAgICAgICAgICAgICAgICAgIHNlbGYtPmhQY21VdGlscywKICAgICAgICAgICAgICAgICAgICAgYnMsCiAgICAgICAgICAgICAgICAgICAgIGRzZUJpdHMsCiAgICAgICAgICAgICAgICAgICAgIDAgLyogbm90IG1wZWcyICovICk7CiAgICB9CgogIC8qIE1vdmUgdG8gdGhlIHZlcnkgZW5kIG9mIHRoZSBlbGVtZW50LiAqLwogIEZES3B1c2hCaURpcmVjdGlvbmFsKGJzLCBGREtnZXRWYWxpZEJpdHMoYnMpLWRhdGFTdGFydCtkc2VCaXRzKTsKCiAgcmV0dXJuIGVycm9yOwp9CgojaWZkZWYgVFBfUENFX0VOQUJMRQovKiEKICBcYnJpZWYgUmVhZCBQcm9ncmFtIENvbmZpZyBFbGVtZW50CgogIFxicyBCaXRzdHJlYW0gSGFuZGxlCiAgXHBUcCBUcmFuc3BvcnQgZGVjb2RlciBoYW5kbGUgZm9yIENSQyBoYW5kbGluZwogIFxwY2UgUG9pbnRlciB0byBQQ0UgYnVmZmVyCiAgXGNoYW5uZWxDb25maWcgQ3VycmVudCBjaGFubmVsIGNvbmZpZ3VyYXRpb24KICBcYWxpZ25BbmNob3IgQW5jaG9yIGZvciBieXRlIGFsaWdubWVudAoKICBccmV0dXJuICBQQ0Ugc3RhdHVzICgtMTogZmFpbCwgMDogbm8gbmV3IFBDRSwgMTogUENFIHVwZGF0ZWQsIDI6IFBDRSB1cGRhdGVkIG5lZWQgcmUtY29uZmlnKS4KKi8Kc3RhdGljIGludCBDUHJvZ3JhbUNvbmZpZ0VsZW1lbnRfUmVhZCAoCiAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBicywKICAgIEhBTkRMRV9UUkFOU1BPUlRERUMgIHBUcCwKICAgIENQcm9ncmFtQ29uZmlnICAgICAgKnBjZSwKICAgIGNvbnN0IFVJTlQgICAgICAgICAgIGNoYW5uZWxDb25maWcsCiAgICBjb25zdCBVSU5UICAgICAgICAgICBhbGlnbkFuY2hvciApCnsKICBpbnQgcGNlU3RhdHVzID0gMDsKICBpbnQgY3JjUmVnOwoKICAvKiByZWFkIFBDRSB0byB0ZW1wb3JhbCBidWZmZXIgZmlyc3QgKi8KICBDX0FMTE9DX1NDUkFUQ0hfU1RBUlQodG1wUGNlLCBDUHJvZ3JhbUNvbmZpZywgMSk7CgogIENQcm9ncmFtQ29uZmlnX0luaXQodG1wUGNlKTsKICBDUHJvZ3JhbUNvbmZpZ19SZXNldCh0bXBQY2UpOwoKICBjcmNSZWcgPSB0cmFuc3BvcnREZWNfQ3JjU3RhcnRSZWcocFRwLCAwKTsKCiAgQ1Byb2dyYW1Db25maWdfUmVhZCh0bXBQY2UsIGJzLCBhbGlnbkFuY2hvcik7CgogIHRyYW5zcG9ydERlY19DcmNFbmRSZWcocFRwLCBjcmNSZWcpOwoKICBpZiAoICBDUHJvZ3JhbUNvbmZpZ19Jc1ZhbGlkKHRtcFBjZSkKICAgICYmICh0bXBQY2UtPlByb2ZpbGUgPT0gMSkgKQogIHsKICAgIGlmICggIXBjZS0+aXNWYWxpZCAmJiAoY2hhbm5lbENvbmZpZyA+IDApICkgewogICAgICAvKiBDcmVhdGUgYSBzdGFuZGFyZCBjaGFubmVsIGNvbmZpZyBQQ0UgdG8gY29tcGFyZSB3aXRoICovCiAgICAgIENQcm9ncmFtQ29uZmlnX0dldERlZmF1bHQoIHBjZSwgY2hhbm5lbENvbmZpZyApOwogICAgfQoKICAgIGlmIChwY2UtPmlzVmFsaWQpIHsKICAgICAgLyogQ29tcGFyZSB0aGUgbmV3IGFuZCB0aGUgb2xkIFBDRSAodGFncyBpZ25vcmVkKSAqLwogICAgICBzd2l0Y2ggKCBDUHJvZ3JhbUNvbmZpZ19Db21wYXJlKCBwY2UsIHRtcFBjZSApICkKICAgICAgewogICAgICBjYXNlIDE6ICAvKiBDaGFubmVsIGNvbmZpZ3VyYXRpb24gbm90IGNoYW5nZWQuIEp1c3QgbmV3IG1ldGFkYXRhLiAqLwogICAgICAgIEZES21lbWNweShwY2UsIHRtcFBjZSwgc2l6ZW9mKENQcm9ncmFtQ29uZmlnKSk7ICAgIC8qIFN0b3JlIHRoZSBjb21wbGV0ZSBQQ0UgKi8KICAgICAgICBwY2VTdGF0dXMgPSAxOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBOZXcgUENFIGJ1dCBubyBjaGFuZ2Ugb2YgY29uZmlnICovCiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgMjogIC8qIFRoZSBudW1iZXIgb2YgY2hhbm5lbHMgYXJlIGlkZW50aWNhbCBidXQgbm90IHRoZSBjb25maWcgKi8KICAgICAgICBpZiAoY2hhbm5lbENvbmZpZyA9PSAwKSB7CiAgICAgICAgICBGREttZW1jcHkocGNlLCB0bXBQY2UsIHNpemVvZihDUHJvZ3JhbUNvbmZpZykpOyAgLyogU3RvcmUgdGhlIGNvbXBsZXRlIFBDRSAqLwogICAgICAgICAgcGNlU3RhdHVzID0gMjsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIERlY29kZXIgbmVlZHMgcmUtY29uZmlndXJhdGlvbiAqLwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgY2FzZSAtMTogIC8qIFRoZSBjaGFubmVsIGNvbmZpZ3VyYXRpb24gaXMgY29tcGxldGVseSBkaWZmZXJlbnQgKi8KICAgICAgICBwY2VTdGF0dXMgPSAtMTsgIC8qIE5vdCBzdXBwb3J0ZWQhICovCiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgMDogIC8qIE5vdGhpbmcgdG8gZG8gYmVjYXVzZSBQQ0UgbWF0Y2hlcyB0aGUgb2xkIG9uZSBleGFjdGx5LiAqLwogICAgICBkZWZhdWx0OgogICAgICAgIC8qIHBjZVN0YXR1cyA9IDA7ICovCiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICB9CgogIENfQUxMT0NfU0NSQVRDSF9FTkQodG1wUGNlLCBDUHJvZ3JhbUNvbmZpZywgMSk7CgogIHJldHVybiBwY2VTdGF0dXM7Cn0KI2VuZGlmIC8qIFRQX1BDRV9FTkFCTEUgKi8KCi8qIQogIFxicmllZiBQYXJzZSBFeHRlbnNpb24gUGF5bG9hZAoKICBcc2VsZiBIYW5kbGUgb2YgQUFDIGRlY29kZXIKICBcY291bnQgUG9pbnRlciB0byBiaXQgY291bnRlci4KICBccHJldmlvdXNfZWxlbWVudCBJRCBvZiBwcmV2aW91cyBlbGVtZW50IChyZXF1aXJlZCBieSBzb21lIGV4dGVuc2lvbiBwYXlsb2FkcykKCiAgXHJldHVybiAgRXJyb3IgY29kZQoqLwpzdGF0aWMKQUFDX0RFQ09ERVJfRVJST1IgQ0FhY0RlY29kZXJfRXh0UGF5bG9hZFBhcnNlIChIQU5ETEVfQUFDREVDT0RFUiBzZWxmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGhCcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgKmNvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1QNF9FTEVNRU5UX0lEIHByZXZpb3VzX2VsZW1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGVsSW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGZJc0ZpbGxFbGVtZW50KQp7CiAgQUFDX0RFQ09ERVJfRVJST1IgZXJyb3IgPSBBQUNfREVDX09LOwogIEVYVF9QQVlMT0FEX1RZUEUgZXh0ZW5zaW9uX3R5cGU7CiAgaW50IGJ5dGVzID0gKCpjb3VudCkgPj4gMzsKICBpbnQgY3JjRmxhZyA9IDA7CgogIGlmICgqY291bnQgPCA0KSB7CiAgICByZXR1cm4gQUFDX0RFQ19QQVJTRV9FUlJPUjsKICB9IGVsc2UgaWYgKChJTlQpRkRLZ2V0VmFsaWRCaXRzKGhCcykgPCAqY291bnQpIHsKICAgIHJldHVybiBBQUNfREVDX0RFQ09ERV9GUkFNRV9FUlJPUjsKICB9CgogIGV4dGVuc2lvbl90eXBlID0gKEVYVF9QQVlMT0FEX1RZUEUpIEZES3JlYWRCaXRzKGhCcywgNCk7ICAgIC8qIGJzX2V4dGVuc2lvbl90eXBlICovCiAgKmNvdW50IC09IDQ7CgogIHN3aXRjaCAoZXh0ZW5zaW9uX3R5cGUpCiAgewogIGNhc2UgRVhUX0RZTkFNSUNfUkFOR0U6CiAgICB7CiAgICAgIElOVCByZWFkQml0cyA9IGFhY0RlY29kZXJfZHJjTWFya1BheWxvYWQoIHNlbGYtPmhEcmNJbmZvLCBoQnMsIE1QRUdfRFJDX0VYVF9EQVRBICk7CgogICAgICBpZiAocmVhZEJpdHMgPiAqY291bnQpCiAgICAgIHsgLyogUmVhZCB0b28gbXVjaC4gU29tZXRoaW5nIHdlbnQgd3JvbmchICovCiAgICAgICAgZXJyb3IgPSBBQUNfREVDX1BBUlNFX0VSUk9SOwogICAgICB9CiAgICAgICpjb3VudCAtPSByZWFkQml0czsKICAgIH0KICAgIGJyZWFrOwoKCiAgY2FzZSBFWFRfU0JSX0RBVEFfQ1JDOgogICAgY3JjRmxhZyA9IDE7CiAgY2FzZSBFWFRfU0JSX0RBVEE6CiAgICBpZiAoSVNfQ0hBTk5FTF9FTEVNRU5UKHByZXZpb3VzX2VsZW1lbnQpKSB7CiAgICAgIFNCUl9FUlJPUiBzYnJFcnJvcjsKCiAgICAgIENBYWNEZWNvZGVyX1N5bmNRbWZNb2RlKHNlbGYpOwoKICAgICAgc2JyRXJyb3IgPSBzYnJEZWNvZGVyX0luaXRFbGVtZW50KAogICAgICAgICAgICAgIHNlbGYtPmhTYnJEZWNvZGVyLAogICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlUmF0ZSwKICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmV4dFNhbXBsaW5nUmF0ZSwKICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZXNQZXJGcmFtZSwKICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmFvdCwKICAgICAgICAgICAgICBwcmV2aW91c19lbGVtZW50LAogICAgICAgICAgICAgIGVsSW5kZXgKICAgICAgICAgICAgICApOwoKICAgICAgaWYgKHNickVycm9yID09IFNCUkRFQ19PSykgewogICAgICAgIHNickVycm9yID0gc2JyRGVjb2Rlcl9QYXJzZSAoCiAgICAgICAgICAgICAgICBzZWxmLT5oU2JyRGVjb2RlciwKICAgICAgICAgICAgICAgIGhCcywKICAgICAgICAgICAgICAgIGNvdW50LAogICAgICAgICAgICAgICAqY291bnQsCiAgICAgICAgICAgICAgICBjcmNGbGFnLAogICAgICAgICAgICAgICAgcHJldmlvdXNfZWxlbWVudCwKICAgICAgICAgICAgICAgIGVsSW5kZXgsCiAgICAgICAgICAgICAgICBzZWxmLT5mbGFncyAmIEFDX0lOREVQICk7CiAgICAgICAgLyogRW5hYmxlIFNCUiBmb3IgaW1wbGljaXQgU0JSIHNpZ25hbGxpbmcgYnV0IG9ubHkgaWYgbm8gc2V2ZXJlIGVycm9yIGhhcHBlbmQuICovCiAgICAgICAgaWYgKCAoc2JyRXJyb3IgPT0gU0JSREVDX09LKQogICAgICAgICAgfHwgKHNickVycm9yID09IFNCUkRFQ19QQVJTRV9FUlJPUikgKSB7CiAgICAgICAgICBzZWxmLT5zYnJFbmFibGVkID0gMTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLyogRG8gbm90IHRyeSB0byBhcHBseSBTQlIgYmVjYXVzZSBpbml0aWFsaXppbmcgdGhlIGVsZW1lbnQgZmFpbGVkLiAqLwogICAgICAgIHNlbGYtPnNickVuYWJsZWQgPSAwOwogICAgICB9CiAgICAgIC8qIENpdGF0aW9uIGZyb20gSVNPL0lFQyAxNDQ5Ni0zIGNoYXB0ZXIgNC41LjIuMS41LjIKICAgICAgRmlsbCBlbGVtZW50cyBjb250YWluaW5nIGFuIGV4dGVuc2lvbl9wYXlsb2FkKCkgd2l0aCBhbiBleHRlbnNpb25fdHlwZSBvZiBFWFRfU0JSX0RBVEEKICAgICAgb3IgRVhUX1NCUl9EQVRBX0NSQyBzaGFsbCBub3QgY29udGFpbiBhbnkgb3RoZXIgZXh0ZW5zaW9uX3BheWxvYWQgb2YgYW55IG90aGVyIGV4dGVuc2lvbl90eXBlLgogICAgICAqLwogICAgICBpZiAoZklzRmlsbEVsZW1lbnQpIHsKICAgICAgICBGREtwdXNoQmlEaXJlY3Rpb25hbChoQnMsICpjb3VudCk7CiAgICAgICAgKmNvdW50ID0gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICAvKiBJZiB0aGlzIGlzIG5vdCBhIGZpbGwgZWxlbWVudCB3aXRoIGEga25vd24gbGVuZ3RoLCB3ZSBhcmUgc2NyZXdlZCBhbmQgZnVydGhlciBwYXJzaW5nIG1ha2VzIG5vIHNlbnNlLiAqLwogICAgICAgIGlmIChzYnJFcnJvciAhPSBTQlJERUNfT0spIHsKICAgICAgICAgIHNlbGYtPmZyYW1lT0sgPSAwOwogICAgICAgIH0KICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgZXJyb3IgPSBBQUNfREVDX1BBUlNFX0VSUk9SOwogICAgfQogICAgYnJlYWs7CgogIGNhc2UgRVhUX0ZJTExfREFUQToKICAgIHsKICAgICAgaW50IHRlbXA7CgogICAgICB0ZW1wID0gRkRLcmVhZEJpdHMoaEJzLDQpOwogICAgICBieXRlcy0tOwogICAgICBpZiAodGVtcCAhPSAwKSB7CiAgICAgICAgZXJyb3IgPSBBQUNfREVDX1BBUlNFX0VSUk9SOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIHdoaWxlIChieXRlcyA+IDApIHsKICAgICAgICB0ZW1wID0gRkRLcmVhZEJpdHMoaEJzLDgpOwogICAgICAgIGJ5dGVzLS07CiAgICAgICAgaWYgKHRlbXAgIT0gMHhhNSkgewogICAgICAgICAgZXJyb3IgPSBBQUNfREVDX1BBUlNFX0VSUk9SOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICB9CiAgICAgICpjb3VudCA9IGJ5dGVzPDwzOwogICAgfQogICAgYnJlYWs7CgogIGNhc2UgRVhUX0RBVEFfRUxFTUVOVDoKICAgIHsKICAgICAgaW50IGRhdGFFbGVtZW50VmVyc2lvbjsKCiAgICAgIGRhdGFFbGVtZW50VmVyc2lvbiA9IEZES3JlYWRCaXRzKGhCcyw0KTsKICAgICAgKmNvdW50IC09IDQ7CiAgICAgIGlmIChkYXRhRWxlbWVudFZlcnNpb24gPT0gMCkgLyogQU5DX0RBVEEgKi8KICAgICAgewogICAgICAgIGludCB0ZW1wLCBkYXRhRWxlbWVudExlbmd0aCA9IDA7CiAgICAgICAgZG8gewogICAgICAgICAgdGVtcCA9IEZES3JlYWRCaXRzKGhCcyw4KTsKICAgICAgICAgICpjb3VudCAtPSA4OwogICAgICAgICAgZGF0YUVsZW1lbnRMZW5ndGggKz0gdGVtcDsKICAgICAgICB9IHdoaWxlICh0ZW1wID09IDI1NSApOwoKICAgICAgICBDQWFjRGVjb2Rlcl9BbmNEYXRhUGFyc2UoJnNlbGYtPmFuY0RhdGEsIGhCcywgZGF0YUVsZW1lbnRMZW5ndGgpOwogICAgICAgICpjb3VudCAtPSAoZGF0YUVsZW1lbnRMZW5ndGg8PDMpOwogICAgICB9IGVsc2UgewogICAgICAgIC8qIGFsaWduID0gMCAqLwogICAgICAgIGVycm9yID0gQUFDX0RFQ19QQVJTRV9FUlJPUjsKICAgICAgICBnb3RvIGJhaWw7CiAgICAgIH0KICAgIH0KICAgIGJyZWFrOwoKICBjYXNlIEVYVF9EQVRBX0xFTkdUSDoKICAgIGlmICggIWZJc0ZpbGxFbGVtZW50ICAgICAgICAgIC8qIE1ha2VzIG5vIHNlbnMgdG8gaGF2ZSBhbiBhZGRpdGlvbmFsIGxlbmd0aCBpbiBhIGZpbGwgLi4uICAgKi8KICAgICAgJiYgKHNlbGYtPmZsYWdzICYgQUNfRVIpICkgIC8qIC4uLiBlbGVtZW50IGJlY2F1c2UgdGhpcyBleHRlbnNpb24gcGF5bG9hZCB0eXBlIHdhcyAuLi4gICAgKi8KICAgIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIC4uLiBjcmVhdGVkIHRvIGNpcmN1bXZlbnQgdGhlIG1pc3NpbmcgbGVuZ3RoIGluIEVSLVN5bnRheC4gKi8KICAgICAgaW50IGJpdENudCwgbGVuID0gRkRLcmVhZEJpdHMoaEJzLCA0KTsKICAgICAgKmNvdW50IC09IDQ7CgogICAgICBpZiAobGVuID09IDE1KSB7CiAgICAgICAgaW50IGFkZF9sZW4gPSBGREtyZWFkQml0cyhoQnMsIDgpOwogICAgICAgICpjb3VudCAtPSA4OwogICAgICAgIGxlbiArPSBhZGRfbGVuOwoKICAgICAgICBpZiAoYWRkX2xlbiA9PSAyNTUpIHsKICAgICAgICAgIGxlbiArPSBGREtyZWFkQml0cyhoQnMsIDE2KTsKICAgICAgICAgICpjb3VudCAtPSAxNjsKICAgICAgICB9CiAgICAgIH0KICAgICAgbGVuIDw8PSAzOwogICAgICBiaXRDbnQgPSBsZW47CgogICAgICBpZiAoIChFWFRfUEFZTE9BRF9UWVBFKUZES3JlYWRCaXRzKGhCcywgNCkgPT0gRVhUX0RBVEFfTEVOR1RIICkgewogICAgICAgIC8qIENoZWNrIE5PVEUgMjogVGhlIGV4dGVuc2lvbl9wYXlsb2FkKCkgaW5jbHVkZWQgaGVyZSBtdXN0CiAgICAgICAgICAgICAgICAgICAgICAgICBub3QgaGF2ZSBleHRlbnNpb25fdHlwZSA9PSBFWFRfREFUQV9MRU5HVEguICovCiAgICAgICAgZXJyb3IgPSBBQUNfREVDX1BBUlNFX0VSUk9SOwogICAgICB9IGVsc2UgewogICAgICAgIC8qIHJld2luZCBhbmQgY2FsbCBteXNlbGYgYWdhaW4uICovCiAgICAgICAgRkRLcHVzaEJhY2soaEJzLCA0KTsKCiAgICAgICAgZXJyb3IgPQogICAgICAgICAgQ0FhY0RlY29kZXJfRXh0UGF5bG9hZFBhcnNlICgKICAgICAgICAgICAgICAgICAgc2VsZiwKICAgICAgICAgICAgICAgICAgaEJzLAogICAgICAgICAgICAgICAgICZiaXRDbnQsCiAgICAgICAgICAgICAgICAgIHByZXZpb3VzX2VsZW1lbnQsCiAgICAgICAgICAgICAgICAgIGVsSW5kZXgsCiAgICAgICAgICAgICAgICAgIDAgKTsKCiAgICAgICAgKmNvdW50IC09IGxlbiAtIGJpdENudDsKICAgICAgfQogICAgICAvKiBOb3RlOiB0aGUgZmFsbCB0aHJvdWdoIGluIGNhc2UgdGhlIGlmIHN0YXRlbWVudCBhYm92ZSBpcyBub3QgdGFrZW4gaXMgaW50ZW50aW9uYWwuICovCiAgICAgIGJyZWFrOwogICAgfQoKICBjYXNlIEVYVF9GSUw6CgogIGRlZmF1bHQ6CiAgICAvKiBhbGlnbiA9IDQgKi8KICAgIEZES3B1c2hGb3IoaEJzLCAqY291bnQpOwogICAgKmNvdW50ID0gMDsKICAgIGJyZWFrOwogIH0KCmJhaWw6CiAgaWYgKCAoZXJyb3IgIT0gQUFDX0RFQ19PSykKICAgICYmIGZJc0ZpbGxFbGVtZW50ICkKICB7IC8qIFNraXAgdGhlIHJlbWFpbmluZyBleHRlbnNpb24gYnl0ZXMgKi8KICAgIEZES3B1c2hCaURpcmVjdGlvbmFsKGhCcywgKmNvdW50KTsKICAgICpjb3VudCA9IDA7CiAgICAvKiBQYXRjaCBlcnJvciBjb2RlIGJlY2F1c2UgZGVjb2RpbmcgY2FuIGdvIG9uLiAqLwogICAgZXJyb3IgPSBBQUNfREVDX09LOwogICAgLyogQmUgc3VyZSB0aGF0IHBhcnNpbmcgZXJyb3JzIGhhdmUgYmVlbiBzdG9yZWQuICovCiAgfQogIHJldHVybiBlcnJvcjsKfQoKLyogIFN0cmVhbSBDb25maWd1cmF0aW9uIGFuZCBJbmZvcm1hdGlvbi4KCiAgICBUaGlzIGNsYXNzIGhvbGRzIGNvbmZpZ3VyYXRpb24gYW5kIGluZm9ybWF0aW9uIGRhdGEgZm9yIGEgc3RyZWFtIHRvIGJlIGRlY29kZWQuIEl0CiAgICBwcm92aWRlcyB0aGUgY2FsbGluZyBhcHBsaWNhdGlvbiBhcyB3ZWxsIGFzIHRoZSBkZWNvZGVyIHdpdGggc3Vic3RhbnRpYWwgaW5mb3JtYXRpb24sCiAgICBlLmcuIHByb2ZpbGUsIHNhbXBsaW5nIHJhdGUsIG51bWJlciBvZiBjaGFubmVscyBmb3VuZCBpbiB0aGUgYml0c3RyZWFtIGV0Yy4KKi8Kc3RhdGljCnZvaWQgQ1N0cmVhbUluZm9Jbml0KENTdHJlYW1JbmZvICpwU3RyZWFtSW5mbykKewogIHBTdHJlYW1JbmZvLT5hYWNTYW1wbGVSYXRlID0gMDsKICBwU3RyZWFtSW5mby0+cHJvZmlsZSA9IC0xOwogIHBTdHJlYW1JbmZvLT5hb3QgPSBBT1RfTk9ORTsKCiAgcFN0cmVhbUluZm8tPmNoYW5uZWxDb25maWcgPSAtMTsKICBwU3RyZWFtSW5mby0+Yml0UmF0ZSA9IDA7CiAgcFN0cmVhbUluZm8tPmFhY1NhbXBsZXNQZXJGcmFtZSA9IDA7CgogIHBTdHJlYW1JbmZvLT5leHRBb3QgID0gQU9UX05PTkU7CiAgcFN0cmVhbUluZm8tPmV4dFNhbXBsaW5nUmF0ZSA9IDA7CgogIHBTdHJlYW1JbmZvLT5mbGFncyA9IDA7CgogIHBTdHJlYW1JbmZvLT5lcENvbmZpZyA9IC0xOyAgIC8qIGRlZmF1bHQgaXMgbm8gRVIgKi8KCiAgcFN0cmVhbUluZm8tPm51bUNoYW5uZWxzID0gMDsKICBwU3RyZWFtSW5mby0+c2FtcGxlUmF0ZSA9IDA7CiAgcFN0cmVhbUluZm8tPmZyYW1lU2l6ZSA9IDA7CgogIHBTdHJlYW1JbmZvLT5vdXRwdXREZWxheSA9IDA7CgogIC8qIERSQyAqLwogIHBTdHJlYW1JbmZvLT5kcmNQcm9nUmVmTGV2ID0gLTE7ICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc2V0IHByb2dyYW0gcmVmZXJlbmNlIGxldmVsIHRvIG5vdCBpbmRpY2F0ZWQgKi8KICBwU3RyZWFtSW5mby0+ZHJjUHJlc01vZGUgPSAtMTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGRlZmF1bHQ6IHByZXNlbnRhdGlvbiBtb2RlIG5vdCBpbmRpY2F0ZWQgKi8KfQoKLyohCiAgXGJyaWVmIEluaXRpYWxpemF0aW9uIG9mIEFhY0RlY29kZXJDaGFubmVsSW5mbwoKICBUaGUgZnVuY3Rpb24gaW5pdGlhbGl6ZXMgdGhlIHBvaW50ZXJzIHRvIEFhY0RlY29kZXJDaGFubmVsSW5mbyBmb3IgZWFjaCBjaGFubmVsLAogIHNldCB0aGUgc3RhcnQgdmFsdWVzIGZvciB3aW5kb3cgc2hhcGUgYW5kIHdpbmRvdyBzZXF1ZW5jZSBvZiBvdmVybGFwJmFkZCB0byB6ZXJvLAogIHNldCB0aGUgb3ZlcmxhcCBidWZmZXIgdG8gemVybyBhbmQgaW5pdGlhbGl6ZXMgdGhlIHBvaW50ZXJzIHRvIHRoZSB3aW5kb3cgY29lZmZpY2llbnRzLgogIFxwYXJhbSBic0Zvcm1hdCBpcyB0aGUgZm9ybWF0IG9mIHRoZSBBQUMgYml0c3RyZWFtCgogIFxyZXR1cm4gIEFBQ0RFQ09ERVIgaW5zdGFuY2UKKi8KTElOS1NQRUNfQ1BQIEhBTkRMRV9BQUNERUNPREVSIENBYWNEZWNvZGVyX09wZW4oVFJBTlNQT1JUX1RZUEUgYnNGb3JtYXQpICAgIC8qITwgYml0c3RyZWFtIGZvcm1hdCAoYWRpZixhZHRzLGxvYXMsLi4uKS4gKi8KewogIEhBTkRMRV9BQUNERUNPREVSIHNlbGY7CgogIHNlbGYgPSBHZXRBYWNEZWNvZGVyKCk7CiAgaWYgKHNlbGYgPT0gTlVMTCkgewogICAgZ290byBiYWlsOwogIH0KCiAgLyogQXNzaWduIGNoYW5uZWwgbWFwcGluZyBpbmZvIGFycmF5cyAoZG9pbmcgc28gcmVtb3ZlcyBkZXBlbmRlbmN5IG9mIHNldHRpbmdzIGhlYWRlciBpbiBBUEkgaGVhZGVyKS4gKi8KICBzZWxmLT5zdHJlYW1JbmZvLnBDaGFubmVsSW5kaWNlcyA9IHNlbGYtPmNoYW5uZWxJbmRpY2VzOwogIHNlbGYtPnN0cmVhbUluZm8ucENoYW5uZWxUeXBlID0gc2VsZi0+Y2hhbm5lbFR5cGU7CgogIC8qIHNldCBkZWZhdWx0IG91dHB1dCBtb2RlICovCiAgc2VsZi0+b3V0cHV0SW50ZXJsZWF2ZWQgPSAxOyAgLyogaW50ZXJsZWF2ZWQgKi8KCiAgLyogaW5pdGlhbGl6ZSBhbmMgZGF0YSAqLwogIENBYWNEZWNvZGVyX0FuY0RhdGFJbml0KCZzZWxmLT5hbmNEYXRhLCBOVUxMLCAwKTsKCiAgLyogaW5pdGlhbGl6ZSBzdHJlYW0gaW5mbyAqLwogIENTdHJlYW1JbmZvSW5pdCgmc2VsZi0+c3RyZWFtSW5mbyk7CgogIC8qIGluaXRpYWxpemUgZXJyb3IgY29uY2VhbG1lbnQgY29tbW9uIGRhdGEgKi8KICBDQ29uY2VhbG1lbnRfSW5pdENvbW1vbkRhdGEoJnNlbGYtPmNvbmNlYWxDb21tb25EYXRhKTsKCiAgc2VsZi0+aERyY0luZm8gPSBHZXREcmNJbmZvKCk7CiAgaWYgKHNlbGYtPmhEcmNJbmZvID09IE5VTEwpIHsKICAgIGdvdG8gYmFpbDsKICB9CiAgLyogSW5pdCBjb21tb24gRFJDIHN0cnVjdHVyZSAqLwogIGFhY0RlY29kZXJfZHJjSW5pdCggc2VsZi0+aERyY0luZm8gKTsKICAvKiBTZXQgZGVmYXVsdCBmcmFtZSBkZWxheSAqLwogIGFhY0RlY29kZXJfZHJjU2V0UGFyYW0gKAogICAgICAgICAgc2VsZi0+aERyY0luZm8sCiAgICAgICAgICBEUkNfQlNfREVMQVksCiAgICAgICAgICBDQ29uY2VhbG1lbnRfR2V0RGVsYXkoJnNlbGYtPmNvbmNlYWxDb21tb25EYXRhKQogICAgICAgICk7CgoKICBzZWxmLT5hYWNDb21tb25EYXRhLndvcmtCdWZmZXJDb3JlMSA9IEdldFdvcmtCdWZmZXJDb3JlMSgpOwogIHNlbGYtPmFhY0NvbW1vbkRhdGEud29ya0J1ZmZlckNvcmUyID0gR2V0V29ya0J1ZmZlckNvcmUyKCk7CiAgaWYgKHNlbGYtPmFhY0NvbW1vbkRhdGEud29ya0J1ZmZlckNvcmUxID09IE5VTEwKICAgIHx8c2VsZi0+YWFjQ29tbW9uRGF0YS53b3JrQnVmZmVyQ29yZTIgPT0gTlVMTCApCiAgICBnb3RvIGJhaWw7CgogIHJldHVybiBzZWxmOwoKYmFpbDoKICBDQWFjRGVjb2Rlcl9DbG9zZSggc2VsZiApOwoKICByZXR1cm4gTlVMTDsKfQoKLyogRGVzdHJveSBhYWMgZGVjb2RlciAqLwpMSU5LU1BFQ19DUFAgdm9pZCBDQWFjRGVjb2Rlcl9DbG9zZShIQU5ETEVfQUFDREVDT0RFUiBzZWxmKQp7CiAgaW50IGNoOwoKICBpZiAoc2VsZiA9PSBOVUxMKQogICAgcmV0dXJuOwoKICBmb3IgKGNoPTA7IGNoPCg4KTsgY2grKykgewogICAgaWYgKHNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bY2hdICE9IE5VTEwpIHsKICAgICAgaWYgKHNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bY2hdLT5wT3ZlcmxhcEJ1ZmZlciAhPSBOVUxMKSB7CiAgICAgICAgRnJlZU92ZXJsYXBCdWZmZXIgKCZzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NoXS0+cE92ZXJsYXBCdWZmZXIpOwogICAgICB9CiAgICAgIGlmIChzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NoXSAhPSBOVUxMKSB7CiAgICAgICAgRnJlZUFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mbyAoJnNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bY2hdKTsKICAgICAgfQogICAgfQogICAgaWYgKHNlbGYtPnBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bY2hdICE9IE5VTEwpIHsKICAgICAgRnJlZUFhY0RlY29kZXJDaGFubmVsSW5mbyAoJnNlbGYtPnBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bY2hdKTsKICAgIH0KICB9CgogIHNlbGYtPmFhY0NoYW5uZWxzID0gMDsKCiAgaWYgKHNlbGYtPmhEcmNJbmZvKSB7CiAgICBGcmVlRHJjSW5mbygmc2VsZi0+aERyY0luZm8pOwogIH0KCiAgaWYgKHNlbGYtPmFhY0NvbW1vbkRhdGEud29ya0J1ZmZlckNvcmUxICE9IE5VTEwpIHsKICAgIEZyZWVXb3JrQnVmZmVyQ29yZTEgKCZzZWxmLT5hYWNDb21tb25EYXRhLndvcmtCdWZmZXJDb3JlMSk7CiAgfQogIGlmIChzZWxmLT5hYWNDb21tb25EYXRhLndvcmtCdWZmZXJDb3JlMiAhPSBOVUxMKSB7CiAgICBGcmVlV29ya0J1ZmZlckNvcmUyICgmc2VsZi0+YWFjQ29tbW9uRGF0YS53b3JrQnVmZmVyQ29yZTIpOwogIH0KCiAgRnJlZUFhY0RlY29kZXIgKCAmc2VsZik7Cn0KCgovKiEKICBcYnJpZWYgSW5pdGlhbGl6YXRpb24gb2YgZGVjb2RlciBpbnN0YW5jZQoKICBUaGUgZnVuY3Rpb24gaW5pdGlhbGl6ZXMgdGhlIGRlY29kZXIuCgogIFxyZXR1cm4gIGVycm9yIHN0YXR1czogMCBmb3Igc3VjY2VzcywgPD4wIGZvciB1bnN1cHBvcnRlZCBjb25maWd1cmF0aW9ucwoqLwpMSU5LU1BFQ19DUFAgQUFDX0RFQ09ERVJfRVJST1IgQ0FhY0RlY29kZXJfSW5pdChIQU5ETEVfQUFDREVDT0RFUiBzZWxmLCBjb25zdCBDU0F1ZGlvU3BlY2lmaWNDb25maWcgKmFzYykKewogIEFBQ19ERUNPREVSX0VSUk9SIGVyciA9IEFBQ19ERUNfT0s7CiAgSU5UIGFzY0NoYW5uZWxzLCBjaCwgYXNjQ2hhbmdlZCA9IDA7CgogIGlmICghc2VsZikKICAgIHJldHVybiBBQUNfREVDX0lOVkFMSURfSEFORExFOwoKICAvLyBzZXQgcHJvZmlsZSBhbmQgY2hlY2sgZm9yIHN1cHBvcnRlZCBhb3QKICAvLyBsZWF2ZSBwcm9maWxlIG9uIGRlZmF1bHQgKD0tMSkgZm9yIGFsbCBvdGhlciBzdXBwb3J0ZWQgTVBFRy00IGFvdCdzIGV4Y2VwdCBhb3Q9MiAoPUFBQy1MQykKICBzd2l0Y2ggKGFzYy0+bV9hb3QpIHsKICBjYXNlIEFPVF9BQUNfTEM6CiAgICBzZWxmLT5zdHJlYW1JbmZvLnByb2ZpbGUgPSAxOwoKICBjYXNlIEFPVF9FUl9BQUNfU0NBTDoKICAgIGlmIChhc2MtPm1fc2MubV9nYVNwZWNpZmljQ29uZmlnLm1fbGF5ZXIgPiAwKSB7CiAgICAgIC8qIGFhY19zY2FsYWJsZV9leHRlbnNpb25fZWxlbWVudCgpIGN1cnJlbnRseSBub3Qgc3VwcG9ydGVkLiAqLwogICAgICByZXR1cm4gQUFDX0RFQ19VTlNVUFBPUlRFRF9GT1JNQVQ7CiAgICB9CgogIGNhc2UgQU9UX1NCUjoKICBjYXNlIEFPVF9QUzoKICBjYXNlIEFPVF9FUl9BQUNfTEQ6CiAgY2FzZSBBT1RfRVJfQUFDX0VMRDoKICBjYXNlIEFPVF9EUk1fQUFDOgogICAgYnJlYWs7CgogIGRlZmF1bHQ6CiAgICByZXR1cm4gQUFDX0RFQ19VTlNVUFBPUlRFRF9BT1Q7CiAgfQoKICBDUHJvZ3JhbUNvbmZpZ19Jbml0KCZzZWxmLT5wY2UpOwoKICAvKiBzZXQgY2hhbm5lbHMgKi8KICBzd2l0Y2ggKGFzYy0+bV9jaGFubmVsQ29uZmlndXJhdGlvbikgewogIGNhc2UgMDoKI2lmZGVmIFRQX1BDRV9FTkFCTEUKICAgIC8qIGdldCBjaGFubmVscyBmcm9tIHByb2dyYW0gY29uZmlnIChBU0MpICovCiAgICBpZiAoQ1Byb2dyYW1Db25maWdfSXNWYWxpZCgmYXNjLT5tX3Byb2dyQ29uZmlnRWxlbWVudCkpIHsKICAgICAgYXNjQ2hhbm5lbHMgPSBhc2MtPm1fcHJvZ3JDb25maWdFbGVtZW50Lk51bUNoYW5uZWxzOwogICAgICBpZiAoYXNjQ2hhbm5lbHMgPiAwKSB7CiAgICAgICAgaW50IGVsOwogICAgICAgIC8qIHZhbGlkIG51bWJlciBvZiBjaGFubmVscyAtPiBjb3B5IHByb2dyYW0gY29uZmlnIGVsZW1lbnQgKFBDRSkgZnJvbSBBU0MgKi8KICAgICAgICBGREttZW1jcHkoJnNlbGYtPnBjZSwgJmFzYy0+bV9wcm9nckNvbmZpZ0VsZW1lbnQsIHNpemVvZihDUHJvZ3JhbUNvbmZpZykpOwogICAgICAgIC8qIEJ1aWx0IGVsZW1lbnQgdGFibGUgKi8KICAgICAgICBlbCA9IENQcm9ncmFtQ29uZmlnX0dldEVsZW1lbnRUYWJsZSgmYXNjLT5tX3Byb2dyQ29uZmlnRWxlbWVudCwgc2VsZi0+ZWxlbWVudHMsICg4KSwgJnNlbGYtPmNoTWFwSW5kZXgpOwogICAgICAgIGZvciAoOyBlbDwoOCk7IGVsKyspIHsKICAgICAgICAgIHNlbGYtPmVsZW1lbnRzW2VsXSA9IElEX05PTkU7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBBQUNfREVDX1VOU1VQUE9SVEVEX0NIQU5ORUxDT05GSUc7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIHNlbGYtPmNoTWFwSW5kZXggPSAwOwogICAgICBpZiAodHJhbnNwb3J0RGVjX0dldEZvcm1hdChzZWxmLT5oSW5wdXQpID09IFRUX01QNF9BRFRTKSB7CiAgICAgICAgLyogc2V0IGRlZmF1bHQgbWF4X2NoYW5uZWxzIGZvciBtZW1vcnkgYWxsb2NhdGlvbiBiZWNhdXNlIGluIGltcGxpY2l0IGNoYW5uZWwgbWFwcGluZyBtb2RlCiAgICAgICAgICAgd2UgZG9uJ3Qga25vdyB0aGUgYWN0dWFsIG51bWJlciBvZiBjaGFubmVscyB1bnRpbCB3ZSBwcm9jZXNzZWQgYXQgbGVhc3Qgb25lIHJhd19kYXRhX2Jsb2NrKCkuICovCiAgICAgICAgYXNjQ2hhbm5lbHMgPSAoOCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEFBQ19ERUNfVU5TVVBQT1JURURfQ0hBTk5FTENPTkZJRzsKICAgICAgfQogICAgfQojZWxzZSAvKiBUUF9QQ0VfRU5BQkxFICovCiAgICByZXR1cm4gQUFDX0RFQ19VTlNVUFBPUlRFRF9DSEFOTkVMQ09ORklHOwojZW5kaWYgLyogVFBfUENFX0VOQUJMRSAqLwogICAgYnJlYWs7CiAgY2FzZSAxOiBjYXNlIDI6IGNhc2UgMzogY2FzZSA0OiBjYXNlIDU6IGNhc2UgNjoKICAgIGFzY0NoYW5uZWxzID0gYXNjLT5tX2NoYW5uZWxDb25maWd1cmF0aW9uOwogICAgYnJlYWs7CiAgY2FzZSAxMToKICAgIGFzY0NoYW5uZWxzID0gNzsKICAgIGJyZWFrOwogIGNhc2UgNzogY2FzZSAxMjogY2FzZSAxNDoKICAgIGFzY0NoYW5uZWxzID0gODsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICByZXR1cm4gQUFDX0RFQ19VTlNVUFBPUlRFRF9DSEFOTkVMQ09ORklHOwogIH0KCiAgaWYgKGFzY0NoYW5uZWxzID4gKDgpKSB7CiAgICByZXR1cm4gQUFDX0RFQ19VTlNVUFBPUlRFRF9DSEFOTkVMQ09ORklHOwogIH0KCiAgLyogSW5pdGlhbGl6ZSBjb25zdGFudCBtYXBwaW5ncyBmb3IgY2hhbm5lbCBjb25maWcgMS03ICovCiAgaWYgKGFzYy0+bV9jaGFubmVsQ29uZmlndXJhdGlvbiA+IDApIHsKICAgIGludCBlbDsKICAgIEZES21lbWNweShzZWxmLT5lbGVtZW50cywgZWxlbWVudHNUYWJbYXNjLT5tX2NoYW5uZWxDb25maWd1cmF0aW9uLTFdLCBzaXplb2YoTVA0X0VMRU1FTlRfSUQpKkZES21pbig3LCg4KSkpOwogICAgZm9yIChlbD03OyBlbDwoOCk7IGVsKyspIHsKICAgICAgc2VsZi0+ZWxlbWVudHNbZWxdID0gSURfTk9ORTsKICAgIH0KICAgIGZvciAoY2g9MDsgY2g8YXNjQ2hhbm5lbHM7IGNoKyspIHsKICAgICAgc2VsZi0+Y2hNYXBwaW5nW2NoXSA9IGNoOwogICAgfQogICAgZm9yICg7IGNoPCg4KTsgY2grKykgewogICAgICBzZWxmLT5jaE1hcHBpbmdbY2hdID0gMjU1OwogICAgfQogICAgc2VsZi0+Y2hNYXBJbmRleCA9IGFzYy0+bV9jaGFubmVsQ29uZmlndXJhdGlvbjsKICB9CiAjaWZkZWYgVFBfUENFX0VOQUJMRQogIGVsc2UgewogICAgaWYgKENQcm9ncmFtQ29uZmlnX0lzVmFsaWQoJmFzYy0+bV9wcm9nckNvbmZpZ0VsZW1lbnQpKSB7CiAgICAgIC8qIFNldCBtYXRyaXggbWl4ZG93biBpbmZvcyBpZiBhdmFpbGFibGUgZnJvbSBQQ0UuICovCiAgICAgIHBjbURteF9TZXRNYXRyaXhNaXhkb3duRnJvbVBjZSAoIHNlbGYtPmhQY21VdGlscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNjLT5tX3Byb2dyQ29uZmlnRWxlbWVudC5NYXRyaXhNaXhkb3duSW5kZXhQcmVzZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc2MtPm1fcHJvZ3JDb25maWdFbGVtZW50Lk1hdHJpeE1peGRvd25JbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNjLT5tX3Byb2dyQ29uZmlnRWxlbWVudC5Qc2V1ZG9TdXJyb3VuZEVuYWJsZSApOwogICAgfQogIH0KICNlbmRpZgoKICBzZWxmLT5zdHJlYW1JbmZvLmNoYW5uZWxDb25maWcgPSBhc2MtPm1fY2hhbm5lbENvbmZpZ3VyYXRpb247CgogIGlmIChzZWxmLT5zdHJlYW1JbmZvLmFvdCAhPSBhc2MtPm1fYW90KSB7CiAgICBzZWxmLT5zdHJlYW1JbmZvLmFvdCA9IGFzYy0+bV9hb3Q7CiAgICBhc2NDaGFuZ2VkID0gMTsKICB9CgogIGlmIChzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZXNQZXJGcmFtZSAhPSAoSU5UKWFzYy0+bV9zYW1wbGVzUGVyRnJhbWUpIHsKICAgIHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlc1BlckZyYW1lID0gYXNjLT5tX3NhbXBsZXNQZXJGcmFtZTsKICAgIGFzY0NoYW5nZWQgPSAxOwogIH0KCiAgc2VsZi0+c3RyZWFtSW5mby5iaXRSYXRlICAgICAgICAgICAgPSAwOwoKICAvKiBTZXQgc3ludGF4IGZsYWdzICovCiAgc2VsZi0+ZmxhZ3MgPSAwOwoKICBzZWxmLT5zdHJlYW1JbmZvLmV4dEFvdCAgICAgICAgICAgICAgID0gYXNjLT5tX2V4dGVuc2lvbkF1ZGlvT2JqZWN0VHlwZTsKICBzZWxmLT5zdHJlYW1JbmZvLmV4dFNhbXBsaW5nUmF0ZSAgICAgID0gYXNjLT5tX2V4dGVuc2lvblNhbXBsaW5nRnJlcXVlbmN5OwogIHNlbGYtPmZsYWdzIHw9IChhc2MtPm1fc2JyUHJlc2VudEZsYWcpID8gQUNfU0JSX1BSRVNFTlQgOiAwOwogIHNlbGYtPmZsYWdzIHw9IChhc2MtPm1fcHNQcmVzZW50RmxhZykgPyBBQ19QU19QUkVTRU5UIDogMDsKICBzZWxmLT5zYnJFbmFibGVkID0gMDsKCiAgLyogLS0tLS0tLS0tIHZjYjExIC0tLS0tLS0tLS0tLSAqLwogIHNlbGYtPmZsYWdzIHw9IChhc2MtPm1fdmNiMTFGbGFnKSA/IEFDX0VSX1ZDQjExIDogMDsKCiAgLyogLS0tLS0tLS0tLSBydmxjIC0tLS0tLS0tLS0tLSAqLwogIHNlbGYtPmZsYWdzIHw9IChhc2MtPm1fcnZsY0ZsYWcpID8gQUNfRVJfUlZMQyA6IDA7CgogIC8qIC0tLS0tLS0tLS0tIGhjciAtLS0tLS0tLS0tLS0gKi8KICBzZWxmLT5mbGFncyB8PSAoYXNjLT5tX2hjckZsYWcpID8gQUNfRVJfSENSIDogMDsKCiAgaWYgKGFzYy0+bV9hb3QgPT0gQU9UX0VSX0FBQ19FTEQpIHsKICAgIHNlbGYtPmZsYWdzIHw9ICBBQ19FTEQ7CiAgICBzZWxmLT5mbGFncyB8PSAoYXNjLT5tX3NiclByZXNlbnRGbGFnKSA/IEFDX1NCUl9QUkVTRU5UIDogMDsgIC8qIE5lZWQgdG8gc2V0IHRoZSBTQlIgZmxhZyBmb3IgYmFja3dhcmQtY29tcGF0aWJpbGl0eQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFzb25zLiBFdmVuIGlmIFNCUiBpcyBub3Qgc3VwcG9ydGVkLiAqLwogICAgc2VsZi0+ZmxhZ3MgfD0gKGFzYy0+bV9zYy5tX2VsZFNwZWNpZmljQ29uZmlnLm1fc2JyQ3JjRmxhZykgPyBBQ19TQlJDUkMgOiAwOwogICAgc2VsZi0+ZmxhZ3MgfD0gKGFzYy0+bV9zYy5tX2VsZFNwZWNpZmljQ29uZmlnLm1fdXNlTGRRbWZUaW1lQWxpZ24pID8gQUNfTERfTVBTIDogMDsKICB9CiAgc2VsZi0+ZmxhZ3MgfD0gKGFzYy0+bV9hb3QgPT0gQU9UX0VSX0FBQ19MRCkgPyBBQ19MRCA6IDA7CiAgc2VsZi0+ZmxhZ3MgfD0gKGFzYy0+bV9lcENvbmZpZyA+PSAwKSA/IEFDX0VSIDogMDsKICBpZiAoIGFzYy0+bV9hb3QgPT0gQU9UX0RSTV9BQUMgKSB7CiAgICBzZWxmLT5mbGFncyB8PSBBQ19EUk18QUNfU0JSQ1JDfEFDX1NDQUxBQkxFOwogIH0KICBpZiAoIChhc2MtPm1fYW90ID09IEFPVF9BQUNfU0NBTCkKICAgIHx8IChhc2MtPm1fYW90ID09IEFPVF9FUl9BQUNfU0NBTCkgKSB7CiAgICBzZWxmLT5mbGFncyB8PSBBQ19TQ0FMQUJMRTsKICB9CgoKICBpZiAoYXNjLT5tX3NiclByZXNlbnRGbGFnKSB7CiAgICBzZWxmLT5zYnJFbmFibGVkID0gMTsKICAgIHNlbGYtPnNickVuYWJsZWRQcmV2ID0gMTsKICB9CiAgaWYgKGFzYy0+bV9wc1ByZXNlbnRGbGFnKSB7CiAgICBzZWxmLT5mbGFncyB8PSBBQ19QU19QUkVTRU5UOwogIH0KCiAgaWYgKCAoYXNjLT5tX2VwQ29uZmlnID49IDApCiAgICAmJiAoYXNjLT5tX2NoYW5uZWxDb25maWd1cmF0aW9uIDw9IDApICkgewogICAgLyogd2UgaGF2ZSB0byBrbm93IHRoZSBudW1iZXIgb2YgY2hhbm5lbHMgb3RoZXJ3aXNlIG5vIGRlY29kaW5nIGlzIHBvc3NpYmxlICovCiAgICByZXR1cm4gQUFDX0RFQ19VTlNVUFBPUlRFRF9FUl9GT1JNQVQ7CiAgfQoKICBzZWxmLT5zdHJlYW1JbmZvLmVwQ29uZmlnID0gYXNjLT5tX2VwQ29uZmlnOwogIC8qIHNlbGYtPmhJbnB1dC0+YXNjLm1fZXBDb25maWcgPSBhc2MtPm1fZXBDb25maWc7ICovCgogIGlmIChhc2MtPm1fZXBDb25maWcgPiAxKQogICAgcmV0dXJuIEFBQ19ERUNfVU5TVVBQT1JURURfRVJfRk9STUFUOwoKICAvKiBDaGVjayBpZiBzYW1wbGVyYXRlIGNoYW5nZWQuICovCiAgaWYgKHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlUmF0ZSAhPSAoSU5UKWFzYy0+bV9zYW1wbGluZ0ZyZXF1ZW5jeSkgewogICAgQUFDX0RFQ09ERVJfRVJST1IgZXJyb3I7CgogICAgYXNjQ2hhbmdlZCA9IDE7CgogICAgLyogVXBkYXRlIHNhbXBsZXJhdGUgaW5mby4gKi8KICAgIGVycm9yID0gZ2V0U2FtcGxpbmdSYXRlSW5mbygmc2VsZi0+c2FtcGxpbmdSYXRlSW5mbywgYXNjLT5tX3NhbXBsZXNQZXJGcmFtZSwgYXNjLT5tX3NhbXBsaW5nRnJlcXVlbmN5SW5kZXgsIGFzYy0+bV9zYW1wbGluZ0ZyZXF1ZW5jeSk7CiAgICBpZiAoZXJyb3IgIT0gQUFDX0RFQ19PSykgewogICAgICByZXR1cm4gZXJyb3I7CiAgICB9CiAgICBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZVJhdGUgPSBzZWxmLT5zYW1wbGluZ1JhdGVJbmZvLnNhbXBsaW5nUmF0ZTsKICB9CgogIC8qIENoZWNrIGlmIGFtb3VudCBvZiBjaGFubmVscyBoYXMgY2hhbmdlZC4gKi8KICBpZiAoc2VsZi0+YXNjQ2hhbm5lbHMgIT0gYXNjQ2hhbm5lbHMpCiAgewogICAgIGFzY0NoYW5nZWQgPSAxOwoKICAgICAvKiBBbGxvY2F0ZSBhbGwgbWVtb3J5IHN0cnVjdHVyZXMgZm9yIGVhY2ggY2hhbm5lbCAqLwogICAgIHsKICAgICAgIGZvciAoY2ggPSAwOyBjaCA8IGFzY0NoYW5uZWxzOyBjaCsrKSB7CiAgICAgICAgIENBYWNEZWNvZGVyRHluYW1pY0RhdGEgKmFhY0RlY29kZXJEeW5hbWljRGF0YSA9ICZzZWxmLT5hYWNDb21tb25EYXRhLndvcmtCdWZmZXJDb3JlMS0+cEFhY0RlY29kZXJEeW5hbWljRGF0YVtjaCUyXTsKCiAgICAgICAgIC8qIGluaXRpYWxpemUgcG9pbnRlciB0byBDQWFjRGVjb2RlckNoYW5uZWxJbmZvICovCiAgICAgICAgIGlmIChzZWxmLT5wQWFjRGVjb2RlckNoYW5uZWxJbmZvW2NoXSA9PSBOVUxMKSB7CiAgICAgICAgICAgc2VsZi0+cEFhY0RlY29kZXJDaGFubmVsSW5mb1tjaF0gPSBHZXRBYWNEZWNvZGVyQ2hhbm5lbEluZm8oY2gpOwogICAgICAgICAgIC8qIFRoaXMgaXMgdGVtcG9yYXJ5IHVudGlsIHRoZSBEeW5hbWljRGF0YSBpcyBzcGxpdCBpbnRvIHR3byBvciBtb3JlIHJlZ2lvbnMhCiAgICAgICAgICAgICAgVGhlIG1lbW9yeSBjb3VsZCBiZSByZXVzZWQgYWZ0ZXIgY29tcGxldGVkIGNvcmUgZGVjb2RpbmcuICovCiAgICAgICAgICAgaWYgKHNlbGYtPnBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bY2hdID09IE5VTEwpIHsKICAgICAgICAgICAgIGdvdG8gYmFpbDsKICAgICAgICAgICB9CiAgICAgICAgICAgLyogSG9vayBzaGFyZWQgd29yayBtZW1vcnkgaW50byBjaGFubmVsIGRhdGEgc3RydWN0dXJlICovCiAgICAgICAgICAgc2VsZi0+cEFhY0RlY29kZXJDaGFubmVsSW5mb1tjaF0tPnBEeW5EYXRhID0gIGFhY0RlY29kZXJEeW5hbWljRGF0YTsKICAgICAgICAgICBzZWxmLT5wQWFjRGVjb2RlckNoYW5uZWxJbmZvW2NoXS0+cENvbURhdGEgPSAmc2VsZi0+YWFjQ29tbW9uRGF0YTsKICAgICAgICAgfQoKICAgICAgICAgLyogQWxsb2NhdGUgcGVyc2lzdGVudCBjaGFubmVsIG1lbW9yeSAqLwogICAgICAgICBpZiAoc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjaF0gPT0gTlVMTCkgewogICAgICAgICAgIHNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bY2hdID0gR2V0QWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvKGNoKTsKICAgICAgICAgICBpZiAoc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjaF0gPT0gTlVMTCkgewogICAgICAgICAgICAgZ290byBiYWlsOwogICAgICAgICAgIH0KICAgICAgICAgICBzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NoXS0+cE92ZXJsYXBCdWZmZXIgPSBHZXRPdmVybGFwQnVmZmVyKGNoKTsgLyogVGhpcyBhcmVhIHNpemUgZGVwZW5kcyBvbiB0aGUgQU9UICovCiAgICAgICAgICAgaWYgKHNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bY2hdLT5wT3ZlcmxhcEJ1ZmZlciA9PSBOVUxMKSB7CiAgICAgICAgICAgICBnb3RvIGJhaWw7CiAgICAgICAgICAgfQogICAgICAgICAgIHNlbGYtPnBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bY2hdLT5wU3BlY3RyYWxDb2VmZmljaWVudCA9IChTUEVDVFJBTF9QVFIpICZzZWxmLT5hYWNDb21tb25EYXRhLndvcmtCdWZmZXJDb3JlMltjaCoxMDI0XTsKCiAgICAgICAgIH0KICAgICAgICAgQ1Buc19Jbml0UG5zKCZzZWxmLT5wQWFjRGVjb2RlckNoYW5uZWxJbmZvW2NoXS0+ZGF0YS5hYWMuUG5zRGF0YSwgJnNlbGYtPmFhY0NvbW1vbkRhdGEucG5zSW50ZXJDaGFubmVsRGF0YSwgJnNlbGYtPmFhY0NvbW1vbkRhdGEucG5zQ3VycmVudFNlZWQsIHNlbGYtPmFhY0NvbW1vbkRhdGEucG5zUmFuZG9tU2VlZCk7CiAgICAgICB9CgogICAgICAgaWYgKGFzY0NoYW5uZWxzID4gc2VsZi0+YWFjQ2hhbm5lbHMpCiAgICAgICB7CiAgICAgICAgIC8qIE1ha2UgYWxsb2NhdGVkIGNoYW5uZWwgY291bnQgcGVyc2lzdGVudCBpbiBkZWNvZGVyIGNvbnRleHQuICovCiAgICAgICAgIHNlbGYtPmFhY0NoYW5uZWxzID0gYXNjQ2hhbm5lbHM7CiAgICAgICB9CgogICAgICAgSGNySW5pdFJvbSgmc2VsZi0+YWFjQ29tbW9uRGF0YS5vdmVybGF5LmFhYy5lckhjckluZm8pOwogICAgICAgc2V0SGNyVHlwZSgmc2VsZi0+YWFjQ29tbW9uRGF0YS5vdmVybGF5LmFhYy5lckhjckluZm8sIElEX1NDRSk7CiAgICB9CgogICAgLyogTWFrZSBhbW91bnQgb2Ygc2lnbmFsbGVkIGNoYW5uZWxzIHBlcnNpc3RlbnQgaW4gZGVjb2RlciBjb250ZXh0LiAqLwogICAgc2VsZi0+YXNjQ2hhbm5lbHMgPSBhc2NDaGFubmVsczsKICB9CgogIC8qIFVwZGF0ZSBzdHJ1Y3R1cmVzICovCiAgaWYgKGFzY0NoYW5nZWQpIHsKCiAgICAgLyogVGhpbmdzIHRvIGJlIGRvbmUgZm9yIGVhY2ggY2hhbm5lbCwgd2hpY2ggZG8gbm90IGludm9sdmUgYWxsb2NhdGluZyBtZW1vcnkuCiAgICAgICAgRG9pbmcgdGhlc2UgdGhpbmdzIG9ubHkgb24gdGhlIGNoYW5uZWxzIG5lZWRlZCBmb3IgdGhlIGN1cnJlbnQgY29uZmlndXJhdGlvbgogICAgICAgIChhc2NDaGFubmVscykgY291bGQgbGVhZCB0byBtZW1vcnkgYWNjZXNzIHZpb2xhdGlvbiBsYXRlciAoZXJyb3IgY29uY2VhbG1lbnQpLiAqLwogICAgIGZvciAoY2ggPSAwOyBjaCA8IHNlbGYtPmFhY0NoYW5uZWxzOyBjaCsrKSB7CiAgICAgICBzd2l0Y2ggKHNlbGYtPnN0cmVhbUluZm8uYW90KSB7CiAgICAgICAgIGNhc2UgQU9UX0VSX0FBQ19FTEQ6CiAgICAgICAgIGNhc2UgQU9UX0VSX0FBQ19MRDoKICAgICAgICAgICBzZWxmLT5wQWFjRGVjb2RlckNoYW5uZWxJbmZvW2NoXS0+Z3JhbnVsZUxlbmd0aCA9IHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlc1BlckZyYW1lOwogICAgICAgICAgIGJyZWFrOwogICAgICAgICBkZWZhdWx0OgogICAgICAgICAgIHNlbGYtPnBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bY2hdLT5ncmFudWxlTGVuZ3RoID0gc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWUgLyA4OwogICAgICAgICAgIGJyZWFrOwogICAgICAgfQogICAgICAgbWRjdF9pbml0KCAmc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjaF0tPklNZGN0LAogICAgICAgICAgICAgICAgICAgc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjaF0tPnBPdmVybGFwQnVmZmVyLAogICAgICAgICAgICAgICAgICAgT3ZlcmxhcEJ1ZmZlclNpemUgKTsKCgogICAgICAgIC8qIFJlc2V0IERSQyBjb250cm9sIGRhdGEgZm9yIHRoaXMgY2hhbm5lbCAqLwogICAgICAgIGFhY0RlY29kZXJfZHJjSW5pdENoYW5uZWxEYXRhICggJnNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bY2hdLT5kcmNEYXRhICk7CgogICAgICAgLyogUmVzZXQgY29uY2VhbG1lbnQgb25seSBpZiBBU0MgY2hhbmdlZC4gT3RoZXJ3aXNlIGl0IHdpbGwgYmUgZG9uZSB3aXRoIGFueSBjb25maWcgY2FsbGJhY2suCiAgICAgICAgICBFLmcuIGV2ZXJ5IHRpbWUgdGhlIExBVE0gU01DIGlzIHByZXNlbnQuICovCiAgICAgICBDQ29uY2VhbG1lbnRfSW5pdENoYW5uZWxEYXRhKCZzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NoXS0+Y29uY2VhbG1lbnRJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2VsZi0+Y29uY2VhbENvbW1vbkRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZXNQZXJGcmFtZSApOwogICAgIH0KICB9CgogIC8qIFVwZGF0ZSBleHRlcm5hbGx5IHZpc2libGUgY29weSBvZiBmbGFncyAqLwogIHNlbGYtPnN0cmVhbUluZm8uZmxhZ3MgPSBzZWxmLT5mbGFnczsKCiAgcmV0dXJuIGVycjsKCmJhaWw6CiAgYWFjRGVjb2Rlcl9DbG9zZSggc2VsZiApOwogIHJldHVybiBBQUNfREVDX09VVF9PRl9NRU1PUlk7Cn0KCgpMSU5LU1BFQ19DUFAgQUFDX0RFQ09ERVJfRVJST1IgQ0FhY0RlY29kZXJfRGVjb2RlRnJhbWUoCiAgICAgICAgSEFORExFX0FBQ0RFQ09ERVIgc2VsZiwKICAgICAgICBjb25zdCBVSU5UIGZsYWdzLAogICAgICAgIElOVF9QQ00gKnBUaW1lRGF0YSwKICAgICAgICBjb25zdCBJTlQgIHRpbWVEYXRhU2l6ZSwKICAgICAgICBjb25zdCBJTlQgaW50ZXJsZWF2ZWQKICAgICAgICApCnsKICBBQUNfREVDT0RFUl9FUlJPUiBFcnJvclN0YXR1cyA9IEFBQ19ERUNfT0s7CgogIENQcm9ncmFtQ29uZmlnICpwY2U7CiAgSEFORExFX0ZES19CSVRTVFJFQU0gYnMgPSB0cmFuc3BvcnREZWNfR2V0Qml0c3RyZWFtKHNlbGYtPmhJbnB1dCwgMCk7CgogIE1QNF9FTEVNRU5UX0lEIHR5cGUgPSBJRF9OT05FOyAgICAgICAgICAgIC8qIEN1cnJlbnQgZWxlbWVudCB0eXBlICovCiAgSU5UIGFhY0NoYW5uZWxzPTA7ICAgICAgICAgICAgICAgICAgICAgICAgLyogQ2hhbm5lbCBjb3VudGVyIGZvciBjaGFubmVscyBmb3VuZCBpbiB0aGUgYml0c3RyZWFtICovCiAgaW50IGNoT3V0TWFwSWR4OyAgICAgICAgICAgICAgICAgICAgICAgICAgLyogT3V0cHV0IGNoYW5uZWwgbWFwcGluZyBpbmRleCAoc2VlIGNvbW1lbnQgYmVsb3cpICovCgogIElOVCBhdVN0YXJ0QW5jaG9yID0gKElOVClGREtnZXRWYWxpZEJpdHMoYnMpOyAgLyogQVUgc3RhcnQgYml0IGJ1ZmZlciBwb3NpdGlvbiBmb3IgQVUgYnl0ZSBhbGlnbm1lbnQgKi8KCiAgc2VsZi0+ZnJhbWVPSyA9IDE7CgogIC8qIEFueSBzdXBwb3J0ZWQgYmFzZSBsYXllciB2YWxpZCBBVSB3aWxsIHJlcXVpcmUgbW9yZSB0aGFuIDE2IGJpdHMuICovCiAgaWYgKCAodHJhbnNwb3J0RGVjX0dldEF1Qml0c1JlbWFpbmluZyhzZWxmLT5oSW5wdXQsIDApIDwgMTUpICYmIChmbGFncyAmIChBQUNERUNfQ09OQ0VBTHxBQUNERUNfRkxVU0gpKSA9PSAwKSB7CiAgICBzZWxmLT5mcmFtZU9LID0gMDsKICAgIEVycm9yU3RhdHVzID0gQUFDX0RFQ19ERUNPREVfRlJBTUVfRVJST1I7CiAgfQoKCiAgLyogUmVzZXQgUHJvZ3JhbSBDb25maWcgc3RydWN0dXJlICovCiAgcGNlID0gJnNlbGYtPnBjZTsKICBDUHJvZ3JhbUNvbmZpZ19SZXNldChwY2UpOwoKICBDQWFjRGVjb2Rlcl9BbmNEYXRhUmVzZXQoJnNlbGYtPmFuY0RhdGEpOwoKICB7CiAgICBpbnQgY2g7CgogICAgaWYgKHNlbGYtPnN0cmVhbUluZm8uY2hhbm5lbENvbmZpZyA9PSAwKSB7CiAgICAgIC8qIEluaXQgQ2hhbm5lbC9FbGVtZW50IG1hcHBpbmcgdGFibGUgKi8KICAgICAgZm9yIChjaD0wOyBjaDwoOCk7IGNoKyspIHsKICAgICAgICBzZWxmLT5jaE1hcHBpbmdbY2hdID0gMjU1OwogICAgICB9CiAgICAgIGlmICghQ1Byb2dyYW1Db25maWdfSXNWYWxpZChwY2UpKSB7CiAgICAgICAgaW50IGVsOwogICAgICAgIGZvciAoZWw9MDsgZWw8KDgpOyBlbCsrKSB7CiAgICAgICAgICBzZWxmLT5lbGVtZW50c1tlbF0gPSBJRF9OT05FOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KCiAgLyogQ2hlY2sgc2FtcGxpbmcgZnJlcXVlbmN5ICAqLwogIHN3aXRjaCAoIHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlUmF0ZSApIHsKICAgIGNhc2UgOTYwMDA6CiAgICBjYXNlIDg4MjAwOgogICAgY2FzZSA2NDAwMDoKICAgIGNhc2UgMTYwMDA6CiAgICBjYXNlIDEyMDAwOgogICBjYXNlIDExMDI1OgogICBjYXNlICA4MDAwOgogICAgY2FzZSAgNzM1MDoKICAgIGNhc2UgNDgwMDA6CiAgICBjYXNlIDQ0MTAwOgogICAgY2FzZSAzMjAwMDoKICAgIGNhc2UgMjQwMDA6CiAgICBjYXNlIDIyMDUwOgogICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIGlmICggISAoc2VsZi0+ZmxhZ3MgJiAoQUNfVVNBQ3xBQ19SU1ZENTApKSApIHsKICAgICAgICByZXR1cm4gQUFDX0RFQ19VTlNVUFBPUlRFRF9TQU1QTElOR1JBVEU7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgfQoKCiAgaWYgKCBmbGFncyAmIEFBQ0RFQ19DTFJISVNUICkKICB7CiAgICBpbnQgY2g7CiAgICAvKiBDbGVhciBoaXN0b3J5ICovCiAgICBmb3IgKGNoID0gMDsgY2ggPCBzZWxmLT5hYWNDaGFubmVsczsgY2grKykgewogICAgICAvKiBSZXNldCBjb25jZWFsbWVudCAqLwogICAgICBDQ29uY2VhbG1lbnRfSW5pdENoYW5uZWxEYXRhKCZzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NoXS0+Y29uY2VhbG1lbnRJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzZWxmLT5jb25jZWFsQ29tbW9uRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWUgKTsKICAgICAgLyogQ2xlYXIgb3ZlcmxhcC1hZGQgYnVmZmVycyB0byBhdm9pZCBjbGlja3MuICovCiAgICAgIEZES21lbWNsZWFyKHNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bY2hdLT5wT3ZlcmxhcEJ1ZmZlciwgT3ZlcmxhcEJ1ZmZlclNpemUqc2l6ZW9mKEZJWFBfREJMKSk7CiAgICAgfQogIH0KCgoKI2lmZGVmIFRQX1BDRV9FTkFCTEUKICBpbnQgcGNlUmVhZCA9IDA7ICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBGbGFnIGluZGljYXRpbmcgYSBQQ0UgaW4gdGhlIGN1cnJlbnQgcmF3X2RhdGFfYmxvY2soKSAqLwojZW5kaWYKCgogIElOVCBoZGFhY0RlY29kZWQgPSAwOwogIE1QNF9FTEVNRU5UX0lEIHByZXZpb3VzX2VsZW1lbnQgPSBJRF9FTkQ7IC8qIExhc3QgZWxlbWVudCBJRCAocmVxdWlyZWQgZm9yIGV4dGVuc2lvbiBwYXlsb2FkIG1hcHBpbmcgKi8KICBVQ0hBUiBwcmV2aW91c19lbGVtZW50X2luZGV4ID0gMDsgICAgICAgICAvKiBDYW5vbmljYWwgaW5kZXggb2YgbGFzdCBlbGVtZW50ICovCiAgaW50IGVsZW1lbnRfY291bnQgPSAwOyAgICAgICAgICAgICAgICAgICAgLyogRWxlbWVudCBjb3VudGVyIGZvciBlbGVtZW50cyBmb3VuZCBpbiB0aGUgYml0c3RyZWFtICovCiAgaW50IGVsX2NudFtJRF9MQVNUXSA9IHsgMCB9OyAgICAgICAgICAgICAgLyogZWxlbWVudCBjb3VudGVyICggcm9idXN0bmVzcyApICovCgogIHdoaWxlICggKHR5cGUgIT0gSURfRU5EKSAmJiAoISAoZmxhZ3MgJiAoQUFDREVDX0NPTkNFQUwgfCBBQUNERUNfRkxVU0gpKSkgJiYgc2VsZi0+ZnJhbWVPSyApCiAgewogICAgaW50IGVsX2NoYW5uZWxzOwoKICAgIGlmICghIChzZWxmLT5mbGFncyAmIChBQ19VU0FDfEFDX1JTVkQ1MHxBQ19FTER8QUNfU0NBTEFCTEV8QUNfRVIpKSkKICAgICAgdHlwZSA9IChNUDRfRUxFTUVOVF9JRCkgRkRLcmVhZEJpdHMoYnMsMyk7CiAgICBlbHNlIAogICAgICB0eXBlID0gc2VsZi0+ZWxlbWVudHNbZWxlbWVudF9jb3VudF07CgogICAgc2V0SGNyVHlwZSgmc2VsZi0+YWFjQ29tbW9uRGF0YS5vdmVybGF5LmFhYy5lckhjckluZm8sIHR5cGUpOwoKCiAgICBpZiAoKElOVClGREtnZXRWYWxpZEJpdHMoYnMpIDwgMCkKICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7CgogICAgc3dpdGNoICh0eXBlKQogICAgewogICAgICBjYXNlIElEX1NDRToKICAgICAgY2FzZSBJRF9DUEU6CiAgICAgIGNhc2UgSURfTEZFOgogICAgICAgIC8qCiAgICAgICAgICBDb25zaXN0ZW5jeSBjaGVjawogICAgICAgICovCgogICAgICAgIGlmICh0eXBlID09IElEX0NQRSkgewogICAgICAgICAgZWxfY2hhbm5lbHMgPSAyOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBlbF9jaGFubmVscyA9IDE7CiAgICAgICAgfQoKICAgICAgICBpZiAoIChlbF9jbnRbdHlwZV0gPj0gKHNlbGYtPmFzY0NoYW5uZWxzPj4oZWxfY2hhbm5lbHMtMSkpKSB8fCAoYWFjQ2hhbm5lbHMgPiAoc2VsZi0+YXNjQ2hhbm5lbHMtZWxfY2hhbm5lbHMpKSApIHsKICAgICAgICAgIEVycm9yU3RhdHVzID0gQUFDX0RFQ19ERUNPREVfRlJBTUVfRVJST1I7CiAgICAgICAgICBzZWxmLT5mcmFtZU9LID0gMDsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgaWYgKCAhKHNlbGYtPmZsYWdzICYgKEFDX1VTQUN8QUNfUlNWRDUwKSkgKSB7CiAgICAgICAgICBpbnQgY2g7CiAgICAgICAgICBmb3IgKGNoPTA7IGNoIDwgZWxfY2hhbm5lbHM7IGNoKz0xKSB7CiAgICAgICAgICAgIENQbnNfUmVzZXREYXRhKCZzZWxmLT5wQWFjRGVjb2RlckNoYW5uZWxJbmZvW2FhY0NoYW5uZWxzK2NoXS0+ZGF0YS5hYWMuUG5zRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgJnNlbGYtPnBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bYWFjQ2hhbm5lbHMrY2hdLT5wQ29tRGF0YS0+cG5zSW50ZXJDaGFubmVsRGF0YSk7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZihzZWxmLT5mcmFtZU9LKSB7CiAgICAgICAgICBFcnJvclN0YXR1cyA9IENDaGFubmVsRWxlbWVudF9SZWFkKCBicywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnNlbGYtPnBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bYWFjQ2hhbm5lbHNdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1thYWNDaGFubmVsc10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmFvdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnNlbGYtPnNhbXBsaW5nUmF0ZUluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5mbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlc1BlckZyYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxfY2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmVwQ29uZmlnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+aElucHV0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgaWYgKEVycm9yU3RhdHVzKSB7CiAgICAgICAgICAgIHNlbGYtPmZyYW1lT0sgPSAwOwogICAgICAgICAgfQogICAgICAgIH0KCgogICAgICAgIGlmICggc2VsZi0+ZnJhbWVPSykgewogICAgICAgICAgLyogTG9va3VwIHRoZSBlbGVtZW50IGFuZCBkZWNvZGUgaXQgb25seSBpZiBpdCBiZWxvbmdzIHRvIHRoZSBjdXJyZW50IHByb2dyYW0gKi8KICAgICAgICAgIGlmICggQ1Byb2dyYW1Db25maWdfTG9va3VwRWxlbWVudCgKICAgICAgICAgICAgICAgICAgcGNlLAogICAgICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmNoYW5uZWxDb25maWcsCiAgICAgICAgICAgICAgICAgIHNlbGYtPnBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bYWFjQ2hhbm5lbHNdLT5FbGVtZW50SW5zdGFuY2VUYWcsCiAgICAgICAgICAgICAgICAgIGFhY0NoYW5uZWxzLAogICAgICAgICAgICAgICAgICBzZWxmLT5jaE1hcHBpbmcsCiAgICAgICAgICAgICAgICAgIHNlbGYtPmNoYW5uZWxUeXBlLAogICAgICAgICAgICAgICAgICBzZWxmLT5jaGFubmVsSW5kaWNlcywKICAgICAgICAgICAgICAgICAmcHJldmlvdXNfZWxlbWVudF9pbmRleCwKICAgICAgICAgICAgICAgICAgc2VsZi0+ZWxlbWVudHMsCiAgICAgICAgICAgICAgICAgIHR5cGUpICkKICAgICAgICAgIHsKICAgICAgICAgICAgaWYgKCAhaGRhYWNEZWNvZGVkICkgewogICAgICAgICAgICAgIENDaGFubmVsRWxlbWVudF9EZWNvZGUoCiAgICAgICAgICAgICAgICAgICAgICZzZWxmLT5wQWFjRGVjb2RlckNoYW5uZWxJbmZvW2FhY0NoYW5uZWxzXSwKICAgICAgICAgICAgICAgICAgICAgJnNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bYWFjQ2hhbm5lbHNdLAogICAgICAgICAgICAgICAgICAgICAmc2VsZi0+c2FtcGxpbmdSYXRlSW5mbywKICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPmZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgZWxfY2hhbm5lbHMKICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYWFjQ2hhbm5lbHMgKz0gMTsKICAgICAgICAgICAgaWYgKHR5cGUgPT0gSURfQ1BFKSB7CiAgICAgICAgICAgICAgYWFjQ2hhbm5lbHMgKz0gMTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIHNlbGYtPmZyYW1lT0sgPSAwOwogICAgICAgICAgfQogICAgICAgICAgLyogQ3JlYXRlIFNCUiBlbGVtZW50IGZvciBTQlIgZm9yIHVwc2FtcGxpbmcgZm9yIExGRSBlbGVtZW50cywKICAgICAgICAgICAgIGFuZCBpZiBTQlIgd2FzIGV4cGxpY2l0bHkgc2lnbmFsZWQsIGJlY2F1c2UgdGhlIGZpcnN0IGZyYW1lKHMpCiAgICAgICAgICAgICBtYXkgbm90IGNvbnRhaW4gU0JSIHBheWxvYWQgKGJyb2tlbiBlbmNvZGVyLCBiaXQgZXJyb3JzKS4gKi8KICAgICAgICAgIGlmICggKHNlbGYtPmZsYWdzICYgQUNfU0JSX1BSRVNFTlQpIHx8IChzZWxmLT5zYnJFbmFibGVkID09IDEpICkKICAgICAgICAgIHsKICAgICAgICAgICAgU0JSX0VSUk9SIHNickVycm9yOwoKICAgICAgICAgICAgc2JyRXJyb3IgPSBzYnJEZWNvZGVyX0luaXRFbGVtZW50KAogICAgICAgICAgICAgICAgICAgIHNlbGYtPmhTYnJEZWNvZGVyLAogICAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlUmF0ZSwKICAgICAgICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmV4dFNhbXBsaW5nUmF0ZSwKICAgICAgICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZXNQZXJGcmFtZSwKICAgICAgICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmFvdCwKICAgICAgICAgICAgICAgICAgICB0eXBlLAogICAgICAgICAgICAgICAgICAgIHByZXZpb3VzX2VsZW1lbnRfaW5kZXgKICAgICAgICAgICAgICAgICAgICApOwogICAgICAgICAgICBpZiAoc2JyRXJyb3IgIT0gU0JSREVDX09LKSB7CiAgICAgICAgICAgICAgLyogRG8gbm90IHRyeSB0byBhcHBseSBTQlIgYmVjYXVzZSBpbml0aWFsaXppbmcgdGhlIGVsZW1lbnQgZmFpbGVkLiAqLwogICAgICAgICAgICAgIHNlbGYtPnNickVuYWJsZWQgPSAwOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBlbF9jbnRbdHlwZV0rKzsKICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgSURfQ0NFOgogICAgICAgIC8qCiAgICAgICAgICBDb25zaXN0ZW5jeSBjaGVjawogICAgICAgICovCiAgICAgICAgaWYgKCBlbF9jbnRbdHlwZV0gPiBzZWxmLT5hc2NDaGFubmVscyApIHsKICAgICAgICAgIEVycm9yU3RhdHVzID0gQUFDX0RFQ19ERUNPREVfRlJBTUVfRVJST1I7CiAgICAgICAgICBzZWxmLT5mcmFtZU9LID0gMDsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICAgICAgaWYgKHNlbGYtPmZyYW1lT0spCiAgICAgICAgewogICAgICAgICAgLyogbWVtb3J5IGZvciBzcGVjdHJhbCBsaW5lcyB0ZW1wb3JhbCBvbiBzY3JhdGNoICovCiAgICAgICAgICBDX0FMTE9DX1NDUkFUQ0hfU1RBUlQobWRjdFNwZWMsIEZJWFBfREJMLCAxMDI0KTsKCiAgICAgICAgICAvKiBjcmVhdGUgZHVtbXkgY2hhbm5lbCBmb3IgQ0NFIHBhcnNpbmcgb24gc3RhY2sgKi8KICAgICAgICAgIENBYWNEZWNvZGVyQ2hhbm5lbEluZm8gIHRtcEFhY0RlY29kZXJDaGFubmVsSW5mbywgKnBUbXBBYWNEZWNvZGVyQ2hhbm5lbEluZm87CgogICAgICAgICAgRkRLbWVtY2xlYXIobWRjdFNwZWMsIDEwMjQqc2l6ZW9mKEZJWFBfREJMKSk7CgogICAgICAgICAgdG1wQWFjRGVjb2RlckNoYW5uZWxJbmZvLnBEeW5EYXRhID0gICBzZWxmLT5hYWNDb21tb25EYXRhLndvcmtCdWZmZXJDb3JlMS0+cEFhY0RlY29kZXJEeW5hbWljRGF0YTsKICAgICAgICAgIHRtcEFhY0RlY29kZXJDaGFubmVsSW5mby5wQ29tRGF0YSA9ICAmc2VsZi0+YWFjQ29tbW9uRGF0YTsKICAgICAgICAgIHRtcEFhY0RlY29kZXJDaGFubmVsSW5mby5wU3BlY3RyYWxDb2VmZmljaWVudCAgPSAoU1BFQ1RSQUxfUFRSKW1kY3RTcGVjOwogICAgICAgICAgLyogQXNzdW1lIEFBQy1MQyAqLwogICAgICAgICAgdG1wQWFjRGVjb2RlckNoYW5uZWxJbmZvLmdyYW51bGVMZW5ndGggPSBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZXNQZXJGcmFtZSAvIDg7CgogICAgICAgICAgLyogUmVzZXQgUE5TIGRhdGEuICovCiAgICAgICAgICBDUG5zX1Jlc2V0RGF0YSgmdG1wQWFjRGVjb2RlckNoYW5uZWxJbmZvLmRhdGEuYWFjLlBuc0RhdGEsICZ0bXBBYWNEZWNvZGVyQ2hhbm5lbEluZm8ucENvbURhdGEtPnBuc0ludGVyQ2hhbm5lbERhdGEpOwoKICAgICAgICAgIHBUbXBBYWNEZWNvZGVyQ2hhbm5lbEluZm8gPSAmdG1wQWFjRGVjb2RlckNoYW5uZWxJbmZvOwogICAgICAgICAgLyogZG8gQ0NFIHBhcnNpbmcgKi8KICAgICAgICAgIEVycm9yU3RhdHVzID0gQ0NoYW5uZWxFbGVtZW50X1JlYWQoIGJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcFRtcEFhY0RlY29kZXJDaGFubmVsSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmFvdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnNlbGYtPnNhbXBsaW5nUmF0ZUluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5mbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlc1BlckZyYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uZXBDb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5oSW5wdXQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgICBDX0FMTE9DX1NDUkFUQ0hfRU5EKG1kY3RTcGVjLCBGSVhQX0RCTCwgMTAyNCk7CgogICAgICAgICAgaWYgKEVycm9yU3RhdHVzKSB7CiAgICAgICAgICAgIHNlbGYtPmZyYW1lT0sgPSAwOwogICAgICAgICAgfQoKICAgICAgICAgIGlmIChzZWxmLT5mcmFtZU9LKSB7CiAgICAgICAgICAgIC8qIExvb2t1cCB0aGUgZWxlbWVudCBhbmQgZGVjb2RlIGl0IG9ubHkgaWYgaXQgYmVsb25ncyB0byB0aGUgY3VycmVudCBwcm9ncmFtICovCiAgICAgICAgICAgIGlmIChDUHJvZ3JhbUNvbmZpZ19Mb29rdXBFbGVtZW50KAogICAgICAgICAgICAgICAgICAgIHBjZSwKICAgICAgICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmNoYW5uZWxDb25maWcsCiAgICAgICAgICAgICAgICAgICAgcFRtcEFhY0RlY29kZXJDaGFubmVsSW5mby0+RWxlbWVudEluc3RhbmNlVGFnLAogICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgc2VsZi0+Y2hNYXBwaW5nLAogICAgICAgICAgICAgICAgICAgIHNlbGYtPmNoYW5uZWxUeXBlLAogICAgICAgICAgICAgICAgICAgIHNlbGYtPmNoYW5uZWxJbmRpY2VzLAogICAgICAgICAgICAgICAgICAgJnByZXZpb3VzX2VsZW1lbnRfaW5kZXgsCiAgICAgICAgICAgICAgICAgICAgc2VsZi0+ZWxlbWVudHMsCiAgICAgICAgICAgICAgICAgICAgdHlwZSkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgLyogZGVjb2Rpbmcgb2YgQ0NFIG5vdCBzdXBwb3J0ZWQgKi8KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICBzZWxmLT5mcmFtZU9LID0gMDsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbF9jbnRbdHlwZV0rKzsKICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgSURfRFNFOgogICAgICAgIHsKICAgICAgICAgIFVDSEFSIGVsZW1lbnRfaW5zdGFuY2VfdGFnOwoKICAgICAgICAgIENEYXRhU3RyZWFtRWxlbWVudF9SZWFkKCBzZWxmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmVsZW1lbnRfaW5zdGFuY2VfdGFnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1U3RhcnRBbmNob3IgKTsKCiAgICAgICAgICBpZiAoIUNQcm9ncmFtQ29uZmlnX0xvb2t1cEVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICBwY2UsCiAgICAgICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmNoYW5uZWxDb25maWcsCiAgICAgICAgICAgICAgICAgICBlbGVtZW50X2luc3RhbmNlX3RhZywKICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICBzZWxmLT5jaE1hcHBpbmcsCiAgICAgICAgICAgICAgICAgICBzZWxmLT5jaGFubmVsVHlwZSwKICAgICAgICAgICAgICAgICAgIHNlbGYtPmNoYW5uZWxJbmRpY2VzLAogICAgICAgICAgICAgICAgICAmcHJldmlvdXNfZWxlbWVudF9pbmRleCwKICAgICAgICAgICAgICAgICAgIHNlbGYtPmVsZW1lbnRzLAogICAgICAgICAgICAgICAgICAgdHlwZSkgKQogICAgICAgICAgewogICAgICAgICAgICAvKiBtb3N0IGxpa2VseSBhbiBlcnJvciBpbiBiaXRzdHJlYW0gb2NjdXJlZCAqLwogICAgICAgICAgICAvL3NlbGYtPmZyYW1lT0sgPSAwOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKCiNpZmRlZiBUUF9QQ0VfRU5BQkxFCiAgICAgIGNhc2UgSURfUENFOgogICAgICAgIHsKICAgICAgICAgIGludCByZXN1bHQgPSBDUHJvZ3JhbUNvbmZpZ0VsZW1lbnRfUmVhZCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPmhJbnB1dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmNoYW5uZWxDb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1U3RhcnRBbmNob3IgKTsKICAgICAgICAgIGlmICggcmVzdWx0IDwgMCApIHsKICAgICAgICAgICAgLyogU29tZXRoaW5nIHdlbnQgd3JvbmcgKi8KICAgICAgICAgICAgRXJyb3JTdGF0dXMgPSBBQUNfREVDX1BBUlNFX0VSUk9SOwogICAgICAgICAgICBzZWxmLT5mcmFtZU9LID0gMDsKICAgICAgICAgIH0KICAgICAgICAgIGVsc2UgaWYgKCByZXN1bHQgPiAxICkgewogICAgICAgICAgICAvKiBCdWlsdCBlbGVtZW50IHRhYmxlICovCiAgICAgICAgICAgIGludCBlbElkeCA9IENQcm9ncmFtQ29uZmlnX0dldEVsZW1lbnRUYWJsZShwY2UsIHNlbGYtPmVsZW1lbnRzLCAoOCksICZzZWxmLT5jaE1hcEluZGV4KTsKICAgICAgICAgICAgLyogUmVzZXQgdGhlIHJlbWFpbmluZyB0YWJzICovCiAgICAgICAgICAgIGZvciAoIDsgZWxJZHg8KDgpOyBlbElkeCsrKSB7CiAgICAgICAgICAgICAgc2VsZi0+ZWxlbWVudHNbZWxJZHhdID0gSURfTk9ORTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBNYWtlIG5ldyBudW1iZXIgb2YgY2hhbm5lbCBwZXJzaXN0YW50ICovCiAgICAgICAgICAgIHNlbGYtPmFzY0NoYW5uZWxzID0gcGNlLT5OdW1DaGFubmVsczsKICAgICAgICAgICAgLyogSWYgUENFIGlzIG5vdCBmaXJzdCBlbGVtZW50IGNvbmNlYWwgdGhpcyBmcmFtZSB0byBhdm9pZCBpbmNvbnNpc3RlbmNpZXMgKi8KICAgICAgICAgICAgaWYgKCBlbGVtZW50X2NvdW50ICE9IDAgKSB7CiAgICAgICAgICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIHBjZVJlYWQgPSAocmVzdWx0Pj0wKSA/IDEgOiAwOwogICAgICAgIH0KICAgICAgICBicmVhazsKI2VuZGlmIC8qIFRQX1BDRV9FTkFCTEUgKi8KCiAgICAgIGNhc2UgSURfRklMOgogICAgICAgIHsKICAgICAgICAgIGludCBiaXRDbnQgPSBGREtyZWFkQml0cyhicyw0KTsgICAgICAgICAgIC8qIGJzX2NvdW50ICovCgogICAgICAgICAgaWYgKGJpdENudCA9PSAxNSkKICAgICAgICAgIHsKICAgICAgICAgICAgaW50IGVzY19jb3VudCA9IEZES3JlYWRCaXRzKGJzLDgpOyAgICAgLyogYnNfZXNjX2NvdW50ICovCiAgICAgICAgICAgIGJpdENudCA9ICBlc2NfY291bnQgKyAxNDsKICAgICAgICAgIH0KCiAgICAgICAgICAvKiBDb252ZXJ0IHRvIGJpdHMgKi8KICAgICAgICAgIGJpdENudCA8PD0gMzsKCiAgICAgICAgICB3aGlsZSAoYml0Q250ID4gMCkgewogICAgICAgICAgICBFcnJvclN0YXR1cyA9IENBYWNEZWNvZGVyX0V4dFBheWxvYWRQYXJzZShzZWxmLCBicywgJmJpdENudCwgcHJldmlvdXNfZWxlbWVudCwgcHJldmlvdXNfZWxlbWVudF9pbmRleCwgMSk7CiAgICAgICAgICAgIGlmIChFcnJvclN0YXR1cyAhPSBBQUNfREVDX09LKSB7CiAgICAgICAgICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgICBjYXNlIElEX0VYVDoKICAgICAgICB7CiAgICAgICAgICBJTlQgYml0Q250ID0gMDsKCiAgICAgICAgICAvKiBnZXQgdGhlIHJlbWFpbmluZyBiaXRzIG9mIHRoaXMgZnJhbWUgKi8KICAgICAgICAgIGJpdENudCA9IHRyYW5zcG9ydERlY19HZXRBdUJpdHNSZW1haW5pbmcoc2VsZi0+aElucHV0LCAwKTsKCiAgICAgICAgICBpZiAoIChiaXRDbnQgPiAwKSAmJiAoc2VsZi0+ZmxhZ3MgJiBBQ19TQlJfUFJFU0VOVCkgJiYgKHNlbGYtPmZsYWdzICYgKEFDX1VTQUN8QUNfUlNWRDUwfEFDX0VMRHxBQ19EUk0pKSApCiAgICAgICAgICB7CiAgICAgICAgICAgIFNCUl9FUlJPUiBlcnIgPSBTQlJERUNfT0s7CiAgICAgICAgICAgIGludCAgZWxJZHgsIG51bUNoRWxlbWVudHMgPSBlbF9jbnRbSURfU0NFXSArIGVsX2NudFtJRF9DUEVdOwoKICAgICAgICAgICAgZm9yIChlbElkeCA9IDA7IGVsSWR4IDwgbnVtQ2hFbGVtZW50czsgZWxJZHggKz0gMSkKICAgICAgICAgICAgewogICAgICAgICAgICAgIGVyciA9IHNickRlY29kZXJfUGFyc2UgKAogICAgICAgICAgICAgICAgICAgIHNlbGYtPmhTYnJEZWNvZGVyLAogICAgICAgICAgICAgICAgICAgIGJzLAogICAgICAgICAgICAgICAgICAgJmJpdENudCwKICAgICAgICAgICAgICAgICAgICAtMSwKICAgICAgICAgICAgICAgICAgICBzZWxmLT5mbGFncyAmIEFDX1NCUkNSQywKICAgICAgICAgICAgICAgICAgICBzZWxmLT5lbGVtZW50c1tlbElkeF0sCiAgICAgICAgICAgICAgICAgICAgZWxJZHgsCiAgICAgICAgICAgICAgICAgICAgc2VsZi0+ZmxhZ3MgJiBBQ19JTkRFUCApOwoKICAgICAgICAgICAgICBpZiAoZXJyICE9IFNCUkRFQ19PSykgewogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHN3aXRjaCAoZXJyKSB7CiAgICAgICAgICAgIGNhc2UgU0JSREVDX1BBUlNFX0VSUk9SOgogICAgICAgICAgICAgIC8qIENhbiBub3QgZ28gb24gcGFyc2luZyBiZWNhdXNlIHdlIGRvIG5vdAogICAgICAgICAgICAgICAgIGtub3cgdGhlIGxlbmd0aCBvZiB0aGUgU0JSIGV4dGVuc2lvbiBkYXRhLiAqLwogICAgICAgICAgICAgIEZES3B1c2hGb3IoYnMsIGJpdENudCk7CiAgICAgICAgICAgICAgYml0Q250ID0gMDsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBTQlJERUNfT0s6CiAgICAgICAgICAgICAgc2VsZi0+c2JyRW5hYmxlZCA9IDE7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KCgogICAgICAgICAgaWYgKHNlbGYtPmZsYWdzICYgQUNfRFJNKQogICAgICAgICAgewogICAgICAgICAgICBpZiAoKGJpdENudCA9IChJTlQpRkRLZ2V0VmFsaWRCaXRzKGJzKSkgIT0gMCkgewogICAgICAgICAgICAgIEZES3B1c2hCaURpcmVjdGlvbmFsKGJzLCBiaXRDbnQpOwogICAgICAgICAgICB9CiAgICAgICAgICB9CgogICAgICAgICAgaWYgKCAhIChzZWxmLT5mbGFncyAmIChBQ19VU0FDfEFDX1JTVkQ1MHxBQ19EUk0pKSApCiAgICAgICAgICB7CiAgICAgICAgICAgIHdoaWxlICggYml0Q250ID4gNyApIHsKICAgICAgICAgICAgICBFcnJvclN0YXR1cyA9IENBYWNEZWNvZGVyX0V4dFBheWxvYWRQYXJzZShzZWxmLCBicywgJmJpdENudCwgcHJldmlvdXNfZWxlbWVudCwgcHJldmlvdXNfZWxlbWVudF9pbmRleCwgMCk7CiAgICAgICAgICAgICAgaWYgKEVycm9yU3RhdHVzICE9IEFBQ19ERUNfT0spIHsKICAgICAgICAgICAgICAgIHNlbGYtPmZyYW1lT0sgPSAwOwogICAgICAgICAgICAgICAgRXJyb3JTdGF0dXMgPSBBQUNfREVDX1BBUlNFX0VSUk9SOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBJRF9FTkQ6CiAgICAgICAgYnJlYWs7CgogICAgICBkZWZhdWx0OgogICAgICAgIEVycm9yU3RhdHVzID0gQUFDX0RFQ19ERUNPREVfRlJBTUVfRVJST1I7CiAgICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgcHJldmlvdXNfZWxlbWVudCA9IHR5cGU7CiAgICBlbGVtZW50X2NvdW50Kys7CgogIH0gICAvKiB3aGlsZSAoICh0eXBlICE9IElEX0VORCkgLi4uICkgKi8KCiAgaWYgKCAhKGZsYWdzICYgKEFBQ0RFQ19DT05DRUFMfEFBQ0RFQ19GTFVTSCkpICkKICB7CiAgICAvKiBCeXRlIGFsaWdubWVudCB3aXRoIHJlc3BlY3QgdG8gdGhlIGZpcnN0IGJpdCBvZiB0aGUgcmF3X2RhdGFfYmxvY2soKS4gKi8KICAgIHsKICAgICAgRkRLYnl0ZUFsaWduKGJzLCBhdVN0YXJ0QW5jaG9yKTsKICAgIH0KCiAgICAvKiBDaGVjayBpZiBhbGwgYml0cyBvZiB0aGUgcmF3X2RhdGFfYmxvY2soKSBoYXZlIGJlZW4gcmVhZC4gKi8KICAgIGlmICggdHJhbnNwb3J0RGVjX0dldEF1Qml0c1RvdGFsKHNlbGYtPmhJbnB1dCwgMCkgPiAwICkgewogICAgICBJTlQgdW5yZWFkQml0cyA9IHRyYW5zcG9ydERlY19HZXRBdUJpdHNSZW1haW5pbmcoc2VsZi0+aElucHV0LCAwKTsKICAgICAgaWYgKCB1bnJlYWRCaXRzICE9IDAgKSB7CgogICAgICAgIHNlbGYtPmZyYW1lT0sgPSAwOwogICAgICAgIC8qIERvIG5vdCBvdmVyd3JpdGUgY3VycmVudCBlcnJvciAqLwogICAgICAgIGlmIChFcnJvclN0YXR1cyA9PSBBQUNfREVDX09LICYmIHNlbGYtPmZyYW1lT0sgPT0gMCkgewogICAgICAgICAgRXJyb3JTdGF0dXMgPSBBQUNfREVDX1BBUlNFX0VSUk9SOwogICAgICAgIH0KICAgICAgICAvKiBBbHdheXMgcHV0IHRoZSBiaXRidWZmZXIgYXQgdGhlIHJpZ2h0IHBvc2l0aW9uIGFmdGVyIHRoZSBjdXJyZW50IEFjY2VzcyBVbml0LiAqLwogICAgICAgIEZES3B1c2hCaURpcmVjdGlvbmFsKGJzLCB1bnJlYWRCaXRzKTsKICAgICAgfQogICAgfQoKICAgIC8qIENoZWNrIHRoZSBsYXN0IGVsZW1lbnQuIFRoZSB0ZXJtaW5hdG9yIChJRF9FTkQpIGhhcyB0byBiZSB0aGUgbGFzdCBvbmUgKGV2ZW4gaWYgRVIgc3ludGF4IGlzIHVzZWQpLiAqLwogICAgaWYgKCBzZWxmLT5mcmFtZU9LICYmIHR5cGUgIT0gSURfRU5EICkgewogICAgICAvKiBEbyBub3Qgb3ZlcndyaXRlIGN1cnJlbnQgZXJyb3IgKi8KICAgICAgaWYgKEVycm9yU3RhdHVzID09IEFBQ19ERUNfT0spIHsKICAgICAgICBFcnJvclN0YXR1cyA9IEFBQ19ERUNfUEFSU0VfRVJST1I7CiAgICAgIH0KICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7CiAgICB9CiAgfQoKICAvKiBNb3JlIEFBQyBjaGFubmVscyB0aGFuIHNwZWNpZmllZCBieSB0aGUgQVNDIG5vdCBhbGxvd2VkLiAqLwogIGlmICggKGFhY0NoYW5uZWxzID09IDAgfHwgYWFjQ2hhbm5lbHMgPiBzZWxmLT5hYWNDaGFubmVscykgJiYgIShmbGFncyAmIChBQUNERUNfQ09OQ0VBTHxBQUNERUNfRkxVU0gpKSApIHsKICAgIHsKICAgICAgLyogRG8gbm90IG92ZXJ3cml0ZSBjdXJyZW50IGVycm9yICovCiAgICAgIGlmIChFcnJvclN0YXR1cyA9PSBBQUNfREVDX09LKSB7CiAgICAgICAgRXJyb3JTdGF0dXMgPSBBQUNfREVDX0RFQ09ERV9GUkFNRV9FUlJPUjsKICAgICAgfQogICAgICBzZWxmLT5mcmFtZU9LID0gMDsKICAgIH0KICAgIGFhY0NoYW5uZWxzID0gMDsKICB9CiAgZWxzZSBpZiAoIGFhY0NoYW5uZWxzID4gc2VsZi0+YXNjQ2hhbm5lbHMgKSB7CiAgICAvKiBEbyBub3Qgb3ZlcndyaXRlIGN1cnJlbnQgZXJyb3IgKi8KICAgIGlmIChFcnJvclN0YXR1cyA9PSBBQUNfREVDX09LKSB7CiAgICAgIEVycm9yU3RhdHVzID0gQUFDX0RFQ19VTlNVUFBPUlRFRF9GT1JNQVQ7CiAgICB9CiAgICBzZWxmLT5mcmFtZU9LID0gMDsKICAgIGFhY0NoYW5uZWxzID0gMDsKICB9CgogIGlmICggVFJBTlNQT1JUREVDX09LICE9IHRyYW5zcG9ydERlY19DcmNDaGVjayhzZWxmLT5oSW5wdXQpICkKICB7CiAgICBzZWxmLT5mcmFtZU9LPTA7CiAgfQoKICAvKiBzdG9yZSBvciByZXN0b3JlIHRoZSBudW1iZXIgb2YgY2hhbm5lbHMgYW5kIHRoZSBjb3JyZXNwb25kaW5nIGluZm8gKi8KICBpZiAoIHNlbGYtPmZyYW1lT0sgJiYgIShmbGFncyAmKEFBQ0RFQ19DT05DRUFMfEFBQ0RFQ19GTFVTSCkpICkgewogICAgc2VsZi0+YWFjQ2hhbm5lbHNQcmV2ID0gYWFjQ2hhbm5lbHM7ICAvKiBzdG9yZSAqLwogICAgRkRLbWVtY3B5KHNlbGYtPmNoYW5uZWxUeXBlUHJldiwgc2VsZi0+Y2hhbm5lbFR5cGUsICg4KSpzaXplb2YoQVVESU9fQ0hBTk5FTF9UWVBFKSk7ICAvKiBzdG9yZSAqLwogICAgRkRLbWVtY3B5KHNlbGYtPmNoYW5uZWxJbmRpY2VzUHJldiwgc2VsZi0+Y2hhbm5lbEluZGljZXMsICg4KSpzaXplb2YoVUNIQVIpKTsgICAgICAgICAvKiBzdG9yZSAqLwogICAgc2VsZi0+c2JyRW5hYmxlZFByZXYgPSBzZWxmLT5zYnJFbmFibGVkOwogIH0gZWxzZSB7CiAgICBpZiAoc2VsZi0+YWFjQ2hhbm5lbHMgPiAwKSB7CiAgICAgIGFhY0NoYW5uZWxzID0gc2VsZi0+YWFjQ2hhbm5lbHNQcmV2OyAgLyogcmVzdG9yZSAqLwogICAgICBGREttZW1jcHkoc2VsZi0+Y2hhbm5lbFR5cGUsIHNlbGYtPmNoYW5uZWxUeXBlUHJldiwgKDgpKnNpemVvZihBVURJT19DSEFOTkVMX1RZUEUpKTsgIC8qIHJlc3RvcmUgKi8KICAgICAgRkRLbWVtY3B5KHNlbGYtPmNoYW5uZWxJbmRpY2VzLCBzZWxmLT5jaGFubmVsSW5kaWNlc1ByZXYsICg4KSpzaXplb2YoVUNIQVIpKTsgICAgICAgICAvKiByZXN0b3JlICovCiAgICAgIHNlbGYtPnNickVuYWJsZWQgPSBzZWxmLT5zYnJFbmFibGVkUHJldjsKICAgICB9CiAgfQoKICAvKiBVcGRhdGUgbnVtYmVyIG9mIG91dHB1dCBjaGFubmVscyAqLwogIHNlbGYtPnN0cmVhbUluZm8uYWFjTnVtQ2hhbm5lbHMgPSBhYWNDaGFubmVsczsKCiAjaWZkZWYgVFBfUENFX0VOQUJMRQogIGlmIChwY2VSZWFkID09IDEgJiYgQ1Byb2dyYW1Db25maWdfSXNWYWxpZChwY2UpKSB7CiAgICAvKiBTZXQgbWF0cml4IG1peGRvd24gaW5mb3MgaWYgYXZhaWxhYmxlIGZyb20gUENFLiAqLwogICAgcGNtRG14X1NldE1hdHJpeE1peGRvd25Gcm9tUGNlICggc2VsZi0+aFBjbVV0aWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGNlLT5NYXRyaXhNaXhkb3duSW5kZXhQcmVzZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGNlLT5NYXRyaXhNaXhkb3duSW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwY2UtPlBzZXVkb1N1cnJvdW5kRW5hYmxlICk7CiAgfQogI2VuZGlmCgogIC8qIElmIHRoZXJlIGlzIG5vIHZhbGlkIGRhdGEgdG8gdHJhbnNmcm9tIGludG8gdGltZSBkb21haW4sIHJldHVybi4gKi8KICBpZiAoICEgSVNfT1VUUFVUX1ZBTElEKEVycm9yU3RhdHVzKSApIHsKICAgIHJldHVybiBFcnJvclN0YXR1czsKICB9CgogIC8qIFNldHVwIHRoZSBvdXRwdXQgY2hhbm5lbCBtYXBwaW5nLiBUaGUgdGFibGUgYmVsb3cgc2hvd3MgdGhlIGZvdXIgcG9zc2liaWxpdGllczoKICAgKiAgICMgfCBjaENmZyB8IFBDRSB8IGNDaENmZyB8IGNoT3V0TWFwSWR4CiAgICogIC0tLSstLS0tLS0tKy0tLS0tKy0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLQogICAqICAgMSB8ICA+IDAgIHwgIG5vIHwgICAgLSAgIHwgY2hDZmcKICAgKiAgIDIgfCAgIDAgICB8IHllcyB8ICA+IDAgICB8IGNDaENmZwogICAqICAgMyB8ICAgMCAgIHwgeWVzIHwgICAgMCAgIHwgYWFjQ2hhbm5lbHMgfHwgMAogICAqICAgNCB8ICAgMCAgIHwgIG5vIHwgICAgLSAgIHwgYWFjQ2hhbm5lbHMgfHwgMAogICAqICAtLS0rLS0tLS0tLSstLS0tLSstLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0KICAgKiAgV2hlcmUgY2hDZmcgaXMgdGhlIGNoYW5uZWwgY29uZmlndXJhdGlvbiBpbmRleCBmcm9tIEFTQyBhbmQgY0NoQ2ZnIGlzIGEgY29ycmVzcG9uZGluZyBjaENmZwogICAqICBkZXJpdmVkIGZyb20gYSBnaXZlbiBQQ0UuIFRoZSB2YXJpYWJsZSBhYWNDaGFubmVscyByZXByZXNlbnRzIHRoZSBudW1iZXIgb2YgY2hhbm5lbCBmb3VuZAogICAqICBkdXJpbmcgYml0c3RyZWFtIGRlY29kaW5nLiBEdWUgdG8gdGhlIHN0cnVjdHVyZSBvZiB0aGUgbWFwcGluZyB0YWJsZSBpdCBjYW4gb25seSBiZSB1c2VkIGZvcgogICAqICBtYXBwaW5nIGlmIGl0cyB2YWx1ZSBpcyBzbWFsbGVyIHRoYW4gNy4gT3RoZXJ3aXNlIHdlIHVzZSB0aGUgZmFsbGJhY2sgKDApIHdoaWNoIGlzIGEgc2ltcGxlCiAgICogIHBhc3MtdGhyb3VnaC4gVGhlIHBvc3NpYmlsaXR5ICM0IHNob3VsZCBhcHBlYXIgb25seSB3aXRoIE1QRUctMiAoQURUUykgc3RyZWFtcy4gVGhpcyBpcwogICAqICBtb2RlIGlzIGNhbGxlZCAiaW1wbGljaXQgY2hhbm5lbCBtYXBwaW5nIi4KICAgKi8KICBjaE91dE1hcElkeCA9ICgoc2VsZi0+Y2hNYXBJbmRleD09MCkgJiYgKGFhY0NoYW5uZWxzPDcpKSA/IGFhY0NoYW5uZWxzIDogc2VsZi0+Y2hNYXBJbmRleDsKCiAgLyoKICAgIEludmVyc2UgdHJhbnNmb3JtCiAgKi8KICB7CiAgICBpbnQgc3RyaWRlLCBvZmZzZXQsIGM7CgogICAgLyogVHVybiBvbi9vZmYgRFJDIG1vZHVsZXMgbGV2ZWwgbm9ybWFsaXphdGlvbiBpbiBkaWdpdGFsIGRvbWFpbiBkZXBlbmRpbmcgb24gdGhlIGxpbWl0ZXIgc3RhdHVzLiAqLwogICAgYWFjRGVjb2Rlcl9kcmNTZXRQYXJhbSggc2VsZi0+aERyY0luZm8sIEFQUExZX05PUk1BTElaQVRJT04sIChzZWxmLT5saW1pdGVyRW5hYmxlQ3VycikgPyAwIDogMSApOwogICAgLyogRXh0cmFjdCBEUkMgY29udHJvbCBkYXRhIGFuZCBtYXAgaXQgdG8gY2hhbm5lbHMgKHdpdGhvdXQgYml0c3RyZWFtIGRlbGF5KSAqLwogICAgYWFjRGVjb2Rlcl9kcmNQcm9sb2cgKAogICAgICAgICAgICBzZWxmLT5oRHJjSW5mbywKICAgICAgICAgICAgYnMsCiAgICAgICAgICAgIHNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm8sCiAgICAgICAgICAgIHNlbGYtPnBjZS5FbGVtZW50SW5zdGFuY2VUYWcsCiAgICAgICAgICAgIHNlbGYtPmNoTWFwcGluZywKICAgICAgICAgICAgYWFjQ2hhbm5lbHMKICAgICAgICAgICk7CgogICAgLyogImMiIGl0ZXJhdGVzIGluIGNhbm9uaWNhbCBNUEVHIGNoYW5uZWwgb3JkZXIgKi8KICAgIGZvciAoYz0wOyBjIDwgYWFjQ2hhbm5lbHM7IGMrKykKICAgIHsKICAgICAgQ0FhY0RlY29kZXJDaGFubmVsSW5mbyAqcEFhY0RlY29kZXJDaGFubmVsSW5mbzsKCiAgICAgIC8qIFNlbGVjdCBjb3JyZWN0IHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8gZm9yIGN1cnJlbnQgY2hhbm5lbCAqLwogICAgICBpZiAoc2VsZi0+Y2hNYXBwaW5nW2NdID49IGFhY0NoYW5uZWxzKSB7CiAgICAgICAgcEFhY0RlY29kZXJDaGFubmVsSW5mbyA9IHNlbGYtPnBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bY107CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcEFhY0RlY29kZXJDaGFubmVsSW5mbyA9IHNlbGYtPnBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bc2VsZi0+Y2hNYXBwaW5nW2NdXTsKICAgICAgfQoKICAgICAgLyogU2V0dXAgb2Zmc2V0IGFuZCBzdHJpZGUgZm9yIHRpbWUgYnVmZmVyIHRyYXZlcnNhbC4gKi8KICAgICAgaWYgKGludGVybGVhdmVkKSB7CiAgICAgICAgc3RyaWRlID0gYWFjQ2hhbm5lbHM7CiAgICAgICAgb2Zmc2V0ID0gc2VsZi0+Y2hhbm5lbE91dHB1dE1hcHBpbmdbY2hPdXRNYXBJZHhdW2NdOwogICAgICB9IGVsc2UgewogICAgICAgIHN0cmlkZSA9IDE7CiAgICAgICAgb2Zmc2V0ID0gc2VsZi0+Y2hhbm5lbE91dHB1dE1hcHBpbmdbY2hPdXRNYXBJZHhdW2NdICogc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWU7CiAgICAgIH0KCgogICAgICBpZiAoIGZsYWdzJkFBQ0RFQ19GTFVTSCApIHsKICAgICAgICAvKiBDbGVhciBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wU3BlY3RyYWxDb2VmZmljaWVudCBiZWNhdXNlIHdpdGggQUFDREVDX0ZMVVNIIHNldCBpdCBjb250YWlucyB1bmRlZmluZWQgZGF0YS4gKi8KICAgICAgICBGREttZW1jbGVhcihwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5wU3BlY3RyYWxDb2VmZmljaWVudCwgc2l6ZW9mKEZJWFBfREJMKSpzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZXNQZXJGcmFtZSk7CiAgICAgIH0KCiAgICAgIC8qCiAgICAgICAgQ29uY2VhbCBkZWZlY3RpdmUgc3BlY3RyYWwgZGF0YQogICAgICAqLwogICAgICBDQ29uY2VhbG1lbnRfQXBwbHkoJnNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bY10tPmNvbmNlYWxtZW50SW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bY10sCiAgICAgICAgICAgICAgICAgICAgICAgICAmc2VsZi0+c2FtcGxpbmdSYXRlSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZXNQZXJGcmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgIChzZWxmLT5mcmFtZU9LICYmICEoZmxhZ3MmQUFDREVDX0NPTkNFQUwpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5mbGFncwogICAgICAgICAgICAgICAgICAgICAgICApOwoKCiAgICAgIGlmIChmbGFncyAmIChBQUNERUNfSU5UUnxBQUNERUNfQ0xSSElTVCkpIHsKICAgICAgICAvKiBSZXNldCBEUkMgY29udHJvbCBkYXRhIGZvciB0aGlzIGNoYW5uZWwgKi8KICAgICAgICBhYWNEZWNvZGVyX2RyY0luaXRDaGFubmVsRGF0YSAoICZzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NdLT5kcmNEYXRhICk7CiAgICAgIH0KICAgICAgLyogVGhlIERSQyBtb2R1bGUgZGVtYW5kcyB0byBiZSBjYWxsZWQgd2l0aCB0aGUgZ2FpbiBmaWVsZCBob2xkaW5nIHRoZSBnYWluIHNjYWxlLiAqLwogICAgICBzZWxmLT5leHRHYWluWzBdID0gKEZJWFBfREJMKVRETF9HQUlOX1NDQUxJTkc7CiAgICAgIC8qIERSQyBwcm9jZXNzaW5nICovCiAgICAgIGFhY0RlY29kZXJfZHJjQXBwbHkgKAogICAgICAgICAgICAgIHNlbGYtPmhEcmNJbmZvLAogICAgICAgICAgICAgIHNlbGYtPmhTYnJEZWNvZGVyLAogICAgICAgICAgICAgIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8sCiAgICAgICAgICAgICAmc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjXS0+ZHJjRGF0YSwKICAgICAgICAgICAgICBzZWxmLT5leHRHYWluLAogICAgICAgICAgICAgIGMsCiAgICAgICAgICAgICAgc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWUsCiAgICAgICAgICAgICAgc2VsZi0+c2JyRW5hYmxlZAogICAgICAgICAgICApOwoKICAgICAgc3dpdGNoIChwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5yZW5kZXJNb2RlKQogICAgICB7CiAgICAgICAgY2FzZSBBQUNERUNfUkVOREVSX0lNRENUOgogICAgICAgICAgQ0Jsb2NrX0ZyZXF1ZW5jeVRvVGltZSgKICAgICAgICAgICAgICAgICAgc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjXSwKICAgICAgICAgICAgICAgICAgcEFhY0RlY29kZXJDaGFubmVsSW5mbywKICAgICAgICAgICAgICAgICAgcFRpbWVEYXRhICsgb2Zmc2V0LAogICAgICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZXNQZXJGcmFtZSwKICAgICAgICAgICAgICAgICAgc3RyaWRlLAogICAgICAgICAgICAgICAgICAoc2VsZi0+ZnJhbWVPSyAmJiAhKGZsYWdzJkFBQ0RFQ19DT05DRUFMKSksCiAgICAgICAgICAgICAgICAgIHNlbGYtPmFhY0NvbW1vbkRhdGEud29ya0J1ZmZlckNvcmUxLT5tZGN0T3V0VGVtcAogICAgICAgICAgICAgICAgICApOwogICAgICAgICAgc2VsZi0+ZXh0R2FpbkRlbGF5ID0gc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWU7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIEFBQ0RFQ19SRU5ERVJfRUxERkI6CiAgICAgICAgICBDQmxvY2tfRnJlcXVlbmN5VG9UaW1lTG93RGVsYXkoCiAgICAgICAgICAgICAgICAgIHNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bY10sCiAgICAgICAgICAgICAgICAgIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8sCiAgICAgICAgICAgICAgICAgIHBUaW1lRGF0YSArIG9mZnNldCwKICAgICAgICAgICAgICAgICAgc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWUsCiAgICAgICAgICAgICAgICAgIHN0cmlkZQogICAgICAgICAgICAgICAgICApOwogICAgICAgICAgc2VsZi0+ZXh0R2FpbkRlbGF5ID0gKHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlc1BlckZyYW1lKjIgLSAgc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWUvMiAtIDEpLzI7CiAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgRXJyb3JTdGF0dXMgPSBBQUNfREVDX1VOS05PV047CiAgICAgICAgICBicmVhazsKICAgICAgfQogICAgICBpZiAoIGZsYWdzJkFBQ0RFQ19GTFVTSCApIHsKICAgICAgICAgIEZES21lbWNsZWFyKHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBTcGVjdHJhbENvZWZmaWNpZW50LCBzaXplb2YoRklYUF9EQkwpKnNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlc1BlckZyYW1lKTsKICAgICAgICBGREttZW1jbGVhcihzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NdLT5wT3ZlcmxhcEJ1ZmZlciwgT3ZlcmxhcEJ1ZmZlclNpemUqc2l6ZW9mKEZJWFBfREJMKSk7CiAgICAgIH0KICAgIH0KCgogICAgLyogRXh0cmFjdCBEUkMgY29udHJvbCBkYXRhIGFuZCBtYXAgaXQgdG8gY2hhbm5lbHMgKHdpdGggYml0c3RyZWFtIGRlbGF5KSAqLwogICAgYWFjRGVjb2Rlcl9kcmNFcGlsb2cgKAogICAgICAgICAgICBzZWxmLT5oRHJjSW5mbywKICAgICAgICAgICAgYnMsCiAgICAgICAgICAgIHNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm8sCiAgICAgICAgICAgIHNlbGYtPnBjZS5FbGVtZW50SW5zdGFuY2VUYWcsCiAgICAgICAgICAgIHNlbGYtPmNoTWFwcGluZywKICAgICAgICAgICAgYWFjQ2hhbm5lbHMKICAgICAgICAgICk7CiAgfQoKICAvKiBBZGQgYWRkaXRpb25hbCBjb25jZWFsbWVudCBkZWxheSAqLwogIHNlbGYtPnN0cmVhbUluZm8ub3V0cHV0RGVsYXkgKz0gQ0NvbmNlYWxtZW50X0dldERlbGF5KCZzZWxmLT5jb25jZWFsQ29tbW9uRGF0YSkgKiBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZXNQZXJGcmFtZTsKCiAgLyogTWFwIERSQyBkYXRhIHRvIFN0cmVhbUluZm8gc3RydWN0dXJlICovCiAgYWFjRGVjb2Rlcl9kcmNHZXRJbmZvICgKICAgICAgICAgICAgc2VsZi0+aERyY0luZm8sCiAgICAgICAgICAgJnNlbGYtPnN0cmVhbUluZm8uZHJjUHJlc01vZGUsCiAgICAgICAgICAgJnNlbGYtPnN0cmVhbUluZm8uZHJjUHJvZ1JlZkxldgogICAgICAgICAgKTsKCiAgLyogUmVvcmRlciBjaGFubmVsIHR5cGUgaW5mb3JtYXRpb24gdGFibGVzLiAgKi8KICB7CiAgICBBVURJT19DSEFOTkVMX1RZUEUgdHlwZXNbKDgpXTsKICAgIFVDSEFSIGlkeFsoOCldOwogICAgaW50IGM7CgogICAgRkRLX0FTU0VSVChzaXplb2Yoc2VsZi0+Y2hhbm5lbFR5cGUpID09IHNpemVvZih0eXBlcykpOwogICAgRkRLX0FTU0VSVChzaXplb2Yoc2VsZi0+Y2hhbm5lbEluZGljZXMpID09IHNpemVvZihpZHgpKTsKCiAgICBGREttZW1jcHkodHlwZXMsIHNlbGYtPmNoYW5uZWxUeXBlLCBzaXplb2YodHlwZXMpKTsKICAgIEZES21lbWNweShpZHgsIHNlbGYtPmNoYW5uZWxJbmRpY2VzLCBzaXplb2YoaWR4KSk7CgogICAgZm9yIChjPTA7IGM8YWFjQ2hhbm5lbHM7IGMrKykgewogICAgICBzZWxmLT5jaGFubmVsVHlwZVtzZWxmLT5jaGFubmVsT3V0cHV0TWFwcGluZ1tjaE91dE1hcElkeF1bY11dID0gdHlwZXNbY107CiAgICAgIHNlbGYtPmNoYW5uZWxJbmRpY2VzW3NlbGYtPmNoYW5uZWxPdXRwdXRNYXBwaW5nW2NoT3V0TWFwSWR4XVtjXV0gPSBpZHhbY107CiAgICB9CiAgfQoKICBzZWxmLT5ibG9ja051bWJlcisrOwoKICByZXR1cm4gRXJyb3JTdGF0dXM7Cn0KCi8qIQogIFxicmllZiByZXR1cm5zIHRoZSBzdHJlYW1pbmZvIHBvaW50ZXIKCiAgVGhlIGZ1bmN0aW9uIGhhbmRzIGJhY2sgYSBwb2ludGVyIHRvIHRoZSBzdHJlYW1pbmZvIHN0cnVjdHVyZQoKICBccmV0dXJuIHBvaW50ZXIgdG8gdGhlIHN0cnVjdAoqLwpMSU5LU1BFQ19DUFAgQ1N0cmVhbUluZm8qIENBYWNEZWNvZGVyX0dldFN0cmVhbUluZm8gKCBIQU5ETEVfQUFDREVDT0RFUiBzZWxmICkKewogIGlmICghc2VsZikgewogICAgcmV0dXJuIE5VTEw7CiAgfQogIHJldHVybiAmc2VsZi0+c3RyZWFtSW5mbzsKfQoKCgoK