Changelog
    * Call provider.dll's DllRegisterServer from CryptSetProviderEx to
update the Name and TypeName values in the registry properly when
setting the default provider

-- 
James Hawkins
Index: dlls/advapi32/crypt.c
===================================================================
RCS file: /home/wine/wine/dlls/advapi32/crypt.c,v
retrieving revision 1.49
diff -u -r1.49 crypt.c
--- dlls/advapi32/crypt.c	17 Aug 2004 22:08:16 -0000	1.49
+++ dlls/advapi32/crypt.c	20 Aug 2004 07:39:18 -0000
@@ -51,6 +51,8 @@
 #define CRYPT_Alloc(size) ((LPVOID)LocalAlloc(LMEM_ZEROINIT, size))
 #define CRYPT_Free(buffer) (LocalFree((HLOCAL)buffer))
 
+typedef HRESULT (CALLBACK * MYPROC)(void);
+
 static inline PSTR CRYPT_GetProvKeyName(PCSTR pProvName)
 {
 	PCSTR KEYSTR = "Software\\Microsoft\\Cryptography\\Defaults\\Provider\\";
@@ -1691,10 +1693,15 @@
 BOOL WINAPI CryptSetProviderExA (LPCSTR pszProvName, DWORD dwProvType, DWORD *pdwReserved, DWORD dwFlags)
 {
 	HKEY hKey;
-	PSTR keyname;
-
+	PSTR keyname, provDll;
+	HINSTANCE hProvInst;
+	MYPROC DllRegisterServer;
+	HRESULT result = S_OK;
+	DWORD keytype, len;
+	ULONG r;
+	
 	TRACE("(%s, %ld, %p, %08ld)\n", pszProvName, dwProvType, pdwReserved, dwFlags);
-
+	
 	if (!pszProvName || pdwReserved)
 		CRYPT_ReturnLastError(ERROR_INVALID_PARAMETER);
 	if (dwProvType > MAXPROVTYPES)
@@ -1702,7 +1709,7 @@
 	if (dwFlags & ~(CRYPT_MACHINE_DEFAULT | CRYPT_USER_DEFAULT | CRYPT_DELETE_DEFAULT)
 			|| dwFlags == CRYPT_DELETE_DEFAULT)
 		CRYPT_ReturnLastError(NTE_BAD_FLAGS);
-
+	
 	if (dwFlags & CRYPT_DELETE_DEFAULT)
 	{
 		if ( !(keyname = CRYPT_GetTypeKeyName(dwProvType, dwFlags & CRYPT_USER_DEFAULT)) )
@@ -1711,23 +1718,55 @@
 		CRYPT_Free(keyname);
 		return TRUE;
 	}
-
-	if ( !(keyname = CRYPT_GetProvKeyName(pszProvName)) )
-		CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
+	
+	/* set the provider as default in the registry */
+	if (!(keyname = CRYPT_GetProvKeyName(pszProvName)))
+		return FALSE;
 	if (RegOpenKeyA(HKEY_LOCAL_MACHINE, keyname, &hKey))
 	{
 		CRYPT_Free(keyname);
 		CRYPT_ReturnLastError(NTE_BAD_PROVIDER);
 	}
 	CRYPT_Free(keyname);
+	
+	/* get the name of the dll of the CSP */
+	r = RegQueryValueExA(hKey, "Image Path", NULL, &keytype, NULL, &len);
+	if( r != ERROR_SUCCESS || !len || keytype != REG_SZ)
+	{
+		TRACE("error %ld reading size of 'Image Path' from registry\n", r );
+		RegCloseKey(hKey);
+		SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
+		return FALSE;
+	}
+	if(!(provDll = CRYPT_Alloc(len)))
+	{
+		RegCloseKey(hKey);
+		SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+		return FALSE;
+	}
+	r = RegQueryValueExA(hKey, "Image Path", NULL, NULL, provDll, &len);
+	if( r != ERROR_SUCCESS )
+	{
+		TRACE("error %ld reading 'Image Path' from registry\n", r );
+		RegCloseKey(hKey);
+		SetLastError(NTE_PROV_TYPE_ENTRY_BAD);
+		CRYPT_Free(provDll);
+		return FALSE;
+	}
 	RegCloseKey(hKey);
-	if ( !(keyname = CRYPT_GetTypeKeyName(dwProvType, dwFlags & CRYPT_USER_DEFAULT)) )
-		CRYPT_ReturnLastError(ERROR_NOT_ENOUGH_MEMORY);
-	RegCreateKeyA( (dwFlags & CRYPT_USER_DEFAULT) ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, keyname, &hKey);
-	CRYPT_Free(keyname);
-	if (RegSetValueExA(hKey, "Name", 0, REG_SZ, pszProvName, strlen(pszProvName) +1))
+	
+	/* open the dll of the CSP */
+	hProvInst = LoadLibraryA(provDll);
+	if (!hProvInst)
 		return FALSE;
-	return TRUE;
+	
+	/* register the CSP in the registry */
+	DllRegisterServer = (MYPROC)GetProcAddress(hProvInst, "DllRegisterServer");
+	result = DllRegisterServer();
+	
+	FreeLibrary(hProvInst);
+	
+	return (result == S_OK);
 }
 
 /******************************************************************************

Reply via email to