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

Last change on this file since 4314 was 4314, checked in by hugh, 25 years ago

Updated to latest wine version

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