ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

dplaysp.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.