LyoKICogUGl4ZWwgYW5kIHZlcnRleCBzaGFkZXJzIGltcGxlbWVudGF0aW9uIHVzaW5nIEFSQl92ZXJ0ZXhfcHJvZ3JhbQogKiBhbmQgQVJCX2ZyYWdtZW50X3Byb2dyYW0gR0wgZXh0ZW5zaW9ucy4KICoKICogQ29weXJpZ2h0IDIwMDItMjAwMyBKYXNvbiBFZG1lYWRlcwogKiBDb3B5cmlnaHQgMjAwMi0yMDAzIFJhcGhhZWwgSnVucXVlaXJhCiAqIENvcHlyaWdodCAyMDA0IENocmlzdGlhbiBDb3N0YQogKiBDb3B5cmlnaHQgMjAwNSBPbGl2ZXIgU3RpZWJlcgogKiBDb3B5cmlnaHQgMjAwNiBJdmFuIEd5dXJkaWV2CiAqIENvcHlyaWdodCAyMDA2IEphc29uIEdyZWVuCiAqIENvcHlyaWdodCAyMDA2IEhlbnJpIFZlcmJlZXQKICogQ29weXJpZ2h0IDIwMDctMjAwOCBTdGVmYW4gRPZzaW5nZXIgZm9yIENvZGVXZWF2ZXJzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKCiNpbmNsdWRlIDxtYXRoLmg+CiNpbmNsdWRlIDxzdGRpby5oPgoKI2luY2x1ZGUgIndpbmVkM2RfcHJpdmF0ZS5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoZDNkX3NoYWRlcik7CldJTkVfREVDTEFSRV9ERUJVR19DSEFOTkVMKGQzZF9jb25zdGFudHMpOwpXSU5FX0RFQ0xBUkVfREVCVUdfQ0hBTk5FTChkM2RfY2Fwcyk7CgojZGVmaW5lIEdMSU5GT19MT0NBVElPTiAgICAgICgqZ2xfaW5mbykKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBUkJfW3ZlcnRleC9mcmFnbWVudF1fcHJvZ3JhbSBoZWxwZXIgZnVuY3Rpb25zIGZvbGxvdwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKiogCiAqIExvYWRzIGZsb2F0aW5nIHBvaW50IGNvbnN0YW50cyBpbnRvIHRoZSBjdXJyZW50bHkgc2V0IEFSQl92ZXJ0ZXgvZnJhZ21lbnRfcHJvZ3JhbS4KICogV2hlbiBjb25zdGFudF9saXN0ID09IE5VTEwsIGl0IHdpbGwgbG9hZCBhbGwgdGhlIGNvbnN0YW50cy4KICogIAogKiBAdGFyZ2V0X3R5cGUgc2hvdWxkIGJlIGVpdGhlciBHTF9WRVJURVhfUFJPR1JBTV9BUkIgKGZvciB2ZXJ0ZXggc2hhZGVycykKICogIG9yIEdMX0ZSQUdNRU5UX1BST0dSQU1fQVJCIChmb3IgcGl4ZWwgc2hhZGVycykKICovCnN0YXRpYyB1bnNpZ25lZCBpbnQgc2hhZGVyX2FyYl9sb2FkX2NvbnN0YW50c0YoSVdpbmVEM0RCYXNlU2hhZGVySW1wbCogVGhpcywgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvLCBHTHVpbnQgdGFyZ2V0X3R5cGUsCiAgICAgICAgdW5zaWduZWQgaW50IG1heF9jb25zdGFudHMsIGZsb2F0KiBjb25zdGFudHMsIGNoYXIgKmRpcnR5X2NvbnN0cykgewogICAgbG9jYWxfY29uc3RhbnQqIGxjb25zdDsKICAgIERXT1JEIGksIGo7CiAgICB1bnNpZ25lZCBpbnQgcmV0OwoKICAgIGlmIChUUkFDRV9PTihkM2Rfc2hhZGVyKSkgewogICAgICAgIGZvcihpID0gMDsgaSA8IG1heF9jb25zdGFudHM7IGkrKykgewogICAgICAgICAgICBpZighZGlydHlfY29uc3RzW2ldKSBjb250aW51ZTsKICAgICAgICAgICAgVFJBQ0VfKGQzZF9jb25zdGFudHMpKCJMb2FkaW5nIGNvbnN0YW50cyAlaTogJWYsICVmLCAlZiwgJWZcbiIsIGksCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0YW50c1tpICogNCArIDBdLCBjb25zdGFudHNbaSAqIDQgKyAxXSwKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3RhbnRzW2kgKiA0ICsgMl0sIGNvbnN0YW50c1tpICogNCArIDNdKTsKICAgICAgICB9CiAgICB9CiAgICAvKiBJbiAxLlggcGl4ZWwgc2hhZGVycyBjb25zdGFudHMgYXJlIGltcGxpY2l0bHkgY2xhbXBlZCBpbiB0aGUgcmFuZ2UgWy0xOzFdICovCiAgICBpZih0YXJnZXRfdHlwZSA9PSBHTF9GUkFHTUVOVF9QUk9HUkFNX0FSQiAmJgogICAgICAgV0lORUQzRFNIQURFUl9WRVJTSU9OX01BSk9SKFRoaXMtPmJhc2VTaGFkZXIuaGV4X3ZlcnNpb24pID09IDEpIHsKICAgICAgICBmbG9hdCBsY2xfY29uc3RbNF07CiAgICAgICAgZm9yKGkgPSAwOyBpIDwgbWF4X2NvbnN0YW50czsgaSsrKSB7CiAgICAgICAgICAgIGlmKCFkaXJ0eV9jb25zdHNbaV0pIGNvbnRpbnVlOwogICAgICAgICAgICBkaXJ0eV9jb25zdHNbaV0gPSAwOwoKICAgICAgICAgICAgaiA9IDQgKiBpOwogICAgICAgICAgICBpZihjb25zdGFudHNbaiArIDBdID4gMS4wKSBsY2xfY29uc3RbMF0gPSAxLjA7CiAgICAgICAgICAgIGVsc2UgaWYoY29uc3RhbnRzW2ogKyAwXSA8IC0xLjApIGxjbF9jb25zdFswXSA9IC0xLjA7CiAgICAgICAgICAgIGVsc2UgbGNsX2NvbnN0WzBdID0gY29uc3RhbnRzW2ogKyAwXTsKCiAgICAgICAgICAgIGlmKGNvbnN0YW50c1tqICsgMV0gPiAxLjApIGxjbF9jb25zdFsxXSA9IDEuMDsKICAgICAgICAgICAgZWxzZSBpZihjb25zdGFudHNbaiArIDFdIDwgLTEuMCkgbGNsX2NvbnN0WzFdID0gLTEuMDsKICAgICAgICAgICAgZWxzZSBsY2xfY29uc3RbMV0gPSBjb25zdGFudHNbaiArIDFdOwoKICAgICAgICAgICAgaWYoY29uc3RhbnRzW2ogKyAyXSA+IDEuMCkgbGNsX2NvbnN0WzJdID0gMS4wOwogICAgICAgICAgICBlbHNlIGlmKGNvbnN0YW50c1tqICsgMl0gPCAtMS4wKSBsY2xfY29uc3RbMl0gPSAtMS4wOwogICAgICAgICAgICBlbHNlIGxjbF9jb25zdFsyXSA9IGNvbnN0YW50c1tqICsgMl07CgogICAgICAgICAgICBpZihjb25zdGFudHNbaiArIDNdID4gMS4wKSBsY2xfY29uc3RbM10gPSAxLjA7CiAgICAgICAgICAgIGVsc2UgaWYoY29uc3RhbnRzW2ogKyAzXSA8IC0xLjApIGxjbF9jb25zdFszXSA9IC0xLjA7CiAgICAgICAgICAgIGVsc2UgbGNsX2NvbnN0WzNdID0gY29uc3RhbnRzW2ogKyAzXTsKCiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xQcm9ncmFtRW52UGFyYW1ldGVyNGZ2QVJCKHRhcmdldF90eXBlLCBpLCBsY2xfY29uc3QpKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIGlmKEdMX1NVUFBPUlQoRVhUX0dQVV9QUk9HUkFNX1BBUkFNRVRFUlMpKSB7CiAgICAgICAgICAgIC8qIFRPRE86IEJlbmNobWFyayBpZiB3ZSdyZSBiZXR0ZXIgb2Ygd2l0aCBmaW5kaW5nIHRoZSBkaXJ0eSBjb25zdGFudHMgb3Vyc2VsdmVzLAogICAgICAgICAgICAgKiBvciBqdXN0IHJlbG9hZGluZyAqYWxsKiBjb25zdGFudHMgYXQgb25jZQogICAgICAgICAgICAgKgogICAgICAgICAgICBHTF9FWFRDQUxMKGdsUHJvZ3JhbUVudlBhcmFtZXRlcnM0ZnZFWFQodGFyZ2V0X3R5cGUsIDAsIG1heF9jb25zdGFudHMsIGNvbnN0YW50cykpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDwgbWF4X2NvbnN0YW50czsgaSsrKSB7CiAgICAgICAgICAgICAgICBpZighZGlydHlfY29uc3RzW2ldKSBjb250aW51ZTsKCiAgICAgICAgICAgICAgICAvKiBGaW5kIHRoZSBuZXh0IGJsb2NrIG9mIGRpcnR5IGNvbnN0YW50cyAqLwogICAgICAgICAgICAgICAgZGlydHlfY29uc3RzW2ldID0gMDsKICAgICAgICAgICAgICAgIGogPSBpOwogICAgICAgICAgICAgICAgZm9yKGkrKzsgKGkgPCBtYXhfY29uc3RhbnRzKSAmJiBkaXJ0eV9jb25zdHNbaV07IGkrKykgewogICAgICAgICAgICAgICAgICAgIGRpcnR5X2NvbnN0c1tpXSA9IDA7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFByb2dyYW1FbnZQYXJhbWV0ZXJzNGZ2RVhUKHRhcmdldF90eXBlLCBqLCBpIC0gaiwgY29uc3RhbnRzICsgKGogKiA0KSkpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDwgbWF4X2NvbnN0YW50czsgaSsrKSB7CiAgICAgICAgICAgICAgICBpZihkaXJ0eV9jb25zdHNbaV0pIHsKICAgICAgICAgICAgICAgICAgICBkaXJ0eV9jb25zdHNbaV0gPSAwOwogICAgICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xQcm9ncmFtRW52UGFyYW1ldGVyNGZ2QVJCKHRhcmdldF90eXBlLCBpLCBjb25zdGFudHMgKyAoaSAqIDQpKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBjaGVja0dMY2FsbCgiZ2xQcm9ncmFtRW52UGFyYW1ldGVyNGZ2QVJCKCkiKTsKCiAgICAvKiBMb2FkIGltbWVkaWF0ZSBjb25zdGFudHMgKi8KICAgIGlmKFRoaXMtPmJhc2VTaGFkZXIubG9hZF9sb2NhbF9jb25zdHNGKSB7CiAgICAgICAgaWYgKFRSQUNFX09OKGQzZF9zaGFkZXIpKSB7CiAgICAgICAgICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkobGNvbnN0LCAmVGhpcy0+YmFzZVNoYWRlci5jb25zdGFudHNGLCBsb2NhbF9jb25zdGFudCwgZW50cnkpIHsKICAgICAgICAgICAgICAgIEdMZmxvYXQqIHZhbHVlcyA9IChHTGZsb2F0KilsY29uc3QtPnZhbHVlOwogICAgICAgICAgICAgICAgVFJBQ0VfKGQzZF9jb25zdGFudHMpKCJMb2FkaW5nIGxvY2FsIGNvbnN0YW50cyAlaTogJWYsICVmLCAlZiwgJWZcbiIsIGxjb25zdC0+aWR4LAogICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXNbMF0sIHZhbHVlc1sxXSwgdmFsdWVzWzJdLCB2YWx1ZXNbM10pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qIEltbWVkaWF0ZSBjb25zdGFudHMgYXJlIGNsYW1wZWQgZm9yIDEuWCBzaGFkZXJzIGF0IGxvYWRpbmcgdGltZXMgKi8KICAgICAgICByZXQgPSAwOwogICAgICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkobGNvbnN0LCAmVGhpcy0+YmFzZVNoYWRlci5jb25zdGFudHNGLCBsb2NhbF9jb25zdGFudCwgZW50cnkpIHsKICAgICAgICAgICAgZGlydHlfY29uc3RzW2xjb25zdC0+aWR4XSA9IDE7IC8qIERpcnRpZnkgc28gdGhlIG5vbi1pbW1lZGlhdGUgY29uc3RhbnQgb3ZlcndyaXRlcyBpdCBuZXh0IHRpbWUgKi8KICAgICAgICAgICAgcmV0ID0gbWF4KHJldCwgbGNvbnN0LT5pZHgpOwogICAgICAgICAgICBHTF9FWFRDQUxMKGdsUHJvZ3JhbUVudlBhcmFtZXRlcjRmdkFSQih0YXJnZXRfdHlwZSwgbGNvbnN0LT5pZHgsIChHTGZsb2F0KilsY29uc3QtPnZhbHVlKSk7CiAgICAgICAgfQogICAgICAgIGNoZWNrR0xjYWxsKCJnbFByb2dyYW1FbnZQYXJhbWV0ZXI0ZnZBUkIoKSIpOwogICAgICAgIHJldHVybiByZXQ7IC8qIFRoZSBsb2FkZWQgaW1tZWRpYXRlIGNvbnN0YW50cyBuZWVkIHJlbG9hZGluZyBmb3IgdGhlIG5leHQgc2hhZGVyICovCiAgICB9IGVsc2UgewogICAgICAgIHJldHVybiAwOyAvKiBObyBjb25zdGFudHMgYXJlIGRpcnR5IG5vdyAqLwogICAgfQp9CgovKioKICogTG9hZHMgdGhlIGFwcC1zdXBwbGllZCBjb25zdGFudHMgaW50byB0aGUgY3VycmVudGx5IHNldCBBUkJfW3ZlcnRleC9mcmFnbWVudF1fcHJvZ3JhbXMuCiAqIAogKiBXZSBvbmx5IHN1cHBvcnQgZmxvYXQgY29uc3RhbnRzIGluIEFSQiBhdCB0aGUgbW9tZW50LCBzbyBkb24ndCAKICogd29ycnkgYWJvdXQgdGhlIEludGVnZXJzIG9yIEJvb2xlYW5zCiAqLwp2b2lkIHNoYWRlcl9hcmJfbG9hZF9jb25zdGFudHMoCiAgICBJV2luZUQzRERldmljZSogZGV2aWNlLAogICAgY2hhciB1c2VQaXhlbFNoYWRlciwKICAgIGNoYXIgdXNlVmVydGV4U2hhZGVyKSB7CiAgIAogICAgSVdpbmVEM0REZXZpY2VJbXBsKiBkZXZpY2VJbXBsID0gKElXaW5lRDNERGV2aWNlSW1wbCopIGRldmljZTsgCiAgICBJV2luZUQzRFN0YXRlQmxvY2tJbXBsKiBzdGF0ZUJsb2NrID0gZGV2aWNlSW1wbC0+c3RhdGVCbG9jazsKICAgIFdpbmVEM0RfR0xfSW5mbyAqZ2xfaW5mbyA9ICZkZXZpY2VJbXBsLT5hZGFwdGVyLT5nbF9pbmZvOwogICAgdW5zaWduZWQgY2hhciBpOwoKICAgIGlmICh1c2VWZXJ0ZXhTaGFkZXIpIHsKICAgICAgICBJV2luZUQzREJhc2VTaGFkZXJJbXBsKiB2c2hhZGVyID0gKElXaW5lRDNEQmFzZVNoYWRlckltcGwqKSBzdGF0ZUJsb2NrLT52ZXJ0ZXhTaGFkZXI7CgogICAgICAgIC8qIExvYWQgRGlyZWN0WCA5IGZsb2F0IGNvbnN0YW50cyBmb3IgdmVydGV4IHNoYWRlciAqLwogICAgICAgIGRldmljZUltcGwtPmhpZ2hlc3RfZGlydHlfdnNfY29uc3QgPSBzaGFkZXJfYXJiX2xvYWRfY29uc3RhbnRzRigKICAgICAgICAgICAgICAgIHZzaGFkZXIsIGdsX2luZm8sIEdMX1ZFUlRFWF9QUk9HUkFNX0FSQiwKICAgICAgICAgICAgICAgIGRldmljZUltcGwtPmhpZ2hlc3RfZGlydHlfdnNfY29uc3QsCiAgICAgICAgICAgICAgICBzdGF0ZUJsb2NrLT52ZXJ0ZXhTaGFkZXJDb25zdGFudEYsCiAgICAgICAgICAgICAgICBkZXZpY2VJbXBsLT5hY3RpdmVDb250ZXh0LT52c2hhZGVyX2NvbnN0X2RpcnR5KTsKCiAgICAgICAgLyogVXBsb2FkIHRoZSBwb3NpdGlvbiBmaXh1cCAqLwogICAgICAgIEdMX0VYVENBTEwoZ2xQcm9ncmFtRW52UGFyYW1ldGVyNGZ2QVJCKEdMX1ZFUlRFWF9QUk9HUkFNX0FSQiwgQVJCX1NIQURFUl9QUklWQ09OU1RfUE9TLCBkZXZpY2VJbXBsLT5wb3NGaXh1cCkpOwogICAgfQoKICAgIGlmICh1c2VQaXhlbFNoYWRlcikgewoKICAgICAgICBJV2luZUQzREJhc2VTaGFkZXJJbXBsKiBwc2hhZGVyID0gKElXaW5lRDNEQmFzZVNoYWRlckltcGwqKSBzdGF0ZUJsb2NrLT5waXhlbFNoYWRlcjsKICAgICAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqcHNpID0gKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICopIHBzaGFkZXI7CgogICAgICAgIC8qIExvYWQgRGlyZWN0WCA5IGZsb2F0IGNvbnN0YW50cyBmb3IgcGl4ZWwgc2hhZGVyICovCiAgICAgICAgZGV2aWNlSW1wbC0+aGlnaGVzdF9kaXJ0eV9wc19jb25zdCA9IHNoYWRlcl9hcmJfbG9hZF9jb25zdGFudHNGKAogICAgICAgICAgICAgICAgcHNoYWRlciwgZ2xfaW5mbywgR0xfRlJBR01FTlRfUFJPR1JBTV9BUkIsCiAgICAgICAgICAgICAgICBkZXZpY2VJbXBsLT5oaWdoZXN0X2RpcnR5X3BzX2NvbnN0LAogICAgICAgICAgICAgICAgc3RhdGVCbG9jay0+cGl4ZWxTaGFkZXJDb25zdGFudEYsCiAgICAgICAgICAgICAgICBkZXZpY2VJbXBsLT5hY3RpdmVDb250ZXh0LT5wc2hhZGVyX2NvbnN0X2RpcnR5KTsKCiAgICAgICAgZm9yKGkgPSAwOyBpIDwgcHNpLT5udW1idW1wZW52bWF0Y29uc3RzOyBpKyspIHsKICAgICAgICAgICAgLyogVGhlIHN0YXRlIG1hbmFnZXIgdGFrZXMgY2FyZSB0aGF0IHRoaXMgZnVuY3Rpb24gaXMgYWx3YXlzIGNhbGxlZCBpZiB0aGUgYnVtcCBlbnYgbWF0cml4IGNoYW5nZXMKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGZsb2F0ICpkYXRhID0gKGZsb2F0ICopICZzdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbKGludCkgcHNpLT5idW1wZW52bWF0Y29uc3RbaV0udGV4dW5pdF1bV0lORUQzRFRTU19CVU1QRU5WTUFUMDBdOwogICAgICAgICAgICBHTF9FWFRDQUxMKGdsUHJvZ3JhbUVudlBhcmFtZXRlcjRmdkFSQihHTF9GUkFHTUVOVF9QUk9HUkFNX0FSQiwgcHNpLT5idW1wZW52bWF0Y29uc3RbaV0uY29uc3RfbnVtLCBkYXRhKSk7CiAgICAgICAgICAgIGRldmljZUltcGwtPmFjdGl2ZUNvbnRleHQtPnBzaGFkZXJfY29uc3RfZGlydHlbcHNpLT5idW1wZW52bWF0Y29uc3RbaV0uY29uc3RfbnVtXSA9IDE7CgogICAgICAgICAgICBpZihwc2ktPmx1bWluYW5jZWNvbnN0W2ldLmNvbnN0X251bSAhPSAtMSkgewogICAgICAgICAgICAgICAgLyogV0lORUQzRFRTU19CVU1QRU5WTFNDQUxFIGFuZCBXSU5FRDNEVFNTX0JVTVBFTlZMT0ZGU0VUIGFyZSBuZXh0IHRvIGVhY2ggb3RoZXIuCiAgICAgICAgICAgICAgICAgKiBwb2ludCBnbCB0byB0aGUgc2NhbGUsIGFuZCBsb2FkIDQgZmxvYXRzLiB4ID0gc2NhbGUsIHkgPSBvZmZzZXQsIHogYW5kIHcgYXJlIGp1bmssIHdlCiAgICAgICAgICAgICAgICAgKiBkb24ndCBjYXJlIGFib3V0IHRoZW0uIFRoZSBwb2ludGVycyBhcmUgdmFsaWQgZm9yIHN1cmUgYmVjYXVzZSB0aGUgc3RhdGVibG9jayBpcyBiaWdnZXIuCiAgICAgICAgICAgICAgICAgKiAodGhleSdyZSBXSU5FRDNEVFNTX1RFWFRVUkVUUkFOU0ZPUk1GTEFHUyBhbmQgV0lORUQzRFRTU19BRERSRVNTVywgc28gbW9zdCBsaWtlbHkgMCBvciBOYU4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgZmxvYXQgKnNjYWxlID0gKGZsb2F0ICopICZzdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbKGludCkgcHNpLT5sdW1pbmFuY2Vjb25zdFtpXS50ZXh1bml0XVtXSU5FRDNEVFNTX0JVTVBFTlZMU0NBTEVdOwogICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFByb2dyYW1FbnZQYXJhbWV0ZXI0ZnZBUkIoR0xfRlJBR01FTlRfUFJPR1JBTV9BUkIsIHBzaS0+bHVtaW5hbmNlY29uc3RbaV0uY29uc3RfbnVtLCBzY2FsZSkpOwogICAgICAgICAgICAgICAgZGV2aWNlSW1wbC0+YWN0aXZlQ29udGV4dC0+cHNoYWRlcl9jb25zdF9kaXJ0eVtwc2ktPmx1bWluYW5jZWNvbnN0W2ldLmNvbnN0X251bV0gPSAxOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZigoKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICopIHBzaGFkZXIpLT5zcmdiX2VuYWJsZWQgJiYKICAgICAgICAgICAhKChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqKSBwc2hhZGVyKS0+c3JnYl9tb2RlX2hhcmRjb2RlZCkgewogICAgICAgICAgICBmbG9hdCBjb21wYXJpc29uWzRdOwogICAgICAgICAgICBmbG9hdCBtdWxfbG93WzRdOwoKICAgICAgICAgICAgaWYoc3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbV0lORUQzRFJTX1NSR0JXUklURUVOQUJMRV0pIHsKICAgICAgICAgICAgICAgIGNvbXBhcmlzb25bMF0gPSBzcmdiX2NtcDsgY29tcGFyaXNvblsxXSA9IHNyZ2JfY21wOwogICAgICAgICAgICAgICAgY29tcGFyaXNvblsyXSA9IHNyZ2JfY21wOyBjb21wYXJpc29uWzNdID0gc3JnYl9jbXA7CgogICAgICAgICAgICAgICAgbXVsX2xvd1swXSA9IHNyZ2JfbXVsX2xvdzsgbXVsX2xvd1sxXSA9IHNyZ2JfbXVsX2xvdzsKICAgICAgICAgICAgICAgIG11bF9sb3dbMl0gPSBzcmdiX211bF9sb3c7IG11bF9sb3dbM10gPSBzcmdiX211bF9sb3c7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBjb21wYXJpc29uWzBdID0gMS4wIC8gMC4wOyBjb21wYXJpc29uWzFdID0gMS4wIC8gMC4wOwogICAgICAgICAgICAgICAgY29tcGFyaXNvblsyXSA9IDEuMCAvIDAuMDsgY29tcGFyaXNvblszXSA9IDEuMCAvIDAuMDsKCiAgICAgICAgICAgICAgICBtdWxfbG93WzBdID0gMS4wOyBtdWxfbG93WzFdID0gMS4wOwogICAgICAgICAgICAgICAgbXVsX2xvd1syXSA9IDEuMDsgbXVsX2xvd1szXSA9IDEuMDsKICAgICAgICAgICAgfQogICAgICAgICAgICBHTF9FWFRDQUxMKGdsUHJvZ3JhbUVudlBhcmFtZXRlcjRmdkFSQihHTF9GUkFHTUVOVF9QUk9HUkFNX0FSQiwgcHNpLT5zcmdiX2NtcF9jb25zdCwgY29tcGFyaXNvbikpOwogICAgICAgICAgICBHTF9FWFRDQUxMKGdsUHJvZ3JhbUVudlBhcmFtZXRlcjRmdkFSQihHTF9GUkFHTUVOVF9QUk9HUkFNX0FSQiwgcHNpLT5zcmdiX2xvd19jb25zdCwgbXVsX2xvdykpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiTG9hZCBzUkdCIGNvcnJlY3Rpb24gY29uc3RhbnRzXG4iKTsKICAgICAgICAgICAgZGV2aWNlSW1wbC0+YWN0aXZlQ29udGV4dC0+cHNoYWRlcl9jb25zdF9kaXJ0eVtwc2ktPnNyZ2JfbG93X2NvbnN0XSA9IDE7CiAgICAgICAgICAgIGRldmljZUltcGwtPmFjdGl2ZUNvbnRleHQtPnBzaGFkZXJfY29uc3RfZGlydHlbcHNpLT5zcmdiX2NtcF9jb25zdF0gPSAxOwoKICAgICAgICB9CiAgICB9Cn0KCi8qIEdlbmVyYXRlIHRoZSB2YXJpYWJsZSAmIHJlZ2lzdGVyIGRlY2xhcmF0aW9ucyBmb3IgdGhlIEFSQl92ZXJ0ZXhfcHJvZ3JhbSBvdXRwdXQgdGFyZ2V0ICovCnZvaWQgc2hhZGVyX2dlbmVyYXRlX2FyYl9kZWNsYXJhdGlvbnMoCiAgICBJV2luZUQzREJhc2VTaGFkZXIgKmlmYWNlLAogICAgc2hhZGVyX3JlZ19tYXBzKiByZWdfbWFwcywKICAgIFNIQURFUl9CVUZGRVIqIGJ1ZmZlciwKICAgIFdpbmVEM0RfR0xfSW5mbyogZ2xfaW5mbykgewoKICAgIElXaW5lRDNEQmFzZVNoYWRlckltcGwqIFRoaXMgPSAoSVdpbmVEM0RCYXNlU2hhZGVySW1wbCopIGlmYWNlOwogICAgSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopIFRoaXMtPmJhc2VTaGFkZXIuZGV2aWNlOwogICAgRFdPUkQgaSwgY3VyOwogICAgY2hhciBwc2hhZGVyID0gc2hhZGVyX2lzX3BzaGFkZXJfdmVyc2lvbihUaGlzLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uKTsKICAgIHVuc2lnbmVkIG1heF9jb25zdGFudHNGID0gbWluKFRoaXMtPmJhc2VTaGFkZXIubGltaXRzLmNvbnN0YW50X2Zsb2F0LCAKICAgICAgICAgICAgKHBzaGFkZXIgPyBHTF9MSU1JVFMocHNoYWRlcl9jb25zdGFudHNGKSA6IEdMX0xJTUlUUyh2c2hhZGVyX2NvbnN0YW50c0YpKSk7CiAgICBVSU5UIGV4dHJhX2NvbnN0YW50c19uZWVkZWQgPSAwOwogICAgbG9jYWxfY29uc3RhbnQqIGxjb25zdDsKCiAgICAvKiBUZW1wb3JhcnkgT3V0cHV0IHJlZ2lzdGVyICovCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJURU1QIFRNUF9PVVQ7XG4iKTsKCiAgICBmb3IoaSA9IDA7IGkgPCBUaGlzLT5iYXNlU2hhZGVyLmxpbWl0cy50ZW1wb3Jhcnk7IGkrKykgewogICAgICAgIGlmIChyZWdfbWFwcy0+dGVtcG9yYXJ5W2ldKQogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJURU1QIFIldTtcbiIsIGkpOwogICAgfQoKICAgIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5iYXNlU2hhZGVyLmxpbWl0cy5hZGRyZXNzOyBpKyspIHsKICAgICAgICBpZiAocmVnX21hcHMtPmFkZHJlc3NbaV0pCiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIkFERFJFU1MgQSVkO1xuIiwgaSk7CiAgICB9CgogICAgZm9yKGkgPSAwOyBpIDwgVGhpcy0+YmFzZVNoYWRlci5saW1pdHMudGV4Y29vcmQ7IGkrKykgewogICAgICAgIGlmIChyZWdfbWFwcy0+dGV4Y29vcmRbaV0pCiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwiVEVNUCBUJXU7XG4iLCBpKTsKICAgIH0KCiAgICAvKiBUZXh0dXJlIGNvb3JkaW5hdGUgcmVnaXN0ZXJzIG11c3QgYmUgcHJlLWxvYWRlZCAqLwogICAgZm9yIChpID0gMDsgaSA8IFRoaXMtPmJhc2VTaGFkZXIubGltaXRzLnRleGNvb3JkOyBpKyspIHsKICAgICAgICBpZiAocmVnX21hcHMtPnRleGNvb3JkW2ldKQogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJNT1YgVCV1LCBmcmFnbWVudC50ZXhjb29yZFsldV07XG4iLCBpLCBpKTsKICAgIH0KCiAgICBmb3IoaSA9IDA7IGkgPCAoc2l6ZW9mKHJlZ19tYXBzLT5idW1wbWF0KSAvIHNpemVvZihyZWdfbWFwcy0+YnVtcG1hdFswXSkpOyBpKyspIHsKICAgICAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqcHMgPSAoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwgKikgVGhpczsKICAgICAgICBpZighcmVnX21hcHMtPmJ1bXBtYXRbaV0pIGNvbnRpbnVlOwoKICAgICAgICBjdXIgPSBwcy0+bnVtYnVtcGVudm1hdGNvbnN0czsKICAgICAgICBwcy0+YnVtcGVudm1hdGNvbnN0W2N1cl0uY29uc3RfbnVtID0gLTE7CiAgICAgICAgcHMtPmJ1bXBlbnZtYXRjb25zdFtjdXJdLnRleHVuaXQgPSBpOwogICAgICAgIHBzLT5sdW1pbmFuY2Vjb25zdFtjdXJdLmNvbnN0X251bSA9IC0xOwogICAgICAgIHBzLT5sdW1pbmFuY2Vjb25zdFtjdXJdLnRleHVuaXQgPSBpOwoKICAgICAgICAvKiBJZiB0aGUgc2hhZGVyIGRvZXMgbm90IHVzZSBhbGwgYXZhaWxhYmxlIGNvbnN0YW50cywgdXNlIHRoZSBuZXh0IGZyZWUgY29uc3RhbnQgdG8gbG9hZCB0aGUgYnVtcCBtYXBwaW5nIGVudmlyb25tZW50IG1hdHJpeCBmcm9tCiAgICAgICAgICogdGhlIHN0YXRlYmxvY2sgaW50byB0aGUgc2hhZGVyLiBJZiBubyBjb25zdGFudCBpcyBhdmFpbGFibGUgZG9uJ3QgbG9hZCwgdGV4YmVtIHdpbGwgdGhlbiBqdXN0IHNhbXBsZSB0aGUgdGV4dHVyZSB3aXRob3V0IGFwcGx5aW5nCiAgICAgICAgICogYnVtcCBtYXBwaW5nLgogICAgICAgICAqLwogICAgICAgIGlmKG1heF9jb25zdGFudHNGICsgZXh0cmFfY29uc3RhbnRzX25lZWRlZCA8IEdMX0xJTUlUUyhwc2hhZGVyX2NvbnN0YW50c0YpKSB7CiAgICAgICAgICAgIHBzLT5idW1wZW52bWF0Y29uc3RbY3VyXS5jb25zdF9udW0gPSBtYXhfY29uc3RhbnRzRiArIGV4dHJhX2NvbnN0YW50c19uZWVkZWQ7CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlBBUkFNIGJ1bXBlbnZtYXQlZCA9IHByb2dyYW0uZW52WyVkXTtcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGksIHBzLT5idW1wZW52bWF0Y29uc3RbY3VyXS5jb25zdF9udW0pOwogICAgICAgICAgICBleHRyYV9jb25zdGFudHNfbmVlZGVkKys7CgogICAgICAgICAgICBpZihyZWdfbWFwcy0+bHVtaW5hbmNlcGFyYW1zICYmIG1heF9jb25zdGFudHNGICsgZXh0cmFfY29uc3RhbnRzX25lZWRlZCA8IEdMX0xJTUlUUyhwc2hhZGVyX2NvbnN0YW50c0YpKSB7CiAgICAgICAgICAgICAgICAoKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICopVGhpcyktPmx1bWluYW5jZWNvbnN0W2N1cl0uY29uc3RfbnVtID0gbWF4X2NvbnN0YW50c0YgKyBleHRyYV9jb25zdGFudHNfbmVlZGVkOwogICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiUEFSQU0gbHVtaW5hbmNlJWQgPSBwcm9ncmFtLmVudlslZF07XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaSwgcHMtPmx1bWluYW5jZWNvbnN0W2N1cl0uY29uc3RfbnVtKTsKICAgICAgICAgICAgICAgIGV4dHJhX2NvbnN0YW50c19uZWVkZWQrKzsKICAgICAgICAgICAgfSBlbHNlIGlmKHJlZ19tYXBzLT5sdW1pbmFuY2VwYXJhbXMpIHsKICAgICAgICAgICAgICAgIEZJWE1FKCJObyBmcmVlIGNvbnN0YW50IHRvIGxvYWQgdGhlIGx1bWluYW5jZSBwYXJhbWV0ZXJzXG4iKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIEZJWE1FKCJObyBmcmVlIGNvbnN0YW50IGZvdW5kIHRvIGxvYWQgZW52aXJvbmVtbnQgYnVtcCBtYXBwaW5nIG1hdHJpeCBpbnRvIHRoZSBzaGFkZXIuIHRleGJlbSBpbnN0cnVjdGlvbiB3aWxsIG5vdCBhcHBseSBidW1wIG1hcHBpbmdcbiIpOwogICAgICAgIH0KCiAgICAgICAgcHMtPm51bWJ1bXBlbnZtYXRjb25zdHMgPSBjdXIgKyAxOwogICAgfQoKICAgIGlmKGRldmljZS0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbV0lORUQzRFJTX1NSR0JXUklURUVOQUJMRV0gJiYgcHNoYWRlcikgewogICAgICAgIElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICpwc19pbXBsID0gKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICopIFRoaXM7CiAgICAgICAgLyogSWYgdGhlcmUgYXJlIDIgY29uc3RhbnRzIGxlZnQgdG8gdXNlLCB1c2UgdGhlbSB0byBwYXNzIHRoZSBzUkdCIGNvcnJlY3Rpb24gdmFsdWVzIGluLiBUaGlzIHdheQogICAgICAgICAqIHNyZ2Igd3JpdGUgY29ycmVjdGlvbiBjYW4gYmUgdHVybmVkIG9uIGFuZCBvZmYgZHluYW1pY2FsbHkgd2l0aG91dCByZWNvbXBpbGF0aW9uLiBPdGhlcndpc2UKICAgICAgICAgKiBoYXJkY29kZSB0aGVtLiBUaGUgZHJhd2JhY2sgb2YgaGFyZGNvZGluZyBpcyB0aGF0IHRoZSBzaGFkZXIgbmVlZHMgcmVjb21waWxhdGlvbiB0byB0dXJuIHNSR0IKICAgICAgICAgKiBvZmYgYWdhaW4KICAgICAgICAgKi8KICAgICAgICBpZihtYXhfY29uc3RhbnRzRiArIGV4dHJhX2NvbnN0YW50c19uZWVkZWQgKyAxIDwgR0xfTElNSVRTKHBzaGFkZXJfY29uc3RhbnRzRikgJiYgRkFMU0UpIHsKICAgICAgICAgICAgLyogVGhlIGlkZWEgaXMgdGhhdCBpZiBzcmdiIGlzIGVuYWJsZWQsIHRoZW4gZGlzYWJsZWQsIHRoZSBjb25zdGFudCBsb2FkaW5nIGNvZGUKICAgICAgICAgICAgICogY2FuIGVmZmVjdGl2ZWx5IGRpc2FibGUgc1JHQiBjb3JyZWN0aW9uIGJ5IHBhc3NpbmcgMS4wIGFuZCBJTkYgYXMgdGhlIG11bHRpcGxpY2F0aW9uCiAgICAgICAgICAgICAqIGFuZCBjb21wYXJpc29uIGNvbnN0YW50cy4gSWYgaXQgZGlzYWJsZXMgaXQgdGhhdCB3YXksIHRoZSBzaGFkZXIgd29uJ3QgYmUgcmVjb21waWxlZAogICAgICAgICAgICAgKiBhbmQgdGhlIGNvZGUgd2lsbCBzdGF5IGluLCBzbyBzUkdCIHdyaXRpbmcgY2FuIGJlIHR1cm5lZCBvbiBhZ2FpbiBieSBzZXR0aW5nIHRoZQogICAgICAgICAgICAgKiBjb25zdGFudHMgZnJvbSB0aGUgc3BlYwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcHNfaW1wbC0+c3JnYl9tb2RlX2hhcmRjb2RlZCA9IDA7CiAgICAgICAgICAgIHBzX2ltcGwtPnNyZ2JfbG93X2NvbnN0ID0gR0xfTElNSVRTKHBzaGFkZXJfY29uc3RhbnRzRikgLSBleHRyYV9jb25zdGFudHNfbmVlZGVkOwogICAgICAgICAgICBwc19pbXBsLT5zcmdiX2NtcF9jb25zdCA9IEdMX0xJTUlUUyhwc2hhZGVyX2NvbnN0YW50c0YpIC0gZXh0cmFfY29uc3RhbnRzX25lZWRlZCAtIDE7CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlBBUkFNIHNyZ2JfbXVsX2xvdyA9IHByb2dyYW0uZW52WyVkXTtcbiIsIHBzX2ltcGwtPnNyZ2JfbG93X2NvbnN0KTsKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiUEFSQU0gc3JnYl9jb21wYXJpc29uID0gcHJvZ3JhbS5lbnZbJWRdO1xuIiwgcHNfaW1wbC0+c3JnYl9jbXBfY29uc3QpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlBBUkFNIHNyZ2JfbXVsX2xvdyA9IHslZiwgJWYsICVmLCAxLjB9O1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JnYl9tdWxfbG93LCBzcmdiX211bF9sb3csIHNyZ2JfbXVsX2xvdyk7CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlBBUkFNIHNyZ2JfY29tcGFyaXNvbiA9ICB7JWYsICVmLCAlZiwgJWZ9O1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc3JnYl9jbXAsIHNyZ2JfY21wLCBzcmdiX2NtcCwgc3JnYl9jbXApOwogICAgICAgICAgICBwc19pbXBsLT5zcmdiX21vZGVfaGFyZGNvZGVkID0gMTsKICAgICAgICB9CiAgICAgICAgLyogVGhlc2UgY2FuIGJlIGhhcmRjb2RlZCwgdGhleSBkbyBub3QgY2F1c2UgYW55IGhhcm0gYmVjYXVzZSBubyBmcmFnbWVudCB3aWxsIGVudGVyIHRoZSBoaWdoCiAgICAgICAgICogcGF0aCBpZiB0aGUgY29tcGFyaXNvbiB2YWx1ZSBpcyBzZXQgdG8gSU5GCiAgICAgICAgICovCiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiUEFSQU0gc3JnYl9wb3cgPSAgeyVmLCAlZiwgJWYsIDEuMH07XG4iLAogICAgICAgICAgICAgICAgICAgICAgIHNyZ2JfcG93LCBzcmdiX3Bvdywgc3JnYl9wb3cpOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlBBUkFNIHNyZ2JfbXVsX2hpID0gIHslZiwgJWYsICVmLCAxLjB9O1xuIiwKICAgICAgICAgICAgICAgICAgICAgICBzcmdiX211bF9oaWdoLCBzcmdiX211bF9oaWdoLCBzcmdiX211bF9oaWdoKTsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJQQVJBTSBzcmdiX3N1Yl9oaSA9ICB7JWYsICVmLCAlZiwgMC4wfTtcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgc3JnYl9zdWJfaGlnaCwgc3JnYl9zdWJfaGlnaCwgc3JnYl9zdWJfaGlnaCk7CiAgICAgICAgcHNfaW1wbC0+c3JnYl9lbmFibGVkID0gMTsKICAgIH0gZWxzZSBpZihwc2hhZGVyKSB7CiAgICAgICAgSVdpbmVEM0RQaXhlbFNoYWRlckltcGwgKnBzX2ltcGwgPSAoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwgKikgVGhpczsKCiAgICAgICAgLyogRG8gbm90IHdyaXRlIGFueSBzcmdiIGZpeHVwIGludG8gdGhlIHNoYWRlciB0byBzYXZlIHNoYWRlciBzaXplIGFuZCBwcm9jZXNzaW5nIHRpbWUuCiAgICAgICAgICogQXMgYSBjb25zZXF1ZW5jZSwgd2UgY2FuJ3QgdG9nZ2xlIHNyZ2Igd3JpdGUgb24gd2l0aG91dCByZWNvbXBpbGF0aW9uCiAgICAgICAgICovCiAgICAgICAgcHNfaW1wbC0+c3JnYl9lbmFibGVkID0gMDsKICAgICAgICBwc19pbXBsLT5zcmdiX21vZGVfaGFyZGNvZGVkID0gMTsKICAgIH0KCiAgICAvKiBIYXJkY29kYWJsZSBsb2NhbCBjb25zdGFudHMgKi8KICAgIGlmKCFUaGlzLT5iYXNlU2hhZGVyLmxvYWRfbG9jYWxfY29uc3RzRikgewogICAgICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkobGNvbnN0LCAmVGhpcy0+YmFzZVNoYWRlci5jb25zdGFudHNGLCBsb2NhbF9jb25zdGFudCwgZW50cnkpIHsKICAgICAgICAgICAgZmxvYXQgKnZhbHVlID0gKGZsb2F0ICopIGxjb25zdC0+dmFsdWU7CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlBBUkFNIEMldSA9IHslZiwgJWYsICVmLCAlZn07XG4iLCBsY29uc3QtPmlkeCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVbMF0sIHZhbHVlWzFdLCB2YWx1ZVsyXSwgdmFsdWVbM10pOwogICAgICAgIH0KICAgIH0KCiAgICAvKiB3ZSB1c2UgdGhlIGFycmF5LWJhc2VkIGNvbnN0YW50cyBhcnJheSBpZiB0aGUgbG9jYWwgY29uc3RhbnRzIGFyZSBtYXJrZWQgZm9yIGxvYWRpbmcsCiAgICAgKiBiZWNhdXNlIHRoZW4gd2UgdXNlIGluZGlyZWN0IGFkZHJlc3NpbmcsIG9yIHdoZW4gdGhlIGxvY2FsIGNvbnN0YW50IGxpc3QgaXMgZW1wdHksCiAgICAgKiBiZWNhdXNlIHRoZW4gd2UgZG9uJ3Qga25vdyBpZiB3ZSdyZSB1c2luZyBpbmRpcmVjdCBhZGRyZXNzaW5nIG9yIG5vdC4gSWYgd2UncmUgaGFyZGNvZGluZwogICAgICogbG9jYWwgY29uc3RhbnRzIGRvIG5vdCBkZWNsYXJlIHRoZSBsb2FkZWQgY29uc3RhbnRzIGFzIGFuIGFycmF5IGJlY2F1c2UgQVJCIGNvbXBpbGVycyB1c3VhbGx5CiAgICAgKiBkbyBub3Qgb3B0aW1pemUgdW51c2VkIGNvbnN0YW50cyBhd2F5CiAgICAgKi8KICAgIGlmKFRoaXMtPmJhc2VTaGFkZXIubG9hZF9sb2NhbF9jb25zdHNGIHx8IGxpc3RfZW1wdHkoJlRoaXMtPmJhc2VTaGFkZXIuY29uc3RhbnRzRikpIHsKICAgICAgICAvKiBOZWVkIHRvIFBBUkFNIHRoZSBlbnZpcm9ubWVudCBwYXJhbWV0ZXJzIChjb25zdGFudHMpIHNvIHdlIGNhbiB1c2UgcmVsYXRpdmUgYWRkcmVzc2luZyAqLwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlBBUkFNIENbJWRdID0geyBwcm9ncmFtLmVudlswLi4lZF0gfTtcbiIsCiAgICAgICAgICAgICAgICAgICAgbWF4X2NvbnN0YW50c0YsIG1heF9jb25zdGFudHNGIC0gMSk7CiAgICB9IGVsc2UgewogICAgICAgIGZvcihpID0gMDsgaSA8IG1heF9jb25zdGFudHNGOyBpKyspIHsKICAgICAgICAgICAgaWYoIXNoYWRlcl9jb25zdGFudF9pc19sb2NhbChUaGlzLCBpKSkgewogICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiUEFSQU0gQyVkID0gcHJvZ3JhbS5lbnZbJWRdO1xuIixpLCBpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KfQoKc3RhdGljIGNvbnN0IGNoYXIgKiBjb25zdCBzaGlmdF90YWJbXSA9IHsKICAgICJkdW1teSIsICAgICAvKiAgMCAobm9uZSkgKi8KICAgICJjb2VmbXVsLngiLCAvKiAgMSAoeDIpICAgKi8KICAgICJjb2VmbXVsLnkiLCAvKiAgMiAoeDQpICAgKi8KICAgICJjb2VmbXVsLnoiLCAvKiAgMyAoeDgpICAgKi8KICAgICJjb2VmbXVsLnciLCAvKiAgNCAoeDE2KSAgKi8KICAgICJkdW1teSIsICAgICAvKiAgNSAoeDMyKSAgKi8KICAgICJkdW1teSIsICAgICAvKiAgNiAoeDY0KSAgKi8KICAgICJkdW1teSIsICAgICAvKiAgNyAoeDEyOCkgKi8KICAgICJkdW1teSIsICAgICAvKiAgOCAoZDI1NikgKi8KICAgICJkdW1teSIsICAgICAvKiAgOSAoZDEyOCkgKi8KICAgICJkdW1teSIsICAgICAvKiAxMCAoZDY0KSAgKi8KICAgICJkdW1teSIsICAgICAvKiAxMSAoZDMyKSAgKi8KICAgICJjb2VmZGl2LnciLCAvKiAxMiAoZDE2KSAgKi8KICAgICJjb2VmZGl2LnoiLCAvKiAxMyAoZDgpICAgKi8KICAgICJjb2VmZGl2LnkiLCAvKiAxNCAoZDQpICAgKi8KICAgICJjb2VmZGl2LngiICAvKiAxNSAoZDIpICAgKi8KfTsKCnN0YXRpYyB2b2lkIHNoYWRlcl9hcmJfZ2V0X3dyaXRlX21hc2soU0hBREVSX09QQ09ERV9BUkcqIGFyZywgY29uc3QgRFdPUkQgcGFyYW0sIGNoYXIgKndyaXRlX21hc2spIHsKICAgIElXaW5lRDNEQmFzZVNoYWRlckltcGwgKlRoaXMgPSAoSVdpbmVEM0RCYXNlU2hhZGVySW1wbCAqKSBhcmctPnNoYWRlcjsKICAgIGNoYXIgKnB0ciA9IHdyaXRlX21hc2s7CiAgICBjaGFyIHZzaGFkZXIgPSBzaGFkZXJfaXNfdnNoYWRlcl92ZXJzaW9uKFRoaXMtPmJhc2VTaGFkZXIuaGV4X3ZlcnNpb24pOwoKICAgIGlmKHZzaGFkZXIgJiYgc2hhZGVyX2dldF9yZWd0eXBlKHBhcmFtKSA9PSBXSU5FRDNEU1BSX0FERFIpIHsKICAgICAgICAqcHRyKysgPSAnLic7CiAgICAgICAgKnB0cisrID0gJ3gnOwogICAgfSBlbHNlIGlmICgocGFyYW0gJiBXSU5FRDNEU1BfV1JJVEVNQVNLX0FMTCkgIT0gV0lORUQzRFNQX1dSSVRFTUFTS19BTEwpIHsKICAgICAgICAqcHRyKysgPSAnLic7CiAgICAgICAgaWYgKHBhcmFtICYgV0lORUQzRFNQX1dSSVRFTUFTS18wKSAqcHRyKysgPSAneCc7CiAgICAgICAgaWYgKHBhcmFtICYgV0lORUQzRFNQX1dSSVRFTUFTS18xKSAqcHRyKysgPSAneSc7CiAgICAgICAgaWYgKHBhcmFtICYgV0lORUQzRFNQX1dSSVRFTUFTS18yKSAqcHRyKysgPSAneic7CiAgICAgICAgaWYgKHBhcmFtICYgV0lORUQzRFNQX1dSSVRFTUFTS18zKSAqcHRyKysgPSAndyc7CiAgICB9CgogICAgKnB0ciA9ICdcMCc7Cn0KCnN0YXRpYyB2b2lkIHNoYWRlcl9hcmJfZ2V0X3N3aXp6bGUoY29uc3QgRFdPUkQgcGFyYW0sIEJPT0wgZml4dXAsIGNoYXIgKnN3aXp6bGVfc3RyKSB7CiAgICAvKiBGb3IgcmVnaXN0ZXJzIG9mIHR5cGUgV0lORUQzRERFQ0xUWVBFX0QzRENPTE9SLCBkYXRhIGlzIHN0b3JlZCBhcyAiYmdyYSIsCiAgICAgKiBidXQgYWRkcmVzc2VkIGFzICJyZ2JhIi4gVG8gZml4IHRoaXMgd2UgbmVlZCB0byBzd2FwIHRoZSByZWdpc3RlcidzIHgKICAgICAqIGFuZCB6IGNvbXBvbmVudHMuICovCiAgICBjb25zdCBjaGFyICpzd2l6emxlX2NoYXJzID0gZml4dXAgPyAienl4dyIgOiAieHl6dyI7CiAgICBjaGFyICpwdHIgPSBzd2l6emxlX3N0cjsKCiAgICAvKiBzd2l6emxlIGJpdHMgZmllbGRzOiB3d3p6eXl4eCAqLwogICAgRFdPUkQgc3dpenpsZSA9IChwYXJhbSAmIFdJTkVEM0RTUF9TV0laWkxFX01BU0spID4+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+ZGVwdGhfYmx0X2Zwcm9ncmFtX2lkKSk7CiAgICBnbEVuYWJsZShHTF9GUkFHTUVOVF9QUk9HUkFNX0FSQik7Cn0KCnN0YXRpYyB2b2lkIHNoYWRlcl9hcmJfZGVzdHJveV9kZXB0aF9ibHQoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBzdHJ1Y3Qgc2hhZGVyX2FyYl9wcml2ICpwcml2ID0gKHN0cnVjdCBzaGFkZXJfYXJiX3ByaXYgKikgVGhpcy0+c2hhZGVyX3ByaXY7CiAgICBXaW5lRDNEX0dMX0luZm8gKmdsX2luZm8gPSAmVGhpcy0+YWRhcHRlci0+Z2xfaW5mbzsKCiAgICBpZihwcml2LT5kZXB0aF9ibHRfdnByb2dyYW1faWQpIHsKICAgICAgICBHTF9FWFRDQUxMKGdsRGVsZXRlUHJvZ3JhbXNBUkIoMSwgJnByaXYtPmRlcHRoX2JsdF92cHJvZ3JhbV9pZCkpOwogICAgICAgIHByaXYtPmRlcHRoX2JsdF92cHJvZ3JhbV9pZCA9IDA7CiAgICB9CiAgICBpZihwcml2LT5kZXB0aF9ibHRfZnByb2dyYW1faWQpIHsKICAgICAgICBHTF9FWFRDQUxMKGdsRGVsZXRlUHJvZ3JhbXNBUkIoMSwgJnByaXYtPmRlcHRoX2JsdF9mcHJvZ3JhbV9pZCkpOwogICAgICAgIHByaXYtPmRlcHRoX2JsdF9mcHJvZ3JhbV9pZCA9IDA7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIHNoYWRlcl9hcmJfY2xlYW51cChJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFdpbmVEM0RfR0xfSW5mbyAqZ2xfaW5mbyA9ICZUaGlzLT5hZGFwdGVyLT5nbF9pbmZvOwogICAgaWYgKEdMX1NVUFBPUlQoQVJCX1ZFUlRFWF9QUk9HUkFNKSkgZ2xEaXNhYmxlKEdMX1ZFUlRFWF9QUk9HUkFNX0FSQik7CiAgICBpZiAoR0xfU1VQUE9SVChBUkJfRlJBR01FTlRfUFJPR1JBTSkpIGdsRGlzYWJsZShHTF9GUkFHTUVOVF9QUk9HUkFNX0FSQik7Cn0KCnN0YXRpYyB2b2lkIHNoYWRlcl9hcmJfZGVzdHJveShJV2luZUQzREJhc2VTaGFkZXIgKmlmYWNlKSB7CiAgICBJV2luZUQzREJhc2VTaGFkZXJJbXBsICpUaGlzID0gKElXaW5lRDNEQmFzZVNoYWRlckltcGwgKikgaWZhY2U7CiAgICBXaW5lRDNEX0dMX0luZm8gKmdsX2luZm8gPSAmKChJV2luZUQzRERldmljZUltcGwgKikgVGhpcy0+YmFzZVNoYWRlci5kZXZpY2UpLT5hZGFwdGVyLT5nbF9pbmZvOwoKICAgIEVOVEVSX0dMKCk7CiAgICBHTF9FWFRDQUxMKGdsRGVsZXRlUHJvZ3JhbXNBUkIoMSwgJlRoaXMtPmJhc2VTaGFkZXIucHJnSWQpKTsKICAgIGNoZWNrR0xjYWxsKCJHTF9FWFRDQUxMKGdsRGVsZXRlUHJvZ3JhbXNBUkIoMSwgJlRoaXMtPmJhc2VTaGFkZXIucHJnSWQpKSIpOwogICAgTEVBVkVfR0woKTsKICAgIFRoaXMtPmJhc2VTaGFkZXIucHJnSWQgPSAwOwogICAgVGhpcy0+YmFzZVNoYWRlci5pc19jb21waWxlZCA9IEZBTFNFOwp9CgpzdGF0aWMgSFJFU1VMVCBzaGFkZXJfYXJiX2FsbG9jKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgVGhpcy0+c2hhZGVyX3ByaXYgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKHN0cnVjdCBzaGFkZXJfYXJiX3ByaXYpKTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpzdGF0aWMgdm9pZCBzaGFkZXJfYXJiX2ZyZWUoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5zaGFkZXJfcHJpdik7Cn0KCnN0YXRpYyBCT09MIHNoYWRlcl9hcmJfZGlydHlfY29uc3QoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIHZvaWQgc2hhZGVyX2FyYl9nZW5lcmF0ZV9wc2hhZGVyKElXaW5lRDNEUGl4ZWxTaGFkZXIgKmlmYWNlLCBTSEFERVJfQlVGRkVSICpidWZmZXIpIHsKICAgIElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICpUaGlzID0gKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICopaWZhY2U7CiAgICBzaGFkZXJfcmVnX21hcHMqIHJlZ19tYXBzID0gJlRoaXMtPmJhc2VTaGFkZXIucmVnX21hcHM7CiAgICBDT05TVCBEV09SRCAqZnVuY3Rpb24gPSBUaGlzLT5iYXNlU2hhZGVyLmZ1bmN0aW9uOwogICAgY29uc3QgY2hhciAqZnJhZ2NvbG9yOwogICAgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvID0gJigoSVdpbmVEM0REZXZpY2VJbXBsICopVGhpcy0+YmFzZVNoYWRlci5kZXZpY2UpLT5hZGFwdGVyLT5nbF9pbmZvOwoKICAgIC8qICBDcmVhdGUgdGhlIGh3IEFSQiBzaGFkZXIgKi8KICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIiEhQVJCZnAxLjBcbiIpOwoKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlRFTVAgVE1QO1xuIik7ICAgICAvKiBVc2VkIGluIG1hdHJpeCBvcHMgKi8KICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlRFTVAgVE1QMjtcbiIpOyAgICAvKiBVc2VkIGluIG1hdHJpeCBvcHMgKi8KICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlRFTVAgVEE7XG4iKTsgICAgICAvKiBVc2VkIGZvciBtb2RpZmllcnMgKi8KICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlRFTVAgVEI7XG4iKTsgICAgICAvKiBVc2VkIGZvciBtb2RpZmllcnMgKi8KICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlRFTVAgVEM7XG4iKTsgICAgICAvKiBVc2VkIGZvciBtb2RpZmllcnMgKi8KICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlBBUkFNIGNvZWZkaXYgPSB7IDAuNSwgMC4yNSwgMC4xMjUsIDAuMDYyNSB9O1xuIik7CiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJQQVJBTSBjb2VmbXVsID0geyAyLCA0LCA4LCAxNiB9O1xuIik7CiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJQQVJBTSBvbmUgPSB7IDEuMCwgMS4wLCAxLjAsIDEuMCB9O1xuIik7CgogICAgLyogQmFzZSBEZWNsYXJhdGlvbnMgKi8KICAgIHNoYWRlcl9nZW5lcmF0ZV9hcmJfZGVjbGFyYXRpb25zKCAoSVdpbmVEM0RCYXNlU2hhZGVyKikgVGhpcywgcmVnX21hcHMsIGJ1ZmZlciwgJkdMSU5GT19MT0NBVElPTik7CgogICAgLyogV2UgbmVlZCB0d28gdmFyaWFibGVzIGZvciBmb2cgYmxlbmRpbmcgKi8KICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlRFTVAgVE1QX0ZPRztcbiIpOwogICAgaWYgKFRoaXMtPmJhc2VTaGFkZXIuaGV4X3ZlcnNpb24gPj0gV0lORUQzRFBTX1ZFUlNJT04oMiwwKSkgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlRFTVAgVE1QX0NPTE9SO1xuIik7CiAgICB9CgogICAgLyogQmFzZSBTaGFkZXIgQm9keSAqLwogICAgc2hhZGVyX2dlbmVyYXRlX21haW4oIChJV2luZUQzREJhc2VTaGFkZXIqKSBUaGlzLCBidWZmZXIsIHJlZ19tYXBzLCBmdW5jdGlvbik7CgogICAgLyogY2FsY3VsYXRlIGZvZyBhbmQgYmxlbmQgaXQKICAgICAqIE5PVEU6IHN0YXRlLmZvZy5wYXJhbXMueSBhbmQgc3RhdGUuZm9nLnBhcmFtcy56IGRvbid0IGhvbGQgZm9nIHN0YXJ0IHMgYW5kIGVuZCBlIGJ1dAogICAgICogLTEvKGUtcykgYW5kIGUvKGUtcykgcmVzcGVjdGl2ZWx5LgogICAgICovCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJNQURfU0FUIFRNUF9GT0csIGZyYWdtZW50LmZvZ2Nvb3JkLCBzdGF0ZS5mb2cucGFyYW1zLnksIHN0YXRlLmZvZy5wYXJhbXMuejtcbiIpOwoKICAgIGlmIChUaGlzLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uIDwgV0lORUQzRFBTX1ZFUlNJT04oMiwwKSkgewogICAgICAgIGZyYWdjb2xvciA9ICJSMCI7CiAgICB9IGVsc2UgewogICAgICAgIGZyYWdjb2xvciA9ICJUTVBfQ09MT1IiOwogICAgfQogICAgaWYoVGhpcy0+c3JnYl9lbmFibGVkKSB7CiAgICAgICAgLyogUGVyZm9ybSBzUkdCIHdyaXRlIGNvcnJlY3Rpb24uIFNlZSBHTFhfRVhUX2ZyYW1lYnVmZmVyX3NSR0IgKi8KCiAgICAgICAgLyogQ2FsY3VsYXRlIHRoZSA+IDAuMDAzMTMwOCBjYXNlICovCiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiUE9XIFRNUC54LCAlcy54LCBzcmdiX3Bvdy54O1xuIiwgZnJhZ2NvbG9yKTsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJQT1cgVE1QLnksICVzLnksIHNyZ2JfcG93Lnk7XG4iLCBmcmFnY29sb3IpOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlBPVyBUTVAueiwgJXMueiwgc3JnYl9wb3cuejtcbiIsIGZyYWdjb2xvcik7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTVVMIFRNUCwgVE1QLCBzcmdiX211bF9oaTtcbiIpOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlNVQiBUTVAsIFRNUCwgc3JnYl9zdWJfaGk7XG4iKTsKICAgICAgICAvKiBDYWxjdWxhdGUgdGhlIDwgY2FzZSAqLwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIk1VTCBUTVAyLCBzcmdiX211bF9sb3csICVzO1xuIiwgZnJhZ2NvbG9yKTsKICAgICAgICAvKiBHZXQgMS4wIC8gMC4wIG1hc2tzIGZvciA+IDAuMDAzMTMwOCBhbmQgPCAwLjAwMzEzMDggKi8KICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJTTFQgVEEsIHNyZ2JfY29tcGFyaXNvbiwgJXM7XG4iLCBmcmFnY29sb3IpOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlNHRSBUQiwgc3JnYl9jb21wYXJpc29uLCAlcztcbiIsIGZyYWdjb2xvcik7CiAgICAgICAgLyogU3RvcmUgdGhlIGNvbXBvbmVudHMgPiAwLjAwMzEzMDggaW4gdGhlIGRlc3RpbmF0aW9uICovCiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTVVMICVzLCBUTVAsIFRBO1xuIiwgZnJhZ2NvbG9yKTsKICAgICAgICAvKiBBZGQgdGhlIGNvbXBvbmVudHMgdGhhdCBhcmUgPCAwLjAwMzEzMDggKi8KICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJNQUQgcmVzdWx0LmNvbG9yLnh5eiwgVE1QMiwgVEIsICVzO1xuIiwgZnJhZ2NvbG9yKTsKICAgICAgICAvKiBbMC4wOzEuMF0gY2xhbXBpbmcuIE5vdCBuZWVkZWQsIHRoaXMgaXMgZG9uZSBpbXBsaWNpdGx5ICovCiAgICB9CiAgICBpZiAoVGhpcy0+YmFzZVNoYWRlci5oZXhfdmVyc2lvbiA8IFdJTkVEM0RQU19WRVJTSU9OKDMsMCkpIHsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJMUlAgcmVzdWx0LmNvbG9yLnJnYiwgVE1QX0ZPRy54LCAlcywgc3RhdGUuZm9nLmNvbG9yO1xuIiwgZnJhZ2NvbG9yKTsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJNT1YgcmVzdWx0LmNvbG9yLmEsICVzLmE7XG4iLCBmcmFnY29sb3IpOwogICAgfQoKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIkVORFxuIik7CgogICAgLyogVE9ETzogY2hhbmdlIHRvIHJlc291cmNlLmdsT2JqZWN0SGFuZGxlIG9yIHNvbWV0aGluZyBsaWtlIHRoYXQgKi8KICAgIEdMX0VYVENBTEwoZ2xHZW5Qcm9ncmFtc0FSQigxLCAmVGhpcy0+YmFzZVNoYWRlci5wcmdJZCkpOwoKICAgIFRSQUNFKCJDcmVhdGluZyBhIGh3IHBpeGVsIHNoYWRlciwgcHJnPSVkXG4iLCBUaGlzLT5iYXNlU2hhZGVyLnByZ0lkKTsKICAgIEdMX0VYVENBTEwoZ2xCaW5kUHJvZ3JhbUFSQihHTF9GUkFHTUVOVF9QUk9HUkFNX0FSQiwgVGhpcy0+YmFzZVNoYWRlci5wcmdJZCkpOwoKICAgIFRSQUNFKCJDcmVhdGVkIGh3IHBpeGVsIHNoYWRlciwgcHJnPSVkXG4iLCBUaGlzLT5iYXNlU2hhZGVyLnByZ0lkKTsKICAgIC8qIENyZWF0ZSB0aGUgcHJvZ3JhbSBhbmQgY2hlY2sgZm9yIGVycm9ycyAqLwogICAgR0xfRVhUQ0FMTChnbFByb2dyYW1TdHJpbmdBUkIoR0xfRlJBR01FTlRfUFJPR1JBTV9BUkIsIEdMX1BST0dSQU1fRk9STUFUX0FTQ0lJX0FSQiwKICAgICAgICAgICAgICAgYnVmZmVyLT5ic2l6ZSwgYnVmZmVyLT5idWZmZXIpKTsKCiAgICBpZiAoZ2xHZXRFcnJvcigpID09IEdMX0lOVkFMSURfT1BFUkFUSU9OKSB7CiAgICAgICAgR0xpbnQgZXJyUG9zOwogICAgICAgIGdsR2V0SW50ZWdlcnYoR0xfUFJPR1JBTV9FUlJPUl9QT1NJVElPTl9BUkIsICZlcnJQb3MpOwogICAgICAgIEZJWE1FKCJIVyBQaXhlbFNoYWRlciBFcnJvciBhdCBwb3NpdGlvbiAlZDogJXNcbiIsCiAgICAgICAgICAgICAgZXJyUG9zLCBkZWJ1Z3N0cl9hKChjb25zdCBjaGFyICopZ2xHZXRTdHJpbmcoR0xfUFJPR1JBTV9FUlJPUl9TVFJJTkdfQVJCKSkpOwogICAgICAgIFRoaXMtPmJhc2VTaGFkZXIucHJnSWQgPSAtMTsKICAgIH0KfQoKc3RhdGljIHZvaWQgc2hhZGVyX2FyYl9nZW5lcmF0ZV92c2hhZGVyKElXaW5lRDNEVmVydGV4U2hhZGVyICppZmFjZSwgU0hBREVSX0JVRkZFUiAqYnVmZmVyKSB7CiAgICBJV2luZUQzRFZlcnRleFNoYWRlckltcGwgKlRoaXMgPSAoSVdpbmVEM0RWZXJ0ZXhTaGFkZXJJbXBsICopaWZhY2U7CiAgICBzaGFkZXJfcmVnX21hcHMqIHJlZ19tYXBzID0gJlRoaXMtPmJhc2VTaGFkZXIucmVnX21hcHM7CiAgICBDT05TVCBEV09SRCAqZnVuY3Rpb24gPSBUaGlzLT5iYXNlU2hhZGVyLmZ1bmN0aW9uOwogICAgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvID0gJigoSVdpbmVEM0REZXZpY2VJbXBsICopVGhpcy0+YmFzZVNoYWRlci5kZXZpY2UpLT5hZGFwdGVyLT5nbF9pbmZvOwoKICAgIC8qICBDcmVhdGUgdGhlIGh3IEFSQiBzaGFkZXIgKi8KICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIiEhQVJCdnAxLjBcbiIpOwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiUEFSQU0gaGVscGVyX2NvbnN0ID0geyAyLjAsIC0xLjAsICVkLjAsIDAuMCB9O1xuIiwgVGhpcy0+cmVsX29mZnNldCk7CgogICAgLyogTWVzYSBzdXBwb3J0cyBvbmx5IDk1IGNvbnN0YW50cyAqLwogICAgaWYgKEdMX1ZFTkQoTUVTQSkgfHwgR0xfVkVORChXSU5FKSkKICAgICAgICBUaGlzLT5iYXNlU2hhZGVyLmxpbWl0cy5jb25zdGFudF9mbG9hdCA9CiAgICAgICAgICAgICAgICBtaW4oOTUsIFRoaXMtPmJhc2VTaGFkZXIubGltaXRzLmNvbnN0YW50X2Zsb2F0KTsKCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJURU1QIFRNUDtcbiIpOwoKICAgIC8qIEJhc2UgRGVjbGFyYXRpb25zICovCiAgICBzaGFkZXJfZ2VuZXJhdGVfYXJiX2RlY2xhcmF0aW9ucyggKElXaW5lRDNEQmFzZVNoYWRlciopIFRoaXMsIHJlZ19tYXBzLCBidWZmZXIsICZHTElORk9fTE9DQVRJT04pOwoKICAgIC8qIFdlIG5lZWQgYSBjb25zdGFudCB0byBmaXh1cCB0aGUgZmluYWwgcG9zaXRpb24gKi8KICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIlBBUkFNIHBvc0ZpeHVwID0gcHJvZ3JhbS5lbnZbJWRdO1xuIiwgQVJCX1NIQURFUl9QUklWQ09OU1RfUE9TKTsKCiAgICAvKiBJbml0aWFsaXplIG91dHB1dCBwYXJhbWV0ZXJzLiBHTF9BUkJfdmVydGV4X3Byb2dyYW0gZG9lcyBub3QgcmVxdWlyZSBzcGVjaWFsIGluaXRpYWxpemF0aW9uIHZhbHVlcwogICAgICogZm9yIG91dHB1dCBwYXJhbWV0ZXJzLiBEM0QgaW4gdGhlb3J5IGRvZXMgbm90IGRvIHRoYXQgZWl0aGVyLCBidXQgc29tZSBhcHBsaWNhdGlvbnMgZGVwZW5kIG9uIGEKICAgICAqIHByb3BlciBpbml0aWFsaXphdGlvbiBvZiB0aGUgc2Vjb25kYXJ5IGNvbG9yLCBhbmQgcHJvZ3JhbXMgdXNpbmcgdGhlIGZpeGVkIGZ1bmN0aW9uIHBpcGVsaW5lIHdpdGhvdXQKICAgICAqIGEgcmVwbGFjZW1lbnQgc2hhZGVyIGRlcGVuZCBvbiB0aGUgdGV4Y29vcmQudyBiZWluZyBzZXQgcHJvcGVybHkuCiAgICAgKgogICAgICogR0xfTlZfdmVydGV4X3Byb2dyYW0gZGVmaW5lcyB0aGF0IGFsbCBvdXRwdXQgdmFsdWVzIGFyZSBpbml0aWFsaXplZCB0byB7MC4wLCAwLjAsIDAuMCwgMS4wfS4gVGhpcwogICAgICogYXNzZXJ0aW9uIGlzIGluIGVmZmVjdCBldmVuIHdoZW4gdXNpbmcgR0xfQVJCX3ZlcnRleF9wcm9ncmFtIHdpdGhvdXQgYW55IE5WIHNwZWNpZmljIGFkZGl0aW9ucy4gU28KICAgICAqIHNraXAgdGhpcyBpZiBOVl92ZXJ0ZXhfcHJvZ3JhbSBpcyBzdXBwb3J0ZWQuIE90aGVyd2lzZSwgaW5pdGlhbGl6ZSB0aGUgc2Vjb25kYXJ5IGNvbG9yLiBGb3IgdGhlIHRleC0KICAgICAqIGNvb3Jkcywgd2UgaGF2ZSBhIGZsYWcgaW4gdGhlIG9wZW5nbCBjYXBzLiBNYW55IGNhcmRzIGRvIG5vdCByZXF1aXJlIHRoZSB0ZXhjb29yZCBiZWluZyBzZXQsIGFuZAogICAgICogdGhpcyBjYW4gZWF0IGEgbnVtYmVyIG9mIGluc3RydWN0aW9ucywgc28gc2tpcCBpdCB1bmxlc3MgdGhpcyBjYXAgaXMgc2V0IGFzIHdlbGwKICAgICAqLwogICAgaWYoIUdMX1NVUFBPUlQoTlZfVkVSVEVYX1BST0dSQU0pKSB7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTU9WIHJlc3VsdC5jb2xvci5zZWNvbmRhcnksIC1oZWxwZXJfY29uc3Qud3d3eTtcbiIpOwoKICAgICAgICBpZigoR0xJTkZPX0xPQ0FUSU9OKS5zZXRfdGV4Y29vcmRfdykgewogICAgICAgICAgICBpbnQgaTsKICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDwgbWluKDgsIE1BWF9SRUdfVEVYQ1JEKTsgaSsrKSB7CiAgICAgICAgICAgICAgICBpZihUaGlzLT5iYXNlU2hhZGVyLnJlZ19tYXBzLnRleGNvb3JkX21hc2tbaV0gIT0gMCAmJgogICAgICAgICAgICAgICAgVGhpcy0+YmFzZVNoYWRlci5yZWdfbWFwcy50ZXhjb29yZF9tYXNrW2ldICE9IFdJTkVEM0RTUF9XUklURU1BU0tfQUxMKSB7CiAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTU9WIHJlc3VsdC50ZXhjb29yZFsldV0udywgLWhlbHBlcl9jb25zdC55O1xuIiwgaSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyogQmFzZSBTaGFkZXIgQm9keSAqLwogICAgc2hhZGVyX2dlbmVyYXRlX21haW4oIChJV2luZUQzREJhc2VTaGFkZXIqKSBUaGlzLCBidWZmZXIsIHJlZ19tYXBzLCBmdW5jdGlvbik7CgogICAgLyogSWYgdGhpcyBzaGFkZXIgZG9lc24ndCB1c2UgZm9nIGNvcHkgdGhlIHogY29vcmQgdG8gdGhlIGZvZyBjb29yZCBzbyB0aGF0IHdlIGNhbiB1c2UgdGFibGUgZm9nICovCiAgICBpZiAoIXJlZ19tYXBzLT5mb2cpCiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTU9WIHJlc3VsdC5mb2djb29yZCwgVE1QX09VVC56O1xuIik7CgogICAgLyogV3JpdGUgdGhlIGZpbmFsIHBvc2l0aW9uLgogICAgICoKICAgICAqIE9wZW5HTCBjb29yZGluYXRlcyBzcGVjaWZ5IHRoZSBjZW50ZXIgb2YgdGhlIHBpeGVsIHdoaWxlIGQzZCBjb29yZHMgc3BlY2lmeQogICAgICogdGhlIGNvcm5lci4gVGhlIG9mZnNldHMgYXJlIHN0b3JlZCBpbiB6IGFuZCB3IGluIHBvc0ZpeHVwLiBwb3NGaXh1cC55IGNvbnRhaW5zCiAgICAgKiAxLjAgb3IgLTEuMCB0byB0dXJuIHRoZSByZW5kZXJpbmcgdXBzaWRlIGRvd24gZm9yIG9mZnNjcmVlbiByZW5kZXJpbmcuIFBvc0ZpeHVwLngKICAgICAqIGNvbnRhaW5zIDEuMCB0byBhbGxvdyBhIG1hZCwgYnV0IGFyYiB2cyBzd2l6emxlcyBhcmUgdG9vIHJlc3RyaWN0ZWQgZm9yIHRoYXQuCiAgICAgKi8KICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIk1VTCBUTVAsIHBvc0ZpeHVwLCBUTVBfT1VULnc7XG4iKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIkFERCBUTVBfT1VULngsIFRNUF9PVVQueCwgVE1QLno7XG4iKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIk1BRCBUTVBfT1VULnksIFRNUF9PVVQueSwgcG9zRml4dXAueSwgVE1QLnc7XG4iKTsKCiAgICAvKiBaIGNvb3JkIFswOzFdLT5bLTE7MV0gbWFwcGluZywgc2VlIGNvbW1lbnQgaW4gdHJhbnNmb3JtX3Byb2plY3Rpb24gaW4gc3RhdGUuYwogICAgICogYW5kIHRoZSBnbHNsIGVxdWl2YWxlbnQKICAgICAqLwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiTUFEIFRNUF9PVVQueiwgVE1QX09VVC56LCBoZWxwZXJfY29uc3QueCwgLVRNUF9PVVQudztcbiIpOwoKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIk1PViByZXN1bHQucG9zaXRpb24sIFRNUF9PVVQ7XG4iKTsKCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJFTkRcbiIpOwoKICAgIC8qIFRPRE86IGNoYW5nZSB0byByZXNvdXJjZS5nbE9iamVjdEhhbmRsZSBvciBzb21ldGhpbmcgbGlrZSB0aGF0ICovCiAgICBHTF9FWFRDQUxMKGdsR2VuUHJvZ3JhbXNBUkIoMSwgJlRoaXMtPmJhc2VTaGFkZXIucHJnSWQpKTsKCiAgICBUUkFDRSgiQ3JlYXRpbmcgYSBodyB2ZXJ0ZXggc2hhZGVyLCBwcmc9JWRcbiIsIFRoaXMtPmJhc2VTaGFkZXIucHJnSWQpOwogICAgR0xfRVhUQ0FMTChnbEJpbmRQcm9ncmFtQVJCKEdMX1ZFUlRFWF9QUk9HUkFNX0FSQiwgVGhpcy0+YmFzZVNoYWRlci5wcmdJZCkpOwoKICAgIFRSQUNFKCJDcmVhdGVkIGh3IHZlcnRleCBzaGFkZXIsIHByZz0lZFxuIiwgVGhpcy0+YmFzZVNoYWRlci5wcmdJZCk7CiAgICAvKiBDcmVhdGUgdGhlIHByb2dyYW0gYW5kIGNoZWNrIGZvciBlcnJvcnMgKi8KICAgIEdMX0VYVENBTEwoZ2xQcm9ncmFtU3RyaW5nQVJCKEdMX1ZFUlRFWF9QUk9HUkFNX0FSQiwgR0xfUFJPR1JBTV9GT1JNQVRfQVNDSUlfQVJCLAogICAgICAgICAgICAgICBidWZmZXItPmJzaXplLCBidWZmZXItPmJ1ZmZlcikpOwoKICAgIGlmIChnbEdldEVycm9yKCkgPT0gR0xfSU5WQUxJRF9PUEVSQVRJT04pIHsKICAgICAgICBHTGludCBlcnJQb3M7CiAgICAgICAgZ2xHZXRJbnRlZ2VydihHTF9QUk9HUkFNX0VSUk9SX1BPU0lUSU9OX0FSQiwgJmVyclBvcyk7CiAgICAgICAgRklYTUUoIkhXIFZlcnRleFNoYWRlciBFcnJvciBhdCBwb3NpdGlvbiAlZDogJXNcbiIsCiAgICAgICAgICAgICAgZXJyUG9zLCBkZWJ1Z3N0cl9hKChjb25zdCBjaGFyICopZ2xHZXRTdHJpbmcoR0xfUFJPR1JBTV9FUlJPUl9TVFJJTkdfQVJCKSkpOwogICAgICAgIFRoaXMtPmJhc2VTaGFkZXIucHJnSWQgPSAtMTsKICAgIH0KfQoKc3RhdGljIHZvaWQgc2hhZGVyX2FyYl9nZXRfY2FwcyhXSU5FRDNEREVWVFlQRSBkZXZ0eXBlLCBXaW5lRDNEX0dMX0luZm8gKmdsX2luZm8sIHN0cnVjdCBzaGFkZXJfY2FwcyAqcENhcHMpIHsKICAgIC8qIFdlIGRvbid0IGhhdmUgYW4gQVJCIGZpeGVkIGZ1bmN0aW9uIHBpcGVsaW5lIHlldCwgc28gbGV0IHRoZSBub25lIGJhY2tlbmQgc2V0IGl0cyBjYXBzLAogICAgICogdGhlbiBvdmVyd3JpdGUgdGhlIHNoYWRlciBzcGVjaWZpYyBvbmVzCiAgICAgKi8KICAgIG5vbmVfc2hhZGVyX2JhY2tlbmQuc2hhZGVyX2dldF9jYXBzKGRldnR5cGUsIGdsX2luZm8sIHBDYXBzKTsKCiAgICBpZihHTF9TVVBQT1JUKEFSQl9WRVJURVhfUFJPR1JBTSkpIHsKICAgICAgICBwQ2Fwcy0+VmVydGV4U2hhZGVyVmVyc2lvbiA9IFdJTkVEM0RWU19WRVJTSU9OKDEsMSk7CiAgICAgICAgVFJBQ0VfKGQzZF9jYXBzKSgiSGFyZHdhcmUgdmVydGV4IHNoYWRlciB2ZXJzaW9uIDEuMSBlbmFibGVkIChBUkJfUFJPR1JBTSlcbiIpOwogICAgICAgIHBDYXBzLT5NYXhWZXJ0ZXhTaGFkZXJDb25zdCA9IEdMX0xJTUlUUyh2c2hhZGVyX2NvbnN0YW50c0YpOwogICAgfQoKICAgIGlmKEdMX1NVUFBPUlQoQVJCX0ZSQUdNRU5UX1BST0dSQU0pKSB7CiAgICAgICAgcENhcHMtPlBpeGVsU2hhZGVyVmVyc2lvbiAgICA9IFdJTkVEM0RQU19WRVJTSU9OKDEsNCk7CiAgICAgICAgcENhcHMtPlBpeGVsU2hhZGVyMXhNYXhWYWx1ZSA9IDguMDsKICAgICAgICBUUkFDRV8oZDNkX2NhcHMpKCJIYXJkd2FyZSBwaXhlbCBzaGFkZXIgdmVyc2lvbiAxLjQgZW5hYmxlZCAoQVJCX1BST0dSQU0pXG4iKTsKICAgIH0KfQoKc3RhdGljIHZvaWQgc2hhZGVyX2FyYl9sb2FkX2luaXQodm9pZCkgewp9CgpzdGF0aWMgdm9pZCBzaGFkZXJfYXJiX2ZyYWdtZW50X2VuYWJsZShJV2luZUQzRERldmljZSAqaWZhY2UsIEJPT0wgZW5hYmxlKSB7CiAgICBub25lX3NoYWRlcl9iYWNrZW5kLnNoYWRlcl9mcmFnbWVudF9lbmFibGUoaWZhY2UsIGVuYWJsZSk7Cn0KCmNvbnN0IHNoYWRlcl9iYWNrZW5kX3QgYXJiX3Byb2dyYW1fc2hhZGVyX2JhY2tlbmQgPSB7CiAgICAmc2hhZGVyX2FyYl9zZWxlY3QsCiAgICAmc2hhZGVyX2FyYl9zZWxlY3RfZGVwdGhfYmx0LAogICAgJnNoYWRlcl9hcmJfZGVzdHJveV9kZXB0aF9ibHQsCiAgICAmc2hhZGVyX2FyYl9sb2FkX2NvbnN0YW50cywKICAgICZzaGFkZXJfYXJiX2NsZWFudXAsCiAgICAmc2hhZGVyX2FyYl9jb2xvcl9jb3JyZWN0aW9uLAogICAgJnNoYWRlcl9hcmJfZGVzdHJveSwKICAgICZzaGFkZXJfYXJiX2FsbG9jLAogICAgJnNoYWRlcl9hcmJfZnJlZSwKICAgICZzaGFkZXJfYXJiX2RpcnR5X2NvbnN0LAogICAgJnNoYWRlcl9hcmJfZ2VuZXJhdGVfcHNoYWRlciwKICAgICZzaGFkZXJfYXJiX2dlbmVyYXRlX3ZzaGFkZXIsCiAgICAmc2hhZGVyX2FyYl9nZXRfY2FwcywKICAgICZzaGFkZXJfYXJiX2xvYWRfaW5pdCwKICAgICZzaGFkZXJfYXJiX2ZyYWdtZW50X2VuYWJsZSwKICAgIEZGUFN0YXRlVGFibGUKfTsK