Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUctNCBBQUMgRGVjb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgIEF1dGhvcihzKTogICBKb3NlZiBIb2VwZmwKICAgRGVzY3JpcHRpb246CgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKLyohCiAgXHBhZ2UgZGVmYXVsdCBHZW5lcmFsIE92ZXJ2aWV3IG9mIHRoZSBBQUMgRGVjb2RlciBJbXBsZW1lbnRhdGlvbgoKICBUaGUgbWFpbiBlbnRyeSBwb2ludCB0byBkZWNvZGUgYSBBQUMgZnJhbWUgaXMgQ0FhY0RlY29kZXJfRGVjb2RlRnJhbWUoKS4gSXQgaGFuZGxlcyB0aGUgZGlmZmVyZW50CiAgdHJhbnNwb3J0IG11bHRpcGxleGVzIGFuZCBiaXRzdHJlYW0gZm9ybWF0cyBzdXBwb3J0ZWQgYnkgdGhpcyBpbXBsZW1lbnRhdGlvbi4gSXQgZXh0cmFjdHMgdGhlCiAgQUFDX3Jhd19kYXRhX2Jsb2NrcyBmcm9tIHRoZXNlIGJpdHN0cmVhbXMgdG8gZnVydGhlciBwcm9jZXNzIHRoZW4gaW4gdGhlIGFjdHVhbCBkZWNvZGluZyBzdGFnZXMuCgogIE5vdGU6IENsaWNrIG9uIGEgZnVuY3Rpb24gb2YgZmlsZSBpbiB0aGUgYWJvdmUgaW1hZ2UgdG8gc2VlIGRldGFpbHMgYWJvdXQgdGhlIGZ1bmN0aW9uLiBBbHNvIG5vdGUsIHRoYXQKICB0aGlzIGlzIGp1c3QgYW4gb3ZlcnZpZXcgb2YgdGhlIG1vc3QgaW1wb3J0YW50IGZ1bmN0aW9ucyBhbmQgbm90IGEgY29tcGxldGUgY2FsbCBncmFwaC4KCiAgPGgyPjEgQml0c3RyZWFtIGRlZm9ybWF0dGVyPC9oMj4KICBUaGUgYmFzaWMgYml0IHN0cmVhbSBwYXJzZXIgZnVuY3Rpb24gQ0NoYW5uZWxFbGVtZW50X1JlYWQoKSBpcyBjYWxsZWQuIEl0IHVzZXMgb3RoZXIgc3ViY2FsbHMgaW4gb3JkZXIKICB0byBwYXJzZSBhbmQgdW5wYWNrIHRoZSBiaXRzdHJlYW1zLiBOb3RlLCB0aGF0IHRoaXMgaW5jbHVkZXMgaHVmZm1hbm4gZGVjb2Rpbmcgb2YgdGhlIGNvZGVkIHNwZWN0cmFsIGRhdGEuCiAgVGhpcyBvcGVyYXRpb24gY2FuIGJlIGNvbXB1dGF0aW9uYWwgc2lnbmlmaWNhbnQgc3BlY2lmaWNhbGx5IGF0IGhpZ2hlciBiaXRyYXRlcy4gT3B0aW1pemF0aW9uIGlzIGxpa2VseSBpbgogIENCbG9ja19SZWFkU3BlY3RyYWxEYXRhKCkuCgogIFRoZSBiaXRzdHJlYW0gZGVmb3JtYXR0ZXIgYWxzbyBpbmNsdWRlcyBtYW55IGJpdGZpZWxkIG9wZXJhdGlvbnMuIFByb2ZpbGluZyBvbiB0aGUgdGFyZ2V0IHdpbGwgZGV0ZXJtaW5lCiAgcmVxdWlyZWQgb3B0aW1pemF0aW9ucy4KCiAgPGgyPjIgQWN0dWFsIGRlY29kaW5nIHRvIHJldGFpbiB0aGUgdGltZSBkb21haW4gb3V0cHV0PC9oMj4KICBUaGUgYmFzaWMgYml0c3RyZWFtIGRlZm9ybWF0dGVyIGZ1bmN0aW9uIENDaGFubmVsRWxlbWVudF9EZWNvZGUoKSBmb3IgQ1BFIGVsZW1lbnRzIGFuZCBTQ0UgZWxlbWVudHMgYXJlIGNhbGxlZC4KICBFeGNlcHQgZm9yIHRoZSBzdGVyZW8gcHJvY2Vzc2luZyAoMi4xKSB3aGljaCBpcyBvbmx5IHVzZWQgZm9yIENQRSBlbGVtZW50cywgdGhlIGZ1bmN0aW9uIGNhbGxzIGZvciBDUEUgb3IgU0NFCiAgYXJlIHNpbWlsYXIsIGV4Y2VwdCB0aGF0IENQRSBhbHdheXMgcHJvY2Vzc2VzIHRvIGluZGVwZW5kZW50IGNoYW5uZWxzIHdoaWxlIFNDRSBvbmx5IHByb2Nlc3NlcyBvbmUgY2hhbm5lbC4KCiAgT2Z0ZW4gdGhlcmUgaXMgdGhlIGRpc3RpbmN0aW9uIGJldHdlZW4gbG9uZyBibG9ja3MgYW5kIHNob3J0IGJsb2Nrcy4gSG93ZXZlciwgY29tcHV0YXRpb25hbCBleHBlbnNpdmUgZnVuY3Rpb25zCiAgdGhhdCB1c3VzYWxseSByZXF1aXJlIG9wdGltaXphdGlvbiBhcmUgYmVpbmcgc2hhcmVkIGJ5IHRoZXNlIHR3byBncm91cHMsCgogIDxoMz4yLjEgU3RlcmVvIHByb2Nlc3NpbmcgZm9yIENQRSBlbGVtZW50czwvaDM+CiAgQ0NoYW5uZWxQYWlyRWxlbWVudF9EZWNvZGUoKSBmaXJzdCBjYWxsZXMgdGhlIGpvaW50IHN0ZXJlbyAgdG9vbHMgaW4gc3RlcmVvLmNwcCB3aGVuIHJlcXVpcmVkLgoKICA8aDM+Mi4yIFNjYWxpbmcgb2Ygc3BlY3RyYWwgZGF0YTwvaDM+CiAgQ0Jsb2NrX1NjYWxlU3BlY3RyYWxEYXRhKCkuCgogIDxoMz4yLjMgQXBwbHkgYWRkaXRpb25hbCBjb2RpbmcgdG9vbHM8L2gzPgogIEFwcGx5VG9vbHMoKSBjYWxsZXMgdGhlIFBOUyB0b29scyBpbiBjYXNlIG9mIE1QRUctNCBiaXRzdHJlYW1zLCBhbmQgVE5TIGZpbHRlcmluZyBDVG5zX0FwcGx5KCkgZm9yIE1QRUctMiBhbmQgTVBFRy00IGJpdHN0cmVhbXMuCiAgVGhlIGZ1bmN0aW9uIFRuc0ZpbHRlcklJUigpIHdoaWNoIGlzIGNhbGxlZCBieSBDVG5zX0FwcGx5KCkgKDIuMy4xKSBtaWdodCByZXF1aXJlIHNvbWUgb3B0aW1pemF0aW9uLgoKICA8aDI+MyBGcmVxdWVuY3ktVG8tVGltZSBjb252ZXJzaW9uPC9oMz4KICBUaGUgZmlsdGVyYmFuayBpcyBjYWxsZWQgdXNpbmcgQ0Jsb2NrX0ZyZXF1ZW5jeVRvVGltZSgpIHVzaW5nIHRoZSBNRENUIG1vZHVsZSBmcm9tIHRoZSBGREsgVG9vbHMKCiovCgoKCiNpbmNsdWRlICJhYWNkZWNvZGVyLmgiCgojaW5jbHVkZSAiYWFjX3JvbS5oIgojaW5jbHVkZSAiYWFjX3JhbS5oIgojaW5jbHVkZSAiY2hhbm5lbC5oIgojaW5jbHVkZSAiRkRLX2F1ZGlvLmgiCgojaW5jbHVkZSAiRkRLX3Rvb2xzX3JvbS5oIgoKICAjaW5jbHVkZSAiYWFjZGVjX3Bucy5oIgoKICAjaW5jbHVkZSAic2JyZGVjb2Rlci5oIgoKCgoKICAjaW5jbHVkZSAiYWFjZGVjX2hjci5oIgogICNpbmNsdWRlICJydmxjLmgiCgoKI2luY2x1ZGUgInRwZGVjX2xpYi5oIgoKI2luY2x1ZGUgImNvbmNlYWwuaCIKCgoKI2RlZmluZSBDQU5fRE9fUFMoYW90KSBcCiAgKChhb3QpID09IEFPVF9BQUNfTEMgXAp8fCAoYW90KSA9PSBBT1RfU0JSIFwKfHwgKGFvdCkgPT0gQU9UX1BTIFwKfHwgKGFvdCkgPT0gQU9UX0VSX0JTQUMgXAp8fCAoYW90KSA9PSBBT1RfRFJNX0FBQykKCiNkZWZpbmUgSVNfVVNBQyhhb3QpIFwKICAoKGFvdCkgPT0gQU9UX1VTQUMgXAp8fCAoYW90KSA9PSBBT1RfUlNWRDUwKQoKI2RlZmluZSBJU19MT1dERUxBWShhb3QpIFwKICAoKGFvdCkgPT0gQU9UX0VSX0FBQ19MRCBcCnx8IChhb3QpID09IEFPVF9FUl9BQUNfRUxEKQoKdm9pZCBDQWFjRGVjb2Rlcl9TeW5jUW1mTW9kZShIQU5ETEVfQUFDREVDT0RFUiBzZWxmKQp7CgogIC8qIEFzc2lnbiB1c2VyIHJlcXVlc3RlZCBtb2RlICovCiAgc2VsZi0+cW1mTW9kZUN1cnIgPSBzZWxmLT5xbWZNb2RlVXNlcjsKCiAgaWYgKCBzZWxmLT5xbWZNb2RlQ3VyciA9PSBOT1RfREVGSU5FRCApCiAgewogICAgaWYgKCAoSVNfTE9XREVMQVkoc2VsZi0+c3RyZWFtSW5mby5hb3QpICYmIChzZWxmLT5mbGFncyAmIEFDX01QU19QUkVTRU5UKSkKICAgICAgfHwgKCAoc2VsZi0+c3RyZWFtSW5mby5hYWNOdW1DaGFubmVscyA9PSAxKQogICAgICAgICYmICggKENBTl9ET19QUyhzZWxmLT5zdHJlYW1JbmZvLmFvdCkgJiYgIShzZWxmLT5mbGFncyAmIEFDX01QU19QUkVTRU5UKSkKICAgICAgICAgIHx8ICggIElTX1VTQUMoc2VsZi0+c3RyZWFtSW5mby5hb3QpICYmICAoc2VsZi0+ZmxhZ3MgJiBBQ19NUFNfUFJFU0VOVCkpICkgKSApCiAgICB7CiAgICAgIHNlbGYtPnFtZk1vZGVDdXJyID0gTU9ERV9IUTsKICAgIH0gZWxzZSB7CiAgICAgIHNlbGYtPnFtZk1vZGVDdXJyID0gTU9ERV9MUDsKICAgIH0KICB9CgoKICAvKiBTZXQgU0JSIHRvIGN1cnJlbnQgUU1GIG1vZGUuIEVycm9yIGRvZXMgbm90IG1hdHRlci4gKi8KICBzYnJEZWNvZGVyX1NldFBhcmFtKHNlbGYtPmhTYnJEZWNvZGVyLCBTQlJfUU1GX01PREUsIChzZWxmLT5xbWZNb2RlQ3VyciA9PSBNT0RFX0xQKSk7CiAgc2VsZi0+cHNQb3NzaWJsZSA9ICgoQ0FOX0RPX1BTKHNlbGYtPnN0cmVhbUluZm8uYW90KSAmJiBzZWxmLT5zdHJlYW1JbmZvLmFhY051bUNoYW5uZWxzID09IDEgJiYgISAoc2VsZi0+ZmxhZ3MgJiBBQ19NUFNfUFJFU0VOVCkpKSAmJiBzZWxmLT5xbWZNb2RlQ3VyciA9PSBNT0RFX0hRIDsKICBGREtfQVNTRVJUKCAhICggKHNlbGYtPmZsYWdzICYgQUNfTVBTX1BSRVNFTlQpICYmIHNlbGYtPnBzUG9zc2libGUgKSApOwp9Cgp2b2lkIENBYWNEZWNvZGVyX1NpZ25hbEludGVycnVwdGlvbihIQU5ETEVfQUFDREVDT0RFUiBzZWxmKQp7Cn0KCi8qIQogIFxicmllZiBSZXNldCBhbmNpbGxhcnkgZGF0YSBzdHJ1Y3QuIENhbGwgYmVmb3JlIHBhcnNpbmcgYSBuZXcgZnJhbWUuCgogIFxhbmNEYXRhIFBvaW50ZXIgdG8gYW5jaWxsYXJ5IGRhdGEgc3RydWN0dXJlCgogIFxyZXR1cm4gIEVycm9yIGNvZGUKKi8Kc3RhdGljIEFBQ19ERUNPREVSX0VSUk9SIENBYWNEZWNvZGVyX0FuY0RhdGFSZXNldChDQW5jRGF0YSAqYW5jRGF0YSkKewogIGludCBpOwogIGZvciAoaT0wOyBpPDg7IGkrKykKICB7CiAgICBhbmNEYXRhLT5vZmZzZXRbaV0gPSAwOwogIH0KICBhbmNEYXRhLT5uckVsZW1lbnRzID0gMDsKCiAgcmV0dXJuIEFBQ19ERUNfT0s7Cn0KCi8qIQogIFxicmllZiBJbml0aWFsaXplIGFuY2lsbGFyeSBidWZmZXIKCiAgXGFuY0RhdGEgUG9pbnRlciB0byBhbmNpbGxhcnkgZGF0YSBzdHJ1Y3R1cmUKICBcYnVmZmVyIFBvaW50ZXIgdG8gKGV4dGVybmFsKSBhbmMgZGF0YSBidWZmZXIKICBcc2l6ZSBTaXplIG9mIHRoZSBidWZmZXIgcG9pbnRlZCBvbiBieSBidWZmZXIgaW4gYnl0ZXMKCiAgXHJldHVybiAgRXJyb3IgY29kZQoqLwpBQUNfREVDT0RFUl9FUlJPUiBDQWFjRGVjb2Rlcl9BbmNEYXRhSW5pdChDQW5jRGF0YSAqYW5jRGF0YSwgdW5zaWduZWQgY2hhciAqYnVmZmVyLCBpbnQgc2l6ZSkKewogIGlmIChzaXplID49IDApIHsKICAgIGFuY0RhdGEtPmJ1ZmZlciA9IGJ1ZmZlcjsKICAgIGFuY0RhdGEtPmJ1ZmZlclNpemUgPSBzaXplOwoKICAgIENBYWNEZWNvZGVyX0FuY0RhdGFSZXNldChhbmNEYXRhKTsKCiAgICByZXR1cm4gQUFDX0RFQ19PSzsKICB9CgogIHJldHVybiBBQUNfREVDX0FOQ19EQVRBX0VSUk9SOwp9CgovKiEKICBcYnJpZWYgR2V0IG9uZSBhbmNpbGxhcnkgZGF0YSBlbGVtZW50CgogIFxhbmNEYXRhIFBvaW50ZXIgdG8gYW5jaWxsYXJ5IGRhdGEgc3RydWN0dXJlCiAgXGluZGV4IEluZGV4IG9mIHRoZSBhbmMgZGF0YSBlbGVtZW50IHRvIGdldAogIFxwdHIgUG9pbnRlciB0byBhIGJ1ZmZlciByZWNlaXZpbmcgYSBwb2ludGVyIHRvIHRoZSByZXF1ZXN0ZWQgYW5jIGRhdGEgZWxlbWVudAogIFxzaXplIFBvaW50ZXIgdG8gYSBidWZmZXIgcmVjZWl2aW5nIHRoZSBsZW5ndGggb2YgdGhlIHJlcXVlc3RlZCBhbmMgZGF0YSBlbGVtZW50IGluIGJ5dGVzCgogIFxyZXR1cm4gIEVycm9yIGNvZGUKKi8KQUFDX0RFQ09ERVJfRVJST1IgQ0FhY0RlY29kZXJfQW5jRGF0YUdldChDQW5jRGF0YSAqYW5jRGF0YSwgaW50IGluZGV4LCB1bnNpZ25lZCBjaGFyICoqcHRyLCBpbnQgKnNpemUpCnsKICBBQUNfREVDT0RFUl9FUlJPUiBlcnJvciA9IEFBQ19ERUNfT0s7CgogICpwdHIgID0gTlVMTDsKICAqc2l6ZSA9IDA7CgogIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgOCAmJiBpbmRleCA8IGFuY0RhdGEtPm5yRWxlbWVudHMpCiAgewogICAgKnB0ciAgPSAmYW5jRGF0YS0+YnVmZmVyW2FuY0RhdGEtPm9mZnNldFtpbmRleF1dOwogICAgKnNpemUgPSBhbmNEYXRhLT5vZmZzZXRbaW5kZXgrMV0gLSBhbmNEYXRhLT5vZmZzZXRbaW5kZXhdOwogIH0KCiAgcmV0dXJuIGVycm9yOwp9CgoKLyohCiAgXGJyaWVmIFBhcnNlIGFuY2lsbGFyeSBkYXRhCgogIFxhbmNEYXRhIFBvaW50ZXIgdG8gYW5jaWxsYXJ5IGRhdGEgc3RydWN0dXJlCiAgXGhCcyBIYW5kbGUgdG8gRkRLIGJpdHN0cmVhbQogIFxhbmNCeXRlcyBMZW5ndGggb2YgYW5jaWxsYXJ5IGRhdGEgdG8gcmVhZCBmcm9tIHRoZSBiaXRzdHJlYW0KCiAgXHJldHVybiAgRXJyb3IgY29kZQoqLwpzdGF0aWMKQUFDX0RFQ09ERVJfRVJST1IgQ0FhY0RlY29kZXJfQW5jRGF0YVBhcnNlICgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0FuY0RhdGEgKmFuY0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGhCcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50IGFuY0J5dGVzICkKewogIEFBQ19ERUNPREVSX0VSUk9SIGVycm9yID0gQUFDX0RFQ19PSzsKICBpbnQgcmVhZEJ5dGVzID0gMDsKCiAgaWYgKGFuY0RhdGEtPmJ1ZmZlciAhPSBOVUxMKQogIHsKICAgIGlmIChhbmNCeXRlcyA+IDApIHsKICAgICAgLyogd3JpdGUgYW5jaWxsYXJ5IGRhdGEgdG8gZXh0ZXJuYWwgYnVmZmVyICovCiAgICAgIGludCBvZmZzZXQgPSBhbmNEYXRhLT5vZmZzZXRbYW5jRGF0YS0+bnJFbGVtZW50c107CgogICAgICBpZiAoKG9mZnNldCArIGFuY0J5dGVzKSA+IGFuY0RhdGEtPmJ1ZmZlclNpemUpCiAgICAgIHsKICAgICAgICBlcnJvciA9IEFBQ19ERUNfVE9PX1NNQUxMX0FOQ19CVUZGRVI7CiAgICAgIH0KICAgICAgZWxzZSBpZiAoYW5jRGF0YS0+bnJFbGVtZW50cyA+PSA4LTEpCiAgICAgIHsKICAgICAgICBlcnJvciA9IEFBQ19ERUNfVE9PX01BTllfQU5DX0VMRU1FTlRTOwogICAgICB9CiAgICAgIGVsc2UKICAgICAgewogICAgICAgIGludCBpOwoKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYW5jQnl0ZXM7IGkrKykgewogICAgICAgICAgYW5jRGF0YS0+YnVmZmVyW2krb2Zmc2V0XSA9IEZES3JlYWRCaXRzKGhCcywgOCk7CiAgICAgICAgICByZWFkQnl0ZXMrKzsKICAgICAgICB9CgogICAgICAgIGFuY0RhdGEtPm5yRWxlbWVudHMrKzsKICAgICAgICBhbmNEYXRhLT5vZmZzZXRbYW5jRGF0YS0+bnJFbGVtZW50c10gPSBhbmNCeXRlcyArIGFuY0RhdGEtPm9mZnNldFthbmNEYXRhLT5uckVsZW1lbnRzLTFdOwogICAgICB9CiAgICB9CiAgfQoKICByZWFkQnl0ZXMgPSBhbmNCeXRlcyAtIHJlYWRCeXRlczsKCiAgaWYgKHJlYWRCeXRlcyA+IDApIHsKICAgIC8qIHNraXAgZGF0YSAqLwogICAgRkRLcHVzaEZvcihoQnMsIHJlYWRCeXRlczw8Myk7CiAgfQoKICByZXR1cm4gZXJyb3I7Cn0KCi8qIQogIFxicmllZiBSZWFkIFN0cmVhbSBEYXRhIEVsZW1lbnQKCiAgXGJzIEJpdHN0cmVhbSBIYW5kbGUKCiAgXHJldHVybiAgRXJyb3IgY29kZQoqLwpzdGF0aWMgQUFDX0RFQ09ERVJfRVJST1IgQ0RhdGFTdHJlYW1FbGVtZW50X1JlYWQgKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9BQUNERUNPREVSICAgIHNlbGYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gYnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNIQVIgICAgKmVsZW1lbnRJbnN0YW5jZVRhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVSU5UICAgICAgYWxpZ25tZW50QW5jaG9yICkKewogIEhBTkRMRV9UUkFOU1BPUlRERUMgIHBUcDsKICBDQW5jRGF0YSAqYW5jRGF0YTsKICBBQUNfREVDT0RFUl9FUlJPUiBlcnJvciA9IEFBQ19ERUNfT0s7CiAgVUlOVCBkYXRhU3RhcnQsIGRzZUJpdHM7CiAgaW50IGRhdGFCeXRlQWxpZ25GbGFnLCBjb3VudDsKCiAgRkRLX0FTU0VSVChzZWxmICE9IE5VTEwpOwoKICBhbmNEYXRhID0gJnNlbGYtPmFuY0RhdGE7CiAgcFRwID0gc2VsZi0+aElucHV0OwoKICBpbnQgY3JjUmVnID0gdHJhbnNwb3J0RGVjX0NyY1N0YXJ0UmVnKHBUcCwgMCk7CgogIC8qIEVsZW1lbnQgSW5zdGFuY2UgVGFnICovCiAgKmVsZW1lbnRJbnN0YW5jZVRhZyA9IEZES3JlYWRCaXRzKGJzLDQpOwogIC8qIERhdGEgQnl0ZSBBbGlnbiBGbGFnICovCiAgZGF0YUJ5dGVBbGlnbkZsYWcgPSBGREtyZWFkQml0cyhicywxKTsKCiAgY291bnQgPSBGREtyZWFkQml0cyhicyw4KTsKCiAgaWYgKGNvdW50ID09IDI1NSkgewogICAgY291bnQgKz0gRkRLcmVhZEJpdHMoYnMsOCk7IC8qIEVzY0NvdW50ICovCiAgfQogIGRzZUJpdHMgPSBjb3VudCo4OwoKICBpZiAoZGF0YUJ5dGVBbGlnbkZsYWcpIHsKICAgIEZES2J5dGVBbGlnbihicywgYWxpZ25tZW50QW5jaG9yKTsKICB9CgogIGRhdGFTdGFydCA9IEZES2dldFZhbGlkQml0cyhicyk7CgogIGVycm9yID0gQ0FhY0RlY29kZXJfQW5jRGF0YVBhcnNlKGFuY0RhdGEsIGJzLCBjb3VudCk7CiAgdHJhbnNwb3J0RGVjX0NyY0VuZFJlZyhwVHAsIGNyY1JlZyk7CgogIHsKICAgIC8qIE1vdmUgdG8gdGhlIGJlZ2lubmluZyBvZiB0aGUgZGF0YSBqdW5rICovCiAgICBGREtwdXNoQmFjayhicywgZGF0YVN0YXJ0LUZES2dldFZhbGlkQml0cyhicykpOwoKICAgIC8qIFJlYWQgQW5jIGRhdGEgaWYgYXZhaWxhYmxlICovCiAgICBhYWNEZWNvZGVyX2RyY01hcmtQYXlsb2FkKCBzZWxmLT5oRHJjSW5mbywgYnMsIERWQl9EUkNfQU5DX0RBVEEgKTsKICB9CgogIHsKICAgIFBDTURNWF9FUlJPUiBkbXhFcnIgPSBQQ01ETVhfT0s7CgogICAgLyogTW92ZSB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBkYXRhIGp1bmsgKi8KICAgIEZES3B1c2hCYWNrKGJzLCBkYXRhU3RhcnQtRkRLZ2V0VmFsaWRCaXRzKGJzKSk7CgogICAgLyogUmVhZCBETVggbWV0YS1kYXRhICovCiAgICBkbXhFcnIgPSBwY21EbXhfUGFyc2UgKAogICAgICAgICAgICAgICAgICAgICBzZWxmLT5oUGNtVXRpbHMsCiAgICAgICAgICAgICAgICAgICAgIGJzLAogICAgICAgICAgICAgICAgICAgICBkc2VCaXRzLAogICAgICAgICAgICAgICAgICAgICAwIC8qIG5vdCBtcGVnMiAqLyApOwogICAgfQoKICAvKiBNb3ZlIHRvIHRoZSB2ZXJ5IGVuZCBvZiB0aGUgZWxlbWVudC4gKi8KICBGREtwdXNoQmlEaXJlY3Rpb25hbChicywgRkRLZ2V0VmFsaWRCaXRzKGJzKS1kYXRhU3RhcnQrZHNlQml0cyk7CgogIHJldHVybiBlcnJvcjsKfQoKI2lmZGVmIFRQX1BDRV9FTkFCTEUKLyohCiAgXGJyaWVmIFJlYWQgUHJvZ3JhbSBDb25maWcgRWxlbWVudAoKICBcYnMgQml0c3RyZWFtIEhhbmRsZQogIFxwVHAgVHJhbnNwb3J0IGRlY29kZXIgaGFuZGxlIGZvciBDUkMgaGFuZGxpbmcKICBccGNlIFBvaW50ZXIgdG8gUENFIGJ1ZmZlcgogIFxjaGFubmVsQ29uZmlnIEN1cnJlbnQgY2hhbm5lbCBjb25maWd1cmF0aW9uCiAgXGFsaWduQW5jaG9yIEFuY2hvciBmb3IgYnl0ZSBhbGlnbm1lbnQKCiAgXHJldHVybiAgUENFIHN0YXR1cyAoLTE6IGZhaWwsIDA6IG5vIG5ldyBQQ0UsIDE6IFBDRSB1cGRhdGVkLCAyOiBQQ0UgdXBkYXRlZCBuZWVkIHJlLWNvbmZpZykuCiovCnN0YXRpYyBpbnQgQ1Byb2dyYW1Db25maWdFbGVtZW50X1JlYWQgKAogICAgSEFORExFX0ZES19CSVRTVFJFQU0gYnMsCiAgICBIQU5ETEVfVFJBTlNQT1JUREVDICBwVHAsCiAgICBDUHJvZ3JhbUNvbmZpZyAgICAgICpwY2UsCiAgICBjb25zdCBVSU5UICAgICAgICAgICBjaGFubmVsQ29uZmlnLAogICAgY29uc3QgVUlOVCAgICAgICAgICAgYWxpZ25BbmNob3IgKQp7CiAgaW50IHBjZVN0YXR1cyA9IDA7CiAgaW50IGNyY1JlZzsKCiAgLyogcmVhZCBQQ0UgdG8gdGVtcG9yYWwgYnVmZmVyIGZpcnN0ICovCiAgQ19BTExPQ19TQ1JBVENIX1NUQVJUKHRtcFBjZSwgQ1Byb2dyYW1Db25maWcsIDEpOwoKICBDUHJvZ3JhbUNvbmZpZ19Jbml0KHRtcFBjZSk7CiAgQ1Byb2dyYW1Db25maWdfUmVzZXQodG1wUGNlKTsKCiAgY3JjUmVnID0gdHJhbnNwb3J0RGVjX0NyY1N0YXJ0UmVnKHBUcCwgMCk7CgogIENQcm9ncmFtQ29uZmlnX1JlYWQodG1wUGNlLCBicywgYWxpZ25BbmNob3IpOwoKICB0cmFuc3BvcnREZWNfQ3JjRW5kUmVnKHBUcCwgY3JjUmVnKTsKCiAgaWYgKCAgQ1Byb2dyYW1Db25maWdfSXNWYWxpZCh0bXBQY2UpCiAgICAmJiAodG1wUGNlLT5Qcm9maWxlID09IDEpICkKICB7CiAgICBpZiAoICFwY2UtPmlzVmFsaWQgJiYgKGNoYW5uZWxDb25maWcgPiAwKSApIHsKICAgICAgLyogQ3JlYXRlIGEgc3RhbmRhcmQgY2hhbm5lbCBjb25maWcgUENFIHRvIGNvbXBhcmUgd2l0aCAqLwogICAgICBDUHJvZ3JhbUNvbmZpZ19HZXREZWZhdWx0KCBwY2UsIGNoYW5uZWxDb25maWcgKTsKICAgIH0KCiAgICBpZiAocGNlLT5pc1ZhbGlkKSB7CiAgICAgIC8qIENvbXBhcmUgdGhlIG5ldyBhbmQgdGhlIG9sZCBQQ0UgKHRhZ3MgaWdub3JlZCkgKi8KICAgICAgc3dpdGNoICggQ1Byb2dyYW1Db25maWdfQ29tcGFyZSggcGNlLCB0bXBQY2UgKSApCiAgICAgIHsKICAgICAgY2FzZSAxOiAgLyogQ2hhbm5lbCBjb25maWd1cmF0aW9uIG5vdCBjaGFuZ2VkLiBKdXN0IG5ldyBtZXRhZGF0YS4gKi8KICAgICAgICBGREttZW1jcHkocGNlLCB0bXBQY2UsIHNpemVvZihDUHJvZ3JhbUNvbmZpZykpOyAgICAvKiBTdG9yZSB0aGUgY29tcGxldGUgUENFICovCiAgICAgICAgcGNlU3RhdHVzID0gMTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTmV3IFBDRSBidXQgbm8gY2hhbmdlIG9mIGNvbmZpZyAqLwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDI6ICAvKiBUaGUgbnVtYmVyIG9mIGNoYW5uZWxzIGFyZSBpZGVudGljYWwgYnV0IG5vdCB0aGUgY29uZmlnICovCiAgICAgICAgaWYgKGNoYW5uZWxDb25maWcgPT0gMCkgewogICAgICAgICAgRkRLbWVtY3B5KHBjZSwgdG1wUGNlLCBzaXplb2YoQ1Byb2dyYW1Db25maWcpKTsgIC8qIFN0b3JlIHRoZSBjb21wbGV0ZSBQQ0UgKi8KICAgICAgICAgIHBjZVN0YXR1cyA9IDI7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBEZWNvZGVyIG5lZWRzIHJlLWNvbmZpZ3VyYXRpb24gKi8KICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgLTE6ICAvKiBUaGUgY2hhbm5lbCBjb25maWd1cmF0aW9uIGlzIGNvbXBsZXRlbHkgZGlmZmVyZW50ICovCiAgICAgICAgcGNlU3RhdHVzID0gLTE7ICAvKiBOb3Qgc3VwcG9ydGVkISAqLwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDA6ICAvKiBOb3RoaW5nIHRvIGRvIGJlY2F1c2UgUENFIG1hdGNoZXMgdGhlIG9sZCBvbmUgZXhhY3RseS4gKi8KICAgICAgZGVmYXVsdDoKICAgICAgICAvKiBwY2VTdGF0dXMgPSAwOyAqLwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CiAgfQoKICBDX0FMTE9DX1NDUkFUQ0hfRU5EKHRtcFBjZSwgQ1Byb2dyYW1Db25maWcsIDEpOwoKICByZXR1cm4gcGNlU3RhdHVzOwp9CiNlbmRpZiAvKiBUUF9QQ0VfRU5BQkxFICovCgovKiEKICBcYnJpZWYgUGFyc2UgRXh0ZW5zaW9uIFBheWxvYWQKCiAgXHNlbGYgSGFuZGxlIG9mIEFBQyBkZWNvZGVyCiAgXGNvdW50IFBvaW50ZXIgdG8gYml0IGNvdW50ZXIuCiAgXHByZXZpb3VzX2VsZW1lbnQgSUQgb2YgcHJldmlvdXMgZWxlbWVudCAocmVxdWlyZWQgYnkgc29tZSBleHRlbnNpb24gcGF5bG9hZHMpCgogIFxyZXR1cm4gIEVycm9yIGNvZGUKKi8Kc3RhdGljCkFBQ19ERUNPREVSX0VSUk9SIENBYWNEZWNvZGVyX0V4dFBheWxvYWRQYXJzZSAoSEFORExFX0FBQ0RFQ09ERVIgc2VsZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICpjb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNUDRfRUxFTUVOVF9JRCBwcmV2aW91c19lbGVtZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBlbEluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmSXNGaWxsRWxlbWVudCkKewogIEFBQ19ERUNPREVSX0VSUk9SIGVycm9yID0gQUFDX0RFQ19PSzsKICBFWFRfUEFZTE9BRF9UWVBFIGV4dGVuc2lvbl90eXBlOwogIGludCBieXRlcyA9ICgqY291bnQpID4+IDM7CiAgaW50IGNyY0ZsYWcgPSAwOwoKICBpZiAoKmNvdW50IDwgNCkgewogICAgcmV0dXJuIEFBQ19ERUNfUEFSU0VfRVJST1I7CiAgfSBlbHNlIGlmICgoSU5UKUZES2dldFZhbGlkQml0cyhoQnMpIDwgKmNvdW50KSB7CiAgICByZXR1cm4gQUFDX0RFQ19ERUNPREVfRlJBTUVfRVJST1I7CiAgfQoKICBleHRlbnNpb25fdHlwZSA9IChFWFRfUEFZTE9BRF9UWVBFKSBGREtyZWFkQml0cyhoQnMsIDQpOyAgICAvKiBic19leHRlbnNpb25fdHlwZSAqLwogICpjb3VudCAtPSA0OwoKICBzd2l0Y2ggKGV4dGVuc2lvbl90eXBlKQogIHsKICBjYXNlIEVYVF9EWU5BTUlDX1JBTkdFOgogICAgewogICAgICBJTlQgcmVhZEJpdHMgPSBhYWNEZWNvZGVyX2RyY01hcmtQYXlsb2FkKCBzZWxmLT5oRHJjSW5mbywgaEJzLCBNUEVHX0RSQ19FWFRfREFUQSApOwoKICAgICAgaWYgKHJlYWRCaXRzID4gKmNvdW50KQogICAgICB7IC8qIFJlYWQgdG9vIG11Y2guIFNvbWV0aGluZyB3ZW50IHdyb25nISAqLwogICAgICAgIGVycm9yID0gQUFDX0RFQ19QQVJTRV9FUlJPUjsKICAgICAgfQogICAgICAqY291bnQgLT0gcmVhZEJpdHM7CiAgICB9CiAgICBicmVhazsKCgogIGNhc2UgRVhUX1NCUl9EQVRBX0NSQzoKICAgIGNyY0ZsYWcgPSAxOwogIGNhc2UgRVhUX1NCUl9EQVRBOgogICAgaWYgKElTX0NIQU5ORUxfRUxFTUVOVChwcmV2aW91c19lbGVtZW50KSkgewogICAgICBTQlJfRVJST1Igc2JyRXJyb3I7CgogICAgICBDQWFjRGVjb2Rlcl9TeW5jUW1mTW9kZShzZWxmKTsKCiAgICAgIHNickVycm9yID0gc2JyRGVjb2Rlcl9Jbml0RWxlbWVudCgKICAgICAgICAgICAgICBzZWxmLT5oU2JyRGVjb2RlciwKICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZVJhdGUsCiAgICAgICAgICAgICAgc2VsZi0+c3RyZWFtSW5mby5leHRTYW1wbGluZ1JhdGUsCiAgICAgICAgICAgICAgc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWUsCiAgICAgICAgICAgICAgc2VsZi0+c3RyZWFtSW5mby5hb3QsCiAgICAgICAgICAgICAgcHJldmlvdXNfZWxlbWVudCwKICAgICAgICAgICAgICBlbEluZGV4CiAgICAgICAgICAgICAgKTsKCiAgICAgIGlmIChzYnJFcnJvciA9PSBTQlJERUNfT0spIHsKICAgICAgICBzYnJFcnJvciA9IHNickRlY29kZXJfUGFyc2UgKAogICAgICAgICAgICAgICAgc2VsZi0+aFNickRlY29kZXIsCiAgICAgICAgICAgICAgICBoQnMsCiAgICAgICAgICAgICAgICBjb3VudCwKICAgICAgICAgICAgICAgKmNvdW50LAogICAgICAgICAgICAgICAgY3JjRmxhZywKICAgICAgICAgICAgICAgIHByZXZpb3VzX2VsZW1lbnQsCiAgICAgICAgICAgICAgICBlbEluZGV4LAogICAgICAgICAgICAgICAgc2VsZi0+ZmxhZ3MgJiBBQ19JTkRFUCApOwogICAgICAgIC8qIEVuYWJsZSBTQlIgZm9yIGltcGxpY2l0IFNCUiBzaWduYWxsaW5nLiAqLwogICAgICAgIGlmIChzYnJFcnJvciA9PSBTQlJERUNfT0spIHsKICAgICAgICAgIHNlbGYtPnNickVuYWJsZWQgPSAxOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAvKiBEbyBub3QgdHJ5IHRvIGFwcGx5IFNCUiBiZWNhdXNlIGluaXRpYWxpemluZyB0aGUgZWxlbWVudCBmYWlsZWQuICovCiAgICAgICAgc2VsZi0+c2JyRW5hYmxlZCA9IDA7CiAgICAgIH0KICAgICAgLyogQ2l0YXRpb24gZnJvbSBJU08vSUVDIDE0NDk2LTMgY2hhcHRlciA0LjUuMi4xLjUuMgogICAgICBGaWxsIGVsZW1lbnRzIGNvbnRhaW5pbmcgYW4gZXh0ZW5zaW9uX3BheWxvYWQoKSB3aXRoIGFuIGV4dGVuc2lvbl90eXBlIG9mIEVYVF9TQlJfREFUQQogICAgICBvciBFWFRfU0JSX0RBVEFfQ1JDIHNoYWxsIG5vdCBjb250YWluIGFueSBvdGhlciBleHRlbnNpb25fcGF5bG9hZCBvZiBhbnkgb3RoZXIgZXh0ZW5zaW9uX3R5cGUuCiAgICAgICovCiAgICAgIGlmIChmSXNGaWxsRWxlbWVudCkgewogICAgICAgIEZES3B1c2hCaURpcmVjdGlvbmFsKGhCcywgKmNvdW50KTsKICAgICAgICAqY291bnQgPSAwOwogICAgICB9IGVsc2UgewogICAgICAgIC8qIElmIHRoaXMgaXMgbm90IGEgZmlsbCBlbGVtZW50IHdpdGggYSBrbm93biBsZW5ndGgsIHdlIGFyZSBzY3Jld2VkIGFuIG5vIGZ1cnRoZXIgcGFyc2luZyBtYWtlcyBzZW5zZS4gKi8KICAgICAgICBpZiAoc2JyRXJyb3IgIT0gU0JSREVDX09LKSB7CiAgICAgICAgICBzZWxmLT5mcmFtZU9LID0gMDsKICAgICAgICB9CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIGVycm9yID0gQUFDX0RFQ19QQVJTRV9FUlJPUjsKICAgIH0KICAgIGJyZWFrOwoKICBjYXNlIEVYVF9GSUxMX0RBVEE6CiAgICB7CiAgICAgIGludCB0ZW1wOwoKICAgICAgdGVtcCA9IEZES3JlYWRCaXRzKGhCcyw0KTsKICAgICAgYnl0ZXMtLTsKICAgICAgaWYgKHRlbXAgIT0gMCkgewogICAgICAgIGVycm9yID0gQUFDX0RFQ19QQVJTRV9FUlJPUjsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICB3aGlsZSAoYnl0ZXMgPiAwKSB7CiAgICAgICAgdGVtcCA9IEZES3JlYWRCaXRzKGhCcyw4KTsKICAgICAgICBieXRlcy0tOwogICAgICAgIGlmICh0ZW1wICE9IDB4YTUpIHsKICAgICAgICAgIGVycm9yID0gQUFDX0RFQ19QQVJTRV9FUlJPUjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgfQogICAgICAqY291bnQgPSBieXRlczw8MzsKICAgIH0KICAgIGJyZWFrOwoKICBjYXNlIEVYVF9EQVRBX0VMRU1FTlQ6CiAgICB7CiAgICAgIGludCBkYXRhRWxlbWVudFZlcnNpb247CgogICAgICBkYXRhRWxlbWVudFZlcnNpb24gPSBGREtyZWFkQml0cyhoQnMsNCk7CiAgICAgICpjb3VudCAtPSA0OwogICAgICBpZiAoZGF0YUVsZW1lbnRWZXJzaW9uID09IDApIC8qIEFOQ19EQVRBICovCiAgICAgIHsKICAgICAgICBpbnQgdGVtcCwgZGF0YUVsZW1lbnRMZW5ndGggPSAwOwogICAgICAgIGRvIHsKICAgICAgICAgIHRlbXAgPSBGREtyZWFkQml0cyhoQnMsOCk7CiAgICAgICAgICAqY291bnQgLT0gODsKICAgICAgICAgIGRhdGFFbGVtZW50TGVuZ3RoICs9IHRlbXA7CiAgICAgICAgfSB3aGlsZSAodGVtcCA9PSAyNTUgKTsKCiAgICAgICAgQ0FhY0RlY29kZXJfQW5jRGF0YVBhcnNlKCZzZWxmLT5hbmNEYXRhLCBoQnMsIGRhdGFFbGVtZW50TGVuZ3RoKTsKICAgICAgICAqY291bnQgLT0gKGRhdGFFbGVtZW50TGVuZ3RoPDwzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICAvKiBhbGlnbiA9IDAgKi8KICAgICAgICBlcnJvciA9IEFBQ19ERUNfUEFSU0VfRVJST1I7CiAgICAgICAgZ290byBiYWlsOwogICAgICB9CiAgICB9CiAgICBicmVhazsKCiAgY2FzZSBFWFRfREFUQV9MRU5HVEg6CiAgICBpZiAoICFmSXNGaWxsRWxlbWVudCAgICAgICAgICAvKiBNYWtlcyBubyBzZW5zIHRvIGhhdmUgYW4gYWRkaXRpb25hbCBsZW5ndGggaW4gYSBmaWxsIC4uLiAgICovCiAgICAgICYmIChzZWxmLT5mbGFncyAmIEFDX0VSKSApICAvKiAuLi4gZWxlbWVudCBiZWNhdXNlIHRoaXMgZXh0ZW5zaW9uIHBheWxvYWQgdHlwZSB3YXMgLi4uICAgICovCiAgICB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiAuLi4gY3JlYXRlZCB0byBjaXJjdW12ZW50IHRoZSBtaXNzaW5nIGxlbmd0aCBpbiBFUi1TeW50YXguICovCiAgICAgIGludCBiaXRDbnQsIGxlbiA9IEZES3JlYWRCaXRzKGhCcywgNCk7CiAgICAgICpjb3VudCAtPSA0OwoKICAgICAgaWYgKGxlbiA9PSAxNSkgewogICAgICAgIGludCBhZGRfbGVuID0gRkRLcmVhZEJpdHMoaEJzLCA4KTsKICAgICAgICAqY291bnQgLT0gODsKICAgICAgICBsZW4gKz0gYWRkX2xlbjsKCiAgICAgICAgaWYgKGFkZF9sZW4gPT0gMjU1KSB7CiAgICAgICAgICBsZW4gKz0gRkRLcmVhZEJpdHMoaEJzLCAxNik7CiAgICAgICAgICAqY291bnQgLT0gMTY7CiAgICAgICAgfQogICAgICB9CiAgICAgIGxlbiA8PD0gMzsKICAgICAgYml0Q250ID0gbGVuOwoKICAgICAgaWYgKCAoRVhUX1BBWUxPQURfVFlQRSlGREtyZWFkQml0cyhoQnMsIDQpID09IEVYVF9EQVRBX0xFTkdUSCApIHsKICAgICAgICAvKiBDaGVjayBOT1RFIDI6IFRoZSBleHRlbnNpb25fcGF5bG9hZCgpIGluY2x1ZGVkIGhlcmUgbXVzdAogICAgICAgICAgICAgICAgICAgICAgICAgbm90IGhhdmUgZXh0ZW5zaW9uX3R5cGUgPT0gRVhUX0RBVEFfTEVOR1RILiAqLwogICAgICAgIGVycm9yID0gQUFDX0RFQ19QQVJTRV9FUlJPUjsKICAgICAgfSBlbHNlIHsKICAgICAgICAvKiByZXdpbmQgYW5kIGNhbGwgbXlzZWxmIGFnYWluLiAqLwogICAgICAgIEZES3B1c2hCYWNrKGhCcywgNCk7CgogICAgICAgIGVycm9yID0KICAgICAgICAgIENBYWNEZWNvZGVyX0V4dFBheWxvYWRQYXJzZSAoCiAgICAgICAgICAgICAgICAgIHNlbGYsCiAgICAgICAgICAgICAgICAgIGhCcywKICAgICAgICAgICAgICAgICAmYml0Q250LAogICAgICAgICAgICAgICAgICBwcmV2aW91c19lbGVtZW50LAogICAgICAgICAgICAgICAgICBlbEluZGV4LAogICAgICAgICAgICAgICAgICAwICk7CgogICAgICAgICpjb3VudCAtPSBsZW4gLSBiaXRDbnQ7CiAgICAgIH0KICAgICAgLyogTm90ZTogdGhlIGZhbGwgdGhyb3VnaCBpbiBjYXNlIHRoZSBpZiBzdGF0ZW1lbnQgYWJvdmUgaXMgbm90IHRha2VuIGlzIGludGVudGlvbmFsLiAqLwogICAgICBicmVhazsKICAgIH0KCiAgY2FzZSBFWFRfRklMOgoKICBkZWZhdWx0OgogICAgLyogYWxpZ24gPSA0ICovCiAgICBGREtwdXNoRm9yKGhCcywgKmNvdW50KTsKICAgICpjb3VudCA9IDA7CiAgICBicmVhazsKICB9CgpiYWlsOgogIGlmICggKGVycm9yICE9IEFBQ19ERUNfT0spCiAgICAmJiBmSXNGaWxsRWxlbWVudCApCiAgeyAvKiBTa2lwIHRoZSByZW1haW5pbmcgZXh0ZW5zaW9uIGJ5dGVzICovCiAgICBGREtwdXNoQmlEaXJlY3Rpb25hbChoQnMsICpjb3VudCk7CiAgICAqY291bnQgPSAwOwogICAgLyogUGF0Y2ggZXJyb3IgY29kZSBiZWNhdXNlIGRlY29kaW5nIGNhbiBnbyBvbi4gKi8KICAgIGVycm9yID0gQUFDX0RFQ19PSzsKICAgIC8qIEJlIHN1cmUgdGhhdCBwYXJzaW5nIGVycm9ycyBoYXZlIGJlZW4gc3RvcmVkLiAqLwogIH0KICByZXR1cm4gZXJyb3I7Cn0KCi8qICBTdHJlYW0gQ29uZmlndXJhdGlvbiBhbmQgSW5mb3JtYXRpb24uCgogICAgVGhpcyBjbGFzcyBob2xkcyBjb25maWd1cmF0aW9uIGFuZCBpbmZvcm1hdGlvbiBkYXRhIGZvciBhIHN0cmVhbSB0byBiZSBkZWNvZGVkLiBJdAogICAgcHJvdmlkZXMgdGhlIGNhbGxpbmcgYXBwbGljYXRpb24gYXMgd2VsbCBhcyB0aGUgZGVjb2RlciB3aXRoIHN1YnN0YW50aWFsIGluZm9ybWF0aW9uLAogICAgZS5nLiBwcm9maWxlLCBzYW1wbGluZyByYXRlLCBudW1iZXIgb2YgY2hhbm5lbHMgZm91bmQgaW4gdGhlIGJpdHN0cmVhbSBldGMuCiovCnN0YXRpYwp2b2lkIENTdHJlYW1JbmZvSW5pdChDU3RyZWFtSW5mbyAqcFN0cmVhbUluZm8pCnsKICBwU3RyZWFtSW5mby0+YWFjU2FtcGxlUmF0ZSA9IDA7CiAgcFN0cmVhbUluZm8tPnByb2ZpbGUgPSAtMTsKICBwU3RyZWFtSW5mby0+YW90ID0gQU9UX05PTkU7CgogIHBTdHJlYW1JbmZvLT5jaGFubmVsQ29uZmlnID0gLTE7CiAgcFN0cmVhbUluZm8tPmJpdFJhdGUgPSAwOwogIHBTdHJlYW1JbmZvLT5hYWNTYW1wbGVzUGVyRnJhbWUgPSAwOwoKICBwU3RyZWFtSW5mby0+ZXh0QW90ICA9IEFPVF9OT05FOwogIHBTdHJlYW1JbmZvLT5leHRTYW1wbGluZ1JhdGUgPSAwOwoKICBwU3RyZWFtSW5mby0+ZmxhZ3MgPSAwOwoKICBwU3RyZWFtSW5mby0+ZXBDb25maWcgPSAtMTsgICAvKiBkZWZhdWx0IGlzIG5vIEVSICovCgogIHBTdHJlYW1JbmZvLT5udW1DaGFubmVscyA9IDA7CiAgcFN0cmVhbUluZm8tPnNhbXBsZVJhdGUgPSAwOwogIHBTdHJlYW1JbmZvLT5mcmFtZVNpemUgPSAwOwoKICBwU3RyZWFtSW5mby0+b3V0cHV0RGVsYXkgPSAwOwoKICAvKiBEUkMgKi8KICBwU3RyZWFtSW5mby0+ZHJjUHJvZ1JlZkxldiA9IC0xOyAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNldCBwcm9ncmFtIHJlZmVyZW5jZSBsZXZlbCB0byBub3QgaW5kaWNhdGVkICovCiAgcFN0cmVhbUluZm8tPmRyY1ByZXNNb2RlID0gLTE7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBkZWZhdWx0OiBwcmVzZW50YXRpb24gbW9kZSBub3QgaW5kaWNhdGVkICovCn0KCi8qIQogIFxicmllZiBJbml0aWFsaXphdGlvbiBvZiBBYWNEZWNvZGVyQ2hhbm5lbEluZm8KCiAgVGhlIGZ1bmN0aW9uIGluaXRpYWxpemVzIHRoZSBwb2ludGVycyB0byBBYWNEZWNvZGVyQ2hhbm5lbEluZm8gZm9yIGVhY2ggY2hhbm5lbCwKICBzZXQgdGhlIHN0YXJ0IHZhbHVlcyBmb3Igd2luZG93IHNoYXBlIGFuZCB3aW5kb3cgc2VxdWVuY2Ugb2Ygb3ZlcmxhcCZhZGQgdG8gemVybywKICBzZXQgdGhlIG92ZXJsYXAgYnVmZmVyIHRvIHplcm8gYW5kIGluaXRpYWxpemVzIHRoZSBwb2ludGVycyB0byB0aGUgd2luZG93IGNvZWZmaWNpZW50cy4KICBccGFyYW0gYnNGb3JtYXQgaXMgdGhlIGZvcm1hdCBvZiB0aGUgQUFDIGJpdHN0cmVhbQoKICBccmV0dXJuICBBQUNERUNPREVSIGluc3RhbmNlCiovCkxJTktTUEVDX0NQUCBIQU5ETEVfQUFDREVDT0RFUiBDQWFjRGVjb2Rlcl9PcGVuKFRSQU5TUE9SVF9UWVBFIGJzRm9ybWF0KSAgICAvKiE8IGJpdHN0cmVhbSBmb3JtYXQgKGFkaWYsYWR0cyxsb2FzLC4uLikuICovCnsKICBIQU5ETEVfQUFDREVDT0RFUiBzZWxmOwoKICBzZWxmID0gR2V0QWFjRGVjb2RlcigpOwogIGlmIChzZWxmID09IE5VTEwpIHsKICAgIGdvdG8gYmFpbDsKICB9CgogIC8qIEFzc2lnbiBjaGFubmVsIG1hcHBpbmcgaW5mbyBhcnJheXMgKGRvaW5nIHNvIHJlbW92ZXMgZGVwZW5kZW5jeSBvZiBzZXR0aW5ncyBoZWFkZXIgaW4gQVBJIGhlYWRlcikuICovCiAgc2VsZi0+c3RyZWFtSW5mby5wQ2hhbm5lbEluZGljZXMgPSBzZWxmLT5jaGFubmVsSW5kaWNlczsKICBzZWxmLT5zdHJlYW1JbmZvLnBDaGFubmVsVHlwZSA9IHNlbGYtPmNoYW5uZWxUeXBlOwoKICAvKiBzZXQgZGVmYXVsdCBvdXRwdXQgbW9kZSAqLwogIHNlbGYtPm91dHB1dEludGVybGVhdmVkID0gMTsgIC8qIGludGVybGVhdmVkICovCgogIC8qIGluaXRpYWxpemUgYW5jIGRhdGEgKi8KICBDQWFjRGVjb2Rlcl9BbmNEYXRhSW5pdCgmc2VsZi0+YW5jRGF0YSwgTlVMTCwgMCk7CgogIC8qIGluaXRpYWxpemUgc3RyZWFtIGluZm8gKi8KICBDU3RyZWFtSW5mb0luaXQoJnNlbGYtPnN0cmVhbUluZm8pOwoKICAvKiBpbml0aWFsaXplIGVycm9yIGNvbmNlYWxtZW50IGNvbW1vbiBkYXRhICovCiAgQ0NvbmNlYWxtZW50X0luaXRDb21tb25EYXRhKCZzZWxmLT5jb25jZWFsQ29tbW9uRGF0YSk7CgogIHNlbGYtPmhEcmNJbmZvID0gR2V0RHJjSW5mbygpOwogIGlmIChzZWxmLT5oRHJjSW5mbyA9PSBOVUxMKSB7CiAgICBnb3RvIGJhaWw7CiAgfQogIC8qIEluaXQgY29tbW9uIERSQyBzdHJ1Y3R1cmUgKi8KICBhYWNEZWNvZGVyX2RyY0luaXQoIHNlbGYtPmhEcmNJbmZvICk7CiAgLyogU2V0IGRlZmF1bHQgZnJhbWUgZGVsYXkgKi8KICBhYWNEZWNvZGVyX2RyY1NldFBhcmFtICgKICAgICAgICAgIHNlbGYtPmhEcmNJbmZvLAogICAgICAgICAgRFJDX0JTX0RFTEFZLAogICAgICAgICAgQ0NvbmNlYWxtZW50X0dldERlbGF5KCZzZWxmLT5jb25jZWFsQ29tbW9uRGF0YSkKICAgICAgICApOwoKCiAgc2VsZi0+YWFjQ29tbW9uRGF0YS53b3JrQnVmZmVyQ29yZTEgPSBHZXRXb3JrQnVmZmVyQ29yZTEoKTsKICBzZWxmLT5hYWNDb21tb25EYXRhLndvcmtCdWZmZXJDb3JlMiA9IEdldFdvcmtCdWZmZXJDb3JlMigpOwogIGlmIChzZWxmLT5hYWNDb21tb25EYXRhLndvcmtCdWZmZXJDb3JlMSA9PSBOVUxMCiAgICB8fHNlbGYtPmFhY0NvbW1vbkRhdGEud29ya0J1ZmZlckNvcmUyID09IE5VTEwgKQogICAgZ290byBiYWlsOwoKICByZXR1cm4gc2VsZjsKCmJhaWw6CiAgQ0FhY0RlY29kZXJfQ2xvc2UoIHNlbGYgKTsKCiAgcmV0dXJuIE5VTEw7Cn0KCi8qIERlc3Ryb3kgYWFjIGRlY29kZXIgKi8KTElOS1NQRUNfQ1BQIHZvaWQgQ0FhY0RlY29kZXJfQ2xvc2UoSEFORExFX0FBQ0RFQ09ERVIgc2VsZikKewogIGludCBjaDsKCiAgaWYgKHNlbGYgPT0gTlVMTCkKICAgIHJldHVybjsKCiAgZm9yIChjaD0wOyBjaDwoOCk7IGNoKyspIHsKICAgIGlmIChzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NoXSAhPSBOVUxMKSB7CiAgICAgIGlmIChzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NoXS0+cE92ZXJsYXBCdWZmZXIgIT0gTlVMTCkgewogICAgICAgIEZyZWVPdmVybGFwQnVmZmVyICgmc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjaF0tPnBPdmVybGFwQnVmZmVyKTsKICAgICAgfQogICAgICBpZiAoc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjaF0gIT0gTlVMTCkgewogICAgICAgIEZyZWVBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm8gKCZzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NoXSk7CiAgICAgIH0KICAgIH0KICAgIGlmIChzZWxmLT5wQWFjRGVjb2RlckNoYW5uZWxJbmZvW2NoXSAhPSBOVUxMKSB7CiAgICAgIEZyZWVBYWNEZWNvZGVyQ2hhbm5lbEluZm8gKCZzZWxmLT5wQWFjRGVjb2RlckNoYW5uZWxJbmZvW2NoXSk7CiAgICB9CiAgfQoKICBzZWxmLT5hYWNDaGFubmVscyA9IDA7CgogIGlmIChzZWxmLT5oRHJjSW5mbykgewogICAgRnJlZURyY0luZm8oJnNlbGYtPmhEcmNJbmZvKTsKICB9CgogIGlmIChzZWxmLT5hYWNDb21tb25EYXRhLndvcmtCdWZmZXJDb3JlMSAhPSBOVUxMKSB7CiAgICBGcmVlV29ya0J1ZmZlckNvcmUxICgmc2VsZi0+YWFjQ29tbW9uRGF0YS53b3JrQnVmZmVyQ29yZTEpOwogIH0KICBpZiAoc2VsZi0+YWFjQ29tbW9uRGF0YS53b3JrQnVmZmVyQ29yZTIgIT0gTlVMTCkgewogICAgRnJlZVdvcmtCdWZmZXJDb3JlMiAoJnNlbGYtPmFhY0NvbW1vbkRhdGEud29ya0J1ZmZlckNvcmUyKTsKICB9CgogIEZyZWVBYWNEZWNvZGVyICggJnNlbGYpOwp9CgoKLyohCiAgXGJyaWVmIEluaXRpYWxpemF0aW9uIG9mIGRlY29kZXIgaW5zdGFuY2UKCiAgVGhlIGZ1bmN0aW9uIGluaXRpYWxpemVzIHRoZSBkZWNvZGVyLgoKICBccmV0dXJuICBlcnJvciBzdGF0dXM6IDAgZm9yIHN1Y2Nlc3MsIDw+MCBmb3IgdW5zdXBwb3J0ZWQgY29uZmlndXJhdGlvbnMKKi8KTElOS1NQRUNfQ1BQIEFBQ19ERUNPREVSX0VSUk9SIENBYWNEZWNvZGVyX0luaXQoSEFORExFX0FBQ0RFQ09ERVIgc2VsZiwgY29uc3QgQ1NBdWRpb1NwZWNpZmljQ29uZmlnICphc2MpCnsKICBBQUNfREVDT0RFUl9FUlJPUiBlcnIgPSBBQUNfREVDX09LOwogIElOVCBhc2NDaGFubmVscywgY2gsIGFzY0NoYW5nZWQgPSAwOwoKICBpZiAoIXNlbGYpCiAgICByZXR1cm4gQUFDX0RFQ19JTlZBTElEX0hBTkRMRTsKCiAgLy8gc2V0IHByb2ZpbGUgYW5kIGNoZWNrIGZvciBzdXBwb3J0ZWQgYW90CiAgLy8gbGVhdmUgcHJvZmlsZSBvbiBkZWZhdWx0ICg9LTEpIGZvciBhbGwgb3RoZXIgc3VwcG9ydGVkIE1QRUctNCBhb3QncyBleGNlcHQgYW90PTIgKD1BQUMtTEMpCiAgc3dpdGNoIChhc2MtPm1fYW90KSB7CiAgY2FzZSBBT1RfQUFDX0xDOgogICAgc2VsZi0+c3RyZWFtSW5mby5wcm9maWxlID0gMTsKICAgIGJyZWFrOwoKICBjYXNlIEFPVF9TQlI6CiAgY2FzZSBBT1RfUFM6CiAgY2FzZSBBT1RfRVJfQUFDX0xEOgogIGNhc2UgQU9UX0VSX0FBQ19FTEQ6CiAgICBicmVhazsKCiAgZGVmYXVsdDoKICAgIHJldHVybiBBQUNfREVDX1VOU1VQUE9SVEVEX0FPVDsKICB9CgogIENQcm9ncmFtQ29uZmlnX0luaXQoJnNlbGYtPnBjZSk7CgogIC8qIHNldCBjaGFubmVscyAqLwogIHN3aXRjaCAoYXNjLT5tX2NoYW5uZWxDb25maWd1cmF0aW9uKSB7CiAgY2FzZSAwOgojaWZkZWYgVFBfUENFX0VOQUJMRQogICAgLyogZ2V0IGNoYW5uZWxzIGZyb20gcHJvZ3JhbSBjb25maWcgKEFTQykgKi8KICAgIGlmIChDUHJvZ3JhbUNvbmZpZ19Jc1ZhbGlkKCZhc2MtPm1fcHJvZ3JDb25maWdFbGVtZW50KSkgewogICAgICBhc2NDaGFubmVscyA9IGFzYy0+bV9wcm9nckNvbmZpZ0VsZW1lbnQuTnVtQ2hhbm5lbHM7CiAgICAgIGlmIChhc2NDaGFubmVscyA+IDApIHsKICAgICAgICBpbnQgZWw7CiAgICAgICAgLyogdmFsaWQgbnVtYmVyIG9mIGNoYW5uZWxzIC0+IGNvcHkgcHJvZ3JhbSBjb25maWcgZWxlbWVudCAoUENFKSBmcm9tIEFTQyAqLwogICAgICAgIEZES21lbWNweSgmc2VsZi0+cGNlLCAmYXNjLT5tX3Byb2dyQ29uZmlnRWxlbWVudCwgc2l6ZW9mKENQcm9ncmFtQ29uZmlnKSk7CiAgICAgICAgLyogQnVpbHQgZWxlbWVudCB0YWJsZSAqLwogICAgICAgIGVsID0gQ1Byb2dyYW1Db25maWdfR2V0RWxlbWVudFRhYmxlKCZhc2MtPm1fcHJvZ3JDb25maWdFbGVtZW50LCBzZWxmLT5lbGVtZW50cywgKDgpLCAmc2VsZi0+Y2hNYXBJbmRleCk7CiAgICAgICAgZm9yICg7IGVsPCg4KTsgZWwrKykgewogICAgICAgICAgc2VsZi0+ZWxlbWVudHNbZWxdID0gSURfTk9ORTsKICAgICAgICB9CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEFBQ19ERUNfVU5TVVBQT1JURURfQ0hBTk5FTENPTkZJRzsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgc2VsZi0+Y2hNYXBJbmRleCA9IDA7CiAgICAgIGlmICh0cmFuc3BvcnREZWNfR2V0Rm9ybWF0KHNlbGYtPmhJbnB1dCkgPT0gVFRfTVA0X0FEVFMpIHsKICAgICAgICAvKiBzZXQgZGVmYXVsdCBtYXhfY2hhbm5lbHMgZm9yIG1lbW9yeSBhbGxvY2F0aW9uIGJlY2F1c2UgaW4gaW1wbGljaXQgY2hhbm5lbCBtYXBwaW5nIG1vZGUKICAgICAgICAgICB3ZSBkb24ndCBrbm93IHRoZSBhY3R1YWwgbnVtYmVyIG9mIGNoYW5uZWxzIHVudGlsIHdlIHByb2Nlc3NlZCBhdCBsZWFzdCBvbmUgcmF3X2RhdGFfYmxvY2soKS4gKi8KICAgICAgICBhc2NDaGFubmVscyA9ICg4KTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gQUFDX0RFQ19VTlNVUFBPUlRFRF9DSEFOTkVMQ09ORklHOwogICAgICB9CiAgICB9CiNlbHNlIC8qIFRQX1BDRV9FTkFCTEUgKi8KICAgIHJldHVybiBBQUNfREVDX1VOU1VQUE9SVEVEX0NIQU5ORUxDT05GSUc7CiNlbmRpZiAvKiBUUF9QQ0VfRU5BQkxFICovCiAgICBicmVhazsKICBjYXNlIDE6IGNhc2UgMjogY2FzZSAzOiBjYXNlIDQ6IGNhc2UgNTogY2FzZSA2OgogICAgYXNjQ2hhbm5lbHMgPSBhc2MtPm1fY2hhbm5lbENvbmZpZ3VyYXRpb247CiAgICBicmVhazsKICBjYXNlIDExOgogICAgYXNjQ2hhbm5lbHMgPSA3OwogICAgYnJlYWs7CiAgY2FzZSA3OiBjYXNlIDEyOiBjYXNlIDE0OgogICAgYXNjQ2hhbm5lbHMgPSA4OwogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIHJldHVybiBBQUNfREVDX1VOU1VQUE9SVEVEX0NIQU5ORUxDT05GSUc7CiAgfQoKICBpZiAoYXNjQ2hhbm5lbHMgPiAoOCkpIHsKICAgIHJldHVybiBBQUNfREVDX1VOU1VQUE9SVEVEX0NIQU5ORUxDT05GSUc7CiAgfQoKICAvKiBJbml0aWFsaXplIGNvbnN0YW50IG1hcHBpbmdzIGZvciBjaGFubmVsIGNvbmZpZyAxLTcgKi8KICBpZiAoYXNjLT5tX2NoYW5uZWxDb25maWd1cmF0aW9uID4gMCkgewogICAgaW50IGVsOwogICAgRkRLbWVtY3B5KHNlbGYtPmVsZW1lbnRzLCBlbGVtZW50c1RhYlthc2MtPm1fY2hhbm5lbENvbmZpZ3VyYXRpb24tMV0sIHNpemVvZihNUDRfRUxFTUVOVF9JRCkqRkRLbWluKDcsKDgpKSk7CiAgICBmb3IgKGVsPTc7IGVsPCg4KTsgZWwrKykgewogICAgICBzZWxmLT5lbGVtZW50c1tlbF0gPSBJRF9OT05FOwogICAgfQogICAgZm9yIChjaD0wOyBjaDxhc2NDaGFubmVsczsgY2grKykgewogICAgICBzZWxmLT5jaE1hcHBpbmdbY2hdID0gY2g7CiAgICB9CiAgICBmb3IgKDsgY2g8KDgpOyBjaCsrKSB7CiAgICAgIHNlbGYtPmNoTWFwcGluZ1tjaF0gPSAyNTU7CiAgICB9CiAgICBzZWxmLT5jaE1hcEluZGV4ID0gYXNjLT5tX2NoYW5uZWxDb25maWd1cmF0aW9uOwogIH0KICNpZmRlZiBUUF9QQ0VfRU5BQkxFCiAgZWxzZSB7CiAgICBpZiAoQ1Byb2dyYW1Db25maWdfSXNWYWxpZCgmYXNjLT5tX3Byb2dyQ29uZmlnRWxlbWVudCkpIHsKICAgICAgLyogU2V0IG1hdHJpeCBtaXhkb3duIGluZm9zIGlmIGF2YWlsYWJsZSBmcm9tIFBDRS4gKi8KICAgICAgcGNtRG14X1NldE1hdHJpeE1peGRvd25Gcm9tUGNlICggc2VsZi0+aFBjbVV0aWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc2MtPm1fcHJvZ3JDb25maWdFbGVtZW50Lk1hdHJpeE1peGRvd25JbmRleFByZXNlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzYy0+bV9wcm9nckNvbmZpZ0VsZW1lbnQuTWF0cml4TWl4ZG93bkluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc2MtPm1fcHJvZ3JDb25maWdFbGVtZW50LlBzZXVkb1N1cnJvdW5kRW5hYmxlICk7CiAgICB9CiAgfQogI2VuZGlmCgogIHNlbGYtPnN0cmVhbUluZm8uY2hhbm5lbENvbmZpZyA9IGFzYy0+bV9jaGFubmVsQ29uZmlndXJhdGlvbjsKCiAgaWYgKHNlbGYtPnN0cmVhbUluZm8uYW90ICE9IGFzYy0+bV9hb3QpIHsKICAgIHNlbGYtPnN0cmVhbUluZm8uYW90ID0gYXNjLT5tX2FvdDsKICAgIGFzY0NoYW5nZWQgPSAxOwogIH0KCiAgaWYgKHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlc1BlckZyYW1lICE9IChJTlQpYXNjLT5tX3NhbXBsZXNQZXJGcmFtZSkgewogICAgc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWUgPSBhc2MtPm1fc2FtcGxlc1BlckZyYW1lOwogICAgYXNjQ2hhbmdlZCA9IDE7CiAgfQoKICBzZWxmLT5zdHJlYW1JbmZvLmJpdFJhdGUgICAgICAgICAgICA9IDA7CgogIC8qIFNldCBzeW50YXggZmxhZ3MgKi8KICBzZWxmLT5mbGFncyA9IDA7CgogIHNlbGYtPnN0cmVhbUluZm8uZXh0QW90ICAgICAgICAgICAgICAgPSBhc2MtPm1fZXh0ZW5zaW9uQXVkaW9PYmplY3RUeXBlOwogIHNlbGYtPnN0cmVhbUluZm8uZXh0U2FtcGxpbmdSYXRlICAgICAgPSBhc2MtPm1fZXh0ZW5zaW9uU2FtcGxpbmdGcmVxdWVuY3k7CiAgc2VsZi0+ZmxhZ3MgfD0gKGFzYy0+bV9zYnJQcmVzZW50RmxhZykgPyBBQ19TQlJfUFJFU0VOVCA6IDA7CiAgc2VsZi0+ZmxhZ3MgfD0gKGFzYy0+bV9wc1ByZXNlbnRGbGFnKSA/IEFDX1BTX1BSRVNFTlQgOiAwOwogIHNlbGYtPnNickVuYWJsZWQgPSAwOwoKICAvKiAtLS0tLS0tLS0gdmNiMTEgLS0tLS0tLS0tLS0tICovCiAgc2VsZi0+ZmxhZ3MgfD0gKGFzYy0+bV92Y2IxMUZsYWcpID8gQUNfRVJfVkNCMTEgOiAwOwoKICAvKiAtLS0tLS0tLS0tIHJ2bGMgLS0tLS0tLS0tLS0tICovCiAgc2VsZi0+ZmxhZ3MgfD0gKGFzYy0+bV9ydmxjRmxhZykgPyBBQ19FUl9SVkxDIDogMDsKCiAgLyogLS0tLS0tLS0tLS0gaGNyIC0tLS0tLS0tLS0tLSAqLwogIHNlbGYtPmZsYWdzIHw9IChhc2MtPm1faGNyRmxhZykgPyBBQ19FUl9IQ1IgOiAwOwoKICBpZiAoYXNjLT5tX2FvdCA9PSBBT1RfRVJfQUFDX0VMRCkgewogICAgc2VsZi0+ZmxhZ3MgfD0gIEFDX0VMRDsKICAgIHNlbGYtPmZsYWdzIHw9IChhc2MtPm1fc2MubV9lbGRTcGVjaWZpY0NvbmZpZy5tX3NickNyY0ZsYWcpID8gQUNfU0JSQ1JDIDogMDsKICAgIHNlbGYtPmZsYWdzIHw9IChhc2MtPm1fc2MubV9lbGRTcGVjaWZpY0NvbmZpZy5tX3VzZUxkUW1mVGltZUFsaWduKSA/IEFDX0xEX01QUyA6IDA7CiAgfQogIHNlbGYtPmZsYWdzIHw9IChhc2MtPm1fYW90ID09IEFPVF9FUl9BQUNfTEQpID8gQUNfTEQgOiAwOwogIHNlbGYtPmZsYWdzIHw9IChhc2MtPm1fZXBDb25maWcgPj0gMCkgPyBBQ19FUiA6IDA7CgoKICBpZiAoYXNjLT5tX3NiclByZXNlbnRGbGFnKSB7CiAgICBzZWxmLT5zYnJFbmFibGVkID0gMTsKICAgIHNlbGYtPnNickVuYWJsZWRQcmV2ID0gMTsKICB9CiAgaWYgKGFzYy0+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+ZnJhbWVPSyA9IDE7CgogIC8qIEFueSBzdXBwb3J0ZWQgYmFzZSBsYXllciB2YWxpZCBBVSB3aWxsIHJlcXVpcmUgbW9yZSB0aGFuIDE2IGJpdHMuICovCiAgaWYgKCAodHJhbnNwb3J0RGVjX0dldEF1Qml0c1JlbWFpbmluZyhzZWxmLT5oSW5wdXQsIDApIDwgMTUpICYmIChmbGFncyAmIChBQUNERUNfQ09OQ0VBTHxBQUNERUNfRkxVU0gpKSA9PSAwKSB7CiAgICBzZWxmLT5mcmFtZU9LID0gMDsKICAgIEVycm9yU3RhdHVzID0gQUFDX0RFQ19ERUNPREVfRlJBTUVfRVJST1I7CiAgfQoKCiAgLyogUmVzZXQgUHJvZ3JhbSBDb25maWcgc3RydWN0dXJlICovCiAgcGNlID0gJnNlbGYtPnBjZTsKICBDUHJvZ3JhbUNvbmZpZ19SZXNldChwY2UpOwoKICBDQWFjRGVjb2Rlcl9BbmNEYXRhUmVzZXQoJnNlbGYtPmFuY0RhdGEpOwoKICB7CiAgICBpbnQgY2g7CgogICAgaWYgKHNlbGYtPnN0cmVhbUluZm8uY2hhbm5lbENvbmZpZyA9PSAwKSB7CiAgICAgIC8qIEluaXQgQ2hhbm5lbC9FbGVtZW50IG1hcHBpbmcgdGFibGUgKi8KICAgICAgZm9yIChjaD0wOyBjaDwoOCk7IGNoKyspIHsKICAgICAgICBzZWxmLT5jaE1hcHBpbmdbY2hdID0gMjU1OwogICAgICB9CiAgICAgIGlmICghQ1Byb2dyYW1Db25maWdfSXNWYWxpZChwY2UpKSB7CiAgICAgICAgaW50IGVsOwogICAgICAgIGZvciAoZWw9MDsgZWw8KDgpOyBlbCsrKSB7CiAgICAgICAgICBzZWxmLT5lbGVtZW50c1tlbF0gPSBJRF9OT05FOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KCiAgLyogQ2hlY2sgc2FtcGxpbmcgZnJlcXVlbmN5ICAqLwogIHN3aXRjaCAoIHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlUmF0ZSApIHsKICAgIGNhc2UgMTYwMDA6CiAgICBjYXNlIDEyMDAwOgogICBjYXNlIDExMDI1OgogICBjYXNlICA4MDAwOgogICAgY2FzZSAgNzM1MDoKICAgIGNhc2UgNDgwMDA6CiAgICBjYXNlIDQ0MTAwOgogICAgY2FzZSAzMjAwMDoKICAgIGNhc2UgMjQwMDA6CiAgICBjYXNlIDIyMDUwOgogICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIGlmICggISAoc2VsZi0+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+ZmxhZ3MgJiBBQ19TQlJfUFJFU0VOVCkgJiYgKHNlbGYtPmZsYWdzICYgKEFDX1VTQUN8QUNfUlNWRDUwfEFDX0VMRCkpICkKICAgICAgICAgIHsKICAgICAgICAgICAgU0JSX0VSUk9SIGVyciA9IFNCUkRFQ19PSzsKICAgICAgICAgICAgaW50ICBlbElkeCwgbnVtQ2hFbGVtZW50cyA9IGVsX2NudFtJRF9TQ0VdICsgZWxfY250W0lEX0NQRV07CgogICAgICAgICAgICBmb3IgKGVsSWR4ID0gMDsgZWxJZHggPCBudW1DaEVsZW1lbnRzOyBlbElkeCArPSAxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgZXJyID0gc2JyRGVjb2Rlcl9QYXJzZSAoCiAgICAgICAgICAgICAgICAgICAgc2VsZi0+aFNickRlY29kZXIsCiAgICAgICAgICAgICAgICAgICAgYnMsCiAgICAgICAgICAgICAgICAgICAmYml0Q250LAogICAgICAgICAgICAgICAgICAgIC0xLAogICAgICAgICAgICAgICAgICAgIHNlbGYtPmZsYWdzICYgQUNfU0JSQ1JDLAogICAgICAgICAgICAgICAgICAgIHNlbGYtPmVsZW1lbnRzW2VsSWR4XSwKICAgICAgICAgICAgICAgICAgICBlbElkeCwKICAgICAgICAgICAgICAgICAgICBzZWxmLT5mbGFncyAmIEFDX0lOREVQICk7CgogICAgICAgICAgICAgIGlmIChlcnIgIT0gU0JSREVDX09LKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3dpdGNoIChlcnIpIHsKICAgICAgICAgICAgY2FzZSBTQlJERUNfUEFSU0VfRVJST1I6CiAgICAgICAgICAgICAgLyogQ2FuIG5vdCBnbyBvbiBwYXJzaW5nIGJlY2F1c2Ugd2UgZG8gbm90CiAgICAgICAgICAgICAgICAga25vdyB0aGUgbGVuZ3RoIG9mIHRoZSBTQlIgZXh0ZW5zaW9uIGRhdGEuICovCiAgICAgICAgICAgICAgRkRLcHVzaEZvcihicywgYml0Q250KTsKICAgICAgICAgICAgICBiaXRDbnQgPSAwOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFNCUkRFQ19PSzoKICAgICAgICAgICAgICBzZWxmLT5zYnJFbmFibGVkID0gMTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICBzZWxmLT5mcmFtZU9LID0gMDsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgfQoKCiAgICAgICAgICBpZiAoICEgKHNlbGYtPmZsYWdzICYgKEFDX1VTQUN8QUNfUlNWRDUwfEFDX0RSTSkpICkKICAgICAgICAgIHsKICAgICAgICAgICAgd2hpbGUgKCBiaXRDbnQgPiA3ICkgewogICAgICAgICAgICAgIEVycm9yU3RhdHVzID0gQ0FhY0RlY29kZXJfRXh0UGF5bG9hZFBhcnNlKHNlbGYsIGJzLCAmYml0Q250LCBwcmV2aW91c19lbGVtZW50LCBwcmV2aW91c19lbGVtZW50X2luZGV4LCAwKTsKICAgICAgICAgICAgICBpZiAoRXJyb3JTdGF0dXMgIT0gQUFDX0RFQ19PSykgewogICAgICAgICAgICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7CiAgICAgICAgICAgICAgICBFcnJvclN0YXR1cyA9IEFBQ19ERUNfUEFSU0VfRVJST1I7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgICBjYXNlIElEX0VORDoKICAgICAgICBicmVhazsKCiAgICAgIGRlZmF1bHQ6CiAgICAgICAgRXJyb3JTdGF0dXMgPSBBQUNfREVDX0RFQ09ERV9GUkFNRV9FUlJPUjsKICAgICAgICBzZWxmLT5mcmFtZU9LID0gMDsKICAgICAgICBicmVhazsKICAgIH0KCiAgICBwcmV2aW91c19lbGVtZW50ID0gdHlwZTsKICAgIGVsZW1lbnRfY291bnQrKzsKCiAgfSAgIC8qIHdoaWxlICggKHR5cGUgIT0gSURfRU5EKSAuLi4gKSAqLwoKICBpZiAoICEoZmxhZ3MgJiAoQUFDREVDX0NPTkNFQUx8QUFDREVDX0ZMVVNIKSkgKQogIHsKICAgIC8qIEJ5dGUgYWxpZ25tZW50IHdpdGggcmVzcGVjdCB0byB0aGUgZmlyc3QgYml0IG9mIHRoZSByYXdfZGF0YV9ibG9jaygpLiAqLwogICAgewogICAgICBGREtieXRlQWxpZ24oYnMsIGF1U3RhcnRBbmNob3IpOwogICAgfQoKICAgIC8qIENoZWNrIGlmIGFsbCBiaXRzIG9mIHRoZSByYXdfZGF0YV9ibG9jaygpIGhhdmUgYmVlbiByZWFkLiAqLwogICAgaWYgKCB0cmFuc3BvcnREZWNfR2V0QXVCaXRzVG90YWwoc2VsZi0+aElucHV0LCAwKSA+IDAgKSB7CiAgICAgIElOVCB1bnJlYWRCaXRzID0gdHJhbnNwb3J0RGVjX0dldEF1Qml0c1JlbWFpbmluZyhzZWxmLT5oSW5wdXQsIDApOwogICAgICBpZiAoIHVucmVhZEJpdHMgIT0gMCApIHsKCiAgICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7CiAgICAgICAgLyogRG8gbm90IG92ZXJ3cml0ZSBjdXJyZW50IGVycm9yICovCiAgICAgICAgaWYgKEVycm9yU3RhdHVzID09IEFBQ19ERUNfT0sgJiYgc2VsZi0+ZnJhbWVPSyA9PSAwKSB7CiAgICAgICAgICBFcnJvclN0YXR1cyA9IEFBQ19ERUNfUEFSU0VfRVJST1I7CiAgICAgICAgfQogICAgICAgIC8qIEFsd2F5cyBwdXQgdGhlIGJpdGJ1ZmZlciBhdCB0aGUgcmlnaHQgcG9zaXRpb24gYWZ0ZXIgdGhlIGN1cnJlbnQgQWNjZXNzIFVuaXQuICovCiAgICAgICAgRkRLcHVzaEJpRGlyZWN0aW9uYWwoYnMsIHVucmVhZEJpdHMpOwogICAgICB9CiAgICB9CgogICAgLyogQ2hlY2sgdGhlIGxhc3QgZWxlbWVudC4gVGhlIHRlcm1pbmF0b3IgKElEX0VORCkgaGFzIHRvIGJlIHRoZSBsYXN0IG9uZSAoZXZlbiBpZiBFUiBzeW50YXggaXMgdXNlZCkuICovCiAgICBpZiAoIHNlbGYtPmZyYW1lT0sgJiYgdHlwZSAhPSBJRF9FTkQgKSB7CiAgICAgIC8qIERvIG5vdCBvdmVyd3JpdGUgY3VycmVudCBlcnJvciAqLwogICAgICBpZiAoRXJyb3JTdGF0dXMgPT0gQUFDX0RFQ19PSykgewogICAgICAgIEVycm9yU3RhdHVzID0gQUFDX0RFQ19QQVJTRV9FUlJPUjsKICAgICAgfQogICAgICBzZWxmLT5mcmFtZU9LID0gMDsKICAgIH0KICB9CgogIC8qIE1vcmUgQUFDIGNoYW5uZWxzIHRoYW4gc3BlY2lmaWVkIGJ5IHRoZSBBU0Mgbm90IGFsbG93ZWQuICovCiAgaWYgKCAoYWFjQ2hhbm5lbHMgPT0gMCB8fCBhYWNDaGFubmVscyA+IHNlbGYtPmFhY0NoYW5uZWxzKSAmJiAhKGZsYWdzICYgKEFBQ0RFQ19DT05DRUFMfEFBQ0RFQ19GTFVTSCkpICkgewogICAgewogICAgICAvKiBEbyBub3Qgb3ZlcndyaXRlIGN1cnJlbnQgZXJyb3IgKi8KICAgICAgaWYgKEVycm9yU3RhdHVzID09IEFBQ19ERUNfT0spIHsKICAgICAgICBFcnJvclN0YXR1cyA9IEFBQ19ERUNfREVDT0RFX0ZSQU1FX0VSUk9SOwogICAgICB9CiAgICAgIHNlbGYtPmZyYW1lT0sgPSAwOwogICAgfQogICAgYWFjQ2hhbm5lbHMgPSAwOwogIH0KICBlbHNlIGlmICggYWFjQ2hhbm5lbHMgPiBzZWxmLT5hc2NDaGFubmVscyApIHsKICAgIC8qIERvIG5vdCBvdmVyd3JpdGUgY3VycmVudCBlcnJvciAqLwogICAgaWYgKEVycm9yU3RhdHVzID09IEFBQ19ERUNfT0spIHsKICAgICAgRXJyb3JTdGF0dXMgPSBBQUNfREVDX1VOU1VQUE9SVEVEX0ZPUk1BVDsKICAgIH0KICAgIHNlbGYtPmZyYW1lT0sgPSAwOwogICAgYWFjQ2hhbm5lbHMgPSAwOwogIH0KCiAgaWYgKCBUUkFOU1BPUlRERUNfT0sgIT0gdHJhbnNwb3J0RGVjX0NyY0NoZWNrKHNlbGYtPmhJbnB1dCkgKQogIHsKICAgIHNlbGYtPmZyYW1lT0s9MDsKICB9CgogIC8qIHN0b3JlIG9yIHJlc3RvcmUgdGhlIG51bWJlciBvZiBjaGFubmVscyBhbmQgdGhlIGNvcnJlc3BvbmRpbmcgaW5mbyAqLwogIGlmICggc2VsZi0+ZnJhbWVPSyAmJiAhKGZsYWdzICYoQUFDREVDX0NPTkNFQUx8QUFDREVDX0ZMVVNIKSkgKSB7CiAgICBzZWxmLT5hYWNDaGFubmVsc1ByZXYgPSBhYWNDaGFubmVsczsgIC8qIHN0b3JlICovCiAgICBGREttZW1jcHkoc2VsZi0+Y2hhbm5lbFR5cGVQcmV2LCBzZWxmLT5jaGFubmVsVHlwZSwgKDgpKnNpemVvZihBVURJT19DSEFOTkVMX1RZUEUpKTsgIC8qIHN0b3JlICovCiAgICBGREttZW1jcHkoc2VsZi0+Y2hhbm5lbEluZGljZXNQcmV2LCBzZWxmLT5jaGFubmVsSW5kaWNlcywgKDgpKnNpemVvZihVQ0hBUikpOyAgICAgICAgIC8qIHN0b3JlICovCiAgICBzZWxmLT5zYnJFbmFibGVkUHJldiA9IHNlbGYtPnNickVuYWJsZWQ7CiAgfSBlbHNlIHsKICAgIGlmIChzZWxmLT5hYWNDaGFubmVscyA+IDApIHsKICAgICAgYWFjQ2hhbm5lbHMgPSBzZWxmLT5hYWNDaGFubmVsc1ByZXY7ICAvKiByZXN0b3JlICovCiAgICAgIEZES21lbWNweShzZWxmLT5jaGFubmVsVHlwZSwgc2VsZi0+Y2hhbm5lbFR5cGVQcmV2LCAoOCkqc2l6ZW9mKEFVRElPX0NIQU5ORUxfVFlQRSkpOyAgLyogcmVzdG9yZSAqLwogICAgICBGREttZW1jcHkoc2VsZi0+Y2hhbm5lbEluZGljZXMsIHNlbGYtPmNoYW5uZWxJbmRpY2VzUHJldiwgKDgpKnNpemVvZihVQ0hBUikpOyAgICAgICAgIC8qIHJlc3RvcmUgKi8KICAgICAgc2VsZi0+c2JyRW5hYmxlZCA9IHNlbGYtPnNickVuYWJsZWRQcmV2OwogICAgIH0KICB9CgogIC8qIFVwZGF0ZSBudW1iZXIgb2Ygb3V0cHV0IGNoYW5uZWxzICovCiAgc2VsZi0+c3RyZWFtSW5mby5hYWNOdW1DaGFubmVscyA9IGFhY0NoYW5uZWxzOwoKICNpZmRlZiBUUF9QQ0VfRU5BQkxFCiAgaWYgKHBjZVJlYWQgPT0gMSAmJiBDUHJvZ3JhbUNvbmZpZ19Jc1ZhbGlkKHBjZSkpIHsKICAgIC8qIFNldCBtYXRyaXggbWl4ZG93biBpbmZvcyBpZiBhdmFpbGFibGUgZnJvbSBQQ0UuICovCiAgICBwY21EbXhfU2V0TWF0cml4TWl4ZG93bkZyb21QY2UgKCBzZWxmLT5oUGNtVXRpbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwY2UtPk1hdHJpeE1peGRvd25JbmRleFByZXNlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwY2UtPk1hdHJpeE1peGRvd25JbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBjZS0+UHNldWRvU3Vycm91bmRFbmFibGUgKTsKICB9CiAjZW5kaWYKCiAgLyogSWYgdGhlcmUgaXMgbm8gdmFsaWQgZGF0YSB0byB0cmFuc2Zyb20gaW50byB0aW1lIGRvbWFpbiwgcmV0dXJuLiAqLwogIGlmICggISBJU19PVVRQVVRfVkFMSUQoRXJyb3JTdGF0dXMpICkgewogICAgcmV0dXJuIEVycm9yU3RhdHVzOwogIH0KCiAgLyogU2V0dXAgdGhlIG91dHB1dCBjaGFubmVsIG1hcHBpbmcuIFRoZSB0YWJsZSBiZWxvdyBzaG93cyB0aGUgZm91ciBwb3NzaWJpbGl0aWVzOgogICAqICAgIyB8IGNoQ2ZnIHwgUENFIHwgY0NoQ2ZnIHwgY2hPdXRNYXBJZHgKICAgKiAgLS0tKy0tLS0tLS0rLS0tLS0rLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tCiAgICogICAxIHwgID4gMCAgfCAgbm8gfCAgICAtICAgfCBjaENmZwogICAqICAgMiB8ICAgMCAgIHwgeWVzIHwgID4gMCAgIHwgY0NoQ2ZnCiAgICogICAzIHwgICAwICAgfCB5ZXMgfCAgICAwICAgfCBhYWNDaGFubmVscyB8fCAwCiAgICogICA0IHwgICAwICAgfCAgbm8gfCAgICAtICAgfCBhYWNDaGFubmVscyB8fCAwCiAgICogIC0tLSstLS0tLS0tKy0tLS0tKy0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tLQogICAqICBXaGVyZSBjaENmZyBpcyB0aGUgY2hhbm5lbCBjb25maWd1cmF0aW9uIGluZGV4IGZyb20gQVNDIGFuZCBjQ2hDZmcgaXMgYSBjb3JyZXNwb25kaW5nIGNoQ2ZnCiAgICogIGRlcml2ZWQgZnJvbSBhIGdpdmVuIFBDRS4gVGhlIHZhcmlhYmxlIGFhY0NoYW5uZWxzIHJlcHJlc2VudHMgdGhlIG51bWJlciBvZiBjaGFubmVsIGZvdW5kCiAgICogIGR1cmluZyBiaXRzdHJlYW0gZGVjb2RpbmcuIER1ZSB0byB0aGUgc3RydWN0dXJlIG9mIHRoZSBtYXBwaW5nIHRhYmxlIGl0IGNhbiBvbmx5IGJlIHVzZWQgZm9yCiAgICogIG1hcHBpbmcgaWYgaXRzIHZhbHVlIGlzIHNtYWxsZXIgdGhhbiA3LiBPdGhlcndpc2Ugd2UgdXNlIHRoZSBmYWxsYmFjayAoMCkgd2hpY2ggaXMgYSBzaW1wbGUKICAgKiAgcGFzcy10aHJvdWdoLiBUaGUgcG9zc2liaWxpdHkgIzQgc2hvdWxkIGFwcGVhciBvbmx5IHdpdGggTVBFRy0yIChBRFRTKSBzdHJlYW1zLiBUaGlzIGlzCiAgICogIG1vZGUgaXMgY2FsbGVkICJpbXBsaWNpdCBjaGFubmVsIG1hcHBpbmciLgogICAqLwogIGNoT3V0TWFwSWR4ID0gKChzZWxmLT5jaE1hcEluZGV4PT0wKSAmJiAoYWFjQ2hhbm5lbHM8NykpID8gYWFjQ2hhbm5lbHMgOiBzZWxmLT5jaE1hcEluZGV4OwoKICAvKgogICAgSW52ZXJzZSB0cmFuc2Zvcm0KICAqLwogIHsKICAgIGludCBzdHJpZGUsIG9mZnNldCwgYzsKCiAgICAvKiBUdXJuIG9uL29mZiBEUkMgbW9kdWxlcyBsZXZlbCBub3JtYWxpemF0aW9uIGluIGRpZ2l0YWwgZG9tYWluIGRlcGVuZGluZyBvbiB0aGUgbGltaXRlciBzdGF0dXMuICovCiAgICBhYWNEZWNvZGVyX2RyY1NldFBhcmFtKCBzZWxmLT5oRHJjSW5mbywgQVBQTFlfTk9STUFMSVpBVElPTiwgKHNlbGYtPmxpbWl0ZXJFbmFibGVDdXJyKSA/IDAgOiAxICk7CiAgICAvKiBFeHRyYWN0IERSQyBjb250cm9sIGRhdGEgYW5kIG1hcCBpdCB0byBjaGFubmVscyAod2l0aG91dCBiaXRzdHJlYW0gZGVsYXkpICovCiAgICBhYWNEZWNvZGVyX2RyY1Byb2xvZyAoCiAgICAgICAgICAgIHNlbGYtPmhEcmNJbmZvLAogICAgICAgICAgICBicywKICAgICAgICAgICAgc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mbywKICAgICAgICAgICAgc2VsZi0+cGNlLkVsZW1lbnRJbnN0YW5jZVRhZywKICAgICAgICAgICAgc2VsZi0+Y2hNYXBwaW5nLAogICAgICAgICAgICBhYWNDaGFubmVscwogICAgICAgICAgKTsKCiAgICAvKiAiYyIgaXRlcmF0ZXMgaW4gY2Fub25pY2FsIE1QRUcgY2hhbm5lbCBvcmRlciAqLwogICAgZm9yIChjPTA7IGMgPCBhYWNDaGFubmVsczsgYysrKQogICAgewogICAgICBDQWFjRGVjb2RlckNoYW5uZWxJbmZvICpwQWFjRGVjb2RlckNoYW5uZWxJbmZvOwoKICAgICAgLyogU2VsZWN0IGNvcnJlY3QgcEFhY0RlY29kZXJDaGFubmVsSW5mbyBmb3IgY3VycmVudCBjaGFubmVsICovCiAgICAgIGlmIChzZWxmLT5jaE1hcHBpbmdbY10gPj0gYWFjQ2hhbm5lbHMpIHsKICAgICAgICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvID0gc2VsZi0+cEFhY0RlY29kZXJDaGFubmVsSW5mb1tjXTsKICAgICAgfSBlbHNlIHsKICAgICAgICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvID0gc2VsZi0+cEFhY0RlY29kZXJDaGFubmVsSW5mb1tzZWxmLT5jaE1hcHBpbmdbY11dOwogICAgICB9CgogICAgICAvKiBTZXR1cCBvZmZzZXQgYW5kIHN0cmlkZSBmb3IgdGltZSBidWZmZXIgdHJhdmVyc2FsLiAqLwogICAgICBpZiAoaW50ZXJsZWF2ZWQpIHsKICAgICAgICBzdHJpZGUgPSBhYWNDaGFubmVsczsKICAgICAgICBvZmZzZXQgPSBzZWxmLT5jaGFubmVsT3V0cHV0TWFwcGluZ1tjaE91dE1hcElkeF1bY107CiAgICAgIH0gZWxzZSB7CiAgICAgICAgc3RyaWRlID0gMTsKICAgICAgICBvZmZzZXQgPSBzZWxmLT5jaGFubmVsT3V0cHV0TWFwcGluZ1tjaE91dE1hcElkeF1bY10gKiBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZXNQZXJGcmFtZTsKICAgICAgfQoKCiAgICAgIGlmICggZmxhZ3MmQUFDREVDX0ZMVVNIICkgewogICAgICAgIC8qIENsZWFyIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBTcGVjdHJhbENvZWZmaWNpZW50IGJlY2F1c2Ugd2l0aCBBQUNERUNfRkxVU0ggc2V0IGl0IGNvbnRhaW5zIHVuZGVmaW5lZCBkYXRhLiAqLwogICAgICAgIEZES21lbWNsZWFyKHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnBTcGVjdHJhbENvZWZmaWNpZW50LCBzaXplb2YoRklYUF9EQkwpKnNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlc1BlckZyYW1lKTsKICAgICAgfQoKICAgICAgLyoKICAgICAgICBDb25jZWFsIGRlZmVjdGl2ZSBzcGVjdHJhbCBkYXRhCiAgICAgICovCiAgICAgIENDb25jZWFsbWVudF9BcHBseSgmc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjXS0+Y29uY2VhbG1lbnRJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjXSwKICAgICAgICAgICAgICAgICAgICAgICAgICZzZWxmLT5zYW1wbGluZ1JhdGVJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlc1BlckZyYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgKHNlbGYtPmZyYW1lT0sgJiYgIShmbGFncyZBQUNERUNfQ09OQ0VBTCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPmZsYWdzCiAgICAgICAgICAgICAgICAgICAgICAgICk7CgoKICAgICAgaWYgKGZsYWdzICYgKEFBQ0RFQ19JTlRSfEFBQ0RFQ19DTFJISVNUKSkgewogICAgICAgIC8qIFJlc2V0IERSQyBjb250cm9sIGRhdGEgZm9yIHRoaXMgY2hhbm5lbCAqLwogICAgICAgIGFhY0RlY29kZXJfZHJjSW5pdENoYW5uZWxEYXRhICggJnNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bY10tPmRyY0RhdGEgKTsKICAgICAgfQogICAgICAvKiBUaGUgRFJDIG1vZHVsZSBkZW1hbmRzIHRvIGJlIGNhbGxlZCB3aXRoIHRoZSBnYWluIGZpZWxkIGhvbGRpbmcgdGhlIGdhaW4gc2NhbGUuICovCiAgICAgIHNlbGYtPmV4dEdhaW5bMF0gPSAoRklYUF9EQkwpVERMX0dBSU5fU0NBTElORzsKICAgICAgLyogRFJDIHByb2Nlc3NpbmcgKi8KICAgICAgYWFjRGVjb2Rlcl9kcmNBcHBseSAoCiAgICAgICAgICAgICAgc2VsZi0+aERyY0luZm8sCiAgICAgICAgICAgICAgc2VsZi0+aFNickRlY29kZXIsCiAgICAgICAgICAgICAgcEFhY0RlY29kZXJDaGFubmVsSW5mbywKICAgICAgICAgICAgICZzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NdLT5kcmNEYXRhLAogICAgICAgICAgICAgIHNlbGYtPmV4dEdhaW4sCiAgICAgICAgICAgICAgYywKICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZXNQZXJGcmFtZSwKICAgICAgICAgICAgICBzZWxmLT5zYnJFbmFibGVkCiAgICAgICAgICAgICk7CgogICAgICBzd2l0Y2ggKHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8tPnJlbmRlck1vZGUpCiAgICAgIHsKICAgICAgICBjYXNlIEFBQ0RFQ19SRU5ERVJfSU1EQ1Q6CiAgICAgICAgICBDQmxvY2tfRnJlcXVlbmN5VG9UaW1lKAogICAgICAgICAgICAgICAgICBzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NdLAogICAgICAgICAgICAgICAgICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLAogICAgICAgICAgICAgICAgICBwVGltZURhdGEgKyBvZmZzZXQsCiAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlc1BlckZyYW1lLAogICAgICAgICAgICAgICAgICBzdHJpZGUsCiAgICAgICAgICAgICAgICAgIChzZWxmLT5mcmFtZU9LICYmICEoZmxhZ3MmQUFDREVDX0NPTkNFQUwpKSwKICAgICAgICAgICAgICAgICAgc2VsZi0+YWFjQ29tbW9uRGF0YS53b3JrQnVmZmVyQ29yZTEtPm1kY3RPdXRUZW1wCiAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICBzZWxmLT5leHRHYWluRGVsYXkgPSBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZXNQZXJGcmFtZTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgQUFDREVDX1JFTkRFUl9FTERGQjoKICAgICAgICAgIENCbG9ja19GcmVxdWVuY3lUb1RpbWVMb3dEZWxheSgKICAgICAgICAgICAgICAgICAgc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjXSwKICAgICAgICAgICAgICAgICAgcEFhY0RlY29kZXJDaGFubmVsSW5mbywKICAgICAgICAgICAgICAgICAgcFRpbWVEYXRhICsgb2Zmc2V0LAogICAgICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZXNQZXJGcmFtZSwKICAgICAgICAgICAgICAgICAgc3RyaWRlCiAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICBzZWxmLT5leHRHYWluRGVsYXkgPSAoc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWUqMiAtICBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZXNQZXJGcmFtZS8yIC0gMSkvMjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICBFcnJvclN0YXR1cyA9IEFBQ19ERUNfVU5LTk9XTjsKICAgICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGlmICggZmxhZ3MmQUFDREVDX0ZMVVNIICkgewogICAgICAgICAgRkRLbWVtY2xlYXIocEFhY0RlY29kZXJDaGFubmVsSW5mby0+cFNwZWN0cmFsQ29lZmZpY2llbnQsIHNpemVvZihGSVhQX0RCTCkqc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWUpOwogICAgICAgIEZES21lbWNsZWFyKHNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bY10tPnBPdmVybGFwQnVmZmVyLCBPdmVybGFwQnVmZmVyU2l6ZSpzaXplb2YoRklYUF9EQkwpKTsKICAgICAgfQogICAgfQoKCiAgICAvKiBFeHRyYWN0IERSQyBjb250cm9sIGRhdGEgYW5kIG1hcCBpdCB0byBjaGFubmVscyAod2l0aCBiaXRzdHJlYW0gZGVsYXkpICovCiAgICBhYWNEZWNvZGVyX2RyY0VwaWxvZyAoCiAgICAgICAgICAgIHNlbGYtPmhEcmNJbmZvLAogICAgICAgICAgICBicywKICAgICAgICAgICAgc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mbywKICAgICAgICAgICAgc2VsZi0+cGNlLkVsZW1lbnRJbnN0YW5jZVRhZywKICAgICAgICAgICAgc2VsZi0+Y2hNYXBwaW5nLAogICAgICAgICAgICBhYWNDaGFubmVscwogICAgICAgICAgKTsKICB9CgogIC8qIEFkZCBhZGRpdGlvbmFsIGNvbmNlYWxtZW50IGRlbGF5ICovCiAgc2VsZi0+c3RyZWFtSW5mby5vdXRwdXREZWxheSArPSBDQ29uY2VhbG1lbnRfR2V0RGVsYXkoJnNlbGYtPmNvbmNlYWxDb21tb25EYXRhKSAqIHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlc1BlckZyYW1lOwoKICAvKiBNYXAgRFJDIGRhdGEgdG8gU3RyZWFtSW5mbyBzdHJ1Y3R1cmUgKi8KICBhYWNEZWNvZGVyX2RyY0dldEluZm8gKAogICAgICAgICAgICBzZWxmLT5oRHJjSW5mbywKICAgICAgICAgICAmc2VsZi0+c3RyZWFtSW5mby5kcmNQcmVzTW9kZSwKICAgICAgICAgICAmc2VsZi0+c3RyZWFtSW5mby5kcmNQcm9nUmVmTGV2CiAgICAgICAgICApOwoKICAvKiBSZW9yZGVyIGNoYW5uZWwgdHlwZSBpbmZvcm1hdGlvbiB0YWJsZXMuICAqLwogIHsKICAgIEFVRElPX0NIQU5ORUxfVFlQRSB0eXBlc1soOCldOwogICAgVUNIQVIgaWR4Wyg4KV07CiAgICBpbnQgYzsKCiAgICBGREtfQVNTRVJUKHNpemVvZihzZWxmLT5jaGFubmVsVHlwZSkgPT0gc2l6ZW9mKHR5cGVzKSk7CiAgICBGREtfQVNTRVJUKHNpemVvZihzZWxmLT5jaGFubmVsSW5kaWNlcykgPT0gc2l6ZW9mKGlkeCkpOwoKICAgIEZES21lbWNweSh0eXBlcywgc2VsZi0+Y2hhbm5lbFR5cGUsIHNpemVvZih0eXBlcykpOwogICAgRkRLbWVtY3B5KGlkeCwgc2VsZi0+Y2hhbm5lbEluZGljZXMsIHNpemVvZihpZHgpKTsKCiAgICBmb3IgKGM9MDsgYzxhYWNDaGFubmVsczsgYysrKSB7CiAgICAgIHNlbGYtPmNoYW5uZWxUeXBlW3NlbGYtPmNoYW5uZWxPdXRwdXRNYXBwaW5nW2NoT3V0TWFwSWR4XVtjXV0gPSB0eXBlc1tjXTsKICAgICAgc2VsZi0+Y2hhbm5lbEluZGljZXNbc2VsZi0+Y2hhbm5lbE91dHB1dE1hcHBpbmdbY2hPdXRNYXBJZHhdW2NdXSA9IGlkeFtjXTsKICAgIH0KICB9CgogIHNlbGYtPmJsb2NrTnVtYmVyKys7CgogIHJldHVybiBFcnJvclN0YXR1czsKfQoKLyohCiAgXGJyaWVmIHJldHVybnMgdGhlIHN0cmVhbWluZm8gcG9pbnRlcgoKICBUaGUgZnVuY3Rpb24gaGFuZHMgYmFjayBhIHBvaW50ZXIgdG8gdGhlIHN0cmVhbWluZm8gc3RydWN0dXJlCgogIFxyZXR1cm4gcG9pbnRlciB0byB0aGUgc3RydWN0CiovCkxJTktTUEVDX0NQUCBDU3RyZWFtSW5mbyogQ0FhY0RlY29kZXJfR2V0U3RyZWFtSW5mbyAoIEhBTkRMRV9BQUNERUNPREVSIHNlbGYgKQp7CiAgaWYgKCFzZWxmKSB7CiAgICByZXR1cm4gTlVMTDsKICB9CiAgcmV0dXJuICZzZWxmLT5zdHJlYW1JbmZvOwp9CgoKCgo=