Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiBNUEVHLTQgSEUtQUFDIEVuY29kZXIgKioqKioqKioqKioqKioqKioqKioqKioqKgoKICBJbml0aWFsIGF1dGhvcjogICAgICAgTS4gTG9od2Fzc2VyCiAgY29udGVudHMvZGVzY3JpcHRpb246IEZESyBIRS1BQUMgRW5jb2RlciBpbnRlcmZhY2UgbGlicmFyeSBmdW5jdGlvbnMKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaW5jbHVkZSAiYWFjZW5jX2xpYi5oIgojaW5jbHVkZSAiRkRLX2F1ZGlvLmgiCiNpbmNsdWRlICJhYWNlbmMuaCIKCiNpbmNsdWRlICJhYWNFbmNfcmFtLmgiCiNpbmNsdWRlICJGREtfY29yZS5oIiAvKiBGREtfdG9vbHMgdmVyc2lvbmluZyBpbmZvICovCgovKiBFbmNvZGVyIGxpYnJhcnkgaW5mbyAqLwojZGVmaW5lIEFBQ0VOQ09ERVJfTElCX1ZMMCAzCiNkZWZpbmUgQUFDRU5DT0RFUl9MSUJfVkwxIDQKI2RlZmluZSBBQUNFTkNPREVSX0xJQl9WTDIgMTAKI2RlZmluZSBBQUNFTkNPREVSX0xJQl9USVRMRSAiQUFDIEVuY29kZXIiCiNkZWZpbmUgQUFDRU5DT0RFUl9MSUJfQlVJTERfREFURSBfX0RBVEVfXwojZGVmaW5lIEFBQ0VOQ09ERVJfTElCX0JVSUxEX1RJTUUgX19USU1FX18KCgojaW5jbHVkZSAic2JyX2VuY29kZXIuaCIKI2luY2x1ZGUgIi4uL3NyYy9zYnJfcmFtLmgiCiNpbmNsdWRlICJjaGFubmVsX21hcC5oIgoKI2luY2x1ZGUgInBzeV9jb25zdC5oIgojaW5jbHVkZSAiYml0ZW5jLmgiCgojaW5jbHVkZSAidHBlbmNfbGliLmgiCgojaW5jbHVkZSAibWV0YWRhdGFfbWFpbi5oIgoKI2RlZmluZSBTQkwoZmwpICAgICAgICAgICAgKGZsLzgpICAgICAgICAgICAgICAgICAvKiE8IFNob3J0IGJsb2NrIGxlbmd0aCAoaGFyZGNvZGVkIHRvIDggc2hvcnQgYmxvY2tzIHBlciBsb25nIGJsb2NrKSAqLwojZGVmaW5lIEJTTEEoZmwpICAgICAgICAgICAoNCpTQkwoZmwpK1NCTChmbCkvMikgIC8qITwgQUFDIGJsb2NrIHN3aXRjaGluZyBsb29rLWFoZWFkICovCiNkZWZpbmUgREVMQVlfQUFDKGZsKSAgICAgIChmbCtCU0xBKGZsKSkgICAgICAgICAgLyohPCBNRENUICsgYmxvY2tzd2l0Y2hpbmcgKi8KI2RlZmluZSBERUxBWV9BQUNFTEQoZmwpICAgKChmbCkvMikgICAgICAgICAgICAgICAvKiE8IEVMRCBGQiBkZWxheSAobm8gZnJhbWluZyBkZWxheSBpbmNsdWRlZCkgKi8KCiNkZWZpbmUgSU5QVVRCVUZGRVJfU0laRSAoMTUzNysxMDArMjA0OCkKCiNkZWZpbmUgREVGQVVMVF9IRUFERVJfUEVSSU9EX1JFUEVUSVRJT05fUkFURSAgMTAgLyohPCBEZWZhdWx0IGhlYWRlciByZXBldGl0aW9uIHJhdGUgdXNlZCBpbiB0cmFuc3BvcnQgbGlicmFyeSBhbmQgZm9yIFNCUiBoZWFkZXIuICovCgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLyoqCiAqIEZsYWdzIHRvIGNoYXJhY3Rlcml6ZSBlbmNvZGVyIG1vZHVsZXMgdG8gYmUgc3VwcG9ydGVkIGluIHByZXNlbnQgaW5zdGFuY2UuCiAqLwplbnVtIHsKICAgIEVOQ19NT0RFX0ZMQUdfQUFDICA9IDB4MDAwMSwKICAgIEVOQ19NT0RFX0ZMQUdfU0JSICA9IDB4MDAwMiwKICAgIEVOQ19NT0RFX0ZMQUdfUFMgICA9IDB4MDAwNCwKICAgIEVOQ19NT0RFX0ZMQUdfU0FDICA9IDB4MDAwOCwKICAgIEVOQ19NT0RFX0ZMQUdfTUVUQSA9IDB4MDAxMAp9OwoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCnR5cGVkZWYgc3RydWN0IHsKICAgIEFVRElPX09CSkVDVF9UWVBFIHVzZXJBT1Q7ICAgICAgICAgICAgICAgLyohPCBBdWRpbyBPYmplY3QgVHlwZS4gICAgICAgICAgICAgKi8KICAgIFVJTlQgICAgICAgICAgICAgIHVzZXJTYW1wbGVyYXRlOyAgICAgICAgLyohPCBTYW1wbGluZyBmcmVxdWVuY3kuICAgICAgICAgICAgKi8KICAgIFVJTlQgICAgICAgICAgICAgIG5DaGFubmVsczsgICAgICAgICAgICAgLyohPCB3aWxsIGJlIHNldCB2aWEgY2hhbm5lbE1vZGUuICAgKi8KICAgIENIQU5ORUxfTU9ERSAgICAgIHVzZXJDaGFubmVsTW9kZTsKICAgIFVJTlQgICAgICAgICAgICAgIHVzZXJCaXRyYXRlOwogICAgVUlOVCAgICAgICAgICAgICAgdXNlckJpdHJhdGVNb2RlOwogICAgVUlOVCAgICAgICAgICAgICAgdXNlckJhbmR3aWR0aDsKICAgIFVJTlQgICAgICAgICAgICAgIHVzZXJBZnRlcmJ1cm5lcjsKICAgIFVJTlQgICAgICAgICAgICAgIHVzZXJGcmFtZWxlbmd0aDsKICAgIFVJTlQgICAgICAgICAgICAgIHVzZXJBbmNEYXRhUmF0ZTsKCiAgICBVQ0hBUiAgICAgICAgICAgICB1c2VyVG5zOyAgICAgICAgICAgICAgIC8qITwgVXNlIFROUyBjb2RpbmcuICovCiAgICBVQ0hBUiAgICAgICAgICAgICB1c2VyUG5zOyAgICAgICAgICAgICAgIC8qITwgVXNlIFBOUyBjb2RpbmcuICovCiAgICBVQ0hBUiAgICAgICAgICAgICB1c2VySW50ZW5zaXR5OyAgICAgICAgIC8qITwgVXNlIEludGVuc2l0eSBjb2RpbmcuICovCgogICAgVFJBTlNQT1JUX1RZUEUgICAgdXNlclRwVHlwZTsgICAgICAgICAgICAvKiE8IFRyYW5zcG9ydCB0eXBlICovCiAgICBVQ0hBUiAgICAgICAgICAgICB1c2VyVHBTaWduYWxpbmc7ICAgICAgIC8qITwgRXh0ZW5zaW9uIEFPVCBzaWduYWxpbmcgbW9kZS4gKi8KICAgIFVDSEFSICAgICAgICAgICAgIHVzZXJUcE5zdWJGcmFtZXM7ICAgICAgLyohPCBOdW1iZXIgb2Ygc3ViIGZyYW1lcyBpbiBhIHRyYW5zcG9ydCBmcmFtZSBmb3IgTE9BUy9MQVRNIG9yIEFEVFMgKGRlZmF1bHQgMSkuICovCiAgICBVQ0hBUiAgICAgICAgICAgICB1c2VyVHBBbXh2OyAgICAgICAgICAgIC8qITwgQXVkaW9NdXhWZXJzaW9uIHRvIGJlIHVzZWQgZm9yIExBVE0gKGRlZmF1bHQgMCkuICovCiAgICBVQ0hBUiAgICAgICAgICAgICB1c2VyVHBQcm90ZWN0aW9uOwogICAgVUNIQVIgICAgICAgICAgICAgdXNlclRwSGVhZGVyUGVyaW9kOyAgICAvKiE8IFBhcmFtZXRlciB1c2VkIHRvIGNvbmZpZ3VyZSBMQVRNL0xPQVMgU01DIHJhdGUuIE1vcmVvdmVyIHRoaXMgcGFyYW1ldGVycyBpcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzZWQgdG8gY29uZmlndXJlIHJlcGV0aXRpb24gcmF0ZSBvZiBQQ0UgaW4gcmF3X2RhdGFfYmxvY2suICovCgogICAgVUNIQVIgICAgICAgICAgICAgdXNlckVyVG9vbHM7ICAgICAgICAgICAvKiE8IFVzZSBWQ0IxMSwgSENSIGFuZC9vciBSVkxDIEVSIHRvb2wuICovCiAgICBVSU5UICAgICAgICAgICAgICB1c2VyUGNlQWRkaXRpb25zOyAgICAgIC8qITwgQ29uZmlndXJlIGFkZGl0aW9uYWwgYml0cyBpbiBQQ0UuICovCgogICAgVUNIQVIgICAgICAgICAgICAgdXNlck1ldGFEYXRhTW9kZTsgICAgICAvKiE8IE1ldGEgZGF0YSBsaWJyYXJ5IGNvbmZpZ3VyYXRpb24uICovCgogICAgVUNIQVIgICAgICAgICAgICAgdXNlclNickVuYWJsZWQ7ICAgICAgICAvKiE8IEVuYWJsZSBTQlIgZm9yIEVMRC4gKi8KICAgIFVJTlQgICAgICAgICAgICAgIHVzZXJTYnJSYXRpbzsgICAgICAgICAgLyohPCBTQlIgc2FtcGxpbmcgcmF0ZSByYXRpby4gRHVhbC0gb3Igc2luZ2xlLXJhdGUuICovCgp9IFVTRVJfUEFSQU07CgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cnVjdHVyZSBEZWZpbml0aW9ucwoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKdHlwZWRlZiBzdHJ1Y3QgIEFBQ0VOQ19DT05GSUcgICAgICpIQU5ETEVfQUFDRU5DX0NPTkZJRzsKCgpzdHJ1Y3QgQUFDRU5DT0RFUgp7CiAgICBVU0VSX1BBUkFNICAgICAgICAgICAgICAgZXh0UGFyYW07CiAgICBDT0RFUl9DT05GSUcgICAgICAgICAgICAgY29kZXJDb25maWc7CgogICAgLyogQUFDICovCiAgICBBQUNFTkNfQ09ORklHICAgICAgICAgICAgYWFjQ29uZmlnOwogICAgSEFORExFX0FBQ19FTkMgICAgICAgICAgIGhBYWNFbmM7CgogICAgLyogU0JSICovCiAgICBIQU5ETEVfU0JSX0VOQ09ERVIgICAgICAgaEVudkVuYzsKCiAgICAvKiBNZXRhIERhdGEgKi8KICAgIEhBTkRMRV9GREtfTUVUQURBVEFfRU5DT0RFUiAgaE1ldGFkYXRhRW5jOwogICAgSU5UICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRhRGF0YUFsbG93ZWQ7IC8qIFNpZ25hbCB3aGV0aGVyIGNob3NlbiBjb25maWd1cmF0aW9uIGFsbG93cyBtZXRhZGF0YS4gTmVjZXNzYXJ5IGZvciBkZWxheQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBlbnNhdGlvbi4gTWV0YWRhdGEgbW9kZSBpcyBhIHNlcGFyYXRlIHBhcmFtZXRlci4gKi8KCiAgICAvKiBUcmFuc3BvcnQgKi8KICAgIEhBTkRMRV9UUkFOU1BPUlRFTkMgICAgICBoVHBFbmM7CgogICAgLyogT3V0cHV0ICovCiAgICBVQ0hBUiAgICAgICAgICAgICAgICAgICAqb3V0QnVmZmVyOyAgICAgICAgIC8qIEludGVybmFsIGJpdHN0cmVhbSBidWZmZXIgKi8KICAgIElOVCAgICAgICAgICAgICAgICAgICAgICBvdXRCdWZmZXJJbkJ5dGVzOyAgIC8qIFNpemUgb2YgaW50ZXJuYWwgYml0c3RyZWFtIGJ1ZmZlciovCgogICAgLyogSW5wdXQgKi8KICAgIElOVF9QQ00gICAgICAgICAgICAgICAgICppbnB1dEJ1ZmZlcjsgICAgICAgIC8qIEludGVybmFsIGlucHV0IGJ1ZmZlci4gSW5wdXQgc291cmNlIGZvciBBQUMgZW5jb2RlciAqLwogICAgSU5UICAgICAgICAgICAgICAgICAgICAgIGlucHV0QnVmZmVyT2Zmc2V0OyAgLyogV2hlcmUgdG8gd3JpdGUgbmV3IGlucHV0IHNhbXBsZXMuICovCgogICAgSU5UICAgICAgICAgICAgICAgICAgICAgIG5TYW1wbGVzVG9SZWFkOyAgICAvKiBudW1iZXIgb2YgaW5wdXQgc2FtcGxlcyBuZWVlZGVkIGZvciBlbmNvZGluZyBvbmUgZnJhbWUgKi8KICAgIElOVCAgICAgICAgICAgICAgICAgICAgICBuU2FtcGxlc1JlYWQ7ICAgICAgLyogbnVtYmVyIG9mIGlucHV0IHNhbXBsZXMgYWxyZWFkeSBpbiBpbnB1dCBidWZmZXIgKi8KICAgIElOVCAgICAgICAgICAgICAgICAgICAgICBuWmVyb3NBcHBlbmRlZDsgICAgLyogYXBwZW5kZWQgemVyb3MgYXQgZW5kIG9mIGZpbGUqLwogICAgSU5UICAgICAgICAgICAgICAgICAgICAgIG5EZWxheTsgICAgICAgICAgICAvKiBlbmNvZGVyIGRlbGF5ICovCgogICAgQUFDRU5DX0VYVF9QQVlMT0FEICAgICAgIGV4dFBheWxvYWQgW01BWF9UT1RBTF9FWFRfUEFZTE9BRFNdOwogICAgLyogRXh0ZW5zaW9uIHBheWxvYWQgKi8KICAgIFVDSEFSICAgICAgICAgICAgICAgICAgICBleHRQYXlsb2FkRGF0YSBbKDEpXVsoNildW01BWF9QQVlMT0FEX1NJWkVdOwogICAgVUlOVCAgICAgICAgICAgICAgICAgICAgIGV4dFBheWxvYWRTaXplIFsoMSldWyg2KV07IC8qIHBheWxvYWQgc2l6ZXMgaW4gYml0cyAqLwoKICAgIFVMT05HICAgICAgICAgICAgICAgICAgICBJbml0RmxhZ3M7ICAgICAgICAgLyogaW50ZXJuYWwgc3RhdHVzIHRvIHRyZWdnaWVyIHJlLWluaXRpYWxpemF0aW9uICovCgoKICAgLyogTWVtb3J5IGFsbG9jYXRpb24gaW5mby4gKi8KICAgSU5UICAgICAgICAgICAgICAgICAgICAgICBuTWF4QWFjRWxlbWVudHM7CiAgIElOVCAgICAgICAgICAgICAgICAgICAgICAgbk1heEFhY0NoYW5uZWxzOwogICBJTlQgICAgICAgICAgICAgICAgICAgICAgIG5NYXhTYnJFbGVtZW50czsKICAgSU5UICAgICAgICAgICAgICAgICAgICAgICBuTWF4U2JyQ2hhbm5lbHM7CiAgIFVJTlQgICAgICAgICAgICAgICAgICAgICAgbk1heFN1YkZyYW1lczsKCiAgIFVJTlQgICAgICAgICAgICAgICAgICAgICAgZW5jb2Rlcl9tb2RpczsKCiAgIC8qIENhcGFiaWxpdHkgZmxhZ3MgKi8KICAgVUlOVCAgICAgICAgICAgICAgICAgICAgICBDQVBGX3RwRW5jOwoKfSA7CgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCnN0YXRpYyBpbmxpbmUgSU5UIGlzU2JyQWN0aXZlKGNvbnN0IEhBTkRMRV9BQUNFTkNfQ09ORklHIGhBYWNDb25maWcpCnsKICAgIElOVCBzYnJVc2VkID0gMDsKCiAgICBpZiAoIChoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGU9PUFPVF9TQlIpICAgICAgICAgfHwgKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZT09QU9UX1BTKQogICAgICB8fCAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlPT1BT1RfTVAyX1NCUikgICAgIHx8IChoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGU9PUFPVF9NUDJfUFMpCiAgICAgIHx8IChoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGU9PUFPVF9EQUJQTFVTX1NCUikgfHwgKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZT09QU9UX0RBQlBMVVNfUFMpCiAgICAgIHx8IChoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGU9PUFPVF9EUk1fU0JSKSAgICAgfHwgKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZT09QU9UX0RSTV9NUEVHX1BTKSApCiAgICB7CiAgICAgICAgc2JyVXNlZCA9IDE7CiAgICB9CiAgICBpZiAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlID09IEFPVF9FUl9BQUNfRUxEICYmIChoQWFjQ29uZmlnLT5zeW50YXhGbGFncyAmIEFDX1NCUl9QUkVTRU5UKSkKICAgIHsKICAgICAgICBzYnJVc2VkID0gMTsKICAgIH0KCiAgICByZXR1cm4gKCBzYnJVc2VkICk7Cn0KCnN0YXRpYyBpbmxpbmUgSU5UIGlzUHNBY3RpdmUoY29uc3QgQVVESU9fT0JKRUNUX1RZUEUgYXVkaW9PYmplY3RUeXBlKQp7CiAgICBJTlQgcHNVc2VkID0gMDsKCiAgICBpZiAoIChhdWRpb09iamVjdFR5cGU9PUFPVF9QUykKICAgICAgfHwgKGF1ZGlvT2JqZWN0VHlwZT09QU9UX01QMl9QUykKICAgICAgfHwgKGF1ZGlvT2JqZWN0VHlwZT09QU9UX0RBQlBMVVNfUFMpCiAgICAgIHx8IChhdWRpb09iamVjdFR5cGU9PUFPVF9EUk1fTVBFR19QUykgKQogICAgewogICAgICAgIHBzVXNlZCA9IDE7CiAgICB9CgogICAgcmV0dXJuICggcHNVc2VkICk7Cn0KCnN0YXRpYyBTQlJfUFNfU0lHTkFMSU5HIGdldFNiclNpZ25hbGluZ01vZGUoCiAgICAgICAgY29uc3QgQVVESU9fT0JKRUNUX1RZUEUgICAgICAgICAgYXVkaW9PYmplY3RUeXBlLAogICAgICAgIGNvbnN0IFRSQU5TUE9SVF9UWVBFICAgICAgICAgICAgIHRyYW5zcG9ydFR5cGUsCiAgICAgICAgY29uc3QgVUNIQVIgICAgICAgICAgICAgICAgICAgICAgdHJhbnNwb3J0U2lnbmFsaW5nLAogICAgICAgIGNvbnN0IFVJTlQgICAgICAgICAgICAgICAgICAgICAgIHNiclJhdGlvCiAgICAgICAgKQoKewogIFNCUl9QU19TSUdOQUxJTkcgc2JyU2lnbmFsaW5nOwoKICBpZiAodHJhbnNwb3J0VHlwZT09VFRfVU5LTk9XTiB8fCBzYnJSYXRpbz09MCkgewogICAgc2JyU2lnbmFsaW5nID0gU0lHX1VOS05PV047IC8qIE5lZWRlZCBwYXJhbWV0ZXJzIGhhdmUgbm90IGJlZW4gc2V0ICovCiAgICByZXR1cm4gc2JyU2lnbmFsaW5nOwogIH0gZWxzZSB7CiAgICBzYnJTaWduYWxpbmcgPSBTSUdfSU1QTElDSVQ7IC8qIGRlZmF1bHQ6IGltcGxpY2l0IHNpZ25hbGluZyAqLwogIH0KCiAgaWYgKChhdWRpb09iamVjdFR5cGU9PUFPVF9BQUNfTEMpICAgICB8fCAoYXVkaW9PYmplY3RUeXBlPT1BT1RfU0JSKSAgICAgfHwgKGF1ZGlvT2JqZWN0VHlwZT09QU9UX1BTKSAgICB8fAogICAgICAoYXVkaW9PYmplY3RUeXBlPT1BT1RfTVAyX0FBQ19MQykgfHwgKGF1ZGlvT2JqZWN0VHlwZT09QU9UX01QMl9TQlIpIHx8IChhdWRpb09iamVjdFR5cGU9PUFPVF9NUDJfUFMpICkgewogICAgc3dpdGNoICh0cmFuc3BvcnRUeXBlKSB7CiAgICAgIGNhc2UgVFRfTVA0X0FESUY6CiAgICAgIGNhc2UgVFRfTVA0X0FEVFM6CiAgICAgICAgc2JyU2lnbmFsaW5nID0gU0lHX0lNUExJQ0lUOyAvKiBGb3IgTVBFRy0yIHRyYW5zcG9ydCB0eXBlcywgb25seSBpbXBsaWNpdCBzaWduYWxpbmcgaXMgcG9zc2libGUgKi8KICAgICAgICBicmVhazsKCiAgICAgIGNhc2UgVFRfTVA0X1JBVzoKICAgICAgY2FzZSBUVF9NUDRfTEFUTV9NQ1AxOgogICAgICBjYXNlIFRUX01QNF9MQVRNX01DUDA6CiAgICAgIGNhc2UgVFRfTVA0X0xPQVM6CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgaWYgKCB0cmFuc3BvcnRTaWduYWxpbmc9PTB4RkYgKSB7CiAgICAgICAgICAvKiBEZWZhdWx0cyAqLwogICAgICAgICAgaWYgKCBzYnJSYXRpbz09MSApIHsKICAgICAgICAgICAgc2JyU2lnbmFsaW5nID0gU0lHX0VYUExJQ0lUX0hJRVJBUkNISUNBTDsgLyogRm9yIGRvd25zYW1wbGVkIFNCUiwgZXhwbGljaXQgc2lnbmFsaW5nIGlzIG1hbmRhdG9yeSAqLwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc2JyU2lnbmFsaW5nID0gU0lHX0lNUExJQ0lUOyAvKiBGb3IgZHVhbC1yYXRlIFNCUiwgaW1wbGljaXQgc2lnbmFsaW5nIGlzIGRlZmF1bHQgKi8KICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgLyogVXNlciBzZXQgcGFyYW1ldGVycyAqLwogICAgICAgICAgLyogQXR0ZW50aW9uOiBCYWNrd2FyZCBjb21wYXRpYmxlIGV4cGxpY2l0IHNpZ25hbGluZyBkb2VzIG9ubHkgd29yayB3aXRoIEFNVjEgZm9yIExBVE0vTE9BUyAqLwogICAgICAgICAgc2JyU2lnbmFsaW5nID0gKFNCUl9QU19TSUdOQUxJTkcpdHJhbnNwb3J0U2lnbmFsaW5nOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KICB9CgogIHJldHVybiBzYnJTaWduYWxpbmc7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbGxvY2F0ZSBFbmNvZGVyCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpIX0FMTE9DX01FTSAoX0FhY0VuY29kZXIsIEFBQ0VOQ09ERVIpCkNfQUxMT0NfTUVNIChfQWFjRW5jb2RlciwgQUFDRU5DT0RFUiwgMSkKCgoKCi8qCiAqIE1hcCBFbmNvZGVyIHNwZWNpZmljIGNvbmZpZyBzdHJ1Y3R1cmVzIHRvIENPREVSX0NPTkZJRy4KICovCnN0YXRpYyB2b2lkIEZES2FhY0VuY19NYXBDb25maWcoCiAgICAgICAgQ09ERVJfQ09ORklHICpjb25zdCAgICAgICAgICAgICAgY2MsCiAgICAgICAgY29uc3QgVVNFUl9QQVJBTSAqY29uc3QgICAgICAgICAgZXh0Q2ZnLAogICAgICAgIGNvbnN0IFNCUl9QU19TSUdOQUxJTkcgICAgICAgICAgIHNiclNpZ25hbGluZywKICAgICAgICBjb25zdCBIQU5ETEVfQUFDRU5DX0NPTkZJRyAgICAgICBoQWFjQ29uZmlnCiAgICAgICAgKQp7CiAgQVVESU9fT0JKRUNUX1RZUEUgdHJhbnNwb3J0X0FPVCA9IEFPVF9OVUxMX09CSkVDVDsKICBGREttZW1jbGVhcihjYywgc2l6ZW9mKENPREVSX0NPTkZJRykpOwoKICBjYy0+ZmxhZ3MgPSAwOwoKICAvKiBNYXAgdmlydHVhbCBhb3QgdG8gdHJhbnNwb3J0IGFvdC4gKi8KICBzd2l0Y2ggKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZSkgewogICAgY2FzZSBBT1RfTVAyX0FBQ19MQzoKICAgICAgdHJhbnNwb3J0X0FPVCA9IEFPVF9BQUNfTEM7CiAgICAgIGJyZWFrOwogICAgY2FzZSBBT1RfTVAyX1NCUjoKICAgICAgdHJhbnNwb3J0X0FPVCA9IEFPVF9TQlI7CiAgICAgIGNjLT5mbGFncyB8PSBDQ19TQlI7CiAgICAgYnJlYWs7CiAgICBjYXNlIEFPVF9NUDJfUFM6CiAgICAgIHRyYW5zcG9ydF9BT1QgPSBBT1RfUFM7CiAgICAgIGNjLT5mbGFncyB8PSBDQ19TQlI7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgdHJhbnNwb3J0X0FPVCA9IGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZTsKICB9CgogIGlmIChoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGUgPT0gQU9UX0VSX0FBQ19FTEQpIHsKICAgIGNjLT5mbGFncyB8PSAoaEFhY0NvbmZpZy0+c3ludGF4RmxhZ3MgJiBBQ19TQlJfUFJFU0VOVCkgPyBDQ19TQlIgOiAwOwogIH0KCiAgLyogdHJhbnNwb3J0IHR5cGUgaXMgdXN1YWxseSBBQUMtTEMuICovCiAgaWYgKCAodHJhbnNwb3J0X0FPVCA9PSBBT1RfU0JSKSB8fCAodHJhbnNwb3J0X0FPVCA9PSBBT1RfUFMpICkgewogICAgY2MtPmFvdCAgICAgICAgICAgPSBBT1RfQUFDX0xDOwogIH0KICBlbHNlIHsKICAgIGNjLT5hb3QgICAgICAgICAgID0gdHJhbnNwb3J0X0FPVDsKICB9CgogIC8qIENvbmZpZ3VyZSBleHRlbnNpb24gYW90LiAqLwogIGlmIChzYnJTaWduYWxpbmc9PVNJR19JTVBMSUNJVCkgewogICAgY2MtPmV4dEFPVCA9IEFPVF9OVUxMX09CSkVDVDsgIC8qIGltcGxpY2l0ICovCiAgfQogIGVsc2UgewogICAgaWYgKCAoc2JyU2lnbmFsaW5nPT1TSUdfRVhQTElDSVRfQldfQ09NUEFUSUJMRSkgJiYgKCAodHJhbnNwb3J0X0FPVD09QU9UX1NCUikgfHwgKHRyYW5zcG9ydF9BT1Q9PUFPVF9QUykgKSApIHsKICAgICAgY2MtPmV4dEFPVCA9IEFPVF9TQlI7ICAgICAgICAvKiBleHBsaWNpdCBiYWNrd2FyZCBjb21wYXRpYmxlICovCiAgICB9CiAgICBlbHNlIHsKICAgICAgY2MtPmV4dEFPVCA9IHRyYW5zcG9ydF9BT1Q7ICAvKiBleHBsaWNpdCBoaWVyYXJjaGljYWwgKi8KICAgIH0KICB9CgogIGlmICggKHRyYW5zcG9ydF9BT1Q9PUFPVF9TQlIpIHx8ICh0cmFuc3BvcnRfQU9UPT1BT1RfUFMpICkgewogICAgY2MtPnNiclByZXNlbnQ9MTsKICAgIGlmICh0cmFuc3BvcnRfQU9UPT1BT1RfUFMpIHsKICAgICAgY2MtPnBzUHJlc2VudD0xOwogICAgfQogIH0KICBjYy0+c2JyU2lnbmFsaW5nICAgID0gc2JyU2lnbmFsaW5nOwoKICBjYy0+ZXh0U2FtcGxpbmdSYXRlID0gZXh0Q2ZnLT51c2VyU2FtcGxlcmF0ZTsKICBjYy0+Yml0UmF0ZSAgICAgICAgID0gaEFhY0NvbmZpZy0+Yml0UmF0ZTsKICBjYy0+bm9DaGFubmVscyAgICAgID0gaEFhY0NvbmZpZy0+bkNoYW5uZWxzOwogIGNjLT5mbGFncyAgICAgICAgICB8PSBDQ19JU19CQVNFTEFZRVI7CiAgY2MtPmNoYW5uZWxNb2RlICAgICA9IGhBYWNDb25maWctPmNoYW5uZWxNb2RlOwoKICBjYy0+blN1YkZyYW1lcyA9IChoQWFjQ29uZmlnLT5uU3ViRnJhbWVzID4gMSAmJiBleHRDZmctPnVzZXJUcE5zdWJGcmFtZXMgPT0gMSkKICAgICAgICAgICAgICAgICA/IGhBYWNDb25maWctPm5TdWJGcmFtZXMKICAgICAgICAgICAgICAgICA6IGV4dENmZy0+dXNlclRwTnN1YkZyYW1lczsKCiAgY2MtPmZsYWdzICAgICAgICAgIHw9IChleHRDZmctPnVzZXJUcFByb3RlY3Rpb24pID8gQ0NfUFJPVEVDVElPTiA6IDA7CgogIGlmIChleHRDZmctPnVzZXJUcEhlYWRlclBlcmlvZCE9MHhGRikgewogICAgY2MtPmhlYWRlclBlcmlvZCAgICA9IGV4dENmZy0+dXNlclRwSGVhZGVyUGVyaW9kOwogIH0KICBlbHNlIHsgLyogYXV0by1tb2RlICovCiAgICBzd2l0Y2ggKGV4dENmZy0+dXNlclRwVHlwZSkgewogICAgICBjYXNlIFRUX01QNF9BRFRTOgogICAgICBjYXNlIFRUX01QNF9MT0FTOgogICAgICBjYXNlIFRUX01QNF9MQVRNX01DUDE6CiAgICAgICAgY2MtPmhlYWRlclBlcmlvZCA9IERFRkFVTFRfSEVBREVSX1BFUklPRF9SRVBFVElUSU9OX1JBVEU7CiAgICAgICAgYnJlYWs7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgY2MtPmhlYWRlclBlcmlvZCA9IDA7CiAgICB9CiAgfQoKICBjYy0+c2FtcGxlc1BlckZyYW1lID0gaEFhY0NvbmZpZy0+ZnJhbWVsZW5ndGg7CiAgY2MtPnNhbXBsaW5nUmF0ZSAgICA9IGhBYWNDb25maWctPnNhbXBsZVJhdGU7CgogIC8qIE1wZWctNCBzaWduYWxpbmcgZm9yIHRyYW5zcG9ydCBsaWJyYXJ5LiAqLwogIHN3aXRjaCAoIGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZSApIHsKICAgIGNhc2UgQU9UX01QMl9BQUNfTEM6CiAgICBjYXNlIEFPVF9NUDJfU0JSOgogICAgY2FzZSBBT1RfTVAyX1BTOgogICAgICBjYy0+ZmxhZ3MgJj0gfkNDX01QRUdfSUQ7IC8qIFJlcXVpcmVkIGZvciBBRFRTLiAqLwogICAgICBjYy0+ZXh0QU9UID0gQU9UX05VTExfT0JKRUNUOwogICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIGNjLT5mbGFncyB8PSBDQ19NUEVHX0lEOwogIH0KCiAgLyogRVItdG9vbHMgc2lnbmFsaW5nLiAqLwogIGNjLT5mbGFncyAgICAgfD0gKGhBYWNDb25maWctPnN5bnRheEZsYWdzICYgQUNfRVJfVkNCMTEpID8gQ0NfVkNCMTEgOiAwOwogIGNjLT5mbGFncyAgICAgfD0gKGhBYWNDb25maWctPnN5bnRheEZsYWdzICYgQUNfRVJfSENSKSAgID8gQ0NfSENSIDogMDsKICBjYy0+ZmxhZ3MgICAgIHw9IChoQWFjQ29uZmlnLT5zeW50YXhGbGFncyAmIEFDX0VSX1JWTEMpICA/IENDX1JWTEMgOiAwOwoKICAvKiBNYXRyaXggbWl4ZG93biBjb2VmZmljaWVudCBjb25maWd1cmF0aW9uLiAqLwogIGlmICggKGV4dENmZy0+dXNlclBjZUFkZGl0aW9ucyYweDEpICYmIChoQWFjQ29uZmlnLT5lcENvbmZpZz09LTEpCiAgICAgICYmICgoY2MtPmNoYW5uZWxNb2RlPT1NT0RFXzFfMl8yKXx8KGNjLT5jaGFubmVsTW9kZT09TU9ERV8xXzJfMl8xKSkgKQogIHsKICAgIGNjLT5tYXRyaXhNaXhkb3duQSAgICAgICA9ICgoZXh0Q2ZnLT51c2VyUGNlQWRkaXRpb25zPj4xKSYweDMpKzE7CiAgICBjYy0+ZmxhZ3MgfD0gKGV4dENmZy0+dXNlclBjZUFkZGl0aW9ucz4+MykmMHgxID8gQ0NfUFNFVURPX1NVUlJPVU5EIDogMDsKICB9CiAgZWxzZSB7CiAgICBjYy0+bWF0cml4TWl4ZG93bkEgPSAwOwogIH0KfQoKLyoKICogRXhhbWluZSBidWZmZXIgZGVzY3JpcHRvciByZWdhcmRpbmcgY2hvb3NlbiBpZGVudGlmaWVyLgogKgogKiBccGFyYW0gcEJ1ZkRlc2MgICAgICAgICAgICAgIFBvaW50ZXIgdG8gYnVmZmVyIGRlc2NyaXB0b3IKICogXHBhcmFtIGlkZW50aWZpZXIgICAgICAgICAgICBCdWZmZXIgaWRlbnRpZmllciB0byBsb29rIGZvci4KCiAqIFxyZXR1cm4gLSBCdWZmZXIgZGVzY3JpcHRvciBpbmRleC4KICogICAgICAgICAtMSwgaWYgdGhlcmUgaXMgbm8gZW50cnkgYXZhaWxhYmxlLgogKi8Kc3RhdGljIElOVCBnZXRCdWZEZXNjSWR4KAogICAgICAgIGNvbnN0IEFBQ0VOQ19CdWZEZXNjICAgICAgICAgKnBCdWZEZXNjLAogICAgICAgIGNvbnN0IEFBQ0VOQ19CdWZmZXJJZGVudGlmaWVyIGlkZW50aWZpZXIKKQp7CiAgICBJTlQgaSwgaWR4ID0gLTE7CgogICAgZm9yIChpPTA7IGk8cEJ1ZkRlc2MtPm51bUJ1ZnM7IGkrKykgewogICAgICBpZiAoIChBQUNFTkNfQnVmZmVySWRlbnRpZmllcilwQnVmRGVzYy0+YnVmZmVySWRlbnRpZmllcnNbaV0gPT0gaWRlbnRpZmllciApIHsKICAgICAgICBpZHggPSBpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gaWR4Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgICAgICAgICAgICAgICAgICAgICAgICBGdW5jdGlvbiBEZWNsYXJhdGlvbnMKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCkFBQ19FTkNPREVSX0VSUk9SIGFhY0VuY0RlZmF1bHRDb25maWcoSEFORExFX0FBQ0VOQ19DT05GSUcgaEFhY0NvbmZpZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVU0VSX1BBUkFNICpjb25maWcpCnsKICAgIC8qIG1ha2UgcmVhc29uYWJsZSBkZWZhdWx0IHNldHRpbmdzICovCiAgICBGREthYWNFbmNfQWFjSW5pdERlZmF1bHRDb25maWcgKGhBYWNDb25maWcpOwoKICAgIC8qIGNsZWFyIGNvbmZpZ3VyYXRpb24gc3RydWN0dXJlIGFuZCBjb3B5IGRlZmF1bHQgc2V0dGluZ3MgKi8KICAgIEZES21lbWNsZWFyKGNvbmZpZywgc2l6ZW9mKFVTRVJfUEFSQU0pKTsKCiAgICAvKiBjb3B5IGVuY29kZXIgY29uZmlndXJhdGlvbiBzZXR0aW5ncyAqLwogICAgY29uZmlnLT5uQ2hhbm5lbHMgICAgICAgPSBoQWFjQ29uZmlnLT5uQ2hhbm5lbHM7CiAgICBjb25maWctPnVzZXJBT1QgPSBoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGUgPSBBT1RfQUFDX0xDOwogICAgY29uZmlnLT51c2VyU2FtcGxlcmF0ZSAgPSBoQWFjQ29uZmlnLT5zYW1wbGVSYXRlOwogICAgY29uZmlnLT51c2VyQ2hhbm5lbE1vZGUgPSBoQWFjQ29uZmlnLT5jaGFubmVsTW9kZTsKICAgIGNvbmZpZy0+dXNlckJpdHJhdGUgICAgID0gaEFhY0NvbmZpZy0+Yml0UmF0ZTsKICAgIGNvbmZpZy0+dXNlckJpdHJhdGVNb2RlID0gaEFhY0NvbmZpZy0+Yml0cmF0ZU1vZGU7CiAgICBjb25maWctPnVzZXJCYW5kd2lkdGggICA9IGhBYWNDb25maWctPmJhbmRXaWR0aDsKICAgIGNvbmZpZy0+dXNlclRucyAgICAgICAgID0gaEFhY0NvbmZpZy0+dXNlVG5zOwogICAgY29uZmlnLT51c2VyUG5zICAgICAgICAgPSBoQWFjQ29uZmlnLT51c2VQbnM7CiAgICBjb25maWctPnVzZXJJbnRlbnNpdHkgICA9IGhBYWNDb25maWctPnVzZUlTOwogICAgY29uZmlnLT51c2VyQWZ0ZXJidXJuZXIgPSBoQWFjQ29uZmlnLT51c2VSZXF1YW50OwogICAgY29uZmlnLT51c2VyRnJhbWVsZW5ndGggPSAoVUlOVCktMTsKCiAgICBpZiAoaEFhY0NvbmZpZy0+c3ludGF4RmxhZ3MgJiBBQ19FUl9WQ0IxMSkgewogICAgICBjb25maWctPnVzZXJFclRvb2xzICB8PSAweDAxOwogICAgfQogICAgaWYgKGhBYWNDb25maWctPnN5bnRheEZsYWdzICYgQUNfRVJfSENSKSB7CiAgICAgIGNvbmZpZy0+dXNlckVyVG9vbHMgIHw9IDB4MDI7CiAgICB9CgogICAgLyogaW5pdGlhbGl6ZSB0cmFuc3BvcnQgcGFyYW1ldGVycyAqLwogICAgY29uZmlnLT51c2VyVHBUeXBlICAgICAgICAgPSBUVF9VTktOT1dOOwogICAgY29uZmlnLT51c2VyVHBBbXh2ICAgICAgICAgPSAwOwogICAgY29uZmlnLT51c2VyVHBTaWduYWxpbmcgICAgPSAweEZGOyAgICAvKiBjaG9vc2Ugc2lnbmFsaW5nIGF1dG9tYXRpY2FsbHkgKi8KICAgIGNvbmZpZy0+dXNlclRwTnN1YkZyYW1lcyAgID0gMTsKICAgIGNvbmZpZy0+dXNlclRwUHJvdGVjdGlvbiAgID0gMDsgICAgLyogbm90IGNyYyBwcm90ZWN0ZWQqLwogICAgY29uZmlnLT51c2VyVHBIZWFkZXJQZXJpb2QgPSAweEZGOyAvKiBoZWFkZXIgcGVyaW9kIGluIGF1dG8gbW9kZSAqLwogICAgY29uZmlnLT51c2VyUGNlQWRkaXRpb25zICAgPSAwOyAgICAvKiBubyBtYXRyaXggbWl4ZG93biBjb2VmZmljaWVudCAqLwogICAgY29uZmlnLT51c2VyTWV0YURhdGFNb2RlICAgPSAwOyAgICAvKiBkbyBub3QgZW1iZWQgYW55IG1ldGEgZGF0YSBpbmZvICovCgogICAgY29uZmlnLT51c2VyQW5jRGF0YVJhdGUgICAgPSAwOwoKICAgIC8qIFNCUiByYXRlIGlzIHNldCB0byAwIGhlcmUsIHdoaWNoIG1lYW5zIGl0IHNob3VsZCBiZSBzZXQgYXV0b21hdGljYWxseQogICAgICAgaW4gRkRLYWFjRW5jX0FkanVzdEVuY1NldHRpbmdzKCkgaWYgdGhlIHVzZXIgZGlkIG5vdCBzZXQgYSByYXRlCiAgICAgICBleHBpbGljaXRlbHkuICovCiAgICBjb25maWctPnVzZXJTYnJSYXRpbyA9IDA7CgogICAgLyogU0JSIGVuYWJsZSBzZXQgdG8gLTEgbWVhbnMgdG8gaW5xdWlyZSBFTEQgYXVkaW8gY29uZmlndXJhdG9yIGZvciByZWFzb25hYmxlIGNvbmZpZ3VyYXRpb24uICovCiAgICBjb25maWctPnVzZXJTYnJFbmFibGVkICAgICA9IC0xOwoKICAgIHJldHVybiBBQUNfRU5DX09LOwp9CgpzdGF0aWMKdm9pZCBhYWNFbmNEaXN0cmlidXRlU2JyQml0cyhDSEFOTkVMX01BUFBJTkcgKmNoYW5uZWxNYXBwaW5nLCBTQlJfRUxFTUVOVF9JTkZPICpzYnJFbEluZm8sIElOVCBiaXRSYXRlKQp7CiAgSU5UIGNvZGViaXRzID0gYml0UmF0ZTsKICBpbnQgZWw7CgogIC8qIENvcHkgRWxlbWVudCBpbmZvICovCiAgZm9yIChlbD0wOyBlbDxjaGFubmVsTWFwcGluZy0+bkVsZW1lbnRzOyBlbCsrKSB7CiAgICAgIHNickVsSW5mb1tlbF0uQ2hhbm5lbEluZGV4WzBdID0gY2hhbm5lbE1hcHBpbmctPmVsSW5mb1tlbF0uQ2hhbm5lbEluZGV4WzBdOwogICAgICBzYnJFbEluZm9bZWxdLkNoYW5uZWxJbmRleFsxXSA9IGNoYW5uZWxNYXBwaW5nLT5lbEluZm9bZWxdLkNoYW5uZWxJbmRleFsxXTsKICAgICAgc2JyRWxJbmZvW2VsXS5lbFR5cGUgICAgICAgICAgPSBjaGFubmVsTWFwcGluZy0+ZWxJbmZvW2VsXS5lbFR5cGU7CiAgICAgIHNickVsSW5mb1tlbF0uYml0UmF0ZSAgICAgICAgID0gKElOVCkoZk11bHROb3JtKGNoYW5uZWxNYXBwaW5nLT5lbEluZm9bZWxdLnJlbGF0aXZlQml0cywgKEZJWFBfREJMKWJpdFJhdGUpKTsKICAgICAgc2JyRWxJbmZvW2VsXS5pbnN0YW5jZVRhZyAgICAgPSBjaGFubmVsTWFwcGluZy0+ZWxJbmZvW2VsXS5pbnN0YW5jZVRhZzsKICAgICAgc2JyRWxJbmZvW2VsXS5uQ2hhbm5lbHNJbkVsICAgPSBjaGFubmVsTWFwcGluZy0+ZWxJbmZvW2VsXS5uQ2hhbm5lbHNJbkVsOwoKICAgICAgY29kZWJpdHMgLT0gc2JyRWxJbmZvW2VsXS5iaXRSYXRlOwogIH0KICBzYnJFbEluZm9bMF0uYml0UmF0ZSArPSBjb2RlYml0czsKfQoKCnN0YXRpYwpJTlQgYWFjRW5jb2Rlcl9MaW1pdEJpdHJhdGUoCiAgICAgICAgY29uc3QgSEFORExFX1RSQU5TUE9SVEVOQyBoVHBFbmMsCiAgICAgICAgY29uc3QgSU5UIHNhbXBsaW5nUmF0ZSwKICAgICAgICBjb25zdCBJTlQgZnJhbWVMZW5ndGgsCiAgICAgICAgY29uc3QgSU5UIG5DaGFubmVscywKICAgICAgICBjb25zdCBDSEFOTkVMX01PREUgY2hhbm5lbE1vZGUsCiAgICAgICAgSU5UIGJpdFJhdGUsCiAgICAgICAgY29uc3QgSU5UIG5TdWJGcmFtZXMsCiAgICAgICAgY29uc3QgSU5UIHNickFjdGl2ZSwKICAgICAgICBjb25zdCBJTlQgc2JyRG93blNhbXBsZVJhdGUsCiAgICAgICAgY29uc3QgQVVESU9fT0JKRUNUX1RZUEUgYW90CiAgICAgICAgKQp7CiAgSU5UIGNvcmVTYW1wbGluZ1JhdGU7CiAgQ0hBTk5FTF9NQVBQSU5HIGNtOwoKICBGREthYWNFbmNfSW5pdENoYW5uZWxNYXBwaW5nKGNoYW5uZWxNb2RlLCBDSF9PUkRFUl9NUEVHLCAmY20pOwoKICBpZiAoc2JyQWN0aXZlKSB7CiAgICBjb3JlU2FtcGxpbmdSYXRlID0gc2FtcGxpbmdSYXRlID4+ICAoc2JyRW5jb2Rlcl9Jc1NpbmdsZVJhdGVQb3NzaWJsZShhb3QpID8gKHNickRvd25TYW1wbGVSYXRlLTEpOjEpOwogIH0gZWxzZSB7CiAgICBjb3JlU2FtcGxpbmdSYXRlID0gc2FtcGxpbmdSYXRlOwogIH0KCiAgLyogQ29uc2lkZXIgYmFuZHdpZHRoIGNoYW5uZWwgYml0IHJhdGUgbGltaXQgKHNlZSBiYW5kd2lkdGguY3BwOiBHZXRCYW5kd2lkdGhFbnRyeSgpKSAqLwogIGlmIChhb3QgPT0gQU9UX0VSX0FBQ19MRCB8fCBhb3QgPT0gQU9UX0VSX0FBQ19FTEQpIHsKICAgIGJpdFJhdGUgPSBGREttaW4oMzYwMDAwKm5DaGFubmVscywgYml0UmF0ZSk7CiAgICBiaXRSYXRlID0gRkRLbWF4KDgwMDAqbkNoYW5uZWxzLCBiaXRSYXRlKTsKICB9CgogIGlmIChhb3QgPT0gQU9UX0FBQ19MQyB8fCBhb3QgPT0gQU9UX1NCUiB8fCBhb3QgPT0gQU9UX1BTKSAgewogICAgYml0UmF0ZSA9IEZES21pbig1NzYwMDAqbkNoYW5uZWxzLCBiaXRSYXRlKTsKICAgIC8qYml0UmF0ZSA9IEZES21heCgwKm5DaGFubmVscywgYml0UmF0ZSk7Ki8KICB9CgoKICAvKiBMaW1pdCBiaXQgcmF0ZSBpbiByZXNwZWN0IHRvIHRoZSBjb3JlIGNvZGVyICovCiAgYml0UmF0ZSA9IEZES2FhY0VuY19MaW1pdEJpdHJhdGUoCiAgICAgICAgICBoVHBFbmMsCiAgICAgICAgICBjb3JlU2FtcGxpbmdSYXRlLAogICAgICAgICAgZnJhbWVMZW5ndGgsCiAgICAgICAgICBuQ2hhbm5lbHMsCiAgICAgICAgICBjbS5uQ2hhbm5lbHNFZmYsCiAgICAgICAgICBiaXRSYXRlLAogICAgICAgICAgLTEsCiAgICAgICAgICBOVUxMLAogICAgICAgICAgLTEsCiAgICAgICAgICBuU3ViRnJhbWVzCiAgICAgICAgICApOwoKICAvKiBMaW1pdCBiaXQgcmF0ZSBpbiByZXNwZWN0IHRvIGF2YWlsYWJsZSBTQlIgbW9kZXMgaWYgYWN0aXZlICovCiAgaWYgKHNickFjdGl2ZSkKICB7CiAgICBpbnQgbnVtSXRlcmF0aW9ucyA9IDA7CiAgICBJTlQgaW5pdGlhbEJpdHJhdGUsIGFkanVzdGVkQml0cmF0ZTsKICAgIGluaXRpYWxCaXRyYXRlID0gYWRqdXN0ZWRCaXRyYXRlID0gYml0UmF0ZTsKCiAgICAvKiBGaW5kIHRvdGFsIGJpdHJhdGUgd2hpY2ggcHJvdmlkZXMgdmFsaWQgY29uZmlndXJhdGlvbiBmb3IgZWFjaCBTQlIgZWxlbWVudC4gKi8KICAgIGRvIHsKICAgICAgaW50IGU7CiAgICAgIFNCUl9FTEVNRU5UX0lORk8gc2JyRWxJbmZvWyg2KV07CiAgICAgIEZES19BU1NFUlQoY20ubkVsZW1lbnRzIDw9ICg2KSk7CgogICAgICBpbml0aWFsQml0cmF0ZSA9IGFkanVzdGVkQml0cmF0ZTsKCiAgICAgIC8qIEdldCBiaXQgcmF0ZSBmb3IgZWFjaCBTQlIgZWxlbWVudCAqLwogICAgICBhYWNFbmNEaXN0cmlidXRlU2JyQml0cygmY20sIHNickVsSW5mbywgaW5pdGlhbEJpdHJhdGUpOwoKICAgICAgZm9yIChlPTA7IGU8Y20ubkVsZW1lbnRzOyBlKyspCiAgICAgIHsKICAgICAgICBJTlQgc2JyRWxlbWVudEJpdFJhdGVJbiwgc2JyQml0UmF0ZU91dDsKCiAgICAgICAgaWYgKGNtLmVsSW5mb1tlXS5lbFR5cGUgIT0gSURfU0NFICYmIGNtLmVsSW5mb1tlXS5lbFR5cGUgIT0gSURfQ1BFKSB7CiAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgc2JyRWxlbWVudEJpdFJhdGVJbiA9IHNickVsSW5mb1tlXS5iaXRSYXRlOwogICAgICAgIHNickJpdFJhdGVPdXQgPSBzYnJFbmNvZGVyX0xpbWl0Qml0UmF0ZShzYnJFbGVtZW50Qml0UmF0ZUluICwgY20uZWxJbmZvW2VdLm5DaGFubmVsc0luRWwsIGNvcmVTYW1wbGluZ1JhdGUsIGFvdCk7CiAgICAgICAgaWYgKHNickJpdFJhdGVPdXQgPT0gMCkgewogICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICAvKiBJZiBiaXRyYXRlcyBkb24ndCBtYXRjaCwgZGlzdHJpYnV0aW9uIGFuZCBsaW1pdGluZyBuZWVkcyB0byBiZSBkZXRlcm1pbmVkIGFnYWluLgogICAgICAgICAgIEFib3J0IGVsZW1lbnQgbG9vcCBhbmQgcmVzdGFydCB3aXRoIGFkYXB0ZWQgYml0cmF0ZS4gKi8KICAgICAgICBpZiAoc2JyRWxlbWVudEJpdFJhdGVJbiAhPSBzYnJCaXRSYXRlT3V0KSB7CgogICAgICAgICAgaWYgKHNickVsZW1lbnRCaXRSYXRlSW4gPCBzYnJCaXRSYXRlT3V0KSB7CiAgICAgICAgICAgIGFkanVzdGVkQml0cmF0ZSA9IGZNYXgoaW5pdGlhbEJpdHJhdGUsIChJTlQpZkRpdk5vcm0oKEZJWFBfREJMKShzYnJCaXRSYXRlT3V0KzgpLCBjbS5lbEluZm9bZV0ucmVsYXRpdmVCaXRzKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQoKICAgICAgICAgIGlmIChzYnJFbGVtZW50Qml0UmF0ZUluID4gc2JyQml0UmF0ZU91dCkgewogICAgICAgICAgICBhZGp1c3RlZEJpdHJhdGUgPSBmTWluKGluaXRpYWxCaXRyYXRlLCAoSU5UKWZEaXZOb3JtKChGSVhQX0RCTCkoc2JyQml0UmF0ZU91dC04KSwgY20uZWxJbmZvW2VdLnJlbGF0aXZlQml0cykpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KCiAgICAgICAgfSAvKiBzYnJFbGVtZW50Qml0UmF0ZUluICE9IHNickJpdFJhdGVPdXQgKi8KCiAgICAgIH0gLyogZWxlbWVudHMgKi8KCiAgICAgIG51bUl0ZXJhdGlvbnMrKzsgLyogcmVzdHJpY3QgaXRlcmF0aW9uIHRvIHdvcnN0IGNhc2Ugb2YgbnVtIGVsZW1lbnRzICovCgogICAgfSB3aGlsZSAoIChpbml0aWFsQml0cmF0ZSE9YWRqdXN0ZWRCaXRyYXRlKSAmJiAobnVtSXRlcmF0aW9uczw9Y20ubkVsZW1lbnRzKSApOwoKICAgIC8qIFVuZXF1YWwgYml0cmF0ZXMgbWVhbiB0aGF0IG5vIHJlYXNvbmFibGUgYml0cmF0ZSBjb25maWd1cmF0aW9uIGZvdW5kLiAqLwogICAgYml0UmF0ZSA9IChpbml0aWFsQml0cmF0ZT09YWRqdXN0ZWRCaXRyYXRlKSA/IGFkanVzdGVkQml0cmF0ZSA6IDA7CiAgfQoKICBGREtfQVNTRVJUKGJpdFJhdGUgPiAwKTsKCiAgcmV0dXJuIGJpdFJhdGU7Cn0KCi8qCiAqIFxicmllZiBDb25zaXN0ZW5jeSBjaGVjayBvZiBnaXZlbiBVU0VSX1BBUkFNIHN0cnVjdCBhbmQKICogICBjb3B5IGJhY2sgY29uZmlndXJhdGlvbiBmcm9tIHB1YmxpYyBzdHJ1Y3QgaW50byBpbnRlcm5hbAogKiAgIGVuY29kZXIgY29uZmlndXJhdGlvbiBzdHJ1Y3QuCiAqCiAqIFxoQWFjRW5jb2RlciBJbnRlcm5hbCBlbmNvZGVyIGNvbmZpZyB3aGljaCBpcyB0byBiZSB1cGRhdGVkCiAqIFxwYXJhbSBjb25maWcgVXNlciBwcm92aWRlZCBjb25maWcgKHB1YmxpYyBzdHJ1Y3QpCiAqIFxyZXR1cm4gtHJldHVybnMgYWx3YXlzIEFBQ19FTkNfT0sKICovCnN0YXRpYwpBQUNFTkNfRVJST1IgRkRLYWFjRW5jX0FkanVzdEVuY1NldHRpbmdzKEhBTkRMRV9BQUNFTkNPREVSIGhBYWNFbmNvZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVTRVJfUEFSQU0gKmNvbmZpZykKewogICAgQUFDRU5DX0VSUk9SIGVyciA9IEFBQ0VOQ19PSzsKCiAgICAvKiBHZXQgc3RydWN0IHBvaW50ZXJzLiAqLwogICAgSEFORExFX0FBQ0VOQ19DT05GSUcgICAgaEFhY0NvbmZpZyA9ICZoQWFjRW5jb2Rlci0+YWFjQ29uZmlnOwoKICAgIGhBYWNDb25maWctPm5DaGFubmVscyAgICAgICA9IGNvbmZpZy0+bkNoYW5uZWxzOwoKICAgIC8qIEVuY29kZXIgc2V0dGluZ3MgdXBkYXRlLiAqLwogICAgaEFhY0NvbmZpZy0+c2FtcGxlUmF0ZSAgICAgID0gY29uZmlnLT51c2VyU2FtcGxlcmF0ZTsKICAgIGhBYWNDb25maWctPnVzZVRucyAgICAgICAgICA9IGNvbmZpZy0+dXNlclRuczsKICAgIGhBYWNDb25maWctPnVzZVBucyAgICAgICAgICA9IGNvbmZpZy0+dXNlclBuczsKICAgIGhBYWNDb25maWctPnVzZUlTICAgICAgICAgICA9IGNvbmZpZy0+dXNlckludGVuc2l0eTsKICAgIGhBYWNDb25maWctPmJpdFJhdGUgICAgICAgICA9IGNvbmZpZy0+dXNlckJpdHJhdGU7CiAgICBoQWFjQ29uZmlnLT5jaGFubmVsTW9kZSAgICAgPSBjb25maWctPnVzZXJDaGFubmVsTW9kZTsKICAgIGhBYWNDb25maWctPmJpdHJhdGVNb2RlICAgICA9IGNvbmZpZy0+dXNlckJpdHJhdGVNb2RlOwogICAgaEFhY0NvbmZpZy0+YmFuZFdpZHRoICAgICAgID0gY29uZmlnLT51c2VyQmFuZHdpZHRoOwogICAgaEFhY0NvbmZpZy0+dXNlUmVxdWFudCAgICAgID0gY29uZmlnLT51c2VyQWZ0ZXJidXJuZXI7CgogICAgaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlID0gY29uZmlnLT51c2VyQU9UOwogICAgaEFhY0NvbmZpZy0+YW5jX1JhdGUgICAgICAgID0gY29uZmlnLT51c2VyQW5jRGF0YVJhdGU7CiAgICBoQWFjQ29uZmlnLT5zeW50YXhGbGFncyAgICAgPSAwOwogICAgaEFhY0NvbmZpZy0+ZXBDb25maWcgICAgICAgID0gLTE7CgogICAgLyogQWRhcHQgaW50ZXJuYWwgQU9UIHdoZW4gbmVjZXNzYXJ5LiAqLwogICAgc3dpdGNoICggaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlICkgewogICAgICBjYXNlIEFPVF9NUDJfQUFDX0xDOgogICAgICBjYXNlIEFPVF9NUDJfU0JSOgogICAgICBjYXNlIEFPVF9NUDJfUFM6CiAgICAgICAgICBoQWFjQ29uZmlnLT51c2VQbnMgPSAwOwogICAgICBjYXNlIEFPVF9BQUNfTEM6CiAgICAgIGNhc2UgQU9UX1NCUjoKICAgICAgY2FzZSBBT1RfUFM6CiAgICAgICAgICBjb25maWctPnVzZXJUcFR5cGUgPSAoY29uZmlnLT51c2VyVHBUeXBlIT1UVF9VTktOT1dOKSA/IGNvbmZpZy0+dXNlclRwVHlwZSA6IFRUX01QNF9BRFRTOwogICAgICAgICAgaEFhY0NvbmZpZy0+ZnJhbWVsZW5ndGggPSAoY29uZmlnLT51c2VyRnJhbWVsZW5ndGghPShVSU5UKS0xKSA/IGNvbmZpZy0+dXNlckZyYW1lbGVuZ3RoIDogMTAyNDsKICAgICAgICAgIGlmIChoQWFjQ29uZmlnLT5mcmFtZWxlbmd0aCAhPSAxMDI0KSB7CiAgICAgICAgICAgIHJldHVybiBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICB9CiAgICAgICAgICBicmVhazsKICAgICAgY2FzZSBBT1RfRVJfQUFDX0xEOgogICAgICAgICAgaEFhY0NvbmZpZy0+ZXBDb25maWcgPSAwOwogICAgICAgICAgaEFhY0NvbmZpZy0+c3ludGF4RmxhZ3MgfD0gQUNfRVJ8QUNfTEQ7CiAgICAgICAgICBoQWFjQ29uZmlnLT5zeW50YXhGbGFncyB8PSAoKGNvbmZpZy0+dXNlckVyVG9vbHMgJiAweDEpID8gQUNfRVJfVkNCMTEgOiAwKTsKICAgICAgICAgIGhBYWNDb25maWctPnN5bnRheEZsYWdzIHw9ICgoY29uZmlnLT51c2VyRXJUb29scyAmIDB4MikgPyBBQ19FUl9IQ1IgOiAwKTsKICAgICAgICAgIGhBYWNDb25maWctPnN5bnRheEZsYWdzIHw9ICgoY29uZmlnLT51c2VyRXJUb29scyAmIDB4NCkgPyBBQ19FUl9SVkxDIDogMCk7CiAgICAgICAgICBjb25maWctPnVzZXJUcFR5cGUgPSAoY29uZmlnLT51c2VyVHBUeXBlIT1UVF9VTktOT1dOKSA/IGNvbmZpZy0+dXNlclRwVHlwZSA6IFRUX01QNF9MT0FTOwogICAgICAgICAgaEFhY0NvbmZpZy0+ZnJhbWVsZW5ndGggPSAoY29uZmlnLT51c2VyRnJhbWVsZW5ndGghPShVSU5UKS0xKSA/IGNvbmZpZy0+dXNlckZyYW1lbGVuZ3RoIDogNTEyOwogICAgICAgICAgaWYgKGhBYWNDb25maWctPmZyYW1lbGVuZ3RoICE9IDUxMiAmJiBoQWFjQ29uZmlnLT5mcmFtZWxlbmd0aCAhPSA0ODApIHsKICAgICAgICAgICAgcmV0dXJuIEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgIH0KICAgICAgICAgIGJyZWFrOwogICAgICBjYXNlIEFPVF9FUl9BQUNfRUxEOgogICAgICAgICAgaEFhY0NvbmZpZy0+ZXBDb25maWcgPSAwOwogICAgICAgICAgaEFhY0NvbmZpZy0+c3ludGF4RmxhZ3MgfD0gQUNfRVJ8QUNfRUxEOwogICAgICAgICAgaEFhY0NvbmZpZy0+c3ludGF4RmxhZ3MgfD0gKChjb25maWctPnVzZXJFclRvb2xzICYgMHgxKSA/IEFDX0VSX1ZDQjExIDogMCk7CiAgICAgICAgICBoQWFjQ29uZmlnLT5zeW50YXhGbGFncyB8PSAoKGNvbmZpZy0+dXNlckVyVG9vbHMgJiAweDIpID8gQUNfRVJfSENSIDogMCk7CiAgICAgICAgICBoQWFjQ29uZmlnLT5zeW50YXhGbGFncyB8PSAoKGNvbmZpZy0+dXNlckVyVG9vbHMgJiAweDQpID8gQUNfRVJfUlZMQyA6IDApOwogICAgICAgICAgaEFhY0NvbmZpZy0+c3ludGF4RmxhZ3MgfD0gKChjb25maWctPnVzZXJTYnJFbmFibGVkPT0xKSAgPyBBQ19TQlJfUFJFU0VOVCA6IDApOwogICAgICAgICAgY29uZmlnLT51c2VyVHBUeXBlID0gKGNvbmZpZy0+dXNlclRwVHlwZSE9VFRfVU5LTk9XTikgPyBjb25maWctPnVzZXJUcFR5cGUgOiBUVF9NUDRfTE9BUzsKICAgICAgICAgIGhBYWNDb25maWctPmZyYW1lbGVuZ3RoID0gKGNvbmZpZy0+dXNlckZyYW1lbGVuZ3RoIT0oVUlOVCktMSkgPyBjb25maWctPnVzZXJGcmFtZWxlbmd0aCA6IDUxMjsKICAgICAgICAgIGlmIChoQWFjQ29uZmlnLT5mcmFtZWxlbmd0aCAhPSA1MTIgJiYgaEFhY0NvbmZpZy0+ZnJhbWVsZW5ndGggIT0gNDgwKSB7CiAgICAgICAgICAgIHJldHVybiBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICB9CiAgICAgICAgICBicmVhazsKICAgICAgZGVmYXVsdDoKICAgICAgICAgIGJyZWFrOwogICAgfQoKICAgIHN3aXRjaCAoIGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZSApIHsKICAgICAgY2FzZSBBT1RfRVJfQUFDX0xEOgogICAgICBjYXNlIEFPVF9FUl9BQUNfRUxEOgogICAgICAgIGlmIChjb25maWctPnVzZXJCaXRyYXRlTW9kZT09OCkgewogICAgICAgICAgaEFhY0NvbmZpZy0+Yml0cmF0ZU1vZGUgPSAwOwogICAgICAgIH0KICAgICAgICBpZiAoY29uZmlnLT51c2VyQml0cmF0ZU1vZGU9PTApIHsKICAgICAgICAgIGhBYWNDb25maWctPmJpdHJlc2Vydm9pciA9IDEwMCpjb25maWctPm5DaGFubmVsczsgLyogZGVmYXVsdCwgcmVkdWNlZCBiaXRyZXNlcnZvaXIgKi8KICAgICAgICB9CiAgICAgICAgaWYgKGhBYWNDb25maWctPmJpdHJhdGVNb2RlIT0wKSB7CiAgICAgICAgICByZXR1cm4gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgZGVmYXVsdDoKICAgICAgICBicmVhazsKICAgIH0KCiAgICBoQWFjQ29uZmlnLT5iaXRSYXRlID0gY29uZmlnLT51c2VyQml0cmF0ZTsKCiAgICAvKiBnZXQgYml0cmF0ZSBpbiBWQlIgY29uZmlndXJhdGlvbiAqLwogICAgaWYgKCAoaEFhY0NvbmZpZy0+Yml0cmF0ZU1vZGU+PTEpICYmIChoQWFjQ29uZmlnLT5iaXRyYXRlTW9kZTw9NSkgKSB7CiAgICAgICAgLyogSW4gVkJSIG1vZGU7IFNCUi1tb2R1bCBkZXBlbmRzIG9uIGJpdHJhdGUsIGNvcmUgZW5jb2RlciBvbiBiaXRyYXRlTW9kZS4gKi8KICAgICAgICBoQWFjQ29uZmlnLT5iaXRSYXRlID0gRkRLYWFjRW5jX0dldFZCUkJpdHJhdGUoaEFhY0NvbmZpZy0+Yml0cmF0ZU1vZGUsIGhBYWNDb25maWctPmNoYW5uZWxNb2RlKTsKICAgIH0KCgoKICAgIC8qIFNldCBkZWZhdWx0IGJpdHJhdGUgaWYgbm8gZXh0ZXJuYWwgYml0cmF0ZSBkZWNsYXJlZC4gKi8KICAgIGlmICggKGhBYWNDb25maWctPmJpdHJhdGVNb2RlPT0wKSAmJiAoY29uZmlnLT51c2VyQml0cmF0ZT09KFVJTlQpLTEpICkgewogICAgICAgIElOVCBiaXRyYXRlID0gRkRLYWFjRW5jX0dldENoYW5uZWxNb2RlQ29uZmlndXJhdGlvbihoQWFjQ29uZmlnLT5jaGFubmVsTW9kZSktPm5DaGFubmVsc0VmZiAqIGhBYWNDb25maWctPnNhbXBsZVJhdGU7CgogICAgICAgIGlmICggaXNQc0FjdGl2ZShoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGUpICkgewogICAgICAgICAgaEFhY0NvbmZpZy0+Yml0UmF0ZSA9IChiaXRyYXRlPj4xKTsgICAgICAgICAgICAgICAgICAvKiAwLjUgYml0IHBlciBzYW1wbGUgKi8KICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoIGlzU2JyQWN0aXZlKGhBYWNDb25maWcpICkKICAgICAgICB7CiAgICAgICAgICBpZiAoIChjb25maWctPnVzZXJTYnJSYXRpbz09MikgfHwgKChjb25maWctPnVzZXJTYnJSYXRpbz09MCkmJihoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGUhPUFPVF9FUl9BQUNfRUxEKSkgKSB7CiAgICAgICAgICAgIGhBYWNDb25maWctPmJpdFJhdGUgPSAoYml0cmF0ZSArIChiaXRyYXRlPj4yKSk+PjE7IC8qIDAuNjI1IGJpdHMgcGVyIHNhbXBsZSAqLwogICAgICAgICAgfQogICAgICAgICAgaWYgKCAoY29uZmlnLT51c2VyU2JyUmF0aW89PTEpIHx8ICgoY29uZmlnLT51c2VyU2JyUmF0aW89PTApJiYoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlPT1BT1RfRVJfQUFDX0VMRCkpICkgewogICAgICAgICAgICBoQWFjQ29uZmlnLT5iaXRSYXRlID0gKGJpdHJhdGUgKyAoYml0cmF0ZT4+MykpOyAgICAvKiAxLjEyNSBiaXRzIHBlciBzYW1wbGUgKi8KICAgICAgICAgIH0KICAgICAgICB9IGVsc2UKICAgICAgICB7CiAgICAgICAgICAgICAgICBoQWFjQ29uZmlnLT5iaXRSYXRlID0gYml0cmF0ZSArIChiaXRyYXRlPj4xKTsgICAgICAgIC8qIDEuNSBiaXRzIHBlciBzYW1wbGUgKi8KICAgICAgICB9CiAgICB9CgogICAgLyogSW5pdGlhbGl6ZSBTQlIgcGFyYW1ldGVycyAqLwogICAgaWYgKCAoY29uZmlnLT51c2VyU2JyUmF0aW89PTApICYmIChpc1NickFjdGl2ZShoQWFjQ29uZmlnKSkgKSB7CiAgICAgIC8qIEF1dG9tYXRpYyBTQlIgcmF0aW8gY29uZmlndXJhdGlvbgogICAgICAgKiAtIGRvd25zYW1wbGVkIFNCUiBmb3IgRUxECiAgICAgICAqIC0gb3RoZXJ3aXNlIGFsd2F5cyBkdWFscmF0ZSBTQlIKICAgICAgICovCiAgICAgICAgaEFhY0NvbmZpZy0+c2JyUmF0aW8gPSAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlPT1BT1RfRVJfQUFDX0VMRCkgPyAxIDogMjsKICAgIH0KICAgIGVsc2UgewogICAgICAvKiBTQlIgcmF0aW8gaGFzIGJlZW4gc2V0IGJ5IHRoZSB1c2VyLCBzbyB1c2UgaXQuICovCiAgICAgIGhBYWNDb25maWctPnNiclJhdGlvID0gY29uZmlnLT51c2VyU2JyUmF0aW87CiAgICB9CgogICAgewogICAgICBVQ0hBUiB0cFNpZ25hbGluZz1nZXRTYnJTaWduYWxpbmdNb2RlKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZSwgY29uZmlnLT51c2VyVHBUeXBlLCBjb25maWctPnVzZXJUcFNpZ25hbGluZywgaEFhY0NvbmZpZy0+c2JyUmF0aW8pOwoKICAgICAgaWYgKCAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlPT1BT1RfQUFDX0xDIHx8IGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZT09QU9UX1NCUiB8fCBoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGU9PUFPVF9QUykgJiYKICAgICAgICAgICAoY29uZmlnLT51c2VyVHBUeXBlPT1UVF9NUDRfTEFUTV9NQ1AxIHx8IGNvbmZpZy0+dXNlclRwVHlwZT09VFRfTVA0X0xBVE1fTUNQMCB8fCBjb25maWctPnVzZXJUcFR5cGU9PVRUX01QNF9MT0FTKSAmJgogICAgICAgICAgICh0cFNpZ25hbGluZz09MSkgJiYgKGNvbmZpZy0+dXNlclRwQW14dj09MCkgKSB7CiAgICAgICAgICAgICAvKiBGb3IgYmFja3dhcmQgY29tcGF0aWJsZSBleHBsaWNpdCBzaWduYWxpbmcsIEFNVjEgaGFzIHRvIGJlIGFjdGl2ZSAqLwogICAgICAgICAgICAgcmV0dXJuIEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgfQoKICAgICAgaWYgKCAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlPT1BT1RfQUFDX0xDIHx8IGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZT09QU9UX1NCUiB8fCBoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGU9PUFPVF9QUykgJiYKICAgICAgICAgICAodHBTaWduYWxpbmc9PTApICYmIChoQWFjQ29uZmlnLT5zYnJSYXRpbz09MSkpIHsKICAgICAgICAgICAgIC8qIERvd25zYW1wbGVkIFNCUiBoYXMgdG8gYmUgc2lnbmFsZWQgZXhwbGljaXRlbHkgKGZvciB0cmFuc21pc3Npb24gb2YgU0JSIHNhbXBsaW5nIGZlcXVlbmN5KSAqLwogICAgICAgICAgICAgcmV0dXJuIEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgfQogICAgfQoKCgogICAgLyogV2UgbmVlZCB0aGUgZnJhbWUgbGVuZ3RoIHRvIGNhbGwgYWFjRW5jb2Rlcl9MaW1pdEJpdHJhdGUoKSAqLwogICAgaEFhY0NvbmZpZy0+Yml0UmF0ZSA9IGFhY0VuY29kZXJfTGltaXRCaXRyYXRlKAogICAgICAgICAgICAgIE5VTEwsCiAgICAgICAgICAgICAgaEFhY0NvbmZpZy0+c2FtcGxlUmF0ZSwKICAgICAgICAgICAgICBoQWFjQ29uZmlnLT5mcmFtZWxlbmd0aCwKICAgICAgICAgICAgICBoQWFjQ29uZmlnLT5uQ2hhbm5lbHMsCiAgICAgICAgICAgICAgaEFhY0NvbmZpZy0+Y2hhbm5lbE1vZGUsCiAgICAgICAgICAgICAgaEFhY0NvbmZpZy0+Yml0UmF0ZSwKICAgICAgICAgICAgICBoQWFjQ29uZmlnLT5uU3ViRnJhbWVzLAogICAgICAgICAgICAgIGlzU2JyQWN0aXZlKGhBYWNDb25maWcpLAogICAgICAgICAgICAgIGhBYWNDb25maWctPnNiclJhdGlvLAogICAgICAgICAgICAgIGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZQogICAgICAgICAgICAgICk7CgogICAgLyogQ29uZmlndXJlIFBOUyAqLwogICAgaWYgKCAoKGhBYWNDb25maWctPmJpdHJhdGVNb2RlPj0xKSAmJiAoaEFhY0NvbmZpZy0+Yml0cmF0ZU1vZGU8PTUpKSAvKiBWQlIgd2l0aG91dCBQTlMuICovCiAgICAgICAgfHwgKGhBYWNDb25maWctPnVzZVRucyA9PSAwKSApICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIFROUyByZXF1aXJlZC4gKi8KICAgIHsKICAgICAgICBoQWFjQ29uZmlnLT51c2VQbnMgPSAwOwogICAgfQoKICAgIGlmIChoQWFjQ29uZmlnLT5lcENvbmZpZyA+PSAwKSB7CiAgICAgICAgaEFhY0NvbmZpZy0+c3ludGF4RmxhZ3MgfD0gQUNfRVI7CiAgICAgICAgIGlmICgoKElOVCloQWFjQ29uZmlnLT5jaGFubmVsTW9kZSA8IDEpIHx8ICgoSU5UKWhBYWNDb25maWctPmNoYW5uZWxNb2RlID4gNykpIHsKICAgICAgICAgICByZXR1cm4gQUFDRU5DX0lOVkFMSURfQ09ORklHOyAgICAgICAgLyogQ2FubmVsIGNvbmZpZyAwIG5vdCBzdXBwb3J0ZWQuICovCiAgICAgICAgIH0KICAgIH0KCiAgICBpZiAoIEZES2FhY0VuY19EZXRlcm1pbmVFbmNvZGVyTW9kZSgmaEFhY0NvbmZpZy0+Y2hhbm5lbE1vZGUsIGhBYWNDb25maWctPm5DaGFubmVscykgIT0gQUFDX0VOQ19PSykgewogICAgICAgIHJldHVybiBBQUNFTkNfSU5WQUxJRF9DT05GSUc7ICAgICAgICAvKiBuQ2hhbm5lbHMgZG9lc24ndCBtYXRjaCBjaE1vZGUsIHRoaXMgaXMganVzdCBhIGNoZWNrLXVwICovCiAgICB9CgogICAgaWYgKCAoaEFhY0NvbmZpZy0+bkNoYW5uZWxzID4gaEFhY0VuY29kZXItPm5NYXhBYWNDaGFubmVscykKICAgICAgfHwgKCAoRkRLYWFjRW5jX0dldENoYW5uZWxNb2RlQ29uZmlndXJhdGlvbihoQWFjQ29uZmlnLT5jaGFubmVsTW9kZSktPm5DaGFubmVsc0VmZiA+IGhBYWNFbmNvZGVyLT5uTWF4U2JyQ2hhbm5lbHMpICYmCiAgICAgICAgICAgIGlzU2JyQWN0aXZlKGhBYWNDb25maWcpICkKICAgICAgICAgKQogICAgewogICAgICAgIHJldHVybiBBQUNFTkNfSU5WQUxJRF9DT05GSUc7ICAgICAgLyogbm90IGVub3VnaCBjaGFubmVscyBhbGxvY2F0ZWQgKi8KICAgIH0KCiAgICAvKiBNZXRhIGRhdGEgcmVzdHJpY3Rpb24uICovCiAgICBzd2l0Y2ggKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZSkKICAgIHsKICAgICAgLyogQWxsb3cgbWV0YWRhdGEgc3VwcG9ydCAqLwogICAgICBjYXNlIEFPVF9BQUNfTEM6CiAgICAgIGNhc2UgQU9UX1NCUjoKICAgICAgY2FzZSBBT1RfUFM6CiAgICAgICAgaEFhY0VuY29kZXItPm1ldGFEYXRhQWxsb3dlZCA9IDE7CiAgICAgICAgaWYgKCgoSU5UKWhBYWNDb25maWctPmNoYW5uZWxNb2RlIDwgMSkgfHwgKChJTlQpaEFhY0NvbmZpZy0+Y2hhbm5lbE1vZGUgPiA3KSkgewogICAgICAgICAgY29uZmlnLT51c2VyTWV0YURhdGFNb2RlID0gMDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIC8qIFByb2hpYml0IG1ldGFkYXRhIHN1cHBvcnQgKi8KICAgICAgZGVmYXVsdDoKICAgICAgICBoQWFjRW5jb2Rlci0+bWV0YURhdGFBbGxvd2VkID0gMDsKICAgIH0KCiAgICByZXR1cm4gZXJyOwp9CgpzdGF0aWMKSU5UIGFhY2VuY19TYnJDYWxsYmFjaygKICAgICAgICB2b2lkICogICAgICAgICAgICAgICAgICBzZWxmLAogICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNICAgIGhCcywKICAgICAgICBjb25zdCBJTlQgc2FtcGxlUmF0ZUluLAogICAgICAgIGNvbnN0IElOVCBzYW1wbGVSYXRlT3V0LAogICAgICAgIGNvbnN0IElOVCBzYW1wbGVzUGVyRnJhbWUsCiAgICAgICAgY29uc3QgQVVESU9fT0JKRUNUX1RZUEUgY29yZUNvZGVjLAogICAgICAgIGNvbnN0IE1QNF9FTEVNRU5UX0lEICAgIGVsZW1lbnRJRCwKICAgICAgICBjb25zdCBJTlQgICAgICAgICAgICAgICBlbGVtZW50SW5kZXgKICAgICAgICApCnsKICBIQU5ETEVfQUFDRU5DT0RFUiBoQWFjRW5jb2RlciA9IChIQU5ETEVfQUFDRU5DT0RFUilzZWxmOwoKICBzYnJFbmNvZGVyX0dldEhlYWRlcihoQWFjRW5jb2Rlci0+aEVudkVuYywgaEJzLCBlbGVtZW50SW5kZXgsIDApOwoKICByZXR1cm4gMDsKfQoKc3RhdGljIEFBQ0VOQ19FUlJPUiBhYWNFbmNJbml0KEhBTkRMRV9BQUNFTkNPREVSICBoQWFjRW5jb2RlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HICAgICAgICAgICAgICBJbml0RmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVU0VSX1BBUkFNICAgICAgICAqY29uZmlnKQp7CiAgICBBQUNFTkNfRVJST1IgZXJyID0gQUFDRU5DX09LOwoKICAgIElOVCBhYWNCdWZmZXJPZmZzZXQgPSAwOwogICAgSEFORExFX1NCUl9FTkNPREVSICAgICAqaFNickVuY29kZXIgPSAmaEFhY0VuY29kZXItPmhFbnZFbmM7CiAgICBIQU5ETEVfQUFDRU5DX0NPTkZJRyAgICBoQWFjQ29uZmlnICA9ICZoQWFjRW5jb2Rlci0+YWFjQ29uZmlnOwoKICAgIGhBYWNFbmNvZGVyLT5uWmVyb3NBcHBlbmRlZCA9IDA7ICAgICAgICAgIC8qIGNvdW50IGFwcGVuZGVkIHplcm9zICovCgogICAgSU5UIGZyYW1lTGVuZ3RoID0gaEFhY0NvbmZpZy0+ZnJhbWVsZW5ndGg7CgogICAgaWYgKCAoSW5pdEZsYWdzICYgQUFDRU5DX0lOSVRfQ09ORklHKSApCiAgICB7CiAgICAgICAgQ0hBTk5FTF9NT0RFIHByZXZDaE1vZGUgPSBoQWFjQ29uZmlnLT5jaGFubmVsTW9kZTsKCiAgICAgICAgLyogVmVyaWZ5IHNldHRpbmdzIGFuZCB1cGRhdGU6IGNvbmZpZyAtPiBoZUFhY0VuY29kZXIgKi8KICAgICAgICBpZiAoIChlcnI9RkRLYWFjRW5jX0FkanVzdEVuY1NldHRpbmdzKGhBYWNFbmNvZGVyLCBjb25maWcpKSAhPSBBQUNFTkNfT0sgKSB7CiAgICAgICAgICAgIHJldHVybiBlcnI7CiAgICAgICAgfQogICAgICAgIGZyYW1lTGVuZ3RoID0gaEFhY0NvbmZpZy0+ZnJhbWVsZW5ndGg7IC8qIGFkYXB0IHRlbXBvcmFsIGZyYW1lbGVuZ3RoICovCgogICAgICAgIC8qIFNlYW1sZXNzIGNoYW5uZWwgcmVjb25maWd1cmF0aW9uIGluIHNiciBub3QgZnVsbHkgaW1wbGVtZW50ZWQgKi8KICAgICAgICBpZiAoIChwcmV2Q2hNb2RlIT1oQWFjQ29uZmlnLT5jaGFubmVsTW9kZSkgJiYgaXNTYnJBY3RpdmUoaEFhY0NvbmZpZykgKSB7CiAgICAgICAgICAgIEluaXRGbGFncyB8PSBBQUNFTkNfSU5JVF9TVEFURVM7CiAgICAgICAgfQogICAgfQoKICAgIC8qIENsZWFyIGlucHV0IGJ1ZmZlciAqLwogICAgaWYgKCAoSW5pdEZsYWdzID09IEFBQ0VOQ19JTklUX0FMTCkgKSB7CiAgICAgICAgRkRLbWVtY2xlYXIoaEFhY0VuY29kZXItPmlucHV0QnVmZmVyLCBzaXplb2YoSU5UX1BDTSkqaEFhY0VuY29kZXItPm5NYXhBYWNDaGFubmVscypJTlBVVEJVRkZFUl9TSVpFKTsKICAgIH0KCiAgICBpZiAoIChJbml0RmxhZ3MgJiBBQUNFTkNfSU5JVF9DT05GSUcpICkKICAgIHsKICAgICAgICBhYWNCdWZmZXJPZmZzZXQgPSAwOwogICAgICAgIGlmIChoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGUgPT0gQU9UX0VSX0FBQ19FTEQpIHsKICAgICAgICAgICAgaEFhY0VuY29kZXItPm5EZWxheSA9IERFTEFZX0FBQ0VMRChoQWFjQ29uZmlnLT5mcmFtZWxlbmd0aCk7CiAgICAgICAgfSBlbHNlCiAgICAgICAgewogICAgICAgICAgICBoQWFjRW5jb2Rlci0+bkRlbGF5ID0gREVMQVlfQUFDKGhBYWNDb25maWctPmZyYW1lbGVuZ3RoKTsgLyogQUFDIGVuY29kZXIgZGVsYXkgKi8KICAgICAgICB9CiAgICAgICAgaEFhY0NvbmZpZy0+YW5jRGF0YUJpdFJhdGUgPSAwOwogICAgfQoKICAgIGlmICggaXNTYnJBY3RpdmUoaEFhY0NvbmZpZykgJiYKICAgICAgICAoKEluaXRGbGFncyAmIEFBQ0VOQ19JTklUX0NPTkZJRykgfHwgKEluaXRGbGFncyAmIEFBQ0VOQ19JTklUX1NUQVRFUykpICkKICAgIHsKICAgICAgICBJTlQgc2JyRXJyb3I7CiAgICAgICAgU0JSX0VMRU1FTlRfSU5GTyBzYnJFbEluZm9bKDYpXTsKICAgICAgICBDSEFOTkVMX01BUFBJTkcgY2hhbm5lbE1hcHBpbmc7CgogICAgICAgIGlmICggRkRLYWFjRW5jX0luaXRDaGFubmVsTWFwcGluZyhoQWFjQ29uZmlnLT5jaGFubmVsTW9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0NvbmZpZy0+Y2hhbm5lbE9yZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjaGFubmVsTWFwcGluZykgIT0gQUFDX0VOQ19PSyApCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gQUFDRU5DX0lOSVRfRVJST1I7CiAgICAgICAgfQoKICAgICAgICAvKiBDaGVjayByZXR1cm4gdmFsdWUgYW5kIGlmIHRoZSBTQlIgZW5jb2RlciBjYW4gaGFuZGxlIGVub3VnaCBlbGVtZW50cyAqLwogICAgICAgIGlmIChjaGFubmVsTWFwcGluZy5uRWxlbWVudHMgPiAoNikpIHsKICAgICAgICAgICAgcmV0dXJuIEFBQ0VOQ19JTklUX0VSUk9SOwogICAgICAgIH0KCiAgICAgICAgYWFjRW5jRGlzdHJpYnV0ZVNickJpdHMoJmNoYW5uZWxNYXBwaW5nLCBzYnJFbEluZm8sIGhBYWNDb25maWctPmJpdFJhdGUpOwoKICAgICAgICBVSU5UIGluaXRGbGFnID0gMDsKICAgICAgICBpbml0RmxhZyArPSAoSW5pdEZsYWdzICYgQUFDRU5DX0lOSVRfU1RBVEVTKSA/IDEgOiAwOwoKICAgICAgICAvKiBMZXQgdGhlIFNCUiBlbmNvZGVyIHRha2UgYSBsb29rIGF0IHRoZSBjb25maWd1cmF0aW9uIGFuZCBjaGFuZ2UgaWYgcmVxdWlyZWQuICovCiAgICAgICAgc2JyRXJyb3IgPSBzYnJFbmNvZGVyX0luaXQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKmhTYnJFbmNvZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYnJFbEluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxNYXBwaW5nLm5FbGVtZW50cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPmlucHV0QnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZoQWFjQ29uZmlnLT5iYW5kV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmFhY0J1ZmZlck9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmaEFhY0NvbmZpZy0+bkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZoQWFjQ29uZmlnLT5zYW1wbGVSYXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZoQWFjQ29uZmlnLT5zYnJSYXRpbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZnJhbWVMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmaEFhY0VuY29kZXItPm5EZWxheSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZSA9PSBBT1RfRVJfQUFDX0VMRCkgPyAxIDogVFJBTlNfRkFDLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29uZmlnLT51c2VyVHBIZWFkZXJQZXJpb2QhPTB4RkYpID8gY29uZmlnLT51c2VyVHBIZWFkZXJQZXJpb2QgOiBERUZBVUxUX0hFQURFUl9QRVJJT0RfUkVQRVRJVElPTl9SQVRFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbml0RmxhZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7CgogICAgICAgIC8qIFN1cHByZXNzIEFPVCByZWNvbmZpZ3VyYXRpb24gYW5kIGNoZWNrIGVycm9yIHN0YXR1cy4gKi8KICAgICAgICBpZiAoc2JyRXJyb3IpIHsKICAgICAgICAgICAgcmV0dXJuIEFBQ0VOQ19JTklUX1NCUl9FUlJPUjsKICAgICAgICB9CgogICAgICAgIGlmIChoQWFjQ29uZmlnLT5uQ2hhbm5lbHMgPT0gMSkgewogICAgICAgICAgICBoQWFjQ29uZmlnLT5jaGFubmVsTW9kZSA9IE1PREVfMTsKICAgICAgICB9CgogICAgICAgIC8qIE5ldmVyIHVzZSBQTlMgaWYgU0JSIGlzIGFjdGl2ZSAqLwogICAgICAgIGlmICggaEFhY0NvbmZpZy0+dXNlUG5zICkgewogICAgICAgICAgIGhBYWNDb25maWctPnVzZVBucyA9IDA7CiAgICAgICAgfQoKICAgICAgICAvKiBlc3RpbWF0ZWQgYml0cmF0ZSBjb25zdW1lZCBieSBTQlIgb3IgUFMgKi8KICAgICAgICBoQWFjQ29uZmlnLT5hbmNEYXRhQml0UmF0ZSA9IHNickVuY29kZXJfR2V0RXN0aW1hdGVCaXRyYXRlKCpoU2JyRW5jb2RlcikgOwoKICAgIH0gLyogc2JyIGluaXRpYWxpemF0aW9uICovCgoKICAgIC8qCiAgICAgKiBJbml0aWFsaXplIFRyYW5zcG9ydCAtIE1vZHVsZS4KICAgICAqLwogICAgaWYgKCAoSW5pdEZsYWdzICYgQUFDRU5DX0lOSVRfVFJBTlNQT1JUKSApCiAgICB7CiAgICAgICAgVUlOVCBmbGFncyA9IDA7CgogICAgICAgIEZES2FhY0VuY19NYXBDb25maWcoCiAgICAgICAgICAgICAgICAmaEFhY0VuY29kZXItPmNvZGVyQ29uZmlnLAogICAgICAgICAgICAgICAgY29uZmlnLAogICAgICAgICAgICAgICAgZ2V0U2JyU2lnbmFsaW5nTW9kZShoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGUsIGNvbmZpZy0+dXNlclRwVHlwZSwgY29uZmlnLT51c2VyVHBTaWduYWxpbmcsIGhBYWNDb25maWctPnNiclJhdGlvKSwKICAgICAgICAgICAgICAgIGhBYWNDb25maWcpOwoKICAgICAgICAvKiBjcmVhdGUgZmxhZ3MgZm9yIHRyYW5zcG9ydCBlbmNvZGVyICovCiAgICAgICAgaWYgKGNvbmZpZy0+dXNlclRwQW14diA9PSAxKSB7CiAgICAgICAgICAgIGZsYWdzIHw9IFRQX0ZMQUdfTEFUTV9BTVY7CiAgICAgICAgfQogICAgICAgIC8qIENsZWFyIG91dHB1dCBidWZmZXIgKi8KICAgICAgICBGREttZW1jbGVhcihoQWFjRW5jb2Rlci0+b3V0QnVmZmVyLCBoQWFjRW5jb2Rlci0+b3V0QnVmZmVySW5CeXRlcypzaXplb2YoVUNIQVIpKTsKCiAgICAgICAgLyogSW5pdGlhbGl6ZSBCaXRzdHJlYW0gZW5jb2RlciAqLwogICAgICAgIGlmICggdHJhbnNwb3J0RW5jX0luaXQoaEFhY0VuY29kZXItPmhUcEVuYywgaEFhY0VuY29kZXItPm91dEJ1ZmZlciwgaEFhY0VuY29kZXItPm91dEJ1ZmZlckluQnl0ZXMsIGNvbmZpZy0+dXNlclRwVHlwZSwgJmhBYWNFbmNvZGVyLT5jb2RlckNvbmZpZywgZmxhZ3MpICE9IDApIHsKICAgICAgICAgICAgcmV0dXJuIEFBQ0VOQ19JTklUX1RQX0VSUk9SOwogICAgICAgIH0KCiAgICB9IC8qIHRyYW5zcG9ydCBpbml0aWFsaXphdGlvbiAqLwoKICAgIC8qCiAgICAgKiBJbml0aWFsaXplIEFBQyAtIENvcmUuCiAgICAgKi8KICAgIGlmICggKEluaXRGbGFncyAmIEFBQ0VOQ19JTklUX0NPTkZJRykgfHwKICAgICAgICAgKEluaXRGbGFncyAmIEFBQ0VOQ19JTklUX1NUQVRFUykgKQogICAgewogICAgICAgIEFBQ19FTkNPREVSX0VSUk9SIGVycjsKICAgICAgICBlcnIgPSBGREthYWNFbmNfSW5pdGlhbGl6ZShoQWFjRW5jb2Rlci0+aEFhY0VuYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjQ29uZmlnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5oVHBFbmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEluaXRGbGFncyAmIEFBQ0VOQ19JTklUX1NUQVRFUykgPyAxIDogMCk7CgogICAgICAgIGlmIChlcnIgIT0gQUFDX0VOQ19PSykgewogICAgICAgICAgICByZXR1cm4gQUFDRU5DX0lOSVRfQUFDX0VSUk9SOwogICAgICAgIH0KCiAgICB9IC8qIGFhYyBpbml0aWFsaXphdGlvbiAqLwoKICAgIC8qCiAgICAgKiBJbml0aWFsaXplIE1ldGEgRGF0YSAtIEVuY29kZXIuCiAgICAgKi8KICAgIGlmICggaEFhY0VuY29kZXItPmhNZXRhZGF0YUVuYyAmJiAoaEFhY0VuY29kZXItPm1ldGFEYXRhQWxsb3dlZCE9MCkgJiYKICAgICAgICAoKEluaXRGbGFncyAmIEFBQ0VOQ19JTklUX0NPTkZJRykgfHwoSW5pdEZsYWdzICYgQUFDRU5DX0lOSVRfU1RBVEVTKSkgKQogICAgewogICAgICAgIElOVCBpbnB1dERhdGFEZWxheSA9IERFTEFZX0FBQyhoQWFjQ29uZmlnLT5mcmFtZWxlbmd0aCk7CgogICAgICAgIGlmICggaXNTYnJBY3RpdmUoaEFhY0NvbmZpZykgJiYgaFNickVuY29kZXIhPU5VTEwpIHsKICAgICAgICAgIGlucHV0RGF0YURlbGF5ID0gaEFhY0NvbmZpZy0+c2JyUmF0aW8qaW5wdXREYXRhRGVsYXkgKyBzYnJFbmNvZGVyX0dldElucHV0RGF0YURlbGF5KCpoU2JyRW5jb2Rlcik7CiAgICAgICAgfQoKICAgICAgICBpZiAoIEZES19NZXRhZGF0YUVuY19Jbml0KGhBYWNFbmNvZGVyLT5oTWV0YWRhdGFFbmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoSW5pdEZsYWdzJkFBQ0VOQ19JTklUX1NUQVRFUykgPyAxIDogMCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWctPnVzZXJNZXRhRGF0YU1vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dERhdGFEZWxheSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyYW1lTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnLT51c2VyU2FtcGxlcmF0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZy0+bkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnLT51c2VyQ2hhbm5lbE1vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjQ29uZmlnLT5jaGFubmVsT3JkZXIpICE9IDApCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gQUFDRU5DX0lOSVRfTUVUQV9FUlJPUjsKICAgICAgICB9CgogICAgICAgIGhBYWNFbmNvZGVyLT5uRGVsYXkgKz0gRkRLX01ldGFkYXRhRW5jX0dldERlbGF5KGhBYWNFbmNvZGVyLT5oTWV0YWRhdGFFbmMpOwogICAgfQoKICAgIC8qCiAgICAgKiBVcGRhdGUgcG9pbnRlciB0byB3b3JraW5nIGJ1ZmZlci4KICAgICAqLwogICAgaWYgKCAoSW5pdEZsYWdzICYgQUFDRU5DX0lOSVRfQ09ORklHKSApCiAgICB7CiAgICAgICAgaEFhY0VuY29kZXItPmlucHV0QnVmZmVyT2Zmc2V0ID0gYWFjQnVmZmVyT2Zmc2V0OwoKICAgICAgICBoQWFjRW5jb2Rlci0+blNhbXBsZXNUb1JlYWQgPSBmcmFtZUxlbmd0aCAqIGNvbmZpZy0+bkNoYW5uZWxzOwoKICAgICAgICAvKiBNYWtlIG5EZWxheSBjb21wYXJpc29uIGNvbXBhdGlibGUgd2l0aCBjb25maWctPm5TYW1wbGVzUmVhZCAqLwogICAgICAgIGhBYWNFbmNvZGVyLT5uRGVsYXkgKj0gY29uZmlnLT5uQ2hhbm5lbHM7CgogICAgfSAvKiBwYXJhbWV0ZXIgY2hhbmdlZCAqLwoKICAgIHJldHVybiBBQUNFTkNfT0s7Cn0KCgpBQUNFTkNfRVJST1IgYWFjRW5jT3BlbigKICAgICAgICBIQU5ETEVfQUFDRU5DT0RFUiAgICAgICAgKnBoQWFjRW5jb2RlciwKICAgICAgICBjb25zdCBVSU5UICAgICAgICAgICAgICAgIGVuY01vZHVsZXMsCiAgICAgICAgY29uc3QgVUlOVCAgICAgICAgICAgICAgICBtYXhDaGFubmVscwogICAgICAgICkKewogICAgQUFDRU5DX0VSUk9SIGVyciA9IEFBQ0VOQ19PSzsKICAgIEhBTkRMRV9BQUNFTkNPREVSICBoQWFjRW5jb2RlciA9IE5VTEw7CgogICAgaWYgKHBoQWFjRW5jb2RlciA9PSBOVUxMKSB7CiAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfSEFORExFOwogICAgICAgIGdvdG8gYmFpbDsKICAgIH0KCiAgICAvKiBhbGxvY2F0ZSBtZW1vcnkgKi8KICAgIGhBYWNFbmNvZGVyID0gR2V0X0FhY0VuY29kZXIoKTsKCiAgICBpZiAoaEFhY0VuY29kZXIgPT0gTlVMTCkgewogICAgICAgIGVyciA9IEFBQ0VOQ19NRU1PUllfRVJST1I7CiAgICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIEZES21lbWNsZWFyKGhBYWNFbmNvZGVyLCBzaXplb2YoQUFDRU5DT0RFUikpOwoKICAgIC8qIFNwZWNpZnkgZW5jb2RlciBtb2R1bGVzIHRvIGJlIGFsbG9jYXRlZC4gKi8KICAgIGlmIChlbmNNb2R1bGVzPT0wKSB7CiAgICAgICAgaEFhY0VuY29kZXItPmVuY29kZXJfbW9kaXMgPSBFTkNfTU9ERV9GTEFHX0FBQzsKICAgICAgICBoQWFjRW5jb2Rlci0+ZW5jb2Rlcl9tb2RpcyB8PSBFTkNfTU9ERV9GTEFHX1NCUjsKICAgICAgICBoQWFjRW5jb2Rlci0+ZW5jb2Rlcl9tb2RpcyB8PSBFTkNfTU9ERV9GTEFHX1BTOwogICAgICAgIGhBYWNFbmNvZGVyLT5lbmNvZGVyX21vZGlzIHw9IEVOQ19NT0RFX0ZMQUdfTUVUQTsKICAgIH0KICAgIGVsc2UgewogICAgICAgLyogY29uc2lkZXIgU0FDIGFuZCBQUyBtb2R1bGUgKi8KICAgICAgICBoQWFjRW5jb2Rlci0+ZW5jb2Rlcl9tb2RpcyA9IGVuY01vZHVsZXM7CiAgICB9CgogICAgLyogRGV0ZXJtaW5lIG1heCBjaGFubmVsIGNvbmZpZ3VyYXRpb24uICovCiAgICBpZiAobWF4Q2hhbm5lbHM9PTApIHsKICAgICAgICBoQWFjRW5jb2Rlci0+bk1heEFhY0NoYW5uZWxzID0gKDYpOwogICAgICAgIGhBYWNFbmNvZGVyLT5uTWF4U2JyQ2hhbm5lbHMgPSAoNik7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBoQWFjRW5jb2Rlci0+bk1heEFhY0NoYW5uZWxzID0gKG1heENoYW5uZWxzJjB4MDBGRik7CiAgICAgICAgaWYgKCAoaEFhY0VuY29kZXItPmVuY29kZXJfbW9kaXMmRU5DX01PREVfRkxBR19TQlIpICkgewogICAgICAgICAgICBoQWFjRW5jb2Rlci0+bk1heFNickNoYW5uZWxzID0gKG1heENoYW5uZWxzJjB4RkYwMCkgPyAobWF4Q2hhbm5lbHM+PjgpIDogaEFhY0VuY29kZXItPm5NYXhBYWNDaGFubmVsczsKICAgICAgICB9CgogICAgICAgIGlmICggKGhBYWNFbmNvZGVyLT5uTWF4QWFjQ2hhbm5lbHM+KDYpKSB8fCAoaEFhY0VuY29kZXItPm5NYXhTYnJDaGFubmVscz4oNikpICkgewogICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgIGdvdG8gYmFpbDsKICAgICAgICB9CiAgICB9IC8qIG1heENoYW5uZWxzPT0wICovCgogICAgLyogTWF4IG51bWJlciBvZiBlbGVtZW50cyBjb3VsZCBiZSB0dW5lZCBhbnkgbW9yZS4gKi8KICAgIGhBYWNFbmNvZGVyLT5uTWF4QWFjRWxlbWVudHMgPSBmaXhNaW4oKDYpLCBoQWFjRW5jb2Rlci0+bk1heEFhY0NoYW5uZWxzKTsKICAgIGhBYWNFbmNvZGVyLT5uTWF4U2JyRWxlbWVudHMgPSBmaXhNaW4oKDYpLCBoQWFjRW5jb2Rlci0+bk1heFNickNoYW5uZWxzKTsKICAgIGhBYWNFbmNvZGVyLT5uTWF4U3ViRnJhbWVzID0gKDEpOwoKCiAgICAvKiBJbiBjYXNlIG9mIG1lbW9yeSBvdmVybGF5LCBhbGxvY2F0ZSBtZW1vcnkgb3V0IG9mIGxpYnJhcmllcyAqLwoKICAgIGhBYWNFbmNvZGVyLT5pbnB1dEJ1ZmZlciA9IChJTlRfUENNKilGREtjYWxsb2MoaEFhY0VuY29kZXItPm5NYXhBYWNDaGFubmVscypJTlBVVEJVRkZFUl9TSVpFLCBzaXplb2YoSU5UX1BDTSkpOwoKICAgIC8qIE9wZW4gU0JSIEVuY29kZXIgKi8KICAgIGlmIChoQWFjRW5jb2Rlci0+ZW5jb2Rlcl9tb2RpcyZFTkNfTU9ERV9GTEFHX1NCUikgewogICAgICAgIGlmICggc2JyRW5jb2Rlcl9PcGVuKCZoQWFjRW5jb2Rlci0+aEVudkVuYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPm5NYXhTYnJFbGVtZW50cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPm5NYXhTYnJDaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaEFhY0VuY29kZXItPmVuY29kZXJfbW9kaXMmRU5DX01PREVfRkxBR19QUykgPyAxIDogMCApICkKICAgICAgICB7CiAgICAgICAgICBlcnIgPSBBQUNFTkNfTUVNT1JZX0VSUk9SOwogICAgICAgICAgZ290byBiYWlsOwogICAgICAgIH0KICAgIH0gLyogKGVuY29kZXJfbW9kaXMmRU5DX01PREVfRkxBR19TQlIpICovCgoKICAgIC8qIE9wZW4gQWFjIEVuY29kZXIgKi8KICAgIGlmICggRkRLYWFjRW5jX09wZW4oJmhBYWNFbmNvZGVyLT5oQWFjRW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPm5NYXhBYWNFbGVtZW50cywKICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5uTWF4QWFjQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAoMSkpICE9IEFBQ19FTkNfT0sgKQogICAgewogICAgICAgIGVyciA9IEFBQ0VOQ19NRU1PUllfRVJST1I7CiAgICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIHsgLyogR2V0IGJpdHN0cmVhbSBvdXRwdXRidWZmZXIgc2l6ZSAqLwogICAgICBVSU5UIGxkX007CiAgICAgIGZvciAobGRfTT0xOyAoVUlOVCkoMTw8bGRfTSkgPCAoaEFhY0VuY29kZXItPm5NYXhTdWJGcmFtZXMqaEFhY0VuY29kZXItPm5NYXhBYWNDaGFubmVscyo2MTQ0KT4+MzsgbGRfTSsrKSA7CiAgICAgIGhBYWNFbmNvZGVyLT5vdXRCdWZmZXJJbkJ5dGVzID0gKDE8PGxkX00pOyAgLyogYnVmZmVyIGhhcyB0byBiZSAyXm4gKi8KICAgIH0KICAgIGhBYWNFbmNvZGVyLT5vdXRCdWZmZXIgPSBHZXRSYW1fYnNPdXRidWZmZXIoKTsKICAgIGlmIChPVVRQVVRCVUZGRVJfU0laRSA8IGhBYWNFbmNvZGVyLT5vdXRCdWZmZXJJbkJ5dGVzICkgewogICAgICBlcnIgPSBBQUNFTkNfTUVNT1JZX0VSUk9SOwogICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgLyogT3BlbiBNZXRhIERhdGEgRW5jb2RlciAqLwogICAgaWYgKGhBYWNFbmNvZGVyLT5lbmNvZGVyX21vZGlzJkVOQ19NT0RFX0ZMQUdfTUVUQSkgewogICAgICBpZiAoIEZES19NZXRhZGF0YUVuY19PcGVuKCZoQWFjRW5jb2Rlci0+aE1ldGFkYXRhRW5jKSApCiAgICAgIHsKICAgICAgICBlcnIgPSBBQUNFTkNfTUVNT1JZX0VSUk9SOwogICAgICAgIGdvdG8gYmFpbDsKICAgICAgfQogICAgfSAvKiAoZW5jb2Rlcl9tb2RpcyZFTkNfTU9ERV9GTEFHX01FVEEpICovCgogICAgLyogT3BlbiBUcmFuc3BvcnQgRW5jb2RlciAqLwogICAgaWYgKCB0cmFuc3BvcnRFbmNfT3BlbigmaEFhY0VuY29kZXItPmhUcEVuYykgIT0gMCApCiAgICB7CiAgICAgICAgZXJyID0gQUFDRU5DX01FTU9SWV9FUlJPUjsKICAgICAgICBnb3RvIGJhaWw7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBDX0FMTE9DX1NDUkFUQ0hfU1RBUlQocExpYkluZm8sIExJQl9JTkZPLCBGREtfTU9EVUxFX0xBU1QpOwoKICAgICAgICBGREtpbml0TGliSW5mbyggcExpYkluZm8pOwogICAgICAgIHRyYW5zcG9ydEVuY19HZXRMaWJJbmZvKCBwTGliSW5mbyApOwoKICAgICAgICAvKiBHZXQgY2FwYWJpbHR5IGZsYWcgZm9yIHRyYW5zcG9ydCBlbmNvZGVyLiAqLwogICAgICAgIGhBYWNFbmNvZGVyLT5DQVBGX3RwRW5jID0gRkRLbGliSW5mb19nZXRDYXBhYmlsaXRpZXMoIHBMaWJJbmZvLCBGREtfVFBFTkMpOwoKICAgICAgICBDX0FMTE9DX1NDUkFUQ0hfRU5EKHBMaWJJbmZvLCBMSUJfSU5GTywgRkRLX01PRFVMRV9MQVNUKTsKICAgIH0KICAgIGlmICggdHJhbnNwb3J0RW5jX1JlZ2lzdGVyU2JyQ2FsbGJhY2soaEFhY0VuY29kZXItPmhUcEVuYywgYWFjZW5jX1NickNhbGxiYWNrLCBoQWFjRW5jb2RlcikgIT0gMCApIHsKICAgICAgZXJyID0gQUFDRU5DX0lOSVRfVFBfRVJST1I7CiAgICAgIGdvdG8gYmFpbDsKICAgIH0KCiAgICAvKiBJbml0aWFsaXplIGVuY29kZXIgaW5zdGFuY2Ugd2l0aCBkZWZhdWx0IHBhcmFtZXRlcnMuICovCiAgICBhYWNFbmNEZWZhdWx0Q29uZmlnKCZoQWFjRW5jb2Rlci0+YWFjQ29uZmlnLCAmaEFhY0VuY29kZXItPmV4dFBhcmFtKTsKCiAgICAvKiBJbml0aWFsaXplIGhlYWRlclBlcmlvZCBpbiBjb2RlckNvbmZpZyBmb3IgYWFjRW5jb2Rlcl9HZXRQYXJhbSgpLiAqLwogICAgaEFhY0VuY29kZXItPmNvZGVyQ29uZmlnLmhlYWRlclBlcmlvZCA9IGhBYWNFbmNvZGVyLT5leHRQYXJhbS51c2VyVHBIZWFkZXJQZXJpb2Q7CgogICAgLyogQWxsIGVuY29kZXIgbW9kdWxlcyBoYXZlIHRvIGJlIGluaXRpYWxpemVkICovCiAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzID0gQUFDRU5DX0lOSVRfQUxMOwoKICAgIC8qIFJldHVybiBlbmNvZGVyIGluc3RhbmNlICovCiAgICAqcGhBYWNFbmNvZGVyID0gaEFhY0VuY29kZXI7CgogICAgcmV0dXJuIGVycjsKCmJhaWw6CiAgICBhYWNFbmNDbG9zZSgmaEFhY0VuY29kZXIpOwoKICAgIHJldHVybiBlcnI7Cn0KCgoKQUFDRU5DX0VSUk9SIGFhY0VuY0Nsb3NlKEhBTkRMRV9BQUNFTkNPREVSICpwaEFhY0VuY29kZXIpCnsKICAgIEFBQ0VOQ19FUlJPUiBlcnIgPSBBQUNFTkNfT0s7CgogICAgaWYgKHBoQWFjRW5jb2RlciA9PSBOVUxMKSB7CiAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfSEFORExFOwogICAgICAgIGdvdG8gYmFpbDsKICAgIH0KCiAgICBpZiAoKnBoQWFjRW5jb2RlciAhPSBOVUxMKSB7CiAgICAgICAgSEFORExFX0FBQ0VOQ09ERVIgaEFhY0VuY29kZXIgPSAqcGhBYWNFbmNvZGVyOwoKCiAgICAgICBpZiAoaEFhY0VuY29kZXItPmlucHV0QnVmZmVyIT1OVUxMKSB7CiAgICAgICAgICAgRkRLZnJlZShoQWFjRW5jb2Rlci0+aW5wdXRCdWZmZXIpOwogICAgICAgICAgIGhBYWNFbmNvZGVyLT5pbnB1dEJ1ZmZlciA9IE5VTEw7CiAgICAgICB9CgogICAgICAgaWYgKGhBYWNFbmNvZGVyLT5vdXRCdWZmZXIpIHsKICAgICAgICAgRnJlZVJhbV9ic091dGJ1ZmZlcigmaEFhY0VuY29kZXItPm91dEJ1ZmZlcik7CiAgICAgICB9CgogICAgICAgIGlmIChoQWFjRW5jb2Rlci0+aEVudkVuYykgewogICAgICAgICAgICBzYnJFbmNvZGVyX0Nsb3NlICgmaEFhY0VuY29kZXItPmhFbnZFbmMpOwogICAgICAgIH0KICAgICAgICBpZiAoaEFhY0VuY29kZXItPmhBYWNFbmMpIHsKICAgICAgICAgICAgRkRLYWFjRW5jX0Nsb3NlICgmaEFhY0VuY29kZXItPmhBYWNFbmMpOwogICAgICAgIH0KCiAgICAgICAgdHJhbnNwb3J0RW5jX0Nsb3NlKCZoQWFjRW5jb2Rlci0+aFRwRW5jKTsKCiAgICAgICAgaWYgKGhBYWNFbmNvZGVyLT5oTWV0YWRhdGFFbmMpIHsKICAgICAgICAgICAgRkRLX01ldGFkYXRhRW5jX0Nsb3NlICgmaEFhY0VuY29kZXItPmhNZXRhZGF0YUVuYyk7CiAgICAgICAgfQoKICAgICAgICBGcmVlX0FhY0VuY29kZXIocGhBYWNFbmNvZGVyKTsKICAgIH0KCmJhaWw6CiAgICByZXR1cm4gZXJyOwp9CgpBQUNFTkNfRVJST1IgYWFjRW5jRW5jb2RlKAogICAgICAgIGNvbnN0IEhBTkRMRV9BQUNFTkNPREVSICAgaEFhY0VuY29kZXIsCiAgICAgICAgY29uc3QgQUFDRU5DX0J1ZkRlc2MgICAgICppbkJ1ZkRlc2MsCiAgICAgICAgY29uc3QgQUFDRU5DX0J1ZkRlc2MgICAgICpvdXRCdWZEZXNjLAogICAgICAgIGNvbnN0IEFBQ0VOQ19JbkFyZ3MgICAgICAqaW5hcmdzLAogICAgICAgIEFBQ0VOQ19PdXRBcmdzICAgICAgICAgICAqb3V0YXJncwogICAgICAgICkKewogICAgQUFDRU5DX0VSUk9SIGVyciA9IEFBQ0VOQ19PSzsKICAgIElOVCBpLCBuQnNCeXRlcyA9IDA7CiAgICBJTlQgIG91dEJ5dGVzWygxKV07CiAgICBpbnQgIG5FeHRlbnNpb25zID0gMDsKICAgIGludCAgYW5jRGF0YUV4dElkeCA9IC0xOwoKICAgIC8qIGRlYWwgd2l0aCB2YWxpZCBlbmNvZGVyIGhhbmRsZSAqLwogICAgaWYgKGhBYWNFbmNvZGVyPT1OVUxMKSB7CiAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfSEFORExFOwogICAgICAgIGdvdG8gYmFpbDsKICAgIH0KCgogICAgLyoKICAgICAqIEFkanVzdCB1c2VyIHNldHRpbmdzIGFuZCB0cmlnZ2VyIHJlaW5pdGlhbGl6YXRpb24uCiAgICAgKi8KICAgIGlmIChoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIT0wKSB7CgogICAgICAgIGVyciA9IGFhY0VuY0luaXQoaEFhY0VuY29kZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAmaEFhY0VuY29kZXItPmV4dFBhcmFtKTsKCiAgICAgICAgaWYgKGVyciE9QUFDRU5DX09LKSB7CiAgICAgICAgICAgIC8qIGtlZXAgaW5pdCBmbGFncyBhbGl2ZSEgKi8KICAgICAgICAgICAgZ290byBiYWlsOwogICAgICAgIH0KICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzID0gQUFDRU5DX0lOSVRfTk9ORTsKICAgIH0KCiAgICBpZiAob3V0YXJncyE9TlVMTCkgewogICAgICAgIEZES21lbWNsZWFyKG91dGFyZ3MsIHNpemVvZihBQUNFTkNfT3V0QXJncykpOwogICAgfQoKICAgIGlmIChvdXRCdWZEZXNjIT1OVUxMKSB7CiAgICAgIGZvciAoaT0wOyBpPG91dEJ1ZkRlc2MtPm51bUJ1ZnM7IGkrKykgewogICAgICAgIGlmIChvdXRCdWZEZXNjLT5idWZzW2ldIT1OVUxMKSB7CiAgICAgICAgICBGREttZW1jbGVhcihvdXRCdWZEZXNjLT5idWZzW2ldLCBvdXRCdWZEZXNjLT5idWZTaXplc1tpXSk7CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgLyoKICAgICAqIElmIG9ubHkgZW5jb2RlciBoYW5kbGUgZ2l2ZW4sIGluZGVwZW5kZW50IChyZSlpbml0aWFsaXphdGlvbiBjYW4gYmUgdHJpZ2dlcmVkLgogICAgICovCiAgICBpZiAoIChoQWFjRW5jb2RlciE9TlVMTCkgJiAoaW5CdWZEZXNjPT1OVUxMKSAmJiAob3V0QnVmRGVzYz09TlVMTCkgJiYgKGluYXJncz09TlVMTCkgJiYgKG91dGFyZ3M9PU5VTEwpICkgewogICAgICAgIGdvdG8gYmFpbDsKICAgIH0KCiAgICAvKiByZXNldCBidWZmZXIgd2ljaCBzaWduYWxzIG51bWJlciBvZiB2YWxpZCBieXRlcyBpbiBvdXRwdXQgYml0c3RyZWFtIGJ1ZmZlciAqLwogICAgRkRLbWVtY2xlYXIob3V0Qnl0ZXMsIGhBYWNFbmNvZGVyLT5hYWNDb25maWcublN1YkZyYW1lcypzaXplb2YoSU5UKSk7CgogICAgLyoKICAgICAqIE1hbmFnZSBpbmNvbWluZyBhdWRpbyBzYW1wbGVzLgogICAgICovCiAgICBpZiAoIChpbmFyZ3MtPm51bUluU2FtcGxlcyA+IDApICYmIChnZXRCdWZEZXNjSWR4KGluQnVmRGVzYyxJTl9BVURJT19EQVRBKSAhPSAtMSkgKQogICAgewogICAgICAgIC8qIEZldGNoIGRhdGEgdW50aWwgblNhbXBsZXNUb1JlYWQgcmVhY2hlZCAqLwogICAgICAgIElOVCBpZHggPSBnZXRCdWZEZXNjSWR4KGluQnVmRGVzYyxJTl9BVURJT19EQVRBKTsKICAgICAgICBJTlQgbmV3U2FtcGxlcyA9IGZpeE1heCgwLGZpeE1pbihpbmFyZ3MtPm51bUluU2FtcGxlcywgaEFhY0VuY29kZXItPm5TYW1wbGVzVG9SZWFkLWhBYWNFbmNvZGVyLT5uU2FtcGxlc1JlYWQpKTsKICAgICAgICBJTlRfUENNICpwSW4gPSBoQWFjRW5jb2Rlci0+aW5wdXRCdWZmZXIraEFhY0VuY29kZXItPmlucHV0QnVmZmVyT2Zmc2V0K2hBYWNFbmNvZGVyLT5uU2FtcGxlc1JlYWQ7CgogICAgICAgIC8qIENvcHkgbmV3IGlucHV0IHNhbXBsZXMgdG8gaW50ZXJuYWwgYnVmZmVyICovCiAgICAgICAgaWYgKGluQnVmRGVzYy0+YnVmRWxTaXplc1tpZHhdPT0oSU5UKXNpemVvZihJTlRfUENNKSkgewogICAgICAgICAgICBGREttZW1jcHkocEluLCAoSU5UX1BDTSopaW5CdWZEZXNjLT5idWZzW2lkeF0sIG5ld1NhbXBsZXMqc2l6ZW9mKElOVF9QQ00pKTsgIC8qIEZhc3QgY29weS4gKi8KICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoaW5CdWZEZXNjLT5idWZFbFNpemVzW2lkeF0+KElOVClzaXplb2YoSU5UX1BDTSkpIHsKICAgICAgICAgICAgZm9yIChpPTA7IGk8bmV3U2FtcGxlczsgaSsrKSB7CiAgICAgICAgICAgICAgICBwSW5baV0gPSAoSU5UX1BDTSkoKChMT05HKilpbkJ1ZkRlc2MtPmJ1ZnNbaWR4XSlbaV0+PjE2KTsgICAgICAgICAgICAgICAgLyogQ29udmVydCAzMiB0byAxNiBiaXQuICovCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGZvciAoaT0wOyBpPG5ld1NhbXBsZXM7IGkrKykgewogICAgICAgICAgICAgICAgcEluW2ldID0gKChJTlRfUENNKSgoKFNIT1JUKilpbkJ1ZkRlc2MtPmJ1ZnNbaWR4XSlbaV0pKTw8MTY7ICAgICAgICAgICAgIC8qIENvbnZlcnQgMTYgdG8gMzIgYml0LiAqLwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGhBYWNFbmNvZGVyLT5uU2FtcGxlc1JlYWQgKz0gbmV3U2FtcGxlczsKCiAgICAgICAgLyogTnVtYmVyIG9mIGZldGNoZWQgaW5wdXQgYnVmZmVyIHNhbXBsZXMuICovCiAgICAgICAgb3V0YXJncy0+bnVtSW5TYW1wbGVzID0gbmV3U2FtcGxlczsKICAgIH0KCiAgICAvKiBpbnB1dCBidWZmZXIgY29tcGxldGVseSBmaWxsZWQgPyAqLwogICAgaWYgKGhBYWNFbmNvZGVyLT5uU2FtcGxlc1JlYWQgPCBoQWFjRW5jb2Rlci0+blNhbXBsZXNUb1JlYWQpCiAgICB7CiAgICAgICAgLyogLSBlb2YgcmVhY2hlZCBhbmQgZmx1c2hpbmcgZW5hYmxlZCwgb3IKICAgICAgICAgICAtIHJldHVybiB0byBtYWluIGFuZCB3YWl0IGZvciBmdXJ0aGVyIGluY29taW5nIGF1ZGlvIHNhbXBsZXMgKi8KICAgICAgICBpZiAoaW5hcmdzLT5udW1JblNhbXBsZXM9PS0xKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCAoaEFhY0VuY29kZXItPm5aZXJvc0FwcGVuZGVkIDwgaEFhY0VuY29kZXItPm5EZWxheSkKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgewogICAgICAgICAgICAgIGludCBuWmVyb3MgPSBoQWFjRW5jb2Rlci0+blNhbXBsZXNUb1JlYWQgLSBoQWFjRW5jb2Rlci0+blNhbXBsZXNSZWFkOwoKICAgICAgICAgICAgICBGREtfQVNTRVJUKG5aZXJvcyA+PSAwKTsKCiAgICAgICAgICAgICAgLyogY2xlYXIgb3V0IHVudGlsIGVuZC1vZi1idWZmZXIgKi8KICAgICAgICAgICAgICBpZiAoblplcm9zKSB7CiAgICAgICAgICAgICAgICBGREttZW1jbGVhcihoQWFjRW5jb2Rlci0+aW5wdXRCdWZmZXIraEFhY0VuY29kZXItPmlucHV0QnVmZmVyT2Zmc2V0K2hBYWNFbmNvZGVyLT5uU2FtcGxlc1JlYWQsIHNpemVvZihJTlRfUENNKSpuWmVyb3MgKTsKICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5uWmVyb3NBcHBlbmRlZCArPSBuWmVyb3M7CiAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+blNhbXBsZXNSZWFkID0gaEFhY0VuY29kZXItPm5TYW1wbGVzVG9SZWFkOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlIHsgLyogZmx1c2hpbmcgY29tcGxldGVkICovCiAgICAgICAgICAgICAgZXJyID0gQUFDRU5DX0VOQ09ERV9FT0Y7IC8qIGVvZiByZWFjaGVkICovCiAgICAgICAgICAgICAgZ290byBiYWlsOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgeyAvKiBpbmFyZ3MtPm51bUluU2FtcGxlcyE9IC0xICovCiAgICAgICAgICAgIGdvdG8gYmFpbDsgLyogbm90IGVub3VnaCBzYW1wbGVzIGluIGlucHV0IGJ1ZmZlciBhbmQgbm8gZmx1c2hpbmcgZW5hYmxlZCAqLwogICAgICAgIH0KICAgIH0KCiAgICAvKiBpbml0IHBheWxvYWQgKi8KICAgIEZES21lbWNsZWFyKGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkLCBzaXplb2YoQUFDRU5DX0VYVF9QQVlMT0FEKSAqIE1BWF9UT1RBTF9FWFRfUEFZTE9BRFMpOwogICAgZm9yIChpID0gMDsgaSA8IE1BWF9UT1RBTF9FWFRfUEFZTE9BRFM7IGkrKykgewogICAgICBoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZFtpXS5hc3NvY2lhdGVkQ2hFbGVtZW50ID0gLTE7CiAgICB9CiAgICBGREttZW1jbGVhcihoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZERhdGEsIHNpemVvZihoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZERhdGEpKTsKICAgIEZES21lbWNsZWFyKGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkU2l6ZSwgc2l6ZW9mKGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkU2l6ZSkpOwoKCiAgICAvKgogICAgICogQ2FsY3VsYXRlIE1ldGEgRGF0YSBpbmZvLgogICAgICovCiAgICBpZiAoIChoQWFjRW5jb2Rlci0+aE1ldGFkYXRhRW5jIT1OVUxMKSAmJiAoaEFhY0VuY29kZXItPm1ldGFEYXRhQWxsb3dlZCE9MCkgKSB7CgogICAgICAgIGNvbnN0IEFBQ0VOQ19NZXRhRGF0YSAqcE1ldGFEYXRhID0gTlVMTDsKICAgICAgICBBQUNFTkNfRVhUX1BBWUxPQUQgKnBNZXRhRGF0YUV4dFBheWxvYWQgPSBOVUxMOwogICAgICAgIFVJTlQgbk1ldGFEYXRhRXh0ZW5zaW9ucyA9IDA7CiAgICAgICAgSU5UICBtYXRyaXhfbWl4ZG93bl9pZHggPSAwOwoKICAgICAgICAvKiBOZXcgbWV0YSBkYXRhIGluZm8gYXZhaWxhYmxlID8gKi8KICAgICAgICBpZiAoIGdldEJ1ZkRlc2NJZHgoaW5CdWZEZXNjLElOX01FVEFEQVRBX1NFVFVQKSAhPSAtMSApIHsKICAgICAgICAgIHBNZXRhRGF0YSA9IChBQUNFTkNfTWV0YURhdGEqKWluQnVmRGVzYy0+YnVmc1tnZXRCdWZEZXNjSWR4KGluQnVmRGVzYyxJTl9NRVRBREFUQV9TRVRVUCldOwogICAgICAgIH0KCiAgICAgICAgRkRLX01ldGFkYXRhRW5jX1Byb2Nlc3MoaEFhY0VuY29kZXItPmhNZXRhZGF0YUVuYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+aW5wdXRCdWZmZXIraEFhY0VuY29kZXItPmlucHV0QnVmZmVyT2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5uU2FtcGxlc1JlYWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE1ldGFEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBNZXRhRGF0YUV4dFBheWxvYWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbk1ldGFEYXRhRXh0ZW5zaW9ucywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZtYXRyaXhfbWl4ZG93bl9pZHgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwoKICAgICAgICBmb3IgKGk9MDsgaTwoSU5UKW5NZXRhRGF0YUV4dGVuc2lvbnM7IGkrKykgeyAgLyogR2V0IG1ldGEgZGF0YSBleHRlbnNpb24gcGF5bG9hZC4gKi8KICAgICAgICAgICAgaEFhY0VuY29kZXItPmV4dFBheWxvYWRbbkV4dGVuc2lvbnMrK10gPSBwTWV0YURhdGFFeHRQYXlsb2FkW2ldOwogICAgICAgIH0KCiAgICAgICAgaWYgKCAobWF0cml4X21peGRvd25faWR4IT0tMSkKICAgICAgICAgICYmICgoaEFhY0VuY29kZXItPmV4dFBhcmFtLnVzZXJDaGFubmVsTW9kZT09TU9ERV8xXzJfMil8fChoQWFjRW5jb2Rlci0+ZXh0UGFyYW0udXNlckNoYW5uZWxNb2RlPT1NT0RFXzFfMl8yXzEpKSApCiAgICAgICAgewogICAgICAgICAgLyogU2V0IG1hdHJpeCBtaXhkb3duIGNvZWZmaWNpZW50LiAqLwogICAgICAgICAgVUlOVCBwY2VWYWx1ZSA9IChVSU5UKSggKDE8PDMpIHwgKChtYXRyaXhfbWl4ZG93bl9pZHgmMHgzKTw8MSkgfCAxICk7CiAgICAgICAgICBpZiAoaEFhY0VuY29kZXItPmV4dFBhcmFtLnVzZXJQY2VBZGRpdGlvbnMgIT0gcGNlVmFsdWUpIHsKICAgICAgICAgICAgaEFhY0VuY29kZXItPmV4dFBhcmFtLnVzZXJQY2VBZGRpdGlvbnMgPSBwY2VWYWx1ZTsKICAgICAgICAgICAgaEFhY0VuY29kZXItPkluaXRGbGFncyB8PSBBQUNFTkNfSU5JVF9UUkFOU1BPUlQ7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKCiAgICBpZiAoIGlzU2JyQWN0aXZlKCZoQWFjRW5jb2Rlci0+YWFjQ29uZmlnKSApIHsKCiAgICAgICAgSU5UIG5QYXlsb2FkID0gMDsKCiAgICAgICAgLyoKICAgICAgICAgKiBFbmNvZGUgU0JSIGRhdGEuCiAgICAgICAgICovCiAgICAgICAgaWYgKHNickVuY29kZXJfRW5jb2RlRnJhbWUoaEFhY0VuY29kZXItPmhFbnZFbmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPmlucHV0QnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5leHRQYXJhbS5uQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPmV4dFBheWxvYWRTaXplW25QYXlsb2FkXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZERhdGFbblBheWxvYWRdCiNpZiBkZWZpbmVkKEVWQUxfUEFDS0FHRV9TSUxFTkNFKSB8fCBkZWZpbmVkKEVWQUxfUEFDS0FHRV9TQlJfU0lMRU5DRSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICxoQWFjRW5jb2Rlci0+aEFhY0VuYy0+Y2xlYXJPdXRwdXQKI2VuZGlmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApKQogICAgICAgIHsKICAgICAgICAgICAgZXJyID0gQUFDRU5DX0VOQ09ERV9FUlJPUjsKICAgICAgICAgICAgZ290byBiYWlsOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgLyogQWRkIFNCUiBleHRlbnNpb24gcGF5bG9hZCAqLwogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgKDYpOyBpKyspIHsKICAgICAgICAgICAgICAgIGlmIChoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZFNpemVbblBheWxvYWRdW2ldID4gMCkgewogICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkW25FeHRlbnNpb25zXS5wRGF0YSAgICA9IGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkRGF0YVtuUGF5bG9hZF1baV07CiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPmV4dFBheWxvYWRbbkV4dGVuc2lvbnNdLmRhdGFTaXplID0gaEFhY0VuY29kZXItPmV4dFBheWxvYWRTaXplW25QYXlsb2FkXVtpXTsKICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkW25FeHRlbnNpb25zXS5hc3NvY2lhdGVkQ2hFbGVtZW50ID0gaTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPmV4dFBheWxvYWRbbkV4dGVuc2lvbnNdLmRhdGFUeXBlID0gRVhUX1NCUl9EQVRBOyAgLyogT25jZSBTQlIgRW5jb2RlciBzdXBwb3J0cyBTQlIgQ1JDIHNldCBFWFRfU0JSX0RBVEFfQ1JDICovCiAgICAgICAgICAgICAgICAgICAgbkV4dGVuc2lvbnMrKzsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogb3IgRVhUX1NCUl9EQVRBIGFjY29yZGluZyB0byBjb25maWd1cmF0aW9uLiAqLwogICAgICAgICAgICAgICAgICAgIEZES19BU1NFUlQobkV4dGVuc2lvbnM8PU1BWF9UT1RBTF9FWFRfUEFZTE9BRFMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIG5QYXlsb2FkKys7CiAgICAgICAgfQogICAgfSAvKiBzYnJFbmFibGVkICovCgogICAgaWYgKCAoaW5hcmdzLT5udW1BbmNCeXRlcyA+IDApICYmICggZ2V0QnVmRGVzY0lkeChpbkJ1ZkRlc2MsSU5fQU5DSUxMUllfREFUQSkhPS0xICkgKSB7CiAgICAgICAgSU5UIGlkeCA9IGdldEJ1ZkRlc2NJZHgoaW5CdWZEZXNjLElOX0FOQ0lMTFJZX0RBVEEpOwogICAgICAgIGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkW25FeHRlbnNpb25zXS5kYXRhU2l6ZSA9IGluYXJncy0+bnVtQW5jQnl0ZXMgKiA4OwogICAgICAgIGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkW25FeHRlbnNpb25zXS5wRGF0YSAgICA9IChVQ0hBUiopaW5CdWZEZXNjLT5idWZzW2lkeF07CiAgICAgICAgaEFhY0VuY29kZXItPmV4dFBheWxvYWRbbkV4dGVuc2lvbnNdLmRhdGFUeXBlID0gRVhUX0RBVEFfRUxFTUVOVDsKICAgICAgICBoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZFtuRXh0ZW5zaW9uc10uYXNzb2NpYXRlZENoRWxlbWVudCA9IC0xOwogICAgICAgIGFuY0RhdGFFeHRJZHggPSBuRXh0ZW5zaW9uczsgLyogc3RvcmUgaW5kZXggKi8KICAgICAgICBuRXh0ZW5zaW9ucysrOwogICAgfQoKICAgIC8qCiAgICAgKiBFbmNvZGUgQUFDIC0gQ29yZS4KICAgICAqLwogICAgaWYgKCBGREthYWNFbmNfRW5jb2RlRnJhbWUoIGhBYWNFbmNvZGVyLT5oQWFjRW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5oVHBFbmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPmlucHV0QnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dEJ5dGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSAhPSBBQUNfRU5DX09LICkKICAgIHsKICAgICAgICBlcnIgPSBBQUNFTkNfRU5DT0RFX0VSUk9SOwogICAgICAgIGdvdG8gYmFpbDsKICAgIH0KCiAgICBpZiAoYW5jRGF0YUV4dElkeCA+PSAwKSB7CiAgICAgIG91dGFyZ3MtPm51bUFuY0J5dGVzID0gaW5hcmdzLT5udW1BbmNCeXRlcyAtIChoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZFthbmNEYXRhRXh0SWR4XS5kYXRhU2l6ZT4+Myk7CiAgICB9CgogICAgLyogc2FtcGxlcyBleGhhdXN0ZWQgKi8KICAgIGhBYWNFbmNvZGVyLT5uU2FtcGxlc1JlYWQgLT0gaEFhY0VuY29kZXItPm5TYW1wbGVzVG9SZWFkOwoKICAgIC8qCiAgICAgKiBEZWxheSBiYWxhbmNpbmcgYnVmZmVyIGhhbmRsaW5nCiAgICAgKi8KICAgIGlmIChpc1NickFjdGl2ZSgmaEFhY0VuY29kZXItPmFhY0NvbmZpZykpIHsKICAgICAgICBzYnJFbmNvZGVyX1VwZGF0ZUJ1ZmZlcnMoaEFhY0VuY29kZXItPmhFbnZFbmMsIGhBYWNFbmNvZGVyLT5pbnB1dEJ1ZmZlcik7CiAgICB9CgogICAgLyoKICAgICAqIE1ha2UgYml0c3RyZWFtIHB1YmxpYwogICAgICovCiAgICBpZiAob3V0QnVmRGVzYy0+bnVtQnVmcz49MSkgewoKICAgICAgICBJTlQgYnNJZHggPSBnZXRCdWZEZXNjSWR4KG91dEJ1ZkRlc2MsT1VUX0JJVFNUUkVBTV9EQVRBKTsKICAgICAgICBJTlQgYXVJZHggPSBnZXRCdWZEZXNjSWR4KG91dEJ1ZkRlc2MsT1VUX0FVX1NJWkVTKTsKCiAgICAgICAgZm9yIChpPTAsbkJzQnl0ZXM9MDsgaTxoQWFjRW5jb2Rlci0+YWFjQ29uZmlnLm5TdWJGcmFtZXM7IGkrKykgewogICAgICAgICAgbkJzQnl0ZXMgKz0gb3V0Qnl0ZXNbaV07CgogICAgICAgICAgaWYgKGF1SWR4IT0tMSkgewogICAgICAgICAgICgoSU5UKilvdXRCdWZEZXNjLT5idWZzW2F1SWR4XSlbaV0gPSBvdXRCeXRlc1tpXTsKICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmICggKGJzSWR4IT0tMSkgJiYgKG91dEJ1ZkRlc2MtPmJ1ZlNpemVzW2JzSWR4XT49bkJzQnl0ZXMpICkgewogICAgICAgICAgRkRLbWVtY3B5KG91dEJ1ZkRlc2MtPmJ1ZnNbYnNJZHhdLCBoQWFjRW5jb2Rlci0+b3V0QnVmZmVyLCBzaXplb2YoVUNIQVIpKm5Cc0J5dGVzKTsKICAgICAgICAgIG91dGFyZ3MtPm51bU91dEJ5dGVzID0gbkJzQnl0ZXM7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgLyogb3V0cHV0IGJ1ZmZlciB0b28gc21hbGwsIGNhbid0IHdyaXRlIHZhbGlkIGJpdHN0cmVhbSAqLwogICAgICAgICAgZXJyID0gQUFDRU5DX0VOQ09ERV9FUlJPUjsKICAgICAgICAgIGdvdG8gYmFpbDsKICAgICAgICB9CiAgICB9CgpiYWlsOgogICAgaWYgKGVyciA9PSBBQUNFTkNfRU5DT0RFX0VSUk9SKSB7CiAgICAgICAgLyogQWxsIGVuY29kZXIgbW9kdWxlcyBoYXZlIHRvIGJlIGluaXRpYWxpemVkICovCiAgICAgICAgaEFhY0VuY29kZXItPkluaXRGbGFncyA9IEFBQ0VOQ19JTklUX0FMTDsKICAgIH0KCiAgICByZXR1cm4gZXJyOwp9CgpzdGF0aWMKQUFDX0VOQ09ERVJfRVJST1IgYWFjRW5jR2V0Q29uZihIQU5ETEVfQUFDRU5DT0RFUiAgaEFhY0VuY29kZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCAgICAgICAgICAgICAgKnNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUNIQVIgICAgICAgICAgICAgKmNvbmZCdWZmZXIpCnsKICAgIEZES19CSVRTVFJFQU0gdG1wQ29uZjsKICAgIFVJTlQgY29uZlR5cGU7CiAgICBVQ0hBUiBidWZbNjRdOwogICAgaW50IGVycjsKCiAgICAvKiBJbml0IGJpdCBidWZmZXIgKi8KICAgIEZES2luaXRCaXRTdHJlYW0oJnRtcENvbmYsIGJ1ZiwgNjQsIDAsIEJTX1dSSVRFUik7CgogICAgLyogd3JpdGUgY29uZiBpbiB0bXAgYnVmZmVyICovCiAgICBlcnIgPSB0cmFuc3BvcnRFbmNfR2V0Q29uZihoQWFjRW5jb2Rlci0+aFRwRW5jLCAmaEFhY0VuY29kZXItPmNvZGVyQ29uZmlnLCAmdG1wQ29uZiwgJmNvbmZUeXBlKTsKCiAgICAvKiBjb3B5IGRhdGEgdG8gb3V0YnVmZmVyOiBsZW5ndGggaW4gYnl0ZXMgKi8KICAgIEZES2J5dGVBbGlnbigmdG1wQ29uZiwgMCk7CgogICAgLyogQ2hlY2sgYnVmZmVyIHNpemUgKi8KICAgIGlmIChGREtnZXRWYWxpZEJpdHMoJnRtcENvbmYpID4gKCgqc2l6ZSk8PDMpKQogICAgICByZXR1cm4gQUFDX0VOQ19VTktOT1dOOwoKICAgIEZES2ZldGNoQnVmZmVyKCZ0bXBDb25mLCBjb25mQnVmZmVyLCBzaXplKTsKCiAgICBpZiAoZXJyICE9IDApCiAgICAgIHJldHVybiBBQUNfRU5DX1VOS05PV047CiAgICBlbHNlCiAgICAgIHJldHVybiBBQUNfRU5DX09LOwp9CgoKQUFDRU5DX0VSUk9SIGFhY0VuY0dldExpYkluZm8oTElCX0lORk8gKmluZm8pCnsKICBpbnQgaSA9IDA7CgogIGlmIChpbmZvID09IE5VTEwpIHsKICAgIHJldHVybiBBQUNFTkNfSU5WQUxJRF9IQU5ETEU7CiAgfQoKICBGREtfdG9vbHNHZXRMaWJJbmZvKCBpbmZvICk7CiAgdHJhbnNwb3J0RW5jX0dldExpYkluZm8oIGluZm8gKTsKCiAgc2JyRW5jb2Rlcl9HZXRMaWJJbmZvKCBpbmZvICk7CgogIC8qIHNlYXJjaCBmb3IgbmV4dCBmcmVlIHRhYiAqLwogIGZvciAoaSA9IDA7IGkgPCBGREtfTU9EVUxFX0xBU1Q7IGkrKykgewogICAgaWYgKGluZm9baV0ubW9kdWxlX2lkID09IEZES19OT05FKSBicmVhazsKICB9CiAgaWYgKGkgPT0gRkRLX01PRFVMRV9MQVNUKSB7CiAgICByZXR1cm4gQUFDRU5DX0lOSVRfRVJST1I7CiAgfQoKICBpbmZvW2ldLm1vZHVsZV9pZCA9IEZES19BQUNFTkM7CiAgaW5mb1tpXS5idWlsZF9kYXRlID0gKGNoYXIqKUFBQ0VOQ09ERVJfTElCX0JVSUxEX0RBVEU7CiAgaW5mb1tpXS5idWlsZF90aW1lID0gKGNoYXIqKUFBQ0VOQ09ERVJfTElCX0JVSUxEX1RJTUU7CiAgaW5mb1tpXS50aXRsZSA9IChjaGFyKilBQUNFTkNPREVSX0xJQl9USVRMRTsKICBpbmZvW2ldLnZlcnNpb24gPSBMSUJfVkVSU0lPTihBQUNFTkNPREVSX0xJQl9WTDAsIEFBQ0VOQ09ERVJfTElCX1ZMMSwgQUFDRU5DT0RFUl9MSUJfVkwyKTs7CiAgTElCX1ZFUlNJT05fU1RSSU5HKCZpbmZvW2ldKTsKCiAgLyogQ2FwYWJpbGl0eSBmbGFncyAqLwogIGluZm9baV0uZmxhZ3MgPSAwCiAgICB8IENBUEZfQUFDXzEwMjQgfCBDQVBGX0FBQ19MQwogICAgfCBDQVBGX0FBQ181MTIKICAgIHwgQ0FQRl9BQUNfNDgwCiAgICB8IENBUEZfQUFDX0RSQwogICAgICA7CiAgLyogRW5kIG9mIGZsYWdzICovCgogIHJldHVybiBBQUNFTkNfT0s7Cn0KCkFBQ0VOQ19FUlJPUiBhYWNFbmNvZGVyX1NldFBhcmFtKAogICAgICAgIGNvbnN0IEhBTkRMRV9BQUNFTkNPREVSICAgaEFhY0VuY29kZXIsCiAgICAgICAgY29uc3QgQUFDRU5DX1BBUkFNICAgICAgICBwYXJhbSwKICAgICAgICBjb25zdCBVSU5UICAgICAgICAgICAgICAgIHZhbHVlCiAgICAgICAgKQp7CiAgICBBQUNFTkNfRVJST1IgZXJyID0gQUFDRU5DX09LOwogICAgVVNFUl9QQVJBTSAqc2V0dGluZ3MgPSAmaEFhY0VuY29kZXItPmV4dFBhcmFtOwoKICAgIC8qIGNoZWNrIGVuY29kZXIgaGFuZGxlICovCiAgICBpZiAoaEFhY0VuY29kZXIgPT0gTlVMTCkgewogICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0hBTkRMRTsKICAgICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgLyogYXBwbHkgcGFyYW0gdmFsdWUgKi8KICAgIHN3aXRjaCAocGFyYW0pCiAgICB7CiAgICBjYXNlIEFBQ0VOQ19BT1Q6CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyQU9UICE9IChBVURJT19PQkpFQ1RfVFlQRSl2YWx1ZSkgewogICAgICAgICAgICAvKiBjaGVjayBpZiBBT1QgbWF0Y2hlcyB0aGUgYWxsb2NhdGVkIG1vZHVsZXMgKi8KICAgICAgICAgICAgc3dpdGNoICggdmFsdWUgKSB7CiAgICAgICAgICAgICAgY2FzZSBBT1RfUFM6CiAgICAgICAgICAgICAgY2FzZSBBT1RfTVAyX1BTOgogICAgICAgICAgICAgICAgaWYgKCEoaEFhY0VuY29kZXItPmVuY29kZXJfbW9kaXMgJiAoRU5DX01PREVfRkxBR19QUykpKSB7CiAgICAgICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgICAgICAgZ290byBiYWlsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGNhc2UgQU9UX1NCUjoKICAgICAgICAgICAgICBjYXNlIEFPVF9NUDJfU0JSOgogICAgICAgICAgICAgICAgaWYgKCEoaEFhY0VuY29kZXItPmVuY29kZXJfbW9kaXMgJiAoRU5DX01PREVfRkxBR19TQlIpKSkgewogICAgICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgICAgICAgIGdvdG8gYmFpbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBjYXNlIEFPVF9BQUNfTEM6CiAgICAgICAgICAgICAgY2FzZSBBT1RfTVAyX0FBQ19MQzoKICAgICAgICAgICAgICBjYXNlIEFPVF9FUl9BQUNfTEQ6CiAgICAgICAgICAgICAgY2FzZSBBT1RfRVJfQUFDX0VMRDoKICAgICAgICAgICAgICAgIGlmICghKGhBYWNFbmNvZGVyLT5lbmNvZGVyX21vZGlzICYgKEVOQ19NT0RFX0ZMQUdfQUFDKSkpIHsKICAgICAgICAgICAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgICAgICAgICBnb3RvIGJhaWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgICAgICAgZ290byBiYWlsOwogICAgICAgICAgICB9Lyogc3dpdGNoIHZhbHVlICovCiAgICAgICAgICAgIHNldHRpbmdzLT51c2VyQU9UID0gKEFVRElPX09CSkVDVF9UWVBFKXZhbHVlOwogICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX0NPTkZJRyB8IEFBQ0VOQ19JTklUX1NUQVRFUyB8IEFBQ0VOQ19JTklUX1RSQU5TUE9SVDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19CSVRSQVRFOgogICAgICAgIGlmIChzZXR0aW5ncy0+dXNlckJpdHJhdGUgIT0gdmFsdWUpIHsKICAgICAgICAgICAgc2V0dGluZ3MtPnVzZXJCaXRyYXRlID0gdmFsdWU7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfQ09ORklHIHwgQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0JJVFJBVEVNT0RFOgogICAgICAgIGlmIChzZXR0aW5ncy0+dXNlckJpdHJhdGVNb2RlICE9IHZhbHVlKSB7CiAgICAgICAgICAgIHN3aXRjaCAoIHZhbHVlICkgewogICAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICBjYXNlIDg6CiAgICAgICAgICAgICAgICBzZXR0aW5ncy0+dXNlckJpdHJhdGVNb2RlID0gdmFsdWU7CiAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX0NPTkZJRyB8IEFBQ0VOQ19JTklUX1RSQU5TUE9SVDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfSAvKiBzd2l0Y2ggdmFsdWUgKi8KICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19TQU1QTEVSQVRFOgogICAgICAgIGlmIChzZXR0aW5ncy0+dXNlclNhbXBsZXJhdGUgIT0gdmFsdWUpIHsKICAgICAgICAgICAgaWYgKCAhKCAodmFsdWU9PTgwMDApIHx8ICh2YWx1ZT09MTEwMjUpIHx8ICh2YWx1ZT09MTIwMDApIHx8ICh2YWx1ZT09MTYwMDApIHx8ICh2YWx1ZT09MjIwNTApIHx8ICh2YWx1ZT09MjQwMDApIHx8CiAgICAgICAgICAgICAgICAgICAodmFsdWU9PTMyMDAwKSB8fCAodmFsdWU9PTQ0MTAwKSB8fCAodmFsdWU9PTQ4MDAwKSB8fCAodmFsdWU9PTY0MDAwKSB8fCAodmFsdWU9PTg4MjAwKSB8fCAodmFsdWU9PTk2MDAwKSApICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2V0dGluZ3MtPnVzZXJTYW1wbGVyYXRlID0gdmFsdWU7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5uU2FtcGxlc1JlYWQgPSAwOyAvKiByZXNldCBpbnRlcm5hbCBpbnB1dGJ1ZmZlciAqLwogICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX0NPTkZJRyB8IEFBQ0VOQ19JTklUX1NUQVRFUyB8IEFBQ0VOQ19JTklUX1RSQU5TUE9SVDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19DSEFOTkVMTU9ERToKICAgICAgICBpZiAoc2V0dGluZ3MtPnVzZXJDaGFubmVsTW9kZSAhPSAoQ0hBTk5FTF9NT0RFKXZhbHVlKSB7CiAgICAgICAgICAgIGNvbnN0IENIQU5ORUxfTU9ERV9DT05GSUdfVEFCKiBwQ29uZmlnID0gRkRLYWFjRW5jX0dldENoYW5uZWxNb2RlQ29uZmlndXJhdGlvbigoQ0hBTk5FTF9NT0RFKXZhbHVlKTsKICAgICAgICAgICAgaWYgKHBDb25maWc9PU5VTEwpIHsKICAgICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICggKHBDb25maWctPm5FbGVtZW50cyA+IGhBYWNFbmNvZGVyLT5uTWF4QWFjRWxlbWVudHMpCiAgICAgICAgICAgICAgfHwgKHBDb25maWctPm5DaGFubmVsc0VmZiA+IGhBYWNFbmNvZGVyLT5uTWF4QWFjQ2hhbm5lbHMpCiAgICAgICAgICAgICAgfHwgISgodmFsdWU+PTEpICYmICh2YWx1ZTw9NikpCiAgICAgICAgICAgICAgICApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzZXR0aW5ncy0+dXNlckNoYW5uZWxNb2RlID0gKENIQU5ORUxfTU9ERSl2YWx1ZTsKICAgICAgICAgICAgc2V0dGluZ3MtPm5DaGFubmVscyA9IHBDb25maWctPm5DaGFubmVsczsKICAgICAgICAgICAgaEFhY0VuY29kZXItPm5TYW1wbGVzUmVhZCA9IDA7IC8qIHJlc2V0IGludGVybmFsIGlucHV0YnVmZmVyICovCiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfQ09ORklHIHwgQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0JBTkRXSURUSDoKICAgICAgICBpZiAoc2V0dGluZ3MtPnVzZXJCYW5kd2lkdGggIT0gdmFsdWUpIHsKICAgICAgICAgIHNldHRpbmdzLT51c2VyQmFuZHdpZHRoID0gdmFsdWU7CiAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX0NPTkZJRzsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19DSEFOTkVMT1JERVI6CiAgICAgICAgaWYgKGhBYWNFbmNvZGVyLT5hYWNDb25maWcuY2hhbm5lbE9yZGVyICE9IChDSEFOTkVMX09SREVSKXZhbHVlKSB7CiAgICAgICAgICAgIGlmICghICgodmFsdWU9PTApIHx8ICh2YWx1ZT09MSkpICkgewogICAgICAgICAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaEFhY0VuY29kZXItPmFhY0NvbmZpZy5jaGFubmVsT3JkZXIgPSAoQ0hBTk5FTF9PUkRFUil2YWx1ZTsKICAgICAgICAgICAgaEFhY0VuY29kZXItPm5TYW1wbGVzUmVhZCA9IDA7IC8qIHJlc2V0IGludGVybmFsIGlucHV0YnVmZmVyICovCiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfQ09ORklHIHwgQUFDRU5DX0lOSVRfU1RBVEVTIHwgQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0FGVEVSQlVSTkVSOgogICAgICAgIGlmIChzZXR0aW5ncy0+dXNlckFmdGVyYnVybmVyICE9IHZhbHVlKSB7CiAgICAgICAgICAgIGlmICghICgodmFsdWU9PTApIHx8ICh2YWx1ZT09MSkpICkgewogICAgICAgICAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2V0dGluZ3MtPnVzZXJBZnRlcmJ1cm5lciA9IHZhbHVlOwogICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX0NPTkZJRzsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19HUkFOVUxFX0xFTkdUSDoKICAgICAgICBpZiAoc2V0dGluZ3MtPnVzZXJGcmFtZWxlbmd0aCAhPSB2YWx1ZSkgewogICAgICAgICAgc3dpdGNoICh2YWx1ZSkgewogICAgICAgICAgICBjYXNlIDEwMjQ6CiAgICAgICAgICAgIGNhc2UgNTEyOgogICAgICAgICAgICBjYXNlIDQ4MDoKICAgICAgICAgICAgICBzZXR0aW5ncy0+dXNlckZyYW1lbGVuZ3RoID0gdmFsdWU7CiAgICAgICAgICAgICAgaEFhY0VuY29kZXItPkluaXRGbGFncyB8PSBBQUNFTkNfSU5JVF9DT05GSUcgfCBBQUNFTkNfSU5JVF9UUkFOU1BPUlQ7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX1NCUl9SQVRJTzoKICAgICAgICBpZiAoc2V0dGluZ3MtPnVzZXJTYnJSYXRpbyAhPSB2YWx1ZSkgewogICAgICAgICAgICBpZiAoISAoKHZhbHVlPT0wKSB8fCAodmFsdWU9PTEpIHx8ICh2YWx1ZT09MikpICkgewogICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBzZXR0aW5ncy0+dXNlclNiclJhdGlvID0gdmFsdWU7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfQ09ORklHIHwgQUFDRU5DX0lOSVRfU1RBVEVTIHwgQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX1NCUl9NT0RFOgogICAgICAgIGlmIChzZXR0aW5ncy0+dXNlclNickVuYWJsZWQgIT0gdmFsdWUpIHsKICAgICAgICAgICAgc2V0dGluZ3MtPnVzZXJTYnJFbmFibGVkID0gdmFsdWU7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfQ09ORklHIHwgQUFDRU5DX0lOSVRfU1RBVEVTIHwgQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX1RSQU5TTVVYOgogICAgICAgIGlmIChzZXR0aW5ncy0+dXNlclRwVHlwZSAhPSAoVFJBTlNQT1JUX1RZUEUpdmFsdWUpIHsKCiAgICAgICAgICAgIFRSQU5TUE9SVF9UWVBFICB0eXBlICA9IChUUkFOU1BPUlRfVFlQRSl2YWx1ZTsKICAgICAgICAgICAgVUlOVCAgICAgICAgICAgIGZsYWdzID0gaEFhY0VuY29kZXItPkNBUEZfdHBFbmM7CgogICAgICAgICAgICBpZiAoICEoICgodHlwZT09VFRfTVA0X0FESUYpICAgICAgJiYgIChmbGFncyZDQVBGX0FESUYpKQogICAgICAgICAgICAgICAgIHx8ICgodHlwZT09VFRfTVA0X0FEVFMpICAgICAgJiYgIChmbGFncyZDQVBGX0FEVFMpKQogICAgICAgICAgICAgICAgIHx8ICgodHlwZT09VFRfTVA0X0xBVE1fTUNQMCkgJiYgKChmbGFncyZDQVBGX0xBVE0pICYmIChmbGFncyZDQVBGX1JBV1BBQ0tFVFMpKSkKICAgICAgICAgICAgICAgICB8fCAoKHR5cGU9PVRUX01QNF9MQVRNX01DUDEpICYmICgoZmxhZ3MmQ0FQRl9MQVRNKSAmJiAoZmxhZ3MmQ0FQRl9SQVdQQUNLRVRTKSkpCiAgICAgICAgICAgICAgICAgfHwgKCh0eXBlPT1UVF9NUDRfTE9BUykgICAgICAmJiAgKGZsYWdzJkNBUEZfTE9BUykpCiAgICAgICAgICAgICAgICAgfHwgKCh0eXBlPT1UVF9NUDRfUkFXKSAgICAgICAmJiAgKGZsYWdzJkNBUEZfUkFXUEFDS0VUUykpCiAgICAgICAgICAgICAgICApICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2V0dGluZ3MtPnVzZXJUcFR5cGUgPSAoVFJBTlNQT1JUX1RZUEUpdmFsdWU7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX1NJR05BTElOR19NT0RFOgogICAgICAgIGlmIChzZXR0aW5ncy0+dXNlclRwU2lnbmFsaW5nICE9IHZhbHVlKSB7CiAgICAgICAgICAgIGlmICggISgodmFsdWU9PTApIHx8ICh2YWx1ZT09MSkgfHwgKHZhbHVlPT0yKSkgKSB7CiAgICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBzZXR0aW5ncy0+dXNlclRwU2lnbmFsaW5nID0gdmFsdWU7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX1BST1RFQ1RJT046CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyVHBQcm90ZWN0aW9uICE9IHZhbHVlKSB7CiAgICAgICAgICAgIGlmICggISgodmFsdWU9PTApIHx8ICh2YWx1ZT09MSkpICkgewogICAgICAgICAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2V0dGluZ3MtPnVzZXJUcFByb3RlY3Rpb24gPSB2YWx1ZTsKICAgICAgICAgICAgaEFhY0VuY29kZXItPkluaXRGbGFncyB8PSBBQUNFTkNfSU5JVF9UUkFOU1BPUlQ7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfSEVBREVSX1BFUklPRDoKICAgICAgICBpZiAoc2V0dGluZ3MtPnVzZXJUcEhlYWRlclBlcmlvZCAhPSB2YWx1ZSkgewogICAgICAgICAgICBzZXR0aW5ncy0+dXNlclRwSGVhZGVyUGVyaW9kID0gdmFsdWU7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX1RQU1VCRlJBTUVTOgogICAgICAgIGlmIChzZXR0aW5ncy0+dXNlclRwTnN1YkZyYW1lcyAhPSB2YWx1ZSkgewogICAgICAgICAgICBpZiAoISAoICh2YWx1ZT49MSkgJiYgKHZhbHVlPD00KSApICkgewogICAgICAgICAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2V0dGluZ3MtPnVzZXJUcE5zdWJGcmFtZXMgPSB2YWx1ZTsKICAgICAgICAgICAgaEFhY0VuY29kZXItPkluaXRGbGFncyB8PSBBQUNFTkNfSU5JVF9UUkFOU1BPUlQ7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfQU5DSUxMQVJZX0JJVFJBVEU6CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyQW5jRGF0YVJhdGUgIT0gdmFsdWUpIHsKICAgICAgICAgICAgc2V0dGluZ3MtPnVzZXJBbmNEYXRhUmF0ZSA9IHZhbHVlOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0NPTlRST0xfU1RBVEU6CiAgICAgICAgaWYgKGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgIT0gdmFsdWUpIHsKICAgICAgICAgICAgaWYgKHZhbHVlJkFBQ0VOQ19SRVNFVF9JTkJVRkZFUikgewogICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPm5TYW1wbGVzUmVhZCA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaEFhY0VuY29kZXItPkluaXRGbGFncyA9IHZhbHVlOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX01FVEFEQVRBX01PREU6CiAgICAgICAgaWYgKChVSU5UKXNldHRpbmdzLT51c2VyTWV0YURhdGFNb2RlICE9IHZhbHVlKSB7CiAgICAgICAgICAgIGlmICggISgodmFsdWU+PTApICYmICh2YWx1ZTw9MikpICkgewogICAgICAgICAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2V0dGluZ3MtPnVzZXJNZXRhRGF0YU1vZGUgPSB2YWx1ZTsKICAgICAgICAgICAgaEFhY0VuY29kZXItPkluaXRGbGFncyB8PSBBQUNFTkNfSU5JVF9DT05GSUc7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgZXJyID0gQUFDRU5DX1VOU1VQUE9SVEVEX1BBUkFNRVRFUjsKICAgICAgYnJlYWs7CiAgICB9ICAvKiBzd2l0Y2gocGFyYW0pICovCgpiYWlsOgogICAgcmV0dXJuIGVycjsKfQoKVUlOVCBhYWNFbmNvZGVyX0dldFBhcmFtKAogICAgICAgIGNvbnN0IEhBTkRMRV9BQUNFTkNPREVSICAgaEFhY0VuY29kZXIsCiAgICAgICAgY29uc3QgQUFDRU5DX1BBUkFNICAgICAgICBwYXJhbQogICAgICAgICkKewogICAgVUlOVCB2YWx1ZSA9IDA7CiAgICBVU0VSX1BBUkFNICpzZXR0aW5ncyA9ICZoQWFjRW5jb2Rlci0+ZXh0UGFyYW07CgogICAgLyogY2hlY2sgZW5jb2RlciBoYW5kbGUgKi8KICAgIGlmIChoQWFjRW5jb2RlciA9PSBOVUxMKSB7CiAgICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIC8qIGFwcGx5IHBhcmFtIHZhbHVlICovCiAgICBzd2l0Y2ggKHBhcmFtKQogICAgewogICAgY2FzZSBBQUNFTkNfQU9UOgogICAgICAgIHZhbHVlID0gKFVJTlQpaEFhY0VuY29kZXItPmFhY0NvbmZpZy5hdWRpb09iamVjdFR5cGU7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19CSVRSQVRFOgogICAgICAgIHZhbHVlID0gKFVJTlQpKChoQWFjRW5jb2Rlci0+YWFjQ29uZmlnLmJpdHJhdGVNb2RlPT1BQUNFTkNfQlJfTU9ERV9DQlIpID8gaEFhY0VuY29kZXItPmFhY0NvbmZpZy5iaXRSYXRlIDogLTEpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfQklUUkFURU1PREU6CiAgICAgICAgdmFsdWUgPSAoVUlOVCloQWFjRW5jb2Rlci0+YWFjQ29uZmlnLmJpdHJhdGVNb2RlOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfU0FNUExFUkFURToKICAgICAgICB2YWx1ZSA9IChVSU5UKWhBYWNFbmNvZGVyLT5jb2RlckNvbmZpZy5leHRTYW1wbGluZ1JhdGU7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19DSEFOTkVMTU9ERToKICAgICAgICB2YWx1ZSA9IChVSU5UKWhBYWNFbmNvZGVyLT5hYWNDb25maWcuY2hhbm5lbE1vZGU7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19CQU5EV0lEVEg6CiAgICAgICAgdmFsdWUgPSAoVUlOVCloQWFjRW5jb2Rlci0+YWFjQ29uZmlnLmJhbmRXaWR0aDsKICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0NIQU5ORUxPUkRFUjoKICAgICAgICB2YWx1ZSA9IChVSU5UKWhBYWNFbmNvZGVyLT5hYWNDb25maWcuY2hhbm5lbE9yZGVyOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfQUZURVJCVVJORVI6CiAgICAgICAgdmFsdWUgPSAoVUlOVCloQWFjRW5jb2Rlci0+YWFjQ29uZmlnLnVzZVJlcXVhbnQ7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19HUkFOVUxFX0xFTkdUSDoKICAgICAgICB2YWx1ZSA9IChVSU5UKWhBYWNFbmNvZGVyLT5hYWNDb25maWcuZnJhbWVsZW5ndGg7CiAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX1NCUl9SQVRJTzoKICAgICAgICB2YWx1ZSA9IGlzU2JyQWN0aXZlKCZoQWFjRW5jb2Rlci0+YWFjQ29uZmlnKSA/IGhBYWNFbmNvZGVyLT5hYWNDb25maWcuc2JyUmF0aW8gOiAwOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfU0JSX01PREU6CiAgICAgICAgdmFsdWUgPSAoVUlOVCkgKGhBYWNFbmNvZGVyLT5hYWNDb25maWcuc3ludGF4RmxhZ3MgJiBBQ19TQlJfUFJFU0VOVCkgPyAxIDogMDsKICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX1RSQU5TTVVYOgogICAgICAgIHZhbHVlID0gKFVJTlQpc2V0dGluZ3MtPnVzZXJUcFR5cGU7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19TSUdOQUxJTkdfTU9ERToKICAgICAgICB2YWx1ZSA9IChVSU5UKWdldFNiclNpZ25hbGluZ01vZGUoaEFhY0VuY29kZXItPmFhY0NvbmZpZy5hdWRpb09iamVjdFR5cGUsIHNldHRpbmdzLT51c2VyVHBUeXBlLCBzZXR0aW5ncy0+dXNlclRwU2lnbmFsaW5nLCBoQWFjRW5jb2Rlci0+YWFjQ29uZmlnLnNiclJhdGlvKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX1BST1RFQ1RJT046CiAgICAgICAgdmFsdWUgPSAoVUlOVClzZXR0aW5ncy0+dXNlclRwUHJvdGVjdGlvbjsKICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0hFQURFUl9QRVJJT0Q6CiAgICAgICAgdmFsdWUgPSAoVUlOVCloQWFjRW5jb2Rlci0+Y29kZXJDb25maWcuaGVhZGVyUGVyaW9kOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfVFBTVUJGUkFNRVM6CiAgICAgICAgdmFsdWUgPSAoVUlOVClzZXR0aW5ncy0+dXNlclRwTnN1YkZyYW1lczsKICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0FOQ0lMTEFSWV9CSVRSQVRFOgogICAgICAgIHZhbHVlID0gKFVJTlQpaEFhY0VuY29kZXItPmFhY0NvbmZpZy5hbmNfUmF0ZTsKICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0NPTlRST0xfU1RBVEU6CiAgICAgICAgdmFsdWUgPSAoVUlOVCloQWFjRW5jb2Rlci0+SW5pdEZsYWdzOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfTUVUQURBVEFfTU9ERToKICAgICAgICB2YWx1ZSA9IChoQWFjRW5jb2Rlci0+bWV0YURhdGFBbGxvd2VkPT0wKSA/IDAgOiAoVUlOVClzZXR0aW5ncy0+dXNlck1ldGFEYXRhTW9kZTsKICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIC8vZXJyID0gTVBTX0lOVkFMSURfUEFSQU1FVEVSOwogICAgICBicmVhazsKICAgIH0gIC8qIHN3aXRjaChwYXJhbSkgKi8KCmJhaWw6CiAgICByZXR1cm4gdmFsdWU7Cn0KCkFBQ0VOQ19FUlJPUiBhYWNFbmNJbmZvKAogICAgICAgIGNvbnN0IEhBTkRMRV9BQUNFTkNPREVSICAgaEFhY0VuY29kZXIsCiAgICAgICAgQUFDRU5DX0luZm9TdHJ1Y3QgICAgICAgICpwSW5mbwogICAgICAgICkKewogICAgQUFDRU5DX0VSUk9SIGVyciA9IEFBQ0VOQ19PSzsKCiAgICBGREttZW1jbGVhcihwSW5mbywgc2l6ZW9mKEFBQ0VOQ19JbmZvU3RydWN0KSk7CiAgICBwSW5mby0+Y29uZlNpemUgPSA2NDsgLyogcHJlLWluaXRpYWxpemUgKi8KCiAgICBwSW5mby0+bWF4T3V0QnVmQnl0ZXMgICAgPSAoKGhBYWNFbmNvZGVyLT5uTWF4QWFjQ2hhbm5lbHMqNjE0NCkrNyk+PjM7CiAgICBwSW5mby0+bWF4QW5jQnl0ZXMgICAgICAgPSBoQWFjRW5jb2Rlci0+YWFjQ29uZmlnLm1heEFuY0J5dGVzUGVyQVU7CiAgICBwSW5mby0+aW5CdWZGaWxsTGV2ZWwgICAgPSBoQWFjRW5jb2Rlci0+blNhbXBsZXNSZWFkL2hBYWNFbmNvZGVyLT5leHRQYXJhbS5uQ2hhbm5lbHM7CiAgICBwSW5mby0+aW5wdXRDaGFubmVscyAgICAgPSBoQWFjRW5jb2Rlci0+ZXh0UGFyYW0ubkNoYW5uZWxzOwogICAgcEluZm8tPmZyYW1lTGVuZ3RoICAgICAgID0gaEFhY0VuY29kZXItPm5TYW1wbGVzVG9SZWFkL2hBYWNFbmNvZGVyLT5leHRQYXJhbS5uQ2hhbm5lbHM7CiAgICBwSW5mby0+ZW5jb2RlckRlbGF5ICAgICAgPSBoQWFjRW5jb2Rlci0+bkRlbGF5L2hBYWNFbmNvZGVyLT5leHRQYXJhbS5uQ2hhbm5lbHM7CgogICAgLyogR2V0IGVuY29kZXIgY29uZmlndXJhdGlvbiAqLwogICAgaWYgKCBhYWNFbmNHZXRDb25mKGhBYWNFbmNvZGVyLCAmcEluZm8tPmNvbmZTaXplLCAmcEluZm8tPmNvbmZCdWZbMF0pICE9IEFBQ19FTkNfT0spIHsKICAgICAgICBlcnIgPSBBQUNFTkNfSU5JVF9FUlJPUjsKICAgICAgICBnb3RvIGJhaWw7CiAgICB9CmJhaWw6CiAgICByZXR1cm4gZXJyOwp9Cgo=