Index: dlls/advapi32/tests/crypt.c
===================================================================
RCS file: /home/wine/wine/dlls/advapi32/tests/crypt.c,v
retrieving revision 1.3
diff -u -r1.3 crypt.c
--- dlls/advapi32/tests/crypt.c	24 Jul 2004 02:27:15 -0000	1.3
+++ dlls/advapi32/tests/crypt.c	10 Aug 2004 21:39:35 -0000
@@ -25,6 +25,7 @@
 #include "winbase.h"
 #include "wincrypt.h"
 #include "winerror.h"
+#include "winreg.h"
 
 static const char szRsaBaseProv[] = MS_DEF_PROV_A;
 static const char szNonExistentProv[] = "Wine Non Existent Cryptographic Provider v11.2";
@@ -119,9 +120,113 @@
 		CryptReleaseContext(hProv, 0);
 }
 
+static BOOL FindProvRegVals(DWORD dwIndex, DWORD *pdwProvType, LPSTR *pszProvName, 
+			    DWORD *pcbProvName, DWORD *pdwProvCount)
+{
+	HKEY hKey;
+	HKEY subkey;
+	DWORD size = sizeof(DWORD);
+	
+	if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Cryptography\\Defaults\\Provider", &hKey))
+		return FALSE;
+	
+	RegQueryInfoKey(hKey, NULL, NULL, NULL, pdwProvCount, pcbProvName, 
+				 NULL, NULL, NULL, NULL, NULL, NULL);
+	
+	if (!(*pszProvName = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, *pcbProvName))))
+		return FALSE;
+	
+	RegEnumKeyEx(hKey, dwIndex, *pszProvName, pcbProvName, NULL, NULL, NULL, NULL);
+	(*pcbProvName)++;
+
+	RegOpenKey(hKey, *pszProvName, &subkey);
+	RegQueryValueEx(subkey, "Type", NULL, NULL, (BYTE*)pdwProvType, &size);
+	
+	RegCloseKey(subkey);
+	RegCloseKey(hKey);
+	
+	return TRUE;
+}
+
+static void test_enum_providers(void)
+{
+	/* expected results */
+	CHAR *pszProvName = NULL;
+	DWORD cbName;
+	DWORD dwType;
+	DWORD provCount;
+	DWORD dwIndex = 0;
+	
+	/* actual results */
+	CHAR *provider = NULL;
+	DWORD providerLen;
+	DWORD type;
+	DWORD count;
+	BOOL result;
+	
+	if (!FindProvRegVals(dwIndex, &dwType, &pszProvName, &cbName, &provCount))
+		return;
+	
+	/* check pdwReserved flag for NULL */
+	DWORD notNull = 5;
+	result = CryptEnumProviders(dwIndex, &notNull, 0, &type, NULL, &providerLen);
+	ok(!result && GetLastError()==ERROR_INVALID_PARAMETER, "%08x\n", (unsigned int)GetLastError());
+	
+	/* check dwFlags == 0 */
+	DWORD notZeroFlags = 5;
+	result = CryptEnumProviders(dwIndex, NULL, notZeroFlags, &type, NULL, &providerLen);
+	ok(!result && GetLastError()==NTE_BAD_FLAGS, "%08x\n", (unsigned int)GetLastError());
+	
+	/* alloc provider to half the size required 
+	 * cbName holds the size required */
+	todo_wine 
+	{
+		providerLen = cbName / 2;
+		if (!(provider = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, providerLen))))
+			return;
+		
+		result = CryptEnumProviders(dwIndex, NULL, 0, &type, provider, &providerLen);
+		ok(!result && GetLastError()==ERROR_MORE_DATA, "expected %08x, got %08x\n", 
+			ERROR_MORE_DATA, (unsigned int)GetLastError());
+		
+		LocalFree(provider);
+	}
+	
+	/* loop through the providers to get the number of providers 
+	 * after loop ends, count should be provCount + 1 so subtract 1
+	 * to get actual number of providers */
+	count = 0;
+	while(CryptEnumProviders(count++, NULL, 0, &dwType, NULL, &providerLen))
+		;
+	count--;
+	ok(count==provCount, "expected %i, got %i\n", (int)provCount, (int)count);
+	
+	/* loop past the actual number of providers to get the error
+	 * ERROR_NO_MORE_ITEMS */
+	for (count = 0; count < provCount + 1; count++)
+		result = CryptEnumProviders(count, NULL, 0, &dwType, NULL, &providerLen);
+	ok(!result && GetLastError()==ERROR_NO_MORE_ITEMS, "expected %08x, got %08x\n", 
+			ERROR_NO_MORE_ITEMS, (unsigned int)GetLastError());
+	
+	/* check expected versus actual values returned */
+	result = CryptEnumProviders(dwIndex, NULL, 0, &type, NULL, &providerLen);
+	ok(result && providerLen==cbName, "expected %i, got %i\n", (int)cbName, (int)providerLen);
+	if (!(provider = ((LPSTR)LocalAlloc(LMEM_ZEROINIT, providerLen))))
+		return;
+		
+	result = CryptEnumProviders(dwIndex, NULL, 0, &type, provider, &providerLen);
+	ok(result && type==dwType, "expected %i, got %i\n", 
+		(unsigned int)dwType, (unsigned int)type);
+	ok(result && !strcmp(pszProvName, provider), "expected %s, got %s\n", pszProvName, provider);
+	ok(result && cbName==providerLen, "expected %i, got %i\n", 
+		(unsigned int)cbName, (unsigned int)providerLen);
+}
+
 START_TEST(crypt)
 {
 	init_environment();
 	test_acquire_context();
 	clean_up_environment();
+	
+	test_enum_providers();
 }
