- Added dplayx LibMain for initialization of all dplayx 'global' data
[wine/gsoc_dplay.git] / dlls / dplayx / dplayx_global.c
blob92706dddbffb4bf33abefface7f0a027036fe570
1 /* dplayx.dll global data implementation.
3 * Copyright 1999 - Peter Hunnisett
5 * <presently under construction - contact hunnise@nortelnetworks.com>
7 */
9 /* NOTE: Methods that begin with DPLAYX_ are used for dealing with
10 * dplayx.dll data which is accessible from all processes.
11 */
13 #include "debugtools.h"
14 #include "winbase.h"
15 #include "winerror.h"
16 #include "heap.h" /* Really shouldn't be using those HEAP_strdupA interfaces should I? */
18 #include "dplayx_global.h"
20 DEFAULT_DEBUG_CHANNEL(dplay)
22 /* FIXME: Need to do all that fun other dll referencing type of stuff */
23 /* FIXME: Need to allocate a giant static area - or a global data type thing for Get/Set */
25 /* Static data for all processes */
26 static LPSTR lpszDplayxSemaName = "DPLAYX_SM";
27 static HANDLE hDplayxSema;
31 #define DPLAYX_AquireSemaphore() 0L /* WaitForSingleObject( hDplayxSema, INFINITE? ) */
32 #define DPLAYX_ReleaseSemaphore() 0L /* ReleaseSemaphore( hDplayxSema, ..., ... ) */
35 /* HACK for simple global data right now */
36 enum { numSupportedLobbies = 32 };
37 typedef struct tagDirectPlayLobbyData
39 DWORD dwConnFlags;
40 DPSESSIONDESC2 sessionDesc;
41 DPNAME playerName;
42 GUID guidSP;
43 LPVOID lpAddress;
44 DWORD dwAddressSize;
45 DWORD dwAppID;
46 HANDLE hReceiveEvent;
47 } DirectPlayLobbyData, *lpDirectPlayLobbyData;
49 static DirectPlayLobbyData lobbyData[ numSupportedLobbies ];
51 /* Function prototypes */
52 BOOL DPLAYX_AppIdLobbied( DWORD dwAppId, lpDirectPlayLobbyData* dplData );
57 /***************************************************************************
58 * Called to initialize the global data. This will only be used on the
59 * loading of the dll
60 ***************************************************************************/
61 void DPLAYX_ConstructData(void)
63 UINT i;
65 TRACE( "DPLAYX dll loaded - construct called\n" );
67 /* FIXME: This needs to be allocated shared */
68 hDplayxSema = CreateSemaphoreA( NULL, 0, 1, lpszDplayxSemaName );
70 if( !hDplayxSema )
72 /* Really don't have any choice but to continue... */
73 ERR( "Semaphore creation error 0x%08lx\n", GetLastError() );
76 /* Set all lobbies to be "empty" */
77 for( i=0; i < numSupportedLobbies; i++ )
79 lobbyData[ i ].dwAppID = 0;
84 /***************************************************************************
85 * Called to destroy all global data. This will only be used on the
86 * unloading of the dll
87 ***************************************************************************/
88 void DPLAYX_DestructData(void)
90 /* Hmmm...what to call to delete the semaphore? Auto delete? */
91 TRACE( "DPLAYX dll unloaded - destruct called\n" );
95 /* NOTE: This must be called with the semaphore aquired.
96 * TRUE/FALSE with a pointer to it's data returned
98 BOOL DPLAYX_AppIdLobbied( DWORD dwAppID, lpDirectPlayLobbyData* lplpDplData )
100 INT i;
102 if( dwAppID == 0 )
104 dwAppID = GetCurrentProcessId();
107 for( i=0; i < numSupportedLobbies; i++ )
109 if( lobbyData[ i ].dwAppID == dwAppID )
111 /* This process is lobbied */
112 *lplpDplData = &lobbyData[ i ];
113 return TRUE;
117 return FALSE;
120 #if !defined( WORKING_PROCESS_SUSPEND )
121 /* These two functions should not exist. We would normally create a process initially
122 suspended when we RunApplication. This gives us time to actually store some data
123 before the new process might try to read it. However, process suspension doesn't
124 work yet and I'm too stupid to get it going. So, we'll just hack in fine fashion */
125 DWORD DPLAYX_AquireSemaphoreHack( void )
127 return DPLAYX_AquireSemaphore();
130 DWORD DPLAYX_ReleaseSemaphoreHack( void )
132 return DPLAYX_ReleaseSemaphore();
135 #endif
140 /* Reserve a spot for the new appliction. TRUE means success and FALSE failure. */
141 BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID, HANDLE hReceiveEvent )
143 INT i;
145 DPLAYX_AquireSemaphore();
147 for( i=0; i < numSupportedLobbies; i++ )
149 if( lobbyData[ i ].dwAppID == 0 )
151 /* This process is now lobbied */
152 lobbyData[ i ].dwAppID = dwAppID;
153 lobbyData[ i ].hReceiveEvent = hReceiveEvent;
155 DPLAYX_ReleaseSemaphore();
156 return TRUE;
160 DPLAYX_ReleaseSemaphore();
161 return FALSE;
164 HRESULT DPLAYX_GetConnectionSettingsA
165 ( DWORD dwAppID,
166 LPVOID lpData,
167 LPDWORD lpdwDataSize )
169 lpDirectPlayLobbyData lpDplData;
170 LPDPLCONNECTION lpDplConnection;
172 DPLAYX_AquireSemaphore();
174 if ( !DPLAYX_AppIdLobbied( dwAppID, &lpDplData ) )
176 DPLAYX_ReleaseSemaphore();
177 return DPERR_NOTLOBBIED;
180 /* Verify buffer size */
181 if ( ( lpData == NULL ) ||
182 ( *lpdwDataSize < sizeof( DPLCONNECTION ) )
185 DPLAYX_ReleaseSemaphore();
187 *lpdwDataSize = sizeof( DPLCONNECTION );
189 return DPERR_BUFFERTOOSMALL;
192 /* Copy the information */
193 lpDplConnection = (LPDPLCONNECTION)lpData;
195 /* Copy everything we've got into here */
196 /* Need to actually store the stuff here. Check if we've already allocated each field first. */
197 lpDplConnection->dwSize = sizeof( DPLCONNECTION );
198 lpDplConnection->dwFlags = lpDplData->dwConnFlags;
200 /* Copy LPDPSESSIONDESC2 struct */
201 lpDplConnection->lpSessionDesc = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( lpDplData->sessionDesc ) );
202 memcpy( lpDplConnection->lpSessionDesc, &lpDplData->sessionDesc, sizeof( lpDplData->sessionDesc ) );
204 if( lpDplData->sessionDesc.sess.lpszSessionNameA )
206 lpDplConnection->lpSessionDesc->sess.lpszSessionNameA =
207 HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->sessionDesc.sess.lpszSessionNameA );
210 if( lpDplData->sessionDesc.pass.lpszPasswordA )
212 lpDplConnection->lpSessionDesc->pass.lpszPasswordA =
213 HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->sessionDesc.pass.lpszPasswordA );
216 lpDplConnection->lpSessionDesc->dwReserved1 = lpDplData->sessionDesc.dwReserved1;
217 lpDplConnection->lpSessionDesc->dwReserved2 = lpDplData->sessionDesc.dwReserved2;
219 /* Copy DPNAME struct - seems to be optional - check for existance first */
220 lpDplConnection->lpPlayerName = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( lpDplData->playerName ) );
221 memcpy( lpDplConnection->lpPlayerName, &(lpDplData->playerName), sizeof( lpDplData->playerName ) );
223 if( lpDplData->playerName.psn.lpszShortNameA )
225 lpDplConnection->lpPlayerName->psn.lpszShortNameA =
226 HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->playerName.psn.lpszShortNameA );
229 if( lpDplData->playerName.pln.lpszLongNameA )
231 lpDplConnection->lpPlayerName->pln.lpszLongNameA =
232 HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->playerName.pln.lpszLongNameA );
235 memcpy( &lpDplConnection->guidSP, &lpDplData->guidSP, sizeof( lpDplData->guidSP ) );
237 lpDplConnection->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->dwAddressSize );
238 memcpy( lpDplConnection->lpAddress, lpDplData->lpAddress, lpDplData->dwAddressSize );
240 lpDplConnection->dwAddressSize = lpDplData->dwAddressSize;
242 /* Send a message - or only the first time? */
244 DPLAYX_ReleaseSemaphore();
246 return DP_OK;
249 HRESULT DPLAYX_GetConnectionSettingsW
250 ( DWORD dwAppID,
251 LPVOID lpData,
252 LPDWORD lpdwDataSize )
254 lpDirectPlayLobbyData lpDplData;
255 LPDPLCONNECTION lpDplConnection;
257 DPLAYX_AquireSemaphore();
259 if ( !DPLAYX_AppIdLobbied( dwAppID, &lpDplData ) )
261 DPLAYX_ReleaseSemaphore();
262 return DPERR_NOTLOBBIED;
265 /* Verify buffer size */
266 if ( ( lpData == NULL ) ||
267 ( *lpdwDataSize < sizeof( DPLCONNECTION ) )
270 DPLAYX_ReleaseSemaphore();
272 *lpdwDataSize = sizeof( DPLCONNECTION );
274 return DPERR_BUFFERTOOSMALL;
277 /* Copy the information */
278 lpDplConnection = (LPDPLCONNECTION)lpData;
280 /* Copy everything we've got into here */
281 /* Need to actually store the stuff here. Check if we've already allocated each field first. */
282 lpDplConnection->dwSize = sizeof( DPLCONNECTION );
283 lpDplConnection->dwFlags = lpDplData->dwConnFlags;
285 /* Copy LPDPSESSIONDESC2 struct */
286 lpDplConnection->lpSessionDesc = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( lpDplData->sessionDesc ) );
287 memcpy( lpDplConnection->lpSessionDesc, &lpDplData->sessionDesc, sizeof( lpDplData->sessionDesc ) );
289 if( lpDplData->sessionDesc.sess.lpszSessionName )
291 lpDplConnection->lpSessionDesc->sess.lpszSessionName =
292 HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->sessionDesc.sess.lpszSessionName );
295 if( lpDplData->sessionDesc.pass.lpszPassword )
297 lpDplConnection->lpSessionDesc->pass.lpszPassword =
298 HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->sessionDesc.pass.lpszPassword );
301 lpDplConnection->lpSessionDesc->dwReserved1 = lpDplData->sessionDesc.dwReserved1;
302 lpDplConnection->lpSessionDesc->dwReserved2 = lpDplData->sessionDesc.dwReserved2;
304 /* Copy DPNAME struct - seems to be optional - check for existance first */
305 lpDplConnection->lpPlayerName = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( lpDplData->playerName ) );
306 memcpy( lpDplConnection->lpPlayerName, &(lpDplData->playerName), sizeof( lpDplData->playerName ) );
308 if( lpDplData->playerName.psn.lpszShortName )
310 lpDplConnection->lpPlayerName->psn.lpszShortName =
311 HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->playerName.psn.lpszShortName );
314 if( lpDplData->playerName.pln.lpszLongName )
316 lpDplConnection->lpPlayerName->pln.lpszLongName =
317 HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->playerName.pln.lpszLongName );
320 memcpy( &lpDplConnection->guidSP, &lpDplData->guidSP, sizeof( lpDplData->guidSP ) );
322 lpDplConnection->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpDplData->dwAddressSize );
323 memcpy( lpDplConnection->lpAddress, lpDplData->lpAddress, lpDplData->dwAddressSize );
325 lpDplConnection->dwAddressSize = lpDplData->dwAddressSize;
327 /* Send a message - or only the first time? */
329 DPLAYX_ReleaseSemaphore();
331 return DP_OK;
335 HRESULT DPLAYX_SetConnectionSettingsA
336 ( DWORD dwFlags,
337 DWORD dwAppID,
338 LPDPLCONNECTION lpConn )
340 lpDirectPlayLobbyData lpDplData;
342 DPLAYX_AquireSemaphore();
344 if ( !DPLAYX_AppIdLobbied( dwAppID, &lpDplData ) )
346 /* FIXME: Create a new entry for this dwAppID? */
347 DPLAYX_ReleaseSemaphore();
349 return DPERR_GENERIC;
352 /* Paramater check */
353 if( dwFlags || !lpConn )
355 DPLAYX_ReleaseSemaphore();
357 ERR("invalid parameters.\n");
358 return DPERR_INVALIDPARAMS;
361 /* Store information */
362 if( lpConn->dwSize != sizeof(DPLCONNECTION) )
364 DPLAYX_ReleaseSemaphore();
366 ERR(": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n",
367 lpConn->dwSize, sizeof( DPLCONNECTION ) );
369 return DPERR_INVALIDPARAMS;
372 /* Need to investigate the lpConn->lpSessionDesc to figure out
373 * what type of session we need to join/create.
375 if( (!lpConn->lpSessionDesc ) ||
376 ( lpConn->lpSessionDesc->dwSize != sizeof( DPSESSIONDESC2 ) )
379 DPLAYX_ReleaseSemaphore();
381 ERR("DPSESSIONDESC passed in? Size=%08lx vs. expected=%ul bytes\n",
382 lpConn->lpSessionDesc->dwSize, sizeof( DPSESSIONDESC2 ) );
384 return DPERR_INVALIDPARAMS;
387 /* FIXME: How do I store this stuff so that it can be read by all processes? Static area? What about strings? Ewww...large global shared */
389 /* Need to actually store the stuff here. Check if we've already allocated each field first. */
390 lpDplData->dwConnFlags = lpConn->dwFlags;
392 /* Copy LPDPSESSIONDESC2 struct - this is required */
393 memcpy( &lpDplData->sessionDesc, lpConn->lpSessionDesc, sizeof( *(lpConn->lpSessionDesc) ) );
395 /* FIXME: Can this just be shorted? Does it handle the NULL case correctly? */
396 if( lpConn->lpSessionDesc->sess.lpszSessionNameA )
397 lpDplData->sessionDesc.sess.lpszSessionNameA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->sess.lpszSessionNameA );
398 else
399 lpDplData->sessionDesc.sess.lpszSessionNameA = NULL;
401 if( lpConn->lpSessionDesc->pass.lpszPasswordA )
402 lpDplData->sessionDesc.pass.lpszPasswordA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->pass.lpszPasswordA );
403 else
404 lpDplData->sessionDesc.pass.lpszPasswordA = NULL;
406 lpDplData->sessionDesc.dwReserved1 = lpConn->lpSessionDesc->dwReserved1;
407 lpDplData->sessionDesc.dwReserved2 = lpConn->lpSessionDesc->dwReserved2;
409 /* Copy DPNAME struct - seems to be optional - check for existance first */
410 if( lpConn->lpPlayerName )
412 memcpy( &lpDplData->playerName, lpConn->lpPlayerName, sizeof( *lpConn->lpPlayerName ) );
414 if( lpConn->lpPlayerName->psn.lpszShortNameA )
415 lpDplData->playerName.psn.lpszShortNameA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->psn.lpszShortNameA );
417 if( lpConn->lpPlayerName->pln.lpszLongNameA )
418 lpDplData->playerName.pln.lpszLongNameA = HEAP_strdupA( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->pln.lpszLongNameA );
422 memcpy( &lpDplData->guidSP, &lpConn->guidSP, sizeof( lpConn->guidSP ) );
424 lpDplData->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->dwAddressSize );
425 memcpy( lpDplData->lpAddress, lpConn->lpAddress, lpConn->dwAddressSize );
427 lpDplData->dwAddressSize = lpConn->dwAddressSize;
429 /* Send a message - I think */
431 DPLAYX_ReleaseSemaphore();
433 return DP_OK;
436 HRESULT DPLAYX_SetConnectionSettingsW
437 ( DWORD dwFlags,
438 DWORD dwAppID,
439 LPDPLCONNECTION lpConn )
441 lpDirectPlayLobbyData lpDplData;
443 DPLAYX_AquireSemaphore();
445 if ( !DPLAYX_AppIdLobbied( dwAppID, &lpDplData ) )
447 DPLAYX_ReleaseSemaphore();
448 return DPERR_NOTLOBBIED;
451 /* Paramater check */
452 if( dwFlags || !lpConn )
454 DPLAYX_ReleaseSemaphore();
455 ERR("invalid parameters.\n");
456 return DPERR_INVALIDPARAMS;
459 /* Store information */
460 if( lpConn->dwSize != sizeof(DPLCONNECTION) )
462 DPLAYX_ReleaseSemaphore();
464 ERR(": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n",
465 lpConn->dwSize, sizeof( DPLCONNECTION ) );
467 return DPERR_INVALIDPARAMS;
470 /* Need to investigate the lpConn->lpSessionDesc to figure out
471 * what type of session we need to join/create.
473 if( (!lpConn->lpSessionDesc ) ||
474 ( lpConn->lpSessionDesc->dwSize != sizeof( DPSESSIONDESC2 ) )
477 DPLAYX_ReleaseSemaphore();
479 ERR("DPSESSIONDESC passed in? Size=%08lx vs. expected=%ul bytes\n",
480 lpConn->lpSessionDesc->dwSize, sizeof( DPSESSIONDESC2 ) );
482 return DPERR_INVALIDPARAMS;
485 /* FIXME: How do I store this stuff so that it can be read by all processes? Static area? What about strings? Ewww...large global shared */
487 /* Need to actually store the stuff here. Check if we've already allocated each field first. */
488 lpDplData->dwConnFlags = lpConn->dwFlags;
490 /* Copy LPDPSESSIONDESC2 struct - this is required */
491 memcpy( &lpDplData->sessionDesc, lpConn->lpSessionDesc, sizeof( *(lpConn->lpSessionDesc) ) );
493 /* FIXME: Can this just be shorted? Does it handle the NULL case correctly? */
494 if( lpConn->lpSessionDesc->sess.lpszSessionName )
495 lpDplData->sessionDesc.sess.lpszSessionName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->sess.lpszSessionName );
496 else
497 lpDplData->sessionDesc.sess.lpszSessionName = NULL;
499 if( lpConn->lpSessionDesc->pass.lpszPassword )
500 lpDplData->sessionDesc.pass.lpszPassword = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpSessionDesc->pass.lpszPassword );
501 else
502 lpDplData->sessionDesc.pass.lpszPassword = NULL;
504 lpDplData->sessionDesc.dwReserved1 = lpConn->lpSessionDesc->dwReserved1;
505 lpDplData->sessionDesc.dwReserved2 = lpConn->lpSessionDesc->dwReserved2;
507 /* Copy DPNAME struct - seems to be optional - check for existance first */
508 if( lpConn->lpPlayerName )
510 memcpy( &lpDplData->playerName, lpConn->lpPlayerName, sizeof( *lpConn->lpPlayerName ) );
512 if( lpConn->lpPlayerName->psn.lpszShortName )
513 lpDplData->playerName.psn.lpszShortName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->psn.lpszShortName );
515 if( lpConn->lpPlayerName->pln.lpszLongName )
516 lpDplData->playerName.pln.lpszLongName = HEAP_strdupW( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->lpPlayerName->pln.lpszLongName );
520 memcpy( &lpDplData->guidSP, &lpConn->guidSP, sizeof( lpConn->guidSP ) );
522 lpDplData->lpAddress = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, lpConn->dwAddressSize );
523 memcpy( lpDplData->lpAddress, lpConn->lpAddress, lpConn->dwAddressSize );
525 lpDplData->dwAddressSize = lpConn->dwAddressSize;
527 /* Send a message - I think */
529 DPLAYX_ReleaseSemaphore();
531 return DP_OK;