LyoKICogdGFibGUuYyAKICovCgovKiBQb3J0aW9ucyBvZiB0aGlzIGZpbGUgYXJlIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb3B5cmlnaHQocykuICBTZWUKICogdGhlIE5ldC1TTk1QJ3MgQ09QWUlORyBmaWxlIGZvciBtb3JlIGRldGFpbHMgYW5kIG90aGVyIGNvcHlyaWdodHMKICogdGhhdCBtYXkgYXBwbHk6CiAqLwovKgogKiBQb3J0aW9ucyBvZiB0aGlzIGZpbGUgYXJlIGNvcHlyaWdodGVkIGJ5OgogKiBDb3B5cmlnaHQgqSAyMDAzIFN1biBNaWNyb3N5c3RlbXMsIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogVXNlIGlzIHN1YmplY3QgdG8gbGljZW5zZSB0ZXJtcyBzcGVjaWZpZWQgaW4gdGhlIENPUFlJTkcgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoZSBOZXQtU05NUCBwYWNrYWdlLgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IChDKSAyMDA3IEFwcGxlLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtY29uZmlnLmg+CgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtaW5jbHVkZXMuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L25ldC1zbm1wLWFnZW50LWluY2x1ZGVzLmg+CgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvdGFibGUuaD4KCiNpZiBIQVZFX1NUUklOR19ICiNpbmNsdWRlIDxzdHJpbmcuaD4KI2Vsc2UKI2luY2x1ZGUgPHN0cmluZ3MuaD4KI2VuZGlmCgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9zbm1wX2Fzc2VydC5oPgoKc3RhdGljIHZvaWQgICAgIHRhYmxlX2hlbHBlcl9jbGVhbnVwKG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc3RhdHVzKTsKc3RhdGljIHZvaWQgICAgIHRhYmxlX2RhdGFfZnJlZV9mdW5jKHZvaWQgKmRhdGEpOwpzdGF0aWMgaW50CnNwYXJzZV90YWJsZV9oZWxwZXJfaGFuZGxlcihuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKTsKCi8qKiBAZGVmZ3JvdXAgdGFibGUgdGFibGUKICogIEhlbHBzIHlvdSBpbXBsZW1lbnQgYSB0YWJsZS4KICogIEBpbmdyb3VwIGhhbmRsZXIKICoKICogIFRoaXMgaGFuZGxlciBoZWxwcyB5b3UgaW1wbGVtZW50IGEgdGFibGUgYnkgZG9pbmcgc29tZSBvZiB0aGUKICogIHByb2Nlc3NpbmcgZm9yIHlvdS4KICogIAogKiAgVGhpcyBoYW5kbGVyIHRydWx5IHNob3dzIHRoZSBwb3dlciBvZiB0aGUgbmV3IGhhbmRsZXIgbWVjaGFuaXNtLgogKiAgQnkgY3JlYXRpbmcgYSB0YWJsZSBoYW5kbGVyIGFuZCBpbmplY3RpbmcgaXQgaW50byB5b3VyIGNhbGxpbmcKICogIGNoYWluLCBvciBieSB1c2luZyB0aGUgbmV0c25tcF9yZWdpc3Rlcl90YWJsZSgpIGZ1bmN0aW9uIHRvIHJlZ2lzdGVyIHlvdXIKICogIHRhYmxlLCB5b3UgZ2V0IGFjY2VzcyB0byBzb21lIHByZS1wYXJzZWQgaW5mb3JtYXRpb24uCiAqICBTcGVjaWZpY2FsbHksIHRoZSB0YWJsZSBoYW5kbGVyIHB1bGxzIG91dCB0aGUgY29sdW1uIG51bWJlciBhbmQKICogIGluZGV4ZXMgZnJvbSB0aGUgcmVxdWVzdCBvaWQgc28gdGhhdCB5b3UgZG9uJ3QgaGF2ZSB0byBkbyB0aGUKICogIGNvbXBsZXggd29yayB0byBkbyB0aGF0IHBhcnNpbmcgd2l0aGluIHlvdXIgb3duIGNvZGUuCiAqCiAqICBUbyBkbyB0aGlzLCB0aGUgdGFibGUgaGFuZGxlciBuZWVkcyB0byBrbm93IHVwIGZyb250IGhvdyB5b3VyCiAqICB0YWJsZSBpcyBzdHJ1Y3R1cmVkLiAgVG8gaW5mb3JtIGl0IGFib3V0IHRoaXMsIHlvdSBmaWxsIGluIGEKICogIHRhYmxlX3JlZ2lzdGVyYXRpb25faW5mbyBzdHJ1Y3R1cmUgdGhhdCBpcyBwYXNzZWQgdG8gdGhlIHRhYmxlCiAqICBoYW5kbGVyLiAgSXQgY29udGFpbnMgdGhlIGFzbiBpbmRleCB0eXBlcyBmb3IgdGhlIHRhYmxlIGFzIHdlbGwgYXMKICogIHRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIGNvbHVtbiB0aGF0IHNob3VsZCBiZSB1c2VkLgogKiAgCiAqICBAewogKi8KCi8qKiBHaXZlbiBhIG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gb2JqZWN0LCBjcmVhdGVzIGEgdGFibGUgaGFuZGxlci4KICogIFlvdSBjYW4gdXNlIHRoaXMgdGFibGUgaGFuZGxlciBieSBpbmplY3RpbmcgaXQgaW50byBhIGNhbGxpbmcKICogIGNoYWluLiAgV2hlbiB0aGUgaGFuZGxlciBnZXRzIGNhbGxlZCwgaXQnbGwgZG8gcHJvY2Vzc2luZyBhbmQKICogIHN0b3JlIGl0J3MgaW5mb3JtYXRpb24gaW50byB0aGUgcmVxdWVzdC0+cGFyZW50X2RhdGEgc3RydWN0dXJlLgogKgogKiAgVGhlIHRhYmxlIGhlbHBlciBoYW5kbGVyIHB1bGxzIG91dCB0aGUgY29sdW1uIG51bWJlciBhbmQgaW5kZXhlcyBmcm9tIAogKiAgdGhlIHJlcXVlc3Qgb2lkIHNvIHRoYXQgeW91IGRvbid0IGhhdmUgdG8gZG8gdGhlIGNvbXBsZXggd29yayBvZgogKiAgcGFyc2luZyB3aXRoaW4geW91ciBvd24gY29kZS4KICoKICogIEBwYXJhbSB0YWJyZXEgaXMgYSBwb2ludGVyIHRvIGEgbmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyBzdHJ1Y3QuCiAqCVRoZSB0YWJsZSBoYW5kbGVyIG5lZWRzIHRvIGtub3cgdXAgZnJvbnQgaG93IHlvdXIgdGFibGUgaXMgc3RydWN0dXJlZC4KICoJQSBuZXRzbm1wX3RhYmxlX3JlZ2lzdGVyYXRpb25faW5mbyBzdHJ1Y3R1cmUgdGhhdCBpcyAKICoJcGFzc2VkIHRvIHRoZSB0YWJsZSBoYW5kbGVyIHNob3VsZCBjb250YWluIHRoZSBhc24gaW5kZXggdHlwZXMgZm9yIHRoZSAKICoJdGFibGUgYXMgd2VsbCBhcyB0aGUgbWluaW11bSBhbmQgbWF4aW11bSBjb2x1bW4gdGhhdCBzaG91bGQgYmUgdXNlZC4KICoKICogIEByZXR1cm4gUmV0dXJucyBhIHBvaW50ZXIgdG8gYSBuZXRzbm1wX21pYl9oYW5kbGVyIHN0cnVjdCB3aGljaCBjb250YWlucwogKgl0aGUgaGFuZGxlcidzIG5hbWUgYW5kIHRoZSBhY2Nlc3MgbWV0aG9kCiAqCiAqLwpuZXRzbm1wX21pYl9oYW5kbGVyICoKbmV0c25tcF9nZXRfdGFibGVfaGFuZGxlcihuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvICp0YWJyZXEpCnsKICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKnJldCA9IE5VTEw7CgogICAgaWYgKCF0YWJyZXEpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfSU5GTywgIm5ldHNubXBfZ2V0X3RhYmxlX2hhbmRsZXIoTlVMTCkgY2FsbGVkXG4iKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByZXQgPSBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyKFRBQkxFX0hBTkRMRVJfTkFNRSwgdGFibGVfaGVscGVyX2hhbmRsZXIpOwogICAgaWYgKHJldCkgewogICAgICAgIHJldC0+bXl2b2lkID0gKHZvaWQgKikgdGFicmVxOwogICAgICAgIHRhYnJlcS0+bnVtYmVyX2luZGV4ZXMgPSBjb3VudF92YXJiaW5kcyh0YWJyZXEtPmluZGV4ZXMpOwogICAgfQogICAgcmV0dXJuIHJldDsKfQoKCi8qKiBjcmVhdGVzIGEgdGFibGUgaGFuZGxlciBnaXZlbiB0aGUgbmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyBvYmplY3QsCiAqICBpbnNlcnRzIGl0IGludG8gdGhlIHJlcXVlc3QgY2hhaW4gYW5kIHRoZW4gY2FsbHMKICogIG5ldHNubXBfcmVnaXN0ZXJfaGFuZGxlcigpIHRvIHJlZ2lzdGVyIHRoZSB0YWJsZSBpbnRvIHRoZSBhZ2VudC4KICovCmludApuZXRzbm1wX3JlZ2lzdGVyX3RhYmxlKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyAqdGFicmVxKQp7CiAgICBpbnQgcmMgPSBuZXRzbm1wX2luamVjdF9oYW5kbGVyKHJlZ2luZm8sIG5ldHNubXBfZ2V0X3RhYmxlX2hhbmRsZXIodGFicmVxKSk7CiAgICBpZiAoU05NUEVSUl9TVUNDRVNTICE9IHJjKQogICAgICAgIHJldHVybiByYzsKCiAgICByZXR1cm4gbmV0c25tcF9yZWdpc3Rlcl9oYW5kbGVyKHJlZ2luZm8pOwp9CgppbnQKbmV0c25tcF91bnJlZ2lzdGVyX3RhYmxlKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8pCnsKICAgIC8qIExvY2F0ZSAidGhpcyIgcmVnaW5mbyAqLwogICAgLyogU05NUF9GUkVFKHJlZ2luZm8tPm15dm9pZCk7ICovCiAgICAvKiByZWdpbmZvLT5teXZvaWQgPSBOVUxMOyAqLwogICAgcmV0dXJuIG5ldHNubXBfdW5yZWdpc3Rlcl9oYW5kbGVyKHJlZ2luZm8pOwp9CgovKiogRXh0cmFjdHMgdGhlIHByb2Nlc3NlZCB0YWJsZSBpbmZvcm1hdGlvbiBmcm9tIGEgZ2l2ZW4gcmVxdWVzdC4KICogIENhbGwgdGhpcyBmcm9tIHN1YmhhbmRsZXJzIG9uIGEgcmVxdWVzdCB0byBleHRyYWN0IHRoZSBwcm9jZXNzZWQKICogIG5ldHNubXBfcmVxdWVzdF9pbmZvIGluZm9ybWF0aW9uLiAgVGhlIHJlc3VsdGluZyBpbmZvcm1hdGlvbiBpbmNsdWRlcyB0aGUKICogIGluZGV4IHZhbHVlcyBhbmQgdGhlIGNvbHVtbiBudW1iZXIuCiAqCiAqIEBwYXJhbSByZXF1ZXN0IHBvcHVsYXRlZCBuZXRzbm1wIHJlcXVlc3Qgc3RydWN0dXJlCiAqCiAqIEByZXR1cm4gcG9wdWxhdGVkIG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvIHN0cnVjdHVyZQogKi8KTkVUU05NUF9JTkxJTkUgbmV0c25tcF90YWJsZV9yZXF1ZXN0X2luZm8gKgpuZXRzbm1wX2V4dHJhY3RfdGFibGVfaW5mbyhuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdCkKewogICAgcmV0dXJuIChuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyAqKQogICAgICAgIG5ldHNubXBfcmVxdWVzdF9nZXRfbGlzdF9kYXRhKHJlcXVlc3QsIFRBQkxFX0hBTkRMRVJfTkFNRSk7Cn0KCi8qKiBleHRyYWN0cyB0aGUgcmVnaXN0ZXJlZCBuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvIG9iamVjdCBmcm9tIGEKICogIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gb2JqZWN0ICovCm5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gKgpuZXRzbm1wX2ZpbmRfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8obmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbykKewogICAgcmV0dXJuIChuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvICopCiAgICAgICAgbmV0c25tcF9maW5kX2hhbmRsZXJfZGF0YV9ieV9uYW1lKHJlZ2luZm8sIFRBQkxFX0hBTkRMRVJfTkFNRSk7Cn0KCi8qKiBpbXBsZW1lbnRzIHRoZSB0YWJsZSBoZWxwZXIgaGFuZGxlciAqLwppbnQKdGFibGVfaGVscGVyX2hhbmRsZXIobmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cykKewoKICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0OwogICAgbmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyAqdGJsX2luZm87CiAgICBpbnQgICAgICAgICAgICAgb2lkX2luZGV4X3BvczsKICAgIHVuc2lnbmVkIGludCAgICBvaWRfY29sdW1uX3BvczsKICAgIHVuc2lnbmVkIGludCAgICB0bXBfaWR4OwogICAgc2l6ZV90CSAgICB0bXBfbGVuOwogICAgaW50ICAgICAgICAgICAgIGluY29tcGxldGUsIG91dF9vZl9yYW5nZSwgY2xlYW5lZF91cCA9IDA7CiAgICBpbnQgICAgICAgICAgICAgc3RhdHVzID0gU05NUF9FUlJfTk9FUlJPUiwgbmVlZF9wcm9jZXNzaW5nID0gMDsKICAgIG9pZCAgICAgICAgICAgICp0bXBfbmFtZTsKICAgIG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvICp0YmxfcmVxX2luZm87CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZiOwoKICAgIGlmICghcmVnaW5mbyB8fCAhaGFuZGxlcikKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CgogICAgb2lkX2luZGV4X3BvcyAgPSByZWdpbmZvLT5yb290b2lkX2xlbiArIDI7CiAgICBvaWRfY29sdW1uX3BvcyA9IHJlZ2luZm8tPnJvb3RvaWRfbGVuICsgMTsKICAgIHRibF9pbmZvID0gKG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gKikgaGFuZGxlci0+bXl2b2lkOwoKICAgIGlmICgoIWhhbmRsZXItPm15dm9pZCkgfHwgKCF0YmxfaW5mby0+aW5kZXhlcykpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiaW1wcm9wZXJseSByZWdpc3RlcmVkIHRhYmxlIGZvdW5kXG4iKTsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAibmFtZTogJXMsIHRhYmxlIGluZm86ICVwLCBpbmRleGVzOiAlcFxuIiwKICAgICAgICAgICAgICAgICBoYW5kbGVyLT5oYW5kbGVyX25hbWUsIGhhbmRsZXItPm15dm9pZCwgdGJsX2luZm8tPmluZGV4ZXMpOwoKICAgICAgICAvKgogICAgICAgICAqIFhYWC1ya3M6IHVucmVnaXN0ZXIgdGFibGU/IAogICAgICAgICAqLwogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICB9CgogICAgREVCVUdJRigiaGVscGVyOnRhYmxlOnJlcSIpIHsKICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOnRhYmxlOnJlcSIsCiAgICAgICAgICAgICAgICAgICAgIkdvdCByZXF1ZXN0IGZvciBoYW5kbGVyICVzOiBiYXNlIG9pZDoiLAogICAgICAgICAgICAgICAgICAgIGhhbmRsZXItPmhhbmRsZXJfbmFtZSkpOwogICAgICAgIERFQlVHTVNHT0lEKCgiaGVscGVyOnRhYmxlOnJlcSIsIHJlZ2luZm8tPnJvb3RvaWQsCiAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPnJvb3RvaWRfbGVuKSk7CiAgICAgICAgREVCVUdNU0coKCJoZWxwZXI6dGFibGU6cmVxIiwgIlxuIikpOwogICAgfQogICAgCiAgICAvKgogICAgICogaWYgdGhlIGFnZW50IHJlcXVlc3QgaW5mbyBoYXMgYSBzdGF0ZSByZWZlcmVuY2UsIHRoZW4gdGhpcyBpcyBhIAogICAgICogbGF0ZXIgcGFzcyBvZiBhIHNldCByZXF1ZXN0IGFuZCB3ZSBjYW4gc2tpcCBhbGwgdGhlIGxvb2t1cCBzdHVmZi4KICAgICAqCiAgICAgKiB4eHgtcmtzOiB0aGlzIG1pZ2h0IGJyZWFrIGZvciBoYW5kbGVycyB3aGljaCBvbmx5IGhhbmRsZSBvbmUgdmFyYmluZAogICAgICogYXQgYSB0aW1lLi4uIHRob3NlIGhhbmRsZXJzIHNob3VsZCBub3Qgc2F2ZSBkYXRhIGJ5IHRoZWlyIGhhbmRsZXJfbmFtZQogICAgICogaW4gdGhlIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvLiAKICAgICAqLwogICAgaWYgKG5ldHNubXBfYWdlbnRfZ2V0X2xpc3RfZGF0YShyZXFpbmZvLCBoYW5kbGVyLT5uZXh0LT5oYW5kbGVyX25hbWUpKSB7CiAgICAgICAgaWYgKE1PREVfSVNfU0VUKHJlcWluZm8tPm1vZGUpKSB7CiAgICAgICAgICAgIHJldHVybiBuZXRzbm1wX2NhbGxfbmV4dF9oYW5kbGVyKGhhbmRsZXIsIHJlZ2luZm8sIHJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RzKTsKICAgICAgICB9IGVsc2UgewovKiogWFhYLXJrczogbWVtb3J5IGxlYWsuIGFkZCBjbGVhbnVwIGhhbmRsZXI/ICovCiAgICAgICAgICAgIG5ldHNubXBfZnJlZV9hZ2VudF9kYXRhX3NldHMocmVxaW5mbyk7CiAgICAgICAgfQogICAgfQoKICAgIGlmICggTU9ERV9JU19TRVQocmVxaW5mby0+bW9kZSkgJiYKICAgICAgICAgKHJlcWluZm8tPm1vZGUgIT0gTU9ERV9TRVRfUkVTRVJWRTEpKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBmb3IgbGF0ZXIgc2V0IG1vZGVzLCB3ZSBjYW4gc2tpcCBhbGwgdGhlIGluZGV4IHBhcnNpbmcsCiAgICAgICAgICogYW5kIHdlIGFsd2F5cyBuZWVkIHRvIGxldCBjaGlsZCBoYW5kbGVycyBoYXZlIGEgY2hhbmNlCiAgICAgICAgICogdG8gY2xlYW4gdXAsIGlmIHRoZXkgd2VyZSBjYWxsZWQgaW4gdGhlIGZpcnN0IHBsYWNlIChpLmUuIGhhdmUKICAgICAgICAgKiBhIHZhbGlkIHRhYmxlIGluZm8gcG9pbnRlcikuCiAgICAgICAgICovCiAgICAgICAgaWYoTlVMTCA9PSBuZXRzbm1wX2V4dHJhY3RfdGFibGVfaW5mbyhyZXF1ZXN0cykpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInRhYmxlOmhlbHBlciIsIm5vIHRhYmxlIGluZm8gZm9yIHNldCAtIHNraXBwaW5nXG4iKSk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICAgICAgbmVlZF9wcm9jZXNzaW5nID0gMTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIC8qCiAgICAgICAgICogZm9yIFJFU0VSVkUxIGFuZCBHRVRTLCBvbmx5IGNvbnRpbnVlIGlmIHdlIGhhdmUgYXQgbGVhc3QKICAgICAgICAgKiBvbmUgdmFsaWQgcmVxdWVzdC4KICAgICAgICAgKi8KICAgICAgICAgICAKICAgIC8qCiAgICAgKiBsb29wIHRocm91Z2ggcmVxdWVzdHMKICAgICAqLwoKICAgIGZvciAocmVxdWVzdCA9IHJlcXVlc3RzOyByZXF1ZXN0OyByZXF1ZXN0ID0gcmVxdWVzdC0+bmV4dCkgewogICAgICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFyID0gcmVxdWVzdC0+cmVxdWVzdHZiOwoKICAgICAgICBERUJVR01TR09JRCgoInZlcmJvc2U6dGFibGUiLCB2YXItPm5hbWUsIHZhci0+bmFtZV9sZW5ndGgpKTsKICAgICAgICBERUJVR01TRygoInZlcmJvc2U6dGFibGUiLCAiXG4iKSk7CgogICAgICAgIGlmIChyZXF1ZXN0LT5wcm9jZXNzZWQpIHsKICAgICAgICAgICAgREVCVUdNU0coKCJ2ZXJib3NlOnRhYmxlIiwgImFscmVhZHkgcHJvY2Vzc2VkXG4iKSk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICBuZXRzbm1wX2Fzc2VydChyZXF1ZXN0LT5zdGF0dXMgPT0gU05NUF9FUlJfTk9FUlJPUik7CgogICAgICAgIC8qCiAgICAgICAgICogdGhpcyBzaG91bGQgcHJvYmFibHkgYmUgaGFuZGxlZCBmdXJ0aGVyIHVwIAogICAgICAgICAqLwogICAgICAgIGlmICgocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVCkgJiYgKHZhci0+dHlwZSAhPSBBU05fTlVMTCkpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogdmFsaWQgcmVxdWVzdCBpZiBBU05fTlVMTCAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGUiLAogICAgICAgICAgICAgICAgICAgICAgICAiICBHRVQgdmFyIHR5cGUgaXMgbm90IEFTTl9OVUxMXG4iKSk7CiAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0VSUl9XUk9OR1RZUEUpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfU0VUX1JFU0VSVkUxKSB7CiAgICAgICAgICAgIERFQlVHSUYoImhlbHBlcjp0YWJsZTpzZXQiKSB7CiAgICAgICAgICAgICAgICB1X2NoYXIgICAgICAgICAqYnVmID0gTlVMTDsKICAgICAgICAgICAgICAgIHNpemVfdCAgICAgICAgICBidWZfbGVuID0gMCwgb3V0X2xlbiA9IDA7CiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOnRhYmxlOnNldCIsICIgU0VUX1JFUVVFU1QgZm9yIE9JRDogIikpOwogICAgICAgICAgICAgICAgREVCVUdNU0dPSUQoKCJoZWxwZXI6dGFibGU6c2V0IiwgdmFyLT5uYW1lLCB2YXItPm5hbWVfbGVuZ3RoKSk7CiAgICAgICAgICAgICAgICBvdXRfbGVuID0gMDsKICAgICAgICAgICAgICAgIGlmIChzcHJpbnRfcmVhbGxvY19ieV90eXBlKCZidWYsICZidWZfbGVuLCAmb3V0X2xlbiwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciwgTlVMTCwgTlVMTCwgTlVMTCkpIHsKICAgICAgICAgICAgICAgICAgICBERUJVR01TRygoImhlbHBlcjp0YWJsZTpzZXQiLCIgdHlwZT0lZCglMDJ4KSwgdmFsdWU9JXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhci0+dHlwZSwgdmFyLT50eXBlLCBidWYpKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGJ1ZiAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIERFQlVHTVNHKCgiaGVscGVyOnRhYmxlOnNldCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIHR5cGU9JWQoJTAyeCksIHZhbHVlPSVzIFtUUlVOQ0FURURdXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyLT50eXBlLCB2YXItPnR5cGUsIGJ1ZikpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIERFQlVHTVNHKCgiaGVscGVyOnRhYmxlOnNldCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIHR5cGU9JWQoJTAyeCksIHZhbHVlPVtOSUxdIFtUUlVOQ0FURURdXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyLT50eXBlLCB2YXItPnR5cGUpKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoYnVmICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBmcmVlKGJ1Zik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogY2hlY2sgdG8gbWFrZSBzdXJlIGl0cyBpbiB0YWJsZSByYW5nZSAKICAgICAgICAgKi8KCiAgICAgICAgb3V0X29mX3JhbmdlID0gMDsKICAgICAgICAvKgogICAgICAgICAqIGlmIG91ciByb290IG9pZCBpcyA+IHZhci0+bmFtZSBhbmQgdGhpcyBpcyBub3QgYSBHRVRORVhULCAKICAgICAgICAgKiB0aGVuIHRoZSBvaWQgaXMgb3V0IG9mIHJhbmdlLiAob25seSBjb21wYXJlIHVwIHRvIHNob3J0ZXIgCiAgICAgICAgICogbGVuZ3RoKSAKICAgICAgICAgKi8KICAgICAgICBpZiAocmVnaW5mby0+cm9vdG9pZF9sZW4gPiB2YXItPm5hbWVfbGVuZ3RoKQogICAgICAgICAgICB0bXBfbGVuID0gdmFyLT5uYW1lX2xlbmd0aDsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHRtcF9sZW4gPSByZWdpbmZvLT5yb290b2lkX2xlbjsKICAgICAgICBpZiAoc25tcF9vaWRfY29tcGFyZShyZWdpbmZvLT5yb290b2lkLCByZWdpbmZvLT5yb290b2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXItPm5hbWUsIHRtcF9sZW4pID4gMCkgewogICAgICAgICAgICBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVE5FWFQpIHsKICAgICAgICAgICAgICAgIGlmICh2YXItPm5hbWUgIT0gdmFyLT5uYW1lX2xvYykKICAgICAgICAgICAgICAgICAgICBTTk1QX0ZSRUUodmFyLT5uYW1lKTsKICAgICAgICAgICAgICAgIHNubXBfc2V0X3Zhcl9vYmppZCh2YXIsIHJlZ2luZm8tPnJvb3RvaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW5mby0+cm9vdG9pZF9sZW4pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZSIsICIgIG9pZCBpcyBvdXQgb2YgcmFuZ2UuXG4iKSk7CiAgICAgICAgICAgICAgICBvdXRfb2ZfcmFuZ2UgPSAxOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qCiAgICAgICAgICogaWYgdmFyLT5uYW1lIGlzIGxvbmdlciB0aGFuIHRoZSByb290LCBtYWtlIHN1cmUgaXQgaXMgCiAgICAgICAgICogdGFibGUuMSAodGFibGUuRU5UUlkpLiAgCiAgICAgICAgICovCiAgICAgICAgZWxzZSBpZiAoKHZhci0+bmFtZV9sZW5ndGggPiByZWdpbmZvLT5yb290b2lkX2xlbikgJiYKICAgICAgICAgICAgICAgICAodmFyLT5uYW1lW3JlZ2luZm8tPnJvb3RvaWRfbGVuXSAhPSAxKSkgewogICAgICAgICAgICBpZiAoKHZhci0+bmFtZVtyZWdpbmZvLT5yb290b2lkX2xlbl0gPCAxKSAmJgogICAgICAgICAgICAgICAgKHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRORVhUKSkgewogICAgICAgICAgICAgICAgdmFyLT5uYW1lW3JlZ2luZm8tPnJvb3RvaWRfbGVuXSA9IDE7CiAgICAgICAgICAgICAgICB2YXItPm5hbWVfbGVuZ3RoID0gcmVnaW5mby0+cm9vdG9pZF9sZW47CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBvdXRfb2ZfcmFuZ2UgPSAxOwogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZSIsICIgIG9pZCBpcyBvdXQgb2YgcmFuZ2UuXG4iKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoKICAgICAgICAgKiBpZiBpdCBpcyBub3QgaW4gcmFuZ2UsIHRoZW4gbWFyayBpdCBpbiB0aGUgcmVxdWVzdCBsaXN0IAogICAgICAgICAqIGJlY2F1c2Ugd2UgY2FuJ3QgcHJvY2VzcyBpdCwgYW5kIHNldCBhbiBlcnJvciBzbwogICAgICAgICAqIG5vYm9keSBlbHNlIHdhc3RlcyB0aW1lIHRyeWluZyB0byBwcm9jZXNzIGl0IGVpdGhlci4gIAogICAgICAgICAqLwogICAgICAgIGlmIChvdXRfb2ZfcmFuZ2UpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZSIsICIgIE5vdCBwcm9jZXNzZWQ6ICIpKTsKICAgICAgICAgICAgREVCVUdNU0dPSUQoKCJoZWxwZXI6dGFibGUiLCB2YXItPm5hbWUsIHZhci0+bmFtZV9sZW5ndGgpKTsKICAgICAgICAgICAgREVCVUdNU0coKCJoZWxwZXI6dGFibGUiLCAiXG4iKSk7CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiAgUmVqZWN0IHJlcXVlc3RzIG9mIHRoZSBmb3JtICdteVRhYmxlLk4nICAgKE4gIT0gMSkKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfU0VUX1JFU0VSVkUxKQogICAgICAgICAgICAgICAgdGFibGVfaGVscGVyX2NsZWFudXAocmVxaW5mbywgcmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX05PVFdSSVRBQkxFKTsKICAgICAgICAgICAgZWxzZSBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVCkKICAgICAgICAgICAgICAgIHRhYmxlX2hlbHBlcl9jbGVhbnVwKHJlcWluZm8sIHJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX05PU1VDSE9CSkVDVCk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCgogICAgICAgIC8qCiAgICAgICAgICogQ2hlY2sgY29sdW1uIHJhbmdlczsgc2V0LXVwIHRvIHB1bGwgb3V0IGluZGV4ZXMgZnJvbSBPSUQuIAogICAgICAgICAqLwoKICAgICAgICBpbmNvbXBsZXRlID0gMDsKICAgICAgICB0YmxfcmVxX2luZm8gPSBuZXRzbm1wX2V4dHJhY3RfdGFibGVfaW5mbyhyZXF1ZXN0KTsKICAgICAgICBpZiAoTlVMTCA9PSB0YmxfcmVxX2luZm8pIHsKICAgICAgICAgICAgdGJsX3JlcV9pbmZvID0gU05NUF9NQUxMT0NfVFlQRURFRihuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyk7CiAgICAgICAgICAgIGlmICh0YmxfcmVxX2luZm8gPT0gTlVMTCkgewogICAgICAgICAgICAgICAgdGFibGVfaGVscGVyX2NsZWFudXAocmVxaW5mbywgcmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX0dFTkVSUik7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICB0YmxfcmVxX2luZm8tPnJlZ19pbmZvID0gdGJsX2luZm87CiAgICAgICAgICAgIHRibF9yZXFfaW5mby0+aW5kZXhlcyA9IHNubXBfY2xvbmVfdmFyYmluZCh0YmxfaW5mby0+aW5kZXhlcyk7CiAgICAgICAgICAgIHRibF9yZXFfaW5mby0+bnVtYmVyX2luZGV4ZXMgPSAwOyAgICAgICAvKiBub25lIHlldCAqLwogICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfYWRkX2xpc3RfZGF0YShyZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV9kYXRhX2xpc3QKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFRBQkxFX0hBTkRMRVJfTkFNRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkICopIHRibF9yZXFfaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlX2RhdGFfZnJlZV9mdW5jKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZSIsICIgIHVzaW5nIGV4aXN0aW5nIHRibF9yZXFfaW5mb1xuICIpKTsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogZG8gd2UgaGF2ZSBhIGNvbHVtbj8KICAgICAgICAgKi8KICAgICAgICBpZiAodmFyLT5uYW1lX2xlbmd0aCA+IG9pZF9jb2x1bW5fcG9zKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIG9pZCBpcyBsb25nIGVub3VnaCB0byBjb250YWluIENPTFVNTiBpbmZvCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOnRhYmxlOmNvbCIsICIgIGhhdmUgYXQgbGVhc3QgYSBjb2x1bW4gKCVsZClcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHZhci0+bmFtZVtvaWRfY29sdW1uX3Bvc10pKTsKICAgICAgICAgICAgaWYgKHZhci0+bmFtZVtvaWRfY29sdW1uX3Bvc10gPCB0YmxfaW5mby0+bWluX2NvbHVtbikgewogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZTpjb2wiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICBidXQgaXQncyBsZXNzIHRoYW4gbWluICglZClcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YmxfaW5mby0+bWluX2NvbHVtbikpOwogICAgICAgICAgICAgICAgaWYgKHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRORVhUKSB7CiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiBmaXggY29sdW1uLCB0cnVuY2F0ZSB1c2VsZXNzIGNvbHVtbiBpbmZvIAogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIHZhci0+bmFtZV9sZW5ndGggPSBvaWRfY29sdW1uX3BvczsKICAgICAgICAgICAgICAgICAgICB0YmxfcmVxX2luZm8tPmNvbG51bSA9IHRibF9pbmZvLT5taW5fY29sdW1uOwogICAgICAgICAgICAgICAgfSBlbHNlCiAgICAgICAgICAgICAgICAgICAgb3V0X29mX3JhbmdlID0gMTsKICAgICAgICAgICAgfSBlbHNlIGlmICh2YXItPm5hbWVbb2lkX2NvbHVtbl9wb3NdID4gdGJsX2luZm8tPm1heF9jb2x1bW4pCiAgICAgICAgICAgICAgICBvdXRfb2ZfcmFuZ2UgPSAxOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB0YmxfcmVxX2luZm8tPmNvbG51bSA9IHZhci0+bmFtZVtvaWRfY29sdW1uX3Bvc107CgogICAgICAgICAgICBpZiAob3V0X29mX3JhbmdlKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogdGhpcyBpcyBvdXQgb2YgcmFuZ2UuLi4gIHJlbW92ZSBmcm9tIHJlcXVlc3RzLCBmcmVlCiAgICAgICAgICAgICAgICAgKiBtZW1vcnkgCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICBvaWQgaXMgb3V0IG9mIHJhbmdlLiBOb3QgcHJvY2Vzc2VkOiAiKSk7CiAgICAgICAgICAgICAgICBERUJVR01TR09JRCgoImhlbHBlcjp0YWJsZSIsIHZhci0+bmFtZSwgdmFyLT5uYW1lX2xlbmd0aCkpOwogICAgICAgICAgICAgICAgREVCVUdNU0coKCJoZWxwZXI6dGFibGUiLCAiXG4iKSk7CgogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqICBSZWplY3QgcmVxdWVzdHMgb2YgdGhlIGZvcm0gJ215RW50cnkuTicgICAoaW52YWxpZCBOKQogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX1NFVF9SRVNFUlZFMSkKICAgICAgICAgICAgICAgICAgICB0YWJsZV9oZWxwZXJfY2xlYW51cChyZXFpbmZvLCByZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX05PVFdSSVRBQkxFKTsKICAgICAgICAgICAgICAgIGVsc2UgaWYgKHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVQpCiAgICAgICAgICAgICAgICAgICAgdGFibGVfaGVscGVyX2NsZWFudXAocmVxaW5mbywgcmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX05PU1VDSE9CSkVDVCk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiB1c2UgY29sdW1uIHZlcmlmaWNhdGlvbiAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGVsc2UgaWYgKHRibF9pbmZvLT52YWxpZF9jb2x1bW5zKSB7CiAgICAgICAgICAgICAgICB0YmxfcmVxX2luZm8tPmNvbG51bSA9CiAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9jbG9zZXN0X2NvbHVtbih2YXItPm5hbWVbb2lkX2NvbHVtbl9wb3NdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGJsX2luZm8tPnZhbGlkX2NvbHVtbnMpOwogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZTpjb2wiLCAiICAgIGNsb3Nlc3QgY29sdW1uIGlzICVkXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgdGJsX3JlcV9pbmZvLT5jb2xudW0pKTsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiB4eHgtcmtzOiBkb2N1bWVudCB3aHkgdGhlIGNvbnRpbnVlLi4uCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmICh0YmxfcmVxX2luZm8tPmNvbG51bSA9PSAwKQogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgaWYgKHRibF9yZXFfaW5mby0+Y29sbnVtICE9IHZhci0+bmFtZVtvaWRfY29sdW1uX3Bvc10pIHsKICAgICAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOnRhYmxlOmNvbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICB3aGljaCBkb2Vzbid0IG1hdGNoIHJlcSAlbGQgLSB0cnVuY2F0aW5nIGluZGV4IGluZm9cbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyLT5uYW1lW29pZF9jb2x1bW5fcG9zXSkpOwogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogZGlmZmVyZW50IGNvbHVtbiEgdHJ1bmNhdGUgdXNlbGVzcyBpbmRleCBpbmZvIAogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIHZhci0+bmFtZV9sZW5ndGggPSBvaWRfY29sdW1uX3BvcyArIDE7IC8qIHBvcyBpcyAwIGJhc2VkICovCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogdmFyLT5uYW1lX2xlbmd0aCBtYXkgaGF2ZSBjaGFuZ2VkIC0gY2hlY2sgYWdhaW4gCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoKGludCl2YXItPm5hbWVfbGVuZ3RoIDw9IG9pZF9pbmRleF9wb3MpIHsgLyogcG9zIGlzIDAgYmFzZWQgKi8KICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGUiLCAiICAgIG5vdCBlbm91Z2ggZm9yIGluZGV4ZXNcbiIpKTsKICAgICAgICAgICAgICAgIHRibF9yZXFfaW5mby0+aW5kZXhfb2lkX2xlbiA9IDA7IC8qKiBub25lIGF2YWlsYWJsZSAqLwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIG9pZCBpcyBsb25nIGVub3VnaCB0byBjb250YWluIElOREVYIGluZm8KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgdGJsX3JlcV9pbmZvLT5pbmRleF9vaWRfbGVuID0KICAgICAgICAgICAgICAgICAgICB2YXItPm5hbWVfbGVuZ3RoIC0gb2lkX2luZGV4X3BvczsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGUiLCAiICAgIGhhdmUgJWx1IGJ5dGVzIG9mIGluZGV4XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVuc2lnbmVkIGxvbmcpdGJsX3JlcV9pbmZvLT5pbmRleF9vaWRfbGVuKSk7CiAgICAgICAgICAgICAgICBuZXRzbm1wX2Fzc2VydCh0YmxfcmVxX2luZm8tPmluZGV4X29pZF9sZW4gPCBNQVhfT0lEX0xFTik7CiAgICAgICAgICAgICAgICBtZW1jcHkodGJsX3JlcV9pbmZvLT5pbmRleF9vaWQsICZ2YXItPm5hbWVbb2lkX2luZGV4X3Bvc10sCiAgICAgICAgICAgICAgICAgICAgICAgdGJsX3JlcV9pbmZvLT5pbmRleF9vaWRfbGVuICogc2l6ZW9mKG9pZCkpOwogICAgICAgICAgICAgICAgdG1wX25hbWUgPSB0YmxfcmVxX2luZm8tPmluZGV4X29pZDsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVE5FWFQgfHwKICAgICAgICAgICAgICAgICAgIHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRCVUxLKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIG9pZCBpcyBOT1QgbG9uZyBlbm91Z2ggdG8gY29udGFpbiBjb2x1bW4gb3IgaW5kZXggaW5mbywgc28gc3RhcnQKICAgICAgICAgICAgICogYXQgdGhlIG1pbmltdW0gY29sdW1uLiBTZXQgaW5kZXggb2lkIGxlbiB0byAwIGJlY2F1c2Ugd2UgZG9uJ3QKICAgICAgICAgICAgICogaGF2ZSBhbnkgaW5kZXggaW5mbyBpbiB0aGUgT0lELgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZSIsICIgIG5vIGNvbHVtbi9pbmRleCBpbiByZXF1ZXN0XG4iKSk7CiAgICAgICAgICAgIHRibF9yZXFfaW5mby0+aW5kZXhfb2lkX2xlbiA9IDA7CiAgICAgICAgICAgIHRibF9yZXFfaW5mby0+Y29sbnVtID0gdGJsX2luZm8tPm1pbl9jb2x1bW47CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogb2lkIGlzIE5PVCBsb25nIGVub3VnaCB0byBjb250YWluIGluZGV4IGluZm8sCiAgICAgICAgICAgICAqIHNvIHdlIGNhbid0IGRvIGFueXRoaW5nIHdpdGggaXQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIFJlamVjdCByZXF1ZXN0cyBvZiB0aGUgZm9ybSAnbXlUYWJsZScgb3IgJ215RW50cnknCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVCApIHsKICAgICAgICAgICAgICAgIHRhYmxlX2hlbHBlcl9jbGVhbnVwKHJlcWluZm8sIHJlcXVlc3QsIFNOTVBfTk9TVUNIT0JKRUNUKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfU0VUX1JFU0VSVkUxICkgewogICAgICAgICAgICAgICAgdGFibGVfaGVscGVyX2NsZWFudXAocmVxaW5mbywgcmVxdWVzdCwgU05NUF9FUlJfTk9UV1JJVEFCTEUpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBzZXQgdXAgdG1wX2xlbiB0byBiZSB0aGUgbnVtYmVyIG9mIE9JRHMgd2UgaGF2ZSBiZXlvbmQgdGhlIGNvbHVtbjsKICAgICAgICAgKiB0aGVzZSBzaG91bGQgYmUgdGhlIGluZGV4KHMpIGZvciB0aGUgdGFibGUuIElmIHRoZSBpbmRleF9vaWRfbGVuCiAgICAgICAgICogaXMgMCwgc2V0IHRtcF9sZW4gdG8gLTEgc28gdGhhdCB3aGVuIHdlIHRyeSB0byBwYXJzZSB0aGUgaW5kZXggYmVsb3csCiAgICAgICAgICogd2UganVzdCB6ZXJvIGZpbGwgZXZlcnl0aGluZy4KICAgICAgICAgKi8KICAgICAgICBpZiAodGJsX3JlcV9pbmZvLT5pbmRleF9vaWRfbGVuID09IDApIHsKICAgICAgICAgICAgaW5jb21wbGV0ZSA9IDE7CiAgICAgICAgICAgIHRtcF9sZW4gPSAtMTsKICAgICAgICB9IGVsc2UKICAgICAgICAgICAgdG1wX2xlbiA9IHRibF9yZXFfaW5mby0+aW5kZXhfb2lkX2xlbjsKCgogICAgICAgIC8qCiAgICAgICAgICogZm9yIGVhY2ggaW5kZXggdHlwZSwgdHJ5IHRvIGV4dHJhY3QgdGhlIGluZGV4IGZyb20gdmFyLT5uYW1lCiAgICAgICAgICovCiAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZSIsICIgIGxvb2tpbmcgZm9yICVkIGluZGV4ZXNcbiIsCiAgICAgICAgICAgICAgICAgICAgdGJsX2luZm8tPm51bWJlcl9pbmRleGVzKSk7CiAgICAgICAgZm9yICh0bXBfaWR4ID0gMCwgdmIgPSB0YmxfcmVxX2luZm8tPmluZGV4ZXM7CiAgICAgICAgICAgICB0bXBfaWR4IDwgdGJsX2luZm8tPm51bWJlcl9pbmRleGVzOwogICAgICAgICAgICAgKyt0bXBfaWR4LCB2YiA9IHZiLT5uZXh0X3ZhcmlhYmxlKSB7CiAgICAgICAgICAgIGlmIChpbmNvbXBsZXRlICYmIHRtcF9sZW4pIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBpbmNvbXBsZXRlL2lsbGVnYWwgT0lELCBzZXQgdXAgZHVtbXkgMCB0byBwYXJzZSAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICBvaWQgaW5kZXhlcyBub3QgY29tcGxldGU6ICIpKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHT0lEKCgiaGVscGVyOnRhYmxlIiwgdmFyLT5uYW1lLCB2YXItPm5hbWVfbGVuZ3RoKSk7CiAgICAgICAgICAgICAgICBERUJVR01TRygoImhlbHBlcjp0YWJsZSIsICJcbiIpKTsKCiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogbm8gc2Vuc2UgaW4gdHJ5aW5nIGFueW1vcmUgaWYgdGhpcyBpcyBhIEdFVC9TRVQuIAogICAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgICAqIFJlamVjdCByZXF1ZXN0cyBvZiB0aGUgZm9ybSAnbXlPYmplY3QnICAgKG5vIGluc3RhbmNlKQogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAocmVxaW5mby0+bW9kZSAhPSBNT0RFX0dFVE5FWFQpIHsKICAgICAgICAgICAgICAgICAgICB0YWJsZV9oZWxwZXJfY2xlYW51cChyZXFpbmZvLCByZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX05PU1VDSElOU1RBTkNFKTsKICAgICAgICAgICAgICAgICAgICBjbGVhbmVkX3VwID0gMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRtcF9sZW4gPSAwOwogICAgICAgICAgICAgICAgdG1wX25hbWUgPSAob2lkICopICYgdG1wX2xlbjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIHRyeSBhbmQgcGFyc2UgY3VycmVudCBpbmRleCAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChwYXJzZV9vbmVfb2lkX2luZGV4KCZ0bXBfbmFtZSwgJnRtcF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZiLCAxKSAhPSBTTk1QRVJSX1NVQ0NFU1MpIHsKICAgICAgICAgICAgICAgIGluY29tcGxldGUgPSAxOwogICAgICAgICAgICAgICAgdG1wX2xlbiA9IC0xOyAgIC8qIGlzIHRoaXMgbmVjZXNzYXJ5PyBCZXR0ZXIgc2FmZSB0aGFuCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogc29ycnkgKi8KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBkbyBub3QgY291bnQgaW5jb21wbGV0ZSBpbmRleGVzIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOnRhYmxlIiwgIiAgZ290IDEgKGluY29tcGxldGU9JWQpXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5jb21wbGV0ZSkpOwogICAgICAgICAgICAgICAgaWYgKGluY29tcGxldGUpCiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICArK3RibF9yZXFfaW5mby0+bnVtYmVyX2luZGV4ZXM7IC8qKiBnb3Qgb25lIG9rICovCiAgICAgICAgICAgICAgICBpZiAodG1wX2xlbiA8PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgaW5jb21wbGV0ZSA9IDE7CiAgICAgICAgICAgICAgICAgICAgdG1wX2xlbiA9IC0xOyAgICAgICAvKiBpcyB0aGlzIG5lY2Vzc2FyeT8gQmV0dGVyIHNhZmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIHRoYW4gc29ycnkgKi8KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgIC8qKiBmb3IgbG9vcCAqLwoKICAgICAgICBERUJVR0lGKCJoZWxwZXI6dGFibGU6cmVzdWx0cyIpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZTpyZXN1bHRzIiwgIiAgZm91bmQgJWQgaW5kZXhlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgdGJsX3JlcV9pbmZvLT5udW1iZXJfaW5kZXhlcykpOwogICAgICAgICAgICBpZiAoIWNsZWFuZWRfdXApIHsKICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCAgICBjb3VudDsKICAgICAgICAgICAgICAgIHVfY2hhciAgICAgICAgICpidWYgPSBOVUxMOwogICAgICAgICAgICAgICAgc2l6ZV90ICAgICAgICAgIGJ1Zl9sZW4gPSAwLCBvdXRfbGVuID0gMDsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGU6cmVzdWx0cyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICBjb2x1bW46ICVkLCBpbmRleGVzOiAlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YmxfcmVxX2luZm8tPmNvbG51bSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRibF9yZXFfaW5mby0+bnVtYmVyX2luZGV4ZXMpKTsKICAgICAgICAgICAgICAgIGZvciAodmIgPSB0YmxfcmVxX2luZm8tPmluZGV4ZXMsIGNvdW50ID0gMDsKICAgICAgICAgICAgICAgICAgICAgdmIgJiYgY291bnQgPCB0YmxfcmVxX2luZm8tPm51bWJlcl9pbmRleGVzOwogICAgICAgICAgICAgICAgICAgICBjb3VudCsrLCB2YiA9IHZiLT5uZXh0X3ZhcmlhYmxlKSB7CiAgICAgICAgICAgICAgICAgICAgb3V0X2xlbiA9IDA7CiAgICAgICAgICAgICAgICAgICAgaWYgKHNwcmludF9yZWFsbG9jX2J5X3R5cGUoJmJ1ZiwgJmJ1Zl9sZW4sICZvdXRfbGVuLCAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZiLCBOVUxMLCBOVUxMLCBOVUxMKSkgewogICAgICAgICAgICAgICAgICAgICAgICBERUJVR01TRygoImhlbHBlcjp0YWJsZTpyZXN1bHRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICBpbmRleDogdHlwZT0lZCglMDJ4KSwgdmFsdWU9JXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmItPnR5cGUsIHZiLT50eXBlLCBidWYpKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYnVmICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERFQlVHTVNHKCgiaGVscGVyOnRhYmxlOnJlc3VsdHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICBpbmRleDogdHlwZT0lZCglMDJ4KSwgdmFsdWU9JXMgW1RSVU5DQVRFRF0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZiLT50eXBlLCB2Yi0+dHlwZSwgYnVmKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBERUJVR01TRygoImhlbHBlcjp0YWJsZTpyZXN1bHRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAgaW5kZXg6IHR5cGU9JWQoJTAyeCksIHZhbHVlPVtOSUxdIFtUUlVOQ0FURURdIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2Yi0+dHlwZSwgdmItPnR5cGUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChidWYgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIGZyZWUoYnVmKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIERFQlVHTVNHKCgiaGVscGVyOnRhYmxlOnJlc3VsdHMiLCAiXG4iKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgoKICAgICAgICAvKgogICAgICAgICAqIGRvIHdlIGhhdmUgc3VmZmljaWVudCBpbmRleCBpbmZvIHRvIGNvbnRpbnVlPwogICAgICAgICAqLwoKICAgICAgICBpZiAoKHJlcWluZm8tPm1vZGUgIT0gTU9ERV9HRVRORVhUKSAmJgogICAgICAgICAgICAoKHRibF9yZXFfaW5mby0+bnVtYmVyX2luZGV4ZXMgIT0gdGJsX2luZm8tPm51bWJlcl9pbmRleGVzKSB8fAogICAgICAgICAgICAgKHRtcF9sZW4gIT0gLTEpKSkgewogICAgICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOnRhYmxlIiwKICAgICAgICAgICAgICAgICAgICAgICAgImludmFsaWQgaW5kZXgoZXMpIGZvciB0YWJsZSAtIHNraXBwaW5nXG4iKSk7CiAgICAgICAgICAgIHRhYmxlX2hlbHBlcl9jbGVhbnVwKHJlcWluZm8sIHJlcXVlc3QsIFNOTVBfTk9TVUNISU5TVEFOQ0UpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgbmV0c25tcF9hc3NlcnQocmVxdWVzdC0+c3RhdHVzID09IFNOTVBfRVJSX05PRVJST1IpOwogICAgICAgIAogICAgICAgICsrbmVlZF9wcm9jZXNzaW5nOwoKICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBmb3IgZWFjaCByZXF1ZXN0ICovCiAgICB9CgogICAgLyoKICAgICAqIGJhaWwgaWYgdGhlcmUgaXMgbm90aGluZyBmb3Igb3VyIGNoaWxkIGhhbmRsZXJzCiAgICAgKi8KICAgIGlmICgwID09IG5lZWRfcHJvY2Vzc2luZykKICAgICAgICByZXR1cm4gc3RhdHVzOwoKICAgIC8qCiAgICAgKiBjYWxsIG91ciBjaGlsZCBhY2Nlc3MgZnVuY3Rpb24gCiAgICAgKi8KICAgIHN0YXR1cyA9CiAgICAgICAgbmV0c25tcF9jYWxsX25leHRfaGFuZGxlcihoYW5kbGVyLCByZWdpbmZvLCByZXFpbmZvLCByZXF1ZXN0cyk7CgogICAgLyoKICAgICAqIGNoZWNrIGZvciBzcGFyc2UgdGFibGVzCiAgICAgKi8KICAgIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfR0VUTkVYVCkKICAgICAgICBzcGFyc2VfdGFibGVfaGVscGVyX2hhbmRsZXIoIGhhbmRsZXIsIHJlZ2luZm8sIHJlcWluZm8sIHJlcXVlc3RzICk7CgogICAgcmV0dXJuIHN0YXR1czsKfQoKI2RlZmluZSBTUEFSU0VfVEFCTEVfSEFORExFUl9OQU1FICJzcGFyc2VfdGFibGUiCgovKiogaW1wbGVtZW50cyB0aGUgc3BhcnNlIHRhYmxlIGhlbHBlciBoYW5kbGVyCiAqIEBpbnRlcm5hbAogKgogKiBAbm90ZQogKiBUaGlzIGZ1bmN0aW9uIGlzIHN0YXRpYyB0byBwcmV2ZW50IG90aGVycyBmcm9tIGNhbGxpbmcgaXQKICogZGlyZWN0bHkuIEl0IGl0IGF1dG9tYXRpY2FsbHkgY2FsbGVkIGJ5IHRoZSB0YWJsZSBoZWxwZXIsCiAqIAogKi8Kc3RhdGljIGludApzcGFyc2VfdGFibGVfaGVscGVyX2hhbmRsZXIobmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cykKewogICAgaW50ICAgICAgICAgICAgIHN0YXR1cyA9IFNOTVBfRVJSX05PRVJST1I7CiAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdDsKICAgIG9pZCAgICAgICAgICAgICBjb2xvaWRbTUFYX09JRF9MRU5dOwogICAgbmV0c25tcF90YWJsZV9yZXF1ZXN0X2luZm8gKnRhYmxlX2luZm87CgogICAgLyoKICAgICAqIHNpbmNlIHdlIGRvbid0IGNhbGwgY2hpbGQgaGFuZGxlcnMsIHdhcm4gaWYgb25lIHdhcyByZWdpc3RlcmVkCiAgICAgKiBiZW5lYXRoIHVzLiBBIHNwZWNpYWwgZXhjZXB0aW9uIGZvciB0aGUgdGFibGUgaGVscGVyLCB3aGljaCBjYWxscwogICAgICogdGhlIGhhbmRsZXIgZGlyZWN0bHkuIFVzZSBoYW5kbGUgY3VzdG9tIGZsYWcgdG8gb25seSBsb2cgb25jZS4KICAgICAqLwogICAgaWYoKHRhYmxlX2hlbHBlcl9oYW5kbGVyICE9IGhhbmRsZXItPmFjY2Vzc19tZXRob2QpICYmCiAgICAgICAoTlVMTCAhPSBoYW5kbGVyLT5uZXh0KSkgewogICAgICAgIC8qCiAgICAgICAgICogYWx3YXlzIHdhcm4gaWYgY2FsbGVkIHdpdGhvdXQgb3VyIG93biBoYW5kbGVyLiBJZiB3ZQogICAgICAgICAqIGhhdmUgb3VyIG93biBoYW5kbGVyLCB1c2UgY3VzdG9tIGJpdCAxIHRvIG9ubHkgbG9nIG9uY2UuCiAgICAgICAgICovCiAgICAgICAgaWYoKHNwYXJzZV90YWJsZV9oZWxwZXJfaGFuZGxlciAhPSBoYW5kbGVyLT5hY2Nlc3NfbWV0aG9kKSB8fAogICAgICAgICAgICEoaGFuZGxlci0+ZmxhZ3MgJiBNSUJfSEFORExFUl9DVVNUT00xKSkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywgImhhbmRsZXIgKCVzKSByZWdpc3RlcmVkIGFmdGVyIHNwYXJzZSB0YWJsZSAiCiAgICAgICAgICAgICAgICAgICAgICJoYW5kZXIgd2lsbCBub3QgYmUgY2FsbGVkXG4iLAogICAgICAgICAgICAgICAgICAgICBoYW5kbGVyLT5uZXh0LT5oYW5kbGVyX25hbWUgPwogICAgICAgICAgICAgICAgICAgICBoYW5kbGVyLT5uZXh0LT5oYW5kbGVyX25hbWUgOiAiIiApOwogICAgICAgICAgICBpZihzcGFyc2VfdGFibGVfaGVscGVyX2hhbmRsZXIgPT0gaGFuZGxlci0+YWNjZXNzX21ldGhvZCkKICAgICAgICAgICAgICAgIGhhbmRsZXItPmZsYWdzIHw9IE1JQl9IQU5ETEVSX0NVU1RPTTE7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfR0VUTkVYVCkgewogICAgICAgIGZvcihyZXF1ZXN0ID0gcmVxdWVzdHMgOyByZXF1ZXN0OyByZXF1ZXN0ID0gcmVxdWVzdC0+bmV4dCkgewogICAgICAgICAgICBpZiAoKHJlcXVlc3QtPnJlcXVlc3R2Yi0+dHlwZSA9PSBBU05fTlVMTCAmJiByZXF1ZXN0LT5wcm9jZXNzZWQpIHx8CiAgICAgICAgICAgICAgICByZXF1ZXN0LT5kZWxlZ2F0ZWQpCiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgaWYgKHJlcXVlc3QtPnJlcXVlc3R2Yi0+dHlwZSA9PSBTTk1QX05PU1VDSElOU1RBTkNFKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogZ2V0IG5leHQgc2tpcHBlZCB0aGlzIHZhbHVlIGZvciB0aGlzIGNvbHVtbiwgd2UKICAgICAgICAgICAgICAgICAqIG5lZWQgdG8ga2VlcCBzZWFyY2hpbmcgZm9yd2FyZCAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgREVCVUdNU0dUKCgic3BhcnNlIiwgInJldHJ5IGZvciBOT1NVQ0hJTlNUQU5DRVxuIikpOwogICAgICAgICAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiLT50eXBlID0gQVNOX1BSSVZfUkVUUlk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKHJlcXVlc3QtPnJlcXVlc3R2Yi0+dHlwZSA9PSBTTk1QX05PU1VDSE9CSkVDVCB8fAogICAgICAgICAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiLT50eXBlID09IFNOTVBfRU5ET0ZNSUJWSUVXKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogZ2V0IG5leHQgaGFzIGNvbXBsZXRlbHkgZmluaXNoZWQgd2l0aCB0aGlzIGNvbHVtbiwKICAgICAgICAgICAgICAgICAqIHNvIHdlIG5lZWQgdG8gdHJ5IHdpdGggdGhlIG5leHQgY29sdW1uIChpZiBhbnkpCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIERFQlVHTVNHVCgoInNwYXJzZSIsICJyZXRyeSBmb3IgTk9TVUNIT0JKRUNUXG4iKSk7CiAgICAgICAgICAgICAgICB0YWJsZV9pbmZvID0gbmV0c25tcF9leHRyYWN0X3RhYmxlX2luZm8ocmVxdWVzdCk7CiAgICAgICAgICAgICAgICB0YWJsZV9pbmZvLT5jb2xudW0gPSBuZXRzbm1wX3RhYmxlX25leHRfY29sdW1uKHRhYmxlX2luZm8pOwogICAgICAgICAgICAgICAgaWYgKDAgIT0gdGFibGVfaW5mby0+Y29sbnVtKSB7CiAgICAgICAgICAgICAgICAgICAgbWVtY3B5KGNvbG9pZCwgcmVnaW5mby0+cm9vdG9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW5mby0+cm9vdG9pZF9sZW4gKiBzaXplb2Yob2lkKSk7CiAgICAgICAgICAgICAgICAgICAgY29sb2lkW3JlZ2luZm8tPnJvb3RvaWRfbGVuXSAgID0gMTsgICAvKiB0YWJsZS5lbnRyeSBub2RlICovCiAgICAgICAgICAgICAgICAgICAgY29sb2lkW3JlZ2luZm8tPnJvb3RvaWRfbGVuKzFdID0gdGFibGVfaW5mby0+Y29sbnVtOwogICAgICAgICAgICAgICAgICAgIHNubXBfc2V0X3Zhcl9vYmppZChyZXF1ZXN0LT5yZXF1ZXN0dmIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9pZCwgcmVnaW5mby0+cm9vdG9pZF9sZW4gKyAyKTsKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yZXF1ZXN0dmItPnR5cGUgPSBBU05fUFJJVl9SRVRSWTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogSWYgd2UgZG9uJ3QgaGF2ZSBjb2x1bW4gaW5mbywgcmVzZXQgdG8gbnVsbCBzbwogICAgICAgICAgICAgICAgICAgICAqIHRoZSBhZ2VudCB3aWxsIG1vdmUgb24gdG8gdGhlIG5leHQgdGFibGUuCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiLT50eXBlID0gQVNOX05VTEw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gc3RhdHVzOwp9CgovKiogY3JlYXRlIHNwYXJzZSB0YWJsZSBoYW5kbGVyCiAqLwpuZXRzbm1wX21pYl9oYW5kbGVyICoKbmV0c25tcF9zcGFyc2VfdGFibGVfaGFuZGxlcl9nZXQodm9pZCkKewogICAgcmV0dXJuIG5ldHNubXBfY3JlYXRlX2hhbmRsZXIoU1BBUlNFX1RBQkxFX0hBTkRMRVJfTkFNRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYXJzZV90YWJsZV9oZWxwZXJfaGFuZGxlcik7Cn0KCi8qKiBjcmVhdGVzIGEgdGFibGUgaGFuZGxlciBnaXZlbiB0aGUgbmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyBvYmplY3QsCiAqICBpbnNlcnRzIGl0IGludG8gdGhlIHJlcXVlc3QgY2hhaW4gYW5kIHRoZW4gY2FsbHMKICogIG5ldHNubXBfcmVnaXN0ZXJfaGFuZGxlcigpIHRvIHJlZ2lzdGVyIHRoZSB0YWJsZSBpbnRvIHRoZSBhZ2VudC4KICovCmludApuZXRzbm1wX3NwYXJzZV90YWJsZV9yZWdpc3RlcihuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gKnRhYnJlcSkKewogICAgbmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlcjEsICpoYW5kbGVyMjsKICAgIGludCByYzsKCiAgICBoYW5kbGVyMSA9IG5ldHNubXBfY3JlYXRlX2hhbmRsZXIoU1BBUlNFX1RBQkxFX0hBTkRMRVJfTkFNRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYXJzZV90YWJsZV9oZWxwZXJfaGFuZGxlcik7CiAgICBpZiAoTlVMTCA9PSBoYW5kbGVyMSkKICAgICAgICByZXR1cm4gU05NUF9FUlJfR0VORVJSOwoKICAgIGhhbmRsZXIyID0gbmV0c25tcF9nZXRfdGFibGVfaGFuZGxlcih0YWJyZXEpOwogICAgaWYgKE5VTEwgPT0gaGFuZGxlcjIgKSB7CiAgICAgICAgbmV0c25tcF9oYW5kbGVyX2ZyZWUoaGFuZGxlcjEpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICB9CgogICAgcmMgPSBuZXRzbm1wX2luamVjdF9oYW5kbGVyKHJlZ2luZm8sIGhhbmRsZXIxKTsKICAgIGlmIChTTk1QRVJSX1NVQ0NFU1MgIT0gcmMpIHsKICAgICAgICBuZXRzbm1wX2hhbmRsZXJfZnJlZShoYW5kbGVyMSk7CiAgICAgICAgbmV0c25tcF9oYW5kbGVyX2ZyZWUoaGFuZGxlcjIpOwogICAgICAgIHJldHVybiByYzsKICAgIH0KCiAgICByYyA9IG5ldHNubXBfaW5qZWN0X2hhbmRsZXIocmVnaW5mbywgaGFuZGxlcjIpOwogICAgaWYgKFNOTVBFUlJfU1VDQ0VTUyAhPSByYykgewogICAgICAgIC8qKiBoYW5kbGVyMSBpcyBpbiByZWdpbmZvLi4uIHJlbW92ZSBhbmQgZnJlZT8/ICovCiAgICAgICAgbmV0c25tcF9oYW5kbGVyX2ZyZWUoaGFuZGxlcjIpOwogICAgICAgIHJldHVybiByYzsKICAgIH0KCiAgICAvKiogYm90aCBoYW5kbGVycyBub3cgaW4gcmVnaW5mbywgc28gbm90aGluZyB0byBkbyBvbiBlcnJvciAqLwogICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfaGFuZGxlcihyZWdpbmZvKTsKfQoKCi8qKiBCdWlsZHMgdGhlIHJlc3VsdCB0byBiZSByZXR1cm5lZCB0byB0aGUgYWdlbnQgZ2l2ZW4gdGhlIHRhYmxlIGluZm9ybWF0aW9uLgogKiAgVXNlIHRoaXMgZnVuY3Rpb24gdG8gcmV0dXJuIHJlc3VsdHMgZnJvbSBsb3dlbCBsZXZlbCBoYW5kbGVycyB0bwogKiAgdGhlIGFnZW50LiAgSXQgdGFrZXMgY2FyZSBvZiBidWlsZGluZyB0aGUgcHJvcGVyIHJlc3VsdGluZyBvaWQKICogIChjb250YWluaW5nIHByb3BlciBpbmRleGluZykgYW5kIGluc2VydHMgdGhlIHJlc3VsdCB2YWx1ZSBpbnRvIHRoZQogKiAgcmV0dXJuaW5nIHZhcmJpbmQuCiAqLwppbnQKbmV0c25tcF90YWJsZV9idWlsZF9yZXN1bHQobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvICp0YWJsZV9pbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICB1X2NoYXIgdHlwZSwgdV9jaGFyICogcmVzdWx0LCBzaXplX3QgcmVzdWx0X2xlbikKewoKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFyOwoKICAgIGlmICghcmVxaW5mbyB8fCAhdGFibGVfaW5mbykKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CgogICAgdmFyID0gcmVxaW5mby0+cmVxdWVzdHZiOwoKICAgIGlmICh2YXItPm5hbWUgIT0gdmFyLT5uYW1lX2xvYykKICAgICAgICBmcmVlKHZhci0+bmFtZSk7CiAgICB2YXItPm5hbWUgPSBOVUxMOwoKICAgIGlmIChuZXRzbm1wX3RhYmxlX2J1aWxkX29pZChyZWdpbmZvLCByZXFpbmZvLCB0YWJsZV9pbmZvKSAhPQogICAgICAgIFNOTVBFUlJfU1VDQ0VTUykKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CgogICAgc25tcF9zZXRfdmFyX3R5cGVkX3ZhbHVlKHZhciwgdHlwZSwgcmVzdWx0LCByZXN1bHRfbGVuKTsKCiAgICByZXR1cm4gU05NUEVSUl9TVUNDRVNTOwp9CgoKLyoqIGdpdmVuIGEgcmVnaXN0cmF0aW9uIGluZm8gb2JqZWN0LCBhIHJlcXVlc3Qgb2JqZWN0IGFuZCB0aGUgdGFibGUKICogIGluZm8gb2JqZWN0IGl0IGJ1aWxkcyB0aGUgcmVxdWVzdC0+cmVxdWVzdHZiLT5uYW1lIG9pZCBmcm9tIHRoZQogKiAgaW5kZXggdmFsdWVzIGFuZCBjb2x1bW4gaW5mb3JtYXRpb24gZm91bmQgaW4gdGhlIHRhYmxlX2luZm8KICogIG9iamVjdC4gSW5kZXggdmFsdWVzIGFyZSBleHRyYWN0ZWQgZnJvbSB0aGUgdGFibGVfaW5mbyB2YXJiaW5kcy4KICovCmludApuZXRzbm1wX3RhYmxlX2J1aWxkX29pZChuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF90YWJsZV9yZXF1ZXN0X2luZm8gKnRhYmxlX2luZm8pCnsKICAgIG9pZCAgICAgICAgICAgICB0bXBvaWRbTUFYX09JRF9MRU5dOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXI7CgogICAgaWYgKCFyZWdpbmZvIHx8ICFyZXFpbmZvIHx8ICF0YWJsZV9pbmZvKQogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKCiAgICAvKgogICAgICogeHh4LXJrczogaW5lZmZpY2VudC4gd2UgZG8gYSBjb3B5IGhlcmUsIHRoZW4gYnVpbGRfb2lkIGRvZXMgaXQKICAgICAqICAgICAgICAgIGFnYWluLiBlaXRoZXIgY29tZSB1cCB3aXRoIGEgbmV3IHV0aWxpdHkgcm91dGluZSwgb3IKICAgICAqICAgICAgICAgIGRvIHNvbWUgaGlqaW5rcyBoZXJlIHRvIGVsaW1pbmF0ZSBleHRyYSBjb3B5LgogICAgICogICAgICAgICAgUHJvYmFibHkgY291bGQgbWFrZSBzdXJlIGFsbCBjYWxsZXJzIGhhdmUgdGhlCiAgICAgKiAgICAgICAgICBpbmRleCAmIHZhcmlhYmxlIGxpc3QgdXBkYXRlZCwgYW5kIHVzZQogICAgICogICAgICAgICAgbmV0c25tcF90YWJsZV9idWlsZF9vaWRfZnJvbV9pbmRleCgpIGluc3RlYWQgb2YgYWxsIHRoaXMuCiAgICAgKi8KICAgIG1lbWNweSh0bXBvaWQsIHJlZ2luZm8tPnJvb3RvaWQsIHJlZ2luZm8tPnJvb3RvaWRfbGVuICogc2l6ZW9mKG9pZCkpOwogICAgdG1wb2lkW3JlZ2luZm8tPnJvb3RvaWRfbGVuXSA9IDE7ICAgLyoqIC5FbnRyeSAqLwogICAgdG1wb2lkW3JlZ2luZm8tPnJvb3RvaWRfbGVuICsgMV0gPSB0YWJsZV9pbmZvLT5jb2xudW07IC8qKiAuY29sdW1uICovCgogICAgdmFyID0gcmVxaW5mby0+cmVxdWVzdHZiOwogICAgaWYgKGJ1aWxkX29pZCgmdmFyLT5uYW1lLCAmdmFyLT5uYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgdG1wb2lkLCByZWdpbmZvLT5yb290b2lkX2xlbiArIDIsIHRhYmxlX2luZm8tPmluZGV4ZXMpCiAgICAgICAgIT0gU05NUEVSUl9TVUNDRVNTKQogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKCiAgICByZXR1cm4gU05NUEVSUl9TVUNDRVNTOwp9CgovKiogZ2l2ZW4gYSByZWdpc3RyYXRpb24gaW5mbyBvYmplY3QsIGEgcmVxdWVzdCBvYmplY3QgYW5kIHRoZSB0YWJsZQogKiAgaW5mbyBvYmplY3QgaXQgYnVpbGRzIHRoZSByZXF1ZXN0LT5yZXF1ZXN0dmItPm5hbWUgb2lkIGZyb20gdGhlCiAqICBpbmRleCB2YWx1ZXMgYW5kIGNvbHVtbiBpbmZvcm1hdGlvbiBmb3VuZCBpbiB0aGUgdGFibGVfaW5mbwogKiAgb2JqZWN0LiAgSW5kZXggdmFsdWVzIGFyZSBleHRyYWN0ZWQgZnJvbSB0aGUgdGFibGVfaW5mbyBpbmRleCBvaWQuCiAqLwppbnQKbmV0c25tcF90YWJsZV9idWlsZF9vaWRfZnJvbV9pbmRleChuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvICp0YWJsZV9pbmZvKQp7CiAgICBvaWQgICAgICAgICAgICAgdG1wb2lkW01BWF9PSURfTEVOXTsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFyOwogICAgaW50ICAgICAgICAgICAgIGxlbjsKCiAgICBpZiAoIXJlZ2luZm8gfHwgIXJlcWluZm8gfHwgIXRhYmxlX2luZm8pCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwoKICAgIHZhciA9IHJlcWluZm8tPnJlcXVlc3R2YjsKICAgIGxlbiA9IHJlZ2luZm8tPnJvb3RvaWRfbGVuOwogICAgbWVtY3B5KHRtcG9pZCwgcmVnaW5mby0+cm9vdG9pZCwgbGVuICogc2l6ZW9mKG9pZCkpOwogICAgdG1wb2lkW2xlbisrXSA9IDE7ICAgICAgICAgIC8qIC5FbnRyeSAqLwogICAgdG1wb2lkW2xlbisrXSA9IHRhYmxlX2luZm8tPmNvbG51bTsgLyogLmNvbHVtbiAqLwogICAgbWVtY3B5KCZ0bXBvaWRbbGVuXSwgdGFibGVfaW5mby0+aW5kZXhfb2lkLAogICAgICAgICAgIHRhYmxlX2luZm8tPmluZGV4X29pZF9sZW4gKiBzaXplb2Yob2lkKSk7CiAgICBsZW4gKz0gdGFibGVfaW5mby0+aW5kZXhfb2lkX2xlbjsKICAgIHNubXBfc2V0X3Zhcl9vYmppZCggdmFyLCB0bXBvaWQsIGxlbiApOwoKICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7Cn0KCi8qKiBwYXJzZXMgYW4gT0lEIGludG8gdGFibGUgaW5kZXhzZXMgKi8KaW50Cm5ldHNubXBfdXBkYXRlX3ZhcmlhYmxlX2xpc3RfZnJvbV9pbmRleChuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyAqdHJpKQp7CiAgICBpZiAoIXRyaSkKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CgogICAgLyoKICAgICAqIGZyZWUgYW55IGV4aXN0aW5nIGFsbG9jYXRlZCBtZW1vcnksIHRoZW4gcGFyc2Ugb2lkIGludG8gdmFyYmluZHMKICAgICAqLwogICAgc25tcF9yZXNldF92YXJfYnVmZmVycyggdHJpLT5pbmRleGVzKTsKCiAgICByZXR1cm4gcGFyc2Vfb2lkX2luZGV4ZXModHJpLT5pbmRleF9vaWQsIHRyaS0+aW5kZXhfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmktPmluZGV4ZXMpOwp9CgovKiogYnVpbGRzIGFuIG9pZCBnaXZlbiBhIHNldCBvZiBpbmRleGVzLiAqLwppbnQKbmV0c25tcF91cGRhdGVfaW5kZXhlc19mcm9tX3ZhcmlhYmxlX2xpc3QobmV0c25tcF90YWJsZV9yZXF1ZXN0X2luZm8gKnRyaSkKewogICAgaWYgKCF0cmkpCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwoKICAgIHJldHVybiBidWlsZF9vaWRfbm9hbGxvYyh0cmktPmluZGV4X29pZCwgc2l6ZW9mKHRyaS0+aW5kZXhfb2lkKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdHJpLT5pbmRleF9vaWRfbGVuLCBOVUxMLCAwLCB0cmktPmluZGV4ZXMpOwp9CgovKioKICogY2hlY2tzIHRoZSBvcmlnaW5hbCByZXF1ZXN0IGFnYWluc3QgdGhlIGN1cnJlbnQgZGF0YSBiZWluZyBwYXNzZWQgaW4gaWYgCiAqIGl0cyBncmVhdGVyIHRoYW4gdGhlIHJlcXVlc3Qgb2lkIGJ1dCBsZXNzIHRoYW4gdGhlIGN1cnJlbnQgdmFsaWQKICogcmV0dXJuLCBzZXQgdGhlIGN1cnJlbnQgdmFsaWQgcmV0dXJuIHRvIHRoZSBuZXcgdmFsdWUuCiAqIAogKiByZXR1cm5zIDEgaWYgb3V0dmFyIHdhcyByZXBsYWNlZCB3aXRoIHRoZSBvaWQgZnJvbSBuZXd2YXIgKHN1Y2Nlc3MpLgogKiByZXR1cm5zIDAgaWYgbm90LiAKICovCmludApuZXRzbm1wX2NoZWNrX2dldG5leHRfcmVwbHkobmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvaWQgKiBwcmVmaXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgcHJlZml4X2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqIG5ld3ZhciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqKiBvdXR2YXIpCnsKICAgIG9pZCAgICAgIG15bmFtZVtNQVhfT0lEX0xFTl07CiAgICBzaXplX3QgICBteW5hbWVfbGVuOwoKICAgIGJ1aWxkX29pZF9ub2FsbG9jKG15bmFtZSwgTUFYX09JRF9MRU4sICZteW5hbWVfbGVuLAogICAgICAgICAgICAgICAgICAgICAgcHJlZml4LCBwcmVmaXhfbGVuLCBuZXd2YXIpOwogICAgLyoKICAgICAqIGlzIHRoZSBidWlsZCBvZiB0aGUgbmV3IGluZGV4ZXMgbGVzcyB0aGFuIG91ciBjdXJyZW50IHJlc3VsdCAKICAgICAqLwogICAgaWYgKCghKCpvdXR2YXIpIHx8IHNubXBfb2lkX2NvbXBhcmUobXluYW1lICsgcHJlZml4X2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG15bmFtZV9sZW4gLSBwcmVmaXhfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCpvdXR2YXIpLT5uYW1lICsgcHJlZml4X2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqb3V0dmFyKS0+bmFtZV9sZW5ndGggLQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4X2xlbikgPCAwKSkgewogICAgICAgIC8qCiAgICAgICAgICogYW5kIGdyZWF0ZXIgdGhhbiB0aGUgcmVxdWVzdGVkIG9pZCAKICAgICAgICAgKi8KICAgICAgICBpZiAoc25tcF9vaWRfY29tcGFyZShteW5hbWUsIG15bmFtZV9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiLT5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJlcXVlc3R2Yi0+bmFtZV9sZW5ndGgpID4gMCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiB0aGUgbmV3IHJlc3VsdCBtdXN0IGJlIGJldHRlciB0aGFuIHRoZSBvbGQgCiAgICAgICAgICAgICAqLwojaWZkZWYgT05MWV9XT1JLU19XSVRIX09ORV9WQVJCSU5ECiAgICAgICAgICAgIGlmICghKm91dHZhcikKICAgICAgICAgICAgICAgICpvdXR2YXIgPSBzbm1wX2Nsb25lX3ZhcmJpbmQobmV3dmFyKTsKCSAgICBlbHNlCiAgICAgICAgICAgICAgICAvKiAKICAgICAgICAgICAgICAgICAqIFRPRE86IHdhbGsgdGhlIGZ1bGwgdmFyYmluZCBsaXN0LCBzZXR0aW5nCiAgICAgICAgICAgICAgICAgKiAgICAgICAqYWxsKiB0aGUgdmFsdWVzIC0gbm90IGp1c3QgdGhlIGZpcnN0LgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBzbm1wX3NldF92YXJfdHlwZWRfdmFsdWUoKm91dHZhciwgbmV3dmFyLT50eXBlLAoJCQkJbmV3dmFyLT52YWwuc3RyaW5nLCBuZXd2YXItPnZhbF9sZW4pOwojZWxzZSAgLyogSW50ZXJpbSByZXBsYWNlbWVudCBhcHByb2FjaCAtIGxlc3MgZWZmaWNpZW50LCBidXQgaXQgd29ya3MhICovCiAgICAgICAgICAgIGlmICgqb3V0dmFyKQogICAgICAgICAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQoKm91dHZhcik7CiAgICAgICAgICAgICpvdXR2YXIgPSBzbm1wX2Nsb25lX3ZhcmJpbmQobmV3dmFyKTsKI2VuZGlmCiAgICAgICAgICAgIHNubXBfc2V0X3Zhcl9vYmppZCgqb3V0dmFyLCBteW5hbWUsIG15bmFtZV9sZW4pOwoKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIDA7Cn0KCnZvaWQKbmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mb19mcmVlKG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gKnRyaSkKewogICAgaWYgKE5VTEwgPT0gdHJpKQogICAgICAgIHJldHVybjsKCiAgICBpZiAoTlVMTCAhPSB0cmktPmluZGV4ZXMpCiAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQodHJpLT5pbmRleGVzKTsKCiNpZiAwCiAgICAvKgogICAgICogc2lnaC4uLiBleGFtcGxlIHVzZSBvZiB2YWxpZF9jb2x1bW5zIHBvaW50cyB0byBzdGF0aWMgbWVtb3J5LAogICAgICogc28gZnJlZWluZyBpdCB3b3VsZCBiZSBiYWQuLi4gd2UnbGwganVzdCBoYXZlIHRvIGxpdmUgd2l0aCBhbnkKICAgICAqIGxlYWtzLCBmb3Igbm93Li4uCiAgICAgKi8KI2VuZGlmCgogICAgZnJlZSh0cmkpOwp9CgovKiogQH0gKi8KCi8qCiAqIGludGVybmFsIHJvdXRpbmVzIAogKi8Kdm9pZAp0YWJsZV9kYXRhX2ZyZWVfZnVuYyh2b2lkICpkYXRhKQp7CiAgICBuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyAqaW5mbyA9IChuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyAqKSBkYXRhOwogICAgaWYgKCFpbmZvKQogICAgICAgIHJldHVybjsKICAgIHNubXBfZnJlZV92YXJiaW5kKGluZm8tPmluZGV4ZXMpOwogICAgZnJlZShpbmZvKTsKfQoKCgpzdGF0aWMgdm9pZAp0YWJsZV9oZWxwZXJfY2xlYW51cChuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbyAqcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3QsIGludCBzdGF0dXMpCnsKICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdCwgc3RhdHVzKTsKICAgIG5ldHNubXBfZnJlZV9yZXF1ZXN0X2RhdGFfc2V0cyhyZXF1ZXN0KTsKICAgIGlmICghcmVxdWVzdCkKICAgICAgICByZXR1cm47CiAgICByZXF1ZXN0LT5wYXJlbnRfZGF0YSA9IE5VTEw7Cn0KCgovKgogKiBmaW5kIHRoZSBjbG9zZXN0IGNvbHVtbiB0byBjdXJyZW50ICh3aGljaCBtYXkgYmUgY3VycmVudCkuCiAqCiAqIGNhbGxlZCB3aGVuIGEgdGFibGUgcnVucyBvdXQgb2Ygcm93cyBmb3IgY29sdW1uIFguIFRoaXMKICogZnVuY3Rpb24gaXMgY2FsbGVkIHdpdGggY3VycmVudCA9IFggKyAxLCB0byB2ZXJpZnkgdGhhdAogKiBYICsgMSBpcyBhIHZhbGlkIGNvbHVtbiwgb3IgZmluZCB0aGUgbmV4dCBjbG9zZXN0IGNvbHVtbiBpZiBub3QuCiAqCiAqIEFsbCBsaXN0IHR5cGVzIHNob3VsZCBiZSBzb3J0ZWQsIGxvd2VzdCB0byBoaWdoZXN0LgogKi8KdW5zaWduZWQgaW50Cm5ldHNubXBfY2xvc2VzdF9jb2x1bW4odW5zaWduZWQgaW50IGN1cnJlbnQsCiAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9jb2x1bW5faW5mbyAqdmFsaWRfY29sdW1ucykKewogICAgdW5zaWduZWQgaW50ICAgIGNsb3Nlc3QgPSAwOwogICAgaW50ICAgICAgICAgICAgIGlkeDsKCiAgICBpZiAodmFsaWRfY29sdW1ucyA9PSBOVUxMKQogICAgICAgIHJldHVybiAwOwoKICAgIGZvciggOyB2YWxpZF9jb2x1bW5zOyB2YWxpZF9jb2x1bW5zID0gdmFsaWRfY29sdW1ucy0+bmV4dCkgewoKICAgICAgICBpZiAodmFsaWRfY29sdW1ucy0+aXNSYW5nZSkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBpZiBjdXJyZW50IDwgbG93IHJhbmdlLCBpdCBtaWdodCBiZSBjbG9zZXN0LgogICAgICAgICAgICAgKiBvdGhlcndpc2UsIGlmIGl0J3MgPCBoaWdoIHJhbmdlLCBjdXJyZW50IGlzIGluCiAgICAgICAgICAgICAqIHRoZSByYW5nZSwgYW5kIHRodXMgaXMgYW4gZXhhY3QgbWF0Y2guCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoY3VycmVudCA8IHZhbGlkX2NvbHVtbnMtPmRldGFpbHMucmFuZ2VbMF0pIHsKICAgICAgICAgICAgICAgIGlmICggKHZhbGlkX2NvbHVtbnMtPmRldGFpbHMucmFuZ2VbMF0gPCBjbG9zZXN0KSB8fAogICAgICAgICAgICAgICAgICAgICAoMCA9PSBjbG9zZXN0KSkgewogICAgICAgICAgICAgICAgICAgIGNsb3Nlc3QgPSB2YWxpZF9jb2x1bW5zLT5kZXRhaWxzLnJhbmdlWzBdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgaWYgKGN1cnJlbnQgPD0gdmFsaWRfY29sdW1ucy0+ZGV0YWlscy5yYW5nZVsxXSkgewogICAgICAgICAgICAgICAgY2xvc2VzdCA9IGN1cnJlbnQ7CiAgICAgICAgICAgICAgICBicmVhazsgICAgICAgLyogY2FuIG5vdCBnZXQgYW55IGNsb3NlciEgKi8KICAgICAgICAgICAgfQoKICAgICAgICB9IC8qIHJhbmdlICovCiAgICAgICAgZWxzZSB7ICAgICAgICAgICAgICAgICAgLyogbGlzdCAqLwogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBpZiBjdXJyZW50IDwgZmlyc3QgaXRlbSwgbm8gbmVlZCB0byBpdGVyYXRlIG92ZXIgbGlzdC4KICAgICAgICAgICAgICogdGhhdCBpdGVtIGlzIGVpdGhlciBjbG9zZXN0LCBvciBub3QuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoY3VycmVudCA8IHZhbGlkX2NvbHVtbnMtPmRldGFpbHMubGlzdFswXSkgewogICAgICAgICAgICAgICAgaWYgKCh2YWxpZF9jb2x1bW5zLT5kZXRhaWxzLmxpc3RbMF0gPCBjbG9zZXN0KSB8fAogICAgICAgICAgICAgICAgICAgICgwID09IGNsb3Nlc3QpKQogICAgICAgICAgICAgICAgICAgIGNsb3Nlc3QgPSB2YWxpZF9jb2x1bW5zLT5kZXRhaWxzLmxpc3RbMF07CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoqIGlmIGN1cnJlbnQgPiBsYXN0IGl0ZW0gaW4gbGlzdCwgbm8gbmVlZCB0byBpdGVyYXRlICovCiAgICAgICAgICAgIGlmIChjdXJyZW50ID4KICAgICAgICAgICAgICAgIHZhbGlkX2NvbHVtbnMtPmRldGFpbHMubGlzdFsoaW50KXZhbGlkX2NvbHVtbnMtPmxpc3RfY291bnQgLSAxXSkKICAgICAgICAgICAgICAgIGNvbnRpbnVlOyAgICAgICAvKiBub3QgaW4gbGlzdCByYW5nZS4gKi8KCiAgICAgICAgICAgIC8qKiBza2lwIGFueXRoaW5nIGxlc3MgdGhhbiBjdXJyZW50Ki8KICAgICAgICAgICAgZm9yIChpZHggPSAwOyB2YWxpZF9jb2x1bW5zLT5kZXRhaWxzLmxpc3RbaWR4XSA8IGN1cnJlbnQ7ICsraWR4KQogICAgICAgICAgICAgICAgOwogICAgICAgICAgICAKICAgICAgICAgICAgLyoqIGNoZWNrIGZvciBleGFjdCBtYXRjaCAqLwogICAgICAgICAgICBpZiAoY3VycmVudCA9PSB2YWxpZF9jb2x1bW5zLT5kZXRhaWxzLmxpc3RbaWR4XSkgewogICAgICAgICAgICAgICAgY2xvc2VzdCA9IGN1cnJlbnQ7CiAgICAgICAgICAgICAgICBicmVhazsgICAgICAvKiBjYW4gbm90IGdldCBhbnkgY2xvc2VyISAqLwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAvKiogbGlzdFtpZHhdID4gY3VycmVudDsgaXMgaXQgPCBjbG9zZXN0PyAqLwogICAgICAgICAgICBpZiAoKHZhbGlkX2NvbHVtbnMtPmRldGFpbHMubGlzdFtpZHhdIDwgY2xvc2VzdCkgfHwKICAgICAgICAgICAgICAgICgwID09IGNsb3Nlc3QpKQogICAgICAgICAgICAgICAgY2xvc2VzdCA9IHZhbGlkX2NvbHVtbnMtPmRldGFpbHMubGlzdFtpZHhdOwoKICAgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAvKiBsaXN0ICovCiAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZm9yICovCgogICAgcmV0dXJuIGNsb3Nlc3Q7Cn0KCi8qKgogKiBUaGlzIGZ1bmN0aW9uIGNhbiBiZSB1c2VkIHRvIHNldHVwIHRoZSB0YWJsZSdzIGRlZmluaXRpb24gd2l0aGluCiAqIHlvdXIgbW9kdWxlJ3MgaW5pdGlhbGl6ZSBmdW5jdGlvbiwgaXQgdGFrZXMgYSB2YXJpYWJsZSBpbmRleCBwYXJhbWV0ZXIgbGlzdAogKiBmb3IgZXhhbXBsZTogdGhlIHRhYmxlX2luZm8gc3RydWN0dXJlIGlzIGZvbGxvd2VkIGJ5IHR3byBpbnRlZ2VyIGluZGV4IHR5cGVzCiAqIG5ldHNubXBfdGFibGVfaGVscGVyX2FkZF9pbmRleGVzKAogKiAgICAgICAgICAgICAgICAgIHRhYmxlX2luZm8sICAgCiAqCSAgICAgICAgICAgIEFTTl9JTlRFR0VSLCAgCiAqCQkgICAgQVNOX0lOVEVHRVIsICAKICoJCSAgICAwKTsKICoKICogQHBhcmFtIHRpbmZvIGlzIGEgcG9pbnRlciB0byBhIG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gc3RydWN0LgogKglUaGUgdGFibGUgaGFuZGxlciBuZWVkcyB0byBrbm93IHVwIGZyb250IGhvdyB5b3VyIHRhYmxlIGlzIHN0cnVjdHVyZWQuCiAqCUEgbmV0c25tcF90YWJsZV9yZWdpc3RlcmF0aW9uX2luZm8gc3RydWN0dXJlIHRoYXQgaXMgCiAqCXBhc3NlZCB0byB0aGUgdGFibGUgaGFuZGxlciBzaG91bGQgY29udGFpbiB0aGUgYXNuIGluZGV4IHR5cGVzIGZvciB0aGUgCiAqCXRhYmxlIGFzIHdlbGwgYXMgdGhlIG1pbmltdW0gYW5kIG1heGltdW0gY29sdW1uIHRoYXQgc2hvdWxkIGJlIHVzZWQuCiAqCiAqIEByZXR1cm4gdm9pZAogKgogKi8Kdm9pZApuZXRzbm1wX3RhYmxlX2hlbHBlcl9hZGRfaW5kZXhlcyhuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvICp0aW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uKQp7CiAgICB2YV9saXN0ICAgICAgICAgZGVidWdhcmdzOwogICAgaW50ICAgICAgICAgICAgIHR5cGU7CgogICAgdmFfc3RhcnQoZGVidWdhcmdzLCB0aW5mbyk7CiAgICB3aGlsZSAoKHR5cGUgPSB2YV9hcmcoZGVidWdhcmdzLCBpbnQpKSAhPSAwKSB7CiAgICAgICAgbmV0c25tcF90YWJsZV9oZWxwZXJfYWRkX2luZGV4KHRpbmZvLCB0eXBlKTsKICAgIH0KICAgIHZhX2VuZChkZWJ1Z2FyZ3MpOwp9CgpzdGF0aWMgdm9pZApfcm93X3N0YXNoX2RhdGFfbGlzdF9mcmVlKHZvaWQgKnB0cikgewogICAgbmV0c25tcF9vaWRfc3Rhc2hfbm9kZSAqKnRtcCA9IChuZXRzbm1wX29pZF9zdGFzaF9ub2RlICoqKXB0cjsKICAgIG5ldHNubXBfb2lkX3N0YXNoX2ZyZWUodG1wLCBOVUxMKTsKICAgIGZyZWUocHRyKTsKfQoKLyoqIHJldHVybnMgYSByb3ctd2lkZSBwbGFjZSB0byBzdG9yZSBkYXRhIGluLgogICAgQHRvZG8gVGhpcyBmdW5jdGlvbiB3aWxsIGxpa2VseSBjaGFuZ2UgdG8gYWRkIGZyZWUgcG9pbnRlciBmdW5jdGlvbnMuICovCm5ldHNubXBfb2lkX3N0YXNoX25vZGUgKioKbmV0c25tcF90YWJsZV9nZXRfb3JfY3JlYXRlX3Jvd19zdGFzaChuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbyAqcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1X2NoYXIgKiBzdG9yYWdlX25hbWUpCnsKICAgIG5ldHNubXBfb2lkX3N0YXNoX25vZGUgKipzdGFzaHAgPSBOVUxMOwogICAgc3Rhc2hwID0gKG5ldHNubXBfb2lkX3N0YXNoX25vZGUgKiopCiAgICAgICAgbmV0c25tcF9hZ2VudF9nZXRfbGlzdF9kYXRhKHJlcWluZm8sIHN0b3JhZ2VfbmFtZSk7CgogICAgaWYgKCFzdGFzaHApIHsKICAgICAgICAvKgogICAgICAgICAqIGhhc24ndCBiZSBjcmVhdGVkIHlldC4gIHdlIGNyZWF0ZSBpdCBoZXJlLiAKICAgICAgICAgKi8KICAgICAgICBzdGFzaHAgPSBTTk1QX01BTExPQ19UWVBFREVGKG5ldHNubXBfb2lkX3N0YXNoX25vZGUgKik7CgogICAgICAgIGlmICghc3Rhc2hwKQogICAgICAgICAgICByZXR1cm4gTlVMTDsgICAgICAgIC8qIGFjay4gb3V0IG9mIG1lbSAqLwoKICAgICAgICBuZXRzbm1wX2FnZW50X2FkZF9saXN0X2RhdGEocmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9jcmVhdGVfZGF0YV9saXN0KHN0b3JhZ2VfbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXNocCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9yb3dfc3Rhc2hfZGF0YV9saXN0X2ZyZWUpKTsKICAgIH0KICAgIHJldHVybiBzdGFzaHA7Cn0KCi8qCiAqIGFkdmFuY2UgdGhlIHRhYmxlIGluZm8gY29sbnVtIHRvIHRoZSBuZXh0IGNvbHVtbiwgb3IgMCBpZiB0aGVyZSBhcmUgbm8gbW9yZQogKgogKiBAcmV0dXJuIG5ldyBjb2x1bW4sIG9yIDAgaWYgdGhlcmUgYXJlIG5vIG1vcmUKICovCnVuc2lnbmVkIGludApuZXRzbm1wX3RhYmxlX25leHRfY29sdW1uKG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvICp0YWJsZV9pbmZvKQp7CiAgICBpZiAoTlVMTCA9PSB0YWJsZV9pbmZvKQogICAgICAgIHJldHVybiAwOwoKICAgIC8qCiAgICAgKiB0cnkgYW5kIHZhbGlkYXRlIG5leHQgY29sdW1uCiAgICAgKi8KICAgIGlmICh0YWJsZV9pbmZvLT5yZWdfaW5mby0+dmFsaWRfY29sdW1ucykKICAgICAgICByZXR1cm4gbmV0c25tcF9jbG9zZXN0X2NvbHVtbih0YWJsZV9pbmZvLT5jb2xudW0gKyAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlX2luZm8tPnJlZ19pbmZvLT52YWxpZF9jb2x1bW5zKTsKICAgIAogICAgLyoKICAgICAqIGNhbid0IHZhbGlkYXRlLiBhc3N1bWUgMS4ubWF4X2NvbHVtbiBhcmUgdmFsaWQKICAgICAqLwogICAgaWYgKHRhYmxlX2luZm8tPmNvbG51bSA8IHRhYmxlX2luZm8tPnJlZ19pbmZvLT5tYXhfY29sdW1uKQogICAgICAgIHJldHVybiB0YWJsZV9pbmZvLT5jb2xudW0gKyAxOwogICAgCiAgICByZXR1cm4gMDsgLyogb3V0IG9mIHJhbmdlICovCn0K