LyoKICogdGFibGVfaXRlcmF0b3IuYyAKICovCi8qIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvcHlyaWdodChzKS4gIFNlZQogKiB0aGUgTmV0LVNOTVAncyBDT1BZSU5HIGZpbGUgZm9yIG1vcmUgZGV0YWlscyBhbmQgb3RoZXIgY29weXJpZ2h0cwogKiB0aGF0IG1heSBhcHBseToKICovCi8qCiAqIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgY29weXJpZ2h0ZWQgYnk6CiAqIENvcHlyaWdodCCpIDIwMDMgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBVc2UgaXMgc3ViamVjdCB0byBsaWNlbnNlIHRlcm1zIHNwZWNpZmllZCBpbiB0aGUgQ09QWUlORyBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhlIE5ldC1TTk1QIHBhY2thZ2UuCiAqLwoKLyoqIEBkZWZncm91cCB0YWJsZV9pdGVyYXRvciB0YWJsZV9pdGVyYXRvcgogKiAgVGhlIHRhYmxlIGl0ZXJhdG9yIGhlbHBlciBpcyBkZXNpZ25lZCB0byBzaW1wbGlmeSB0aGUgdGFzayBvZiB3cml0aW5nIGEgdGFibGUgaGFuZGxlciBmb3IgdGhlIG5ldC1zbm1wIGFnZW50IHdoZW4gdGhlIGRhdGEgYmVpbmcgYWNjZXNzZWQgaXMgbm90IGluIGFuIG9pZCBzb3J0ZWQgZm9ybSBhbmQgbXVzdCBiZSBhY2Nlc3NlZCBleHRlcm5hbGx5LgogKiAgQGluZ3JvdXAgdGFibGUKICAgIEZ1bmN0aW9uYWxseSwgaXQgaXMgYSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIHRoZSBtb3JlCiAgICBnZW5lcmljIHRhYmxlIGhlbHBlciBidXQgZWFzaWVzIHRoZSBidXJkZW4gb2YgR0VUTkVYVCBwcm9jZXNzaW5nIGJ5CiAgICBtYW51YWxseSBsb29waW5nIHRocm91Z2ggYWxsIHRoZSBkYXRhIGluZGV4ZXMgcmV0cmlldmVkIHRocm91Z2gKICAgIGZ1bmN0aW9uIGNhbGxzIHdoaWNoIHNob3VsZCBiZSBzdXBwbGllZCBieSB0aGUgbW9kdWxlIHRoYXQgd2lzaGVzCiAgICBoZWxwLiAgVGhlIG1vZHVsZSB0aGUgdGFibGVfaXRlcmF0b3IgaGVscHMgc2hvdWxkLCBhZnRlcndhcmRzLAogICAgbmV2ZXIgYmUgY2FsbGVkIGZvciB0aGUgY2FzZSBvZiAiTU9ERV9HRVRORVhUIiBhbmQgb25seSBmb3IgdGhlIEdFVAogICAgYW5kIFNFVCByZWxhdGVkIG1vZGVzIGluc3RlYWQuCiAKICAgIFRoZSBmdW5kYW1lbnRhbCBub3Rpb24gYmV0d2VlbiB0aGUgdGFibGUgaXRlcmF0b3IgaXMgdGhhdCBpdAogICAgYWxsb3dzIHlvdXIgY29kZSB0byBpdGVyYXRlIG92ZXIgZWFjaCAicm93IiB3aXRoaW4geW91ciBkYXRhCiAgICBzdG9yYWdlIG1lY2hhbmlzbSwgd2l0aG91dCByZXF1aXJpbmcgdGhhdCBpdCBiZSBzb3J0ZWQgaW4gYQogICAgU05NUC1pbmRleC1jb21wbGlhbnQgbWFubmVyLiAgVGhyb3VnaCB0aGUgZ2V0X2ZpcnN0X2RhdGFfcG9pbnQgYW5kCiAgICBnZXRfbmV4dF9kYXRhX3BvaW50IGhvb2tzLCB0aGUgdGFibGVfaXRlcmF0b3IgaGVscGVyIHdpbGwKICAgIHJlcGVhdGVkbHkgY2FsbCB5b3VyIGhvb2tzIHRvIGZpbmQgdGhlICJwcm9wZXIiIHJvdyBvZiBkYXRhIHRoYXQKICAgIG5lZWRzIHByb2Nlc3NpbmcuICBUaGUgZm9sbG93aW5nIGNvbmNlcHRzIGFyZSBpbXBvcnRhbnQ6CgogICAgICAtIEEgbG9vcCBjb250ZXh0IGlzIGEgcG9pbnRlciB3aGljaCBpbmRpY2F0ZXMgd2hlcmUgaW4gdGhlCiAgICAgICAgY3VycmVudCBwcm9jZXNzaW5nIG9mIGEgc2V0IG9mIHJvd3MgeW91IGN1cnJlbnRseSBhcmUuICBBbGxvd3MKCXRoZSBnZXRfKl9kYXRhX3BvaW50IHJvdXRpbmVzIHRvIG1vdmUgZnJvbSBvbmUgcm93IHRvIHRoZSBuZXh0LAoJb25jZSB0aGUgaXRlcmF0b3IgaGFuZGxlciBoYXMgaWRlbnRpZmllZCB0aGUgYXBwcm9wcmlhdGUgcm93IGZvcgoJdGhpcyByZXF1ZXN0LCB0aGUgam9iIG9mIHRoZSBsb29wIGNvbnRleHQgaXMgZG9uZS4gIFRoZQogICAgICAgIG1vc3Qgc2ltcGxlIGV4YW1wbGUgd291bGQgYmUgYSBwb2ludGVyIHRvIGFuIGludGVnZXIgd2hpY2gKICAgICAgICBzaW1wbHkgY291bnRzIHJvd3MgZnJvbSAxIHRvIFguICBNb3JlIGNvbW1vbmx5LCBpdCBtaWdodCBiZSBhCiAgICAgICAgcG9pbnRlciB0byBhIGxpbmtlZCBsaXN0IG5vZGUsIG9yIHNvbWVvdGhlciBpbnRlcm5hbCBvcgogICAgICAgIGV4dGVybmFsIHJlZmVyZW5jZSB0byBhIGRhdGEgc2V0IChmaWxlIHNlZWsgdmFsdWUsIGFycmF5CiAgICAgICAgcG9pbnRlciwgLi4uKS4gIElmIGFsbG9jYXRlZCBkdXJpbmcgaXRlcmF0aW9uLCBlaXRoZXIgdGhlCiAgICAgICAgZnJlZV9sb29wX2NvbnRleHRfYXRfZW5kIChwcmVmZXJhYmx5KSBvciB0aGUgZnJlZV9sb29wX2NvbnRleHQKICAgICAgICBwb2ludGVycyBzaG91bGQgYmUgc2V0LgoKICAgICAgLSBBIGRhdGEgY29udGV4dCBpcyBzb21ldGhpbmcgdGhhdCB5b3VyIGhhbmRsZXIgY29kZSBjYW4gdXNlCiAgICAgICAgaW4gb3JkZXIgdG8gcmV0cmlldmUgdGhlIHJlc3Qgb2YgdGhlIGRhdGEgZm9yIHRoZSBuZWVkZWQKICAgICAgICByb3cuICBUaGlzIGRhdGEgY2FuIGJlIGFjY2Vzc2VkIGluIHlvdXIgaGFuZGxlciB2aWEKCW5ldHNubXBfZXh0cmFjdF9pdGVyYXRvcl9jb250ZXh0IGFwaSB3aXRoIHRoZSBuZXRzbm1wX3JlcXVlc3RfaW5mbwoJc3RydWN0dXJlIHRoYXQncyBwYXNzZWQgaW4uCglUaGUgaW1wb3J0YW50IGRpZmZlcmVuY2UgYmV0d2VlbiBhIGxvb3AgY29udGV4dCBhbmQgYQogICAgICAgIGRhdGEgY29udGV4dCBpcyB0aGF0IG11bHRpcGxlIGRhdGEgY29udGV4dHMgY2FuIGJlIGtlcHQgYnkgdGhlCiAgICAgICAgdGFibGVfaXRlcmF0b3IgaGVscGVyLCB3aGVyZSBhcyBvbmx5IG9uZSBsb29wIGNvbnRleHQgd2lsbAogICAgICAgIGV2ZXIgYmUgaGVsZCBieSB0aGUgdGFibGVfaXRlcmF0b3IgaGVscGVyLiAgSWYgYWxsb2NhdGVkCiAgICAgICAgZHVyaW5nIGl0ZXJhdGlvbiB0aGUgZnJlZV9kYXRhX2NvbnRleHQgcG9pbnRlciBzaG91bGQgYmUgc2V0CiAgICAgICAgdG8gYW4gYXBwcm9wcmlhdGUgZnVuY3Rpb24uCiAKICAgIFRoZSB0YWJsZSBpdGVyYXRvciBvcGVyYXRlcyBpbiBhIHNlcmllcyBvZiBzdGVwcyB0aGF0IGNhbGwgeW91cgogICAgY29kZSBob29rcyBmcm9tIHlvdXIgbmV0c25tcF9pdGVyYXRvcl9pbmZvIHJlZ2lzdHJhdGlvbiBwb2ludGVyLgogCiAgICAgIC0gdGhlIGdldF9maXJzdF9kYXRhX3BvaW50IGhvb2sgaXMgY2FsbGVkIGF0IHRoZSBiZWdpbm5pbmcgb2YKICAgICAgICBwcm9jZXNzaW5nLiAgSXQgc2hvdWxkIHNldCB0aGUgdmFyaWFibGUgbGlzdCB0byBhIGxpc3Qgb2YKICAgICAgICBpbmRleGVzIGZvciB0aGUgZ2l2ZW4gdGFibGUuICBJdCBzaG91bGQgYWxzbyBzZXQgdGhlCiAgICAgICAgbG9vcF9jb250ZXh0IGFuZCBtYXliZSBhIGRhdGFfY29udGV4dCB3aGljaCB5b3Ugd2lsbCBnZXQgYQogICAgICAgIHBvaW50ZXIgYmFjayB0byB3aGVuIGl0IG5lZWRzIHRvIGNhbGwgeW91ciBjb2RlIHRvIHJldHJpZXZlCiAgICAgICAgYWN0dWFsIGRhdGEgbGF0ZXIuICBUaGUgbGlzdCBvZiBpbmRleGVzIHNob3VsZCBiZSByZXR1cm5lZAogICAgICAgIGFmdGVyIGJlaW5nIHVwZGF0ZS4KCiAgICAgIC0gdGhlIGdldF9uZXh0X2RhdGFfcG9pbnQgaG9vayBpcyB0aGVuIGNhbGxlZCByZXBlYXRlZGx5IGFuZCBpcwogICAgICAgIHBhc3NlZCB0aGUgbG9vcCBjb250ZXh0IGFuZCB0aGUgZGF0YSBjb250ZXh0IGZvciBpdCB0byB1cGRhdGUuCiAgICAgICAgVGhlIGluZGV4ZXMsIGxvb3AgY29udGV4dCBhbmQgZGF0YSBjb250ZXh0IHNob3VsZCBhbGwgYmUKICAgICAgICB1cGRhdGVkIGlmIG1vcmUgZGF0YSBpcyBhdmFpbGFibGUsIG90aGVyd2lzZSB0aGV5IHNob3VsZCBiZQogICAgICAgIGxlZnQgYWxvbmUgYW5kIGEgTlVMTCBzaG91bGQgYmUgcmV0dXJuZWQuICBJZGVhbGx5LCBpdCBzaG91bGQKICAgICAgICB1cGRhdGUgdGhlIGxvb3AgY29udGV4dCB3aXRob3V0IHRoZSBuZWVkIHRvIHJlYWxsb2NhdGUgaXQuICBJZgogICAgICAgIHJlYWxsb2NhdGlvbiBpcyBuZWNlc3NhcnkgZm9yIGV2ZXJ5IGl0ZXJhdGl2ZSBzdGVwLCB0aGVuIHRoZQogICAgICAgIGZyZWVfbG9vcF9jb250ZXh0IGZ1bmN0aW9uIHBvaW50ZXIgc2hvdWxkIGJlIHNldC4gIElmIG5vdCwKICAgICAgICB0aGVuIHRoZSBmcmVlX2xvb3BfY29udGV4dF9hdF9lbmQgcG9pbnRlciBzaG91bGQgYmUgc2V0LCB3aGljaAogICAgICAgIGlzIG1vcmUgZWZmaWNpZW50IHNpbmNlIGEgbWFsbG9jL2ZyZWUgd2lsbCBvbmx5IGJlIHBlcmZvcm1lZAogICAgICAgIG9uY2UgZm9yIGV2ZXJ5IGl0ZXJhdGlvbi4KICoKICogIEB7CiAqLwoKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWNvbmZpZy5oPgoKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWluY2x1ZGVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9uZXQtc25tcC1hZ2VudC1pbmNsdWRlcy5oPgoKI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L3RhYmxlX2l0ZXJhdG9yLmg+CgojaWYgSEFWRV9TVFJJTkdfSAojaW5jbHVkZSA8c3RyaW5nLmg+CiNlbHNlCiNpbmNsdWRlIDxzdHJpbmdzLmg+CiNlbmRpZgoKI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L3RhYmxlLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9zZXJpYWxpemUuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L3N0YXNoX2NhY2hlLmg+CgovKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAqCiAqIEl0ZXJhdG9yIEFQSTogVGFibGUgbWFpbnRlbmFuY2UKICoKICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLwoKICAgIC8qCiAgICAgKiBJdGVyYXRvci1iYXNlZCB0YWJsZXMgYXJlIHR5cGljYWxseSBtYWludGFpbmVkIGJ5IGV4dGVybmFsCiAgICAgKiAgY29kZSwgYW5kIHRoaXMgaGVscGVyIGlzIHJlYWxseSBvbmx5IGNvbmNlcm5lZCB3aXRoCiAgICAgKiAgbWFwcGluZyBiZXR3ZWVuIGEgd2FsayB0aHJvdWdoIHRoaXMgbG9jYWwgcmVwcmVzZW50YXRpb24sCiAgICAgKiAgYW5kIHRoZSByZXF1aXJlbWVudHMgb2YgU05NUCB0YWJsZSBvcmRlcmluZy4KICAgICAqIEhvd2V2ZXIsIHRoZXJlJ3MgYSBjYXNlIHRvIGJlIG1hZGUgZm9yIGNvbnNpZGVyaW5nIHRoZQogICAgICogIGl0ZXJhdG9yIGluZm8gc3RydWN0dXJlIGFzIGVuY2Fwc3VsYXRpbmcgdGhlIHRhYmxlLCBzbwogICAgICogIGl0J3MgcHJvYmFibHkgd29ydGggZGVmaW5pbmcgdGhlIHRhYmxlIGNyZWF0aW9uL2RlbGV0aW9uCiAgICAgKiAgcm91dGluZXMgZnJvbSB0aGUgZ2VuZXJpYyBBUEkuCiAgICAgKgogICAgICogVGltZSB3aWxsIHNob3cgd2hldGhlciB0aGlzIGlzIGEgc2Vuc2libGUgYXBwcm9hY2ggb3Igbm90LgogICAgICovCm5ldHNubXBfaXRlcmF0b3JfaW5mbyAqCm5ldHNubXBfaXRlcmF0b3JfY3JlYXRlX3RhYmxlKCBOZXRzbm1wX0ZpcnN0X0RhdGFfUG9pbnQgKmZpcnN0RFAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZXRzbm1wX05leHRfRGF0YV9Qb2ludCAgKm5leHREUCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5ldHNubXBfRmlyc3RfRGF0YV9Qb2ludCAqZ2V0aWR4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICAgICppbmRleGVzKQp7CiAgICBuZXRzbm1wX2l0ZXJhdG9yX2luZm8gKmlpbmZvID0KICAgICAgICBTTk1QX01BTExPQ19UWVBFREVGKG5ldHNubXBfaXRlcmF0b3JfaW5mbyk7CgogICAgaWYgKCAhaWluZm8gKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGlmICggaW5kZXhlcyApCiAgICAgICAgaWluZm8tPmluZGV4ZXMgPSBzbm1wX2Nsb25lX3ZhcmJpbmQoaW5kZXhlcyk7CiAgICBpaW5mby0+Z2V0X2ZpcnN0X2RhdGFfcG9pbnQgPSBmaXJzdERQOwogICAgaWluZm8tPmdldF9uZXh0X2RhdGFfcG9pbnQgID0gbmV4dERQOwogICAgaWluZm8tPmdldF9yb3dfaW5kZXhlcyAgICAgID0gZ2V0aWR4OwoKICAgIHJldHVybiBpaW5mbzsKfQoKdm9pZApuZXRzbm1wX2l0ZXJhdG9yX2RlbGV0ZV90YWJsZSggbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbyApCnsKICAgIGlmICghaWluZm8pCiAgICAgICAgcmV0dXJuOwoKICAgIGlmIChpaW5mby0+aW5kZXhlcykgewogICAgICAgIHNubXBfZnJlZV92YXJiaW5kKCBpaW5mby0+aW5kZXhlcyApOwogICAgICAgIGlpbmZvLT5pbmRleGVzID0gTlVMTDsKICAgIH0KICAgIFNOTVBfRlJFRSggaWluZm8gKTsKfQoKICAgIC8qCiAgICAgKiBUaGUgcmVzdCBvZiB0aGUgdGFibGUgbWFpbnRlbmFuY2Ugc2VjdGlvbiBvZiB0aGUKICAgICAqICAgZ2VuZXJpYyB0YWJsZSBBUEkgaXMgTm90IEFwcGxpY2FibGUgdG8gdGhpcyBoZWxwZXIuCiAgICAgKgogICAgICogVGhlIGNvbnRlbnRzIG9mIGEgaXRlcmF0b3ItYmFzZWQgdGFibGUgd2lsbCBiZQogICAgICogIG1haW50YWluZWQgYnkgdGhlIHRhYmxlLXNwZWNpZmljIG1vZHVsZSBpdHNlbGYuCiAgICAgKi8KCi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICoKICogSXRlcmF0b3IgQVBJOiBNSUIgbWFpbnRlbmFuY2UKICoKICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLwoKLyoqIHJldHVybnMgYSBuZXRzbm1wX21pYl9oYW5kbGVyIG9iamVjdCBmb3IgdGhlIHRhYmxlX2l0ZXJhdG9yIGhlbHBlciAqLwpuZXRzbm1wX21pYl9oYW5kbGVyICoKbmV0c25tcF9nZXRfdGFibGVfaXRlcmF0b3JfaGFuZGxlcihuZXRzbm1wX2l0ZXJhdG9yX2luZm8gKmlpbmZvKQp7CiAgICBuZXRzbm1wX21pYl9oYW5kbGVyICptZTsKCiAgICBpZiAoIWlpbmZvKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIG1lID0KICAgICAgICBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyKFRBQkxFX0lURVJBVE9SX05BTUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3RhYmxlX2l0ZXJhdG9yX2hlbHBlcl9oYW5kbGVyKTsKCiAgICBpZiAoIW1lKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIG1lLT5teXZvaWQgPSBpaW5mbzsKICAgIHJldHVybiBtZTsKfQoKLyoqIAogKiBDcmVhdGVzIGFuZCByZWdpc3RlcnMgYSB0YWJsZSBpdGVyYXRvciBoZWxwZXIgaGFuZGxlciBjYWxsaW5nIAogKiBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyIHdpdGggYSBoYW5kbGVyIG5hbWUgc2V0IHRvIFRBQkxFX0lURVJBVE9SX05BTUUgCiAqIGFuZCBhY2Nlc3MgbWV0aG9kLCBuZXRzbm1wX3RhYmxlX2l0ZXJhdG9yX2hlbHBlcl9oYW5kbGVyLgogKgogKiBJZiBOT1RfU0VSSUFMSVpFRCBpcyBub3QgZGVmaW5lZCB0aGUgZnVuY3Rpb24gaW5qZWN0cyB0aGUgc2VyaWFsaXplCiAqIGhhbmRsZXIgaW50byB0aGUgY2FsbGluZyBjaGFpbiBwcmlvciB0byBjYWxsaW5nIG5ldHNubXBfcmVnaXN0ZXJfdGFibGUuCiAqCiAqIEBwYXJhbSByZWdpbmZvIGlzIGEgcG9pbnRlciB0byBhIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gc3RydWN0CiAqCiAqIEBwYXJhbSBpaW5mbyBpcyBhIHBvaW50ZXIgdG8gYSBuZXRzbm1wX2l0ZXJhdG9yX2luZm8gc3RydWN0CiAqCiAqIEByZXR1cm4gTUlCX1JFR0lTVEVSRURfT0sgaXMgcmV0dXJuZWQgaWYgdGhlIHJlZ2lzdHJhdGlvbiB3YXMgYSBzdWNjZXNzLgogKglGYWlsdXJlcyBhcmUgTUlCX1JFR0lTVFJBVElPTl9GQUlMRUQsIE1JQl9EVVBMSUNBVEVfUkVHSVNUUkFUSU9OLgogKglJZiBpaW5mbyBpcyBOVUxMLCBTTk1QRVJSX0dFTkVSUiBpcyByZXR1cm5lZC4KICoKICovCmludApuZXRzbm1wX3JlZ2lzdGVyX3RhYmxlX2l0ZXJhdG9yKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbykKewogICAgcmVnaW5mby0+bW9kZXMgfD0gSEFORExFUl9DQU5fU1RBU0g7CiAgICBuZXRzbm1wX2luamVjdF9oYW5kbGVyKHJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfZ2V0X3RhYmxlX2l0ZXJhdG9yX2hhbmRsZXIoaWluZm8pKTsKICAgIGlmICghaWluZm8pCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgaWYgKCFpaW5mby0+aW5kZXhlcyAmJiBpaW5mby0+dGFibGVfcmVnaW5mbyAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICBpaW5mby0+dGFibGVfcmVnaW5mby0+aW5kZXhlcyApCiAgICAgICAgaWluZm8tPmluZGV4ZXMgPSBzbm1wX2Nsb25lX3ZhcmJpbmQoIGlpbmZvLT50YWJsZV9yZWdpbmZvLT5pbmRleGVzICk7CgogICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfdGFibGUocmVnaW5mbywgaWluZm8tPnRhYmxlX3JlZ2luZm8pOwp9CgovKiogZXh0cmFjdHMgdGhlIHRhYmxlX2l0ZXJhdG9yIHNwZWNpZmljIGRhdGEgZnJvbSBhIHJlcXVlc3QuCiAqIFRoaXMgZnVuY3Rpb24gZXh0cmFjdHMgdGhlIHRhYmxlIGl0ZXJhdG9yIHNwZWNpZmljIGRhdGEgZnJvbSBhIAogKiBuZXRzbm1wX3JlcXVlc3RfaW5mbyBvYmplY3QuICBDYWxscyBuZXRzbm1wX3JlcXVlc3RfZ2V0X2xpc3RfZGF0YQogKiB3aXRoIHJlcXVlc3QtPnBhcmVudF9kYXRhIHNldCB3aXRoIGRhdGEgZnJvbSBhIHJlcXVlc3QgdGhhdCB3YXMgYWRkZWQgCiAqIHByZXZpb3VzbHkgYnkgYSBtb2R1bGUgYW5kIFRBQkxFX0lURVJBVE9SX05BTUUgaGFuZGxlciBuYW1lLgogKgogKiBAcGFyYW0gcmVxdWVzdCB0aGUgbmV0c25tcCByZXF1ZXN0IGluZm8gc3RydWN0dXJlCiAqCiAqIEByZXR1cm4gYSB2b2lkIHBvaW50ZXIocmVxdWVzdC0+cGFyZW50X2RhdGEtPmRhdGEpLCBvdGhlcndpc2UgTlVMTCBpcwogKiAgICAgICAgIHJldHVybmVkIGlmIHJlcXVlc3QgaXMgTlVMTCBvciByZXF1ZXN0LT5wYXJlbnRfZGF0YSBpcyBOVUxMIG9yCiAqICAgICAgICAgcmVxdWVzdC0+cGFyZW50X2RhdGEgb2JqZWN0IGlzIG5vdCBmb3VuZC50aGUgbmV0CiAqCiAqLwpORVRTTk1QX0lOTElORSB2b2lkICAgICoKbmV0c25tcF9leHRyYWN0X2l0ZXJhdG9yX2NvbnRleHQobmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3QpCnsKICAgIHJldHVybiBuZXRzbm1wX3JlcXVlc3RfZ2V0X2xpc3RfZGF0YShyZXF1ZXN0LCBUQUJMRV9JVEVSQVRPUl9OQU1FKTsKfQoKLyoqIGluc2VydHMgdGFibGVfaXRlcmF0b3Igc3BlY2lmaWMgZGF0YSBmb3IgYSBuZXdseQogKiAgY3JlYXRlZCByb3cgaW50byBhIHJlcXVlc3QgKi8KTkVUU05NUF9JTkxJTkUgdm9pZApuZXRzbm1wX2luc2VydF9pdGVyYXRvcl9jb250ZXh0KG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0LCB2b2lkICpkYXRhKQp7CiAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAgICAgICAqcmVxOwogICAgbmV0c25tcF90YWJsZV9yZXF1ZXN0X2luZm8gKnRhYmxlX2luZm8gPSBOVUxMOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICAgICAgKnRoaXNfaW5kZXggPSBOVUxMOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICAgICAgKnRoYXRfaW5kZXggPSBOVUxMOwogICAgb2lkICAgICAgYmFzZV9vaWRbXSA9IHswLCAwfTsJLyogTWFrZSBzdXJlIGluZGV4IE9JRHMgYXJlIGxlZ2FsISAqLwogICAgb2lkICAgICAgdGhpc19vaWRbTUFYX09JRF9MRU5dOwogICAgb2lkICAgICAgdGhhdF9vaWRbTUFYX09JRF9MRU5dOwogICAgc2l6ZV90ICAgdGhpc19vaWRfbGVuLCB0aGF0X29pZF9sZW47CgogICAgaWYgKCFyZXF1ZXN0KQogICAgICAgIHJldHVybjsKCiAgICAvKgogICAgICogV2UnbGwgYWRkIHRoZSBuZXcgcm93IGluZm9ybWF0aW9uIHRvIGFueSByZXF1ZXN0CiAgICAgKiBzdHJ1Y3R1cmUgd2l0aCB0aGUgc2FtZSBpbmRleCB2YWx1ZXMgYXMgdGhlIHJlcXVlc3QKICAgICAqIHBhc3NlZCBpbiAod2hpY2ggaW5jbHVkZXMgdGhhdCBvbmUhKS4KICAgICAqCiAgICAgKiBTbyBjb25zdHJ1Y3QgYW4gT0lEIGJhc2VkIG9uIHRoZXNlIGluZGV4IHZhbHVlcy4KICAgICAqLwoKICAgIHRhYmxlX2luZm8gPSBuZXRzbm1wX2V4dHJhY3RfdGFibGVfaW5mbyhyZXF1ZXN0KTsKICAgIHRoaXNfaW5kZXggPSB0YWJsZV9pbmZvLT5pbmRleGVzOwogICAgYnVpbGRfb2lkX25vYWxsb2ModGhpc19vaWQsIE1BWF9PSURfTEVOLCAmdGhpc19vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgYmFzZV9vaWQsIDIsIHRoaXNfaW5kZXgpOwoKICAgIC8qCiAgICAgKiBXZSBuZWVkIHRvIGxvb2sgdGhyb3VnaCB0aGUgd2hvbGUgb2YgdGhlIHJlcXVlc3QgbGlzdAogICAgICogKGFzIHJlY2VpdmVkIGJ5IHRoZSBjdXJyZW50IGhhbmRsZXIpLCBhcyB0aGVyZSdzIG5vCiAgICAgKiBndWFyYW50ZWUgdGhhdCB0aGlzIHJvdXRpbmUgd2lsbCBiZSBjYWxsZWQgYnkgdGhlIGZpcnN0CiAgICAgKiB2YXJiaW5kIHRoYXQgcmVmZXJzIHRvIHRoaXMgcm93LgogICAgICogICBJbiBwYXJ0aWN1bGFyLCBhIFJvd1N0YXR1cyBjb250cm9sbGVkIHJvdyBjcmVhdGlvbgogICAgICogbWF5IGVhc2lseSBvY2N1ciBsYXRlciBpbiB0aGUgdmFyaWFibGUgbGlzdC4KICAgICAqCiAgICAgKiBTbyBmaXJzdCwgd2UgcmV3aW5kIHRvIHRoZSBoZWFkIG9mIHRoZSBsaXN0Li4uLgogICAgICovCiAgICBmb3IgKHJlcT1yZXF1ZXN0OyByZXEtPnByZXY7IHJlcT1yZXEtPnByZXYpCiAgICAgICAgOwoKICAgIC8qCiAgICAgKiAuLi4gYW5kIHRoZW4gc3RhcnQgbG9va2luZyBmb3IgbWF0Y2hpbmcgaW5kZXhlcwogICAgICogKGJ5IGNvbnN0cnVjdGluZyBPSURzIGZyb20gdGhlc2UgaW5kZXggdmFsdWVzKQogICAgICovCiAgICBmb3IgKDsgcmVxOyByZXE9cmVxLT5uZXh0KSB7CiAgICAgICAgdGFibGVfaW5mbyA9IG5ldHNubXBfZXh0cmFjdF90YWJsZV9pbmZvKHJlcSk7CiAgICAgICAgdGhhdF9pbmRleCA9IHRhYmxlX2luZm8tPmluZGV4ZXM7CiAgICAgICAgYnVpbGRfb2lkX25vYWxsb2ModGhhdF9vaWQsIE1BWF9PSURfTEVOLCAmdGhhdF9vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgIGJhc2Vfb2lkLCAyLCB0aGF0X2luZGV4KTsKICAgICAgCiAgICAgICAgLyoKICAgICAgICAgKiBUaGlzIHJlcXVlc3QgaGFzIHRoZSBzYW1lIGluZGV4IHZhbHVlcywKICAgICAgICAgKiBzbyBhZGQgdGhlIG5ld2x5LWNyZWF0ZWQgcm93IGluZm9ybWF0aW9uLgogICAgICAgICAqLwogICAgICAgIGlmIChzbm1wX29pZF9jb21wYXJlKHRoaXNfb2lkLCB0aGlzX29pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhhdF9vaWQsIHRoYXRfb2lkX2xlbikgPT0gMCkgewogICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfYWRkX2xpc3RfZGF0YShyZXEsCiAgICAgICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV9kYXRhX2xpc3QoVEFCTEVfSVRFUkFUT1JfTkFNRSwgZGF0YSwgTlVMTCkpOwogICAgICAgIH0KICAgIH0KfQoKI2RlZmluZSBUSV9SRVFVRVNUX0NBQ0hFICJ0aV9jYWNoZSIKCnR5cGVkZWYgc3RydWN0IHRpX2NhY2hlX2luZm9fcyB7CiAgIG9pZCBiZXN0X21hdGNoW01BWF9PSURfTEVOXTsKICAgc2l6ZV90IGJlc3RfbWF0Y2hfbGVuOwogICB2b2lkICpkYXRhX2NvbnRleHQ7CiAgIE5ldHNubXBfRnJlZV9EYXRhX0NvbnRleHQgKmZyZWVfY29udGV4dDsKICAgbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbzsKICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICpyZXN1bHRzOwp9IHRpX2NhY2hlX2luZm87CgpzdGF0aWMgdm9pZApuZXRzbm1wX2ZyZWVfdGlfY2FjaGUodm9pZCAqaXQpIHsKICAgIHRpX2NhY2hlX2luZm8gKmJlZXIgPSBpdDsKICAgIGlmICghaXQpIHJldHVybjsKICAgIGlmIChiZWVyLT5kYXRhX2NvbnRleHQgJiYgYmVlci0+ZnJlZV9jb250ZXh0KSB7CiAgICAgICAgICAgIChiZWVyLT5mcmVlX2NvbnRleHQpKGJlZXItPmRhdGFfY29udGV4dCwgYmVlci0+aWluZm8pOwogICAgfQogICAgaWYgKGJlZXItPnJlc3VsdHMpIHsKICAgICAgICBzbm1wX2ZyZWVfdmFyYmluZChiZWVyLT5yZXN1bHRzKTsKICAgIH0KICAgIGZyZWUoYmVlcik7Cn0KCi8qIGNhY2hlcyBpbmZvcm1hdGlvbiAoaW4gdGhlIHJlcXVlc3QpIHdlJ2xsIG5lZWQgYXQgYSBsYXRlciBwb2ludCBpbiB0aW1lICovCnN0YXRpYyB0aV9jYWNoZV9pbmZvICoKbmV0c25tcF9pdGVyYXRvcl9yZW1lbWJlcihuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICBvaWQgKm9pZF90b19zYXZlLAogICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBvaWRfdG9fc2F2ZV9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY2FsbGJhY2tfZGF0YV9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmNhbGxiYWNrX2xvb3BfY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2l0ZXJhdG9yX2luZm8gKmlpbmZvKQp7CiAgICB0aV9jYWNoZV9pbmZvICp0aV9pbmZvOwoKICAgIGlmICghcmVxdWVzdCB8fCAhb2lkX3RvX3NhdmUgfHwgb2lkX3RvX3NhdmVfbGVuID4gTUFYX09JRF9MRU4pCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgLyogZXh0cmFjdCBleGlzdGluZyBjYWNoZWQgc3RhdGUgKi8KICAgIHRpX2luZm8gPSBuZXRzbm1wX3JlcXVlc3RfZ2V0X2xpc3RfZGF0YShyZXF1ZXN0LCBUSV9SRVFVRVNUX0NBQ0hFKTsKCiAgICAvKiBubyBleGlzdGluZyBjYWNoZWQgc3RhdGUuICBtYWtlIGEgbmV3IG9uZS4gKi8KICAgIGlmICghdGlfaW5mbykgewogICAgICAgIHRpX2luZm8gPSBTTk1QX01BTExPQ19UWVBFREVGKHRpX2NhY2hlX2luZm8pOwogICAgICAgIGlmICh0aV9pbmZvID09IE5VTEwpCiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIG5ldHNubXBfcmVxdWVzdF9hZGRfbGlzdF9kYXRhKHJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfZGF0YV9saXN0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFRJX1JFUVVFU1RfQ0FDSEUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpX2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfZnJlZV90aV9jYWNoZSkpOwogICAgfQoKICAgIC8qIGZyZWUgZXhpc3RpbmcgY2FjaGUgYmVmb3JlIHJlcGxhY2luZyAqLwogICAgaWYgKHRpX2luZm8tPmRhdGFfY29udGV4dCAmJiB0aV9pbmZvLT5mcmVlX2NvbnRleHQpCiAgICAgICAgKHRpX2luZm8tPmZyZWVfY29udGV4dCkodGlfaW5mby0+ZGF0YV9jb250ZXh0LCBpaW5mbyk7CgogICAgLyogbWF5YmUgZ2VuZXJhdGUgaXQgZnJvbSB0aGUgbG9vcCBjb250ZXh0PyAqLwogICAgaWYgKGlpbmZvLT5tYWtlX2RhdGFfY29udGV4dCAmJiAhY2FsbGJhY2tfZGF0YV9jb250ZXh0KSB7CiAgICAgICAgY2FsbGJhY2tfZGF0YV9jb250ZXh0ID0KICAgICAgICAgICAgKGlpbmZvLT5tYWtlX2RhdGFfY29udGV4dCkoY2FsbGJhY2tfbG9vcF9jb250ZXh0LCBpaW5mbyk7CgogICAgfQoKICAgIC8qIHNhdmUgZGF0YSBhcyByZXF1ZXN0ZWQgKi8KICAgIHRpX2luZm8tPmRhdGFfY29udGV4dCA9IGNhbGxiYWNrX2RhdGFfY29udGV4dDsKICAgIHRpX2luZm8tPmZyZWVfY29udGV4dCA9IGlpbmZvLT5mcmVlX2RhdGFfY29udGV4dDsKICAgIHRpX2luZm8tPmJlc3RfbWF0Y2hfbGVuID0gb2lkX3RvX3NhdmVfbGVuOwogICAgdGlfaW5mby0+aWluZm8gPSBpaW5mbzsKICAgIGlmIChvaWRfdG9fc2F2ZV9sZW4pCiAgICAgICAgbWVtY3B5KHRpX2luZm8tPmJlc3RfbWF0Y2gsIG9pZF90b19zYXZlLCBvaWRfdG9fc2F2ZV9sZW4gKiBzaXplb2Yob2lkKSk7CgogICAgcmV0dXJuIHRpX2luZm87Cn0gICAgCgojZGVmaW5lIFRBQkxFX0lURVJBVE9SX05PVEFHQUlOIDI1NQovKiBpbXBsZW1lbnRzIHRoZSB0YWJsZV9pdGVyYXRvciBoZWxwZXIgKi8KaW50Cm5ldHNubXBfdGFibGVfaXRlcmF0b3JfaGVscGVyX2hhbmRsZXIobmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cykKewogICAgbmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyAqdGJsX2luZm87CiAgICBuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyAqdGFibGVfaW5mbyA9IE5VTEw7CiAgICBvaWQgICAgICAgICAgICAgY29sb2lkW01BWF9PSURfTEVOXTsKICAgIHNpemVfdCAgICAgICAgICBjb2xvaWRfbGVuOwogICAgaW50ICAgICAgICAgICAgIHJldCA9IFNOTVBfRVJSX05PRVJST1I7CiAgICBzdGF0aWMgb2lkICAgICAgbXluYW1lW01BWF9PSURfTEVOXTsKICAgIHNpemVfdCAgICAgICAgICBteW5hbWVfbGVuOwogICAgaW50ICAgICAgICAgICAgIG9sZG1vZGUgPSAwOwogICAgbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbzsKICAgIGludCBub3Rkb25lOwogICAgaW50IGhpbnRvayA9IDA7CiAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdCwgKnJlcXRtcCA9IE5VTEw7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKmluZGV4X3NlYXJjaCA9IE5VTEw7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKmZyZWVfdGhpc19pbmRleF9zZWFyY2ggPSBOVUxMOwogICAgdm9pZCAgICAgICAgICAgKmNhbGxiYWNrX2xvb3BfY29udGV4dCA9IE5VTEwsICpsYXN0X2xvb3BfY29udGV4dDsKICAgIHZvaWQgICAgICAgICAgICpjYWxsYmFja19kYXRhX2NvbnRleHQgPSBOVUxMOwogICAgdGlfY2FjaGVfaW5mbyAgKnRpX2luZm8gPSBOVUxMOwogICAgaW50ICAgICAgICAgICAgIHJlcXVlc3RfY291bnQgPSAwOwogICAgbmV0c25tcF9vaWRfc3Rhc2hfbm9kZSAqKmNpbmZvID0gTlVMTDsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqb2xkX2luZGV4ZXMgPSBOVUxMLCAqdmI7CiAgICBuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvICp0YWJsZV9yZWdfaW5mbyA9IE5VTEw7CiAgICBpbnQgaTsKICAgIG5ldHNubXBfZGF0YV9saXN0ICAgICpsZGF0YSA9IE5VTEw7CiAgICAKICAgIGlpbmZvID0gKG5ldHNubXBfaXRlcmF0b3JfaW5mbyAqKSBoYW5kbGVyLT5teXZvaWQ7CiAgICBpZiAoIWlpbmZvIHx8ICFyZWdpbmZvIHx8ICFyZXFpbmZvKQogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CgogICAgdGJsX2luZm8gPSBpaW5mby0+dGFibGVfcmVnaW5mbzsKCiAgICAvKgogICAgICogY29weSBpbiB0aGUgdGFibGUgcmVnaXN0cmF0aW9uIG9pZCBmb3IgbGF0ZXIgdXNlIAogICAgICovCiAgICBjb2xvaWRfbGVuID0gcmVnaW5mby0+cm9vdG9pZF9sZW4gKyAyOwogICAgbWVtY3B5KGNvbG9pZCwgcmVnaW5mby0+cm9vdG9pZCwgcmVnaW5mby0+cm9vdG9pZF9sZW4gKiBzaXplb2Yob2lkKSk7CiAgICBjb2xvaWRbcmVnaW5mby0+cm9vdG9pZF9sZW5dID0gMTsgICAvKiB0YWJsZS5lbnRyeSBub2RlICovCgogICAgLyoKICAgICAqIGlsbGVnYWxseSBnb3QgaGVyZSBpZiB0aGVzZSBmdW5jdGlvbnMgYXJlbid0IGRlZmluZWQgCiAgICAgKi8KICAgIGlmIChpaW5mby0+Z2V0X2ZpcnN0X2RhdGFfcG9pbnQgPT0gTlVMTCB8fAogICAgICAgIGlpbmZvLT5nZXRfbmV4dF9kYXRhX3BvaW50ID09IE5VTEwpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLAogICAgICAgICAgICAgICAgICJ0YWJsZV9pdGVyYXRvciBoZWxwZXIgY2FsbGVkIHdpdGhvdXQgZGF0YSBhY2Nlc3NvciBmdW5jdGlvbnNcbiIpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICB9CgogICAgLyogcHJlbGltaW5hcnkgYW5hbHlzaXMgKi8KICAgIHN3aXRjaCAocmVxaW5mby0+bW9kZSkgewogICAgY2FzZSBNT0RFX0dFVF9TVEFTSDoKICAgICAgICBjaW5mbyA9IG5ldHNubXBfZXh0cmFjdF9zdGFzaF9jYWNoZShyZXFpbmZvKTsKICAgICAgICB0YWJsZV9yZWdfaW5mbyA9IG5ldHNubXBfZmluZF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyhyZWdpbmZvKTsKCiAgICAgICAgLyogWFhYOiBtb3ZlIHRoaXMgbWFsbG9jIHRvIHN0YXNoX2NhY2hlIGhhbmRsZXI/ICovCiAgICAgICAgcmVxdG1wID0gU05NUF9NQUxMT0NfVFlQRURFRihuZXRzbm1wX3JlcXVlc3RfaW5mbyk7CiAgICAgICAgaWYgKHJlcXRtcCA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfR0VORVJSOwogICAgICAgIHJlcXRtcC0+c3VidHJlZSA9IHJlcXVlc3RzLT5zdWJ0cmVlOwogICAgICAgIHRhYmxlX2luZm8gPSBuZXRzbm1wX2V4dHJhY3RfdGFibGVfaW5mbyhyZXF1ZXN0cyk7CiAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2FkZF9saXN0X2RhdGEocmVxdG1wLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX2RhdGFfbGlzdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChUQUJMRV9IQU5ETEVSX05BTUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkICopIHRhYmxlX2luZm8sIE5VTEwpKTsKCiAgICAgICAgLyogcmVtZW1iZXIgdGhlIGluZGV4ZXMgdGhhdCB3ZXJlIG9yaWdpbmFsbHkgcGFyc2VkLiAqLwogICAgICAgIG9sZF9pbmRleGVzID0gdGFibGVfaW5mby0+aW5kZXhlczsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfR0VUTkVYVDoKICAgICAgICBmb3IocmVxdWVzdCA9IHJlcXVlc3RzIDsgcmVxdWVzdDsgcmVxdWVzdCA9IHJlcXVlc3QtPm5leHQpIHsKICAgICAgICAgICAgaWYgKHJlcXVlc3QtPnByb2Nlc3NlZCkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB0YWJsZV9pbmZvID0gbmV0c25tcF9leHRyYWN0X3RhYmxlX2luZm8ocmVxdWVzdCk7CiAgICAgICAgICAgIGlmICh0YWJsZV9pbmZvID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBDbGVhbnVwIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAoZnJlZV90aGlzX2luZGV4X3NlYXJjaCkKICAgICAgICAgICAgICAgICAgICBzbm1wX2ZyZWVfdmFyYmluZChmcmVlX3RoaXNfaW5kZXhfc2VhcmNoKTsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHRhYmxlX2luZm8tPmNvbG51bSA8IHRibF9pbmZvLT5taW5fY29sdW1uIC0gMSkgewogICAgICAgICAgICAgICAgLyogWFhYOiBvcHRpbWl6ZSBiZXR0ZXIgdGhhbiB0aGlzICovCiAgICAgICAgICAgICAgICAvKiBmb3Igbm93LCBqdXN0IGluY3JlYXNlIHRvIGNvbG51bS0xICovCiAgICAgICAgICAgICAgICAvKiB3ZSBuZWVkIHRvIGp1bXAgdG8gdGhlIGxvd2VzdCByZXN1bHQgb2YgdGhlIG1pbl9jb2x1bW4KICAgICAgICAgICAgICAgICAgIGFuZCB0YWtlIGl0LCBjb21wYXJpbmcgdG8gbm90aGluZyBmcm9tIHRoZSByZXF1ZXN0ICovCiAgICAgICAgICAgICAgICB0YWJsZV9pbmZvLT5jb2xudW0gPSB0YmxfaW5mby0+bWluX2NvbHVtbiAtIDE7CiAgICAgICAgICAgIH0gZWxzZSBpZiAodGFibGVfaW5mby0+Y29sbnVtID4gdGJsX2luZm8tPm1heF9jb2x1bW4pIHsKICAgICAgICAgICAgICAgIHJlcXVlc3QtPnByb2Nlc3NlZCA9IFRBQkxFX0lURVJBVE9SX05PVEFHQUlOOwogICAgICAgICAgICB9CgogICAgICAgICAgICB0aV9pbmZvID0KICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9nZXRfbGlzdF9kYXRhKHJlcXVlc3QsIFRJX1JFUVVFU1RfQ0FDSEUpOwogICAgICAgICAgICBpZiAoIXRpX2luZm8pIHsKICAgICAgICAgICAgICAgIHRpX2luZm8gPSBTTk1QX01BTExPQ19UWVBFREVGKHRpX2NhY2hlX2luZm8pOwogICAgICAgICAgICAgICAgaWYgKHRpX2luZm8gPT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogQ2xlYW51cCAKICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBpZiAoZnJlZV90aGlzX2luZGV4X3NlYXJjaCkKICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQoZnJlZV90aGlzX2luZGV4X3NlYXJjaCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9hZGRfbGlzdF9kYXRhKHJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV9kYXRhX2xpc3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChUSV9SRVFVRVNUX0NBQ0hFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpX2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9mcmVlX3RpX2NhY2hlKSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIFhYWDogaWYgbm8gdmFsaWQgcmVxdWVzdHMsIGRvbid0IGV2ZW4gbG9vcCBiZWxvdyAqLwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KCiAgICAvKgogICAgICogY29sbGVjdCBhbGwgaW5mb3JtYXRpb24gZm9yIGVhY2ggbmVlZGVkIHJvdwogICAgICovCiAgICBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVCB8fAogICAgICAgIHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRORVhUIHx8CiAgICAgICAgcmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVF9TVEFTSCB8fAogICAgICAgIHJlcWluZm8tPm1vZGUgPT0gTU9ERV9TRVRfUkVTRVJWRTEpIHsKICAgICAgICAvKgogICAgICAgICAqIENvdW50IHRoZSBudW1iZXIgb2YgcmVxdWVzdCBpbiB0aGUgbGlzdCwKICAgICAgICAgKiAgIHNvIHRoYXQgd2UnbGwga25vdyB3aGVuIHdlJ3JlIGZpbmlzaGVkCiAgICAgICAgICovCiAgICAgICAgZm9yKHJlcXVlc3QgPSByZXF1ZXN0cyA7IHJlcXVlc3Q7IHJlcXVlc3QgPSByZXF1ZXN0LT5uZXh0KQogICAgICAgICAgaWYgKCFyZXF1ZXN0LT5wcm9jZXNzZWQpCiAgICAgICAgICAgIHJlcXVlc3RfY291bnQrKzsKICAgICAgICBub3Rkb25lID0gMTsKICAgICAgICBoaW50b2sgPSAxOwogICAgICAgIHdoaWxlKG5vdGRvbmUpIHsKICAgICAgICAgICAgbm90ZG9uZSA9IDA7CgogICAgICAgICAgICAvKiBmaW5kIGZpcnN0IGRhdGEgcG9pbnQgKi8KICAgICAgICAgICAgaWYgKCFpbmRleF9zZWFyY2gpIHsKICAgICAgICAgICAgICAgIGlmIChmcmVlX3RoaXNfaW5kZXhfc2VhcmNoKSB7CiAgICAgICAgICAgICAgICAgICAgLyogcHJldmlvdXNseSBkb25lICovCiAgICAgICAgICAgICAgICAgICAgaW5kZXhfc2VhcmNoID0gZnJlZV90aGlzX2luZGV4X3NlYXJjaDsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZm9yKHJlcXVlc3Q9cmVxdWVzdHMgOyByZXF1ZXN0OyByZXF1ZXN0PXJlcXVlc3QtPm5leHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgdGFibGVfaW5mbyA9IG5ldHNubXBfZXh0cmFjdF90YWJsZV9pbmZvKHJlcXVlc3QpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAodGFibGVfaW5mbykKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBpZiAoIXRhYmxlX2luZm8pIHsKICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJubyB2YWxpZCByZXF1ZXN0cyBmb3IgaXRlcmF0b3IgdGFibGUgJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPmhhbmRsZXJOYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9mcmVlX3JlcXVlc3RfZGF0YV9zZXRzKHJlcXRtcCk7CiAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRlJFRShyZXF0bXApOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgaW5kZXhfc2VhcmNoID0gc25tcF9jbG9uZV92YXJiaW5kKHRhYmxlX2luZm8tPmluZGV4ZXMpOwogICAgICAgICAgICAgICAgICAgIGZyZWVfdGhpc19pbmRleF9zZWFyY2ggPSBpbmRleF9zZWFyY2g7CgogICAgICAgICAgICAgICAgICAgIC8qIHNldHVwLCBtYWxsb2Mgc2VhcmNoIGRhdGE6ICovCiAgICAgICAgICAgICAgICAgICAgaWYgKCFpbmRleF9zZWFyY2gpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgICAgICogaG1tbS4uLi4gIGludmFsaWQgdGFibGU/IAogICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpbnZhbGlkIGluZGV4IGxpc3Qgb3IgZmFpbGVkIG1hbGxvYyBmb3IgdGFibGUgJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPmhhbmRsZXJOYW1lKTsKICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9mcmVlX3JlcXVlc3RfZGF0YV9zZXRzKHJlcXRtcCk7CiAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRlJFRShyZXF0bXApOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIGlmIHNvcnRlZCwgcGFzcyBpbiBhIGhpbnQgKi8KICAgICAgICAgICAgaWYgKGhpbnRvayAmJiAoaWluZm8tPmZsYWdzICYgTkVUU05NUF9JVEVSQVRPUl9GTEFHX1NPUlRFRCkpIHsKICAgICAgICAgICAgICAgIGNhbGxiYWNrX2xvb3BfY29udGV4dCA9IHRhYmxlX2luZm87CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaW5kZXhfc2VhcmNoID0KICAgICAgICAgICAgICAgIChpaW5mby0+Z2V0X2ZpcnN0X2RhdGFfcG9pbnQpICgmY2FsbGJhY2tfbG9vcF9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjYWxsYmFja19kYXRhX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXhfc2VhcmNoLCBpaW5mbyk7CgogICAgICAgICAgICAvKiBsb29wIG92ZXIgZWFjaCBkYXRhIHBvaW50ICovCiAgICAgICAgICAgIHdoaWxlKGluZGV4X3NlYXJjaCkgewoKICAgICAgICAgICAgICAgIC8qIHJlbWVtYmVyIHRvIGZyZWUgdGhpcyBsYXRlciAqLwogICAgICAgICAgICAgICAgZnJlZV90aGlzX2luZGV4X3NlYXJjaCA9IGluZGV4X3NlYXJjaDsKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvKiBjb21wYXJlIGFnYWluc3QgZWFjaCByZXF1ZXN0Ki8KICAgICAgICAgICAgICAgIGZvcihyZXF1ZXN0ID0gcmVxdWVzdHMgOyByZXF1ZXN0OyByZXF1ZXN0ID0gcmVxdWVzdC0+bmV4dCkgewogICAgICAgICAgICAgICAgICAgIGlmIChyZXF1ZXN0LT5wcm9jZXNzZWQpCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICAgICAgICAgICAgICAvKiBYWFg6IHN0b3JlIGluIGFuIGFycmF5IGZvciBmYXN0ZXIgcmV0cml2YWwgKi8KICAgICAgICAgICAgICAgICAgICB0YWJsZV9pbmZvID0gbmV0c25tcF9leHRyYWN0X3RhYmxlX2luZm8ocmVxdWVzdCk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHRhYmxlX2luZm8gPT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAgICAgKiBDbGVhbnVwIAogICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZyZWVfdGhpc19pbmRleF9zZWFyY2gpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbm1wX2ZyZWVfdmFyYmluZChmcmVlX3RoaXNfaW5kZXhfc2VhcmNoKTsKICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9mcmVlX3JlcXVlc3RfZGF0YV9zZXRzKHJlcXRtcCk7CiAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRlJFRShyZXF0bXApOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfR0VORVJSOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBjb2xvaWRbcmVnaW5mby0+cm9vdG9pZF9sZW4gKyAxXSA9IHRhYmxlX2luZm8tPmNvbG51bTsKCiAgICAgICAgICAgICAgICAgICAgdGlfaW5mbyA9CiAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9nZXRfbGlzdF9kYXRhKHJlcXVlc3QsIFRJX1JFUVVFU1RfQ0FDSEUpOwoKICAgICAgICAgICAgICAgICAgICBzd2l0Y2gocmVxaW5mby0+bW9kZSkgewogICAgICAgICAgICAgICAgICAgIGNhc2UgTU9ERV9HRVQ6CiAgICAgICAgICAgICAgICAgICAgY2FzZSBNT0RFX1NFVF9SRVNFUlZFMToKICAgICAgICAgICAgICAgICAgICAgICAgLyogbG9va2luZyBmb3IgZXhhY3QgbWF0Y2hlcyAqLwogICAgICAgICAgICAgICAgICAgICAgICBidWlsZF9vaWRfbm9hbGxvYyhteW5hbWUsIE1BWF9PSURfTEVOLCAmbXluYW1lX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb2lkLCBjb2xvaWRfbGVuLCBpbmRleF9zZWFyY2gpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoc25tcF9vaWRfY29tcGFyZShteW5hbWUsIG15bmFtZV9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJlcXVlc3R2Yi0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiLT5uYW1lX2xlbmd0aCkgPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBrZWVwIHRoaXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5ldHNubXBfaXRlcmF0b3JfcmVtZW1iZXIocmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG15bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG15bmFtZV9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFja19kYXRhX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFja19sb29wX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpaW5mbykgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogQ2xlYW51cCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZnJlZV90aGlzX2luZGV4X3NlYXJjaCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmcmVlX3RoaXNfaW5kZXhfc2VhcmNoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2ZyZWVfcmVxdWVzdF9kYXRhX3NldHMocmVxdG1wKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0ZSRUUocmVxdG1wKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfR0VORVJSOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdF9jb3VudC0tOyAgIC8qIE9uZSBsZXNzIHRvIGxvb2sgZm9yICovCiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaWluZm8tPmZyZWVfZGF0YV9jb250ZXh0ICYmIGNhbGxiYWNrX2RhdGFfY29udGV4dCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpaW5mby0+ZnJlZV9kYXRhX2NvbnRleHQpKGNhbGxiYWNrX2RhdGFfY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpaW5mbyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgTU9ERV9HRVRfU1RBU0g6CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNvbGxlY3QgZGF0YSBmb3IgZWFjaCBjb2x1bW4gZm9yIGV2ZXJ5IHJvdyAqLwogICAgICAgICAgICAgICAgICAgICAgICBidWlsZF9vaWRfbm9hbGxvYyhteW5hbWUsIE1BWF9PSURfTEVOLCAmbXluYW1lX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb2lkLCBjb2xvaWRfbGVuLCBpbmRleF9zZWFyY2gpOwogICAgICAgICAgICAgICAgICAgICAgICByZXFpbmZvLT5tb2RlID0gTU9ERV9HRVQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXF0bXApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZGF0YSA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9nZXRfbGlzdF9ub2RlKHJlcXRtcC0+cGFyZW50X2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRBQkxFX0lURVJBVE9SX05BTUUpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWxkYXRhKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfYWRkX2xpc3RfZGF0YShyZXF0bXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV9kYXRhX2xpc3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChUQUJMRV9JVEVSQVRPUl9OQU1FLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrX2RhdGFfY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBtYXkgaGF2ZSBjaGFuZ2VkICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZGF0YS0+ZGF0YSA9IGNhbGxiYWNrX2RhdGFfY29udGV4dDsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgdGFibGVfaW5mby0+aW5kZXhlcyA9IGluZGV4X3NlYXJjaDsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yKGkgPSB0YWJsZV9yZWdfaW5mby0+bWluX2NvbHVtbjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGkgPD0gKGludCl0YWJsZV9yZWdfaW5mby0+bWF4X2NvbHVtbjsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBteW5hbWVbcmVnaW5mby0+cm9vdG9pZF9sZW4gKyAxXSA9IGk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWJsZV9pbmZvLT5jb2xudW0gPSBpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmIgPSByZXF0bXAtPnJlcXVlc3R2YiA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9NQUxMT0NfVFlQRURFRihuZXRzbm1wX3ZhcmlhYmxlX2xpc3QpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZiID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIENsZWFudXAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZyZWVfdGhpc19pbmRleF9zZWFyY2gpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNubXBfZnJlZV92YXJiaW5kCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZnJlZV90aGlzX2luZGV4X3NlYXJjaCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZiLT50eXBlID0gQVNOX05VTEw7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbm1wX3NldF92YXJfb2JqaWQodmIsIG15bmFtZSwgbXluYW1lX2xlbik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2NhbGxfbmV4dF9oYW5kbGVyKGhhbmRsZXIsIHJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcWluZm8sIHJlcXRtcCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF0bXAtPnJlcXVlc3R2YiA9IE5VTEw7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF0bXAtPnByb2Nlc3NlZCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodmItPnR5cGUgIT0gQVNOX05VTEwpIHsgLyogWFhYLCBub3QgYWxsICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9vaWRfc3Rhc2hfYWRkX2RhdGEoY2luZm8sIG15bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBteW5hbWVfbGVuLCB2Yik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNubXBfZnJlZV92YXIodmIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHJlcWluZm8tPm1vZGUgPSBNT0RFX0dFVF9TVEFTSDsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgICAgIGNhc2UgTU9ERV9HRVRORVhUOgogICAgICAgICAgICAgICAgICAgICAgICAvKiBsb29raW5nIGZvciAibmV4dCIgbWF0Y2hlcyAqLwogICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV0c25tcF9jaGVja19nZXRuZXh0X3JlcGx5CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVxdWVzdCwgY29sb2lkLCBjb2xvaWRfbGVuLCBpbmRleF9zZWFyY2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnRpX2luZm8tPnJlc3VsdHMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV0c25tcF9pdGVyYXRvcl9yZW1lbWJlcihyZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGlfaW5mby0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzLT5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGlfaW5mby0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzLT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tfZGF0YV9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2tfbG9vcF9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWluZm8pID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIENsZWFudXAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZyZWVfdGhpc19pbmRleF9zZWFyY2gpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNubXBfZnJlZV92YXJiaW5kCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZnJlZV90aGlzX2luZGV4X3NlYXJjaCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiAgSWYgd2UndmUgYmVlbiB0b2xkIHRoYXQgdGhlIHJvd3MgYXJlIHNvcnRlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqICAgdGhlbiB0aGUgZmlyc3QgdmFsaWQgb25lIHdlIGZpbmQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqICAgbXVzdCBiZSB0aGUgcmlnaHQgb25lLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaWluZm8tPmZsYWdzICYgTkVUU05NUF9JVEVSQVRPUl9GTEFHX1NPUlRFRCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0X2NvdW50LS07CiAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlpbmZvLT5mcmVlX2RhdGFfY29udGV4dCAmJiBjYWxsYmFja19kYXRhX2NvbnRleHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoaWluZm8tPmZyZWVfZGF0YV9jb250ZXh0KShjYWxsYmFja19kYXRhX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWluZm8pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUyOgogICAgICAgICAgICAgICAgICAgIGNhc2UgTU9ERV9TRVRfRlJFRToKICAgICAgICAgICAgICAgICAgICBjYXNlIE1PREVfU0VUX1VORE86CiAgICAgICAgICAgICAgICAgICAgY2FzZSBNT0RFX1NFVF9DT01NSVQ6CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5lZWRlZCBwcm9jZXNzaW5nIGFscmVhZHkgZG9uZSBpbiBSRVNFUlZFMSAqLwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhYmxlX2l0ZXJhdG9yIGNhbGxlZCB3aXRoIHVuc3VwcG9ydGVkIG1vZGVcbiIpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsgIC8qIFhYWCByZXR1cm4gKi8KICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvKiBJcyB0aGVyZSBhbnkgcG9pbnQgaW4gY2Fycnlpbmcgb24/ICovCiAgICAgICAgICAgICAgICBpZiAoIXJlcXVlc3RfY291bnQpCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAvKiBnZXQgdGhlIG5leHQgc2VhcmNoIHBvc3NpYmlsaXR5ICovCiAgICAgICAgICAgICAgICBsYXN0X2xvb3BfY29udGV4dCA9IGNhbGxiYWNrX2xvb3BfY29udGV4dDsKICAgICAgICAgICAgICAgIGluZGV4X3NlYXJjaCA9CiAgICAgICAgICAgICAgICAgICAgKGlpbmZvLT5nZXRfbmV4dF9kYXRhX3BvaW50KSAoJmNhbGxiYWNrX2xvb3BfY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmY2FsbGJhY2tfZGF0YV9jb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4X3NlYXJjaCwgaWluZm8pOwogICAgICAgICAgICAgICAgaWYgKGlpbmZvLT5mcmVlX2xvb3BfY29udGV4dCAmJiBsYXN0X2xvb3BfY29udGV4dCAmJgogICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrX2RhdGFfY29udGV4dCAhPSBsYXN0X2xvb3BfY29udGV4dCkgewogICAgICAgICAgICAgICAgICAgIChpaW5mby0+ZnJlZV9sb29wX2NvbnRleHQpIChsYXN0X2xvb3BfY29udGV4dCwgaWluZm8pOwogICAgICAgICAgICAgICAgICAgIGxhc3RfbG9vcF9jb250ZXh0ID0gTlVMTDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogZnJlZSBsb29wIGNvbnRleHQgYmVmb3JlIGdvaW5nIG9uICovCiAgICAgICAgICAgIGlmIChjYWxsYmFja19sb29wX2NvbnRleHQgJiYgaWluZm8tPmZyZWVfbG9vcF9jb250ZXh0X2F0X2VuZCkgewogICAgICAgICAgICAgICAgKGlpbmZvLT5mcmVlX2xvb3BfY29udGV4dF9hdF9lbmQpIChjYWxsYmFja19sb29wX2NvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlpbmZvKTsKICAgICAgICAgICAgICAgIGNhbGxiYWNrX2xvb3BfY29udGV4dCA9IE5VTEw7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIGRlY2lkZSB3aGljaCAoR0VUTkVYVCkgcmVxdWVzdHMgYXJlIG5vdCB5ZXQgZmlsbGVkICovCiAgICAgICAgICAgIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfR0VUTkVYVCkgewogICAgICAgICAgICAgICAgZm9yKHJlcXVlc3QgPSByZXF1ZXN0cyA7IHJlcXVlc3Q7IHJlcXVlc3QgPSByZXF1ZXN0LT5uZXh0KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJlcXVlc3QtPnByb2Nlc3NlZCkKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgdGlfaW5mbyA9CiAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9nZXRfbGlzdF9kYXRhKHJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRJX1JFUVVFU1RfQ0FDSEUpOwogICAgICAgICAgICAgICAgICAgIGlmICghdGlfaW5mby0+cmVzdWx0cykgewogICAgICAgICAgICAgICAgICAgICAgaW50IG5jOwogICAgICAgICAgICAgICAgICAgICAgICB0YWJsZV9pbmZvID0gbmV0c25tcF9leHRyYWN0X3RhYmxlX2luZm8ocmVxdWVzdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIG5jID0gbmV0c25tcF90YWJsZV9uZXh0X2NvbHVtbih0YWJsZV9pbmZvKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKDAgPT0gbmMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9pZFtyZWdpbmZvLT5yb290b2lkX2xlbisxXSA9IHRhYmxlX2luZm8tPmNvbG51bSsxOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9zZXRfdmFyX29iamlkKHJlcXVlc3QtPnJlcXVlc3R2YiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvaWQsIHJlZ2luZm8tPnJvb3RvaWRfbGVuKzIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cHJvY2Vzc2VkID0gVEFCTEVfSVRFUkFUT1JfTk9UQUdBSU47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICB0YWJsZV9pbmZvLT5jb2xudW0gPSBuYzsKICAgICAgICAgICAgICAgICAgICAgICAgICBoaW50b2sgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAgIG5vdGRvbmUgPSAxOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfR0VUIHx8CiAgICAgICAgcmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVE5FWFQgfHwKICAgICAgICByZXFpbmZvLT5tb2RlID09IE1PREVfU0VUX1JFU0VSVkUxKSB7CiAgICAgICAgLyogcGVyIHJlcXVlc3QgbGFzdCBtaW51dGUgcHJvY2Vzc2luZyAqLwogICAgICAgIGZvcihyZXF1ZXN0ID0gcmVxdWVzdHMgOyByZXF1ZXN0OyByZXF1ZXN0ID0gcmVxdWVzdC0+bmV4dCkgewogICAgICAgICAgICBpZiAocmVxdWVzdC0+cHJvY2Vzc2VkKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIHRpX2luZm8gPQogICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2dldF9saXN0X2RhdGEocmVxdWVzdCwgVElfUkVRVUVTVF9DQUNIRSk7CiAgICAgICAgICAgIHRhYmxlX2luZm8gPQogICAgICAgICAgICAgICAgbmV0c25tcF9leHRyYWN0X3RhYmxlX2luZm8ocmVxdWVzdCk7CgogICAgICAgICAgICBpZiAoIXRpX2luZm8pCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAKICAgICAgICAgICAgc3dpdGNoKHJlcWluZm8tPm1vZGUpIHsKCiAgICAgICAgICAgIGNhc2UgTU9ERV9HRVRORVhUOgogICAgICAgICAgICAgICAgaWYgKHRpX2luZm8tPmJlc3RfbWF0Y2hfbGVuKQogICAgICAgICAgICAgICAgICAgIHNubXBfc2V0X3Zhcl9vYmppZChyZXF1ZXN0LT5yZXF1ZXN0dmIsIHRpX2luZm8tPmJlc3RfbWF0Y2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpX2luZm8tPmJlc3RfbWF0Y2hfbGVuKTsKICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIGNvbG9pZFtyZWdpbmZvLT5yb290b2lkX2xlbisxXSA9IAogICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3RhYmxlX25leHRfY29sdW1uKHRhYmxlX2luZm8pOwogICAgICAgICAgICAgICAgICAgIGlmICgwID09IGNvbG9pZFtyZWdpbmZvLT5yb290b2lkX2xlbisxXSkgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBvdXQgb2YgcmFuZ2UuICovCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9pZFtyZWdpbmZvLT5yb290b2lkX2xlbisxXSA9IHRibF9pbmZvLT5tYXhfY29sdW1uICsgMTsKICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cHJvY2Vzc2VkID0gVEFCTEVfSVRFUkFUT1JfTk9UQUdBSU47CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHNubXBfc2V0X3Zhcl9vYmppZChyZXF1ZXN0LT5yZXF1ZXN0dmIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9pZCwgcmVnaW5mby0+cm9vdG9pZF9sZW4rMik7CiAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cHJvY2Vzc2VkID0gMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHNubXBfZnJlZV92YXJiaW5kKHRhYmxlX2luZm8tPmluZGV4ZXMpOwogICAgICAgICAgICAgICAgdGFibGVfaW5mby0+aW5kZXhlcyA9IHNubXBfY2xvbmVfdmFyYmluZCh0aV9pbmZvLT5yZXN1bHRzKTsKICAgICAgICAgICAgICAgIC8qIEZBTEwgVEhST1VHSCAqLwoKICAgICAgICAgICAgY2FzZSBNT0RFX0dFVDoKICAgICAgICAgICAgY2FzZSBNT0RFX1NFVF9SRVNFUlZFMToKICAgICAgICAgICAgICAgIGlmICh0aV9pbmZvLT5kYXRhX2NvbnRleHQpCiAgICAgICAgICAgICAgICAgICAgLyogd2UgZG9uJ3QgYWRkIGEgZnJlZSBwb2ludGVyLCBzaW5jZSBpdCdzIGluIHRoZQogICAgICAgICAgICAgICAgICAgICAgIFRJX1JFUVVFU1RfQ0FDSEUgaW5zdGVhZCAqLwogICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9hZGRfbGlzdF9kYXRhKHJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfZGF0YV9saXN0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFRBQkxFX0lURVJBVE9SX05BTUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpX2luZm8tPmRhdGFfY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCkpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIAogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgIC8qIHdlIGNoYW5nZSBhbGwgR0VUTkVYVCBvcGVyYXRpb25zIGludG8gR0VUIG9wZXJhdGlvbnMuCiAgICAgICAgICAgd2h5PyBiZWNhdXNlIHdlJ3JlIGp1c3Qgc28gbmljZSB0byB0aGUgbG93ZXIgbGV2ZWxzLgogICAgICAgICAgIG1heWJlIHNvbWVkYXkgdGhleSdsbCBwYXkgdXMgZm9yIGl0LiAgZG91YnRmdWwgdGhvdWdoLiAqLwogICAgICAgIG9sZG1vZGUgPSByZXFpbmZvLT5tb2RlOwogICAgICAgIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfR0VUTkVYVCkgewogICAgICAgICAgICByZXFpbmZvLT5tb2RlID0gTU9ERV9HRVQ7CiAgICAgICAgfQogICAgfSBlbHNlIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfR0VUX1NUQVNIKSB7CiAgICAgICAgbmV0c25tcF9mcmVlX3JlcXVlc3RfZGF0YV9zZXRzKHJlcXRtcCk7CiAgICAgICAgU05NUF9GUkVFKHJlcXRtcCk7CiAgICAgICAgdGFibGVfaW5mby0+aW5kZXhlcyA9IG9sZF9pbmRleGVzOwogICAgfQoKCiAgICAvKiBGaW5hbGx5LCB3ZSBnZXQgdG8gY2FsbCB0aGUgbmV4dCBoYW5kbGVyIGJlbG93IHVzLiAgQm95LCB3YXNuJ3QKICAgICAgIGFsbCB0aGF0IHNpbXBsZT8gIFRoZXkgYmV0dGVyIGJlIGdsYWQgdGhleSBkb24ndCBoYXZlIHRvIGRvIGl0ISAqLwogICAgaWYgKHJlcWluZm8tPm1vZGUgIT0gTU9ERV9HRVRfU1RBU0gpIHsKICAgICAgICBERUJVR01TR1RMKCgidGFibGVfaXRlcmF0b3IiLCAiY2FsbCBzdWJoYW5kbGVyIGZvciBtb2RlOiAlc1xuIiwKICAgICAgICAgICAgICAgICAgICBzZV9maW5kX2xhYmVsX2luX3NsaXN0KCJhZ2VudF9tb2RlIiwgb2xkbW9kZSkpKTsKICAgICAgICByZXQgPQogICAgICAgICAgICBuZXRzbm1wX2NhbGxfbmV4dF9oYW5kbGVyKGhhbmRsZXIsIHJlZ2luZm8sIHJlcWluZm8sIHJlcXVlc3RzKTsKICAgIH0KCiAgICAvKiByZXZlcnNlIHRoZSBwcmV2aW91c2x5IHNhdmVkIG1vZGUgaWYgd2Ugd2VyZSBhIGdldG5leHQgKi8KICAgIGlmIChvbGRtb2RlID09IE1PREVfR0VUTkVYVCkgewogICAgICAgIHJlcWluZm8tPm1vZGUgPSBvbGRtb2RlOwogICAgfQoKICAgIC8qIGNsZWFudXAgKi8KICAgIGlmIChmcmVlX3RoaXNfaW5kZXhfc2VhcmNoKQogICAgICAgIHNubXBfZnJlZV92YXJiaW5kKGZyZWVfdGhpc19pbmRleF9zZWFyY2gpOwoKICAgIHJldHVybiByZXQ7Cn0KCi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICoKICogSXRlcmF0b3IgQVBJOiBSb3cgb3BlcmF0aW9ucwogKgogKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09ICovCgp2b2lkICoKbmV0c25tcF9pdGVyYXRvcl9yb3dfZmlyc3QoIG5ldHNubXBfaXRlcmF0b3JfaW5mbyAqaWluZm8gKSB7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZwMSwgKnZwMjsKICAgIHZvaWQgKmN0eDEsICpjdHgyOwoKICAgIGlmICghaWluZm8pCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgdnAxID0gc25tcF9jbG9uZV92YXJiaW5kKGlpbmZvLT5pbmRleGVzKTsKICAgIHZwMiA9IGlpbmZvLT5nZXRfZmlyc3RfZGF0YV9wb2ludCggJmN0eDEsICZjdHgyLCB2cDEsIGlpbmZvICk7CgogICAgaWYgKCF2cDIpCiAgICAgICAgY3R4MiA9IE5VTEw7CgogICAgLyogZnJlZSBsb29wIGNvbnRleHQgPz8gKi8KICAgIHNubXBfZnJlZV92YXJiaW5kKCB2cDEgKTsKICAgIHJldHVybiBjdHgyOyAgLyogb3IgKmN0eDIgPz8gKi8KfQoKdm9pZCAqCm5ldHNubXBfaXRlcmF0b3Jfcm93X2dldCggbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbywgdm9pZCAqcm93ICkKewogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2cDEsICp2cDI7CiAgICB2b2lkICpjdHgxLCAqY3R4MjsKCiAgICBpZiAoIWlpbmZvIHx8ICFyb3cpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgICAgIC8qCiAgICAgICAgICogVGhpcyByb3V0aW5lIHJlbGllcyBvbiBiZWluZyBhYmxlIHRvCiAgICAgICAgICogICBkZXRlcm1pbmUgdGhlIGluZGV4ZXMgZm9yIGEgZ2l2ZW4gcm93LiAgCiAgICAgICAgICovCiAgICBpZiAoIWlpbmZvLT5nZXRfcm93X2luZGV4ZXMpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgdnAxICA9IHNubXBfY2xvbmVfdmFyYmluZChpaW5mby0+aW5kZXhlcyk7CiAgICBjdHgxID0gcm93OyAgIC8qIFByb2JhYmx5IG9ubHkgbmVlZCBvbmUgb2YgdGhlc2UgLi4uICovCiAgICBjdHgyID0gcm93OwogICAgdnAyICA9IGlpbmZvLT5nZXRfcm93X2luZGV4ZXMoICZjdHgxLCAmY3R4MiwgdnAxLCBpaW5mbyApOwoKICAgIGN0eDIgPSBOVUxMOwogICAgaWYgKHZwMikgewogICAgICAgIGN0eDIgPSBuZXRzbm1wX2l0ZXJhdG9yX3Jvd19nZXRfYnlpZHgoIGlpbmZvLCB2cDIgKTsKICAgIH0KICAgIHNubXBfZnJlZV92YXJiaW5kKCB2cDEgKTsKICAgIHJldHVybiBjdHgyOwp9Cgp2b2lkICoKbmV0c25tcF9pdGVyYXRvcl9yb3dfbmV4dCggbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbywgdm9pZCAqcm93ICkKewogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2cDEsICp2cDI7CiAgICB2b2lkICpjdHgxLCAqY3R4MjsKCiAgICBpZiAoIWlpbmZvIHx8ICFyb3cpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgICAgIC8qCiAgICAgICAgICogVGhpcyByb3V0aW5lIHJlbGllcyBvbiBiZWluZyBhYmxlIHRvCiAgICAgICAgICogICBkZXRlcm1pbmUgdGhlIGluZGV4ZXMgZm9yIGEgZ2l2ZW4gcm93LiAgCiAgICAgICAgICovCiAgICBpZiAoIWlpbmZvLT5nZXRfcm93X2luZGV4ZXMpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgdnAxICA9IHNubXBfY2xvbmVfdmFyYmluZChpaW5mby0+aW5kZXhlcyk7CiAgICBjdHgxID0gcm93OyAgIC8qIFByb2JhYmx5IG9ubHkgbmVlZCBvbmUgb2YgdGhlc2UgLi4uICovCiAgICBjdHgyID0gcm93OwogICAgdnAyICA9IGlpbmZvLT5nZXRfcm93X2luZGV4ZXMoICZjdHgxLCAmY3R4MiwgdnAxLCBpaW5mbyApOwoKICAgIGN0eDIgPSBOVUxMOwogICAgaWYgKHZwMikgewogICAgICAgIGN0eDIgPSBuZXRzbm1wX2l0ZXJhdG9yX3Jvd19uZXh0X2J5aWR4KCBpaW5mbywgdnAyICk7CiAgICB9CiAgICBzbm1wX2ZyZWVfdmFyYmluZCggdnAxICk7CiAgICByZXR1cm4gY3R4MjsKfQoKdm9pZCAqCm5ldHNubXBfaXRlcmF0b3Jfcm93X2dldF9ieWlkeCggIG5ldHNubXBfaXRlcmF0b3JfaW5mbyAqaWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqaW5kZXhlcyApCnsKICAgIG9pZCAgICBkdW1teVtdID0gezAsMH07ICAgLyogS2VlcCAnYnVpbGRfb2lkJyBoYXBweSAqLwogICAgb2lkICAgIGluc3RhbmNlW01BWF9PSURfTEVOXTsKICAgIHNpemVfdCBsZW4gPSAgICBNQVhfT0lEX0xFTjsKCiAgICBpZiAoIWlpbmZvIHx8ICFpbmRleGVzKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGJ1aWxkX29pZF9ub2FsbG9jKGluc3RhbmNlLCBNQVhfT0lEX0xFTiwgJmxlbiwKICAgICAgICAgICAgICAgICAgICAgIGR1bW15LCAyLCBpbmRleGVzKTsKICAgIHJldHVybiBuZXRzbm1wX2l0ZXJhdG9yX3Jvd19nZXRfYnlvaWQoIGlpbmZvLCBpbnN0YW5jZSsyLCBsZW4tMiApOwp9Cgp2b2lkICoKbmV0c25tcF9pdGVyYXRvcl9yb3dfbmV4dF9ieWlkeCggbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICppbmRleGVzICkKewogICAgb2lkICAgIGR1bW15W10gPSB7MCwwfTsKICAgIG9pZCAgICBpbnN0YW5jZVtNQVhfT0lEX0xFTl07CiAgICBzaXplX3QgbGVuID0gICAgTUFYX09JRF9MRU47CgogICAgaWYgKCFpaW5mbyB8fCAhaW5kZXhlcykKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICBidWlsZF9vaWRfbm9hbGxvYyhpbnN0YW5jZSwgTUFYX09JRF9MRU4sICZsZW4sCiAgICAgICAgICAgICAgICAgICAgICBkdW1teSwgMiwgaW5kZXhlcyk7CiAgICByZXR1cm4gbmV0c25tcF9pdGVyYXRvcl9yb3dfbmV4dF9ieW9pZCggaWluZm8sIGluc3RhbmNlKzIsIGxlbi0yICk7Cn0KCnZvaWQgKgpuZXRzbm1wX2l0ZXJhdG9yX3Jvd19nZXRfYnlvaWQoICBuZXRzbm1wX2l0ZXJhdG9yX2luZm8gKmlpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvaWQgKmluc3RhbmNlLCBzaXplX3QgbGVuICkKewogICAgb2lkICAgIGR1bW15W10gPSB7MCwwfTsKICAgIG9pZCAgICB0aGlzX2luc3RbIE1BWF9PSURfTEVOXTsKICAgIHNpemVfdCB0aGlzX2xlbjsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdnAxLCAqdnAyOwogICAgdm9pZCAqY3R4MSwgKmN0eDI7CiAgICBpbnQgICBuOwoKICAgIGlmICghaWluZm8gfHwgIWlpbmZvLT5nZXRfZmlyc3RfZGF0YV9wb2ludAogICAgICAgICAgICAgICB8fCAhaWluZm8tPmdldF9uZXh0X2RhdGFfcG9pbnQgKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGlmICggIWluc3RhbmNlIHx8ICFsZW4gKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIHZwMSA9IHNubXBfY2xvbmVfdmFyYmluZChpaW5mby0+aW5kZXhlcyk7CiAgICB2cDIgPSBpaW5mby0+Z2V0X2ZpcnN0X2RhdGFfcG9pbnQoICZjdHgxLCAmY3R4MiwgdnAxLCBpaW5mbyApOwogICAgREVCVUdNU0dUTCgoInRhYmxlOml0ZXJhdG9yOmdldCIsICJmaXJzdCBEUDogJXAgJXAgJXBcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0eDEsIGN0eDIsIHZwMikpOwoKICAgIC8qIFhYWCAtIGZyZWUgY29udGV4dCA/ICovCiAgICAKICAgIHdoaWxlICggdnAyICkgewogICAgICAgIHRoaXNfbGVuID0gTUFYX09JRF9MRU47CiAgICAgICAgYnVpbGRfb2lkX25vYWxsb2ModGhpc19pbnN0LCBNQVhfT0lEX0xFTiwgJnRoaXNfbGVuLCBkdW1teSwgMiwgdnAyKTsKICAgICAgICBuID0gc25tcF9vaWRfY29tcGFyZSggaW5zdGFuY2UsIGxlbiwgdGhpc19pbnN0KzIsIHRoaXNfbGVuLTIgKTsKICAgICAgICBpZiAoIG4gPT0gMCApCiAgICAgICAgICAgIGJyZWFrOyAgLyogRm91bmQgbWF0Y2hpbmcgcm93ICovCgogICAgICAgIGlmICgoIG4gPiAwKSAmJgogICAgICAgICAgICAoaWluZm8tPmZsYWdzICYgTkVUU05NUF9JVEVSQVRPUl9GTEFHX1NPUlRFRCkpIHsKICAgICAgICAgICAgdnAyID0gTlVMTDsgIC8qIFJvdyBub3QgcHJlc2VudCAqLwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdnAyID0gaWluZm8tPmdldF9uZXh0X2RhdGFfcG9pbnQoICZjdHgxLCAmY3R4MiwgdnAyLCBpaW5mbyApOwogICAgICAgIERFQlVHTVNHVEwoKCJ0YWJsZTppdGVyYXRvcjpnZXQiLCAibmV4dCBEUDogJXAgJXAgJXBcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHgxLCBjdHgyLCB2cDIpKTsKICAgICAgICAvKiBYWFggLSBmcmVlIGNvbnRleHQgPyAqLwogICAgfQogICAgICAgICAgIAogICAgLyogWFhYIC0gZmluYWwgZnJlZSBjb250ZXh0ID8gKi8KICAgIHNubXBfZnJlZV92YXJiaW5kKCB2cDEgKTsKCiAgICByZXR1cm4gKCB2cDIgPyBjdHgyIDogTlVMTCApOwp9Cgp2b2lkICoKbmV0c25tcF9pdGVyYXRvcl9yb3dfbmV4dF9ieW9pZCggbmV0c25tcF9pdGVyYXRvcl9pbmZvICppaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2lkICppbnN0YW5jZSwgc2l6ZV90IGxlbiApCnsKICAgIG9pZCAgICBkdW1teVtdID0gezAsMH07CiAgICBvaWQgICAgdGhpc19pbnN0WyBNQVhfT0lEX0xFTl07CiAgICBzaXplX3QgdGhpc19sZW47CiAgICBvaWQgICAgYmVzdF9pbnN0WyBNQVhfT0lEX0xFTl07CiAgICBzaXplX3QgYmVzdF9sZW4gPSAwOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2cDEsICp2cDI7CiAgICB2b2lkICpjdHgxLCAqY3R4MjsKICAgIGludCAgIG47CgogICAgaWYgKCFpaW5mbyB8fCAhaWluZm8tPmdldF9maXJzdF9kYXRhX3BvaW50CiAgICAgICAgICAgICAgIHx8ICFpaW5mby0+Z2V0X25leHRfZGF0YV9wb2ludCApCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgdnAxID0gc25tcF9jbG9uZV92YXJiaW5kKGlpbmZvLT5pbmRleGVzKTsKICAgIHZwMiA9IGlpbmZvLT5nZXRfZmlyc3RfZGF0YV9wb2ludCggJmN0eDEsICZjdHgyLCB2cDEsIGlpbmZvICk7CiAgICBERUJVR01TR1RMKCgidGFibGU6aXRlcmF0b3I6Z2V0IiwgImZpcnN0IERQOiAlcCAlcCAlcFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4MSwgY3R4MiwgdnAyKSk7CgogICAgaWYgKCAhaW5zdGFuY2UgfHwgIWxlbiApIHsKICAgICAgICBzbm1wX2ZyZWVfdmFyYmluZCggdnAxICk7CiAgICAgICAgcmV0dXJuICggdnAyID8gY3R4MiA6IE5VTEwgKTsgICAvKiBGaXJzdCBlbnRyeSAqLwogICAgfQoKICAgIC8qIFhYWCAtIGZyZWUgY29udGV4dCA/ICovCiAgICAKICAgIHdoaWxlICggdnAyICkgewogICAgICAgIHRoaXNfbGVuID0gTUFYX09JRF9MRU47CiAgICAgICAgYnVpbGRfb2lkX25vYWxsb2ModGhpc19pbnN0LCBNQVhfT0lEX0xFTiwgJnRoaXNfbGVuLCBkdW1teSwgMiwgdnAyKTsKICAgICAgICBuID0gc25tcF9vaWRfY29tcGFyZSggaW5zdGFuY2UsIGxlbiwgdGhpc19pbnN0KzIsIHRoaXNfbGVuLTIgKTsKCiAgICAgICAgLyoKICAgICAgICAgKiBMb29rIGZvciB0aGUgYmVzdC1maXQgY2FuZGlkYXRlIGZvciB0aGUgbmV4dCByb3cKICAgICAgICAgKiAgIChiZWFyaW5nIGluIG1pbmQgdGhlIHJvd3MgbWF5IG5vdCBiZSBvcmRlcmVkICJjb3JyZWN0bHkiKQogICAgICAgICAqLwogICAgICAgIGlmICggbiA+IDAgKSB7CiAgICAgICAgICAgIGlmICggYmVzdF9sZW4gPT0gMCApIHsKICAgICAgICAgICAgICAgIG1lbWNweSggYmVzdF9pbnN0LCB0aGlzX2luc3QsIHNpemVvZiggdGhpc19pbnN0ICkpOwogICAgICAgICAgICAgICAgYmVzdF9sZW4gPSB0aGlzX2xlbjsKICAgICAgICAgICAgICAgIGlmIChpaW5mby0+ZmxhZ3MgJiBORVRTTk1QX0lURVJBVE9SX0ZMQUdfU09SVEVEKQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbiA9IHNubXBfb2lkX2NvbXBhcmUoIGJlc3RfaW5zdCwgYmVzdF9sZW4sIHRoaXNfaW5zdCwgdGhpc19sZW4gKTsKICAgICAgICAgICAgICAgIGlmICggbiA8IDAgKSB7CiAgICAgICAgICAgICAgICAgICAgbWVtY3B5KCBiZXN0X2luc3QsIHRoaXNfaW5zdCwgc2l6ZW9mKCB0aGlzX2luc3QgKSk7CiAgICAgICAgICAgICAgICAgICAgYmVzdF9sZW4gPSB0aGlzX2xlbjsKICAgICAgICAgICAgICAgICAgICBpZiAoaWluZm8tPmZsYWdzICYgTkVUU05NUF9JVEVSQVRPUl9GTEFHX1NPUlRFRCkKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdnAyID0gaWluZm8tPmdldF9uZXh0X2RhdGFfcG9pbnQoICZjdHgxLCAmY3R4MiwgdnAyLCBpaW5mbyApOwogICAgICAgIERFQlVHTVNHVEwoKCJ0YWJsZTppdGVyYXRvcjpnZXQiLCAibmV4dCBEUDogJXAgJXAgJXBcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdHgxLCBjdHgyLCB2cDIpKTsKICAgICAgICAvKiBYWFggLSBmcmVlIGNvbnRleHQgPyAqLwogICAgfQogICAgICAgICAgIAogICAgLyogWFhYIC0gZmluYWwgZnJlZSBjb250ZXh0ID8gKi8KICAgIHNubXBfZnJlZV92YXJiaW5kKCB2cDEgKTsKCiAgICByZXR1cm4gKCB2cDIgPyBjdHgyIDogTlVMTCApOwp9CgppbnQKbmV0c25tcF9pdGVyYXRvcl9yb3dfY291bnQoIG5ldHNubXBfaXRlcmF0b3JfaW5mbyAqaWluZm8gKQp7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZwMSwgKnZwMjsKICAgIHZvaWQgKmN0eDEsICpjdHgyOwogICAgaW50ICAgaT0wOwoKICAgIGlmICghaWluZm8gfHwgIWlpbmZvLT5nZXRfZmlyc3RfZGF0YV9wb2ludAogICAgICAgICAgICAgICB8fCAhaWluZm8tPmdldF9uZXh0X2RhdGFfcG9pbnQgKQogICAgICAgIHJldHVybiAwOwoKICAgIHZwMSA9IHNubXBfY2xvbmVfdmFyYmluZChpaW5mby0+aW5kZXhlcyk7CiAgICB2cDIgPSBpaW5mby0+Z2V0X2ZpcnN0X2RhdGFfcG9pbnQoICZjdHgxLCAmY3R4MiwgdnAxLCBpaW5mbyApOwogICAgaWYgKCF2cDIpIHsKICAgICAgICBzbm1wX2ZyZWVfdmFyYmluZCggdnAxICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICAKICAgIERFQlVHTVNHVEwoKCJ0YWJsZTppdGVyYXRvcjpjb3VudCIsICJmaXJzdCBEUDogJXAgJXAgJXBcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4MSwgY3R4MiwgdnAyKSk7CgogICAgLyogWFhYIC0gZnJlZSBjb250ZXh0ID8gKi8KCiAgICB3aGlsZSAodnAyKSB7CiAgICAgICAgaSsrOwogICAgICAgIHZwMiA9IGlpbmZvLT5nZXRfbmV4dF9kYXRhX3BvaW50KCAmY3R4MSwgJmN0eDIsIHZwMiwgaWluZm8gKTsKICAgICAgICBERUJVR01TR1RMKCgidGFibGU6aXRlcmF0b3I6Y291bnQiLCAibmV4dCBEUDogJXAgJXAgJXAgKCVkKVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4MSwgY3R4MiwgdnAyLCBpKSk7CiAgICAgICAgLyogWFhYIC0gZnJlZSBjb250ZXh0ID8gKi8KICAgIH0KICAgICAgICAgICAKICAgIC8qIFhYWCAtIGZpbmFsIGZyZWUgY29udGV4dCA/ICovCiAgICBzbm1wX2ZyZWVfdmFyYmluZCggdnAxICk7CiAgICByZXR1cm4gaTsKfQoKCi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KICoKICogSXRlcmF0b3IgQVBJOiBJbmRleCBvcGVyYXRpb25zCiAqCiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi8KCgovKiogQH0gKi8K