Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUctNCBBQUMgRGVjb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqKioKCiAgIEF1dGhvcihzKTogICBKb3NlZiBIb2VwZmwKICAgRGVzY3JpcHRpb246CgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgoKLyohCiAgXHBhZ2UgZGVmYXVsdCBHZW5lcmFsIE92ZXJ2aWV3IG9mIHRoZSBBQUMgRGVjb2RlciBJbXBsZW1lbnRhdGlvbgoKICBUaGUgbWFpbiBlbnRyeSBwb2ludCB0byBkZWNvZGUgYSBBQUMgZnJhbWUgaXMgQ0FhY0RlY29kZXJfRGVjb2RlRnJhbWUoKS4gSXQgaGFuZGxlcyB0aGUgZGlmZmVyZW50CiAgdHJhbnNwb3J0IG11bHRpcGxleGVzIGFuZCBiaXRzdHJlYW0gZm9ybWF0cyBzdXBwb3J0ZWQgYnkgdGhpcyBpbXBsZW1lbnRhdGlvbi4gSXQgZXh0cmFjdHMgdGhlCiAgQUFDX3Jhd19kYXRhX2Jsb2NrcyBmcm9tIHRoZXNlIGJpdHN0cmVhbXMgdG8gZnVydGhlciBwcm9jZXNzIHRoZW4gaW4gdGhlIGFjdHVhbCBkZWNvZGluZyBzdGFnZXMuCgogIE5vdGU6IENsaWNrIG9uIGEgZnVuY3Rpb24gb2YgZmlsZSBpbiB0aGUgYWJvdmUgaW1hZ2UgdG8gc2VlIGRldGFpbHMgYWJvdXQgdGhlIGZ1bmN0aW9uLiBBbHNvIG5vdGUsIHRoYXQKICB0aGlzIGlzIGp1c3QgYW4gb3ZlcnZpZXcgb2YgdGhlIG1vc3QgaW1wb3J0YW50IGZ1bmN0aW9ucyBhbmQgbm90IGEgY29tcGxldGUgY2FsbCBncmFwaC4KCiAgPGgyPjEgQml0c3RyZWFtIGRlZm9ybWF0dGVyPC9oMj4KICBUaGUgYmFzaWMgYml0IHN0cmVhbSBwYXJzZXIgZnVuY3Rpb24gQ0NoYW5uZWxFbGVtZW50X1JlYWQoKSBpcyBjYWxsZWQuIEl0IHVzZXMgb3RoZXIgc3ViY2FsbHMgaW4gb3JkZXIKICB0byBwYXJzZSBhbmQgdW5wYWNrIHRoZSBiaXRzdHJlYW1zLiBOb3RlLCB0aGF0IHRoaXMgaW5jbHVkZXMgaHVmZm1hbm4gZGVjb2Rpbmcgb2YgdGhlIGNvZGVkIHNwZWN0cmFsIGRhdGEuCiAgVGhpcyBvcGVyYXRpb24gY2FuIGJlIGNvbXB1dGF0aW9uYWwgc2lnbmlmaWNhbnQgc3BlY2lmaWNhbGx5IGF0IGhpZ2hlciBiaXRyYXRlcy4gT3B0aW1pemF0aW9uIGlzIGxpa2VseSBpbgogIENCbG9ja19SZWFkU3BlY3RyYWxEYXRhKCkuCgogIFRoZSBiaXRzdHJlYW0gZGVmb3JtYXR0ZXIgYWxzbyBpbmNsdWRlcyBtYW55IGJpdGZpZWxkIG9wZXJhdGlvbnMuIFByb2ZpbGluZyBvbiB0aGUgdGFyZ2V0IHdpbGwgZGV0ZXJtaW5lCiAgcmVxdWlyZWQgb3B0aW1pemF0aW9ucy4KCiAgPGgyPjIgQWN0dWFsIGRlY29kaW5nIHRvIHJldGFpbiB0aGUgdGltZSBkb21haW4gb3V0cHV0PC9oMj4KICBUaGUgYmFzaWMgYml0c3RyZWFtIGRlZm9ybWF0dGVyIGZ1bmN0aW9uIENDaGFubmVsRWxlbWVudF9EZWNvZGUoKSBmb3IgQ1BFIGVsZW1lbnRzIGFuZCBTQ0UgZWxlbWVudHMgYXJlIGNhbGxlZC4KICBFeGNlcHQgZm9yIHRoZSBzdGVyZW8gcHJvY2Vzc2luZyAoMi4xKSB3aGljaCBpcyBvbmx5IHVzZWQgZm9yIENQRSBlbGVtZW50cywgdGhlIGZ1bmN0aW9uIGNhbGxzIGZvciBDUEUgb3IgU0NFCiAgYXJlIHNpbWlsYXIsIGV4Y2VwdCB0aGF0IENQRSBhbHdheXMgcHJvY2Vzc2VzIHRvIGluZGVwZW5kZW50IGNoYW5uZWxzIHdoaWxlIFNDRSBvbmx5IHByb2Nlc3NlcyBvbmUgY2hhbm5lbC4KCiAgT2Z0ZW4gdGhlcmUgaXMgdGhlIGRpc3RpbmN0aW9uIGJldHdlZW4gbG9uZyBibG9ja3MgYW5kIHNob3J0IGJsb2Nrcy4gSG93ZXZlciwgY29tcHV0YXRpb25hbCBleHBlbnNpdmUgZnVuY3Rpb25zCiAgdGhhdCB1c3VzYWxseSByZXF1aXJlIG9wdGltaXphdGlvbiBhcmUgYmVpbmcgc2hhcmVkIGJ5IHRoZXNlIHR3byBncm91cHMsCgogIDxoMz4yLjEgU3RlcmVvIHByb2Nlc3NpbmcgZm9yIENQRSBlbGVtZW50czwvaDM+CiAgQ0NoYW5uZWxQYWlyRWxlbWVudF9EZWNvZGUoKSBmaXJzdCBjYWxsZXMgdGhlIGpvaW50IHN0ZXJlbyAgdG9vbHMgaW4gc3RlcmVvLmNwcCB3aGVuIHJlcXVpcmVkLgoKICA8aDM+Mi4yIFNjYWxpbmcgb2Ygc3BlY3RyYWwgZGF0YTwvaDM+CiAgQ0Jsb2NrX1NjYWxlU3BlY3RyYWxEYXRhKCkuCgogIDxoMz4yLjMgQXBwbHkgYWRkaXRpb25hbCBjb2RpbmcgdG9vbHM8L2gzPgogIEFwcGx5VG9vbHMoKSBjYWxsZXMgdGhlIFBOUyB0b29scyBpbiBjYXNlIG9mIE1QRUctNCBiaXRzdHJlYW1zLCBhbmQgVE5TIGZpbHRlcmluZyBDVG5zX0FwcGx5KCkgZm9yIE1QRUctMiBhbmQgTVBFRy00IGJpdHN0cmVhbXMuCiAgVGhlIGZ1bmN0aW9uIFRuc0ZpbHRlcklJUigpIHdoaWNoIGlzIGNhbGxlZCBieSBDVG5zX0FwcGx5KCkgKDIuMy4xKSBtaWdodCByZXF1aXJlIHNvbWUgb3B0aW1pemF0aW9uLgoKICA8aDI+MyBGcmVxdWVuY3ktVG8tVGltZSBjb252ZXJzaW9uPC9oMz4KICBUaGUgZmlsdGVyYmFuayBpcyBjYWxsZWQgdXNpbmcgQ0Jsb2NrX0ZyZXF1ZW5jeVRvVGltZSgpIHVzaW5nIHRoZSBNRENUIG1vZHVsZSBmcm9tIHRoZSBGREsgVG9vbHMKCiovCgoKCiNpbmNsdWRlICJhYWNkZWNvZGVyLmgiCgojaW5jbHVkZSAiYWFjX3JvbS5oIgojaW5jbHVkZSAiYWFjX3JhbS5oIgojaW5jbHVkZSAiY2hhbm5lbC5oIgojaW5jbHVkZSAiRkRLX2F1ZGlvLmgiCgojaW5jbHVkZSAiRkRLX3Rvb2xzX3JvbS5oIgoKICAjaW5jbHVkZSAiYWFjZGVjX3Bucy5oIgoKICAjaW5jbHVkZSAic2JyZGVjb2Rlci5oIgoKCgoKICAjaW5jbHVkZSAiYWFjZGVjX2hjci5oIgogICNpbmNsdWRlICJydmxjLmgiCgoKI2luY2x1ZGUgInRwZGVjX2xpYi5oIgoKI2luY2x1ZGUgImNvbmNlYWwuaCIKCgoKI2RlZmluZSBDQU5fRE9fUFMoYW90KSBcCiAgKChhb3QpID09IEFPVF9BQUNfTEMgXAp8fCAoYW90KSA9PSBBT1RfU0JSIFwKfHwgKGFvdCkgPT0gQU9UX1BTIFwKfHwgKGFvdCkgPT0gQU9UX0VSX0JTQUMgXAp8fCAoYW90KSA9PSBBT1RfRFJNX0FBQykKCiNkZWZpbmUgSVNfVVNBQyhhb3QpIFwKICAoKGFvdCkgPT0gQU9UX1VTQUMgXAp8fCAoYW90KSA9PSBBT1RfUlNWRDUwKQoKI2RlZmluZSBJU19MT1dERUxBWShhb3QpIFwKICAoKGFvdCkgPT0gQU9UX0VSX0FBQ19MRCBcCnx8IChhb3QpID09IEFPVF9FUl9BQUNfRUxEKQoKdm9pZCBDQWFjRGVjb2Rlcl9TeW5jUW1mTW9kZShIQU5ETEVfQUFDREVDT0RFUiBzZWxmKQp7CgogIC8qIEFzc2lnbiB1c2VyIHJlcXVlc3RlZCBtb2RlICovCiAgc2VsZi0+cW1mTW9kZUN1cnIgPSBzZWxmLT5xbWZNb2RlVXNlcjsKCiAgaWYgKCBzZWxmLT5xbWZNb2RlQ3VyciA9PSBOT1RfREVGSU5FRCApCiAgewogICAgaWYgKCAoSVNfTE9XREVMQVkoc2VsZi0+c3RyZWFtSW5mby5hb3QpICYmIChzZWxmLT5mbGFncyAmIEFDX01QU19QUkVTRU5UKSkKICAgICAgfHwgKCAoc2VsZi0+c3RyZWFtSW5mby5hYWNOdW1DaGFubmVscyA9PSAxKQogICAgICAgICYmICggKENBTl9ET19QUyhzZWxmLT5zdHJlYW1JbmZvLmFvdCkgJiYgIShzZWxmLT5mbGFncyAmIEFDX01QU19QUkVTRU5UKSkKICAgICAgICAgIHx8ICggIElTX1VTQUMoc2VsZi0+c3RyZWFtSW5mby5hb3QpICYmICAoc2VsZi0+ZmxhZ3MgJiBBQ19NUFNfUFJFU0VOVCkpICkgKSApCiAgICB7CiAgICAgIHNlbGYtPnFtZk1vZGVDdXJyID0gTU9ERV9IUTsKICAgIH0gZWxzZSB7CiAgICAgIHNlbGYtPnFtZk1vZGVDdXJyID0gTU9ERV9MUDsKICAgIH0KICB9CgoKICAvKiBTZXQgU0JSIHRvIGN1cnJlbnQgUU1GIG1vZGUuIEVycm9yIGRvZXMgbm90IG1hdHRlci4gKi8KICBzYnJEZWNvZGVyX1NldFBhcmFtKHNlbGYtPmhTYnJEZWNvZGVyLCBTQlJfUU1GX01PREUsIChzZWxmLT5xbWZNb2RlQ3VyciA9PSBNT0RFX0xQKSk7CiAgc2VsZi0+cHNQb3NzaWJsZSA9ICgoQ0FOX0RPX1BTKHNlbGYtPnN0cmVhbUluZm8uYW90KSAmJiBzZWxmLT5zdHJlYW1JbmZvLmFhY051bUNoYW5uZWxzID09IDEgJiYgISAoc2VsZi0+ZmxhZ3MgJiBBQ19NUFNfUFJFU0VOVCkpKSAmJiBzZWxmLT5xbWZNb2RlQ3VyciA9PSBNT0RFX0hRIDsKICBGREtfQVNTRVJUKCAhICggKHNlbGYtPmZsYWdzICYgQUNfTVBTX1BSRVNFTlQpICYmIHNlbGYtPnBzUG9zc2libGUgKSApOwp9Cgp2b2lkIENBYWNEZWNvZGVyX1NpZ25hbEludGVycnVwdGlvbihIQU5ETEVfQUFDREVDT0RFUiBzZWxmKQp7Cn0KCi8qIQogIFxicmllZiBSZXNldCBhbmNpbGxhcnkgZGF0YSBzdHJ1Y3QuIENhbGwgYmVmb3JlIHBhcnNpbmcgYSBuZXcgZnJhbWUuCgogIFxhbmNEYXRhIFBvaW50ZXIgdG8gYW5jaWxsYXJ5IGRhdGEgc3RydWN0dXJlCgogIFxyZXR1cm4gIEVycm9yIGNvZGUKKi8Kc3RhdGljIEFBQ19ERUNPREVSX0VSUk9SIENBYWNEZWNvZGVyX0FuY0RhdGFSZXNldChDQW5jRGF0YSAqYW5jRGF0YSkKewogIGludCBpOwogIGZvciAoaT0wOyBpPDg7IGkrKykKICB7CiAgICBhbmNEYXRhLT5vZmZzZXRbaV0gPSAwOwogIH0KICBhbmNEYXRhLT5uckVsZW1lbnRzID0gMDsKCiAgcmV0dXJuIEFBQ19ERUNfT0s7Cn0KCi8qIQogIFxicmllZiBJbml0aWFsaXplIGFuY2lsbGFyeSBidWZmZXIKCiAgXGFuY0RhdGEgUG9pbnRlciB0byBhbmNpbGxhcnkgZGF0YSBzdHJ1Y3R1cmUKICBcYnVmZmVyIFBvaW50ZXIgdG8gKGV4dGVybmFsKSBhbmMgZGF0YSBidWZmZXIKICBcc2l6ZSBTaXplIG9mIHRoZSBidWZmZXIgcG9pbnRlZCBvbiBieSBidWZmZXIgaW4gYnl0ZXMKCiAgXHJldHVybiAgRXJyb3IgY29kZQoqLwpBQUNfREVDT0RFUl9FUlJPUiBDQWFjRGVjb2Rlcl9BbmNEYXRhSW5pdChDQW5jRGF0YSAqYW5jRGF0YSwgdW5zaWduZWQgY2hhciAqYnVmZmVyLCBpbnQgc2l6ZSkKewogIGlmIChzaXplID49IDApIHsKICAgIGFuY0RhdGEtPmJ1ZmZlciA9IGJ1ZmZlcjsKICAgIGFuY0RhdGEtPmJ1ZmZlclNpemUgPSBzaXplOwoKICAgIENBYWNEZWNvZGVyX0FuY0RhdGFSZXNldChhbmNEYXRhKTsKCiAgICByZXR1cm4gQUFDX0RFQ19PSzsKICB9CgogIHJldHVybiBBQUNfREVDX0FOQ19EQVRBX0VSUk9SOwp9CgovKiEKICBcYnJpZWYgR2V0IG9uZSBhbmNpbGxhcnkgZGF0YSBlbGVtZW50CgogIFxhbmNEYXRhIFBvaW50ZXIgdG8gYW5jaWxsYXJ5IGRhdGEgc3RydWN0dXJlCiAgXGluZGV4IEluZGV4IG9mIHRoZSBhbmMgZGF0YSBlbGVtZW50IHRvIGdldAogIFxwdHIgUG9pbnRlciB0byBhIGJ1ZmZlciByZWNlaXZpbmcgYSBwb2ludGVyIHRvIHRoZSByZXF1ZXN0ZWQgYW5jIGRhdGEgZWxlbWVudAogIFxzaXplIFBvaW50ZXIgdG8gYSBidWZmZXIgcmVjZWl2aW5nIHRoZSBsZW5ndGggb2YgdGhlIHJlcXVlc3RlZCBhbmMgZGF0YSBlbGVtZW50IGluIGJ5dGVzCgogIFxyZXR1cm4gIEVycm9yIGNvZGUKKi8KQUFDX0RFQ09ERVJfRVJST1IgQ0FhY0RlY29kZXJfQW5jRGF0YUdldChDQW5jRGF0YSAqYW5jRGF0YSwgaW50IGluZGV4LCB1bnNpZ25lZCBjaGFyICoqcHRyLCBpbnQgKnNpemUpCnsKICBBQUNfREVDT0RFUl9FUlJPUiBlcnJvciA9IEFBQ19ERUNfT0s7CgogICpwdHIgID0gTlVMTDsKICAqc2l6ZSA9IDA7CgogIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDwgOCAmJiBpbmRleCA8IGFuY0RhdGEtPm5yRWxlbWVudHMpCiAgewogICAgKnB0ciAgPSAmYW5jRGF0YS0+YnVmZmVyW2FuY0RhdGEtPm9mZnNldFtpbmRleF1dOwogICAgKnNpemUgPSBhbmNEYXRhLT5vZmZzZXRbaW5kZXgrMV0gLSBhbmNEYXRhLT5vZmZzZXRbaW5kZXhdOwogIH0KCiAgcmV0dXJuIGVycm9yOwp9CgoKLyohCiAgXGJyaWVmIFBhcnNlIGFuY2lsbGFyeSBkYXRhCgogIFxhbmNEYXRhIFBvaW50ZXIgdG8gYW5jaWxsYXJ5IGRhdGEgc3RydWN0dXJlCiAgXGhCcyBIYW5kbGUgdG8gRkRLIGJpdHN0cmVhbQogIFxhbmNCeXRlcyBMZW5ndGggb2YgYW5jaWxsYXJ5IGRhdGEgdG8gcmVhZCBmcm9tIHRoZSBiaXRzdHJlYW0KCiAgXHJldHVybiAgRXJyb3IgY29kZQoqLwpzdGF0aWMKQUFDX0RFQ09ERVJfRVJST1IgQ0FhY0RlY29kZXJfQW5jRGF0YVBhcnNlICgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ0FuY0RhdGEgKmFuY0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGhCcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW50IGFuY0J5dGVzICkKewogIEFBQ19ERUNPREVSX0VSUk9SIGVycm9yID0gQUFDX0RFQ19PSzsKICBpbnQgcmVhZEJ5dGVzID0gMDsKCiAgaWYgKGFuY0RhdGEtPmJ1ZmZlciAhPSBOVUxMKQogIHsKICAgIGlmIChhbmNCeXRlcyA+IDApIHsKICAgICAgLyogd3JpdGUgYW5jaWxsYXJ5IGRhdGEgdG8gZXh0ZXJuYWwgYnVmZmVyICovCiAgICAgIGludCBvZmZzZXQgPSBhbmNEYXRhLT5vZmZzZXRbYW5jRGF0YS0+bnJFbGVtZW50c107CgogICAgICBpZiAoKG9mZnNldCArIGFuY0J5dGVzKSA+IGFuY0RhdGEtPmJ1ZmZlclNpemUpCiAgICAgIHsKICAgICAgICBlcnJvciA9IEFBQ19ERUNfVE9PX1NNQUxMX0FOQ19CVUZGRVI7CiAgICAgIH0KICAgICAgZWxzZSBpZiAoYW5jRGF0YS0+bnJFbGVtZW50cyA+PSA4LTEpCiAgICAgIHsKICAgICAgICBlcnJvciA9IEFBQ19ERUNfVE9PX01BTllfQU5DX0VMRU1FTlRTOwogICAgICB9CiAgICAgIGVsc2UKICAgICAgewogICAgICAgIGludCBpOwoKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgYW5jQnl0ZXM7IGkrKykgewogICAgICAgICAgYW5jRGF0YS0+YnVmZmVyW2krb2Zmc2V0XSA9IEZES3JlYWRCaXRzKGhCcywgOCk7CiAgICAgICAgICByZWFkQnl0ZXMrKzsKICAgICAgICB9CgogICAgICAgIGFuY0RhdGEtPm5yRWxlbWVudHMrKzsKICAgICAgICBhbmNEYXRhLT5vZmZzZXRbYW5jRGF0YS0+bnJFbGVtZW50c10gPSBhbmNCeXRlcyArIGFuY0RhdGEtPm9mZnNldFthbmNEYXRhLT5uckVsZW1lbnRzLTFdOwogICAgICB9CiAgICB9CiAgfQoKICByZWFkQnl0ZXMgPSBhbmNCeXRlcyAtIHJlYWRCeXRlczsKCiAgaWYgKHJlYWRCeXRlcyA+IDApIHsKICAgIC8qIHNraXAgZGF0YSAqLwogICAgRkRLcHVzaEZvcihoQnMsIHJlYWRCeXRlczw8Myk7CiAgfQoKICByZXR1cm4gZXJyb3I7Cn0KCi8qIQogIFxicmllZiBSZWFkIFN0cmVhbSBEYXRhIEVsZW1lbnQKCiAgXGJzIEJpdHN0cmVhbSBIYW5kbGUKCiAgXHJldHVybiAgRXJyb3IgY29kZQoqLwpzdGF0aWMgQUFDX0RFQ09ERVJfRVJST1IgQ0RhdGFTdHJlYW1FbGVtZW50X1JlYWQgKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENBbmNEYXRhICphbmNEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9BQUNfRFJDIGhEcmNJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9UUkFOU1BPUlRERUMgcFRwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDSEFSICAgICplbGVtZW50SW5zdGFuY2VUYWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCAgICAgIGFsaWdubWVudEFuY2hvciApCnsKICBBQUNfREVDT0RFUl9FUlJPUiBlcnJvciA9IEFBQ19ERUNfT0s7CiAgVUlOVCBkYXRhU3RhcnQ7CiAgaW50IGRhdGFCeXRlQWxpZ25GbGFnLCBjb3VudDsKCiAgaW50IGNyY1JlZyA9IHRyYW5zcG9ydERlY19DcmNTdGFydFJlZyhwVHAsIDApOwoKICAvKiBFbGVtZW50IEluc3RhbmNlIFRhZyAqLwogICplbGVtZW50SW5zdGFuY2VUYWcgPSBGREtyZWFkQml0cyhicyw0KTsKICAvKiBEYXRhIEJ5dGUgQWxpZ24gRmxhZyAqLwogIGRhdGFCeXRlQWxpZ25GbGFnID0gRkRLcmVhZEJpdHMoYnMsMSk7CgogIGNvdW50ID0gRkRLcmVhZEJpdHMoYnMsOCk7CgogIGlmIChjb3VudCA9PSAyNTUpIHsKICAgIGNvdW50ICs9IEZES3JlYWRCaXRzKGJzLDgpOyAvKiBFc2NDb3VudCAqLwogIH0KCiAgaWYgKGRhdGFCeXRlQWxpZ25GbGFnKSB7CiAgICBGREtieXRlQWxpZ24oYnMsIGFsaWdubWVudEFuY2hvcik7CiAgfQoKICBkYXRhU3RhcnQgPSBGREtnZXRWYWxpZEJpdHMoYnMpOwoKICBlcnJvciA9IENBYWNEZWNvZGVyX0FuY0RhdGFQYXJzZShhbmNEYXRhLCBicywgY291bnQpOwogIHRyYW5zcG9ydERlY19DcmNFbmRSZWcocFRwLCBjcmNSZWcpOwoKICB7CiAgICBJTlQgcmVhZEJpdHMsIGRhdGFCaXRzID0gY291bnQ8PDM7CgogICAgLyogTW92ZSB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBkYXRhIGp1bmsgKi8KICAgIEZES3B1c2hCYWNrKGJzLCBkYXRhU3RhcnQtRkRLZ2V0VmFsaWRCaXRzKGJzKSk7CgogICAgLyogUmVhZCBBbmMgZGF0YSBpZiBhdmFpbGFibGUgKi8KICAgIHJlYWRCaXRzID0gYWFjRGVjb2Rlcl9kcmNNYXJrUGF5bG9hZCggaERyY0luZm8sIGJzLCBEVkJfRFJDX0FOQ19EQVRBICk7CgogICAgaWYgKHJlYWRCaXRzICE9IGRhdGFCaXRzKSB7CiAgICAgIC8qIE1vdmUgdG8gdGhlIGVuZCBhZ2Fpbi4gKi8KICAgICAgRkRLcHVzaEJpRGlyZWN0aW9uYWwoYnMsIEZES2dldFZhbGlkQml0cyhicyktZGF0YVN0YXJ0K2RhdGFCaXRzKTsKICAgIH0KICB9CgogIHJldHVybiBlcnJvcjsKfQoKI2lmZGVmIFRQX1BDRV9FTkFCTEUKLyohCiAgXGJyaWVmIFJlYWQgUHJvZ3JhbSBDb25maWcgRWxlbWVudAoKICBcYnMgQml0c3RyZWFtIEhhbmRsZQogIFxwVHAgVHJhbnNwb3J0IGRlY29kZXIgaGFuZGxlIGZvciBDUkMgaGFuZGxpbmcKICBccGNlIFBvaW50ZXIgdG8gUENFIGJ1ZmZlcgogIFxjaGFubmVsQ29uZmlnIEN1cnJlbnQgY2hhbm5lbCBjb25maWd1cmF0aW9uCiAgXGFsaWduQW5jaG9yIEFuY2hvciBmb3IgYnl0ZSBhbGlnbm1lbnQKCiAgXHJldHVybiAgUENFIHN0YXR1cyAoLTE6IGZhaWwsIDA6IG5vIG5ldyBQQ0UsIDE6IFBDRSB1cGRhdGVkLCAyOiBQQ0UgdXBkYXRlZCBuZWVkIHJlLWNvbmZpZykuCiovCnN0YXRpYyBpbnQgQ1Byb2dyYW1Db25maWdFbGVtZW50X1JlYWQgKAogICAgSEFORExFX0ZES19CSVRTVFJFQU0gYnMsCiAgICBIQU5ETEVfVFJBTlNQT1JUREVDICBwVHAsCiAgICBDUHJvZ3JhbUNvbmZpZyAgICAgICpwY2UsCiAgICBjb25zdCBVSU5UICAgICAgICAgICBjaGFubmVsQ29uZmlnLAogICAgY29uc3QgVUlOVCAgICAgICAgICAgYWxpZ25BbmNob3IgKQp7CiAgaW50IHBjZVN0YXR1cyA9IDA7CiAgaW50IGNyY1JlZzsKCiAgLyogcmVhZCBQQ0UgdG8gdGVtcG9yYWwgYnVmZmVyIGZpcnN0ICovCiAgQ19BTExPQ19TQ1JBVENIX1NUQVJUKHRtcFBjZSwgQ1Byb2dyYW1Db25maWcsIDEpOwoKICBDUHJvZ3JhbUNvbmZpZ19Jbml0KHRtcFBjZSk7CiAgQ1Byb2dyYW1Db25maWdfUmVzZXQodG1wUGNlKTsKCiAgY3JjUmVnID0gdHJhbnNwb3J0RGVjX0NyY1N0YXJ0UmVnKHBUcCwgMCk7CgogIENQcm9ncmFtQ29uZmlnX1JlYWQodG1wUGNlLCBicywgYWxpZ25BbmNob3IpOwoKICB0cmFuc3BvcnREZWNfQ3JjRW5kUmVnKHBUcCwgY3JjUmVnKTsKCiAgaWYgKCAgQ1Byb2dyYW1Db25maWdfSXNWYWxpZCh0bXBQY2UpCiAgICAmJiAodG1wUGNlLT5Qcm9maWxlID09IDEpICkKICB7CiAgICBpZiAoICFwY2UtPmlzVmFsaWQgJiYgKGNoYW5uZWxDb25maWcgPiAwKSApIHsKICAgICAgLyogQ3JlYXRlIGEgc3RhbmRhcmQgY2hhbm5lbCBjb25maWcgUENFIHRvIGNvbXBhcmUgd2l0aCAqLwogICAgICBDUHJvZ3JhbUNvbmZpZ19HZXREZWZhdWx0KCBwY2UsIGNoYW5uZWxDb25maWcgKTsKICAgIH0KCiAgICBpZiAocGNlLT5pc1ZhbGlkKSB7CiAgICAgIC8qIENvbXBhcmUgdGhlIG5ldyBhbmQgdGhlIG9sZCBQQ0UgKHRhZ3MgaWdub3JlZCkgKi8KICAgICAgc3dpdGNoICggQ1Byb2dyYW1Db25maWdfQ29tcGFyZSggcGNlLCB0bXBQY2UgKSApCiAgICAgIHsKICAgICAgY2FzZSAxOiAgLyogQ2hhbm5lbCBjb25maWd1cmF0aW9uIG5vdCBjaGFuZ2VkLiBKdXN0IG5ldyBtZXRhZGF0YS4gKi8KICAgICAgICBGREttZW1jcHkocGNlLCB0bXBQY2UsIHNpemVvZihDUHJvZ3JhbUNvbmZpZykpOyAgICAvKiBTdG9yZSB0aGUgY29tcGxldGUgUENFICovCiAgICAgICAgcGNlU3RhdHVzID0gMTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTmV3IFBDRSBidXQgbm8gY2hhbmdlIG9mIGNvbmZpZyAqLwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDI6ICAvKiBUaGUgbnVtYmVyIG9mIGNoYW5uZWxzIGFyZSBpZGVudGljYWwgYnV0IG5vdCB0aGUgY29uZmlnICovCiAgICAgICAgaWYgKGNoYW5uZWxDb25maWcgPT0gMCkgewogICAgICAgICAgRkRLbWVtY3B5KHBjZSwgdG1wUGNlLCBzaXplb2YoQ1Byb2dyYW1Db25maWcpKTsgIC8qIFN0b3JlIHRoZSBjb21wbGV0ZSBQQ0UgKi8KICAgICAgICAgIHBjZVN0YXR1cyA9IDI7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBEZWNvZGVyIG5lZWRzIHJlLWNvbmZpZ3VyYXRpb24gKi8KICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgLTE6ICAvKiBUaGUgY2hhbm5lbCBjb25maWd1cmF0aW9uIGlzIGNvbXBsZXRlbHkgZGlmZmVyZW50ICovCiAgICAgICAgcGNlU3RhdHVzID0gLTE7ICAvKiBOb3Qgc3VwcG9ydGVkISAqLwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDA6ICAvKiBOb3RoaW5nIHRvIGRvIGJlY2F1c2UgUENFIG1hdGNoZXMgdGhlIG9sZCBvbmUgZXhhY3RseS4gKi8KICAgICAgZGVmYXVsdDoKICAgICAgICAvKiBwY2VTdGF0dXMgPSAwOyAqLwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CiAgfQoKICBDX0FMTE9DX1NDUkFUQ0hfRU5EKHRtcFBjZSwgQ1Byb2dyYW1Db25maWcsIDEpOwoKICByZXR1cm4gcGNlU3RhdHVzOwp9CiNlbmRpZiAvKiBUUF9QQ0VfRU5BQkxFICovCgovKiEKICBcYnJpZWYgUGFyc2UgRXh0ZW5zaW9uIFBheWxvYWQKCiAgXHNlbGYgSGFuZGxlIG9mIEFBQyBkZWNvZGVyCiAgXGNvdW50IFBvaW50ZXIgdG8gYml0IGNvdW50ZXIuCiAgXHByZXZpb3VzX2VsZW1lbnQgSUQgb2YgcHJldmlvdXMgZWxlbWVudCAocmVxdWlyZWQgYnkgc29tZSBleHRlbnNpb24gcGF5bG9hZHMpCgogIFxyZXR1cm4gIEVycm9yIGNvZGUKKi8Kc3RhdGljCkFBQ19ERUNPREVSX0VSUk9SIENBYWNEZWNvZGVyX0V4dFBheWxvYWRQYXJzZSAoSEFORExFX0FBQ0RFQ09ERVIgc2VsZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ICpjb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNUDRfRUxFTUVOVF9JRCBwcmV2aW91c19lbGVtZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBlbEluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmSXNGaWxsRWxlbWVudCkKewogIEFBQ19ERUNPREVSX0VSUk9SIGVycm9yID0gQUFDX0RFQ19PSzsKICBFWFRfUEFZTE9BRF9UWVBFIGV4dGVuc2lvbl90eXBlOwogIGludCBieXRlcyA9ICgqY291bnQpID4+IDM7CiAgaW50IGNyY0ZsYWcgPSAwOwoKICBpZiAoKmNvdW50IDwgNCkgewogICAgcmV0dXJuIEFBQ19ERUNfUEFSU0VfRVJST1I7CiAgfSBlbHNlIGlmICgoSU5UKUZES2dldFZhbGlkQml0cyhoQnMpIDwgKmNvdW50KSB7CiAgICByZXR1cm4gQUFDX0RFQ19ERUNPREVfRlJBTUVfRVJST1I7CiAgfQoKICBleHRlbnNpb25fdHlwZSA9IChFWFRfUEFZTE9BRF9UWVBFKSBGREtyZWFkQml0cyhoQnMsIDQpOyAgICAvKiBic19leHRlbnNpb25fdHlwZSAqLwogICpjb3VudCAtPSA0OwoKICBzd2l0Y2ggKGV4dGVuc2lvbl90eXBlKQogIHsKICBjYXNlIEVYVF9EWU5BTUlDX1JBTkdFOgogICAgewogICAgICBJTlQgcmVhZEJpdHMgPSBhYWNEZWNvZGVyX2RyY01hcmtQYXlsb2FkKCBzZWxmLT5oRHJjSW5mbywgaEJzLCBNUEVHX0RSQ19FWFRfREFUQSApOwoKICAgICAgaWYgKHJlYWRCaXRzID4gKmNvdW50KQogICAgICB7IC8qIFJlYWQgdG9vIG11Y2guIFNvbWV0aGluZyB3ZW50IHdyb25nISAqLwogICAgICAgIGVycm9yID0gQUFDX0RFQ19QQVJTRV9FUlJPUjsKICAgICAgfQogICAgICAqY291bnQgLT0gcmVhZEJpdHM7CiAgICB9CiAgICBicmVhazsKCgogIGNhc2UgRVhUX1NCUl9EQVRBX0NSQzoKICAgIGNyY0ZsYWcgPSAxOwogIGNhc2UgRVhUX1NCUl9EQVRBOgogICAgaWYgKElTX0NIQU5ORUxfRUxFTUVOVChwcmV2aW91c19lbGVtZW50KSkgewogICAgICBTQlJfRVJST1Igc2JyRXJyb3I7CgogICAgICBDQWFjRGVjb2Rlcl9TeW5jUW1mTW9kZShzZWxmKTsKCiAgICAgIHNickVycm9yID0gc2JyRGVjb2Rlcl9Jbml0RWxlbWVudCgKICAgICAgICAgICAgICBzZWxmLT5oU2JyRGVjb2RlciwKICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZVJhdGUsCiAgICAgICAgICAgICAgc2VsZi0+c3RyZWFtSW5mby5leHRTYW1wbGluZ1JhdGUsCiAgICAgICAgICAgICAgc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWUsCiAgICAgICAgICAgICAgc2VsZi0+c3RyZWFtSW5mby5hb3QsCiAgICAgICAgICAgICAgcHJldmlvdXNfZWxlbWVudCwKICAgICAgICAgICAgICBlbEluZGV4CiAgICAgICAgICAgICAgKTsKCiAgICAgIGlmIChzYnJFcnJvciA9PSBTQlJERUNfT0spIHsKICAgICAgICBzYnJFcnJvciA9IHNickRlY29kZXJfUGFyc2UgKAogICAgICAgICAgICAgICAgc2VsZi0+aFNickRlY29kZXIsCiAgICAgICAgICAgICAgICBoQnMsCiAgICAgICAgICAgICAgICBjb3VudCwKICAgICAgICAgICAgICAgKmNvdW50LAogICAgICAgICAgICAgICAgY3JjRmxhZywKICAgICAgICAgICAgICAgIHByZXZpb3VzX2VsZW1lbnQsCiAgICAgICAgICAgICAgICBlbEluZGV4LAogICAgICAgICAgICAgICAgc2VsZi0+ZmxhZ3MgJiBBQ19JTkRFUCApOwogICAgICAgIC8qIEVuYWJsZSBTQlIgZm9yIGltcGxpY2l0IFNCUiBzaWduYWxsaW5nLiAqLwogICAgICAgIGlmIChzYnJFcnJvciA9PSBTQlJERUNfT0spIHsKICAgICAgICAgIHNlbGYtPnNickVuYWJsZWQgPSAxOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICAvKiBEbyBub3QgdHJ5IHRvIGFwcGx5IFNCUiBiZWNhdXNlIGluaXRpYWxpemluZyB0aGUgZWxlbWVudCBmYWlsZWQuICovCiAgICAgICAgc2VsZi0+c2JyRW5hYmxlZCA9IDA7CiAgICAgIH0KICAgICAgLyogQ2l0YXRpb24gZnJvbSBJU08vSUVDIDE0NDk2LTMgY2hhcHRlciA0LjUuMi4xLjUuMgogICAgICBGaWxsIGVsZW1lbnRzIGNvbnRhaW5pbmcgYW4gZXh0ZW5zaW9uX3BheWxvYWQoKSB3aXRoIGFuIGV4dGVuc2lvbl90eXBlIG9mIEVYVF9TQlJfREFUQQogICAgICBvciBFWFRfU0JSX0RBVEFfQ1JDIHNoYWxsIG5vdCBjb250YWluIGFueSBvdGhlciBleHRlbnNpb25fcGF5bG9hZCBvZiBhbnkgb3RoZXIgZXh0ZW5zaW9uX3R5cGUuCiAgICAgICovCiAgICAgIGlmIChmSXNGaWxsRWxlbWVudCkgewogICAgICAgIEZES3B1c2hCaURpcmVjdGlvbmFsKGhCcywgKmNvdW50KTsKICAgICAgICAqY291bnQgPSAwOwogICAgICB9IGVsc2UgewogICAgICAgIC8qIElmIHRoaXMgaXMgbm90IGEgZmlsbCBlbGVtZW50IHdpdGggYSBrbm93biBsZW5ndGgsIHdlIGFyZSBzY3Jld2VkIGFuIG5vIGZ1cnRoZXIgcGFyc2luZyBtYWtlcyBzZW5zZS4gKi8KICAgICAgICBpZiAoc2JyRXJyb3IgIT0gU0JSREVDX09LKSB7CiAgICAgICAgICBzZWxmLT5mcmFtZU9LID0gMDsKICAgICAgICB9CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIGVycm9yID0gQUFDX0RFQ19QQVJTRV9FUlJPUjsKICAgIH0KICAgIGJyZWFrOwoKICBjYXNlIEVYVF9GSUxMX0RBVEE6CiAgICB7CiAgICAgIGludCB0ZW1wOwoKICAgICAgdGVtcCA9IEZES3JlYWRCaXRzKGhCcyw0KTsKICAgICAgYnl0ZXMtLTsKICAgICAgaWYgKHRlbXAgIT0gMCkgewogICAgICAgIGVycm9yID0gQUFDX0RFQ19QQVJTRV9FUlJPUjsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICB3aGlsZSAoYnl0ZXMgPiAwKSB7CiAgICAgICAgdGVtcCA9IEZES3JlYWRCaXRzKGhCcyw4KTsKICAgICAgICBieXRlcy0tOwogICAgICAgIGlmICh0ZW1wICE9IDB4YTUpIHsKICAgICAgICAgIGVycm9yID0gQUFDX0RFQ19QQVJTRV9FUlJPUjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgfQogICAgICAqY291bnQgPSBieXRlczw8MzsKICAgIH0KICAgIGJyZWFrOwoKICBjYXNlIEVYVF9EQVRBX0VMRU1FTlQ6CiAgICB7CiAgICAgIGludCBkYXRhRWxlbWVudFZlcnNpb247CgogICAgICBkYXRhRWxlbWVudFZlcnNpb24gPSBGREtyZWFkQml0cyhoQnMsNCk7CiAgICAgICpjb3VudCAtPSA0OwogICAgICBpZiAoZGF0YUVsZW1lbnRWZXJzaW9uID09IDApIC8qIEFOQ19EQVRBICovCiAgICAgIHsKICAgICAgICBpbnQgdGVtcCwgZGF0YUVsZW1lbnRMZW5ndGggPSAwOwogICAgICAgIGRvIHsKICAgICAgICAgIHRlbXAgPSBGREtyZWFkQml0cyhoQnMsOCk7CiAgICAgICAgICAqY291bnQgLT0gODsKICAgICAgICAgIGRhdGFFbGVtZW50TGVuZ3RoICs9IHRlbXA7CiAgICAgICAgfSB3aGlsZSAodGVtcCA9PSAyNTUgKTsKCiAgICAgICAgQ0FhY0RlY29kZXJfQW5jRGF0YVBhcnNlKCZzZWxmLT5hbmNEYXRhLCBoQnMsIGRhdGFFbGVtZW50TGVuZ3RoKTsKICAgICAgICAqY291bnQgLT0gKGRhdGFFbGVtZW50TGVuZ3RoPDwzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICAvKiBhbGlnbiA9IDAgKi8KICAgICAgICBlcnJvciA9IEFBQ19ERUNfUEFSU0VfRVJST1I7CiAgICAgICAgZ290byBiYWlsOwogICAgICB9CiAgICB9CiAgICBicmVhazsKCiAgY2FzZSBFWFRfREFUQV9MRU5HVEg6CiAgICBpZiAoICFmSXNGaWxsRWxlbWVudCAgICAgICAgICAvKiBNYWtlcyBubyBzZW5zIHRvIGhhdmUgYW4gYWRkaXRpb25hbCBsZW5ndGggaW4gYSBmaWxsIC4uLiAgICovCiAgICAgICYmIChzZWxmLT5mbGFncyAmIEFDX0VSKSApICAvKiAuLi4gZWxlbWVudCBiZWNhdXNlIHRoaXMgZXh0ZW5zaW9uIHBheWxvYWQgdHlwZSB3YXMgLi4uICAgICovCiAgICB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiAuLi4gY3JlYXRlZCB0byBjaXJjdW12ZW50IHRoZSBtaXNzaW5nIGxlbmd0aCBpbiBFUi1TeW50YXguICovCiAgICAgIGludCBiaXRDbnQsIGxlbiA9IEZES3JlYWRCaXRzKGhCcywgNCk7CiAgICAgICpjb3VudCAtPSA0OwoKICAgICAgaWYgKGxlbiA9PSAxNSkgewogICAgICAgIGludCBhZGRfbGVuID0gRkRLcmVhZEJpdHMoaEJzLCA4KTsKICAgICAgICAqY291bnQgLT0gODsKICAgICAgICBsZW4gKz0gYWRkX2xlbjsKCiAgICAgICAgaWYgKGFkZF9sZW4gPT0gMjU1KSB7CiAgICAgICAgICBsZW4gKz0gRkRLcmVhZEJpdHMoaEJzLCAxNik7CiAgICAgICAgICAqY291bnQgLT0gMTY7CiAgICAgICAgfQogICAgICB9CiAgICAgIGxlbiA8PD0gMzsKICAgICAgYml0Q250ID0gbGVuOwoKICAgICAgaWYgKCAoRVhUX1BBWUxPQURfVFlQRSlGREtyZWFkQml0cyhoQnMsIDQpID09IEVYVF9EQVRBX0xFTkdUSCApIHsKICAgICAgICAvKiBDaGVjayBOT1RFIDI6IFRoZSBleHRlbnNpb25fcGF5bG9hZCgpIGluY2x1ZGVkIGhlcmUgbXVzdAogICAgICAgICAgICAgICAgICAgICAgICAgbm90IGhhdmUgZXh0ZW5zaW9uX3R5cGUgPT0gRVhUX0RBVEFfTEVOR1RILiAqLwogICAgICAgIGVycm9yID0gQUFDX0RFQ19QQVJTRV9FUlJPUjsKICAgICAgfSBlbHNlIHsKICAgICAgICAvKiByZXdpbmQgYW5kIGNhbGwgbXlzZWxmIGFnYWluLiAqLwogICAgICAgIEZES3B1c2hCYWNrKGhCcywgNCk7CgogICAgICAgIGVycm9yID0KICAgICAgICAgIENBYWNEZWNvZGVyX0V4dFBheWxvYWRQYXJzZSAoCiAgICAgICAgICAgICAgICAgIHNlbGYsCiAgICAgICAgICAgICAgICAgIGhCcywKICAgICAgICAgICAgICAgICAmYml0Q250LAogICAgICAgICAgICAgICAgICBwcmV2aW91c19lbGVtZW50LAogICAgICAgICAgICAgICAgICBlbEluZGV4LAogICAgICAgICAgICAgICAgICAwICk7CgogICAgICAgICpjb3VudCAtPSBsZW4gLSBiaXRDbnQ7CiAgICAgIH0KICAgICAgLyogTm90ZTogdGhlIGZhbGwgdGhyb3VnaCBpbiBjYXNlIHRoZSBpZiBzdGF0ZW1lbnQgYWJvdmUgaXMgbm90IHRha2VuIGlzIGludGVudGlvbmFsLiAqLwogICAgICBicmVhazsKICAgIH0KCiAgY2FzZSBFWFRfRklMOgoKICBkZWZhdWx0OgogICAgLyogYWxpZ24gPSA0ICovCiAgICBGREtwdXNoRm9yKGhCcywgKmNvdW50KTsKICAgICpjb3VudCA9IDA7CiAgICBicmVhazsKICB9CgpiYWlsOgogIGlmICggKGVycm9yICE9IEFBQ19ERUNfT0spCiAgICAmJiBmSXNGaWxsRWxlbWVudCApCiAgeyAvKiBTa2lwIHRoZSByZW1haW5pbmcgZXh0ZW5zaW9uIGJ5dGVzICovCiAgICBGREtwdXNoQmlEaXJlY3Rpb25hbChoQnMsICpjb3VudCk7CiAgICAqY291bnQgPSAwOwogICAgLyogUGF0Y2ggZXJyb3IgY29kZSBiZWNhdXNlIGRlY29kaW5nIGNhbiBnbyBvbi4gKi8KICAgIGVycm9yID0gQUFDX0RFQ19PSzsKICAgIC8qIEJlIHN1cmUgdGhhdCBwYXJzaW5nIGVycm9ycyBoYXZlIGJlZW4gc3RvcmVkLiAqLwogIH0KICByZXR1cm4gZXJyb3I7Cn0KCi8qICBTdHJlYW0gQ29uZmlndXJhdGlvbiBhbmQgSW5mb3JtYXRpb24uCgogICAgVGhpcyBjbGFzcyBob2xkcyBjb25maWd1cmF0aW9uIGFuZCBpbmZvcm1hdGlvbiBkYXRhIGZvciBhIHN0cmVhbSB0byBiZSBkZWNvZGVkLiBJdAogICAgcHJvdmlkZXMgdGhlIGNhbGxpbmcgYXBwbGljYXRpb24gYXMgd2VsbCBhcyB0aGUgZGVjb2RlciB3aXRoIHN1YnN0YW50aWFsIGluZm9ybWF0aW9uLAogICAgZS5nLiBwcm9maWxlLCBzYW1wbGluZyByYXRlLCBudW1iZXIgb2YgY2hhbm5lbHMgZm91bmQgaW4gdGhlIGJpdHN0cmVhbSBldGMuCiovCnN0YXRpYwp2b2lkIENTdHJlYW1JbmZvSW5pdChDU3RyZWFtSW5mbyAqcFN0cmVhbUluZm8pCnsKICBwU3RyZWFtSW5mby0+YWFjU2FtcGxlUmF0ZSA9IDA7CiAgcFN0cmVhbUluZm8tPnByb2ZpbGUgPSAtMTsKICBwU3RyZWFtSW5mby0+YW90ID0gQU9UX05PTkU7CgogIHBTdHJlYW1JbmZvLT5jaGFubmVsQ29uZmlnID0gLTE7CiAgcFN0cmVhbUluZm8tPmJpdFJhdGUgPSAwOwogIHBTdHJlYW1JbmZvLT5hYWNTYW1wbGVzUGVyRnJhbWUgPSAwOwoKICBwU3RyZWFtSW5mby0+ZXh0QW90ICA9IEFPVF9OT05FOwogIHBTdHJlYW1JbmZvLT5leHRTYW1wbGluZ1JhdGUgPSAwOwoKICBwU3RyZWFtSW5mby0+ZmxhZ3MgPSAwOwoKICBwU3RyZWFtSW5mby0+ZXBDb25maWcgPSAtMTsgICAvKiBkZWZhdWx0IGlzIG5vIEVSICovCgogIHBTdHJlYW1JbmZvLT5udW1DaGFubmVscyA9IDA7CiAgcFN0cmVhbUluZm8tPnNhbXBsZVJhdGUgPSAwOwogIHBTdHJlYW1JbmZvLT5mcmFtZVNpemUgPSAwOwp9CgovKiEKICBcYnJpZWYgSW5pdGlhbGl6YXRpb24gb2YgQWFjRGVjb2RlckNoYW5uZWxJbmZvCgogIFRoZSBmdW5jdGlvbiBpbml0aWFsaXplcyB0aGUgcG9pbnRlcnMgdG8gQWFjRGVjb2RlckNoYW5uZWxJbmZvIGZvciBlYWNoIGNoYW5uZWwsCiAgc2V0IHRoZSBzdGFydCB2YWx1ZXMgZm9yIHdpbmRvdyBzaGFwZSBhbmQgd2luZG93IHNlcXVlbmNlIG9mIG92ZXJsYXAmYWRkIHRvIHplcm8sCiAgc2V0IHRoZSBvdmVybGFwIGJ1ZmZlciB0byB6ZXJvIGFuZCBpbml0aWFsaXplcyB0aGUgcG9pbnRlcnMgdG8gdGhlIHdpbmRvdyBjb2VmZmljaWVudHMuCiAgXHBhcmFtIGJzRm9ybWF0IGlzIHRoZSBmb3JtYXQgb2YgdGhlIEFBQyBiaXRzdHJlYW0KCiAgXHJldHVybiAgQUFDREVDT0RFUiBpbnN0YW5jZQoqLwpMSU5LU1BFQ19DUFAgSEFORExFX0FBQ0RFQ09ERVIgQ0FhY0RlY29kZXJfT3BlbihUUkFOU1BPUlRfVFlQRSBic0Zvcm1hdCkgICAgLyohPCBiaXRzdHJlYW0gZm9ybWF0IChhZGlmLGFkdHMsbG9hcywuLi4pLiAqLwp7CiAgSEFORExFX0FBQ0RFQ09ERVIgc2VsZjsKCiAgc2VsZiA9IEdldEFhY0RlY29kZXIoKTsKICBpZiAoc2VsZiA9PSBOVUxMKSB7CiAgICBnb3RvIGJhaWw7CiAgfQoKICAvKiBBc3NpZ24gY2hhbm5lbCBtYXBwaW5nIGluZm8gYXJyYXlzIChkb2luZyBzbyByZW1vdmVzIGRlcGVuZGVuY3kgb2Ygc2V0dGluZ3MgaGVhZGVyIGluIEFQSSBoZWFkZXIpLiAqLwogIHNlbGYtPnN0cmVhbUluZm8ucENoYW5uZWxJbmRpY2VzID0gc2VsZi0+Y2hhbm5lbEluZGljZXM7CiAgc2VsZi0+c3RyZWFtSW5mby5wQ2hhbm5lbFR5cGUgPSBzZWxmLT5jaGFubmVsVHlwZTsKCiAgLyogc2V0IGRlZmF1bHQgb3V0cHV0IG1vZGUgKi8KICBzZWxmLT5vdXRwdXRJbnRlcmxlYXZlZCA9IDE7ICAvKiBpbnRlcmxlYXZlZCAqLwoKICAvKiBpbml0aWFsaXplIGFuYyBkYXRhICovCiAgQ0FhY0RlY29kZXJfQW5jRGF0YUluaXQoJnNlbGYtPmFuY0RhdGEsIE5VTEwsIDApOwoKICAvKiBpbml0aWFsaXplIHN0cmVhbSBpbmZvICovCiAgQ1N0cmVhbUluZm9Jbml0KCZzZWxmLT5zdHJlYW1JbmZvKTsKCiAgLyogaW5pdGlhbGl6ZSBlcnJvciBjb25jZWFsbWVudCBjb21tb24gZGF0YSAqLwogIENDb25jZWFsbWVudF9Jbml0Q29tbW9uRGF0YSgmc2VsZi0+Y29uY2VhbENvbW1vbkRhdGEpOwoKICBzZWxmLT5oRHJjSW5mbyA9IEdldERyY0luZm8oKTsKICBpZiAoc2VsZi0+aERyY0luZm8gPT0gTlVMTCkgewogICAgZ290byBiYWlsOwogIH0KICAvKiBJbml0IGNvbW1vbiBEUkMgc3RydWN0dXJlICovCiAgYWFjRGVjb2Rlcl9kcmNJbml0KCBzZWxmLT5oRHJjSW5mbyApOwogIC8qIFNldCBkZWZhdWx0IGZyYW1lIGRlbGF5ICovCiAgYWFjRGVjb2Rlcl9kcmNTZXRQYXJhbSAoCiAgICAgICAgICBzZWxmLT5oRHJjSW5mbywKICAgICAgICAgIERSQ19CU19ERUxBWSwKICAgICAgICAgIENDb25jZWFsbWVudF9HZXREZWxheSgmc2VsZi0+Y29uY2VhbENvbW1vbkRhdGEpCiAgICAgICAgKTsKCgogIHNlbGYtPmFhY0NvbW1vbkRhdGEud29ya0J1ZmZlckNvcmUxID0gR2V0V29ya0J1ZmZlckNvcmUxKCk7CiAgc2VsZi0+YWFjQ29tbW9uRGF0YS53b3JrQnVmZmVyQ29yZTIgPSBHZXRXb3JrQnVmZmVyQ29yZTIoKTsKICBpZiAoc2VsZi0+YWFjQ29tbW9uRGF0YS53b3JrQnVmZmVyQ29yZTEgPT0gTlVMTAogICAgfHxzZWxmLT5hYWNDb21tb25EYXRhLndvcmtCdWZmZXJDb3JlMiA9PSBOVUxMICkKICAgIGdvdG8gYmFpbDsKCiAgcmV0dXJuIHNlbGY7CgpiYWlsOgogIENBYWNEZWNvZGVyX0Nsb3NlKCBzZWxmICk7CgogIHJldHVybiBOVUxMOwp9CgovKiBEZXN0cm95IGFhYyBkZWNvZGVyICovCkxJTktTUEVDX0NQUCB2b2lkIENBYWNEZWNvZGVyX0Nsb3NlKEhBTkRMRV9BQUNERUNPREVSIHNlbGYpCnsKICBpbnQgY2g7CgogIGlmIChzZWxmID09IE5VTEwpCiAgICByZXR1cm47CgogIGZvciAoY2g9MDsgY2g8KDYpOyBjaCsrKSB7CiAgICBpZiAoc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjaF0gIT0gTlVMTCkgewogICAgICBpZiAoc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjaF0tPnBPdmVybGFwQnVmZmVyICE9IE5VTEwpIHsKICAgICAgICBGcmVlT3ZlcmxhcEJ1ZmZlciAoJnNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bY2hdLT5wT3ZlcmxhcEJ1ZmZlcik7CiAgICAgIH0KICAgICAgaWYgKHNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bY2hdICE9IE5VTEwpIHsKICAgICAgICBGcmVlQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvICgmc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjaF0pOwogICAgICB9CiAgICB9CiAgICBpZiAoc2VsZi0+cEFhY0RlY29kZXJDaGFubmVsSW5mb1tjaF0gIT0gTlVMTCkgewogICAgICBGcmVlQWFjRGVjb2RlckNoYW5uZWxJbmZvICgmc2VsZi0+cEFhY0RlY29kZXJDaGFubmVsSW5mb1tjaF0pOwogICAgfQogIH0KCiAgc2VsZi0+YWFjQ2hhbm5lbHMgPSAwOwoKICBpZiAoc2VsZi0+aERyY0luZm8pIHsKICAgIEZyZWVEcmNJbmZvKCZzZWxmLT5oRHJjSW5mbyk7CiAgfQoKICBpZiAoc2VsZi0+YWFjQ29tbW9uRGF0YS53b3JrQnVmZmVyQ29yZTEgIT0gTlVMTCkgewogICAgRnJlZVdvcmtCdWZmZXJDb3JlMSAoJnNlbGYtPmFhY0NvbW1vbkRhdGEud29ya0J1ZmZlckNvcmUxKTsKICB9CiAgaWYgKHNlbGYtPmFhY0NvbW1vbkRhdGEud29ya0J1ZmZlckNvcmUyICE9IE5VTEwpIHsKICAgIEZyZWVXb3JrQnVmZmVyQ29yZTIgKCZzZWxmLT5hYWNDb21tb25EYXRhLndvcmtCdWZmZXJDb3JlMik7CiAgfQoKICBGcmVlQWFjRGVjb2RlciAoICZzZWxmKTsKfQoKCi8qIQogIFxicmllZiBJbml0aWFsaXphdGlvbiBvZiBkZWNvZGVyIGluc3RhbmNlCgogIFRoZSBmdW5jdGlvbiBpbml0aWFsaXplcyB0aGUgZGVjb2Rlci4KCiAgXHJldHVybiAgZXJyb3Igc3RhdHVzOiAwIGZvciBzdWNjZXNzLCA8PjAgZm9yIHVuc3VwcG9ydGVkIGNvbmZpZ3VyYXRpb25zCiovCkxJTktTUEVDX0NQUCBBQUNfREVDT0RFUl9FUlJPUiBDQWFjRGVjb2Rlcl9Jbml0KEhBTkRMRV9BQUNERUNPREVSIHNlbGYsIGNvbnN0IENTQXVkaW9TcGVjaWZpY0NvbmZpZyAqYXNjKQp7CiAgQUFDX0RFQ09ERVJfRVJST1IgZXJyID0gQUFDX0RFQ19PSzsKICBJTlQgYXNjQ2hhbm5lbHMsIGNoLCBhc2NDaGFuZ2VkID0gMDsKCiAgaWYgKCFzZWxmKQogICAgcmV0dXJuIEFBQ19ERUNfSU5WQUxJRF9IQU5ETEU7CgogIC8vIHNldCBwcm9maWxlIGFuZCBjaGVjayBmb3Igc3VwcG9ydGVkIGFvdAogIC8vIGxlYXZlIHByb2ZpbGUgb24gZGVmYXVsdCAoPS0xKSBmb3IgYWxsIG90aGVyIHN1cHBvcnRlZCBNUEVHLTQgYW90J3MgZXhjZXB0IGFvdD0yICg9QUFDLUxDKQogIHN3aXRjaCAoYXNjLT5tX2FvdCkgewogIGNhc2UgQU9UX0FBQ19MQzoKICAgIHNlbGYtPnN0cmVhbUluZm8ucHJvZmlsZSA9IDE7CiAgICBicmVhazsKCiAgY2FzZSBBT1RfU0JSOgogIGNhc2UgQU9UX1BTOgogIGNhc2UgQU9UX0VSX0FBQ19MRDoKICBjYXNlIEFPVF9FUl9BQUNfRUxEOgogICAgYnJlYWs7CgogIGRlZmF1bHQ6CiAgICByZXR1cm4gQUFDX0RFQ19VTlNVUFBPUlRFRF9BT1Q7CiAgfQoKICBDUHJvZ3JhbUNvbmZpZ19Jbml0KCZzZWxmLT5wY2UpOwoKICAvKiBzZXQgY2hhbm5lbHMgKi8KICBzd2l0Y2ggKGFzYy0+bV9jaGFubmVsQ29uZmlndXJhdGlvbikgewogIGNhc2UgMDoKI2lmZGVmIFRQX1BDRV9FTkFCTEUKICAgIC8qIGdldCBjaGFubmVscyBmcm9tIHByb2dyYW0gY29uZmlnIChBU0MpICovCiAgICBpZiAoQ1Byb2dyYW1Db25maWdfSXNWYWxpZCgmYXNjLT5tX3Byb2dyQ29uZmlnRWxlbWVudCkpIHsKICAgICAgYXNjQ2hhbm5lbHMgPSBhc2MtPm1fcHJvZ3JDb25maWdFbGVtZW50Lk51bUNoYW5uZWxzOwogICAgICBpZiAoYXNjQ2hhbm5lbHMgPiAwKSB7CiAgICAgICAgaW50IGVsOwogICAgICAgIC8qIHZhbGlkIG51bWJlciBvZiBjaGFubmVscyAtPiBjb3B5IHByb2dyYW0gY29uZmlnIGVsZW1lbnQgKFBDRSkgZnJvbSBBU0MgKi8KICAgICAgICBGREttZW1jcHkoJnNlbGYtPnBjZSwgJmFzYy0+bV9wcm9nckNvbmZpZ0VsZW1lbnQsIHNpemVvZihDUHJvZ3JhbUNvbmZpZykpOwogICAgICAgIC8qIEJ1aWx0IGVsZW1lbnQgdGFibGUgKi8KICAgICAgICBlbCA9IENQcm9ncmFtQ29uZmlnX0dldEVsZW1lbnRUYWJsZSgmYXNjLT5tX3Byb2dyQ29uZmlnRWxlbWVudCwgc2VsZi0+ZWxlbWVudHMsIDcpOwogICAgICAgIGZvciAoOyBlbDw3OyBlbCsrKSB7CiAgICAgICAgICBzZWxmLT5lbGVtZW50c1tlbF0gPSBJRF9OT05FOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gQUFDX0RFQ19VTlNVUFBPUlRFRF9DSEFOTkVMQ09ORklHOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBpZiAodHJhbnNwb3J0RGVjX0dldEZvcm1hdChzZWxmLT5oSW5wdXQpID09IFRUX01QNF9BRFRTKSB7CiAgICAgICAgLyogc2V0IGRlZmF1bHQgbWF4X2NoYW5uZWxzIGZvciBtZW1vcnkgYWxsb2NhdGlvbiBiZWNhdXNlIGluIGltcGxpY2l0IGNoYW5uZWwgbWFwcGluZyBtb2RlCiAgICAgICAgICAgd2UgZG9uJ3Qga25vdyB0aGUgYWN0dWFsIG51bWJlciBvZiBjaGFubmVscyB1bnRpbCB3ZSBwcm9jZXNzZWQgYXQgbGVhc3Qgb25lIHJhd19kYXRhX2Jsb2NrKCkuICovCiAgICAgICAgYXNjQ2hhbm5lbHMgPSAoNik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEFBQ19ERUNfVU5TVVBQT1JURURfQ0hBTk5FTENPTkZJRzsKICAgICAgfQogICAgfQojZWxzZSAvKiBUUF9QQ0VfRU5BQkxFICovCiAgICByZXR1cm4gQUFDX0RFQ19VTlNVUFBPUlRFRF9DSEFOTkVMQ09ORklHOwojZW5kaWYgLyogVFBfUENFX0VOQUJMRSAqLwogICAgYnJlYWs7CiAgY2FzZSAxOiBjYXNlIDI6IGNhc2UgMzogY2FzZSA0OiBjYXNlIDU6IGNhc2UgNjoKICAgIGFzY0NoYW5uZWxzID0gYXNjLT5tX2NoYW5uZWxDb25maWd1cmF0aW9uOwogICAgYnJlYWs7CiAgY2FzZSA3OgogICAgYXNjQ2hhbm5lbHMgPSA4OwogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIHJldHVybiBBQUNfREVDX1VOU1VQUE9SVEVEX0NIQU5ORUxDT05GSUc7CiAgfQoKICAvKiBJbml0aWFsaXplIGNvbnN0YW50IG1hcHBpbmdzIGZvciBjaGFubmVsIGNvbmZpZyAxLTcgKi8KICBpZiAoYXNjLT5tX2NoYW5uZWxDb25maWd1cmF0aW9uID4gMCkgewogICAgaW50IGVsOwogICAgRkRLbWVtY3B5KHNlbGYtPmVsZW1lbnRzLCBlbGVtZW50c1RhYlthc2MtPm1fY2hhbm5lbENvbmZpZ3VyYXRpb24tMV0sIHNpemVvZihNUDRfRUxFTUVOVF9JRCkqRkRLbWluKDcsNykpOwogICAgZm9yIChlbD03OyBlbDw3OyBlbCsrKSB7CiAgICAgIHNlbGYtPmVsZW1lbnRzW2VsXSA9IElEX05PTkU7CiAgICB9CiAgICBmb3IgKGNoPTA7IGNoPGFzY0NoYW5uZWxzOyBjaCsrKSB7CiAgICAgIHNlbGYtPmNoTWFwcGluZ1tjaF0gPSBjaDsKICAgIH0KICAgIGZvciAoOyBjaDwoNik7IGNoKyspIHsKICAgICAgc2VsZi0+Y2hNYXBwaW5nW2NoXSA9IDI1NTsKICAgIH0KICB9CiAjaWZkZWYgVFBfUENFX0VOQUJMRQogIGVsc2UgewogICAgaWYgKENQcm9ncmFtQ29uZmlnX0lzVmFsaWQoJmFzYy0+bV9wcm9nckNvbmZpZ0VsZW1lbnQpKSB7CiAgICAgIC8qIFNldCBtYXRyaXggbWl4ZG93biBpbmZvcyBpZiBhdmFpbGFibGUgZnJvbSBQQ0UuICovCiAgICAgIHBjbURteF9TZXRNYXRyaXhNaXhkb3duRnJvbVBjZSAoIHNlbGYtPmhQY21VdGlscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNjLT5tX3Byb2dyQ29uZmlnRWxlbWVudC5NYXRyaXhNaXhkb3duSW5kZXhQcmVzZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc2MtPm1fcHJvZ3JDb25maWdFbGVtZW50Lk1hdHJpeE1peGRvd25JbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNjLT5tX3Byb2dyQ29uZmlnRWxlbWVudC5Qc2V1ZG9TdXJyb3VuZEVuYWJsZSApOwogICAgfQogIH0KICNlbmRpZgoKICBzZWxmLT5zdHJlYW1JbmZvLmNoYW5uZWxDb25maWcgPSBhc2MtPm1fY2hhbm5lbENvbmZpZ3VyYXRpb247CgogIGlmIChhc2NDaGFubmVscyA+ICg2KSkgewogICAgcmV0dXJuIEFBQ19ERUNfVU5TVVBQT1JURURfQ0hBTk5FTENPTkZJRzsKICB9CiAgaWYgKHNlbGYtPnN0cmVhbUluZm8uYW90ICE9IGFzYy0+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+Y29uY2VhbENvbW1vbkRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZXNQZXJGcmFtZSApOwogICAgIH0KICB9CgogIC8qIFVwZGF0ZSBleHRlcm5hbGx5IHZpc2libGUgY29weSBvZiBmbGFncyAqLwogIHNlbGYtPnN0cmVhbUluZm8uZmxhZ3MgPSBzZWxmLT5mbGFnczsKCiAgcmV0dXJuIGVycjsKCmJhaWw6CiAgYWFjRGVjb2Rlcl9DbG9zZSggc2VsZiApOwogIHJldHVybiBBQUNfREVDX09VVF9PRl9NRU1PUlk7Cn0KCgpMSU5LU1BFQ19DUFAgQUFDX0RFQ09ERVJfRVJST1IgQ0FhY0RlY29kZXJfRGVjb2RlRnJhbWUoCiAgICAgICAgSEFORExFX0FBQ0RFQ09ERVIgc2VsZiwKICAgICAgICBjb25zdCBVSU5UIGZsYWdzLAogICAgICAgIElOVF9QQ00gKnBUaW1lRGF0YSwKICAgICAgICBjb25zdCBJTlQgIHRpbWVEYXRhU2l6ZSwKICAgICAgICBjb25zdCBJTlQgaW50ZXJsZWF2ZWQKICAgICAgICApCnsKICBBQUNfREVDT0RFUl9FUlJPUiBFcnJvclN0YXR1cyA9IEFBQ19ERUNfT0s7CgogIENQcm9ncmFtQ29uZmlnICpwY2U7CiAgSEFORExFX0ZES19CSVRTVFJFQU0gYnMgPSB0cmFuc3BvcnREZWNfR2V0Qml0c3RyZWFtKHNlbGYtPmhJbnB1dCwgMCk7CgogIE1QNF9FTEVNRU5UX0lEIHR5cGUgPSBJRF9OT05FOyAgICAgICAgICAgIC8qIEN1cnJlbnQgZWxlbWVudCB0eXBlICovCiAgSU5UIGFhY0NoYW5uZWxzPTA7ICAgICAgICAgICAgICAgICAgICAgICAgLyogQ2hhbm5lbCBjb3VudGVyIGZvciBjaGFubmVscyBmb3VuZCBpbiB0aGUgYml0c3RyZWFtICovCgogIElOVCBhdVN0YXJ0QW5jaG9yID0gKElOVClGREtnZXRWYWxpZEJpdHMoYnMpOyAgLyogQVUgc3RhcnQgYml0IGJ1ZmZlciBwb3NpdGlvbiBmb3IgQVUgYnl0ZSBhbGlnbm1lbnQgKi8KCiAgc2VsZi0+ZnJhbWVPSyA9IDE7CgogIC8qIEFueSBzdXBwb3J0ZWQgYmFzZSBsYXllciB2YWxpZCBBVSB3aWxsIHJlcXVpcmUgbW9yZSB0aGFuIDE2IGJpdHMuICovCiAgaWYgKCAodHJhbnNwb3J0RGVjX0dldEF1Qml0c1JlbWFpbmluZyhzZWxmLT5oSW5wdXQsIDApIDwgMTUpICYmIChmbGFncyAmIChBQUNERUNfQ09OQ0VBTHxBQUNERUNfRkxVU0gpKSA9PSAwKSB7CiAgICBzZWxmLT5mcmFtZU9LID0gMDsKICAgIEVycm9yU3RhdHVzID0gQUFDX0RFQ19ERUNPREVfRlJBTUVfRVJST1I7CiAgfQoKCiAgLyogUmVzZXQgUHJvZ3JhbSBDb25maWcgc3RydWN0dXJlICovCiAgcGNlID0gJnNlbGYtPnBjZTsKICBDUHJvZ3JhbUNvbmZpZ19SZXNldChwY2UpOwoKICBDQWFjRGVjb2Rlcl9BbmNEYXRhUmVzZXQoJnNlbGYtPmFuY0RhdGEpOwoKICB7CiAgICBpbnQgY2g7CgogICAgaWYgKHNlbGYtPnN0cmVhbUluZm8uY2hhbm5lbENvbmZpZyA9PSAwKSB7CiAgICAgIC8qIEluaXQgQ2hhbm5lbC9FbGVtZW50IG1hcHBpbmcgdGFibGUgKi8KICAgICAgZm9yIChjaD0wOyBjaDwoNik7IGNoKyspIHsKICAgICAgICBzZWxmLT5jaE1hcHBpbmdbY2hdID0gMjU1OwogICAgICB9CiAgICAgIGlmICghQ1Byb2dyYW1Db25maWdfSXNWYWxpZChwY2UpKSB7CiAgICAgICAgaW50IGVsOwogICAgICAgIGZvciAoZWw9MDsgZWw8NzsgZWwrKykgewogICAgICAgICAgc2VsZi0+ZWxlbWVudHNbZWxdID0gSURfTk9ORTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9CgogIC8qIENoZWNrIHNhbXBsaW5nIGZyZXF1ZW5jeSAgKi8KICBzd2l0Y2ggKCBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZVJhdGUgKSB7CiAgICBjYXNlIDE2MDAwOgogICAgY2FzZSAxMjAwMDoKICAgY2FzZSAxMTAyNToKICAgY2FzZSAgODAwMDoKICAgIGNhc2UgIDczNTA6CiAgICBjYXNlIDQ4MDAwOgogICAgY2FzZSA0NDEwMDoKICAgIGNhc2UgMzIwMDA6CiAgICBjYXNlIDI0MDAwOgogICAgY2FzZSAyMjA1MDoKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICBpZiAoICEgKHNlbGYtPmZsYWdzICYgKEFDX1VTQUN8QUNfUlNWRDUwKSkgKSB7CiAgICAgICAgcmV0dXJuIEFBQ19ERUNfVU5TVVBQT1JURURfU0FNUExJTkdSQVRFOwogICAgICB9CiAgICAgIGJyZWFrOwogIH0KCgogIGlmICggZmxhZ3MgJiBBQUNERUNfQ0xSSElTVCApCiAgewogICAgaW50IGNoOwogICAgLyogQ2xlYXIgaGlzdG9yeSAqLwogICAgZm9yIChjaCA9IDA7IGNoIDwgc2VsZi0+YWFjQ2hhbm5lbHM7IGNoKyspIHsKICAgICAgLyogUmVzZXQgY29uY2VhbG1lbnQgKi8KICAgICAgQ0NvbmNlYWxtZW50X0luaXRDaGFubmVsRGF0YSgmc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjaF0tPmNvbmNlYWxtZW50SW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2VsZi0+Y29uY2VhbENvbW1vbkRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlc1BlckZyYW1lICk7CiAgICAgIC8qIENsZWFyIGNvbmNlYWxtZW50IGJ1ZmZlcnMgdG8gZ2V0IHJpZCBvZiB0aGUgY29tcGxldGUgaGlzdG9yeSAqLwogICAgICBGREttZW1jbGVhcihzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NoXS0+Y29uY2VhbG1lbnRJbmZvLnNwZWN0cmFsQ29lZmZpY2llbnQsIDEwMjQgKiBzaXplb2YoRklYUF9DTkNMKSk7CiAgICAgIEZES21lbWNsZWFyKHNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bY2hdLT5jb25jZWFsbWVudEluZm8uc3BlY1NjYWxlLCA4ICogc2l6ZW9mKFNIT1JUKSk7CiAgICAgIC8qIENsZWFyIG92ZXJsYXAtYWRkIGJ1ZmZlcnMgdG8gYXZvaWQgY2xpY2tzLiAqLwogICAgICBGREttZW1jbGVhcihzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NoXS0+SU1kY3Qub3ZlcmxhcC5mcmVxLCBPdmVybGFwQnVmZmVyU2l6ZSpzaXplb2YoRklYUF9EQkwpKTsKICAgICB9CiAgfQoKCgojaWZkZWYgVFBfUENFX0VOQUJMRQogIGludCBwY2VSZWFkID0gMDsgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIEZsYWcgaW5kaWNhdGluZyBhIFBDRSBpbiB0aGUgY3VycmVudCByYXdfZGF0YV9ibG9jaygpICovCiNlbmRpZgoKCiAgSU5UIGhkYWFjRGVjb2RlZCA9IDA7CiAgTVA0X0VMRU1FTlRfSUQgcHJldmlvdXNfZWxlbWVudCA9IElEX0VORDsgLyogTGFzdCBlbGVtZW50IElEIChyZXF1aXJlZCBmb3IgZXh0ZW5zaW9uIHBheWxvYWQgbWFwcGluZyAqLwogIFVDSEFSIHByZXZpb3VzX2VsZW1lbnRfaW5kZXggPSAwOyAgICAgICAgIC8qIENhbm9uaWNhbCBpbmRleCBvZiBsYXN0IGVsZW1lbnQgKi8KICBpbnQgZWxlbWVudF9jb3VudCA9IDA7ICAgICAgICAgICAgICAgICAgICAvKiBFbGVtZW50IGNvdW50ZXIgZm9yIGVsZW1lbnRzIGZvdW5kIGluIHRoZSBiaXRzdHJlYW0gKi8KICBpbnQgZWxfY250W0lEX0xBU1RdID0geyAwIH07ICAgICAgICAgICAgICAvKiBlbGVtZW50IGNvdW50ZXIgKCByb2J1c3RuZXNzICkgKi8KCiAgd2hpbGUgKCAodHlwZSAhPSBJRF9FTkQpICYmICghIChmbGFncyAmIChBQUNERUNfQ09OQ0VBTCB8IEFBQ0RFQ19GTFVTSCkpKSAmJiBzZWxmLT5mcmFtZU9LICkKICB7CiAgICBpbnQgZWxfY2hhbm5lbHM7CgogICAgaWYgKCEgKHNlbGYtPmZsYWdzICYgKEFDX1VTQUN8QUNfUlNWRDUwfEFDX0VMRHxBQ19TQ0FMQUJMRXxBQ19FUikpKQogICAgICB0eXBlID0gKE1QNF9FTEVNRU5UX0lEKSBGREtyZWFkQml0cyhicywzKTsKICAgIGVsc2UgCiAgICAgIHR5cGUgPSBzZWxmLT5lbGVtZW50c1tlbGVtZW50X2NvdW50XTsKCiAgICBzZXRIY3JUeXBlKCZzZWxmLT5hYWNDb21tb25EYXRhLm92ZXJsYXkuYWFjLmVySGNySW5mbywgdHlwZSk7CgoKICAgIGlmICgoSU5UKUZES2dldFZhbGlkQml0cyhicykgPCAwKQogICAgICBzZWxmLT5mcmFtZU9LID0gMDsKCiAgICBzd2l0Y2ggKHR5cGUpCiAgICB7CiAgICAgIGNhc2UgSURfU0NFOgogICAgICBjYXNlIElEX0NQRToKICAgICAgY2FzZSBJRF9MRkU6CiAgICAgICAgLyoKICAgICAgICAgIENvbnNpc3RlbmN5IGNoZWNrCiAgICAgICAgKi8KCiAgICAgICAgaWYgKHR5cGUgPT0gSURfQ1BFKSB7CiAgICAgICAgICBlbF9jaGFubmVscyA9IDI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGVsX2NoYW5uZWxzID0gMTsKICAgICAgICB9CgogICAgICAgIGlmICggKGVsX2NudFt0eXBlXSA+PSAoc2VsZi0+YXNjQ2hhbm5lbHM+PihlbF9jaGFubmVscy0xKSkpIHx8IChhYWNDaGFubmVscyA+IChzZWxmLT5hc2NDaGFubmVscy1lbF9jaGFubmVscykpICkgewogICAgICAgICAgRXJyb3JTdGF0dXMgPSBBQUNfREVDX0RFQ09ERV9GUkFNRV9FUlJPUjsKICAgICAgICAgIHNlbGYtPmZyYW1lT0sgPSAwOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBpZiAoICEoc2VsZi0+ZmxhZ3MgJiAoQUNfVVNBQ3xBQ19SU1ZENTApKSApIHsKICAgICAgICAgIGludCBjaDsKICAgICAgICAgIGZvciAoY2g9MDsgY2ggPCBlbF9jaGFubmVsczsgY2grPTEpIHsKICAgICAgICAgICAgQ1Buc19SZXNldERhdGEoJnNlbGYtPnBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bYWFjQ2hhbm5lbHMrY2hdLT5kYXRhLmFhYy5QbnNEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAmc2VsZi0+cEFhY0RlY29kZXJDaGFubmVsSW5mb1thYWNDaGFubmVscytjaF0tPnBDb21EYXRhLT5wbnNJbnRlckNoYW5uZWxEYXRhKTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmKHNlbGYtPmZyYW1lT0spIHsKICAgICAgICAgIEVycm9yU3RhdHVzID0gQ0NoYW5uZWxFbGVtZW50X1JlYWQoIGJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2VsZi0+cEFhY0RlY29kZXJDaGFubmVsSW5mb1thYWNDaGFubmVsc10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2FhY0NoYW5uZWxzXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uYW90LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2VsZi0+c2FtcGxpbmdSYXRlSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPmZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbF9jaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uZXBDb25maWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5oSW5wdXQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICBpZiAoRXJyb3JTdGF0dXMpIHsKICAgICAgICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7CiAgICAgICAgICB9CiAgICAgICAgfQoKCiAgICAgICAgaWYgKCBzZWxmLT5mcmFtZU9LKSB7CiAgICAgICAgICAvKiBMb29rdXAgdGhlIGVsZW1lbnQgYW5kIGRlY29kZSBpdCBvbmx5IGlmIGl0IGJlbG9uZ3MgdG8gdGhlIGN1cnJlbnQgcHJvZ3JhbSAqLwogICAgICAgICAgaWYgKCBDUHJvZ3JhbUNvbmZpZ19Mb29rdXBFbGVtZW50KAogICAgICAgICAgICAgICAgICBwY2UsCiAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uY2hhbm5lbENvbmZpZywKICAgICAgICAgICAgICAgICAgc2VsZi0+cEFhY0RlY29kZXJDaGFubmVsSW5mb1thYWNDaGFubmVsc10tPkVsZW1lbnRJbnN0YW5jZVRhZywKICAgICAgICAgICAgICAgICAgYWFjQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgIHNlbGYtPmNoTWFwcGluZywKICAgICAgICAgICAgICAgICAgc2VsZi0+Y2hhbm5lbFR5cGUsCiAgICAgICAgICAgICAgICAgIHNlbGYtPmNoYW5uZWxJbmRpY2VzLAogICAgICAgICAgICAgICAgICZwcmV2aW91c19lbGVtZW50X2luZGV4LAogICAgICAgICAgICAgICAgICBzZWxmLT5lbGVtZW50cywKICAgICAgICAgICAgICAgICAgdHlwZSkgKQogICAgICAgICAgewogICAgICAgICAgICBpZiAoICFoZGFhY0RlY29kZWQgKSB7CiAgICAgICAgICAgICAgQ0NoYW5uZWxFbGVtZW50X0RlY29kZSgKICAgICAgICAgICAgICAgICAgICAgJnNlbGYtPnBBYWNEZWNvZGVyQ2hhbm5lbEluZm9bYWFjQ2hhbm5lbHNdLAogICAgICAgICAgICAgICAgICAgICAmc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1thYWNDaGFubmVsc10sCiAgICAgICAgICAgICAgICAgICAgICZzZWxmLT5zYW1wbGluZ1JhdGVJbmZvLAogICAgICAgICAgICAgICAgICAgICAgc2VsZi0+ZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICBlbF9jaGFubmVscwogICAgICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBhYWNDaGFubmVscyArPSAxOwogICAgICAgICAgICBpZiAodHlwZSA9PSBJRF9DUEUpIHsKICAgICAgICAgICAgICBhYWNDaGFubmVscyArPSAxOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7CiAgICAgICAgICB9CiAgICAgICAgICAvKiBDcmVhdGUgU0JSIGVsZW1lbnQgZm9yIFNCUiBmb3IgdXBzYW1wbGluZyBmb3IgTEZFIGVsZW1lbnRzLAogICAgICAgICAgICAgYW5kIGlmIFNCUiB3YXMgZXhwbGljaXRseSBzaWduYWxlZCwgYmVjYXVzZSB0aGUgZmlyc3QgZnJhbWUocykKICAgICAgICAgICAgIG1heSBub3QgY29udGFpbiBTQlIgcGF5bG9hZCAoYnJva2VuIGVuY29kZXIsIGJpdCBlcnJvcnMpLiAqLwogICAgICAgICAgaWYgKCAoc2VsZi0+ZmxhZ3MgJiBBQ19TQlJfUFJFU0VOVCkgfHwgKHNlbGYtPnNickVuYWJsZWQgPT0gMSkgKQogICAgICAgICAgewogICAgICAgICAgICBTQlJfRVJST1Igc2JyRXJyb3I7CgogICAgICAgICAgICBzYnJFcnJvciA9IHNickRlY29kZXJfSW5pdEVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgc2VsZi0+aFNickRlY29kZXIsCiAgICAgICAgICAgICAgICAgICAgc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVSYXRlLAogICAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uZXh0U2FtcGxpbmdSYXRlLAogICAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlc1BlckZyYW1lLAogICAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uYW90LAogICAgICAgICAgICAgICAgICAgIHR5cGUsCiAgICAgICAgICAgICAgICAgICAgcHJldmlvdXNfZWxlbWVudF9pbmRleAogICAgICAgICAgICAgICAgICAgICk7CiAgICAgICAgICAgIGlmIChzYnJFcnJvciAhPSBTQlJERUNfT0spIHsKICAgICAgICAgICAgICAvKiBEbyBub3QgdHJ5IHRvIGFwcGx5IFNCUiBiZWNhdXNlIGluaXRpYWxpemluZyB0aGUgZWxlbWVudCBmYWlsZWQuICovCiAgICAgICAgICAgICAgc2VsZi0+c2JyRW5hYmxlZCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGVsX2NudFt0eXBlXSsrOwogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBJRF9DQ0U6CiAgICAgICAgLyoKICAgICAgICAgIENvbnNpc3RlbmN5IGNoZWNrCiAgICAgICAgKi8KICAgICAgICBpZiAoIGVsX2NudFt0eXBlXSA+IHNlbGYtPmFzY0NoYW5uZWxzICkgewogICAgICAgICAgRXJyb3JTdGF0dXMgPSBBQUNfREVDX0RFQ09ERV9GUkFNRV9FUlJPUjsKICAgICAgICAgIHNlbGYtPmZyYW1lT0sgPSAwOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBpZiAoc2VsZi0+ZnJhbWVPSykKICAgICAgICB7CiAgICAgICAgICAvKiBtZW1vcnkgZm9yIHNwZWN0cmFsIGxpbmVzIHRlbXBvcmFsIG9uIHNjcmF0Y2ggKi8KICAgICAgICAgIENfQUxMT0NfU0NSQVRDSF9TVEFSVChtZGN0U3BlYywgRklYUF9EQkwsIDEwMjQpOwoKICAgICAgICAgIC8qIGNyZWF0ZSBkdW1teSBjaGFubmVsIGZvciBDQ0UgcGFyc2luZyBvbiBzdGFjayAqLwogICAgICAgICAgQ0FhY0RlY29kZXJDaGFubmVsSW5mbyAgdG1wQWFjRGVjb2RlckNoYW5uZWxJbmZvLCAqcFRtcEFhY0RlY29kZXJDaGFubmVsSW5mbzsKCiAgICAgICAgICBGREttZW1jbGVhcihtZGN0U3BlYywgMTAyNCpzaXplb2YoRklYUF9EQkwpKTsKCiAgICAgICAgICB0bXBBYWNEZWNvZGVyQ2hhbm5lbEluZm8ucER5bkRhdGEgPSAgIHNlbGYtPmFhY0NvbW1vbkRhdGEud29ya0J1ZmZlckNvcmUxLT5wQWFjRGVjb2RlckR5bmFtaWNEYXRhOwogICAgICAgICAgdG1wQWFjRGVjb2RlckNoYW5uZWxJbmZvLnBDb21EYXRhID0gICZzZWxmLT5hYWNDb21tb25EYXRhOwogICAgICAgICAgdG1wQWFjRGVjb2RlckNoYW5uZWxJbmZvLnBTcGVjdHJhbENvZWZmaWNpZW50ICA9IChTUEVDVFJBTF9QVFIpbWRjdFNwZWM7CiAgICAgICAgICAvKiBBc3N1bWUgQUFDLUxDICovCiAgICAgICAgICB0bXBBYWNEZWNvZGVyQ2hhbm5lbEluZm8uZ3JhbnVsZUxlbmd0aCA9IHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlc1BlckZyYW1lIC8gODsKCiAgICAgICAgICAvKiBSZXNldCBQTlMgZGF0YS4gKi8KICAgICAgICAgIENQbnNfUmVzZXREYXRhKCZ0bXBBYWNEZWNvZGVyQ2hhbm5lbEluZm8uZGF0YS5hYWMuUG5zRGF0YSwgJnRtcEFhY0RlY29kZXJDaGFubmVsSW5mby5wQ29tRGF0YS0+cG5zSW50ZXJDaGFubmVsRGF0YSk7CgogICAgICAgICAgcFRtcEFhY0RlY29kZXJDaGFubmVsSW5mbyA9ICZ0bXBBYWNEZWNvZGVyQ2hhbm5lbEluZm87CiAgICAgICAgICAvKiBkbyBDQ0UgcGFyc2luZyAqLwogICAgICAgICAgRXJyb3JTdGF0dXMgPSBDQ2hhbm5lbEVsZW1lbnRfUmVhZCggYnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwVG1wQWFjRGVjb2RlckNoYW5uZWxJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uYW90LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2VsZi0+c2FtcGxpbmdSYXRlSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPmZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+c3RyZWFtSW5mby5lcENvbmZpZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPmhJbnB1dAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwoKICAgICAgICAgIENfQUxMT0NfU0NSQVRDSF9FTkQobWRjdFNwZWMsIEZJWFBfREJMLCAxMDI0KTsKCiAgICAgICAgICBpZiAoRXJyb3JTdGF0dXMpIHsKICAgICAgICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7CiAgICAgICAgICB9CgogICAgICAgICAgaWYgKHNlbGYtPmZyYW1lT0spIHsKICAgICAgICAgICAgLyogTG9va3VwIHRoZSBlbGVtZW50IGFuZCBkZWNvZGUgaXQgb25seSBpZiBpdCBiZWxvbmdzIHRvIHRoZSBjdXJyZW50IHByb2dyYW0gKi8KICAgICAgICAgICAgaWYgKENQcm9ncmFtQ29uZmlnX0xvb2t1cEVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICAgcGNlLAogICAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uY2hhbm5lbENvbmZpZywKICAgICAgICAgICAgICAgICAgICBwVG1wQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5FbGVtZW50SW5zdGFuY2VUYWcsCiAgICAgICAgICAgICAgICAgICAgMCwKICAgICAgICAgICAgICAgICAgICBzZWxmLT5jaE1hcHBpbmcsCiAgICAgICAgICAgICAgICAgICAgc2VsZi0+Y2hhbm5lbFR5cGUsCiAgICAgICAgICAgICAgICAgICAgc2VsZi0+Y2hhbm5lbEluZGljZXMsCiAgICAgICAgICAgICAgICAgICAmcHJldmlvdXNfZWxlbWVudF9pbmRleCwKICAgICAgICAgICAgICAgICAgICBzZWxmLT5lbGVtZW50cywKICAgICAgICAgICAgICAgICAgICB0eXBlKSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAvKiBkZWNvZGluZyBvZiBDQ0Ugbm90IHN1cHBvcnRlZCAqLwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgIHNlbGYtPmZyYW1lT0sgPSAwOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsX2NudFt0eXBlXSsrOwogICAgICAgIGJyZWFrOwoKICAgICAgY2FzZSBJRF9EU0U6CiAgICAgICAgewogICAgICAgICAgVUNIQVIgZWxlbWVudF9pbnN0YW5jZV90YWc7CgogICAgICAgICAgQ0RhdGFTdHJlYW1FbGVtZW50X1JlYWQoIGJzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnNlbGYtPmFuY0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+aERyY0luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+aElucHV0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmVsZW1lbnRfaW5zdGFuY2VfdGFnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1U3RhcnRBbmNob3IgKTsKCiAgICAgICAgICBpZiAoIUNQcm9ncmFtQ29uZmlnX0xvb2t1cEVsZW1lbnQoCiAgICAgICAgICAgICAgICAgICBwY2UsCiAgICAgICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmNoYW5uZWxDb25maWcsCiAgICAgICAgICAgICAgICAgICBlbGVtZW50X2luc3RhbmNlX3RhZywKICAgICAgICAgICAgICAgICAgIDAsCiAgICAgICAgICAgICAgICAgICBzZWxmLT5jaE1hcHBpbmcsCiAgICAgICAgICAgICAgICAgICBzZWxmLT5jaGFubmVsVHlwZSwKICAgICAgICAgICAgICAgICAgIHNlbGYtPmNoYW5uZWxJbmRpY2VzLAogICAgICAgICAgICAgICAgICAmcHJldmlvdXNfZWxlbWVudF9pbmRleCwKICAgICAgICAgICAgICAgICAgIHNlbGYtPmVsZW1lbnRzLAogICAgICAgICAgICAgICAgICAgdHlwZSkgKQogICAgICAgICAgewogICAgICAgICAgICAvKiBtb3N0IGxpa2VseSBhbiBlcnJvciBpbiBiaXRzdHJlYW0gb2NjdXJlZCAqLwogICAgICAgICAgICAvL3NlbGYtPmZyYW1lT0sgPSAwOwogICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgewogICAgICAgICAgVUNIQVIgKnBEdmJBbmNEYXRhID0gTlVMTDsKICAgICAgICAgIEFBQ19ERUNPREVSX0VSUk9SIGFuY0VycjsKICAgICAgICAgIGludCBhbmNJbmRleDsKICAgICAgICAgIGludCBkdmJBbmNEYXRhU2l6ZSA9IDA7CgogICAgICAgICAgLyogQXNrIGhvdyBtYW55IGFuYyBkYXRhIGVsZW1lbnRzIGFyZSBpbiBidWZmZXIgKi8KICAgICAgICAgIGFuY0luZGV4ID0gc2VsZi0+YW5jRGF0YS5uckVsZW1lbnRzIC0gMTsKICAgICAgICAgIC8qIEdldCB0aGUgbGFzdCBvbmUgKGlmIGF2YWlsYWJsZSkgKi8KICAgICAgICAgIGFuY0VyciAgID0gQ0FhY0RlY29kZXJfQW5jRGF0YUdldCggJnNlbGYtPmFuY0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmNJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBEdmJBbmNEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZHZiQW5jRGF0YVNpemUgKTsKCiAgICAgICAgICBpZiAoYW5jRXJyID09IEFBQ19ERUNfT0spIHsKICAgICAgICAgICAgcGNtRG14X1JlYWREdmJBbmNEYXRhICgKICAgICAgICAgICAgICAgICAgc2VsZi0+aFBjbVV0aWxzLAogICAgICAgICAgICAgICAgICBwRHZiQW5jRGF0YSwKICAgICAgICAgICAgICAgICAgZHZiQW5jRGF0YVNpemUsCiAgICAgICAgICAgICAgICAgIDAgLyogbm90IG1wZWcyICovICk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKI2lmZGVmIFRQX1BDRV9FTkFCTEUKICAgICAgY2FzZSBJRF9QQ0U6CiAgICAgICAgewogICAgICAgICAgaW50IHJlc3VsdCA9IENQcm9ncmFtQ29uZmlnRWxlbWVudF9SZWFkKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+aElucHV0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uY2hhbm5lbENvbmZpZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXVTdGFydEFuY2hvciApOwogICAgICAgICAgaWYgKCByZXN1bHQgPCAwICkgewogICAgICAgICAgICAvKiBTb21ldGhpbmcgd2VudCB3cm9uZyAqLwogICAgICAgICAgICBFcnJvclN0YXR1cyA9IEFBQ19ERUNfUEFSU0VfRVJST1I7CiAgICAgICAgICAgIHNlbGYtPmZyYW1lT0sgPSAwOwogICAgICAgICAgfQogICAgICAgICAgZWxzZSBpZiAoIHJlc3VsdCA+IDEgKSB7CiAgICAgICAgICAgIC8qIEJ1aWx0IGVsZW1lbnQgdGFibGUgKi8KICAgICAgICAgICAgaW50IGVsSWR4ID0gQ1Byb2dyYW1Db25maWdfR2V0RWxlbWVudFRhYmxlKHBjZSwgc2VsZi0+ZWxlbWVudHMsIDcpOwogICAgICAgICAgICAvKiBSZXNldCB0aGUgcmVtYWluaW5nIHRhYnMgKi8KICAgICAgICAgICAgZm9yICggOyBlbElkeDw3OyBlbElkeCsrKSB7CiAgICAgICAgICAgICAgc2VsZi0+ZWxlbWVudHNbZWxJZHhdID0gSURfTk9ORTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBNYWtlIG5ldyBudW1iZXIgb2YgY2hhbm5lbCBwZXJzaXN0YW50ICovCiAgICAgICAgICAgIHNlbGYtPmFzY0NoYW5uZWxzID0gcGNlLT5OdW1DaGFubmVsczsKICAgICAgICAgICAgLyogSWYgUENFIGlzIG5vdCBmaXJzdCBlbGVtZW50IGNvbmNlYWwgdGhpcyBmcmFtZSB0byBhdm9pZCBpbmNvbnNpc3RlbmNpZXMgKi8KICAgICAgICAgICAgaWYgKCBlbGVtZW50X2NvdW50ICE9IDAgKSB7CiAgICAgICAgICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIHBjZVJlYWQgPSAocmVzdWx0Pj0wKSA/IDEgOiAwOwogICAgICAgIH0KICAgICAgICBicmVhazsKI2VuZGlmIC8qIFRQX1BDRV9FTkFCTEUgKi8KCiAgICAgIGNhc2UgSURfRklMOgogICAgICAgIHsKICAgICAgICAgIGludCBiaXRDbnQgPSBGREtyZWFkQml0cyhicyw0KTsgICAgICAgICAgIC8qIGJzX2NvdW50ICovCgogICAgICAgICAgaWYgKGJpdENudCA9PSAxNSkKICAgICAgICAgIHsKICAgICAgICAgICAgaW50IGVzY19jb3VudCA9IEZES3JlYWRCaXRzKGJzLDgpOyAgICAgLyogYnNfZXNjX2NvdW50ICovCiAgICAgICAgICAgIGJpdENudCA9ICBlc2NfY291bnQgKyAxNDsKICAgICAgICAgIH0KCiAgICAgICAgICAvKiBDb252ZXJ0IHRvIGJpdHMgKi8KICAgICAgICAgIGJpdENudCA8PD0gMzsKCiAgICAgICAgICB3aGlsZSAoYml0Q250ID4gMCkgewogICAgICAgICAgICBFcnJvclN0YXR1cyA9IENBYWNEZWNvZGVyX0V4dFBheWxvYWRQYXJzZShzZWxmLCBicywgJmJpdENudCwgcHJldmlvdXNfZWxlbWVudCwgcHJldmlvdXNfZWxlbWVudF9pbmRleCwgMSk7CiAgICAgICAgICAgIGlmIChFcnJvclN0YXR1cyAhPSBBQUNfREVDX09LKSB7CiAgICAgICAgICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgICBjYXNlIElEX0VYVDoKICAgICAgICB7CiAgICAgICAgICBJTlQgYml0Q250ID0gMDsKCiAgICAgICAgICAvKiBnZXQgdGhlIHJlbWFpbmluZyBiaXRzIG9mIHRoaXMgZnJhbWUgKi8KICAgICAgICAgIGJpdENudCA9IHRyYW5zcG9ydERlY19HZXRBdUJpdHNSZW1haW5pbmcoc2VsZi0+aElucHV0LCAwKTsKCiAgICAgICAgICBpZiAoIChiaXRDbnQgPiAwKSAmJiAoc2VsZi0+ZmxhZ3MgJiBBQ19TQlJfUFJFU0VOVCkgJiYgKHNlbGYtPmZsYWdzICYgKEFDX1VTQUN8QUNfUlNWRDUwfEFDX0VMRCkpICkKICAgICAgICAgIHsKICAgICAgICAgICAgU0JSX0VSUk9SIGVyciA9IFNCUkRFQ19PSzsKICAgICAgICAgICAgaW50ICBlbElkeCwgbnVtQ2hFbGVtZW50cyA9IGVsX2NudFtJRF9TQ0VdICsgZWxfY250W0lEX0NQRV07CgogICAgICAgICAgICBmb3IgKGVsSWR4ID0gMDsgZWxJZHggPCBudW1DaEVsZW1lbnRzOyBlbElkeCArPSAxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgZXJyID0gc2JyRGVjb2Rlcl9QYXJzZSAoCiAgICAgICAgICAgICAgICAgICAgc2VsZi0+aFNickRlY29kZXIsCiAgICAgICAgICAgICAgICAgICAgYnMsCiAgICAgICAgICAgICAgICAgICAmYml0Q250LAogICAgICAgICAgICAgICAgICAgIC0xLAogICAgICAgICAgICAgICAgICAgIHNlbGYtPmZsYWdzICYgQUNfU0JSQ1JDLAogICAgICAgICAgICAgICAgICAgIHNlbGYtPmVsZW1lbnRzW2VsSWR4XSwKICAgICAgICAgICAgICAgICAgICBlbElkeCwKICAgICAgICAgICAgICAgICAgICBzZWxmLT5mbGFncyAmIEFDX0lOREVQICk7CgogICAgICAgICAgICAgIGlmIChlcnIgIT0gU0JSREVDX09LKSB7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGVyciA9PSBTQlJERUNfT0spIHsKICAgICAgICAgICAgICBzZWxmLT5zYnJFbmFibGVkID0gMTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBzZWxmLT5mcmFtZU9LID0gMDsKICAgICAgICAgICAgfQogICAgICAgICAgfQoKCiAgICAgICAgICBpZiAoICEgKHNlbGYtPmZsYWdzICYgKEFDX1VTQUN8QUNfUlNWRDUwfEFDX0RSTSkpICkKICAgICAgICAgIHsKICAgICAgICAgICAgd2hpbGUgKCBiaXRDbnQgPiA3ICkgewogICAgICAgICAgICAgIEVycm9yU3RhdHVzID0gQ0FhY0RlY29kZXJfRXh0UGF5bG9hZFBhcnNlKHNlbGYsIGJzLCAmYml0Q250LCBwcmV2aW91c19lbGVtZW50LCBwcmV2aW91c19lbGVtZW50X2luZGV4LCAwKTsKICAgICAgICAgICAgICBpZiAoRXJyb3JTdGF0dXMgIT0gQUFDX0RFQ19PSykgewogICAgICAgICAgICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7CiAgICAgICAgICAgICAgICBFcnJvclN0YXR1cyA9IEFBQ19ERUNfUEFSU0VfRVJST1I7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgICBjYXNlIElEX0VORDoKICAgICAgICBicmVhazsKCiAgICAgIGRlZmF1bHQ6CiAgICAgICAgRXJyb3JTdGF0dXMgPSBBQUNfREVDX0RFQ09ERV9GUkFNRV9FUlJPUjsKICAgICAgICBzZWxmLT5mcmFtZU9LID0gMDsKICAgICAgICBicmVhazsKICAgIH0KCiAgICBwcmV2aW91c19lbGVtZW50ID0gdHlwZTsKICAgIGVsZW1lbnRfY291bnQrKzsKCiAgfSAgIC8qIHdoaWxlICggKHR5cGUgIT0gSURfRU5EKSAuLi4gKSAqLwoKICBpZiAoICEoZmxhZ3MgJiAoQUFDREVDX0NPTkNFQUx8QUFDREVDX0ZMVVNIKSkgKQogIHsKICAgIC8qIEJ5dGUgYWxpZ25tZW50IHdpdGggcmVzcGVjdCB0byB0aGUgZmlyc3QgYml0IG9mIHRoZSByYXdfZGF0YV9ibG9jaygpLiAqLwogICAgewogICAgICBGREtieXRlQWxpZ24oYnMsIGF1U3RhcnRBbmNob3IpOwogICAgfQoKICAgIC8qIENoZWNrIGlmIGFsbCBiaXRzIG9mIHRoZSByYXdfZGF0YV9ibG9jaygpIGhhdmUgYmVlbiByZWFkLiAqLwogICAgaWYgKCB0cmFuc3BvcnREZWNfR2V0QXVCaXRzVG90YWwoc2VsZi0+aElucHV0LCAwKSA+IDAgKSB7CiAgICAgIElOVCB1bnJlYWRCaXRzID0gdHJhbnNwb3J0RGVjX0dldEF1Qml0c1JlbWFpbmluZyhzZWxmLT5oSW5wdXQsIDApOwogICAgICBpZiAoIHVucmVhZEJpdHMgIT0gMCApIHsKCiAgICAgICAgc2VsZi0+ZnJhbWVPSyA9IDA7CiAgICAgICAgLyogRG8gbm90IG92ZXJ3cml0ZSBjdXJyZW50IGVycm9yICovCiAgICAgICAgaWYgKEVycm9yU3RhdHVzID09IEFBQ19ERUNfT0sgJiYgc2VsZi0+ZnJhbWVPSyA9PSAwKSB7CiAgICAgICAgICBFcnJvclN0YXR1cyA9IEFBQ19ERUNfUEFSU0VfRVJST1I7CiAgICAgICAgfQogICAgICAgIC8qIEFsd2F5cyBwdXQgdGhlIGJpdGJ1ZmZlciBhdCB0aGUgcmlnaHQgcG9zaXRpb24gYWZ0ZXIgdGhlIGN1cnJlbnQgQWNjZXNzIFVuaXQuICovCiAgICAgICAgRkRLcHVzaEJpRGlyZWN0aW9uYWwoYnMsIHVucmVhZEJpdHMpOwogICAgICB9CiAgICB9CgogICAgLyogQ2hlY2sgdGhlIGxhc3QgZWxlbWVudC4gVGhlIHRlcm1pbmF0b3IgKElEX0VORCkgaGFzIHRvIGJlIHRoZSBsYXN0IG9uZSAoZXZlbiBpZiBFUiBzeW50YXggaXMgdXNlZCkuICovCiAgICBpZiAoIHNlbGYtPmZyYW1lT0sgJiYgdHlwZSAhPSBJRF9FTkQgKSB7CiAgICAgIC8qIERvIG5vdCBvdmVyd3JpdGUgY3VycmVudCBlcnJvciAqLwogICAgICBpZiAoRXJyb3JTdGF0dXMgPT0gQUFDX0RFQ19PSykgewogICAgICAgIEVycm9yU3RhdHVzID0gQUFDX0RFQ19QQVJTRV9FUlJPUjsKICAgICAgfQogICAgICBzZWxmLT5mcmFtZU9LID0gMDsKICAgIH0KICB9CgogIC8qIE1vcmUgQUFDIGNoYW5uZWxzIHRoYW4gc3BlY2lmaWVkIGJ5IHRoZSBBU0Mgbm90IGFsbG93ZWQuICovCiAgaWYgKCAoYWFjQ2hhbm5lbHMgPT0gMCB8fCBhYWNDaGFubmVscyA+IHNlbGYtPmFhY0NoYW5uZWxzKSAmJiAhKGZsYWdzICYgKEFBQ0RFQ19DT05DRUFMfEFBQ0RFQ19GTFVTSCkpICkgewogICAgewogICAgICAvKiBEbyBub3Qgb3ZlcndyaXRlIGN1cnJlbnQgZXJyb3IgKi8KICAgICAgaWYgKEVycm9yU3RhdHVzID09IEFBQ19ERUNfT0spIHsKICAgICAgICBFcnJvclN0YXR1cyA9IEFBQ19ERUNfREVDT0RFX0ZSQU1FX0VSUk9SOwogICAgICB9CiAgICAgIHNlbGYtPmZyYW1lT0sgPSAwOwogICAgfQogICAgYWFjQ2hhbm5lbHMgPSAwOwogIH0KICBlbHNlIGlmICggYWFjQ2hhbm5lbHMgPiBzZWxmLT5hc2NDaGFubmVscyApIHsKICAgIC8qIERvIG5vdCBvdmVyd3JpdGUgY3VycmVudCBlcnJvciAqLwogICAgaWYgKEVycm9yU3RhdHVzID09IEFBQ19ERUNfT0spIHsKICAgICAgRXJyb3JTdGF0dXMgPSBBQUNfREVDX1VOU1VQUE9SVEVEX0ZPUk1BVDsKICAgIH0KICAgIHNlbGYtPmZyYW1lT0sgPSAwOwogICAgYWFjQ2hhbm5lbHMgPSAwOwogIH0KCiAgaWYgKCBUUkFOU1BPUlRERUNfT0sgIT0gdHJhbnNwb3J0RGVjX0NyY0NoZWNrKHNlbGYtPmhJbnB1dCkgKQogIHsKICAgIHNlbGYtPmZyYW1lT0s9MDsKICB9CgogIC8qIHN0b3JlIG9yIHJlc3RvcmUgdGhlIG51bWJlciBvZiBjaGFubmVscyAqLwogIGlmICggc2VsZi0+ZnJhbWVPSyAmJiAhKGZsYWdzICYoQUFDREVDX0NPTkNFQUx8QUFDREVDX0ZMVVNIKSkgKSB7CiAgICBzZWxmLT5jb25jZWFsQ2hhbm5lbHMgPSBhYWNDaGFubmVsczsgIC8qIHN0b3JlICovCiAgICBzZWxmLT5zYnJFbmFibGVkUHJldiA9IHNlbGYtPnNickVuYWJsZWQ7CiAgfSBlbHNlIHsKICAgIGlmIChzZWxmLT5hYWNDaGFubmVscyA+IDApIHsKICAgICAgYWFjQ2hhbm5lbHMgPSBzZWxmLT5jb25jZWFsQ2hhbm5lbHM7ICAvKiByZXN0b3JlICovCiAgICAgIHNlbGYtPnNickVuYWJsZWQgPSBzZWxmLT5zYnJFbmFibGVkUHJldjsKICAgICB9CiAgfQoKICAvKiBVcGRhdGUgbnVtYmVyIG9mIG91dHB1dCBjaGFubmVscyAqLwogIHNlbGYtPnN0cmVhbUluZm8uYWFjTnVtQ2hhbm5lbHMgPSBhYWNDaGFubmVsczsKCiAjaWZkZWYgVFBfUENFX0VOQUJMRQogIGlmIChwY2VSZWFkID09IDEgJiYgQ1Byb2dyYW1Db25maWdfSXNWYWxpZChwY2UpKSB7CiAgICAvKiBTZXQgbWF0cml4IG1peGRvd24gaW5mb3MgaWYgYXZhaWxhYmxlIGZyb20gUENFLiAqLwogICAgcGNtRG14X1NldE1hdHJpeE1peGRvd25Gcm9tUGNlICggc2VsZi0+aFBjbVV0aWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGNlLT5NYXRyaXhNaXhkb3duSW5kZXhQcmVzZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGNlLT5NYXRyaXhNaXhkb3duSW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwY2UtPlBzZXVkb1N1cnJvdW5kRW5hYmxlICk7CiAgfQogI2VuZGlmCgogIC8qIElmIHRoZXJlIGlzIG5vIHZhbGlkIGRhdGEgdG8gdHJhbnNmcm9tIGludG8gdGltZSBkb21haW4sIHJldHVybi4gKi8KICBpZiAoICEgSVNfT1VUUFVUX1ZBTElEKEVycm9yU3RhdHVzKSApIHsKICAgIHJldHVybiBFcnJvclN0YXR1czsKICB9CgogIC8qCiAgICBJbnZlcnNlIHRyYW5zZm9ybQogICovCiAgewogICAgaW50IHN0cmlkZSwgb2Zmc2V0LCBjOwoKICAgIC8qIEV4dHJhY3QgRFJDIGNvbnRyb2wgZGF0YSBhbmQgbWFwIGl0IHRvIGNoYW5uZWxzICh3aXRob3V0IGJpdHN0cmVhbSBkZWxheSkgKi8KICAgIGFhY0RlY29kZXJfZHJjUHJvbG9nICgKICAgICAgICAgICAgc2VsZi0+aERyY0luZm8sCiAgICAgICAgICAgIGJzLAogICAgICAgICAgICBzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvLAogICAgICAgICAgICBzZWxmLT5wY2UuRWxlbWVudEluc3RhbmNlVGFnLAogICAgICAgICAgICBzZWxmLT5jaE1hcHBpbmcsCiAgICAgICAgICAgIGFhY0NoYW5uZWxzCiAgICAgICAgICApOwoKICAgIC8qICJjIiBpdGVyYXRlcyBpbiBjYW5vbmljYWwgTVBFRyBjaGFubmVsIG9yZGVyICovCiAgICBmb3IgKGM9MDsgYyA8IGFhY0NoYW5uZWxzOyBjKyspCiAgICB7CiAgICAgIENBYWNEZWNvZGVyQ2hhbm5lbEluZm8gKnBBYWNEZWNvZGVyQ2hhbm5lbEluZm87CgogICAgICAvKiBTZWxlY3QgY29ycmVjdCBwQWFjRGVjb2RlckNoYW5uZWxJbmZvIGZvciBjdXJyZW50IGNoYW5uZWwgKi8KICAgICAgaWYgKHNlbGYtPmNoTWFwcGluZ1tjXSA+PSBhYWNDaGFubmVscykgewogICAgICAgIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8gPSBzZWxmLT5wQWFjRGVjb2RlckNoYW5uZWxJbmZvW2NdOwogICAgICB9IGVsc2UgewogICAgICAgIHBBYWNEZWNvZGVyQ2hhbm5lbEluZm8gPSBzZWxmLT5wQWFjRGVjb2RlckNoYW5uZWxJbmZvW3NlbGYtPmNoTWFwcGluZ1tjXV07CiAgICAgIH0KCiAgICAgIC8qIFNldHVwIG9mZnNldCBhbmQgc3RyaWRlIGZvciB0aW1lIGJ1ZmZlciB0cmF2ZXJzYWwuICovCiAgICAgIGlmIChpbnRlcmxlYXZlZCkgewogICAgICAgIHN0cmlkZSA9IGFhY0NoYW5uZWxzOwogICAgICAgIG9mZnNldCA9IHNlbGYtPmNoYW5uZWxPdXRwdXRNYXBwaW5nW2FhY0NoYW5uZWxzLTFdW2NdOwogICAgICB9IGVsc2UgewogICAgICAgIHN0cmlkZSA9IDE7CiAgICAgICAgb2Zmc2V0ID0gc2VsZi0+Y2hhbm5lbE91dHB1dE1hcHBpbmdbYWFjQ2hhbm5lbHMtMV1bY10gKiBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZXNQZXJGcmFtZTsKICAgICAgfQoKCiAgICAgIC8qCiAgICAgICAgQ29uY2VhbCBkZWZlY3RpdmUgc3BlY3RyYWwgZGF0YQogICAgICAqLwogICAgICBDQ29uY2VhbG1lbnRfQXBwbHkoJnNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bY10tPmNvbmNlYWxtZW50SW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bY10sCiAgICAgICAgICAgICAgICAgICAgICAgICAmc2VsZi0+c2FtcGxpbmdSYXRlSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZXNQZXJGcmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAwLAogICAgICAgICAgICAgICAgICAgICAgICAgIChzZWxmLT5mcmFtZU9LICYmICEoZmxhZ3MmQUFDREVDX0NPTkNFQUwpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5mbGFncwogICAgICAgICAgICAgICAgICAgICAgICApOwoKCiAgICAgIGlmIChmbGFncyAmIChBQUNERUNfSU5UUnxBQUNERUNfQ0xSSElTVCkpIHsKICAgICAgICAvKiBSZXNldCBEUkMgY29udHJvbCBkYXRhIGZvciB0aGlzIGNoYW5uZWwgKi8KICAgICAgICBhYWNEZWNvZGVyX2RyY0luaXRDaGFubmVsRGF0YSAoICZzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NdLT5kcmNEYXRhICk7CiAgICAgIH0KICAgICAgLyogRFJDIHByb2Nlc3NpbmcgKi8KICAgICAgYWFjRGVjb2Rlcl9kcmNBcHBseSAoCiAgICAgICAgICAgICAgc2VsZi0+aERyY0luZm8sCiAgICAgICAgICAgICAgc2VsZi0+aFNickRlY29kZXIsCiAgICAgICAgICAgICAgcEFhY0RlY29kZXJDaGFubmVsSW5mbywKICAgICAgICAgICAgICZzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NdLT5kcmNEYXRhLAogICAgICAgICAgICAgIGMsCiAgICAgICAgICAgICAgc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWUsCiAgICAgICAgICAgICAgc2VsZi0+c2JyRW5hYmxlZAogICAgICAgICAgICApOwoKICAgICAgc3dpdGNoIChwQWFjRGVjb2RlckNoYW5uZWxJbmZvLT5yZW5kZXJNb2RlKQogICAgICB7CiAgICAgICAgY2FzZSBBQUNERUNfUkVOREVSX0lNRENUOgogICAgICAgICAgQ0Jsb2NrX0ZyZXF1ZW5jeVRvVGltZSgKICAgICAgICAgICAgICAgICAgc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mb1tjXSwKICAgICAgICAgICAgICAgICAgcEFhY0RlY29kZXJDaGFubmVsSW5mbywKICAgICAgICAgICAgICAgICAgcFRpbWVEYXRhICsgb2Zmc2V0LAogICAgICAgICAgICAgICAgICBzZWxmLT5zdHJlYW1JbmZvLmFhY1NhbXBsZXNQZXJGcmFtZSwKICAgICAgICAgICAgICAgICAgc3RyaWRlLAogICAgICAgICAgICAgICAgICAoc2VsZi0+ZnJhbWVPSyAmJiAhKGZsYWdzJkFBQ0RFQ19DT05DRUFMKSksCiAgICAgICAgICAgICAgICAgIHNlbGYtPmFhY0NvbW1vbkRhdGEud29ya0J1ZmZlckNvcmUxLT5tZGN0T3V0VGVtcAogICAgICAgICAgICAgICAgICApOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBBQUNERUNfUkVOREVSX0VMREZCOgogICAgICAgICAgQ0Jsb2NrX0ZyZXF1ZW5jeVRvVGltZUxvd0RlbGF5KAogICAgICAgICAgICAgICAgICBzZWxmLT5wQWFjRGVjb2RlclN0YXRpY0NoYW5uZWxJbmZvW2NdLAogICAgICAgICAgICAgICAgICBwQWFjRGVjb2RlckNoYW5uZWxJbmZvLAogICAgICAgICAgICAgICAgICBwVGltZURhdGEgKyBvZmZzZXQsCiAgICAgICAgICAgICAgICAgIHNlbGYtPnN0cmVhbUluZm8uYWFjU2FtcGxlc1BlckZyYW1lLAogICAgICAgICAgICAgICAgICBzdHJpZGUKICAgICAgICAgICAgICAgICAgKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICBFcnJvclN0YXR1cyA9IEFBQ19ERUNfVU5LTk9XTjsKICAgICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGlmICggZmxhZ3MmQUFDREVDX0ZMVVNIICkgewogICAgICAgICAgRkRLbWVtY2xlYXIocEFhY0RlY29kZXJDaGFubmVsSW5mby0+cFNwZWN0cmFsQ29lZmZpY2llbnQsIHNpemVvZihGSVhQX0RCTCkqc2VsZi0+c3RyZWFtSW5mby5hYWNTYW1wbGVzUGVyRnJhbWUpOwogICAgICAgIEZES21lbWNsZWFyKHNlbGYtPnBBYWNEZWNvZGVyU3RhdGljQ2hhbm5lbEluZm9bY10tPnBPdmVybGFwQnVmZmVyLCBPdmVybGFwQnVmZmVyU2l6ZSpzaXplb2YoRklYUF9EQkwpKTsKICAgICAgfQogICAgfQoKCiAgICAvKiBFeHRyYWN0IERSQyBjb250cm9sIGRhdGEgYW5kIG1hcCBpdCB0byBjaGFubmVscyAod2l0aCBiaXRzdHJlYW0gZGVsYXkpICovCiAgICBhYWNEZWNvZGVyX2RyY0VwaWxvZyAoCiAgICAgICAgICAgIHNlbGYtPmhEcmNJbmZvLAogICAgICAgICAgICBicywKICAgICAgICAgICAgc2VsZi0+cEFhY0RlY29kZXJTdGF0aWNDaGFubmVsSW5mbywKICAgICAgICAgICAgc2VsZi0+cGNlLkVsZW1lbnRJbnN0YW5jZVRhZywKICAgICAgICAgICAgc2VsZi0+Y2hNYXBwaW5nLAogICAgICAgICAgICBhYWNDaGFubmVscwogICAgICAgICAgKTsKICB9CgoKICAvKiBSZW9yZGVyIGNoYW5uZWwgdHlwZSBpbmZvcm1hdGlvbiB0YWJsZXMuICAqLwogIHsKICAgIEFVRElPX0NIQU5ORUxfVFlQRSB0eXBlc1soNildOwogICAgVUNIQVIgaWR4Wyg2KV07CiAgICBpbnQgYzsKCiAgICBGREtfQVNTRVJUKHNpemVvZihzZWxmLT5jaGFubmVsVHlwZSkgPT0gc2l6ZW9mKHR5cGVzKSk7CiAgICBGREtfQVNTRVJUKHNpemVvZihzZWxmLT5jaGFubmVsSW5kaWNlcykgPT0gc2l6ZW9mKGlkeCkpOwoKICAgIEZES21lbWNweSh0eXBlcywgc2VsZi0+Y2hhbm5lbFR5cGUsIHNpemVvZih0eXBlcykpOwogICAgRkRLbWVtY3B5KGlkeCwgc2VsZi0+Y2hhbm5lbEluZGljZXMsIHNpemVvZihpZHgpKTsKCiAgICBmb3IgKGM9MDsgYzxhYWNDaGFubmVsczsgYysrKSB7CiAgICAgIHNlbGYtPmNoYW5uZWxUeXBlW3NlbGYtPmNoYW5uZWxPdXRwdXRNYXBwaW5nW2FhY0NoYW5uZWxzLTFdW2NdXSA9IHR5cGVzW2NdOwogICAgICBzZWxmLT5jaGFubmVsSW5kaWNlc1tzZWxmLT5jaGFubmVsT3V0cHV0TWFwcGluZ1thYWNDaGFubmVscy0xXVtjXV0gPSBpZHhbY107CiAgICB9CiAgfQoKICBzZWxmLT5ibG9ja051bWJlcisrOwoKICByZXR1cm4gRXJyb3JTdGF0dXM7Cn0KCi8qIQogIFxicmllZiByZXR1cm5zIHRoZSBzdHJlYW1pbmZvIHBvaW50ZXIKCiAgVGhlIGZ1bmN0aW9uIGhhbmRzIGJhY2sgYSBwb2ludGVyIHRvIHRoZSBzdHJlYW1pbmZvIHN0cnVjdHVyZQoKICBccmV0dXJuIHBvaW50ZXIgdG8gdGhlIHN0cnVjdAoqLwpMSU5LU1BFQ19DUFAgQ1N0cmVhbUluZm8qIENBYWNEZWNvZGVyX0dldFN0cmVhbUluZm8gKCBIQU5ETEVfQUFDREVDT0RFUiBzZWxmICkKewogIGlmICghc2VsZikgewogICAgcmV0dXJuIE5VTEw7CiAgfQogIHJldHVybiAmc2VsZi0+c3RyZWFtSW5mbzsKfQoKCgoK