LyoKQ29weXJpZ2h0IChjKSAyMDExLTIwMTIsMjAxNSwgVGhlIExpbnV4IEZvdW5kYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuCgpSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZQptZXQ6CiAgICAqIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZQogICAgICBjb3B5cmlnaHQgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZwogICAgICBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQKICAgICAgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogICAgKiBOZWl0aGVyIHRoZSBuYW1lIG9mIFRoZSBMaW51eCBGb3VuZGF0aW9uIG5vciB0aGUgbmFtZXMgb2YgaXRzCiAgICAgIGNvbnRyaWJ1dG9ycyBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZAogICAgICBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCgpUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIgQU5EIEFOWSBFWFBSRVNTIE9SIElNUExJRUQKV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YKTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVApBUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgT1dORVIgT1IgQ09OVFJJQlVUT1JTCkJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IKQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YKU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SCkJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLApXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRQpPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOCklGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgoqLwoKI2luY2x1ZGUgPHB0aHJlYWQuaD4KI2luY2x1ZGUgIm1tX2NhbWVyYV9kYmcuaCIKI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzeXMvaW9jdGwuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzdGRkZWYuaD4KI2luY2x1ZGUgPHBvbGwuaD4KI2luY2x1ZGUgPGxpbnV4L21lZGlhLmg+CgojaW5jbHVkZSAibW1fY2FtZXJhX2ludGVyZmFjZTIuaCIKI2luY2x1ZGUgIm1tX2NhbWVyYS5oIgoKI2RlZmluZSBTRVRfUEFSTV9CSVQzMihwYXJtLCBwYXJtX2FycikgXAogICAgKHBhcm1fYXJyW3Bhcm0vMzJdIHw9ICgxPDwocGFybSUzMikpKQoKI2RlZmluZSBHRVRfUEFSTV9CSVQzMihwYXJtLCBwYXJtX2FycikgXAogICAgKChwYXJtX2FycltwYXJtLzMyXT4+KHBhcm0lMzIpKSYgMHgxKQoKc3RhdGljIHB0aHJlYWRfbXV0ZXhfdCBnX211dGV4ID0gUFRIUkVBRF9NVVRFWF9JTklUSUFMSVpFUjsKCnN0YXRpYyBtbV9jYW1lcmFfY3RybF90IGdfY2FtX2N0cmw7CgpzdGF0aWMgaW50IG1tX2NhbWVyYV91dGlsX29wY29kZV8yX2NoX3R5cGUobW1fY2FtZXJhX29ial90ICpteV9vYmosCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtbV9jYW1lcmFfb3BzX3R5cGVfdCBvcGNvZGUpCnsKICAgIHN3aXRjaChvcGNvZGUpIHsKICAgIGNhc2UgTU1fQ0FNRVJBX09QU19QUkVWSUVXOgogICAgICAgIHJldHVybiBNTV9DQU1FUkFfQ0hfUFJFVklFVzsKICAgIGNhc2UgTU1fQ0FNRVJBX09QU19aU0w6CiAgICBjYXNlIE1NX0NBTUVSQV9PUFNfU05BUFNIT1Q6CiAgICAgICAgcmV0dXJuIE1NX0NBTUVSQV9DSF9TTkFQU0hPVDsKICAgIGNhc2UgTU1fQ0FNRVJBX09QU19QUkVQQVJFX1NOQVBTSE9UOgogICAgICAgIHJldHVybiBNTV9DQU1FUkFfQ0hfU05BUFNIT1Q7CiAgICBjYXNlIE1NX0NBTUVSQV9PUFNfUkFXOgogICAgICAgIHJldHVybiBNTV9DQU1FUkFfQ0hfUkFXOwogICAgZGVmYXVsdDoKICAgICAgICBicmVhazsKICAgIH0KICAgIHJldHVybiAtMTsKfQoKY29uc3QgY2hhciAqbW1fY2FtZXJhX3V0aWxfZ2V0X2Rldl9uYW1lKG1tX2NhbWVyYV9vYmpfdCAqIG15X29iaikKewogICAgQ0RCRygiJXM6IFJldHVybmluZyAlcyBhdCBpbmRleCA6JWRcbiIsCiAgICAgICAgX19mdW5jX18sZ19jYW1fY3RybC5jYW1lcmFbbXlfb2JqLT5teV9pZF0udmlkZW9fZGV2X25hbWUsbXlfb2JqLT5teV9pZCk7CiAgICByZXR1cm4gZ19jYW1fY3RybC5jYW1lcmFbbXlfb2JqLT5teV9pZF0udmlkZW9fZGV2X25hbWU7Cn0KCi8qIHVzZWQgZm9yIHF1ZXJ5aW5nIHRoZSBjYW1lcmFfaW5mbyBvZiB0aGUgZ2l2ZW4gY2FtZXJhX2lkICovCnN0YXRpYyBjb25zdCBxY2FtZXJhX2luZm9fdCAqIG1tX2NhbWVyYV9jZmdfcXVlcnlfY2FtZXJhX2luZm8gKGludDhfdCBjYW1lcmFfaWQpCnsKICAgIGlmKGNhbWVyYV9pZCA+PSBNU01fTUFYX0NBTUVSQV9TRU5TT1JTKQogICAgICAgIHJldHVybiBOVUxMOwogICAgcmV0dXJuICZnX2NhbV9jdHJsLmNhbWVyYVtjYW1lcmFfaWRdLmNhbWVyYV9pbmZvOwp9Ci8qIGNoZWNrIGlmIHRoZSBwYXJtIGlzIHN1cHBvcnRlZCAqLwpzdGF0aWMgdWludDhfdCBtbV9jYW1lcmFfY2ZnX2lzX3Bhcm1fc3VwcG9ydGVkIChtbV9jYW1lcmFfdCAqIGNhbWVyYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW1fY2FtZXJhX3Bhcm1fdHlwZV90IHBhcm1fdHlwZSkKewogICAgaW50IGlzX3Bhcm1fc3VwcG9ydGVkID0gMDsKICAgIG1tX2NhbWVyYV9vYmpfdCAqIG15X29iaiA9IE5VTEw7CgogICAgcHRocmVhZF9tdXRleF9sb2NrKCZnX211dGV4KTsKICAgIG15X29iaiA9IGdfY2FtX2N0cmwuY2FtX29ialtjYW1lcmEtPmNhbWVyYV9pbmZvLmNhbWVyYV9pZF07CiAgICBwdGhyZWFkX211dGV4X3VubG9jaygmZ19tdXRleCk7CiAgICBpZihteV9vYmopIHsKICAgICAgICBwdGhyZWFkX211dGV4X2xvY2soJm15X29iai0+bXV0ZXgpOwogICAgICAgIGlzX3Bhcm1fc3VwcG9ydGVkID0gR0VUX1BBUk1fQklUMzIocGFybV90eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXlfb2JqLT5wcm9wZXJ0aWVzLnBhcm0pOwogICAgICAgIHB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZteV9vYmotPm11dGV4KTsKICAgIH0KCiAgICByZXR1cm4gaXNfcGFybV9zdXBwb3J0ZWQ7Cn0KCi8qIGNoZWNrIGlmIHRoZSBjaGFubmVsIGlzIHN1cHBvcnRlZCAqLwpzdGF0aWMgdWludDhfdCBtbV9jYW1lcmFfY2ZnX2lzX2NoX3N1cHBvcnRlZCAobW1fY2FtZXJhX3QgKiBjYW1lcmEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtbV9jYW1lcmFfY2hhbm5lbF90eXBlX3QgY2hfdHlwZSkKewogICAgc3dpdGNoKGNoX3R5cGUpIHsKICAgIGNhc2UgTU1fQ0FNRVJBX0NIX1BSRVZJRVc6CiAgICBjYXNlIE1NX0NBTUVSQV9DSF9WSURFTzoKICAgIGNhc2UgTU1fQ0FNRVJBX0NIX1NOQVBTSE9UOgogICAgY2FzZSBNTV9DQU1FUkFfQ0hfUkFXOgogICAgICAgIHJldHVybiBUUlVFOwogICAgY2FzZSBNTV9DQU1FUkFfQ0hfTUFYOgogICAgZGVmYXVsdDoKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CiAgICByZXR1cm4gRkFMU0U7Cn0KCi8qIHNldCBhIHBhcm2ScyBjdXJyZW50IHZhbHVlICovCnN0YXRpYyBpbnQzMl90IG1tX2NhbWVyYV9jZmdfc2V0X3Bhcm0gKG1tX2NhbWVyYV90ICogY2FtZXJhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtbV9jYW1lcmFfcGFybV90eXBlX3QgcGFybV90eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpwX3ZhbHVlKQp7CiAgICBpbnQzMl90IHJjID0gLU1NX0NBTUVSQV9FX0dFTkVSQUw7CiAgICB1aW50MzJfdCB0bXA7CiAgICBtbV9jYW1lcmFfb2JqX3QgKiBteV9vYmogPSBOVUxMOwogICAgbW1fY2FtZXJhX3Bhcm1fdCBwYXJtID0gey5wYXJtX3R5cGUgPSBwYXJtX3R5cGUsIC5wX3ZhbHVlID0gcF92YWx1ZX07CgogICAgcHRocmVhZF9tdXRleF9sb2NrKCZnX211dGV4KTsKICAgIG15X29iaiA9IGdfY2FtX2N0cmwuY2FtX29ialtjYW1lcmEtPmNhbWVyYV9pbmZvLmNhbWVyYV9pZF07CiAgICBwdGhyZWFkX211dGV4X3VubG9jaygmZ19tdXRleCk7CiAgICBpZihteV9vYmopIHsKICAgICAgICBwdGhyZWFkX211dGV4X2xvY2soJm15X29iai0+bXV0ZXgpOwogICAgICAgIHJjID0gbW1fY2FtZXJhX3NldF9wYXJtKG15X29iaiwgJnBhcm0pOwogICAgICAgIHB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZteV9vYmotPm11dGV4KTsKICAgIH0KICAgIHJldHVybiByYzsKfQoKLyogZ2V0IGEgcGFybZJzIGN1cnJlbnQgdmFsdWUgKi8Kc3RhdGljIGludDMyX3QgbW1fY2FtZXJhX2NmZ19nZXRfcGFybSAobW1fY2FtZXJhX3QgKiBjYW1lcmEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1tX2NhbWVyYV9wYXJtX3R5cGVfdCBwYXJtX3R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQqIHBfdmFsdWUpCnsKICAgIGludDMyX3QgcmMgPSAtTU1fQ0FNRVJBX0VfR0VORVJBTDsKICAgIHVpbnQzMl90IHRtcDsKICAgIG1tX2NhbWVyYV9vYmpfdCAqIG15X29iaiA9IE5VTEw7CiAgICBtbV9jYW1lcmFfcGFybV90IHBhcm0gPSB7LnBhcm1fdHlwZSA9IHBhcm1fdHlwZSwgLnBfdmFsdWUgPSBwX3ZhbHVlfTsKCiAgICBwdGhyZWFkX211dGV4X2xvY2soJmdfbXV0ZXgpOwogICAgbXlfb2JqID0gZ19jYW1fY3RybC5jYW1fb2JqW2NhbWVyYS0+Y2FtZXJhX2luZm8uY2FtZXJhX2lkXTsKICAgIHB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZnX211dGV4KTsKICAgIGlmKG15X29iaikgewogICAgICAgIHB0aHJlYWRfbXV0ZXhfbG9jaygmbXlfb2JqLT5tdXRleCk7CiAgICAgICAgcmMgPSAgbW1fY2FtZXJhX2dldF9wYXJtKG15X29iaiwgJnBhcm0pOwogICAgICAgIHB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZteV9vYmotPm11dGV4KTsKICAgIH0KICAgIHJldHVybiByYzsKfQoKc3RhdGljIGludDMyX3QgbW1fY2FtZXJhX2NmZ19yZXF1ZXN0X2J1ZihtbV9jYW1lcmFfdCAqIGNhbWVyYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtbV9jYW1lcmFfcmVnX2J1Zl90ICpidWYpCnsKICAgIGludDMyX3QgcmMgPSAtTU1fQ0FNRVJBX0VfR0VORVJBTDsKICAgIHVpbnQzMl90IHRtcDsKICAgIG1tX2NhbWVyYV9vYmpfdCAqIG15X29iaiA9IE5VTEw7CgogICAgcHRocmVhZF9tdXRleF9sb2NrKCZnX211dGV4KTsKICAgIG15X29iaiA9IGdfY2FtX2N0cmwuY2FtX29ialtjYW1lcmEtPmNhbWVyYV9pbmZvLmNhbWVyYV9pZF07CiAgICBwdGhyZWFkX211dGV4X3VubG9jaygmZ19tdXRleCk7CiAgICBpZihteV9vYmopIHsKICAgICAgICBwdGhyZWFkX211dGV4X2xvY2soJm15X29iai0+bXV0ZXgpOwogICAgICAgIHJjID0gIG1tX2NhbWVyYV9yZXF1ZXN0X2J1ZihteV9vYmosIGJ1Zik7CiAgICAgICAgcHRocmVhZF9tdXRleF91bmxvY2soJm15X29iai0+bXV0ZXgpOwogICAgfQogICAgcmV0dXJuIHJjOwp9CgpzdGF0aWMgaW50MzJfdCBtbV9jYW1lcmFfY2ZnX3ByZXBhcmVfYnVmKG1tX2NhbWVyYV90ICogY2FtZXJhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1tX2NhbWVyYV9yZWdfYnVmX3QgKmJ1ZikKewogICAgaW50MzJfdCByYyA9IC1NTV9DQU1FUkFfRV9HRU5FUkFMOwogICAgdWludDMyX3QgdG1wOwogICAgbW1fY2FtZXJhX29ial90ICogbXlfb2JqID0gTlVMTDsKCiAgICBwdGhyZWFkX211dGV4X2xvY2soJmdfbXV0ZXgpOwogICAgbXlfb2JqID0gZ19jYW1fY3RybC5jYW1fb2JqW2NhbWVyYS0+Y2FtZXJhX2luZm8uY2FtZXJhX2lkXTsKICAgIHB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZnX211dGV4KTsKICAgIGlmKG15X29iaikgewogICAgICAgIHB0aHJlYWRfbXV0ZXhfbG9jaygmbXlfb2JqLT5tdXRleCk7CiAgICAgICAgcmMgPSAgbW1fY2FtZXJhX3ByZXBhcmVfYnVmKG15X29iaiwgYnVmKTsKICAgICAgICBwdGhyZWFkX211dGV4X3VubG9jaygmbXlfb2JqLT5tdXRleCk7CiAgICB9CiAgICByZXR1cm4gcmM7Cn0Kc3RhdGljIGludDMyX3QgbW1fY2FtZXJhX2NmZ191bnByZXBhcmVfYnVmKG1tX2NhbWVyYV90ICogY2FtZXJhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW1fY2FtZXJhX2NoYW5uZWxfdHlwZV90IGNoX3R5cGUpCnsKICAgIGludDMyX3QgcmMgPSAtTU1fQ0FNRVJBX0VfR0VORVJBTDsKICAgIHVpbnQzMl90IHRtcDsKICAgIG1tX2NhbWVyYV9vYmpfdCAqIG15X29iaiA9IE5VTEw7CgogICAgcHRocmVhZF9tdXRleF9sb2NrKCZnX211dGV4KTsKICAgIG15X29iaiA9IGdfY2FtX2N0cmwuY2FtX29ialtjYW1lcmEtPmNhbWVyYV9pbmZvLmNhbWVyYV9pZF07CiAgICBwdGhyZWFkX211dGV4X3VubG9jaygmZ19tdXRleCk7CiAgICBpZihteV9vYmopIHsKICAgICAgICBwdGhyZWFkX211dGV4X2xvY2soJm15X29iai0+bXV0ZXgpOwogICAgICAgIHJjID0gIG1tX2NhbWVyYV91bnByZXBhcmVfYnVmKG15X29iaixjaF90eXBlKTsKICAgICAgICBwdGhyZWFkX211dGV4X3VubG9jaygmbXlfb2JqLT5tdXRleCk7CiAgICB9CiAgICByZXR1cm4gcmM7Cn0KCnN0YXRpYyBtbV9jYW1lcmFfY29uZmlnX3QgbW1fY2FtZXJhX2NmZyA9IHsKICAuaXNfcGFybV9zdXBwb3J0ZWQgPSBtbV9jYW1lcmFfY2ZnX2lzX3Bhcm1fc3VwcG9ydGVkLAogIC5pc19jaF9zdXBwb3J0ZWQgPSBtbV9jYW1lcmFfY2ZnX2lzX2NoX3N1cHBvcnRlZCwKICAuc2V0X3Bhcm0gPSBtbV9jYW1lcmFfY2ZnX3NldF9wYXJtLAogIC5nZXRfcGFybSA9IG1tX2NhbWVyYV9jZmdfZ2V0X3Bhcm0sCiAgLnJlcXVlc3RfYnVmID0gbW1fY2FtZXJhX2NmZ19yZXF1ZXN0X2J1ZiwKICAucHJlcGFyZV9idWYgPSBtbV9jYW1lcmFfY2ZnX3ByZXBhcmVfYnVmLAogIC51bnByZXBhcmVfYnVmID0gbW1fY2FtZXJhX2NmZ191bnByZXBhcmVfYnVmCn07CgpzdGF0aWMgdWludDhfdCBtbV9jYW1lcmFfb3BzX2lzX29wX3N1cHBvcnRlZCAobW1fY2FtZXJhX3QgKiBjYW1lcmEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtbV9jYW1lcmFfb3BzX3R5cGVfdCBvcGNvZGUpCnsKICAgIHVpbnQ4X3QgaXNfb3BzX3N1cHBvcnRlZDsKICAgIG1tX2NhbWVyYV9vYmpfdCAqIG15X29iaiA9IE5VTEw7CiAgICBpbnQgaW5kZXggPSAwOwogICAgbW1fY2FtZXJhX2xlZ2FjeV9vcHNfdHlwZV90IGxlZ2FjeV9vcGNvZGUgPSBDQU1FUkFfT1BTX01BWDsKCiAgICAvKiBUZW1wOiBXZSB3aWxsIGJlIHRyYW5zbGF0aW5nIG91ciBuZXcgb3Bjb2RlCiAgICAgICB0byBsZWdhY3kgb3BzIHR5cGUuIFRoaXMgaXMganVzdCBhIGhhY2sgdG8KICAgICAgIHRlbXBvcmFyaWx5IHVuYmxvY2sgQVBUIHRlYW0uIE5ldyBkZXNpZ24gaXMKICAgICAgIHVuZGVyIGRpc2N1c3Npb24gKi8KICAgIHN3aXRjaCAob3Bjb2RlKSB7CiAgICBjYXNlIE1NX0NBTUVSQV9PUFNfUFJFVklFVzoKICAgICAgICBsZWdhY3lfb3Bjb2RlID0gQ0FNRVJBX09QU19TVFJFQU1JTkdfUFJFVklFVzsKICAgICAgICBicmVhazsKICAgIGNhc2UgTU1fQ0FNRVJBX09QU19WSURFTzoKICAgICAgICBsZWdhY3lfb3Bjb2RlID0gQ0FNRVJBX09QU19TVFJFQU1JTkdfVklERU87CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIE1NX0NBTUVSQV9PUFNfUFJFUEFSRV9TTkFQU0hPVDoKICAgICAgICBsZWdhY3lfb3Bjb2RlID0gQ0FNRVJBX09QU19QUkVQQVJFX1NOQVBTSE9UOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBNTV9DQU1FUkFfT1BTX1NOQVBTSE9UOgogICAgICAgIGxlZ2FjeV9vcGNvZGUgPSBDQU1FUkFfT1BTX1NOQVBTSE9UOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBNTV9DQU1FUkFfT1BTX1JBVzoKICAgICAgICBsZWdhY3lfb3Bjb2RlID0gQ0FNRVJBX09QU19SQVdfQ0FQVFVSRTsKICAgICAgICBicmVhazsKICAgIGNhc2UgTU1fQ0FNRVJBX09QU19aU0w6CiAgICAgICAgbGVnYWN5X29wY29kZSA9IENBTUVSQV9PUFNfU1RSRUFNSU5HX1pTTDsKICAgICAgICBicmVhazsKICAgIGNhc2UgTU1fQ0FNRVJBX09QU19GT0NVUzoKICAgICAgICBsZWdhY3lfb3Bjb2RlID0gQ0FNRVJBX09QU19GT0NVUzsKICAgICAgICBicmVhazsKICAgIGNhc2UgTU1fQ0FNRVJBX09QU19HRVRfQlVGRkVSRURfRlJBTUU6CiAgICAgIGxlZ2FjeV9vcGNvZGUgPSBDQU1FUkFfT1BTX0xPQ0FMOwogICAgICBpc19vcHNfc3VwcG9ydGVkID0gVFJVRTsKICAgICAgQ0RCRygiTU1fQ0FNRVJBX09QU19HRVRfQlVGRkVSRURfRlJBTUUgbm90IGhhbmRsZWQiKTsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICBDREJHX0VSUk9SKCIlczogY2FzZSAlZCBub3QgaGFuZGxlZCIsIF9fZnVuY19fLCBvcGNvZGUpOwogICAgICBsZWdhY3lfb3Bjb2RlID0gQ0FNRVJBX09QU19MT0NBTDsKICAgICAgaXNfb3BzX3N1cHBvcnRlZCA9IEZBTFNFOwogICAgICBicmVhazsKICAgIH0KICAgIGlmIChsZWdhY3lfb3Bjb2RlICE9IENBTUVSQV9PUFNfTE9DQUwpIHsKICAgIHB0aHJlYWRfbXV0ZXhfbG9jaygmZ19tdXRleCk7CiAgICBteV9vYmogPSBnX2NhbV9jdHJsLmNhbV9vYmpbY2FtZXJhLT5jYW1lcmFfaW5mby5jYW1lcmFfaWRdOwogICAgcHRocmVhZF9tdXRleF91bmxvY2soJmdfbXV0ZXgpOwogICAgaWYobXlfb2JqKSB7CiAgICAgICAgcHRocmVhZF9tdXRleF9sb2NrKCZteV9vYmotPm11dGV4KTsKICAgICAgICBpbmRleCA9IGxlZ2FjeV9vcGNvZGUvMzI7ICAvKiAzMiBiaXRzICovCiAgICAgICAgaXNfb3BzX3N1cHBvcnRlZCA9ICgobXlfb2JqLT5wcm9wZXJ0aWVzLm9wc1tpbmRleF0gJgogICAgICAgICAgICAoMTw8bGVnYWN5X29wY29kZSkpICE9IDApOwogICAgICAgIHB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZteV9vYmotPm11dGV4KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBpc19vcHNfc3VwcG9ydGVkID0gRkFMU0U7CiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gaXNfb3BzX3N1cHBvcnRlZDsKfQoKc3RhdGljIGludDMyX3QgbW1fY2FtZXJhX29wc19hY3Rpb24gKG1tX2NhbWVyYV90ICogY2FtZXJhLCB1aW50OF90IHN0YXJ0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtbV9jYW1lcmFfb3BzX3R5cGVfdCBvcGNvZGUsIHZvaWQgKnZhbCkKewogICAgaW50MzJfdCByYyA9IC1NTV9DQU1FUkFfRV9HRU5FUkFMOwogICAgbW1fY2FtZXJhX29ial90ICogbXlfb2JqID0gTlVMTDsKICAgIHB0aHJlYWRfbXV0ZXhfbG9jaygmZ19tdXRleCk7CiAgICBteV9vYmogPSBnX2NhbV9jdHJsLmNhbV9vYmpbY2FtZXJhLT5jYW1lcmFfaW5mby5jYW1lcmFfaWRdOwogICAgcHRocmVhZF9tdXRleF91bmxvY2soJmdfbXV0ZXgpOwogICAgaWYobXlfb2JqKSB7CiAgICAgICAgcHRocmVhZF9tdXRleF9sb2NrKCZteV9vYmotPm11dGV4KTsKICAgICAgICByYyA9IG1tX2NhbWVyYV9hY3Rpb24obXlfb2JqLCBzdGFydCwgb3Bjb2RlLCB2YWwpOwogICAgICAgIHB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZteV9vYmotPm11dGV4KTsKICAgIH0KICAgIHJldHVybiByYzsKfQoKLyogb3BlbiB1c2VzIGZsYWdzIHRvIG9wdGlvbmFsbHkgZGlzYWJsZSBqcGVnL3ZwZSBpbnRlcmZhY2UuICovCnN0YXRpYyBpbnQzMl90IG1tX2NhbWVyYV9vcHNfb3BlbiAobW1fY2FtZXJhX3QgKiBjYW1lcmEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW1fY2FtZXJhX29wX21vZGVfdHlwZV90IG9wX21vZGUpCnsKICAgIGludDhfdCBjYW1lcmFfaWQgPSBjYW1lcmEtPmNhbWVyYV9pbmZvLmNhbWVyYV9pZDsKICAgIGludDMyX3QgcmMgPSBNTV9DQU1FUkFfT0s7CgogICAgQ0RCRygiJXM6IEJFR0lOXG4iLCBfX2Z1bmNfXyk7CiAgICBwdGhyZWFkX211dGV4X2xvY2soJmdfbXV0ZXgpOwogICAgLyogbm90IGZpcnN0IG9wZW4gKi8KICAgIGlmKGdfY2FtX2N0cmwuY2FtX29ialtjYW1lcmFfaWRdKSB7CiAgICAgICAgZ19jYW1fY3RybC5jYW1fb2JqW2NhbWVyYV9pZF0tPnJlZl9jb3VudCsrOwogICAgQ0RCRygiJXM6ICBvcGVuZWQgYWxyZWFkeW4iLCBfX2Z1bmNfXyk7CiAgICAgICAgZ290byBlbmQ7CiAgICB9CiAgICBnX2NhbV9jdHJsLmNhbV9vYmpbY2FtZXJhX2lkXSA9CiAgICAobW1fY2FtZXJhX29ial90ICopbWFsbG9jKHNpemVvZihtbV9jYW1lcmFfb2JqX3QpKTsKICAgIGlmKCFnX2NhbV9jdHJsLmNhbV9vYmpbY2FtZXJhX2lkXSkgewogICAgICAgIHJjID0gLU1NX0NBTUVSQV9FX05PX01FTU9SWTsKICAgICBDREJHKCIlczogIG5vIG1lbSIsIF9fZnVuY19fKTsKICAgICAgIGdvdG8gZW5kOwogICAgfQogICAgbWVtc2V0KGdfY2FtX2N0cmwuY2FtX29ialtjYW1lcmFfaWRdLCAwLAogICAgICAgICAgICAgICAgIHNpemVvZihtbV9jYW1lcmFfb2JqX3QpKTsKICAgIC8vZ19jYW1fY3RybC5jYW1fb2JqW2NhbWVyYV9pZF0tPmN0cmxfZmQgPSAtMTsKICAgIGdfY2FtX2N0cmwuY2FtX29ialtjYW1lcmFfaWRdLT5yZWZfY291bnQrKzsKICAgIGdfY2FtX2N0cmwuY2FtX29ialtjYW1lcmFfaWRdLT5teV9pZD1jYW1lcmFfaWQ7CgogICAgcHRocmVhZF9tdXRleF9pbml0KCZnX2NhbV9jdHJsLmNhbV9vYmpbY2FtZXJhX2lkXS0+bXV0ZXgsIE5VTEwpOwogICAgcmMgPSBtbV9jYW1lcmFfb3BlbihnX2NhbV9jdHJsLmNhbV9vYmpbY2FtZXJhX2lkXSwgb3BfbW9kZSk7CiAgICBpZihyYyA8IDApIHsKICAgICAgICBDREJHKCIlczogb3BlbiBmYWlsZWQsIHJjID0gJWRcbiIsIF9fZnVuY19fLCByYyk7CiAgICAgICAgcHRocmVhZF9tdXRleF9kZXN0cm95KCZnX2NhbV9jdHJsLmNhbV9vYmpbY2FtZXJhX2lkXS0+bXV0ZXgpOwogICAgICAgIGdfY2FtX2N0cmwuY2FtX29ialtjYW1lcmFfaWRdLT5yZWZfY291bnQtLTsKICAgICAgICBmcmVlKGdfY2FtX2N0cmwuY2FtX29ialtjYW1lcmFfaWRdKTsKICAgICAgICBnX2NhbV9jdHJsLmNhbV9vYmpbY2FtZXJhX2lkXT1OVUxMOwogICAgQ0RCRygiJXM6IG1tX2NhbWVyYV9vcGVuIGVyciA9ICVkIiwgX19mdW5jX18sIHJjKTsKICAgICAgICBnb3RvIGVuZDsKICAgIH1lbHNlewogICAgICAgIENEQkcoIiVzOiBvcGVuIHN1Y2NlZGVkXG4iLCBfX2Z1bmNfXyk7CiAgICB9CmVuZDoKICAgIHB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZnX211dGV4KTsKICAgIENEQkcoIiVzOiBFTkQsIHJjPSVkXG4iLCBfX2Z1bmNfXywgcmMpOwogICAgcmV0dXJuIHJjOwp9CgpzdGF0aWMgdm9pZCBtbV9jYW1lcmFfb3BzX2Nsb3NlIChtbV9jYW1lcmFfdCAqIGNhbWVyYSkKewogICAgbW1fY2FtZXJhX29ial90ICogbXlfb2JqOwogICAgaW50IGk7CiAgICBpbnQ4X3QgY2FtZXJhX2lkID0gY2FtZXJhLT5jYW1lcmFfaW5mby5jYW1lcmFfaWQ7CgogICAgcHRocmVhZF9tdXRleF9sb2NrKCZnX211dGV4KTsKICAgIG15X29iaiA9IGdfY2FtX2N0cmwuY2FtX29ialtjYW1lcmFfaWRdOwogICAgaWYobXlfb2JqKSB7CiAgICAgIG15X29iai0+cmVmX2NvdW50LS07CiAgICAgIGlmKG15X29iai0+cmVmX2NvdW50ID4gMCkgewogICAgICAgIENEQkcoIiVzOiByZWZfY291bnQ9JWRcbiIsIF9fZnVuY19fLCBteV9vYmotPnJlZl9jb3VudCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgLy8gbW1fY2FtZXJhX3BvbGxfdGhyZWFkX3JlbGVhc2UobXlfb2JqLCBNTV9DQU1FUkFfQ0hfTUFYKTsKICAgICAgICAodm9pZCltbV9jYW1lcmFfY2xvc2UoZ19jYW1fY3RybC5jYW1fb2JqW2NhbWVyYV9pZF0pOwogICAgICAgIHB0aHJlYWRfbXV0ZXhfZGVzdHJveSgmbXlfb2JqLT5tdXRleCk7CiAgICAgICAgZnJlZShteV9vYmopOwogICAgICAgIGdfY2FtX2N0cmwuY2FtX29ialtjYW1lcmFfaWRdID0gTlVMTDsKICAgICAgfQogICAgfQogICAgcHRocmVhZF9tdXRleF91bmxvY2soJmdfbXV0ZXgpOwp9CgpzdGF0aWMgdm9pZCBtbV9jYW1lcmFfb3BzX3N0b3AgKG1tX2NhbWVyYV90ICogY2FtZXJhKQp7CiAgICBtbV9jYW1lcmFfb2JqX3QgKiBteV9vYmo7CiAgICBpbnQgaTsKICAgIGludDhfdCBjYW1lcmFfaWQgPSBjYW1lcmEtPmNhbWVyYV9pbmZvLmNhbWVyYV9pZDsKCiAgICBwdGhyZWFkX211dGV4X2xvY2soJmdfbXV0ZXgpOwogICAgbXlfb2JqID0gZ19jYW1fY3RybC5jYW1fb2JqW2NhbWVyYV9pZF07CiAgICBpZihteV9vYmopIHsKICAgICAgICBDREJHKCIlcyA6IENsb3NlIFRocmVhZHMgaW4gbW1fY2FtZXJhX29wc19zdG9wIixfX2Z1bmNfXyk7CiAgICAgICAgZm9yKGkgPSAwOyBpIDw9IE1NX0NBTUVSQV9DSF9NQVg7IGkrKykgewogICAgICAgICAgICBtbV9jYW1lcmFfcG9sbF90aHJlYWRfcmVsZWFzZShteV9vYmosKG1tX2NhbWVyYV9jaGFubmVsX3R5cGVfdClpKTsKICAgICAgICB9CiAgICAgICAgbW1fY2FtZXJhX3BvbGxfdGhyZWFkc19kZWluaXQobXlfb2JqKTsKICAgIH0KICAgIHB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZnX211dGV4KTsKfQoKCnN0YXRpYyBpbnQzMl90IG1tX2NhbWVyYV9vcHNfY2hfYWNxdWlyZShtbV9jYW1lcmFfdCAqIGNhbWVyYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1tX2NhbWVyYV9jaGFubmVsX3R5cGVfdCBjaF90eXBlKQp7CiAgICBpbnQzMl90IHJjID0gLU1NX0NBTUVSQV9FX0dFTkVSQUw7CiAgICBtbV9jYW1lcmFfb2JqX3QgKiBteV9vYmogPSBOVUxMOwogICAgcHRocmVhZF9tdXRleF9sb2NrKCZnX211dGV4KTsKICAgIG15X29iaiA9IGdfY2FtX2N0cmwuY2FtX29ialtjYW1lcmEtPmNhbWVyYV9pbmZvLmNhbWVyYV9pZF07CiAgICBwdGhyZWFkX211dGV4X3VubG9jaygmZ19tdXRleCk7CiAgICBpZihteV9vYmopIHsKICAgICAgICBwdGhyZWFkX211dGV4X2xvY2soJm15X29iai0+bXV0ZXgpOwogICAgICAgIHJjID0gbW1fY2FtZXJhX2NoX2FjcXVpcmUobXlfb2JqLCBjaF90eXBlKTsKICAgICAgICBwdGhyZWFkX211dGV4X3VubG9jaygmbXlfb2JqLT5tdXRleCk7CiAgICB9CiAgICByZXR1cm4gcmM7Cgp9CnN0YXRpYyB2b2lkIG1tX2NhbWVyYV9vcHNfY2hfcmVsZWFzZShtbV9jYW1lcmFfdCAqIGNhbWVyYSwgbW1fY2FtZXJhX2NoYW5uZWxfdHlwZV90IGNoX3R5cGUpCnsKICAgIG1tX2NhbWVyYV9vYmpfdCAqIG15X29iaiA9IE5VTEw7CiAgICBwdGhyZWFkX211dGV4X2xvY2soJmdfbXV0ZXgpOwogICAgbXlfb2JqID0gZ19jYW1fY3RybC5jYW1fb2JqW2NhbWVyYS0+Y2FtZXJhX2luZm8uY2FtZXJhX2lkXTsKICAgIHB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZnX211dGV4KTsKICAgIGlmKG15X29iaikgewogICAgICAgIHB0aHJlYWRfbXV0ZXhfbG9jaygmbXlfb2JqLT5tdXRleCk7CiAgICAgICAgbW1fY2FtZXJhX2NoX3JlbGVhc2UobXlfb2JqLCBjaF90eXBlKTsKICAgICAgICBwdGhyZWFkX211dGV4X3VubG9jaygmbXlfb2JqLT5tdXRleCk7CiAgICB9Cn0KCnN0YXRpYyBpbnQzMl90IG1tX2NhbWVyYV9vcHNfY2hfYXR0cihtbV9jYW1lcmFfdCAqIGNhbWVyYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1tX2NhbWVyYV9jaGFubmVsX3R5cGVfdCBjaF90eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW1fY2FtZXJhX2NoYW5uZWxfYXR0cl90ICphdHRyKQp7CiAgICBtbV9jYW1lcmFfb2JqX3QgKiBteV9vYmogPSBOVUxMOwogICAgaW50MzJfdCByYyA9IC1NTV9DQU1FUkFfRV9HRU5FUkFMOwogICAgcHRocmVhZF9tdXRleF9sb2NrKCZnX211dGV4KTsKICAgIG15X29iaiA9IGdfY2FtX2N0cmwuY2FtX29ialtjYW1lcmEtPmNhbWVyYV9pbmZvLmNhbWVyYV9pZF07CiAgICBwdGhyZWFkX211dGV4X3VubG9jaygmZ19tdXRleCk7CiAgICBpZihteV9vYmopIHsKICAgICAgICBwdGhyZWFkX211dGV4X2xvY2soJm15X29iai0+bXV0ZXgpOwogICAgICAgIHJjID0gbW1fY2FtZXJhX2NoX2ZuKG15X29iaiwgY2hfdHlwZSwgTU1fQ0FNRVJBX1NUQVRFX0VWVF9BVFRSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQgKilhdHRyKTsKICAgICAgICBwdGhyZWFkX211dGV4X3VubG9jaygmbXlfb2JqLT5tdXRleCk7CiAgICB9CiAgICByZXR1cm4gcmM7Cn0KCnN0YXRpYyBpbnQzMl90IG1tX2NhbWVyYV9vcHNfc2VuZG1zZyhtbV9jYW1lcmFfdCAqIGNhbWVyYSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKm1zZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IGJ1Zl9zaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHNlbmRmZCkKewogICAgaW50MzJfdCByYyA9IC1NTV9DQU1FUkFfRV9HRU5FUkFMOwogICAgbW1fY2FtZXJhX29ial90ICogbXlfb2JqID0gTlVMTDsKICAgIHB0aHJlYWRfbXV0ZXhfbG9jaygmZ19tdXRleCk7CiAgICBteV9vYmogPSBnX2NhbV9jdHJsLmNhbV9vYmpbY2FtZXJhLT5jYW1lcmFfaW5mby5jYW1lcmFfaWRdOwogICAgcHRocmVhZF9tdXRleF91bmxvY2soJmdfbXV0ZXgpOwogICAgaWYobXlfb2JqKSB7CiAgICAgICAgcHRocmVhZF9tdXRleF9sb2NrKCZteV9vYmotPm11dGV4KTsKICAgICAgICByYyA9IG1tX2NhbWVyYV9zZW5kbXNnKG15X29iaiwgbXNnLCBidWZfc2l6ZSwgc2VuZGZkKTsKICAgICAgICBwdGhyZWFkX211dGV4X3VubG9jaygmbXlfb2JqLT5tdXRleCk7CiAgICB9CiAgICByZXR1cm4gcmM7Cn0KCnN0YXRpYyBtbV9jYW1lcmFfb3BzX3QgbW1fY2FtZXJhX29wcyA9IHsKICAuaXNfb3Bfc3VwcG9ydGVkID0gbW1fY2FtZXJhX29wc19pc19vcF9zdXBwb3J0ZWQsCiAgICAuYWN0aW9uID0gbW1fY2FtZXJhX29wc19hY3Rpb24sCiAgICAub3BlbiA9IG1tX2NhbWVyYV9vcHNfb3BlbiwKICAgIC5jbG9zZSA9IG1tX2NhbWVyYV9vcHNfY2xvc2UsCiAgICAuc3RvcCA9IG1tX2NhbWVyYV9vcHNfc3RvcCwKICAgIC5jaF9hY3F1aXJlID0gbW1fY2FtZXJhX29wc19jaF9hY3F1aXJlLAogICAgLmNoX3JlbGVhc2UgPSBtbV9jYW1lcmFfb3BzX2NoX3JlbGVhc2UsCiAgICAuY2hfc2V0X2F0dHIgPSBtbV9jYW1lcmFfb3BzX2NoX2F0dHIsCiAgICAuc2VuZG1zZyA9IG1tX2NhbWVyYV9vcHNfc2VuZG1zZwp9OwoKc3RhdGljIHVpbnQ4X3QgbW1fY2FtZXJhX25vdGlmeV9pc19ldmVudF9zdXBwb3J0ZWQobW1fY2FtZXJhX3QgKiBjYW1lcmEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW1fY2FtZXJhX2V2ZW50X3R5cGVfdCBldnRfdHlwZSkKewogIHN3aXRjaChldnRfdHlwZSkgewogIGNhc2UgTU1fQ0FNRVJBX0VWVF9UWVBFX0NIOgogIGNhc2UgTU1fQ0FNRVJBX0VWVF9UWVBFX0NUUkw6CiAgY2FzZSBNTV9DQU1FUkFfRVZUX1RZUEVfU1RBVFM6CiAgY2FzZSBNTV9DQU1FUkFfRVZUX1RZUEVfSU5GTzoKICAgIHJldHVybiAxOwogIGRlZmF1bHQ6CiAgICByZXR1cm4gMDsKICB9CiAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQzMl90IG1tX2NhbWVyYV9ub3RpZnlfcmVnaXN0ZXJfZXZlbnRfY2IobW1fY2FtZXJhX3QgKiBjYW1lcmEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW1fY2FtZXJhX2V2ZW50X25vdGlmeV90IGV2dF9jYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqIHVzZXJfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtbV9jYW1lcmFfZXZlbnRfdHlwZV90IGV2dF90eXBlKQp7CiAgbW1fY2FtZXJhX29ial90ICogbXlfb2JqID0gTlVMTDsKICBtbV9jYW1lcmFfYnVmX2NiX3QgcmVnIDsKICBpbnQgcmMgPSAtMTsKCiAgcHRocmVhZF9tdXRleF9sb2NrKCZnX211dGV4KTsKICBteV9vYmogPSBnX2NhbV9jdHJsLmNhbV9vYmpbY2FtZXJhLT5jYW1lcmFfaW5mby5jYW1lcmFfaWRdOwogIHB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZnX211dGV4KTsKICBpZihteV9vYmopIHsKICAgICAgcHRocmVhZF9tdXRleF9sb2NrKCZteV9vYmotPm11dGV4KTsKICAgICAgcmMgPSBtbV9jYW1lcmFfcmVnX2V2ZW50KG15X29iaiwgZXZ0X2NiLCB1c2VyX2RhdGEsIGV2dF90eXBlKTsKICAgICAgcHRocmVhZF9tdXRleF91bmxvY2soJm15X29iai0+bXV0ZXgpOwogIH0KICByZXR1cm4gcmM7Cn0KCnN0YXRpYyBpbnQzMl90IG1tX2NhbWVyYV9yZWdpc3Rlcl9idWZfbm90aWZ5ICgKICAgICAgICAgIG1tX2NhbWVyYV90ICogY2FtZXJhLAogICAgICAgICAgbW1fY2FtZXJhX2NoYW5uZWxfdHlwZV90IGNoX3R5cGUsCiAgICAgICAgICBtbV9jYW1lcmFfYnVmX25vdGlmeV90ICBidWZfY2IsCiAgICAgICAgICBtbV9jYW1lcmFfcmVnaXN0ZXJfYnVmX2NiX3R5cGVfdCBjYl90eXBlLAogICAgICAgICAgdWludDMyX3QgY2JfY291bnQsCiAgICAgICAgICB2b2lkICogdXNlcl9kYXRhKQp7CiAgICBtbV9jYW1lcmFfb2JqX3QgKiBteV9vYmogPSBOVUxMOwogICAgbW1fY2FtZXJhX2J1Zl9jYl90IHJlZyA7CiAgICBpbnQgcmMgPSAtMTsKCiAgICByZWcuY2IgPSBidWZfY2I7CiAgICByZWcudXNlcl9kYXRhID0gdXNlcl9kYXRhOwogICAgcmVnLmNiX3R5cGU9Y2JfdHlwZTsKICAgIHJlZy5jYl9jb3VudD1jYl9jb3VudDsKICAgIHB0aHJlYWRfbXV0ZXhfbG9jaygmZ19tdXRleCk7CiAgICBteV9vYmogPSBnX2NhbV9jdHJsLmNhbV9vYmpbY2FtZXJhLT5jYW1lcmFfaW5mby5jYW1lcmFfaWRdOwogICAgcHRocmVhZF9tdXRleF91bmxvY2soJmdfbXV0ZXgpOwogICAgaWYobXlfb2JqKSB7CiAgICAgICAgcHRocmVhZF9tdXRleF9sb2NrKCZteV9vYmotPm11dGV4KTsKICAgICAgICByYyA9IG1tX2NhbWVyYV9jaF9mbihteV9vYmosY2hfdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1NX0NBTUVSQV9TVEFURV9FVlRfUkVHX0JVRl9DQiwgKHZvaWQgKikmcmVnKTsKICAgICAgICBwdGhyZWFkX211dGV4X3VubG9jaygmbXlfb2JqLT5tdXRleCk7CiAgICB9CiAgICByZXR1cm4gcmM7Cn0Kc3RhdGljIGludDMyX3QgbW1fY2FtZXJhX2J1Zl9kb25lKG1tX2NhbWVyYV90ICogY2FtZXJhLCBtbV9jYW1lcmFfY2hfZGF0YV9idWZfdCAqIGJ1ZnMpCnsKICAgIG1tX2NhbWVyYV9vYmpfdCAqIG15X29iaiA9IE5VTEw7CiAgICBpbnQgcmMgPSAtMTsKICAgIG15X29iaiA9IGdfY2FtX2N0cmwuY2FtX29ialtjYW1lcmEtPmNhbWVyYV9pbmZvLmNhbWVyYV9pZF07CiAgICBpZihteV9vYmopIHsKICAgICAgICAvKnB0aHJlYWRfbXV0ZXhfbG9jaygmbXlfb2JqLT5tdXRleCk7Ki8KICAgICAgICByYyA9IG1tX2NhbWVyYV9jaF9mbihteV9vYmosIGJ1ZnMtPnR5cGUsCiAgICAgICAgICAgICAgICAgTU1fQ0FNRVJBX1NUQVRFX0VWVF9RQlVGLCAgICh2b2lkICopYnVmcyk7CiAgICAgICAgLypwdGhyZWFkX211dGV4X3VubG9jaygmbXlfb2JqLT5tdXRleCk7Ki8KICAgIH0KICAgIHJldHVybiByYzsKfQoKc3RhdGljIG1tX2NhbWVyYV9ub3RpZnlfdCBtbV9jYW1lcmFfbm90aWZ5ID0gewogICAgLmlzX2V2ZW50X3N1cHBvcnRlZCA9IG1tX2NhbWVyYV9ub3RpZnlfaXNfZXZlbnRfc3VwcG9ydGVkLAogICAgLnJlZ2lzdGVyX2V2ZW50X25vdGlmeSA9IG1tX2NhbWVyYV9ub3RpZnlfcmVnaXN0ZXJfZXZlbnRfY2IsCiAgICAucmVnaXN0ZXJfYnVmX25vdGlmeSA9IG1tX2NhbWVyYV9yZWdpc3Rlcl9idWZfbm90aWZ5LAogICAgLmJ1Zl9kb25lID0gbW1fY2FtZXJhX2J1Zl9kb25lCn07CgpzdGF0aWMgdWludDhfdCBtbV9jYW1lcmFfanBlZ19pc19qcGVnX3N1cHBvcnRlZCAobW1fY2FtZXJhX3QgKiBjYW1lcmEpCnsKICAgIHJldHVybiBGQUxTRTsKfQpzdGF0aWMgaW50MzJfdCBtbV9jYW1lcmFfanBlZ19zZXRfcGFybSAobW1fY2FtZXJhX3QgKiBjYW1lcmEsCiAgICAgICAgICAgICAgICAgICAgbW1fY2FtZXJhX2pwZWdfcGFybV90eXBlX3QgcGFybV90eXBlLAogICAgICAgICAgICAgICAgICAgIHZvaWQqIHBfdmFsdWUpCnsKICAgIHJldHVybiAtMTsKfQpzdGF0aWMgaW50MzJfdCBtbV9jYW1lcmFfanBlZ19nZXRfcGFybSAobW1fY2FtZXJhX3QgKiBjYW1lcmEsCiAgICAgICAgICAgICAgICAgICAgbW1fY2FtZXJhX2pwZWdfcGFybV90eXBlX3QgcGFybV90eXBlLAogICAgICAgICAgICAgICAgICAgIHZvaWQqIHBfdmFsdWUpCnsKICAgIHJldHVybiAtMTsKfQpzdGF0aWMgaW50MzJfdCBtbV9jYW1lcmFfanBlZ19yZWdpc3Rlcl9ldmVudF9jYihtbV9jYW1lcmFfdCAqIGNhbWVyYSwKICAgICAgICAgICAgICAgICAgICBtbV9jYW1lcmFfanBlZ19jYl90ICogZXZ0X2NiLAogICAgICAgICAgICAgICAgICAgIHZvaWQgKiB1c2VyX2RhdGEpCnsKICAgIHJldHVybiAtMTsKfQpzdGF0aWMgaW50MzJfdCBtbV9jYW1lcmFfanBlZ19lbmNvZGUgKG1tX2NhbWVyYV90ICogY2FtZXJhLCB1aW50OF90IHN0YXJ0LAogICAgICAgICAgICAgICAgICAgIG1tX2NhbWVyYV9qcGVnX2VuY29kZV90ICpkYXRhKQp7CiAgICByZXR1cm4gLTE7Cn0KCnN0YXRpYyBtbV9jYW1lcmFfanBlZ190IG1tX2NhbWVyYV9qcGVnID0gIHsKICAgIC5pc19qcGVnX3N1cHBvcnRlZCA9IG1tX2NhbWVyYV9qcGVnX2lzX2pwZWdfc3VwcG9ydGVkLAogICAgLnNldF9wYXJtID0gbW1fY2FtZXJhX2pwZWdfc2V0X3Bhcm0sCiAgICAuZ2V0X3Bhcm0gPSBtbV9jYW1lcmFfanBlZ19nZXRfcGFybSwKICAgIC5yZWdpc3Rlcl9ldmVudF9jYiA9IG1tX2NhbWVyYV9qcGVnX3JlZ2lzdGVyX2V2ZW50X2NiLAogICAgLmVuY29kZSA9IG1tX2NhbWVyYV9qcGVnX2VuY29kZSwKfTsKCmV4dGVybiBtbV9jYW1lcmFfdCAqIG1tX2NhbWVyYV9xdWVyeSAodWludDhfdCAqbnVtX2NhbWVyYXMpCnsKICAgIGludCBpID0gMCwgcmMgPSBNTV9DQU1FUkFfT0s7CiAgICBpbnQgZGV2X2ZkID0gMDsKICAgIHN0cnVjdCBtZWRpYV9kZXZpY2VfaW5mbyBtZGV2X2luZm87CiAgICBpbnQgbnVtX21lZGlhX2RldmljZXMgPSAwOwogICAgaWYgKCFudW1fY2FtZXJhcykKICAgICAgcmV0dXJuIE5VTEw7CiAgICAvKiBsb2NrIHRoZSBtdXRleCAqLwogICAgcHRocmVhZF9tdXRleF9sb2NrKCZnX211dGV4KTsKICAgICpudW1fY2FtZXJhcyA9IDA7CiAgICB3aGlsZSAoMSkgewogICAgICBjaGFyIGRldl9uYW1lWzMyXTsKICAgICAgc25wcmludGYoZGV2X25hbWUsIHNpemVvZihkZXZfbmFtZSksICIvZGV2L21lZGlhJWQiLCBudW1fbWVkaWFfZGV2aWNlcyk7CiAgICAgIGRldl9mZCA9IG9wZW4oZGV2X25hbWUsIE9fUkRXUiB8IE9fTk9OQkxPQ0spOwogICAgICBpZiAoZGV2X2ZkIDwgMCkgewogICAgICAgIENEQkcoIkRvbmUgZGlzY292ZXJpbmcgbWVkaWEgZGV2aWNlc1xuIik7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgbnVtX21lZGlhX2RldmljZXMrKzsKICAgICAgcmMgPSBpb2N0bChkZXZfZmQsIE1FRElBX0lPQ19ERVZJQ0VfSU5GTywgJm1kZXZfaW5mbyk7CiAgICAgIGlmIChyYyA8IDApIHsKICAgICAgICBDREJHX0VSUk9SKCJFcnJvcjogaW9jdGwgbWVkaWFfZGV2IGZhaWxlZDogJXNcbiIsIHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgY2xvc2UoZGV2X2ZkKTsKICAgICAgICBicmVhazsKICAgICAgfQoKICAgICAgaWYoc3RybmNtcChtZGV2X2luZm8ubW9kZWwsIFFDQU1FUkFfTkFNRSwgc2l6ZW9mKG1kZXZfaW5mby5tb2RlbCkgIT0gMCkpIHsKICAgICAgICBjbG9zZShkZXZfZmQpOwogICAgICAgIGNvbnRpbnVlOwogICAgICB9CgogICAgICBjaGFyICogbWRldl9jZmc7CiAgICAgIGludCBjYW1fdHlwZSA9IDAsIG1vdW50X2FuZ2xlID0gMCwgaW5mb19pbmRleCA9IDA7CiAgICAgIG1kZXZfY2ZnID0gc3RydG9rKG1kZXZfaW5mby5zZXJpYWwsICItIik7CiAgICAgIHdoaWxlKG1kZXZfY2ZnICE9IE5VTEwpIHsKICAgICAgICAgIGlmKGluZm9faW5kZXggPT0gMCkgewogICAgICAgICAgICAgIGlmKHN0cmNtcChtZGV2X2NmZywgUUNBTUVSQV9OQU1FKSkKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9IGVsc2UgaWYoaW5mb19pbmRleCA9PSAxKSB7CiAgICAgICAgICAgICAgbW91bnRfYW5nbGUgPSBhdG9pKG1kZXZfY2ZnKTsKICAgICAgICAgIH0gZWxzZSBpZihpbmZvX2luZGV4ID09IDIpIHsKICAgICAgICAgICAgICBjYW1fdHlwZSA9IGF0b2kobWRldl9jZmcpOwogICAgICAgICAgfQogICAgICAgICAgbWRldl9jZmcgPSBzdHJ0b2soTlVMTCwgIi0iKTsKICAgICAgICAgIGluZm9faW5kZXgrKzsKICAgICAgfQoKICAgICAgaWYoaW5mb19pbmRleCA9PSAwKSB7CiAgICAgICAgICBjbG9zZShkZXZfZmQpOwogICAgICAgICAgY29udGludWU7CiAgICAgIH0KCiAgICAgIGludCBudW1fZW50aXRpZXMgPSAxOwogICAgICB3aGlsZSAoMSkgewogICAgICAgIHN0cnVjdCBtZWRpYV9lbnRpdHlfZGVzYyBlbnRpdHk7CiAgICAgICAgbWVtc2V0KCZlbnRpdHksIDAsIHNpemVvZihlbnRpdHkpKTsKICAgICAgICBlbnRpdHkuaWQgPSBudW1fZW50aXRpZXMrKzsKICAgICAgICByYyA9IGlvY3RsKGRldl9mZCwgTUVESUFfSU9DX0VOVU1fRU5USVRJRVMsICZlbnRpdHkpOwogICAgICAgIGlmIChyYyA8IDApIHsKICAgICAgICAgICAgQ0RCRygiRG9uZSBlbnVtZXJhdGluZyBtZWRpYSBlbnRpdGllc1xuIik7CiAgICAgICAgICAgIHJjID0gMDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGlmKGVudGl0eS50eXBlID09IE1FRElBX0VOVF9UX0RFVk5PREVfVjRMICYmIGVudGl0eS5ncm91cF9pZCA9PSBRQ0FNRVJBX1ZOT0RFX0dST1VQX0lEKSB7CiAgICAgICAgICAgICBzdHJuY3B5KGdfY2FtX2N0cmwuY2FtZXJhWypudW1fY2FtZXJhc10udmlkZW9fZGV2X25hbWUsCiAgICAgICAgICAgICAgICAgICAgIGVudGl0eS5uYW1lLCBzaXplb2YoZW50aXR5Lm5hbWUpKTsKICAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgfQoKICAgICAgZ19jYW1fY3RybC5jYW1lcmFbKm51bV9jYW1lcmFzXS5jYW1lcmFfaW5mby5jYW1lcmFfaWQgPSAqbnVtX2NhbWVyYXM7CgogICAgICBnX2NhbV9jdHJsLmNhbWVyYVsqbnVtX2NhbWVyYXNdLgogICAgICAgICAgY2FtZXJhX2luZm8ubW9kZXNfc3VwcG9ydGVkID0gQ0FNRVJBX01PREVfMkQ7CiAgICAgIGlmKGNhbV90eXBlID4gMSkKICAgICAgICBnX2NhbV9jdHJsLmNhbWVyYVsqbnVtX2NhbWVyYXNdLgogICAgICAgICAgY2FtZXJhX2luZm8ubW9kZXNfc3VwcG9ydGVkIHw9IENBTUVSQV9NT0RFXzNEOwoKICAgICAgZ19jYW1fY3RybC5jYW1lcmFbKm51bV9jYW1lcmFzXS5jYW1lcmFfaW5mby5wb3NpdGlvbiA9CiAgICAgICAgKGNhbV90eXBlID09IDEpID8gRlJPTlRfQ0FNRVJBIDogQkFDS19DQU1FUkE7CiAgICAgIGdfY2FtX2N0cmwuY2FtZXJhWypudW1fY2FtZXJhc10uY2FtZXJhX2luZm8uc2Vuc29yX21vdW50X2FuZ2xlID0KICAgICAgICAgIG1vdW50X2FuZ2xlOwogICAgICBnX2NhbV9jdHJsLmNhbWVyYVsqbnVtX2NhbWVyYXNdLnNlbnNvcl90eXBlID0gMDsKICAgICAgZ19jYW1fY3RybC5jYW1lcmFbKm51bV9jYW1lcmFzXS5jZmcgPSAmbW1fY2FtZXJhX2NmZzsKICAgICAgZ19jYW1fY3RybC5jYW1lcmFbKm51bV9jYW1lcmFzXS5vcHMgPSAmbW1fY2FtZXJhX29wczsKICAgICAgZ19jYW1fY3RybC5jYW1lcmFbKm51bV9jYW1lcmFzXS5ldnQgPSAmbW1fY2FtZXJhX25vdGlmeTsKICAgICAgZ19jYW1fY3RybC5jYW1lcmFbKm51bV9jYW1lcmFzXS5qcGVnX29wcyA9IE5VTEw7CgogICAgICBDREJHKCIlczogZGV2X2luZm9baWQ9JWQsbmFtZT0nJXMnLHBvcz0lZCxtb2Rlcz0weCV4LHNlbnNvcj0lZF1cbiIsCiAgICAgICAgX19mdW5jX18sICpudW1fY2FtZXJhcywKICAgICAgICBnX2NhbV9jdHJsLmNhbWVyYVsqbnVtX2NhbWVyYXNdLnZpZGVvX2Rldl9uYW1lLAogICAgICAgIGdfY2FtX2N0cmwuY2FtZXJhWypudW1fY2FtZXJhc10uY2FtZXJhX2luZm8ucG9zaXRpb24sCiAgICAgICAgZ19jYW1fY3RybC5jYW1lcmFbKm51bV9jYW1lcmFzXS5jYW1lcmFfaW5mby5tb2Rlc19zdXBwb3J0ZWQsCiAgICAgICAgZ19jYW1fY3RybC5jYW1lcmFbKm51bV9jYW1lcmFzXS5zZW5zb3JfdHlwZSk7CgogICAgICAqbnVtX2NhbWVyYXMrPTE7CiAgICAgIGlmIChkZXZfZmQgPiAwKSB7CiAgICAgICAgICBjbG9zZShkZXZfZmQpOwogICAgICB9CiAgICB9CiAgICAqbnVtX2NhbWVyYXMgPSAqbnVtX2NhbWVyYXM7CiAgICBnX2NhbV9jdHJsLm51bV9jYW0gPSAqbnVtX2NhbWVyYXM7CmVuZDoKICAgIC8qIHVubG9jayB0aGUgbXV0ZXggKi8KICAgIHB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZnX211dGV4KTsKICAgIENEQkcoIiVzOiBudW1fY2FtZXJhcz0lZFxuIiwgX19mdW5jX18sIGdfY2FtX2N0cmwubnVtX2NhbSk7CiAgICBpZihyYyA9PSAwKQogICAgICAgIHJldHVybiAmZ19jYW1fY3RybC5jYW1lcmFbMF07CiAgICBlbHNlCiAgICAgICAgcmV0dXJuIE5VTEw7Cn0KCgpzdGF0aWMgbW1fY2FtZXJhX3QgKiBnZXRfY2FtZXJhX2J5X2lkKCBpbnQgY2FtX2lkKQp7CiAgbW1fY2FtZXJhX3QgKiBtbV9jYW07CiAgaWYoIGNhbV9pZCA8IDAgfHwgY2FtX2lkID49IGdfY2FtX2N0cmwubnVtX2NhbSkgewogICAgIG1tX2NhbSA9IE5VTEw7CiAgfSBlbHNlIHsKICAgIG1tX2NhbSA9ICYgZ19jYW1fY3RybC5jYW1lcmFbY2FtX2lkXTsKICB9CiAgcmV0dXJuIG1tX2NhbTsKfQoKLypjb25maWd1cmUgbWV0aG9kcyovCnVpbnQ4X3QgY2FtX2NvbmZpZ19pc19wYXJtX3N1cHBvcnRlZCgKICBpbnQgY2FtX2lkLAogIG1tX2NhbWVyYV9wYXJtX3R5cGVfdCBwYXJtX3R5cGUpCnsKICB1aW50OF90IHJjID0gMDsKICBtbV9jYW1lcmFfdCAqIG1tX2NhbSA9IGdldF9jYW1lcmFfYnlfaWQoY2FtX2lkKTsKICBpZiAobW1fY2FtICYmIG1tX2NhbS0+Y2ZnKSB7CiAgICByYyA9IG1tX2NhbS0+Y2ZnLT5pc19wYXJtX3N1cHBvcnRlZChtbV9jYW0sIHBhcm1fdHlwZSk7CiAgfQogIHJldHVybiByYzsKfQoKdWludDhfdCBjYW1fY29uZmlnX2lzX2NoX3N1cHBvcnRlZCgKICBpbnQgY2FtX2lkLAogIG1tX2NhbWVyYV9jaGFubmVsX3R5cGVfdCBjaF90eXBlKQp7CiAgdWludDhfdCByYyA9IDA7CiAgbW1fY2FtZXJhX3QgKiBtbV9jYW0gPSBnZXRfY2FtZXJhX2J5X2lkKGNhbV9pZCk7CiAgaWYgKG1tX2NhbSkgewogICAgcmMgPSBtbV9jYW0tPmNmZy0+aXNfY2hfc3VwcG9ydGVkKG1tX2NhbSwgY2hfdHlwZSk7CiAgfQogIHJldHVybiByYzsKCn0KCi8qIHNldCBhIHBhcm2ScyBjdXJyZW50IHZhbHVlICovCmludDMyX3QgY2FtX2NvbmZpZ19zZXRfcGFybSgKICBpbnQgY2FtX2lkLAogIG1tX2NhbWVyYV9wYXJtX3R5cGVfdCBwYXJtX3R5cGUsCiAgdm9pZCogcF92YWx1ZSkKewogIGludDMyX3QgcmMgPSAtMTsKICBtbV9jYW1lcmFfdCAqIG1tX2NhbSA9IGdldF9jYW1lcmFfYnlfaWQoY2FtX2lkKTsKICBpZiAobW1fY2FtKSB7CiAgICByYyA9IG1tX2NhbS0+Y2ZnLT5zZXRfcGFybShtbV9jYW0sIHBhcm1fdHlwZSwgcF92YWx1ZSk7CiAgfQogIHJldHVybiByYzsKfQoKLyogZ2V0IGEgcGFybZJzIGN1cnJlbnQgdmFsdWUgKi8KaW50MzJfdCBjYW1fY29uZmlnX2dldF9wYXJtKAogIGludCBjYW1faWQsCiAgbW1fY2FtZXJhX3Bhcm1fdHlwZV90IHBhcm1fdHlwZSwKICB2b2lkKiBwX3ZhbHVlKQp7CiAgaW50MzJfdCByYyA9IC0xOwogIG1tX2NhbWVyYV90ICogbW1fY2FtID0gZ2V0X2NhbWVyYV9ieV9pZChjYW1faWQpOwogIGlmIChtbV9jYW0pIHsKICAgIHJjID0gbW1fY2FtLT5jZmctPmdldF9wYXJtKG1tX2NhbSwgcGFybV90eXBlLCBwX3ZhbHVlKTsKICB9CiAgcmV0dXJuIHJjOwp9CgppbnQzMl90IGNhbV9jb25maWdfcmVxdWVzdF9idWYoaW50IGNhbV9pZCwgbW1fY2FtZXJhX3JlZ19idWZfdCAqYnVmKQp7CgogIGludDMyX3QgcmMgPSAtMTsKICBtbV9jYW1lcmFfdCAqIG1tX2NhbSA9IGdldF9jYW1lcmFfYnlfaWQoY2FtX2lkKTsKICBpZiAobW1fY2FtKSB7CiAgICByYyA9IG1tX2NhbS0+Y2ZnLT5yZXF1ZXN0X2J1ZihtbV9jYW0sIGJ1Zik7CiAgfQogIHJldHVybiByYzsKfQoKaW50MzJfdCBjYW1fY29uZmlnX3ByZXBhcmVfYnVmKGludCBjYW1faWQsIG1tX2NhbWVyYV9yZWdfYnVmX3QgKmJ1ZikKewoKICBpbnQzMl90IHJjID0gLTE7CiAgbW1fY2FtZXJhX3QgKiBtbV9jYW0gPSBnZXRfY2FtZXJhX2J5X2lkKGNhbV9pZCk7CiAgaWYgKG1tX2NhbSkgewogICAgcmMgPSBtbV9jYW0tPmNmZy0+cHJlcGFyZV9idWYobW1fY2FtLCBidWYpOwogIH0KICByZXR1cm4gcmM7Cn0KaW50MzJfdCBjYW1fY29uZmlnX3VucHJlcGFyZV9idWYoaW50IGNhbV9pZCwgbW1fY2FtZXJhX2NoYW5uZWxfdHlwZV90IGNoX3R5cGUpCnsKICBpbnQzMl90IHJjID0gLTE7CiAgbW1fY2FtZXJhX3QgKiBtbV9jYW0gPSBnZXRfY2FtZXJhX2J5X2lkKGNhbV9pZCk7CiAgaWYgKG1tX2NhbSkgewogICAgcmMgPSBtbV9jYW0tPmNmZy0+dW5wcmVwYXJlX2J1ZihtbV9jYW0sIGNoX3R5cGUpOwogIH0KICByZXR1cm4gcmM7Cn0KCi8qb3BlcmF0aW9uIG1ldGhvZHMqLwp1aW50OF90IGNhbV9vcHNfaXNfb3Bfc3VwcG9ydGVkKGludCBjYW1faWQsIG1tX2NhbWVyYV9vcHNfdHlwZV90IG9wY29kZSkKewogIHVpbnQ4X3QgcmMgPSAwOwogIG1tX2NhbWVyYV90ICogbW1fY2FtID0gZ2V0X2NhbWVyYV9ieV9pZChjYW1faWQpOwogIGlmIChtbV9jYW0pIHsKICAgIHJjID0gbW1fY2FtLT5vcHMtPmlzX29wX3N1cHBvcnRlZChtbV9jYW0sIG9wY29kZSk7CiAgfQogIHJldHVybiByYzsKfQovKiB2YWwgaXMgcmVzZXJ2ZWQgZm9yIHNvbWUgYWN0aW9uIHN1Y2ggYXMgTU1fQ0FNRVJBX09QU19GT0NVUyAqLwppbnQzMl90IGNhbV9vcHNfYWN0aW9uKGludCBjYW1faWQsIHVpbnQ4X3Qgc3RhcnQsCiAgbW1fY2FtZXJhX29wc190eXBlX3Qgb3Bjb2RlLCB2b2lkICp2YWwpCnsKICBpbnQzMl90IHJjID0gLTE7CiAgbW1fY2FtZXJhX3QgKiBtbV9jYW0gPSBnZXRfY2FtZXJhX2J5X2lkKGNhbV9pZCk7CiAgaWYgKG1tX2NhbSkgewogICAgcmMgPSBtbV9jYW0tPm9wcy0+YWN0aW9uKG1tX2NhbSwgc3RhcnQsIG9wY29kZSwgdmFsKTsKICB9CiAgcmV0dXJuIHJjOwp9CgppbnQzMl90IGNhbV9vcHNfb3BlbihpbnQgY2FtX2lkLCBtbV9jYW1lcmFfb3BfbW9kZV90eXBlX3Qgb3BfbW9kZSkKewogIGludDMyX3QgcmMgPSAtMTsKICBtbV9jYW1lcmFfdCAqIG1tX2NhbSA9IGdldF9jYW1lcmFfYnlfaWQoY2FtX2lkKTsKICBpZiAobW1fY2FtKSB7CiAgICByYyA9IG1tX2NhbS0+b3BzLT5vcGVuKG1tX2NhbSwgb3BfbW9kZSk7CiAgfQogIHJldHVybiByYzsKfQoKdm9pZCBjYW1fb3BzX2Nsb3NlKGludCBjYW1faWQpCnsKICBtbV9jYW1lcmFfdCAqIG1tX2NhbSA9IGdldF9jYW1lcmFfYnlfaWQoY2FtX2lkKTsKICBpZiAobW1fY2FtKSB7CiAgICBtbV9jYW0tPm9wcy0+Y2xvc2UobW1fY2FtKTsKICB9Cn0KCnZvaWQgY2FtX29wc19zdG9wKGludCBjYW1faWQpCnsKICBtbV9jYW1lcmFfdCAqIG1tX2NhbSA9IGdldF9jYW1lcmFfYnlfaWQoY2FtX2lkKTsKICBpZiAobW1fY2FtKSB7CiAgICBtbV9jYW0tPm9wcy0+c3RvcChtbV9jYW0pOwogIH0KfQoKaW50MzJfdCBjYW1fb3BzX2NoX2FjcXVpcmUoaW50IGNhbV9pZCwgbW1fY2FtZXJhX2NoYW5uZWxfdHlwZV90IGNoX3R5cGUpCnsKICBpbnQzMl90IHJjID0gLTE7CiAgbW1fY2FtZXJhX3QgKiBtbV9jYW0gPSBnZXRfY2FtZXJhX2J5X2lkKGNhbV9pZCk7CiAgaWYgKG1tX2NhbSkgewogICAgcmMgPSBtbV9jYW0tPm9wcy0+Y2hfYWNxdWlyZShtbV9jYW0sIGNoX3R5cGUpOwogIH0KICByZXR1cm4gcmM7Cn0KCnZvaWQgY2FtX29wc19jaF9yZWxlYXNlKGludCBjYW1faWQsIG1tX2NhbWVyYV9jaGFubmVsX3R5cGVfdCBjaF90eXBlKQp7CiAgbW1fY2FtZXJhX3QgKiBtbV9jYW0gPSBnZXRfY2FtZXJhX2J5X2lkKGNhbV9pZCk7CiAgaWYgKG1tX2NhbSkgewogICAgbW1fY2FtLT5vcHMtPmNoX3JlbGVhc2UobW1fY2FtLCBjaF90eXBlKTsKICB9Cn0KCmludDMyX3QgY2FtX29wc19jaF9zZXRfYXR0cihpbnQgY2FtX2lkLCBtbV9jYW1lcmFfY2hhbm5lbF90eXBlX3QgY2hfdHlwZSwKICBtbV9jYW1lcmFfY2hhbm5lbF9hdHRyX3QgKmF0dHIpCnsKICBpbnQzMl90IHJjID0gLTE7CiAgbW1fY2FtZXJhX3QgKiBtbV9jYW0gPSBnZXRfY2FtZXJhX2J5X2lkKGNhbV9pZCk7CiAgaWYgKG1tX2NhbSkgewogICAgcmMgPSBtbV9jYW0tPm9wcy0+Y2hfc2V0X2F0dHIobW1fY2FtLCBjaF90eXBlLCBhdHRyKTsKICB9CiAgcmV0dXJuIHJjOwp9CgppbnQzMl90IGNhbV9vcHNfc2VuZG1zZyhpbnQgY2FtX2lkLCB2b2lkICptc2csIHVpbnQzMl90IGJ1Zl9zaXplLCBpbnQgc2VuZGZkKQp7CiAgICBpbnQzMl90IHJjID0gLTE7CiAgICBtbV9jYW1lcmFfdCAqIG1tX2NhbSA9IGdldF9jYW1lcmFfYnlfaWQoY2FtX2lkKTsKICAgIGlmIChtbV9jYW0pIHsKICAgICAgcmMgPSBtbV9jYW0tPm9wcy0+c2VuZG1zZyhtbV9jYW0sIG1zZywgYnVmX3NpemUsIHNlbmRmZCk7CiAgICB9CiAgICByZXR1cm4gcmM7Cn0KCi8qY2FsbC1iYWNrIG5vdGlmeSBtZXRob2RzKi8KdWludDhfdCBjYW1fZXZ0X2lzX2V2ZW50X3N1cHBvcnRlZChpbnQgY2FtX2lkLCBtbV9jYW1lcmFfZXZlbnRfdHlwZV90IGV2dF90eXBlKQp7CiAgdWludDhfdCByYyA9IDA7CiAgbW1fY2FtZXJhX3QgKiBtbV9jYW0gPSBnZXRfY2FtZXJhX2J5X2lkKGNhbV9pZCk7CiAgaWYgKG1tX2NhbSkgewogICAgcmMgPSBtbV9jYW0tPmV2dC0+aXNfZXZlbnRfc3VwcG9ydGVkKG1tX2NhbSwgZXZ0X3R5cGUpOwogIH0KICByZXR1cm4gcmM7Cn0KCmludDMyX3QgY2FtX2V2dF9yZWdpc3Rlcl9ldmVudF9ub3RpZnkoaW50IGNhbV9pZCwKICBtbV9jYW1lcmFfZXZlbnRfbm90aWZ5X3QgZXZ0X2NiLAogIHZvaWQgKiB1c2VyX2RhdGEsCiAgbW1fY2FtZXJhX2V2ZW50X3R5cGVfdCBldnRfdHlwZSkKewogIGludDMyX3QgcmMgPSAtMTsKICBtbV9jYW1lcmFfdCAqIG1tX2NhbSA9IGdldF9jYW1lcmFfYnlfaWQoY2FtX2lkKTsKICBpZiAobW1fY2FtKSB7CiAgICByYyA9IG1tX2NhbS0+ZXZ0LT5yZWdpc3Rlcl9ldmVudF9ub3RpZnkoCiAgICAgIG1tX2NhbSwgZXZ0X2NiLCB1c2VyX2RhdGEsIGV2dF90eXBlKTsKICB9CiAgcmV0dXJuIHJjOwp9CgppbnQzMl90IGNhbV9ldnRfcmVnaXN0ZXJfYnVmX25vdGlmeShpbnQgY2FtX2lkLAogIG1tX2NhbWVyYV9jaGFubmVsX3R5cGVfdCBjaF90eXBlLAogIG1tX2NhbWVyYV9idWZfbm90aWZ5X3QgYnVmX2NiLAogIG1tX2NhbWVyYV9yZWdpc3Rlcl9idWZfY2JfdHlwZV90IGNiX3R5cGUsCiAgdWludDMyX3QgY2JfY291bnQsCiAgdm9pZCAqIHVzZXJfZGF0YSkKewogIGludDMyX3QgcmMgPSAtMTsKICBtbV9jYW1lcmFfdCAqIG1tX2NhbSA9IGdldF9jYW1lcmFfYnlfaWQoY2FtX2lkKTsKICBpZiAobW1fY2FtKSB7CiAgICByYyA9IG1tX2NhbS0+ZXZ0LT5yZWdpc3Rlcl9idWZfbm90aWZ5KAogICAgICBtbV9jYW0sIGNoX3R5cGUsIGJ1Zl9jYiwgY2JfdHlwZSwKICAgICAgY2JfY291bnQsIHVzZXJfZGF0YSk7CiAgfQogIHJldHVybiByYzsKfQoKaW50MzJfdCBjYW1fZXZ0X2J1Zl9kb25lKGludCBjYW1faWQsIG1tX2NhbWVyYV9jaF9kYXRhX2J1Zl90ICpidWZzKQp7CiAgaW50MzJfdCByYyA9IC0xOwogIG1tX2NhbWVyYV90ICogbW1fY2FtID0gZ2V0X2NhbWVyYV9ieV9pZChjYW1faWQpOwogIGlmIChtbV9jYW0pIHsKICAgIHJjID0gbW1fY2FtLT5ldnQtPmJ1Zl9kb25lKG1tX2NhbSwgYnVmcyk7CiAgfQogIHJldHVybiByYzsKfQoKLypjYW1lcmEgSlBFRyBtZXRob2RzKi8KdWludDhfdCBjYW1fanBlZ19pc19qcGVnX3N1cHBvcnRlZChpbnQgY2FtX2lkKQp7CiAgdWludDhfdCByYyA9IDA7CiAgbW1fY2FtZXJhX3QgKiBtbV9jYW0gPSBnZXRfY2FtZXJhX2J5X2lkKGNhbV9pZCk7CiAgaWYgKG1tX2NhbSkgewogICAgcmMgPSBtbV9jYW0tPmpwZWdfb3BzLT5pc19qcGVnX3N1cHBvcnRlZChtbV9jYW0pOwogIH0KICByZXR1cm4gcmM7Cn0KCmludDMyX3QgY2FtX2pwZWdfc2V0X3Bhcm0oaW50IGNhbV9pZCwgbW1fY2FtZXJhX2pwZWdfcGFybV90eXBlX3QgcGFybV90eXBlLAogIHZvaWQqIHBfdmFsdWUpCnsKICBpbnQzMl90IHJjID0gLTE7CiAgbW1fY2FtZXJhX3QgKiBtbV9jYW0gPSBnZXRfY2FtZXJhX2J5X2lkKGNhbV9pZCk7CiAgaWYgKG1tX2NhbSkgewogICAgcmMgPSBtbV9jYW0tPmpwZWdfb3BzLT5zZXRfcGFybShtbV9jYW0sIHBhcm1fdHlwZSwgcF92YWx1ZSk7CiAgfQogIHJldHVybiByYzsKfQoKaW50MzJfdCBjYW1fanBlZ19nZXRfcGFybShpbnQgY2FtX2lkLCBtbV9jYW1lcmFfanBlZ19wYXJtX3R5cGVfdCBwYXJtX3R5cGUsCiAgdm9pZCogcF92YWx1ZSkKewogIGludDMyX3QgcmMgPSAtMTsKICBtbV9jYW1lcmFfdCAqIG1tX2NhbSA9IGdldF9jYW1lcmFfYnlfaWQoY2FtX2lkKTsKICBpZiAobW1fY2FtKSB7CiAgICByYyA9IG1tX2NhbS0+anBlZ19vcHMtPmdldF9wYXJtKG1tX2NhbSwgcGFybV90eXBlLCBwX3ZhbHVlKTsKICB9CiAgcmV0dXJuIHJjOwp9CmludDMyX3QgY2FtX2pwZWdfcmVnaXN0ZXJfZXZlbnRfY2IoaW50IGNhbV9pZCwgbW1fY2FtZXJhX2pwZWdfY2JfdCAqIGV2dF9jYiwKICB2b2lkICogdXNlcl9kYXRhKQp7CiAgaW50MzJfdCByYyA9IC0xOwogIG1tX2NhbWVyYV90ICogbW1fY2FtID0gZ2V0X2NhbWVyYV9ieV9pZChjYW1faWQpOwogIGlmIChtbV9jYW0pIHsKICAgIHJjID0gbW1fY2FtLT5qcGVnX29wcy0+cmVnaXN0ZXJfZXZlbnRfY2IobW1fY2FtLCBldnRfY2IsIHVzZXJfZGF0YSk7CiAgfQogIHJldHVybiByYzsKfQppbnQzMl90IGNhbV9qcGVnX2VuY29kZShpbnQgY2FtX2lkLCB1aW50OF90IHN0YXJ0LAogIG1tX2NhbWVyYV9qcGVnX2VuY29kZV90ICpkYXRhKQp7CiAgaW50MzJfdCByYyA9IC0xOwogIG1tX2NhbWVyYV90ICogbW1fY2FtID0gZ2V0X2NhbWVyYV9ieV9pZChjYW1faWQpOwogIGlmIChtbV9jYW0pIHsKICAgIHJjID0gbW1fY2FtLT5qcGVnX29wcy0+ZW5jb2RlKG1tX2NhbSwgc3RhcnQsIGRhdGEpOwogIH0KICByZXR1cm4gcmM7Cn0KCg==