LyoKICogIEFnZW50WCBtYXN0ZXIgYWdlbnQKICovCi8qIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvcHlyaWdodChzKS4gIFNlZQogKiB0aGUgTmV0LVNOTVAncyBDT1BZSU5HIGZpbGUgZm9yIG1vcmUgZGV0YWlscyBhbmQgb3RoZXIgY29weXJpZ2h0cwogKiB0aGF0IG1heSBhcHBseToKICovCi8qCiAqIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgY29weXJpZ2h0ZWQgYnk6CiAqIENvcHlyaWdodCCpIDIwMDMgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBVc2UgaXMgc3ViamVjdCB0byBsaWNlbnNlIHRlcm1zIHNwZWNpZmllZCBpbiB0aGUgQ09QWUlORyBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhlIE5ldC1TTk1QIHBhY2thZ2UuCiAqLwoKCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KI2lmIEhBVkVfSU9fSAojaW5jbHVkZSA8aW8uaD4KI2VuZGlmCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaWZkZWYgSEFWRV9TVERMSUJfSAojaW5jbHVkZSA8c3RkbGliLmg+CiNlbmRpZgojaWYgSEFWRV9TVFJJTkdfSAojaW5jbHVkZSA8c3RyaW5nLmg+CiNlbHNlCiNpbmNsdWRlIDxzdHJpbmdzLmg+CiNlbmRpZgojaWYgSEFWRV9ORVRJTkVUX0lOX0gKI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4KI2VuZGlmCiNpZiBIQVZFX1dJTlNPQ0tfSAojaW5jbHVkZSA8d2luc29jay5oPgojZW5kaWYKI2lmIEhBVkVfU1lTX1NPQ0tFVF9ICiNpbmNsdWRlIDxzeXMvc29ja2V0Lmg+CiNlbmRpZgojaW5jbHVkZSA8ZXJybm8uaD4KCiNpZiBIQVZFX1VOSVNURF9ICiNpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCiNpZmRlZiBIQVZFX1NZU19TVEFUX0gKI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNlbmRpZgoKI2RlZmluZSBTTk1QX05FRURfUkVRVUVTVF9MSVNUCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1pbmNsdWRlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvbmV0LXNubXAtYWdlbnQtaW5jbHVkZXMuaD4KI2luY2x1ZGUgInNubXBkLmgiCiNpbmNsdWRlICJhZ2VudHgvcHJvdG9jb2wuaCIKI2luY2x1ZGUgImFnZW50eC9tYXN0ZXJfYWRtaW4uaCIKCnZvaWQKcmVhbF9pbml0X21hc3Rlcih2b2lkKQp7CiAgICBuZXRzbm1wX3Nlc3Npb24gc2VzcywgKnNlc3Npb24gPSBOVUxMOwogICAgY2hhciAqYWdlbnR4X3NvY2tldHM7CiAgICBjaGFyICpjcDE7CgogICAgaWYgKG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19BUFBMSUNBVElPTl9JRCwgTkVUU05NUF9EU19BR0VOVF9ST0xFKSAhPSBNQVNURVJfQUdFTlQpCiAgICAgICAgcmV0dXJuOwoKICAgIGlmIChuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19BUFBMSUNBVElPTl9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19BR0VOVF9YX1NPQ0tFVCkpIHsKICAgICAgIGFnZW50eF9zb2NrZXRzID0gc3RyZHVwKG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0FQUExJQ0FUSU9OX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfQUdFTlRfWF9TT0NLRVQpKTsKI2lmZGVmIE5FVFNOTVBfQUdFTlRYX0RPTV9TT0NLX09OTFkKICAgICAgIGlmIChhZ2VudHhfc29ja2V0c1swXSAhPSAnLycpIHsKICAgICAgICAgICAvKiB1bml4Oi9wYXRoICovCiAgICAgICAgICAgaWYgKGFnZW50eF9zb2NrZXRzWzVdICE9ICcvJykgewogICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLAogICAgICAgICAgICAgICAgICAgICJFcnJvcjogJXMgdHJhbnNwb3J0IGlzIG5vdCBzdXBwb3J0ZWQsIGRpc2FibGluZyBhZ2VudHgvbWFzdGVyLlxuIiwgYWdlbnR4X3NvY2tldHMpOwogICAgICAgICAgICAgICBTTk1QX0ZSRUUoYWdlbnR4X3NvY2tldHMpOwogICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgfQogICAgICAgfQojZW5kaWYKICAgIH0gZWxzZSB7CiAgICAgICAgYWdlbnR4X3NvY2tldHMgPSBzdHJkdXAoIiIpOwogICAgfQoKCiAgICBERUJVR01TR1RMKCgiYWdlbnR4L21hc3RlciIsICJpbml0aWFsaXppbmcuLi5cbiIpKTsKICAgIHNubXBfc2Vzc19pbml0KCZzZXNzKTsKICAgIHNlc3MudmVyc2lvbiA9IEFHRU5UWF9WRVJTSU9OXzE7CiAgICBzZXNzLmZsYWdzIHw9IFNOTVBfRkxBR1NfU1RSRUFNX1NPQ0tFVDsKICAgIHNlc3MudGltZW91dCA9IG5ldHNubXBfZHNfZ2V0X2ludChORVRTTk1QX0RTX0FQUExJQ0FUSU9OX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfQUdFTlRfQUdFTlRYX1RJTUVPVVQpOwogICAgc2Vzcy5yZXRyaWVzID0gbmV0c25tcF9kc19nZXRfaW50KE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19BR0VOVF9BR0VOVFhfUkVUUklFUyk7CgojaWZkZWYgTkVUU05NUF9UUkFOU1BPUlRfVU5JWF9ET01BSU4KICAgIHsKCWludCBhZ2VudHhfZGlyX3Blcm0gPQoJICAgIG5ldHNubXBfZHNfZ2V0X2ludChORVRTTk1QX0RTX0FQUExJQ0FUSU9OX0lELAoJCQkgICAgICAgTkVUU05NUF9EU19BR0VOVF9YX0RJUl9QRVJNKTsKCWlmIChhZ2VudHhfZGlyX3Blcm0gPT0gMCkKCSAgICBhZ2VudHhfZGlyX3Blcm0gPSBORVRTTk1QX0FHRU5UX0RJUkVDVE9SWV9NT0RFOwoJbmV0c25tcF91bml4X2NyZWF0ZV9wYXRoX3dpdGhfbW9kZShhZ2VudHhfZGlyX3Blcm0pOwogICAgfQojZW5kaWYKCiAgICBjcDEgPSBhZ2VudHhfc29ja2V0czsKICAgIHdoaWxlIChjcDEpIHsKICAgICAgICBuZXRzbm1wX3RyYW5zcG9ydCAqdDsKICAgICAgICAvKgogICAgICAgICAqICBJZiB0aGUgQWdlbnRYIHNvY2tldCBzdHJpbmcgY29udGFpbnMgbXVsdGlwbGUgZGVzY3JpcHRvcnMsCiAgICAgICAgICogIHRoZW4gcGljayB0aGlzIGFwYXJ0IGFuZCBoYW5kbGUgdGhlbSBvbmUgYnkgb25lLgogICAgICAgICAqCiAgICAgICAgICovCiAgICAgICAgc2Vzcy5wZWVybmFtZSA9IGNwMTsKICAgICAgICBjcDEgPSBzdHJjaHIoc2Vzcy5wZWVybmFtZSwgJywnKTsKICAgICAgICBpZiAoY3AxICE9IE5VTEwpIHsKICAgICAgICAgICAgKmNwMSsrID0gJ1wwJzsKCX0KCiAgICAgICAgLyoKICAgICAgICAgKiAgTGV0ICdzbm1wX29wZW4nIGludGVycHJldCB0aGUgZGVzY3JpcHRvci4KICAgICAgICAgKi8KICAgICAgICBzZXNzLmxvY2FsX3BvcnQgPSBBR0VOVFhfUE9SVDsgICAgICAvKiBJbmRpY2F0ZSBzZXJ2ZXIgJiBzZXQgZGVmYXVsdCBwb3J0ICovCiAgICAgICAgc2Vzcy5yZW1vdGVfcG9ydCA9IDA7CiAgICAgICAgc2Vzcy5jYWxsYmFjayA9IGhhbmRsZV9tYXN0ZXJfYWdlbnR4X3BhY2tldDsKICAgICAgICBlcnJubyA9IDA7CiAgICAgICAgdCA9IG5ldHNubXBfdHJhbnNwb3J0X29wZW5fc2VydmVyKCJhZ2VudHgiLCBzZXNzLnBlZXJuYW1lKTsKICAgICAgICBpZiAodCA9PSBOVUxMKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGRpYWdub3NlIHNubXBfb3BlbiBlcnJvcnMgd2l0aCB0aGUgaW5wdXQgbmV0c25tcF9zZXNzaW9uCiAgICAgICAgICAgICAqIHBvaW50ZXIuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBjaGFyIGJ1ZlsxMDI0XTsKICAgICAgICAgICAgaWYgKCFuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0FHRU5UX05PX1JPT1RfQUNDRVNTKSkgewogICAgICAgICAgICAgICAgc25wcmludGYoYnVmLCBzaXplb2YoYnVmKSwKICAgICAgICAgICAgICAgICAgICAgICAgICJFcnJvcjogQ291bGRuJ3Qgb3BlbiBhIG1hc3RlciBhZ2VudHggc29ja2V0IHRvICIKICAgICAgICAgICAgICAgICAgICAgICAgICJsaXN0ZW4gb24gKCVzKSIsIHNlc3MucGVlcm5hbWUpOwogICAgICAgICAgICAgICAgc25tcF9zZXNzX3BlcnJvcihidWYsICZzZXNzKTsKICAgICAgICAgICAgICAgIGV4aXQoMSk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzbnByaW50ZihidWYsIHNpemVvZihidWYpLAogICAgICAgICAgICAgICAgICAgICAgICAgIldhcm5pbmc6IENvdWxkbid0IG9wZW4gYSBtYXN0ZXIgYWdlbnR4IHNvY2tldCB0byAiCiAgICAgICAgICAgICAgICAgICAgICAgICAibGlzdGVuIG9uICglcykiLCBzZXNzLnBlZXJuYW1lKTsKICAgICAgICAgICAgICAgIG5ldHNubXBfc2Vzc19sb2dfZXJyb3IoTE9HX1dBUk5JTkcsIGJ1ZiwgJnNlc3MpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKI2lmZGVmIE5FVFNOTVBfVFJBTlNQT1JUX1VOSVhfRE9NQUlOCiAgICAgICAgICAgIGlmICh0LT5kb21haW4gPT0gbmV0c25tcF9Vbml4RG9tYWluICYmIHQtPmxvY2FsICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBBcHBseSBhbnkgc2V0dGluZ3MgdG8gdGhlIG93bmVyc2hpcC9wZXJtaXNzaW9ucyBvZiB0aGUKICAgICAgICAgICAgICAgICAqIEFnZW50WCBzb2NrZXQKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaW50IGFnZW50eF9zb2NrX3Blcm0gPQogICAgICAgICAgICAgICAgICAgIG5ldHNubXBfZHNfZ2V0X2ludChORVRTTk1QX0RTX0FQUExJQ0FUSU9OX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0FHRU5UX1hfU09DS19QRVJNKTsKICAgICAgICAgICAgICAgIGludCBhZ2VudHhfc29ja191c2VyID0KICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2RzX2dldF9pbnQoTkVUU05NUF9EU19BUFBMSUNBVElPTl9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19BR0VOVF9YX1NPQ0tfVVNFUik7CiAgICAgICAgICAgICAgICBpbnQgYWdlbnR4X3NvY2tfZ3JvdXAgPQogICAgICAgICAgICAgICAgICAgIG5ldHNubXBfZHNfZ2V0X2ludChORVRTTk1QX0RTX0FQUExJQ0FUSU9OX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0FHRU5UX1hfU09DS19HUk9VUCk7CgogICAgICAgICAgICAgICAgY2hhciBuYW1lW3NpemVvZihzdHJ1Y3Qgc29ja2FkZHJfdW4pICsgMV07CiAgICAgICAgICAgICAgICBtZW1jcHkobmFtZSwgdC0+bG9jYWwsIHQtPmxvY2FsX2xlbmd0aCk7CiAgICAgICAgICAgICAgICBuYW1lW3QtPmxvY2FsX2xlbmd0aF0gPSAnXDAnOwoKICAgICAgICAgICAgICAgIGlmIChhZ2VudHhfc29ja19wZXJtICE9IDApCiAgICAgICAgICAgICAgICAgICAgY2htb2QobmFtZSwgYWdlbnR4X3NvY2tfcGVybSk7CgogICAgICAgICAgICAgICAgaWYgKGFnZW50eF9zb2NrX3VzZXIgfHwgYWdlbnR4X3NvY2tfZ3JvdXApIHsKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIElmIGVpdGhlciBvZiB1c2VyIG9yIGdyb3VwIGhhdmVuJ3QgYmVlbiBzZXQsCiAgICAgICAgICAgICAgICAgICAgICogIHRoZW4gbGVhdmUgdGhlbSB1bmNoYW5nZWQuCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgaWYgKGFnZW50eF9zb2NrX3VzZXIgPT0gMCApCiAgICAgICAgICAgICAgICAgICAgICAgIGFnZW50eF9zb2NrX3VzZXIgPSAtMTsKICAgICAgICAgICAgICAgICAgICBpZiAoYWdlbnR4X3NvY2tfZ3JvdXAgPT0gMCApCiAgICAgICAgICAgICAgICAgICAgICAgIGFnZW50eF9zb2NrX2dyb3VwID0gLTE7CiAgICAgICAgICAgICAgICAgICAgY2hvd24obmFtZSwgYWdlbnR4X3NvY2tfdXNlciwgYWdlbnR4X3NvY2tfZ3JvdXApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiNlbmRpZgogICAgICAgICAgICBzZXNzaW9uID0KICAgICAgICAgICAgICAgIHNubXBfYWRkX2Z1bGwoJnNlc3MsIHQsIE5VTEwsIGFnZW50eF9wYXJzZSwgTlVMTCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWdlbnR4X3JlYWxsb2NfYnVpbGQsIGFnZW50eF9jaGVja19wYWNrZXQsIE5VTEwpOwogICAgICAgIH0KICAgICAgICBpZiAoc2Vzc2lvbiA9PSBOVUxMKSB7CiAgICAgICAgICAgIG5ldHNubXBfdHJhbnNwb3J0X2ZyZWUodCk7CiAgICAgICAgfQogICAgfQoKI2lmZGVmIE5FVFNOTVBfVFJBTlNQT1JUX1VOSVhfRE9NQUlOCiAgICBuZXRzbm1wX3VuaXhfZG9udF9jcmVhdGVfcGF0aCgpOwojZW5kaWYKCiAgICBTTk1QX0ZSRUUoYWdlbnR4X3NvY2tldHMpOwogICAgREVCVUdNU0dUTCgoImFnZW50eC9tYXN0ZXIiLCAiaW5pdGlhbGl6aW5nLi4uICAgRE9ORVxuIikpOwp9CgogICAgICAgIC8qCiAgICAgICAgICogSGFuZGxlIHRoZSByZXNwb25zZSBmcm9tIGFuIEFnZW50WCBzdWJhZ2VudCwKICAgICAgICAgKiAgIG1lcmdpbmcgdGhlIGFuc3dlcnMgYmFjayBpbnRvIHRoZSBvcmlnaW5hbCBxdWVyeQogICAgICAgICAqLwppbnQKYWdlbnR4X2dvdF9yZXNwb25zZShpbnQgb3BlcmF0aW9uLAogICAgICAgICAgICAgICAgICAgIG5ldHNubXBfc2Vzc2lvbiAqIHNlc3Npb24sCiAgICAgICAgICAgICAgICAgICAgaW50IHJlcWlkLCBuZXRzbm1wX3BkdSAqcGR1LCB2b2lkICptYWdpYykKewogICAgbmV0c25tcF9kZWxlZ2F0ZWRfY2FjaGUgKmNhY2hlID0gKG5ldHNubXBfZGVsZWdhdGVkX2NhY2hlICopIG1hZ2ljOwogICAgaW50ICAgICAgICAgICAgIGksIHJldDsKICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cywgKnJlcXVlc3Q7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcjsKICAgIG5ldHNubXBfc2Vzc2lvbiAqYXhfc2Vzc2lvbjsKCiAgICBjYWNoZSA9IG5ldHNubXBfaGFuZGxlcl9jaGVja19jYWNoZShjYWNoZSk7CiAgICBpZiAoIWNhY2hlKSB7CiAgICAgICAgREVCVUdNU0dUTCgoImFnZW50eC9tYXN0ZXIiLCAicmVzcG9uc2UgdG9vIGxhdGUgb24gc2Vzc2lvbiAlOHBcbiIsCiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbikpOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgcmVxdWVzdHMgPSBjYWNoZS0+cmVxdWVzdHM7CgogICAgc3dpdGNoIChvcGVyYXRpb24pIHsKICAgIGNhc2UgTkVUU05NUF9DQUxMQkFDS19PUF9USU1FRF9PVVQ6ewogICAgICAgICAgICB2b2lkICAgICAgICAgICAqcyA9IHNubXBfc2Vzc19wb2ludGVyKHNlc3Npb24pOwogICAgICAgICAgICBERUJVR01TR1RMKCgiYWdlbnR4L21hc3RlciIsICJ0aW1lb3V0IG9uIHNlc3Npb24gJThwIHJlcT0weCV4XG4iLAogICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLCAodW5zaWduZWQpcmVxaWQpKTsKCiAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9tYXJrX3JlcXVlc3RzX2FzX2RlbGVnYXRlZChyZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVRVUVTVF9JU19OT1RfREVMRUdBVEVEKTsKICAgICAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihjYWNoZS0+cmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogWFhYV1dXOiBzaG91bGQgYmUgaW5kZXg9MCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX0dFTkVSUik7CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBUaGlzIGlzIGEgYml0IHNsZWRnZWhhbW1lciBiZWNhdXNlIHRoZSBvdGhlciBzZXNzaW9ucyBvbiB0aGlzCiAgICAgICAgICAgICAqIHRyYW5zcG9ydCBtYXkgYmUgb2theSAoZS5nLiBzb21lIHRocmVhZCBpbiB0aGUgc3ViYWdlbnQgaGFzCiAgICAgICAgICAgICAqIHdlZGdlZCwgYnV0IHRoZSBvdGhlcnMgYXJlIGFscmlnaHQpLiAgT1RPSCB0aGUgb3ZlcndoZWxtaW5nCiAgICAgICAgICAgICAqIHByb2JhYmlsaXR5IGlzIHRoYXQgdGhlIHdob2xlIGFnZW50IGhhcyBkaWVkIHNvbWVob3cuICAKICAgICAgICAgICAgICovCgogICAgICAgICAgICBpZiAocyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICBuZXRzbm1wX3RyYW5zcG9ydCAqdCA9IHNubXBfc2Vzc190cmFuc3BvcnQocyk7CiAgICAgICAgICAgICAgICBjbG9zZV9hZ2VudHhfc2Vzc2lvbihzZXNzaW9uLCAtMSk7CgogICAgICAgICAgICAgICAgaWYgKHQgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwgImNsb3NlIHRyYW5zcG9ydFxuIikpOwogICAgICAgICAgICAgICAgICAgIHQtPmZfY2xvc2UodCk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwgIk5VTEwgdHJhbnNwb3J0Pz9cbiIpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwgIk5VTEwgc2Vzc19wb2ludGVyPz9cbiIpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBheF9zZXNzaW9uID0gKG5ldHNubXBfc2Vzc2lvbiAqKSBjYWNoZS0+bG9jYWxpbmZvOwogICAgICAgICAgICBuZXRzbm1wX2ZyZWVfYWdlbnRfc25tcF9zZXNzaW9uX2J5X3Nlc3Npb24oYXhfc2Vzc2lvbiwgTlVMTCk7CiAgICAgICAgICAgIG5ldHNubXBfZnJlZV9kZWxlZ2F0ZWRfY2FjaGUoY2FjaGUpOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgY2FzZSBORVRTTk1QX0NBTExCQUNLX09QX0RJU0NPTk5FQ1Q6CiAgICBjYXNlIE5FVFNOTVBfQ0FMTEJBQ0tfT1BfU0VORF9GQUlMRUQ6CiAgICAgICAgaWYgKG9wZXJhdGlvbiA9PSBORVRTTk1QX0NBTExCQUNLX09QX0RJU0NPTk5FQ1QpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoImFnZW50eC9tYXN0ZXIiLCAiZGlzY29ubmVjdCBvbiBzZXNzaW9uICU4cFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbikpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwgInNlbmQgZmFpbGVkIG9uIHNlc3Npb24gJThwXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uKSk7CiAgICAgICAgfQogICAgICAgIGNsb3NlX2FnZW50eF9zZXNzaW9uKHNlc3Npb24sIC0xKTsKICAgICAgICBuZXRzbm1wX2hhbmRsZXJfbWFya19yZXF1ZXN0c19hc19kZWxlZ2F0ZWQocmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFUVVFU1RfSVNfTk9UX0RFTEVHQVRFRCk7CiAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihjYWNoZS0+cmVxaW5mbywgcmVxdWVzdHMsICAgICAvKiBYWFhXV1c6IHNob3VsZCBiZSBpbmRleD0wICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0VSUl9HRU5FUlIpOwogICAgICAgIG5ldHNubXBfZnJlZV9kZWxlZ2F0ZWRfY2FjaGUoY2FjaGUpOwogICAgICAgIHJldHVybiAwOwoKICAgIGNhc2UgTkVUU05NUF9DQUxMQkFDS19PUF9SRUNFSVZFRF9NRVNTQUdFOgogICAgICAgIC8qCiAgICAgICAgICogVGhpcyBzZXNzaW9uIGlzIGFsaXZlIAogICAgICAgICAqLwogICAgICAgIENMRUFSX1NOTVBfU1RSSUtFX0ZMQUdTKHNlc3Npb24tPmZsYWdzKTsKICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIlVua25vd24gb3BlcmF0aW9uICVkIGluIGFnZW50eF9nb3RfcmVzcG9uc2VcbiIsCiAgICAgICAgICAgICAgICAgb3BlcmF0aW9uKTsKICAgICAgICBuZXRzbm1wX2ZyZWVfZGVsZWdhdGVkX2NhY2hlKGNhY2hlKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBERUJVR01TR1RMKCgiYWdlbnR4L21hc3RlciIsICJnb3QgcmVzcG9uc2UgZXJyc3RhdD0lbGQsIChyZXE9MHgleCx0cmFucz0iCiAgICAgICAgICAgICAgICAiMHgleCxzZXNzPTB4JXgpXG4iLAogICAgICAgICAgICAgICAgcGR1LT5lcnJzdGF0LCAodW5zaWduZWQpcGR1LT5yZXFpZCwgKHVuc2lnbmVkKXBkdS0+dHJhbnNpZCwKCQkodW5zaWduZWQpcGR1LT5zZXNzaWQpKTsKCiAgICBpZiAocGR1LT5lcnJzdGF0ICE9IEFHRU5UWF9FUlJfTk9FUlJPUikgewogICAgICAgIC8qIFtSRkMgMjQ3MSAtIDcuMi41LjIuXQogICAgICAgICAqCiAgICAgICAgICogICAxKSBGb3IgYW55IHJlY2VpdmVkIEFnZW50WCByZXNwb25zZSBQRFUsIGlmIHJlcy5lcnJvciBpcwogICAgICAgICAqICAgICAgbm90IGBub0Vycm9yJywgdGhlIFNOTVAgcmVzcG9uc2UgUERVJ3MgZXJyb3IgY29kZSBpcwogICAgICAgICAqICAgICAgc2V0IHRvIHRoaXMgdmFsdWUuICBJZiByZXMuZXJyb3IgY29udGFpbnMgYW4gQWdlbnRYCiAgICAgICAgICogICAgICBzcGVjaWZpYyB2YWx1ZSAoZS5nLiAgYHBhcnNlRXJyb3InKSwgdGhlIFNOTVAgcmVzcG9uc2UKICAgICAgICAgKiAgICAgIFBEVSdzIGVycm9yIGNvZGUgaXMgc2V0IHRvIGEgdmFsdWUgb2YgZ2VuRXJyIGluc3RlYWQuCiAgICAgICAgICogICAgICBBbHNvLCB0aGUgU05NUCByZXNwb25zZSBQRFUncyBlcnJvciBpbmRleCBpcyBzZXQgdG8KICAgICAgICAgKiAgICAgIHRoZSBpbmRleCBvZiB0aGUgdmFyaWFibGUgYmluZGluZyBjb3JyZXNwb25kaW5nIHRvIHRoZQogICAgICAgICAqICAgICAgZmFpbGVkIFZhckJpbmQgaW4gdGhlIHN1YmFnZW50J3MgQWdlbnRYIHJlc3BvbnNlIFBEVS4KICAgICAgICAgKgogICAgICAgICAqICAgICAgQWxsIG90aGVyIEFnZW50WCByZXNwb25zZSBQRFVzIHJlY2VpdmVkIGR1ZSB0bwogICAgICAgICAqICAgICAgcHJvY2Vzc2luZyB0aGlzIFNOTVAgcmVxdWVzdCBhcmUgaWdub3JlZC4gIFByb2Nlc3NpbmcKICAgICAgICAgKiAgICAgIGlzIGNvbXBsZXRlOyB0aGUgU05NUCBSZXNwb25zZSBQRFUgaXMgcmVhZHkgdG8gYmUgc2VudAogICAgICAgICAqICAgICAgKHNlZSBzZWN0aW9uIDcuMi42LCAiU2VuZGluZyB0aGUgU05NUCBSZXNwb25zZS1QRFUiKS4KICAgICAgICAgKi8KICAgICAgICBpbnQgZXJyOwoKICAgICAgICBERUJVR01TR1RMKCgiYWdlbnR4L21hc3RlciIsCiAgICAgICAgICAgICAgICAgICAgImFnZW50eF9nb3RfcmVzcG9uc2UoKSBlcnJvciBicmFuY2hcbiIpKTsKCiAgICAgICAgc3dpdGNoIChwZHUtPmVycnN0YXQpIHsKICAgICAgICBjYXNlIEFHRU5UWF9FUlJfUEFSU0VfRkFJTEVEOgogICAgICAgIGNhc2UgQUdFTlRYX0VSUl9SRVFVRVNUX0RFTklFRDoKICAgICAgICBjYXNlIEFHRU5UWF9FUlJfUFJPQ0VTU0lOR19FUlJPUjoKICAgICAgICAgICAgZXJyID0gU05NUF9FUlJfR0VORVJSOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBlcnIgPSBwZHUtPmVycnN0YXQ7CiAgICAgICAgfQoKICAgICAgICByZXQgPSAwOwogICAgICAgIGZvciAocmVxdWVzdCA9IHJlcXVlc3RzLCBpID0gMTsgcmVxdWVzdDsKICAgICAgICAgICAgIHJlcXVlc3QgPSByZXF1ZXN0LT5uZXh0LCBpKyspIHsKICAgICAgICAgICAgaWYgKGkgPT0gcGR1LT5lcnJpbmRleCkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIE1hcmsgdGhpcyB2YXJiaW5kIGFzIHRoZSBvbmUgZ2VuZXJhdGluZyB0aGUgZXJyb3IuCiAgICAgICAgICAgICAgICAgKiBOb3RlIHRoYXQgdGhlIEFnZW50WCBlcnJpbmRleCBtYXkgbm90IG1hdGNoIHRoZQogICAgICAgICAgICAgICAgICogcG9zaXRpb24gaW4gdGhlIG9yaWdpbmFsIFNOTVAgUERVIChyZXF1ZXN0LT5pbmRleCkKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihjYWNoZS0+cmVxaW5mbywgcmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyKTsKICAgICAgICAgICAgICAgIHJldCA9IDE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVxdWVzdC0+ZGVsZWdhdGVkID0gUkVRVUVTVF9JU19OT1RfREVMRUdBVEVEOwogICAgICAgIH0KICAgICAgICBpZiAoIXJldCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBhY2ssIHVua25vd24sIG1hcmsgdGhlIGZpcnN0IG9uZQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihjYWNoZS0+cmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9FUlJfR0VORVJSKTsKICAgICAgICB9CiAgICAgICAgbmV0c25tcF9mcmVlX2RlbGVnYXRlZF9jYWNoZShjYWNoZSk7CiAgICAgICAgREVCVUdNU0dUTCgoImFnZW50eC9tYXN0ZXIiLCAiZW5kIGVycm9yIGJyYW5jaFxuIikpOwogICAgICAgIHJldHVybiAxOwogICAgfSBlbHNlIGlmIChjYWNoZS0+cmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVCB8fAogICAgICAgICAgICAgICBjYWNoZS0+cmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVE5FWFQgfHwKICAgICAgICAgICAgICAgY2FjaGUtPnJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRCVUxLKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBSZXBsYWNlIHZhcmJpbmRzIGZvciBkYXRhIHJlcXVlc3QgdHlwZXMsIGJ1dCBub3QgU0VUcy4gIAogICAgICAgICAqLwogICAgICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwKICAgICAgICAgICAgICAgICAgICAiYWdlbnR4X2dvdF9yZXNwb25zZSgpIGJlZ2lubmluZy4uLlxuIikpOwogICAgICAgIGZvciAodmFyID0gcGR1LT52YXJpYWJsZXMsIHJlcXVlc3QgPSByZXF1ZXN0czsgcmVxdWVzdCAmJiB2YXI7CiAgICAgICAgICAgICByZXF1ZXN0ID0gcmVxdWVzdC0+bmV4dCwgdmFyID0gdmFyLT5uZXh0X3ZhcmlhYmxlKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIE90aGVyd2lzZSwgcHJvY2VzcyBzdWNjZXNzZnVsIHJlcXVlc3RzCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBERUJVR01TR1RMKCgiYWdlbnR4L21hc3RlciIsCiAgICAgICAgICAgICAgICAgICAgICAgICIgIGhhbmRsZV9hZ2VudHhfcmVzcG9uc2U6IHByb2Nlc3Npbmc6ICIpKTsKICAgICAgICAgICAgREVCVUdNU0dPSUQoKCJhZ2VudHgvbWFzdGVyIiwgdmFyLT5uYW1lLCB2YXItPm5hbWVfbGVuZ3RoKSk7CiAgICAgICAgICAgIERFQlVHTVNHKCgiYWdlbnR4L21hc3RlciIsICJcbiIpKTsKICAgICAgICAgICAgaWYgKG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19BUFBMSUNBVElPTl9JRCwgTkVUU05NUF9EU19BR0VOVF9WRVJCT1NFKSkgewogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImFnZW50eC9tYXN0ZXIiLCAiICAgID4+ICIpKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHVkFSKCgiYWdlbnR4L21hc3RlciIsIHZhcikpOwogICAgICAgICAgICAgICAgREVCVUdNU0coKCJhZ2VudHgvbWFzdGVyIiwgIlxuIikpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiB1cGRhdGUgdGhlIG9pZCBpbiB0aGUgb3JpZ2luYWwgcmVxdWVzdCAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmICh2YXItPnR5cGUgIT0gU05NUF9FTkRPRk1JQlZJRVcpIHsKICAgICAgICAgICAgICAgIHNubXBfc2V0X3Zhcl90eXBlZF92YWx1ZShyZXF1ZXN0LT5yZXF1ZXN0dmIsIHZhci0+dHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXItPnZhbC5zdHJpbmcsIHZhci0+dmFsX2xlbik7CiAgICAgICAgICAgICAgICBzbm1wX3NldF92YXJfb2JqaWQocmVxdWVzdC0+cmVxdWVzdHZiLCB2YXItPm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyLT5uYW1lX2xlbmd0aCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmVxdWVzdC0+ZGVsZWdhdGVkID0gUkVRVUVTVF9JU19OT1RfREVMRUdBVEVEOwogICAgICAgIH0KCiAgICAgICAgaWYgKHJlcXVlc3QgfHwgdmFyKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGFjaywgdGhpcyBpcyBiYWQuICBUaGUgIyBvZiB2YXJiaW5kcyBkb24ndCBtYXRjaCBhbmQKICAgICAgICAgICAgICogdGhlcmUgaXMgbm8gd2F5IHRvIGZpeCB0aGUgcHJvYmxlbSAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsCiAgICAgICAgICAgICAgICAgICAgICJyZXNwb25zZSB0byBhZ2VudHggcmVxdWVzdCBpbGxlZ2FsLiAgYmFpbGluZyBvdXQuXG4iKTsKICAgICAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihjYWNoZS0+cmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9FUlJfR0VORVJSKTsKICAgICAgICB9CgogICAgICAgIGlmIChjYWNoZS0+cmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVEJVTEspCiAgICAgICAgICAgIG5ldHNubXBfYnVsa190b19uZXh0X2ZpeF9yZXF1ZXN0cyhyZXF1ZXN0cyk7CiAgICB9IGVsc2UgewogICAgICAgIC8qCiAgICAgICAgICogbWFyayBzZXQgcmVxdWVzdHMgYXMgaGFuZGxlZCAKICAgICAgICAgKi8KICAgICAgICBmb3IgKHJlcXVlc3QgPSByZXF1ZXN0czsgcmVxdWVzdDsgcmVxdWVzdCA9IHJlcXVlc3QtPm5leHQpIHsKICAgICAgICAgICAgcmVxdWVzdC0+ZGVsZWdhdGVkID0gUkVRVUVTVF9JU19OT1RfREVMRUdBVEVEOwogICAgICAgIH0KICAgIH0KICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwKICAgICAgICAgICAgICAgICJoYW5kbGVfYWdlbnR4X3Jlc3BvbnNlKCkgZmluaXNoaW5nLi4uXG4iKSk7CiAgICBuZXRzbm1wX2ZyZWVfZGVsZWdhdGVkX2NhY2hlKGNhY2hlKTsKICAgIHJldHVybiAxOwp9CgovKgogKgogKiBBZ2VudFggU3RhdGUgZGlhZ3JhbS4gIFttb2RlXSA9IGludGVybmFsIG1vZGUgaXQncyBtYXBwZWQgZnJvbToKICoKICogVEVTVFNFVCAtc3VjY2Vzcy0+IENPTU1JVCAtc3VjY2Vzcy0+IENMRUFOVVAKICogW1JFU0VSVkUxXSAgICAgICAgIFtBQ1RJT05dICAgICAgICAgIFtDT01NSVRdCiAqICAgIHwgICAgICAgICAgICAgICAgIHwKICogICAgfCAgICAgICAgICAgICAgICAgXC0tZmFpbHVyZS0+IFVORE8KICogICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtVTkRPXQogKiAgICB8CiAqICAgICAtLWZhaWx1cmUtPiBDTEVBTlVQCiAqICAgICAgICAgICAgICAgICBbRlJFRV0KICovCmludAphZ2VudHhfbWFzdGVyX2hhbmRsZXIobmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbyAqcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cykKewogICAgbmV0c25tcF9zZXNzaW9uICpheF9zZXNzaW9uID0gKG5ldHNubXBfc2Vzc2lvbiAqKSBoYW5kbGVyLT5teXZvaWQ7CiAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdCA9IHJlcXVlc3RzOwogICAgbmV0c25tcF9wZHUgICAgKnBkdTsKICAgIHZvaWQgICAgICAgICAgICpjYl9kYXRhOwogICAgaW50ICAgICAgICAgICAgIHJlc3VsdDsKCiAgICBERUJVR01TR1RMKCgiYWdlbnR4L21hc3RlciIsCiAgICAgICAgICAgICAgICAiYWdlbnR4IG1hc3RlciBoYW5kbGVyIHN0YXJ0aW5nLCBtb2RlID0gMHglMDJ4XG4iLAogICAgICAgICAgICAgICAgcmVxaW5mby0+bW9kZSkpOwoKICAgIGlmICghYXhfc2Vzc2lvbikgewogICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsIFNOTVBfRVJSX0dFTkVSUik7CiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7CiAgICB9ICAgICAgICAKCiAgICAvKgogICAgICogYnVpbGQgYSBuZXcgcGR1IGJhc2VkIG9uIHRoZSBwZHUgdHlwZSBjb21pbmcgaW4gCiAgICAgKi8KICAgIHN3aXRjaCAocmVxaW5mby0+bW9kZSkgewogICAgY2FzZSBNT0RFX0dFVDoKICAgICAgICBwZHUgPSBzbm1wX3BkdV9jcmVhdGUoQUdFTlRYX01TR19HRVQpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9HRVRORVhUOgogICAgICAgIHBkdSA9IHNubXBfcGR1X2NyZWF0ZShBR0VOVFhfTVNHX0dFVE5FWFQpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9HRVRCVUxLOiAgICAgICAgIC8qIFdXV1hYWCAqLwogICAgICAgIHBkdSA9IHNubXBfcGR1X2NyZWF0ZShBR0VOVFhfTVNHX0dFVE5FWFQpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTE6CiAgICAgICAgcGR1ID0gc25tcF9wZHVfY3JlYXRlKEFHRU5UWF9NU0dfVEVTVFNFVCk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9SRVNFUlZFMjoKICAgICAgICAvKgogICAgICAgICAqIGRvbid0IGRvIGFueXRoaW5nIGhlcmUgZm9yIEFnZW50WC4gIEFzc3VtZSBhbGwgaXMgZmluZQogICAgICAgICAqIGFuZCBnbyBvbiBzaW5jZSBBZ2VudFggb25seSBoYXMgb25lIHRlc3QgcGhhc2UuIAogICAgICAgICAqLwogICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwoKICAgIGNhc2UgTU9ERV9TRVRfQUNUSU9OOgogICAgICAgIHBkdSA9IHNubXBfcGR1X2NyZWF0ZShBR0VOVFhfTVNHX0NPTU1JVFNFVCk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9VTkRPOgogICAgICAgIHBkdSA9IHNubXBfcGR1X2NyZWF0ZShBR0VOVFhfTVNHX1VORE9TRVQpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfQ09NTUlUOgogICAgY2FzZSBNT0RFX1NFVF9GUkVFOgogICAgICAgIHBkdSA9IHNubXBfcGR1X2NyZWF0ZShBR0VOVFhfTVNHX0NMRUFOVVBTRVQpOwogICAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgInVuc3VwcG9ydGVkIG1vZGUgZm9yIGFnZW50eC9tYXN0ZXIgY2FsbGVkXG4iKTsKICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgIH0KCiAgICBpZiAoIXBkdSkgewogICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsIFNOTVBfRVJSX0dFTkVSUik7CiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7CiAgICB9CgogICAgcGR1LT52ZXJzaW9uID0gQUdFTlRYX1ZFUlNJT05fMTsKICAgIHBkdS0+cmVxaWQgPSBzbm1wX2dldF9uZXh0X3RyYW5zaWQoKTsKICAgIHBkdS0+dHJhbnNpZCA9IHJlcWluZm8tPmFzcC0+cGR1LT50cmFuc2lkOwogICAgcGR1LT5zZXNzaWQgPSBheF9zZXNzaW9uLT5zdWJzZXNzaW9uLT5zZXNzaWQ7CiAgICBpZiAocmVnaW5mby0+Y29udGV4dE5hbWUpIHsKICAgICAgICBwZHUtPmNvbW11bml0eSA9ICh1X2NoYXIgKikgc3RyZHVwKHJlZ2luZm8tPmNvbnRleHROYW1lKTsKICAgICAgICBwZHUtPmNvbW11bml0eV9sZW4gPSBzdHJsZW4ocmVnaW5mby0+Y29udGV4dE5hbWUpOwogICAgICAgIHBkdS0+ZmxhZ3MgfD0gQUdFTlRYX01TR19GTEFHX05PTl9ERUZBVUxUX0NPTlRFWFQ7CiAgICB9CiAgICBpZiAoYXhfc2Vzc2lvbi0+c3Vic2Vzc2lvbi0+ZmxhZ3MgJiBBR0VOVFhfTVNHX0ZMQUdfTkVUV09SS19CWVRFX09SREVSKQogICAgICAgIHBkdS0+ZmxhZ3MgfD0gQUdFTlRYX01TR19GTEFHX05FVFdPUktfQllURV9PUkRFUjsKCiAgICB3aGlsZSAocmVxdWVzdCkgewoKICAgICAgICBzaXplX3QgbmxlbiA9IHJlcXVlc3QtPnJlcXVlc3R2Yi0+bmFtZV9sZW5ndGg7CiAgICAgICAgb2lkICAgKm5wdHIgPSByZXF1ZXN0LT5yZXF1ZXN0dmItPm5hbWU7CiAgICAgICAgCiAgICAgICAgREVCVUdNU0dUTCgoImFnZW50eC9tYXN0ZXIiLCJyZXF1ZXN0IGZvciB2YXJpYWJsZSAoIikpOwogICAgICAgIERFQlVHTVNHT0lEKCgiYWdlbnR4L21hc3RlciIsIG5wdHIsIG5sZW4pKTsKICAgICAgICBERUJVR01TRygoImFnZW50eC9tYXN0ZXIiLCAiKVxuIikpOwogICAgICAgIAogICAgICAgIC8qCiAgICAgICAgICogbG9vcCB0aHJvdWdoIGFsbCB0aGUgcmVxdWVzdHMgYW5kIGNyZWF0ZSBhZ2VudHggb25lcyBvdXQgb2YgdGhlbSAKICAgICAgICAgKi8KCiAgICAgICAgaWYgKHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRORVhUIHx8IHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRCVUxLKSB7CgogICAgICAgICAgICBpZiAoc25tcF9vaWRfY29tcGFyZShucHRyLCBubGVuLCByZXF1ZXN0LT5zdWJ0cmVlLT5zdGFydF9hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5zdWJ0cmVlLT5zdGFydF9sZW4pIDwgMCkgewogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImFnZW50eC9tYXN0ZXIiLCJpbmV4YWN0IHJlcXVlc3QgcHJlY2VlZGluZyByZWdpb24gKCIpKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHT0lEKCgiYWdlbnR4L21hc3RlciIsIHJlcXVlc3QtPnN1YnRyZWUtPnN0YXJ0X2EsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+c3VidHJlZS0+c3RhcnRfbGVuKSk7CiAgICAgICAgICAgICAgICBERUJVR01TRygoImFnZW50eC9tYXN0ZXIiLCAiKVxuIikpOwogICAgICAgICAgICAgICAgbnB0ciA9IHJlcXVlc3QtPnN1YnRyZWUtPnN0YXJ0X2E7CiAgICAgICAgICAgICAgICBubGVuID0gcmVxdWVzdC0+c3VidHJlZS0+c3RhcnRfbGVuOwogICAgICAgICAgICAgICAgcmVxdWVzdC0+aW5jbHVzaXZlID0gMTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHJlcXVlc3QtPmluY2x1c2l2ZSkgewogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImFnZW50eC9tYXN0ZXIiLCAiSU5DTFVTSVZFIHZhcmJpbmQgIikpOwogICAgICAgICAgICAgICAgREVCVUdNU0dPSUQoKCJhZ2VudHgvbWFzdGVyIiwgbnB0ciwgbmxlbikpOwogICAgICAgICAgICAgICAgREVCVUdNU0coKCJhZ2VudHgvbWFzdGVyIiwgIiBzY29wZWQgdG8gIikpOwogICAgICAgICAgICAgICAgREVCVUdNU0dPSUQoKCJhZ2VudHgvbWFzdGVyIiwgcmVxdWVzdC0+cmFuZ2VfZW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJhbmdlX2VuZF9sZW4pKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHKCgiYWdlbnR4L21hc3RlciIsICJcbiIpKTsKICAgICAgICAgICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIG5wdHIsIG5sZW4sIEFTTl9QUklWX0lOQ0xfUkFOR0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhciAqKSByZXF1ZXN0LT5yYW5nZV9lbmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmFuZ2VfZW5kX2xlbiAqCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKG9pZCkpOwogICAgICAgICAgICAgICAgcmVxdWVzdC0+aW5jbHVzaXZlID0gMDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwgIkVYQ0xVU0lWRSB2YXJiaW5kICIpKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHT0lEKCgiYWdlbnR4L21hc3RlciIsIG5wdHIsIG5sZW4pKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHKCgiYWdlbnR4L21hc3RlciIsICIgc2NvcGVkIHRvICIpKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHT0lEKCgiYWdlbnR4L21hc3RlciIsIHJlcXVlc3QtPnJhbmdlX2VuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yYW5nZV9lbmRfbGVuKSk7CiAgICAgICAgICAgICAgICBERUJVR01TRygoImFnZW50eC9tYXN0ZXIiLCAiXG4iKSk7CiAgICAgICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBucHRyLCBubGVuLCBBU05fUFJJVl9FWENMX1JBTkdFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgcmVxdWVzdC0+cmFuZ2VfZW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJhbmdlX2VuZF9sZW4gKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihvaWQpKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIHJlcXVlc3QtPnJlcXVlc3R2Yi0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJlcXVlc3R2Yi0+bmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yZXF1ZXN0dmItPnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yZXF1ZXN0dmItPnZhbC5zdHJpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yZXF1ZXN0dmItPnZhbF9sZW4pOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBtYXJrIHRoZSByZXF1ZXN0IGFzIGRlbGF5ZWQgCiAgICAgICAgICovCiAgICAgICAgaWYgKHBkdS0+Y29tbWFuZCAhPSBBR0VOVFhfTVNHX0NMRUFOVVBTRVQpCiAgICAgICAgICAgIHJlcXVlc3QtPmRlbGVnYXRlZCA9IFJFUVVFU1RfSVNfREVMRUdBVEVEOwogICAgICAgIGVsc2UKICAgICAgICAgICAgcmVxdWVzdC0+ZGVsZWdhdGVkID0gUkVRVUVTVF9JU19OT1RfREVMRUdBVEVEOwoKICAgICAgICAvKgogICAgICAgICAqIG5leHQuLi4gCiAgICAgICAgICovCiAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3QtPm5leHQ7CiAgICB9CgogICAgLyoKICAgICAqIFdoZW4gdGhlIG1hc3RlciBzZW5kcyBhIENsZWFudXBTZXQgUERVLCBpdCB3aWxsIG5ldmVyIGdldCBhIHJlc3BvbnNlCiAgICAgKiBiYWNrIGZyb20gdGhlIHN1YmFnZW50LiBTbyB3ZSBzaG91bGRuJ3QgYWxsb2NhdGUgdGhlCiAgICAgKiBuZXRzbm1wX2RlbGVnYXRlZF9jYWNoZSBzdHJ1Y3R1cmUgaW4gdGhpcyBjYXNlLgogICAgICovCiAgICBpZiAocGR1LT5jb21tYW5kICE9IEFHRU5UWF9NU0dfQ0xFQU5VUFNFVCkKICAgICAgICBjYl9kYXRhID0gbmV0c25tcF9jcmVhdGVfZGVsZWdhdGVkX2NhY2hlKGhhbmRsZXIsIHJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXFpbmZvLCByZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkICopIGF4X3Nlc3Npb24pOwogICAgZWxzZQogICAgICAgIGNiX2RhdGEgPSBOVUxMOwoKICAgIC8qCiAgICAgKiBzZW5kIHRoZSByZXF1ZXN0cyBvdXQuCiAgICAgKi8KICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwgInNlbmRpbmcgcGR1IChyZXE9MHgleCx0cmFucz0weCV4LHNlc3M9MHgleClcbiIsCiAgICAgICAgICAgICAgICAodW5zaWduZWQpcGR1LT5yZXFpZCwgKHVuc2lnbmVkKXBkdS0+dHJhbnNpZCwgKHVuc2lnbmVkKXBkdS0+c2Vzc2lkKSk7CiAgICByZXN1bHQgPSBzbm1wX2FzeW5jX3NlbmQoYXhfc2Vzc2lvbiwgcGR1LCBhZ2VudHhfZ290X3Jlc3BvbnNlLCBjYl9kYXRhKTsKICAgIGlmIChyZXN1bHQgPT0gMCkgewogICAgICAgIHNubXBfZnJlZV9wZHUocGR1KTsKICAgIH0KCiAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKfQo=