LyoKICoJQXV0b0NvbXBsZXRlIGludGVyZmFjZXMgaW1wbGVtZW50YXRpb24uCiAqCiAqCUNvcHlyaWdodCAyMDA0CU1heGltZSBCZWxsZW5n6SA8bWF4aW1lLmJlbGxlbmdlQGxhcG9zdGUubmV0PgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgovKgogIEltcGxlbWVudGVkOgogIC0gQUNPX0FVVE9BUFBFTkQgc3R5bGUKICAtIEFDT19BVVRPU1VHR0VTVCBzdHlsZQogIC0gQUNPX1VQRE9XTktFWURST1BTTElTVCBzdHlsZQoKICAtIEhhbmRsZSBwd3pzUmVnS2V5UGF0aCBhbmQgcHdzelF1aWNrQ29tcGxldGUgaW4gSW5pdAoKICBUT0RPOgogIC0gaW1wbGVtZW50IEFDT19TRUFSQ0ggc3R5bGUKICAtIGltcGxlbWVudCBBQ09fRklMVEVSUFJFRklYRVMgc3R5bGUKICAtIGltcGxlbWVudCBBQ09fVVNFVEFCIHN0eWxlCiAgLSBpbXBsZW1lbnQgQUNPX1JUTFJFQURJTkcgc3R5bGUKICAKICovCiNpbmNsdWRlICJjb25maWcuaCIKCiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CgojZGVmaW5lIENPQkpNQUNST1MKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAidW5kb2NzaGVsbC5oIgojaW5jbHVkZSAic2hsd2FwaS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm9iamJhc2UuaCIKCiNpbmNsdWRlICJwaWRsLmgiCiNpbmNsdWRlICJzaGxndWlkLmgiCiNpbmNsdWRlICJzaGxvYmouaCIKI2luY2x1ZGUgInNobGRpc3AuaCIKI2luY2x1ZGUgImRlYnVnaGxwLmgiCgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChzaGVsbCk7Cgp0eXBlZGVmIHN0cnVjdAp7CiAgICBjb25zdCBJQXV0b0NvbXBsZXRlVnRibCAgKmxwVnRibDsKICAgIGNvbnN0IElBdXRvQ29tcGxldGUyVnRibCAqbHB2dGJsQXV0b0NvbXBsZXRlMjsKICAgIExPTkcgcmVmOwogICAgQk9PTCAgZW5hYmxlZDsKICAgIEhXTkQgaHduZEVkaXQ7CiAgICBIV05EIGh3bmRMaXN0Qm94OwogICAgV05EUFJPQyB3cE9yaWdFZGl0UHJvYzsKICAgIFdORFBST0Mgd3BPcmlnTEJveFByb2M7CiAgICBXQ0hBUiAqdHh0YmFja3VwOwogICAgV0NIQVIgKnF1aWNrQ29tcGxldGU7CiAgICBJRW51bVN0cmluZyAqZW51bXN0cjsKICAgIEFVVE9DT01QTEVURU9QVElPTlMgb3B0aW9uczsKfSBJQXV0b0NvbXBsZXRlSW1wbDsKCnN0YXRpYyBjb25zdCBJQXV0b0NvbXBsZXRlVnRibCBhY3Z0OwpzdGF0aWMgY29uc3QgSUF1dG9Db21wbGV0ZTJWdGJsIGFjMnZ0OwoKc3RhdGljIGlubGluZSBJQXV0b0NvbXBsZXRlSW1wbCAqaW1wbF9mcm9tX0lBdXRvQ29tcGxldGUyKCBJQXV0b0NvbXBsZXRlMiAqaWZhY2UgKQp7CiAgICByZXR1cm4gKElBdXRvQ29tcGxldGVJbXBsICopKChjaGFyKilpZmFjZSAtIEZJRUxEX09GRlNFVChJQXV0b0NvbXBsZXRlSW1wbCwgbHB2dGJsQXV0b0NvbXBsZXRlMikpOwp9CgoKLyoKICBjb252ZXJ0cyBUaGlzIHRvIGFuIGludGVyZmFjZSBwb2ludGVyCiovCiNkZWZpbmUgX0lVbmtub3duXyhUaGlzKSAoSVVua25vd24qKSYoVGhpcy0+bHBWdGJsKQojZGVmaW5lIF9JQXV0b0NvbXBsZXRlMl8oVGhpcykgIChJQXV0b0NvbXBsZXRlMiopJihUaGlzLT5scHZ0YmxBdXRvQ29tcGxldGUyKSAKCnN0YXRpYyBMUkVTVUxUIEFQSUVOVFJZIEFDRWRpdFN1YmNsYXNzUHJvYyhIV05EIGh3bmQsIFVJTlQgdU1zZywgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSk7CnN0YXRpYyBMUkVTVUxUIEFQSUVOVFJZIEFDTEJveFN1YmNsYXNzUHJvYyhIV05EIGh3bmQsIFVJTlQgdU1zZywgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIElBdXRvQ29tcGxldGVfQ29uc3RydWN0b3IKICovCkhSRVNVTFQgV0lOQVBJIElBdXRvQ29tcGxldGVfQ29uc3RydWN0b3IoSVVua25vd24gKiBwVW5rT3V0ZXIsIFJFRklJRCByaWlkLCBMUFZPSUQgKiBwcHYpCnsKICAgIElBdXRvQ29tcGxldGVJbXBsICpscGFjOwoKICAgIGlmIChwVW5rT3V0ZXIgJiYgIUlzRXF1YWxJSUQgKHJpaWQsICZJSURfSVVua25vd24pKQoJcmV0dXJuIENMQVNTX0VfTk9BR0dSRUdBVElPTjsKCiAgICBscGFjID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJQXV0b0NvbXBsZXRlSW1wbCkpOwogICAgaWYgKCFscGFjKSAKCXJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIGxwYWMtPnJlZiA9IDE7CiAgICBscGFjLT5scFZ0YmwgPSAmYWN2dDsKICAgIGxwYWMtPmxwdnRibEF1dG9Db21wbGV0ZTIgPSAmYWMydnQ7CiAgICBscGFjLT5lbmFibGVkID0gVFJVRTsKICAgIGxwYWMtPmVudW1zdHIgPSBOVUxMOwogICAgbHBhYy0+b3B0aW9ucyA9IEFDT19BVVRPQVBQRU5EOwogICAgbHBhYy0+d3BPcmlnRWRpdFByb2MgPSBOVUxMOwogICAgbHBhYy0+aHduZExpc3RCb3ggPSBOVUxMOwogICAgbHBhYy0+dHh0YmFja3VwID0gTlVMTDsKICAgIGxwYWMtPnF1aWNrQ29tcGxldGUgPSBOVUxMOwogICAgCiAgICBpZiAoIVNVQ0NFRURFRCAoSVVua25vd25fUXVlcnlJbnRlcmZhY2UgKF9JVW5rbm93bl8gKGxwYWMpLCByaWlkLCBwcHYpKSkgewoJSVVua25vd25fUmVsZWFzZSAoX0lVbmtub3duXyAobHBhYykpOwoJcmV0dXJuIEVfTk9JTlRFUkZBQ0U7CiAgICB9CiAgICAKICAgIFRSQUNFKCItLSAoJXApLT5cbiIsbHBhYyk7CgogICAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgQXV0b0NvbXBsZXRlX1F1ZXJ5SW50ZXJmYWNlCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUF1dG9Db21wbGV0ZV9mblF1ZXJ5SW50ZXJmYWNlKAogICAgSUF1dG9Db21wbGV0ZSAqIGlmYWNlLAogICAgUkVGSUlEIHJpaWQsCiAgICBMUFZPSUQgKnBwdk9iaikKewogICAgSUF1dG9Db21wbGV0ZUltcGwgKlRoaXMgPSAoSUF1dG9Db21wbGV0ZUltcGwgKilpZmFjZTsKICAgIAogICAgVFJBQ0UoIiglcCktPihcblx0SUlEOlx0JXMsJXApXG4iLCBUaGlzLCBzaGRlYnVnc3RyX2d1aWQocmlpZCksIHBwdk9iaik7CiAgICAqcHB2T2JqID0gTlVMTDsKCiAgICBpZihJc0VxdWFsSUlEKHJpaWQsICZJSURfSVVua25vd24pKSAKICAgIHsKCSpwcHZPYmogPSBUaGlzOwogICAgfSAKICAgIGVsc2UgaWYoSXNFcXVhbElJRChyaWlkLCAmSUlEX0lBdXRvQ29tcGxldGUpKQogICAgewoJKnBwdk9iaiA9IChJQXV0b0NvbXBsZXRlKilUaGlzOwogICAgfQogICAgZWxzZSBpZihJc0VxdWFsSUlEKHJpaWQsICZJSURfSUF1dG9Db21wbGV0ZTIpKQogICAgewoJKnBwdk9iaiA9IF9JQXV0b0NvbXBsZXRlMl8gKFRoaXMpOwogICAgfQoKICAgIGlmICgqcHB2T2JqKQogICAgewoJSUF1dG9Db21wbGV0ZV9BZGRSZWYoKElBdXRvQ29tcGxldGUqKSpwcHZPYmopOwoJVFJBQ0UoIi0tIEludGVyZmFjZTogKCVwKS0+KCVwKVxuIiwgcHB2T2JqLCAqcHB2T2JqKTsKCXJldHVybiBTX09LOwogICAgfQogICAgVFJBQ0UoIi0tIEludGVyZmFjZTogRV9OT0lOVEVSRkFDRVxuIik7CiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsJCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUF1dG9Db21wbGV0ZV9mbkFkZFJlZgogKi8Kc3RhdGljIFVMT05HIFdJTkFQSSBJQXV0b0NvbXBsZXRlX2ZuQWRkUmVmKAoJSUF1dG9Db21wbGV0ZSAqIGlmYWNlKQp7CiAgICBJQXV0b0NvbXBsZXRlSW1wbCAqVGhpcyA9IChJQXV0b0NvbXBsZXRlSW1wbCAqKWlmYWNlOwogICAgVUxPTkcgcmVmQ291bnQgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKICAgIAogICAgVFJBQ0UoIiglcCktPiglbHUpXG4iLCBUaGlzLCByZWZDb3VudCAtIDEpOwoKICAgIHJldHVybiByZWZDb3VudDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJQXV0b0NvbXBsZXRlX2ZuUmVsZWFzZQogKi8Kc3RhdGljIFVMT05HIFdJTkFQSSBJQXV0b0NvbXBsZXRlX2ZuUmVsZWFzZSgKCUlBdXRvQ29tcGxldGUgKiBpZmFjZSkKewogICAgSUF1dG9Db21wbGV0ZUltcGwgKlRoaXMgPSAoSUF1dG9Db21wbGV0ZUltcGwgKilpZmFjZTsKICAgIFVMT05HIHJlZkNvdW50ID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZik7CiAgICAKICAgIFRSQUNFKCIoJXApLT4oJWx1KVxuIiwgVGhpcywgcmVmQ291bnQgKyAxKTsKCiAgICBpZiAoIXJlZkNvdW50KSB7CglUUkFDRSgiIGRlc3Ryb3lpbmcgSUF1dG9Db21wbGV0ZSglcClcbiIsVGhpcyk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cXVpY2tDb21wbGV0ZSk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+dHh0YmFja3VwKTsKCWlmIChUaGlzLT5od25kTGlzdEJveCkKCSAgICBEZXN0cm95V2luZG93KFRoaXMtPmh3bmRMaXN0Qm94KTsKCWlmIChUaGlzLT5lbnVtc3RyKQoJICAgIElFbnVtU3RyaW5nX1JlbGVhc2UoVGhpcy0+ZW51bXN0cik7CglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKICAgIH0KICAgIHJldHVybiByZWZDb3VudDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJQXV0b0NvbXBsZXRlX2ZuRW5hYmxlCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUF1dG9Db21wbGV0ZV9mbkVuYWJsZSgKICAgIElBdXRvQ29tcGxldGUgKiBpZmFjZSwKICAgIEJPT0wgZkVuYWJsZSkKewogICAgSUF1dG9Db21wbGV0ZUltcGwgKlRoaXMgPSAoSUF1dG9Db21wbGV0ZUltcGwgKilpZmFjZTsKCiAgICBIUkVTVUxUIGhyID0gU19PSzsKCiAgICBUUkFDRSgiKCVwKS0+KCVzKVxuIiwgVGhpcywgKGZFbmFibGUpPyJ0cnVlIjoiZmFsc2UiKTsKCiAgICBUaGlzLT5lbmFibGVkID0gZkVuYWJsZTsKCiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUF1dG9Db21wbGV0ZV9mbkluaXQKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQXV0b0NvbXBsZXRlX2ZuSW5pdCgKICAgIElBdXRvQ29tcGxldGUgKiBpZmFjZSwKICAgIEhXTkQgaHduZEVkaXQsCiAgICBJVW5rbm93biAqcHVua0FDTCwKICAgIExQQ09MRVNUUiBwd3pzUmVnS2V5UGF0aCwKICAgIExQQ09MRVNUUiBwd3N6UXVpY2tDb21wbGV0ZSkKewogICAgSUF1dG9Db21wbGV0ZUltcGwgKlRoaXMgPSAoSUF1dG9Db21wbGV0ZUltcGwgKilpZmFjZTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBsYk5hbWVbXSA9IHsnTCcsJ2knLCdzJywndCcsJ0InLCdvJywneCcsMH07CgogICAgVFJBQ0UoIiglcCktPigweCUwOGx4LCAlcCwgJXMsICVzKVxuIiwgCgkgIFRoaXMsIChsb25nKWh3bmRFZGl0LCBwdW5rQUNMLCBkZWJ1Z3N0cl93KHB3enNSZWdLZXlQYXRoKSwgZGVidWdzdHJfdyhwd3N6UXVpY2tDb21wbGV0ZSkpOwoKICAgIGlmIChUaGlzLT5vcHRpb25zICYgQUNPX0FVVE9TVUdHRVNUKSBUUkFDRSgiIEFDT19BVVRPU1VHR0VTVFxuIik7CiAgICBpZiAoVGhpcy0+b3B0aW9ucyAmIEFDT19BVVRPQVBQRU5EKSBUUkFDRSgiIEFDT19BVVRPQVBQRU5EXG4iKTsKICAgIGlmIChUaGlzLT5vcHRpb25zICYgQUNPX1NFQVJDSCkgRklYTUUoIiBBQ09fU0VBUkNIIG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgaWYgKFRoaXMtPm9wdGlvbnMgJiBBQ09fRklMVEVSUFJFRklYRVMpIEZJWE1FKCIgQUNPX0ZJTFRFUlBSRUZJWEVTIG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgaWYgKFRoaXMtPm9wdGlvbnMgJiBBQ09fVVNFVEFCKSBGSVhNRSgiIEFDT19VU0VUQUIgbm90IHN1cHBvcnRlZFxuIik7CiAgICBpZiAoVGhpcy0+b3B0aW9ucyAmIEFDT19VUERPV05LRVlEUk9QU0xJU1QpIFRSQUNFKCIgQUNPX1VQRE9XTktFWURST1BTTElTVFxuIik7CiAgICBpZiAoVGhpcy0+b3B0aW9ucyAmIEFDT19SVExSRUFESU5HKSBGSVhNRSgiIEFDT19SVExSRUFESU5HIG5vdCBzdXBwb3J0ZWRcbiIpOwoKICAgIFRoaXMtPmh3bmRFZGl0ID0gaHduZEVkaXQ7CgogICAgaWYgKCFTVUNDRUVERUQgKElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlIChwdW5rQUNMLCAmSUlEX0lFbnVtU3RyaW5nLCAoTFBWT0lEKikmVGhpcy0+ZW51bXN0cikpKSB7CglUUkFDRSgiTm8gSUVudW1TdHJpbmcgaW50ZXJmYWNlXG4iKTsKCXJldHVybiAgRV9OT0lOVEVSRkFDRTsKICAgIH0KCiAgICBUaGlzLT53cE9yaWdFZGl0UHJvYyA9IChXTkRQUk9DKSBTZXRXaW5kb3dMb25nUHRyVyggaHduZEVkaXQsIEdXTFBfV05EUFJPQywgKExPTkdfUFRSKSBBQ0VkaXRTdWJjbGFzc1Byb2MpOwogICAgU2V0V2luZG93TG9uZ1B0clcoIGh3bmRFZGl0LCBHV0xQX1VTRVJEQVRBLCAoTE9OR19QVFIpVGhpcyk7CgogICAgaWYgKFRoaXMtPm9wdGlvbnMgJiBBQ09fQVVUT1NVR0dFU1QpIHsKCUhXTkQgaHduZFBhcmVudDsKCglod25kUGFyZW50ID0gR2V0UGFyZW50KFRoaXMtPmh3bmRFZGl0KTsKCQoJLyogRklYTUUgOiBUaGUgbGlzdGJveCBzaG91bGQgYmUgcmVzaXphYmxlIHdpdGggdGhlIG1vdXNlLiBXU19USElDS0ZSQU1FIGxvb2tzIHVnbHkgKi8KCVRoaXMtPmh3bmRMaXN0Qm94ID0gQ3JlYXRlV2luZG93RXhXKDAsIGxiTmFtZSwgTlVMTCwgCgkJCQkJICAgIFdTX0JPUkRFUiB8IFdTX0NISUxEIHwgV1NfVlNDUk9MTCB8IExCU19IQVNTVFJJTkdTIHwgTEJTX05PVElGWSB8IExCU19OT0lOVEVHUkFMSEVJR0hULCAKCQkJCQkgICAgQ1dfVVNFREVGQVVMVCwgQ1dfVVNFREVGQVVMVCwgQ1dfVVNFREVGQVVMVCwgQ1dfVVNFREVGQVVMVCwKCQkJCQkgICAgaHduZFBhcmVudCwgTlVMTCwgCgkJCQkJICAgIChISU5TVEFOQ0UpR2V0V2luZG93TG9uZ1B0clcoIGh3bmRQYXJlbnQsIEdXTFBfSElOU1RBTkNFICksIE5VTEwpOwoJCQkJCSAgICAKCWlmIChUaGlzLT5od25kTGlzdEJveCkgewoJICAgIFRoaXMtPndwT3JpZ0xCb3hQcm9jID0gKFdORFBST0MpIFNldFdpbmRvd0xvbmdQdHJXKCBUaGlzLT5od25kTGlzdEJveCwgR1dMUF9XTkRQUk9DLCAoTE9OR19QVFIpIEFDTEJveFN1YmNsYXNzUHJvYyk7CgkgICAgU2V0V2luZG93TG9uZ1B0clcoIFRoaXMtPmh3bmRMaXN0Qm94LCBHV0xQX1VTRVJEQVRBLCAoTE9OR19QVFIpVGhpcyk7Cgl9CiAgICB9CgogICAgaWYgKHB3enNSZWdLZXlQYXRoKSB7CglXQ0hBUiAqa2V5OwoJV0NIQVIgcmVzdWx0W01BWF9QQVRIXTsKCVdDSEFSICp2YWx1ZTsKCUhLRVkgaEtleSA9IDA7CglMT05HIHJlczsKCUxPTkcgbGVuOwoKCS8qIHB3c3pSZWdLZXlQYXRoIGNvbnRhaW5zIHRoZSBrZXkgYXMgd2VsbCBhcyB0aGUgdmFsdWUsIHNvIHdlIHNwbGl0ICovCglrZXkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgKGxzdHJsZW5XKHB3enNSZWdLZXlQYXRoKSsxKSpzaXplb2YoV0NIQVIpKTsKCXN0cmNweVcoa2V5LCBwd3pzUmVnS2V5UGF0aCk7Cgl2YWx1ZSA9IHN0cnJjaHJXKGtleSwgJ1xcJyk7CgkqdmFsdWUgPSAwOwoJdmFsdWUrKzsKCS8qIE5vdyB2YWx1ZSBjb250YWlucyB0aGUgdmFsdWUgYW5kIGJ1ZmZlciB0aGUga2V5ICovCglyZXMgPSBSZWdPcGVuS2V5RXhXKEhLRVlfQ1VSUkVOVF9VU0VSLCBrZXksIDAsIEtFWV9SRUFELCAmaEtleSk7CglpZiAocmVzICE9IEVSUk9SX1NVQ0NFU1MpIHsKCSAgICAvKiBpZiB0aGUga2V5IGlzIG5vdCBmb3VuZCwgTVNETiBzdGF0ZXMgd2UgbXVzdCBzZWVrIGluIEhLRVlfTE9DQUxfTUFDSElORSAqLwoJICAgIHJlcyA9IFJlZ09wZW5LZXlFeFcoSEtFWV9MT0NBTF9NQUNISU5FLCBrZXksIDAsIEtFWV9SRUFELCAmaEtleSk7ICAKCX0KCWlmIChyZXMgPT0gRVJST1JfU1VDQ0VTUykgewoJICAgIHJlcyA9IFJlZ1F1ZXJ5VmFsdWVXKGhLZXksIHZhbHVlLCByZXN1bHQsICZsZW4pOwoJICAgIGlmIChyZXMgPT0gRVJST1JfU1VDQ0VTUykgewoJCVRoaXMtPnF1aWNrQ29tcGxldGUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgbGVuKnNpemVvZihXQ0hBUikpOwoJCXN0cmNweVcoVGhpcy0+cXVpY2tDb21wbGV0ZSwgcmVzdWx0KTsKCSAgICB9CgkgICAgUmVnQ2xvc2VLZXkoaEtleSk7Cgl9CglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBrZXkpOwogICAgfQoKICAgIGlmICgocHdzelF1aWNrQ29tcGxldGUpICYmICghVGhpcy0+cXVpY2tDb21wbGV0ZSkpIHsKCVRoaXMtPnF1aWNrQ29tcGxldGUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgKGxzdHJsZW5XKHB3c3pRdWlja0NvbXBsZXRlKSsxKSpzaXplb2YoV0NIQVIpKTsKCWxzdHJjcHlXKFRoaXMtPnF1aWNrQ29tcGxldGUsIHB3c3pRdWlja0NvbXBsZXRlKTsKICAgIH0KCiAgICByZXR1cm4gU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBJQXV0b0NvbXBsZXRlX2ZuVlRhYmxlCiAqLwpzdGF0aWMgY29uc3QgSUF1dG9Db21wbGV0ZVZ0YmwgYWN2dCA9CnsKICAgIElBdXRvQ29tcGxldGVfZm5RdWVyeUludGVyZmFjZSwKICAgIElBdXRvQ29tcGxldGVfZm5BZGRSZWYsCiAgICBJQXV0b0NvbXBsZXRlX2ZuUmVsZWFzZSwKICAgIElBdXRvQ29tcGxldGVfZm5Jbml0LAogICAgSUF1dG9Db21wbGV0ZV9mbkVuYWJsZSwKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgQXV0b0NvbXBsZXRlMl9RdWVyeUludGVyZmFjZQogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBdXRvQ29tcGxldGUyX2ZuUXVlcnlJbnRlcmZhY2UoCiAgICBJQXV0b0NvbXBsZXRlMiAqIGlmYWNlLAogICAgUkVGSUlEIHJpaWQsCiAgICBMUFZPSUQgKnBwdk9iaikKewogICAgSUF1dG9Db21wbGV0ZUltcGwgKlRoaXMgPSBpbXBsX2Zyb21fSUF1dG9Db21wbGV0ZTIoaWZhY2UpOwoKICAgIFRSQUNFICgiKCVwKS0+KCVzLCVwKVxuIiwgVGhpcywgc2hkZWJ1Z3N0cl9ndWlkIChyaWlkKSwgcHB2T2JqKTsKCiAgICByZXR1cm4gSUF1dG9Db21wbGV0ZV9RdWVyeUludGVyZmFjZSgoSUF1dG9Db21wbGV0ZSopVGhpcywgcmlpZCwgcHB2T2JqKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJQXV0b0NvbXBsZXRlMl9mbkFkZFJlZgogKi8Kc3RhdGljIFVMT05HIFdJTkFQSSBJQXV0b0NvbXBsZXRlMl9mbkFkZFJlZigKCUlBdXRvQ29tcGxldGUyICogaWZhY2UpCnsKICAgIElBdXRvQ29tcGxldGVJbXBsICpUaGlzID0gaW1wbF9mcm9tX0lBdXRvQ29tcGxldGUyKGlmYWNlKTsKCiAgICBUUkFDRSAoIiglcCktPihjb3VudD0lbHUpXG4iLCBUaGlzLCBUaGlzLT5yZWYpOwoKICAgIHJldHVybiBJQXV0b0NvbXBsZXRlMl9BZGRSZWYoKElBdXRvQ29tcGxldGUqKVRoaXMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElBdXRvQ29tcGxldGUyX2ZuUmVsZWFzZQogKi8Kc3RhdGljIFVMT05HIFdJTkFQSSBJQXV0b0NvbXBsZXRlMl9mblJlbGVhc2UoCglJQXV0b0NvbXBsZXRlMiAqIGlmYWNlKQp7CiAgICBJQXV0b0NvbXBsZXRlSW1wbCAqVGhpcyA9IGltcGxfZnJvbV9JQXV0b0NvbXBsZXRlMihpZmFjZSk7CgogICAgVFJBQ0UgKCIoJXApLT4oY291bnQ9JWx1KVxuIiwgVGhpcywgVGhpcy0+cmVmKTsKCiAgICByZXR1cm4gSUF1dG9Db21wbGV0ZV9SZWxlYXNlKChJQXV0b0NvbXBsZXRlKilUaGlzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJQXV0b0NvbXBsZXRlMl9mbkVuYWJsZQogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBdXRvQ29tcGxldGUyX2ZuRW5hYmxlKAogICAgSUF1dG9Db21wbGV0ZTIgKiBpZmFjZSwKICAgIEJPT0wgZkVuYWJsZSkKewogICAgSUF1dG9Db21wbGV0ZUltcGwgKlRoaXMgPSBpbXBsX2Zyb21fSUF1dG9Db21wbGV0ZTIoaWZhY2UpOwoKICAgIFRSQUNFICgiKCVwKS0+KCVzKVxuIiwgVGhpcywgKGZFbmFibGUpPyJ0cnVlIjoiZmFsc2UiKTsKCiAgICByZXR1cm4gSUF1dG9Db21wbGV0ZV9FbmFibGUoKElBdXRvQ29tcGxldGUqKVRoaXMsIGZFbmFibGUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElBdXRvQ29tcGxldGUyX2ZuSW5pdAogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBdXRvQ29tcGxldGUyX2ZuSW5pdCgKICAgIElBdXRvQ29tcGxldGUyICogaWZhY2UsCiAgICBIV05EIGh3bmRFZGl0LAogICAgSVVua25vd24gKnB1bmtBQ0wsCiAgICBMUENPTEVTVFIgcHd6c1JlZ0tleVBhdGgsCiAgICBMUENPTEVTVFIgcHdzelF1aWNrQ29tcGxldGUpCnsKICAgIElBdXRvQ29tcGxldGVJbXBsICpUaGlzID0gaW1wbF9mcm9tX0lBdXRvQ29tcGxldGUyKGlmYWNlKTsKCiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgcmV0dXJuIElBdXRvQ29tcGxldGVfSW5pdCgoSUF1dG9Db21wbGV0ZSopVGhpcywgaHduZEVkaXQsIHB1bmtBQ0wsIHB3enNSZWdLZXlQYXRoLCBwd3N6UXVpY2tDb21wbGV0ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgSUF1dG9Db21wbGV0ZV9mbkdldE9wdGlvbnMKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQXV0b0NvbXBsZXRlMl9mbkdldE9wdGlvbnMoCiAgICBJQXV0b0NvbXBsZXRlMiAqIGlmYWNlLAogICAgRFdPUkQgKnBkd0ZsYWcpCnsKICAgIEhSRVNVTFQgaHIgPSBTX09LOwoKICAgIElBdXRvQ29tcGxldGVJbXBsICpUaGlzID0gaW1wbF9mcm9tX0lBdXRvQ29tcGxldGUyKGlmYWNlKTsKCiAgICBUUkFDRSgiKCVwKSAtPiAoJXApXG4iLCBUaGlzLCBwZHdGbGFnKTsKCiAgICAqcGR3RmxhZyA9IFRoaXMtPm9wdGlvbnM7CgogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIElBdXRvQ29tcGxldGVfZm5TZXRPcHRpb25zCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUF1dG9Db21wbGV0ZTJfZm5TZXRPcHRpb25zKAogICAgSUF1dG9Db21wbGV0ZTIgKiBpZmFjZSwKICAgIERXT1JEIGR3RmxhZykKewogICAgSFJFU1VMVCBociA9IFNfT0s7CgogICAgSUF1dG9Db21wbGV0ZUltcGwgKlRoaXMgPSBpbXBsX2Zyb21fSUF1dG9Db21wbGV0ZTIoaWZhY2UpOwoKICAgIFRSQUNFKCIoJXApIC0+ICgweCVseClcbiIsIFRoaXMsIGR3RmxhZyk7CgogICAgVGhpcy0+b3B0aW9ucyA9IGR3RmxhZzsKCiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgSUF1dG9Db21wbGV0ZTJfZm5WVGFibGUKICovCnN0YXRpYyBjb25zdCBJQXV0b0NvbXBsZXRlMlZ0YmwgYWMydnQgPQp7CiAgICBJQXV0b0NvbXBsZXRlMl9mblF1ZXJ5SW50ZXJmYWNlLAogICAgSUF1dG9Db21wbGV0ZTJfZm5BZGRSZWYsCiAgICBJQXV0b0NvbXBsZXRlMl9mblJlbGVhc2UsCiAgICBJQXV0b0NvbXBsZXRlMl9mbkluaXQsCiAgICBJQXV0b0NvbXBsZXRlMl9mbkVuYWJsZSwKICAgIC8qIElBdXRvQ29tcGxldGUyICovCiAgICBJQXV0b0NvbXBsZXRlMl9mblNldE9wdGlvbnMsCiAgICBJQXV0b0NvbXBsZXRlMl9mbkdldE9wdGlvbnMsCn07CgovKgogIFdpbmRvdyBwcm9jZWR1cmUgZm9yIGF1dG9jb21wbGV0aW9uCiAqLwpzdGF0aWMgTFJFU1VMVCBBUElFTlRSWSBBQ0VkaXRTdWJjbGFzc1Byb2MoSFdORCBod25kLCBVSU5UIHVNc2csIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0pCnsKICAgIElBdXRvQ29tcGxldGVJbXBsICpUaGlzID0gKElBdXRvQ29tcGxldGVJbXBsICopR2V0V2luZG93TG9uZ1B0clcoaHduZCwgR1dMUF9VU0VSREFUQSk7CiAgICBMUE9MRVNUUiBzdHJzOwogICAgSFJFU1VMVCBocjsKICAgIFdDSEFSIGh3bmRUZXh0WzI1NV07CiAgICBXQ0hBUiAqaHduZFFDVGV4dDsKICAgIFJFQ1QgcjsKICAgIEJPT0wgY29udHJvbCwgZmlsbGVkLCBkaXNwbGF5YWxsID0gRkFMU0U7CiAgICBpbnQgY3B0LCBoZWlnaHQsIHNlbDsKCiAgICBpZiAoIVRoaXMtPmVuYWJsZWQpIHJldHVybiBDYWxsV2luZG93UHJvY1coVGhpcy0+d3BPcmlnRWRpdFByb2MsIGh3bmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKCiAgICBzd2l0Y2ggKHVNc2cpCiAgICB7CgljYXNlIENCX1NIT1dEUk9QRE9XTjoKCSAgICBTaG93V2luZG93KFRoaXMtPmh3bmRMaXN0Qm94LCBTV19ISURFKTsKCSAgICBicmVhazsKCWNhc2UgV01fS0lMTEZPQ1VTOgoJICAgIGlmICgoVGhpcy0+b3B0aW9ucyAmJiBBQ09fQVVUT1NVR0dFU1QpICYmIAoJCSgoSFdORCl3UGFyYW0gIT0gVGhpcy0+aHduZExpc3RCb3gpKQoJICAgIHsKCQlTaG93V2luZG93KFRoaXMtPmh3bmRMaXN0Qm94LCBTV19ISURFKTsKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFdNX0tFWVVQOgoJICAgIAoJICAgIEdldFdpbmRvd1RleHRXKCBod25kLCAoTFBXU1RSKWh3bmRUZXh0LCAyNTUpOwogICAgICAKCSAgICBzd2l0Y2god1BhcmFtKSB7CgkJY2FzZSBWS19SRVRVUk46CgkJICAgIC8qIElmIHF1aWNrQ29tcGxldGUgaXMgc2V0IGFuZCBjb250cm9sIGlzIHByZXNzZWQsIHJlcGxhY2UgdGhlIHN0cmluZyAqLwoJCSAgICBjb250cm9sID0gR2V0S2V5U3RhdGUoVktfQ09OVFJPTCkgJiAweDgwMDA7CQkgICAgCgkJICAgIGlmIChjb250cm9sICYmIFRoaXMtPnF1aWNrQ29tcGxldGUpIHsKCQkJaHduZFFDVGV4dCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCAKCQkJCQkJICAgICAgIChsc3RybGVuVyhUaGlzLT5xdWlja0NvbXBsZXRlKStsc3RybGVuVyhod25kVGV4dCkpKnNpemVvZihXQ0hBUikpOwoJCQlzZWwgPSBzcHJpbnRmVyhod25kUUNUZXh0LCBUaGlzLT5xdWlja0NvbXBsZXRlLCBod25kVGV4dCk7CgkJCVNlbmRNZXNzYWdlVyhod25kLCBXTV9TRVRURVhULCAwLCAoTFBBUkFNKWh3bmRRQ1RleHQpOwoJCQlTZW5kTWVzc2FnZVcoaHduZCwgRU1fU0VUU0VMLCAwLCBzZWwpOwoJCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBod25kUUNUZXh0KTsKCQkgICAgfQoKCQkgICAgU2hvd1dpbmRvdyhUaGlzLT5od25kTGlzdEJveCwgU1dfSElERSk7CgkJICAgIHJldHVybiAwOwoJCWNhc2UgVktfTEVGVDoKCQljYXNlIFZLX1JJR0hUOgoJCSAgICByZXR1cm4gMDsKCQljYXNlIFZLX1VQOgkgICAgICAKCQljYXNlIFZLX0RPV046CgkJICAgIC8qIFR3byBjYXNlcyBoZXJlIDogCgkJICAgICAgIC0gaWYgdGhlIGxpc3Rib3ggaXMgbm90IHZpc2libGUsIGRpc3BsYXlzIGl0IAoJCSAgICAgICB3aXRoIGFsbCB0aGUgZW50cmllcyBpZiB0aGUgc3R5bGUgQUNPX1VQRE9XTktFWURST1BTTElTVAoJCSAgICAgICBpcyBwcmVzZW50IGJ1dCBkb2VzIG5vdCBzZWxlY3QgYW55dGhpbmcuCgkJICAgICAgIC0gaWYgdGhlIGxpc3Rib3ggaXMgdmlzaWJsZSwgY2hhbmdlIHRoZSBzZWxlY3Rpb24KCQkgICAgKi8KCQkgICAgaWYgKCAoVGhpcy0+b3B0aW9ucyAmIChBQ09fQVVUT1NVR0dFU1QgfCBBQ09fVVBET1dOS0VZRFJPUFNMSVNUKSkgCgkJCSAmJiAoIUlzV2luZG93VmlzaWJsZShUaGlzLT5od25kTGlzdEJveCkgJiYgKCEgKmh3bmRUZXh0KSkgKQoJCSAgICB7CgkJCSAvKiBXZSBtdXN0IGRpc3BheXMgYWxsIHRoZSBlbnRyaWVzICovCgkJCSBkaXNwbGF5YWxsID0gVFJVRTsKCQkgICAgfSBlbHNlIHsKCQkJaWYgKElzV2luZG93VmlzaWJsZShUaGlzLT5od25kTGlzdEJveCkpIHsKCQkJICAgIGludCBjb3VudDsKCgkJCSAgICBjb3VudCA9IFNlbmRNZXNzYWdlVyhUaGlzLT5od25kTGlzdEJveCwgTEJfR0VUQ09VTlQsIDAsIDApOwoJCQkgICAgLyogQ2hhbmdlIHRoZSBzZWxlY3Rpb24gKi8KCQkJICAgIHNlbCA9IFNlbmRNZXNzYWdlVyhUaGlzLT5od25kTGlzdEJveCwgTEJfR0VUQ1VSU0VMLCAwLCAwKTsKCQkJICAgIGlmICh3UGFyYW0gPT0gVktfVVApCgkJCQlzZWwgPSAoKHNlbC0xKTwwKT9jb3VudC0xOnNlbC0xOwoJCQkgICAgZWxzZQoJCQkJc2VsID0gKChzZWwrMSk+PSBjb3VudCk/LTE6c2VsKzE7CgkJCSAgICBTZW5kTWVzc2FnZVcoVGhpcy0+aHduZExpc3RCb3gsIExCX1NFVENVUlNFTCwgc2VsLCAwKTsKCQkJICAgIGlmIChzZWwgIT0gLTEpIHsKCQkJCVdDSEFSICptc2c7CgkJCQlpbnQgbGVuOwoJCQkJCgkJCQlsZW4gPSBTZW5kTWVzc2FnZVcoVGhpcy0+aHduZExpc3RCb3gsIExCX0dFVFRFWFRMRU4sIHNlbCwgKExQQVJBTSlOVUxMKTsKCQkJCW1zZyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCAobGVuKzEpKnNpemVvZihXQ0hBUikpOwoJCQkJU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRMaXN0Qm94LCBMQl9HRVRURVhULCBzZWwsIChMUEFSQU0pbXNnKTsKCQkJCVNlbmRNZXNzYWdlVyhod25kLCBXTV9TRVRURVhULCAwLCAoTFBBUkFNKW1zZyk7CgkJCQlTZW5kTWVzc2FnZVcoaHduZCwgRU1fU0VUU0VMLCBsc3RybGVuVyhtc2cpLCBsc3RybGVuVyhtc2cpKTsKCQkJCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1zZyk7CgkJCSAgICB9IGVsc2UgewoJCQkJU2VuZE1lc3NhZ2VXKGh3bmQsIFdNX1NFVFRFWFQsIDAsIChMUEFSQU0pVGhpcy0+dHh0YmFja3VwKTsKCQkJCVNlbmRNZXNzYWdlVyhod25kLCBFTV9TRVRTRUwsIGxzdHJsZW5XKFRoaXMtPnR4dGJhY2t1cCksIGxzdHJsZW5XKFRoaXMtPnR4dGJhY2t1cCkpOwoJCQkgICAgfQkJCQoJCQl9IAkJCgkJCXJldHVybiAwOwoJCSAgICB9CgkJICAgIGJyZWFrOwoJCWNhc2UgVktfQkFDSzoKCQljYXNlIFZLX0RFTEVURToKCQkgICAgaWYgKCghICpod25kVGV4dCkgJiYgKFRoaXMtPm9wdGlvbnMgJiBBQ09fQVVUT1NVR0dFU1QpKSB7CgkJCVNob3dXaW5kb3coVGhpcy0+aHduZExpc3RCb3gsIFNXX0hJREUpOwoJCQlyZXR1cm4gQ2FsbFdpbmRvd1Byb2NXKFRoaXMtPndwT3JpZ0VkaXRQcm9jLCBod25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7CgkJICAgIH0KCQkgICAgaWYgKFRoaXMtPm9wdGlvbnMgJiBBQ09fQVVUT0FQUEVORCkgewoJCQlEV09SRCBiOwoJCQlTZW5kTWVzc2FnZVcoaHduZCwgRU1fR0VUU0VMLCAoV1BBUkFNKSZiLCAoTFBBUkFNKU5VTEwpOwoJCQlpZiAoYj4xKSB7CgkJCSAgICBod25kVGV4dFtiLTFdID0gJ1wwJzsKCQkJfSBlbHNlIHsKCQkJICAgIGh3bmRUZXh0WzBdID0gJ1wwJzsKCQkJICAgIFNldFdpbmRvd1RleHRXKGh3bmQsIGh3bmRUZXh0KTsgCgkJCX0JCQkKCQkgICAgfQoJCSAgICBicmVhazsKCQlkZWZhdWx0OgkJICAgIAoJCSAgICA7CgkgICAgfQogICAgICAKCSAgICBTZW5kTWVzc2FnZVcoVGhpcy0+aHduZExpc3RCb3gsIExCX1JFU0VUQ09OVEVOVCwgMCwgMCk7CgoJICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnR4dGJhY2t1cCk7CgkgICAgVGhpcy0+dHh0YmFja3VwID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksCgkJCQkJCSBIRUFQX1pFUk9fTUVNT1JZLCAobHN0cmxlblcoaHduZFRleHQpKzEpKnNpemVvZihXQ0hBUikpOwkJCQkJCQkgICAgICAKCSAgICBsc3RyY3B5VyhUaGlzLT50eHRiYWNrdXAsIGh3bmRUZXh0KTsKCgkgICAgLyogUmV0dXJucyBpZiB0aGVyZSBpcyBubyB0ZXh0IHRvIHNlYXJjaCBhbmQgd2UgZG9lc24ndCB3YW50IHRvIGRpc3BsYXkgYWxsIHRoZSBlbnRyaWVzICovCgkgICAgaWYgKCghZGlzcGxheWFsbCkgJiYgKCEgKmh3bmRUZXh0KSApCgkJYnJlYWs7CgkgICAgCgkgICAgSUVudW1TdHJpbmdfUmVzZXQoVGhpcy0+ZW51bXN0cik7CgkgICAgZmlsbGVkID0gRkFMU0U7CgkgICAgZm9yKGNwdCA9IDA7OykgewoJCWhyID0gSUVudW1TdHJpbmdfTmV4dChUaGlzLT5lbnVtc3RyLCAxLCAmc3RycywgTlVMTCk7CgkJaWYgKGhyICE9IFNfT0spCgkJICAgIGJyZWFrOwoKCQlpZiAoKExQV1NUUilzdHJzdHJXKHN0cnMsIGh3bmRUZXh0KSA9PSBzdHJzKSB7CgkJICAgIAoJCSAgICBpZiAoVGhpcy0+b3B0aW9ucyAmIEFDT19BVVRPQVBQRU5EKSB7CgkJCVNldFdpbmRvd1RleHRXKGh3bmQsIHN0cnMpOwoJCQlTZW5kTWVzc2FnZVcoaHduZCwgRU1fU0VUU0VMLCBsc3RybGVuVyhod25kVGV4dCksIGxzdHJsZW5XKHN0cnMpKTsKCQkJYnJlYWs7CgkJICAgIH0JCQoKCQkgICAgaWYgKFRoaXMtPm9wdGlvbnMgJiBBQ09fQVVUT1NVR0dFU1QpIHsKCQkJU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRMaXN0Qm94LCBMQl9BRERTVFJJTkcsIDAsIChMUEFSQU0pc3Rycyk7CgkJCWZpbGxlZCA9IFRSVUU7CgkJCWNwdCsrOwoJCSAgICB9CgkJfQkJCgkgICAgfQoJICAgIAoJICAgIGlmIChUaGlzLT5vcHRpb25zICYgQUNPX0FVVE9TVUdHRVNUKSB7CgkJaWYgKGZpbGxlZCkgewoJCSAgICBoZWlnaHQgPSBTZW5kTWVzc2FnZVcoVGhpcy0+aHduZExpc3RCb3gsIExCX0dFVElURU1IRUlHSFQsIDAsIDApOwoJCSAgICBTZW5kTWVzc2FnZVcoVGhpcy0+aHduZExpc3RCb3gsIExCX0NBUkVUT0ZGLCAwLCAwKTsKCQkgICAgR2V0V2luZG93UmVjdChod25kLCAmcik7CgkJICAgIFNldFBhcmVudChUaGlzLT5od25kTGlzdEJveCwgSFdORF9ERVNLVE9QKTsKCQkgICAgLyogSXQgc2VlbXMgdGhhdCBXaW5kb3dzIFhQIGRpc3BsYXlzIDcgbGluZXMgYXQgbW9zdCAKCQkgICAgICAgYW5kIG90aGVyd2lzZSBkaXNwbGF5cyBhIHZlcnRpY2FsIHNjcm9sbCBiYXIgKi8KCQkgICAgU2V0V2luZG93UG9zKFRoaXMtPmh3bmRMaXN0Qm94LCBIV05EX1RPUCwgCgkJCQkgci5sZWZ0LCByLmJvdHRvbSArIDEsIHIucmlnaHQgLSByLmxlZnQsIG1pbihoZWlnaHQgKiA3LCBoZWlnaHQqKGNwdCsxKSksIAoJCQkJIFNXUF9TSE9XV0lORE9XICk7CgkJfSBlbHNlIHsKCQkgICAgU2hvd1dpbmRvdyhUaGlzLT5od25kTGlzdEJveCwgU1dfSElERSk7CgkJfQoJICAgIH0KCSAgICAKCSAgICBicmVhazsgCglkZWZhdWx0OgoJICAgIHJldHVybiBDYWxsV2luZG93UHJvY1coVGhpcy0+d3BPcmlnRWRpdFByb2MsIGh3bmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKCSAgICAKICAgIH0KCiAgICByZXR1cm4gMDsKfQoKc3RhdGljIExSRVNVTFQgQVBJRU5UUlkgQUNMQm94U3ViY2xhc3NQcm9jKEhXTkQgaHduZCwgVUlOVCB1TXNnLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBJQXV0b0NvbXBsZXRlSW1wbCAqVGhpcyA9IChJQXV0b0NvbXBsZXRlSW1wbCAqKUdldFdpbmRvd0xvbmdQdHJXKGh3bmQsIEdXTFBfVVNFUkRBVEEpOwogICAgV0NIQVIgKm1zZzsKICAgIGludCBzZWwgPSAtMSwgbGVuOwoKICAgIHN3aXRjaCAodU1zZykgewoJY2FzZSBXTV9NT1VTRU1PVkU6CgkgICAgc2VsID0gU2VuZE1lc3NhZ2VXKGh3bmQsIExCX0lURU1GUk9NUE9JTlQsIDAsIGxQYXJhbSk7CgkgICAgU2VuZE1lc3NhZ2VXKGh3bmQsIExCX1NFVENVUlNFTCwgKFdQQVJBTSlzZWwsIChMUEFSQU0pMCk7CgkgICAgYnJlYWs7CgljYXNlIFdNX0xCVVRUT05ET1dOOgoJICAgIGxlbiA9IFNlbmRNZXNzYWdlVyhUaGlzLT5od25kTGlzdEJveCwgTEJfR0VUVEVYVExFTiwgc2VsLCAoTFBBUkFNKU5VTEwpOwoJICAgIG1zZyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCAobGVuKzEpKnNpemVvZihXQ0hBUikpOwoJICAgIHNlbCA9IChJTlQpU2VuZE1lc3NhZ2VXKGh3bmQsIExCX0dFVENVUlNFTCwgMCwgMCk7CgkgICAgU2VuZE1lc3NhZ2VXKGh3bmQsIExCX0dFVFRFWFQsIHNlbCwgKExQQVJBTSltc2cpOwoJICAgIFNlbmRNZXNzYWdlVyhUaGlzLT5od25kRWRpdCwgV01fU0VUVEVYVCwgMCwgKExQQVJBTSltc2cpOwoJICAgIFNlbmRNZXNzYWdlVyhUaGlzLT5od25kRWRpdCwgRU1fU0VUU0VMLCAwLCBsc3RybGVuVyhtc2cpKTsKCSAgICBTaG93V2luZG93KGh3bmQsIFNXX0hJREUpOwoJICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG1zZyk7CgkgICAgYnJlYWs7CglkZWZhdWx0OgoJICAgIHJldHVybiBDYWxsV2luZG93UHJvY1coVGhpcy0+d3BPcmlnTEJveFByb2MsIGh3bmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKICAgIH0KICAgIHJldHVybiAwOwp9Cg==