4 * Copyright 2004 Raphael Junqueira
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #include "wine/debug.h"
34 #include "dpnet_private.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(dpnet
);
39 static char *heap_strdupA( const char *str
)
43 if (!str
) return NULL
;
44 if ((ret
= HeapAlloc( GetProcessHeap(), 0, strlen(str
) + 1 ))) strcpy( ret
, str
);
48 static BOOL
add_component(IDirectPlay8AddressImpl
*This
, struct component
*item
)
50 if(This
->comp_count
== This
->comp_array_size
)
52 struct component
**temp
;
54 temp
= heap_realloc(This
->components
, sizeof(*temp
) * This
->comp_array_size
* 2 );
60 This
->comp_array_size
*= 2;
61 This
->components
= temp
;
64 This
->components
[This
->comp_count
] = item
;
70 static inline IDirectPlay8AddressImpl
*impl_from_IDirectPlay8Address(IDirectPlay8Address
*iface
)
72 return CONTAINING_RECORD(iface
, IDirectPlay8AddressImpl
, IDirectPlay8Address_iface
);
75 /* IDirectPlay8Address IUnknown parts follow: */
76 static HRESULT WINAPI
IDirectPlay8AddressImpl_QueryInterface(IDirectPlay8Address
*iface
,
77 REFIID riid
, void **ppv
)
79 if (IsEqualGUID(riid
, &IID_IUnknown
) || IsEqualGUID(riid
, &IID_IDirectPlay8Address
)) {
80 IUnknown_AddRef(iface
);
85 WARN("(%p)->(%s,%p),not found\n", iface
, debugstr_guid(riid
), ppv
);
89 static ULONG WINAPI
IDirectPlay8AddressImpl_AddRef(IDirectPlay8Address
*iface
)
91 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
92 ULONG ref
= InterlockedIncrement(&This
->ref
);
94 TRACE("(%p) ref=%u\n", This
, ref
);
99 static ULONG WINAPI
IDirectPlay8AddressImpl_Release(IDirectPlay8Address
*iface
)
101 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
102 ULONG ref
= InterlockedDecrement(&This
->ref
);
104 TRACE("(%p) ref=%u\n", This
, ref
);
108 struct component
*entry
;
111 for(i
=0; i
< This
->comp_count
; i
++)
113 entry
= This
->components
[i
];
117 case DPNA_DATATYPE_STRING
:
118 heap_free(entry
->data
.string
);
120 case DPNA_DATATYPE_STRING_ANSI
:
121 heap_free(entry
->data
.ansi
);
123 case DPNA_DATATYPE_BINARY
:
124 heap_free(entry
->data
.binary
);
128 heap_free(entry
->name
);
132 heap_free(This
->components
);
138 /* returns name of given GUID */
139 static const char *debugstr_SP(const GUID
*id
) {
140 static const guid_info guids
[] = {
143 GE(CLSID_DP8SP_TCPIP
),
144 GE(CLSID_DP8SP_SERIAL
),
145 GE(CLSID_DP8SP_MODEM
)
149 if (!id
) return "(null)";
151 for (i
= 0; i
< ARRAY_SIZE(guids
); i
++) {
152 if (IsEqualGUID(id
, guids
[i
].guid
))
153 return guids
[i
].name
;
155 /* if we didn't find it, act like standard debugstr_guid */
156 return debugstr_guid(id
);
159 /* IDirectPlay8Address Interface follow: */
161 static HRESULT WINAPI
IDirectPlay8AddressImpl_BuildFromURLW(IDirectPlay8Address
*iface
,
162 WCHAR
*pwszSourceURL
)
164 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
165 TRACE("(%p, %s): stub\n", This
, debugstr_w(pwszSourceURL
));
169 static HRESULT WINAPI
IDirectPlay8AddressImpl_BuildFromURLA(IDirectPlay8Address
*iface
,
172 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
173 TRACE("(%p, %s): stub\n", This
, pszSourceURL
);
177 static HRESULT WINAPI
IDirectPlay8AddressImpl_Duplicate(IDirectPlay8Address
*iface
,
178 IDirectPlay8Address
**ppdpaNewAddress
)
180 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
181 IDirectPlay8Address
*dup
;
184 TRACE("(%p, %p)\n", This
, ppdpaNewAddress
);
189 hr
= DPNET_CreateDirectPlay8Address(NULL
, NULL
, &IID_IDirectPlay8Address
, (LPVOID
*)&dup
);
192 IDirectPlay8AddressImpl
*DupThis
= impl_from_IDirectPlay8Address(dup
);
195 DupThis
->SP_guid
= This
->SP_guid
;
196 DupThis
->init
= This
->init
;
198 for(i
=0; i
< This
->comp_count
; i
++)
200 struct component
*entry
= This
->components
[i
];
204 case DPNA_DATATYPE_DWORD
:
205 hr
= IDirectPlay8Address_AddComponent(dup
, entry
->name
, &entry
->data
.value
, entry
->size
, entry
->type
);
207 case DPNA_DATATYPE_GUID
:
208 hr
= IDirectPlay8Address_AddComponent(dup
, entry
->name
, &entry
->data
.guid
, entry
->size
, entry
->type
);
210 case DPNA_DATATYPE_STRING
:
211 hr
= IDirectPlay8Address_AddComponent(dup
, entry
->name
, entry
->data
.string
, entry
->size
, entry
->type
);
213 case DPNA_DATATYPE_STRING_ANSI
:
214 hr
= IDirectPlay8Address_AddComponent(dup
, entry
->name
, entry
->data
.ansi
, entry
->size
, entry
->type
);
216 case DPNA_DATATYPE_BINARY
:
217 hr
= IDirectPlay8Address_AddComponent(dup
, entry
->name
, entry
->data
.binary
, entry
->size
, entry
->type
);
223 IDirectPlay8Address_Release(dup
);
225 ERR("Failed to copy component: %s - 0x%08x\n", debugstr_w(entry
->name
), hr
);
230 *ppdpaNewAddress
= dup
;
236 static HRESULT WINAPI
IDirectPlay8AddressImpl_SetEqual(IDirectPlay8Address
*iface
,
237 IDirectPlay8Address
*pdpaAddress
)
239 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
240 TRACE("(%p, %p): stub\n", This
, pdpaAddress
);
244 static HRESULT WINAPI
IDirectPlay8AddressImpl_IsEqual(IDirectPlay8Address
*iface
,
245 IDirectPlay8Address
*pdpaAddress
)
247 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
248 TRACE("(%p, %p): stub\n", This
, pdpaAddress
);
252 static HRESULT WINAPI
IDirectPlay8AddressImpl_Clear(IDirectPlay8Address
*iface
)
254 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
255 TRACE("(%p): stub\n", This
);
259 static HRESULT WINAPI
IDirectPlay8AddressImpl_GetURLW(IDirectPlay8Address
*iface
, WCHAR
*pwszURL
,
262 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
263 TRACE("(%p): stub\n", This
);
267 static HRESULT WINAPI
IDirectPlay8AddressImpl_GetURLA(IDirectPlay8Address
*iface
, CHAR
*pszURL
,
270 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
271 TRACE("(%p): stub\n", This
);
275 static HRESULT WINAPI
IDirectPlay8AddressImpl_GetSP(IDirectPlay8Address
*iface
, GUID
*pguidSP
)
277 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
279 TRACE("(%p, %p)\n", iface
, pguidSP
);
282 return DPNERR_INVALIDPOINTER
;
285 return DPNERR_DOESNOTEXIST
;
287 *pguidSP
= This
->SP_guid
;
291 static HRESULT WINAPI
IDirectPlay8AddressImpl_GetUserData(IDirectPlay8Address
*iface
,
292 void *pvUserData
, DWORD
*pdwBufferSize
)
294 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
295 TRACE("(%p): stub\n", This
);
299 static HRESULT WINAPI
IDirectPlay8AddressImpl_SetSP(IDirectPlay8Address
*iface
,
300 const GUID
*const pguidSP
)
302 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
304 TRACE("(%p, %s)\n", iface
, debugstr_SP(pguidSP
));
307 return DPNERR_INVALIDPOINTER
;
310 This
->SP_guid
= *pguidSP
;
312 IDirectPlay8Address_AddComponent(iface
, DPNA_KEY_PROVIDER
, &This
->SP_guid
, sizeof(GUID
), DPNA_DATATYPE_GUID
);
317 static HRESULT WINAPI
IDirectPlay8AddressImpl_SetUserData(IDirectPlay8Address
*iface
,
318 const void *const pvUserData
, const DWORD dwDataSize
)
320 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
321 TRACE("(%p): stub\n", This
);
325 static HRESULT WINAPI
IDirectPlay8AddressImpl_GetNumComponents(IDirectPlay8Address
*iface
,
326 DWORD
*pdwNumComponents
)
328 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
329 TRACE("(%p): stub\n", This
);
331 if(!pdwNumComponents
)
332 return DPNERR_INVALIDPOINTER
;
334 *pdwNumComponents
= This
->comp_count
;
339 static HRESULT WINAPI
IDirectPlay8AddressImpl_GetComponentByName(IDirectPlay8Address
*iface
,
340 const WCHAR
*const pwszName
, void *pvBuffer
, DWORD
*pdwBufferSize
, DWORD
*pdwDataType
)
342 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
343 struct component
*entry
;
346 TRACE("(%p)->(%s %p %p %p)\n", This
, debugstr_w(pwszName
), pvBuffer
, pdwBufferSize
, pdwDataType
);
348 if(!pwszName
|| !pdwBufferSize
|| !pdwDataType
|| (!pvBuffer
&& *pdwBufferSize
))
351 for(i
=0; i
< This
->comp_count
; i
++)
353 entry
= This
->components
[i
];
355 if (lstrcmpW(pwszName
, entry
->name
) == 0)
357 TRACE("Found %s\n", debugstr_w(pwszName
));
359 if(*pdwBufferSize
< entry
->size
)
361 *pdwBufferSize
= entry
->size
;
362 return DPNERR_BUFFERTOOSMALL
;
365 *pdwBufferSize
= entry
->size
;
366 *pdwDataType
= entry
->type
;
370 case DPNA_DATATYPE_DWORD
:
371 memcpy(pvBuffer
, &entry
->data
.value
, sizeof(DWORD
));
373 case DPNA_DATATYPE_GUID
:
374 memcpy(pvBuffer
, &entry
->data
.guid
, sizeof(GUID
));
376 case DPNA_DATATYPE_STRING
:
377 memcpy(pvBuffer
, entry
->data
.string
, entry
->size
);
379 case DPNA_DATATYPE_STRING_ANSI
:
380 memcpy(pvBuffer
, entry
->data
.ansi
, entry
->size
);
382 case DPNA_DATATYPE_BINARY
:
383 memcpy(pvBuffer
, entry
->data
.binary
, entry
->size
);
391 return DPNERR_DOESNOTEXIST
;
394 static HRESULT WINAPI
IDirectPlay8AddressImpl_GetComponentByIndex(IDirectPlay8Address
*iface
,
395 const DWORD dwComponentID
, WCHAR
*pwszName
, DWORD
*pdwNameLen
, void *pvBuffer
,
396 DWORD
*pdwBufferSize
, DWORD
*pdwDataType
)
398 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
399 struct component
*entry
;
402 TRACE("(%p)->(%u %p %p %p %p %p)\n", This
, dwComponentID
, pwszName
, pdwNameLen
, pvBuffer
, pdwBufferSize
, pdwDataType
);
404 if(!pdwNameLen
|| !pdwBufferSize
|| !pdwDataType
)
406 WARN("Invalid buffer (%p, %p, %p)\n", pdwNameLen
, pdwBufferSize
, pdwDataType
);
407 return DPNERR_INVALIDPOINTER
;
410 if(dwComponentID
> This
->comp_count
)
412 WARN("dwComponentID out of range\n");
413 return DPNERR_DOESNOTEXIST
;
416 entry
= This
->components
[dwComponentID
];
418 namesize
= lstrlenW(entry
->name
);
419 if(*pdwBufferSize
< entry
->size
|| *pdwNameLen
< namesize
)
421 WARN("Buffer too small\n");
423 *pdwNameLen
= namesize
+ 1;
424 *pdwBufferSize
= entry
->size
;
425 *pdwDataType
= entry
->type
;
426 return DPNERR_BUFFERTOOSMALL
;
429 if(!pwszName
|| !pvBuffer
)
431 WARN("Invalid buffer (%p, %p)\n", pwszName
, pvBuffer
);
432 return DPNERR_INVALIDPOINTER
;
435 lstrcpyW(pwszName
, entry
->name
);
437 *pdwNameLen
= namesize
+ 1;
438 *pdwBufferSize
= entry
->size
;
439 *pdwDataType
= entry
->type
;
443 case DPNA_DATATYPE_DWORD
:
444 *(DWORD
*)pvBuffer
= entry
->data
.value
;
446 case DPNA_DATATYPE_GUID
:
447 *(GUID
*)pvBuffer
= entry
->data
.guid
;
449 case DPNA_DATATYPE_STRING
:
450 memcpy(pvBuffer
, entry
->data
.string
, entry
->size
);
452 case DPNA_DATATYPE_STRING_ANSI
:
453 memcpy(pvBuffer
, entry
->data
.ansi
, entry
->size
);
455 case DPNA_DATATYPE_BINARY
:
456 memcpy(pvBuffer
, entry
->data
.binary
, entry
->size
);
463 static HRESULT WINAPI
IDirectPlay8AddressImpl_AddComponent(IDirectPlay8Address
*iface
,
464 const WCHAR
*const pwszName
, const void* const lpvData
, const DWORD dwDataSize
,
465 const DWORD dwDataType
)
467 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
468 struct component
*entry
;
472 TRACE("(%p, %s, %p, %u, %x)\n", This
, debugstr_w(pwszName
), lpvData
, dwDataSize
, dwDataType
);
475 return DPNERR_INVALIDPOINTER
;
479 case DPNA_DATATYPE_DWORD
:
480 if (sizeof(DWORD
) != dwDataSize
)
482 WARN("Invalid DWORD size, returning DPNERR_INVALIDPARAM\n");
483 return DPNERR_INVALIDPARAM
;
486 case DPNA_DATATYPE_GUID
:
487 if (sizeof(GUID
) != dwDataSize
)
489 WARN("Invalid GUID size, returning DPNERR_INVALIDPARAM\n");
490 return DPNERR_INVALIDPARAM
;
493 case DPNA_DATATYPE_STRING
:
494 if (((lstrlenW((WCHAR
*)lpvData
)+1)*sizeof(WCHAR
)) != dwDataSize
)
496 WARN("Invalid STRING size, returning DPNERR_INVALIDPARAM\n");
497 return DPNERR_INVALIDPARAM
;
500 case DPNA_DATATYPE_STRING_ANSI
:
501 if ((strlen((const CHAR
*)lpvData
)+1) != dwDataSize
)
503 WARN("Invalid ASCII size, returning DPNERR_INVALIDPARAM\n");
504 return DPNERR_INVALIDPARAM
;
509 for(i
=0; i
< This
->comp_count
; i
++)
511 entry
= This
->components
[i
];
513 if (lstrcmpW(pwszName
, entry
->name
) == 0)
515 TRACE("Found %s\n", debugstr_w(pwszName
));
518 if(entry
->type
== DPNA_DATATYPE_STRING_ANSI
)
519 heap_free(entry
->data
.ansi
);
520 else if(entry
->type
== DPNA_DATATYPE_STRING
)
521 heap_free(entry
->data
.string
);
522 else if(entry
->type
== DPNA_DATATYPE_BINARY
)
523 heap_free(entry
->data
.binary
);
531 /* Create a new one */
532 entry
= heap_alloc(sizeof(struct component
));
534 return E_OUTOFMEMORY
;
536 entry
->name
= heap_strdupW(pwszName
);
540 return E_OUTOFMEMORY
;
543 if(!add_component(This
, entry
))
545 heap_free(entry
->name
);
547 return E_OUTOFMEMORY
;
553 case DPNA_DATATYPE_DWORD
:
554 entry
->data
.value
= *(DWORD
*)lpvData
;
555 TRACE("(%p, %u): DWORD Type -> %u\n", lpvData
, dwDataSize
, *(const DWORD
*) lpvData
);
557 case DPNA_DATATYPE_GUID
:
558 entry
->data
.guid
= *(GUID
*)lpvData
;
559 TRACE("(%p, %u): GUID Type -> %s\n", lpvData
, dwDataSize
, debugstr_guid(lpvData
));
561 case DPNA_DATATYPE_STRING
:
562 entry
->data
.string
= heap_strdupW((WCHAR
*)lpvData
);
563 TRACE("(%p, %u): STRING Type -> %s\n", lpvData
, dwDataSize
, debugstr_w((WCHAR
*)lpvData
));
565 case DPNA_DATATYPE_STRING_ANSI
:
566 entry
->data
.ansi
= heap_strdupA((CHAR
*)lpvData
);
567 TRACE("(%p, %u): ANSI STRING Type -> %s\n", lpvData
, dwDataSize
, (const CHAR
*) lpvData
);
569 case DPNA_DATATYPE_BINARY
:
570 entry
->data
.binary
= heap_alloc(dwDataSize
);
571 memcpy(entry
->data
.binary
, lpvData
, dwDataSize
);
572 TRACE("(%p, %u): BINARY Type\n", lpvData
, dwDataSize
);
576 entry
->type
= dwDataType
;
577 entry
->size
= dwDataSize
;
582 static HRESULT WINAPI
IDirectPlay8AddressImpl_GetDevice(IDirectPlay8Address
*iface
, GUID
*pDevGuid
) {
583 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
584 TRACE("(%p): stub\n", This
);
588 static HRESULT WINAPI
IDirectPlay8AddressImpl_SetDevice(IDirectPlay8Address
*iface
,
589 const GUID
*const devGuid
)
591 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
592 TRACE("(%p, %s): stub\n", This
, debugstr_guid(devGuid
));
596 static HRESULT WINAPI
IDirectPlay8AddressImpl_BuildFromDirectPlay4Address(IDirectPlay8Address
*iface
,
597 void *pvAddress
, DWORD dwDataSize
)
599 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
600 TRACE("(%p): stub\n", This
);
604 static const IDirectPlay8AddressVtbl DirectPlay8Address_Vtbl
=
606 IDirectPlay8AddressImpl_QueryInterface
,
607 IDirectPlay8AddressImpl_AddRef
,
608 IDirectPlay8AddressImpl_Release
,
609 IDirectPlay8AddressImpl_BuildFromURLW
,
610 IDirectPlay8AddressImpl_BuildFromURLA
,
611 IDirectPlay8AddressImpl_Duplicate
,
612 IDirectPlay8AddressImpl_SetEqual
,
613 IDirectPlay8AddressImpl_IsEqual
,
614 IDirectPlay8AddressImpl_Clear
,
615 IDirectPlay8AddressImpl_GetURLW
,
616 IDirectPlay8AddressImpl_GetURLA
,
617 IDirectPlay8AddressImpl_GetSP
,
618 IDirectPlay8AddressImpl_GetUserData
,
619 IDirectPlay8AddressImpl_SetSP
,
620 IDirectPlay8AddressImpl_SetUserData
,
621 IDirectPlay8AddressImpl_GetNumComponents
,
622 IDirectPlay8AddressImpl_GetComponentByName
,
623 IDirectPlay8AddressImpl_GetComponentByIndex
,
624 IDirectPlay8AddressImpl_AddComponent
,
625 IDirectPlay8AddressImpl_GetDevice
,
626 IDirectPlay8AddressImpl_SetDevice
,
627 IDirectPlay8AddressImpl_BuildFromDirectPlay4Address
630 HRESULT
DPNET_CreateDirectPlay8Address(IClassFactory
*iface
, IUnknown
*pUnkOuter
, REFIID riid
, LPVOID
*ppobj
)
632 IDirectPlay8AddressImpl
* client
;
635 TRACE("(%p, %s, %p)\n", pUnkOuter
, debugstr_guid(riid
), ppobj
);
639 client
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectPlay8AddressImpl
));
641 return E_OUTOFMEMORY
;
643 client
->IDirectPlay8Address_iface
.lpVtbl
= &DirectPlay8Address_Vtbl
;
645 client
->comp_array_size
= 4;
646 client
->components
= heap_alloc( sizeof(*client
->components
) * client
->comp_array_size
);
647 if(!client
->components
)
650 return E_OUTOFMEMORY
;
653 ret
= IDirectPlay8AddressImpl_QueryInterface(&client
->IDirectPlay8Address_iface
, riid
, ppobj
);
654 IDirectPlay8AddressImpl_Release(&client
->IDirectPlay8Address_iface
);