[DPlay] Rewrite of DirectPlayEnumerate[A|W]
Lionel Ulmer
lionel.ulmer at free.fr
Sun May 22 14:52:37 CDT 2005
As seen in my debugging tutorial, just started looking a bit into DirectPlay
(not that it is used much in games, but well, it's just another part of
DirectX I did not know, so it's good to explore a bit :-) ).
Lionel
Changelog:
- rewrite DirectPlayEnumerateA and add W version at the same time
--
Lionel Ulmer - http://www.bbrox.org/
-------------- next part --------------
Index: dlls/dplayx/dplay.c
===================================================================
RCS file: /home/wine/wine/dlls/dplayx/dplay.c,v
retrieving revision 1.57
diff -u -r1.57 dplay.c
--- dlls/dplayx/dplay.c 19 Apr 2005 09:48:09 -0000 1.57
+++ dlls/dplayx/dplay.c 22 May 2005 19:49:58 -0000
@@ -5157,6 +5157,7 @@
/***************************************************************************
* DirectPlayEnumerate [DPLAYX.9]
* DirectPlayEnumerateA [DPLAYX.2]
+ * DirectPlayEnumerateW [DPLAYX.3]
*
* The pointer to the structure lpContext will be filled with the
* appropriate data for each service offered by the OS. These services are
@@ -5176,125 +5177,162 @@
* supply service providers to use specialized hardware, protocols, communications
* media, and network resources.
*
- * TODO: Allocate string buffer space from the heap (length from reg)
- * Pass real device driver numbers...
- * Get the GUID properly...
*/
-HRESULT WINAPI DirectPlayEnumerateA( LPDPENUMDPCALLBACKA lpEnumCallback,
- LPVOID lpContext )
+HRESULT WINAPI DirectPlayEnumerateA_W(LPDPENUMDPCALLBACKA lpEnumCallbackA,
+ LPDPENUMDPCALLBACKW lpEnumCallbackW,
+ LPVOID lpContext)
{
-
- HKEY hkResult;
- LPCSTR searchSubKey = "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers";
- DWORD dwIndex;
- DWORD sizeOfSubKeyName=50;
- char subKeyName[51];
- FILETIME filetime;
-
- TRACE(": lpEnumCallback=%p lpContext=%p\n", lpEnumCallback, lpContext );
-
- if( !lpEnumCallback || !*lpEnumCallback )
- {
- return DPERR_INVALIDPARAMS;
- }
-
- /* Need to loop over the service providers in the registry */
- if( RegOpenKeyExA( HKEY_LOCAL_MACHINE, searchSubKey,
- 0, KEY_READ, &hkResult ) != ERROR_SUCCESS )
- {
- /* Hmmm. Does this mean that there are no service providers? */
- ERR(": no service providers?\n");
- return DPERR_NOSERVICEPROVIDER;
- }
-
- /* Traverse all the service providers we have available */
- for( dwIndex=0;
- RegEnumKeyExA( hkResult, dwIndex, subKeyName, &sizeOfSubKeyName,
- NULL, NULL, NULL, &filetime ) != ERROR_NO_MORE_ITEMS;
- ++dwIndex, sizeOfSubKeyName=50 )
- {
- LPCSTR majVerDataSubKey = "dwReserved1";
- LPCSTR minVerDataSubKey = "dwReserved2";
- LPCSTR guidDataSubKey = "Guid";
- HKEY hkServiceProvider;
- GUID serviceProviderGUID;
- DWORD returnTypeGUID, returnTypeReserved, sizeOfReturnBuffer = 50;
- char returnBuffer[51];
- WCHAR buff[51];
- DWORD majVersionNum , minVersionNum = 0;
-
- TRACE(" this time through: %s\n", subKeyName );
-
- /* Get a handle for this particular service provider */
- if( RegOpenKeyExA( hkResult, subKeyName, 0, KEY_READ,
- &hkServiceProvider ) != ERROR_SUCCESS )
- {
- ERR(": what the heck is going on?\n" );
- continue;
- }
-
- /* Get the GUID, Device major number and device minor number
- * from the registry.
- */
- if( RegQueryValueExA( hkServiceProvider, guidDataSubKey,
- NULL, &returnTypeGUID, returnBuffer,
- &sizeOfReturnBuffer ) != ERROR_SUCCESS )
- {
- ERR(": missing GUID registry data members\n" );
- continue;
- }
-
- /* FIXME: Check return types to ensure we're interpreting data right */
- MultiByteToWideChar( CP_ACP, 0, returnBuffer, -1, buff, sizeof(buff)/sizeof(WCHAR) );
- CLSIDFromString( buff, &serviceProviderGUID );
-
- /* FIXME: Need to know which of dwReserved1 and dwReserved2 are maj and min */
-
- sizeOfReturnBuffer = 50;
- if( RegQueryValueExA( hkServiceProvider, majVerDataSubKey,
- NULL, &returnTypeReserved, returnBuffer,
- &sizeOfReturnBuffer ) != ERROR_SUCCESS )
+ HKEY hkResult;
+ static const WCHAR searchSubKey[] = {
+ 'S', 'O', 'F', 'T', 'W', 'A', 'R', 'E', '\\',
+ 'M', 'i', 'c', 'r', 'o', 's', 'o', 'f', 't', '\\',
+ 'D', 'i', 'r', 'e', 'c', 't', 'P', 'l', 'a', 'y', '\\',
+ 'S', 'e', 'r', 'v', 'i', 'c', 'e', ' ', 'P', 'r', 'o', 'v', 'i', 'd', 'e', 'r', 's', 0 };
+ static const WCHAR guidKey[] = { 'G', 'u', 'i', 'd', 0 };
+ static const WCHAR descW[] = { 'D', 'e', 's', 'c', 'r', 'i', 'p', 't', 'i', 'o', 'n', 'W', 0 };
+
+ DWORD dwIndex;
+ FILETIME filetime;
+
+ char *descriptionA = NULL;
+ DWORD max_sizeOfDescriptionA = 0;
+ WCHAR *descriptionW = NULL;
+ DWORD max_sizeOfDescriptionW = 0;
+
+ if (!lpEnumCallbackA && !lpEnumCallbackW)
{
- ERR(": missing dwReserved1 registry data members\n") ;
- continue;
+ return DPERR_INVALIDPARAMS;
}
- memcpy( &majVersionNum, returnBuffer, sizeof(majVersionNum) );
-
- sizeOfReturnBuffer = 50;
- if( RegQueryValueExA( hkServiceProvider, minVerDataSubKey,
- NULL, &returnTypeReserved, returnBuffer,
- &sizeOfReturnBuffer ) != ERROR_SUCCESS )
+
+ /* Need to loop over the service providers in the registry */
+ if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, searchSubKey,
+ 0, KEY_READ, &hkResult) != ERROR_SUCCESS)
{
- ERR(": missing dwReserved2 registry data members\n") ;
- continue;
+ /* Hmmm. Does this mean that there are no service providers? */
+ ERR(": no service provider key in the registry - check your Wine installation !!!\n");
+ return DPERR_GENERIC;
}
- memcpy( &minVersionNum, returnBuffer, sizeof(minVersionNum) );
-
-
- /* The enumeration will return FALSE if we are not to continue */
- if( !lpEnumCallback( &serviceProviderGUID , subKeyName,
- majVersionNum, minVersionNum, lpContext ) )
+
+ /* Traverse all the service providers we have available */
+ dwIndex = 0;
+ while (1)
{
- WARN("lpEnumCallback returning FALSE\n" );
- break;
- }
+ WCHAR subKeyName[255]; /* 255 is the maximum key size according to MSDN */
+ DWORD sizeOfSubKeyName = sizeof(subKeyName) / sizeof(WCHAR);
+ HKEY hkServiceProvider;
+ GUID serviceProviderGUID;
+ WCHAR guidKeyContent[(2 * 16) + 1 + 6 /* This corresponds to '{....-..-..-..-......}' */ ];
+ DWORD sizeOfGuidKeyContent = sizeof(guidKeyContent);
+ LONG ret_value;
+
+ ret_value = RegEnumKeyExW(hkResult, dwIndex, subKeyName, &sizeOfSubKeyName,
+ NULL, NULL, NULL, &filetime);
+ if (ret_value == ERROR_NO_MORE_ITEMS)
+ break;
+ else if (ret_value != ERROR_SUCCESS)
+ {
+ ERR(": could not enumerate on service provider key.\n");
+ return DPERR_EXCEPTION;
+ }
+ TRACE(" this time through sub-key %s.\n", debugstr_w(subKeyName));
+
+ /* Open the key for this service provider */
+ if (RegOpenKeyExW(hkResult, subKeyName, 0, KEY_READ, &hkServiceProvider) != ERROR_SUCCESS)
+ {
+ ERR(": could not open registry key for service provider %s.\n", debugstr_w(subKeyName));
+ continue;
+ }
+
+ /* Get the GUID from the registry */
+ if (RegQueryValueExW(hkServiceProvider, guidKey,
+ NULL, NULL, (LPBYTE) guidKeyContent, &sizeOfGuidKeyContent) != ERROR_SUCCESS)
+ {
+ ERR(": missing GUID registry data member for service provider %s.\n", debugstr_w(subKeyName));
+ continue;
+ }
+ if (sizeOfGuidKeyContent != sizeof(guidKeyContent))
+ {
+ ERR(": invalid format for the GUID registry data member for service provider %s (%s).\n", debugstr_w(subKeyName), debugstr_w(guidKeyContent));
+ continue;
+ }
+ CLSIDFromString(guidKeyContent, &serviceProviderGUID );
+
+ /* The enumeration will return FALSE if we are not to continue.
+ *
+ * Note: on my windows box, major / minor version is 6 / 0 for all service providers
+ * and have no relations to any of the two dwReserved1 and dwReserved2 keys.
+ * I think that it simply means that they are in-line with DirectX 6.0
+ */
+ if (lpEnumCallbackA)
+ {
+ DWORD sizeOfDescription = 0;
+
+ /* Note that this the the A case of this function, so use the A variant to get the description string */
+ if (RegQueryValueExA(hkServiceProvider, "DescriptionA",
+ NULL, NULL, NULL, &sizeOfDescription) != ERROR_SUCCESS)
+ {
+ ERR(": missing 'DescriptionA' registry data member for service provider %s.\n", debugstr_w(subKeyName));
+ continue;
+ }
+ if (sizeOfDescription > max_sizeOfDescriptionA)
+ {
+ HeapFree(GetProcessHeap(), 0, descriptionA);
+ max_sizeOfDescriptionA = sizeOfDescription;
+ descriptionA = HeapAlloc(GetProcessHeap(), 0, max_sizeOfDescriptionA);
+ }
+ descriptionA = HeapAlloc(GetProcessHeap(), 0, sizeOfDescription);
+ RegQueryValueExA(hkServiceProvider, "DescriptionA",
+ NULL, NULL, (LPBYTE) descriptionA, &sizeOfDescription);
+
+ if (!lpEnumCallbackA(&serviceProviderGUID, descriptionA, 6, 0, lpContext))
+ goto end;
+ }
+ else
+ {
+ DWORD sizeOfDescription = 0;
+
+ if (RegQueryValueExW(hkServiceProvider, descW,
+ NULL, NULL, NULL, &sizeOfDescription) != ERROR_SUCCESS)
+ {
+ ERR(": missing 'DescriptionW' registry data member for service provider %s.\n", debugstr_w(subKeyName));
+ continue;
+ }
+ if (sizeOfDescription > max_sizeOfDescriptionW)
+ {
+ HeapFree(GetProcessHeap(), 0, descriptionW);
+ max_sizeOfDescriptionW = sizeOfDescription;
+ descriptionW = HeapAlloc(GetProcessHeap(), 0, max_sizeOfDescriptionW);
+ }
+ descriptionW = HeapAlloc(GetProcessHeap(), 0, sizeOfDescription);
+ RegQueryValueExW(hkServiceProvider, descW,
+ NULL, NULL, (LPBYTE) descriptionW, &sizeOfDescription);
+
+ if (!lpEnumCallbackW(&serviceProviderGUID, descriptionW, 6, 0, lpContext))
+ goto end;
+ }
+
+ dwIndex++;
}
- return DP_OK;
-
+ end:
+ HeapFree(GetProcessHeap(), 0, descriptionA);
+ HeapFree(GetProcessHeap(), 0, descriptionW);
+
+ return DP_OK;
}
-/***************************************************************************
- * DirectPlayEnumerateW [DPLAYX.3]
- *
- */
-HRESULT WINAPI DirectPlayEnumerateW( LPDPENUMDPCALLBACKW lpEnumCallback, LPVOID lpContext )
+HRESULT WINAPI DirectPlayEnumerateA(LPDPENUMDPCALLBACKA lpEnumCallback, LPVOID lpContext )
{
+ TRACE("(%p,%p)\n", lpEnumCallback, lpContext);
+
+ return DirectPlayEnumerateA_W(lpEnumCallback, NULL, lpContext);
+}
- FIXME(":stub\n");
-
- return DPERR_OUTOFMEMORY;
-
+HRESULT WINAPI DirectPlayEnumerateW(LPDPENUMDPCALLBACKW lpEnumCallback, LPVOID lpContext )
+{
+ TRACE("(%p,%p)\n", lpEnumCallback, lpContext);
+
+ return DirectPlayEnumerateA_W(NULL, lpEnumCallback, lpContext);
}
typedef struct tagCreateEnum
More information about the wine-patches
mailing list