Commit 3747f223 authored by Paul Vriens's avatar Paul Vriens Committed by Alexandre Julliard

wintrust: Implementation of WintrustAddActionID.

parent 94e4f593
...@@ -49,6 +49,48 @@ static const WCHAR FinalPolicy[] = {'F','i','n','a','l','P','o','l','i','c' ...@@ -49,6 +49,48 @@ static const WCHAR FinalPolicy[] = {'F','i','n','a','l','P','o','l','i','c'
static const WCHAR DiagnosticPolicy[] = {'D','i','a','g','n','o','s','t','i','c','P','o','l','i','c','y','\\', 0}; static const WCHAR DiagnosticPolicy[] = {'D','i','a','g','n','o','s','t','i','c','P','o','l','i','c','y','\\', 0};
static const WCHAR Cleanup[] = {'C','l','e','a','n','u','p','\\', 0}; static const WCHAR Cleanup[] = {'C','l','e','a','n','u','p','\\', 0};
/***********************************************************************
* WINTRUST_WriteProviderToReg
*
* Helper function for WintrustAddActionID
*
*/
static LONG WINTRUST_WriteProviderToReg(WCHAR* GuidString,
const WCHAR* FunctionType,
CRYPT_TRUST_REG_ENTRY RegEntry)
{
static const WCHAR Dll[] = {'$','D','L','L', 0};
static const WCHAR Function[] = {'$','F','u','n','c','t','i','o','n', 0};
WCHAR ProvKey[MAX_PATH];
HKEY Key;
LONG Res = ERROR_SUCCESS;
/* Create the needed key string */
ProvKey[0]='\0';
lstrcatW(ProvKey, Trust);
lstrcatW(ProvKey, FunctionType);
lstrcatW(ProvKey, GuidString);
if (!RegEntry.pwszDLLName || !RegEntry.pwszFunctionName)
return ERROR_INVALID_PARAMETER;
Res = RegCreateKeyExW(HKEY_LOCAL_MACHINE, ProvKey, 0, NULL, 0, KEY_WRITE, NULL, &Key, NULL);
if (Res != ERROR_SUCCESS) goto error_close_key;
/* Create the $DLL entry */
Res = RegSetValueExW(Key, Dll, 0, REG_SZ, (BYTE*)RegEntry.pwszDLLName,
(lstrlenW(RegEntry.pwszDLLName) + 1)*sizeof(WCHAR));
if (Res != ERROR_SUCCESS) goto error_close_key;
/* Create the $Function entry */
Res = RegSetValueExW(Key, Function, 0, REG_SZ, (BYTE*)RegEntry.pwszFunctionName,
(lstrlenW(RegEntry.pwszFunctionName) + 1)*sizeof(WCHAR));
error_close_key:
RegCloseKey(Key);
return Res;
}
/*********************************************************************** /***********************************************************************
* WintrustAddActionID (WINTRUST.@) * WintrustAddActionID (WINTRUST.@)
...@@ -71,17 +113,77 @@ static const WCHAR Cleanup[] = {'C','l','e','a','n','u','p','\\', 0}; ...@@ -71,17 +113,77 @@ static const WCHAR Cleanup[] = {'C','l','e','a','n','u','p','\\', 0};
* to the registry. No verification takes place whether a DLL or it's * to the registry. No verification takes place whether a DLL or it's
* entrypoints exist. * entrypoints exist.
* Information in the registry will always be overwritten. * Information in the registry will always be overwritten.
*
*/ */
BOOL WINAPI WintrustAddActionID( GUID* pgActionID, DWORD fdwFlags, BOOL WINAPI WintrustAddActionID( GUID* pgActionID, DWORD fdwFlags,
CRYPT_REGISTER_ACTIONID* psProvInfo) CRYPT_REGISTER_ACTIONID* psProvInfo)
{ {
FIXME("%p %lx %p\n", pgActionID, fdwFlags, psProvInfo); static const WCHAR wszFormat[] = {'{','%','0','8','l','X','-','%','0','4','X','-','%','0','4','X','-',
SetLastError(ERROR_CALL_NOT_IMPLEMENTED); '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2',
return FALSE; 'X','%','0','2','X','%','0','2','X','}', 0};
WCHAR GuidString[39];
LONG Res;
LONG WriteActionError = ERROR_SUCCESS;
TRACE("%p %lx %p\n", debugstr_guid(pgActionID), fdwFlags, psProvInfo);
/* Some sanity checks.
* We use the W2K3 last error as it makes more sense (W2K leaves the last error
* as is).
*/
if (!pgActionID ||
!psProvInfo ||
(psProvInfo->cbStruct != sizeof(CRYPT_REGISTER_ACTIONID)))
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
/* Create this string only once, instead of in the helper function */
wsprintfW(GuidString, wszFormat, pgActionID->Data1, pgActionID->Data2, pgActionID->Data3,
pgActionID->Data4[0], pgActionID->Data4[1], pgActionID->Data4[2], pgActionID->Data4[3],
pgActionID->Data4[4], pgActionID->Data4[5], pgActionID->Data4[6], pgActionID->Data4[7]);
/* Write the information to the registry */
Res = WINTRUST_WriteProviderToReg(GuidString, Initialization , psProvInfo->sInitProvider);
if (Res != ERROR_SUCCESS) WriteActionError = Res;
Res = WINTRUST_WriteProviderToReg(GuidString, Message , psProvInfo->sObjectProvider);
if (Res != ERROR_SUCCESS) WriteActionError = Res;
Res = WINTRUST_WriteProviderToReg(GuidString, Signature , psProvInfo->sSignatureProvider);
if (Res != ERROR_SUCCESS) WriteActionError = Res;
Res = WINTRUST_WriteProviderToReg(GuidString, Certificate , psProvInfo->sCertificateProvider);
if (Res != ERROR_SUCCESS) WriteActionError = Res;
Res = WINTRUST_WriteProviderToReg(GuidString, CertCheck , psProvInfo->sCertificatePolicyProvider);
if (Res != ERROR_SUCCESS) WriteActionError = Res;
Res = WINTRUST_WriteProviderToReg(GuidString, FinalPolicy , psProvInfo->sFinalPolicyProvider);
if (Res != ERROR_SUCCESS) WriteActionError = Res;
Res = WINTRUST_WriteProviderToReg(GuidString, DiagnosticPolicy, psProvInfo->sTestPolicyProvider);
if (Res != ERROR_SUCCESS) WriteActionError = Res;
Res = WINTRUST_WriteProviderToReg(GuidString, Cleanup , psProvInfo->sCleanupProvider);
if (Res != ERROR_SUCCESS) WriteActionError = Res;
/* Testing (by restricting access to the registry for some keys) shows that the last failing function
* will be used for last error.
* an error is the one used to propagate the last error.
* If the flag WT_ADD_ACTION_ID_RET_RESULT_FLAG is set and there are errors when adding the action
* we have to return FALSE. Errors includes both invalid entries as well as registry errors.
* Testing also showed that one error doesn't stop the registry writes. Every action will be dealt with.
*/
if (WriteActionError != ERROR_SUCCESS)
{
SetLastError(WriteActionError);
if (fdwFlags == WT_ADD_ACTION_ID_RET_RESULT_FLAG)
return FALSE;
}
return TRUE;
} }
/*********************************************************************** /***********************************************************************
* WINTRUST_RemoveProviderFromReg (WINTRUST.@) * WINTRUST_RemoveProviderFromReg
* *
* Helper function for WintrustRemoveActionID * Helper function for WintrustRemoveActionID
* *
......
...@@ -70,47 +70,35 @@ static void test_AddRem_ActionID(void) ...@@ -70,47 +70,35 @@ static void test_AddRem_ActionID(void)
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = pWintrustAddActionID(NULL, 0, NULL); ret = pWintrustAddActionID(NULL, 0, NULL);
ok (!ret, "Expected WintrustAddActionID to fail.\n"); ok (!ret, "Expected WintrustAddActionID to fail.\n");
todo_wine ok (GetLastError() == ERROR_INVALID_PARAMETER /* XP/W2K3 */ ||
{ GetLastError() == 0xdeadbeef /* Win98/NT4/W2K */,
ok (GetLastError() == ERROR_INVALID_PARAMETER /* XP/W2K3 */ || "Expected ERROR_INVALID_PARAMETER(W2K3) or 0xdeadbeef(Win98/NT4/W2K), got %ld.\n", GetLastError());
GetLastError() == 0xdeadbeef /* Win98/NT4/W2K */,
"Expected ERROR_INVALID_PARAMETER(W2K3) or 0xdeadbeef(Win98/NT4/W2K), got %ld.\n", GetLastError());
}
/* NULL functions */ /* NULL functions */
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = pWintrustAddActionID(&ActionID, 0, NULL); ret = pWintrustAddActionID(&ActionID, 0, NULL);
ok (!ret, "Expected WintrustAddActionID to fail.\n"); ok (!ret, "Expected WintrustAddActionID to fail.\n");
todo_wine ok (GetLastError() == ERROR_INVALID_PARAMETER /* XP/W2K3 */ ||
{ GetLastError() == 0xdeadbeef /* Win98/NT4/W2K */,
ok (GetLastError() == ERROR_INVALID_PARAMETER /* XP/W2K3 */ || "Expected ERROR_INVALID_PARAMETER(W2K3) or 0xdeadbeef(Win98/NT4/W2K), got %ld.\n", GetLastError());
GetLastError() == 0xdeadbeef /* Win98/NT4/W2K */,
"Expected ERROR_INVALID_PARAMETER(W2K3) or 0xdeadbeef(Win98/NT4/W2K), got %ld.\n", GetLastError());
}
/* All OK (although no functions defined), except cbStruct is not set in ActionIDFunctions */ /* All OK (although no functions defined), except cbStruct is not set in ActionIDFunctions */
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
memset(&ActionIDFunctions, 0, sizeof(CRYPT_REGISTER_ACTIONID)); memset(&ActionIDFunctions, 0, sizeof(CRYPT_REGISTER_ACTIONID));
ret = pWintrustAddActionID(&ActionID, 0, &ActionIDFunctions); ret = pWintrustAddActionID(&ActionID, 0, &ActionIDFunctions);
ok (!ret, "Expected WintrustAddActionID to fail.\n"); ok (!ret, "Expected WintrustAddActionID to fail.\n");
todo_wine ok (GetLastError() == ERROR_INVALID_PARAMETER /* XP/W2K3 */ ||
{ GetLastError() == 0xdeadbeef /* Win98/NT4/W2K */,
ok (GetLastError() == ERROR_INVALID_PARAMETER /* XP/W2K3 */ || "Expected ERROR_INVALID_PARAMETER(W2K3) or 0xdeadbeef(Win98/NT4/W2K), got %ld.\n", GetLastError());
GetLastError() == 0xdeadbeef /* Win98/NT4/W2K */,
"Expected ERROR_INVALID_PARAMETER(W2K3) or 0xdeadbeef(Win98/NT4/W2K), got %ld.\n", GetLastError());
}
/* All OK (although no functions defined) and cbStruct is set now */ /* All OK (although no functions defined) and cbStruct is set now */
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
memset(&ActionIDFunctions, 0, sizeof(CRYPT_REGISTER_ACTIONID)); memset(&ActionIDFunctions, 0, sizeof(CRYPT_REGISTER_ACTIONID));
ActionIDFunctions.cbStruct = sizeof(CRYPT_REGISTER_ACTIONID); ActionIDFunctions.cbStruct = sizeof(CRYPT_REGISTER_ACTIONID);
ret = pWintrustAddActionID(&ActionID, 0, &ActionIDFunctions); ret = pWintrustAddActionID(&ActionID, 0, &ActionIDFunctions);
todo_wine ok (ret, "Expected WintrustAddActionID to succeed.\n");
{ ok (GetLastError() == ERROR_INVALID_PARAMETER,
ok (ret, "Expected WintrustAddActionID to succeed.\n"); "Expected ERROR_INVALID_PARAMETER, got %ld.\n", GetLastError());
ok (GetLastError() == ERROR_INVALID_PARAMETER /* W2K */,
"Expected ERROR_INVALID_PARAMETER, got %ld.\n", GetLastError());
}
/* All OK and all (but 1) functions are correctly defined. The DLL and entrypoints /* All OK and all (but 1) functions are correctly defined. The DLL and entrypoints
* are not present. * are not present.
...@@ -127,12 +115,9 @@ static void test_AddRem_ActionID(void) ...@@ -127,12 +115,9 @@ static void test_AddRem_ActionID(void)
ActionIDFunctions.sCleanupProvider = DummyProvider; ActionIDFunctions.sCleanupProvider = DummyProvider;
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = pWintrustAddActionID(&ActionID, 0, &ActionIDFunctions); ret = pWintrustAddActionID(&ActionID, 0, &ActionIDFunctions);
todo_wine ok (ret, "Expected WintrustAddActionID to succeed.\n");
{ ok (GetLastError() == ERROR_INVALID_PARAMETER,
ok (ret, "Expected WintrustAddActionID to succeed.\n"); "Expected ERROR_INVALID_PARAMETER, got %ld.\n", GetLastError());
ok (GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %ld.\n", GetLastError());
}
/* All OK and all functions are correctly defined. The DLL and entrypoints /* All OK and all functions are correctly defined. The DLL and entrypoints
* are not present. * are not present.
...@@ -149,12 +134,9 @@ static void test_AddRem_ActionID(void) ...@@ -149,12 +134,9 @@ static void test_AddRem_ActionID(void)
ActionIDFunctions.sCleanupProvider = DummyProvider; ActionIDFunctions.sCleanupProvider = DummyProvider;
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = pWintrustAddActionID(&ActionID, 0, &ActionIDFunctions); ret = pWintrustAddActionID(&ActionID, 0, &ActionIDFunctions);
todo_wine ok (ret, "Expected WintrustAddActionID to succeed.\n");
{ ok (GetLastError() == 0xdeadbeef,
ok (ret, "Expected WintrustAddActionID to succeed.\n"); "Expected 0xdeadbeef, got %ld.\n", GetLastError());
ok (GetLastError() == 0xdeadbeef,
"Expected 0xdeadbeef, got %ld.\n", GetLastError());
}
SetLastError(0xdeadbeef); SetLastError(0xdeadbeef);
ret = pWintrustRemoveActionID(&ActionID); ret = pWintrustRemoveActionID(&ActionID);
......
...@@ -297,6 +297,7 @@ typedef struct _CRYPT_PROVUI_FUNCS { ...@@ -297,6 +297,7 @@ typedef struct _CRYPT_PROVUI_FUNCS {
#include <poppack.h> #include <poppack.h>
#define WT_ADD_ACTION_ID_RET_RESULT_FLAG 1
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment