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); } /******************************************************************************