diff --git a/dlls/dpnet/address.c b/dlls/dpnet/address.c index 6305fe7547a..c5457eb62e7 100644 --- a/dlls/dpnet/address.c +++ b/dlls/dpnet/address.c @@ -39,37 +39,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(dpnet); -static inline void *heap_alloc(size_t len) -{ - return HeapAlloc(GetProcessHeap(), 0, len); -} - -static inline void *heap_realloc(void *mem, size_t len) -{ - return HeapReAlloc( GetProcessHeap(), 0, mem, len); -} - -static inline BOOL heap_free(void *mem) -{ - return HeapFree(GetProcessHeap(), 0, mem); -} - -static inline LPWSTR heap_strdupW(LPCWSTR str) -{ - LPWSTR ret = NULL; - - if(str) { - DWORD size; - - size = (strlenW(str)+1)*sizeof(WCHAR); - ret = heap_alloc(size); - if(ret) - memcpy(ret, str, size); - } - - return ret; -} - static char *heap_strdupA( const char *str ) { char *ret; diff --git a/dlls/dpnet/dpnet_private.h b/dlls/dpnet/dpnet_private.h index f9c44009216..05608a64a68 100644 --- a/dlls/dpnet/dpnet_private.h +++ b/dlls/dpnet/dpnet_private.h @@ -26,6 +26,7 @@ #endif #include +#include "wine/unicode.h" #include "dplay8.h" #include "dplobby8.h" @@ -146,6 +147,27 @@ typedef struct { #define FE(x) { x, #x } #define GE(x) { &x, #x } +static inline void *heap_alloc( size_t len ) +{ + return HeapAlloc( GetProcessHeap(), 0, len ); +} +static inline void *heap_realloc(void *mem, size_t len) +{ + return HeapReAlloc( GetProcessHeap(), 0, mem, len); +} + +static inline BOOL heap_free( void *mem ) +{ + return HeapFree( GetProcessHeap(), 0, mem ); +} + +static inline WCHAR *heap_strdupW( const WCHAR *src ) +{ + WCHAR *dst; + if (!src) return NULL; + if ((dst = heap_alloc( (strlenW( src ) + 1) * sizeof(WCHAR) ))) strcpyW( dst, src ); + return dst; +} #endif diff --git a/dlls/dpnet/peer.c b/dlls/dpnet/peer.c index a07a59a993f..264ca70a87f 100644 --- a/dlls/dpnet/peer.c +++ b/dlls/dpnet/peer.c @@ -48,6 +48,10 @@ typedef struct IDirectPlay8PeerImpl DWORD flags; void *usercontext; + WCHAR *username; + void *data; + DWORD datasize; + DPN_SP_CAPS spcaps; } IDirectPlay8PeerImpl; @@ -92,7 +96,12 @@ static ULONG WINAPI IDirectPlay8PeerImpl_Release(IDirectPlay8Peer *iface) TRACE("(%p) ref=%d\n", This, RefCount); if(!RefCount) - HeapFree(GetProcessHeap(), 0, This); + { + heap_free(This->username); + heap_free(This->data); + + heap_free(This); + } return RefCount; } @@ -310,9 +319,42 @@ static HRESULT WINAPI IDirectPlay8PeerImpl_SetPeerInfo(IDirectPlay8Peer *iface, const DPN_PLAYER_INFO * const pdpnPlayerInfo, void * const pvAsyncContext, DPNHANDLE * const phAsyncHandle, const DWORD dwFlags) { - FIXME("(%p)->(%p,%p,%p,%x): stub\n", iface, pdpnPlayerInfo, pvAsyncContext, phAsyncHandle, dwFlags); + IDirectPlay8PeerImpl* This = impl_from_IDirectPlay8Peer(iface); - return DPNERR_GENERIC; + FIXME("(%p)->(%p,%p,%p,%x) Semi-stub.\n", This, pdpnPlayerInfo, pvAsyncContext, phAsyncHandle, dwFlags); + + if(!pdpnPlayerInfo) + return E_POINTER; + + if(phAsyncHandle) + FIXME("Async handle currently not supported.\n"); + + if (pdpnPlayerInfo->dwInfoFlags & DPNINFO_NAME) + { + heap_free(This->username); + This->username = NULL; + + if(pdpnPlayerInfo->pwszName) + { + This->username = heap_strdupW(pdpnPlayerInfo->pwszName); + if (!This->username) + return E_OUTOFMEMORY; + } + } + + if (pdpnPlayerInfo->dwInfoFlags & DPNINFO_DATA) + { + heap_free(This->data); + + This->datasize = pdpnPlayerInfo->dwDataSize; + This->data = heap_alloc(pdpnPlayerInfo->dwDataSize); + if (!This->data) + return E_OUTOFMEMORY; + + memcpy(This->data, pdpnPlayerInfo->pvData, pdpnPlayerInfo->dwDataSize); + } + + return S_OK; } static HRESULT WINAPI IDirectPlay8PeerImpl_GetPeerInfo(IDirectPlay8Peer *iface, const DPNID dpnid, diff --git a/dlls/dpnet/tests/peer.c b/dlls/dpnet/tests/peer.c index 1fec1f23b6c..f6c413f60a8 100644 --- a/dlls/dpnet/tests/peer.c +++ b/dlls/dpnet/tests/peer.c @@ -212,6 +212,74 @@ static void test_get_sp_caps(void) "expected 0x10000, got 0x%x\n", caps.dwSystemBufferSize); } +static void test_player_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}; + + ZeroMemory( &info, sizeof(DPN_PLAYER_INFO) ); + info.dwSize = sizeof(DPN_PLAYER_INFO); + info.dwInfoFlags = DPNINFO_NAME; + + hr = IDirectPlay8Peer_SetPeerInfo(peer, NULL, NULL, NULL, DPNSETPEERINFO_SYNC); + ok(hr == E_POINTER, "got %x\n", hr); + + info.pwszName = NULL; + hr = IDirectPlay8Peer_SetPeerInfo(peer, &info, NULL, NULL, DPNSETPEERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + info.pwszName = name; + hr = IDirectPlay8Peer_SetPeerInfo(peer, &info, NULL, NULL, DPNSETPEERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + info.dwInfoFlags = DPNINFO_NAME; + info.pwszName = name2; + hr = IDirectPlay8Peer_SetPeerInfo(peer, &info, NULL, NULL, DPNSETPEERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + +if(0) /* Crashes on windows */ +{ + info.dwInfoFlags = DPNINFO_DATA; + info.pwszName = NULL; + info.pvData = NULL; + info.dwDataSize = sizeof(data); + hr = IDirectPlay8Peer_SetPeerInfo(peer, &info, NULL, NULL, DPNSETPEERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); +} + + info.dwInfoFlags = DPNINFO_DATA; + info.pwszName = NULL; + info.pvData = data; + info.dwDataSize = 0; + hr = IDirectPlay8Peer_SetPeerInfo(peer, &info, NULL, NULL, DPNSETPEERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + info.dwInfoFlags = DPNINFO_DATA; + info.pwszName = NULL; + info.pvData = data; + info.dwDataSize = sizeof(data); + hr = IDirectPlay8Peer_SetPeerInfo(peer, &info, NULL, NULL, DPNSETPEERINFO_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 = IDirectPlay8Peer_SetPeerInfo(peer, &info, NULL, NULL, DPNSETPEERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); + + /* Leave PeerInfo with only the name set. */ + info.dwInfoFlags = DPNINFO_DATA | DPNINFO_NAME; + info.pwszName = name; + info.pvData = NULL; + info.dwDataSize = 0; + hr = IDirectPlay8Peer_SetPeerInfo(peer, &info, NULL, NULL, DPNSETPEERINFO_SYNC); + ok(hr == S_OK, "got %x\n", hr); +} + static void test_cleanup_dp(void) { HRESULT hr; @@ -238,5 +306,6 @@ START_TEST(peer) test_enum_service_providers(); test_enum_hosts(); test_get_sp_caps(); + test_player_info(); test_cleanup_dp(); }