[wintrust] Implementation of WintrustAddActionID

Paul Vriens Paul.Vriens at xs4all.nl
Thu Aug 31 09:37:19 CDT 2006


Hi,

Implemented WintrustAddActionID. The idea was that this function could be used
in DllRegister. Native however doesn't use this for DllRegister. One of the
reasons could be that some actions are not needed and there is no way to tell
WintrustAddActionID to skip an action without reporting a failure.

Changelog
  Implementation of WintrustAddActionID

Cheers,

Paul.
---
 dlls/wintrust/register.c       |  110 +++++++++++++++++++++++++++++++++++++++-
 dlls/wintrust/tests/register.c |   54 +++++++-------------
 include/wintrust.h             |    1 
 3 files changed, 125 insertions(+), 40 deletions(-)

diff --git a/dlls/wintrust/register.c b/dlls/wintrust/register.c
index 93b1fed..10ccbae 100644
--- a/dlls/wintrust/register.c
+++ b/dlls/wintrust/register.c
@@ -49,6 +49,48 @@ static const WCHAR FinalPolicy[]      = 
 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};
 
+/***********************************************************************
+ *              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.@)
@@ -71,17 +113,77 @@ static const WCHAR Cleanup[]          = 
  *   to the registry. No verification takes place whether a DLL or it's
  *   entrypoints exist.
  *   Information in the registry will always be overwritten.
+ *
  */
 BOOL WINAPI WintrustAddActionID( GUID* pgActionID, DWORD fdwFlags,
                                  CRYPT_REGISTER_ACTIONID* psProvInfo)
 {
-    FIXME("%p %lx %p\n", pgActionID, fdwFlags, psProvInfo);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    static const WCHAR wszFormat[] = {'{','%','0','8','l','X','-','%','0','4','X','-','%','0','4','X','-',
+                                      '%','0','2','X','%','0','2','X','-','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2',
+                                      '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
  *
diff --git a/dlls/wintrust/tests/register.c b/dlls/wintrust/tests/register.c
index 2a56c07..51804ac 100644
--- a/dlls/wintrust/tests/register.c
+++ b/dlls/wintrust/tests/register.c
@@ -70,47 +70,35 @@ static void test_AddRem_ActionID(void)
     SetLastError(0xdeadbeef);
     ret = pWintrustAddActionID(NULL, 0, NULL);
     ok (!ret, "Expected WintrustAddActionID to fail.\n");
-    todo_wine
-    {
-        ok (GetLastError() == ERROR_INVALID_PARAMETER /* XP/W2K3 */ ||
-            GetLastError() == 0xdeadbeef              /* Win98/NT4/W2K */,
-            "Expected ERROR_INVALID_PARAMETER(W2K3) or 0xdeadbeef(Win98/NT4/W2K), got %ld.\n", GetLastError());
-    }
+    ok (GetLastError() == ERROR_INVALID_PARAMETER /* XP/W2K3 */ ||
+        GetLastError() == 0xdeadbeef              /* Win98/NT4/W2K */,
+        "Expected ERROR_INVALID_PARAMETER(W2K3) or 0xdeadbeef(Win98/NT4/W2K), got %ld.\n", GetLastError());
 
     /* NULL functions */
     SetLastError(0xdeadbeef);
     ret = pWintrustAddActionID(&ActionID, 0, NULL);
     ok (!ret, "Expected WintrustAddActionID to fail.\n");
-    todo_wine
-    {
-        ok (GetLastError() == ERROR_INVALID_PARAMETER /* XP/W2K3 */ ||
-            GetLastError() == 0xdeadbeef              /* Win98/NT4/W2K */,
-            "Expected ERROR_INVALID_PARAMETER(W2K3) or 0xdeadbeef(Win98/NT4/W2K), got %ld.\n", GetLastError());
-    }
+    ok (GetLastError() == ERROR_INVALID_PARAMETER /* XP/W2K3 */ ||
+        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 */
     SetLastError(0xdeadbeef);
     memset(&ActionIDFunctions, 0, sizeof(CRYPT_REGISTER_ACTIONID));
     ret = pWintrustAddActionID(&ActionID, 0, &ActionIDFunctions);
     ok (!ret, "Expected WintrustAddActionID to fail.\n");
-    todo_wine
-    {
-        ok (GetLastError() == ERROR_INVALID_PARAMETER /* XP/W2K3 */ ||
-            GetLastError() == 0xdeadbeef              /* Win98/NT4/W2K */,
-            "Expected ERROR_INVALID_PARAMETER(W2K3) or 0xdeadbeef(Win98/NT4/W2K), got %ld.\n", GetLastError());
-    }
+    ok (GetLastError() == ERROR_INVALID_PARAMETER /* XP/W2K3 */ ||
+        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 */
     SetLastError(0xdeadbeef);
     memset(&ActionIDFunctions, 0, sizeof(CRYPT_REGISTER_ACTIONID));
     ActionIDFunctions.cbStruct = sizeof(CRYPT_REGISTER_ACTIONID);
     ret = pWintrustAddActionID(&ActionID, 0, &ActionIDFunctions);
-    todo_wine
-    {
-        ok (ret, "Expected WintrustAddActionID to succeed.\n");
-        ok (GetLastError() == ERROR_INVALID_PARAMETER /* W2K */,
-            "Expected ERROR_INVALID_PARAMETER, got %ld.\n", GetLastError());
-    }
+    ok (ret, "Expected WintrustAddActionID to succeed.\n");
+    ok (GetLastError() == ERROR_INVALID_PARAMETER,
+        "Expected ERROR_INVALID_PARAMETER, got %ld.\n", GetLastError());
 
     /* All OK and all (but 1) functions are correctly defined. The DLL and entrypoints
      * are not present.
@@ -127,12 +115,9 @@ static void test_AddRem_ActionID(void)
     ActionIDFunctions.sCleanupProvider = DummyProvider;
     SetLastError(0xdeadbeef);
     ret = pWintrustAddActionID(&ActionID, 0, &ActionIDFunctions);
-    todo_wine
-    {
-        ok (ret, "Expected WintrustAddActionID to succeed.\n");
-        ok (GetLastError() == ERROR_INVALID_PARAMETER,
-            "Expected ERROR_INVALID_PARAMETER, got %ld.\n", GetLastError());
-    }
+    ok (ret, "Expected WintrustAddActionID to succeed.\n");
+    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
      * are not present.
@@ -149,12 +134,9 @@ static void test_AddRem_ActionID(void)
     ActionIDFunctions.sCleanupProvider = DummyProvider;
     SetLastError(0xdeadbeef);
     ret = pWintrustAddActionID(&ActionID, 0, &ActionIDFunctions);
-    todo_wine
-    {
-        ok (ret, "Expected WintrustAddActionID to succeed.\n");
-        ok (GetLastError() == 0xdeadbeef,
-            "Expected 0xdeadbeef, got %ld.\n", GetLastError());
-    }
+    ok (ret, "Expected WintrustAddActionID to succeed.\n");
+    ok (GetLastError() == 0xdeadbeef,
+        "Expected 0xdeadbeef, got %ld.\n", GetLastError());
 
     SetLastError(0xdeadbeef);
     ret = pWintrustRemoveActionID(&ActionID);
diff --git a/include/wintrust.h b/include/wintrust.h
index 3d2ba8c..6abaa70 100644
--- a/include/wintrust.h
+++ b/include/wintrust.h
@@ -303,6 +303,7 @@ extern "C" {
 #endif
 
 BOOL      WINAPI WintrustAddActionID(GUID*,DWORD,CRYPT_REGISTER_ACTIONID*);
+#define WT_ADD_ACTION_ID_RET_RESULT_FLAG 1
 BOOL      WINAPI WintrustRemoveActionID(GUID*);
 BOOL      WINAPI WintrustLoadFunctionPointers(GUID*,CRYPT_PROVIDER_FUNCTIONS*);
 void      WINAPI WintrustGetRegPolicyFlags(DWORD*);
-- 
1.4.1.1




More information about the wine-patches mailing list