From 5bcc37a9fd6564a8d6b85ce8af169fced5c6f49d Mon Sep 17 00:00:00 2001 From: Owen Rudge Date: Fri, 4 Dec 2009 10:11:57 -0600 Subject: [PATCH] imagehlp: Implement ImageRemoveCertificate. --- dlls/imagehlp/integrity.c | 80 +++++++++++++++++++++++++++++++++++++++-- dlls/imagehlp/tests/integrity.c | 4 +-- 2 files changed, 79 insertions(+), 5 deletions(-) diff --git a/dlls/imagehlp/integrity.c b/dlls/imagehlp/integrity.c index 6a13c53bb23..3aaac7d5e30 100644 --- a/dlls/imagehlp/integrity.c +++ b/dlls/imagehlp/integrity.c @@ -564,7 +564,81 @@ BOOL WINAPI ImageGetDigestStream( */ BOOL WINAPI ImageRemoveCertificate(HANDLE FileHandle, DWORD Index) { - FIXME("(%p, %d): stub\n", FileHandle, Index); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + DWORD size = 0, count = 0, sd_VirtualAddr = 0, offset = 0; + DWORD data_size = 0, cert_size = 0, cert_size_padded = 0, ret = 0; + LPVOID cert_data; + BOOL r; + + TRACE("(%p, %d)\n", FileHandle, Index); + + r = ImageEnumerateCertificates(FileHandle, CERT_SECTION_TYPE_ANY, &count, NULL, 0); + + if ((!r) || (count == 0)) + return FALSE; + + if ((!IMAGEHLP_GetSecurityDirOffset(FileHandle, &sd_VirtualAddr, &size)) || + (!IMAGEHLP_GetCertificateOffset(FileHandle, Index, &offset, &cert_size))) + return FALSE; + + /* Ignore any padding we have, too */ + if (cert_size % 8) + cert_size_padded = cert_size + (8 - (cert_size % 8)); + else + cert_size_padded = cert_size; + + data_size = size - (offset - sd_VirtualAddr) - cert_size_padded; + + if (data_size == 0) + { + ret = SetFilePointer(FileHandle, sd_VirtualAddr, NULL, FILE_BEGIN); + + if (ret == INVALID_SET_FILE_POINTER) + return FALSE; + } + else + { + cert_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, data_size); + + if (!cert_data) + return FALSE; + + ret = SetFilePointer(FileHandle, offset + cert_size_padded, NULL, FILE_BEGIN); + + if (ret == INVALID_SET_FILE_POINTER) + goto error; + + /* Read any subsequent certificates */ + r = ReadFile(FileHandle, cert_data, data_size, &count, NULL); + + if ((!r) || (count != data_size)) + goto error; + + SetFilePointer(FileHandle, offset, NULL, FILE_BEGIN); + + /* Write them one index back */ + r = WriteFile(FileHandle, cert_data, data_size, &count, NULL); + + if ((!r) || (count != data_size)) + goto error; + + HeapFree(GetProcessHeap(), 0, cert_data); + } + + /* If security directory is at end of file, trim the file */ + if (GetFileSize(FileHandle, NULL) == sd_VirtualAddr + size) + SetEndOfFile(FileHandle); + + if (count == 1) + r = IMAGEHLP_SetSecurityDirOffset(FileHandle, 0, 0); + else + r = IMAGEHLP_SetSecurityDirOffset(FileHandle, sd_VirtualAddr, size - cert_size_padded); + + if (!r) + return FALSE; + + return TRUE; + +error: + HeapFree(GetProcessHeap(), 0, cert_data); + return FALSE; } diff --git a/dlls/imagehlp/tests/integrity.c b/dlls/imagehlp/tests/integrity.c index e89167c4fd4..718ca3eba44 100644 --- a/dlls/imagehlp/tests/integrity.c +++ b/dlls/imagehlp/tests/integrity.c @@ -201,10 +201,10 @@ static void test_remove_certificate(void) return; } - todo_wine ok (pImageRemoveCertificate(hFile, 0), "Unable to remove certificate from file; err=%x\n", GetLastError()); + ok (pImageRemoveCertificate(hFile, 0), "Unable to remove certificate from file; err=%x\n", GetLastError()); /* Test to see if the certificate has actually been removed */ - todo_wine ok(pImageGetCertificateHeader(hFile, 0, &cert) == FALSE, "Certificate header retrieval succeeded when it should have failed\n"); + ok(pImageGetCertificateHeader(hFile, 0, &cert) == FALSE, "Certificate header retrieval succeeded when it should have failed\n"); CloseHandle(hFile); } -- 2.11.4.GIT