LyoKICoJQXV0b0NvbXBsZXRlIGludGVyZmFjZXMgaW1wbGVtZW50YXRpb24uCiAqCiAqCUNvcHlyaWdodCAyMDA0CU1heGltZSBCZWxsZW5n6SA8bWF4aW1lLmJlbGxlbmdlQGxhcG9zdGUubmV0PgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgovKgogIEltcGxlbWVudGVkOgogIC0gQUNPX0FVVE9BUFBFTkQgc3R5bGUKICAtIEFDT19BVVRPU1VHR0VTVCBzdHlsZQogIC0gQUNPX1VQRE9XTktFWURST1BTTElTVCBzdHlsZQoKICAtIEhhbmRsZSBwd3pzUmVnS2V5UGF0aCBhbmQgcHdzelF1aWNrQ29tcGxldGUgaW4gSW5pdAoKICBUT0RPOgogIC0gaW1wbGVtZW50IEFDT19TRUFSQ0ggc3R5bGUKICAtIGltcGxlbWVudCBBQ09fRklMVEVSUFJFRklYRVMgc3R5bGUKICAtIGltcGxlbWVudCBBQ09fVVNFVEFCIHN0eWxlCiAgLSBpbXBsZW1lbnQgQUNPX1JUTFJFQURJTkcgc3R5bGUKICAKICovCiNpbmNsdWRlICJjb25maWcuaCIKCiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAidW5kb2NzaGVsbC5oIgojaW5jbHVkZSAic2hsd2FwaS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm9iamJhc2UuaCIKCiNpbmNsdWRlICJwaWRsLmgiCiNpbmNsdWRlICJzaGxndWlkLmgiCiNpbmNsdWRlICJzaGxvYmouaCIKI2luY2x1ZGUgInNobGRpc3AuaCIKI2luY2x1ZGUgImRlYnVnaGxwLmgiCgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChzaGVsbCk7Cgp0eXBlZGVmIHN0cnVjdAp7CiAgICBJQXV0b0NvbXBsZXRlVnRibCAgKmxwVnRibDsKICAgIElBdXRvQ29tcGxldGUyVnRibCAqbHB2dGJsQXV0b0NvbXBsZXRlMjsKICAgIERXT1JEIHJlZjsKICAgIEJPT0wgIGVuYWJsZWQ7CiAgICBIV05EIGh3bmRFZGl0OwogICAgSFdORCBod25kTGlzdEJveDsKICAgIFdORFBST0Mgd3BPcmlnRWRpdFByb2M7CiAgICBXTkRQUk9DIHdwT3JpZ0xCb3hQcm9jOwogICAgV0NIQVIgKnR4dGJhY2t1cDsKICAgIFdDSEFSICpxdWlja0NvbXBsZXRlOwogICAgSUVudW1TdHJpbmcgKmVudW1zdHI7CiAgICBBVVRPQ09NUExFVEVPUFRJT05TIG9wdGlvbnM7Cn0gSUF1dG9Db21wbGV0ZUltcGw7CgpzdGF0aWMgc3RydWN0IElBdXRvQ29tcGxldGVWdGJsIGFjdnQ7CnN0YXRpYyBzdHJ1Y3QgSUF1dG9Db21wbGV0ZTJWdGJsIGFjMnZ0OwoKI2RlZmluZSBfSUF1dG9Db21wbGV0ZTJfT2Zmc2V0ICgoaW50KSgmKCgoSUF1dG9Db21wbGV0ZUltcGwqKTApLT5scHZ0YmxBdXRvQ29tcGxldGUyKSkpCiNkZWZpbmUgX0lDT01fVEhJU19Gcm9tX0lBdXRvQ29tcGxldGUyKGNsYXNzLCBuYW1lKSBjbGFzcyogVGhpcyA9IChjbGFzcyopKCgoY2hhciopbmFtZSktX0lBdXRvQ29tcGxldGUyX09mZnNldCk7CgovKgogIGNvbnZlcnRzIFRoaXMgdG8gYSBpbnRlcmZhY2UgcG9pbnRlcgoqLwojZGVmaW5lIF9JVW5rbm93bl8oVGhpcykgKElVbmtub3duKikmKFRoaXMtPmxwVnRibCkKI2RlZmluZSBfSUF1dG9Db21wbGV0ZTJfKFRoaXMpICAoSUF1dG9Db21wbGV0ZTIqKSYoVGhpcy0+bHB2dGJsQXV0b0NvbXBsZXRlMikgCgpzdGF0aWMgTFJFU1VMVCBBUElFTlRSWSBBQ0VkaXRTdWJjbGFzc1Byb2MoSFdORCBod25kLCBVSU5UIHVNc2csIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0pOwpzdGF0aWMgTFJFU1VMVCBBUElFTlRSWSBBQ0xCb3hTdWJjbGFzc1Byb2MoSFdORCBod25kLCBVSU5UIHVNc2csIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0pOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBJQXV0b0NvbXBsZXRlX0NvbnN0cnVjdG9yCiAqLwpIUkVTVUxUIFdJTkFQSSBJQXV0b0NvbXBsZXRlX0NvbnN0cnVjdG9yKElVbmtub3duICogcFVua091dGVyLCBSRUZJSUQgcmlpZCwgTFBWT0lEICogcHB2KQp7CiAgICBJQXV0b0NvbXBsZXRlSW1wbCAqbHBhYzsKCiAgICBpZiAocFVua091dGVyICYmICFJc0VxdWFsSUlEIChyaWlkLCAmSUlEX0lVbmtub3duKSkKCXJldHVybiBDTEFTU19FX05PQUdHUkVHQVRJT047CgogICAgbHBhYyA9IChJQXV0b0NvbXBsZXRlSW1wbCopSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksCiAgICAgIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJQXV0b0NvbXBsZXRlSW1wbCkpOwogICAgaWYgKCFscGFjKSAKCXJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIGxwYWMtPnJlZiA9IDE7CiAgICBscGFjLT5scFZ0YmwgPSAmYWN2dDsKICAgIGxwYWMtPmxwdnRibEF1dG9Db21wbGV0ZTIgPSAmYWMydnQ7CiAgICBscGFjLT5lbmFibGVkID0gVFJVRTsKICAgIGxwYWMtPmVudW1zdHIgPSBOVUxMOwogICAgbHBhYy0+b3B0aW9ucyA9IEFDT19BVVRPQVBQRU5EOwogICAgbHBhYy0+d3BPcmlnRWRpdFByb2MgPSBOVUxMOwogICAgbHBhYy0+aHduZExpc3RCb3ggPSBOVUxMOwogICAgbHBhYy0+dHh0YmFja3VwID0gTlVMTDsKICAgIGxwYWMtPnF1aWNrQ29tcGxldGUgPSBOVUxMOwogICAgCiAgICBpZiAoIVNVQ0NFRURFRCAoSVVua25vd25fUXVlcnlJbnRlcmZhY2UgKF9JVW5rbm93bl8gKGxwYWMpLCByaWlkLCBwcHYpKSkgewoJSVVua25vd25fUmVsZWFzZSAoX0lVbmtub3duXyAobHBhYykpOwoJcmV0dXJuIEVfTk9JTlRFUkZBQ0U7CiAgICB9CiAgICAKICAgIFRSQUNFKCItLSAoJXApLT5cbiIsbHBhYyk7CgogICAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgQXV0b0NvbXBsZXRlX1F1ZXJ5SW50ZXJmYWNlCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUF1dG9Db21wbGV0ZV9mblF1ZXJ5SW50ZXJmYWNlKAogICAgSUF1dG9Db21wbGV0ZSAqIGlmYWNlLAogICAgUkVGSUlEIHJpaWQsCiAgICBMUFZPSUQgKnBwdk9iaikKewogICAgSUNPTV9USElTKElBdXRvQ29tcGxldGVJbXBsLCBpZmFjZSk7CiAgICAKICAgIFRSQUNFKCIoJXApLT4oXG5cdElJRDpcdCVzLCVwKVxuIiwgVGhpcywgc2hkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBwcHZPYmopOwogICAgKnBwdk9iaiA9IE5VTEw7CgogICAgaWYoSXNFcXVhbElJRChyaWlkLCAmSUlEX0lVbmtub3duKSkgCiAgICB7CgkqcHB2T2JqID0gVGhpczsKICAgIH0gCiAgICBlbHNlIGlmKElzRXF1YWxJSUQocmlpZCwgJklJRF9JQXV0b0NvbXBsZXRlKSkKICAgIHsKCSpwcHZPYmogPSAoSUF1dG9Db21wbGV0ZSopVGhpczsKICAgIH0KICAgIGVsc2UgaWYoSXNFcXVhbElJRChyaWlkLCAmSUlEX0lBdXRvQ29tcGxldGUyKSkKICAgIHsKCSpwcHZPYmogPSBfSUF1dG9Db21wbGV0ZTJfIChUaGlzKTsKICAgIH0KCiAgICBpZiAoKnBwdk9iaikKICAgIHsKCUlBdXRvQ29tcGxldGVfQWRkUmVmKChJQXV0b0NvbXBsZXRlKikqcHB2T2JqKTsKCVRSQUNFKCItLSBJbnRlcmZhY2U6ICglcCktPiglcClcbiIsIHBwdk9iaiwgKnBwdk9iaik7CglyZXR1cm4gU19PSzsKICAgIH0KICAgIFRSQUNFKCItLSBJbnRlcmZhY2U6IEVfTk9JTlRFUkZBQ0VcbiIpOwogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7CQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElBdXRvQ29tcGxldGVfZm5BZGRSZWYKICovCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUF1dG9Db21wbGV0ZV9mbkFkZFJlZigKCUlBdXRvQ29tcGxldGUgKiBpZmFjZSkKewogICAgSUNPTV9USElTKElBdXRvQ29tcGxldGVJbXBsLGlmYWNlKTsKICAgIAogICAgVFJBQ0UoIiglcCktPiglbHUpXG4iLFRoaXMsVGhpcy0+cmVmKTsKICAgIHJldHVybiArKyhUaGlzLT5yZWYpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElBdXRvQ29tcGxldGVfZm5SZWxlYXNlCiAqLwpzdGF0aWMgVUxPTkcgV0lOQVBJIElBdXRvQ29tcGxldGVfZm5SZWxlYXNlKAoJSUF1dG9Db21wbGV0ZSAqIGlmYWNlKQp7CiAgICBJQ09NX1RISVMoSUF1dG9Db21wbGV0ZUltcGwsaWZhY2UpOwogICAgCiAgICBUUkFDRSgiKCVwKS0+KCVsdSlcbiIsVGhpcyxUaGlzLT5yZWYpOwoKICAgIGlmICghLS0oVGhpcy0+cmVmKSkgewoJVFJBQ0UoIiBkZXN0cm95aW5nIElBdXRvQ29tcGxldGUoJXApXG4iLFRoaXMpOwoJaWYgKFRoaXMtPnF1aWNrQ29tcGxldGUpCgkgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cXVpY2tDb21wbGV0ZSk7CglpZiAoVGhpcy0+dHh0YmFja3VwKQoJICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnR4dGJhY2t1cCk7CglpZiAoVGhpcy0+aHduZExpc3RCb3gpCgkgICAgRGVzdHJveVdpbmRvdyhUaGlzLT5od25kTGlzdEJveCk7CglpZiAoVGhpcy0+ZW51bXN0cikKCSAgICBJRW51bVN0cmluZ19SZWxlYXNlKFRoaXMtPmVudW1zdHIpOwoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CglyZXR1cm4gMDsKICAgIH0KICAgIHJldHVybiBUaGlzLT5yZWY7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUF1dG9Db21wbGV0ZV9mbkVuYWJsZQogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBdXRvQ29tcGxldGVfZm5FbmFibGUoCiAgICBJQXV0b0NvbXBsZXRlICogaWZhY2UsCiAgICBCT09MIGZFbmFibGUpCnsKICAgIElDT01fVEhJUyhJQXV0b0NvbXBsZXRlSW1wbCwgaWZhY2UpOwoKICAgIEhSRVNVTFQgaHIgPSBTX09LOwoKICAgIFRSQUNFKCIoJXApLT4oJXMpXG4iLCBUaGlzLCAoZkVuYWJsZSk/InRydWUiOiJmYWxzZSIpOwoKICAgIFRoaXMtPmVuYWJsZWQgPSBmRW5hYmxlOwoKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJQXV0b0NvbXBsZXRlX2ZuSW5pdAogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBdXRvQ29tcGxldGVfZm5Jbml0KAogICAgSUF1dG9Db21wbGV0ZSAqIGlmYWNlLAogICAgSFdORCBod25kRWRpdCwKICAgIElVbmtub3duICpwdW5rQUNMLAogICAgTFBDT0xFU1RSIHB3enNSZWdLZXlQYXRoLAogICAgTFBDT0xFU1RSIHB3c3pRdWlja0NvbXBsZXRlKQp7CiAgICBJQ09NX1RISVMoSUF1dG9Db21wbGV0ZUltcGwsIGlmYWNlKTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBsYk5hbWVbXSA9IHsnTCcsJ2knLCdzJywndCcsJ0InLCdvJywneCcsMH07CgogICAgVFJBQ0UoIiglcCktPigweCUwOGx4LCAlcCwgJXMsICVzKVxuIiwgCgkgIFRoaXMsIChsb25nKWh3bmRFZGl0LCBwdW5rQUNMLCBkZWJ1Z3N0cl93KHB3enNSZWdLZXlQYXRoKSwgZGVidWdzdHJfdyhwd3N6UXVpY2tDb21wbGV0ZSkpOwoKICAgIGlmIChUaGlzLT5vcHRpb25zICYgQUNPX0FVVE9TVUdHRVNUKSBUUkFDRSgiIEFDT19BVVRPU1VHR0VTVFxuIik7CiAgICBpZiAoVGhpcy0+b3B0aW9ucyAmIEFDT19BVVRPQVBQRU5EKSBUUkFDRSgiIEFDT19BVVRPQVBQRU5EXG4iKTsKICAgIGlmIChUaGlzLT5vcHRpb25zICYgQUNPX1NFQVJDSCkgRklYTUUoIiBBQ09fU0VBUkNIIG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgaWYgKFRoaXMtPm9wdGlvbnMgJiBBQ09fRklMVEVSUFJFRklYRVMpIEZJWE1FKCIgQUNPX0ZJTFRFUlBSRUZJWEVTIG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgaWYgKFRoaXMtPm9wdGlvbnMgJiBBQ09fVVNFVEFCKSBGSVhNRSgiIEFDT19VU0VUQUIgbm90IHN1cHBvcnRlZFxuIik7CiAgICBpZiAoVGhpcy0+b3B0aW9ucyAmIEFDT19VUERPV05LRVlEUk9QU0xJU1QpIFRSQUNFKCIgQUNPX1VQRE9XTktFWURST1BTTElTVFxuIik7CiAgICBpZiAoVGhpcy0+b3B0aW9ucyAmIEFDT19SVExSRUFESU5HKSBGSVhNRSgiIEFDT19SVExSRUFESU5HIG5vdCBzdXBwb3J0ZWRcbiIpOwoKICAgIFRoaXMtPmh3bmRFZGl0ID0gaHduZEVkaXQ7CgogICAgaWYgKCFTVUNDRUVERUQgKElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlIChwdW5rQUNMLCAmSUlEX0lFbnVtU3RyaW5nLCAoTFBWT0lEKikmVGhpcy0+ZW51bXN0cikpKSB7CglUUkFDRSgiTm8gSUVudW1TdHJpbmcgaW50ZXJmYWNlXG4iKTsKCXJldHVybiAgRV9OT0lOVEVSRkFDRTsKICAgIH0KCiAgICBUaGlzLT53cE9yaWdFZGl0UHJvYyA9IChXTkRQUk9DKSBTZXRXaW5kb3dMb25nUHRyVyggaHduZEVkaXQsIEdXTFBfV05EUFJPQywgKExPTkdfUFRSKSBBQ0VkaXRTdWJjbGFzc1Byb2MpOwogICAgU2V0V2luZG93TG9uZ1B0clcoIGh3bmRFZGl0LCBHV0xQX1VTRVJEQVRBLCAoTE9OR19QVFIpVGhpcyk7CgogICAgaWYgKFRoaXMtPm9wdGlvbnMgJiBBQ09fQVVUT1NVR0dFU1QpIHsKCUhXTkQgaHduZFBhcmVudDsKCglod25kUGFyZW50ID0gR2V0UGFyZW50KFRoaXMtPmh3bmRFZGl0KTsKCQoJLyogRklYTUUgOiBUaGUgbGlzdGJveCBzaG91bGQgYmUgcmVzaXphYmxlIHdpdGggdGhlIG1vdXNlLiBXU19USElDS0ZSQU1FIGxvb2tzIHVnbHkgKi8KCVRoaXMtPmh3bmRMaXN0Qm94ID0gQ3JlYXRlV2luZG93RXhXKDAsIGxiTmFtZSwgTlVMTCwgCgkJCQkJICAgIFdTX0JPUkRFUiB8IFdTX0NISUxEIHwgV1NfVlNDUk9MTCB8IExCU19IQVNTVFJJTkdTIHwgTEJTX05PVElGWSB8IExCU19OT0lOVEVHUkFMSEVJR0hULCAKCQkJCQkgICAgQ1dfVVNFREVGQVVMVCwgQ1dfVVNFREVGQVVMVCwgQ1dfVVNFREVGQVVMVCwgQ1dfVVNFREVGQVVMVCwKCQkJCQkgICAgaHduZFBhcmVudCwgTlVMTCwgCgkJCQkJICAgIChISU5TVEFOQ0UpR2V0V2luZG93TG9uZ0EoIGh3bmRQYXJlbnQsIEdXTF9ISU5TVEFOQ0UgKSwgTlVMTCk7CgkJCQkJICAgIAoJaWYgKFRoaXMtPmh3bmRMaXN0Qm94KSB7CgkgICAgVGhpcy0+d3BPcmlnTEJveFByb2MgPSAoV05EUFJPQykgU2V0V2luZG93TG9uZ1B0clcoIFRoaXMtPmh3bmRMaXN0Qm94LCBHV0xQX1dORFBST0MsIChMT05HX1BUUikgQUNMQm94U3ViY2xhc3NQcm9jKTsKCSAgICBTZXRXaW5kb3dMb25nUHRyVyggVGhpcy0+aHduZExpc3RCb3gsIEdXTFBfVVNFUkRBVEEsIChMT05HX1BUUilUaGlzKTsKCX0KICAgIH0KCiAgICBpZiAocHd6c1JlZ0tleVBhdGgpIHsKCVdDSEFSICprZXk7CglXQ0hBUiByZXN1bHRbTUFYX1BBVEhdOwoJV0NIQVIgKnZhbHVlOwoJSEtFWSBoS2V5ID0gMDsKCUxPTkcgcmVzOwoJTE9ORyBsZW47CgoJLyogcHdzelJlZ0tleVBhdGggY29udGFpbnMgdGhlIGtleSBhcyB3ZWxsIGFzIHRoZSB2YWx1ZSwgc28gd2Ugc3BsaXQgKi8KCWtleSA9IChXQ0hBUiopSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIChsc3RybGVuVyhwd3pzUmVnS2V5UGF0aCkrMSkqc2l6ZW9mKFdDSEFSKSk7CglzdHJjcHlXKGtleSwgcHd6c1JlZ0tleVBhdGgpOwoJdmFsdWUgPSBzdHJyY2hyVyhrZXksICdcXCcpOwoJKnZhbHVlID0gMDsKCXZhbHVlKys7CgkvKiBOb3cgdmFsdWUgY29udGFpbnMgdGhlIHZhbHVlIGFuZCBidWZmZXIgdGhlIGtleSAqLwoJcmVzID0gUmVnT3BlbktleUV4VyhIS0VZX0NVUlJFTlRfVVNFUiwga2V5LCAwLCBLRVlfUkVBRCwgJmhLZXkpOwoJaWYgKHJlcyAhPSBFUlJPUl9TVUNDRVNTKSB7CgkgICAgLyogaWYgdGhlIGtleSBpcyBub3QgZm91bmQsIE1TRE4gc3RhdGVzIHdlIG11c3Qgc2VlayBpbiBIS0VZX0xPQ0FMX01BQ0hJTkUgKi8KCSAgICByZXMgPSBSZWdPcGVuS2V5RXhXKEhLRVlfTE9DQUxfTUFDSElORSwga2V5LCAwLCBLRVlfUkVBRCwgJmhLZXkpOyAgCgl9CglpZiAocmVzID09IEVSUk9SX1NVQ0NFU1MpIHsKCSAgICByZXMgPSBSZWdRdWVyeVZhbHVlVyhoS2V5LCB2YWx1ZSwgcmVzdWx0LCAmbGVuKTsKCSAgICBpZiAocmVzID09IEVSUk9SX1NVQ0NFU1MpIHsKCQlUaGlzLT5xdWlja0NvbXBsZXRlID0gKFdDSEFSKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgbGVuKnNpemVvZihXQ0hBUikpOwoJCXN0cmNweVcoVGhpcy0+cXVpY2tDb21wbGV0ZSwgcmVzdWx0KTsKCSAgICB9CgkgICAgUmVnQ2xvc2VLZXkoaEtleSk7Cgl9CglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBrZXkpOwogICAgfQoKICAgIGlmICgocHdzelF1aWNrQ29tcGxldGUpICYmICghVGhpcy0+cXVpY2tDb21wbGV0ZSkpIHsKCVRoaXMtPnF1aWNrQ29tcGxldGUgPSAoV0NIQVIqKUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCAobHN0cmxlblcocHdzelF1aWNrQ29tcGxldGUpKzEpKnNpemVvZihXQ0hBUikpOwoJbHN0cmNweVcoVGhpcy0+cXVpY2tDb21wbGV0ZSwgcHdzelF1aWNrQ29tcGxldGUpOwogICAgfQoKICAgIHJldHVybiBTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIElBdXRvQ29tcGxldGVfZm5WVGFibGUKICovCnN0YXRpYyBJQXV0b0NvbXBsZXRlVnRibCBhY3Z0ID0KewogICAgSUNPTV9NU1ZUQUJMRV9DT01QQVRfRHVtbXlSVFRJVkFMVUUKICAgIElBdXRvQ29tcGxldGVfZm5RdWVyeUludGVyZmFjZSwKICAgIElBdXRvQ29tcGxldGVfZm5BZGRSZWYsCiAgICBJQXV0b0NvbXBsZXRlX2ZuUmVsZWFzZSwKICAgIElBdXRvQ29tcGxldGVfZm5Jbml0LAogICAgSUF1dG9Db21wbGV0ZV9mbkVuYWJsZSwKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgQXV0b0NvbXBsZXRlMl9RdWVyeUludGVyZmFjZQogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBdXRvQ29tcGxldGUyX2ZuUXVlcnlJbnRlcmZhY2UoCiAgICBJQXV0b0NvbXBsZXRlMiAqIGlmYWNlLAogICAgUkVGSUlEIHJpaWQsCiAgICBMUFZPSUQgKnBwdk9iaikKewogICAgX0lDT01fVEhJU19Gcm9tX0lBdXRvQ29tcGxldGUyKElBdXRvQ29tcGxldGVJbXBsLCBpZmFjZSk7CgogICAgVFJBQ0UgKCIoJXApLT4oJXMsJXApXG4iLCBUaGlzLCBzaGRlYnVnc3RyX2d1aWQgKHJpaWQpLCBwcHZPYmopOwoKICAgIHJldHVybiBJQXV0b0NvbXBsZXRlX1F1ZXJ5SW50ZXJmYWNlKChJQXV0b0NvbXBsZXRlKilUaGlzLCByaWlkLCBwcHZPYmopOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElBdXRvQ29tcGxldGUyX2ZuQWRkUmVmCiAqLwpzdGF0aWMgVUxPTkcgV0lOQVBJIElBdXRvQ29tcGxldGUyX2ZuQWRkUmVmKAoJSUF1dG9Db21wbGV0ZTIgKiBpZmFjZSkKewogICAgX0lDT01fVEhJU19Gcm9tX0lBdXRvQ29tcGxldGUyKElBdXRvQ29tcGxldGVJbXBsLGlmYWNlKTsKCiAgICBUUkFDRSAoIiglcCktPihjb3VudD0lbHUpXG4iLCBUaGlzLCBUaGlzLT5yZWYpOwoKICAgIHJldHVybiBJQXV0b0NvbXBsZXRlMl9BZGRSZWYoKElBdXRvQ29tcGxldGUqKVRoaXMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElBdXRvQ29tcGxldGUyX2ZuUmVsZWFzZQogKi8Kc3RhdGljIFVMT05HIFdJTkFQSSBJQXV0b0NvbXBsZXRlMl9mblJlbGVhc2UoCglJQXV0b0NvbXBsZXRlMiAqIGlmYWNlKQp7CiAgICBfSUNPTV9USElTX0Zyb21fSUF1dG9Db21wbGV0ZTIoSUF1dG9Db21wbGV0ZUltcGwsaWZhY2UpOwoKICAgIFRSQUNFICgiKCVwKS0+KGNvdW50PSVsdSlcbiIsIFRoaXMsIFRoaXMtPnJlZik7CgogICAgcmV0dXJuIElBdXRvQ29tcGxldGVfUmVsZWFzZSgoSUF1dG9Db21wbGV0ZSopVGhpcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUF1dG9Db21wbGV0ZTJfZm5FbmFibGUKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQXV0b0NvbXBsZXRlMl9mbkVuYWJsZSgKICAgIElBdXRvQ29tcGxldGUyICogaWZhY2UsCiAgICBCT09MIGZFbmFibGUpCnsKICAgIF9JQ09NX1RISVNfRnJvbV9JQXV0b0NvbXBsZXRlMihJQXV0b0NvbXBsZXRlSW1wbCwgaWZhY2UpOwoKICAgIFRSQUNFICgiKCVwKS0+KCVzKVxuIiwgVGhpcywgKGZFbmFibGUpPyJ0cnVlIjoiZmFsc2UiKTsKCiAgICByZXR1cm4gSUF1dG9Db21wbGV0ZV9FbmFibGUoKElBdXRvQ29tcGxldGUqKVRoaXMsIGZFbmFibGUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElBdXRvQ29tcGxldGUyX2ZuSW5pdAogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBdXRvQ29tcGxldGUyX2ZuSW5pdCgKICAgIElBdXRvQ29tcGxldGUyICogaWZhY2UsCiAgICBIV05EIGh3bmRFZGl0LAogICAgSVVua25vd24gKnB1bmtBQ0wsCiAgICBMUENPTEVTVFIgcHd6c1JlZ0tleVBhdGgsCiAgICBMUENPTEVTVFIgcHdzelF1aWNrQ29tcGxldGUpCnsKICAgIF9JQ09NX1RISVNfRnJvbV9JQXV0b0NvbXBsZXRlMihJQXV0b0NvbXBsZXRlSW1wbCwgaWZhY2UpOwoKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICByZXR1cm4gSUF1dG9Db21wbGV0ZV9Jbml0KChJQXV0b0NvbXBsZXRlKilUaGlzLCBod25kRWRpdCwgcHVua0FDTCwgcHd6c1JlZ0tleVBhdGgsIHB3c3pRdWlja0NvbXBsZXRlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBJQXV0b0NvbXBsZXRlX2ZuR2V0T3B0aW9ucwogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBdXRvQ29tcGxldGUyX2ZuR2V0T3B0aW9ucygKICAgIElBdXRvQ29tcGxldGUyICogaWZhY2UsCiAgICBEV09SRCAqcGR3RmxhZykKewogICAgSFJFU1VMVCBociA9IFNfT0s7CgogICAgX0lDT01fVEhJU19Gcm9tX0lBdXRvQ29tcGxldGUyKElBdXRvQ29tcGxldGVJbXBsLCBpZmFjZSk7CgogICAgVFJBQ0UoIiglcCkgLT4gKCVwKVxuIiwgVGhpcywgcGR3RmxhZyk7CgogICAgKnBkd0ZsYWcgPSBUaGlzLT5vcHRpb25zOwoKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBJQXV0b0NvbXBsZXRlX2ZuU2V0T3B0aW9ucwogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBdXRvQ29tcGxldGUyX2ZuU2V0T3B0aW9ucygKICAgIElBdXRvQ29tcGxldGUyICogaWZhY2UsCiAgICBEV09SRCBkd0ZsYWcpCnsKICAgIEhSRVNVTFQgaHIgPSBTX09LOwoKICAgIF9JQ09NX1RISVNfRnJvbV9JQXV0b0NvbXBsZXRlMihJQXV0b0NvbXBsZXRlSW1wbCwgaWZhY2UpOwoKICAgIFRSQUNFKCIoJXApIC0+ICgweCVseClcbiIsIFRoaXMsIGR3RmxhZyk7CgogICAgVGhpcy0+b3B0aW9ucyA9IGR3RmxhZzsKCiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgSUF1dG9Db21wbGV0ZTJfZm5WVGFibGUKICovCnN0YXRpYyBJQXV0b0NvbXBsZXRlMlZ0YmwgYWMydnQgPQp7CiAgICBJQ09NX01TVlRBQkxFX0NPTVBBVF9EdW1teVJUVElWQUxVRQogICAgSUF1dG9Db21wbGV0ZTJfZm5RdWVyeUludGVyZmFjZSwKICAgIElBdXRvQ29tcGxldGUyX2ZuQWRkUmVmLAogICAgSUF1dG9Db21wbGV0ZTJfZm5SZWxlYXNlLAogICAgSUF1dG9Db21wbGV0ZTJfZm5Jbml0LAogICAgSUF1dG9Db21wbGV0ZTJfZm5FbmFibGUsCiAgICAvKiBJQXV0b0NvbXBsZXRlMiAqLwogICAgSUF1dG9Db21wbGV0ZTJfZm5TZXRPcHRpb25zLAogICAgSUF1dG9Db21wbGV0ZTJfZm5HZXRPcHRpb25zLAp9OwoKLyoKICBXaW5kb3cgcHJvY2VkdXJlIGZvciBhdXRvY29tcGxldGlvbgogKi8Kc3RhdGljIExSRVNVTFQgQVBJRU5UUlkgQUNFZGl0U3ViY2xhc3NQcm9jKEhXTkQgaHduZCwgVUlOVCB1TXNnLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBJQ09NX1RISVMoSUF1dG9Db21wbGV0ZUltcGwsIEdldFdpbmRvd0xvbmdQdHJXKGh3bmQsIEdXTFBfVVNFUkRBVEEpKTsKICAgIExQT0xFU1RSIHN0cnM7CiAgICBIUkVTVUxUIGhyOwogICAgV0NIQVIgaHduZFRleHRbMjU1XTsKICAgIFdDSEFSICpod25kUUNUZXh0OwogICAgUkVDVCByOwogICAgQk9PTCBjb250cm9sLCBmaWxsZWQsIGRpc3BsYXlhbGwgPSBGQUxTRTsKICAgIGludCBjcHQsIGhlaWdodCwgc2VsOwoKICAgIGlmICghVGhpcy0+ZW5hYmxlZCkgcmV0dXJuIENhbGxXaW5kb3dQcm9jVyhUaGlzLT53cE9yaWdFZGl0UHJvYywgaHduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwoKICAgIHN3aXRjaCAodU1zZykKICAgIHsKCWNhc2UgQ0JfU0hPV0RST1BET1dOOgoJICAgIFNob3dXaW5kb3coVGhpcy0+aHduZExpc3RCb3gsIFNXX0hJREUpOwoJICAgIGJyZWFrOwoJY2FzZSBXTV9LSUxMRk9DVVM6CgkgICAgaWYgKChUaGlzLT5vcHRpb25zICYmIEFDT19BVVRPU1VHR0VTVCkgJiYgCgkJKChIV05EKXdQYXJhbSAhPSBUaGlzLT5od25kTGlzdEJveCkpCgkgICAgewoJCVNob3dXaW5kb3coVGhpcy0+aHduZExpc3RCb3gsIFNXX0hJREUpOwoJICAgIH0KCSAgICBicmVhazsKCWNhc2UgV01fS0VZVVA6CgkgICAgCgkgICAgR2V0V2luZG93VGV4dFcoIGh3bmQsIChMUFdTVFIpaHduZFRleHQsIDI1NSk7CiAgICAgIAoJICAgIHN3aXRjaCh3UGFyYW0pIHsKCQljYXNlIFZLX1JFVFVSTjoKCQkgICAgLyogSWYgcXVpY2tDb21wbGV0ZSBpcyBzZXQgYW5kIGNvbnRyb2wgaXMgcHJlc3NlZCwgcmVwbGFjZSB0aGUgc3RyaW5nICovCgkJICAgIGNvbnRyb2wgPSBHZXRLZXlTdGF0ZShWS19DT05UUk9MKSAmIDB4ODAwMDsJCSAgICAKCQkgICAgaWYgKGNvbnRyb2wgJiYgVGhpcy0+cXVpY2tDb21wbGV0ZSkgewoJCQlod25kUUNUZXh0ID0gKFdDSEFSKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgCgkJCQkJCSAgICAgICAobHN0cmxlblcoVGhpcy0+cXVpY2tDb21wbGV0ZSkrbHN0cmxlblcoaHduZFRleHQpKSpzaXplb2YoV0NIQVIpKTsKCQkJc2VsID0gc3ByaW50ZlcoaHduZFFDVGV4dCwgVGhpcy0+cXVpY2tDb21wbGV0ZSwgaHduZFRleHQpOwoJCQlTZW5kTWVzc2FnZVcoaHduZCwgV01fU0VUVEVYVCwgMCwgKExQQVJBTSlod25kUUNUZXh0KTsKCQkJU2VuZE1lc3NhZ2VXKGh3bmQsIEVNX1NFVFNFTCwgMCwgc2VsKTsKCQkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgaHduZFFDVGV4dCk7CgkJICAgIH0KCgkJICAgIFNob3dXaW5kb3coVGhpcy0+aHduZExpc3RCb3gsIFNXX0hJREUpOwoJCSAgICByZXR1cm4gMDsKCQljYXNlIFZLX0xFRlQ6CgkJY2FzZSBWS19SSUdIVDoKCQkgICAgcmV0dXJuIDA7CgkJY2FzZSBWS19VUDoJICAgICAgCgkJY2FzZSBWS19ET1dOOgoJCSAgICAvKiBUd28gY2FzZXMgaGVyZSA6IAoJCSAgICAgICAtIGlmIHRoZSBsaXN0Ym94IGlzIG5vdCB2aXNpYmxlLCBkaXNwbGF5cyBpdCAKCQkgICAgICAgd2l0aCBhbGwgdGhlIGVudHJpZXMgaWYgdGhlIHN0eWxlIEFDT19VUERPV05LRVlEUk9QU0xJU1QKCQkgICAgICAgaXMgcHJlc2VudCBidXQgZG9lcyBub3Qgc2VsZWN0IGFueXRoaW5nLgoJCSAgICAgICAtIGlmIHRoZSBsaXN0Ym94IGlzIHZpc2libGUsIGNoYW5nZSB0aGUgc2VsZWN0aW9uCgkJICAgICovCgkJICAgIGlmICggKFRoaXMtPm9wdGlvbnMgJiAoQUNPX0FVVE9TVUdHRVNUIHwgQUNPX1VQRE9XTktFWURST1BTTElTVCkpIAoJCQkgJiYgKCFJc1dpbmRvd1Zpc2libGUoVGhpcy0+aHduZExpc3RCb3gpICYmICghICpod25kVGV4dCkpICkKCQkgICAgewoJCQkgLyogV2UgbXVzdCBkaXNwYXlzIGFsbCB0aGUgZW50cmllcyAqLwoJCQkgZGlzcGxheWFsbCA9IFRSVUU7CgkJICAgIH0gZWxzZSB7CgkJCWlmIChJc1dpbmRvd1Zpc2libGUoVGhpcy0+aHduZExpc3RCb3gpKSB7CgkJCSAgICBpbnQgY291bnQ7CgoJCQkgICAgY291bnQgPSBTZW5kTWVzc2FnZVcoVGhpcy0+aHduZExpc3RCb3gsIExCX0dFVENPVU5ULCAwLCAwKTsKCQkJICAgIC8qIENoYW5nZSB0aGUgc2VsZWN0aW9uICovCgkJCSAgICBzZWwgPSBTZW5kTWVzc2FnZVcoVGhpcy0+aHduZExpc3RCb3gsIExCX0dFVENVUlNFTCwgMCwgMCk7CgkJCSAgICBpZiAod1BhcmFtID09IFZLX1VQKQoJCQkJc2VsID0gKChzZWwtMSk8MCk/Y291bnQtMTpzZWwtMTsKCQkJICAgIGVsc2UKCQkJCXNlbCA9ICgoc2VsKzEpPj0gY291bnQpPy0xOnNlbCsxOwoJCQkgICAgU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRMaXN0Qm94LCBMQl9TRVRDVVJTRUwsIHNlbCwgMCk7CgkJCSAgICBpZiAoc2VsICE9IC0xKSB7CgkJCQlXQ0hBUiAqbXNnOwoJCQkJaW50IGxlbjsKCQkJCQoJCQkJbGVuID0gU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRMaXN0Qm94LCBMQl9HRVRURVhUTEVOLCBzZWwsIChMUEFSQU0pTlVMTCk7CgkJCQltc2cgPSAoV0NIQVIqKSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgKGxlbisxKSpzaXplb2YoV0NIQVIpKTsKCQkJCVNlbmRNZXNzYWdlVyhUaGlzLT5od25kTGlzdEJveCwgTEJfR0VUVEVYVCwgc2VsLCAoTFBBUkFNKW1zZyk7CgkJCQlTZW5kTWVzc2FnZVcoaHduZCwgV01fU0VUVEVYVCwgMCwgKExQQVJBTSltc2cpOwoJCQkJU2VuZE1lc3NhZ2VXKGh3bmQsIEVNX1NFVFNFTCwgbHN0cmxlblcobXNnKSwgbHN0cmxlblcobXNnKSk7CgkJCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtc2cpOwoJCQkgICAgfSBlbHNlIHsKCQkJCVNlbmRNZXNzYWdlVyhod25kLCBXTV9TRVRURVhULCAwLCAoTFBBUkFNKVRoaXMtPnR4dGJhY2t1cCk7CgkJCQlTZW5kTWVzc2FnZVcoaHduZCwgRU1fU0VUU0VMLCBsc3RybGVuVyhUaGlzLT50eHRiYWNrdXApLCBsc3RybGVuVyhUaGlzLT50eHRiYWNrdXApKTsKCQkJICAgIH0JCQkKCQkJfSAJCQoJCQlyZXR1cm4gMDsKCQkgICAgfQoJCSAgICBicmVhazsKCQljYXNlIFZLX0JBQ0s6CgkJY2FzZSBWS19ERUxFVEU6CgkJICAgIGlmICgoISAqaHduZFRleHQpICYmIChUaGlzLT5vcHRpb25zICYgQUNPX0FVVE9TVUdHRVNUKSkgewoJCQlTaG93V2luZG93KFRoaXMtPmh3bmRMaXN0Qm94LCBTV19ISURFKTsKCQkJcmV0dXJuIENhbGxXaW5kb3dQcm9jVyhUaGlzLT53cE9yaWdFZGl0UHJvYywgaHduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwoJCSAgICB9CgkJICAgIGlmIChUaGlzLT5vcHRpb25zICYgQUNPX0FVVE9BUFBFTkQpIHsKCQkJRFdPUkQgYjsKCQkJU2VuZE1lc3NhZ2VXKGh3bmQsIEVNX0dFVFNFTCwgKFdQQVJBTSkmYiwgKExQQVJBTSlOVUxMKTsKCQkJaWYgKGI+MSkgewoJCQkgICAgaHduZFRleHRbYi0xXSA9ICdcMCc7CgkJCX0gZWxzZSB7CgkJCSAgICBod25kVGV4dFswXSA9ICdcMCc7CgkJCSAgICBTZXRXaW5kb3dUZXh0Vyhod25kLCBod25kVGV4dCk7IAoJCQl9CQkJCgkJICAgIH0KCQkgICAgYnJlYWs7CgkJZGVmYXVsdDoJCSAgICAKCQkgICAgOwoJICAgIH0KICAgICAgCgkgICAgU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRMaXN0Qm94LCBMQl9SRVNFVENPTlRFTlQsIDAsIDApOwoKCSAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT50eHRiYWNrdXApOwoJICAgIFRoaXMtPnR4dGJhY2t1cCA9IChXQ0hBUiopIEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLAoJCQkJCQkgSEVBUF9aRVJPX01FTU9SWSwgKGxzdHJsZW5XKGh3bmRUZXh0KSsxKSpzaXplb2YoV0NIQVIpKTsJCQkJCQkJICAgICAgCgkgICAgbHN0cmNweVcoVGhpcy0+dHh0YmFja3VwLCBod25kVGV4dCk7CgoJICAgIC8qIFJldHVybnMgaWYgdGhlcmUgaXMgbm8gdGV4dCB0byBzZWFyY2ggYW5kIHdlIGRvZXNuJ3Qgd2FudCB0byBkaXNwbGF5IGFsbCB0aGUgZW50cmllcyAqLwoJICAgIGlmICgoIWRpc3BsYXlhbGwpICYmICghICpod25kVGV4dCkgKQoJCWJyZWFrOwoJICAgIAoJICAgIElFbnVtU3RyaW5nX1Jlc2V0KFRoaXMtPmVudW1zdHIpOwoJICAgIGZpbGxlZCA9IEZBTFNFOwoJICAgIGZvcihjcHQgPSAwOzspIHsKCQlociA9IElFbnVtU3RyaW5nX05leHQoVGhpcy0+ZW51bXN0ciwgMSwgJnN0cnMsIE5VTEwpOwoJCWlmIChociAhPSBTX09LKQoJCSAgICBicmVhazsKCgkJaWYgKChMUFdTVFIpc3Ryc3RyVyhzdHJzLCBod25kVGV4dCkgPT0gc3RycykgewoJCSAgICAKCQkgICAgaWYgKFRoaXMtPm9wdGlvbnMgJiBBQ09fQVVUT0FQUEVORCkgewoJCQlTZXRXaW5kb3dUZXh0Vyhod25kLCBzdHJzKTsKCQkJU2VuZE1lc3NhZ2VXKGh3bmQsIEVNX1NFVFNFTCwgbHN0cmxlblcoaHduZFRleHQpLCBsc3RybGVuVyhzdHJzKSk7CgkJCWJyZWFrOwoJCSAgICB9CQkKCgkJICAgIGlmIChUaGlzLT5vcHRpb25zICYgQUNPX0FVVE9TVUdHRVNUKSB7CgkJCVNlbmRNZXNzYWdlVyhUaGlzLT5od25kTGlzdEJveCwgTEJfQUREU1RSSU5HLCAwLCAoTFBBUkFNKXN0cnMpOwoJCQlmaWxsZWQgPSBUUlVFOwoJCQljcHQrKzsKCQkgICAgfQoJCX0JCQoJICAgIH0KCSAgICAKCSAgICBpZiAoVGhpcy0+b3B0aW9ucyAmIEFDT19BVVRPU1VHR0VTVCkgewoJCWlmIChmaWxsZWQpIHsKCQkgICAgaGVpZ2h0ID0gU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRMaXN0Qm94LCBMQl9HRVRJVEVNSEVJR0hULCAwLCAwKTsKCQkgICAgU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRMaXN0Qm94LCBMQl9DQVJFVE9GRiwgMCwgMCk7CgkJICAgIEdldFdpbmRvd1JlY3QoaHduZCwgJnIpOwoJCSAgICBTZXRQYXJlbnQoVGhpcy0+aHduZExpc3RCb3gsIEhXTkRfREVTS1RPUCk7CgkJICAgIC8qIEl0IHNlZW1zIHRoYXQgV2luZG93cyBYUCBkaXNwbGF5cyA3IGxpbmVzIGF0IG1vc3QgCgkJICAgICAgIGFuZCBvdGhlcndpc2UgZGlzcGxheXMgYSB2ZXJ0aWNhbCBzY3JvbGwgYmFyICovCgkJICAgIFNldFdpbmRvd1BvcyhUaGlzLT5od25kTGlzdEJveCwgSFdORF9UT1AsIAoJCQkJIHIubGVmdCwgci5ib3R0b20gKyAxLCByLnJpZ2h0IC0gci5sZWZ0LCBtaW4oaGVpZ2h0ICogNywgaGVpZ2h0KihjcHQrMSkpLCAKCQkJCSBTV1BfU0hPV1dJTkRPVyApOwoJCX0gZWxzZSB7CgkJICAgIFNob3dXaW5kb3coVGhpcy0+aHduZExpc3RCb3gsIFNXX0hJREUpOwoJCX0KCSAgICB9CgkgICAgCgkgICAgYnJlYWs7IAoJZGVmYXVsdDoKCSAgICByZXR1cm4gQ2FsbFdpbmRvd1Byb2NXKFRoaXMtPndwT3JpZ0VkaXRQcm9jLCBod25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7CgkgICAgCiAgICB9CgogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBMUkVTVUxUIEFQSUVOVFJZIEFDTEJveFN1YmNsYXNzUHJvYyhIV05EIGh3bmQsIFVJTlQgdU1zZywgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogICAgSUNPTV9USElTKElBdXRvQ29tcGxldGVJbXBsLCBHZXRXaW5kb3dMb25nUHRyVyhod25kLCBHV0xQX1VTRVJEQVRBKSk7CiAgICBXQ0hBUiAqbXNnOwogICAgaW50IHNlbCA9IC0xLCBsZW47CgogICAgc3dpdGNoICh1TXNnKSB7CgljYXNlIFdNX01PVVNFTU9WRToKCSAgICBzZWwgPSBTZW5kTWVzc2FnZVcoaHduZCwgTEJfSVRFTUZST01QT0lOVCwgMCwgbFBhcmFtKTsKCSAgICBTZW5kTWVzc2FnZVcoaHduZCwgTEJfU0VUQ1VSU0VMLCAoV1BBUkFNKXNlbCwgKExQQVJBTSkwKTsKCSAgICBicmVhazsKCWNhc2UgV01fTEJVVFRPTkRPV046CgkgICAgbGVuID0gU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRMaXN0Qm94LCBMQl9HRVRURVhUTEVOLCBzZWwsIChMUEFSQU0pTlVMTCk7CgkgICAgbXNnID0gKFdDSEFSKikgSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIChsZW4rMSkqc2l6ZW9mKFdDSEFSKSk7CgkgICAgc2VsID0gKElOVClTZW5kTWVzc2FnZVcoaHduZCwgTEJfR0VUQ1VSU0VMLCAwLCAwKTsKCSAgICBTZW5kTWVzc2FnZVcoaHduZCwgTEJfR0VUVEVYVCwgc2VsLCAoTFBBUkFNKW1zZyk7CgkgICAgU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRFZGl0LCBXTV9TRVRURVhULCAwLCAoTFBBUkFNKW1zZyk7CgkgICAgU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRFZGl0LCBFTV9TRVRTRUwsIDAsIGxzdHJsZW5XKG1zZykpOwoJICAgIFNob3dXaW5kb3coaHduZCwgU1dfSElERSk7CgkgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbXNnKTsKCSAgICBicmVhazsKCWRlZmF1bHQ6CgkgICAgcmV0dXJuIENhbGxXaW5kb3dQcm9jVyhUaGlzLT53cE9yaWdMQm94UHJvYywgaHduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwogICAgfQogICAgcmV0dXJuIDA7Cn0K