LyoKICogR0xTTCBwaXhlbCBhbmQgdmVydGV4IHNoYWRlciBpbXBsZW1lbnRhdGlvbgogKgogKiBDb3B5cmlnaHQgMjAwNiBKYXNvbiBHcmVlbiAKICogQ29weXJpZ2h0IDIwMDYtMjAwNyBIZW5yaSBWZXJiZWV0CiAqIENvcHlyaWdodCAyMDA3LTIwMDggU3RlZmFuIET2c2luZ2VyIGZvciBDb2RlV2VhdmVycwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgovKgogKiBEM0Qgc2hhZGVyIGFzbSBoYXMgc3dpenpsZXMgb24gc291cmNlIHBhcmFtZXRlcnMsIGFuZCB3cml0ZSBtYXNrcyBmb3IKICogZGVzdGluYXRpb24gcGFyYW1ldGVycy4gR0xTTCB1c2VzIHN3aXp6bGVzIGZvciBib3RoLiBUaGUgcmVzdWx0IG9mIHRoaXMgaXMKICogdGhhdCBmb3IgZXhhbXBsZSAibW92IGRzdC54dywgc3JjLnp5eHciIGJlY29tZXMgImRzdC54dyA9IHNyYy56dyIgaW4gR0xTTC4KICogSWUsIHRvIGdlbmVyYXRlIGEgcHJvcGVyIEdMU0wgc291cmNlIHN3aXp6bGUsIHdlIG5lZWQgdG8gdGFrZSB0aGUgRDNEIHdyaXRlCiAqIG1hc2sgZm9yIHRoZSBkZXN0aW5hdGlvbiBwYXJhbWV0ZXIgaW50byBhY2NvdW50LgogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlICJ3aW5lZDNkX3ByaXZhdGUuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGQzZF9zaGFkZXIpOwpXSU5FX0RFQ0xBUkVfREVCVUdfQ0hBTk5FTChkM2RfY29uc3RhbnRzKTsKV0lORV9ERUNMQVJFX0RFQlVHX0NIQU5ORUwoZDNkX2NhcHMpOwoKI2RlZmluZSBHTElORk9fTE9DQVRJT04gICAgICAoKmdsX2luZm8pCgp0eXBlZGVmIHN0cnVjdCB7CiAgICBjaGFyIHJlZ19uYW1lWzUwXTsKICAgIGNoYXIgbWFza19zdHJbNl07Cn0gZ2xzbF9kc3RfcGFyYW1fdDsKCnR5cGVkZWYgc3RydWN0IHsKICAgIGNoYXIgcmVnX25hbWVbNTBdOwogICAgY2hhciBwYXJhbV9zdHJbMTAwXTsKfSBnbHNsX3NyY19wYXJhbV90OwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgY29uc3QgY2hhciAqbmFtZTsKICAgIERXT1JEIGNvb3JkX21hc2s7Cn0gZ2xzbF9zYW1wbGVfZnVuY3Rpb25fdDsKCi8qKiBQcmludHMgdGhlIEdMU0wgaW5mbyBsb2cgd2hpY2ggd2lsbCBjb250YWluIGVycm9yIG1lc3NhZ2VzIGlmIHRoZXkgZXhpc3QgKi8Kdm9pZCBwcmludF9nbHNsX2luZm9fbG9nKFdpbmVEM0RfR0xfSW5mbyAqZ2xfaW5mbywgR0xoYW5kbGVBUkIgb2JqKSB7CiAgICAKICAgIGludCBpbmZvbG9nTGVuZ3RoID0gMDsKICAgIGNoYXIgKmluZm9Mb2c7CiAgICBpbnQgaTsKICAgIEJPT0wgaXNfc3BhbTsKCiAgICBjb25zdCBjaGFyICpzcGFtW10gPSB7CiAgICAgICAgIlZlcnRleCBzaGFkZXIgd2FzIHN1Y2Nlc3NmdWxseSBjb21waWxlZCB0byBydW4gb24gaGFyZHdhcmUuXG4iLCAgICAvKiBmZ2xyeCAgICAgICAgICAqLwogICAgICAgICJGcmFnbWVudCBzaGFkZXIgd2FzIHN1Y2Nlc3NmdWxseSBjb21waWxlZCB0byBydW4gb24gaGFyZHdhcmUuXG4iLCAgLyogZmdscnggICAgICAgICAgKi8KICAgICAgICAiRnJhZ21lbnQgc2hhZGVyKHMpIGxpbmtlZCwgdmVydGV4IHNoYWRlcihzKSBsaW5rZWQuIFxuICIsICAgICAgICAgIC8qIGZnbHJ4LCB3aXRoIFxuICovCiAgICAgICAgIkZyYWdtZW50IHNoYWRlcihzKSBsaW5rZWQsIHZlcnRleCBzaGFkZXIocykgbGlua2VkLiIsICAgICAgICAgICAgICAvKiBmZ2xyeCwgbm8gXG4gICAqLwogICAgICAgICJWZXJ0ZXggc2hhZGVyKHMpIGxpbmtlZCwgbm8gZnJhZ21lbnQgc2hhZGVyKHMpIGRlZmluZWQuIFxuICIsICAgICAgLyogZmdscngsIHdpdGggXG4gKi8KICAgICAgICAiVmVydGV4IHNoYWRlcihzKSBsaW5rZWQsIG5vIGZyYWdtZW50IHNoYWRlcihzKSBkZWZpbmVkLiIsICAgICAgICAgIC8qIGZnbHJ4LCBubyBcbiAgICovCiAgICAgICAgIkZyYWdtZW50IHNoYWRlciB3YXMgc3VjY2Vzc2Z1bGx5IGNvbXBpbGVkIHRvIHJ1biBvbiBoYXJkd2FyZS5cbldBUk5JTkc6IDA6MTogZXh0ZW5zaW9uICdHTF9BUkJfZHJhd19idWZmZXJzJyBpcyBub3Qgc3VwcG9ydGVkIiwKICAgICAgICAiRnJhZ21lbnQgc2hhZGVyKHMpIGxpbmtlZCwgbm8gdmVydGV4IHNoYWRlcihzKSBkZWZpbmVkLiIsICAgICAgICAgIC8qIGZnbHJ4LCBubyBcbiAgICovCiAgICAgICAgIkZyYWdtZW50IHNoYWRlcihzKSBsaW5rZWQsIG5vIHZlcnRleCBzaGFkZXIocykgZGVmaW5lZC4gXG4gIiAgICAgICAvKiBmZ2xyeCwgd2l0aCBcbiAqLwogICAgfTsKCiAgICBHTF9FWFRDQUxMKGdsR2V0T2JqZWN0UGFyYW1ldGVyaXZBUkIob2JqLAogICAgICAgICAgICAgICBHTF9PQkpFQ1RfSU5GT19MT0dfTEVOR1RIX0FSQiwKICAgICAgICAgICAgICAgJmluZm9sb2dMZW5ndGgpKTsKCiAgICAvKiBBIHNpemUgb2YgMSBpcyBqdXN0IGEgbnVsbC10ZXJtaW5hdGVkIHN0cmluZywgc28gdGhlIGxvZyBzaG91bGQgYmUgYmlnZ2VyIHRoYW4KICAgICAqIHRoYXQgaWYgdGhlcmUgYXJlIGVycm9ycy4gKi8KICAgIGlmIChpbmZvbG9nTGVuZ3RoID4gMSkKICAgIHsKICAgICAgICAvKiBGZ2xyeCBkb2Vzbid0IHRlcm1pbmF0ZSB0aGUgc3RyaW5nIHByb3Blcmx5LCBidXQgaXQgdGVsbHMgdXMgdGhlIHByb3BlciBsZW5ndGguCiAgICAgICAgICogU28gdXNlIEhFQVBfWkVST19NRU1PUlkgdG8gYXZvaWQgdW5pbml0aWFsaXplZCBieXRlcwogICAgICAgICAqLwogICAgICAgIGluZm9Mb2cgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgaW5mb2xvZ0xlbmd0aCk7CiAgICAgICAgR0xfRVhUQ0FMTChnbEdldEluZm9Mb2dBUkIob2JqLCBpbmZvbG9nTGVuZ3RoLCBOVUxMLCBpbmZvTG9nKSk7CiAgICAgICAgaXNfc3BhbSA9IEZBTFNFOwoKICAgICAgICBmb3IoaSA9IDA7IGkgPCBzaXplb2Yoc3BhbSkgLyBzaXplb2Yoc3BhbVswXSk7IGkrKykgewogICAgICAgICAgICBpZihzdHJjbXAoaW5mb0xvZywgc3BhbVtpXSkgPT0gMCkgewogICAgICAgICAgICAgICAgaXNfc3BhbSA9IFRSVUU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZihpc19zcGFtKSB7CiAgICAgICAgICAgIFRSQUNFKCJTcGFtIHJlY2VpdmVkIGZyb20gR0xTTCBzaGFkZXIgIyV1OiAlc1xuIiwgb2JqLCBkZWJ1Z3N0cl9hKGluZm9Mb2cpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBGSVhNRSgiRXJyb3IgcmVjZWl2ZWQgZnJvbSBHTFNMIHNoYWRlciAjJXU6ICVzXG4iLCBvYmosIGRlYnVnc3RyX2EoaW5mb0xvZykpOwogICAgICAgIH0KICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBpbmZvTG9nKTsKICAgIH0KfQoKLyoqCiAqIExvYWRzIChwaXhlbCBzaGFkZXIpIHNhbXBsZXJzCiAqLwpzdGF0aWMgdm9pZCBzaGFkZXJfZ2xzbF9sb2FkX3BzYW1wbGVycygKICAgIFdpbmVEM0RfR0xfSW5mbyAqZ2xfaW5mbywKICAgIElXaW5lRDNEU3RhdGVCbG9jayogaWZhY2UsCiAgICBHTGhhbmRsZUFSQiBwcm9ncmFtSWQpIHsKCiAgICBJV2luZUQzRFN0YXRlQmxvY2tJbXBsKiBzdGF0ZUJsb2NrID0gKElXaW5lRDNEU3RhdGVCbG9ja0ltcGwqKSBpZmFjZTsKICAgIEdMaGFuZGxlQVJCIG5hbWVfbG9jOwogICAgaW50IGk7CiAgICBjaGFyIHNhbXBsZXJfbmFtZVsyMF07CgogICAgZm9yIChpID0gMDsgaSA8IE1BWF9GUkFHTUVOVF9TQU1QTEVSUzsgKytpKSB7CiAgICAgICAgc25wcmludGYoc2FtcGxlcl9uYW1lLCBzaXplb2Yoc2FtcGxlcl9uYW1lKSwgIlBzYW1wbGVyJWQiLCBpKTsKICAgICAgICBuYW1lX2xvYyA9IEdMX0VYVENBTEwoZ2xHZXRVbmlmb3JtTG9jYXRpb25BUkIocHJvZ3JhbUlkLCBzYW1wbGVyX25hbWUpKTsKICAgICAgICBpZiAobmFtZV9sb2MgIT0gLTEpIHsKICAgICAgICAgICAgaW50IG1hcHBlZF91bml0ID0gc3RhdGVCbG9jay0+d2luZUQzRERldmljZS0+dGV4VW5pdE1hcFtpXTsKICAgICAgICAgICAgaWYgKG1hcHBlZF91bml0ICE9IC0xICYmIG1hcHBlZF91bml0IDwgR0xfTElNSVRTKGZyYWdtZW50X3NhbXBsZXJzKSkgewogICAgICAgICAgICAgICAgVFJBQ0UoIkxvYWRpbmcgJXMgZm9yIHRleHR1cmUgJWRcbiIsIHNhbXBsZXJfbmFtZSwgbWFwcGVkX3VuaXQpOwogICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFVuaWZvcm0xaUFSQihuYW1lX2xvYywgbWFwcGVkX3VuaXQpKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFVuaWZvcm0xaUFSQiIpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgRVJSKCJUcnlpbmcgdG8gbG9hZCBzYW1wbGVyICVzIG9uIHVuc3VwcG9ydGVkIHVuaXQgJWRcbiIsIHNhbXBsZXJfbmFtZSwgbWFwcGVkX3VuaXQpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CgpzdGF0aWMgdm9pZCBzaGFkZXJfZ2xzbF9sb2FkX3ZzYW1wbGVycyhXaW5lRDNEX0dMX0luZm8gKmdsX2luZm8sIElXaW5lRDNEU3RhdGVCbG9jayogaWZhY2UsIEdMaGFuZGxlQVJCIHByb2dyYW1JZCkgewogICAgSVdpbmVEM0RTdGF0ZUJsb2NrSW1wbCogc3RhdGVCbG9jayA9IChJV2luZUQzRFN0YXRlQmxvY2tJbXBsKikgaWZhY2U7CiAgICBHTGhhbmRsZUFSQiBuYW1lX2xvYzsKICAgIGNoYXIgc2FtcGxlcl9uYW1lWzIwXTsKICAgIGludCBpOwoKICAgIGZvciAoaSA9IDA7IGkgPCBNQVhfVkVSVEVYX1NBTVBMRVJTOyArK2kpIHsKICAgICAgICBzbnByaW50ZihzYW1wbGVyX25hbWUsIHNpemVvZihzYW1wbGVyX25hbWUpLCAiVnNhbXBsZXIlZCIsIGkpOwogICAgICAgIG5hbWVfbG9jID0gR0xfRVhUQ0FMTChnbEdldFVuaWZvcm1Mb2NhdGlvbkFSQihwcm9ncmFtSWQsIHNhbXBsZXJfbmFtZSkpOwogICAgICAgIGlmIChuYW1lX2xvYyAhPSAtMSkgewogICAgICAgICAgICBpbnQgbWFwcGVkX3VuaXQgPSBzdGF0ZUJsb2NrLT53aW5lRDNERGV2aWNlLT50ZXhVbml0TWFwW01BWF9GUkFHTUVOVF9TQU1QTEVSUyArIGldOwogICAgICAgICAgICBpZiAobWFwcGVkX3VuaXQgIT0gLTEgJiYgbWFwcGVkX3VuaXQgPCBHTF9MSU1JVFMoY29tYmluZWRfc2FtcGxlcnMpKSB7CiAgICAgICAgICAgICAgICBUUkFDRSgiTG9hZGluZyAlcyBmb3IgdGV4dHVyZSAlZFxuIiwgc2FtcGxlcl9uYW1lLCBtYXBwZWRfdW5pdCk7CiAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsVW5pZm9ybTFpQVJCKG5hbWVfbG9jLCBtYXBwZWRfdW5pdCkpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsVW5pZm9ybTFpQVJCIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBFUlIoIlRyeWluZyB0byBsb2FkIHNhbXBsZXIgJXMgb24gdW5zdXBwb3J0ZWQgdW5pdCAlZFxuIiwgc2FtcGxlcl9uYW1lLCBtYXBwZWRfdW5pdCk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCi8qKiAKICogTG9hZHMgZmxvYXRpbmcgcG9pbnQgY29uc3RhbnRzIChha2EgdW5pZm9ybXMpIGludG8gdGhlIGN1cnJlbnRseSBzZXQgR0xTTCBwcm9ncmFtLgogKiBXaGVuIGNvbnN0YW50X2xpc3QgPT0gTlVMTCwgaXQgd2lsbCBsb2FkIGFsbCB0aGUgY29uc3RhbnRzLgogKi8Kc3RhdGljIHZvaWQgc2hhZGVyX2dsc2xfbG9hZF9jb25zdGFudHNGKElXaW5lRDNEQmFzZVNoYWRlckltcGwqIFRoaXMsIFdpbmVEM0RfR0xfSW5mbyAqZ2xfaW5mbywKICAgICAgICB1bnNpZ25lZCBpbnQgbWF4X2NvbnN0YW50cywgZmxvYXQqIGNvbnN0YW50cywgR0xoYW5kbGVBUkIgKmNvbnN0YW50X2xvY2F0aW9ucywKICAgICAgICBzdHJ1Y3QgbGlzdCAqY29uc3RhbnRfbGlzdCkgewogICAgY29uc3RhbnRzX2VudHJ5ICpjb25zdGFudDsKICAgIGxvY2FsX2NvbnN0YW50KiBsY29uc3Q7CiAgICBHTGhhbmRsZUFSQiB0bXBfbG9jOwogICAgRFdPUkQgaSwgaiwgazsKICAgIERXT1JEICppZHg7CgogICAgaWYgKFRSQUNFX09OKGQzZF9zaGFkZXIpKSB7CiAgICAgICAgTElTVF9GT1JfRUFDSF9FTlRSWShjb25zdGFudCwgY29uc3RhbnRfbGlzdCwgY29uc3RhbnRzX2VudHJ5LCBlbnRyeSkgewogICAgICAgICAgICBpZHggPSBjb25zdGFudC0+aWR4OwogICAgICAgICAgICBqID0gY29uc3RhbnQtPmNvdW50OwogICAgICAgICAgICB3aGlsZSAoai0tKSB7CiAgICAgICAgICAgICAgICBpID0gKmlkeCsrOwogICAgICAgICAgICAgICAgdG1wX2xvYyA9IGNvbnN0YW50X2xvY2F0aW9uc1tpXTsKICAgICAgICAgICAgICAgIGlmICh0bXBfbG9jICE9IC0xKSB7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0VfKGQzZF9jb25zdGFudHMpKCJMb2FkaW5nIGNvbnN0YW50cyAlaTogJWYsICVmLCAlZiwgJWZcbiIsIGksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdGFudHNbaSAqIDQgKyAwXSwgY29uc3RhbnRzW2kgKiA0ICsgMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdGFudHNbaSAqIDQgKyAyXSwgY29uc3RhbnRzW2kgKiA0ICsgM10pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qIDEuWCBwc2hhZGVycyBoYXZlIHRoZSBjb25zdGFudHMgY2xhbXBlZCB0byBbLTE7MV0gaW1wbGljaXRseS4gKi8KICAgIGlmKFdJTkVEM0RTSEFERVJfVkVSU0lPTl9NQUpPUihUaGlzLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uKSA9PSAxICYmCiAgICAgICBzaGFkZXJfaXNfcHNoYWRlcl92ZXJzaW9uKFRoaXMtPmJhc2VTaGFkZXIuaGV4X3ZlcnNpb24pKSB7CiAgICAgICAgZmxvYXQgbGNsX2NvbnN0WzRdOwoKICAgICAgICBMSVNUX0ZPUl9FQUNIX0VOVFJZKGNvbnN0YW50LCBjb25zdGFudF9saXN0LCBjb25zdGFudHNfZW50cnksIGVudHJ5KSB7CiAgICAgICAgICAgIGlkeCA9IGNvbnN0YW50LT5pZHg7CiAgICAgICAgICAgIGogPSBjb25zdGFudC0+Y291bnQ7CiAgICAgICAgICAgIHdoaWxlIChqLS0pIHsKICAgICAgICAgICAgICAgIGkgPSAqaWR4Kys7CiAgICAgICAgICAgICAgICB0bXBfbG9jID0gY29uc3RhbnRfbG9jYXRpb25zW2ldOwogICAgICAgICAgICAgICAgaWYgKHRtcF9sb2MgIT0gLTEpIHsKICAgICAgICAgICAgICAgICAgICAvKiBXZSBmb3VuZCB0aGlzIHVuaWZvcm0gbmFtZSBpbiB0aGUgcHJvZ3JhbSAtIGdvIGFoZWFkIGFuZCBzZW5kIHRoZSBkYXRhICovCiAgICAgICAgICAgICAgICAgICAgayA9IGkgKiA0OwogICAgICAgICAgICAgICAgICAgIGlmKGNvbnN0YW50c1trICsgMF0gPCAtMS4wKSBsY2xfY29uc3RbMF0gPSAtMS4wOwogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYoY29uc3RhbnRzW2sgKyAwXSA+IDEuMCkgbGNsX2NvbnN0WzBdID0gMS4wOwogICAgICAgICAgICAgICAgICAgIGVsc2UgbGNsX2NvbnN0WzBdID0gY29uc3RhbnRzW2sgKyAwXTsKICAgICAgICAgICAgICAgICAgICBpZihjb25zdGFudHNbayArIDFdIDwgLTEuMCkgbGNsX2NvbnN0WzFdID0gLTEuMDsKICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKGNvbnN0YW50c1trICsgMV0gPiAxLjApIGxjbF9jb25zdFsxXSA9IDEuMDsKICAgICAgICAgICAgICAgICAgICBlbHNlIGxjbF9jb25zdFsxXSA9IGNvbnN0YW50c1trICsgMV07CiAgICAgICAgICAgICAgICAgICAgaWYoY29uc3RhbnRzW2sgKyAyXSA8IC0xLjApIGxjbF9jb25zdFsyXSA9IC0xLjA7CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZihjb25zdGFudHNbayArIDJdID4gMS4wKSBsY2xfY29uc3RbMl0gPSAxLjA7CiAgICAgICAgICAgICAgICAgICAgZWxzZSBsY2xfY29uc3RbMl0gPSBjb25zdGFudHNbayArIDJdOwogICAgICAgICAgICAgICAgICAgIGlmKGNvbnN0YW50c1trICsgM10gPCAtMS4wKSBsY2xfY29uc3RbM10gPSAtMS4wOwogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYoY29uc3RhbnRzW2sgKyAzXSA+IDEuMCkgbGNsX2NvbnN0WzNdID0gMS4wOwogICAgICAgICAgICAgICAgICAgIGVsc2UgbGNsX2NvbnN0WzNdID0gY29uc3RhbnRzW2sgKyAzXTsKCiAgICAgICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFVuaWZvcm00ZnZBUkIodG1wX2xvYywgMSwgbGNsX2NvbnN0KSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkoY29uc3RhbnQsIGNvbnN0YW50X2xpc3QsIGNvbnN0YW50c19lbnRyeSwgZW50cnkpIHsKICAgICAgICAgICAgaWR4ID0gY29uc3RhbnQtPmlkeDsKICAgICAgICAgICAgaiA9IGNvbnN0YW50LT5jb3VudDsKICAgICAgICAgICAgd2hpbGUgKGotLSkgewogICAgICAgICAgICAgICAgaSA9ICppZHgrKzsKICAgICAgICAgICAgICAgIHRtcF9sb2MgPSBjb25zdGFudF9sb2NhdGlvbnNbaV07CiAgICAgICAgICAgICAgICBpZiAodG1wX2xvYyAhPSAtMSkgewogICAgICAgICAgICAgICAgICAgIC8qIFdlIGZvdW5kIHRoaXMgdW5pZm9ybSBuYW1lIGluIHRoZSBwcm9ncmFtIC0gZ28gYWhlYWQgYW5kIHNlbmQgdGhlIGRhdGEgKi8KICAgICAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsVW5pZm9ybTRmdkFSQih0bXBfbG9jLCAxLCBjb25zdGFudHMgKyAoaSAqIDQpKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBjaGVja0dMY2FsbCgiZ2xVbmlmb3JtNGZ2QVJCKCkiKTsKCiAgICBpZighVGhpcy0+YmFzZVNoYWRlci5sb2FkX2xvY2FsX2NvbnN0c0YpIHsKICAgICAgICBUUkFDRSgiTm8gbmVlZCB0byBsb2FkIGxvY2FsIGZsb2F0IGNvbnN0YW50cyBmb3IgdGhpcyBzaGFkZXJcbiIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvKiBMb2FkIGltbWVkaWF0ZSBjb25zdGFudHMgKi8KICAgIGlmIChUUkFDRV9PTihkM2Rfc2hhZGVyKSkgewogICAgICAgIExJU1RfRk9SX0VBQ0hfRU5UUlkobGNvbnN0LCAmVGhpcy0+YmFzZVNoYWRlci5jb25zdGFudHNGLCBsb2NhbF9jb25zdGFudCwgZW50cnkpIHsKICAgICAgICAgICAgdG1wX2xvYyA9IGNvbnN0YW50X2xvY2F0aW9uc1tsY29uc3QtPmlkeF07CiAgICAgICAgICAgIGlmICh0bXBfbG9jICE9IC0xKSB7CiAgICAgICAgICAgICAgICBHTGZsb2F0KiB2YWx1ZXMgPSAoR0xmbG9hdCopbGNvbnN0LT52YWx1ZTsKICAgICAgICAgICAgICAgIFRSQUNFXyhkM2RfY29uc3RhbnRzKSgiTG9hZGluZyBsb2NhbCBjb25zdGFudHMgJWk6ICVmLCAlZiwgJWYsICVmXG4iLCBsY29uc3QtPmlkeCwKICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzWzBdLCB2YWx1ZXNbMV0sIHZhbHVlc1syXSwgdmFsdWVzWzNdKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIC8qIEltbWVkaWF0ZSBjb25zdGFudHMgYXJlIGNsYW1wZWQgdG8gWy0xOzFdIGF0IHNoYWRlciBjcmVhdGlvbiB0aW1lIGlmIG5lZWRlZCAqLwogICAgTElTVF9GT1JfRUFDSF9FTlRSWShsY29uc3QsICZUaGlzLT5iYXNlU2hhZGVyLmNvbnN0YW50c0YsIGxvY2FsX2NvbnN0YW50LCBlbnRyeSkgewogICAgICAgIHRtcF9sb2MgPSBjb25zdGFudF9sb2NhdGlvbnNbbGNvbnN0LT5pZHhdOwogICAgICAgIGlmICh0bXBfbG9jICE9IC0xKSB7CiAgICAgICAgICAgIC8qIFdlIGZvdW5kIHRoaXMgdW5pZm9ybSBuYW1lIGluIHRoZSBwcm9ncmFtIC0gZ28gYWhlYWQgYW5kIHNlbmQgdGhlIGRhdGEgKi8KICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFVuaWZvcm00ZnZBUkIodG1wX2xvYywgMSwgKEdMZmxvYXQqKWxjb25zdC0+dmFsdWUpKTsKICAgICAgICB9CiAgICB9CiAgICBjaGVja0dMY2FsbCgiZ2xVbmlmb3JtNGZ2QVJCKCkiKTsKfQoKLyoqIAogKiBMb2FkcyBpbnRlZ2VyIGNvbnN0YW50cyAoYWthIHVuaWZvcm1zKSBpbnRvIHRoZSBjdXJyZW50bHkgc2V0IEdMU0wgcHJvZ3JhbS4KICogV2hlbiBAY29uc3RhbnRzX3NldCA9PSBOVUxMLCBpdCB3aWxsIGxvYWQgYWxsIHRoZSBjb25zdGFudHMuCiAqLwpzdGF0aWMgdm9pZCBzaGFkZXJfZ2xzbF9sb2FkX2NvbnN0YW50c0koCiAgICBJV2luZUQzREJhc2VTaGFkZXJJbXBsKiBUaGlzLAogICAgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvLAogICAgR0xoYW5kbGVBUkIgcHJvZ3JhbUlkLAogICAgR0xoYW5kbGVBUkIgbG9jYXRpb25zW01BWF9DT05TVF9JXSwKICAgIHVuc2lnbmVkIG1heF9jb25zdGFudHMsCiAgICBpbnQqIGNvbnN0YW50cywKICAgIEJPT0wqIGNvbnN0YW50c19zZXQpIHsKICAgIAogICAgaW50IGk7CiAgICBzdHJ1Y3QgbGlzdCogcHRyOwoKICAgIGZvciAoaT0wOyBpPG1heF9jb25zdGFudHM7ICsraSkgewogICAgICAgIGlmIChOVUxMID09IGNvbnN0YW50c19zZXQgfHwgY29uc3RhbnRzX3NldFtpXSkgewoKICAgICAgICAgICAgVFJBQ0VfKGQzZF9jb25zdGFudHMpKCJMb2FkaW5nIGNvbnN0YW50cyAlaTogJWksICVpLCAlaSwgJWlcbiIsCiAgICAgICAgICAgICAgICAgIGksIGNvbnN0YW50c1tpKjRdLCBjb25zdGFudHNbaSo0KzFdLCBjb25zdGFudHNbaSo0KzJdLCBjb25zdGFudHNbaSo0KzNdKTsKCiAgICAgICAgICAgIC8qIFdlIGZvdW5kIHRoaXMgdW5pZm9ybSBuYW1lIGluIHRoZSBwcm9ncmFtIC0gZ28gYWhlYWQgYW5kIHNlbmQgdGhlIGRhdGEgKi8KICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFVuaWZvcm00aXZBUkIobG9jYXRpb25zW2ldLCAxLCAmY29uc3RhbnRzW2kqNF0pKTsKICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsVW5pZm9ybTRpdkFSQiIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBMb2FkIGltbWVkaWF0ZSBjb25zdGFudHMgKi8KICAgIHB0ciA9IGxpc3RfaGVhZCgmVGhpcy0+YmFzZVNoYWRlci5jb25zdGFudHNJKTsKICAgIHdoaWxlIChwdHIpIHsKICAgICAgICBsb2NhbF9jb25zdGFudCogbGNvbnN0ID0gTElTVF9FTlRSWShwdHIsIHN0cnVjdCBsb2NhbF9jb25zdGFudCwgZW50cnkpOwogICAgICAgIHVuc2lnbmVkIGludCBpZHggPSBsY29uc3QtPmlkeDsKICAgICAgICBHTGludCogdmFsdWVzID0gKEdMaW50KikgbGNvbnN0LT52YWx1ZTsKCiAgICAgICAgVFJBQ0VfKGQzZF9jb25zdGFudHMpKCJMb2FkaW5nIGxvY2FsIGNvbnN0YW50cyAlaTogJWksICVpLCAlaSwgJWlcbiIsIGlkeCwKICAgICAgICAgICAgdmFsdWVzWzBdLCB2YWx1ZXNbMV0sIHZhbHVlc1syXSwgdmFsdWVzWzNdKTsKCiAgICAgICAgLyogV2UgZm91bmQgdGhpcyB1bmlmb3JtIG5hbWUgaW4gdGhlIHByb2dyYW0gLSBnbyBhaGVhZCBhbmQgc2VuZCB0aGUgZGF0YSAqLwogICAgICAgIEdMX0VYVENBTEwoZ2xVbmlmb3JtNGl2QVJCKGxvY2F0aW9uc1tpZHhdLCAxLCB2YWx1ZXMpKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xVbmlmb3JtNGl2QVJCIik7CiAgICAgICAgcHRyID0gbGlzdF9uZXh0KCZUaGlzLT5iYXNlU2hhZGVyLmNvbnN0YW50c0ksIHB0cik7CiAgICB9Cn0KCi8qKiAKICogTG9hZHMgYm9vbGVhbiBjb25zdGFudHMgKGFrYSB1bmlmb3JtcykgaW50byB0aGUgY3VycmVudGx5IHNldCBHTFNMIHByb2dyYW0uCiAqIFdoZW4gQGNvbnN0YW50c19zZXQgPT0gTlVMTCwgaXQgd2lsbCBsb2FkIGFsbCB0aGUgY29uc3RhbnRzLgogKi8Kc3RhdGljIHZvaWQgc2hhZGVyX2dsc2xfbG9hZF9jb25zdGFudHNCKAogICAgSVdpbmVEM0RCYXNlU2hhZGVySW1wbCogVGhpcywKICAgIFdpbmVEM0RfR0xfSW5mbyAqZ2xfaW5mbywKICAgIEdMaGFuZGxlQVJCIHByb2dyYW1JZCwKICAgIHVuc2lnbmVkIG1heF9jb25zdGFudHMsCiAgICBCT09MKiBjb25zdGFudHMsCiAgICBCT09MKiBjb25zdGFudHNfc2V0KSB7CiAgICAKICAgIEdMaGFuZGxlQVJCIHRtcF9sb2M7CiAgICBpbnQgaTsKICAgIGNoYXIgdG1wX25hbWVbOF07CiAgICBjaGFyIGlzX3BzaGFkZXIgPSBzaGFkZXJfaXNfcHNoYWRlcl92ZXJzaW9uKFRoaXMtPmJhc2VTaGFkZXIuaGV4X3ZlcnNpb24pOwogICAgY29uc3QgY2hhciogcHJlZml4ID0gaXNfcHNoYWRlcj8gIlBCIjoiVkIiOwogICAgc3RydWN0IGxpc3QqIHB0cjsKCiAgICBmb3IgKGk9MDsgaTxtYXhfY29uc3RhbnRzOyArK2kpIHsKICAgICAgICBpZiAoTlVMTCA9PSBjb25zdGFudHNfc2V0IHx8IGNvbnN0YW50c19zZXRbaV0pIHsKCiAgICAgICAgICAgIFRSQUNFXyhkM2RfY29uc3RhbnRzKSgiTG9hZGluZyBjb25zdGFudHMgJWk6ICVpO1xuIiwgaSwgY29uc3RhbnRzW2ldKTsKCiAgICAgICAgICAgIC8qIFRPRE86IEJlbmNobWFyayBhbmQgc2VlIGlmIGl0IHdvdWxkIGJlIGJlbmVmaWNpYWwgdG8gc3RvcmUgdGhlIAogICAgICAgICAgICAgKiBsb2NhdGlvbnMgb2YgdGhlIGNvbnN0YW50cyB0byBhdm9pZCBsb29raW5nIHVwIGVhY2ggdGltZSAqLwogICAgICAgICAgICBzbnByaW50Zih0bXBfbmFtZSwgc2l6ZW9mKHRtcF9uYW1lKSwgIiVzWyVpXSIsIHByZWZpeCwgaSk7CiAgICAgICAgICAgIHRtcF9sb2MgPSBHTF9FWFRDQUxMKGdsR2V0VW5pZm9ybUxvY2F0aW9uQVJCKHByb2dyYW1JZCwgdG1wX25hbWUpKTsKICAgICAgICAgICAgaWYgKHRtcF9sb2MgIT0gLTEpIHsKICAgICAgICAgICAgICAgIC8qIFdlIGZvdW5kIHRoaXMgdW5pZm9ybSBuYW1lIGluIHRoZSBwcm9ncmFtIC0gZ28gYWhlYWQgYW5kIHNlbmQgdGhlIGRhdGEgKi8KICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xVbmlmb3JtMWl2QVJCKHRtcF9sb2MsIDEsICZjb25zdGFudHNbaV0pKTsKICAgICAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFVuaWZvcm0xaXZBUkIiKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKiBMb2FkIGltbWVkaWF0ZSBjb25zdGFudHMgKi8KICAgIHB0ciA9IGxpc3RfaGVhZCgmVGhpcy0+YmFzZVNoYWRlci5jb25zdGFudHNCKTsKICAgIHdoaWxlIChwdHIpIHsKICAgICAgICBsb2NhbF9jb25zdGFudCogbGNvbnN0ID0gTElTVF9FTlRSWShwdHIsIHN0cnVjdCBsb2NhbF9jb25zdGFudCwgZW50cnkpOwogICAgICAgIHVuc2lnbmVkIGludCBpZHggPSBsY29uc3QtPmlkeDsKICAgICAgICBHTGludCogdmFsdWVzID0gKEdMaW50KikgbGNvbnN0LT52YWx1ZTsKCiAgICAgICAgVFJBQ0VfKGQzZF9jb25zdGFudHMpKCJMb2FkaW5nIGxvY2FsIGNvbnN0YW50cyAlaTogJWlcbiIsIGlkeCwgdmFsdWVzWzBdKTsKCiAgICAgICAgc25wcmludGYodG1wX25hbWUsIHNpemVvZih0bXBfbmFtZSksICIlc1slaV0iLCBwcmVmaXgsIGlkeCk7CiAgICAgICAgdG1wX2xvYyA9IEdMX0VYVENBTEwoZ2xHZXRVbmlmb3JtTG9jYXRpb25BUkIocHJvZ3JhbUlkLCB0bXBfbmFtZSkpOwogICAgICAgIGlmICh0bXBfbG9jICE9IC0xKSB7CiAgICAgICAgICAgIC8qIFdlIGZvdW5kIHRoaXMgdW5pZm9ybSBuYW1lIGluIHRoZSBwcm9ncmFtIC0gZ28gYWhlYWQgYW5kIHNlbmQgdGhlIGRhdGEgKi8KICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFVuaWZvcm0xaXZBUkIodG1wX2xvYywgMSwgdmFsdWVzKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFVuaWZvcm0xaXZBUkIiKTsKICAgICAgICB9CiAgICAgICAgcHRyID0gbGlzdF9uZXh0KCZUaGlzLT5iYXNlU2hhZGVyLmNvbnN0YW50c0IsIHB0cik7CiAgICB9Cn0KCgoKLyoqCiAqIExvYWRzIHRoZSBhcHAtc3VwcGxpZWQgY29uc3RhbnRzIGludG8gdGhlIGN1cnJlbnRseSBzZXQgR0xTTCBwcm9ncmFtLgogKi8Kdm9pZCBzaGFkZXJfZ2xzbF9sb2FkX2NvbnN0YW50cygKICAgIElXaW5lRDNERGV2aWNlKiBkZXZpY2UsCiAgICBjaGFyIHVzZVBpeGVsU2hhZGVyLAogICAgY2hhciB1c2VWZXJ0ZXhTaGFkZXIpIHsKICAgCiAgICBJV2luZUQzRERldmljZUltcGwqIGRldmljZUltcGwgPSAoSVdpbmVEM0REZXZpY2VJbXBsKikgZGV2aWNlOwogICAgSVdpbmVEM0RTdGF0ZUJsb2NrSW1wbCogc3RhdGVCbG9jayA9IGRldmljZUltcGwtPnN0YXRlQmxvY2s7CiAgICBXaW5lRDNEX0dMX0luZm8gKmdsX2luZm8gPSAmZGV2aWNlSW1wbC0+YWRhcHRlci0+Z2xfaW5mbzsKCiAgICBHTGhhbmRsZUFSQiAqY29uc3RhbnRfbG9jYXRpb25zOwogICAgc3RydWN0IGxpc3QgKmNvbnN0YW50X2xpc3Q7CiAgICBHTGhhbmRsZUFSQiBwcm9ncmFtSWQ7CiAgICBzdHJ1Y3QgZ2xzbF9zaGFkZXJfcHJvZ19saW5rICpwcm9nID0gc3RhdGVCbG9jay0+Z2xzbF9wcm9ncmFtOwogICAgdW5zaWduZWQgaW50IGk7CgogICAgaWYgKCFwcm9nKSB7CiAgICAgICAgLyogTm8gR0xTTCBwcm9ncmFtIHNldCAtIG5vdGhpbmcgdG8gZG8uICovCiAgICAgICAgcmV0dXJuOwogICAgfQogICAgcHJvZ3JhbUlkID0gcHJvZy0+cHJvZ3JhbUlkOwoKICAgIGlmICh1c2VWZXJ0ZXhTaGFkZXIpIHsKICAgICAgICBJV2luZUQzREJhc2VTaGFkZXJJbXBsKiB2c2hhZGVyID0gKElXaW5lRDNEQmFzZVNoYWRlckltcGwqKSBzdGF0ZUJsb2NrLT52ZXJ0ZXhTaGFkZXI7CgogICAgICAgIGNvbnN0YW50X2xvY2F0aW9ucyA9IHByb2ctPnZ1bmlmb3JtRl9sb2NhdGlvbnM7CiAgICAgICAgY29uc3RhbnRfbGlzdCA9ICZzdGF0ZUJsb2NrLT5zZXRfdmNvbnN0YW50c0Y7CgogICAgICAgIC8qIExvYWQgRGlyZWN0WCA5IGZsb2F0IGNvbnN0YW50cy91bmlmb3JtcyBmb3IgdmVydGV4IHNoYWRlciAqLwogICAgICAgIHNoYWRlcl9nbHNsX2xvYWRfY29uc3RhbnRzRih2c2hhZGVyLCBnbF9pbmZvLCBHTF9MSU1JVFModnNoYWRlcl9jb25zdGFudHNGKSwKICAgICAgICAgICAgICAgIHN0YXRlQmxvY2stPnZlcnRleFNoYWRlckNvbnN0YW50RiwgY29uc3RhbnRfbG9jYXRpb25zLCBjb25zdGFudF9saXN0KTsKCiAgICAgICAgLyogTG9hZCBEaXJlY3RYIDkgaW50ZWdlciBjb25zdGFudHMvdW5pZm9ybXMgZm9yIHZlcnRleCBzaGFkZXIgKi8KICAgICAgICBzaGFkZXJfZ2xzbF9sb2FkX2NvbnN0YW50c0kodnNoYWRlciwgZ2xfaW5mbywgcHJvZ3JhbUlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9nLT52dW5pZm9ybUlfbG9jYXRpb25zLCBNQVhfQ09OU1RfSSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGVCbG9jay0+dmVydGV4U2hhZGVyQ29uc3RhbnRJLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZUJsb2NrLT5jaGFuZ2VkLnZlcnRleFNoYWRlckNvbnN0YW50c0kpOwoKICAgICAgICAvKiBMb2FkIERpcmVjdFggOSBib29sZWFuIGNvbnN0YW50cy91bmlmb3JtcyBmb3IgdmVydGV4IHNoYWRlciAqLwogICAgICAgIHNoYWRlcl9nbHNsX2xvYWRfY29uc3RhbnRzQih2c2hhZGVyLCBnbF9pbmZvLCBwcm9ncmFtSWQsIE1BWF9DT05TVF9CLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZUJsb2NrLT52ZXJ0ZXhTaGFkZXJDb25zdGFudEIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlQmxvY2stPmNoYW5nZWQudmVydGV4U2hhZGVyQ29uc3RhbnRzQik7CgogICAgICAgIC8qIFVwbG9hZCB0aGUgcG9zaXRpb24gZml4dXAgcGFyYW1zICovCiAgICAgICAgR0xfRVhUQ0FMTChnbFVuaWZvcm00ZnZBUkIocHJvZy0+cG9zRml4dXBfbG9jYXRpb24sIDEsICZkZXZpY2VJbXBsLT5wb3NGaXh1cFswXSkpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbFVuaWZvcm00ZnZBUkIiKTsKICAgIH0KCiAgICBpZiAodXNlUGl4ZWxTaGFkZXIpIHsKCiAgICAgICAgSVdpbmVEM0RCYXNlU2hhZGVySW1wbCogcHNoYWRlciA9IChJV2luZUQzREJhc2VTaGFkZXJJbXBsKikgc3RhdGVCbG9jay0+cGl4ZWxTaGFkZXI7CgogICAgICAgIGNvbnN0YW50X2xvY2F0aW9ucyA9IHByb2ctPnB1bmlmb3JtRl9sb2NhdGlvbnM7CiAgICAgICAgY29uc3RhbnRfbGlzdCA9ICZzdGF0ZUJsb2NrLT5zZXRfcGNvbnN0YW50c0Y7CgogICAgICAgIC8qIExvYWQgRGlyZWN0WCA5IGZsb2F0IGNvbnN0YW50cy91bmlmb3JtcyBmb3IgcGl4ZWwgc2hhZGVyICovCiAgICAgICAgc2hhZGVyX2dsc2xfbG9hZF9jb25zdGFudHNGKHBzaGFkZXIsIGdsX2luZm8sIEdMX0xJTUlUUyhwc2hhZGVyX2NvbnN0YW50c0YpLAogICAgICAgICAgICAgICAgc3RhdGVCbG9jay0+cGl4ZWxTaGFkZXJDb25zdGFudEYsIGNvbnN0YW50X2xvY2F0aW9ucywgY29uc3RhbnRfbGlzdCk7CgogICAgICAgIC8qIExvYWQgRGlyZWN0WCA5IGludGVnZXIgY29uc3RhbnRzL3VuaWZvcm1zIGZvciBwaXhlbCBzaGFkZXIgKi8KICAgICAgICBzaGFkZXJfZ2xzbF9sb2FkX2NvbnN0YW50c0kocHNoYWRlciwgZ2xfaW5mbywgcHJvZ3JhbUlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9nLT5wdW5pZm9ybUlfbG9jYXRpb25zLCBNQVhfQ09OU1RfSSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGVCbG9jay0+cGl4ZWxTaGFkZXJDb25zdGFudEksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZUJsb2NrLT5jaGFuZ2VkLnBpeGVsU2hhZGVyQ29uc3RhbnRzSSk7CgogICAgICAgIC8qIExvYWQgRGlyZWN0WCA5IGJvb2xlYW4gY29uc3RhbnRzL3VuaWZvcm1zIGZvciBwaXhlbCBzaGFkZXIgKi8KICAgICAgICBzaGFkZXJfZ2xzbF9sb2FkX2NvbnN0YW50c0IocHNoYWRlciwgZ2xfaW5mbywgcHJvZ3JhbUlkLCBNQVhfQ09OU1RfQiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGVCbG9jay0+cGl4ZWxTaGFkZXJDb25zdGFudEIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZUJsb2NrLT5jaGFuZ2VkLnBpeGVsU2hhZGVyQ29uc3RhbnRzQik7CgogICAgICAgIC8qIFVwbG9hZCB0aGUgZW52aXJvbm1lbnQgYnVtcCBtYXAgbWF0cml4IGlmIG5lZWRlZC4gVGhlIG5lZWRzYnVtcG1hdCBtZW1iZXIgc3BlY2lmaWVzIHRoZSB0ZXh0dXJlIHN0YWdlIHRvIGxvYWQgdGhlIG1hdHJpeCBmcm9tLgogICAgICAgICAqIEl0IGNhbid0IGJlIDAgZm9yIGEgdmFsaWQgdGV4YmVtIGluc3RydWN0aW9uLgogICAgICAgICAqLwogICAgICAgIGZvcihpID0gMDsgaSA8ICgoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwgKikgcHNoYWRlciktPm51bWJ1bXBlbnZtYXRjb25zdHM7IGkrKykgewogICAgICAgICAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqcHMgPSAoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwgKikgcHNoYWRlcjsKICAgICAgICAgICAgaW50IHN0YWdlID0gcHMtPmx1bWluYW5jZWNvbnN0W2ldLnRleHVuaXQ7CgogICAgICAgICAgICBmbG9hdCAqZGF0YSA9IChmbG9hdCAqKSAmc3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlWyhpbnQpIHBzLT5idW1wZW52bWF0Y29uc3RbaV0udGV4dW5pdF1bV0lORUQzRFRTU19CVU1QRU5WTUFUMDBdOwogICAgICAgICAgICBHTF9FWFRDQUxMKGdsVW5pZm9ybU1hdHJpeDJmdkFSQihwcm9nLT5idW1wZW52bWF0X2xvY2F0aW9uW2ldLCAxLCAwLCBkYXRhKSk7CiAgICAgICAgICAgIGNoZWNrR0xjYWxsKCJnbFVuaWZvcm1NYXRyaXgyZnZBUkIiKTsKCiAgICAgICAgICAgIC8qIHRleGJlbWwgbmVlZHMgdGhlIGx1bWluYW5jZSBzY2FsZSBhbmQgb2Zmc2V0IHRvby4gSWYgdGV4YmVtbCBpcyB1c2VkLCBuZWVkc2J1bXBtYXQKICAgICAgICAgICAgICogaXMgc2V0IHRvbywgc28gd2UgY2FuIGNoZWNrIHRoYXQgaW4gdGhlIG5lZWRzYnVtcG1hdCBjaGVjawogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYocHMtPmJhc2VTaGFkZXIucmVnX21hcHMubHVtaW5hbmNlcGFyYW1zW3N0YWdlXSkgewogICAgICAgICAgICAgICAgR0xmbG9hdCAqc2NhbGUgPSAoR0xmbG9hdCAqKSAmc3RhdGVCbG9jay0+dGV4dHVyZVN0YXRlW3N0YWdlXVtXSU5FRDNEVFNTX0JVTVBFTlZMU0NBTEVdOwogICAgICAgICAgICAgICAgR0xmbG9hdCAqb2Zmc2V0ID0gKEdMZmxvYXQgKikgJnN0YXRlQmxvY2stPnRleHR1cmVTdGF0ZVtzdGFnZV1bV0lORUQzRFRTU19CVU1QRU5WTE9GRlNFVF07CgogICAgICAgICAgICAgICAgR0xfRVhUQ0FMTChnbFVuaWZvcm0xZnZBUkIocHJvZy0+bHVtaW5hbmNlc2NhbGVfbG9jYXRpb25baV0sIDEsIHNjYWxlKSk7CiAgICAgICAgICAgICAgICBjaGVja0dMY2FsbCgiZ2xVbmlmb3JtMWZ2QVJCIik7CiAgICAgICAgICAgICAgICBHTF9FWFRDQUxMKGdsVW5pZm9ybTFmdkFSQihwcm9nLT5sdW1pbmFuY2VvZmZzZXRfbG9jYXRpb25baV0sIDEsIG9mZnNldCkpOwogICAgICAgICAgICAgICAgY2hlY2tHTGNhbGwoImdsVW5pZm9ybTFmdkFSQiIpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZigoKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICopIHBzaGFkZXIpLT5zcmdiX2VuYWJsZWQgJiYKICAgICAgICAgICAgICAgICAgISgoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwgKikgcHNoYWRlciktPnNyZ2JfbW9kZV9oYXJkY29kZWQpIHsKICAgICAgICAgICAgZmxvYXQgY29tcGFyaXNvbls0XTsKICAgICAgICAgICAgZmxvYXQgbXVsX2xvd1s0XTsKCiAgICAgICAgICAgIGlmKHN0YXRlQmxvY2stPnJlbmRlclN0YXRlW1dJTkVEM0RSU19TUkdCV1JJVEVFTkFCTEVdKSB7CiAgICAgICAgICAgICAgICBjb21wYXJpc29uWzBdID0gc3JnYl9jbXA7IGNvbXBhcmlzb25bMV0gPSBzcmdiX2NtcDsKICAgICAgICAgICAgICAgIGNvbXBhcmlzb25bMl0gPSBzcmdiX2NtcDsgY29tcGFyaXNvblszXSA9IHNyZ2JfY21wOwoKICAgICAgICAgICAgICAgIG11bF9sb3dbMF0gPSBzcmdiX211bF9sb3c7IG11bF9sb3dbMV0gPSBzcmdiX211bF9sb3c7CiAgICAgICAgICAgICAgICBtdWxfbG93WzJdID0gc3JnYl9tdWxfbG93OyBtdWxfbG93WzNdID0gc3JnYl9tdWxfbG93OwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgY29tcGFyaXNvblswXSA9IDEuMCAvIDAuMDsgY29tcGFyaXNvblsxXSA9IDEuMCAvIDAuMDsKICAgICAgICAgICAgICAgIGNvbXBhcmlzb25bMl0gPSAxLjAgLyAwLjA7IGNvbXBhcmlzb25bM10gPSAxLjAgLyAwLjA7CgogICAgICAgICAgICAgICAgbXVsX2xvd1swXSA9IDEuMDsgbXVsX2xvd1sxXSA9IDEuMDsKICAgICAgICAgICAgICAgIG11bF9sb3dbMl0gPSAxLjA7IG11bF9sb3dbM10gPSAxLjA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xVbmlmb3JtNGZ2QVJCKHByb2ctPnNyZ2JfY29tcGFyaXNvbl9sb2NhdGlvbiwgMSwgY29tcGFyaXNvbikpOwogICAgICAgICAgICBHTF9FWFRDQUxMKGdsVW5pZm9ybTRmdkFSQihwcm9nLT5zcmdiX211bF9sb3dfbG9jYXRpb24sIDEsIG11bF9sb3cpKTsKICAgICAgICB9CiAgICAgICAgaWYoKChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqKSBwc2hhZGVyKS0+dnBvc191bmlmb3JtKSB7CiAgICAgICAgICAgIGZsb2F0IGNvcnJlY3Rpb25fcGFyYW1zWzRdOwogICAgICAgICAgICBpZihkZXZpY2VJbXBsLT5yZW5kZXJfb2Zmc2NyZWVuKSB7CiAgICAgICAgICAgICAgICBjb3JyZWN0aW9uX3BhcmFtc1swXSA9IDAuMDsKICAgICAgICAgICAgICAgIGNvcnJlY3Rpb25fcGFyYW1zWzFdID0gMS4wOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLyogcG9zaXRpb24gaXMgd2luZG93IHJlbGF0aXZlLCBub3Qgdmlld3BvcnQgcmVsYXRpdmUgKi8KICAgICAgICAgICAgICAgIGNvcnJlY3Rpb25fcGFyYW1zWzBdID0gKChJV2luZUQzRFN1cmZhY2VJbXBsICopIGRldmljZUltcGwtPnJlbmRlcl90YXJnZXRzWzBdKS0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgICAgICAgICAgICAgY29ycmVjdGlvbl9wYXJhbXNbMV0gPSAtMS4wOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xVbmlmb3JtNGZ2QVJCKHByb2ctPnljb3JyZWN0aW9uX2xvY2F0aW9uLCAxLCBjb3JyZWN0aW9uX3BhcmFtcykpOwogICAgICAgIH0KICAgIH0KfQoKLyoqIEdlbmVyYXRlIHRoZSB2YXJpYWJsZSAmIHJlZ2lzdGVyIGRlY2xhcmF0aW9ucyBmb3IgdGhlIEdMU0wgb3V0cHV0IHRhcmdldCAqLwp2b2lkIHNoYWRlcl9nZW5lcmF0ZV9nbHNsX2RlY2xhcmF0aW9ucygKICAgIElXaW5lRDNEQmFzZVNoYWRlciAqaWZhY2UsCiAgICBzaGFkZXJfcmVnX21hcHMqIHJlZ19tYXBzLAogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyLAogICAgV2luZUQzRF9HTF9JbmZvKiBnbF9pbmZvKSB7CgogICAgSVdpbmVEM0RCYXNlU2hhZGVySW1wbCogVGhpcyA9IChJV2luZUQzREJhc2VTaGFkZXJJbXBsKikgaWZhY2U7CiAgICBJV2luZUQzRERldmljZUltcGwgKmRldmljZSA9IChJV2luZUQzRERldmljZUltcGwgKikgVGhpcy0+YmFzZVNoYWRlci5kZXZpY2U7CiAgICBpbnQgaTsKICAgIHVuc2lnbmVkIGludCBleHRyYV9jb25zdGFudHNfbmVlZGVkID0gMDsKICAgIGxvY2FsX2NvbnN0YW50KiBsY29uc3Q7CgogICAgLyogVGhlcmUgYXJlIHNvbWUgbWlub3IgZGlmZmVyZW5jZXMgYmV0d2VlbiBwaXhlbCBhbmQgdmVydGV4IHNoYWRlcnMgKi8KICAgIGNoYXIgcHNoYWRlciA9IHNoYWRlcl9pc19wc2hhZGVyX3ZlcnNpb24oVGhpcy0+YmFzZVNoYWRlci5oZXhfdmVyc2lvbik7CiAgICBjaGFyIHByZWZpeCA9IHBzaGFkZXIgPyAnUCcgOiAnVic7CgogICAgLyogUHJvdG90eXBlIHRoZSBzdWJyb3V0aW5lcyAqLwogICAgZm9yIChpID0gMDsgaSA8IFRoaXMtPmJhc2VTaGFkZXIubGltaXRzLmxhYmVsOyBpKyspIHsKICAgICAgICBpZiAocmVnX21hcHMtPmxhYmVsc1tpXSkKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidm9pZCBzdWJyb3V0aW5lJXUoKTtcbiIsIGkpOwogICAgfQoKICAgIC8qIERlY2xhcmUgdGhlIGNvbnN0YW50cyAoYWthIHVuaWZvcm1zKSAqLwogICAgaWYgKFRoaXMtPmJhc2VTaGFkZXIubGltaXRzLmNvbnN0YW50X2Zsb2F0ID4gMCkgewogICAgICAgIHVuc2lnbmVkIG1heF9jb25zdGFudHNGID0gbWluKFRoaXMtPmJhc2VTaGFkZXIubGltaXRzLmNvbnN0YW50X2Zsb2F0LCAKICAgICAgICAgICAgICAgIChwc2hhZGVyID8gR0xfTElNSVRTKHBzaGFkZXJfY29uc3RhbnRzRikgOiBHTF9MSU1JVFModnNoYWRlcl9jb25zdGFudHNGKSkpOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInVuaWZvcm0gdmVjNCAlY0NbJXVdO1xuIiwgcHJlZml4LCBtYXhfY29uc3RhbnRzRik7CiAgICB9CgogICAgaWYgKFRoaXMtPmJhc2VTaGFkZXIubGltaXRzLmNvbnN0YW50X2ludCA+IDApCiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidW5pZm9ybSBpdmVjNCAlY0lbJXVdO1xuIiwgcHJlZml4LCBUaGlzLT5iYXNlU2hhZGVyLmxpbWl0cy5jb25zdGFudF9pbnQpOwoKICAgIGlmIChUaGlzLT5iYXNlU2hhZGVyLmxpbWl0cy5jb25zdGFudF9ib29sID4gMCkKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ1bmlmb3JtIGJvb2wgJWNCWyV1XTtcbiIsIHByZWZpeCwgVGhpcy0+YmFzZVNoYWRlci5saW1pdHMuY29uc3RhbnRfYm9vbCk7CgogICAgaWYoIXBzaGFkZXIpIHsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ1bmlmb3JtIHZlYzQgcG9zRml4dXA7XG4iKTsKICAgICAgICAvKiBQcmVkZWNsYXJhdGlvbjsgVGhpcyBmdW5jdGlvbiBpcyBhZGRlZCBhdCBsaW5rIHRpbWUgYmFzZWQgb24gdGhlIHBpeGVsIHNoYWRlci4KICAgICAgICAgKiBWUyAzLjAgc2hhZGVycyBoYXZlIGFuIGFycmF5IE9VVFtdIHRoZSBzaGFkZXIgd3JpdGVzIHRvLCBlYXJsaWVyIHZlcnNpb25zIGRvbid0IGhhdmUKICAgICAgICAgKiB0aGF0LiBXZSBrbm93IHRoZSBpbnB1dCB0byB0aGUgcmVvcmRlciBmdW5jdGlvbiBhdCB2ZXJ0ZXggc2hhZGVyIGNvbXBpbGUgdGltZSwgc28KICAgICAgICAgKiB3ZSBjYW4gZGVhbCB3aXRoIHRoYXQuIFRoZSByZW9yZGVyIGZ1bmN0aW9uIGZvciBhIDEueCBhbmQgMi54IHZlcnRleCBzaGFkZXIgY2FuIGp1c3QKICAgICAgICAgKiByZWFkIGdsX0Zyb250Q29sb3IuIFRoZSBvdXRwdXQgZGVwZW5kcyBvbiB0aGUgcGl4ZWwgc2hhZGVyLiBUaGUgcmVvcmRlciBmdW5jdGlvbiBmb3IgYQogICAgICAgICAqIDEueCBhbmQgMi54IHBzaGFkZXIgb3IgZm9yIGZpeGVkIGZ1bmN0aW9uIHdpbGwgd3JpdGUgZ2xfRnJvbnRDb2xvciwgYW5kIGZvciBhIDMuMCBzaGFkZXIKICAgICAgICAgKiBpdCB3aWxsIHdyaXRlIHRvIHRoZSB2YXJ5aW5nIGFycmF5LiBIZXJlIHdlIGRlcGVuZCBvbiB0aGUgc2hhZGVyIG9wdGltaXplciBvbiBzb3J0aW5nIHRoYXQKICAgICAgICAgKiBvdXQuIFRoZSBudmlkaWEgZHJpdmVyIG9ubHkgZG9lcyB0aGF0IGlmIHRoZSBwYXJhbWV0ZXIgaXMgaW5vdXQgaW5zdGVhZCBvZiBvdXQsIGhlbmNlIHRoZQogICAgICAgICAqIGlub3V0LgogICAgICAgICAqLwogICAgICAgIGlmKFRoaXMtPmJhc2VTaGFkZXIuaGV4X3ZlcnNpb24gPj0gV0lORUQzRFZTX1ZFUlNJT04oMywgMCkpIHsKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidm9pZCBvcmRlcl9wc19pbnB1dChpbiB2ZWM0WyV1XSk7XG4iLCBNQVhfUkVHX09VVFBVVCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidm9pZCBvcmRlcl9wc19pbnB1dCgpO1xuIik7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqcHNfaW1wbCA9IChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqKSBUaGlzOwoKICAgICAgICBwc19pbXBsLT5udW1idW1wZW52bWF0Y29uc3RzID0gMDsKICAgICAgICBmb3IoaSA9IDA7IGkgPCAoc2l6ZW9mKHJlZ19tYXBzLT5idW1wbWF0KSAvIHNpemVvZihyZWdfbWFwcy0+YnVtcG1hdFswXSkpOyBpKyspIHsKICAgICAgICAgICAgaWYoIXJlZ19tYXBzLT5idW1wbWF0W2ldKSB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcHNfaW1wbC0+YnVtcGVudm1hdGNvbnN0WyhpbnQpIHBzX2ltcGwtPm51bWJ1bXBlbnZtYXRjb25zdHNdLnRleHVuaXQgPSBpOwogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ1bmlmb3JtIG1hdDIgYnVtcGVudm1hdCVkO1xuIiwgaSk7CgogICAgICAgICAgICBpZihyZWdfbWFwcy0+bHVtaW5hbmNlcGFyYW1zKSB7CiAgICAgICAgICAgICAgICBwc19pbXBsLT5sdW1pbmFuY2Vjb25zdFsoaW50KSBwc19pbXBsLT5udW1idW1wZW52bWF0Y29uc3RzXS50ZXh1bml0ID0gaTsKICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInVuaWZvcm0gZmxvYXQgbHVtaW5hbmNlc2NhbGUlZDtcbiIsIGkpOwogICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidW5pZm9ybSBmbG9hdCBsdW1pbmFuY2VvZmZzZXQlZDtcbiIsIGkpOwogICAgICAgICAgICAgICAgZXh0cmFfY29uc3RhbnRzX25lZWRlZCsrOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcHNfaW1wbC0+bHVtaW5hbmNlY29uc3RbKGludCkgcHNfaW1wbC0+bnVtYnVtcGVudm1hdGNvbnN0c10udGV4dW5pdCA9IC0xOwogICAgICAgICAgICB9CgogICAgICAgICAgICBleHRyYV9jb25zdGFudHNfbmVlZGVkKys7CiAgICAgICAgICAgIHBzX2ltcGwtPm51bWJ1bXBlbnZtYXRjb25zdHMrKzsKICAgICAgICB9CgogICAgICAgIGlmKGRldmljZS0+c3RhdGVCbG9jay0+cmVuZGVyU3RhdGVbV0lORUQzRFJTX1NSR0JXUklURUVOQUJMRV0pIHsKICAgICAgICAgICAgcHNfaW1wbC0+c3JnYl9lbmFibGVkID0gMTsKICAgICAgICAgICAgaWYoVGhpcy0+YmFzZVNoYWRlci5saW1pdHMuY29uc3RhbnRfZmxvYXQgKyBleHRyYV9jb25zdGFudHNfbmVlZGVkICsgMSA8IEdMX0xJTUlUUyhwc2hhZGVyX2NvbnN0YW50c0YpKSB7CiAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ1bmlmb3JtIHZlYzQgc3JnYl9tdWxfbG93O1xuIik7CiAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ1bmlmb3JtIHZlYzQgc3JnYl9jb21wYXJpc29uO1xuIik7CiAgICAgICAgICAgICAgICBwc19pbXBsLT5zcmdiX21vZGVfaGFyZGNvZGVkID0gMDsKICAgICAgICAgICAgICAgIGV4dHJhX2NvbnN0YW50c19uZWVkZWQrKzsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHBzX2ltcGwtPnNyZ2JfbW9kZV9oYXJkY29kZWQgPSAxOwogICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiY29uc3QgdmVjNCBzcmdiX211bF9sb3cgPSB2ZWM0KCVmLCAlZiwgJWYsICVmKTtcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcmdiX211bF9sb3csIHNyZ2JfbXVsX2xvdywgc3JnYl9tdWxfbG93LCBzcmdiX211bF9sb3cpOwogICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiY29uc3QgdmVjNCBzcmdiX2NvbXBhcmlzb24gPSB2ZWM0KCVmLCAlZiwgJWYsICVmKTtcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcmdiX2NtcCwgc3JnYl9jbXAsIHNyZ2JfY21wLCBzcmdiX2NtcCk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqcHNfaW1wbCA9IChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqKSBUaGlzOwoKICAgICAgICAgICAgLyogRG8gbm90IHdyaXRlIGFueSBzcmdiIGZpeHVwIGludG8gdGhlIHNoYWRlciB0byBzYXZlIHNoYWRlciBzaXplIGFuZCBwcm9jZXNzaW5nIHRpbWUuCiAgICAgICAgICAgICAqIEFzIGEgY29uc2VxdWVuY2UsIHdlIGNhbid0IHRvZ2dsZSBzcmdiIHdyaXRlIG9uIHdpdGhvdXQgcmVjb21waWxhdGlvbgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcHNfaW1wbC0+c3JnYl9lbmFibGVkID0gMDsKICAgICAgICAgICAgcHNfaW1wbC0+c3JnYl9tb2RlX2hhcmRjb2RlZCA9IDE7CiAgICAgICAgfQogICAgICAgIGlmKHJlZ19tYXBzLT52cG9zIHx8IHJlZ19tYXBzLT51c2VzZHN5KSB7CiAgICAgICAgICAgIGlmKFRoaXMtPmJhc2VTaGFkZXIubGltaXRzLmNvbnN0YW50X2Zsb2F0ICsgZXh0cmFfY29uc3RhbnRzX25lZWRlZCArIDEgPCBHTF9MSU1JVFMocHNoYWRlcl9jb25zdGFudHNGKSkgewogICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidW5pZm9ybSB2ZWM0IHljb3JyZWN0aW9uO1xuIik7CiAgICAgICAgICAgICAgICAoKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICopIFRoaXMpLT52cG9zX3VuaWZvcm0gPSAxOwogICAgICAgICAgICAgICAgZXh0cmFfY29uc3RhbnRzX25lZWRlZCsrOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLyogVGhpcyBoYXBwZW5zIGJlY2F1c2Ugd2UgZG8gbm90IGhhdmUgcHJvcGVyIHRyYWNraW5nIG9mIHRoZSBjb25zdGFudCByZWdpc3RlcnMgdGhhdCBhcmUKICAgICAgICAgICAgICAgICAqIGFjdHVhbGx5IHVzZWQsIG9ubHkgdGhlIG1heCBsaW1pdCBvZiB0aGUgc2hhZGVyIHZlcnNpb24KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgRklYTUUoIkNhbm5vdCBmaW5kIGEgZnJlZSB1bmlmb3JtIGZvciB2cG9zIGNvcnJlY3Rpb24gcGFyYW1zXG4iKTsKICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgImNvbnN0IHZlYzQgeWNvcnJlY3Rpb24gPSB2ZWM0KCVmLCAlZiwgMC4wLCAwLjApO1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZS0+cmVuZGVyX29mZnNjcmVlbiA/IDAuMCA6ICgoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBkZXZpY2UtPnJlbmRlcl90YXJnZXRzWzBdKS0+Y3VycmVudERlc2MuSGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlLT5yZW5kZXJfb2Zmc2NyZWVuID8gMS4wIDogLTEuMCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidmVjNCB2cG9zO1xuIik7CiAgICAgICAgfQogICAgfQoKICAgIC8qIERlY2xhcmUgdGV4dHVyZSBzYW1wbGVycyAqLyAKICAgIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5iYXNlU2hhZGVyLmxpbWl0cy5zYW1wbGVyOyBpKyspIHsKICAgICAgICBpZiAocmVnX21hcHMtPnNhbXBsZXJzW2ldKSB7CgogICAgICAgICAgICBEV09SRCBzdHlwZSA9IHJlZ19tYXBzLT5zYW1wbGVyc1tpXSAmIFdJTkVEM0RTUF9URVhUVVJFVFlQRV9NQVNLOwogICAgICAgICAgICBzd2l0Y2ggKHN0eXBlKSB7CgogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEU1RUXzFEOgogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInVuaWZvcm0gc2FtcGxlcjFEICVjc2FtcGxlciV1O1xuIiwgcHJlZml4LCBpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRFNUVF8yRDoKICAgICAgICAgICAgICAgICAgICBpZihkZXZpY2UtPnN0YXRlQmxvY2stPnRleHR1cmVzW2ldICYmCiAgICAgICAgICAgICAgICAgICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9HZXRUZXh0dXJlRGltZW5zaW9ucyhkZXZpY2UtPnN0YXRlQmxvY2stPnRleHR1cmVzW2ldKSA9PSBHTF9URVhUVVJFX1JFQ1RBTkdMRV9BUkIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidW5pZm9ybSBzYW1wbGVyMkRSZWN0ICVjc2FtcGxlciV1O1xuIiwgcHJlZml4LCBpKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ1bmlmb3JtIHNhbXBsZXIyRCAlY3NhbXBsZXIldTtcbiIsIHByZWZpeCwgaSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEU1RUX0NVQkU6CiAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidW5pZm9ybSBzYW1wbGVyQ3ViZSAlY3NhbXBsZXIldTtcbiIsIHByZWZpeCwgaSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RTVFRfVk9MVU1FOgogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInVuaWZvcm0gc2FtcGxlcjNEICVjc2FtcGxlciV1O1xuIiwgcHJlZml4LCBpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidW5pZm9ybSB1bnN1cHBvcnRlZF9zYW1wbGVyICVjc2FtcGxlciV1O1xuIiwgcHJlZml4LCBpKTsKICAgICAgICAgICAgICAgICAgICBGSVhNRSgiVW5yZWNvZ25pemVkIHNhbXBsZXIgdHlwZTogJSN4XG4iLCBzdHlwZSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICAKICAgIC8qIERlY2xhcmUgYWRkcmVzcyB2YXJpYWJsZXMgKi8KICAgIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5iYXNlU2hhZGVyLmxpbWl0cy5hZGRyZXNzOyBpKyspIHsKICAgICAgICBpZiAocmVnX21hcHMtPmFkZHJlc3NbaV0pCiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIml2ZWM0IEElZDtcbiIsIGkpOwogICAgfQoKICAgIC8qIERlY2xhcmUgdGV4dHVyZSBjb29yZGluYXRlIHRlbXBvcmFyaWVzIGFuZCBpbml0aWFsaXplIHRoZW0gKi8KICAgIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5iYXNlU2hhZGVyLmxpbWl0cy50ZXhjb29yZDsgaSsrKSB7CiAgICAgICAgaWYgKHJlZ19tYXBzLT50ZXhjb29yZFtpXSkgCiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInZlYzQgVCV1ID0gZ2xfVGV4Q29vcmRbJXVdO1xuIiwgaSwgaSk7CiAgICB9CgogICAgLyogRGVjbGFyZSBpbnB1dCByZWdpc3RlciB2YXJ5aW5ncy4gT25seSBwaXhlbCBzaGFkZXIsIHZlcnRleCBzaGFkZXJzIGhhdmUgdGhhdCBkZWNsYXJlZCBpbiB0aGUKICAgICAqIGhlbHBlciBmdW5jdGlvbiBzaGFkZXIgdGhhdCBpcyBsaW5rZWQgaW4gYXQgbGluayB0aW1lCiAgICAgKi8KICAgIGlmKHBzaGFkZXIgJiYgVGhpcy0+YmFzZVNoYWRlci5oZXhfdmVyc2lvbiA+PSBXSU5FRDNEUFNfVkVSU0lPTigzLCAwKSkgewogICAgICAgIGlmKHVzZV92cyhkZXZpY2UpKSB7CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInZhcnlpbmcgdmVjNCBJTlsldV07XG4iLCBHTF9MSU1JVFMoZ2xzbF92YXJ5aW5ncykgLyA0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvKiBUT0RPOiBXcml0ZSBhIHJlcGxhY2VtZW50IHNoYWRlciBmb3IgdGhlIGZpeGVkIGZ1bmN0aW9uIHZlcnRleCBwaXBlbGluZSwgc28gdGhpcyBpc24ndCBuZWVkZWQuCiAgICAgICAgICAgICAqIEZvciBmaXhlZCBmdW5jdGlvbiB2ZXJ0ZXggcHJvY2Vzc2luZyArIDMuMCBwaXhlbCBzaGFkZXIgd2UgbmVlZCBhIHNlcGFyYXRlIGZ1bmN0aW9uIGluIHRoZQogICAgICAgICAgICAgKiBwaXhlbCBzaGFkZXIgdGhhdCByZWFkcyB0aGUgZml4ZWQgZnVuY3Rpb24gY29sb3IgaW50byB0aGUgcGFja2VkIGlucHV0IHJlZ2lzdGVycy4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInZlYzQgSU5bJXVdO1xuIiwgR0xfTElNSVRTKGdsc2xfdmFyeWluZ3MpIC8gNCk7CiAgICAgICAgfQogICAgfQoKICAgIC8qIERlY2xhcmUgb3V0cHV0IHJlZ2lzdGVyIHRlbXBvcmFyaWVzICovCiAgICBpZihUaGlzLT5iYXNlU2hhZGVyLmxpbWl0cy5wYWNrZWRfb3V0cHV0KSB7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidmVjNCBPVVRbJXVdO1xuIiwgVGhpcy0+YmFzZVNoYWRlci5saW1pdHMucGFja2VkX291dHB1dCk7CiAgICB9CgogICAgLyogRGVjbGFyZSB0ZW1wb3JhcnkgdmFyaWFibGVzICovCiAgICBmb3IoaSA9IDA7IGkgPCBUaGlzLT5iYXNlU2hhZGVyLmxpbWl0cy50ZW1wb3Jhcnk7IGkrKykgewogICAgICAgIGlmIChyZWdfbWFwcy0+dGVtcG9yYXJ5W2ldKQogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ2ZWM0IFIldTtcbiIsIGkpOwogICAgfQoKICAgIC8qIERlY2xhcmUgYXR0cmlidXRlcyAqLwogICAgZm9yIChpID0gMDsgaSA8IFRoaXMtPmJhc2VTaGFkZXIubGltaXRzLmF0dHJpYnV0ZXM7IGkrKykgewogICAgICAgIGlmIChyZWdfbWFwcy0+YXR0cmlidXRlc1tpXSkKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiYXR0cmlidXRlIHZlYzQgYXR0cmliJWk7XG4iLCBpKTsKICAgIH0KCiAgICAvKiBEZWNsYXJlIGxvb3AgcmVnaXN0ZXJzIGFMeCAqLwogICAgZm9yIChpID0gMDsgaSA8IHJlZ19tYXBzLT5sb29wX2RlcHRoOyBpKyspIHsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJpbnQgYUwldTtcbiIsIGkpOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgImludCB0bXBJbnQldTtcbiIsIGkpOwogICAgfQoKICAgIC8qIFRlbXBvcmFyeSB2YXJpYWJsZXMgZm9yIG1hdHJpeCBvcGVyYXRpb25zICovCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ2ZWM0IHRtcDA7XG4iKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInZlYzQgdG1wMTtcbiIpOwoKICAgIC8qIEhhcmRjb2RhYmxlIGxvY2FsIGNvbnN0YW50cyAqLwogICAgaWYoIVRoaXMtPmJhc2VTaGFkZXIubG9hZF9sb2NhbF9jb25zdHNGKSB7CiAgICAgICAgTElTVF9GT1JfRUFDSF9FTlRSWShsY29uc3QsICZUaGlzLT5iYXNlU2hhZGVyLmNvbnN0YW50c0YsIGxvY2FsX2NvbnN0YW50LCBlbnRyeSkgewogICAgICAgICAgICBmbG9hdCAqdmFsdWUgPSAoZmxvYXQgKikgbGNvbnN0LT52YWx1ZTsKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiY29uc3QgdmVjNCBMQyV1ID0gdmVjNCglZiwgJWYsICVmLCAlZik7XG4iLCBsY29uc3QtPmlkeCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVbMF0sIHZhbHVlWzFdLCB2YWx1ZVsyXSwgdmFsdWVbM10pOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBTdGFydCB0aGUgbWFpbiBwcm9ncmFtICovCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ2b2lkIG1haW4oKSB7XG4iKTsKICAgIGlmKHBzaGFkZXIgJiYgcmVnX21hcHMtPnZwb3MpIHsKICAgICAgICAvKiBEaXJlY3RYIGFwcHMgZXhwZWN0IGludGVnZXIgdmFsdWVzLCB3aGlsZSBPcGVuR0wgZHJpdmVycyBhZGQgYXBwcm94aW1hdGVseSAwLjUuIFRoaXMgY2F1c2VzCiAgICAgICAgICogb2ZmLWJ5LW9uZSBwcm9ibGVtcyBhcyBzcG90dGVkIGJ5IHRoZSB2UG9zIGQzZDkgdmlzdWFsIHRlc3QuIFVuZm9ydHVuYXRlbHkgdGhlIEFUSSBjYXJkcyBkbwogICAgICAgICAqIG5vdCBhZGQgZXhhY3RseSAwLjUsIGJ1dCByYXRoZXIgc29tZXRoaW5nIGxpa2UgMC40OTk5OTk5OSBvciAwLjUwMDAwMDAxLCB3aGljaCBzdGlsbCBjYXVzZXMKICAgICAgICAgKiBwcmVjaXNpb24gdHJvdWJsZXMgd2hlbiB3ZSBqdXN0IHN1YnN0cmFjdCAwLjUuCiAgICAgICAgICoKICAgICAgICAgKiBUbyBkZWFsIHdpdGggdGhhdCBqdXN0IGZsb29yKCkgdGhlIHBvc2l0aW9uLiBUaGlzIHdpbGwgZWxpbWluYXRlIHRoZSBmcmFjdGlvbiBvbiBhbGwgY2FyZHMuCiAgICAgICAgICoKICAgICAgICAgKiBUT0RPOiBUZXN0IGhvdyB0aGF0IGJlaGF2ZXMgd2l0aCBtdWx0aXNhbXBsaW5nIG9uY2Ugd2UgY2FuIGVuYWJsZSBtdWx0aXNhbXBsaW5nIGluIHdpbmV4MTEuCiAgICAgICAgICoKICAgICAgICAgKiBBbiBhZHZhbnRhZ2Ugb2YgZmxvb3IgaXMgdGhhdCBpdCB3b3JrcyBldmVuIGlmIHRoZSBkcml2ZXIgZG9lc24ndCBhZGQgMS8yLiBJdCBpcyBzb21ld2hhdAogICAgICAgICAqIHF1ZXN0aW9uYWJsZSBpZiAxLjUsIDIuNSwgLi4uIGFyZSB0aGUgcHJvcGVyIHZhbHVlcyB0byByZXR1cm4gaW4gZ2xfRnJhZ0Nvb3JkLCBldmVuIHRob3VnaAogICAgICAgICAqIGNvb3JkaW5hdGVzIHNwZWNpZnkgdGhlIHBpeGVsIGNlbnRlcnMgaW5zdGVhZCBvZiB0aGUgcGl4ZWwgY29ybmVycy4gVGhpcyBjb2RlIHdpbGwgYmVoYXZlCiAgICAgICAgICogY29ycmVjdGx5IG9uIGRyaXZlcnMgdGhhdCByZXR1cm5zIGludGVnZXIgdmFsdWVzLgogICAgICAgICAqLwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInZwb3MgPSBmbG9vcih2ZWM0KDAsIHljb3JyZWN0aW9uWzBdLCAwLCAwKSArIGdsX0ZyYWdDb29yZCAqIHZlYzQoMSwgeWNvcnJlY3Rpb25bMV0sIDEsIDEpKTtcbiIpOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRnVuY3Rpb25zIHRvIGdlbmVyYXRlIEdMU0wgc3RyaW5ncyBmcm9tIERpcmVjdFggU2hhZGVyIGJ5dGVjb2RlIGJlZ2luIGhlcmUuCiAqCiAqIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWUgaHR0cDovL3dpa2kud2luZWhxLm9yZy9EaXJlY3RYLVNoYWRlcnMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKiBQcm90b3R5cGVzICovCnN0YXRpYyB2b2lkIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oU0hBREVSX09QQ09ERV9BUkcqIGFyZywgY29uc3QgRFdPUkQgcGFyYW0sCiAgICAgICAgY29uc3QgRFdPUkQgYWRkcl90b2tlbiwgRFdPUkQgbWFzaywgZ2xzbF9zcmNfcGFyYW1fdCAqc3JjX3BhcmFtKTsKCi8qKiBVc2VkIGZvciBvcGNvZGUgbW9kaWZpZXJzIC0gVGhleSBtdWx0aXBseSB0aGUgcmVzdWx0IGJ5IHRoZSBzcGVjaWZpZWQgYW1vdW50ICovCnN0YXRpYyBjb25zdCBjaGFyICogY29uc3Qgc2hpZnRfZ2xzbF90YWJbXSA9IHsKICAgICIiLCAgICAgICAgICAgLyogIDAgKG5vbmUpICovIAogICAgIjIuMCAqICIsICAgICAvKiAgMSAoeDIpICAgKi8gCiAgICAiNC4wICogIiwgICAgIC8qICAyICh4NCkgICAqLyAKICAgICI4LjAgKiAiLCAgICAgLyogIDMgKHg4KSAgICovIAogICAgIjE2LjAgKiAiLCAgICAvKiAgNCAoeDE2KSAgKi8gCiAgICAiMzIuMCAqICIsICAgIC8qICA1ICh4MzIpICAqLyAKICAgICIiLCAgICAgICAgICAgLyogIDYgKHg2NCkgICovIAogICAgIiIsICAgICAgICAgICAvKiAgNyAoeDEyOCkgKi8gCiAgICAiIiwgICAgICAgICAgIC8qICA4IChkMjU2KSAqLyAKICAgICIiLCAgICAgICAgICAgLyogIDkgKGQxMjgpICovIAogICAgIiIsICAgICAgICAgICAvKiAxMCAoZDY0KSAgKi8gCiAgICAiIiwgICAgICAgICAgIC8qIDExIChkMzIpICAqLyAKICAgICIwLjA2MjUgKiAiLCAgLyogMTIgKGQxNikgICovIAogICAgIjAuMTI1ICogIiwgICAvKiAxMyAoZDgpICAgKi8gCiAgICAiMC4yNSAqICIsICAgIC8qIDE0IChkNCkgICAqLyAKICAgICIwLjUgKiAiICAgICAgLyogMTUgKGQyKSAgICovIAp9OwoKLyogR2VuZXJhdGUgYSBHTFNMIHBhcmFtZXRlciB0aGF0IGRvZXMgdGhlIGlucHV0IG1vZGlmaWVyIGNvbXB1dGF0aW9uIGFuZCByZXR1cm4gdGhlIGlucHV0IHJlZ2lzdGVyL21hc2sgdG8gdXNlICovCnN0YXRpYyB2b2lkIHNoYWRlcl9nbHNsX2dlbl9tb2RpZmllciAoCiAgICBjb25zdCBEV09SRCBpbnN0ciwKICAgIGNvbnN0IGNoYXIgKmluX3JlZywKICAgIGNvbnN0IGNoYXIgKmluX3JlZ3N3aXp6bGUsCiAgICBjaGFyICpvdXRfc3RyKSB7CgogICAgb3V0X3N0clswXSA9IDA7CiAgICAKICAgIGlmIChpbnN0ciA9PSBXSU5FRDNEU0lPX1RFWEtJTEwpCiAgICAgICAgcmV0dXJuOwoKICAgIHN3aXRjaCAoaW5zdHIgJiBXSU5FRDNEU1BfU1JDTU9EX01BU0spIHsKICAgIGNhc2UgV0lORUQzRFNQU01fRFo6IC8qIE5lZWQgdG8gaGFuZGxlIHRoaXMgaW4gdGhlIGluc3RydWN0aW9ucyBpdHNlbGYgKHRleGxkICYgdGV4Y3JkKS4gKi8KICAgIGNhc2UgV0lORUQzRFNQU01fRFc6CiAgICBjYXNlIFdJTkVEM0RTUFNNX05PTkU6CiAgICAgICAgc3ByaW50ZihvdXRfc3RyLCAiJXMlcyIsIGluX3JlZywgaW5fcmVnc3dpenpsZSk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFdJTkVEM0RTUFNNX05FRzoKICAgICAgICBzcHJpbnRmKG91dF9zdHIsICItJXMlcyIsIGluX3JlZywgaW5fcmVnc3dpenpsZSk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFdJTkVEM0RTUFNNX05PVDoKICAgICAgICBzcHJpbnRmKG91dF9zdHIsICIhJXMlcyIsIGluX3JlZywgaW5fcmVnc3dpenpsZSk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFdJTkVEM0RTUFNNX0JJQVM6CiAgICAgICAgc3ByaW50ZihvdXRfc3RyLCAiKCVzJXMgLSB2ZWM0KDAuNSklcykiLCBpbl9yZWcsIGluX3JlZ3N3aXp6bGUsIGluX3JlZ3N3aXp6bGUpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU1BTTV9CSUFTTkVHOgogICAgICAgIHNwcmludGYob3V0X3N0ciwgIi0oJXMlcyAtIHZlYzQoMC41KSVzKSIsIGluX3JlZywgaW5fcmVnc3dpenpsZSwgaW5fcmVnc3dpenpsZSk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFdJTkVEM0RTUFNNX1NJR046CiAgICAgICAgc3ByaW50ZihvdXRfc3RyLCAiKDIuMCAqICglcyVzIC0gMC41KSkiLCBpbl9yZWcsIGluX3JlZ3N3aXp6bGUpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU1BTTV9TSUdOTkVHOgogICAgICAgIHNwcmludGYob3V0X3N0ciwgIi0oMi4wICogKCVzJXMgLSAwLjUpKSIsIGluX3JlZywgaW5fcmVnc3dpenpsZSk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFdJTkVEM0RTUFNNX0NPTVA6CiAgICAgICAgc3ByaW50ZihvdXRfc3RyLCAiKDEuMCAtICVzJXMpIiwgaW5fcmVnLCBpbl9yZWdzd2l6emxlKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgV0lORUQzRFNQU01fWDI6CiAgICAgICAgc3ByaW50ZihvdXRfc3RyLCAiKDIuMCAqICVzJXMpIiwgaW5fcmVnLCBpbl9yZWdzd2l6emxlKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgV0lORUQzRFNQU01fWDJORUc6CiAgICAgICAgc3ByaW50ZihvdXRfc3RyLCAiLSgyLjAgKiAlcyVzKSIsIGluX3JlZywgaW5fcmVnc3dpenpsZSk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFdJTkVEM0RTUFNNX0FCUzoKICAgICAgICBzcHJpbnRmKG91dF9zdHIsICJhYnMoJXMlcykiLCBpbl9yZWcsIGluX3JlZ3N3aXp6bGUpOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU1BTTV9BQlNORUc6CiAgICAgICAgc3ByaW50ZihvdXRfc3RyLCAiLWFicyglcyVzKSIsIGluX3JlZywgaW5fcmVnc3dpenpsZSk7CiAgICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAgIEZJWE1FKCJVbmhhbmRsZWQgbW9kaWZpZXIgJXVcbiIsIChpbnN0ciAmIFdJTkVEM0RTUF9TUkNNT0RfTUFTSykpOwogICAgICAgIHNwcmludGYob3V0X3N0ciwgIiVzJXMiLCBpbl9yZWcsIGluX3JlZ3N3aXp6bGUpOwogICAgfQp9CgovKiogV3JpdGVzIHRoZSBHTFNMIHZhcmlhYmxlIG5hbWUgdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgcmVnaXN0ZXIgdGhhdCB0aGUKICogRFggb3Bjb2RlIHBhcmFtZXRlciBpcyB0cnlpbmcgdG8gYWNjZXNzICovCnN0YXRpYyB2b2lkIHNoYWRlcl9nbHNsX2dldF9yZWdpc3Rlcl9uYW1lKAogICAgY29uc3QgRFdPUkQgcGFyYW0sCiAgICBjb25zdCBEV09SRCBhZGRyX3Rva2VuLAogICAgY2hhciogcmVnc3RyLAogICAgQk9PTCogaXNfY29sb3IsCiAgICBTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CgogICAgLyogb1Bvcywgb0ZvZyBhbmQgb1B0cyBpbiBEM0QgKi8KICAgIHN0YXRpYyBjb25zdCBjaGFyICogY29uc3QgaHdyYXN0b3V0X3JlZ19uYW1lc1tdID0geyAiZ2xfUG9zaXRpb24iLCAiZ2xfRm9nRnJhZ0Nvb3JkIiwgImdsX1BvaW50U2l6ZSIgfTsKCiAgICBEV09SRCByZWcgPSBwYXJhbSAmIFdJTkVEM0RTUF9SRUdOVU1fTUFTSzsKICAgIERXT1JEIHJlZ3R5cGUgPSBzaGFkZXJfZ2V0X3JlZ3R5cGUocGFyYW0pOwogICAgSVdpbmVEM0RCYXNlU2hhZGVySW1wbCogVGhpcyA9IChJV2luZUQzREJhc2VTaGFkZXJJbXBsKikgYXJnLT5zaGFkZXI7CiAgICBJV2luZUQzRERldmljZUltcGwqIGRldmljZUltcGwgPSAoSVdpbmVEM0REZXZpY2VJbXBsKikgVGhpcy0+YmFzZVNoYWRlci5kZXZpY2U7CiAgICBXaW5lRDNEX0dMX0luZm8qIGdsX2luZm8gPSAmZGV2aWNlSW1wbC0+YWRhcHRlci0+Z2xfaW5mbzsKCiAgICBjaGFyIHBzaGFkZXIgPSBzaGFkZXJfaXNfcHNoYWRlcl92ZXJzaW9uKFRoaXMtPmJhc2VTaGFkZXIuaGV4X3ZlcnNpb24pOwogICAgY2hhciB0bXBTdHJbNTBdOwoKICAgICppc19jb2xvciA9IEZBTFNFOyAgIAogCiAgICBzd2l0Y2ggKHJlZ3R5cGUpIHsKICAgIGNhc2UgV0lORUQzRFNQUl9URU1QOgogICAgICAgIHNwcmludGYodG1wU3RyLCAiUiV1IiwgcmVnKTsKICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU1BSX0lOUFVUOgogICAgICAgIGlmIChwc2hhZGVyKSB7CiAgICAgICAgICAgIC8qIFBpeGVsIHNoYWRlcnMgPj0gMy4wICovCiAgICAgICAgICAgIGlmIChXSU5FRDNEU0hBREVSX1ZFUlNJT05fTUFKT1IoVGhpcy0+YmFzZVNoYWRlci5oZXhfdmVyc2lvbikgPj0gMykgewogICAgICAgICAgICAgICAgaWYgKHBhcmFtICYgV0lORUQzRFNIQURFUl9BRERSTU9ERV9SRUxBVElWRSkgewogICAgICAgICAgICAgICAgICAgIGdsc2xfc3JjX3BhcmFtX3QgcmVsX3BhcmFtOwogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhZGRyX3Rva2VuLCAwLCBXSU5FRDNEU1BfV1JJVEVNQVNLXzAsICZyZWxfcGFyYW0pOwoKICAgICAgICAgICAgICAgICAgICAvKiBSZW1vdmluZyBhICsgMCB3b3VsZCBiZSBhbiBvYnZpb3VzIG9wdGltaXphdGlvbiwgYnV0IG1hY29zIGRvZXNuJ3Qgc2VlIHRoZSBOT1AKICAgICAgICAgICAgICAgICAgICAgKiBvcGVyYXRpb24gdGhlcmUKICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBpZigoKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICopIFRoaXMpLT5pbnB1dF9yZWdfbWFwW3JlZ10pIHsKICAgICAgICAgICAgICAgICAgICAgICAgc3ByaW50Zih0bXBTdHIsICJJTlslcyArICV1XSIsIHJlbF9wYXJhbS5wYXJhbV9zdHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqKSBUaGlzKS0+aW5wdXRfcmVnX21hcFtyZWddKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgIklOWyVzXSIsIHJlbF9wYXJhbS5wYXJhbV9zdHIpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgc3ByaW50Zih0bXBTdHIsICJJTlsldV0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqKSBUaGlzKS0+aW5wdXRfcmVnX21hcFtyZWddKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmIChyZWc9PTApCiAgICAgICAgICAgICAgICAgICAgc3RyY3B5KHRtcFN0ciwgImdsX0NvbG9yIik7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgc3RyY3B5KHRtcFN0ciwgImdsX1NlY29uZGFyeUNvbG9yIik7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAodnNoYWRlcl9pbnB1dF9pc19jb2xvcigoSVdpbmVEM0RWZXJ0ZXhTaGFkZXIqKSBUaGlzLCByZWcpKQogICAgICAgICAgICAgICAqaXNfY29sb3IgPSBUUlVFOwogICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgImF0dHJpYiV1IiwgcmVnKTsKICAgICAgICB9IAogICAgICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU1BSX0NPTlNUOgogICAgewogICAgICAgIGNvbnN0IGNoYXIqIHByZWZpeCA9IHBzaGFkZXI/ICJQQyI6IlZDIjsKCiAgICAgICAgLyogUmVsYXRpdmUgYWRkcmVzc2luZyAqLwogICAgICAgIGlmIChwYXJhbSAmIFdJTkVEM0RTSEFERVJfQUREUk1PREVfUkVMQVRJVkUpIHsKCiAgICAgICAgICAgLyogUmVsYXRpdmUgYWRkcmVzc2luZyBvbiBzaGFkZXJzIDIuMCsgaGF2ZSBhIHJlbGF0aXZlIGFkZHJlc3MgdG9rZW4sIAogICAgICAgICAgICAqIHByaW9yIHRvIHRoYXQsIGl0IHdhcyBoYXJkLWNvZGVkIGFzICJBMC54IiBiZWNhdXNlIHRoZXJlJ3Mgb25seSAxIHJlZ2lzdGVyICovCiAgICAgICAgICAgaWYgKFdJTkVEM0RTSEFERVJfVkVSU0lPTl9NQUpPUihUaGlzLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uKSA+PSAyKSAgewogICAgICAgICAgICAgICBnbHNsX3NyY19wYXJhbV90IHJlbF9wYXJhbTsKICAgICAgICAgICAgICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFkZHJfdG9rZW4sIDAsIFdJTkVEM0RTUF9XUklURU1BU0tfMCwgJnJlbF9wYXJhbSk7CiAgICAgICAgICAgICAgIGlmKHJlZykgewogICAgICAgICAgICAgICAgICAgc3ByaW50Zih0bXBTdHIsICIlc1slcyArICV1XSIsIHByZWZpeCwgcmVsX3BhcmFtLnBhcmFtX3N0ciwgcmVnKTsKICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgIHNwcmludGYodG1wU3RyLCAiJXNbJXNdIiwgcHJlZml4LCByZWxfcGFyYW0ucGFyYW1fc3RyKTsKICAgICAgICAgICAgICAgfQogICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgIGlmKHJlZykgewogICAgICAgICAgICAgICAgICAgc3ByaW50Zih0bXBTdHIsICIlc1tBMC54ICsgJXVdIiwgcHJlZml4LCByZWcpOwogICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgc3ByaW50Zih0bXBTdHIsICIlc1tBMC54XSIsIHByZWZpeCk7CiAgICAgICAgICAgICAgIH0KICAgICAgICAgICB9CgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmKHNoYWRlcl9jb25zdGFudF9pc19sb2NhbChUaGlzLCByZWcpKSB7CiAgICAgICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgIkxDJXUiLCByZWcpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc3ByaW50Zih0bXBTdHIsICIlc1sldV0iLCBwcmVmaXgsIHJlZyk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGJyZWFrOwogICAgfQogICAgY2FzZSBXSU5FRDNEU1BSX0NPTlNUSU5UOgogICAgICAgIGlmIChwc2hhZGVyKQogICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgIlBJWyV1XSIsIHJlZyk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgIlZJWyV1XSIsIHJlZyk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFdJTkVEM0RTUFJfQ09OU1RCT09MOgogICAgICAgIGlmIChwc2hhZGVyKQogICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgIlBCWyV1XSIsIHJlZyk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgIlZCWyV1XSIsIHJlZyk7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFdJTkVEM0RTUFJfVEVYVFVSRTogLyogY2FzZSBXSU5FRDNEU1BSX0FERFI6ICovCiAgICAgICAgaWYgKHBzaGFkZXIpIHsKICAgICAgICAgICAgc3ByaW50Zih0bXBTdHIsICJUJXUiLCByZWcpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNwcmludGYodG1wU3RyLCAiQSV1IiwgcmVnKTsKICAgICAgICB9CiAgICBicmVhazsKICAgIGNhc2UgV0lORUQzRFNQUl9MT09QOgogICAgICAgIHNwcmludGYodG1wU3RyLCAiYUwldSIsIFRoaXMtPmJhc2VTaGFkZXIuY3VyX2xvb3BfcmVnbm8gLSAxKTsKICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU1BSX1NBTVBMRVI6CiAgICAgICAgaWYgKHBzaGFkZXIpCiAgICAgICAgICAgIHNwcmludGYodG1wU3RyLCAiUHNhbXBsZXIldSIsIHJlZyk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgIlZzYW1wbGVyJXUiLCByZWcpOwogICAgYnJlYWs7CiAgICBjYXNlIFdJTkVEM0RTUFJfQ09MT1JPVVQ6CiAgICAgICAgaWYgKHJlZyA+PSBHTF9MSU1JVFMoYnVmZmVycykpIHsKICAgICAgICAgICAgV0FSTigiV3JpdGUgdG8gcmVuZGVyIHRhcmdldCAldSwgb25seSAlZCBzdXBwb3J0ZWRcbiIsIHJlZywgNCk7CiAgICAgICAgfQogICAgICAgIGlmIChHTF9TVVBQT1JUKEFSQl9EUkFXX0JVRkZFUlMpKSB7CiAgICAgICAgICAgIHNwcmludGYodG1wU3RyLCAiZ2xfRnJhZ0RhdGFbJXVdIiwgcmVnKTsKICAgICAgICB9IGVsc2UgeyAvKiBPbiBvbGRlciBjYXJkcyB3aXRoIEdMU0wgc3VwcG9ydCBsaWtlIHRoZSBHZWZvcmNlRlggdGhlcmUncyBvbmx5IG9uZSBidWZmZXIuICovCiAgICAgICAgICAgIHNwcmludGYodG1wU3RyLCAiZ2xfRnJhZ0NvbG9yIik7CiAgICAgICAgfQogICAgYnJlYWs7CiAgICBjYXNlIFdJTkVEM0RTUFJfUkFTVE9VVDoKICAgICAgICBzcHJpbnRmKHRtcFN0ciwgIiVzIiwgaHdyYXN0b3V0X3JlZ19uYW1lc1tyZWddKTsKICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU1BSX0RFUFRIT1VUOgogICAgICAgIHNwcmludGYodG1wU3RyLCAiZ2xfRnJhZ0RlcHRoIik7CiAgICBicmVhazsKICAgIGNhc2UgV0lORUQzRFNQUl9BVFRST1VUOgogICAgICAgIGlmIChyZWcgPT0gMCkgewogICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgImdsX0Zyb250Q29sb3IiKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgImdsX0Zyb250U2Vjb25kYXJ5Q29sb3IiKTsKICAgICAgICB9CiAgICBicmVhazsKICAgIGNhc2UgV0lORUQzRFNQUl9URVhDUkRPVVQ6CiAgICAgICAgLyogVmVydGV4IHNoYWRlcnMgPj0gMy4wOiBXSU5FRDNEU1BSX09VVFBVVCAqLwogICAgICAgIGlmIChXSU5FRDNEU0hBREVSX1ZFUlNJT05fTUFKT1IoVGhpcy0+YmFzZVNoYWRlci5oZXhfdmVyc2lvbikgPj0gMykKICAgICAgICAgICAgc3ByaW50Zih0bXBTdHIsICJPVVRbJXVdIiwgcmVnKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHNwcmludGYodG1wU3RyLCAiZ2xfVGV4Q29vcmRbJXVdIiwgcmVnKTsKICAgIGJyZWFrOwogICAgY2FzZSBXSU5FRDNEU1BSX01JU0NUWVBFOgogICAgICAgIGlmIChyZWcgPT0gMCkgewogICAgICAgICAgICAvKiB2UG9zICovCiAgICAgICAgICAgIHNwcmludGYodG1wU3RyLCAidnBvcyIpOwogICAgICAgIH0gZWxzZSBpZiAocmVnID09IDEpewogICAgICAgICAgICAvKiBOb3RlIHRoYXQgZ2xfRnJvbnRGYWNpbmcgaXMgYSBib29sLCB3aGlsZSB2RmFjZSBpcwogICAgICAgICAgICAgKiBhIGZsb2F0IGZvciB3aGljaCB0aGUgc2lnbiBkZXRlcm1pbmVzIGZyb250L2JhY2sKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHNwcmludGYodG1wU3RyLCAiKGdsX0Zyb250RmFjaW5nID8gMS4wIDogLTEuMCkiKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBGSVhNRSgiVW5oYW5kbGVkIG1pc2N0eXBlIHJlZ2lzdGVyICVkXG4iLCByZWcpOwogICAgICAgICAgICBzcHJpbnRmKHRtcFN0ciwgInVucmVjb2duaXplZF9yZWdpc3RlciIpOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgRklYTUUoIlVuaGFuZGxlZCByZWdpc3RlciBuYW1lIFR5cGUoJWQpXG4iLCByZWd0eXBlKTsKICAgICAgICBzcHJpbnRmKHRtcFN0ciwgInVucmVjb2duaXplZF9yZWdpc3RlciIpOwogICAgYnJlYWs7CiAgICB9CgogICAgc3RyY2F0KHJlZ3N0ciwgdG1wU3RyKTsKfQoKLyogR2V0IHRoZSBHTFNMIHdyaXRlIG1hc2sgZm9yIHRoZSBkZXN0aW5hdGlvbiByZWdpc3RlciAqLwpzdGF0aWMgRFdPUkQgc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2soY29uc3QgRFdPUkQgcGFyYW0sIGNoYXIgKndyaXRlX21hc2spIHsKICAgIGNoYXIgKnB0ciA9IHdyaXRlX21hc2s7CiAgICBEV09SRCBtYXNrID0gcGFyYW0gJiBXSU5FRDNEU1BfV1JJVEVNQVNLX0FMTDsKCiAgICBpZiAoc2hhZGVyX2lzX3NjYWxhcihwYXJhbSkpIHsKICAgICAgICBtYXNrID0gV0lORUQzRFNQX1dSSVRFTUFTS18wOwogICAgfSBlbHNlIHsKICAgICAgICAqcHRyKysgPSAnLic7CiAgICAgICAgaWYgKHBhcmFtICYgV0lORUQzRFNQX1dSSVRFTUFTS18wKSAqcHRyKysgPSAneCc7CiAgICAgICAgaWYgKHBhcmFtICYgV0lORUQzRFNQX1dSSVRFTUFTS18xKSAqcHRyKysgPSAneSc7CiAgICAgICAgaWYgKHBhcmFtICYgV0lORUQzRFNQX1dSSVRFTUFTS18yKSAqcHRyKysgPSAneic7CiAgICAgICAgaWYgKHBhcmFtICYgV0lORUQzRFNQX1dSSVRFTUFTS18zKSAqcHRyKysgPSAndyc7CiAgICB9CgogICAgKnB0ciA9ICdcMCc7CgogICAgcmV0dXJuIG1hc2s7Cn0KCnN0YXRpYyB1bnNpZ25lZCBpbnQgc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2tfc2l6ZShEV09SRCB3cml0ZV9tYXNrKSB7CiAgICB1bnNpZ25lZCBpbnQgc2l6ZSA9IDA7CgogICAgaWYgKHdyaXRlX21hc2sgJiBXSU5FRDNEU1BfV1JJVEVNQVNLXzApICsrc2l6ZTsKICAgIGlmICh3cml0ZV9tYXNrICYgV0lORUQzRFNQX1dSSVRFTUFTS18xKSArK3NpemU7CiAgICBpZiAod3JpdGVfbWFzayAmIFdJTkVEM0RTUF9XUklURU1BU0tfMikgKytzaXplOwogICAgaWYgKHdyaXRlX21hc2sgJiBXSU5FRDNEU1BfV1JJVEVNQVNLXzMpICsrc2l6ZTsKCiAgICByZXR1cm4gc2l6ZTsKfQoKc3RhdGljIHZvaWQgc2hhZGVyX2dsc2xfZ2V0X3N3aXp6bGUoY29uc3QgRFdPUkQgcGFyYW0sIEJPT0wgZml4dXAsIERXT1JEIG1hc2ssIGNoYXIgKnN3aXp6bGVfc3RyKSB7CiAgICAvKiBGb3IgcmVnaXN0ZXJzIG9mIHR5cGUgV0lORUQzRERFQ0xUWVBFX0QzRENPTE9SLCBkYXRhIGlzIHN0b3JlZCBhcyAiYmdyYSIsCiAgICAgKiBidXQgYWRkcmVzc2VkIGFzICJyZ2JhIi4gVG8gZml4IHRoaXMgd2UgbmVlZCB0byBzd2FwIHRoZSByZWdpc3RlcidzIHgKICAgICAqIGFuZCB6IGNvbXBvbmVudHMuICovCiAgICBEV09SRCBzd2l6emxlID0gKHBhcmFtICYgV0lORUQzRFNQX1NXSVpaTEVfTUFTSykgPj4gV0lORUQzRFNQX1NXSVpaTEVfU0hJRlQ7CiAgICBjb25zdCBjaGFyICpzd2l6emxlX2NoYXJzID0gZml4dXAgPyAienl4dyIgOiAieHl6dyI7CiAgICBjaGFyICpwdHIgPSBzd2l6emxlX3N0cjsKCiAgICBpZiAoIXNoYWRlcl9pc19zY2FsYXIocGFyYW0pKSB7CiAgICAgICAgKnB0cisrID0gJy4nOwogICAgICAgIC8qIHN3aXp6bGUgYml0cyBmaWVsZHM6IHd3enp5eXh4ICovCiAgICAgICAgaWYgKG1hc2sgJiBXSU5FRDNEU1BfV1JJVEVNQVNLXzApICpwdHIrKyA9IHN3aXp6bGVfY2hhcnNbc3dpenpsZSAmIDB4MDNdOwogICAgICAgIGlmIChtYXNrICYgV0lORUQzRFNQX1dSSVRFTUFTS18xKSAqcHRyKysgPSBzd2l6emxlX2NoYXJzWyhzd2l6emxlID4+IDIpICYgMHgwM107CiAgICAgICAgaWYgKG1hc2sgJiBXSU5FRDNEU1BfV1JJVEVNQVNLXzIpICpwdHIrKyA9IHN3aXp6bGVfY2hhcnNbKHN3aXp6bGUgPj4gNCkgJiAweDAzXTsKICAgICAgICBpZiAobWFzayAmIFdJTkVEM0RTUF9XUklURU1BU0tfMykgKnB0cisrID0gc3dpenpsZV9jaGFyc1soc3dpenpsZSA+PiA2KSAmIDB4MDNdOwogICAgfQoKICAgICpwdHIgPSAnXDAnOwp9CgovKiBGcm9tIGEgZ2l2ZW4gcGFyYW1ldGVyIHRva2VuLCBnZW5lcmF0ZSB0aGUgY29ycmVzcG9uZGluZyBHTFNMIHN0cmluZy4KICogQWxzbywgcmV0dXJuIHRoZSBhY3R1YWwgcmVnaXN0ZXIgbmFtZSBhbmQgc3dpenpsZSBpbiBjYXNlIHRoZQogKiBjYWxsZXIgbmVlZHMgdGhpcyBpbmZvcm1hdGlvbiBhcyB3ZWxsLiAqLwpzdGF0aWMgdm9pZCBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKFNIQURFUl9PUENPREVfQVJHKiBhcmcsIGNvbnN0IERXT1JEIHBhcmFtLAogICAgICAgIGNvbnN0IERXT1JEIGFkZHJfdG9rZW4sIERXT1JEIG1hc2ssIGdsc2xfc3JjX3BhcmFtX3QgKnNyY19wYXJhbSkgewogICAgQk9PTCBpc19jb2xvciA9IEZBTFNFOwogICAgY2hhciBzd2l6emxlX3N0cls2XTsKCiAgICBzcmNfcGFyYW0tPnJlZ19uYW1lWzBdID0gJ1wwJzsKICAgIHNyY19wYXJhbS0+cGFyYW1fc3RyWzBdID0gJ1wwJzsKICAgIHN3aXp6bGVfc3RyWzBdID0gJ1wwJzsKCiAgICBzaGFkZXJfZ2xzbF9nZXRfcmVnaXN0ZXJfbmFtZShwYXJhbSwgYWRkcl90b2tlbiwgc3JjX3BhcmFtLT5yZWdfbmFtZSwgJmlzX2NvbG9yLCBhcmcpOwoKICAgIHNoYWRlcl9nbHNsX2dldF9zd2l6emxlKHBhcmFtLCBpc19jb2xvciwgbWFzaywgc3dpenpsZV9zdHIpOwogICAgc2hhZGVyX2dsc2xfZ2VuX21vZGlmaWVyKHBhcmFtLCBzcmNfcGFyYW0tPnJlZ19uYW1lLCBzd2l6emxlX3N0ciwgc3JjX3BhcmFtLT5wYXJhbV9zdHIpOwp9CgovKiBGcm9tIGEgZ2l2ZW4gcGFyYW1ldGVyIHRva2VuLCBnZW5lcmF0ZSB0aGUgY29ycmVzcG9uZGluZyBHTFNMIHN0cmluZy4KICogQWxzbywgcmV0dXJuIHRoZSBhY3R1YWwgcmVnaXN0ZXIgbmFtZSBhbmQgc3dpenpsZSBpbiBjYXNlIHRoZQogKiBjYWxsZXIgbmVlZHMgdGhpcyBpbmZvcm1hdGlvbiBhcyB3ZWxsLiAqLwpzdGF0aWMgRFdPUkQgc2hhZGVyX2dsc2xfYWRkX2RzdF9wYXJhbShTSEFERVJfT1BDT0RFX0FSRyogYXJnLCBjb25zdCBEV09SRCBwYXJhbSwKICAgICAgICBjb25zdCBEV09SRCBhZGRyX3Rva2VuLCBnbHNsX2RzdF9wYXJhbV90ICpkc3RfcGFyYW0pIHsKICAgIEJPT0wgaXNfY29sb3IgPSBGQUxTRTsKCiAgICBkc3RfcGFyYW0tPm1hc2tfc3RyWzBdID0gJ1wwJzsKICAgIGRzdF9wYXJhbS0+cmVnX25hbWVbMF0gPSAnXDAnOwoKICAgIHNoYWRlcl9nbHNsX2dldF9yZWdpc3Rlcl9uYW1lKHBhcmFtLCBhZGRyX3Rva2VuLCBkc3RfcGFyYW0tPnJlZ19uYW1lLCAmaXNfY29sb3IsIGFyZyk7CiAgICByZXR1cm4gc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2socGFyYW0sIGRzdF9wYXJhbS0+bWFza19zdHIpOwp9CgovKiBBcHBlbmQgdGhlIGRlc3RpbmF0aW9uIHBhcnQgb2YgdGhlIGluc3RydWN0aW9uIHRvIHRoZSBidWZmZXIsIHJldHVybiB0aGUgZWZmZWN0aXZlIHdyaXRlIG1hc2sgKi8Kc3RhdGljIERXT1JEIHNoYWRlcl9nbHNsX2FwcGVuZF9kc3RfZXh0KFNIQURFUl9CVUZGRVIgKmJ1ZmZlciwgU0hBREVSX09QQ09ERV9BUkcgKmFyZywgY29uc3QgRFdPUkQgcGFyYW0pIHsKICAgIGdsc2xfZHN0X3BhcmFtX3QgZHN0X3BhcmFtOwogICAgRFdPUkQgbWFzazsKICAgIGludCBzaGlmdDsKCiAgICBtYXNrID0gc2hhZGVyX2dsc2xfYWRkX2RzdF9wYXJhbShhcmcsIHBhcmFtLCBhcmctPmRzdF9hZGRyLCAmZHN0X3BhcmFtKTsKCiAgICBpZihtYXNrKSB7CiAgICAgICAgc2hpZnQgPSAocGFyYW0gJiBXSU5FRDNEU1BfRFNUU0hJRlRfTUFTSykgPj4gV0lORUQzRFNQX0RTVFNISUZUX1NISUZUOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIiVzJXMgPSAlcygiLCBkc3RfcGFyYW0ucmVnX25hbWUsIGRzdF9wYXJhbS5tYXNrX3N0ciwgc2hpZnRfZ2xzbF90YWJbc2hpZnRdKTsKICAgIH0KCiAgICByZXR1cm4gbWFzazsKfQoKLyogQXBwZW5kIHRoZSBkZXN0aW5hdGlvbiBwYXJ0IG9mIHRoZSBpbnN0cnVjdGlvbiB0byB0aGUgYnVmZmVyLCByZXR1cm4gdGhlIGVmZmVjdGl2ZSB3cml0ZSBtYXNrICovCnN0YXRpYyBEV09SRCBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KFNIQURFUl9CVUZGRVIgKmJ1ZmZlciwgU0hBREVSX09QQ09ERV9BUkcgKmFyZykgewogICAgcmV0dXJuIHNoYWRlcl9nbHNsX2FwcGVuZF9kc3RfZXh0KGJ1ZmZlciwgYXJnLCBhcmctPmRzdCk7Cn0KCi8qKiBQcm9jZXNzIEdMU0wgaW5zdHJ1Y3Rpb24gbW9kaWZpZXJzICovCnZvaWQgc2hhZGVyX2dsc2xfYWRkX2luc3RydWN0aW9uX21vZGlmaWVycyhTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICAKICAgIERXT1JEIG1hc2sgPSBhcmctPmRzdCAmIFdJTkVEM0RTUF9EU1RNT0RfTUFTSzsKIAogICAgaWYgKGFyZy0+b3Bjb2RlLT5kc3RfdG9rZW4gJiYgbWFzayAhPSAwKSB7CiAgICAgICAgZ2xzbF9kc3RfcGFyYW1fdCBkc3RfcGFyYW07CgogICAgICAgIHNoYWRlcl9nbHNsX2FkZF9kc3RfcGFyYW0oYXJnLCBhcmctPmRzdCwgMCwgJmRzdF9wYXJhbSk7CgogICAgICAgIGlmIChtYXNrICYgV0lORUQzRFNQRE1fU0FUVVJBVEUpIHsKICAgICAgICAgICAgLyogX1NBVCBtZWFucyB0byBjbGFtcCB0aGUgdmFsdWUgb2YgdGhlIHJlZ2lzdGVyIHRvIGJldHdlZW4gMCBhbmQgMSAqLwogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgIiVzJXMgPSBjbGFtcCglcyVzLCAwLjAsIDEuMCk7XG4iLCBkc3RfcGFyYW0ucmVnX25hbWUsCiAgICAgICAgICAgICAgICAgICAgZHN0X3BhcmFtLm1hc2tfc3RyLCBkc3RfcGFyYW0ucmVnX25hbWUsIGRzdF9wYXJhbS5tYXNrX3N0cik7CiAgICAgICAgfQogICAgICAgIGlmIChtYXNrICYgV0lORUQzRFNQRE1fTVNBTVBDRU5UUk9JRCkgewogICAgICAgICAgICBGSVhNRSgiX2NlbnRyb2lkIG1vZGlmaWVyIG5vdCBoYW5kbGVkXG4iKTsKICAgICAgICB9CiAgICAgICAgaWYgKG1hc2sgJiBXSU5FRDNEU1BETV9QQVJUSUFMUFJFQ0lTSU9OKSB7CiAgICAgICAgICAgIC8qIE1TRE4gc2F5cyB0aGlzIG1vZGlmaWVyIGNhbiBiZSBzYWZlbHkgaWdub3JlZCwgc28gdGhhdCdzIHdoYXQgd2UnbGwgZG8uICovCiAgICAgICAgfQogICAgfQp9CgpzdGF0aWMgaW5saW5lIGNvbnN0IGNoYXIqIHNoYWRlcl9nZXRfY29tcF9vcCgKICAgIGNvbnN0IERXT1JEIG9wY29kZSkgewoKICAgIERXT1JEIG9wID0gKG9wY29kZSAmIElOU1RfQ09OVFJPTFNfTUFTSykgPj4gSU5TVF9DT05UUk9MU19TSElGVDsKICAgIHN3aXRjaCAob3ApIHsKICAgICAgICBjYXNlIENPTVBBUklTT05fR1Q6IHJldHVybiAiPiI7CiAgICAgICAgY2FzZSBDT01QQVJJU09OX0VROiByZXR1cm4gIj09IjsKICAgICAgICBjYXNlIENPTVBBUklTT05fR0U6IHJldHVybiAiPj0iOwogICAgICAgIGNhc2UgQ09NUEFSSVNPTl9MVDogcmV0dXJuICI8IjsKICAgICAgICBjYXNlIENPTVBBUklTT05fTkU6IHJldHVybiAiIT0iOwogICAgICAgIGNhc2UgQ09NUEFSSVNPTl9MRTogcmV0dXJuICI8PSI7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRklYTUUoIlVucmVjb2duaXplZCBjb21wYXJpc29uIHZhbHVlOiAldVxuIiwgb3ApOwogICAgICAgICAgICByZXR1cm4gIihcP1w/KSI7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIHNoYWRlcl9nbHNsX2dldF9zYW1wbGVfZnVuY3Rpb24oRFdPUkQgc2FtcGxlcl90eXBlLCBCT09MIHByb2plY3RlZCwgQk9PTCB0ZXhyZWN0LCBnbHNsX3NhbXBsZV9mdW5jdGlvbl90ICpzYW1wbGVfZnVuY3Rpb24pIHsKICAgIC8qIE5vdGUgdGhhdCB0aGVyZSdzIG5vIHN1Y2ggdGhpbmcgYXMgYSBwcm9qZWN0ZWQgY3ViZSB0ZXh0dXJlLiAqLwogICAgc3dpdGNoKHNhbXBsZXJfdHlwZSkgewogICAgICAgIGNhc2UgV0lORUQzRFNUVF8xRDoKICAgICAgICAgICAgc2FtcGxlX2Z1bmN0aW9uLT5uYW1lID0gcHJvamVjdGVkID8gInRleHR1cmUxRFByb2oiIDogInRleHR1cmUxRCI7CiAgICAgICAgICAgIHNhbXBsZV9mdW5jdGlvbi0+Y29vcmRfbWFzayA9IFdJTkVEM0RTUF9XUklURU1BU0tfMDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEU1RUXzJEOgogICAgICAgICAgICBpZih0ZXhyZWN0KSB7CiAgICAgICAgICAgICAgICBzYW1wbGVfZnVuY3Rpb24tPm5hbWUgPSBwcm9qZWN0ZWQgPyAidGV4dHVyZTJEUmVjdFByb2oiIDogInRleHR1cmUyRFJlY3QiOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc2FtcGxlX2Z1bmN0aW9uLT5uYW1lID0gcHJvamVjdGVkID8gInRleHR1cmUyRFByb2oiIDogInRleHR1cmUyRCI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc2FtcGxlX2Z1bmN0aW9uLT5jb29yZF9tYXNrID0gV0lORUQzRFNQX1dSSVRFTUFTS18wIHwgV0lORUQzRFNQX1dSSVRFTUFTS18xOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RTVFRfQ1VCRToKICAgICAgICAgICAgc2FtcGxlX2Z1bmN0aW9uLT5uYW1lID0gInRleHR1cmVDdWJlIjsKICAgICAgICAgICAgc2FtcGxlX2Z1bmN0aW9uLT5jb29yZF9tYXNrID0gV0lORUQzRFNQX1dSSVRFTUFTS18wIHwgV0lORUQzRFNQX1dSSVRFTUFTS18xIHwgV0lORUQzRFNQX1dSSVRFTUFTS18yOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RTVFRfVk9MVU1FOgogICAgICAgICAgICBzYW1wbGVfZnVuY3Rpb24tPm5hbWUgPSBwcm9qZWN0ZWQgPyAidGV4dHVyZTNEUHJvaiIgOiAidGV4dHVyZTNEIjsKICAgICAgICAgICAgc2FtcGxlX2Z1bmN0aW9uLT5jb29yZF9tYXNrID0gV0lORUQzRFNQX1dSSVRFTUFTS18wIHwgV0lORUQzRFNQX1dSSVRFTUFTS18xIHwgV0lORUQzRFNQX1dSSVRFTUFTS18yOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBzYW1wbGVfZnVuY3Rpb24tPm5hbWUgPSAiIjsKICAgICAgICAgICAgRklYTUUoIlVucmVjb2duaXplZCBzYW1wbGVyIHR5cGU6ICUjeDtcbiIsIHNhbXBsZXJfdHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQp9CgpzdGF0aWMgdm9pZCBzaGFkZXJfZ2xzbF9jb2xvcl9jb3JyZWN0aW9uKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIElXaW5lRDNEQmFzZVNoYWRlckltcGwqIHNoYWRlciA9IChJV2luZUQzREJhc2VTaGFkZXJJbXBsKikgYXJnLT5zaGFkZXI7CiAgICBJV2luZUQzRERldmljZUltcGwqIGRldmljZUltcGwgPSAoSVdpbmVEM0REZXZpY2VJbXBsKikgc2hhZGVyLT5iYXNlU2hhZGVyLmRldmljZTsKICAgIFdpbmVEM0RfR0xfSW5mbyAqZ2xfaW5mbyA9ICZkZXZpY2VJbXBsLT5hZGFwdGVyLT5nbF9pbmZvOwogICAgZ2xzbF9kc3RfcGFyYW1fdCBkc3RfcGFyYW07CiAgICBnbHNsX2RzdF9wYXJhbV90IGRzdF9wYXJhbTI7CiAgICBXSU5FRDNERk9STUFUIGZtdDsKICAgIFdJTkVEM0RGT1JNQVQgY29udmVyc2lvbl9ncm91cDsKICAgIElXaW5lRDNEQmFzZVRleHR1cmVJbXBsICp0ZXh0dXJlOwogICAgRFdPUkQgbWFzaywgbWFza19zaXplOwogICAgVUlOVCBpOwogICAgQk9PTCByZWNvcmRlZCA9IEZBTFNFOwogICAgRFdPUkQgc2FtcGxlcl9pZHg7CiAgICBEV09SRCBoZXhfdmVyc2lvbiA9IHNoYWRlci0+YmFzZVNoYWRlci5oZXhfdmVyc2lvbjsKCiAgICBzd2l0Y2goYXJnLT5vcGNvZGUtPm9wY29kZSkgewogICAgICAgIGNhc2UgV0lORUQzRFNJT19URVg6CiAgICAgICAgICAgIGlmIChoZXhfdmVyc2lvbiA8IFdJTkVEM0RQU19WRVJTSU9OKDIsMCkpIHsKICAgICAgICAgICAgICAgIHNhbXBsZXJfaWR4ID0gYXJnLT5kc3QgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzYW1wbGVyX2lkeCA9IGFyZy0+c3JjWzFdICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fVEVYTERMOgogICAgICAgICAgICBGSVhNRSgiQWRkIGNvbG9yIGZpeHVwIGZvciB2ZXJ0ZXggdGV4dHVyZSBXSU5FRDNEU0lPX1RFWExETFxuIik7CiAgICAgICAgICAgIHJldHVybjsKCiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX1RFWERQM1RFWDoKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fVEVYTTN4M1RFWDoKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fVEVYTTN4M1NQRUM6CiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX1RFWE0zeDNWU1BFQzoKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fVEVYQkVNOgogICAgICAgIGNhc2UgV0lORUQzRFNJT19URVhSRUcyQVI6CiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX1RFWFJFRzJHQjoKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fVEVYUkVHMlJHQjoKICAgICAgICAgICAgc2FtcGxlcl9pZHggPSBhcmctPmRzdCAmIFdJTkVEM0RTUF9SRUdOVU1fTUFTSzsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIC8qIE5vdCBhIHRleHR1cmUgc2FtcGxpbmcgaW5zdHJ1Y3Rpb24sIG5vdGhpbmcgdG8gZG8gKi8KICAgICAgICAgICAgcmV0dXJuOwogICAgfTsKCiAgICB0ZXh0dXJlID0gKElXaW5lRDNEQmFzZVRleHR1cmVJbXBsICopIGRldmljZUltcGwtPnN0YXRlQmxvY2stPnRleHR1cmVzW3NhbXBsZXJfaWR4XTsKICAgIGlmKHRleHR1cmUpIHsKICAgICAgICBmbXQgPSB0ZXh0dXJlLT5yZXNvdXJjZS5mb3JtYXQ7CiAgICAgICAgY29udmVyc2lvbl9ncm91cCA9IHRleHR1cmUtPmJhc2VUZXh0dXJlLnNoYWRlcl9jb252ZXJzaW9uX2dyb3VwOwogICAgfSBlbHNlIHsKICAgICAgICBmbXQgPSBXSU5FRDNERk1UX1VOS05PV047CiAgICAgICAgY29udmVyc2lvbl9ncm91cCA9IFdJTkVEM0RGTVRfVU5LTk9XTjsKICAgIH0KCiAgICAvKiBiZWZvcmUgZG9pbmcgYW55dGhpbmcsIHJlY29yZCB0aGUgc2FtcGxlciB3aXRoIHRoZSBmb3JtYXQgaW4gdGhlIGZvcm1hdCBjb252ZXJzaW9uIGxpc3QsCiAgICAgKiBidXQgY2hlY2sgaWYgaXQncyBub3QgdGhlcmUgYWxyZWFkeQogICAgICovCiAgICBmb3IoaSA9IDA7IGkgPCBzaGFkZXItPmJhc2VTaGFkZXIubnVtX3NhbXBsZWRfc2FtcGxlcnM7IGkrKykgewogICAgICAgIGlmKHNoYWRlci0+YmFzZVNoYWRlci5zYW1wbGVkX3NhbXBsZXJzW2ldID09IHNhbXBsZXJfaWR4KSB7CiAgICAgICAgICAgIHJlY29yZGVkID0gVFJVRTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgaWYoIXJlY29yZGVkKSB7CiAgICAgICAgc2hhZGVyLT5iYXNlU2hhZGVyLnNhbXBsZWRfc2FtcGxlcnNbc2hhZGVyLT5iYXNlU2hhZGVyLm51bV9zYW1wbGVkX3NhbXBsZXJzXSA9IHNhbXBsZXJfaWR4OwogICAgICAgIHNoYWRlci0+YmFzZVNoYWRlci5udW1fc2FtcGxlZF9zYW1wbGVycysrOwogICAgICAgIHNoYWRlci0+YmFzZVNoYWRlci5zYW1wbGVkX2Zvcm1hdFtzYW1wbGVyX2lkeF0gPSBjb252ZXJzaW9uX2dyb3VwOwogICAgfQoKICAgIHN3aXRjaChmbXQpIHsKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfVjhVODoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfVjE2VTE2OgogICAgICAgICAgICBpZihHTF9TVVBQT1JUKE5WX1RFWFRVUkVfU0hBREVSKSB8fAogICAgICAgICAgICAgIChHTF9TVVBQT1JUKEFUSV9FTlZNQVBfQlVNUE1BUCkgJiYgZm10ID09IFdJTkVEM0RGTVRfVjhVOCkpIHsKICAgICAgICAgICAgICAgIC8qIFRoZSAzcmQgY2hhbm5lbCByZXR1cm5zIDEuMCBpbiBkM2QsIGJ1dCAwLjAgaW4gZ2wuIEZpeCB0aGlzIHdoaWxlIHdlJ3JlIGF0IGl0IDotKSAqLwogICAgICAgICAgICAgICAgbWFzayA9IHNoYWRlcl9nbHNsX2FkZF9kc3RfcGFyYW0oYXJnLCBhcmctPmRzdCwgV0lORUQzRFNQX1dSSVRFTUFTS18yLCAmZHN0X3BhcmFtKTsKICAgICAgICAgICAgICAgIG1hc2tfc2l6ZSA9IHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrX3NpemUobWFzayk7CiAgICAgICAgICAgICAgICBpZihtYXNrX3NpemUgPj0gMykgewogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXMuJWMgPSAxLjA7XG4iLCBkc3RfcGFyYW0ucmVnX25hbWUsIGRzdF9wYXJhbS5tYXNrX3N0clszXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvKiBDb3JyZWN0IHRoZSBzaWduLCBidXQgbGVhdmUgdGhlIGJsdWUgYXMgaXQgaXMgLSBpdCB3YXMgbG9hZGVkIGNvcnJlY3RseSBhbHJlYWR5ICovCiAgICAgICAgICAgICAgICBtYXNrID0gc2hhZGVyX2dsc2xfYWRkX2RzdF9wYXJhbShhcmcsIGFyZy0+ZHN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBXSU5FRDNEU1BfV1JJVEVNQVNLXzAgfCBXSU5FRDNEU1BfV1JJVEVNQVNLXzEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZkc3RfcGFyYW0pOwogICAgICAgICAgICAgICAgbWFza19zaXplID0gc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2tfc2l6ZShtYXNrKTsKICAgICAgICAgICAgICAgIGlmKG1hc2tfc2l6ZSA+PSAyKSB7CiAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICIlcy4lYyVjID0gJXMuJWMlYyAqIDIuMCAtIDEuMDtcbiIsCiAgICAgICAgICAgICAgICAgICAgZHN0X3BhcmFtLnJlZ19uYW1lLCBkc3RfcGFyYW0ubWFza19zdHJbMV0sIGRzdF9wYXJhbS5tYXNrX3N0clsyXSwKICAgICAgICAgICAgICAgICAgICBkc3RfcGFyYW0ucmVnX25hbWUsIGRzdF9wYXJhbS5tYXNrX3N0clsxXSwgZHN0X3BhcmFtLm1hc2tfc3RyWzJdKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZihtYXNrX3NpemUgPT0gMSkgewogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXMuJWMgPSAlcy4lYyAqIDIuMCAtIDEuMDtcbiIsIGRzdF9wYXJhbS5yZWdfbmFtZSwgZHN0X3BhcmFtLm1hc2tfc3RyWzFdLAogICAgICAgICAgICAgICAgICAgIGRzdF9wYXJhbS5yZWdfbmFtZSwgZHN0X3BhcmFtLm1hc2tfc3RyWzFdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1g4TDhWOFU4OgogICAgICAgICAgICBpZighR0xfU1VQUE9SVChOVl9URVhUVVJFX1NIQURFUikpIHsKICAgICAgICAgICAgICAgIC8qIFJlZCBhbmQgYmx1ZSBhcmUgdGhlIHNpZ25lZCBjaGFubmVscywgZml4IHRoZW0gdXA7IEJsdWUoPUwpIGlzIGNvcnJlY3QgYWxyZWFkeSwKICAgICAgICAgICAgICAgICAqIGFuZCBhKFgpIGlzIGFsd2F5cyAxLjAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgbWFzayA9IHNoYWRlcl9nbHNsX2FkZF9kc3RfcGFyYW0oYXJnLCBhcmctPmRzdCwgV0lORUQzRFNQX1dSSVRFTUFTS18wIHwgV0lORUQzRFNQX1dSSVRFTUFTS18xLCAmZHN0X3BhcmFtKTsKICAgICAgICAgICAgICAgIG1hc2tfc2l6ZSA9IHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrX3NpemUobWFzayk7CiAgICAgICAgICAgICAgICBpZihtYXNrX3NpemUgPj0gMikgewogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXMuJWMlYyA9ICVzLiVjJWMgKiAyLjAgLSAxLjA7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdF9wYXJhbS5yZWdfbmFtZSwgZHN0X3BhcmFtLm1hc2tfc3RyWzFdLCBkc3RfcGFyYW0ubWFza19zdHJbMl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0X3BhcmFtLnJlZ19uYW1lLCBkc3RfcGFyYW0ubWFza19zdHJbMV0sIGRzdF9wYXJhbS5tYXNrX3N0clsyXSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYobWFza19zaXplID09IDEpIHsKICAgICAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgIiVzLiVjID0gJXMuJWMgKiAyLjAgLSAxLjA7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdF9wYXJhbS5yZWdfbmFtZSwgZHN0X3BhcmFtLm1hc2tfc3RyWzFdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdF9wYXJhbS5yZWdfbmFtZSwgZHN0X3BhcmFtLm1hc2tfc3RyWzFdKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX0w2VjVVNToKICAgICAgICAgICAgaWYoIUdMX1NVUFBPUlQoTlZfVEVYVFVSRV9TSEFERVIpKSB7CiAgICAgICAgICAgICAgICBtYXNrID0gc2hhZGVyX2dsc2xfYWRkX2RzdF9wYXJhbShhcmcsIGFyZy0+ZHN0LCBXSU5FRDNEU1BfV1JJVEVNQVNLXzAgfCBXSU5FRDNEU1BfV1JJVEVNQVNLXzEsICZkc3RfcGFyYW0pOwogICAgICAgICAgICAgICAgbWFza19zaXplID0gc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2tfc2l6ZShtYXNrKTsKICAgICAgICAgICAgICAgIHNoYWRlcl9nbHNsX2FkZF9kc3RfcGFyYW0oYXJnLCBhcmctPmRzdCwgV0lORUQzRFNQX1dSSVRFTUFTS18wIHwgV0lORUQzRFNQX1dSSVRFTUFTS18yLCAmZHN0X3BhcmFtMik7CiAgICAgICAgICAgICAgICBpZihtYXNrX3NpemUgPj0gMykgewogICAgICAgICAgICAgICAgICAgIC8qIFN3YXAgeSBhbmQgeiAoVSBhbmQgTCksIGFuZCBkbyBhIHNpZ24gY29udmVyc2lvbiBvbiB4IGFuZCB0aGUgbmV3IHkoViBhbmQgVSkgKi8KICAgICAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgInRtcDAuZyA9ICVzLiVjO1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3RfcGFyYW0ucmVnX25hbWUsIGRzdF9wYXJhbS5tYXNrX3N0clsyXSk7CiAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICIlcy4lYyVjID0gJXMuJWMlYyAqIDIuMCAtIDEuMDtcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0X3BhcmFtLnJlZ19uYW1lLCBkc3RfcGFyYW0ubWFza19zdHJbMl0sIGRzdF9wYXJhbS5tYXNrX3N0clsxXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3RfcGFyYW0yLnJlZ19uYW1lLCBkc3RfcGFyYW0ubWFza19zdHJbMV0sIGRzdF9wYXJhbS5tYXNrX3N0clszXSk7CiAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICIlcy4lYyA9IHRtcDAuZztcbiIsIGRzdF9wYXJhbS5yZWdfbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3RfcGFyYW0ubWFza19zdHJbM10pOwogICAgICAgICAgICAgICAgfSBlbHNlIGlmKG1hc2tfc2l6ZSA9PSAyKSB7CiAgICAgICAgICAgICAgICAgICAgLyogVGhpcyBpcyBiYWQ6IFdlIGhhdmUgVkwsIGJ1dCB3ZSBuZWVkIFZVICovCiAgICAgICAgICAgICAgICAgICAgRklYTUUoIjIgY29tcG9uZW50cyBzYW1wbGVkIGZyb20gYSBjb252ZXJ0ZWQgTDZWNVU1IHRleHR1cmVcbiIpOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgIiVzLiVjID0gJXMuJWMgKiAyLjAgLSAxLjA7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdF9wYXJhbS5yZWdfbmFtZSwgZHN0X3BhcmFtLm1hc2tfc3RyWzFdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdF9wYXJhbTIucmVnX25hbWUsIGRzdF9wYXJhbS5tYXNrX3N0clsxXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzREZNVF9ROFc4VjhVODoKICAgICAgICAgICAgaWYoIUdMX1NVUFBPUlQoTlZfVEVYVFVSRV9TSEFERVIpKSB7CiAgICAgICAgICAgICAgICAvKiBDb3JyZWN0IHRoZSBzaWduIGluIGFsbCBjaGFubmVscy4gVGhlIHdyaXRlbWFzayBqdXN0IGFwcGxpZXMgYXMtaXMsIG5vCiAgICAgICAgICAgICAgICAgKiBuZWVkIGZvciBjaGVja2luZyB0aGUgbWFzayBzaXplCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHNoYWRlcl9nbHNsX2FkZF9kc3RfcGFyYW0oYXJnLCBhcmctPmRzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFNQX1dSSVRFTUFTS18wIHwgV0lORUQzRFNQX1dSSVRFTUFTS18xIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFNQX1dSSVRFTUFTS18yIHwgV0lORUQzRFNQX1dSSVRFTUFTS18zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZHN0X3BhcmFtKTsKICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXMlcyA9ICVzJXMgKiAyLjAgLSAxLjA7XG4iLCBkc3RfcGFyYW0ucmVnX25hbWUsIGRzdF9wYXJhbS5tYXNrX3N0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRzdF9wYXJhbS5yZWdfbmFtZSwgZHN0X3BhcmFtLm1hc2tfc3RyKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIC8qIHN0dXBpZCBjb21waWxlciAqLwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGJyZWFrOwogICAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogCiAqIEJlZ2luIHByb2Nlc3NpbmcgaW5kaXZpZHVhbCBpbnN0cnVjdGlvbiBvcGNvZGVzCiAqIAogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qIEdlbmVyYXRlIEdMU0wgYXJpdGhtZXRpYyBmdW5jdGlvbnMgKGRzdCA9IHNyYzEgKyBzcmMyKSAqLwp2b2lkIHNoYWRlcl9nbHNsX2FyaXRoKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIENPTlNUIFNIQURFUl9PUENPREUqIGN1ck9wY29kZSA9IGFyZy0+b3Bjb2RlOwogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW07CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzFfcGFyYW07CiAgICBEV09SRCB3cml0ZV9tYXNrOwogICAgY2hhciBvcDsKCiAgICAvKiBEZXRlcm1pbmUgdGhlIEdMU0wgb3BlcmF0b3IgdG8gdXNlIGJhc2VkIG9uIHRoZSBvcGNvZGUgKi8KICAgIHN3aXRjaCAoY3VyT3Bjb2RlLT5vcGNvZGUpIHsKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fTVVMOiBvcCA9ICcqJzsgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX0FERDogb3AgPSAnKyc7IGJyZWFrOwogICAgICAgIGNhc2UgV0lORUQzRFNJT19TVUI6IG9wID0gJy0nOyBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBvcCA9ICcgJzsKICAgICAgICAgICAgRklYTUUoIk9wY29kZSAlcyBub3QgeWV0IGhhbmRsZWQgaW4gR0xTTFxuIiwgY3VyT3Bjb2RlLT5uYW1lKTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CgogICAgd3JpdGVfbWFzayA9IHNoYWRlcl9nbHNsX2FwcGVuZF9kc3QoYnVmZmVyLCBhcmcpOwogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCB3cml0ZV9tYXNrLCAmc3JjMF9wYXJhbSk7CiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMV0sIGFyZy0+c3JjX2FkZHJbMV0sIHdyaXRlX21hc2ssICZzcmMxX3BhcmFtKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIiVzICVjICVzKTtcbiIsIHNyYzBfcGFyYW0ucGFyYW1fc3RyLCBvcCwgc3JjMV9wYXJhbS5wYXJhbV9zdHIpOwp9CgovKiBQcm9jZXNzIHRoZSBXSU5FRDNEU0lPX01PViBvcGNvZGUgdXNpbmcgR0xTTCAoZHN0ID0gc3JjKSAqLwp2b2lkIHNoYWRlcl9nbHNsX21vdihTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBJV2luZUQzREJhc2VTaGFkZXJJbXBsKiBzaGFkZXIgPSAoSVdpbmVEM0RCYXNlU2hhZGVySW1wbCopIGFyZy0+c2hhZGVyOwogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW07CiAgICBEV09SRCB3cml0ZV9tYXNrOwoKICAgIHdyaXRlX21hc2sgPSBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGJ1ZmZlciwgYXJnKTsKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgd3JpdGVfbWFzaywgJnNyYzBfcGFyYW0pOwoKICAgIC8qIEluIHZzXzFfMSBXSU5FRDNEU0lPX01PViBjYW4gd3JpdGUgdG8gdGhlIGFkZHJlc3MgcmVnaXN0ZXIuIEluIGxhdGVyCiAgICAgKiBzaGFkZXIgdmVyc2lvbnMgV0lORUQzRFNJT19NT1ZBIGlzIHVzZWQgZm9yIHRoaXMuICovCiAgICBpZiAoKFdJTkVEM0RTSEFERVJfVkVSU0lPTl9NQUpPUihzaGFkZXItPmJhc2VTaGFkZXIuaGV4X3ZlcnNpb24pID09IDEgJiYKICAgICAgICAgICAgIXNoYWRlcl9pc19wc2hhZGVyX3ZlcnNpb24oc2hhZGVyLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uKSAmJgogICAgICAgICAgICBzaGFkZXJfZ2V0X3JlZ3R5cGUoYXJnLT5kc3QpID09IFdJTkVEM0RTUFJfQUREUikpIHsKICAgICAgICAvKiBUaGlzIGlzIGEgc2ltcGxlIGZsb29yKCkgKi8KICAgICAgICB1bnNpZ25lZCBpbnQgbWFza19zaXplID0gc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2tfc2l6ZSh3cml0ZV9tYXNrKTsKICAgICAgICBpZiAobWFza19zaXplID4gMSkgewogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJpdmVjJWQoZmxvb3IoJXMpKSk7XG4iLCBtYXNrX3NpemUsIHNyYzBfcGFyYW0ucGFyYW1fc3RyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJpbnQoZmxvb3IoJXMpKSk7XG4iLCBzcmMwX3BhcmFtLnBhcmFtX3N0cik7CiAgICAgICAgfQogICAgfSBlbHNlIGlmKGFyZy0+b3Bjb2RlLT5vcGNvZGUgPT0gV0lORUQzRFNJT19NT1ZBKSB7CiAgICAgICAgLyogV2UgbmVlZCB0byAqcm91bmQqIHRvIHRoZSBuZWFyZXN0IGludCBoZXJlLiAqLwogICAgICAgIHVuc2lnbmVkIGludCBtYXNrX3NpemUgPSBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFza19zaXplKHdyaXRlX21hc2spOwogICAgICAgIGlmIChtYXNrX3NpemUgPiAxKSB7CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIml2ZWMlZChmbG9vcihhYnMoJXMpICsgdmVjJWQoMC41KSkgKiBzaWduKCVzKSkpO1xuIiwgbWFza19zaXplLCBzcmMwX3BhcmFtLnBhcmFtX3N0ciwgbWFza19zaXplLCBzcmMwX3BhcmFtLnBhcmFtX3N0cik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiaW50KGZsb29yKGFicyglcykgKyAwLjUpICogc2lnbiglcykpKTtcbiIsIHNyYzBfcGFyYW0ucGFyYW1fc3RyLCBzcmMwX3BhcmFtLnBhcmFtX3N0cik7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICIlcyk7XG4iLCBzcmMwX3BhcmFtLnBhcmFtX3N0cik7CiAgICB9Cn0KCi8qIFByb2Nlc3MgdGhlIGRvdCBwcm9kdWN0IG9wZXJhdG9ycyBEUDMgYW5kIERQNCBpbiBHTFNMIChkc3QgPSBkb3Qoc3JjMCwgc3JjMSkpICovCnZvaWQgc2hhZGVyX2dsc2xfZG90KFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIENPTlNUIFNIQURFUl9PUENPREUqIGN1ck9wY29kZSA9IGFyZy0+b3Bjb2RlOwogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW07CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzFfcGFyYW07CiAgICBEV09SRCBkc3Rfd3JpdGVfbWFzaywgc3JjX3dyaXRlX21hc2s7CiAgICB1bnNpZ25lZCBpbnQgZHN0X3NpemUgPSAwOwoKICAgIGRzdF93cml0ZV9tYXNrID0gc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChidWZmZXIsIGFyZyk7CiAgICBkc3Rfc2l6ZSA9IHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrX3NpemUoZHN0X3dyaXRlX21hc2spOwoKICAgIC8qIGRwMyB3b3JrcyBvbiB2ZWMzLCBkcDQgb24gdmVjNCAqLwogICAgaWYgKGN1ck9wY29kZS0+b3Bjb2RlID09IFdJTkVEM0RTSU9fRFA0KSB7CiAgICAgICAgc3JjX3dyaXRlX21hc2sgPSBXSU5FRDNEU1BfV1JJVEVNQVNLX0FMTDsKICAgIH0gZWxzZSB7CiAgICAgICAgc3JjX3dyaXRlX21hc2sgPSBXSU5FRDNEU1BfV1JJVEVNQVNLXzAgfCBXSU5FRDNEU1BfV1JJVEVNQVNLXzEgfCBXSU5FRDNEU1BfV1JJVEVNQVNLXzI7CiAgICB9CgogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBzcmNfd3JpdGVfbWFzaywgJnNyYzBfcGFyYW0pOwogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzFdLCBhcmctPnNyY19hZGRyWzFdLCBzcmNfd3JpdGVfbWFzaywgJnNyYzFfcGFyYW0pOwoKICAgIGlmIChkc3Rfc2l6ZSA+IDEpIHsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ2ZWMlZChkb3QoJXMsICVzKSkpO1xuIiwgZHN0X3NpemUsIHNyYzBfcGFyYW0ucGFyYW1fc3RyLCBzcmMxX3BhcmFtLnBhcmFtX3N0cik7CiAgICB9IGVsc2UgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgImRvdCglcywgJXMpKTtcbiIsIHNyYzBfcGFyYW0ucGFyYW1fc3RyLCBzcmMxX3BhcmFtLnBhcmFtX3N0cik7CiAgICB9Cn0KCi8qIE5vdGUgdGhhdCB0aGlzIGluc3RydWN0aW9uIGhhcyBzb21lIHJlc3RyaWN0aW9ucy4gVGhlIGRlc3RpbmF0aW9uIHdyaXRlIG1hc2sKICogY2FuJ3QgY29udGFpbiB0aGUgdyBjb21wb25lbnQsIGFuZCB0aGUgc291cmNlIHN3aXp6bGVzIGhhdmUgdG8gYmUgLnh5encgKi8Kdm9pZCBzaGFkZXJfZ2xzbF9jcm9zcyhTSEFERVJfT1BDT0RFX0FSRyAqYXJnKSB7CiAgICBEV09SRCBzcmNfbWFzayA9IFdJTkVEM0RTUF9XUklURU1BU0tfMCB8IFdJTkVEM0RTUF9XUklURU1BU0tfMSB8IFdJTkVEM0RTUF9XUklURU1BU0tfMjsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMF9wYXJhbTsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMV9wYXJhbTsKICAgIGNoYXIgZHN0X21hc2tbNl07CgogICAgc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2soYXJnLT5kc3QsIGRzdF9tYXNrKTsKICAgIHNoYWRlcl9nbHNsX2FwcGVuZF9kc3QoYXJnLT5idWZmZXIsIGFyZyk7CiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIHNyY19tYXNrLCAmc3JjMF9wYXJhbSk7CiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMV0sIGFyZy0+c3JjX2FkZHJbMV0sIHNyY19tYXNrLCAmc3JjMV9wYXJhbSk7CiAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgImNyb3NzKCVzLCAlcyklcyk7XG4iLCBzcmMwX3BhcmFtLnBhcmFtX3N0ciwgc3JjMV9wYXJhbS5wYXJhbV9zdHIsIGRzdF9tYXNrKTsKfQoKLyogUHJvY2VzcyB0aGUgV0lORUQzRFNJT19QT1cgaW5zdHJ1Y3Rpb24gaW4gR0xTTCAoZHN0ID0gfHNyYzB8XnNyYzEpCiAqIFNyYzAgYW5kIHNyYzEgYXJlIHNjYWxhcnMuIE5vdGUgdGhhdCBEM0QgdXNlcyB0aGUgYWJzb2x1dGUgb2Ygc3JjMCwgd2hpbGUKICogR0xTTCB1c2VzIHRoZSB2YWx1ZSBhcy1pcy4gKi8Kdm9pZCBzaGFkZXJfZ2xzbF9wb3coU0hBREVSX09QQ09ERV9BUkcgKmFyZykgewogICAgU0hBREVSX0JVRkZFUiAqYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW07CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzFfcGFyYW07CiAgICBEV09SRCBkc3Rfd3JpdGVfbWFzazsKICAgIHVuc2lnbmVkIGludCBkc3Rfc2l6ZTsKCiAgICBkc3Rfd3JpdGVfbWFzayA9IHNoYWRlcl9nbHNsX2FwcGVuZF9kc3QoYnVmZmVyLCBhcmcpOwogICAgZHN0X3NpemUgPSBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFza19zaXplKGRzdF93cml0ZV9tYXNrKTsKCiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfMCwgJnNyYzBfcGFyYW0pOwogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzFdLCBhcmctPnNyY19hZGRyWzFdLCBXSU5FRDNEU1BfV1JJVEVNQVNLXzAsICZzcmMxX3BhcmFtKTsKCiAgICBpZiAoZHN0X3NpemUgPiAxKSB7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidmVjJWQocG93KGFicyglcyksICVzKSkpO1xuIiwgZHN0X3NpemUsIHNyYzBfcGFyYW0ucGFyYW1fc3RyLCBzcmMxX3BhcmFtLnBhcmFtX3N0cik7CiAgICB9IGVsc2UgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInBvdyhhYnMoJXMpLCAlcykpO1xuIiwgc3JjMF9wYXJhbS5wYXJhbV9zdHIsIHNyYzFfcGFyYW0ucGFyYW1fc3RyKTsKICAgIH0KfQoKLyogUHJvY2VzcyB0aGUgV0lORUQzRFNJT19MT0cgaW5zdHJ1Y3Rpb24gaW4gR0xTTCAoZHN0ID0gbG9nMih8c3JjMHwpKQogKiBTcmMwIGlzIGEgc2NhbGFyLiBOb3RlIHRoYXQgRDNEIHVzZXMgdGhlIGFic29sdXRlIG9mIHNyYzAsIHdoaWxlCiAqIEdMU0wgdXNlcyB0aGUgdmFsdWUgYXMtaXMuICovCnZvaWQgc2hhZGVyX2dsc2xfbG9nKFNIQURFUl9PUENPREVfQVJHICphcmcpIHsKICAgIFNIQURFUl9CVUZGRVIgKmJ1ZmZlciA9IGFyZy0+YnVmZmVyOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMwX3BhcmFtOwogICAgRFdPUkQgZHN0X3dyaXRlX21hc2s7CiAgICB1bnNpZ25lZCBpbnQgZHN0X3NpemU7CgogICAgZHN0X3dyaXRlX21hc2sgPSBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGJ1ZmZlciwgYXJnKTsKICAgIGRzdF9zaXplID0gc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2tfc2l6ZShkc3Rfd3JpdGVfbWFzayk7CgogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBXSU5FRDNEU1BfV1JJVEVNQVNLXzAsICZzcmMwX3BhcmFtKTsKCiAgICBpZiAoZHN0X3NpemUgPiAxKSB7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidmVjJWQobG9nMihhYnMoJXMpKSkpO1xuIiwgZHN0X3NpemUsIHNyYzBfcGFyYW0ucGFyYW1fc3RyKTsKICAgIH0gZWxzZSB7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAibG9nMihhYnMoJXMpKSk7XG4iLCBzcmMwX3BhcmFtLnBhcmFtX3N0cik7CiAgICB9Cn0KCi8qIE1hcCB0aGUgb3Bjb2RlIDEtdG8tMSB0byB0aGUgR0wgY29kZSAoYXJnLT5kc3QgPSBpbnN0cnVjdGlvbihzcmMwLCBzcmMxLCAuLi4pICovCnZvaWQgc2hhZGVyX2dsc2xfbWFwMmdsKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIENPTlNUIFNIQURFUl9PUENPREUqIGN1ck9wY29kZSA9IGFyZy0+b3Bjb2RlOwogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyY19wYXJhbTsKICAgIGNvbnN0IGNoYXIgKmluc3RydWN0aW9uOwogICAgY2hhciBhcmd1bWVudHNbMjU2XTsKICAgIERXT1JEIHdyaXRlX21hc2s7CiAgICB1bnNpZ25lZCBpOwoKICAgIC8qIERldGVybWluZSB0aGUgR0xTTCBmdW5jdGlvbiB0byB1c2UgYmFzZWQgb24gdGhlIG9wY29kZSAqLwogICAgLyogVE9ETzogUG9zc2libHkgbWFrZSB0aGlzIGEgdGFibGUgZm9yIGZhc3RlciBsb29rdXBzICovCiAgICBzd2l0Y2ggKGN1ck9wY29kZS0+b3Bjb2RlKSB7CiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX01JTjogaW5zdHJ1Y3Rpb24gPSAibWluIjsgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX01BWDogaW5zdHJ1Y3Rpb24gPSAibWF4IjsgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX0FCUzogaW5zdHJ1Y3Rpb24gPSAiYWJzIjsgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX0ZSQzogaW5zdHJ1Y3Rpb24gPSAiZnJhY3QiOyBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fTlJNOiBpbnN0cnVjdGlvbiA9ICJub3JtYWxpemUiOyBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fTE9HUDoKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fTE9HOiBpbnN0cnVjdGlvbiA9ICJsb2cyIjsgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX0VYUDogaW5zdHJ1Y3Rpb24gPSAiZXhwMiI7IGJyZWFrOwogICAgICAgIGNhc2UgV0lORUQzRFNJT19TR046IGluc3RydWN0aW9uID0gInNpZ24iOyBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fRFNYOiBpbnN0cnVjdGlvbiA9ICJkRmR4IjsgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX0RTWTogaW5zdHJ1Y3Rpb24gPSAieWNvcnJlY3Rpb24ueSAqIGRGZHkiOyBicmVhazsKICAgICAgICBkZWZhdWx0OiBpbnN0cnVjdGlvbiA9ICIiOwogICAgICAgICAgICBGSVhNRSgiT3Bjb2RlICVzIG5vdCB5ZXQgaGFuZGxlZCBpbiBHTFNMXG4iLCBjdXJPcGNvZGUtPm5hbWUpOwogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICB3cml0ZV9tYXNrID0gc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChidWZmZXIsIGFyZyk7CgogICAgYXJndW1lbnRzWzBdID0gJ1wwJzsKICAgIGlmIChjdXJPcGNvZGUtPm51bV9wYXJhbXMgPiAwKSB7CiAgICAgICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCB3cml0ZV9tYXNrLCAmc3JjX3BhcmFtKTsKICAgICAgICBzdHJjYXQoYXJndW1lbnRzLCBzcmNfcGFyYW0ucGFyYW1fc3RyKTsKICAgICAgICBmb3IgKGkgPSAyOyBpIDwgY3VyT3Bjb2RlLT5udW1fcGFyYW1zOyArK2kpIHsKICAgICAgICAgICAgc3RyY2F0KGFyZ3VtZW50cywgIiwgIik7CiAgICAgICAgICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1tpLTFdLCBhcmctPnNyY19hZGRyW2ktMV0sIHdyaXRlX21hc2ssICZzcmNfcGFyYW0pOwogICAgICAgICAgICBzdHJjYXQoYXJndW1lbnRzLCBzcmNfcGFyYW0ucGFyYW1fc3RyKTsKICAgICAgICB9CiAgICB9CgogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiJXMoJXMpKTtcbiIsIGluc3RydWN0aW9uLCBhcmd1bWVudHMpOwp9CgovKiogUHJvY2VzcyB0aGUgV0lORUQzRFNJT19FWFBQIGluc3RydWN0aW9uIGluIEdMU0w6CiAqIEZvciBzaGFkZXIgbW9kZWwgMS54LCBkbyB0aGUgZm9sbG93aW5nIChhbmQgaG9ub3IgdGhlIHdyaXRlbWFzaywgc28gdXNlIGEgdGVtcG9yYXJ5IHZhcmlhYmxlKToKICogICBkc3QueCA9IDJeKGZsb29yKHNyYykpCiAqICAgZHN0LnkgPSBzcmMgLSBmbG9vcihzcmMpCiAqICAgZHN0LnogPSAyXnNyYyAgIChwYXJ0aWFsIHByZWNpc2lvbiBpcyBhbGxvd2VkLCBidXQgb3B0aW9uYWwpCiAqICAgZHN0LncgPSAxLjA7CiAqIEZvciAyLjAgc2hhZGVycywganVzdCBkbyB0aGlzIChob25vcmluZyB3cml0ZW1hc2sgYW5kIHN3aXp6bGUpOgogKiAgIGRzdCA9IDJec3JjOyAgICAocGFydGlhbCBwcmVjaXNpb24gaXMgYWxsb3dlZCwgYnV0IG9wdGlvbmFsKQogKi8Kdm9pZCBzaGFkZXJfZ2xzbF9leHBwKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIElXaW5lRDNEQmFzZVNoYWRlckltcGwgKnNoYWRlciA9IChJV2luZUQzREJhc2VTaGFkZXJJbXBsICopYXJnLT5zaGFkZXI7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyY19wYXJhbTsKCiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfMCwgJnNyY19wYXJhbSk7CgogICAgaWYgKHNoYWRlci0+YmFzZVNoYWRlci5oZXhfdmVyc2lvbiA8IFdJTkVEM0RQU19WRVJTSU9OKDIsMCkpIHsKICAgICAgICBjaGFyIGRzdF9tYXNrWzZdOwoKICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgInRtcDAueCA9IGV4cDIoZmxvb3IoJXMpKTtcbiIsIHNyY19wYXJhbS5wYXJhbV9zdHIpOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAidG1wMC55ID0gJXMgLSBmbG9vciglcyk7XG4iLCBzcmNfcGFyYW0ucGFyYW1fc3RyLCBzcmNfcGFyYW0ucGFyYW1fc3RyKTsKICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgInRtcDAueiA9IGV4cDIoJXMpO1xuIiwgc3JjX3BhcmFtLnBhcmFtX3N0cik7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJ0bXAwLncgPSAxLjA7XG4iKTsKCiAgICAgICAgc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChhcmctPmJ1ZmZlciwgYXJnKTsKICAgICAgICBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFzayhhcmctPmRzdCwgZHN0X21hc2spOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAidG1wMCVzKTtcbiIsIGRzdF9tYXNrKTsKICAgIH0gZWxzZSB7CiAgICAgICAgRFdPUkQgd3JpdGVfbWFzazsKICAgICAgICB1bnNpZ25lZCBpbnQgbWFza19zaXplOwoKICAgICAgICB3cml0ZV9tYXNrID0gc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChhcmctPmJ1ZmZlciwgYXJnKTsKICAgICAgICBtYXNrX3NpemUgPSBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFza19zaXplKHdyaXRlX21hc2spOwoKICAgICAgICBpZiAobWFza19zaXplID4gMSkgewogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgInZlYyVkKGV4cDIoJXMpKSk7XG4iLCBtYXNrX3NpemUsIHNyY19wYXJhbS5wYXJhbV9zdHIpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiZXhwMiglcykpO1xuIiwgc3JjX3BhcmFtLnBhcmFtX3N0cik7CiAgICAgICAgfQogICAgfQp9CgovKiogUHJvY2VzcyB0aGUgUkNQIChyZWNpcHJvY2FsIG9yIGludmVyc2UpIG9wY29kZSBpbiBHTFNMIChkc3QgPSAxIC8gc3JjKSAqLwp2b2lkIHNoYWRlcl9nbHNsX3JjcChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyY19wYXJhbTsKICAgIERXT1JEIHdyaXRlX21hc2s7CiAgICB1bnNpZ25lZCBpbnQgbWFza19zaXplOwoKICAgIHdyaXRlX21hc2sgPSBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGFyZy0+YnVmZmVyLCBhcmcpOwogICAgbWFza19zaXplID0gc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2tfc2l6ZSh3cml0ZV9tYXNrKTsKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgV0lORUQzRFNQX1dSSVRFTUFTS18zLCAmc3JjX3BhcmFtKTsKCiAgICBpZiAobWFza19zaXplID4gMSkgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAidmVjJWQoMS4wIC8gJXMpKTtcbiIsIG1hc2tfc2l6ZSwgc3JjX3BhcmFtLnBhcmFtX3N0cik7CiAgICB9IGVsc2UgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiMS4wIC8gJXMpO1xuIiwgc3JjX3BhcmFtLnBhcmFtX3N0cik7CiAgICB9Cn0KCnZvaWQgc2hhZGVyX2dsc2xfcnNxKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIFNIQURFUl9CVUZGRVIqIGJ1ZmZlciA9IGFyZy0+YnVmZmVyOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmNfcGFyYW07CiAgICBEV09SRCB3cml0ZV9tYXNrOwogICAgdW5zaWduZWQgaW50IG1hc2tfc2l6ZTsKCiAgICB3cml0ZV9tYXNrID0gc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChidWZmZXIsIGFyZyk7CiAgICBtYXNrX3NpemUgPSBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFza19zaXplKHdyaXRlX21hc2spOwoKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgV0lORUQzRFNQX1dSSVRFTUFTS18zLCAmc3JjX3BhcmFtKTsKCiAgICBpZiAobWFza19zaXplID4gMSkgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInZlYyVkKGludmVyc2VzcXJ0KCVzKSkpO1xuIiwgbWFza19zaXplLCBzcmNfcGFyYW0ucGFyYW1fc3RyKTsKICAgIH0gZWxzZSB7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiaW52ZXJzZXNxcnQoJXMpKTtcbiIsIHNyY19wYXJhbS5wYXJhbV9zdHIpOwogICAgfQp9CgovKiogUHJvY2VzcyBzaWduZWQgY29tcGFyaXNvbiBvcGNvZGVzIGluIEdMU0wuICovCnZvaWQgc2hhZGVyX2dsc2xfY29tcGFyZShTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW07CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzFfcGFyYW07CiAgICBEV09SRCB3cml0ZV9tYXNrOwogICAgdW5zaWduZWQgaW50IG1hc2tfc2l6ZTsKCiAgICB3cml0ZV9tYXNrID0gc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChhcmctPmJ1ZmZlciwgYXJnKTsKICAgIG1hc2tfc2l6ZSA9IHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrX3NpemUod3JpdGVfbWFzayk7CiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIHdyaXRlX21hc2ssICZzcmMwX3BhcmFtKTsKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1sxXSwgYXJnLT5zcmNfYWRkclsxXSwgd3JpdGVfbWFzaywgJnNyYzFfcGFyYW0pOwoKICAgIGlmIChtYXNrX3NpemUgPiAxKSB7CiAgICAgICAgY29uc3QgY2hhciAqY29tcGFyZTsKCiAgICAgICAgc3dpdGNoKGFyZy0+b3Bjb2RlLT5vcGNvZGUpIHsKICAgICAgICAgICAgY2FzZSBXSU5FRDNEU0lPX1NMVDogY29tcGFyZSA9ICJsZXNzVGhhbiI7IGJyZWFrOwogICAgICAgICAgICBjYXNlIFdJTkVEM0RTSU9fU0dFOiBjb21wYXJlID0gImdyZWF0ZXJUaGFuRXF1YWwiOyBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDogY29tcGFyZSA9ICIiOwogICAgICAgICAgICAgICAgRklYTUUoIkNhbid0IGhhbmRsZSBvcGNvZGUgJXNcbiIsIGFyZy0+b3Bjb2RlLT5uYW1lKTsKICAgICAgICB9CgogICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAidmVjJWQoJXMoJXMsICVzKSkpO1xuIiwgbWFza19zaXplLCBjb21wYXJlLAogICAgICAgICAgICAgICAgc3JjMF9wYXJhbS5wYXJhbV9zdHIsIHNyYzFfcGFyYW0ucGFyYW1fc3RyKTsKICAgIH0gZWxzZSB7CiAgICAgICAgc3dpdGNoKGFyZy0+b3Bjb2RlLT5vcGNvZGUpIHsKICAgICAgICAgICAgY2FzZSBXSU5FRDNEU0lPX1NMVDoKICAgICAgICAgICAgICAgIC8qIFN0ZXAoc3JjMCwgc3JjMSkgaXMgbm90IHN1aXRhYmxlIGhlcmUgYmVjYXVzZSBpZiBzcmMwID09IHNyYzEgU0xUIGlzIHN1cHBvc2VkLAogICAgICAgICAgICAgICAgICogdG8gcmV0dXJuIDAuMCBidXQgc3RlcCByZXR1cm5zIDEuMCBiZWNhdXNlIHN0ZXAgaXMgbm90IDwgeAogICAgICAgICAgICAgICAgICogQW4gYWx0ZXJuYXRpdmUgaXMgYSBidmVjIGNvbXBhcmUgcGFkZGVkIHdpdGggYW4gdW51c2VkIHNlY29uZCBjb21wb25lbnQuCiAgICAgICAgICAgICAgICAgKiBzdGVwKHNyYzEgKiAtMS4wLCBzcmMwICogLTEuMCkgaXMgbm90IGFuIG9wdGlvbiBiZWNhdXNlIGl0IHN1ZmZlcnMgZnJvbSB0aGUgc2FtZQogICAgICAgICAgICAgICAgICogaXNzdWUuIFBsYXlpbmcgd2l0aCBub3QoKSBpcyBub3QgcG9zc2libGUgZWl0aGVyIGJlY2F1c2Ugbm90KCkgZG9lcyBub3QgYWNjZXB0CiAgICAgICAgICAgICAgICAgKiBhIHNjYWxhci4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICIoJXMgPCAlcykgPyAxLjAgOiAwLjApO1xuIiwgc3JjMF9wYXJhbS5wYXJhbV9zdHIsIHNyYzFfcGFyYW0ucGFyYW1fc3RyKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFdJTkVEM0RTSU9fU0dFOgogICAgICAgICAgICAgICAgLyogSGVyZSB3ZSBjYW4gdXNlIHRoZSBzdGVwKCkgZnVuY3Rpb24gYW5kIHNhZmUgYSBjb25kaXRpb25hbCAqLwogICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJzdGVwKCVzLCAlcykpO1xuIiwgc3JjMV9wYXJhbS5wYXJhbV9zdHIsIHNyYzBfcGFyYW0ucGFyYW1fc3RyKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgRklYTUUoIkNhbid0IGhhbmRsZSBvcGNvZGUgJXNcbiIsIGFyZy0+b3Bjb2RlLT5uYW1lKTsKICAgICAgICB9CgogICAgfQp9CgovKiogUHJvY2VzcyBDTVAgaW5zdHJ1Y3Rpb24gaW4gR0xTTCAoZHN0ID0gc3JjMCA+PSAwLjAgPyBzcmMxIDogc3JjMiksIHBlciBjaGFubmVsICovCnZvaWQgc2hhZGVyX2dsc2xfY21wKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMF9wYXJhbTsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMV9wYXJhbTsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMl9wYXJhbTsKICAgIERXT1JEIHdyaXRlX21hc2ssIGNtcF9jaGFubmVsID0gMDsKICAgIHVuc2lnbmVkIGludCBpLCBqOwogICAgY2hhciBtYXNrX2NoYXJbNl07CiAgICBCT09MIHRlbXBfZGVzdGluYXRpb24gPSBGQUxTRTsKCiAgICBpZihzaGFkZXJfaXNfc2NhbGFyKGFyZy0+c3JjWzBdKSkgewogICAgICAgIHdyaXRlX21hc2sgPSBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGFyZy0+YnVmZmVyLCBhcmcpOwoKICAgICAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfQUxMLCAmc3JjMF9wYXJhbSk7CiAgICAgICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzFdLCBhcmctPnNyY19hZGRyWzFdLCB3cml0ZV9tYXNrLCAmc3JjMV9wYXJhbSk7CiAgICAgICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzJdLCBhcmctPnNyY19hZGRyWzJdLCB3cml0ZV9tYXNrLCAmc3JjMl9wYXJhbSk7CgogICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXMgPj0gMC4wID8gJXMgOiAlcyk7XG4iLAogICAgICAgICAgICAgICAgICAgICAgIHNyYzBfcGFyYW0ucGFyYW1fc3RyLCBzcmMxX3BhcmFtLnBhcmFtX3N0ciwgc3JjMl9wYXJhbS5wYXJhbV9zdHIpOwogICAgfSBlbHNlIHsKICAgICAgICBEV09SRCBzcmMwcmVnID0gYXJnLT5zcmNbMF0gJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICAgICAgRFdPUkQgc3JjMXJlZyA9IGFyZy0+c3JjWzFdICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgICAgIERXT1JEIHNyYzJyZWcgPSBhcmctPnNyY1syXSAmIFdJTkVEM0RTUF9SRUdOVU1fTUFTSzsKICAgICAgICBEV09SRCBzcmMwcmVndHlwZSA9IHNoYWRlcl9nZXRfcmVndHlwZShhcmctPnNyY1swXSk7CiAgICAgICAgRFdPUkQgc3JjMXJlZ3R5cGUgPSBzaGFkZXJfZ2V0X3JlZ3R5cGUoYXJnLT5zcmNbMV0pOwogICAgICAgIERXT1JEIHNyYzJyZWd0eXBlID0gc2hhZGVyX2dldF9yZWd0eXBlKGFyZy0+c3JjWzJdKTsKICAgICAgICBEV09SRCBkc3RyZWcgPSBhcmctPmRzdCAmIFdJTkVEM0RTUF9SRUdOVU1fTUFTSzsKICAgICAgICBEV09SRCBkc3RyZWd0eXBlID0gc2hhZGVyX2dldF9yZWd0eXBlKGFyZy0+ZHN0KTsKCiAgICAgICAgLyogQ3ljbGUgdGhyb3VnaCBhbGwgc291cmNlMCBjaGFubmVscyAqLwogICAgICAgIGZvciAoaT0wOyBpPDQ7IGkrKykgewogICAgICAgICAgICB3cml0ZV9tYXNrID0gMDsKICAgICAgICAgICAgLyogRmluZCB0aGUgZGVzdGluYXRpb24gY2hhbm5lbHMgd2hpY2ggdXNlIHRoZSBjdXJyZW50IHNvdXJjZTAgY2hhbm5lbCAqLwogICAgICAgICAgICBmb3IgKGo9MDsgajw0OyBqKyspIHsKICAgICAgICAgICAgICAgIGlmICggKChhcmctPnNyY1swXSA+PiAoV0lORUQzRFNQX1NXSVpaTEVfU0hJRlQgKyAyKmopKSAmIDB4MykgPT0gaSApIHsKICAgICAgICAgICAgICAgICAgICB3cml0ZV9tYXNrIHw9IFdJTkVEM0RTUF9XUklURU1BU0tfMCA8PCBqOwogICAgICAgICAgICAgICAgICAgIGNtcF9jaGFubmVsID0gV0lORUQzRFNQX1dSSVRFTUFTS18wIDw8IGo7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIFNwbGl0dGluZyB0aGUgY21wIGluc3RydWN0aW9uIHVwIGluIG11bHRpcGxlIGxpbmVzIGltcG9zZXMgYSBwcm9ibGVtOgogICAgICAgICAgICAqIFRoZSBmaXJzdCBsaW5lcyBtYXkgb3ZlcndyaXRlIHNvdXJjZSBwYXJhbWV0ZXJzIG9mIHRoZSBmb2xsb3dpbmcgbGluZXMuCiAgICAgICAgICAgICogRGVhbCB3aXRoIHRoYXQgYnkgdXNpbmcgYSB0ZW1wb3JhcnkgZGVzdGluYXRpb24gcmVnaXN0ZXIgaWYgbmVlZGVkCiAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmKChzcmMwcmVnID09IGRzdHJlZyAmJiBzcmMwcmVndHlwZSA9PSBkc3RyZWd0eXBlKSB8fAogICAgICAgICAgICAoc3JjMXJlZyA9PSBkc3RyZWcgJiYgc3JjMXJlZ3R5cGUgPT0gZHN0cmVndHlwZSkgfHwKICAgICAgICAgICAgKHNyYzJyZWcgPT0gZHN0cmVnICYmIHNyYzJyZWd0eXBlID09IGRzdHJlZ3R5cGUpKSB7CgogICAgICAgICAgICAgICAgd3JpdGVfbWFzayA9IHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrKGFyZy0+ZHN0ICYgKH5XSU5FRDNEU1BfU1dJWlpMRV9NQVNLIHwgd3JpdGVfbWFzayksIG1hc2tfY2hhcik7CiAgICAgICAgICAgICAgICBpZiAoIXdyaXRlX21hc2spIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJ0bXAwJXMgPSAoIiwgbWFza19jaGFyKTsKICAgICAgICAgICAgICAgIHRlbXBfZGVzdGluYXRpb24gPSBUUlVFOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgd3JpdGVfbWFzayA9IHNoYWRlcl9nbHNsX2FwcGVuZF9kc3RfZXh0KGFyZy0+YnVmZmVyLCBhcmcsIGFyZy0+ZHN0ICYgKH5XSU5FRDNEU1BfU1dJWlpMRV9NQVNLIHwgd3JpdGVfbWFzaykpOwogICAgICAgICAgICAgICAgaWYgKCF3cml0ZV9tYXNrKSBjb250aW51ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBjbXBfY2hhbm5lbCwgJnNyYzBfcGFyYW0pOwogICAgICAgICAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMV0sIGFyZy0+c3JjX2FkZHJbMV0sIHdyaXRlX21hc2ssICZzcmMxX3BhcmFtKTsKICAgICAgICAgICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzJdLCBhcmctPnNyY19hZGRyWzJdLCB3cml0ZV9tYXNrLCAmc3JjMl9wYXJhbSk7CgogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgIiVzID49IDAuMCA/ICVzIDogJXMpO1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgc3JjMF9wYXJhbS5wYXJhbV9zdHIsIHNyYzFfcGFyYW0ucGFyYW1fc3RyLCBzcmMyX3BhcmFtLnBhcmFtX3N0cik7CiAgICAgICAgfQoKICAgICAgICBpZih0ZW1wX2Rlc3RpbmF0aW9uKSB7CiAgICAgICAgICAgIHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrKGFyZy0+ZHN0LCBtYXNrX2NoYXIpOwogICAgICAgICAgICBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0X2V4dChhcmctPmJ1ZmZlciwgYXJnLCBhcmctPmRzdCk7CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAidG1wMCVzKTtcbiIsIG1hc2tfY2hhcik7CiAgICAgICAgfQogICAgfQoKfQoKLyoqIFByb2Nlc3MgdGhlIENORCBvcGNvZGUgaW4gR0xTTCAoZHN0ID0gKHNyYzAgPiAwLjUpID8gc3JjMSA6IHNyYzIpICovCi8qIEZvciBwcyAxLjEtMS4zLCBvbmx5IGEgc2luZ2xlIGNvbXBvbmVudCBvZiBzcmMwIGlzIHVzZWQuIEZvciBwcyAxLjQKICogdGhlIGNvbXBhcmUgaXMgZG9uZSBwZXIgY29tcG9uZW50IG9mIHNyYzAuICovCnZvaWQgc2hhZGVyX2dsc2xfY25kKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIElXaW5lRDNEQmFzZVNoYWRlckltcGwqIHNoYWRlciA9IChJV2luZUQzREJhc2VTaGFkZXJJbXBsKikgYXJnLT5zaGFkZXI7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW07CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzFfcGFyYW07CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzJfcGFyYW07CiAgICBEV09SRCB3cml0ZV9tYXNrLCBjbXBfY2hhbm5lbCA9IDA7CiAgICB1bnNpZ25lZCBpbnQgaSwgajsKCiAgICBpZiAoc2hhZGVyLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uIDwgV0lORUQzRFBTX1ZFUlNJT04oMSwgNCkpIHsKICAgICAgICB3cml0ZV9tYXNrID0gc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChhcmctPmJ1ZmZlciwgYXJnKTsKICAgICAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfMCwgJnNyYzBfcGFyYW0pOwogICAgICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1sxXSwgYXJnLT5zcmNfYWRkclsxXSwgd3JpdGVfbWFzaywgJnNyYzFfcGFyYW0pOwogICAgICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1syXSwgYXJnLT5zcmNfYWRkclsyXSwgd3JpdGVfbWFzaywgJnNyYzJfcGFyYW0pOwoKICAgICAgICAvKiBGdW46IFRoZSBEM0RTSV9DT0lTU1VFIGZsYWcgY2hhbmdlcyB0aGUgc2VtYW50aWMgb2YgdGhlIGNuZCBpbnN0cnVjdGlvbiBmb3IgPCAxLjQgc2hhZGVycyAqLwogICAgICAgIGlmKGFyZy0+b3Bjb2RlX3Rva2VuICYgV0lORUQzRFNJX0NPSVNTVUUpIHsKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICIlcyAvKiBDT0lTU1VFISAqLyk7XG4iLCBzcmMxX3BhcmFtLnBhcmFtX3N0cik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICIlcyA+IDAuNSA/ICVzIDogJXMpO1xuIiwKICAgICAgICAgICAgICAgICAgICBzcmMwX3BhcmFtLnBhcmFtX3N0ciwgc3JjMV9wYXJhbS5wYXJhbV9zdHIsIHNyYzJfcGFyYW0ucGFyYW1fc3RyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgLyogQ3ljbGUgdGhyb3VnaCBhbGwgc291cmNlMCBjaGFubmVscyAqLwogICAgZm9yIChpPTA7IGk8NDsgaSsrKSB7CiAgICAgICAgd3JpdGVfbWFzayA9IDA7CiAgICAgICAgLyogRmluZCB0aGUgZGVzdGluYXRpb24gY2hhbm5lbHMgd2hpY2ggdXNlIHRoZSBjdXJyZW50IHNvdXJjZTAgY2hhbm5lbCAqLwogICAgICAgIGZvciAoaj0wOyBqPDQ7IGorKykgewogICAgICAgICAgICBpZiAoICgoYXJnLT5zcmNbMF0gPj4gKFdJTkVEM0RTUF9TV0laWkxFX1NISUZUICsgMipqKSkgJiAweDMpID09IGkgKSB7CiAgICAgICAgICAgICAgICB3cml0ZV9tYXNrIHw9IFdJTkVEM0RTUF9XUklURU1BU0tfMCA8PCBqOwogICAgICAgICAgICAgICAgY21wX2NoYW5uZWwgPSBXSU5FRDNEU1BfV1JJVEVNQVNLXzAgPDwgajsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB3cml0ZV9tYXNrID0gc2hhZGVyX2dsc2xfYXBwZW5kX2RzdF9leHQoYXJnLT5idWZmZXIsIGFyZywgYXJnLT5kc3QgJiAofldJTkVEM0RTUF9TV0laWkxFX01BU0sgfCB3cml0ZV9tYXNrKSk7CiAgICAgICAgaWYgKCF3cml0ZV9tYXNrKSBjb250aW51ZTsKCiAgICAgICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBjbXBfY2hhbm5lbCwgJnNyYzBfcGFyYW0pOwogICAgICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1sxXSwgYXJnLT5zcmNfYWRkclsxXSwgd3JpdGVfbWFzaywgJnNyYzFfcGFyYW0pOwogICAgICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1syXSwgYXJnLT5zcmNfYWRkclsyXSwgd3JpdGVfbWFzaywgJnNyYzJfcGFyYW0pOwoKICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgIiVzID4gMC41ID8gJXMgOiAlcyk7XG4iLAogICAgICAgICAgICAgICAgc3JjMF9wYXJhbS5wYXJhbV9zdHIsIHNyYzFfcGFyYW0ucGFyYW1fc3RyLCBzcmMyX3BhcmFtLnBhcmFtX3N0cik7CiAgICB9Cn0KCi8qKiBHTFNMIGNvZGUgZ2VuZXJhdGlvbiBmb3IgV0lORUQzRFNJT19NQUQ6IE11bHRpcGx5IHRoZSBmaXJzdCAyIG9wY29kZXMsIHRoZW4gYWRkIHRoZSBsYXN0ICovCnZvaWQgc2hhZGVyX2dsc2xfbWFkKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMF9wYXJhbTsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMV9wYXJhbTsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMl9wYXJhbTsKICAgIERXT1JEIHdyaXRlX21hc2s7CgogICAgd3JpdGVfbWFzayA9IHNoYWRlcl9nbHNsX2FwcGVuZF9kc3QoYXJnLT5idWZmZXIsIGFyZyk7CiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIHdyaXRlX21hc2ssICZzcmMwX3BhcmFtKTsKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1sxXSwgYXJnLT5zcmNfYWRkclsxXSwgd3JpdGVfbWFzaywgJnNyYzFfcGFyYW0pOwogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzJdLCBhcmctPnNyY19hZGRyWzJdLCB3cml0ZV9tYXNrLCAmc3JjMl9wYXJhbSk7CiAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgIiglcyAqICVzKSArICVzKTtcbiIsCiAgICAgICAgICAgIHNyYzBfcGFyYW0ucGFyYW1fc3RyLCBzcmMxX3BhcmFtLnBhcmFtX3N0ciwgc3JjMl9wYXJhbS5wYXJhbV9zdHIpOwp9CgovKiogSGFuZGxlcyB0cmFuc2Zvcm1pbmcgYWxsIFdJTkVEM0RTSU9fTT94PyBvcGNvZGVzIGZvciAKICAgIFZlcnRleCBzaGFkZXJzIHRvIEdMU0wgY29kZXMgKi8Kdm9pZCBzaGFkZXJfZ2xzbF9tbnhuKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIGludCBpOwogICAgaW50IG5Db21wb25lbnRzID0gMDsKICAgIFNIQURFUl9PUENPREVfQVJHIHRtcEFyZzsKICAgCiAgICBtZW1zZXQoJnRtcEFyZywgMCwgc2l6ZW9mKFNIQURFUl9PUENPREVfQVJHKSk7CgogICAgLyogU2V0IGNvbnN0YW50cyBmb3IgdGhlIHRlbXBvcmFyeSBhcmd1bWVudCAqLwogICAgdG1wQXJnLnNoYWRlciAgICAgID0gYXJnLT5zaGFkZXI7CiAgICB0bXBBcmcuYnVmZmVyICAgICAgPSBhcmctPmJ1ZmZlcjsKICAgIHRtcEFyZy5zcmNbMF0gICAgICA9IGFyZy0+c3JjWzBdOwogICAgdG1wQXJnLnNyY19hZGRyWzBdID0gYXJnLT5zcmNfYWRkclswXTsKICAgIHRtcEFyZy5zcmNfYWRkclsxXSA9IGFyZy0+c3JjX2FkZHJbMV07CiAgICB0bXBBcmcucmVnX21hcHMgPSBhcmctPnJlZ19tYXBzOyAKICAgIAogICAgc3dpdGNoKGFyZy0+b3Bjb2RlLT5vcGNvZGUpIHsKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fTTR4NDoKICAgICAgICAgICAgbkNvbXBvbmVudHMgPSA0OwogICAgICAgICAgICB0bXBBcmcub3Bjb2RlID0gc2hhZGVyX2dldF9vcGNvZGUoYXJnLT5zaGFkZXIsIFdJTkVEM0RTSU9fRFA0KTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX000eDM6CiAgICAgICAgICAgIG5Db21wb25lbnRzID0gMzsKICAgICAgICAgICAgdG1wQXJnLm9wY29kZSA9IHNoYWRlcl9nZXRfb3Bjb2RlKGFyZy0+c2hhZGVyLCBXSU5FRDNEU0lPX0RQNCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgV0lORUQzRFNJT19NM3g0OgogICAgICAgICAgICBuQ29tcG9uZW50cyA9IDQ7CiAgICAgICAgICAgIHRtcEFyZy5vcGNvZGUgPSBzaGFkZXJfZ2V0X29wY29kZShhcmctPnNoYWRlciwgV0lORUQzRFNJT19EUDMpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFdJTkVEM0RTSU9fTTN4MzoKICAgICAgICAgICAgbkNvbXBvbmVudHMgPSAzOwogICAgICAgICAgICB0bXBBcmcub3Bjb2RlID0gc2hhZGVyX2dldF9vcGNvZGUoYXJnLT5zaGFkZXIsIFdJTkVEM0RTSU9fRFAzKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBXSU5FRDNEU0lPX00zeDI6CiAgICAgICAgICAgIG5Db21wb25lbnRzID0gMjsKICAgICAgICAgICAgdG1wQXJnLm9wY29kZSA9IHNoYWRlcl9nZXRfb3Bjb2RlKGFyZy0+c2hhZGVyLCBXSU5FRDNEU0lPX0RQMyk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGJyZWFrOwogICAgfQoKICAgIGZvciAoaSA9IDA7IGkgPCBuQ29tcG9uZW50czsgaSsrKSB7CiAgICAgICAgdG1wQXJnLmRzdCA9ICgoYXJnLT5kc3QpICYgfldJTkVEM0RTUF9XUklURU1BU0tfQUxMKXwoV0lORUQzRFNQX1dSSVRFTUFTS18wPDxpKTsKICAgICAgICB0bXBBcmcuc3JjWzFdICAgICAgPSBhcmctPnNyY1sxXStpOwogICAgICAgIHNoYWRlcl9nbHNsX2RvdCgmdG1wQXJnKTsKICAgIH0KfQoKLyoqCiAgICBUaGUgTFJQIGluc3RydWN0aW9uIHBlcmZvcm1zIGEgY29tcG9uZW50LXdpc2UgbGluZWFyIGludGVycG9sYXRpb24gCiAgICBiZXR3ZWVuIHRoZSBzZWNvbmQgYW5kIHRoaXJkIG9wZXJhbmRzIHVzaW5nIHRoZSBmaXJzdCBvcGVyYW5kIGFzIHRoZQogICAgYmxlbmQgZmFjdG9yLiAgRXF1YXRpb246ICAoZHN0ID0gc3JjMiArIHNyYzAgKiAoc3JjMSAtIHNyYzIpKQogICAgVGhpcyBpcyBlcXVpdmFsZW50IHRvIG1peChzcmMyLCBzcmMxLCBzcmMwKTsKKi8Kdm9pZCBzaGFkZXJfZ2xzbF9scnAoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMwX3BhcmFtOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMxX3BhcmFtOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMyX3BhcmFtOwogICAgRFdPUkQgd3JpdGVfbWFzazsKCiAgICB3cml0ZV9tYXNrID0gc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChhcmctPmJ1ZmZlciwgYXJnKTsKCiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIHdyaXRlX21hc2ssICZzcmMwX3BhcmFtKTsKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1sxXSwgYXJnLT5zcmNfYWRkclsxXSwgd3JpdGVfbWFzaywgJnNyYzFfcGFyYW0pOwogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzJdLCBhcmctPnNyY19hZGRyWzJdLCB3cml0ZV9tYXNrLCAmc3JjMl9wYXJhbSk7CgogICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJtaXgoJXMsICVzLCAlcykpO1xuIiwKICAgICAgICAgICAgc3JjMl9wYXJhbS5wYXJhbV9zdHIsIHNyYzFfcGFyYW0ucGFyYW1fc3RyLCBzcmMwX3BhcmFtLnBhcmFtX3N0cik7Cn0KCi8qKiBQcm9jZXNzIHRoZSBXSU5FRDNEU0lPX0xJVCBpbnN0cnVjdGlvbiBpbiBHTFNMOgogKiBkc3QueCA9IGRzdC53ID0gMS4wCiAqIGRzdC55ID0gKHNyYzAueCA+IDApID8gc3JjMC54CiAqIGRzdC56ID0gKHNyYzAueCA+IDApID8gKChzcmMwLnkgPiAwKSA/IHBvdyhzcmMwLnksIHNyYy53KSA6IDApIDogMAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGVyZSBzcmMudyBpcyBjbGFtcGVkIGF0ICstIDEyOAogKi8Kdm9pZCBzaGFkZXJfZ2xzbF9saXQoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMwX3BhcmFtOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMxX3BhcmFtOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMzX3BhcmFtOwogICAgY2hhciBkc3RfbWFza1s2XTsKCiAgICBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGFyZy0+YnVmZmVyLCBhcmcpOwogICAgc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2soYXJnLT5kc3QsIGRzdF9tYXNrKTsKCiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfMCwgJnNyYzBfcGFyYW0pOwogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBXSU5FRDNEU1BfV1JJVEVNQVNLXzEsICZzcmMxX3BhcmFtKTsKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgV0lORUQzRFNQX1dSSVRFTUFTS18zLCAmc3JjM19wYXJhbSk7CgogICAgLyogVGhlIHNkayBzcGVjaWZpZXMgdGhlIGluc3RydWN0aW9uIGxpa2UgdGhpcwogICAgICogZHN0LnggPSAxLjA7CiAgICAgKiBpZihzcmMueCA+IDAuMCkgZHN0LnkgPSBzcmMueAogICAgICogZWxzZSBkc3QueSA9IDAuMC4KICAgICAqIGlmKHNyYy54ID4gMC4wICYmIHNyYy55ID4gMC4wKSBkc3QueiA9IHBvdyhzcmMueSwgcG93ZXIpOwogICAgICogZWxzZSBkc3QueiA9IDAuMDsKICAgICAqIGRzdC53ID0gMS4wOwogICAgICoKICAgICAqIE9idmlvdXNseSB0aGF0IGhhcyBxdWl0ZSBhIGZldyBjb25kaXRpb25hbHMgaW4gaXQgd2hpY2ggd2UgZG9uJ3QgbGlrZS4gU28gdGhlIGZpcnN0IHN0ZXAgaXMgdGhpczoKICAgICAqIGRzdC54ID0gMS4wICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLiBObyBmdXJ0aGVyIGV4cGxhbmF0aW9uIG5lZWRlZAogICAgICogZHN0LnkgPSBtYXgoc3JjLnksIDAuMCk7ICAgICAgICAgICAgICAgICAgICAgLi4uIElmIHggPCAwLjAsIHVzZSAwLjAsIG90aGVyd2lzZSB4LiBTYW1lIGFzIHRoZSBjb25kaXRpb25hbAogICAgICogZHN0LnogPSB4ID4gMC4wID8gcG93KG1heCh5LCAwLjApLCBwKSA6IDA7ICAgLi4uIDAgXiBwb3dlciBpcyAwLCBhbmQgb3RoZXJ3aXNlIHdlIHVzZSB5IGFueXdheQogICAgICogZHN0LncgPSAxLjAuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uIE5vdGhpbmcgZmFuY3kuCiAgICAgKgogICAgICogU28gd2Ugc3RpbGwgaGF2ZSBvbmUgY29uZGl0aW9uYWwgaW4gdGhlcmUuIFNvIGRvIHRoaXM6CiAgICAgKiBkc3QueiA9IHBvdyhtYXgoMC4wLCBzcmMueSkgKiBzdGVwKDAuMCwgc3JjLngpLCBwb3dlcik7CiAgICAgKgogICAgICogc3RlcCgwLjAsIHgpIHdpbGwgcmV0dXJuIDEgaWYgc3JjLnggPiAwLjAsIGFuZCAwIG90aGVyd2lzZS4gU28gaWYgeSBpcyAwIHdlIGdldCBwb3coMC4wICogMS4wLCBwb3dlciksCiAgICAgKiB3aGljaCBzZXRzIGRzdC56IHRvIDAuIElmIHkgPiAwLCBidXQgeCA9IDAuMCwgd2UgZ2V0IHBvdyh5ICogMC4wLCBwb3dlciksIHdoaWNoIHJlc3VsdHMgaW4gMCB0b28uCiAgICAgKiBpZiBib3RoIHggYW5kIHkgYXJlID4gMCwgd2UgZ2V0IHBvdyh5ICogMS4wLCBwb3dlciksIGFzIGl0IGlzIHN1cHBvc2VkIHRvCiAgICAgKi8KICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAidmVjNCgxLjAsIG1heCglcywgMC4wKSwgcG93KG1heCgwLjAsICVzKSAqIHN0ZXAoMC4wLCAlcyksIGNsYW1wKCVzLCAtMTI4LjAsIDEyOC4wKSksIDEuMCklcyk7XG4iLAogICAgICAgICAgICAgICAgICAgc3JjMF9wYXJhbS5wYXJhbV9zdHIsIHNyYzFfcGFyYW0ucGFyYW1fc3RyLCBzcmMwX3BhcmFtLnBhcmFtX3N0ciwgc3JjM19wYXJhbS5wYXJhbV9zdHIsIGRzdF9tYXNrKTsKfQoKLyoqIFByb2Nlc3MgdGhlIFdJTkVEM0RTSU9fRFNUIGluc3RydWN0aW9uIGluIEdMU0w6CiAqIGRzdC54ID0gMS4wCiAqIGRzdC55ID0gc3JjMC54ICogc3JjMC55CiAqIGRzdC56ID0gc3JjMC56CiAqIGRzdC53ID0gc3JjMS53CiAqLwp2b2lkIHNoYWRlcl9nbHNsX2RzdChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzB5X3BhcmFtOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMwel9wYXJhbTsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMXlfcGFyYW07CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzF3X3BhcmFtOwogICAgY2hhciBkc3RfbWFza1s2XTsKCiAgICBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGFyZy0+YnVmZmVyLCBhcmcpOwogICAgc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2soYXJnLT5kc3QsIGRzdF9tYXNrKTsKCiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfMSwgJnNyYzB5X3BhcmFtKTsKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgV0lORUQzRFNQX1dSSVRFTUFTS18yLCAmc3JjMHpfcGFyYW0pOwogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzFdLCBhcmctPnNyY19hZGRyWzFdLCBXSU5FRDNEU1BfV1JJVEVNQVNLXzEsICZzcmMxeV9wYXJhbSk7CiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMV0sIGFyZy0+c3JjX2FkZHJbMV0sIFdJTkVEM0RTUF9XUklURU1BU0tfMywgJnNyYzF3X3BhcmFtKTsKCiAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgInZlYzQoMS4wLCAlcyAqICVzLCAlcywgJXMpKSVzO1xuIiwKICAgICAgICAgICAgc3JjMHlfcGFyYW0ucGFyYW1fc3RyLCBzcmMxeV9wYXJhbS5wYXJhbV9zdHIsIHNyYzB6X3BhcmFtLnBhcmFtX3N0ciwgc3JjMXdfcGFyYW0ucGFyYW1fc3RyLCBkc3RfbWFzayk7Cn0KCi8qKiBQcm9jZXNzIHRoZSBXSU5FRDNEU0lPX1NJTkNPUyBpbnN0cnVjdGlvbiBpbiBHTFNMOgogKiBWUyAyLjAgcmVxdWlyZXMgdGhhdCBzcGVjaWZpYyBjb3NpbmUgYW5kIHNpbmUgY29uc3RhbnRzIGJlIHBhc3NlZCB0byB0aGlzIGluc3RydWN0aW9uIHNvIHRoZSBoYXJkd2FyZQogKiBjYW4gaGFuZGxlIGl0LiAgQnV0LCB0aGVzZSBmdW5jdGlvbnMgYXJlIGJ1aWx0LWluIGZvciBHTFNMLCBzbyB3ZSBjYW4ganVzdCBpZ25vcmUgdGhlIGxhc3QgMiBwYXJhbXMuCiAqIAogKiBkc3QueCA9IGNvcyhzcmMwLj8pCiAqIGRzdC55ID0gc2luKHNyYzAuPykKICogZHN0LnogPSBkc3QuegogKiBkc3QudyA9IGRzdC53CiAqLwp2b2lkIHNoYWRlcl9nbHNsX3NpbmNvcyhTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW07CiAgICBEV09SRCB3cml0ZV9tYXNrOwoKICAgIHdyaXRlX21hc2sgPSBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGFyZy0+YnVmZmVyLCBhcmcpOwogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBXSU5FRDNEU1BfV1JJVEVNQVNLXzAsICZzcmMwX3BhcmFtKTsKCiAgICBzd2l0Y2ggKHdyaXRlX21hc2spIHsKICAgICAgICBjYXNlIFdJTkVEM0RTUF9XUklURU1BU0tfMDoKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJjb3MoJXMpKTtcbiIsIHNyYzBfcGFyYW0ucGFyYW1fc3RyKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgV0lORUQzRFNQX1dSSVRFTUFTS18xOgogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgInNpbiglcykpO1xuIiwgc3JjMF9wYXJhbS5wYXJhbV9zdHIpOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSAoV0lORUQzRFNQX1dSSVRFTUFTS18wIHwgV0lORUQzRFNQX1dSSVRFTUFTS18xKToKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJ2ZWMyKGNvcyglcyksIHNpbiglcykpKTtcbiIsIHNyYzBfcGFyYW0ucGFyYW1fc3RyLCBzcmMwX3BhcmFtLnBhcmFtX3N0cik7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBFUlIoIldyaXRlIG1hc2sgc2hvdWxkIGJlIC54LCAueSBvciAueHlcbiIpOwogICAgICAgICAgICBicmVhazsKICAgIH0KfQoKLyoqIFByb2Nlc3MgdGhlIFdJTkVEM0RTSU9fTE9PUCBpbnN0cnVjdGlvbiBpbiBHTFNMOgogKiBTdGFydCBhIGZvcigpIGxvb3Agd2hlcmUgc3JjMS55IGlzIHRoZSBpbml0aWFsIHZhbHVlIG9mIGFMLAogKiAgaW5jcmVtZW50IGFMIGJ5IHNyYzEueiBmb3IgYSB0b3RhbCBvZiBzcmMxLnggaXRlcmF0aW9ucy4KICogIE5lZWQgdG8gdXNlIGEgdGVtcG9yYXJ5IHZhcmlhYmxlIGZvciB0aGlzIG9wZXJhdGlvbi4KICovCi8qIEZJWE1FOiBJIGRvbid0IHRoaW5rIG5lc3RlZCBsb29wcyB3aWxsIHdvcmsgY29ycmVjdGx5IHRoaXMgd2F5LiAqLwp2b2lkIHNoYWRlcl9nbHNsX2xvb3AoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMxX3BhcmFtOwogICAgSVdpbmVEM0RCYXNlU2hhZGVySW1wbCogc2hhZGVyID0gKElXaW5lRDNEQmFzZVNoYWRlckltcGwqKSBhcmctPnNoYWRlcjsKICAgIERXT1JEIHJlZ3R5cGUgPSBzaGFkZXJfZ2V0X3JlZ3R5cGUoYXJnLT5zcmNbMV0pOwogICAgRFdPUkQgcmVnID0gYXJnLT5zcmNbMV0gJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICBjb25zdCBEV09SRCAqY29udHJvbF92YWx1ZXMgPSBOVUxMOwogICAgbG9jYWxfY29uc3RhbnQgKmNvbnN0YW50OwoKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1sxXSwgYXJnLT5zcmNfYWRkclsxXSwgV0lORUQzRFNQX1dSSVRFTUFTS19BTEwsICZzcmMxX3BhcmFtKTsKCiAgICAvKiBUcnkgdG8gaGFyZGNvZGUgdGhlIGxvb3AgY29udHJvbCBwYXJhbWV0ZXJzIGlmIHBvc3NpYmxlLiBEaXJlY3QzRCA5IGNsYXNzIGhhcmR3YXJlIGRvZXNuJ3Qgc3VwcG9ydCByZWFsCiAgICAgKiB2YXJ5aW5nIGluZGV4aW5nLCBidXQgTWljcm9zb2Z0IGRlc2lnbmVkIHRoaXMgZmVhdHVyZSBmb3IgU2hhZGVyIG1vZGVsIDIueCsuIElmIHRoZSBsb29wIGNvbnRyb2wgaXMKICAgICAqIGtub3duIGF0IGNvbXBpbGUgdGltZSwgdGhlIEdMU0wgY29tcGlsZXIgY2FuIHVucm9sbCB0aGUgbG9vcCwgYW5kIHJlcGxhY2UgaW5kaXJlY3QgYWRkcmVzc2luZyB3aXRoIGRpcmVjdAogICAgICogYWRkcmVzc2luZy4KICAgICAqLwogICAgaWYocmVndHlwZSA9PSBXSU5FRDNEU1BSX0NPTlNUSU5UKSB7CiAgICAgICAgTElTVF9GT1JfRUFDSF9FTlRSWShjb25zdGFudCwgJnNoYWRlci0+YmFzZVNoYWRlci5jb25zdGFudHNJLCBsb2NhbF9jb25zdGFudCwgZW50cnkpIHsKICAgICAgICAgICAgaWYoY29uc3RhbnQtPmlkeCA9PSByZWcpIHsKICAgICAgICAgICAgICAgIGNvbnRyb2xfdmFsdWVzID0gY29uc3RhbnQtPnZhbHVlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgaWYoY29udHJvbF92YWx1ZXMpIHsKICAgICAgICBpZihjb250cm9sX3ZhbHVlc1syXSA+IDApIHsKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJmb3IgKGFMJXUgPSAlZDsgYUwldSA8ICglZCAqICVkICsgJWQpOyBhTCV1ICs9ICVkKSB7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzaGFkZXItPmJhc2VTaGFkZXIuY3VyX2xvb3BfZGVwdGgsIGNvbnRyb2xfdmFsdWVzWzFdLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzaGFkZXItPmJhc2VTaGFkZXIuY3VyX2xvb3BfZGVwdGgsIGNvbnRyb2xfdmFsdWVzWzBdLCBjb250cm9sX3ZhbHVlc1syXSwgY29udHJvbF92YWx1ZXNbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYWRlci0+YmFzZVNoYWRlci5jdXJfbG9vcF9kZXB0aCwgY29udHJvbF92YWx1ZXNbMl0pOwogICAgICAgIH0gZWxzZSBpZihjb250cm9sX3ZhbHVlc1syXSA9PSAwKSB7CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiZm9yIChhTCV1ID0gJWQsIHRtcEludCV1ID0gMDsgdG1wSW50JXUgPCAlZDsgdG1wSW50JXUrKykge1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhZGVyLT5iYXNlU2hhZGVyLmN1cl9sb29wX2RlcHRoLCBjb250cm9sX3ZhbHVlc1sxXSwgc2hhZGVyLT5iYXNlU2hhZGVyLmN1cl9sb29wX2RlcHRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzaGFkZXItPmJhc2VTaGFkZXIuY3VyX2xvb3BfZGVwdGgsIGNvbnRyb2xfdmFsdWVzWzBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzaGFkZXItPmJhc2VTaGFkZXIuY3VyX2xvb3BfZGVwdGgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiZm9yIChhTCV1ID0gJWQ7IGFMJXUgPiAoJWQgKiAlZCArICVkKTsgYUwldSArPSAlZCkge1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhZGVyLT5iYXNlU2hhZGVyLmN1cl9sb29wX2RlcHRoLCBjb250cm9sX3ZhbHVlc1sxXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhZGVyLT5iYXNlU2hhZGVyLmN1cl9sb29wX2RlcHRoLCBjb250cm9sX3ZhbHVlc1swXSwgY29udHJvbF92YWx1ZXNbMl0sIGNvbnRyb2xfdmFsdWVzWzFdLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzaGFkZXItPmJhc2VTaGFkZXIuY3VyX2xvb3BfZGVwdGgsIGNvbnRyb2xfdmFsdWVzWzJdKTsKICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiZm9yICh0bXBJbnQldSA9IDAsIGFMJXUgPSAlcy55OyB0bXBJbnQldSA8ICVzLng7IHRtcEludCV1KyssIGFMJXUgKz0gJXMueikge1xuIiwKICAgICAgICAgICAgICAgICAgICAgICBzaGFkZXItPmJhc2VTaGFkZXIuY3VyX2xvb3BfZGVwdGgsIHNoYWRlci0+YmFzZVNoYWRlci5jdXJfbG9vcF9yZWdubywKICAgICAgICAgICAgICAgICAgICAgICBzcmMxX3BhcmFtLnJlZ19uYW1lLCBzaGFkZXItPmJhc2VTaGFkZXIuY3VyX2xvb3BfZGVwdGgsIHNyYzFfcGFyYW0ucmVnX25hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgc2hhZGVyLT5iYXNlU2hhZGVyLmN1cl9sb29wX2RlcHRoLCBzaGFkZXItPmJhc2VTaGFkZXIuY3VyX2xvb3BfcmVnbm8sIHNyYzFfcGFyYW0ucmVnX25hbWUpOwogICAgfQoKICAgIHNoYWRlci0+YmFzZVNoYWRlci5jdXJfbG9vcF9kZXB0aCsrOwogICAgc2hhZGVyLT5iYXNlU2hhZGVyLmN1cl9sb29wX3JlZ25vKys7Cn0KCnZvaWQgc2hhZGVyX2dsc2xfZW5kKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIElXaW5lRDNEQmFzZVNoYWRlckltcGwqIHNoYWRlciA9IChJV2luZUQzREJhc2VTaGFkZXJJbXBsKikgYXJnLT5zaGFkZXI7CgogICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJ9XG4iKTsKCiAgICBpZihhcmctPm9wY29kZS0+b3Bjb2RlID09IFdJTkVEM0RTSU9fRU5ETE9PUCkgewogICAgICAgIHNoYWRlci0+YmFzZVNoYWRlci5jdXJfbG9vcF9kZXB0aC0tOwogICAgICAgIHNoYWRlci0+YmFzZVNoYWRlci5jdXJfbG9vcF9yZWduby0tOwogICAgfQogICAgaWYoYXJnLT5vcGNvZGUtPm9wY29kZSA9PSBXSU5FRDNEU0lPX0VORFJFUCkgewogICAgICAgIHNoYWRlci0+YmFzZVNoYWRlci5jdXJfbG9vcF9kZXB0aC0tOwogICAgfQp9Cgp2b2lkIHNoYWRlcl9nbHNsX3JlcChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBJV2luZUQzREJhc2VTaGFkZXJJbXBsKiBzaGFkZXIgPSAoSVdpbmVEM0RCYXNlU2hhZGVySW1wbCopIGFyZy0+c2hhZGVyOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMwX3BhcmFtOwoKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgV0lORUQzRFNQX1dSSVRFTUFTS18wLCAmc3JjMF9wYXJhbSk7CiAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgImZvciAodG1wSW50JWQgPSAwOyB0bXBJbnQlZCA8ICVzOyB0bXBJbnQlZCsrKSB7XG4iLAogICAgICAgICAgICAgICAgICAgc2hhZGVyLT5iYXNlU2hhZGVyLmN1cl9sb29wX2RlcHRoLCBzaGFkZXItPmJhc2VTaGFkZXIuY3VyX2xvb3BfZGVwdGgsCiAgICAgICAgICAgICAgICAgICBzcmMwX3BhcmFtLnBhcmFtX3N0ciwgc2hhZGVyLT5iYXNlU2hhZGVyLmN1cl9sb29wX2RlcHRoKTsKICAgIHNoYWRlci0+YmFzZVNoYWRlci5jdXJfbG9vcF9kZXB0aCsrOwp9Cgp2b2lkIHNoYWRlcl9nbHNsX2lmKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMF9wYXJhbTsKCiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfMCwgJnNyYzBfcGFyYW0pOwogICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJpZiAoJXMpIHtcbiIsIHNyYzBfcGFyYW0ucGFyYW1fc3RyKTsKfQoKdm9pZCBzaGFkZXJfZ2xzbF9pZmMoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMwX3BhcmFtOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMxX3BhcmFtOwoKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgV0lORUQzRFNQX1dSSVRFTUFTS18wLCAmc3JjMF9wYXJhbSk7CiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMV0sIGFyZy0+c3JjX2FkZHJbMV0sIFdJTkVEM0RTUF9XUklURU1BU0tfMCwgJnNyYzFfcGFyYW0pOwoKICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiaWYgKCVzICVzICVzKSB7XG4iLAogICAgICAgICAgICBzcmMwX3BhcmFtLnBhcmFtX3N0ciwgc2hhZGVyX2dldF9jb21wX29wKGFyZy0+b3Bjb2RlX3Rva2VuKSwgc3JjMV9wYXJhbS5wYXJhbV9zdHIpOwp9Cgp2b2lkIHNoYWRlcl9nbHNsX2Vsc2UoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJ9IGVsc2Uge1xuIik7Cn0KCnZvaWQgc2hhZGVyX2dsc2xfYnJlYWsoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJicmVhaztcbiIpOwp9CgovKiBGSVhNRTogQWNjb3JkaW5nIHRvIE1TRE4gdGhlIGNvbXBhcmUgaXMgZG9uZSBwZXIgY29tcG9uZW50LiAqLwp2b2lkIHNoYWRlcl9nbHNsX2JyZWFrYyhTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW07CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzFfcGFyYW07CgogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBXSU5FRDNEU1BfV1JJVEVNQVNLXzAsICZzcmMwX3BhcmFtKTsKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1sxXSwgYXJnLT5zcmNfYWRkclsxXSwgV0lORUQzRFNQX1dSSVRFTUFTS18wLCAmc3JjMV9wYXJhbSk7CgogICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJpZiAoJXMgJXMgJXMpIGJyZWFrO1xuIiwKICAgICAgICAgICAgc3JjMF9wYXJhbS5wYXJhbV9zdHIsIHNoYWRlcl9nZXRfY29tcF9vcChhcmctPm9wY29kZV90b2tlbiksIHNyYzFfcGFyYW0ucGFyYW1fc3RyKTsKfQoKdm9pZCBzaGFkZXJfZ2xzbF9sYWJlbChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CgogICAgRFdPUkQgc251bSA9IChhcmctPnNyY1swXSkgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgIn1cbiIpOwogICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJ2b2lkIHN1YnJvdXRpbmUldSAoKSB7XG4iLCAgc251bSk7Cn0KCnZvaWQgc2hhZGVyX2dsc2xfY2FsbChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBEV09SRCBzbnVtID0gKGFyZy0+c3JjWzBdKSAmIFdJTkVEM0RTUF9SRUdOVU1fTUFTSzsKICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAic3Vicm91dGluZSV1KCk7XG4iLCBzbnVtKTsKfQoKdm9pZCBzaGFkZXJfZ2xzbF9jYWxsbnooU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMxX3BhcmFtOwoKICAgIERXT1JEIHNudW0gPSAoYXJnLT5zcmNbMF0pICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzFdLCBhcmctPnNyY19hZGRyWzFdLCBXSU5FRDNEU1BfV1JJVEVNQVNLXzAsICZzcmMxX3BhcmFtKTsKICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiaWYgKCVzKSBzdWJyb3V0aW5lJXUoKTtcbiIsIHNyYzFfcGFyYW0ucGFyYW1fc3RyLCBzbnVtKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBQaXhlbCBTaGFkZXIgU3BlY2lmaWMgQ29kZSBiZWdpbnMgaGVyZQogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnZvaWQgcHNoYWRlcl9nbHNsX3RleChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCogVGhpcyA9IChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCopIGFyZy0+c2hhZGVyOwogICAgSVdpbmVEM0REZXZpY2VJbXBsKiBkZXZpY2VJbXBsID0gKElXaW5lRDNERGV2aWNlSW1wbCopIFRoaXMtPmJhc2VTaGFkZXIuZGV2aWNlOwogICAgRFdPUkQgaGV4X3ZlcnNpb24gPSBUaGlzLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uOwogICAgY2hhciBkc3Rfc3dpenpsZVs2XTsKICAgIGdsc2xfc2FtcGxlX2Z1bmN0aW9uX3Qgc2FtcGxlX2Z1bmN0aW9uOwogICAgRFdPUkQgc2FtcGxlcl90eXBlOwogICAgRFdPUkQgc2FtcGxlcl9pZHg7CiAgICBCT09MIHByb2plY3RlZCwgdGV4cmVjdCA9IEZBTFNFOwogICAgRFdPUkQgbWFzayA9IDA7CgogICAgLyogQWxsIHZlcnNpb25zIGhhdmUgYSBkZXN0aW5hdGlvbiByZWdpc3RlciAqLwogICAgc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChhcmctPmJ1ZmZlciwgYXJnKTsKCiAgICAvKiAxLjAtMS40OiBVc2UgZGVzdGluYXRpb24gcmVnaXN0ZXIgYXMgc2FtcGxlciBzb3VyY2UuCiAgICAgKiAyLjArOiBVc2UgcHJvdmlkZWQgc2FtcGxlciBzb3VyY2UuICovCiAgICBpZiAoaGV4X3ZlcnNpb24gPCBXSU5FRDNEUFNfVkVSU0lPTigxLDQpKSB7CiAgICAgICAgRFdPUkQgZmxhZ3M7CgogICAgICAgIHNhbXBsZXJfaWR4ID0gYXJnLT5kc3QgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICAgICAgZmxhZ3MgPSBkZXZpY2VJbXBsLT5zdGF0ZUJsb2NrLT50ZXh0dXJlU3RhdGVbc2FtcGxlcl9pZHhdW1dJTkVEM0RUU1NfVEVYVFVSRVRSQU5TRk9STUZMQUdTXTsKCiAgICAgICAgaWYgKGZsYWdzICYgV0lORUQzRFRURkZfUFJPSkVDVEVEKSB7CiAgICAgICAgICAgIHByb2plY3RlZCA9IFRSVUU7CiAgICAgICAgICAgIHN3aXRjaCAoZmxhZ3MgJiB+V0lORUQzRFRURkZfUFJPSkVDVEVEKSB7CiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RUVEZGX0NPVU5UMTogRklYTUUoIldJTkVEM0RUVEZGX1BST0pFQ1RFRCB3aXRoIFdJTkVEM0RUVEZGX0NPVU5UMT9cbiIpOyBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRFRURkZfQ09VTlQyOiBtYXNrID0gV0lORUQzRFNQX1dSSVRFTUFTS18xOyBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRFRURkZfQ09VTlQzOiBtYXNrID0gV0lORUQzRFNQX1dSSVRFTUFTS18yOyBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRFRURkZfQ09VTlQ0OgogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEVFRGRl9ESVNBQkxFOiBtYXNrID0gV0lORUQzRFNQX1dSSVRFTUFTS18zOyBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHByb2plY3RlZCA9IEZBTFNFOwogICAgICAgIH0KICAgIH0gZWxzZSBpZiAoaGV4X3ZlcnNpb24gPCBXSU5FRDNEUFNfVkVSU0lPTigyLDApKSB7CiAgICAgICAgRFdPUkQgc3JjX21vZCA9IGFyZy0+c3JjWzBdICYgV0lORUQzRFNQX1NSQ01PRF9NQVNLOwogICAgICAgIHNhbXBsZXJfaWR4ID0gYXJnLT5kc3QgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CgogICAgICAgIGlmIChzcmNfbW9kID09IFdJTkVEM0RTUFNNX0RaKSB7CiAgICAgICAgICAgIHByb2plY3RlZCA9IFRSVUU7CiAgICAgICAgICAgIG1hc2sgPSBXSU5FRDNEU1BfV1JJVEVNQVNLXzI7CiAgICAgICAgfSBlbHNlIGlmIChzcmNfbW9kID09IFdJTkVEM0RTUFNNX0RXKSB7CiAgICAgICAgICAgIHByb2plY3RlZCA9IFRSVUU7CiAgICAgICAgICAgIG1hc2sgPSBXSU5FRDNEU1BfV1JJVEVNQVNLXzM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcHJvamVjdGVkID0gRkFMU0U7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBzYW1wbGVyX2lkeCA9IGFyZy0+c3JjWzFdICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgICAgIGlmKGFyZy0+b3Bjb2RlX3Rva2VuICYgV0lORUQzRFNJX1RFWExEX1BST0pFQ1QpIHsKICAgICAgICAgICAgICAgIC8qIHBzIDIuMCB0ZXhsZHAgaW5zdHJ1Y3Rpb24gYWx3YXlzIGRpdmlkZXMgYnkgdGhlIGZvdXJ0aCBjb21wb25lbnQuICovCiAgICAgICAgICAgICAgICBwcm9qZWN0ZWQgPSBUUlVFOwogICAgICAgICAgICAgICAgbWFzayA9IFdJTkVEM0RTUF9XUklURU1BU0tfMzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBwcm9qZWN0ZWQgPSBGQUxTRTsKICAgICAgICB9CiAgICB9CgogICAgaWYoZGV2aWNlSW1wbC0+c3RhdGVCbG9jay0+dGV4dHVyZXNbc2FtcGxlcl9pZHhdICYmCiAgICAgICBJV2luZUQzREJhc2VUZXh0dXJlX0dldFRleHR1cmVEaW1lbnNpb25zKGRldmljZUltcGwtPnN0YXRlQmxvY2stPnRleHR1cmVzW3NhbXBsZXJfaWR4XSkgPT0gR0xfVEVYVFVSRV9SRUNUQU5HTEVfQVJCKSB7CiAgICAgICAgdGV4cmVjdCA9IFRSVUU7CiAgICB9CgogICAgc2FtcGxlcl90eXBlID0gYXJnLT5yZWdfbWFwcy0+c2FtcGxlcnNbc2FtcGxlcl9pZHhdICYgV0lORUQzRFNQX1RFWFRVUkVUWVBFX01BU0s7CiAgICBzaGFkZXJfZ2xzbF9nZXRfc2FtcGxlX2Z1bmN0aW9uKHNhbXBsZXJfdHlwZSwgcHJvamVjdGVkLCB0ZXhyZWN0LCAmc2FtcGxlX2Z1bmN0aW9uKTsKICAgIG1hc2sgfD0gc2FtcGxlX2Z1bmN0aW9uLmNvb3JkX21hc2s7CgogICAgaWYgKGhleF92ZXJzaW9uIDwgV0lORUQzRFBTX1ZFUlNJT04oMiwwKSkgewogICAgICAgIHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrKGFyZy0+ZHN0LCBkc3Rfc3dpenpsZSk7CiAgICB9IGVsc2UgewogICAgICAgIHNoYWRlcl9nbHNsX2dldF9zd2l6emxlKGFyZy0+c3JjWzFdLCBGQUxTRSwgYXJnLT5kc3QsIGRzdF9zd2l6emxlKTsKICAgIH0KCiAgICAvKiAxLjAtMS4zOiBVc2UgZGVzdGluYXRpb24gcmVnaXN0ZXIgYXMgY29vcmRpbmF0ZSBzb3VyY2UuCiAgICAgICAxLjQrOiBVc2UgcHJvdmlkZWQgY29vcmRpbmF0ZSBzb3VyY2UgcmVnaXN0ZXIuICovCiAgICBpZiAoaGV4X3ZlcnNpb24gPCBXSU5FRDNEUFNfVkVSU0lPTigxLDQpKSB7CiAgICAgICAgY2hhciBjb29yZF9tYXNrWzZdOwogICAgICAgIHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrKG1hc2ssIGNvb3JkX21hc2spOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXMoUHNhbXBsZXIldSwgVCV1JXMpJXMpO1xuIiwKICAgICAgICAgICAgICAgIHNhbXBsZV9mdW5jdGlvbi5uYW1lLCBzYW1wbGVyX2lkeCwgc2FtcGxlcl9pZHgsIGNvb3JkX21hc2ssIGRzdF9zd2l6emxlKTsKICAgIH0gZWxzZSB7CiAgICAgICAgZ2xzbF9zcmNfcGFyYW1fdCBjb29yZF9wYXJhbTsKICAgICAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIG1hc2ssICZjb29yZF9wYXJhbSk7CiAgICAgICAgaWYoYXJnLT5vcGNvZGVfdG9rZW4gJiBXSU5FRDNEU0lfVEVYTERfQklBUykgewogICAgICAgICAgICBnbHNsX3NyY19wYXJhbV90IGJpYXM7CiAgICAgICAgICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgV0lORUQzRFNQX1dSSVRFTUFTS18zLCAmYmlhcyk7CgogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgIiVzKFBzYW1wbGVyJXUsICVzLCAlcyklcyk7XG4iLAogICAgICAgICAgICAgICAgICAgIHNhbXBsZV9mdW5jdGlvbi5uYW1lLCBzYW1wbGVyX2lkeCwgY29vcmRfcGFyYW0ucGFyYW1fc3RyLAogICAgICAgICAgICAgICAgICAgIGJpYXMucGFyYW1fc3RyLCBkc3Rfc3dpenpsZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICIlcyhQc2FtcGxlciV1LCAlcyklcyk7XG4iLAogICAgICAgICAgICAgICAgICAgIHNhbXBsZV9mdW5jdGlvbi5uYW1lLCBzYW1wbGVyX2lkeCwgY29vcmRfcGFyYW0ucGFyYW1fc3RyLCBkc3Rfc3dpenpsZSk7CiAgICAgICAgfQogICAgfQp9Cgp2b2lkIHNoYWRlcl9nbHNsX3RleGxkbChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBJV2luZUQzREJhc2VTaGFkZXJJbXBsKiBUaGlzID0gKElXaW5lRDNEQmFzZVNoYWRlckltcGwqKWFyZy0+c2hhZGVyOwogICAgSVdpbmVEM0REZXZpY2VJbXBsKiBkZXZpY2VJbXBsID0gKElXaW5lRDNERGV2aWNlSW1wbCopIFRoaXMtPmJhc2VTaGFkZXIuZGV2aWNlOwogICAgZ2xzbF9zYW1wbGVfZnVuY3Rpb25fdCBzYW1wbGVfZnVuY3Rpb247CiAgICBnbHNsX3NyY19wYXJhbV90IGNvb3JkX3BhcmFtLCBsb2RfcGFyYW07CiAgICBjaGFyIGRzdF9zd2l6emxlWzZdOwogICAgRFdPUkQgc2FtcGxlcl90eXBlOwogICAgRFdPUkQgc2FtcGxlcl9pZHg7CiAgICBCT09MIHRleHJlY3QgPSBGQUxTRTsKCiAgICBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGFyZy0+YnVmZmVyLCBhcmcpOwogICAgc2hhZGVyX2dsc2xfZ2V0X3N3aXp6bGUoYXJnLT5zcmNbMV0sIEZBTFNFLCBhcmctPmRzdCwgZHN0X3N3aXp6bGUpOwoKICAgIHNhbXBsZXJfaWR4ID0gYXJnLT5zcmNbMV0gJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICBzYW1wbGVyX3R5cGUgPSBhcmctPnJlZ19tYXBzLT5zYW1wbGVyc1tzYW1wbGVyX2lkeF0gJiBXSU5FRDNEU1BfVEVYVFVSRVRZUEVfTUFTSzsKICAgIGlmKGRldmljZUltcGwtPnN0YXRlQmxvY2stPnRleHR1cmVzW3NhbXBsZXJfaWR4XSAmJgogICAgICAgSVdpbmVEM0RCYXNlVGV4dHVyZV9HZXRUZXh0dXJlRGltZW5zaW9ucyhkZXZpY2VJbXBsLT5zdGF0ZUJsb2NrLT50ZXh0dXJlc1tzYW1wbGVyX2lkeF0pID09IEdMX1RFWFRVUkVfUkVDVEFOR0xFX0FSQikgewogICAgICAgIHRleHJlY3QgPSBUUlVFOwogICAgfQogICAgc2hhZGVyX2dsc2xfZ2V0X3NhbXBsZV9mdW5jdGlvbihzYW1wbGVyX3R5cGUsIEZBTFNFLCB0ZXhyZWN0LCAmc2FtcGxlX2Z1bmN0aW9uKTsgICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBzYW1wbGVfZnVuY3Rpb24uY29vcmRfbWFzaywgJmNvb3JkX3BhcmFtKTsKCiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfMywgJmxvZF9wYXJhbSk7CgogICAgaWYgKHNoYWRlcl9pc19wc2hhZGVyX3ZlcnNpb24oVGhpcy0+YmFzZVNoYWRlci5oZXhfdmVyc2lvbikpIHsKICAgICAgICAvKiBUaGUgR0xTTCBzcGVjIGNsYWltcyB0aGUgTG9kIHNhbXBsaW5nIGZ1bmN0aW9ucyBhcmUgb25seSBzdXBwb3J0ZWQgaW4gdmVydGV4IHNoYWRlcnMuCiAgICAgICAgICogSG93ZXZlciwgdGhleSBzZWVtIHRvIHdvcmsganVzdCBmaW5lIGluIGZyYWdtZW50IHNoYWRlcnMgYXMgd2VsbC4gKi8KICAgICAgICBXQVJOKCJVc2luZyAlc0xvZCBpbiBmcmFnbWVudCBzaGFkZXIuXG4iLCBzYW1wbGVfZnVuY3Rpb24ubmFtZSk7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICIlc0xvZChQc2FtcGxlciV1LCAlcywgJXMpJXMpO1xuIiwKICAgICAgICAgICAgICAgIHNhbXBsZV9mdW5jdGlvbi5uYW1lLCBzYW1wbGVyX2lkeCwgY29vcmRfcGFyYW0ucGFyYW1fc3RyLCBsb2RfcGFyYW0ucGFyYW1fc3RyLCBkc3Rfc3dpenpsZSk7CiAgICB9IGVsc2UgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXNMb2QoVnNhbXBsZXIldSwgJXMsICVzKSVzKTtcbiIsCiAgICAgICAgICAgICAgICBzYW1wbGVfZnVuY3Rpb24ubmFtZSwgc2FtcGxlcl9pZHgsIGNvb3JkX3BhcmFtLnBhcmFtX3N0ciwgbG9kX3BhcmFtLnBhcmFtX3N0ciwgZHN0X3N3aXp6bGUpOwogICAgfQp9Cgp2b2lkIHBzaGFkZXJfZ2xzbF90ZXhjb29yZChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CgogICAgLyogRklYTUU6IE1ha2UgdGhpcyB3b3JrIGZvciBtb3JlIHRoYW4ganVzdCAyRCB0ZXh0dXJlcyAqLwogICAgCiAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCogVGhpcyA9IChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCopIGFyZy0+c2hhZGVyOwogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBEV09SRCBoZXhfdmVyc2lvbiA9IFRoaXMtPmJhc2VTaGFkZXIuaGV4X3ZlcnNpb247CiAgICBEV09SRCB3cml0ZV9tYXNrOwogICAgY2hhciBkc3RfbWFza1s2XTsKCiAgICB3cml0ZV9tYXNrID0gc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChhcmctPmJ1ZmZlciwgYXJnKTsKICAgIHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrKHdyaXRlX21hc2ssIGRzdF9tYXNrKTsKCiAgICBpZiAoaGV4X3ZlcnNpb24gIT0gV0lORUQzRFBTX1ZFUlNJT04oMSw0KSkgewogICAgICAgIERXT1JEIHJlZyA9IGFyZy0+ZHN0ICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgImNsYW1wKGdsX1RleENvb3JkWyV1XSwgMC4wLCAxLjApJXMpO1xuIiwgcmVnLCBkc3RfbWFzayk7CiAgICB9IGVsc2UgewogICAgICAgIERXT1JEIHJlZyA9IGFyZy0+c3JjWzBdICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgICAgIERXT1JEIHNyY19tb2QgPSBhcmctPnNyY1swXSAmIFdJTkVEM0RTUF9TUkNNT0RfTUFTSzsKICAgICAgICBjaGFyIGRzdF9zd2l6emxlWzZdOwoKICAgICAgICBzaGFkZXJfZ2xzbF9nZXRfc3dpenpsZShhcmctPnNyY1swXSwgRkFMU0UsIHdyaXRlX21hc2ssIGRzdF9zd2l6emxlKTsKCiAgICAgICAgaWYgKHNyY19tb2QgPT0gV0lORUQzRFNQU01fRFopIHsKICAgICAgICAgICAgZ2xzbF9zcmNfcGFyYW1fdCBkaXZfcGFyYW07CiAgICAgICAgICAgIHVuc2lnbmVkIGludCBtYXNrX3NpemUgPSBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFza19zaXplKHdyaXRlX21hc2spOwogICAgICAgICAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfMiwgJmRpdl9wYXJhbSk7CgogICAgICAgICAgICBpZiAobWFza19zaXplID4gMSkgewogICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiZ2xfVGV4Q29vcmRbJXVdJXMgLyB2ZWMlZCglcykpO1xuIiwgcmVnLCBkc3Rfc3dpenpsZSwgbWFza19zaXplLCBkaXZfcGFyYW0ucGFyYW1fc3RyKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgImdsX1RleENvb3JkWyV1XSVzIC8gJXMpO1xuIiwgcmVnLCBkc3Rfc3dpenpsZSwgZGl2X3BhcmFtLnBhcmFtX3N0cik7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKHNyY19tb2QgPT0gV0lORUQzRFNQU01fRFcpIHsKICAgICAgICAgICAgZ2xzbF9zcmNfcGFyYW1fdCBkaXZfcGFyYW07CiAgICAgICAgICAgIHVuc2lnbmVkIGludCBtYXNrX3NpemUgPSBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFza19zaXplKHdyaXRlX21hc2spOwogICAgICAgICAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfMywgJmRpdl9wYXJhbSk7CgogICAgICAgICAgICBpZiAobWFza19zaXplID4gMSkgewogICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiZ2xfVGV4Q29vcmRbJXVdJXMgLyB2ZWMlZCglcykpO1xuIiwgcmVnLCBkc3Rfc3dpenpsZSwgbWFza19zaXplLCBkaXZfcGFyYW0ucGFyYW1fc3RyKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgImdsX1RleENvb3JkWyV1XSVzIC8gJXMpO1xuIiwgcmVnLCBkc3Rfc3dpenpsZSwgZGl2X3BhcmFtLnBhcmFtX3N0cik7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJnbF9UZXhDb29yZFsldV0lcyk7XG4iLCByZWcsIGRzdF9zd2l6emxlKTsKICAgICAgICB9CiAgICB9Cn0KCi8qKiBQcm9jZXNzIHRoZSBXSU5FRDNEU0lPX1RFWERQM1RFWCBpbnN0cnVjdGlvbiBpbiBHTFNMOgogKiBUYWtlIGEgMy1jb21wb25lbnQgZG90IHByb2R1Y3Qgb2YgdGhlIFRleENvb3JkW2RzdHJlZ10gYW5kIHNyYywKICogdGhlbiBwZXJmb3JtIGEgMUQgdGV4dHVyZSBsb29rdXAgZnJvbSBzdGFnZSBkc3RyZWdudW0sIHBsYWNlIGludG8gZHN0LiAqLwp2b2lkIHBzaGFkZXJfZ2xzbF90ZXhkcDN0ZXgoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMwX3BhcmFtOwogICAgY2hhciBkc3RfbWFza1s2XTsKICAgIGdsc2xfc2FtcGxlX2Z1bmN0aW9uX3Qgc2FtcGxlX2Z1bmN0aW9uOwogICAgRFdPUkQgc2FtcGxlcl9pZHggPSBhcmctPmRzdCAmIFdJTkVEM0RTUF9SRUdOVU1fTUFTSzsKICAgIERXT1JEIHNyY19tYXNrID0gV0lORUQzRFNQX1dSSVRFTUFTS18wIHwgV0lORUQzRFNQX1dSSVRFTUFTS18xIHwgV0lORUQzRFNQX1dSSVRFTUFTS18yOwogICAgRFdPUkQgc2FtcGxlcl90eXBlID0gYXJnLT5yZWdfbWFwcy0+c2FtcGxlcnNbc2FtcGxlcl9pZHhdICYgV0lORUQzRFNQX1RFWFRVUkVUWVBFX01BU0s7CgogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBzcmNfbWFzaywgJnNyYzBfcGFyYW0pOwoKICAgIHNoYWRlcl9nbHNsX2FwcGVuZF9kc3QoYXJnLT5idWZmZXIsIGFyZyk7CiAgICBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFzayhhcmctPmRzdCwgZHN0X21hc2spOwoKICAgIC8qIERvIEkgaGF2ZSB0byB0YWtlIGNhcmUgYWJvdXQgdGhlIHByb2plY3RlZCBiaXQ/IEkgZG9uJ3QgdGhpbmsgc28sIHNpbmNlIHRoZSBkcDMgcmV0dXJucyBvbmx5IG9uZQogICAgICogc2NhbGFyLCBhbmQgcHJvamVjdGVkIHNhbXBsaW5nIHdvdWxkIHJlcXVpcmUgNC4KICAgICAqCiAgICAgKiBJdCBpcyBhIGRlcGVuZGVudCByZWFkIC0gbm90IHZhbGlkIHdpdGggY29uZGl0aW9uYWwgTlAyIHRleHR1cmVzCiAgICAgKi8KICAgIHNoYWRlcl9nbHNsX2dldF9zYW1wbGVfZnVuY3Rpb24oc2FtcGxlcl90eXBlLCBGQUxTRSwgRkFMU0UsICZzYW1wbGVfZnVuY3Rpb24pOwoKICAgIHN3aXRjaChjb3VudF9iaXRzKHNhbXBsZV9mdW5jdGlvbi5jb29yZF9tYXNrKSkgewogICAgICAgIGNhc2UgMToKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICIlcyhQc2FtcGxlciV1LCBkb3QoZ2xfVGV4Q29vcmRbJXVdLnh5eiwgJXMpKSVzKTtcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNhbXBsZV9mdW5jdGlvbi5uYW1lLCBzYW1wbGVyX2lkeCwgc2FtcGxlcl9pZHgsIHNyYzBfcGFyYW0ucGFyYW1fc3RyLCBkc3RfbWFzayk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXMoUHNhbXBsZXIldSwgdmVjMihkb3QoZ2xfVGV4Q29vcmRbJXVdLnh5eiwgJXMpLCAwLjApKSVzKTtcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2FtcGxlX2Z1bmN0aW9uLm5hbWUsIHNhbXBsZXJfaWR4LCBzYW1wbGVyX2lkeCwgc3JjMF9wYXJhbS5wYXJhbV9zdHIsIGRzdF9tYXNrKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICIlcyhQc2FtcGxlciV1LCB2ZWMzKGRvdChnbF9UZXhDb29yZFsldV0ueHl6LCAlcyksIDAuMCwgMC4wKSklcyk7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzYW1wbGVfZnVuY3Rpb24ubmFtZSwgc2FtcGxlcl9pZHgsIHNhbXBsZXJfaWR4LCBzcmMwX3BhcmFtLnBhcmFtX3N0ciwgZHN0X21hc2spOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBGSVhNRSgiVW5leHBlY3RlZCBtYXNrIGJpdGNvdW50ICVkXG4iLCBjb3VudF9iaXRzKHNhbXBsZV9mdW5jdGlvbi5jb29yZF9tYXNrKSk7CiAgICB9Cn0KCi8qKiBQcm9jZXNzIHRoZSBXSU5FRDNEU0lPX1RFWERQMyBpbnN0cnVjdGlvbiBpbiBHTFNMOgogKiBUYWtlIGEgMy1jb21wb25lbnQgZG90IHByb2R1Y3Qgb2YgdGhlIFRleENvb3JkW2RzdHJlZ10gYW5kIHNyYy4gKi8Kdm9pZCBwc2hhZGVyX2dsc2xfdGV4ZHAzKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMF9wYXJhbTsKICAgIERXT1JEIGRzdHJlZyA9IGFyZy0+ZHN0ICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgRFdPUkQgc3JjX21hc2sgPSBXSU5FRDNEU1BfV1JJVEVNQVNLXzAgfCBXSU5FRDNEU1BfV1JJVEVNQVNLXzEgfCBXSU5FRDNEU1BfV1JJVEVNQVNLXzI7CiAgICBEV09SRCBkc3RfbWFzazsKICAgIHVuc2lnbmVkIGludCBtYXNrX3NpemU7CgogICAgZHN0X21hc2sgPSBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGFyZy0+YnVmZmVyLCBhcmcpOwogICAgbWFza19zaXplID0gc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2tfc2l6ZShkc3RfbWFzayk7CiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIHNyY19tYXNrLCAmc3JjMF9wYXJhbSk7CgogICAgaWYgKG1hc2tfc2l6ZSA+IDEpIHsKICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgInZlYyVkKGRvdChUJXUueHl6LCAlcykpKTtcbiIsIG1hc2tfc2l6ZSwgZHN0cmVnLCBzcmMwX3BhcmFtLnBhcmFtX3N0cik7CiAgICB9IGVsc2UgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiZG90KFQldS54eXosICVzKSk7XG4iLCBkc3RyZWcsIHNyYzBfcGFyYW0ucGFyYW1fc3RyKTsKICAgIH0KfQoKLyoqIFByb2Nlc3MgdGhlIFdJTkVEM0RTSU9fVEVYREVQVEggaW5zdHJ1Y3Rpb24gaW4gR0xTTDoKICogQ2FsY3VsYXRlIHRoZSBkZXB0aCBhcyBkc3QueCAvIGRzdC55ICAgKi8Kdm9pZCBwc2hhZGVyX2dsc2xfdGV4ZGVwdGgoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgZ2xzbF9kc3RfcGFyYW1fdCBkc3RfcGFyYW07CgogICAgc2hhZGVyX2dsc2xfYWRkX2RzdF9wYXJhbShhcmcsIGFyZy0+ZHN0LCAwLCAmZHN0X3BhcmFtKTsKCiAgICAvKiBUZXN0cyBzaG93IHRoYXQgdGV4ZGVwdGggbmV2ZXIgcmV0dXJucyBhbnl0aGluZyBiZWxvdyAwLjAsIGFuZCB0aGF0IHI1LnkgaXMgY2xhbXBlZCB0byAxLjAuCiAgICAgKiBOZWdhdGl2ZSBpbnB1dCBpcyBhY2NlcHRlZCwgLTAuMjUgLyAtMC41IHJldHVybnMgMC41LiBHTCBzaG91bGQgY2xhbXAgZ2xfRnJhZ0RlcHRoIHRvIFswOzFdLCBidXQKICAgICAqIHRoaXMgZG9lc24ndCBhbHdheXMgd29yaywgc28gY2xhbXAgdGhlIHJlc3VsdHMgbWFudWFsbHkuIFdoZXRoZXIgb3Igbm90IHRoZSB4IHZhbHVlIGlzIGNsYW1wZWQgYXQgMQogICAgICogdG9vIGlzIGlycmVsZXZhbnQsIHNpbmNlIGlmIHggPSAwLCBhbnkgeSB2YWx1ZSA8IDEuMCAoYW5kID4gMS4wIGlzIG5vdCBhbGxvd2VkKSByZXN1bHRzIGluIGEgcmVzdWx0CiAgICAgKiA+PSAxLjAgb3IgPCAwLjAKICAgICAqLwogICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJnbF9GcmFnRGVwdGggPSBjbGFtcCgoJXMueCAvIG1pbiglcy55LCAxLjApKSwgMC4wLCAxLjApO1xuIiwgZHN0X3BhcmFtLnJlZ19uYW1lLCBkc3RfcGFyYW0ucmVnX25hbWUpOwp9CgovKiogUHJvY2VzcyB0aGUgV0lORUQzRFNJT19URVhNM1gyREVQVEggaW5zdHJ1Y3Rpb24gaW4gR0xTTDoKICogTGFzdCByb3cgb2YgYSAzeDIgbWF0cml4IG11bHRpcGx5LCB1c2UgdGhlIHJlc3VsdCB0byBjYWxjdWxhdGUgdGhlIGRlcHRoOgogKiBDYWxjdWxhdGUgdG1wMC55ID0gVGV4Q29vcmRbZHN0cmVnXSAuIHNyYy54eXo7ICAodG1wMC54IGhhcyBhbHJlYWR5IGJlZW4gY2FsY3VsYXRlZCkKICogZGVwdGggPSAodG1wMC55ID09IDAuMCkgPyAxLjAgOiB0bXAwLnggLyB0bXAwLnkKICovCnZvaWQgcHNoYWRlcl9nbHNsX3RleG0zeDJkZXB0aChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBEV09SRCBzcmNfbWFzayA9IFdJTkVEM0RTUF9XUklURU1BU0tfMCB8IFdJTkVEM0RTUF9XUklURU1BU0tfMSB8IFdJTkVEM0RTUF9XUklURU1BU0tfMjsKICAgIERXT1JEIGRzdHJlZyA9IGFyZy0+ZHN0ICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMwX3BhcmFtOwoKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgc3JjX21hc2ssICZzcmMwX3BhcmFtKTsKCiAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgInRtcDAueSA9IGRvdChUJXUueHl6LCAlcyk7XG4iLCBkc3RyZWcsIHNyYzBfcGFyYW0ucGFyYW1fc3RyKTsKICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiZ2xfRnJhZ0RlcHRoID0gKHRtcDAueSA9PSAwLjApID8gMS4wIDogY2xhbXAodG1wMC54IC8gdG1wMC55LCAwLjAsIDEuMCk7XG4iKTsKfQoKLyoqIFByb2Nlc3MgdGhlIFdJTkVEM0RTSU9fVEVYTTNYMlBBRCBpbnN0cnVjdGlvbiBpbiBHTFNMCiAqIENhbGN1bGF0ZSB0aGUgMXN0IG9mIGEgMi1yb3cgbWF0cml4IG11bHRpcGxpY2F0aW9uLiAqLwp2b2lkIHBzaGFkZXJfZ2xzbF90ZXhtM3gycGFkKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIERXT1JEIHNyY19tYXNrID0gV0lORUQzRFNQX1dSSVRFTUFTS18wIHwgV0lORUQzRFNQX1dSSVRFTUFTS18xIHwgV0lORUQzRFNQX1dSSVRFTUFTS18yOwogICAgRFdPUkQgcmVnID0gYXJnLT5kc3QgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICBTSEFERVJfQlVGRkVSKiBidWZmZXIgPSBhcmctPmJ1ZmZlcjsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMF9wYXJhbTsKCiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIHNyY19tYXNrLCAmc3JjMF9wYXJhbSk7CiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ0bXAwLnggPSBkb3QoVCV1Lnh5eiwgJXMpO1xuIiwgcmVnLCBzcmMwX3BhcmFtLnBhcmFtX3N0cik7Cn0KCi8qKiBQcm9jZXNzIHRoZSBXSU5FRDNEU0lPX1RFWE0zWDNQQUQgaW5zdHJ1Y3Rpb24gaW4gR0xTTAogKiBDYWxjdWxhdGUgdGhlIDFzdCBvciAybmQgcm93IG9mIGEgMy1yb3cgbWF0cml4IG11bHRpcGxpY2F0aW9uLiAqLwp2b2lkIHBzaGFkZXJfZ2xzbF90ZXhtM3gzcGFkKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKCiAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCogc2hhZGVyID0gKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsKikgYXJnLT5zaGFkZXI7CiAgICBEV09SRCBzcmNfbWFzayA9IFdJTkVEM0RTUF9XUklURU1BU0tfMCB8IFdJTkVEM0RTUF9XUklURU1BU0tfMSB8IFdJTkVEM0RTUF9XUklURU1BU0tfMjsKICAgIERXT1JEIHJlZyA9IGFyZy0+ZHN0ICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBTSEFERVJfUEFSU0VfU1RBVEUqIGN1cnJlbnRfc3RhdGUgPSAmc2hhZGVyLT5iYXNlU2hhZGVyLnBhcnNlX3N0YXRlOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMwX3BhcmFtOwoKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgc3JjX21hc2ssICZzcmMwX3BhcmFtKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInRtcDAuJWMgPSBkb3QoVCV1Lnh5eiwgJXMpO1xuIiwgJ3gnICsgY3VycmVudF9zdGF0ZS0+Y3VycmVudF9yb3csIHJlZywgc3JjMF9wYXJhbS5wYXJhbV9zdHIpOwogICAgY3VycmVudF9zdGF0ZS0+dGV4Y29vcmRfd1tjdXJyZW50X3N0YXRlLT5jdXJyZW50X3JvdysrXSA9IHJlZzsKfQoKdm9pZCBwc2hhZGVyX2dsc2xfdGV4bTN4MnRleChTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBEV09SRCBzcmNfbWFzayA9IFdJTkVEM0RTUF9XUklURU1BU0tfMCB8IFdJTkVEM0RTUF9XUklURU1BU0tfMSB8IFdJTkVEM0RTUF9XUklURU1BU0tfMjsKICAgIERXT1JEIHJlZyA9IGFyZy0+ZHN0ICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW07CiAgICBjaGFyIGRzdF9tYXNrWzZdOwoKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgc3JjX21hc2ssICZzcmMwX3BhcmFtKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInRtcDAueSA9IGRvdChUJXUueHl6LCAlcyk7XG4iLCByZWcsIHNyYzBfcGFyYW0ucGFyYW1fc3RyKTsKCiAgICBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGJ1ZmZlciwgYXJnKTsKICAgIHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrKGFyZy0+ZHN0LCBkc3RfbWFzayk7CgogICAgLyogU2FtcGxlIHRoZSB0ZXh0dXJlIHVzaW5nIHRoZSBjYWxjdWxhdGVkIGNvb3JkaW5hdGVzICovCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ0ZXh0dXJlMkQoUHNhbXBsZXIldSwgdG1wMC54eSklcyk7XG4iLCByZWcsIGRzdF9tYXNrKTsKfQoKLyoqIFByb2Nlc3MgdGhlIFdJTkVEM0RTSU9fVEVYTTNYM1RFWCBpbnN0cnVjdGlvbiBpbiBHTFNMCiAqIFBlcmZvcm0gdGhlIDNyZCByb3cgb2YgYSAzeDMgbWF0cml4IG11bHRpcGx5LCB0aGVuIHNhbXBsZSB0aGUgdGV4dHVyZSB1c2luZyB0aGUgY2FsY3VsYXRlZCBjb29yZGluYXRlcyAqLwp2b2lkIHBzaGFkZXJfZ2xzbF90ZXhtM3gzdGV4KFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIERXT1JEIHNyY19tYXNrID0gV0lORUQzRFNQX1dSSVRFTUFTS18wIHwgV0lORUQzRFNQX1dSSVRFTUFTS18xIHwgV0lORUQzRFNQX1dSSVRFTUFTS18yOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMwX3BhcmFtOwogICAgY2hhciBkc3RfbWFza1s2XTsKICAgIERXT1JEIHJlZyA9IGFyZy0+ZHN0ICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgSVdpbmVEM0RQaXhlbFNoYWRlckltcGwqIFRoaXMgPSAoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwqKSBhcmctPnNoYWRlcjsKICAgIFNIQURFUl9QQVJTRV9TVEFURSogY3VycmVudF9zdGF0ZSA9ICZUaGlzLT5iYXNlU2hhZGVyLnBhcnNlX3N0YXRlOwogICAgRFdPUkQgc2FtcGxlcl90eXBlID0gYXJnLT5yZWdfbWFwcy0+c2FtcGxlcnNbcmVnXSAmIFdJTkVEM0RTUF9URVhUVVJFVFlQRV9NQVNLOwogICAgZ2xzbF9zYW1wbGVfZnVuY3Rpb25fdCBzYW1wbGVfZnVuY3Rpb247CgogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBzcmNfbWFzaywgJnNyYzBfcGFyYW0pOwogICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJ0bXAwLnogPSBkb3QoVCV1Lnh5eiwgJXMpO1xuIiwgcmVnLCBzcmMwX3BhcmFtLnBhcmFtX3N0cik7CgogICAgc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChhcmctPmJ1ZmZlciwgYXJnKTsKICAgIHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrKGFyZy0+ZHN0LCBkc3RfbWFzayk7CiAgICAvKiBEZXBlbmRlbnQgcmVhZCwgbm90IHZhbGlkIHdpdGggY29uZGl0aW9uYWwgTlAyICovCiAgICBzaGFkZXJfZ2xzbF9nZXRfc2FtcGxlX2Z1bmN0aW9uKHNhbXBsZXJfdHlwZSwgRkFMU0UsIEZBTFNFLCAmc2FtcGxlX2Z1bmN0aW9uKTsKCiAgICAvKiBTYW1wbGUgdGhlIHRleHR1cmUgdXNpbmcgdGhlIGNhbGN1bGF0ZWQgY29vcmRpbmF0ZXMgKi8KICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXMoUHNhbXBsZXIldSwgdG1wMC54eXopJXMpO1xuIiwgc2FtcGxlX2Z1bmN0aW9uLm5hbWUsIHJlZywgZHN0X21hc2spOwoKICAgIGN1cnJlbnRfc3RhdGUtPmN1cnJlbnRfcm93ID0gMDsKfQoKLyoqIFByb2Nlc3MgdGhlIFdJTkVEM0RTSU9fVEVYTTNYMyBpbnN0cnVjdGlvbiBpbiBHTFNMCiAqIFBlcmZvcm0gdGhlIDNyZCByb3cgb2YgYSAzeDMgbWF0cml4IG11bHRpcGx5ICovCnZvaWQgcHNoYWRlcl9nbHNsX3RleG0zeDMoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewogICAgRFdPUkQgc3JjX21hc2sgPSBXSU5FRDNEU1BfV1JJVEVNQVNLXzAgfCBXSU5FRDNEU1BfV1JJVEVNQVNLXzEgfCBXSU5FRDNEU1BfV1JJVEVNQVNLXzI7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW07CiAgICBjaGFyIGRzdF9tYXNrWzZdOwogICAgRFdPUkQgcmVnID0gYXJnLT5kc3QgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCogVGhpcyA9IChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCopIGFyZy0+c2hhZGVyOwogICAgU0hBREVSX1BBUlNFX1NUQVRFKiBjdXJyZW50X3N0YXRlID0gJlRoaXMtPmJhc2VTaGFkZXIucGFyc2Vfc3RhdGU7CgogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBzcmNfbWFzaywgJnNyYzBfcGFyYW0pOwoKICAgIHNoYWRlcl9nbHNsX2FwcGVuZF9kc3QoYXJnLT5idWZmZXIsIGFyZyk7CiAgICBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFzayhhcmctPmRzdCwgZHN0X21hc2spOwogICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJ2ZWM0KHRtcDAueHksIGRvdChUJXUueHl6LCAlcyksIDEuMCklcyk7XG4iLCByZWcsIHNyYzBfcGFyYW0ucGFyYW1fc3RyLCBkc3RfbWFzayk7CgogICAgY3VycmVudF9zdGF0ZS0+Y3VycmVudF9yb3cgPSAwOwp9CgovKiogUHJvY2VzcyB0aGUgV0lORUQzRFNJT19URVhNM1gzU1BFQyBpbnN0cnVjdGlvbiBpbiBHTFNMIAogKiBQZWZvcm0gdGhlIGZpbmFsIHRleHR1cmUgbG9va3VwIGJhc2VkIG9uIHRoZSBwcmV2aW91cyAyIDN4MyBtYXRyaXggbXVsdGlwbGllcyAqLwp2b2lkIHBzaGFkZXJfZ2xzbF90ZXhtM3gzc3BlYyhTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CgogICAgSVdpbmVEM0RQaXhlbFNoYWRlckltcGwqIHNoYWRlciA9IChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCopIGFyZy0+c2hhZGVyOwogICAgRFdPUkQgcmVnID0gYXJnLT5kc3QgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW07CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzFfcGFyYW07CiAgICBjaGFyIGRzdF9tYXNrWzZdOwogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBTSEFERVJfUEFSU0VfU1RBVEUqIGN1cnJlbnRfc3RhdGUgPSAmc2hhZGVyLT5iYXNlU2hhZGVyLnBhcnNlX3N0YXRlOwogICAgRFdPUkQgc3R5cGUgPSBhcmctPnJlZ19tYXBzLT5zYW1wbGVyc1tyZWddICYgV0lORUQzRFNQX1RFWFRVUkVUWVBFX01BU0s7CiAgICBEV09SRCBzcmNfbWFzayA9IFdJTkVEM0RTUF9XUklURU1BU0tfMCB8IFdJTkVEM0RTUF9XUklURU1BU0tfMSB8IFdJTkVEM0RTUF9XUklURU1BU0tfMjsKICAgIGdsc2xfc2FtcGxlX2Z1bmN0aW9uX3Qgc2FtcGxlX2Z1bmN0aW9uOwoKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgc3JjX21hc2ssICZzcmMwX3BhcmFtKTsKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1sxXSwgYXJnLT5zcmNfYWRkclsxXSwgc3JjX21hc2ssICZzcmMxX3BhcmFtKTsKCiAgICAvKiBQZXJmb3JtIHRoZSBsYXN0IG1hdHJpeCBtdWx0aXBseSBvcGVyYXRpb24gKi8KICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInRtcDAueiA9IGRvdChUJXUueHl6LCAlcyk7XG4iLCByZWcsIHNyYzBfcGFyYW0ucGFyYW1fc3RyKTsKICAgIC8qIFJlZmxlY3Rpb24gY2FsY3VsYXRpb24gKi8KICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInRtcDAueHl6ID0gLXJlZmxlY3QoKCVzKSwgbm9ybWFsaXplKHRtcDAueHl6KSk7XG4iLCBzcmMxX3BhcmFtLnBhcmFtX3N0cik7CgogICAgc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChidWZmZXIsIGFyZyk7CiAgICBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFzayhhcmctPmRzdCwgZHN0X21hc2spOwogICAgLyogRGVwZW5kZW50IHJlYWQsIG5vdCB2YWxpZCB3aXRoIGNvbmRpdGlvbmFsIE5QMiAqLwogICAgc2hhZGVyX2dsc2xfZ2V0X3NhbXBsZV9mdW5jdGlvbihzdHlwZSwgRkFMU0UsIEZBTFNFLCAmc2FtcGxlX2Z1bmN0aW9uKTsKCiAgICAvKiBTYW1wbGUgdGhlIHRleHR1cmUgKi8KICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIiVzKFBzYW1wbGVyJXUsIHRtcDAueHl6KSVzKTtcbiIsIHNhbXBsZV9mdW5jdGlvbi5uYW1lLCByZWcsIGRzdF9tYXNrKTsKCiAgICBjdXJyZW50X3N0YXRlLT5jdXJyZW50X3JvdyA9IDA7Cn0KCi8qKiBQcm9jZXNzIHRoZSBXSU5FRDNEU0lPX1RFWE0zWDNWU1BFQyBpbnN0cnVjdGlvbiBpbiBHTFNMIAogKiBQZWZvcm0gdGhlIGZpbmFsIHRleHR1cmUgbG9va3VwIGJhc2VkIG9uIHRoZSBwcmV2aW91cyAyIDN4MyBtYXRyaXggbXVsdGlwbGllcyAqLwp2b2lkIHBzaGFkZXJfZ2xzbF90ZXhtM3gzdnNwZWMoU0hBREVSX09QQ09ERV9BUkcqIGFyZykgewoKICAgIElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsKiBzaGFkZXIgPSAoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwqKSBhcmctPnNoYWRlcjsKICAgIERXT1JEIHJlZyA9IGFyZy0+ZHN0ICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgU0hBREVSX0JVRkZFUiogYnVmZmVyID0gYXJnLT5idWZmZXI7CiAgICBTSEFERVJfUEFSU0VfU1RBVEUqIGN1cnJlbnRfc3RhdGUgPSAmc2hhZGVyLT5iYXNlU2hhZGVyLnBhcnNlX3N0YXRlOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMwX3BhcmFtOwogICAgY2hhciBkc3RfbWFza1s2XTsKICAgIERXT1JEIHNyY19tYXNrID0gV0lORUQzRFNQX1dSSVRFTUFTS18wIHwgV0lORUQzRFNQX1dSSVRFTUFTS18xIHwgV0lORUQzRFNQX1dSSVRFTUFTS18yOwogICAgRFdPUkQgc2FtcGxlcl90eXBlID0gYXJnLT5yZWdfbWFwcy0+c2FtcGxlcnNbcmVnXSAmIFdJTkVEM0RTUF9URVhUVVJFVFlQRV9NQVNLOwogICAgZ2xzbF9zYW1wbGVfZnVuY3Rpb25fdCBzYW1wbGVfZnVuY3Rpb247CgogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBzcmNfbWFzaywgJnNyYzBfcGFyYW0pOwoKICAgIC8qIFBlcmZvcm0gdGhlIGxhc3QgbWF0cml4IG11bHRpcGx5IG9wZXJhdGlvbiAqLwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAidG1wMC56ID0gZG90KHZlYzMoVCV1KSwgdmVjMyglcykpO1xuIiwgcmVnLCBzcmMwX3BhcmFtLnBhcmFtX3N0cik7CgogICAgLyogQ29uc3RydWN0IHRoZSBleWUtcmF5IHZlY3RvciBmcm9tIHcgY29vcmRpbmF0ZXMgKi8KICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInRtcDEueHl6ID0gbm9ybWFsaXplKHZlYzMoZ2xfVGV4Q29vcmRbJXVdLncsIGdsX1RleENvb3JkWyV1XS53LCBnbF9UZXhDb29yZFsldV0udykpO1xuIiwKICAgICAgICAgICAgY3VycmVudF9zdGF0ZS0+dGV4Y29vcmRfd1swXSwgY3VycmVudF9zdGF0ZS0+dGV4Y29vcmRfd1sxXSwgcmVnKTsKICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInRtcDAueHl6ID0gLXJlZmxlY3QodG1wMS54eXosIG5vcm1hbGl6ZSh0bXAwLnh5eikpO1xuIik7CgogICAgc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChidWZmZXIsIGFyZyk7CiAgICBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFzayhhcmctPmRzdCwgZHN0X21hc2spOwogICAgLyogRGVwZW5kZW50IHJlYWQsIG5vdCB2YWxpZCB3aXRoIGNvbmRpdGlvbmFsIE5QMiAqLwogICAgc2hhZGVyX2dsc2xfZ2V0X3NhbXBsZV9mdW5jdGlvbihzYW1wbGVyX3R5cGUsIEZBTFNFLCBGQUxTRSwgJnNhbXBsZV9mdW5jdGlvbik7CgogICAgLyogU2FtcGxlIHRoZSB0ZXh0dXJlIHVzaW5nIHRoZSBjYWxjdWxhdGVkIGNvb3JkaW5hdGVzICovCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICIlcyhQc2FtcGxlciV1LCB0bXAwLnh5eiklcyk7XG4iLCBzYW1wbGVfZnVuY3Rpb24ubmFtZSwgcmVnLCBkc3RfbWFzayk7CgogICAgY3VycmVudF9zdGF0ZS0+Y3VycmVudF9yb3cgPSAwOwp9CgovKiogUHJvY2VzcyB0aGUgV0lORUQzRFNJT19URVhCRU0gaW5zdHJ1Y3Rpb24gaW4gR0xTTC4KICogQXBwbHkgYSBmYWtlIGJ1bXAgbWFwIHRyYW5zZm9ybS4KICogdGV4YmVtIGlzIHBzaGFkZXIgPD0gMS4zIG9ubHksIHRoaXMgc2F2ZXMgYSBmZXcgdmVyc2lvbiBjaGVja3MKICovCnZvaWQgcHNoYWRlcl9nbHNsX3RleGJlbShTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCogVGhpcyA9IChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCopIGFyZy0+c2hhZGVyOwogICAgSVdpbmVEM0REZXZpY2VJbXBsKiBkZXZpY2VJbXBsID0gKElXaW5lRDNERGV2aWNlSW1wbCopIFRoaXMtPmJhc2VTaGFkZXIuZGV2aWNlOwogICAgY2hhciBkc3Rfc3dpenpsZVs2XTsKICAgIGdsc2xfc2FtcGxlX2Z1bmN0aW9uX3Qgc2FtcGxlX2Z1bmN0aW9uOwogICAgZ2xzbF9zcmNfcGFyYW1fdCBjb29yZF9wYXJhbTsKICAgIERXT1JEIHNhbXBsZXJfdHlwZTsKICAgIERXT1JEIHNhbXBsZXJfaWR4OwogICAgRFdPUkQgbWFzazsKICAgIERXT1JEIGZsYWdzOwogICAgY2hhciBjb29yZF9tYXNrWzZdOwoKICAgIHNhbXBsZXJfaWR4ID0gYXJnLT5kc3QgJiBXSU5FRDNEU1BfUkVHTlVNX01BU0s7CiAgICBmbGFncyA9IGRldmljZUltcGwtPnN0YXRlQmxvY2stPnRleHR1cmVTdGF0ZVtzYW1wbGVyX2lkeF1bV0lORUQzRFRTU19URVhUVVJFVFJBTlNGT1JNRkxBR1NdOwoKICAgIHNhbXBsZXJfdHlwZSA9IGFyZy0+cmVnX21hcHMtPnNhbXBsZXJzW3NhbXBsZXJfaWR4XSAmIFdJTkVEM0RTUF9URVhUVVJFVFlQRV9NQVNLOwogICAgLyogRGVwZW5kZW50IHJlYWQsIG5vdCB2YWxpZCB3aXRoIGNvbmRpdGlvbmFsIE5QMiAqLwogICAgc2hhZGVyX2dsc2xfZ2V0X3NhbXBsZV9mdW5jdGlvbihzYW1wbGVyX3R5cGUsIEZBTFNFLCBGQUxTRSwgJnNhbXBsZV9mdW5jdGlvbik7CiAgICBtYXNrID0gc2FtcGxlX2Z1bmN0aW9uLmNvb3JkX21hc2s7CgogICAgc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2soYXJnLT5kc3QsIGRzdF9zd2l6emxlKTsKCiAgICBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFzayhtYXNrLCBjb29yZF9tYXNrKTsKCiAgICAvKiB3aXRoIHByb2plY3RpdmUgdGV4dHVyZXMsIHRleGJlbSBvbmx5IGRpdmlkZXMgdGhlIHN0YXRpYyB0ZXh0dXJlIGNvb3JkLCBub3QgdGhlIGRpc3BsYWNlbWVudCwKICAgICAgICAgKiBzbyB3ZSBjYW4ndCBsZXQgdGhlIEdMIGhhbmRsZSB0aGlzLgogICAgICAgICAqLwogICAgaWYgKGZsYWdzICYgV0lORUQzRFRURkZfUFJPSkVDVEVEKSB7CiAgICAgICAgRFdPUkQgZGl2X21hc2s9MDsKICAgICAgICBjaGFyIGNvb3JkX2Rpdl9tYXNrWzNdOwogICAgICAgIHN3aXRjaCAoZmxhZ3MgJiB+V0lORUQzRFRURkZfUFJPSkVDVEVEKSB7CiAgICAgICAgICAgIGNhc2UgV0lORUQzRFRURkZfQ09VTlQxOiBGSVhNRSgiV0lORUQzRFRURkZfUFJPSkVDVEVEIHdpdGggV0lORUQzRFRURkZfQ09VTlQxP1xuIik7IGJyZWFrOwogICAgICAgICAgICBjYXNlIFdJTkVEM0RUVEZGX0NPVU5UMjogZGl2X21hc2sgPSBXSU5FRDNEU1BfV1JJVEVNQVNLXzE7IGJyZWFrOwogICAgICAgICAgICBjYXNlIFdJTkVEM0RUVEZGX0NPVU5UMzogZGl2X21hc2sgPSBXSU5FRDNEU1BfV1JJVEVNQVNLXzI7IGJyZWFrOwogICAgICAgICAgICBjYXNlIFdJTkVEM0RUVEZGX0NPVU5UNDoKICAgICAgICAgICAgY2FzZSBXSU5FRDNEVFRGRl9ESVNBQkxFOiBkaXZfbWFzayA9IFdJTkVEM0RTUF9XUklURU1BU0tfMzsgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrKGRpdl9tYXNrLCBjb29yZF9kaXZfbWFzayk7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJUJXUlcyAvPSBUJXUlcztcbiIsIHNhbXBsZXJfaWR4LCBjb29yZF9tYXNrLCBzYW1wbGVyX2lkeCwgY29vcmRfZGl2X21hc2spOwogICAgfQoKICAgIHNoYWRlcl9nbHNsX2FwcGVuZF9kc3QoYXJnLT5idWZmZXIsIGFyZyk7CiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfMHxXSU5FRDNEU1BfV1JJVEVNQVNLXzEsICZjb29yZF9wYXJhbSk7CiAgICBpZihhcmctPm9wY29kZS0+b3Bjb2RlID09IFdJTkVEM0RTSU9fVEVYQkVNTCkgewogICAgICAgIGdsc2xfc3JjX3BhcmFtX3QgbHVtaW5hbmNlX3BhcmFtOwogICAgICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgV0lORUQzRFNQX1dSSVRFTUFTS18yLCAmbHVtaW5hbmNlX3BhcmFtKTsKICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgIiglcyhQc2FtcGxlciV1LCBUJXUlcyArIHZlYzQoYnVtcGVudm1hdCVkICogJXMsIDAuMCwgMC4wKSVzICkqKCVzICogbHVtaW5hbmNlc2NhbGUlZCArIGx1bWluYW5jZW9mZnNldCVkKSklcyk7XG4iLAogICAgICAgICAgICAgICAgICAgICAgIHNhbXBsZV9mdW5jdGlvbi5uYW1lLCBzYW1wbGVyX2lkeCwgc2FtcGxlcl9pZHgsIGNvb3JkX21hc2ssIHNhbXBsZXJfaWR4LCBjb29yZF9wYXJhbS5wYXJhbV9zdHIsIGNvb3JkX21hc2ssCiAgICAgICAgICAgICAgICAgICAgICAgbHVtaW5hbmNlX3BhcmFtLnBhcmFtX3N0ciwgc2FtcGxlcl9pZHgsIHNhbXBsZXJfaWR4LCBkc3Rfc3dpenpsZSk7CiAgICB9IGVsc2UgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXMoUHNhbXBsZXIldSwgVCV1JXMgKyB2ZWM0KGJ1bXBlbnZtYXQlZCAqICVzLCAwLjAsIDAuMCklcyApJXMpO1xuIiwKICAgICAgICAgICAgICAgICAgICAgICBzYW1wbGVfZnVuY3Rpb24ubmFtZSwgc2FtcGxlcl9pZHgsIHNhbXBsZXJfaWR4LCBjb29yZF9tYXNrLCBzYW1wbGVyX2lkeCwgY29vcmRfcGFyYW0ucGFyYW1fc3RyLCBjb29yZF9tYXNrLCBkc3Rfc3dpenpsZSk7CiAgICB9Cn0KCnZvaWQgcHNoYWRlcl9nbHNsX2JlbShTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW0sIHNyYzFfcGFyYW07CiAgICBEV09SRCBzYW1wbGVyX2lkeCA9IGFyZy0+ZHN0ICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwoKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgV0lORUQzRFNQX1dSSVRFTUFTS18wfFdJTkVEM0RTUF9XUklURU1BU0tfMSwgJnNyYzBfcGFyYW0pOwogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzFdLCBhcmctPnNyY19hZGRyWzFdLCBXSU5FRDNEU1BfV1JJVEVNQVNLXzB8V0lORUQzRFNQX1dSSVRFTUFTS18xLCAmc3JjMV9wYXJhbSk7CgogICAgc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChhcmctPmJ1ZmZlciwgYXJnKTsKICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXMgKyBidW1wZW52bWF0JWQgKiAlcyk7XG4iLAogICAgICAgICAgICAgICAgICAgc3JjMF9wYXJhbS5wYXJhbV9zdHIsIHNhbXBsZXJfaWR4LCBzcmMxX3BhcmFtLnBhcmFtX3N0cik7Cn0KCi8qKiBQcm9jZXNzIHRoZSBXSU5FRDNEU0lPX1RFWFJFRzJBUiBpbnN0cnVjdGlvbiBpbiBHTFNMCiAqIFNhbXBsZSAyRCB0ZXh0dXJlIGF0IGRzdCB1c2luZyB0aGUgYWxwaGEgJiByZWQgKHd4KSBjb21wb25lbnRzIG9mIHNyYyBhcyB0ZXh0dXJlIGNvb3JkaW5hdGVzICovCnZvaWQgcHNoYWRlcl9nbHNsX3RleHJlZzJhcihTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CgogICAgZ2xzbF9zcmNfcGFyYW1fdCBzcmMwX3BhcmFtOwogICAgRFdPUkQgc2FtcGxlcl9pZHggPSBhcmctPmRzdCAmIFdJTkVEM0RTUF9SRUdOVU1fTUFTSzsKICAgIGNoYXIgZHN0X21hc2tbNl07CgogICAgc2hhZGVyX2dsc2xfYXBwZW5kX2RzdChhcmctPmJ1ZmZlciwgYXJnKTsKICAgIHNoYWRlcl9nbHNsX2dldF93cml0ZV9tYXNrKGFyZy0+ZHN0LCBkc3RfbWFzayk7CiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfQUxMLCAmc3JjMF9wYXJhbSk7CgogICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJ0ZXh0dXJlMkQoUHNhbXBsZXIldSwgJXMud3gpJXMpO1xuIiwgc2FtcGxlcl9pZHgsIHNyYzBfcGFyYW0ucmVnX25hbWUsIGRzdF9tYXNrKTsKfQoKLyoqIFByb2Nlc3MgdGhlIFdJTkVEM0RTSU9fVEVYUkVHMkdCIGluc3RydWN0aW9uIGluIEdMU0wKICogU2FtcGxlIDJEIHRleHR1cmUgYXQgZHN0IHVzaW5nIHRoZSBncmVlbiAmIGJsdWUgKHl6KSBjb21wb25lbnRzIG9mIHNyYyBhcyB0ZXh0dXJlIGNvb3JkaW5hdGVzICovCnZvaWQgcHNoYWRlcl9nbHNsX3RleHJlZzJnYihTSEFERVJfT1BDT0RFX0FSRyogYXJnKSB7CiAgICBnbHNsX3NyY19wYXJhbV90IHNyYzBfcGFyYW07CiAgICBEV09SRCBzYW1wbGVyX2lkeCA9IGFyZy0+ZHN0ICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgY2hhciBkc3RfbWFza1s2XTsKCiAgICBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGFyZy0+YnVmZmVyLCBhcmcpOwogICAgc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2soYXJnLT5kc3QsIGRzdF9tYXNrKTsKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1swXSwgYXJnLT5zcmNfYWRkclswXSwgV0lORUQzRFNQX1dSSVRFTUFTS19BTEwsICZzcmMwX3BhcmFtKTsKCiAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgInRleHR1cmUyRChQc2FtcGxlciV1LCAlcy55eiklcyk7XG4iLCBzYW1wbGVyX2lkeCwgc3JjMF9wYXJhbS5yZWdfbmFtZSwgZHN0X21hc2spOwp9CgovKiogUHJvY2VzcyB0aGUgV0lORUQzRFNJT19URVhSRUcyUkdCIGluc3RydWN0aW9uIGluIEdMU0wKICogU2FtcGxlIHRleHR1cmUgYXQgZHN0IHVzaW5nIHRoZSByZ2IgKHh5eikgY29tcG9uZW50cyBvZiBzcmMgYXMgdGV4dHVyZSBjb29yZGluYXRlcyAqLwp2b2lkIHBzaGFkZXJfZ2xzbF90ZXhyZWcycmdiKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMF9wYXJhbTsKICAgIGNoYXIgZHN0X21hc2tbNl07CiAgICBEV09SRCBzYW1wbGVyX2lkeCA9IGFyZy0+ZHN0ICYgV0lORUQzRFNQX1JFR05VTV9NQVNLOwogICAgRFdPUkQgc2FtcGxlcl90eXBlID0gYXJnLT5yZWdfbWFwcy0+c2FtcGxlcnNbc2FtcGxlcl9pZHhdICYgV0lORUQzRFNQX1RFWFRVUkVUWVBFX01BU0s7CiAgICBnbHNsX3NhbXBsZV9mdW5jdGlvbl90IHNhbXBsZV9mdW5jdGlvbjsKCiAgICBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGFyZy0+YnVmZmVyLCBhcmcpOwogICAgc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2soYXJnLT5kc3QsIGRzdF9tYXNrKTsKICAgIC8qIERlcGVuZGVudCByZWFkLCBub3QgdmFsaWQgd2l0aCBjb25kaXRpb25hbCBOUDIgKi8KICAgIHNoYWRlcl9nbHNsX2dldF9zYW1wbGVfZnVuY3Rpb24oc2FtcGxlcl90eXBlLCBGQUxTRSwgRkFMU0UsICZzYW1wbGVfZnVuY3Rpb24pOwogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzBdLCBhcmctPnNyY19hZGRyWzBdLCBzYW1wbGVfZnVuY3Rpb24uY29vcmRfbWFzaywgJnNyYzBfcGFyYW0pOwoKICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiJXMoUHNhbXBsZXIldSwgJXMpJXMpO1xuIiwgc2FtcGxlX2Z1bmN0aW9uLm5hbWUsIHNhbXBsZXJfaWR4LCBzcmMwX3BhcmFtLnBhcmFtX3N0ciwgZHN0X21hc2spOwp9CgovKiogUHJvY2VzcyB0aGUgV0lORUQzRFNJT19URVhLSUxMIGluc3RydWN0aW9uIGluIEdMU0wuCiAqIElmIGFueSBvZiB0aGUgZmlyc3QgMyBjb21wb25lbnRzIGFyZSA8IDAsIGRpc2NhcmQgdGhpcyBwaXhlbCAqLwp2b2lkIHBzaGFkZXJfZ2xzbF90ZXhraWxsKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsKiBUaGlzID0gKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsKikgYXJnLT5zaGFkZXI7CiAgICBEV09SRCBoZXhfdmVyc2lvbiA9IFRoaXMtPmJhc2VTaGFkZXIuaGV4X3ZlcnNpb247CiAgICBnbHNsX2RzdF9wYXJhbV90IGRzdF9wYXJhbTsKCiAgICAvKiBUaGUgYXJndW1lbnQgaXMgYSBkZXN0aW5hdGlvbiBwYXJhbWV0ZXIsIGFuZCBubyB3cml0ZW1hc2tzIGFyZSBhbGxvd2VkICovCiAgICBzaGFkZXJfZ2xzbF9hZGRfZHN0X3BhcmFtKGFyZywgYXJnLT5kc3QsIDAsICZkc3RfcGFyYW0pOwogICAgaWYoKGhleF92ZXJzaW9uID49IFdJTkVEM0RQU19WRVJTSU9OKDIsMCkpKSB7CiAgICAgICAgLyogMi4wIHNoYWRlcnMgY29tcGFyZSBhbGwgNCBjb21wb25lbnRzIGluIHRleGtpbGwgKi8KICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgImlmIChhbnkobGVzc1RoYW4oJXMueHl6dywgdmVjNCgwLjApKSkpIGRpc2NhcmQ7XG4iLCBkc3RfcGFyYW0ucmVnX25hbWUpOwogICAgfSBlbHNlIHsKICAgICAgICAvKiAxLlggc2hhZGVycyBvbmx5IGNvbXBhcmUgdGhlIGZpcnN0IDMgY29tcG9uZW50cywgcHJvYmFibHkgZHVlIHRvIHRoZSBuYXR1cmUgb2YgdGhlIHRleGtpbGwKICAgICAgICAgKiBpbnN0cnVjdGlvbiBhcyBhIHRleCogaW5zdHJ1Y3Rpb24sIGFuZCBwaGFzZSwgd2hpY2gga2lsbHMgYWxsIGEgLyB3IGNvbXBvbmVudHMuIEV2ZW4gaWYgYWxsCiAgICAgICAgICogNCBjb21wb25lbnRzIGFyZSBkZWZpbmVkLCBvbmx5IHRoZSBmaXJzdCAzIGFyZSB1c2VkCiAgICAgICAgICovCiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYXJnLT5idWZmZXIsICJpZiAoYW55KGxlc3NUaGFuKCVzLnh5eiwgdmVjMygwLjApKSkpIGRpc2NhcmQ7XG4iLCBkc3RfcGFyYW0ucmVnX25hbWUpOwogICAgfQp9CgovKiogUHJvY2VzcyB0aGUgV0lORUQzRFNJT19EUDJBREQgaW5zdHJ1Y3Rpb24gaW4gR0xTTC4KICogZHN0ID0gZG90MihzcmMwLCBzcmMxKSArIHNyYzIgKi8Kdm9pZCBwc2hhZGVyX2dsc2xfZHAyYWRkKFNIQURFUl9PUENPREVfQVJHKiBhcmcpIHsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMF9wYXJhbTsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMV9wYXJhbTsKICAgIGdsc2xfc3JjX3BhcmFtX3Qgc3JjMl9wYXJhbTsKICAgIERXT1JEIHdyaXRlX21hc2s7CiAgICB1bnNpZ25lZCBpbnQgbWFza19zaXplOwoKICAgIHdyaXRlX21hc2sgPSBzaGFkZXJfZ2xzbF9hcHBlbmRfZHN0KGFyZy0+YnVmZmVyLCBhcmcpOwogICAgbWFza19zaXplID0gc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2tfc2l6ZSh3cml0ZV9tYXNrKTsKCiAgICBzaGFkZXJfZ2xzbF9hZGRfc3JjX3BhcmFtKGFyZywgYXJnLT5zcmNbMF0sIGFyZy0+c3JjX2FkZHJbMF0sIFdJTkVEM0RTUF9XUklURU1BU0tfMCB8IFdJTkVEM0RTUF9XUklURU1BU0tfMSwgJnNyYzBfcGFyYW0pOwogICAgc2hhZGVyX2dsc2xfYWRkX3NyY19wYXJhbShhcmcsIGFyZy0+c3JjWzFdLCBhcmctPnNyY19hZGRyWzFdLCBXSU5FRDNEU1BfV1JJVEVNQVNLXzAgfCBXSU5FRDNEU1BfV1JJVEVNQVNLXzEsICZzcmMxX3BhcmFtKTsKICAgIHNoYWRlcl9nbHNsX2FkZF9zcmNfcGFyYW0oYXJnLCBhcmctPnNyY1syXSwgYXJnLT5zcmNfYWRkclsyXSwgV0lORUQzRFNQX1dSSVRFTUFTS18wLCAmc3JjMl9wYXJhbSk7CgogICAgaWYgKG1hc2tfc2l6ZSA+IDEpIHsKICAgICAgICBzaGFkZXJfYWRkbGluZShhcmctPmJ1ZmZlciwgInZlYyVkKGRvdCglcywgJXMpICsgJXMpKTtcbiIsIG1hc2tfc2l6ZSwgc3JjMF9wYXJhbS5wYXJhbV9zdHIsIHNyYzFfcGFyYW0ucGFyYW1fc3RyLCBzcmMyX3BhcmFtLnBhcmFtX3N0cik7CiAgICB9IGVsc2UgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGFyZy0+YnVmZmVyLCAiZG90KCVzLCAlcykgKyAlcyk7XG4iLCBzcmMwX3BhcmFtLnBhcmFtX3N0ciwgc3JjMV9wYXJhbS5wYXJhbV9zdHIsIHNyYzJfcGFyYW0ucGFyYW1fc3RyKTsKICAgIH0KfQoKdm9pZCBwc2hhZGVyX2dsc2xfaW5wdXRfcGFjaygKICAgU0hBREVSX0JVRkZFUiogYnVmZmVyLAogICBzZW1hbnRpYyogc2VtYW50aWNzX2luLAogICBJV2luZUQzRFBpeGVsU2hhZGVyICppZmFjZSkgewoKICAgdW5zaWduZWQgaW50IGk7CiAgIElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICpUaGlzID0gKElXaW5lRDNEUGl4ZWxTaGFkZXJJbXBsICopIGlmYWNlOwoKICAgZm9yIChpID0gMDsgaSA8IE1BWF9SRUdfSU5QVVQ7IGkrKykgewoKICAgICAgIERXT1JEIHVzYWdlX3Rva2VuID0gc2VtYW50aWNzX2luW2ldLnVzYWdlOwogICAgICAgRFdPUkQgcmVnaXN0ZXJfdG9rZW4gPSBzZW1hbnRpY3NfaW5baV0ucmVnOwogICAgICAgRFdPUkQgdXNhZ2UsIHVzYWdlX2lkeDsKICAgICAgIGNoYXIgcmVnX21hc2tbNl07CgogICAgICAgLyogVW5pbml0aWFsaXplZCAqLwogICAgICAgaWYgKCF1c2FnZV90b2tlbikgY29udGludWU7CiAgICAgICB1c2FnZSA9ICh1c2FnZV90b2tlbiAmIFdJTkVEM0RTUF9EQ0xfVVNBR0VfTUFTSykgPj4gV0lORUQzRFNQX0RDTF9VU0FHRV9TSElGVDsKICAgICAgIHVzYWdlX2lkeCA9ICh1c2FnZV90b2tlbiAmIFdJTkVEM0RTUF9EQ0xfVVNBR0VJTkRFWF9NQVNLKSA+PiBXSU5FRDNEU1BfRENMX1VTQUdFSU5ERVhfU0hJRlQ7CiAgICAgICBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFzayhyZWdpc3Rlcl90b2tlbiwgcmVnX21hc2spOwoKICAgICAgIHN3aXRjaCh1c2FnZSkgewoKICAgICAgICAgICBjYXNlIFdJTkVEM0RERUNMVVNBR0VfVEVYQ09PUkQ6CiAgICAgICAgICAgICAgIGlmKHVzYWdlX2lkeCA8IDggJiYgVGhpcy0+dmVydGV4cHJvY2Vzc2luZyA9PSBwcmV0cmFuc2Zvcm1lZCkgewogICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiSU5bJXVdJXMgPSBnbF9UZXhDb29yZFsldV0lcztcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5pbnB1dF9yZWdfbWFwW2ldLCByZWdfbWFzaywgdXNhZ2VfaWR4LCByZWdfbWFzayk7CiAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJJTlsldV0lcyA9IHZlYzQoMC4wLCAwLjAsIDAuMCwgMC4wKSVzO1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRoaXMtPmlucHV0X3JlZ19tYXBbaV0sIHJlZ19tYXNrLCByZWdfbWFzayk7CiAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgIGNhc2UgV0lORUQzRERFQ0xVU0FHRV9DT0xPUjoKICAgICAgICAgICAgICAgaWYgKHVzYWdlX2lkeCA9PSAwKQogICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiSU5bJXVdJXMgPSB2ZWM0KGdsX0NvbG9yKSVzO1xuIiwKICAgICAgICAgICAgICAgICAgICAgICBUaGlzLT5pbnB1dF9yZWdfbWFwW2ldLCByZWdfbWFzaywgcmVnX21hc2spOwogICAgICAgICAgICAgICBlbHNlIGlmICh1c2FnZV9pZHggPT0gMSkKICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIklOWyV1XSVzID0gdmVjNChnbF9TZWNvbmRhcnlDb2xvciklcztcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+aW5wdXRfcmVnX21hcFtpXSwgcmVnX21hc2ssIHJlZ19tYXNrKTsKICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiSU5bJXVdJXMgPSB2ZWM0KDAuMCwgMC4wLCAwLjAsIDAuMCklcztcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgVGhpcy0+aW5wdXRfcmVnX21hcFtpXSwgcmVnX21hc2ssIHJlZ19tYXNrKTsKICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIklOWyV1XSVzID0gdmVjNCgwLjAsIDAuMCwgMC4wLCAwLjApJXM7XG4iLAogICAgICAgICAgICAgICAgICAgVGhpcy0+aW5wdXRfcmVnX21hcFtpXSwgcmVnX21hc2ssIHJlZ19tYXNrKTsKICAgICAgICB9CiAgICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogVmVydGV4IFNoYWRlciBTcGVjaWZpYyBDb2RlIGJlZ2lucyBoZXJlCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyB2b2lkIGFkZF9nbHNsX3Byb2dyYW1fZW50cnkoSVdpbmVEM0REZXZpY2VJbXBsICpkZXZpY2UsIHN0cnVjdCBnbHNsX3NoYWRlcl9wcm9nX2xpbmsgKmVudHJ5KSB7CiAgICBnbHNsX3Byb2dyYW1fa2V5X3QgKmtleTsKCiAgICBrZXkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKGdsc2xfcHJvZ3JhbV9rZXlfdCkpOwogICAga2V5LT52c2hhZGVyID0gZW50cnktPnZzaGFkZXI7CiAgICBrZXktPnBzaGFkZXIgPSBlbnRyeS0+cHNoYWRlcjsKCiAgICBoYXNoX3RhYmxlX3B1dChkZXZpY2UtPmdsc2xfcHJvZ3JhbV9sb29rdXAsIGtleSwgZW50cnkpOwp9CgpzdGF0aWMgc3RydWN0IGdsc2xfc2hhZGVyX3Byb2dfbGluayAqZ2V0X2dsc2xfcHJvZ3JhbV9lbnRyeShJV2luZUQzRERldmljZUltcGwgKmRldmljZSwKICAgICAgICBHTGhhbmRsZUFSQiB2c2hhZGVyLCBHTGhhbmRsZUFSQiBwc2hhZGVyKSB7CiAgICBnbHNsX3Byb2dyYW1fa2V5X3Qga2V5OwoKICAgIGtleS52c2hhZGVyID0gdnNoYWRlcjsKICAgIGtleS5wc2hhZGVyID0gcHNoYWRlcjsKCiAgICByZXR1cm4gKHN0cnVjdCBnbHNsX3NoYWRlcl9wcm9nX2xpbmsgKiloYXNoX3RhYmxlX2dldChkZXZpY2UtPmdsc2xfcHJvZ3JhbV9sb29rdXAsICZrZXkpOwp9Cgp2b2lkIGRlbGV0ZV9nbHNsX3Byb2dyYW1fZW50cnkoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBzdHJ1Y3QgZ2xzbF9zaGFkZXJfcHJvZ19saW5rICplbnRyeSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvID0gJlRoaXMtPmFkYXB0ZXItPmdsX2luZm87CiAgICBnbHNsX3Byb2dyYW1fa2V5X3QgKmtleTsKCiAgICBrZXkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKGdsc2xfcHJvZ3JhbV9rZXlfdCkpOwogICAga2V5LT52c2hhZGVyID0gZW50cnktPnZzaGFkZXI7CiAgICBrZXktPnBzaGFkZXIgPSBlbnRyeS0+cHNoYWRlcjsKICAgIGhhc2hfdGFibGVfcmVtb3ZlKFRoaXMtPmdsc2xfcHJvZ3JhbV9sb29rdXAsIGtleSk7CgogICAgR0xfRVhUQ0FMTChnbERlbGV0ZU9iamVjdEFSQihlbnRyeS0+cHJvZ3JhbUlkKSk7CiAgICBpZiAoZW50cnktPnZzaGFkZXIpIGxpc3RfcmVtb3ZlKCZlbnRyeS0+dnNoYWRlcl9lbnRyeSk7CiAgICBpZiAoZW50cnktPnBzaGFkZXIpIGxpc3RfcmVtb3ZlKCZlbnRyeS0+cHNoYWRlcl9lbnRyeSk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBlbnRyeS0+dnVuaWZvcm1GX2xvY2F0aW9ucyk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBlbnRyeS0+cHVuaWZvcm1GX2xvY2F0aW9ucyk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBlbnRyeSk7Cn0KCnN0YXRpYyB2b2lkIGhhbmRsZV9wczNfaW5wdXQoU0hBREVSX0JVRkZFUiAqYnVmZmVyLCBzZW1hbnRpYyAqc2VtYW50aWNzX2luLCBzZW1hbnRpYyAqc2VtYW50aWNzX291dCwgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvLCBEV09SRCAqbWFwKSB7CiAgICB1bnNpZ25lZCBpbnQgaSwgajsKICAgIERXT1JEIHVzYWdlX3Rva2VuLCB1c2FnZV90b2tlbl9vdXQ7CiAgICBEV09SRCByZWdpc3Rlcl90b2tlbiwgcmVnaXN0ZXJfdG9rZW5fb3V0OwogICAgRFdPUkQgdXNhZ2UsIHVzYWdlX2lkeCwgdXNhZ2Vfb3V0LCB1c2FnZV9pZHhfb3V0OwogICAgRFdPUkQgKnNldDsKICAgIGNoYXIgcmVnX21hc2tbNl0sIHJlZ19tYXNrX291dFs2XTsKCiAgICBzZXQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKCpzZXQpICogKEdMX0xJTUlUUyhnbHNsX3ZhcnlpbmdzKSAvIDQpKTsKCiAgICBmb3IoaSA9IDA7IGkgPCBNQVhfUkVHX0lOUFVUOyBpKyspIHsKICAgICAgICB1c2FnZV90b2tlbiA9IHNlbWFudGljc19pbltpXS51c2FnZTsKICAgICAgICBpZiAoIXVzYWdlX3Rva2VuKSBjb250aW51ZTsKICAgICAgICBpZihtYXBbaV0gPj0gKEdMX0xJTUlUUyhnbHNsX3ZhcnlpbmdzKSAvIDQpKSB7CiAgICAgICAgICAgIEZJWE1FKCJNb3JlIGlucHV0IHZhcnlpbmdzIGRlY2xhcmVkIHRoYW4gc3VwcG9ydGVkLCBleHBlY3QgaXNzdWVzXG4iKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfSBlbHNlIGlmKG1hcFtpXSA9PSAtMSkgewogICAgICAgICAgICAvKiBEZWNsYXJlZCwgYnV0IG5vdCByZWFkIHJlZ2lzdGVyICovCiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICByZWdpc3Rlcl90b2tlbiA9IHNlbWFudGljc19pbltpXS5yZWc7CgogICAgICAgIHVzYWdlID0gKHVzYWdlX3Rva2VuICYgV0lORUQzRFNQX0RDTF9VU0FHRV9NQVNLKSA+PiBXSU5FRDNEU1BfRENMX1VTQUdFX1NISUZUOwogICAgICAgIHVzYWdlX2lkeCA9ICh1c2FnZV90b2tlbiAmIFdJTkVEM0RTUF9EQ0xfVVNBR0VJTkRFWF9NQVNLKSA+PiBXSU5FRDNEU1BfRENMX1VTQUdFSU5ERVhfU0hJRlQ7CiAgICAgICAgc2V0W21hcFtpXV0gPSBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFzayhyZWdpc3Rlcl90b2tlbiwgcmVnX21hc2spOwoKICAgICAgICBpZighc2VtYW50aWNzX291dCkgewogICAgICAgICAgICBzd2l0Y2godXNhZ2UpIHsKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRERFQ0xVU0FHRV9DT0xPUjoKICAgICAgICAgICAgICAgICAgICBpZiAodXNhZ2VfaWR4ID09IDApCiAgICAgICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIklOWyV1XSVzID0gZ2xfRnJvbnRDb2xvciVzO1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwW2ldLCByZWdfbWFzaywgcmVnX21hc2spOwogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHVzYWdlX2lkeCA9PSAxKQogICAgICAgICAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJJTlsldV0lcyA9IGdsX0Zyb250U2Vjb25kYXJ5Q29sb3IlcztcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcFtpXSwgcmVnX21hc2ssIHJlZ19tYXNrKTsKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIklOWyV1XSVzID0gdmVjNCgwLjAsIDAuMCwgMC4wLCAwLjApJXM7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXBbaV0sIHJlZ19tYXNrLCByZWdfbWFzayk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEREVDTFVTQUdFX1RFWENPT1JEOgogICAgICAgICAgICAgICAgICAgIGlmICh1c2FnZV9pZHggPCA4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIklOWyV1XSVzID0gZ2xfVGV4Q29vcmRbJXVdJXM7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXBbaV0sIHJlZ19tYXNrLCB1c2FnZV9pZHgsIHJlZ19tYXNrKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJJTlsldV0lcyA9IHZlYzQoMC4wLCAwLjAsIDAuMCwgMC4wKSVzO1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwW2ldLCByZWdfbWFzaywgcmVnX21hc2spOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RERUNMVVNBR0VfRk9HOgogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIklOWyV1XSVzID0gdmVjNChnbF9Gb2dGcmFnQ29vcmQsIDAuMCwgMC4wLCAwLjApJXM7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcFtpXSwgcmVnX21hc2ssIHJlZ19tYXNrKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIklOWyV1XSVzID0gdmVjNCgwLjAsIDAuMCwgMC4wLCAwLjApJXM7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcFtpXSwgcmVnX21hc2ssIHJlZ19tYXNrKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIEJPT0wgZm91bmQgPSBGQUxTRTsKICAgICAgICAgICAgZm9yKGogPSAwOyBqIDwgTUFYX1JFR19PVVRQVVQ7IGorKykgewogICAgICAgICAgICAgICAgdXNhZ2VfdG9rZW5fb3V0ID0gc2VtYW50aWNzX291dFtqXS51c2FnZTsKICAgICAgICAgICAgICAgIGlmICghdXNhZ2VfdG9rZW5fb3V0KSBjb250aW51ZTsKICAgICAgICAgICAgICAgIHJlZ2lzdGVyX3Rva2VuX291dCA9IHNlbWFudGljc19vdXRbal0ucmVnOwoKICAgICAgICAgICAgICAgIHVzYWdlX291dCA9ICh1c2FnZV90b2tlbl9vdXQgJiBXSU5FRDNEU1BfRENMX1VTQUdFX01BU0spID4+IFdJTkVEM0RTUF9EQ0xfVVNBR0VfU0hJRlQ7CiAgICAgICAgICAgICAgICB1c2FnZV9pZHhfb3V0ID0gKHVzYWdlX3Rva2VuX291dCAmIFdJTkVEM0RTUF9EQ0xfVVNBR0VJTkRFWF9NQVNLKSA+PiBXSU5FRDNEU1BfRENMX1VTQUdFSU5ERVhfU0hJRlQ7CiAgICAgICAgICAgICAgICBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFzayhyZWdpc3Rlcl90b2tlbl9vdXQsIHJlZ19tYXNrX291dCk7CgogICAgICAgICAgICAgICAgaWYodXNhZ2UgPT0gdXNhZ2Vfb3V0ICYmCiAgICAgICAgICAgICAgICAgICB1c2FnZV9pZHggPT0gdXNhZ2VfaWR4X291dCkgewogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIklOWyV1XSVzID0gT1VUWyV1XSVzO1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXBbaV0sIHJlZ19tYXNrLCBqLCByZWdfbWFzayk7CiAgICAgICAgICAgICAgICAgICAgZm91bmQgPSBUUlVFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKCFmb3VuZCkgewogICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiSU5bJXVdJXMgPSB2ZWM0KDAuMCwgMC4wLCAwLjAsIDAuMCklcztcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXBbaV0sIHJlZ19tYXNrLCByZWdfbWFzayk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyogVGhpcyBpcyBzb2xlbHkgdG8gbWFrZSB0aGUgY29tcGlsZXIgLyBsaW5rZXIgaGFwcHkgYW5kIGF2b2lkIHdhcm5pbmcgYWJvdXQgdW5kZWZpbmVkCiAgICAgKiB2YXJ5aW5ncy4gSXQgc2hvdWxkbid0IHJlc3VsdCBpbiBhbnkgcmVhbCBjb2RlIGV4ZWN1dGVkIG9uIHRoZSBHUFUsIHNpbmNlIGFsbCByZWFkCiAgICAgKiBpbnB1dCB2YXJ5aW5ncyBhcmUgYXNzaWduZWQgYWJvdmUsIGlmIHRoZSBvcHRpbWl6ZXIgd29ya3MgcHJvcGVybHkuCiAgICAgKi8KICAgIGZvcihpID0gMDsgaSA8IEdMX0xJTUlUUyhnbHNsX3ZhcnlpbmdzKSAvIDQ7IGkrKykgewogICAgICAgIGlmKHNldFtpXSAhPSBXSU5FRDNEU1BfV1JJVEVNQVNLX0FMTCkgewogICAgICAgICAgICB1bnNpZ25lZCBpbnQgc2l6ZSA9IDA7CiAgICAgICAgICAgIG1lbXNldChyZWdfbWFzaywgMCwgc2l6ZW9mKHJlZ19tYXNrKSk7CiAgICAgICAgICAgIGlmKCEoc2V0W2ldICYgV0lORUQzRFNQX1dSSVRFTUFTS18wKSkgewogICAgICAgICAgICAgICAgcmVnX21hc2tbc2l6ZV0gPSAneCc7CiAgICAgICAgICAgICAgICBzaXplKys7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYoIShzZXRbaV0gJiBXSU5FRDNEU1BfV1JJVEVNQVNLXzEpKSB7CiAgICAgICAgICAgICAgICByZWdfbWFza1tzaXplXSA9ICd5JzsKICAgICAgICAgICAgICAgIHNpemUrKzsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZighKHNldFtpXSAmIFdJTkVEM0RTUF9XUklURU1BU0tfMikpIHsKICAgICAgICAgICAgICAgIHJlZ19tYXNrW3NpemVdID0gJ3onOwogICAgICAgICAgICAgICAgc2l6ZSsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmKCEoc2V0W2ldICYgV0lORUQzRFNQX1dSSVRFTUFTS18zKSkgewogICAgICAgICAgICAgICAgcmVnX21hc2tbc2l6ZV0gPSAndyc7CiAgICAgICAgICAgICAgICBzaXplKys7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3dpdGNoKHNpemUpIHsKICAgICAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJJTlsldV0uJXMgPSAwLjA7XG4iLCBpLCByZWdfbWFzayk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiSU5bJXVdLiVzID0gdmVjMigwLjAsIDAuMCk7XG4iLCBpLCByZWdfbWFzayk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIDM6CiAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiSU5bJXVdLiVzID0gdmVjMygwLjAsIDAuMCwgMC4wKTtcbiIsIGksIHJlZ19tYXNrKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgNDoKICAgICAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJJTlsldV0uJXMgPSB2ZWM0KDAuMCwgMC4wLCAwLjAsIDAuMCk7XG4iLCBpLCByZWdfbWFzayk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2V0KTsKfQoKc3RhdGljIEdMaGFuZGxlQVJCIGdlbmVyYXRlX3BhcmFtX3Jlb3JkZXJfZnVuY3Rpb24oSVdpbmVEM0RWZXJ0ZXhTaGFkZXIgKnZlcnRleHNoYWRlciwKICAgICAgICBJV2luZUQzRFBpeGVsU2hhZGVyICpwaXhlbHNoYWRlciwKICAgICAgICBXaW5lRDNEX0dMX0luZm8gKmdsX2luZm8pIHsKICAgIEdMaGFuZGxlQVJCIHJldCA9IDA7CiAgICBJV2luZUQzRFZlcnRleFNoYWRlckltcGwgKnZzID0gKElXaW5lRDNEVmVydGV4U2hhZGVySW1wbCAqKSB2ZXJ0ZXhzaGFkZXI7CiAgICBJV2luZUQzRFBpeGVsU2hhZGVySW1wbCAqcHMgPSAoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwgKikgcGl4ZWxzaGFkZXI7CiAgICBEV09SRCB2c19tYWpvciA9IHZzID8gV0lORUQzRFNIQURFUl9WRVJTSU9OX01BSk9SKHZzLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uKSA6IDA7CiAgICBEV09SRCBwc19tYWpvciA9IHBzID8gV0lORUQzRFNIQURFUl9WRVJTSU9OX01BSk9SKHBzLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uKSA6IDA7CiAgICB1bnNpZ25lZCBpbnQgaTsKICAgIFNIQURFUl9CVUZGRVIgYnVmZmVyOwogICAgRFdPUkQgdXNhZ2VfdG9rZW47CiAgICBEV09SRCByZWdpc3Rlcl90b2tlbjsKICAgIERXT1JEIHVzYWdlLCB1c2FnZV9pZHgsIHdyaXRlbWFzazsKICAgIGNoYXIgcmVnX21hc2tbNl07CiAgICBzZW1hbnRpYyAqc2VtYW50aWNzX291dCwgKnNlbWFudGljc19pbjsKCiAgICBidWZmZXIuYnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIFNIQURFUl9QR01TSVpFKTsKICAgIGJ1ZmZlci5ic2l6ZSA9IDA7CiAgICBidWZmZXIubGluZU5vID0gMDsKICAgIGJ1ZmZlci5uZXdsaW5lID0gVFJVRTsKCiAgICBpZih2c19tYWpvciA8IDMgJiYgcHNfbWFqb3IgPCAzKSB7CiAgICAgICAgLyogVGhhdCBvbmUgaXMgZWFzeTogVGhlIHZlcnRleCBzaGFkZXIgd3JpdGVzIHRvIHRoZSBidWlsdGluIHZhcnlpbmdzLCB0aGUgcGl4ZWwgc2hhZGVyIHJlYWRzIGZyb20gdGhlbS4KICAgICAgICAgKiBUYWtlIGNhcmUgYWJvdXQgdGhlIHRleGNvb3JkIC53IGZpeHVwIHRob3VnaCBpZiB3ZSdyZSB1c2luZyB0aGUgZml4ZWQgZnVuY3Rpb24gZnJhZ21lbnQgcGlwZWxpbmUKICAgICAgICAgKi8KICAgICAgICBpZigoR0xJTkZPX0xPQ0FUSU9OKS5zZXRfdGV4Y29vcmRfdyAmJiBwc19tYWpvciA9PSAwICYmIHZzX21ham9yID4gMCkgewogICAgICAgICAgICBzaGFkZXJfYWRkbGluZSgmYnVmZmVyLCAidm9pZCBvcmRlcl9wc19pbnB1dCgpIHtcbiIpOwogICAgICAgICAgICBmb3IoaSA9IDA7IGkgPCBtaW4oOCwgTUFYX1JFR19URVhDUkQpOyBpKyspIHsKICAgICAgICAgICAgICAgIGlmKHZzLT5iYXNlU2hhZGVyLnJlZ19tYXBzLnRleGNvb3JkX21hc2tbaV0gIT0gMCAmJgogICAgICAgICAgICAgICAgICAgdnMtPmJhc2VTaGFkZXIucmVnX21hcHMudGV4Y29vcmRfbWFza1tpXSAhPSBXSU5FRDNEU1BfV1JJVEVNQVNLX0FMTCkgewogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKCZidWZmZXIsICJnbF9UZXhDb29yZFsldV0udyA9IDEuMDtcbiIsIGkpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKCZidWZmZXIsICJ9XG4iKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzaGFkZXJfYWRkbGluZSgmYnVmZmVyLCAidm9pZCBvcmRlcl9wc19pbnB1dCgpIHsgLyogZG8gbm90aGluZyAqLyB9XG4iKTsKICAgICAgICB9CiAgICB9IGVsc2UgaWYocHNfbWFqb3IgPCAzICYmIHZzX21ham9yID49IDMpIHsKICAgICAgICAvKiBUaGUgdmVydGV4IHNoYWRlciB3cml0ZXMgdG8gaXRzIG93biB2YXJ5aW5ncywgdGhlIHBpeGVsIHNoYWRlciBuZWVkcyB0aGVtIGluIHRoZSBidWlsdGluIG9uZXMgKi8KICAgICAgICBzZW1hbnRpY3Nfb3V0ID0gdnMtPnNlbWFudGljc19vdXQ7CgogICAgICAgIHNoYWRlcl9hZGRsaW5lKCZidWZmZXIsICJ2b2lkIG9yZGVyX3BzX2lucHV0KGluIHZlYzQgT1VUWyV1XSkge1xuIiwgTUFYX1JFR19PVVRQVVQpOwogICAgICAgIGZvcihpID0gMDsgaSA8IE1BWF9SRUdfT1VUUFVUOyBpKyspIHsKICAgICAgICAgICAgdXNhZ2VfdG9rZW4gPSBzZW1hbnRpY3Nfb3V0W2ldLnVzYWdlOwogICAgICAgICAgICBpZiAoIXVzYWdlX3Rva2VuKSBjb250aW51ZTsKICAgICAgICAgICAgcmVnaXN0ZXJfdG9rZW4gPSBzZW1hbnRpY3Nfb3V0W2ldLnJlZzsKCiAgICAgICAgICAgIHVzYWdlID0gKHVzYWdlX3Rva2VuICYgV0lORUQzRFNQX0RDTF9VU0FHRV9NQVNLKSA+PiBXSU5FRDNEU1BfRENMX1VTQUdFX1NISUZUOwogICAgICAgICAgICB1c2FnZV9pZHggPSAodXNhZ2VfdG9rZW4gJiBXSU5FRDNEU1BfRENMX1VTQUdFSU5ERVhfTUFTSykgPj4gV0lORUQzRFNQX0RDTF9VU0FHRUlOREVYX1NISUZUOwogICAgICAgICAgICB3cml0ZW1hc2sgPSBzaGFkZXJfZ2xzbF9nZXRfd3JpdGVfbWFzayhyZWdpc3Rlcl90b2tlbiwgcmVnX21hc2spOwoKICAgICAgICAgICAgc3dpdGNoKHVzYWdlKSB7CiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RERUNMVVNBR0VfQ09MT1I6CiAgICAgICAgICAgICAgICAgICAgaWYgKHVzYWdlX2lkeCA9PSAwKQogICAgICAgICAgICAgICAgICAgICAgICBzaGFkZXJfYWRkbGluZSgmYnVmZmVyLCAiZ2xfRnJvbnRDb2xvciVzID0gT1VUWyV1XSVzO1xuIiwgcmVnX21hc2ssIGksIHJlZ19tYXNrKTsKICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICh1c2FnZV9pZHggPT0gMSkKICAgICAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoJmJ1ZmZlciwgImdsX0Zyb250U2Vjb25kYXJ5Q29sb3IlcyA9IE9VVFsldV0lcztcbiIsIHJlZ19tYXNrLCBpLCByZWdfbWFzayk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEREVDTFVTQUdFX1BPU0lUSU9OOgogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKCZidWZmZXIsICJnbF9Qb3NpdGlvbiVzID0gT1VUWyV1XSVzO1xuIiwgcmVnX21hc2ssIGksIHJlZ19tYXNrKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RERUNMVVNBR0VfVEVYQ09PUkQ6CiAgICAgICAgICAgICAgICAgICAgaWYgKHVzYWdlX2lkeCA8IDgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYoIShHTElORk9fTE9DQVRJT04pLnNldF90ZXhjb29yZF93IHx8IHBzX21ham9yID4gMCkgd3JpdGVtYXNrIHw9IFdJTkVEM0RTUF9XUklURU1BU0tfMzsKCiAgICAgICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKCZidWZmZXIsICJnbF9UZXhDb29yZFsldV0lcyA9IE9VVFsldV0lcztcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2FnZV9pZHgsIHJlZ19tYXNrLCBpLCByZWdfbWFzayk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmKCEod3JpdGVtYXNrICYgV0lORUQzRFNQX1dSSVRFTUFTS18zKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoJmJ1ZmZlciwgImdsX1RleENvb3JkWyV1XS53ID0gMS4wO1xuIiwgdXNhZ2VfaWR4KTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RERUNMVVNBR0VfUFNJWkU6CiAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoJmJ1ZmZlciwgImdsX1BvaW50U2l6ZSA9IE9VVFsldV0ueDtcbiIsIGkpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGNhc2UgV0lORUQzRERFQ0xVU0FHRV9GT0c6CiAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoJmJ1ZmZlciwgImdsX0ZvZ0ZyYWdDb29yZCA9IE9VVFsldV0uJWM7XG4iLCBpLCByZWdfbWFza1sxXSk7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBzaGFkZXJfYWRkbGluZSgmYnVmZmVyLCAifVxuIik7CgogICAgfSBlbHNlIGlmKHBzX21ham9yID49IDMgJiYgdnNfbWFqb3IgPj0gMykgewogICAgICAgIHNlbWFudGljc19vdXQgPSB2cy0+c2VtYW50aWNzX291dDsKICAgICAgICBzZW1hbnRpY3NfaW4gPSBwcy0+c2VtYW50aWNzX2luOwoKICAgICAgICAvKiBUaGlzIG9uZSBpcyB0cmlja3k6IGEgMy4wIHBpeGVsIHNoYWRlciByZWFkcyBmcm9tIGEgMy4wIHZlcnRleCBzaGFkZXIgKi8KICAgICAgICBzaGFkZXJfYWRkbGluZSgmYnVmZmVyLCAidmFyeWluZyB2ZWM0IElOWyV1XTtcbiIsIEdMX0xJTUlUUyhnbHNsX3ZhcnlpbmdzKSAvIDQpOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKCZidWZmZXIsICJ2b2lkIG9yZGVyX3BzX2lucHV0KGluIHZlYzQgT1VUWyV1XSkge1xuIiwgTUFYX1JFR19PVVRQVVQpOwoKICAgICAgICAvKiBGaXJzdCwgc29ydCBvdXQgcG9zaXRpb24gYW5kIHBvaW50IHNpemUuIFRob3NlIGFyZSBub3QgcGFzc2VkIHRvIHRoZSBwaXhlbCBzaGFkZXIgKi8KICAgICAgICBmb3IoaSA9IDA7IGkgPCBNQVhfUkVHX09VVFBVVDsgaSsrKSB7CiAgICAgICAgICAgIHVzYWdlX3Rva2VuID0gc2VtYW50aWNzX291dFtpXS51c2FnZTsKICAgICAgICAgICAgaWYgKCF1c2FnZV90b2tlbikgY29udGludWU7CiAgICAgICAgICAgIHJlZ2lzdGVyX3Rva2VuID0gc2VtYW50aWNzX291dFtpXS5yZWc7CgogICAgICAgICAgICB1c2FnZSA9ICh1c2FnZV90b2tlbiAmIFdJTkVEM0RTUF9EQ0xfVVNBR0VfTUFTSykgPj4gV0lORUQzRFNQX0RDTF9VU0FHRV9TSElGVDsKICAgICAgICAgICAgdXNhZ2VfaWR4ID0gKHVzYWdlX3Rva2VuICYgV0lORUQzRFNQX0RDTF9VU0FHRUlOREVYX01BU0spID4+IFdJTkVEM0RTUF9EQ0xfVVNBR0VJTkRFWF9TSElGVDsKICAgICAgICAgICAgc2hhZGVyX2dsc2xfZ2V0X3dyaXRlX21hc2socmVnaXN0ZXJfdG9rZW4sIHJlZ19tYXNrKTsKCiAgICAgICAgICAgIHN3aXRjaCh1c2FnZSkgewogICAgICAgICAgICAgICAgY2FzZSBXSU5FRDNEREVDTFVTQUdFX1BPU0lUSU9OOgogICAgICAgICAgICAgICAgICAgIHNoYWRlcl9hZGRsaW5lKCZidWZmZXIsICJnbF9Qb3NpdGlvbiVzID0gT1VUWyV1XSVzO1xuIiwgcmVnX21hc2ssIGksIHJlZ19tYXNrKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICBjYXNlIFdJTkVEM0RERUNMVVNBR0VfUFNJWkU6CiAgICAgICAgICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoJmJ1ZmZlciwgImdsX1BvaW50U2l6ZSA9IE9VVFsldV0ueDtcbiIsIGkpOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8qIFRoZW4sIGZpeCB0aGUgcGl4ZWwgc2hhZGVyIGlucHV0ICovCiAgICAgICAgaGFuZGxlX3BzM19pbnB1dCgmYnVmZmVyLCBzZW1hbnRpY3NfaW4sIHNlbWFudGljc19vdXQsIGdsX2luZm8sIHBzLT5pbnB1dF9yZWdfbWFwKTsKCiAgICAgICAgc2hhZGVyX2FkZGxpbmUoJmJ1ZmZlciwgIn1cbiIpOwogICAgfSBlbHNlIGlmKHBzX21ham9yID49IDMgJiYgdnNfbWFqb3IgPCAzKSB7CiAgICAgICAgc2VtYW50aWNzX2luID0gcHMtPnNlbWFudGljc19pbjsKCiAgICAgICAgc2hhZGVyX2FkZGxpbmUoJmJ1ZmZlciwgInZhcnlpbmcgdmVjNCBJTlsldV07XG4iLCBHTF9MSU1JVFMoZ2xzbF92YXJ5aW5ncykgLyA0KTsKICAgICAgICBzaGFkZXJfYWRkbGluZSgmYnVmZmVyLCAidm9pZCBvcmRlcl9wc19pbnB1dCgpIHtcbiIpOwogICAgICAgIC8qIFRoZSB2ZXJ0ZXggc2hhZGVyIHdyb3RlIHRvIHRoZSBidWlsdGluIHZhcnlpbmdzLiBUaGVyZSBpcyBubyBuZWVkIHRvIGZpZ3VyZSBvdXQgcG9zaXRpb24gYW5kCiAgICAgICAgICogcG9pbnQgc2l6ZSwgYnV0IHdlIGRlcGVuZCBvbiB0aGUgb3B0aW1pemVycyBraW5kbmVzcyB0byBmaW5kIG91dCB0aGF0IHRoZSBwaXhlbCBzaGFkZXIgZG9lc24ndAogICAgICAgICAqIHJlYWQgZ2xfVGV4Q29vcmQgYW5kIGdsX0NvbG9yWCwgb3RoZXJ3aXNlIHdlJ2xsIHJ1biBvdXQgb2YgdmFyeWluZ3MKICAgICAgICAgKi8KICAgICAgICBoYW5kbGVfcHMzX2lucHV0KCZidWZmZXIsIHNlbWFudGljc19pbiwgTlVMTCwgZ2xfaW5mbywgcHMtPmlucHV0X3JlZ19tYXApOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKCZidWZmZXIsICJ9XG4iKTsKICAgIH0gZWxzZSB7CiAgICAgICAgRVJSKCJVbmV4cGVjdGVkIHZlcnRleCBhbmQgcGl4ZWwgc2hhZGVyIHZlcnNpb24gY29uZGl0aW9uOiB2czogJWQsIHBzOiAlZFxuIiwgdnNfbWFqb3IsIHBzX21ham9yKTsKICAgIH0KCiAgICByZXQgPSBHTF9FWFRDQUxMKGdsQ3JlYXRlU2hhZGVyT2JqZWN0QVJCKEdMX1ZFUlRFWF9TSEFERVJfQVJCKSk7CiAgICBjaGVja0dMY2FsbCgiZ2xDcmVhdGVTaGFkZXJPYmplY3RBUkIoR0xfVkVSVEVYX1NIQURFUl9BUkIpIik7CiAgICBHTF9FWFRDQUxMKGdsU2hhZGVyU291cmNlQVJCKHJldCwgMSwgKGNvbnN0IGNoYXIqKikmYnVmZmVyLmJ1ZmZlciwgTlVMTCkpOwogICAgY2hlY2tHTGNhbGwoImdsU2hhZGVyU291cmNlQVJCKHJldCwgMSwgKGNvbnN0IGNoYXIqKikmYnVmZmVyLmJ1ZmZlciwgTlVMTCkiKTsKICAgIEdMX0VYVENBTEwoZ2xDb21waWxlU2hhZGVyQVJCKHJldCkpOwogICAgY2hlY2tHTGNhbGwoImdsQ29tcGlsZVNoYWRlckFSQihyZXQpIik7CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgYnVmZmVyLmJ1ZmZlcik7CiAgICByZXR1cm4gcmV0Owp9CgovKiogU2V0cyB0aGUgR0xTTCBwcm9ncmFtIElEIGZvciB0aGUgZ2l2ZW4gcGl4ZWwgYW5kIHZlcnRleCBzaGFkZXIgY29tYmluYXRpb24uCiAqIEl0IHNldHMgdGhlIHByb2dyYW1JZCBvbiB0aGUgY3VycmVudCBTdGF0ZUJsb2NrIChiZWNhdXNlIGl0IHNob3VsZCBiZSBjYWxsZWQKICogaW5zaWRlIG9mIHRoZSBEcmF3UHJpbWl0aXZlKCkgcGFydCBvZiB0aGUgcmVuZGVyIGxvb3ApLgogKgogKiBJZiBhIHByb2dyYW0gZm9yIHRoZSBnaXZlbiBjb21iaW5hdGlvbiBkb2VzIG5vdCBleGlzdCwgY3JlYXRlIG9uZSwgYW5kIHN0b3JlCiAqIHRoZSBwcm9ncmFtIGluIHRoZSBoYXNoIHRhYmxlLiAgSWYgaXQgY3JlYXRlcyBhIHByb2dyYW0sIGl0IHdpbGwgbGluayB0aGUKICogZ2l2ZW4gb2JqZWN0cywgdG9vLgogKi8Kc3RhdGljIHZvaWQgc2V0X2dsc2xfc2hhZGVyX3Byb2dyYW0oSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBCT09MIHVzZV9wcywgQk9PTCB1c2VfdnMpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyAgICAgICAgICAgICAgID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvICAgICAgICAgICAgICAgPSAmVGhpcy0+YWRhcHRlci0+Z2xfaW5mbzsKICAgIElXaW5lRDNEUGl4ZWxTaGFkZXIgICpwc2hhZGVyICAgICAgICAgID0gVGhpcy0+c3RhdGVCbG9jay0+cGl4ZWxTaGFkZXI7CiAgICBJV2luZUQzRFZlcnRleFNoYWRlciAqdnNoYWRlciAgICAgICAgICA9IFRoaXMtPnN0YXRlQmxvY2stPnZlcnRleFNoYWRlcjsKICAgIHN0cnVjdCBnbHNsX3NoYWRlcl9wcm9nX2xpbmsgKmVudHJ5ICAgID0gTlVMTDsKICAgIEdMaGFuZGxlQVJCIHByb2dyYW1JZCAgICAgICAgICAgICAgICAgID0gMDsKICAgIEdMaGFuZGxlQVJCIHJlb3JkZXJfc2hhZGVyX2lkICAgICAgICAgID0gMDsKICAgIGludCBpOwogICAgY2hhciBnbHNsX25hbWVbOF07CgogICAgR0xoYW5kbGVBUkIgdnNoYWRlcl9pZCA9IHVzZV92cyA/ICgoSVdpbmVEM0RCYXNlU2hhZGVySW1wbCopdnNoYWRlciktPmJhc2VTaGFkZXIucHJnSWQgOiAwOwogICAgR0xoYW5kbGVBUkIgcHNoYWRlcl9pZCA9IHVzZV9wcyA/ICgoSVdpbmVEM0RCYXNlU2hhZGVySW1wbCopcHNoYWRlciktPmJhc2VTaGFkZXIucHJnSWQgOiAwOwogICAgZW50cnkgPSBnZXRfZ2xzbF9wcm9ncmFtX2VudHJ5KFRoaXMsIHZzaGFkZXJfaWQsIHBzaGFkZXJfaWQpOwogICAgaWYgKGVudHJ5KSB7CiAgICAgICAgVGhpcy0+c3RhdGVCbG9jay0+Z2xzbF9wcm9ncmFtID0gZW50cnk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8qIElmIHdlIGdldCB0byB0aGlzIHBvaW50LCB0aGVuIG5vIG1hdGNoaW5nIHByb2dyYW0gZXhpc3RzLCBzbyB3ZSBjcmVhdGUgb25lICovCiAgICBwcm9ncmFtSWQgPSBHTF9FWFRDQUxMKGdsQ3JlYXRlUHJvZ3JhbU9iamVjdEFSQigpKTsKICAgIFRSQUNFKCJDcmVhdGVkIG5ldyBHTFNMIHNoYWRlciBwcm9ncmFtICV1XG4iLCBwcm9ncmFtSWQpOwoKICAgIC8qIENyZWF0ZSB0aGUgZW50cnkgKi8KICAgIGVudHJ5ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihzdHJ1Y3QgZ2xzbF9zaGFkZXJfcHJvZ19saW5rKSk7CiAgICBlbnRyeS0+cHJvZ3JhbUlkID0gcHJvZ3JhbUlkOwogICAgZW50cnktPnZzaGFkZXIgPSB2c2hhZGVyX2lkOwogICAgZW50cnktPnBzaGFkZXIgPSBwc2hhZGVyX2lkOwogICAgLyogQWRkIHRoZSBoYXNoIHRhYmxlIGVudHJ5ICovCiAgICBhZGRfZ2xzbF9wcm9ncmFtX2VudHJ5KFRoaXMsIGVudHJ5KTsKCiAgICAvKiBTZXQgdGhlIGN1cnJlbnQgcHJvZ3JhbSAqLwogICAgVGhpcy0+c3RhdGVCbG9jay0+Z2xzbF9wcm9ncmFtID0gZW50cnk7CgogICAgLyogQXR0YWNoIEdMU0wgdnNoYWRlciAqLwogICAgaWYgKHZzaGFkZXJfaWQpIHsKICAgICAgICBpbnQgbWF4X2F0dHJpYnMgPSAxNjsgICAvKiBUT0RPOiBXaWxsIHRoaXMgYWx3YXlzIGJlIHRoZSBjYXNlPyBJdCBpcyBhdCB0aGUgbW9tZW50Li4uICovCiAgICAgICAgY2hhciB0bXBfbmFtZVsxMF07CgogICAgICAgIHJlb3JkZXJfc2hhZGVyX2lkID0gZ2VuZXJhdGVfcGFyYW1fcmVvcmRlcl9mdW5jdGlvbih2c2hhZGVyLCBwc2hhZGVyLCBnbF9pbmZvKTsKICAgICAgICBUUkFDRSgiQXR0YWNoaW5nIEdMU0wgc2hhZGVyIG9iamVjdCAldSB0byBwcm9ncmFtICV1XG4iLCByZW9yZGVyX3NoYWRlcl9pZCwgcHJvZ3JhbUlkKTsKICAgICAgICBHTF9FWFRDQUxMKGdsQXR0YWNoT2JqZWN0QVJCKHByb2dyYW1JZCwgcmVvcmRlcl9zaGFkZXJfaWQpKTsKICAgICAgICBjaGVja0dMY2FsbCgiZ2xBdHRhY2hPYmplY3RBUkIiKTsKICAgICAgICAvKiBGbGFnIHRoZSByZW9yZGVyIGZ1bmN0aW9uIGZvciBkZWxldGlvbiwgdGhlbiBpdCB3aWxsIGJlIGZyZWVkIGF1dG9tYXRpY2FsbHkgd2hlbiB0aGUgcHJvZ3JhbQogICAgICAgICAqIGlzIGRlc3Ryb3llZAogICAgICAgICAqLwogICAgICAgIEdMX0VYVENBTEwoZ2xEZWxldGVPYmplY3RBUkIocmVvcmRlcl9zaGFkZXJfaWQpKTsKCiAgICAgICAgVFJBQ0UoIkF0dGFjaGluZyBHTFNMIHNoYWRlciBvYmplY3QgJXUgdG8gcHJvZ3JhbSAldVxuIiwgdnNoYWRlcl9pZCwgcHJvZ3JhbUlkKTsKICAgICAgICBHTF9FWFRDQUxMKGdsQXR0YWNoT2JqZWN0QVJCKHByb2dyYW1JZCwgdnNoYWRlcl9pZCkpOwogICAgICAgIGNoZWNrR0xjYWxsKCJnbEF0dGFjaE9iamVjdEFSQiIpOwoKICAgICAgICAvKiBCaW5kIHZlcnRleCBhdHRyaWJ1dGVzIHRvIGEgY29ycmVzcG9uZGluZyBpbmRleCBudW1iZXIgdG8gbWF0Y2gKICAgICAgICAgKiB0aGUgc2FtZSBpbmRleCBudW1iZXJzIGFzIEFSQl92ZXJ0ZXhfcHJvZ3JhbXMgKG1ha2VzIGxvYWRpbmcKICAgICAgICAgKiB2ZXJ0ZXggYXR0cmlidXRlcyBzaW1wbGVyKS4gIFdpdGggdGhpcyBtZXRob2QsIHdlIGNhbiB1c2UgdGhlCiAgICAgICAgICogZXhhY3Qgc2FtZSBjb2RlIHRvIGxvYWQgdGhlIGF0dHJpYnV0ZXMgbGF0ZXIgZm9yIGJvdGggQVJCIGFuZAogICAgICAgICAqIEdMU0wgc2hhZGVycy4KICAgICAgICAgKgogICAgICAgICAqIFdlIGhhdmUgdG8gZG8gdGhpcyBoZXJlIGJlY2F1c2Ugd2UgbmVlZCB0byBrbm93IHRoZSBQcm9ncmFtIElECiAgICAgICAgICogaW4gb3JkZXIgdG8gbWFrZSB0aGUgYmluZGluZ3Mgd29yaywgYW5kIGl0IGhhcyB0byBiZSBkb25lIHByaW9yCiAgICAgICAgICogdG8gbGlua2luZyB0aGUgR0xTTCBwcm9ncmFtLiAqLwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBtYXhfYXR0cmliczsgKytpKSB7CiAgICAgICAgICAgIGlmICgoKElXaW5lRDNEQmFzZVNoYWRlckltcGwqKXZzaGFkZXIpLT5iYXNlU2hhZGVyLnJlZ19tYXBzLmF0dHJpYnV0ZXNbaV0pIHsKICAgICAgICAgICAgICAgIHNucHJpbnRmKHRtcF9uYW1lLCBzaXplb2YodG1wX25hbWUpLCAiYXR0cmliJWkiLCBpKTsKICAgICAgICAgICAgICAgIEdMX0VYVENBTEwoZ2xCaW5kQXR0cmliTG9jYXRpb25BUkIocHJvZ3JhbUlkLCBpLCB0bXBfbmFtZSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNoZWNrR0xjYWxsKCJnbEJpbmRBdHRyaWJMb2NhdGlvbkFSQiIpOwoKICAgICAgICBsaXN0X2FkZF9oZWFkKCYoKElXaW5lRDNEQmFzZVNoYWRlckltcGwgKil2c2hhZGVyKS0+YmFzZVNoYWRlci5saW5rZWRfcHJvZ3JhbXMsICZlbnRyeS0+dnNoYWRlcl9lbnRyeSk7CiAgICB9CgogICAgLyogQXR0YWNoIEdMU0wgcHNoYWRlciAqLwogICAgaWYgKHBzaGFkZXJfaWQpIHsKICAgICAgICBUUkFDRSgiQXR0YWNoaW5nIEdMU0wgc2hhZGVyIG9iamVjdCAldSB0byBwcm9ncmFtICV1XG4iLCBwc2hhZGVyX2lkLCBwcm9ncmFtSWQpOwogICAgICAgIEdMX0VYVENBTEwoZ2xBdHRhY2hPYmplY3RBUkIocHJvZ3JhbUlkLCBwc2hhZGVyX2lkKSk7CiAgICAgICAgY2hlY2tHTGNhbGwoImdsQXR0YWNoT2JqZWN0QVJCIik7CgogICAgICAgIGxpc3RfYWRkX2hlYWQoJigoSVdpbmVEM0RCYXNlU2hhZGVySW1wbCAqKXBzaGFkZXIpLT5iYXNlU2hhZGVyLmxpbmtlZF9wcm9ncmFtcywgJmVudHJ5LT5wc2hhZGVyX2VudHJ5KTsKICAgIH0KCiAgICAvKiBMaW5rIHRoZSBwcm9ncmFtICovCiAgICBUUkFDRSgiTGlua2luZyBHTFNMIHNoYWRlciBwcm9ncmFtICV1XG4iLCBwcm9ncmFtSWQpOwogICAgR0xfRVhUQ0FMTChnbExpbmtQcm9ncmFtQVJCKHByb2dyYW1JZCkpOwogICAgcHJpbnRfZ2xzbF9pbmZvX2xvZygmR0xJTkZPX0xPQ0FUSU9OLCBwcm9ncmFtSWQpOwoKICAgIGVudHJ5LT52dW5pZm9ybUZfbG9jYXRpb25zID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihHTGhhbmRsZUFSQikgKiBHTF9MSU1JVFModnNoYWRlcl9jb25zdGFudHNGKSk7CiAgICBmb3IgKGkgPSAwOyBpIDwgR0xfTElNSVRTKHZzaGFkZXJfY29uc3RhbnRzRik7ICsraSkgewogICAgICAgIHNucHJpbnRmKGdsc2xfbmFtZSwgc2l6ZW9mKGdsc2xfbmFtZSksICJWQ1slaV0iLCBpKTsKICAgICAgICBlbnRyeS0+dnVuaWZvcm1GX2xvY2F0aW9uc1tpXSA9IEdMX0VYVENBTEwoZ2xHZXRVbmlmb3JtTG9jYXRpb25BUkIocHJvZ3JhbUlkLCBnbHNsX25hbWUpKTsKICAgIH0KICAgIGZvciAoaSA9IDA7IGkgPCBNQVhfQ09OU1RfSTsgKytpKSB7CiAgICAgICAgc25wcmludGYoZ2xzbF9uYW1lLCBzaXplb2YoZ2xzbF9uYW1lKSwgIlZJWyVpXSIsIGkpOwogICAgICAgIGVudHJ5LT52dW5pZm9ybUlfbG9jYXRpb25zW2ldID0gR0xfRVhUQ0FMTChnbEdldFVuaWZvcm1Mb2NhdGlvbkFSQihwcm9ncmFtSWQsIGdsc2xfbmFtZSkpOwogICAgfQogICAgZW50cnktPnB1bmlmb3JtRl9sb2NhdGlvbnMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKEdMaGFuZGxlQVJCKSAqIEdMX0xJTUlUUyhwc2hhZGVyX2NvbnN0YW50c0YpKTsKICAgIGZvciAoaSA9IDA7IGkgPCBHTF9MSU1JVFMocHNoYWRlcl9jb25zdGFudHNGKTsgKytpKSB7CiAgICAgICAgc25wcmludGYoZ2xzbF9uYW1lLCBzaXplb2YoZ2xzbF9uYW1lKSwgIlBDWyVpXSIsIGkpOwogICAgICAgIGVudHJ5LT5wdW5pZm9ybUZfbG9jYXRpb25zW2ldID0gR0xfRVhUQ0FMTChnbEdldFVuaWZvcm1Mb2NhdGlvbkFSQihwcm9ncmFtSWQsIGdsc2xfbmFtZSkpOwogICAgfQogICAgZm9yIChpID0gMDsgaSA8IE1BWF9DT05TVF9JOyArK2kpIHsKICAgICAgICBzbnByaW50ZihnbHNsX25hbWUsIHNpemVvZihnbHNsX25hbWUpLCAiUElbJWldIiwgaSk7CiAgICAgICAgZW50cnktPnB1bmlmb3JtSV9sb2NhdGlvbnNbaV0gPSBHTF9FWFRDQUxMKGdsR2V0VW5pZm9ybUxvY2F0aW9uQVJCKHByb2dyYW1JZCwgZ2xzbF9uYW1lKSk7CiAgICB9CgogICAgaWYocHNoYWRlcikgewogICAgICAgIGZvcihpID0gMDsgaSA8ICgoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwqKXBzaGFkZXIpLT5udW1idW1wZW52bWF0Y29uc3RzOyBpKyspIHsKICAgICAgICAgICAgY2hhciBuYW1lWzMyXTsKICAgICAgICAgICAgc3ByaW50ZihuYW1lLCAiYnVtcGVudm1hdCVkIiwgKChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCopcHNoYWRlciktPmJ1bXBlbnZtYXRjb25zdFtpXS50ZXh1bml0KTsKICAgICAgICAgICAgZW50cnktPmJ1bXBlbnZtYXRfbG9jYXRpb25baV0gPSBHTF9FWFRDQUxMKGdsR2V0VW5pZm9ybUxvY2F0aW9uQVJCKHByb2dyYW1JZCwgbmFtZSkpOwogICAgICAgICAgICBzcHJpbnRmKG5hbWUsICJsdW1pbmFuY2VzY2FsZSVkIiwgKChJV2luZUQzRFBpeGVsU2hhZGVySW1wbCopcHNoYWRlciktPmx1bWluYW5jZWNvbnN0W2ldLnRleHVuaXQpOwogICAgICAgICAgICBlbnRyeS0+bHVtaW5hbmNlc2NhbGVfbG9jYXRpb25baV0gPSBHTF9FWFRDQUxMKGdsR2V0VW5pZm9ybUxvY2F0aW9uQVJCKHByb2dyYW1JZCwgbmFtZSkpOwogICAgICAgICAgICBzcHJpbnRmKG5hbWUsICJsdW1pbmFuY2VvZmZzZXQlZCIsICgoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwqKXBzaGFkZXIpLT5sdW1pbmFuY2Vjb25zdFtpXS50ZXh1bml0KTsKICAgICAgICAgICAgZW50cnktPmx1bWluYW5jZW9mZnNldF9sb2NhdGlvbltpXSA9IEdMX0VYVENBTEwoZ2xHZXRVbmlmb3JtTG9jYXRpb25BUkIocHJvZ3JhbUlkLCBuYW1lKSk7CiAgICAgICAgfQogICAgfQoKCiAgICBlbnRyeS0+cG9zRml4dXBfbG9jYXRpb24gPSBHTF9FWFRDQUxMKGdsR2V0VW5pZm9ybUxvY2F0aW9uQVJCKHByb2dyYW1JZCwgInBvc0ZpeHVwIikpOwogICAgZW50cnktPnNyZ2JfY29tcGFyaXNvbl9sb2NhdGlvbiA9IEdMX0VYVENBTEwoZ2xHZXRVbmlmb3JtTG9jYXRpb25BUkIocHJvZ3JhbUlkLCAic3JnYl9jb21wYXJpc29uIikpOwogICAgZW50cnktPnNyZ2JfbXVsX2xvd19sb2NhdGlvbiA9IEdMX0VYVENBTEwoZ2xHZXRVbmlmb3JtTG9jYXRpb25BUkIocHJvZ3JhbUlkLCAic3JnYl9tdWxfbG93IikpOwogICAgZW50cnktPnljb3JyZWN0aW9uX2xvY2F0aW9uID0gR0xfRVhUQ0FMTChnbEdldFVuaWZvcm1Mb2NhdGlvbkFSQihwcm9ncmFtSWQsICJ5Y29ycmVjdGlvbiIpKTsKICAgIGNoZWNrR0xjYWxsKCJGaW5kIGdsc2wgcHJvZ3JhbSB1bmlmb3JtIGxvY2F0aW9ucyIpOwoKICAgIC8qIFNldCB0aGUgc2hhZGVyIHRvIGFsbG93IHVuaWZvcm0gbG9hZGluZyBvbiBpdCAqLwogICAgR0xfRVhUQ0FMTChnbFVzZVByb2dyYW1PYmplY3RBUkIocHJvZ3JhbUlkKSk7CiAgICBjaGVja0dMY2FsbCgiZ2xVc2VQcm9ncmFtT2JqZWN0QVJCKHByb2dyYW1JZCkiKTsKCiAgICAvKiBMb2FkIHRoZSB2ZXJ0ZXggYW5kIHBpeGVsIHNhbXBsZXJzIG5vdy4gVGhlIGZ1bmN0aW9uIHRoYXQgZmluZHMgdGhlIG1hcHBpbmdzIG1ha2VzIHN1cmUKICAgICAqIHRoYXQgaXQgc3RheXMgdGhlIHNhbWUgZm9yIGVhY2ggdmVydGV4c2hhZGVyLXBpeGVsc2hhZGVyIHBhaXIoPWxpbmtlZCBnbHNsIHByb2dyYW0pLiBJZgogICAgICogYSBwc2hhZGVyIHdpdGggZml4ZWQgZnVuY3Rpb24gcGlwZWxpbmUgaXMgdXNlZCB0aGVyZSBhcmUgbm8gdmVydGV4IHNhbXBsZXJzLCBhbmQgaWYgYQogICAgICogdmVydGV4IHNoYWRlciB3aXRoIGZpeGVkIGZ1bmN0aW9uIHBpeGVsIHByb2Nlc3NpbmcgaXMgdXNlZCB3ZSBtYWtlIHN1cmUgdGhhdCB0aGUgY2FyZAogICAgICogc3VwcG9ydHMgZW5vdWdoIHNhbXBsZXJzIHRvIGFsbG93IHRoZSBtYXggbnVtYmVyIG9mIHZlcnRleCBzYW1wbGVycyB3aXRoIGFsbCBwb3NzaWJsZQogICAgICogZml4ZWQgZnVuY3Rpb24gZnJhZ21lbnQgcHJvY2Vzc2luZyBzZXR1cHMuIFNvIG9uY2UgdGhlIHByb2dyYW0gaXMgbGlua2VkIHRoZXNlIHNhbXBsZXJzCiAgICAgKiB3b24ndCBjaGFuZ2UuCiAgICAgKi8KICAgIGlmKHZzaGFkZXJfaWQpIHsKICAgICAgICAvKiBMb2FkIHZlcnRleCBzaGFkZXIgc2FtcGxlcnMgKi8KICAgICAgICBzaGFkZXJfZ2xzbF9sb2FkX3ZzYW1wbGVycyhnbF9pbmZvLCAoSVdpbmVEM0RTdGF0ZUJsb2NrKilUaGlzLT5zdGF0ZUJsb2NrLCBwcm9ncmFtSWQpOwogICAgfQogICAgaWYocHNoYWRlcl9pZCkgewogICAgICAgIC8qIExvYWQgcGl4ZWwgc2hhZGVyIHNhbXBsZXJzICovCiAgICAgICAgc2hhZGVyX2dsc2xfbG9hZF9wc2FtcGxlcnMoZ2xfaW5mbywgKElXaW5lRDNEU3RhdGVCbG9jayopVGhpcy0+c3RhdGVCbG9jaywgcHJvZ3JhbUlkKTsKICAgIH0KfQoKc3RhdGljIEdMaGFuZGxlQVJCIGNyZWF0ZV9nbHNsX2JsdF9zaGFkZXIoV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvKSB7CiAgICBHTGhhbmRsZUFSQiBwcm9ncmFtX2lkOwogICAgR0xoYW5kbGVBUkIgdnNoYWRlcl9pZCwgcHNoYWRlcl9pZDsKICAgIGNvbnN0IGNoYXIgKmJsdF92c2hhZGVyW10gPSB7CiAgICAgICAgInZvaWQgbWFpbih2b2lkKVxuIgogICAgICAgICJ7XG4iCiAgICAgICAgIiAgICBnbF9Qb3NpdGlvbiA9IGdsX1ZlcnRleDtcbiIKICAgICAgICAiICAgIGdsX0Zyb250Q29sb3IgPSB2ZWM0KDEuMCk7XG4iCiAgICAgICAgIiAgICBnbF9UZXhDb29yZFswXS54ID0gKGdsX1ZlcnRleC54ICogMC41KSArIDAuNTtcbiIKICAgICAgICAiICAgIGdsX1RleENvb3JkWzBdLnkgPSAoLWdsX1ZlcnRleC55ICogMC41KSArIDAuNTtcbiIKICAgICAgICAifVxuIgogICAgfTsKCiAgICBjb25zdCBjaGFyICpibHRfcHNoYWRlcltdID0gewogICAgICAgICJ1bmlmb3JtIHNhbXBsZXIyRCBzYW1wbGVyO1xuIgogICAgICAgICJ2b2lkIG1haW4odm9pZClcbiIKICAgICAgICAie1xuIgogICAgICAgICIgICAgZ2xfRnJhZ0RlcHRoID0gdGV4dHVyZTJEKHNhbXBsZXIsIGdsX1RleENvb3JkWzBdLnh5KS54O1xuIgogICAgICAgICJ9XG4iCiAgICB9OwoKICAgIHZzaGFkZXJfaWQgPSBHTF9FWFRDQUxMKGdsQ3JlYXRlU2hhZGVyT2JqZWN0QVJCKEdMX1ZFUlRFWF9TSEFERVJfQVJCKSk7CiAgICBHTF9FWFRDQUxMKGdsU2hhZGVyU291cmNlQVJCKHZzaGFkZXJfaWQsIDEsIGJsdF92c2hhZGVyLCBOVUxMKSk7CiAgICBHTF9FWFRDQUxMKGdsQ29tcGlsZVNoYWRlckFSQih2c2hhZGVyX2lkKSk7CgogICAgcHNoYWRlcl9pZCA9IEdMX0VYVENBTEwoZ2xDcmVhdGVTaGFkZXJPYmplY3RBUkIoR0xfRlJBR01FTlRfU0hBREVSX0FSQikpOwogICAgR0xfRVhUQ0FMTChnbFNoYWRlclNvdXJjZUFSQihwc2hhZGVyX2lkLCAxLCBibHRfcHNoYWRlciwgTlVMTCkpOwogICAgR0xfRVhUQ0FMTChnbENvbXBpbGVTaGFkZXJBUkIocHNoYWRlcl9pZCkpOwoKICAgIHByb2dyYW1faWQgPSBHTF9FWFRDQUxMKGdsQ3JlYXRlUHJvZ3JhbU9iamVjdEFSQigpKTsKICAgIEdMX0VYVENBTEwoZ2xBdHRhY2hPYmplY3RBUkIocHJvZ3JhbV9pZCwgdnNoYWRlcl9pZCkpOwogICAgR0xfRVhUQ0FMTChnbEF0dGFjaE9iamVjdEFSQihwcm9ncmFtX2lkLCBwc2hhZGVyX2lkKSk7CiAgICBHTF9FWFRDQUxMKGdsTGlua1Byb2dyYW1BUkIocHJvZ3JhbV9pZCkpOwoKICAgIHByaW50X2dsc2xfaW5mb19sb2coJkdMSU5GT19MT0NBVElPTiwgcHJvZ3JhbV9pZCk7CgogICAgLyogT25jZSBsaW5rZWQgd2UgY2FuIG1hcmsgdGhlIHNoYWRlcnMgZm9yIGRlbGV0aW9uLiBUaGV5IHdpbGwgYmUgZGVsZXRlZCBvbmNlIHRoZSBwcm9ncmFtCiAgICAgKiBpcyBkZXN0cm95ZWQKICAgICAqLwogICAgR0xfRVhUQ0FMTChnbERlbGV0ZU9iamVjdEFSQih2c2hhZGVyX2lkKSk7CiAgICBHTF9FWFRDQUxMKGdsRGVsZXRlT2JqZWN0QVJCKHBzaGFkZXJfaWQpKTsKICAgIHJldHVybiBwcm9ncmFtX2lkOwp9CgpzdGF0aWMgdm9pZCBzaGFkZXJfZ2xzbF9zZWxlY3QoSVdpbmVEM0REZXZpY2UgKmlmYWNlLCBCT09MIHVzZVBTLCBCT09MIHVzZVZTKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBXaW5lRDNEX0dMX0luZm8gKmdsX2luZm8gPSAmVGhpcy0+YWRhcHRlci0+Z2xfaW5mbzsKICAgIEdMaGFuZGxlQVJCIHByb2dyYW1faWQgPSAwOwoKICAgIGlmICh1c2VWUyB8fCB1c2VQUykgc2V0X2dsc2xfc2hhZGVyX3Byb2dyYW0oaWZhY2UsIHVzZVBTLCB1c2VWUyk7CiAgICBlbHNlIFRoaXMtPnN0YXRlQmxvY2stPmdsc2xfcHJvZ3JhbSA9IE5VTEw7CgogICAgcHJvZ3JhbV9pZCA9IFRoaXMtPnN0YXRlQmxvY2stPmdsc2xfcHJvZ3JhbSA/IFRoaXMtPnN0YXRlQmxvY2stPmdsc2xfcHJvZ3JhbS0+cHJvZ3JhbUlkIDogMDsKICAgIGlmIChwcm9ncmFtX2lkKSBUUkFDRSgiVXNpbmcgR0xTTCBwcm9ncmFtICV1XG4iLCBwcm9ncmFtX2lkKTsKICAgIEdMX0VYVENBTEwoZ2xVc2VQcm9ncmFtT2JqZWN0QVJCKHByb2dyYW1faWQpKTsKICAgIGNoZWNrR0xjYWxsKCJnbFVzZVByb2dyYW1PYmplY3RBUkIiKTsKfQoKc3RhdGljIHZvaWQgc2hhZGVyX2dsc2xfc2VsZWN0X2RlcHRoX2JsdChJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFdpbmVEM0RfR0xfSW5mbyAqZ2xfaW5mbyA9ICZUaGlzLT5hZGFwdGVyLT5nbF9pbmZvOwogICAgc3RydWN0IHNoYWRlcl9nbHNsX3ByaXYgKnByaXYgPSAoc3RydWN0IHNoYWRlcl9nbHNsX3ByaXYgKikgVGhpcy0+c2hhZGVyX3ByaXY7CiAgICBzdGF0aWMgR0xoYW5kbGVBUkIgbG9jID0gLTE7CgogICAgaWYgKCFwcml2LT5kZXB0aF9ibHRfZ2xzbF9wcm9ncmFtX2lkKSB7CiAgICAgICAgcHJpdi0+ZGVwdGhfYmx0X2dsc2xfcHJvZ3JhbV9pZCA9IGNyZWF0ZV9nbHNsX2JsdF9zaGFkZXIoZ2xfaW5mbyk7CiAgICAgICAgbG9jID0gR0xfRVhUQ0FMTChnbEdldFVuaWZvcm1Mb2NhdGlvbkFSQihwcml2LT5kZXB0aF9ibHRfZ2xzbF9wcm9ncmFtX2lkLCAic2FtcGxlciIpKTsKICAgIH0KCiAgICBHTF9FWFRDQUxMKGdsVXNlUHJvZ3JhbU9iamVjdEFSQihwcml2LT5kZXB0aF9ibHRfZ2xzbF9wcm9ncmFtX2lkKSk7CiAgICBHTF9FWFRDQUxMKGdsVW5pZm9ybTFpQVJCKGxvYywgMCkpOwp9CgpzdGF0aWMgdm9pZCBzaGFkZXJfZ2xzbF9kZXN0cm95X2RlcHRoX2JsdChJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIHN0cnVjdCBzaGFkZXJfZ2xzbF9wcml2ICpwcml2ID0gKHN0cnVjdCBzaGFkZXJfZ2xzbF9wcml2ICopIFRoaXMtPnNoYWRlcl9wcml2OwogICAgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvID0gJlRoaXMtPmFkYXB0ZXItPmdsX2luZm87CgogICAgaWYocHJpdi0+ZGVwdGhfYmx0X2dsc2xfcHJvZ3JhbV9pZCkgewogICAgICAgIEdMX0VYVENBTEwoZ2xEZWxldGVPYmplY3RBUkIocHJpdi0+ZGVwdGhfYmx0X2dsc2xfcHJvZ3JhbV9pZCkpOwogICAgICAgIHByaXYtPmRlcHRoX2JsdF9nbHNsX3Byb2dyYW1faWQgPSAwOwogICAgfQp9CgpzdGF0aWMgdm9pZCBzaGFkZXJfZ2xzbF9jbGVhbnVwKElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgSVdpbmVEM0REZXZpY2VJbXBsICpUaGlzID0gKElXaW5lRDNERGV2aWNlSW1wbCAqKWlmYWNlOwogICAgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvID0gJlRoaXMtPmFkYXB0ZXItPmdsX2luZm87CiAgICBHTF9FWFRDQUxMKGdsVXNlUHJvZ3JhbU9iamVjdEFSQigwKSk7Cn0KCnN0YXRpYyB2b2lkIHNoYWRlcl9nbHNsX2Rlc3Ryb3koSVdpbmVEM0RCYXNlU2hhZGVyICppZmFjZSkgewogICAgc3RydWN0IGxpc3QgKmxpbmtlZF9wcm9ncmFtczsKICAgIElXaW5lRDNEQmFzZVNoYWRlckltcGwgKlRoaXMgPSAoSVdpbmVEM0RCYXNlU2hhZGVySW1wbCAqKSBpZmFjZTsKICAgIFdpbmVEM0RfR0xfSW5mbyAqZ2xfaW5mbyA9ICYoKElXaW5lRDNERGV2aWNlSW1wbCAqKSBUaGlzLT5iYXNlU2hhZGVyLmRldmljZSktPmFkYXB0ZXItPmdsX2luZm87CgogICAgLyogTm90ZTogRG8gbm90IHVzZSBRdWVyeUludGVyZmFjZSBoZXJlIHRvIGZpbmQgb3V0IHdoaWNoIHNoYWRlciB0eXBlIHRoaXMgaXMgYmVjYXVzZSB0aGlzIGNvZGUKICAgICAqIGNhbiBiZSBjYWxsZWQgZnJvbSBJV2luZUQzREJhc2VTaGFkZXI6OlJlbGVhc2UKICAgICAqLwogICAgY2hhciBwc2hhZGVyID0gc2hhZGVyX2lzX3BzaGFkZXJfdmVyc2lvbihUaGlzLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uKTsKCiAgICBpZihUaGlzLT5iYXNlU2hhZGVyLnByZ0lkID09IDApIHJldHVybjsKICAgIGxpbmtlZF9wcm9ncmFtcyA9ICZUaGlzLT5iYXNlU2hhZGVyLmxpbmtlZF9wcm9ncmFtczsKCiAgICBUUkFDRSgiRGVsZXRpbmcgbGlua2VkIHByb2dyYW1zXG4iKTsKICAgIGlmIChsaW5rZWRfcHJvZ3JhbXMtPm5leHQpIHsKICAgICAgICBzdHJ1Y3QgZ2xzbF9zaGFkZXJfcHJvZ19saW5rICplbnRyeSwgKmVudHJ5MjsKCiAgICAgICAgaWYocHNoYWRlcikgewogICAgICAgICAgICBMSVNUX0ZPUl9FQUNIX0VOVFJZX1NBRkUoZW50cnksIGVudHJ5MiwgbGlua2VkX3Byb2dyYW1zLCBzdHJ1Y3QgZ2xzbF9zaGFkZXJfcHJvZ19saW5rLCBwc2hhZGVyX2VudHJ5KSB7CiAgICAgICAgICAgICAgICBkZWxldGVfZ2xzbF9wcm9ncmFtX2VudHJ5KFRoaXMtPmJhc2VTaGFkZXIuZGV2aWNlLCBlbnRyeSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBMSVNUX0ZPUl9FQUNIX0VOVFJZX1NBRkUoZW50cnksIGVudHJ5MiwgbGlua2VkX3Byb2dyYW1zLCBzdHJ1Y3QgZ2xzbF9zaGFkZXJfcHJvZ19saW5rLCB2c2hhZGVyX2VudHJ5KSB7CiAgICAgICAgICAgICAgICBkZWxldGVfZ2xzbF9wcm9ncmFtX2VudHJ5KFRoaXMtPmJhc2VTaGFkZXIuZGV2aWNlLCBlbnRyeSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgVFJBQ0UoIkRlbGV0aW5nIHNoYWRlciBvYmplY3QgJXVcbiIsIFRoaXMtPmJhc2VTaGFkZXIucHJnSWQpOwogICAgR0xfRVhUQ0FMTChnbERlbGV0ZU9iamVjdEFSQihUaGlzLT5iYXNlU2hhZGVyLnByZ0lkKSk7CiAgICBjaGVja0dMY2FsbCgiZ2xEZWxldGVPYmplY3RBUkIiKTsKICAgIFRoaXMtPmJhc2VTaGFkZXIucHJnSWQgPSAwOwogICAgVGhpcy0+YmFzZVNoYWRlci5pc19jb21waWxlZCA9IEZBTFNFOwp9CgpzdGF0aWMgdW5zaWduZWQgaW50IGdsc2xfcHJvZ3JhbV9rZXlfaGFzaCh2b2lkICprZXkpIHsKICAgIGdsc2xfcHJvZ3JhbV9rZXlfdCAqayA9IChnbHNsX3Byb2dyYW1fa2V5X3QgKilrZXk7CgogICAgdW5zaWduZWQgaW50IGhhc2ggPSBrLT52c2hhZGVyIHwgay0+cHNoYWRlciA8PCAxNjsKICAgIGhhc2ggKz0gfihoYXNoIDw8IDE1KTsKICAgIGhhc2ggXj0gIChoYXNoID4+IDEwKTsKICAgIGhhc2ggKz0gIChoYXNoIDw8IDMpOwogICAgaGFzaCBePSAgKGhhc2ggPj4gNik7CiAgICBoYXNoICs9IH4oaGFzaCA8PCAxMSk7CiAgICBoYXNoIF49ICAoaGFzaCA+PiAxNik7CgogICAgcmV0dXJuIGhhc2g7Cn0KCnN0YXRpYyBCT09MIGdsc2xfcHJvZ3JhbV9rZXlfY29tcGFyZSh2b2lkICprZXlhLCB2b2lkICprZXliKSB7CiAgICBnbHNsX3Byb2dyYW1fa2V5X3QgKmthID0gKGdsc2xfcHJvZ3JhbV9rZXlfdCAqKWtleWE7CiAgICBnbHNsX3Byb2dyYW1fa2V5X3QgKmtiID0gKGdsc2xfcHJvZ3JhbV9rZXlfdCAqKWtleWI7CgogICAgcmV0dXJuIGthLT52c2hhZGVyID09IGtiLT52c2hhZGVyICYmIGthLT5wc2hhZGVyID09IGtiLT5wc2hhZGVyOwp9CgpzdGF0aWMgSFJFU1VMVCBzaGFkZXJfZ2xzbF9hbGxvYyhJV2luZUQzRERldmljZSAqaWZhY2UpIHsKICAgIElXaW5lRDNERGV2aWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRERldmljZUltcGwgKilpZmFjZTsKICAgIFRoaXMtPnNoYWRlcl9wcml2ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihzdHJ1Y3Qgc2hhZGVyX2dsc2xfcHJpdikpOwogICAgVGhpcy0+Z2xzbF9wcm9ncmFtX2xvb2t1cCA9IGhhc2hfdGFibGVfY3JlYXRlKCZnbHNsX3Byb2dyYW1fa2V5X2hhc2gsICZnbHNsX3Byb2dyYW1fa2V5X2NvbXBhcmUpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyB2b2lkIHNoYWRlcl9nbHNsX2ZyZWUoSVdpbmVEM0REZXZpY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRERldmljZUltcGwgKlRoaXMgPSAoSVdpbmVEM0REZXZpY2VJbXBsICopaWZhY2U7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5zaGFkZXJfcHJpdik7CiAgICBUaGlzLT5zaGFkZXJfcHJpdiA9IE5VTEw7Cn0KCnN0YXRpYyBCT09MIHNoYWRlcl9nbHNsX2RpcnR5X2NvbnN0KElXaW5lRDNERGV2aWNlICppZmFjZSkgewogICAgLyogVE9ETzogR0xfRVhUX2JpbmRhYmxlX3VuaWZvcm0gY2FuIGJlIHVzZWQgdG8gc2hhcmUgY29uc3RhbnRzIGFjcm9zcyBzaGFkZXJzICovCiAgICByZXR1cm4gRkFMU0U7Cn0KCnN0YXRpYyB2b2lkIHNoYWRlcl9nbHNsX2dlbmVyYXRlX3BzaGFkZXIoSVdpbmVEM0RQaXhlbFNoYWRlciAqaWZhY2UsIFNIQURFUl9CVUZGRVIgKmJ1ZmZlcikgewogICAgSVdpbmVEM0RQaXhlbFNoYWRlckltcGwgKlRoaXMgPSAoSVdpbmVEM0RQaXhlbFNoYWRlckltcGwgKilpZmFjZTsKICAgIHNoYWRlcl9yZWdfbWFwcyogcmVnX21hcHMgPSAmVGhpcy0+YmFzZVNoYWRlci5yZWdfbWFwczsKICAgIENPTlNUIERXT1JEICpmdW5jdGlvbiA9IFRoaXMtPmJhc2VTaGFkZXIuZnVuY3Rpb247CiAgICBjb25zdCBjaGFyICpmcmFnY29sb3I7CiAgICBXaW5lRDNEX0dMX0luZm8gKmdsX2luZm8gPSAmKChJV2luZUQzRERldmljZUltcGwgKilUaGlzLT5iYXNlU2hhZGVyLmRldmljZSktPmFkYXB0ZXItPmdsX2luZm87CgogICAgLyogQ3JlYXRlIHRoZSBodyBHTFNMIHNoYWRlciBvYmplY3QgYW5kIGFzc2lnbiBpdCBhcyB0aGUgYmFzZVNoYWRlci5wcmdJZCAqLwogICAgR0xoYW5kbGVBUkIgc2hhZGVyX29iaiA9IEdMX0VYVENBTEwoZ2xDcmVhdGVTaGFkZXJPYmplY3RBUkIoR0xfRlJBR01FTlRfU0hBREVSX0FSQikpOwoKICAgIGlmIChHTF9TVVBQT1JUKEFSQl9EUkFXX0JVRkZFUlMpKSB7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiI2V4dGVuc2lvbiBHTF9BUkJfZHJhd19idWZmZXJzIDogZW5hYmxlXG4iKTsKICAgIH0KICAgIGlmIChHTF9TVVBQT1JUKEFSQl9URVhUVVJFX1JFQ1RBTkdMRSkpIHsKICAgICAgICAvKiBUaGUgc3BlYyBzYXlzIHRoYXQgaXQgZG9lc24ndCBoYXZlIHRvIGJlIGV4cGxpY2l0bHkgZW5hYmxlZCwgYnV0IHRoZSBudmlkaWEKICAgICAgICAgKiBkcml2ZXJzIHdyaXRlIGEgd2FybmluZyBpZiB3ZSBkb24ndCBkbyBzbwogICAgICAgICAqLwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIiNleHRlbnNpb24gR0xfQVJCX3RleHR1cmVfcmVjdGFuZ2xlIDogZW5hYmxlXG4iKTsKICAgIH0KCiAgICAvKiBCYXNlIERlY2xhcmF0aW9ucyAqLwogICAgc2hhZGVyX2dlbmVyYXRlX2dsc2xfZGVjbGFyYXRpb25zKCAoSVdpbmVEM0RCYXNlU2hhZGVyKikgVGhpcywgcmVnX21hcHMsIGJ1ZmZlciwgJkdMSU5GT19MT0NBVElPTik7CgogICAgLyogUGFjayAzLjAgaW5wdXRzICovCiAgICBpZiAoVGhpcy0+YmFzZVNoYWRlci5oZXhfdmVyc2lvbiA+PSBXSU5FRDNEUFNfVkVSU0lPTigzLDApKSB7CgogICAgICAgIGlmKCgoSVdpbmVEM0REZXZpY2VJbXBsICopIFRoaXMtPmJhc2VTaGFkZXIuZGV2aWNlKS0+c3RyaWRlZF9zdHJlYW1zLnUucy5wb3NpdGlvbl90cmFuc2Zvcm1lZCkgewogICAgICAgICAgICBUaGlzLT52ZXJ0ZXhwcm9jZXNzaW5nID0gcHJldHJhbnNmb3JtZWQ7CiAgICAgICAgICAgIHBzaGFkZXJfZ2xzbF9pbnB1dF9wYWNrKGJ1ZmZlciwgVGhpcy0+c2VtYW50aWNzX2luLCBpZmFjZSk7CiAgICAgICAgfSBlbHNlIGlmKCF1c2VfdnMoKElXaW5lRDNERGV2aWNlSW1wbCAqKSBUaGlzLT5iYXNlU2hhZGVyLmRldmljZSkpIHsKICAgICAgICAgICAgVGhpcy0+dmVydGV4cHJvY2Vzc2luZyA9IGZpeGVkZnVuY3Rpb247CiAgICAgICAgICAgIHBzaGFkZXJfZ2xzbF9pbnB1dF9wYWNrKGJ1ZmZlciwgVGhpcy0+c2VtYW50aWNzX2luLCBpZmFjZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgVGhpcy0+dmVydGV4cHJvY2Vzc2luZyA9IHZlcnRleHNoYWRlcjsKICAgICAgICB9CiAgICB9CgogICAgLyogQmFzZSBTaGFkZXIgQm9keSAqLwogICAgc2hhZGVyX2dlbmVyYXRlX21haW4oIChJV2luZUQzREJhc2VTaGFkZXIqKSBUaGlzLCBidWZmZXIsIHJlZ19tYXBzLCBmdW5jdGlvbik7CgogICAgLyogUGl4ZWwgc2hhZGVycyA8IDIuMCBwbGFjZSB0aGUgcmVzdWx0aW5nIGNvbG9yIGluIFIwIGltcGxpY2l0bHkgKi8KICAgIGlmIChUaGlzLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uIDwgV0lORUQzRFBTX1ZFUlNJT04oMiwwKSkgewogICAgICAgIC8qIFNvbWUgb2xkZXIgY2FyZHMgbGlrZSBHZWZvcmNlRlggb25lcyBkb24ndCBzdXBwb3J0IG11bHRpcGxlIGJ1ZmZlcnMsIHNvIGFsc28gbm90IGdsX0ZyYWdEYXRhICovCiAgICAgICAgaWYoR0xfU1VQUE9SVChBUkJfRFJBV19CVUZGRVJTKSkKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiZ2xfRnJhZ0RhdGFbMF0gPSBSMDtcbiIpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiZ2xfRnJhZ0NvbG9yID0gUjA7XG4iKTsKICAgIH0KCiAgICBpZihHTF9TVVBQT1JUKEFSQl9EUkFXX0JVRkZFUlMpKSB7CiAgICAgICAgZnJhZ2NvbG9yID0gImdsX0ZyYWdEYXRhWzBdIjsKICAgIH0gZWxzZSB7CiAgICAgICAgZnJhZ2NvbG9yID0gImdsX0ZyYWdDb2xvciI7CiAgICB9CiAgICBpZihUaGlzLT5zcmdiX2VuYWJsZWQpIHsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ0bXAwLnh5eiA9IHBvdyglcy54eXosIHZlYzMoJWYsICVmLCAlZikpICogdmVjMyglZiwgJWYsICVmKSAtIHZlYzMoJWYsICVmLCAlZik7XG4iLAogICAgICAgICAgICAgICAgICAgICAgICBmcmFnY29sb3IsIHNyZ2JfcG93LCBzcmdiX3Bvdywgc3JnYl9wb3csIHNyZ2JfbXVsX2hpZ2gsIHNyZ2JfbXVsX2hpZ2gsIHNyZ2JfbXVsX2hpZ2gsCiAgICAgICAgICAgICAgICAgICAgICAgIHNyZ2Jfc3ViX2hpZ2gsIHNyZ2Jfc3ViX2hpZ2gsIHNyZ2Jfc3ViX2hpZ2gpOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgInRtcDEueHl6ID0gJXMueHl6ICogc3JnYl9tdWxfbG93Lnh5ejtcbiIsIGZyYWdjb2xvcik7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiJXMueCA9ICVzLnggPCBzcmdiX2NvbXBhcmlzb24ueCA/IHRtcDEueCA6IHRtcDAueDtcbiIsIGZyYWdjb2xvciwgZnJhZ2NvbG9yKTsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICIlcy55ID0gJXMueSA8IHNyZ2JfY29tcGFyaXNvbi55ID8gdG1wMS55IDogdG1wMC55O1xuIiwgZnJhZ2NvbG9yLCBmcmFnY29sb3IpOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIiVzLnogPSAlcy56IDwgc3JnYl9jb21wYXJpc29uLnogPyB0bXAxLnogOiB0bXAwLno7XG4iLCBmcmFnY29sb3IsIGZyYWdjb2xvcik7CiAgICAgICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiJXMgPSBjbGFtcCglcywgMC4wLCAxLjApO1xuIiwgZnJhZ2NvbG9yLCBmcmFnY29sb3IpOwogICAgfQogICAgLyogUGl4ZWwgc2hhZGVyIDwgMy4wIGRvIG5vdCByZXBsYWNlIHRoZSBmb2cgc3RhZ2UuCiAgICAgKiBUaGlzIGltcGxlbWVudHMgbGluZWFyIGZvZyBjb21wdXRhdGlvbiBhbmQgYmxlbmRpbmcuCiAgICAgKiBUT0RPOiBub24gbGluZWFyIGZvZwogICAgICogTk9URTogZ2xfRm9nLnN0YXJ0IGFuZCBnbF9Gb2cuZW5kIGRvbid0IGhvbGQgZm9nIHN0YXJ0IHMgYW5kIGVuZCBlIGJ1dAogICAgICogLTEvKGUtcykgYW5kIGUvKGUtcykgcmVzcGVjdGl2ZWx5LgogICAgICovCiAgICBpZihUaGlzLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uIDwgV0lORUQzRFBTX1ZFUlNJT04oMywwKSkgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgImZsb2F0IEZvZyA9IGNsYW1wKGdsX0ZvZ0ZyYWdDb29yZCAqIGdsX0ZvZy5zdGFydCArIGdsX0ZvZy5lbmQsIDAuMCwgMS4wKTtcbiIpOwogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIiVzLnh5eiA9IG1peChnbF9Gb2cuY29sb3IueHl6LCAlcy54eXosIEZvZyk7XG4iLCBmcmFnY29sb3IsIGZyYWdjb2xvcik7CiAgICB9CgogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAifVxuIik7CgogICAgVFJBQ0UoIkNvbXBpbGluZyBzaGFkZXIgb2JqZWN0ICV1XG4iLCBzaGFkZXJfb2JqKTsKICAgIEdMX0VYVENBTEwoZ2xTaGFkZXJTb3VyY2VBUkIoc2hhZGVyX29iaiwgMSwgKGNvbnN0IGNoYXIqKikmYnVmZmVyLT5idWZmZXIsIE5VTEwpKTsKICAgIEdMX0VYVENBTEwoZ2xDb21waWxlU2hhZGVyQVJCKHNoYWRlcl9vYmopKTsKICAgIHByaW50X2dsc2xfaW5mb19sb2coJkdMSU5GT19MT0NBVElPTiwgc2hhZGVyX29iaik7CgogICAgLyogU3RvcmUgdGhlIHNoYWRlciBvYmplY3QgKi8KICAgIFRoaXMtPmJhc2VTaGFkZXIucHJnSWQgPSBzaGFkZXJfb2JqOwp9CgpzdGF0aWMgdm9pZCBzaGFkZXJfZ2xzbF9nZW5lcmF0ZV92c2hhZGVyKElXaW5lRDNEVmVydGV4U2hhZGVyICppZmFjZSwgU0hBREVSX0JVRkZFUiAqYnVmZmVyKSB7CiAgICBJV2luZUQzRFZlcnRleFNoYWRlckltcGwgKlRoaXMgPSAoSVdpbmVEM0RWZXJ0ZXhTaGFkZXJJbXBsICopaWZhY2U7CiAgICBzaGFkZXJfcmVnX21hcHMqIHJlZ19tYXBzID0gJlRoaXMtPmJhc2VTaGFkZXIucmVnX21hcHM7CiAgICBDT05TVCBEV09SRCAqZnVuY3Rpb24gPSBUaGlzLT5iYXNlU2hhZGVyLmZ1bmN0aW9uOwogICAgV2luZUQzRF9HTF9JbmZvICpnbF9pbmZvID0gJigoSVdpbmVEM0REZXZpY2VJbXBsICopVGhpcy0+YmFzZVNoYWRlci5kZXZpY2UpLT5hZGFwdGVyLT5nbF9pbmZvOwoKICAgIC8qIENyZWF0ZSB0aGUgaHcgR0xTTCBzaGFkZXIgcHJvZ3JhbSBhbmQgYXNzaWduIGl0IGFzIHRoZSBiYXNlU2hhZGVyLnByZ0lkICovCiAgICBHTGhhbmRsZUFSQiBzaGFkZXJfb2JqID0gR0xfRVhUQ0FMTChnbENyZWF0ZVNoYWRlck9iamVjdEFSQihHTF9WRVJURVhfU0hBREVSX0FSQikpOwoKICAgIC8qIEJhc2UgRGVjbGFyYXRpb25zICovCiAgICBzaGFkZXJfZ2VuZXJhdGVfZ2xzbF9kZWNsYXJhdGlvbnMoIChJV2luZUQzREJhc2VTaGFkZXIqKSBUaGlzLCByZWdfbWFwcywgYnVmZmVyLCAmR0xJTkZPX0xPQ0FUSU9OKTsKCiAgICAvKiBCYXNlIFNoYWRlciBCb2R5ICovCiAgICBzaGFkZXJfZ2VuZXJhdGVfbWFpbiggKElXaW5lRDNEQmFzZVNoYWRlciopIFRoaXMsIGJ1ZmZlciwgcmVnX21hcHMsIGZ1bmN0aW9uKTsKCiAgICAvKiBVbnBhY2sgMy4wIG91dHB1dHMgKi8KICAgIGlmIChUaGlzLT5iYXNlU2hhZGVyLmhleF92ZXJzaW9uID49IFdJTkVEM0RWU19WRVJTSU9OKDMsMCkpIHsKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJvcmRlcl9wc19pbnB1dChPVVQpO1xuIik7CiAgICB9IGVsc2UgewogICAgICAgIHNoYWRlcl9hZGRsaW5lKGJ1ZmZlciwgIm9yZGVyX3BzX2lucHV0KCk7XG4iKTsKICAgIH0KCiAgICAvKiBJZiB0aGlzIHNoYWRlciBkb2Vzbid0IHVzZSBmb2cgY29weSB0aGUgeiBjb29yZCB0byB0aGUgZm9nIGNvb3JkIHNvIHRoYXQgd2UgY2FuIHVzZSB0YWJsZSBmb2cgKi8KICAgIGlmICghcmVnX21hcHMtPmZvZykKICAgICAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJnbF9Gb2dGcmFnQ29vcmQgPSBnbF9Qb3NpdGlvbi56O1xuIik7CgogICAgLyogV3JpdGUgdGhlIGZpbmFsIHBvc2l0aW9uLgogICAgICoKICAgICAqIE9wZW5HTCBjb29yZGluYXRlcyBzcGVjaWZ5IHRoZSBjZW50ZXIgb2YgdGhlIHBpeGVsIHdoaWxlIGQzZCBjb29yZHMgc3BlY2lmeQogICAgICogdGhlIGNvcm5lci4gVGhlIG9mZnNldHMgYXJlIHN0b3JlZCBpbiB6IGFuZCB3IGluIHBvc0ZpeHVwLiBwb3NGaXh1cC55IGNvbnRhaW5zCiAgICAgKiAxLjAgb3IgLTEuMCB0byB0dXJuIHRoZSByZW5kZXJpbmcgdXBzaWRlIGRvd24gZm9yIG9mZnNjcmVlbiByZW5kZXJpbmcuIFBvc0ZpeHVwLngKICAgICAqIGNvbnRhaW5zIDEuMCB0byBhbGxvdyBhIG1hZC4KICAgICAqLwogICAgc2hhZGVyX2FkZGxpbmUoYnVmZmVyLCAiZ2xfUG9zaXRpb24ueSA9IGdsX1Bvc2l0aW9uLnkgKiBwb3NGaXh1cC55O1xuIik7CiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJnbF9Qb3NpdGlvbi54eSArPSBwb3NGaXh1cC56dyAqIGdsX1Bvc2l0aW9uLnd3O1xuIik7CgogICAgLyogWiBjb29yZCBbMDsxXS0+Wy0xOzFdIG1hcHBpbmcsIHNlZSBjb21tZW50IGluIHRyYW5zZm9ybV9wcm9qZWN0aW9uIGluIHN0YXRlLmMKICAgICAqCiAgICAgKiBCYXNpY2FsbHkgd2Ugd2FudCAoaW4gaG9tb2dlbmVvdXMgY29vcmRpbmF0ZXMpIHogPSB6ICogMiAtIDEuIEhvd2V2ZXIsIHNoYWRlcnMgYXJlIHJ1bgogICAgICogYmVmb3JlIHRoZSBob21vZ2VuZW91cyBkaXZpZGUsIHNvIHdlIGhhdmUgdG8gdGFrZSB0aGUgdyBpbnRvIGFjY291bnQ6IHogPSAoKHogLyB3KSAqIDIgLSAxKSAqIHcsCiAgICAgKiB3aGljaCBpcyB0aGUgc2FtZSBhcyB6ID0geiAvIDIgLSB3LgogICAgICovCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJnbF9Qb3NpdGlvbi56ID0gZ2xfUG9zaXRpb24ueiAqIDIuMCAtIGdsX1Bvc2l0aW9uLnc7XG4iKTsKCiAgICBzaGFkZXJfYWRkbGluZShidWZmZXIsICJ9XG4iKTsKCiAgICBUUkFDRSgiQ29tcGlsaW5nIHNoYWRlciBvYmplY3QgJXVcbiIsIHNoYWRlcl9vYmopOwogICAgR0xfRVhUQ0FMTChnbFNoYWRlclNvdXJjZUFSQihzaGFkZXJfb2JqLCAxLCAoY29uc3QgY2hhcioqKSZidWZmZXItPmJ1ZmZlciwgTlVMTCkpOwogICAgR0xfRVhUQ0FMTChnbENvbXBpbGVTaGFkZXJBUkIoc2hhZGVyX29iaikpOwogICAgcHJpbnRfZ2xzbF9pbmZvX2xvZygmR0xJTkZPX0xPQ0FUSU9OLCBzaGFkZXJfb2JqKTsKCiAgICAvKiBTdG9yZSB0aGUgc2hhZGVyIG9iamVjdCAqLwogICAgVGhpcy0+YmFzZVNoYWRlci5wcmdJZCA9IHNoYWRlcl9vYmo7Cn0KCnN0YXRpYyB2b2lkIHNoYWRlcl9nbHNsX2dldF9jYXBzKFdJTkVEM0RERVZUWVBFIGRldnR5cGUsIFdpbmVEM0RfR0xfSW5mbyAqZ2xfaW5mbywgc3RydWN0IHNoYWRlcl9jYXBzICpwQ2FwcykgewogICAgLyogV2UgZG9uJ3QgaGF2ZSBhIEdMU0wgZml4ZWQgZnVuY3Rpb24gcGlwZWxpbmUgeWV0LCBzbyBsZXQgdGhlIG5vbmUgYmFja2VuZCBzZXQgaXRzIGNhcHMsCiAgICAgKiB0aGVuIG92ZXJ3cml0ZSB0aGUgc2hhZGVyIHNwZWNpZmljIG9uZXMKICAgICAqLwogICAgbm9uZV9zaGFkZXJfYmFja2VuZC5zaGFkZXJfZ2V0X2NhcHMoZGV2dHlwZSwgZ2xfaW5mbywgcENhcHMpOwoKICAgIC8qIE52aWRpYSBHZWZvcmNlNi83IG9yIEF0aSBSNHh4L1I1eHggY2FyZHMgd2l0aCBHTFNMIHN1cHBvcnQsIHN1cHBvcnQgVlMgMy4wIGJ1dCBvbGRlciBOdmlkaWEvQXRpCiAgICAgKiBtb2RlbHMgd2l0aCBHTFNMIHN1cHBvcnQgb25seSBzdXBwb3J0IDIuMC4gSW4gY2FzZSBvZiBudmlkaWEgd2UgY2FuIGRldGVjdCBWUyAyLjAgc3VwcG9ydCB1c2luZwogICAgICogdnNfbnZfdmVyc2lvbiB3aGljaCBpcyBiYXNlZCBvbiBOVl92ZXJ0ZXhfcHJvZ3JhbS4KICAgICAqIEZvciBBdGkgY2FyZHMgdGhlcmUncyBubyB3YXkgdXNpbmcgZ2xzbCAoaXQgYWJzdHJhY3RzIHRoZSBsb3dsZXZlbCBpbmZvIGF3YXkpIGFuZCBhbHNvIG5vdAogICAgICogdXNpbmcgQVJCX3ZlcnRleF9wcm9ncmFtLiBJdCBpcyBzYWZlIHRvIGFzc3VtZSB0aGF0IHdoZW4gYSBjYXJkIHN1cHBvcnRzIHBpeGVsIHNoYWRlciAyLjAgaXQKICAgICAqIHN1cHBvcnRzIHZlcnRleCBzaGFkZXIgMi4wIHRvbyBhbmQgdGhlIHdheSBhcm91bmQuIFdlIGNhbiBkZXRlY3QgcHMyLjAgdXNpbmcgdGhlIG1heGltdW0gbnVtYmVyCiAgICAgKiBvZiBuYXRpdmUgaW5zdHJ1Y3Rpb25zLCBzbyB1c2UgdGhhdCBoZXJlLiBGb3IgbW9yZSBpbmZvIHNlZSB0aGUgcGl4ZWwgc2hhZGVyIHZlcnNpb25pbmcgY29kZSBiZWxvdy4KICAgICAqLwogICAgaWYoKEdMSU5GT19MT0NBVElPTi52c19udl92ZXJzaW9uID09IFZTX1ZFUlNJT05fMjApIHx8IChHTElORk9fTE9DQVRJT04ucHNfYXJiX21heF9pbnN0cnVjdGlvbnMgPD0gNTEyKSkKICAgICAgICBwQ2Fwcy0+VmVydGV4U2hhZGVyVmVyc2lvbiA9IFdJTkVEM0RWU19WRVJTSU9OKDIsMCk7CiAgICBlbHNlCiAgICAgICAgcENhcHMtPlZlcnRleFNoYWRlclZlcnNpb24gPSBXSU5FRDNEVlNfVkVSU0lPTigzLDApOwogICAgVFJBQ0VfKGQzZF9jYXBzKSgiSGFyZHdhcmUgdmVydGV4IHNoYWRlciB2ZXJzaW9uICVkLiVkIGVuYWJsZWQgKEdMU0wpXG4iLCAocENhcHMtPlZlcnRleFNoYWRlclZlcnNpb24gPj4gOCkgJiAweGZmLCBwQ2Fwcy0+VmVydGV4U2hhZGVyVmVyc2lvbiAmIDB4ZmYpOwogICAgcENhcHMtPk1heFZlcnRleFNoYWRlckNvbnN0ID0gR0xfTElNSVRTKHZzaGFkZXJfY29uc3RhbnRzRik7CgogICAgLyogT2xkZXIgRFg5LWNsYXNzIHZpZGVvY2FyZHMgKEdlZm9yY2VGWCAvIFJhZGVvbiA+OTUwMC9YKjAwKSBvbmx5IHN1cHBvcnQgcGl4ZWwgc2hhZGVyIDIuMC8yLjBhLzIuMGIuCiAgICAgKiBJbiBPcGVuR0wgdGhlIGV4dGVuc2lvbnMgcmVsYXRlZCB0byBHTFNMIGFic3RyYWN0IGxvd2xldmVsIEdMIGluZm8gYXdheSB3aGljaCBpcyBuZWVkZWQKICAgICAqIHRvIGRpc3Rpbmd1aXNoIGJldHdlZW4gMi4wIGFuZCAzLjAgKGFuZCAyLjBhLzIuMGIpLiBJbiBjYXNlIG9mIE52aWRpYSB3ZSB1c2UgdGhlaXIgZnJhZ21lbnQKICAgICAqIHByb2dyYW0gZXh0ZW5zaW9ucy4gT24gb3RoZXIgaGFyZHdhcmUgaW5jbHVkaW5nIEFUSSBHTF9BUkJfZnJhZ21lbnRfcHJvZ3JhbSBvZmZlcnMgdGhlIGluZm8KICAgICAqIGluIG1heCBuYXRpdmUgaW5zdHJ1Y3Rpb25zLiBJbnRlbCBhbmQgb3RoZXJzIGFsc28gb2ZmZXIgdGhlIGluZm8gaW4gdGhpcyBleHRlbnNpb24gYnV0IHRoZXkKICAgICAqIGRvbid0IHN1cHBvcnQgR0xTTCAoYXQgbGVhc3Qgb24gV2luZG93cykuCiAgICAgKgogICAgICogUFMyLjAgcmVxdWlyZXMgYXQgbGVhc3QgOTYgaW5zdHJ1Y3Rpb25zLCAyLjBhLzIuMGIgZ28gdXAgdG8gNTEyLiBBc3N1bWUgdGhhdCBpZiB0aGUgbnVtYmVyCiAgICAgKiBvZiBpbnN0cnVjdGlvbnMgaXMgNTEyIG9yIGxlc3Mgd2UgaGF2ZSB0byBkbyB3aXRoIHBzMi4wIGhhcmR3YXJlLgogICAgICogTk9URTogcHMzLjAgaGFyZHdhcmUgcmVxdWlyZXMgNTEyIG9yIG1vcmUgaW5zdHJ1Y3Rpb25zIGJ1dCBhdGkgYW5kIG52aWRpYSBvZmZlciAnZW5vdWdoJyAoMTAyNCB2cyA0MDk2KSBvbiB0aGVpciBtb3N0IGJhc2ljIHBzMy4wIGhhcmR3YXJlLgogICAgICovCiAgICBpZigoR0xJTkZPX0xPQ0FUSU9OLnBzX252X3ZlcnNpb24gPT0gUFNfVkVSU0lPTl8yMCkgfHwgKEdMSU5GT19MT0NBVElPTi5wc19hcmJfbWF4X2luc3RydWN0aW9ucyA8PSA1MTIpKQogICAgICAgIHBDYXBzLT5QaXhlbFNoYWRlclZlcnNpb24gPSBXSU5FRDNEUFNfVkVSU0lPTigyLDApOwogICAgZWxzZQogICAgICAgIHBDYXBzLT5QaXhlbFNoYWRlclZlcnNpb24gPSBXSU5FRDNEUFNfVkVSU0lPTigzLDApOwoKICAgIC8qIEZJWE1FOiBUaGUgZm9sbG93aW5nIGxpbmUgaXMgY2FyZCBkZXBlbmRlbnQuIC04LjAgdG8gOC4wIGlzIHRoZQogICAgICogRGlyZWN0M0QgbWluaW11bSByZXF1aXJlbWVudC4KICAgICAqCiAgICAgKiBCb3RoIEdMX0FSQl9mcmFnbWVudF9wcm9ncmFtIGFuZCBHTFNMIHJlcXVpcmUgYSAibWF4aW11bSByZXByZXNlbnRhYmxlIG1hZ25pdHVkZSIKICAgICAqIG9mIGNvbG9ycyB0byBiZSAyXjEwLCBhbmQgMl4zMiBmb3Igb3RoZXIgZmxvYXRzLiBTaG91bGQgd2UgdXNlIDEwMjQgaGVyZT8KICAgICAqCiAgICAgKiBUaGUgcHJvYmxlbSBpcyB0aGF0IHRoZSByZWZyYXN0IGNsYW1wcyB0ZW1wb3JhcnkgcmVzdWx0cyBpbiB0aGUgc2hhZGVyIHRvCiAgICAgKiBbLU1heFZhbHVlOytNYXhWYWx1ZV0uIElmIHRoZSBjYXJkJ3MgbWF4IHZhbHVlIGlzIGJpZ2dlciB0aGFuIHRoZSBvbmUgd2UgYWR2ZXJ0aXplIGhlcmUsCiAgICAgKiB0aGVuIGFwcGxpY2F0aW9ucyBtYXkgbWlzcyB0aGUgY2xhbXBpbmcgYmVoYXZpb3IuIE9uIHRoZSBvdGhlciBoYW5kLCBpZiBpdCBpcyBzbWFsbGVyLAogICAgICogdGhlIHNoYWRlciB3aWxsIGdlbmVyYXRlIGluY29ycmVjdCByZXN1bHRzIHRvby4gVW5mb3J0dW5hdGVseSwgR0wgZGVsaWJlcmF0ZWx5IGRvZXNuJ3QKICAgICAqIG9mZmVyIGEgd2F5IHRvIHF1ZXJ5IHRoaXMuCiAgICAgKi8KICAgIHBDYXBzLT5QaXhlbFNoYWRlcjF4TWF4VmFsdWUgPSA4LjA7CiAgICBUUkFDRV8oZDNkX2NhcHMpKCJIYXJkd2FyZSBwaXhlbCBzaGFkZXIgdmVyc2lvbiAlZC4lZCBlbmFibGVkIChHTFNMKVxuIiwgKHBDYXBzLT5QaXhlbFNoYWRlclZlcnNpb24gPj4gOCkgJiAweGZmLCBwQ2Fwcy0+UGl4ZWxTaGFkZXJWZXJzaW9uICYgMHhmZik7Cn0KCnN0YXRpYyB2b2lkIHNoYWRlcl9nbHNsX2xvYWRfaW5pdCh2b2lkKSB7fQoKc3RhdGljIHZvaWQgc2hhZGVyX2dsc2xfZnJhZ21lbnRfZW5hYmxlKElXaW5lRDNERGV2aWNlICppZmFjZSwgQk9PTCBlbmFibGUpIHsKICAgIG5vbmVfc2hhZGVyX2JhY2tlbmQuc2hhZGVyX2ZyYWdtZW50X2VuYWJsZShpZmFjZSwgZW5hYmxlKTsKfQoKY29uc3Qgc2hhZGVyX2JhY2tlbmRfdCBnbHNsX3NoYWRlcl9iYWNrZW5kID0gewogICAgJnNoYWRlcl9nbHNsX3NlbGVjdCwKICAgICZzaGFkZXJfZ2xzbF9zZWxlY3RfZGVwdGhfYmx0LAogICAgJnNoYWRlcl9nbHNsX2Rlc3Ryb3lfZGVwdGhfYmx0LAogICAgJnNoYWRlcl9nbHNsX2xvYWRfY29uc3RhbnRzLAogICAgJnNoYWRlcl9nbHNsX2NsZWFudXAsCiAgICAmc2hhZGVyX2dsc2xfY29sb3JfY29ycmVjdGlvbiwKICAgICZzaGFkZXJfZ2xzbF9kZXN0cm95LAogICAgJnNoYWRlcl9nbHNsX2FsbG9jLAogICAgJnNoYWRlcl9nbHNsX2ZyZWUsCiAgICAmc2hhZGVyX2dsc2xfZGlydHlfY29uc3QsCiAgICAmc2hhZGVyX2dsc2xfZ2VuZXJhdGVfcHNoYWRlciwKICAgICZzaGFkZXJfZ2xzbF9nZW5lcmF0ZV92c2hhZGVyLAogICAgJnNoYWRlcl9nbHNsX2dldF9jYXBzLAogICAgJnNoYWRlcl9nbHNsX2xvYWRfaW5pdCwKICAgICZzaGFkZXJfZ2xzbF9mcmFnbWVudF9lbmFibGUsCiAgICBGRlBTdGF0ZVRhYmxlCn07Cg==