1 /* Direct Play Lobby 2 & 3 Implementation 2 * 3 * Copyright 1998,1999,2000 - Peter Hunnisett 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 18 */ 19 20 #include "dplayx_global.h" 21 22 /* Forward declarations for this module helper methods */ 23 HRESULT DPL_CreateCompoundAddress ( LPCDPCOMPOUNDADDRESSELEMENT lpElements, DWORD dwElementCount, 24 LPVOID lpAddress, LPDWORD lpdwAddressSize, BOOL bAnsiInterface )DECLSPEC_HIDDEN; 25 26 static HRESULT DPL_CreateAddress( REFGUID guidSP, REFGUID guidDataType, LPCVOID lpData, DWORD dwDataSize, 27 LPVOID lpAddress, LPDWORD lpdwAddressSize, BOOL bAnsiInterface ); 28 29 30 /***************************************************************************** 31 * IDirectPlayLobby {1,2,3} implementation structure 32 * 33 * The philosophy behind this extra pointer dereference is that I wanted to 34 * have the same structure for all types of objects without having to do 35 * a lot of casting. I also only wanted to implement an interface in the 36 * object it was "released" with IUnknown interface being implemented in the 1 version. 37 * Of course, with these new interfaces comes the data required to keep the state required 38 * by these interfaces. So, basically, the pointers contain the data associated with 39 * a release. If you use the data associated with release 3 in a release 2 object, you'll 40 * get a run time trap, as that won't have any data. 41 * 42 */ 43 struct DPLMSG 44 { 45 DPQ_ENTRY( DPLMSG ) msgs; /* Link to next queued message */ 46 }; 47 typedef struct DPLMSG* LPDPLMSG; 48 49 typedef struct IDirectPlayLobbyImpl 50 { 51 IDirectPlayLobby IDirectPlayLobby_iface; 52 IDirectPlayLobbyA IDirectPlayLobbyA_iface; 53 IDirectPlayLobby2 IDirectPlayLobby2_iface; 54 IDirectPlayLobby2A IDirectPlayLobby2A_iface; 55 IDirectPlayLobby3 IDirectPlayLobby3_iface; 56 IDirectPlayLobby3A IDirectPlayLobby3A_iface; 57 LONG numIfaces; /* "in use interfaces" refcount */ 58 LONG ref, refA, ref2, ref2A, ref3, ref3A; 59 CRITICAL_SECTION lock; 60 HKEY cbkeyhack; 61 DWORD msgtid; 62 DPQ_HEAD( DPLMSG ) msgs; /* List of messages received */ 63 } IDirectPlayLobbyImpl; 64 65 static inline IDirectPlayLobbyImpl *impl_from_IDirectPlayLobby( IDirectPlayLobby *iface ) 66 { 67 return CONTAINING_RECORD( iface, IDirectPlayLobbyImpl, IDirectPlayLobby_iface ); 68 } 69 70 static inline IDirectPlayLobbyImpl *impl_from_IDirectPlayLobbyA( IDirectPlayLobbyA *iface ) 71 { 72 return CONTAINING_RECORD( iface, IDirectPlayLobbyImpl, IDirectPlayLobbyA_iface ); 73 } 74 75 static inline IDirectPlayLobbyImpl *impl_from_IDirectPlayLobby2( IDirectPlayLobby2 *iface ) 76 { 77 return CONTAINING_RECORD( iface, IDirectPlayLobbyImpl, IDirectPlayLobby2_iface ); 78 } 79 80 static inline IDirectPlayLobbyImpl *impl_from_IDirectPlayLobby2A( IDirectPlayLobby2A *iface ) 81 { 82 return CONTAINING_RECORD( iface, IDirectPlayLobbyImpl, IDirectPlayLobby2A_iface ); 83 } 84 85 static inline IDirectPlayLobbyImpl *impl_from_IDirectPlayLobby3( IDirectPlayLobby3 *iface ) 86 { 87 return CONTAINING_RECORD( iface, IDirectPlayLobbyImpl, IDirectPlayLobby3_iface ); 88 } 89 90 static inline IDirectPlayLobbyImpl *impl_from_IDirectPlayLobby3A( IDirectPlayLobby3A *iface ) 91 { 92 return CONTAINING_RECORD( iface, IDirectPlayLobbyImpl, IDirectPlayLobby3A_iface ); 93 } 94 95 static void dplobby_destroy(IDirectPlayLobbyImpl *obj) 96 { 97 if ( obj->msgtid ) 98 FIXME( "Should kill the msg thread\n" ); 99 100 DPQ_DELETEQ( obj->msgs, msgs, LPDPLMSG, cbDeleteElemFromHeap ); 101 obj->lock.DebugInfo->Spare[0] = 0; 102 DeleteCriticalSection( &obj->lock ); 103 HeapFree( GetProcessHeap(), 0, obj ); 104 } 105 106 static HRESULT WINAPI IDirectPlayLobbyAImpl_QueryInterface( IDirectPlayLobbyA *iface, REFIID riid, 107 void **ppv ) 108 { 109 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface ); 110 return IDirectPlayLobby_QueryInterface( &This->IDirectPlayLobby3_iface, riid, ppv ); 111 } 112 113 static HRESULT WINAPI IDirectPlayLobbyImpl_QueryInterface( IDirectPlayLobby *iface, REFIID riid, 114 void **ppv ) 115 { 116 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface ); 117 return IDirectPlayLobby_QueryInterface( &This->IDirectPlayLobby3_iface, riid, ppv ); 118 } 119 120 static HRESULT WINAPI IDirectPlayLobby2AImpl_QueryInterface( IDirectPlayLobby2A *iface, REFIID riid, 121 void **ppv ) 122 { 123 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface ); 124 return IDirectPlayLobby_QueryInterface( &This->IDirectPlayLobby3_iface, riid, ppv ); 125 } 126 127 static HRESULT WINAPI IDirectPlayLobby2Impl_QueryInterface( IDirectPlayLobby2 *iface, REFIID riid, 128 void **ppv ) 129 { 130 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface ); 131 return IDirectPlayLobby_QueryInterface( &This->IDirectPlayLobby3_iface, riid, ppv ); 132 } 133 134 static HRESULT WINAPI IDirectPlayLobby3AImpl_QueryInterface( IDirectPlayLobby3A *iface, REFIID riid, 135 void **ppv ) 136 { 137 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3A( iface ); 138 return IDirectPlayLobby_QueryInterface( &This->IDirectPlayLobby3_iface, riid, ppv ); 139 } 140 141 static HRESULT WINAPI IDirectPlayLobby3Impl_QueryInterface( IDirectPlayLobby3 *iface, REFIID riid, 142 void **ppv ) 143 { 144 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3( iface ); 145 146 if ( IsEqualGUID( &IID_IUnknown, riid ) ) 147 { 148 TRACE( "(%p)->(IID_IUnknown %p)\n", This, ppv ); 149 *ppv = &This->IDirectPlayLobby_iface; 150 } 151 else if ( IsEqualGUID( &IID_IDirectPlayLobby, riid ) ) 152 { 153 TRACE( "(%p)->(IID_IDirectPlayLobby %p)\n", This, ppv ); 154 *ppv = &This->IDirectPlayLobby_iface; 155 } 156 else if ( IsEqualGUID( &IID_IDirectPlayLobbyA, riid ) ) 157 { 158 TRACE( "(%p)->(IID_IDirectPlayLobbyA %p)\n", This, ppv ); 159 *ppv = &This->IDirectPlayLobbyA_iface; 160 } 161 else if ( IsEqualGUID( &IID_IDirectPlayLobby2, riid ) ) 162 { 163 TRACE( "(%p)->(IID_IDirectPlayLobby2 %p)\n", This, ppv ); 164 *ppv = &This->IDirectPlayLobby2_iface; 165 } 166 else if ( IsEqualGUID( &IID_IDirectPlayLobby2A, riid ) ) 167 { 168 TRACE( "(%p)->(IID_IDirectPlayLobby2A %p)\n", This, ppv ); 169 *ppv = &This->IDirectPlayLobby2A_iface; 170 } 171 else if ( IsEqualGUID( &IID_IDirectPlayLobby3, riid ) ) 172 { 173 TRACE( "(%p)->(IID_IDirectPlay3 %p)\n", This, ppv ); 174 *ppv = &This->IDirectPlayLobby3_iface; 175 } 176 else if ( IsEqualGUID( &IID_IDirectPlayLobby3A, riid ) ) 177 { 178 TRACE( "(%p)->(IID_IDirectPlayLobby3A %p)\n", This, ppv ); 179 *ppv = &This->IDirectPlayLobby3A_iface; 180 } 181 else 182 { 183 WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); 184 *ppv = NULL; 185 return E_NOINTERFACE; 186 } 187 188 IUnknown_AddRef((IUnknown*)*ppv); 189 return S_OK; 190 } 191 192 static ULONG WINAPI IDirectPlayLobbyAImpl_AddRef( IDirectPlayLobbyA *iface ) 193 { 194 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface ); 195 ULONG ref = InterlockedIncrement( &This->refA ); 196 197 TRACE( "(%p) refA=%d\n", This, ref ); 198 199 if ( ref == 1 ) 200 InterlockedIncrement( &This->numIfaces ); 201 202 return ref; 203 } 204 205 static ULONG WINAPI IDirectPlayLobbyImpl_AddRef( IDirectPlayLobby *iface ) 206 { 207 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface ); 208 ULONG ref = InterlockedIncrement( &This->ref ); 209 210 TRACE( "(%p) ref=%d\n", This, ref ); 211 212 if ( ref == 1 ) 213 InterlockedIncrement( &This->numIfaces ); 214 215 return ref; 216 } 217 218 static ULONG WINAPI IDirectPlayLobby2AImpl_AddRef(IDirectPlayLobby2A *iface) 219 { 220 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface ); 221 ULONG ref = InterlockedIncrement( &This->ref2A ); 222 223 TRACE( "(%p) ref2A=%d\n", This, ref ); 224 225 if ( ref == 1 ) 226 InterlockedIncrement( &This->numIfaces ); 227 228 return ref; 229 } 230 231 static ULONG WINAPI IDirectPlayLobby2Impl_AddRef(IDirectPlayLobby2 *iface) 232 { 233 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface ); 234 ULONG ref = InterlockedIncrement( &This->ref2 ); 235 236 TRACE( "(%p) ref2=%d\n", This, ref ); 237 238 if ( ref == 1 ) 239 InterlockedIncrement( &This->numIfaces ); 240 241 return ref; 242 } 243 244 static ULONG WINAPI IDirectPlayLobby3AImpl_AddRef(IDirectPlayLobby3A *iface) 245 { 246 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3A( iface ); 247 ULONG ref = InterlockedIncrement( &This->ref3A ); 248 249 TRACE( "(%p) ref3A=%d\n", This, ref ); 250 251 if ( ref == 1 ) 252 InterlockedIncrement( &This->numIfaces ); 253 254 return ref; 255 } 256 257 static ULONG WINAPI IDirectPlayLobby3Impl_AddRef(IDirectPlayLobby3 *iface) 258 { 259 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3( iface ); 260 ULONG ref = InterlockedIncrement( &This->ref3 ); 261 262 TRACE( "(%p) ref3=%d\n", This, ref ); 263 264 if ( ref == 1 ) 265 InterlockedIncrement( &This->numIfaces ); 266 267 return ref; 268 } 269 270 static ULONG WINAPI IDirectPlayLobbyAImpl_Release( IDirectPlayLobbyA *iface ) 271 { 272 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface ); 273 ULONG ref = InterlockedDecrement( &This->refA ); 274 275 TRACE( "(%p) refA=%d\n", This, ref ); 276 277 if ( !ref && !InterlockedDecrement( &This->numIfaces ) ) 278 dplobby_destroy( This ); 279 280 return ref; 281 } 282 283 static ULONG WINAPI IDirectPlayLobbyImpl_Release( IDirectPlayLobby *iface ) 284 { 285 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface ); 286 ULONG ref = InterlockedDecrement( &This->ref ); 287 288 TRACE( "(%p) ref=%d\n", This, ref ); 289 290 if ( !ref && !InterlockedDecrement( &This->numIfaces ) ) 291 dplobby_destroy( This ); 292 293 return ref; 294 } 295 296 static ULONG WINAPI IDirectPlayLobby2AImpl_Release(IDirectPlayLobby2A *iface) 297 { 298 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface ); 299 ULONG ref = InterlockedDecrement( &This->ref2A ); 300 301 TRACE( "(%p) ref2A=%d\n", This, ref ); 302 303 if ( !ref && !InterlockedDecrement( &This->numIfaces ) ) 304 dplobby_destroy( This ); 305 306 return ref; 307 } 308 309 static ULONG WINAPI IDirectPlayLobby2Impl_Release(IDirectPlayLobby2 *iface) 310 { 311 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface ); 312 ULONG ref = InterlockedDecrement( &This->ref2 ); 313 314 TRACE( "(%p) ref2=%d\n", This, ref ); 315 316 if ( !ref && !InterlockedDecrement( &This->numIfaces ) ) 317 dplobby_destroy( This ); 318 319 return ref; 320 } 321 322 static ULONG WINAPI IDirectPlayLobby3AImpl_Release(IDirectPlayLobby3A *iface) 323 { 324 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3A( iface ); 325 ULONG ref = InterlockedDecrement( &This->ref3A ); 326 327 TRACE( "(%p) ref3A=%d\n", This, ref ); 328 329 if ( !ref && !InterlockedDecrement( &This->numIfaces ) ) 330 dplobby_destroy( This ); 331 332 return ref; 333 } 334 335 static ULONG WINAPI IDirectPlayLobby3Impl_Release(IDirectPlayLobby3 *iface) 336 { 337 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3( iface ); 338 ULONG ref = InterlockedDecrement( &This->ref3 ); 339 340 TRACE( "(%p) ref3=%d\n", This, ref ); 341 342 if ( !ref && !InterlockedDecrement( &This->numIfaces ) ) 343 dplobby_destroy( This ); 344 345 return ref; 346 } 347 348 349 /******************************************************************** 350 * 351 * Connects an application to the session specified by the DPLCONNECTION 352 * structure currently stored with the DirectPlayLobby object. 353 * 354 * Returns an IDirectPlay interface. 355 * 356 */ 357 static HRESULT DPL_ConnectEx( IDirectPlayLobbyImpl *This, DWORD dwFlags, REFIID riid, void **lplpDP, 358 IUnknown* pUnk) 359 { 360 HRESULT hr; 361 DWORD dwOpenFlags = 0; 362 DWORD dwConnSize = 0; 363 LPDPLCONNECTION lpConn; 364 365 FIXME("(%p)->(0x%08x,%p,%p): semi stub\n", This, dwFlags, lplpDP, pUnk ); 366 367 if( pUnk ) 368 { 369 return DPERR_INVALIDPARAMS; 370 } 371 372 /* Backwards compatibility */ 373 if( dwFlags == 0 ) 374 { 375 dwFlags = DPCONNECT_RETURNSTATUS; 376 } 377 378 if ( ( hr = dplay_create( riid, lplpDP ) ) != DP_OK ) 379 { 380 ERR( "error creating interface for %s:%s.\n", 381 debugstr_guid( riid ), DPLAYX_HresultToString( hr ) ); 382 return hr; 383 } 384 385 /* FIXME: Is it safe/correct to use appID of 0? */ 386 hr = IDirectPlayLobby_GetConnectionSettings( &This->IDirectPlayLobby3_iface, 387 0, NULL, &dwConnSize ); 388 if( hr != DPERR_BUFFERTOOSMALL ) 389 { 390 return hr; 391 } 392 393 lpConn = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwConnSize ); 394 395 if( lpConn == NULL ) 396 { 397 return DPERR_NOMEMORY; 398 } 399 400 /* FIXME: Is it safe/correct to use appID of 0? */ 401 hr = IDirectPlayLobby_GetConnectionSettings( &This->IDirectPlayLobby3_iface, 402 0, lpConn, &dwConnSize ); 403 if( FAILED( hr ) ) 404 { 405 HeapFree( GetProcessHeap(), 0, lpConn ); 406 return hr; 407 } 408 409 #if 0 410 /* - Need to call IDirectPlay::EnumConnections with the service provider to get that good information 411 * - Need to call CreateAddress to create the lpConnection param for IDirectPlay::InitializeConnection 412 * - Call IDirectPlay::InitializeConnection 413 */ 414 415 /* Now initialize the Service Provider */ 416 hr = IDirectPlayX_InitializeConnection( (*(LPDIRECTPLAY2*)lplpDP), 417 #endif 418 419 420 /* Setup flags to pass into DirectPlay::Open */ 421 if( dwFlags & DPCONNECT_RETURNSTATUS ) 422 { 423 dwOpenFlags |= DPOPEN_RETURNSTATUS; 424 } 425 dwOpenFlags |= lpConn->dwFlags; 426 427 hr = IDirectPlayX_Open( (*(LPDIRECTPLAY2*)lplpDP), lpConn->lpSessionDesc, 428 dwOpenFlags ); 429 430 HeapFree( GetProcessHeap(), 0, lpConn ); 431 432 return hr; 433 } 434 435 static HRESULT WINAPI IDirectPlayLobbyAImpl_Connect( IDirectPlayLobbyA *iface, DWORD flags, 436 IDirectPlay2A **dp, IUnknown *unk ) 437 { 438 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface ); 439 return IDirectPlayLobby_Connect( &This->IDirectPlayLobby3A_iface, flags, dp, unk ); 440 } 441 442 static HRESULT WINAPI IDirectPlayLobbyImpl_Connect( IDirectPlayLobby *iface, DWORD flags, 443 IDirectPlay2A **dp, IUnknown *unk ) 444 { 445 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface ); 446 return IDirectPlayLobby_Connect( &This->IDirectPlayLobby3_iface, flags, dp, unk ); 447 } 448 449 static HRESULT WINAPI IDirectPlayLobby2AImpl_Connect( IDirectPlayLobby2A *iface, DWORD flags, 450 IDirectPlay2A **dp, IUnknown *unk ) 451 { 452 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface ); 453 return IDirectPlayLobby_Connect( &This->IDirectPlayLobby3A_iface, flags, dp, unk ); 454 } 455 456 static HRESULT WINAPI IDirectPlayLobby2Impl_Connect( IDirectPlayLobby2 *iface, DWORD flags, 457 IDirectPlay2A **dp, IUnknown *unk ) 458 { 459 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface ); 460 return IDirectPlayLobby_Connect( &This->IDirectPlayLobby3_iface, flags, dp, unk ); 461 } 462 463 static HRESULT WINAPI IDirectPlayLobby3AImpl_Connect( IDirectPlayLobby3A *iface, DWORD flags, 464 IDirectPlay2A **dp, IUnknown *unk) 465 { 466 return IDirectPlayLobby_ConnectEx( iface, flags, &IID_IDirectPlay2A, (void**)dp, unk ); 467 } 468 469 static HRESULT WINAPI IDirectPlayLobby3Impl_Connect( IDirectPlayLobby3 *iface, DWORD flags, 470 IDirectPlay2 **dp, IUnknown *unk) 471 { 472 return IDirectPlayLobby_ConnectEx( iface, flags, &IID_IDirectPlay2A, (void**)dp, unk ); 473 } 474 475 /******************************************************************** 476 * 477 * Creates a DirectPlay Address, given a service provider-specific network 478 * address. 479 * Returns an address contains the globally unique identifier 480 * (GUID) of the service provider and data that the service provider can 481 * interpret as a network address. 482 * 483 * NOTE: It appears that this method is supposed to be really really stupid 484 * with no error checking on the contents. 485 */ 486 static HRESULT WINAPI IDirectPlayLobbyAImpl_CreateAddress( IDirectPlayLobbyA *iface, REFGUID sp, 487 REFGUID datatype, const void *data, DWORD datasize, void *address, DWORD *addrsize ) 488 { 489 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface ); 490 return IDirectPlayLobby_CreateAddress( &This->IDirectPlayLobby3A_iface, sp, datatype, data, 491 datasize, address, addrsize ); 492 } 493 494 static HRESULT WINAPI IDirectPlayLobbyImpl_CreateAddress( IDirectPlayLobby *iface, REFGUID sp, 495 REFGUID datatype, const void *data, DWORD datasize, void *address, DWORD *addrsize ) 496 { 497 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface ); 498 return IDirectPlayLobby_CreateAddress( &This->IDirectPlayLobby3_iface, sp, datatype, data, 499 datasize, address, addrsize ); 500 } 501 502 static HRESULT WINAPI IDirectPlayLobby2AImpl_CreateAddress( IDirectPlayLobby2A *iface, REFGUID sp, 503 REFGUID datatype, const void *data, DWORD datasize, void *address, DWORD *addrsize ) 504 { 505 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface ); 506 return IDirectPlayLobby_CreateAddress( &This->IDirectPlayLobby3A_iface, sp, datatype, data, 507 datasize, address, addrsize ); 508 } 509 510 static HRESULT WINAPI IDirectPlayLobby2Impl_CreateAddress( IDirectPlayLobby2 *iface, REFGUID sp, 511 REFGUID datatype, const void *data, DWORD datasize, void *address, DWORD *addrsize ) 512 { 513 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface ); 514 return IDirectPlayLobby_CreateAddress( &This->IDirectPlayLobby3_iface, sp, datatype, data, 515 datasize, address, addrsize ); 516 } 517 518 static HRESULT WINAPI IDirectPlayLobby3AImpl_CreateAddress( IDirectPlayLobby3A *iface, 519 REFGUID guidSP, REFGUID guidDataType, const void *lpData, DWORD dwDataSize, void *lpAddress, 520 DWORD *lpdwAddressSize ) 521 { 522 return DPL_CreateAddress( guidSP, guidDataType, lpData, dwDataSize, 523 lpAddress, lpdwAddressSize, TRUE ); 524 } 525 526 static HRESULT WINAPI IDirectPlayLobby3Impl_CreateAddress( IDirectPlayLobby3 *iface, REFGUID guidSP, 527 REFGUID guidDataType, const void *lpData, DWORD dwDataSize, void *lpAddress, 528 DWORD *lpdwAddressSize ) 529 { 530 return DPL_CreateAddress( guidSP, guidDataType, lpData, dwDataSize, 531 lpAddress, lpdwAddressSize, FALSE ); 532 } 533 534 static HRESULT DPL_CreateAddress( 535 REFGUID guidSP, 536 REFGUID guidDataType, 537 LPCVOID lpData, 538 DWORD dwDataSize, 539 LPVOID lpAddress, 540 LPDWORD lpdwAddressSize, 541 BOOL bAnsiInterface ) 542 { 543 const DWORD dwNumAddElements = 2; /* Service Provide & address data type */ 544 DPCOMPOUNDADDRESSELEMENT addressElements[ 2 /* dwNumAddElements */ ]; 545 546 TRACE( "(%p)->(%p,%p,0x%08x,%p,%p,%d)\n", guidSP, guidDataType, lpData, dwDataSize, 547 lpAddress, lpdwAddressSize, bAnsiInterface ); 548 549 addressElements[ 0 ].guidDataType = DPAID_ServiceProvider; 550 addressElements[ 0 ].dwDataSize = sizeof( GUID ); 551 addressElements[ 0 ].lpData = (LPVOID)guidSP; 552 553 addressElements[ 1 ].guidDataType = *guidDataType; 554 addressElements[ 1 ].dwDataSize = dwDataSize; 555 addressElements[ 1 ].lpData = (LPVOID)lpData; 556 557 /* Call CreateCompoundAddress to cut down on code. 558 NOTE: We can do this because we don't support DPL 1 interfaces! */ 559 return DPL_CreateCompoundAddress( addressElements, dwNumAddElements, 560 lpAddress, lpdwAddressSize, bAnsiInterface ); 561 } 562 563 564 565 /******************************************************************** 566 * 567 * Parses out chunks from the DirectPlay Address buffer by calling the 568 * given callback function, with lpContext, for each of the chunks. 569 * 570 */ 571 static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumAddress( IDirectPlayLobbyA *iface, 572 LPDPENUMADDRESSCALLBACK enumaddrcb, const void *address, DWORD size, void *context ) 573 { 574 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface ); 575 return IDirectPlayLobby_EnumAddress( &This->IDirectPlayLobby3A_iface, enumaddrcb, address, size, 576 context ); 577 } 578 579 static HRESULT WINAPI IDirectPlayLobbyImpl_EnumAddress( IDirectPlayLobby *iface, 580 LPDPENUMADDRESSCALLBACK enumaddrcb, const void *address, DWORD size, void *context ) 581 { 582 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface ); 583 return IDirectPlayLobby_EnumAddress( &This->IDirectPlayLobby3_iface, enumaddrcb, address, size, 584 context ); 585 } 586 587 static HRESULT WINAPI IDirectPlayLobby2AImpl_EnumAddress( IDirectPlayLobby2A *iface, 588 LPDPENUMADDRESSCALLBACK enumaddrcb, const void *address, DWORD size, void *context ) 589 { 590 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface ); 591 return IDirectPlayLobby_EnumAddress( &This->IDirectPlayLobby3A_iface, enumaddrcb, address, size, 592 context ); 593 } 594 595 static HRESULT WINAPI IDirectPlayLobby2Impl_EnumAddress( IDirectPlayLobby2 *iface, 596 LPDPENUMADDRESSCALLBACK enumaddrcb, const void *address, DWORD size, void *context ) 597 { 598 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface ); 599 return IDirectPlayLobby_EnumAddress( &This->IDirectPlayLobby3_iface, enumaddrcb, address, size, 600 context ); 601 } 602 603 static HRESULT WINAPI IDirectPlayLobby3AImpl_EnumAddress( IDirectPlayLobby3A *iface, 604 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback, const void *lpAddress, DWORD dwAddressSize, 605 void *lpContext ) 606 { 607 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3A( iface ); 608 609 TRACE("(%p)->(%p,%p,0x%08x,%p)\n", This, lpEnumAddressCallback, lpAddress, 610 dwAddressSize, lpContext ); 611 612 return DPL_EnumAddress( lpEnumAddressCallback, lpAddress, dwAddressSize, lpContext ); 613 } 614 615 static HRESULT WINAPI IDirectPlayLobby3Impl_EnumAddress( IDirectPlayLobby3 *iface, 616 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback, const void *lpAddress, DWORD dwAddressSize, 617 void *lpContext ) 618 { 619 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3( iface ); 620 621 TRACE("(%p)->(%p,%p,0x%08x,%p)\n", This, lpEnumAddressCallback, lpAddress, 622 dwAddressSize, lpContext ); 623 624 return DPL_EnumAddress( lpEnumAddressCallback, lpAddress, dwAddressSize, lpContext ); 625 } 626 627 HRESULT DPL_EnumAddress( LPDPENUMADDRESSCALLBACK lpEnumAddressCallback, LPCVOID lpAddress, 628 DWORD dwAddressSize, LPVOID lpContext ) 629 { 630 DWORD dwTotalSizeEnumerated = 0; 631 632 /* FIXME: First chunk is always the total size chunk - Should we report it? */ 633 634 while ( dwTotalSizeEnumerated < dwAddressSize ) 635 { 636 const DPADDRESS* lpElements = lpAddress; 637 DWORD dwSizeThisEnumeration; 638 639 /* Invoke the enum method. If false is returned, stop enumeration */ 640 if ( !lpEnumAddressCallback( &lpElements->guidDataType, 641 lpElements->dwDataSize, 642 (const BYTE *)lpElements + sizeof( DPADDRESS ), 643 lpContext ) ) 644 { 645 break; 646 } 647 648 dwSizeThisEnumeration = sizeof( DPADDRESS ) + lpElements->dwDataSize; 649 lpAddress = (const BYTE*) lpAddress + dwSizeThisEnumeration; 650 dwTotalSizeEnumerated += dwSizeThisEnumeration; 651 } 652 653 return DP_OK; 654 } 655 656 /******************************************************************** 657 * 658 * Enumerates all the address types that a given service provider needs to 659 * build the DirectPlay Address. 660 * 661 */ 662 static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumAddressTypes( IDirectPlayLobbyA *iface, 663 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb, REFGUID sp, void *context, DWORD flags ) 664 { 665 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface ); 666 return IDirectPlayLobby_EnumAddressTypes( &This->IDirectPlayLobby3A_iface, enumaddrtypecb, sp, 667 context, flags ); 668 } 669 670 static HRESULT WINAPI IDirectPlayLobbyImpl_EnumAddressTypes( IDirectPlayLobby *iface, 671 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb, REFGUID sp, void *context, DWORD flags ) 672 { 673 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface ); 674 return IDirectPlayLobby_EnumAddressTypes( &This->IDirectPlayLobby3_iface, enumaddrtypecb, sp, 675 context, flags ); 676 } 677 678 static HRESULT WINAPI IDirectPlayLobby2AImpl_EnumAddressTypes( IDirectPlayLobby2A *iface, 679 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb, REFGUID sp, void *context, DWORD flags ) 680 { 681 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface ); 682 return IDirectPlayLobby_EnumAddressTypes( &This->IDirectPlayLobby3A_iface, enumaddrtypecb, sp, 683 context, flags ); 684 } 685 686 static HRESULT WINAPI IDirectPlayLobby2Impl_EnumAddressTypes( IDirectPlayLobby2 *iface, 687 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb, REFGUID sp, void *context, DWORD flags ) 688 { 689 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface ); 690 return IDirectPlayLobby_EnumAddressTypes( &This->IDirectPlayLobby3_iface, enumaddrtypecb, sp, 691 context, flags ); 692 } 693 694 static HRESULT WINAPI IDirectPlayLobby3AImpl_EnumAddressTypes( IDirectPlayLobby3A *iface, 695 LPDPLENUMADDRESSTYPESCALLBACK lpEnumAddressTypeCallback, REFGUID guidSP, void *lpContext, 696 DWORD dwFlags ) 697 { 698 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3A( iface ); 699 700 HKEY hkResult; 701 LPCSTR searchSubKey = "SOFTWARE\\Microsoft\\DirectPlay\\Service Providers"; 702 DWORD dwIndex, sizeOfSubKeyName=50; 703 char subKeyName[51]; 704 FILETIME filetime; 705 706 TRACE(" (%p)->(%p,%p,%p,0x%08x)\n", This, lpEnumAddressTypeCallback, guidSP, lpContext, dwFlags ); 707 708 if( dwFlags != 0 ) 709 { 710 return DPERR_INVALIDPARAMS; 711 } 712 713 if( !lpEnumAddressTypeCallback ) 714 { 715 return DPERR_INVALIDPARAMS; 716 } 717 718 if( guidSP == NULL ) 719 { 720 return DPERR_INVALIDOBJECT; 721 } 722 723 /* Need to loop over the service providers in the registry */ 724 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE, searchSubKey, 725 0, KEY_READ, &hkResult ) != ERROR_SUCCESS ) 726 { 727 /* Hmmm. Does this mean that there are no service providers? */ 728 ERR(": no service providers?\n"); 729 return DP_OK; 730 } 731 732 /* Traverse all the service providers we have available */ 733 for( dwIndex=0; 734 RegEnumKeyExA( hkResult, dwIndex, subKeyName, &sizeOfSubKeyName, 735 NULL, NULL, NULL, &filetime ) != ERROR_NO_MORE_ITEMS; 736 ++dwIndex, sizeOfSubKeyName=50 ) 737 { 738 739 HKEY hkServiceProvider, hkServiceProviderAt; 740 GUID serviceProviderGUID; 741 DWORD returnTypeGUID, sizeOfReturnBuffer = 50; 742 char atSubKey[51]; 743 char returnBuffer[51]; 744 WCHAR buff[51]; 745 DWORD dwAtIndex; 746 LPCSTR atKey = "Address Types"; 747 LPCSTR guidDataSubKey = "Guid"; 748 749 TRACE(" this time through: %s\n", subKeyName ); 750 751 /* Get a handle for this particular service provider */ 752 if( RegOpenKeyExA( hkResult, subKeyName, 0, KEY_READ, 753 &hkServiceProvider ) != ERROR_SUCCESS ) 754 { 755 ERR(": what the heck is going on?\n" ); 756 continue; 757 } 758 759 if( RegQueryValueExA( hkServiceProvider, guidDataSubKey, 760 NULL, &returnTypeGUID, (LPBYTE)returnBuffer, 761 &sizeOfReturnBuffer ) != ERROR_SUCCESS ) 762 { 763 ERR(": missing GUID registry data members\n" ); 764 continue; 765 } 766 767 /* FIXME: Check return types to ensure we're interpreting data right */ 768 MultiByteToWideChar( CP_ACP, 0, returnBuffer, -1, buff, sizeof(buff)/sizeof(WCHAR) ); 769 CLSIDFromString( buff, &serviceProviderGUID ); 770 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */ 771 772 /* Determine if this is the Service Provider that the user asked for */ 773 if( !IsEqualGUID( &serviceProviderGUID, guidSP ) ) 774 { 775 continue; 776 } 777 778 /* Get a handle for this particular service provider */ 779 if( RegOpenKeyExA( hkServiceProvider, atKey, 0, KEY_READ, 780 &hkServiceProviderAt ) != ERROR_SUCCESS ) 781 { 782 TRACE(": No Address Types registry data sub key/members\n" ); 783 break; 784 } 785 786 /* Traverse all the address type we have available */ 787 for( dwAtIndex=0; 788 RegEnumKeyExA( hkServiceProviderAt, dwAtIndex, atSubKey, &sizeOfSubKeyName, 789 NULL, NULL, NULL, &filetime ) != ERROR_NO_MORE_ITEMS; 790 ++dwAtIndex, sizeOfSubKeyName=50 ) 791 { 792 TRACE( "Found Address Type GUID %s\n", atSubKey ); 793 794 /* FIXME: Check return types to ensure we're interpreting data right */ 795 MultiByteToWideChar( CP_ACP, 0, atSubKey, -1, buff, sizeof(buff)/sizeof(WCHAR) ); 796 CLSIDFromString( buff, &serviceProviderGUID ); 797 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */ 798 799 /* The enumeration will return FALSE if we are not to continue */ 800 if( !lpEnumAddressTypeCallback( &serviceProviderGUID, lpContext, 0 ) ) 801 { 802 WARN("lpEnumCallback returning FALSE\n" ); 803 break; /* FIXME: This most likely has to break from the procedure...*/ 804 } 805 806 } 807 808 /* We only enumerate address types for 1 GUID. We've found it, so quit looking */ 809 break; 810 } 811 812 return DP_OK; 813 } 814 815 static HRESULT WINAPI IDirectPlayLobby3Impl_EnumAddressTypes( IDirectPlayLobby3 *iface, 816 LPDPLENUMADDRESSTYPESCALLBACK enumaddrtypecb, REFGUID sp, void *context, DWORD flags ) 817 { 818 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3( iface ); 819 return IDirectPlayLobby_EnumAddressTypes( &This->IDirectPlayLobby3A_iface, enumaddrtypecb, sp, 820 context, flags ); 821 } 822 823 /******************************************************************** 824 * 825 * Enumerates what applications are registered with DirectPlay by 826 * invoking the callback function with lpContext. 827 * 828 */ 829 static HRESULT WINAPI IDirectPlayLobby3Impl_EnumLocalApplications( IDirectPlayLobby3 *iface, 830 LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback, void *lpContext, DWORD dwFlags ) 831 { 832 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3( iface ); 833 834 FIXME("(%p)->(%p,%p,0x%08x):stub\n", This, lpEnumLocalAppCallback, lpContext, dwFlags ); 835 836 return DPERR_OUTOFMEMORY; 837 } 838 839 static HRESULT WINAPI IDirectPlayLobbyAImpl_EnumLocalApplications( IDirectPlayLobbyA *iface, 840 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb, void *context, DWORD flags ) 841 { 842 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface ); 843 return IDirectPlayLobby_EnumLocalApplications( &This->IDirectPlayLobby3A_iface, enumlocalappcb, 844 context, flags ); 845 } 846 847 static HRESULT WINAPI IDirectPlayLobbyImpl_EnumLocalApplications( IDirectPlayLobby *iface, 848 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb, void *context, DWORD flags ) 849 { 850 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface ); 851 return IDirectPlayLobby_EnumLocalApplications( &This->IDirectPlayLobby3_iface, enumlocalappcb, 852 context, flags ); 853 } 854 855 static HRESULT WINAPI IDirectPlayLobby2AImpl_EnumLocalApplications( IDirectPlayLobby2A *iface, 856 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb, void *context, DWORD flags ) 857 { 858 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface ); 859 return IDirectPlayLobby_EnumLocalApplications( &This->IDirectPlayLobby3A_iface, enumlocalappcb, 860 context, flags ); 861 } 862 863 static HRESULT WINAPI IDirectPlayLobby2Impl_EnumLocalApplications( IDirectPlayLobby2 *iface, 864 LPDPLENUMLOCALAPPLICATIONSCALLBACK enumlocalappcb, void *context, DWORD flags ) 865 { 866 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface ); 867 return IDirectPlayLobby_EnumLocalApplications( &This->IDirectPlayLobby3_iface, enumlocalappcb, 868 context, flags ); 869 } 870 871 static HRESULT WINAPI IDirectPlayLobby3AImpl_EnumLocalApplications( IDirectPlayLobby3A *iface, 872 LPDPLENUMLOCALAPPLICATIONSCALLBACK lpEnumLocalAppCallback, void *lpContext, DWORD dwFlags ) 873 { 874 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3A( iface ); 875 876 HKEY hkResult; 877 LPCSTR searchSubKey = "SOFTWARE\\Microsoft\\DirectPlay\\Applications"; 878 LPCSTR guidDataSubKey = "Guid"; 879 DWORD dwIndex, sizeOfSubKeyName=50; 880 char subKeyName[51]; 881 FILETIME filetime; 882 883 TRACE("(%p)->(%p,%p,0x%08x)\n", This, lpEnumLocalAppCallback, lpContext, dwFlags ); 884 885 if( dwFlags != 0 ) 886 { 887 return DPERR_INVALIDPARAMS; 888 } 889 890 if( !lpEnumLocalAppCallback ) 891 { 892 return DPERR_INVALIDPARAMS; 893 } 894 895 /* Need to loop over the service providers in the registry */ 896 if( RegOpenKeyExA( HKEY_LOCAL_MACHINE, searchSubKey, 897 0, KEY_READ, &hkResult ) != ERROR_SUCCESS ) 898 { 899 /* Hmmm. Does this mean that there are no service providers? */ 900 ERR(": no service providers?\n"); 901 return DP_OK; 902 } 903 904 /* Traverse all registered applications */ 905 for( dwIndex=0; 906 RegEnumKeyExA( hkResult, dwIndex, subKeyName, &sizeOfSubKeyName, NULL, NULL, NULL, &filetime ) != ERROR_NO_MORE_ITEMS; 907 ++dwIndex, sizeOfSubKeyName=50 ) 908 { 909 910 HKEY hkServiceProvider; 911 GUID serviceProviderGUID; 912 DWORD returnTypeGUID, sizeOfReturnBuffer = 50; 913 char returnBuffer[51]; 914 WCHAR buff[51]; 915 DPLAPPINFO dplAppInfo; 916 917 TRACE(" this time through: %s\n", subKeyName ); 918 919 /* Get a handle for this particular service provider */ 920 if( RegOpenKeyExA( hkResult, subKeyName, 0, KEY_READ, 921 &hkServiceProvider ) != ERROR_SUCCESS ) 922 { 923 ERR(": what the heck is going on?\n" ); 924 continue; 925 } 926 927 if( RegQueryValueExA( hkServiceProvider, guidDataSubKey, 928 NULL, &returnTypeGUID, (LPBYTE)returnBuffer, 929 &sizeOfReturnBuffer ) != ERROR_SUCCESS ) 930 { 931 ERR(": missing GUID registry data members\n" ); 932 continue; 933 } 934 935 /* FIXME: Check return types to ensure we're interpreting data right */ 936 MultiByteToWideChar( CP_ACP, 0, returnBuffer, -1, buff, sizeof(buff)/sizeof(WCHAR) ); 937 CLSIDFromString( buff, &serviceProviderGUID ); 938 /* FIXME: Have I got a memory leak on the serviceProviderGUID? */ 939 940 dplAppInfo.dwSize = sizeof( dplAppInfo ); 941 dplAppInfo.guidApplication = serviceProviderGUID; 942 dplAppInfo.u.lpszAppNameA = subKeyName; 943 944 EnterCriticalSection( &This->lock ); 945 946 memcpy( &This->cbkeyhack, &hkServiceProvider, sizeof( hkServiceProvider ) ); 947 948 if( !lpEnumLocalAppCallback( &dplAppInfo, lpContext, dwFlags ) ) 949 { 950 LeaveCriticalSection( &This->lock ); 951 break; 952 } 953 954 LeaveCriticalSection( &This->lock ); 955 } 956 957 return DP_OK; 958 } 959 960 /******************************************************************** 961 * 962 * Retrieves the DPLCONNECTION structure that contains all the information 963 * needed to start and connect an application. This was generated using 964 * either the RunApplication or SetConnectionSettings methods. 965 * 966 * NOTES: If lpData is NULL then just return lpdwDataSize. This allows 967 * the data structure to be allocated by our caller which can then 968 * call this procedure/method again with a valid data pointer. 969 */ 970 static HRESULT WINAPI IDirectPlayLobbyAImpl_GetConnectionSettings( IDirectPlayLobbyA *iface, 971 DWORD appid, void *data, DWORD *size ) 972 { 973 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface ); 974 return IDirectPlayLobby_GetConnectionSettings( &This->IDirectPlayLobby3A_iface, appid, data, 975 size ); 976 } 977 978 static HRESULT WINAPI IDirectPlayLobbyImpl_GetConnectionSettings( IDirectPlayLobby *iface, 979 DWORD appid, void *data, DWORD *size ) 980 { 981 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface ); 982 return IDirectPlayLobby_GetConnectionSettings( &This->IDirectPlayLobby3_iface, appid, data, 983 size ); 984 } 985 986 static HRESULT WINAPI IDirectPlayLobby2AImpl_GetConnectionSettings( IDirectPlayLobby2A *iface, 987 DWORD appid, void *data, DWORD *size ) 988 { 989 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface ); 990 return IDirectPlayLobby_GetConnectionSettings( &This->IDirectPlayLobby3A_iface, appid, data, 991 size ); 992 } 993 994 static HRESULT WINAPI IDirectPlayLobby2Impl_GetConnectionSettings( IDirectPlayLobby2 *iface, 995 DWORD appid, void *data, DWORD *size ) 996 { 997 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface ); 998 return IDirectPlayLobby_GetConnectionSettings( &This->IDirectPlayLobby3_iface, appid, data, 999 size ); 1000 } 1001 1002 static HRESULT WINAPI IDirectPlayLobby3AImpl_GetConnectionSettings( IDirectPlayLobby3A *iface, 1003 DWORD dwAppID, void *lpData, DWORD *lpdwDataSize ) 1004 { 1005 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3A( iface ); 1006 HRESULT hr; 1007 1008 TRACE("(%p)->(0x%08x,%p,%p)\n", This, dwAppID, lpData, lpdwDataSize ); 1009 1010 EnterCriticalSection( &This->lock ); 1011 1012 hr = DPLAYX_GetConnectionSettingsA( dwAppID, 1013 lpData, 1014 lpdwDataSize 1015 ); 1016 1017 LeaveCriticalSection( &This->lock ); 1018 1019 return hr; 1020 } 1021 1022 static HRESULT WINAPI IDirectPlayLobby3Impl_GetConnectionSettings( IDirectPlayLobby3 *iface, 1023 DWORD dwAppID, void *lpData, DWORD *lpdwDataSize ) 1024 { 1025 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3( iface ); 1026 HRESULT hr; 1027 1028 TRACE("(%p)->(0x%08x,%p,%p)\n", This, dwAppID, lpData, lpdwDataSize ); 1029 1030 EnterCriticalSection( &This->lock ); 1031 1032 hr = DPLAYX_GetConnectionSettingsW( dwAppID, 1033 lpData, 1034 lpdwDataSize 1035 ); 1036 1037 LeaveCriticalSection( &This->lock ); 1038 1039 return hr; 1040 } 1041 1042 /******************************************************************** 1043 * 1044 * Retrieves the message sent between a lobby client and a DirectPlay 1045 * application. All messages are queued until received. 1046 * 1047 */ 1048 static HRESULT WINAPI IDirectPlayLobbyAImpl_ReceiveLobbyMessage( IDirectPlayLobbyA *iface, 1049 DWORD flags, DWORD appid, DWORD *msgflags, void *data, DWORD *size ) 1050 { 1051 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface ); 1052 return IDirectPlayLobby_ReceiveLobbyMessage( &This->IDirectPlayLobby3A_iface, flags, appid, 1053 msgflags, data, size ); 1054 } 1055 1056 static HRESULT WINAPI IDirectPlayLobbyImpl_ReceiveLobbyMessage( IDirectPlayLobby *iface, 1057 DWORD flags, DWORD appid, DWORD *msgflags, void *data, DWORD *size ) 1058 { 1059 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface ); 1060 return IDirectPlayLobby_ReceiveLobbyMessage( &This->IDirectPlayLobby3_iface, flags, appid, 1061 msgflags, data, size ); 1062 } 1063 1064 static HRESULT WINAPI IDirectPlayLobby2AImpl_ReceiveLobbyMessage( IDirectPlayLobby2A *iface, 1065 DWORD flags, DWORD appid, DWORD *msgflags, void *data, DWORD *size ) 1066 { 1067 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface ); 1068 return IDirectPlayLobby_ReceiveLobbyMessage( &This->IDirectPlayLobby3A_iface, flags, appid, 1069 msgflags, data, size ); 1070 } 1071 1072 static HRESULT WINAPI IDirectPlayLobby2Impl_ReceiveLobbyMessage( IDirectPlayLobby2 *iface, 1073 DWORD flags, DWORD appid, DWORD *msgflags, void *data, DWORD *size ) 1074 { 1075 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface ); 1076 return IDirectPlayLobby_ReceiveLobbyMessage( &This->IDirectPlayLobby3_iface, flags, appid, 1077 msgflags, data, size ); 1078 } 1079 1080 static HRESULT WINAPI IDirectPlayLobby3AImpl_ReceiveLobbyMessage( IDirectPlayLobby3A *iface, 1081 DWORD dwFlags, DWORD dwAppID, DWORD *lpdwMessageFlags, void *lpData, 1082 DWORD *lpdwDataSize ) 1083 { 1084 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3A( iface ); 1085 FIXME(":stub %p %08x %08x %p %p %p\n", This, dwFlags, dwAppID, lpdwMessageFlags, lpData, 1086 lpdwDataSize ); 1087 return DPERR_OUTOFMEMORY; 1088 } 1089 1090 static HRESULT WINAPI IDirectPlayLobby3Impl_ReceiveLobbyMessage( IDirectPlayLobby3 *iface, 1091 DWORD dwFlags, DWORD dwAppID, DWORD *lpdwMessageFlags, void *lpData, 1092 DWORD *lpdwDataSize ) 1093 { 1094 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3( iface ); 1095 FIXME(":stub %p %08x %08x %p %p %p\n", This, dwFlags, dwAppID, lpdwMessageFlags, lpData, 1096 lpdwDataSize ); 1097 return DPERR_OUTOFMEMORY; 1098 } 1099 1100 typedef struct tagRunApplicationEnumStruct 1101 { 1102 IDirectPlayLobbyImpl *This; 1103 1104 GUID appGUID; 1105 LPSTR lpszPath; 1106 LPSTR lpszFileName; 1107 LPSTR lpszCommandLine; 1108 LPSTR lpszCurrentDirectory; 1109 } RunApplicationEnumStruct, *lpRunApplicationEnumStruct; 1110 1111 /* To be called by RunApplication to find how to invoke the function */ 1112 static BOOL CALLBACK RunApplicationA_EnumLocalApplications 1113 ( LPCDPLAPPINFO lpAppInfo, 1114 LPVOID lpContext, 1115 DWORD dwFlags ) 1116 { 1117 lpRunApplicationEnumStruct lpData = (lpRunApplicationEnumStruct)lpContext; 1118 1119 if( IsEqualGUID( &lpAppInfo->guidApplication, &lpData->appGUID ) ) 1120 { 1121 char returnBuffer[200]; 1122 DWORD returnType, sizeOfReturnBuffer; 1123 LPCSTR clSubKey = "CommandLine"; 1124 LPCSTR cdSubKey = "CurrentDirectory"; 1125 LPCSTR fileSubKey = "File"; 1126 LPCSTR pathSubKey = "Path"; 1127 1128 /* FIXME: Lazy man hack - dplay struct has the present reg key saved */ 1129 1130 sizeOfReturnBuffer = 200; 1131 1132 /* Get all the appropriate data from the registry */ 1133 if( RegQueryValueExA( lpData->This->cbkeyhack, clSubKey, 1134 NULL, &returnType, (LPBYTE)returnBuffer, 1135 &sizeOfReturnBuffer ) != ERROR_SUCCESS ) 1136 { 1137 ERR( ": missing CommandLine registry data member\n" ); 1138 } 1139 else 1140 { 1141 if ((lpData->lpszCommandLine = HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer)+1 ))) 1142 strcpy( lpData->lpszCommandLine, returnBuffer ); 1143 } 1144 1145 sizeOfReturnBuffer = 200; 1146 1147 if( RegQueryValueExA( lpData->This->cbkeyhack, cdSubKey, 1148 NULL, &returnType, (LPBYTE)returnBuffer, 1149 &sizeOfReturnBuffer ) != ERROR_SUCCESS ) 1150 { 1151 ERR( ": missing CurrentDirectory registry data member\n" ); 1152 } 1153 else 1154 { 1155 if ((lpData->lpszCurrentDirectory = HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer)+1 ))) 1156 strcpy( lpData->lpszCurrentDirectory, returnBuffer ); 1157 } 1158 1159 sizeOfReturnBuffer = 200; 1160 1161 if( RegQueryValueExA( lpData->This->cbkeyhack, fileSubKey, 1162 NULL, &returnType, (LPBYTE)returnBuffer, 1163 &sizeOfReturnBuffer ) != ERROR_SUCCESS ) 1164 { 1165 ERR( ": missing File registry data member\n" ); 1166 } 1167 else 1168 { 1169 if ((lpData->lpszFileName = HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer)+1 ))) 1170 strcpy( lpData->lpszFileName, returnBuffer ); 1171 } 1172 1173 sizeOfReturnBuffer = 200; 1174 1175 if( RegQueryValueExA( lpData->This->cbkeyhack, pathSubKey, 1176 NULL, &returnType, (LPBYTE)returnBuffer, 1177 &sizeOfReturnBuffer ) != ERROR_SUCCESS ) 1178 { 1179 ERR( ": missing Path registry data member\n" ); 1180 } 1181 else 1182 { 1183 if ((lpData->lpszPath = HeapAlloc( GetProcessHeap(), 0, strlen(returnBuffer)+1 ))) 1184 strcpy( lpData->lpszPath, returnBuffer ); 1185 } 1186 1187 return FALSE; /* No need to keep going as we found what we wanted */ 1188 } 1189 1190 return TRUE; /* Keep enumerating, haven't found the application yet */ 1191 } 1192 1193 static BOOL DPL_CreateAndSetLobbyHandles( DWORD dwDestProcessId, HANDLE hDestProcess, 1194 LPHANDLE lphStart, LPHANDLE lphDeath, 1195 LPHANDLE lphRead ) 1196 { 1197 /* These are the handles for the created process */ 1198 HANDLE hAppStart = 0, hAppDeath = 0, hAppRead = 0; 1199 SECURITY_ATTRIBUTES s_attrib; 1200 1201 s_attrib.nLength = sizeof( s_attrib ); 1202 s_attrib.lpSecurityDescriptor = NULL; 1203 s_attrib.bInheritHandle = TRUE; 1204 1205 *lphStart = CreateEventW( &s_attrib, TRUE, FALSE, NULL ); 1206 *lphDeath = CreateEventW( &s_attrib, TRUE, FALSE, NULL ); 1207 *lphRead = CreateEventW( &s_attrib, TRUE, FALSE, NULL ); 1208 1209 if( ( !DuplicateHandle( GetCurrentProcess(), *lphStart, 1210 hDestProcess, &hAppStart, 1211 0, FALSE, DUPLICATE_SAME_ACCESS ) ) || 1212 ( !DuplicateHandle( GetCurrentProcess(), *lphDeath, 1213 hDestProcess, &hAppDeath, 1214 0, FALSE, DUPLICATE_SAME_ACCESS ) ) || 1215 ( !DuplicateHandle( GetCurrentProcess(), *lphRead, 1216 hDestProcess, &hAppRead, 1217 0, FALSE, DUPLICATE_SAME_ACCESS ) ) 1218 ) 1219 { 1220 if (*lphStart) { CloseHandle(*lphStart); *lphStart = 0; } 1221 if (*lphDeath) { CloseHandle(*lphDeath); *lphDeath = 0; } 1222 if (*lphRead) { CloseHandle(*lphRead); *lphRead = 0; } 1223 /* FIXME: Handle leak... */ 1224 ERR( "Unable to dup handles\n" ); 1225 return FALSE; 1226 } 1227 1228 if( !DPLAYX_SetLobbyHandles( dwDestProcessId, 1229 hAppStart, hAppDeath, hAppRead ) ) 1230 { 1231 /* FIXME: Handle leak... */ 1232 return FALSE; 1233 } 1234 1235 return TRUE; 1236 } 1237 1238 1239 /******************************************************************** 1240 * 1241 * Starts an application and passes to it all the information to 1242 * connect to a session. 1243 * 1244 */ 1245 static HRESULT WINAPI IDirectPlayLobbyAImpl_RunApplication( IDirectPlayLobbyA *iface, DWORD flags, 1246 DWORD *appid, DPLCONNECTION *conn, HANDLE event ) 1247 { 1248 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface ); 1249 return IDirectPlayLobby_RunApplication( &This->IDirectPlayLobby3A_iface, flags, appid, conn, 1250 event ); 1251 } 1252 1253 static HRESULT WINAPI IDirectPlayLobbyImpl_RunApplication( IDirectPlayLobby *iface, DWORD flags, 1254 DWORD *appid, DPLCONNECTION *conn, HANDLE event ) 1255 { 1256 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface ); 1257 return IDirectPlayLobby_RunApplication( &This->IDirectPlayLobby3_iface, flags, appid, conn, 1258 event ); 1259 } 1260 1261 static HRESULT WINAPI IDirectPlayLobby2AImpl_RunApplication( IDirectPlayLobby2A *iface, DWORD flags, 1262 DWORD *appid, DPLCONNECTION *conn, HANDLE event ) 1263 { 1264 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface ); 1265 return IDirectPlayLobby_RunApplication( &This->IDirectPlayLobby3A_iface, flags, appid, conn, 1266 event ); 1267 } 1268 1269 static HRESULT WINAPI IDirectPlayLobby2Impl_RunApplication( IDirectPlayLobby2 *iface, DWORD flags, 1270 DWORD *appid, DPLCONNECTION *conn, HANDLE event ) 1271 { 1272 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface ); 1273 return IDirectPlayLobby_RunApplication( &This->IDirectPlayLobby3_iface, flags, appid, conn, 1274 event ); 1275 } 1276 1277 static HRESULT WINAPI IDirectPlayLobby3AImpl_RunApplication( IDirectPlayLobby3A *iface, 1278 DWORD dwFlags, DWORD *lpdwAppID, DPLCONNECTION *lpConn, HANDLE hReceiveEvent ) 1279 { 1280 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3A( iface ); 1281 HRESULT hr; 1282 RunApplicationEnumStruct enumData; 1283 char temp[200]; 1284 STARTUPINFOA startupInfo; 1285 PROCESS_INFORMATION newProcessInfo; 1286 LPSTR appName; 1287 DWORD dwSuspendCount; 1288 HANDLE hStart, hDeath, hSettingRead; 1289 1290 TRACE( "(%p)->(0x%08x,%p,%p,%p)\n", 1291 This, dwFlags, lpdwAppID, lpConn, hReceiveEvent ); 1292 1293 if( dwFlags != 0 ) 1294 { 1295 return DPERR_INVALIDPARAMS; 1296 } 1297 1298 if( DPLAYX_AnyLobbiesWaitingForConnSettings() ) 1299 { 1300 FIXME( "Waiting lobby not being handled correctly\n" ); 1301 } 1302 1303 EnterCriticalSection( &This->lock ); 1304 1305 ZeroMemory( &enumData, sizeof( enumData ) ); 1306 enumData.This = This; 1307 enumData.appGUID = lpConn->lpSessionDesc->guidApplication; 1308 1309 /* Our callback function will fill up the enumData structure with all the information 1310 required to start a new process */ 1311 IDirectPlayLobby_EnumLocalApplications( iface, RunApplicationA_EnumLocalApplications, 1312 (&enumData), 0 ); 1313 1314 /* First the application name */ 1315 strcpy( temp, enumData.lpszPath ); 1316 strcat( temp, "\\" ); 1317 strcat( temp, enumData.lpszFileName ); 1318 HeapFree( GetProcessHeap(), 0, enumData.lpszPath ); 1319 HeapFree( GetProcessHeap(), 0, enumData.lpszFileName ); 1320 if ((appName = HeapAlloc( GetProcessHeap(), 0, strlen(temp)+1 ))) strcpy( appName, temp ); 1321 1322 /* Now the command line */ 1323 strcat( temp, " " ); 1324 strcat( temp, enumData.lpszCommandLine ); 1325 HeapFree( GetProcessHeap(), 0, enumData.lpszCommandLine ); 1326 if ((enumData.lpszCommandLine = HeapAlloc( GetProcessHeap(), 0, strlen(temp)+1 ))) 1327 strcpy( enumData.lpszCommandLine, temp ); 1328 1329 ZeroMemory( &startupInfo, sizeof( startupInfo ) ); 1330 startupInfo.cb = sizeof( startupInfo ); 1331 /* FIXME: Should any fields be filled in? */ 1332 1333 ZeroMemory( &newProcessInfo, sizeof( newProcessInfo ) ); 1334 1335 if( !CreateProcessA( appName, 1336 enumData.lpszCommandLine, 1337 NULL, 1338 NULL, 1339 FALSE, 1340 CREATE_DEFAULT_ERROR_MODE | CREATE_NEW_CONSOLE | CREATE_SUSPENDED, /* Creation Flags */ 1341 NULL, 1342 enumData.lpszCurrentDirectory, 1343 &startupInfo, 1344 &newProcessInfo 1345 ) 1346 ) 1347 { 1348 ERR( "Failed to create process for app %s\n", appName ); 1349 1350 HeapFree( GetProcessHeap(), 0, appName ); 1351 HeapFree( GetProcessHeap(), 0, enumData.lpszCommandLine ); 1352 HeapFree( GetProcessHeap(), 0, enumData.lpszCurrentDirectory ); 1353 1354 LeaveCriticalSection( &This->lock ); 1355 return DPERR_CANTCREATEPROCESS; 1356 } 1357 1358 HeapFree( GetProcessHeap(), 0, appName ); 1359 HeapFree( GetProcessHeap(), 0, enumData.lpszCommandLine ); 1360 HeapFree( GetProcessHeap(), 0, enumData.lpszCurrentDirectory ); 1361 1362 /* Reserve this global application id! */ 1363 if( !DPLAYX_CreateLobbyApplication( newProcessInfo.dwProcessId ) ) 1364 { 1365 ERR( "Unable to create global application data for 0x%08x\n", 1366 newProcessInfo.dwProcessId ); 1367 } 1368 1369 hr = IDirectPlayLobby_SetConnectionSettings( iface, 0, newProcessInfo.dwProcessId, lpConn ); 1370 1371 if( hr != DP_OK ) 1372 { 1373 ERR( "SetConnectionSettings failure %s\n", DPLAYX_HresultToString( hr ) ); 1374 LeaveCriticalSection( &This->lock ); 1375 return hr; 1376 } 1377 1378 /* Setup the handles for application notification */ 1379 DPL_CreateAndSetLobbyHandles( newProcessInfo.dwProcessId, 1380 newProcessInfo.hProcess, 1381 &hStart, &hDeath, &hSettingRead ); 1382 1383 /* Setup the message thread ID */ 1384 This->msgtid = CreateLobbyMessageReceptionThread( hReceiveEvent, hStart, hDeath, hSettingRead ); 1385 1386 DPLAYX_SetLobbyMsgThreadId( newProcessInfo.dwProcessId, This->msgtid ); 1387 1388 LeaveCriticalSection( &This->lock ); 1389 1390 /* Everything seems to have been set correctly, update the dwAppID */ 1391 *lpdwAppID = newProcessInfo.dwProcessId; 1392 1393 /* Unsuspend the process - should return the prev suspension count */ 1394 if( ( dwSuspendCount = ResumeThread( newProcessInfo.hThread ) ) != 1 ) 1395 { 1396 ERR( "ResumeThread failed with 0x%08x\n", dwSuspendCount ); 1397 } 1398 1399 return DP_OK; 1400 } 1401 1402 static HRESULT WINAPI IDirectPlayLobby3Impl_RunApplication( IDirectPlayLobby3 *iface, DWORD dwFlags, 1403 DWORD *lpdwAppID, DPLCONNECTION *lpConn, HANDLE hReceiveEvent ) 1404 { 1405 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3( iface ); 1406 FIXME( "(%p)->(0x%08x,%p,%p,%p):stub\n", This, dwFlags, lpdwAppID, lpConn, hReceiveEvent ); 1407 return DPERR_OUTOFMEMORY; 1408 } 1409 1410 /******************************************************************** 1411 * 1412 * Sends a message between the application and the lobby client. 1413 * All messages are queued until received. 1414 * 1415 */ 1416 static HRESULT WINAPI IDirectPlayLobbyAImpl_SendLobbyMessage( IDirectPlayLobbyA *iface, DWORD flags, 1417 DWORD appid, void *data, DWORD size ) 1418 { 1419 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface ); 1420 return IDirectPlayLobby_SendLobbyMessage( &This->IDirectPlayLobby3A_iface, flags, appid, data, 1421 size ); 1422 } 1423 1424 static HRESULT WINAPI IDirectPlayLobbyImpl_SendLobbyMessage( IDirectPlayLobby *iface, DWORD flags, 1425 DWORD appid, void *data, DWORD size ) 1426 { 1427 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface ); 1428 return IDirectPlayLobby_SendLobbyMessage( &This->IDirectPlayLobby3_iface, flags, appid, data, 1429 size ); 1430 } 1431 1432 static HRESULT WINAPI IDirectPlayLobby2AImpl_SendLobbyMessage( IDirectPlayLobby2A *iface, 1433 DWORD flags, DWORD appid, void *data, DWORD size ) 1434 { 1435 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface ); 1436 return IDirectPlayLobby_SendLobbyMessage( &This->IDirectPlayLobby3A_iface, flags, appid, data, 1437 size ); 1438 } 1439 1440 static HRESULT WINAPI IDirectPlayLobby2Impl_SendLobbyMessage( IDirectPlayLobby2 *iface, DWORD flags, 1441 DWORD appid, void *data, DWORD size ) 1442 { 1443 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface ); 1444 return IDirectPlayLobby_SendLobbyMessage( &This->IDirectPlayLobby3_iface, flags, appid, data, 1445 size ); 1446 } 1447 1448 static HRESULT WINAPI IDirectPlayLobby3AImpl_SendLobbyMessage( IDirectPlayLobby3A *iface, 1449 DWORD flags, DWORD appid, void *data, DWORD size ) 1450 { 1451 FIXME(":stub\n"); 1452 return DPERR_OUTOFMEMORY; 1453 } 1454 1455 static HRESULT WINAPI IDirectPlayLobby3Impl_SendLobbyMessage( IDirectPlayLobby3 *iface, 1456 DWORD flags, DWORD appid, void *data, DWORD size ) 1457 { 1458 FIXME(":stub\n"); 1459 return DPERR_OUTOFMEMORY; 1460 } 1461 1462 /******************************************************************** 1463 * 1464 * Modifies the DPLCONNECTION structure to contain all information 1465 * needed to start and connect an application. 1466 * 1467 */ 1468 static HRESULT WINAPI IDirectPlayLobby3Impl_SetConnectionSettings( IDirectPlayLobby3 *iface, 1469 DWORD dwFlags, DWORD dwAppID, DPLCONNECTION *lpConn ) 1470 { 1471 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3( iface ); 1472 HRESULT hr; 1473 1474 TRACE("(%p)->(0x%08x,0x%08x,%p)\n", This, dwFlags, dwAppID, lpConn ); 1475 1476 EnterCriticalSection( &This->lock ); 1477 1478 hr = DPLAYX_SetConnectionSettingsW( dwFlags, dwAppID, lpConn ); 1479 1480 /* FIXME: Don't think that this is supposed to fail, but the documentation 1481 is somewhat sketchy. I'll try creating a lobby application 1482 for this... */ 1483 if( hr == DPERR_NOTLOBBIED ) 1484 { 1485 FIXME( "Unlobbied app setting connections. Is this correct behavior?\n" ); 1486 if( dwAppID == 0 ) 1487 { 1488 dwAppID = GetCurrentProcessId(); 1489 } 1490 DPLAYX_CreateLobbyApplication( dwAppID ); 1491 hr = DPLAYX_SetConnectionSettingsW( dwFlags, dwAppID, lpConn ); 1492 } 1493 1494 LeaveCriticalSection( &This->lock ); 1495 1496 return hr; 1497 } 1498 1499 static HRESULT WINAPI IDirectPlayLobbyAImpl_SetConnectionSettings( IDirectPlayLobbyA *iface, 1500 DWORD flags, DWORD appid, DPLCONNECTION *conn ) 1501 { 1502 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface ); 1503 return IDirectPlayLobby_SetConnectionSettings( &This->IDirectPlayLobby3A_iface, flags, 1504 appid, conn ); 1505 } 1506 1507 static HRESULT WINAPI IDirectPlayLobbyImpl_SetConnectionSettings( IDirectPlayLobby *iface, 1508 DWORD flags, DWORD appid, DPLCONNECTION *conn ) 1509 { 1510 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface ); 1511 return IDirectPlayLobby_SetConnectionSettings( &This->IDirectPlayLobby3_iface, flags, 1512 appid, conn ); 1513 } 1514 1515 static HRESULT WINAPI IDirectPlayLobby2AImpl_SetConnectionSettings( IDirectPlayLobby2A *iface, 1516 DWORD flags, DWORD appid, DPLCONNECTION *conn ) 1517 { 1518 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface ); 1519 return IDirectPlayLobby_SetConnectionSettings( &This->IDirectPlayLobby3A_iface, flags, 1520 appid, conn ); 1521 } 1522 1523 static HRESULT WINAPI IDirectPlayLobby2Impl_SetConnectionSettings( IDirectPlayLobby2 *iface, 1524 DWORD flags, DWORD appid, DPLCONNECTION *conn ) 1525 { 1526 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface ); 1527 return IDirectPlayLobby_SetConnectionSettings( &This->IDirectPlayLobby3_iface, flags, 1528 appid, conn ); 1529 } 1530 1531 static HRESULT WINAPI IDirectPlayLobby3AImpl_SetConnectionSettings( IDirectPlayLobby3A *iface, 1532 DWORD dwFlags, DWORD dwAppID, DPLCONNECTION *lpConn ) 1533 { 1534 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3A( iface ); 1535 HRESULT hr; 1536 1537 TRACE("(%p)->(0x%08x,0x%08x,%p)\n", This, dwFlags, dwAppID, lpConn ); 1538 1539 EnterCriticalSection( &This->lock ); 1540 1541 hr = DPLAYX_SetConnectionSettingsA( dwFlags, dwAppID, lpConn ); 1542 1543 /* FIXME: Don't think that this is supposed to fail, but the documentation 1544 is somewhat sketchy. I'll try creating a lobby application 1545 for this... */ 1546 if( hr == DPERR_NOTLOBBIED ) 1547 { 1548 FIXME( "Unlobbied app setting connections. Is this correct behavior?\n" ); 1549 dwAppID = GetCurrentProcessId(); 1550 DPLAYX_CreateLobbyApplication( dwAppID ); 1551 hr = DPLAYX_SetConnectionSettingsA( dwFlags, dwAppID, lpConn ); 1552 } 1553 1554 LeaveCriticalSection( &This->lock ); 1555 1556 return hr; 1557 } 1558 1559 /******************************************************************** 1560 * 1561 * Registers an event that will be set when a lobby message is received. 1562 * 1563 */ 1564 static HRESULT WINAPI IDirectPlayLobbyAImpl_SetLobbyMessageEvent( IDirectPlayLobbyA *iface, 1565 DWORD flags, DWORD appid, HANDLE event ) 1566 { 1567 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobbyA( iface ); 1568 return IDirectPlayLobby_SetLobbyMessageEvent( &This->IDirectPlayLobby3A_iface, flags, appid, 1569 event ); 1570 } 1571 1572 static HRESULT WINAPI IDirectPlayLobbyImpl_SetLobbyMessageEvent( IDirectPlayLobby *iface, 1573 DWORD flags, DWORD appid, HANDLE event ) 1574 { 1575 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby( iface ); 1576 return IDirectPlayLobby_SetLobbyMessageEvent( &This->IDirectPlayLobby3_iface, flags, appid, 1577 event ); 1578 } 1579 1580 static HRESULT WINAPI IDirectPlayLobby2AImpl_SetLobbyMessageEvent( IDirectPlayLobby2A *iface, 1581 DWORD flags, DWORD appid, HANDLE event ) 1582 { 1583 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface ); 1584 return IDirectPlayLobby_SetLobbyMessageEvent( &This->IDirectPlayLobby3A_iface, flags, appid, 1585 event ); 1586 } 1587 1588 static HRESULT WINAPI IDirectPlayLobby2Impl_SetLobbyMessageEvent( IDirectPlayLobby2 *iface, 1589 DWORD flags, DWORD appid, HANDLE event ) 1590 { 1591 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface ); 1592 return IDirectPlayLobby_SetLobbyMessageEvent( &This->IDirectPlayLobby3_iface, flags, appid, 1593 event ); 1594 } 1595 1596 static HRESULT WINAPI IDirectPlayLobby3AImpl_SetLobbyMessageEvent( IDirectPlayLobby3A *iface, 1597 DWORD flags, DWORD appid, HANDLE event ) 1598 { 1599 FIXME(":stub\n"); 1600 return DPERR_OUTOFMEMORY; 1601 } 1602 1603 static HRESULT WINAPI IDirectPlayLobby3Impl_SetLobbyMessageEvent( IDirectPlayLobby3 *iface, 1604 DWORD flags, DWORD appid, HANDLE event ) 1605 { 1606 FIXME(":stub\n"); 1607 return DPERR_OUTOFMEMORY; 1608 } 1609 1610 1611 /* DPL 2 methods */ 1612 static HRESULT WINAPI IDirectPlayLobby2AImpl_CreateCompoundAddress( IDirectPlayLobby2A *iface, 1613 const DPCOMPOUNDADDRESSELEMENT *elements, DWORD count, void *address, DWORD *size ) 1614 { 1615 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2A( iface ); 1616 return IDirectPlayLobby_CreateCompoundAddress( &This->IDirectPlayLobby3A_iface, elements, 1617 count, address, size ); 1618 } 1619 1620 static HRESULT WINAPI IDirectPlayLobby2Impl_CreateCompoundAddress( IDirectPlayLobby2 *iface, 1621 const DPCOMPOUNDADDRESSELEMENT *elements, DWORD count, void *address, DWORD *size ) 1622 { 1623 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby2( iface ); 1624 return IDirectPlayLobby_CreateCompoundAddress( &This->IDirectPlayLobby3_iface, elements, 1625 count, address, size ); 1626 } 1627 1628 static HRESULT WINAPI IDirectPlayLobby3Impl_CreateCompoundAddress( IDirectPlayLobby3 *iface, 1629 const DPCOMPOUNDADDRESSELEMENT *lpElements, DWORD dwElementCount, void *lpAddress, 1630 DWORD *lpdwAddressSize ) 1631 { 1632 return DPL_CreateCompoundAddress( lpElements, dwElementCount, lpAddress, lpdwAddressSize, FALSE ); 1633 } 1634 1635 static HRESULT WINAPI IDirectPlayLobby3AImpl_CreateCompoundAddress( IDirectPlayLobby3A *iface, 1636 const DPCOMPOUNDADDRESSELEMENT *lpElements, DWORD dwElementCount, void *lpAddress, 1637 DWORD *lpdwAddressSize ) 1638 { 1639 return DPL_CreateCompoundAddress( lpElements, dwElementCount, lpAddress, lpdwAddressSize, TRUE ); 1640 } 1641 1642 HRESULT DPL_CreateCompoundAddress 1643 ( LPCDPCOMPOUNDADDRESSELEMENT lpElements, 1644 DWORD dwElementCount, 1645 LPVOID lpAddress, 1646 LPDWORD lpdwAddressSize, 1647 BOOL bAnsiInterface ) 1648 { 1649 DWORD dwSizeRequired = 0; 1650 DWORD dwElements; 1651 LPCDPCOMPOUNDADDRESSELEMENT lpOrigElements = lpElements; 1652 1653 TRACE("(%p,0x%08x,%p,%p)\n", lpElements, dwElementCount, lpAddress, lpdwAddressSize ); 1654 1655 /* Parameter check */ 1656 if( ( lpElements == NULL ) || 1657 ( dwElementCount == 0 ) /* FIXME: Not sure if this is a failure case */ 1658 ) 1659 { 1660 return DPERR_INVALIDPARAMS; 1661 } 1662 1663 /* Add the total size chunk */ 1664 dwSizeRequired += sizeof( DPADDRESS ) + sizeof( DWORD ); 1665 1666 /* Calculate the size of the buffer required */ 1667 for ( dwElements = dwElementCount; dwElements > 0; --dwElements, ++lpElements ) 1668 { 1669 if ( ( IsEqualGUID( &lpElements->guidDataType, &DPAID_ServiceProvider ) ) || 1670 ( IsEqualGUID( &lpElements->guidDataType, &DPAID_LobbyProvider ) ) 1671 ) 1672 { 1673 dwSizeRequired += sizeof( DPADDRESS ) + sizeof( GUID ); 1674 } 1675 else if ( ( IsEqualGUID( &lpElements->guidDataType, &DPAID_Phone ) ) || 1676 ( IsEqualGUID( &lpElements->guidDataType, &DPAID_Modem ) ) || 1677 ( IsEqualGUID( &lpElements->guidDataType, &DPAID_INet ) ) 1678 ) 1679 { 1680 if( !bAnsiInterface ) 1681 { 1682 ERR( "Ansi GUIDs used for unicode interface\n" ); 1683 return DPERR_INVALIDFLAGS; 1684 } 1685 1686 dwSizeRequired += sizeof( DPADDRESS ) + lpElements->dwDataSize; 1687 } 1688 else if ( ( IsEqualGUID( &lpElements->guidDataType, &DPAID_PhoneW ) ) || 1689 ( IsEqualGUID( &lpElements->guidDataType, &DPAID_ModemW ) ) || 1690 ( IsEqualGUID( &lpElements->guidDataType, &DPAID_INetW ) ) 1691 ) 1692 { 1693 if( bAnsiInterface ) 1694 { 1695 ERR( "Unicode GUIDs used for ansi interface\n" ); 1696 return DPERR_INVALIDFLAGS; 1697 } 1698 1699 FIXME( "Right size for unicode interface?\n" ); 1700 dwSizeRequired += sizeof( DPADDRESS ) + lpElements->dwDataSize * sizeof( WCHAR ); 1701 } 1702 else if ( IsEqualGUID( &lpElements->guidDataType, &DPAID_INetPort ) ) 1703 { 1704 dwSizeRequired += sizeof( DPADDRESS ) + sizeof( WORD ); 1705 } 1706 else if ( IsEqualGUID( &lpElements->guidDataType, &DPAID_ComPort ) ) 1707 { 1708 FIXME( "Right size for unicode interface?\n" ); 1709 dwSizeRequired += sizeof( DPADDRESS ) + sizeof( DPCOMPORTADDRESS ); /* FIXME: Right size? */ 1710 } 1711 else 1712 { 1713 WARN( "Skipping Unknown GUID %s\n", debugstr_guid(&lpElements->guidDataType) ); 1714 } 1715 } 1716 1717 /* The user wants to know how big a buffer to allocate for us */ 1718 if( ( lpAddress == NULL ) || 1719 ( *lpdwAddressSize < dwSizeRequired ) 1720 ) 1721 { 1722 *lpdwAddressSize = dwSizeRequired; 1723 return DPERR_BUFFERTOOSMALL; 1724 } 1725 1726 /* Add the total size chunk */ 1727 { 1728 LPDPADDRESS lpdpAddress = lpAddress; 1729 1730 lpdpAddress->guidDataType = DPAID_TotalSize; 1731 lpdpAddress->dwDataSize = sizeof( DWORD ); 1732 lpAddress = (char *) lpAddress + sizeof( DPADDRESS ); 1733 1734 *(LPDWORD)lpAddress = dwSizeRequired; 1735 lpAddress = (char *) lpAddress + sizeof( DWORD ); 1736 } 1737 1738 /* Calculate the size of the buffer required */ 1739 for( dwElements = dwElementCount, lpElements = lpOrigElements; 1740 dwElements > 0; 1741 --dwElements, ++lpElements ) 1742 { 1743 if ( ( IsEqualGUID( &lpElements->guidDataType, &DPAID_ServiceProvider ) ) || 1744 ( IsEqualGUID( &lpElements->guidDataType, &DPAID_LobbyProvider ) ) 1745 ) 1746 { 1747 LPDPADDRESS lpdpAddress = lpAddress; 1748 1749 lpdpAddress->guidDataType = lpElements->guidDataType; 1750 lpdpAddress->dwDataSize = sizeof( GUID ); 1751 lpAddress = (char *) lpAddress + sizeof( DPADDRESS ); 1752 1753 CopyMemory( lpAddress, lpElements->lpData, sizeof( GUID ) ); 1754 lpAddress = (char *) lpAddress + sizeof( GUID ); 1755 } 1756 else if ( ( IsEqualGUID( &lpElements->guidDataType, &DPAID_Phone ) ) || 1757 ( IsEqualGUID( &lpElements->guidDataType, &DPAID_Modem ) ) || 1758 ( IsEqualGUID( &lpElements->guidDataType, &DPAID_INet ) ) 1759 ) 1760 { 1761 LPDPADDRESS lpdpAddress = lpAddress; 1762 1763 lpdpAddress->guidDataType = lpElements->guidDataType; 1764 lpdpAddress->dwDataSize = lpElements->dwDataSize; 1765 lpAddress = (char *) lpAddress + sizeof( DPADDRESS ); 1766 1767 lstrcpynA( lpAddress, lpElements->lpData, lpElements->dwDataSize ); 1768 lpAddress = (char *) lpAddress + lpElements->dwDataSize; 1769 } 1770 else if ( ( IsEqualGUID( &lpElements->guidDataType, &DPAID_PhoneW ) ) || 1771 ( IsEqualGUID( &lpElements->guidDataType, &DPAID_ModemW ) ) || 1772 ( IsEqualGUID( &lpElements->guidDataType, &DPAID_INetW ) ) 1773 ) 1774 { 1775 LPDPADDRESS lpdpAddress = lpAddress; 1776 1777 lpdpAddress->guidDataType = lpElements->guidDataType; 1778 lpdpAddress->dwDataSize = lpElements->dwDataSize; 1779 lpAddress = (char *) lpAddress + sizeof( DPADDRESS ); 1780 1781 lstrcpynW( lpAddress, lpElements->lpData, lpElements->dwDataSize ); 1782 lpAddress = (char *) lpAddress + lpElements->dwDataSize * sizeof( WCHAR ); 1783 } 1784 else if ( IsEqualGUID( &lpElements->guidDataType, &DPAID_INetPort ) ) 1785 { 1786 LPDPADDRESS lpdpAddress = lpAddress; 1787 1788 lpdpAddress->guidDataType = lpElements->guidDataType; 1789 lpdpAddress->dwDataSize = lpElements->dwDataSize; 1790 lpAddress = (char *) lpAddress + sizeof( DPADDRESS ); 1791 1792 *((LPWORD)lpAddress) = *((LPWORD)lpElements->lpData); 1793 lpAddress = (char *) lpAddress + sizeof( WORD ); 1794 } 1795 else if ( IsEqualGUID( &lpElements->guidDataType, &DPAID_ComPort ) ) 1796 { 1797 LPDPADDRESS lpdpAddress = lpAddress; 1798 1799 lpdpAddress->guidDataType = lpElements->guidDataType; 1800 lpdpAddress->dwDataSize = lpElements->dwDataSize; 1801 lpAddress = (char *) lpAddress + sizeof( DPADDRESS ); 1802 1803 CopyMemory( lpAddress, lpElements->lpData, sizeof( DPADDRESS ) ); 1804 lpAddress = (char *) lpAddress + sizeof( DPADDRESS ); 1805 } 1806 } 1807 1808 return DP_OK; 1809 } 1810 1811 /* DPL 3 methods */ 1812 1813 static HRESULT WINAPI IDirectPlayLobby3Impl_ConnectEx( IDirectPlayLobby3 *iface, DWORD dwFlags, 1814 REFIID riid, LPVOID* lplpDP, IUnknown* pUnk ) 1815 { 1816 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3( iface ); 1817 return DPL_ConnectEx( This, dwFlags, riid, lplpDP, pUnk ); 1818 } 1819 1820 static HRESULT WINAPI IDirectPlayLobby3AImpl_ConnectEx( IDirectPlayLobby3A *iface, DWORD dwFlags, 1821 REFIID riid, void **lplpDP, IUnknown *pUnk ) 1822 { 1823 IDirectPlayLobbyImpl *This = impl_from_IDirectPlayLobby3A( iface ); 1824 return DPL_ConnectEx( This, dwFlags, riid, lplpDP, pUnk ); 1825 } 1826 1827 static HRESULT WINAPI IDirectPlayLobby3Impl_RegisterApplication( IDirectPlayLobby3 *iface, 1828 DWORD flags, DPAPPLICATIONDESC *appdesc ) 1829 { 1830 FIXME(":stub\n"); 1831 return DP_OK; 1832 } 1833 1834 static HRESULT WINAPI IDirectPlayLobby3AImpl_RegisterApplication( IDirectPlayLobby3A *iface, 1835 DWORD flags, DPAPPLICATIONDESC *appdesc ) 1836 { 1837 FIXME(":stub\n"); 1838 return DP_OK; 1839 } 1840 1841 static HRESULT WINAPI IDirectPlayLobby3Impl_UnregisterApplication( IDirectPlayLobby3 *iface, 1842 DWORD flags, REFGUID appdesc ) 1843 { 1844 FIXME(":stub\n"); 1845 return DP_OK; 1846 } 1847 1848 static HRESULT WINAPI IDirectPlayLobby3AImpl_UnregisterApplication( IDirectPlayLobby3A *iface, 1849 DWORD flags, REFGUID appdesc ) 1850 { 1851 FIXME(":stub\n"); 1852 return DP_OK; 1853 } 1854 1855 static HRESULT WINAPI IDirectPlayLobby3Impl_WaitForConnectionSettings( IDirectPlayLobby3 *iface, 1856 DWORD dwFlags ) 1857 { 1858 HRESULT hr = DP_OK; 1859 BOOL bStartWait = !(dwFlags & DPLWAIT_CANCEL); 1860 1861 TRACE( "(%p)->(0x%08x)\n", iface, dwFlags ); 1862 1863 if( DPLAYX_WaitForConnectionSettings( bStartWait ) ) 1864 { 1865 /* FIXME: What is the correct error return code? */ 1866 hr = DPERR_NOTLOBBIED; 1867 } 1868 1869 return hr; 1870 } 1871 1872 static HRESULT WINAPI IDirectPlayLobby3AImpl_WaitForConnectionSettings( IDirectPlayLobby3A *iface, 1873 DWORD dwFlags ) 1874 { 1875 HRESULT hr = DP_OK; 1876 BOOL bStartWait = !(dwFlags & DPLWAIT_CANCEL); 1877 1878 TRACE( "(%p)->(0x%08x)\n", iface, dwFlags ); 1879 1880 if( DPLAYX_WaitForConnectionSettings( bStartWait ) ) 1881 { 1882 /* FIXME: What is the correct error return code? */ 1883 hr = DPERR_NOTLOBBIED; 1884 } 1885 1886 return hr; 1887 } 1888 1889 static const IDirectPlayLobbyVtbl dplA_vt = 1890 { 1891 IDirectPlayLobbyAImpl_QueryInterface, 1892 IDirectPlayLobbyAImpl_AddRef, 1893 IDirectPlayLobbyAImpl_Release, 1894 IDirectPlayLobbyAImpl_Connect, 1895 IDirectPlayLobbyAImpl_CreateAddress, 1896 IDirectPlayLobbyAImpl_EnumAddress, 1897 IDirectPlayLobbyAImpl_EnumAddressTypes, 1898 IDirectPlayLobbyAImpl_EnumLocalApplications, 1899 IDirectPlayLobbyAImpl_GetConnectionSettings, 1900 IDirectPlayLobbyAImpl_ReceiveLobbyMessage, 1901 IDirectPlayLobbyAImpl_RunApplication, 1902 IDirectPlayLobbyAImpl_SendLobbyMessage, 1903 IDirectPlayLobbyAImpl_SetConnectionSettings, 1904 IDirectPlayLobbyAImpl_SetLobbyMessageEvent 1905 }; 1906 1907 static const IDirectPlayLobbyVtbl dpl_vt = 1908 { 1909 IDirectPlayLobbyImpl_QueryInterface, 1910 IDirectPlayLobbyImpl_AddRef, 1911 IDirectPlayLobbyImpl_Release, 1912 IDirectPlayLobbyImpl_Connect, 1913 IDirectPlayLobbyImpl_CreateAddress, 1914 IDirectPlayLobbyImpl_EnumAddress, 1915 IDirectPlayLobbyImpl_EnumAddressTypes, 1916 IDirectPlayLobbyImpl_EnumLocalApplications, 1917 IDirectPlayLobbyImpl_GetConnectionSettings, 1918 IDirectPlayLobbyImpl_ReceiveLobbyMessage, 1919 IDirectPlayLobbyImpl_RunApplication, 1920 IDirectPlayLobbyImpl_SendLobbyMessage, 1921 IDirectPlayLobbyImpl_SetConnectionSettings, 1922 IDirectPlayLobbyImpl_SetLobbyMessageEvent 1923 }; 1924 1925 static const IDirectPlayLobby2Vtbl dpl2A_vt = 1926 { 1927 IDirectPlayLobby2AImpl_QueryInterface, 1928 IDirectPlayLobby2AImpl_AddRef, 1929 IDirectPlayLobby2AImpl_Release, 1930 IDirectPlayLobby2AImpl_Connect, 1931 IDirectPlayLobby2AImpl_CreateAddress, 1932 IDirectPlayLobby2AImpl_EnumAddress, 1933 IDirectPlayLobby2AImpl_EnumAddressTypes, 1934 IDirectPlayLobby2AImpl_EnumLocalApplications, 1935 IDirectPlayLobby2AImpl_GetConnectionSettings, 1936 IDirectPlayLobby2AImpl_ReceiveLobbyMessage, 1937 IDirectPlayLobby2AImpl_RunApplication, 1938 IDirectPlayLobby2AImpl_SendLobbyMessage, 1939 IDirectPlayLobby2AImpl_SetConnectionSettings, 1940 IDirectPlayLobby2AImpl_SetLobbyMessageEvent, 1941 IDirectPlayLobby2AImpl_CreateCompoundAddress 1942 }; 1943 1944 static const IDirectPlayLobby2Vtbl dpl2_vt = 1945 { 1946 IDirectPlayLobby2Impl_QueryInterface, 1947 IDirectPlayLobby2Impl_AddRef, 1948 IDirectPlayLobby2Impl_Release, 1949 IDirectPlayLobby2Impl_Connect, 1950 IDirectPlayLobby2Impl_CreateAddress, 1951 IDirectPlayLobby2Impl_EnumAddress, 1952 IDirectPlayLobby2Impl_EnumAddressTypes, 1953 IDirectPlayLobby2Impl_EnumLocalApplications, 1954 IDirectPlayLobby2Impl_GetConnectionSettings, 1955 IDirectPlayLobby2Impl_ReceiveLobbyMessage, 1956 IDirectPlayLobby2Impl_RunApplication, 1957 IDirectPlayLobby2Impl_SendLobbyMessage, 1958 IDirectPlayLobby2Impl_SetConnectionSettings, 1959 IDirectPlayLobby2Impl_SetLobbyMessageEvent, 1960 IDirectPlayLobby2Impl_CreateCompoundAddress 1961 }; 1962 1963 static const IDirectPlayLobby3Vtbl dpl3A_vt = 1964 { 1965 IDirectPlayLobby3AImpl_QueryInterface, 1966 IDirectPlayLobby3AImpl_AddRef, 1967 IDirectPlayLobby3AImpl_Release, 1968 IDirectPlayLobby3AImpl_Connect, 1969 IDirectPlayLobby3AImpl_CreateAddress, 1970 IDirectPlayLobby3AImpl_EnumAddress, 1971 IDirectPlayLobby3AImpl_EnumAddressTypes, 1972 IDirectPlayLobby3AImpl_EnumLocalApplications, 1973 IDirectPlayLobby3AImpl_GetConnectionSettings, 1974 IDirectPlayLobby3AImpl_ReceiveLobbyMessage, 1975 IDirectPlayLobby3AImpl_RunApplication, 1976 IDirectPlayLobby3AImpl_SendLobbyMessage, 1977 IDirectPlayLobby3AImpl_SetConnectionSettings, 1978 IDirectPlayLobby3AImpl_SetLobbyMessageEvent, 1979 IDirectPlayLobby3AImpl_CreateCompoundAddress, 1980 IDirectPlayLobby3AImpl_ConnectEx, 1981 IDirectPlayLobby3AImpl_RegisterApplication, 1982 IDirectPlayLobby3AImpl_UnregisterApplication, 1983 IDirectPlayLobby3AImpl_WaitForConnectionSettings 1984 }; 1985 1986 static const IDirectPlayLobby3Vtbl dpl3_vt = 1987 { 1988 IDirectPlayLobby3Impl_QueryInterface, 1989 IDirectPlayLobby3Impl_AddRef, 1990 IDirectPlayLobby3Impl_Release, 1991 IDirectPlayLobby3Impl_Connect, 1992 IDirectPlayLobby3Impl_CreateAddress, 1993 IDirectPlayLobby3Impl_EnumAddress, 1994 IDirectPlayLobby3Impl_EnumAddressTypes, 1995 IDirectPlayLobby3Impl_EnumLocalApplications, 1996 IDirectPlayLobby3Impl_GetConnectionSettings, 1997 IDirectPlayLobby3Impl_ReceiveLobbyMessage, 1998 IDirectPlayLobby3Impl_RunApplication, 1999 IDirectPlayLobby3Impl_SendLobbyMessage, 2000 IDirectPlayLobby3Impl_SetConnectionSettings, 2001 IDirectPlayLobby3Impl_SetLobbyMessageEvent, 2002 IDirectPlayLobby3Impl_CreateCompoundAddress, 2003 IDirectPlayLobby3Impl_ConnectEx, 2004 IDirectPlayLobby3Impl_RegisterApplication, 2005 IDirectPlayLobby3Impl_UnregisterApplication, 2006 IDirectPlayLobby3Impl_WaitForConnectionSettings 2007 }; 2008 2009 HRESULT dplobby_create( REFIID riid, void **ppv ) 2010 { 2011 IDirectPlayLobbyImpl *obj; 2012 HRESULT hr; 2013 2014 TRACE( "(%s, %p)\n", debugstr_guid( riid ), ppv ); 2015 2016 *ppv = NULL; 2017 obj = HeapAlloc( GetProcessHeap(), 0, sizeof( *obj ) ); 2018 if ( !obj ) 2019 return DPERR_OUTOFMEMORY; 2020 2021 obj->IDirectPlayLobby_iface.lpVtbl = &dpl_vt; 2022 obj->IDirectPlayLobbyA_iface.lpVtbl = &dplA_vt; 2023 obj->IDirectPlayLobby2_iface.lpVtbl = &dpl2_vt; 2024 obj->IDirectPlayLobby2A_iface.lpVtbl = &dpl2A_vt; 2025 obj->IDirectPlayLobby3_iface.lpVtbl = &dpl3_vt; 2026 obj->IDirectPlayLobby3A_iface.lpVtbl = &dpl3A_vt; 2027 obj->numIfaces = 1; 2028 obj->msgtid = 0; 2029 obj->ref = 0; 2030 obj->refA = 0; 2031 obj->ref2 = 0; 2032 obj->ref2A = 0; 2033 obj->ref3 = 1; 2034 obj->ref3A = 0; 2035 2036 InitializeCriticalSection( &obj->lock ); 2037 obj->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IDirectPlayLobbyImpl.lock"); 2038 DPQ_INIT( obj->msgs ); 2039 2040 hr = IDirectPlayLobby_QueryInterface( &obj->IDirectPlayLobby3_iface, riid, ppv ); 2041 IDirectPlayLobby_Release( &obj->IDirectPlayLobby3_iface ); 2042 2043 return hr; 2044 } 2045 2046 2047 2048 /*************************************************************************** 2049 * DirectPlayLobbyCreateA (DPLAYX.4) 2050 * 2051 */ 2052 HRESULT WINAPI DirectPlayLobbyCreateA( GUID *lpGUIDDSP, IDirectPlayLobbyA **lplpDPL, 2053 IUnknown *lpUnk, void *lpData, DWORD dwDataSize ) 2054 { 2055 TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08x\n", 2056 lpGUIDDSP,lplpDPL,lpUnk,lpData,dwDataSize); 2057 2058 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must 2059 * equal 0. These fields are mostly for future expansion. 2060 */ 2061 if ( lpGUIDDSP || lpData || dwDataSize ) 2062 { 2063 *lplpDPL = NULL; 2064 return DPERR_INVALIDPARAMS; 2065 } 2066 2067 if( lpUnk ) 2068 { 2069 *lplpDPL = NULL; 2070 ERR("Bad parameters!\n" ); 2071 return CLASS_E_NOAGGREGATION; 2072 } 2073 2074 return dplobby_create( &IID_IDirectPlayLobbyA, (void**)lplpDPL ); 2075 } 2076 2077 /*************************************************************************** 2078 * DirectPlayLobbyCreateW (DPLAYX.5) 2079 * 2080 */ 2081 HRESULT WINAPI DirectPlayLobbyCreateW( GUID *lpGUIDDSP, IDirectPlayLobby **lplpDPL, 2082 IUnknown *lpUnk, void *lpData, DWORD dwDataSize ) 2083 { 2084 TRACE("lpGUIDDSP=%p lplpDPL=%p lpUnk=%p lpData=%p dwDataSize=%08x\n", 2085 lpGUIDDSP,lplpDPL,lpUnk,lpData,dwDataSize); 2086 2087 /* Parameter Check: lpGUIDSP, lpUnk & lpData must be NULL. dwDataSize must 2088 * equal 0. These fields are mostly for future expansion. 2089 */ 2090 if ( lpGUIDDSP || lpData || dwDataSize ) 2091 { 2092 *lplpDPL = NULL; 2093 ERR("Bad parameters!\n" ); 2094 return DPERR_INVALIDPARAMS; 2095 } 2096 2097 if( lpUnk ) 2098 { 2099 *lplpDPL = NULL; 2100 ERR("Bad parameters!\n" ); 2101 return CLASS_E_NOAGGREGATION; 2102 } 2103 2104 return dplobby_create( &IID_IDirectPlayLobby, (void**)lplpDPL ); 2105 } 2106