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+aW5kYXRhKSB7CglXQVJOKCJDYW4ndCBhbGxvYyBpbnB1dCBidWZmZXJcbiIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIHJldHVybiBUUlVFOwp9CgoKc3RhdGljIEJPT0wgICAgQU5JTUFURV9HZXRBdmlDb2RlYyhBTklNQVRFX0lORk8gKmluZm9QdHIpCnsKICAgIERXT1JECW91dFNpemU7CgogICAgLyogY2hlY2sgdW5jb21wcmVzc2VkIEFWSSAqLwogICAgaWYgKGluZm9QdHItPmFzaC5mY2NIYW5kbGVyID09IG1taW9GT1VSQ0MoJ0QnLCAnSScsICdCJywgJyAnKSB8fAoJaW5mb1B0ci0+YXNoLmZjY0hhbmRsZXIgPT0gbW1pb0ZPVVJDQygnUicsICdMJywgJ0UnLCAnICcpKSB7CglpbmZvUHRyLT5oaWMgPSAwOwoJcmV0dXJuIFRSVUU7CiAgICB9CgogICAgLyogdHJ5IHRvIGdldCBhIGRlY29tcHJlc3NvciBmb3IgdGhhdCB0eXBlICovCiAgICBpbmZvUHRyLT5oaWMgPSAoaW5mb1B0ci0+Zm5JQ09wZW4pKElDVFlQRV9WSURFTywgCgkJCQkgICAgICAgaW5mb1B0ci0+YXNoLmZjY0hhbmRsZXIsIAoJCQkJICAgICAgIElDTU9ERV9ERUNPTVBSRVNTKTsKICAgIGlmICghaW5mb1B0ci0+aGljKSB7CglXQVJOKCJDYW4ndCBsb2FkIGNvZGVjIGZvciB0aGUgZmlsZVxuIik7CglyZXR1cm4gRkFMU0U7CiAgICB9CiAgICAKICAgIG91dFNpemUgPSAoaW5mb1B0ci0+Zm5JQ1NlbmRNZXNzYWdlKShpbmZvUHRyLT5oaWMsIAoJCQkJCSBJQ01fREVDT01QUkVTU19HRVRfRk9STUFULCAKCQkJCQkgKERXT1JEKWluZm9QdHItPmluYmloLCAwTCk7CiAgICBpbmZvUHRyLT5vdXRiaWggPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb3V0U2l6ZSk7CiAgICBpZiAoIWluZm9QdHItPm91dGJpaCkgewoJV0FSTigiQ2FuJ3QgYWxsb2Mgb3V0cHV0IEJJSFxuIik7CglyZXR1cm4gRkFMU0U7CiAgICB9CgogICAgaWYgKChpbmZvUHRyLT5mbklDU2VuZE1lc3NhZ2UpKGluZm9QdHItPmhpYywgSUNNX0RFQ09NUFJFU1NfR0VUX0ZPUk1BVCwgCgkJCQkgICAoRFdPUkQpaW5mb1B0ci0+aW5iaWgsIAoJCQkJICAgKERXT1JEKWluZm9QdHItPm91dGJpaCkgIT0gSUNFUlJfT0spIHsKCVdBUk4oIkNhbid0IGdldCBvdXRwdXQgQklIXG4iKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpbmZvUHRyLT5vdXRkYXRhID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGluZm9QdHItPm91dGJpaC0+YmlTaXplSW1hZ2UpOwogICAgaWYgKCFpbmZvUHRyLT5vdXRkYXRhKSB7CglXQVJOKCJDYW4ndCBhbGxvYyBvdXRwdXQgYnVmZmVyXG4iKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAoKGluZm9QdHItPmZuSUNTZW5kTWVzc2FnZSkoaW5mb1B0ci0+aGljLCBJQ01fREVDT01QUkVTU19CRUdJTiwgCgkJCQkgICAoRFdPUkQpaW5mb1B0ci0+aW5iaWgsIAoJCQkJICAgKERXT1JEKWluZm9QdHItPm91dGJpaCkgIT0gSUNFUlJfT0spIHsKCVdBUk4oIkNhbid0IGJlZ2luIGRlY29tcHJlc3Npb25cbiIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgTFJFU1VMVCBBTklNQVRFX09wZW5BKEhXTkQgaFduZCwgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogICAgQU5JTUFURV9JTkZPICppbmZvUHRyID0gQU5JTUFURV9HZXRJbmZvUHRyKGhXbmQpOwogICAgSElOU1RBTkNFIGhJbnN0YW5jZSA9IChISU5TVEFOQ0Upd1BhcmFtOwoKICAgIEFOSU1BVEVfRnJlZShpbmZvUHRyKTsKCiAgICBpZiAoIWxQYXJhbSkgewoJVFJBQ0UoIkNsb3NpbmcgYXZpIVxuIik7CglyZXR1cm4gVFJVRTsKICAgIH0KICAgIAogICAgaWYgKCFoSW5zdGFuY2UpCiAgICAgICBoSW5zdGFuY2UgPSBHZXRXaW5kb3dMb25nQShoV25kLCBHV0xfSElOU1RBTkNFKTsKCiAgICBpZiAoSElXT1JEKGxQYXJhbSkpIHsKCVRSQUNFKCIoXCIlc1wiKTtcbiIsIChMUFNUUilsUGFyYW0pOwoKCWlmICghQU5JTUFURV9Mb2FkUmVzQShpbmZvUHRyLCBoSW5zdGFuY2UsIChMUFNUUilsUGFyYW0pKSB7CgkgICAgVFJBQ0UoIk5vIEFWSSByZXNvdXJjZSBmb3VuZCFcbiIpOwoJICAgIGlmICghQU5JTUFURV9Mb2FkRmlsZUEoaW5mb1B0ciwgKExQU1RSKWxQYXJhbSkpIHsKCQlXQVJOKCJObyBBVkkgZmlsZSBmb3VuZCFcbiIpOwoJCXJldHVybiBGQUxTRTsKCSAgICB9Cgl9CiAgICB9IGVsc2UgewoJVFJBQ0UoIigldSk7XG4iLCAoV09SRClMT1dPUkQobFBhcmFtKSk7CgoJaWYgKCFBTklNQVRFX0xvYWRSZXNBKGluZm9QdHIsIGhJbnN0YW5jZSwKCQkJICAgICAgTUFLRUlOVFJFU09VUkNFQSgoSU5UKWxQYXJhbSkpKSB7CgkgICAgV0FSTigiTm8gQVZJIHJlc291cmNlIGZvdW5kIVxuIik7CgkgICAgcmV0dXJuIEZBTFNFOwoJfQogICAgfQoKICAgIGlmICghQU5JTUFURV9HZXRBdmlJbmZvKGluZm9QdHIpKSB7CglXQVJOKCJDYW4ndCBnZXQgQVZJIGluZm9ybWF0aW9uXG4iKTsKCUFOSU1BVEVfRnJlZShpbmZvUHRyKTsKCXJldHVybiBGQUxTRTsKICAgIH0KCiAgICBpZiAoIUFOSU1BVEVfR2V0QXZpQ29kZWMoaW5mb1B0cikpIHsKCVdBUk4oIkNhbid0IGdldCBBVkkgQ29kZWNcbiIpOwoJQU5JTUFURV9GcmVlKGluZm9QdHIpOwoJcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIGlmIChHZXRXaW5kb3dMb25nQShoV25kLCBHV0xfU1RZTEUpICYgQUNTX0NFTlRFUikgewoJRklYTUUoIkFDU19DRU5URVI6IE5JWVxuIik7CiAgICB9IGVsc2UgewoJLyoJTW92ZVdpbmRvdyhoV25kLCAwLCAwLCBpbmZvUHRyLT5tYWguZHdXaWR0aCwgaW5mb1B0ci0+bWFoLmR3SGVpZ2h0LCBGQUxTRSk7Ki8KCVNldFdpbmRvd1BvcyhoV25kLCAwLCAwLCAwLCBpbmZvUHRyLT5tYWguZHdXaWR0aCwgaW5mb1B0ci0+bWFoLmR3SGVpZ2h0LAoJCSAgICAgU1dQX05PQUNUSVZBVEUgfCBTV1BfTk9NT1ZFIHwgU1dQX05PWk9SREVSKTsKICAgIH0KCiAgICBpZiAoR2V0V2luZG93TG9uZ0EoaFduZCwgR1dMX1NUWUxFKSAmIEFDU19UUkFOU1BBUkVOVCkgewoJRklYTUUoIkFDU19UUkFOU1BBUkVOVDogTklZXG4iKTsKICAgIH0KCiAgICBpZiAoR2V0V2luZG93TG9uZ0EoaFduZCwgR1dMX1NUWUxFKSAmIEFDU19BVVRPUExBWSkgewoJcmV0dXJuIEFOSU1BVEVfUGxheShoV25kLCAtMSwgKExQQVJBTSlNQUtFTE9ORygwLCBpbmZvUHRyLT5tYWguZHdUb3RhbEZyYW1lcy0xKSk7CiAgICB9CgogICAgcmV0dXJuIFRSVUU7Cn0KCgovKiA8PCBBTklNQVRFX09wZW4zMlcgPj4gKi8KCnN0YXRpYyBMUkVTVUxUIEFOSU1BVEVfU3RvcChIV05EIGhXbmQsIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0pCnsKICAgIEFOSU1BVEVfSU5GTyAqaW5mb1B0ciA9IEFOSU1BVEVfR2V0SW5mb1B0cihoV25kKTsKCiAgICAvKiBub3RoaW5nIG9wZW5lZCAqLwogICAgaWYgKCFpbmZvUHRyLT5oTU1pbykKCXJldHVybiBGQUxTRTsKCiAgICBBTklNQVRFX0RvU3RvcChpbmZvUHRyKTsKICAgIHJldHVybiBUUlVFOwp9CgoKc3RhdGljIExSRVNVTFQgQU5JTUFURV9DcmVhdGUoSFdORCBoV25kLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBBTklNQVRFX0lORk8qCWluZm9QdHI7CiAgICBITU9EVUxFCQloTW9kdWxlID0gTG9hZExpYnJhcnlBKCJtc3ZmdzMyLmRsbCIpOwoKICAgIGlmICghaE1vZHVsZSkKCXJldHVybiBGQUxTRTsKCiAgICAvKiBhbGxvY2F0ZSBtZW1vcnkgZm9yIGluZm8gc3RydWN0dXJlICovCiAgICBpbmZvUHRyID0gKEFOSU1BVEVfSU5GTyAqKUNPTUNUTDMyX0FsbG9jKHNpemVvZihBTklNQVRFX0lORk8pKTsKICAgIGlmICghaW5mb1B0cikgewoJRVJSKCJjb3VsZCBub3QgYWxsb2NhdGUgaW5mbyBtZW1vcnkhXG4iKTsKCXJldHVybiAwOwogICAgfQoKICAgIC8qIFRlbXBvcmFyeSBoYWNrIHVudGlsIHdlIGdldCBkbGxnbHVlIHVwIGFuZCBydW5uaW5nICovCiAgICBpbmZvUHRyLT5mbklDT3BlbiAgICAgICAgPSAodm9pZCopR2V0UHJvY0FkZHJlc3MoaE1vZHVsZSwgIklDT3BlbiIpOwogICAgaW5mb1B0ci0+Zm5JQ0Nsb3NlICAgICAgID0gKHZvaWQqKUdldFByb2NBZGRyZXNzKGhNb2R1bGUsICJJQ0Nsb3NlIik7CiAgICBpbmZvUHRyLT5mbklDU2VuZE1lc3NhZ2UgPSAodm9pZCopR2V0UHJvY0FkZHJlc3MoaE1vZHVsZSwgIklDU2VuZE1lc3NhZ2UiKTsKICAgIGluZm9QdHItPmZuSUNEZWNvbXByZXNzICA9ICh2b2lkKilHZXRQcm9jQWRkcmVzcyhoTW9kdWxlLCAiSUNEZWNvbXByZXNzIik7CgogICAgVFJBQ0UoIkFuaW1hdGUgc3R5bGU9MHglMDhseCwgcGFyZW50PSUwOGx4XG4iLCBHZXRXaW5kb3dMb25nQShoV25kLCBHV0xfU1RZTEUpLCAoRFdPUkQpR2V0UGFyZW50KGhXbmQpKTsKCiAgICAvKiBzdG9yZSBjcm9zc3JlZiBoV25kIDwtPiBpbmZvIHN0cnVjdHVyZSAqLwogICAgU2V0V2luZG93TG9uZ0EoaFduZCwgMCwgKERXT1JEKWluZm9QdHIpOwogICAgaW5mb1B0ci0+aFduZCA9IGhXbmQ7CgogICAgaE1vZFdpbm1tID0gTG9hZExpYnJhcnlBKCJXSU5NTSIpOwoKICAgIGluZm9QdHItPmZubW1pb09wZW5BID0gKHZvaWQqKUdldFByb2NBZGRyZXNzKGhNb2RXaW5tbSwgIm1taW9PcGVuQSIpOwogICAgaW5mb1B0ci0+Zm5tbWlvQ2xvc2UgPSAodm9pZCopR2V0UHJvY0FkZHJlc3MoaE1vZFdpbm1tLCAibW1pb0Nsb3NlIik7CiAgICBpbmZvUHRyLT5mbm1taW9Bc2NlbmQgPSAodm9pZCopR2V0UHJvY0FkZHJlc3MoaE1vZFdpbm1tLCAibW1pb0FzY2VuZCIpOwogICAgaW5mb1B0ci0+Zm5tbWlvRGVzY2VuZCA9ICh2b2lkKilHZXRQcm9jQWRkcmVzcyhoTW9kV2lubW0sICJtbWlvRGVzY2VuZCIpOwogICAgaW5mb1B0ci0+Zm5tbWlvU2VlayA9ICh2b2lkKilHZXRQcm9jQWRkcmVzcyhoTW9kV2lubW0sICJtbWlvU2VlayIpOwogICAgaW5mb1B0ci0+Zm5tbWlvUmVhZCA9ICh2b2lkKilHZXRQcm9jQWRkcmVzcyhoTW9kV2lubW0sICJtbWlvUmVhZCIpOwoKICAgIEluaXRpYWxpemVDcml0aWNhbFNlY3Rpb24oJmluZm9QdHItPmNzKTsKICAgIAogICAgcmV0dXJuIDA7Cn0KCgpzdGF0aWMgTFJFU1VMVCBBTklNQVRFX0Rlc3Ryb3koSFdORCBoV25kLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBBTklNQVRFX0lORk8gKmluZm9QdHIgPSBBTklNQVRFX0dldEluZm9QdHIoaFduZCk7CgoKICAgIC8qIGZyZWUgYXZpIGRhdGEgKi8KICAgIEFOSU1BVEVfRnJlZShpbmZvUHRyKTsKCiAgICAvKiBmcmVlIGFuaW1hdGUgaW5mbyBkYXRhICovCiAgICBDT01DVEwzMl9GcmVlKGluZm9QdHIpOwogICAgU2V0V2luZG93TG9uZ0EoaFduZCwgMCwgMCk7CgogICAgRnJlZUxpYnJhcnkoaE1vZFdpbm1tKTsKICAgIHJldHVybiAwOwp9CgoKc3RhdGljIExSRVNVTFQgQU5JTUFURV9FcmFzZUJhY2tncm91bmQoSFdORCBoV25kLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBSRUNUIHJlY3Q7CgogICAgR2V0Q2xpZW50UmVjdChoV25kLCAmcmVjdCk7CiNpZiAwCiAgICBIQlJVU0ggaEJydXNoID0gQ3JlYXRlU29saWRCcnVzaChpbmZvUHRyLT5jbHJCayk7CgogICAgRmlsbFJlY3QoKEhEQyl3UGFyYW0sICZyZWN0LCBoQnJ1c2gpOwogICAgRGVsZXRlT2JqZWN0KGhCcnVzaCk7CiNlbHNlCiAgICBGaWxsUmVjdCgoSERDKXdQYXJhbSwgJnJlY3QsIEdldFN5c0NvbG9yQnJ1c2goQ09MT1JfV0lORE9XKSk7CiNlbmRpZgogICAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBMUkVTVUxUIFdJTkFQSSBBTklNQVRFX1NpemUoSFdORCBoV25kLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBBTklNQVRFX0lORk8gKmluZm9QdHIgPSBBTklNQVRFX0dldEluZm9QdHIoaFduZCk7CgogICAgaWYgKEdldFdpbmRvd0xvbmdBKGhXbmQsIEdXTF9TVFlMRSkgJiBBQ1NfQ0VOVEVSKSB7CglGSVhNRSgiTklZXG4iKTsKCWlmIChpbmZvUHRyLT5oTU1pbykgewoJICAgIC8qIGNlbnRlcnMgdGhlIGFuaW1hdGlvbiBpbiB0aGUgY29udHJvbCwgaW52YWxpZGF0ZXMgdGhlIGNvbnRyb2wKCSAgICAgKi8KCX0KCUludmFsaWRhdGVSZWN0KGhXbmQsIE5VTEwsIFRSVUUpOwogICAgfQogICAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBMUkVTVUxUIFdJTkFQSSBBTklNQVRFX1dpbmRvd1Byb2MoSFdORCBoV25kLCBVSU5UIHVNc2csIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0pCnsKICAgIFRSQUNFKCJod25kPSV4IG1zZz0leCB3cGFyYW09JXggbHBhcmFtPSVseFxuIiwgaFduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwogICAgaWYgKCFBTklNQVRFX0dldEluZm9QdHIoaFduZCkgJiYgKHVNc2cgIT0gV01fTkNDUkVBVEUpKQoJcmV0dXJuIERlZldpbmRvd1Byb2NBKGhXbmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKICAgIHN3aXRjaCAodU1zZykKICAgIHsKICAgIGNhc2UgQUNNX09QRU5BOgoJcmV0dXJuIEFOSU1BVEVfT3BlbkEoaFduZCwgd1BhcmFtLCBsUGFyYW0pOwoJCgkvKgljYXNlIEFDTV9PUEVOMzJXOiBGSVhNRSEhICovCgkvKgkgICAgcmV0dXJuIEFOSU1BVEVfT3BlbjMyVyhoV25kLCB3UGFyYW0sIGxQYXJhbSk7ICovCgkKICAgIGNhc2UgQUNNX1BMQVk6CglyZXR1cm4gQU5JTUFURV9QbGF5KGhXbmQsIHdQYXJhbSwgbFBhcmFtKTsKCQogICAgY2FzZSBBQ01fU1RPUDoKCXJldHVybiBBTklNQVRFX1N0b3AoaFduZCwgd1BhcmFtLCBsUGFyYW0pOwoJCiAgICBjYXNlIFdNX05DQ1JFQVRFOgoJQU5JTUFURV9DcmVhdGUoaFduZCwgd1BhcmFtLCBsUGFyYW0pOwoJcmV0dXJuIERlZldpbmRvd1Byb2NBKGhXbmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKCQogICAgY2FzZSBXTV9OQ0hJVFRFU1Q6CglyZXR1cm4gSFRUUkFOU1BBUkVOVDsKCiAgICBjYXNlIFdNX0RFU1RST1k6CglBTklNQVRFX0Rlc3Ryb3koaFduZCwgd1BhcmFtLCBsUGFyYW0pOwoJcmV0dXJuIERlZldpbmRvd1Byb2NBKGhXbmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKCQogICAgY2FzZSBXTV9FUkFTRUJLR05EOgoJQU5JTUFURV9FcmFzZUJhY2tncm91bmQoaFduZCwgd1BhcmFtLCBsUGFyYW0pOwoJYnJlYWs7CgogICAgLyoJY2FzZSBXTV9TVFlMRUNIQU5HRUQ6IEZJWE1FIHNoYWxsIHdlIGRvIHNvbWV0aGluZyA/PyAqLwoKICAgIGNhc2UgV01fVElNRVI6CglyZXR1cm4gQU5JTUFURV9EcmF3RnJhbWUoQU5JTUFURV9HZXRJbmZvUHRyKGhXbmQpKTsKCQogICAgY2FzZSBXTV9DTE9TRToKCUFOSU1BVEVfRnJlZShBTklNQVRFX0dldEluZm9QdHIoaFduZCkpOwoJcmV0dXJuIFRSVUU7CgogICAgY2FzZSBXTV9QQUlOVDoKCWlmICh3UGFyYW0pIHsKCSAgICBBTklNQVRFX1BhaW50RnJhbWUoQU5JTUFURV9HZXRJbmZvUHRyKGhXbmQpLCAoSERDKXdQYXJhbSk7Cgl9IGVsc2UgewoJICAgIFBBSU5UU1RSVUNUIHBzOwogCSAgICBIREMgaERDID0gQmVnaW5QYWludChoV25kLCAmcHMpOwoJICAgIEFOSU1BVEVfUGFpbnRGcmFtZShBTklNQVRFX0dldEluZm9QdHIoaFduZCksIGhEQyk7CgkgICAgRW5kUGFpbnQoaFduZCwgJnBzKTsKCX0KCWJyZWFrOwoKICAgIGNhc2UgV01fU0laRToKCUFOSU1BVEVfU2l6ZShoV25kLCB3UGFyYW0sIGxQYXJhbSk7CglyZXR1cm4gRGVmV2luZG93UHJvY0EoaFduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwoKICAgIGRlZmF1bHQ6CglpZiAodU1zZyA+PSBXTV9VU0VSKQoJICAgIEVSUigidW5rbm93biBtc2cgJTA0eCB3cD0lMDh4IGxwPSUwOGx4XG4iLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7CgkKCXJldHVybiBEZWZXaW5kb3dQcm9jQShoV25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7CiAgICB9CiAgICByZXR1cm4gMDsKfQoKCnZvaWQgQU5JTUFURV9SZWdpc3Rlcih2b2lkKQp7CiAgICBXTkRDTEFTU0Egd25kQ2xhc3M7CgogICAgWmVyb01lbW9yeSgmd25kQ2xhc3MsIHNpemVvZihXTkRDTEFTU0EpKTsKICAgIHduZENsYXNzLnN0eWxlICAgICAgICAgPSBDU19HTE9CQUxDTEFTUyB8IENTX0RCTENMS1M7CiAgICB3bmRDbGFzcy5scGZuV25kUHJvYyAgID0gKFdORFBST0MpQU5JTUFURV9XaW5kb3dQcm9jOwogICAgd25kQ2xhc3MuY2JDbHNFeHRyYSAgICA9IDA7CiAgICB3bmRDbGFzcy5jYlduZEV4dHJhICAgID0gc2l6ZW9mKEFOSU1BVEVfSU5GTyAqKTsKICAgIHduZENsYXNzLmhDdXJzb3IgICAgICAgPSBMb2FkQ3Vyc29yQSgwLCBJRENfQVJST1dBKTsKICAgIHduZENsYXNzLmhickJhY2tncm91bmQgPSAoSEJSVVNIKShDT0xPUl9CVE5GQUNFICsgMSk7CiAgICB3bmRDbGFzcy5scHN6Q2xhc3NOYW1lID0gQU5JTUFURV9DTEFTU0E7CiAKICAgIFJlZ2lzdGVyQ2xhc3NBKCZ3bmRDbGFzcyk7Cn0KCgp2b2lkIEFOSU1BVEVfVW5yZWdpc3Rlcih2b2lkKQp7CiAgICBVbnJlZ2lzdGVyQ2xhc3NBKEFOSU1BVEVfQ0xBU1NBLCAoSElOU1RBTkNFKU5VTEwpOwp9Cgo=