LyoKICogQ29udGV4dCBhbmQgcmVuZGVyIHRhcmdldCBtYW5hZ2VtZW50IGluIHdpbmVkM2QKICoKICogQ29weXJpZ2h0IDIwMDcgU3RlZmFuIET2c2luZ2VyIGZvciBDb2RlV2VhdmVycwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlIDxzdGRpby5oPgojaWZkZWYgSEFWRV9GTE9BVF9ICiMgaW5jbHVkZSA8ZmxvYXQuaD4KI2VuZGlmCiNpbmNsdWRlICJ3aW5lZDNkX3ByaXZhdGUuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGQzZCk7CgojZGVmaW5lIEdMSU5GT19MT0NBVElPTiAoKElXaW5lRDNESW1wbCAqKShUaGlzLT53aW5lRDNEKSktPmdsX2luZm8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDb250ZXh0X01hcmtTdGF0ZURpcnR5CiAqCiAqIE1hcmtzIGEgc3RhdGUgaW4gYSBjb250ZXh0IGRpcnR5LiBPbmx5IG9uZSBjb250ZXh0LCBvcHBvc2VkIHRvCiAqIElXaW5lRDNERGV2aWNlSW1wbF9NYXJrU3RhdGVEaXJ0eSwgd2hpY2ggbWFya3MgdGhlIHN0YXRlIGRpcnR5IGluIGFsbAogKiBjb250ZXh0cwogKgogKiBQYXJhbXM6CiAqICBjb250ZXh0OiBDb250ZXh0IHRvIG1hcmsgdGhlIHN0YXRlIGRpcnR5IGluCiAqICBzdGF0ZTogU3RhdGUgdG8gbWFyayBkaXJ0eQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyB2b2lkIENvbnRleHRfTWFya1N0YXRlRGlydHkoV2luZUQzRENvbnRleHQgKmNvbnRleHQsIERXT1JEIHN0YXRlKSB7CiAgICBEV09SRCByZXAgPSBTdGF0ZVRhYmxlW3N0YXRlXS5yZXByZXNlbnRhdGl2ZTsKICAgIERXT1JEIGlkeDsKICAgIEJZVEUgc2hpZnQ7CgogICAgaWYoIXJlcCB8fCBpc1N0YXRlRGlydHkoY29udGV4dCwgcmVwKSkgcmV0dXJuOwoKICAgIGNvbnRleHQtPmRpcnR5QXJyYXlbY29udGV4dC0+bnVtRGlydHlFbnRyaWVzKytdID0gcmVwOwogICAgaWR4ID0gcmVwID4+IDU7CiAgICBzaGlmdCA9IHJlcCAmIDB4MWY7CiAgICBjb250ZXh0LT5pc1N0YXRlRGlydHlbaWR4XSB8PSAoMSA8PCBzaGlmdCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBZGRDb250ZXh0VG9BcnJheQogKgogKiBBZGRzIGEgY29udGV4dCB0byB0aGUgY29udGV4dCBhcnJheS4gSGVscGVyIGZ1bmN0aW9uIGZvciBDcmVhdGVDb250ZXh0CiAqCiAqIFRoaXMgbWV0aG9kIGlzIG5vdCBjYWxsZWQgaW4gcGVyZm9ybWFuY2UtY3JpdGljYWwgY29kZSBwYXRocywgb25seSB3aGVuIGEKICogbmV3IHJlbmRlciB0YXJnZXQgb3Igc3dhcGNoYWluIGlzIGNyZWF0ZWQuIFRodXMgcGVyZm9ybWFuY2UgaXMgbm90IGFuIGlzc3VlCiAqIGhlcmUuCiAqCiAqIFBhcmFtczoKICogIFRoaXM6IERldmljZSB0byBhZGQgdGhlIGNvbnRleHQgZm9yCiAqICBkaXNwbGF5OiBYIGRpc3BsYXkgdGhpcyBjb250ZXh0IHVzZXMKICogIGdsQ3R4OiBnbFggY29udGV4dCB0byBhZGQKICogIGRyYXdhYmxlOiBkcmF3YWJsZSB1c2VkIHdpdGggdGhpcyBjb250ZXh0LgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBXaW5lRDNEQ29udGV4dCAqQWRkQ29udGV4dFRvQXJyYXkoSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzLCBEaXNwbGF5ICpkaXNwbGF5LCBHTFhDb250ZXh0IGdsQ3R4LCBEcmF3YWJsZSBkcmF3YWJsZSkgewogICAgV2luZUQzRENvbnRleHQgKipvbGRBcnJheSA9IFRoaXMtPmNvbnRleHRzOwogICAgRFdPUkQgc3RhdGU7CgogICAgVGhpcy0+Y29udGV4dHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKCpUaGlzLT5jb250ZXh0cykgKiAoVGhpcy0+bnVtQ29udGV4dHMgKyAxKSk7CiAgICBpZihUaGlzLT5jb250ZXh0cyA9PSBOVUxMKSB7CiAgICAgICAgRVJSKCJVbmFibGUgdG8gZ3JvdyB0aGUgY29udGV4dCBhcnJheVxuIik7CiAgICAgICAgVGhpcy0+Y29udGV4dHMgPSBvbGRBcnJheTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIGlmKG9sZEFycmF5KSB7CiAgICAgICAgbWVtY3B5KFRoaXMtPmNvbnRleHRzLCBvbGRBcnJheSwgc2l6ZW9mKCpUaGlzLT5jb250ZXh0cykgKiBUaGlzLT5udW1Db250ZXh0cyk7CiAgICB9CgogICAgVGhpcy0+Y29udGV4dHNbVGhpcy0+bnVtQ29udGV4dHNdID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihXaW5lRDNEQ29udGV4dCkpOwogICAgaWYoVGhpcy0+Y29udGV4dHNbVGhpcy0+bnVtQ29udGV4dHNdID09IE5VTEwpIHsKICAgICAgICBFUlIoIlVuYWJsZSB0byBhbGxvY2F0ZSBhIG5ldyBjb250ZXh0XG4iKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5jb250ZXh0cyk7CiAgICAgICAgVGhpcy0+Y29udGV4dHMgPSBvbGRBcnJheTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBUaGlzLT5jb250ZXh0c1tUaGlzLT5udW1Db250ZXh0c10tPmRpc3BsYXkgPSBkaXNwbGF5OwogICAgVGhpcy0+Y29udGV4dHNbVGhpcy0+bnVtQ29udGV4dHNdLT5nbEN0eCA9IGdsQ3R4OwogICAgVGhpcy0+Y29udGV4dHNbVGhpcy0+bnVtQ29udGV4dHNdLT5kcmF3YWJsZSA9IGRyYXdhYmxlOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2xkQXJyYXkpOwoKICAgIC8qIE1hcmsgYWxsIHN0YXRlcyBkaXJ0eSB0byBmb3JjZSBhIHByb3BlciBpbml0aWFsaXphdGlvbiBvZiB0aGUgc3RhdGVzIG9uIHRoZSBmaXJzdCB1c2Ugb2YgdGhlIGNvbnRleHQKICAgICAqLwogICAgZm9yKHN0YXRlID0gMDsgc3RhdGUgPD0gU1RBVEVfSElHSEVTVDsgc3RhdGUrKykgewogICAgICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoVGhpcy0+Y29udGV4dHNbVGhpcy0+bnVtQ29udGV4dHNdLCBzdGF0ZSk7CiAgICB9CgogICAgVGhpcy0+bnVtQ29udGV4dHMrKzsKICAgIFRSQUNFKCJDcmVhdGVkIGNvbnRleHQgJXBcbiIsIFRoaXMtPmNvbnRleHRzW1RoaXMtPm51bUNvbnRleHRzIC0gMV0pOwogICAgcmV0dXJuIFRoaXMtPmNvbnRleHRzW1RoaXMtPm51bUNvbnRleHRzIC0gMV07Cn0KCi8qIFJldHVybnMgYW4gYXJyYXkgb2YgY29tcGF0aWJsZSBGQmNvbmZpZyhzKS4KICogVGhlIGFycmF5IG11c3QgYmUgZnJlZWQgd2l0aCBYRnJlZS4gUmVxdWlyZXMgRU5URVJfR0woKQogKi8Kc3RhdGljIEdMWEZCQ29uZmlnKiBwYnVmZmVyX2ZpbmRfZmJjb25maWdzKAogICAgSVdpbmVEM0REZXZpY2VJbXBsKiBUaGlzLAogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCogUmVuZGVyU3VyZmFjZSwKICAgIERpc3BsYXkgKmRpc3BsYXkpIHsKCiAgICBHTFhGQkNvbmZpZyogY2ZncyA9IE5VTEw7CiAgICBpbnQgbkNmZ3MgPSAwOwogICAgaW50IGF0dHJpYnNbMjU2XTsKICAgIGludCBuQXR0cmlicyA9IDA7CgogICAgSVdpbmVEM0RTdXJmYWNlICpTdGVuY2lsU3VyZmFjZSA9IFRoaXMtPnN0ZW5jaWxCdWZmZXJUYXJnZXQ7CiAgICBXSU5FRDNERk9STUFUIEJhY2tCdWZmZXJGb3JtYXQgPSBSZW5kZXJTdXJmYWNlLT5yZXNvdXJjZS5mb3JtYXQ7CiAgICBXSU5FRDNERk9STUFUIFN0ZW5jaWxCdWZmZXJGb3JtYXQgPSAoTlVMTCAhPSBTdGVuY2lsU3VyZmFjZSkgPyAoKElXaW5lRDNEU3VyZmFjZUltcGwgKikgU3RlbmNpbFN1cmZhY2UpLT5yZXNvdXJjZS5mb3JtYXQgOiAwOwoKICAgIC8qIFRPRE86CiAgICAgKiAgaWYgU3RlbmNpbFN1cmZhY2UgPT0gTlVMTCAmJiB6QnVmZmVyVGFyZ2V0ICE9IE5VTEwgdGhlbiBzd2l0Y2ggdGhlIHpidWZmZXIgb2ZmLAogICAgICogIGl0IFN0ZW5jaWxTdXJmYWNlICE9IE5VTEwgJiYgekJ1ZmZlclRhcmdldCA9PSBOVUxMIHN3aXRjaCBpdCBvbgogICAgICovCgojZGVmaW5lIFBVU0gxKGF0dCkgICAgICAgIGF0dHJpYnNbbkF0dHJpYnMrK10gPSAoYXR0KTsKI2RlZmluZSBQVVNIMihhdHQsdmFsdWUpICBhdHRyaWJzW25BdHRyaWJzKytdID0gKGF0dCk7IGF0dHJpYnNbbkF0dHJpYnMrK10gPSAodmFsdWUpOwoKICAgIC8qIFBVU0gyKEdMWF9CSU5EX1RPX1RFWFRVUkVfUkdCQV9BVEksIFRydWUpOyBleGFtcGxlcyBvZiB0aGlzIGFyZSBmZXcgYW5kIGZhciBiZXR3ZWVuIChidXQgSSd2ZSBnb3QgYSBuaWNlIHdvcmtpbmcgb25lISkqLwoKICAgIFBVU0gyKEdMWF9EUkFXQUJMRV9UWVBFLCBHTFhfUEJVRkZFUl9CSVQpOwogICAgUFVTSDIoR0xYX1hfUkVOREVSQUJMRSwgIFRSVUUpOwogICAgUFVTSDIoR0xYX0RPVUJMRUJVRkZFUiwgIFRSVUUpOwogICAgVFJBQ0UoImNhbGxpbmcgbWFrZWdsY2ZnXG4iKTsKICAgIEQzREZtdE1ha2VHbENmZyhCYWNrQnVmZmVyRm9ybWF0LCBTdGVuY2lsQnVmZmVyRm9ybWF0LCBhdHRyaWJzLCAmbkF0dHJpYnMsIEZBTFNFIC8qIGFsdGVybmF0ZSAqLyk7CiAgICBQVVNIMShOb25lKTsKICAgIFRSQUNFKCJjYWxsaW5nIGNob29zZUZHQ29uZmlnXG4iKTsKICAgIGNmZ3MgPSBnbFhDaG9vc2VGQkNvbmZpZyhkaXNwbGF5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlZmF1bHRTY3JlZW4oZGlzcGxheSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlicywgJm5DZmdzKTsKICAgIGlmIChjZmdzID09IE5VTEwpIHsKICAgICAgICAvKiBPSyB3ZSBkaWRuJ3QgZmluZCB0aGUgZXhhY3QgY29uZmlnLCBzbyB1c2UgYW55IHJlYXNvbmFibGUgbWF0Y2ggKi8KICAgICAgICAvKiBUT0RPOiBmaWxsIGluIHRoZSAncmVxdWVzdGVkJyBhbmQgJ2N1cnJlbnQnIGRlcHRocywgYW5kIG1ha2Ugc3VyZSB0aGF0J3MKICAgICAgICAgICB3aHkgd2UgZmFpbGVkLiAqLwogICAgICAgIHN0YXRpYyBCT09MIHNob3dfbWVzc2FnZSA9IFRSVUU7CiAgICAgICAgaWYgKHNob3dfbWVzc2FnZSkgewogICAgICAgICAgICBFUlIoIkZhaWxlZCB0byBmaW5kIGV4YWN0IG1hdGNoLCBmaW5kaW5nIGFsdGVybmF0aXZlIGJ1dCB5b3UgbWF5ICIKICAgICAgICAgICAgICAgICJzdWZmZXIgcGVyZm9ybWFuY2UgaXNzdWVzLCB0cnkgY2hhbmdpbmcgeGZyZWUncyBkZXB0aCB0byBtYXRjaCB0aGUgcmVxdWVzdGVkIGRlcHRoXG4iKTsKICAgICAgICAgICAgc2hvd19tZXNzYWdlID0gRkFMU0U7CiAgICAgICAgfQogICAgICAgIG5BdHRyaWJzID0gMDsKICAgICAgICBQVVNIMihHTFhfRFJBV0FCTEVfVFlQRSwgR0xYX1BCVUZGRVJfQklUIHwgR0xYX1dJTkRPV19CSVQpOwogICAgICAgIC8qIFBVU0gyKEdMWF9YX1JFTkRFUkFCTEUsICBUUlVFKTsgKi8KICAgICAgICBQVVNIMihHTFhfUkVOREVSX1RZUEUsICAgR0xYX1JHQkFfQklUKTsKICAgICAgICBQVVNIMihHTFhfRE9VQkxFQlVGRkVSLCBGQUxTRSk7CiAgICAgICAgVFJBQ0UoImNhbGxpbmcgbWFrZWdsY2ZnXG4iKTsKICAgICAgICBEM0RGbXRNYWtlR2xDZmcoQmFja0J1ZmZlckZvcm1hdCwgU3RlbmNpbEJ1ZmZlckZvcm1hdCwgYXR0cmlicywgJm5BdHRyaWJzLCBUUlVFIC8qIGFsdGVybmF0ZSAqLyk7CiAgICAgICAgUFVTSDEoTm9uZSk7CiAgICAgICAgY2ZncyA9IGdsWENob29zZUZCQ29uZmlnKGRpc3BsYXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlZmF1bHRTY3JlZW4oZGlzcGxheSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnMsICZuQ2Zncyk7CiAgICB9CgogICAgaWYgKGNmZ3MgPT0gTlVMTCkgewogICAgICAgIEVSUigiQ291bGQgbm90IGdldCBhIHZhbGlkIEZCQ29uZmlnIGZvciAoJXUsJXMpLygldSwlcylcbiIsCiAgICAgICAgICAgIEJhY2tCdWZmZXJGb3JtYXQsIGRlYnVnX2QzZGZvcm1hdChCYWNrQnVmZmVyRm9ybWF0KSwKICAgICAgICAgICAgU3RlbmNpbEJ1ZmZlckZvcm1hdCwgZGVidWdfZDNkZm9ybWF0KFN0ZW5jaWxCdWZmZXJGb3JtYXQpKTsKICAgIH0gZWxzZSB7CiNpZmRlZiBFWFRSQV9UUkFDRVMKICAgICAgICBpbnQgaTsKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbkNmZ3M7ICsraSkgewogICAgICAgICAgICBUUkFDRSgiZm9yICgldSwlcykvKCV1LCVzKSBmb3VuZCBjb25maWdbJWRdQCVwXG4iLCBCYWNrQnVmZmVyRm9ybWF0LAogICAgICAgICAgICBkZWJ1Z19kM2Rmb3JtYXQoQmFja0J1ZmZlckZvcm1hdCksIFN0ZW5jaWxCdWZmZXJGb3JtYXQsCiAgICAgICAgICAgIGRlYnVnX2QzZGZvcm1hdChTdGVuY2lsQnVmZmVyRm9ybWF0KSwgaSwgY2Znc1tpXSk7CiAgICAgICAgfQojZW5kaWYKICAgIH0KI3VuZGVmIFBVU0gxCiN1bmRlZiBQVVNIMgoKICAgcmV0dXJuIGNmZ3M7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDcmVhdGVDb250ZXh0CiAqCiAqIENyZWF0ZXMgYSBuZXcgY29udGV4dCBmb3IgYSB3aW5kb3csIG9yIGEgcGJ1ZmZlciBjb250ZXh0LgogKgogKiAqIFBhcmFtczoKICogIFRoaXM6IERldmljZSB0byBhY3RpdmF0ZSB0aGUgY29udGV4dCBmb3IKICogIHRhcmdldDogU3VyZmFjZSB0aGlzIGNvbnRleHQgd2lsbCByZW5kZXIgdG8KICogIGRpc3BsYXk6IFgxMSBjb25uZWN0aW9uCiAqICB3aW46IFRhcmdldCB3aW5kb3cuIE5VTEwgZm9yIGEgcGJ1ZmZlcgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCldpbmVEM0RDb250ZXh0ICpDcmVhdGVDb250ZXh0KElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcywgSVdpbmVEM0RTdXJmYWNlSW1wbCAqdGFyZ2V0LCBEaXNwbGF5ICpkaXNwbGF5LCBXaW5kb3cgd2luKSB7CiAgICBEcmF3YWJsZSBkcmF3YWJsZSA9IHdpbiwgb2xkRHJhd2FibGU7CiAgICBYVmlzdWFsSW5mbyAqdmlzaW5mbyA9IE5VTEw7CiAgICBHTFhGQkNvbmZpZyAqY2ZncyA9IE5VTEw7CiAgICBHTFhDb250ZXh0IGN0eCA9IE5VTEwsIG9sZEN0eDsKICAgIFdpbmVEM0RDb250ZXh0ICpyZXQgPSBOVUxMOwoKICAgIFRSQUNFKCIoJXApOiBDcmVhdGluZyBhICVzIGNvbnRleHQgZm9yIHJlbmRlciB0YXJnZXQgJXBcbiIsIFRoaXMsIHdpbiA/ICJvbnNjcmVlbiIgOiAib2Zmc2NyZWVuIiwgdGFyZ2V0KTsKCiAgICBpZighd2luKSB7CiAgICAgICAgaW50IGF0dHJpYnNbMjU2XTsKICAgICAgICBpbnQgbkF0dHJpYnMgPSAwOwoKICAgICAgICBUUkFDRSgiQ3JlYXRpbmcgYSBwQnVmZmVyIGRyYXdhYmxlIGZvciB0aGUgbmV3IGNvbnRleHRcbiIpOwoKICAgICAgICBjZmdzID0gcGJ1ZmZlcl9maW5kX2ZiY29uZmlncyhUaGlzLCB0YXJnZXQsIGRpc3BsYXkpOwogICAgICAgIGlmKCFjZmdzKSB7CiAgICAgICAgICAgIEVSUigiQ2Fubm90IGZpbmQgYSBmcmFtZSBidWZmZXIgY29uZmlndXJhdGlvbiBmb3IgdGhlIHBidWZmZXJcbiIpOwogICAgICAgICAgICBnb3RvIG91dDsKICAgICAgICB9CgogICAgICAgIGF0dHJpYnNbbkF0dHJpYnMrK10gPSBHTFhfUEJVRkZFUl9XSURUSDsKICAgICAgICBhdHRyaWJzW25BdHRyaWJzKytdID0gdGFyZ2V0LT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICBhdHRyaWJzW25BdHRyaWJzKytdID0gR0xYX1BCVUZGRVJfSEVJR0hUOwogICAgICAgIGF0dHJpYnNbbkF0dHJpYnMrK10gPSB0YXJnZXQtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICBhdHRyaWJzW25BdHRyaWJzKytdID0gTm9uZTsKCiAgICAgICAgdmlzaW5mbyA9IGdsWEdldFZpc3VhbEZyb21GQkNvbmZpZyhkaXNwbGF5LCBjZmdzWzBdKTsKICAgICAgICBpZighdmlzaW5mbykgewogICAgICAgICAgICBFUlIoIkNhbm5vdCBmaW5kIGEgdmlzdWFsIGZvciB0aGUgcGJ1ZmZlclxuIik7CiAgICAgICAgICAgIGdvdG8gb3V0OwogICAgICAgIH0KCiAgICAgICAgZHJhd2FibGUgPSBnbFhDcmVhdGVQYnVmZmVyKGRpc3BsYXksIGNmZ3NbMF0sIGF0dHJpYnMpOwoKICAgICAgICBpZighZHJhd2FibGUpIHsKICAgICAgICAgICAgRVJSKCJDYW5ub3QgY3JlYXRlIGEgcGJ1ZmZlclxuIik7CiAgICAgICAgICAgIGdvdG8gb3V0OwogICAgICAgIH0KICAgICAgICBYRnJlZShjZmdzKTsKICAgICAgICBjZmdzID0gTlVMTDsKICAgIH0gZWxzZSB7CiAgICAgICAgLyogQ3JlYXRlIGFuIG9uc2NyZWVuIHRhcmdldCAqLwogICAgICAgIFhWaXN1YWxJbmZvICAgICAgICAgICAgIHRlbXBsYXRlOwogICAgICAgIGludCAgICAgICAgICAgICAgICAgICAgIG51bTsKCiAgICAgICAgdGVtcGxhdGUudmlzdWFsaWQgPSAoVmlzdWFsSUQpR2V0UHJvcEEoR2V0RGVza3RvcFdpbmRvdygpLCAiX193aW5lX3gxMV92aXN1YWxfaWQiKTsKICAgICAgICAvKiBUT0RPOiBjaGFuZ2UgdGhpcyB0byBmaW5kIGEgc2ltaWxhciB2aXN1YWwsIGJ1dCBvbmUgd2l0aCBhIHN0ZW5jaWwvemJ1ZmZlciBidWZmZXIgdGhhdCBtYXRjaGVzIHRoZSByZXF1ZXN0CiAgICAgICAgKG9yIHRoZSBiZXN0IHBvc3NpYmxlIGlmIG5vbmUgaXMgcmVxdWVzdGVkKSAqLwogICAgICAgIFRSQUNFKCJGb3VuZCB4IHZpc3VhbCBJRCAgOiAlbGRcbiIsIHRlbXBsYXRlLnZpc3VhbGlkKTsKICAgICAgICB2aXNpbmZvICAgPSBYR2V0VmlzdWFsSW5mbyhkaXNwbGF5LCBWaXN1YWxJRE1hc2ssICZ0ZW1wbGF0ZSwgJm51bSk7CgogICAgICAgIGlmIChOVUxMID09IHZpc2luZm8pIHsKICAgICAgICAgICAgRVJSKCJjYW5ub3QgcmVhbGx5IGdldCBYVmlzdWFsXG4iKTsKICAgICAgICAgICAgZ290byBvdXQ7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaW50IG4sIHZhbHVlOwogICAgICAgICAgICAvKiBXcml0ZSBvdXQgc29tZSBkZWJ1ZyBpbmZvIGFib3V0IHRoZSB2aXN1YWwvcyAqLwogICAgICAgICAgICBUUkFDRSgiVXNpbmcgeCB2aXN1YWwgSUQgIDogJWxkXG4iLCB0ZW1wbGF0ZS52aXN1YWxpZCk7CiAgICAgICAgICAgIFRSQUNFKCIgICAgICAgIHZpc3VhbCBpbmZvOiAlcFxuIiwgdmlzaW5mbyk7CiAgICAgICAgICAgIFRSQUNFKCIgICAgICAgIG51bSBpdGVtcyAgOiAlZFxuIiwgbnVtKTsKICAgICAgICAgICAgZm9yIChuID0gMDtuIDwgbnVtOyBuKyspIHsKICAgICAgICAgICAgICAgIFRSQUNFKCI9PT09PWl0ZW09PT09PTogJWRcbiIsIG4gKyAxKTsKICAgICAgICAgICAgICAgIFRSQUNFKCIgICB2aXN1YWxpZCAgICAgIDogJWxkXG4iLCB2aXNpbmZvW25dLnZpc3VhbGlkKTsKICAgICAgICAgICAgICAgIFRSQUNFKCIgICBzY3JlZW4gICAgICAgIDogJWRcbiIsICB2aXNpbmZvW25dLnNjcmVlbik7CiAgICAgICAgICAgICAgICBUUkFDRSgiICAgZGVwdGggICAgICAgICA6ICV1XG4iLCAgdmlzaW5mb1tuXS5kZXB0aCk7CiAgICAgICAgICAgICAgICBUUkFDRSgiICAgY2xhc3MgICAgICAgICA6ICVkXG4iLCAgdmlzaW5mb1tuXS5jbGFzcyk7CiAgICAgICAgICAgICAgICBUUkFDRSgiICAgcmVkX21hc2sgICAgICA6ICVsZFxuIiwgdmlzaW5mb1tuXS5yZWRfbWFzayk7CiAgICAgICAgICAgICAgICBUUkFDRSgiICAgZ3JlZW5fbWFzayAgICA6ICVsZFxuIiwgdmlzaW5mb1tuXS5ncmVlbl9tYXNrKTsKICAgICAgICAgICAgICAgIFRSQUNFKCIgICBibHVlX21hc2sgICAgIDogJWxkXG4iLCB2aXNpbmZvW25dLmJsdWVfbWFzayk7CiAgICAgICAgICAgICAgICBUUkFDRSgiICAgY29sb3JtYXBfc2l6ZSA6ICVkXG4iLCAgdmlzaW5mb1tuXS5jb2xvcm1hcF9zaXplKTsKICAgICAgICAgICAgICAgIFRSQUNFKCIgICBiaXRzX3Blcl9yZ2IgIDogJWRcbiIsICB2aXNpbmZvW25dLmJpdHNfcGVyX3JnYik7CiAgICAgICAgICAgICAgICAvKiBsb2cgc29tZSBleHRyYSBnbHggaW5mbyAqLwogICAgICAgICAgICAgICAgZ2xYR2V0Q29uZmlnKGRpc3BsYXksIHZpc2luZm8sIEdMWF9BVVhfQlVGRkVSUywgJnZhbHVlKTsKICAgICAgICAgICAgICAgIFRSQUNFKCIgICBnbF9hdXhfYnVmZmVycyAgOiAlZFxuIiwgIHZhbHVlKTsKICAgICAgICAgICAgICAgIGdsWEdldENvbmZpZyhkaXNwbGF5LCB2aXNpbmZvLCBHTFhfQlVGRkVSX1NJWkUgLCZ2YWx1ZSk7CiAgICAgICAgICAgICAgICBUUkFDRSgiICAgZ2xfYnVmZmVyX3NpemUgIDogJWRcbiIsICB2YWx1ZSk7CiAgICAgICAgICAgICAgICBnbFhHZXRDb25maWcoZGlzcGxheSwgdmlzaW5mbywgR0xYX1JFRF9TSVpFLCAmdmFsdWUpOwogICAgICAgICAgICAgICAgVFJBQ0UoIiAgIGdsX3JlZF9zaXplICA6ICVkXG4iLCAgdmFsdWUpOwogICAgICAgICAgICAgICAgZ2xYR2V0Q29uZmlnKGRpc3BsYXksIHZpc2luZm8sIEdMWF9HUkVFTl9TSVpFLCAmdmFsdWUpOwogICAgICAgICAgICAgICAgVFJBQ0UoIiAgIGdsX2dyZWVuX3NpemUgIDogJWRcbiIsICB2YWx1ZSk7CiAgICAgICAgICAgICAgICBnbFhHZXRDb25maWcoZGlzcGxheSwgdmlzaW5mbywgR0xYX0JMVUVfU0laRSwgJnZhbHVlKTsKICAgICAgICAgICAgICAgIFRSQUNFKCIgICBnbF9ibHVlX3NpemUgIDogJWRcbiIsICB2YWx1ZSk7CiAgICAgICAgICAgICAgICBnbFhHZXRDb25maWcoZGlzcGxheSwgdmlzaW5mbywgR0xYX0FMUEhBX1NJWkUsICZ2YWx1ZSk7CiAgICAgICAgICAgICAgICBUUkFDRSgiICAgZ2xfYWxwaGFfc2l6ZSAgOiAlZFxuIiwgIHZhbHVlKTsKICAgICAgICAgICAgICAgIGdsWEdldENvbmZpZyhkaXNwbGF5LCB2aXNpbmZvLCBHTFhfREVQVEhfU0laRSAsJnZhbHVlKTsKICAgICAgICAgICAgICAgIFRSQUNFKCIgICBnbF9kZXB0aF9zaXplICA6ICVkXG4iLCAgdmFsdWUpOwogICAgICAgICAgICAgICAgZ2xYR2V0Q29uZmlnKGRpc3BsYXksIHZpc2luZm8sIEdMWF9TVEVOQ0lMX1NJWkUsICZ2YWx1ZSk7CiAgICAgICAgICAgICAgICBUUkFDRSgiICAgZ2xfc3RlbmNpbF9zaXplIDogJWRcbiIsICB2YWx1ZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogTm93IGNob29zZSBhIHNpbWlsYXIgdmlzdWFsIElEKi8KICAgICAgICB9CiAgICB9CgogICAgY3R4ID0gZ2xYQ3JlYXRlQ29udGV4dChkaXNwbGF5LCB2aXNpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5udW1Db250ZXh0cyA/IFRoaXMtPmNvbnRleHRzWzBdLT5nbEN0eCA6IE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEdMX1RSVUUpOwogICAgaWYoIWN0eCkgewogICAgICAgIEVSUigiRmFpbGVkIHRvIGNyZWF0ZSBhIGdsWCBjb250ZXh0XG4iKTsKICAgICAgICBpZihkcmF3YWJsZSAhPSB3aW4pIGdsWERlc3Ryb3lQYnVmZmVyKGRpc3BsYXksIGRyYXdhYmxlKTsKICAgICAgICBnb3RvIG91dDsKICAgIH0KICAgIHJldCA9IEFkZENvbnRleHRUb0FycmF5KFRoaXMsIGRpc3BsYXksIGN0eCwgZHJhd2FibGUpOwogICAgaWYoIXJldCkgewogICAgICAgIEVSUigiRmFpbGVkIHRvIGFkZCB0aGUgbmV3bHkgY3JlYXRlZCBjb250ZXh0IHRvIHRoZSBjb250ZXh0IGxpc3RcbiIpOwogICAgICAgIGdsWERlc3Ryb3lDb250ZXh0KGRpc3BsYXksIGN0eCk7CiAgICAgICAgaWYoZHJhd2FibGUgIT0gd2luKSBnbFhEZXN0cm95UGJ1ZmZlcihkaXNwbGF5LCBkcmF3YWJsZSk7CiAgICAgICAgZ290byBvdXQ7CiAgICB9CiAgICByZXQtPnN1cmZhY2UgPSAoSVdpbmVEM0RTdXJmYWNlICopIHRhcmdldDsKICAgIHJldC0+aXNQQnVmZmVyID0gd2luID09IDA7CgogICAgVFJBQ0UoIlN1Y2Nlc3NmdWxseSBjcmVhdGVkIG5ldyBjb250ZXh0ICVwXG4iLCByZXQpOwoKICAgIC8qIFNldCB1cCB0aGUgY29udGV4dCBkZWZhdWx0cyAqLwogICAgb2xkQ3R4ICA9IGdsWEdldEN1cnJlbnRDb250ZXh0KCk7CiAgICBvbGREcmF3YWJsZSA9IGdsWEdldEN1cnJlbnREcmF3YWJsZSgpOwogICAgaWYoZ2xYTWFrZUN1cnJlbnQoZGlzcGxheSwgZHJhd2FibGUsIGN0eCkgPT0gRkFMU0UpIHsKICAgICAgICBFUlIoIkNhbm5vdCBhY3RpdmF0ZSBjb250ZXh0IHRvIHNldCB1cCBkZWZhdWx0c1xuIik7CiAgICAgICAgZ290byBvdXQ7CiAgICB9CgogICAgVFJBQ0UoIlNldHRpbmcgdXAgdGhlIHNjcmVlblxuIik7CiAgICAvKiBDbGVhciB0aGUgc2NyZWVuICovCiAgICBnbENsZWFyQ29sb3IoMS4wLCAwLjAsIDAuMCwgMC4wKTsKICAgIGNoZWNrR0xjYWxsKCJnbENsZWFyQ29sb3IiKTsKICAgIGdsQ2xlYXJJbmRleCgwKTsKICAgIGdsQ2xlYXJEZXB0aCgxKTsKICAgIGdsQ2xlYXJTdGVuY2lsKDB4ZmZmZik7CgogICAgY2hlY2tHTGNhbGwoImdsQ2xlYXIiKTsKCiAgICBnbENvbG9yM2YoMS4wLCAxLjAsIDEuMCk7CiAgICBjaGVja0dMY2FsbCgiZ2xDb2xvcjNmIik7CgogICAgZ2xFbmFibGUoR0xfTElHSFRJTkcpOwogICAgY2hlY2tHTGNhbGwoImdsRW5hYmxlIik7CgogICAgZ2xMaWdodE1vZGVsaShHTF9MSUdIVF9NT0RFTF9MT0NBTF9WSUVXRVIsIEdMX1RSVUUpOwogICAgY2hlY2tHTGNhbGwoImdsTGlnaHRNb2RlbGkoR0xfTElHSFRfTU9ERUxfTE9DQUxfVklFV0VSLCBHTF9UUlVFKTsiKTsKCiAgICBnbFRleEVudmYoR0xfVEVYVFVSRV9FTlYsIEdMX1RFWFRVUkVfRU5WX01PREUsIEdMX0NPTUJJTkVfRVhUKTsKICAgIGNoZWNrR0xjYWxsKCJnbFRleEVudmYoR0xfVEVYVFVSRV9FTlYsIEdMX1RFWFRVUkVfRU5WX01PREUsIEdMX0NPTUJJTkVfRVhUKTsiKTsKCiAgICBnbExpZ2h0TW9kZWxpKEdMX0xJR0hUX01PREVMX0NPTE9SX0NPTlRST0wsIEdMX1NFUEFSQVRFX1NQRUNVTEFSX0NPTE9SKTsKICAgIGNoZWNrR0xjYWxsKCJnbExpZ2h0TW9kZWxpKEdMX0xJR0hUX01PREVMX0NPTE9SX0NPTlRST0wsIEdMX1NFUEFSQVRFX1NQRUNVTEFSX0NPTE9SKTsiKTsKCiAgICBnbFBpeGVsU3RvcmVpKEdMX1BBQ0tfQUxJR05NRU5ULCBTVVJGQUNFX0FMSUdOTUVOVCk7CiAgICBjaGVja0dMY2FsbCgiZ2xQaXhlbFN0b3JlaShHTF9QQUNLX0FMSUdOTUVOVCwgU1VSRkFDRV9BTElHTk1FTlQpOyIpOwogICAgZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfQUxJR05NRU5ULCBTVVJGQUNFX0FMSUdOTUVOVCk7CiAgICBjaGVja0dMY2FsbCgiZ2xQaXhlbFN0b3JlaShHTF9VTlBBQ0tfQUxJR05NRU5ULCBTVVJGQUNFX0FMSUdOTUVOVCk7Iik7CgogICAgaWYob2xkRHJhd2FibGUgJiYgb2xkQ3R4KSB7CiAgICAgICAgZ2xYTWFrZUN1cnJlbnQoZGlzcGxheSwgb2xkRHJhd2FibGUsIG9sZEN0eCk7CiAgICB9CgpvdXQ6CiAgICBpZih2aXNpbmZvKSBYRnJlZSh2aXNpbmZvKTsKICAgIGlmKGNmZ3MpIFhGcmVlKGNmZ3MpOwogICAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFJlbW92ZUNvbnRleHRGcm9tQXJyYXkKICoKICogUmVtb3ZlcyBhIGNvbnRleHQgZnJvbSB0aGUgY29udGV4dCBtYW5hZ2VyLiBUaGUgb3BlbmdsIGNvbnRleHQgaXMgbm90CiAqIGRlc3Ryb3llZCBvciB1bnNldC4gY29udGV4dCBpcyBub3QgYSB2YWxpZCBwb2ludGVyIGFmdGVyIHRoYXQgY2FsbC4KICoKICogU2ltaWxhciB0byB0aGUgZm9ybWVyIGNhbGwgdGhpcyBpc24ndCBhIHBlcmZvcm1hbmNlIGNyaXRpY2FsIGZ1bmN0aW9uLiBBCiAqIGhlbHBlciBmdW5jdGlvbiBmb3IgRGVzdHJveUNvbnRleHQuCiAqCiAqIFBhcmFtczoKICogIFRoaXM6IERldmljZSB0byBhY3RpdmF0ZSB0aGUgY29udGV4dCBmb3IKICogIGNvbnRleHQ6IENvbnRleHQgdG8gcmVtb3ZlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIHZvaWQgUmVtb3ZlQ29udGV4dEZyb21BcnJheShJV2luZUQzRERldmljZUltcGwgKlRoaXMsIFdpbmVEM0RDb250ZXh0ICpjb250ZXh0KSB7CiAgICBVSU5UIHQsIHM7CiAgICBXaW5lRDNEQ29udGV4dCAqKm9sZEFycmF5ID0gVGhpcy0+Y29udGV4dHM7CgogICAgVFJBQ0UoIlJlbW92aW5nIGN0eCAlcFxuIiwgY29udGV4dCk7CgogICAgVGhpcy0+bnVtQ29udGV4dHMtLTsKCiAgICBpZihUaGlzLT5udW1Db250ZXh0cykgewogICAgICAgIFRoaXMtPmNvbnRleHRzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqVGhpcy0+Y29udGV4dHMpICogVGhpcy0+bnVtQ29udGV4dHMpOwogICAgICAgIGlmKCFUaGlzLT5jb250ZXh0cykgewogICAgICAgICAgICBFUlIoIkNhbm5vdCBhbGxvY2F0ZSBhIG5ldyBjb250ZXh0IGFycmF5LCBQQU5JQyEhIVxuIik7CiAgICAgICAgfQogICAgICAgIHQgPSAwOwogICAgICAgIGZvcihzID0gMDsgcyA8IFRoaXMtPm51bUNvbnRleHRzOyBzKyspIHsKICAgICAgICAgICAgaWYob2xkQXJyYXlbc10gPT0gY29udGV4dCkgY29udGludWU7CiAgICAgICAgICAgIFRoaXMtPmNvbnRleHRzW3RdID0gb2xkQXJyYXlbc107CiAgICAgICAgICAgIHQrKzsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIFRoaXMtPmNvbnRleHRzID0gTlVMTDsKICAgIH0KCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBjb250ZXh0KTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9sZEFycmF5KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERlc3Ryb3lDb250ZXh0CiAqCiAqIERlc3Ryb3lzIGEgd2luZUQzRENvbnRleHQKICoKICogUGFyYW1zOgogKiAgVGhpczogRGV2aWNlIHRvIGFjdGl2YXRlIHRoZSBjb250ZXh0IGZvcgogKiAgY29udGV4dDogQ29udGV4dCB0byBkZXN0cm95CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kdm9pZCBEZXN0cm95Q29udGV4dChJV2luZUQzRERldmljZUltcGwgKlRoaXMsIFdpbmVEM0RDb250ZXh0ICpjb250ZXh0KSB7CgogICAgLyogY2hlY2sgdGhhdCB3ZSBhcmUgdGhlIGN1cnJlbnQgY29udGV4dCBmaXJzdCAqLwogICAgVFJBQ0UoIkRlc3Ryb3lpbmcgY3R4ICVwXG4iLCBjb250ZXh0KTsKICAgIGlmKGdsWEdldEN1cnJlbnRDb250ZXh0KCkgPT0gY29udGV4dC0+Z2xDdHgpewogICAgICAgIGdsWE1ha2VDdXJyZW50KGNvbnRleHQtPmRpc3BsYXksIE5vbmUsIE5VTEwpOwogICAgfQoKICAgIGdsWERlc3Ryb3lDb250ZXh0KGNvbnRleHQtPmRpc3BsYXksIGNvbnRleHQtPmdsQ3R4KTsKICAgIGlmKGNvbnRleHQtPmlzUEJ1ZmZlcikgewogICAgICAgIGdsWERlc3Ryb3lQYnVmZmVyKGNvbnRleHQtPmRpc3BsYXksIGNvbnRleHQtPmRyYXdhYmxlKTsKICAgIH0KICAgIFJlbW92ZUNvbnRleHRGcm9tQXJyYXkoVGhpcywgY29udGV4dCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBTZXR1cEZvckJsaXQKICoKICogU2V0cyB1cCBhIGNvbnRleHQgZm9yIERpcmVjdERyYXcgYmxpdHRpbmcuCiAqIEFsbCB0ZXh0dXJlIHVuaXRzIGFyZSBkaXNhYmxlZCwgZXhjZXB0IHVuaXQgMAogKiBUZXh0dXJlIHVuaXQgMCBpcyBhY3RpdnRlZCB3aGVyZSBHTF9URVhUVVJFXzJEIGlzIGFjdGl2YXRlZAogKiBmb2csIGxpZ2h0aW5nLCBibGVuZGluZywgYWxwaGEgdGVzdCwgeiB0ZXN0LCBzY2lzc29yIHRlc3QsIGN1bGxpbmcgZGlhYmxlZAogKiBjb2xvciB3cml0aW5nIGVuYWJsZWQgZm9yIGFsbCBjaGFubmVscwogKiByZWdpc3RlciBjb21iaW5lcnMgZGlzYWJsZWQsIHNoYWRlcnMgZGlzYWJsZWQKICogd29ybGQgbWF0cmlzIGlzIHNldCB0byBpZGVudGl0eSwgdGV4dHVyZSBtYXRyaXggMCB0b28KICogcHJvamVjdGlvbiBtYXRyaXggaXMgc2V0dXAgZm9yIGRyYXdpbmcgc2NyZWVuIGNvb3JkaW5hdGVzCiAqCiAqIFBhcmFtczoKICogIFRoaXM6IERldmljZSB0byBhY3RpdmF0ZSB0aGUgY29udGV4dCBmb3IKICogIGNvbnRleHQ6IENvbnRleHQgdG8gc2V0dXAKICogIHdpZHRoOiByZW5kZXIgdGFyZ2V0IHdpZHRoCiAqICBoZWlnaHQ6IHJlbmRlciB0YXJnZXQgaGVpZ2h0CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIGlubGluZSB2b2lkIFNldHVwRm9yQmxpdChJV2luZUQzRERldmljZUltcGwgKlRoaXMsIFdpbmVEM0RDb250ZXh0ICpjb250ZXh0LCBVSU5UIHdpZHRoLCBVSU5UIGhlaWdodCkgewogICAgaW50IGk7CgogICAgVFJBQ0UoIlNldHRpbmcgdXAgY29udGV4dCAlcCBmb3IgYmxpdHRpbmdcbiIsIGNvbnRleHQpOwogICAgaWYoY29udGV4dC0+bGFzdF93YXNfYmxpdCkgewogICAgICAgIFRSQUNFKCJDb250ZXh0IGlzIGFscmVhZHkgc2V0IHVwIGZvciBibGl0dGluZywgbm90aGluZyB0byBkb1xuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgY29udGV4dC0+bGFzdF93YXNfYmxpdCA9IFRSVUU7CgogICAgLyogVE9ETzogVXNlIGEgZGlzcGxheSBsaXN0ICovCgogICAgLyogRGlzYWJsZSBzaGFkZXJzICovCiAgICBUaGlzLT5zaGFkZXJfYmFja2VuZC0+c2hhZGVyX2NsZWFudXAoKElXaW5lRDNERGV2aWNlICopIFRoaXMpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9WU0hBREVSKTsKICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfUElYRUxTSEFERVIpOwoKICAgIC8qIERpc2FibGUgYWxsIHRleHR1cmVzLiBUaGUgY2FsbGVyIGNhbiB0aGVuIGJpbmQgYSB0ZXh0dXJlIGl0IHdhbnRzIHRvIGJsaXQKICAgICAqIGZyb20KICAgICAqLwogICAgaWYoR0xfU1VQUE9SVChOVl9SRUdJU1RFUl9DT01CSU5FUlMpKSB7CiAgICAgICAgZ2xEaXNhYmxlKEdMX1JFR0lTVEVSX0NPTUJJTkVSU19OVik7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShHTF9SRUdJU1RFUl9DT01CSU5FUlNfTlYpIik7CiAgICB9CiAgICBpZiAoR0xfU1VQUE9SVChBUkJfTVVMVElURVhUVVJFKSkgewogICAgICAgIC8qIFRoZSBibGl0dGluZyBjb2RlIHVzZXMgKGZvciBub3cpIHRoZSBmaXhlZCBmdW5jdGlvbiBwaXBlbGluZSwgc28gbWFrZSBzdXJlIHRvIHJlc2V0IGFsbCBmaXhlZAogICAgICAgICAqIGZ1bmN0aW9uIHRleHR1cmUgdW5pdC4gTm8gbmVlZCB0byBjYXJlIGZvciBoaWdoZXIgc2FtcGxlcnMKICAgICAgICAgKi8KICAgICAgICBmb3IoaSA9IEdMX0xJTUlUUyh0ZXh0dXJlcykgLSAxOyBpID4gMCA7IGktLSkgewogICAgICAgICAgICBHTF9FWFRDQUxMKGdsQWN0aXZlVGV4dHVyZUFSQihHTF9URVhUVVJFMF9BUkIgKyBpKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbEFjdGl2ZVRleHR1cmVBUkIiKTsKCiAgICAgICAgICAgIGdsRGlzYWJsZShHTF9URVhUVVJFX0NVQkVfTUFQX0FSQik7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfVEVYVFVSRV9DVUJFX01BUF9BUkIiKTsKICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX1RFWFRVUkVfM0QpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX1RFWFRVUkVfM0QiKTsKICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX1RFWFRVUkVfMkQpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX1RFWFRVUkVfMkQiKTsKICAgICAgICAgICAgZ2xEaXNhYmxlKEdMX1RFWFRVUkVfMUQpOwogICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX1RFWFRVUkVfMUQiKTsKCiAgICAgICAgICAgIGdsVGV4RW52aShHTF9URVhUVVJFX0VOViwgR0xfVEVYVFVSRV9FTlZfTU9ERSwgR0xfUkVQTEFDRSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleEVudmkoR0xfVEVYVFVSRV9FTlYsIEdMX1RFWFRVUkVfRU5WX01PREUsIEdMX1JFUExBQ0UpOyIpOwoKICAgICAgICAgICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9URVhUVVJFU1RBR0UoaSwgV0lORUQzRFRTU19DT0xPUk9QKSk7CiAgICAgICAgICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfU0FNUExFUihpKSk7CiAgICAgICAgfQogICAgICAgIEdMX0VYVENBTEwoZ2xBY3RpdmVUZXh0dXJlQVJCKEdMX1RFWFRVUkUwX0FSQikpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEFjdGl2ZVRleHR1cmVBUkIiKTsKICAgIH0KICAgIGdsRGlzYWJsZShHTF9URVhUVVJFX0NVQkVfTUFQX0FSQik7CiAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX1RFWFRVUkVfQ1VCRV9NQVBfQVJCIik7CiAgICBnbERpc2FibGUoR0xfVEVYVFVSRV8zRCk7CiAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX1RFWFRVUkVfM0QiKTsKICAgIGdsRGlzYWJsZShHTF9URVhUVVJFXzFEKTsKICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfVEVYVFVSRV8xRCIpOwogICAgZ2xFbmFibGUoR0xfVEVYVFVSRV8yRCk7CiAgICBjaGVja0dMY2FsbCgiZ2xFbmFibGUgR0xfVEVYVFVSRV8yRCIpOwoKICAgIGdsVGV4RW52aShHTF9URVhUVVJFX0VOViwgR0xfVEVYVFVSRV9FTlZfTU9ERSwgR0xfUkVQTEFDRSk7CgogICAgZ2xNYXRyaXhNb2RlKEdMX1RFWFRVUkUpOwogICAgY2hlY2tHTGNhbGwoImdsTWF0cml4TW9kZShHTF9URVhUVVJFKSIpOwogICAgZ2xMb2FkSWRlbnRpdHkoKTsKICAgIGNoZWNrR0xjYWxsKCJnbExvYWRJZGVudGl0eSgpIik7CiAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1RSQU5TRk9STShXSU5FRDNEVFNfVEVYVFVSRTApKTsKCiAgICBpZiAoR0xfU1VQUE9SVChFWFRfVEVYVFVSRV9MT0RfQklBUykpIHsKICAgICAgICBnbFRleEVudmYoR0xfVEVYVFVSRV9GSUxURVJfQ09OVFJPTF9FWFQsCiAgICAgICAgICAgICAgICAgIEdMX1RFWFRVUkVfTE9EX0JJQVNfRVhULAogICAgICAgICAgICAgICAgICAwLjApOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFRleEVudmkgR0xfVEVYVFVSRV9MT0RfQklBU19FWFQgLi4uIik7CiAgICB9CiAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1NBTVBMRVIoMCkpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9URVhUVVJFU1RBR0UoMCwgV0lORUQzRFRTU19DT0xPUk9QKSk7CgogICAgLyogT3RoZXIgbWlzYyBzdGF0ZXMgKi8KICAgIGdsRGlzYWJsZShHTF9BTFBIQV9URVNUKTsKICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUoR0xfQUxQSEFfVEVTVCkiKTsKICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19BTFBIQVRFU1RFTkFCTEUpKTsKICAgIGdsRGlzYWJsZShHTF9MSUdIVElORyk7CiAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX0xJR0hUSU5HIik7CiAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1JFTkRFUihXSU5FRDNEUlNfTElHSFRJTkcpKTsKICAgIGdsRGlzYWJsZShHTF9ERVBUSF9URVNUKTsKICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfREVQVEhfVEVTVCIpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX1pFTkFCTEUpKTsKICAgIGdsRGlzYWJsZShHTF9GT0cpOwogICAgY2hlY2tHTGNhbGwoImdsRGlzYWJsZSBHTF9GT0ciKTsKICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19GT0dFTkFCTEUpKTsKICAgIGdsRGlzYWJsZShHTF9CTEVORCk7CiAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX0JMRU5EIik7CiAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1JFTkRFUihXSU5FRDNEUlNfQUxQSEFCTEVOREVOQUJMRSkpOwogICAgZ2xEaXNhYmxlKEdMX0NVTExfRkFDRSk7CiAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX0NVTExfRkFDRSIpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX0NVTExNT0RFKSk7CiAgICBnbERpc2FibGUoR0xfU1RFTkNJTF9URVNUKTsKICAgIGNoZWNrR0xjYWxsKCJnbERpc2FibGUgR0xfU1RFTkNJTF9URVNUIik7CiAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1JFTkRFUihXSU5FRDNEUlNfU1RFTkNJTEVOQUJMRSkpOwogICAgaWYoR0xfU1VQUE9SVChBUkJfUE9JTlRfU1BSSVRFKSkgewogICAgICAgIGdsRGlzYWJsZShHTF9QT0lOVF9TUFJJVEVfQVJCKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlIEdMX1BPSU5UX1NQUklURV9BUkIiKTsKICAgICAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFNUQVRFX1JFTkRFUihXSU5FRDNEUlNfUE9JTlRTUFJJVEVFTkFCTEUpKTsKICAgIH0KICAgIGdsQ29sb3JNYXNrKEdMX1RSVUUsIEdMX1RSVUUsR0xfVFJVRSxHTF9UUlVFKTsKICAgIGNoZWNrR0xjYWxsKCJnbENvbG9yTWFzayIpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9SRU5ERVIoV0lORUQzRFJTX0NMSVBQSU5HKSk7CgogICAgLyogU2V0dXAgdHJhbnNmb3JtcyAqLwogICAgZ2xNYXRyaXhNb2RlKEdMX01PREVMVklFVyk7CiAgICBjaGVja0dMY2FsbCgiZ2xNYXRyaXhNb2RlKEdMX01PREVMVklFVykiKTsKICAgIGdsTG9hZElkZW50aXR5KCk7CiAgICBjaGVja0dMY2FsbCgiZ2xMb2FkSWRlbnRpdHkoKSIpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9UUkFOU0ZPUk0oV0lORUQzRFRTX1dPUkxETUFUUklYKDApKSk7CgogICAgZ2xNYXRyaXhNb2RlKEdMX1BST0pFQ1RJT04pOwogICAgY2hlY2tHTGNhbGwoImdsTWF0cml4TW9kZShHTF9QUk9KRUNUSU9OKSIpOwogICAgZ2xMb2FkSWRlbnRpdHkoKTsKICAgIGNoZWNrR0xjYWxsKCJnbExvYWRJZGVudGl0eSgpIik7CiAgICBnbE9ydGhvKDAsIHdpZHRoLCBoZWlnaHQsIDAsIDAuMCwgLTEuMCk7CiAgICBjaGVja0dMY2FsbCgiZ2xPcnRobyIpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9UUkFOU0ZPUk0oV0lORUQzRFRTX1BST0pFQ1RJT04pKTsKCiAgICBjb250ZXh0LT5sYXN0X3dhc19yaHcgPSBUUlVFOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9WREVDTCk7IC8qIGJlY2F1c2Ugb2YgbGFzdF93YXNfcmh3ID0gVFJVRSAqLwoKICAgIGdsRGlzYWJsZShHTF9DTElQX1BMQU5FMCk7IGNoZWNrR0xjYWxsKCJnbERpc2FibGUoY2xpcCBwbGFuZSAwKSIpOwogICAgZ2xEaXNhYmxlKEdMX0NMSVBfUExBTkUxKTsgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShjbGlwIHBsYW5lIDEpIik7CiAgICBnbERpc2FibGUoR0xfQ0xJUF9QTEFORTIpOyBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKGNsaXAgcGxhbmUgMikiKTsKICAgIGdsRGlzYWJsZShHTF9DTElQX1BMQU5FMyk7IGNoZWNrR0xjYWxsKCJnbERpc2FibGUoY2xpcCBwbGFuZSAzKSIpOwogICAgZ2xEaXNhYmxlKEdMX0NMSVBfUExBTkU0KTsgY2hlY2tHTGNhbGwoImdsRGlzYWJsZShjbGlwIHBsYW5lIDQpIik7CiAgICBnbERpc2FibGUoR0xfQ0xJUF9QTEFORTUpOyBjaGVja0dMY2FsbCgiZ2xEaXNhYmxlKGNsaXAgcGxhbmUgNSkiKTsKICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgU1RBVEVfUkVOREVSKFdJTkVEM0RSU19DTElQUElORykpOwoKICAgIGdsVmlld3BvcnQoMCwgMCwgd2lkdGgsIGhlaWdodCk7CiAgICBjaGVja0dMY2FsbCgiZ2xWaWV3cG9ydCIpOwogICAgQ29udGV4dF9NYXJrU3RhdGVEaXJ0eShjb250ZXh0LCBTVEFURV9WSUVXUE9SVCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBBY3RpdmF0ZUNvbnRleHQKICoKICogRmluZHMgYSByZW5kZXJpbmcgY29udGV4dCBhbmQgZHJhd2FibGUgbWF0Y2hpbmcgdGhlIGRldmljZSBhbmQgcmVuZGVyCiAqIHRhcmdldCBmb3IgdGhlIGN1cnJlbnQgdGhyZWFkLCBhY3RpdmF0ZXMgdGhlbSBhbmQgcHV0cyB0aGVtIGludG8gdGhlCiAqIHJlcXVlc3RlZCBzdGF0ZS4KICoKICogUGFyYW1zOgogKiAgVGhpczogRGV2aWNlIHRvIGFjdGl2YXRlIHRoZSBjb250ZXh0IGZvcgogKiAgdGFyZ2V0OiBSZXF1ZXN0ZWQgcmVuZGVyIHRhcmdldAogKiAgdXNhZ2U6IFByZXBhcmVzIHRoZSBjb250ZXh0IGZvciBibGl0dGluZywgZHJhd2luZyBvciBvdGhlciBhY3Rpb25zCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kdm9pZCBBY3RpdmF0ZUNvbnRleHQoSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzLCBJV2luZUQzRFN1cmZhY2UgKnRhcmdldCwgQ29udGV4dFVzYWdlIHVzYWdlKSB7CiAgICBEV09SRCB0aWQgPSBUaGlzLT5jcmVhdGVQYXJtcy5CZWhhdmlvckZsYWdzICYgV0lORUQzRENSRUFURV9NVUxUSVRIUkVBREVEID8gR2V0Q3VycmVudFRocmVhZElkKCkgOiAwOwogICAgaW50ICAgICAgICAgICAgICAgICAgICAgICAgICAgaTsKICAgIERXT1JEICAgICAgICAgICAgICAgICAgICAgICAgIGRpcnR5U3RhdGUsIGlkeDsKICAgIEJZVEUgICAgICAgICAgICAgICAgICAgICAgICAgIHNoaWZ0OwogICAgV2luZUQzRENvbnRleHQgICAgICAgICAgICAgICAgKmNvbnRleHQgPSBUaGlzLT5hY3RpdmVDb250ZXh0OwogICAgQk9PTCAgICAgICAgICAgICAgICAgICAgICAgICAgb2xkUmVuZGVyT2Zmc2NyZWVuID0gVGhpcy0+cmVuZGVyX29mZnNjcmVlbjsKCiAgICBUUkFDRSgiKCVwKTogU2VsZWN0aW5nIGNvbnRleHQgZm9yIHJlbmRlciB0YXJnZXQgJXAsIHRocmVhZCAlZFxuIiwgVGhpcywgdGFyZ2V0LCB0aWQpOwoKICAgIGlmKFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQgIT0gdGFyZ2V0KSB7CiAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW4gKnN3YXBjaGFpbiA9IE5VTEw7CiAgICAgICAgSFJFU1VMVCBocjsKICAgICAgICBCT09MIHJlYWRUZXh0dXJlID0gd2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUgIT0gT1JNX0ZCTyAmJiBUaGlzLT5yZW5kZXJfb2Zmc2NyZWVuOwoKICAgICAgICBociA9IElXaW5lRDNEU3VyZmFjZV9HZXRDb250YWluZXIodGFyZ2V0LCAmSUlEX0lXaW5lRDNEU3dhcENoYWluLCAodm9pZCAqKikgJnN3YXBjaGFpbik7CiAgICAgICAgaWYoaHIgPT0gV0lORUQzRF9PSyAmJiBzd2FwY2hhaW4pIHsKICAgICAgICAgICAgVFJBQ0UoIlJlbmRlcmluZyBvbnNjcmVlblxuIik7CiAgICAgICAgICAgIGNvbnRleHQgPSAoKElXaW5lRDNEU3dhcENoYWluSW1wbCAqKSBzd2FwY2hhaW4pLT5jb250ZXh0OwogICAgICAgICAgICBUaGlzLT5yZW5kZXJfb2Zmc2NyZWVuID0gRkFMU0U7CiAgICAgICAgICAgIC8qIFRoZSBjb250ZXh0ICE9IFRoaXMtPmFjdGl2ZUNvbnRleHQgd2lsbCBjYXRjaCBhIE5PUCBjb250ZXh0IGNoYW5nZS4gVGhpcyBjYW4gb2NjdXIKICAgICAgICAgICAgICogaWYgd2UgYXJlIHN3aXRjaGluZyBiYWNrIHRvIHN3YXBjaGFpbiByZW5kZXJpbmcgaW4gY2FzZSBvZiBGQk8gb3IgQmFjayBCdWZmZXIgb2Zmc2NyZWVuCiAgICAgICAgICAgICAqIHJlbmRlcmluZy4gTm8gY29udGV4dCBjaGFuZ2UgaXMgbmVlZGVkIGluIHRoYXQgY2FzZQogICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIGlmICh3aW5lZDNkX3NldHRpbmdzLm9mZnNjcmVlbl9yZW5kZXJpbmdfbW9kZSA9PSBPUk1fRkJPICYmIG9sZFJlbmRlck9mZnNjcmVlbikgewogICAgICAgICAgICAgICAgc2V0X3JlbmRlcl90YXJnZXRfZmJvKChJV2luZUQzRERldmljZSAqKSBUaGlzLCAwLCB0YXJnZXQpOwogICAgICAgICAgICB9IGVsc2UgaWYod2luZWQzZF9zZXR0aW5ncy5vZmZzY3JlZW5fcmVuZGVyaW5nX21vZGUgPT0gT1JNX0JBQ0tCVUZGRVIpIHsKICAgICAgICAgICAgICAgIGlmKCgoSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICopIHN3YXBjaGFpbiktPmJhY2tCdWZmZXIpIHsKICAgICAgICAgICAgICAgICAgICBnbERyYXdCdWZmZXIoR0xfQkFDSyk7CiAgICAgICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcihHTF9CQUNLKSIpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBnbERyYXdCdWZmZXIoR0xfRlJPTlQpOwogICAgICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbERyYXdCdWZmZXIoR0xfRlJPTlQpIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgSVdpbmVEM0RTd2FwQ2hhaW5fUmVsZWFzZShzd2FwY2hhaW4pOwoKICAgICAgICAgICAgaWYob2xkUmVuZGVyT2Zmc2NyZWVuKSB7CiAgICAgICAgICAgICAgICBDb250ZXh0X01hcmtTdGF0ZURpcnR5KGNvbnRleHQsIFdJTkVEM0RSU19DVUxMTU9ERSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBUUkFDRSgiUmVuZGVyaW5nIG9mZnNjcmVlblxuIik7CiAgICAgICAgICAgIFRoaXMtPnJlbmRlcl9vZmZzY3JlZW4gPSBUUlVFOwoKICAgICAgICAgICAgc3dpdGNoKHdpbmVkM2Rfc2V0dGluZ3Mub2Zmc2NyZWVuX3JlbmRlcmluZ19tb2RlKSB7CiAgICAgICAgICAgICAgICBjYXNlIE9STV9GQk86CiAgICAgICAgICAgICAgICAgICAgLyogRkJPcyBkbyBub3QgbmVlZCBhIGRpZmZlcmVudCBjb250ZXh0LiBTdGF5IHdpdGggd2hhdGV2ZXIgY29udGV4dCBpcyBhY3RpdmUgYXQgdGhlIG1vbWVudCAqLwogICAgICAgICAgICAgICAgICAgIGlmKFRoaXMtPmFjdGl2ZUNvbnRleHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dCA9IFRoaXMtPmFjdGl2ZUNvbnRleHQ7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogVGhpcyBtYXkgaGFwcGVuIGlmIHRoZSBhcHAganVtcHMgc3RyZWlnaHQgaW50byBvZmZzY3JlZW4gcmVuZGVyaW5nCiAgICAgICAgICAgICAgICAgICAgICAgICAqIFN0YXJ0IHVzaW5nIHRoZSBjb250ZXh0IG9mIHRoZSBwcmltYXJ5IHN3YXBjaGFpbgogICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgY29udGV4dCA9ICgoSVdpbmVEM0RTd2FwQ2hhaW5JbXBsICopIFRoaXMtPnN3YXBjaGFpbnNbMF0pLT5jb250ZXh0OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBzZXRfcmVuZGVyX3RhcmdldF9mYm8oKElXaW5lRDNERGV2aWNlICopIFRoaXMsIDAsIHRhcmdldCk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBPUk1fUEJVRkZFUjoKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VJbXBsICp0YXJnZXRpbXBsID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgdGFyZ2V0OwogICAgICAgICAgICAgICAgICAgIGlmKFRoaXMtPnBidWZmZXJDb250ZXh0ID09IE5VTEwgfHwKICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5wYnVmZmVyV2lkdGggPCB0YXJnZXRpbXBsLT5jdXJyZW50RGVzYy5XaWR0aCB8fAogICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPnBidWZmZXJIZWlnaHQgPCB0YXJnZXRpbXBsLT5jdXJyZW50RGVzYy5IZWlnaHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoVGhpcy0+cGJ1ZmZlckNvbnRleHQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERlc3Ryb3lDb250ZXh0KFRoaXMsIFRoaXMtPnBidWZmZXJDb250ZXh0KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgLyogVGhlIGRpc3BsYXkgaXMgaXJyZWxldmFudCBoZXJlLCB0aGUgd2luZG93IGlzIDAuIEJ1dCBDcmVhdGVDb250ZXh0IG5lZWRzIGEgdmFsaWQgWCBjb25uZWN0aW9uLgogICAgICAgICAgICAgICAgICAgICAgICAgKiBDcmVhdGUgdGhlIGNvbnRleHQgb24gdGhlIHNhbWUgc2VydmVyIGFzIHRoZSBwcmltYXJ5IHN3YXBjaGFpbi4gVGhlIHByaW1hcnkgc3dhcGNoYWluIGlzIGV4aXN0cyBhdCB0aGlzIHBvaW50LgogICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+cGJ1ZmZlckNvbnRleHQgPSBDcmVhdGVDb250ZXh0KFRoaXMsIHRhcmdldGltcGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKElXaW5lRDNEU3dhcENoYWluSW1wbCAqKSBUaGlzLT5zd2FwY2hhaW5zWzBdKS0+Y29udGV4dC0+ZGlzcGxheSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLyogV2luZG93ICovKTsKICAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+cGJ1ZmZlcldpZHRoID0gdGFyZ2V0aW1wbC0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPnBidWZmZXJIZWlnaHQgPSB0YXJnZXRpbXBsLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpZihUaGlzLT5wYnVmZmVyQ29udGV4dCkgewogICAgICAgICAgICAgICAgICAgICAgICBjb250ZXh0ID0gVGhpcy0+cGJ1ZmZlckNvbnRleHQ7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIEVSUigiRmFpbGVkIHRvIGNyZWF0ZSBhIGJ1ZmZlciBjb250ZXh0IGFuZCBkcmF3YWJsZSwgZmFsbGluZyBiYWNrIHRvIGJhY2sgYnVmZmVyIG9mZnNjcmVlbiByZW5kZXJpbmdcbiIpOwogICAgICAgICAgICAgICAgICAgICAgICB3aW5lZDNkX3NldHRpbmdzLm9mZnNjcmVlbl9yZW5kZXJpbmdfbW9kZSA9IE9STV9CQUNLQlVGRkVSOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBjYXNlIE9STV9CQUNLQlVGRkVSOgogICAgICAgICAgICAgICAgICAgIC8qIFN0YXkgd2l0aCB0aGUgY3VycmVudGx5IGFjdGl2ZSBjb250ZXh0IGZvciBiYWNrIGJ1ZmZlciByZW5kZXJpbmcgKi8KICAgICAgICAgICAgICAgICAgICBpZihUaGlzLT5hY3RpdmVDb250ZXh0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQgPSBUaGlzLT5hY3RpdmVDb250ZXh0OwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFRoaXMgbWF5IGhhcHBlbiBpZiB0aGUgYXBwIGp1bXBzIHN0cmVpZ2h0IGludG8gb2Zmc2NyZWVuIHJlbmRlcmluZwogICAgICAgICAgICAgICAgICAgICAgICAgKiBTdGFydCB1c2luZyB0aGUgY29udGV4dCBvZiB0aGUgcHJpbWFyeSBzd2FwY2hhaW4KICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQgPSAoKElXaW5lRDNEU3dhcENoYWluSW1wbCAqKSBUaGlzLT5zd2FwY2hhaW5zWzBdKS0+Y29udGV4dDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZ2xEcmF3QnVmZmVyKFRoaXMtPm9mZnNjcmVlbkJ1ZmZlcik7CiAgICAgICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsRHJhd0J1ZmZlcihUaGlzLT5vZmZzY3JlZW5CdWZmZXIpIik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmKCFvbGRSZW5kZXJPZmZzY3JlZW4pIHsKICAgICAgICAgICAgICAgIENvbnRleHRfTWFya1N0YXRlRGlydHkoY29udGV4dCwgV0lORUQzRFJTX0NVTExNT0RFKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAocmVhZFRleHR1cmUpIHsKICAgICAgICAgICAgQk9PTCBvbGRJbkRyYXcgPSBUaGlzLT5pc0luRHJhdzsKCiAgICAgICAgICAgIC8qIFByZUxvYWQgcmVxdWlyZXMgYSBjb250ZXh0IHRvIGxvYWQgdGhlIHRleHR1cmUsIHRodXMgaXQgd2lsbCBjYWxsIEFjdGl2YXRlQ29udGV4dC4KICAgICAgICAgICAgICogU2V0IHRoZSBpc0luRHJhdyB0byB0cnVlIHRvIHNpZ25hbCBQcmVMb2FkIHRoYXQgaXQgaGFzIGEgY29udGV4dC4gV2lsbCBiZSB0cmlja3kKICAgICAgICAgICAgICogd2hlbiB1c2luZyBvZmZzY3JlZW4gcmVuZGVyaW5nIHdpdGggbXVsdGl0aHJlYWRpbmcKICAgICAgICAgICAgICovCiAgICAgICAgICAgIFRoaXMtPmlzSW5EcmF3ID0gVFJVRTsKCiAgICAgICAgICAgIC8qIERvIHRoYXQgYmVmb3JlIHN3aXRjaGluZyB0aGUgY29udGV4dDoKICAgICAgICAgICAgICogUmVhZCB0aGUgYmFjayBidWZmZXIgb2YgdGhlIG9sZCBkcmF3YWJsZSBpbnRvIHRoZSBkZXN0aW5hdGlvbiB0ZXh0dXJlCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfUHJlTG9hZChUaGlzLT5sYXN0QWN0aXZlUmVuZGVyVGFyZ2V0KTsKCiAgICAgICAgICAgIC8qIEFzc3VtZSB0aGF0IHRoZSBkcmF3YWJsZSB3aWxsIGJlIG1vZGlmaWVkIGJ5IHNvbWUgb3RoZXIgdGhpbmdzIG5vdyAqLwogICAgICAgICAgICAoKElXaW5lRDNEU3VyZmFjZUltcGwgKikgVGhpcy0+bGFzdEFjdGl2ZVJlbmRlclRhcmdldCktPkZsYWdzICY9IH5TRkxBR19JTkRSQVdBQkxFOwoKICAgICAgICAgICAgVGhpcy0+aXNJbkRyYXcgPSBvbGRJbkRyYXc7CiAgICAgICAgfQogICAgICAgIFRoaXMtPmxhc3RBY3RpdmVSZW5kZXJUYXJnZXQgPSB0YXJnZXQ7CiAgICAgICAgaWYob2xkUmVuZGVyT2Zmc2NyZWVuICE9IFRoaXMtPnJlbmRlcl9vZmZzY3JlZW4gJiYgVGhpcy0+ZGVwdGhfY29weV9zdGF0ZSAhPSBXSU5FRDNEX0RDU19OT19DT1BZKSB7CiAgICAgICAgICAgIFRoaXMtPmRlcHRoX2NvcHlfc3RhdGUgPSBXSU5FRDNEX0RDU19DT1BZOwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgLyogU3RpY2sgdG8gdGhlIG9sZCBjb250ZXh0ICovCiAgICAgICAgY29udGV4dCA9IFRoaXMtPmFjdGl2ZUNvbnRleHQ7CiAgICB9CgogICAgLyogQWN0aXZhdGUgdGhlIG9wZW5nbCBjb250ZXh0ICovCiAgICBpZihjb250ZXh0ICE9IFRoaXMtPmFjdGl2ZUNvbnRleHQpIHsKICAgICAgICBCb29sIHJldDsKICAgICAgICBUUkFDRSgiU3dpdGNoaW5nIGdsIGN0eCB0byAlcCwgZHJhd2FibGU9JWxkLCBjdHg9JXBcbiIsIGNvbnRleHQsIGNvbnRleHQtPmRyYXdhYmxlLCBjb250ZXh0LT5nbEN0eCk7CiAgICAgICAgcmV0ID0gZ2xYTWFrZUN1cnJlbnQoY29udGV4dC0+ZGlzcGxheSwgY29udGV4dC0+ZHJhd2FibGUsIGNvbnRleHQtPmdsQ3R4KTsKICAgICAgICBpZihyZXQgPT0gRkFMU0UpIHsKICAgICAgICAgICAgRVJSKCJGYWlsZWQgdG8gYWN0aXZhdGUgdGhlIG5ldyBjb250ZXh0XG4iKTsKICAgICAgICB9CiAgICAgICAgVGhpcy0+YWN0aXZlQ29udGV4dCA9IGNvbnRleHQ7CiAgICB9CgogICAgc3dpdGNoKHVzYWdlKSB7CiAgICAgICAgY2FzZSBDVFhVU0FHRV9SRVNPVVJDRUxPQUQ6CiAgICAgICAgICAgIC8qIFRoaXMgZG9lcyBub3QgcmVxdWlyZSBhbnkgc3BlY2lhbCBzdGF0ZXMgdG8gYmUgc2V0IHVwICovCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIENUWFVTQUdFX0RSQVdQUklNOgogICAgICAgICAgICAvKiBUaGlzIG5lZWRzIGFsbCBkaXJ0eSBzdGF0ZXMgYXBwbGllZCAqLwogICAgICAgICAgICBmb3IoaT0wOyBpIDwgY29udGV4dC0+bnVtRGlydHlFbnRyaWVzOyBpKyspIHsKICAgICAgICAgICAgICAgIGRpcnR5U3RhdGUgPSBjb250ZXh0LT5kaXJ0eUFycmF5W2ldOwogICAgICAgICAgICAgICAgaWR4ID0gZGlydHlTdGF0ZSA+PiA1OwogICAgICAgICAgICAgICAgc2hpZnQgPSBkaXJ0eVN0YXRlICYgMHgxZjsKICAgICAgICAgICAgICAgIGNvbnRleHQtPmlzU3RhdGVEaXJ0eVtpZHhdICY9IH4oMSA8PCBzaGlmdCk7CiAgICAgICAgICAgICAgICBTdGF0ZVRhYmxlW2RpcnR5U3RhdGVdLmFwcGx5KGRpcnR5U3RhdGUsIFRoaXMtPnN0YXRlQmxvY2ssIGNvbnRleHQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNvbnRleHQtPm51bURpcnR5RW50cmllcyA9IDA7IC8qIFRoaXMgbWFrZXMgdGhlIHdob2xlIGxpc3QgY2xlYW4gKi8KICAgICAgICAgICAgY29udGV4dC0+bGFzdF93YXNfYmxpdCA9IEZBTFNFOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBDVFhVU0FHRV9CTElUOgogICAgICAgICAgICBTZXR1cEZvckJsaXQoVGhpcywgY29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKXRhcmdldCktPmN1cnJlbnREZXNjLldpZHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgKChJV2luZUQzRFN1cmZhY2VJbXBsICopdGFyZ2V0KS0+Y3VycmVudERlc2MuSGVpZ2h0KTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEZJWE1FKCJVbmV4cGVjdGVkIGNvbnRleHQgdXNhZ2UgcmVxdWVzdGVkXG4iKTsKICAgIH0KfQo=