diff --git a/dlls/wintrust/register.c b/dlls/wintrust/register.c index 6f0f57516b9..d16b1862fa7 100644 --- a/dlls/wintrust/register.c +++ b/dlls/wintrust/register.c @@ -771,6 +771,88 @@ BOOL WINAPI WintrustAddDefaultForUsage(const char *pszUsageOID, return TRUE; } +static FARPROC WINTRUST_ReadProviderFromReg(WCHAR *GuidString, const WCHAR *FunctionType) +{ + WCHAR ProvKey[MAX_PATH], DllName[MAX_PATH]; + char FunctionName[MAX_PATH]; + HKEY Key; + LONG Res = ERROR_SUCCESS; + DWORD Size; + HMODULE Lib; + FARPROC Func = NULL; + + /* Create the needed key string */ + ProvKey[0]='\0'; + lstrcatW(ProvKey, Trust); + lstrcatW(ProvKey, FunctionType); + lstrcatW(ProvKey, GuidString); + + Res = RegOpenKeyExW(HKEY_LOCAL_MACHINE, ProvKey, 0, KEY_READ, &Key); + if (Res != ERROR_SUCCESS) goto error_close_key; + + /* Read the $DLL entry */ + Size = sizeof(DllName); + Res = RegQueryValueExW(Key, Dll, NULL, NULL, (LPBYTE)DllName, &Size); + if (Res != ERROR_SUCCESS) goto error_close_key; + + /* Read the $Function entry */ + Size = sizeof(FunctionName); + Res = RegQueryValueExA(Key, "$Function", NULL, NULL, (LPBYTE)FunctionName, &Size); + if (Res != ERROR_SUCCESS) goto error_close_key; + + /* Load the library - there appears to be no way to close a provider, so + * just leak the module handle. + */ + Lib = LoadLibraryW(DllName); + Func = GetProcAddress(Lib, FunctionName); + +error_close_key: + RegCloseKey(Key); + + return Func; +} + +/*********************************************************************** + * WintrustLoadFunctionPointers (WINTRUST.@) + */ +BOOL WINAPI WintrustLoadFunctionPointers( GUID* pgActionID, + CRYPT_PROVIDER_FUNCTIONS* pPfns ) +{ + WCHAR GuidString[39]; + + TRACE("(%s %p)\n", debugstr_guid(pgActionID), pPfns); + + if (!pPfns) return FALSE; + if (!pgActionID) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + if (pPfns->cbStruct != sizeof(CRYPT_PROVIDER_FUNCTIONS)) return FALSE; + + /* Create this string only once, instead of in the helper function */ + WINTRUST_Guid2Wstr( pgActionID, GuidString); + + /* Get the function pointers from the registry, where applicable */ + pPfns->pfnAlloc = NULL; + pPfns->pfnFree = NULL; + pPfns->pfnAddStore2Chain = NULL; + pPfns->pfnAddSgnr2Chain = NULL; + pPfns->pfnAddCert2Chain = NULL; + pPfns->pfnAddPrivData2Chain = NULL; + pPfns->psUIpfns = NULL; + pPfns->pfnInitialize = (PFN_PROVIDER_INIT_CALL)WINTRUST_ReadProviderFromReg(GuidString, Initialization); + pPfns->pfnObjectTrust = (PFN_PROVIDER_OBJTRUST_CALL)WINTRUST_ReadProviderFromReg(GuidString, Message); + pPfns->pfnSignatureTrust = (PFN_PROVIDER_SIGTRUST_CALL)WINTRUST_ReadProviderFromReg(GuidString, Signature); + pPfns->pfnCertificateTrust = (PFN_PROVIDER_CERTTRUST_CALL)WINTRUST_ReadProviderFromReg(GuidString, Certificate); + pPfns->pfnCertCheckPolicy = (PFN_PROVIDER_CERTCHKPOLICY_CALL)WINTRUST_ReadProviderFromReg(GuidString, CertCheck); + pPfns->pfnFinalPolicy = (PFN_PROVIDER_FINALPOLICY_CALL)WINTRUST_ReadProviderFromReg(GuidString, FinalPolicy); + pPfns->pfnTestFinalPolicy = (PFN_PROVIDER_TESTFINALPOLICY_CALL)WINTRUST_ReadProviderFromReg(GuidString, DiagnosticPolicy); + pPfns->pfnCleanupPolicy = (PFN_PROVIDER_CLEANUP_CALL)WINTRUST_ReadProviderFromReg(GuidString, Cleanup); + + return TRUE; +} + /*********************************************************************** * WINTRUST_SIPPAddProvider * diff --git a/dlls/wintrust/tests/register.c b/dlls/wintrust/tests/register.c index d442c07ae16..95f8dc68032 100644 --- a/dlls/wintrust/tests/register.c +++ b/dlls/wintrust/tests/register.c @@ -31,6 +31,7 @@ static BOOL (WINAPI * pWintrustAddActionID)(GUID*, DWORD, CRYPT_REGISTER_ACTIONID*); static BOOL (WINAPI * pWintrustAddDefaultForUsage)(const CHAR*,CRYPT_PROVIDER_REGDEFUSAGE*); static BOOL (WINAPI * pWintrustRemoveActionID)(GUID*); +static BOOL (WINAPI * pWintrustLoadFunctionPointers)(GUID *, CRYPT_PROVIDER_FUNCTIONS *); static HMODULE hWintrust = 0; @@ -55,6 +56,7 @@ static BOOL InitFunctionPtrs(void) WINTRUST_GET_PROC(WintrustAddActionID) WINTRUST_GET_PROC(WintrustAddDefaultForUsage) WINTRUST_GET_PROC(WintrustRemoveActionID) + WINTRUST_GET_PROC(WintrustLoadFunctionPointers) return TRUE; } @@ -256,6 +258,34 @@ static void test_AddDefaultForUsage(void) } } +static void test_LoadFunctionPointers(void) +{ + BOOL ret; + CRYPT_PROVIDER_FUNCTIONS funcs; + GUID action = WINTRUST_ACTION_GENERIC_VERIFY_V2; + + SetLastError(0xdeadbeef); + ret = pWintrustLoadFunctionPointers(NULL, NULL); + ok(!ret && GetLastError() == 0xdeadbeef, "Expected failure\n"); + SetLastError(0xdeadbeef); + ret = pWintrustLoadFunctionPointers(&action, NULL); + ok(!ret && GetLastError() == 0xdeadbeef, "Expected failure\n"); + + SetLastError(0xdeadbeef); + ret = pWintrustLoadFunctionPointers(NULL, &funcs); + ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + + SetLastError(0xdeadbeef); + funcs.cbStruct = 0; + ret = pWintrustLoadFunctionPointers(&action, &funcs); + ok(!ret && GetLastError() == 0xdeadbeef, "Expected failure\n"); + SetLastError(0xdeadbeef); + funcs.cbStruct = sizeof(funcs); + ret = pWintrustLoadFunctionPointers(&action, &funcs); + ok(ret, "WintrustLoadFunctionPointers failed: %d\n", GetLastError()); +} + START_TEST(register) { if(!InitFunctionPtrs()) @@ -263,6 +293,7 @@ START_TEST(register) test_AddRem_ActionID(); test_AddDefaultForUsage(); + test_LoadFunctionPointers(); FreeLibrary(hWintrust); } diff --git a/dlls/wintrust/wintrust_main.c b/dlls/wintrust/wintrust_main.c index 41c97d9337f..073a36991a8 100644 --- a/dlls/wintrust/wintrust_main.c +++ b/dlls/wintrust/wintrust_main.c @@ -118,17 +118,6 @@ CRYPT_PROVIDER_DATA * WINAPI WTHelperProvDataFromStateData(HANDLE hStateData) return NULL; } -/*********************************************************************** - * WintrustLoadFunctionPointers (WINTRUST.@) - */ -BOOL WINAPI WintrustLoadFunctionPointers( GUID* pgActionID, - CRYPT_PROVIDER_FUNCTIONS* pPfns ) -{ - FIXME("%s %p\n", debugstr_guid(pgActionID), pPfns); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - /*********************************************************************** * WintrustGetRegPolicyFlags (WINTRUST.@) */