LyoKICoJQXV0b0NvbXBsZXRlIGludGVyZmFjZXMgaW1wbGVtZW50YXRpb24uCiAqCiAqCUNvcHlyaWdodCAyMDA0CU1heGltZSBCZWxsZW5n6SA8bWF4aW1lLmJlbGxlbmdlQGxhcG9zdGUubmV0PgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgovKgogIEltcGxlbWVudGVkOgogIC0gQUNPX0FVVE9BUFBFTkQgc3R5bGUKICAtIEFDT19BVVRPU1VHR0VTVCBzdHlsZQogIC0gQUNPX1VQRE9XTktFWURST1BTTElTVCBzdHlsZQoKICAtIEhhbmRsZSBwd3pzUmVnS2V5UGF0aCBhbmQgcHdzelF1aWNrQ29tcGxldGUgaW4gSW5pdAoKICBUT0RPOgogIC0gaW1wbGVtZW50IEFDT19TRUFSQ0ggc3R5bGUKICAtIGltcGxlbWVudCBBQ09fRklMVEVSUFJFRklYRVMgc3R5bGUKICAtIGltcGxlbWVudCBBQ09fVVNFVEFCIHN0eWxlCiAgLSBpbXBsZW1lbnQgQUNPX1JUTFJFQURJTkcgc3R5bGUKICAKICovCiNpbmNsdWRlICJjb25maWcuaCIKCiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CgojZGVmaW5lIENPQkpNQUNST1MKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAidW5kb2NzaGVsbC5oIgojaW5jbHVkZSAic2hsd2FwaS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm9iamJhc2UuaCIKCiNpbmNsdWRlICJwaWRsLmgiCiNpbmNsdWRlICJzaGxndWlkLmgiCiNpbmNsdWRlICJzaGxvYmouaCIKI2luY2x1ZGUgInNobGRpc3AuaCIKI2luY2x1ZGUgImRlYnVnaGxwLmgiCgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChzaGVsbCk7Cgp0eXBlZGVmIHN0cnVjdAp7CiAgICBJQXV0b0NvbXBsZXRlVnRibCAgKmxwVnRibDsKICAgIElBdXRvQ29tcGxldGUyVnRibCAqbHB2dGJsQXV0b0NvbXBsZXRlMjsKICAgIERXT1JEIHJlZjsKICAgIEJPT0wgIGVuYWJsZWQ7CiAgICBIV05EIGh3bmRFZGl0OwogICAgSFdORCBod25kTGlzdEJveDsKICAgIFdORFBST0Mgd3BPcmlnRWRpdFByb2M7CiAgICBXTkRQUk9DIHdwT3JpZ0xCb3hQcm9jOwogICAgV0NIQVIgKnR4dGJhY2t1cDsKICAgIFdDSEFSICpxdWlja0NvbXBsZXRlOwogICAgSUVudW1TdHJpbmcgKmVudW1zdHI7CiAgICBBVVRPQ09NUExFVEVPUFRJT05TIG9wdGlvbnM7Cn0gSUF1dG9Db21wbGV0ZUltcGw7CgpzdGF0aWMgc3RydWN0IElBdXRvQ29tcGxldGVWdGJsIGFjdnQ7CnN0YXRpYyBzdHJ1Y3QgSUF1dG9Db21wbGV0ZTJWdGJsIGFjMnZ0OwoKI2RlZmluZSBfSUF1dG9Db21wbGV0ZTJfT2Zmc2V0ICgoaW50KSgmKCgoSUF1dG9Db21wbGV0ZUltcGwqKTApLT5scHZ0YmxBdXRvQ29tcGxldGUyKSkpCiNkZWZpbmUgX0lDT01fVEhJU19Gcm9tX0lBdXRvQ29tcGxldGUyKGNsYXNzLCBuYW1lKSBjbGFzcyogVGhpcyA9IChjbGFzcyopKCgoY2hhciopbmFtZSktX0lBdXRvQ29tcGxldGUyX09mZnNldCk7CgovKgogIGNvbnZlcnRzIFRoaXMgdG8gYSBpbnRlcmZhY2UgcG9pbnRlcgoqLwojZGVmaW5lIF9JVW5rbm93bl8oVGhpcykgKElVbmtub3duKikmKFRoaXMtPmxwVnRibCkKI2RlZmluZSBfSUF1dG9Db21wbGV0ZTJfKFRoaXMpICAoSUF1dG9Db21wbGV0ZTIqKSYoVGhpcy0+bHB2dGJsQXV0b0NvbXBsZXRlMikgCgpzdGF0aWMgTFJFU1VMVCBBUElFTlRSWSBBQ0VkaXRTdWJjbGFzc1Byb2MoSFdORCBod25kLCBVSU5UIHVNc2csIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0pOwpzdGF0aWMgTFJFU1VMVCBBUElFTlRSWSBBQ0xCb3hTdWJjbGFzc1Byb2MoSFdORCBod25kLCBVSU5UIHVNc2csIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0pOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBJQXV0b0NvbXBsZXRlX0NvbnN0cnVjdG9yCiAqLwpIUkVTVUxUIFdJTkFQSSBJQXV0b0NvbXBsZXRlX0NvbnN0cnVjdG9yKElVbmtub3duICogcFVua091dGVyLCBSRUZJSUQgcmlpZCwgTFBWT0lEICogcHB2KQp7CiAgICBJQXV0b0NvbXBsZXRlSW1wbCAqbHBhYzsKCiAgICBpZiAocFVua091dGVyICYmICFJc0VxdWFsSUlEIChyaWlkLCAmSUlEX0lVbmtub3duKSkKCXJldHVybiBDTEFTU19FX05PQUdHUkVHQVRJT047CgogICAgbHBhYyA9IChJQXV0b0NvbXBsZXRlSW1wbCopSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksCiAgICAgIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJQXV0b0NvbXBsZXRlSW1wbCkpOwogICAgaWYgKCFscGFjKSAKCXJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIGxwYWMtPnJlZiA9IDE7CiAgICBscGFjLT5scFZ0YmwgPSAmYWN2dDsKICAgIGxwYWMtPmxwdnRibEF1dG9Db21wbGV0ZTIgPSAmYWMydnQ7CiAgICBscGFjLT5lbmFibGVkID0gVFJVRTsKICAgIGxwYWMtPmVudW1zdHIgPSBOVUxMOwogICAgbHBhYy0+b3B0aW9ucyA9IEFDT19BVVRPQVBQRU5EOwogICAgbHBhYy0+d3BPcmlnRWRpdFByb2MgPSBOVUxMOwogICAgbHBhYy0+aHduZExpc3RCb3ggPSBOVUxMOwogICAgbHBhYy0+dHh0YmFja3VwID0gTlVMTDsKICAgIGxwYWMtPnF1aWNrQ29tcGxldGUgPSBOVUxMOwogICAgCiAgICBpZiAoIVNVQ0NFRURFRCAoSVVua25vd25fUXVlcnlJbnRlcmZhY2UgKF9JVW5rbm93bl8gKGxwYWMpLCByaWlkLCBwcHYpKSkgewoJSVVua25vd25fUmVsZWFzZSAoX0lVbmtub3duXyAobHBhYykpOwoJcmV0dXJuIEVfTk9JTlRFUkZBQ0U7CiAgICB9CiAgICAKICAgIFRSQUNFKCItLSAoJXApLT5cbiIsbHBhYyk7CgogICAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgQXV0b0NvbXBsZXRlX1F1ZXJ5SW50ZXJmYWNlCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUF1dG9Db21wbGV0ZV9mblF1ZXJ5SW50ZXJmYWNlKAogICAgSUF1dG9Db21wbGV0ZSAqIGlmYWNlLAogICAgUkVGSUlEIHJpaWQsCiAgICBMUFZPSUQgKnBwdk9iaikKewogICAgSUF1dG9Db21wbGV0ZUltcGwgKlRoaXMgPSAoSUF1dG9Db21wbGV0ZUltcGwgKilpZmFjZTsKICAgIAogICAgVFJBQ0UoIiglcCktPihcblx0SUlEOlx0JXMsJXApXG4iLCBUaGlzLCBzaGRlYnVnc3RyX2d1aWQocmlpZCksIHBwdk9iaik7CiAgICAqcHB2T2JqID0gTlVMTDsKCiAgICBpZihJc0VxdWFsSUlEKHJpaWQsICZJSURfSVVua25vd24pKSAKICAgIHsKCSpwcHZPYmogPSBUaGlzOwogICAgfSAKICAgIGVsc2UgaWYoSXNFcXVhbElJRChyaWlkLCAmSUlEX0lBdXRvQ29tcGxldGUpKQogICAgewoJKnBwdk9iaiA9IChJQXV0b0NvbXBsZXRlKilUaGlzOwogICAgfQogICAgZWxzZSBpZihJc0VxdWFsSUlEKHJpaWQsICZJSURfSUF1dG9Db21wbGV0ZTIpKQogICAgewoJKnBwdk9iaiA9IF9JQXV0b0NvbXBsZXRlMl8gKFRoaXMpOwogICAgfQoKICAgIGlmICgqcHB2T2JqKQogICAgewoJSUF1dG9Db21wbGV0ZV9BZGRSZWYoKElBdXRvQ29tcGxldGUqKSpwcHZPYmopOwoJVFJBQ0UoIi0tIEludGVyZmFjZTogKCVwKS0+KCVwKVxuIiwgcHB2T2JqLCAqcHB2T2JqKTsKCXJldHVybiBTX09LOwogICAgfQogICAgVFJBQ0UoIi0tIEludGVyZmFjZTogRV9OT0lOVEVSRkFDRVxuIik7CiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsJCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUF1dG9Db21wbGV0ZV9mbkFkZFJlZgogKi8Kc3RhdGljIFVMT05HIFdJTkFQSSBJQXV0b0NvbXBsZXRlX2ZuQWRkUmVmKAoJSUF1dG9Db21wbGV0ZSAqIGlmYWNlKQp7CiAgICBJQXV0b0NvbXBsZXRlSW1wbCAqVGhpcyA9IChJQXV0b0NvbXBsZXRlSW1wbCAqKWlmYWNlOwogICAgVUxPTkcgcmVmQ291bnQgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKICAgIAogICAgVFJBQ0UoIiglcCktPiglbHUpXG4iLCBUaGlzLCByZWZDb3VudCAtIDEpOwoKICAgIHJldHVybiByZWZDb3VudDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJQXV0b0NvbXBsZXRlX2ZuUmVsZWFzZQogKi8Kc3RhdGljIFVMT05HIFdJTkFQSSBJQXV0b0NvbXBsZXRlX2ZuUmVsZWFzZSgKCUlBdXRvQ29tcGxldGUgKiBpZmFjZSkKewogICAgSUF1dG9Db21wbGV0ZUltcGwgKlRoaXMgPSAoSUF1dG9Db21wbGV0ZUltcGwgKilpZmFjZTsKICAgIFVMT05HIHJlZkNvdW50ID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZik7CiAgICAKICAgIFRSQUNFKCIoJXApLT4oJWx1KVxuIiwgVGhpcywgcmVmQ291bnQgKyAxKTsKCiAgICBpZiAoIXJlZkNvdW50KSB7CglUUkFDRSgiIGRlc3Ryb3lpbmcgSUF1dG9Db21wbGV0ZSglcClcbiIsVGhpcyk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cXVpY2tDb21wbGV0ZSk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+dHh0YmFja3VwKTsKCWlmIChUaGlzLT5od25kTGlzdEJveCkKCSAgICBEZXN0cm95V2luZG93KFRoaXMtPmh3bmRMaXN0Qm94KTsKCWlmIChUaGlzLT5lbnVtc3RyKQoJICAgIElFbnVtU3RyaW5nX1JlbGVhc2UoVGhpcy0+ZW51bXN0cik7CglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKICAgIH0KICAgIHJldHVybiByZWZDb3VudDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJQXV0b0NvbXBsZXRlX2ZuRW5hYmxlCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUF1dG9Db21wbGV0ZV9mbkVuYWJsZSgKICAgIElBdXRvQ29tcGxldGUgKiBpZmFjZSwKICAgIEJPT0wgZkVuYWJsZSkKewogICAgSUF1dG9Db21wbGV0ZUltcGwgKlRoaXMgPSAoSUF1dG9Db21wbGV0ZUltcGwgKilpZmFjZTsKCiAgICBIUkVTVUxUIGhyID0gU19PSzsKCiAgICBUUkFDRSgiKCVwKS0+KCVzKVxuIiwgVGhpcywgKGZFbmFibGUpPyJ0cnVlIjoiZmFsc2UiKTsKCiAgICBUaGlzLT5lbmFibGVkID0gZkVuYWJsZTsKCiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUF1dG9Db21wbGV0ZV9mbkluaXQKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQXV0b0NvbXBsZXRlX2ZuSW5pdCgKICAgIElBdXRvQ29tcGxldGUgKiBpZmFjZSwKICAgIEhXTkQgaHduZEVkaXQsCiAgICBJVW5rbm93biAqcHVua0FDTCwKICAgIExQQ09MRVNUUiBwd3pzUmVnS2V5UGF0aCwKICAgIExQQ09MRVNUUiBwd3N6UXVpY2tDb21wbGV0ZSkKewogICAgSUF1dG9Db21wbGV0ZUltcGwgKlRoaXMgPSAoSUF1dG9Db21wbGV0ZUltcGwgKilpZmFjZTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBsYk5hbWVbXSA9IHsnTCcsJ2knLCdzJywndCcsJ0InLCdvJywneCcsMH07CgogICAgVFJBQ0UoIiglcCktPigweCUwOGx4LCAlcCwgJXMsICVzKVxuIiwgCgkgIFRoaXMsIChsb25nKWh3bmRFZGl0LCBwdW5rQUNMLCBkZWJ1Z3N0cl93KHB3enNSZWdLZXlQYXRoKSwgZGVidWdzdHJfdyhwd3N6UXVpY2tDb21wbGV0ZSkpOwoKICAgIGlmIChUaGlzLT5vcHRpb25zICYgQUNPX0FVVE9TVUdHRVNUKSBUUkFDRSgiIEFDT19BVVRPU1VHR0VTVFxuIik7CiAgICBpZiAoVGhpcy0+b3B0aW9ucyAmIEFDT19BVVRPQVBQRU5EKSBUUkFDRSgiIEFDT19BVVRPQVBQRU5EXG4iKTsKICAgIGlmIChUaGlzLT5vcHRpb25zICYgQUNPX1NFQVJDSCkgRklYTUUoIiBBQ09fU0VBUkNIIG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgaWYgKFRoaXMtPm9wdGlvbnMgJiBBQ09fRklMVEVSUFJFRklYRVMpIEZJWE1FKCIgQUNPX0ZJTFRFUlBSRUZJWEVTIG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgaWYgKFRoaXMtPm9wdGlvbnMgJiBBQ09fVVNFVEFCKSBGSVhNRSgiIEFDT19VU0VUQUIgbm90IHN1cHBvcnRlZFxuIik7CiAgICBpZiAoVGhpcy0+b3B0aW9ucyAmIEFDT19VUERPV05LRVlEUk9QU0xJU1QpIFRSQUNFKCIgQUNPX1VQRE9XTktFWURST1BTTElTVFxuIik7CiAgICBpZiAoVGhpcy0+b3B0aW9ucyAmIEFDT19SVExSRUFESU5HKSBGSVhNRSgiIEFDT19SVExSRUFESU5HIG5vdCBzdXBwb3J0ZWRcbiIpOwoKICAgIFRoaXMtPmh3bmRFZGl0ID0gaHduZEVkaXQ7CgogICAgaWYgKCFTVUNDRUVERUQgKElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlIChwdW5rQUNMLCAmSUlEX0lFbnVtU3RyaW5nLCAoTFBWT0lEKikmVGhpcy0+ZW51bXN0cikpKSB7CglUUkFDRSgiTm8gSUVudW1TdHJpbmcgaW50ZXJmYWNlXG4iKTsKCXJldHVybiAgRV9OT0lOVEVSRkFDRTsKICAgIH0KCiAgICBUaGlzLT53cE9yaWdFZGl0UHJvYyA9IChXTkRQUk9DKSBTZXRXaW5kb3dMb25nUHRyVyggaHduZEVkaXQsIEdXTFBfV05EUFJPQywgKExPTkdfUFRSKSBBQ0VkaXRTdWJjbGFzc1Byb2MpOwogICAgU2V0V2luZG93TG9uZ1B0clcoIGh3bmRFZGl0LCBHV0xQX1VTRVJEQVRBLCAoTE9OR19QVFIpVGhpcyk7CgogICAgaWYgKFRoaXMtPm9wdGlvbnMgJiBBQ09fQVVUT1NVR0dFU1QpIHsKCUhXTkQgaHduZFBhcmVudDsKCglod25kUGFyZW50ID0gR2V0UGFyZW50KFRoaXMtPmh3bmRFZGl0KTsKCQoJLyogRklYTUUgOiBUaGUgbGlzdGJveCBzaG91bGQgYmUgcmVzaXphYmxlIHdpdGggdGhlIG1vdXNlLiBXU19USElDS0ZSQU1FIGxvb2tzIHVnbHkgKi8KCVRoaXMtPmh3bmRMaXN0Qm94ID0gQ3JlYXRlV2luZG93RXhXKDAsIGxiTmFtZSwgTlVMTCwgCgkJCQkJICAgIFdTX0JPUkRFUiB8IFdTX0NISUxEIHwgV1NfVlNDUk9MTCB8IExCU19IQVNTVFJJTkdTIHwgTEJTX05PVElGWSB8IExCU19OT0lOVEVHUkFMSEVJR0hULCAKCQkJCQkgICAgQ1dfVVNFREVGQVVMVCwgQ1dfVVNFREVGQVVMVCwgQ1dfVVNFREVGQVVMVCwgQ1dfVVNFREVGQVVMVCwKCQkJCQkgICAgaHduZFBhcmVudCwgTlVMTCwgCgkJCQkJICAgIChISU5TVEFOQ0UpR2V0V2luZG93TG9uZ1B0clcoIGh3bmRQYXJlbnQsIEdXTFBfSElOU1RBTkNFICksIE5VTEwpOwoJCQkJCSAgICAKCWlmIChUaGlzLT5od25kTGlzdEJveCkgewoJICAgIFRoaXMtPndwT3JpZ0xCb3hQcm9jID0gKFdORFBST0MpIFNldFdpbmRvd0xvbmdQdHJXKCBUaGlzLT5od25kTGlzdEJveCwgR1dMUF9XTkRQUk9DLCAoTE9OR19QVFIpIEFDTEJveFN1YmNsYXNzUHJvYyk7CgkgICAgU2V0V2luZG93TG9uZ1B0clcoIFRoaXMtPmh3bmRMaXN0Qm94LCBHV0xQX1VTRVJEQVRBLCAoTE9OR19QVFIpVGhpcyk7Cgl9CiAgICB9CgogICAgaWYgKHB3enNSZWdLZXlQYXRoKSB7CglXQ0hBUiAqa2V5OwoJV0NIQVIgcmVzdWx0W01BWF9QQVRIXTsKCVdDSEFSICp2YWx1ZTsKCUhLRVkgaEtleSA9IDA7CglMT05HIHJlczsKCUxPTkcgbGVuOwoKCS8qIHB3c3pSZWdLZXlQYXRoIGNvbnRhaW5zIHRoZSBrZXkgYXMgd2VsbCBhcyB0aGUgdmFsdWUsIHNvIHdlIHNwbGl0ICovCglrZXkgPSAoV0NIQVIqKUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCAobHN0cmxlblcocHd6c1JlZ0tleVBhdGgpKzEpKnNpemVvZihXQ0hBUikpOwoJc3RyY3B5VyhrZXksIHB3enNSZWdLZXlQYXRoKTsKCXZhbHVlID0gc3RycmNoclcoa2V5LCAnXFwnKTsKCSp2YWx1ZSA9IDA7Cgl2YWx1ZSsrOwoJLyogTm93IHZhbHVlIGNvbnRhaW5zIHRoZSB2YWx1ZSBhbmQgYnVmZmVyIHRoZSBrZXkgKi8KCXJlcyA9IFJlZ09wZW5LZXlFeFcoSEtFWV9DVVJSRU5UX1VTRVIsIGtleSwgMCwgS0VZX1JFQUQsICZoS2V5KTsKCWlmIChyZXMgIT0gRVJST1JfU1VDQ0VTUykgewoJICAgIC8qIGlmIHRoZSBrZXkgaXMgbm90IGZvdW5kLCBNU0ROIHN0YXRlcyB3ZSBtdXN0IHNlZWsgaW4gSEtFWV9MT0NBTF9NQUNISU5FICovCgkgICAgcmVzID0gUmVnT3BlbktleUV4VyhIS0VZX0xPQ0FMX01BQ0hJTkUsIGtleSwgMCwgS0VZX1JFQUQsICZoS2V5KTsgIAoJfQoJaWYgKHJlcyA9PSBFUlJPUl9TVUNDRVNTKSB7CgkgICAgcmVzID0gUmVnUXVlcnlWYWx1ZVcoaEtleSwgdmFsdWUsIHJlc3VsdCwgJmxlbik7CgkgICAgaWYgKHJlcyA9PSBFUlJPUl9TVUNDRVNTKSB7CgkJVGhpcy0+cXVpY2tDb21wbGV0ZSA9IChXQ0hBUiopSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIGxlbipzaXplb2YoV0NIQVIpKTsKCQlzdHJjcHlXKFRoaXMtPnF1aWNrQ29tcGxldGUsIHJlc3VsdCk7CgkgICAgfQoJICAgIFJlZ0Nsb3NlS2V5KGhLZXkpOwoJfQoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwga2V5KTsKICAgIH0KCiAgICBpZiAoKHB3c3pRdWlja0NvbXBsZXRlKSAmJiAoIVRoaXMtPnF1aWNrQ29tcGxldGUpKSB7CglUaGlzLT5xdWlja0NvbXBsZXRlID0gKFdDSEFSKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgKGxzdHJsZW5XKHB3c3pRdWlja0NvbXBsZXRlKSsxKSpzaXplb2YoV0NIQVIpKTsKCWxzdHJjcHlXKFRoaXMtPnF1aWNrQ29tcGxldGUsIHB3c3pRdWlja0NvbXBsZXRlKTsKICAgIH0KCiAgICByZXR1cm4gU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBJQXV0b0NvbXBsZXRlX2ZuVlRhYmxlCiAqLwpzdGF0aWMgSUF1dG9Db21wbGV0ZVZ0YmwgYWN2dCA9CnsKICAgIElBdXRvQ29tcGxldGVfZm5RdWVyeUludGVyZmFjZSwKICAgIElBdXRvQ29tcGxldGVfZm5BZGRSZWYsCiAgICBJQXV0b0NvbXBsZXRlX2ZuUmVsZWFzZSwKICAgIElBdXRvQ29tcGxldGVfZm5Jbml0LAogICAgSUF1dG9Db21wbGV0ZV9mbkVuYWJsZSwKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgQXV0b0NvbXBsZXRlMl9RdWVyeUludGVyZmFjZQogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBdXRvQ29tcGxldGUyX2ZuUXVlcnlJbnRlcmZhY2UoCiAgICBJQXV0b0NvbXBsZXRlMiAqIGlmYWNlLAogICAgUkVGSUlEIHJpaWQsCiAgICBMUFZPSUQgKnBwdk9iaikKewogICAgX0lDT01fVEhJU19Gcm9tX0lBdXRvQ29tcGxldGUyKElBdXRvQ29tcGxldGVJbXBsLCBpZmFjZSk7CgogICAgVFJBQ0UgKCIoJXApLT4oJXMsJXApXG4iLCBUaGlzLCBzaGRlYnVnc3RyX2d1aWQgKHJpaWQpLCBwcHZPYmopOwoKICAgIHJldHVybiBJQXV0b0NvbXBsZXRlX1F1ZXJ5SW50ZXJmYWNlKChJQXV0b0NvbXBsZXRlKilUaGlzLCByaWlkLCBwcHZPYmopOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElBdXRvQ29tcGxldGUyX2ZuQWRkUmVmCiAqLwpzdGF0aWMgVUxPTkcgV0lOQVBJIElBdXRvQ29tcGxldGUyX2ZuQWRkUmVmKAoJSUF1dG9Db21wbGV0ZTIgKiBpZmFjZSkKewogICAgX0lDT01fVEhJU19Gcm9tX0lBdXRvQ29tcGxldGUyKElBdXRvQ29tcGxldGVJbXBsLGlmYWNlKTsKCiAgICBUUkFDRSAoIiglcCktPihjb3VudD0lbHUpXG4iLCBUaGlzLCBUaGlzLT5yZWYpOwoKICAgIHJldHVybiBJQXV0b0NvbXBsZXRlMl9BZGRSZWYoKElBdXRvQ29tcGxldGUqKVRoaXMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElBdXRvQ29tcGxldGUyX2ZuUmVsZWFzZQogKi8Kc3RhdGljIFVMT05HIFdJTkFQSSBJQXV0b0NvbXBsZXRlMl9mblJlbGVhc2UoCglJQXV0b0NvbXBsZXRlMiAqIGlmYWNlKQp7CiAgICBfSUNPTV9USElTX0Zyb21fSUF1dG9Db21wbGV0ZTIoSUF1dG9Db21wbGV0ZUltcGwsaWZhY2UpOwoKICAgIFRSQUNFICgiKCVwKS0+KGNvdW50PSVsdSlcbiIsIFRoaXMsIFRoaXMtPnJlZik7CgogICAgcmV0dXJuIElBdXRvQ29tcGxldGVfUmVsZWFzZSgoSUF1dG9Db21wbGV0ZSopVGhpcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUF1dG9Db21wbGV0ZTJfZm5FbmFibGUKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQXV0b0NvbXBsZXRlMl9mbkVuYWJsZSgKICAgIElBdXRvQ29tcGxldGUyICogaWZhY2UsCiAgICBCT09MIGZFbmFibGUpCnsKICAgIF9JQ09NX1RISVNfRnJvbV9JQXV0b0NvbXBsZXRlMihJQXV0b0NvbXBsZXRlSW1wbCwgaWZhY2UpOwoKICAgIFRSQUNFICgiKCVwKS0+KCVzKVxuIiwgVGhpcywgKGZFbmFibGUpPyJ0cnVlIjoiZmFsc2UiKTsKCiAgICByZXR1cm4gSUF1dG9Db21wbGV0ZV9FbmFibGUoKElBdXRvQ29tcGxldGUqKVRoaXMsIGZFbmFibGUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElBdXRvQ29tcGxldGUyX2ZuSW5pdAogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBdXRvQ29tcGxldGUyX2ZuSW5pdCgKICAgIElBdXRvQ29tcGxldGUyICogaWZhY2UsCiAgICBIV05EIGh3bmRFZGl0LAogICAgSVVua25vd24gKnB1bmtBQ0wsCiAgICBMUENPTEVTVFIgcHd6c1JlZ0tleVBhdGgsCiAgICBMUENPTEVTVFIgcHdzelF1aWNrQ29tcGxldGUpCnsKICAgIF9JQ09NX1RISVNfRnJvbV9JQXV0b0NvbXBsZXRlMihJQXV0b0NvbXBsZXRlSW1wbCwgaWZhY2UpOwoKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICByZXR1cm4gSUF1dG9Db21wbGV0ZV9Jbml0KChJQXV0b0NvbXBsZXRlKilUaGlzLCBod25kRWRpdCwgcHVua0FDTCwgcHd6c1JlZ0tleVBhdGgsIHB3c3pRdWlja0NvbXBsZXRlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBJQXV0b0NvbXBsZXRlX2ZuR2V0T3B0aW9ucwogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBdXRvQ29tcGxldGUyX2ZuR2V0T3B0aW9ucygKICAgIElBdXRvQ29tcGxldGUyICogaWZhY2UsCiAgICBEV09SRCAqcGR3RmxhZykKewogICAgSFJFU1VMVCBociA9IFNfT0s7CgogICAgX0lDT01fVEhJU19Gcm9tX0lBdXRvQ29tcGxldGUyKElBdXRvQ29tcGxldGVJbXBsLCBpZmFjZSk7CgogICAgVFJBQ0UoIiglcCkgLT4gKCVwKVxuIiwgVGhpcywgcGR3RmxhZyk7CgogICAgKnBkd0ZsYWcgPSBUaGlzLT5vcHRpb25zOwoKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBJQXV0b0NvbXBsZXRlX2ZuU2V0T3B0aW9ucwogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBdXRvQ29tcGxldGUyX2ZuU2V0T3B0aW9ucygKICAgIElBdXRvQ29tcGxldGUyICogaWZhY2UsCiAgICBEV09SRCBkd0ZsYWcpCnsKICAgIEhSRVNVTFQgaHIgPSBTX09LOwoKICAgIF9JQ09NX1RISVNfRnJvbV9JQXV0b0NvbXBsZXRlMihJQXV0b0NvbXBsZXRlSW1wbCwgaWZhY2UpOwoKICAgIFRSQUNFKCIoJXApIC0+ICgweCVseClcbiIsIFRoaXMsIGR3RmxhZyk7CgogICAgVGhpcy0+b3B0aW9ucyA9IGR3RmxhZzsKCiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgSUF1dG9Db21wbGV0ZTJfZm5WVGFibGUKICovCnN0YXRpYyBJQXV0b0NvbXBsZXRlMlZ0YmwgYWMydnQgPQp7CiAgICBJQXV0b0NvbXBsZXRlMl9mblF1ZXJ5SW50ZXJmYWNlLAogICAgSUF1dG9Db21wbGV0ZTJfZm5BZGRSZWYsCiAgICBJQXV0b0NvbXBsZXRlMl9mblJlbGVhc2UsCiAgICBJQXV0b0NvbXBsZXRlMl9mbkluaXQsCiAgICBJQXV0b0NvbXBsZXRlMl9mbkVuYWJsZSwKICAgIC8qIElBdXRvQ29tcGxldGUyICovCiAgICBJQXV0b0NvbXBsZXRlMl9mblNldE9wdGlvbnMsCiAgICBJQXV0b0NvbXBsZXRlMl9mbkdldE9wdGlvbnMsCn07CgovKgogIFdpbmRvdyBwcm9jZWR1cmUgZm9yIGF1dG9jb21wbGV0aW9uCiAqLwpzdGF0aWMgTFJFU1VMVCBBUElFTlRSWSBBQ0VkaXRTdWJjbGFzc1Byb2MoSFdORCBod25kLCBVSU5UIHVNc2csIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0pCnsKICAgIElBdXRvQ29tcGxldGVJbXBsICpUaGlzID0gKElBdXRvQ29tcGxldGVJbXBsICopR2V0V2luZG93TG9uZ1B0clcoaHduZCwgR1dMUF9VU0VSREFUQSk7CiAgICBMUE9MRVNUUiBzdHJzOwogICAgSFJFU1VMVCBocjsKICAgIFdDSEFSIGh3bmRUZXh0WzI1NV07CiAgICBXQ0hBUiAqaHduZFFDVGV4dDsKICAgIFJFQ1QgcjsKICAgIEJPT0wgY29udHJvbCwgZmlsbGVkLCBkaXNwbGF5YWxsID0gRkFMU0U7CiAgICBpbnQgY3B0LCBoZWlnaHQsIHNlbDsKCiAgICBpZiAoIVRoaXMtPmVuYWJsZWQpIHJldHVybiBDYWxsV2luZG93UHJvY1coVGhpcy0+d3BPcmlnRWRpdFByb2MsIGh3bmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKCiAgICBzd2l0Y2ggKHVNc2cpCiAgICB7CgljYXNlIENCX1NIT1dEUk9QRE9XTjoKCSAgICBTaG93V2luZG93KFRoaXMtPmh3bmRMaXN0Qm94LCBTV19ISURFKTsKCSAgICBicmVhazsKCWNhc2UgV01fS0lMTEZPQ1VTOgoJICAgIGlmICgoVGhpcy0+b3B0aW9ucyAmJiBBQ09fQVVUT1NVR0dFU1QpICYmIAoJCSgoSFdORCl3UGFyYW0gIT0gVGhpcy0+aHduZExpc3RCb3gpKQoJICAgIHsKCQlTaG93V2luZG93KFRoaXMtPmh3bmRMaXN0Qm94LCBTV19ISURFKTsKCSAgICB9CgkgICAgYnJlYWs7CgljYXNlIFdNX0tFWVVQOgoJICAgIAoJICAgIEdldFdpbmRvd1RleHRXKCBod25kLCAoTFBXU1RSKWh3bmRUZXh0LCAyNTUpOwogICAgICAKCSAgICBzd2l0Y2god1BhcmFtKSB7CgkJY2FzZSBWS19SRVRVUk46CgkJICAgIC8qIElmIHF1aWNrQ29tcGxldGUgaXMgc2V0IGFuZCBjb250cm9sIGlzIHByZXNzZWQsIHJlcGxhY2UgdGhlIHN0cmluZyAqLwoJCSAgICBjb250cm9sID0gR2V0S2V5U3RhdGUoVktfQ09OVFJPTCkgJiAweDgwMDA7CQkgICAgCgkJICAgIGlmIChjb250cm9sICYmIFRoaXMtPnF1aWNrQ29tcGxldGUpIHsKCQkJaHduZFFDVGV4dCA9IChXQ0hBUiopSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIAoJCQkJCQkgICAgICAgKGxzdHJsZW5XKFRoaXMtPnF1aWNrQ29tcGxldGUpK2xzdHJsZW5XKGh3bmRUZXh0KSkqc2l6ZW9mKFdDSEFSKSk7CgkJCXNlbCA9IHNwcmludGZXKGh3bmRRQ1RleHQsIFRoaXMtPnF1aWNrQ29tcGxldGUsIGh3bmRUZXh0KTsKCQkJU2VuZE1lc3NhZ2VXKGh3bmQsIFdNX1NFVFRFWFQsIDAsIChMUEFSQU0paHduZFFDVGV4dCk7CgkJCVNlbmRNZXNzYWdlVyhod25kLCBFTV9TRVRTRUwsIDAsIHNlbCk7CgkJCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGh3bmRRQ1RleHQpOwoJCSAgICB9CgoJCSAgICBTaG93V2luZG93KFRoaXMtPmh3bmRMaXN0Qm94LCBTV19ISURFKTsKCQkgICAgcmV0dXJuIDA7CgkJY2FzZSBWS19MRUZUOgoJCWNhc2UgVktfUklHSFQ6CgkJICAgIHJldHVybiAwOwoJCWNhc2UgVktfVVA6CSAgICAgIAoJCWNhc2UgVktfRE9XTjoKCQkgICAgLyogVHdvIGNhc2VzIGhlcmUgOiAKCQkgICAgICAgLSBpZiB0aGUgbGlzdGJveCBpcyBub3QgdmlzaWJsZSwgZGlzcGxheXMgaXQgCgkJICAgICAgIHdpdGggYWxsIHRoZSBlbnRyaWVzIGlmIHRoZSBzdHlsZSBBQ09fVVBET1dOS0VZRFJPUFNMSVNUCgkJICAgICAgIGlzIHByZXNlbnQgYnV0IGRvZXMgbm90IHNlbGVjdCBhbnl0aGluZy4KCQkgICAgICAgLSBpZiB0aGUgbGlzdGJveCBpcyB2aXNpYmxlLCBjaGFuZ2UgdGhlIHNlbGVjdGlvbgoJCSAgICAqLwoJCSAgICBpZiAoIChUaGlzLT5vcHRpb25zICYgKEFDT19BVVRPU1VHR0VTVCB8IEFDT19VUERPV05LRVlEUk9QU0xJU1QpKSAKCQkJICYmICghSXNXaW5kb3dWaXNpYmxlKFRoaXMtPmh3bmRMaXN0Qm94KSAmJiAoISAqaHduZFRleHQpKSApCgkJICAgIHsKCQkJIC8qIFdlIG11c3QgZGlzcGF5cyBhbGwgdGhlIGVudHJpZXMgKi8KCQkJIGRpc3BsYXlhbGwgPSBUUlVFOwoJCSAgICB9IGVsc2UgewoJCQlpZiAoSXNXaW5kb3dWaXNpYmxlKFRoaXMtPmh3bmRMaXN0Qm94KSkgewoJCQkgICAgaW50IGNvdW50OwoKCQkJICAgIGNvdW50ID0gU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRMaXN0Qm94LCBMQl9HRVRDT1VOVCwgMCwgMCk7CgkJCSAgICAvKiBDaGFuZ2UgdGhlIHNlbGVjdGlvbiAqLwoJCQkgICAgc2VsID0gU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRMaXN0Qm94LCBMQl9HRVRDVVJTRUwsIDAsIDApOwoJCQkgICAgaWYgKHdQYXJhbSA9PSBWS19VUCkKCQkJCXNlbCA9ICgoc2VsLTEpPDApP2NvdW50LTE6c2VsLTE7CgkJCSAgICBlbHNlCgkJCQlzZWwgPSAoKHNlbCsxKT49IGNvdW50KT8tMTpzZWwrMTsKCQkJICAgIFNlbmRNZXNzYWdlVyhUaGlzLT5od25kTGlzdEJveCwgTEJfU0VUQ1VSU0VMLCBzZWwsIDApOwoJCQkgICAgaWYgKHNlbCAhPSAtMSkgewoJCQkJV0NIQVIgKm1zZzsKCQkJCWludCBsZW47CgkJCQkKCQkJCWxlbiA9IFNlbmRNZXNzYWdlVyhUaGlzLT5od25kTGlzdEJveCwgTEJfR0VUVEVYVExFTiwgc2VsLCAoTFBBUkFNKU5VTEwpOwoJCQkJbXNnID0gKFdDSEFSKikgSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIChsZW4rMSkqc2l6ZW9mKFdDSEFSKSk7CgkJCQlTZW5kTWVzc2FnZVcoVGhpcy0+aHduZExpc3RCb3gsIExCX0dFVFRFWFQsIHNlbCwgKExQQVJBTSltc2cpOwoJCQkJU2VuZE1lc3NhZ2VXKGh3bmQsIFdNX1NFVFRFWFQsIDAsIChMUEFSQU0pbXNnKTsKCQkJCVNlbmRNZXNzYWdlVyhod25kLCBFTV9TRVRTRUwsIGxzdHJsZW5XKG1zZyksIGxzdHJsZW5XKG1zZykpOwoJCQkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbXNnKTsKCQkJICAgIH0gZWxzZSB7CgkJCQlTZW5kTWVzc2FnZVcoaHduZCwgV01fU0VUVEVYVCwgMCwgKExQQVJBTSlUaGlzLT50eHRiYWNrdXApOwoJCQkJU2VuZE1lc3NhZ2VXKGh3bmQsIEVNX1NFVFNFTCwgbHN0cmxlblcoVGhpcy0+dHh0YmFja3VwKSwgbHN0cmxlblcoVGhpcy0+dHh0YmFja3VwKSk7CgkJCSAgICB9CQkJCgkJCX0gCQkKCQkJcmV0dXJuIDA7CgkJICAgIH0KCQkgICAgYnJlYWs7CgkJY2FzZSBWS19CQUNLOgoJCWNhc2UgVktfREVMRVRFOgoJCSAgICBpZiAoKCEgKmh3bmRUZXh0KSAmJiAoVGhpcy0+b3B0aW9ucyAmIEFDT19BVVRPU1VHR0VTVCkpIHsKCQkJU2hvd1dpbmRvdyhUaGlzLT5od25kTGlzdEJveCwgU1dfSElERSk7CgkJCXJldHVybiBDYWxsV2luZG93UHJvY1coVGhpcy0+d3BPcmlnRWRpdFByb2MsIGh3bmQsIHVNc2csIHdQYXJhbSwgbFBhcmFtKTsKCQkgICAgfQoJCSAgICBpZiAoVGhpcy0+b3B0aW9ucyAmIEFDT19BVVRPQVBQRU5EKSB7CgkJCURXT1JEIGI7CgkJCVNlbmRNZXNzYWdlVyhod25kLCBFTV9HRVRTRUwsIChXUEFSQU0pJmIsIChMUEFSQU0pTlVMTCk7CgkJCWlmIChiPjEpIHsKCQkJICAgIGh3bmRUZXh0W2ItMV0gPSAnXDAnOwoJCQl9IGVsc2UgewoJCQkgICAgaHduZFRleHRbMF0gPSAnXDAnOwoJCQkgICAgU2V0V2luZG93VGV4dFcoaHduZCwgaHduZFRleHQpOyAKCQkJfQkJCQoJCSAgICB9CgkJICAgIGJyZWFrOwoJCWRlZmF1bHQ6CQkgICAgCgkJICAgIDsKCSAgICB9CiAgICAgIAoJICAgIFNlbmRNZXNzYWdlVyhUaGlzLT5od25kTGlzdEJveCwgTEJfUkVTRVRDT05URU5ULCAwLCAwKTsKCgkgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+dHh0YmFja3VwKTsKCSAgICBUaGlzLT50eHRiYWNrdXAgPSAoV0NIQVIqKSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwKCQkJCQkJIEhFQVBfWkVST19NRU1PUlksIChsc3RybGVuVyhod25kVGV4dCkrMSkqc2l6ZW9mKFdDSEFSKSk7CQkJCQkJCSAgICAgIAoJICAgIGxzdHJjcHlXKFRoaXMtPnR4dGJhY2t1cCwgaHduZFRleHQpOwoKCSAgICAvKiBSZXR1cm5zIGlmIHRoZXJlIGlzIG5vIHRleHQgdG8gc2VhcmNoIGFuZCB3ZSBkb2Vzbid0IHdhbnQgdG8gZGlzcGxheSBhbGwgdGhlIGVudHJpZXMgKi8KCSAgICBpZiAoKCFkaXNwbGF5YWxsKSAmJiAoISAqaHduZFRleHQpICkKCQlicmVhazsKCSAgICAKCSAgICBJRW51bVN0cmluZ19SZXNldChUaGlzLT5lbnVtc3RyKTsKCSAgICBmaWxsZWQgPSBGQUxTRTsKCSAgICBmb3IoY3B0ID0gMDs7KSB7CgkJaHIgPSBJRW51bVN0cmluZ19OZXh0KFRoaXMtPmVudW1zdHIsIDEsICZzdHJzLCBOVUxMKTsKCQlpZiAoaHIgIT0gU19PSykKCQkgICAgYnJlYWs7CgoJCWlmICgoTFBXU1RSKXN0cnN0clcoc3RycywgaHduZFRleHQpID09IHN0cnMpIHsKCQkgICAgCgkJICAgIGlmIChUaGlzLT5vcHRpb25zICYgQUNPX0FVVE9BUFBFTkQpIHsKCQkJU2V0V2luZG93VGV4dFcoaHduZCwgc3Rycyk7CgkJCVNlbmRNZXNzYWdlVyhod25kLCBFTV9TRVRTRUwsIGxzdHJsZW5XKGh3bmRUZXh0KSwgbHN0cmxlblcoc3RycykpOwoJCQlicmVhazsKCQkgICAgfQkJCgoJCSAgICBpZiAoVGhpcy0+b3B0aW9ucyAmIEFDT19BVVRPU1VHR0VTVCkgewoJCQlTZW5kTWVzc2FnZVcoVGhpcy0+aHduZExpc3RCb3gsIExCX0FERFNUUklORywgMCwgKExQQVJBTSlzdHJzKTsKCQkJZmlsbGVkID0gVFJVRTsKCQkJY3B0Kys7CgkJICAgIH0KCQl9CQkKCSAgICB9CgkgICAgCgkgICAgaWYgKFRoaXMtPm9wdGlvbnMgJiBBQ09fQVVUT1NVR0dFU1QpIHsKCQlpZiAoZmlsbGVkKSB7CgkJICAgIGhlaWdodCA9IFNlbmRNZXNzYWdlVyhUaGlzLT5od25kTGlzdEJveCwgTEJfR0VUSVRFTUhFSUdIVCwgMCwgMCk7CgkJICAgIFNlbmRNZXNzYWdlVyhUaGlzLT5od25kTGlzdEJveCwgTEJfQ0FSRVRPRkYsIDAsIDApOwoJCSAgICBHZXRXaW5kb3dSZWN0KGh3bmQsICZyKTsKCQkgICAgU2V0UGFyZW50KFRoaXMtPmh3bmRMaXN0Qm94LCBIV05EX0RFU0tUT1ApOwoJCSAgICAvKiBJdCBzZWVtcyB0aGF0IFdpbmRvd3MgWFAgZGlzcGxheXMgNyBsaW5lcyBhdCBtb3N0IAoJCSAgICAgICBhbmQgb3RoZXJ3aXNlIGRpc3BsYXlzIGEgdmVydGljYWwgc2Nyb2xsIGJhciAqLwoJCSAgICBTZXRXaW5kb3dQb3MoVGhpcy0+aHduZExpc3RCb3gsIEhXTkRfVE9QLCAKCQkJCSByLmxlZnQsIHIuYm90dG9tICsgMSwgci5yaWdodCAtIHIubGVmdCwgbWluKGhlaWdodCAqIDcsIGhlaWdodCooY3B0KzEpKSwgCgkJCQkgU1dQX1NIT1dXSU5ET1cgKTsKCQl9IGVsc2UgewoJCSAgICBTaG93V2luZG93KFRoaXMtPmh3bmRMaXN0Qm94LCBTV19ISURFKTsKCQl9CgkgICAgfQoJICAgIAoJICAgIGJyZWFrOyAKCWRlZmF1bHQ6CgkgICAgcmV0dXJuIENhbGxXaW5kb3dQcm9jVyhUaGlzLT53cE9yaWdFZGl0UHJvYywgaHduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwoJICAgIAogICAgfQoKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgTFJFU1VMVCBBUElFTlRSWSBBQ0xCb3hTdWJjbGFzc1Byb2MoSFdORCBod25kLCBVSU5UIHVNc2csIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0pCnsKICAgIElBdXRvQ29tcGxldGVJbXBsICpUaGlzID0gKElBdXRvQ29tcGxldGVJbXBsICopR2V0V2luZG93TG9uZ1B0clcoaHduZCwgR1dMUF9VU0VSREFUQSk7CiAgICBXQ0hBUiAqbXNnOwogICAgaW50IHNlbCA9IC0xLCBsZW47CgogICAgc3dpdGNoICh1TXNnKSB7CgljYXNlIFdNX01PVVNFTU9WRToKCSAgICBzZWwgPSBTZW5kTWVzc2FnZVcoaHduZCwgTEJfSVRFTUZST01QT0lOVCwgMCwgbFBhcmFtKTsKCSAgICBTZW5kTWVzc2FnZVcoaHduZCwgTEJfU0VUQ1VSU0VMLCAoV1BBUkFNKXNlbCwgKExQQVJBTSkwKTsKCSAgICBicmVhazsKCWNhc2UgV01fTEJVVFRPTkRPV046CgkgICAgbGVuID0gU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRMaXN0Qm94LCBMQl9HRVRURVhUTEVOLCBzZWwsIChMUEFSQU0pTlVMTCk7CgkgICAgbXNnID0gKFdDSEFSKikgSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIChsZW4rMSkqc2l6ZW9mKFdDSEFSKSk7CgkgICAgc2VsID0gKElOVClTZW5kTWVzc2FnZVcoaHduZCwgTEJfR0VUQ1VSU0VMLCAwLCAwKTsKCSAgICBTZW5kTWVzc2FnZVcoaHduZCwgTEJfR0VUVEVYVCwgc2VsLCAoTFBBUkFNKW1zZyk7CgkgICAgU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRFZGl0LCBXTV9TRVRURVhULCAwLCAoTFBBUkFNKW1zZyk7CgkgICAgU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRFZGl0LCBFTV9TRVRTRUwsIDAsIGxzdHJsZW5XKG1zZykpOwoJICAgIFNob3dXaW5kb3coaHduZCwgU1dfSElERSk7CgkgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbXNnKTsKCSAgICBicmVhazsKCWRlZmF1bHQ6CgkgICAgcmV0dXJuIENhbGxXaW5kb3dQcm9jVyhUaGlzLT53cE9yaWdMQm94UHJvYywgaHduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwogICAgfQogICAgcmV0dXJuIDA7Cn0K