LyoKICoJQXV0b0NvbXBsZXRlIGludGVyZmFjZXMgaW1wbGVtZW50YXRpb24uCiAqCiAqCUNvcHlyaWdodCAyMDA0CU1heGltZSBCZWxsZW5n6SA8bWF4aW1lLmJlbGxlbmdlQGxhcG9zdGUubmV0PgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgovKgogIEltcGxlbWVudGVkOgogIC0gQUNPX0FVVE9BUFBFTkQgc3R5bGUKICAtIEFDT19BVVRPU1VHR0VTVCBzdHlsZQogIC0gQUNPX1VQRE9XTktFWURST1BTTElTVCBzdHlsZQoKICAtIEhhbmRsZSBwd3pzUmVnS2V5UGF0aCBhbmQgcHdzelF1aWNrQ29tcGxldGUgaW4gSW5pdAoKICBUT0RPOgogIC0gaW1wbGVtZW50IEFDT19TRUFSQ0ggc3R5bGUKICAtIGltcGxlbWVudCBBQ09fRklMVEVSUFJFRklYRVMgc3R5bGUKICAtIGltcGxlbWVudCBBQ09fVVNFVEFCIHN0eWxlCiAgLSBpbXBsZW1lbnQgQUNPX1JUTFJFQURJTkcgc3R5bGUKICAKICovCiNpbmNsdWRlICJjb25maWcuaCIKCiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CgojZGVmaW5lIENPQkpNQUNST1MKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgojaW5jbHVkZSAidW5kb2NzaGVsbC5oIgojaW5jbHVkZSAic2hsd2FwaS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm9iamJhc2UuaCIKCiNpbmNsdWRlICJwaWRsLmgiCiNpbmNsdWRlICJzaGxvYmouaCIKI2luY2x1ZGUgInNobGRpc3AuaCIKI2luY2x1ZGUgImRlYnVnaGxwLmgiCgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChzaGVsbCk7Cgp0eXBlZGVmIHN0cnVjdAp7CiAgICBjb25zdCBJQXV0b0NvbXBsZXRlVnRibCAgKmxwVnRibDsKICAgIGNvbnN0IElBdXRvQ29tcGxldGUyVnRibCAqbHB2dGJsQXV0b0NvbXBsZXRlMjsKICAgIExPTkcgcmVmOwogICAgQk9PTCAgZW5hYmxlZDsKICAgIEhXTkQgaHduZEVkaXQ7CiAgICBIV05EIGh3bmRMaXN0Qm94OwogICAgV05EUFJPQyB3cE9yaWdFZGl0UHJvYzsKICAgIFdORFBST0Mgd3BPcmlnTEJveFByb2M7CiAgICBXQ0hBUiAqdHh0YmFja3VwOwogICAgV0NIQVIgKnF1aWNrQ29tcGxldGU7CiAgICBJRW51bVN0cmluZyAqZW51bXN0cjsKICAgIEFVVE9DT01QTEVURU9QVElPTlMgb3B0aW9uczsKfSBJQXV0b0NvbXBsZXRlSW1wbDsKCnN0YXRpYyBjb25zdCBJQXV0b0NvbXBsZXRlVnRibCBhY3Z0OwpzdGF0aWMgY29uc3QgSUF1dG9Db21wbGV0ZTJWdGJsIGFjMnZ0OwoKc3RhdGljIGlubGluZSBJQXV0b0NvbXBsZXRlSW1wbCAqaW1wbF9mcm9tX0lBdXRvQ29tcGxldGUyKCBJQXV0b0NvbXBsZXRlMiAqaWZhY2UgKQp7CiAgICByZXR1cm4gKElBdXRvQ29tcGxldGVJbXBsICopKChjaGFyKilpZmFjZSAtIEZJRUxEX09GRlNFVChJQXV0b0NvbXBsZXRlSW1wbCwgbHB2dGJsQXV0b0NvbXBsZXRlMikpOwp9CgoKLyoKICBjb252ZXJ0cyBUaGlzIHRvIGFuIGludGVyZmFjZSBwb2ludGVyCiovCiNkZWZpbmUgX0lVbmtub3duXyhUaGlzKSAoSVVua25vd24qKSYoVGhpcy0+bHBWdGJsKQojZGVmaW5lIF9JQXV0b0NvbXBsZXRlMl8oVGhpcykgIChJQXV0b0NvbXBsZXRlMiopJihUaGlzLT5scHZ0YmxBdXRvQ29tcGxldGUyKSAKCnN0YXRpYyBMUkVTVUxUIEFQSUVOVFJZIEFDRWRpdFN1YmNsYXNzUHJvYyhIV05EIGh3bmQsIFVJTlQgdU1zZywgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSk7CnN0YXRpYyBMUkVTVUxUIEFQSUVOVFJZIEFDTEJveFN1YmNsYXNzUHJvYyhIV05EIGh3bmQsIFVJTlQgdU1zZywgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIElBdXRvQ29tcGxldGVfQ29uc3RydWN0b3IKICovCkhSRVNVTFQgV0lOQVBJIElBdXRvQ29tcGxldGVfQ29uc3RydWN0b3IoSVVua25vd24gKiBwVW5rT3V0ZXIsIFJFRklJRCByaWlkLCBMUFZPSUQgKiBwcHYpCnsKICAgIElBdXRvQ29tcGxldGVJbXBsICpscGFjOwoKICAgIGlmIChwVW5rT3V0ZXIgJiYgIUlzRXF1YWxJSUQgKHJpaWQsICZJSURfSVVua25vd24pKQoJcmV0dXJuIENMQVNTX0VfTk9BR0dSRUdBVElPTjsKCiAgICBscGFjID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJQXV0b0NvbXBsZXRlSW1wbCkpOwogICAgaWYgKCFscGFjKSAKCXJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIGxwYWMtPnJlZiA9IDE7CiAgICBscGFjLT5scFZ0YmwgPSAmYWN2dDsKICAgIGxwYWMtPmxwdnRibEF1dG9Db21wbGV0ZTIgPSAmYWMydnQ7CiAgICBscGFjLT5lbmFibGVkID0gVFJVRTsKICAgIGxwYWMtPmVudW1zdHIgPSBOVUxMOwogICAgbHBhYy0+b3B0aW9ucyA9IEFDT19BVVRPQVBQRU5EOwogICAgbHBhYy0+d3BPcmlnRWRpdFByb2MgPSBOVUxMOwogICAgbHBhYy0+aHduZExpc3RCb3ggPSBOVUxMOwogICAgbHBhYy0+dHh0YmFja3VwID0gTlVMTDsKICAgIGxwYWMtPnF1aWNrQ29tcGxldGUgPSBOVUxMOwogICAgCiAgICBpZiAoIVNVQ0NFRURFRCAoSVVua25vd25fUXVlcnlJbnRlcmZhY2UgKF9JVW5rbm93bl8gKGxwYWMpLCByaWlkLCBwcHYpKSkgewoJSVVua25vd25fUmVsZWFzZSAoX0lVbmtub3duXyAobHBhYykpOwoJcmV0dXJuIEVfTk9JTlRFUkZBQ0U7CiAgICB9CiAgICAKICAgIFRSQUNFKCItLSAoJXApLT5cbiIsbHBhYyk7CgogICAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgQXV0b0NvbXBsZXRlX1F1ZXJ5SW50ZXJmYWNlCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUF1dG9Db21wbGV0ZV9mblF1ZXJ5SW50ZXJmYWNlKAogICAgSUF1dG9Db21wbGV0ZSAqIGlmYWNlLAogICAgUkVGSUlEIHJpaWQsCiAgICBMUFZPSUQgKnBwdk9iaikKewogICAgSUF1dG9Db21wbGV0ZUltcGwgKlRoaXMgPSAoSUF1dG9Db21wbGV0ZUltcGwgKilpZmFjZTsKICAgIAogICAgVFJBQ0UoIiglcCktPihcblx0SUlEOlx0JXMsJXApXG4iLCBUaGlzLCBzaGRlYnVnc3RyX2d1aWQocmlpZCksIHBwdk9iaik7CiAgICAqcHB2T2JqID0gTlVMTDsKCiAgICBpZihJc0VxdWFsSUlEKHJpaWQsICZJSURfSVVua25vd24pKSAKICAgIHsKCSpwcHZPYmogPSBUaGlzOwogICAgfSAKICAgIGVsc2UgaWYoSXNFcXVhbElJRChyaWlkLCAmSUlEX0lBdXRvQ29tcGxldGUpKQogICAgewoJKnBwdk9iaiA9IChJQXV0b0NvbXBsZXRlKilUaGlzOwogICAgfQogICAgZWxzZSBpZihJc0VxdWFsSUlEKHJpaWQsICZJSURfSUF1dG9Db21wbGV0ZTIpKQogICAgewoJKnBwdk9iaiA9IF9JQXV0b0NvbXBsZXRlMl8gKFRoaXMpOwogICAgfQoKICAgIGlmICgqcHB2T2JqKQogICAgewoJSUF1dG9Db21wbGV0ZV9BZGRSZWYoKElBdXRvQ29tcGxldGUqKSpwcHZPYmopOwoJVFJBQ0UoIi0tIEludGVyZmFjZTogKCVwKS0+KCVwKVxuIiwgcHB2T2JqLCAqcHB2T2JqKTsKCXJldHVybiBTX09LOwogICAgfQogICAgVFJBQ0UoIi0tIEludGVyZmFjZTogRV9OT0lOVEVSRkFDRVxuIik7CiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsJCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUF1dG9Db21wbGV0ZV9mbkFkZFJlZgogKi8Kc3RhdGljIFVMT05HIFdJTkFQSSBJQXV0b0NvbXBsZXRlX2ZuQWRkUmVmKAoJSUF1dG9Db21wbGV0ZSAqIGlmYWNlKQp7CiAgICBJQXV0b0NvbXBsZXRlSW1wbCAqVGhpcyA9IChJQXV0b0NvbXBsZXRlSW1wbCAqKWlmYWNlOwogICAgVUxPTkcgcmVmQ291bnQgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKICAgIAogICAgVFJBQ0UoIiglcCktPigldSlcbiIsIFRoaXMsIHJlZkNvdW50IC0gMSk7CgogICAgcmV0dXJuIHJlZkNvdW50Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElBdXRvQ29tcGxldGVfZm5SZWxlYXNlCiAqLwpzdGF0aWMgVUxPTkcgV0lOQVBJIElBdXRvQ29tcGxldGVfZm5SZWxlYXNlKAoJSUF1dG9Db21wbGV0ZSAqIGlmYWNlKQp7CiAgICBJQXV0b0NvbXBsZXRlSW1wbCAqVGhpcyA9IChJQXV0b0NvbXBsZXRlSW1wbCAqKWlmYWNlOwogICAgVUxPTkcgcmVmQ291bnQgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmKTsKICAgIAogICAgVFJBQ0UoIiglcCktPigldSlcbiIsIFRoaXMsIHJlZkNvdW50ICsgMSk7CgogICAgaWYgKCFyZWZDb3VudCkgewoJVFJBQ0UoIiBkZXN0cm95aW5nIElBdXRvQ29tcGxldGUoJXApXG4iLFRoaXMpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnF1aWNrQ29tcGxldGUpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnR4dGJhY2t1cCk7CglpZiAoVGhpcy0+aHduZExpc3RCb3gpCgkgICAgRGVzdHJveVdpbmRvdyhUaGlzLT5od25kTGlzdEJveCk7CglpZiAoVGhpcy0+ZW51bXN0cikKCSAgICBJRW51bVN0cmluZ19SZWxlYXNlKFRoaXMtPmVudW1zdHIpOwoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CiAgICB9CiAgICByZXR1cm4gcmVmQ291bnQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUF1dG9Db21wbGV0ZV9mbkVuYWJsZQogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBdXRvQ29tcGxldGVfZm5FbmFibGUoCiAgICBJQXV0b0NvbXBsZXRlICogaWZhY2UsCiAgICBCT09MIGZFbmFibGUpCnsKICAgIElBdXRvQ29tcGxldGVJbXBsICpUaGlzID0gKElBdXRvQ29tcGxldGVJbXBsICopaWZhY2U7CgogICAgSFJFU1VMVCBociA9IFNfT0s7CgogICAgVFJBQ0UoIiglcCktPiglcylcbiIsIFRoaXMsIChmRW5hYmxlKT8idHJ1ZSI6ImZhbHNlIik7CgogICAgVGhpcy0+ZW5hYmxlZCA9IGZFbmFibGU7CgogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElBdXRvQ29tcGxldGVfZm5Jbml0CiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUF1dG9Db21wbGV0ZV9mbkluaXQoCiAgICBJQXV0b0NvbXBsZXRlICogaWZhY2UsCiAgICBIV05EIGh3bmRFZGl0LAogICAgSVVua25vd24gKnB1bmtBQ0wsCiAgICBMUENPTEVTVFIgcHd6c1JlZ0tleVBhdGgsCiAgICBMUENPTEVTVFIgcHdzelF1aWNrQ29tcGxldGUpCnsKICAgIElBdXRvQ29tcGxldGVJbXBsICpUaGlzID0gKElBdXRvQ29tcGxldGVJbXBsICopaWZhY2U7CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgbGJOYW1lW10gPSB7J0wnLCdpJywncycsJ3QnLCdCJywnbycsJ3gnLDB9OwoKICAgIFRSQUNFKCIoJXApLT4oMHglMDhseCwgJXAsICVzLCAlcylcbiIsIAoJICBUaGlzLCAobG9uZylod25kRWRpdCwgcHVua0FDTCwgZGVidWdzdHJfdyhwd3pzUmVnS2V5UGF0aCksIGRlYnVnc3RyX3cocHdzelF1aWNrQ29tcGxldGUpKTsKCiAgICBpZiAoVGhpcy0+b3B0aW9ucyAmIEFDT19BVVRPU1VHR0VTVCkgVFJBQ0UoIiBBQ09fQVVUT1NVR0dFU1RcbiIpOwogICAgaWYgKFRoaXMtPm9wdGlvbnMgJiBBQ09fQVVUT0FQUEVORCkgVFJBQ0UoIiBBQ09fQVVUT0FQUEVORFxuIik7CiAgICBpZiAoVGhpcy0+b3B0aW9ucyAmIEFDT19TRUFSQ0gpIEZJWE1FKCIgQUNPX1NFQVJDSCBub3Qgc3VwcG9ydGVkXG4iKTsKICAgIGlmIChUaGlzLT5vcHRpb25zICYgQUNPX0ZJTFRFUlBSRUZJWEVTKSBGSVhNRSgiIEFDT19GSUxURVJQUkVGSVhFUyBub3Qgc3VwcG9ydGVkXG4iKTsKICAgIGlmIChUaGlzLT5vcHRpb25zICYgQUNPX1VTRVRBQikgRklYTUUoIiBBQ09fVVNFVEFCIG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgaWYgKFRoaXMtPm9wdGlvbnMgJiBBQ09fVVBET1dOS0VZRFJPUFNMSVNUKSBUUkFDRSgiIEFDT19VUERPV05LRVlEUk9QU0xJU1RcbiIpOwogICAgaWYgKFRoaXMtPm9wdGlvbnMgJiBBQ09fUlRMUkVBRElORykgRklYTUUoIiBBQ09fUlRMUkVBRElORyBub3Qgc3VwcG9ydGVkXG4iKTsKCiAgICBUaGlzLT5od25kRWRpdCA9IGh3bmRFZGl0OwoKICAgIGlmICghU1VDQ0VFREVEIChJVW5rbm93bl9RdWVyeUludGVyZmFjZSAocHVua0FDTCwgJklJRF9JRW51bVN0cmluZywgKExQVk9JRCopJlRoaXMtPmVudW1zdHIpKSkgewoJVFJBQ0UoIk5vIElFbnVtU3RyaW5nIGludGVyZmFjZVxuIik7CglyZXR1cm4gIEVfTk9JTlRFUkZBQ0U7CiAgICB9CgogICAgVGhpcy0+d3BPcmlnRWRpdFByb2MgPSAoV05EUFJPQykgU2V0V2luZG93TG9uZ1B0clcoIGh3bmRFZGl0LCBHV0xQX1dORFBST0MsIChMT05HX1BUUikgQUNFZGl0U3ViY2xhc3NQcm9jKTsKICAgIFNldFdpbmRvd0xvbmdQdHJXKCBod25kRWRpdCwgR1dMUF9VU0VSREFUQSwgKExPTkdfUFRSKVRoaXMpOwoKICAgIGlmIChUaGlzLT5vcHRpb25zICYgQUNPX0FVVE9TVUdHRVNUKSB7CglIV05EIGh3bmRQYXJlbnQ7CgoJaHduZFBhcmVudCA9IEdldFBhcmVudChUaGlzLT5od25kRWRpdCk7CgkKCS8qIEZJWE1FIDogVGhlIGxpc3Rib3ggc2hvdWxkIGJlIHJlc2l6YWJsZSB3aXRoIHRoZSBtb3VzZS4gV1NfVEhJQ0tGUkFNRSBsb29rcyB1Z2x5ICovCglUaGlzLT5od25kTGlzdEJveCA9IENyZWF0ZVdpbmRvd0V4VygwLCBsYk5hbWUsIE5VTEwsIAoJCQkJCSAgICBXU19CT1JERVIgfCBXU19DSElMRCB8IFdTX1ZTQ1JPTEwgfCBMQlNfSEFTU1RSSU5HUyB8IExCU19OT1RJRlkgfCBMQlNfTk9JTlRFR1JBTEhFSUdIVCwgCgkJCQkJICAgIENXX1VTRURFRkFVTFQsIENXX1VTRURFRkFVTFQsIENXX1VTRURFRkFVTFQsIENXX1VTRURFRkFVTFQsCgkJCQkJICAgIGh3bmRQYXJlbnQsIE5VTEwsIAoJCQkJCSAgICAoSElOU1RBTkNFKUdldFdpbmRvd0xvbmdQdHJXKCBod25kUGFyZW50LCBHV0xQX0hJTlNUQU5DRSApLCBOVUxMKTsKCQkJCQkgICAgCglpZiAoVGhpcy0+aHduZExpc3RCb3gpIHsKCSAgICBUaGlzLT53cE9yaWdMQm94UHJvYyA9IChXTkRQUk9DKSBTZXRXaW5kb3dMb25nUHRyVyggVGhpcy0+aHduZExpc3RCb3gsIEdXTFBfV05EUFJPQywgKExPTkdfUFRSKSBBQ0xCb3hTdWJjbGFzc1Byb2MpOwoJICAgIFNldFdpbmRvd0xvbmdQdHJXKCBUaGlzLT5od25kTGlzdEJveCwgR1dMUF9VU0VSREFUQSwgKExPTkdfUFRSKVRoaXMpOwoJfQogICAgfQoKICAgIGlmIChwd3pzUmVnS2V5UGF0aCkgewoJV0NIQVIgKmtleTsKCVdDSEFSIHJlc3VsdFtNQVhfUEFUSF07CglXQ0hBUiAqdmFsdWU7CglIS0VZIGhLZXkgPSAwOwoJTE9ORyByZXM7CglMT05HIGxlbjsKCgkvKiBwd3N6UmVnS2V5UGF0aCBjb250YWlucyB0aGUga2V5IGFzIHdlbGwgYXMgdGhlIHZhbHVlLCBzbyB3ZSBzcGxpdCAqLwoJa2V5ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIChsc3RybGVuVyhwd3pzUmVnS2V5UGF0aCkrMSkqc2l6ZW9mKFdDSEFSKSk7CglzdHJjcHlXKGtleSwgcHd6c1JlZ0tleVBhdGgpOwoJdmFsdWUgPSBzdHJyY2hyVyhrZXksICdcXCcpOwoJKnZhbHVlID0gMDsKCXZhbHVlKys7CgkvKiBOb3cgdmFsdWUgY29udGFpbnMgdGhlIHZhbHVlIGFuZCBidWZmZXIgdGhlIGtleSAqLwoJcmVzID0gUmVnT3BlbktleUV4VyhIS0VZX0NVUlJFTlRfVVNFUiwga2V5LCAwLCBLRVlfUkVBRCwgJmhLZXkpOwoJaWYgKHJlcyAhPSBFUlJPUl9TVUNDRVNTKSB7CgkgICAgLyogaWYgdGhlIGtleSBpcyBub3QgZm91bmQsIE1TRE4gc3RhdGVzIHdlIG11c3Qgc2VlayBpbiBIS0VZX0xPQ0FMX01BQ0hJTkUgKi8KCSAgICByZXMgPSBSZWdPcGVuS2V5RXhXKEhLRVlfTE9DQUxfTUFDSElORSwga2V5LCAwLCBLRVlfUkVBRCwgJmhLZXkpOyAgCgl9CglpZiAocmVzID09IEVSUk9SX1NVQ0NFU1MpIHsKCSAgICByZXMgPSBSZWdRdWVyeVZhbHVlVyhoS2V5LCB2YWx1ZSwgcmVzdWx0LCAmbGVuKTsKCSAgICBpZiAocmVzID09IEVSUk9SX1NVQ0NFU1MpIHsKCQlUaGlzLT5xdWlja0NvbXBsZXRlID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIGxlbipzaXplb2YoV0NIQVIpKTsKCQlzdHJjcHlXKFRoaXMtPnF1aWNrQ29tcGxldGUsIHJlc3VsdCk7CgkgICAgfQoJICAgIFJlZ0Nsb3NlS2V5KGhLZXkpOwoJfQoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwga2V5KTsKICAgIH0KCiAgICBpZiAoKHB3c3pRdWlja0NvbXBsZXRlKSAmJiAoIVRoaXMtPnF1aWNrQ29tcGxldGUpKSB7CglUaGlzLT5xdWlja0NvbXBsZXRlID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIChsc3RybGVuVyhwd3N6UXVpY2tDb21wbGV0ZSkrMSkqc2l6ZW9mKFdDSEFSKSk7Cglsc3RyY3B5VyhUaGlzLT5xdWlja0NvbXBsZXRlLCBwd3N6UXVpY2tDb21wbGV0ZSk7CiAgICB9CgogICAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgSUF1dG9Db21wbGV0ZV9mblZUYWJsZQogKi8Kc3RhdGljIGNvbnN0IElBdXRvQ29tcGxldGVWdGJsIGFjdnQgPQp7CiAgICBJQXV0b0NvbXBsZXRlX2ZuUXVlcnlJbnRlcmZhY2UsCiAgICBJQXV0b0NvbXBsZXRlX2ZuQWRkUmVmLAogICAgSUF1dG9Db21wbGV0ZV9mblJlbGVhc2UsCiAgICBJQXV0b0NvbXBsZXRlX2ZuSW5pdCwKICAgIElBdXRvQ29tcGxldGVfZm5FbmFibGUsCn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIEF1dG9Db21wbGV0ZTJfUXVlcnlJbnRlcmZhY2UKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQXV0b0NvbXBsZXRlMl9mblF1ZXJ5SW50ZXJmYWNlKAogICAgSUF1dG9Db21wbGV0ZTIgKiBpZmFjZSwKICAgIFJFRklJRCByaWlkLAogICAgTFBWT0lEICpwcHZPYmopCnsKICAgIElBdXRvQ29tcGxldGVJbXBsICpUaGlzID0gaW1wbF9mcm9tX0lBdXRvQ29tcGxldGUyKGlmYWNlKTsKCiAgICBUUkFDRSAoIiglcCktPiglcywlcClcbiIsIFRoaXMsIHNoZGVidWdzdHJfZ3VpZCAocmlpZCksIHBwdk9iaik7CgogICAgcmV0dXJuIElBdXRvQ29tcGxldGVfUXVlcnlJbnRlcmZhY2UoKElBdXRvQ29tcGxldGUqKVRoaXMsIHJpaWQsIHBwdk9iaik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUF1dG9Db21wbGV0ZTJfZm5BZGRSZWYKICovCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUF1dG9Db21wbGV0ZTJfZm5BZGRSZWYoCglJQXV0b0NvbXBsZXRlMiAqIGlmYWNlKQp7CiAgICBJQXV0b0NvbXBsZXRlSW1wbCAqVGhpcyA9IGltcGxfZnJvbV9JQXV0b0NvbXBsZXRlMihpZmFjZSk7CgogICAgVFJBQ0UgKCIoJXApLT4oY291bnQ9JXUpXG4iLCBUaGlzLCBUaGlzLT5yZWYpOwoKICAgIHJldHVybiBJQXV0b0NvbXBsZXRlMl9BZGRSZWYoKElBdXRvQ29tcGxldGUqKVRoaXMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElBdXRvQ29tcGxldGUyX2ZuUmVsZWFzZQogKi8Kc3RhdGljIFVMT05HIFdJTkFQSSBJQXV0b0NvbXBsZXRlMl9mblJlbGVhc2UoCglJQXV0b0NvbXBsZXRlMiAqIGlmYWNlKQp7CiAgICBJQXV0b0NvbXBsZXRlSW1wbCAqVGhpcyA9IGltcGxfZnJvbV9JQXV0b0NvbXBsZXRlMihpZmFjZSk7CgogICAgVFJBQ0UgKCIoJXApLT4oY291bnQ9JXUpXG4iLCBUaGlzLCBUaGlzLT5yZWYpOwoKICAgIHJldHVybiBJQXV0b0NvbXBsZXRlX1JlbGVhc2UoKElBdXRvQ29tcGxldGUqKVRoaXMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElBdXRvQ29tcGxldGUyX2ZuRW5hYmxlCiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUF1dG9Db21wbGV0ZTJfZm5FbmFibGUoCiAgICBJQXV0b0NvbXBsZXRlMiAqIGlmYWNlLAogICAgQk9PTCBmRW5hYmxlKQp7CiAgICBJQXV0b0NvbXBsZXRlSW1wbCAqVGhpcyA9IGltcGxfZnJvbV9JQXV0b0NvbXBsZXRlMihpZmFjZSk7CgogICAgVFJBQ0UgKCIoJXApLT4oJXMpXG4iLCBUaGlzLCAoZkVuYWJsZSk/InRydWUiOiJmYWxzZSIpOwoKICAgIHJldHVybiBJQXV0b0NvbXBsZXRlX0VuYWJsZSgoSUF1dG9Db21wbGV0ZSopVGhpcywgZkVuYWJsZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSUF1dG9Db21wbGV0ZTJfZm5Jbml0CiAqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUF1dG9Db21wbGV0ZTJfZm5Jbml0KAogICAgSUF1dG9Db21wbGV0ZTIgKiBpZmFjZSwKICAgIEhXTkQgaHduZEVkaXQsCiAgICBJVW5rbm93biAqcHVua0FDTCwKICAgIExQQ09MRVNUUiBwd3pzUmVnS2V5UGF0aCwKICAgIExQQ09MRVNUUiBwd3N6UXVpY2tDb21wbGV0ZSkKewogICAgSUF1dG9Db21wbGV0ZUltcGwgKlRoaXMgPSBpbXBsX2Zyb21fSUF1dG9Db21wbGV0ZTIoaWZhY2UpOwoKICAgIFRSQUNFKCIoJXApXG4iLCBUaGlzKTsKCiAgICByZXR1cm4gSUF1dG9Db21wbGV0ZV9Jbml0KChJQXV0b0NvbXBsZXRlKilUaGlzLCBod25kRWRpdCwgcHVua0FDTCwgcHd6c1JlZ0tleVBhdGgsIHB3c3pRdWlja0NvbXBsZXRlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICBJQXV0b0NvbXBsZXRlX2ZuR2V0T3B0aW9ucwogKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBdXRvQ29tcGxldGUyX2ZuR2V0T3B0aW9ucygKICAgIElBdXRvQ29tcGxldGUyICogaWZhY2UsCiAgICBEV09SRCAqcGR3RmxhZykKewogICAgSFJFU1VMVCBociA9IFNfT0s7CgogICAgSUF1dG9Db21wbGV0ZUltcGwgKlRoaXMgPSBpbXBsX2Zyb21fSUF1dG9Db21wbGV0ZTIoaWZhY2UpOwoKICAgIFRSQUNFKCIoJXApIC0+ICglcClcbiIsIFRoaXMsIHBkd0ZsYWcpOwoKICAgICpwZHdGbGFnID0gVGhpcy0+b3B0aW9uczsKCiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgSUF1dG9Db21wbGV0ZV9mblNldE9wdGlvbnMKICovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQXV0b0NvbXBsZXRlMl9mblNldE9wdGlvbnMoCiAgICBJQXV0b0NvbXBsZXRlMiAqIGlmYWNlLAogICAgRFdPUkQgZHdGbGFnKQp7CiAgICBIUkVTVUxUIGhyID0gU19PSzsKCiAgICBJQXV0b0NvbXBsZXRlSW1wbCAqVGhpcyA9IGltcGxfZnJvbV9JQXV0b0NvbXBsZXRlMihpZmFjZSk7CgogICAgVFJBQ0UoIiglcCkgLT4gKDB4JXgpXG4iLCBUaGlzLCBkd0ZsYWcpOwoKICAgIFRoaXMtPm9wdGlvbnMgPSBkd0ZsYWc7CgogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogIElBdXRvQ29tcGxldGUyX2ZuVlRhYmxlCiAqLwpzdGF0aWMgY29uc3QgSUF1dG9Db21wbGV0ZTJWdGJsIGFjMnZ0ID0KewogICAgSUF1dG9Db21wbGV0ZTJfZm5RdWVyeUludGVyZmFjZSwKICAgIElBdXRvQ29tcGxldGUyX2ZuQWRkUmVmLAogICAgSUF1dG9Db21wbGV0ZTJfZm5SZWxlYXNlLAogICAgSUF1dG9Db21wbGV0ZTJfZm5Jbml0LAogICAgSUF1dG9Db21wbGV0ZTJfZm5FbmFibGUsCiAgICAvKiBJQXV0b0NvbXBsZXRlMiAqLwogICAgSUF1dG9Db21wbGV0ZTJfZm5TZXRPcHRpb25zLAogICAgSUF1dG9Db21wbGV0ZTJfZm5HZXRPcHRpb25zLAp9OwoKLyoKICBXaW5kb3cgcHJvY2VkdXJlIGZvciBhdXRvY29tcGxldGlvbgogKi8Kc3RhdGljIExSRVNVTFQgQVBJRU5UUlkgQUNFZGl0U3ViY2xhc3NQcm9jKEhXTkQgaHduZCwgVUlOVCB1TXNnLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtKQp7CiAgICBJQXV0b0NvbXBsZXRlSW1wbCAqVGhpcyA9IChJQXV0b0NvbXBsZXRlSW1wbCAqKUdldFdpbmRvd0xvbmdQdHJXKGh3bmQsIEdXTFBfVVNFUkRBVEEpOwogICAgTFBPTEVTVFIgc3RyczsKICAgIEhSRVNVTFQgaHI7CiAgICBXQ0hBUiBod25kVGV4dFsyNTVdOwogICAgV0NIQVIgKmh3bmRRQ1RleHQ7CiAgICBSRUNUIHI7CiAgICBCT09MIGNvbnRyb2wsIGZpbGxlZCwgZGlzcGxheWFsbCA9IEZBTFNFOwogICAgaW50IGNwdCwgaGVpZ2h0LCBzZWw7CgogICAgaWYgKCFUaGlzLT5lbmFibGVkKSByZXR1cm4gQ2FsbFdpbmRvd1Byb2NXKFRoaXMtPndwT3JpZ0VkaXRQcm9jLCBod25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7CgogICAgc3dpdGNoICh1TXNnKQogICAgewoJY2FzZSBDQl9TSE9XRFJPUERPV046CgkgICAgU2hvd1dpbmRvdyhUaGlzLT5od25kTGlzdEJveCwgU1dfSElERSk7CgkgICAgYnJlYWs7CgljYXNlIFdNX0tJTExGT0NVUzoKCSAgICBpZiAoKFRoaXMtPm9wdGlvbnMgJiYgQUNPX0FVVE9TVUdHRVNUKSAmJiAKCQkoKEhXTkQpd1BhcmFtICE9IFRoaXMtPmh3bmRMaXN0Qm94KSkKCSAgICB7CgkJU2hvd1dpbmRvdyhUaGlzLT5od25kTGlzdEJveCwgU1dfSElERSk7CgkgICAgfQoJICAgIGJyZWFrOwoJY2FzZSBXTV9LRVlVUDoKCSAgICAKCSAgICBHZXRXaW5kb3dUZXh0VyggaHduZCwgKExQV1NUUilod25kVGV4dCwgMjU1KTsKICAgICAgCgkgICAgc3dpdGNoKHdQYXJhbSkgewoJCWNhc2UgVktfUkVUVVJOOgoJCSAgICAvKiBJZiBxdWlja0NvbXBsZXRlIGlzIHNldCBhbmQgY29udHJvbCBpcyBwcmVzc2VkLCByZXBsYWNlIHRoZSBzdHJpbmcgKi8KCQkgICAgY29udHJvbCA9IEdldEtleVN0YXRlKFZLX0NPTlRST0wpICYgMHg4MDAwOwkJICAgIAoJCSAgICBpZiAoY29udHJvbCAmJiBUaGlzLT5xdWlja0NvbXBsZXRlKSB7CgkJCWh3bmRRQ1RleHQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgCgkJCQkJCSAgICAgICAobHN0cmxlblcoVGhpcy0+cXVpY2tDb21wbGV0ZSkrbHN0cmxlblcoaHduZFRleHQpKSpzaXplb2YoV0NIQVIpKTsKCQkJc2VsID0gc3ByaW50ZlcoaHduZFFDVGV4dCwgVGhpcy0+cXVpY2tDb21wbGV0ZSwgaHduZFRleHQpOwoJCQlTZW5kTWVzc2FnZVcoaHduZCwgV01fU0VUVEVYVCwgMCwgKExQQVJBTSlod25kUUNUZXh0KTsKCQkJU2VuZE1lc3NhZ2VXKGh3bmQsIEVNX1NFVFNFTCwgMCwgc2VsKTsKCQkJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgaHduZFFDVGV4dCk7CgkJICAgIH0KCgkJICAgIFNob3dXaW5kb3coVGhpcy0+aHduZExpc3RCb3gsIFNXX0hJREUpOwoJCSAgICByZXR1cm4gMDsKCQljYXNlIFZLX0xFRlQ6CgkJY2FzZSBWS19SSUdIVDoKCQkgICAgcmV0dXJuIDA7CgkJY2FzZSBWS19VUDoJICAgICAgCgkJY2FzZSBWS19ET1dOOgoJCSAgICAvKiBUd28gY2FzZXMgaGVyZSA6IAoJCSAgICAgICAtIGlmIHRoZSBsaXN0Ym94IGlzIG5vdCB2aXNpYmxlLCBkaXNwbGF5cyBpdCAKCQkgICAgICAgd2l0aCBhbGwgdGhlIGVudHJpZXMgaWYgdGhlIHN0eWxlIEFDT19VUERPV05LRVlEUk9QU0xJU1QKCQkgICAgICAgaXMgcHJlc2VudCBidXQgZG9lcyBub3Qgc2VsZWN0IGFueXRoaW5nLgoJCSAgICAgICAtIGlmIHRoZSBsaXN0Ym94IGlzIHZpc2libGUsIGNoYW5nZSB0aGUgc2VsZWN0aW9uCgkJICAgICovCgkJICAgIGlmICggKFRoaXMtPm9wdGlvbnMgJiAoQUNPX0FVVE9TVUdHRVNUIHwgQUNPX1VQRE9XTktFWURST1BTTElTVCkpIAoJCQkgJiYgKCFJc1dpbmRvd1Zpc2libGUoVGhpcy0+aHduZExpc3RCb3gpICYmICghICpod25kVGV4dCkpICkKCQkgICAgewoJCQkgLyogV2UgbXVzdCBkaXNwYXlzIGFsbCB0aGUgZW50cmllcyAqLwoJCQkgZGlzcGxheWFsbCA9IFRSVUU7CgkJICAgIH0gZWxzZSB7CgkJCWlmIChJc1dpbmRvd1Zpc2libGUoVGhpcy0+aHduZExpc3RCb3gpKSB7CgkJCSAgICBpbnQgY291bnQ7CgoJCQkgICAgY291bnQgPSBTZW5kTWVzc2FnZVcoVGhpcy0+aHduZExpc3RCb3gsIExCX0dFVENPVU5ULCAwLCAwKTsKCQkJICAgIC8qIENoYW5nZSB0aGUgc2VsZWN0aW9uICovCgkJCSAgICBzZWwgPSBTZW5kTWVzc2FnZVcoVGhpcy0+aHduZExpc3RCb3gsIExCX0dFVENVUlNFTCwgMCwgMCk7CgkJCSAgICBpZiAod1BhcmFtID09IFZLX1VQKQoJCQkJc2VsID0gKChzZWwtMSk8MCk/Y291bnQtMTpzZWwtMTsKCQkJICAgIGVsc2UKCQkJCXNlbCA9ICgoc2VsKzEpPj0gY291bnQpPy0xOnNlbCsxOwoJCQkgICAgU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRMaXN0Qm94LCBMQl9TRVRDVVJTRUwsIHNlbCwgMCk7CgkJCSAgICBpZiAoc2VsICE9IC0xKSB7CgkJCQlXQ0hBUiAqbXNnOwoJCQkJaW50IGxlbjsKCQkJCQoJCQkJbGVuID0gU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRMaXN0Qm94LCBMQl9HRVRURVhUTEVOLCBzZWwsIChMUEFSQU0pTlVMTCk7CgkJCQltc2cgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgKGxlbisxKSpzaXplb2YoV0NIQVIpKTsKCQkJCVNlbmRNZXNzYWdlVyhUaGlzLT5od25kTGlzdEJveCwgTEJfR0VUVEVYVCwgc2VsLCAoTFBBUkFNKW1zZyk7CgkJCQlTZW5kTWVzc2FnZVcoaHduZCwgV01fU0VUVEVYVCwgMCwgKExQQVJBTSltc2cpOwoJCQkJU2VuZE1lc3NhZ2VXKGh3bmQsIEVNX1NFVFNFTCwgbHN0cmxlblcobXNnKSwgbHN0cmxlblcobXNnKSk7CgkJCQlIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtc2cpOwoJCQkgICAgfSBlbHNlIHsKCQkJCVNlbmRNZXNzYWdlVyhod25kLCBXTV9TRVRURVhULCAwLCAoTFBBUkFNKVRoaXMtPnR4dGJhY2t1cCk7CgkJCQlTZW5kTWVzc2FnZVcoaHduZCwgRU1fU0VUU0VMLCBsc3RybGVuVyhUaGlzLT50eHRiYWNrdXApLCBsc3RybGVuVyhUaGlzLT50eHRiYWNrdXApKTsKCQkJICAgIH0JCQkKCQkJfSAJCQoJCQlyZXR1cm4gMDsKCQkgICAgfQoJCSAgICBicmVhazsKCQljYXNlIFZLX0JBQ0s6CgkJY2FzZSBWS19ERUxFVEU6CgkJICAgIGlmICgoISAqaHduZFRleHQpICYmIChUaGlzLT5vcHRpb25zICYgQUNPX0FVVE9TVUdHRVNUKSkgewoJCQlTaG93V2luZG93KFRoaXMtPmh3bmRMaXN0Qm94LCBTV19ISURFKTsKCQkJcmV0dXJuIENhbGxXaW5kb3dQcm9jVyhUaGlzLT53cE9yaWdFZGl0UHJvYywgaHduZCwgdU1zZywgd1BhcmFtLCBsUGFyYW0pOwoJCSAgICB9CgkJICAgIGlmIChUaGlzLT5vcHRpb25zICYgQUNPX0FVVE9BUFBFTkQpIHsKCQkJRFdPUkQgYjsKCQkJU2VuZE1lc3NhZ2VXKGh3bmQsIEVNX0dFVFNFTCwgKFdQQVJBTSkmYiwgKExQQVJBTSlOVUxMKTsKCQkJaWYgKGI+MSkgewoJCQkgICAgaHduZFRleHRbYi0xXSA9ICdcMCc7CgkJCX0gZWxzZSB7CgkJCSAgICBod25kVGV4dFswXSA9ICdcMCc7CgkJCSAgICBTZXRXaW5kb3dUZXh0Vyhod25kLCBod25kVGV4dCk7IAoJCQl9CQkJCgkJICAgIH0KCQkgICAgYnJlYWs7CgkJZGVmYXVsdDoJCSAgICAKCQkgICAgOwoJICAgIH0KICAgICAgCgkgICAgU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRMaXN0Qm94LCBMQl9SRVNFVENPTlRFTlQsIDAsIDApOwoKCSAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT50eHRiYWNrdXApOwoJICAgIFRoaXMtPnR4dGJhY2t1cCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLAoJCQkJCQkgSEVBUF9aRVJPX01FTU9SWSwgKGxzdHJsZW5XKGh3bmRUZXh0KSsxKSpzaXplb2YoV0NIQVIpKTsJCQkJCQkJICAgICAgCgkgICAgbHN0cmNweVcoVGhpcy0+dHh0YmFja3VwLCBod25kVGV4dCk7CgoJICAgIC8qIFJldHVybnMgaWYgdGhlcmUgaXMgbm8gdGV4dCB0byBzZWFyY2ggYW5kIHdlIGRvZXNuJ3Qgd2FudCB0byBkaXNwbGF5IGFsbCB0aGUgZW50cmllcyAqLwoJICAgIGlmICgoIWRpc3BsYXlhbGwpICYmICghICpod25kVGV4dCkgKQoJCWJyZWFrOwoJICAgIAoJICAgIElFbnVtU3RyaW5nX1Jlc2V0KFRoaXMtPmVudW1zdHIpOwoJICAgIGZpbGxlZCA9IEZBTFNFOwoJICAgIGZvcihjcHQgPSAwOzspIHsKCQlociA9IElFbnVtU3RyaW5nX05leHQoVGhpcy0+ZW51bXN0ciwgMSwgJnN0cnMsIE5VTEwpOwoJCWlmIChociAhPSBTX09LKQoJCSAgICBicmVhazsKCgkJaWYgKChMUFdTVFIpc3Ryc3RyVyhzdHJzLCBod25kVGV4dCkgPT0gc3RycykgewoJCSAgICAKCQkgICAgaWYgKFRoaXMtPm9wdGlvbnMgJiBBQ09fQVVUT0FQUEVORCkgewoJCQlTZXRXaW5kb3dUZXh0Vyhod25kLCBzdHJzKTsKCQkJU2VuZE1lc3NhZ2VXKGh3bmQsIEVNX1NFVFNFTCwgbHN0cmxlblcoaHduZFRleHQpLCBsc3RybGVuVyhzdHJzKSk7CgkJCWJyZWFrOwoJCSAgICB9CQkKCgkJICAgIGlmIChUaGlzLT5vcHRpb25zICYgQUNPX0FVVE9TVUdHRVNUKSB7CgkJCVNlbmRNZXNzYWdlVyhUaGlzLT5od25kTGlzdEJveCwgTEJfQUREU1RSSU5HLCAwLCAoTFBBUkFNKXN0cnMpOwoJCQlmaWxsZWQgPSBUUlVFOwoJCQljcHQrKzsKCQkgICAgfQoJCX0JCQoJICAgIH0KCSAgICAKCSAgICBpZiAoVGhpcy0+b3B0aW9ucyAmIEFDT19BVVRPU1VHR0VTVCkgewoJCWlmIChmaWxsZWQpIHsKCQkgICAgaGVpZ2h0ID0gU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRMaXN0Qm94LCBMQl9HRVRJVEVNSEVJR0hULCAwLCAwKTsKCQkgICAgU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRMaXN0Qm94LCBMQl9DQVJFVE9GRiwgMCwgMCk7CgkJICAgIEdldFdpbmRvd1JlY3QoaHduZCwgJnIpOwoJCSAgICBTZXRQYXJlbnQoVGhpcy0+aHduZExpc3RCb3gsIEhXTkRfREVTS1RPUCk7CgkJICAgIC8qIEl0IHNlZW1zIHRoYXQgV2luZG93cyBYUCBkaXNwbGF5cyA3IGxpbmVzIGF0IG1vc3QgCgkJICAgICAgIGFuZCBvdGhlcndpc2UgZGlzcGxheXMgYSB2ZXJ0aWNhbCBzY3JvbGwgYmFyICovCgkJICAgIFNldFdpbmRvd1BvcyhUaGlzLT5od25kTGlzdEJveCwgSFdORF9UT1AsIAoJCQkJIHIubGVmdCwgci5ib3R0b20gKyAxLCByLnJpZ2h0IC0gci5sZWZ0LCBtaW4oaGVpZ2h0ICogNywgaGVpZ2h0KihjcHQrMSkpLCAKCQkJCSBTV1BfU0hPV1dJTkRPVyApOwoJCX0gZWxzZSB7CgkJICAgIFNob3dXaW5kb3coVGhpcy0+aHduZExpc3RCb3gsIFNXX0hJREUpOwoJCX0KCSAgICB9CgkgICAgCgkgICAgYnJlYWs7IAoJZGVmYXVsdDoKCSAgICByZXR1cm4gQ2FsbFdpbmRvd1Byb2NXKFRoaXMtPndwT3JpZ0VkaXRQcm9jLCBod25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7CgkgICAgCiAgICB9CgogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBMUkVTVUxUIEFQSUVOVFJZIEFDTEJveFN1YmNsYXNzUHJvYyhIV05EIGh3bmQsIFVJTlQgdU1zZywgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewogICAgSUF1dG9Db21wbGV0ZUltcGwgKlRoaXMgPSAoSUF1dG9Db21wbGV0ZUltcGwgKilHZXRXaW5kb3dMb25nUHRyVyhod25kLCBHV0xQX1VTRVJEQVRBKTsKICAgIFdDSEFSICptc2c7CiAgICBpbnQgc2VsLCBsZW47CgogICAgc3dpdGNoICh1TXNnKSB7CgljYXNlIFdNX01PVVNFTU9WRToKCSAgICBzZWwgPSBTZW5kTWVzc2FnZVcoaHduZCwgTEJfSVRFTUZST01QT0lOVCwgMCwgbFBhcmFtKTsKCSAgICBTZW5kTWVzc2FnZVcoaHduZCwgTEJfU0VUQ1VSU0VMLCAoV1BBUkFNKXNlbCwgKExQQVJBTSkwKTsKCSAgICBicmVhazsKCWNhc2UgV01fTEJVVFRPTkRPV046CgkgICAgc2VsID0gU2VuZE1lc3NhZ2VXKGh3bmQsIExCX0dFVENVUlNFTCwgMCwgMCk7CgkgICAgaWYgKHNlbCA8IDApCgkJYnJlYWs7CgkgICAgbGVuID0gU2VuZE1lc3NhZ2VXKFRoaXMtPmh3bmRMaXN0Qm94LCBMQl9HRVRURVhUTEVOLCBzZWwsIDApOwoJICAgIG1zZyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCAobGVuKzEpKnNpemVvZihXQ0hBUikpOwoJICAgIFNlbmRNZXNzYWdlVyhod25kLCBMQl9HRVRURVhULCBzZWwsIChMUEFSQU0pbXNnKTsKCSAgICBTZW5kTWVzc2FnZVcoVGhpcy0+aHduZEVkaXQsIFdNX1NFVFRFWFQsIDAsIChMUEFSQU0pbXNnKTsKCSAgICBTZW5kTWVzc2FnZVcoVGhpcy0+aHduZEVkaXQsIEVNX1NFVFNFTCwgMCwgbHN0cmxlblcobXNnKSk7CgkgICAgU2hvd1dpbmRvdyhod25kLCBTV19ISURFKTsKCSAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBtc2cpOwoJICAgIGJyZWFrOwoJZGVmYXVsdDoKCSAgICByZXR1cm4gQ2FsbFdpbmRvd1Byb2NXKFRoaXMtPndwT3JpZ0xCb3hQcm9jLCBod25kLCB1TXNnLCB3UGFyYW0sIGxQYXJhbSk7CiAgICB9CiAgICByZXR1cm4gMDsKfQo=