LyogLSotIHRhYi13aWR0aDogODsgYy1iYXNpYy1vZmZzZXQ6IDQgLSotICovCi8qCiAqIEFuaW1hdGlvbiBjb250cm9sCiAqCiAqIENvcHlyaWdodCAxOTk4LCAxOTk5IEVyaWMgS29obAogKiAJCSAgIDE5OTkgRXJpYyBQb3VlY2gKICoKICogTk9URVMKICogICBJIHdpbGwgb25seSBpbXByb3ZlIHRoaXMgY29udHJvbCBvbmNlIGluIGEgd2hpbGUuCiAqICAgICBFcmljIDxla29obEBhYm8ucmhlaW4temVpdHVuZy5kZT4KICoKICogVE9ETzoKICogICAtIGNoZWNrIGZvciB0aGUgJ3JlYyAnIGxpc3QgaW4gc29tZSBBVkkgZmlsZXMKICogICAtIGltcGxlbWVudCBzb21lIG1pc3NpbmcgZmxhZ3MgKEFDU19UUkFOU1BBUkVOVCBhbmQgQUNTX0NFTlRFUikKICogICAtIHByb3RlY3Rpb24gYmV0d2VlbiBzZXJ2aWNlIHRocmVhZCBhbmQgd25kcHJvYyBtZXNzYWdlcyBoYW5kbGluZyAKICogICAgIGNvbmN1cnJlbnQgYWNjZXNzIHRvIGluZm9QdHIKICovCgoKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgImNvbW1jdHJsLmgiCiNpbmNsdWRlICJkcml2ZXIuaCIKI2luY2x1ZGUgImFuaW1hdGUuaCIKI2luY2x1ZGUgIm1tc3lzdGVtLmgiCiNpbmNsdWRlICJzZXJ2aWNlcy5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgoKREVGQVVMVF9ERUJVR19DSEFOTkVMKGFuaW1hdGUpOwoKI2RlZmluZSBBTklNQVRFX0dldEluZm9QdHIoaFduZCkgKChBTklNQVRFX0lORk8gKilHZXRXaW5kb3dMb25nQShoV25kLCAwKSkKCkhNT0RVTEUgaE1vZFdpbm1tOwoKc3RhdGljIHZvaWQgQU5JTUFURV9Ob3RpZnkoQU5JTUFURV9JTkZPKiBpbmZvUHRyLCBVSU5UIG5vdGlmKQp7CiAgICBTZW5kTWVzc2FnZUEoR2V0UGFyZW50KGluZm9QdHItPmhXbmQpLCBXTV9DT01NQU5ELCAKCQkgTUFLRVdQQVJBTShHZXREbGdDdHJsSUQoaW5mb1B0ci0+aFduZCksIG5vdGlmKSwgCgkJIChMUEFSQU0paW5mb1B0ci0+aFduZCk7Cn0KCnN0YXRpYyBCT09MIEFOSU1BVEVfTG9hZFJlc0EoQU5JTUFURV9JTkZPICppbmZvUHRyLCBISU5TVEFOQ0UgaEluc3QsIExQU1RSIGxwTmFtZSkKewogICAgSFJTUkMgCWhyc3JjOwogICAgTU1JT0lORk8JbW1pbmZvOwogICAgTFBWT0lECWxwQXZpOwogICAgCiAgICBocnNyYyA9IEZpbmRSZXNvdXJjZUEoaEluc3QsIGxwTmFtZSwgIkFWSSIpOwogICAgaWYgKCFocnNyYykKCXJldHVybiBGQUxTRTsKICAgIAogICAgaW5mb1B0ci0+aFJlcyA9IExvYWRSZXNvdXJjZShoSW5zdCwgaHJzcmMpOwogICAgaWYgKCFpbmZvUHRyLT5oUmVzKQogCXJldHVybiBGQUxTRTsKICAgIAogICAgbHBBdmkgPSBMb2NrUmVzb3VyY2UoaW5mb1B0ci0+aFJlcyk7CiAgICBpZiAoIWxwQXZpKQoJcmV0dXJuIEZBTFNFOwogICAgCiAgICBtZW1zZXQoJm1taW5mbywgMCwgc2l6ZW9mKG1taW5mbykpOwogICAgbW1pbmZvLmZjY0lPUHJvYyA9IEZPVVJDQ19NRU07CiAgICBtbWluZm8ucGNoQnVmZmVyID0gKExQU1RSKWxwQXZpOwogICAgbW1pbmZvLmNjaEJ1ZmZlciA9IFNpemVvZlJlc291cmNlKGhJbnN0LCBocnNyYyk7CiAgICBpbmZvUHRyLT5oTU1pbyA9IGluZm9QdHItPmZubW1pb09wZW5BKE5VTEwsICZtbWluZm8sIE1NSU9fUkVBRCk7CiAgICAKICAgIGlmICghaW5mb1B0ci0+aE1NaW8pIHsKCUdsb2JhbEZyZWUoKEhHTE9CQUwpbHBBdmkpOwoJcmV0dXJuIEZBTFNFOwogICAgfQogICAgCiAgICByZXR1cm4gVFJVRTsKfQoKCnN0YXRpYyBCT09MIEFOSU1BVEVfTG9hZEZpbGVBKEFOSU1BVEVfSU5GTyAqaW5mb1B0ciwgTFBTVFIgbHBOYW1lKQp7CiAgICBpbmZvUHRyLT5oTU1pbyA9IGluZm9QdHItPmZubW1pb09wZW5BKChMUFNUUilscE5hbWUsIE5VTEwsCgkJCSAgICAgICBNTUlPX0FMTE9DQlVGIHwgTU1JT19SRUFEIHwgTU1JT19ERU5ZV1JJVEUpOwogICAgCiAgICBpZiAoIWluZm9QdHItPmhNTWlvKQoJcmV0dXJuIEZBTFNFOwogICAgCiAgICByZXR1cm4gVFJVRTsKfQoKCnN0YXRpYyBMUkVTVUxUIEFOSU1BVEVfRG9TdG9wKEFOSU1BVEVfSU5GTyAqaW5mb1B0cikKewogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmluZm9QdHItPmNzKTsKCiAgICAvKiBzaG91bGQgc3RvcCBwbGF5aW5nICovCiAgICBpZiAoaW5mb1B0ci0+aFNlcnZpY2UpIHsKCVNFUlZJQ0VfRGVsZXRlKGluZm9QdHItPmhTZXJ2aWNlKTsKCWluZm9QdHItPmhTZXJ2aWNlID0gMDsKICAgIH0KICAgIGlmIChpbmZvUHRyLT51VGltZXIpIHsKCUtpbGxUaW1lcihpbmZvUHRyLT5oV25kLCBpbmZvUHRyLT51VGltZXIpOwoJaW5mb1B0ci0+dVRpbWVyID0gMDsKICAgIH0KCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmaW5mb1B0ci0+Y3MpOwoKICAgIEFOSU1BVEVfTm90aWZ5KGluZm9QdHIsIEFDTl9TVE9QKTsKCiAgICByZXR1cm4gVFJVRTsKfQoKCnN0YXRpYyB2b2lkIEFOSU1BVEVfRnJlZShBTklNQVRFX0lORk8gKmluZm9QdHIpCnsKICAgIGlmIChpbmZvUHRyLT5oTU1pbykgewoJQU5JTUFURV9Eb1N0b3AoaW5mb1B0cik7CglpbmZvUHRyLT5mbm1taW9DbG9zZShpbmZvUHRyLT5oTU1pbywgMCk7CglpZiAoaW5mb1B0ci0+aFJlcykgewogCSAgICBGcmVlUmVzb3VyY2UoaW5mb1B0ci0+aFJlcyk7CgkgICAgaW5mb1B0ci0+aFJlcyA9IDA7Cgl9CglpZiAoaW5mb1B0ci0+bHBJbmRleCkgewoJICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGluZm9QdHItPmxwSW5kZXgpOwoJICAgIGluZm9QdHItPmxwSW5kZXggPSBOVUxMOwoJfQoJaWYgKGluZm9QdHItPmhpYykgewoJICAgIChpbmZvUHRyLT5mbklDQ2xvc2UpKGluZm9QdHItPmhpYyk7CgkgICAgaW5mb1B0ci0+aGljID0gMDsKCX0KCWlmIChpbmZvUHRyLT5pbmJpaCkgewoJICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGluZm9QdHItPmluYmloKTsKCSAgICBpbmZvUHRyLT5pbmJpaCA9IE5VTEw7Cgl9CglpZiAoaW5mb1B0ci0+b3V0YmloKSB7CgkgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgaW5mb1B0ci0+b3V0YmloKTsKCSAgICBpbmZvUHRyLT5vdXRiaWggPSBOVUxMOwoJfQoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgaW5mb1B0ci0+aW5kYXRhKTsKCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGluZm9QdHItPm91dGRhdGEpOwoJaW5mb1B0ci0+aW5kYXRhID0gaW5mb1B0ci0+b3V0ZGF0YSA9IE5VTEw7CglpbmZvUHRyLT5oV25kID0gMDsKCWluZm9QdHItPmhNTWlvID0gMDsKCW1lbXNldCgmaW5mb1B0ci0+bWFoLCAwLCBzaXplb2YoaW5mb1B0ci0+bWFoKSk7CgltZW1zZXQoJmluZm9QdHItPmFzaCwgMCwgc2l6ZW9mKGluZm9QdHItPmFzaCkpOwoJaW5mb1B0ci0+bkZyb21GcmFtZSA9IGluZm9QdHItPm5Ub0ZyYW1lID0gaW5mb1B0ci0+bkxvb3AgPSBpbmZvUHRyLT5jdXJyRnJhbWUgPSAwOwogICAgfQp9CgoKc3RhdGljIExSRVNVTFQgQU5JTUFURV9QYWludEZyYW1lKEFOSU1BVEVfSU5GTyogaW5mb1B0ciwgSERDIGhEQykKewogICAgaWYgKCFoREMgfHwgIWluZm9QdHItPmluYmloKQoJcmV0dXJuIFRSVUU7CiAgICBpZiAoaW5mb1B0ci0+aGljKQoJU3RyZXRjaERJQml0cyhoREMsIDAsIDAsIGluZm9QdHItPm91dGJpaC0+YmlXaWR0aCwgaW5mb1B0ci0+b3V0YmloLT5iaUhlaWdodCwgCgkJICAgICAgMCwgMCwgaW5mb1B0ci0+b3V0YmloLT5iaVdpZHRoLCBpbmZvUHRyLT5vdXRiaWgtPmJpSGVpZ2h0LCAKCQkgICAgICBpbmZvUHRyLT5vdXRkYXRhLCAoTFBCSVRNQVBJTkZPKWluZm9QdHItPm91dGJpaCwgRElCX1JHQl9DT0xPUlMsIAoJCSAgICAgIFNSQ0NPUFkpOwogICAgZWxzZQoJU3RyZXRjaERJQml0cyhoREMsIDAsIDAsIGluZm9QdHItPmluYmloLT5iaVdpZHRoLCBpbmZvUHRyLT5pbmJpaC0+YmlIZWlnaHQsIAoJCSAgICAgIDAsIDAsIGluZm9QdHItPmluYmloLT5iaVdpZHRoLCBpbmZvUHRyLT5pbmJpaC0+YmlIZWlnaHQsIAoJCSAgICAgIGluZm9QdHItPmluZGF0YSwgKExQQklUTUFQSU5GTylpbmZvUHRyLT5pbmJpaCwgRElCX1JHQl9DT0xPUlMsIAoJCSAgICAgIFNSQ0NPUFkpOwoKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgTFJFU1VMVCBBTklNQVRFX0RyYXdGcmFtZShBTklNQVRFX0lORk8qIGluZm9QdHIpCnsKICAgIEhEQwkJaERDOwoKICAgIFRSQUNFKCJEcmF3aW5nIGZyYW1lICVkIChsb29wICVkKVxuIiwgaW5mb1B0ci0+Y3VyckZyYW1lLCBpbmZvUHRyLT5uTG9vcCk7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmluZm9QdHItPmNzKTsKCiAgICBpbmZvUHRyLT5mbm1taW9TZWVrKGluZm9QdHItPmhNTWlvLCBpbmZvUHRyLT5scEluZGV4W2luZm9QdHItPmN1cnJGcmFtZV0sIFNFRUtfU0VUKTsKICAgIGluZm9QdHItPmZubW1pb1JlYWQoaW5mb1B0ci0+aE1NaW8sIGluZm9QdHItPmluZGF0YSwgaW5mb1B0ci0+YXNoLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSk7CiAgICAKICAgIGlmIChpbmZvUHRyLT5oaWMgJiYKCShpbmZvUHRyLT5mbklDRGVjb21wcmVzcykoaW5mb1B0ci0+aGljLCAwLCBpbmZvUHRyLT5pbmJpaCwgaW5mb1B0ci0+aW5kYXRhLCAKCQkJCSAgaW5mb1B0ci0+b3V0YmloLCBpbmZvUHRyLT5vdXRkYXRhKSAhPSBJQ0VSUl9PSykgewoJTGVhdmVDcml0aWNhbFNlY3Rpb24oJmluZm9QdHItPmNzKTsKCVdBUk4oIkRlY29tcHJlc3Npb24gZXJyb3JcbiIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmICgoaERDID0gR2V0REMoaW5mb1B0ci0+aFduZCkpICE9IDApIHsKCUFOSU1BVEVfUGFpbnRGcmFtZShpbmZvUHRyLCBoREMpOwoJUmVsZWFzZURDKGluZm9QdHItPmhXbmQsIGhEQyk7CiAgICB9CgogICAgaWYgKGluZm9QdHItPmN1cnJGcmFtZSsrID49IGluZm9QdHItPm5Ub0ZyYW1lKSB7CglpbmZvUHRyLT5jdXJyRnJhbWUgPSBpbmZvUHRyLT5uRnJvbUZyYW1lOwoJaWYgKGluZm9QdHItPm5Mb29wICE9IC0xKSB7CgkgICAgaWYgKC0taW5mb1B0ci0+bkxvb3AgPT0gMCkgewoJCUFOSU1BVEVfRG9TdG9wKGluZm9QdHIpOwoJICAgIH0KCX0KICAgIH0KICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZpbmZvUHRyLT5jcyk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyB2b2lkIENBTExCQUNLIEFOSU1BVEVfU2VydmljZUNhbGxiYWNrKFVMT05HX1BUUiBwdHJfKQp7CiAgICBBTklNQVRFX0lORk8qCWluZm9QdHIgPSAoQU5JTUFURV9JTkZPKilwdHJfOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZpbmZvUHRyLT5jcyk7CiAgICBBTklNQVRFX0RyYXdGcmFtZShpbmZvUHRyKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZpbmZvUHRyLT5jcyk7Cn0KCnN0YXRpYyBMUkVTVUxUIEFOSU1BVEVfUGxheShIV05EIGhXbmQsIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0pCnsKICAgIEFOSU1BVEVfSU5GTyAqaW5mb1B0ciA9IEFOSU1BVEVfR2V0SW5mb1B0cihoV25kKTsKCiAgICAvKiBub3RoaW5nIG9wZW5lZCAqLwogICAgaWYgKCFpbmZvUHRyLT5oTU1pbykKCXJldHVybiBGQUxTRTsKCiAgICBpZiAoaW5mb1B0ci0+aFNlcnZpY2UgfHwgaW5mb1B0ci0+dVRpbWVyKSB7CglGSVhNRSgiQWxyZWFkeSBwbGF5aW5nID8gd2hhdCBzaG91bGQgSSBkbyA/P1xuIik7CglBTklNQVRFX0RvU3RvcChpbmZvUHRyKTsKICAgIH0KCiAgICBpbmZvUHRyLT5uRnJvbUZyYW1lID0gKElOVClMT1dPUkQobFBhcmFtKTsKICAgIGluZm9QdHItPm5Ub0ZyYW1lICAgPSAoSU5UKUhJV09SRChsUGFyYW0pOwogICAgaW5mb1B0ci0+bkxvb3AgICAgICA9IChJTlQpd1BhcmFtOwoKICAgIGlmIChpbmZvUHRyLT5uVG9GcmFtZSA9PSAweEZGRkYpCglpbmZvUHRyLT5uVG9GcmFtZSA9IGluZm9QdHItPm1haC5kd1RvdGFsRnJhbWVzIC0gMTsKCiAgICBUUkFDRSgiKHJlcGVhdD0lZCBmcm9tPSVkIHRvPSVkKTtcbiIsIAoJICBpbmZvUHRyLT5uTG9vcCwgaW5mb1B0ci0+bkZyb21GcmFtZSwgaW5mb1B0ci0+blRvRnJhbWUpOwoKICAgIGlmIChpbmZvUHRyLT5uRnJvbUZyYW1lID49IGluZm9QdHItPm5Ub0ZyYW1lIHx8CglpbmZvUHRyLT5uVG9GcmFtZSA+PSBpbmZvUHRyLT5tYWguZHdUb3RhbEZyYW1lcykKCXJldHVybiBGQUxTRTsKCiAgICBpbmZvUHRyLT5jdXJyRnJhbWUgPSBpbmZvUHRyLT5uRnJvbUZyYW1lOwoKICAgIGlmIChHZXRXaW5kb3dMb25nQShoV25kLCBHV0xfU1RZTEUpICYgQUNTX1RJTUVSKSB7CglUUkFDRSgiVXNpbmcgYSB0aW1lclxuIik7CgkvKiBjcmVhdGUgYSB0aW1lciB0byBkaXNwbGF5IEFWSSAqLwoJaW5mb1B0ci0+dVRpbWVyID0gU2V0VGltZXIoaFduZCwgMSwgaW5mb1B0ci0+bWFoLmR3TWljcm9TZWNQZXJGcmFtZSAvIDEwMDAsIE5VTEwpOwogICAgfSBlbHNlIHsKCVRSQUNFKCJVc2luZyB0aGUgc2VydmljZSB0aHJlYWRcbiIpOwoJLyogdGltZSBpcyBpbiC1cyAqLwoJaW5mb1B0ci0+aFNlcnZpY2UgPSBTRVJWSUNFX0FkZFRpbWVyKGluZm9QdHItPm1haC5kd01pY3JvU2VjUGVyRnJhbWUgLyAxMDAwLCAKCQkJCQkgICAgIEFOSU1BVEVfU2VydmljZUNhbGxiYWNrLCAoRFdPUkQpaW5mb1B0cik7CiAgICB9CgkKICAgIEFOSU1BVEVfTm90aWZ5KGluZm9QdHIsIEFDTl9TVEFSVCk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCgpzdGF0aWMgQk9PTCBBTklNQVRFX0dldEF2aUluZm8oQU5JTUFURV9JTkZPICppbmZvUHRyKQp7CiAgICBNTUNLSU5GTwkJY2tNYWluUklGRjsKICAgIE1NQ0tJTkZPCQltbWNrSGVhZDsKICAgIE1NQ0tJTkZPCQltbWNrTGlzdDsKICAgIE1NQ0tJTkZPCQltbWNrSW5mbzsKICAgIERXT1JECQludW1GcmFtZTsKICAgIERXT1JECQlpbnNpemU7CgogICAgaWYgKGluZm9QdHItPmZubW1pb0Rlc2NlbmQoaW5mb1B0ci0+aE1NaW8sICZja01haW5SSUZGLCBOVUxMLCAwKSAhPSAwKSB7CglXQVJOKCJDYW4ndCBmaW5kICdSSUZGJyBjaHVua1xuIik7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKChja01haW5SSUZGLmNraWQgIT0gRk9VUkNDX1JJRkYpIHx8CgkoY2tNYWluUklGRi5mY2NUeXBlICE9IG1taW9GT1VSQ0MoJ0EnLCAnVicsICdJJywgJyAnKSkpIHsKCVdBUk4oIkNhbid0IGZpbmQgJ0FWSSAnIGNodW5rXG4iKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICBtbWNrSGVhZC5mY2NUeXBlID0gbW1pb0ZPVVJDQygnaCcsICdkJywgJ3InLCAnbCcpOwogICAgaWYgKGluZm9QdHItPmZubW1pb0Rlc2NlbmQoaW5mb1B0ci0+aE1NaW8sICZtbWNrSGVhZCwgJmNrTWFpblJJRkYsIE1NSU9fRklORExJU1QpICE9IDApIHsKCVdBUk4oIkNhbid0IGZpbmQgJ2hkcmwnIGxpc3RcbiIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIG1tY2tJbmZvLmNraWQgPSBtbWlvRk9VUkNDKCdhJywgJ3YnLCAnaScsICdoJyk7CiAgICBpZiAoaW5mb1B0ci0+Zm5tbWlvRGVzY2VuZChpbmZvUHRyLT5oTU1pbywgJm1tY2tJbmZvLCAmbW1ja0hlYWQsIE1NSU9fRklORENIVU5LKSAhPSAwKSB7CglXQVJOKCJDYW4ndCBmaW5kICdhdmloJyBjaHVua1xuIik7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaW5mb1B0ci0+Zm5tbWlvUmVhZChpbmZvUHRyLT5oTU1pbywgKExQU1RSKSZpbmZvUHRyLT5tYWgsIHNpemVvZihpbmZvUHRyLT5tYWgpKTsKICAgIFRSQUNFKCJtYWguZHdNaWNyb1NlY1BlckZyYW1lPSVsZFxuIiwgCWluZm9QdHItPm1haC5kd01pY3JvU2VjUGVyRnJhbWUpOwogICAgVFJBQ0UoIm1haC5kd01heEJ5dGVzUGVyU2VjPSVsZFxuIiwgCWluZm9QdHItPm1haC5kd01heEJ5dGVzUGVyU2VjKTsKICAgIFRSQUNFKCJtYWguZHdQYWRkaW5nR3JhbnVsYXJpdHk9JWxkXG4iLCAJaW5mb1B0ci0+bWFoLmR3UGFkZGluZ0dyYW51bGFyaXR5KTsKICAgIFRSQUNFKCJtYWguZHdGbGFncz0lbGRcbiIsIAkJCWluZm9QdHItPm1haC5kd0ZsYWdzKTsKICAgIFRSQUNFKCJtYWguZHdUb3RhbEZyYW1lcz0lbGRcbiIsIAkJaW5mb1B0ci0+bWFoLmR3VG90YWxGcmFtZXMpOwogICAgVFJBQ0UoIm1haC5kd0luaXRpYWxGcmFtZXM9JWxkXG4iLCAJCWluZm9QdHItPm1haC5kd0luaXRpYWxGcmFtZXMpOwogICAgVFJBQ0UoIm1haC5kd1N0cmVhbXM9JWxkXG4iLCAJCWluZm9QdHItPm1haC5kd1N0cmVhbXMpOwogICAgVFJBQ0UoIm1haC5kd1N1Z2dlc3RlZEJ1ZmZlclNpemU9JWxkXG4iLAlpbmZvUHRyLT5tYWguZHdTdWdnZXN0ZWRCdWZmZXJTaXplKTsKICAgIFRSQUNFKCJtYWguZHdXaWR0aD0lbGRcbiIsIAkJCWluZm9QdHItPm1haC5kd1dpZHRoKTsKICAgIFRSQUNFKCJtYWguZHdIZWlnaHQ9JWxkXG4iLCAJCWluZm9QdHItPm1haC5kd0hlaWdodCk7CiAgICBpbmZvUHRyLT5mbm1taW9Bc2NlbmQoaW5mb1B0ci0+aE1NaW8sICZtbWNrSW5mbywgMCk7CgogICAgbW1ja0xpc3QuZmNjVHlwZSA9IG1taW9GT1VSQ0MoJ3MnLCAndCcsICdyJywgJ2wnKTsKICAgIGlmIChpbmZvUHRyLT5mbm1taW9EZXNjZW5kKGluZm9QdHItPmhNTWlvLCAmbW1ja0xpc3QsICZtbWNrSGVhZCwgTU1JT19GSU5ETElTVCkgIT0gMCkgewoJV0FSTigiQ2FuJ3QgZmluZCAnc3RybCcgbGlzdFxuIik7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgbW1ja0luZm8uY2tpZCA9IG1taW9GT1VSQ0MoJ3MnLCAndCcsICdyJywgJ2gnKTsKICAgIGlmIChpbmZvUHRyLT5mbm1taW9EZXNjZW5kKGluZm9QdHItPmhNTWlvLCAmbW1ja0luZm8sICZtbWNrTGlzdCwgTU1JT19GSU5EQ0hVTkspICE9IDApIHsKCVdBUk4oIkNhbid0IGZpbmQgJ3N0cmgnIGNodW5rXG4iKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpbmZvUHRyLT5mbm1taW9SZWFkKGluZm9QdHItPmhNTWlvLCAoTFBTVFIpJmluZm9QdHItPmFzaCwgc2l6ZW9mKGluZm9QdHItPmFzaCkpOwogICAgVFJBQ0UoImFzaC5mY2NUeXBlPSclYyVjJWMlYydcbiIsIAkJTE9CWVRFKExPV09SRChpbmZvUHRyLT5hc2guZmNjVHlwZSkpLCAKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBISUJZVEUoTE9XT1JEKGluZm9QdHItPmFzaC5mY2NUeXBlKSksIAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPQllURShISVdPUkQoaW5mb1B0ci0+YXNoLmZjY1R5cGUpKSwgCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSElCWVRFKEhJV09SRChpbmZvUHRyLT5hc2guZmNjVHlwZSkpKTsKICAgIFRSQUNFKCJhc2guZmNjSGFuZGxlcj0nJWMlYyVjJWMnXG4iLAlMT0JZVEUoTE9XT1JEKGluZm9QdHItPmFzaC5mY2NIYW5kbGVyKSksIAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhJQllURShMT1dPUkQoaW5mb1B0ci0+YXNoLmZjY0hhbmRsZXIpKSwgCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9CWVRFKEhJV09SRChpbmZvUHRyLT5hc2guZmNjSGFuZGxlcikpLCAKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBISUJZVEUoSElXT1JEKGluZm9QdHItPmFzaC5mY2NIYW5kbGVyKSkpOwogICAgVFJBQ0UoImFzaC5kd0ZsYWdzPSVsZFxuIiwgCQkJaW5mb1B0ci0+YXNoLmR3RmxhZ3MpOwogICAgVFJBQ0UoImFzaC53UHJpb3JpdHk9JWRcbiIsIAkJaW5mb1B0ci0+YXNoLndQcmlvcml0eSk7CiAgICBUUkFDRSgiYXNoLndMYW5ndWFnZT0lZFxuIiwgCQlpbmZvUHRyLT5hc2gud0xhbmd1YWdlKTsKICAgIFRSQUNFKCJhc2guZHdJbml0aWFsRnJhbWVzPSVsZFxuIiwgCQlpbmZvUHRyLT5hc2guZHdJbml0aWFsRnJhbWVzKTsKICAgIFRSQUNFKCJhc2guZHdTY2FsZT0lbGRcbiIsIAkJCWluZm9QdHItPmFzaC5kd1NjYWxlKTsKICAgIFRSQUNFKCJhc2guZHdSYXRlPSVsZFxuIiwgCQkJaW5mb1B0ci0+YXNoLmR3UmF0ZSk7CiAgICBUUkFDRSgiYXNoLmR3U3RhcnQ9JWxkXG4iLCAJCQlpbmZvUHRyLT5hc2guZHdTdGFydCk7CiAgICBUUkFDRSgiYXNoLmR3TGVuZ3RoPSVsZFxuIiwgCQlpbmZvUHRyLT5hc2guZHdMZW5ndGgpOwogICAgVFJBQ0UoImFzaC5kd1N1Z2dlc3RlZEJ1ZmZlclNpemU9JWxkXG4iLCAJaW5mb1B0ci0+YXNoLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSk7CiAgICBUUkFDRSgiYXNoLmR3UXVhbGl0eT0lbGRcbiIsIAkJaW5mb1B0ci0+YXNoLmR3UXVhbGl0eSk7CiAgICBUUkFDRSgiYXNoLmR3U2FtcGxlU2l6ZT0lbGRcbiIsIAkJaW5mb1B0ci0+YXNoLmR3U2FtcGxlU2l6ZSk7CiAgICBUUkFDRSgiYXNoLnJjRnJhbWU9KCVkLCVkLCVkLCVkKVxuIiwgCWluZm9QdHItPmFzaC5yY0ZyYW1lLnRvcCwgaW5mb1B0ci0+YXNoLnJjRnJhbWUubGVmdCwgCgkgIGluZm9QdHItPmFzaC5yY0ZyYW1lLmJvdHRvbSwgaW5mb1B0ci0+YXNoLnJjRnJhbWUucmlnaHQpOwogICAgaW5mb1B0ci0+Zm5tbWlvQXNjZW5kKGluZm9QdHItPmhNTWlvLCAmbW1ja0luZm8sIDApOwoKICAgIG1tY2tJbmZvLmNraWQgPSBtbWlvRk9VUkNDKCdzJywgJ3QnLCAncicsICdmJyk7CiAgICBpZiAoaW5mb1B0ci0+Zm5tbWlvRGVzY2VuZChpbmZvUHRyLT5oTU1pbywgJm1tY2tJbmZvLCAmbW1ja0xpc3QsIE1NSU9fRklORENIVU5LKSAhPSAwKSB7CglXQVJOKCJDYW4ndCBmaW5kICdzdHJoJyBjaHVua1xuIik7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaW5mb1B0ci0+aW5iaWggPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbW1ja0luZm8uY2tzaXplKTsKICAgIGlmICghaW5mb1B0ci0+aW5iaWgpIHsKCVdBUk4oIkNhbid0IGFsbG9jIGlucHV0IEJJSFxuIik7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaW5mb1B0ci0+Zm5tbWlvUmVhZChpbmZvUHRyLT5oTU1pbywgKExQU1RSKWluZm9QdHItPmluYmloLCBtbWNrSW5mby5ja3NpemUpOwogICAgVFJBQ0UoImJpaC5iaVNpemU9JWxkXG4iLCAJCWluZm9QdHItPmluYmloLT5iaVNpemUpOwogICAgVFJBQ0UoImJpaC5iaVdpZHRoPSVsZFxuIiwgCQlpbmZvUHRyLT5pbmJpaC0+YmlXaWR0aCk7CiAgICBUUkFDRSgiYmloLmJpSGVpZ2h0PSVsZFxuIiwgCWluZm9QdHItPmluYmloLT5iaUhlaWdodCk7CiAgICBUUkFDRSgiYmloLmJpUGxhbmVzPSVkXG4iLCAJCWluZm9QdHItPmluYmloLT5iaVBsYW5lcyk7CiAgICBUUkFDRSgiYmloLmJpQml0Q291bnQ9JWRcbiIsIAlpbmZvUHRyLT5pbmJpaC0+YmlCaXRDb3VudCk7CiAgICBUUkFDRSgiYmloLmJpQ29tcHJlc3Npb249JWxkXG4iLCAJaW5mb1B0ci0+aW5iaWgtPmJpQ29tcHJlc3Npb24pOwogICAgVFJBQ0UoImJpaC5iaVNpemVJbWFnZT0lbGRcbiIsIAlpbmZvUHRyLT5pbmJpaC0+YmlTaXplSW1hZ2UpOwogICAgVFJBQ0UoImJpaC5iaVhQZWxzUGVyTWV0ZXI9JWxkXG4iLCAJaW5mb1B0ci0+aW5iaWgtPmJpWFBlbHNQZXJNZXRlcik7CiAgICBUUkFDRSgiYmloLmJpWVBlbHNQZXJNZXRlcj0lbGRcbiIsIAlpbmZvUHRyLT5pbmJpaC0+YmlZUGVsc1Blck1ldGVyKTsKICAgIFRSQUNFKCJiaWguYmlDbHJVc2VkPSVsZFxuIiwgCWluZm9QdHItPmluYmloLT5iaUNsclVzZWQpOwogICAgVFJBQ0UoImJpaC5iaUNsckltcG9ydGFudD0lbGRcbiIsIAlpbmZvUHRyLT5pbmJpaC0+YmlDbHJJbXBvcnRhbnQpOwogICAgaW5mb1B0ci0+Zm5tbWlvQXNjZW5kKGluZm9QdHItPmhNTWlvLCAmbW1ja0luZm8sIDApOwoKICAgIGluZm9QdHItPmZubW1pb0FzY2VuZChpbmZvUHRyLT5oTU1pbywgJm1tY2tMaXN0LCAwKTsKICAgIAojaWYgMAogICAgLyogYW4gQVZJIGhhcyAwIG9yIDEgdmlkZW8gc3RyZWFtLCBhbmQgdG8gYmUgYW5pbWF0ZWQgc2hvdWxkIG5vdCBjb250YWluCiAgICAgKiBhbiBhdWRpbyBzdHJlYW0sIHNvIG9ubHkgb25lIHN0cmwgaXMgYWxsb3dlZCAKICAgICAqLwogICAgbW1ja0xpc3QuZmNjVHlwZSA9IG1taW9GT1VSQ0MoJ3MnLCAndCcsICdyJywgJ2wnKTsKICAgIGlmIChpbmZvUHRyLT5mbm1taW9EZXNjZW5kKGluZm9QdHItPmhNTWlvLCAmbW1ja0xpc3QsICZtbWNrSGVhZCwgTU1JT19GSU5ETElTVCkgPT0gMCkgewoJV0FSTigiVGhlcmUgc2hvdWxkIGJlIGEgc2luZ2xlICdzdHJsJyBsaXN0XG4iKTsKCXJldHVybiBGQUxTRTsKICAgIH0KI2VuZGlmCgogICAgaW5mb1B0ci0+Zm5tbWlvQXNjZW5kKGluZm9QdHItPmhNTWlvLCAmbW1ja0hlYWQsIDApOwoKICAgIC8qIG5vIG5lZWQgdG8gcmVhZCBvcHRpb25hbCBKVU5LIGNodW5rICovCgogICAgbW1ja0xpc3QuZmNjVHlwZSA9IG1taW9GT1VSQ0MoJ20nLCAnbycsICd2JywgJ2knKTsKICAgIGlmIChpbmZvUHRyLT5mbm1taW9EZXNjZW5kKGluZm9QdHItPmhNTWlvLCAmbW1ja0xpc3QsICZja01haW5SSUZGLCBNTUlPX0ZJTkRMSVNUKSAhPSAwKSB7CglXQVJOKCJDYW4ndCBmaW5kICdtb3ZpJyBsaXN0XG4iKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICAvKiBGSVhNRTogc2hvdWxkIGhhbmRsZSB0aGUgJ3JlYyAnIExJU1Qgd2hlbiBwcmVzZW50ICovCgogICAgaW5mb1B0ci0+bHBJbmRleCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCAKCQkJCSBpbmZvUHRyLT5tYWguZHdUb3RhbEZyYW1lcyAqIHNpemVvZihEV09SRCkpOwogICAgaWYgKCFpbmZvUHRyLT5scEluZGV4KSB7CglXQVJOKCJDYW4ndCBhbGxvYyBpbmRleCBhcnJheVxuIik7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgbnVtRnJhbWUgPSBpbnNpemUgPSAwOwogICAgd2hpbGUgKGluZm9QdHItPmZubW1pb0Rlc2NlbmQoaW5mb1B0ci0+aE1NaW8sICZtbWNrSW5mbywgJm1tY2tMaXN0LCAwKSA9PSAwICYmIAoJICAgbnVtRnJhbWUgPCBpbmZvUHRyLT5tYWguZHdUb3RhbEZyYW1lcykgewoJaW5mb1B0ci0+bHBJbmRleFtudW1GcmFtZV0gPSBtbWNrSW5mby5kd0RhdGFPZmZzZXQ7CglpZiAoaW5zaXplIDwgbW1ja0luZm8uY2tzaXplKQoJICAgIGluc2l6ZSA9IG1tY2tJbmZvLmNrc2l6ZTsKCW51bUZyYW1lKys7CglpbmZvUHRyLT5mbm1taW9Bc2NlbmQoaW5mb1B0ci0+aE1NaW8sICZtbWNrSW5mbywgMCk7CiAgICB9CiAgICBpZiAobnVtRnJhbWUgIT0gaW5mb1B0ci0+bWFoLmR3VG90YWxGcmFtZXMpIHsKCVdBUk4oIkZvdW5kICVsZCBmcmFtZXMgKC8lbGQpXG4iLCBudW1GcmFtZSwgaW5mb1B0ci0+bWFoLmR3VG90YWxGcmFtZXMpOwoJcmV0dXJuIEZBTFNFOwogICAgfQogICAgaWYgKGluc2l6ZSA+IGluZm9QdHItPmFzaC5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUpIHsKCVdBUk4oImluc2l6ZT0lbGQgc3VnZ2VzdGVkU2l6ZT0lbGRcbiIsIGluc2l6ZSwgaW5mb1B0ci0+YXNoLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSk7CglpbmZvUHRyLT5hc2guZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gaW5zaXplOwogICAgfQoKICAgIGluZm9QdHItPmluZGF0YSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBpbmZvUHRyLT5hc2guZHdTdWdnZXN0ZWRCdWZmZXJTaXplKTsKICAgIGlmICghaW5mb1B0ci0+aW5kYXRhKSB7CglXQVJOKCJDYW4ndCBhbGxvYyBpbnB1dCBidWZmZXJcbiIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIHJldHVybiBUUlVFOwp9CgoKc3RhdGljIEJPT0wgICAgQU5JTUFURV9HZXRBdmlDb2RlYyhBTklNQVRFX0lORk8gKmluZm9QdHIpCnsKICAgIERXT1JECW91dFNpemU7CgogICAgLyogY2hlY2sgdW5jb21wcmVzc2VkIEFWSSAqLwogICAgaWYgKGluZm9QdHItPmFzaC5mY2NIYW5kbGVyID09IG1taW9GT1VSQ0MoJ0QnLCAnSScsICdCJywgJyAnKSkgewoJaW5mb1B0ci0+aGljID0gMDsKCXJldHVybiBUUlVFOwogICAgfQoKICAgIC8qIHRyeSB0byBnZXQgYSBkZWNvbXByZXNzb3IgZm9yIHRoYXQgdHlwZSAqLwogICAgaW5mb1B0ci0+aGljID0gKGluZm9QdHItPmZuSUNPcGVuKShJQ1RZUEVfVklERU8sIAoJCQkJICAgICAgIGluZm9QdHItPmFzaC5mY2NIYW5kbGVyLCAKCQkJCSAgICAgICBJQ01PREVfREVDT01QUkVTUyk7CiAgICBpZiAoIWluZm9QdHItPmhpYykgewoJV0FSTigiQ2FuJ3QgbG9hZCBjb2RlYyBmb3IgdGhlIGZpbGVcbiIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQogICAgCiAgICBvdXRTaXplID0gKGluZm9QdHItPmZuSUNTZW5kTWVzc2FnZSkoaW5mb1B0ci0+aGljLCAKCQkJCQkgSUNNX0RFQ09NUFJFU1NfR0VUX0ZPUk1BVCwgCgkJCQkJIChEV09SRClpbmZvUHRyLT5pbmJpaCwgMEwpOwogICAgaW5mb1B0ci0+b3V0YmloID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIG91dFNpemUpOwogICAgaWYgKCFpbmZvUHRyLT5vdXRiaWgpIHsKCVdBUk4oIkNhbid0IGFsbG9jIG91dHB1dCBCSUhcbiIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmICgoaW5mb1B0ci0+Zm5JQ1NlbmRNZXNzYWdlKShpbmZvUHRyLT5oaWMsIElDTV9ERUNPTVBSRVNTX0dFVF9GT1JNQVQsIAoJCQkJICAgKERXT1JEKWluZm9QdHItPmluYmloLCAKCQkJCSAgIChEV09SRClpbmZvUHRyLT5vdXRiaWgpICE9IElDRVJSX09LKSB7CglXQVJOKCJDYW4ndCBnZXQgb3V0cHV0IEJJSFxuIik7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaW5mb1B0ci0+b3V0ZGF0YSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBpbmZvUHRyLT5vdXRiaWgtPmJpU2l6ZUltYWdlKTsKICAgIGlmICghaW5mb1B0ci0+b3V0ZGF0YSkgewoJV0FSTigiQ2FuJ3QgYWxsb2Mgb3V0cHV0IGJ1ZmZlclxuIik7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKChpbmZvUHRyLT5mbklDU2VuZE1lc3NhZ2UpKGluZm9QdHItPmhpYywgSUNNX0RFQ09NUFJFU1NfQkVHSU4sIAoJCQkJICAgKERXT1JEKWluZm9QdHItPmluYmloLCAKCQkJCSAgIChEV09SRClpbmZvUHRyLT5vdXRiaWgpICE9IElDRVJSX09LKSB7CglXQVJOKCJDYW4ndCBiZWdpbiBkZWNvbXByZXNzaW9uXG4iKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIExSRVNVTFQgQU5JTUFURV9PcGVuQShIV05EIGhXbmQsIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0pCnsKICAgIEFOSU1BVEVfSU5GTyAqaW5mb1B0ciA9IEFOSU1BVEVfR2V0SW5mb1B0cihoV25kKTsKICAgIEhJTlNUQU5DRSBoSW5zdGFuY2UgPSAoSElOU1RBTkNFKXdQYXJhbTsKCiAgICBBTklNQVRFX0ZyZWUoaW5mb1B0cik7CgogICAgaWYgKCFsUGFyYW0pIHsKCVRSQUNFKCJDbG9zaW5nIGF2aSFcbiIpOwoJcmV0dXJuIFRSVUU7CiAgICB9CiAgICAKICAgIGlmICghaEluc3RhbmNlKQogICAgICAgaEluc3RhbmNlID0gR2V0V2luZG93TG9uZ0EoaFduZCwgR1dMX0hJTlNUQU5DRSk7CgogICAgaWYgKEhJV09SRChsUGFyYW0pKSB7CglUUkFDRSgiKFwiJXNcIik7XG4iLCAoTFBTVFIpbFBhcmFtKTsKCglpZiAoIUFOSU1BVEVfTG9hZFJlc0EoaW5mb1B0ciwgaEluc3RhbmNlLCAoTFBTVFIpbFBhcmFtKSkgewoJICAgIFRSQUNFKCJObyBBVkkgcmVzb3VyY2UgZm91bmQhXG4iKTsKCSAgICBpZiAoIUFOSU1BVEVfTG9hZEZpbGVBKGluZm9QdHIsIChMUFNUUilsUGFyYW0pKSB7CgkJV0FSTigiTm8gQVZJIGZpbGUgZm91bmQhXG4iKTsKCQlyZXR1cm4gRkFMU0U7CgkgICAgfQoJfQogICAgfSBlbHNlIHsKCVRSQUNFKCIoJXUpO1xuIiwgKFdPUkQpTE9XT1JEKGxQYXJhbSkpOwoKCWlmICghQU5JTUFURV9Mb2FkUmVzQShpbmZvUHRyLCBoSW5zdGFuY2UsCgkJCSAgICAgIE1BS0VJTlRSRVNPVVJDRUEoKElOVClsUGFyYW0pKSkgewoJICAgIFdBUk4oIk5vIEFWSSByZXNvdXJjZSBmb3VuZCFcbiIpOwoJICAgIHJldHVybiBGQUxTRTsKCX0KICAgIH0KCiAgICBpZiAoIUFOSU1BVEVfR2V0QXZpSW5mbyhpbmZvUHRyKSkgewoJV0FSTigiQ2FuJ3QgZ2V0IEFWSSBpbmZvcm1hdGlvblxuIik7CglBTklNQVRFX0ZyZWUoaW5mb1B0cik7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKCFBTklNQVRFX0dldEF2aUNvZGVjKGluZm9QdHIpKSB7CglXQVJOKCJDYW4ndCBnZXQgQVZJIENvZGVjXG4iKTsKCUFOSU1BVEVfRnJlZShpbmZvUHRyKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAoR2V0V2luZG93TG9uZ0EoaFduZCwgR1dMX1NUWUxFKSAmIEFDU19DRU5URVIpIHsKCUZJWE1FKCJBQ1NfQ0VOVEVSOiBOSVlcbiIpOwogICAgfSBlbHNlIHsKCS8qCU1vdmVXaW5kb3coaFduZCwgMCwgMCwgaW5mb1B0ci0+bWFoLmR3V2lkdGgsIGluZm9QdHItPm1haC5kd0hlaWdodCwgRkFMU0UpOyovCglTZXRXaW5kb3dQb3MoaFduZCwgMCwgMCwgMCwgaW5mb1B0ci0+bWFoLmR3V2lkdGgsIGluZm9QdHItPm1haC5kd0hlaWdodCwKCQkgICAgIFNXUF9OT0FDVElWQVRFIHwgU1dQX05PTU9WRSB8IFNXUF9OT1pPUkRFUik7CiAgICB9CgogICAgaWYgKEdldFdpbmRvd0xvbmdBKGhXbmQsIEdXTF9TVFlMRSkgJiBBQ1NfVFJBTlNQQVJFTlQpIHsKCUZJWE1FKCJBQ1NfVFJBTlNQQVJFTlQ6IE5JWVxuIik7CiAgICB9CgogICAgaWYgKEdldFdpbmRvd0xvbmdBKGhXbmQsIEdXTF9TVFlMRSkgJiBBQ1NfQVVUT1BMQVkpIHsKCXJldHVybiBBTklNQVRFX1BsYXkoaFduZCwgLTEsIChMUEFSQU0pTUFLRUxPTkcoMCwgaW5mb1B0ci0+bWFoLmR3VG90YWxGcmFtZXMtMSkpOwogICAgfQoKICAgIHJldHVybiBUUlVFOwp9CgoKLyogPDwgQU5JTUFURV9PcGVuMzJXID4+ICovCgpzdGF0aWMgTFJFU1VMVCBBTklNQVRFX1N0b3AoSFdORCBoV25kLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBBTklNQVRFX0lORk8gKmluZm9QdHIgPSBBTklNQVRFX0dldEluZm9QdHIoaFduZCk7CgogICAgLyogbm90aGluZyBvcGVuZWQgKi8KICAgIGlmICghaW5mb1B0ci0+aE1NaW8pCglyZXR1cm4gRkFMU0U7CgogICAgQU5JTUFURV9Eb1N0b3AoaW5mb1B0cik7CiAgICByZXR1cm4gVFJVRTsKfQoKCnN0YXRpYyBMUkVTVUxUIEFOSU1BVEVfQ3JlYXRlKEhXTkQgaFduZCwgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogICAgQU5JTUFURV9JTkZPKglpbmZvUHRyOwogICAgSE1PRFVMRQkJaE1vZHVsZSA9IExvYWRMaWJyYXJ5QSgibXN2ZnczMi5kbGwiKTsKCiAgICBpZiAoIWhNb2R1bGUpCglyZXR1cm4gRkFMU0U7CgogICAgLyogYWxsb2NhdGUgbWVtb3J5IGZvciBpbmZvIHN0cnVjdHVyZSAqLwogICAgaW5mb1B0ciA9IChBTklNQVRFX0lORk8gKilDT01DVEwzMl9BbGxvYyhzaXplb2YoQU5JTUFURV9JTkZPKSk7CiAgICBpZiAoIWluZm9QdHIpIHsKCUVSUigiY291bGQgbm90IGFsbG9jYXRlIGluZm8gbWVtb3J5IVxuIik7CglyZXR1cm4gMDsKICAgIH0KCiAgICAvKiBUZW1wb3JhcnkgaGFjayB1bnRpbCB3ZSBnZXQgZGxsZ2x1ZSB1cCBhbmQgcnVubmluZyAqLwogICAgaW5mb1B0ci0+Zm5JQ09wZW4gICAgICAgID0gKHZvaWQqKUdldFByb2NBZGRyZXNzKGhNb2R1bGUsICJJQ09wZW4iKTsKICAgIGluZm9QdHItPmZuSUNDbG9zZSAgICAgICA9ICh2b2lkKilHZXRQcm9jQWRkcmVzcyhoTW9kdWxlLCAiSUNDbG9zZSIpOwogICAgaW5mb1B0ci0+Zm5JQ1NlbmRNZXNzYWdlID0gKHZvaWQqKUdldFByb2NBZGRyZXNzKGhNb2R1bGUsICJJQ1NlbmRNZXNzYWdlIik7CiAgICBpbmZvUHRyLT5mbklDRGVjb21wcmVzcyAgPSAodm9pZCopR2V0UHJvY0FkZHJlc3MoaE1vZHVsZSwgIklDRGVjb21wcmVzcyIpOwoKICAgIFRSQUNFKCJBbmltYXRlIHN0eWxlPTB4JTA4bHgsIHBhcmVudD0lMDhseFxuIiwgR2V0V2luZG93TG9uZ0EoaFduZCwgR1dMX1NUWUxFKSwgKERXT1JEKUdldFBhcmVudChoV25kKSk7CgogICAgLyogc3RvcmUgY3Jvc3NyZWYgaFduZCA8LT4gaW5mbyBzdHJ1Y3R1cmUgKi8KICAgIFNldFdpbmRvd0xvbmdBKGhXbmQsIDAsIChEV09SRClpbmZvUHRyKTsKICAgIGluZm9QdHItPmhXbmQgPSBoV25kOwoKICAgIGhNb2RXaW5tbSA9IExvYWRMaWJyYXJ5QSgiV0lOTU0iKTsKCiAgICBpbmZvUHRyLT5mbm1taW9PcGVuQSA9ICh2b2lkKilHZXRQcm9jQWRkcmVzcyhoTW9kV2lubW0sICJtbWlvT3BlbkEiKTsKICAgIGluZm9QdHItPmZubW1pb0Nsb3NlID0gKHZvaWQqKUdldFByb2NBZGRyZXNzKGhNb2RXaW5tbSwgIm1taW9DbG9zZSIpOwogICAgaW5mb1B0ci0+Zm5tbWlvQXNjZW5kID0gKHZvaWQqKUdldFByb2NBZGRyZXNzKGhNb2RXaW5tbSwgIm1taW9Bc2NlbmQiKTsKICAgIGluZm9QdHItPmZubW1pb0Rlc2NlbmQgPSAodm9pZCopR2V0UHJvY0FkZHJlc3MoaE1vZFdpbm1tLCAibW1pb0Rlc2NlbmQiKTsKICAgIGluZm9QdHItPmZubW1pb1NlZWsgPSAodm9pZCopR2V0UHJvY0FkZHJlc3MoaE1vZFdpbm1tLCAibW1pb1NlZWsiKTsKICAgIGluZm9QdHItPmZubW1pb1JlYWQgPSAodm9pZCopR2V0UHJvY0FkZHJlc3MoaE1vZFdpbm1tLCAibW1pb1JlYWQiKTsKCiAgICBJbml0aWFsaXplQ3JpdGljYWxTZWN0aW9uKCZpbmZvUHRyLT5jcyk7CiAgICAKICAgIHJldHVybiAwOwp9CgoKc3RhdGljIExSRVNVTFQgQU5JTUFURV9EZXN0cm95KEhXTkQgaFduZCwgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogICAgQU5JTUFURV9JTkZPICppbmZvUHRyID0gQU5JTUFURV9HZXRJbmZvUHRyKGhXbmQpOwoKCiAgICAvKiBmcmVlIGF2aSBkYXRhICovCiAgICBBTklNQVRFX0ZyZWUoaW5mb1B0cik7CgogICAgLyogZnJlZSBhbmltYXRlIGluZm8gZGF0YSAqLwogICAgQ09NQ1RMMzJfRnJlZShpbmZvUHRyKTsKICAgIFNldFdpbmRvd0xvbmdBKGhXbmQsIDAsIDApOwoKICAgIEZyZWVMaWJyYXJ5KGhNb2RXaW5tbSk7CiAgICByZXR1cm4gMDsKfQoKCnN0YXRpYyBMUkVTVUxUIEFOSU1BVEVfRXJhc2VCYWNrZ3JvdW5kKEhXTkQgaFduZCwgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogICAgUkVDVCByZWN0OwoKICAgIEdldENsaWVudFJlY3QoaFduZCwgJnJlY3QpOwojaWYgMAogICAgSEJSVVNIIGhCcnVzaCA9IENyZWF0ZVNvbGlkQnJ1c2goaW5mb1B0ci0+Y2xyQmspOwoKICAgIEZpbGxSZWN0KChIREMpd1BhcmFtLCAmcmVjdCwgaEJydXNoKTsKICAgIERlbGV0ZU9iamVjdChoQnJ1c2gpOwojZWxzZQogICAgRmlsbFJlY3QoKEhEQyl3UGFyYW0sICZyZWN0LCBHZXRTeXNDb2xvckJydXNoKENPTE9SX1dJTkRPVykpOwojZW5kaWYKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgTFJFU1VMVCBXSU5BUEkgQU5JTUFURV9TaXplKEhXTkQgaFduZCwgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogICAgQU5JTUFURV9JTkZPICppbmZvUHRyID0gQU5JTUFURV9HZXRJbmZvUHRyKGhXbmQpOwoKICAgIGlmIChHZXRXaW5kb3dMb25nQShoV25kLCBHV0xfU1RZTEUpICYgQUNTX0NFTlRFUikgewoJRklYTUUoIk5JWVxuIik7CglpZiAoaW5mb1B0ci0+aE1NaW8pIHsKCSAgICAvKiBjZW50ZXJzIHRoZSBhbmltYXRpb24gaW4gdGhlIGNvbnRyb2wsIGludmFsaWRhdGVzIHRoZSBjb250cm9sCgkgICAgICovCgl9CglJbnZhbGlkYXRlUmVjdChoV25kLCBOVUxMLCBUUlVFKTsKICAgIH0KICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgTFJFU1VMVCBXSU5BUEkgQU5JTUFURV9XaW5kb3dQcm9jKEhXTkQgaFduZCwgVUlOVCB1TXNnLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBUUkFDRSgiaHduZD0leCBtc2c9JXggd3BhcmFtPSV4IGxwYXJhbT0lbHhcbiIsIGhXbmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKICAgIGlmICghQU5JTUFURV9HZXRJbmZvUHRyKGhXbmQpICYmICh1TXNnICE9IFdNX05DQ1JFQVRFKSkKCXJldHVybiBEZWZXaW5kb3dQcm9jQShoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7CiAgICBzd2l0Y2ggKHVNc2cpCiAgICB7CiAgICBjYXNlIEFDTV9PUEVOQToKCXJldHVybiBBTklNQVRFX09wZW5BKGhXbmQsIHdQYXJhbSwgbFBhcmFtKTsKCQoJLyoJY2FzZSBBQ01fT1BFTjMyVzogRklYTUUhISAqLwoJLyoJICAgIHJldHVybiBBTklNQVRFX09wZW4zMlcoaFduZCwgd1BhcmFtLCBsUGFyYW0pOyAqLwoJCiAgICBjYXNlIEFDTV9QTEFZOgoJcmV0dXJuIEFOSU1BVEVfUGxheShoV25kLCB3UGFyYW0sIGxQYXJhbSk7CgkKICAgIGNhc2UgQUNNX1NUT1A6CglyZXR1cm4gQU5JTUFURV9TdG9wKGhXbmQsIHdQYXJhbSwgbFBhcmFtKTsKCQogICAgY2FzZSBXTV9OQ0NSRUFURToKCUFOSU1BVEVfQ3JlYXRlKGhXbmQsIHdQYXJhbSwgbFBhcmFtKTsKCXJldHVybiBEZWZXaW5kb3dQcm9jQShoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7CgkKICAgIGNhc2UgV01fTkNISVRURVNUOgoJcmV0dXJuIEhUVFJBTlNQQVJFTlQ7CgogICAgY2FzZSBXTV9ERVNUUk9ZOgoJQU5JTUFURV9EZXN0cm95KGhXbmQsIHdQYXJhbSwgbFBhcmFtKTsKCXJldHVybiBEZWZXaW5kb3dQcm9jQShoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7CgkKICAgIGNhc2UgV01fRVJBU0VCS0dORDoKCUFOSU1BVEVfRXJhc2VCYWNrZ3JvdW5kKGhXbmQsIHdQYXJhbSwgbFBhcmFtKTsKCWJyZWFrOwoKICAgIC8qCWNhc2UgV01fU1RZTEVDSEFOR0VEOiBGSVhNRSBzaGFsbCB3ZSBkbyBzb21ldGhpbmcgPz8gKi8KCiAgICBjYXNlIFdNX1RJTUVSOgoJcmV0dXJuIEFOSU1BVEVfRHJhd0ZyYW1lKEFOSU1BVEVfR2V0SW5mb1B0cihoV25kKSk7CgkKICAgIGNhc2UgV01fQ0xPU0U6CglBTklNQVRFX0ZyZWUoQU5JTUFURV9HZXRJbmZvUHRyKGhXbmQpKTsKCXJldHVybiBUUlVFOwoKICAgIGNhc2UgV01fUEFJTlQ6CglpZiAod1BhcmFtKSB7CgkgICAgQU5JTUFURV9QYWludEZyYW1lKEFOSU1BVEVfR2V0SW5mb1B0cihoV25kKSwgKEhEQyl3UGFyYW0pOwoJfSBlbHNlIHsKCSAgICBQQUlOVFNUUlVDVCBwczsKIAkgICAgSERDIGhEQyA9IEJlZ2luUGFpbnQoaFduZCwgJnBzKTsKCSAgICBBTklNQVRFX1BhaW50RnJhbWUoQU5JTUFURV9HZXRJbmZvUHRyKGhXbmQpLCBoREMpOwoJICAgIEVuZFBhaW50KGhXbmQsICZwcyk7Cgl9CglicmVhazsKCiAgICBjYXNlIFdNX1NJWkU6CglBTklNQVRFX1NpemUoaFduZCwgd1BhcmFtLCBsUGFyYW0pOwoJcmV0dXJuIERlZldpbmRvd1Byb2NBKGhXbmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKCiAgICBkZWZhdWx0OgoJaWYgKHVNc2cgPj0gV01fVVNFUikKCSAgICBFUlIoInVua25vd24gbXNnICUwNHggd3A9JTA4eCBscD0lMDhseFxuIiwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwoJCglyZXR1cm4gRGVmV2luZG93UHJvY0EoaFduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCgp2b2lkIEFOSU1BVEVfUmVnaXN0ZXIodm9pZCkKewogICAgV05EQ0xBU1NBIHduZENsYXNzOwoKICAgIFplcm9NZW1vcnkoJnduZENsYXNzLCBzaXplb2YoV05EQ0xBU1NBKSk7CiAgICB3bmRDbGFzcy5zdHlsZSAgICAgICAgID0gQ1NfR0xPQkFMQ0xBU1MgfCBDU19EQkxDTEtTOwogICAgd25kQ2xhc3MubHBmblduZFByb2MgICA9IChXTkRQUk9DKUFOSU1BVEVfV2luZG93UHJvYzsKICAgIHduZENsYXNzLmNiQ2xzRXh0cmEgICAgPSAwOwogICAgd25kQ2xhc3MuY2JXbmRFeHRyYSAgICA9IHNpemVvZihBTklNQVRFX0lORk8gKik7CiAgICB3bmRDbGFzcy5oQ3Vyc29yICAgICAgID0gTG9hZEN1cnNvckEoMCwgSURDX0FSUk9XQSk7CiAgICB3bmRDbGFzcy5oYnJCYWNrZ3JvdW5kID0gKEhCUlVTSCkoQ09MT1JfQlRORkFDRSArIDEpOwogICAgd25kQ2xhc3MubHBzekNsYXNzTmFtZSA9IEFOSU1BVEVfQ0xBU1NBOwogCiAgICBSZWdpc3RlckNsYXNzQSgmd25kQ2xhc3MpOwp9CgoKdm9pZCBBTklNQVRFX1VucmVnaXN0ZXIodm9pZCkKewogICAgVW5yZWdpc3RlckNsYXNzQShBTklNQVRFX0NMQVNTQSwgKEhJTlNUQU5DRSlOVUxMKTsKfQoK