Replaced all lstr* calls from inside Wine code by their str* equivalent.
[wine/hacks.git] / dlls / dplayx / dplayx_global.c
blob1e171a68d18e85cfba1bdcd334831c367191ae39
1 /* dplayx.dll global data implementation.
3 * Copyright 1999,2000 - 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 <stdio.h>
14 #include "debugtools.h"
15 #include "winbase.h"
16 #include "winerror.h"
17 #include "wine/unicode.h"
19 #include "dplayx_global.h"
20 #include "dplayx_messages.h" /* For CreateMessageReceptionThread only */
22 DEFAULT_DEBUG_CHANNEL(dplay);
24 /* FIXME: Need to do all that fun other dll referencing type of stuff */
26 /* Static data for all processes */
27 static LPCSTR lpszDplayxSemaName = "WINE_DPLAYX_SM";
28 static HANDLE hDplayxSema;
30 static LPCSTR lpszDplayxFileMapping = "WINE_DPLAYX_FM";
31 static HANDLE hDplayxSharedMem;
33 static LPVOID lpSharedStaticData = NULL;
36 #define DPLAYX_AquireSemaphore() TRACE( "Waiting for DPLAYX semaphore\n" ); \
37 WaitForSingleObject( hDplayxSema, INFINITE );\
38 TRACE( "Through wait\n" )
40 #define DPLAYX_ReleaseSemaphore() ReleaseSemaphore( hDplayxSema, 1, NULL ); \
41 TRACE( "DPLAYX Semaphore released\n" ) /* FIXME: Is this correct? */
44 /* HACK for simple global data right now */
45 #define dwStaticSharedSize (128 * 1024) /* FIXME: Way too much */
46 #define dwDynamicSharedSize (128 * 1024) /* FIXME: Enough? */
47 #define dwTotalSharedSize (dwStaticSharedSize + dwDynamicSharedSize)
50 /* FIXME: Is there no easier way? */
52 /* Pretend the entire dynamic area is carved up into 512 byte blocks.
53 * Each block has 4 bytes which are 0 unless used */
54 #define dwBlockSize 512
55 #define dwMaxBlock (dwDynamicSharedSize/dwBlockSize)
56 DWORD dwBlockOn = 0;
58 typedef struct
60 DWORD used;
61 DWORD data[dwBlockSize-sizeof(DWORD)];
62 } DPLAYX_MEM_SLICE;
64 DPLAYX_MEM_SLICE* lpMemArea;
66 void DPLAYX_PrivHeapFree( LPVOID addr );
67 void DPLAYX_PrivHeapFree( LPVOID addr )
69 LPVOID lpAddrStart;
70 DWORD dwBlockUsed;
72 /* Handle getting passed a NULL */
73 if( addr == NULL )
75 return;
78 lpAddrStart = addr - sizeof(DWORD); /* Find block header */
79 dwBlockUsed = ((BYTE*)lpAddrStart - (BYTE*)lpMemArea)/dwBlockSize;
81 lpMemArea[ dwBlockUsed ].used = 0;
84 LPVOID DPLAYX_PrivHeapAlloc( DWORD flags, DWORD size );
85 LPVOID DPLAYX_PrivHeapAlloc( DWORD flags, DWORD size )
87 LPVOID lpvArea = NULL;
88 UINT uBlockUsed;
90 if( size > (dwBlockSize - sizeof(DWORD)) )
92 FIXME( "Size exceeded. Request of 0x%08lx\n", size );
93 size = dwBlockSize - sizeof(DWORD);
96 /* Find blank area */
97 uBlockUsed = 0;
98 while( ( lpMemArea[ uBlockUsed ].used != 0 ) && ( uBlockUsed <= dwMaxBlock ) ) { uBlockUsed++; }
100 if( uBlockUsed <= dwMaxBlock )
102 /* Set the area used */
103 lpMemArea[ uBlockUsed ].used = 1;
104 lpvArea = &(lpMemArea[ uBlockUsed ].data);
106 else
108 ERR( "No free block found\n" );
109 return NULL;
112 if( flags & HEAP_ZERO_MEMORY )
114 ZeroMemory( lpvArea, size );
117 return lpvArea;
120 LPSTR DPLAYX_strdupA( DWORD flags, LPCSTR str );
121 LPSTR DPLAYX_strdupA( DWORD flags, LPCSTR str )
123 LPSTR p = DPLAYX_PrivHeapAlloc( flags, strlen(str) + 1 );
124 if(p) {
125 strcpy( p, str );
127 return p;
130 LPWSTR DPLAYX_strdupW( DWORD flags, LPCWSTR str );
131 LPWSTR DPLAYX_strdupW( DWORD flags, LPCWSTR str )
133 INT len = strlenW(str) + 1;
134 LPWSTR p = DPLAYX_PrivHeapAlloc( flags, len * sizeof(WCHAR) );
135 if(p) {
136 strcpyW( p, str );
138 return p;
142 enum { numSupportedLobbies = 32, numSupportedSessions = 32 };
143 typedef struct tagDPLAYX_LOBBYDATA
145 /* Points to lpConn + block of contiguous extra memory for dynamic parts
146 * of the struct directly following
148 LPDPLCONNECTION lpConn;
150 /* Information for dplobby interfaces */
151 DWORD dwAppID;
152 HANDLE hReceiveEvent;
153 DWORD dwAppLaunchedFromID;
155 /* Should this lobby app send messages to creator at important life
156 * stages
158 BOOL bInformOnConnect; /* FIXME: Not used yet */
159 BOOL bInformOnSettingRead;
160 BOOL bInformOnAppDeath; /* FIXME: Not used yet */
162 BOOL bWaitForConnectionSettings;
164 } DPLAYX_LOBBYDATA, *LPDPLAYX_LOBBYDATA;
166 static DPLAYX_LOBBYDATA* lobbyData = NULL;
167 /* static DPLAYX_LOBBYDATA lobbyData[ numSupportedLobbies ]; */
169 static DPSESSIONDESC2* sessionData = NULL;
170 /* static DPSESSIONDESC2* sessionData[ numSupportedSessions ]; */
172 /* Function prototypes */
173 DWORD DPLAYX_SizeOfLobbyDataA( LPDPLCONNECTION lpDplData );
174 DWORD DPLAYX_SizeOfLobbyDataW( LPDPLCONNECTION lpDplData );
175 void DPLAYX_CopyConnStructA( LPDPLCONNECTION dest, LPDPLCONNECTION src );
176 void DPLAYX_CopyConnStructW( LPDPLCONNECTION dest, LPDPLCONNECTION src );
177 BOOL DPLAYX_IsAppIdLobbied( DWORD dwAppId, LPDPLAYX_LOBBYDATA* dplData );
178 void DPLAYX_InitializeLobbyDataEntry( LPDPLAYX_LOBBYDATA lpData );
179 BOOL DPLAYX_CopyIntoSessionDesc2A( LPDPSESSIONDESC2 lpSessionDest,
180 LPCDPSESSIONDESC2 lpSessionSrc );
184 /***************************************************************************
185 * Called to initialize the global data. This will only be used on the
186 * loading of the dll
187 ***************************************************************************/
188 BOOL DPLAYX_ConstructData(void)
190 SECURITY_ATTRIBUTES s_attrib;
191 BOOL bInitializeSharedMemory = FALSE;
192 LPVOID lpDesiredMemoryMapStart = (LPVOID)0x50000000;
194 TRACE( "DPLAYX dll loaded - construct called\n" );
196 /* Create a semaphore to block access to DPLAYX global data structs */
198 s_attrib.bInheritHandle = TRUE;
199 s_attrib.lpSecurityDescriptor = NULL;
200 s_attrib.nLength = sizeof(s_attrib);
202 hDplayxSema = CreateSemaphoreA( &s_attrib, 1, 1, lpszDplayxSemaName );
204 /* First instance creates the semaphore. Others just use it */
205 if( GetLastError() == ERROR_SUCCESS )
207 TRACE( "Semaphore %u created\n", hDplayxSema );
209 /* The semaphore creator will also build the shared memory */
210 bInitializeSharedMemory = TRUE;
212 else if ( GetLastError() == ERROR_ALREADY_EXISTS )
214 TRACE( "Found semaphore handle %u\n", hDplayxSema );
216 else
218 ERR( ": semaphore error 0x%08lx\n", GetLastError() );
219 return FALSE;
222 SetLastError( ERROR_SUCCESS );
224 DPLAYX_AquireSemaphore();
226 hDplayxSharedMem = CreateFileMappingA( INVALID_HANDLE_VALUE,
227 &s_attrib,
228 PAGE_READWRITE | SEC_COMMIT,
230 dwTotalSharedSize,
231 lpszDplayxFileMapping );
233 if( GetLastError() == ERROR_SUCCESS )
235 TRACE( "File mapped %u created\n", hDplayxSharedMem );
237 else if ( GetLastError() == ERROR_ALREADY_EXISTS )
239 TRACE( "Found FileMapping handle %u\n", hDplayxSharedMem );
241 else
243 ERR( ": unable to create shared memory 0x%08lx\n", GetLastError() );
244 return FALSE;
247 lpSharedStaticData = MapViewOfFileEx( hDplayxSharedMem,
248 FILE_MAP_WRITE,
249 0, 0, 0, lpDesiredMemoryMapStart );
251 if( lpSharedStaticData == NULL )
253 ERR( ": unable to map static data into process memory space: 0x%08lx\n",
254 GetLastError() );
255 return FALSE;
257 else
259 if( lpDesiredMemoryMapStart == lpSharedStaticData )
261 TRACE( "File mapped to %p\n", lpSharedStaticData );
263 else
265 /* Presently the shared data structures use pointers. If the
266 * files are no mapped into the same area, the pointers will no
267 * longer make any sense :(
268 * FIXME: In the future make the shared data structures have some
269 * sort of fixup to make them independent between data spaces.
270 * This will also require a rework of the session data stuff.
272 ERR( "File mapped to %p (not %p). Expect failure\n",
273 lpSharedStaticData, lpDesiredMemoryMapStart );
277 /* Dynamic area starts just after the static area */
278 lpMemArea = (LPVOID)((BYTE*)lpSharedStaticData + dwStaticSharedSize);
280 /* FIXME: Crude hack */
281 lobbyData = (DPLAYX_LOBBYDATA*)lpSharedStaticData;
282 sessionData = (DPSESSIONDESC2*)((BYTE*)lpSharedStaticData + (dwStaticSharedSize/2));
284 /* Initialize shared data segments. */
285 if( bInitializeSharedMemory )
287 UINT i;
289 TRACE( "Initializing shared memory\n" );
291 /* Set all lobbies to be "empty" */
292 for( i=0; i < numSupportedLobbies; i++ )
294 DPLAYX_InitializeLobbyDataEntry( &lobbyData[ i ] );
297 /* Set all sessions to be "empty" */
298 for( i=0; i < numSupportedSessions; i++ )
300 sessionData[i].dwSize = 0;
303 /* Zero out the dynmaic area */
304 ZeroMemory( lpMemArea, dwDynamicSharedSize );
306 /* Just for fun sync the whole data area */
307 FlushViewOfFile( lpSharedStaticData, dwTotalSharedSize );
310 DPLAYX_ReleaseSemaphore();
312 return TRUE;
315 /***************************************************************************
316 * Called to destroy all global data. This will only be used on the
317 * unloading of the dll
318 ***************************************************************************/
319 BOOL DPLAYX_DestructData(void)
321 TRACE( "DPLAYX dll unloaded - destruct called\n" );
323 /* Delete the semaphore */
324 CloseHandle( hDplayxSema );
326 /* Delete shared memory file mapping */
327 UnmapViewOfFile( lpSharedStaticData );
328 CloseHandle( hDplayxSharedMem );
330 return FALSE;
334 void DPLAYX_InitializeLobbyDataEntry( LPDPLAYX_LOBBYDATA lpData )
336 ZeroMemory( lpData, sizeof( *lpData ) );
338 /* Set the handle to a better invalid value */
339 lpData->hReceiveEvent = INVALID_HANDLE_VALUE;
342 /* NOTE: This must be called with the semaphore aquired.
343 * TRUE/FALSE with a pointer to it's data returned. Pointer data is
344 * is only valid if TRUE is returned.
346 BOOL DPLAYX_IsAppIdLobbied( DWORD dwAppID, LPDPLAYX_LOBBYDATA* lplpDplData )
348 UINT i;
350 *lplpDplData = NULL;
352 if( dwAppID == 0 )
354 dwAppID = GetCurrentProcessId();
355 TRACE( "Translated dwAppID == 0 into 0x%08lx\n", dwAppID );
358 for( i=0; i < numSupportedLobbies; i++ )
360 if( lobbyData[ i ].dwAppID == dwAppID )
362 /* This process is lobbied */
363 TRACE( "Found 0x%08lx @ %u\n", dwAppID, i );
364 *lplpDplData = &lobbyData[ i ];
365 return TRUE;
369 return FALSE;
372 /* Reserve a spot for the new appliction. TRUE means success and FALSE failure. */
373 BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID, HANDLE hReceiveEvent )
375 UINT i;
377 /* 0 is the marker for unused application data slots */
378 if( dwAppID == 0 )
380 return FALSE;
383 DPLAYX_AquireSemaphore();
385 /* Find an empty space in the list and insert the data */
386 for( i=0; i < numSupportedLobbies; i++ )
388 if( lobbyData[ i ].dwAppID == 0 )
390 /* This process is now lobbied */
391 TRACE( "Setting lobbyData[%u] for (0x%08lx,%u,0x%08lx)\n",
392 i, dwAppID, hReceiveEvent, GetCurrentProcessId() );
394 lobbyData[ i ].dwAppID = dwAppID;
395 lobbyData[ i ].hReceiveEvent = hReceiveEvent;
396 lobbyData[ i ].dwAppLaunchedFromID = GetCurrentProcessId();
398 lobbyData[ i ].bInformOnConnect = TRUE;
399 lobbyData[ i ].bInformOnSettingRead = TRUE;
400 lobbyData[ i ].bInformOnAppDeath = TRUE;
402 DPLAYX_ReleaseSemaphore();
403 return TRUE;
407 ERR( "No empty lobbies\n" );
409 DPLAYX_ReleaseSemaphore();
410 return FALSE;
413 /* I'm not sure when I'm going to need this, but here it is */
414 BOOL DPLAYX_DestroyLobbyApplication( DWORD dwAppID )
416 UINT i;
418 DPLAYX_AquireSemaphore();
420 /* Find an empty space in the list and insert the data */
421 for( i=0; i < numSupportedLobbies; i++ )
423 if( lobbyData[ i ].dwAppID == dwAppID )
425 /* FIXME: Should free up anything unused. Tisk tisk :0 */
426 /* Mark this entry unused */
427 TRACE( "Marking lobbyData[%u] unused\n", i );
428 DPLAYX_InitializeLobbyDataEntry( &lobbyData[ i ] );
430 DPLAYX_ReleaseSemaphore();
431 return TRUE;
435 DPLAYX_ReleaseSemaphore();
436 ERR( "Unable to find global entry for application\n" );
437 return FALSE;
440 HRESULT DPLAYX_GetConnectionSettingsA
441 ( DWORD dwAppID,
442 LPVOID lpData,
443 LPDWORD lpdwDataSize,
444 LPBOOL lpbSendHaveReadMessage )
446 LPDPLAYX_LOBBYDATA lpDplData;
447 DWORD dwRequiredDataSize = 0;
449 DPLAYX_AquireSemaphore();
451 if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) )
453 DPLAYX_ReleaseSemaphore();
455 TRACE( "Application 0x%08lx is not lobbied\n", dwAppID );
456 return DPERR_NOTLOBBIED;
459 dwRequiredDataSize = DPLAYX_SizeOfLobbyDataA( lpDplData->lpConn );
461 /* Do they want to know the required buffer size or is the provided buffer
462 * big enough?
464 if ( ( lpData == NULL ) ||
465 ( *lpdwDataSize < dwRequiredDataSize )
468 DPLAYX_ReleaseSemaphore();
470 *lpdwDataSize = DPLAYX_SizeOfLobbyDataA( lpDplData->lpConn );
472 return DPERR_BUFFERTOOSMALL;
475 /* They have gotten the information */
476 *lpbSendHaveReadMessage = lpDplData->bInformOnSettingRead;
477 lpDplData->bInformOnSettingRead = FALSE;
479 DPLAYX_CopyConnStructA( (LPDPLCONNECTION)lpData, lpDplData->lpConn );
481 DPLAYX_ReleaseSemaphore();
483 return DP_OK;
486 /* Assumption: Enough contiguous space was allocated at dest */
487 void DPLAYX_CopyConnStructA( LPDPLCONNECTION dest, LPDPLCONNECTION src )
489 BYTE* lpStartOfFreeSpace;
491 memcpy( dest, src, sizeof( DPLCONNECTION ) );
493 lpStartOfFreeSpace = ((BYTE*)dest) + sizeof( DPLCONNECTION );
495 /* Copy the LPDPSESSIONDESC2 structure if it exists */
496 if( src->lpSessionDesc )
498 dest->lpSessionDesc = (LPDPSESSIONDESC2)lpStartOfFreeSpace;
499 lpStartOfFreeSpace += sizeof( DPSESSIONDESC2 );
500 memcpy( dest->lpSessionDesc, src->lpSessionDesc, sizeof( DPSESSIONDESC2 ) );
502 /* Session names may or may not exist */
503 if( src->lpSessionDesc->sess.lpszSessionNameA )
505 strcpy( (LPSTR)lpStartOfFreeSpace, src->lpSessionDesc->sess.lpszSessionNameA );
506 dest->lpSessionDesc->sess.lpszSessionNameA = (LPSTR)lpStartOfFreeSpace;
507 lpStartOfFreeSpace +=
508 strlen( (LPSTR)dest->lpSessionDesc->sess.lpszSessionName ) + 1;
511 if( src->lpSessionDesc->pass.lpszPasswordA )
513 strcpy( (LPSTR)lpStartOfFreeSpace, src->lpSessionDesc->pass.lpszPasswordA );
514 dest->lpSessionDesc->pass.lpszPasswordA = (LPSTR)lpStartOfFreeSpace;
515 lpStartOfFreeSpace +=
516 strlen( (LPSTR)dest->lpSessionDesc->pass.lpszPasswordA ) + 1;
520 /* DPNAME structure is optional */
521 if( src->lpPlayerName )
523 dest->lpPlayerName = (LPDPNAME)lpStartOfFreeSpace;
524 lpStartOfFreeSpace += sizeof( DPNAME );
525 memcpy( dest->lpPlayerName, src->lpPlayerName, sizeof( DPNAME ) );
527 if( src->lpPlayerName->psn.lpszShortNameA )
529 strcpy( (LPSTR)lpStartOfFreeSpace, src->lpPlayerName->psn.lpszShortNameA );
530 dest->lpPlayerName->psn.lpszShortNameA = (LPSTR)lpStartOfFreeSpace;
531 lpStartOfFreeSpace +=
532 strlen( (LPSTR)dest->lpPlayerName->psn.lpszShortNameA ) + 1;
535 if( src->lpPlayerName->pln.lpszLongNameA )
537 strcpy( (LPSTR)lpStartOfFreeSpace, src->lpPlayerName->pln.lpszLongNameA );
538 dest->lpPlayerName->pln.lpszLongNameA = (LPSTR)lpStartOfFreeSpace;
539 lpStartOfFreeSpace +=
540 strlen( (LPSTR)dest->lpPlayerName->pln.lpszLongName ) + 1 ;
545 /* Copy address if it exists */
546 if( src->lpAddress )
548 dest->lpAddress = (LPVOID)lpStartOfFreeSpace;
549 memcpy( lpStartOfFreeSpace, src->lpAddress, src->dwAddressSize );
550 /* No need to advance lpStartOfFreeSpace as there is no more "dynamic" data */
554 HRESULT DPLAYX_GetConnectionSettingsW
555 ( DWORD dwAppID,
556 LPVOID lpData,
557 LPDWORD lpdwDataSize,
558 LPBOOL lpbSendHaveReadMessage )
560 LPDPLAYX_LOBBYDATA lpDplData;
561 DWORD dwRequiredDataSize = 0;
563 DPLAYX_AquireSemaphore();
565 if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) )
567 DPLAYX_ReleaseSemaphore();
568 return DPERR_NOTLOBBIED;
571 dwRequiredDataSize = DPLAYX_SizeOfLobbyDataW( lpDplData->lpConn );
573 /* Do they want to know the required buffer size or is the provided buffer
574 * big enough?
576 if ( ( lpData == NULL ) ||
577 ( *lpdwDataSize < dwRequiredDataSize )
580 DPLAYX_ReleaseSemaphore();
582 *lpdwDataSize = DPLAYX_SizeOfLobbyDataW( lpDplData->lpConn );
584 return DPERR_BUFFERTOOSMALL;
587 /* They have gotten the information */
588 *lpbSendHaveReadMessage = lpDplData->bInformOnSettingRead;
589 lpDplData->bInformOnSettingRead = FALSE;
591 DPLAYX_CopyConnStructW( (LPDPLCONNECTION)lpData, lpDplData->lpConn );
593 DPLAYX_ReleaseSemaphore();
595 return DP_OK;
598 /* Assumption: Enough contiguous space was allocated at dest */
599 void DPLAYX_CopyConnStructW( LPDPLCONNECTION dest, LPDPLCONNECTION src )
601 BYTE* lpStartOfFreeSpace;
603 memcpy( dest, src, sizeof( DPLCONNECTION ) );
605 lpStartOfFreeSpace = ( (BYTE*)dest) + sizeof( DPLCONNECTION );
607 /* Copy the LPDPSESSIONDESC2 structure if it exists */
608 if( src->lpSessionDesc )
610 dest->lpSessionDesc = (LPDPSESSIONDESC2)lpStartOfFreeSpace;
611 lpStartOfFreeSpace += sizeof( DPSESSIONDESC2 );
612 memcpy( dest->lpSessionDesc, src->lpSessionDesc, sizeof( DPSESSIONDESC2 ) );
614 /* Session names may or may not exist */
615 if( src->lpSessionDesc->sess.lpszSessionName )
617 strcpyW( (LPWSTR)lpStartOfFreeSpace, dest->lpSessionDesc->sess.lpszSessionName );
618 src->lpSessionDesc->sess.lpszSessionName = (LPWSTR)lpStartOfFreeSpace;
619 lpStartOfFreeSpace += sizeof(WCHAR) *
620 ( strlenW( (LPWSTR)dest->lpSessionDesc->sess.lpszSessionName ) + 1 );
623 if( src->lpSessionDesc->pass.lpszPassword )
625 strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpSessionDesc->pass.lpszPassword );
626 dest->lpSessionDesc->pass.lpszPassword = (LPWSTR)lpStartOfFreeSpace;
627 lpStartOfFreeSpace += sizeof(WCHAR) *
628 ( strlenW( (LPWSTR)dest->lpSessionDesc->pass.lpszPassword ) + 1 );
632 /* DPNAME structure is optional */
633 if( src->lpPlayerName )
635 dest->lpPlayerName = (LPDPNAME)lpStartOfFreeSpace;
636 lpStartOfFreeSpace += sizeof( DPNAME );
637 memcpy( dest->lpPlayerName, src->lpPlayerName, sizeof( DPNAME ) );
639 if( src->lpPlayerName->psn.lpszShortName )
641 strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpPlayerName->psn.lpszShortName );
642 dest->lpPlayerName->psn.lpszShortName = (LPWSTR)lpStartOfFreeSpace;
643 lpStartOfFreeSpace += sizeof(WCHAR) *
644 ( strlenW( (LPWSTR)dest->lpPlayerName->psn.lpszShortName ) + 1 );
647 if( src->lpPlayerName->pln.lpszLongName )
649 strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpPlayerName->pln.lpszLongName );
650 dest->lpPlayerName->pln.lpszLongName = (LPWSTR)lpStartOfFreeSpace;
651 lpStartOfFreeSpace += sizeof(WCHAR) *
652 ( strlenW( (LPWSTR)dest->lpPlayerName->pln.lpszLongName ) + 1 );
657 /* Copy address if it exists */
658 if( src->lpAddress )
660 dest->lpAddress = (LPVOID)lpStartOfFreeSpace;
661 memcpy( lpStartOfFreeSpace, src->lpAddress, src->dwAddressSize );
662 /* No need to advance lpStartOfFreeSpace as there is no more "dynamic" data */
667 /* Store the structure into the shared data structre. Ensure that allocs for
668 * variable length strings come from the shared data structure.
669 * FIXME: We need to free information as well
671 HRESULT DPLAYX_SetConnectionSettingsA
672 ( DWORD dwFlags,
673 DWORD dwAppID,
674 LPDPLCONNECTION lpConn )
676 LPDPLAYX_LOBBYDATA lpDplData;
678 /* Paramater check */
679 if( dwFlags || !lpConn )
681 ERR("invalid parameters.\n");
682 return DPERR_INVALIDPARAMS;
685 /* Store information */
686 if( lpConn->dwSize != sizeof(DPLCONNECTION) )
688 ERR(": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n",
689 lpConn->dwSize, sizeof( DPLCONNECTION ) );
691 return DPERR_INVALIDPARAMS;
694 DPLAYX_AquireSemaphore();
696 if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) )
698 DPLAYX_ReleaseSemaphore();
700 return DPERR_NOTLOBBIED;
703 if( (!lpConn->lpSessionDesc ) ||
704 ( lpConn->lpSessionDesc->dwSize != sizeof( DPSESSIONDESC2 ) )
707 DPLAYX_ReleaseSemaphore();
709 ERR("DPSESSIONDESC passed in? Size=%lu vs. expected=%u bytes\n",
710 lpConn->lpSessionDesc->dwSize, sizeof( DPSESSIONDESC2 ) );
712 return DPERR_INVALIDPARAMS;
715 /* Free the existing memory */
716 DPLAYX_PrivHeapFree( lpDplData->lpConn );
718 lpDplData->lpConn = DPLAYX_PrivHeapAlloc( HEAP_ZERO_MEMORY,
719 DPLAYX_SizeOfLobbyDataA( lpConn ) );
721 DPLAYX_CopyConnStructA( lpDplData->lpConn, lpConn );
724 DPLAYX_ReleaseSemaphore();
726 /* FIXME: Send a message - I think */
728 return DP_OK;
731 /* Store the structure into the shared data structre. Ensure that allocs for
732 * variable length strings come from the shared data structure.
733 * FIXME: We need to free information as well
735 HRESULT DPLAYX_SetConnectionSettingsW
736 ( DWORD dwFlags,
737 DWORD dwAppID,
738 LPDPLCONNECTION lpConn )
740 LPDPLAYX_LOBBYDATA lpDplData;
742 /* Paramater check */
743 if( dwFlags || !lpConn )
745 ERR("invalid parameters.\n");
746 return DPERR_INVALIDPARAMS;
749 /* Store information */
750 if( lpConn->dwSize != sizeof(DPLCONNECTION) )
752 ERR(": old/new DPLCONNECTION type? Size=%lu vs. expected=%u bytes\n",
753 lpConn->dwSize, sizeof( DPLCONNECTION ) );
755 return DPERR_INVALIDPARAMS;
758 DPLAYX_AquireSemaphore();
760 if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) )
762 DPLAYX_ReleaseSemaphore();
764 return DPERR_NOTLOBBIED;
767 /* Free the existing memory */
768 DPLAYX_PrivHeapFree( lpDplData->lpConn );
770 lpDplData->lpConn = DPLAYX_PrivHeapAlloc( HEAP_ZERO_MEMORY,
771 DPLAYX_SizeOfLobbyDataW( lpConn ) );
773 DPLAYX_CopyConnStructW( lpDplData->lpConn, lpConn );
776 DPLAYX_ReleaseSemaphore();
778 /* FIXME: Send a message - I think */
780 return DP_OK;
783 DWORD DPLAYX_SizeOfLobbyDataA( LPDPLCONNECTION lpConn )
785 DWORD dwTotalSize = sizeof( DPLCONNECTION );
787 /* Just a safety check */
788 if( lpConn == NULL )
790 ERR( "lpConn is NULL\n" );
791 return 0;
794 if( lpConn->lpSessionDesc != NULL )
796 dwTotalSize += sizeof( DPSESSIONDESC2 );
798 if( lpConn->lpSessionDesc->sess.lpszSessionNameA )
800 dwTotalSize += strlen( lpConn->lpSessionDesc->sess.lpszSessionNameA ) + 1;
803 if( lpConn->lpSessionDesc->pass.lpszPasswordA )
805 dwTotalSize += strlen( lpConn->lpSessionDesc->pass.lpszPasswordA ) + 1;
809 if( lpConn->lpPlayerName != NULL )
811 dwTotalSize += sizeof( DPNAME );
813 if( lpConn->lpPlayerName->psn.lpszShortNameA )
815 dwTotalSize += strlen( lpConn->lpPlayerName->psn.lpszShortNameA ) + 1;
818 if( lpConn->lpPlayerName->pln.lpszLongNameA )
820 dwTotalSize += strlen( lpConn->lpPlayerName->pln.lpszLongNameA ) + 1;
825 dwTotalSize += lpConn->dwAddressSize;
827 return dwTotalSize;
830 DWORD DPLAYX_SizeOfLobbyDataW( LPDPLCONNECTION lpConn )
832 DWORD dwTotalSize = sizeof( DPLCONNECTION );
834 /* Just a safety check */
835 if( lpConn == NULL )
837 ERR( "lpConn is NULL\n" );
838 return 0;
841 if( lpConn->lpSessionDesc != NULL )
843 dwTotalSize += sizeof( DPSESSIONDESC2 );
845 if( lpConn->lpSessionDesc->sess.lpszSessionName )
847 dwTotalSize += sizeof( WCHAR ) *
848 ( strlenW( lpConn->lpSessionDesc->sess.lpszSessionName ) + 1 );
851 if( lpConn->lpSessionDesc->pass.lpszPassword )
853 dwTotalSize += sizeof( WCHAR ) *
854 ( strlenW( lpConn->lpSessionDesc->pass.lpszPassword ) + 1 );
858 if( lpConn->lpPlayerName != NULL )
860 dwTotalSize += sizeof( DPNAME );
862 if( lpConn->lpPlayerName->psn.lpszShortName )
864 dwTotalSize += sizeof( WCHAR ) *
865 ( strlenW( lpConn->lpPlayerName->psn.lpszShortName ) + 1 );
868 if( lpConn->lpPlayerName->pln.lpszLongName )
870 dwTotalSize += sizeof( WCHAR ) *
871 ( strlenW( lpConn->lpPlayerName->pln.lpszLongName ) + 1 );
876 dwTotalSize += lpConn->dwAddressSize;
878 return dwTotalSize;
883 LPDPSESSIONDESC2 DPLAYX_CopyAndAllocateSessionDesc2A( LPCDPSESSIONDESC2 lpSessionSrc )
885 LPDPSESSIONDESC2 lpSessionDest =
886 (LPDPSESSIONDESC2)DPLAYX_PrivHeapAlloc( HEAP_ZERO_MEMORY, sizeof( *lpSessionSrc ) );
887 DPLAYX_CopyIntoSessionDesc2A( lpSessionDest, lpSessionSrc );
889 return lpSessionDest;
892 /* Copy an ANSI session desc structure to the given buffer */
893 BOOL DPLAYX_CopyIntoSessionDesc2A( LPDPSESSIONDESC2 lpSessionDest,
894 LPCDPSESSIONDESC2 lpSessionSrc )
896 memcpy( lpSessionDest, lpSessionSrc, sizeof( *lpSessionSrc ) );
898 if( lpSessionSrc->sess.lpszSessionNameA )
900 lpSessionDest->sess.lpszSessionNameA =
901 DPLAYX_strdupA( HEAP_ZERO_MEMORY, lpSessionSrc->sess.lpszSessionNameA );
903 if( lpSessionSrc->pass.lpszPasswordA )
905 lpSessionDest->pass.lpszPasswordA =
906 DPLAYX_strdupA( HEAP_ZERO_MEMORY, lpSessionSrc->pass.lpszPasswordA );
909 return TRUE;
912 /* Start the index at 0. index will be updated to equal that which should
913 be passed back into this function for the next element */
914 LPDPSESSIONDESC2 DPLAYX_CopyAndAllocateLocalSession( UINT* index )
916 for( ; (*index) < numSupportedSessions; (*index)++ )
918 if( sessionData[(*index)].dwSize != 0 )
920 return DPLAYX_CopyAndAllocateSessionDesc2A( &sessionData[(*index)++] );
924 /* No more sessions */
925 return NULL;
928 /* Start the index at 0. index will be updated to equal that which should
929 be passed back into this function for the next element */
930 BOOL DPLAYX_CopyLocalSession( UINT* index, LPDPSESSIONDESC2 lpsd )
932 for( ; (*index) < numSupportedSessions; (*index)++ )
934 if( sessionData[(*index)].dwSize != 0 )
936 return DPLAYX_CopyIntoSessionDesc2A( lpsd, &sessionData[(*index)++] );
940 /* No more sessions */
941 return FALSE;
944 void DPLAYX_SetLocalSession( LPCDPSESSIONDESC2 lpsd )
946 UINT i;
948 /* FIXME: Is this an error if it exists already? */
950 /* Crude/wrong implementation for now. Just always add to first empty spot */
951 for( i=0; i < numSupportedSessions; i++ )
953 /* Is this one empty? */
954 if( sessionData[i].dwSize == 0 )
956 DPLAYX_CopyIntoSessionDesc2A( &sessionData[i], lpsd );
957 break;
963 BOOL DPLAYX_WaitForConnectionSettings( BOOL bWait )
965 LPDPLAYX_LOBBYDATA lpLobbyData;
967 DPLAYX_AquireSemaphore();
969 if( !DPLAYX_IsAppIdLobbied( 0, &lpLobbyData ) )
971 DPLAYX_ReleaseSemaphore();
972 return FALSE;
975 lpLobbyData->bWaitForConnectionSettings = bWait;
977 DPLAYX_ReleaseSemaphore();
979 return TRUE;
982 BOOL DPLAYX_AnyLobbiesWaitingForConnSettings(void)
984 UINT i;
985 BOOL bFound = FALSE;
987 DPLAYX_AquireSemaphore();
989 for( i=0; i < numSupportedLobbies; i++ )
991 if( ( lobbyData[ i ].dwAppID != 0 ) && /* lobby initialized */
992 ( lobbyData[ i ].bWaitForConnectionSettings ) /* Waiting */
995 bFound = TRUE;
996 break;
1000 DPLAYX_ReleaseSemaphore();
1002 return bFound;
1006 /* NOTE: This is potentially not thread safe. You are not guaranteed to end up
1007 with the correct string printed in the case where the HRESULT is not
1008 known. You'll just get the last hr passed in printed. This can change
1009 over time if this method is used alot :) */
1010 LPCSTR DPLAYX_HresultToString(HRESULT hr)
1012 static char szTempStr[12];
1014 switch (hr)
1016 case DP_OK:
1017 return "DP_OK";
1018 case DPERR_ALREADYINITIALIZED:
1019 return "DPERR_ALREADYINITIALIZED";
1020 case DPERR_ACCESSDENIED:
1021 return "DPERR_ACCESSDENIED";
1022 case DPERR_ACTIVEPLAYERS:
1023 return "DPERR_ACTIVEPLAYERS";
1024 case DPERR_BUFFERTOOSMALL:
1025 return "DPERR_BUFFERTOOSMALL";
1026 case DPERR_CANTADDPLAYER:
1027 return "DPERR_CANTADDPLAYER";
1028 case DPERR_CANTCREATEGROUP:
1029 return "DPERR_CANTCREATEGROUP";
1030 case DPERR_CANTCREATEPLAYER:
1031 return "DPERR_CANTCREATEPLAYER";
1032 case DPERR_CANTCREATESESSION:
1033 return "DPERR_CANTCREATESESSION";
1034 case DPERR_CAPSNOTAVAILABLEYET:
1035 return "DPERR_CAPSNOTAVAILABLEYET";
1036 case DPERR_EXCEPTION:
1037 return "DPERR_EXCEPTION";
1038 case DPERR_GENERIC:
1039 return "DPERR_GENERIC";
1040 case DPERR_INVALIDFLAGS:
1041 return "DPERR_INVALIDFLAGS";
1042 case DPERR_INVALIDOBJECT:
1043 return "DPERR_INVALIDOBJECT";
1044 case DPERR_INVALIDPARAMS:
1045 return "DPERR_INVALIDPARAMS";
1046 case DPERR_INVALIDPLAYER:
1047 return "DPERR_INVALIDPLAYER";
1048 case DPERR_INVALIDGROUP:
1049 return "DPERR_INVALIDGROUP";
1050 case DPERR_NOCAPS:
1051 return "DPERR_NOCAPS";
1052 case DPERR_NOCONNECTION:
1053 return "DPERR_NOCONNECTION";
1054 case DPERR_OUTOFMEMORY:
1055 return "DPERR_OUTOFMEMORY";
1056 case DPERR_NOMESSAGES:
1057 return "DPERR_NOMESSAGES";
1058 case DPERR_NONAMESERVERFOUND:
1059 return "DPERR_NONAMESERVERFOUND";
1060 case DPERR_NOPLAYERS:
1061 return "DPERR_NOPLAYERS";
1062 case DPERR_NOSESSIONS:
1063 return "DPERR_NOSESSIONS";
1064 /* This one isn't defined yet in WINE sources. I don't know the value
1065 case DPERR_PENDING:
1066 return "DPERR_PENDING";
1068 case DPERR_SENDTOOBIG:
1069 return "DPERR_SENDTOOBIG";
1070 case DPERR_TIMEOUT:
1071 return "DPERR_TIMEOUT";
1072 case DPERR_UNAVAILABLE:
1073 return "DPERR_UNAVAILABLE";
1074 case DPERR_UNSUPPORTED:
1075 return "DPERR_UNSUPPORTED";
1076 case DPERR_BUSY:
1077 return "DPERR_BUSY";
1078 case DPERR_USERCANCEL:
1079 return "DPERR_USERCANCEL";
1080 case DPERR_NOINTERFACE:
1081 return "DPERR_NOINTERFACE";
1082 case DPERR_CANNOTCREATESERVER:
1083 return "DPERR_CANNOTCREATESERVER";
1084 case DPERR_PLAYERLOST:
1085 return "DPERR_PLAYERLOST";
1086 case DPERR_SESSIONLOST:
1087 return "DPERR_SESSIONLOST";
1088 case DPERR_UNINITIALIZED:
1089 return "DPERR_UNINITIALIZED";
1090 case DPERR_NONEWPLAYERS:
1091 return "DPERR_NONEWPLAYERS";
1092 case DPERR_INVALIDPASSWORD:
1093 return "DPERR_INVALIDPASSWORD";
1094 case DPERR_CONNECTING:
1095 return "DPERR_CONNECTING";
1096 case DPERR_CONNECTIONLOST:
1097 return "DPERR_CONNECTIONLOST";
1098 case DPERR_UNKNOWNMESSAGE:
1099 return "DPERR_UNKNOWNMESSAGE";
1100 case DPERR_CANCELFAILED:
1101 return "DPERR_CANCELFAILED";
1102 case DPERR_INVALIDPRIORITY:
1103 return "DPERR_INVALIDPRIORITY";
1104 case DPERR_NOTHANDLED:
1105 return "DPERR_NOTHANDLED";
1106 case DPERR_CANCELLED:
1107 return "DPERR_CANCELLED";
1108 case DPERR_ABORTED:
1109 return "DPERR_ABORTED";
1110 case DPERR_BUFFERTOOLARGE:
1111 return "DPERR_BUFFERTOOLARGE";
1112 case DPERR_CANTCREATEPROCESS:
1113 return "DPERR_CANTCREATEPROCESS";
1114 case DPERR_APPNOTSTARTED:
1115 return "DPERR_APPNOTSTARTED";
1116 case DPERR_INVALIDINTERFACE:
1117 return "DPERR_INVALIDINTERFACE";
1118 case DPERR_NOSERVICEPROVIDER:
1119 return "DPERR_NOSERVICEPROVIDER";
1120 case DPERR_UNKNOWNAPPLICATION:
1121 return "DPERR_UNKNOWNAPPLICATION";
1122 case DPERR_NOTLOBBIED:
1123 return "DPERR_NOTLOBBIED";
1124 case DPERR_SERVICEPROVIDERLOADED:
1125 return "DPERR_SERVICEPROVIDERLOADED";
1126 case DPERR_ALREADYREGISTERED:
1127 return "DPERR_ALREADYREGISTERED";
1128 case DPERR_NOTREGISTERED:
1129 return "DPERR_NOTREGISTERED";
1130 case DPERR_AUTHENTICATIONFAILED:
1131 return "DPERR_AUTHENTICATIONFAILED";
1132 case DPERR_CANTLOADSSPI:
1133 return "DPERR_CANTLOADSSPI";
1134 case DPERR_ENCRYPTIONFAILED:
1135 return "DPERR_ENCRYPTIONFAILED";
1136 case DPERR_SIGNFAILED:
1137 return "DPERR_SIGNFAILED";
1138 case DPERR_CANTLOADSECURITYPACKAGE:
1139 return "DPERR_CANTLOADSECURITYPACKAGE";
1140 case DPERR_ENCRYPTIONNOTSUPPORTED:
1141 return "DPERR_ENCRYPTIONNOTSUPPORTED";
1142 case DPERR_CANTLOADCAPI:
1143 return "DPERR_CANTLOADCAPI";
1144 case DPERR_NOTLOGGEDIN:
1145 return "DPERR_NOTLOGGEDIN";
1146 case DPERR_LOGONDENIED:
1147 return "DPERR_LOGONDENIED";
1148 default:
1149 /* For errors not in the list, return HRESULT as a string
1150 This part is not thread safe */
1151 WARN( "Unknown error 0x%08lx\n", hr );
1152 sprintf( szTempStr, "0x%08lx", hr );
1153 return szTempStr;