source: trunk/src/DPlayX/dplayx_global.cpp@ 10367

Last change on this file since 10367 was 5526, checked in by sandervl, 24 years ago

compile fixes

File size: 35.7 KB
Line 
1// $Id: dplayx_global.cpp,v 1.5 2001-04-16 17:25:21 sandervl Exp $
2/* dplayx.dll global data implementation.
3 *
4 * Copyright 1999,2000 - Peter Hunnisett
5 *
6 * <presently under construction - contact hunnise@nortelnetworks.com>
7 *
8 */
9
10/* NOTE: Methods that begin with DPLAYX_ are used for dealing with
11 * dplayx.dll data which is accessible from all processes.
12 */
13
14#include <string.h>
15
16#include <odin.h>
17#define ICOM_CINTERFACE 1
18#define CINTERFACE
19
20#include "debugtools.h"
21#include "winbase.h"
22#include "winerror.h"
23#include "wine/unicode.h"
24#include "heap.h"
25
26#include "wingdi.h"
27#include "winuser.h"
28
29#include "dplayx_global.h"
30#include "dplayx_messages.h" /* For CreateMessageReceptionThread only */
31
32DEFAULT_DEBUG_CHANNEL(dplay);
33
34#undef debugstr_guid
35#define debugstr_guid(a) a
36
37
38/* FIXME: Need to do all that fun other dll referencing type of stuff */
39
40/* Static data for all processes */
41static LPCSTR lpszDplayxSemaName = "WINE_DPLAYX_SM";
42static HANDLE hDplayxSema;
43
44static LPCSTR lpszDplayxFileMapping = "WINE_DPLAYX_FM";
45static HANDLE hDplayxSharedMem;
46
47static LPVOID lpSharedStaticData = NULL;
48
49
50#define DPLAYX_AquireSemaphore() TRACE( "Waiting for DPLAYX semaphore\n" ); \
51 WaitForSingleObject( hDplayxSema, INFINITE );\
52 TRACE( "Through wait\n" )
53
54#define DPLAYX_ReleaseSemaphore() ReleaseSemaphore( hDplayxSema, 1, NULL ); \
55 TRACE( "DPLAYX Semaphore released\n" ) /* FIXME: Is this correct? */
56
57
58/* HACK for simple global data right now */
59#define dwStaticSharedSize (128 * 1024) /* 128 KBytes */
60#define dwDynamicSharedSize (512 * 1024) /* 512 KBytes */
61#define dwTotalSharedSize ( dwStaticSharedSize + dwDynamicSharedSize )
62
63
64/* FIXME: Is there no easier way? */
65
66/* Pretend the entire dynamic area is carved up into 512 byte blocks.
67 * Each block has 4 bytes which are 0 unless used */
68#define dwBlockSize 512
69#define dwMaxBlock (dwDynamicSharedSize/dwBlockSize)
70
71typedef struct
72{
73 DWORD used;
74 DWORD data[dwBlockSize-sizeof(DWORD)];
75} DPLAYX_MEM_SLICE;
76
77static DPLAYX_MEM_SLICE* lpMemArea;
78
79void DPLAYX_PrivHeapFree( LPVOID addr );
80void DPLAYX_PrivHeapFree( LPVOID addr )
81{
82 LPVOID lpAddrStart;
83 DWORD dwBlockUsed;
84
85 /* Handle getting passed a NULL */
86 if( addr == NULL )
87 {
88 return;
89 }
90
91 lpAddrStart = (LPVOID)((DWORD)addr - sizeof(DWORD)); /* Find block header */
92 dwBlockUsed = ((BYTE*)lpAddrStart - (BYTE*)lpMemArea)/dwBlockSize;
93
94 lpMemArea[ dwBlockUsed ].used = 0;
95}
96
97/* FIXME: This should be static, but is being used for a hack right now */
98LPVOID DPLAYX_PrivHeapAlloc( DWORD flags, DWORD size );
99LPVOID DPLAYX_PrivHeapAlloc( DWORD flags, DWORD size )
100{
101 LPVOID lpvArea = NULL;
102 UINT uBlockUsed;
103
104 if( size > (dwBlockSize - sizeof(DWORD)) )
105 {
106 FIXME( "Size exceeded. Request of 0x%08lx\n", size );
107 size = dwBlockSize - sizeof(DWORD);
108 }
109
110 /* Find blank area */
111 uBlockUsed = 0;
112 while( ( lpMemArea[ uBlockUsed ].used != 0 ) && ( uBlockUsed <= dwMaxBlock ) ) { uBlockUsed++; }
113
114 if( uBlockUsed <= dwMaxBlock )
115 {
116 /* Set the area used */
117 lpMemArea[ uBlockUsed ].used = 1;
118 lpvArea = &(lpMemArea[ uBlockUsed ].data);
119 }
120 else
121 {
122 ERR( "No free block found\n" );
123 return NULL;
124 }
125
126 if( flags & HEAP_ZERO_MEMORY )
127 {
128 ZeroMemory( lpvArea, size );
129 }
130
131 return lpvArea;
132}
133
134LPSTR DPLAYX_strdupA( DWORD flags, LPCSTR str );
135LPSTR DPLAYX_strdupA( DWORD flags, LPCSTR str )
136{
137 LPSTR p = (LPSTR)DPLAYX_PrivHeapAlloc( flags, strlen(str) + 1 );
138 if(p) {
139 strcpy( p, str );
140 }
141 return p;
142}
143
144LPWSTR DPLAYX_strdupW( DWORD flags, LPCWSTR str );
145LPWSTR DPLAYX_strdupW( DWORD flags, LPCWSTR str )
146{
147 INT len = strlenW(str) + 1;
148 LPWSTR p = (LPWSTR)DPLAYX_PrivHeapAlloc( flags, len * sizeof(WCHAR) );
149 if(p) {
150 strcpyW( p, str );
151 }
152 return p;
153}
154
155
156enum { numSupportedLobbies = 32, numSupportedSessions = 32 };
157typedef struct tagDPLAYX_LOBBYDATA
158{
159 /* Points to lpConn + block of contiguous extra memory for dynamic parts
160 * of the struct directly following
161 */
162 LPDPLCONNECTION lpConn;
163
164 /* Information for dplobby interfaces */
165 DWORD dwAppID;
166 DWORD dwAppLaunchedFromID;
167
168 /* Should this lobby app send messages to creator at important life
169 * stages
170 */
171 HANDLE hInformOnAppStart;
172 HANDLE hInformOnAppDeath;
173 HANDLE hInformOnSettingRead;
174
175 /* Sundries */
176 BOOL bWaitForConnectionSettings;
177 DWORD dwLobbyMsgThreadId;
178
179
180} DPLAYX_LOBBYDATA, *LPDPLAYX_LOBBYDATA;
181
182static DPLAYX_LOBBYDATA* lobbyData = NULL;
183/* static DPLAYX_LOBBYDATA lobbyData[ numSupportedLobbies ]; */
184
185static DPSESSIONDESC2* sessionData = NULL;
186/* static DPSESSIONDESC2* sessionData[ numSupportedSessions ]; */
187
188/* Function prototypes */
189DWORD DPLAYX_SizeOfLobbyDataA( LPDPLCONNECTION lpDplData );
190DWORD DPLAYX_SizeOfLobbyDataW( LPDPLCONNECTION lpDplData );
191void DPLAYX_CopyConnStructA( LPDPLCONNECTION dest, LPDPLCONNECTION src );
192void DPLAYX_CopyConnStructW( LPDPLCONNECTION dest, LPDPLCONNECTION src );
193BOOL DPLAYX_IsAppIdLobbied( DWORD dwAppId, LPDPLAYX_LOBBYDATA* dplData );
194void DPLAYX_InitializeLobbyDataEntry( LPDPLAYX_LOBBYDATA lpData );
195BOOL DPLAYX_CopyIntoSessionDesc2A( LPDPSESSIONDESC2 lpSessionDest,
196 LPCDPSESSIONDESC2 lpSessionSrc );
197
198
199
200/***************************************************************************
201 * Called to initialize the global data. This will only be used on the
202 * loading of the dll
203 ***************************************************************************/
204BOOL DPLAYX_ConstructData(void)
205{
206 SECURITY_ATTRIBUTES s_attrib;
207 BOOL bInitializeSharedMemory = FALSE;
208 LPVOID lpDesiredMemoryMapStart = (LPVOID)0x50000000;
209 HANDLE hInformOnStart;
210
211 TRACE( "DPLAYX dll loaded - construct called\n" );
212
213 /* Create a semaphore to block access to DPLAYX global data structs */
214
215 s_attrib.bInheritHandle = TRUE;
216 s_attrib.lpSecurityDescriptor = NULL;
217 s_attrib.nLength = sizeof(s_attrib);
218
219 hDplayxSema = CreateSemaphoreA( &s_attrib, 1, 1, lpszDplayxSemaName );
220
221 /* First instance creates the semaphore. Others just use it */
222 if( GetLastError() == ERROR_SUCCESS )
223 {
224 TRACE( "Semaphore %u created\n", hDplayxSema );
225
226 /* The semaphore creator will also build the shared memory */
227 bInitializeSharedMemory = TRUE;
228 }
229 else if ( GetLastError() == ERROR_ALREADY_EXISTS )
230 {
231 TRACE( "Found semaphore handle %u\n", hDplayxSema );
232 }
233 else
234 {
235 ERR( ": semaphore error 0x%08lx\n", GetLastError() );
236 return FALSE;
237 }
238
239 SetLastError( ERROR_SUCCESS );
240
241 DPLAYX_AquireSemaphore();
242
243 hDplayxSharedMem = CreateFileMappingA( INVALID_HANDLE_VALUE,
244 &s_attrib,
245 PAGE_READWRITE | SEC_COMMIT,
246 0,
247 dwTotalSharedSize,
248 lpszDplayxFileMapping );
249
250 if( GetLastError() == ERROR_SUCCESS )
251 {
252 TRACE( "File mapped %u created\n", hDplayxSharedMem );
253 }
254 else if ( GetLastError() == ERROR_ALREADY_EXISTS )
255 {
256 TRACE( "Found FileMapping handle %u\n", hDplayxSharedMem );
257 }
258 else
259 {
260 ERR( ": unable to create shared memory 0x%08lx\n", GetLastError() );
261 return FALSE;
262 }
263
264 lpSharedStaticData = MapViewOfFileEx( hDplayxSharedMem,
265 FILE_MAP_WRITE,
266 0, 0, 0, lpDesiredMemoryMapStart );
267
268 if( lpSharedStaticData == NULL )
269 {
270 ERR( ": unable to map static data into process memory space: 0x%08lx\n",
271 GetLastError() );
272 return FALSE;
273 }
274 else
275 {
276 if( lpDesiredMemoryMapStart == lpSharedStaticData )
277 {
278 TRACE( "File mapped to %p\n", lpSharedStaticData );
279 }
280 else
281 {
282 /* Presently the shared data structures use pointers. If the
283 * files are no mapped into the same area, the pointers will no
284 * longer make any sense :(
285 * FIXME: In the future make the shared data structures have some
286 * sort of fixup to make them independent between data spaces.
287 * This will also require a rework of the session data stuff.
288 */
289 ERR( "File mapped to %p (not %p). Expect failure\n",
290 lpSharedStaticData, lpDesiredMemoryMapStart );
291 }
292 }
293
294 /* Dynamic area starts just after the static area */
295 lpMemArea = (DPLAYX_MEM_SLICE*)((BYTE*)lpSharedStaticData + dwStaticSharedSize);
296
297 /* FIXME: Crude hack */
298 lobbyData = (DPLAYX_LOBBYDATA*)lpSharedStaticData;
299 sessionData = (DPSESSIONDESC2*)((BYTE*)lpSharedStaticData + (dwStaticSharedSize/2));
300
301 /* Initialize shared data segments. */
302 if( bInitializeSharedMemory )
303 {
304 UINT i;
305
306 TRACE( "Initializing shared memory\n" );
307
308 /* Set all lobbies to be "empty" */
309 for( i=0; i < numSupportedLobbies; i++ )
310 {
311 DPLAYX_InitializeLobbyDataEntry( &lobbyData[ i ] );
312 }
313
314 /* Set all sessions to be "empty" */
315 for( i=0; i < numSupportedSessions; i++ )
316 {
317 sessionData[i].dwSize = 0;
318 }
319
320 /* Zero out the dynmaic area */
321 ZeroMemory( lpMemArea, dwDynamicSharedSize );
322
323 /* Just for fun sync the whole data area */
324 FlushViewOfFile( lpSharedStaticData, dwTotalSharedSize );
325 }
326
327 DPLAYX_ReleaseSemaphore();
328
329 /* Everything was created correctly. Signal the lobby client that
330 * we started up correctly
331 */
332 if( DPLAYX_GetThisLobbyHandles( &hInformOnStart, NULL, NULL, FALSE ) &&
333 hInformOnStart
334 )
335 {
336 BOOL bSuccess;
337 bSuccess = SetEvent( hInformOnStart );
338 TRACE( "Signalling lobby app start event %u %s\n",
339 hInformOnStart, bSuccess ? "succeed" : "failed" );
340
341 /* Close out handle */
342 DPLAYX_GetThisLobbyHandles( &hInformOnStart, NULL, NULL, TRUE );
343 }
344
345 return TRUE;
346}
347
348/***************************************************************************
349 * Called to destroy all global data. This will only be used on the
350 * unloading of the dll
351 ***************************************************************************/
352BOOL DPLAYX_DestructData(void)
353{
354 HANDLE hInformOnDeath;
355
356 TRACE( "DPLAYX dll unloaded - destruct called\n" );
357
358 /* If required, inform that this app is dying */
359 if( DPLAYX_GetThisLobbyHandles( NULL, &hInformOnDeath, NULL, FALSE ) &&
360 hInformOnDeath
361 )
362 {
363 BOOL bSuccess;
364 bSuccess = SetEvent( hInformOnDeath );
365 TRACE( "Signalling lobby app death event %u %s\n",
366 hInformOnDeath, bSuccess ? "succeed" : "failed" );
367
368 /* Close out handle */
369 DPLAYX_GetThisLobbyHandles( NULL, &hInformOnDeath, NULL, TRUE );
370 }
371
372 /* DO CLEAN UP (LAST) */
373
374 /* Delete the semaphore */
375 CloseHandle( hDplayxSema );
376
377 /* Delete shared memory file mapping */
378 UnmapViewOfFile( lpSharedStaticData );
379 CloseHandle( hDplayxSharedMem );
380
381 return FALSE;
382}
383
384
385void DPLAYX_InitializeLobbyDataEntry( LPDPLAYX_LOBBYDATA lpData )
386{
387 ZeroMemory( lpData, sizeof( *lpData ) );
388}
389
390/* NOTE: This must be called with the semaphore aquired.
391 * TRUE/FALSE with a pointer to it's data returned. Pointer data is
392 * is only valid if TRUE is returned.
393 */
394BOOL DPLAYX_IsAppIdLobbied( DWORD dwAppID, LPDPLAYX_LOBBYDATA* lplpDplData )
395{
396 UINT i;
397
398 *lplpDplData = NULL;
399
400 if( dwAppID == 0 )
401 {
402 dwAppID = GetCurrentProcessId();
403 TRACE( "Translated dwAppID == 0 into 0x%08lx\n", dwAppID );
404 }
405
406 for( i=0; i < numSupportedLobbies; i++ )
407 {
408 if( lobbyData[ i ].dwAppID == dwAppID )
409 {
410 /* This process is lobbied */
411 TRACE( "Found 0x%08lx @ %u\n", dwAppID, i );
412 *lplpDplData = &lobbyData[ i ];
413 return TRUE;
414 }
415 }
416
417 return FALSE;
418}
419
420/* Reserve a spot for the new appliction. TRUE means success and FALSE failure. */
421BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID )
422{
423 UINT i;
424
425 /* 0 is the marker for unused application data slots */
426 if( dwAppID == 0 )
427 {
428 return FALSE;
429 }
430
431 DPLAYX_AquireSemaphore();
432
433 /* Find an empty space in the list and insert the data */
434 for( i=0; i < numSupportedLobbies; i++ )
435 {
436 if( lobbyData[ i ].dwAppID == 0 )
437 {
438 /* This process is now lobbied */
439 TRACE( "Setting lobbyData[%u] for (0x%08lx,0x%08lx)\n",
440 i, dwAppID, GetCurrentProcessId() );
441
442 lobbyData[ i ].dwAppID = dwAppID;
443 lobbyData[ i ].dwAppLaunchedFromID = GetCurrentProcessId();
444
445 /* FIXME: Where is the best place for this? In interface or here? */
446 lobbyData[ i ].hInformOnAppStart = 0;
447 lobbyData[ i ].hInformOnAppDeath = 0;
448 lobbyData[ i ].hInformOnSettingRead = 0;
449
450 DPLAYX_ReleaseSemaphore();
451 return TRUE;
452 }
453 }
454
455 ERR( "No empty lobbies\n" );
456
457 DPLAYX_ReleaseSemaphore();
458 return FALSE;
459}
460
461/* I'm not sure when I'm going to need this, but here it is */
462BOOL DPLAYX_DestroyLobbyApplication( DWORD dwAppID )
463{
464 UINT i;
465
466 DPLAYX_AquireSemaphore();
467
468 /* Find an empty space in the list and insert the data */
469 for( i=0; i < numSupportedLobbies; i++ )
470 {
471 if( lobbyData[ i ].dwAppID == dwAppID )
472 {
473 /* FIXME: Should free up anything unused. Tisk tisk :0 */
474 /* Mark this entry unused */
475 TRACE( "Marking lobbyData[%u] unused\n", i );
476 DPLAYX_InitializeLobbyDataEntry( &lobbyData[ i ] );
477
478 DPLAYX_ReleaseSemaphore();
479 return TRUE;
480 }
481 }
482
483 DPLAYX_ReleaseSemaphore();
484 ERR( "Unable to find global entry for application\n" );
485 return FALSE;
486}
487
488BOOL DPLAYX_SetLobbyHandles( DWORD dwAppID,
489 HANDLE hStart, HANDLE hDeath, HANDLE hConnRead )
490{
491 LPDPLAYX_LOBBYDATA lpLData;
492
493 /* Need to explictly give lobby application. Can't set for yourself */
494 if( dwAppID == 0 )
495 {
496 return FALSE;
497 }
498
499 DPLAYX_AquireSemaphore();
500
501 if( !DPLAYX_IsAppIdLobbied( dwAppID, &lpLData ) )
502 {
503 DPLAYX_ReleaseSemaphore();
504 return FALSE;
505 }
506
507 lpLData->hInformOnAppStart = hStart;
508 lpLData->hInformOnAppDeath = hDeath;
509 lpLData->hInformOnSettingRead = hConnRead;
510
511 DPLAYX_ReleaseSemaphore();
512
513 return TRUE;
514}
515
516BOOL DPLAYX_GetThisLobbyHandles( LPHANDLE lphStart,
517 LPHANDLE lphDeath,
518 LPHANDLE lphConnRead,
519 BOOL bClearSetHandles )
520{
521 LPDPLAYX_LOBBYDATA lpLData;
522
523 DPLAYX_AquireSemaphore();
524
525 if( !DPLAYX_IsAppIdLobbied( 0, &lpLData ) )
526 {
527 DPLAYX_ReleaseSemaphore();
528 return FALSE;
529 }
530
531 if( lphStart != NULL )
532 {
533 if( lpLData->hInformOnAppStart == 0 )
534 {
535 DPLAYX_ReleaseSemaphore();
536 return FALSE;
537 }
538
539 *lphStart = lpLData->hInformOnAppStart;
540
541 if( bClearSetHandles )
542 {
543 CloseHandle( lpLData->hInformOnAppStart );
544 lpLData->hInformOnAppStart = 0;
545 }
546 }
547
548 if( lphDeath != NULL )
549 {
550 if( lpLData->hInformOnAppDeath == 0 )
551 {
552 DPLAYX_ReleaseSemaphore();
553 return FALSE;
554 }
555
556 *lphDeath = lpLData->hInformOnAppDeath;
557
558 if( bClearSetHandles )
559 {
560 CloseHandle( lpLData->hInformOnAppDeath );
561 lpLData->hInformOnAppDeath = 0;
562 }
563 }
564
565 if( lphConnRead != NULL )
566 {
567 if( lpLData->hInformOnSettingRead == 0 )
568 {
569 DPLAYX_ReleaseSemaphore();
570 return FALSE;
571 }
572
573 *lphConnRead = lpLData->hInformOnSettingRead;
574
575 if( bClearSetHandles )
576 {
577 CloseHandle( lpLData->hInformOnSettingRead );
578 lpLData->hInformOnSettingRead = 0;
579 }
580 }
581
582 DPLAYX_ReleaseSemaphore();
583
584 return TRUE;
585}
586
587
588HRESULT DPLAYX_GetConnectionSettingsA
589( DWORD dwAppID,
590 LPVOID lpData,
591 LPDWORD lpdwDataSize )
592{
593 LPDPLAYX_LOBBYDATA lpDplData;
594 DWORD dwRequiredDataSize = 0;
595 HANDLE hInformOnSettingRead;
596
597 DPLAYX_AquireSemaphore();
598
599 if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) )
600 {
601 DPLAYX_ReleaseSemaphore();
602
603 TRACE( "Application 0x%08lx is not lobbied\n", dwAppID );
604 return DPERR_NOTLOBBIED;
605 }
606
607 dwRequiredDataSize = DPLAYX_SizeOfLobbyDataA( lpDplData->lpConn );
608
609 /* Do they want to know the required buffer size or is the provided buffer
610 * big enough?
611 */
612 if ( ( lpData == NULL ) ||
613 ( *lpdwDataSize < dwRequiredDataSize )
614 )
615 {
616 DPLAYX_ReleaseSemaphore();
617
618 *lpdwDataSize = DPLAYX_SizeOfLobbyDataA( lpDplData->lpConn );
619
620 return DPERR_BUFFERTOOSMALL;
621 }
622
623 DPLAYX_CopyConnStructA( (LPDPLCONNECTION)lpData, lpDplData->lpConn );
624
625 DPLAYX_ReleaseSemaphore();
626
627 /* They have gotten the information - signal the event if required */
628 if( DPLAYX_GetThisLobbyHandles( NULL, NULL, &hInformOnSettingRead, FALSE ) &&
629 hInformOnSettingRead
630 )
631 {
632 BOOL bSuccess;
633 bSuccess = SetEvent( hInformOnSettingRead );
634 TRACE( "Signalling setting read event %u %s\n",
635 hInformOnSettingRead, bSuccess ? "succeed" : "failed" );
636
637 /* Close out handle */
638 DPLAYX_GetThisLobbyHandles( NULL, NULL, &hInformOnSettingRead, TRUE );
639 }
640
641 return DP_OK;
642}
643
644/* Assumption: Enough contiguous space was allocated at dest */
645void DPLAYX_CopyConnStructA( LPDPLCONNECTION dest, LPDPLCONNECTION src )
646{
647 BYTE* lpStartOfFreeSpace;
648
649 CopyMemory( dest, src, sizeof( DPLCONNECTION ) );
650
651 lpStartOfFreeSpace = ((BYTE*)dest) + sizeof( DPLCONNECTION );
652
653 /* Copy the LPDPSESSIONDESC2 structure if it exists */
654 if( src->lpSessionDesc )
655 {
656 dest->lpSessionDesc = (LPDPSESSIONDESC2)lpStartOfFreeSpace;
657 lpStartOfFreeSpace += sizeof( DPSESSIONDESC2 );
658 CopyMemory( dest->lpSessionDesc, src->lpSessionDesc, sizeof( DPSESSIONDESC2 ) );
659
660 /* Session names may or may not exist */
661 if( src->lpSessionDesc->lpszSessionNameA )
662 {
663 strcpy( (LPSTR)lpStartOfFreeSpace, src->lpSessionDesc->lpszSessionNameA );
664 dest->lpSessionDesc->lpszSessionNameA = (LPSTR)lpStartOfFreeSpace;
665 lpStartOfFreeSpace +=
666 strlen( (LPSTR)dest->lpSessionDesc->lpszSessionNameA ) + 1;
667 }
668
669 if( src->lpSessionDesc->lpszPasswordA )
670 {
671 strcpy( (LPSTR)lpStartOfFreeSpace, src->lpSessionDesc->lpszPasswordA );
672 dest->lpSessionDesc->lpszPasswordA = (LPSTR)lpStartOfFreeSpace;
673 lpStartOfFreeSpace +=
674 strlen( (LPSTR)dest->lpSessionDesc->lpszPasswordA ) + 1;
675 }
676 }
677
678 /* DPNAME structure is optional */
679 if( src->lpPlayerName )
680 {
681 dest->lpPlayerName = (LPDPNAME)lpStartOfFreeSpace;
682 lpStartOfFreeSpace += sizeof( DPNAME );
683 CopyMemory( dest->lpPlayerName, src->lpPlayerName, sizeof( DPNAME ) );
684
685 if( src->lpPlayerName->lpszShortNameA )
686 {
687 strcpy( (LPSTR)lpStartOfFreeSpace, src->lpPlayerName->lpszShortNameA );
688 dest->lpPlayerName->lpszShortNameA = (LPSTR)lpStartOfFreeSpace;
689 lpStartOfFreeSpace +=
690 strlen( (LPSTR)dest->lpPlayerName->lpszShortNameA ) + 1;
691 }
692
693 if( src->lpPlayerName->lpszLongNameA )
694 {
695 strcpy( (LPSTR)lpStartOfFreeSpace, src->lpPlayerName->lpszLongNameA );
696 dest->lpPlayerName->lpszLongNameA = (LPSTR)lpStartOfFreeSpace;
697 lpStartOfFreeSpace +=
698 strlen( (LPSTR)dest->lpPlayerName->lpszLongName ) + 1 ;
699 }
700
701 }
702
703 /* Copy address if it exists */
704 if( src->lpAddress )
705 {
706 dest->lpAddress = (LPVOID)lpStartOfFreeSpace;
707 CopyMemory( lpStartOfFreeSpace, src->lpAddress, src->dwAddressSize );
708 /* No need to advance lpStartOfFreeSpace as there is no more "dynamic" data */
709 }
710}
711
712HRESULT DPLAYX_GetConnectionSettingsW
713( DWORD dwAppID,
714 LPVOID lpData,
715 LPDWORD lpdwDataSize )
716{
717 LPDPLAYX_LOBBYDATA lpDplData;
718 DWORD dwRequiredDataSize = 0;
719 HANDLE hInformOnSettingRead;
720
721 DPLAYX_AquireSemaphore();
722
723 if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) )
724 {
725 DPLAYX_ReleaseSemaphore();
726 return DPERR_NOTLOBBIED;
727 }
728
729 dwRequiredDataSize = DPLAYX_SizeOfLobbyDataW( lpDplData->lpConn );
730
731 /* Do they want to know the required buffer size or is the provided buffer
732 * big enough?
733 */
734 if ( ( lpData == NULL ) ||
735 ( *lpdwDataSize < dwRequiredDataSize )
736 )
737 {
738 DPLAYX_ReleaseSemaphore();
739
740 *lpdwDataSize = DPLAYX_SizeOfLobbyDataW( lpDplData->lpConn );
741
742 return DPERR_BUFFERTOOSMALL;
743 }
744
745 DPLAYX_CopyConnStructW( (LPDPLCONNECTION)lpData, lpDplData->lpConn );
746
747 DPLAYX_ReleaseSemaphore();
748
749 /* They have gotten the information - signal the event if required */
750 if( DPLAYX_GetThisLobbyHandles( NULL, NULL, &hInformOnSettingRead, FALSE ) &&
751 hInformOnSettingRead
752 )
753 {
754 BOOL bSuccess;
755 bSuccess = SetEvent( hInformOnSettingRead );
756 TRACE( "Signalling setting read event %u %s\n",
757 hInformOnSettingRead, bSuccess ? "succeed" : "failed" );
758
759 /* Close out handle */
760 DPLAYX_GetThisLobbyHandles( NULL, NULL, &hInformOnSettingRead, TRUE );
761 }
762
763 return DP_OK;
764}
765
766/* Assumption: Enough contiguous space was allocated at dest */
767void DPLAYX_CopyConnStructW( LPDPLCONNECTION dest, LPDPLCONNECTION src )
768{
769 BYTE* lpStartOfFreeSpace;
770
771 CopyMemory( dest, src, sizeof( DPLCONNECTION ) );
772
773 lpStartOfFreeSpace = ( (BYTE*)dest) + sizeof( DPLCONNECTION );
774
775 /* Copy the LPDPSESSIONDESC2 structure if it exists */
776 if( src->lpSessionDesc )
777 {
778 dest->lpSessionDesc = (LPDPSESSIONDESC2)lpStartOfFreeSpace;
779 lpStartOfFreeSpace += sizeof( DPSESSIONDESC2 );
780 CopyMemory( dest->lpSessionDesc, src->lpSessionDesc, sizeof( DPSESSIONDESC2 ) );
781
782 /* Session names may or may not exist */
783 if( src->lpSessionDesc->lpszSessionName )
784 {
785 strcpyW( (LPWSTR)lpStartOfFreeSpace, dest->lpSessionDesc->lpszSessionName );
786 src->lpSessionDesc->lpszSessionName = (LPWSTR)lpStartOfFreeSpace;
787 lpStartOfFreeSpace += sizeof(WCHAR) *
788 ( strlenW( (LPWSTR)dest->lpSessionDesc->lpszSessionName ) + 1 );
789 }
790
791 if( src->lpSessionDesc->lpszPassword )
792 {
793 strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpSessionDesc->lpszPassword );
794 dest->lpSessionDesc->lpszPassword = (LPWSTR)lpStartOfFreeSpace;
795 lpStartOfFreeSpace += sizeof(WCHAR) *
796 ( strlenW( (LPWSTR)dest->lpSessionDesc->lpszPassword ) + 1 );
797 }
798 }
799
800 /* DPNAME structure is optional */
801 if( src->lpPlayerName )
802 {
803 dest->lpPlayerName = (LPDPNAME)lpStartOfFreeSpace;
804 lpStartOfFreeSpace += sizeof( DPNAME );
805 CopyMemory( dest->lpPlayerName, src->lpPlayerName, sizeof( DPNAME ) );
806
807 if( src->lpPlayerName->lpszShortName )
808 {
809 strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpPlayerName->lpszShortName );
810 dest->lpPlayerName->lpszShortName = (LPWSTR)lpStartOfFreeSpace;
811 lpStartOfFreeSpace += sizeof(WCHAR) *
812 ( strlenW( (LPWSTR)dest->lpPlayerName->lpszShortName ) + 1 );
813 }
814
815 if( src->lpPlayerName->lpszLongName )
816 {
817 strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpPlayerName->lpszLongName );
818 dest->lpPlayerName->lpszLongName = (LPWSTR)lpStartOfFreeSpace;
819 lpStartOfFreeSpace += sizeof(WCHAR) *
820 ( strlenW( (LPWSTR)dest->lpPlayerName->lpszLongName ) + 1 );
821 }
822
823 }
824
825 /* Copy address if it exists */
826 if( src->lpAddress )
827 {
828 dest->lpAddress = (LPVOID)lpStartOfFreeSpace;
829 CopyMemory( lpStartOfFreeSpace, src->lpAddress, src->dwAddressSize );
830 /* No need to advance lpStartOfFreeSpace as there is no more "dynamic" data */
831 }
832
833}
834
835/* Store the structure into the shared data structre. Ensure that allocs for
836 * variable length strings come from the shared data structure.
837 * FIXME: We need to free information as well
838 */
839HRESULT DPLAYX_SetConnectionSettingsA
840( DWORD dwFlags,
841 DWORD dwAppID,
842 LPDPLCONNECTION lpConn )
843{
844 LPDPLAYX_LOBBYDATA lpDplData;
845
846 /* Paramater check */
847 if( dwFlags || !lpConn )
848 {
849 ERR("invalid parameters.\n");
850 return DPERR_INVALIDPARAMS;
851 }
852
853 /* Store information */
854 if( lpConn->dwSize != sizeof(DPLCONNECTION) )
855 {
856 ERR(": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n",
857 lpConn->dwSize, sizeof( DPLCONNECTION ) );
858
859 return DPERR_INVALIDPARAMS;
860 }
861
862 DPLAYX_AquireSemaphore();
863
864 if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) )
865 {
866 DPLAYX_ReleaseSemaphore();
867
868 return DPERR_NOTLOBBIED;
869 }
870
871 if( (!lpConn->lpSessionDesc ) ||
872 ( lpConn->lpSessionDesc->dwSize != sizeof( DPSESSIONDESC2 ) )
873 )
874 {
875 DPLAYX_ReleaseSemaphore();
876
877 ERR("DPSESSIONDESC passed in? Size=%lu vs. expected=%u bytes\n",
878 lpConn->lpSessionDesc->dwSize, sizeof( DPSESSIONDESC2 ) );
879
880 return DPERR_INVALIDPARAMS;
881 }
882
883 /* Free the existing memory */
884 DPLAYX_PrivHeapFree( lpDplData->lpConn );
885
886 lpDplData->lpConn = (LPDPLCONNECTION) DPLAYX_PrivHeapAlloc( HEAP_ZERO_MEMORY,
887 DPLAYX_SizeOfLobbyDataA( lpConn ) );
888
889 DPLAYX_CopyConnStructA( lpDplData->lpConn, lpConn );
890
891
892 DPLAYX_ReleaseSemaphore();
893
894 /* FIXME: Send a message - I think */
895
896 return DP_OK;
897}
898
899/* Store the structure into the shared data structre. Ensure that allocs for
900 * variable length strings come from the shared data structure.
901 * FIXME: We need to free information as well
902 */
903HRESULT DPLAYX_SetConnectionSettingsW
904( DWORD dwFlags,
905 DWORD dwAppID,
906 LPDPLCONNECTION lpConn )
907{
908 LPDPLAYX_LOBBYDATA lpDplData;
909
910 /* Paramater check */
911 if( dwFlags || !lpConn )
912 {
913 ERR("invalid parameters.\n");
914 return DPERR_INVALIDPARAMS;
915 }
916
917 /* Store information */
918 if( lpConn->dwSize != sizeof(DPLCONNECTION) )
919 {
920 ERR(": old/new DPLCONNECTION type? Size=%lu vs. expected=%u bytes\n",
921 lpConn->dwSize, sizeof( DPLCONNECTION ) );
922
923 return DPERR_INVALIDPARAMS;
924 }
925
926 DPLAYX_AquireSemaphore();
927
928 if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) )
929 {
930 DPLAYX_ReleaseSemaphore();
931
932 return DPERR_NOTLOBBIED;
933 }
934
935 /* Free the existing memory */
936 DPLAYX_PrivHeapFree( lpDplData->lpConn );
937
938 lpDplData->lpConn = (LPDPLCONNECTION) DPLAYX_PrivHeapAlloc( HEAP_ZERO_MEMORY,
939 DPLAYX_SizeOfLobbyDataW( lpConn ) );
940
941 DPLAYX_CopyConnStructW( lpDplData->lpConn, lpConn );
942
943
944 DPLAYX_ReleaseSemaphore();
945
946 /* FIXME: Send a message - I think */
947
948 return DP_OK;
949}
950
951DWORD DPLAYX_SizeOfLobbyDataA( LPDPLCONNECTION lpConn )
952{
953 DWORD dwTotalSize = sizeof( DPLCONNECTION );
954
955 /* Just a safety check */
956 if( lpConn == NULL )
957 {
958 ERR( "lpConn is NULL\n" );
959 return 0;
960 }
961
962 if( lpConn->lpSessionDesc != NULL )
963 {
964 dwTotalSize += sizeof( DPSESSIONDESC2 );
965
966 if( lpConn->lpSessionDesc->lpszSessionNameA )
967 {
968 dwTotalSize += strlen( lpConn->lpSessionDesc->lpszSessionNameA ) + 1;
969 }
970
971 if( lpConn->lpSessionDesc->lpszPasswordA )
972 {
973 dwTotalSize += strlen( lpConn->lpSessionDesc->lpszPasswordA ) + 1;
974 }
975 }
976
977 if( lpConn->lpPlayerName != NULL )
978 {
979 dwTotalSize += sizeof( DPNAME );
980
981 if( lpConn->lpPlayerName->lpszShortNameA )
982 {
983 dwTotalSize += strlen( lpConn->lpPlayerName->lpszShortNameA ) + 1;
984 }
985
986 if( lpConn->lpPlayerName->lpszLongNameA )
987 {
988 dwTotalSize += strlen( lpConn->lpPlayerName->lpszLongNameA ) + 1;
989 }
990
991 }
992
993 dwTotalSize += lpConn->dwAddressSize;
994
995 return dwTotalSize;
996}
997
998DWORD DPLAYX_SizeOfLobbyDataW( LPDPLCONNECTION lpConn )
999{
1000 DWORD dwTotalSize = sizeof( DPLCONNECTION );
1001
1002 /* Just a safety check */
1003 if( lpConn == NULL )
1004 {
1005 ERR( "lpConn is NULL\n" );
1006 return 0;
1007 }
1008
1009 if( lpConn->lpSessionDesc != NULL )
1010 {
1011 dwTotalSize += sizeof( DPSESSIONDESC2 );
1012
1013 if( lpConn->lpSessionDesc->lpszSessionName )
1014 {
1015 dwTotalSize += sizeof( WCHAR ) *
1016 ( strlenW( lpConn->lpSessionDesc->lpszSessionName ) + 1 );
1017 }
1018
1019 if( lpConn->lpSessionDesc->lpszPassword )
1020 {
1021 dwTotalSize += sizeof( WCHAR ) *
1022 ( strlenW( lpConn->lpSessionDesc->lpszPassword ) + 1 );
1023 }
1024 }
1025
1026 if( lpConn->lpPlayerName != NULL )
1027 {
1028 dwTotalSize += sizeof( DPNAME );
1029
1030 if( lpConn->lpPlayerName->lpszShortName )
1031 {
1032 dwTotalSize += sizeof( WCHAR ) *
1033 ( strlenW( lpConn->lpPlayerName->lpszShortName ) + 1 );
1034 }
1035
1036 if( lpConn->lpPlayerName->lpszLongName )
1037 {
1038 dwTotalSize += sizeof( WCHAR ) *
1039 ( strlenW( lpConn->lpPlayerName->lpszLongName ) + 1 );
1040 }
1041
1042 }
1043
1044 dwTotalSize += lpConn->dwAddressSize;
1045
1046 return dwTotalSize;
1047}
1048
1049
1050
1051LPDPSESSIONDESC2 DPLAYX_CopyAndAllocateSessionDesc2A( LPCDPSESSIONDESC2 lpSessionSrc )
1052{
1053 LPDPSESSIONDESC2 lpSessionDest =
1054 (LPDPSESSIONDESC2)HeapAlloc( GetProcessHeap(),
1055 HEAP_ZERO_MEMORY, sizeof( *lpSessionSrc ) );
1056 DPLAYX_CopyIntoSessionDesc2A( lpSessionDest, lpSessionSrc );
1057
1058 return lpSessionDest;
1059}
1060
1061/* Copy an ANSI session desc structure to the given buffer */
1062BOOL DPLAYX_CopyIntoSessionDesc2A( LPDPSESSIONDESC2 lpSessionDest,
1063 LPCDPSESSIONDESC2 lpSessionSrc )
1064{
1065 CopyMemory( lpSessionDest, lpSessionSrc, sizeof( *lpSessionSrc ) );
1066
1067 if( lpSessionSrc->lpszSessionNameA )
1068 {
1069 if ((lpSessionDest->lpszSessionNameA = (LPSTR)HeapAlloc( GetProcessHeap(), 0,
1070 strlen(lpSessionSrc->lpszSessionNameA)+1 )))
1071 strcpy( lpSessionDest->lpszSessionNameA, lpSessionSrc->lpszSessionNameA );
1072 }
1073 if( lpSessionSrc->lpszPasswordA )
1074 {
1075 if ((lpSessionDest->lpszPasswordA = (LPSTR)HeapAlloc( GetProcessHeap(), 0,
1076 strlen(lpSessionSrc->lpszPasswordA)+1 )))
1077 strcpy( lpSessionDest->lpszPasswordA, lpSessionSrc->lpszPasswordA );
1078 }
1079
1080 return TRUE;
1081}
1082
1083/* Start the index at 0. index will be updated to equal that which should
1084 be passed back into this function for the next element */
1085LPDPSESSIONDESC2 DPLAYX_CopyAndAllocateLocalSession( UINT* index )
1086{
1087 for( ; (*index) < numSupportedSessions; (*index)++ )
1088 {
1089 if( sessionData[(*index)].dwSize != 0 )
1090 {
1091 return DPLAYX_CopyAndAllocateSessionDesc2A( &sessionData[(*index)++] );
1092 }
1093 }
1094
1095 /* No more sessions */
1096 return NULL;
1097}
1098
1099/* Start the index at 0. index will be updated to equal that which should
1100 be passed back into this function for the next element */
1101BOOL DPLAYX_CopyLocalSession( UINT* index, LPDPSESSIONDESC2 lpsd )
1102{
1103 for( ; (*index) < numSupportedSessions; (*index)++ )
1104 {
1105 if( sessionData[(*index)].dwSize != 0 )
1106 {
1107 return DPLAYX_CopyIntoSessionDesc2A( lpsd, &sessionData[(*index)++] );
1108 }
1109 }
1110
1111 /* No more sessions */
1112 return FALSE;
1113}
1114
1115void DPLAYX_SetLocalSession( LPCDPSESSIONDESC2 lpsd )
1116{
1117 UINT i;
1118
1119 /* FIXME: Is this an error if it exists already? */
1120
1121 /* Crude/wrong implementation for now. Just always add to first empty spot */
1122 for( i=0; i < numSupportedSessions; i++ )
1123 {
1124 /* Is this one empty? */
1125 if( sessionData[i].dwSize == 0 )
1126 {
1127 DPLAYX_CopyIntoSessionDesc2A( &sessionData[i], lpsd );
1128 break;
1129 }
1130 }
1131
1132}
1133
1134BOOL DPLAYX_WaitForConnectionSettings( BOOL bWait )
1135{
1136 LPDPLAYX_LOBBYDATA lpLobbyData;
1137
1138 DPLAYX_AquireSemaphore();
1139
1140 if( !DPLAYX_IsAppIdLobbied( 0, &lpLobbyData ) )
1141 {
1142 DPLAYX_ReleaseSemaphore();
1143 return FALSE;
1144 }
1145
1146 lpLobbyData->bWaitForConnectionSettings = bWait;
1147
1148 DPLAYX_ReleaseSemaphore();
1149
1150 return TRUE;
1151}
1152
1153BOOL DPLAYX_AnyLobbiesWaitingForConnSettings(void)
1154{
1155 UINT i;
1156 BOOL bFound = FALSE;
1157
1158 DPLAYX_AquireSemaphore();
1159
1160 for( i=0; i < numSupportedLobbies; i++ )
1161 {
1162 if( ( lobbyData[ i ].dwAppID != 0 ) && /* lobby initialized */
1163 ( lobbyData[ i ].bWaitForConnectionSettings ) /* Waiting */
1164 )
1165 {
1166 bFound = TRUE;
1167 break;
1168 }
1169 }
1170
1171 DPLAYX_ReleaseSemaphore();
1172
1173 return bFound;
1174}
1175
1176BOOL DPLAYX_SetLobbyMsgThreadId( DWORD dwAppId, DWORD dwThreadId )
1177{
1178 LPDPLAYX_LOBBYDATA lpLobbyData;
1179
1180 DPLAYX_AquireSemaphore();
1181
1182 if( !DPLAYX_IsAppIdLobbied( dwAppId, &lpLobbyData ) )
1183 {
1184 DPLAYX_ReleaseSemaphore();
1185 return FALSE;
1186 }
1187
1188 lpLobbyData->dwLobbyMsgThreadId = dwThreadId;
1189
1190 DPLAYX_ReleaseSemaphore();
1191
1192 return TRUE;
1193}
1194
1195/* NOTE: This is potentially not thread safe. You are not guaranteed to end up
1196 with the correct string printed in the case where the HRESULT is not
1197 known. You'll just get the last hr passed in printed. This can change
1198 over time if this method is used alot :) */
1199LPCSTR DPLAYX_HresultToString(HRESULT hr)
1200{
1201 static char szTempStr[12];
1202
1203 switch (hr)
1204 {
1205 case DP_OK:
1206 return "DP_OK";
1207 case DPERR_ALREADYINITIALIZED:
1208 return "DPERR_ALREADYINITIALIZED";
1209 case DPERR_ACCESSDENIED:
1210 return "DPERR_ACCESSDENIED";
1211 case DPERR_ACTIVEPLAYERS:
1212 return "DPERR_ACTIVEPLAYERS";
1213 case DPERR_BUFFERTOOSMALL:
1214 return "DPERR_BUFFERTOOSMALL";
1215 case DPERR_CANTADDPLAYER:
1216 return "DPERR_CANTADDPLAYER";
1217 case DPERR_CANTCREATEGROUP:
1218 return "DPERR_CANTCREATEGROUP";
1219 case DPERR_CANTCREATEPLAYER:
1220 return "DPERR_CANTCREATEPLAYER";
1221 case DPERR_CANTCREATESESSION:
1222 return "DPERR_CANTCREATESESSION";
1223 case DPERR_CAPSNOTAVAILABLEYET:
1224 return "DPERR_CAPSNOTAVAILABLEYET";
1225 case DPERR_EXCEPTION:
1226 return "DPERR_EXCEPTION";
1227 case DPERR_GENERIC:
1228 return "DPERR_GENERIC";
1229 case DPERR_INVALIDFLAGS:
1230 return "DPERR_INVALIDFLAGS";
1231 case DPERR_INVALIDOBJECT:
1232 return "DPERR_INVALIDOBJECT";
1233 case DPERR_INVALIDPARAMS:
1234 return "DPERR_INVALIDPARAMS";
1235 case DPERR_INVALIDPLAYER:
1236 return "DPERR_INVALIDPLAYER";
1237 case DPERR_INVALIDGROUP:
1238 return "DPERR_INVALIDGROUP";
1239 case DPERR_NOCAPS:
1240 return "DPERR_NOCAPS";
1241 case DPERR_NOCONNECTION:
1242 return "DPERR_NOCONNECTION";
1243 case DPERR_OUTOFMEMORY:
1244 return "DPERR_OUTOFMEMORY";
1245 case DPERR_NOMESSAGES:
1246 return "DPERR_NOMESSAGES";
1247 case DPERR_NONAMESERVERFOUND:
1248 return "DPERR_NONAMESERVERFOUND";
1249 case DPERR_NOPLAYERS:
1250 return "DPERR_NOPLAYERS";
1251 case DPERR_NOSESSIONS:
1252 return "DPERR_NOSESSIONS";
1253/* This one isn't defined yet in WINE sources. I don't know the value
1254 case DPERR_PENDING:
1255 return "DPERR_PENDING";
1256*/
1257 case DPERR_SENDTOOBIG:
1258 return "DPERR_SENDTOOBIG";
1259 case DPERR_TIMEOUT:
1260 return "DPERR_TIMEOUT";
1261 case DPERR_UNAVAILABLE:
1262 return "DPERR_UNAVAILABLE";
1263 case DPERR_UNSUPPORTED:
1264 return "DPERR_UNSUPPORTED";
1265 case DPERR_BUSY:
1266 return "DPERR_BUSY";
1267 case DPERR_USERCANCEL:
1268 return "DPERR_USERCANCEL";
1269 case DPERR_NOINTERFACE:
1270 return "DPERR_NOINTERFACE";
1271 case DPERR_CANNOTCREATESERVER:
1272 return "DPERR_CANNOTCREATESERVER";
1273 case DPERR_PLAYERLOST:
1274 return "DPERR_PLAYERLOST";
1275 case DPERR_SESSIONLOST:
1276 return "DPERR_SESSIONLOST";
1277 case DPERR_UNINITIALIZED:
1278 return "DPERR_UNINITIALIZED";
1279 case DPERR_NONEWPLAYERS:
1280 return "DPERR_NONEWPLAYERS";
1281 case DPERR_INVALIDPASSWORD:
1282 return "DPERR_INVALIDPASSWORD";
1283 case DPERR_CONNECTING:
1284 return "DPERR_CONNECTING";
1285 case DPERR_CONNECTIONLOST:
1286 return "DPERR_CONNECTIONLOST";
1287 case DPERR_UNKNOWNMESSAGE:
1288 return "DPERR_UNKNOWNMESSAGE";
1289 case DPERR_CANCELFAILED:
1290 return "DPERR_CANCELFAILED";
1291 case DPERR_INVALIDPRIORITY:
1292 return "DPERR_INVALIDPRIORITY";
1293 case DPERR_NOTHANDLED:
1294 return "DPERR_NOTHANDLED";
1295 case DPERR_CANCELLED:
1296 return "DPERR_CANCELLED";
1297 case DPERR_ABORTED:
1298 return "DPERR_ABORTED";
1299 case DPERR_BUFFERTOOLARGE:
1300 return "DPERR_BUFFERTOOLARGE";
1301 case DPERR_CANTCREATEPROCESS:
1302 return "DPERR_CANTCREATEPROCESS";
1303 case DPERR_APPNOTSTARTED:
1304 return "DPERR_APPNOTSTARTED";
1305 case DPERR_INVALIDINTERFACE:
1306 return "DPERR_INVALIDINTERFACE";
1307 case DPERR_NOSERVICEPROVIDER:
1308 return "DPERR_NOSERVICEPROVIDER";
1309 case DPERR_UNKNOWNAPPLICATION:
1310 return "DPERR_UNKNOWNAPPLICATION";
1311 case DPERR_NOTLOBBIED:
1312 return "DPERR_NOTLOBBIED";
1313 case DPERR_SERVICEPROVIDERLOADED:
1314 return "DPERR_SERVICEPROVIDERLOADED";
1315 case DPERR_ALREADYREGISTERED:
1316 return "DPERR_ALREADYREGISTERED";
1317 case DPERR_NOTREGISTERED:
1318 return "DPERR_NOTREGISTERED";
1319 case DPERR_AUTHENTICATIONFAILED:
1320 return "DPERR_AUTHENTICATIONFAILED";
1321 case DPERR_CANTLOADSSPI:
1322 return "DPERR_CANTLOADSSPI";
1323 case DPERR_ENCRYPTIONFAILED:
1324 return "DPERR_ENCRYPTIONFAILED";
1325 case DPERR_SIGNFAILED:
1326 return "DPERR_SIGNFAILED";
1327 case DPERR_CANTLOADSECURITYPACKAGE:
1328 return "DPERR_CANTLOADSECURITYPACKAGE";
1329 case DPERR_ENCRYPTIONNOTSUPPORTED:
1330 return "DPERR_ENCRYPTIONNOTSUPPORTED";
1331 case DPERR_CANTLOADCAPI:
1332 return "DPERR_CANTLOADCAPI";
1333 case DPERR_NOTLOGGEDIN:
1334 return "DPERR_NOTLOGGEDIN";
1335 case DPERR_LOGONDENIED:
1336 return "DPERR_LOGONDENIED";
1337 default:
1338 /* For errors not in the list, return HRESULT as a string
1339 This part is not thread safe */
1340 WARN( "Unknown error 0x%08lx\n", hr );
1341 wsprintfA( szTempStr, "0x%08lx", hr );
1342 return szTempStr;
1343 }
1344}
1345
Note: See TracBrowser for help on using the repository browser.