LyoKICogUGl4ZWwgYW5kIHZlcnRleCBzaGFkZXJzIGltcGxlbWVudGF0aW9uIHVzaW5nIEFSQl92ZXJ0ZXhfcHJvZ3JhbQogKiBhbmQgQVJCX2ZyYWdtZW50X3Byb2dyYW0gR0wgZXh0ZW5zaW9ucy4KICoKICogQ29weXJpZ2h0IDIwMDItMjAwMyBKYXNvbiBFZG1lYWRlcwogKiBDb3B5cmlnaHQgMjAwMi0yMDAzIFJhcGhhZWwgSnVucXVlaXJhCiAqIENvcHlyaWdodCAyMDA0IENocmlzdGlhbiBDb3N0YQogKiBDb3B5cmlnaHQgMjAwNSBPbGl2ZXIgU3RpZWJlcgogKiBDb3B5cmlnaHQgMjAwNiBJdmFuIEd5dXJkaWV2CiAqIENvcHlyaWdodCAyMDA2IEphc29uIEdyZWVuCiAqIENvcHlyaWdodCAyMDA2IEhlbnJpIFZlcmJlZXQKICogQ29weXJpZ2h0IDIwMDctMjAwOCBTdGVmYW4gRPZzaW5nZXIgZm9yIENvZGVXZWF2ZXJzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKCiNpbmNsdWRlIDxtYXRoLmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKI2luY2x1ZGUgIndpbmVkM2RfcHJpdmF0ZS5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoZDNkX3NoYWRlcik7CldJTkVfREVDTEFSRV9ERUJVR19DSEFOTkVMKGQzZF9jb25zdGFudHMpOwpXSU5FX0RFQ0xBUkVfREVCVUdfQ0hBTk5FTChkM2RfY2Fwcyk7CgojZGVmaW5lIEdMSU5GT19MT0NBVElPTiAgICAgICgqZ2xfaW5mbykKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBUkJfW3ZlcnRleC9mcmFnbWVudF1fcHJvZ3JhbSBoZWxwZXIgZnVuY3Rpb25zIGZvbGxvdwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKiogCiAqIExvYWRzIGZsb2F0aW5nIHBvaW50IGNvbnN0YW50cyBpbnRvIHRoZSBjdXJyZW50bHkgc2V0IEFSQl92ZXJ0ZXgvZnJhZ21lbnRfcHJvZ3JhbS4KICogV2hlbiBjb25zdGFudF9saXN0ID09IE5VTEwsIGl0IHdpbGwgbG9hZCBhbGwgdGhlIGNvbnN0YW50cy4KICogIAogKiBAdGFyZ2V0X3R5cGUgc2hvdWxkIGJlIGVpdGhlciBHTF9WRVJURVhfUFJPR1JBTV9BUkIgKGZvciB2ZXJ0ZXggc2hhZGVycykKICogIG9yIEdMX0ZSQUdNRU5UX1BST0dSQU1fQVJCIChmb3IgcGl4ZWwgc2hhZGVycykKICovCnN0YXRpYyB1bnNpZ25lZCBpbnQgc2hhZGVyX2FyYl9sb2FkX2NvbnN0YW50c0YoSVdpbmVEM0RCYXNlU2hhZGVySW1wbCogVGhpcywgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvLCBHTHVpbnQgdGFyZ2V0X3R5cGUsCiAgICAgICAgdW5zaWduZWQgaW50IG1heF9jb25zdGFudHMsIGZsb2F0KiBjb25zdGFudHMsIGNoYXIgKmRpcnR5X2NvbnN0cykgewogICAgbG9jYWxfY29uc3RhbnQqIGxjb25zdDsKICAgIERXT1JEIGksIGo7CiAgICB1bnNpZ25lZCBpbnQgcmV0OwoKICAgIGlmIChUUkFDRV9PTihkM2Rfc2hhZGVyKSkgewogICAgICAgIGZvcihpID0gMDsgaSA8IG1heF9jb25zdGFudHM7IGkrKykgewogICAgICAgICAgICBpZighZGlydHlfY29uc3RzW2ldKSBjb250aW51ZTsKICAgICAgICAgICAgVFJBQ0VfKGQzZF9jb25zdGFudHMpKCJMb2FkaW5nIGNvbnN0YW50cyAlaTogJWYsICVmLCAlZiwgJWZcbiIsIGksCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0YW50c1tpICogNCArIDBdLCBjb25zdGFudHNbaSAqIDQgKyAxXSwKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RhbnRzW2kgKiA0ICsgMl0sIGNvbnN0YW50c1tpICogNCArIDNdKTsKICAgICAgICB9CiAgICB9CiAgICAvKiBJbiAxLlggcGl4ZWwgc2hhZGVycyBjb25zdGFudHMgYXJlIGltcGxpY2l0bHkgY2xhbXBlZCBpbiB0aGUgcmFuZ2UgWy0xOzFdICovCiAgICBpZih0YXJnZXRfdHlwZSA9PSBHTF9GUkFHTUVOVF9QUk9HUkFNX0FSQiAmJgogICAgICAgV0lORUQzRFNIQURFUl9WRVJTSU9OX01BSk9SKFRoaXMtPmJhc2VTaGFkZXIuaGV4X3ZlcnNpb24pID09IDEpIHsKICAgICAgICBmbG9hdCBsY2xfY29uc3RbNF07CiAgICAgICAgZm9yKGkgPSAwOyBpIDwgbWF4X2NvbnN0YW50czsgaSsrKSB7CiAgICAgICAgICAgIGlmKCFkaXJ0eV9jb25zdHNbaV0pIGNvbnRpbnVlOwogICAgICAgICAgICBkaXJ0eV9jb25zdHNbaV0gPSAwOwoKICAgICAgICAgICAgaiA9IDQgKiBpOwogICAgICAgICAgICBpZihjb25zdGFudHNbaiArIDBdID4gMS4wKSBsY2xfY29uc3RbMF0gPSAxLjA7CiAgICAgICAgICAgIGVsc2UgaWYoY29uc3RhbnRzW2ogKyAwXSA8IC0xLjApIGxjbF9jb25zdFswXSA9IC0xLjA7CiAgICAgICAgICAgIGVsc2UgbGNsX2NvbnN0WzBdID0gY29uc3RhbnRzW2ogKyAwXTsKCiAgICAgICAgICAgIGlmKGNvbnN0YW50c1tqICsgMV0gPiAxLjApIGxjbF9jb25zdFsxXSA9IDEuMDsKICAgICAgICAgICAgZWxzZSBpZihjb25zdGFudHNbaiArIDFdIDwgLTEuMCkgbGNsX2NvbnN0WzFdID0gLTEuMDsKICAgICAgICAgICAgZWxzZSBsY2xfY29uc3RbMV0gPSBjb25zdGFudHNbaiArIDFdOwoKICAgICAgICAgICAgaWYoY29uc3RhbnRzW2ogKyAyXSA+IDEuMCkgbGNsX2NvbnN0WzJdID0gMS4wOwogICAgICAgICAgICBlbHNlIGlmKGNvbnN0YW50c1tqICsgMl0gPCAtMS4wKSBsY2xfY29uc3RbMl0gPSAtMS4wOwogICAgICAgICAgICBlbHNlIGxjbF9jb25zdFsyXSA9IGNvbnN0YW50c1tqICsgMl07CgogICAgICAgICAgICBpZihjb25zdGFudHNbaiArIDNdID4gMS4wKSBsY2xfY29uc3RbM10gPSAxLjA7CiAgICAgICAgICAgIGVsc2UgaWYoY29uc3RhbnRzW2ogKyAzXSA8IC0xLjApIGxjbF9jb25zdFszXSA9IC0xLjA7CiAgICAgICAgICAgIGVsc2UgbGNsX2NvbnN0WzNdID0gY29uc3RhbnRzW2ogKyAzXTsKCiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xQcm9ncmFtRW52UGFyYW1ldGVyNGZ2QVJCKHRhcmdldF90eXBlLCBpLCBsY2xfY29uc3QpKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIGlmKEdMX1NVUFBPUlQoRVhUX0dQVV9QUk9HUkFNX1BBUkFNRVRFUlMpKSB7CiAgICAgICAgICAgIC8qIFRPRE86IEJlbmNobWFyayBpZiB3ZSdyZSBiZXR0ZXIgb2Ygd2l0aCBmaW5kaW5nIHRoZSBkaXJ0eSBjb25zdGFudHMgb3Vyc2VsdmVzLAogICAgICAgICAgICAgKiBvciBqdXN0IHJlbG9hZGluZyAqYWxsKiBjb25zdGFudHMgYXQgb25jZQogICAgICAgICAgICAgKgogICAgICAgICAgICBHTF9FWFRDQUxMKGdsUHJvZ3JhbUVudlBhcmFtZXRlcnM0ZnZFWFQodGFyZ2V0X3R5cGUsIDAsIG1heF9jb25zdGFudHMsIGNvbnN0YW50cykpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDwgbWF4X2NvbnN0YW50czsgaSsrKSB7CiAgICAgICAgICAgICAgICBpZighZGlydHlfY29uc3RzW2ldKSBjb250aW51ZTsKCiAgICAgICAgICAgICAgICAvKiBGaW5kIHRoZSBuZXh0IGJsb2NrIG9mIGRpcnR5IGNvbnN0YW50cyAqLwogICAgICAgICAgICAgICAgZGlydHlfY29uc3RzW2ldID0gMDsKICAgICAgICAgICAgICAgIGogPSBpOwogICAgICAgICAgICAgICAgZm9yKGkrKzsgKGkgPCBtYXhfY29uc3RhbnRzKSAmJiBkaXJ0eV9jb25zdHNbaV07IGkrKykgewogICAgICAgICAgICAgICAgICAgIGRpcnR5X2NvbnN0c1tpXSA9IDA7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFByb2dyYW1FbnZQYXJhbWV0ZXJzNGZ2RVhUKHRhcmdldF90eXBlLCBqLCBpIC0gaiwgY29uc3RhbnRzICsgKGogKiA0KSkpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDwgbWF4X2NvbnN0YW50czsgaSsrKSB7CiAgICAgICAgICAgICAgICBpZihkaXJ0eV9jb25zdHNbaV0pIHsKICAgICAgICAgICAgICAgICAgICBkaXJ0eV9jb25zdHNbaV0gPSAwOwogICAgICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xQcm9ncmFtRW52UGFyYW1ldGVyNGZ2QVJCKHRhcmdldF90eXBlLCBpLCBjb25zdGFudHMgKyAoaSAqIDQpKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBjaGVja0dMY2FsbCgiZ2xQcm9ncmFtRW52UGFyYW1ldGVyNGZ2QVJCKCkiKTsKCiAgICAvKiBMb2FkIGltbWVkaWF0ZSBjb25zdGFudHMgKi8KICAgIGlmKFRoaXMtPmJhc2VTaGFkZXIubG9hZF9sb2NhbF9jb25zdHNGKSB7CiAgICAgICAgaWYgKFRSQUNFX09OKGQzZF9zaGFkZXIpKSB7CiAgICAgICAgICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkobGNvbnN0LCAmVGhpcy0+YmFzZVNoYWRlci5jb25zdGFudHNGLCBsb2NhbF9jb25zdGFudCwgZW50cnkpIHsKICAgICAgICAgICAgICAgIEdMZmxvYXQqIHZhbHVlcyA9IChHTGZsb2F0KilsY29uc3QtPnZhbHVlOwogICAgICAgICAgICAgICAgVFJBQ0VfKGQzZF9jb25zdGFudHMpKCJMb2FkaW5nIGxvY2FsIGNvbnN0YW50cyAlaTogJWYsICVmLCAlZiwgJWZcbiIsIGxjb25zdC0+aWR4LAogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXNbMF0sIHZhbHVlc1sxXSwgdmFsdWVzWzJdLCB2YWx1ZXNbM10pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qIEltbWVkaWF0ZSBjb25zdGFudHMgYXJlIGNsYW1wZWQgZm9yIDEuWCBzaGFkZXJzIGF0IGxvYWRpbmcgdGltZXMgKi8KICAgICAgICByZXQgPSAwOwogICAgICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkobGNvbnN0LCAmVGhpcy0+YmFzZVNoYWRlci5jb25zdGFudHNGLCBsb2NhbF9jb25zdGFudCwgZW50cnkpIHsKICAgICAgICAgICAgZGlydHlfY29uc3RzW2xjb25zdC0+aWR4XSA9IDE7IC8qIERpcnRpZnkgc28gdGhlIG5vbi1pbW1lZGlhdGUgY29uc3RhbnQgb3ZlcndyaXRlcyBpdCBuZXh0IHRpbWUgKi8KICAgICAgICAgICAgcmV0ID0gbWF4KHJldCwgbGNvbnN0LT5pZHggKyAxKTsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFByb2dyYW1FbnZQYXJhbWV0ZXI0ZnZBUkIodGFyZ2V0X3R5cGUsIGxjb25zdC0+aWR4LCAoR0xmbG9hdCopbGNvbnN0LT52YWx1ZSkpOwogICAgICAgIH0KICAgICAgICBjaGVja0dMY2FsbCgiZ2xQcm9ncmFtRW52UGFyYW1ldGVyNGZ2QVJCKCkiKTsKICAgICAgICByZXR1cm4gcmV0OyAvKiBUaGUgbG9hZGVkIGltbWVkaWF0ZSBjb25zdGFudHMgbmVlZCByZWxvYWRpbmcgZm9yIHRoZSBuZXh0IHNoYWRlciAqLwogICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gMDsgLyogTm8gY29uc3RhbnRzIGFyZSBkaXJ0eSBub3cgKi8KICAgIH0KfQoKLyoqCiAqIExvYWRzIHRoZSBhcHAtc3VwcGxpZWQgY29uc3RhbnRzIGludG8gdGhlIGN1cnJlbnRseSBzZXQgQVJCX1t2ZXJ0ZXgvZnJhZ21lbnRdX3Byb2dyYW1zLgogKiAKICogV2Ugb25seSBzdXBwb3J0IGZsb2F0IGNvbnN0YW50cyBpbiBBUkIgYXQgdGhlIG1vbWVudCwgc28gZG9uJ3QgCiAqIHdvcnJ5IGFib3V0IHRoZSBJbnRlZ2VycyBvciBCb29sZWFucwogKi8Kdm9pZCBzaGFkZXJfYXJiX2xvYWRfY29uc3RhbnRzKAogICAgSVdpbmVEM0REZXZpY2UqIGRldmljZSwKICAgIGNoYXIgdXNlUGl4ZWxTaGFkZXIsCiAgICBjaGFyIHVzZVZlcnRleFNoYWRlcikgewogICAKICAgIElXaW5lRDNERGV2aWNlSW1wbCogZGV2aWNlSW1wbCA9IChJV2luZUQzRERldmljZUltcGwqKSBkZXZpY2U7IAogICAgSVdpbmVEM0RTdGF0ZUJsb2NrSW1wbCogc3RhdGVCbG9jayA9IGRldmljZUltcGwtPnN0YXRlQmxvY2s7CiAgICBXaW5lRDNEX0dMX0luZm8gKmdsX2luZm8gPSAmZGV2aWNlSW1wbC0+YWRhcHRlci0+Z2xfaW5mbzsKICAgIHVuc2lnbmVkIGNoYXIgaTsKCiAgICBpZiAodXNlVmVydGV4U2hhZGVyKSB7CiAgICAgICAgSVdpbmVEM0RCYXNlU2hhZGVySW1wbCogdnNoYWRlciA9IChJV2luZUQzREJhc2VTaGFkZXJJbXBsKikgc3RhdGVCbG9jay0+dmVydGV4U2hhZGVyOwoKICAgICAgICAvKiBMb2FkIERpcmVjdFggOSBmbG9hdCBjb25zdGFudHMgZm9yIHZlcnRleCBzaGFkZXIgKi8KICAgICAgICBkZXZpY2VJbXBsLT5oaWdoZXN0X2RpcnR5X3ZzX2NvbnN0ID0gc2hhZGVyX2FyYl9sb2FkX2NvbnN0YW50c0YoCiAgICAgICAgICAgICAgICB2c2hhZGVyLCBnbF9pbmZvLCBHTF9WRVJURVhfUFJPR1JBTV9BUkIsCiAgICAgICAgICAgICAgICBkZXZpY2VJbXBsLT5oaWdoZXN0X2RpcnR5X3ZzX2NvbnN0LAogICAgICAgICAgICAgICAgc3RhdGVCbG9jay0+dmVydGV4U2hhZGVyQ29uc3RhbnRGLAogICAgICAgICAgICAgICAgZGV2aWNlSW1wbC0+YWN0aXZlQ29udGV4dC0+dnNoYWRlcl9jb25zdF9kaXJ0eSk7CgogICAgICAgIC8qIFVwbG9hZCB0aGUgcG9zaXRpb24gZml4dXAgKi8KICAgICAgICBHTF9FWFRDQUxMKGdsUHJvZ3JhbUVudlBhcmFtZXRlcjRmdkFSQihHTF9WRVJURVhfUFJPR1JBTV9BUkIsIEFSQl9TSEFERVJfUFJJVkNPTlNUX1BPUywgZGV2aWNlSW1wbC0+cG9zRml4dXApKTsKICAgIH0KCiAgICBpZiAodXNlUGl4ZWxTaGFkZXIpIHsKCiAgICAgICAgSVdpbmVEM0RCYXNlU2hhZGVySW1wbCogcHNoYWRlciA9IChJV2luZUQzREJhc2VTaGFkZXJJbXBsKikgc3RhdGVCbG9jay0+cGl4ZWxTaGFkZXI7CiAgICAgICAgSVdpbmVEM0RQaXhlbFNoYWRlckltcGwgKnBzaSA9IChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqKSBwc2hhZGVyOwoKICAgICAgICAvKiBMb2FkIERpcmVjdFggOSBmbG9hdCBjb25zdGFudHMgZm9yIHBpeGVsIHNoYWRlciAqLwogICAgICAgIGRldmljZUltcGwtPmhpZ2hlc3RfZGlydHlfcHNfY29uc3QgPSBzaGFkZXJfYXJiX2xvYWRfY29uc3RhbnRzRigKICAgICAgICAgICAgICAgIHBzaGFkZXIsIGdsX2luZm8sIEdMX0ZSQUdNRU5UX1BST0dSQU1fQVJCLAogICAgICAgICAgICAgICAgZGV2aWNlSW1wbC0+aGlnaGVzdF9kaXJ0eV9wc19jb25zdCwKICAgICAgICAgICAgICAgIHN0YXRlQmxvY2stPnBpeGVsU2hhZGVyQ29uc3RhbnRGLAogICAgICAgICAgICAgICAgZGV2aWNlSW1wbC0+YWN0aXZlQ29udGV4dC0+cHNoYWRlcl9jb25zdF9kaXJ0eSk7CgogICAgICAgIGZvcihpID0gMDsgaSA8IHBzaS0+bnVtYnVtcGVudm1hdGNvbnN0czsgaSsrKSB7CiAgICAgICAgICAgIC8qIFRoZSBzdGF0ZSBtYW5hZ2VyIHRha2VzIGNhcmUgdGhhdCB0aGlzIGZ1bmN0aW9uIGlzIGFsd2F5cyBjYWxsZWQgaWYgdGhlIGJ1bXAgZW52IG1hdHJpeCBjaGFuZ2VzCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBmbG9hdCAqZGF0YSA9IChmbG9hdCAqKSAmc3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlWyhpbnQpIHBzaS0+YnVtcGVudm1hdGNvbnN0W2ldLnRleHVuaXRdW1dJTkVEM0RUU1NfQlVNUEVOVk1BVDAwXTsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFByb2dyYW1FbnZQYXJhbWV0ZXI0ZnZBUkIoR0xfRlJBR01FTlRfUFJPR1JBTV9BUkIsIHBzaS0+YnVtcGVudm1hdGNvbnN0W2ldLmNvbnN0X251bSwgZGF0YSkpOwogICAgICAgICAgICBkZXZpY2VJbXBsLT5hY3RpdmVDb250ZXh0LT5wc2hhZGVyX2NvbnN0X2RpcnR5W3BzaS0+YnVtcGVudm1hdGNvbnN0W2ldLmNvbnN0X251bV0gPSAxOwoKICAgICAgICAgICAgaWYocHNpLT5sdW1pbmFuY2Vjb25zdFtpXS5jb25zdF9udW0gIT0gLTEpIHsKICAgICAgICAgICAgICAgIC8qIFdJTkVEM0RUU1NfQlVNUEVOVkxTQ0FMRSBhbmQgV0lORUQzRFRTU19CVU1QRU5WTE9GRlNFVCBhcmUgbmV4dCB0byBlYWNoIG90aGVyLgogICAgICAgICAgICAgICAgICogcG9pbnQgZ2wgdG8gdGhlIHNjYWxlLCBhbmQgbG9hZCA0IGZsb2F0cy4geCA9IHNjYWxlLCB5ID0gb2Zmc2V0LCB6IGFuZCB3IGFyZSBqdW5rLCB3ZQogICAgICAgICAgICAgICAgICogZG9uJ3QgY2FyZSBhYm91dCB0aGVtLiBUaGUgcG9pbnRlcnMgYXJlIHZhbGlkIGZvciBzdXJlIGJlY2F1c2UgdGhlIHN0YXRlYmxvY2sgaXMgYmlnZ2VyLgogICAgICAgICAgICAgICAgICogKHRoZXkncmUgV0lORUQzRFRTU19URVhUVVJFVFJBTlNGT1JNRkxBR1MgYW5kIFdJTkVEM0RUU1NfQUREUkVTU1csIHNvIG1vc3QgbGlrZWx5IDAgb3IgTmFOCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGZsb2F0ICpzY2FsZSA9IChmbG9hdCAqKSAmc3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlWyhpbnQpIHBzaS0+bHVtaW5hbmNlY29uc3RbaV0udGV4dW5pdF1bV0lORUQzRFRTU19CVU1QRU5WTFNDQUxFXTsKICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xQcm9ncmFtRW52UGFyYW1ldGVyNGZ2QVJCKEdMX0ZSQUdNRU5UX1BST0dSQU1fQVJCLCBwc2ktPmx1bWluYW5jZWNvbnN0W2ldLmNvbnN0X251bSwgc2NhbGUpKTsKICAgICAgICAgICAgICAgIGRldmljZUltcGwtPmFjdGl2ZUNvbnRleHQtPnBzaGFkZXJfY29uc3RfZGlydHlbcHNpLT5sdW1pbmFuY2Vjb25zdFtpXS5jb25zdF9udW1dID0gMTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYoKChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqKSBwc2hhZGVyKS0+c3JnYl9lbmFibGVkICYmCiAgICAgICAgICAgISgoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwgKikgcHNoYWRlciktPnNyZ2JfbW9kZV9oYXJkY29kZWQpIHsKICAgICAgICAgICAgZmxvYXQgY29tcGFyaXNvbls0XTsKICAgICAgICAgICAgZmxvYXQgbXVsX2xvd1s0XTsKCiAgICAgICAgICAgIGlmKHN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19TUkdCV1JJVEVFTkFCTEVdKSB7CiAgICAgICAgICAgICAgICBjb21wYXJpc29uWzBdID0gc3JnYl9jbXA7IGNvbXBhcmlzb25bMV0gPSBzcmdiX2NtcDsKICAgICAgICAgICAgICAgIGNvbXBhcmlzb25bMl0gPSBzcmdiX2NtcDsgY29tcGFyaXNvblszXSA9IHNyZ2JfY21wOwoKICAgICAgICAgICAgICAgIG11bF9sb3dbMF0gPSBzcmdiX211bF9sb3c7IG11bF9sb3dbMV0gPSBzcmdiX211bF9sb3c7CiAgICAgICAgICAgICAgICBtdWxfbG93WzJdID0gc3JnYl9tdWxfbG93OyBtdWxfbG93WzNdID0gc3JnYl9tdWxfbG93OwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgY29tcGFyaXNvblswXSA9IDEuMCAvIDAuMDsgY29tcGFyaXNvblsxXSA9IDEuMCAvIDAuMDsKICAgICAgICAgICAgICAgIGNvbXBhcmlzb25bMl0gPSAxLjAgLyAwLjA7IGNvbXBhcmlzb25bM10gPSAxLjAgLyAwLjA7CgogICAgICAgICAgICAgICAgbXVsX2xvd1swXSA9IDEuMDsgbXVsX2xvd1sxXSA9IDEuMDsKICAgICAgICAgICAgICAgIG11bF9sb3dbMl0gPSAxLjA7IG11bF9sb3dbM10gPSAxLjA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFByb2dyYW1FbnZQYXJhbWV0ZXI0ZnZBUkIoR0xfRlJBR01FTlRfUFJPR1JBTV9BUkIsIHBzaS0+c3JnYl9jbXBfY29uc3QsIGNvbXBhcmlzb24pKTsKICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFByb2dyYW1FbnZQYXJhbWV0ZXI0ZnZBUkIoR0xfRlJBR01FTlRfUFJPR1JBTV9BUkIsIHBzaS0+c3JnYl9sb3dfY29uc3QsIG11bF9sb3cpKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoIkxvYWQgc1JHQiBjb3JyZWN0aW9uIGNvbnN0YW50c1xuIik7CiAgICAgICAgICAgIGRldmljZUltcGwtPmFjdGl2ZUNvbnRleHQtPnBzaGFkZXJfY29uc3RfZGlydHlbcHNpLT5zcmdiX2xvd19jb25zdF0gPSAxOwogICAgICAgICAgICBkZXZpY2VJbXBsLT5hY3RpdmVDb250ZXh0LT5wc2hhZGVyX2NvbnN0X2RpcnR5W3BzaS0+c3JnYl9jbXBfY29uc3RdID0gMTsKCiAgICAgICAgfQogICAgfQp9CgovKiBHZW5lcmF0ZSB0aGUgdmFyaWFibGUgJiByZWdpc3RlciBkZWNsYXJhdGlvbnMgZm9yIHRoZSBBUkJfdmVydGV4X3Byb2dyYW0gb3V0cHV0IHRhcmdldCAqLwp2b2lkIHNoYWRlcl9nZW5lcmF0ZV9hcmJfZGVjbGFyYXRpb25zKAogICAgSVdpbmVEM0RCYXNlU2hhZGVyICppZmFjZSwKICAgIHNoYWRlcl9yZWdfbWFwcyogcmVnX21hcHMsCiAgICBTSEFERVJfQlVGRkVSKiBidWZmZXIsCiAgICBXaW5lRDNEX0dMX0luZm8qIGdsX2luZm8pIHsKCiAgICBJV2luZUQzREJhc2VTaGFkZXJJbXBsKiBUaGlzID0gKElXaW5lRDNEQmFzZVNoYWRlckltcGwqKSBpZmFjZTsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqZGV2aWNlID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBUaGlzLT5iYXNlU2hhZGVyLmRldmljZTsKICAgIERXT1JEIGksIGN1cjsKICAgIGNoYXIgcHNoYWRlciA9IHNoYWRlcl9pc19wc2hhZGVyX3ZlcnNpb24oVGhpcy0+YmFzZVNoYWRlci5oZXhfdmVyc2lvbik7CiAgICB1bnNpZ25lZCBtYXhfY29uc3RhbnRzRiA9IG1pbihUaGlzLT5iYXNlU2hhZGVyLmxpbWl0cy5jb25zdGFudF9mbG9hdCwgCiAgICAgICAgICAgIChwc2hhZGVyID8gR0xfTElNSVRTKHBzaGFkZXJfY29uc3RhbnRzRikgOiBHTF9MSU1JVFModnNoYWRlcl9jb25zdGFudHNGKSkpOwogICAgVUlOVCBleHRyYV9jb25zdGFudHNfbmVlZGVkID0gMDsKICAgIGxvY2FsX2NvbnN0YW50KiBsY29uc3Q7CgogICAgLyogVGVtcG9yYXJ5IE91dHB1dCByZWdpc3RlciAqLwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiVEVNUCBUTVBfT1VUO1xuIik7CgogICAgZm9yKGkgPSAwOyBpIDwgVGhpcy0+YmFzZVNoYWRlci5saW1pdHMudGVtcG9yYXJ5OyBpKyspIHsKICAgICAgICBpZiAocmVnX21hcHMtPnRlbXBvcmFyeVtpXSkKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiVEVNUCBSJXU7XG4iLCBpKTsKICAgIH0KCiAgICBmb3IgKGkgPSAwOyBpIDwgVGhpcy0+YmFzZVNoYWRlci5saW1pdHMuYWRkcmVzczsgaSsrKSB7CiAgICAgICAgaWYgKHJlZ19tYXBzLT5hZGRyZXNzW2ldKQogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJBRERSRVNTIEElZDtcbiIsIGkpOwogICAgfQoKICAgIGZvcihpID0gMDsgaSA8IFRoaXMtPmJhc2VTaGFkZXIubGltaXRzLnRleGNvb3JkOyBpKyspIHsKICAgICAgICBpZiAocmVnX21hcHMtPnRleGNvb3JkW2ldKQogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsIlRFTVAgVCV1O1xuIiwgaSk7CiAgICB9CgogICAgLyogVGV4dHVyZSBjb29yZGluYXRlIHJlZ2lzdGVycyBtdXN0IGJlIHByZS1sb2FkZWQgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5iYXNlU2hhZGVyLmxpbWl0cy50ZXhjb29yZDsgaSsrKSB7CiAgICAgICAgaWYgKHJlZ19tYXBzLT50ZXhjb29yZFtpXSkKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTU9WIFQldSwgZnJhZ21lbnQudGV4Y29vcmRbJXVdO1xuIiwgaSwgaSk7CiAgICB9CgogICAgZm9yKGkgPSAwOyBpIDwgKHNpemVvZihyZWdfbWFwcy0+YnVtcG1hdCkgLyBzaXplb2YocmVnX21hcHMtPmJ1bXBtYXRbMF0pKTsgaSsrKSB7CiAgICAgICAgSVdpbmVEM0RQaXhlbFNoYWRlckltcGwgKnBzID0gKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICopIFRoaXM7CiAgICAgICAgaWYoIXJlZ19tYXBzLT5idW1wbWF0W2ldKSBjb250aW51ZTsKCiAgICAgICAgY3VyID0gcHMtPm51bWJ1bXBlbnZtYXRjb25zdHM7CiAgICAgICAgcHMtPmJ1bXBlbnZtYXRjb25zdFtjdXJdLmNvbnN0X251bSA9IC0xOwogICAgICAgIHBzLT5idW1wZW52bWF0Y29uc3RbY3VyXS50ZXh1bml0ID0gaTsKICAgICAgICBwcy0+bHVtaW5hbmNlY29uc3RbY3VyXS5jb25zdF9udW0gPSAtMTsKICAgICAgICBwcy0+bHVtaW5hbmNlY29uc3RbY3VyXS50ZXh1bml0ID0gaTsKCiAgICAgICAgLyogSWYgdGhlIHNoYWRlciBkb2VzIG5vdCB1c2UgYWxsIGF2YWlsYWJsZSBjb25zdGFudHMsIHVzZSB0aGUgbmV4dCBmcmVlIGNvbnN0YW50IHRvIGxvYWQgdGhlIGJ1bXAgbWFwcGluZyBlbnZpcm9ubWVudCBtYXRyaXggZnJvbQogICAgICAgICAqIHRoZSBzdGF0ZWJsb2NrIGludG8gdGhlIHNoYWRlci4gSWYgbm8gY29uc3RhbnQgaXMgYXZhaWxhYmxlIGRvbid0IGxvYWQsIHRleGJlbSB3aWxsIHRoZW4ganVzdCBzYW1wbGUgdGhlIHRleHR1cmUgd2l0aG91dCBhcHBseWluZwogICAgICAgICAqIGJ1bXAgbWFwcGluZy4KICAgICAgICAgKi8KICAgICAgICBpZihtYXhfY29uc3RhbnRzRiArIGV4dHJhX2NvbnN0YW50c19uZWVkZWQgPCBHTF9MSU1JVFMocHNoYWRlcl9jb25zdGFudHNGKSkgewogICAgICAgICAgICBwcy0+YnVtcGVudm1hdGNvbnN0W2N1cl0uY29uc3RfbnVtID0gbWF4X2NvbnN0YW50c0YgKyBleHRyYV9jb25zdGFudHNfbmVlZGVkOwogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJQQVJBTSBidW1wZW52bWF0JWQgPSBwcm9ncmFtLmVudlslZF07XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICBpLCBwcy0+YnVtcGVudm1hdGNvbnN0W2N1cl0uY29uc3RfbnVtKTsKICAgICAgICAgICAgZXh0cmFfY29uc3RhbnRzX25lZWRlZCsrOwoKICAgICAgICAgICAgaWYocmVnX21hcHMtPmx1bWluYW5jZXBhcmFtcyAmJiBtYXhfY29uc3RhbnRzRiArIGV4dHJhX2NvbnN0YW50c19uZWVkZWQgPCBHTF9MSU1JVFMocHNoYWRlcl9jb25zdGFudHNGKSkgewogICAgICAgICAgICAgICAgKChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqKVRoaXMpLT5sdW1pbmFuY2Vjb25zdFtjdXJdLmNvbnN0X251bSA9IG1heF9jb25zdGFudHNGICsgZXh0cmFfY29uc3RhbnRzX25lZWRlZDsKICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlBBUkFNIGx1bWluYW5jZSVkID0gcHJvZ3JhbS5lbnZbJWRdO1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGksIHBzLT5sdW1pbmFuY2Vjb25zdFtjdXJdLmNvbnN0X251bSk7CiAgICAgICAgICAgICAgICBleHRyYV9jb25zdGFudHNfbmVlZGVkKys7CiAgICAgICAgICAgIH0gZWxzZSBpZihyZWdfbWFwcy0+bHVtaW5hbmNlcGFyYW1zKSB7CiAgICAgICAgICAgICAgICBGSVhNRSgiTm8gZnJlZSBjb25zdGFudCB0byBsb2FkIHRoZSBsdW1pbmFuY2UgcGFyYW1ldGVyc1xuIik7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBGSVhNRSgiTm8gZnJlZSBjb25zdGFudCBmb3VuZCB0byBsb2FkIGVudmlyb25lbW50IGJ1bXAgbWFwcGluZyBtYXRyaXggaW50byB0aGUgc2hhZGVyLiB0ZXhiZW0gaW5zdHJ1Y3Rpb24gd2lsbCBub3QgYXBwbHkgYnVtcCBtYXBwaW5nXG4iKTsKICAgICAgICB9CgogICAgICAgIHBzLT5udW1idW1wZW52bWF0Y29uc3RzID0gY3VyICsgMTsKICAgIH0KCiAgICBpZihkZXZpY2UtPnN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19TUkdCV1JJVEVFTkFCTEVdICYmIHBzaGFkZXIpIHsKICAgICAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqcHNfaW1wbCA9IChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqKSBUaGlzOwogICAgICAgIC8qIElmIHRoZXJlIGFyZSAyIGNvbnN0YW50cyBsZWZ0IHRvIHVzZSwgdXNlIHRoZW0gdG8gcGFzcyB0aGUgc1JHQiBjb3JyZWN0aW9uIHZhbHVlcyBpbi4gVGhpcyB3YXkKICAgICAgICAgKiBzcmdiIHdyaXRlIGNvcnJlY3Rpb24gY2FuIGJlIHR1cm5lZCBvbiBhbmQgb2ZmIGR5bmFtaWNhbGx5IHdpdGhvdXQgcmVjb21waWxhdGlvbi4gT3RoZXJ3aXNlCiAgICAgICAgICogaGFyZGNvZGUgdGhlbS4gVGhlIGRyYXdiYWNrIG9mIGhhcmRjb2RpbmcgaXMgdGhhdCB0aGUgc2hhZGVyIG5lZWRzIHJlY29tcGlsYXRpb24gdG8gdHVybiBzUkdCCiAgICAgICAgICogb2ZmIGFnYWluCiAgICAgICAgICovCiAgICAgICAgaWYobWF4X2NvbnN0YW50c0YgKyBleHRyYV9jb25zdGFudHNfbmVlZGVkICsgMSA8IEdMX0xJTUlUUyhwc2hhZGVyX2NvbnN0YW50c0YpICYmIEZBTFNFKSB7CiAgICAgICAgICAgIC8qIFRoZSBpZGVhIGlzIHRoYXQgaWYgc3JnYiBpcyBlbmFibGVkLCB0aGVuIGRpc2FibGVkLCB0aGUgY29uc3RhbnQgbG9hZGluZyBjb2RlCiAgICAgICAgICAgICAqIGNhbiBlZmZlY3RpdmVseSBkaXNhYmxlIHNSR0IgY29ycmVjdGlvbiBieSBwYXNzaW5nIDEuMCBhbmQgSU5GIGFzIHRoZSBtdWx0aXBsaWNhdGlvbgogICAgICAgICAgICAgKiBhbmQgY29tcGFyaXNvbiBjb25zdGFudHMuIElmIGl0IGRpc2FibGVzIGl0IHRoYXQgd2F5LCB0aGUgc2hhZGVyIHdvbid0IGJlIHJlY29tcGlsZWQKICAgICAgICAgICAgICogYW5kIHRoZSBjb2RlIHdpbGwgc3RheSBpbiwgc28gc1JHQiB3cml0aW5nIGNhbiBiZSB0dXJuZWQgb24gYWdhaW4gYnkgc2V0dGluZyB0aGUKICAgICAgICAgICAgICogY29uc3RhbnRzIGZyb20gdGhlIHNwZWMKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHBzX2ltcGwtPnNyZ2JfbW9kZV9oYXJkY29kZWQgPSAwOwogICAgICAgICAgICBwc19pbXBsLT5zcmdiX2xvd19jb25zdCA9IEdMX0xJTUlUUyhwc2hhZGVyX2NvbnN0YW50c0YpIC0gZXh0cmFfY29uc3RhbnRzX25lZWRlZDsKICAgICAgICAgICAgcHNfaW1wbC0+c3JnYl9jbXBfY29uc3QgPSBHTF9MSU1JVFMocHNoYWRlcl9jb25zdGFudHNGKSAtIGV4dHJhX2NvbnN0YW50c19uZWVkZWQgLSAxOwogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJQQVJBTSBzcmdiX211bF9sb3cgPSBwcm9ncmFtLmVudlslZF07XG4iLCBwc19pbXBsLT5zcmdiX2xvd19jb25zdCk7CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlBBUkFNIHNyZ2JfY29tcGFyaXNvbiA9IHByb2dyYW0uZW52WyVkXTtcbiIsIHBzX2ltcGwtPnNyZ2JfY21wX2NvbnN0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJQQVJBTSBzcmdiX211bF9sb3cgPSB7JWYsICVmLCAlZiwgMS4wfTtcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyZ2JfbXVsX2xvdywgc3JnYl9tdWxfbG93LCBzcmdiX211bF9sb3cpOwogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJQQVJBTSBzcmdiX2NvbXBhcmlzb24gPSAgeyVmLCAlZiwgJWYsICVmfTtcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyZ2JfY21wLCBzcmdiX2NtcCwgc3JnYl9jbXAsIHNyZ2JfY21wKTsKICAgICAgICAgICAgcHNfaW1wbC0+c3JnYl9tb2RlX2hhcmRjb2RlZCA9IDE7CiAgICAgICAgfQogICAgICAgIC8qIFRoZXNlIGNhbiBiZSBoYXJkY29kZWQsIHRoZXkgZG8gbm90IGNhdXNlIGFueSBoYXJtIGJlY2F1c2Ugbm8gZnJhZ21lbnQgd2lsbCBlbnRlciB0aGUgaGlnaAogICAgICAgICAqIHBhdGggaWYgdGhlIGNvbXBhcmlzb24gdmFsdWUgaXMgc2V0IHRvIElORgogICAgICAgICAqLwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlBBUkFNIHNyZ2JfcG93ID0gIHslZiwgJWYsICVmLCAxLjB9O1xuIiwKICAgICAgICAgICAgICAgICAgICAgICBzcmdiX3Bvdywgc3JnYl9wb3csIHNyZ2JfcG93KTsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJQQVJBTSBzcmdiX211bF9oaSA9ICB7JWYsICVmLCAlZiwgMS4wfTtcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgc3JnYl9tdWxfaGlnaCwgc3JnYl9tdWxfaGlnaCwgc3JnYl9tdWxfaGlnaCk7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiUEFSQU0gc3JnYl9zdWJfaGkgPSAgeyVmLCAlZiwgJWYsIDAuMH07XG4iLAogICAgICAgICAgICAgICAgICAgICAgIHNyZ2Jfc3ViX2hpZ2gsIHNyZ2Jfc3ViX2hpZ2gsIHNyZ2Jfc3ViX2hpZ2gpOwogICAgICAgIHBzX2ltcGwtPnNyZ2JfZW5hYmxlZCA9IDE7CiAgICB9IGVsc2UgaWYocHNoYWRlcikgewogICAgICAgIElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICpwc19pbXBsID0gKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICopIFRoaXM7CgogICAgICAgIC8qIERvIG5vdCB3cml0ZSBhbnkgc3JnYiBmaXh1cCBpbnRvIHRoZSBzaGFkZXIgdG8gc2F2ZSBzaGFkZXIgc2l6ZSBhbmQgcHJvY2Vzc2luZyB0aW1lLgogICAgICAgICAqIEFzIGEgY29uc2VxdWVuY2UsIHdlIGNhbid0IHRvZ2dsZSBzcmdiIHdyaXRlIG9uIHdpdGhvdXQgcmVjb21waWxhdGlvbgogICAgICAgICAqLwogICAgICAgIHBzX2ltcGwtPnNyZ2JfZW5hYmxlZCA9IDA7CiAgICAgICAgcHNfaW1wbC0+c3JnYl9tb2RlX2hhcmRjb2RlZCA9IDE7CiAgICB9CgogICAgLyogTG9hZCBsb2NhbCBjb25zdGFudHMgdXNpbmcgdGhlIHByb2dyYW0tbG9jYWwgc3BhY2UsCiAgICAgKiB0aGlzIGF2b2lkcyByZWxvYWRpbmcgdGhlbSBlYWNoIHRpbWUgdGhlIHNoYWRlciBpcyB1c2VkCiAgICAgKi8KICAgIGlmKCFUaGlzLT5iYXNlU2hhZGVyLmxvYWRfbG9jYWxfY29uc3RzRikgewogICAgICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkobGNvbnN0LCAmVGhpcy0+YmFzZVNoYWRlci5jb25zdGFudHNGLCBsb2NhbF9jb25zdGFudCwgZW50cnkpIHsKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiUEFSQU0gQyV1ID0gcHJvZ3JhbS5sb2NhbFsldV07XG4iLCBsY29uc3QtPmlkeCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgbGNvbnN0LT5pZHgpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiB3ZSB1c2UgdGhlIGFycmF5LWJhc2VkIGNvbnN0YW50cyBhcnJheSBpZiB0aGUgbG9jYWwgY29uc3RhbnRzIGFyZSBtYXJrZWQgZm9yIGxvYWRpbmcsCiAgICAgKiBiZWNhdXNlIHRoZW4gd2UgdXNlIGluZGlyZWN0IGFkZHJlc3NpbmcsIG9yIHdoZW4gdGhlIGxvY2FsIGNvbnN0YW50IGxpc3QgaXMgZW1wdHksCiAgICAgKiBiZWNhdXNlIHRoZW4gd2UgZG9uJ3Qga25vdyBpZiB3ZSdyZSB1c2luZyBpbmRpcmVjdCBhZGRyZXNzaW5nIG9yIG5vdC4gSWYgd2UncmUgaGFyZGNvZGluZwogICAgICogbG9jYWwgY29uc3RhbnRzIGRvIG5vdCBkZWNsYXJlIHRoZSBsb2FkZWQgY29uc3RhbnRzIGFzIGFuIGFycmF5IGJlY2F1c2UgQVJCIGNvbXBpbGVycyB1c3VhbGx5CiAgICAgKiBkbyBub3Qgb3B0aW1pemUgdW51c2VkIGNvbnN0YW50cyBhd2F5CiAgICAgKi8KICAgIGlmKFRoaXMtPmJhc2VTaGFkZXIubG9hZF9sb2NhbF9jb25zdHNGIHx8IGxpc3RfZW1wdHkoJlRoaXMtPmJhc2VTaGFkZXIuY29uc3RhbnRzRikpIHsKICAgICAgICAvKiBOZWVkIHRvIFBBUkFNIHRoZSBlbnZpcm9ubWVudCBwYXJhbWV0ZXJzIChjb25zdGFudHMpIHNvIHdlIGNhbiB1c2UgcmVsYXRpdmUgYWRkcmVzc2luZyAqLwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlBBUkFNIENbJWRdID0geyBwcm9ncmFtLmVudlswLi4lZF0gfTtcbiIsCiAgICAgICAgICAgICAgICAgICAgbWF4X2NvbnN0YW50c0YsIG1heF9jb25zdGFudHNGIC0gMSk7CiAgICB9IGVsc2UgewogICAgICAgIGZvcihpID0gMDsgaSA8IG1heF9jb25zdGFudHNGOyBpKyspIHsKICAgICAgICAgICAgaWYoIXNoYWRlcl9jb25zdGFudF9pc19sb2NhbChUaGlzLCBpKSkgewogICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiUEFSQU0gQyVkID0gcHJvZ3JhbS5lbnZbJWRdO1xuIixpLCBpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQoKc3RhdGljIGNvbnN0IGNoYXIgKiBjb25zdCBzaGlmdF90YWJbXSA9IHsKICAgICJkdW1teSIsICAgICAvKiAgMCAobm9uZSkgKi8KICAgICJjb2VmbXVsLngiLCAvKiAgMSAoeDIpICAgKi8KICAgICJjb2VmbXVsLnkiLCAvKiAgMiAoeDQpICAgKi8KICAgICJjb2VmbXVsLnoiLCAvKiAgMyAoeDgpICAgKi8KICAgICJjb2VmbXVsLnciLCAvKiAgNCAoeDE2KSAgKi8KICAgICJkdW1teSIsICAgICAvKiAgNSAoeDMyKSAgKi8KICAgICJkdW1teSIsICAgICAvKiAgNiAoeDY0KSAgKi8KICAgICJkdW1teSIsICAgICAvKiAgNyAoeDEyOCkgKi8KICAgICJkdW1teSIsICAgICAvKiAgOCAoZDI1NikgKi8KICAgICJkdW1teSIsICAgICAvKiAgOSAoZDEyOCkgKi8KICAgICJkdW1teSIsICAgICAvKiAxMCAoZDY0KSAgKi8KICAgICJkdW1teSIsICAgICAvKiAxMSAoZDMyKSAgKi8KICAgICJjb2VmZGl2LnciLCAvKiAxMiAoZDE2KSAgKi8KICAgICJjb2VmZGl2LnoiLCAvKiAxMyAoZDgpICAgKi8KICAgICJjb2VmZGl2LnkiLCAvKiAxNCAoZDQpICAgKi8KICAgICJjb2VmZGl2LngiICAvKiAxNSAoZDIpICAgKi8KfTsKCnN0YXRpYyB2b2lkIHNoYWRlcl9hcmJfZ2V0X3dyaXRlX21hc2soU0hBREVSX09QQ09ERV9BUkcqIGFyZywgY29uc3QgRFdPUkQgcGFyYW0sIGNoYXIgKndyaXRlX21hc2spIHsKICAgIElXaW5lRDNEQmFzZVNoYWRlckltcGwgKlRoaXMgPSAoSVdpbmVEM0RCYXNlU2hhZGVySW1wbCAqKSBhcmctPnNoYWRlcjsKICAgIGNoYXIgKnB0ciA9IHdyaXRlX21hc2s7CiAgICBjaGFyIHZzaGFkZXIgPSBzaGFkZXJfaXNfdnNoYWRlcl92ZXJzaW9uKFRoaXMtPmJhc2VTaGFkZXIuaGV4X3ZlcnNpb24pOwoKICAgIGlmKHZzaGFkZXIgJiYgc2hhZGVyX2dldF9yZWd0eXBlKHBhcmFtKSA9PSBXSU5FRDNEU1BSX0FERFIpIHsKICAgICAgICAqcHRyKysgPSAnLic7CiAgICAgICAgKnB0cisrID0gJ3gnOwogICAgfSBlbHNlIGlmICgocGFyYW0gJiBXSU5FRDNEU1BfV1JJVEVNQVNLX0FMTCkgIT0gV0lORUQzRFNQX1dSSVRFTUFTS19BTEwpIHsKICAgICAgICAqcHRyKysgPSAnLic7CiAgICAgICAgaWYgKHBhcmFtICYgV0lORUQzRFNQX1dSSVRFTUFTS18wKSAqcHRyKysgPSAneCc7CiAgICAgICAgaWYgKHBhcmFtICYgV0lORUQzRFNQX1dSSVRFTUFTS18xKSAqcHRyKysgPSAneSc7CiAgICAgICAgaWYgKHBhcmFtICYgV0lORUQzRFNQX1dSSVRFTUFTS18yKSAqcHRyKysgPSAneic7CiAgICAgICAgaWYgKHBhcmFtICYgV0lORUQzRFNQX1dSSVRFTUFTS18zKSAqcHRyKysgPSAndyc7CiAgICB9CgogICAgKnB0ciA9ICdcMCc7Cn0KCnN0YXRpYyB2b2lkIHNoYWRlcl9hcmJfZ2V0X3N3aXp6bGUoY29uc3QgRFdPUkQgcGFyYW0sIEJPT0wgZml4dXAsIGNoYXIgKnN3aXp6bGVfc3RyKSB7CiAgICAvKiBGb3IgcmVnaXN0ZXJzIG9mIHR5cGUgV0lORUQzRERFQ0xUWVBFX0QzRENPTE9SLCBkYXRhIGlzIHN0b3JlZCBhcyAiYmdyYSIsCiAgICAgKiBidXQgYWRkcmVzc2VkIGFzICJyZ2JhIi4gVG8gZml4IHRoaXMgd2UgbmVlZCB0byBzd2FwIHRoZSByZWdpc3RlcidzIHgKICAgICAqIGFuZCB6IGNvbXBvbmVudHMuICovCiAgICBjb25zdCBjaGFyICpzd2l6emxlX2NoYXJzID0gZml4dXAgPyAienl4dyIgOiAieHl6dyI7CiAgICBjaGFyICpwdHIgPSBzd2l6emxlX3N0cjsKCiAgICAvKiBzd2l6emxlIGJpdHMgZmllbGRzOiB3d3p6eXl4eCAqLwogICAgRFdPUkQgc3dpenpsZSA9IChwYXJhbSAmIFdJTkVEM0RTUF9TV0laWkxFX01BU0spID4+IFdJTkVEM0RTUF9TV0laWkxFX1NISUZUOwogICAgRFdPUkQgc3dpenpsZV94ID0gc3dpenpsZSAmIDB4MDM7CiAgICBEV09SRCBzd2l6emxlX3kgPSAoc3dpenpsZSA+PiAyKSAmIDB4MDM7CiAgICBEV09SRCBzd2l6emxlX3ogPSAoc3dpenpsZSA+PiA0KSAmIDB4MDM7CiAgICBEV09SRCBzd2l6emxlX3cgPSAoc3dpenpsZSA+PiA2KSAmIDB4MDM7CgogICAgLyogSWYgdGhlIHN3aXp6bGUgaXMgdGhlIGRlZmF1bHQgc3dpenpsZSAoaWUsICJ4eXp3IiksIHdlIGRvbid0IG5lZWQgdG8KICAgICAqIGdlbmVyYXRlIGEgc3dpenpsZSBzdHJpbmcuIFVubGVzcyB3ZSBuZWVkIHRvIG91ciBvd24gc3dpenpsaW5nLiAqLwogICAgaWYgKChXSU5FRDNEU1BfTk9TV0laWkxFID4+IFdJTkVEM0RTUF9TV0laWkxFX1NISUZUKSAhPSBzd2l6emxlIHx8IGZpeHVwKSB7CiAgICAgICAgKnB0cisrID0gJy4nOwogICAgICAgIGlmIChzd2l6emxlX3ggPT0gc3dpenpsZV95ICYmIHN3aXp6bGVfeCA9PSBzd2l6emxlX3ogJiYgc3dpenpsZV94ID09IHN3aXp6bGVfdykgewogICAgICAgICAgICAqcHRyKysgPSBzd2l6emxlX2NoYXJzW3N3aXp6bGVfeF07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgKnB0cisrID0gc3dpenpsZV9jaGFyc1tzd2l6emxlX3hdOwogICAgICAgICAgICAqcHRyKysgPSBzd2l6emxlX2NoYXJzW3N3aXp6bGVfeV07CiAgICAgICAgICAgICpwdHIrKyA9IHN3aXp6bGVfY2hhcnNbc3dpenpsZV96XTsKICAgICAgICAgICAgKnB0cisrID0gc3dpenpsZV9jaGFyc1tzd2l6emxlX3ddOwogICAgICAgIH0KICAgIH0KCiAgICAqcHRyID0gJ1wwJzsKfQoKc3RhdGljIHZvaWQgcHNoYWRlcl9nZXRfcmVnaXN0ZXJfbmFtZShJV2luZUQzREJhc2VTaGFkZXIqIGlmYWNlLAogICAgY29uc3QgRFdPUkQgcGFyYW0sIGNoYXIqIHJlZ3N0cikgewoKICAgIERXT1JEIHJlZyA9IHBhcmFtICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgRFdPUkQgcmVndHlwZSA9IHNoYWRlcl9nZXRfcmVndHlwZShwYXJhbSk7CiAgICBJV2luZUQzREJhc2VTaGFkZXJJbXBsICpUaGlzID0gKElXaW5lRDNEQmFzZVNoYWRlckltcGwgKikgaWZhY2U7CgogICAgc3dpdGNoIChyZWd0eXBlKSB7CiAgICBjYXNlIFdJTkVEM0RTUFJfVEVNUDoKICAgICAgICBzcHJpbnRmKHJlZ3N0ciwgIlIldSIsIHJlZyk7CiAgICBicmVhazsKICAgIGNhc2UgV0lORUQzRFNQUl9JTlBVVDoKICAgICAgICBpZiAocmVnPT0wKSB7CiAgICAgICAgICAgIHN0cmNweShyZWdzdHIsICJmcmFnbWVudC5jb2xvci5wcmltYXJ5Iik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3RyY3B5KHJlZ3N0ciwgImZyYWdtZW50LmNvbG9yLnNlY29uZGFyeSIpOwogICAgICAgIH0KICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU1BSX0NPTlNUOgogICAgICAgIGlmKFRoaXMtPmJhc2VTaGFkZXIubG9hZF9sb2NhbF9jb25zdHNGIHx8IGxpc3RfZW1wdHkoJlRoaXMtPmJhc2VTaGFkZXIuY29uc3RhbnRzRikpIHsKICAgICAgICAgICAgc3ByaW50ZihyZWdzdHIsICJDWyV1XSIsIHJlZyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc3ByaW50ZihyZWdzdHIsICJDJXUiLCByZWcpOwogICAgICAgIH0KICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU1BSX1RFWFRVUkU6IC8qIGNhc2UgV0lORUQzRFNQUl9BRERSOiAqLwogICAgICAgIHNwcmludGYocmVnc3RyLCJUJXUiLCByZWcpOwogICAgYnJlYWs7CiAgICBjYXNlIFdJTkVEM0RTUFJfQ09MT1JPVVQ6CiAgICAgICAgaWYgKHJlZyA9PSAwKQogICAgICAgICAgICBzcHJpbnRmKHJlZ3N0ciwgIlRNUF9DT0xPUiIpOwogICAgICAgIGVsc2UgewogICAgICAgICAgICAvKiBUT0RPOiBTZWUgR0xfQVJCX2RyYXdfYnVmZmVycyAqLwogICAgICAgICAgICBGSVhNRSgiVW5zdXBwb3J0ZWQgd3JpdGUgdG8gcmVuZGVyIHRhcmdldCAldVxuIiwgcmVnKTsKICAgICAgICAgICAgc3ByaW50ZihyZWdzdHIsICJ1bnN1cHBvcnRlZF9yZWdpc3RlciIpOwogICAgICAgIH0KICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU1BSX0RFUFRIT1VUOgogICAgICAgIHNwcmludGYocmVnc3RyLCAicmVzdWx0LmRlcHRoIik7CiAgICBicmVhazsKICAgIGNhc2UgV0lORUQzRFNQUl9BVFRST1VUOgogICAgICAgIHNwcmludGYocmVnc3RyLCAib0RbJXVdIiwgcmVnKTsKICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU1BSX1RFWENSRE9VVDoKICAgICAgICBzcHJpbnRmKHJlZ3N0ciwgIm9UWyV1XSIsIHJlZyk7CiAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgRklYTUUoIlVuaGFuZGxlZCByZWdpc3RlciBuYW1lIFR5cGUoJWQpXG4iLCByZWd0eXBlKTsKICAgICAgICBzcHJpbnRmKHJlZ3N0ciwgInVucmVjb2duaXplZF9yZWdpc3RlciIpOwogICAgYnJlYWs7CiAgICB9Cn0KCi8qIFRPRE86IG1lcmdlIHdpdGggcGl4ZWwgc2hhZGVyICovCnN0YXRpYyB2b2lkIHZzaGFkZXJfcHJvZ3JhbV9hZGRfcGFyYW0oU0hBREVSX09QQ09ERV9BUkcgKmFyZywgY29uc3QgRFdPUkQgcGFyYW0sIEJPT0wgaXNfaW5wdXQsIGNoYXIgKmh3TGluZSkgewoKICBJV2luZUQzRFZlcnRleFNoYWRlckltcGwqIFRoaXMgPSAoSVdpbmVEM0RWZXJ0ZXhTaGFkZXJJbXBsKikgYXJnLT5zaGFkZXI7CgogIC8qIG9Qb3MsIG9Gb2cgYW5kIG9QdHMgaW4gRDNEICovCiAgc3RhdGljIGNvbnN0IGNoYXIgKiBjb25zdCBod3Jhc3RvdXRfcmVnX25hbWVzW10gPSB7ICJUTVBfT1VUIiwgInJlc3VsdC5mb2djb29yZCIsICJyZXN1bHQucG9pbnRzaXplIiB9OwoKICBEV09SRCByZWcgPSBwYXJhbSAmIFdJTkVEM0RTUF9SRUdOVU1fTUFTSzsKICBEV09SRCByZWd0eXBlID0gc2hhZGVyX2dldF9yZWd0eXBlKHBhcmFtKTsKICBjaGFyICB0bXBSZWdbMjU1XTsKICBCT09MIGlzX2NvbG9yID0gRkFMU0U7CgogIGlmICgocGFyYW0gJiBXSU5FRDNEU1BfU1JDTU9EX01BU0spID09IFdJTkVEM0RTUFNNX05FRykgewogICAgICBzdHJjYXQoaHdMaW5lLCAiIC0iKTsKICB9IGVsc2UgewogICAgICBzdHJjYXQoaHdMaW5lLCAiICIpOwogIH0KCiAgc3dpdGNoIChyZWd0eXBlKSB7CiAgY2FzZSBXSU5FRDNEU1BSX1RFTVA6CiAgICBzcHJpbnRmKHRtcFJlZywgIlIldSIsIHJlZyk7CiAgICBzdHJjYXQoaHdMaW5lLCB0bXBSZWcpOwogICAgYnJlYWs7CiAgY2FzZSBXSU5FRDNEU1BSX0lOUFVUOgoKICAgIGlmICh2c2hhZGVyX2lucHV0X2lzX2NvbG9yKChJV2luZUQzRFZlcnRleFNoYWRlciopIFRoaXMsIHJlZykpCiAgICAgICAgaXNfY29sb3IgPSBUUlVFOwoKICAgIHNwcmludGYodG1wUmVnLCAidmVydGV4LmF0dHJpYlsldV0iLCByZWcpOwogICAgc3RyY2F0KGh3TGluZSwgdG1wUmVnKTsKICAgIGJyZWFrOwogIGNhc2UgV0lORUQzRFNQUl9DT05TVDoKICAgICAgaWYocGFyYW0gJiBXSU5FRDNEU0hBREVSX0FERFJNT0RFX1JFTEFUSVZFKSB7CiAgICAgICAgICBpZihyZWcgPj0gVGhpcy0+cmVsX29mZnNldCkgewogICAgICAgICAgICAgIHNwcmludGYodG1wUmVnLCAiQ1tBMC54ICsgJXVdIiwgcmVnIC0gVGhpcy0+cmVsX29mZnNldCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHNwcmludGYodG1wUmVnLCAiQ1tBMC54IC0gJXVdIiwgLXJlZyArIFRoaXMtPnJlbF9vZmZzZXQpOwogICAgICAgICAgfQogICAgICB9IGVsc2UgewogICAgICAgICAgaWYoVGhpcy0+YmFzZVNoYWRlci5sb2FkX2xvY2FsX2NvbnN0c0YgfHwgbGlzdF9lbXB0eSgmVGhpcy0+YmFzZVNoYWRlci5jb25zdGFudHNGKSkgewogICAgICAgICAgICAgIHNwcmludGYodG1wUmVnLCAiQ1sldV0iLCByZWcpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBzcHJpbnRmKHRtcFJlZywgIkMldSIsIHJlZyk7CiAgICAgICAgICB9CiAgICAgIH0KICAgIHN0cmNhdChod0xpbmUsIHRtcFJlZyk7CiAgICBicmVhazsKICBjYXNlIFdJTkVEM0RTUFJfQUREUjogLypjYXNlIEQzRFNQUl9URVhUVVJFOiovCiAgICBzcHJpbnRmKHRtcFJlZywgIkEldSIsIHJlZyk7CiAgICBzdHJjYXQoaHdMaW5lLCB0bXBSZWcpOwogICAgYnJlYWs7CiAgY2FzZSBXSU5FRDNEU1BSX1JBU1RPVVQ6CiAgICBzcHJpbnRmKHRtcFJlZywgIiVzIiwgaHdyYXN0b3V0X3JlZ19uYW1lc1tyZWddKTsKICAgIHN0cmNhdChod0xpbmUsIHRtcFJlZyk7CiAgICBicmVhazsKICBjYXNlIFdJTkVEM0RTUFJfQVRUUk9VVDoKICAgIGlmIChyZWc9PTApIHsKICAgICAgIHN0cmNhdChod0xpbmUsICJyZXN1bHQuY29sb3IucHJpbWFyeSIpOwogICAgfSBlbHNlIHsKICAgICAgIHN0cmNhdChod0xpbmUsICJyZXN1bHQuY29sb3Iuc2Vjb25kYXJ5Iik7CiAgICB9CiAgICBicmVhazsKICBjYXNlIFdJTkVEM0RTUFJfVEVYQ1JET1VUOgogICAgc3ByaW50Zih0bXBSZWcsICJyZXN1bHQudGV4Y29vcmRbJXVdIiwgcmVnKTsKICAgIHN0cmNhdChod0xpbmUsIHRtcFJlZyk7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgRklYTUUoIlVua25vd24gcmVnIHR5cGUgJWQgJWRcbiIsIHJlZ3R5cGUsIHJlZyk7CiAgICBzdHJjYXQoaHdMaW5lLCAidW5yZWNvZ25pemVkX3JlZ2lzdGVyIik7CiAgICBicmVhazsKICB9CgogIGlmICghaXNfaW5wdXQpIHsKICAgIGNoYXIgd3JpdGVfbWFza1s2XTsKICAgIHNoYWRlcl9hcmJfZ2V0X3dyaXRlX21hc2soYXJnLCBwYXJhbSwgd3JpdGVfbWFzayk7CiAgICBzdHJjYXQoaHdMaW5lLCB3cml0ZV9tYXNrKTsKICB9IGVsc2UgewogICAgY2hhciBzd2l6emxlWzZdOwogICAgc2hhZGVyX2FyYl9nZXRfc3dpenpsZShwYXJhbSwgaXNfY29sb3IsIHN3aXp6bGUpOwogICAgc3RyY2F0KGh3TGluZSwgc3dpenpsZSk7CiAgfQp9CgpzdGF0aWMgdm9pZCBzaGFkZXJfaHdfc2FtcGxlKFNIQURFUl9PUENPREVfQVJHKiBhcmcsIERXT1JEIHNhbXBsZXJfaWR4LCBjb25zdCBjaGFyICpkc3Rfc3RyLCBjb25zdCBjaGFyICpjb29yZF9yZWcsIEJPT0wgcHJvamVjdGVkLCBCT09MIGJpYXMpIHsKICAgIFNIQURFUl9CVUZGRVIqIGJ1ZmZlciA9IGFyZy0+YnVmZmVyOwogICAgRFdPUkQgc2FtcGxlcl90eXBlID0gYXJnLT5yZWdfbWFwcy0+c2FtcGxlcnNbc2FtcGxlcl9pZHhdICYgV0lORUQzRFNQX1RFWFRVUkVUWVBFX01BU0s7CiAgICBjb25zdCBjaGFyICp0ZXhfdHlwZTsKCiAgICBzd2l0Y2goc2FtcGxlcl90eXBlKSB7CiAgICAgICAgY2FzZSBXSU5FRDNEU1RUXzFEOgogICAgICAgICAgICB0ZXhfdHlwZSA9ICIxRCI7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RTVFRfMkQ6CiAgICAgICAgewogICAgICAgICAgICBJV2luZUQzREJhc2VTaGFkZXJJbXBsICpUaGlzID0gKElXaW5lRDNEQmFzZVNoYWRlckltcGwgKikgYXJnLT5zaGFkZXI7CiAgICAgICAgICAgIElXaW5lRDNERGV2aWNlSW1wbCAqZGV2aWNlID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKSBUaGlzLT5iYXNlU2hhZGVyLmRldmljZTsKICAgICAgICAgICAgaWYoZGV2aWNlLT5zdGF0ZUJsb2NrLT50ZXh0dXJlc1tzYW1wbGVyX2lkeF0gJiYKICAgICAgICAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9HZXRUZXh0dXJlRGltZW5zaW9ucyhkZXZpY2UtPnN0YXRlQmxvY2stPnRleHR1cmVzW3NhbXBsZXJfaWR4XSkgPT0gR0xfVEVYVFVSRV9SRUNUQU5HTEVfQVJCKSB7CiAgICAgICAgICAgICAgICB0ZXhfdHlwZSA9ICJSRUNUIjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHRleF90eXBlID0gIjJEIjsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgIGNhc2UgV0lORUQzRFNUVF9WT0xVTUU6CiAgICAgICAgICAgIHRleF90eXBlID0gIjNEIjsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzRFNUVF9DVUJFOgogICAgICAgICAgICB0ZXhfdHlwZSA9ICJDVUJFIjsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEVSUigiVW5leHBlY3RlZCB0ZXh0dXJlIHR5cGUgJWRcbiIsIHNhbXBsZXJfdHlwZSk7CiAgICAgICAgICAgIHRleF90eXBlID0gIiI7CiAgICB9CgogICAgaWYgKGJpYXMpIHsKICAgICAgICAvKiBTaG91bGRuJ3QgYmUgcG9zc2libGUsIGJ1dCBsZXQncyBjaGVjayBmb3IgaXQgKi8KICAgICAgICBpZihwcm9qZWN0ZWQpIEZJWE1FKCJCaWFzZWQgYW5kIFByb2plY3RlZCB0ZXh0dXJlIHNhbXBsaW5nXG4iKTsKICAgICAgICAvKiBUWEIgdGFrZXMgdGhlIDR0aCBjb21wb25lbnQgb2YgdGhlIHNvdXJjZSB2ZWN0b3IgYXV0b21hdGljYWxseSwgYXMgZDNkLiBOb3RoaW5nIG1vcmUgdG8gZG8gKi8KICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJUWEIgJXMsICVzLCB0ZXh0dXJlWyV1XSwgJXM7XG4iLCBkc3Rfc3RyLCBjb29yZF9yZWcsIHNhbXBsZXJfaWR4LCB0ZXhfdHlwZSk7CiAgICB9IGVsc2UgaWYgKHByb2plY3RlZCkgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlRYUCAlcywgJXMsIHRleHR1cmVbJXVdLCAlcztcbiIsIGRzdF9zdHIsIGNvb3JkX3JlZywgc2FtcGxlcl9pZHgsIHRleF90eXBlKTsKICAgIH0gZWxzZSB7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiVEVYICVzLCAlcywgdGV4dHVyZVsldV0sICVzO1xuIiwgZHN0X3N0ciwgY29vcmRfcmVnLCBzYW1wbGVyX2lkeCwgdGV4X3R5cGUpOwogICAgfQp9CgpzdGF0aWMgdm9pZCBzaGFkZXJfYXJiX2NvbG9yX2NvcnJlY3Rpb24oU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgSVdpbmVEM0RCYXNlU2hhZGVySW1wbCogc2hhZGVyID0gKElXaW5lRDNEQmFzZVNoYWRlckltcGwqKSBhcmctPnNoYWRlcjsKICAgIElXaW5lRDNERGV2aWNlSW1wbCogZGV2aWNlSW1wbCA9IChJV2luZUQzRERldmljZUltcGwqKSBzaGFkZXItPmJhc2VTaGFkZXIuZGV2aWNlOwogICAgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvID0gJmRldmljZUltcGwtPmFkYXB0ZXItPmdsX2luZm87CiAgICBXSU5FRDNERk9STUFUIGZtdDsKICAgIFdJTkVEM0RGT1JNQVQgY29udmVyc2lvbl9ncm91cDsKICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsICp0ZXh0dXJlOwogICAgVUlOVCBpOwogICAgQk9PTCByZWNvcmRlZCA9IEZBTFNFOwogICAgRFdPUkQgc2FtcGxlcl9pZHg7CiAgICBEV09SRCBoZXhfdmVyc2lvbiA9IHNoYWRlci0+YmFzZVNoYWRlci5oZXhfdmVyc2lvbjsKICAgIGNoYXIgcmVnWzI1Nl07CiAgICBjaGFyIHdyaXRlbWFza1s2XTsKCiAgICBzd2l0Y2goYXJnLT5vcGNvZGUtPm9wY29kZSkgewogICAgICAgIGNhc2UgV0lORUQzRFNJT19URVg6CiAgICAgICAgICAgIGlmIChoZXhfdmVyc2lvbiA8IFdJTkVEM0RQU19WRVJTSU9OKDIsMCkpIHsKICAgICAgICAgICAgICAgIHNhbXBsZXJfaWR4ID0gYXJnLT5kc3QgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzYW1wbGVyX2lkeCA9IGFyZy0+c3JjWzFdICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fVEVYTERMOgogICAgICAgICAgICBGSVhNRSgiQWRkIGNvbG9yIGZpeHVwIGZvciB2ZXJ0ZXggdGV4dHVyZSBXSU5FRDNEU0lPX1RFWExETFxuIik7CiAgICAgICAgICAgIHJldHVybjsKCiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX1RFWERQM1RFWDoKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fVEVYTTN4M1RFWDoKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fVEVYTTN4M1NQRUM6CiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX1RFWE0zeDNWU1BFQzoKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fVEVYQkVNOgogICAgICAgIGNhc2UgV0lORUQzRFNJT19URVhSRUcyQVI6CiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX1RFWFJFRzJHQjoKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fVEVYUkVHMlJHQjoKICAgICAgICAgICAgc2FtcGxlcl9pZHggPSBhcmctPmRzdCAmIFdJTkVEM0RTUF9SRUdOVU1fTUFTSzsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIC8qIE5vdCBhIHRleHR1cmUgc2FtcGxpbmcgaW5zdHJ1Y3Rpb24sIG5vdGhpbmcgdG8gZG8gKi8KICAgICAgICAgICAgcmV0dXJuOwogICAgfTsKCiAgICB0ZXh0dXJlID0gKElXaW5lRDNEQmFzZVRleHR1cmVJbXBsICopIGRldmljZUltcGwtPnN0YXRlQmxvY2stPnRleHR1cmVzW3NhbXBsZXJfaWR4XTsKICAgIGlmKHRleHR1cmUpIHsKICAgICAgICBmbXQgPSB0ZXh0dXJlLT5yZXNvdXJjZS5mb3JtYXQ7CiAgICAgICAgY29udmVyc2lvbl9ncm91cCA9IHRleHR1cmUtPmJhc2VUZXh0dXJlLnNoYWRlcl9jb252ZXJzaW9uX2dyb3VwOwogICAgfSBlbHNlIHsKICAgICAgICBmbXQgPSBXSU5FRDNERk1UX1VOS05PV047CiAgICAgICAgY29udmVyc2lvbl9ncm91cCA9IFdJTkVEM0RGTVRfVU5LTk9XTjsKICAgIH0KCiAgICAvKiBiZWZvcmUgZG9pbmcgYW55dGhpbmcsIHJlY29yZCB0aGUgc2FtcGxlciB3aXRoIHRoZSBmb3JtYXQgaW4gdGhlIGZvcm1hdCBjb252ZXJzaW9uIGxpc3QsCiAgICAgKiBidXQgY2hlY2sgaWYgaXQncyBub3QgdGhlcmUgYWxyZWFkeQogICAgICovCiAgICBmb3IoaSA9IDA7IGkgPCBzaGFkZXItPmJhc2VTaGFkZXIubnVtX3NhbXBsZWRfc2FtcGxlcnM7IGkrKykgewogICAgICAgIGlmKHNoYWRlci0+YmFzZVNoYWRlci5zYW1wbGVkX3NhbXBsZXJzW2ldID09IHNhbXBsZXJfaWR4KSB7CiAgICAgICAgICAgIHJlY29yZGVkID0gVFJVRTsKICAgICAgICB9CiAgICB9CiAgICBpZighcmVjb3JkZWQpIHsKICAgICAgICBzaGFkZXItPmJhc2VTaGFkZXIuc2FtcGxlZF9zYW1wbGVyc1tzaGFkZXItPmJhc2VTaGFkZXIubnVtX3NhbXBsZWRfc2FtcGxlcnNdID0gc2FtcGxlcl9pZHg7CiAgICAgICAgc2hhZGVyLT5iYXNlU2hhZGVyLm51bV9zYW1wbGVkX3NhbXBsZXJzKys7CiAgICAgICAgc2hhZGVyLT5iYXNlU2hhZGVyLnNhbXBsZWRfZm9ybWF0W3NhbXBsZXJfaWR4XSA9IGNvbnZlcnNpb25fZ3JvdXA7CiAgICB9CgogICAgcHNoYWRlcl9nZXRfcmVnaXN0ZXJfbmFtZShhcmctPnNoYWRlciwgYXJnLT5kc3QsIHJlZyk7CiAgICBzaGFkZXJfYXJiX2dldF93cml0ZV9tYXNrKGFyZywgYXJnLT5kc3QsIHdyaXRlbWFzayk7CiAgICBpZihzdHJsZW4od3JpdGVtYXNrKSA9PSAwKSBzdHJjcHkod3JpdGVtYXNrLCAiLnh5enciKTsKCiAgICBzd2l0Y2goZm10KSB7CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1Y4VTg6CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1YxNlUxNjoKICAgICAgICAgICAgaWYoR0xfU1VQUE9SVChOVl9URVhUVVJFX1NIQURFUikgfHwKICAgICAgICAgICAgICAgKEdMX1NVUFBPUlQoQVRJX0VOVk1BUF9CVU1QTUFQKSAmJiBmbXQgPT0gV0lORUQzREZNVF9WOFU4KSkgewojaWYgMAogICAgICAgICAgICAgICAgLyogVGhlIDNyZCBjaGFubmVsIHJldHVybnMgMS4wIGluIGQzZCwgYnV0IDAuMCBpbiBnbC4gRml4IHRoaXMgd2hpbGUgd2UncmUgYXQgaXQgOi0pCiAgICAgICAgICAgICAgICAgKiBkaXNhYmxlZCB1bnRpbCBhbiBhcHBsaWNhdGlvbiB0aGF0IG5lZWRzIGl0IGlzIGZvdW5kIGJlY2F1c2UgaXQgY2F1c2VzIHVubmVlZGVkCiAgICAgICAgICAgICAgICAgKiBzaGFkZXIgcmVjb21waWxhdGlvbiBpbiBzb21lIGdhbWUKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYoc3RybGVuKHdyaXRlbWFzaykgPj0gNCkgewogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiTU9WICVzLiVjLCBvbmUuejtcbiIsIHJlZywgd3JpdGVtYXNrWzNdKTsKICAgICAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvKiBDb3JyZWN0IHRoZSBzaWduLCBidXQgbGVhdmUgdGhlIGJsdWUgYXMgaXQgaXMgLSBpdCB3YXMgbG9hZGVkIGNvcnJlY3RseSBhbHJlYWR5CiAgICAgICAgICAgICAgICAgKiBBUkIgc2hhZGVycyBhcmUgYSBiaXQgcGlja3kgd3J0IHdyaXRlbWFza3MgYW5kIHN3aXp6bGVzLiBJZiB3ZSdyZSBmcmVlIHRvIHNjYWxlCiAgICAgICAgICAgICAgICAgKiBhbGwgcmVnaXN0ZXJzLCBkbyBzbywgdGhpcyBzYXZlcyBhbiBpbnN0cnVjdGlvbi4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYoc3RybGVuKHdyaXRlbWFzaykgPj0gNSkgewogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiTUFEICVzLCAlcywgY29lZm11bC54LCAtb25lO1xuIiwgcmVnLCByZWcpOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmKHN0cmxlbih3cml0ZW1hc2spID49IDMpIHsKICAgICAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgIk1BRCAlcy4lYywgJXMuJWMsIGNvZWZtdWwueCwgLW9uZTtcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnLCB3cml0ZW1hc2tbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnLCB3cml0ZW1hc2tbMV0pOwogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiTUFEICVzLiVjLCAlcy4lYywgY29lZm11bC54LCAtb25lO1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWcsIHdyaXRlbWFza1syXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWcsIHdyaXRlbWFza1syXSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYoc3RybGVuKHdyaXRlbWFzaykgPT0gMikgewogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiTUFEICVzLiVjLCAlcy4lYywgY29lZm11bC54LCAtb25lO1xuIiwgcmVnLCB3cml0ZW1hc2tbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnLCB3cml0ZW1hc2tbMV0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfWDhMOFY4VTg6CiAgICAgICAgICAgIGlmKCFHTF9TVVBQT1JUKE5WX1RFWFRVUkVfU0hBREVSKSkgewogICAgICAgICAgICAgICAgLyogUmVkIGFuZCBibHVlIGFyZSB0aGUgc2lnbmVkIGNoYW5uZWxzLCBmaXggdGhlbSB1cDsgQmx1ZSg9TCkgaXMgY29ycmVjdCBhbHJlYWR5LAogICAgICAgICAgICAgICAgICogYW5kIGEoWCkgaXMgYWx3YXlzIDEuMC4gQ2Fubm90IGRvIGEgZnVsbCBjb252ZXJzaW9uIGR1ZSB0byBMKGJsdWUpCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmKHN0cmxlbih3cml0ZW1hc2spID49IDMpIHsKICAgICAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgIk1BRCAlcy4lYywgJXMuJWMsIGNvZWZtdWwueCwgLW9uZTtcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnLCB3cml0ZW1hc2tbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnLCB3cml0ZW1hc2tbMV0pOwogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiTUFEICVzLiVjLCAlcy4lYywgY29lZm11bC54LCAtb25lO1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWcsIHdyaXRlbWFza1syXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWcsIHdyaXRlbWFza1syXSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYoc3RybGVuKHdyaXRlbWFzaykgPT0gMikgewogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiTUFEICVzLiVjLCAlcy4lYywgY29lZm11bC54LCAtb25lO1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWcsIHdyaXRlbWFza1sxXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWcsIHdyaXRlbWFza1sxXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9MNlY1VTU6CiAgICAgICAgICAgIGlmKCFHTF9TVVBQT1JUKE5WX1RFWFRVUkVfU0hBREVSKSkgewogICAgICAgICAgICAgICAgaWYoc3RybGVuKHdyaXRlbWFzaykgPj0gNCkgewogICAgICAgICAgICAgICAgICAgIC8qIFN3YXAgeSBhbmQgeiAoVSBhbmQgTCksIGFuZCBkbyBhIHNpZ24gY29udmVyc2lvbiBvbiB4IGFuZCB0aGUgbmV3IHkoViBhbmQgVSkgKi8KICAgICAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgIk1PViBUTVAuZywgJXMuJWM7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZywgd3JpdGVtYXNrWzJdKTsKICAgICAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgIk1BRCAlcy4lYyVjLCAlcy4lYyVjLCBjb2VmbXVsLngsIC1vbmU7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZywgd3JpdGVtYXNrWzFdLCB3cml0ZW1hc2tbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnLCB3cml0ZW1hc2tbMV0sIHdyaXRlbWFza1szXSk7CiAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJNT1YgJXMuJWMsIFRNUC5nO1xuIiwgcmVnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdyaXRlbWFza1szXSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYoc3RybGVuKHdyaXRlbWFzaykgPT0gMykgewogICAgICAgICAgICAgICAgICAgIC8qIFRoaXMgaXMgYmFkOiBXZSBoYXZlIFZMLCBidXQgd2UgbmVlZCBWVSAqLwogICAgICAgICAgICAgICAgICAgIEZJWE1FKCIyIGNvbXBvbmVudHMgc2FtcGxlZCBmcm9tIGEgY29udmVydGVkIEw2VjVVNSB0ZXh0dXJlXG4iKTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJNQUQgJXMuJWMsICVzLiVjLCBjb2VmbXVsLngsIC1vbmU7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZywgd3JpdGVtYXNrWzFdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZywgd3JpdGVtYXNrWzFdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1E4VzhWOFU4OgogICAgICAgICAgICBpZighR0xfU1VQUE9SVChOVl9URVhUVVJFX1NIQURFUikpIHsKICAgICAgICAgICAgICAgIC8qIENvcnJlY3QgdGhlIHNpZ24gaW4gYWxsIGNoYW5uZWxzICovCiAgICAgICAgICAgICAgICBzd2l0Y2goc3RybGVuKHdyaXRlbWFzaykpIHsKICAgICAgICAgICAgICAgICAgICBjYXNlIDQ6CiAgICAgICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiTUFEICVzLiVjLCAlcy4lYywgY29lZm11bC54LCAtb25lO1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnLCB3cml0ZW1hc2tbM10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZywgd3JpdGVtYXNrWzNdKTsKICAgICAgICAgICAgICAgICAgICAgICAgLyogZHJvcCB0aHJvdWdoICovCiAgICAgICAgICAgICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgIk1BRCAlcy4lYywgJXMuJWMsIGNvZWZtdWwueCwgLW9uZTtcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZywgd3JpdGVtYXNrWzJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWcsIHdyaXRlbWFza1syXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIGRyb3AgdGhyb3VnaCAqLwogICAgICAgICAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJNQUQgJXMuJWMsICVzLiVjLCBjb2VmbXVsLngsIC1vbmU7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWcsIHdyaXRlbWFza1sxXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnLCB3cml0ZW1hc2tbMV0pOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFNob3VsZCBub3Qgb2NjdXIsIHNpbmNlIGl0J3MgYXQgbWluaW11bSAnLicgYW5kIGEgbGV0dGVyICovCiAgICAgICAgICAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgICAgICAgICAgICBFUlIoIlVuZXhwZWN0ZWQgd3JpdGVtYXNrOiBcIiVzXCJcbiIsIHdyaXRlbWFzayk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBjYXNlIDU6CiAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJNQUQgJXMsICVzLCBjb2VmbXVsLngsIC1vbmU7XG4iLCByZWcsIHJlZyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAvKiBzdHVwaWQgY29tcGlsZXIgKi8KICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBicmVhazsKICAgIH0KfQoKCnN0YXRpYyB2b2lkIHBzaGFkZXJfZ2VuX2lucHV0X21vZGlmaWVyX2xpbmUgKAogICAgSVdpbmVEM0RCYXNlU2hhZGVyICppZmFjZSwKICAgIFNIQURFUl9CVUZGRVIqIGJ1ZmZlciwKICAgIGNvbnN0IERXT1JEIGluc3RyLAogICAgaW50IHRtcHJlZywKICAgIGNoYXIgKm91dHJlZ3N0cikgewoKICAgIC8qIEdlbmVyYXRlIGEgbGluZSB0aGF0IGRvZXMgdGhlIGlucHV0IG1vZGlmaWVyIGNvbXB1dGF0aW9uIGFuZCByZXR1cm4gdGhlIGlucHV0IHJlZ2lzdGVyIHRvIHVzZSAqLwogICAgY2hhciByZWdzdHJbMjU2XTsKICAgIGNoYXIgc3d6c3RyWzIwXTsKICAgIGludCBpbnNlcnRfbGluZTsKCiAgICAvKiBBc3N1bWUgYSBuZXcgbGluZSB3aWxsIGJlIGFkZGVkICovCiAgICBpbnNlcnRfbGluZSA9IDE7CgogICAgLyogR2V0IHJlZ2lzdGVyIG5hbWUgKi8KICAgIHBzaGFkZXJfZ2V0X3JlZ2lzdGVyX25hbWUoaWZhY2UsIGluc3RyLCByZWdzdHIpOwogICAgc2hhZGVyX2FyYl9nZXRfc3dpenpsZShpbnN0ciwgRkFMU0UsIHN3enN0cik7CgogICAgc3dpdGNoIChpbnN0ciAmIFdJTkVEM0RTUF9TUkNNT0RfTUFTSykgewogICAgY2FzZSBXSU5FRDNEU1BTTV9OT05FOgogICAgICAgIHNwcmludGYob3V0cmVnc3RyLCAiJXMlcyIsIHJlZ3N0ciwgc3d6c3RyKTsKICAgICAgICBpbnNlcnRfbGluZSA9IDA7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFdJTkVEM0RTUFNNX05FRzoKICAgICAgICBzcHJpbnRmKG91dHJlZ3N0ciwgIi0lcyVzIiwgcmVnc3RyLCBzd3pzdHIpOwogICAgICAgIGluc2VydF9saW5lID0gMDsKICAgICAgICBicmVhazsKICAgIGNhc2UgV0lORUQzRFNQU01fQklBUzoKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJBREQgVCVjLCAlcywgLWNvZWZkaXYueDtcbiIsICdBJyArIHRtcHJlZywgcmVnc3RyKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgV0lORUQzRFNQU01fQklBU05FRzoKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJBREQgVCVjLCAtJXMsIGNvZWZkaXYueDtcbiIsICdBJyArIHRtcHJlZywgcmVnc3RyKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgV0lORUQzRFNQU01fU0lHTjoKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJNQUQgVCVjLCAlcywgY29lZm11bC54LCAtb25lLng7XG4iLCAnQScgKyB0bXByZWcsIHJlZ3N0cik7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFdJTkVEM0RTUFNNX1NJR05ORUc6CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTUFEIFQlYywgJXMsIC1jb2VmbXVsLngsIG9uZS54O1xuIiwgJ0EnICsgdG1wcmVnLCByZWdzdHIpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU1BTTV9DT01QOgogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlNVQiBUJWMsIG9uZS54LCAlcztcbiIsICdBJyArIHRtcHJlZywgcmVnc3RyKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgV0lORUQzRFNQU01fWDI6CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiQUREIFQlYywgJXMsICVzO1xuIiwgJ0EnICsgdG1wcmVnLCByZWdzdHIsIHJlZ3N0cik7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFdJTkVEM0RTUFNNX1gyTkVHOgogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIkFERCBUJWMsIC0lcywgLSVzO1xuIiwgJ0EnICsgdG1wcmVnLCByZWdzdHIsIHJlZ3N0cik7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFdJTkVEM0RTUFNNX0RaOgogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlJDUCBUJWMsICVzLno7XG4iLCAnQScgKyB0bXByZWcsIHJlZ3N0cik7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTVVMIFQlYywgJXMsIFQlYztcbiIsICdBJyArIHRtcHJlZywgcmVnc3RyLCAnQScgKyB0bXByZWcpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU1BTTV9EVzoKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJSQ1AgVCVjLCAlcy53O1xuIiwgJ0EnICsgdG1wcmVnLCByZWdzdHIpOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIk1VTCBUJWMsICVzLCBUJWM7XG4iLCAnQScgKyB0bXByZWcsIHJlZ3N0ciwgJ0EnICsgdG1wcmVnKTsKICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgc3ByaW50ZihvdXRyZWdzdHIsICIlcyVzIiwgcmVnc3RyLCBzd3pzdHIpOwogICAgICAgIGluc2VydF9saW5lID0gMDsKICAgIH0KCiAgICAvKiBSZXR1cm4gbW9kaWZpZWQgb3Igb3JpZ2luYWwgcmVnaXN0ZXIsIHdpdGggc3dpenpsZSAqLwogICAgaWYgKGluc2VydF9saW5lKQogICAgICAgIHNwcmludGYob3V0cmVnc3RyLCAiVCVjJXMiLCAnQScgKyB0bXByZWcsIHN3enN0cik7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBwc2hhZGVyX2dlbl9vdXRwdXRfbW9kaWZpZXJfbGluZSgKICAgIFNIQURFUl9CVUZGRVIqIGJ1ZmZlciwKICAgIGludCBzYXR1cmF0ZSwKICAgIGNoYXIgKndyaXRlX21hc2ssCiAgICBpbnQgc2hpZnQsCiAgICBjaGFyICpyZWdzdHIpIHsKCiAgICAvKiBHZW5lcmF0ZSBhIGxpbmUgdGhhdCBkb2VzIHRoZSBvdXRwdXQgbW9kaWZpZXIgY29tcHV0YXRpb24gKi8KICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIk1VTCVzICVzJXMsICVzLCAlcztcbiIsIHNhdHVyYXRlID8gIl9TQVQiIDogIiIsCiAgICAgICAgcmVnc3RyLCB3cml0ZV9tYXNrLCByZWdzdHIsIHNoaWZ0X3RhYltzaGlmdF0pOwp9Cgp2b2lkIHBzaGFkZXJfaHdfYmVtKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsKiBUaGlzID0gKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsKikgYXJnLT5zaGFkZXI7CgogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBjaGFyIGRzdF9uYW1lWzUwXTsKICAgIGNoYXIgc3JjX25hbWVbMl1bNTBdOwogICAgY2hhciBkc3Rfd21hc2tbMjBdOwogICAgRFdPUkQgc2FtcGxlcl9jb2RlID0gYXJnLT5kc3QgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICBCT09MIGhhc19idW1wbWF0ID0gRkFMU0U7CiAgICBpbnQgaTsKCiAgICBmb3IoaSA9IDA7IGkgPCBUaGlzLT5udW1idW1wZW52bWF0Y29uc3RzOyBpKyspIHsKICAgICAgICBpZihUaGlzLT5idW1wZW52bWF0Y29uc3RbaV0uY29uc3RfbnVtICE9IC0xICYmIFRoaXMtPmJ1bXBlbnZtYXRjb25zdFtpXS50ZXh1bml0ID09IHNhbXBsZXJfY29kZSkgewogICAgICAgICAgICBoYXNfYnVtcG1hdCA9IFRSVUU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICBwc2hhZGVyX2dldF9yZWdpc3Rlcl9uYW1lKGFyZy0+c2hhZGVyLCBhcmctPmRzdCwgZHN0X25hbWUpOwogICAgc2hhZGVyX2FyYl9nZXRfd3JpdGVfbWFzayhhcmcsIGFyZy0+ZHN0LCBkc3Rfd21hc2spOwogICAgc3RyY2F0KGRzdF9uYW1lLCBkc3Rfd21hc2spOwoKICAgIHBzaGFkZXJfZ2VuX2lucHV0X21vZGlmaWVyX2xpbmUoYXJnLT5zaGFkZXIsIGJ1ZmZlciwgYXJnLT5zcmNbMF0sIDAsIHNyY19uYW1lWzBdKTsKICAgIHBzaGFkZXJfZ2VuX2lucHV0X21vZGlmaWVyX2xpbmUoYXJnLT5zaGFkZXIsIGJ1ZmZlciwgYXJnLT5zcmNbMV0sIDEsIHNyY19uYW1lWzFdKTsKCiAgICBpZihoYXNfYnVtcG1hdCkgewogICAgICAgIC8qIFNhbXBsaW5nIHRoZSBwZXJ0dXJiYXRpb24gbWFwIGluIFRzcmMgd2FzIGRvbmUgYWxyZWFkeSwgaW5jbHVkaW5nIHRoZSBzaWduZWRuZXNzIGNvcnJlY3Rpb24gaWYgbmVlZGVkICovCiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiU1daIFRNUDIsIGJ1bXBlbnZtYXQlZCwgeCwgeiwgMCwgMDtcbiIsIHNhbXBsZXJfY29kZSk7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiRFAzIFRNUC5yLCBUTVAyLCAlcztcbiIsIHNyY19uYW1lWzFdKTsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJTV1ogVE1QMiwgYnVtcGVudm1hdCVkLCB5LCB3LCAwLCAwO1xuIiwgc2FtcGxlcl9jb2RlKTsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJEUDMgVE1QLmcsIFRNUDIsICVzO1xuIiwgc3JjX25hbWVbMV0pOwoKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJBREQgJXMsICVzLCBUTVA7XG4iLCBkc3RfbmFtZSwgc3JjX25hbWVbMF0pOwogICAgfSBlbHNlIHsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJNT1YgJXMsICVzO1xuIiwgZHN0X25hbWUsIHNyY19uYW1lWzBdKTsKICAgIH0KfQoKdm9pZCBwc2hhZGVyX2h3X2NuZChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CgogICAgSVdpbmVEM0RCYXNlU2hhZGVySW1wbCogc2hhZGVyID0gKElXaW5lRDNEQmFzZVNoYWRlckltcGwqKSBhcmctPnNoYWRlcjsKICAgIFNIQURFUl9CVUZGRVIqIGJ1ZmZlciA9IGFyZy0+YnVmZmVyOwogICAgY2hhciBkc3Rfd21hc2tbMjBdOwogICAgY2hhciBkc3RfbmFtZVs1MF07CiAgICBjaGFyIHNyY19uYW1lWzNdWzUwXTsKICAgIEJPT0wgc2F0ID0gKGFyZy0+ZHN0ICYgV0lORUQzRFNQX0RTVE1PRF9NQVNLKSAmIFdJTkVEM0RTUERNX1NBVFVSQVRFOwogICAgRFdPUkQgc2hpZnQgPSAoYXJnLT5kc3QgJiBXSU5FRDNEU1BfRFNUU0hJRlRfTUFTSykgPj4gV0lORUQzRFNQX0RTVFNISUZUX1NISUZUOwoKICAgIC8qIEZJWE1FOiBzdXBwb3J0IG91dHB1dCBtb2RpZmllcnMgKi8KCiAgICAvKiBIYW5kbGUgb3V0cHV0IHJlZ2lzdGVyICovCiAgICBwc2hhZGVyX2dldF9yZWdpc3Rlcl9uYW1lKGFyZy0+c2hhZGVyLCBhcmctPmRzdCwgZHN0X25hbWUpOwogICAgc2hhZGVyX2FyYl9nZXRfd3JpdGVfbWFzayhhcmcsIGFyZy0+ZHN0LCBkc3Rfd21hc2spOwoKICAgIC8qIEdlbmVyYXRlIGlucHV0IHJlZ2lzdGVyIG5hbWVzICh3aXRoIG1vZGlmaWVycykgKi8KICAgIHBzaGFkZXJfZ2VuX2lucHV0X21vZGlmaWVyX2xpbmUoYXJnLT5zaGFkZXIsIGJ1ZmZlciwgYXJnLT5zcmNbMF0sIDAsIHNyY19uYW1lWzBdKTsKICAgIHBzaGFkZXJfZ2VuX2lucHV0X21vZGlmaWVyX2xpbmUoYXJnLT5zaGFkZXIsIGJ1ZmZlciwgYXJnLT5zcmNbMV0sIDEsIHNyY19uYW1lWzFdKTsKICAgIHBzaGFkZXJfZ2VuX2lucHV0X21vZGlmaWVyX2xpbmUoYXJnLT5zaGFkZXIsIGJ1ZmZlciwgYXJnLT5zcmNbMl0sIDIsIHNyY19uYW1lWzJdKTsKCiAgICAvKiBUaGUgY29pc3N1ZSBmbGFnIGNoYW5nZXMgdGhlIHNlbWFudGljIG9mIHRoZSBjbmQgaW5zdHJ1Y3Rpb24gaW4gPD0gMS4zIHNoYWRlcnMgKi8KICAgIGlmIChzaGFkZXItPmJhc2VTaGFkZXIuaGV4X3ZlcnNpb24gPD0gV0lORUQzRFBTX1ZFUlNJT04oMSwgMykgJiYKICAgICAgICBhcmctPm9wY29kZV90b2tlbiAmIFdJTkVEM0RTSV9DT0lTU1VFKSB7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTU9WJXMgJXMlcywgJXM7XG4iLCBzYXQgPyAiX1NBVCIgOiAiIiwgZHN0X25hbWUsIGRzdF93bWFzaywgc3JjX25hbWVbMV0pOwogICAgfSBlbHNlIHsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJBREQgVE1QLCAtJXMsIGNvZWZkaXYueDtcbiIsIHNyY19uYW1lWzBdKTsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJDTVAlcyAlcyVzLCBUTVAsICVzLCAlcztcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2F0ID8gIl9TQVQiIDogIiIsIGRzdF9uYW1lLCBkc3Rfd21hc2ssIHNyY19uYW1lWzFdLCBzcmNfbmFtZVsyXSk7CiAgICB9CiAgICBpZiAoc2hpZnQgIT0gMCkKICAgICAgICBwc2hhZGVyX2dlbl9vdXRwdXRfbW9kaWZpZXJfbGluZShidWZmZXIsIEZBTFNFLCBkc3Rfd21hc2ssIHNoaWZ0LCBkc3RfbmFtZSk7Cn0KCnZvaWQgcHNoYWRlcl9od19jbXAoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewoKICAgIFNIQURFUl9CVUZGRVIqIGJ1ZmZlciA9IGFyZy0+YnVmZmVyOwogICAgY2hhciBkc3Rfd21hc2tbMjBdOwogICAgY2hhciBkc3RfbmFtZVs1MF07CiAgICBjaGFyIHNyY19uYW1lWzNdWzUwXTsKICAgIERXT1JEIHNoaWZ0ID0gKGFyZy0+ZHN0ICYgV0lORUQzRFNQX0RTVFNISUZUX01BU0spID4+IFdJTkVEM0RTUF9EU1RTSElGVF9TSElGVDsKICAgIEJPT0wgc2F0ID0gKGFyZy0+ZHN0ICYgV0lORUQzRFNQX0RTVE1PRF9NQVNLKSAmIFdJTkVEM0RTUERNX1NBVFVSQVRFOwoKICAgIC8qIEZJWE1FOiBzdXBwb3J0IG91dHB1dCBtb2RpZmllcnMgKi8KCiAgICAvKiBIYW5kbGUgb3V0cHV0IHJlZ2lzdGVyICovCiAgICBwc2hhZGVyX2dldF9yZWdpc3Rlcl9uYW1lKGFyZy0+c2hhZGVyLCBhcmctPmRzdCwgZHN0X25hbWUpOwogICAgc2hhZGVyX2FyYl9nZXRfd3JpdGVfbWFzayhhcmcsIGFyZy0+ZHN0LCBkc3Rfd21hc2spOwoKICAgIC8qIEdlbmVyYXRlIGlucHV0IHJlZ2lzdGVyIG5hbWVzICh3aXRoIG1vZGlmaWVycykgKi8KICAgIHBzaGFkZXJfZ2VuX2lucHV0X21vZGlmaWVyX2xpbmUoYXJnLT5zaGFkZXIsIGJ1ZmZlciwgYXJnLT5zcmNbMF0sIDAsIHNyY19uYW1lWzBdKTsKICAgIHBzaGFkZXJfZ2VuX2lucHV0X21vZGlmaWVyX2xpbmUoYXJnLT5zaGFkZXIsIGJ1ZmZlciwgYXJnLT5zcmNbMV0sIDEsIHNyY19uYW1lWzFdKTsKICAgIHBzaGFkZXJfZ2VuX2lucHV0X21vZGlmaWVyX2xpbmUoYXJnLT5zaGFkZXIsIGJ1ZmZlciwgYXJnLT5zcmNbMl0sIDIsIHNyY19uYW1lWzJdKTsKCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJDTVAlcyAlcyVzLCAlcywgJXMsICVzO1xuIiwgc2F0ID8gIl9TQVQiIDogIiIsIGRzdF9uYW1lLCBkc3Rfd21hc2ssCiAgICAgICAgICAgICAgICAgICBzcmNfbmFtZVswXSwgc3JjX25hbWVbMl0sIHNyY19uYW1lWzFdKTsKCiAgICBpZiAoc2hpZnQgIT0gMCkKICAgICAgICBwc2hhZGVyX2dlbl9vdXRwdXRfbW9kaWZpZXJfbGluZShidWZmZXIsIEZBTFNFLCBkc3Rfd21hc2ssIHNoaWZ0LCBkc3RfbmFtZSk7Cn0KCi8qKiBQcm9jZXNzIHRoZSBXSU5FRDNEU0lPX0RQMkFERCBpbnN0cnVjdGlvbiBpbiBBUkIuCiAqIGRzdCA9IGRvdDIoc3JjMCwgc3JjMSkgKyBzcmMyICovCnZvaWQgcHNoYWRlcl9od19kcDJhZGQoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBjaGFyIGRzdF93bWFza1syMF07CiAgICBjaGFyIGRzdF9uYW1lWzUwXTsKICAgIGNoYXIgc3JjX25hbWVbM11bNTBdOwogICAgRFdPUkQgc2hpZnQgPSAoYXJnLT5kc3QgJiBXSU5FRDNEU1BfRFNUU0hJRlRfTUFTSykgPj4gV0lORUQzRFNQX0RTVFNISUZUX1NISUZUOwogICAgQk9PTCBzYXQgPSAoYXJnLT5kc3QgJiBXSU5FRDNEU1BfRFNUTU9EX01BU0spICYgV0lORUQzRFNQRE1fU0FUVVJBVEU7CgogICAgcHNoYWRlcl9nZXRfcmVnaXN0ZXJfbmFtZShhcmctPnNoYWRlciwgYXJnLT5kc3QsIGRzdF9uYW1lKTsKICAgIHNoYWRlcl9hcmJfZ2V0X3dyaXRlX21hc2soYXJnLCBhcmctPmRzdCwgZHN0X3dtYXNrKTsKCiAgICBwc2hhZGVyX2dlbl9pbnB1dF9tb2RpZmllcl9saW5lKGFyZy0+c2hhZGVyLCBidWZmZXIsIGFyZy0+c3JjWzBdLCAwLCBzcmNfbmFtZVswXSk7CiAgICBwc2hhZGVyX2dlbl9pbnB1dF9tb2RpZmllcl9saW5lKGFyZy0+c2hhZGVyLCBidWZmZXIsIGFyZy0+c3JjWzFdLCAxLCBzcmNfbmFtZVsxXSk7CiAgICBwc2hhZGVyX2dlbl9pbnB1dF9tb2RpZmllcl9saW5lKGFyZy0+c2hhZGVyLCBidWZmZXIsIGFyZy0+c3JjWzJdLCAyLCBzcmNfbmFtZVsyXSk7CgogICAgLyogRW11bGF0ZSBhIERQMiB3aXRoIGEgRFAzIGFuZCAwLjAgKi8KICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIk1PViBUTVAsICVzO1xuIiwgc3JjX25hbWVbMF0pOwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTU9WIFRNUC56LCAwLjA7XG4iKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIkRQMyBUTVAyLCBUTVAsICVzO1xuIiwgc3JjX25hbWVbMV0pOwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiQUREJXMgJXMlcywgVE1QMiwgJXM7XG4iLCBzYXQgPyAiX1NBVCIgOiAiIiwgZHN0X25hbWUsIGRzdF93bWFzaywgc3JjX25hbWVbMl0pOwoKICAgIGlmIChzaGlmdCAhPSAwKQogICAgICAgIHBzaGFkZXJfZ2VuX291dHB1dF9tb2RpZmllcl9saW5lKGJ1ZmZlciwgRkFMU0UsIGRzdF93bWFzaywgc2hpZnQsIGRzdF9uYW1lKTsKfQoKLyogTWFwIHRoZSBvcGNvZGUgMS10by0xIHRvIHRoZSBHTCBjb2RlICovCnZvaWQgcHNoYWRlcl9od19tYXAyZ2woU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewoKICAgICBDT05TVCBTSEFERVJfT1BDT0RFKiBjdXJPcGNvZGUgPSBhcmctPm9wY29kZTsKICAgICBTSEFERVJfQlVGRkVSKiBidWZmZXIgPSBhcmctPmJ1ZmZlcjsKICAgICBEV09SRCBkc3QgPSBhcmctPmRzdDsKICAgICBEV09SRCogc3JjID0gYXJnLT5zcmM7CgogICAgIHVuc2lnbmVkIGludCBpOwogICAgIGNoYXIgdG1wTGluZVsyNTZdOwoKICAgICAvKiBPdXRwdXQgdG9rZW4gcmVsYXRlZCAqLwogICAgIGNoYXIgb3V0cHV0X3JuYW1lWzI1Nl07CiAgICAgY2hhciBvdXRwdXRfd21hc2tbMjBdOwogICAgIEJPT0wgc2F0dXJhdGUgPSBGQUxTRTsKICAgICBCT09MIGNlbnRyb2lkID0gRkFMU0U7CiAgICAgQk9PTCBwYXJ0aWFscHJlY2lzaW9uID0gRkFMU0U7CiAgICAgRFdPUkQgc2hpZnQ7CgogICAgIHN0cmNweSh0bXBMaW5lLCBjdXJPcGNvZGUtPmdsbmFtZSk7CgogICAgIC8qIFByb2Nlc3MgbW9kaWZpZXJzICovCiAgICAgaWYgKDAgIT0gKGRzdCAmIFdJTkVEM0RTUF9EU1RNT0RfTUFTSykpIHsKICAgICAgICAgRFdPUkQgbWFzayA9IGRzdCAmIFdJTkVEM0RTUF9EU1RNT0RfTUFTSzsKCiAgICAgICAgIHNhdHVyYXRlID0gbWFzayAmIFdJTkVEM0RTUERNX1NBVFVSQVRFOwogICAgICAgICBjZW50cm9pZCA9IG1hc2sgJiBXSU5FRDNEU1BETV9NU0FNUENFTlRST0lEOwogICAgICAgICBwYXJ0aWFscHJlY2lzaW9uID0gbWFzayAmIFdJTkVEM0RTUERNX1BBUlRJQUxQUkVDSVNJT047CiAgICAgICAgIG1hc2sgJj0gfihXSU5FRDNEU1BETV9NU0FNUENFTlRST0lEIHwgV0lORUQzRFNQRE1fUEFSVElBTFBSRUNJU0lPTiB8IFdJTkVEM0RTUERNX1NBVFVSQVRFKTsKICAgICAgICAgaWYgKG1hc2spCiAgICAgICAgICAgIEZJWE1FKCJVbnJlY29nbml6ZWQgbW9kaWZpZXIoJSN4KVxuIiwgbWFzayA+PiBXSU5FRDNEU1BfRFNUTU9EX1NISUZUKTsKCiAgICAgICAgIGlmIChjZW50cm9pZCkKICAgICAgICAgICAgIEZJWE1FKCJVbmhhbmRsZWQgbW9kaWZpZXIoJSN4KVxuIiwgbWFzayA+PiBXSU5FRDNEU1BfRFNUTU9EX1NISUZUKTsKICAgICB9CiAgICAgc2hpZnQgPSAoZHN0ICYgV0lORUQzRFNQX0RTVFNISUZUX01BU0spID4+IFdJTkVEM0RTUF9EU1RTSElGVF9TSElGVDsKCiAgICAgIC8qIEdlbmVyYXRlIGlucHV0IGFuZCBvdXRwdXQgcmVnaXN0ZXJzICovCiAgICAgIGlmIChjdXJPcGNvZGUtPm51bV9wYXJhbXMgPiAwKSB7CiAgICAgICAgICBjaGFyIG9wZXJhbmRzWzRdWzEwMF07CgogICAgICAgICAgLyogR2VuZXJhdGUgaW5wdXQgcmVnaXN0ZXIgbmFtZXMgKHdpdGggbW9kaWZpZXJzKSAqLwogICAgICAgICAgZm9yIChpID0gMTsgaSA8IGN1ck9wY29kZS0+bnVtX3BhcmFtczsgKytpKQogICAgICAgICAgICAgIHBzaGFkZXJfZ2VuX2lucHV0X21vZGlmaWVyX2xpbmUoYXJnLT5zaGFkZXIsIGJ1ZmZlciwgc3JjW2ktMV0sIGktMSwgb3BlcmFuZHNbaV0pOwoKICAgICAgICAgIC8qIEhhbmRsZSBvdXRwdXQgcmVnaXN0ZXIgKi8KICAgICAgICAgIHBzaGFkZXJfZ2V0X3JlZ2lzdGVyX25hbWUoYXJnLT5zaGFkZXIsIGRzdCwgb3V0cHV0X3JuYW1lKTsKICAgICAgICAgIHN0cmNweShvcGVyYW5kc1swXSwgb3V0cHV0X3JuYW1lKTsKICAgICAgICAgIHNoYWRlcl9hcmJfZ2V0X3dyaXRlX21hc2soYXJnLCBkc3QsIG91dHB1dF93bWFzayk7CiAgICAgICAgICBzdHJjYXQob3BlcmFuZHNbMF0sIG91dHB1dF93bWFzayk7CgogICAgICAgICAgaWYgKHNhdHVyYXRlICYmIChzaGlmdCA9PSAwKSkKICAgICAgICAgICAgIHN0cmNhdCh0bXBMaW5lLCAiX1NBVCIpOwogICAgICAgICAgc3RyY2F0KHRtcExpbmUsICIgIik7CiAgICAgICAgICBzdHJjYXQodG1wTGluZSwgb3BlcmFuZHNbMF0pOwogICAgICAgICAgZm9yIChpID0gMTsgaSA8IGN1ck9wY29kZS0+bnVtX3BhcmFtczsgaSsrKSB7CiAgICAgICAgICAgICAgc3RyY2F0KHRtcExpbmUsICIsICIpOwogICAgICAgICAgICAgIHN0cmNhdCh0bXBMaW5lLCBvcGVyYW5kc1tpXSk7CiAgICAgICAgICB9CiAgICAgICAgICBzdHJjYXQodG1wTGluZSwiO1xuIik7CiAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsIHRtcExpbmUpOwoKICAgICAgICAgIC8qIEEgc2hpZnQgcmVxdWlyZXMgYW5vdGhlciBsaW5lLiAqLwogICAgICAgICAgaWYgKHNoaWZ0ICE9IDApCiAgICAgICAgICAgICAgcHNoYWRlcl9nZW5fb3V0cHV0X21vZGlmaWVyX2xpbmUoYnVmZmVyLCBzYXR1cmF0ZSwgb3V0cHV0X3dtYXNrLCBzaGlmdCwgb3V0cHV0X3JuYW1lKTsKICAgICAgfQp9Cgp2b2lkIHBzaGFkZXJfaHdfdGV4a2lsbChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCogVGhpcyA9IChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCopIGFyZy0+c2hhZGVyOwogICAgRFdPUkQgaGV4X3ZlcnNpb24gPSBUaGlzLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uOwogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBjaGFyIHJlZ19kZXN0WzQwXTsKCiAgICAvKiBObyBzd2l6emxlcyBhcmUgYWxsb3dlZCBpbiBkM2QncyB0ZXhraWxsLiBQUyAxLnggaWdub3JlcyB0aGUgNHRoIGNvbXBvbmVudCBhcyBkb2N1bWVudGVkLAogICAgICogYnV0ID49IDIuMCBob25vcnMgaXQodW5kb2N1bWVudGVkLCBidXQgdGVzdGVkIGJ5IHRoZSBkM2Q5IHRlc3RzdWl0KQogICAgICovCiAgICBwc2hhZGVyX2dldF9yZWdpc3Rlcl9uYW1lKGFyZy0+c2hhZGVyLCBhcmctPmRzdCwgcmVnX2Rlc3QpOwoKICAgIGlmKGhleF92ZXJzaW9uID49IFdJTkVEM0RQU19WRVJTSU9OKDIsMCkpIHsKICAgICAgICAvKiBUaGUgYXJiIGJhY2tlbmQgZG9lc24ndCBjbGFpbSBwcyAyLjAgc3VwcG9ydCwgYnV0IHRyeSB0byBlYXQgd2hhdCB0aGUgYXBwIGZlZWRzIHRvIHVzICovCiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiS0lMICVzO1xuIiwgcmVnX2Rlc3QpOwogICAgfSBlbHNlIHsKICAgICAgICAvKiBBUkIgZnAgZG9lc24ndCBsaWtlIHN3aXp6bGVzIG9uIHRoZSBwYXJhbWV0ZXIgb2YgdGhlIEtJTCBpbnN0cnVjdGlvbi4gVG8gbWFzayB0aGUgNHRoIGNvbXBvbmVudCwKICAgICAgICAgKiBjb3B5IHRoZSByZWdpc3RlciBpbnRvIG91ciBnZW5lcmFsIHB1cnBvc2UgVE1QIHZhcmlhYmxlLCBvdmVyd3JpdGUgLncgYW5kIHBhc3MgVE1QIHRvIEtJTAogICAgICAgICAqLwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIk1PViBUTVAsICVzO1xuIiwgcmVnX2Rlc3QpOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIk1PViBUTVAudywgb25lLnc7XG4iKTsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJLSUwgVE1QO1xuIik7CiAgICB9Cn0KCnZvaWQgcHNoYWRlcl9od190ZXgoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgSVdpbmVEM0RQaXhlbFNoYWRlckltcGwqIFRoaXMgPSAoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwqKSBhcmctPnNoYWRlcjsKICAgIElXaW5lRDNERGV2aWNlSW1wbCogZGV2aWNlSW1wbCA9IChJV2luZUQzRERldmljZUltcGwqKSBUaGlzLT5iYXNlU2hhZGVyLmRldmljZTsKCiAgICBEV09SRCBkc3QgPSBhcmctPmRzdDsKICAgIERXT1JEKiBzcmMgPSBhcmctPnNyYzsKICAgIFNIQURFUl9CVUZGRVIqIGJ1ZmZlciA9IGFyZy0+YnVmZmVyOwogICAgRFdPUkQgaGV4X3ZlcnNpb24gPSBUaGlzLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uOwogICAgQk9PTCBwcm9qZWN0ZWQgPSBGQUxTRSwgYmlhcyA9IEZBTFNFOwoKICAgIGNoYXIgcmVnX2Rlc3RbNDBdOwogICAgY2hhciByZWdfY29vcmRbNDBdOwogICAgRFdPUkQgcmVnX2Rlc3RfY29kZTsKICAgIERXT1JEIHJlZ19zYW1wbGVyX2NvZGU7CgogICAgLyogQWxsIHZlcnNpb25zIGhhdmUgYSBkZXN0aW5hdGlvbiByZWdpc3RlciAqLwogICAgcmVnX2Rlc3RfY29kZSA9IGRzdCAmIFdJTkVEM0RTUF9SRUdOVU1fTUFTSzsKICAgIHBzaGFkZXJfZ2V0X3JlZ2lzdGVyX25hbWUoYXJnLT5zaGFkZXIsIGRzdCwgcmVnX2Rlc3QpOwoKICAgIC8qIDEuMC0xLjM6IFVzZSBkZXN0aW5hdGlvbiByZWdpc3RlciBhcyBjb29yZGluYXRlIHNvdXJjZS4KICAgICAgIDEuNCs6IFVzZSBwcm92aWRlZCBjb29yZGluYXRlIHNvdXJjZSByZWdpc3Rlci4gKi8KICAgaWYgKGhleF92ZXJzaW9uIDwgV0lORUQzRFBTX1ZFUlNJT04oMSw0KSkKICAgICAgc3RyY3B5KHJlZ19jb29yZCwgcmVnX2Rlc3QpOwogICBlbHNlCiAgICAgIHBzaGFkZXJfZ2VuX2lucHV0X21vZGlmaWVyX2xpbmUoYXJnLT5zaGFkZXIsIGJ1ZmZlciwgc3JjWzBdLCAwLCByZWdfY29vcmQpOwoKICAvKiAxLjAtMS40OiBVc2UgZGVzdGluYXRpb24gcmVnaXN0ZXIgbnVtYmVyIGFzIHRleHR1cmUgY29kZS4KICAgICAyLjArOiBVc2UgcHJvdmlkZWQgc2FtcGxlciBudW1iZXIgYXMgdGV4dXJlIGNvZGUuICovCiAgaWYgKGhleF92ZXJzaW9uIDwgV0lORUQzRFBTX1ZFUlNJT04oMiwwKSkKICAgICByZWdfc2FtcGxlcl9jb2RlID0gcmVnX2Rlc3RfY29kZTsKICBlbHNlCiAgICAgcmVnX3NhbXBsZXJfY29kZSA9IHNyY1sxXSAmIFdJTkVEM0RTUF9SRUdOVU1fTUFTSzsKCiAgLyogcHJvamVjdGlvbiBmbGFnOgogICAqIDEuMSwgMS4yLCAxLjM6IFVzZSBXSU5FRDNEVFNTX1RFWFRVUkVUUkFOU0ZPUk1GTEFHUwogICAqIDEuNDogVXNlIFdJTkVEM0RTUFNNX0RaIG9yIFdJTkVEM0RTUFNNX0RXIG9uIHNyY1swXQogICAqIDIuMCs6IFVzZSBXSU5FRDNEU0lfVEVYTERfUFJPSkVDVCBvbiB0aGUgb3Bjb2RlCiAgICovCiAgaWYoaGV4X3ZlcnNpb24gPCBXSU5FRDNEUFNfVkVSU0lPTigxLDQpKSB7CiAgICAgIERXT1JEIGZsYWdzID0gMDsKICAgICAgaWYocmVnX3NhbXBsZXJfY29kZSA8IE1BWF9URVhUVVJFUykgewogICAgICAgIGZsYWdzID0gZGV2aWNlSW1wbC0+c3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlW3JlZ19zYW1wbGVyX2NvZGVdW1dJTkVEM0RUU1NfVEVYVFVSRVRSQU5TRk9STUZMQUdTXTsKICAgICAgfQogICAgICBpZiAoZmxhZ3MgJiBXSU5FRDNEVFRGRl9QUk9KRUNURUQpIHsKICAgICAgICAgIHByb2plY3RlZCA9IFRSVUU7CiAgICAgIH0KICB9IGVsc2UgaWYoaGV4X3ZlcnNpb24gPCBXSU5FRDNEUFNfVkVSU0lPTigyLDApKSB7CiAgICAgIERXT1JEIHNyY19tb2QgPSBhcmctPnNyY1swXSAmIFdJTkVEM0RTUF9TUkNNT0RfTUFTSzsKICAgICAgaWYgKHNyY19tb2QgPT0gV0lORUQzRFNQU01fRFopIHsKICAgICAgICAgIHByb2plY3RlZCA9IFRSVUU7CiAgICAgIH0gZWxzZSBpZihzcmNfbW9kID09IFdJTkVEM0RTUFNNX0RXKSB7CiAgICAgICAgICBwcm9qZWN0ZWQgPSBUUlVFOwogICAgICB9CiAgfSBlbHNlIHsKICAgICAgaWYoYXJnLT5vcGNvZGVfdG9rZW4gJiBXSU5FRDNEU0lfVEVYTERfUFJPSkVDVCkgewogICAgICAgICAgcHJvamVjdGVkID0gVFJVRTsKICAgICAgfQogICAgICBpZihhcmctPm9wY29kZV90b2tlbiAmIFdJTkVEM0RTSV9URVhMRF9CSUFTKSB7CiAgICAgICAgICBiaWFzID0gVFJVRTsKICAgICAgfQogIH0KICBzaGFkZXJfaHdfc2FtcGxlKGFyZywgcmVnX3NhbXBsZXJfY29kZSwgcmVnX2Rlc3QsIHJlZ19jb29yZCwgcHJvamVjdGVkLCBiaWFzKTsKfQoKdm9pZCBwc2hhZGVyX2h3X3RleGNvb3JkKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKCiAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCogVGhpcyA9IChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCopIGFyZy0+c2hhZGVyOwogICAgRFdPUkQgZHN0ID0gYXJnLT5kc3Q7CiAgICBTSEFERVJfQlVGRkVSKiBidWZmZXIgPSBhcmctPmJ1ZmZlcjsKICAgIERXT1JEIGhleF92ZXJzaW9uID0gVGhpcy0+YmFzZVNoYWRlci5oZXhfdmVyc2lvbjsKCiAgICBjaGFyIHRtcFsyMF07CiAgICBzaGFkZXJfYXJiX2dldF93cml0ZV9tYXNrKGFyZywgZHN0LCB0bXApOwogICAgaWYgKGhleF92ZXJzaW9uICE9IFdJTkVEM0RQU19WRVJTSU9OKDEsNCkpIHsKICAgICAgICBEV09SRCByZWcgPSBkc3QgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTU9WX1NBVCBUJXUlcywgZnJhZ21lbnQudGV4Y29vcmRbJXVdO1xuIiwgcmVnLCB0bXAsIHJlZyk7CiAgICB9IGVsc2UgewogICAgICAgIERXT1JEIHJlZzEgPSBkc3QgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICAgICAgY2hhciByZWdfc3JjWzQwXTsKCiAgICAgICAgcHNoYWRlcl9nZW5faW5wdXRfbW9kaWZpZXJfbGluZShhcmctPnNoYWRlciwgYnVmZmVyLCBhcmctPnNyY1swXSwgMCwgcmVnX3NyYyk7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTU9WIFIldSVzLCAlcztcbiIsIHJlZzEsIHRtcCwgcmVnX3NyYyk7CiAgIH0KfQoKdm9pZCBwc2hhZGVyX2h3X3RleHJlZzJhcihTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CgogICAgIFNIQURFUl9CVUZGRVIqIGJ1ZmZlciA9IGFyZy0+YnVmZmVyOwogICAgIElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsKiBUaGlzID0gKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsKikgYXJnLT5zaGFkZXI7CiAgICAgSVdpbmVEM0REZXZpY2VJbXBsKiBkZXZpY2VJbXBsID0gKElXaW5lRDNERGV2aWNlSW1wbCopIFRoaXMtPmJhc2VTaGFkZXIuZGV2aWNlOwogICAgIERXT1JEIGZsYWdzOwoKICAgICBEV09SRCByZWcxID0gYXJnLT5kc3QgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICAgY2hhciBkc3Rfc3RyWzhdOwogICAgIGNoYXIgc3JjX3N0cls1MF07CgogICAgIHNwcmludGYoZHN0X3N0ciwgIlQldSIsIHJlZzEpOwogICAgIHBzaGFkZXJfZ2VuX2lucHV0X21vZGlmaWVyX2xpbmUoYXJnLT5zaGFkZXIsIGJ1ZmZlciwgYXJnLT5zcmNbMF0sIDAsIHNyY19zdHIpOwogICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIk1PViBUTVAuciwgJXMuYTtcbiIsIHNyY19zdHIpOwogICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIk1PViBUTVAuZywgJXMucjtcbiIsIHNyY19zdHIpOwogICAgIGZsYWdzID0gcmVnMSA8IE1BWF9URVhUVVJFUyA/IGRldmljZUltcGwtPnN0YXRlQmxvY2stPnRleHR1cmVTdGF0ZVtyZWcxXVtXSU5FRDNEVFNTX1RFWFRVUkVUUkFOU0ZPUk1GTEFHU10gOiAwOwogICAgIHNoYWRlcl9od19zYW1wbGUoYXJnLCByZWcxLCBkc3Rfc3RyLCAiVE1QIiwgZmxhZ3MgJiBXSU5FRDNEVFRGRl9QUk9KRUNURUQsIEZBTFNFKTsKfQoKdm9pZCBwc2hhZGVyX2h3X3RleHJlZzJnYihTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CgogICAgIFNIQURFUl9CVUZGRVIqIGJ1ZmZlciA9IGFyZy0+YnVmZmVyOwoKICAgICBEV09SRCByZWcxID0gYXJnLT5kc3QgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICAgY2hhciBkc3Rfc3RyWzhdOwogICAgIGNoYXIgc3JjX3N0cls1MF07CgogICAgIHNwcmludGYoZHN0X3N0ciwgIlQldSIsIHJlZzEpOwogICAgIHBzaGFkZXJfZ2VuX2lucHV0X21vZGlmaWVyX2xpbmUoYXJnLT5zaGFkZXIsIGJ1ZmZlciwgYXJnLT5zcmNbMF0sIDAsIHNyY19zdHIpOwogICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIk1PViBUTVAuciwgJXMuZztcbiIsIHNyY19zdHIpOwogICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIk1PViBUTVAuZywgJXMuYjtcbiIsIHNyY19zdHIpOwogICAgIHNoYWRlcl9od19zYW1wbGUoYXJnLCByZWcxLCBkc3Rfc3RyLCAiVE1QIiwgRkFMU0UsIEZBTFNFKTsKfQoKdm9pZCBwc2hhZGVyX2h3X3RleHJlZzJyZ2IoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewoKICAgIFNIQURFUl9CVUZGRVIqIGJ1ZmZlciA9IGFyZy0+YnVmZmVyOwogICAgRFdPUkQgcmVnMSA9IGFyZy0+ZHN0ICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgY2hhciBkc3Rfc3RyWzhdOwogICAgY2hhciBzcmNfc3RyWzUwXTsKCiAgICBzcHJpbnRmKGRzdF9zdHIsICJUJXUiLCByZWcxKTsKICAgIHBzaGFkZXJfZ2VuX2lucHV0X21vZGlmaWVyX2xpbmUoYXJnLT5zaGFkZXIsIGJ1ZmZlciwgYXJnLT5zcmNbMF0sIDAsIHNyY19zdHIpOwogICAgc2hhZGVyX2h3X3NhbXBsZShhcmcsIHJlZzEsIGRzdF9zdHIsIHNyY19zdHIsIEZBTFNFLCBGQUxTRSk7Cn0KCnZvaWQgcHNoYWRlcl9od190ZXhiZW0oU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgSVdpbmVEM0RQaXhlbFNoYWRlckltcGwqIFRoaXMgPSAoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwqKSBhcmctPnNoYWRlcjsKICAgIEJPT0wgaGFzX2J1bXBtYXQgPSBGQUxTRTsKICAgIEJPT0wgaGFzX2x1bWluYW5jZSA9IEZBTFNFOwogICAgaW50IGk7CgogICAgRFdPUkQgZHN0ID0gYXJnLT5kc3Q7CiAgICBEV09SRCBzcmMgPSBhcmctPnNyY1swXSAmIFdJTkVEM0RTUF9SRUdOVU1fTUFTSzsKICAgIFNIQURFUl9CVUZGRVIqIGJ1ZmZlciA9IGFyZy0+YnVmZmVyOwoKICAgIGNoYXIgcmVnX2Nvb3JkWzQwXTsKICAgIERXT1JEIHJlZ19kZXN0X2NvZGU7CgogICAgLyogQWxsIHZlcnNpb25zIGhhdmUgYSBkZXN0aW5hdGlvbiByZWdpc3RlciAqLwogICAgcmVnX2Rlc3RfY29kZSA9IGRzdCAmIFdJTkVEM0RTUF9SRUdOVU1fTUFTSzsKICAgIC8qIENhbiBkaXJlY3RseSB1c2UgdGhlIG5hbWUgYmVjYXVzZSB0ZXhiZW0gaXMgb25seSB2YWxpZCBmb3IgPD0gMS4zIHNoYWRlcnMgKi8KICAgIHBzaGFkZXJfZ2V0X3JlZ2lzdGVyX25hbWUoYXJnLT5zaGFkZXIsIGRzdCwgcmVnX2Nvb3JkKTsKCiAgICBmb3IoaSA9IDA7IGkgPCBUaGlzLT5udW1idW1wZW52bWF0Y29uc3RzOyBpKyspIHsKICAgICAgICBpZihUaGlzLT5idW1wZW52bWF0Y29uc3RbaV0uY29uc3RfbnVtICE9IC0xICYmIHJlZ19kZXN0X2NvZGUgPT0gVGhpcy0+YnVtcGVudm1hdGNvbnN0W2ldLnRleHVuaXQpIHsKICAgICAgICAgICAgaGFzX2J1bXBtYXQgPSBUUlVFOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiAgICBmb3IoaSA9IDA7IGkgPCBUaGlzLT5udW1idW1wZW52bWF0Y29uc3RzOyBpKyspIHsKICAgICAgICBpZihUaGlzLT5sdW1pbmFuY2Vjb25zdFtpXS5jb25zdF9udW0gIT0gLTEgJiYgcmVnX2Rlc3RfY29kZSA9PSBUaGlzLT5sdW1pbmFuY2Vjb25zdFtpXS50ZXh1bml0KSB7CiAgICAgICAgICAgIGhhc19sdW1pbmFuY2UgPSBUUlVFOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgaWYoaGFzX2J1bXBtYXQpIHsKICAgICAgICAvKiBTYW1wbGluZyB0aGUgcGVydHVyYmF0aW9uIG1hcCBpbiBUc3JjIHdhcyBkb25lIGFscmVhZHksIGluY2x1ZGluZyB0aGUgc2lnbmVkbmVzcyBjb3JyZWN0aW9uIGlmIG5lZWRlZCAqLwoKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJTV1ogVE1QMiwgYnVtcGVudm1hdCVkLCB4LCB6LCAwLCAwO1xuIiwgcmVnX2Rlc3RfY29kZSk7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiRFAzIFRNUC5yLCBUTVAyLCBUJXU7XG4iLCBzcmMpOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlNXWiBUTVAyLCBidW1wZW52bWF0JWQsIHksIHcsIDAsIDA7XG4iLCByZWdfZGVzdF9jb2RlKTsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJEUDMgVE1QLmcsIFRNUDIsIFQldTtcbiIsIHNyYyk7CgogICAgICAgIC8qIHdpdGggcHJvamVjdGl2ZSB0ZXh0dXJlcywgdGV4YmVtIG9ubHkgZGl2aWRlcyB0aGUgc3RhdGljIHRleHR1cmUgY29vcmQsIG5vdCB0aGUgZGlzcGxhY2VtZW50LAogICAgICAgICAqIHNvIHdlIGNhbid0IGxldCB0aGUgR0wgaGFuZGxlIHRoaXMuCiAgICAgICAgICovCiAgICAgICAgaWYgKCgoSVdpbmVEM0REZXZpY2VJbXBsKikgVGhpcy0+YmFzZVNoYWRlci5kZXZpY2UpLT5zdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbcmVnX2Rlc3RfY29kZV1bV0lORUQzRFRTU19URVhUVVJFVFJBTlNGT1JNRkxBR1NdCiAgICAgICAgICAgICAgJiBXSU5FRDNEVFRGRl9QUk9KRUNURUQpIHsKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiUkNQIFRNUDIuYSwgJXMuYTtcbiIsIHJlZ19jb29yZCk7CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIk1VTCBUTVAyLnJnLCAlcywgVE1QMi5hO1xuIiwgcmVnX2Nvb3JkKTsKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiQUREIFRNUC5yZywgVE1QLCBUTVAyO1xuIik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiQUREIFRNUC5yZywgVE1QLCAlcztcbiIsIHJlZ19jb29yZCk7CiAgICAgICAgfQoKICAgICAgICBzaGFkZXJfaHdfc2FtcGxlKGFyZywgcmVnX2Rlc3RfY29kZSwgcmVnX2Nvb3JkLCAiVE1QIiwgRkFMU0UsIEZBTFNFKTsKCiAgICAgICAgaWYoYXJnLT5vcGNvZGUtPm9wY29kZSA9PSBXSU5FRDNEU0lPX1RFWEJFTUwgJiYgaGFzX2x1bWluYW5jZSkgewogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJNQUQgVE1QLCBUJXUueiwgbHVtaW5hbmNlJWQueCwgbHVtaW5hbmNlJWQueTtcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNyYywgcmVnX2Rlc3RfY29kZSwgcmVnX2Rlc3RfY29kZSk7CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIk1VTCAlcywgJXMsIFRNUDtcbiIsIHJlZ19jb29yZCwgcmVnX2Nvb3JkKTsKICAgICAgICB9CgogICAgfSBlbHNlIHsKICAgICAgICBEV09SRCB0ZjsKICAgICAgICBpZihyZWdfZGVzdF9jb2RlIDwgTUFYX1RFWFRVUkVTKSB7CiAgICAgICAgICAgIHRmID0gKChJV2luZUQzRERldmljZUltcGwqKSBUaGlzLT5iYXNlU2hhZGVyLmRldmljZSktPnN0YXRlQmxvY2stPnRleHR1cmVTdGF0ZVtyZWdfZGVzdF9jb2RlXVtXSU5FRDNEVFNTX1RFWFRVUkVUUkFOU0ZPUk1GTEFHU107CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGYgPSAwOwogICAgICAgIH0KICAgICAgICAvKiBXaXRob3V0IGEgYnVtcCBtYXRyaXggbG9hZGVkLCBqdXN0IHNhbXBsZSB3aXRoIHRoZSB1bm1vZGlmaWVkIGNvb3JkaW5hdGVzICovCiAgICAgICAgc2hhZGVyX2h3X3NhbXBsZShhcmcsIHJlZ19kZXN0X2NvZGUsIHJlZ19jb29yZCwgcmVnX2Nvb3JkLCB0ZiAmIFdJTkVEM0RUVEZGX1BST0pFQ1RFRCwgRkFMU0UpOwogICAgfQp9Cgp2b2lkIHBzaGFkZXJfaHdfdGV4bTN4MnBhZChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CgogICAgRFdPUkQgcmVnID0gYXJnLT5kc3QgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICBTSEFERVJfQlVGRkVSKiBidWZmZXIgPSBhcmctPmJ1ZmZlcjsKICAgIGNoYXIgc3JjMF9uYW1lWzUwXTsKCiAgICBwc2hhZGVyX2dlbl9pbnB1dF9tb2RpZmllcl9saW5lKGFyZy0+c2hhZGVyLCBidWZmZXIsIGFyZy0+c3JjWzBdLCAwLCBzcmMwX25hbWUpOwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiRFAzIFRNUC54LCBUJXUsICVzO1xuIiwgcmVnLCBzcmMwX25hbWUpOwp9Cgp2b2lkIHBzaGFkZXJfaHdfdGV4bTN4MnRleChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CgogICAgSVdpbmVEM0RQaXhlbFNoYWRlckltcGwqIFRoaXMgPSAoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwqKSBhcmctPnNoYWRlcjsKICAgIElXaW5lRDNERGV2aWNlSW1wbCogZGV2aWNlSW1wbCA9IChJV2luZUQzRERldmljZUltcGwqKSBUaGlzLT5iYXNlU2hhZGVyLmRldmljZTsKICAgIERXT1JEIGZsYWdzOwogICAgRFdPUkQgcmVnID0gYXJnLT5kc3QgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICBTSEFERVJfQlVGRkVSKiBidWZmZXIgPSBhcmctPmJ1ZmZlcjsKICAgIGNoYXIgZHN0X3N0cls4XTsKICAgIGNoYXIgc3JjMF9uYW1lWzUwXTsKCiAgICBzcHJpbnRmKGRzdF9zdHIsICJUJXUiLCByZWcpOwogICAgcHNoYWRlcl9nZW5faW5wdXRfbW9kaWZpZXJfbGluZShhcmctPnNoYWRlciwgYnVmZmVyLCBhcmctPnNyY1swXSwgMCwgc3JjMF9uYW1lKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIkRQMyBUTVAueSwgVCV1LCAlcztcbiIsIHJlZywgc3JjMF9uYW1lKTsKICAgIGZsYWdzID0gcmVnIDwgTUFYX1RFWFRVUkVTID8gZGV2aWNlSW1wbC0+c3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlW3JlZ11bV0lORUQzRFRTU19URVhUVVJFVFJBTlNGT1JNRkxBR1NdIDogMDsKICAgIHNoYWRlcl9od19zYW1wbGUoYXJnLCByZWcsIGRzdF9zdHIsICJUTVAiLCBmbGFncyAmIFdJTkVEM0RUVEZGX1BST0pFQ1RFRCwgRkFMU0UpOwp9Cgp2b2lkIHBzaGFkZXJfaHdfdGV4bTN4M3BhZChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CgogICAgSVdpbmVEM0RQaXhlbFNoYWRlckltcGwqIFRoaXMgPSAoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwqKSBhcmctPnNoYWRlcjsKICAgIERXT1JEIHJlZyA9IGFyZy0+ZHN0ICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBTSEFERVJfUEFSU0VfU1RBVEUqIGN1cnJlbnRfc3RhdGUgPSAmVGhpcy0+YmFzZVNoYWRlci5wYXJzZV9zdGF0ZTsKICAgIGNoYXIgc3JjMF9uYW1lWzUwXTsKCiAgICBwc2hhZGVyX2dlbl9pbnB1dF9tb2RpZmllcl9saW5lKGFyZy0+c2hhZGVyLCBidWZmZXIsIGFyZy0+c3JjWzBdLCAwLCBzcmMwX25hbWUpOwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiRFAzIFRNUC4lYywgVCV1LCAlcztcbiIsICd4JyArIGN1cnJlbnRfc3RhdGUtPmN1cnJlbnRfcm93LCByZWcsIHNyYzBfbmFtZSk7CiAgICBjdXJyZW50X3N0YXRlLT50ZXhjb29yZF93W2N1cnJlbnRfc3RhdGUtPmN1cnJlbnRfcm93KytdID0gcmVnOwp9Cgp2b2lkIHBzaGFkZXJfaHdfdGV4bTN4M3RleChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CgogICAgSVdpbmVEM0RQaXhlbFNoYWRlckltcGwqIFRoaXMgPSAoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwqKSBhcmctPnNoYWRlcjsKICAgIElXaW5lRDNERGV2aWNlSW1wbCogZGV2aWNlSW1wbCA9IChJV2luZUQzRERldmljZUltcGwqKSBUaGlzLT5iYXNlU2hhZGVyLmRldmljZTsKICAgIERXT1JEIGZsYWdzOwogICAgRFdPUkQgcmVnID0gYXJnLT5kc3QgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICBTSEFERVJfQlVGRkVSKiBidWZmZXIgPSBhcmctPmJ1ZmZlcjsKICAgIFNIQURFUl9QQVJTRV9TVEFURSogY3VycmVudF9zdGF0ZSA9ICZUaGlzLT5iYXNlU2hhZGVyLnBhcnNlX3N0YXRlOwogICAgY2hhciBkc3Rfc3RyWzhdOwogICAgY2hhciBzcmMwX25hbWVbNTBdOwoKICAgIHBzaGFkZXJfZ2VuX2lucHV0X21vZGlmaWVyX2xpbmUoYXJnLT5zaGFkZXIsIGJ1ZmZlciwgYXJnLT5zcmNbMF0sIDAsIHNyYzBfbmFtZSk7CiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJEUDMgVE1QLnosIFQldSwgJXM7XG4iLCByZWcsIHNyYzBfbmFtZSk7CgogICAgLyogU2FtcGxlIHRoZSB0ZXh0dXJlIHVzaW5nIHRoZSBjYWxjdWxhdGVkIGNvb3JkaW5hdGVzICovCiAgICBzcHJpbnRmKGRzdF9zdHIsICJUJXUiLCByZWcpOwogICAgZmxhZ3MgPSByZWcgPCBNQVhfVEVYVFVSRVMgPyBkZXZpY2VJbXBsLT5zdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbcmVnXVtXSU5FRDNEVFNTX1RFWFRVUkVUUkFOU0ZPUk1GTEFHU10gOiAwOwogICAgc2hhZGVyX2h3X3NhbXBsZShhcmcsIHJlZywgZHN0X3N0ciwgIlRNUCIsIGZsYWdzICYgV0lORUQzRFRURkZfUFJPSkVDVEVELCBGQUxTRSk7CiAgICBjdXJyZW50X3N0YXRlLT5jdXJyZW50X3JvdyA9IDA7Cn0KCnZvaWQgcHNoYWRlcl9od190ZXhtM3gzdnNwZWMoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewoKICAgIElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsKiBUaGlzID0gKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsKikgYXJnLT5zaGFkZXI7CiAgICBJV2luZUQzRERldmljZUltcGwqIGRldmljZUltcGwgPSAoSVdpbmVEM0REZXZpY2VJbXBsKikgVGhpcy0+YmFzZVNoYWRlci5kZXZpY2U7CiAgICBEV09SRCBmbGFnczsKICAgIERXT1JEIHJlZyA9IGFyZy0+ZHN0ICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBTSEFERVJfUEFSU0VfU1RBVEUqIGN1cnJlbnRfc3RhdGUgPSAmVGhpcy0+YmFzZVNoYWRlci5wYXJzZV9zdGF0ZTsKICAgIGNoYXIgZHN0X3N0cls4XTsKICAgIGNoYXIgc3JjMF9uYW1lWzUwXTsKCiAgICBwc2hhZGVyX2dlbl9pbnB1dF9tb2RpZmllcl9saW5lKGFyZy0+c2hhZGVyLCBidWZmZXIsIGFyZy0+c3JjWzBdLCAwLCBzcmMwX25hbWUpOwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiRFAzIFRNUC56LCBUJXUsICVzO1xuIiwgcmVnLCBzcmMwX25hbWUpOwoKICAgIC8qIENvbnN0cnVjdCB0aGUgZXllLXJheSB2ZWN0b3IgZnJvbSB3IGNvb3JkaW5hdGVzICovCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJNT1YgVE1QMi54LCBmcmFnbWVudC50ZXhjb29yZFsldV0udztcbiIsIGN1cnJlbnRfc3RhdGUtPnRleGNvb3JkX3dbMF0pOwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTU9WIFRNUDIueSwgZnJhZ21lbnQudGV4Y29vcmRbJXVdLnc7XG4iLCBjdXJyZW50X3N0YXRlLT50ZXhjb29yZF93WzFdKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIk1PViBUTVAyLnosIGZyYWdtZW50LnRleGNvb3JkWyV1XS53O1xuIiwgcmVnKTsKCiAgICAvKiBDYWxjdWxhdGUgcmVmbGVjdGlvbiB2ZWN0b3IKICAgICAqLwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiRFAzIFRNUC53LCBUTVAsIFRNUDI7XG4iKTsKICAgIC8qIFRoZSAudyBpcyBpZ25vcmVkIHdoZW4gc2FtcGxpbmcsIHNvIEkgY2FuIHVzZSBUTVAyLncgdG8gY2FsY3VsYXRlIGRvdChOLCBOKSAqLwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiRFAzIFRNUDIudywgVE1QLCBUTVA7XG4iKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlJDUCBUTVAyLncsIFRNUDIudztcbiIpOwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTVVMIFRNUC53LCBUTVAudywgVE1QMi53O1xuIik7CiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJNVUwgVE1QLCBUTVAudywgVE1QO1xuIik7CiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJNQUQgVE1QLCBjb2VmbXVsLngsIFRNUCwgLVRNUDI7XG4iKTsKCiAgICAvKiBTYW1wbGUgdGhlIHRleHR1cmUgdXNpbmcgdGhlIGNhbGN1bGF0ZWQgY29vcmRpbmF0ZXMgKi8KICAgIHNwcmludGYoZHN0X3N0ciwgIlQldSIsIHJlZyk7CiAgICBmbGFncyA9IHJlZyA8IE1BWF9URVhUVVJFUyA/IGRldmljZUltcGwtPnN0YXRlQmxvY2stPnRleHR1cmVTdGF0ZVtyZWddW1dJTkVEM0RUU1NfVEVYVFVSRVRSQU5TRk9STUZMQUdTXSA6IDA7CiAgICBzaGFkZXJfaHdfc2FtcGxlKGFyZywgcmVnLCBkc3Rfc3RyLCAiVE1QIiwgZmxhZ3MgJiBXSU5FRDNEVFRGRl9QUk9KRUNURUQsIEZBTFNFKTsKICAgIGN1cnJlbnRfc3RhdGUtPmN1cnJlbnRfcm93ID0gMDsKfQoKdm9pZCBwc2hhZGVyX2h3X3RleG0zeDNzcGVjKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKCiAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCogVGhpcyA9IChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCopIGFyZy0+c2hhZGVyOwogICAgSVdpbmVEM0REZXZpY2VJbXBsKiBkZXZpY2VJbXBsID0gKElXaW5lRDNERGV2aWNlSW1wbCopIFRoaXMtPmJhc2VTaGFkZXIuZGV2aWNlOwogICAgRFdPUkQgZmxhZ3M7CiAgICBEV09SRCByZWcgPSBhcmctPmRzdCAmIFdJTkVEM0RTUF9SRUdOVU1fTUFTSzsKICAgIERXT1JEIHJlZzMgPSBhcmctPnNyY1sxXSAmIFdJTkVEM0RTUF9SRUdOVU1fTUFTSzsKICAgIFNIQURFUl9QQVJTRV9TVEFURSogY3VycmVudF9zdGF0ZSA9ICZUaGlzLT5iYXNlU2hhZGVyLnBhcnNlX3N0YXRlOwogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBjaGFyIGRzdF9zdHJbOF07CiAgICBjaGFyIHNyYzBfbmFtZVs1MF07CgogICAgcHNoYWRlcl9nZW5faW5wdXRfbW9kaWZpZXJfbGluZShhcmctPnNoYWRlciwgYnVmZmVyLCBhcmctPnNyY1swXSwgMCwgc3JjMF9uYW1lKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIkRQMyBUTVAueiwgVCV1LCAlcztcbiIsIHJlZywgc3JjMF9uYW1lKTsKCiAgICAvKiBDYWxjdWxhdGUgcmVmbGVjdGlvbiB2ZWN0b3IuCiAgICAgKgogICAgICogICAgICAgICAgICAgICBkb3QoTiwgRSkKICAgICAqIFRNUC54eXogPSAyICogLS0tLS0tLS0tICogTiAtIEUKICAgICAqICAgICAgICAgICAgICAgZG90KE4sIE4pCiAgICAgKgogICAgICogV2hpY2ggbm9ybWFsaXplcyB0aGUgbm9ybWFsIHZlY3RvcgogICAgICovCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJEUDMgVE1QLncsIFRNUCwgQ1sldV07XG4iLCByZWczKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIkRQMyBUTVAyLncsIFRNUCwgVE1QO1xuIik7CiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJSQ1AgVE1QMi53LCBUTVAyLnc7XG4iKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIk1VTCBUTVAudywgVE1QLncsIFRNUDIudztcbiIpOwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTVVMIFRNUCwgVE1QLncsIFRNUDtcbiIpOwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTUFEIFRNUCwgY29lZm11bC54LCBUTVAsIC1DWyV1XTtcbiIsIHJlZzMpOwoKICAgIC8qIFNhbXBsZSB0aGUgdGV4dHVyZSB1c2luZyB0aGUgY2FsY3VsYXRlZCBjb29yZGluYXRlcyAqLwogICAgc3ByaW50Zihkc3Rfc3RyLCAiVCV1IiwgcmVnKTsKICAgIGZsYWdzID0gcmVnIDwgTUFYX1RFWFRVUkVTID8gZGV2aWNlSW1wbC0+c3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlW3JlZ11bV0lORUQzRFRTU19URVhUVVJFVFJBTlNGT1JNRkxBR1NdIDogMDsKICAgIHNoYWRlcl9od19zYW1wbGUoYXJnLCByZWcsIGRzdF9zdHIsICJUTVAiLCBmbGFncyAmIFdJTkVEM0RUVEZGX1BST0pFQ1RFRCwgRkFMU0UpOwogICAgY3VycmVudF9zdGF0ZS0+Y3VycmVudF9yb3cgPSAwOwp9Cgp2b2lkIHBzaGFkZXJfaHdfdGV4ZGVwdGgoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBjaGFyIGRzdF9uYW1lWzUwXTsKCiAgICAvKiB0ZXhkZXB0aCBoYXMgYW4gaW1wbGljaXQgZGVzdGluYXRpb24sIHRoZSBmcmFnbWVudCBkZXB0aCB2YWx1ZS4gSXQncyBvbmx5IHBhcmFtZXRlciwKICAgICAqIHdoaWNoIGlzIGVzc2VudGlhbGx5IGFuIGlucHV0LCBpcyB0aGUgZGVzdGluYXRpb24gcmVnaXN0ZXIgYmVjYXVzZSBpdCBpcyB0aGUgZmlyc3QKICAgICAqIHBhcmFtZXRlci4gQWNjb3JkaW5nIHRvIHRoZSBtc2RuLCB0aGlzIG11c3QgYmUgcmVnaXN0ZXIgcjUsIGJ1dCBsZXQncyBrZWVwIGl0IG1vcmUgZmxleGlibGUKICAgICAqIGhlcmUKICAgICAqLwogICAgcHNoYWRlcl9nZXRfcmVnaXN0ZXJfbmFtZShhcmctPnNoYWRlciwgYXJnLT5kc3QsIGRzdF9uYW1lKTsKCiAgICAvKiBBY2NvcmRpbmcgdG8gdGhlIG1zZG4sIHRoZSBzb3VyY2UgcmVnaXN0ZXIobXVzdCBiZSByNSkgaXMgdW51c2FibGUgYWZ0ZXIKICAgICAqIHRoZSB0ZXhkZXB0aCBpbnN0cnVjdGlvbiwgc28gd2UncmUgZnJlZSB0byBtb2RpZnkgaXQKICAgICAqLwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTUlOICVzLmcsICVzLmcsIG9uZS5nO1xuIiwgZHN0X25hbWUsIGRzdF9uYW1lKTsKCiAgICAvKiBIb3cgdG8gZGVhbCB3aXRoIHRoZSBzcGVjaWFsIGNhc2UgZHN0X25hbWUuZyA9PSAwPyBpZiByICE9IDAsIHRoZW4KICAgICAqIHRoZSByICogKDEgLyAwKSB3aWxsIGdpdmUgaW5maW5pdHksIHdoaWNoIGlzIGNsYW1wZWQgdG8gMS4wLCB0aGUgY29ycmVjdAogICAgICogcmVzdWx0LiBCdXQgaWYgciA9IDAuMCwgdGhlbiAwICogaW5mID0gMCwgd2hpY2ggaXMgaW5jb3JyZWN0LgogICAgICovCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJSQ1AgJXMuZywgJXMuZztcbiIsIGRzdF9uYW1lLCBkc3RfbmFtZSk7CiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJNVUwgVE1QLngsICVzLnIsICVzLmc7XG4iLCBkc3RfbmFtZSwgZHN0X25hbWUpOwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTUlOIFRNUC54LCBUTVAueCwgb25lLnI7XG4iKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIk1BWCByZXN1bHQuZGVwdGgsIFRNUC54LCAwLjA7XG4iKTsKfQoKLyoqIFByb2Nlc3MgdGhlIFdJTkVEM0RTSU9fVEVYRFAzVEVYIGluc3RydWN0aW9uIGluIEFSQjoKICogVGFrZSBhIDMtY29tcG9uZW50IGRvdCBwcm9kdWN0IG9mIHRoZSBUZXhDb29yZFtkc3RyZWddIGFuZCBzcmMsCiAqIHRoZW4gcGVyZm9ybSBhIDFEIHRleHR1cmUgbG9va3VwIGZyb20gc3RhZ2UgZHN0cmVnbnVtLCBwbGFjZSBpbnRvIGRzdC4gKi8Kdm9pZCBwc2hhZGVyX2h3X3RleGRwM3RleChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBTSEFERVJfQlVGRkVSKiBidWZmZXIgPSBhcmctPmJ1ZmZlcjsKICAgIERXT1JEIHNhbXBsZXJfaWR4ID0gYXJnLT5kc3QgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICBjaGFyIHNyYzBbNTBdOwogICAgY2hhciBkc3Rfc3RyWzhdOwoKICAgIHBzaGFkZXJfZ2VuX2lucHV0X21vZGlmaWVyX2xpbmUoYXJnLT5zaGFkZXIsIGJ1ZmZlciwgYXJnLT5zcmNbMF0sIDAsIHNyYzApOwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTU9WIFRNUCwgMC4wO1xuIik7CiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJEUDMgVE1QLngsIFQldSwgJXM7XG4iLCBzYW1wbGVyX2lkeCwgc3JjMCk7CgogICAgc3ByaW50Zihkc3Rfc3RyLCAiVCV1Iiwgc2FtcGxlcl9pZHgpOwogICAgc2hhZGVyX2h3X3NhbXBsZShhcmcsIHNhbXBsZXJfaWR4LCBkc3Rfc3RyLCAiVE1QIiwgRkFMU0UgLyogT25seSBvbmUgY29vcmQsIGNhbid0IGJlIHByb2plY3RlZCAqLywgRkFMU0UpOwp9CgovKiogUHJvY2VzcyB0aGUgV0lORUQzRFNJT19URVhEUDMgaW5zdHJ1Y3Rpb24gaW4gQVJCOgogKiBUYWtlIGEgMy1jb21wb25lbnQgZG90IHByb2R1Y3Qgb2YgdGhlIFRleENvb3JkW2RzdHJlZ10gYW5kIHNyYy4gKi8Kdm9pZCBwc2hhZGVyX2h3X3RleGRwMyhTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBjaGFyIHNyYzBbNTBdOwogICAgY2hhciBkc3Rfc3RyWzUwXTsKICAgIGNoYXIgZHN0X21hc2tbNl07CiAgICBEV09SRCBkc3RyZWcgPSBhcmctPmRzdCAmIFdJTkVEM0RTUF9SRUdOVU1fTUFTSzsKICAgIFNIQURFUl9CVUZGRVIqIGJ1ZmZlciA9IGFyZy0+YnVmZmVyOwoKICAgIC8qIEhhbmRsZSBvdXRwdXQgcmVnaXN0ZXIgKi8KICAgIHBzaGFkZXJfZ2V0X3JlZ2lzdGVyX25hbWUoYXJnLT5zaGFkZXIsIGFyZy0+ZHN0LCBkc3Rfc3RyKTsKICAgIHNoYWRlcl9hcmJfZ2V0X3dyaXRlX21hc2soYXJnLCBhcmctPmRzdCwgZHN0X21hc2spOwoKICAgIHBzaGFkZXJfZ2VuX2lucHV0X21vZGlmaWVyX2xpbmUoYXJnLT5zaGFkZXIsIGJ1ZmZlciwgYXJnLT5zcmNbMF0sIDAsIHNyYzApOwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiRFAzICVzJXMsIFQldSwgJXM7XG4iLCBkc3Rfc3RyLCBkc3RfbWFzaywgZHN0cmVnLCBzcmMwKTsKCiAgICAvKiBUT0RPOiBIYW5kbGUgb3V0cHV0IG1vZGlmaWVycyAqLwp9CgovKiogUHJvY2VzcyB0aGUgV0lORUQzRFNJT19URVhNM1gzIGluc3RydWN0aW9uIGluIEFSQgogKiBQZXJmb3JtIHRoZSAzcmQgcm93IG9mIGEgM3gzIG1hdHJpeCBtdWx0aXBseSAqLwp2b2lkIHBzaGFkZXJfaHdfdGV4bTN4MyhTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBTSEFERVJfQlVGRkVSKiBidWZmZXIgPSBhcmctPmJ1ZmZlcjsKICAgIGNoYXIgZHN0X3N0cls1MF07CiAgICBjaGFyIGRzdF9tYXNrWzZdOwogICAgY2hhciBzcmMwWzUwXTsKICAgIERXT1JEIGRzdF9yZWcgPSBhcmctPmRzdCAmIFdJTkVEM0RTUF9SRUdOVU1fTUFTSzsKCiAgICBwc2hhZGVyX2dldF9yZWdpc3Rlcl9uYW1lKGFyZy0+c2hhZGVyLCBhcmctPmRzdCwgZHN0X3N0cik7CiAgICBzaGFkZXJfYXJiX2dldF93cml0ZV9tYXNrKGFyZywgYXJnLT5kc3QsIGRzdF9tYXNrKTsKCiAgICBwc2hhZGVyX2dlbl9pbnB1dF9tb2RpZmllcl9saW5lKGFyZy0+c2hhZGVyLCBidWZmZXIsIGFyZy0+c3JjWzBdLCAwLCBzcmMwKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIkRQMyBUTVAueiwgVCV1LCAlcztcbiIsIGRzdF9yZWcsIHNyYzApOwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTU9WICVzJXMsIFRNUDtcbiIsIGRzdF9zdHIsIGRzdF9tYXNrKTsKCiAgICAvKiBUT0RPOiBIYW5kbGUgb3V0cHV0IG1vZGlmaWVycyAqLwp9CgovKiogUHJvY2VzcyB0aGUgV0lORUQzRFNJT19URVhNM1gyREVQVEggaW5zdHJ1Y3Rpb24gaW4gQVJCOgogKiBMYXN0IHJvdyBvZiBhIDN4MiBtYXRyaXggbXVsdGlwbHksIHVzZSB0aGUgcmVzdWx0IHRvIGNhbGN1bGF0ZSB0aGUgZGVwdGg6CiAqIENhbGN1bGF0ZSB0bXAwLnkgPSBUZXhDb29yZFtkc3RyZWddIC4gc3JjLnh5ejsgICh0bXAwLnggaGFzIGFscmVhZHkgYmVlbiBjYWxjdWxhdGVkKQogKiBkZXB0aCA9ICh0bXAwLnkgPT0gMC4wKSA/IDEuMCA6IHRtcDAueCAvIHRtcDAueQogKi8Kdm9pZCBwc2hhZGVyX2h3X3RleG0zeDJkZXB0aChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBTSEFERVJfQlVGRkVSKiBidWZmZXIgPSBhcmctPmJ1ZmZlcjsKICAgIERXT1JEIGRzdF9yZWcgPSBhcmctPmRzdCAmIFdJTkVEM0RTUF9SRUdOVU1fTUFTSzsKICAgIGNoYXIgc3JjMFs1MF07CgogICAgcHNoYWRlcl9nZW5faW5wdXRfbW9kaWZpZXJfbGluZShhcmctPnNoYWRlciwgYnVmZmVyLCBhcmctPnNyY1swXSwgMCwgc3JjMCk7CiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJEUDMgVE1QLnksIFQldSwgJXM7XG4iLCBkc3RfcmVnLCBzcmMwKTsKCiAgICAvKiBIb3cgdG8gZGVhbCB3aXRoIHRoZSBzcGVjaWFsIGNhc2UgZHN0X25hbWUuZyA9PSAwPyBpZiByICE9IDAsIHRoZW4KICAgICAqIHRoZSByICogKDEgLyAwKSB3aWxsIGdpdmUgaW5maW5pdHksIHdoaWNoIGlzIGNsYW1wZWQgdG8gMS4wLCB0aGUgY29ycmVjdAogICAgICogcmVzdWx0LiBCdXQgaWYgciA9IDAuMCwgdGhlbiAwICogaW5mID0gMCwgd2hpY2ggaXMgaW5jb3JyZWN0LgogICAgICovCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJSQ1AgVE1QLnksIFRNUC55O1xuIik7CiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJNVUwgVE1QLngsIFRNUC54LCBUTVAueTtcbiIpOwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTUlOIFRNUC54LCBUTVAueCwgb25lLnI7XG4iKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIk1BWCByZXN1bHQuZGVwdGgsIFRNUC54LCAwLjA7XG4iKTsKfQoKLyoqIEhhbmRsZXMgdHJhbnNmb3JtaW5nIGFsbCBXSU5FRDNEU0lPX00/eD8gb3Bjb2RlcyBmb3IKICAgIFZlcnRleC9QaXhlbCBzaGFkZXJzIHRvIEFSQl92ZXJ0ZXhfcHJvZ3JhbSBjb2RlcyAqLwp2b2lkIHNoYWRlcl9od19tbnhuKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKCiAgICBpbnQgaTsKICAgIGludCBuQ29tcG9uZW50cyA9IDA7CiAgICBTSEFERVJfT1BDT0RFX0FSRyB0bXBBcmc7CgogICAgbWVtc2V0KCZ0bXBBcmcsIDAsIHNpemVvZihTSEFERVJfT1BDT0RFX0FSRykpOwoKICAgIC8qIFNldCBjb25zdGFudHMgZm9yIHRoZSB0ZW1wb3JhcnkgYXJndW1lbnQgKi8KICAgIHRtcEFyZy5zaGFkZXIgICAgICA9IGFyZy0+c2hhZGVyOwogICAgdG1wQXJnLmJ1ZmZlciAgICAgID0gYXJnLT5idWZmZXI7CiAgICB0bXBBcmcuc3JjWzBdICAgICAgPSBhcmctPnNyY1swXTsKICAgIHRtcEFyZy5zcmNfYWRkclswXSA9IGFyZy0+c3JjX2FkZHJbMF07CiAgICB0bXBBcmcuc3JjX2FkZHJbMV0gPSBhcmctPnNyY19hZGRyWzFdOwogICAgdG1wQXJnLnJlZ19tYXBzID0gYXJnLT5yZWdfbWFwczsKCiAgICBzd2l0Y2goYXJnLT5vcGNvZGUtPm9wY29kZSkgewogICAgY2FzZSBXSU5FRDNEU0lPX000eDQ6CiAgICAgICAgbkNvbXBvbmVudHMgPSA0OwogICAgICAgIHRtcEFyZy5vcGNvZGUgPSBzaGFkZXJfZ2V0X29wY29kZShhcmctPnNoYWRlciwgV0lORUQzRFNJT19EUDQpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU0lPX000eDM6CiAgICAgICAgbkNvbXBvbmVudHMgPSAzOwogICAgICAgIHRtcEFyZy5vcGNvZGUgPSBzaGFkZXJfZ2V0X29wY29kZShhcmctPnNoYWRlciwgV0lORUQzRFNJT19EUDQpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU0lPX00zeDQ6CiAgICAgICAgbkNvbXBvbmVudHMgPSA0OwogICAgICAgIHRtcEFyZy5vcGNvZGUgPSBzaGFkZXJfZ2V0X29wY29kZShhcmctPnNoYWRlciwgV0lORUQzRFNJT19EUDMpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU0lPX00zeDM6CiAgICAgICAgbkNvbXBvbmVudHMgPSAzOwogICAgICAgIHRtcEFyZy5vcGNvZGUgPSBzaGFkZXJfZ2V0X29wY29kZShhcmctPnNoYWRlciwgV0lORUQzRFNJT19EUDMpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU0lPX00zeDI6CiAgICAgICAgbkNvbXBvbmVudHMgPSAyOwogICAgICAgIHRtcEFyZy5vcGNvZGUgPSBzaGFkZXJfZ2V0X29wY29kZShhcmctPnNoYWRlciwgV0lORUQzRFNJT19EUDMpOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBicmVhazsKICAgIH0KCiAgICBmb3IgKGkgPSAwOyBpIDwgbkNvbXBvbmVudHM7IGkrKykgewogICAgICAgIHRtcEFyZy5kc3QgPSAoKGFyZy0+ZHN0KSAmIH5XSU5FRDNEU1BfV1JJVEVNQVNLX0FMTCl8KFdJTkVEM0RTUF9XUklURU1BU0tfMDw8aSk7CiAgICAgICAgdG1wQXJnLnNyY1sxXSA9IGFyZy0+c3JjWzFdK2k7CiAgICAgICAgdnNoYWRlcl9od19tYXAyZ2woJnRtcEFyZyk7CiAgICB9Cn0KCnZvaWQgdnNoYWRlcl9od19yc3FfcmNwKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIENPTlNUIFNIQURFUl9PUENPREUqIGN1ck9wY29kZSA9IGFyZy0+b3Bjb2RlOwogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBEV09SRCBkc3QgPSBhcmctPmRzdDsKICAgIERXT1JEIHNyYyA9IGFyZy0+c3JjWzBdOwogICAgRFdPUkQgc3dpenpsZSA9IChzcmMgJiBXSU5FRDNEU1BfU1dJWlpMRV9NQVNLKSA+PiBXSU5FRDNEU1BfU1dJWlpMRV9TSElGVDsKCiAgICBjaGFyIHRtcExpbmVbMjU2XTsKCiAgICBzdHJjcHkodG1wTGluZSwgY3VyT3Bjb2RlLT5nbG5hbWUpOyAvKiBPcGNvZGUgKi8KICAgIHZzaGFkZXJfcHJvZ3JhbV9hZGRfcGFyYW0oYXJnLCBkc3QsIEZBTFNFLCB0bXBMaW5lKTsgLyogRGVzdGluYXRpb24gKi8KICAgIHN0cmNhdCh0bXBMaW5lLCAiLCIpOwogICAgdnNoYWRlcl9wcm9ncmFtX2FkZF9wYXJhbShhcmcsIHNyYywgVFJVRSwgdG1wTGluZSk7CiAgICBpZiAoKFdJTkVEM0RTUF9OT1NXSVpaTEUgPj4gV0lORUQzRFNQX1NXSVpaTEVfU0hJRlQpID09IHN3aXp6bGUpIHsKICAgICAgICAvKiBEeCBzZGsgc2F5cyAueCBpcyB1c2VkIGlmIG5vIHN3aXp6bGUgaXMgZ2l2ZW4sIGJ1dCBvdXIgdGVzdCBzaG93cyB0aGF0CiAgICAgICAgICogLncgaXMgdXNlZAogICAgICAgICAqLwogICAgICAgIHN0cmNhdCh0bXBMaW5lLCAiLnciKTsKICAgIH0KCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICIlcztcbiIsIHRtcExpbmUpOwp9Cgp2b2lkIHNoYWRlcl9od19ucm0oU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBjaGFyIGRzdF9uYW1lWzUwXTsKICAgIGNoYXIgc3JjX25hbWVbNTBdOwogICAgY2hhciBkc3Rfd21hc2tbMjBdOwogICAgRFdPUkQgc2hpZnQgPSAoYXJnLT5kc3QgJiBXSU5FRDNEU1BfRFNUU0hJRlRfTUFTSykgPj4gV0lORUQzRFNQX0RTVFNISUZUX1NISUZUOwogICAgQk9PTCBzYXQgPSAoYXJnLT5kc3QgJiBXSU5FRDNEU1BfRFNUTU9EX01BU0spICYgV0lORUQzRFNQRE1fU0FUVVJBVEU7CgogICAgcHNoYWRlcl9nZXRfcmVnaXN0ZXJfbmFtZShhcmctPnNoYWRlciwgYXJnLT5kc3QsIGRzdF9uYW1lKTsKICAgIHNoYWRlcl9hcmJfZ2V0X3dyaXRlX21hc2soYXJnLCBhcmctPmRzdCwgZHN0X3dtYXNrKTsKCiAgICBwc2hhZGVyX2dlbl9pbnB1dF9tb2RpZmllcl9saW5lKGFyZy0+c2hhZGVyLCBidWZmZXIsIGFyZy0+c3JjWzBdLCAwLCBzcmNfbmFtZSk7CiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJEUDMgVE1QLCAlcywgJXM7XG4iLCBzcmNfbmFtZSwgc3JjX25hbWUpOwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiUlNRIFRNUCwgVE1QLng7XG4iKTsKICAgIC8qIGRzdC53ID0gc3JjWzBdLncgKiAxIC8gKHNyYy54XjIgKyBzcmMueV4yICsgc3JjLnpeMileKDEvMikgYWNjb3JkaW5nIHRvIG1zZG4qLwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTVVMJXMgJXMlcywgJXMsIFRNUDtcbiIsIHNhdCA/ICJfU0FUIiA6ICIiLCBkc3RfbmFtZSwgZHN0X3dtYXNrLAogICAgICAgICAgICAgICAgICAgc3JjX25hbWUpOwoKICAgIGlmIChzaGlmdCAhPSAwKQogICAgICAgIHBzaGFkZXJfZ2VuX291dHB1dF9tb2RpZmllcl9saW5lKGJ1ZmZlciwgRkFMU0UsIGRzdF93bWFzaywgc2hpZnQsIGRzdF9uYW1lKTsKfQoKdm9pZCBzaGFkZXJfaHdfc2luY29zKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIC8qIFRoaXMgaW5zdHJ1Y3Rpb24gZXhpc3RzIGluIEFSQiwgYnV0IHRoZSBkM2QgaW5zdHJ1Y3Rpb24gdGFrZXMgdHdvIGV4dHJhIHBhcmFtZXRlcnMgd2hpY2gKICAgICAqIG11c3QgY29udGFpbiBmaXhlZCBjb25zdGFudHMuIFNvIHdlIG5lZWQgYSBzZXBhcmF0ZSBmdW5jdGlvbiB0byBmaWx0ZXIgdGhvc2UgY29uc3RhbnRzIGFuZAogICAgICogY2FuJ3QgdXNlIG1hcDJnbAogICAgICovCiAgICBTSEFERVJfQlVGRkVSKiBidWZmZXIgPSBhcmctPmJ1ZmZlcjsKICAgIGNoYXIgZHN0X25hbWVbNTBdOwogICAgY2hhciBzcmNfbmFtZVs1MF07CiAgICBjaGFyIGRzdF93bWFza1syMF07CiAgICBEV09SRCBzaGlmdCA9IChhcmctPmRzdCAmIFdJTkVEM0RTUF9EU1RTSElGVF9NQVNLKSA+PiBXSU5FRDNEU1BfRFNUU0hJRlRfU0hJRlQ7CiAgICBCT09MIHNhdCA9IChhcmctPmRzdCAmIFdJTkVEM0RTUF9EU1RNT0RfTUFTSykgJiBXSU5FRDNEU1BETV9TQVRVUkFURTsKCiAgICBwc2hhZGVyX2dldF9yZWdpc3Rlcl9uYW1lKGFyZy0+c2hhZGVyLCBhcmctPmRzdCwgZHN0X25hbWUpOwogICAgc2hhZGVyX2FyYl9nZXRfd3JpdGVfbWFzayhhcmcsIGFyZy0+ZHN0LCBkc3Rfd21hc2spOwoKICAgIHBzaGFkZXJfZ2VuX2lucHV0X21vZGlmaWVyX2xpbmUoYXJnLT5zaGFkZXIsIGJ1ZmZlciwgYXJnLT5zcmNbMF0sIDAsIHNyY19uYW1lKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlNDUyVzICVzJXMsICVzO1xuIiwgc2F0ID8gIl9TQVQiIDogIiIsIGRzdF9uYW1lLCBkc3Rfd21hc2ssCiAgICAgICAgICAgICAgICAgICBzcmNfbmFtZSk7CgogICAgaWYgKHNoaWZ0ICE9IDApCiAgICAgICAgcHNoYWRlcl9nZW5fb3V0cHV0X21vZGlmaWVyX2xpbmUoYnVmZmVyLCBGQUxTRSwgZHN0X3dtYXNrLCBzaGlmdCwgZHN0X25hbWUpOwoKfQoKLyogVE9ETzogbWVyZ2Ugd2l0aCBwaXhlbCBzaGFkZXIgKi8KLyogTWFwIHRoZSBvcGNvZGUgMS10by0xIHRvIHRoZSBHTCBjb2RlICovCnZvaWQgdnNoYWRlcl9od19tYXAyZ2woU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewoKICAgIElXaW5lRDNEVmVydGV4U2hhZGVySW1wbCAqc2hhZGVyID0gKElXaW5lRDNEVmVydGV4U2hhZGVySW1wbCopIGFyZy0+c2hhZGVyOwogICAgQ09OU1QgU0hBREVSX09QQ09ERSogY3VyT3Bjb2RlID0gYXJnLT5vcGNvZGU7CiAgICBTSEFERVJfQlVGRkVSKiBidWZmZXIgPSBhcmctPmJ1ZmZlcjsKICAgIERXT1JEIGRzdCA9IGFyZy0+ZHN0OwogICAgRFdPUkQqIHNyYyA9IGFyZy0+c3JjOwoKICAgIERXT1JEIGRzdF9yZWd0eXBlID0gc2hhZGVyX2dldF9yZWd0eXBlKGRzdCk7CiAgICBjaGFyIHRtcExpbmVbMjU2XTsKICAgIHVuc2lnbmVkIGludCBpOwoKICAgIGlmICgoY3VyT3Bjb2RlLT5vcGNvZGUgPT0gV0lORUQzRFNJT19NT1YgJiYgZHN0X3JlZ3R5cGUgPT0gV0lORUQzRFNQUl9BRERSKSB8fCBjdXJPcGNvZGUtPm9wY29kZSA9PSBXSU5FRDNEU0lPX01PVkEpIHsKICAgICAgICBpZihzaGFkZXItPnJlbF9vZmZzZXQpIHsKICAgICAgICAgICAgbWVtc2V0KHRtcExpbmUsIDAsIHNpemVvZih0bXBMaW5lKSk7CiAgICAgICAgICAgIHZzaGFkZXJfcHJvZ3JhbV9hZGRfcGFyYW0oYXJnLCBzcmNbMF0sIFRSVUUsIHRtcExpbmUpOwogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJBREQgVE1QLngsICVzLCBoZWxwZXJfY29uc3QuejtcbiIsIHRtcExpbmUpOwogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJBUkwgQTAueCwgVE1QLng7XG4iKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN0cmNweSh0bXBMaW5lLCAiQVJMIik7CiAgICAgICAgfQogICAgfSBlbHNlCiAgICAgICAgc3RyY3B5KHRtcExpbmUsIGN1ck9wY29kZS0+Z2xuYW1lKTsKCiAgICBpZiAoY3VyT3Bjb2RlLT5udW1fcGFyYW1zID4gMCkgewogICAgICAgIHZzaGFkZXJfcHJvZ3JhbV9hZGRfcGFyYW0oYXJnLCBkc3QsIEZBTFNFLCB0bXBMaW5lKTsKICAgICAgICBmb3IgKGkgPSAxOyBpIDwgY3VyT3Bjb2RlLT5udW1fcGFyYW1zOyArK2kpIHsKICAgICAgICAgICBzdHJjYXQodG1wTGluZSwgIiwiKTsKICAgICAgICAgICB2c2hhZGVyX3Byb2dyYW1fYWRkX3BhcmFtKGFyZywgc3JjW2ktMV0sIFRSVUUsIHRtcExpbmUpOwogICAgICAgIH0KICAgIH0KICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiJXM7XG4iLCB0bXBMaW5lKTsKfQoKc3RhdGljIEdMdWludCBjcmVhdGVfYXJiX2JsdF92ZXJ0ZXhfcHJvZ3JhbShXaW5lRDNEX0dMX0luZm8gKmdsX2luZm8pIHsKICAgIEdMdWludCBwcm9ncmFtX2lkID0gMDsKICAgIGNvbnN0IGNoYXIgKmJsdF92cHJvZ3JhbSA9CiAgICAgICAgIiEhQVJCdnAxLjBcbiIKICAgICAgICAiUEFSQU0gY1sxXSA9IHsgeyAxLCAwLjUgfSB9O1xuIgogICAgICAgICJNT1YgcmVzdWx0LnBvc2l0aW9uLCB2ZXJ0ZXgucG9zaXRpb247XG4iCiAgICAgICAgIk1PViByZXN1bHQuY29sb3IsIGNbMF0ueDtcbiIKICAgICAgICAiTUFEIHJlc3VsdC50ZXhjb29yZFswXS55LCAtdmVydGV4LnBvc2l0aW9uLCBjWzBdLCBjWzBdO1xuIgogICAgICAgICJNQUQgcmVzdWx0LnRleGNvb3JkWzBdLngsIHZlcnRleC5wb3NpdGlvbiwgY1swXS55LCBjWzBdLnk7XG4iCiAgICAgICAgIkVORFxuIjsKCiAgICBHTF9FWFRDQUxMKGdsR2VuUHJvZ3JhbXNBUkIoMSwgJnByb2dyYW1faWQpKTsKICAgIEdMX0VYVENBTEwoZ2xCaW5kUHJvZ3JhbUFSQihHTF9WRVJURVhfUFJPR1JBTV9BUkIsIHByb2dyYW1faWQpKTsKICAgIEdMX0VYVENBTEwoZ2xQcm9ncmFtU3RyaW5nQVJCKEdMX1ZFUlRFWF9QUk9HUkFNX0FSQiwgR0xfUFJPR1JBTV9GT1JNQVRfQVNDSUlfQVJCLCBzdHJsZW4oYmx0X3Zwcm9ncmFtKSwgYmx0X3Zwcm9ncmFtKSk7CgogICAgaWYgKGdsR2V0RXJyb3IoKSA9PSBHTF9JTlZBTElEX09QRVJBVElPTikgewogICAgICAgIEdMaW50IHBvczsKICAgICAgICBnbEdldEludGVnZXJ2KEdMX1BST0dSQU1fRVJST1JfUE9TSVRJT05fQVJCLCAmcG9zKTsKICAgICAgICBGSVhNRSgiVmVydGV4IHByb2dyYW0gZXJyb3IgYXQgcG9zaXRpb24gJWQ6ICVzXG4iLCBwb3MsCiAgICAgICAgICAgIGRlYnVnc3RyX2EoKGNvbnN0IGNoYXIgKilnbEdldFN0cmluZyhHTF9QUk9HUkFNX0VSUk9SX1NUUklOR19BUkIpKSk7CiAgICB9CgogICAgcmV0dXJuIHByb2dyYW1faWQ7Cn0KCnN0YXRpYyBHTHVpbnQgY3JlYXRlX2FyYl9ibHRfZnJhZ21lbnRfcHJvZ3JhbShXaW5lRDNEX0dMX0luZm8gKmdsX2luZm8pIHsKICAgIEdMdWludCBwcm9ncmFtX2lkID0gMDsKICAgIGNvbnN0IGNoYXIgKmJsdF9mcHJvZ3JhbSA9CiAgICAgICAgIiEhQVJCZnAxLjBcbiIKICAgICAgICAiVEVNUCBSMDtcbiIKICAgICAgICAiVEVYIFIwLngsIGZyYWdtZW50LnRleGNvb3JkWzBdLCB0ZXh0dXJlWzBdLCAyRDtcbiIKICAgICAgICAiTU9WIHJlc3VsdC5kZXB0aC56LCBSMC54O1xuIgogICAgICAgICJFTkRcbiI7CgogICAgR0xfRVhUQ0FMTChnbEdlblByb2dyYW1zQVJCKDEsICZwcm9ncmFtX2lkKSk7CiAgICBHTF9FWFRDQUxMKGdsQmluZFByb2dyYW1BUkIoR0xfRlJBR01FTlRfUFJPR1JBTV9BUkIsIHByb2dyYW1faWQpKTsKICAgIEdMX0VYVENBTEwoZ2xQcm9ncmFtU3RyaW5nQVJCKEdMX0ZSQUdNRU5UX1BST0dSQU1fQVJCLCBHTF9QUk9HUkFNX0ZPUk1BVF9BU0NJSV9BUkIsIHN0cmxlbihibHRfZnByb2dyYW0pLCBibHRfZnByb2dyYW0pKTsKCiAgICBpZiAoZ2xHZXRFcnJvcigpID09IEdMX0lOVkFMSURfT1BFUkFUSU9OKSB7CiAgICAgICAgR0xpbnQgcG9zOwogICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfUFJPR1JBTV9FUlJPUl9QT1NJVElPTl9BUkIsICZwb3MpOwogICAgICAgIEZJWE1FKCJGcmFnbWVudCBwcm9ncmFtIGVycm9yIGF0IHBvc2l0aW9uICVkOiAlc1xuIiwgcG9zLAogICAgICAgICAgICBkZWJ1Z3N0cl9hKChjb25zdCBjaGFyICopZ2xHZXRTdHJpbmcoR0xfUFJPR1JBTV9FUlJPUl9TVFJJTkdfQVJCKSkpOwogICAgfQoKICAgIHJldHVybiBwcm9ncmFtX2lkOwp9CgpzdGF0aWMgdm9pZCBzaGFkZXJfYXJiX3NlbGVjdChJV2luZUQzRERldmljZSAqaWZhY2UsIEJPT0wgdXNlUFMsIEJPT0wgdXNlVlMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFdpbmVEM0RfR0xfSW5mbyAqZ2xfaW5mbyA9ICZUaGlzLT5hZGFwdGVyLT5nbF9pbmZvOwoKICAgIGlmICh1c2VWUykgewogICAgICAgIFRSQUNFKCJVc2luZyB2ZXJ0ZXggc2hhZGVyXG4iKTsKCiAgICAgICAgLyogQmluZCB0aGUgdmVydGV4IHByb2dyYW0gKi8KICAgICAgICBHTF9FWFRDQUxMKGdsQmluZFByb2dyYW1BUkIoR0xfVkVSVEVYX1BST0dSQU1fQVJCLAogICAgICAgICAgICAoKElXaW5lRDNEVmVydGV4U2hhZGVySW1wbCAqKVRoaXMtPnN0YXRlQmxvY2stPnZlcnRleFNoYWRlciktPmJhc2VTaGFkZXIucHJnSWQpKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kUHJvZ3JhbUFSQihHTF9WRVJURVhfUFJPR1JBTV9BUkIsIHZlcnRleFNoYWRlci0+cHJnSWQpOyIpOwoKICAgICAgICAvKiBFbmFibGUgT3BlbkdMIHZlcnRleCBwcm9ncmFtcyAqLwogICAgICAgIGdsRW5hYmxlKEdMX1ZFUlRFWF9QUk9HUkFNX0FSQik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlKEdMX1ZFUlRFWF9QUk9HUkFNX0FSQik7Iik7CiAgICAgICAgVFJBQ0UoIiglcCkgOiBCb3VuZCB2ZXJ0ZXggcHJvZ3JhbSAldSBhbmQgZW5hYmxlZCBHTF9WRVJURVhfUFJPR1JBTV9BUkJcbiIsCiAgICAgICAgICAgIFRoaXMsICgoSVdpbmVEM0RWZXJ0ZXhTaGFkZXJJbXBsICopVGhpcy0+c3RhdGVCbG9jay0+dmVydGV4U2hhZGVyKS0+YmFzZVNoYWRlci5wcmdJZCk7CiAgICB9IGVsc2UgaWYoR0xfU1VQUE9SVChBUkJfVkVSVEVYX1BST0dSQU0pKSB7CiAgICAgICAgZ2xEaXNhYmxlKEdMX1ZFUlRFWF9QUk9HUkFNX0FSQik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShHTF9WRVJURVhfUFJPR1JBTV9BUkIpIik7CiAgICB9CgogICAgaWYgKHVzZVBTKSB7CiAgICAgICAgVFJBQ0UoIlVzaW5nIHBpeGVsIHNoYWRlclxuIik7CgogICAgICAgIC8qIEJpbmQgdGhlIGZyYWdtZW50IHByb2dyYW0gKi8KICAgICAgICBHTF9FWFRDQUxMKGdsQmluZFByb2dyYW1BUkIoR0xfRlJBR01FTlRfUFJPR1JBTV9BUkIsCiAgICAgICAgICAgICgoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwgKilUaGlzLT5zdGF0ZUJsb2NrLT5waXhlbFNoYWRlciktPmJhc2VTaGFkZXIucHJnSWQpKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xCaW5kUHJvZ3JhbUFSQihHTF9GUkFHTUVOVF9QUk9HUkFNX0FSQiwgcGl4ZWxTaGFkZXItPnByZ0lkKTsiKTsKCiAgICAgICAgLyogRW5hYmxlIE9wZW5HTCBmcmFnbWVudCBwcm9ncmFtcyAqLwogICAgICAgIGdsRW5hYmxlKEdMX0ZSQUdNRU5UX1BST0dSQU1fQVJCKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUoR0xfRlJBR01FTlRfUFJPR1JBTV9BUkIpOyIpOwogICAgICAgIFRSQUNFKCIoJXApIDogQm91bmQgZnJhZ21lbnQgcHJvZ3JhbSAldSBhbmQgZW5hYmxlZCBHTF9GUkFHTUVOVF9QUk9HUkFNX0FSQlxuIiwKICAgICAgICAgICAgVGhpcywgKChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqKVRoaXMtPnN0YXRlQmxvY2stPnBpeGVsU2hhZGVyKS0+YmFzZVNoYWRlci5wcmdJZCk7CiAgICB9IGVsc2UgaWYoR0xfU1VQUE9SVChBUkJfRlJBR01FTlRfUFJPR1JBTSkpIHsKICAgICAgICBnbERpc2FibGUoR0xfRlJBR01FTlRfUFJPR1JBTV9BUkIpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUoR0xfRlJBR01FTlRfUFJPR1JBTV9BUkIpIik7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIHNoYWRlcl9hcmJfc2VsZWN0X2RlcHRoX2JsdChJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIHN0cnVjdCBzaGFkZXJfYXJiX3ByaXYgKnByaXYgPSAoc3RydWN0IHNoYWRlcl9hcmJfcHJpdiAqKSBUaGlzLT5zaGFkZXJfcHJpdjsKICAgIFdpbmVEM0RfR0xfSW5mbyAqZ2xfaW5mbyA9ICZUaGlzLT5hZGFwdGVyLT5nbF9pbmZvOwoKICAgIGlmICghcHJpdi0+ZGVwdGhfYmx0X3Zwcm9ncmFtX2lkKSBwcml2LT5kZXB0aF9ibHRfdnByb2dyYW1faWQgPSBjcmVhdGVfYXJiX2JsdF92ZXJ0ZXhfcHJvZ3JhbShnbF9pbmZvKTsKICAgIEdMX0VYVENBTEwoZ2xCaW5kUHJvZ3JhbUFSQihHTF9WRVJURVhfUFJPR1JBTV9BUkIsIHByaXYtPmRlcHRoX2JsdF92cHJvZ3JhbV9pZCkpOwogICAgZ2xFbmFibGUoR0xfVkVSVEVYX1BST0dSQU1fQVJCKTsKCiAgICBpZiAoIXByaXYtPmRlcHRoX2JsdF9mcHJvZ3JhbV9pZCkgcHJpdi0+ZGVwdGhfYmx0X2Zwcm9ncmFtX2lkID0gY3JlYXRlX2FyYl9ibHRfZnJhZ21lbnRfcHJvZ3JhbShnbF9pbmZvKTsKICAgIEdMX0VYVENBTEwoZ2xCaW5kUHJvZ3JhbUFSQihHTF9GUkFHTUVOVF9QUk9HUkFNX0FSQiwgcHJpdi0+ZGVwdGhfYmx0X2Zwcm9ncmFtX2lkKSk7CiAgICBnbEVuYWJsZShHTF9GUkFHTUVOVF9QUk9HUkFNX0FSQik7Cn0KCnN0YXRpYyB2b2lkIHNoYWRlcl9hcmJfY2xlYW51cChJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFdpbmVEM0RfR0xfSW5mbyAqZ2xfaW5mbyA9ICZUaGlzLT5hZGFwdGVyLT5nbF9pbmZvOwogICAgaWYgKEdMX1NVUFBPUlQoQVJCX1ZFUlRFWF9QUk9HUkFNKSkgZ2xEaXNhYmxlKEdMX1ZFUlRFWF9QUk9HUkFNX0FSQik7CiAgICBpZiAoR0xfU1VQUE9SVChBUkJfRlJBR01FTlRfUFJPR1JBTSkpIGdsRGlzYWJsZShHTF9GUkFHTUVOVF9QUk9HUkFNX0FSQik7Cn0KCnN0YXRpYyB2b2lkIHNoYWRlcl9hcmJfZGVzdHJveShJV2luZUQzREJhc2VTaGFkZXIgKmlmYWNlKSB7CiAgICBJV2luZUQzREJhc2VTaGFkZXJJbXBsICpUaGlzID0gKElXaW5lRDNEQmFzZVNoYWRlckltcGwgKikgaWZhY2U7CiAgICBXaW5lRDNEX0dMX0luZm8gKmdsX2luZm8gPSAmKChJV2luZUQzRERldmljZUltcGwgKikgVGhpcy0+YmFzZVNoYWRlci5kZXZpY2UpLT5hZGFwdGVyLT5nbF9pbmZvOwoKICAgIEVOVEVSX0dMKCk7CiAgICBHTF9FWFRDQUxMKGdsRGVsZXRlUHJvZ3JhbXNBUkIoMSwgJlRoaXMtPmJhc2VTaGFkZXIucHJnSWQpKTsKICAgIGNoZWNrR0xjYWxsKCJHTF9FWFRDQUxMKGdsRGVsZXRlUHJvZ3JhbXNBUkIoMSwgJlRoaXMtPmJhc2VTaGFkZXIucHJnSWQpKSIpOwogICAgTEVBVkVfR0woKTsKICAgIFRoaXMtPmJhc2VTaGFkZXIucHJnSWQgPSAwOwogICAgVGhpcy0+YmFzZVNoYWRlci5pc19jb21waWxlZCA9IEZBTFNFOwp9CgpzdGF0aWMgSFJFU1VMVCBzaGFkZXJfYXJiX2FsbG9jKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVGhpcy0+c2hhZGVyX3ByaXYgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKHN0cnVjdCBzaGFkZXJfYXJiX3ByaXYpKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgdm9pZCBzaGFkZXJfYXJiX2ZyZWUoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBXaW5lRDNEX0dMX0luZm8gKmdsX2luZm8gPSAmVGhpcy0+YWRhcHRlci0+Z2xfaW5mbzsKICAgIHN0cnVjdCBzaGFkZXJfYXJiX3ByaXYgKnByaXYgPSAoc3RydWN0IHNoYWRlcl9hcmJfcHJpdiAqKSBUaGlzLT5zaGFkZXJfcHJpdjsKCiAgICBpZihwcml2LT5kZXB0aF9ibHRfdnByb2dyYW1faWQpIHsKICAgICAgICBHTF9FWFRDQUxMKGdsRGVsZXRlUHJvZ3JhbXNBUkIoMSwgJnByaXYtPmRlcHRoX2JsdF92cHJvZ3JhbV9pZCkpOwogICAgfQogICAgaWYocHJpdi0+ZGVwdGhfYmx0X2Zwcm9ncmFtX2lkKSB7CiAgICAgICAgR0xfRVhUQ0FMTChnbERlbGV0ZVByb2dyYW1zQVJCKDEsICZwcml2LT5kZXB0aF9ibHRfZnByb2dyYW1faWQpKTsKICAgIH0KCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5zaGFkZXJfcHJpdik7Cn0KCnN0YXRpYyBCT09MIHNoYWRlcl9hcmJfZGlydHlfY29uc3QoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIHZvaWQgc2hhZGVyX2FyYl9nZW5lcmF0ZV9wc2hhZGVyKElXaW5lRDNEUGl4ZWxTaGFkZXIgKmlmYWNlLCBTSEFERVJfQlVGRkVSICpidWZmZXIpIHsKICAgIElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICpUaGlzID0gKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICopaWZhY2U7CiAgICBzaGFkZXJfcmVnX21hcHMqIHJlZ19tYXBzID0gJlRoaXMtPmJhc2VTaGFkZXIucmVnX21hcHM7CiAgICBDT05TVCBEV09SRCAqZnVuY3Rpb24gPSBUaGlzLT5iYXNlU2hhZGVyLmZ1bmN0aW9uOwogICAgY29uc3QgY2hhciAqZnJhZ2NvbG9yOwogICAgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvID0gJigoSVdpbmVEM0REZXZpY2VJbXBsICopVGhpcy0+YmFzZVNoYWRlci5kZXZpY2UpLT5hZGFwdGVyLT5nbF9pbmZvOwogICAgbG9jYWxfY29uc3RhbnQqIGxjb25zdDsKCiAgICAvKiAgQ3JlYXRlIHRoZSBodyBBUkIgc2hhZGVyICovCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICIhIUFSQmZwMS4wXG4iKTsKCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJURU1QIFRNUDtcbiIpOyAgICAgLyogVXNlZCBpbiBtYXRyaXggb3BzICovCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJURU1QIFRNUDI7XG4iKTsgICAgLyogVXNlZCBpbiBtYXRyaXggb3BzICovCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJURU1QIFRBO1xuIik7ICAgICAgLyogVXNlZCBmb3IgbW9kaWZpZXJzICovCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJURU1QIFRCO1xuIik7ICAgICAgLyogVXNlZCBmb3IgbW9kaWZpZXJzICovCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJURU1QIFRDO1xuIik7ICAgICAgLyogVXNlZCBmb3IgbW9kaWZpZXJzICovCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJQQVJBTSBjb2VmZGl2ID0geyAwLjUsIDAuMjUsIDAuMTI1LCAwLjA2MjUgfTtcbiIpOwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiUEFSQU0gY29lZm11bCA9IHsgMiwgNCwgOCwgMTYgfTtcbiIpOwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiUEFSQU0gb25lID0geyAxLjAsIDEuMCwgMS4wLCAxLjAgfTtcbiIpOwoKICAgIC8qIEJhc2UgRGVjbGFyYXRpb25zICovCiAgICBzaGFkZXJfZ2VuZXJhdGVfYXJiX2RlY2xhcmF0aW9ucyggKElXaW5lRDNEQmFzZVNoYWRlciopIFRoaXMsIHJlZ19tYXBzLCBidWZmZXIsICZHTElORk9fTE9DQVRJT04pOwoKICAgIC8qIFdlIG5lZWQgdHdvIHZhcmlhYmxlcyBmb3IgZm9nIGJsZW5kaW5nICovCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJURU1QIFRNUF9GT0c7XG4iKTsKICAgIGlmIChUaGlzLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uID49IFdJTkVEM0RQU19WRVJTSU9OKDIsMCkpIHsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJURU1QIFRNUF9DT0xPUjtcbiIpOwogICAgfQoKICAgIC8qIEJhc2UgU2hhZGVyIEJvZHkgKi8KICAgIHNoYWRlcl9nZW5lcmF0ZV9tYWluKCAoSVdpbmVEM0RCYXNlU2hhZGVyKikgVGhpcywgYnVmZmVyLCByZWdfbWFwcywgZnVuY3Rpb24pOwoKICAgIC8qIGNhbGN1bGF0ZSBmb2cgYW5kIGJsZW5kIGl0CiAgICAgKiBOT1RFOiBzdGF0ZS5mb2cucGFyYW1zLnkgYW5kIHN0YXRlLmZvZy5wYXJhbXMueiBkb24ndCBob2xkIGZvZyBzdGFydCBzIGFuZCBlbmQgZSBidXQKICAgICAqIC0xLyhlLXMpIGFuZCBlLyhlLXMpIHJlc3BlY3RpdmVseS4KICAgICAqLwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTUFEX1NBVCBUTVBfRk9HLCBmcmFnbWVudC5mb2djb29yZCwgc3RhdGUuZm9nLnBhcmFtcy55LCBzdGF0ZS5mb2cucGFyYW1zLno7XG4iKTsKCiAgICBpZiAoVGhpcy0+YmFzZVNoYWRlci5oZXhfdmVyc2lvbiA8IFdJTkVEM0RQU19WRVJTSU9OKDIsMCkpIHsKICAgICAgICBmcmFnY29sb3IgPSAiUjAiOwogICAgfSBlbHNlIHsKICAgICAgICBmcmFnY29sb3IgPSAiVE1QX0NPTE9SIjsKICAgIH0KICAgIGlmKFRoaXMtPnNyZ2JfZW5hYmxlZCkgewogICAgICAgIC8qIFBlcmZvcm0gc1JHQiB3cml0ZSBjb3JyZWN0aW9uLiBTZWUgR0xYX0VYVF9mcmFtZWJ1ZmZlcl9zUkdCICovCgogICAgICAgIC8qIENhbGN1bGF0ZSB0aGUgPiAwLjAwMzEzMDggY2FzZSAqLwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlBPVyBUTVAueCwgJXMueCwgc3JnYl9wb3cueDtcbiIsIGZyYWdjb2xvcik7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiUE9XIFRNUC55LCAlcy55LCBzcmdiX3Bvdy55O1xuIiwgZnJhZ2NvbG9yKTsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJQT1cgVE1QLnosICVzLnosIHNyZ2JfcG93Lno7XG4iLCBmcmFnY29sb3IpOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIk1VTCBUTVAsIFRNUCwgc3JnYl9tdWxfaGk7XG4iKTsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJTVUIgVE1QLCBUTVAsIHNyZ2Jfc3ViX2hpO1xuIik7CiAgICAgICAgLyogQ2FsY3VsYXRlIHRoZSA8IGNhc2UgKi8KICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJNVUwgVE1QMiwgc3JnYl9tdWxfbG93LCAlcztcbiIsIGZyYWdjb2xvcik7CiAgICAgICAgLyogR2V0IDEuMCAvIDAuMCBtYXNrcyBmb3IgPiAwLjAwMzEzMDggYW5kIDwgMC4wMDMxMzA4ICovCiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiU0xUIFRBLCBzcmdiX2NvbXBhcmlzb24sICVzO1xuIiwgZnJhZ2NvbG9yKTsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJTR0UgVEIsIHNyZ2JfY29tcGFyaXNvbiwgJXM7XG4iLCBmcmFnY29sb3IpOwogICAgICAgIC8qIFN0b3JlIHRoZSBjb21wb25lbnRzID4gMC4wMDMxMzA4IGluIHRoZSBkZXN0aW5hdGlvbiAqLwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIk1VTCAlcywgVE1QLCBUQTtcbiIsIGZyYWdjb2xvcik7CiAgICAgICAgLyogQWRkIHRoZSBjb21wb25lbnRzIHRoYXQgYXJlIDwgMC4wMDMxMzA4ICovCiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTUFEIHJlc3VsdC5jb2xvci54eXosIFRNUDIsIFRCLCAlcztcbiIsIGZyYWdjb2xvcik7CiAgICAgICAgLyogWzAuMDsxLjBdIGNsYW1waW5nLiBOb3QgbmVlZGVkLCB0aGlzIGlzIGRvbmUgaW1wbGljaXRseSAqLwogICAgfQogICAgaWYgKFRoaXMtPmJhc2VTaGFkZXIuaGV4X3ZlcnNpb24gPCBXSU5FRDNEUFNfVkVSU0lPTigzLDApKSB7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTFJQIHJlc3VsdC5jb2xvci5yZ2IsIFRNUF9GT0cueCwgJXMsIHN0YXRlLmZvZy5jb2xvcjtcbiIsIGZyYWdjb2xvcik7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTU9WIHJlc3VsdC5jb2xvci5hLCAlcy5hO1xuIiwgZnJhZ2NvbG9yKTsKICAgIH0KCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJFTkRcbiIpOwoKICAgIC8qIFRPRE86IGNoYW5nZSB0byByZXNvdXJjZS5nbE9iamVjdEhhbmRsZSBvciBzb21ldGhpbmcgbGlrZSB0aGF0ICovCiAgICBHTF9FWFRDQUxMKGdsR2VuUHJvZ3JhbXNBUkIoMSwgJlRoaXMtPmJhc2VTaGFkZXIucHJnSWQpKTsKCiAgICBUUkFDRSgiQ3JlYXRpbmcgYSBodyBwaXhlbCBzaGFkZXIsIHByZz0lZFxuIiwgVGhpcy0+YmFzZVNoYWRlci5wcmdJZCk7CiAgICBHTF9FWFRDQUxMKGdsQmluZFByb2dyYW1BUkIoR0xfRlJBR01FTlRfUFJPR1JBTV9BUkIsIFRoaXMtPmJhc2VTaGFkZXIucHJnSWQpKTsKCiAgICBUUkFDRSgiQ3JlYXRlZCBodyBwaXhlbCBzaGFkZXIsIHByZz0lZFxuIiwgVGhpcy0+YmFzZVNoYWRlci5wcmdJZCk7CiAgICAvKiBDcmVhdGUgdGhlIHByb2dyYW0gYW5kIGNoZWNrIGZvciBlcnJvcnMgKi8KICAgIEdMX0VYVENBTEwoZ2xQcm9ncmFtU3RyaW5nQVJCKEdMX0ZSQUdNRU5UX1BST0dSQU1fQVJCLCBHTF9QUk9HUkFNX0ZPUk1BVF9BU0NJSV9BUkIsCiAgICAgICAgICAgICAgIGJ1ZmZlci0+YnNpemUsIGJ1ZmZlci0+YnVmZmVyKSk7CgogICAgaWYgKGdsR2V0RXJyb3IoKSA9PSBHTF9JTlZBTElEX09QRVJBVElPTikgewogICAgICAgIEdMaW50IGVyclBvczsKICAgICAgICBnbEdldEludGVnZXJ2KEdMX1BST0dSQU1fRVJST1JfUE9TSVRJT05fQVJCLCAmZXJyUG9zKTsKICAgICAgICBGSVhNRSgiSFcgUGl4ZWxTaGFkZXIgRXJyb3IgYXQgcG9zaXRpb24gJWQ6ICVzXG4iLAogICAgICAgICAgICAgIGVyclBvcywgZGVidWdzdHJfYSgoY29uc3QgY2hhciAqKWdsR2V0U3RyaW5nKEdMX1BST0dSQU1fRVJST1JfU1RSSU5HX0FSQikpKTsKICAgICAgICBUaGlzLT5iYXNlU2hhZGVyLnByZ0lkID0gLTE7CiAgICB9CgogICAgLyogTG9hZCBpbW1lZGlhdGUgY29uc3RhbnRzICovCiAgICBpZighVGhpcy0+YmFzZVNoYWRlci5sb2FkX2xvY2FsX2NvbnN0c0YpIHsKICAgICAgICBMSVNUX0ZPUl9FQUNIX0VOVFJZKGxjb25zdCwgJlRoaXMtPmJhc2VTaGFkZXIuY29uc3RhbnRzRiwgbG9jYWxfY29uc3RhbnQsIGVudHJ5KSB7CiAgICAgICAgICAgIGZsb2F0ICp2YWx1ZSA9IChmbG9hdCAqKSBsY29uc3QtPnZhbHVlOwogICAgICAgICAgICBHTF9FWFRDQUxMKGdsUHJvZ3JhbUxvY2FsUGFyYW1ldGVyNGZ2QVJCKEdMX0ZSQUdNRU5UX1BST0dSQU1fQVJCLCBsY29uc3QtPmlkeCwgdmFsdWUpKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsUHJvZ3JhbUxvY2FsUGFyYW1ldGVyNGZ2QVJCIik7CiAgICAgICAgfQogICAgfQp9CgpzdGF0aWMgdm9pZCBzaGFkZXJfYXJiX2dlbmVyYXRlX3ZzaGFkZXIoSVdpbmVEM0RWZXJ0ZXhTaGFkZXIgKmlmYWNlLCBTSEFERVJfQlVGRkVSICpidWZmZXIpIHsKICAgIElXaW5lRDNEVmVydGV4U2hhZGVySW1wbCAqVGhpcyA9IChJV2luZUQzRFZlcnRleFNoYWRlckltcGwgKilpZmFjZTsKICAgIHNoYWRlcl9yZWdfbWFwcyogcmVnX21hcHMgPSAmVGhpcy0+YmFzZVNoYWRlci5yZWdfbWFwczsKICAgIENPTlNUIERXT1JEICpmdW5jdGlvbiA9IFRoaXMtPmJhc2VTaGFkZXIuZnVuY3Rpb247CiAgICBXaW5lRDNEX0dMX0luZm8gKmdsX2luZm8gPSAmKChJV2luZUQzRERldmljZUltcGwgKilUaGlzLT5iYXNlU2hhZGVyLmRldmljZSktPmFkYXB0ZXItPmdsX2luZm87CiAgICBsb2NhbF9jb25zdGFudCogbGNvbnN0OwoKICAgIC8qICBDcmVhdGUgdGhlIGh3IEFSQiBzaGFkZXIgKi8KICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIiEhQVJCdnAxLjBcbiIpOwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiUEFSQU0gaGVscGVyX2NvbnN0ID0geyAyLjAsIC0xLjAsICVkLjAsIDAuMCB9O1xuIiwgVGhpcy0+cmVsX29mZnNldCk7CgogICAgLyogTWVzYSBzdXBwb3J0cyBvbmx5IDk1IGNvbnN0YW50cyAqLwogICAgaWYgKEdMX1ZFTkQoTUVTQSkgfHwgR0xfVkVORChXSU5FKSkKICAgICAgICBUaGlzLT5iYXNlU2hhZGVyLmxpbWl0cy5jb25zdGFudF9mbG9hdCA9CiAgICAgICAgICAgICAgICBtaW4oOTUsIFRoaXMtPmJhc2VTaGFkZXIubGltaXRzLmNvbnN0YW50X2Zsb2F0KTsKCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJURU1QIFRNUDtcbiIpOwoKICAgIC8qIEJhc2UgRGVjbGFyYXRpb25zICovCiAgICBzaGFkZXJfZ2VuZXJhdGVfYXJiX2RlY2xhcmF0aW9ucyggKElXaW5lRDNEQmFzZVNoYWRlciopIFRoaXMsIHJlZ19tYXBzLCBidWZmZXIsICZHTElORk9fTE9DQVRJT04pOwoKICAgIC8qIFdlIG5lZWQgYSBjb25zdGFudCB0byBmaXh1cCB0aGUgZmluYWwgcG9zaXRpb24gKi8KICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlBBUkFNIHBvc0ZpeHVwID0gcHJvZ3JhbS5lbnZbJWRdO1xuIiwgQVJCX1NIQURFUl9QUklWQ09OU1RfUE9TKTsKCiAgICAvKiBJbml0aWFsaXplIG91dHB1dCBwYXJhbWV0ZXJzLiBHTF9BUkJfdmVydGV4X3Byb2dyYW0gZG9lcyBub3QgcmVxdWlyZSBzcGVjaWFsIGluaXRpYWxpemF0aW9uIHZhbHVlcwogICAgICogZm9yIG91dHB1dCBwYXJhbWV0ZXJzLiBEM0QgaW4gdGhlb3J5IGRvZXMgbm90IGRvIHRoYXQgZWl0aGVyLCBidXQgc29tZSBhcHBsaWNhdGlvbnMgZGVwZW5kIG9uIGEKICAgICAqIHByb3BlciBpbml0aWFsaXphdGlvbiBvZiB0aGUgc2Vjb25kYXJ5IGNvbG9yLCBhbmQgcHJvZ3JhbXMgdXNpbmcgdGhlIGZpeGVkIGZ1bmN0aW9uIHBpcGVsaW5lIHdpdGhvdXQKICAgICAqIGEgcmVwbGFjZW1lbnQgc2hhZGVyIGRlcGVuZCBvbiB0aGUgdGV4Y29vcmQudyBiZWluZyBzZXQgcHJvcGVybHkuCiAgICAgKgogICAgICogR0xfTlZfdmVydGV4X3Byb2dyYW0gZGVmaW5lcyB0aGF0IGFsbCBvdXRwdXQgdmFsdWVzIGFyZSBpbml0aWFsaXplZCB0byB7MC4wLCAwLjAsIDAuMCwgMS4wfS4gVGhpcwogICAgICogYXNzZXJ0aW9uIGlzIGluIGVmZmVjdCBldmVuIHdoZW4gdXNpbmcgR0xfQVJCX3ZlcnRleF9wcm9ncmFtIHdpdGhvdXQgYW55IE5WIHNwZWNpZmljIGFkZGl0aW9ucy4gU28KICAgICAqIHNraXAgdGhpcyBpZiBOVl92ZXJ0ZXhfcHJvZ3JhbSBpcyBzdXBwb3J0ZWQuIE90aGVyd2lzZSwgaW5pdGlhbGl6ZSB0aGUgc2Vjb25kYXJ5IGNvbG9yLiBGb3IgdGhlIHRleC0KICAgICAqIGNvb3Jkcywgd2UgaGF2ZSBhIGZsYWcgaW4gdGhlIG9wZW5nbCBjYXBzLiBNYW55IGNhcmRzIGRvIG5vdCByZXF1aXJlIHRoZSB0ZXhjb29yZCBiZWluZyBzZXQsIGFuZAogICAgICogdGhpcyBjYW4gZWF0IGEgbnVtYmVyIG9mIGluc3RydWN0aW9ucywgc28gc2tpcCBpdCB1bmxlc3MgdGhpcyBjYXAgaXMgc2V0IGFzIHdlbGwKICAgICAqLwogICAgaWYoIUdMX1NVUFBPUlQoTlZfVkVSVEVYX1BST0dSQU0pKSB7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTU9WIHJlc3VsdC5jb2xvci5zZWNvbmRhcnksIC1oZWxwZXJfY29uc3Qud3d3eTtcbiIpOwoKICAgICAgICBpZigoR0xJTkZPX0xPQ0FUSU9OKS5zZXRfdGV4Y29vcmRfdykgewogICAgICAgICAgICBpbnQgaTsKICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDwgbWluKDgsIE1BWF9SRUdfVEVYQ1JEKTsgaSsrKSB7CiAgICAgICAgICAgICAgICBpZihUaGlzLT5iYXNlU2hhZGVyLnJlZ19tYXBzLnRleGNvb3JkX21hc2tbaV0gIT0gMCAmJgogICAgICAgICAgICAgICAgVGhpcy0+YmFzZVNoYWRlci5yZWdfbWFwcy50ZXhjb29yZF9tYXNrW2ldICE9IFdJTkVEM0RTUF9XUklURU1BU0tfQUxMKSB7CiAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTU9WIHJlc3VsdC50ZXhjb29yZFsldV0udywgLWhlbHBlcl9jb25zdC55O1xuIiwgaSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyogQmFzZSBTaGFkZXIgQm9keSAqLwogICAgc2hhZGVyX2dlbmVyYXRlX21haW4oIChJV2luZUQzREJhc2VTaGFkZXIqKSBUaGlzLCBidWZmZXIsIHJlZ19tYXBzLCBmdW5jdGlvbik7CgogICAgLyogSWYgdGhpcyBzaGFkZXIgZG9lc24ndCB1c2UgZm9nIGNvcHkgdGhlIHogY29vcmQgdG8gdGhlIGZvZyBjb29yZCBzbyB0aGF0IHdlIGNhbiB1c2UgdGFibGUgZm9nICovCiAgICBpZiAoIXJlZ19tYXBzLT5mb2cpCiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTU9WIHJlc3VsdC5mb2djb29yZCwgVE1QX09VVC56O1xuIik7CgogICAgLyogV3JpdGUgdGhlIGZpbmFsIHBvc2l0aW9uLgogICAgICoKICAgICAqIE9wZW5HTCBjb29yZGluYXRlcyBzcGVjaWZ5IHRoZSBjZW50ZXIgb2YgdGhlIHBpeGVsIHdoaWxlIGQzZCBjb29yZHMgc3BlY2lmeQogICAgICogdGhlIGNvcm5lci4gVGhlIG9mZnNldHMgYXJlIHN0b3JlZCBpbiB6IGFuZCB3IGluIHBvc0ZpeHVwLiBwb3NGaXh1cC55IGNvbnRhaW5zCiAgICAgKiAxLjAgb3IgLTEuMCB0byB0dXJuIHRoZSByZW5kZXJpbmcgdXBzaWRlIGRvd24gZm9yIG9mZnNjcmVlbiByZW5kZXJpbmcuIFBvc0ZpeHVwLngKICAgICAqIGNvbnRhaW5zIDEuMCB0byBhbGxvdyBhIG1hZCwgYnV0IGFyYiB2cyBzd2l6emxlcyBhcmUgdG9vIHJlc3RyaWN0ZWQgZm9yIHRoYXQuCiAgICAgKi8KICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIk1VTCBUTVAsIHBvc0ZpeHVwLCBUTVBfT1VULnc7XG4iKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIkFERCBUTVBfT1VULngsIFRNUF9PVVQueCwgVE1QLno7XG4iKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIk1BRCBUTVBfT1VULnksIFRNUF9PVVQueSwgcG9zRml4dXAueSwgVE1QLnc7XG4iKTsKCiAgICAvKiBaIGNvb3JkIFswOzFdLT5bLTE7MV0gbWFwcGluZywgc2VlIGNvbW1lbnQgaW4gdHJhbnNmb3JtX3Byb2plY3Rpb24gaW4gc3RhdGUuYwogICAgICogYW5kIHRoZSBnbHNsIGVxdWl2YWxlbnQKICAgICAqLwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTUFEIFRNUF9PVVQueiwgVE1QX09VVC56LCBoZWxwZXJfY29uc3QueCwgLVRNUF9PVVQudztcbiIpOwoKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIk1PViByZXN1bHQucG9zaXRpb24sIFRNUF9PVVQ7XG4iKTsKCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJFTkRcbiIpOwoKICAgIC8qIFRPRE86IGNoYW5nZSB0byByZXNvdXJjZS5nbE9iamVjdEhhbmRsZSBvciBzb21ldGhpbmcgbGlrZSB0aGF0ICovCiAgICBHTF9FWFRDQUxMKGdsR2VuUHJvZ3JhbXNBUkIoMSwgJlRoaXMtPmJhc2VTaGFkZXIucHJnSWQpKTsKCiAgICBUUkFDRSgiQ3JlYXRpbmcgYSBodyB2ZXJ0ZXggc2hhZGVyLCBwcmc9JWRcbiIsIFRoaXMtPmJhc2VTaGFkZXIucHJnSWQpOwogICAgR0xfRVhUQ0FMTChnbEJpbmRQcm9ncmFtQVJCKEdMX1ZFUlRFWF9QUk9HUkFNX0FSQiwgVGhpcy0+YmFzZVNoYWRlci5wcmdJZCkpOwoKICAgIFRSQUNFKCJDcmVhdGVkIGh3IHZlcnRleCBzaGFkZXIsIHByZz0lZFxuIiwgVGhpcy0+YmFzZVNoYWRlci5wcmdJZCk7CiAgICAvKiBDcmVhdGUgdGhlIHByb2dyYW0gYW5kIGNoZWNrIGZvciBlcnJvcnMgKi8KICAgIEdMX0VYVENBTEwoZ2xQcm9ncmFtU3RyaW5nQVJCKEdMX1ZFUlRFWF9QUk9HUkFNX0FSQiwgR0xfUFJPR1JBTV9GT1JNQVRfQVNDSUlfQVJCLAogICAgICAgICAgICAgICBidWZmZXItPmJzaXplLCBidWZmZXItPmJ1ZmZlcikpOwoKICAgIGlmIChnbEdldEVycm9yKCkgPT0gR0xfSU5WQUxJRF9PUEVSQVRJT04pIHsKICAgICAgICBHTGludCBlcnJQb3M7CiAgICAgICAgZ2xHZXRJbnRlZ2VydihHTF9QUk9HUkFNX0VSUk9SX1BPU0lUSU9OX0FSQiwgJmVyclBvcyk7CiAgICAgICAgRklYTUUoIkhXIFZlcnRleFNoYWRlciBFcnJvciBhdCBwb3NpdGlvbiAlZDogJXNcbiIsCiAgICAgICAgICAgICAgZXJyUG9zLCBkZWJ1Z3N0cl9hKChjb25zdCBjaGFyICopZ2xHZXRTdHJpbmcoR0xfUFJPR1JBTV9FUlJPUl9TVFJJTkdfQVJCKSkpOwogICAgICAgIFRoaXMtPmJhc2VTaGFkZXIucHJnSWQgPSAtMTsKICAgIH0KCiAgICAvKiBMb2FkIGltbWVkaWF0ZSBjb25zdGFudHMgKi8KICAgIGlmKCFUaGlzLT5iYXNlU2hhZGVyLmxvYWRfbG9jYWxfY29uc3RzRikgewogICAgICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkobGNvbnN0LCAmVGhpcy0+YmFzZVNoYWRlci5jb25zdGFudHNGLCBsb2NhbF9jb25zdGFudCwgZW50cnkpIHsKICAgICAgICAgICAgZmxvYXQgKnZhbHVlID0gKGZsb2F0ICopIGxjb25zdC0+dmFsdWU7CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xQcm9ncmFtTG9jYWxQYXJhbWV0ZXI0ZnZBUkIoR0xfVkVSVEVYX1BST0dSQU1fQVJCLCBsY29uc3QtPmlkeCwgdmFsdWUpKTsKICAgICAgICB9CiAgICB9Cn0KCnN0YXRpYyB2b2lkIHNoYWRlcl9hcmJfZ2V0X2NhcHMoV0lORUQzRERFVlRZUEUgZGV2dHlwZSwgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvLCBzdHJ1Y3Qgc2hhZGVyX2NhcHMgKnBDYXBzKSB7CiAgICAvKiBXZSBkb24ndCBoYXZlIGFuIEFSQiBmaXhlZCBmdW5jdGlvbiBwaXBlbGluZSB5ZXQsIHNvIGxldCB0aGUgbm9uZSBiYWNrZW5kIHNldCBpdHMgY2FwcywKICAgICAqIHRoZW4gb3ZlcndyaXRlIHRoZSBzaGFkZXIgc3BlY2lmaWMgb25lcwogICAgICovCiAgICBub25lX3NoYWRlcl9iYWNrZW5kLnNoYWRlcl9nZXRfY2FwcyhkZXZ0eXBlLCBnbF9pbmZvLCBwQ2Fwcyk7CgogICAgaWYoR0xfU1VQUE9SVChBUkJfVkVSVEVYX1BST0dSQU0pKSB7CiAgICAgICAgcENhcHMtPlZlcnRleFNoYWRlclZlcnNpb24gPSBXSU5FRDNEVlNfVkVSU0lPTigxLDEpOwogICAgICAgIFRSQUNFXyhkM2RfY2FwcykoIkhhcmR3YXJlIHZlcnRleCBzaGFkZXIgdmVyc2lvbiAxLjEgZW5hYmxlZCAoQVJCX1BST0dSQU0pXG4iKTsKICAgICAgICBwQ2Fwcy0+TWF4VmVydGV4U2hhZGVyQ29uc3QgPSBHTF9MSU1JVFModnNoYWRlcl9jb25zdGFudHNGKTsKICAgIH0KCiAgICBpZihHTF9TVVBQT1JUKEFSQl9GUkFHTUVOVF9QUk9HUkFNKSkgewogICAgICAgIHBDYXBzLT5QaXhlbFNoYWRlclZlcnNpb24gICAgPSBXSU5FRDNEUFNfVkVSU0lPTigxLDQpOwogICAgICAgIHBDYXBzLT5QaXhlbFNoYWRlcjF4TWF4VmFsdWUgPSA4LjA7CiAgICAgICAgVFJBQ0VfKGQzZF9jYXBzKSgiSGFyZHdhcmUgcGl4ZWwgc2hhZGVyIHZlcnNpb24gMS40IGVuYWJsZWQgKEFSQl9QUk9HUkFNKVxuIik7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIHNoYWRlcl9hcmJfZnJhZ21lbnRfZW5hYmxlKElXaW5lRDNERGV2aWNlICppZmFjZSwgQk9PTCBlbmFibGUpIHsKICAgIG5vbmVfc2hhZGVyX2JhY2tlbmQuc2hhZGVyX2ZyYWdtZW50X2VuYWJsZShpZmFjZSwgZW5hYmxlKTsKfQoKY29uc3Qgc2hhZGVyX2JhY2tlbmRfdCBhcmJfcHJvZ3JhbV9zaGFkZXJfYmFja2VuZCA9IHsKICAgIHNoYWRlcl9hcmJfc2VsZWN0LAogICAgc2hhZGVyX2FyYl9zZWxlY3RfZGVwdGhfYmx0LAogICAgc2hhZGVyX2FyYl9sb2FkX2NvbnN0YW50cywKICAgIHNoYWRlcl9hcmJfY2xlYW51cCwKICAgIHNoYWRlcl9hcmJfY29sb3JfY29ycmVjdGlvbiwKICAgIHNoYWRlcl9hcmJfZGVzdHJveSwKICAgIHNoYWRlcl9hcmJfYWxsb2MsCiAgICBzaGFkZXJfYXJiX2ZyZWUsCiAgICBzaGFkZXJfYXJiX2RpcnR5X2NvbnN0LAogICAgc2hhZGVyX2FyYl9nZW5lcmF0ZV9wc2hhZGVyLAogICAgc2hhZGVyX2FyYl9nZW5lcmF0ZV92c2hhZGVyLAogICAgc2hhZGVyX2FyYl9nZXRfY2FwcywKICAgIHNoYWRlcl9hcmJfZnJhZ21lbnRfZW5hYmxlLAp9Owo=