diff --git a/dlls/dpnet/address.c b/dlls/dpnet/address.c index 7e10136e2dd..7a33f8af141 100644 --- a/dlls/dpnet/address.c +++ b/dlls/dpnet/address.c @@ -405,9 +405,69 @@ static HRESULT WINAPI IDirectPlay8AddressImpl_GetComponentByIndex(IDirectPlay8Ad const DWORD dwComponentID, WCHAR *pwszName, DWORD *pdwNameLen, void *pvBuffer, DWORD *pdwBufferSize, DWORD *pdwDataType) { - IDirectPlay8AddressImpl *This = impl_from_IDirectPlay8Address(iface); - TRACE("(%p): stub\n", This); - return DPN_OK; + IDirectPlay8AddressImpl *This = impl_from_IDirectPlay8Address(iface); + struct component *entry; + int namesize; + + TRACE("(%p)->(%u %p %p %p %p %p)\n", This, dwComponentID, pwszName, pdwNameLen, pvBuffer, pdwBufferSize, pdwDataType); + + if(!pdwNameLen || !pdwBufferSize || !pdwDataType) + { + WARN("Invalid buffer (%p, %p, %p)\n", pdwNameLen, pdwBufferSize, pdwDataType); + return DPNERR_INVALIDPOINTER; + } + + if(dwComponentID > This->comp_count) + { + WARN("dwComponentID out of range\n"); + return DPNERR_DOESNOTEXIST; + } + + entry = This->components[dwComponentID]; + + namesize = strlenW(entry->name); + if(*pdwBufferSize < entry->size || *pdwNameLen < namesize) + { + WARN("Buffer too small\n"); + + *pdwNameLen = namesize + 1; + *pdwBufferSize = entry->size; + *pdwDataType = entry->type; + return DPNERR_BUFFERTOOSMALL; + } + + if(!pwszName || !pvBuffer) + { + WARN("Invalid buffer (%p, %p)\n", pwszName, pvBuffer); + return DPNERR_INVALIDPOINTER; + } + + lstrcpyW(pwszName, entry->name); + + *pdwNameLen = namesize + 1; + *pdwBufferSize = entry->size; + *pdwDataType = entry->type; + + switch (entry->type) + { + case DPNA_DATATYPE_DWORD: + *(DWORD*)pvBuffer = entry->data.value; + break; + case DPNA_DATATYPE_GUID: + *(GUID*)pvBuffer = entry->data.guid; + break; + case DPNA_DATATYPE_STRING: + memcpy(pvBuffer, entry->data.string, entry->size); + break; + case DPNA_DATATYPE_STRING_ANSI: + memcpy(pvBuffer, entry->data.ansi, entry->size); + break; + case DPNA_DATATYPE_BINARY: + memcpy(pvBuffer, entry->data.binary, entry->size); + break; + } + + return S_OK; } static HRESULT WINAPI IDirectPlay8AddressImpl_AddComponent(IDirectPlay8Address *iface, diff --git a/dlls/dpnet/tests/address.c b/dlls/dpnet/tests/address.c index 077f99ed824..ee589f56a82 100644 --- a/dlls/dpnet/tests/address.c +++ b/dlls/dpnet/tests/address.c @@ -87,6 +87,7 @@ static void address_addcomponents(void) DWORD bufflen = 0; DWORD port = 8888; WCHAR buffer[256]; + WCHAR *name = NULL; /* We can add any Component to the Address interface not just the predefined ones. */ hr = IDirectPlay8Address_AddComponent(localaddr, UNKNOWN, &IID_Random, sizeof(GUID), DPNA_DATATYPE_GUID); @@ -175,25 +176,45 @@ static void address_addcomponents(void) ok(hr == S_OK, "got 0x%08x\n", hr); hr = IDirectPlay8Address_GetComponentByIndex(localaddr, 100, NULL, &namelen, NULL, &bufflen, &type); - todo_wine ok(hr == DPNERR_DOESNOTEXIST, "got 0x%08x\n", hr); + ok(hr == DPNERR_DOESNOTEXIST, "got 0x%08x\n", hr); + + hr = IDirectPlay8Address_GetComponentByIndex(localaddr, 1, NULL, &namelen, NULL, &bufflen, NULL); + ok(hr == DPNERR_INVALIDPOINTER, "got 0x%08x\n", hr); + + bufflen = 100; + namelen = 0; + hr = IDirectPlay8Address_GetComponentByIndex(localaddr, 1, name, &namelen, buffer, &bufflen, &type); + ok(hr == DPNERR_BUFFERTOOSMALL, "got 0x%08x\n", hr); + + namelen = 100; + hr = IDirectPlay8Address_GetComponentByIndex(localaddr, 1, NULL, &namelen, NULL, &bufflen, &type); + ok(hr == DPNERR_INVALIDPOINTER, "got 0x%08x\n", hr); hr = IDirectPlay8Address_GetComponentByIndex(localaddr, 100, NULL, NULL, NULL, &bufflen, &type); - todo_wine ok(hr == E_POINTER, "got 0x%08x\n", hr); + ok(hr == DPNERR_INVALIDPOINTER, "got 0x%08x\n", hr); hr = IDirectPlay8Address_GetComponentByIndex(localaddr, 100, NULL, &namelen, NULL, NULL, &type); - todo_wine ok(hr == E_POINTER, "got 0x%08x\n", hr); + ok(hr == DPNERR_INVALIDPOINTER, "got 0x%08x\n", hr); + + bufflen = 0; + namelen = 0; + type = 0; + hr = IDirectPlay8Address_GetComponentByIndex(localaddr, 0, NULL, &namelen, NULL, &bufflen, &type); + ok(hr == DPNERR_BUFFERTOOSMALL, "got 0x%08x\n", hr); + ok(namelen == 8, "namelen expected 8 got %d\n", namelen); + ok(bufflen == 16, "bufflen expected 16 got %d\n", bufflen); + ok(type == DPNA_DATATYPE_GUID, "type expected DPNA_DATATYPE_GUID got %d\n", type); trace("GetNumComponents=%d\n", components); for(i=0; i < components; i++) { - WCHAR *name; void *buffer; bufflen = 0; namelen = 0; hr = IDirectPlay8Address_GetComponentByIndex(localaddr, i, NULL, &namelen, NULL, &bufflen, &type); - todo_wine ok(hr == DPNERR_BUFFERTOOSMALL, "got 0x%08x\n", hr); + ok(hr == DPNERR_BUFFERTOOSMALL, "got 0x%08x\n", hr); name = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, namelen * sizeof(WCHAR)); buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bufflen); @@ -258,14 +279,14 @@ static void address_setsp(void) ok(components == 1, "components=%d\n", components); hr = IDirectPlay8Address_GetComponentByIndex(localaddr, 0, NULL, &namelen, NULL, &bufflen, &type); - todo_wine ok(hr == DPNERR_BUFFERTOOSMALL, "got 0x%08x\n", hr); + ok(hr == DPNERR_BUFFERTOOSMALL, "got 0x%08x\n", hr); name = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, namelen * sizeof(WCHAR)); hr = IDirectPlay8Address_GetComponentByIndex(localaddr, 0, name, &namelen, (void*)&guid, &bufflen, &type); ok(hr == S_OK, "got 0x%08x\n", hr); - todo_wine ok(type == DPNA_DATATYPE_GUID, "wrong datatype: %d\n", type); - todo_wine ok(IsEqualGUID(&guid, &CLSID_DP8SP_TCPIP), "wrong guid\n"); + ok(type == DPNA_DATATYPE_GUID, "wrong datatype: %d\n", type); + ok(IsEqualGUID(&guid, &CLSID_DP8SP_TCPIP), "wrong guid\n"); HeapFree(GetProcessHeap(), 0, name);