LyoKICogdGFibGVfaXRlcmF0b3IuYyAKICovCi8qIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvcHlyaWdodChzKS4gIFNlZQogKiB0aGUgTmV0LVNOTVAncyBDT1BZSU5HIGZpbGUgZm9yIG1vcmUgZGV0YWlscyBhbmQgb3RoZXIgY29weXJpZ2h0cwogKiB0aGF0IG1heSBhcHBseToKICovCi8qCiAqIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgY29weXJpZ2h0ZWQgYnk6CiAqIENvcHlyaWdodCCpIDIwMDMgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBVc2UgaXMgc3ViamVjdCB0byBsaWNlbnNlIHRlcm1zIHNwZWNpZmllZCBpbiB0aGUgQ09QWUlORyBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhlIE5ldC1TTk1QIHBhY2thZ2UuCiAqLwoKLyoqIEBkZWZncm91cCB0YWJsZV9pdGVyYXRvciB0YWJsZV9pdGVyYXRvcgogKiAgVGhlIHRhYmxlIGl0ZXJhdG9yIGhlbHBlciBpcyBkZXNpZ25lZCB0byBzaW1wbGlmeSB0aGUgdGFzayBvZiB3cml0aW5nIGEgdGFibGUgaGFuZGxlciBmb3IgdGhlIG5ldC1zbm1wIGFnZW50IHdoZW4gdGhlIGRhdGEgYmVpbmcgYWNjZXNzZWQgaXMgbm90IGluIGFuIG9pZCBzb3J0ZWQgZm9ybSBhbmQgbXVzdCBiZSBhY2Nlc3NlZCBleHRlcm5hbGx5LgogKiAgQGluZ3JvdXAgdGFibGUKICAgIEZ1bmN0aW9uYWxseSwgaXQgaXMgYSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIHRoZSBtb3JlCiAgICBnZW5lcmljIHRhYmxlIGhlbHBlciBidXQgZWFzaWVzIHRoZSBidXJkZW4gb2YgR0VUTkVYVCBwcm9jZXNzaW5nIGJ5CiAgICBtYW51YWxseSBsb29waW5nIHRocm91Z2ggYWxsIHRoZSBkYXRhIGluZGV4ZXMgcmV0cmlldmVkIHRocm91Z2gKICAgIGZ1bmN0aW9uIGNhbGxzIHdoaWNoIHNob3VsZCBiZSBzdXBwbGllZCBieSB0aGUgbW9kdWxlIHRoYXQgd2lzaGVzCiAgICBoZWxwLiAgVGhlIG1vZHVsZSB0aGUgdGFibGVfaXRlcmF0b3IgaGVscHMgc2hvdWxkLCBhZnRlcndhcmRzLAogICAgbmV2ZXIgYmUgY2FsbGVkIGZvciB0aGUgY2FzZSBvZiAiTU9ERV9HRVRORVhUIiBhbmQgb25seSBmb3IgdGhlIEdFVAogICAgYW5kIFNFVCByZWxhdGVkIG1vZGVzIGluc3RlYWQuCiAKICAgIFRoZSBmdW5kYW1lbnRhbCBub3Rpb24gYmV0d2VlbiB0aGUgdGFibGUgaXRlcmF0b3IgaXMgdGhhdCBpdAogICAgYWxsb3dzIHlvdXIgY29kZSB0byBpdGVyYXRlIG92ZXIgZWFjaCAicm93IiB3aXRoaW4geW91ciBkYXRhCiAgICBzdG9yYWdlIG1lY2hhbmlzbSwgd2l0aG91dCByZXF1aXJpbmcgdGhhdCBpdCBiZSBzb3J0ZWQgaW4gYQogICAgU05NUC1pbmRleC1jb21wbGlhbnQgbWFubmVyLiAgVGhyb3VnaCB0aGUgZ2V0X2ZpcnN0X2RhdGFfcG9pbnQgYW5kCiAgICBnZXRfbmV4dF9kYXRhX3BvaW50IGhvb2tzLCB0aGUgdGFibGVfaXRlcmF0b3IgaGVscGVyIHdpbGwKICAgIHJlcGVhdGVkbHkgY2FsbCB5b3VyIGhvb2tzIHRvIGZpbmQgdGhlICJwcm9wZXIiIHJvdyBvZiBkYXRhIHRoYXQKICAgIG5lZWRzIHByb2Nlc3NpbmcuICBUaGUgZm9sbG93aW5nIGNvbmNlcHRzIGFyZSBpbXBvcnRhbnQ6CgogICAgICAtIEEgbG9vcCBjb250ZXh0IGlzIGEgcG9pbnRlciB3aGljaCBpbmRpY2F0ZXMgd2hlcmUgaW4gdGhlCiAgICAgICAgY3VycmVudCBwcm9jZXNzaW5nIG9mIGEgc2V0IG9mIHJvd3MgeW91IGN1cnJlbnRseSBhcmUuICBBbGxvd3MKCXRoZSBnZXRfKl9kYXRhX3BvaW50IHJvdXRpbmVzIHRvIG1vdmUgZnJvbSBvbmUgcm93IHRvIHRoZSBuZXh0LAoJb25jZSB0aGUgaXRlcmF0b3IgaGFuZGxlciBoYXMgaWRlbnRpZmllZCB0aGUgYXBwcm9wcmlhdGUgcm93IGZvcgoJdGhpcyByZXF1ZXN0LCB0aGUgam9iIG9mIHRoZSBsb29wIGNvbnRleHQgaXMgZG9uZS4gIFRoZQogICAgICAgIG1vc3Qgc2ltcGxlIGV4YW1wbGUgd291bGQgYmUgYSBwb2ludGVyIHRvIGFuIGludGVnZXIgd2hpY2gKICAgICAgICBzaW1wbHkgY291bnRzIHJvd3MgZnJvbSAxIHRvIFguICBNb3JlIGNvbW1vbmx5LCBpdCBtaWdodCBiZSBhCiAgICAgICAgcG9pbnRlciB0byBhIGxpbmtlZCBsaXN0IG5vZGUsIG9yIHNvbWVvdGhlciBpbnRlcm5hbCBvcgogICAgICAgIGV4dGVybmFsIHJlZmVyZW5jZSB0byBhIGRhdGEgc2V0IChmaWxlIHNlZWsgdmFsdWUsIGFycmF5CiAgICAgICAgcG9pbnRlciwgLi4uKS4gIElmIGFsbG9jYXRlZCBkdXJpbmcgaXRlcmF0aW9uLCBlaXRoZXIgdGhlCiAgICAgICAgZnJlZV9sb29wX2NvbnRleHRfYXRfZW5kIChwcmVmZXJhYmx5KSBvciB0aGUgZnJlZV9sb29wX2NvbnRleHQKICAgICAgICBwb2ludGVycyBzaG91bGQgYmUgc2V0LgoKICAgICAgLSBBIGRhdGEgY29udGV4dCBpcyBzb21ldGhpbmcgdGhhdCB5b3VyIGhhbmRsZXIgY29kZSBjYW4gdXNlCiAgICAgICAgaW4gb3JkZXIgdG8gcmV0cmlldmUgdGhlIHJlc3Qgb2YgdGhlIGRhdGEgZm9yIHRoZSBuZWVkZWQKICAgICAgICByb3cuICBUaGlzIGRhdGEgY2FuIGJlIGFjY2Vzc2VkIGluIHlvdXIgaGFuZGxlciB2aWEKCW5ldHNubXBfZXh0cmFjdF9pdGVyYXRvcl9jb250ZXh0IGFwaSB3aXRoIHRoZSBuZXRzbm1wX3JlcXVlc3RfaW5mbwoJc3RydWN0dXJlIHRoYXQncyBwYXNzZWQgaW4uCglUaGUgaW1wb3J0YW50IGRpZmZlcmVuY2UgYmV0d2VlbiBhIGxvb3AgY29udGV4dCBhbmQgYQogICAgICAgIGRhdGEgY29udGV4dCBpcyB0aGF0IG11bHRpcGxlIGRhdGEgY29udGV4dHMgY2FuIGJlIGtlcHQgYnkgdGhlCiAgICAgICAgdGFibGVfaXRlcmF0b3IgaGVscGVyLCB3aGVyZSBhcyBvbmx5IG9uZSBsb29wIGNvbnRleHQgd2lsbAogICAgICAgIGV2ZXIgYmUgaGVsZCBieSB0aGUgdGFibGVfaXRlcmF0b3IgaGVscGVyLiAgSWYgYWxsb2NhdGVkCiAgICAgICAgZHVyaW5nIGl0ZXJhdGlvbiB0aGUgZnJlZV9kYXRhX2NvbnRleHQgcG9pbnRlciBzaG91bGQgYmUgc2V0CiAgICAgICAgdG8gYW4gYXBwcm9wcmlhdGUgZnVuY3Rpb24uCiAKICAgIFRoZSB0YWJsZSBpdGVyYXRvciBvcGVyYXRlcyBpbiBhIHNlcmllcyBvZiBzdGVwcyB0aGF0IGNhbGwgeW91cgogICAgY29kZSBob29rcyBmcm9tIHlvdXIgbmV0c25tcF9pdGVyYXRvcl9pbmZvIHJlZ2lzdHJhdGlvbiBwb2ludGVyLgogCiAgICAgIC0gdGhlIGdldF9maXJzdF9kYXRhX3BvaW50IGhvb2sgaXMgY2FsbGVkIGF0IHRoZSBiZWdpbm5pbmcgb2YKICAgICAgICBwcm9jZXNzaW5nLiAgSXQgc2hvdWxkIHNldCB0aGUgdmFyaWFibGUgbGlzdCB0byBhIGxpc3Qgb2YKICAgICAgICBpbmRleGVzIGZvciB0aGUgZ2l2ZW4gdGFibGUuICBJdCBzaG91bGQgYWxzbyBzZXQgdGhlCiAgICAgICAgbG9vcF9jb250ZXh0IGFuZCBtYXliZSBhIGRhdGFfY29udGV4dCB3aGljaCB5b3Ugd2lsbCBnZXQgYQogICAgICAgIHBvaW50ZXIgYmFjayB0byB3aGVuIGl0IG5lZWRzIHRvIGNhbGwgeW91ciBjb2RlIHRvIHJldHJpZXZlCiAgICAgICAgYWN0dWFsIGRhdGEgbGF0ZXIuICBUaGUgbGlzdCBvZiBpbmRleGVzIHNob3VsZCBiZSByZXR1cm5lZAogICAgICAgIGFmdGVyIGJlaW5nIHVwZGF0ZS4KCiAgICAgIC0gdGhlIGdldF9uZXh0X2RhdGFfcG9pbnQgaG9vayBpcyB0aGVuIGNhbGxlZCByZXBlYXRlZGx5IGFuZCBpcwogICAgICAgIHBhc3NlZCB0aGUgbG9vcCBjb250ZXh0IGFuZCB0aGUgZGF0YSBjb250ZXh0IGZvciBpdCB0byB1cGRhdGUuCiAgICAgICAgVGhlIGluZGV4ZXMsIGxvb3AgY29udGV4dCBhbmQgZGF0YSBjb250ZXh0IHNob3VsZCBhbGwgYmUKICAgICAgICB1cGRhdGVkIGlmIG1vcmUgZGF0YSBpcyBhdmFpbGFibGUsIG90aGVyd2lzZSB0aGV5IHNob3VsZCBiZQogICAgICAgIGxlZnQgYWxvbmUgYW5kIGEgTlVMTCBzaG91bGQgYmUgcmV0dXJuZWQuICBJZGVhbGx5LCBpdCBzaG91bGQKICAgICAgICB1cGRhdGUgdGhlIGxvb3AgY29udGV4dCB3aXRob3V0IHRoZSBuZWVkIHRvIHJlYWxsb2NhdGUgaXQuICBJZgogICAgICAgIHJlYWxsb2NhdGlvbiBpcyBuZWNlc3NhcnkgZm9yIGV2ZXJ5IGl0ZXJhdGl2ZSBzdGVwLCB0aGVuIHRoZQogICAgICAgIGZyZWVfbG9vcF9jb250ZXh0IGZ1bmN0aW9uIHBvaW50ZXIgc2hvdWxkIGJlIHNldC4gIElmIG5vdCwKICAgICAgICB0aGVuIHRoZSBmcmVlX2xvb3BfY29udGV4dF9hdF9lbmQgcG9pbnRlciBzaG91bGQgYmUgc2V0LCB3aGljaAogICAgICAgIGlzIG1vcmUgZWZmaWNpZW50IHNpbmNlIGEgbWFsbG9jL2ZyZWUgd2lsbCBvbmx5IGJlIHBlcmZvcm1lZAogICAgICAgIG9uY2UgZm9yIGV2ZXJ5IGl0ZXJhdGlvbi4KICoKICogIEB7CiAqLwoKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWNvbmZpZy5oPgoKI2lmIEhBVkVfU1RSSU5HX0gKI2luY2x1ZGUgPHN0cmluZy5oPgojZWxzZQojaW5jbHVkZSA8c3RyaW5ncy5oPgojZW5kaWYKCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1pbmNsdWRlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvbmV0LXNubXAtYWdlbnQtaW5jbHVkZXMuaD4KCiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC90YWJsZS5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvc2VyaWFsaXplLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC90YWJsZV9pdGVyYXRvci5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvc3Rhc2hfY2FjaGUuaD4KCi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICoKICogSXRlcmF0b3IgQVBJOiBUYWJsZSBtYWludGVuYW5jZQogKgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovCgogICAgLyoKICAgICAqIEl0ZXJhdG9yLWJhc2VkIHRhYmxlcyBhcmUgdHlwaWNhbGx5IG1haW50YWluZWQgYnkgZXh0ZXJuYWwKICAgICAqICBjb2RlLCBhbmQgdGhpcyBoZWxwZXIgaXMgcmVhbGx5IG9ubHkgY29uY2VybmVkIHdpdGgKICAgICAqICBtYXBwaW5nIGJldHdlZW4gYSB3YWxrIHRocm91Z2ggdGhpcyBsb2NhbCByZXByZXNlbnRhdGlvbiwKICAgICAqICBhbmQgdGhlIHJlcXVpcmVtZW50cyBvZiBTTk1QIHRhYmxlIG9yZGVyaW5nLgogICAgICogSG93ZXZlciwgdGhlcmUncyBhIGNhc2UgdG8gYmUgbWFkZSBmb3IgY29uc2lkZXJpbmcgdGhlCiAgICAgKiAgaXRlcmF0b3IgaW5mbyBzdHJ1Y3R1cmUgYXMgZW5jYXBzdWxhdGluZyB0aGUgdGFibGUsIHNvCiAgICAgKiAgaXQncyBwcm9iYWJseSB3b3J0aCBkZWZpbmluZyB0aGUgdGFibGUgY3JlYXRpb24vZGVsZXRpb24KICAgICAqICByb3V0aW5lcyBmcm9tIHRoZSBnZW5lcmljIEFQSS4KICAgICAqCiAgICAgKiBUaW1lIHdpbGwgc2hvdyB3aGV0aGVyIHRoaXMgaXMgYSBzZW5zaWJsZSBhcHByb2FjaCBvciBub3QuCiAgICAgKi8KbmV0c25tcF9pdGVyYXRvcl9pbmZvICoKbmV0c25tcF9pdGVyYXRvcl9jcmVhdGVfdGFibGUoIE5ldHNubXBfRmlyc3RfRGF0YV9Qb2ludCAqZmlyc3REUCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5ldHNubXBfTmV4dF9EYXRhX1BvaW50ICAqbmV4dERQLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmV0c25tcF9GaXJzdF9EYXRhX1BvaW50ICpnZXRpZHgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgICAgKmluZGV4ZXMpCnsKICAgIG5ldHNubXBfaXRlcmF0b3JfaW5mbyAqaWluZm8gPQogICAgICAgIFNOTVBfTUFMTE9DX1RZUEVERUYobmV0c25tcF9pdGVyYXRvcl9pbmZvKTsKCiAgICBpZiAoICFpaW5mbyApCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgaWYgKCBpbmRleGVzICkKICAgICAgICBpaW5mby0+aW5kZXhlcyA9IHNubXBfY2xvbmVfdmFyYmluZChpbmRleGVzKTsKICAgIGlpbmZvLT5nZXRfZmlyc3RfZGF0YV9wb2ludCA9IGZpcnN0RFA7CiAgICBpaW5mby0+Z2V0X25leHRfZGF0YV9wb2ludCAgPSBuZXh0RFA7CiAgICBpaW5mby0+Z2V0X3Jvd19pbmRleGVzICAgICAgPSBnZXRpZHg7CgogICAgcmV0dXJuIGlpbmZvOwp9Cgp2b2lkCm5ldHNubXBfaXRlcmF0b3JfZGVsZXRlX3RhYmxlKCBuZXRzbm1wX2l0ZXJhdG9yX2luZm8gKmlpbmZvICkKewogICAgaWYgKCFpaW5mbykKICAgICAgICByZXR1cm47CgogICAgaWYgKGlpbmZvLT5pbmRleGVzKSB7CiAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQoIGlpbmZvLT5pbmRleGVzICk7CiAgICAgICAgaWluZm8tPmluZGV4ZXMgPSBOVUxMOwogICAgfQogICAgU05NUF9GUkVFKCBpaW5mbyApOwp9CgogICAgLyoKICAgICAqIFRoZSByZXN0IG9mIHRoZSB0YWJsZSBtYWludGVuYW5jZSBzZWN0aW9uIG9mIHRoZQogICAgICogICBnZW5lcmljIHRhYmxlIEFQSSBpcyBOb3QgQXBwbGljYWJsZSB0byB0aGlzIGhlbHBlci4KICAgICAqCiAgICAgKiBUaGUgY29udGVudHMgb2YgYSBpdGVyYXRvci1iYXNlZCB0YWJsZSB3aWxsIGJlCiAgICAgKiAgbWFpbnRhaW5lZCBieSB0aGUgdGFibGUtc3BlY2lmaWMgbW9kdWxlIGl0c2VsZi4KICAgICAqLwoKLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQogKgogKiBJdGVyYXRvciBBUEk6IE1JQiBtYWludGVuYW5jZQogKgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovCgovKiogcmV0dXJucyBhIG5ldHNubXBfbWliX2hhbmRsZXIgb2JqZWN0IGZvciB0aGUgdGFibGVfaXRlcmF0b3IgaGVscGVyICovCm5ldHNubXBfbWliX2hhbmRsZXIgKgpuZXRzbm1wX2dldF90YWJsZV9pdGVyYXRvcl9oYW5kbGVyKG5ldHNubXBfaXRlcmF0b3JfaW5mbyAqaWluZm8pCnsKICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKm1lOwoKICAgIGlmICghaWluZm8pCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgbWUgPQogICAgICAgIG5ldHNubXBfY3JlYXRlX2hhbmRsZXIoVEFCTEVfSVRFUkFUT1JfTkFNRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdGFibGVfaXRlcmF0b3JfaGVscGVyX2hhbmRsZXIpOwoKICAgIGlmICghbWUpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgbWUtPm15dm9pZCA9IGlpbmZvOwogICAgcmV0dXJuIG1lOwp9CgovKiogCiAqIENyZWF0ZXMgYW5kIHJlZ2lzdGVycyBhIHRhYmxlIGl0ZXJhdG9yIGhlbHBlciBoYW5kbGVyIGNhbGxpbmcgCiAqIG5ldHNubXBfY3JlYXRlX2hhbmRsZXIgd2l0aCBhIGhhbmRsZXIgbmFtZSBzZXQgdG8gVEFCTEVfSVRFUkFUT1JfTkFNRSAKICogYW5kIGFjY2VzcyBtZXRob2QsIG5ldHNubXBfdGFibGVfaXRlcmF0b3JfaGVscGVyX2hhbmRsZXIuCiAqCiAqIElmIE5PVF9TRVJJQUxJWkVEIGlzIG5vdCBkZWZpbmVkIHRoZSBmdW5jdGlvbiBpbmplY3RzIHRoZSBzZXJpYWxpemUKICogaGFuZGxlciBpbnRvIHRoZSBjYWxsaW5nIGNoYWluIHByaW9yIHRvIGNhbGxpbmcgbmV0c25tcF9yZWdpc3Rlcl90YWJsZS4KICoKICogQHBhcmFtIHJlZ2luZm8gaXMgYSBwb2ludGVyIHRvIGEgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiBzdHJ1Y3QKICoKICogQHBhcmFtIGlpbmZvIGlzIGEgcG9pbnRlciB0byBhIG5ldHNubXBfaXRlcmF0b3JfaW5mbyBzdHJ1Y3QKICoKICogQHJldHVybiBNSUJfUkVHSVNURVJFRF9PSyBpcyByZXR1cm5lZCBpZiB0aGUgcmVnaXN0cmF0aW9uIHdhcyBhIHN1Y2Nlc3MuCiAqCUZhaWx1cmVzIGFyZSBNSUJfUkVHSVNUUkFUSU9OX0ZBSUxFRCwgTUlCX0RVUExJQ0FURV9SRUdJU1RSQVRJT04uCiAqCUlmIGlpbmZvIGlzIE5VTEwsIFNOTVBFUlJfR0VORVJSIGlzIHJldHVybmVkLgogKgogKi8KaW50Cm5ldHNubXBfcmVnaXN0ZXJfdGFibGVfaXRlcmF0b3IobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2l0ZXJhdG9yX2luZm8gKmlpbmZvKQp7CiAgICByZWdpbmZvLT5tb2RlcyB8PSBIQU5ETEVSX0NBTl9TVEFTSDsKICAgIG5ldHNubXBfaW5qZWN0X2hhbmRsZXIocmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9nZXRfdGFibGVfaXRlcmF0b3JfaGFuZGxlcihpaW5mbykpOwogICAgaWYgKCFpaW5mbykKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICBpZiAoIWlpbmZvLT5pbmRleGVzICYmIGlpbmZvLT50YWJsZV9yZWdpbmZvICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGlpbmZvLT50YWJsZV9yZWdpbmZvLT5pbmRleGVzICkKICAgICAgICBpaW5mby0+aW5kZXhlcyA9IHNubXBfY2xvbmVfdmFyYmluZCggaWluZm8tPnRhYmxlX3JlZ2luZm8tPmluZGV4ZXMgKTsKCiAgICByZXR1cm4gbmV0c25tcF9yZWdpc3Rlcl90YWJsZShyZWdpbmZvLCBpaW5mby0+dGFibGVfcmVnaW5mbyk7Cn0KCi8qKiBleHRyYWN0cyB0aGUgdGFibGVfaXRlcmF0b3Igc3BlY2lmaWMgZGF0YSBmcm9tIGEgcmVxdWVzdC4KICogVGhpcyBmdW5jdGlvbiBleHRyYWN0cyB0aGUgdGFibGUgaXRlcmF0b3Igc3BlY2lmaWMgZGF0YSBmcm9tIGEgCiAqIG5ldHNubXBfcmVxdWVzdF9pbmZvIG9iamVjdC4gIENhbGxzIG5ldHNubXBfcmVxdWVzdF9nZXRfbGlzdF9kYXRhCiAqIHdpdGggcmVxdWVzdC0+cGFyZW50X2RhdGEgc2V0IHdpdGggZGF0YSBmcm9tIGEgcmVxdWVzdCB0aGF0IHdhcyBhZGRlZCAKICogcHJldmlvdXNseSBieSBhIG1vZHVsZSBhbmQgVEFCTEVfSVRFUkFUT1JfTkFNRSBoYW5kbGVyIG5hbWUuCiAqCiAqIEBwYXJhbSByZXF1ZXN0IHRoZSBuZXRzbm1wIHJlcXVlc3QgaW5mbyBzdHJ1Y3R1cmUKICoKICogQHJldHVybiBhIHZvaWQgcG9pbnRlcihyZXF1ZXN0LT5wYXJlbnRfZGF0YS0+ZGF0YSksIG90aGVyd2lzZSBOVUxMIGlzCiAqICAgICAgICAgcmV0dXJuZWQgaWYgcmVxdWVzdCBpcyBOVUxMIG9yIHJlcXVlc3QtPnBhcmVudF9kYXRhIGlzIE5VTEwgb3IKICogICAgICAgICByZXF1ZXN0LT5wYXJlbnRfZGF0YSBvYmplY3QgaXMgbm90IGZvdW5kLnRoZSBuZXQKICoKICovCk5FVFNOTVBfSU5MSU5FIHZvaWQgICAgKgpuZXRzbm1wX2V4dHJhY3RfaXRlcmF0b3JfY29udGV4dChuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdCkKewogICAgcmV0dXJuIG5ldHNubXBfcmVxdWVzdF9nZXRfbGlzdF9kYXRhKHJlcXVlc3QsIFRBQkxFX0lURVJBVE9SX05BTUUpOwp9CgovKiogaW5zZXJ0cyB0YWJsZV9pdGVyYXRvciBzcGVjaWZpYyBkYXRhIGZvciBhIG5ld2x5CiAqICBjcmVhdGVkIHJvdyBpbnRvIGEgcmVxdWVzdCAqLwpORVRTTk1QX0lOTElORSB2b2lkCm5ldHNubXBfaW5zZXJ0X2l0ZXJhdG9yX2NvbnRleHQobmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3QsIHZvaWQgKmRhdGEpCnsKICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICAgICAgICpyZXE7CiAgICBuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyAqdGFibGVfaW5mbyA9IE5VTEw7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgICAgICAqdGhpc19pbmRleCA9IE5VTEw7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgICAgICAqdGhhdF9pbmRleCA9IE5VTEw7CiAgICBvaWQgICAgICBiYXNlX29pZFtdID0gezAsIDB9OwkvKiBNYWtlIHN1cmUgaW5kZXggT0lEcyBhcmUgbGVnYWwhICovCiAgICBvaWQgICAgICB0aGlzX29pZFtNQVhfT0lEX0xFTl07CiAgICBvaWQgICAgICB0aGF0X29pZFtNQVhfT0lEX0xFTl07CiAgICBzaXplX3QgICB0aGlzX29pZF9sZW4sIHRoYXRfb2lkX2xlbjsKCiAgICBpZiAoIXJlcXVlc3QpCiAgICAgICAgcmV0dXJuOwoKICAgIC8qCiAgICAgKiBXZSdsbCBhZGQgdGhlIG5ldyByb3cgaW5mb3JtYXRpb24gdG8gYW55IHJlcXVlc3QKICAgICAqIHN0cnVjdHVyZSB3aXRoIHRoZSBzYW1lIGluZGV4IHZhbHVlcyBhcyB0aGUgcmVxdWVzdAogICAgICogcGFzc2VkIGluICh3aGljaCBpbmNsdWRlcyB0aGF0IG9uZSEpLgogICAgICoKICAgICAqIFNvIGNvbnN0cnVjdCBhbiBPSUQgYmFzZWQgb24gdGhlc2UgaW5kZXggdmFsdWVzLgogICAgICovCgogICAgdGFibGVfaW5mbyA9IG5ldHNubXBfZXh0cmFjdF90YWJsZV9pbmZvKHJlcXVlc3QpOwogICAgdGhpc19pbmRleCA9IHRhYmxlX2luZm8tPmluZGV4ZXM7CiAgICBidWlsZF9vaWRfbm9hbGxvYyh0aGlzX29pZCwgTUFYX09JRF9MRU4sICZ0aGlzX29pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICBiYXNlX29pZCwgMiwgdGhpc19pbmRleCk7CgogICAgLyoKICAgICAqIFdlIG5lZWQgdG8gbG9vayB0aHJvdWdoIHRoZSB3aG9sZSBvZiB0aGUgcmVxdWVzdCBsaXN0CiAgICAgKiAoYXMgcmVjZWl2ZWQgYnkgdGhlIGN1cnJlbnQgaGFuZGxlciksIGFzIHRoZXJlJ3Mgbm8KICAgICAqIGd1YXJhbnRlZSB0aGF0IHRoaXMgcm91dGluZSB3aWxsIGJlIGNhbGxlZCBieSB0aGUgZmlyc3QKICAgICAqIHZhcmJpbmQgdGhhdCByZWZlcnMgdG8gdGhpcyByb3cuCiAgICAgKiAgIEluIHBhcnRpY3VsYXIsIGEgUm93U3RhdHVzIGNvbnRyb2xsZWQgcm93IGNyZWF0aW9uCiAgICAgKiBtYXkgZWFzaWx5IG9jY3VyIGxhdGVyIGluIHRoZSB2YXJpYWJsZSBsaXN0LgogICAgICoKICAgICAqIFNvIGZpcnN0LCB3ZSByZXdpbmQgdG8gdGhlIGhlYWQgb2YgdGhlIGxpc3QuLi4uCiAgICAgKi8KICAgIGZvciAocmVxPXJlcXVlc3Q7IHJlcS0+cHJldjsgcmVxPXJlcS0+cHJldikKICAgICAgICA7CgogICAgLyoKICAgICAqIC4uLiBhbmQgdGhlbiBzdGFydCBsb29raW5nIGZvciBtYXRjaGluZyBpbmRleGVzCiAgICAgKiAoYnkgY29uc3RydWN0aW5nIE9JRHMgZnJvbSB0aGVzZSBpbmRleCB2YWx1ZXMpCiAgICAgKi8KICAgIGZvciAoOyByZXE7IHJlcT1yZXEtPm5leHQpIHsKICAgICAgICB0YWJsZV9pbmZvID0gbmV0c25tcF9leHRyYWN0X3RhYmxlX2luZm8ocmVxKTsKICAgICAgICB0aGF0X2luZGV4ID0gdGFibGVfaW5mby0+aW5kZXhlczsKICAgICAgICBidWlsZF9vaWRfbm9hbGxvYyh0aGF0X29pZCwgTUFYX09JRF9MRU4sICZ0aGF0X29pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgYmFzZV9vaWQsIDIsIHRoYXRfaW5kZXgpOwogICAgICAKICAgICAgICAvKgogICAgICAgICAqIFRoaXMgcmVxdWVzdCBoYXMgdGhlIHNhbWUgaW5kZXggdmFsdWVzLAogICAgICAgICAqIHNvIGFkZCB0aGUgbmV3bHktY3JlYXRlZCByb3cgaW5mb3JtYXRpb24uCiAgICAgICAgICovCiAgICAgICAgaWYgKHNubXBfb2lkX2NvbXBhcmUodGhpc19vaWQsIHRoaXNfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGF0X29pZCwgdGhhdF9vaWRfbGVuKSA9PSAwKSB7CiAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9hZGRfbGlzdF9kYXRhKHJlcSwKICAgICAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX2RhdGFfbGlzdChUQUJMRV9JVEVSQVRPUl9OQU1FLCBkYXRhLCBOVUxMKSk7CiAgICAgICAgfQogICAgfQp9CgojZGVmaW5lIFRJX1JFUVVFU1RfQ0FDSEUgInRpX2NhY2hlIgoKdHlwZWRlZiBzdHJ1Y3QgdGlfY2FjaGVfaW5mb19zIHsKICAgb2lkIGJlc3RfbWF0Y2hbTUFYX09JRF9MRU5dOwogICBzaXplX3QgYmVzdF9tYXRjaF9sZW47CiAgIHZvaWQgKmRhdGFfY29udGV4dDsKICAgTmV0c25tcF9GcmVlX0RhdGFfQ29udGV4dCAqZnJlZV9jb250ZXh0OwogICBuZXRzbm1wX2l0ZXJhdG9yX2luZm8gKmlpbmZvOwogICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnJlc3VsdHM7Cn0gdGlfY2FjaGVfaW5mbzsKCnN0YXRpYyB2b2lkCm5ldHNubXBfZnJlZV90aV9jYWNoZSh2b2lkICppdCkgewogICAgdGlfY2FjaGVfaW5mbyAqYmVlciA9IGl0OwogICAgaWYgKCFpdCkgcmV0dXJuOwogICAgaWYgKGJlZXItPmRhdGFfY29udGV4dCAmJiBiZWVyLT5mcmVlX2NvbnRleHQpIHsKICAgICAgICAgICAgKGJlZXItPmZyZWVfY29udGV4dCkoYmVlci0+ZGF0YV9jb250ZXh0LCBiZWVyLT5paW5mbyk7CiAgICB9CiAgICBpZiAoYmVlci0+cmVzdWx0cykgewogICAgICAgIHNubXBfZnJlZV92YXJiaW5kKGJlZXItPnJlc3VsdHMpOwogICAgfQogICAgZnJlZShiZWVyKTsKfQoKLyogY2FjaGVzIGluZm9ybWF0aW9uIChpbiB0aGUgcmVxdWVzdCkgd2UnbGwgbmVlZCBhdCBhIGxhdGVyIHBvaW50IGluIHRpbWUgKi8Kc3RhdGljIHRpX2NhY2hlX2luZm8gKgpuZXRzbm1wX2l0ZXJhdG9yX3JlbWVtYmVyKG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgIG9pZCAqb2lkX3RvX3NhdmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IG9pZF90b19zYXZlX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpjYWxsYmFja19kYXRhX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY2FsbGJhY2tfbG9vcF9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfaXRlcmF0b3JfaW5mbyAqaWluZm8pCnsKICAgIHRpX2NhY2hlX2luZm8gKnRpX2luZm87CgogICAgaWYgKCFyZXF1ZXN0IHx8ICFvaWRfdG9fc2F2ZSB8fCBvaWRfdG9fc2F2ZV9sZW4gPiBNQVhfT0lEX0xFTikKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICAvKiBleHRyYWN0IGV4aXN0aW5nIGNhY2hlZCBzdGF0ZSAqLwogICAgdGlfaW5mbyA9IG5ldHNubXBfcmVxdWVzdF9nZXRfbGlzdF9kYXRhKHJlcXVlc3QsIFRJX1JFUVVFU1RfQ0FDSEUpOwoKICAgIC8qIG5vIGV4aXN0aW5nIGNhY2hlZCBzdGF0ZS4gIG1ha2UgYSBuZXcgb25lLiAqLwogICAgaWYgKCF0aV9pbmZvKSB7CiAgICAgICAgdGlfaW5mbyA9IFNOTVBfTUFMTE9DX1RZUEVERUYodGlfY2FjaGVfaW5mbyk7CiAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2FkZF9saXN0X2RhdGEocmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV9kYXRhX2xpc3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoVElfUkVRVUVTVF9DQUNIRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGlfaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9mcmVlX3RpX2NhY2hlKSk7CiAgICB9CgogICAgLyogZnJlZSBleGlzdGluZyBjYWNoZSBiZWZvcmUgcmVwbGFjaW5nICovCiAgICBpZiAodGlfaW5mby0+ZGF0YV9jb250ZXh0ICYmIHRpX2luZm8tPmZyZWVfY29udGV4dCkKICAgICAgICAodGlfaW5mby0+ZnJlZV9jb250ZXh0KSh0aV9pbmZvLT5kYXRhX2NvbnRleHQsIGlpbmZvKTsKCiAgICAvKiBtYXliZSBnZW5lcmF0ZSBpdCBmcm9tIHRoZSBsb29wIGNvbnRleHQ/ICovCiAgICBpZiAoaWluZm8tPm1ha2VfZGF0YV9jb250ZXh0ICYmICFjYWxsYmFja19kYXRhX2NvbnRleHQpIHsKICAgICAgICBjYWxsYmFja19kYXRhX2NvbnRleHQgPQogICAgICAgICAgICAoaWluZm8tPm1ha2VfZGF0YV9jb250ZXh0KShjYWxsYmFja19sb29wX2NvbnRleHQsIGlpbmZvKTsKCiAgICB9CgogICAgLyogc2F2ZSBkYXRhIGFzIHJlcXVlc3RlZCAqLwogICAgdGlfaW5mby0+ZGF0YV9jb250ZXh0ID0gY2FsbGJhY2tfZGF0YV9jb250ZXh0OwogICAgdGlfaW5mby0+ZnJlZV9jb250ZXh0ID0gaWluZm8tPmZyZWVfZGF0YV9jb250ZXh0OwogICAgdGlfaW5mby0+YmVzdF9tYXRjaF9sZW4gPSBvaWRfdG9fc2F2ZV9sZW47CiAgICB0aV9pbmZvLT5paW5mbyA9IGlpbmZvOwogICAgaWYgKG9pZF90b19zYXZlX2xlbikKICAgICAgICBtZW1jcHkodGlfaW5mby0+YmVzdF9tYXRjaCwgb2lkX3RvX3NhdmUsIG9pZF90b19zYXZlX2xlbiAqIHNpemVvZihvaWQpKTsKCiAgICByZXR1cm4gdGlfaW5mbzsKfSAgICAKCiNkZWZpbmUgVEFCTEVfSVRFUkFUT1JfTk9UQUdBSU4gMjU1Ci8qIGltcGxlbWVudHMgdGhlIHRhYmxlX2l0ZXJhdG9yIGhlbHBlciAqLwppbnQKbmV0c25tcF90YWJsZV9pdGVyYXRvcl9oZWxwZXJfaGFuZGxlcihuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKQp7CiAgICBuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvICp0YmxfaW5mbzsKICAgIG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvICp0YWJsZV9pbmZvID0gTlVMTDsKICAgIG9pZCAgICAgICAgICAgICBjb2xvaWRbTUFYX09JRF9MRU5dOwogICAgc2l6ZV90ICAgICAgICAgIGNvbG9pZF9sZW47CiAgICBpbnQgICAgICAgICAgICAgcmV0ID0gU05NUF9FUlJfTk9FUlJPUjsKICAgIHN0YXRpYyBvaWQgICAgICBteW5hbWVbTUFYX09JRF9MRU5dOwogICAgc2l6ZV90ICAgICAgICAgIG15bmFtZV9sZW47CiAgICBpbnQgICAgICAgICAgICAgb2xkbW9kZSA9IDA7CiAgICBuZXRzbm1wX2l0ZXJhdG9yX2luZm8gKmlpbmZvOwogICAgaW50IG5vdGRvbmU7CiAgICBpbnQgaGludG9rID0gMDsKICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0LCAqcmVxdG1wID0gTlVMTDsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqaW5kZXhfc2VhcmNoID0gTlVMTDsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqZnJlZV90aGlzX2luZGV4X3NlYXJjaCA9IE5VTEw7CiAgICB2b2lkICAgICAgICAgICAqY2FsbGJhY2tfbG9vcF9jb250ZXh0ID0gTlVMTCwgKmxhc3RfbG9vcF9jb250ZXh0OwogICAgdm9pZCAgICAgICAgICAgKmNhbGxiYWNrX2RhdGFfY29udGV4dCA9IE5VTEw7CiAgICB0aV9jYWNoZV9pbmZvICAqdGlfaW5mbyA9IE5VTEw7CiAgICBpbnQgICAgICAgICAgICAgcmVxdWVzdF9jb3VudCA9IDA7CiAgICBuZXRzbm1wX29pZF9zdGFzaF9ub2RlICoqY2luZm8gPSBOVUxMOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICpvbGRfaW5kZXhlcyA9IE5VTEwsICp2YjsKICAgIG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gKnRhYmxlX3JlZ19pbmZvID0gTlVMTDsKICAgIGludCBpOwogICAgbmV0c25tcF9kYXRhX2xpc3QgICAgKmxkYXRhID0gTlVMTDsKICAgIAogICAgaWluZm8gPSAobmV0c25tcF9pdGVyYXRvcl9pbmZvICopIGhhbmRsZXItPm15dm9pZDsKICAgIGlmICghaWluZm8gfHwgIXJlZ2luZm8gfHwgIXJlcWluZm8pCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwoKICAgIHRibF9pbmZvID0gaWluZm8tPnRhYmxlX3JlZ2luZm87CgogICAgLyoKICAgICAqIGNvcHkgaW4gdGhlIHRhYmxlIHJlZ2lzdHJhdGlvbiBvaWQgZm9yIGxhdGVyIHVzZSAKICAgICAqLwogICAgY29sb2lkX2xlbiA9IHJlZ2luZm8tPnJvb3RvaWRfbGVuICsgMjsKICAgIG1lbWNweShjb2xvaWQsIHJlZ2luZm8tPnJvb3RvaWQsIHJlZ2luZm8tPnJvb3RvaWRfbGVuICogc2l6ZW9mKG9pZCkpOwogICAgY29sb2lkW3JlZ2luZm8tPnJvb3RvaWRfbGVuXSA9IDE7ICAgLyogdGFibGUuZW50cnkgbm9kZSAqLwoKICAgIC8qCiAgICAgKiBpbGxlZ2FsbHkgZ290IGhlcmUgaWYgdGhlc2UgZnVuY3Rpb25zIGFyZW4ndCBkZWZpbmVkIAogICAgICovCiAgICBpZiAoaWluZm8tPmdldF9maXJzdF9kYXRhX3BvaW50ID09IE5VTEwgfHwKICAgICAgICBpaW5mby0+Z2V0X25leHRfZGF0YV9wb2ludCA9PSBOVUxMKSB7CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwKICAgICAgICAgICAgICAgICAidGFibGVfaXRlcmF0b3IgaGVscGVyIGNhbGxlZCB3aXRob3V0IGRhdGEgYWNjZXNzb3IgZnVuY3Rpb25zXG4iKTsKICAgICAgICByZXR1cm4gU05NUF9FUlJfR0VORVJSOwogICAgfQoKICAgIC8qIHByZWxpbWluYXJ5IGFuYWx5c2lzICovCiAgICBzd2l0Y2ggKHJlcWluZm8tPm1vZGUpIHsKICAgIGNhc2UgTU9ERV9HRVRfU1RBU0g6CiAgICAgICAgY2luZm8gPSBuZXRzbm1wX2V4dHJhY3Rfc3Rhc2hfY2FjaGUocmVxaW5mbyk7CiAgICAgICAgdGFibGVfcmVnX2luZm8gPSBuZXRzbm1wX2ZpbmRfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8ocmVnaW5mbyk7CgogICAgICAgIC8qIFhYWDogbW92ZSB0aGlzIG1hbGxvYyB0byBzdGFzaF9jYWNoZSBoYW5kbGVyPyAqLwogICAgICAgIHJlcXRtcCA9IFNOTVBfTUFMTE9DX1RZUEVERUYobmV0c25tcF9yZXF1ZXN0X2luZm8pOwogICAgICAgIHJlcXRtcC0+c3VidHJlZSA9IHJlcXVlc3RzLT5zdWJ0cmVlOwogICAgICAgIHRhYmxlX2luZm8gPSBuZXRzbm1wX2V4dHJhY3RfdGFibGVfaW5mbyhyZXF1ZXN0cyk7CiAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2FkZF9saXN0X2RhdGEocmVxdG1wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX2RhdGFfbGlzdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChUQUJMRV9IQU5ETEVSX05BTUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkICopIHRhYmxlX2luZm8sIE5VTEwpKTsKCiAgICAgICAgLyogcmVtZW1iZXIgdGhlIGluZGV4ZXMgdGhhdCB3ZXJlIG9yaWdpbmFsbHkgcGFyc2VkLiAqLwogICAgICAgIG9sZF9pbmRleGVzID0gdGFibGVfaW5mby0+aW5kZXhlczsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfR0VUTkVYVDoKICAgICAgICBmb3IocmVxdWVzdCA9IHJlcXVlc3RzIDsgcmVxdWVzdDsgcmVxdWVzdCA9IHJlcXVlc3QtPm5leHQpIHsKICAgICAgICAgICAgaWYgKHJlcXVlc3QtPnByb2Nlc3NlZCkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB0YWJsZV9pbmZvID0gbmV0c25tcF9leHRyYWN0X3RhYmxlX2luZm8ocmVxdWVzdCk7CiAgICAgICAgICAgIGlmICh0YWJsZV9pbmZvLT5jb2xudW0gPCB0YmxfaW5mby0+bWluX2NvbHVtbiAtIDEpIHsKICAgICAgICAgICAgICAgIC8qIFhYWDogb3B0aW1pemUgYmV0dGVyIHRoYW4gdGhpcyAqLwogICAgICAgICAgICAgICAgLyogZm9yIG5vdywganVzdCBpbmNyZWFzZSB0byBjb2xudW0tMSAqLwogICAgICAgICAgICAgICAgLyogd2UgbmVlZCB0byBqdW1wIHRvIHRoZSBsb3dlc3QgcmVzdWx0IG9mIHRoZSBtaW5fY29sdW1uCiAgICAgICAgICAgICAgICAgICBhbmQgdGFrZSBpdCwgY29tcGFyaW5nIHRvIG5vdGhpbmcgZnJvbSB0aGUgcmVxdWVzdCAqLwogICAgICAgICAgICAgICAgdGFibGVfaW5mby0+Y29sbnVtID0gdGJsX2luZm8tPm1pbl9jb2x1bW4gLSAxOwogICAgICAgICAgICB9IGVsc2UgaWYgKHRhYmxlX2luZm8tPmNvbG51bSA+IHRibF9pbmZvLT5tYXhfY29sdW1uKSB7CiAgICAgICAgICAgICAgICByZXF1ZXN0LT5wcm9jZXNzZWQgPSBUQUJMRV9JVEVSQVRPUl9OT1RBR0FJTjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgdGlfaW5mbyA9CiAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfZ2V0X2xpc3RfZGF0YShyZXF1ZXN0LCBUSV9SRVFVRVNUX0NBQ0hFKTsKICAgICAgICAgICAgaWYgKCF0aV9pbmZvKSB7CiAgICAgICAgICAgICAgICB0aV9pbmZvID0gU05NUF9NQUxMT0NfVFlQRURFRih0aV9jYWNoZV9pbmZvKTsKICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9hZGRfbGlzdF9kYXRhKHJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV9kYXRhX2xpc3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChUSV9SRVFVRVNUX0NBQ0hFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpX2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9mcmVlX3RpX2NhY2hlKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIFhYWDogaWYgbm8gdmFsaWQgcmVxdWVzdHMsIGRvbid0IGV2ZW4gbG9vcCBiZWxvdyAqLwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KCiAgICAvKgogICAgICogY29sbGVjdCBhbGwgaW5mb3JtYXRpb24gZm9yIGVhY2ggbmVlZGVkIHJvdwogICAgICovCiAgICBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVCB8fAogICAgICAgIHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRORVhUIHx8CiAgICAgICAgcmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVF9TVEFTSCB8fAogICAgICAgIHJlcWluZm8tPm1vZGUgPT0gTU9ERV9TRVRfUkVTRVJWRTEpIHsKICAgICAgICAvKgogICAgICAgICAqIENvdW50IHRoZSBudW1iZXIgb2YgcmVxdWVzdCBpbiB0aGUgbGlzdCwKICAgICAgICAgKiAgIHNvIHRoYXQgd2UnbGwga25vdyB3aGVuIHdlJ3JlIGZpbmlzaGVkCiAgICAgICAgICovCiAgICAgICAgZm9yKHJlcXVlc3QgPSByZXF1ZXN0cyA7IHJlcXVlc3Q7IHJlcXVlc3QgPSByZXF1ZXN0LT5uZXh0KQogICAgICAgICAgaWYgKCFyZXF1ZXN0LT5wcm9jZXNzZWQpCiAgICAgICAgICAgIHJlcXVlc3RfY291bnQrKzsKICAgICAgICBub3Rkb25lID0gMTsKICAgICAgICBoaW50b2sgPSAxOwogICAgICAgIHdoaWxlKG5vdGRvbmUpIHsKICAgICAgICAgICAgbm90ZG9uZSA9IDA7CgogICAgICAgICAgICAvKiBmaW5kIGZpcnN0IGRhdGEgcG9pbnQgKi8KICAgICAgICAgICAgaWYgKCFpbmRleF9zZWFyY2gpIHsKICAgICAgICAgICAgICAgIGlmIChmcmVlX3RoaXNfaW5kZXhfc2VhcmNoKSB7CiAgICAgICAgICAgICAgICAgICAgLyogcHJldmlvdXNseSBkb25lICovCiAgICAgICAgICAgICAgICAgICAgaW5kZXhfc2VhcmNoID0gZnJlZV90aGlzX2luZGV4X3NlYXJjaDsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZm9yKHJlcXVlc3Q9cmVxdWVzdHMgOyByZXF1ZXN0OyByZXF1ZXN0PXJlcXVlc3QtPm5leHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGFibGVfaW5mbyA9IG5ldHNubXBfZXh0cmFjdF90YWJsZV9pbmZvKHJlcXVlc3QpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodGFibGVfaW5mbykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoIXRhYmxlX2luZm8pIHsKICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJubyB2YWxpZCByZXF1ZXN0cyBmb3IgaXRlcmF0b3IgdGFibGUgJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPmhhbmRsZXJOYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9mcmVlX3JlcXVlc3RfZGF0YV9zZXRzKHJlcXRtcCk7CiAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRlJFRShyZXF0bXApOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaW5kZXhfc2VhcmNoID0gc25tcF9jbG9uZV92YXJiaW5kKHRhYmxlX2luZm8tPmluZGV4ZXMpOwogICAgICAgICAgICAgICAgICAgIGZyZWVfdGhpc19pbmRleF9zZWFyY2ggPSBpbmRleF9zZWFyY2g7CgogICAgICAgICAgICAgICAgICAgIC8qIHNldHVwLCBtYWxsb2Mgc2VhcmNoIGRhdGE6ICovCiAgICAgICAgICAgICAgICAgICAgaWYgKCFpbmRleF9zZWFyY2gpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgICAgICogaG1tbS4uLi4gIGludmFsaWQgdGFibGU/IAogICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpbnZhbGlkIGluZGV4IGxpc3Qgb3IgZmFpbGVkIG1hbGxvYyBmb3IgdGFibGUgJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPmhhbmRsZXJOYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9mcmVlX3JlcXVlc3RfZGF0YV9zZXRzKHJlcXRtcCk7CiAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRlJFRShyZXF0bXApOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIGlmIHNvcnRlZCwgcGFzcyBpbiBhIGhpbnQgKi8KICAgICAgICAgICAgaWYgKGhpbnRvayAmJiAoaWluZm8tPmZsYWdzICYgTkVUU05NUF9JVEVSQVRPUl9GTEFHX1NPUlRFRCkpIHsKICAgICAgICAgICAgICAgIGNhbGxiYWNrX2xvb3BfY29udGV4dCA9IHRhYmxlX2luZm87CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaW5kZXhfc2VhcmNoID0KICAgICAgICAgICAgICAgIChpaW5mby0+Z2V0X2ZpcnN0X2RhdGFfcG9pbnQpICgmY2FsbGJhY2tfbG9vcF9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjYWxsYmFja19kYXRhX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXhfc2VhcmNoLCBpaW5mbyk7CgogICAgICAgICAgICAvKiBsb29wIG92ZXIgZWFjaCBkYXRhIHBvaW50ICovCiAgICAgICAgICAgIHdoaWxlKGluZGV4X3NlYXJjaCkgewoKICAgICAgICAgICAgICAgIC8qIHJlbWVtYmVyIHRvIGZyZWUgdGhpcyBsYXRlciAqLwogICAgICAgICAgICAgICAgZnJlZV90aGlzX2luZGV4X3NlYXJjaCA9IGluZGV4X3NlYXJjaDsKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvKiBjb21wYXJlIGFnYWluc3QgZWFjaCByZXF1ZXN0Ki8KICAgICAgICAgICAgICAgIGZvcihyZXF1ZXN0ID0gcmVxdWVzdHMgOyByZXF1ZXN0OyByZXF1ZXN0ID0gcmVxdWVzdC0+bmV4dCkgewogICAgICAgICAgICAgICAgICAgIGlmIChyZXF1ZXN0LT5wcm9jZXNzZWQpCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICAgICAgICAgICAgICAvKiBYWFg6IHN0b3JlIGluIGFuIGFycmF5IGZvciBmYXN0ZXIgcmV0cml2YWwgKi8KICAgICAgICAgICAgICAgICAgICB0YWJsZV9pbmZvID0gbmV0c25tcF9leHRyYWN0X3RhYmxlX2luZm8ocmVxdWVzdCk7CiAgICAgICAgICAgICAgICAgICAgY29sb2lkW3JlZ2luZm8tPnJvb3RvaWRfbGVuICsgMV0gPSB0YWJsZV9pbmZvLT5jb2xudW07CgogICAgICAgICAgICAgICAgICAgIHRpX2luZm8gPQogICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfZ2V0X2xpc3RfZGF0YShyZXF1ZXN0LCBUSV9SRVFVRVNUX0NBQ0hFKTsKCiAgICAgICAgICAgICAgICAgICAgc3dpdGNoKHJlcWluZm8tPm1vZGUpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlIE1PREVfR0VUOgogICAgICAgICAgICAgICAgICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTE6CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIGxvb2tpbmcgZm9yIGV4YWN0IG1hdGNoZXMgKi8KICAgICAgICAgICAgICAgICAgICAgICAgYnVpbGRfb2lkX25vYWxsb2MobXluYW1lLCBNQVhfT0lEX0xFTiwgJm15bmFtZV9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9pZCwgY29sb2lkX2xlbiwgaW5kZXhfc2VhcmNoKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNubXBfb2lkX2NvbXBhcmUobXluYW1lLCBteW5hbWVfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yZXF1ZXN0dmItPm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJlcXVlc3R2Yi0+bmFtZV9sZW5ndGgpID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGtlZXAgdGhpcyAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9pdGVyYXRvcl9yZW1lbWJlcihyZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBteW5hbWUsIG15bmFtZV9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrX2RhdGFfY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tfbG9vcF9jb250ZXh0LCBpaW5mbyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0X2NvdW50LS07ICAgLyogT25lIGxlc3MgdG8gbG9vayBmb3IgKi8KICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpaW5mby0+ZnJlZV9kYXRhX2NvbnRleHQgJiYgY2FsbGJhY2tfZGF0YV9jb250ZXh0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGlpbmZvLT5mcmVlX2RhdGFfY29udGV4dCkoY2FsbGJhY2tfZGF0YV9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlpbmZvKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgY2FzZSBNT0RFX0dFVF9TVEFTSDoKICAgICAgICAgICAgICAgICAgICAgICAgLyogY29sbGVjdCBkYXRhIGZvciBlYWNoIGNvbHVtbiBmb3IgZXZlcnkgcm93ICovCiAgICAgICAgICAgICAgICAgICAgICAgIGJ1aWxkX29pZF9ub2FsbG9jKG15bmFtZSwgTUFYX09JRF9MRU4sICZteW5hbWVfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvaWQsIGNvbG9pZF9sZW4sIGluZGV4X3NlYXJjaCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJlcWluZm8tPm1vZGUgPSBNT0RFX0dFVDsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlcXRtcCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxkYXRhID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2dldF9saXN0X25vZGUocmVxdG1wLT5wYXJlbnRfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVEFCTEVfSVRFUkFUT1JfTkFNRSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghbGRhdGEpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9hZGRfbGlzdF9kYXRhKHJlcXRtcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX2RhdGFfbGlzdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFRBQkxFX0lURVJBVE9SX05BTUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tfZGF0YV9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG1heSBoYXZlIGNoYW5nZWQgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxkYXRhLT5kYXRhID0gY2FsbGJhY2tfZGF0YV9jb250ZXh0OwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICB0YWJsZV9pbmZvLT5pbmRleGVzID0gaW5kZXhfc2VhcmNoOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IoaSA9IHRhYmxlX3JlZ19pbmZvLT5taW5fY29sdW1uOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaSA8PSAoaW50KXRhYmxlX3JlZ19pbmZvLT5tYXhfY29sdW1uOyBpKyspIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG15bmFtZVtyZWdpbmZvLT5yb290b2lkX2xlbiArIDFdID0gaTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlX2luZm8tPmNvbG51bSA9IGk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YiA9IHJlcXRtcC0+cmVxdWVzdHZiID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX01BTExPQ19UWVBFREVGKG5ldHNubXBfdmFyaWFibGVfbGlzdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2Yi0+dHlwZSA9IEFTTl9OVUxMOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9zZXRfdmFyX29iamlkKHZiLCBteW5hbWUsIG15bmFtZV9sZW4pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9jYWxsX25leHRfaGFuZGxlcihoYW5kbGVyLCByZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXFpbmZvLCByZXF0bXApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdG1wLT5yZXF1ZXN0dmIgPSBOVUxMOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdG1wLT5wcm9jZXNzZWQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZiLT50eXBlICE9IEFTTl9OVUxMKSB7IC8qIFhYWCwgbm90IGFsbCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfb2lkX3N0YXNoX2FkZF9kYXRhKGNpbmZvLCBteW5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXluYW1lX2xlbiwgdmIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbm1wX2ZyZWVfdmFyKHZiKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICByZXFpbmZvLT5tb2RlID0gTU9ERV9HRVRfU1RBU0g7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlIE1PREVfR0VUTkVYVDoKICAgICAgICAgICAgICAgICAgICAgICAgLyogbG9va2luZyBmb3IgIm5leHQiIG1hdGNoZXMgKi8KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ldHNubXBfY2hlY2tfZ2V0bmV4dF9yZXBseQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHJlcXVlc3QsIGNvbG9pZCwgY29sb2lkX2xlbiwgaW5kZXhfc2VhcmNoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0aV9pbmZvLT5yZXN1bHRzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9pdGVyYXRvcl9yZW1lbWJlcihyZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aV9pbmZvLT5yZXN1bHRzLT5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aV9pbmZvLT5yZXN1bHRzLT5uYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tfZGF0YV9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFja19sb29wX2NvbnRleHQsIGlpbmZvKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiAgSWYgd2UndmUgYmVlbiB0b2xkIHRoYXQgdGhlIHJvd3MgYXJlIHNvcnRlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqICAgdGhlbiB0aGUgZmlyc3QgdmFsaWQgb25lIHdlIGZpbmQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqICAgbXVzdCBiZSB0aGUgcmlnaHQgb25lLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaWluZm8tPmZsYWdzICYgTkVUU05NUF9JVEVSQVRPUl9GTEFHX1NPUlRFRCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0X2NvdW50LS07CiAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlpbmZvLT5mcmVlX2RhdGFfY29udGV4dCAmJiBjYWxsYmFja19kYXRhX2NvbnRleHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaWluZm8tPmZyZWVfZGF0YV9jb250ZXh0KShjYWxsYmFja19kYXRhX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWluZm8pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUyOgogICAgICAgICAgICAgICAgICAgIGNhc2UgTU9ERV9TRVRfRlJFRToKICAgICAgICAgICAgICAgICAgICBjYXNlIE1PREVfU0VUX1VORE86CiAgICAgICAgICAgICAgICAgICAgY2FzZSBNT0RFX1NFVF9DT01NSVQ6CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5lZWRlZCBwcm9jZXNzaW5nIGFscmVhZHkgZG9uZSBpbiBSRVNFUlZFMSAqLwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhYmxlX2l0ZXJhdG9yIGNhbGxlZCB3aXRoIHVuc3VwcG9ydGVkIG1vZGVcbiIpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsgIC8qIFhYWCByZXR1cm4gKi8KICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvKiBJcyB0aGVyZSBhbnkgcG9pbnQgaW4gY2Fycnlpbmcgb24/ICovCiAgICAgICAgICAgICAgICBpZiAoIXJlcXVlc3RfY291bnQpCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAvKiBnZXQgdGhlIG5leHQgc2VhcmNoIHBvc3NpYmlsaXR5ICovCiAgICAgICAgICAgICAgICBsYXN0X2xvb3BfY29udGV4dCA9IGNhbGxiYWNrX2xvb3BfY29udGV4dDsKICAgICAgICAgICAgICAgIGluZGV4X3NlYXJjaCA9CiAgICAgICAgICAgICAgICAgICAgKGlpbmZvLT5nZXRfbmV4dF9kYXRhX3BvaW50KSAoJmNhbGxiYWNrX2xvb3BfY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmY2FsbGJhY2tfZGF0YV9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4X3NlYXJjaCwgaWluZm8pOwogICAgICAgICAgICAgICAgaWYgKGlpbmZvLT5mcmVlX2xvb3BfY29udGV4dCAmJiBsYXN0X2xvb3BfY29udGV4dCAmJgogICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrX2RhdGFfY29udGV4dCAhPSBsYXN0X2xvb3BfY29udGV4dCkgewogICAgICAgICAgICAgICAgICAgIChpaW5mby0+ZnJlZV9sb29wX2NvbnRleHQpIChsYXN0X2xvb3BfY29udGV4dCwgaWluZm8pOwogICAgICAgICAgICAgICAgICAgIGxhc3RfbG9vcF9jb250ZXh0ID0gTlVMTDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogZnJlZSBsb29wIGNvbnRleHQgYmVmb3JlIGdvaW5nIG9uICovCiAgICAgICAgICAgIGlmIChjYWxsYmFja19sb29wX2NvbnRleHQgJiYgaWluZm8tPmZyZWVfbG9vcF9jb250ZXh0X2F0X2VuZCkgewogICAgICAgICAgICAgICAgKGlpbmZvLT5mcmVlX2xvb3BfY29udGV4dF9hdF9lbmQpIChjYWxsYmFja19sb29wX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlpbmZvKTsKICAgICAgICAgICAgICAgIGNhbGxiYWNrX2xvb3BfY29udGV4dCA9IE5VTEw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIGRlY2lkZSB3aGljaCAoR0VUTkVYVCkgcmVxdWVzdHMgYXJlIG5vdCB5ZXQgZmlsbGVkICovCiAgICAgICAgICAgIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfR0VUTkVYVCkgewogICAgICAgICAgICAgICAgZm9yKHJlcXVlc3QgPSByZXF1ZXN0cyA7IHJlcXVlc3Q7IHJlcXVlc3QgPSByZXF1ZXN0LT5uZXh0KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJlcXVlc3QtPnByb2Nlc3NlZCkKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgdGlfaW5mbyA9CiAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9nZXRfbGlzdF9kYXRhKHJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRJX1JFUVVFU1RfQ0FDSEUpOwogICAgICAgICAgICAgICAgICAgIGlmICghdGlfaW5mby0+cmVzdWx0cykgewogICAgICAgICAgICAgICAgICAgICAgaW50IG5jOwogICAgICAgICAgICAgICAgICAgICAgICB0YWJsZV9pbmZvID0gbmV0c25tcF9leHRyYWN0X3RhYmxlX2luZm8ocmVxdWVzdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIG5jID0gbmV0c25tcF90YWJsZV9uZXh0X2NvbHVtbih0YWJsZV9pbmZvKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKDAgPT0gbmMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9pZFtyZWdpbmZvLT5yb290b2lkX2xlbisxXSA9IHRhYmxlX2luZm8tPmNvbG51bSsxOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9zZXRfdmFyX29iamlkKHJlcXVlc3QtPnJlcXVlc3R2YiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvaWQsIHJlZ2luZm8tPnJvb3RvaWRfbGVuKzIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cHJvY2Vzc2VkID0gVEFCTEVfSVRFUkFUT1JfTk9UQUdBSU47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICB0YWJsZV9pbmZvLT5jb2xudW0gPSBuYzsKICAgICAgICAgICAgICAgICAgICAgICAgICBoaW50b2sgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAgIG5vdGRvbmUgPSAxOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfR0VUIHx8CiAgICAgICAgcmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVE5FWFQgfHwKICAgICAgICByZXFpbmZvLT5tb2RlID09IE1PREVfU0VUX1JFU0VSVkUxKSB7CiAgICAgICAgLyogcGVyIHJlcXVlc3QgbGFzdCBtaW51dGUgcHJvY2Vzc2luZyAqLwogICAgICAgIGZvcihyZXF1ZXN0ID0gcmVxdWVzdHMgOyByZXF1ZXN0OyByZXF1ZXN0ID0gcmVxdWVzdC0+bmV4dCkgewogICAgICAgICAgICBpZiAocmVxdWVzdC0+cHJvY2Vzc2VkKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIHRpX2luZm8gPQogICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2dldF9saXN0X2RhdGEocmVxdWVzdCwgVElfUkVRVUVTVF9DQUNIRSk7CiAgICAgICAgICAgIHRhYmxlX2luZm8gPQogICAgICAgICAgICAgICAgbmV0c25tcF9leHRyYWN0X3RhYmxlX2luZm8ocmVxdWVzdCk7CgogICAgICAgICAgICBpZiAoIXRpX2luZm8pCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAKICAgICAgICAgICAgc3dpdGNoKHJlcWluZm8tPm1vZGUpIHsKCiAgICAgICAgICAgIGNhc2UgTU9ERV9HRVRORVhUOgogICAgICAgICAgICAgICAgaWYgKHRpX2luZm8tPmJlc3RfbWF0Y2hfbGVuKQogICAgICAgICAgICAgICAgICAgIHNubXBfc2V0X3Zhcl9vYmppZChyZXF1ZXN0LT5yZXF1ZXN0dmIsIHRpX2luZm8tPmJlc3RfbWF0Y2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpX2luZm8tPmJlc3RfbWF0Y2hfbGVuKTsKICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIGNvbG9pZFtyZWdpbmZvLT5yb290b2lkX2xlbisxXSA9IAogICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3RhYmxlX25leHRfY29sdW1uKHRhYmxlX2luZm8pOwogICAgICAgICAgICAgICAgICAgIGlmICgwID09IGNvbG9pZFtyZWdpbmZvLT5yb290b2lkX2xlbisxXSkgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBvdXQgb2YgcmFuZ2UuICovCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9pZFtyZWdpbmZvLT5yb290b2lkX2xlbisxXSA9IHRibF9pbmZvLT5tYXhfY29sdW1uICsgMTsKICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cHJvY2Vzc2VkID0gVEFCTEVfSVRFUkFUT1JfTk9UQUdBSU47CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHNubXBfc2V0X3Zhcl9vYmppZChyZXF1ZXN0LT5yZXF1ZXN0dmIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9pZCwgcmVnaW5mby0+cm9vdG9pZF9sZW4rMik7CiAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cHJvY2Vzc2VkID0gMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHNubXBfZnJlZV92YXJiaW5kKHRhYmxlX2luZm8tPmluZGV4ZXMpOwogICAgICAgICAgICAgICAgdGFibGVfaW5mby0+aW5kZXhlcyA9IHNubXBfY2xvbmVfdmFyYmluZCh0aV9pbmZvLT5yZXN1bHRzKTsKICAgICAgICAgICAgICAgIC8qIEZBTEwgVEhST1VHSCAqLwoKICAgICAgICAgICAgY2FzZSBNT0RFX0dFVDoKICAgICAgICAgICAgY2FzZSBNT0RFX1NFVF9SRVNFUlZFMToKICAgICAgICAgICAgICAgIGlmICh0aV9pbmZvLT5kYXRhX2NvbnRleHQpCiAgICAgICAgICAgICAgICAgICAgLyogd2UgZG9uJ3QgYWRkIGEgZnJlZSBwb2ludGVyLCBzaW5jZSBpdCdzIGluIHRoZQogICAgICAgICAgICAgICAgICAgICAgIFRJX1JFUVVFU1RfQ0FDSEUgaW5zdGVhZCAqLwogICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9hZGRfbGlzdF9kYXRhKHJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfZGF0YV9saXN0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFRBQkxFX0lURVJBVE9SX05BTUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpX2luZm8tPmRhdGFfY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCkpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIAogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgIC8qIHdlIGNoYW5nZSBhbGwgR0VUTkVYVCBvcGVyYXRpb25zIGludG8gR0VUIG9wZXJhdGlvbnMuCiAgICAgICAgICAgd2h5PyBiZWNhdXNlIHdlJ3JlIGp1c3Qgc28gbmljZSB0byB0aGUgbG93ZXIgbGV2ZWxzLgogICAgICAgICAgIG1heWJlIHNvbWVkYXkgdGhleSdsbCBwYXkgdXMgZm9yIGl0LiAgZG91YnRmdWwgdGhvdWdoLiAqLwogICAgICAgIG9sZG1vZGUgPSByZXFpbmZvLT5tb2RlOwogICAgICAgIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfR0VUTkVYVCkgewogICAgICAgICAgICByZXFpbmZvLT5tb2RlID0gTU9ERV9HRVQ7CiAgICAgICAgfQogICAgfSBlbHNlIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfR0VUX1NUQVNIKSB7CiAgICAgICAgbmV0c25tcF9mcmVlX3JlcXVlc3RfZGF0YV9zZXRzKHJlcXRtcCk7CiAgICAgICAgU05NUF9GUkVFKHJlcXRtcCk7CiAgICAgICAgdGFibGVfaW5mby0+aW5kZXhlcyA9IG9sZF9pbmRleGVzOwogICAgfQoKCiAgICAvKiBGaW5hbGx5LCB3ZSBnZXQgdG8gY2FsbCB0aGUgbmV4dCBoYW5kbGVyIGJlbG93IHVzLiAgQm95LCB3YXNuJ3QKICAgICAgIGFsbCB0aGF0IHNpbXBsZT8gIFRoZXkgYmV0dGVyIGJlIGdsYWQgdGhleSBkb24ndCBoYXZlIHRvIGRvIGl0ISAqLwogICAgaWYgKHJlcWluZm8tPm1vZGUgIT0gTU9ERV9HRVRfU1RBU0gpIHsKICAgICAgICBERUJVR01TR1RMKCgidGFibGVfaXRlcmF0b3IiLCAiY2FsbCBzdWJoYW5kbGVyIGZvciBtb2RlOiAlc1xuIiwKICAgICAgICAgICAgICAgICAgICBzZV9maW5kX2xhYmVsX2luX3NsaXN0KCJhZ2VudF9tb2RlIiwgb2xkbW9kZSkpKTsKICAgICAgICByZXQgPQogICAgICAgICAgICBuZXRzbm1wX2NhbGxfbmV4dF9oYW5kbGVyKGhhbmRsZXIsIHJlZ2luZm8sIHJlcWluZm8sIHJlcXVlc3RzKTsKICAgIH0KCiAgICAvKiByZXZlcnNlIHRoZSBwcmV2aW91c2x5IHNhdmVkIG1vZGUgaWYgd2Ugd2VyZSBhIGdldG5leHQgKi8KICAgIGlmIChvbGRtb2RlID09IE1PREVfR0VUTkVYVCkgewogICAgICAgIHJlcWluZm8tPm1vZGUgPSBvbGRtb2RlOwogICAgfQoKICAgIC8qIGNsZWFudXAgKi8KICAgIGlmIChmcmVlX3RoaXNfaW5kZXhfc2VhcmNoKQogICAgICAgIHNubXBfZnJlZV92YXJiaW5kKGZyZWVfdGhpc19pbmRleF9zZWFyY2gpOwoKICAgIHJldHVybiByZXQ7Cn0KCi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICoKICogSXRlcmF0b3IgQVBJOiBSb3cgb3BlcmF0aW9ucwogKgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovCgp2b2lkICoKbmV0c25tcF9pdGVyYXRvcl9yb3dfZmlyc3QoIG5ldHNubXBfaXRlcmF0b3JfaW5mbyAqaWluZm8gKSB7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZwMSwgKnZwMjsKICAgIHZvaWQgKmN0eDEsICpjdHgyOwoKICAgIGlmICghaWluZm8pCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgdnAxID0gc25tcF9jbG9uZV92YXJiaW5kKGlpbmZvLT5pbmRleGVzKTsKICAgIHZwMiA9IGlpbmZvLT5nZXRfZmlyc3RfZGF0YV9wb2ludCggJmN0eDEsICZjdHgyLCB2cDEsIGlpbmZvICk7CgogICAgaWYgKCF2cDIpCiAgICAgICAgY3R4MiA9IE5VTEw7CgogICAgLyogZnJlZSBsb29wIGNvbnRleHQgPz8gKi8KICAgIHNubXBfZnJlZV92YXJiaW5kKCB2cDEgKTsKICAgIHJldHVybiBjdHgyOyAgLyogb3IgKmN0eDIgPz8gKi8KfQoKdm9pZCAqCm5ldHNubXBfaXRlcmF0b3Jfcm93X2dldCggbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbywgdm9pZCAqcm93ICkKewogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2cDEsICp2cDI7CiAgICB2b2lkICpjdHgxLCAqY3R4MjsKCiAgICBpZiAoIWlpbmZvIHx8ICFyb3cpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgICAgIC8qCiAgICAgICAgICogVGhpcyByb3V0aW5lIHJlbGllcyBvbiBiZWluZyBhYmxlIHRvCiAgICAgICAgICogICBkZXRlcm1pbmUgdGhlIGluZGV4ZXMgZm9yIGEgZ2l2ZW4gcm93LiAgCiAgICAgICAgICovCiAgICBpZiAoIWlpbmZvLT5nZXRfcm93X2luZGV4ZXMpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgdnAxICA9IHNubXBfY2xvbmVfdmFyYmluZChpaW5mby0+aW5kZXhlcyk7CiAgICBjdHgxID0gcm93OyAgIC8qIFByb2JhYmx5IG9ubHkgbmVlZCBvbmUgb2YgdGhlc2UgLi4uICovCiAgICBjdHgyID0gcm93OwogICAgdnAyICA9IGlpbmZvLT5nZXRfcm93X2luZGV4ZXMoICZjdHgxLCAmY3R4MiwgdnAxLCBpaW5mbyApOwoKICAgIGN0eDIgPSBOVUxMOwogICAgaWYgKHZwMikgewogICAgICAgIGN0eDIgPSBuZXRzbm1wX2l0ZXJhdG9yX3Jvd19nZXRfYnlpZHgoIGlpbmZvLCB2cDIgKTsKICAgIH0KICAgIHNubXBfZnJlZV92YXJiaW5kKCB2cDEgKTsKICAgIHJldHVybiBjdHgyOwp9Cgp2b2lkICoKbmV0c25tcF9pdGVyYXRvcl9yb3dfbmV4dCggbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbywgdm9pZCAqcm93ICkKewogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2cDEsICp2cDI7CiAgICB2b2lkICpjdHgxLCAqY3R4MjsKCiAgICBpZiAoIWlpbmZvIHx8ICFyb3cpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgICAgIC8qCiAgICAgICAgICogVGhpcyByb3V0aW5lIHJlbGllcyBvbiBiZWluZyBhYmxlIHRvCiAgICAgICAgICogICBkZXRlcm1pbmUgdGhlIGluZGV4ZXMgZm9yIGEgZ2l2ZW4gcm93LiAgCiAgICAgICAgICovCiAgICBpZiAoIWlpbmZvLT5nZXRfcm93X2luZGV4ZXMpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgdnAxICA9IHNubXBfY2xvbmVfdmFyYmluZChpaW5mby0+aW5kZXhlcyk7CiAgICBjdHgxID0gcm93OyAgIC8qIFByb2JhYmx5IG9ubHkgbmVlZCBvbmUgb2YgdGhlc2UgLi4uICovCiAgICBjdHgyID0gcm93OwogICAgdnAyICA9IGlpbmZvLT5nZXRfcm93X2luZGV4ZXMoICZjdHgxLCAmY3R4MiwgdnAxLCBpaW5mbyApOwoKICAgIGN0eDIgPSBOVUxMOwogICAgaWYgKHZwMikgewogICAgICAgIGN0eDIgPSBuZXRzbm1wX2l0ZXJhdG9yX3Jvd19uZXh0X2J5aWR4KCBpaW5mbywgdnAyICk7CiAgICB9CiAgICBzbm1wX2ZyZWVfdmFyYmluZCggdnAxICk7CiAgICByZXR1cm4gY3R4MjsKfQoKdm9pZCAqCm5ldHNubXBfaXRlcmF0b3Jfcm93X2dldF9ieWlkeCggIG5ldHNubXBfaXRlcmF0b3JfaW5mbyAqaWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqaW5kZXhlcyApCnsKICAgIG9pZCAgICBkdW1teVtdID0gezAsMH07ICAgLyogS2VlcCAnYnVpbGRfb2lkJyBoYXBweSAqLwogICAgb2lkICAgIGluc3RhbmNlW01BWF9PSURfTEVOXTsKICAgIHNpemVfdCBsZW4gPSAgICBNQVhfT0lEX0xFTjsKCiAgICBpZiAoIWlpbmZvIHx8ICFpbmRleGVzKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGJ1aWxkX29pZF9ub2FsbG9jKGluc3RhbmNlLCBNQVhfT0lEX0xFTiwgJmxlbiwKICAgICAgICAgICAgICAgICAgICAgIGR1bW15LCAyLCBpbmRleGVzKTsKICAgIHJldHVybiBuZXRzbm1wX2l0ZXJhdG9yX3Jvd19nZXRfYnlvaWQoIGlpbmZvLCBpbnN0YW5jZSsyLCBsZW4tMiApOwp9Cgp2b2lkICoKbmV0c25tcF9pdGVyYXRvcl9yb3dfbmV4dF9ieWlkeCggbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICppbmRleGVzICkKewogICAgb2lkICAgIGR1bW15W10gPSB7MCwwfTsKICAgIG9pZCAgICBpbnN0YW5jZVtNQVhfT0lEX0xFTl07CiAgICBzaXplX3QgbGVuID0gICAgTUFYX09JRF9MRU47CgogICAgaWYgKCFpaW5mbyB8fCAhaW5kZXhlcykKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICBidWlsZF9vaWRfbm9hbGxvYyhpbnN0YW5jZSwgTUFYX09JRF9MRU4sICZsZW4sCiAgICAgICAgICAgICAgICAgICAgICBkdW1teSwgMiwgaW5kZXhlcyk7CiAgICByZXR1cm4gbmV0c25tcF9pdGVyYXRvcl9yb3dfbmV4dF9ieW9pZCggaWluZm8sIGluc3RhbmNlKzIsIGxlbi0yICk7Cn0KCnZvaWQgKgpuZXRzbm1wX2l0ZXJhdG9yX3Jvd19nZXRfYnlvaWQoICBuZXRzbm1wX2l0ZXJhdG9yX2luZm8gKmlpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvaWQgKmluc3RhbmNlLCBzaXplX3QgbGVuICkKewogICAgb2lkICAgIGR1bW15W10gPSB7MCwwfTsKICAgIG9pZCAgICB0aGlzX2luc3RbIE1BWF9PSURfTEVOXTsKICAgIHNpemVfdCB0aGlzX2xlbjsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdnAxLCAqdnAyOwogICAgdm9pZCAqY3R4MSwgKmN0eDI7CiAgICBpbnQgICBuOwoKICAgIGlmICghaWluZm8gfHwgIWlpbmZvLT5nZXRfZmlyc3RfZGF0YV9wb2ludAogICAgICAgICAgICAgICB8fCAhaWluZm8tPmdldF9uZXh0X2RhdGFfcG9pbnQgKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGlmICggIWluc3RhbmNlIHx8ICFsZW4gKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIHZwMSA9IHNubXBfY2xvbmVfdmFyYmluZChpaW5mby0+aW5kZXhlcyk7CiAgICB2cDIgPSBpaW5mby0+Z2V0X2ZpcnN0X2RhdGFfcG9pbnQoICZjdHgxLCAmY3R4MiwgdnAxLCBpaW5mbyApOwogICAgREVCVUdNU0dUTCgoInRhYmxlOml0ZXJhdG9yOmdldCIsICJmaXJzdCBEUDogJXggJXggJXhcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eDEsIGN0eDIsIHZwMikpOwoKICAgIC8qIFhYWCAtIGZyZWUgY29udGV4dCA/ICovCiAgICAKICAgIHdoaWxlICggdnAyICkgewogICAgICAgIHRoaXNfbGVuID0gTUFYX09JRF9MRU47CiAgICAgICAgYnVpbGRfb2lkX25vYWxsb2ModGhpc19pbnN0LCBNQVhfT0lEX0xFTiwgJnRoaXNfbGVuLCBkdW1teSwgMiwgdnAyKTsKICAgICAgICBuID0gc25tcF9vaWRfY29tcGFyZSggaW5zdGFuY2UsIGxlbiwgdGhpc19pbnN0KzIsIHRoaXNfbGVuLTIgKTsKICAgICAgICBpZiAoIG4gPT0gMCApCiAgICAgICAgICAgIGJyZWFrOyAgLyogRm91bmQgbWF0Y2hpbmcgcm93ICovCgogICAgICAgIGlmICgoIG4gPiAwKSAmJgogICAgICAgICAgICAoaWluZm8tPmZsYWdzICYgTkVUU05NUF9JVEVSQVRPUl9GTEFHX1NPUlRFRCkpIHsKICAgICAgICAgICAgdnAyID0gTlVMTDsgIC8qIFJvdyBub3QgcHJlc2VudCAqLwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdnAyID0gaWluZm8tPmdldF9uZXh0X2RhdGFfcG9pbnQoICZjdHgxLCAmY3R4MiwgdnAyLCBpaW5mbyApOwogICAgICAgIERFQlVHTVNHVEwoKCJ0YWJsZTppdGVyYXRvcjpnZXQiLCAibmV4dCBEUDogJXggJXggJXhcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHgxLCBjdHgyLCB2cDIpKTsKICAgICAgICAvKiBYWFggLSBmcmVlIGNvbnRleHQgPyAqLwogICAgfQogICAgICAgICAgIAogICAgLyogWFhYIC0gZmluYWwgZnJlZSBjb250ZXh0ID8gKi8KICAgIHNubXBfZnJlZV92YXJiaW5kKCB2cDEgKTsKCiAgICByZXR1cm4gKCB2cDIgPyBjdHgyIDogTlVMTCApOwp9Cgp2b2lkICoKbmV0c25tcF9pdGVyYXRvcl9yb3dfbmV4dF9ieW9pZCggbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2lkICppbnN0YW5jZSwgc2l6ZV90IGxlbiApCnsKICAgIG9pZCAgICBkdW1teVtdID0gezAsMH07CiAgICBvaWQgICAgdGhpc19pbnN0WyBNQVhfT0lEX0xFTl07CiAgICBzaXplX3QgdGhpc19sZW47CiAgICBvaWQgICAgYmVzdF9pbnN0WyBNQVhfT0lEX0xFTl07CiAgICBzaXplX3QgYmVzdF9sZW4gPSAwOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2cDEsICp2cDI7CiAgICB2b2lkICpjdHgxLCAqY3R4MjsKICAgIGludCAgIG47CgogICAgaWYgKCFpaW5mbyB8fCAhaWluZm8tPmdldF9maXJzdF9kYXRhX3BvaW50CiAgICAgICAgICAgICAgIHx8ICFpaW5mby0+Z2V0X25leHRfZGF0YV9wb2ludCApCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgdnAxID0gc25tcF9jbG9uZV92YXJiaW5kKGlpbmZvLT5pbmRleGVzKTsKICAgIHZwMiA9IGlpbmZvLT5nZXRfZmlyc3RfZGF0YV9wb2ludCggJmN0eDEsICZjdHgyLCB2cDEsIGlpbmZvICk7CiAgICBERUJVR01TR1RMKCgidGFibGU6aXRlcmF0b3I6Z2V0IiwgImZpcnN0IERQOiAleCAleCAleFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4MSwgY3R4MiwgdnAyKSk7CgogICAgaWYgKCAhaW5zdGFuY2UgfHwgIWxlbiApIHsKICAgICAgICBzbm1wX2ZyZWVfdmFyYmluZCggdnAxICk7CiAgICAgICAgcmV0dXJuICggdnAyID8gY3R4MiA6IE5VTEwgKTsgICAvKiBGaXJzdCBlbnRyeSAqLwogICAgfQoKICAgIC8qIFhYWCAtIGZyZWUgY29udGV4dCA/ICovCiAgICAKICAgIHdoaWxlICggdnAyICkgewogICAgICAgIHRoaXNfbGVuID0gTUFYX09JRF9MRU47CiAgICAgICAgYnVpbGRfb2lkX25vYWxsb2ModGhpc19pbnN0LCBNQVhfT0lEX0xFTiwgJnRoaXNfbGVuLCBkdW1teSwgMiwgdnAyKTsKICAgICAgICBuID0gc25tcF9vaWRfY29tcGFyZSggaW5zdGFuY2UsIGxlbiwgdGhpc19pbnN0KzIsIHRoaXNfbGVuLTIgKTsKCiAgICAgICAgLyoKICAgICAgICAgKiBMb29rIGZvciB0aGUgYmVzdC1maXQgY2FuZGlkYXRlIGZvciB0aGUgbmV4dCByb3cKICAgICAgICAgKiAgIChiZWFyaW5nIGluIG1pbmQgdGhlIHJvd3MgbWF5IG5vdCBiZSBvcmRlcmVkICJjb3JyZWN0bHkiKQogICAgICAgICAqLwogICAgICAgIGlmICggbiA+IDAgKSB7CiAgICAgICAgICAgIGlmICggYmVzdF9sZW4gPT0gMCApIHsKICAgICAgICAgICAgICAgIG1lbWNweSggYmVzdF9pbnN0LCB0aGlzX2luc3QsIHNpemVvZiggdGhpc19pbnN0ICkpOwogICAgICAgICAgICAgICAgYmVzdF9sZW4gPSB0aGlzX2xlbjsKICAgICAgICAgICAgICAgIGlmIChpaW5mby0+ZmxhZ3MgJiBORVRTTk1QX0lURVJBVE9SX0ZMQUdfU09SVEVEKQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbiA9IHNubXBfb2lkX2NvbXBhcmUoIGJlc3RfaW5zdCwgYmVzdF9sZW4sIHRoaXNfaW5zdCwgdGhpc19sZW4gKTsKICAgICAgICAgICAgICAgIGlmICggbiA8IDAgKSB7CiAgICAgICAgICAgICAgICAgICAgbWVtY3B5KCBiZXN0X2luc3QsIHRoaXNfaW5zdCwgc2l6ZW9mKCB0aGlzX2luc3QgKSk7CiAgICAgICAgICAgICAgICAgICAgYmVzdF9sZW4gPSB0aGlzX2xlbjsKICAgICAgICAgICAgICAgICAgICBpZiAoaWluZm8tPmZsYWdzICYgTkVUU05NUF9JVEVSQVRPUl9GTEFHX1NPUlRFRCkKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdnAyID0gaWluZm8tPmdldF9uZXh0X2RhdGFfcG9pbnQoICZjdHgxLCAmY3R4MiwgdnAyLCBpaW5mbyApOwogICAgICAgIERFQlVHTVNHVEwoKCJ0YWJsZTppdGVyYXRvcjpnZXQiLCAibmV4dCBEUDogJXggJXggJXhcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHgxLCBjdHgyLCB2cDIpKTsKICAgICAgICAvKiBYWFggLSBmcmVlIGNvbnRleHQgPyAqLwogICAgfQogICAgICAgICAgIAogICAgLyogWFhYIC0gZmluYWwgZnJlZSBjb250ZXh0ID8gKi8KICAgIHNubXBfZnJlZV92YXJiaW5kKCB2cDEgKTsKCiAgICByZXR1cm4gKCB2cDIgPyBjdHgyIDogTlVMTCApOwp9CgppbnQKbmV0c25tcF9pdGVyYXRvcl9yb3dfY291bnQoIG5ldHNubXBfaXRlcmF0b3JfaW5mbyAqaWluZm8gKQp7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZwMSwgKnZwMjsKICAgIHZvaWQgKmN0eDEsICpjdHgyOwogICAgaW50ICAgaT0wOwoKICAgIGlmICghaWluZm8gfHwgIWlpbmZvLT5nZXRfZmlyc3RfZGF0YV9wb2ludAogICAgICAgICAgICAgICB8fCAhaWluZm8tPmdldF9uZXh0X2RhdGFfcG9pbnQgKQogICAgICAgIHJldHVybiAwOwoKICAgIHZwMSA9IHNubXBfY2xvbmVfdmFyYmluZChpaW5mby0+aW5kZXhlcyk7CiAgICB2cDIgPSBpaW5mby0+Z2V0X2ZpcnN0X2RhdGFfcG9pbnQoICZjdHgxLCAmY3R4MiwgdnAxLCBpaW5mbyApOwogICAgaWYgKCF2cDIpIHsKICAgICAgICBzbm1wX2ZyZWVfdmFyYmluZCggdnAxICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICAKICAgIERFQlVHTVNHVEwoKCJ0YWJsZTppdGVyYXRvcjpjb3VudCIsICJmaXJzdCBEUDogJXggJXggJXhcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4MSwgY3R4MiwgdnAyKSk7CgogICAgLyogWFhYIC0gZnJlZSBjb250ZXh0ID8gKi8KCiAgICB3aGlsZSAodnAyKSB7CiAgICAgICAgaSsrOwogICAgICAgIHZwMiA9IGlpbmZvLT5nZXRfbmV4dF9kYXRhX3BvaW50KCAmY3R4MSwgJmN0eDIsIHZwMiwgaWluZm8gKTsKICAgICAgICBERUJVR01TR1RMKCgidGFibGU6aXRlcmF0b3I6Y291bnQiLCAibmV4dCBEUDogJXggJXggJXggKCVkKVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4MSwgY3R4MiwgdnAyLCBpKSk7CiAgICAgICAgLyogWFhYIC0gZnJlZSBjb250ZXh0ID8gKi8KICAgIH0KICAgICAgICAgICAKICAgIC8qIFhYWCAtIGZpbmFsIGZyZWUgY29udGV4dCA/ICovCiAgICBzbm1wX2ZyZWVfdmFyYmluZCggdnAxICk7CiAgICByZXR1cm4gaTsKfQoKCi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICoKICogSXRlcmF0b3IgQVBJOiBJbmRleCBvcGVyYXRpb25zCiAqCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi8KCgovKiogQH0gKi8K