diff --git a/dlls/dpnet/server.c b/dlls/dpnet/server.c index 3e026fc7774..cd54ba49e5a 100644 --- a/dlls/dpnet/server.c +++ b/dlls/dpnet/server.c @@ -43,6 +43,10 @@ typedef struct IDirectPlay8ServerImpl PFNDPNMESSAGEHANDLER msghandler; DWORD flags; void *usercontext; + + WCHAR *servername; + void *data; + DWORD datasize; } IDirectPlay8ServerImpl; WINE_DEFAULT_DEBUG_CHANNEL(dpnet); @@ -91,8 +95,11 @@ static ULONG WINAPI IDirectPlay8ServerImpl_Release(IDirectPlay8Server *iface) TRACE("(%p) ref=%d\n", This, ref); - if (!ref) { - HeapFree(GetProcessHeap(), 0, This); + if (!ref) + { + heap_free(This->servername); + heap_free(This->data); + heap_free(This); } return ref; @@ -151,8 +158,54 @@ static HRESULT WINAPI IDirectPlay8ServerImpl_SetServerInfo(IDirectPlay8Server *i PVOID pvAsyncContext, DPNHANDLE *phAsyncHandle, DWORD dwFlags) { IDirectPlay8ServerImpl *This = impl_from_IDirectPlay8Server(iface); - FIXME("(%p)->(%p %p %p %d)\n", This, pdpnPlayerInfo, pvAsyncContext, phAsyncHandle, dwFlags); - return E_NOTIMPL; + + FIXME("(%p)->(%p %p %p %x) Semi-stub\n", This, pdpnPlayerInfo, pvAsyncContext, phAsyncHandle, dwFlags); + + if(!pdpnPlayerInfo) + return E_POINTER; + + if(!This->msghandler) + return DPNERR_UNINITIALIZED; + + if(phAsyncHandle) + FIXME("Async handle currently not supported.\n"); + + if (pdpnPlayerInfo->dwInfoFlags & DPNINFO_NAME) + { + heap_free(This->servername); + This->servername = NULL; + + if(pdpnPlayerInfo->pwszName) + { + This->servername = heap_strdupW(pdpnPlayerInfo->pwszName); + if (!This->servername) + return E_OUTOFMEMORY; + } + } + + if (pdpnPlayerInfo->dwInfoFlags & DPNINFO_DATA) + { + heap_free(This->data); + This->data = NULL; + This->datasize = 0; + + if(!pdpnPlayerInfo->pvData && pdpnPlayerInfo->dwDataSize) + return E_POINTER; + + if(pdpnPlayerInfo->dwDataSize && pdpnPlayerInfo->pvData) + { + This->data = heap_alloc(pdpnPlayerInfo->dwDataSize); + if (!This->data) + return E_OUTOFMEMORY; + + This->datasize = pdpnPlayerInfo->dwDataSize; + + memcpy(This->data, pdpnPlayerInfo->pvData, pdpnPlayerInfo->dwDataSize); + } + } + + /* TODO: Send DPN_MSGID_SERVER_INFO message to all players. */ + return S_OK; } static HRESULT WINAPI IDirectPlay8ServerImpl_GetClientInfo(IDirectPlay8Server *iface, DPNID dpnid, DPN_PLAYER_INFO *pdpnPlayerInfo, diff --git a/dlls/dpnet/tests/server.c b/dlls/dpnet/tests/server.c index 8279666ed29..928c6a0f163 100644 --- a/dlls/dpnet/tests/server.c +++ b/dlls/dpnet/tests/server.c @@ -98,6 +98,88 @@ static void create_server(void) } } +static void test_server_info(void) +{ + HRESULT hr; + DPN_PLAYER_INFO info; + WCHAR name[] = {'w','i','n','e',0}; + WCHAR name2[] = {'w','i','n','e','2',0}; + WCHAR data[] = {'X','X','X','X',0}; + IDirectPlay8Server *server = NULL; + + hr = CoCreateInstance( &CLSID_DirectPlay8Server, NULL, CLSCTX_ALL, &IID_IDirectPlay8Server, (LPVOID*)&server); + ok(hr == S_OK, "Failed to create IDirectPlay8Server object\n"); + if( SUCCEEDED(hr) ) + { + ZeroMemory( &info, sizeof(DPN_PLAYER_INFO) ); + info.dwSize = sizeof(DPN_PLAYER_INFO); + info.dwInfoFlags = DPNINFO_NAME; + + hr = IDirectPlay8Server_SetServerInfo(server, NULL, NULL, NULL, DPNSETSERVERINFO_SYNC); + ok(hr == E_POINTER, "got %x\n", hr); + + info.pwszName = name; + hr = IDirectPlay8Server_SetServerInfo(server, &info, NULL, NULL, DPNSETSERVERINFO_SYNC); + ok(hr == DPNERR_UNINITIALIZED, "got %x\n", hr); + + hr = IDirectPlay8Server_Initialize(server, NULL, DirectPlayMessageHandler, 0); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IDirectPlay8Server_SetServerInfo(server, NULL, NULL, NULL, DPNSETSERVERINFO_SYNC); + ok(hr == E_POINTER, "got %x\n", hr); + + info.pwszName = NULL; + hr = IDirectPlay8Server_SetServerInfo(server, &info, NULL, NULL, DPNSETSERVERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + info.pwszName = name; + hr = IDirectPlay8Server_SetServerInfo(server, &info, NULL, NULL, DPNSETSERVERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + info.dwInfoFlags = DPNINFO_NAME; + info.pwszName = name2; + hr = IDirectPlay8Server_SetServerInfo(server, &info, NULL, NULL, DPNSETSERVERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + info.dwInfoFlags = DPNINFO_DATA; + info.pwszName = NULL; + info.pvData = NULL; + info.dwDataSize = sizeof(data); + hr = IDirectPlay8Server_SetServerInfo(server, &info, NULL, NULL, DPNSETSERVERINFO_SYNC); + ok(hr == E_POINTER, "got %x\n", hr); + + info.dwInfoFlags = DPNINFO_DATA; + info.pwszName = NULL; + info.pvData = data; + info.dwDataSize = 0; + hr = IDirectPlay8Server_SetServerInfo(server, &info, NULL, NULL, DPNSETSERVERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + info.dwInfoFlags = DPNINFO_DATA; + info.pwszName = NULL; + info.pvData = data; + info.dwDataSize = sizeof(data); + hr = IDirectPlay8Server_SetServerInfo(server, &info, NULL, NULL, DPNSETSERVERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + info.dwInfoFlags = DPNINFO_DATA | DPNINFO_NAME; + info.pwszName = name; + info.pvData = data; + info.dwDataSize = sizeof(data); + hr = IDirectPlay8Server_SetServerInfo(server, &info, NULL, NULL, DPNSETSERVERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + info.dwInfoFlags = DPNINFO_DATA | DPNINFO_NAME; + info.pwszName = name; + info.pvData = NULL; + info.dwDataSize = 0; + hr = IDirectPlay8Server_SetServerInfo(server, &info, NULL, NULL, DPNSETSERVERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + IDirectPlay8Server_Release(server); + } +} + START_TEST(server) { HRESULT hr; @@ -108,6 +190,7 @@ START_TEST(server) return; create_server(); + test_server_info(); CoUninitialize(); }