ZGlmZiAtLWdpdCBhL2NvbnRyb2xzL2J1dHRvbi5jIGIvY29udHJvbHMvYnV0dG9uLmMKaW5kZXggODhmZDk3NC4uNTYwNzQ2YiAxMDA2NDQKLS0tIGEvY29udHJvbHMvYnV0dG9uLmMKKysrIGIvY29udHJvbHMvYnV0dG9uLmMKQEAgLTYsNiArNiw3IEBACiAgKi8KIAogI2luY2x1ZGUgPHN0cmluZy5oPgorI2luY2x1ZGUgPHN0ZGxpYi5oPgkvKiBmb3IgYWJzKCkgKi8KICNpbmNsdWRlICJ3aW4uaCIKICNpbmNsdWRlICJidXR0b24uaCIKICNpbmNsdWRlICJ3aW5iYXNlLmgiCkBAIC0xNCw5ICsxNSw2IEBACiAjaW5jbHVkZSAid2luZS93aW51c2VyMTYuaCIKICNpbmNsdWRlICJ0d2Vhay5oIgogCi1zdGF0aWMgdm9pZCBQYWludEdyYXlPbkdyYXkoIEhEQyBoREMsSEZPTlQgaEZvbnQsUkVDVCAqcmMsCi0JCQkgICAgIExQQ1dTVFIgdGV4dCwgVUlOVCBmb3JtYXQgKTsKLQogc3RhdGljIHZvaWQgUEJfUGFpbnQoIFdORCAqd25kUHRyLCBIREMgaERDLCBXT1JEIGFjdGlvbiApOwogc3RhdGljIHZvaWQgQ0JfUGFpbnQoIFdORCAqd25kUHRyLCBIREMgaERDLCBXT1JEIGFjdGlvbiApOwogc3RhdGljIHZvaWQgR0JfUGFpbnQoIFdORCAqd25kUHRyLCBIREMgaERDLCBXT1JEIGFjdGlvbiApOwpAQCAtMjgwLDIxICsyNzgsMzcgQEAKIAlicmVhazsKIAogICAgIGNhc2UgQk1fU0VUSU1BR0U6Ci0Jb2xkSGJpdG1hcCA9IGluZm9QdHItPmhJbWFnZTsKLQlpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIEJTX0JJVE1BUCkgfHwgKHduZFB0ci0+ZHdTdHlsZSAmIEJTX0lDT04pKQorCS8qIENoZWNrIHRoYXQgaW1hZ2UgZm9ybWF0IGNvbmZpcm0gYnV0dG9uIHN0eWxlICovCisJaWYgKCh3bmRQdHItPmR3U3R5bGUgJiAoQlNfQklUTUFQfEJTX0lDT04pKSA9PSBCU19CSVRNQVApCiAJewotCSAgICBpbmZvUHRyLT5oSW1hZ2UgPSAoSEFORExFKSBsUGFyYW07Ci0JICAgIEludmFsaWRhdGVSZWN0KCBoV25kLCBOVUxMLCBGQUxTRSApOworCSAgICBpZiAod1BhcmFtICE9IChXUEFSQU0pIElNQUdFX0JJVE1BUCkKKwkJcmV0dXJuIChISUNPTikwOwogCX0KKwllbHNlIGlmICgod25kUHRyLT5kd1N0eWxlICYgKEJTX0JJVE1BUHxCU19JQ09OKSkgPT0gQlNfSUNPTikKKwl7CisJICAgIGlmICh3UGFyYW0gIT0gKFdQQVJBTSkgSU1BR0VfSUNPTikKKwkJcmV0dXJuIChISUNPTikwOworCX0gZWxzZQorCSAgICByZXR1cm4gKEhJQ09OKTA7CisKKwlvbGRIYml0bWFwID0gaW5mb1B0ci0+aEltYWdlOworCWluZm9QdHItPmhJbWFnZSA9IChIQU5ETEUpIGxQYXJhbTsKKwlJbnZhbGlkYXRlUmVjdCggaFduZCwgTlVMTCwgRkFMU0UgKTsKIAlyZXR1cm4gb2xkSGJpdG1hcDsKIAogICAgIGNhc2UgQk1fR0VUSU1BR0U6Ci0gICAgICAgIGlmICh3UGFyYW0gPT0gSU1BR0VfQklUTUFQKQotCSAgICByZXR1cm4gKEhCSVRNQVApaW5mb1B0ci0+aEltYWdlOwotCWVsc2UgaWYgKHdQYXJhbSA9PSBJTUFHRV9JQ09OKQotCSAgICByZXR1cm4gKEhJQ09OKWluZm9QdHItPmhJbWFnZTsKLQllbHNlCisJaWYgKCh3bmRQdHItPmR3U3R5bGUgJiAoQlNfQklUTUFQfEJTX0lDT04pKSA9PSBCU19CSVRNQVApCisJeworCSAgICBpZiAod1BhcmFtICE9IChXUEFSQU0pIElNQUdFX0JJVE1BUCkKKwkJcmV0dXJuIChISUNPTikwOworCX0KKwllbHNlIGlmICgod25kUHRyLT5kd1N0eWxlICYgKEJTX0JJVE1BUHxCU19JQ09OKSkgPT0gQlNfSUNPTikKKwl7CisJICAgIGlmICh3UGFyYW0gIT0gKFdQQVJBTSkgSU1BR0VfSUNPTikKKwkJcmV0dXJuIChISUNPTikwOworCX0gZWxzZQogCSAgICByZXR1cm4gKEhJQ09OKTA7CisJcmV0dXJuIGluZm9QdHItPmhJbWFnZTsKIAogICAgIGNhc2UgQk1fR0VUQ0hFQ0sxNjoKICAgICBjYXNlIEJNX0dFVENIRUNLOgpAQCAtMzgxLDYgKzM5NSwyMTMgQEAKIH0KIAogLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAqIENvbnZlcnQgYnV0dG9uIHN0eWxlcyB0byBmbGFncyB1c2VkIGJ5IERyYXdUZXh0LgorICogVE9ETzogaGFuZGxlIFdTX0VYX1JJR0hUIGV4dGVuZGVkIHN0eWxlLgorICovCitzdGF0aWMgVUlOVCBCVVRUT05fQlN0b0RUKERXT1JEIHN0eWxlKQoreworICAgVUlOVCBkdFN0eWxlID0gRFRfTk9DTElQOyAgLyogV2UgdXNlIFNlbGVjdENsaXBSZ24gdG8gbGltaXQgb3V0cHV0ICovCisKKyAgIC8qICJDb252ZXJ0IiBwdXNobGlrZSBidXR0b25zIHRvIHB1c2hidXR0b25zICovCisgICBpZiAoc3R5bGUgJiBCU19QVVNITElLRSkKKyAgICAgIHN0eWxlICY9IH4weDBGOworCisgICBpZiAoIShzdHlsZSAmIEJTX01VTFRJTElORSkpCisgICAgICBkdFN0eWxlIHw9IERUX1NJTkdMRUxJTkU7CisgICBlbHNlCisgICAgICBkdFN0eWxlIHw9IERUX1dPUkRCUkVBSzsKKworICAgc3dpdGNoIChzdHlsZSAmIEJTX0NFTlRFUikKKyAgIHsKKyAgICAgIGNhc2UgQlNfTEVGVDogICAvKiBEVF9MRUZUIGlzIDAgKi8gICAgYnJlYWs7CisgICAgICBjYXNlIEJTX1JJR0hUOiAgZHRTdHlsZSB8PSBEVF9SSUdIVDsgIGJyZWFrOworICAgICAgY2FzZSBCU19DRU5URVI6IGR0U3R5bGUgfD0gRFRfQ0VOVEVSOyBicmVhazsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgICAvKiBQdXNoYnV0dG9uJ3MgdGV4dCBpcyBjZW50ZXJlZCBieSBkZWZhdWx0ICovCisgICAgICAgICBpZiAoKHN0eWxlICYgMHgwRikgPD0gQlNfREVGUFVTSEJVVFRPTikKKyAgICAgICAgICAgIGR0U3R5bGUgfD0gRFRfQ0VOVEVSOworICAgICAgICAgLyogYWxsIG90aGVyIGZsYXZvdXJzIGhhdmUgbGVmdCBhbGlnbmVkIHRleHQgKi8KKyAgIH0KKworICAgLyogRHJhd1RleHQgaWdub3JlcyB2ZXJ0aWNhbCBhbGlnbm1lbnQgZm9yIG11bHRpbGluZSB0ZXh0LAorICAgICogYnV0IHdlIHVzZSB0aGVzZSBmbGFncyB0byBhbGlnbiBsYWJlbCBtYW51YWx5LgorICAgICovCisgICBpZiAoKHN0eWxlICYgMHgwRikgIT0gQlNfR1JPVVBCT1gpCisgICB7CisgICAgICBzd2l0Y2ggKHN0eWxlICYgQlNfVkNFTlRFUikKKyAgICAgIHsKKyAgICAgICAgIGNhc2UgQlNfVE9QOiAgICAgLyogRFRfVE9QIGlzIDAgKi8gICAgICBicmVhazsKKyAgICAgICAgIGNhc2UgQlNfQk9UVE9NOiAgZHRTdHlsZSB8PSBEVF9CT1RUT007ICBicmVhazsKKyAgICAgICAgIGNhc2UgQlNfVkNFTlRFUjogLyogZmFsbCB0aHJvdWdoICovCisgICAgICAgICBkZWZhdWx0OiAgICAgICAgIGR0U3R5bGUgfD0gRFRfVkNFTlRFUjsgYnJlYWs7CisgICAgICB9CisgICB9CisgICBlbHNlCisgICAgICAvKiBHcm91cEJveCdzIHRleHQgaXMgYWx3YXlzIHNpbmdsZSBsaW5lIGFuZCBpcyB0b3AgYWxpZ25lZC4gKi8KKyAgICAgIGR0U3R5bGUgfD0gRFRfU0lOR0xFTElORTsKKworICAgcmV0dXJuIGR0U3R5bGU7Cit9CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKiAgICAgICBCVVRUT05fQ2FsY0xhYmVsUmVjdAorICoKKyAqICAgQ2FsY3VsYXRlcyBsYWJlbCdzIHJlY3RhbmdsZSBkZXBlbmRpbmcgb24gYnV0dG9uIHN0eWxlLgorICoKKyAqIFJldHVybnMgZmxhZ3MgdG8gYmUgcGFzc2VkIHRvIERyYXdUZXh0LgorICogQ2FsY3VsYXRlZCByZWN0YW5nbGUgZG9lc24ndCB0YWtlIGludG8gYWNjb3VudCBidXR0b24gc3RhdGUKKyAqIChwdXNoZWQsIGV0Yy4pLiBJZiB0aGVyZSBpcyBub3RoaW5nIHRvIGRyYXcgKG5vIHRleHQvaW1hZ2UpIG91dHB1dAorICogcmVjdGFuZ2xlIGlzIGVtcHR5LCBhbmQgcmV0dXJuIHZhbHVlIGlzIChVSU5UKS0xLgorICovCitzdGF0aWMgVUlOVCBCVVRUT05fQ2FsY0xhYmVsUmVjdChXTkQgKnduZFB0ciwgSERDIGhkYywgUkVDVCAqcmMpCit7CisgICBCVVRUT05JTkZPICppbmZvUHRyID0gKEJVVFRPTklORk8gKil3bmRQdHItPndFeHRyYTsKKyAgIElDT05JTkZPICAgIGljb25JbmZvOworICAgQklUTUFQICAgICAgYm07CisgICBVSU5UICAgICAgICBkdFN0eWxlID0gQlVUVE9OX0JTdG9EVCh3bmRQdHItPmR3U3R5bGUpOworICAgUkVDVCAgICAgICAgciA9ICpyYzsKKyAgIElOVCAgICAgICAgIG47CisKKyAgIC8qIENhbGN1bGF0ZSBsYWJlbCByZWN0YW5nbGUgYWNjb3JkaW5nIHRvIGxhYmVsIHR5cGUgKi8KKyAgIHN3aXRjaCAod25kUHRyLT5kd1N0eWxlICYgKEJTX0lDT058QlNfQklUTUFQKSkKKyAgIHsKKyAgICAgIGNhc2UgQlNfVEVYVDoKKyAgICAgICAgIGlmICh3bmRQdHItPnRleHQgJiYgd25kUHRyLT50ZXh0WzBdKQorICAgICAgICAgICAgRHJhd1RleHRXKGhkYywgd25kUHRyLT50ZXh0LCAtMSwgJnIsIGR0U3R5bGUgfCBEVF9DQUxDUkVDVCk7CisgICAgICAgICBlbHNlCisgICAgICAgICAgICBnb3RvIGVtcHR5X3JlY3Q7CisgICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBCU19JQ09OOgorICAgICAgICAgaWYgKCFHZXRJY29uSW5mbygoSElDT04paW5mb1B0ci0+aEltYWdlLCAmaWNvbkluZm8pKQorICAgICAgICAgICAgZ290byBlbXB0eV9yZWN0OworCisgICAgICAgICBHZXRPYmplY3RBIChpY29uSW5mby5oYm1Db2xvciwgc2l6ZW9mKEJJVE1BUCksICZibSk7CisKKyAgICAgICAgIHIucmlnaHQgID0gci5sZWZ0ICsgYm0uYm1XaWR0aDsKKyAgICAgICAgIHIuYm90dG9tID0gci50b3AgICsgYm0uYm1IZWlnaHQ7CisKKyAgICAgICAgIERlbGV0ZU9iamVjdChpY29uSW5mby5oYm1Db2xvcik7CisgICAgICAgICBEZWxldGVPYmplY3QoaWNvbkluZm8uaGJtTWFzayk7CisgICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBCU19CSVRNQVA6CisgICAgICAgICBpZiAoIUdldE9iamVjdEEgKGluZm9QdHItPmhJbWFnZSwgc2l6ZW9mKEJJVE1BUCksICZibSkpCisgICAgICAgICAgICBnb3RvIGVtcHR5X3JlY3Q7CisKKyAgICAgICAgIHIucmlnaHQgID0gci5sZWZ0ICsgYm0uYm1XaWR0aDsKKyAgICAgICAgIHIuYm90dG9tID0gci50b3AgICsgYm0uYm1IZWlnaHQ7CisgICAgICAgICBicmVhazsKKworICAgICAgZGVmYXVsdDoKKyAgICAgIGVtcHR5X3JlY3Q6ICAgCisgICAgICAgICByLnJpZ2h0ID0gci5sZWZ0OworICAgICAgICAgci5ib3R0b20gPSByLnRvcDsKKyAgICAgICAgIHJldHVybiAoVUlOVCkoTE9ORyktMTsKKyAgIH0KKworICAgLyogUG9zaXRpb24gbGFiZWwgaW5zaWRlIGJvdW5kaW5nIHJlY3RhbmdsZSBhY2NvcmRpbmcgdG8KKyAgICAqIGFsaWdubWVudCBmbGFncy4gKGNhbGN1bGF0ZWQgcmVjdCBpcyBhbHdheXMgbGVmdC10b3AgYWxpZ25lZCkuCisgICAgKiBJZiBsYWJlbCBpcyBhbGlnbmVkIHRvIGFueSBzaWRlIC0gc2hpZnQgbGFiZWwgaW4gb3Bwb3NpdGUKKyAgICAqIGRpcmVjdGlvbiB0byBsZWF2ZSBleHRyYSBzcGFjZSBmb3IgZm9jdXMgcmVjdGFuZ2xlLgorICAgICovCisgICBzd2l0Y2ggKGR0U3R5bGUgJiAoRFRfQ0VOVEVSfERUX1JJR0hUKSkKKyAgIHsKKyAgICAgIGNhc2UgRFRfTEVGVDogICAgci5sZWZ0Kys7ICByLnJpZ2h0Kys7ICBicmVhazsKKyAgICAgIGNhc2UgRFRfQ0VOVEVSOiAgbiA9IHIucmlnaHQgLSByLmxlZnQ7CisgICAgICAgICAgICAgICAgICAgICAgIHIubGVmdCAgID0gcmMtPmxlZnQgKyAoKHJjLT5yaWdodCAtIHJjLT5sZWZ0KSAtIG4pIC8gMjsKKyAgICAgICAgICAgICAgICAgICAgICAgci5yaWdodCAgPSByLmxlZnQgKyBuOyBicmVhazsKKyAgICAgIGNhc2UgRFRfUklHSFQ6ICAgbiA9IHIucmlnaHQgLSByLmxlZnQ7CisgICAgICAgICAgICAgICAgICAgICAgIHIucmlnaHQgID0gcmMtPnJpZ2h0IC0gMTsKKyAgICAgICAgICAgICAgICAgICAgICAgci5sZWZ0ICAgPSByLnJpZ2h0IC0gbjsKKyAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICB9CisKKyAgIHN3aXRjaCAoZHRTdHlsZSAmIChEVF9WQ0VOVEVSfERUX0JPVFRPTSkpCisgICB7CisgICAgICBjYXNlIERUX1RPUDogICAgIHIudG9wKys7ICByLmJvdHRvbSsrOyAgYnJlYWs7CisgICAgICBjYXNlIERUX1ZDRU5URVI6IG4gPSByLmJvdHRvbSAtIHIudG9wOworICAgICAgICAgICAgICAgICAgICAgICByLnRvcCAgICA9IHJjLT50b3AgKyAoKHJjLT5ib3R0b20gLSByYy0+dG9wKSAtIG4pIC8gMjsKKyAgICAgICAgICAgICAgICAgICAgICAgci5ib3R0b20gPSByLnRvcCArIG47ICBicmVhazsKKyAgICAgIGNhc2UgRFRfQk9UVE9NOiAgbiA9IHIuYm90dG9tIC0gci50b3A7CisgICAgICAgICAgICAgICAgICAgICAgIHIuYm90dG9tID0gcmMtPmJvdHRvbSAtIDE7CisgICAgICAgICAgICAgICAgICAgICAgIHIudG9wICAgID0gci5ib3R0b20gLSBuOworICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgIH0KKworICAgKnJjID0gcjsKKyAgIHJldHVybiBkdFN0eWxlOworfQorCisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKiAgICAgICBCVVRUT05fRHJhd1RleHRDYWxsYmFjaworICoKKyAqICAgQ2FsbGJhY2sgZnVuY3Rpb24gdXNlZCBiZSBEcmF3U3RhdGVBIGZ1bmN0aW9uLgorICovCitzdGF0aWMgQk9PTCBDQUxMQkFDSyBCVVRUT05fRHJhd1RleHRDYWxsYmFjayhIREMgaGRjLCBMUEFSQU0gbHAsIFdQQVJBTSB3cCwgaW50IGN4LCBpbnQgY3kpCit7CisgICBSRUNUIHJjID0gezAsIDAsIGN4LCBjeX07CisKKyAgIERyYXdUZXh0VyhoZGMsIChMUENXU1RSKWxwLCAtMSwgJnJjLCAoVUlOVCl3cCk7CisgICByZXR1cm4gVFJVRTsKK30KKworCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgorICogICAgICAgQlVUVE9OX0RyYXdMYWJlbAorICoKKyAqICAgQ29tbW9uIGZ1bmN0aW9uIGZvciBkcmF3aW5nIGJ1dHRvbiBsYWJlbC4KKyAqLworc3RhdGljIHZvaWQgQlVUVE9OX0RyYXdMYWJlbChXTkQgKnduZFB0ciwgSERDIGhkYywgVUlOVCBkdEZsYWdzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVDVCAqcmMpCit7CisgICBCVVRUT05JTkZPICppbmZvUHRyID0gKEJVVFRPTklORk8gKil3bmRQdHItPndFeHRyYTsKKyAgIERSQVdTVEFURVBST0MgbHBPdXRwdXRQcm9jID0gTlVMTDsKKyAgIExQQVJBTSBscDsKKyAgIFdQQVJBTSB3cCA9IDA7CisgICBIQlJVU0ggaGJyID0gMDsKKyAgIFVJTlQgZmxhZ3MgPSBJc1dpbmRvd0VuYWJsZWQod25kUHRyLT5od25kU2VsZikgPyBEU1NfTk9STUFMIDogRFNTX0RJU0FCTEVEOworCisgICAvKiBGaXhtZTogVG8gZHJhdyBkaXNhYmxlZCBsYWJlbCBpbiBXaW4zMSBsb29rLWFuZC1mZWVsLCB3ZSBwcm9iYWJseQorICAgICogbXVzdCB1c2UgRFNTX01PTk8gZmxhZyBhbmQgQ09MT1JfR1JBWVRFWFQgYnJ1c2ggKG9yIG1heWJlIERTU19VTklPTikuCisgICAgKiBJIGRvbid0IGhhdmUgV2luMzEgb24gaGFuZCB0byB2ZXJpZnkgdGhhdCwgc28gSSBsZWF2ZSBpdCBhcyBpcy4KKyAgICAqLworCisgICBpZiAoKHduZFB0ci0+ZHdTdHlsZSAmIEJTX1BVU0hMSUtFKSAmJiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fM1NUQVRFKSkKKyAgIHsKKyAgICAgIGhiciA9IEdldFN5c0NvbG9yQnJ1c2goQ09MT1JfR1JBWVRFWFQpOworICAgICAgZmxhZ3MgfD0gRFNTX01PTk87CisgICB9CisKKyAgIHN3aXRjaCAod25kUHRyLT5kd1N0eWxlICYgKEJTX0lDT058QlNfQklUTUFQKSkKKyAgIHsKKyAgICAgIGNhc2UgQlNfVEVYVDoKKyAgICAgICAgIC8qIERTVF9DT01QTEVYIC0tIGlzIDAgKi8KKyAgICAgICAgIGxwT3V0cHV0UHJvYyA9IEJVVFRPTl9EcmF3VGV4dENhbGxiYWNrOworICAgICAgICAgbHAgPSAoTFBBUkFNKXduZFB0ci0+dGV4dDsKKyAgICAgICAgIHdwID0gKFdQQVJBTSlkdEZsYWdzOworICAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgQlNfSUNPTjoKKyAgICAgICAgIGZsYWdzIHw9IERTVF9JQ09OOworICAgICAgICAgbHAgPSAoTFBBUkFNKWluZm9QdHItPmhJbWFnZTsKKyAgICAgICAgIGJyZWFrOworCisgICAgICBjYXNlIEJTX0JJVE1BUDoKKyAgICAgICAgIGZsYWdzIHw9IERTVF9CSVRNQVA7CisgICAgICAgICBscCA9IChMUEFSQU0paW5mb1B0ci0+aEltYWdlOworICAgICAgICAgYnJlYWs7CisKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgICByZXR1cm47CisgICB9CisKKyAgIERyYXdTdGF0ZVcoaGRjLCBoYnIsIGxwT3V0cHV0UHJvYywgbHAsIHdwLCByYy0+bGVmdCwgcmMtPnRvcCwKKyAgICAgICAgICAgICAgcmMtPnJpZ2h0IC0gcmMtPmxlZnQsIHJjLT5ib3R0b20gLSByYy0+dG9wLCBmbGFncyk7Cit9CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAgKiBUaGlzIG1ldGhvZCB3aWxsIGFjdHVhbGx5IGRvIHRoZSBkcmF3aW5nIG9mIHRoZSBwdXNoYnV0dG9uIAogICogZGVwZW5kaW5nIG9uIGl0J3Mgc3RhdGUgYW5kIHRoZSBwdXNoZWRTdGF0ZSBwYXJhbWV0ZXIuCiAgKi8KQEAgLTM5MCwzMCArNjExLDMzIEBACiAgIFdPUkQgYWN0aW9uLCAKICAgQk9PTCBwdXNoZWRTdGF0ZSApCiB7Ci0gICAgUkVDVCByYywgZm9jdXNfcmVjdDsKLSAgICBIUEVOIGhPbGRQZW47Ci0gICAgSEJSVVNIIGhPbGRCcnVzaDsKICAgICBCVVRUT05JTkZPICppbmZvUHRyID0gKEJVVFRPTklORk8gKil3bmRQdHItPndFeHRyYTsKLSAgICBpbnQgeEJvcmRlck9mZnNldCwgeUJvcmRlck9mZnNldDsKLSAgICB4Qm9yZGVyT2Zmc2V0ID0geUJvcmRlck9mZnNldCA9IDA7CisgICAgUkVDVCAgICAgcmMsIGZvY3VzX3JlY3QsIHI7CisgICAgVUlOVCAgICAgZHRGbGFnczsKKyAgICBIUkdOICAgICBoUmduOworICAgIEhQRU4gICAgIGhPbGRQZW47CisgICAgSEJSVVNIICAgaE9sZEJydXNoOworICAgIElOVCAgICAgIG9sZEJrTW9kZTsKKyAgICBDT0xPUlJFRiBvbGRUeHRDb2xvcjsKIAogICAgIEdldENsaWVudFJlY3QoIHduZFB0ci0+aHduZFNlbGYsICZyYyApOwogCi0gICAgICAvKiBTZW5kIFdNX0NUTENPTE9SIHRvIGFsbG93IGNoYW5naW5nIHRoZSBmb250ICh0aGUgY29sb3JzIGFyZSBmaXhlZCkgKi8KKyAgICAvKiBTZW5kIFdNX0NUTENPTE9SIHRvIGFsbG93IGNoYW5naW5nIHRoZSBmb250ICh0aGUgY29sb3JzIGFyZSBmaXhlZCkgKi8KICAgICBpZiAoaW5mb1B0ci0+aEZvbnQpIFNlbGVjdE9iamVjdCggaERDLCBpbmZvUHRyLT5oRm9udCApOwogICAgIEJVVFRPTl9TRU5EX0NUTENPTE9SKCB3bmRQdHIsIGhEQyApOwogICAgIGhPbGRQZW4gPSAoSFBFTilTZWxlY3RPYmplY3QoaERDLCBHZXRTeXNDb2xvclBlbihDT0xPUl9XSU5ET1dGUkFNRSkpOwogICAgIGhPbGRCcnVzaCA9KEhCUlVTSClTZWxlY3RPYmplY3QoaERDLEdldFN5c0NvbG9yQnJ1c2goQ09MT1JfQlRORkFDRSkpOwotICAgIFNldEJrTW9kZShoREMsIFRSQU5TUEFSRU5UKTsKKyAgICBvbGRCa01vZGUgPSBTZXRCa01vZGUoaERDLCBUUkFOU1BBUkVOVCk7CiAKICAgICBpZiAoIFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spCiAgICAgeworICAgICAgICBDT0xPUlJFRiBjbHJfd25kID0gR2V0U3lzQ29sb3IoQ09MT1JfV0lORE9XKTsKICAgICAgICAgUmVjdGFuZ2xlKGhEQywgcmMubGVmdCwgcmMudG9wLCByYy5yaWdodCwgcmMuYm90dG9tKTsKIAotICAgICAgICBTZXRQaXhlbCggaERDLCByYy5sZWZ0LCByYy50b3AsIEdldFN5c0NvbG9yKENPTE9SX1dJTkRPVykgKTsKLSAgICAgICAgU2V0UGl4ZWwoIGhEQywgcmMubGVmdCwgcmMuYm90dG9tLTEsIEdldFN5c0NvbG9yKENPTE9SX1dJTkRPVykgKTsKLSAgICAgICAgU2V0UGl4ZWwoIGhEQywgcmMucmlnaHQtMSwgcmMudG9wLCBHZXRTeXNDb2xvcihDT0xPUl9XSU5ET1cpICk7Ci0gICAgICAgIFNldFBpeGVsKCBoREMsIHJjLnJpZ2h0LTEsIHJjLmJvdHRvbS0xLCBHZXRTeXNDb2xvcihDT0xPUl9XSU5ET1cpKTsKKyAgICAgICAgU2V0UGl4ZWwoIGhEQywgcmMubGVmdCwgcmMudG9wLCBjbHJfd25kKTsKKyAgICAgICAgU2V0UGl4ZWwoIGhEQywgcmMubGVmdCwgcmMuYm90dG9tLTEsIGNscl93bmQpOworICAgICAgICBTZXRQaXhlbCggaERDLCByYy5yaWdodC0xLCByYy50b3AsIGNscl93bmQpOworICAgICAgICBTZXRQaXhlbCggaERDLCByYy5yaWdodC0xLCByYy5ib3R0b20tMSwgY2xyX3duZCk7CiAJSW5mbGF0ZVJlY3QoICZyYywgLTEsIC0xICk7CiAgICAgfQogICAgIApAQCAtNDMxLDI0ICs2NTUsMTkgQEAKIAkgICAgU2VsZWN0T2JqZWN0KGhEQywgR2V0U3lzQ29sb3JCcnVzaChDT0xPUl9CVE5TSEFET1cpKTsKIAkgICAgUGF0Qmx0KGhEQywgcmMubGVmdCwgcmMudG9wLCAxLCByYy5ib3R0b20tcmMudG9wLCBQQVRDT1BZICk7CiAJICAgIFBhdEJsdChoREMsIHJjLmxlZnQsIHJjLnRvcCwgcmMucmlnaHQtcmMubGVmdCwgMSwgUEFUQ09QWSApOwotCSAgICByYy5sZWZ0ICs9IDI7ICAvKiBUbyBwb3NpdGlvbiB0aGUgdGV4dCBkb3duIGFuZCByaWdodCAqLwotCSAgICByYy50b3AgICs9IDI7CiAJfSBlbHNlIHsKIAkgICByYy5yaWdodCsrLCByYy5ib3R0b20rKzsKIAkgICBEcmF3RWRnZSggaERDLCAmcmMsIEVER0VfUkFJU0VELCBCRl9SRUNUICk7Ci0KLQkgICAvKiBUbyBwbGFjZSB0aGUgYml0bWFwIGNvcnJlY3RseSAqLwotCSAgIHhCb3JkZXJPZmZzZXQgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWEVER0UpOwotCSAgIHlCb3JkZXJPZmZzZXQgKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWUVER0UpOwotCiAJICAgcmMucmlnaHQtLSwgcmMuYm90dG9tLS07CiAJfQogICAgIH0KICAgICBlbHNlCiAgICAgewotICAgICAgICBVSU5UIHVTdGF0ZSA9IERGQ1NfQlVUVE9OUFVTSDsKKyAgICAgICAgVUlOVCB1U3RhdGUgPSBERkNTX0JVVFRPTlBVU0ggfCBERkNTX0FESlVTVFJFQ1Q7CiAKLSAgICAgICAgaWYgKHB1c2hlZFN0YXRlKQorICAgICAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgQlNfRkxBVCkKKyAgICAgICAgICAgIHVTdGF0ZSB8PSBERkNTX01PTk87CisgICAgICAgIGVsc2UgaWYgKHB1c2hlZFN0YXRlKQogCXsKIAkgICAgaWYgKCAod25kUHRyLT5kd1N0eWxlICYgMHgwMDBmKSA9PSBCU19ERUZQVVNIQlVUVE9OICkKIAkgICAgICAgIHVTdGF0ZSB8PSBERkNTX0ZMQVQ7CkBAIC00NTYsMjExICs2NzUsNTQgQEAKIAkgICAgICAgIHVTdGF0ZSB8PSBERkNTX1BVU0hFRDsKIAl9CiAKKyAgICAgICAgaWYgKGluZm9QdHItPnN0YXRlICYgKEJVVFRPTl9DSEVDS0VEIHwgQlVUVE9OXzNTVEFURSkpCisgICAgICAgICAgICB1U3RhdGUgfD0gREZDU19DSEVDS0VEOworCiAJRHJhd0ZyYW1lQ29udHJvbCggaERDLCAmcmMsIERGQ19CVVRUT04sIHVTdGF0ZSApOwotCUluZmxhdGVSZWN0KCAmcmMsIC0yLCAtMiApOwogCiAJZm9jdXNfcmVjdCA9IHJjOwotCi0gICAgICAgIGlmIChwdXNoZWRTdGF0ZSkKLQl7Ci0JICAgIHJjLmxlZnQgKz0gMjsgIC8qIFRvIHBvc2l0aW9uIHRoZSB0ZXh0IGRvd24gYW5kIHJpZ2h0ICovCi0JICAgIHJjLnRvcCAgKz0gMjsKLQl9CiAgICAgfQogCi0gICAgLyogZHJhdyBidXR0b24gbGFiZWwsIGlmIGFueToKLSAgICAgKgotICAgICAqIEluIHdpbjl4IHdlIGRvbid0IHNob3cgdGV4dCBpZiB0aGVyZSBpcyBhIGJpdG1hcCBvciBpY29uLgotICAgICAqIEkgZG9uJ3Qga25vdyBhYm91dCB3aW4zMSBzbyBJIGxlYXZlIGl0IGFzIGl0IHdhcyBmb3Igd2luMzEuCi0gICAgICogRGVubmlzIEJq9nJrbHVuZCAxMiBKdWwsIDk5Ci0gICAgICovCi0gICAgaWYgKCB3bmRQdHItPnRleHQgJiYgd25kUHRyLT50ZXh0WzBdCi0JICYmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LIHx8ICEod25kUHRyLT5kd1N0eWxlICYgKEJTX0lDT058QlNfQklUTUFQKSkpICkKKyAgICAvKiBkcmF3IGJ1dHRvbiBsYWJlbCAqLworICAgIHIgPSByYzsKKyAgICBkdEZsYWdzID0gQlVUVE9OX0NhbGNMYWJlbFJlY3Qod25kUHRyLCBoREMsICZyKTsKKworICAgIGlmIChkdEZsYWdzID09IChVSU5UKS0xTCkKKyAgICAgICBnb3RvIGNsZWFudXA7CisKKyAgICBpZiAocHVzaGVkU3RhdGUpCisgICAgICAgT2Zmc2V0UmVjdCgmciwgMSwgMSk7CisKKyAgICBpZihUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LKQogICAgIHsKLSAgICAgICAgTE9HQlJVU0ggbGI7Ci0gICAgICAgIEdldE9iamVjdEEoIEdldFN5c0NvbG9yQnJ1c2goQ09MT1JfQlRORkFDRSksIHNpemVvZihsYiksICZsYiApOwotICAgICAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfRElTQUJMRUQgJiYKLSAgICAgICAgICAgIEdldFN5c0NvbG9yKENPTE9SX0dSQVlURVhUKT09bGIubGJDb2xvcikKLSAgICAgICAgICAgIC8qIGRvbid0IHdyaXRlIGdyYXkgdGV4dCBvbiBncmF5IGJhY2tncm91bmQgKi8KLSAgICAgICAgICAgIFBhaW50R3JheU9uR3JheSggaERDLGluZm9QdHItPmhGb250LCZyYyx3bmRQdHItPnRleHQsCi0JCQkgICAgICAgRFRfQ0VOVEVSIHwgRFRfVkNFTlRFUiApOwotICAgICAgICBlbHNlCi0gICAgICAgIHsKLSAgICAgICAgICAgIFNldFRleHRDb2xvciggaERDLCAod25kUHRyLT5kd1N0eWxlICYgV1NfRElTQUJMRUQpID8KLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdldFN5c0NvbG9yKENPTE9SX0dSQVlURVhUKSA6Ci0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRTeXNDb2xvcihDT0xPUl9CVE5URVhUKSApOwotICAgICAgICAgICAgRHJhd1RleHRXKCBoREMsIHduZFB0ci0+dGV4dCwgLTEsICZyYywKLSAgICAgICAgICAgICAgICAgICAgICAgICBEVF9TSU5HTEVMSU5FIHwgRFRfQ0VOVEVSIHwgRFRfVkNFTlRFUiApOwotICAgICAgICAgICAgLyogZG8gd2UgaGF2ZSB0aGUgZm9jdXM/Ci0JICAgICAqIFdpbjl4IGRyYXdzIGZvY3VzIGxhc3Qgd2l0aCBhIHNpemUgcHJvcC4gdG8gdGhlIGJ1dHRvbgotCSAgICAgKi8KLSAgICAgICAgICAgIGlmIChUV0VBS19XaW5lTG9vayA9PSBXSU4zMV9MT09LCi0JCSYmIGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hBU0ZPQ1VTKQotICAgICAgICAgICAgewotICAgICAgICAgICAgICAgIFJFQ1QgciA9IHsgMCwgMCwgMCwgMCB9OwotICAgICAgICAgICAgICAgIElOVCB4ZGVsdGEsIHlkZWx0YTsKLQotICAgICAgICAgICAgICAgIERyYXdUZXh0VyggaERDLCB3bmRQdHItPnRleHQsIC0xLCAmciwKLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFRfU0lOR0xFTElORSB8IERUX0NBTENSRUNUICk7Ci0gICAgICAgICAgICAgICAgeGRlbHRhID0gKChyYy5yaWdodCAtIHJjLmxlZnQpIC0gKHIucmlnaHQgLSByLmxlZnQpIC0gMSkgLyAyOwotICAgICAgICAgICAgICAgIHlkZWx0YSA9ICgocmMuYm90dG9tIC0gcmMudG9wKSAtIChyLmJvdHRvbSAtIHIudG9wKSAtIDEpIC8gMjsKLSAgICAgICAgICAgICAgICBpZiAoeGRlbHRhIDwgMCkgeGRlbHRhID0gMDsKLSAgICAgICAgICAgICAgICBpZiAoeWRlbHRhIDwgMCkgeWRlbHRhID0gMDsKLSAgICAgICAgICAgICAgICBJbmZsYXRlUmVjdCggJnJjLCAteGRlbHRhLCAteWRlbHRhICk7Ci0gICAgICAgICAgICAgICAgRHJhd0ZvY3VzUmVjdCggaERDLCAmcmMgKTsKLSAgICAgICAgICAgIH0KLSAgICAgICAgfSAgIAotICAgIH0KLSAgICBpZiAoICgod25kUHRyLT5kd1N0eWxlICYgQlNfSUNPTikgfHwgKHduZFB0ci0+ZHdTdHlsZSAmIEJTX0JJVE1BUCkgKSAmJgotCSAoaW5mb1B0ci0+aEltYWdlICE9IDApICkKLSAgICB7Ci0JaW50IHlPZmZzZXQsIHhPZmZzZXQ7Ci0JaW50IGltYWdlV2lkdGgsIGltYWdlSGVpZ2h0OwotCi0JLyoKLQkgKiBXZSBleHRyYWN0IHRoZSBzaXplIG9mIHRoZSBpbWFnZSBmcm9tIHRoZSBoYW5kbGUuCi0JICovCi0JaWYgKHduZFB0ci0+ZHdTdHlsZSAmIEJTX0lDT04pCi0JewotCSAgICBJQ09OSU5GTyBpY29uSW5mbzsKLQkgICAgQklUTUFQICAgYm07Ci0KLQkgICAgR2V0SWNvbkluZm8oKEhJQ09OKWluZm9QdHItPmhJbWFnZSwgJmljb25JbmZvKTsKLQkgICAgR2V0T2JqZWN0QSAoaWNvbkluZm8uaGJtQ29sb3IsIHNpemVvZihCSVRNQVApLCAmYm0pOwotCSAgICAKLQkgICAgaW1hZ2VXaWR0aCAgPSBibS5ibVdpZHRoOwotCSAgICBpbWFnZUhlaWdodCA9IGJtLmJtSGVpZ2h0OwotCi0gICAgICAgICAgICBEZWxldGVPYmplY3QoaWNvbkluZm8uaGJtQ29sb3IpOwotICAgICAgICAgICAgRGVsZXRlT2JqZWN0KGljb25JbmZvLmhibU1hc2spOwotCi0JfQotCWVsc2UKLQl7Ci0JICAgIEJJVE1BUCAgIGJtOwotCi0JICAgIEdldE9iamVjdEEgKGluZm9QdHItPmhJbWFnZSwgc2l6ZW9mKEJJVE1BUCksICZibSk7Ci0JCi0JICAgIGltYWdlV2lkdGggID0gYm0uYm1XaWR0aDsKLQkgICAgaW1hZ2VIZWlnaHQgPSBibS5ibUhlaWdodDsKLQl9Ci0KLQkvKiBDZW50ZXIgdGhlIGJpdG1hcCAqLwotCXhPZmZzZXQgPSAoKChyYy5yaWdodCAtIHJjLmxlZnQpIC0gMip4Qm9yZGVyT2Zmc2V0KSAtIGltYWdlV2lkdGggKSAvIDI7Ci0JeU9mZnNldCA9ICgoKHJjLmJvdHRvbSAtIHJjLnRvcCkgLSAyKnlCb3JkZXJPZmZzZXQpIC0gaW1hZ2VIZWlnaHQpIC8gMjsKLQotCS8qIElmIHRoZSBpbWFnZSBpcyB0b28gYmlnIGZvciB0aGUgYnV0dG9uIHRoZW4gY3JlYXRlIGEgcmVnaW9uICovCi0gICAgICAgIGlmKHhPZmZzZXQgPCAwIHx8IHlPZmZzZXQgPCAwKQotCXsKLSAgICAgICAgICAgIEhSR04gaEJpdG1hcFJnbiA9IDA7Ci0gICAgICAgICAgICBoQml0bWFwUmduID0gQ3JlYXRlUmVjdFJnbigKLSAgICAgICAgICAgICAgICByYy5sZWZ0ICsgeEJvcmRlck9mZnNldCwgcmMudG9wICt5Qm9yZGVyT2Zmc2V0LCAKLSAgICAgICAgICAgICAgICByYy5yaWdodCAtIHhCb3JkZXJPZmZzZXQsIHJjLmJvdHRvbSAtIHlCb3JkZXJPZmZzZXQpOwotICAgICAgICAgICAgU2VsZWN0Q2xpcFJnbihoREMsIGhCaXRtYXBSZ24pOwotICAgICAgICAgICAgRGVsZXRlT2JqZWN0KGhCaXRtYXBSZ24pOwotCX0KLQotCS8qIExldCBtaW5pbXVtIDEgc3BhY2UgZnJvbSBib3JkZXIgKi8KLQl4T2Zmc2V0KyssIHlPZmZzZXQrKzsKLQotCS8qCi0JICogRHJhdyB0aGUgaW1hZ2Ugbm93LgotCSAqLwotCWlmICh3bmRQdHItPmR3U3R5bGUgJiBCU19JQ09OKQotCXsKLSAgCSAgICBEcmF3SWNvbihoREMsCi0gICAgICAgICAgICAgICAgcmMubGVmdCArIHhPZmZzZXQsIHJjLnRvcCArIHlPZmZzZXQsCi0JCSAgICAgKEhJQ09OKWluZm9QdHItPmhJbWFnZSk7Ci0JfQotCWVsc2UKLSAgICAgICAgewotCSAgICBIREMgaGRjTWVtOwotCi0JICAgIGhkY01lbSA9IENyZWF0ZUNvbXBhdGlibGVEQyAoaERDKTsKLQkgICAgU2VsZWN0T2JqZWN0IChoZGNNZW0sIChIQklUTUFQKWluZm9QdHItPmhJbWFnZSk7Ci0JICAgIEJpdEJsdChoREMsIAotCQkgICByYy5sZWZ0ICsgeE9mZnNldCwgCi0JCSAgIHJjLnRvcCArIHlPZmZzZXQsIAotCQkgICBpbWFnZVdpZHRoLCBpbWFnZUhlaWdodCwKLQkJICAgaGRjTWVtLCAwLCAwLCBTUkNDT1BZKTsKLQkgICAgCi0JICAgIERlbGV0ZURDIChoZGNNZW0pOwotCX0KLQotICAgICAgICBpZih4T2Zmc2V0IDwgMCB8fCB5T2Zmc2V0IDwgMCkKLSAgICAgICAgewotICAgICAgICAgICAgU2VsZWN0Q2xpcFJnbihoREMsIDApOwotICAgICAgICB9CisgICAgICAgZm9jdXNfcmVjdCA9IHI7CisgICAgICAgSW5mbGF0ZVJlY3QoJmZvY3VzX3JlY3QsIDIsIDApOwogICAgIH0KIAotICAgIGlmIChUV0VBS19XaW5lTG9vayAhPSBXSU4zMV9MT09LCi0JJiYgaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSEFTRk9DVVMpCisgICAgaFJnbiA9IENyZWF0ZVJlY3RSZ24ocmMubGVmdCwgcmMudG9wLCByYy5yaWdodCwgcmMuYm90dG9tKTsKKyAgICBTZWxlY3RDbGlwUmduKGhEQywgaFJnbik7CisKKyAgICBvbGRUeHRDb2xvciA9IFNldFRleHRDb2xvciggaERDLCBHZXRTeXNDb2xvcihDT0xPUl9CVE5URVhUKSApOworCisgICAgQlVUVE9OX0RyYXdMYWJlbCh3bmRQdHIsIGhEQywgZHRGbGFncywgJnIpOworCisgICAgU2V0VGV4dENvbG9yKCBoREMsIG9sZFR4dENvbG9yICk7CisgICAgU2VsZWN0Q2xpcFJnbihoREMsIDApOworICAgIERlbGV0ZU9iamVjdChoUmduKTsKKworICAgIGlmIChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9IQVNGT0NVUykKICAgICB7CiAgICAgICAgIEluZmxhdGVSZWN0KCAmZm9jdXNfcmVjdCwgLTEsIC0xICk7CisgICAgICAgIEludGVyc2VjdFJlY3QoJmZvY3VzX3JlY3QsICZmb2N1c19yZWN0LCAmcmMpOwogICAgICAgICBEcmF3Rm9jdXNSZWN0KCBoREMsICZmb2N1c19yZWN0ICk7CiAgICAgfQogCi0gICAgCisgY2xlYW51cDoKICAgICBTZWxlY3RPYmplY3QoIGhEQywgaE9sZFBlbiApOwogICAgIFNlbGVjdE9iamVjdCggaERDLCBoT2xkQnJ1c2ggKTsKKyAgICBTZXRCa01vZGUoaERDLCBvbGRCa01vZGUpOwogfQogCi0KLS8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCi0gKiAgIFBCX1BhaW50ICYgQ0JfUGFpbnQgc3ViIGZ1bmN0aW9uICAgICAgICAgICAgICAgICAgICAgICAgW2ludGVybmFsXQotICogICBQYWludCB0ZXh0IHVzaW5nIGEgcmFzdGVyIGJydXNoIHRvIGF2b2lkIGdyYXkgdGV4dCBvbiBncmF5IAotICogICBiYWNrZ3JvdW5kLiAnZm9ybWF0JyBjYW4gYmUgYSBjb21iaW5hdGlvbiBvZiBEVF9DRU5URVIgYW5kIAotICogICBEVF9WQ0VOVEVSIHRvIHVzZSB0aGlzIGZ1bmN0aW9uIGluIGJvdGggUEJfUEFJTlQgYW5kIAotICogICBDQl9QQUlOVC4gICAtIERpcmsgVGhpZXJiYWNoCi0gKgotICogICBGSVhNRTogVGhpcyBhbmQgVEVYVF9HcmF5U3RyaW5nIHNob3VsZCBiZSBldmVudHVhbGx5IGNvbWJpbmVkLAotICogICBzbyBjYWxsaW5nIG9uZSBjb21tb24gZnVuY3Rpb24gZnJvbSBQQl9QYWludCwgQ0JfUGFpbnQgYW5kCi0gKiAgIFRFWFRfR3JheVN0cmluZyB3aWxsIGJlIGVub3VnaC4gQWxzbyBub3RlIHRoYXQgdGhpcwotICogICBmdW5jdGlvbiBpZ25vcmVzIHRoZSBDQUNIRV9HZXRQYXR0ZXJuIGZ1bmNzLgotICovCi0KLXZvaWQgUGFpbnRHcmF5T25HcmF5KEhEQyBoREMsIEhGT05UIGhGb250LCBSRUNUICpyYywgTFBDV1NUUiB0ZXh0LAotCQkJVUlOVCBmb3JtYXQpCi17Ci0vKiAgVGhpcyBpcyB0aGUgc3RhbmRhcmQgZ3JheSBvbiBncmF5IHBhdHRlcm46Ci0gICAgc3RhdGljIGNvbnN0IFdPUkQgUGF0dGVybltdID0gezB4QUEsMHg1NSwweEFBLDB4NTUsMHhBQSwweDU1LDB4QUEsMHg1NX07IAotKi8KLS8qICBUaGlzIHBhdHRlcm4gZ2l2ZXMgYmV0dGVyIHJlYWRhYmlsaXR5IHdpdGggWCBGb250cy4KLSAgICBGSVhNRTogTWF5YmUgdGhlIHVzZXIgc2hvdWxkIGJlIGFsbG93ZWQgdG8gZGVjaWRlIHdoaWNoIGhlIHdhbnRzLiAqLwotICAgIHN0YXRpYyBjb25zdCBXT1JEIFBhdHRlcm5bXSA9IHsweDU1LDB4RkYsMHhBQSwweEZGLDB4NTUsMHhGRiwweEFBLDB4RkZ9OyAKLQotICAgIEhCSVRNQVAgaGJtICA9IENyZWF0ZUJpdG1hcCggOCwgOCwgMSwgMSwgUGF0dGVybiApOwotICAgIEhEQyBoZGNNZW0gPSBDcmVhdGVDb21wYXRpYmxlREMoaERDKTsKLSAgICBIQklUTUFQIGhibU1lbTsKLSAgICBIQlJVU0ggaEJyOwotICAgIFJFQ1QgcmVjdCxyYzI7Ci0KLSAgICByZWN0PSpyYzsKLSAgICBEcmF3VGV4dFcoIGhEQywgdGV4dCwgLTEsICZyZWN0LCBEVF9TSU5HTEVMSU5FIHwgRFRfQ0FMQ1JFQ1QpOwotICAgIC8qIG5vdyB0ZXh0IHdpZHRoIGFuZCBoZWlnaHQgYXJlIGluIHJlY3QucmlnaHQgYW5kIHJlY3QuYm90dG9tICovCi0gICAgcmMyPXJlY3Q7Ci0gICAgcmVjdC5sZWZ0ID0gcmVjdC50b3AgPSAwOyAvKiBkcmF3aW5nIHBvcyBpbiBoZGNNZW0gKi8KLSAgICBpZiAoZm9ybWF0ICYgRFRfQ0VOVEVSKSByZWN0LmxlZnQ9KHJjLT5yaWdodC1yZWN0LnJpZ2h0KS8yOwotICAgIGlmIChmb3JtYXQgJiBEVF9WQ0VOVEVSKSByZWN0LnRvcD0ocmMtPmJvdHRvbS1yZWN0LmJvdHRvbSkvMjsKLSAgICBoYm1NZW0gPSBDcmVhdGVDb21wYXRpYmxlQml0bWFwKCBoREMscmVjdC5yaWdodCxyZWN0LmJvdHRvbSApOwotICAgIFNlbGVjdE9iamVjdCggaGRjTWVtLCBoYm1NZW0pOwotICAgIFBhdEJsdCggaGRjTWVtLDAsMCxyZWN0LnJpZ2h0LHJlY3QuYm90dG9tLFdISVRFTkVTUyk7Ci0gICAgICAvKiB3aWxsIGJlIG92ZXJ3cml0dGVuIGJ5IERyYXdUZXh0LCBidXQganVzdCBpbiBjYXNlICovCi0gICAgaWYgKGhGb250KSBTZWxlY3RPYmplY3QoIGhkY01lbSwgaEZvbnQpOwotICAgIERyYXdUZXh0VyggaGRjTWVtLCB0ZXh0LCAtMSwgJnJjMiwgRFRfU0lOR0xFTElORSk7Ci0gICAgICAvKiBBZnRlciBkcmF3OiBmb3JlZ3JvdW5kID0gMCBiaXRzLCBiYWNrZ3JvdW5kID0gMSBiaXRzICovCi0gICAgaEJyID0gU2VsZWN0T2JqZWN0KCBoZGNNZW0sIENyZWF0ZVBhdHRlcm5CcnVzaChoYm0pICk7Ci0gICAgRGVsZXRlT2JqZWN0KCBoYm0gKTsKLSAgICBQYXRCbHQoIGhkY01lbSwwLDAscmVjdC5yaWdodCxyZWN0LmJvdHRvbSwweEFGMDIyOSk7IAotICAgICAgLyogb25seSBrZWVwIHRoZSBmb3JlZ3JvdW5kIGJpdHMgd2hlcmUgcGF0dGVybiBpcyAxICovCi0gICAgRGVsZXRlT2JqZWN0KCBTZWxlY3RPYmplY3QoIGhkY01lbSxoQnIpICk7Ci0gICAgQml0Qmx0KGhEQyxyZWN0LmxlZnQscmVjdC50b3AscmVjdC5yaWdodCxyZWN0LmJvdHRvbSxoZGNNZW0sMCwwLFNSQ0FORCk7Ci0gICAgICAvKiBrZWVwIHRoZSBiYWNrZ3JvdW5kIG9mIHRoZSBkZXN0ICovCi0gICAgRGVsZXRlREMoIGhkY01lbSk7Ci0gICAgRGVsZXRlT2JqZWN0KCBoYm1NZW0gKTsKLX0KLQotCiAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICogICAgICAgQ2hlY2sgQm94ICYgUmFkaW8gQnV0dG9uIEZ1bmN0aW9ucwogICovCkBAIC02NjksMTcgKzczMSwxNCBAQAogewogICAgIFJFQ1QgcmJveCwgcnRleHQsIGNsaWVudDsKICAgICBIQlJVU0ggaEJydXNoOwotICAgIGludCB0ZXh0bGVuLCBkZWx0YTsKKyAgICBpbnQgZGVsdGE7CiAgICAgQlVUVE9OSU5GTyAqaW5mb1B0ciA9IChCVVRUT05JTkZPICopd25kUHRyLT53RXh0cmE7CisgICAgVUlOVCBkdEZsYWdzOworICAgIEhSR04gaFJnbjsKIAotICAgIC8qIAotICAgICAqIGlmIHRoZSBidXR0b24gaGFzIGEgYml0bWFwL2ljb24sIGRyYXcgYSBub3JtYWwgcHVzaGJ1dHRvbgotICAgICAqIGluc3RlYWQgb2YgYSByYWRpb24gYnV0dG9uLgotICAgICAqLwotICAgIGlmIChpbmZvUHRyLT5oSW1hZ2UgIT0gMCkKKyAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgQlNfUFVTSExJS0UpCiAgICAgewotICAgICAgICBCT09MIGJIaWdoTGlnaHRlZCA9ICgoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSElHSExJR0hURUQpIHx8Ci0JCQkgICAgIChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9DSEVDS0VEKSk7CisgICAgICAgIEJPT0wgYkhpZ2hMaWdodGVkID0gKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hJR0hMSUdIVEVEKTsKIAogICAgICAgICBCVVRUT05fRHJhd1B1c2hCdXR0b24od25kUHRyLAogCQkJICAgICAgaERDLApAQCAtNjg4LDE4ICs3NDcsMTQgQEAKIAlyZXR1cm47CiAgICAgfQogCi0gICAgdGV4dGxlbiA9IDA7CiAgICAgR2V0Q2xpZW50UmVjdCh3bmRQdHItPmh3bmRTZWxmLCAmY2xpZW50KTsKICAgICByYm94ID0gcnRleHQgPSBjbGllbnQ7CiAKICAgICBpZiAoaW5mb1B0ci0+aEZvbnQpIFNlbGVjdE9iamVjdCggaERDLCBpbmZvUHRyLT5oRm9udCApOwogCi0gICAgLyogU29tZXRoaW5nIGlzIHN0aWxsIG5vdCByaWdodCwgY2hlY2tib3hlcyAoYW5kIGVkaXQgY29udHJvbHMpCi0gICAgICogaW4gd3NwaW5nMzIgaGF2ZSB3aGl0ZSBiYWNrZ3JvdW5kcyBpbnN0ZWFkIG9mIGRhcmsgZ3JleS4KLSAgICAgKiBCVVRUT05fU0VORF9DVExDT0xPUigpIGlzIGV2ZW4gd29yc2Ugc2luY2UgaXQgcmV0dXJucyAwIGluIHRoaXMKLSAgICAgKiBwYXJ0aWN1bGFyIGNhc2UgYW5kIHRoZSBiYWNrZ3JvdW5kIGlzIG5vdCBwYWludGVkIGF0IGFsbC4KKyAgICAvKiBHZXRDb250cm9sQnJ1c2gxNiBzZW5kcyBXTV9DVExDT0xPUkJUTiwgcGx1cyBpdCByZXR1cm5zIGRlZmF1bHQgYnJ1c2gKKyAgICAgKiBpZiBwYXJlbnQgZGlkbid0IHJldHVybiB2YWxpZCBvbmUuIFNvIHdlIGtpbGwgdHdvIGhhcmVzIGF0IG9uY2UKICAgICAgKi8KLQogICAgIGhCcnVzaCA9IEdldENvbnRyb2xCcnVzaDE2KCB3bmRQdHItPmh3bmRTZWxmLCBoREMsIENUTENPTE9SX0JUTiApOwogCiAgICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIEJTX0xFRlRURVhUKSAKQEAgLTcxNSw5ICs3NzAsNyBAQAogICAgICAgICByYm94LnJpZ2h0ID0gY2hlY2tCb3hXaWR0aDsKICAgICB9CiAKLSAgICAgIC8qIERyYXcgdGhlIGNoZWNrLWJveCBiaXRtYXAgKi8KLQotICAgIGlmICh3bmRQdHItPnRleHQpIHRleHRsZW4gPSBsc3RybGVuVyggd25kUHRyLT50ZXh0ICk7CisgICAgLyogRHJhdyB0aGUgY2hlY2stYm94IGJpdG1hcCAqLwogICAgIGlmIChhY3Rpb24gPT0gT0RBX0RSQVdFTlRJUkUgfHwgYWN0aW9uID09IE9EQV9TRUxFQ1QpCiAgICAgeyAKICAgICAgICAgaWYoIFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0sgKQpAQCAtNzgxLDQwICs4MzQsMzEgQEAKIAogCSAgICBEcmF3RnJhbWVDb250cm9sKCBoREMsICZyYm94LCBERkNfQlVUVE9OLCBzdGF0ZSApOwogICAgICAgICB9Ci0KLSAgICAgICAgaWYoIHRleHRsZW4gJiYgYWN0aW9uICE9IE9EQV9TRUxFQ1QgKQotICAgICAgICB7Ci0JICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfRElTQUJMRUQgJiYKLQkgICAgICBHZXRTeXNDb2xvcihDT0xPUl9HUkFZVEVYVCk9PUdldEJrQ29sb3IoaERDKSkgewotICAgICAgICAgICAgLyogZG9uJ3Qgd3JpdGUgZ3JheSB0ZXh0IG9uIGdyYXkgYmFja2dyb3VuZCAqLwotICAgICAgICAgICAgUGFpbnRHcmF5T25HcmF5KCBoREMsIGluZm9QdHItPmhGb250LCAmcnRleHQsIHduZFB0ci0+dGV4dCwKLQkJCSAgICAgRFRfVkNFTlRFUik7Ci0JICB9IGVsc2UgewotICAgICAgICAgICAgaWYgKHduZFB0ci0+ZHdTdHlsZSAmIFdTX0RJU0FCTEVEKQotICAgICAgICAgICAgICAgIFNldFRleHRDb2xvciggaERDLCBHZXRTeXNDb2xvcihDT0xPUl9HUkFZVEVYVCkgKTsKLSAgICAgICAgICAgIERyYXdUZXh0VyggaERDLCB3bmRQdHItPnRleHQsIHRleHRsZW4sICZydGV4dCwKLQkJCSBEVF9TSU5HTEVMSU5FIHwgRFRfVkNFTlRFUiApOwotCSAgfQotICAgICAgICB9CiAgICAgfQogCisgICAgLyogRHJhdyBsYWJlbCAqLworICAgIGNsaWVudCA9IHJ0ZXh0OworICAgIGR0RmxhZ3MgPSBCVVRUT05fQ2FsY0xhYmVsUmVjdCh3bmRQdHIsIGhEQywgJnJ0ZXh0KTsKKworICAgIGlmIChkdEZsYWdzID09IChVSU5UKS0xTCkgLyogTm90aW5nIHRvIGRyYXcgKi8KKwlyZXR1cm47CisgICAgaFJnbiA9IENyZWF0ZVJlY3RSZ24oY2xpZW50LmxlZnQsIGNsaWVudC50b3AsIGNsaWVudC5yaWdodCwgY2xpZW50LmJvdHRvbSk7CisgICAgU2VsZWN0Q2xpcFJnbihoREMsIGhSZ24pOworICAgIERlbGV0ZU9iamVjdChoUmduKTsKKworICAgIGlmIChhY3Rpb24gPT0gT0RBX0RSQVdFTlRJUkUpCisJQlVUVE9OX0RyYXdMYWJlbCh3bmRQdHIsIGhEQywgZHRGbGFncywgJnJ0ZXh0KTsKKworICAgIC8qIC4uLiBhbmQgZm9jdXMgKi8KICAgICBpZiAoKGFjdGlvbiA9PSBPREFfRk9DVVMpIHx8CiAgICAgICAgICgoYWN0aW9uID09IE9EQV9EUkFXRU5USVJFKSAmJiAoaW5mb1B0ci0+c3RhdGUgJiBCVVRUT05fSEFTRk9DVVMpKSkKICAgICB7Ci0JLyogYWdhaW4sIHRoaXMgaXMgd2hhdCBDVEwzRCBleHBlY3RzICovCi0KLSAgICAgICAgU2V0UmVjdEVtcHR5KCZyYm94KTsKLSAgICAgICAgaWYoIHRleHRsZW4gKQotICAgICAgICAgICAgRHJhd1RleHRXKCBoREMsIHduZFB0ci0+dGV4dCwgdGV4dGxlbiwgJnJib3gsCi0JCQkgRFRfU0lOR0xFTElORSB8IERUX0NBTENSRUNUICk7Ci0gICAgICAgIHRleHRsZW4gPSByYm94LmJvdHRvbSAtIHJib3gudG9wOwotICAgICAgICBkZWx0YSA9ICgocnRleHQuYm90dG9tIC0gcnRleHQudG9wKSAtIHRleHRsZW4pLzI7Ci0gICAgICAgIHJib3guYm90dG9tID0gKHJib3gudG9wID0gcnRleHQudG9wICsgZGVsdGEgLSAxKSArIHRleHRsZW4gKyAyOwotICAgICAgICB0ZXh0bGVuID0gcmJveC5yaWdodCAtIHJib3gubGVmdDsKLSAgICAgICAgcmJveC5yaWdodCA9IChyYm94LmxlZnQgKz0gLS1ydGV4dC5sZWZ0KSArIHRleHRsZW4gKyAyOwotICAgICAgICBJbnRlcnNlY3RSZWN0KCZyYm94LCAmcmJveCwgJnJ0ZXh0KTsKLSAgICAgICAgRHJhd0ZvY3VzUmVjdCggaERDLCAmcmJveCApOworCXJ0ZXh0LmxlZnQtLTsKKwlydGV4dC5yaWdodCsrOworCUludGVyc2VjdFJlY3QoJnJ0ZXh0LCAmcnRleHQsICZjbGllbnQpOworCURyYXdGb2N1c1JlY3QoIGhEQywgJnJ0ZXh0ICk7CiAgICAgfQorICAgIFNlbGVjdENsaXBSZ24oaERDLCAwKTsKIH0KIAogCkBAIC04NTIsMTAgKzg5NiwxNiBAQAogewogICAgIFJFQ1QgcmMsIHJjRnJhbWU7CiAgICAgQlVUVE9OSU5GTyAqaW5mb1B0ciA9IChCVVRUT05JTkZPICopd25kUHRyLT53RXh0cmE7CisgICAgSEJSVVNIIGhicjsKKyAgICBVSU5UIGR0RmxhZ3M7CiAKICAgICBpZiAoYWN0aW9uICE9IE9EQV9EUkFXRU5USVJFKSByZXR1cm47CiAKLSAgICBCVVRUT05fU0VORF9DVExDT0xPUiggd25kUHRyLCBoREMgKTsKKyAgICBpZiAoaW5mb1B0ci0+aEZvbnQpCisJU2VsZWN0T2JqZWN0IChoREMsIGluZm9QdHItPmhGb250KTsKKyAgICAvKiBHcm91cEJveCBhY3RzIGxpa2Ugc3RhdGljIGNvbnRyb2wsIHNvIGl0IHNlbmRzIENUTENPTE9SU1RBVElDICovCisgICAgaGJyID0gR2V0Q29udHJvbEJydXNoMTYoIHduZFB0ci0+aHduZFNlbGYsIGhEQywgQ1RMQ09MT1JfU1RBVElDICk7CisKIAogICAgIEdldENsaWVudFJlY3QoIHduZFB0ci0+aHduZFNlbGYsICZyYyk7CiAgICAgaWYgKFRXRUFLX1dpbmVMb29rID09IFdJTjMxX0xPT0spIHsKQEAgLTg3MSwyMSArOTIxLDI5IEBACiAJVEVYVE1FVFJJQ0EgdG07CiAJcmNGcmFtZSA9IHJjOwogCi0JaWYgKGluZm9QdHItPmhGb250KQotCSAgICBTZWxlY3RPYmplY3QgKGhEQywgaW5mb1B0ci0+aEZvbnQpOwogCUdldFRleHRNZXRyaWNzQSAoaERDLCAmdG0pOwogCXJjRnJhbWUudG9wICs9ICh0bS50bUhlaWdodCAvIDIpIC0gMTsKLQlEcmF3RWRnZSAoaERDLCAmcmNGcmFtZSwgRURHRV9FVENIRUQsIEJGX1JFQ1QpOworCURyYXdFZGdlIChoREMsICZyY0ZyYW1lLCBFREdFX0VUQ0hFRCwgQkZfUkVDVCB8CisJCQkgICAoKHduZFB0ci0+ZHdTdHlsZSAmIEJTX0ZMQVQpID8gQkZfRkxBVCA6IDApKTsKICAgICB9CiAKLSAgICBpZiAod25kUHRyLT50ZXh0KQotICAgIHsKLQlpZiAoaW5mb1B0ci0+aEZvbnQpIFNlbGVjdE9iamVjdCggaERDLCBpbmZvUHRyLT5oRm9udCApOwotICAgICAgICBpZiAod25kUHRyLT5kd1N0eWxlICYgV1NfRElTQUJMRUQpCi0gICAgICAgICAgICBTZXRUZXh0Q29sb3IoIGhEQywgR2V0U3lzQ29sb3IoQ09MT1JfR1JBWVRFWFQpICk7Ci0gICAgICAgIHJjLmxlZnQgKz0gMTA7Ci0gICAgICAgIERyYXdUZXh0VyggaERDLCB3bmRQdHItPnRleHQsIC0xLCAmcmMsIERUX1NJTkdMRUxJTkUgfCBEVF9OT0NMSVAgKTsKLSAgICB9CisgICAgSW5mbGF0ZVJlY3QoJnJjLCAtNywgMSk7CisgICAgZHRGbGFncyA9IEJVVFRPTl9DYWxjTGFiZWxSZWN0KHduZFB0ciwgaERDLCAmcmMpOworCisgICAgaWYgKGR0RmxhZ3MgPT0gKFVJTlQpLTFMKQorICAgICAgIHJldHVybjsKKworICAgIC8qIEJlY2F1c2UgYnV0dG9ucyBoYXZlIENTX1BBUkVOVERDIGNsYXNzIHN0eWxlLCB0aGVyZSBpcyBhIGNoYW5jZQorICAgICAqIHRoYXQgbGFiZWwgd2lsbCBiZSBkcmF3biBvdXQgb2YgY2xpZW50IHJlY3QuCisgICAgICogQnV0IFdpbmRvd3MgZG9lc24ndCBjbGlwIGxhYmVsJ3MgcmVjdCwgc28gZG8gSS4KKyAgICAgKi8KKworICAgIC8qIFRoZXJlIGlzIDEtcGl4ZWwgbWFyZ2luZyBhdCB0aGUgbGVmdCwgcmlnaHQsIGFuZCBib3R0b20gKi8KKyAgICByYy5sZWZ0LS07IHJjLnJpZ2h0Kys7IHJjLmJvdHRvbSsrOworICAgIEZpbGxSZWN0KGhEQywgJnJjLCBoYnIpOworICAgIHJjLmxlZnQrKzsgcmMucmlnaHQtLTsgcmMuYm90dG9tLS07CisKKyAgICBCVVRUT05fRHJhd0xhYmVsKHduZFB0ciwgaERDLCBkdEZsYWdzLCAmcmMpOyAgIAogfQogCiAKQEAgLTkzMCw3ICs5ODgsNyBAQAogICAgIGRpcy5pdGVtQWN0aW9uID0gYWN0aW9uOwogICAgIGRpcy5pdGVtU3RhdGUgID0gKChpbmZvUHRyLT5zdGF0ZSAmIEJVVFRPTl9IQVNGT0NVUykgPyBPRFNfRk9DVVMgOiAwKSB8CiAgICAgICAgICAgICAgICAgICAgICAoKGluZm9QdHItPnN0YXRlICYgQlVUVE9OX0hJR0hMSUdIVEVEKSA/IE9EU19TRUxFQ1RFRCA6IDApIHwKLSAgICAgICAgICAgICAgICAgICAgICgod25kUHRyLT5kd1N0eWxlICYgV1NfRElTQUJMRUQpID8gT0RTX0RJU0FCTEVEIDogMCk7CisgICAgICAgICAgICAgICAgICAgICAoSXNXaW5kb3dFbmFibGVkKHduZFB0ci0+aHduZFNlbGYpID8gMDogT0RTX0RJU0FCTEVEKTsKICAgICBkaXMuaHduZEl0ZW0gICA9IHduZFB0ci0+aHduZFNlbGY7CiAgICAgZGlzLmhEQyAgICAgICAgPSBoREM7CiAgICAgZGlzLml0ZW1EYXRhICAgPSAwOwo=