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"
36 #include "dpnet_private.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(dpnet
);
41 static char *heap_strdupA( const char *str
)
45 if (!str
) return NULL
;
46 if ((ret
= HeapAlloc( GetProcessHeap(), 0, strlen(str
) + 1 ))) strcpy( ret
, str
);
50 static BOOL
add_component(IDirectPlay8AddressImpl
*This
, struct component
*item
)
52 if(This
->comp_count
== This
->comp_array_size
)
54 struct component
**temp
;
56 temp
= heap_realloc(This
->components
, sizeof(*temp
) * This
->comp_array_size
* 2 );
62 This
->comp_array_size
*= 2;
63 This
->components
= temp
;
66 This
->components
[This
->comp_count
] = item
;
72 static inline IDirectPlay8AddressImpl
*impl_from_IDirectPlay8Address(IDirectPlay8Address
*iface
)
74 return CONTAINING_RECORD(iface
, IDirectPlay8AddressImpl
, IDirectPlay8Address_iface
);
77 /* IDirectPlay8Address IUnknown parts follow: */
78 static HRESULT WINAPI
IDirectPlay8AddressImpl_QueryInterface(IDirectPlay8Address
*iface
,
79 REFIID riid
, void **ppv
)
81 if (IsEqualGUID(riid
, &IID_IUnknown
) || IsEqualGUID(riid
, &IID_IDirectPlay8Address
)) {
82 IUnknown_AddRef(iface
);
87 WARN("(%p)->(%s,%p),not found\n", iface
, debugstr_guid(riid
), ppv
);
91 static ULONG WINAPI
IDirectPlay8AddressImpl_AddRef(IDirectPlay8Address
*iface
)
93 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
94 ULONG ref
= InterlockedIncrement(&This
->ref
);
96 TRACE("(%p) ref=%u\n", This
, ref
);
101 static ULONG WINAPI
IDirectPlay8AddressImpl_Release(IDirectPlay8Address
*iface
)
103 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
104 ULONG ref
= InterlockedDecrement(&This
->ref
);
106 TRACE("(%p) ref=%u\n", This
, ref
);
110 struct component
*entry
;
113 for(i
=0; i
< This
->comp_count
; i
++)
115 entry
= This
->components
[i
];
119 case DPNA_DATATYPE_STRING
:
120 heap_free(entry
->data
.string
);
122 case DPNA_DATATYPE_STRING_ANSI
:
123 heap_free(entry
->data
.ansi
);
125 case DPNA_DATATYPE_BINARY
:
126 heap_free(entry
->data
.binary
);
130 heap_free(entry
->name
);
134 heap_free(This
->components
);
140 /* returns name of given GUID */
141 static const char *debugstr_SP(const GUID
*id
) {
142 static const guid_info guids
[] = {
145 GE(CLSID_DP8SP_TCPIP
),
146 GE(CLSID_DP8SP_SERIAL
),
147 GE(CLSID_DP8SP_MODEM
)
151 if (!id
) return "(null)";
153 for (i
= 0; i
< sizeof(guids
)/sizeof(guids
[0]); i
++) {
154 if (IsEqualGUID(id
, guids
[i
].guid
))
155 return guids
[i
].name
;
157 /* if we didn't find it, act like standard debugstr_guid */
158 return debugstr_guid(id
);
161 /* IDirectPlay8Address Interface follow: */
163 static HRESULT WINAPI
IDirectPlay8AddressImpl_BuildFromURLW(IDirectPlay8Address
*iface
,
164 WCHAR
*pwszSourceURL
)
166 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
167 TRACE("(%p, %s): stub\n", This
, debugstr_w(pwszSourceURL
));
171 static HRESULT WINAPI
IDirectPlay8AddressImpl_BuildFromURLA(IDirectPlay8Address
*iface
,
174 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
175 TRACE("(%p, %s): stub\n", This
, pszSourceURL
);
179 static HRESULT WINAPI
IDirectPlay8AddressImpl_Duplicate(IDirectPlay8Address
*iface
,
180 IDirectPlay8Address
**ppdpaNewAddress
)
182 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
183 IDirectPlay8Address
*dup
;
186 TRACE("(%p, %p)\n", This
, ppdpaNewAddress
);
191 hr
= DPNET_CreateDirectPlay8Address(NULL
, NULL
, &IID_IDirectPlay8Address
, (LPVOID
*)&dup
);
194 IDirectPlay8AddressImpl
*DupThis
= impl_from_IDirectPlay8Address(dup
);
197 DupThis
->SP_guid
= This
->SP_guid
;
198 DupThis
->init
= This
->init
;
200 for(i
=0; i
< This
->comp_count
; i
++)
202 struct component
*entry
= This
->components
[i
];
206 case DPNA_DATATYPE_DWORD
:
207 hr
= IDirectPlay8Address_AddComponent(dup
, entry
->name
, &entry
->data
.value
, entry
->size
, entry
->type
);
209 case DPNA_DATATYPE_GUID
:
210 hr
= IDirectPlay8Address_AddComponent(dup
, entry
->name
, &entry
->data
.guid
, entry
->size
, entry
->type
);
212 case DPNA_DATATYPE_STRING
:
213 hr
= IDirectPlay8Address_AddComponent(dup
, entry
->name
, entry
->data
.string
, entry
->size
, entry
->type
);
215 case DPNA_DATATYPE_STRING_ANSI
:
216 hr
= IDirectPlay8Address_AddComponent(dup
, entry
->name
, entry
->data
.ansi
, entry
->size
, entry
->type
);
218 case DPNA_DATATYPE_BINARY
:
219 hr
= IDirectPlay8Address_AddComponent(dup
, entry
->name
, entry
->data
.binary
, entry
->size
, entry
->type
);
225 IDirectPlay8Address_Release(dup
);
227 ERR("Failed to copy component: %s - 0x%08x\n", debugstr_w(entry
->name
), hr
);
232 *ppdpaNewAddress
= dup
;
238 static HRESULT WINAPI
IDirectPlay8AddressImpl_SetEqual(IDirectPlay8Address
*iface
,
239 IDirectPlay8Address
*pdpaAddress
)
241 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
242 TRACE("(%p, %p): stub\n", This
, pdpaAddress
);
246 static HRESULT WINAPI
IDirectPlay8AddressImpl_IsEqual(IDirectPlay8Address
*iface
,
247 IDirectPlay8Address
*pdpaAddress
)
249 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
250 TRACE("(%p, %p): stub\n", This
, pdpaAddress
);
254 static HRESULT WINAPI
IDirectPlay8AddressImpl_Clear(IDirectPlay8Address
*iface
)
256 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
257 TRACE("(%p): stub\n", This
);
261 static HRESULT WINAPI
IDirectPlay8AddressImpl_GetURLW(IDirectPlay8Address
*iface
, WCHAR
*pwszURL
,
264 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
265 TRACE("(%p): stub\n", This
);
269 static HRESULT WINAPI
IDirectPlay8AddressImpl_GetURLA(IDirectPlay8Address
*iface
, CHAR
*pszURL
,
272 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
273 TRACE("(%p): stub\n", This
);
277 static HRESULT WINAPI
IDirectPlay8AddressImpl_GetSP(IDirectPlay8Address
*iface
, GUID
*pguidSP
)
279 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
281 TRACE("(%p, %p)\n", iface
, pguidSP
);
284 return DPNERR_INVALIDPOINTER
;
287 return DPNERR_DOESNOTEXIST
;
289 *pguidSP
= This
->SP_guid
;
293 static HRESULT WINAPI
IDirectPlay8AddressImpl_GetUserData(IDirectPlay8Address
*iface
,
294 void *pvUserData
, DWORD
*pdwBufferSize
)
296 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
297 TRACE("(%p): stub\n", This
);
301 static HRESULT WINAPI
IDirectPlay8AddressImpl_SetSP(IDirectPlay8Address
*iface
,
302 const GUID
*const pguidSP
)
304 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
306 TRACE("(%p, %s)\n", iface
, debugstr_SP(pguidSP
));
309 return DPNERR_INVALIDPOINTER
;
312 This
->SP_guid
= *pguidSP
;
314 IDirectPlay8Address_AddComponent(iface
, DPNA_KEY_PROVIDER
, &This
->SP_guid
, sizeof(GUID
), DPNA_DATATYPE_GUID
);
319 static HRESULT WINAPI
IDirectPlay8AddressImpl_SetUserData(IDirectPlay8Address
*iface
,
320 const void *const pvUserData
, const DWORD dwDataSize
)
322 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
323 TRACE("(%p): stub\n", This
);
327 static HRESULT WINAPI
IDirectPlay8AddressImpl_GetNumComponents(IDirectPlay8Address
*iface
,
328 DWORD
*pdwNumComponents
)
330 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
331 TRACE("(%p): stub\n", This
);
333 if(!pdwNumComponents
)
334 return DPNERR_INVALIDPOINTER
;
336 *pdwNumComponents
= This
->comp_count
;
341 static HRESULT WINAPI
IDirectPlay8AddressImpl_GetComponentByName(IDirectPlay8Address
*iface
,
342 const WCHAR
*const pwszName
, void *pvBuffer
, DWORD
*pdwBufferSize
, DWORD
*pdwDataType
)
344 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
345 struct component
*entry
;
348 TRACE("(%p)->(%s %p %p %p)\n", This
, debugstr_w(pwszName
), pvBuffer
, pdwBufferSize
, pdwDataType
);
350 if(!pwszName
|| !pdwBufferSize
|| !pdwDataType
|| (!pvBuffer
&& *pdwBufferSize
))
353 for(i
=0; i
< This
->comp_count
; i
++)
355 entry
= This
->components
[i
];
357 if (lstrcmpW(pwszName
, entry
->name
) == 0)
359 TRACE("Found %s\n", debugstr_w(pwszName
));
361 if(*pdwBufferSize
< entry
->size
)
363 *pdwBufferSize
= entry
->size
;
364 return DPNERR_BUFFERTOOSMALL
;
367 *pdwBufferSize
= entry
->size
;
368 *pdwDataType
= entry
->type
;
372 case DPNA_DATATYPE_DWORD
:
373 memcpy(pvBuffer
, &entry
->data
.value
, sizeof(DWORD
));
375 case DPNA_DATATYPE_GUID
:
376 memcpy(pvBuffer
, &entry
->data
.guid
, sizeof(GUID
));
378 case DPNA_DATATYPE_STRING
:
379 memcpy(pvBuffer
, entry
->data
.string
, entry
->size
);
381 case DPNA_DATATYPE_STRING_ANSI
:
382 memcpy(pvBuffer
, entry
->data
.ansi
, entry
->size
);
384 case DPNA_DATATYPE_BINARY
:
385 memcpy(pvBuffer
, entry
->data
.binary
, entry
->size
);
393 return DPNERR_DOESNOTEXIST
;
396 static HRESULT WINAPI
IDirectPlay8AddressImpl_GetComponentByIndex(IDirectPlay8Address
*iface
,
397 const DWORD dwComponentID
, WCHAR
*pwszName
, DWORD
*pdwNameLen
, void *pvBuffer
,
398 DWORD
*pdwBufferSize
, DWORD
*pdwDataType
)
400 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
401 struct component
*entry
;
404 TRACE("(%p)->(%u %p %p %p %p %p)\n", This
, dwComponentID
, pwszName
, pdwNameLen
, pvBuffer
, pdwBufferSize
, pdwDataType
);
406 if(!pdwNameLen
|| !pdwBufferSize
|| !pdwDataType
)
408 WARN("Invalid buffer (%p, %p, %p)\n", pdwNameLen
, pdwBufferSize
, pdwDataType
);
409 return DPNERR_INVALIDPOINTER
;
412 if(dwComponentID
> This
->comp_count
)
414 WARN("dwComponentID out of range\n");
415 return DPNERR_DOESNOTEXIST
;
418 entry
= This
->components
[dwComponentID
];
420 namesize
= strlenW(entry
->name
);
421 if(*pdwBufferSize
< entry
->size
|| *pdwNameLen
< namesize
)
423 WARN("Buffer too small\n");
425 *pdwNameLen
= namesize
+ 1;
426 *pdwBufferSize
= entry
->size
;
427 *pdwDataType
= entry
->type
;
428 return DPNERR_BUFFERTOOSMALL
;
431 if(!pwszName
|| !pvBuffer
)
433 WARN("Invalid buffer (%p, %p)\n", pwszName
, pvBuffer
);
434 return DPNERR_INVALIDPOINTER
;
437 lstrcpyW(pwszName
, entry
->name
);
439 *pdwNameLen
= namesize
+ 1;
440 *pdwBufferSize
= entry
->size
;
441 *pdwDataType
= entry
->type
;
445 case DPNA_DATATYPE_DWORD
:
446 *(DWORD
*)pvBuffer
= entry
->data
.value
;
448 case DPNA_DATATYPE_GUID
:
449 *(GUID
*)pvBuffer
= entry
->data
.guid
;
451 case DPNA_DATATYPE_STRING
:
452 memcpy(pvBuffer
, entry
->data
.string
, entry
->size
);
454 case DPNA_DATATYPE_STRING_ANSI
:
455 memcpy(pvBuffer
, entry
->data
.ansi
, entry
->size
);
457 case DPNA_DATATYPE_BINARY
:
458 memcpy(pvBuffer
, entry
->data
.binary
, entry
->size
);
465 static HRESULT WINAPI
IDirectPlay8AddressImpl_AddComponent(IDirectPlay8Address
*iface
,
466 const WCHAR
*const pwszName
, const void* const lpvData
, const DWORD dwDataSize
,
467 const DWORD dwDataType
)
469 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
470 struct component
*entry
;
474 TRACE("(%p, %s, %p, %u, %x)\n", This
, debugstr_w(pwszName
), lpvData
, dwDataSize
, dwDataType
);
477 return DPNERR_INVALIDPOINTER
;
481 case DPNA_DATATYPE_DWORD
:
482 if (sizeof(DWORD
) != dwDataSize
)
484 WARN("Invalid DWORD size, returning DPNERR_INVALIDPARAM\n");
485 return DPNERR_INVALIDPARAM
;
488 case DPNA_DATATYPE_GUID
:
489 if (sizeof(GUID
) != dwDataSize
)
491 WARN("Invalid GUID size, returning DPNERR_INVALIDPARAM\n");
492 return DPNERR_INVALIDPARAM
;
495 case DPNA_DATATYPE_STRING
:
496 if (((strlenW((WCHAR
*)lpvData
)+1)*sizeof(WCHAR
)) != dwDataSize
)
498 WARN("Invalid STRING size, returning DPNERR_INVALIDPARAM\n");
499 return DPNERR_INVALIDPARAM
;
502 case DPNA_DATATYPE_STRING_ANSI
:
503 if ((strlen((const CHAR
*)lpvData
)+1) != dwDataSize
)
505 WARN("Invalid ASCII size, returning DPNERR_INVALIDPARAM\n");
506 return DPNERR_INVALIDPARAM
;
511 for(i
=0; i
< This
->comp_count
; i
++)
513 entry
= This
->components
[i
];
515 if (lstrcmpW(pwszName
, entry
->name
) == 0)
517 TRACE("Found %s\n", debugstr_w(pwszName
));
520 if(entry
->type
== DPNA_DATATYPE_STRING_ANSI
)
521 heap_free(entry
->data
.ansi
);
522 else if(entry
->type
== DPNA_DATATYPE_STRING
)
523 heap_free(entry
->data
.string
);
524 else if(entry
->type
== DPNA_DATATYPE_BINARY
)
525 heap_free(entry
->data
.binary
);
533 /* Create a new one */
534 entry
= heap_alloc(sizeof(struct component
));
536 return E_OUTOFMEMORY
;
538 entry
->name
= heap_strdupW(pwszName
);
542 return E_OUTOFMEMORY
;
545 if(!add_component(This
, entry
))
547 heap_free(entry
->name
);
549 return E_OUTOFMEMORY
;
555 case DPNA_DATATYPE_DWORD
:
556 entry
->data
.value
= *(DWORD
*)lpvData
;
557 TRACE("(%p, %u): DWORD Type -> %u\n", lpvData
, dwDataSize
, *(const DWORD
*) lpvData
);
559 case DPNA_DATATYPE_GUID
:
560 entry
->data
.guid
= *(GUID
*)lpvData
;
561 TRACE("(%p, %u): GUID Type -> %s\n", lpvData
, dwDataSize
, debugstr_guid(lpvData
));
563 case DPNA_DATATYPE_STRING
:
564 entry
->data
.string
= heap_strdupW((WCHAR
*)lpvData
);
565 TRACE("(%p, %u): STRING Type -> %s\n", lpvData
, dwDataSize
, debugstr_w((WCHAR
*)lpvData
));
567 case DPNA_DATATYPE_STRING_ANSI
:
568 entry
->data
.ansi
= heap_strdupA((CHAR
*)lpvData
);
569 TRACE("(%p, %u): ANSI STRING Type -> %s\n", lpvData
, dwDataSize
, (const CHAR
*) lpvData
);
571 case DPNA_DATATYPE_BINARY
:
572 entry
->data
.binary
= heap_alloc(dwDataSize
);
573 memcpy(entry
->data
.binary
, lpvData
, dwDataSize
);
574 TRACE("(%p, %u): BINARY Type\n", lpvData
, dwDataSize
);
578 entry
->type
= dwDataType
;
579 entry
->size
= dwDataSize
;
584 static HRESULT WINAPI
IDirectPlay8AddressImpl_GetDevice(IDirectPlay8Address
*iface
, GUID
*pDevGuid
) {
585 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
586 TRACE("(%p): stub\n", This
);
590 static HRESULT WINAPI
IDirectPlay8AddressImpl_SetDevice(IDirectPlay8Address
*iface
,
591 const GUID
*const devGuid
)
593 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
594 TRACE("(%p, %s): stub\n", This
, debugstr_guid(devGuid
));
598 static HRESULT WINAPI
IDirectPlay8AddressImpl_BuildFromDirectPlay4Address(IDirectPlay8Address
*iface
,
599 void *pvAddress
, DWORD dwDataSize
)
601 IDirectPlay8AddressImpl
*This
= impl_from_IDirectPlay8Address(iface
);
602 TRACE("(%p): stub\n", This
);
606 static const IDirectPlay8AddressVtbl DirectPlay8Address_Vtbl
=
608 IDirectPlay8AddressImpl_QueryInterface
,
609 IDirectPlay8AddressImpl_AddRef
,
610 IDirectPlay8AddressImpl_Release
,
611 IDirectPlay8AddressImpl_BuildFromURLW
,
612 IDirectPlay8AddressImpl_BuildFromURLA
,
613 IDirectPlay8AddressImpl_Duplicate
,
614 IDirectPlay8AddressImpl_SetEqual
,
615 IDirectPlay8AddressImpl_IsEqual
,
616 IDirectPlay8AddressImpl_Clear
,
617 IDirectPlay8AddressImpl_GetURLW
,
618 IDirectPlay8AddressImpl_GetURLA
,
619 IDirectPlay8AddressImpl_GetSP
,
620 IDirectPlay8AddressImpl_GetUserData
,
621 IDirectPlay8AddressImpl_SetSP
,
622 IDirectPlay8AddressImpl_SetUserData
,
623 IDirectPlay8AddressImpl_GetNumComponents
,
624 IDirectPlay8AddressImpl_GetComponentByName
,
625 IDirectPlay8AddressImpl_GetComponentByIndex
,
626 IDirectPlay8AddressImpl_AddComponent
,
627 IDirectPlay8AddressImpl_GetDevice
,
628 IDirectPlay8AddressImpl_SetDevice
,
629 IDirectPlay8AddressImpl_BuildFromDirectPlay4Address
632 HRESULT
DPNET_CreateDirectPlay8Address(IClassFactory
*iface
, IUnknown
*pUnkOuter
, REFIID riid
, LPVOID
*ppobj
)
634 IDirectPlay8AddressImpl
* client
;
637 TRACE("(%p, %s, %p)\n", pUnkOuter
, debugstr_guid(riid
), ppobj
);
641 client
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectPlay8AddressImpl
));
643 return E_OUTOFMEMORY
;
645 client
->IDirectPlay8Address_iface
.lpVtbl
= &DirectPlay8Address_Vtbl
;
647 client
->comp_array_size
= 4;
648 client
->components
= heap_alloc( sizeof(*client
->components
) * client
->comp_array_size
);
649 if(!client
->components
)
652 return E_OUTOFMEMORY
;
655 ret
= IDirectPlay8AddressImpl_QueryInterface(&client
->IDirectPlay8Address_iface
, riid
, ppobj
);
656 IDirectPlay8AddressImpl_Release(&client
->IDirectPlay8Address_iface
);