Ci8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClNvZnR3YXJlIExpY2Vuc2UgZm9yIFRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZAoKqSBDb3B5cmlnaHQgIDE5OTUgLSAyMDEzIEZyYXVuaG9mZXItR2VzZWxsc2NoYWZ0IHp1ciBG9nJkZXJ1bmcgZGVyIGFuZ2V3YW5kdGVuIEZvcnNjaHVuZyBlLlYuCiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KCiAxLiAgICBJTlRST0RVQ1RJT04KVGhlIEZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkICgiRkRLIEFBQyBDb2RlYyIpIGlzIHNvZnR3YXJlIHRoYXQgaW1wbGVtZW50cwp0aGUgTVBFRyBBZHZhbmNlZCBBdWRpbyBDb2RpbmcgKCJBQUMiKSBlbmNvZGluZyBhbmQgZGVjb2Rpbmcgc2NoZW1lIGZvciBkaWdpdGFsIGF1ZGlvLgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgaW50ZW5kZWQgdG8gYmUgdXNlZCBvbiBhIHdpZGUgdmFyaWV0eSBvZiBBbmRyb2lkIGRldmljZXMuCgpBQUMncyBIRS1BQUMgYW5kIEhFLUFBQyB2MiB2ZXJzaW9ucyBhcmUgcmVnYXJkZWQgYXMgdG9kYXkncyBtb3N0IGVmZmljaWVudCBnZW5lcmFsIHBlcmNlcHR1YWwKYXVkaW8gY29kZWNzLiBBQUMtRUxEIGlzIGNvbnNpZGVyZWQgdGhlIGJlc3QtcGVyZm9ybWluZyBmdWxsLWJhbmR3aWR0aCBjb21tdW5pY2F0aW9ucyBjb2RlYyBieQppbmRlcGVuZGVudCBzdHVkaWVzIGFuZCBpcyB3aWRlbHkgZGVwbG95ZWQuIEFBQyBoYXMgYmVlbiBzdGFuZGFyZGl6ZWQgYnkgSVNPIGFuZCBJRUMgYXMgcGFydApvZiB0aGUgTVBFRyBzcGVjaWZpY2F0aW9ucy4KClBhdGVudCBsaWNlbnNlcyBmb3IgbmVjZXNzYXJ5IHBhdGVudCBjbGFpbXMgZm9yIHRoZSBGREsgQUFDIENvZGVjIChpbmNsdWRpbmcgdGhvc2Ugb2YgRnJhdW5ob2ZlcikKbWF5IGJlIG9idGFpbmVkIHRocm91Z2ggVmlhIExpY2Vuc2luZyAod3d3LnZpYWxpY2Vuc2luZy5jb20pIG9yIHRocm91Z2ggdGhlIHJlc3BlY3RpdmUgcGF0ZW50IG93bmVycwppbmRpdmlkdWFsbHkgZm9yIHRoZSBwdXJwb3NlIG9mIGVuY29kaW5nIG9yIGRlY29kaW5nIGJpdCBzdHJlYW1zIGluIHByb2R1Y3RzIHRoYXQgYXJlIGNvbXBsaWFudCB3aXRoCnRoZSBJU08vSUVDIE1QRUcgYXVkaW8gc3RhbmRhcmRzLiBQbGVhc2Ugbm90ZSB0aGF0IG1vc3QgbWFudWZhY3R1cmVycyBvZiBBbmRyb2lkIGRldmljZXMgYWxyZWFkeSBsaWNlbnNlCnRoZXNlIHBhdGVudCBjbGFpbXMgdGhyb3VnaCBWaWEgTGljZW5zaW5nIG9yIGRpcmVjdGx5IGZyb20gdGhlIHBhdGVudCBvd25lcnMsIGFuZCB0aGVyZWZvcmUgRkRLIEFBQyBDb2RlYwpzb2Z0d2FyZSBtYXkgYWxyZWFkeSBiZSBjb3ZlcmVkIHVuZGVyIHRob3NlIHBhdGVudCBsaWNlbnNlcyB3aGVuIGl0IGlzIHVzZWQgZm9yIHRob3NlIGxpY2Vuc2VkIHB1cnBvc2VzIG9ubHkuCgpDb21tZXJjaWFsbHktbGljZW5zZWQgQUFDIHNvZnR3YXJlIGxpYnJhcmllcywgaW5jbHVkaW5nIGZsb2F0aW5nLXBvaW50IHZlcnNpb25zIHdpdGggZW5oYW5jZWQgc291bmQgcXVhbGl0eSwKYXJlIGFsc28gYXZhaWxhYmxlIGZyb20gRnJhdW5ob2Zlci4gVXNlcnMgYXJlIGVuY291cmFnZWQgdG8gY2hlY2sgdGhlIEZyYXVuaG9mZXIgd2Vic2l0ZSBmb3IgYWRkaXRpb25hbAphcHBsaWNhdGlvbnMgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uCgoyLiAgICBDT1BZUklHSFQgTElDRU5TRQoKUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCB3aXRob3V0CnBheW1lbnQgb2YgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBwcm92aWRlZCB0aGF0IHlvdSBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKCllvdSBtdXN0IHJldGFpbiB0aGUgY29tcGxldGUgdGV4dCBvZiB0aGlzIHNvZnR3YXJlIGxpY2Vuc2UgaW4gcmVkaXN0cmlidXRpb25zIG9mIHRoZSBGREsgQUFDIENvZGVjIG9yCnlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvIGluIHNvdXJjZSBjb2RlIGZvcm0uCgpZb3UgbXVzdCByZXRhaW4gdGhlIGNvbXBsZXRlIHRleHQgb2YgdGhpcyBzb2Z0d2FyZSBsaWNlbnNlIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMKcHJvdmlkZWQgd2l0aCByZWRpc3RyaWJ1dGlvbnMgb2YgdGhlIEZESyBBQUMgQ29kZWMgb3IgeW91ciBtb2RpZmljYXRpb25zIHRoZXJldG8gaW4gYmluYXJ5IGZvcm0uCllvdSBtdXN0IG1ha2UgYXZhaWxhYmxlIGZyZWUgb2YgY2hhcmdlIGNvcGllcyBvZiB0aGUgY29tcGxldGUgc291cmNlIGNvZGUgb2YgdGhlIEZESyBBQUMgQ29kZWMgYW5kIHlvdXIKbW9kaWZpY2F0aW9ucyB0aGVyZXRvIHRvIHJlY2lwaWVudHMgb2YgY29waWVzIGluIGJpbmFyeSBmb3JtLgoKVGhlIG5hbWUgb2YgRnJhdW5ob2ZlciBtYXkgbm90IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIGxpYnJhcnkgd2l0aG91dApwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpZb3UgbWF5IG5vdCBjaGFyZ2UgY29weXJpZ2h0IGxpY2Vuc2UgZmVlcyBmb3IgYW55b25lIHRvIHVzZSwgY29weSBvciBkaXN0cmlidXRlIHRoZSBGREsgQUFDIENvZGVjCnNvZnR3YXJlIG9yIHlvdXIgbW9kaWZpY2F0aW9ucyB0aGVyZXRvLgoKWW91ciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYyBtdXN0IGNhcnJ5IHByb21pbmVudCBub3RpY2VzIHN0YXRpbmcgdGhhdCB5b3UgY2hhbmdlZCB0aGUgc29mdHdhcmUKYW5kIHRoZSBkYXRlIG9mIGFueSBjaGFuZ2UuIEZvciBtb2RpZmllZCB2ZXJzaW9ucyBvZiB0aGUgRkRLIEFBQyBDb2RlYywgdGhlIHRlcm0KIkZyYXVuaG9mZXIgRkRLIEFBQyBDb2RlYyBMaWJyYXJ5IGZvciBBbmRyb2lkIiBtdXN0IGJlIHJlcGxhY2VkIGJ5IHRoZSB0ZXJtCiJUaGlyZC1QYXJ0eSBNb2RpZmllZCBWZXJzaW9uIG9mIHRoZSBGcmF1bmhvZmVyIEZESyBBQUMgQ29kZWMgTGlicmFyeSBmb3IgQW5kcm9pZC4iCgozLiAgICBOTyBQQVRFTlQgTElDRU5TRQoKTk8gRVhQUkVTUyBPUiBJTVBMSUVEIExJQ0VOU0VTIFRPIEFOWSBQQVRFTlQgQ0xBSU1TLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSBwYXRlbnRzIG9mIEZyYXVuaG9mZXIsCkFSRSBHUkFOVEVEIEJZIFRISVMgU09GVFdBUkUgTElDRU5TRS4gRnJhdW5ob2ZlciBwcm92aWRlcyBubyB3YXJyYW50eSBvZiBwYXRlbnQgbm9uLWluZnJpbmdlbWVudCB3aXRoCnJlc3BlY3QgdG8gdGhpcyBzb2Z0d2FyZS4KCllvdSBtYXkgdXNlIHRoaXMgRkRLIEFBQyBDb2RlYyBzb2Z0d2FyZSBvciBtb2RpZmljYXRpb25zIHRoZXJldG8gb25seSBmb3IgcHVycG9zZXMgdGhhdCBhcmUgYXV0aG9yaXplZApieSBhcHByb3ByaWF0ZSBwYXRlbnQgbGljZW5zZXMuCgo0LiAgICBESVNDTEFJTUVSCgpUaGlzIEZESyBBQUMgQ29kZWMgc29mdHdhcmUgaXMgcHJvdmlkZWQgYnkgRnJhdW5ob2ZlciBvbiBiZWhhbGYgb2YgdGhlIGNvcHlyaWdodCBob2xkZXJzIGFuZCBjb250cmlidXRvcnMKIkFTIElTIiBhbmQgV0lUSE9VVCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIGluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gdGhlIGltcGxpZWQgd2FycmFudGllcwpvZiBtZXJjaGFudGFiaWxpdHkgYW5kIGZpdG5lc3MgZm9yIGEgcGFydGljdWxhciBwdXJwb3NlLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUgpDT05UUklCVVRPUlMgQkUgTElBQkxFIGZvciBhbnkgZGlyZWN0LCBpbmRpcmVjdCwgaW5jaWRlbnRhbCwgc3BlY2lhbCwgZXhlbXBsYXJ5LCBvciBjb25zZXF1ZW50aWFsIGRhbWFnZXMsCmluY2x1ZGluZyBidXQgbm90IGxpbWl0ZWQgdG8gcHJvY3VyZW1lbnQgb2Ygc3Vic3RpdHV0ZSBnb29kcyBvciBzZXJ2aWNlczsgbG9zcyBvZiB1c2UsIGRhdGEsIG9yIHByb2ZpdHMsCm9yIGJ1c2luZXNzIGludGVycnVwdGlvbiwgaG93ZXZlciBjYXVzZWQgYW5kIG9uIGFueSB0aGVvcnkgb2YgbGlhYmlsaXR5LCB3aGV0aGVyIGluIGNvbnRyYWN0LCBzdHJpY3QKbGlhYmlsaXR5LCBvciB0b3J0IChpbmNsdWRpbmcgbmVnbGlnZW5jZSksIGFyaXNpbmcgaW4gYW55IHdheSBvdXQgb2YgdGhlIHVzZSBvZiB0aGlzIHNvZnR3YXJlLCBldmVuIGlmCmFkdmlzZWQgb2YgdGhlIHBvc3NpYmlsaXR5IG9mIHN1Y2ggZGFtYWdlLgoKNS4gICAgQ09OVEFDVCBJTkZPUk1BVElPTgoKRnJhdW5ob2ZlciBJbnN0aXR1dGUgZm9yIEludGVncmF0ZWQgQ2lyY3VpdHMgSUlTCkF0dGVudGlvbjogQXVkaW8gYW5kIE11bHRpbWVkaWEgRGVwYXJ0bWVudHMgLSBGREsgQUFDIExMCkFtIFdvbGZzbWFudGVsIDMzCjkxMDU4IEVybGFuZ2VuLCBHZXJtYW55Cgp3d3cuaWlzLmZyYXVuaG9mZXIuZGUvYW1tCmFtbS1pbmZvQGlpcy5mcmF1bmhvZmVyLmRlCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogTVBFRyBBdWRpbyBFbmNvZGVyICoqKioqKioqKioqKioqKioqKioqKioqKioqCgogICBJbml0aWFsIGF1dGhvcjogICAgICAgQWxleCBHcm9lc2NoZWwKICAgY29udGVudHMvZGVzY3JpcHRpb246IEFEVFMgVHJhbnNwb3J0IEhlYWRlcnMgc3VwcG9ydAoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgInRwZW5jX2FkdHMuaCIKCgojaW5jbHVkZSAidHBlbmNfbGliLmgiCiNpbmNsdWRlICJ0cGVuY19hc2MuaCIKCgppbnQgYWR0c1dyaXRlX0NyY1N0YXJ0UmVnKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfQURUUyBwQWR0cywgICAgICAgICAgLyohPCBwb2ludGVyIHRvIGFkdHMgc3R1Y3R1cmUgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEFORExFX0ZES19CSVRTVFJFQU0gaEJzLCAgIC8qITwgaGFuZGxlIHRvIGN1cnJlbnQgYml0IGJ1ZmZlciBzdHJ1Y3R1cmUgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1CaXRzICAgICAgICAgICAgICAgICAgIC8qITwgbnVtYmVyIG9mIGJpdHMgaW4gY3JjIHJlZ2lvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKewogIGlmIChwQWR0cy0+cHJvdGVjdGlvbl9hYnNlbnQpIHsKICAgIHJldHVybiAwOwogIH0KICByZXR1cm4gKCBGREtjcmNTdGFydFJlZygmcEFkdHMtPmNyY0luZm8sIGhCcywgbUJpdHMpICk7Cn0KCnZvaWQgYWR0c1dyaXRlX0NyY0VuZFJlZygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfQURUUyBwQWR0cywgLyohPCBwb2ludGVyIHRvIGFkdHMgY3JjIGluZm8gc3R1Y3R1cmUgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIQU5ETEVfRkRLX0JJVFNUUkVBTSBoQnMsICAgLyohPCBoYW5kbGUgdG8gY3VycmVudCBiaXQgYnVmZmVyIHN0cnVjdHVyZSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCByZWcgICAgICAgICAgICAgICAgICAgIC8qITwgY3JjIHJlZ2lvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKQp7CiAgaWYgKHBBZHRzLT5wcm90ZWN0aW9uX2Fic2VudCA9PSAwKQogIHsKICAgIEZES2NyY0VuZFJlZygmcEFkdHMtPmNyY0luZm8sIGhCcywgcmVnKTsKICB9Cn0KCmludCBhZHRzV3JpdGVfR2V0SGVhZGVyQml0cyggSEFORExFX0FEVFMgaEFkdHMgKQp7CiAgaW50IGJpdHMgPSAwOwoKICBpZiAoaEFkdHMtPmN1cnJlbnRCbG9jayA9PSAwKSB7CiAgICAvKiBTdGF0aWMgYW5kIHZhcmlhYmxlIGhlYWRlciBiaXRzICovCiAgICBiaXRzID0gNTY7CiAgICBpZiAoIWhBZHRzLT5wcm90ZWN0aW9uX2Fic2VudCkgewogICAgICAvKiBBZGQgaGVhZGVyLyBzaW5nbGUgcmF3IGRhdGEgYmxvY2sgQ1JDIGJpdHMgKi8KICAgICAgYml0cyArPSAxNjsKICAgICAgaWYgKGhBZHRzLT5udW1fcmF3X2Jsb2Nrcz4wKSB7CiAgICAgICAgLyogQWRkIGJpdHMgb2YgcmF3IGRhdGEgYmxvY2sgcG9zaXRpb24gbWFya2VycyAqLwogICAgICAgIGJpdHMgKz0gKGhBZHRzLT5udW1fcmF3X2Jsb2NrcykqMTY7CiAgICAgIH0KICAgIH0KICB9CiAgaWYgKCFoQWR0cy0+cHJvdGVjdGlvbl9hYnNlbnQgJiYgaEFkdHMtPm51bV9yYXdfYmxvY2tzPjApIHsKICAgIC8qIEFkZCByYXcgZGF0YSBibG9jayBDUkMgYml0cy4gTm90IHJlYWxseSBwYXJ0IG9mIHRoZSBoZWFkZXIsIHB1dCB0aGV5IGNhdXNlIGJpdCBvdmVyaGVhZCB0byBiZSBhY2NvdW50ZWQuICovCiAgICBiaXRzICs9IDE2OwogIH0KCiAgaEFkdHMtPmhlYWRlckJpdHMgPSBiaXRzOwoKICByZXR1cm4gYml0czsKfQoKSU5UIGFkdHNXcml0ZV9Jbml0KEhBTkRMRV9BRFRTIGhBZHRzLCBDT0RFUl9DT05GSUcgKmNvbmZpZykKewogIC8qIFNhbml0eSBjaGVja3MgKi8KICBpZiAoIGNvbmZpZy0+blN1YkZyYW1lcyA8IDEKICAgIHx8IGNvbmZpZy0+blN1YkZyYW1lcyA+IDQKICAgIHx8IChpbnQpY29uZmlnLT5hb3QgPiA0CiAgICB8fCAoaW50KWNvbmZpZy0+YW90IDwgMSApIHsKICAgIHJldHVybiAtMTsKICB9CgogIC8qIGZpeGVkIGhlYWRlciAqLwogIGlmIChjb25maWctPmZsYWdzICYgQ0NfTVBFR19JRCkgewogICAgaEFkdHMtPm1wZWdfaWQgPSAwOyAvKiBNUEVHIDQgKi8KICB9IGVsc2UgewogICAgaEFkdHMtPm1wZWdfaWQgPSAxOyAvKiBNUEVHIDIgKi8KICB9CiAgaEFkdHMtPmxheWVyPTA7CiAgaEFkdHMtPnByb3RlY3Rpb25fYWJzZW50ID0gISAoY29uZmlnLT5mbGFncyAmIENDX1BST1RFQ1RJT04pOwogIGhBZHRzLT5wcm9maWxlID0gKChpbnQpY29uZmlnLT5hb3QpIC0gMTsKICBoQWR0cy0+c2FtcGxlX2ZyZXFfaW5kZXggPSBnZXRTYW1wbGluZ1JhdGVJbmRleChjb25maWctPnNhbXBsaW5nUmF0ZSk7CiAgaEFkdHMtPnNhbXBsZV9mcmVxID0gY29uZmlnLT5zYW1wbGluZ1JhdGU7CiAgaEFkdHMtPnByaXZhdGVfYml0PTA7CiAgaEFkdHMtPmNoYW5uZWxfbW9kZSA9IGNvbmZpZy0+Y2hhbm5lbE1vZGU7CiAgaEFkdHMtPm9yaWdpbmFsPTA7CiAgaEFkdHMtPmhvbWU9MDsKICAvKiB2YXJpYWJsZSBoZWFkZXIgKi8KICBoQWR0cy0+Y29weXJpZ2h0X2lkPTA7CiAgaEFkdHMtPmNvcHlyaWdodF9zdGFydD0wOwoKICBoQWR0cy0+bnVtX3Jhd19ibG9ja3M9Y29uZmlnLT5uU3ViRnJhbWVzLTE7IC8qIDAgbWVhbnMgMSByYXcgZGF0YSBibG9jayAqLwoKICBGREtjcmNJbml0KCZoQWR0cy0+Y3JjSW5mbywgMHg4MDA1LCAweEZGRkYsIDE2KTsKCiAgaEFkdHMtPmN1cnJlbnRCbG9jayA9IDA7CgoKICByZXR1cm4gMDsKfQoKaW50IGFkdHNXcml0ZV9FbmNvZGVIZWFkZXIoSEFORExFX0FEVFMgaEFkdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGhCaXRTdHJlYW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBidWZmZXJfZnVsbG5lc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmcmFtZV9sZW5ndGgpCnsKICBJTlQgY3JjSW5kZXggPSAwOwoKCiAgaEFkdHMtPmhlYWRlckJpdHMgPSBhZHRzV3JpdGVfR2V0SGVhZGVyQml0cyhoQWR0cyk7CgogIEZES19BU1NFUlQoKChmcmFtZV9sZW5ndGgraEFkdHMtPmhlYWRlckJpdHMpLzgpPDB4MjAwMCk7ICAgICAgLyoxMyBiaXQqLwogIEZES19BU1NFUlQoYnVmZmVyX2Z1bGxuZXNzPDB4ODAwKTsgICAgLyogMTEgYml0ICAgKi8KCiAgaWYgKCFoQWR0cy0+cHJvdGVjdGlvbl9hYnNlbnQpIHsKICAgIEZES2NyY1Jlc2V0KCZoQWR0cy0+Y3JjSW5mbyk7CiAgfQoKICBpZiAoaEFkdHMtPmN1cnJlbnRCbG9jayA9PSAwKSB7CiAgICBGREtyZXNldEJpdGJ1ZmZlcihoQml0U3RyZWFtLCBCU19XUklURVIpOwogIH0KCiAgaEFkdHMtPnN1YkZyYW1lU3RhcnRCaXQgPSBGREtnZXRWYWxpZEJpdHMoaEJpdFN0cmVhbSk7CgogIC8qIFNraXAgbmV3IGhlYWRlciBpZiB0aGlzIGlzIHJhdyBkYXRhIGJsb2NrIDEuLm4gKi8KICBpZiAoaEFkdHMtPmN1cnJlbnRCbG9jayA9PSAwKQogIHsKICAgIEZES3Jlc2V0Qml0YnVmZmVyKGhCaXRTdHJlYW0sIEJTX1dSSVRFUik7CgogICAgaWYgKGhBZHRzLT5udW1fcmF3X2Jsb2NrcyA9PSAwKSB7CiAgICAgIGNyY0luZGV4ID0gYWR0c1dyaXRlX0NyY1N0YXJ0UmVnKGhBZHRzLCBoQml0U3RyZWFtLCAwKTsKICAgIH0KCiAgICAvKiBmaXhlZCBoZWFkZXIgKi8KICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLCAweEZGRiwgMTIpOwogICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0sIGhBZHRzLT5tcGVnX2lkLCAxKTsKICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLCBoQWR0cy0+bGF5ZXIsIDIpOwogICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0sIGhBZHRzLT5wcm90ZWN0aW9uX2Fic2VudCwgMSk7CiAgICBGREt3cml0ZUJpdHMoaEJpdFN0cmVhbSwgaEFkdHMtPnByb2ZpbGUsIDIpOwogICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0sIGhBZHRzLT5zYW1wbGVfZnJlcV9pbmRleCwgNCk7CiAgICBGREt3cml0ZUJpdHMoaEJpdFN0cmVhbSwgaEFkdHMtPnByaXZhdGVfYml0LCAxKTsKICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLCBnZXRDaGFubmVsQ29uZmlnKGhBZHRzLT5jaGFubmVsX21vZGUpLCAzKTsKICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLCBoQWR0cy0+b3JpZ2luYWwsIDEpOwogICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0sIGhBZHRzLT5ob21lLCAxKTsKICAgIC8qIHZhcmlhYmxlIGhlYWRlciAqLwogICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0sIGhBZHRzLT5jb3B5cmlnaHRfaWQsIDEpOwogICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0sIGhBZHRzLT5jb3B5cmlnaHRfc3RhcnQsIDEpOwogICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0sIChmcmFtZV9sZW5ndGggKyBoQWR0cy0+aGVhZGVyQml0cyk+PjMsIDEzKTsKICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLCBidWZmZXJfZnVsbG5lc3MsIDExKTsKICAgIEZES3dyaXRlQml0cyhoQml0U3RyZWFtLCBoQWR0cy0+bnVtX3Jhd19ibG9ja3MsIDIpOwoKICAgIGlmICghaEFkdHMtPnByb3RlY3Rpb25fYWJzZW50KSB7CiAgICAgIGludCBpOwoKICAgICAgLyogRW5kIGhlYWRlciBDUkMgcG9ydGlvbiBmb3Igc2luZ2xlIHJhdyBkYXRhIGJsb2NrIGFuZCB3cml0ZSBkdW1teSB6ZXJvIHZhbHVlcyBmb3IgdW5rbm93biBmaWVsZHMuICovCiAgICAgIGlmIChoQWR0cy0+bnVtX3Jhd19ibG9ja3MgPT0gMCkgewogICAgICAgIGFkdHNXcml0ZV9DcmNFbmRSZWcoaEFkdHMsIGhCaXRTdHJlYW0sIGNyY0luZGV4KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBmb3IgKGk9MDsgaTxoQWR0cy0+bnVtX3Jhd19ibG9ja3M7IGkrKykgewogICAgICAgICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0sIDAsIDE2KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgRkRLd3JpdGVCaXRzKGhCaXRTdHJlYW0sIDAsIDE2KTsKICAgIH0KICB9IC8qIEVuZCBvZiBBRFRTIGhlYWRlciAqLwoKICByZXR1cm4gMDsKfQoKdm9pZCBhZHRzV3JpdGVfRW5kUmF3RGF0YUJsb2NrKEhBTkRMRV9BRFRTIGhBZHRzLAogICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRV9GREtfQklUU1RSRUFNIGhCcywKICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgKnBCaXRzKQp7CiAgaWYgKCFoQWR0cy0+cHJvdGVjdGlvbl9hYnNlbnQpIHsKICAgIEZES19CSVRTVFJFQU0gYnNXcml0ZXI7CgogICAgRkRLaW5pdEJpdFN0cmVhbSgmYnNXcml0ZXIsIGhCcy0+aEJpdEJ1Zi5CdWZmZXIsIGhCcy0+aEJpdEJ1Zi5idWZTaXplLCAwLCBCU19XUklURVIpOwogICAgRkRLcHVzaEZvcigmYnNXcml0ZXIsIDU2KTsKCiAgICBpZiAoaEFkdHMtPm51bV9yYXdfYmxvY2tzID09IDApIHsKICAgICAgRkRLd3JpdGVCaXRzKCZic1dyaXRlciwgRkRLY3JjR2V0Q1JDKCZoQWR0cy0+Y3JjSW5mbyksIDE2KTsKICAgIH0gZWxzZSB7CiAgICAgIGludCBkaXN0YW5jZTsKCiAgICAgIC8qIFdyaXRlIENSQyBvZiBjdXJyZW50IHJhdyBkYXRhIGJsb2NrICovCiAgICAgIEZES3dyaXRlQml0cyhoQnMsIEZES2NyY0dldENSQygmaEFkdHMtPmNyY0luZm8pLCAxNik7CgogICAgICAvKiBXcml0ZSBkaXN0YW5jZSB0byBjdXJyZW50IGRhdGEgYmxvY2sgKi8KICAgICAgaWYgKGhBZHRzLT5jdXJyZW50QmxvY2sgPCBoQWR0cy0+bnVtX3Jhd19ibG9ja3MpIHsKICAgICAgICBGREtwdXNoRm9yKCZic1dyaXRlciwgaEFkdHMtPmN1cnJlbnRCbG9jayoxNik7CiAgICAgICAgZGlzdGFuY2UgPSBGREtnZXRWYWxpZEJpdHMoaEJzKSAtICg1NiArIChoQWR0cy0+bnVtX3Jhd19ibG9ja3MpKjE2ICsgMTYpOwogICAgICAgIEZES3dyaXRlQml0cygmYnNXcml0ZXIsIGRpc3RhbmNlPj4zLCAxNik7CiAgICAgIH0KICAgIH0KICAgIEZES3N5bmNDYWNoZSgmYnNXcml0ZXIpOwogIH0KCiAgLyogV3JpdGUgdG90YWwgZnJhbWUgbGVudGggZm9yIG11bHRpcGxlIHJhdyBkYXRhIGJsb2NrcyBhbmQgaGVhZGVyIENSQyAqLwogIGlmIChoQWR0cy0+bnVtX3Jhd19ibG9ja3MgPiAwICYmIGhBZHRzLT5jdXJyZW50QmxvY2sgPT0gaEFkdHMtPm51bV9yYXdfYmxvY2tzKSB7CiAgICBGREtfQklUU1RSRUFNIGJzV3JpdGVyOwogICAgaW50IGNyY0luZGV4ID0gMDsKCiAgICBGREtpbml0Qml0U3RyZWFtKCZic1dyaXRlciwgaEJzLT5oQml0QnVmLkJ1ZmZlciwgaEJzLT5oQml0QnVmLmJ1ZlNpemUsIDAsIEJTX1dSSVRFUik7CgogICAgaWYgKCFoQWR0cy0+cHJvdGVjdGlvbl9hYnNlbnQpIHsKICAgICAgRkRLY3JjUmVzZXQoJmhBZHRzLT5jcmNJbmZvKTsKICAgICAgY3JjSW5kZXggPSBGREtjcmNTdGFydFJlZygmaEFkdHMtPmNyY0luZm8sICZic1dyaXRlciwgMCk7CiAgICB9CiAgICAvKiBXcml0ZSB0b3RhbCBmcmFtZSBsZW5ndGggKi8KICAgIEZES3B1c2hGb3IoJmJzV3JpdGVyLCA1Ni0yOCsyKTsKICAgIEZES3dyaXRlQml0cygmYnNXcml0ZXIsIEZES2dldFZhbGlkQml0cyhoQnMpPj4zLCAxMyk7CgogICAgLyogV3JpdGUgaGVhZGVyIENSQyAqLwogICAgaWYgKCFoQWR0cy0+cHJvdGVjdGlvbl9hYnNlbnQpIHsKICAgICAgRkRLcHVzaEZvcigmYnNXcml0ZXIsIDExKzIgKyAoaEFkdHMtPm51bV9yYXdfYmxvY2tzKSoxNik7CiAgICAgIEZES2NyY0VuZFJlZygmaEFkdHMtPmNyY0luZm8sICZic1dyaXRlciwgY3JjSW5kZXgpOwogICAgICBGREt3cml0ZUJpdHMoJmJzV3JpdGVyLCBGREtjcmNHZXRDUkMoJmhBZHRzLT5jcmNJbmZvKSwgMTYpOwogICAgfQogICAgRkRLc3luY0NhY2hlKCZic1dyaXRlcik7CiAgfQoKICAvKiBDb3JyZWN0ICpwQml0cyB0byByZWZsZWN0IHRoZSBhbW91bnQgb2YgYml0cyBvZiB0aGUgY3VycmVudCBzdWJmcmFtZSAqLwogICpwQml0cyAtPSBoQWR0cy0+c3ViRnJhbWVTdGFydEJpdDsKICBpZiAoIWhBZHRzLT5wcm90ZWN0aW9uX2Fic2VudCAmJiBoQWR0cy0+bnVtX3Jhd19ibG9ja3MgPiAwKSB7CiAgICAvKiBGaXh1cCBDUkMgYml0cywgc2luY2UgdGhleSBjb21lIGFmdGVyIGVhY2ggcmF3IGRhdGEgYmxvY2sgKi8KICAgICpwQml0cyArPSAxNjsKICB9CiAgaEFkdHMtPmN1cnJlbnRCbG9jaysrOwp9Cgo=