LyoKICogdGFibGUuYyAKICovCgovKiBQb3J0aW9ucyBvZiB0aGlzIGZpbGUgYXJlIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb3B5cmlnaHQocykuICBTZWUKICogdGhlIE5ldC1TTk1QJ3MgQ09QWUlORyBmaWxlIGZvciBtb3JlIGRldGFpbHMgYW5kIG90aGVyIGNvcHlyaWdodHMKICogdGhhdCBtYXkgYXBwbHk6CiAqLwovKgogKiBQb3J0aW9ucyBvZiB0aGlzIGZpbGUgYXJlIGNvcHlyaWdodGVkIGJ5OgogKiBDb3B5cmlnaHQgqSAyMDAzIFN1biBNaWNyb3N5c3RlbXMsIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogVXNlIGlzIHN1YmplY3QgdG8gbGljZW5zZSB0ZXJtcyBzcGVjaWZpZWQgaW4gdGhlIENPUFlJTkcgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoZSBOZXQtU05NUCBwYWNrYWdlLgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IChDKSAyMDA3IEFwcGxlLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtY29uZmlnLmg+CgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtaW5jbHVkZXMuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L25ldC1zbm1wLWFnZW50LWluY2x1ZGVzLmg+CgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvdGFibGUuaD4KCiNpZiBIQVZFX1NUUklOR19ICiNpbmNsdWRlIDxzdHJpbmcuaD4KI2Vsc2UKI2luY2x1ZGUgPHN0cmluZ3MuaD4KI2VuZGlmCgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9zbm1wX2Fzc2VydC5oPgoKc3RhdGljIHZvaWQgICAgIHRhYmxlX2hlbHBlcl9jbGVhbnVwKG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc3RhdHVzKTsKc3RhdGljIHZvaWQgICAgIHRhYmxlX2RhdGFfZnJlZV9mdW5jKHZvaWQgKmRhdGEpOwpzdGF0aWMgaW50CnNwYXJzZV90YWJsZV9oZWxwZXJfaGFuZGxlcihuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKTsKCi8qKiBAZGVmZ3JvdXAgdGFibGUgdGFibGUKICogIEhlbHBzIHlvdSBpbXBsZW1lbnQgYSB0YWJsZS4KICogIEBpbmdyb3VwIGhhbmRsZXIKICoKICogIFRoaXMgaGFuZGxlciBoZWxwcyB5b3UgaW1wbGVtZW50IGEgdGFibGUgYnkgZG9pbmcgc29tZSBvZiB0aGUKICogIHByb2Nlc3NpbmcgZm9yIHlvdS4KICogIAogKiAgVGhpcyBoYW5kbGVyIHRydWx5IHNob3dzIHRoZSBwb3dlciBvZiB0aGUgbmV3IGhhbmRsZXIgbWVjaGFuaXNtLgogKiAgQnkgY3JlYXRpbmcgYSB0YWJsZSBoYW5kbGVyIGFuZCBpbmplY3RpbmcgaXQgaW50byB5b3VyIGNhbGxpbmcKICogIGNoYWluLCBvciBieSB1c2luZyB0aGUgbmV0c25tcF9yZWdpc3Rlcl90YWJsZSgpIGZ1bmN0aW9uIHRvIHJlZ2lzdGVyIHlvdXIKICogIHRhYmxlLCB5b3UgZ2V0IGFjY2VzcyB0byBzb21lIHByZS1wYXJzZWQgaW5mb3JtYXRpb24uCiAqICBTcGVjaWZpY2FsbHksIHRoZSB0YWJsZSBoYW5kbGVyIHB1bGxzIG91dCB0aGUgY29sdW1uIG51bWJlciBhbmQKICogIGluZGV4ZXMgZnJvbSB0aGUgcmVxdWVzdCBvaWQgc28gdGhhdCB5b3UgZG9uJ3QgaGF2ZSB0byBkbyB0aGUKICogIGNvbXBsZXggd29yayB0byBkbyB0aGF0IHBhcnNpbmcgd2l0aGluIHlvdXIgb3duIGNvZGUuCiAqCiAqICBUbyBkbyB0aGlzLCB0aGUgdGFibGUgaGFuZGxlciBuZWVkcyB0byBrbm93IHVwIGZyb250IGhvdyB5b3VyCiAqICB0YWJsZSBpcyBzdHJ1Y3R1cmVkLiAgVG8gaW5mb3JtIGl0IGFib3V0IHRoaXMsIHlvdSBmaWxsIGluIGEKICogIHRhYmxlX3JlZ2lzdGVyYXRpb25faW5mbyBzdHJ1Y3R1cmUgdGhhdCBpcyBwYXNzZWQgdG8gdGhlIHRhYmxlCiAqICBoYW5kbGVyLiAgSXQgY29udGFpbnMgdGhlIGFzbiBpbmRleCB0eXBlcyBmb3IgdGhlIHRhYmxlIGFzIHdlbGwgYXMKICogIHRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIGNvbHVtbiB0aGF0IHNob3VsZCBiZSB1c2VkLgogKiAgCiAqICBAewogKi8KCi8qKiBHaXZlbiBhIG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gb2JqZWN0LCBjcmVhdGVzIGEgdGFibGUgaGFuZGxlci4KICogIFlvdSBjYW4gdXNlIHRoaXMgdGFibGUgaGFuZGxlciBieSBpbmplY3RpbmcgaXQgaW50byBhIGNhbGxpbmcKICogIGNoYWluLiAgV2hlbiB0aGUgaGFuZGxlciBnZXRzIGNhbGxlZCwgaXQnbGwgZG8gcHJvY2Vzc2luZyBhbmQKICogIHN0b3JlIGl0J3MgaW5mb3JtYXRpb24gaW50byB0aGUgcmVxdWVzdC0+cGFyZW50X2RhdGEgc3RydWN0dXJlLgogKgogKiAgVGhlIHRhYmxlIGhlbHBlciBoYW5kbGVyIHB1bGxzIG91dCB0aGUgY29sdW1uIG51bWJlciBhbmQgaW5kZXhlcyBmcm9tIAogKiAgdGhlIHJlcXVlc3Qgb2lkIHNvIHRoYXQgeW91IGRvbid0IGhhdmUgdG8gZG8gdGhlIGNvbXBsZXggd29yayBvZgogKiAgcGFyc2luZyB3aXRoaW4geW91ciBvd24gY29kZS4KICoKICogIEBwYXJhbSB0YWJyZXEgaXMgYSBwb2ludGVyIHRvIGEgbmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyBzdHJ1Y3QuCiAqCVRoZSB0YWJsZSBoYW5kbGVyIG5lZWRzIHRvIGtub3cgdXAgZnJvbnQgaG93IHlvdXIgdGFibGUgaXMgc3RydWN0dXJlZC4KICoJQSBuZXRzbm1wX3RhYmxlX3JlZ2lzdGVyYXRpb25faW5mbyBzdHJ1Y3R1cmUgdGhhdCBpcyAKICoJcGFzc2VkIHRvIHRoZSB0YWJsZSBoYW5kbGVyIHNob3VsZCBjb250YWluIHRoZSBhc24gaW5kZXggdHlwZXMgZm9yIHRoZSAKICoJdGFibGUgYXMgd2VsbCBhcyB0aGUgbWluaW11bSBhbmQgbWF4aW11bSBjb2x1bW4gdGhhdCBzaG91bGQgYmUgdXNlZC4KICoKICogIEByZXR1cm4gUmV0dXJucyBhIHBvaW50ZXIgdG8gYSBuZXRzbm1wX21pYl9oYW5kbGVyIHN0cnVjdCB3aGljaCBjb250YWlucwogKgl0aGUgaGFuZGxlcidzIG5hbWUgYW5kIHRoZSBhY2Nlc3MgbWV0aG9kCiAqCiAqLwpuZXRzbm1wX21pYl9oYW5kbGVyICoKbmV0c25tcF9nZXRfdGFibGVfaGFuZGxlcihuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvICp0YWJyZXEpCnsKICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKnJldCA9IE5VTEw7CgogICAgaWYgKCF0YWJyZXEpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfSU5GTywgIm5ldHNubXBfZ2V0X3RhYmxlX2hhbmRsZXIoTlVMTCkgY2FsbGVkXG4iKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByZXQgPSBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyKFRBQkxFX0hBTkRMRVJfTkFNRSwgdGFibGVfaGVscGVyX2hhbmRsZXIpOwogICAgaWYgKHJldCkgewogICAgICAgIHJldC0+bXl2b2lkID0gKHZvaWQgKikgdGFicmVxOwogICAgICAgIHRhYnJlcS0+bnVtYmVyX2luZGV4ZXMgPSBjb3VudF92YXJiaW5kcyh0YWJyZXEtPmluZGV4ZXMpOwogICAgfQogICAgcmV0dXJuIHJldDsKfQoKCi8qKiBjcmVhdGVzIGEgdGFibGUgaGFuZGxlciBnaXZlbiB0aGUgbmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyBvYmplY3QsCiAqICBpbnNlcnRzIGl0IGludG8gdGhlIHJlcXVlc3QgY2hhaW4gYW5kIHRoZW4gY2FsbHMKICogIG5ldHNubXBfcmVnaXN0ZXJfaGFuZGxlcigpIHRvIHJlZ2lzdGVyIHRoZSB0YWJsZSBpbnRvIHRoZSBhZ2VudC4KICovCmludApuZXRzbm1wX3JlZ2lzdGVyX3RhYmxlKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyAqdGFicmVxKQp7CiAgICBpbnQgcmMgPSBuZXRzbm1wX2luamVjdF9oYW5kbGVyKHJlZ2luZm8sIG5ldHNubXBfZ2V0X3RhYmxlX2hhbmRsZXIodGFicmVxKSk7CiAgICBpZiAoU05NUEVSUl9TVUNDRVNTICE9IHJjKQogICAgICAgIHJldHVybiByYzsKCiAgICByZXR1cm4gbmV0c25tcF9yZWdpc3Rlcl9oYW5kbGVyKHJlZ2luZm8pOwp9CgppbnQKbmV0c25tcF91bnJlZ2lzdGVyX3RhYmxlKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8pCnsKICAgIC8qIExvY2F0ZSAidGhpcyIgcmVnaW5mbyAqLwogICAgLyogU05NUF9GUkVFKHJlZ2luZm8tPm15dm9pZCk7ICovCiAgICAvKiByZWdpbmZvLT5teXZvaWQgPSBOVUxMOyAqLwogICAgcmV0dXJuIG5ldHNubXBfdW5yZWdpc3Rlcl9oYW5kbGVyKHJlZ2luZm8pOwp9CgovKiogRXh0cmFjdHMgdGhlIHByb2Nlc3NlZCB0YWJsZSBpbmZvcm1hdGlvbiBmcm9tIGEgZ2l2ZW4gcmVxdWVzdC4KICogIENhbGwgdGhpcyBmcm9tIHN1YmhhbmRsZXJzIG9uIGEgcmVxdWVzdCB0byBleHRyYWN0IHRoZSBwcm9jZXNzZWQKICogIG5ldHNubXBfcmVxdWVzdF9pbmZvIGluZm9ybWF0aW9uLiAgVGhlIHJlc3VsdGluZyBpbmZvcm1hdGlvbiBpbmNsdWRlcyB0aGUKICogIGluZGV4IHZhbHVlcyBhbmQgdGhlIGNvbHVtbiBudW1iZXIuCiAqCiAqIEBwYXJhbSByZXF1ZXN0IHBvcHVsYXRlZCBuZXRzbm1wIHJlcXVlc3Qgc3RydWN0dXJlCiAqCiAqIEByZXR1cm4gcG9wdWxhdGVkIG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvIHN0cnVjdHVyZQogKi8KTkVUU05NUF9JTkxJTkUgbmV0c25tcF90YWJsZV9yZXF1ZXN0X2luZm8gKgpuZXRzbm1wX2V4dHJhY3RfdGFibGVfaW5mbyhuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdCkKewogICAgcmV0dXJuIChuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyAqKQogICAgICAgIG5ldHNubXBfcmVxdWVzdF9nZXRfbGlzdF9kYXRhKHJlcXVlc3QsIFRBQkxFX0hBTkRMRVJfTkFNRSk7Cn0KCi8qKiBleHRyYWN0cyB0aGUgcmVnaXN0ZXJlZCBuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvIG9iamVjdCBmcm9tIGEKICogIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gb2JqZWN0ICovCm5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gKgpuZXRzbm1wX2ZpbmRfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8obmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbykKewogICAgcmV0dXJuIChuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvICopCiAgICAgICAgbmV0c25tcF9maW5kX2hhbmRsZXJfZGF0YV9ieV9uYW1lKHJlZ2luZm8sIFRBQkxFX0hBTkRMRVJfTkFNRSk7Cn0KCi8qKiBpbXBsZW1lbnRzIHRoZSB0YWJsZSBoZWxwZXIgaGFuZGxlciAqLwppbnQKdGFibGVfaGVscGVyX2hhbmRsZXIobmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cykKewoKICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0OwogICAgbmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyAqdGJsX2luZm87CiAgICBpbnQgICAgICAgICAgICAgb2lkX2luZGV4X3BvczsKICAgIHVuc2lnbmVkIGludCAgICBvaWRfY29sdW1uX3BvczsKICAgIHVuc2lnbmVkIGludCAgICB0bXBfaWR4OwogICAgc3NpemVfdCAJICAgIHRtcF9sZW47CiAgICBpbnQgICAgICAgICAgICAgaW5jb21wbGV0ZSwgb3V0X29mX3JhbmdlOwogICAgaW50ICAgICAgICAgICAgIHN0YXR1cyA9IFNOTVBfRVJSX05PRVJST1IsIG5lZWRfcHJvY2Vzc2luZyA9IDA7CiAgICBvaWQgICAgICAgICAgICAqdG1wX25hbWU7CiAgICBuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyAqdGJsX3JlcV9pbmZvOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YjsKCiAgICBpZiAoIXJlZ2luZm8gfHwgIWhhbmRsZXIpCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwoKICAgIG9pZF9pbmRleF9wb3MgID0gcmVnaW5mby0+cm9vdG9pZF9sZW4gKyAyOwogICAgb2lkX2NvbHVtbl9wb3MgPSByZWdpbmZvLT5yb290b2lkX2xlbiArIDE7CiAgICB0YmxfaW5mbyA9IChuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvICopIGhhbmRsZXItPm15dm9pZDsKCiAgICBpZiAoKCFoYW5kbGVyLT5teXZvaWQpIHx8ICghdGJsX2luZm8tPmluZGV4ZXMpKSB7CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgImltcHJvcGVybHkgcmVnaXN0ZXJlZCB0YWJsZSBmb3VuZFxuIik7CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIm5hbWU6ICVzLCB0YWJsZSBpbmZvOiAlcCwgaW5kZXhlczogJXBcbiIsCiAgICAgICAgICAgICAgICAgaGFuZGxlci0+aGFuZGxlcl9uYW1lLCBoYW5kbGVyLT5teXZvaWQsIHRibF9pbmZvLT5pbmRleGVzKTsKCiAgICAgICAgLyoKICAgICAgICAgKiBYWFgtcmtzOiB1bnJlZ2lzdGVyIHRhYmxlPyAKICAgICAgICAgKi8KICAgICAgICByZXR1cm4gU05NUF9FUlJfR0VORVJSOwogICAgfQoKICAgIERFQlVHSUYoImhlbHBlcjp0YWJsZTpyZXEiKSB7CiAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZTpyZXEiLAogICAgICAgICAgICAgICAgICAgICJHb3QgJXMgKCVkKSBtb2RlIHJlcXVlc3QgZm9yIGhhbmRsZXIgJXM6IGJhc2Ugb2lkOiIsCiAgICAgICAgICAgICAgICAgICAgc2VfZmluZF9sYWJlbF9pbl9zbGlzdCgiYWdlbnRfbW9kZSIsIHJlcWluZm8tPm1vZGUpLAogICAgICAgICAgICAgICAgICAgIHJlcWluZm8tPm1vZGUsIGhhbmRsZXItPmhhbmRsZXJfbmFtZSkpOwogICAgICAgIERFQlVHTVNHT0lEKCgiaGVscGVyOnRhYmxlOnJlcSIsIHJlZ2luZm8tPnJvb3RvaWQsCiAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPnJvb3RvaWRfbGVuKSk7CiAgICAgICAgREVCVUdNU0coKCJoZWxwZXI6dGFibGU6cmVxIiwgIlxuIikpOwogICAgfQogICAgCiAgICAvKgogICAgICogaWYgdGhlIGFnZW50IHJlcXVlc3QgaW5mbyBoYXMgYSBzdGF0ZSByZWZlcmVuY2UsIHRoZW4gdGhpcyBpcyBhIAogICAgICogbGF0ZXIgcGFzcyBvZiBhIHNldCByZXF1ZXN0IGFuZCB3ZSBjYW4gc2tpcCBhbGwgdGhlIGxvb2t1cCBzdHVmZi4KICAgICAqCiAgICAgKiB4eHgtcmtzOiB0aGlzIG1pZ2h0IGJyZWFrIGZvciBoYW5kbGVycyB3aGljaCBvbmx5IGhhbmRsZSBvbmUgdmFyYmluZAogICAgICogYXQgYSB0aW1lLi4uIHRob3NlIGhhbmRsZXJzIHNob3VsZCBub3Qgc2F2ZSBkYXRhIGJ5IHRoZWlyIGhhbmRsZXJfbmFtZQogICAgICogaW4gdGhlIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvLiAKICAgICAqLwogICAgaWYgKG5ldHNubXBfYWdlbnRfZ2V0X2xpc3RfZGF0YShyZXFpbmZvLCBoYW5kbGVyLT5uZXh0LT5oYW5kbGVyX25hbWUpKSB7CiAgICAgICAgaWYgKE1PREVfSVNfU0VUKHJlcWluZm8tPm1vZGUpKSB7CiAgICAgICAgICAgIHJldHVybiBuZXRzbm1wX2NhbGxfbmV4dF9oYW5kbGVyKGhhbmRsZXIsIHJlZ2luZm8sIHJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RzKTsKICAgICAgICB9IGVsc2UgewovKiogWFhYLXJrczogbWVtb3J5IGxlYWsuIGFkZCBjbGVhbnVwIGhhbmRsZXI/ICovCiAgICAgICAgICAgIG5ldHNubXBfZnJlZV9hZ2VudF9kYXRhX3NldHMocmVxaW5mbyk7CiAgICAgICAgfQogICAgfQoKICAgIGlmICggTU9ERV9JU19TRVQocmVxaW5mby0+bW9kZSkgJiYKICAgICAgICAgKHJlcWluZm8tPm1vZGUgIT0gTU9ERV9TRVRfUkVTRVJWRTEpKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBmb3IgbGF0ZXIgc2V0IG1vZGVzLCB3ZSBjYW4gc2tpcCBhbGwgdGhlIGluZGV4IHBhcnNpbmcsCiAgICAgICAgICogYW5kIHdlIGFsd2F5cyBuZWVkIHRvIGxldCBjaGlsZCBoYW5kbGVycyBoYXZlIGEgY2hhbmNlCiAgICAgICAgICogdG8gY2xlYW4gdXAsIGlmIHRoZXkgd2VyZSBjYWxsZWQgaW4gdGhlIGZpcnN0IHBsYWNlIChpLmUuIGhhdmUKICAgICAgICAgKiBhIHZhbGlkIHRhYmxlIGluZm8gcG9pbnRlcikuCiAgICAgICAgICovCiAgICAgICAgaWYoTlVMTCA9PSBuZXRzbm1wX2V4dHJhY3RfdGFibGVfaW5mbyhyZXF1ZXN0cykpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZSIsIm5vIHRhYmxlIGluZm8gZm9yIHNldCAtIHNraXBwaW5nXG4iKSk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICAgICAgbmVlZF9wcm9jZXNzaW5nID0gMTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIC8qCiAgICAgICAgICogZm9yIEdFVFMsIG9ubHkgY29udGludWUgaWYgd2UgaGF2ZSBhdCBsZWFzdCBvbmUgdmFsaWQgcmVxdWVzdC4KICAgICAgICAgKiBmb3IgUkVTRVJWRTEsIG9ubHkgY29udGludWUgaWYgd2UgaGF2ZSBpbmRleGVzIGZvciBhbGwgcmVxdWVzdHMuCiAgICAgICAgICovCiAgICAgICAgICAgCiAgICAvKgogICAgICogbG9vcCB0aHJvdWdoIHJlcXVlc3RzCiAgICAgKi8KCiAgICBmb3IgKHJlcXVlc3QgPSByZXF1ZXN0czsgcmVxdWVzdDsgcmVxdWVzdCA9IHJlcXVlc3QtPm5leHQpIHsKICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhciA9IHJlcXVlc3QtPnJlcXVlc3R2YjsKCiAgICAgICAgREVCVUdNU0dPSUQoKCJ2ZXJib3NlOnRhYmxlIiwgdmFyLT5uYW1lLCB2YXItPm5hbWVfbGVuZ3RoKSk7CiAgICAgICAgREVCVUdNU0coKCJ2ZXJib3NlOnRhYmxlIiwgIlxuIikpOwoKICAgICAgICBpZiAocmVxdWVzdC0+cHJvY2Vzc2VkKSB7CiAgICAgICAgICAgIERFQlVHTVNHKCgidmVyYm9zZTp0YWJsZSIsICJhbHJlYWR5IHByb2Nlc3NlZFxuIikpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgbmV0c25tcF9hc3NlcnQocmVxdWVzdC0+c3RhdHVzID09IFNOTVBfRVJSX05PRVJST1IpOwoKICAgICAgICAvKgogICAgICAgICAqIHRoaXMgc2hvdWxkIHByb2JhYmx5IGJlIGhhbmRsZWQgZnVydGhlciB1cCAKICAgICAgICAgKi8KICAgICAgICBpZiAoKHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVQpICYmICh2YXItPnR5cGUgIT0gQVNOX05VTEwpKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIHZhbGlkIHJlcXVlc3QgaWYgQVNOX05VTEwgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOnRhYmxlIiwKICAgICAgICAgICAgICAgICAgICAgICAgIiAgR0VUIHZhciB0eXBlIGlzIG5vdCBBU05fTlVMTFxuIikpOwogICAgICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9FUlJfV1JPTkdUWVBFKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKICAgICAgICBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX1NFVF9SRVNFUlZFMSkgewogICAgICAgICAgICBERUJVR0lGKCJoZWxwZXI6dGFibGU6c2V0IikgewogICAgICAgICAgICAgICAgdV9jaGFyICAgICAgICAgKmJ1ZiA9IE5VTEw7CiAgICAgICAgICAgICAgICBzaXplX3QgICAgICAgICAgYnVmX2xlbiA9IDAsIG91dF9sZW4gPSAwOwogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZTpzZXQiLCAiIFNFVF9SRVFVRVNUIGZvciBPSUQ6ICIpKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHT0lEKCgiaGVscGVyOnRhYmxlOnNldCIsIHZhci0+bmFtZSwgdmFyLT5uYW1lX2xlbmd0aCkpOwogICAgICAgICAgICAgICAgb3V0X2xlbiA9IDA7CiAgICAgICAgICAgICAgICBpZiAoc3ByaW50X3JlYWxsb2NfYnlfdHlwZSgmYnVmLCAmYnVmX2xlbiwgJm91dF9sZW4sIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIsIE5VTEwsIE5VTEwsIE5VTEwpKSB7CiAgICAgICAgICAgICAgICAgICAgREVCVUdNU0coKCJoZWxwZXI6dGFibGU6c2V0IiwiIHR5cGU9JWQoJTAyeCksIHZhbHVlPSVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXItPnR5cGUsIHZhci0+dHlwZSwgYnVmKSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmIChidWYgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICBERUJVR01TRygoImhlbHBlcjp0YWJsZTpzZXQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiB0eXBlPSVkKCUwMngpLCB2YWx1ZT0lcyBbVFJVTkNBVEVEXVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhci0+dHlwZSwgdmFyLT50eXBlLCBidWYpKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBERUJVR01TRygoImhlbHBlcjp0YWJsZTpzZXQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiB0eXBlPSVkKCUwMngpLCB2YWx1ZT1bTklMXSBbVFJVTkNBVEVEXVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhci0+dHlwZSwgdmFyLT50eXBlKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGJ1ZiAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgZnJlZShidWYpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIGNoZWNrIHRvIG1ha2Ugc3VyZSBpdHMgaW4gdGFibGUgcmFuZ2UgCiAgICAgICAgICovCgogICAgICAgIG91dF9vZl9yYW5nZSA9IDA7CiAgICAgICAgLyoKICAgICAgICAgKiBpZiBvdXIgcm9vdCBvaWQgaXMgPiB2YXItPm5hbWUgYW5kIHRoaXMgaXMgbm90IGEgR0VUTkVYVCwgCiAgICAgICAgICogdGhlbiB0aGUgb2lkIGlzIG91dCBvZiByYW5nZS4gKG9ubHkgY29tcGFyZSB1cCB0byBzaG9ydGVyIAogICAgICAgICAqIGxlbmd0aCkgCiAgICAgICAgICovCiAgICAgICAgaWYgKHJlZ2luZm8tPnJvb3RvaWRfbGVuID4gdmFyLT5uYW1lX2xlbmd0aCkKICAgICAgICAgICAgdG1wX2xlbiA9IHZhci0+bmFtZV9sZW5ndGg7CiAgICAgICAgZWxzZQogICAgICAgICAgICB0bXBfbGVuID0gcmVnaW5mby0+cm9vdG9pZF9sZW47CiAgICAgICAgaWYgKHNubXBfb2lkX2NvbXBhcmUocmVnaW5mby0+cm9vdG9pZCwgcmVnaW5mby0+cm9vdG9pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyLT5uYW1lLCB0bXBfbGVuKSA+IDApIHsKICAgICAgICAgICAgaWYgKHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRORVhUKSB7CiAgICAgICAgICAgICAgICBpZiAodmFyLT5uYW1lICE9IHZhci0+bmFtZV9sb2MpCiAgICAgICAgICAgICAgICAgICAgU05NUF9GUkVFKHZhci0+bmFtZSk7CiAgICAgICAgICAgICAgICBzbm1wX3NldF92YXJfb2JqaWQodmFyLCByZWdpbmZvLT5yb290b2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPnJvb3RvaWRfbGVuKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGUiLCAiICBvaWQgaXMgb3V0IG9mIHJhbmdlLlxuIikpOwogICAgICAgICAgICAgICAgb3V0X29mX3JhbmdlID0gMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAvKgogICAgICAgICAqIGlmIHZhci0+bmFtZSBpcyBsb25nZXIgdGhhbiB0aGUgcm9vdCwgbWFrZSBzdXJlIGl0IGlzIAogICAgICAgICAqIHRhYmxlLjEgKHRhYmxlLkVOVFJZKS4gIAogICAgICAgICAqLwogICAgICAgIGVsc2UgaWYgKCh2YXItPm5hbWVfbGVuZ3RoID4gcmVnaW5mby0+cm9vdG9pZF9sZW4pICYmCiAgICAgICAgICAgICAgICAgKHZhci0+bmFtZVtyZWdpbmZvLT5yb290b2lkX2xlbl0gIT0gMSkpIHsKICAgICAgICAgICAgaWYgKCh2YXItPm5hbWVbcmVnaW5mby0+cm9vdG9pZF9sZW5dIDwgMSkgJiYKICAgICAgICAgICAgICAgIChyZXFpbmZvLT5tb2RlID09IE1PREVfR0VUTkVYVCkpIHsKICAgICAgICAgICAgICAgIHZhci0+bmFtZVtyZWdpbmZvLT5yb290b2lkX2xlbl0gPSAxOwogICAgICAgICAgICAgICAgdmFyLT5uYW1lX2xlbmd0aCA9IHJlZ2luZm8tPnJvb3RvaWRfbGVuOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgb3V0X29mX3JhbmdlID0gMTsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGUiLCAiICBvaWQgaXMgb3V0IG9mIHJhbmdlLlxuIikpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qCiAgICAgICAgICogaWYgaXQgaXMgbm90IGluIHJhbmdlLCB0aGVuIG1hcmsgaXQgaW4gdGhlIHJlcXVlc3QgbGlzdCAKICAgICAgICAgKiBiZWNhdXNlIHdlIGNhbid0IHByb2Nlc3MgaXQsIGFuZCBzZXQgYW4gZXJyb3Igc28KICAgICAgICAgKiBub2JvZHkgZWxzZSB3YXN0ZXMgdGltZSB0cnlpbmcgdG8gcHJvY2VzcyBpdCBlaXRoZXIuICAKICAgICAgICAgKi8KICAgICAgICBpZiAob3V0X29mX3JhbmdlKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGUiLCAiICBOb3QgcHJvY2Vzc2VkOiAiKSk7CiAgICAgICAgICAgIERFQlVHTVNHT0lEKCgiaGVscGVyOnRhYmxlIiwgdmFyLT5uYW1lLCB2YXItPm5hbWVfbGVuZ3RoKSk7CiAgICAgICAgICAgIERFQlVHTVNHKCgiaGVscGVyOnRhYmxlIiwgIlxuIikpOwoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogIFJlamVjdCByZXF1ZXN0cyBvZiB0aGUgZm9ybSAnbXlUYWJsZS5OJyAgIChOICE9IDEpCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX1NFVF9SRVNFUlZFMSkKICAgICAgICAgICAgICAgIHRhYmxlX2hlbHBlcl9jbGVhbnVwKHJlcWluZm8sIHJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0VSUl9OT1RXUklUQUJMRSk7CiAgICAgICAgICAgIGVsc2UgaWYgKHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVQpCiAgICAgICAgICAgICAgICB0YWJsZV9oZWxwZXJfY2xlYW51cChyZXFpbmZvLCByZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9OT1NVQ0hPQkpFQ1QpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgoKICAgICAgICAvKgogICAgICAgICAqIENoZWNrIGNvbHVtbiByYW5nZXM7IHNldC11cCB0byBwdWxsIG91dCBpbmRleGVzIGZyb20gT0lELiAKICAgICAgICAgKi8KCiAgICAgICAgaW5jb21wbGV0ZSA9IDA7CiAgICAgICAgdGJsX3JlcV9pbmZvID0gbmV0c25tcF9leHRyYWN0X3RhYmxlX2luZm8ocmVxdWVzdCk7CiAgICAgICAgaWYgKE5VTEwgPT0gdGJsX3JlcV9pbmZvKSB7CiAgICAgICAgICAgIHRibF9yZXFfaW5mbyA9IFNOTVBfTUFMTE9DX1RZUEVERUYobmV0c25tcF90YWJsZV9yZXF1ZXN0X2luZm8pOwogICAgICAgICAgICBpZiAodGJsX3JlcV9pbmZvID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIHRhYmxlX2hlbHBlcl9jbGVhbnVwKHJlcWluZm8sIHJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0VSUl9HRU5FUlIpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdGJsX3JlcV9pbmZvLT5yZWdfaW5mbyA9IHRibF9pbmZvOwogICAgICAgICAgICB0YmxfcmVxX2luZm8tPmluZGV4ZXMgPSBzbm1wX2Nsb25lX3ZhcmJpbmQodGJsX2luZm8tPmluZGV4ZXMpOwogICAgICAgICAgICB0YmxfcmVxX2luZm8tPm51bWJlcl9pbmRleGVzID0gMDsgICAgICAgLyogbm9uZSB5ZXQgKi8KICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2FkZF9saXN0X2RhdGEocmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfZGF0YV9saXN0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChUQUJMRV9IQU5ETEVSX05BTUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCAqKSB0YmxfcmVxX2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWJsZV9kYXRhX2ZyZWVfZnVuYykpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGUiLCAiICB1c2luZyBleGlzdGluZyB0YmxfcmVxX2luZm9cbiAiKSk7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIGRvIHdlIGhhdmUgYSBjb2x1bW4/CiAgICAgICAgICovCiAgICAgICAgaWYgKHZhci0+bmFtZV9sZW5ndGggPiBvaWRfY29sdW1uX3BvcykgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBvaWQgaXMgbG9uZyBlbm91Z2ggdG8gY29udGFpbiBDT0xVTU4gaW5mbwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZTpjb2wiLAogICAgICAgICAgICAgICAgICAgICAgICAiICBoYXZlIGF0IGxlYXN0IGEgY29sdW1uICglIiBORVRTTk1QX1BSSW8gImQpXG4iLAogICAgICAgICAgICAgICAgICAgICAgICB2YXItPm5hbWVbb2lkX2NvbHVtbl9wb3NdKSk7CiAgICAgICAgICAgIGlmICh2YXItPm5hbWVbb2lkX2NvbHVtbl9wb3NdIDwgdGJsX2luZm8tPm1pbl9jb2x1bW4pIHsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGU6Y29sIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICAgYnV0IGl0J3MgbGVzcyB0aGFuIG1pbiAoJWQpXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGJsX2luZm8tPm1pbl9jb2x1bW4pKTsKICAgICAgICAgICAgICAgIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfR0VUTkVYVCkgewogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogZml4IGNvbHVtbiwgdHJ1bmNhdGUgdXNlbGVzcyBjb2x1bW4gaW5mbyAKICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICB2YXItPm5hbWVfbGVuZ3RoID0gb2lkX2NvbHVtbl9wb3M7CiAgICAgICAgICAgICAgICAgICAgdGJsX3JlcV9pbmZvLT5jb2xudW0gPSB0YmxfaW5mby0+bWluX2NvbHVtbjsKICAgICAgICAgICAgICAgIH0gZWxzZQogICAgICAgICAgICAgICAgICAgIG91dF9vZl9yYW5nZSA9IDE7CiAgICAgICAgICAgIH0gZWxzZSBpZiAodmFyLT5uYW1lW29pZF9jb2x1bW5fcG9zXSA+IHRibF9pbmZvLT5tYXhfY29sdW1uKQogICAgICAgICAgICAgICAgb3V0X29mX3JhbmdlID0gMTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgdGJsX3JlcV9pbmZvLT5jb2xudW0gPSB2YXItPm5hbWVbb2lkX2NvbHVtbl9wb3NdOwoKICAgICAgICAgICAgaWYgKG91dF9vZl9yYW5nZSkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIHRoaXMgaXMgb3V0IG9mIHJhbmdlLi4uICByZW1vdmUgZnJvbSByZXF1ZXN0cywgZnJlZQogICAgICAgICAgICAgICAgICogbWVtb3J5IAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOnRhYmxlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICAgb2lkIGlzIG91dCBvZiByYW5nZS4gTm90IHByb2Nlc3NlZDogIikpOwogICAgICAgICAgICAgICAgREVCVUdNU0dPSUQoKCJoZWxwZXI6dGFibGUiLCB2YXItPm5hbWUsIHZhci0+bmFtZV9sZW5ndGgpKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHKCgiaGVscGVyOnRhYmxlIiwgIlxuIikpOwoKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiAgUmVqZWN0IHJlcXVlc3RzIG9mIHRoZSBmb3JtICdteUVudHJ5Lk4nICAgKGludmFsaWQgTikKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYgKHJlcWluZm8tPm1vZGUgPT0gTU9ERV9TRVRfUkVTRVJWRTEpCiAgICAgICAgICAgICAgICAgICAgdGFibGVfaGVscGVyX2NsZWFudXAocmVxaW5mbywgcmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0VSUl9OT1RXUklUQUJMRSk7CiAgICAgICAgICAgICAgICBlbHNlIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfR0VUKQogICAgICAgICAgICAgICAgICAgIHRhYmxlX2hlbHBlcl9jbGVhbnVwKHJlcWluZm8sIHJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9OT1NVQ0hPQkpFQ1QpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogdXNlIGNvbHVtbiB2ZXJpZmljYXRpb24gCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBlbHNlIGlmICh0YmxfaW5mby0+dmFsaWRfY29sdW1ucykgewogICAgICAgICAgICAgICAgdGJsX3JlcV9pbmZvLT5jb2xudW0gPQogICAgICAgICAgICAgICAgICAgIG5ldHNubXBfY2xvc2VzdF9jb2x1bW4odmFyLT5uYW1lW29pZF9jb2x1bW5fcG9zXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRibF9pbmZvLT52YWxpZF9jb2x1bW5zKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGU6Y29sIiwgIiAgICBjbG9zZXN0IGNvbHVtbiBpcyAlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRibF9yZXFfaW5mby0+Y29sbnVtKSk7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogeHh4LXJrczogZG9jdW1lbnQgd2h5IHRoZSBjb250aW51ZS4uLgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAodGJsX3JlcV9pbmZvLT5jb2xudW0gPT0gMCkKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIGlmICh0YmxfcmVxX2luZm8tPmNvbG51bSAhPSB2YXItPm5hbWVbb2lkX2NvbHVtbl9wb3NdKSB7CiAgICAgICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZTpjb2wiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICAgd2hpY2ggZG9lc24ndCBtYXRjaCByZXEgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIlIiBORVRTTk1QX1BSSW8gImQgLSB0cnVuY2F0aW5nIGluZGV4IGluZm9cbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyLT5uYW1lW29pZF9jb2x1bW5fcG9zXSkpOwogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogZGlmZmVyZW50IGNvbHVtbiEgdHJ1bmNhdGUgdXNlbGVzcyBpbmRleCBpbmZvIAogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIHZhci0+bmFtZV9sZW5ndGggPSBvaWRfY29sdW1uX3BvcyArIDE7IC8qIHBvcyBpcyAwIGJhc2VkICovCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogdmFyLT5uYW1lX2xlbmd0aCBtYXkgaGF2ZSBjaGFuZ2VkIC0gY2hlY2sgYWdhaW4gCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoKGludCl2YXItPm5hbWVfbGVuZ3RoIDw9IG9pZF9pbmRleF9wb3MpIHsgLyogcG9zIGlzIDAgYmFzZWQgKi8KICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGUiLCAiICAgIG5vdCBlbm91Z2ggZm9yIGluZGV4ZXNcbiIpKTsKICAgICAgICAgICAgICAgIHRibF9yZXFfaW5mby0+aW5kZXhfb2lkX2xlbiA9IDA7IC8qKiBub25lIGF2YWlsYWJsZSAqLwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIG9pZCBpcyBsb25nIGVub3VnaCB0byBjb250YWluIElOREVYIGluZm8KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgdGJsX3JlcV9pbmZvLT5pbmRleF9vaWRfbGVuID0KICAgICAgICAgICAgICAgICAgICB2YXItPm5hbWVfbGVuZ3RoIC0gb2lkX2luZGV4X3BvczsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGUiLCAiICAgIGhhdmUgJWx1IGJ5dGVzIG9mIGluZGV4XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVuc2lnbmVkIGxvbmcpdGJsX3JlcV9pbmZvLT5pbmRleF9vaWRfbGVuKSk7CiAgICAgICAgICAgICAgICBuZXRzbm1wX2Fzc2VydCh0YmxfcmVxX2luZm8tPmluZGV4X29pZF9sZW4gPCBNQVhfT0lEX0xFTik7CiAgICAgICAgICAgICAgICBtZW1jcHkodGJsX3JlcV9pbmZvLT5pbmRleF9vaWQsICZ2YXItPm5hbWVbb2lkX2luZGV4X3Bvc10sCiAgICAgICAgICAgICAgICAgICAgICAgdGJsX3JlcV9pbmZvLT5pbmRleF9vaWRfbGVuICogc2l6ZW9mKG9pZCkpOwogICAgICAgICAgICAgICAgdG1wX25hbWUgPSB0YmxfcmVxX2luZm8tPmluZGV4X29pZDsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVE5FWFQgfHwKICAgICAgICAgICAgICAgICAgIHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRCVUxLKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIG9pZCBpcyBOT1QgbG9uZyBlbm91Z2ggdG8gY29udGFpbiBjb2x1bW4gb3IgaW5kZXggaW5mbywgc28gc3RhcnQKICAgICAgICAgICAgICogYXQgdGhlIG1pbmltdW0gY29sdW1uLiBTZXQgaW5kZXggb2lkIGxlbiB0byAwIGJlY2F1c2Ugd2UgZG9uJ3QKICAgICAgICAgICAgICogaGF2ZSBhbnkgaW5kZXggaW5mbyBpbiB0aGUgT0lELgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZSIsICIgIG5vIGNvbHVtbi9pbmRleCBpbiByZXF1ZXN0XG4iKSk7CiAgICAgICAgICAgIHRibF9yZXFfaW5mby0+aW5kZXhfb2lkX2xlbiA9IDA7CiAgICAgICAgICAgIHRibF9yZXFfaW5mby0+Y29sbnVtID0gdGJsX2luZm8tPm1pbl9jb2x1bW47CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogb2lkIGlzIE5PVCBsb25nIGVub3VnaCB0byBjb250YWluIGluZGV4IGluZm8sCiAgICAgICAgICAgICAqIHNvIHdlIGNhbid0IGRvIGFueXRoaW5nIHdpdGggaXQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIFJlamVjdCByZXF1ZXN0cyBvZiB0aGUgZm9ybSAnbXlUYWJsZScgb3IgJ215RW50cnknCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVCApIHsKICAgICAgICAgICAgICAgIHRhYmxlX2hlbHBlcl9jbGVhbnVwKHJlcWluZm8sIHJlcXVlc3QsIFNOTVBfTk9TVUNIT0JKRUNUKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfU0VUX1JFU0VSVkUxICkgewogICAgICAgICAgICAgICAgdGFibGVfaGVscGVyX2NsZWFudXAocmVxaW5mbywgcmVxdWVzdCwgU05NUF9FUlJfTk9UV1JJVEFCTEUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBzZXQgdXAgdG1wX2xlbiB0byBiZSB0aGUgbnVtYmVyIG9mIE9JRHMgd2UgaGF2ZSBiZXlvbmQgdGhlIGNvbHVtbjsKICAgICAgICAgKiB0aGVzZSBzaG91bGQgYmUgdGhlIGluZGV4KHMpIGZvciB0aGUgdGFibGUuIElmIHRoZSBpbmRleF9vaWRfbGVuCiAgICAgICAgICogaXMgMCwgc2V0IHRtcF9sZW4gdG8gLTEgc28gdGhhdCB3aGVuIHdlIHRyeSB0byBwYXJzZSB0aGUgaW5kZXggYmVsb3csCiAgICAgICAgICogd2UganVzdCB6ZXJvIGZpbGwgZXZlcnl0aGluZy4KICAgICAgICAgKi8KICAgICAgICBpZiAodGJsX3JlcV9pbmZvLT5pbmRleF9vaWRfbGVuID09IDApIHsKICAgICAgICAgICAgaW5jb21wbGV0ZSA9IDE7CiAgICAgICAgICAgIHRtcF9sZW4gPSAtMTsKICAgICAgICB9IGVsc2UKICAgICAgICAgICAgdG1wX2xlbiA9IHRibF9yZXFfaW5mby0+aW5kZXhfb2lkX2xlbjsKCgogICAgICAgIC8qCiAgICAgICAgICogZm9yIGVhY2ggaW5kZXggdHlwZSwgdHJ5IHRvIGV4dHJhY3QgdGhlIGluZGV4IGZyb20gdmFyLT5uYW1lCiAgICAgICAgICovCiAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZSIsICIgIGxvb2tpbmcgZm9yICVkIGluZGV4ZXNcbiIsCiAgICAgICAgICAgICAgICAgICAgdGJsX2luZm8tPm51bWJlcl9pbmRleGVzKSk7CiAgICAgICAgZm9yICh0bXBfaWR4ID0gMCwgdmIgPSB0YmxfcmVxX2luZm8tPmluZGV4ZXM7CiAgICAgICAgICAgICB0bXBfaWR4IDwgdGJsX2luZm8tPm51bWJlcl9pbmRleGVzOwogICAgICAgICAgICAgKyt0bXBfaWR4LCB2YiA9IHZiLT5uZXh0X3ZhcmlhYmxlKSB7CiAgICAgICAgICAgIHNpemVfdCBwYXJzZWRfb2lkX2xlbjsKCiAgICAgICAgICAgIGlmIChpbmNvbXBsZXRlICYmIHRtcF9sZW4pIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBpbmNvbXBsZXRlL2lsbGVnYWwgT0lELCBzZXQgdXAgZHVtbXkgMCB0byBwYXJzZSAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICBvaWQgaW5kZXhlcyBub3QgY29tcGxldGU6ICIpKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHT0lEKCgiaGVscGVyOnRhYmxlIiwgdmFyLT5uYW1lLCB2YXItPm5hbWVfbGVuZ3RoKSk7CiAgICAgICAgICAgICAgICBERUJVR01TRygoImhlbHBlcjp0YWJsZSIsICJcbiIpKTsKCiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogbm8gc2Vuc2UgaW4gdHJ5aW5nIGFueW1vcmUgaWYgdGhpcyBpcyBhIEdFVC9TRVQuIAogICAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgICAqIFJlamVjdCByZXF1ZXN0cyBvZiB0aGUgZm9ybSAnbXlPYmplY3QnICAgKG5vIGluc3RhbmNlKQogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICB0bXBfbGVuID0gMDsKICAgICAgICAgICAgICAgIHRtcF9uYW1lID0gTlVMTDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIHRyeSBhbmQgcGFyc2UgY3VycmVudCBpbmRleCAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIG5ldHNubXBfYXNzZXJ0KHRtcF9sZW4gPj0gMCk7CiAgICAgICAgICAgIHBhcnNlZF9vaWRfbGVuID0gdG1wX2xlbjsKICAgICAgICAgICAgaWYgKHBhcnNlX29uZV9vaWRfaW5kZXgoJnRtcF9uYW1lLCAmcGFyc2VkX29pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZiLCAxKSAhPSBTTk1QRVJSX1NVQ0NFU1MpIHsKICAgICAgICAgICAgICAgIGluY29tcGxldGUgPSAxOwogICAgICAgICAgICAgICAgdG1wX2xlbiA9IC0xOyAgIC8qIGlzIHRoaXMgbmVjZXNzYXJ5PyBCZXR0ZXIgc2FmZSB0aGFuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogc29ycnkgKi8KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRtcF9sZW4gPSBwYXJzZWRfb2lkX2xlbjsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGUiLCAiICBnb3QgMSAoaW5jb21wbGV0ZT0lZClcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmNvbXBsZXRlKSk7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogZG8gbm90IGNvdW50IGluY29tcGxldGUgaW5kZXhlcyAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYgKGluY29tcGxldGUpCiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICArK3RibF9yZXFfaW5mby0+bnVtYmVyX2luZGV4ZXM7IC8qKiBnb3Qgb25lIG9rICovCiAgICAgICAgICAgICAgICBpZiAodG1wX2xlbiA8PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgaW5jb21wbGV0ZSA9IDE7CiAgICAgICAgICAgICAgICAgICAgdG1wX2xlbiA9IC0xOyAgICAgICAvKiBpcyB0aGlzIG5lY2Vzc2FyeT8gQmV0dGVyIHNhZmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIHRoYW4gc29ycnkgKi8KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgIC8qKiBmb3IgbG9vcCAqLwoKICAgICAgICBERUJVR0lGKCJoZWxwZXI6dGFibGU6cmVzdWx0cyIpIHsKICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCAgICBjb3VudDsKICAgICAgICAgICAgICAgIHVfY2hhciAgICAgICAgICpidWYgPSBOVUxMOwogICAgICAgICAgICAgICAgc2l6ZV90ICAgICAgICAgIGJ1Zl9sZW4gPSAwLCBvdXRfbGVuID0gMDsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGU6cmVzdWx0cyIsICIgIGZvdW5kICVkIGluZGV4ZXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YmxfcmVxX2luZm8tPm51bWJlcl9pbmRleGVzKSk7CiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOnRhYmxlOnJlc3VsdHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgY29sdW1uOiAlZCwgaW5kZXhlczogJWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGJsX3JlcV9pbmZvLT5jb2xudW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YmxfcmVxX2luZm8tPm51bWJlcl9pbmRleGVzKSk7CiAgICAgICAgICAgICAgICBmb3IgKHZiID0gdGJsX3JlcV9pbmZvLT5pbmRleGVzLCBjb3VudCA9IDA7CiAgICAgICAgICAgICAgICAgICAgIHZiICYmIGNvdW50IDwgdGJsX3JlcV9pbmZvLT5udW1iZXJfaW5kZXhlczsKICAgICAgICAgICAgICAgICAgICAgY291bnQrKywgdmIgPSB2Yi0+bmV4dF92YXJpYWJsZSkgewogICAgICAgICAgICAgICAgICAgIG91dF9sZW4gPSAwOwogICAgICAgICAgICAgICAgICAgIGlmIChzcHJpbnRfcmVhbGxvY19ieV90eXBlKCZidWYsICZidWZfbGVuLCAmb3V0X2xlbiwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YiwgTlVMTCwgTlVMTCwgTlVMTCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgREVCVUdNU0coKCJoZWxwZXI6dGFibGU6cmVzdWx0cyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAgaW5kZXg6IHR5cGU9JWQoJTAyeCksIHZhbHVlPSVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZiLT50eXBlLCB2Yi0+dHlwZSwgYnVmKSk7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGJ1ZiAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBERUJVR01TRygoImhlbHBlcjp0YWJsZTpyZXN1bHRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAgaW5kZXg6IHR5cGU9JWQoJTAyeCksIHZhbHVlPSVzIFtUUlVOQ0FURURdIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2Yi0+dHlwZSwgdmItPnR5cGUsIGJ1ZikpOwogICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgREVCVUdNU0coKCJoZWxwZXI6dGFibGU6cmVzdWx0cyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgIGluZGV4OiB0eXBlPSVkKCUwMngpLCB2YWx1ZT1bTklMXSBbVFJVTkNBVEVEXSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmItPnR5cGUsIHZiLT50eXBlKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoYnVmICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBmcmVlKGJ1Zik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBERUJVR01TRygoImhlbHBlcjp0YWJsZTpyZXN1bHRzIiwgIlxuIikpOwogICAgICAgIH0KCgogICAgICAgIC8qCiAgICAgICAgICogZG8gd2UgaGF2ZSBzdWZmaWNpZW50IGluZGV4IGluZm8gdG8gY29udGludWU/CiAgICAgICAgICovCgogICAgICAgIGlmICgocmVxaW5mby0+bW9kZSAhPSBNT0RFX0dFVE5FWFQpICYmCiAgICAgICAgICAgICgodGJsX3JlcV9pbmZvLT5udW1iZXJfaW5kZXhlcyAhPSB0YmxfaW5mby0+bnVtYmVyX2luZGV4ZXMpIHx8CiAgICAgICAgICAgICAodG1wX2xlbiAhPSAtMSkpKSB7CgogICAgICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOnRhYmxlIiwKICAgICAgICAgICAgICAgICAgICAgICAgImludmFsaWQgaW5kZXgoZXMpIGZvciB0YWJsZSAtIHNraXBwaW5nXG4iKSk7CgogICAgICAgICAgICBpZiAoIE1PREVfSVNfU0VUKHJlcWluZm8tPm1vZGUpICkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIG5vIHBvaW50IGluIGNvbnRpbnVpbmcgd2l0aG91dCBpbmRleGVzIGZvciBzZXQuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIG5ldHNubXBfYXNzZXJ0KHJlcWluZm8tPm1vZGUgPT0gTU9ERV9TRVRfUkVTRVJWRTEpOwogICAgICAgICAgICAgICAgLyoqIGNsZWFyIGZpcnN0IHJlcXVlc3Qgc28gd2Ugd29udCB0cnkgdG8gcnVuIEZSRUUgbW9kZSAqLwogICAgICAgICAgICAgICAgbmV0c25tcF9mcmVlX3JlcXVlc3RfZGF0YV9zZXRzKHJlcXVlc3RzKTsKICAgICAgICAgICAgICAgIC8qKiBzZXQgYWN0dWFsIGVycm9yICovCiAgICAgICAgICAgICAgICB0YWJsZV9oZWxwZXJfY2xlYW51cChyZXFpbmZvLCByZXF1ZXN0LCBTTk1QX0VSUl9OT0NSRUFUSU9OKTsKICAgICAgICAgICAgICAgIG5lZWRfcHJvY2Vzc2luZyA9IDA7IC8qIGRvbid0IGNhbGwgbmV4dCBoYW5kbGVyICovCiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICB0YWJsZV9oZWxwZXJfY2xlYW51cChyZXFpbmZvLCByZXF1ZXN0LCBTTk1QX05PU1VDSElOU1RBTkNFKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIG5ldHNubXBfYXNzZXJ0KHJlcXVlc3QtPnN0YXR1cyA9PSBTTk1QX0VSUl9OT0VSUk9SKTsKICAgICAgICAKICAgICAgICArK25lZWRfcHJvY2Vzc2luZzsKCiAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZm9yIGVhY2ggcmVxdWVzdCAqLwogICAgfQoKICAgIC8qCiAgICAgKiBiYWlsIGlmIHRoZXJlIGlzIG5vdGhpbmcgZm9yIG91ciBjaGlsZCBoYW5kbGVycwogICAgICovCiAgICBpZiAoMCA9PSBuZWVkX3Byb2Nlc3NpbmcpCiAgICAgICAgcmV0dXJuIHN0YXR1czsKCiAgICAvKgogICAgICogY2FsbCBvdXIgY2hpbGQgYWNjZXNzIGZ1bmN0aW9uIAogICAgICovCiAgICBzdGF0dXMgPQogICAgICAgIG5ldHNubXBfY2FsbF9uZXh0X2hhbmRsZXIoaGFuZGxlciwgcmVnaW5mbywgcmVxaW5mbywgcmVxdWVzdHMpOwoKICAgIC8qCiAgICAgKiBjaGVjayBmb3Igc3BhcnNlIHRhYmxlcwogICAgICovCiAgICBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVE5FWFQpCiAgICAgICAgc3BhcnNlX3RhYmxlX2hlbHBlcl9oYW5kbGVyKCBoYW5kbGVyLCByZWdpbmZvLCByZXFpbmZvLCByZXF1ZXN0cyApOwoKICAgIHJldHVybiBzdGF0dXM7Cn0KCiNkZWZpbmUgU1BBUlNFX1RBQkxFX0hBTkRMRVJfTkFNRSAic3BhcnNlX3RhYmxlIgoKLyoqIGltcGxlbWVudHMgdGhlIHNwYXJzZSB0YWJsZSBoZWxwZXIgaGFuZGxlcgogKiBAaW50ZXJuYWwKICoKICogQG5vdGUKICogVGhpcyBmdW5jdGlvbiBpcyBzdGF0aWMgdG8gcHJldmVudCBvdGhlcnMgZnJvbSBjYWxsaW5nIGl0CiAqIGRpcmVjdGx5LiBJdCBpdCBhdXRvbWF0aWNhbGx5IGNhbGxlZCBieSB0aGUgdGFibGUgaGVscGVyLAogKiAKICovCnN0YXRpYyBpbnQKc3BhcnNlX3RhYmxlX2hlbHBlcl9oYW5kbGVyKG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMpCnsKICAgIGludCAgICAgICAgICAgICBzdGF0dXMgPSBTTk1QX0VSUl9OT0VSUk9SOwogICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3Q7CiAgICBvaWQgICAgICAgICAgICAgY29sb2lkW01BWF9PSURfTEVOXTsKICAgIG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvICp0YWJsZV9pbmZvOwoKICAgIC8qCiAgICAgKiBzaW5jZSB3ZSBkb24ndCBjYWxsIGNoaWxkIGhhbmRsZXJzLCB3YXJuIGlmIG9uZSB3YXMgcmVnaXN0ZXJlZAogICAgICogYmVuZWF0aCB1cy4gQSBzcGVjaWFsIGV4Y2VwdGlvbiBmb3IgdGhlIHRhYmxlIGhlbHBlciwgd2hpY2ggY2FsbHMKICAgICAqIHRoZSBoYW5kbGVyIGRpcmVjdGx5LiBVc2UgaGFuZGxlIGN1c3RvbSBmbGFnIHRvIG9ubHkgbG9nIG9uY2UuCiAgICAgKi8KICAgIGlmKCh0YWJsZV9oZWxwZXJfaGFuZGxlciAhPSBoYW5kbGVyLT5hY2Nlc3NfbWV0aG9kKSAmJgogICAgICAgKE5VTEwgIT0gaGFuZGxlci0+bmV4dCkpIHsKICAgICAgICAvKgogICAgICAgICAqIGFsd2F5cyB3YXJuIGlmIGNhbGxlZCB3aXRob3V0IG91ciBvd24gaGFuZGxlci4gSWYgd2UKICAgICAgICAgKiBoYXZlIG91ciBvd24gaGFuZGxlciwgdXNlIGN1c3RvbSBiaXQgMSB0byBvbmx5IGxvZyBvbmNlLgogICAgICAgICAqLwogICAgICAgIGlmKChzcGFyc2VfdGFibGVfaGVscGVyX2hhbmRsZXIgIT0gaGFuZGxlci0+YWNjZXNzX21ldGhvZCkgfHwKICAgICAgICAgICAhKGhhbmRsZXItPmZsYWdzICYgTUlCX0hBTkRMRVJfQ1VTVE9NMSkpIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsICJoYW5kbGVyICglcykgcmVnaXN0ZXJlZCBhZnRlciBzcGFyc2UgdGFibGUgIgogICAgICAgICAgICAgICAgICAgICAiaGFuZGVyIHdpbGwgbm90IGJlIGNhbGxlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgaGFuZGxlci0+bmV4dC0+aGFuZGxlcl9uYW1lID8KICAgICAgICAgICAgICAgICAgICAgaGFuZGxlci0+bmV4dC0+aGFuZGxlcl9uYW1lIDogIiIgKTsKICAgICAgICAgICAgaWYoc3BhcnNlX3RhYmxlX2hlbHBlcl9oYW5kbGVyID09IGhhbmRsZXItPmFjY2Vzc19tZXRob2QpCiAgICAgICAgICAgICAgICBoYW5kbGVyLT5mbGFncyB8PSBNSUJfSEFORExFUl9DVVNUT00xOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVE5FWFQpIHsKICAgICAgICBmb3IocmVxdWVzdCA9IHJlcXVlc3RzIDsgcmVxdWVzdDsgcmVxdWVzdCA9IHJlcXVlc3QtPm5leHQpIHsKICAgICAgICAgICAgaWYgKChyZXF1ZXN0LT5yZXF1ZXN0dmItPnR5cGUgPT0gQVNOX05VTEwgJiYgcmVxdWVzdC0+cHJvY2Vzc2VkKSB8fAogICAgICAgICAgICAgICAgcmVxdWVzdC0+ZGVsZWdhdGVkKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIGlmIChyZXF1ZXN0LT5yZXF1ZXN0dmItPnR5cGUgPT0gU05NUF9OT1NVQ0hJTlNUQU5DRSkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGdldCBuZXh0IHNraXBwZWQgdGhpcyB2YWx1ZSBmb3IgdGhpcyBjb2x1bW4sIHdlCiAgICAgICAgICAgICAgICAgKiBuZWVkIHRvIGtlZXAgc2VhcmNoaW5nIGZvcndhcmQgCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIERFQlVHTVNHVCgoInNwYXJzZSIsICJyZXRyeSBmb3IgTk9TVUNISU5TVEFOQ0VcbiIpKTsKICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJlcXVlc3R2Yi0+dHlwZSA9IEFTTl9QUklWX1JFVFJZOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChyZXF1ZXN0LT5yZXF1ZXN0dmItPnR5cGUgPT0gU05NUF9OT1NVQ0hPQkpFQ1QgfHwKICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJlcXVlc3R2Yi0+dHlwZSA9PSBTTk1QX0VORE9GTUlCVklFVykgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGdldCBuZXh0IGhhcyBjb21wbGV0ZWx5IGZpbmlzaGVkIHdpdGggdGhpcyBjb2x1bW4sCiAgICAgICAgICAgICAgICAgKiBzbyB3ZSBuZWVkIHRvIHRyeSB3aXRoIHRoZSBuZXh0IGNvbHVtbiAoaWYgYW55KQogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBERUJVR01TR1QoKCJzcGFyc2UiLCAicmV0cnkgZm9yIE5PU1VDSE9CSkVDVFxuIikpOwogICAgICAgICAgICAgICAgdGFibGVfaW5mbyA9IG5ldHNubXBfZXh0cmFjdF90YWJsZV9pbmZvKHJlcXVlc3QpOwogICAgICAgICAgICAgICAgdGFibGVfaW5mby0+Y29sbnVtID0gbmV0c25tcF90YWJsZV9uZXh0X2NvbHVtbih0YWJsZV9pbmZvKTsKICAgICAgICAgICAgICAgIGlmICgwICE9IHRhYmxlX2luZm8tPmNvbG51bSkgewogICAgICAgICAgICAgICAgICAgIG1lbWNweShjb2xvaWQsIHJlZ2luZm8tPnJvb3RvaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPnJvb3RvaWRfbGVuICogc2l6ZW9mKG9pZCkpOwogICAgICAgICAgICAgICAgICAgIGNvbG9pZFtyZWdpbmZvLT5yb290b2lkX2xlbl0gICA9IDE7ICAgLyogdGFibGUuZW50cnkgbm9kZSAqLwogICAgICAgICAgICAgICAgICAgIGNvbG9pZFtyZWdpbmZvLT5yb290b2lkX2xlbisxXSA9IHRhYmxlX2luZm8tPmNvbG51bTsKICAgICAgICAgICAgICAgICAgICBzbm1wX3NldF92YXJfb2JqaWQocmVxdWVzdC0+cmVxdWVzdHZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvaWQsIHJlZ2luZm8tPnJvb3RvaWRfbGVuICsgMik7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiLT50eXBlID0gQVNOX1BSSVZfUkVUUlk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIElmIHdlIGRvbid0IGhhdmUgY29sdW1uIGluZm8sIHJlc2V0IHRvIG51bGwgc28KICAgICAgICAgICAgICAgICAgICAgKiB0aGUgYWdlbnQgd2lsbCBtb3ZlIG9uIHRvIHRoZSBuZXh0IHRhYmxlLgogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJlcXVlc3R2Yi0+dHlwZSA9IEFTTl9OVUxMOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIHN0YXR1czsKfQoKLyoqIGNyZWF0ZSBzcGFyc2UgdGFibGUgaGFuZGxlcgogKi8KbmV0c25tcF9taWJfaGFuZGxlciAqCm5ldHNubXBfc3BhcnNlX3RhYmxlX2hhbmRsZXJfZ2V0KHZvaWQpCnsKICAgIHJldHVybiBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyKFNQQVJTRV9UQUJMRV9IQU5ETEVSX05BTUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGFyc2VfdGFibGVfaGVscGVyX2hhbmRsZXIpOwp9CgovKiogY3JlYXRlcyBhIHRhYmxlIGhhbmRsZXIgZ2l2ZW4gdGhlIG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gb2JqZWN0LAogKiAgaW5zZXJ0cyBpdCBpbnRvIHRoZSByZXF1ZXN0IGNoYWluIGFuZCB0aGVuIGNhbGxzCiAqICBuZXRzbm1wX3JlZ2lzdGVyX2hhbmRsZXIoKSB0byByZWdpc3RlciB0aGUgdGFibGUgaW50byB0aGUgYWdlbnQuCiAqLwppbnQKbmV0c25tcF9zcGFyc2VfdGFibGVfcmVnaXN0ZXIobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvICp0YWJyZXEpCnsKICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIxLCAqaGFuZGxlcjI7CiAgICBpbnQgcmM7CgogICAgaGFuZGxlcjEgPSBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyKFNQQVJTRV9UQUJMRV9IQU5ETEVSX05BTUUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGFyc2VfdGFibGVfaGVscGVyX2hhbmRsZXIpOwogICAgaWYgKE5VTEwgPT0gaGFuZGxlcjEpCiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKCiAgICBoYW5kbGVyMiA9IG5ldHNubXBfZ2V0X3RhYmxlX2hhbmRsZXIodGFicmVxKTsKICAgIGlmIChOVUxMID09IGhhbmRsZXIyICkgewogICAgICAgIG5ldHNubXBfaGFuZGxlcl9mcmVlKGhhbmRsZXIxKTsKICAgICAgICByZXR1cm4gU05NUF9FUlJfR0VORVJSOwogICAgfQoKICAgIHJjID0gbmV0c25tcF9pbmplY3RfaGFuZGxlcihyZWdpbmZvLCBoYW5kbGVyMSk7CiAgICBpZiAoU05NUEVSUl9TVUNDRVNTICE9IHJjKSB7CiAgICAgICAgbmV0c25tcF9oYW5kbGVyX2ZyZWUoaGFuZGxlcjEpOwogICAgICAgIG5ldHNubXBfaGFuZGxlcl9mcmVlKGhhbmRsZXIyKTsKICAgICAgICByZXR1cm4gcmM7CiAgICB9CgogICAgcmMgPSBuZXRzbm1wX2luamVjdF9oYW5kbGVyKHJlZ2luZm8sIGhhbmRsZXIyKTsKICAgIGlmIChTTk1QRVJSX1NVQ0NFU1MgIT0gcmMpIHsKICAgICAgICAvKiogaGFuZGxlcjEgaXMgaW4gcmVnaW5mby4uLiByZW1vdmUgYW5kIGZyZWU/PyAqLwogICAgICAgIG5ldHNubXBfaGFuZGxlcl9mcmVlKGhhbmRsZXIyKTsKICAgICAgICByZXR1cm4gcmM7CiAgICB9CgogICAgLyoqIGJvdGggaGFuZGxlcnMgbm93IGluIHJlZ2luZm8sIHNvIG5vdGhpbmcgdG8gZG8gb24gZXJyb3IgKi8KICAgIHJldHVybiBuZXRzbm1wX3JlZ2lzdGVyX2hhbmRsZXIocmVnaW5mbyk7Cn0KCgovKiogQnVpbGRzIHRoZSByZXN1bHQgdG8gYmUgcmV0dXJuZWQgdG8gdGhlIGFnZW50IGdpdmVuIHRoZSB0YWJsZSBpbmZvcm1hdGlvbi4KICogIFVzZSB0aGlzIGZ1bmN0aW9uIHRvIHJldHVybiByZXN1bHRzIGZyb20gbG93ZWwgbGV2ZWwgaGFuZGxlcnMgdG8KICogIHRoZSBhZ2VudC4gIEl0IHRha2VzIGNhcmUgb2YgYnVpbGRpbmcgdGhlIHByb3BlciByZXN1bHRpbmcgb2lkCiAqICAoY29udGFpbmluZyBwcm9wZXIgaW5kZXhpbmcpIGFuZCBpbnNlcnRzIHRoZSByZXN1bHQgdmFsdWUgaW50byB0aGUKICogIHJldHVybmluZyB2YXJiaW5kLgogKi8KaW50Cm5ldHNubXBfdGFibGVfYnVpbGRfcmVzdWx0KG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyAqdGFibGVfaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgdV9jaGFyIHR5cGUsIHVfY2hhciAqIHJlc3VsdCwgc2l6ZV90IHJlc3VsdF9sZW4pCnsKCiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcjsKCiAgICBpZiAoIXJlcWluZm8gfHwgIXRhYmxlX2luZm8pCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwoKICAgIHZhciA9IHJlcWluZm8tPnJlcXVlc3R2YjsKCiAgICBpZiAodmFyLT5uYW1lICE9IHZhci0+bmFtZV9sb2MpCiAgICAgICAgZnJlZSh2YXItPm5hbWUpOwogICAgdmFyLT5uYW1lID0gTlVMTDsKCiAgICBpZiAobmV0c25tcF90YWJsZV9idWlsZF9vaWQocmVnaW5mbywgcmVxaW5mbywgdGFibGVfaW5mbykgIT0KICAgICAgICBTTk1QRVJSX1NVQ0NFU1MpCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwoKICAgIHNubXBfc2V0X3Zhcl90eXBlZF92YWx1ZSh2YXIsIHR5cGUsIHJlc3VsdCwgcmVzdWx0X2xlbik7CgogICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKfQoKCi8qKiBnaXZlbiBhIHJlZ2lzdHJhdGlvbiBpbmZvIG9iamVjdCwgYSByZXF1ZXN0IG9iamVjdCBhbmQgdGhlIHRhYmxlCiAqICBpbmZvIG9iamVjdCBpdCBidWlsZHMgdGhlIHJlcXVlc3QtPnJlcXVlc3R2Yi0+bmFtZSBvaWQgZnJvbSB0aGUKICogIGluZGV4IHZhbHVlcyBhbmQgY29sdW1uIGluZm9ybWF0aW9uIGZvdW5kIGluIHRoZSB0YWJsZV9pbmZvCiAqICBvYmplY3QuIEluZGV4IHZhbHVlcyBhcmUgZXh0cmFjdGVkIGZyb20gdGhlIHRhYmxlX2luZm8gdmFyYmluZHMuCiAqLwppbnQKbmV0c25tcF90YWJsZV9idWlsZF9vaWQobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvICp0YWJsZV9pbmZvKQp7CiAgICBvaWQgICAgICAgICAgICAgdG1wb2lkW01BWF9PSURfTEVOXTsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFyOwoKICAgIGlmICghcmVnaW5mbyB8fCAhcmVxaW5mbyB8fCAhdGFibGVfaW5mbykKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CgogICAgLyoKICAgICAqIHh4eC1ya3M6IGluZWZmaWNlbnQuIHdlIGRvIGEgY29weSBoZXJlLCB0aGVuIGJ1aWxkX29pZCBkb2VzIGl0CiAgICAgKiAgICAgICAgICBhZ2Fpbi4gZWl0aGVyIGNvbWUgdXAgd2l0aCBhIG5ldyB1dGlsaXR5IHJvdXRpbmUsIG9yCiAgICAgKiAgICAgICAgICBkbyBzb21lIGhpamlua3MgaGVyZSB0byBlbGltaW5hdGUgZXh0cmEgY29weS4KICAgICAqICAgICAgICAgIFByb2JhYmx5IGNvdWxkIG1ha2Ugc3VyZSBhbGwgY2FsbGVycyBoYXZlIHRoZQogICAgICogICAgICAgICAgaW5kZXggJiB2YXJpYWJsZSBsaXN0IHVwZGF0ZWQsIGFuZCB1c2UKICAgICAqICAgICAgICAgIG5ldHNubXBfdGFibGVfYnVpbGRfb2lkX2Zyb21faW5kZXgoKSBpbnN0ZWFkIG9mIGFsbCB0aGlzLgogICAgICovCiAgICBtZW1jcHkodG1wb2lkLCByZWdpbmZvLT5yb290b2lkLCByZWdpbmZvLT5yb290b2lkX2xlbiAqIHNpemVvZihvaWQpKTsKICAgIHRtcG9pZFtyZWdpbmZvLT5yb290b2lkX2xlbl0gPSAxOyAgIC8qKiAuRW50cnkgKi8KICAgIHRtcG9pZFtyZWdpbmZvLT5yb290b2lkX2xlbiArIDFdID0gdGFibGVfaW5mby0+Y29sbnVtOyAvKiogLmNvbHVtbiAqLwoKICAgIHZhciA9IHJlcWluZm8tPnJlcXVlc3R2YjsKICAgIGlmIChidWlsZF9vaWQoJnZhci0+bmFtZSwgJnZhci0+bmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgIHRtcG9pZCwgcmVnaW5mby0+cm9vdG9pZF9sZW4gKyAyLCB0YWJsZV9pbmZvLT5pbmRleGVzKQogICAgICAgICE9IFNOTVBFUlJfU1VDQ0VTUykKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CgogICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKfQoKLyoqIGdpdmVuIGEgcmVnaXN0cmF0aW9uIGluZm8gb2JqZWN0LCBhIHJlcXVlc3Qgb2JqZWN0IGFuZCB0aGUgdGFibGUKICogIGluZm8gb2JqZWN0IGl0IGJ1aWxkcyB0aGUgcmVxdWVzdC0+cmVxdWVzdHZiLT5uYW1lIG9pZCBmcm9tIHRoZQogKiAgaW5kZXggdmFsdWVzIGFuZCBjb2x1bW4gaW5mb3JtYXRpb24gZm91bmQgaW4gdGhlIHRhYmxlX2luZm8KICogIG9iamVjdC4gIEluZGV4IHZhbHVlcyBhcmUgZXh0cmFjdGVkIGZyb20gdGhlIHRhYmxlX2luZm8gaW5kZXggb2lkLgogKi8KaW50Cm5ldHNubXBfdGFibGVfYnVpbGRfb2lkX2Zyb21faW5kZXgobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyAqdGFibGVfaW5mbykKewogICAgb2lkICAgICAgICAgICAgIHRtcG9pZFtNQVhfT0lEX0xFTl07CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcjsKICAgIGludCAgICAgICAgICAgICBsZW47CgogICAgaWYgKCFyZWdpbmZvIHx8ICFyZXFpbmZvIHx8ICF0YWJsZV9pbmZvKQogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKCiAgICB2YXIgPSByZXFpbmZvLT5yZXF1ZXN0dmI7CiAgICBsZW4gPSByZWdpbmZvLT5yb290b2lkX2xlbjsKICAgIG1lbWNweSh0bXBvaWQsIHJlZ2luZm8tPnJvb3RvaWQsIGxlbiAqIHNpemVvZihvaWQpKTsKICAgIHRtcG9pZFtsZW4rK10gPSAxOyAgICAgICAgICAvKiAuRW50cnkgKi8KICAgIHRtcG9pZFtsZW4rK10gPSB0YWJsZV9pbmZvLT5jb2xudW07IC8qIC5jb2x1bW4gKi8KICAgIG1lbWNweSgmdG1wb2lkW2xlbl0sIHRhYmxlX2luZm8tPmluZGV4X29pZCwKICAgICAgICAgICB0YWJsZV9pbmZvLT5pbmRleF9vaWRfbGVuICogc2l6ZW9mKG9pZCkpOwogICAgbGVuICs9IHRhYmxlX2luZm8tPmluZGV4X29pZF9sZW47CiAgICBzbm1wX3NldF92YXJfb2JqaWQoIHZhciwgdG1wb2lkLCBsZW4gKTsKCiAgICByZXR1cm4gU05NUEVSUl9TVUNDRVNTOwp9CgovKiogcGFyc2VzIGFuIE9JRCBpbnRvIHRhYmxlIGluZGV4c2VzICovCmludApuZXRzbm1wX3VwZGF0ZV92YXJpYWJsZV9saXN0X2Zyb21faW5kZXgobmV0c25tcF90YWJsZV9yZXF1ZXN0X2luZm8gKnRyaSkKewogICAgaWYgKCF0cmkpCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwoKICAgIC8qCiAgICAgKiBmcmVlIGFueSBleGlzdGluZyBhbGxvY2F0ZWQgbWVtb3J5LCB0aGVuIHBhcnNlIG9pZCBpbnRvIHZhcmJpbmRzCiAgICAgKi8KICAgIHNubXBfcmVzZXRfdmFyX2J1ZmZlcnMoIHRyaS0+aW5kZXhlcyk7CgogICAgcmV0dXJuIHBhcnNlX29pZF9pbmRleGVzKHRyaS0+aW5kZXhfb2lkLCB0cmktPmluZGV4X29pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJpLT5pbmRleGVzKTsKfQoKLyoqIGJ1aWxkcyBhbiBvaWQgZ2l2ZW4gYSBzZXQgb2YgaW5kZXhlcy4gKi8KaW50Cm5ldHNubXBfdXBkYXRlX2luZGV4ZXNfZnJvbV92YXJpYWJsZV9saXN0KG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvICp0cmkpCnsKICAgIGlmICghdHJpKQogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKCiAgICByZXR1cm4gYnVpbGRfb2lkX25vYWxsb2ModHJpLT5pbmRleF9vaWQsIHNpemVvZih0cmktPmluZGV4X29pZCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnRyaS0+aW5kZXhfb2lkX2xlbiwgTlVMTCwgMCwgdHJpLT5pbmRleGVzKTsKfQoKLyoqCiAqIGNoZWNrcyB0aGUgb3JpZ2luYWwgcmVxdWVzdCBhZ2FpbnN0IHRoZSBjdXJyZW50IGRhdGEgYmVpbmcgcGFzc2VkIGluIGlmIAogKiBpdHMgZ3JlYXRlciB0aGFuIHRoZSByZXF1ZXN0IG9pZCBidXQgbGVzcyB0aGFuIHRoZSBjdXJyZW50IHZhbGlkCiAqIHJldHVybiwgc2V0IHRoZSBjdXJyZW50IHZhbGlkIHJldHVybiB0byB0aGUgbmV3IHZhbHVlLgogKiAKICogcmV0dXJucyAxIGlmIG91dHZhciB3YXMgcmVwbGFjZWQgd2l0aCB0aGUgb2lkIGZyb20gbmV3dmFyIChzdWNjZXNzKS4KICogcmV0dXJucyAwIGlmIG5vdC4gCiAqLwppbnQKbmV0c25tcF9jaGVja19nZXRuZXh0X3JlcGx5KG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgb2lkICogcHJlZml4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHByZWZpeF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKiBuZXd2YXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKiogb3V0dmFyKQp7CiAgICBvaWQgICAgICBteW5hbWVbTUFYX09JRF9MRU5dOwogICAgc2l6ZV90ICAgbXluYW1lX2xlbjsKCiAgICBidWlsZF9vaWRfbm9hbGxvYyhteW5hbWUsIE1BWF9PSURfTEVOLCAmbXluYW1lX2xlbiwKICAgICAgICAgICAgICAgICAgICAgIHByZWZpeCwgcHJlZml4X2xlbiwgbmV3dmFyKTsKICAgIC8qCiAgICAgKiBpcyB0aGUgYnVpbGQgb2YgdGhlIG5ldyBpbmRleGVzIGxlc3MgdGhhbiBvdXIgY3VycmVudCByZXN1bHQgCiAgICAgKi8KICAgIGlmICgoISgqb3V0dmFyKSB8fCBzbm1wX29pZF9jb21wYXJlKG15bmFtZSArIHByZWZpeF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBteW5hbWVfbGVuIC0gcHJlZml4X2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqb3V0dmFyKS0+bmFtZSArIHByZWZpeF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKm91dHZhciktPm5hbWVfbGVuZ3RoIC0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWZpeF9sZW4pIDwgMCkpIHsKICAgICAgICAvKgogICAgICAgICAqIGFuZCBncmVhdGVyIHRoYW4gdGhlIHJlcXVlc3RlZCBvaWQgCiAgICAgICAgICovCiAgICAgICAgaWYgKHNubXBfb2lkX2NvbXBhcmUobXluYW1lLCBteW5hbWVfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJlcXVlc3R2Yi0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yZXF1ZXN0dmItPm5hbWVfbGVuZ3RoKSA+IDApIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogdGhlIG5ldyByZXN1bHQgbXVzdCBiZSBiZXR0ZXIgdGhhbiB0aGUgb2xkIAogICAgICAgICAgICAgKi8KI2lmZGVmIE9OTFlfV09SS1NfV0lUSF9PTkVfVkFSQklORAogICAgICAgICAgICBpZiAoISpvdXR2YXIpCiAgICAgICAgICAgICAgICAqb3V0dmFyID0gc25tcF9jbG9uZV92YXJiaW5kKG5ld3Zhcik7CgkgICAgZWxzZQogICAgICAgICAgICAgICAgLyogCiAgICAgICAgICAgICAgICAgKiBUT0RPOiB3YWxrIHRoZSBmdWxsIHZhcmJpbmQgbGlzdCwgc2V0dGluZwogICAgICAgICAgICAgICAgICogICAgICAgKmFsbCogdGhlIHZhbHVlcyAtIG5vdCBqdXN0IHRoZSBmaXJzdC4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgc25tcF9zZXRfdmFyX3R5cGVkX3ZhbHVlKCpvdXR2YXIsIG5ld3Zhci0+dHlwZSwKCQkJCW5ld3Zhci0+dmFsLnN0cmluZywgbmV3dmFyLT52YWxfbGVuKTsKI2Vsc2UgIC8qIEludGVyaW0gcmVwbGFjZW1lbnQgYXBwcm9hY2ggLSBsZXNzIGVmZmljaWVudCwgYnV0IGl0IHdvcmtzISAqLwogICAgICAgICAgICBpZiAoKm91dHZhcikKICAgICAgICAgICAgICAgIHNubXBfZnJlZV92YXJiaW5kKCpvdXR2YXIpOwogICAgICAgICAgICAqb3V0dmFyID0gc25tcF9jbG9uZV92YXJiaW5kKG5ld3Zhcik7CiNlbmRpZgogICAgICAgICAgICBzbm1wX3NldF92YXJfb2JqaWQoKm91dHZhciwgbXluYW1lLCBteW5hbWVfbGVuKTsKCiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiAwOwp9Cgp2b2lkCm5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm9fZnJlZShuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvICp0cmkpCnsKICAgIGlmIChOVUxMID09IHRyaSkKICAgICAgICByZXR1cm47CgogICAgaWYgKE5VTEwgIT0gdHJpLT5pbmRleGVzKQogICAgICAgIHNubXBfZnJlZV92YXJiaW5kKHRyaS0+aW5kZXhlcyk7CgojaWYgMAogICAgLyoKICAgICAqIHNpZ2guLi4gZXhhbXBsZSB1c2Ugb2YgdmFsaWRfY29sdW1ucyBwb2ludHMgdG8gc3RhdGljIG1lbW9yeSwKICAgICAqIHNvIGZyZWVpbmcgaXQgd291bGQgYmUgYmFkLi4uIHdlJ2xsIGp1c3QgaGF2ZSB0byBsaXZlIHdpdGggYW55CiAgICAgKiBsZWFrcywgZm9yIG5vdy4uLgogICAgICovCiNlbmRpZgoKICAgIGZyZWUodHJpKTsKfQoKLyoqIEB9ICovCgovKgogKiBpbnRlcm5hbCByb3V0aW5lcyAKICovCnZvaWQKdGFibGVfZGF0YV9mcmVlX2Z1bmModm9pZCAqZGF0YSkKewogICAgbmV0c25tcF90YWJsZV9yZXF1ZXN0X2luZm8gKmluZm8gPSAobmV0c25tcF90YWJsZV9yZXF1ZXN0X2luZm8gKikgZGF0YTsKICAgIGlmICghaW5mbykKICAgICAgICByZXR1cm47CiAgICBzbm1wX2ZyZWVfdmFyYmluZChpbmZvLT5pbmRleGVzKTsKICAgIGZyZWUoaW5mbyk7Cn0KCgoKc3RhdGljIHZvaWQKdGFibGVfaGVscGVyX2NsZWFudXAobmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0LCBpbnQgc3RhdHVzKQp7CiAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3QsIHN0YXR1cyk7CiAgICBuZXRzbm1wX2ZyZWVfcmVxdWVzdF9kYXRhX3NldHMocmVxdWVzdCk7CiAgICBpZiAoIXJlcXVlc3QpCiAgICAgICAgcmV0dXJuOwogICAgcmVxdWVzdC0+cGFyZW50X2RhdGEgPSBOVUxMOwp9CgoKLyoKICogZmluZCB0aGUgY2xvc2VzdCBjb2x1bW4gdG8gY3VycmVudCAod2hpY2ggbWF5IGJlIGN1cnJlbnQpLgogKgogKiBjYWxsZWQgd2hlbiBhIHRhYmxlIHJ1bnMgb3V0IG9mIHJvd3MgZm9yIGNvbHVtbiBYLiBUaGlzCiAqIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aXRoIGN1cnJlbnQgPSBYICsgMSwgdG8gdmVyaWZ5IHRoYXQKICogWCArIDEgaXMgYSB2YWxpZCBjb2x1bW4sIG9yIGZpbmQgdGhlIG5leHQgY2xvc2VzdCBjb2x1bW4gaWYgbm90LgogKgogKiBBbGwgbGlzdCB0eXBlcyBzaG91bGQgYmUgc29ydGVkLCBsb3dlc3QgdG8gaGlnaGVzdC4KICovCnVuc2lnbmVkIGludApuZXRzbm1wX2Nsb3Nlc3RfY29sdW1uKHVuc2lnbmVkIGludCBjdXJyZW50LAogICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfY29sdW1uX2luZm8gKnZhbGlkX2NvbHVtbnMpCnsKICAgIHVuc2lnbmVkIGludCAgICBjbG9zZXN0ID0gMDsKICAgIGludCAgICAgICAgICAgICBpZHg7CgogICAgaWYgKHZhbGlkX2NvbHVtbnMgPT0gTlVMTCkKICAgICAgICByZXR1cm4gMDsKCiAgICBmb3IoIDsgdmFsaWRfY29sdW1uczsgdmFsaWRfY29sdW1ucyA9IHZhbGlkX2NvbHVtbnMtPm5leHQpIHsKCiAgICAgICAgaWYgKHZhbGlkX2NvbHVtbnMtPmlzUmFuZ2UpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogaWYgY3VycmVudCA8IGxvdyByYW5nZSwgaXQgbWlnaHQgYmUgY2xvc2VzdC4KICAgICAgICAgICAgICogb3RoZXJ3aXNlLCBpZiBpdCdzIDwgaGlnaCByYW5nZSwgY3VycmVudCBpcyBpbgogICAgICAgICAgICAgKiB0aGUgcmFuZ2UsIGFuZCB0aHVzIGlzIGFuIGV4YWN0IG1hdGNoLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKGN1cnJlbnQgPCB2YWxpZF9jb2x1bW5zLT5kZXRhaWxzLnJhbmdlWzBdKSB7CiAgICAgICAgICAgICAgICBpZiAoICh2YWxpZF9jb2x1bW5zLT5kZXRhaWxzLnJhbmdlWzBdIDwgY2xvc2VzdCkgfHwKICAgICAgICAgICAgICAgICAgICAgKDAgPT0gY2xvc2VzdCkpIHsKICAgICAgICAgICAgICAgICAgICBjbG9zZXN0ID0gdmFsaWRfY29sdW1ucy0+ZGV0YWlscy5yYW5nZVswXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmIChjdXJyZW50IDw9IHZhbGlkX2NvbHVtbnMtPmRldGFpbHMucmFuZ2VbMV0pIHsKICAgICAgICAgICAgICAgIGNsb3Nlc3QgPSBjdXJyZW50OwogICAgICAgICAgICAgICAgYnJlYWs7ICAgICAgIC8qIGNhbiBub3QgZ2V0IGFueSBjbG9zZXIhICovCiAgICAgICAgICAgIH0KCiAgICAgICAgfSAvKiByYW5nZSAqLwogICAgICAgIGVsc2UgeyAgICAgICAgICAgICAgICAgIC8qIGxpc3QgKi8KICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogaWYgY3VycmVudCA8IGZpcnN0IGl0ZW0sIG5vIG5lZWQgdG8gaXRlcmF0ZSBvdmVyIGxpc3QuCiAgICAgICAgICAgICAqIHRoYXQgaXRlbSBpcyBlaXRoZXIgY2xvc2VzdCwgb3Igbm90LgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKGN1cnJlbnQgPCB2YWxpZF9jb2x1bW5zLT5kZXRhaWxzLmxpc3RbMF0pIHsKICAgICAgICAgICAgICAgIGlmICgodmFsaWRfY29sdW1ucy0+ZGV0YWlscy5saXN0WzBdIDwgY2xvc2VzdCkgfHwKICAgICAgICAgICAgICAgICAgICAoMCA9PSBjbG9zZXN0KSkKICAgICAgICAgICAgICAgICAgICBjbG9zZXN0ID0gdmFsaWRfY29sdW1ucy0+ZGV0YWlscy5saXN0WzBdOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qKiBpZiBjdXJyZW50ID4gbGFzdCBpdGVtIGluIGxpc3QsIG5vIG5lZWQgdG8gaXRlcmF0ZSAqLwogICAgICAgICAgICBpZiAoY3VycmVudCA+CiAgICAgICAgICAgICAgICB2YWxpZF9jb2x1bW5zLT5kZXRhaWxzLmxpc3RbKGludCl2YWxpZF9jb2x1bW5zLT5saXN0X2NvdW50IC0gMV0pCiAgICAgICAgICAgICAgICBjb250aW51ZTsgICAgICAgLyogbm90IGluIGxpc3QgcmFuZ2UuICovCgogICAgICAgICAgICAvKiogc2tpcCBhbnl0aGluZyBsZXNzIHRoYW4gY3VycmVudCovCiAgICAgICAgICAgIGZvciAoaWR4ID0gMDsgdmFsaWRfY29sdW1ucy0+ZGV0YWlscy5saXN0W2lkeF0gPCBjdXJyZW50OyArK2lkeCkKICAgICAgICAgICAgICAgIDsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8qKiBjaGVjayBmb3IgZXhhY3QgbWF0Y2ggKi8KICAgICAgICAgICAgaWYgKGN1cnJlbnQgPT0gdmFsaWRfY29sdW1ucy0+ZGV0YWlscy5saXN0W2lkeF0pIHsKICAgICAgICAgICAgICAgIGNsb3Nlc3QgPSBjdXJyZW50OwogICAgICAgICAgICAgICAgYnJlYWs7ICAgICAgLyogY2FuIG5vdCBnZXQgYW55IGNsb3NlciEgKi8KICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgLyoqIGxpc3RbaWR4XSA+IGN1cnJlbnQ7IGlzIGl0IDwgY2xvc2VzdD8gKi8KICAgICAgICAgICAgaWYgKCh2YWxpZF9jb2x1bW5zLT5kZXRhaWxzLmxpc3RbaWR4XSA8IGNsb3Nlc3QpIHx8CiAgICAgICAgICAgICAgICAoMCA9PSBjbG9zZXN0KSkKICAgICAgICAgICAgICAgIGNsb3Nlc3QgPSB2YWxpZF9jb2x1bW5zLT5kZXRhaWxzLmxpc3RbaWR4XTsKCiAgICAgICAgfSAgICAgICAgICAgICAgICAgICAgICAgLyogbGlzdCAqLwogICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGZvciAqLwoKICAgIHJldHVybiBjbG9zZXN0Owp9CgovKioKICogVGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBzZXR1cCB0aGUgdGFibGUncyBkZWZpbml0aW9uIHdpdGhpbgogKiB5b3VyIG1vZHVsZSdzIGluaXRpYWxpemUgZnVuY3Rpb24sIGl0IHRha2VzIGEgdmFyaWFibGUgaW5kZXggcGFyYW1ldGVyIGxpc3QKICogZm9yIGV4YW1wbGU6IHRoZSB0YWJsZV9pbmZvIHN0cnVjdHVyZSBpcyBmb2xsb3dlZCBieSB0d28gaW50ZWdlciBpbmRleCB0eXBlcwogKiBuZXRzbm1wX3RhYmxlX2hlbHBlcl9hZGRfaW5kZXhlcygKICogICAgICAgICAgICAgICAgICB0YWJsZV9pbmZvLCAgIAogKgkgICAgICAgICAgICBBU05fSU5URUdFUiwgIAogKgkJICAgIEFTTl9JTlRFR0VSLCAgCiAqCQkgICAgMCk7CiAqCiAqIEBwYXJhbSB0aW5mbyBpcyBhIHBvaW50ZXIgdG8gYSBuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvIHN0cnVjdC4KICoJVGhlIHRhYmxlIGhhbmRsZXIgbmVlZHMgdG8ga25vdyB1cCBmcm9udCBob3cgeW91ciB0YWJsZSBpcyBzdHJ1Y3R1cmVkLgogKglBIG5ldHNubXBfdGFibGVfcmVnaXN0ZXJhdGlvbl9pbmZvIHN0cnVjdHVyZSB0aGF0IGlzIAogKglwYXNzZWQgdG8gdGhlIHRhYmxlIGhhbmRsZXIgc2hvdWxkIGNvbnRhaW4gdGhlIGFzbiBpbmRleCB0eXBlcyBmb3IgdGhlIAogKgl0YWJsZSBhcyB3ZWxsIGFzIHRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIGNvbHVtbiB0aGF0IHNob3VsZCBiZSB1c2VkLgogKgogKiBAcmV0dXJuIHZvaWQKICoKICovCnZvaWQKbmV0c25tcF90YWJsZV9oZWxwZXJfYWRkX2luZGV4ZXMobmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyAqdGluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLikKewogICAgdmFfbGlzdCAgICAgICAgIGRlYnVnYXJnczsKICAgIGludCAgICAgICAgICAgICB0eXBlOwoKICAgIHZhX3N0YXJ0KGRlYnVnYXJncywgdGluZm8pOwogICAgd2hpbGUgKCh0eXBlID0gdmFfYXJnKGRlYnVnYXJncywgaW50KSkgIT0gMCkgewogICAgICAgIG5ldHNubXBfdGFibGVfaGVscGVyX2FkZF9pbmRleCh0aW5mbywgdHlwZSk7CiAgICB9CiAgICB2YV9lbmQoZGVidWdhcmdzKTsKfQoKc3RhdGljIHZvaWQKX3Jvd19zdGFzaF9kYXRhX2xpc3RfZnJlZSh2b2lkICpwdHIpIHsKICAgIG5ldHNubXBfb2lkX3N0YXNoX25vZGUgKip0bXAgPSAobmV0c25tcF9vaWRfc3Rhc2hfbm9kZSAqKilwdHI7CiAgICBuZXRzbm1wX29pZF9zdGFzaF9mcmVlKHRtcCwgTlVMTCk7CiAgICBmcmVlKHB0cik7Cn0KCi8qKiByZXR1cm5zIGEgcm93LXdpZGUgcGxhY2UgdG8gc3RvcmUgZGF0YSBpbi4KICAgIEB0b2RvIFRoaXMgZnVuY3Rpb24gd2lsbCBsaWtlbHkgY2hhbmdlIHRvIGFkZCBmcmVlIHBvaW50ZXIgZnVuY3Rpb25zLiAqLwpuZXRzbm1wX29pZF9zdGFzaF9ub2RlICoqCm5ldHNubXBfdGFibGVfZ2V0X29yX2NyZWF0ZV9yb3dfc3Rhc2gobmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdV9jaGFyICogc3RvcmFnZV9uYW1lKQp7CiAgICBuZXRzbm1wX29pZF9zdGFzaF9ub2RlICoqc3Rhc2hwID0gTlVMTDsKICAgIHN0YXNocCA9IChuZXRzbm1wX29pZF9zdGFzaF9ub2RlICoqKQogICAgICAgIG5ldHNubXBfYWdlbnRfZ2V0X2xpc3RfZGF0YShyZXFpbmZvLCAoY29uc3QgY2hhciAqKSBzdG9yYWdlX25hbWUpOwoKICAgIGlmICghc3Rhc2hwKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBoYXNuJ3QgYmUgY3JlYXRlZCB5ZXQuICB3ZSBjcmVhdGUgaXQgaGVyZS4gCiAgICAgICAgICovCiAgICAgICAgc3Rhc2hwID0gU05NUF9NQUxMT0NfVFlQRURFRihuZXRzbm1wX29pZF9zdGFzaF9ub2RlICopOwoKICAgICAgICBpZiAoIXN0YXNocCkKICAgICAgICAgICAgcmV0dXJuIE5VTEw7ICAgICAgICAvKiBhY2suIG91dCBvZiBtZW0gKi8KCiAgICAgICAgbmV0c25tcF9hZ2VudF9hZGRfbGlzdF9kYXRhKHJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX2RhdGFfbGlzdCgoY29uc3QgY2hhciAqKSBzdG9yYWdlX25hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFzaHAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfcm93X3N0YXNoX2RhdGFfbGlzdF9mcmVlKSk7CiAgICB9CiAgICByZXR1cm4gc3Rhc2hwOwp9CgovKgogKiBhZHZhbmNlIHRoZSB0YWJsZSBpbmZvIGNvbG51bSB0byB0aGUgbmV4dCBjb2x1bW4sIG9yIDAgaWYgdGhlcmUgYXJlIG5vIG1vcmUKICoKICogQHJldHVybiBuZXcgY29sdW1uLCBvciAwIGlmIHRoZXJlIGFyZSBubyBtb3JlCiAqLwp1bnNpZ25lZCBpbnQKbmV0c25tcF90YWJsZV9uZXh0X2NvbHVtbihuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyAqdGFibGVfaW5mbykKewogICAgaWYgKE5VTEwgPT0gdGFibGVfaW5mbykKICAgICAgICByZXR1cm4gMDsKCiAgICAvKgogICAgICogdHJ5IGFuZCB2YWxpZGF0ZSBuZXh0IGNvbHVtbgogICAgICovCiAgICBpZiAodGFibGVfaW5mby0+cmVnX2luZm8tPnZhbGlkX2NvbHVtbnMpCiAgICAgICAgcmV0dXJuIG5ldHNubXBfY2xvc2VzdF9jb2x1bW4odGFibGVfaW5mby0+Y29sbnVtICsgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWJsZV9pbmZvLT5yZWdfaW5mby0+dmFsaWRfY29sdW1ucyk7CiAgICAKICAgIC8qCiAgICAgKiBjYW4ndCB2YWxpZGF0ZS4gYXNzdW1lIDEuLm1heF9jb2x1bW4gYXJlIHZhbGlkCiAgICAgKi8KICAgIGlmICh0YWJsZV9pbmZvLT5jb2xudW0gPCB0YWJsZV9pbmZvLT5yZWdfaW5mby0+bWF4X2NvbHVtbikKICAgICAgICByZXR1cm4gdGFibGVfaW5mby0+Y29sbnVtICsgMTsKICAgIAogICAgcmV0dXJuIDA7IC8qIG91dCBvZiByYW5nZSAqLwp9Cg==