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
33 #include "wine/unicode.h"
34 #include "wine/debug.h"
37 #include "dpnet_private.h"
39 WINE_DEFAULT_DEBUG_CHANNEL(dpnet
);
42 static inline void *heap_alloc(size_t len
)
44 return HeapAlloc(GetProcessHeap(), 0, len
);
47 static inline void *heap_realloc(void *mem
, size_t len
)
49 return HeapReAlloc( GetProcessHeap(), 0, mem
, len
);
52 static inline BOOL
heap_free(void *mem
)
54 return HeapFree(GetProcessHeap(), 0, mem
);
57 static inline LPWSTR
heap_strdupW(LPCWSTR str
)
64 size
= (strlenW(str
)+1)*sizeof(WCHAR
);
65 ret
= heap_alloc(size
);
67 memcpy(ret
, str
, size
);
73 static char *heap_strdupA( const char *str
)
77 if (!str
) return NULL
;
78 if ((ret
= HeapAlloc( GetProcessHeap(), 0, strlen(str
) + 1 ))) strcpy( ret
, str
);
82 static BOOL
add_component(IDirectPlay8AddressImpl
*This
, struct component
*item
)
84 if(This
->comp_count
== This
->comp_array_size
)
86 struct component
**temp
;
88 temp
= heap_realloc(This
->components
, sizeof(*temp
) * This
->comp_array_size
* 2 );
94 This
->comp_array_size
*= 2;
95 This
->components
= temp
;
98 This
->components
[This
->comp_count
] = item
;
104 static inline IDirectPlay8AddressImpl
*impl_from_IDirectPlay8Address(IDirectPlay8Address
*iface
)
106 return CONTAINING_RECORD(iface
, IDirectPlay8AddressImpl
, IDirectPlay8Address_iface
);
109 /* IDirectPlay8Address IUnknown parts follow: */
110 static HRESULT WINAPI
IDirectPlay8AddressImpl_QueryInterface(IDirectPlay8Address
*iface
,
111 REFIID riid
, void **ppv
)
113 if (IsEqualGUID(riid
, &IID_IUnknown
) || IsEqualGUID(riid
, &IID_IDirectPlay8Address
)) {
114 IUnknown_AddRef(iface
);
119 WARN("(%p)->(%s,%p),not found\n", iface
, debugstr_guid(riid
), ppv
);
120 return E_NOINTERFACE
;
123 static ULONG WINAPI
IDirectPlay8AddressImpl_AddRef(IDirectPlay8Address
*iface
)
125 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
126 ULONG ref
= InterlockedIncrement(&This
->ref
);
128 TRACE("(%p) ref=%u\n", This
, ref
);
133 static ULONG WINAPI
IDirectPlay8AddressImpl_Release(IDirectPlay8Address
*iface
)
135 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
136 ULONG ref
= InterlockedDecrement(&This
->ref
);
138 TRACE("(%p) ref=%u\n", This
, ref
);
142 struct component
*entry
;
145 for(i
=0; i
< This
->comp_count
; i
++)
147 entry
= This
->components
[i
];
151 case DPNA_DATATYPE_STRING
:
152 heap_free(entry
->data
.string
);
154 case DPNA_DATATYPE_STRING_ANSI
:
155 heap_free(entry
->data
.ansi
);
157 case DPNA_DATATYPE_BINARY
:
158 heap_free(entry
->data
.binary
);
162 heap_free(entry
->name
);
166 heap_free(This
->components
);
172 /* returns name of given GUID */
173 static const char *debugstr_SP(const GUID
*id
) {
174 static const guid_info guids
[] = {
177 GE(CLSID_DP8SP_TCPIP
),
178 GE(CLSID_DP8SP_SERIAL
),
179 GE(CLSID_DP8SP_MODEM
)
183 if (!id
) return "(null)";
185 for (i
= 0; i
< sizeof(guids
)/sizeof(guids
[0]); i
++) {
186 if (IsEqualGUID(id
, guids
[i
].guid
))
187 return guids
[i
].name
;
189 /* if we didn't find it, act like standard debugstr_guid */
190 return debugstr_guid(id
);
193 /* IDirectPlay8Address Interface follow: */
195 static HRESULT WINAPI
IDirectPlay8AddressImpl_BuildFromURLW(IDirectPlay8Address
*iface
,
196 WCHAR
*pwszSourceURL
)
198 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
199 TRACE("(%p, %s): stub\n", This
, debugstr_w(pwszSourceURL
));
203 static HRESULT WINAPI
IDirectPlay8AddressImpl_BuildFromURLA(IDirectPlay8Address
*iface
,
206 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
207 TRACE("(%p, %s): stub\n", This
, pszSourceURL
);
211 static HRESULT WINAPI
IDirectPlay8AddressImpl_Duplicate(IDirectPlay8Address
*iface
,
212 IDirectPlay8Address
**ppdpaNewAddress
)
214 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
215 IDirectPlay8Address
*dup
;
218 TRACE("(%p, %p)\n", This
, ppdpaNewAddress
);
223 hr
= DPNET_CreateDirectPlay8Address(NULL
, NULL
, &IID_IDirectPlay8Address
, (LPVOID
*)&dup
);
226 IDirectPlay8AddressImpl
*DupThis
= impl_from_IDirectPlay8Address(dup
);
229 DupThis
->SP_guid
= This
->SP_guid
;
230 DupThis
->init
= This
->init
;
232 for(i
=0; i
< This
->comp_count
; i
++)
234 struct component
*entry
= This
->components
[i
];
238 case DPNA_DATATYPE_DWORD
:
239 hr
= IDirectPlay8Address_AddComponent(dup
, entry
->name
, &entry
->data
.value
, entry
->size
, entry
->type
);
241 case DPNA_DATATYPE_GUID
:
242 hr
= IDirectPlay8Address_AddComponent(dup
, entry
->name
, &entry
->data
.guid
, entry
->size
, entry
->type
);
244 case DPNA_DATATYPE_STRING
:
245 hr
= IDirectPlay8Address_AddComponent(dup
, entry
->name
, entry
->data
.string
, entry
->size
, entry
->type
);
247 case DPNA_DATATYPE_STRING_ANSI
:
248 hr
= IDirectPlay8Address_AddComponent(dup
, entry
->name
, entry
->data
.ansi
, entry
->size
, entry
->type
);
250 case DPNA_DATATYPE_BINARY
:
251 hr
= IDirectPlay8Address_AddComponent(dup
, entry
->name
, entry
->data
.binary
, entry
->size
, entry
->type
);
257 IDirectPlay8Address_Release(dup
);
259 ERR("Failed to copy component: %s - 0x%08x\n", debugstr_w(entry
->name
), hr
);
264 *ppdpaNewAddress
= dup
;
270 static HRESULT WINAPI
IDirectPlay8AddressImpl_SetEqual(IDirectPlay8Address
*iface
,
271 IDirectPlay8Address
*pdpaAddress
)
273 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
274 TRACE("(%p, %p): stub\n", This
, pdpaAddress
);
278 static HRESULT WINAPI
IDirectPlay8AddressImpl_IsEqual(IDirectPlay8Address
*iface
,
279 IDirectPlay8Address
*pdpaAddress
)
281 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
282 TRACE("(%p, %p): stub\n", This
, pdpaAddress
);
286 static HRESULT WINAPI
IDirectPlay8AddressImpl_Clear(IDirectPlay8Address
*iface
)
288 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
289 TRACE("(%p): stub\n", This
);
293 static HRESULT WINAPI
IDirectPlay8AddressImpl_GetURLW(IDirectPlay8Address
*iface
, WCHAR
*pwszURL
,
296 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
297 TRACE("(%p): stub\n", This
);
301 static HRESULT WINAPI
IDirectPlay8AddressImpl_GetURLA(IDirectPlay8Address
*iface
, CHAR
*pszURL
,
304 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
305 TRACE("(%p): stub\n", This
);
309 static HRESULT WINAPI
IDirectPlay8AddressImpl_GetSP(IDirectPlay8Address
*iface
, GUID
*pguidSP
)
311 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
313 TRACE("(%p, %p)\n", iface
, pguidSP
);
316 return DPNERR_INVALIDPOINTER
;
319 return DPNERR_DOESNOTEXIST
;
321 *pguidSP
= This
->SP_guid
;
325 static HRESULT WINAPI
IDirectPlay8AddressImpl_GetUserData(IDirectPlay8Address
*iface
,
326 void *pvUserData
, DWORD
*pdwBufferSize
)
328 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
329 TRACE("(%p): stub\n", This
);
333 static HRESULT WINAPI
IDirectPlay8AddressImpl_SetSP(IDirectPlay8Address
*iface
,
334 const GUID
*const pguidSP
)
336 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
338 TRACE("(%p, %s)\n", iface
, debugstr_SP(pguidSP
));
341 return DPNERR_INVALIDPOINTER
;
344 This
->SP_guid
= *pguidSP
;
346 IDirectPlay8Address_AddComponent(iface
, DPNA_KEY_PROVIDER
, &This
->SP_guid
, sizeof(GUID
), DPNA_DATATYPE_GUID
);
351 static HRESULT WINAPI
IDirectPlay8AddressImpl_SetUserData(IDirectPlay8Address
*iface
,
352 const void *const pvUserData
, const DWORD dwDataSize
)
354 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
355 TRACE("(%p): stub\n", This
);
359 static HRESULT WINAPI
IDirectPlay8AddressImpl_GetNumComponents(IDirectPlay8Address
*iface
,
360 DWORD
*pdwNumComponents
)
362 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
363 TRACE("(%p): stub\n", This
);
365 if(!pdwNumComponents
)
366 return DPNERR_INVALIDPOINTER
;
368 *pdwNumComponents
= This
->comp_count
;
373 static HRESULT WINAPI
IDirectPlay8AddressImpl_GetComponentByName(IDirectPlay8Address
*iface
,
374 const WCHAR
*const pwszName
, void *pvBuffer
, DWORD
*pdwBufferSize
, DWORD
*pdwDataType
)
376 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
377 struct component
*entry
;
380 TRACE("(%p)->(%p %p %p %p)\n", This
, pwszName
, pvBuffer
, pdwBufferSize
, pdwDataType
);
382 if(!pwszName
|| !pdwBufferSize
|| !pdwDataType
|| (!pvBuffer
&& pdwBufferSize
))
385 for(i
=0; i
< This
->comp_count
; i
++)
387 entry
= This
->components
[i
];
389 if (lstrcmpW(pwszName
, entry
->name
) == 0)
391 TRACE("Found %s\n", debugstr_w(pwszName
));
393 if(*pdwBufferSize
< entry
->size
)
395 *pdwBufferSize
= entry
->size
;
396 return DPNERR_BUFFERTOOSMALL
;
399 *pdwBufferSize
= entry
->size
;
400 *pdwDataType
= entry
->type
;
404 case DPNA_DATATYPE_DWORD
:
405 memcpy(pvBuffer
, &entry
->data
.value
, sizeof(DWORD
));
407 case DPNA_DATATYPE_GUID
:
408 memcpy(pvBuffer
, &entry
->data
.guid
, sizeof(GUID
));
410 case DPNA_DATATYPE_STRING
:
411 memcpy(pvBuffer
, entry
->data
.string
, entry
->size
);
413 case DPNA_DATATYPE_STRING_ANSI
:
414 memcpy(pvBuffer
, entry
->data
.ansi
, entry
->size
);
416 case DPNA_DATATYPE_BINARY
:
417 memcpy(pvBuffer
, entry
->data
.binary
, entry
->size
);
425 return DPNERR_DOESNOTEXIST
;
428 static HRESULT WINAPI
IDirectPlay8AddressImpl_GetComponentByIndex(IDirectPlay8Address
*iface
,
429 const DWORD dwComponentID
, WCHAR
*pwszName
, DWORD
*pdwNameLen
, void *pvBuffer
,
430 DWORD
*pdwBufferSize
, DWORD
*pdwDataType
)
432 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
433 struct component
*entry
;
436 TRACE("(%p)->(%u %p %p %p %p %p)\n", This
, dwComponentID
, pwszName
, pdwNameLen
, pvBuffer
, pdwBufferSize
, pdwDataType
);
438 if(!pdwNameLen
|| !pdwBufferSize
|| !pdwDataType
)
440 WARN("Invalid buffer (%p, %p, %p)\n", pdwNameLen
, pdwBufferSize
, pdwDataType
);
441 return DPNERR_INVALIDPOINTER
;
444 if(dwComponentID
> This
->comp_count
)
446 WARN("dwComponentID out of range\n");
447 return DPNERR_DOESNOTEXIST
;
450 entry
= This
->components
[dwComponentID
];
452 namesize
= strlenW(entry
->name
);
453 if(*pdwBufferSize
< entry
->size
|| *pdwNameLen
< namesize
)
455 WARN("Buffer too small\n");
457 *pdwNameLen
= namesize
+ 1;
458 *pdwBufferSize
= entry
->size
;
459 *pdwDataType
= entry
->type
;
460 return DPNERR_BUFFERTOOSMALL
;
463 if(!pwszName
|| !pvBuffer
)
465 WARN("Invalid buffer (%p, %p)\n", pwszName
, pvBuffer
);
466 return DPNERR_INVALIDPOINTER
;
469 lstrcpyW(pwszName
, entry
->name
);
471 *pdwNameLen
= namesize
+ 1;
472 *pdwBufferSize
= entry
->size
;
473 *pdwDataType
= entry
->type
;
477 case DPNA_DATATYPE_DWORD
:
478 *(DWORD
*)pvBuffer
= entry
->data
.value
;
480 case DPNA_DATATYPE_GUID
:
481 *(GUID
*)pvBuffer
= entry
->data
.guid
;
483 case DPNA_DATATYPE_STRING
:
484 memcpy(pvBuffer
, entry
->data
.string
, entry
->size
);
486 case DPNA_DATATYPE_STRING_ANSI
:
487 memcpy(pvBuffer
, entry
->data
.ansi
, entry
->size
);
489 case DPNA_DATATYPE_BINARY
:
490 memcpy(pvBuffer
, entry
->data
.binary
, entry
->size
);
497 static HRESULT WINAPI
IDirectPlay8AddressImpl_AddComponent(IDirectPlay8Address
*iface
,
498 const WCHAR
*const pwszName
, const void* const lpvData
, const DWORD dwDataSize
,
499 const DWORD dwDataType
)
501 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
502 struct component
*entry
;
506 TRACE("(%p, %s, %p, %u, %x)\n", This
, debugstr_w(pwszName
), lpvData
, dwDataSize
, dwDataType
);
509 return DPNERR_INVALIDPOINTER
;
513 case DPNA_DATATYPE_DWORD
:
514 if (sizeof(DWORD
) != dwDataSize
)
516 WARN("Invalid DWORD size, returning DPNERR_INVALIDPARAM\n");
517 return DPNERR_INVALIDPARAM
;
520 case DPNA_DATATYPE_GUID
:
521 if (sizeof(GUID
) != dwDataSize
)
523 WARN("Invalid GUID size, returning DPNERR_INVALIDPARAM\n");
524 return DPNERR_INVALIDPARAM
;
527 case DPNA_DATATYPE_STRING
:
528 if (((strlenW((WCHAR
*)lpvData
)+1)*sizeof(WCHAR
)) != dwDataSize
)
530 WARN("Invalid STRING size, returning DPNERR_INVALIDPARAM\n");
531 return DPNERR_INVALIDPARAM
;
534 case DPNA_DATATYPE_STRING_ANSI
:
535 if ((strlen((const CHAR
*)lpvData
)+1) != dwDataSize
)
537 WARN("Invalid ASCII size, returning DPNERR_INVALIDPARAM\n");
538 return DPNERR_INVALIDPARAM
;
543 for(i
=0; i
< This
->comp_count
; i
++)
545 entry
= This
->components
[i
];
547 if (lstrcmpW(pwszName
, entry
->name
) == 0)
549 TRACE("Found %s\n", debugstr_w(pwszName
));
552 if(entry
->type
== DPNA_DATATYPE_STRING_ANSI
)
553 heap_free(entry
->data
.ansi
);
554 else if(entry
->type
== DPNA_DATATYPE_STRING
)
555 heap_free(entry
->data
.string
);
556 else if(entry
->type
== DPNA_DATATYPE_BINARY
)
557 heap_free(entry
->data
.binary
);
565 /* Create a new one */
566 entry
= heap_alloc(sizeof(struct component
));
568 return E_OUTOFMEMORY
;
570 entry
->name
= heap_strdupW(pwszName
);
574 return E_OUTOFMEMORY
;
577 if(!add_component(This
, entry
))
579 heap_free(entry
->name
);
581 return E_OUTOFMEMORY
;
587 case DPNA_DATATYPE_DWORD
:
588 entry
->data
.value
= *(DWORD
*)lpvData
;
589 TRACE("(%p, %u): DWORD Type -> %u\n", lpvData
, dwDataSize
, *(const DWORD
*) lpvData
);
591 case DPNA_DATATYPE_GUID
:
592 entry
->data
.guid
= *(GUID
*)lpvData
;
593 TRACE("(%p, %u): GUID Type -> %s\n", lpvData
, dwDataSize
, debugstr_guid(lpvData
));
595 case DPNA_DATATYPE_STRING
:
596 entry
->data
.string
= heap_strdupW((WCHAR
*)lpvData
);
597 TRACE("(%p, %u): STRING Type -> %s\n", lpvData
, dwDataSize
, debugstr_w((WCHAR
*)lpvData
));
599 case DPNA_DATATYPE_STRING_ANSI
:
600 entry
->data
.ansi
= heap_strdupA((CHAR
*)lpvData
);
601 TRACE("(%p, %u): ANSI STRING Type -> %s\n", lpvData
, dwDataSize
, (const CHAR
*) lpvData
);
603 case DPNA_DATATYPE_BINARY
:
604 entry
->data
.binary
= heap_alloc(dwDataSize
);
605 memcpy(entry
->data
.binary
, lpvData
, dwDataSize
);
606 TRACE("(%p, %u): BINARY Type\n", lpvData
, dwDataSize
);
610 entry
->type
= dwDataType
;
611 entry
->size
= dwDataSize
;
616 static HRESULT WINAPI
IDirectPlay8AddressImpl_GetDevice(IDirectPlay8Address
*iface
, GUID
*pDevGuid
) {
617 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
618 TRACE("(%p): stub\n", This
);
622 static HRESULT WINAPI
IDirectPlay8AddressImpl_SetDevice(IDirectPlay8Address
*iface
,
623 const GUID
*const devGuid
)
625 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
626 TRACE("(%p, %s): stub\n", This
, debugstr_guid(devGuid
));
630 static HRESULT WINAPI
IDirectPlay8AddressImpl_BuildFromDirectPlay4Address(IDirectPlay8Address
*iface
,
631 void *pvAddress
, DWORD dwDataSize
)
633 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
634 TRACE("(%p): stub\n", This
);
638 static const IDirectPlay8AddressVtbl DirectPlay8Address_Vtbl
=
640 IDirectPlay8AddressImpl_QueryInterface
,
641 IDirectPlay8AddressImpl_AddRef
,
642 IDirectPlay8AddressImpl_Release
,
643 IDirectPlay8AddressImpl_BuildFromURLW
,
644 IDirectPlay8AddressImpl_BuildFromURLA
,
645 IDirectPlay8AddressImpl_Duplicate
,
646 IDirectPlay8AddressImpl_SetEqual
,
647 IDirectPlay8AddressImpl_IsEqual
,
648 IDirectPlay8AddressImpl_Clear
,
649 IDirectPlay8AddressImpl_GetURLW
,
650 IDirectPlay8AddressImpl_GetURLA
,
651 IDirectPlay8AddressImpl_GetSP
,
652 IDirectPlay8AddressImpl_GetUserData
,
653 IDirectPlay8AddressImpl_SetSP
,
654 IDirectPlay8AddressImpl_SetUserData
,
655 IDirectPlay8AddressImpl_GetNumComponents
,
656 IDirectPlay8AddressImpl_GetComponentByName
,
657 IDirectPlay8AddressImpl_GetComponentByIndex
,
658 IDirectPlay8AddressImpl_AddComponent
,
659 IDirectPlay8AddressImpl_GetDevice
,
660 IDirectPlay8AddressImpl_SetDevice
,
661 IDirectPlay8AddressImpl_BuildFromDirectPlay4Address
664 HRESULT
DPNET_CreateDirectPlay8Address(IClassFactory
*iface
, IUnknown
*pUnkOuter
, REFIID riid
, LPVOID
*ppobj
)
666 IDirectPlay8AddressImpl
* client
;
669 TRACE("(%p, %s, %p)\n", pUnkOuter
, debugstr_guid(riid
), ppobj
);
673 client
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectPlay8AddressImpl
));
675 return E_OUTOFMEMORY
;
677 client
->IDirectPlay8Address_iface
.lpVtbl
= &DirectPlay8Address_Vtbl
;
679 client
->comp_array_size
= 4;
680 client
->components
= heap_alloc( sizeof(*client
->components
) * client
->comp_array_size
);
681 if(!client
->components
)
684 return E_OUTOFMEMORY
;
687 ret
= IDirectPlay8AddressImpl_QueryInterface(&client
->IDirectPlay8Address_iface
, riid
, ppobj
);
688 IDirectPlay8AddressImpl_Release(&client
->IDirectPlay8Address_iface
);