LyoKICogIEFnZW50WCBtYXN0ZXIgYWdlbnQKICovCi8qIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvcHlyaWdodChzKS4gIFNlZQogKiB0aGUgTmV0LVNOTVAncyBDT1BZSU5HIGZpbGUgZm9yIG1vcmUgZGV0YWlscyBhbmQgb3RoZXIgY29weXJpZ2h0cwogKiB0aGF0IG1heSBhcHBseToKICovCi8qCiAqIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgY29weXJpZ2h0ZWQgYnk6CiAqIENvcHlyaWdodCCpIDIwMDMgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBVc2UgaXMgc3ViamVjdCB0byBsaWNlbnNlIHRlcm1zIHNwZWNpZmllZCBpbiB0aGUgQ09QWUlORyBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhlIE5ldC1TTk1QIHBhY2thZ2UuCiAqLwoKCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KI2lmIEhBVkVfSU9fSAojaW5jbHVkZSA8aW8uaD4KI2VuZGlmCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaWZkZWYgSEFWRV9TVERMSUJfSAojaW5jbHVkZSA8c3RkbGliLmg+CiNlbmRpZgojaWYgSEFWRV9TVFJJTkdfSAojaW5jbHVkZSA8c3RyaW5nLmg+CiNlbHNlCiNpbmNsdWRlIDxzdHJpbmdzLmg+CiNlbmRpZgojaWYgSEFWRV9ORVRJTkVUX0lOX0gKI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4KI2VuZGlmCiNpZiBIQVZFX1NZU19TT0NLRVRfSAojaW5jbHVkZSA8c3lzL3NvY2tldC5oPgojZW5kaWYKI2luY2x1ZGUgPGVycm5vLmg+CgojaWYgSEFWRV9VTklTVERfSAojaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgojaWZkZWYgSEFWRV9TWVNfU1RBVF9ICiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojZW5kaWYKCiNkZWZpbmUgU05NUF9ORUVEX1JFUVVFU1RfTElTVAojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtaW5jbHVkZXMuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L25ldC1zbm1wLWFnZW50LWluY2x1ZGVzLmg+CiNpbmNsdWRlICJzbm1wZC5oIgojaW5jbHVkZSAiYWdlbnR4L3Byb3RvY29sLmgiCiNpbmNsdWRlICJhZ2VudHgvbWFzdGVyX2FkbWluLmgiCgp2b2lkCnJlYWxfaW5pdF9tYXN0ZXIodm9pZCkKewogICAgbmV0c25tcF9zZXNzaW9uIHNlc3MsICpzZXNzaW9uID0gTlVMTDsKICAgIGNoYXIgKmFnZW50eF9zb2NrZXRzOwogICAgY2hhciAqY3AxOwoKICAgIGlmIChuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsIE5FVFNOTVBfRFNfQUdFTlRfUk9MRSkgIT0gTUFTVEVSX0FHRU5UKQogICAgICAgIHJldHVybjsKCiAgICBpZiAobmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfQUdFTlRfWF9TT0NLRVQpKSB7CiAgICAgICBhZ2VudHhfc29ja2V0cyA9IHN0cmR1cChuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19BUFBMSUNBVElPTl9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0FHRU5UX1hfU09DS0VUKSk7CiNpZmRlZiBORVRTTk1QX0FHRU5UWF9ET01fU09DS19PTkxZCiAgICAgICBpZiAoYWdlbnR4X3NvY2tldHNbMF0gIT0gJy8nKSB7CiAgICAgICAgICAgLyogdW5peDovcGF0aCAqLwogICAgICAgICAgIGlmIChhZ2VudHhfc29ja2V0c1s1XSAhPSAnLycpIHsKICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwKICAgICAgICAgICAgICAgICAgICAiRXJyb3I6ICVzIHRyYW5zcG9ydCBpcyBub3Qgc3VwcG9ydGVkLCBkaXNhYmxpbmcgYWdlbnR4L21hc3Rlci5cbiIsIGFnZW50eF9zb2NrZXRzKTsKICAgICAgICAgICAgICAgU05NUF9GUkVFKGFnZW50eF9zb2NrZXRzKTsKICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgIH0KICAgICAgIH0KI2VuZGlmCiAgICB9IGVsc2UgewogICAgICAgIGFnZW50eF9zb2NrZXRzID0gc3RyZHVwKCIiKTsKICAgIH0KCgogICAgREVCVUdNU0dUTCgoImFnZW50eC9tYXN0ZXIiLCAiaW5pdGlhbGl6aW5nLi4uXG4iKSk7CiAgICBzbm1wX3Nlc3NfaW5pdCgmc2Vzcyk7CiAgICBzZXNzLnZlcnNpb24gPSBBR0VOVFhfVkVSU0lPTl8xOwogICAgc2Vzcy5mbGFncyB8PSBTTk1QX0ZMQUdTX1NUUkVBTV9TT0NLRVQ7CiAgICBzZXNzLnRpbWVvdXQgPSBuZXRzbm1wX2RzX2dldF9pbnQoTkVUU05NUF9EU19BUFBMSUNBVElPTl9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0FHRU5UX0FHRU5UWF9USU1FT1VUKTsKICAgIHNlc3MucmV0cmllcyA9IG5ldHNubXBfZHNfZ2V0X2ludChORVRTTk1QX0RTX0FQUExJQ0FUSU9OX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfQUdFTlRfQUdFTlRYX1JFVFJJRVMpOwoKI2lmZGVmIE5FVFNOTVBfVFJBTlNQT1JUX1VOSVhfRE9NQUlOCiAgICB7CglpbnQgYWdlbnR4X2Rpcl9wZXJtID0KCSAgICBuZXRzbm1wX2RzX2dldF9pbnQoTkVUU05NUF9EU19BUFBMSUNBVElPTl9JRCwKCQkJICAgICAgIE5FVFNOTVBfRFNfQUdFTlRfWF9ESVJfUEVSTSk7CglpZiAoYWdlbnR4X2Rpcl9wZXJtID09IDApCgkgICAgYWdlbnR4X2Rpcl9wZXJtID0gTkVUU05NUF9BR0VOVF9ESVJFQ1RPUllfTU9ERTsKCW5ldHNubXBfdW5peF9jcmVhdGVfcGF0aF93aXRoX21vZGUoYWdlbnR4X2Rpcl9wZXJtKTsKICAgIH0KI2VuZGlmCgogICAgY3AxID0gYWdlbnR4X3NvY2tldHM7CiAgICB3aGlsZSAoY3AxKSB7CiAgICAgICAgbmV0c25tcF90cmFuc3BvcnQgKnQ7CiAgICAgICAgLyoKICAgICAgICAgKiAgSWYgdGhlIEFnZW50WCBzb2NrZXQgc3RyaW5nIGNvbnRhaW5zIG11bHRpcGxlIGRlc2NyaXB0b3JzLAogICAgICAgICAqICB0aGVuIHBpY2sgdGhpcyBhcGFydCBhbmQgaGFuZGxlIHRoZW0gb25lIGJ5IG9uZS4KICAgICAgICAgKgogICAgICAgICAqLwogICAgICAgIHNlc3MucGVlcm5hbWUgPSBjcDE7CiAgICAgICAgY3AxID0gc3RyY2hyKHNlc3MucGVlcm5hbWUsICcsJyk7CiAgICAgICAgaWYgKGNwMSAhPSBOVUxMKSB7CiAgICAgICAgICAgICpjcDErKyA9ICdcMCc7Cgl9CgogICAgICAgIC8qCiAgICAgICAgICogIExldCAnc25tcF9vcGVuJyBpbnRlcnByZXQgdGhlIGRlc2NyaXB0b3IuCiAgICAgICAgICovCiAgICAgICAgc2Vzcy5sb2NhbF9wb3J0ID0gQUdFTlRYX1BPUlQ7ICAgICAgLyogSW5kaWNhdGUgc2VydmVyICYgc2V0IGRlZmF1bHQgcG9ydCAqLwogICAgICAgIHNlc3MucmVtb3RlX3BvcnQgPSAwOwogICAgICAgIHNlc3MuY2FsbGJhY2sgPSBoYW5kbGVfbWFzdGVyX2FnZW50eF9wYWNrZXQ7CiAgICAgICAgZXJybm8gPSAwOwogICAgICAgIHQgPSBuZXRzbm1wX3RyYW5zcG9ydF9vcGVuX3NlcnZlcigiYWdlbnR4Iiwgc2Vzcy5wZWVybmFtZSk7CiAgICAgICAgaWYgKHQgPT0gTlVMTCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBkaWFnbm9zZSBzbm1wX29wZW4gZXJyb3JzIHdpdGggdGhlIGlucHV0IG5ldHNubXBfc2Vzc2lvbgogICAgICAgICAgICAgKiBwb2ludGVyLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY2hhciBidWZbMTAyNF07CiAgICAgICAgICAgIGlmICghbmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0FQUExJQ0FUSU9OX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19BR0VOVF9OT19ST09UX0FDQ0VTUykpIHsKICAgICAgICAgICAgICAgIHNucHJpbnRmKGJ1Ziwgc2l6ZW9mKGJ1ZiksCiAgICAgICAgICAgICAgICAgICAgICAgICAiRXJyb3I6IENvdWxkbid0IG9wZW4gYSBtYXN0ZXIgYWdlbnR4IHNvY2tldCB0byAiCiAgICAgICAgICAgICAgICAgICAgICAgICAibGlzdGVuIG9uICglcykiLCBzZXNzLnBlZXJuYW1lKTsKICAgICAgICAgICAgICAgIHNubXBfc2Vzc19wZXJyb3IoYnVmLCAmc2Vzcyk7CiAgICAgICAgICAgICAgICBleGl0KDEpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc25wcmludGYoYnVmLCBzaXplb2YoYnVmKSwKICAgICAgICAgICAgICAgICAgICAgICAgICJXYXJuaW5nOiBDb3VsZG4ndCBvcGVuIGEgbWFzdGVyIGFnZW50eCBzb2NrZXQgdG8gIgogICAgICAgICAgICAgICAgICAgICAgICAgImxpc3RlbiBvbiAoJXMpIiwgc2Vzcy5wZWVybmFtZSk7CiAgICAgICAgICAgICAgICBuZXRzbm1wX3Nlc3NfbG9nX2Vycm9yKExPR19XQVJOSU5HLCBidWYsICZzZXNzKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiNpZmRlZiBORVRTTk1QX1RSQU5TUE9SVF9VTklYX0RPTUFJTgogICAgICAgICAgICBpZiAodC0+ZG9tYWluID09IG5ldHNubXBfVW5peERvbWFpbiAmJiB0LT5sb2NhbCAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogQXBwbHkgYW55IHNldHRpbmdzIHRvIHRoZSBvd25lcnNoaXAvcGVybWlzc2lvbnMgb2YgdGhlCiAgICAgICAgICAgICAgICAgKiBBZ2VudFggc29ja2V0CiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGludCBhZ2VudHhfc29ja19wZXJtID0KICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2RzX2dldF9pbnQoTkVUU05NUF9EU19BUFBMSUNBVElPTl9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19BR0VOVF9YX1NPQ0tfUEVSTSk7CiAgICAgICAgICAgICAgICBpbnQgYWdlbnR4X3NvY2tfdXNlciA9CiAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9kc19nZXRfaW50KE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfQUdFTlRfWF9TT0NLX1VTRVIpOwogICAgICAgICAgICAgICAgaW50IGFnZW50eF9zb2NrX2dyb3VwID0KICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2RzX2dldF9pbnQoTkVUU05NUF9EU19BUFBMSUNBVElPTl9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19BR0VOVF9YX1NPQ0tfR1JPVVApOwoKICAgICAgICAgICAgICAgIGNoYXIgbmFtZVtzaXplb2Yoc3RydWN0IHNvY2thZGRyX3VuKSArIDFdOwogICAgICAgICAgICAgICAgbWVtY3B5KG5hbWUsIHQtPmxvY2FsLCB0LT5sb2NhbF9sZW5ndGgpOwogICAgICAgICAgICAgICAgbmFtZVt0LT5sb2NhbF9sZW5ndGhdID0gJ1wwJzsKCiAgICAgICAgICAgICAgICBpZiAoYWdlbnR4X3NvY2tfcGVybSAhPSAwKQogICAgICAgICAgICAgICAgICAgIGNobW9kKG5hbWUsIGFnZW50eF9zb2NrX3Blcm0pOwoKICAgICAgICAgICAgICAgIGlmIChhZ2VudHhfc29ja191c2VyIHx8IGFnZW50eF9zb2NrX2dyb3VwKSB7CiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiBJZiBlaXRoZXIgb2YgdXNlciBvciBncm91cCBoYXZlbid0IGJlZW4gc2V0LAogICAgICAgICAgICAgICAgICAgICAqICB0aGVuIGxlYXZlIHRoZW0gdW5jaGFuZ2VkLgogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIGlmIChhZ2VudHhfc29ja191c2VyID09IDAgKQogICAgICAgICAgICAgICAgICAgICAgICBhZ2VudHhfc29ja191c2VyID0gLTE7CiAgICAgICAgICAgICAgICAgICAgaWYgKGFnZW50eF9zb2NrX2dyb3VwID09IDAgKQogICAgICAgICAgICAgICAgICAgICAgICBhZ2VudHhfc29ja19ncm91cCA9IC0xOwogICAgICAgICAgICAgICAgICAgIGNob3duKG5hbWUsIGFnZW50eF9zb2NrX3VzZXIsIGFnZW50eF9zb2NrX2dyb3VwKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQojZW5kaWYKICAgICAgICAgICAgc2Vzc2lvbiA9CiAgICAgICAgICAgICAgICBzbm1wX2FkZF9mdWxsKCZzZXNzLCB0LCBOVUxMLCBhZ2VudHhfcGFyc2UsIE5VTEwsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFnZW50eF9yZWFsbG9jX2J1aWxkLCBhZ2VudHhfY2hlY2tfcGFja2V0LCBOVUxMKTsKICAgICAgICB9CiAgICAgICAgaWYgKHNlc3Npb24gPT0gTlVMTCkgewogICAgICAgICAgICBuZXRzbm1wX3RyYW5zcG9ydF9mcmVlKHQpOwogICAgICAgIH0KICAgIH0KCiNpZmRlZiBORVRTTk1QX1RSQU5TUE9SVF9VTklYX0RPTUFJTgogICAgbmV0c25tcF91bml4X2RvbnRfY3JlYXRlX3BhdGgoKTsKI2VuZGlmCgogICAgU05NUF9GUkVFKGFnZW50eF9zb2NrZXRzKTsKICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwgImluaXRpYWxpemluZy4uLiAgIERPTkVcbiIpKTsKfQoKICAgICAgICAvKgogICAgICAgICAqIEhhbmRsZSB0aGUgcmVzcG9uc2UgZnJvbSBhbiBBZ2VudFggc3ViYWdlbnQsCiAgICAgICAgICogICBtZXJnaW5nIHRoZSBhbnN3ZXJzIGJhY2sgaW50byB0aGUgb3JpZ2luYWwgcXVlcnkKICAgICAgICAgKi8KaW50CmFnZW50eF9nb3RfcmVzcG9uc2UoaW50IG9wZXJhdGlvbiwKICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3Nlc3Npb24gKiBzZXNzaW9uLAogICAgICAgICAgICAgICAgICAgIGludCByZXFpZCwgbmV0c25tcF9wZHUgKnBkdSwgdm9pZCAqbWFnaWMpCnsKICAgIG5ldHNubXBfZGVsZWdhdGVkX2NhY2hlICpjYWNoZSA9IChuZXRzbm1wX2RlbGVnYXRlZF9jYWNoZSAqKSBtYWdpYzsKICAgIGludCAgICAgICAgICAgICBpLCByZXQ7CiAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMsICpyZXF1ZXN0OwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXI7CiAgICBuZXRzbm1wX3Nlc3Npb24gKmF4X3Nlc3Npb247CgogICAgY2FjaGUgPSBuZXRzbm1wX2hhbmRsZXJfY2hlY2tfY2FjaGUoY2FjaGUpOwogICAgaWYgKCFjYWNoZSkgewogICAgICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwgInJlc3BvbnNlIHRvbyBsYXRlIG9uIHNlc3Npb24gJThwXG4iLAogICAgICAgICAgICAgICAgICAgIHNlc3Npb24pKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIHJlcXVlc3RzID0gY2FjaGUtPnJlcXVlc3RzOwoKICAgIHN3aXRjaCAob3BlcmF0aW9uKSB7CiAgICBjYXNlIE5FVFNOTVBfQ0FMTEJBQ0tfT1BfVElNRURfT1VUOnsKICAgICAgICAgICAgdm9pZCAgICAgICAgICAgKnMgPSBzbm1wX3Nlc3NfcG9pbnRlcihzZXNzaW9uKTsKICAgICAgICAgICAgREVCVUdNU0dUTCgoImFnZW50eC9tYXN0ZXIiLCAidGltZW91dCBvbiBzZXNzaW9uICU4cCByZXE9MHgleFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbiwgKHVuc2lnbmVkKXJlcWlkKSk7CgogICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfbWFya19yZXF1ZXN0c19hc19kZWxlZ2F0ZWQocmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFUVVFU1RfSVNfTk9UX0RFTEVHQVRFRCk7CiAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IoY2FjaGUtPnJlcWluZm8sIHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIFhYWFdXVzogc2hvdWxkIGJlIGluZGV4PTAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0VSUl9HRU5FUlIpOwoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogVGhpcyBpcyBhIGJpdCBzbGVkZ2VoYW1tZXIgYmVjYXVzZSB0aGUgb3RoZXIgc2Vzc2lvbnMgb24gdGhpcwogICAgICAgICAgICAgKiB0cmFuc3BvcnQgbWF5IGJlIG9rYXkgKGUuZy4gc29tZSB0aHJlYWQgaW4gdGhlIHN1YmFnZW50IGhhcwogICAgICAgICAgICAgKiB3ZWRnZWQsIGJ1dCB0aGUgb3RoZXJzIGFyZSBhbHJpZ2h0KS4gIE9UT0ggdGhlIG92ZXJ3aGVsbWluZwogICAgICAgICAgICAgKiBwcm9iYWJpbGl0eSBpcyB0aGF0IHRoZSB3aG9sZSBhZ2VudCBoYXMgZGllZCBzb21laG93LiAgCiAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgaWYgKHMgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgbmV0c25tcF90cmFuc3BvcnQgKnQgPSBzbm1wX3Nlc3NfdHJhbnNwb3J0KHMpOwogICAgICAgICAgICAgICAgY2xvc2VfYWdlbnR4X3Nlc3Npb24oc2Vzc2lvbiwgLTEpOwoKICAgICAgICAgICAgICAgIGlmICh0ICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiYWdlbnR4L21hc3RlciIsICJjbG9zZSB0cmFuc3BvcnRcbiIpKTsKICAgICAgICAgICAgICAgICAgICB0LT5mX2Nsb3NlKHQpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiYWdlbnR4L21hc3RlciIsICJOVUxMIHRyYW5zcG9ydD8/XG4iKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiYWdlbnR4L21hc3RlciIsICJOVUxMIHNlc3NfcG9pbnRlcj8/XG4iKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYXhfc2Vzc2lvbiA9IChuZXRzbm1wX3Nlc3Npb24gKikgY2FjaGUtPmxvY2FsaW5mbzsKICAgICAgICAgICAgbmV0c25tcF9mcmVlX2FnZW50X3NubXBfc2Vzc2lvbl9ieV9zZXNzaW9uKGF4X3Nlc3Npb24sIE5VTEwpOwogICAgICAgICAgICBuZXRzbm1wX2ZyZWVfZGVsZWdhdGVkX2NhY2hlKGNhY2hlKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgIGNhc2UgTkVUU05NUF9DQUxMQkFDS19PUF9ESVNDT05ORUNUOgogICAgY2FzZSBORVRTTk1QX0NBTExCQUNLX09QX1NFTkRfRkFJTEVEOgogICAgICAgIGlmIChvcGVyYXRpb24gPT0gTkVUU05NUF9DQUxMQkFDS19PUF9ESVNDT05ORUNUKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwgImRpc2Nvbm5lY3Qgb24gc2Vzc2lvbiAlOHBcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24pKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBERUJVR01TR1RMKCgiYWdlbnR4L21hc3RlciIsICJzZW5kIGZhaWxlZCBvbiBzZXNzaW9uICU4cFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbikpOwogICAgICAgIH0KICAgICAgICBjbG9zZV9hZ2VudHhfc2Vzc2lvbihzZXNzaW9uLCAtMSk7CiAgICAgICAgbmV0c25tcF9oYW5kbGVyX21hcmtfcmVxdWVzdHNfYXNfZGVsZWdhdGVkKHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRVFVRVNUX0lTX05PVF9ERUxFR0FURUQpOwogICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IoY2FjaGUtPnJlcWluZm8sIHJlcXVlc3RzLCAgICAgLyogWFhYV1dXOiBzaG91bGQgYmUgaW5kZXg9MCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9FUlJfR0VORVJSKTsKICAgICAgICBuZXRzbm1wX2ZyZWVfZGVsZWdhdGVkX2NhY2hlKGNhY2hlKTsKICAgICAgICByZXR1cm4gMDsKCiAgICBjYXNlIE5FVFNOTVBfQ0FMTEJBQ0tfT1BfUkVDRUlWRURfTUVTU0FHRToKICAgICAgICAvKgogICAgICAgICAqIFRoaXMgc2Vzc2lvbiBpcyBhbGl2ZSAKICAgICAgICAgKi8KICAgICAgICBDTEVBUl9TTk1QX1NUUklLRV9GTEFHUyhzZXNzaW9uLT5mbGFncyk7CiAgICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAgIHNubXBfbG9nKExPR19FUlIsICJVbmtub3duIG9wZXJhdGlvbiAlZCBpbiBhZ2VudHhfZ290X3Jlc3BvbnNlXG4iLAogICAgICAgICAgICAgICAgIG9wZXJhdGlvbik7CiAgICAgICAgbmV0c25tcF9mcmVlX2RlbGVnYXRlZF9jYWNoZShjYWNoZSk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgREVCVUdNU0dUTCgoImFnZW50eC9tYXN0ZXIiLCAiZ290IHJlc3BvbnNlIGVycnN0YXQ9JWxkLCAocmVxPTB4JXgsdHJhbnM9IgogICAgICAgICAgICAgICAgIjB4JXgsc2Vzcz0weCV4KVxuIiwKICAgICAgICAgICAgICAgIHBkdS0+ZXJyc3RhdCwgKHVuc2lnbmVkKXBkdS0+cmVxaWQsICh1bnNpZ25lZClwZHUtPnRyYW5zaWQsCgkJKHVuc2lnbmVkKXBkdS0+c2Vzc2lkKSk7CgogICAgaWYgKHBkdS0+ZXJyc3RhdCAhPSBBR0VOVFhfRVJSX05PRVJST1IpIHsKICAgICAgICAvKiBbUkZDIDI0NzEgLSA3LjIuNS4yLl0KICAgICAgICAgKgogICAgICAgICAqICAgMSkgRm9yIGFueSByZWNlaXZlZCBBZ2VudFggcmVzcG9uc2UgUERVLCBpZiByZXMuZXJyb3IgaXMKICAgICAgICAgKiAgICAgIG5vdCBgbm9FcnJvcicsIHRoZSBTTk1QIHJlc3BvbnNlIFBEVSdzIGVycm9yIGNvZGUgaXMKICAgICAgICAgKiAgICAgIHNldCB0byB0aGlzIHZhbHVlLiAgSWYgcmVzLmVycm9yIGNvbnRhaW5zIGFuIEFnZW50WAogICAgICAgICAqICAgICAgc3BlY2lmaWMgdmFsdWUgKGUuZy4gIGBwYXJzZUVycm9yJyksIHRoZSBTTk1QIHJlc3BvbnNlCiAgICAgICAgICogICAgICBQRFUncyBlcnJvciBjb2RlIGlzIHNldCB0byBhIHZhbHVlIG9mIGdlbkVyciBpbnN0ZWFkLgogICAgICAgICAqICAgICAgQWxzbywgdGhlIFNOTVAgcmVzcG9uc2UgUERVJ3MgZXJyb3IgaW5kZXggaXMgc2V0IHRvCiAgICAgICAgICogICAgICB0aGUgaW5kZXggb2YgdGhlIHZhcmlhYmxlIGJpbmRpbmcgY29ycmVzcG9uZGluZyB0byB0aGUKICAgICAgICAgKiAgICAgIGZhaWxlZCBWYXJCaW5kIGluIHRoZSBzdWJhZ2VudCdzIEFnZW50WCByZXNwb25zZSBQRFUuCiAgICAgICAgICoKICAgICAgICAgKiAgICAgIEFsbCBvdGhlciBBZ2VudFggcmVzcG9uc2UgUERVcyByZWNlaXZlZCBkdWUgdG8KICAgICAgICAgKiAgICAgIHByb2Nlc3NpbmcgdGhpcyBTTk1QIHJlcXVlc3QgYXJlIGlnbm9yZWQuICBQcm9jZXNzaW5nCiAgICAgICAgICogICAgICBpcyBjb21wbGV0ZTsgdGhlIFNOTVAgUmVzcG9uc2UgUERVIGlzIHJlYWR5IHRvIGJlIHNlbnQKICAgICAgICAgKiAgICAgIChzZWUgc2VjdGlvbiA3LjIuNiwgIlNlbmRpbmcgdGhlIFNOTVAgUmVzcG9uc2UtUERVIikuCiAgICAgICAgICovCiAgICAgICAgaW50IGVycjsKCiAgICAgICAgREVCVUdNU0dUTCgoImFnZW50eC9tYXN0ZXIiLAogICAgICAgICAgICAgICAgICAgICJhZ2VudHhfZ290X3Jlc3BvbnNlKCkgZXJyb3IgYnJhbmNoXG4iKSk7CgogICAgICAgIHN3aXRjaCAocGR1LT5lcnJzdGF0KSB7CiAgICAgICAgY2FzZSBBR0VOVFhfRVJSX1BBUlNFX0ZBSUxFRDoKICAgICAgICBjYXNlIEFHRU5UWF9FUlJfUkVRVUVTVF9ERU5JRUQ6CiAgICAgICAgY2FzZSBBR0VOVFhfRVJSX1BST0NFU1NJTkdfRVJST1I6CiAgICAgICAgICAgIGVyciA9IFNOTVBfRVJSX0dFTkVSUjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgZXJyID0gcGR1LT5lcnJzdGF0OwogICAgICAgIH0KCiAgICAgICAgcmV0ID0gMDsKICAgICAgICBmb3IgKHJlcXVlc3QgPSByZXF1ZXN0cywgaSA9IDE7IHJlcXVlc3Q7CiAgICAgICAgICAgICByZXF1ZXN0ID0gcmVxdWVzdC0+bmV4dCwgaSsrKSB7CiAgICAgICAgICAgIGlmIChpID09IHBkdS0+ZXJyaW5kZXgpIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBNYXJrIHRoaXMgdmFyYmluZCBhcyB0aGUgb25lIGdlbmVyYXRpbmcgdGhlIGVycm9yLgogICAgICAgICAgICAgICAgICogTm90ZSB0aGF0IHRoZSBBZ2VudFggZXJyaW5kZXggbWF5IG5vdCBtYXRjaCB0aGUKICAgICAgICAgICAgICAgICAqIHBvc2l0aW9uIGluIHRoZSBvcmlnaW5hbCBTTk1QIFBEVSAocmVxdWVzdC0+aW5kZXgpCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IoY2FjaGUtPnJlcWluZm8sIHJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycik7CiAgICAgICAgICAgICAgICByZXQgPSAxOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlcXVlc3QtPmRlbGVnYXRlZCA9IFJFUVVFU1RfSVNfTk9UX0RFTEVHQVRFRDsKICAgICAgICB9CiAgICAgICAgaWYgKCFyZXQpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogYWNrLCB1bmtub3duLCBtYXJrIHRoZSBmaXJzdCBvbmUKICAgICAgICAgICAgICovCiAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IoY2FjaGUtPnJlcWluZm8sIHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX0dFTkVSUik7CiAgICAgICAgfQogICAgICAgIG5ldHNubXBfZnJlZV9kZWxlZ2F0ZWRfY2FjaGUoY2FjaGUpOwogICAgICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwgImVuZCBlcnJvciBicmFuY2hcbiIpKTsKICAgICAgICByZXR1cm4gMTsKICAgIH0gZWxzZSBpZiAoY2FjaGUtPnJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVQgfHwKICAgICAgICAgICAgICAgY2FjaGUtPnJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRORVhUIHx8CiAgICAgICAgICAgICAgIGNhY2hlLT5yZXFpbmZvLT5tb2RlID09IE1PREVfR0VUQlVMSykgewogICAgICAgIC8qCiAgICAgICAgICogUmVwbGFjZSB2YXJiaW5kcyBmb3IgZGF0YSByZXF1ZXN0IHR5cGVzLCBidXQgbm90IFNFVHMuICAKICAgICAgICAgKi8KICAgICAgICBERUJVR01TR1RMKCgiYWdlbnR4L21hc3RlciIsCiAgICAgICAgICAgICAgICAgICAgImFnZW50eF9nb3RfcmVzcG9uc2UoKSBiZWdpbm5pbmcuLi5cbiIpKTsKICAgICAgICBmb3IgKHZhciA9IHBkdS0+dmFyaWFibGVzLCByZXF1ZXN0ID0gcmVxdWVzdHM7IHJlcXVlc3QgJiYgdmFyOwogICAgICAgICAgICAgcmVxdWVzdCA9IHJlcXVlc3QtPm5leHQsIHZhciA9IHZhci0+bmV4dF92YXJpYWJsZSkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBPdGhlcndpc2UsIHByb2Nlc3Mgc3VjY2Vzc2Z1bCByZXF1ZXN0cwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVCVUdNU0dUTCgoImFnZW50eC9tYXN0ZXIiLAogICAgICAgICAgICAgICAgICAgICAgICAiICBoYW5kbGVfYWdlbnR4X3Jlc3BvbnNlOiBwcm9jZXNzaW5nOiAiKSk7CiAgICAgICAgICAgIERFQlVHTVNHT0lEKCgiYWdlbnR4L21hc3RlciIsIHZhci0+bmFtZSwgdmFyLT5uYW1lX2xlbmd0aCkpOwogICAgICAgICAgICBERUJVR01TRygoImFnZW50eC9tYXN0ZXIiLCAiXG4iKSk7CiAgICAgICAgICAgIGlmIChuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsIE5FVFNOTVBfRFNfQUdFTlRfVkVSQk9TRSkpIHsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwgIiAgICA+PiAiKSk7CiAgICAgICAgICAgICAgICBERUJVR01TR1ZBUigoImFnZW50eC9tYXN0ZXIiLCB2YXIpKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHKCgiYWdlbnR4L21hc3RlciIsICJcbiIpKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogdXBkYXRlIHRoZSBvaWQgaW4gdGhlIG9yaWdpbmFsIHJlcXVlc3QgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAodmFyLT50eXBlICE9IFNOTVBfRU5ET0ZNSUJWSUVXKSB7CiAgICAgICAgICAgICAgICBzbm1wX3NldF92YXJfdHlwZWRfdmFsdWUocmVxdWVzdC0+cmVxdWVzdHZiLCB2YXItPnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyLT52YWwuc3RyaW5nLCB2YXItPnZhbF9sZW4pOwogICAgICAgICAgICAgICAgc25tcF9zZXRfdmFyX29iamlkKHJlcXVlc3QtPnJlcXVlc3R2YiwgdmFyLT5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhci0+bmFtZV9sZW5ndGgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlcXVlc3QtPmRlbGVnYXRlZCA9IFJFUVVFU1RfSVNfTk9UX0RFTEVHQVRFRDsKICAgICAgICB9CgogICAgICAgIGlmIChyZXF1ZXN0IHx8IHZhcikgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBhY2ssIHRoaXMgaXMgYmFkLiAgVGhlICMgb2YgdmFyYmluZHMgZG9uJ3QgbWF0Y2ggYW5kCiAgICAgICAgICAgICAqIHRoZXJlIGlzIG5vIHdheSB0byBmaXggdGhlIHByb2JsZW0gCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLAogICAgICAgICAgICAgICAgICAgICAicmVzcG9uc2UgdG8gYWdlbnR4IHJlcXVlc3QgaWxsZWdhbC4gIGJhaWxpbmcgb3V0LlxuIik7CiAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IoY2FjaGUtPnJlcWluZm8sIHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX0dFTkVSUik7CiAgICAgICAgfQoKICAgICAgICBpZiAoY2FjaGUtPnJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRCVUxLKQogICAgICAgICAgICBuZXRzbm1wX2J1bGtfdG9fbmV4dF9maXhfcmVxdWVzdHMocmVxdWVzdHMpOwogICAgfSBlbHNlIHsKICAgICAgICAvKgogICAgICAgICAqIG1hcmsgc2V0IHJlcXVlc3RzIGFzIGhhbmRsZWQgCiAgICAgICAgICovCiAgICAgICAgZm9yIChyZXF1ZXN0ID0gcmVxdWVzdHM7IHJlcXVlc3Q7IHJlcXVlc3QgPSByZXF1ZXN0LT5uZXh0KSB7CiAgICAgICAgICAgIHJlcXVlc3QtPmRlbGVnYXRlZCA9IFJFUVVFU1RfSVNfTk9UX0RFTEVHQVRFRDsKICAgICAgICB9CiAgICB9CiAgICBERUJVR01TR1RMKCgiYWdlbnR4L21hc3RlciIsCiAgICAgICAgICAgICAgICAiaGFuZGxlX2FnZW50eF9yZXNwb25zZSgpIGZpbmlzaGluZy4uLlxuIikpOwogICAgbmV0c25tcF9mcmVlX2RlbGVnYXRlZF9jYWNoZShjYWNoZSk7CiAgICByZXR1cm4gMTsKfQoKLyoKICoKICogQWdlbnRYIFN0YXRlIGRpYWdyYW0uICBbbW9kZV0gPSBpbnRlcm5hbCBtb2RlIGl0J3MgbWFwcGVkIGZyb206CiAqCiAqIFRFU1RTRVQgLXN1Y2Nlc3MtPiBDT01NSVQgLXN1Y2Nlc3MtPiBDTEVBTlVQCiAqIFtSRVNFUlZFMV0gICAgICAgICBbQUNUSU9OXSAgICAgICAgICBbQ09NTUlUXQogKiAgICB8ICAgICAgICAgICAgICAgICB8CiAqICAgIHwgICAgICAgICAgICAgICAgIFwtLWZhaWx1cmUtPiBVTkRPCiAqICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbVU5ET10KICogICAgfAogKiAgICAgLS1mYWlsdXJlLT4gQ0xFQU5VUAogKiAgICAgICAgICAgICAgICAgW0ZSRUVdCiAqLwppbnQKYWdlbnR4X21hc3Rlcl9oYW5kbGVyKG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMpCnsKICAgIG5ldHNubXBfc2Vzc2lvbiAqYXhfc2Vzc2lvbiA9IChuZXRzbm1wX3Nlc3Npb24gKikgaGFuZGxlci0+bXl2b2lkOwogICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3QgPSByZXF1ZXN0czsKICAgIG5ldHNubXBfcGR1ICAgICpwZHU7CiAgICB2b2lkICAgICAgICAgICAqY2JfZGF0YTsKICAgIGludCAgICAgICAgICAgICByZXN1bHQ7CgogICAgREVCVUdNU0dUTCgoImFnZW50eC9tYXN0ZXIiLAogICAgICAgICAgICAgICAgImFnZW50eCBtYXN0ZXIgaGFuZGxlciBzdGFydGluZywgbW9kZSA9IDB4JTAyeFxuIiwKICAgICAgICAgICAgICAgIHJlcWluZm8tPm1vZGUpKTsKCiAgICBpZiAoIWF4X3Nlc3Npb24pIHsKICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3RzLCBTTk1QX0VSUl9HRU5FUlIpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgfSAgICAgICAgCgogICAgLyoKICAgICAqIGJ1aWxkIGEgbmV3IHBkdSBiYXNlZCBvbiB0aGUgcGR1IHR5cGUgY29taW5nIGluIAogICAgICovCiAgICBzd2l0Y2ggKHJlcWluZm8tPm1vZGUpIHsKICAgIGNhc2UgTU9ERV9HRVQ6CiAgICAgICAgcGR1ID0gc25tcF9wZHVfY3JlYXRlKEFHRU5UWF9NU0dfR0VUKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfR0VUTkVYVDoKICAgICAgICBwZHUgPSBzbm1wX3BkdV9jcmVhdGUoQUdFTlRYX01TR19HRVRORVhUKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfR0VUQlVMSzogICAgICAgICAvKiBXV1dYWFggKi8KICAgICAgICBwZHUgPSBzbm1wX3BkdV9jcmVhdGUoQUdFTlRYX01TR19HRVRORVhUKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUxOgogICAgICAgIHBkdSA9IHNubXBfcGR1X2NyZWF0ZShBR0VOVFhfTVNHX1RFU1RTRVQpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTI6CiAgICAgICAgLyoKICAgICAgICAgKiBkb24ndCBkbyBhbnl0aGluZyBoZXJlIGZvciBBZ2VudFguICBBc3N1bWUgYWxsIGlzIGZpbmUKICAgICAgICAgKiBhbmQgZ28gb24gc2luY2UgQWdlbnRYIG9ubHkgaGFzIG9uZSB0ZXN0IHBoYXNlLiAKICAgICAgICAgKi8KICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKCiAgICBjYXNlIE1PREVfU0VUX0FDVElPTjoKICAgICAgICBwZHUgPSBzbm1wX3BkdV9jcmVhdGUoQUdFTlRYX01TR19DT01NSVRTRVQpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfVU5ETzoKICAgICAgICBwZHUgPSBzbm1wX3BkdV9jcmVhdGUoQUdFTlRYX01TR19VTkRPU0VUKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX0NPTU1JVDoKICAgIGNhc2UgTU9ERV9TRVRfRlJFRToKICAgICAgICBwZHUgPSBzbm1wX3BkdV9jcmVhdGUoQUdFTlRYX01TR19DTEVBTlVQU0VUKTsKICAgICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICJ1bnN1cHBvcnRlZCBtb2RlIGZvciBhZ2VudHgvbWFzdGVyIGNhbGxlZFxuIik7CiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7CiAgICB9CgogICAgaWYgKCFwZHUpIHsKICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3RzLCBTTk1QX0VSUl9HRU5FUlIpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgfQoKICAgIHBkdS0+dmVyc2lvbiA9IEFHRU5UWF9WRVJTSU9OXzE7CiAgICBwZHUtPnJlcWlkID0gc25tcF9nZXRfbmV4dF90cmFuc2lkKCk7CiAgICBwZHUtPnRyYW5zaWQgPSByZXFpbmZvLT5hc3AtPnBkdS0+dHJhbnNpZDsKICAgIHBkdS0+c2Vzc2lkID0gYXhfc2Vzc2lvbi0+c3Vic2Vzc2lvbi0+c2Vzc2lkOwogICAgaWYgKHJlZ2luZm8tPmNvbnRleHROYW1lKSB7CiAgICAgICAgcGR1LT5jb21tdW5pdHkgPSAodV9jaGFyICopIHN0cmR1cChyZWdpbmZvLT5jb250ZXh0TmFtZSk7CiAgICAgICAgcGR1LT5jb21tdW5pdHlfbGVuID0gc3RybGVuKHJlZ2luZm8tPmNvbnRleHROYW1lKTsKICAgICAgICBwZHUtPmZsYWdzIHw9IEFHRU5UWF9NU0dfRkxBR19OT05fREVGQVVMVF9DT05URVhUOwogICAgfQogICAgaWYgKGF4X3Nlc3Npb24tPnN1YnNlc3Npb24tPmZsYWdzICYgQUdFTlRYX01TR19GTEFHX05FVFdPUktfQllURV9PUkRFUikKICAgICAgICBwZHUtPmZsYWdzIHw9IEFHRU5UWF9NU0dfRkxBR19ORVRXT1JLX0JZVEVfT1JERVI7CgogICAgd2hpbGUgKHJlcXVlc3QpIHsKCiAgICAgICAgc2l6ZV90IG5sZW4gPSByZXF1ZXN0LT5yZXF1ZXN0dmItPm5hbWVfbGVuZ3RoOwogICAgICAgIG9pZCAgICpucHRyID0gcmVxdWVzdC0+cmVxdWVzdHZiLT5uYW1lOwogICAgICAgIAogICAgICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwicmVxdWVzdCBmb3IgdmFyaWFibGUgKCIpKTsKICAgICAgICBERUJVR01TR09JRCgoImFnZW50eC9tYXN0ZXIiLCBucHRyLCBubGVuKSk7CiAgICAgICAgREVCVUdNU0coKCJhZ2VudHgvbWFzdGVyIiwgIilcbiIpKTsKICAgICAgICAKICAgICAgICAvKgogICAgICAgICAqIGxvb3AgdGhyb3VnaCBhbGwgdGhlIHJlcXVlc3RzIGFuZCBjcmVhdGUgYWdlbnR4IG9uZXMgb3V0IG9mIHRoZW0gCiAgICAgICAgICovCgogICAgICAgIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfR0VUTkVYVCB8fCByZXFpbmZvLT5tb2RlID09IE1PREVfR0VUQlVMSykgewoKICAgICAgICAgICAgaWYgKHNubXBfb2lkX2NvbXBhcmUobnB0ciwgbmxlbiwgcmVxdWVzdC0+c3VidHJlZS0+c3RhcnRfYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+c3VidHJlZS0+c3RhcnRfbGVuKSA8IDApIHsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwiaW5leGFjdCByZXF1ZXN0IHByZWNlZWRpbmcgcmVnaW9uICgiKSk7CiAgICAgICAgICAgICAgICBERUJVR01TR09JRCgoImFnZW50eC9tYXN0ZXIiLCByZXF1ZXN0LT5zdWJ0cmVlLT5zdGFydF9hLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnN1YnRyZWUtPnN0YXJ0X2xlbikpOwogICAgICAgICAgICAgICAgREVCVUdNU0coKCJhZ2VudHgvbWFzdGVyIiwgIilcbiIpKTsKICAgICAgICAgICAgICAgIG5wdHIgPSByZXF1ZXN0LT5zdWJ0cmVlLT5zdGFydF9hOwogICAgICAgICAgICAgICAgbmxlbiA9IHJlcXVlc3QtPnN1YnRyZWUtPnN0YXJ0X2xlbjsKICAgICAgICAgICAgICAgIHJlcXVlc3QtPmluY2x1c2l2ZSA9IDE7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChyZXF1ZXN0LT5pbmNsdXNpdmUpIHsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJhZ2VudHgvbWFzdGVyIiwgIklOQ0xVU0lWRSB2YXJiaW5kICIpKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHT0lEKCgiYWdlbnR4L21hc3RlciIsIG5wdHIsIG5sZW4pKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHKCgiYWdlbnR4L21hc3RlciIsICIgc2NvcGVkIHRvICIpKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHT0lEKCgiYWdlbnR4L21hc3RlciIsIHJlcXVlc3QtPnJhbmdlX2VuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yYW5nZV9lbmRfbGVuKSk7CiAgICAgICAgICAgICAgICBERUJVR01TRygoImFnZW50eC9tYXN0ZXIiLCAiXG4iKSk7CiAgICAgICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBucHRyLCBubGVuLCBBU05fUFJJVl9JTkNMX1JBTkdFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgcmVxdWVzdC0+cmFuZ2VfZW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJhbmdlX2VuZF9sZW4gKgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihvaWQpKTsKICAgICAgICAgICAgICAgIHJlcXVlc3QtPmluY2x1c2l2ZSA9IDA7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiYWdlbnR4L21hc3RlciIsICJFWENMVVNJVkUgdmFyYmluZCAiKSk7CiAgICAgICAgICAgICAgICBERUJVR01TR09JRCgoImFnZW50eC9tYXN0ZXIiLCBucHRyLCBubGVuKSk7CiAgICAgICAgICAgICAgICBERUJVR01TRygoImFnZW50eC9tYXN0ZXIiLCAiIHNjb3BlZCB0byAiKSk7CiAgICAgICAgICAgICAgICBERUJVR01TR09JRCgoImFnZW50eC9tYXN0ZXIiLCByZXF1ZXN0LT5yYW5nZV9lbmQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmFuZ2VfZW5kX2xlbikpOwogICAgICAgICAgICAgICAgREVCVUdNU0coKCJhZ2VudHgvbWFzdGVyIiwgIlxuIikpOwogICAgICAgICAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgbnB0ciwgbmxlbiwgQVNOX1BSSVZfRVhDTF9SQU5HRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopIHJlcXVlc3QtPnJhbmdlX2VuZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yYW5nZV9lbmRfbGVuICoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yob2lkKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCByZXF1ZXN0LT5yZXF1ZXN0dmItPm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0LT5yZXF1ZXN0dmItPm5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiLT50eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiLT52YWwuc3RyaW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiLT52YWxfbGVuKTsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogbWFyayB0aGUgcmVxdWVzdCBhcyBkZWxheWVkIAogICAgICAgICAqLwogICAgICAgIGlmIChwZHUtPmNvbW1hbmQgIT0gQUdFTlRYX01TR19DTEVBTlVQU0VUKQogICAgICAgICAgICByZXF1ZXN0LT5kZWxlZ2F0ZWQgPSBSRVFVRVNUX0lTX0RFTEVHQVRFRDsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHJlcXVlc3QtPmRlbGVnYXRlZCA9IFJFUVVFU1RfSVNfTk9UX0RFTEVHQVRFRDsKCiAgICAgICAgLyoKICAgICAgICAgKiBuZXh0Li4uIAogICAgICAgICAqLwogICAgICAgIHJlcXVlc3QgPSByZXF1ZXN0LT5uZXh0OwogICAgfQoKICAgIC8qCiAgICAgKiBXaGVuIHRoZSBtYXN0ZXIgc2VuZHMgYSBDbGVhbnVwU2V0IFBEVSwgaXQgd2lsbCBuZXZlciBnZXQgYSByZXNwb25zZQogICAgICogYmFjayBmcm9tIHRoZSBzdWJhZ2VudC4gU28gd2Ugc2hvdWxkbid0IGFsbG9jYXRlIHRoZQogICAgICogbmV0c25tcF9kZWxlZ2F0ZWRfY2FjaGUgc3RydWN0dXJlIGluIHRoaXMgY2FzZS4KICAgICAqLwogICAgaWYgKHBkdS0+Y29tbWFuZCAhPSBBR0VOVFhfTVNHX0NMRUFOVVBTRVQpCiAgICAgICAgY2JfZGF0YSA9IG5ldHNubXBfY3JlYXRlX2RlbGVnYXRlZF9jYWNoZShoYW5kbGVyLCByZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCAqKSBheF9zZXNzaW9uKTsKICAgIGVsc2UKICAgICAgICBjYl9kYXRhID0gTlVMTDsKCiAgICAvKgogICAgICogc2VuZCB0aGUgcmVxdWVzdHMgb3V0LgogICAgICovCiAgICBERUJVR01TR1RMKCgiYWdlbnR4L21hc3RlciIsICJzZW5kaW5nIHBkdSAocmVxPTB4JXgsdHJhbnM9MHgleCxzZXNzPTB4JXgpXG4iLAogICAgICAgICAgICAgICAgKHVuc2lnbmVkKXBkdS0+cmVxaWQsICh1bnNpZ25lZClwZHUtPnRyYW5zaWQsICh1bnNpZ25lZClwZHUtPnNlc3NpZCkpOwogICAgcmVzdWx0ID0gc25tcF9hc3luY19zZW5kKGF4X3Nlc3Npb24sIHBkdSwgYWdlbnR4X2dvdF9yZXNwb25zZSwgY2JfZGF0YSk7CiAgICBpZiAocmVzdWx0ID09IDApIHsKICAgICAgICBzbm1wX2ZyZWVfcGR1KHBkdSk7CiAgICB9CgogICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7Cn0K