Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKiogIE1QRUctNCBUcmFuc3BvcnQgRGVjb2RlciAgKioqKioqKioqKioqKioqKioqKioqKioqCgogICBBdXRob3Iocyk6IE1hbnVlbCBKYW5kZXIKICAgRGVzY3JpcHRpb246IE1QRUcgVHJhbnNwb3J0IGRlY29kZXIKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNpbmNsdWRlICJ0cGRlY19saWIuaCIKCi8qIGxpYnJhcnkgdmVyc2lvbiAqLwojaW5jbHVkZSAidmVyc2lvbiIKCgojaW5jbHVkZSAidHBfZGF0YS5oIgoKI2luY2x1ZGUgInRwZGVjX2FkdHMuaCIKCiNpbmNsdWRlICJ0cGRlY19hZGlmLmgiCgojaW5jbHVkZSAidHBkZWNfbGF0bS5oIgoKCgojZGVmaW5lIE1PRFVMRV9OQU1FICJ0cmFuc3BvcnREZWMiCgp0eXBlZGVmIHVuaW9uIHsKICBTVFJVQ1RfQURUUyBhZHRzOwoKICBDQWRpZkhlYWRlciBhZGlmOwoKICBDTGF0bURlbXV4IGxhdG07CgoKfSB0cmFuc3BvcnRkZWNfcGFyc2VyX3Q7CgpzdHJ1Y3QgVFJBTlNQT1JUREVDCnsKICBUUkFOU1BPUlRfVFlQRSB0cmFuc3BvcnRGbXQ7ICAgICAvKiE8IE1QRUc0IHRyYW5zcG9ydERlYyB0eXBlLiAqLwoKICBDU1RwQ2FsbEJhY2tzIGNhbGxiYWNrczsgICAgICAgICAvKiE8IFN0cnVjdCBob2xkaW5nIGNhbGxiYWNrIGFuZCBpdHMgZGF0YSAqLwoKICBGREtfQklUU1RSRUFNIGJpdFN0cmVhbVsyXTsgLyogQml0c3RyZWFtIHJlYWRlciAqLwogIFVDSEFSICpic0J1ZmZlcjsgICAgICAgICAgICAgICAgIC8qIEludGVybmFsIGJpdHN0cmVhbWQgZGF0YSBidWZmZXIgKHVuYWxsb2NhdGVkIGluIGNhc2Ugb2YgVFRfTVA0X1JBV1BBQ0tFVFMpICovCgogIHRyYW5zcG9ydGRlY19wYXJzZXJfdCBwYXJzZXI7ICAgIC8qIEZvcm1hdCBzcGVjaWZpYyBwYXJzZXIgc3RydWN0cy4gKi8KCiAgQ1NBdWRpb1NwZWNpZmljQ29uZmlnIGFzY1soMSoyKV07IC8qIEF1ZGlvIHNwZWNpZmljIGNvbmZpZyBmcm9tIHRoZSBsYXN0IGNvbmZpZyBmb3VuZC4gKi8KICBVSU5UICBnbG9iYWxGcmFtZVBvczsgICAgICAgICAgICAvKiBHbG9iYWwgdHJhbnNwb3J0IGZyYW1lIHJlZmVyZW5jZSBiaXQgcG9zaXRpb24uICovCiAgVUlOVCAgYWNjZXNzVW5pdEFuY2hvclsyXTsgICAgLyogQ3VycmVudCBhY2Nlc3MgdW5pdCBzdGFydCBiaXQgcG9zaXRpb24uICovCiAgSU5UICAgYXVMZW5ndGhbMl07ICAgICAgICAgICAgLyogTGVuZ3RoIG9mIGN1cnJlbnQgYWNjZXNzIHVuaXQuICovCiAgSU5UICAgbnVtYmVyT2ZSYXdEYXRhQmxvY2tzOyAgICAgLyogQ3VycmVudCBudW1iZXIgb2YgcmF3IGRhdGEgYmxvY2tzIGNvbnRhaW5lZCByZW1haW5pbmcgZnJvbSB0aGUgY3VycmVudCB0cmFuc3BvcnQgZnJhbWUuICovCiAgVUlOVCAgYXZnQml0UmF0ZTsgICAgICAgICAgICAgICAgLyogQXZlcmFnZSBiaXQgcmF0ZSB1c2VkIGZvciBmcmFtZSBsb3NzIGVzdGltYXRpb24uICovCiAgVUlOVCAgbGFzdFZhbGlkQnVmZmVyRnVsbG5lc3M7ICAgLyogTGFzdCB2YWxpZCBidWZmZXIgZnVsbG5lc3MgdmFsdWUgZm9yIGZyYW1lIGxvc3MgZXN0aW1hdGlvbiAqLwogIElOVCAgIHJlbWFpbmRlcjsgICAgICAgICAgICAgICAgIC8qIFJlbWluZGVyIGluIGRpdmlzaW9uIGR1cmluZyBsb3N0IGFjY2VzcyB1bml0IGVzdGltYXRpb24uICovCiAgSU5UICAgbWlzc2luZ0FjY2Vzc1VuaXRzOyAgICAgICAgLyogRXN0aW1hdGVkIG1pc3NpbmcgYWNjZXNzIHVuaXRzLiAqLwogIFVJTlQgIGJ1cnN0UGVyaW9kOyAgICAgICAgICAgICAgIC8qIERhdGEgYnVyc3QgcGVyaW9kIGluIG1pbGkgc2Vjb25kcy4gKi8KICBVSU5UICBob2xkT2ZmRnJhbWVzOyAgICAgICAgICAgICAvKiBBbW91bnQgb2YgZnJhbWVzIHRoYXQgd2VyZSBhbHJlYWR5IGhvbGQgb2ZmIGR1ZSB0byBidWZmZXIgZnVsbG5lc3MgY29uZGl0aW9uIG5vdCBiZWluZyBtZXQuICovCiAgVUlOVCAgZmxhZ3M7ICAgICAgICAgICAgICAgICAgICAgLyogRmxhZ3MuICovCn07CgovKiBGbGFnIGJpdG1hc2tzIGZvciAiZmxhZ3MiIG1lbWJlciBvZiBzdHJ1Y3QgVFJBTlNQT1JUREVDICovCiNkZWZpbmUgVFBERUNfU1lOQ09LICAgICAgICAgICAgICAgIDEKI2RlZmluZSBUUERFQ19NSU5JTUlaRV9ERUxBWSAgICAgICAgMgojZGVmaW5lIFRQREVDX0lHTk9SRV9CVUZGRVJGVUxMTkVTUyA0CiNkZWZpbmUgVFBERUNfRUFSTFlfQ09ORklHICAgICAgICAgIDgKI2RlZmluZSBUUERFQ19MT1NUX0ZSQU1FU19QRU5ESU5HICAxNgojZGVmaW5lIFRQREVDX0NPTkZJR19GT1VORCAgICAgICAgIDMyCgpDX0FMTE9DX01FTShSYW1fVHJhbnNwb3J0RGVjb2RlciwgVFJBTlNQT1JUREVDLCAxKQpDX0FMTE9DX01FTShSYW1fVHJhbnNwb3J0RGVjb2RlckJ1ZmZlciwgVUNIQVIsIFRSQU5TUE9SVERFQ19JTkJVRl9TSVpFKQoKCgoKSEFORExFX1RSQU5TUE9SVERFQyB0cmFuc3BvcnREZWNfT3BlbiggY29uc3QgVFJBTlNQT1JUX1RZUEUgdHJhbnNwb3J0Rm10LCBjb25zdCBVSU5UIGZsYWdzKQp7CiAgSEFORExFX1RSQU5TUE9SVERFQyBoSW5wdXQ7CgogIGhJbnB1dCA9IEdldFJhbV9UcmFuc3BvcnREZWNvZGVyKDApOwogIGlmICggaElucHV0ID09IE5VTEwgKSB7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIC8qIEluaXQgdHJhbnNwb3J0RGVjIHN0cnVjdC4gKi8KICBoSW5wdXQtPnRyYW5zcG9ydEZtdCA9IHRyYW5zcG9ydEZtdDsKCiAgc3dpdGNoICh0cmFuc3BvcnRGbXQpIHsKCiAgY2FzZSBUVF9NUDRfQURJRjoKICAgIGJyZWFrOwoKICBjYXNlIFRUX01QNF9BRFRTOgogICAgaWYgKGZsYWdzICYgVFBfRkxBR19NUEVHNCkKICAgICAgaElucHV0LT5wYXJzZXIuYWR0cy5kZWNvZGVyQ2FuRG9NcGVnNCA9IDE7CiAgICBlbHNlCiAgICAgIGhJbnB1dC0+cGFyc2VyLmFkdHMuZGVjb2RlckNhbkRvTXBlZzQgPSAwOwogICAgYWR0c1JlYWRfQ3JjSW5pdCgmaElucHV0LT5wYXJzZXIuYWR0cyk7CiAgICBoSW5wdXQtPnBhcnNlci5hZHRzLkJ1ZmZlckZ1bGxuZXNTdGFydEZsYWcgPSAxOwogICAgaElucHV0LT5udW1iZXJPZlJhd0RhdGFCbG9ja3MgPSAwOwogICAgYnJlYWs7CgoKICBjYXNlIFRUX01QNF9MQVRNX01DUDA6CiAgY2FzZSBUVF9NUDRfTEFUTV9NQ1AxOgogIGNhc2UgVFRfTVA0X0xPQVM6CiAgY2FzZSBUVF9NUDRfUkFXOgogICAgYnJlYWs7CgogIGRlZmF1bHQ6CiAgICBGcmVlUmFtX1RyYW5zcG9ydERlY29kZXIoJmhJbnB1dCk7CiAgICBoSW5wdXQgPSBOVUxMOwogICAgYnJlYWs7CiAgfQoKICBpZiAoaElucHV0ICE9IE5VTEwpIHsKICAgIC8qIENyZWF0ZSBiaXRzdHJlYW0gKi8KICAgIGlmICggVFRfSVNfUEFDS0VUKHRyYW5zcG9ydEZtdCkgKSB7CiAgICAgIGhJbnB1dC0+YnNCdWZmZXIgPSBOVUxMOwogICAgfSBlbHNlIHsKICAgICAgaElucHV0LT5ic0J1ZmZlciA9IEdldFJhbV9UcmFuc3BvcnREZWNvZGVyQnVmZmVyKDApOwogICAgICBpZiAoaElucHV0LT5ic0J1ZmZlciA9PSBOVUxMKSB7CiAgICAgICAgICB0cmFuc3BvcnREZWNfQ2xvc2UoICZoSW5wdXQgKTsKICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICB9CiAgICAgIEZES2luaXRCaXRTdHJlYW0oJmhJbnB1dC0+Yml0U3RyZWFtWzBdLCBoSW5wdXQtPmJzQnVmZmVyLCBUUkFOU1BPUlRERUNfSU5CVUZfU0laRSwgMCwgQlNfUkVBREVSKTsKICAgIH0KCiAgICBoSW5wdXQtPmJ1cnN0UGVyaW9kID0gMDsKICB9CgogIHJldHVybiBoSW5wdXQ7Cn0KClRSQU5TUE9SVERFQ19FUlJPUiB0cmFuc3BvcnREZWNfT3V0T2ZCYW5kQ29uZmlnKEhBTkRMRV9UUkFOU1BPUlRERUMgaFRwLCBVQ0hBUiAqY29uZiwgY29uc3QgVUlOVCBsZW5ndGgsIFVJTlQgbGF5ZXIgKQp7CiAgVFJBTlNQT1JUREVDX0VSUk9SICAgICBlcnIgICAgICAgID0gVFJBTlNQT1JUREVDX09LOwoKICBGREtfQklUU1RSRUFNIGJzOwogIEhBTkRMRV9GREtfQklUU1RSRUFNICBoQnMgICAgICAgID0gJmJzOwoKICBGREtpbml0Qml0U3RyZWFtKGhCcywgY29uZiwgMHgxMDAwMDAwMCwgbGVuZ3RoPDwzLCBCU19SRUFERVIpOwoKICBpbnQgZkNvbmZpZ0ZvdW5kID0gMDsKCiAgLyogY29uZmlnIHRyYW5zcG9ydCBkZWNvZGVyICovCiAgc3dpdGNoIChoVHAtPnRyYW5zcG9ydEZtdCkgewogICAgY2FzZSBUVF9NUDRfTEFUTV9NQ1AwOgogICAgY2FzZSBUVF9NUDRfTEFUTV9NQ1AxOgogICAgY2FzZSBUVF9NUDRfTE9BUzoKICAgICAgewogICAgICAgIGlmIChsYXllciAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gVFJBTlNQT1JUREVDX0lOVkFMSURfUEFSQU1FVEVSOwogICAgICAgIH0KICAgICAgICBDTGF0bURlbXV4ICpwTGF0bURlbXV4ID0gJmhUcC0+cGFyc2VyLmxhdG07CiAgICAgICAgZXJyID0gQ0xhdG1EZW11eF9SZWFkU3RyZWFtTXV4Q29uZmlnKGhCcywgcExhdG1EZW11eCwgJmhUcC0+Y2FsbGJhY2tzLCBoVHAtPmFzYywgJmZDb25maWdGb3VuZCk7CiAgICAgICAgaWYgKGVyciAhPSBUUkFOU1BPUlRERUNfT0spIHsKICAgICAgICAgIHJldHVybiBlcnI7CiAgICAgICAgfQogICAgICB9CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgZkNvbmZpZ0ZvdW5kID0gMTsKICAgICAgZXJyID0gQXVkaW9TcGVjaWZpY0NvbmZpZ19QYXJzZSgmaFRwLT5hc2NbbGF5ZXJdLCBoQnMsIDEsICZoVHAtPmNhbGxiYWNrcyk7CiAgICAgIGlmIChlcnIgPT0gVFJBTlNQT1JUREVDX09LKSB7CiAgICAgICAgaW50IGVyckM7CgogICAgICAgIGVyckMgPSBoVHAtPmNhbGxiYWNrcy5jYlVwZGF0ZUNvbmZpZyhoVHAtPmNhbGxiYWNrcy5jYlVwZGF0ZUNvbmZpZ0RhdGEsICZoVHAtPmFzY1tsYXllcl0pOwogICAgICAgIGlmIChlcnJDICE9IDApIHsKICAgICAgICAgIGVyciA9IFRSQU5TUE9SVERFQ19QQVJTRV9FUlJPUjsKICAgICAgICB9CiAgICAgIH0KICAgICAgYnJlYWs7CiAgfQoKICBpZiAoZXJyID09IFRSQU5TUE9SVERFQ19PSyAmJiBmQ29uZmlnRm91bmQpIHsKICAgIGhUcC0+ZmxhZ3MgfD0gVFBERUNfQ09ORklHX0ZPVU5EOwogIH0KCiAgcmV0dXJuIGVycjsKfQoKaW50IHRyYW5zcG9ydERlY19SZWdpc3RlckFzY0NhbGxiYWNrKCBIQU5ETEVfVFJBTlNQT1JUREVDIGhUcERlYywgY29uc3QgY2JVcGRhdGVDb25maWdfdCBjYlVwZGF0ZUNvbmZpZywgdm9pZCogdXNlcl9kYXRhKQp7CiAgaWYgKGhUcERlYyA9PSBOVUxMKSB7CiAgICByZXR1cm4gLTE7CiAgfQogIGhUcERlYy0+Y2FsbGJhY2tzLmNiVXBkYXRlQ29uZmlnID0gY2JVcGRhdGVDb25maWc7CiAgaFRwRGVjLT5jYWxsYmFja3MuY2JVcGRhdGVDb25maWdEYXRhID0gdXNlcl9kYXRhOwogIHJldHVybiAwOwp9CgppbnQgdHJhbnNwb3J0RGVjX1JlZ2lzdGVyU3NjQ2FsbGJhY2soIEhBTkRMRV9UUkFOU1BPUlRERUMgaFRwRGVjLCBjb25zdCBjYlNzY190IGNiU3NjLCB2b2lkKiB1c2VyX2RhdGEpCnsKICBpZiAoaFRwRGVjID09IE5VTEwpIHsKICAgIHJldHVybiAtMTsKICB9CiAgaFRwRGVjLT5jYWxsYmFja3MuY2JTc2MgPSBjYlNzYzsKICBoVHBEZWMtPmNhbGxiYWNrcy5jYlNzY0RhdGEgPSB1c2VyX2RhdGE7CiAgcmV0dXJuIDA7Cn0KCmludCB0cmFuc3BvcnREZWNfUmVnaXN0ZXJTYnJDYWxsYmFjayggSEFORExFX1RSQU5TUE9SVERFQyBoVHBEZWMsIGNvbnN0IGNiU2JyX3QgY2JTYnIsIHZvaWQqIHVzZXJfZGF0YSkKewogIGlmIChoVHBEZWMgPT0gTlVMTCkgewogICAgcmV0dXJuIC0xOwogIH0KICBoVHBEZWMtPmNhbGxiYWNrcy5jYlNiciA9IGNiU2JyOwogIGhUcERlYy0+Y2FsbGJhY2tzLmNiU2JyRGF0YSA9IHVzZXJfZGF0YTsKICByZXR1cm4gMDsKfQoKVFJBTlNQT1JUREVDX0VSUk9SIHRyYW5zcG9ydERlY19GaWxsRGF0YSgKICAgICAgICBjb25zdCBIQU5ETEVfVFJBTlNQT1JUREVDICBoVHAsCiAgICAgICAgVUNIQVIgICAgICAgICAgICAgICAgICAgICAqcEJ1ZmZlciwKICAgICAgICBjb25zdCBVSU5UICAgICAgICAgICAgICAgICBidWZmZXJTaXplLAogICAgICAgIFVJTlQgICAgICAgICAgICAgICAgICAgICAgKnBCeXRlc1ZhbGlkLAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICAgIGxheWVyICkKewogIEhBTkRMRV9GREtfQklUU1RSRUFNIGhCczsKCiAgaWYgKCAoaFRwID09IE5VTEwpCiAgICB8fCAobGF5ZXIgPj0gMikgKSB7CiAgICByZXR1cm4gVFJBTlNQT1JUREVDX0lOVkFMSURfUEFSQU1FVEVSOwogIH0KCiAgaWYgKCpwQnl0ZXNWYWxpZCA9PSAwKSB7CiAgICAvKiBub3RoaW5nIHRvIGRvICovCiAgICByZXR1cm4gVFJBTlNQT1JUREVDX09LOwogIH0KCiAgLyogc2V0IGJpdGJ1ZmZlciBzaG9ydGN1dCAqLwogIGhCcyA9ICZoVHAtPmJpdFN0cmVhbVtsYXllcl07CgogIGlmICggVFRfSVNfUEFDS0VUKGhUcC0+dHJhbnNwb3J0Rm10KSApIHsKICAgIGlmIChoVHAtPm51bWJlck9mUmF3RGF0YUJsb2NrcyA9PSAwKSB7CiAgICAvKiBGb3IgcGFja2V0IGJhc2VkIHRyYW5zcG9ydCwgcGFzcyBpbnB1dCBidWZmZXIgdG8gYml0YnVmZmVyIHdpdGhvdXQgY29weWluZyB0aGUgZGF0YS4KICAgICAgIFVuZm9ydHVuYXRlbHkgd2UgZG8gbm90IGtub3cgdGhlIGFjdHVhbCBidWZmZXIgc2l6ZS4gQW5kIHRoZSBGREsgYml0IGJ1ZmZlciBpbXBsZW1lbnRhdGlvbgogICAgICAgbmVlZHMgYSBudW1iZXIgMl54LiBTbyB3ZSBhc3N1bWUgdGhlIG1heGltdW0gb2YgNDggY2hhbm5lbHMgd2l0aCA2MTQ0IGJpdHMgcGVyIGNoYW5uZWwKICAgICAgIGFuZCByb3VuZCBpdCB1cCB0byB0aGUgbmV4dCBwb3dlciBvZiAyID0+IDY1NTM2IGJ5dGVzICovCiAgICBGREtpbml0Qml0U3RyZWFtKGhCcywgcEJ1ZmZlciwgMHgxMDAwMCwgKCpwQnl0ZXNWYWxpZCk8PDMsIEJTX1JFQURFUik7CiAgICAqcEJ5dGVzVmFsaWQgPSAwOwogICAgfQogIH0gZWxzZSB7CiAgICAvKiAuLi4gZWxzZSBmZWVkIGJpdGJ1ZmZlciB3aXRoIG5ldyBzdHJlYW0gZGF0YSAoYXBwZW5kKS4gKi8KICAgIGlmIChoVHAtPm51bWJlck9mUmF3RGF0YUJsb2NrcyA8PSAwKSB7CiAgICAgIEZES2ZlZWRCdWZmZXIgKGhCcywgcEJ1ZmZlciwgYnVmZmVyU2l6ZSwgcEJ5dGVzVmFsaWQpIDsKICAgIH0KICB9CgogIHJldHVybiBUUkFOU1BPUlRERUNfT0s7Cn0KCkhBTkRMRV9GREtfQklUU1RSRUFNIHRyYW5zcG9ydERlY19HZXRCaXRzdHJlYW0oIGNvbnN0IEhBTkRMRV9UUkFOU1BPUlRERUMgaFRwLCBjb25zdCBVSU5UIGxheWVyICkKewogIHJldHVybiAmaFRwLT5iaXRTdHJlYW1bbGF5ZXJdOwp9CgpUUkFOU1BPUlRfVFlQRSB0cmFuc3BvcnREZWNfR2V0Rm9ybWF0KCBjb25zdCBIQU5ETEVfVFJBTlNQT1JUREVDIGhUcCApCnsKICByZXR1cm4gaFRwLT50cmFuc3BvcnRGbXQ7Cn0KCklOVCB0cmFuc3BvcnREZWNfR2V0QnVmZmVyRnVsbG5lc3MoIGNvbnN0IEhBTkRMRV9UUkFOU1BPUlRERUMgaFRwICkKewogIElOVCBidWZmZXJGdWxsbmVzcyA9IC0xOwoKICBzd2l0Y2ggKGhUcC0+dHJhbnNwb3J0Rm10KSB7CiAgICBjYXNlIFRUX01QNF9BRFRTOgogICAgICBpZiAoaFRwLT5wYXJzZXIuYWR0cy5icy5hZHRzX2Z1bGxuZXNzICE9IDB4N2ZmKSB7CiAgICAgICAgYnVmZmVyRnVsbG5lc3MgPSBoVHAtPnBhcnNlci5hZHRzLmJzLmZyYW1lX2xlbmd0aCo4ICsgaFRwLT5wYXJzZXIuYWR0cy5icy5hZHRzX2Z1bGxuZXNzICogMzIgKiBnZXROdW1iZXJPZkVmZmVjdGl2ZUNoYW5uZWxzKGhUcC0+cGFyc2VyLmFkdHMuYnMuY2hhbm5lbF9jb25maWcpOwogICAgICB9CiAgICAgIGJyZWFrOwogICAgY2FzZSBUVF9NUDRfTE9BUzoKICAgIGNhc2UgVFRfTVA0X0xBVE1fTUNQMDoKICAgIGNhc2UgVFRfTVA0X0xBVE1fTUNQMToKICAgICAgaWYgKGhUcC0+cGFyc2VyLmxhdG0ubV9saW5mb1swXVswXS5tX2J1ZmZlckZ1bGxuZXNzICE9IDB4ZmYpIHsKICAgICAgICBidWZmZXJGdWxsbmVzcyA9IGhUcC0+cGFyc2VyLmxhdG0ubV9saW5mb1swXVswXS5tX2J1ZmZlckZ1bGxuZXNzOwogICAgICB9CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgYnJlYWs7CiAgfQoKICByZXR1cm4gYnVmZmVyRnVsbG5lc3M7Cn0KCi8qKgogKiBcYnJpZWYgYWRqdXN0IGJpdCBzdHJlYW0gcG9zaXRpb24gYW5kIHRoZSBlbmQgb2YgYW4gYWNjZXNzIHVuaXQuCiAqIFxwYXJhbSBoVHAgdHJhbnNwb3J0IGRlY29kZXIgaGFuZGxlLgogKiBccmV0dXJuIGVycm9yIGNvZGUuCiAqLwpzdGF0aWMKVFJBTlNQT1JUREVDX0VSUk9SIHRyYW5zcG9ydERlY19BZGp1c3RFbmRPZkFjY2Vzc1VuaXQoSEFORExFX1RSQU5TUE9SVERFQyBoVHApCnsKICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQnMgPSAmaFRwLT5iaXRTdHJlYW1bMF07CiAgVFJBTlNQT1JUREVDX0VSUk9SIGVyciA9IFRSQU5TUE9SVERFQ19PSzsKCiAgc3dpdGNoIChoVHAtPnRyYW5zcG9ydEZtdCkgewogICAgY2FzZSBUVF9NUDRfTE9BUzoKICAgIGNhc2UgVFRfTVA0X0xBVE1fTUNQMDoKICAgIGNhc2UgVFRfTVA0X0xBVE1fTUNQMToKICAgICAgaWYgKCBoVHAtPm51bWJlck9mUmF3RGF0YUJsb2NrcyA9PSAwICkKICAgICAgewogICAgICAgIC8qIERvIGJ5dGUgYWxpZ24gYXQgdGhlIGVuZCBvZiBBdWRpb011eEVsZW1lbnQuICovCiAgICAgICAgRkRLYnl0ZUFsaWduKGhCcywgaFRwLT5nbG9iYWxGcmFtZVBvcyk7CgogICAgICAgIC8qIENoZWNrIGdsb2JhbCBmcmFtZSBsZW5ndGggKi8KICAgICAgICBpZiAoaFRwLT50cmFuc3BvcnRGbXQgPT0gVFRfTVA0X0xPQVMgJiYgaFRwLT5wYXJzZXIubGF0bS5tX2F1ZGlvTXV4TGVuZ3RoQnl0ZXMgPiAwKQogICAgICAgIHsKICAgICAgICAgIGludCBsb2FzT2Zmc2V0OwoKICAgICAgICAgIGxvYXNPZmZzZXQgPSAoaFRwLT5wYXJzZXIubGF0bS5tX2F1ZGlvTXV4TGVuZ3RoQnl0ZXMqOCArIEZES2dldFZhbGlkQml0cyhoQnMpKSAtIGhUcC0+Z2xvYmFsRnJhbWVQb3M7CiAgICAgICAgICBpZiAobG9hc09mZnNldCAhPSAwKSB7CiAgICAgICAgICAgIEZES3B1c2hCaURpcmVjdGlvbmFsKGhCcywgbG9hc09mZnNldCk7CiAgICAgICAgICAgIC8qIEZvciBFTEQgYW5kIG90aGVyIHBheWxvYWRzIHRoZXJlIGlzIGFuIHVua25vd24gYW1vdW50IG9mIHBhZGRpbmcsIHNvIGlnbm9yZSB1bnJlYWQgYml0cywgYnV0CiAgICAgICAgICAgICAgIHRocm93IGFuIGVycm9yIG9ubHkgaWYgdG9vIG1hbnkgYml0cyB3aGVyZSByZWFkLiAqLwogICAgICAgICAgICBpZiAobG9hc09mZnNldCA8IDApIHsKICAgICAgICAgICAgICBlcnIgPSBUUkFOU1BPUlRERUNfUEFSU0VfRVJST1I7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgYnJlYWs7CgogICAgY2FzZSBUVF9NUDRfQURUUzoKICAgICAgaWYgKGhUcC0+cGFyc2VyLmFkdHMuYnMucHJvdGVjdGlvbl9hYnNlbnQgPT0gMCkKICAgICAgewogICAgICAgIGludCBvZmZzZXQ7CgogICAgICAgIC8qIENhbGN1bGF0ZSBvZmZzZXQgdG8gZW5kIG9mIEFVICovCiAgICAgICAgb2Zmc2V0ICA9IGhUcC0+cGFyc2VyLmFkdHMucmF3RGF0YUJsb2NrRGlzdFtoVHAtPnBhcnNlci5hZHRzLmJzLm51bV9yYXdfYmxvY2tzLWhUcC0+bnVtYmVyT2ZSYXdEYXRhQmxvY2tzXTw8MzsKICAgICAgICAvKiBDQVVUSU9OOiBUaGUgUENFIChpZiBhdmFpbGFibGUpIGlzIGRlY2xhcmVkIHRvIGJlIGEgcGFydCBvZiB0aGUgaGVhZGVyISAqLwogICAgICAgIG9mZnNldCAtPSBoVHAtPmFjY2Vzc1VuaXRBbmNob3JbMF0gLSBGREtnZXRWYWxpZEJpdHMoaEJzKSArIDE2ICsgaFRwLT5wYXJzZXIuYWR0cy5icy5udW1fcGNlX2JpdHM7CiAgICAgICAgRkRLcHVzaEJpRGlyZWN0aW9uYWwoaEJzLCBvZmZzZXQpOwogICAgICB9CiAgICAgIGlmIChoVHAtPnBhcnNlci5hZHRzLmJzLm51bV9yYXdfYmxvY2tzID4gMCAmJiBoVHAtPnBhcnNlci5hZHRzLmJzLnByb3RlY3Rpb25fYWJzZW50ID09IDApIHsKICAgICAgICAvKiBOb3RlIHRoaXMgQ1JDIHJlYWQgY3VycmVudGx5IGhhcHBlbnMgdHdpY2UgYmVjYXVzZSBvZiB0cmFuc3BvcnREZWNfQ3JjQ2hlY2soKSAqLwogICAgICAgIGhUcC0+cGFyc2VyLmFkdHMuY3JjUmVhZFZhbHVlID0gRkRLcmVhZEJpdHMoaEJzLCAxNik7CiAgICAgIH0KICAgICAgaWYgKCBoVHAtPm51bWJlck9mUmF3RGF0YUJsb2NrcyA9PSAwICkKICAgICAgewogICAgICAgIC8qIENoZWNrIGdsb2JhbCBmcmFtZSBsZW5ndGggKi8KICAgICAgICBpZiAoaFRwLT5wYXJzZXIuYWR0cy5icy5wcm90ZWN0aW9uX2Fic2VudCA9PSAwKQogICAgICAgIHsKICAgICAgICAgIGludCBvZmZzZXQ7CgogICAgICAgICAgb2Zmc2V0ID0gKGhUcC0+cGFyc2VyLmFkdHMuYnMuZnJhbWVfbGVuZ3RoKjggLSBBRFRTX1NZTkNMRU5HVEggKyBGREtnZXRWYWxpZEJpdHMoaEJzKSkgLSBoVHAtPmdsb2JhbEZyYW1lUG9zOwogICAgICAgICAgaWYgKG9mZnNldCAhPSAwKSB7CiAgICAgICAgICAgIEZES3B1c2hCaURpcmVjdGlvbmFsKGhCcywgb2Zmc2V0KTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgYnJlYWs7CiAgfQoKICByZXR1cm4gZXJyOwp9CgoKLyoqCiAqIFxicmllZiBEZXRlcm1pbmUgYWRkaXRpb25hbCBidWZmZXIgZnVsbG5lc3MgY29udHJhaW50IGR1ZSB0byBidXJzdCBkYXRhIHJlY2VwdGlvbi4KICogICAgICAgIFRoZSBwYXJhbWV0ZXIgVFBERUNfUEFSQU1fQlVSU1RQRVJJT0QgbXVzdCBoYXZlIGJlZW4gc2V0IGFzIGEgcHJlY29uZGl0aW9uLgogKiBccGFyYW0gaFRwIHRyYW5zcG9ydCBkZWNvZGVyIGhhbmRsZS4KICogXHBhcmFtIGJ1ZmZlckZ1bGxuZXNzIHRoZSBidWZmZXIgZnVsbG5lc3MgdmFsdWUgb2YgdGhlIGZpcnN0IGZyYW1lIHRvIGJlIGRlY29kZWQuCiAqIFxwYXJhbSBiaXRzQXZhaWwgdGhlIGFtb3VudCBvZiBhdmFpbGFibGUgYml0cyBhdCB0aGUgZW5kIG9mIHRoZSBmaXJzdCBmcmFtZSB0byBiZSBkZWNvZGVkLgogKiBccmV0dXJuIGVycm9yIGNvZGUKICovCnN0YXRpYyAKVFJBTlNQT1JUREVDX0VSUk9SIGFkZGl0aW9uYWxIb2xkT2ZmTmVlZGVkKAogICAgICAgIEhBTkRMRV9UUkFOU1BPUlRERUMgaFRwLAogICAgICAgIElOVCAgICAgICAgICAgICAgICAgYnVmZmVyRnVsbG5lc3MsCiAgICAgICAgSU5UICAgICAgICAgICAgICAgICBiaXRzQXZhaWwKICAgICAgICApCnsKICBJTlQgY2hlY2tMZW5ndGhCaXRzLCBhdmdCaXRzUGVyRnJhbWU7CiAgSU5UIG1heEFVOyAvKiBtYXhpbXVtIG51bWJlciBvZiBmcmFtZXMgcGVyIE1hc3RlciBGcmFtZSAqLwogIElOVCBzYW1wbGVzUGVyRnJhbWUgPSBoVHAtPmFzYy0+bV9zYW1wbGVzUGVyRnJhbWU7CiAgSU5UIHNhbXBsaW5nRnJlcXVlbmN5ID0gKElOVCloVHAtPmFzYy0+bV9zYW1wbGluZ0ZyZXF1ZW5jeTsKCiAgaWYgKCAoaFRwLT5hdmdCaXRSYXRlID09IDApIHx8IChoVHAtPmJ1cnN0UGVyaW9kID09IDApICkgewogICAgcmV0dXJuIFRSQU5TUE9SVERFQ19PSzsKICB9CiAgaWYgKCAoc2FtcGxlc1BlckZyYW1lID09IDAgKSB8fCAoc2FtcGxpbmdGcmVxdWVuY3kgPT0gMCkgKSB7CiAgICByZXR1cm4gVFJBTlNQT1JUREVDX05PVF9FTk9VR0hfQklUUzsKICB9CgogIC8qIE9uZSBNYXN0ZXIgRnJhbWUgaXMgc2VudCBldmVyeSBoVHAtPmJ1cnN0UGVyaW9kIG1zICovCiAgbWF4QVUgPSBoVHAtPmJ1cnN0UGVyaW9kICogc2FtcGxpbmdGcmVxdWVuY3kgKyAoc2FtcGxlc1BlckZyYW1lKjEwMDAgLSAxKTsKICBtYXhBVSA9IG1heEFVIC8gKHNhbXBsZXNQZXJGcmFtZSoxMDAwKTsKICAvKiBTdWJ0cmFjdCBudW1iZXIgb2YgZnJhbWVzIHdoaWNoIHdlcmUgYWxyZWFkeSBoZWxkIG9mZi4gKi8KICBtYXhBVSAtPSBoVHAtPmhvbGRPZmZGcmFtZXM7CgogIGF2Z0JpdHNQZXJGcmFtZSA9IGhUcC0+YXZnQml0UmF0ZSAqIHNhbXBsZXNQZXJGcmFtZSArIChzYW1wbGluZ0ZyZXF1ZW5jeS0xKTsKICBhdmdCaXRzUGVyRnJhbWUgPSBhdmdCaXRzUGVyRnJhbWUgLyBzYW1wbGluZ0ZyZXF1ZW5jeTsKCiAgLyogQ29uc2lkZXIgd29yc3QgY2FzZSBvZiBidWZmZXJGdWxsbmVzcyBxdWFudGl6YXRpb24uICovCiAgc3dpdGNoIChoVHAtPnRyYW5zcG9ydEZtdCkgewogICAgY2FzZSBUVF9NUDRfQURJRjoKICAgIGNhc2UgVFRfTVA0X0FEVFM6CiAgICBjYXNlIFRUX01QNF9MT0FTOgogICAgY2FzZSBUVF9NUDRfTEFUTV9NQ1AwOgogICAgY2FzZSBUVF9NUDRfTEFUTV9NQ1AxOgogICAgICBidWZmZXJGdWxsbmVzcyArPSAzMTsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICBicmVhazsKICB9CgogIGNoZWNrTGVuZ3RoQml0cyA9IGJ1ZmZlckZ1bGxuZXNzICsgKG1heEFVLTEpKmF2Z0JpdHNQZXJGcmFtZTsKCiAgLyogQ2hlY2sgaWYgYnVmZmVyIGlzIGJpZyBlbm91Z2ggdG8gZnVsbGZpbGwgYnVmZmVyIGZ1bGxuZXNzIGNvbmRpdGlvbiAqLwogIGlmICggKGNoZWNrTGVuZ3RoQml0cyAvKitoZWFkZXJCaXRzKi8pID4gKChUUkFOU1BPUlRERUNfSU5CVUZfU0laRTw8MyktNykgKSB7CiAgICByZXR1cm4gVFJBTlNQT1JUREVDX1NZTkNfRVJST1I7CiAgfQoKICBpZiAoIGJpdHNBdmFpbCA8IGNoZWNrTGVuZ3RoQml0cyApIHsKICAgIHJldHVybiBUUkFOU1BPUlRERUNfTk9UX0VOT1VHSF9CSVRTOwogIH0KICBlbHNlIHsKICAgIHJldHVybiBUUkFOU1BPUlRERUNfT0s7CiAgfQp9CgpzdGF0aWMgVFJBTlNQT1JUREVDX0VSUk9SIHRyYW5zcG9ydERlY19yZWFkSGVhZGVyKAogICAgICAgIEhBTkRMRV9UUkFOU1BPUlRERUMgaFRwLAogICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGhCcywKICAgICAgICBpbnQgc3luY0xlbmd0aCwKICAgICAgICBpbnQgaWdub3JlQnVmZmVyRnVsbG5lc3MsCiAgICAgICAgaW50ICpwUmF3RGF0YUJsb2NrTGVuZ3RoLAogICAgICAgIGludCAqcGZUcmF2ZXJzZU1vcmVGcmFtZXMsCiAgICAgICAgaW50ICpwU3luY0xheWVyRnJhbWVCaXRzLAogICAgICAgIGludCAqcGZDb25maWdGb3VuZCwKICAgICAgICBpbnQgKnBIZWFkZXJCaXRzCiAgICAgICAgKQp7CiAgVFJBTlNQT1JUREVDX0VSUk9SIGVyciA9IFRSQU5TUE9SVERFQ19PSzsKICBpbnQgcmF3RGF0YUJsb2NrTGVuZ3RoID0gKnBSYXdEYXRhQmxvY2tMZW5ndGg7CiAgaW50IGZUcmF2ZXJzZU1vcmVGcmFtZXMgPSAocGZUcmF2ZXJzZU1vcmVGcmFtZXMgIT0gTlVMTCkgPyAqcGZUcmF2ZXJzZU1vcmVGcmFtZXMgOiAwOwogIGludCBzeW5jTGF5ZXJGcmFtZUJpdHMgPSAocFN5bmNMYXllckZyYW1lQml0cyAhPSBOVUxMKSA/ICpwU3luY0xheWVyRnJhbWVCaXRzIDogMDsKICBpbnQgZkNvbmZpZ0ZvdW5kID0gKHBmQ29uZmlnRm91bmQgIT0gTlVMTCkgPyAqcGZDb25maWdGb3VuZCA6IDA7CiAgaW50IHN0YXJ0UG9zOwoKICBzdGFydFBvcyA9IEZES2dldFZhbGlkQml0cyhoQnMpOwoKICBzd2l0Y2ggKGhUcC0+dHJhbnNwb3J0Rm10KSB7CiAgICBjYXNlIFRUX01QNF9BRFRTOgogICAgICBpZiAoaFRwLT5udW1iZXJPZlJhd0RhdGFCbG9ja3MgPD0gMCkKICAgICAgewogICAgICAgIGludCBlcnJDOwoKICAgICAgICBoVHAtPmdsb2JhbEZyYW1lUG9zID0gRkRLZ2V0VmFsaWRCaXRzKGhCcyk7CgogICAgICAgIC8qIFBhcnNlIEFEVFMgaGVhZGVyICovCiAgICAgICAgZXJyID0gYWR0c1JlYWRfRGVjb2RlSGVhZGVyKCAmaFRwLT5wYXJzZXIuYWR0cywgJmhUcC0+YXNjWzBdLCBoQnMsIGlnbm9yZUJ1ZmZlckZ1bGxuZXNzICk7CiAgICAgICAgaWYgKGVyciAhPSBUUkFOU1BPUlRERUNfT0spIHsKICAgICAgICAgIGlmIChlcnIgIT0gVFJBTlNQT1JUREVDX05PVF9FTk9VR0hfQklUUykgewogICAgICAgICAgICBlcnIgPSBUUkFOU1BPUlRERUNfU1lOQ19FUlJPUjsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgZXJyQyA9IGhUcC0+Y2FsbGJhY2tzLmNiVXBkYXRlQ29uZmlnKGhUcC0+Y2FsbGJhY2tzLmNiVXBkYXRlQ29uZmlnRGF0YSwgJmhUcC0+YXNjWzBdKTsKICAgICAgICAgIGlmIChlcnJDICE9IDApIHsKICAgICAgICAgICAgaWYgKGVyckMgPT0gVFJBTlNQT1JUREVDX05FRURfVE9fUkVTVEFSVCkgewogICAgICAgICAgICAgIGVyciA9IFRSQU5TUE9SVERFQ19ORUVEX1RPX1JFU1RBUlQ7CiAgICAgICAgICAgICAgZ290byBiYWlsOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGVyciA9IFRSQU5TUE9SVERFQ19TWU5DX0VSUk9SOwogICAgICAgICAgICB9CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBmQ29uZmlnRm91bmQgPSAxOwogICAgICAgICAgICBoVHAtPm51bWJlck9mUmF3RGF0YUJsb2NrcyA9IGhUcC0+cGFyc2VyLmFkdHMuYnMubnVtX3Jhd19ibG9ja3MrMTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgZWxzZSB7CiAgICAgICAgLyogUmVzZXQgQ1JDIGJlY2F1c2UgdGhlIG5leHQgYml0cyBhcmUgdGhlIGJlZ2lubmluZyBvZiBhIHJhd19kYXRhX2Jsb2NrKCkgKi8KICAgICAgICBGREtjcmNSZXNldCgmaFRwLT5wYXJzZXIuYWR0cy5jcmNJbmZvKTsKICAgICAgICBoVHAtPnBhcnNlci5hZHRzLmJzLm51bV9wY2VfYml0cyA9IDA7CiAgICAgIH0KICAgICAgaWYgKGVyciA9PSBUUkFOU1BPUlRERUNfT0spIHsKICAgICAgICBoVHAtPm51bWJlck9mUmF3RGF0YUJsb2Nrcy0tOwogICAgICAgIHJhd0RhdGFCbG9ja0xlbmd0aCA9IGFkdHNSZWFkX0dldFJhd0RhdGFCbG9ja0xlbmd0aCgmaFRwLT5wYXJzZXIuYWR0cywgKGhUcC0+cGFyc2VyLmFkdHMuYnMubnVtX3Jhd19ibG9ja3MtaFRwLT5udW1iZXJPZlJhd0RhdGFCbG9ja3MpKTsKICAgICAgICBpZiAocmF3RGF0YUJsb2NrTGVuZ3RoIDw9IDApIHsKICAgICAgICAgIC8qIE5vIGZ1cnRoZXIgZnJhbWUgdHJhdmVyc2FsIHBvc3NpYmxlLiAqLwogICAgICAgICAgZlRyYXZlcnNlTW9yZUZyYW1lcyA9IDA7CiAgICAgICAgfQogICAgICAgIHN5bmNMYXllckZyYW1lQml0cyA9IChoVHAtPnBhcnNlci5hZHRzLmJzLmZyYW1lX2xlbmd0aDw8MykgLSAoc3RhcnRQb3MgLSBGREtnZXRWYWxpZEJpdHMoaEJzKSkgLSBzeW5jTGVuZ3RoOwogICAgICAgIGlmIChzeW5jTGF5ZXJGcmFtZUJpdHMgPD0gMCkgewogICAgICAgICAgZXJyID0gVFJBTlNQT1JUREVDX1NZTkNfRVJST1I7CiAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgIGhUcC0+bnVtYmVyT2ZSYXdEYXRhQmxvY2tzID0gMDsKICAgICAgfQogICAgICBicmVhazsKICAgIGNhc2UgVFRfTVA0X0xPQVM6CiAgICAgIGlmIChoVHAtPm51bWJlck9mUmF3RGF0YUJsb2NrcyA8PSAwKQogICAgICB7CiAgICAgICAgc3luY0xheWVyRnJhbWVCaXRzID0gRkRLcmVhZEJpdHMoaEJzLCAxMyk7CiAgICAgICAgaFRwLT5wYXJzZXIubGF0bS5tX2F1ZGlvTXV4TGVuZ3RoQnl0ZXMgPSBzeW5jTGF5ZXJGcmFtZUJpdHM7CiAgICAgICAgc3luY0xheWVyRnJhbWVCaXRzIDw8PSAzOwogICAgICB9CiAgICBjYXNlIFRUX01QNF9MQVRNX01DUDE6CiAgICBjYXNlIFRUX01QNF9MQVRNX01DUDA6CiAgICAgIGlmIChoVHAtPm51bWJlck9mUmF3RGF0YUJsb2NrcyA8PSAwKQogICAgICB7CiAgICAgICAgaFRwLT5nbG9iYWxGcmFtZVBvcyA9IEZES2dldFZhbGlkQml0cyhoQnMpOwoKICAgICAgICBlcnIgPSBDTGF0bURlbXV4X1JlYWQoCiAgICAgICAgICAgICAgICBoQnMsCiAgICAgICAgICAgICAgICZoVHAtPnBhcnNlci5sYXRtLAogICAgICAgICAgICAgICAgaFRwLT50cmFuc3BvcnRGbXQsCiAgICAgICAgICAgICAgICZoVHAtPmNhbGxiYWNrcywKICAgICAgICAgICAgICAgIGhUcC0+YXNjLAogICAgICAgICAgICAgICAmZkNvbmZpZ0ZvdW5kLAogICAgICAgICAgICAgICAgaWdub3JlQnVmZmVyRnVsbG5lc3MpOwoKICAgICAgICBpZiAoZXJyICE9IFRSQU5TUE9SVERFQ19PSykgewogICAgICAgICAgaWYgKGVyciAhPSBUUkFOU1BPUlRERUNfTk9UX0VOT1VHSF9CSVRTKSB7CiAgICAgICAgICAgIGVyciA9IFRSQU5TUE9SVERFQ19TWU5DX0VSUk9SOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBoVHAtPm51bWJlck9mUmF3RGF0YUJsb2NrcyA9IENMYXRtRGVtdXhfR2V0TnJPZlN1YkZyYW1lcygmaFRwLT5wYXJzZXIubGF0bSk7CiAgICAgICAgICBpZiAoaFRwLT50cmFuc3BvcnRGbXQgPT0gVFRfTVA0X0xPQVMpIHsKICAgICAgICAgICAgc3luY0xheWVyRnJhbWVCaXRzIC09IHN0YXJ0UG9zIC0gRkRLZ2V0VmFsaWRCaXRzKGhCcykgLSAoMTMpOyAgICAgICAgICAgIAogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBlcnIgPSBDTGF0bURlbXV4X1JlYWRQYXlsb2FkTGVuZ3RoSW5mbyhoQnMsICZoVHAtPnBhcnNlci5sYXRtKTsKICAgICAgICBpZiAoZXJyICE9IFRSQU5TUE9SVERFQ19PSykgewogICAgICAgICAgZXJyID0gVFJBTlNQT1JUREVDX1NZTkNfRVJST1I7CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmIChlcnIgPT0gVFJBTlNQT1JUREVDX09LKSB7CiAgICAgICAgcmF3RGF0YUJsb2NrTGVuZ3RoID0gQ0xhdG1EZW11eF9HZXRGcmFtZUxlbmd0aEluQml0cygmaFRwLT5wYXJzZXIubGF0bSk7CiAgICAgICAgaFRwLT5udW1iZXJPZlJhd0RhdGFCbG9ja3MtLTsKICAgICAgfSBlbHNlIHsKICAgICAgICBoVHAtPm51bWJlck9mUmF3RGF0YUJsb2NrcyA9IDA7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICB7CiAgICAgICAgc3luY0xheWVyRnJhbWVCaXRzID0gMDsKICAgICAgfQogICAgICBicmVhazsKICB9CgpiYWlsOgoKICAqcFJhd0RhdGFCbG9ja0xlbmd0aCA9IHJhd0RhdGFCbG9ja0xlbmd0aDsKCiAgaWYgKHBIZWFkZXJCaXRzICE9IE5VTEwpIHsKICAgICpwSGVhZGVyQml0cyArPSBzdGFydFBvcyAtIChJTlQpRkRLZ2V0VmFsaWRCaXRzKGhCcyk7CiAgfQogIGlmIChwZkNvbmZpZ0ZvdW5kICE9IE5VTEwpIHsKICAgICpwZkNvbmZpZ0ZvdW5kID0gZkNvbmZpZ0ZvdW5kOwogIH0KCiAgaWYgKHBmVHJhdmVyc2VNb3JlRnJhbWVzICE9IE5VTEwpIHsKICAgICpwZlRyYXZlcnNlTW9yZUZyYW1lcyA9IGZUcmF2ZXJzZU1vcmVGcmFtZXM7CiAgfQogIGlmICAocFN5bmNMYXllckZyYW1lQml0cyAhPSBOVUxMKSB7CiAgICAqcFN5bmNMYXllckZyYW1lQml0cyA9IHN5bmNMYXllckZyYW1lQml0czsKICB9CiAgaWYgKHBmQ29uZmlnRm91bmQgIT0gTlVMTCkgewogICAgKnBmQ29uZmlnRm91bmQgPSBmQ29uZmlnRm91bmQ7CiAgfQoKICByZXR1cm4gZXJyOwp9CgovKiBIb3cgbWFueSBiaXRzIHRvIGFkdmFuY2UgZm9yIHN5bmNocm9uaXphdGlvbiBzZWFyY2guICovCiNkZWZpbmUgVFBERUNfU1lOQ1NLSVAgOAoKc3RhdGljClRSQU5TUE9SVERFQ19FUlJPUiBzeW5jaHJvbml6YXRpb24oCiAgICAgICAgSEFORExFX1RSQU5TUE9SVERFQyBoVHAsCiAgICAgICAgSU5UICAgICAgICAgICAgICAgICpwSGVhZGVyQml0cwogICAgICAgICkKewogIFRSQU5TUE9SVERFQ19FUlJPUiBlcnIgPSBUUkFOU1BPUlRERUNfT0ssIGVyckZpcnN0RnJhbWUgPSBUUkFOU1BPUlRERUNfT0s7CiAgSEFORExFX0ZES19CSVRTVFJFQU0gaEJzID0gJmhUcC0+Yml0U3RyZWFtWzBdOwoKICBJTlQgc3luY0xheWVyRnJhbWVCaXRzID0gMDsgLyogTGVuZ3RoIG9mIHN5bmMgbGF5ZXIgZnJhbWUgKGkuZS4gTE9BUykgKi8KICBJTlQgcmF3RGF0YUJsb2NrTGVuZ3RoID0gMCwgcmF3RGF0YUJsb2NrTGVuZ3RoUHJldmlvdXM7CiAgSU5UIHRvdGFsQml0czsKICBJTlQgaGVhZGVyQml0cyA9IDAsIGhlYWRlckJpdHNGaXJzdEZyYW1lID0gMCwgaGVhZGVyQml0c1ByZXZpb3VzOwogIElOVCBudW1GcmFtZXNUcmF2ZXJzZWQgPSAwLCBmVHJhdmVyc2VNb3JlRnJhbWVzLCBmQ29uZmlnRm91bmQgPSAoaFRwLT5mbGFncyAmIFRQREVDX0NPTkZJR19GT1VORCksIHN0YXJ0UG9zRmlyc3RGcmFtZSA9IC0xOwogIElOVCBudW1SYXdEYXRhQmxvY2tzRmlyc3RGcmFtZSA9IDAsIG51bVJhd0RhdGFCbG9ja3NQcmV2aW91cywgZ2xvYmFsRnJhbWVQb3NGaXJzdEZyYW1lID0gMCwgcmF3RGF0YUJsb2NrTGVuZ3RoRmlyc3RGcmFtZSA9IDA7CiAgSU5UIGlnbm9yZUJ1ZmZlckZ1bGxuZXNzID0gaFRwLT5mbGFncyAmIChUUERFQ19MT1NUX0ZSQU1FU19QRU5ESU5HfFRQREVDX0lHTk9SRV9CVUZGRVJGVUxMTkVTU3xUUERFQ19TWU5DT0spOwoKICAvKiBTeW5jaCBwYXJhbWV0ZXJzICovCiAgSU5UIHN5bmNMZW5ndGg7ICAgICAgLyogTGVuZ3RoIG9mIHN5bmMgd29yZCBpbiBiaXRzICovCiAgVUlOVCBzeW5jV29yZDsgICAgICAgLyogU3luYyB3b3JkIHRvIGJlIGZvdW5kICovCiAgVUlOVCBzeW5jTWFzazsgICAgICAgLyogTWFzayBmb3Igc3luYyB3b3JkIChmb3IgYWRkaW5nIG9uZSBiaXQsIHNvIGNvbXByaXNpbmcgb25lIGJpdCBsZXNzKSAqLwogIENfQUxMT0NfU0NSQVRDSF9TVEFSVChjb250ZXh0Rmlyc3RGcmFtZSwgdHJhbnNwb3J0ZGVjX3BhcnNlcl90LCAxKTsKCiAgdG90YWxCaXRzID0gKElOVClGREtnZXRWYWxpZEJpdHMoaEJzKTsKCiAgaWYgKHRvdGFsQml0cyA8PSAwKSB7CiAgICBlcnIgPSBUUkFOU1BPUlRERUNfTk9UX0VOT1VHSF9CSVRTOwogICAgZ290byBiYWlsOwogIH0KCiAgZlRyYXZlcnNlTW9yZUZyYW1lcyA9IChoVHAtPmZsYWdzICYgKFRQREVDX01JTklNSVpFX0RFTEFZfFRQREVDX0VBUkxZX0NPTkZJRykpICYmICEgKGhUcC0+ZmxhZ3MgJiBUUERFQ19TWU5DT0spOwoKICAvKiBTZXQgdHJhbnNwb3J0IHNwZWNpZmljIHN5bmMgcGFyYW1ldGVycyAqLwogIHN3aXRjaCAoaFRwLT50cmFuc3BvcnRGbXQpIHsKICAgIGNhc2UgVFRfTVA0X0FEVFM6CiAgICAgIHN5bmNXb3JkID0gQURUU19TWU5DV09SRDsKICAgICAgc3luY0xlbmd0aCA9IEFEVFNfU1lOQ0xFTkdUSDsKICAgICAgYnJlYWs7CiAgICBjYXNlIFRUX01QNF9MT0FTOgogICAgICBzeW5jV29yZCA9IDB4MkI3OwogICAgICBzeW5jTGVuZ3RoID0gMTE7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgc3luY1dvcmQgPSAwOwogICAgICBzeW5jTGVuZ3RoID0gMDsKICAgICAgYnJlYWs7CiAgfQoKICBzeW5jTWFzayA9ICgxPDxzeW5jTGVuZ3RoKS0xOwoKICBkbyB7CiAgICBJTlQgYml0c0F2YWlsID0gMDsgICAgIC8qIEJpdHMgYXZhaWxhYmxlIGluIGJpdHN0cmVhbSBidWZmZXIgICAgKi8KICAgIElOVCBjaGVja0xlbmd0aEJpdHM7ICAgLyogSGVscGVyIHRvIGNoZWNrIHJlbWFpbmluZyBiaXRzIGFuZCBidWZmZXIgYm91bmRhcmllcyAqLwogICAgVUlOVCBzeW5jaDsgICAgICAgICAgICAvKiBDdXJyZW50IHN5bmMgd29yZCByZWFkIGZyb20gYml0c3RyZWFtICovCgogICAgaGVhZGVyQml0c1ByZXZpb3VzID0gaGVhZGVyQml0czsKCiAgICBiaXRzQXZhaWwgPSAoSU5UKUZES2dldFZhbGlkQml0cyhoQnMpOwoKICAgIGlmIChoVHAtPm51bWJlck9mUmF3RGF0YUJsb2NrcyA9PSAwKSB7CiAgICAgIC8qIHNlYXJjaCBzeW5jaHdvcmQgKi8KCiAgICAgIEZES19BU1NFUlQoIChiaXRzQXZhaWwgJSBUUERFQ19TWU5DU0tJUCkgPT0gMCk7CgogICAgICBpZiAoKGJpdHNBdmFpbC1zeW5jTGVuZ3RoKSA8IFRQREVDX1NZTkNTS0lQKSB7CiAgICAgICAgZXJyID0gVFJBTlNQT1JUREVDX05PVF9FTk9VR0hfQklUUzsKICAgICAgICBoZWFkZXJCaXRzID0gMDsKICAgICAgfSBlbHNlIHsKCiAgICAgICAgc3luY2ggPSBGREtyZWFkQml0cyhoQnMsIHN5bmNMZW5ndGgpOwoKICAgICAgICBpZiAoICEoaFRwLT5mbGFncyAmIFRQREVDX1NZTkNPSykgKSB7CiAgICAgICAgICBmb3IgKDsgKGJpdHNBdmFpbC1zeW5jTGVuZ3RoKSA+PSBUUERFQ19TWU5DU0tJUDsgYml0c0F2YWlsLT1UUERFQ19TWU5DU0tJUCkgewogICAgICAgICAgICBpZiAoc3luY2ggPT0gc3luY1dvcmQpIHsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBzeW5jaCA9ICgoc3luY2ggPDwgVFBERUNfU1lOQ1NLSVApICYgc3luY01hc2spIHwgRkRLcmVhZEJpdHMoaEJzLCBUUERFQ19TWU5DU0tJUCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChzeW5jaCAhPSBzeW5jV29yZCkgewogICAgICAgICAgLyogTm8gY29ycmVjdCBzeW5jd29yZCBmb3VuZC4gKi8KICAgICAgICAgIGVyciA9IFRSQU5TUE9SVERFQ19TWU5DX0VSUk9SOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBlcnIgPSBUUkFOU1BPUlRERUNfT0s7CiAgICAgICAgfQogICAgICAgIGhlYWRlckJpdHMgPSBzeW5jTGVuZ3RoOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBoZWFkZXJCaXRzID0gMDsKICAgIH0KCiAgICAvKiBTYXZlIHByZXZpb3VzIHJhdyBkYXRhIGJsb2NrIGRhdGEgKi8KICAgIHJhd0RhdGFCbG9ja0xlbmd0aFByZXZpb3VzID0gcmF3RGF0YUJsb2NrTGVuZ3RoOwogICAgbnVtUmF3RGF0YUJsb2Nrc1ByZXZpb3VzID0gaFRwLT5udW1iZXJPZlJhd0RhdGFCbG9ja3M7CgogICAgLyogUGFyc2UgdHJhbnNwb3J0IGhlYWRlciAocmF3IGRhdGEgYmxvY2sgZ3JhbnVsYXJpdHkpICovCgogICAgaWYgKGVyciA9PSBUUkFOU1BPUlRERUNfT0sgKQogICAgewogICAgICBlcnIgPSB0cmFuc3BvcnREZWNfcmVhZEhlYWRlcigKICAgICAgICAgICAgICBoVHAsCiAgICAgICAgICAgICAgaEJzLAogICAgICAgICAgICAgIHN5bmNMZW5ndGgsCiAgICAgICAgICAgICAgaWdub3JlQnVmZmVyRnVsbG5lc3MsCiAgICAgICAgICAgICAmcmF3RGF0YUJsb2NrTGVuZ3RoLAogICAgICAgICAgICAgJmZUcmF2ZXJzZU1vcmVGcmFtZXMsCiAgICAgICAgICAgICAmc3luY0xheWVyRnJhbWVCaXRzLAogICAgICAgICAgICAgJmZDb25maWdGb3VuZCwKICAgICAgICAgICAgICZoZWFkZXJCaXRzCiAgICAgICAgICAgICAgKTsKICAgIH0KCiAgICBiaXRzQXZhaWwgLT0gaGVhZGVyQml0czsKCiAgICBjaGVja0xlbmd0aEJpdHMgID0gc3luY0xheWVyRnJhbWVCaXRzOwoKICAgIC8qIENoZWNrIGlmIHRoZSB3aG9sZSBmcmFtZSB3b3VsZCBmaXQgdGhlIGJpdHN0cmVhbSBidWZmZXIgKi8KICAgIGlmIChlcnIgPT0gVFJBTlNQT1JUREVDX09LKSB7CiAgICAgIGlmICggKGNoZWNrTGVuZ3RoQml0cytoZWFkZXJCaXRzKSA+ICgoVFJBTlNQT1JUREVDX0lOQlVGX1NJWkU8PDMpLTcpICkgewogICAgICAgIC8qIFdlIGFzc3VtZSB0aGF0IHRoZSBzaXplIG9mIHRoZSB0cmFuc3BvcnQgYml0IGJ1ZmZlciBoYXMgYmVlbgogICAgICAgICAgIGNob3NlbiB0byBtZWV0IGFsbCBzeXN0ZW0gcmVxdWlyZW1lbnRzLCB0aHVzIHRoaXMgY29uZGl0aW9uCiAgICAgICAgICAgaXMgY29uc2lkZXJlZCBhIHN5bmNocm9uaXNhdGlvbiBlcnJvci4gKi8KICAgICAgICBlcnIgPSBUUkFOU1BPUlRERUNfU1lOQ19FUlJPUjsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAoIGJpdHNBdmFpbCA8IGNoZWNrTGVuZ3RoQml0cyApIHsKICAgICAgICAgIGVyciA9IFRSQU5TUE9SVERFQ19OT1RfRU5PVUdIX0JJVFM7CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgaWYgKGVyciA9PSBUUkFOU1BPUlRERUNfTk9UX0VOT1VHSF9CSVRTKSB7CiAgICAgIGJyZWFrOwogICAgfQoKCiAgICBpZiAoZXJyID09IFRSQU5TUE9SVERFQ19TWU5DX0VSUk9SKSB7CiAgICAgIGludCBiaXRzOwoKICAgICAgLyogRW5mb3JjZSByZS1zeW5jIG9mIHRyYW5zcG9ydCBoZWFkZXJzLiAqLwogICAgICBoVHAtPm51bWJlck9mUmF3RGF0YUJsb2NrcyA9IDA7CgogICAgICAvKiBFbnN1cmUgdGhhdCB0aGUgYml0IGFtb3VudCBsYW5kcyBhdCBhIG11bHRpcGxlIG9mIFRQREVDX1NZTkNTS0lQICovCiAgICAgIGJpdHMgPSAoYml0c0F2YWlsICsgaGVhZGVyQml0cykgJSBUUERFQ19TWU5DU0tJUDsKICAgICAgLyogUmV3aW5kIC0gVFBERUNfU1lOQ1NLSVAsIGluIG9yZGVyIHRvIGxvb2sgZm9yIGEgc3luY2ggb25lIGJpdCBhaGVhZCBuZXh0IHRpbWUuICovCiAgICAgIEZES3B1c2hCaURpcmVjdGlvbmFsKGhCcywgLShoZWFkZXJCaXRzIC0gVFBERUNfU1lOQ1NLSVApICsgYml0cyk7CiAgICAgIGJpdHNBdmFpbCArPSBoZWFkZXJCaXRzIC0gVFBERUNfU1lOQ1NLSVAgLSBiaXRzOwogICAgICBoZWFkZXJCaXRzID0gMDsKICAgIH0KCiAgICAvKiBGcmFtZSB0cmF2ZXJzYWwgKi8KICAgIGlmICggZlRyYXZlcnNlTW9yZUZyYW1lcyApCiAgICB7CiAgICAgIC8qIFNhdmUgcGFyc2VyIGNvbnRleHQgZm9yIGVhcmx5IGNvbmZpZyBkaXNjb3ZlcnkgInJld2luZCBhbGwgZnJhbWVzIiAqLwogICAgICBpZiAoIChoVHAtPmZsYWdzICYgVFBERUNfRUFSTFlfQ09ORklHKSAmJiAhKGhUcC0+ZmxhZ3MgJiBUUERFQ19NSU5JTUlaRV9ERUxBWSkpCiAgICAgIHsKICAgICAgICAvKiBpZ25vcmUgYnVmZmVyIGZ1bGxuZXNzIGlmIGp1c3QgdHJhdmVyc2luZyBhZGRpdGlvbmFsIGZyYW1lcyBmb3IgRUNEICovCiAgICAgICAgaWdub3JlQnVmZmVyRnVsbG5lc3MgPSAxOwoKICAgICAgICAvKiBTYXZlIGNvbnRleHQgaW4gb3JkZXIgdG8gcmV0dXJuIGxhdGVyICovCiAgICAgICAgaWYgKCBlcnIgPT0gVFJBTlNQT1JUREVDX09LICYmIHN0YXJ0UG9zRmlyc3RGcmFtZSA9PSAtMSApIHsKICAgICAgICAgIHN0YXJ0UG9zRmlyc3RGcmFtZSA9IEZES2dldFZhbGlkQml0cyhoQnMpOwogICAgICAgICAgbnVtUmF3RGF0YUJsb2Nrc0ZpcnN0RnJhbWUgPSBoVHAtPm51bWJlck9mUmF3RGF0YUJsb2NrczsKICAgICAgICAgIGdsb2JhbEZyYW1lUG9zRmlyc3RGcmFtZSA9IGhUcC0+Z2xvYmFsRnJhbWVQb3M7CiAgICAgICAgICByYXdEYXRhQmxvY2tMZW5ndGhGaXJzdEZyYW1lID0gcmF3RGF0YUJsb2NrTGVuZ3RoOwogICAgICAgICAgaGVhZGVyQml0c0ZpcnN0RnJhbWUgPSBoZWFkZXJCaXRzOwogICAgICAgICAgZXJyRmlyc3RGcmFtZSA9IGVycjsKICAgICAgICAgIEZES21lbWNweShjb250ZXh0Rmlyc3RGcmFtZSwgJmhUcC0+cGFyc2VyLCBzaXplb2YodHJhbnNwb3J0ZGVjX3BhcnNlcl90KSk7CiAgICAgICAgfQoKICAgICAgICAvKiBCcmVhayB3aGVuIGNvbmZpZyB3YXMgZm91bmQgb3IgaXQgaXMgbm90IHBvc3NpYmxlIGFueW1vcmUgdG8gZmluZCBhIGNvbmZpZyAqLwogICAgICAgIGlmIChzdGFydFBvc0ZpcnN0RnJhbWUgIT0gLTEgJiYgKGZDb25maWdGb3VuZCB8fCBlcnIgIT0gVFJBTlNQT1JUREVDX09LKSkKICAgICAgICB7CiAgICAgICAgICAvKiBJbiBjYXNlIG9mIEVDRCBhbmQgc3luYyBlcnJvciwgZG8gbm90IHJld2luZCBhbnl3aGVyZS4gKi8KICAgICAgICAgIGlmIChlcnIgPT0gVFJBTlNQT1JUREVDX1NZTkNfRVJST1IpCiAgICAgICAgICB7CiAgICAgICAgICAgIHN0YXJ0UG9zRmlyc3RGcmFtZSA9IC0xOwogICAgICAgICAgICBmQ29uZmlnRm91bmQgPSAwOwogICAgICAgICAgICBudW1GcmFtZXNUcmF2ZXJzZWQgPSAwOwogICAgICAgICAgfQogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICB9CgogICAgICBpZiAoZXJyID09IFRSQU5TUE9SVERFQ19PSykgewogICAgICAgIEZES3B1c2hGb3IoaEJzLCByYXdEYXRhQmxvY2tMZW5ndGgpOwogICAgICAgIGJpdHNBdmFpbCAtPSByYXdEYXRhQmxvY2tMZW5ndGg7CiAgICAgICAgbnVtRnJhbWVzVHJhdmVyc2VkKys7CiAgICAgICAgLyogSWdub3JlIGVycm9yIGhlcmUgaXRlbnRpb25hbGx5LiAqLwogICAgICAgIHRyYW5zcG9ydERlY19BZGp1c3RFbmRPZkFjY2Vzc1VuaXQoaFRwKTsKICAgICAgfQogICAgfQogIH0gd2hpbGUgKCBmVHJhdmVyc2VNb3JlRnJhbWVzIHx8IChlcnIgPT0gVFJBTlNQT1JUREVDX1NZTkNfRVJST1IgJiYgIShoVHAtPmZsYWdzICYgVFBERUNfU1lOQ09LKSkpOwoKICAvKiBSZXN0b3JlIGNvbnRleHQgaW4gY2FzZSBvZiBFQ0QgZnJhbWUgdHJhdmVyc2FsICovCiAgaWYgKCBzdGFydFBvc0ZpcnN0RnJhbWUgIT0gLTEgJiYgKGZDb25maWdGb3VuZCB8fCBlcnIgIT0gVFJBTlNQT1JUREVDX09LKSApIHsKICAgIEZES3B1c2hCaURpcmVjdGlvbmFsKGhCcywgRkRLZ2V0VmFsaWRCaXRzKGhCcykgLSBzdGFydFBvc0ZpcnN0RnJhbWUpOwogICAgRkRLbWVtY3B5KCZoVHAtPnBhcnNlciwgY29udGV4dEZpcnN0RnJhbWUsIHNpemVvZih0cmFuc3BvcnRkZWNfcGFyc2VyX3QpKTsKICAgIGhUcC0+bnVtYmVyT2ZSYXdEYXRhQmxvY2tzID0gbnVtUmF3RGF0YUJsb2Nrc0ZpcnN0RnJhbWU7CiAgICBoVHAtPmdsb2JhbEZyYW1lUG9zID0gZ2xvYmFsRnJhbWVQb3NGaXJzdEZyYW1lOwogICAgcmF3RGF0YUJsb2NrTGVuZ3RoID0gcmF3RGF0YUJsb2NrTGVuZ3RoRmlyc3RGcmFtZTsKICAgIGhlYWRlckJpdHMgPSBoZWFkZXJCaXRzRmlyc3RGcmFtZTsKICAgIGVyciA9IGVyckZpcnN0RnJhbWU7CiAgICBudW1GcmFtZXNUcmF2ZXJzZWQgPSAwOwogIH0gCgogIC8qIEFkZGl0aW9uYWwgYnVyc3QgZGF0YSBtb2RlIGJ1ZmZlciBmdWxsbmVzcyBjaGVjay4gKi8KICBpZiAoICEoaFRwLT5mbGFncyAmIChUUERFQ19MT1NUX0ZSQU1FU19QRU5ESU5HfFRQREVDX0lHTk9SRV9CVUZGRVJGVUxMTkVTU3xUUERFQ19TWU5DT0spKSAmJiBlcnIgPT0gVFJBTlNQT1JUREVDX09LKSB7CiAgICBlcnIgPSBhZGRpdGlvbmFsSG9sZE9mZk5lZWRlZChoVHAsIHRyYW5zcG9ydERlY19HZXRCdWZmZXJGdWxsbmVzcyhoVHApLCBGREtnZXRWYWxpZEJpdHMoaEJzKSAtIHN5bmNMYXllckZyYW1lQml0cyk7CiAgICBpZiAoZXJyID09IFRSQU5TUE9SVERFQ19OT1RfRU5PVUdIX0JJVFMpIHsKICAgICAgaFRwLT5ob2xkT2ZmRnJhbWVzKys7CiAgICB9CiAgfQogIAogIC8qIFJld2luZCBmb3IgcmV0cnkgYmVjYXVzZSBvZiBub3QgZW5vdWdoIGJpdHMgKi8KICBpZiAoZXJyID09IFRSQU5TUE9SVERFQ19OT1RfRU5PVUdIX0JJVFMpIHsKICAgIEZES3B1c2hCYWNrKGhCcywgaGVhZGVyQml0cyk7CiAgICBoZWFkZXJCaXRzID0gMDsKICB9CiAgZWxzZSB7CiAgICAvKiByZXNldCBob2xkIG9mZiBmcmFtZSBjb3VudGVyICovCiAgICBoVHAtPmhvbGRPZmZGcmFtZXMgPSAwOwogIH0KCiAgLyogUmV0dXJuIHRvIGxhc3QgZ29vZCBmcmFtZSBpbiBjYXNlIG9mIGZyYW1lIHRyYXZlcnNhbCBidXQgbm90IEVDRC4gKi8KICBpZiAobnVtRnJhbWVzVHJhdmVyc2VkID4gMCkgewogICAgRkRLcHVzaEJhY2soaEJzLCByYXdEYXRhQmxvY2tMZW5ndGhQcmV2aW91cyk7CiAgICBpZiAoZXJyICE9IFRSQU5TUE9SVERFQ19PSykgewogICAgICBoVHAtPm51bWJlck9mUmF3RGF0YUJsb2NrcyA9IG51bVJhd0RhdGFCbG9ja3NQcmV2aW91czsKICAgICAgaGVhZGVyQml0cyA9IGhlYWRlckJpdHNQcmV2aW91czsKICAgIH0KICAgIGVyciA9IFRSQU5TUE9SVERFQ19PSzsKICB9CgpiYWlsOgogIGhUcC0+YXVMZW5ndGhbMF0gPSByYXdEYXRhQmxvY2tMZW5ndGg7CgogIC8qIERldGVjdCBwb2ludGxlc3MgVFJBTlNQT1JUREVDX05PVF9FTk9VR0hfQklUUyBlcnJvciBjYXNlLCB3ZXJlIHRoZSBiaXQgYnVmZmVyIGlzIGFscmVhZHkgZnVsbCwKICAgICBvciBubyBuZXcgYnVyc3QgcGFja2V0IGZpdHMuIFJlY292ZXIgYnkgYWR2YW5jaW5nIHRoZSBiaXQgYnVmZmVyLiAqLwogIGlmICggKFRSQU5TUE9SVERFQ19OT1RfRU5PVUdIX0JJVFMgPT0gZXJyKSAmJiAgKEZES2dldFZhbGlkQml0cyhoQnMpID49ICgoVFJBTlNQT1JUREVDX0lOQlVGX1NJWkUqOCAtICgoaFRwLT5hdmdCaXRSYXRlKmhUcC0+YnVyc3RQZXJpb2QpLzEwMDApKSAtIDcpKSApCiAgewogICAgRkRLcHVzaEZvcihoQnMsIFRQREVDX1NZTkNTS0lQKTsKICAgIGVyciA9IFRSQU5TUE9SVERFQ19TWU5DX0VSUk9SOwogIH0KCiAgaWYgKGVyciA9PSBUUkFOU1BPUlRERUNfT0spIHsKICAgIGhUcC0+ZmxhZ3MgfD0gVFBERUNfU1lOQ09LOwogIH0KCiAgaWYgKGZDb25maWdGb3VuZCkgewogICAgaFRwLT5mbGFncyB8PSBUUERFQ19DT05GSUdfRk9VTkQ7CiAgfQoKICBpZiAocEhlYWRlckJpdHMgIT0gTlVMTCkgewogICAgKnBIZWFkZXJCaXRzID0gaGVhZGVyQml0czsKICB9CgogIGlmIChlcnIgPT0gVFJBTlNQT1JUREVDX1NZTkNfRVJST1IpIHsKICAgIGhUcC0+ZmxhZ3MgJj0gflRQREVDX1NZTkNPSzsKICB9CgogIENfQUxMT0NfU0NSQVRDSF9FTkQoY29udGV4dEZpcnN0RnJhbWUsIHRyYW5zcG9ydGRlY19wYXJzZXJfdCwgMSk7CgogIHJldHVybiBlcnI7Cn0KCi8qKgogKiBcYnJpZWYgU3luY2hyb25pemUgdG8gc3RyZWFtIGFuZCBlc3RpbWF0ZSB0aGUgYW1vdW50IG9mIG1pc3NpbmcgYWNjZXNzIHVuaXRzIGR1ZQogKiAgICAgICAgdG8gYSBjdXJyZW50IHN5bmNocm9uaXphdGlvbiBlcnJvciBpbiBjYXNlIG9mIGNvbnN0YW50IGF2ZXJhZ2UgYml0IHJhdGUuCiAqLwpzdGF0aWMKVFJBTlNQT1JUREVDX0VSUk9SIHRyYW5zcG9ydERlY19yZWFkU3RyZWFtICggSEFORExFX1RSQU5TUE9SVERFQyBoVHAsIGNvbnN0IFVJTlQgbGF5ZXIgKQp7CgogIFRSQU5TUE9SVERFQ19FUlJPUiBlcnJvciA9IFRSQU5TUE9SVERFQ19PSzsKICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQnMgPSAmaFRwLT5iaXRTdHJlYW1bbGF5ZXJdOwogIElOVCBuQVUgPSAtMTsKICBJTlQgaGVhZGVyQml0czsKICBJTlQgYml0RGlzdGFuY2UsIGJmRGVsdGE7CgogIC8qIE9idGFpbiBkaXN0YW5jZSB0byBuZXh0IHN5bmNoIHdvcmQgKi8KICBiaXREaXN0YW5jZSA9IEZES2dldFZhbGlkQml0cyhoQnMpOwogIGVycm9yID0gc3luY2hyb25pemF0aW9uKGhUcCwgJmhlYWRlckJpdHMpOwogIGJpdERpc3RhbmNlIC09IEZES2dldFZhbGlkQml0cyhoQnMpOwoKCiAgRkRLX0FTU0VSVChiaXREaXN0YW5jZSA+PSAwKTsKCiAgaWYgKGVycm9yID09IFRSQU5TUE9SVERFQ19TWU5DX0VSUk9SIHx8IChoVHAtPmZsYWdzICYgVFBERUNfTE9TVF9GUkFNRVNfUEVORElORykpCiAgewogICAgLyogQ2hlY2sgaWYgZXN0aW1hdGluZyBsb3N0IGFjY2VzcyB1bml0cyBpcyBmZWFzaWJsZS4gKi8KICAgIGlmIChoVHAtPmF2Z0JpdFJhdGUgPiAwICYmIGhUcC0+YXNjWzBdLm1fc2FtcGxlc1BlckZyYW1lID4gMCAmJiBoVHAtPmFzY1swXS5tX3NhbXBsaW5nRnJlcXVlbmN5ID4gMCkKICAgIHsKICAgICAgaWYgKGVycm9yID09IFRSQU5TUE9SVERFQ19PSykKICAgICAgewogICAgICAgIGludCBhajsKCiAgICAgICAgYWogPSB0cmFuc3BvcnREZWNfR2V0QnVmZmVyRnVsbG5lc3MoaFRwKTsKICAgICAgICBpZiAoYWogPiAwKSB7CiAgICAgICAgICBiZkRlbHRhID0gYWo7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGJmRGVsdGEgPSAwOwogICAgICAgIH0KICAgICAgICAvKiBzeW5jIHdhcyBvazogbGFzdCBvZiBhIHNlcmllcyBvZiBiYWQgYWNjZXNzIHVuaXRzLiAqLwogICAgICAgIGhUcC0+ZmxhZ3MgJj0gflRQREVDX0xPU1RfRlJBTUVTX1BFTkRJTkc7CiAgICAgICAgLyogQWRkIHVwIGJpdERpc3RhbmNlIHVudGlsIGVuZCBvZiB0aGUgY3VycmVudCBmcmFtZS4gTGF0ZXIgd2Ugc3Vic3RyYWN0CiAgICAgICAgICAgdGhpcyBmcmFtZSBmcm9tIHRoZSBncmFuZCB0b3RhbCwgc2luY2UgdGhpcyBjdXJyZW50IHN1Y2Nlc3NmdWxseSBzeW5jaHJvbml6ZWQKICAgICAgICAgICBmcmFtZSBzaG91bGQgbm90IGJlIHNraXBwZWQgb2YgY291cnNlOyBidXQgaXQgbXVzdCBiZSBhY2NvdW50ZWQgaW50byB0aGUKICAgICAgICAgICBidWZmZXJmdWxuZXNzIG1hdGguICovCiAgICAgICAgYml0RGlzdGFuY2UgKz0gaFRwLT5hdUxlbmd0aFswXTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAoICEoaFRwLT5mbGFncyAmIFRQREVDX0xPU1RfRlJBTUVTX1BFTkRJTkcpICkgewogICAgICAgICAgLyogc3luYyBub3Qgb2s6IG9uZSBvZiBtYW55IGJhZCBhY2Nlc3MgdW5pdHMuICovCiAgICAgICAgICBoVHAtPmZsYWdzIHw9IFRQREVDX0xPU1RfRlJBTUVTX1BFTkRJTkc7CiAgICAgICAgICBiZkRlbHRhID0gLSAoSU5UKWhUcC0+bGFzdFZhbGlkQnVmZmVyRnVsbG5lc3M7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGJmRGVsdGEgPSAwOwogICAgICAgIH0KICAgICAgfQoKICAgICAgewogICAgICAgIGludCBudW0sIGRlbm9tOwoKICAgICAgICAvKiBPYnRhaW4gZXN0aW1hdGUgb2YgbnVtYmVyIG9mIGxvc3QgZnJhbWVzICovCiAgICAgICAgbnVtID0gaFRwLT5hc2NbMF0ubV9zYW1wbGluZ0ZyZXF1ZW5jeSAqIChiZkRlbHRhICsgYml0RGlzdGFuY2UpICsgaFRwLT5yZW1haW5kZXI7CiAgICAgICAgZGVub20gPSBoVHAtPmF2Z0JpdFJhdGUgKiBoVHAtPmFzY1swXS5tX3NhbXBsZXNQZXJGcmFtZTsKICAgICAgICBpZiAobnVtID4gMCkgewogICAgICAgICAgbkFVID0gbnVtIC8gZGVub207CiAgICAgICAgICBoVHAtPnJlbWFpbmRlciA9IG51bSAlIGRlbm9tOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBoVHAtPnJlbWFpbmRlciA9IG51bTsKICAgICAgICB9CgogICAgICAgIGlmIChlcnJvciA9PSBUUkFOU1BPUlRERUNfT0spCiAgICAgICAgewogICAgICAgICAgLyogRmluYWwgYWRqdXN0bWVudCBvZiByZW1haW5kZXIsIHRha2VuIC0xIGludG8gYWNjb3VudCBiZWNhdXNlIGN1cnJlbnQKICAgICAgICAgICAgIGZyYW1lIHNob3VsZCBub3QgYmUgc2tpcHBlZCwgdGh1cyBzdWJzdHJhY3QgLTEgb3IgZG8gbm90aGluZyBpbnN0ZWFkCiAgICAgICAgICAgICBvZiArMS0xIGFjY29yZGluZ2x5LiAqLwogICAgICAgICAgaWYgKCAoZGVub20gLSBoVHAtPnJlbWFpbmRlcikgPj0gaFRwLT5yZW1haW5kZXIgKSB7CiAgICAgICAgICAgIG5BVS0tOwogICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgIGlmIChuQVUgPCAwKSB7CiAgICAgICAgICAgIC8qIFRoZXJlIHdhcyBvbmUgZnJhbWUgdG9vIG11Y2ggY29uY2VhbGVkLCBzbyB1bmZvcnR1bmF0ZWx5IHdlIHdpbGwgaGF2ZSB0byBza2lwIG9uZSBnb29kIGZyYW1lLiAqLwogICAgICAgICAgICB0cmFuc3BvcnREZWNfRW5kQWNjZXNzVW5pdChoVHApOwogICAgICAgICAgICBlcnJvciA9IHN5bmNocm9uaXphdGlvbihoVHAsICZoZWFkZXJCaXRzKTsgICAgICAgICAgICAgCiAgICAgICAgICAgIG5BVSA9IC0xOwojaWZkZWYgREVCVUcKICAgICAgICAgICAgRkRLcHJpbnRmKCJFUlJPUjogQnVmZmVyZnVsbG5lc3MgYWNjb3VudGluZyBmYWlsZWQuIHJlbWFpbmRlcj0lZCwgbkFVPSVkXG4iLCBoVHAtPnJlbWFpbmRlciwgbkFVKTsKI2VuZGlmCiAgICAgICAgICB9CiAgICAgICAgICBoVHAtPnJlbWFpbmRlciA9IDA7CiAgICAgICAgICAvKiBFbmZvcmNlIGxhc3QgbWlzc2VkIGZyYW1lcyB0byBiZSBjb25jZWFsZWQuICovCiAgICAgICAgICBpZiAobkFVID4gMCkgewogICAgICAgICAgICBGREtwdXNoQmFjayhoQnMsIGhlYWRlckJpdHMpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KCiAgLyogQmUgc3VyZSB0aGF0IGxvc3QgZnJhbWVzIGFyZSBoYW5kbGVkIGNvcnJlY3RseS4gVGhpcyBpcyBuZWNlc3NhcnkgZHVlIHRvIHNvbWUKICAgICBzeW5jIGVycm9yIHNlcXVlbmNlcyB3aGVyZSBsYXRlciBpdCB0dXJucyBvdXQgdGhhdCB0aGVyZSBpcyBub3QgZW5vdWdoIGRhdGEsIGJ1dAogICAgIHRoZSBiaXRzIHVwdG8gdGhlIHN5bmMgd29yZCBhcmUgZGlzY2FyZGVkLCB0aHVzIGNhdXNpbmcgYSB2YWx1ZSBvZiBuQVUgPiAwICovCiAgaWYgKG5BVSA+IDApIHsKICAgIGVycm9yID0gVFJBTlNQT1JUREVDX1NZTkNfRVJST1I7CiAgfQoKICBoVHAtPm1pc3NpbmdBY2Nlc3NVbml0cyA9IG5BVTsKCiAgcmV0dXJuIGVycm9yOwp9CgovKiByZXR1cm5zIGVycm9yIGNvZGUgKi8KVFJBTlNQT1JUREVDX0VSUk9SIHRyYW5zcG9ydERlY19SZWFkQWNjZXNzVW5pdCggY29uc3QgSEFORExFX1RSQU5TUE9SVERFQyBoVHAsIGNvbnN0IFVJTlQgbGF5ZXIgKQp7CiAgVFJBTlNQT1JUREVDX0VSUk9SIGVyciA9IFRSQU5TUE9SVERFQ19PSzsKICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQnM7CgogIGlmICghaFRwKSB7CiAgICByZXR1cm4gVFJBTlNQT1JUREVDX0lOVkFMSURfUEFSQU1FVEVSOwogIH0KCiAgaEJzID0gJmhUcC0+Yml0U3RyZWFtW2xheWVyXTsKCiAgaWYgKChJTlQpRkRLZ2V0VmFsaWRCaXRzKGhCcykgPD0gMCkgewogICAgZXJyID0gVFJBTlNQT1JUREVDX05PVF9FTk9VR0hfQklUUzsKICB9CgogIHN3aXRjaCAoaFRwLT50cmFuc3BvcnRGbXQpIHsKCiAgICBjYXNlIFRUX01QNF9BRElGOgogICAgICAvKiBSZWFkIGhlYWRlciBpZiBub3QgYWxyZWFkeSBkb25lICovCiAgICAgIGlmICghKGhUcC0+ZmxhZ3MgJiBUUERFQ19DT05GSUdfRk9VTkQpKQogICAgICB7CiAgICAgICAgQ1Byb2dyYW1Db25maWcgKnBjZTsKCiAgICAgICAgQXVkaW9TcGVjaWZpY0NvbmZpZ19Jbml0KCZoVHAtPmFzY1swXSk7CiAgICAgICAgcGNlID0gJmhUcC0+YXNjWzBdLm1fcHJvZ3JDb25maWdFbGVtZW50OwogICAgICAgIGVyciA9IGFkaWZSZWFkX0RlY29kZUhlYWRlcigmaFRwLT5wYXJzZXIuYWRpZiwgcGNlLCBoQnMpOwogICAgICAgIGlmIChlcnIpCiAgICAgICAgICBnb3RvIGJhaWw7CgogICAgICAgIC8qIE1hcCBhZGlmIGhlYWRlciB0byBBU0MgKi8KICAgICAgICBoVHAtPmFzY1swXS5tX2FvdCAgICAgICAgICAgICAgICAgICAgPSAoQVVESU9fT0JKRUNUX1RZUEUpKHBjZS0+UHJvZmlsZSArIDEpOwogICAgICAgIGhUcC0+YXNjWzBdLm1fc2FtcGxpbmdGcmVxdWVuY3lJbmRleCA9IHBjZS0+U2FtcGxpbmdGcmVxdWVuY3lJbmRleDsKICAgICAgICBoVHAtPmFzY1swXS5tX3NhbXBsaW5nRnJlcXVlbmN5ICAgICAgPSBTYW1wbGluZ1JhdGVUYWJsZVtwY2UtPlNhbXBsaW5nRnJlcXVlbmN5SW5kZXhdOwogICAgICAgIGhUcC0+YXNjWzBdLm1fY2hhbm5lbENvbmZpZ3VyYXRpb24gICA9IDA7CiAgICAgICAgaFRwLT5hc2NbMF0ubV9zYW1wbGVzUGVyRnJhbWUgICAgICAgID0gMTAyNDsKICAgICAgICBoVHAtPmF2Z0JpdFJhdGUgICAgICAgICAgICAgICAgICAgICAgPSBoVHAtPnBhcnNlci5hZGlmLkJpdFJhdGU7CgogICAgICAgIC8qIENhbGwgY2FsbGJhY2sgdG8gZGVjb2Rlci4gKi8KICAgICAgICB7CiAgICAgICAgICBpbnQgZXJyQzsKCiAgICAgICAgICBlcnJDID0gaFRwLT5jYWxsYmFja3MuY2JVcGRhdGVDb25maWcoaFRwLT5jYWxsYmFja3MuY2JVcGRhdGVDb25maWdEYXRhLCAmaFRwLT5hc2NbMF0pOwogICAgICAgICAgaWYgKGVyckMgPT0gMCkgewogICAgICAgICAgICBoVHAtPmZsYWdzIHw9IFRQREVDX0NPTkZJR19GT1VORDsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGVyciA9IFRSQU5TUE9SVERFQ19QQVJTRV9FUlJPUjsKICAgICAgICAgICAgZ290byBiYWlsOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgICBoVHAtPmF1TGVuZ3RoW2xheWVyXSA9IC0xOyAvKiBBY2Nlc3MgVW5pdCBkYXRhIGxlbmd0aCBpcyB1bmtub3duLiAqLwogICAgICBicmVhazsKCiAgICBjYXNlIFRUX01QNF9SQVc6CiAgICAgIC8qIE9uZSBBY2Nlc3MgVW5pdCB3YXMgZmlsbGVkIGludG8gYnVmZmVyLgogICAgICAgICBTbyBnZXQgdGhlIGxlbmd0aCBvdXQgb2YgdGhlIGJ1ZmZlci4gKi8KICAgICAgaFRwLT5hdUxlbmd0aFtsYXllcl0gPSBGREtnZXRWYWxpZEJpdHMoaEJzKTsKICAgICAgaFRwLT5mbGFncyB8PSBUUERFQ19TWU5DT0s7CiAgICAgIGJyZWFrOwoKICAgIGNhc2UgVFRfTVA0X0xBVE1fTUNQMDoKICAgIGNhc2UgVFRfTVA0X0xBVE1fTUNQMToKICAgICAgewogICAgICAgIGludCBmQ29uZmlnRm91bmQgPSBoVHAtPmZsYWdzICYgVFBERUNfQ09ORklHX0ZPVU5EOwogICAgICAgIGVyciA9IHRyYW5zcG9ydERlY19yZWFkSGVhZGVyKGhUcCwgaEJzLCAwLCAxLCAmaFRwLT5hdUxlbmd0aFtsYXllcl0sIE5VTEwsIE5VTEwsICZmQ29uZmlnRm91bmQsIE5VTEwpOwogICAgICAgIGlmIChmQ29uZmlnRm91bmQpIHsKICAgICAgICAgIGhUcC0+ZmxhZ3MgfD0gVFBERUNfQ09ORklHX0ZPVU5EOwogICAgICAgIH0KICAgICAgfQogICAgICBicmVhazsKCiAgICBjYXNlIFRUX1JTVkQ1MDoKICAgIGNhc2UgVFRfTVA0X0FEVFM6CiAgICBjYXNlIFRUX01QNF9MT0FTOgogICAgICBlcnIgPSB0cmFuc3BvcnREZWNfcmVhZFN0cmVhbShoVHAsIGxheWVyKTsKICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgZXJyID0gVFJBTlNQT1JUREVDX1VOU1VQUE9SVEVEX0ZPUk1BVDsKICAgICAgYnJlYWs7CiAgfQoKICBpZiAoZXJyID09IFRSQU5TUE9SVERFQ19PSykgewogICAgaFRwLT5hY2Nlc3NVbml0QW5jaG9yW2xheWVyXSA9IEZES2dldFZhbGlkQml0cyhoQnMpOwogIH0gZWxzZSB7CiAgICBoVHAtPmFjY2Vzc1VuaXRBbmNob3JbbGF5ZXJdID0gMDsKICB9CgpiYWlsOgogIHJldHVybiBlcnI7Cn0KCklOVCB0cmFuc3BvcnREZWNfR2V0QXVCaXRzUmVtYWluaW5nKCBjb25zdCBIQU5ETEVfVFJBTlNQT1JUREVDIGhUcCwgY29uc3QgVUlOVCBsYXllciApCnsKICBJTlQgYml0czsKCiAgaWYgKGhUcC0+YWNjZXNzVW5pdEFuY2hvcltsYXllcl0gPiAwICYmIGhUcC0+YXVMZW5ndGhbbGF5ZXJdID4gMCkgewogICAgYml0cyA9IGhUcC0+YXVMZW5ndGhbbGF5ZXJdIC0gKGhUcC0+YWNjZXNzVW5pdEFuY2hvcltsYXllcl0gLSBGREtnZXRWYWxpZEJpdHMoJmhUcC0+Yml0U3RyZWFtW2xheWVyXSkpOwogIH0gZWxzZSB7CiAgICBiaXRzID0gRkRLZ2V0VmFsaWRCaXRzKCZoVHAtPmJpdFN0cmVhbVtsYXllcl0pOwogIH0KCiAgcmV0dXJuIGJpdHM7Cn0KCklOVCB0cmFuc3BvcnREZWNfR2V0QXVCaXRzVG90YWwoIGNvbnN0IEhBTkRMRV9UUkFOU1BPUlRERUMgaFRwLCBjb25zdCBVSU5UIGxheWVyICkKewogIHJldHVybiBoVHAtPmF1TGVuZ3RoW2xheWVyXTsKfQoKVFJBTlNQT1JUREVDX0VSUk9SIHRyYW5zcG9ydERlY19HZXRNaXNzaW5nQWNjZXNzVW5pdENvdW50ICggSU5UICpwTkFjY2Vzc1VuaXRzLCBIQU5ETEVfVFJBTlNQT1JUREVDIGhUcCApCnsKICAqcE5BY2Nlc3NVbml0cyA9IGhUcC0+bWlzc2luZ0FjY2Vzc1VuaXRzOwoKICByZXR1cm4gVFJBTlNQT1JUREVDX09LOwp9CgovKiBJbmZvcm0gdGhlIHRyYW5zcG9ydERlYyBsYXllciB0aGF0IHJlYWRpbmcgb2YgYWNjZXNzIHVuaXQgaGFzIGZpbmlzaGVkLiAqLwpUUkFOU1BPUlRERUNfRVJST1IgdHJhbnNwb3J0RGVjX0VuZEFjY2Vzc1VuaXQoSEFORExFX1RSQU5TUE9SVERFQyBoVHApCnsKICBUUkFOU1BPUlRERUNfRVJST1IgZXJyID0gVFJBTlNQT1JUREVDX09LOwoKCiAgZXJyID0gdHJhbnNwb3J0RGVjX0FkanVzdEVuZE9mQWNjZXNzVW5pdChoVHApOwoKICBzd2l0Y2ggKGhUcC0+dHJhbnNwb3J0Rm10KSB7CiAgICBkZWZhdWx0OgogICAgICBicmVhazsKICB9CgogIHJldHVybiBlcnI7Cn0KClRSQU5TUE9SVERFQ19FUlJPUiB0cmFuc3BvcnREZWNfU2V0UGFyYW0gKCBjb25zdCBIQU5ETEVfVFJBTlNQT1JUREVDIGhUcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFRQREVDX1BBUkFNICAgICAgICBwYXJhbSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgICB2YWx1ZSkKewogIFRSQU5TUE9SVERFQ19FUlJPUiBlcnJvciA9IFRSQU5TUE9SVERFQ19PSzsKCiAgc3dpdGNoIChwYXJhbSkgewogICAgY2FzZSBUUERFQ19QQVJBTV9NSU5JTUlaRV9ERUxBWToKICAgICAgaWYgKHZhbHVlKSB7CiAgICAgICAgaFRwLT5mbGFncyB8PSBUUERFQ19NSU5JTUlaRV9ERUxBWTsKICAgICAgfSBlbHNlIHsKICAgICAgICBoVHAtPmZsYWdzICY9IH5UUERFQ19NSU5JTUlaRV9ERUxBWTsKICAgICAgfQogICAgICBicmVhazsKICAgIGNhc2UgVFBERUNfUEFSQU1fRUFSTFlfQ09ORklHOgogICAgICBpZiAodmFsdWUpIHsKICAgICAgICBoVHAtPmZsYWdzIHw9IFRQREVDX0VBUkxZX0NPTkZJRzsKICAgICAgfSBlbHNlIHsKICAgICAgICBoVHAtPmZsYWdzICY9IH5UUERFQ19FQVJMWV9DT05GSUc7CiAgICAgIH0KICAgICAgYnJlYWs7CiAgICBjYXNlIFRQREVDX1BBUkFNX0lHTk9SRV9CVUZGRVJGVUxMTkVTUzoKICAgICAgaWYgKHZhbHVlKSB7CiAgICAgICAgaFRwLT5mbGFncyB8PSBUUERFQ19JR05PUkVfQlVGRkVSRlVMTE5FU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaFRwLT5mbGFncyAmPSB+VFBERUNfSUdOT1JFX0JVRkZFUkZVTExORVNTOwogICAgICB9CiAgICAgIGJyZWFrOwogICAgY2FzZSBUUERFQ19QQVJBTV9TRVRfQklUUkFURToKICAgICAgaFRwLT5hdmdCaXRSYXRlID0gdmFsdWU7CiAgICAgIGJyZWFrOwogICAgY2FzZSBUUERFQ19QQVJBTV9CVVJTVF9QRVJJT0Q6CiAgICAgIGhUcC0+YnVyc3RQZXJpb2QgPSB2YWx1ZTsKICAgICAgYnJlYWs7CiAgICBjYXNlIFRQREVDX1BBUkFNX1JFU0VUOgogICAgICB7CiAgICAgICAgaW50IGk7CgogICAgICAgIGZvciAoaT0wOyBpPCgxKjIpOyBpKyspIHsKICAgICAgICAgIEZES3Jlc2V0Qml0YnVmZmVyKCZoVHAtPmJpdFN0cmVhbVtpXSk7CiAgICAgICAgICBoVHAtPmF1TGVuZ3RoW2ldID0gMDsKICAgICAgICAgIGhUcC0+YWNjZXNzVW5pdEFuY2hvcltpXSA9IDA7CiAgICAgICAgfQogICAgICAgIGhUcC0+ZmxhZ3MgJj0gfihUUERFQ19TWU5DT0t8VFBERUNfTE9TVF9GUkFNRVNfUEVORElORyk7CiAgICAgICAgaWYgKGhUcC0+dHJhbnNwb3J0Rm10ICE9IFRUX01QNF9BRElGKSB7CiAgICAgICAgICBoVHAtPmZsYWdzICY9IH5UUERFQ19DT05GSUdfRk9VTkQ7CiAgICAgICAgfQogICAgICAgIGhUcC0+cmVtYWluZGVyID0gMDsKICAgICAgICBoVHAtPmF2Z0JpdFJhdGUgPSAwOwogICAgICAgIGhUcC0+bWlzc2luZ0FjY2Vzc1VuaXRzID0gMDsKICAgICAgICBoVHAtPm51bWJlck9mUmF3RGF0YUJsb2NrcyA9IDA7CiAgICAgICAgaFRwLT5nbG9iYWxGcmFtZVBvcyA9IDA7CiAgICAgICAgaFRwLT5ob2xkT2ZmRnJhbWVzID0gMDsKICAgICAgfQogICAgICBicmVhazsKICB9CgogIHJldHVybiBlcnJvcjsKfQoKVUlOVCB0cmFuc3BvcnREZWNfR2V0TnJPZlN1YkZyYW1lcyhIQU5ETEVfVFJBTlNQT1JUREVDIGhUcCkKewogIFVJTlQgblN1YkZyYW1lcyA9IDA7CgogIGlmIChoVHAgPT0gTlVMTCkKICAgIHJldHVybiAwOwoKICBpZiAoaFRwLT50cmFuc3BvcnRGbXQ9PVRUX01QNF9MQVRNX01DUDEgfHwgaFRwLT50cmFuc3BvcnRGbXQ9PVRUX01QNF9MQVRNX01DUDAgfHwgaFRwLT50cmFuc3BvcnRGbXQ9PVRUX01QNF9MT0FTKQogICAgblN1YkZyYW1lcyA9IENMYXRtRGVtdXhfR2V0TnJPZlN1YkZyYW1lcygmaFRwLT5wYXJzZXIubGF0bSk7CiAgZWxzZSBpZiAoaFRwLT50cmFuc3BvcnRGbXQ9PVRUX01QNF9BRFRTKQogICAgblN1YkZyYW1lcyA9IGhUcC0+cGFyc2VyLmFkdHMuYnMubnVtX3Jhd19ibG9ja3M7CgogIHJldHVybiBuU3ViRnJhbWVzOwp9Cgp2b2lkIHRyYW5zcG9ydERlY19DbG9zZShIQU5ETEVfVFJBTlNQT1JUREVDICpwaFRwKQp7CiAgaWYgKHBoVHAgIT0gTlVMTCkKICB7CiAgICBpZiAoKnBoVHAgIT0gTlVMTCkgewogICAgICBpZiAoICEgVFRfSVNfUEFDS0VUKCgqcGhUcCktPnRyYW5zcG9ydEZtdCkgKSB7CiAgICAgICAgRnJlZVJhbV9UcmFuc3BvcnREZWNvZGVyQnVmZmVyKCYoKnBoVHApLT5ic0J1ZmZlcik7CiAgICAgIH0KICAgICAgaWYgKCpwaFRwICE9IE5VTEwpIHsKICAgICAgICBGcmVlUmFtX1RyYW5zcG9ydERlY29kZXIocGhUcCk7CiAgICAgIH0KICAgIH0KICB9Cn0KClRSQU5TUE9SVERFQ19FUlJPUiB0cmFuc3BvcnREZWNfR2V0TGliSW5mbyggTElCX0lORk8gKmluZm8gKQp7CiAgaW50IGk7CgogIGlmIChpbmZvID09IE5VTEwpIHsKICAgIHJldHVybiBUUkFOU1BPUlRERUNfVU5LT1dOX0VSUk9SOwogIH0KCiAgLyogc2VhcmNoIGZvciBuZXh0IGZyZWUgdGFiICovCiAgZm9yIChpID0gMDsgaSA8IEZES19NT0RVTEVfTEFTVDsgaSsrKSB7CiAgICBpZiAoaW5mb1tpXS5tb2R1bGVfaWQgPT0gRkRLX05PTkUpIGJyZWFrOwogIH0KICBpZiAoaSA9PSBGREtfTU9EVUxFX0xBU1QpIHJldHVybiBUUkFOU1BPUlRERUNfVU5LT1dOX0VSUk9SOwogIGluZm8gKz0gaTsKCiAgaW5mby0+bW9kdWxlX2lkICA9IEZES19UUERFQzsKI2lmZGVmIF9fQU5EUk9JRF9fCiAgaW5mby0+YnVpbGRfZGF0ZSA9ICIiOwogIGluZm8tPmJ1aWxkX3RpbWUgPSAiIjsKI2Vsc2UKICBpbmZvLT5idWlsZF9kYXRlID0gX19EQVRFX187CiAgaW5mby0+YnVpbGRfdGltZSA9IF9fVElNRV9fOwojZW5kaWYKICBpbmZvLT50aXRsZSAgICAgID0gVFBfTElCX1RJVExFOwogIGluZm8tPnZlcnNpb24gICAgPSBMSUJfVkVSU0lPTihUUF9MSUJfVkwwLCBUUF9MSUJfVkwxLCBUUF9MSUJfVkwyKTsKICBMSUJfVkVSU0lPTl9TVFJJTkcoaW5mbyk7CiAgaW5mby0+ZmxhZ3MgPSAwCiAgICB8IENBUEZfQURJRgogICAgfCBDQVBGX0FEVFMKICAgIHwgQ0FQRl9MQVRNCiAgICB8IENBUEZfTE9BUwogICAgfCBDQVBGX1JBV1BBQ0tFVFMKICAgIDsKCiAgcmV0dXJuIFRSQU5TUE9SVERFQ19PSzsgLyogRkRLRVJSX05PRVJST1I7ICovCn0KCgppbnQgIHRyYW5zcG9ydERlY19DcmNTdGFydFJlZyhIQU5ETEVfVFJBTlNQT1JUREVDIHBUcCwgSU5UIG1CaXRzKQp7CiAgc3dpdGNoIChwVHAtPnRyYW5zcG9ydEZtdCkgewogIGNhc2UgVFRfTVA0X0FEVFM6CiAgICByZXR1cm4gYWR0c1JlYWRfQ3JjU3RhcnRSZWcoJnBUcC0+cGFyc2VyLmFkdHMsICZwVHAtPmJpdFN0cmVhbVswXSwgbUJpdHMpOwogIGRlZmF1bHQ6CiAgICByZXR1cm4gMDsKICB9Cn0KCnZvaWQgdHJhbnNwb3J0RGVjX0NyY0VuZFJlZyhIQU5ETEVfVFJBTlNQT1JUREVDIHBUcCwgSU5UIHJlZykKewogIHN3aXRjaCAocFRwLT50cmFuc3BvcnRGbXQpIHsKICBjYXNlIFRUX01QNF9BRFRTOgogICAgYWR0c1JlYWRfQ3JjRW5kUmVnKCZwVHAtPnBhcnNlci5hZHRzLCAmcFRwLT5iaXRTdHJlYW1bMF0sIHJlZyk7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgYnJlYWs7CiAgfQp9CgpUUkFOU1BPUlRERUNfRVJST1IgdHJhbnNwb3J0RGVjX0NyY0NoZWNrKEhBTkRMRV9UUkFOU1BPUlRERUMgcFRwKQp7CiAgc3dpdGNoIChwVHAtPnRyYW5zcG9ydEZtdCkgewogIGNhc2UgVFRfTVA0X0FEVFM6CiAgICBpZiAoIChwVHAtPnBhcnNlci5hZHRzLmJzLm51bV9yYXdfYmxvY2tzID4gMCkgJiYgKHBUcC0+cGFyc2VyLmFkdHMuYnMucHJvdGVjdGlvbl9hYnNlbnQgPT0gMCkgKQogICAgewogICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQnMgPSAmcFRwLT5iaXRTdHJlYW1bMF07CiAgICAgIAogICAgICB0cmFuc3BvcnREZWNfQWRqdXN0RW5kT2ZBY2Nlc3NVbml0KHBUcCk7CiAgICB9CiAgICByZXR1cm4gYWR0c1JlYWRfQ3JjQ2hlY2soJnBUcC0+cGFyc2VyLmFkdHMpOwogIGRlZmF1bHQ6CiAgICByZXR1cm4gVFJBTlNQT1JUREVDX09LOwogIH0KfQo=