Module: wine Branch: master Commit: f3f25af9002d4f3386f1eb372173b80ace4cf164 URL: http://source.winehq.org/git/wine.git/?a=commit;h=f3f25af9002d4f3386f1eb3721...
Author: Hans Leidekker hans@codeweavers.com Date: Wed Mar 30 12:31:35 2011 +0200
msi: Implement MsiGetFileSignatureInformationA/W.
---
dlls/msi/Makefile.in | 2 +- dlls/msi/msi.c | 80 +++++++++++++++++++++++++++++++++++++++++--------- dlls/msi/tests/msi.c | 43 ++++++++++++++++++++++++++- 3 files changed, 109 insertions(+), 16 deletions(-)
diff --git a/dlls/msi/Makefile.in b/dlls/msi/Makefile.in index 8217bcf..066398e 100644 --- a/dlls/msi/Makefile.in +++ b/dlls/msi/Makefile.in @@ -1,7 +1,7 @@ MODULE = msi.dll IMPORTLIB = msi IMPORTS = uuid urlmon wininet comctl32 shell32 shlwapi cabinet oleaut32 ole32 version user32 gdi32 advapi32 -DELAYIMPORTS = odbccp32 +DELAYIMPORTS = odbccp32 wintrust crypt32
C_SRCS = \ action.c \ diff --git a/dlls/msi/msi.c b/dlls/msi/msi.c index 325a5b0..890132a 100644 --- a/dlls/msi/msi.c +++ b/dlls/msi/msi.c @@ -28,7 +28,6 @@ #include "winreg.h" #include "winnls.h" #include "shlwapi.h" -#include "wine/debug.h" #include "msi.h" #include "msidefs.h" #include "msiquery.h" @@ -39,6 +38,10 @@ #include "shlobj.h" #include "shobjidl.h" #include "objidl.h" +#include "wintrust.h" +#include "softpub.h" + +#include "wine/debug.h" #include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(msi); @@ -2261,22 +2264,71 @@ UINT WINAPI MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor, return ERROR_CALL_NOT_IMPLEMENTED; }
-HRESULT WINAPI MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath, - DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, LPBYTE pbHashData, - LPDWORD pcbHashData) +HRESULT WINAPI MsiGetFileSignatureInformationA( LPCSTR path, DWORD flags, PCCERT_CONTEXT *cert, + LPBYTE hash, LPDWORD hashlen ) { - FIXME("%s %08x %p %p %p\n", debugstr_a(szSignedObjectPath), dwFlags, - ppcCertContext, pbHashData, pcbHashData); - return ERROR_CALL_NOT_IMPLEMENTED; + UINT r; + WCHAR *pathW = NULL; + + TRACE("%s %08x %p %p %p\n", debugstr_a(path), flags, cert, hash, hashlen); + + if (path && !(pathW = strdupAtoW( path ))) return ERROR_OUTOFMEMORY; + r = MsiGetFileSignatureInformationW( pathW, flags, cert, hash, hashlen ); + msi_free( pathW ); + return r; }
-HRESULT WINAPI MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath, - DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, LPBYTE pbHashData, - LPDWORD pcbHashData) -{ - FIXME("%s %08x %p %p %p\n", debugstr_w(szSignedObjectPath), dwFlags, - ppcCertContext, pbHashData, pcbHashData); - return ERROR_CALL_NOT_IMPLEMENTED; +HRESULT WINAPI MsiGetFileSignatureInformationW( LPCWSTR path, DWORD flags, PCCERT_CONTEXT *cert, + LPBYTE hash, LPDWORD hashlen ) +{ + static GUID generic_verify_v2 = WINTRUST_ACTION_GENERIC_VERIFY_V2; + HRESULT hr; + WINTRUST_DATA data; + WINTRUST_FILE_INFO info; + CRYPT_PROVIDER_SGNR *signer; + CRYPT_PROVIDER_CERT *provider; + + TRACE("%s %08x %p %p %p\n", debugstr_w(path), flags, cert, hash, hashlen); + + if (!path || !cert) return E_INVALIDARG; + + info.cbStruct = sizeof(info); + info.pcwszFilePath = path; + info.hFile = NULL; + info.pgKnownSubject = NULL; + + data.cbStruct = sizeof(data); + data.pPolicyCallbackData = NULL; + data.pSIPClientData = NULL; + data.dwUIChoice = WTD_UI_NONE; + data.fdwRevocationChecks = WTD_REVOKE_WHOLECHAIN; + data.dwUnionChoice = WTD_CHOICE_FILE; + data.u.pFile = &info; + data.dwStateAction = WTD_STATEACTION_VERIFY; + data.hWVTStateData = NULL; + data.pwszURLReference = NULL; + data.dwProvFlags = 0; + data.dwUIContext = WTD_UICONTEXT_INSTALL; + hr = WinVerifyTrustEx( INVALID_HANDLE_VALUE, &generic_verify_v2, &data ); + if (FAILED(hr)) return hr; + + signer = WTHelperGetProvSignerFromChain( data.hWVTStateData, 0, FALSE, 0 ); + if (!signer) return TRUST_E_NOSIGNATURE; + if (hash) + { + DWORD len = signer->psSigner->EncryptedHash.cbData; + if (*hashlen < len) + { + *hashlen = len; + return HRESULT_FROM_WIN32(ERROR_MORE_DATA); + } + memcpy( hash, signer->psSigner->EncryptedHash.pbData, len ); + *hashlen = len; + } + provider = WTHelperGetProvCertFromChain( signer, 0 ); + if (!provider) return TRUST_E_PROVIDER_UNKNOWN; + *cert = CertDuplicateCertificateContext( provider->pCert ); + return S_OK; }
/****************************************************************** diff --git a/dlls/msi/tests/msi.c b/dlls/msi/tests/msi.c index e21d1e1..6ba0e11 100644 --- a/dlls/msi/tests/msi.c +++ b/dlls/msi/tests/msi.c @@ -11753,6 +11753,47 @@ static void test_MsiEnumProducts(void) LocalFree(usersid); }
+static void test_MsiGetFileSignatureInformation(void) +{ + HRESULT hr; + const CERT_CONTEXT *cert; + DWORD len; + + hr = MsiGetFileSignatureInformationA( NULL, 0, NULL, NULL, NULL ); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr); + + hr = MsiGetFileSignatureInformationA( NULL, 0, NULL, NULL, &len ); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr); + + hr = MsiGetFileSignatureInformationA( NULL, 0, &cert, NULL, &len ); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr); + + hr = MsiGetFileSignatureInformationA( "", 0, NULL, NULL, NULL ); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr); + + hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, NULL ); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr); + + hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len ); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr); + + hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len ); + todo_wine ok(hr == CRYPT_E_FILE_ERROR, "expected CRYPT_E_FILE_ERROR got 0x%08x\n", hr); + + create_file( "signature.bin", "signature", sizeof("signature") ); + + hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, NULL ); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr); + + hr = MsiGetFileSignatureInformationA( "signature.bin", 0, NULL, NULL, &len ); + ok(hr == E_INVALIDARG, "expected E_INVALIDARG got 0x%08x\n", hr); + + hr = MsiGetFileSignatureInformationA( "signature.bin", 0, &cert, NULL, &len ); + todo_wine ok(hr == HRESULT_FROM_WIN32(ERROR_FUNCTION_FAILED), "got 0x%08x\n", hr); + + DeleteFileA( "signature.bin" ); +} + START_TEST(msi) { init_functionpointers(); @@ -11786,6 +11827,6 @@ START_TEST(msi) test_MsiGetPatchInfo(); test_MsiEnumProducts(); } - test_MsiGetFileVersion(); + test_MsiGetFileSignatureInformation(); }