LyoKICoJQXV0b0NvbXBsZXRlIGludGVyZmFjZXMgaW1wbGVtZW50YXRpb24uCiAqCiAqCUNvcHlyaWdodCAyMDA0CU1heGltZSBCZWxsZW5n6SA8bWF4aW1lLmJlbGxlbmdlQGxhcG9zdGUubmV0PgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgovKgogIEltcGxlbWVudGVkOgogIC0gQUNPX0FVVE9BUFBFTkQgc3R5bGUKICAtIEFDT19BVVRPU1VHR0VTVCBzdHlsZQogIC0gQUNPX1VQRE9XTktFWURST1BTTElTVCBzdHlsZQoKICAtIEhhbmRsZSBwd3pzUmVnS2V5UGF0aCBhbmQgcHdzelF1aWNrQ29tcGxldGUgaW4gSW5pdAoKICBUT0RPOgogIC0gaW1wbGVtZW50IEFDT19TRUFSQ0ggc3R5bGUKICAtIGltcGxlbWVudCBBQ09fRklMVEVSUFJFRklYRVMgc3R5bGUKICAtIGltcGxlbWVudCBBQ09fVVNFVEFCIHN0eWxlCiAgLSBpbXBsZW1lbnQgQUNPX1JUTFJFQURJTkcgc3R5bGUKICAKICovCiNpbmNsdWRlICJjb25maWcuaCIKCiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAidW5kb2NzaGVsbC5oIgojaW5jbHVkZSAic2hsd2FwaS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm9iamJhc2UuaCIKCiNpbmNsdWRlICJwaWRsLmgiCiNpbmNsdWRlICJzaGxndWlkLmgiCiNpbmNsdWRlICJzaGxvYmouaCIKI2luY2x1ZGUgInNobGRpc3AuaCIKI2luY2x1ZGUgImRlYnVnaGxwLmgiCgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChzaGVsbCk7Cgp0eXBlZGVmIHN0cnVjdAp7CiAgICBJQXV0b0NvbXBsZXRlVnRibCAgKmxwVnRibDsKICAgIElBdXRvQ29tcGxldGUyVnRibCAqbHB2dGJsQXV0b0NvbXBsZXRlMjsKICAgIERXT1JEIHJlZjsKICAgIEJPT0wgIGVuYWJsZWQ7CiAgICBIV05EIGh3bmRFZGl0OwogICAgSFdORCBod25kTGlzdEJveDsKICAgIFdORFBST0Mgd3BPcmlnRWRpdFByb2M7CiAgICBXTkRQUk9DIHdwT3JpZ0xCb3hQcm9jOwogICAgV0NIQVIgKnR4dGJhY2t1cDsKICAgIFdDSEFSICpxdWlja0NvbXBsZXRlOwogICAgSUVudW1TdHJpbmcgKmVudW1zdHI7CiAgICBBVVRPQ09NUExFVEVPUFRJT05TIG9wdGlvbnM7Cn0gSUF1dG9Db21wbGV0ZUltcGw7CgpzdGF0aWMgc3RydWN0IElBdXRvQ29tcGxldGVWdGJsIGFjdnQ7CnN0YXRpYyBzdHJ1Y3QgSUF1dG9Db21wbGV0ZTJWdGJsIGFjMnZ0OwoKI2RlZmluZSBfSUF1dG9Db21wbGV0ZTJfT2Zmc2V0ICgoaW50KSgmKCgoSUF1dG9Db21wbGV0ZUltcGwqKTApLT5scHZ0YmxBdXRvQ29tcGxldGUyKSkpCiNkZWZpbmUgX0lDT01fVEhJU19Gcm9tX0lBdXRvQ29tcGxldGUyKGNsYXNzLCBuYW1lKSBjbGFzcyogVGhpcyA9IChjbGFzcyopKCgoY2hhciopbmFtZSktX0lBdXRvQ29tcGxldGUyX09mZnNldCk7CgovKgogIGNvbnZlcnRzIFRoaXMgdG8gYSBpbnRlcmZhY2UgcG9pbnRlcgoqLwojZGVmaW5lIF9JVW5rbm93bl8oVGhpcykgKElVbmtub3duKikmKFRoaXMtPmxwVnRibCkKI2RlZmluZSBfSUF1dG9Db21wbGV0ZTJfKFRoaXMpICAoSUF1dG9Db21wbGV0ZTIqKSYoVGhpcy0+bHB2dGJsQXV0b0NvbXBsZXRlMikgCgpzdGF0aWMgTFJFU1VMVCBBUElFTlRSWSBBQ0VkaXRTdWJjbGFzc1Byb2MoSFdORCBod25kLCBVSU5UIHVNc2csIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0pOwpzdGF0aWMgTFJFU1VMVCBBUElFTlRSWSBBQ0xCb3hTdWJjbGFzc1Byb2MoSFdORCBod25kLCBVSU5UIHVNc2csIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0pOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBJQXV0b0NvbXBsZXRlX0NvbnN0cnVjdG9yCiAqLwpIUkVTVUxUIFdJTkFQSSBJQXV0b0NvbXBsZXRlX0NvbnN0cnVjdG9yKElVbmtub3duICogcFVua091dGVyLCBSRUZJSUQgcmlpZCwgTFBWT0lEICogcHB2KQp7CiAgICBJQXV0b0NvbXBsZXRlSW1wbCAqbHBhYzsKCiAgICBpZiAocFVua091dGVyICYmICFJc0VxdWFsSUlEIChyaWlkLCAmSUlEX0lVbmtub3duKSkKCXJldHVybiBDTEFTU19FX05PQUdHUkVHQVRJT047CgogICAgbHBhYyA9IChJQXV0b0NvbXBsZXRlSW1wbCopSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksCiAgICAgIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJQXV0b0NvbXBsZXRlSW1wbCkpOwogICAgaWYgKCFscGFjKSAKCXJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIGxwYWMtPnJlZiA9IDE7CiAgICBscGFjLT5scFZ0YmwgPSAmYWN2dDsKICAgIGxwYWMtPmxwdnRibEF1dG9Db21wbGV0ZTIgPSAmYWMydnQ7CiAgICBscGFjLT5lbmFibGVkID0gVFJVRTsKICAgIGxwYWMtPmVudW1zdHIgPSBOVUxMOwogICAgbHBhYy0+b3B0aW9ucyA9IEFDT19BVVRPQVBQRU5EOwogICAgbHBhYy0+d3BPcmlnRWRpdFByb2MgPSBOVUxMOwogICAgbHBhYy0+aHduZExpc3RCb3ggPSBOVUxMOwogICAgbHBhYy0+dHh0YmFja3VwID0gTlVMTDsKICAgIGxwYWMtPnF1aWNrQ29tcGxldGUgPSBOVUxMOwogICAgCiAgICBpZiAoIVNVQ0NFRURFRCAoSVVua25vd25fUXVlcnlJbnRlcmZhY2UgKF9JVW5rbm93bl8gKGxwYWMpLCByaWlkLCBwcHYpKSkgewoJSVVua25vd25fUmVsZWFzZSAoX0lVbmtub3duXyAobHBhYykpOwoJcmV0dXJuIEVfTk9JTlRFUkZBQ0U7CiAgICB9CiAgICAKICAgIFRSQUNFKCItLSAoJXApLT5cbiIsbHBhYyk7CgogICAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgQXV0b0NvbXBsZXRlX1F1ZXJ5SW50ZXJmYWNlCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUF1dG9Db21wbGV0ZV9mblF1ZXJ5SW50ZXJmYWNlKAogICAgSUF1dG9Db21wbGV0ZSAqIGlmYWNlLAogICAgUkVGSUlEIHJpaWQsCiAgICBMUFZPSUQgKnBwdk9iaikKewogICAgSUF1dG9Db21wbGV0ZUltcGwgKlRoaXMgPSAoSUF1dG9Db21wbGV0ZUltcGwgKilpZmFjZTsKICAgIAogICAgVFJBQ0UoIiglcCktPihcblx0SUlEOlx0JXMsJXApXG4iLCBUaGlzLCBzaGRlYnVnc3RyX2d1aWQocmlpZCksIHBwdk9iaik7CiAgICAqcHB2T2JqID0gTlVMTDsKCiAgICBpZihJc0VxdWFsSUlEKHJpaWQsICZJSURfSVVua25vd24pKSAKICAgIHsKCSpwcHZPYmogPSBUaGlzOwogICAgfSAKICAgIGVsc2UgaWYoSXNFcXVhbElJRChyaWlkLCAmSUlEX0lBdXRvQ29tcGxldGUpKQogICAgewoJKnBwdk9iaiA9IChJQXV0b0NvbXBsZXRlKilUaGlzOwogICAgfQogICAgZWxzZSBpZihJc0VxdWFsSUlEKHJpaWQsICZJSURfSUF1dG9Db21wbGV0ZTIpKQogICAgewoJKnBwdk9iaiA9IF9JQXV0b0NvbXBsZXRlMl8gKFRoaXMpOwogICAgfQoKICAgIGlmICgqcHB2T2JqKQogICAgewoJSUF1dG9Db21wbGV0ZV9BZGRSZWYoKElBdXRvQ29tcGxldGUqKSpwcHZPYmopOwoJVFJBQ0UoIi0tIEludGVyZmFjZTogKCVwKS0+KCVwKVxuIiwgcHB2T2JqLCAqcHB2T2JqKTsKCXJldHVybiBTX09LOwogICAgfQogICAgVFJBQ0UoIi0tIEludGVyZmFjZTogRV9OT0lOVEVSRkFDRVxuIik7CiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsJCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUF1dG9Db21wbGV0ZV9mbkFkZFJlZgogKi8Kc3RhdGljIFVMT05HIFdJTkFQSSBJQXV0b0NvbXBsZXRlX2ZuQWRkUmVmKAoJSUF1dG9Db21wbGV0ZSAqIGlmYWNlKQp7CiAgICBJQXV0b0NvbXBsZXRlSW1wbCAqVGhpcyA9IChJQXV0b0NvbXBsZXRlSW1wbCAqKWlmYWNlOwogICAgCiAgICBUUkFDRSgiKCVwKS0+KCVsdSlcbiIsVGhpcyxUaGlzLT5yZWYpOwogICAgcmV0dXJuICsrKFRoaXMtPnJlZik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUF1dG9Db21wbGV0ZV9mblJlbGVhc2UKICovCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUF1dG9Db21wbGV0ZV9mblJlbGVhc2UoCglJQXV0b0NvbXBsZXRlICogaWZhY2UpCnsKICAgIElBdXRvQ29tcGxldGVJbXBsICpUaGlzID0gKElBdXRvQ29tcGxldGVJbXBsICopaWZhY2U7CiAgICAKICAgIFRSQUNFKCIoJXApLT4oJWx1KVxuIixUaGlzLFRoaXMtPnJlZik7CgogICAgaWYgKCEtLShUaGlzLT5yZWYpKSB7CglUUkFDRSgiIGRlc3Ryb3lpbmcgSUF1dG9Db21wbGV0ZSglcClcbiIsVGhpcyk7CglpZiAoVGhpcy0+cXVpY2tDb21wbGV0ZSkKCSAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5xdWlja0NvbXBsZXRlKTsKCWlmIChUaGlzLT50eHRiYWNrdXApCgkgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+dHh0YmFja3VwKTsKCWlmIChUaGlzLT5od25kTGlzdEJveCkKCSAgICBEZXN0cm95V2luZG93KFRoaXMtPmh3bmRMaXN0Qm94KTsKCWlmIChUaGlzLT5lbnVtc3RyKQoJICAgIElFbnVtU3RyaW5nX1JlbGVhc2UoVGhpcy0+ZW51bXN0cik7CglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKCXJldHVybiAwOwogICAgfQogICAgcmV0dXJuIFRoaXMtPnJlZjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJQXV0b0NvbXBsZXRlX2ZuRW5hYmxlCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUF1dG9Db21wbGV0ZV9mbkVuYWJsZSgKICAgIElBdXRvQ29tcGxldGUgKiBpZmFjZSwKICAgIEJPT0wgZkVuYWJsZSkKewogICAgSUF1dG9Db21wbGV0ZUltcGwgKlRoaXMgPSAoSUF1dG9Db21wbGV0ZUltcGwgKilpZmFjZTsKCiAgICBIUkVTVUxUIGhyID0gU19PSzsKCiAgICBUUkFDRSgiKCVwKS0+KCVzKVxuIiwgVGhpcywgKGZFbmFibGUpPyJ0cnVlIjoiZmFsc2UiKTsKCiAgICBUaGlzLT5lbmFibGVkID0gZkVuYWJsZTsKCiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUF1dG9Db21wbGV0ZV9mbkluaXQKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQXV0b0NvbXBsZXRlX2ZuSW5pdCgKICAgIElBdXRvQ29tcGxldGUgKiBpZmFjZSwKICAgIEhXTkQgaHduZEVkaXQsCiAgICBJVW5rbm93biAqcHVua0FDTCwKICAgIExQQ09MRVNUUiBwd3pzUmVnS2V5UGF0aCwKICAgIExQQ09MRVNUUiBwd3N6UXVpY2tDb21wbGV0ZSkKewogICAgSUF1dG9Db21wbGV0ZUltcGwgKlRoaXMgPSAoSUF1dG9Db21wbGV0ZUltcGwgKilpZmFjZTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBsYk5hbWVbXSA9IHsnTCcsJ2knLCdzJywndCcsJ0InLCdvJywneCcsMH07CgogICAgVFJBQ0UoIiglcCktPigweCUwOGx4LCAlcCwgJXMsICVzKVxuIiwgCgkgIFRoaXMsIChsb25nKWh3bmRFZGl0LCBwdW5rQUNMLCBkZWJ1Z3N0cl93KHB3enNSZWdLZXlQYXRoKSwgZGVidWdzdHJfdyhwd3N6UXVpY2tDb21wbGV0ZSkpOwoKICAgIGlmIChUaGlzLT5vcHRpb25zICYgQUNPX0FVVE9TVUdHRVNUKSBUUkFDRSgiIEFDT19BVVRPU1VHR0VTVFxuIik7CiAgICBpZiAoVGhpcy0+b3B0aW9ucyAmIEFDT19BVVRPQVBQRU5EKSBUUkFDRSgiIEFDT19BVVRPQVBQRU5EXG4iKTsKICAgIGlmIChUaGlzLT5vcHRpb25zICYgQUNPX1NFQVJDSCkgRklYTUUoIiBBQ09fU0VBUkNIIG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgaWYgKFRoaXMtPm9wdGlvbnMgJiBBQ09fRklMVEVSUFJFRklYRVMpIEZJWE1FKCIgQUNPX0ZJTFRFUlBSRUZJWEVTIG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgaWYgKFRoaXMtPm9wdGlvbnMgJiBBQ09fVVNFVEFCKSBGSVhNRSgiIEFDT19VU0VUQUIgbm90IHN1cHBvcnRlZFxuIik7CiAgICBpZiAoVGhpcy0+b3B0aW9ucyAmIEFDT19VUERPV05LRVlEUk9QU0xJU1QpIFRSQUNFKCIgQUNPX1VQRE9XTktFWURST1BTTElTVFxuIik7CiAgICBpZiAoVGhpcy0+b3B0aW9ucyAmIEFDT19SVExSRUFESU5HKSBGSVhNRSgiIEFDT19SVExSRUFESU5HIG5vdCBzdXBwb3J0ZWRcbiIpOwoKICAgIFRoaXMtPmh3bmRFZGl0ID0gaHduZEVkaXQ7CgogICAgaWYgKCFTVUNDRUVERUQgKElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlIChwdW5rQUNMLCAmSUlEX0lFbnVtU3RyaW5nLCAoTFBWT0lEKikmVGhpcy0+ZW51bXN0cikpKSB7CglUUkFDRSgiTm8gSUVudW1TdHJpbmcgaW50ZXJmYWNlXG4iKTsKCXJldHVybiAgRV9OT0lOVEVSRkFDRTsKICAgIH0KCiAgICBUaGlzLT53cE9yaWdFZGl0UHJvYyA9IChXTkRQUk9DKSBTZXRXaW5kb3dMb25nUHRyVyggaHduZEVkaXQsIEdXTFBfV05EUFJPQywgKExPTkdfUFRSKSBBQ0VkaXRTdWJjbGFzc1Byb2MpOwogICAgU2V0V2luZG93TG9uZ1B0clcoIGh3bmRFZGl0LCBHV0xQX1VTRVJEQVRBLCAoTE9OR19QVFIpVGhpcyk7CgogICAgaWYgKFRoaXMtPm9wdGlvbnMgJiBBQ09fQVVUT1NVR0dFU1QpIHsKCUhXTkQgaHduZFBhcmVudDsKCglod25kUGFyZW50ID0gR2V0UGFyZW50KFRoaXMtPmh3bmRFZGl0KTsKCQoJLyogRklYTUUgOiBUaGUgbGlzdGJveCBzaG91bGQgYmUgcmVzaXphYmxlIHdpdGggdGhlIG1vdXNlLiBXU19USElDS0ZSQU1FIGxvb2tzIHVnbHkgKi8KCVRoaXMtPmh3bmRMaXN0Qm94ID0gQ3JlYXRlV2luZG93RXhXKDAsIGxiTmFtZSwgTlVMTCwgCgkJCQkJICAgIFdTX0JPUkRFUiB8IFdTX0NISUxEIHwgV1NfVlNDUk9MTCB8IExCU19IQVNTVFJJTkdTIHwgTEJTX05PVElGWSB8IExCU19OT0lOVEVHUkFMSEVJR0hULCAKCQkJCQkgICAgQ1dfVVNFREVGQVVMVCwgQ1dfVVNFREVGQVVMVCwgQ1dfVVNFREVGQVVMVCwgQ1dfVVNFREVGQVVMVCwKCQkJCQkgICAgaHduZFBhcmVudCwgTlVMTCwgCgkJCQkJICAgIChISU5TVEFOQ0UpR2V0V2luZG93TG9uZ0EoIGh3bmRQYXJlbnQsIEdXTF9ISU5TVEFOQ0UgKSwgTlVMTCk7CgkJCQkJICAgIAoJaWYgKFRoaXMtPmh3bmRMaXN0Qm94KSB7CgkgICAgVGhpcy0+d3BPcmlnTEJveFByb2MgPSAoV05EUFJPQykgU2V0V2luZG93TG9uZ1B0clcoIFRoaXMtPmh3bmRMaXN0Qm94LCBHV0xQX1dORFBST0MsIChMT05HX1BUUikgQUNMQm94U3ViY2xhc3NQcm9jKTsKCSAgICBTZXRXaW5kb3dMb25nUHRyVyggVGhpcy0+aHduZExpc3RCb3gsIEdXTFBfVVNFUkRBVEEsIChMT05HX1BUUilUaGlzKTsKCX0KICAgIH0KCiAgICBpZiAocHd6c1JlZ0tleVBhdGgpIHsKCVdDSEFSICprZXk7CglXQ0hBUiByZXN1bHRbTUFYX1BBVEhdOwoJV0NIQVIgKnZhbHVlOwoJSEtFWSBoS2V5ID0gMDsKCUxPTkcgcmVzOwoJTE9ORyBsZW47CgoJLyogcHdzelJlZ0tleVBhdGggY29udGFpbnMgdGhlIGtleSBhcyB3ZWxsIGFzIHRoZSB2YWx1ZSwgc28gd2Ugc3BsaXQgKi8KCWtleSA9IChXQ0hBUiopSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIChsc3RybGVuVyhwd3pzUmVnS2V5UGF0aCkrMSkqc2l6ZW9mKFdDSEFSKSk7CglzdHJjcHlXKGtleSwgcHd6c1JlZ0tleVBhdGgpOwoJdmFsdWUgPSBzdHJyY2hyVyhrZXksICdcXCcpOwoJKnZhbHVlID0gMDsKCXZhbHVlKys7CgkvKiBOb3cgdmFsdWUgY29udGFpbnMgdGhlIHZhbHVlIGFuZCBidWZmZXIgdGhlIGtleSAqLwoJcmVzID0gUmVnT3BlbktleUV4VyhIS0VZX0NVUlJFTlRfVVNFUiwga2V5LCAwLCBLRVlfUkVBRCwgJmhLZXkpOwoJaWYgKHJlcyAhPSBFUlJPUl9TVUNDRVNTKSB7CgkgICAgLyogaWYgdGhlIGtleSBpcyBub3QgZm91bmQsIE1TRE4gc3RhdGVzIHdlIG11c3Qgc2VlayBpbiBIS0VZX0xPQ0FMX01BQ0hJTkUgKi8KCSAgICByZXMgPSBSZWdPcGVuS2V5RXhXKEhLRVlfTE9DQUxfTUFDSElORSwga2V5LCAwLCBLRVlfUkVBRCwgJmhLZXkpOyAgCgl9CglpZiAocmVzID09IEVSUk9SX1NVQ0NFU1MpIHsKCSAgICByZXMgPSBSZWdRdWVyeVZhbHVlVyhoS2V5LCB2YWx1ZSwgcmVzdWx0LCAmbGVuKTsKCSAgICBpZiAocmVzID09IEVSUk9SX1NVQ0NFU1MpIHsKCQlUaGlzLT5xdWlja0NvbXBsZXRlID0gKFdDSEFSKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgbGVuKnNpemVvZihXQ0hBUikpOwoJCXN0cmNweVcoVGhpcy0+cXVpY2tDb21wbGV0ZSwgcmVzdWx0KTsKCSAgICB9CgkgICAgUmVnQ2xvc2VLZXkoaEtleSk7Cgl9CglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBrZXkpOwogICAgfQoKICAgIGlmICgocHdzelF1aWNrQ29tcGxldGUpICYmICghVGhpcy0+cXVpY2tDb21wbGV0ZSkpIHsKCVRoaXMtPnF1aWNrQ29tcGxldGUgPSAoV0NIQVIqKUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCAobHN0cmxlblcocHdzelF1aWNrQ29tcGxldGUpKzEpKnNpemVvZihXQ0hBUikpOwoJbHN0cmNweVcoVGhpcy0+cXVpY2tDb21wbGV0ZSwgcHdzelF1aWNrQ29tcGxldGUpOwogICAgfQoKICAgIHJldHVybiBTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIElBdXRvQ29tcGxldGVfZm5WVGFibGUKICovCnN0YXRpYyBJQXV0b0NvbXBsZXRlVnRibCBhY3Z0ID0KewogICAgSUF1dG9Db21wbGV0ZV9mblF1ZXJ5SW50ZXJmYWNlLAogICAgSUF1dG9Db21wbGV0ZV9mbkFkZFJlZiwKICAgIElBdXRvQ29tcGxldGVfZm5SZWxlYXNlLAogICAgSUF1dG9Db21wbGV0ZV9mbkluaXQsCiAgICBJQXV0b0NvbXBsZXRlX2ZuRW5hYmxlLAp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBBdXRvQ29tcGxldGUyX1F1ZXJ5SW50ZXJmYWNlCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUF1dG9Db21wbGV0ZTJfZm5RdWVyeUludGVyZmFjZSgKICAgIElBdXRvQ29tcGxldGUyICogaWZhY2UsCiAgICBSRUZJSUQgcmlpZCwKICAgIExQVk9JRCAqcHB2T2JqKQp7CiAgICBfSUNPTV9USElTX0Zyb21fSUF1dG9Db21wbGV0ZTIoSUF1dG9Db21wbGV0ZUltcGwsIGlmYWNlKTsKCiAgICBUUkFDRSAoIiglcCktPiglcywlcClcbiIsIFRoaXMsIHNoZGVidWdzdHJfZ3VpZCAocmlpZCksIHBwdk9iaik7CgogICAgcmV0dXJuIElBdXRvQ29tcGxldGVfUXVlcnlJbnRlcmZhY2UoKElBdXRvQ29tcGxldGUqKVRoaXMsIHJpaWQsIHBwdk9iaik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUF1dG9Db21wbGV0ZTJfZm5BZGRSZWYKICovCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUF1dG9Db21wbGV0ZTJfZm5BZGRSZWYoCglJQXV0b0NvbXBsZXRlMiAqIGlmYWNlKQp7CiAgICBfSUNPTV9USElTX0Zyb21fSUF1dG9Db21wbGV0ZTIoSUF1dG9Db21wbGV0ZUltcGwsaWZhY2UpOwoKICAgIFRSQUNFICgiKCVwKS0+KGNvdW50PSVsdSlcbiIsIFRoaXMsIFRoaXMtPnJlZik7CgogICAgcmV0dXJuIElBdXRvQ29tcGxldGUyX0FkZFJlZigoSUF1dG9Db21wbGV0ZSopVGhpcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUF1dG9Db21wbGV0ZTJfZm5SZWxlYXNlCiAqLwpzdGF0aWMgVUxPTkcgV0lOQVBJIElBdXRvQ29tcGxldGUyX2ZuUmVsZWFzZSgKCUlBdXRvQ29tcGxldGUyICogaWZhY2UpCnsKICAgIF9JQ09NX1RISVNfRnJvbV9JQXV0b0NvbXBsZXRlMihJQXV0b0NvbXBsZXRlSW1wbCxpZmFjZSk7CgogICAgVFJBQ0UgKCIoJXApLT4oY291bnQ9JWx1KVxuIiwgVGhpcywgVGhpcy0+cmVmKTsKCiAgICByZXR1cm4gSUF1dG9Db21wbGV0ZV9SZWxlYXNlKChJQXV0b0NvbXBsZXRlKilUaGlzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJQXV0b0NvbXBsZXRlMl9mbkVuYWJsZQogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBdXRvQ29tcGxldGUyX2ZuRW5hYmxlKAogICAgSUF1dG9Db21wbGV0ZTIgKiBpZmFjZSwKICAgIEJPT0wgZkVuYWJsZSkKewogICAgX0lDT01fVEhJU19Gcm9tX0lBdXRvQ29tcGxldGUyKElBdXRvQ29tcGxldGVJbXBsLCBpZmFjZSk7CgogICAgVFJBQ0UgKCIoJXApLT4oJXMpXG4iLCBUaGlzLCAoZkVuYWJsZSk/InRydWUiOiJmYWxzZSIpOwoKICAgIHJldHVybiBJQXV0b0NvbXBsZXRlX0VuYWJsZSgoSUF1dG9Db21wbGV0ZSopVGhpcywgZkVuYWJsZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUF1dG9Db21wbGV0ZTJfZm5Jbml0CiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUF1dG9Db21wbGV0ZTJfZm5Jbml0KAogICAgSUF1dG9Db21wbGV0ZTIgKiBpZmFjZSwKICAgIEhXTkQgaHduZEVkaXQsCiAgICBJVW5rbm93biAqcHVua0FDTCwKICAgIExQQ09MRVNUUiBwd3pzUmVnS2V5UGF0aCwKICAgIExQQ09MRVNUUiBwd3N6UXVpY2tDb21wbGV0ZSkKewogICAgX0lDT01fVEhJU19Gcm9tX0lBdXRvQ29tcGxldGUyKElBdXRvQ29tcGxldGVJbXBsLCBpZmFjZSk7CgogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIHJldHVybiBJQXV0b0NvbXBsZXRlX0luaXQoKElBdXRvQ29tcGxldGUqKVRoaXMsIGh3bmRFZGl0LCBwdW5rQUNMLCBwd3pzUmVnS2V5UGF0aCwgcHdzelF1aWNrQ29tcGxldGUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIElBdXRvQ29tcGxldGVfZm5HZXRPcHRpb25zCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUF1dG9Db21wbGV0ZTJfZm5HZXRPcHRpb25zKAogICAgSUF1dG9Db21wbGV0ZTIgKiBpZmFjZSwKICAgIERXT1JEICpwZHdGbGFnKQp7CiAgICBIUkVTVUxUIGhyID0gU19PSzsKCiAgICBfSUNPTV9USElTX0Zyb21fSUF1dG9Db21wbGV0ZTIoSUF1dG9Db21wbGV0ZUltcGwsIGlmYWNlKTsKCiAgICBUUkFDRSgiKCVwKSAtPiAoJXApXG4iLCBUaGlzLCBwZHdGbGFnKTsKCiAgICAqcGR3RmxhZyA9IFRoaXMtPm9wdGlvbnM7CgogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIElBdXRvQ29tcGxldGVfZm5TZXRPcHRpb25zCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUF1dG9Db21wbGV0ZTJfZm5TZXRPcHRpb25zKAogICAgSUF1dG9Db21wbGV0ZTIgKiBpZmFjZSwKICAgIERXT1JEIGR3RmxhZykKewogICAgSFJFU1VMVCBociA9IFNfT0s7CgogICAgX0lDT01fVEhJU19Gcm9tX0lBdXRvQ29tcGxldGUyKElBdXRvQ29tcGxldGVJbXBsLCBpZmFjZSk7CgogICAgVFJBQ0UoIiglcCkgLT4gKDB4JWx4KVxuIiwgVGhpcywgZHdGbGFnKTsKCiAgICBUaGlzLT5vcHRpb25zID0gZHdGbGFnOwoKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBJQXV0b0NvbXBsZXRlMl9mblZUYWJsZQogKi8Kc3RhdGljIElBdXRvQ29tcGxldGUyVnRibCBhYzJ2dCA9CnsKICAgIElBdXRvQ29tcGxldGUyX2ZuUXVlcnlJbnRlcmZhY2UsCiAgICBJQXV0b0NvbXBsZXRlMl9mbkFkZFJlZiwKICAgIElBdXRvQ29tcGxldGUyX2ZuUmVsZWFzZSwKICAgIElBdXRvQ29tcGxldGUyX2ZuSW5pdCwKICAgIElBdXRvQ29tcGxldGUyX2ZuRW5hYmxlLAogICAgLyogSUF1dG9Db21wbGV0ZTIgKi8KICAgIElBdXRvQ29tcGxldGUyX2ZuU2V0T3B0aW9ucywKICAgIElBdXRvQ29tcGxldGUyX2ZuR2V0T3B0aW9ucywKfTsKCi8qCiAgV2luZG93IHByb2NlZHVyZSBmb3IgYXV0b2NvbXBsZXRpb24KICovCnN0YXRpYyBMUkVTVUxUIEFQSUVOVFJZIEFDRWRpdFN1YmNsYXNzUHJvYyhIV05EIGh3bmQsIFVJTlQgdU1zZywgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogICAgSUF1dG9Db21wbGV0ZUltcGwgKlRoaXMgPSAoSUF1dG9Db21wbGV0ZUltcGwgKilHZXRXaW5kb3dMb25nUHRyVyhod25kLCBHV0xQX1VTRVJEQVRBKTsKICAgIExQT0xFU1RSIHN0cnM7CiAgICBIUkVTVUxUIGhyOwogICAgV0NIQVIgaHduZFRleHRbMjU1XTsKICAgIFdDSEFSICpod25kUUNUZXh0OwogICAgUkVDVCByOwogICAgQk9PTCBjb250cm9sLCBmaWxsZWQsIGRpc3BsYXlhbGwgPSBGQUxTRTsKICAgIGludCBjcHQsIGhlaWdodCwgc2VsOwoKICAgIGlmICghVGhpcy0+ZW5hYmxlZCkgcmV0dXJuIENhbGxXaW5kb3dQcm9jVyhUaGlzLT53cE9yaWdFZGl0UHJvYywgaHduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwoKICAgIHN3aXRjaCAodU1zZykKICAgIHsKCWNhc2UgQ0JfU0hPV0RST1BET1dOOgoJICAgIFNob3dXaW5kb3coVGhpcy0+aHduZExpc3RCb3gsIFNXX0hJREUpOwoJICAgIGJyZWFrOwoJY2FzZSBXTV9LSUxMRk9DVVM6CgkgICAgaWYgKChUaGlzLT5vcHRpb25zICYmIEFDT19BVVRPU1VHR0VTVCkgJiYgCgkJKChIV05EKXdQYXJhbSAhPSBUaGlzLT5od25kTGlzdEJveCkpCgkgICAgewoJCVNob3dXaW5kb3coVGhpcy0+aHduZExpc3RCb3gsIFNXX0hJREUpOwoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgV01fS0VZVVA6CgkgICAgCgkgICAgR2V0V2luZG93VGV4dFcoIGh3bmQsIChMUFdTVFIpaHduZFRleHQsIDI1NSk7CiAgICAgIAoJICAgIHN3aXRjaCh3UGFyYW0pIHsKCQljYXNlIFZLX1JFVFVSTjoKCQkgICAgLyogSWYgcXVpY2tDb21wbGV0ZSBpcyBzZXQgYW5kIGNvbnRyb2wgaXMgcHJlc3NlZCwgcmVwbGFjZSB0aGUgc3RyaW5nICovCgkJICAgIGNvbnRyb2wgPSBHZXRLZXlTdGF0ZShWS19DT05UUk9MKSAmIDB4ODAwMDsJCSAgICAKCQkgICAgaWYgKGNvbnRyb2wgJiYgVGhpcy0+cXVpY2tDb21wbGV0ZSkgewoJCQlod25kUUNUZXh0ID0gKFdDSEFSKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgCgkJCQkJCSAgICAgICAobHN0cmxlblcoVGhpcy0+cXVpY2tDb21wbGV0ZSkrbHN0cmxlblcoaHduZFRleHQpKSpzaXplb2YoV0NIQVIpKTsKCQkJc2VsID0gc3ByaW50ZlcoaHduZFFDVGV4dCwgVGhpcy0+cXVpY2tDb21wbGV0ZSwgaHduZFRleHQpOwoJCQlTZW5kTWVzc2FnZVcoaHduZCwgV01fU0VUVEVYVCwgMCwgKExQQVJBTSlod25kUUNUZXh0KTsKCQkJU2VuZE1lc3NhZ2VXKGh3bmQsIEVNX1NFVFNFTCwgMCwgc2VsKTsKCQkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgaHduZFFDVGV4dCk7CgkJICAgIH0KCgkJICAgIFNob3dXaW5kb3coVGhpcy0+aHduZExpc3RCb3gsIFNXX0hJREUpOwoJCSAgICByZXR1cm4gMDsKCQljYXNlIFZLX0xFRlQ6CgkJY2FzZSBWS19SSUdIVDoKCQkgICAgcmV0dXJuIDA7CgkJY2FzZSBWS19VUDoJICAgICAgCgkJY2FzZSBWS19ET1dOOgoJCSAgICAvKiBUd28gY2FzZXMgaGVyZSA6IAoJCSAgICAgICAtIGlmIHRoZSBsaXN0Ym94IGlzIG5vdCB2aXNpYmxlLCBkaXNwbGF5cyBpdCAKCQkgICAgICAgd2l0aCBhbGwgdGhlIGVudHJpZXMgaWYgdGhlIHN0eWxlIEFDT19VUERPV05LRVlEUk9QU0xJU1QKCQkgICAgICAgaXMgcHJlc2VudCBidXQgZG9lcyBub3Qgc2VsZWN0IGFueXRoaW5nLgoJCSAgICAgICAtIGlmIHRoZSBsaXN0Ym94IGlzIHZpc2libGUsIGNoYW5nZSB0aGUgc2VsZWN0aW9uCgkJICAgICovCgkJICAgIGlmICggKFRoaXMtPm9wdGlvbnMgJiAoQUNPX0FVVE9TVUdHRVNUIHwgQUNPX1VQRE9XTktFWURST1BTTElTVCkpIAoJCQkgJiYgKCFJc1dpbmRvd1Zpc2libGUoVGhpcy0+aHduZExpc3RCb3gpICYmICghICpod25kVGV4dCkpICkKCQkgICAgewoJCQkgLyogV2UgbXVzdCBkaXNwYXlzIGFsbCB0aGUgZW50cmllcyAqLwoJCQkgZGlzcGxheWFsbCA9IFRSVUU7CgkJICAgIH0gZWxzZSB7CgkJCWlmIChJc1dpbmRvd1Zpc2libGUoVGhpcy0+aHduZExpc3RCb3gpKSB7CgkJCSAgICBpbnQgY291bnQ7CgoJCQkgICAgY291bnQgPSBTZW5kTWVzc2FnZVcoVGhpcy0+aHduZExpc3RCb3gsIExCX0dFVENPVU5ULCAwLCAwKTsKCQkJICAgIC8qIENoYW5nZSB0aGUgc2VsZWN0aW9uICovCgkJCSAgICBzZWwgPSBTZW5kTWVzc2FnZVcoVGhpcy0+aHduZExpc3RCb3gsIExCX0dFVENVUlNFTCwgMCwgMCk7CgkJCSAgICBpZiAod1BhcmFtID09IFZLX1VQKQoJCQkJc2VsID0gKChzZWwtMSk8MCk/Y291bnQtMTpzZWwtMTsKCQkJICAgIGVsc2UKCQkJCXNlbCA9ICgoc2VsKzEpPj0gY291bnQpPy0xOnNlbCsxOwoJCQkgICAgU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRMaXN0Qm94LCBMQl9TRVRDVVJTRUwsIHNlbCwgMCk7CgkJCSAgICBpZiAoc2VsICE9IC0xKSB7CgkJCQlXQ0hBUiAqbXNnOwoJCQkJaW50IGxlbjsKCQkJCQoJCQkJbGVuID0gU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRMaXN0Qm94LCBMQl9HRVRURVhUTEVOLCBzZWwsIChMUEFSQU0pTlVMTCk7CgkJCQltc2cgPSAoV0NIQVIqKSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgKGxlbisxKSpzaXplb2YoV0NIQVIpKTsKCQkJCVNlbmRNZXNzYWdlVyhUaGlzLT5od25kTGlzdEJveCwgTEJfR0VUVEVYVCwgc2VsLCAoTFBBUkFNKW1zZyk7CgkJCQlTZW5kTWVzc2FnZVcoaHduZCwgV01fU0VUVEVYVCwgMCwgKExQQVJBTSltc2cpOwoJCQkJU2VuZE1lc3NhZ2VXKGh3bmQsIEVNX1NFVFNFTCwgbHN0cmxlblcobXNnKSwgbHN0cmxlblcobXNnKSk7CgkJCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtc2cpOwoJCQkgICAgfSBlbHNlIHsKCQkJCVNlbmRNZXNzYWdlVyhod25kLCBXTV9TRVRURVhULCAwLCAoTFBBUkFNKVRoaXMtPnR4dGJhY2t1cCk7CgkJCQlTZW5kTWVzc2FnZVcoaHduZCwgRU1fU0VUU0VMLCBsc3RybGVuVyhUaGlzLT50eHRiYWNrdXApLCBsc3RybGVuVyhUaGlzLT50eHRiYWNrdXApKTsKCQkJICAgIH0JCQkKCQkJfSAJCQoJCQlyZXR1cm4gMDsKCQkgICAgfQoJCSAgICBicmVhazsKCQljYXNlIFZLX0JBQ0s6CgkJY2FzZSBWS19ERUxFVEU6CgkJICAgIGlmICgoISAqaHduZFRleHQpICYmIChUaGlzLT5vcHRpb25zICYgQUNPX0FVVE9TVUdHRVNUKSkgewoJCQlTaG93V2luZG93KFRoaXMtPmh3bmRMaXN0Qm94LCBTV19ISURFKTsKCQkJcmV0dXJuIENhbGxXaW5kb3dQcm9jVyhUaGlzLT53cE9yaWdFZGl0UHJvYywgaHduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwoJCSAgICB9CgkJICAgIGlmIChUaGlzLT5vcHRpb25zICYgQUNPX0FVVE9BUFBFTkQpIHsKCQkJRFdPUkQgYjsKCQkJU2VuZE1lc3NhZ2VXKGh3bmQsIEVNX0dFVFNFTCwgKFdQQVJBTSkmYiwgKExQQVJBTSlOVUxMKTsKCQkJaWYgKGI+MSkgewoJCQkgICAgaHduZFRleHRbYi0xXSA9ICdcMCc7CgkJCX0gZWxzZSB7CgkJCSAgICBod25kVGV4dFswXSA9ICdcMCc7CgkJCSAgICBTZXRXaW5kb3dUZXh0Vyhod25kLCBod25kVGV4dCk7IAoJCQl9CQkJCgkJICAgIH0KCQkgICAgYnJlYWs7CgkJZGVmYXVsdDoJCSAgICAKCQkgICAgOwoJICAgIH0KICAgICAgCgkgICAgU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRMaXN0Qm94LCBMQl9SRVNFVENPTlRFTlQsIDAsIDApOwoKCSAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT50eHRiYWNrdXApOwoJICAgIFRoaXMtPnR4dGJhY2t1cCA9IChXQ0hBUiopIEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLAoJCQkJCQkgSEVBUF9aRVJPX01FTU9SWSwgKGxzdHJsZW5XKGh3bmRUZXh0KSsxKSpzaXplb2YoV0NIQVIpKTsJCQkJCQkJICAgICAgCgkgICAgbHN0cmNweVcoVGhpcy0+dHh0YmFja3VwLCBod25kVGV4dCk7CgoJICAgIC8qIFJldHVybnMgaWYgdGhlcmUgaXMgbm8gdGV4dCB0byBzZWFyY2ggYW5kIHdlIGRvZXNuJ3Qgd2FudCB0byBkaXNwbGF5IGFsbCB0aGUgZW50cmllcyAqLwoJICAgIGlmICgoIWRpc3BsYXlhbGwpICYmICghICpod25kVGV4dCkgKQoJCWJyZWFrOwoJICAgIAoJICAgIElFbnVtU3RyaW5nX1Jlc2V0KFRoaXMtPmVudW1zdHIpOwoJICAgIGZpbGxlZCA9IEZBTFNFOwoJICAgIGZvcihjcHQgPSAwOzspIHsKCQlociA9IElFbnVtU3RyaW5nX05leHQoVGhpcy0+ZW51bXN0ciwgMSwgJnN0cnMsIE5VTEwpOwoJCWlmIChociAhPSBTX09LKQoJCSAgICBicmVhazsKCgkJaWYgKChMUFdTVFIpc3Ryc3RyVyhzdHJzLCBod25kVGV4dCkgPT0gc3RycykgewoJCSAgICAKCQkgICAgaWYgKFRoaXMtPm9wdGlvbnMgJiBBQ09fQVVUT0FQUEVORCkgewoJCQlTZXRXaW5kb3dUZXh0Vyhod25kLCBzdHJzKTsKCQkJU2VuZE1lc3NhZ2VXKGh3bmQsIEVNX1NFVFNFTCwgbHN0cmxlblcoaHduZFRleHQpLCBsc3RybGVuVyhzdHJzKSk7CgkJCWJyZWFrOwoJCSAgICB9CQkKCgkJICAgIGlmIChUaGlzLT5vcHRpb25zICYgQUNPX0FVVE9TVUdHRVNUKSB7CgkJCVNlbmRNZXNzYWdlVyhUaGlzLT5od25kTGlzdEJveCwgTEJfQUREU1RSSU5HLCAwLCAoTFBBUkFNKXN0cnMpOwoJCQlmaWxsZWQgPSBUUlVFOwoJCQljcHQrKzsKCQkgICAgfQoJCX0JCQoJICAgIH0KCSAgICAKCSAgICBpZiAoVGhpcy0+b3B0aW9ucyAmIEFDT19BVVRPU1VHR0VTVCkgewoJCWlmIChmaWxsZWQpIHsKCQkgICAgaGVpZ2h0ID0gU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRMaXN0Qm94LCBMQl9HRVRJVEVNSEVJR0hULCAwLCAwKTsKCQkgICAgU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRMaXN0Qm94LCBMQl9DQVJFVE9GRiwgMCwgMCk7CgkJICAgIEdldFdpbmRvd1JlY3QoaHduZCwgJnIpOwoJCSAgICBTZXRQYXJlbnQoVGhpcy0+aHduZExpc3RCb3gsIEhXTkRfREVTS1RPUCk7CgkJICAgIC8qIEl0IHNlZW1zIHRoYXQgV2luZG93cyBYUCBkaXNwbGF5cyA3IGxpbmVzIGF0IG1vc3QgCgkJICAgICAgIGFuZCBvdGhlcndpc2UgZGlzcGxheXMgYSB2ZXJ0aWNhbCBzY3JvbGwgYmFyICovCgkJICAgIFNldFdpbmRvd1BvcyhUaGlzLT5od25kTGlzdEJveCwgSFdORF9UT1AsIAoJCQkJIHIubGVmdCwgci5ib3R0b20gKyAxLCByLnJpZ2h0IC0gci5sZWZ0LCBtaW4oaGVpZ2h0ICogNywgaGVpZ2h0KihjcHQrMSkpLCAKCQkJCSBTV1BfU0hPV1dJTkRPVyApOwoJCX0gZWxzZSB7CgkJICAgIFNob3dXaW5kb3coVGhpcy0+aHduZExpc3RCb3gsIFNXX0hJREUpOwoJCX0KCSAgICB9CgkgICAgCgkgICAgYnJlYWs7IAoJZGVmYXVsdDoKCSAgICByZXR1cm4gQ2FsbFdpbmRvd1Byb2NXKFRoaXMtPndwT3JpZ0VkaXRQcm9jLCBod25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7CgkgICAgCiAgICB9CgogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBMUkVTVUxUIEFQSUVOVFJZIEFDTEJveFN1YmNsYXNzUHJvYyhIV05EIGh3bmQsIFVJTlQgdU1zZywgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogICAgSUF1dG9Db21wbGV0ZUltcGwgKlRoaXMgPSAoSUF1dG9Db21wbGV0ZUltcGwgKilHZXRXaW5kb3dMb25nUHRyVyhod25kLCBHV0xQX1VTRVJEQVRBKTsKICAgIFdDSEFSICptc2c7CiAgICBpbnQgc2VsID0gLTEsIGxlbjsKCiAgICBzd2l0Y2ggKHVNc2cpIHsKCWNhc2UgV01fTU9VU0VNT1ZFOgoJICAgIHNlbCA9IFNlbmRNZXNzYWdlVyhod25kLCBMQl9JVEVNRlJPTVBPSU5ULCAwLCBsUGFyYW0pOwoJICAgIFNlbmRNZXNzYWdlVyhod25kLCBMQl9TRVRDVVJTRUwsIChXUEFSQU0pc2VsLCAoTFBBUkFNKTApOwoJICAgIGJyZWFrOwoJY2FzZSBXTV9MQlVUVE9ORE9XTjoKCSAgICBsZW4gPSBTZW5kTWVzc2FnZVcoVGhpcy0+aHduZExpc3RCb3gsIExCX0dFVFRFWFRMRU4sIHNlbCwgKExQQVJBTSlOVUxMKTsKCSAgICBtc2cgPSAoV0NIQVIqKSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgKGxlbisxKSpzaXplb2YoV0NIQVIpKTsKCSAgICBzZWwgPSAoSU5UKVNlbmRNZXNzYWdlVyhod25kLCBMQl9HRVRDVVJTRUwsIDAsIDApOwoJICAgIFNlbmRNZXNzYWdlVyhod25kLCBMQl9HRVRURVhULCBzZWwsIChMUEFSQU0pbXNnKTsKCSAgICBTZW5kTWVzc2FnZVcoVGhpcy0+aHduZEVkaXQsIFdNX1NFVFRFWFQsIDAsIChMUEFSQU0pbXNnKTsKCSAgICBTZW5kTWVzc2FnZVcoVGhpcy0+aHduZEVkaXQsIEVNX1NFVFNFTCwgMCwgbHN0cmxlblcobXNnKSk7CgkgICAgU2hvd1dpbmRvdyhod25kLCBTV19ISURFKTsKCSAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtc2cpOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICByZXR1cm4gQ2FsbFdpbmRvd1Byb2NXKFRoaXMtPndwT3JpZ0xCb3hQcm9jLCBod25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7CiAgICB9CiAgICByZXR1cm4gMDsKfQo=