Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEyIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKiBNUEVHLTQgSEUtQUFDIEVuY29kZXIgKioqKioqKioqKioqKioqKioqKioqKioqKgoKICBJbml0aWFsIGF1dGhvcjogICAgICAgTS4gTG9od2Fzc2VyCiAgY29udGVudHMvZGVzY3JpcHRpb246IEZESyBIRS1BQUMgRW5jb2RlciBpbnRlcmZhY2UgbGlicmFyeSBmdW5jdGlvbnMKCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojaW5jbHVkZSAiYWFjZW5jX2xpYi5oIgojaW5jbHVkZSAiRkRLX2F1ZGlvLmgiCiNpbmNsdWRlICJhYWNlbmMuaCIKCiNpbmNsdWRlICJhYWNFbmNfcmFtLmgiCiNpbmNsdWRlICJGREtfY29yZS5oIiAvKiBGREtfdG9vbHMgdmVyc2lvbmluZyBpbmZvICovCgovKiBFbmNvZGVyIGxpYnJhcnkgaW5mbyAqLwojZGVmaW5lIEFBQ0VOQ09ERVJfTElCX1ZMMCAzCiNkZWZpbmUgQUFDRU5DT0RFUl9MSUJfVkwxIDMKI2RlZmluZSBBQUNFTkNPREVSX0xJQl9WTDIgMQojZGVmaW5lIEFBQ0VOQ09ERVJfTElCX1RJVExFICJBQUMgRW5jb2RlciIKI2RlZmluZSBBQUNFTkNPREVSX0xJQl9CVUlMRF9EQVRFIF9fREFURV9fCiNkZWZpbmUgQUFDRU5DT0RFUl9MSUJfQlVJTERfVElNRSBfX1RJTUVfXwoKCiNpbmNsdWRlICJzYnJfZW5jb2Rlci5oIgojaW5jbHVkZSAiLi4vc3JjL3Nicl9yYW0uaCIKI2luY2x1ZGUgImNoYW5uZWxfbWFwLmgiCgojaW5jbHVkZSAicHN5X2NvbnN0LmgiCiNpbmNsdWRlICJiaXRlbmMuaCIKCiNpbmNsdWRlICJ0cGVuY19saWIuaCIKCiNpbmNsdWRlICJtZXRhZGF0YV9tYWluLmgiCgojZGVmaW5lIFNCTChmbCkgICAgICAgICAgICAoZmwvOCkgICAgICAgICAgICAgICAgIC8qITwgU2hvcnQgYmxvY2sgbGVuZ3RoIChoYXJkY29kZWQgdG8gOCBzaG9ydCBibG9ja3MgcGVyIGxvbmcgYmxvY2spICovCiNkZWZpbmUgQlNMQShmbCkgICAgICAgICAgICg0KlNCTChmbCkrU0JMKGZsKS8yKSAgLyohPCBBQUMgYmxvY2sgc3dpdGNoaW5nIGxvb2stYWhlYWQgKi8KI2RlZmluZSBERUxBWV9BQUMoZmwpICAgICAgKGZsK0JTTEEoZmwpKSAgICAgICAgICAvKiE8IE1EQ1QgKyBibG9ja3N3aXRjaGluZyAqLwojZGVmaW5lIERFTEFZX0FBQ0VMRChmbCkgICAoIChmbCkgKyAoKGZsKS8yKSAgKSAgIC8qITwgRUxEIEZCIGRlbGF5ICovCgojZGVmaW5lIElOUFVUQlVGRkVSX1NJWkUgKDE1MzcrMTAwKzIwNDgpCgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KLyoqCiAqIEZsYWdzIHRvIGNoYXJhY3Rlcml6ZSBlbmNvZGVyIG1vZHVsZXMgdG8gYmUgc3VwcG9ydGVkIGluIHByZXNlbnQgaW5zdGFuY2UuCiAqLwplbnVtIHsKICAgIEVOQ19NT0RFX0ZMQUdfQUFDICA9IDB4MDAwMSwKICAgIEVOQ19NT0RFX0ZMQUdfU0JSICA9IDB4MDAwMiwKICAgIEVOQ19NT0RFX0ZMQUdfUFMgICA9IDB4MDAwNCwKICAgIEVOQ19NT0RFX0ZMQUdfU0FDICA9IDB4MDAwOCwKICAgIEVOQ19NT0RFX0ZMQUdfTUVUQSA9IDB4MDAxMAp9OwoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCnR5cGVkZWYgc3RydWN0IHsKICAgIEFVRElPX09CSkVDVF9UWVBFIHVzZXJBT1Q7ICAgICAgICAgICAgICAgLyohPCBBdWRpbyBPYmplY3QgVHlwZS4gICAgICAgICAgICAgKi8KICAgIFVJTlQgICAgICAgICAgICAgIHVzZXJTYW1wbGVyYXRlOyAgICAgICAgLyohPCBTYW1wbGluZyBmcmVxdWVuY3kuICAgICAgICAgICAgKi8KICAgIFVJTlQgICAgICAgICAgICAgIG5DaGFubmVsczsgICAgICAgICAgICAgLyohPCB3aWxsIGJlIHNldCB2aWEgY2hhbm5lbE1vZGUuICAgKi8KICAgIENIQU5ORUxfTU9ERSAgICAgIHVzZXJDaGFubmVsTW9kZTsKICAgIFVJTlQgICAgICAgICAgICAgIHVzZXJCaXRyYXRlOwogICAgVUlOVCAgICAgICAgICAgICAgdXNlckJpdHJhdGVNb2RlOwogICAgVUlOVCAgICAgICAgICAgICAgdXNlckJhbmR3aWR0aDsKICAgIFVJTlQgICAgICAgICAgICAgIHVzZXJBZnRlcmJ1cm5lcjsKICAgIFVJTlQgICAgICAgICAgICAgIHVzZXJGcmFtZWxlbmd0aDsKICAgIFVJTlQgICAgICAgICAgICAgIHVzZXJBbmNEYXRhUmF0ZTsKCiAgICBVQ0hBUiAgICAgICAgICAgICB1c2VyVG5zOyAgICAgICAgICAgICAgIC8qITwgVXNlIFROUyBjb2RpbmcuICovCiAgICBVQ0hBUiAgICAgICAgICAgICB1c2VyUG5zOyAgICAgICAgICAgICAgIC8qITwgVXNlIFBOUyBjb2RpbmcuICovCiAgICBVQ0hBUiAgICAgICAgICAgICB1c2VySW50ZW5zaXR5OyAgICAgICAgIC8qITwgVXNlIEludGVuc2l0eSBjb2RpbmcuICovCgogICAgVFJBTlNQT1JUX1RZUEUgICAgdXNlclRwVHlwZTsgICAgICAgICAgICAvKiE8IFRyYW5zcG9ydCB0eXBlICovCiAgICBVQ0hBUiAgICAgICAgICAgICB1c2VyVHBTaWduYWxpbmc7ICAgICAgIC8qITwgRXh0ZW5zaW9uIEFPVCBzaWduYWxpbmcgbW9kZS4gKi8KICAgIFVDSEFSICAgICAgICAgICAgIHVzZXJUcE5zdWJGcmFtZXM7ICAgICAgLyohPCBOdW1iZXIgb2Ygc3ViIGZyYW1lcyBpbiBhIHRyYW5zcG9ydCBmcmFtZSBmb3IgTE9BUy9MQVRNIG9yIEFEVFMgKGRlZmF1bHQgMSkuICovCiAgICBVQ0hBUiAgICAgICAgICAgICB1c2VyVHBBbXh2OyAgICAgICAgICAgIC8qITwgQXVkaW9NdXhWZXJzaW9uIHRvIGJlIHVzZWQgZm9yIExBVE0gKGRlZmF1bHQgMCkuICovCiAgICBVQ0hBUiAgICAgICAgICAgICB1c2VyVHBQcm90ZWN0aW9uOwogICAgVUNIQVIgICAgICAgICAgICAgdXNlclRwSGVhZGVyUGVyaW9kOyAgICAvKiE8IFBhcmFtZXRlciB1c2VkIHRvIGNvbmZpZ3VyZSBMQVRNL0xPQVMgU01DIHJhdGUuIE1vcmVvdmVyIHRoaXMgcGFyYW1ldGVycyBpcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzZWQgdG8gY29uZmlndXJlIHJlcGV0aXRpb24gcmF0ZSBvZiBQQ0UgaW4gcmF3X2RhdGFfYmxvY2suICovCgogICAgVUNIQVIgICAgICAgICAgICAgdXNlckVyVG9vbHM7ICAgICAgICAgICAvKiE8IFVzZSBWQ0IxMSwgSENSIGFuZC9vciBSVkxDIEVSIHRvb2wuICovCiAgICBVSU5UICAgICAgICAgICAgICB1c2VyUGNlQWRkaXRpb25zOyAgICAgIC8qITwgQ29uZmlndXJlIGFkZGl0aW9uYWwgYml0cyBpbiBQQ0UuICovCgogICAgVUNIQVIgICAgICAgICAgICAgdXNlck1ldGFEYXRhTW9kZTsgICAgICAvKiE8IE1ldGEgZGF0YSBsaWJyYXJ5IGNvbmZpZ3VyYXRpb24uICovCgogICAgVUNIQVIgICAgICAgICAgICAgdXNlclNickVuYWJsZWQ7Cgp9IFVTRVJfUEFSQU07CgovLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0cnVjdHVyZSBEZWZpbml0aW9ucwoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKdHlwZWRlZiBzdHJ1Y3QgIEFBQ0VOQ19DT05GSUcgICAgICpIQU5ETEVfQUFDRU5DX0NPTkZJRzsKCgpzdHJ1Y3QgQUFDRU5DT0RFUgp7CiAgICBVU0VSX1BBUkFNICAgICAgICAgICAgICAgZXh0UGFyYW07CiAgICBDT0RFUl9DT05GSUcgICAgICAgICAgICAgY29kZXJDb25maWc7CgogICAgLyogQUFDICovCiAgICBBQUNFTkNfQ09ORklHICAgICAgICAgICAgYWFjQ29uZmlnOwogICAgSEFORExFX0FBQ19FTkMgICAgICAgICAgIGhBYWNFbmM7CgogICAgLyogU0JSICovCiAgICBIQU5ETEVfU0JSX0VOQ09ERVIgICAgICAgaEVudkVuYzsKCiAgICAvKiBNZXRhIERhdGEgKi8KICAgIEhBTkRMRV9GREtfTUVUQURBVEFfRU5DT0RFUiAgaE1ldGFkYXRhRW5jOwogICAgSU5UICAgICAgICAgICAgICAgICAgICAgICAgICBtZXRhRGF0YUFsbG93ZWQ7IC8qIFNpZ25hbCB3aGV0aGVyIGNob3NlbiBjb25maWd1cmF0aW9uIGFsbG93cyBtZXRhZGF0YS4gTmVjZXNzYXJ5IGZvciBkZWxheQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBlbnNhdGlvbi4gTWV0YWRhdGEgbW9kZSBpcyBhIHNlcGFyYXRlIHBhcmFtZXRlci4gKi8KCiAgICAvKiBUcmFuc3BvcnQgKi8KICAgIEhBTkRMRV9UUkFOU1BPUlRFTkMgICAgICBoVHBFbmM7CgogICAgLyogT3V0cHV0ICovCiAgICBVQ0hBUiAgICAgICAgICAgICAgICAgICAqb3V0QnVmZmVyOyAgICAgICAgIC8qIEludGVybmFsIGJpdHN0cmVhbSBidWZmZXIgKi8KICAgIElOVCAgICAgICAgICAgICAgICAgICAgICBvdXRCdWZmZXJJbkJ5dGVzOyAgIC8qIFNpemUgb2YgaW50ZXJuYWwgYml0c3RyZWFtIGJ1ZmZlciovCgogICAgLyogSW5wdXQgKi8KICAgIElOVF9QQ00gICAgICAgICAgICAgICAgICppbnB1dEJ1ZmZlcjsgICAgICAgIC8qIEludGVybmFsIGlucHV0IGJ1ZmZlci4gSW5wdXQgc291cmNlIGZvciBBQUMgZW5jb2RlciAqLwogICAgSU5UICAgICAgICAgICAgICAgICAgICAgIGlucHV0QnVmZmVyT2Zmc2V0OyAgLyogV2hlcmUgdG8gd3JpdGUgbmV3IGlucHV0IHNhbXBsZXMuICovCgogICAgSU5UICAgICAgICAgICAgICAgICAgICAgIG5TYW1wbGVzVG9SZWFkOyAgICAvKiBudW1iZXIgb2YgaW5wdXQgc2FtcGxlcyBuZWVlZGVkIGZvciBlbmNvZGluZyBvbmUgZnJhbWUgKi8KICAgIElOVCAgICAgICAgICAgICAgICAgICAgICBuU2FtcGxlc1JlYWQ7ICAgICAgLyogbnVtYmVyIG9mIGlucHV0IHNhbXBsZXMgYWxyZWFkeSBpbiBpbnB1dCBidWZmZXIgKi8KICAgIElOVCAgICAgICAgICAgICAgICAgICAgICBuWmVyb3NBcHBlbmRlZDsgICAgLyogYXBwZW5kZWQgemVyb3MgYXQgZW5kIG9mIGZpbGUqLwogICAgSU5UICAgICAgICAgICAgICAgICAgICAgIG5EZWxheTsgICAgICAgICAgICAvKiBlbmNvZGVyIGRlbGF5ICovCgogICAgQUFDRU5DX0VYVF9QQVlMT0FEICAgICAgIGV4dFBheWxvYWQgW01BWF9UT1RBTF9FWFRfUEFZTE9BRFNdOwogICAgLyogRXh0ZW5zaW9uIHBheWxvYWQgKi8KICAgIFVDSEFSICAgICAgICAgICAgICAgICAgICBleHRQYXlsb2FkRGF0YSBbKDEpXVsoNildW01BWF9QQVlMT0FEX1NJWkVdOwogICAgVUlOVCAgICAgICAgICAgICAgICAgICAgIGV4dFBheWxvYWRTaXplIFsoMSldWyg2KV07IC8qIHBheWxvYWQgc2l6ZXMgaW4gYml0cyAqLwoKICAgIFVMT05HICAgICAgICAgICAgICAgICAgICBJbml0RmxhZ3M7ICAgICAgICAgLyogaW50ZXJuYWwgc3RhdHVzIHRvIHRyZWdnaWVyIHJlLWluaXRpYWxpemF0aW9uICovCgoKICAgLyogTWVtb3J5IGFsbG9jYXRpb24gaW5mby4gKi8KICAgSU5UICAgICAgICAgICAgICAgICAgICAgICBuTWF4QWFjRWxlbWVudHM7CiAgIElOVCAgICAgICAgICAgICAgICAgICAgICAgbk1heEFhY0NoYW5uZWxzOwogICBJTlQgICAgICAgICAgICAgICAgICAgICAgIG5NYXhTYnJFbGVtZW50czsKICAgSU5UICAgICAgICAgICAgICAgICAgICAgICBuTWF4U2JyQ2hhbm5lbHM7CiAgIFVJTlQgICAgICAgICAgICAgICAgICAgICAgbk1heFN1YkZyYW1lczsKCiAgIFVJTlQgICAgICAgICAgICAgICAgICAgICAgZW5jb2Rlcl9tb2RpczsKCiAgIC8qIENhcGFiaXR5IGZsYWdzICovCiAgIFVJTlQgICAgICAgICAgICAgICAgICAgICAgQ0FQRl90cEVuYzsKCn0gOwoKLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCgpzdGF0aWMgaW5saW5lIElOVCBpc1NickFjdGl2ZShjb25zdCBIQU5ETEVfQUFDRU5DX0NPTkZJRyBoQWFjQ29uZmlnKQp7CiAgICBJTlQgc2JyVXNlZCA9IDA7CgogICAgaWYgKCAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlPT1BT1RfU0JSKSAgICAgICAgIHx8IChoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGU9PUFPVF9QUykKICAgICAgfHwgKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZT09QU9UX01QMl9TQlIpICAgICB8fCAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlPT1BT1RfTVAyX1BTKQogICAgICB8fCAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlPT1BT1RfREFCUExVU19TQlIpIHx8IChoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGU9PUFPVF9EQUJQTFVTX1BTKQogICAgICB8fCAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlPT1BT1RfRFJNX1NCUikgICAgIHx8IChoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGU9PUFPVF9EUk1fTVBFR19QUykgKQogICAgewogICAgICAgIHNiclVzZWQgPSAxOwogICAgfQogICAgaWYgKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZSA9PSBBT1RfRVJfQUFDX0VMRCAmJiAoaEFhY0NvbmZpZy0+c3ludGF4RmxhZ3MgJiBBQ19TQlJfUFJFU0VOVCkpCiAgICB7CiAgICAgICAgc2JyVXNlZCA9IDE7CiAgICB9CgogICAgcmV0dXJuICggc2JyVXNlZCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQWxsb2NhdGUgRW5jb2RlcgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKSF9BTExPQ19NRU0gKF9BYWNFbmNvZGVyLCBBQUNFTkNPREVSKQpDX0FMTE9DX01FTSAoX0FhY0VuY29kZXIsIEFBQ0VOQ09ERVIsIDEpCgoKCgovKgogKiBNYXAgRW5jb2RlciBzcGVjaWZpYyBjb25maWcgc3RydWN0dXJlcyB0byBDT0RFUl9DT05GSUcuCiAqLwpzdGF0aWMKdm9pZCBGREthYWNFbmNfTWFwQ29uZmlnKENPREVSX0NPTkZJRyAqY2MsIFVTRVJfUEFSQU0gKmV4dENmZywgSEFORExFX0FBQ0VOQ19DT05GSUcgaEFhY0NvbmZpZykKewogIEFVRElPX09CSkVDVF9UWVBFIHRyYW5zcG9ydF9BT1QgPSBBT1RfTlVMTF9PQkpFQ1Q7CiAgRkRLbWVtY2xlYXIoY2MsIHNpemVvZihDT0RFUl9DT05GSUcpKTsKCiAgY2MtPmZsYWdzID0gMDsKCiAgLyogTWFwIHZpcnR1YWwgYW90IHRvIHRyYW5zcG9ydCBhb3QuICovCiAgc3dpdGNoIChoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGUpIHsKICAgIGNhc2UgQU9UX01QMl9BQUNfTEM6CiAgICAgIHRyYW5zcG9ydF9BT1QgPSBBT1RfQUFDX0xDOwogICAgICBicmVhazsKICAgIGNhc2UgQU9UX01QMl9TQlI6CiAgICAgIHRyYW5zcG9ydF9BT1QgPSBBT1RfU0JSOwogICAgICBjYy0+ZmxhZ3MgfD0gQ0NfU0JSOwogICAgIGJyZWFrOwogICAgY2FzZSBBT1RfTVAyX1BTOgogICAgICB0cmFuc3BvcnRfQU9UID0gQU9UX1BTOwogICAgICBjYy0+ZmxhZ3MgfD0gQ0NfU0JSOwogICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIHRyYW5zcG9ydF9BT1QgPSBoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGU7CiAgfQoKICBpZiAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlID09IEFPVF9FUl9BQUNfRUxEKSB7CiAgICBjYy0+ZmxhZ3MgfD0gKGhBYWNDb25maWctPnN5bnRheEZsYWdzICYgQUNfU0JSX1BSRVNFTlQpID8gQ0NfU0JSIDogMDsKICB9CgogIC8qIHRyYW5zcG9ydCB0eXBlIGlzIHVzdWFsbHkgQUFDLUxDLiAqLwogIGlmICggKHRyYW5zcG9ydF9BT1QgPT0gQU9UX1NCUikgfHwgKHRyYW5zcG9ydF9BT1QgPT0gQU9UX1BTKSApIHsKICAgIGNjLT5hb3QgICAgICAgICAgID0gQU9UX0FBQ19MQzsKICB9CiAgZWxzZSB7CiAgICBjYy0+YW90ICAgICAgICAgICA9IHRyYW5zcG9ydF9BT1Q7CiAgfQoKICAvKiBDb25maWd1cmUgZXh0ZW5zaW9uIGFvdC4gKi8KICBpZiAoZXh0Q2ZnLT51c2VyVHBTaWduYWxpbmc9PTApIHsKICAgIGNjLT5leHRBT1QgPSBBT1RfTlVMTF9PQkpFQ1Q7ICAvKiBpbXBsaWNpdCAqLwogIH0KICBlbHNlIHsKICAgIGlmICggKGV4dENmZy0+dXNlclRwU2lnbmFsaW5nPT0xKSAmJiAoICh0cmFuc3BvcnRfQU9UPT1BT1RfU0JSKSB8fCAodHJhbnNwb3J0X0FPVD09QU9UX1BTKSApICkgewogICAgICBjYy0+ZXh0QU9UID0gQU9UX1NCUjsgICAgICAgIC8qIGV4cGxpY2l0IGJhY2t3YXJkIGNvbXBhdGlibGUgKi8KICAgIH0KICAgIGVsc2UgewogICAgICBjYy0+ZXh0QU9UID0gdHJhbnNwb3J0X0FPVDsgIC8qIGV4cGxpY2l0IGhpZXJhcmNoaWNhbCAqLwogICAgfQogIH0KICBjYy0+ZXh0U2FtcGxpbmdSYXRlID0gZXh0Q2ZnLT51c2VyU2FtcGxlcmF0ZTsKICBjYy0+Yml0UmF0ZSAgICAgICAgID0gaEFhY0NvbmZpZy0+Yml0UmF0ZTsKICBjYy0+bm9DaGFubmVscyAgICAgID0gaEFhY0NvbmZpZy0+bkNoYW5uZWxzOwogIGNjLT5mbGFncyAgICAgICAgICB8PSBDQ19JU19CQVNFTEFZRVI7CiAgY2MtPmNoYW5uZWxNb2RlICAgICA9IGhBYWNDb25maWctPmNoYW5uZWxNb2RlOwoKICBjYy0+blN1YkZyYW1lcyA9IChoQWFjQ29uZmlnLT5uU3ViRnJhbWVzID4gMSAmJiBleHRDZmctPnVzZXJUcE5zdWJGcmFtZXMgPT0gMSkKICAgICAgICAgICAgICAgICA/IGhBYWNDb25maWctPm5TdWJGcmFtZXMKICAgICAgICAgICAgICAgICA6IGV4dENmZy0+dXNlclRwTnN1YkZyYW1lczsKCiAgY2MtPmZsYWdzICAgICAgICAgIHw9IChleHRDZmctPnVzZXJUcFByb3RlY3Rpb24pID8gQ0NfUFJPVEVDVElPTiA6IDA7CgogIGlmIChleHRDZmctPnVzZXJUcEhlYWRlclBlcmlvZCE9MHhGRikgewogICAgY2MtPmhlYWRlclBlcmlvZCAgICA9IGV4dENmZy0+dXNlclRwSGVhZGVyUGVyaW9kOwogIH0KICBlbHNlIHsgLyogYXV0by1tb2RlICovCiAgICBzd2l0Y2ggKGV4dENmZy0+dXNlclRwVHlwZSkgewogICAgICBjYXNlIFRUX01QNF9BRFRTOgogICAgICBjYXNlIFRUX01QNF9MT0FTOgogICAgICBjYXNlIFRUX01QNF9MQVRNX01DUDE6CiAgICAgICAgY2MtPmhlYWRlclBlcmlvZCA9IDEwOwogICAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OgogICAgICAgIGNjLT5oZWFkZXJQZXJpb2QgPSAwOwogICAgfQogIH0KCiAgY2MtPnNhbXBsZXNQZXJGcmFtZSA9IGhBYWNDb25maWctPmZyYW1lbGVuZ3RoOwogIGNjLT5zYW1wbGluZ1JhdGUgICAgPSBoQWFjQ29uZmlnLT5zYW1wbGVSYXRlOwoKICAvKiBNcGVnLTQgc2lnbmFsaW5nIGZvciB0cmFuc3BvcnQgbGlicmFyeS4gKi8KICBzd2l0Y2ggKCBoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGUgKSB7CiAgICBjYXNlIEFPVF9NUDJfQUFDX0xDOgogICAgY2FzZSBBT1RfTVAyX1NCUjoKICAgIGNhc2UgQU9UX01QMl9QUzoKICAgICAgY2MtPmZsYWdzICY9IH5DQ19NUEVHX0lEOyAvKiBSZXF1aXJlZCBmb3IgQURUUy4gKi8KICAgICAgLy9jb25maWctPnVzZXJUcFNpZ25hbGluZz0wOwogICAgICBjYy0+ZXh0QU9UID0gQU9UX05VTExfT0JKRUNUOwogICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIGNjLT5mbGFncyB8PSBDQ19NUEVHX0lEOwogIH0KCiAgLyogRVItdG9vbHMgc2lnbmFsaW5nLiAqLwogIGNjLT5mbGFncyAgICAgfD0gKGhBYWNDb25maWctPnN5bnRheEZsYWdzICYgQUNfRVJfVkNCMTEpID8gQ0NfVkNCMTEgOiAwOwogIGNjLT5mbGFncyAgICAgfD0gKGhBYWNDb25maWctPnN5bnRheEZsYWdzICYgQUNfRVJfSENSKSAgID8gQ0NfSENSIDogMDsKICBjYy0+ZmxhZ3MgICAgIHw9IChoQWFjQ29uZmlnLT5zeW50YXhGbGFncyAmIEFDX0VSX1JWTEMpICA/IENDX1JWTEMgOiAwOwoKICAvKiBNYXRyaXggbWl4ZG93biBjb2VmZmljaWVudCBjb25maWd1cmF0aW9uLiAqLwogIGlmICggKGV4dENmZy0+dXNlclBjZUFkZGl0aW9ucyYweDEpICYmIChoQWFjQ29uZmlnLT5lcENvbmZpZz09LTEpCiAgICAgICYmICgoY2MtPmNoYW5uZWxNb2RlPT1NT0RFXzFfMl8yKXx8KGNjLT5jaGFubmVsTW9kZT09TU9ERV8xXzJfMl8xKSkgKQogIHsKICAgIGNjLT5tYXRyaXhNaXhkb3duQSAgICAgICA9ICgoZXh0Q2ZnLT51c2VyUGNlQWRkaXRpb25zPj4xKSYweDMpKzE7CiAgICBjYy0+ZmxhZ3MgfD0gKGV4dENmZy0+dXNlclBjZUFkZGl0aW9ucz4+MykmMHgxID8gQ0NfUFNFVURPX1NVUlJPVU5EIDogMDsKICB9CiAgZWxzZSB7CiAgICBjYy0+bWF0cml4TWl4ZG93bkEgPSAwOwogIH0KfQoKLyoKICogRXhhbWluZSBidWZmZXIgZGVzY3JpcHRvciByZWdhcmRpbmcgY2hvb3NlbiBpZGVudGlmaWVyLgogKgogKiBccGFyYW0gcEJ1ZkRlc2MgICAgICAgICAgICAgIFBvaW50ZXIgdG8gYnVmZmVyIGRlc2NyaXB0b3IKICogXHBhcmFtIGlkZW50aWZpZXIgICAgICAgICAgICBCdWZmZXIgaWRlbnRpZmllciB0byBsb29rIGZvci4KCiAqIFxyZXR1cm4gLSBCdWZmZXIgZGVzY3JpcHRvciBpbmRleC4KICogICAgICAgICAtMSwgaWYgdGhlcmUgaXMgbm8gZW50cnkgYXZhaWxhYmxlLgogKi8Kc3RhdGljIElOVCBnZXRCdWZEZXNjSWR4KAogICAgICAgIGNvbnN0IEFBQ0VOQ19CdWZEZXNjICAgICAgICAgKnBCdWZEZXNjLAogICAgICAgIGNvbnN0IEFBQ0VOQ19CdWZmZXJJZGVudGlmaWVyIGlkZW50aWZpZXIKKQp7CiAgICBJTlQgaSwgaWR4ID0gLTE7CgogICAgZm9yIChpPTA7IGk8cEJ1ZkRlc2MtPm51bUJ1ZnM7IGkrKykgewogICAgICBpZiAoIChBQUNFTkNfQnVmZmVySWRlbnRpZmllcilwQnVmRGVzYy0+YnVmZmVySWRlbnRpZmllcnNbaV0gPT0gaWRlbnRpZmllciApIHsKICAgICAgICBpZHggPSBpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gaWR4Owp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgICAgICAgICAgICAgICAgICAgICAgICBGdW5jdGlvbiBEZWNsYXJhdGlvbnMKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCkFBQ19FTkNPREVSX0VSUk9SIGFhY0VuY0RlZmF1bHRDb25maWcoSEFORExFX0FBQ0VOQ19DT05GSUcgaEFhY0NvbmZpZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVU0VSX1BBUkFNICpjb25maWcpCnsKICAgIC8qIG1ha2UgcmVhc29uYWJsZSBkZWZhdWx0IHNldHRpbmdzICovCiAgICBGREthYWNFbmNfQWFjSW5pdERlZmF1bHRDb25maWcgKGhBYWNDb25maWcpOwoKICAgIC8qIGNsZWFyIGNvbmZ1cmUgc3RydWN0dXJlIGFuZCBjb3B5IGRlZmF1bHQgc2V0dGluZ3MgKi8KICAgIEZES21lbWNsZWFyKGNvbmZpZywgc2l6ZW9mKFVTRVJfUEFSQU0pKTsKCiAgICAvKiBjb3B5IGVuY29kZXIgY29uZmlndXJhdGlvbiBzZXR0aW5ncyAqLwogICAgY29uZmlnLT5uQ2hhbm5lbHMgICAgICAgPSBoQWFjQ29uZmlnLT5uQ2hhbm5lbHM7CiAgICBjb25maWctPnVzZXJBT1QgPSBoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGUgPSBBT1RfQUFDX0xDOwogICAgY29uZmlnLT51c2VyU2FtcGxlcmF0ZSAgPSBoQWFjQ29uZmlnLT5zYW1wbGVSYXRlOwogICAgY29uZmlnLT51c2VyQ2hhbm5lbE1vZGUgPSBoQWFjQ29uZmlnLT5jaGFubmVsTW9kZTsKICAgIGNvbmZpZy0+dXNlckJpdHJhdGUgICAgID0gaEFhY0NvbmZpZy0+Yml0UmF0ZTsKICAgIGNvbmZpZy0+dXNlckJpdHJhdGVNb2RlID0gaEFhY0NvbmZpZy0+Yml0cmF0ZU1vZGU7CiAgICBjb25maWctPnVzZXJCYW5kd2lkdGggICA9IGhBYWNDb25maWctPmJhbmRXaWR0aDsKICAgIGNvbmZpZy0+dXNlclRucyAgICAgICAgID0gaEFhY0NvbmZpZy0+dXNlVG5zOwogICAgY29uZmlnLT51c2VyUG5zICAgICAgICAgPSBoQWFjQ29uZmlnLT51c2VQbnM7CiAgICBjb25maWctPnVzZXJJbnRlbnNpdHkgICA9IGhBYWNDb25maWctPnVzZUlTOwogICAgY29uZmlnLT51c2VyQWZ0ZXJidXJuZXIgPSBoQWFjQ29uZmlnLT51c2VSZXF1YW50OwogICAgY29uZmlnLT51c2VyRnJhbWVsZW5ndGggPSAoVUlOVCktMTsKCiAgICBpZiAoaEFhY0NvbmZpZy0+c3ludGF4RmxhZ3MgJiBBQ19FUl9WQ0IxMSkgewogICAgICBjb25maWctPnVzZXJFclRvb2xzICB8PSAweDAxOwogICAgfQogICAgaWYgKGhBYWNDb25maWctPnN5bnRheEZsYWdzICYgQUNfRVJfSENSKSB7CiAgICAgIGNvbmZpZy0+dXNlckVyVG9vbHMgIHw9IDB4MDI7CiAgICB9CgogICAgLyogaW5pdGlhbGl6ZSB0cmFuc3BvcnQgcGFyYW1ldGVycyAqLwogICAgY29uZmlnLT51c2VyVHBUeXBlICAgICAgICAgPSBUVF9VTktOT1dOOwogICAgY29uZmlnLT51c2VyVHBBbXh2ICAgICAgICAgPSAwOwogICAgY29uZmlnLT51c2VyVHBTaWduYWxpbmcgICAgPSAwOyAgICAvKiBkZWZhdWx0LCBpbXBsaWNpdCBzaWduYWxpbmcgKi8KICAgIGNvbmZpZy0+dXNlclRwTnN1YkZyYW1lcyAgID0gMTsKICAgIGNvbmZpZy0+dXNlclRwUHJvdGVjdGlvbiAgID0gMDsgICAgLyogbm90IGNyYyBwcm90ZWN0ZWQqLwogICAgY29uZmlnLT51c2VyVHBIZWFkZXJQZXJpb2QgPSAweEZGOyAvKiBoZWFkZXIgcGVyaW9kIGluIGF1dG8gbW9kZSAqLwogICAgY29uZmlnLT51c2VyUGNlQWRkaXRpb25zICAgPSAwOyAgICAvKiBubyBtYXRyaXggbWl4ZG93biBjb2VmZmljaWVudCAqLwogICAgY29uZmlnLT51c2VyTWV0YURhdGFNb2RlICAgPSAwOyAgICAvKiBkbyBub3QgZW1iZWQgYW55IG1ldGEgZGF0YSBpbmZvICovCgogICAgY29uZmlnLT51c2VyQW5jRGF0YVJhdGUgICAgPSAwOwoKICAgIHJldHVybiBBQUNfRU5DX09LOwp9CgpzdGF0aWMKdm9pZCBhYWNFbmNEaXN0cmlidXRlU2JyQml0cyhDSEFOTkVMX01BUFBJTkcgKmNoYW5uZWxNYXBwaW5nLCBTQlJfRUxFTUVOVF9JTkZPICpzYnJFbEluZm8sIElOVCBiaXRSYXRlKQp7CiAgSU5UIGNvZGViaXRzID0gYml0UmF0ZTsKICBpbnQgZWw7CgogIC8qIENvcHkgRWxlbWVudCBpbmZvICovCiAgZm9yIChlbD0wOyBlbDxjaGFubmVsTWFwcGluZy0+bkVsZW1lbnRzOyBlbCsrKSB7CiAgICAgIHNickVsSW5mb1tlbF0uQ2hhbm5lbEluZGV4WzBdID0gY2hhbm5lbE1hcHBpbmctPmVsSW5mb1tlbF0uQ2hhbm5lbEluZGV4WzBdOwogICAgICBzYnJFbEluZm9bZWxdLkNoYW5uZWxJbmRleFsxXSA9IGNoYW5uZWxNYXBwaW5nLT5lbEluZm9bZWxdLkNoYW5uZWxJbmRleFsxXTsKICAgICAgc2JyRWxJbmZvW2VsXS5lbFR5cGUgICAgICAgICAgPSBjaGFubmVsTWFwcGluZy0+ZWxJbmZvW2VsXS5lbFR5cGU7CiAgICAgIHNickVsSW5mb1tlbF0uYml0UmF0ZSAgICAgICAgID0gKElOVCkoZk11bHROb3JtKGNoYW5uZWxNYXBwaW5nLT5lbEluZm9bZWxdLnJlbGF0aXZlQml0cywgKEZJWFBfREJMKWJpdFJhdGUpKTsKICAgICAgc2JyRWxJbmZvW2VsXS5pbnN0YW5jZVRhZyAgICAgPSBjaGFubmVsTWFwcGluZy0+ZWxJbmZvW2VsXS5pbnN0YW5jZVRhZzsKICAgICAgc2JyRWxJbmZvW2VsXS5uQ2hhbm5lbHNJbkVsICAgPSBjaGFubmVsTWFwcGluZy0+ZWxJbmZvW2VsXS5uQ2hhbm5lbHNJbkVsOwoKICAgICAgY29kZWJpdHMgLT0gc2JyRWxJbmZvW2VsXS5iaXRSYXRlOwogIH0KICBzYnJFbEluZm9bMF0uYml0UmF0ZSArPSBjb2RlYml0czsKfQoKCnN0YXRpYwpJTlQgYWFjRW5jb2Rlcl9MaW1pdEJpdHJhdGUoCiAgICAgICAgY29uc3QgSEFORExFX1RSQU5TUE9SVEVOQyBoVHBFbmMsCiAgICAgICAgY29uc3QgSU5UIHNhbXBsaW5nUmF0ZSwKICAgICAgICBjb25zdCBJTlQgZnJhbWVMZW5ndGgsCiAgICAgICAgY29uc3QgSU5UIG5DaGFubmVscywKICAgICAgICBjb25zdCBDSEFOTkVMX01PREUgY2hhbm5lbE1vZGUsCiAgICAgICAgSU5UIGJpdFJhdGUsCiAgICAgICAgY29uc3QgSU5UIG5TdWJGcmFtZXMsCiAgICAgICAgY29uc3QgSU5UIHNickFjdGl2ZSwKICAgICAgICBjb25zdCBBVURJT19PQkpFQ1RfVFlQRSBhb3QKICAgICAgICApCnsKICBJTlQgY29yZVNhbXBsaW5nUmF0ZTsKICBDSEFOTkVMX01BUFBJTkcgY207CgogIEZES2FhY0VuY19Jbml0Q2hhbm5lbE1hcHBpbmcoY2hhbm5lbE1vZGUsIENIX09SREVSX01QRUcsICZjbSk7CgogIGlmIChzYnJBY3RpdmUpIHsKICAgIC8qIEFzc3VtZSBTQlIgcmF0ZSByYXRpbyBvZiAyOjEgKi8KICAgIGNvcmVTYW1wbGluZ1JhdGUgPSBzYW1wbGluZ1JhdGUgLyAyOwogIH0gZWxzZSB7CiAgICBjb3JlU2FtcGxpbmdSYXRlID0gc2FtcGxpbmdSYXRlOwogIH0KCiAgLyogQ29uc2lkZXIgYmFuZHdpZHRoIGNoYW5uZWwgYml0IHJhdGUgbGltaXQgKHNlZSBiYW5kd2lkdGguY3BwOiBHZXRCYW5kd2lkdGhFbnRyeSgpKSAqLwogIGlmIChhb3QgPT0gQU9UX0VSX0FBQ19MRCB8fCBhb3QgPT0gQU9UX0VSX0FBQ19FTEQpIHsKICAgIGJpdFJhdGUgPSBGREttaW4oMzYwMDAwKm5DaGFubmVscywgYml0UmF0ZSk7CiAgICBiaXRSYXRlID0gRkRLbWF4KDgwMDAqbkNoYW5uZWxzLCBiaXRSYXRlKTsKICB9CgogIGlmIChhb3QgPT0gQU9UX0FBQ19MQyB8fCBhb3QgPT0gQU9UX1NCUiB8fCBhb3QgPT0gQU9UX1BTKSAgewogICAgYml0UmF0ZSA9IEZES21pbig1NzYwMDAqbkNoYW5uZWxzLCBiaXRSYXRlKTsKICAgIC8qYml0UmF0ZSA9IEZES21heCgwKm5DaGFubmVscywgYml0UmF0ZSk7Ki8KICB9CiAgCgogIC8qIExpbWl0IGJpdCByYXRlIGluIHJlc3BlY3QgdG8gdGhlIGNvcmUgY29kZXIgKi8KICBiaXRSYXRlID0gRkRLYWFjRW5jX0xpbWl0Qml0cmF0ZSgKICAgICAgICAgIGhUcEVuYywKICAgICAgICAgIGNvcmVTYW1wbGluZ1JhdGUsCiAgICAgICAgICBmcmFtZUxlbmd0aCwKICAgICAgICAgIG5DaGFubmVscywKICAgICAgICAgIGNtLm5DaGFubmVsc0VmZiwKICAgICAgICAgIGJpdFJhdGUsCiAgICAgICAgICAtMSwKICAgICAgICAgIE5VTEwsCiAgICAgICAgICAtMSwKICAgICAgICAgIG5TdWJGcmFtZXMKICAgICAgICAgICk7CgogIC8qIExpbWl0IGJpdCByYXRlIGluIHJlc3BlY3QgdG8gYXZhaWxhYmxlIFNCUiBtb2RlcyBpZiBhY3RpdmUgKi8KICBpZiAoc2JyQWN0aXZlKQogIHsKICAgIFNCUl9FTEVNRU5UX0lORk8gc2JyRWxJbmZvWzZdOwogICAgSU5UIHNickJpdFJhdGUgPSAwOwogICAgaW50IGUsIHRvb0JpZz0tMTsKCiAgICBGREtfQVNTRVJUKGNtLm5FbGVtZW50cyA8PSAoNikpOwoKICAgIC8qIEdldCBiaXQgcmF0ZSBmb3IgZWFjaCBTQlIgZWxlbWVudCAqLwogICAgYWFjRW5jRGlzdHJpYnV0ZVNickJpdHMoJmNtLCBzYnJFbEluZm8sIGJpdFJhdGUpOwoKICAgIGZvciAoZT0wOyBlPGNtLm5FbGVtZW50czsgZSsrKQogICAgeyAKICAgICAgSU5UIHNickVsZW1lbnRCaXRSYXRlSW4sIHNickJpdFJhdGVPdXQ7CgogICAgICBpZiAoY20uZWxJbmZvW2VdLmVsVHlwZSAhPSBJRF9TQ0UgJiYgY20uZWxJbmZvW2VdLmVsVHlwZSAhPSBJRF9DUEUpIHsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBzYnJFbGVtZW50Qml0UmF0ZUluID0gc2JyRWxJbmZvW2VdLmJpdFJhdGU7CiAgICAgIHNickJpdFJhdGVPdXQgPSBzYnJFbmNvZGVyX0xpbWl0Qml0UmF0ZShzYnJFbGVtZW50Qml0UmF0ZUluICwgY20uZWxJbmZvW2VdLm5DaGFubmVsc0luRWwsIGNvcmVTYW1wbGluZ1JhdGUsIGFvdCk7CiAgICAgIGlmIChzYnJCaXRSYXRlT3V0ID09IDApIHsKICAgICAgICByZXR1cm4gMDsKICAgICAgfQogICAgICBpZiAoc2JyRWxlbWVudEJpdFJhdGVJbiA8IHNickJpdFJhdGVPdXQpIHsKICAgICAgICBGREtfQVNTRVJUKHRvb0JpZyAhPSAxKTsKICAgICAgICB0b29CaWcgPSAwOwogICAgICAgIGlmIChlID09IDApIHsKICAgICAgICAgIHNickJpdFJhdGUgPSAwOwogICAgICAgIH0KICAgICAgfQogICAgICBpZiAoc2JyRWxlbWVudEJpdFJhdGVJbiA+IHNickJpdFJhdGVPdXQpIHsKICAgICAgICBGREtfQVNTRVJUKHRvb0JpZyAhPSAwKTsKICAgICAgICB0b29CaWcgPSAxOwogICAgICAgIGlmIChlID09IDApIHsKICAgICAgICAgIHNickJpdFJhdGUgPSA1MDAwMDAwOwogICAgICAgIH0KICAgICAgfQogICAgICBpZiAodG9vQmlnICE9IC0xKQogICAgICB7CiAgICAgICAgSU5UIHNickJpdFJhdGVMaW1pdCA9IChJTlQpZkRpdk5vcm0oKEZJWFBfREJMKXNickJpdFJhdGVPdXQsIGNtLmVsSW5mb1tlXS5yZWxhdGl2ZUJpdHMpOwogICAgICAgIGlmICh0b29CaWcpIHsKICAgICAgICAgIHNickJpdFJhdGUgPSBmTWluKHNickJpdFJhdGUsIHNickJpdFJhdGVMaW1pdC0xNik7CiAgICAgICAgICBGREtfQVNTRVJUKCAoSU5UKWZNdWx0Tm9ybShjbS5lbEluZm9bZV0ucmVsYXRpdmVCaXRzLCAoRklYUF9EQkwpc2JyQml0UmF0ZSkgPCBzYnJCaXRSYXRlT3V0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgc2JyQml0UmF0ZSA9IGZNYXgoc2JyQml0UmF0ZSwgc2JyQml0UmF0ZUxpbWl0KzE2KTsKICAgICAgICAgIEZES19BU1NFUlQoIChJTlQpZk11bHROb3JtKGNtLmVsSW5mb1tlXS5yZWxhdGl2ZUJpdHMsIChGSVhQX0RCTClzYnJCaXRSYXRlKSA+PSBzYnJCaXRSYXRlT3V0KTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGlmICh0b29CaWcgIT0gLTEpIHsKICAgICAgYml0UmF0ZSA9IHNickJpdFJhdGU7CiAgICB9CiAgfQoKICBGREtfQVNTRVJUKGJpdFJhdGUgPiAwKTsKCiAgcmV0dXJuIGJpdFJhdGU7Cn0KCi8qCiAqIFxicmllZiBDb25zaXN0ZW5jeSBjaGVjayBvZiBnaXZlbiBVU0VSX1BBUkFNIHN0cnVjdCBhbmQKICogICBjb3B5IGJhY2sgY29uZmlndXJhdGlvbiBmcm9tIHB1YmxpYyBzdHJ1Y3QgaW50byBpbnRlcm5hbAogKiAgIGVuY29kZXIgY29uZmlndXJhdGlvbiBzdHJ1Y3QuCiAqCiAqIFxoQWFjRW5jb2RlciBJbnRlcm5hbCBlbmNvZGVyIGNvbmZpZyB3aGljaCBpcyB0byBiZSB1cGRhdGVkCiAqIFxwYXJhbSBjb25maWcgVXNlciBwcm92aWRlZCBjb25maWcgKHB1YmxpYyBzdHJ1Y3QpCiAqIFxyZXR1cm4gtHJldHVybnMgYWx3YXlzIEFBQ19FTkNfT0sKICovCnN0YXRpYwpBQUNFTkNfRVJST1IgRkRLYWFjRW5jX0FkanVzdEVuY1NldHRpbmdzKEhBTkRMRV9BQUNFTkNPREVSIGhBYWNFbmNvZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVTRVJfUEFSQU0gKmNvbmZpZykKewogICAgQUFDRU5DX0VSUk9SIGVyciA9IEFBQ0VOQ19PSzsKCiAgICAvKiBHZXQgc3RydWN0IHBvaW50ZXJzLiAqLwogICAgSEFORExFX0FBQ0VOQ19DT05GSUcgICAgaEFhY0NvbmZpZyA9ICZoQWFjRW5jb2Rlci0+YWFjQ29uZmlnOwoKICAgIGhBYWNDb25maWctPm5DaGFubmVscyAgICAgICA9IGNvbmZpZy0+bkNoYW5uZWxzOwoKICAgIC8qIEVuY29kZXIgc2V0dGluZ3MgdXBkYXRlLiAqLwogICAgaEFhY0NvbmZpZy0+c2FtcGxlUmF0ZSAgICAgID0gY29uZmlnLT51c2VyU2FtcGxlcmF0ZTsKICAgIGhBYWNDb25maWctPnVzZVRucyAgICAgICAgICA9IGNvbmZpZy0+dXNlclRuczsKICAgIGhBYWNDb25maWctPnVzZVBucyAgICAgICAgICA9IGNvbmZpZy0+dXNlclBuczsKICAgIGhBYWNDb25maWctPnVzZUlTICAgICAgICAgICA9IGNvbmZpZy0+dXNlckludGVuc2l0eTsKICAgIGhBYWNDb25maWctPmJpdFJhdGUgICAgICAgICA9IGNvbmZpZy0+dXNlckJpdHJhdGU7CiAgICBoQWFjQ29uZmlnLT5jaGFubmVsTW9kZSAgICAgPSBjb25maWctPnVzZXJDaGFubmVsTW9kZTsKICAgIGhBYWNDb25maWctPmJpdHJhdGVNb2RlICAgICA9IGNvbmZpZy0+dXNlckJpdHJhdGVNb2RlOwogICAgaEFhY0NvbmZpZy0+YmFuZFdpZHRoICAgICAgID0gY29uZmlnLT51c2VyQmFuZHdpZHRoOwogICAgaEFhY0NvbmZpZy0+dXNlUmVxdWFudCAgICAgID0gY29uZmlnLT51c2VyQWZ0ZXJidXJuZXI7CgogICAgaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlID0gY29uZmlnLT51c2VyQU9UOwogICAgaEFhY0NvbmZpZy0+YW5jX1JhdGUgICAgICAgID0gY29uZmlnLT51c2VyQW5jRGF0YVJhdGU7CiAgICBoQWFjQ29uZmlnLT5zeW50YXhGbGFncyAgICAgPSAwOwogICAgaEFhY0NvbmZpZy0+ZXBDb25maWcgICAgICAgID0gLTE7CgogICAgLyogQWRhcHQgaW50ZXJuYWwgQU9UIHdoZW4gbmVjZXNzYXJ5LiAqLwogICAgc3dpdGNoICggaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlICkgewogICAgICBjYXNlIEFPVF9NUDJfQUFDX0xDOgogICAgICBjYXNlIEFPVF9NUDJfU0JSOgogICAgICBjYXNlIEFPVF9NUDJfUFM6CiAgICAgICAgICBoQWFjQ29uZmlnLT51c2VQbnMgPSAwOwogICAgICAgICAgaWYgKGNvbmZpZy0+dXNlclRwU2lnbmFsaW5nIT0wKSB7CiAgICAgICAgICAgIHJldHVybiBBQUNFTkNfSU5WQUxJRF9DT05GSUc7IC8qIG9ubHkgaW1wbGljaXQgc2lnbmFsaW5nIGFsbG93ZWQgKi8KICAgICAgICAgIH0KICAgICAgY2FzZSBBT1RfQUFDX0xDOgogICAgICBjYXNlIEFPVF9TQlI6CiAgICAgIGNhc2UgQU9UX1BTOgogICAgICAgICAgY29uZmlnLT51c2VyVHBUeXBlID0gKGNvbmZpZy0+dXNlclRwVHlwZSE9VFRfVU5LTk9XTikgPyBjb25maWctPnVzZXJUcFR5cGUgOiBUVF9NUDRfQURUUzsKICAgICAgICAgIGhBYWNDb25maWctPmZyYW1lbGVuZ3RoID0gKGNvbmZpZy0+dXNlckZyYW1lbGVuZ3RoIT0oVUlOVCktMSkgPyBjb25maWctPnVzZXJGcmFtZWxlbmd0aCA6IDEwMjQ7CiAgICAgICAgICBpZiAoaEFhY0NvbmZpZy0+ZnJhbWVsZW5ndGggIT0gMTAyNCAmJiBoQWFjQ29uZmlnLT5mcmFtZWxlbmd0aCAhPSA5NjApIHsKICAgICAgICAgICAgcmV0dXJuIEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgIH0KICAgICAgICAgIGJyZWFrOwogICAgICBjYXNlIEFPVF9FUl9BQUNfTEM6CiAgICAgICAgICBoQWFjQ29uZmlnLT5lcENvbmZpZyA9IDA7CiAgICAgICAgICBoQWFjQ29uZmlnLT5zeW50YXhGbGFncyB8PSBBQ19FUjsKICAgICAgICAgIGhBYWNDb25maWctPnN5bnRheEZsYWdzIHw9ICgoY29uZmlnLT51c2VyRXJUb29scyAmIDB4MSkgPyBBQ19FUl9WQ0IxMSA6IDApOwogICAgICAgICAgaEFhY0NvbmZpZy0+c3ludGF4RmxhZ3MgfD0gKChjb25maWctPnVzZXJFclRvb2xzICYgMHgyKSA/IEFDX0VSX0hDUiA6IDApOwogICAgICAgICAgY29uZmlnLT51c2VyVHBUeXBlID0gKGNvbmZpZy0+dXNlclRwVHlwZSE9VFRfVU5LTk9XTikgPyBjb25maWctPnVzZXJUcFR5cGUgOiBUVF9NUDRfTE9BUzsKICAgICAgICAgIGhBYWNDb25maWctPmZyYW1lbGVuZ3RoID0gKGNvbmZpZy0+dXNlckZyYW1lbGVuZ3RoIT0oVUlOVCktMSkgPyBjb25maWctPnVzZXJGcmFtZWxlbmd0aCA6IDEwMjQ7CiAgICAgICAgICBpZiAoaEFhY0NvbmZpZy0+ZnJhbWVsZW5ndGggIT0gMTAyNCAmJiBoQWFjQ29uZmlnLT5mcmFtZWxlbmd0aCAhPSA5NjApIHsKICAgICAgICAgICAgcmV0dXJuIEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgIH0KICAgICAgICAgIGJyZWFrOwogICAgICBjYXNlIEFPVF9FUl9BQUNfTEQ6CiAgICAgICAgICBoQWFjQ29uZmlnLT5lcENvbmZpZyA9IDA7CiAgICAgICAgICBoQWFjQ29uZmlnLT5zeW50YXhGbGFncyB8PSBBQ19FUnxBQ19MRDsKICAgICAgICAgIGhBYWNDb25maWctPnN5bnRheEZsYWdzIHw9ICgoY29uZmlnLT51c2VyRXJUb29scyAmIDB4MSkgPyBBQ19FUl9WQ0IxMSA6IDApOwogICAgICAgICAgaEFhY0NvbmZpZy0+c3ludGF4RmxhZ3MgfD0gKChjb25maWctPnVzZXJFclRvb2xzICYgMHgyKSA/IEFDX0VSX0hDUiA6IDApOwogICAgICAgICAgaEFhY0NvbmZpZy0+c3ludGF4RmxhZ3MgfD0gKChjb25maWctPnVzZXJFclRvb2xzICYgMHg0KSA/IEFDX0VSX1JWTEMgOiAwKTsKICAgICAgICAgIGNvbmZpZy0+dXNlclRwVHlwZSA9IChjb25maWctPnVzZXJUcFR5cGUhPVRUX1VOS05PV04pID8gY29uZmlnLT51c2VyVHBUeXBlIDogVFRfTVA0X0xPQVM7CiAgICAgICAgICBoQWFjQ29uZmlnLT5mcmFtZWxlbmd0aCA9IChjb25maWctPnVzZXJGcmFtZWxlbmd0aCE9KFVJTlQpLTEpID8gY29uZmlnLT51c2VyRnJhbWVsZW5ndGggOiA1MTI7CiAgICAgICAgICBpZiAoaEFhY0NvbmZpZy0+ZnJhbWVsZW5ndGggIT0gNTEyICYmIGhBYWNDb25maWctPmZyYW1lbGVuZ3RoICE9IDQ4MCkgewogICAgICAgICAgICByZXR1cm4gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgfQogICAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgQU9UX0VSX0FBQ19FTEQ6CiAgICAgICAgICBoQWFjQ29uZmlnLT5lcENvbmZpZyA9IDA7CiAgICAgICAgICBoQWFjQ29uZmlnLT5zeW50YXhGbGFncyB8PSBBQ19FUnxBQ19FTEQ7CiAgICAgICAgICBoQWFjQ29uZmlnLT5zeW50YXhGbGFncyB8PSAoKGNvbmZpZy0+dXNlckVyVG9vbHMgJiAweDEpID8gQUNfRVJfVkNCMTEgOiAwKTsKICAgICAgICAgIGhBYWNDb25maWctPnN5bnRheEZsYWdzIHw9ICgoY29uZmlnLT51c2VyRXJUb29scyAmIDB4MikgPyBBQ19FUl9IQ1IgOiAwKTsKICAgICAgICAgIGhBYWNDb25maWctPnN5bnRheEZsYWdzIHw9ICgoY29uZmlnLT51c2VyRXJUb29scyAmIDB4NCkgPyBBQ19FUl9SVkxDIDogMCk7CiAgICAgICAgICBoQWFjQ29uZmlnLT5zeW50YXhGbGFncyB8PSAoKGNvbmZpZy0+dXNlclNickVuYWJsZWQpICAgID8gQUNfU0JSX1BSRVNFTlQgOiAwKTsKICAgICAgICAgIGNvbmZpZy0+dXNlclRwVHlwZSA9IChjb25maWctPnVzZXJUcFR5cGUhPVRUX1VOS05PV04pID8gY29uZmlnLT51c2VyVHBUeXBlIDogVFRfTVA0X0xPQVM7CiAgICAgICAgICBoQWFjQ29uZmlnLT5mcmFtZWxlbmd0aCA9IChjb25maWctPnVzZXJGcmFtZWxlbmd0aCE9KFVJTlQpLTEpID8gY29uZmlnLT51c2VyRnJhbWVsZW5ndGggOiA1MTI7CiAgICAgICAgICBpZiAoaEFhY0NvbmZpZy0+ZnJhbWVsZW5ndGggIT0gNTEyICYmIGhBYWNDb25maWctPmZyYW1lbGVuZ3RoICE9IDQ4MCkgewogICAgICAgICAgICByZXR1cm4gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgfQogICAgICAgICAgYnJlYWs7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgICBicmVhazsKICAgIH0KCiAgICAvKiBXZSBuZWVkIHRoZSBmcmFtZSBsZW5ndGggdG8gY2FsbCBhYWNFbmNvZGVyX0xpbWl0Qml0cmF0ZSgpICovCiAgICBoQWFjQ29uZmlnLT5iaXRSYXRlID0gYWFjRW5jb2Rlcl9MaW1pdEJpdHJhdGUoCiAgICAgICAgICAgICAgTlVMTCwKICAgICAgICAgICAgICBoQWFjQ29uZmlnLT5zYW1wbGVSYXRlLAogICAgICAgICAgICAgIGhBYWNDb25maWctPmZyYW1lbGVuZ3RoLAogICAgICAgICAgICAgIGhBYWNDb25maWctPm5DaGFubmVscywKICAgICAgICAgICAgICBoQWFjQ29uZmlnLT5jaGFubmVsTW9kZSwKICAgICAgICAgICAgICBjb25maWctPnVzZXJCaXRyYXRlLAogICAgICAgICAgICAgIGhBYWNDb25maWctPm5TdWJGcmFtZXMsCiAgICAgICAgICAgICAgaXNTYnJBY3RpdmUoaEFhY0NvbmZpZyksCiAgICAgICAgICAgICAgaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlCiAgICAgICAgICAgICAgKTsKCiAgICBzd2l0Y2ggKCBoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGUgKSB7CiAgICAgIGNhc2UgQU9UX0VSX0FBQ19MRDoKICAgICAgY2FzZSBBT1RfRVJfQUFDX0VMRDoKICAgICAgICBpZiAoY29uZmlnLT51c2VyQml0cmF0ZU1vZGU9PTgpIHsKICAgICAgICAgIGhBYWNDb25maWctPmJpdHJhdGVNb2RlID0gMDsKICAgICAgICB9CiAgICAgICAgaWYgKGNvbmZpZy0+dXNlckJpdHJhdGVNb2RlPT0wKSB7CiAgICAgICAgICBoQWFjQ29uZmlnLT5iaXRyZXNlcnZvaXIgPSA1MCpjb25maWctPm5DaGFubmVsczsgLyogZGVmYXVsdCwgcmVkdWNlZCBiaXRyZXNlcnZvaXIgKi8KICAgICAgICB9CiAgICAgICAgaWYgKGhBYWNDb25maWctPmJpdHJhdGVNb2RlIT0wKSB7CiAgICAgICAgICByZXR1cm4gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgZGVmYXVsdDoKICAgICAgICBicmVhazsKICAgIH0KCiAgICBpZiAoaEFhY0NvbmZpZy0+ZXBDb25maWcgPj0gMCkgewogICAgICAgIGhBYWNDb25maWctPnN5bnRheEZsYWdzIHw9IEFDX0VSOwogICAgICAgICBpZiAoKChJTlQpaEFhY0NvbmZpZy0+Y2hhbm5lbE1vZGUgPCAxKSB8fCAoKElOVCloQWFjQ29uZmlnLT5jaGFubmVsTW9kZSA+IDcpKSB7CiAgICAgICAgICAgcmV0dXJuIEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsgICAgICAgIC8qIENhbm5lbCBjb25maWcgMCBub3Qgc3VwcG9ydGVkLiAqLwogICAgICAgICB9CiAgICB9CgogICAgaWYgKCBGREthYWNFbmNfRGV0ZXJtaW5lRW5jb2Rlck1vZGUoJmhBYWNDb25maWctPmNoYW5uZWxNb2RlLCBoQWFjQ29uZmlnLT5uQ2hhbm5lbHMpICE9IEFBQ19FTkNfT0spIHsKICAgICAgICByZXR1cm4gQUFDRU5DX0lOVkFMSURfQ09ORklHOyAgICAgICAgLyogbkNoYW5uZWxzIGRvZXNuJ3QgbWF0Y2ggY2hNb2RlLCB0aGlzIGlzIGp1c3QgYSBjaGVjay11cCAqLwogICAgfQoKICAgIGlmICggKGhBYWNDb25maWctPm5DaGFubmVscyA+IGhBYWNFbmNvZGVyLT5uTWF4QWFjQ2hhbm5lbHMpCiAgICAgIHx8ICggKEZES2FhY0VuY19HZXRDaGFubmVsTW9kZUNvbmZpZ3VyYXRpb24oaEFhY0NvbmZpZy0+Y2hhbm5lbE1vZGUpLT5uQ2hhbm5lbHNFZmYgPiBoQWFjRW5jb2Rlci0+bk1heFNickNoYW5uZWxzKSAmJgogICAgICAgICAgICBpc1NickFjdGl2ZShoQWFjQ29uZmlnKSApCiAgICAgICAgICkKICAgIHsKICAgICAgICByZXR1cm4gQUFDRU5DX0lOVkFMSURfQ09ORklHOyAgICAgIC8qIG5vdCBlbm91Z2ggY2hhbm5lbHMgYWxsb2NhdGVkICovCiAgICB9CgogICAgLyogZ2V0IGJpdHJhdGUgaW4gVkJSIGNvbmZpZ3VyYXRpb24gKi8KICAgIGlmICggKGhBYWNDb25maWctPmJpdHJhdGVNb2RlPj0xKSAmJiAoaEFhY0NvbmZpZy0+Yml0cmF0ZU1vZGU8PTUpICkgewogICAgICAgIC8qIEluIFZCUiBtb2RlOyBTQlItbW9kdWwgZGVwZW5kcyBvbiBiaXRyYXRlLCBjb3JlIGVuY29kZXIgb24gYml0cmF0ZU1vZGUuICovCiAgICAgICAgaEFhY0NvbmZpZy0+Yml0UmF0ZSA9IEZES2FhY0VuY19HZXRWQlJCaXRyYXRlKGhBYWNDb25maWctPmJpdHJhdGVNb2RlLCBoQWFjQ29uZmlnLT5jaGFubmVsTW9kZSk7CiAgICB9CgoKCiAgICAvKiBTZXQgZGVmYXVsdCBiaXRyYXRlIGlmIG5vIGV4dGVybmFsIGJpdHJhdGUgZGVjbGFyZWQuICovCiAgICBpZiAoaEFhY0NvbmZpZy0+Yml0UmF0ZT09LTEpIHsKICAgICAgICBJTlQgYml0cmF0ZSA9IEZES2FhY0VuY19HZXRDaGFubmVsTW9kZUNvbmZpZ3VyYXRpb24oaEFhY0NvbmZpZy0+Y2hhbm5lbE1vZGUpLT5uQ2hhbm5lbHNFZmYgKiBoQWFjQ29uZmlnLT5zYW1wbGVSYXRlOwogICAgICAgIHN3aXRjaCAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlKQogICAgICAgIHsKICAgICAgICAgICAgY2FzZSBBT1RfQUFDX0xDOgogICAgICAgICAgICAgICAgaEFhY0NvbmZpZy0+Yml0UmF0ZSA9IGJpdHJhdGUgKyAoYml0cmF0ZT4+MSk7ICAgICAgICAvKiAxLjUgYml0cyBwZXIgc2FtcGxlICovCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBBT1RfU0JSOgogICAgICAgICAgICAgICAgaEFhY0NvbmZpZy0+Yml0UmF0ZSA9IChiaXRyYXRlICsgKGJpdHJhdGU+PjIpKT4+MTsgICAvKiAwLjYyNSBiaXRzIHBlciBzYW1wbGUgKi8KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIEFPVF9QUzoKICAgICAgICAgICAgICAgIGhBYWNDb25maWctPmJpdFJhdGUgPSAoYml0cmF0ZT4+MSk7ICAgICAgICAgICAgICAgICAgLyogMC41IGJpdCBwZXIgc2FtcGxlICovCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIGhBYWNDb25maWctPmJpdFJhdGUgPSBiaXRyYXRlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIC8qIENvbmZpZ3VyZSBQTlMgKi8KICAgIGlmICggKChoQWFjQ29uZmlnLT5iaXRyYXRlTW9kZT49MSkgJiYgKGhBYWNDb25maWctPmJpdHJhdGVNb2RlPD01KSkgLyogVkJSIHdpdGhvdXQgUE5TLiAqLwogICAgICAgIHx8IChoQWFjQ29uZmlnLT51c2VUbnMgPT0gMCkgKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBUTlMgcmVxdWlyZWQuICovCiAgICB7CiAgICAgICAgaEFhY0NvbmZpZy0+dXNlUG5zID0gMDsKICAgIH0KCiAgICAvKiBNZXRhIGRhdGEgcmVzdHJpY3Rpb24uICovCiAgICBzd2l0Y2ggKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZSkKICAgIHsKICAgICAgLyogQWxsb3cgbWV0YWRhdGEgc3VwcG9ydCAqLwogICAgICBjYXNlIEFPVF9BQUNfTEM6CiAgICAgIGNhc2UgQU9UX1NCUjoKICAgICAgICBoQWFjRW5jb2Rlci0+bWV0YURhdGFBbGxvd2VkID0gMTsKICAgICAgICBpZiAoKChJTlQpaEFhY0NvbmZpZy0+Y2hhbm5lbE1vZGUgPCAxKSB8fCAoKElOVCloQWFjQ29uZmlnLT5jaGFubmVsTW9kZSA+IDcpKSB7CiAgICAgICAgICBjb25maWctPnVzZXJNZXRhRGF0YU1vZGUgPSAwOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgLyogUHJvaGliaXQgbWV0YWRhdGEgc3VwcG9ydCAqLwogICAgICBkZWZhdWx0OgogICAgICAgIGhBYWNFbmNvZGVyLT5tZXRhRGF0YUFsbG93ZWQgPSAwOwogICAgfQoKICAgIHJldHVybiBlcnI7Cn0KCnN0YXRpYwpJTlQgYWFjZW5jX1NickNhbGxiYWNrKAogICAgICAgIHZvaWQgKiAgICAgICAgICAgICAgICAgIHNlbGYsCiAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gICAgaEJzLAogICAgICAgIGNvbnN0IElOVCBzYW1wbGVSYXRlSW4sCiAgICAgICAgY29uc3QgSU5UIHNhbXBsZVJhdGVPdXQsCiAgICAgICAgY29uc3QgSU5UIHNhbXBsZXNQZXJGcmFtZSwKICAgICAgICBjb25zdCBBVURJT19PQkpFQ1RfVFlQRSBjb3JlQ29kZWMsCiAgICAgICAgY29uc3QgTVA0X0VMRU1FTlRfSUQgICAgZWxlbWVudElELAogICAgICAgIGNvbnN0IElOVCAgICAgICAgICAgICAgIGVsZW1lbnRJbmRleAogICAgICAgICkKewogIEhBTkRMRV9BQUNFTkNPREVSIGhBYWNFbmNvZGVyID0gKEhBTkRMRV9BQUNFTkNPREVSKXNlbGY7CgogIHNickVuY29kZXJfR2V0SGVhZGVyKGhBYWNFbmNvZGVyLT5oRW52RW5jLCBoQnMsIGVsZW1lbnRJbmRleCwgMCk7CgogIHJldHVybiAwOwp9CgpzdGF0aWMgQUFDRU5DX0VSUk9SIGFhY0VuY0luaXQoSEFORExFX0FBQ0VOQ09ERVIgIGhBYWNFbmNvZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUxPTkcgICAgICAgICAgICAgIEluaXRGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVTRVJfUEFSQU0gICAgICAgICpjb25maWcpCnsKICAgIEFBQ0VOQ19FUlJPUiBlcnIgPSBBQUNFTkNfT0s7CgogICAgSU5UIGFhY0J1ZmZlck9mZnNldCA9IDA7CiAgICBIQU5ETEVfU0JSX0VOQ09ERVIgICAgICpoU2JyRW5jb2RlciA9ICZoQWFjRW5jb2Rlci0+aEVudkVuYzsKICAgIEhBTkRMRV9BQUNFTkNfQ09ORklHICAgIGhBYWNDb25maWcgID0gJmhBYWNFbmNvZGVyLT5hYWNDb25maWc7CgogICAgaEFhY0VuY29kZXItPm5aZXJvc0FwcGVuZGVkID0gMDsgICAgICAgICAgLyogY291bnQgYXBwZW5kZWQgemVyb3MgKi8KCiAgICBJTlQgZnJhbWVMZW5ndGggPSBoQWFjQ29uZmlnLT5mcmFtZWxlbmd0aDsKCiAgICBpZiAoIChJbml0RmxhZ3MgJiBBQUNFTkNfSU5JVF9DT05GSUcpICkKICAgIHsKICAgICAgICBDSEFOTkVMX01PREUgcHJldkNoTW9kZSA9IGhBYWNDb25maWctPmNoYW5uZWxNb2RlOwoKICAgICAgICAvKiBWZXJpZnkgc2V0dGluZ3MgYW5kIHVwZGF0ZTogY29uZmlnIC0+IGhlQWFjRW5jb2RlciAqLwogICAgICAgIGlmICggKGVycj1GREthYWNFbmNfQWRqdXN0RW5jU2V0dGluZ3MoaEFhY0VuY29kZXIsIGNvbmZpZykpICE9IEFBQ0VOQ19PSyApIHsKICAgICAgICAgICAgcmV0dXJuIGVycjsKICAgICAgICB9CiAgICAgICAgZnJhbWVMZW5ndGggPSBoQWFjQ29uZmlnLT5mcmFtZWxlbmd0aDsgLyogYWRhcHQgdGVtcG9yYWwgZnJhbWVsZW5ndGggKi8KCiAgICAgICAgLyogU2VhbWxlc3MgY2hhbm5lbCByZWNvbmZpZ3VyYXRpb24gaW4gc2JyIG5vdCBmdWxseSBpbXBsZW1lbnRlZCAqLwogICAgICAgIGlmICggKHByZXZDaE1vZGUhPWhBYWNDb25maWctPmNoYW5uZWxNb2RlKSAmJiBpc1NickFjdGl2ZShoQWFjQ29uZmlnKSApIHsKICAgICAgICAgICAgSW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX1NUQVRFUzsKICAgICAgICB9CiAgICB9CgogICAgLyogQ2xlYXIgaW5wdXQgYnVmZmVyICovCiAgICBpZiAoIChJbml0RmxhZ3MgPT0gQUFDRU5DX0lOSVRfQUxMKSApIHsKICAgICAgICBGREttZW1jbGVhcihoQWFjRW5jb2Rlci0+aW5wdXRCdWZmZXIsIHNpemVvZihJTlRfUENNKSpoQWFjRW5jb2Rlci0+bk1heEFhY0NoYW5uZWxzKklOUFVUQlVGRkVSX1NJWkUpOwogICAgfQoKICAgIGlmICggKEluaXRGbGFncyAmIEFBQ0VOQ19JTklUX0NPTkZJRykgKQogICAgewogICAgICAgIGFhY0J1ZmZlck9mZnNldCA9IDA7CiAgICAgICAgaWYgKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZSA9PSBBT1RfRVJfQUFDX0VMRCkgewogICAgICAgICAgICBoQWFjRW5jb2Rlci0+bkRlbGF5ID0gREVMQVlfQUFDRUxEKGhBYWNDb25maWctPmZyYW1lbGVuZ3RoKTsKICAgICAgICB9IGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5uRGVsYXkgPSBERUxBWV9BQUMoaEFhY0NvbmZpZy0+ZnJhbWVsZW5ndGgpOyAvKiBBQUMgZW5jb2RlciBkZWxheSAqLwogICAgICAgIH0KICAgICAgICBoQWFjQ29uZmlnLT5hbmNEYXRhQml0UmF0ZSA9IDA7CiAgICB9CgogICAgaWYgKCBpc1NickFjdGl2ZShoQWFjQ29uZmlnKSAmJgogICAgICAgICgoSW5pdEZsYWdzICYgQUFDRU5DX0lOSVRfQ09ORklHKSB8fCAoSW5pdEZsYWdzICYgQUFDRU5DX0lOSVRfU1RBVEVTKSkgKQogICAgewogICAgICAgIElOVCBzYnJFcnJvcjsKICAgICAgICBTQlJfRUxFTUVOVF9JTkZPIHNickVsSW5mb1soNildOwogICAgICAgIENIQU5ORUxfTUFQUElORyBjaGFubmVsTWFwcGluZzsKICAgICAgICAKICAgICAgICBBVURJT19PQkpFQ1RfVFlQRSBhb3QgPSBoQWFjQ29uZmlnLT5hdWRpb09iamVjdFR5cGU7CgogICAgICAgIGlmICggRkRLYWFjRW5jX0luaXRDaGFubmVsTWFwcGluZyhoQWFjQ29uZmlnLT5jaGFubmVsTW9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0NvbmZpZy0+Y2hhbm5lbE9yZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjaGFubmVsTWFwcGluZykgIT0gQUFDX0VOQ19PSyApCiAgICAgICAgewogICAgICAgICAgICByZXR1cm4gQUFDRU5DX0lOSVRfRVJST1I7CiAgICAgICAgfQoKICAgICAgICAvKiBDaGVjayByZXR1cm4gdmFsdWUgYW5kIGlmIHRoZSBTQlIgZW5jb2RlciBjYW4gaGFuZGxlIGVub3VnaCBlbGVtZW50cyAqLwogICAgICAgIGlmIChjaGFubmVsTWFwcGluZy5uRWxlbWVudHMgPiAoNikpIHsKICAgICAgICAgICAgcmV0dXJuIEFBQ0VOQ19JTklUX0VSUk9SOwogICAgICAgIH0KCiAgICAgICAgYWFjRW5jRGlzdHJpYnV0ZVNickJpdHMoJmNoYW5uZWxNYXBwaW5nLCBzYnJFbEluZm8sIGhBYWNDb25maWctPmJpdFJhdGUpOwoKICAgICAgICBVSU5UIGluaXRGbGFnID0gMDsKICAgICAgICBpbml0RmxhZyArPSAoSW5pdEZsYWdzICYgQUFDRU5DX0lOSVRfU1RBVEVTKSA/IDEgOiAwOwoKICAgICAgICAvKiBMZXQgdGhlIFNCUiBlbmNvZGVyIHRha2UgYSBsb29rIGF0IHRoZSBjb25maWd1cmF0aW9uIGFuZCBjaGFuZ2UgaWYgcmVxdWlyZWQuICovCiAgICAgICAgc2JyRXJyb3IgPSBzYnJFbmNvZGVyX0luaXQoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKmhTYnJFbmNvZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYnJFbEluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxNYXBwaW5nLm5FbGVtZW50cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPmlucHV0QnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZoQWFjQ29uZmlnLT5iYW5kV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmFhY0J1ZmZlck9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmaEFhY0NvbmZpZy0+bkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZoQWFjQ29uZmlnLT5zYW1wbGVSYXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZmcmFtZUxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZoQWFjRW5jb2Rlci0+bkRlbGF5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaEFhY0NvbmZpZy0+YXVkaW9PYmplY3RUeXBlID09IEFPVF9FUl9BQUNfRUxEKSA/IDEgOiBUUkFOU19GQUMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluaXRGbGFnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTsKCiAgICAgICAgLyogU3VwcHJlc3MgQU9UIHJlY29uZmlndXJhdGlvbiBhbmQgY2hlY2sgZXJyb3Igc3RhdHVzLiAqLwogICAgICAgIGlmICggc2JyRXJyb3IgfHwgKGhBYWNDb25maWctPmF1ZGlvT2JqZWN0VHlwZSE9YW90KSApIHsKICAgICAgICAgICAgcmV0dXJuIEFBQ0VOQ19JTklUX1NCUl9FUlJPUjsKICAgICAgICB9CgogICAgICAgIGlmIChoQWFjQ29uZmlnLT5uQ2hhbm5lbHMgPT0gMSkgewogICAgICAgICAgICBoQWFjQ29uZmlnLT5jaGFubmVsTW9kZSA9IE1PREVfMTsKICAgICAgICB9CgogICAgICAgIC8qIE5ldmVyIHVzZSBQTlMgaWYgU0JSIGlzIGFjdGl2ZSAqLwogICAgICAgIGlmICggaEFhY0NvbmZpZy0+dXNlUG5zICkgewogICAgICAgICAgIGhBYWNDb25maWctPnVzZVBucyA9IDA7CiAgICAgICAgfQoKICAgICAgICAvKiBlc3RpbWF0ZWQgYml0cmF0ZSBjb25zdW1lZCBieSBTQlIgb3IgUFMgKi8KICAgICAgICBoQWFjQ29uZmlnLT5hbmNEYXRhQml0UmF0ZSA9IHNickVuY29kZXJfR2V0RXN0aW1hdGVCaXRyYXRlKCpoU2JyRW5jb2RlcikgOwoKICAgIH0gLyogc2JyIGluaXRpYWxpemF0aW9uICovCgoKICAgIC8qCiAgICAgKiBJbml0aWFsaXplIFRyYW5zcG9ydCAtIE1vZHVsZS4KICAgICAqLwogICAgaWYgKCAoSW5pdEZsYWdzICYgQUFDRU5DX0lOSVRfVFJBTlNQT1JUKSApCiAgICB7CiAgICAgICAgVUlOVCBmbGFncyA9IDA7CgogICAgICAgIEZES2FhY0VuY19NYXBDb25maWcoJmhBYWNFbmNvZGVyLT5jb2RlckNvbmZpZywgY29uZmlnLCBoQWFjQ29uZmlnKTsKCiAgICAgICAgLyogY3JlYXRlIGZsYWdzIGZvciB0cmFuc3BvcnQgZW5jb2RlciAqLwogICAgICAgIGlmIChjb25maWctPnVzZXJUcEFteHYgPT0gMSkgewogICAgICAgICAgICBmbGFncyB8PSBUUF9GTEFHX0xBVE1fQU1WOwogICAgICAgIH0KICAgICAgICAvKiBDbGVhciBvdXRwdXQgYnVmZmVyICovCiAgICAgICAgRkRLbWVtY2xlYXIoaEFhY0VuY29kZXItPm91dEJ1ZmZlciwgaEFhY0VuY29kZXItPm91dEJ1ZmZlckluQnl0ZXMqc2l6ZW9mKFVDSEFSKSk7CgogICAgICAgIC8qIEluaXRpYWxpemUgQml0c3RyZWFtIGVuY29kZXIgKi8KICAgICAgICBpZiAoIHRyYW5zcG9ydEVuY19Jbml0KGhBYWNFbmNvZGVyLT5oVHBFbmMsIGhBYWNFbmNvZGVyLT5vdXRCdWZmZXIsIGhBYWNFbmNvZGVyLT5vdXRCdWZmZXJJbkJ5dGVzLCBjb25maWctPnVzZXJUcFR5cGUsICZoQWFjRW5jb2Rlci0+Y29kZXJDb25maWcsIGZsYWdzKSAhPSAwKSB7CiAgICAgICAgICAgIHJldHVybiBBQUNFTkNfSU5JVF9UUF9FUlJPUjsKICAgICAgICB9CgogICAgfSAvKiB0cmFuc3BvcnQgaW5pdGlhbGl6YXRpb24gKi8KCiAgICAvKgogICAgICogSW5pdGlhbGl6ZSBBQUMgLSBDb3JlLgogICAgICovCiAgICBpZiAoIChJbml0RmxhZ3MgJiBBQUNFTkNfSU5JVF9DT05GSUcpIHx8CiAgICAgICAgIChJbml0RmxhZ3MgJiBBQUNFTkNfSU5JVF9TVEFURVMpICkKICAgIHsKICAgICAgICBBQUNfRU5DT0RFUl9FUlJPUiBlcnI7CiAgICAgICAgZXJyID0gRkRLYWFjRW5jX0luaXRpYWxpemUoaEFhY0VuY29kZXItPmhBYWNFbmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0NvbmZpZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+aFRwRW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJbml0RmxhZ3MgJiBBQUNFTkNfSU5JVF9TVEFURVMpID8gMSA6IDApOwoKICAgICAgICBpZiAoZXJyICE9IEFBQ19FTkNfT0spIHsKICAgICAgICAgICAgcmV0dXJuIEFBQ0VOQ19JTklUX0FBQ19FUlJPUjsKICAgICAgICB9CgogICAgfSAvKiBhYWMgaW5pdGlhbGl6YXRpb24gKi8KCiAgICAvKgogICAgICogSW5pdGlhbGl6ZSBNZXRhIERhdGEgLSBFbmNvZGVyLgogICAgICovCiAgICBpZiAoIGhBYWNFbmNvZGVyLT5oTWV0YWRhdGFFbmMgJiYgKGhBYWNFbmNvZGVyLT5tZXRhRGF0YUFsbG93ZWQhPTApICYmCiAgICAgICAgKChJbml0RmxhZ3MgJiBBQUNFTkNfSU5JVF9DT05GSUcpIHx8KEluaXRGbGFncyAmIEFBQ0VOQ19JTklUX1NUQVRFUykpICkKICAgIHsKICAgICAgICBJTlQgaW5wdXREYXRhRGVsYXkgPSBERUxBWV9BQUMoaEFhY0NvbmZpZy0+ZnJhbWVsZW5ndGgpOwoKICAgICAgICBpZiAoIGlzU2JyQWN0aXZlKGhBYWNDb25maWcpICYmIGhTYnJFbmNvZGVyIT1OVUxMKSB7CiAgICAgICAgICAgIGlucHV0RGF0YURlbGF5ID0gMippbnB1dERhdGFEZWxheSArIHNickVuY29kZXJfR2V0SW5wdXREYXRhRGVsYXkoKmhTYnJFbmNvZGVyKTsKICAgICAgICB9CgogICAgICAgIGlmICggRkRLX01ldGFkYXRhRW5jX0luaXQoaEFhY0VuY29kZXItPmhNZXRhZGF0YUVuYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChJbml0RmxhZ3MmQUFDRU5DX0lOSVRfU1RBVEVTKSA/IDEgOiAwKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZy0+dXNlck1ldGFEYXRhTW9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0RGF0YURlbGF5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJhbWVMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWctPnVzZXJTYW1wbGVyYXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uZmlnLT5uQ2hhbm5lbHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWctPnVzZXJDaGFubmVsTW9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNDb25maWctPmNoYW5uZWxPcmRlcikgIT0gMCkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBBQUNFTkNfSU5JVF9NRVRBX0VSUk9SOwogICAgICAgIH0KCiAgICAgICAgaEFhY0VuY29kZXItPm5EZWxheSArPSBGREtfTWV0YWRhdGFFbmNfR2V0RGVsYXkoaEFhY0VuY29kZXItPmhNZXRhZGF0YUVuYyk7CiAgICB9CgogICAgLyoKICAgICAqIFVwZGF0ZSBwb2ludGVyIHRvIHdvcmtpbmcgYnVmZmVyLgogICAgICovCiAgICBpZiAoIChJbml0RmxhZ3MgJiBBQUNFTkNfSU5JVF9DT05GSUcpICkKICAgIHsKICAgICAgICBoQWFjRW5jb2Rlci0+aW5wdXRCdWZmZXJPZmZzZXQgPSBhYWNCdWZmZXJPZmZzZXQ7CgogICAgICAgIGhBYWNFbmNvZGVyLT5uU2FtcGxlc1RvUmVhZCA9IGZyYW1lTGVuZ3RoICogY29uZmlnLT5uQ2hhbm5lbHM7CgogICAgICAgIC8qIE1ha2UgbkRlbGF5IGNvbXBhcmlzb24gY29tcGF0aWJsZSB3aXRoIGNvbmZpZy0+blNhbXBsZXNSZWFkICovCiAgICAgICAgaEFhY0VuY29kZXItPm5EZWxheSAqPSBjb25maWctPm5DaGFubmVsczsKCiAgICB9IC8qIHBhcmFtZXRlciBjaGFuZ2VkICovCgogICAgcmV0dXJuIEFBQ0VOQ19PSzsKfQoKCkFBQ0VOQ19FUlJPUiBhYWNFbmNPcGVuKAogICAgICAgIEhBTkRMRV9BQUNFTkNPREVSICAgICAgICAqcGhBYWNFbmNvZGVyLAogICAgICAgIGNvbnN0IFVJTlQgICAgICAgICAgICAgICAgZW5jTW9kdWxlcywKICAgICAgICBjb25zdCBVSU5UICAgICAgICAgICAgICAgIG1heENoYW5uZWxzCiAgICAgICAgKQp7CiAgICBBQUNFTkNfRVJST1IgZXJyID0gQUFDRU5DX09LOwogICAgSEFORExFX0FBQ0VOQ09ERVIgIGhBYWNFbmNvZGVyID0gTlVMTDsKCiAgICBpZiAocGhBYWNFbmNvZGVyID09IE5VTEwpIHsKICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9IQU5ETEU7CiAgICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIC8qIGFsbG9jYXRlIG1lbW9yeSAqLwogICAgaEFhY0VuY29kZXIgPSBHZXRfQWFjRW5jb2RlcigpOwoKICAgIGlmIChoQWFjRW5jb2RlciA9PSBOVUxMKSB7CiAgICAgICAgZXJyID0gQUFDRU5DX01FTU9SWV9FUlJPUjsKICAgICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgRkRLbWVtY2xlYXIoaEFhY0VuY29kZXIsIHNpemVvZihBQUNFTkNPREVSKSk7CgogICAgLyogU3BlY2lmeSBlbmNvZGVyIG1vZHVsZXMgdG8gYmUgYWxsb2NhdGVkLiAqLwogICAgaWYgKGVuY01vZHVsZXM9PTApIHsKICAgICAgICBoQWFjRW5jb2Rlci0+ZW5jb2Rlcl9tb2RpcyA9IEVOQ19NT0RFX0ZMQUdfQUFDOwogICAgICAgIGhBYWNFbmNvZGVyLT5lbmNvZGVyX21vZGlzIHw9IEVOQ19NT0RFX0ZMQUdfU0JSOwogICAgICAgIGhBYWNFbmNvZGVyLT5lbmNvZGVyX21vZGlzIHw9IEVOQ19NT0RFX0ZMQUdfUFM7CiAgICAgICAgaEFhY0VuY29kZXItPmVuY29kZXJfbW9kaXMgfD0gRU5DX01PREVfRkxBR19NRVRBOwogICAgfQogICAgZWxzZSB7CiAgICAgICAvKiBjb25zaWRlciBTQUMgYW5kIFBTIG1vZHVsZSAqLwogICAgICAgIGhBYWNFbmNvZGVyLT5lbmNvZGVyX21vZGlzID0gZW5jTW9kdWxlczsKICAgIH0KCiAgICAvKiBEZXRlcm1pbmUgbWF4IGNoYW5uZWwgY29uZmlndXJhdGlvbi4gKi8KICAgIGlmIChtYXhDaGFubmVscz09MCkgewogICAgICAgIGhBYWNFbmNvZGVyLT5uTWF4QWFjQ2hhbm5lbHMgPSAoNik7CiAgICAgICAgaEFhY0VuY29kZXItPm5NYXhTYnJDaGFubmVscyA9ICg2KTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIGhBYWNFbmNvZGVyLT5uTWF4QWFjQ2hhbm5lbHMgPSAobWF4Q2hhbm5lbHMmMHgwMEZGKTsKICAgICAgICBpZiAoIChoQWFjRW5jb2Rlci0+ZW5jb2Rlcl9tb2RpcyZFTkNfTU9ERV9GTEFHX1NCUikgKSB7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5uTWF4U2JyQ2hhbm5lbHMgPSAobWF4Q2hhbm5lbHMmMHhGRjAwKSA/IChtYXhDaGFubmVscz4+OCkgOiBoQWFjRW5jb2Rlci0+bk1heEFhY0NoYW5uZWxzOwogICAgICAgIH0KCiAgICAgICAgaWYgKCAoaEFhY0VuY29kZXItPm5NYXhBYWNDaGFubmVscz4oNikpIHx8IChoQWFjRW5jb2Rlci0+bk1heFNickNoYW5uZWxzPig2KSkgKSB7CiAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgZ290byBiYWlsOwogICAgICAgIH0KICAgIH0gLyogbWF4Q2hhbm5lbHM9PTAgKi8KCiAgICAvKiBNYXggbnVtYmVyIG9mIGVsZW1lbnRzIGNvdWxkIGJlIHR1bmVkIGFueSBtb3JlLiAqLwogICAgaEFhY0VuY29kZXItPm5NYXhBYWNFbGVtZW50cyA9IGZpeE1pbigoNiksIGhBYWNFbmNvZGVyLT5uTWF4QWFjQ2hhbm5lbHMpOwogICAgaEFhY0VuY29kZXItPm5NYXhTYnJFbGVtZW50cyA9IGZpeE1pbigoNiksIGhBYWNFbmNvZGVyLT5uTWF4U2JyQ2hhbm5lbHMpOwogICAgaEFhY0VuY29kZXItPm5NYXhTdWJGcmFtZXMgPSAoMSk7CgoKICAgIC8qIEluIGNhc2Ugb2YgbWVtb3J5IG92ZXJsYXksIGFsbG9jYXRlIG1lbW9yeSBvdXQgb2YgbGlicmFyaWVzICovCgogICAgaEFhY0VuY29kZXItPmlucHV0QnVmZmVyID0gKElOVF9QQ00qKUZES2NhbGxvYyhoQWFjRW5jb2Rlci0+bk1heEFhY0NoYW5uZWxzKklOUFVUQlVGRkVSX1NJWkUsIHNpemVvZihJTlRfUENNKSk7CgogICAgLyogT3BlbiBTQlIgRW5jb2RlciAqLwogICAgaWYgKGhBYWNFbmNvZGVyLT5lbmNvZGVyX21vZGlzJkVOQ19NT0RFX0ZMQUdfU0JSKSB7CiAgICAgICAgaWYgKCBzYnJFbmNvZGVyX09wZW4oJmhBYWNFbmNvZGVyLT5oRW52RW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+bk1heFNickVsZW1lbnRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+bk1heFNickNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChoQWFjRW5jb2Rlci0+ZW5jb2Rlcl9tb2RpcyZFTkNfTU9ERV9GTEFHX1BTKSA/IDEgOiAwICkgKQogICAgICAgIHsKICAgICAgICAgIGVyciA9IEFBQ0VOQ19NRU1PUllfRVJST1I7CiAgICAgICAgICBnb3RvIGJhaWw7CiAgICAgICAgfQogICAgfSAvKiAoZW5jb2Rlcl9tb2RpcyZFTkNfTU9ERV9GTEFHX1NCUikgKi8KCgogICAgLyogT3BlbiBBYWMgRW5jb2RlciAqLwogICAgaWYgKCBGREthYWNFbmNfT3BlbigmaEFhY0VuY29kZXItPmhBYWNFbmMsCiAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+bk1heEFhY0VsZW1lbnRzLAogICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPm5NYXhBYWNDaGFubmVscywKICAgICAgICAgICAgICAgICAgICAgICAgICgxKSkgIT0gQUFDX0VOQ19PSyApCiAgICB7CiAgICAgICAgZXJyID0gQUFDRU5DX01FTU9SWV9FUlJPUjsKICAgICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgeyAvKiBHZXQgYml0c3RyZWFtIG91dHB1dGJ1ZmZlciBzaXplICovCiAgICAgIFVJTlQgbGRfTTsKICAgICAgZm9yIChsZF9NPTE7IChVSU5UKSgxPDxsZF9NKSA8IChoQWFjRW5jb2Rlci0+bk1heFN1YkZyYW1lcypoQWFjRW5jb2Rlci0+bk1heEFhY0NoYW5uZWxzKjYxNDQpPj4zOyBsZF9NKyspIDsKICAgICAgaEFhY0VuY29kZXItPm91dEJ1ZmZlckluQnl0ZXMgPSAoMTw8bGRfTSk7ICAvKiBidWZmZXIgaGFzIHRvIGJlIDJebiAqLwogICAgfQogICAgaEFhY0VuY29kZXItPm91dEJ1ZmZlciA9IEdldFJhbV9ic091dGJ1ZmZlcigpOwogICAgaWYgKE9VVFBVVEJVRkZFUl9TSVpFIDwgaEFhY0VuY29kZXItPm91dEJ1ZmZlckluQnl0ZXMgKSB7CiAgICAgIGVyciA9IEFBQ0VOQ19NRU1PUllfRVJST1I7CiAgICAgIGdvdG8gYmFpbDsKICAgIH0KCiAgICAvKiBPcGVuIE1ldGEgRGF0YSBFbmNvZGVyICovCiAgICBpZiAoaEFhY0VuY29kZXItPmVuY29kZXJfbW9kaXMmRU5DX01PREVfRkxBR19NRVRBKSB7CiAgICAgIGlmICggRkRLX01ldGFkYXRhRW5jX09wZW4oJmhBYWNFbmNvZGVyLT5oTWV0YWRhdGFFbmMpICkKICAgICAgewogICAgICAgIGVyciA9IEFBQ0VOQ19NRU1PUllfRVJST1I7CiAgICAgICAgZ290byBiYWlsOwogICAgICB9CiAgICB9IC8qIChlbmNvZGVyX21vZGlzJkVOQ19NT0RFX0ZMQUdfTUVUQSkgKi8KCiAgICAvKiBPcGVuIFRyYW5zcG9ydCBFbmNvZGVyICovCiAgICBpZiAoIHRyYW5zcG9ydEVuY19PcGVuKCZoQWFjRW5jb2Rlci0+aFRwRW5jKSAhPSAwICkKICAgIHsKICAgICAgICBlcnIgPSBBQUNFTkNfTUVNT1JZX0VSUk9SOwogICAgICAgIGdvdG8gYmFpbDsKICAgIH0KICAgIGVsc2UgewogICAgICAgIENfQUxMT0NfU0NSQVRDSF9TVEFSVChwTGliSW5mbywgTElCX0lORk8sIEZES19NT0RVTEVfTEFTVCk7IAoKICAgICAgICBGREtpbml0TGliSW5mbyggcExpYkluZm8pOwogICAgICAgIHRyYW5zcG9ydEVuY19HZXRMaWJJbmZvKCBwTGliSW5mbyApOwoKICAgICAgICAvKiBHZXQgY2FwYWJpbHR5IGZsYWcgZm9yIHRyYW5zcG9ydCBlbmNvZGVyLiAqLwogICAgICAgIGhBYWNFbmNvZGVyLT5DQVBGX3RwRW5jID0gRkRLbGliSW5mb19nZXRDYXBhYmlsaXRpZXMoIHBMaWJJbmZvLCBGREtfVFBFTkMpOwoKICAgICAgICBDX0FMTE9DX1NDUkFUQ0hfRU5EKHBMaWJJbmZvLCBMSUJfSU5GTywgRkRLX01PRFVMRV9MQVNUKTsKICAgIH0KICAgIGlmICggdHJhbnNwb3J0RW5jX1JlZ2lzdGVyU2JyQ2FsbGJhY2soaEFhY0VuY29kZXItPmhUcEVuYywgYWFjZW5jX1NickNhbGxiYWNrLCBoQWFjRW5jb2RlcikgIT0gMCApIHsKICAgICAgZXJyID0gQUFDRU5DX0lOSVRfVFBfRVJST1I7CiAgICAgIGdvdG8gYmFpbDsKICAgIH0KCiAgICAvKiBJbml0aWFsaXplIGVuY29kZXIgaW5zdGFuY2Ugd2l0aCBkZWZhdWx0IHBhcmFtZXRlcnMuICovCiAgICBhYWNFbmNEZWZhdWx0Q29uZmlnKCZoQWFjRW5jb2Rlci0+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+aW5wdXRCdWZmZXIraEFhY0VuY29kZXItPmlucHV0QnVmZmVyT2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5uU2FtcGxlc1JlYWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE1ldGFEYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBNZXRhRGF0YUV4dFBheWxvYWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbk1ldGFEYXRhRXh0ZW5zaW9ucywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZtYXRyaXhfbWl4ZG93bl9pZHgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOwoKICAgICAgICBmb3IgKGk9MDsgaTwoSU5UKW5NZXRhRGF0YUV4dGVuc2lvbnM7IGkrKykgeyAgLyogR2V0IG1ldGEgZGF0YSBleHRlbnNpb24gcGF5bG9hZC4gKi8KICAgICAgICAgICAgaEFhY0VuY29kZXItPmV4dFBheWxvYWRbbkV4dGVuc2lvbnMrK10gPSBwTWV0YURhdGFFeHRQYXlsb2FkW2ldOwogICAgICAgIH0KICAgICAgICBpZiAobWF0cml4X21peGRvd25faWR4IT0tMSkgeyAgICAgICAgICAgIC8qIFNldCBtYXRyaXggbWl4ZG93biBjb2VmZmljaWVudC4gKi8KICAgICAgICAgIFVJTlQgcGNlVmFsdWUgPSAoVUlOVCkoICgxPDwzKSB8ICgobWF0cml4X21peGRvd25faWR4JjB4Mik8PDEpIHwgMSApOwogICAgICAgICAgaWYgKGhBYWNFbmNvZGVyLT5leHRQYXJhbS51c2VyUGNlQWRkaXRpb25zICE9IHBjZVZhbHVlKSB7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5leHRQYXJhbS51c2VyUGNlQWRkaXRpb25zID0gcGNlVmFsdWU7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCgogICAgaWYgKCBpc1NickFjdGl2ZSgmaEFhY0VuY29kZXItPmFhY0NvbmZpZykgKSB7CgogICAgICAgIElOVCBuUGF5bG9hZCA9IDA7CgogICAgICAgIC8qCiAgICAgICAgICogRW5jb2RlIFNCUiBkYXRhLgogICAgICAgICAqLwogICAgICAgIGlmIChzYnJFbmNvZGVyX0VuY29kZUZyYW1lKGhBYWNFbmNvZGVyLT5oRW52RW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5pbnB1dEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+ZXh0UGFyYW0ubkNoYW5uZWxzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkU2l6ZVtuUGF5bG9hZF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaEFhY0VuY29kZXItPmV4dFBheWxvYWREYXRhW25QYXlsb2FkXQojaWYgZGVmaW5lZChFVkFMX1BBQ0tBR0VfU0lMRU5DRSkgfHwgZGVmaW5lZChFVkFMX1BBQ0tBR0VfU0JSX1NJTEVOQ0UpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAsaEFhY0VuY29kZXItPmhBYWNFbmMtPmNsZWFyT3V0cHV0CiNlbmRpZgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSkKICAgICAgICB7CiAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19FTkNPREVfRVJST1I7CiAgICAgICAgICAgIGdvdG8gYmFpbDsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIC8qIEFkZCBTQlIgZXh0ZW5zaW9uIHBheWxvYWQgKi8KICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8ICg2KTsgaSsrKSB7CiAgICAgICAgICAgICAgICBpZiAoaEFhY0VuY29kZXItPmV4dFBheWxvYWRTaXplW25QYXlsb2FkXVtpXSA+IDApIHsKICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZFtuRXh0ZW5zaW9uc10ucERhdGEgICAgPSBoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZERhdGFbblBheWxvYWRdW2ldOwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkW25FeHRlbnNpb25zXS5kYXRhU2l6ZSA9IGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkU2l6ZVtuUGF5bG9hZF1baV07CiAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZFtuRXh0ZW5zaW9uc10uYXNzb2NpYXRlZENoRWxlbWVudCA9IGk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkW25FeHRlbnNpb25zXS5kYXRhVHlwZSA9IEVYVF9TQlJfREFUQTsgIC8qIE9uY2UgU0JSIEVuY29kZXIgc3VwcG9ydHMgU0JSIENSQyBzZXQgRVhUX1NCUl9EQVRBX0NSQyAqLwogICAgICAgICAgICAgICAgICAgIG5FeHRlbnNpb25zKys7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG9yIEVYVF9TQlJfREFUQSBhY2NvcmRpbmcgdG8gY29uZmlndXJhdGlvbi4gKi8KICAgICAgICAgICAgICAgICAgICBGREtfQVNTRVJUKG5FeHRlbnNpb25zPD1NQVhfVE9UQUxfRVhUX1BBWUxPQURTKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBuUGF5bG9hZCsrOwogICAgICAgIH0KICAgIH0gLyogc2JyRW5hYmxlZCAqLwoKICAgIGlmICggKGluYXJncy0+bnVtQW5jQnl0ZXMgPiAwKSAmJiAoIGdldEJ1ZkRlc2NJZHgoaW5CdWZEZXNjLElOX0FOQ0lMTFJZX0RBVEEpIT0tMSApICkgewogICAgICAgIElOVCBpZHggPSBnZXRCdWZEZXNjSWR4KGluQnVmRGVzYyxJTl9BTkNJTExSWV9EQVRBKTsKICAgICAgICBoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZFtuRXh0ZW5zaW9uc10uZGF0YVNpemUgPSBpbmFyZ3MtPm51bUFuY0J5dGVzICogODsKICAgICAgICBoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZFtuRXh0ZW5zaW9uc10ucERhdGEgICAgPSAoVUNIQVIqKWluQnVmRGVzYy0+YnVmc1tpZHhdOwogICAgICAgIGhBYWNFbmNvZGVyLT5leHRQYXlsb2FkW25FeHRlbnNpb25zXS5kYXRhVHlwZSA9IEVYVF9EQVRBX0VMRU1FTlQ7CiAgICAgICAgaEFhY0VuY29kZXItPmV4dFBheWxvYWRbbkV4dGVuc2lvbnNdLmFzc29jaWF0ZWRDaEVsZW1lbnQgPSAtMTsKICAgICAgICBhbmNEYXRhRXh0SWR4ID0gbkV4dGVuc2lvbnM7IC8qIHN0b3JlIGluZGV4ICovCiAgICAgICAgbkV4dGVuc2lvbnMrKzsKICAgIH0KCiAgICAvKgogICAgICogRW5jb2RlIEFBQyAtIENvcmUuCiAgICAgKi8KICAgIGlmICggRkRLYWFjRW5jX0VuY29kZUZyYW1lKCBoQWFjRW5jb2Rlci0+aEFhY0VuYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+aFRwRW5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5pbnB1dEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRCeXRlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+ZXh0UGF5bG9hZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkgIT0gQUFDX0VOQ19PSyApCiAgICB7CiAgICAgICAgZXJyID0gQUFDRU5DX0VOQ09ERV9FUlJPUjsKICAgICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgaWYgKGFuY0RhdGFFeHRJZHggPj0gMCkgewogICAgICBvdXRhcmdzLT5udW1BbmNCeXRlcyA9IGluYXJncy0+bnVtQW5jQnl0ZXMgLSAoaEFhY0VuY29kZXItPmV4dFBheWxvYWRbYW5jRGF0YUV4dElkeF0uZGF0YVNpemU+PjMpOwogICAgfQoKICAgIC8qIHNhbXBsZXMgZXhoYXVzdGVkICovCiAgICBoQWFjRW5jb2Rlci0+blNhbXBsZXNSZWFkIC09IGhBYWNFbmNvZGVyLT5uU2FtcGxlc1RvUmVhZDsKCiAgICAvKgogICAgICogRGVsYXkgYmFsYW5jaW5nIGJ1ZmZlciBoYW5kbGluZwogICAgICovCiAgICBpZiAoaXNTYnJBY3RpdmUoJmhBYWNFbmNvZGVyLT5hYWNDb25maWcpKSB7CiAgICAgICAgc2JyRW5jb2Rlcl9VcGRhdGVCdWZmZXJzKGhBYWNFbmNvZGVyLT5oRW52RW5jLCBoQWFjRW5jb2Rlci0+aW5wdXRCdWZmZXIpOwogICAgfQoKICAgIC8qCiAgICAgKiBNYWtlIGJpdHN0cmVhbSBwdWJsaWMKICAgICAqLwogICAgaWYgKG91dEJ1ZkRlc2MtPm51bUJ1ZnM+PTEpIHsKCiAgICAgICAgSU5UIGJzSWR4ID0gZ2V0QnVmRGVzY0lkeChvdXRCdWZEZXNjLE9VVF9CSVRTVFJFQU1fREFUQSk7CiAgICAgICAgSU5UIGF1SWR4ID0gZ2V0QnVmRGVzY0lkeChvdXRCdWZEZXNjLE9VVF9BVV9TSVpFUyk7CgogICAgICAgIGZvciAoaT0wLG5Cc0J5dGVzPTA7IGk8aEFhY0VuY29kZXItPmFhY0NvbmZpZy5uU3ViRnJhbWVzOyBpKyspIHsKICAgICAgICAgIG5Cc0J5dGVzICs9IG91dEJ5dGVzW2ldOwoKICAgICAgICAgIGlmIChhdUlkeCE9LTEpIHsKICAgICAgICAgICAoKElOVCopb3V0QnVmRGVzYy0+YnVmc1thdUlkeF0pW2ldID0gb3V0Qnl0ZXNbaV07CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoIChic0lkeCE9LTEpICYmIChvdXRCdWZEZXNjLT5idWZTaXplc1tic0lkeF0+PW5Cc0J5dGVzKSApIHsKICAgICAgICAgIEZES21lbWNweShvdXRCdWZEZXNjLT5idWZzW2JzSWR4XSwgaEFhY0VuY29kZXItPm91dEJ1ZmZlciwgc2l6ZW9mKFVDSEFSKSpuQnNCeXRlcyk7CiAgICAgICAgICBvdXRhcmdzLT5udW1PdXRCeXRlcyA9IG5Cc0J5dGVzOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgIC8qIG91dHB1dCBidWZmZXIgdG9vIHNtYWxsLCBjYW4ndCB3cml0ZSB2YWxpZCBiaXRzdHJlYW0gKi8KICAgICAgICAgIGVyciA9IEFBQ0VOQ19FTkNPREVfRVJST1I7CiAgICAgICAgICBnb3RvIGJhaWw7CiAgICAgICAgfQogICAgfQoKYmFpbDoKICAgIGlmIChlcnIgPT0gQUFDRU5DX0VOQ09ERV9FUlJPUikgewogICAgICAgIC8qIEFsbCBlbmNvZGVyIG1vZHVsZXMgaGF2ZSB0byBiZSBpbml0aWFsaXplZCAqLwogICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgPSBBQUNFTkNfSU5JVF9BTEw7CiAgICB9CgogICAgcmV0dXJuIGVycjsKfQoKc3RhdGljCkFBQ19FTkNPREVSX0VSUk9SIGFhY0VuY0dldENvbmYoSEFORExFX0FBQ0VOQ09ERVIgIGhBYWNFbmNvZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVJTlQgICAgICAgICAgICAgICpzaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVDSEFSICAgICAgICAgICAgICpjb25mQnVmZmVyKQp7CiAgICBGREtfQklUU1RSRUFNIHRtcENvbmY7CiAgICBVSU5UIGNvbmZUeXBlOwogICAgVUNIQVIgYnVmWzY0XTsKICAgIGludCBlcnI7CgogICAgLyogSW5pdCBiaXQgYnVmZmVyICovCiAgICBGREtpbml0Qml0U3RyZWFtKCZ0bXBDb25mLCBidWYsIDY0LCAwLCBCU19XUklURVIpOwoKICAgIC8qIHdyaXRlIGNvbmYgaW4gdG1wIGJ1ZmZlciAqLwogICAgZXJyID0gdHJhbnNwb3J0RW5jX0dldENvbmYoaEFhY0VuY29kZXItPmhUcEVuYywgJmhBYWNFbmNvZGVyLT5jb2RlckNvbmZpZywgJnRtcENvbmYsICZjb25mVHlwZSk7CgogICAgLyogY29weSBkYXRhIHRvIG91dGJ1ZmZlcjogbGVuZ3RoIGluIGJ5dGVzICovCiAgICBGREtieXRlQWxpZ24oJnRtcENvbmYsIDApOwoKICAgIC8qIENoZWNrIGJ1ZmZlciBzaXplICovCiAgICBpZiAoRkRLZ2V0VmFsaWRCaXRzKCZ0bXBDb25mKSA+ICgoKnNpemUpPDwzKSkKICAgICAgcmV0dXJuIEFBQ19FTkNfVU5LTk9XTjsKCiAgICBGREtmZXRjaEJ1ZmZlcigmdG1wQ29uZiwgY29uZkJ1ZmZlciwgc2l6ZSk7CgogICAgaWYgKGVyciAhPSAwKQogICAgICByZXR1cm4gQUFDX0VOQ19VTktOT1dOOwogICAgZWxzZQogICAgICByZXR1cm4gQUFDX0VOQ19PSzsKfQoKCkFBQ0VOQ19FUlJPUiBhYWNFbmNHZXRMaWJJbmZvKExJQl9JTkZPICppbmZvKQp7CiAgaW50IGkgPSAwOwoKICBpZiAoaW5mbyA9PSBOVUxMKSB7CiAgICByZXR1cm4gQUFDRU5DX0lOVkFMSURfSEFORExFOwogIH0KCiAgRkRLX3Rvb2xzR2V0TGliSW5mbyggaW5mbyApOwogIHRyYW5zcG9ydEVuY19HZXRMaWJJbmZvKCBpbmZvICk7CgogIHNickVuY29kZXJfR2V0TGliSW5mbyggaW5mbyApOwoKICAvKiBzZWFyY2ggZm9yIG5leHQgZnJlZSB0YWIgKi8KICBmb3IgKGkgPSAwOyBpIDwgRkRLX01PRFVMRV9MQVNUOyBpKyspIHsKICAgIGlmIChpbmZvW2ldLm1vZHVsZV9pZCA9PSBGREtfTk9ORSkgYnJlYWs7CiAgfQogIGlmIChpID09IEZES19NT0RVTEVfTEFTVCkgewogICAgcmV0dXJuIEFBQ0VOQ19JTklUX0VSUk9SOwogIH0KCiAgaW5mb1tpXS5tb2R1bGVfaWQgPSBGREtfQUFDRU5DOwogIGluZm9baV0uYnVpbGRfZGF0ZSA9IChjaGFyKilBQUNFTkNPREVSX0xJQl9CVUlMRF9EQVRFOwogIGluZm9baV0uYnVpbGRfdGltZSA9IChjaGFyKilBQUNFTkNPREVSX0xJQl9CVUlMRF9USU1FOwogIGluZm9baV0udGl0bGUgPSAoY2hhciopQUFDRU5DT0RFUl9MSUJfVElUTEU7CiAgaW5mb1tpXS52ZXJzaW9uID0gTElCX1ZFUlNJT04oQUFDRU5DT0RFUl9MSUJfVkwwLCBBQUNFTkNPREVSX0xJQl9WTDEsIEFBQ0VOQ09ERVJfTElCX1ZMMik7OwogIExJQl9WRVJTSU9OX1NUUklORygmaW5mb1tpXSk7CgogIC8qIENhcGFiaWxpdHkgZmxhZ3MgKi8KICBpbmZvW2ldLmZsYWdzID0gMAogICAgfCBDQVBGX0FBQ18xMDI0IHwgQ0FQRl9BQUNfTEMKICAgIHwgQ0FQRl9BQUNfNTEyCiAgICB8IENBUEZfQUFDXzQ4MAogICAgfCBDQVBGX0FBQ19EUkMKICAgICAgOwogIC8qIEVuZCBvZiBmbGFncyAqLwoKICByZXR1cm4gQUFDRU5DX09LOwp9CgpBQUNFTkNfRVJST1IgYWFjRW5jb2Rlcl9TZXRQYXJhbSgKICAgICAgICBjb25zdCBIQU5ETEVfQUFDRU5DT0RFUiAgIGhBYWNFbmNvZGVyLAogICAgICAgIGNvbnN0IEFBQ0VOQ19QQVJBTSAgICAgICAgcGFyYW0sCiAgICAgICAgY29uc3QgVUlOVCAgICAgICAgICAgICAgICB2YWx1ZQogICAgICAgICkKewogICAgQUFDRU5DX0VSUk9SIGVyciA9IEFBQ0VOQ19PSzsKICAgIFVTRVJfUEFSQU0gKnNldHRpbmdzID0gJmhBYWNFbmNvZGVyLT5leHRQYXJhbTsKCiAgICAvKiBjaGVjayBlbmNvZGVyIGhhbmRsZSAqLwogICAgaWYgKGhBYWNFbmNvZGVyID09IE5VTEwpIHsKICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9IQU5ETEU7CiAgICAgICAgZ290byBiYWlsOwogICAgfQoKICAgIC8qIGFwcGx5IHBhcmFtIHZhbHVlICovCiAgICBzd2l0Y2ggKHBhcmFtKQogICAgewogICAgY2FzZSBBQUNFTkNfQU9UOgogICAgICAgIGlmIChzZXR0aW5ncy0+dXNlckFPVCAhPSAoQVVESU9fT0JKRUNUX1RZUEUpdmFsdWUpIHsKICAgICAgICAgICAgLyogY2hlY2sgaWYgQU9UIG1hdGNoZXMgdGhlIGFsbG9jYXRlZCBtb2R1bGVzICovCiAgICAgICAgICAgIHN3aXRjaCAoIHZhbHVlICkgewogICAgICAgICAgICAgIGNhc2UgQU9UX1BTOgogICAgICAgICAgICAgIGNhc2UgQU9UX01QMl9QUzoKICAgICAgICAgICAgICAgIGlmICghKGhBYWNFbmNvZGVyLT5lbmNvZGVyX21vZGlzICYgKEVOQ19NT0RFX0ZMQUdfUFMpKSkgewogICAgICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgICAgICAgIGdvdG8gYmFpbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBjYXNlIEFPVF9TQlI6CiAgICAgICAgICAgICAgY2FzZSBBT1RfTVAyX1NCUjoKICAgICAgICAgICAgICAgIGlmICghKGhBYWNFbmNvZGVyLT5lbmNvZGVyX21vZGlzICYgKEVOQ19NT0RFX0ZMQUdfU0JSKSkpIHsKICAgICAgICAgICAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgICAgICAgICBnb3RvIGJhaWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgY2FzZSBBT1RfQUFDX0xDOgogICAgICAgICAgICAgIGNhc2UgQU9UX01QMl9BQUNfTEM6CiAgICAgICAgICAgICAgY2FzZSBBT1RfRVJfQUFDX0xDOgogICAgICAgICAgICAgIGNhc2UgQU9UX0VSX0FBQ19MRDoKICAgICAgICAgICAgICBjYXNlIEFPVF9FUl9BQUNfRUxEOgogICAgICAgICAgICAgICAgaWYgKCEoaEFhY0VuY29kZXItPmVuY29kZXJfbW9kaXMgJiAoRU5DX01PREVfRkxBR19BQUMpKSkgewogICAgICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgICAgICAgIGdvdG8gYmFpbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgICAgICBnb3RvIGJhaWw7CiAgICAgICAgICAgIH0vKiBzd2l0Y2ggdmFsdWUgKi8KICAgICAgICAgICAgc2V0dGluZ3MtPnVzZXJBT1QgPSAoQVVESU9fT0JKRUNUX1RZUEUpdmFsdWU7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfQ09ORklHIHwgQUFDRU5DX0lOSVRfU1RBVEVTIHwgQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0JJVFJBVEU6CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyQml0cmF0ZSAhPSB2YWx1ZSkgewogICAgICAgICAgICBzZXR0aW5ncy0+dXNlckJpdHJhdGUgPSB2YWx1ZTsKICAgICAgICAgICAgaEFhY0VuY29kZXItPkluaXRGbGFncyB8PSBBQUNFTkNfSU5JVF9DT05GSUcgfCBBQUNFTkNfSU5JVF9UUkFOU1BPUlQ7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfQklUUkFURU1PREU6CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyQml0cmF0ZU1vZGUgIT0gdmFsdWUpIHsKICAgICAgICAgICAgc3dpdGNoICggdmFsdWUgKSB7CiAgICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgIGNhc2UgODoKICAgICAgICAgICAgICAgIHNldHRpbmdzLT51c2VyQml0cmF0ZU1vZGUgPSB2YWx1ZTsKICAgICAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfQ09ORklHIHwgQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IC8qIHN3aXRjaCB2YWx1ZSAqLwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX1NBTVBMRVJBVEU6CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyU2FtcGxlcmF0ZSAhPSB2YWx1ZSkgewogICAgICAgICAgICBpZiAoICEoICh2YWx1ZT09ODAwMCkgfHwgKHZhbHVlPT0xMTAyNSkgfHwgKHZhbHVlPT0xMjAwMCkgfHwgKHZhbHVlPT0xNjAwMCkgfHwgKHZhbHVlPT0yMjA1MCkgfHwgKHZhbHVlPT0yNDAwMCkgfHwKICAgICAgICAgICAgICAgICAgICh2YWx1ZT09MzIwMDApIHx8ICh2YWx1ZT09NDQxMDApIHx8ICh2YWx1ZT09NDgwMDApIHx8ICh2YWx1ZT09NjQwMDApIHx8ICh2YWx1ZT09ODgyMDApIHx8ICh2YWx1ZT09OTYwMDApICkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBzZXR0aW5ncy0+dXNlclNhbXBsZXJhdGUgPSB2YWx1ZTsKICAgICAgICAgICAgaEFhY0VuY29kZXItPm5TYW1wbGVzUmVhZCA9IDA7IC8qIHJlc2V0IGludGVybmFsIGlucHV0YnVmZmVyICovCiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfQ09ORklHIHwgQUFDRU5DX0lOSVRfU1RBVEVTIHwgQUFDRU5DX0lOSVRfVFJBTlNQT1JUOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0NIQU5ORUxNT0RFOgogICAgICAgIGlmIChzZXR0aW5ncy0+dXNlckNoYW5uZWxNb2RlICE9IChDSEFOTkVMX01PREUpdmFsdWUpIHsKICAgICAgICAgICAgY29uc3QgQ0hBTk5FTF9NT0RFX0NPTkZJR19UQUIqIHBDb25maWcgPSBGREthYWNFbmNfR2V0Q2hhbm5lbE1vZGVDb25maWd1cmF0aW9uKChDSEFOTkVMX01PREUpdmFsdWUpOwogICAgICAgICAgICBpZiAocENvbmZpZz09TlVMTCkgewogICAgICAgICAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKCAocENvbmZpZy0+bkVsZW1lbnRzID4gaEFhY0VuY29kZXItPm5NYXhBYWNFbGVtZW50cykKICAgICAgICAgICAgICB8fCAocENvbmZpZy0+bkNoYW5uZWxzRWZmID4gaEFhY0VuY29kZXItPm5NYXhBYWNDaGFubmVscykKICAgICAgICAgICAgICB8fCAhKCh2YWx1ZT49MSkgJiYgKHZhbHVlPD02KSkKICAgICAgICAgICAgICAgICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZXJyID0gQUFDRU5DX0lOVkFMSURfQ09ORklHOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHNldHRpbmdzLT51c2VyQ2hhbm5lbE1vZGUgPSAoQ0hBTk5FTF9NT0RFKXZhbHVlOwogICAgICAgICAgICBzZXR0aW5ncy0+bkNoYW5uZWxzID0gcENvbmZpZy0+bkNoYW5uZWxzOwogICAgICAgICAgICBoQWFjRW5jb2Rlci0+blNhbXBsZXNSZWFkID0gMDsgLyogcmVzZXQgaW50ZXJuYWwgaW5wdXRidWZmZXIgKi8KICAgICAgICAgICAgaEFhY0VuY29kZXItPkluaXRGbGFncyB8PSBBQUNFTkNfSU5JVF9DT05GSUcgfCBBQUNFTkNfSU5JVF9UUkFOU1BPUlQ7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfQkFORFdJRFRIOgogICAgICAgIGlmIChzZXR0aW5ncy0+dXNlckJhbmR3aWR0aCAhPSB2YWx1ZSkgewogICAgICAgICAgc2V0dGluZ3MtPnVzZXJCYW5kd2lkdGggPSB2YWx1ZTsKICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfQ09ORklHOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0NIQU5ORUxPUkRFUjoKICAgICAgICBpZiAoaEFhY0VuY29kZXItPmFhY0NvbmZpZy5jaGFubmVsT3JkZXIgIT0gKENIQU5ORUxfT1JERVIpdmFsdWUpIHsKICAgICAgICAgICAgaWYgKCEgKCh2YWx1ZT09MCkgfHwgKHZhbHVlPT0xKSkgKSB7CiAgICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBoQWFjRW5jb2Rlci0+YWFjQ29uZmlnLmNoYW5uZWxPcmRlciA9IChDSEFOTkVMX09SREVSKXZhbHVlOwogICAgICAgICAgICBoQWFjRW5jb2Rlci0+blNhbXBsZXNSZWFkID0gMDsgLyogcmVzZXQgaW50ZXJuYWwgaW5wdXRidWZmZXIgKi8KICAgICAgICAgICAgaEFhY0VuY29kZXItPkluaXRGbGFncyB8PSBBQUNFTkNfSU5JVF9DT05GSUcgfCBBQUNFTkNfSU5JVF9TVEFURVMgfCBBQUNFTkNfSU5JVF9UUkFOU1BPUlQ7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfQUZURVJCVVJORVI6CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyQWZ0ZXJidXJuZXIgIT0gdmFsdWUpIHsKICAgICAgICAgICAgaWYgKCEgKCh2YWx1ZT09MCkgfHwgKHZhbHVlPT0xKSkgKSB7CiAgICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBzZXR0aW5ncy0+dXNlckFmdGVyYnVybmVyID0gdmFsdWU7CiAgICAgICAgICAgIGhBYWNFbmNvZGVyLT5Jbml0RmxhZ3MgfD0gQUFDRU5DX0lOSVRfQ09ORklHOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0dSQU5VTEVfTEVOR1RIOgogICAgICAgIGlmIChzZXR0aW5ncy0+dXNlckZyYW1lbGVuZ3RoICE9IHZhbHVlKSB7CiAgICAgICAgICBzd2l0Y2ggKHZhbHVlKSB7CiAgICAgICAgICAgIGNhc2UgMTAyNDoKICAgICAgICAgICAgY2FzZSA1MTI6CiAgICAgICAgICAgIGNhc2UgNDgwOgogICAgICAgICAgICAgIHNldHRpbmdzLT51c2VyRnJhbWVsZW5ndGggPSB2YWx1ZTsKICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX0NPTkZJRyB8IEFBQ0VOQ19JTklUX1RSQU5TUE9SVDsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfU0JSX01PREU6CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyU2JyRW5hYmxlZCAhPSB2YWx1ZSkgewogICAgICAgICAgICBzZXR0aW5ncy0+dXNlclNickVuYWJsZWQgPSB2YWx1ZTsKICAgICAgICAgICAgaEFhY0VuY29kZXItPkluaXRGbGFncyB8PSBBQUNFTkNfSU5JVF9DT05GSUcgfCBBQUNFTkNfSU5JVF9TVEFURVMgfCBBQUNFTkNfSU5JVF9UUkFOU1BPUlQ7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfVFJBTlNNVVg6CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyVHBUeXBlICE9IChUUkFOU1BPUlRfVFlQRSl2YWx1ZSkgewoKICAgICAgICAgICAgVFJBTlNQT1JUX1RZUEUgIHR5cGUgID0gKFRSQU5TUE9SVF9UWVBFKXZhbHVlOwogICAgICAgICAgICBVSU5UICAgICAgICAgICAgZmxhZ3MgPSBoQWFjRW5jb2Rlci0+Q0FQRl90cEVuYzsKCiAgICAgICAgICAgIGlmICggISggKCh0eXBlPT1UVF9NUDRfQURJRikgICAgICAmJiAgKGZsYWdzJkNBUEZfQURJRikpCiAgICAgICAgICAgICAgICAgfHwgKCh0eXBlPT1UVF9NUDRfQURUUykgICAgICAmJiAgKGZsYWdzJkNBUEZfQURUUykpCiAgICAgICAgICAgICAgICAgfHwgKCh0eXBlPT1UVF9NUDRfTEFUTV9NQ1AwKSAmJiAoKGZsYWdzJkNBUEZfTEFUTSkgJiYgKGZsYWdzJkNBUEZfUkFXUEFDS0VUUykpKQogICAgICAgICAgICAgICAgIHx8ICgodHlwZT09VFRfTVA0X0xBVE1fTUNQMSkgJiYgKChmbGFncyZDQVBGX0xBVE0pICYmIChmbGFncyZDQVBGX1JBV1BBQ0tFVFMpKSkKICAgICAgICAgICAgICAgICB8fCAoKHR5cGU9PVRUX01QNF9MT0FTKSAgICAgICYmICAoZmxhZ3MmQ0FQRl9MT0FTKSkKICAgICAgICAgICAgICAgICB8fCAoKHR5cGU9PVRUX01QNF9SQVcpICAgICAgICYmICAoZmxhZ3MmQ0FQRl9SQVdQQUNLRVRTKSkKICAgICAgICAgICAgICAgICkgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBzZXR0aW5ncy0+dXNlclRwVHlwZSA9IChUUkFOU1BPUlRfVFlQRSl2YWx1ZTsKICAgICAgICAgICAgaEFhY0VuY29kZXItPkluaXRGbGFncyB8PSBBQUNFTkNfSU5JVF9UUkFOU1BPUlQ7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfU0lHTkFMSU5HX01PREU6CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyVHBTaWduYWxpbmcgIT0gdmFsdWUpIHsKICAgICAgICAgICAgaWYgKCAhKCh2YWx1ZT09MCkgfHwgKHZhbHVlPT0xKSB8fCAodmFsdWU9PTIpKSApIHsKICAgICAgICAgICAgICAgIGVyciA9IEFBQ0VOQ19JTlZBTElEX0NPTkZJRzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHNldHRpbmdzLT51c2VyVHBTaWduYWxpbmcgPSB2YWx1ZTsKICAgICAgICAgICAgaEFhY0VuY29kZXItPkluaXRGbGFncyB8PSBBQUNFTkNfSU5JVF9UUkFOU1BPUlQ7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfUFJPVEVDVElPTjoKICAgICAgICBpZiAoc2V0dGluZ3MtPnVzZXJUcFByb3RlY3Rpb24gIT0gdmFsdWUpIHsKICAgICAgICAgICAgaWYgKCAhKCh2YWx1ZT09MCkgfHwgKHZhbHVlPT0xKSkgKSB7CiAgICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBzZXR0aW5ncy0+dXNlclRwUHJvdGVjdGlvbiA9IHZhbHVlOwogICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX1RSQU5TUE9SVDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19IRUFERVJfUEVSSU9EOgogICAgICAgIGlmIChzZXR0aW5ncy0+dXNlclRwSGVhZGVyUGVyaW9kICE9IHZhbHVlKSB7CiAgICAgICAgICAgIHNldHRpbmdzLT51c2VyVHBIZWFkZXJQZXJpb2QgPSB2YWx1ZTsKICAgICAgICAgICAgaEFhY0VuY29kZXItPkluaXRGbGFncyB8PSBBQUNFTkNfSU5JVF9UUkFOU1BPUlQ7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfVFBTVUJGUkFNRVM6CiAgICAgICAgaWYgKHNldHRpbmdzLT51c2VyVHBOc3ViRnJhbWVzICE9IHZhbHVlKSB7CiAgICAgICAgICAgIGlmICghICggKHZhbHVlPj0xKSAmJiAodmFsdWU8PTQpICkgKSB7CiAgICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBzZXR0aW5ncy0+dXNlclRwTnN1YkZyYW1lcyA9IHZhbHVlOwogICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX1RSQU5TUE9SVDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19BTkNJTExBUllfQklUUkFURToKICAgICAgICBpZiAoc2V0dGluZ3MtPnVzZXJBbmNEYXRhUmF0ZSAhPSB2YWx1ZSkgewogICAgICAgICAgICBzZXR0aW5ncy0+dXNlckFuY0RhdGFSYXRlID0gdmFsdWU7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfQ09OVFJPTF9TVEFURToKICAgICAgICBpZiAoaEFhY0VuY29kZXItPkluaXRGbGFncyAhPSB2YWx1ZSkgewogICAgICAgICAgICBpZiAodmFsdWUmQUFDRU5DX1JFU0VUX0lOQlVGRkVSKSB7CiAgICAgICAgICAgICAgICBoQWFjRW5jb2Rlci0+blNhbXBsZXNSZWFkID0gMDsKICAgICAgICAgICAgfQogICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzID0gdmFsdWU7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfTUVUQURBVEFfTU9ERToKICAgICAgICBpZiAoKFVJTlQpc2V0dGluZ3MtPnVzZXJNZXRhRGF0YU1vZGUgIT0gdmFsdWUpIHsKICAgICAgICAgICAgaWYgKCAhKCh2YWx1ZT49MCkgJiYgKHZhbHVlPD0yKSkgKSB7CiAgICAgICAgICAgICAgICBlcnIgPSBBQUNFTkNfSU5WQUxJRF9DT05GSUc7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBzZXR0aW5ncy0+dXNlck1ldGFEYXRhTW9kZSA9IHZhbHVlOwogICAgICAgICAgICBoQWFjRW5jb2Rlci0+SW5pdEZsYWdzIHw9IEFBQ0VOQ19JTklUX0NPTkZJRzsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICBlcnIgPSBBQUNFTkNfVU5TVVBQT1JURURfUEFSQU1FVEVSOwogICAgICBicmVhazsKICAgIH0gIC8qIHN3aXRjaChwYXJhbSkgKi8KCmJhaWw6CiAgICByZXR1cm4gZXJyOwp9CgpVSU5UIGFhY0VuY29kZXJfR2V0UGFyYW0oCiAgICAgICAgY29uc3QgSEFORExFX0FBQ0VOQ09ERVIgICBoQWFjRW5jb2RlciwKICAgICAgICBjb25zdCBBQUNFTkNfUEFSQU0gICAgICAgIHBhcmFtCiAgICAgICAgKQp7CiAgICBVSU5UIHZhbHVlID0gMDsKICAgIFVTRVJfUEFSQU0gKnNldHRpbmdzID0gJmhBYWNFbmNvZGVyLT5leHRQYXJhbTsKCiAgICAvKiBjaGVjayBlbmNvZGVyIGhhbmRsZSAqLwogICAgaWYgKGhBYWNFbmNvZGVyID09IE5VTEwpIHsKICAgICAgICBnb3RvIGJhaWw7CiAgICB9CgogICAgLyogYXBwbHkgcGFyYW0gdmFsdWUgKi8KICAgIHN3aXRjaCAocGFyYW0pCiAgICB7CiAgICBjYXNlIEFBQ0VOQ19BT1Q6CiAgICAgICAgdmFsdWUgPSAoVUlOVCloQWFjRW5jb2Rlci0+YWFjQ29uZmlnLmF1ZGlvT2JqZWN0VHlwZTsKICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0JJVFJBVEU6CiAgICAgICAgdmFsdWUgPSAoVUlOVCkoKGhBYWNFbmNvZGVyLT5hYWNDb25maWcuYml0cmF0ZU1vZGU9PUFBQ0VOQ19CUl9NT0RFX0NCUikgPyBoQWFjRW5jb2Rlci0+YWFjQ29uZmlnLmJpdFJhdGUgOiAtMSk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19CSVRSQVRFTU9ERToKICAgICAgICB2YWx1ZSA9IChVSU5UKWhBYWNFbmNvZGVyLT5hYWNDb25maWcuYml0cmF0ZU1vZGU7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19TQU1QTEVSQVRFOgogICAgICAgIHZhbHVlID0gKFVJTlQpc2V0dGluZ3MtPnVzZXJTYW1wbGVyYXRlOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfQ0hBTk5FTE1PREU6CiAgICAgICAgdmFsdWUgPSAoVUlOVCloQWFjRW5jb2Rlci0+YWFjQ29uZmlnLmNoYW5uZWxNb2RlOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfQkFORFdJRFRIOgogICAgICAgIHZhbHVlID0gKFVJTlQpaEFhY0VuY29kZXItPmFhY0NvbmZpZy5iYW5kV2lkdGg7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19DSEFOTkVMT1JERVI6CiAgICAgICAgdmFsdWUgPSAoVUlOVCloQWFjRW5jb2Rlci0+YWFjQ29uZmlnLmNoYW5uZWxPcmRlcjsKICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0FGVEVSQlVSTkVSOgogICAgICAgIHZhbHVlID0gKFVJTlQpaEFhY0VuY29kZXItPmFhY0NvbmZpZy51c2VSZXF1YW50OwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfR1JBTlVMRV9MRU5HVEg6CiAgICAgICAgdmFsdWUgPSAoVUlOVCloQWFjRW5jb2Rlci0+YWFjQ29uZmlnLmZyYW1lbGVuZ3RoOwogICAgICAgYnJlYWs7CiAgICBjYXNlIEFBQ0VOQ19TQlJfTU9ERToKICAgICAgICB2YWx1ZSA9IChVSU5UKSAoaEFhY0VuY29kZXItPmFhY0NvbmZpZy5zeW50YXhGbGFncyAmIEFDX1NCUl9QUkVTRU5UKSA/IDEgOiAwOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfVFJBTlNNVVg6CiAgICAgICAgdmFsdWUgPSAoVUlOVClzZXR0aW5ncy0+dXNlclRwVHlwZTsKICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX1NJR05BTElOR19NT0RFOgogICAgICAgIHZhbHVlID0gKFVJTlQpc2V0dGluZ3MtPnVzZXJUcFNpZ25hbGluZzsKICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX1BST1RFQ1RJT046CiAgICAgICAgdmFsdWUgPSAoVUlOVClzZXR0aW5ncy0+dXNlclRwUHJvdGVjdGlvbjsKICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0hFQURFUl9QRVJJT0Q6CiAgICAgICAgdmFsdWUgPSAoVUlOVCloQWFjRW5jb2Rlci0+Y29kZXJDb25maWcuaGVhZGVyUGVyaW9kOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfVFBTVUJGUkFNRVM6CiAgICAgICAgdmFsdWUgPSAoVUlOVClzZXR0aW5ncy0+dXNlclRwTnN1YkZyYW1lczsKICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0FOQ0lMTEFSWV9CSVRSQVRFOgogICAgICAgIHZhbHVlID0gKFVJTlQpaEFhY0VuY29kZXItPmFhY0NvbmZpZy5hbmNfUmF0ZTsKICAgICAgICBicmVhazsKICAgIGNhc2UgQUFDRU5DX0NPTlRST0xfU1RBVEU6CiAgICAgICAgdmFsdWUgPSAoVUlOVCloQWFjRW5jb2Rlci0+SW5pdEZsYWdzOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBBQUNFTkNfTUVUQURBVEFfTU9ERToKICAgICAgICB2YWx1ZSA9IChoQWFjRW5jb2Rlci0+bWV0YURhdGFBbGxvd2VkPT0wKSA/IDAgOiAoVUlOVClzZXR0aW5ncy0+dXNlck1ldGFEYXRhTW9kZTsKICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgIC8vZXJyID0gTVBTX0lOVkFMSURfUEFSQU1FVEVSOwogICAgICBicmVhazsKICAgIH0gIC8qIHN3aXRjaChwYXJhbSkgKi8KCmJhaWw6CiAgICByZXR1cm4gdmFsdWU7Cn0KCkFBQ0VOQ19FUlJPUiBhYWNFbmNJbmZvKAogICAgICAgIGNvbnN0IEhBTkRMRV9BQUNFTkNPREVSICAgaEFhY0VuY29kZXIsCiAgICAgICAgQUFDRU5DX0luZm9TdHJ1Y3QgICAgICAgICpwSW5mbwogICAgICAgICkKewogICAgQUFDRU5DX0VSUk9SIGVyciA9IEFBQ0VOQ19PSzsKCiAgICBGREttZW1jbGVhcihwSW5mbywgc2l6ZW9mKEFBQ0VOQ19JbmZvU3RydWN0KSk7CiAgICBwSW5mby0+Y29uZlNpemUgPSA2NDsgLyogcHJlLWluaXRpYWxpemUgKi8KCiAgICBwSW5mby0+bWF4T3V0QnVmQnl0ZXMgICAgPSAoKGhBYWNFbmNvZGVyLT5uTWF4QWFjQ2hhbm5lbHMqNjE0NCkrNyk+PjM7CiAgICBwSW5mby0+bWF4QW5jQnl0ZXMgICAgICAgPSBoQWFjRW5jb2Rlci0+YWFjQ29uZmlnLm1heEFuY0J5dGVzUGVyQVU7CiAgICBwSW5mby0+aW5CdWZGaWxsTGV2ZWwgICAgPSBoQWFjRW5jb2Rlci0+blNhbXBsZXNSZWFkL2hBYWNFbmNvZGVyLT5leHRQYXJhbS5uQ2hhbm5lbHM7CiAgICBwSW5mby0+aW5wdXRDaGFubmVscyAgICAgPSBoQWFjRW5jb2Rlci0+ZXh0UGFyYW0ubkNoYW5uZWxzOwogICAgcEluZm8tPmZyYW1lTGVuZ3RoICAgICAgID0gaEFhY0VuY29kZXItPm5TYW1wbGVzVG9SZWFkL2hBYWNFbmNvZGVyLT5leHRQYXJhbS5uQ2hhbm5lbHM7CiAgICBwSW5mby0+ZW5jb2RlckRlbGF5ICAgICAgPSBoQWFjRW5jb2Rlci0+bkRlbGF5L2hBYWNFbmNvZGVyLT5leHRQYXJhbS5uQ2hhbm5lbHM7CgogICAgLyogR2V0IGVuY29kZXIgY29uZmlndXJhdGlvbiAqLwogICAgaWYgKCBhYWNFbmNHZXRDb25mKGhBYWNFbmNvZGVyLCAmcEluZm8tPmNvbmZTaXplLCAmcEluZm8tPmNvbmZCdWZbMF0pICE9IEFBQ19FTkNfT0spIHsKICAgICAgICBlcnIgPSBBQUNFTkNfSU5JVF9FUlJPUjsKICAgICAgICBnb3RvIGJhaWw7CiAgICB9CmJhaWw6CiAgICByZXR1cm4gZXJyOwp9Cgo=