Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendplaysp.c
Go to the documentation of this file.
00001 /* This contains the implementation of the interface Service 00002 * Providers require to communicate with Direct Play 00003 * 00004 * Copyright 2000 Peter Hunnisett 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 */ 00020 00021 #include <string.h> 00022 #include "winerror.h" 00023 #include "wine/debug.h" 00024 00025 #include "dpinit.h" 00026 #include "dplaysp.h" 00027 #include "dplay_global.h" 00028 #include "name_server.h" 00029 #include "dplayx_messages.h" 00030 00031 #include "dplayx_global.h" /* FIXME: For global hack */ 00032 00033 /* FIXME: Need to add interface locking inside procedures */ 00034 00035 WINE_DEFAULT_DEBUG_CHANNEL(dplay); 00036 00037 /* Prototypes */ 00038 static BOOL DPSP_CreateIUnknown( LPVOID lpSP ); 00039 static BOOL DPSP_DestroyIUnknown( LPVOID lpSP ); 00040 static BOOL DPSP_CreateDirectPlaySP( LPVOID lpSP, IDirectPlay2Impl* dp ); 00041 static BOOL DPSP_DestroyDirectPlaySP( LPVOID lpSP ); 00042 00043 /* Predefine the interface */ 00044 typedef struct IDirectPlaySPImpl IDirectPlaySPImpl; 00045 00046 typedef struct tagDirectPlaySPIUnknownData 00047 { 00048 LONG ulObjRef; 00049 CRITICAL_SECTION DPSP_lock; 00050 } DirectPlaySPIUnknownData; 00051 00052 typedef struct tagDirectPlaySPData 00053 { 00054 LPVOID lpSpRemoteData; 00055 DWORD dwSpRemoteDataSize; /* Size of data pointed to by lpSpRemoteData */ 00056 00057 LPVOID lpSpLocalData; 00058 DWORD dwSpLocalDataSize; /* Size of data pointed to by lpSpLocalData */ 00059 00060 IDirectPlay2Impl* dplay; /* FIXME: This should perhaps be iface not impl */ 00061 00062 } DirectPlaySPData; 00063 00064 #define DPSP_IMPL_FIELDS \ 00065 LONG ulInterfaceRef; \ 00066 DirectPlaySPIUnknownData* unk; \ 00067 DirectPlaySPData* sp; 00068 00069 struct IDirectPlaySPImpl 00070 { 00071 const IDirectPlaySPVtbl *lpVtbl; 00072 DPSP_IMPL_FIELDS 00073 }; 00074 00075 /* Forward declaration of virtual tables */ 00076 static const IDirectPlaySPVtbl directPlaySPVT; 00077 00078 /* This structure is passed to the DP object for safe keeping */ 00079 typedef struct tagDP_SPPLAYERDATA 00080 { 00081 LPVOID lpPlayerLocalData; 00082 DWORD dwPlayerLocalDataSize; 00083 00084 LPVOID lpPlayerRemoteData; 00085 DWORD dwPlayerRemoteDataSize; 00086 } DP_SPPLAYERDATA, *LPDP_SPPLAYERDATA; 00087 00088 /* Create the SP interface */ 00089 extern 00090 HRESULT DPSP_CreateInterface( REFIID riid, LPVOID* ppvObj, IDirectPlay2Impl* dp ) 00091 { 00092 TRACE( " for %s\n", debugstr_guid( riid ) ); 00093 00094 *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 00095 sizeof( IDirectPlaySPImpl ) ); 00096 00097 if( *ppvObj == NULL ) 00098 { 00099 return DPERR_OUTOFMEMORY; 00100 } 00101 00102 if( IsEqualGUID( &IID_IDirectPlaySP, riid ) ) 00103 { 00104 IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)*ppvObj; 00105 This->lpVtbl = &directPlaySPVT; 00106 } 00107 else 00108 { 00109 /* Unsupported interface */ 00110 HeapFree( GetProcessHeap(), 0, *ppvObj ); 00111 *ppvObj = NULL; 00112 00113 return E_NOINTERFACE; 00114 } 00115 00116 /* Initialize it */ 00117 if( DPSP_CreateIUnknown( *ppvObj ) && 00118 DPSP_CreateDirectPlaySP( *ppvObj, dp ) 00119 ) 00120 { 00121 IDirectPlaySP_AddRef( (LPDIRECTPLAYSP)*ppvObj ); 00122 return S_OK; 00123 } 00124 00125 /* Initialize failed, destroy it */ 00126 DPSP_DestroyDirectPlaySP( *ppvObj ); 00127 DPSP_DestroyIUnknown( *ppvObj ); 00128 00129 HeapFree( GetProcessHeap(), 0, *ppvObj ); 00130 *ppvObj = NULL; 00131 00132 return DPERR_NOMEMORY; 00133 } 00134 00135 static BOOL DPSP_CreateIUnknown( LPVOID lpSP ) 00136 { 00137 IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)lpSP; 00138 00139 This->unk = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( *(This->unk) ) ); 00140 00141 if ( This->unk == NULL ) 00142 { 00143 return FALSE; 00144 } 00145 00146 InitializeCriticalSection( &This->unk->DPSP_lock ); 00147 00148 return TRUE; 00149 } 00150 00151 static BOOL DPSP_DestroyIUnknown( LPVOID lpSP ) 00152 { 00153 IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)lpSP; 00154 00155 DeleteCriticalSection( &This->unk->DPSP_lock ); 00156 HeapFree( GetProcessHeap(), 0, This->unk ); 00157 00158 return TRUE; 00159 } 00160 00161 00162 static BOOL DPSP_CreateDirectPlaySP( LPVOID lpSP, IDirectPlay2Impl* dp ) 00163 { 00164 IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)lpSP; 00165 00166 This->sp = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( *(This->sp) ) ); 00167 00168 if ( This->sp == NULL ) 00169 { 00170 return FALSE; 00171 } 00172 00173 This->sp->dplay = dp; 00174 00175 /* Normally we should be keeping a reference, but since only the dplay 00176 * interface that created us can destroy us, we do not keep a reference 00177 * to it (ie we'd be stuck with always having one reference to the dplay 00178 * object, and hence us, around). 00179 * NOTE: The dp object does reference count us. 00180 * 00181 * FIXME: This is a kludge to get around a problem where a queryinterface 00182 * is used to get a new interface and then is closed. We will then 00183 * reference garbage. However, with this we will never deallocate 00184 * the interface we store. The correct fix is to require all 00185 * DP internal interfaces to use the This->dp2 interface which 00186 * should be changed to This->dp 00187 */ 00188 IDirectPlayX_AddRef( (LPDIRECTPLAY2)dp ); 00189 00190 return TRUE; 00191 } 00192 00193 static BOOL DPSP_DestroyDirectPlaySP( LPVOID lpSP ) 00194 { 00195 IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)lpSP; 00196 00197 /* Normally we should be keeping a reference, but since only the dplay 00198 * interface that created us can destroy us, we do not keep a reference 00199 * to it (ie we'd be stuck with always having one reference to the dplay 00200 * object, and hence us, around). 00201 * NOTE: The dp object does reference count us. 00202 */ 00203 /*IDirectPlayX_Release( (LPDIRECTPLAY2)This->sp->dplay ); */ 00204 00205 HeapFree( GetProcessHeap(), 0, This->sp->lpSpRemoteData ); 00206 HeapFree( GetProcessHeap(), 0, This->sp->lpSpLocalData ); 00207 00208 /* FIXME: Need to delete player queue */ 00209 00210 HeapFree( GetProcessHeap(), 0, This->sp ); 00211 return TRUE; 00212 } 00213 00214 /* Interface implementation */ 00215 00216 static HRESULT WINAPI DPSP_QueryInterface 00217 ( LPDIRECTPLAYSP iface, 00218 REFIID riid, 00219 LPVOID* ppvObj ) 00220 { 00221 IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface; 00222 TRACE("(%p)->(%s,%p)\n", This, debugstr_guid( riid ), ppvObj ); 00223 00224 *ppvObj = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 00225 sizeof( *This ) ); 00226 00227 if( *ppvObj == NULL ) 00228 { 00229 return DPERR_OUTOFMEMORY; 00230 } 00231 00232 CopyMemory( *ppvObj, This, sizeof( *This ) ); 00233 (*(IDirectPlaySPImpl**)ppvObj)->ulInterfaceRef = 0; 00234 00235 if( IsEqualGUID( &IID_IDirectPlaySP, riid ) ) 00236 { 00237 IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)*ppvObj; 00238 This->lpVtbl = &directPlaySPVT; 00239 } 00240 else 00241 { 00242 /* Unsupported interface */ 00243 HeapFree( GetProcessHeap(), 0, *ppvObj ); 00244 *ppvObj = NULL; 00245 00246 return E_NOINTERFACE; 00247 } 00248 00249 IDirectPlaySP_AddRef( (LPDIRECTPLAYSP)*ppvObj ); 00250 00251 return S_OK; 00252 } 00253 00254 static ULONG WINAPI DPSP_AddRef 00255 ( LPDIRECTPLAYSP iface ) 00256 { 00257 ULONG ulInterfaceRefCount, ulObjRefCount; 00258 IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface; 00259 00260 ulObjRefCount = InterlockedIncrement( &This->unk->ulObjRef ); 00261 ulInterfaceRefCount = InterlockedIncrement( &This->ulInterfaceRef ); 00262 00263 TRACE( "ref count incremented to %lu:%lu for %p\n", 00264 ulInterfaceRefCount, ulObjRefCount, This ); 00265 00266 return ulObjRefCount; 00267 } 00268 00269 static ULONG WINAPI DPSP_Release 00270 ( LPDIRECTPLAYSP iface ) 00271 { 00272 ULONG ulInterfaceRefCount, ulObjRefCount; 00273 IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface; 00274 00275 ulObjRefCount = InterlockedDecrement( &This->unk->ulObjRef ); 00276 ulInterfaceRefCount = InterlockedDecrement( &This->ulInterfaceRef ); 00277 00278 TRACE( "ref count decremented to %lu:%lu for %p\n", 00279 ulInterfaceRefCount, ulObjRefCount, This ); 00280 00281 /* Deallocate if this is the last reference to the object */ 00282 if( ulObjRefCount == 0 ) 00283 { 00284 DPSP_DestroyDirectPlaySP( This ); 00285 DPSP_DestroyIUnknown( This ); 00286 } 00287 00288 if( ulInterfaceRefCount == 0 ) 00289 { 00290 HeapFree( GetProcessHeap(), 0, This ); 00291 } 00292 00293 return ulInterfaceRefCount; 00294 } 00295 00296 static HRESULT WINAPI IDirectPlaySPImpl_AddMRUEntry 00297 ( LPDIRECTPLAYSP iface, 00298 LPCWSTR lpSection, 00299 LPCWSTR lpKey, 00300 LPCVOID lpData, 00301 DWORD dwDataSize, 00302 DWORD dwMaxEntries 00303 ) 00304 { 00305 IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface; 00306 00307 /* Should be able to call the comctl32 undocumented MRU routines. 00308 I suspect that the interface works appropriately */ 00309 FIXME( "(%p)->(%p,%p%p,0x%08lx,0x%08lx): stub\n", 00310 This, lpSection, lpKey, lpData, dwDataSize, dwMaxEntries ); 00311 00312 return DP_OK; 00313 } 00314 00315 static HRESULT WINAPI IDirectPlaySPImpl_CreateAddress 00316 ( LPDIRECTPLAYSP iface, 00317 REFGUID guidSP, 00318 REFGUID guidDataType, 00319 LPCVOID lpData, 00320 DWORD dwDataSize, 00321 LPVOID lpAddress, 00322 LPDWORD lpdwAddressSize 00323 ) 00324 { 00325 IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface; 00326 00327 FIXME( "(%p)->(%s,%s,%p,0x%08lx,%p,%p): stub\n", 00328 This, debugstr_guid(guidSP), debugstr_guid(guidDataType), 00329 lpData, dwDataSize, lpAddress, lpdwAddressSize ); 00330 00331 return DP_OK; 00332 } 00333 00334 static HRESULT WINAPI IDirectPlaySPImpl_EnumAddress 00335 ( LPDIRECTPLAYSP iface, 00336 LPDPENUMADDRESSCALLBACK lpEnumAddressCallback, 00337 LPCVOID lpAddress, 00338 DWORD dwAddressSize, 00339 LPVOID lpContext 00340 ) 00341 { 00342 IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface; 00343 00344 TRACE( "(%p)->(%p,%p,0x%08lx,%p)\n", 00345 This, lpEnumAddressCallback, lpAddress, dwAddressSize, lpContext ); 00346 00347 DPL_EnumAddress( lpEnumAddressCallback, lpAddress, dwAddressSize, lpContext ); 00348 00349 return DP_OK; 00350 } 00351 00352 static HRESULT WINAPI IDirectPlaySPImpl_EnumMRUEntries 00353 ( LPDIRECTPLAYSP iface, 00354 LPCWSTR lpSection, 00355 LPCWSTR lpKey, 00356 LPENUMMRUCALLBACK lpEnumMRUCallback, 00357 LPVOID lpContext 00358 ) 00359 { 00360 IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface; 00361 00362 /* Should be able to call the comctl32 undocumented MRU routines. 00363 I suspect that the interface works appropriately */ 00364 FIXME( "(%p)->(%p,%p,%p,%p,): stub\n", 00365 This, lpSection, lpKey, lpEnumMRUCallback, lpContext ); 00366 00367 return DP_OK; 00368 } 00369 00370 static HRESULT WINAPI IDirectPlaySPImpl_GetPlayerFlags 00371 ( LPDIRECTPLAYSP iface, 00372 DPID idPlayer, 00373 LPDWORD lpdwPlayerFlags 00374 ) 00375 { 00376 IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface; 00377 00378 FIXME( "(%p)->(0x%08lx,%p): stub\n", 00379 This, idPlayer, lpdwPlayerFlags ); 00380 00381 return DP_OK; 00382 } 00383 00384 static HRESULT WINAPI IDirectPlaySPImpl_GetSPPlayerData 00385 ( LPDIRECTPLAYSP iface, 00386 DPID idPlayer, 00387 LPVOID* lplpData, 00388 LPDWORD lpdwDataSize, 00389 DWORD dwFlags 00390 ) 00391 { 00392 HRESULT hr; 00393 LPDP_SPPLAYERDATA lpPlayerData; 00394 IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface; 00395 00396 TRACE( "(%p)->(0x%08lx,%p,%p,0x%08lx)\n", 00397 This, idPlayer, lplpData, lpdwDataSize, dwFlags ); 00398 00399 hr = DP_GetSPPlayerData( This->sp->dplay, idPlayer, (LPVOID*)&lpPlayerData ); 00400 00401 if( FAILED(hr) ) 00402 { 00403 TRACE( "Couldn't get player data: %s\n", DPLAYX_HresultToString(hr) ); 00404 return DPERR_INVALIDPLAYER; 00405 } 00406 00407 /* What to do in the case where there is nothing set yet? */ 00408 if( dwFlags == DPSET_LOCAL ) 00409 { 00410 HeapFree( GetProcessHeap(), 0, lpPlayerData->lpPlayerLocalData ); 00411 *lplpData = lpPlayerData->lpPlayerLocalData; 00412 *lpdwDataSize = lpPlayerData->dwPlayerLocalDataSize; 00413 } 00414 else if( dwFlags == DPSET_REMOTE ) 00415 { 00416 HeapFree( GetProcessHeap(), 0, lpPlayerData->lpPlayerRemoteData ); 00417 *lplpData = lpPlayerData->lpPlayerRemoteData; 00418 *lpdwDataSize = lpPlayerData->dwPlayerRemoteDataSize; 00419 } 00420 00421 if( *lplpData == NULL ) 00422 { 00423 hr = DPERR_GENERIC; 00424 } 00425 00426 return hr; 00427 } 00428 00429 static HRESULT WINAPI IDirectPlaySPImpl_HandleMessage 00430 ( LPDIRECTPLAYSP iface, 00431 LPVOID lpMessageBody, 00432 DWORD dwMessageBodySize, 00433 LPVOID lpMessageHeader 00434 ) 00435 { 00436 LPDPMSG_SENDENVELOPE lpMsg = (LPDPMSG_SENDENVELOPE)lpMessageBody; 00437 HRESULT hr = DPERR_GENERIC; 00438 WORD wCommandId; 00439 WORD wVersion; 00440 DPSP_REPLYDATA data; 00441 00442 IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface; 00443 00444 FIXME( "(%p)->(%p,0x%08lx,%p): mostly stub\n", 00445 This, lpMessageBody, dwMessageBodySize, lpMessageHeader ); 00446 00447 wCommandId = lpMsg->wCommandId; 00448 wVersion = lpMsg->wVersion; 00449 00450 TRACE( "Incoming message has envelope of 0x%08lx, %u, %u\n", 00451 lpMsg->dwMagic, wCommandId, wVersion ); 00452 00453 if( lpMsg->dwMagic != DPMSGMAGIC_DPLAYMSG ) 00454 { 00455 ERR( "Unknown magic 0x%08lx!\n", lpMsg->dwMagic ); 00456 return DPERR_GENERIC; 00457 } 00458 00459 #if 0 00460 { 00461 const LPDWORD lpcHeader = (LPDWORD)lpMessageHeader; 00462 00463 TRACE( "lpMessageHeader = [0x%08lx] [0x%08lx] [0x%08lx] [0x%08lx] [0x%08lx]\n", 00464 lpcHeader[0], lpcHeader[1], lpcHeader[2], lpcHeader[3], lpcHeader[4] ); 00465 } 00466 #endif 00467 00468 /* Pass everything else to Direct Play */ 00469 data.lpMessage = NULL; 00470 data.dwMessageSize = 0; 00471 00472 /* Pass this message to the dplay interface to handle */ 00473 hr = DP_HandleMessage( This->sp->dplay, lpMessageBody, dwMessageBodySize, 00474 lpMessageHeader, wCommandId, wVersion, 00475 &data.lpMessage, &data.dwMessageSize ); 00476 00477 if( FAILED(hr) ) 00478 { 00479 ERR( "Command processing failed %s\n", DPLAYX_HresultToString(hr) ); 00480 } 00481 00482 /* Do we want a reply? */ 00483 if( data.lpMessage != NULL ) 00484 { 00485 data.lpSPMessageHeader = lpMessageHeader; 00486 data.idNameServer = 0; 00487 data.lpISP = iface; 00488 00489 hr = (This->sp->dplay->dp2->spData.lpCB->Reply)( &data ); 00490 00491 if( FAILED(hr) ) 00492 { 00493 ERR( "Reply failed %s\n", DPLAYX_HresultToString(hr) ); 00494 } 00495 } 00496 00497 return hr; 00498 00499 #if 0 00500 HRESULT hr = DP_OK; 00501 HANDLE hReceiveEvent = 0; 00502 /* FIXME: Aquire some sort of interface lock */ 00503 /* FIXME: Need some sort of context for this callback. Need to determine 00504 * how this is actually done with the SP 00505 */ 00506 /* FIXME: Who needs to delete the message when done? */ 00507 switch( lpMsg->dwType ) 00508 { 00509 case DPSYS_CREATEPLAYERORGROUP: 00510 { 00511 LPDPMSG_CREATEPLAYERORGROUP msg = (LPDPMSG_CREATEPLAYERORGROUP)lpMsg; 00512 00513 if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER ) 00514 { 00515 hr = DP_IF_CreatePlayer( This, lpMessageHeader, msg->dpId, 00516 &msg->dpnName, 0, msg->lpData, 00517 msg->dwDataSize, msg->dwFlags, ... ); 00518 } 00519 else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP ) 00520 { 00521 /* Group in group situation? */ 00522 if( msg->dpIdParent == DPID_NOPARENT_GROUP ) 00523 { 00524 hr = DP_IF_CreateGroup( This, lpMessageHeader, msg->dpId, 00525 &msg->dpnName, 0, msg->lpData, 00526 msg->dwDataSize, msg->dwFlags, ... ); 00527 } 00528 else /* Group in Group */ 00529 { 00530 hr = DP_IF_CreateGroupInGroup( This, lpMessageHeader, msg->dpIdParent, 00531 &msg->dpnName, 0, msg->lpData, 00532 msg->dwDataSize, msg->dwFlags, ... ); 00533 } 00534 } 00535 else /* Hmmm? */ 00536 { 00537 ERR( "Corrupt msg->dwPlayerType for DPSYS_CREATEPLAYERORGROUP\n" ); 00538 return; 00539 } 00540 00541 break; 00542 } 00543 00544 case DPSYS_DESTROYPLAYERORGROUP: 00545 { 00546 LPDPMSG_DESTROYPLAYERORGROUP msg = (LPDPMSG_DESTROYPLAYERORGROUP)lpMsg; 00547 00548 if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER ) 00549 { 00550 hr = DP_IF_DestroyPlayer( This, msg->dpId, ... ); 00551 } 00552 else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP ) 00553 { 00554 hr = DP_IF_DestroyGroup( This, msg->dpId, ... ); 00555 } 00556 else /* Hmmm? */ 00557 { 00558 ERR( "Corrupt msg->dwPlayerType for DPSYS_DESTROYPLAYERORGROUP\n" ); 00559 return; 00560 } 00561 00562 break; 00563 } 00564 00565 case DPSYS_ADDPLAYERTOGROUP: 00566 { 00567 LPDPMSG_ADDPLAYERTOGROUP msg = (LPDPMSG_ADDPLAYERTOGROUP)lpMsg; 00568 00569 hr = DP_IF_AddPlayerToGroup( This, msg->dpIdGroup, msg->dpIdPlayer, ... ); 00570 break; 00571 } 00572 00573 case DPSYS_DELETEPLAYERFROMGROUP: 00574 { 00575 LPDPMSG_DELETEPLAYERFROMGROUP msg = (LPDPMSG_DELETEPLAYERFROMGROUP)lpMsg; 00576 00577 hr = DP_IF_DeletePlayerFromGroup( This, msg->dpIdGroup, msg->dpIdPlayer, 00578 ... ); 00579 00580 break; 00581 } 00582 00583 case DPSYS_SESSIONLOST: 00584 { 00585 LPDPMSG_SESSIONLOST msg = (LPDPMSG_SESSIONLOST)lpMsg; 00586 00587 FIXME( "DPSYS_SESSIONLOST not handled\n" ); 00588 00589 break; 00590 } 00591 00592 case DPSYS_HOST: 00593 { 00594 LPDPMSG_HOST msg = (LPDPMSG_HOST)lpMsg; 00595 00596 FIXME( "DPSYS_HOST not handled\n" ); 00597 00598 break; 00599 } 00600 00601 case DPSYS_SETPLAYERORGROUPDATA: 00602 { 00603 LPDPMSG_SETPLAYERORGROUPDATA msg = (LPDPMSG_SETPLAYERORGROUPDATA)lpMsg; 00604 00605 if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER ) 00606 { 00607 hr = DP_IF_SetPlayerData( This, msg->dpId, msg->lpData, msg->dwDataSize, DPSET_REMOTE, ... ); 00608 } 00609 else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP ) 00610 { 00611 hr = DP_IF_SetGroupData( This, msg->dpId, msg->lpData, msg->dwDataSize, 00612 DPSET_REMOTE, ... ); 00613 } 00614 else /* Hmmm? */ 00615 { 00616 ERR( "Corrupt msg->dwPlayerType for LPDPMSG_SETPLAYERORGROUPDATA\n" ); 00617 return; 00618 } 00619 00620 break; 00621 } 00622 00623 case DPSYS_SETPLAYERORGROUPNAME: 00624 { 00625 LPDPMSG_SETPLAYERORGROUPNAME msg = (LPDPMSG_SETPLAYERORGROUPNAME)lpMsg; 00626 00627 if( msg->dwPlayerType == DPPLAYERTYPE_PLAYER ) 00628 { 00629 hr = DP_IF_SetPlayerName( This, msg->dpId, msg->dpnName, ... ); 00630 } 00631 else if( msg->dwPlayerType == DPPLAYERTYPE_GROUP ) 00632 { 00633 hr = DP_IF_SetGroupName( This, msg->dpId, msg->dpnName, ... ); 00634 } 00635 else /* Hmmm? */ 00636 { 00637 ERR( "Corrupt msg->dwPlayerType for LPDPMSG_SETPLAYERORGROUPDATA\n" ); 00638 return; 00639 } 00640 00641 break; 00642 } 00643 00644 case DPSYS_SETSESSIONDESC; 00645 { 00646 LPDPMSG_SETSESSIONDESC msg = (LPDPMSG_SETSESSIONDESC)lpMsg; 00647 00648 hr = DP_IF_SetSessionDesc( This, &msg->dpDesc ); 00649 00650 break; 00651 } 00652 00653 case DPSYS_ADDGROUPTOGROUP: 00654 { 00655 LPDPMSG_ADDGROUPTOGROUP msg = (LPDPMSG_ADDGROUPTOGROUP)lpMsg; 00656 00657 hr = DP_IF_AddGroupToGroup( This, msg->dpIdParentGroup, msg->dpIdGroup, 00658 ... ); 00659 00660 break; 00661 } 00662 00663 case DPSYS_DELETEGROUPFROMGROUP: 00664 { 00665 LPDPMSG_DELETEGROUPFROMGROUP msg = (LPDPMSG_DELETEGROUPFROMGROUP)lpMsg; 00666 00667 hr = DP_IF_DeleteGroupFromGroup( This, msg->dpIdParentGroup, 00668 msg->dpIdGroup, ... ); 00669 00670 break; 00671 } 00672 00673 case DPSYS_SECUREMESSAGE: 00674 { 00675 LPDPMSG_SECUREMESSAGE msg = (LPDPMSG_SECUREMESSAGE)lpMsg; 00676 00677 FIXME( "DPSYS_SECUREMESSAGE not implemented\n" ); 00678 00679 break; 00680 } 00681 00682 case DPSYS_STARTSESSION: 00683 { 00684 LPDPMSG_STARTSESSION msg = (LPDPMSG_STARTSESSION)lpMsg; 00685 00686 FIXME( "DPSYS_STARTSESSION not implemented\n" ); 00687 00688 break; 00689 } 00690 00691 case DPSYS_CHAT: 00692 { 00693 LPDPMSG_CHAT msg = (LPDPMSG_CHAT)lpMsg; 00694 00695 FIXME( "DPSYS_CHAT not implemeneted\n" ); 00696 00697 break; 00698 } 00699 00700 case DPSYS_SETGROUPOWNER: 00701 { 00702 LPDPMSG_SETGROUPOWNER msg = (LPDPMSG_SETGROUPOWNER)lpMsg; 00703 00704 FIXME( "DPSYS_SETGROUPOWNER not implemented\n" ); 00705 00706 break; 00707 } 00708 00709 case DPSYS_SENDCOMPLETE: 00710 { 00711 LPDPMSG_SENDCOMPLETE msg = (LPDPMSG_SENDCOMPLETE)lpMsg; 00712 00713 FIXME( "DPSYS_SENDCOMPLETE not implemented\n" ); 00714 00715 break; 00716 } 00717 00718 default: 00719 { 00720 /* NOTE: This should be a user defined type. There is nothing that we 00721 * need to do with it except queue it. 00722 */ 00723 TRACE( "Received user message type(?) 0x%08lx through SP.\n", 00724 lpMsg->dwType ); 00725 break; 00726 } 00727 } 00728 00729 FIXME( "Queue message in the receive queue. Need some context data!\n" ); 00730 00731 if( FAILED(hr) ) 00732 { 00733 ERR( "Unable to perform action for msg type 0x%08lx\n", lpMsg->dwType ); 00734 } 00735 /* If a receive event was registered for this player, invoke it */ 00736 if( hReceiveEvent ) 00737 { 00738 SetEvent( hReceiveEvent ); 00739 } 00740 #endif 00741 } 00742 00743 static HRESULT WINAPI IDirectPlaySPImpl_SetSPPlayerData 00744 ( LPDIRECTPLAYSP iface, 00745 DPID idPlayer, 00746 LPVOID lpData, 00747 DWORD dwDataSize, 00748 DWORD dwFlags 00749 ) 00750 { 00751 HRESULT hr; 00752 LPDP_SPPLAYERDATA lpPlayerEntry; 00753 LPVOID lpPlayerData; 00754 00755 IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface; 00756 00757 /* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */ 00758 TRACE( "(%p)->(0x%08lx,%p,0x%08lx,0x%08lx)\n", 00759 This, idPlayer, lpData, dwDataSize, dwFlags ); 00760 00761 hr = DP_GetSPPlayerData( This->sp->dplay, idPlayer, (LPVOID*)&lpPlayerEntry ); 00762 if( FAILED(hr) ) 00763 { 00764 /* Player must not exist */ 00765 return DPERR_INVALIDPLAYER; 00766 } 00767 00768 lpPlayerData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize ); 00769 CopyMemory( lpPlayerData, lpData, dwDataSize ); 00770 00771 if( dwFlags == DPSET_LOCAL ) 00772 { 00773 lpPlayerEntry->lpPlayerLocalData = lpPlayerData; 00774 lpPlayerEntry->dwPlayerLocalDataSize = dwDataSize; 00775 } 00776 else if( dwFlags == DPSET_REMOTE ) 00777 { 00778 lpPlayerEntry->lpPlayerRemoteData = lpPlayerData; 00779 lpPlayerEntry->dwPlayerRemoteDataSize = dwDataSize; 00780 } 00781 00782 hr = DP_SetSPPlayerData( This->sp->dplay, idPlayer, lpPlayerEntry ); 00783 00784 return hr; 00785 } 00786 00787 static HRESULT WINAPI IDirectPlaySPImpl_CreateCompoundAddress 00788 ( LPDIRECTPLAYSP iface, 00789 LPCDPCOMPOUNDADDRESSELEMENT lpElements, 00790 DWORD dwElementCount, 00791 LPVOID lpAddress, 00792 LPDWORD lpdwAddressSize 00793 ) 00794 { 00795 IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface; 00796 00797 FIXME( "(%p)->(%p,0x%08lx,%p,%p): stub\n", 00798 This, lpElements, dwElementCount, lpAddress, lpdwAddressSize ); 00799 00800 return DP_OK; 00801 } 00802 00803 static HRESULT WINAPI IDirectPlaySPImpl_GetSPData 00804 ( LPDIRECTPLAYSP iface, 00805 LPVOID* lplpData, 00806 LPDWORD lpdwDataSize, 00807 DWORD dwFlags 00808 ) 00809 { 00810 HRESULT hr = DP_OK; 00811 IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface; 00812 00813 /* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */ 00814 TRACE( "(%p)->(%p,%p,0x%08lx)\n", 00815 This, lplpData, lpdwDataSize, dwFlags ); 00816 00817 #if 0 00818 /* This is what the documentation says... */ 00819 if( dwFlags != DPSET_REMOTE ) 00820 { 00821 return DPERR_INVALIDPARAMS; 00822 } 00823 #else 00824 /* ... but most service providers call this with 1 */ 00825 /* Guess that this is using a DPSET_LOCAL or DPSET_REMOTE type of 00826 * thing? 00827 */ 00828 if( dwFlags != DPSET_REMOTE ) 00829 { 00830 TRACE( "Undocumented dwFlags 0x%08lx used\n", dwFlags ); 00831 } 00832 #endif 00833 00834 /* FIXME: What to do in the case where this isn't initialized yet? */ 00835 00836 /* Yes, we're supposed to return a pointer to the memory we have stored! */ 00837 if( dwFlags == DPSET_REMOTE ) 00838 { 00839 *lpdwDataSize = This->sp->dwSpRemoteDataSize; 00840 *lplpData = This->sp->lpSpRemoteData; 00841 00842 if( This->sp->lpSpRemoteData == NULL ) 00843 { 00844 hr = DPERR_GENERIC; 00845 } 00846 } 00847 else if( dwFlags == DPSET_LOCAL ) 00848 { 00849 *lpdwDataSize = This->sp->dwSpLocalDataSize; 00850 *lplpData = This->sp->lpSpLocalData; 00851 00852 if( This->sp->lpSpLocalData == NULL ) 00853 { 00854 hr = DPERR_GENERIC; 00855 } 00856 } 00857 00858 return hr; 00859 } 00860 00861 static HRESULT WINAPI IDirectPlaySPImpl_SetSPData 00862 ( LPDIRECTPLAYSP iface, 00863 LPVOID lpData, 00864 DWORD dwDataSize, 00865 DWORD dwFlags 00866 ) 00867 { 00868 LPVOID lpSpData; 00869 00870 IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface; 00871 00872 /* TRACE( "Called on process 0x%08lx\n", GetCurrentProcessId() ); */ 00873 TRACE( "(%p)->(%p,0x%08lx,0x%08lx)\n", 00874 This, lpData, dwDataSize, dwFlags ); 00875 00876 #if 0 00877 /* This is what the documentation says... */ 00878 if( dwFlags != DPSET_REMOTE ) 00879 { 00880 return DPERR_INVALIDPARAMS; 00881 } 00882 #else 00883 /* ... but most service providers call this with 1 */ 00884 /* Guess that this is using a DPSET_LOCAL or DPSET_REMOTE type of 00885 * thing? 00886 */ 00887 if( dwFlags != DPSET_REMOTE ) 00888 { 00889 TRACE( "Undocumented dwFlags 0x%08lx used\n", dwFlags ); 00890 } 00891 #endif 00892 00893 lpSpData = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwDataSize ); 00894 CopyMemory( lpSpData, lpData, dwDataSize ); 00895 00896 /* If we have data already allocated, free it and replace it */ 00897 if( dwFlags == DPSET_REMOTE ) 00898 { 00899 HeapFree( GetProcessHeap(), 0, This->sp->lpSpRemoteData ); 00900 This->sp->dwSpRemoteDataSize = dwDataSize; 00901 This->sp->lpSpRemoteData = lpSpData; 00902 } 00903 else if ( dwFlags == DPSET_LOCAL ) 00904 { 00905 HeapFree( GetProcessHeap(), 0, This->sp->lpSpLocalData ); 00906 This->sp->lpSpLocalData = lpSpData; 00907 This->sp->dwSpLocalDataSize = dwDataSize; 00908 } 00909 00910 return DP_OK; 00911 } 00912 00913 static VOID WINAPI IDirectPlaySPImpl_SendComplete 00914 ( LPDIRECTPLAYSP iface, 00915 LPVOID unknownA, 00916 DWORD unknownB 00917 ) 00918 { 00919 IDirectPlaySPImpl *This = (IDirectPlaySPImpl *)iface; 00920 00921 FIXME( "(%p)->(%p,0x%08lx): stub\n", 00922 This, unknownA, unknownB ); 00923 } 00924 00925 static const IDirectPlaySPVtbl directPlaySPVT = 00926 { 00927 00928 DPSP_QueryInterface, 00929 DPSP_AddRef, 00930 DPSP_Release, 00931 00932 IDirectPlaySPImpl_AddMRUEntry, 00933 IDirectPlaySPImpl_CreateAddress, 00934 IDirectPlaySPImpl_EnumAddress, 00935 IDirectPlaySPImpl_EnumMRUEntries, 00936 IDirectPlaySPImpl_GetPlayerFlags, 00937 IDirectPlaySPImpl_GetSPPlayerData, 00938 IDirectPlaySPImpl_HandleMessage, 00939 IDirectPlaySPImpl_SetSPPlayerData, 00940 IDirectPlaySPImpl_CreateCompoundAddress, 00941 IDirectPlaySPImpl_GetSPData, 00942 IDirectPlaySPImpl_SetSPData, 00943 IDirectPlaySPImpl_SendComplete 00944 }; 00945 00946 00947 /* DP external interfaces to call into DPSP interface */ 00948 00949 /* Allocate the structure */ 00950 extern LPVOID DPSP_CreateSPPlayerData(void) 00951 { 00952 TRACE( "Creating SPPlayer data struct\n" ); 00953 return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 00954 sizeof( DP_SPPLAYERDATA ) ); 00955 } Generated on Sat May 26 2012 04:20:09 for ReactOS by
1.7.6.1
|