dplayx: Cache GUID values so they persist after enumeration.
This commit is contained in:
parent
e584edd379
commit
2d08038bac
|
@ -5785,6 +5785,11 @@ static HRESULT DirectPlayEnumerateAW(LPDPENUMDPCALLBACKA lpEnumCallbackA,
|
|||
DWORD max_sizeOfDescriptionA = 0;
|
||||
WCHAR *descriptionW = NULL;
|
||||
DWORD max_sizeOfDescriptionW = 0;
|
||||
DWORD sizeOfSubKeyName;
|
||||
WCHAR subKeyName[255]; /* 255 is the maximum key size according to MSDN */
|
||||
LONG ret_value;
|
||||
static GUID *guid_cache;
|
||||
static int cache_count;
|
||||
|
||||
if (!lpEnumCallbackA && !lpEnumCallbackW)
|
||||
{
|
||||
|
@ -5799,19 +5804,37 @@ static HRESULT DirectPlayEnumerateAW(LPDPENUMDPCALLBACKA lpEnumCallbackA,
|
|||
ERR(": no service provider key in the registry - check your Wine installation !!!\n");
|
||||
return DPERR_GENERIC;
|
||||
}
|
||||
|
||||
|
||||
dwIndex = 0;
|
||||
do
|
||||
{
|
||||
sizeOfSubKeyName = sizeof(subKeyName) / sizeof(WCHAR);
|
||||
ret_value = RegEnumKeyW(hkResult, dwIndex, subKeyName, sizeOfSubKeyName);
|
||||
dwIndex++;
|
||||
}
|
||||
while (ret_value == ERROR_SUCCESS);
|
||||
/* The game Swing from bug 37185 expects GUID values to persist after
|
||||
* the end of the enumeration. */
|
||||
if (cache_count < dwIndex)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, guid_cache);
|
||||
guid_cache = HeapAlloc(GetProcessHeap(), 0, sizeof(GUID) * dwIndex);
|
||||
if (!guid_cache)
|
||||
{
|
||||
ERR(": failed to alloc required memory.\n");
|
||||
return DPERR_EXCEPTION;
|
||||
}
|
||||
cache_count = dwIndex;
|
||||
}
|
||||
/* Traverse all the service providers we have available */
|
||||
dwIndex = 0;
|
||||
while (1)
|
||||
{
|
||||
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;
|
||||
|
||||
sizeOfSubKeyName = sizeof(subKeyName) / sizeof(WCHAR);
|
||||
ret_value = RegEnumKeyExW(hkResult, dwIndex, subKeyName, &sizeOfSubKeyName,
|
||||
NULL, NULL, NULL, &filetime);
|
||||
if (ret_value == ERROR_NO_MORE_ITEMS)
|
||||
|
@ -5842,7 +5865,7 @@ static HRESULT DirectPlayEnumerateAW(LPDPENUMDPCALLBACKA lpEnumCallbackA,
|
|||
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 );
|
||||
CLSIDFromString(guidKeyContent, &guid_cache[dwIndex]);
|
||||
|
||||
/* The enumeration will return FALSE if we are not to continue.
|
||||
*
|
||||
|
@ -5870,7 +5893,7 @@ static HRESULT DirectPlayEnumerateAW(LPDPENUMDPCALLBACKA lpEnumCallbackA,
|
|||
RegQueryValueExA(hkServiceProvider, "DescriptionA",
|
||||
NULL, NULL, (LPBYTE) descriptionA, &sizeOfDescription);
|
||||
|
||||
if (!lpEnumCallbackA(&serviceProviderGUID, descriptionA, 6, 0, lpContext))
|
||||
if (!lpEnumCallbackA(&guid_cache[dwIndex], descriptionA, 6, 0, lpContext))
|
||||
goto end;
|
||||
}
|
||||
else
|
||||
|
@ -5892,7 +5915,7 @@ static HRESULT DirectPlayEnumerateAW(LPDPENUMDPCALLBACKA lpEnumCallbackA,
|
|||
RegQueryValueExW(hkServiceProvider, descW,
|
||||
NULL, NULL, (LPBYTE) descriptionW, &sizeOfDescription);
|
||||
|
||||
if (!lpEnumCallbackW(&serviceProviderGUID, descriptionW, 6, 0, lpContext))
|
||||
if (!lpEnumCallbackW(&guid_cache[dwIndex], descriptionW, 6, 0, lpContext))
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,6 +72,13 @@ typedef struct tagCallbackData
|
|||
UINT dpidSize;
|
||||
} CallbackData, *lpCallbackData;
|
||||
|
||||
struct provider_data
|
||||
{
|
||||
int call_count;
|
||||
GUID *guid_ptr[10];
|
||||
GUID guid_data[10];
|
||||
BOOL ret_value;
|
||||
};
|
||||
|
||||
static LPSTR get_temp_buffer(void)
|
||||
{
|
||||
|
@ -749,6 +756,113 @@ static void test_DirectPlayCreate(void)
|
|||
|
||||
}
|
||||
|
||||
static BOOL CALLBACK callback_providersA(GUID* guid, char *name, DWORD major, DWORD minor, void *arg)
|
||||
{
|
||||
struct provider_data *prov = arg;
|
||||
|
||||
if (!prov) return TRUE;
|
||||
|
||||
if (prov->call_count < sizeof(prov->guid_data) / sizeof(prov->guid_data[0]))
|
||||
{
|
||||
prov->guid_ptr[prov->call_count] = guid;
|
||||
prov->guid_data[prov->call_count] = *guid;
|
||||
|
||||
prov->call_count++;
|
||||
}
|
||||
|
||||
if (prov->ret_value) /* Only trace when looping all providers */
|
||||
trace("Provider #%d '%s' (%d.%d)\n", prov->call_count, name, major, minor);
|
||||
return prov->ret_value;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK callback_providersW(GUID* guid, WCHAR *name, DWORD major, DWORD minor, void *arg)
|
||||
{
|
||||
struct provider_data *prov = arg;
|
||||
|
||||
if (!prov) return TRUE;
|
||||
|
||||
if (prov->call_count < sizeof(prov->guid_data) / sizeof(prov->guid_data[0]))
|
||||
{
|
||||
prov->guid_ptr[prov->call_count] = guid;
|
||||
prov->guid_data[prov->call_count] = *guid;
|
||||
|
||||
prov->call_count++;
|
||||
}
|
||||
|
||||
return prov->ret_value;
|
||||
}
|
||||
|
||||
static void test_EnumerateProviders(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
int i;
|
||||
struct provider_data arg;
|
||||
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
arg.ret_value = TRUE;
|
||||
|
||||
hr = DirectPlayEnumerateA(callback_providersA, NULL);
|
||||
ok(SUCCEEDED(hr), "DirectPlayEnumerateA failed\n");
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
hr = DirectPlayEnumerateA(NULL, &arg);
|
||||
ok(FAILED(hr), "DirectPlayEnumerateA expected to fail\n");
|
||||
ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got 0x%x\n", GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
hr = DirectPlayEnumerateA(NULL, NULL);
|
||||
ok(FAILED(hr), "DirectPlayEnumerateA expected to fail\n");
|
||||
ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got 0x%x\n", GetLastError());
|
||||
|
||||
hr = DirectPlayEnumerateA(callback_providersA, &arg);
|
||||
ok(SUCCEEDED(hr), "DirectPlayEnumerateA failed\n");
|
||||
ok(arg.call_count > 0, "Expected at least one valid provider\n");
|
||||
trace("Found %d providers\n", arg.call_count);
|
||||
|
||||
/* The returned GUID values must have persisted after enumeration (bug 37185) */
|
||||
for(i = 0; i < arg.call_count; i++)
|
||||
{
|
||||
ok(IsEqualGUID(arg.guid_ptr[i], &arg.guid_data[i]), "#%d Expected equal GUID values\n", i);
|
||||
}
|
||||
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
arg.ret_value = FALSE;
|
||||
hr = DirectPlayEnumerateA(callback_providersA, &arg);
|
||||
ok(SUCCEEDED(hr), "DirectPlayEnumerateA failed\n");
|
||||
ok(arg.call_count == 1, "Expected 1, got %d\n", arg.call_count);
|
||||
|
||||
hr = DirectPlayEnumerateW(callback_providersW, NULL);
|
||||
ok(SUCCEEDED(hr), "DirectPlayEnumerateW failed\n");
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
hr = DirectPlayEnumerateW(NULL, &arg);
|
||||
ok(FAILED(hr), "DirectPlayEnumerateW expected to fail\n");
|
||||
ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got 0x%x\n", GetLastError());
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
hr = DirectPlayEnumerateW(NULL, NULL);
|
||||
ok(FAILED(hr), "DirectPlayEnumerateW expected to fail\n");
|
||||
ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got 0x%x\n", GetLastError());
|
||||
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
arg.ret_value = TRUE;
|
||||
hr = DirectPlayEnumerateW(callback_providersW, &arg);
|
||||
ok(SUCCEEDED(hr), "DirectPlayEnumerateW failed\n");
|
||||
ok(arg.call_count > 0, "Expected at least one valid provider\n");
|
||||
|
||||
/* The returned GUID values must have persisted after enumeration (bug 37185) */
|
||||
for(i = 0; i < arg.call_count; i++)
|
||||
{
|
||||
ok(IsEqualGUID(arg.guid_ptr[i], &arg.guid_data[i]), "#%d Expected equal GUID values\n", i);
|
||||
}
|
||||
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
arg.ret_value = FALSE;
|
||||
hr = DirectPlayEnumerateW(callback_providersW, &arg);
|
||||
ok(SUCCEEDED(hr), "DirectPlayEnumerateW failed\n");
|
||||
ok(arg.call_count == 1, "Expected 1, got %d\n", arg.call_count);
|
||||
}
|
||||
|
||||
/* EnumConnections */
|
||||
|
||||
static BOOL CALLBACK EnumAddress_cb2( REFGUID guidDataType,
|
||||
|
@ -6544,6 +6658,7 @@ START_TEST(dplayx)
|
|||
|
||||
test_COM();
|
||||
test_COM_dplobby();
|
||||
test_EnumerateProviders();
|
||||
|
||||
if (!winetest_interactive)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue