Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendplayx_global.c
Go to the documentation of this file.
00001 /* dplayx.dll global data implementation. 00002 * 00003 * Copyright 1999,2000 - Peter Hunnisett 00004 * 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 * 00020 * 00021 * NOTES: 00022 * o Implementation of all things which are associated with dplay on 00023 * the computer - ie shared resources and such. Methods in this 00024 * compilation unit should not call anything out side this unit 00025 * excepting base windows services and an interface to start the 00026 * messaging thread. 00027 * o Methods that begin with DPLAYX_ are used for dealing with 00028 * dplayx.dll data which is accessible from all processes. 00029 * 00030 */ 00031 00032 #include <stdarg.h> 00033 #include <string.h> 00034 00035 #define NONAMELESSUNION 00036 #define NONAMELESSSTRUCT 00037 #include "wine/debug.h" 00038 #include "windef.h" 00039 #include "winbase.h" 00040 #include "winerror.h" 00041 #include "wine/unicode.h" 00042 00043 #include "wingdi.h" 00044 #include "winuser.h" 00045 00046 #include "dplayx_global.h" 00047 #include "dplayx_messages.h" /* For CreateMessageReceptionThread only */ 00048 00049 WINE_DEFAULT_DEBUG_CHANNEL(dplay); 00050 00051 /* FIXME: Need to do all that fun other dll referencing type of stuff */ 00052 00053 /* Static data for all processes */ 00054 static LPCSTR lpszDplayxSemaName = "WINE_DPLAYX_SM"; 00055 static HANDLE hDplayxSema; 00056 00057 static LPCSTR lpszDplayxFileMapping = "WINE_DPLAYX_FM"; 00058 static HANDLE hDplayxSharedMem; 00059 00060 static LPVOID lpSharedStaticData = NULL; 00061 00062 00063 #define DPLAYX_AquireSemaphore() TRACE( "Waiting for DPLAYX semaphore\n" ); \ 00064 WaitForSingleObject( hDplayxSema, INFINITE );\ 00065 TRACE( "Through wait\n" ) 00066 00067 #define DPLAYX_ReleaseSemaphore() ReleaseSemaphore( hDplayxSema, 1, NULL ); \ 00068 TRACE( "DPLAYX Semaphore released\n" ) /* FIXME: Is this correct? */ 00069 00070 00071 /* HACK for simple global data right now */ 00072 #define dwStaticSharedSize (128 * 1024) /* 128 KBytes */ 00073 #define dwDynamicSharedSize (512 * 1024) /* 512 KBytes */ 00074 #define dwTotalSharedSize ( dwStaticSharedSize + dwDynamicSharedSize ) 00075 00076 00077 /* FIXME: Is there no easier way? */ 00078 00079 /* Pretend the entire dynamic area is carved up into 512 byte blocks. 00080 * Each block has 4 bytes which are 0 unless used */ 00081 #define dwBlockSize 512 00082 #define dwMaxBlock (dwDynamicSharedSize/dwBlockSize) 00083 00084 typedef struct 00085 { 00086 DWORD used; 00087 DWORD data[dwBlockSize-sizeof(DWORD)]; 00088 } DPLAYX_MEM_SLICE; 00089 00090 static DPLAYX_MEM_SLICE* lpMemArea; 00091 00092 void DPLAYX_PrivHeapFree( LPVOID addr ); 00093 void DPLAYX_PrivHeapFree( LPVOID addr ) 00094 { 00095 LPVOID lpAddrStart; 00096 DWORD dwBlockUsed; 00097 00098 /* Handle getting passed a NULL */ 00099 if( addr == NULL ) 00100 { 00101 return; 00102 } 00103 00104 lpAddrStart = (char*)addr - sizeof(DWORD); /* Find block header */ 00105 dwBlockUsed = ((BYTE*)lpAddrStart - (BYTE*)lpMemArea)/dwBlockSize; 00106 00107 lpMemArea[ dwBlockUsed ].used = 0; 00108 } 00109 00110 /* FIXME: This should be static, but is being used for a hack right now */ 00111 LPVOID DPLAYX_PrivHeapAlloc( DWORD flags, DWORD size ); 00112 LPVOID DPLAYX_PrivHeapAlloc( DWORD flags, DWORD size ) 00113 { 00114 LPVOID lpvArea = NULL; 00115 UINT uBlockUsed; 00116 00117 if( size > (dwBlockSize - sizeof(DWORD)) ) 00118 { 00119 FIXME( "Size exceeded. Request of 0x%08lx\n", size ); 00120 size = dwBlockSize - sizeof(DWORD); 00121 } 00122 00123 /* Find blank area */ 00124 uBlockUsed = 0; 00125 while( ( lpMemArea[ uBlockUsed ].used != 0 ) && ( uBlockUsed <= dwMaxBlock ) ) { uBlockUsed++; } 00126 00127 if( uBlockUsed <= dwMaxBlock ) 00128 { 00129 /* Set the area used */ 00130 lpMemArea[ uBlockUsed ].used = 1; 00131 lpvArea = &(lpMemArea[ uBlockUsed ].data); 00132 } 00133 else 00134 { 00135 ERR( "No free block found\n" ); 00136 return NULL; 00137 } 00138 00139 if( flags & HEAP_ZERO_MEMORY ) 00140 { 00141 ZeroMemory( lpvArea, size ); 00142 } 00143 00144 return lpvArea; 00145 } 00146 00147 LPSTR DPLAYX_strdupA( DWORD flags, LPCSTR str ); 00148 LPSTR DPLAYX_strdupA( DWORD flags, LPCSTR str ) 00149 { 00150 LPSTR p = DPLAYX_PrivHeapAlloc( flags, strlen(str) + 1 ); 00151 if(p) { 00152 strcpy( p, str ); 00153 } 00154 return p; 00155 } 00156 00157 LPWSTR DPLAYX_strdupW( DWORD flags, LPCWSTR str ); 00158 LPWSTR DPLAYX_strdupW( DWORD flags, LPCWSTR str ) 00159 { 00160 INT len = strlenW(str) + 1; 00161 LPWSTR p = DPLAYX_PrivHeapAlloc( flags, len * sizeof(WCHAR) ); 00162 if(p) { 00163 strcpyW( p, str ); 00164 } 00165 return p; 00166 } 00167 00168 00169 enum { numSupportedLobbies = 32, numSupportedSessions = 32 }; 00170 typedef struct tagDPLAYX_LOBBYDATA 00171 { 00172 /* Points to lpConn + block of contiguous extra memory for dynamic parts 00173 * of the struct directly following 00174 */ 00175 LPDPLCONNECTION lpConn; 00176 00177 /* Information for dplobby interfaces */ 00178 DWORD dwAppID; 00179 DWORD dwAppLaunchedFromID; 00180 00181 /* Should this lobby app send messages to creator at important life 00182 * stages 00183 */ 00184 HANDLE hInformOnAppStart; 00185 HANDLE hInformOnAppDeath; 00186 HANDLE hInformOnSettingRead; 00187 00188 /* Sundries */ 00189 BOOL bWaitForConnectionSettings; 00190 DWORD dwLobbyMsgThreadId; 00191 00192 00193 } DPLAYX_LOBBYDATA, *LPDPLAYX_LOBBYDATA; 00194 00195 static DPLAYX_LOBBYDATA* lobbyData = NULL; 00196 /* static DPLAYX_LOBBYDATA lobbyData[ numSupportedLobbies ]; */ 00197 00198 static DPSESSIONDESC2* sessionData = NULL; 00199 /* static DPSESSIONDESC2* sessionData[ numSupportedSessions ]; */ 00200 00201 /* Function prototypes */ 00202 DWORD DPLAYX_SizeOfLobbyDataA( LPDPLCONNECTION lpDplData ); 00203 DWORD DPLAYX_SizeOfLobbyDataW( LPDPLCONNECTION lpDplData ); 00204 void DPLAYX_CopyConnStructA( LPDPLCONNECTION dest, LPDPLCONNECTION src ); 00205 void DPLAYX_CopyConnStructW( LPDPLCONNECTION dest, LPDPLCONNECTION src ); 00206 BOOL DPLAYX_IsAppIdLobbied( DWORD dwAppId, LPDPLAYX_LOBBYDATA* dplData ); 00207 void DPLAYX_InitializeLobbyDataEntry( LPDPLAYX_LOBBYDATA lpData ); 00208 BOOL DPLAYX_CopyIntoSessionDesc2A( LPDPSESSIONDESC2 lpSessionDest, 00209 LPCDPSESSIONDESC2 lpSessionSrc ); 00210 00211 00212 00213 /*************************************************************************** 00214 * Called to initialize the global data. This will only be used on the 00215 * loading of the dll 00216 ***************************************************************************/ 00217 BOOL DPLAYX_ConstructData(void) 00218 { 00219 SECURITY_ATTRIBUTES s_attrib; 00220 BOOL bInitializeSharedMemory = FALSE; 00221 LPVOID lpDesiredMemoryMapStart = (LPVOID)0x50000000; 00222 HANDLE hInformOnStart; 00223 00224 TRACE( "DPLAYX dll loaded - construct called\n" ); 00225 00226 /* Create a semaphore to block access to DPLAYX global data structs */ 00227 00228 s_attrib.bInheritHandle = TRUE; 00229 s_attrib.lpSecurityDescriptor = NULL; 00230 s_attrib.nLength = sizeof(s_attrib); 00231 00232 hDplayxSema = CreateSemaphoreA( &s_attrib, 1, 1, lpszDplayxSemaName ); 00233 00234 /* First instance creates the semaphore. Others just use it */ 00235 if( GetLastError() == ERROR_SUCCESS ) 00236 { 00237 TRACE( "Semaphore %p created\n", hDplayxSema ); 00238 00239 /* The semaphore creator will also build the shared memory */ 00240 bInitializeSharedMemory = TRUE; 00241 } 00242 else if ( GetLastError() == ERROR_ALREADY_EXISTS ) 00243 { 00244 TRACE( "Found semaphore handle %p\n", hDplayxSema ); 00245 } 00246 else 00247 { 00248 ERR( ": semaphore error %ld\n", GetLastError() ); 00249 return FALSE; 00250 } 00251 00252 SetLastError( ERROR_SUCCESS ); 00253 00254 DPLAYX_AquireSemaphore(); 00255 00256 hDplayxSharedMem = CreateFileMappingA( INVALID_HANDLE_VALUE, 00257 &s_attrib, 00258 PAGE_READWRITE | SEC_COMMIT, 00259 0, 00260 dwTotalSharedSize, 00261 lpszDplayxFileMapping ); 00262 00263 if( GetLastError() == ERROR_SUCCESS ) 00264 { 00265 TRACE( "File mapped %p created\n", hDplayxSharedMem ); 00266 } 00267 else if ( GetLastError() == ERROR_ALREADY_EXISTS ) 00268 { 00269 TRACE( "Found FileMapping handle %p\n", hDplayxSharedMem ); 00270 } 00271 else 00272 { 00273 ERR( ": unable to create shared memory (%ld)\n", GetLastError() ); 00274 return FALSE; 00275 } 00276 00277 lpSharedStaticData = MapViewOfFileEx( hDplayxSharedMem, 00278 FILE_MAP_WRITE, 00279 0, 0, 0, lpDesiredMemoryMapStart ); 00280 00281 if( lpSharedStaticData == NULL ) 00282 { 00283 ERR( ": unable to map static data into process memory space (%ld)\n", 00284 GetLastError() ); 00285 return FALSE; 00286 } 00287 else 00288 { 00289 if( lpDesiredMemoryMapStart == lpSharedStaticData ) 00290 { 00291 TRACE( "File mapped to %p\n", lpSharedStaticData ); 00292 } 00293 else 00294 { 00295 /* Presently the shared data structures use pointers. If the 00296 * files are no mapped into the same area, the pointers will no 00297 * longer make any sense :( 00298 * FIXME: In the future make the shared data structures have some 00299 * sort of fixup to make them independent between data spaces. 00300 * This will also require a rework of the session data stuff. 00301 */ 00302 ERR( "File mapped to %p (not %p). Expect failure\n", 00303 lpSharedStaticData, lpDesiredMemoryMapStart ); 00304 } 00305 } 00306 00307 /* Dynamic area starts just after the static area */ 00308 lpMemArea = (LPVOID)((BYTE*)lpSharedStaticData + dwStaticSharedSize); 00309 00310 /* FIXME: Crude hack */ 00311 lobbyData = (DPLAYX_LOBBYDATA*)lpSharedStaticData; 00312 sessionData = (DPSESSIONDESC2*)((BYTE*)lpSharedStaticData + (dwStaticSharedSize/2)); 00313 00314 /* Initialize shared data segments. */ 00315 if( bInitializeSharedMemory ) 00316 { 00317 UINT i; 00318 00319 TRACE( "Initializing shared memory\n" ); 00320 00321 /* Set all lobbies to be "empty" */ 00322 for( i=0; i < numSupportedLobbies; i++ ) 00323 { 00324 DPLAYX_InitializeLobbyDataEntry( &lobbyData[ i ] ); 00325 } 00326 00327 /* Set all sessions to be "empty" */ 00328 for( i=0; i < numSupportedSessions; i++ ) 00329 { 00330 sessionData[i].dwSize = 0; 00331 } 00332 00333 /* Zero out the dynmaic area */ 00334 ZeroMemory( lpMemArea, dwDynamicSharedSize ); 00335 00336 /* Just for fun sync the whole data area */ 00337 FlushViewOfFile( lpSharedStaticData, dwTotalSharedSize ); 00338 } 00339 00340 DPLAYX_ReleaseSemaphore(); 00341 00342 /* Everything was created correctly. Signal the lobby client that 00343 * we started up correctly 00344 */ 00345 if( DPLAYX_GetThisLobbyHandles( &hInformOnStart, NULL, NULL, FALSE ) && 00346 hInformOnStart 00347 ) 00348 { 00349 BOOL bSuccess; 00350 bSuccess = SetEvent( hInformOnStart ); 00351 TRACE( "Signalling lobby app start event %p %s\n", 00352 hInformOnStart, bSuccess ? "succeed" : "failed" ); 00353 00354 /* Close out handle */ 00355 DPLAYX_GetThisLobbyHandles( &hInformOnStart, NULL, NULL, TRUE ); 00356 } 00357 00358 return TRUE; 00359 } 00360 00361 /*************************************************************************** 00362 * Called to destroy all global data. This will only be used on the 00363 * unloading of the dll 00364 ***************************************************************************/ 00365 BOOL DPLAYX_DestructData(void) 00366 { 00367 HANDLE hInformOnDeath; 00368 00369 TRACE( "DPLAYX dll unloaded - destruct called\n" ); 00370 00371 /* If required, inform that this app is dying */ 00372 if( DPLAYX_GetThisLobbyHandles( NULL, &hInformOnDeath, NULL, FALSE ) && 00373 hInformOnDeath 00374 ) 00375 { 00376 BOOL bSuccess; 00377 bSuccess = SetEvent( hInformOnDeath ); 00378 TRACE( "Signalling lobby app death event %p %s\n", 00379 hInformOnDeath, bSuccess ? "succeed" : "failed" ); 00380 00381 /* Close out handle */ 00382 DPLAYX_GetThisLobbyHandles( NULL, &hInformOnDeath, NULL, TRUE ); 00383 } 00384 00385 /* DO CLEAN UP (LAST) */ 00386 00387 /* Delete the semaphore */ 00388 CloseHandle( hDplayxSema ); 00389 00390 /* Delete shared memory file mapping */ 00391 UnmapViewOfFile( lpSharedStaticData ); 00392 CloseHandle( hDplayxSharedMem ); 00393 00394 return FALSE; 00395 } 00396 00397 00398 void DPLAYX_InitializeLobbyDataEntry( LPDPLAYX_LOBBYDATA lpData ) 00399 { 00400 ZeroMemory( lpData, sizeof( *lpData ) ); 00401 } 00402 00403 /* NOTE: This must be called with the semaphore aquired. 00404 * TRUE/FALSE with a pointer to it's data returned. Pointer data is 00405 * is only valid if TRUE is returned. 00406 */ 00407 BOOL DPLAYX_IsAppIdLobbied( DWORD dwAppID, LPDPLAYX_LOBBYDATA* lplpDplData ) 00408 { 00409 UINT i; 00410 00411 *lplpDplData = NULL; 00412 00413 if( dwAppID == 0 ) 00414 { 00415 dwAppID = GetCurrentProcessId(); 00416 TRACE( "Translated dwAppID == 0 into 0x%08lx\n", dwAppID ); 00417 } 00418 00419 for( i=0; i < numSupportedLobbies; i++ ) 00420 { 00421 if( lobbyData[ i ].dwAppID == dwAppID ) 00422 { 00423 /* This process is lobbied */ 00424 TRACE( "Found 0x%08lx @ %u\n", dwAppID, i ); 00425 *lplpDplData = &lobbyData[ i ]; 00426 return TRUE; 00427 } 00428 } 00429 00430 return FALSE; 00431 } 00432 00433 /* Reserve a spot for the new appliction. TRUE means success and FALSE failure. */ 00434 BOOL DPLAYX_CreateLobbyApplication( DWORD dwAppID ) 00435 { 00436 UINT i; 00437 00438 /* 0 is the marker for unused application data slots */ 00439 if( dwAppID == 0 ) 00440 { 00441 return FALSE; 00442 } 00443 00444 DPLAYX_AquireSemaphore(); 00445 00446 /* Find an empty space in the list and insert the data */ 00447 for( i=0; i < numSupportedLobbies; i++ ) 00448 { 00449 if( lobbyData[ i ].dwAppID == 0 ) 00450 { 00451 /* This process is now lobbied */ 00452 TRACE( "Setting lobbyData[%u] for (0x%08lx,0x%08lx)\n", 00453 i, dwAppID, GetCurrentProcessId() ); 00454 00455 lobbyData[ i ].dwAppID = dwAppID; 00456 lobbyData[ i ].dwAppLaunchedFromID = GetCurrentProcessId(); 00457 00458 /* FIXME: Where is the best place for this? In interface or here? */ 00459 lobbyData[ i ].hInformOnAppStart = 0; 00460 lobbyData[ i ].hInformOnAppDeath = 0; 00461 lobbyData[ i ].hInformOnSettingRead = 0; 00462 00463 DPLAYX_ReleaseSemaphore(); 00464 return TRUE; 00465 } 00466 } 00467 00468 ERR( "No empty lobbies\n" ); 00469 00470 DPLAYX_ReleaseSemaphore(); 00471 return FALSE; 00472 } 00473 00474 /* I'm not sure when I'm going to need this, but here it is */ 00475 BOOL DPLAYX_DestroyLobbyApplication( DWORD dwAppID ) 00476 { 00477 UINT i; 00478 00479 DPLAYX_AquireSemaphore(); 00480 00481 /* Find an empty space in the list and insert the data */ 00482 for( i=0; i < numSupportedLobbies; i++ ) 00483 { 00484 if( lobbyData[ i ].dwAppID == dwAppID ) 00485 { 00486 /* FIXME: Should free up anything unused. Tisk tisk :0 */ 00487 /* Mark this entry unused */ 00488 TRACE( "Marking lobbyData[%u] unused\n", i ); 00489 DPLAYX_InitializeLobbyDataEntry( &lobbyData[ i ] ); 00490 00491 DPLAYX_ReleaseSemaphore(); 00492 return TRUE; 00493 } 00494 } 00495 00496 DPLAYX_ReleaseSemaphore(); 00497 ERR( "Unable to find global entry for application\n" ); 00498 return FALSE; 00499 } 00500 00501 BOOL DPLAYX_SetLobbyHandles( DWORD dwAppID, 00502 HANDLE hStart, HANDLE hDeath, HANDLE hConnRead ) 00503 { 00504 LPDPLAYX_LOBBYDATA lpLData; 00505 00506 /* Need to explictly give lobby application. Can't set for yourself */ 00507 if( dwAppID == 0 ) 00508 { 00509 return FALSE; 00510 } 00511 00512 DPLAYX_AquireSemaphore(); 00513 00514 if( !DPLAYX_IsAppIdLobbied( dwAppID, &lpLData ) ) 00515 { 00516 DPLAYX_ReleaseSemaphore(); 00517 return FALSE; 00518 } 00519 00520 lpLData->hInformOnAppStart = hStart; 00521 lpLData->hInformOnAppDeath = hDeath; 00522 lpLData->hInformOnSettingRead = hConnRead; 00523 00524 DPLAYX_ReleaseSemaphore(); 00525 00526 return TRUE; 00527 } 00528 00529 BOOL DPLAYX_GetThisLobbyHandles( LPHANDLE lphStart, 00530 LPHANDLE lphDeath, 00531 LPHANDLE lphConnRead, 00532 BOOL bClearSetHandles ) 00533 { 00534 LPDPLAYX_LOBBYDATA lpLData; 00535 00536 DPLAYX_AquireSemaphore(); 00537 00538 if( !DPLAYX_IsAppIdLobbied( 0, &lpLData ) ) 00539 { 00540 DPLAYX_ReleaseSemaphore(); 00541 return FALSE; 00542 } 00543 00544 if( lphStart != NULL ) 00545 { 00546 if( lpLData->hInformOnAppStart == 0 ) 00547 { 00548 DPLAYX_ReleaseSemaphore(); 00549 return FALSE; 00550 } 00551 00552 *lphStart = lpLData->hInformOnAppStart; 00553 00554 if( bClearSetHandles ) 00555 { 00556 CloseHandle( lpLData->hInformOnAppStart ); 00557 lpLData->hInformOnAppStart = 0; 00558 } 00559 } 00560 00561 if( lphDeath != NULL ) 00562 { 00563 if( lpLData->hInformOnAppDeath == 0 ) 00564 { 00565 DPLAYX_ReleaseSemaphore(); 00566 return FALSE; 00567 } 00568 00569 *lphDeath = lpLData->hInformOnAppDeath; 00570 00571 if( bClearSetHandles ) 00572 { 00573 CloseHandle( lpLData->hInformOnAppDeath ); 00574 lpLData->hInformOnAppDeath = 0; 00575 } 00576 } 00577 00578 if( lphConnRead != NULL ) 00579 { 00580 if( lpLData->hInformOnSettingRead == 0 ) 00581 { 00582 DPLAYX_ReleaseSemaphore(); 00583 return FALSE; 00584 } 00585 00586 *lphConnRead = lpLData->hInformOnSettingRead; 00587 00588 if( bClearSetHandles ) 00589 { 00590 CloseHandle( lpLData->hInformOnSettingRead ); 00591 lpLData->hInformOnSettingRead = 0; 00592 } 00593 } 00594 00595 DPLAYX_ReleaseSemaphore(); 00596 00597 return TRUE; 00598 } 00599 00600 00601 HRESULT DPLAYX_GetConnectionSettingsA 00602 ( DWORD dwAppID, 00603 LPVOID lpData, 00604 LPDWORD lpdwDataSize ) 00605 { 00606 LPDPLAYX_LOBBYDATA lpDplData; 00607 DWORD dwRequiredDataSize = 0; 00608 HANDLE hInformOnSettingRead; 00609 00610 DPLAYX_AquireSemaphore(); 00611 00612 if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) ) 00613 { 00614 DPLAYX_ReleaseSemaphore(); 00615 00616 TRACE( "Application 0x%08lx is not lobbied\n", dwAppID ); 00617 return DPERR_NOTLOBBIED; 00618 } 00619 00620 dwRequiredDataSize = DPLAYX_SizeOfLobbyDataA( lpDplData->lpConn ); 00621 00622 /* Do they want to know the required buffer size or is the provided buffer 00623 * big enough? 00624 */ 00625 if ( ( lpData == NULL ) || 00626 ( *lpdwDataSize < dwRequiredDataSize ) 00627 ) 00628 { 00629 DPLAYX_ReleaseSemaphore(); 00630 00631 *lpdwDataSize = DPLAYX_SizeOfLobbyDataA( lpDplData->lpConn ); 00632 00633 return DPERR_BUFFERTOOSMALL; 00634 } 00635 00636 DPLAYX_CopyConnStructA( (LPDPLCONNECTION)lpData, lpDplData->lpConn ); 00637 00638 DPLAYX_ReleaseSemaphore(); 00639 00640 /* They have gotten the information - signal the event if required */ 00641 if( DPLAYX_GetThisLobbyHandles( NULL, NULL, &hInformOnSettingRead, FALSE ) && 00642 hInformOnSettingRead 00643 ) 00644 { 00645 BOOL bSuccess; 00646 bSuccess = SetEvent( hInformOnSettingRead ); 00647 TRACE( "Signalling setting read event %p %s\n", 00648 hInformOnSettingRead, bSuccess ? "succeed" : "failed" ); 00649 00650 /* Close out handle */ 00651 DPLAYX_GetThisLobbyHandles( NULL, NULL, &hInformOnSettingRead, TRUE ); 00652 } 00653 00654 return DP_OK; 00655 } 00656 00657 /* Assumption: Enough contiguous space was allocated at dest */ 00658 void DPLAYX_CopyConnStructA( LPDPLCONNECTION dest, LPDPLCONNECTION src ) 00659 { 00660 BYTE* lpStartOfFreeSpace; 00661 00662 CopyMemory( dest, src, sizeof( DPLCONNECTION ) ); 00663 00664 lpStartOfFreeSpace = ((BYTE*)dest) + sizeof( DPLCONNECTION ); 00665 00666 /* Copy the LPDPSESSIONDESC2 structure if it exists */ 00667 if( src->lpSessionDesc ) 00668 { 00669 dest->lpSessionDesc = (LPDPSESSIONDESC2)lpStartOfFreeSpace; 00670 lpStartOfFreeSpace += sizeof( DPSESSIONDESC2 ); 00671 CopyMemory( dest->lpSessionDesc, src->lpSessionDesc, sizeof( DPSESSIONDESC2 ) ); 00672 00673 /* Session names may or may not exist */ 00674 if( src->lpSessionDesc->lpszSessionNameA ) 00675 { 00676 strcpy( (LPSTR)lpStartOfFreeSpace, src->lpSessionDesc->lpszSessionNameA ); 00677 dest->lpSessionDesc->lpszSessionNameA = (LPSTR)lpStartOfFreeSpace; 00678 lpStartOfFreeSpace += 00679 strlen( (LPSTR)dest->lpSessionDesc->lpszSessionNameA ) + 1; 00680 } 00681 00682 if( src->lpSessionDesc->lpszPasswordA ) 00683 { 00684 strcpy( (LPSTR)lpStartOfFreeSpace, src->lpSessionDesc->lpszPasswordA ); 00685 dest->lpSessionDesc->lpszPasswordA = (LPSTR)lpStartOfFreeSpace; 00686 lpStartOfFreeSpace += 00687 strlen( (LPSTR)dest->lpSessionDesc->lpszPasswordA ) + 1; 00688 } 00689 } 00690 00691 /* DPNAME structure is optional */ 00692 if( src->lpPlayerName ) 00693 { 00694 dest->lpPlayerName = (LPDPNAME)lpStartOfFreeSpace; 00695 lpStartOfFreeSpace += sizeof( DPNAME ); 00696 CopyMemory( dest->lpPlayerName, src->lpPlayerName, sizeof( DPNAME ) ); 00697 00698 if( src->lpPlayerName->lpszShortNameA ) 00699 { 00700 strcpy( (LPSTR)lpStartOfFreeSpace, src->lpPlayerName->lpszShortNameA ); 00701 dest->lpPlayerName->lpszShortNameA = (LPSTR)lpStartOfFreeSpace; 00702 lpStartOfFreeSpace += 00703 strlen( (LPSTR)dest->lpPlayerName->lpszShortNameA ) + 1; 00704 } 00705 00706 if( src->lpPlayerName->lpszLongNameA ) 00707 { 00708 strcpy( (LPSTR)lpStartOfFreeSpace, src->lpPlayerName->lpszLongNameA ); 00709 dest->lpPlayerName->lpszLongNameA = (LPSTR)lpStartOfFreeSpace; 00710 lpStartOfFreeSpace += 00711 strlen( (LPSTR)dest->lpPlayerName->lpszLongName ) + 1 ; 00712 } 00713 00714 } 00715 00716 /* Copy address if it exists */ 00717 if( src->lpAddress ) 00718 { 00719 dest->lpAddress = (LPVOID)lpStartOfFreeSpace; 00720 CopyMemory( lpStartOfFreeSpace, src->lpAddress, src->dwAddressSize ); 00721 /* No need to advance lpStartOfFreeSpace as there is no more "dynamic" data */ 00722 } 00723 } 00724 00725 HRESULT DPLAYX_GetConnectionSettingsW 00726 ( DWORD dwAppID, 00727 LPVOID lpData, 00728 LPDWORD lpdwDataSize ) 00729 { 00730 LPDPLAYX_LOBBYDATA lpDplData; 00731 DWORD dwRequiredDataSize = 0; 00732 HANDLE hInformOnSettingRead; 00733 00734 DPLAYX_AquireSemaphore(); 00735 00736 if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) ) 00737 { 00738 DPLAYX_ReleaseSemaphore(); 00739 return DPERR_NOTLOBBIED; 00740 } 00741 00742 dwRequiredDataSize = DPLAYX_SizeOfLobbyDataW( lpDplData->lpConn ); 00743 00744 /* Do they want to know the required buffer size or is the provided buffer 00745 * big enough? 00746 */ 00747 if ( ( lpData == NULL ) || 00748 ( *lpdwDataSize < dwRequiredDataSize ) 00749 ) 00750 { 00751 DPLAYX_ReleaseSemaphore(); 00752 00753 *lpdwDataSize = DPLAYX_SizeOfLobbyDataW( lpDplData->lpConn ); 00754 00755 return DPERR_BUFFERTOOSMALL; 00756 } 00757 00758 DPLAYX_CopyConnStructW( (LPDPLCONNECTION)lpData, lpDplData->lpConn ); 00759 00760 DPLAYX_ReleaseSemaphore(); 00761 00762 /* They have gotten the information - signal the event if required */ 00763 if( DPLAYX_GetThisLobbyHandles( NULL, NULL, &hInformOnSettingRead, FALSE ) && 00764 hInformOnSettingRead 00765 ) 00766 { 00767 BOOL bSuccess; 00768 bSuccess = SetEvent( hInformOnSettingRead ); 00769 TRACE( "Signalling setting read event %p %s\n", 00770 hInformOnSettingRead, bSuccess ? "succeed" : "failed" ); 00771 00772 /* Close out handle */ 00773 DPLAYX_GetThisLobbyHandles( NULL, NULL, &hInformOnSettingRead, TRUE ); 00774 } 00775 00776 return DP_OK; 00777 } 00778 00779 /* Assumption: Enough contiguous space was allocated at dest */ 00780 void DPLAYX_CopyConnStructW( LPDPLCONNECTION dest, LPDPLCONNECTION src ) 00781 { 00782 BYTE* lpStartOfFreeSpace; 00783 00784 CopyMemory( dest, src, sizeof( DPLCONNECTION ) ); 00785 00786 lpStartOfFreeSpace = ( (BYTE*)dest) + sizeof( DPLCONNECTION ); 00787 00788 /* Copy the LPDPSESSIONDESC2 structure if it exists */ 00789 if( src->lpSessionDesc ) 00790 { 00791 dest->lpSessionDesc = (LPDPSESSIONDESC2)lpStartOfFreeSpace; 00792 lpStartOfFreeSpace += sizeof( DPSESSIONDESC2 ); 00793 CopyMemory( dest->lpSessionDesc, src->lpSessionDesc, sizeof( DPSESSIONDESC2 ) ); 00794 00795 /* Session names may or may not exist */ 00796 if( src->lpSessionDesc->lpszSessionName ) 00797 { 00798 strcpyW( (LPWSTR)lpStartOfFreeSpace, dest->lpSessionDesc->lpszSessionName ); 00799 src->lpSessionDesc->lpszSessionName = (LPWSTR)lpStartOfFreeSpace; 00800 lpStartOfFreeSpace += sizeof(WCHAR) * 00801 ( strlenW( (LPWSTR)dest->lpSessionDesc->lpszSessionName ) + 1 ); 00802 } 00803 00804 if( src->lpSessionDesc->lpszPassword ) 00805 { 00806 strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpSessionDesc->lpszPassword ); 00807 dest->lpSessionDesc->lpszPassword = (LPWSTR)lpStartOfFreeSpace; 00808 lpStartOfFreeSpace += sizeof(WCHAR) * 00809 ( strlenW( (LPWSTR)dest->lpSessionDesc->lpszPassword ) + 1 ); 00810 } 00811 } 00812 00813 /* DPNAME structure is optional */ 00814 if( src->lpPlayerName ) 00815 { 00816 dest->lpPlayerName = (LPDPNAME)lpStartOfFreeSpace; 00817 lpStartOfFreeSpace += sizeof( DPNAME ); 00818 CopyMemory( dest->lpPlayerName, src->lpPlayerName, sizeof( DPNAME ) ); 00819 00820 if( src->lpPlayerName->lpszShortName ) 00821 { 00822 strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpPlayerName->lpszShortName ); 00823 dest->lpPlayerName->lpszShortName = (LPWSTR)lpStartOfFreeSpace; 00824 lpStartOfFreeSpace += sizeof(WCHAR) * 00825 ( strlenW( (LPWSTR)dest->lpPlayerName->lpszShortName ) + 1 ); 00826 } 00827 00828 if( src->lpPlayerName->lpszLongName ) 00829 { 00830 strcpyW( (LPWSTR)lpStartOfFreeSpace, src->lpPlayerName->lpszLongName ); 00831 dest->lpPlayerName->lpszLongName = (LPWSTR)lpStartOfFreeSpace; 00832 lpStartOfFreeSpace += sizeof(WCHAR) * 00833 ( strlenW( (LPWSTR)dest->lpPlayerName->lpszLongName ) + 1 ); 00834 } 00835 00836 } 00837 00838 /* Copy address if it exists */ 00839 if( src->lpAddress ) 00840 { 00841 dest->lpAddress = (LPVOID)lpStartOfFreeSpace; 00842 CopyMemory( lpStartOfFreeSpace, src->lpAddress, src->dwAddressSize ); 00843 /* No need to advance lpStartOfFreeSpace as there is no more "dynamic" data */ 00844 } 00845 00846 } 00847 00848 /* Store the structure into the shared data structre. Ensure that allocs for 00849 * variable length strings come from the shared data structure. 00850 * FIXME: We need to free information as well 00851 */ 00852 HRESULT DPLAYX_SetConnectionSettingsA 00853 ( DWORD dwFlags, 00854 DWORD dwAppID, 00855 LPDPLCONNECTION lpConn ) 00856 { 00857 LPDPLAYX_LOBBYDATA lpDplData; 00858 00859 /* Parameter check */ 00860 if( dwFlags || !lpConn ) 00861 { 00862 ERR("invalid parameters.\n"); 00863 return DPERR_INVALIDPARAMS; 00864 } 00865 00866 /* Store information */ 00867 if( lpConn->dwSize != sizeof(DPLCONNECTION) ) 00868 { 00869 ERR(": old/new DPLCONNECTION type? Size=%08lx vs. expected=%ul bytes\n", 00870 lpConn->dwSize, sizeof( DPLCONNECTION ) ); 00871 00872 return DPERR_INVALIDPARAMS; 00873 } 00874 00875 DPLAYX_AquireSemaphore(); 00876 00877 if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) ) 00878 { 00879 DPLAYX_ReleaseSemaphore(); 00880 00881 return DPERR_NOTLOBBIED; 00882 } 00883 00884 if( (!lpConn->lpSessionDesc ) || 00885 ( lpConn->lpSessionDesc->dwSize != sizeof( DPSESSIONDESC2 ) ) 00886 ) 00887 { 00888 DPLAYX_ReleaseSemaphore(); 00889 00890 ERR("DPSESSIONDESC passed in? Size=%lu vs. expected=%u bytes\n", 00891 lpConn->lpSessionDesc->dwSize, sizeof( DPSESSIONDESC2 ) ); 00892 00893 return DPERR_INVALIDPARAMS; 00894 } 00895 00896 /* Free the existing memory */ 00897 DPLAYX_PrivHeapFree( lpDplData->lpConn ); 00898 00899 lpDplData->lpConn = DPLAYX_PrivHeapAlloc( HEAP_ZERO_MEMORY, 00900 DPLAYX_SizeOfLobbyDataA( lpConn ) ); 00901 00902 DPLAYX_CopyConnStructA( lpDplData->lpConn, lpConn ); 00903 00904 00905 DPLAYX_ReleaseSemaphore(); 00906 00907 /* FIXME: Send a message - I think */ 00908 00909 return DP_OK; 00910 } 00911 00912 /* Store the structure into the shared data structre. Ensure that allocs for 00913 * variable length strings come from the shared data structure. 00914 * FIXME: We need to free information as well 00915 */ 00916 HRESULT DPLAYX_SetConnectionSettingsW 00917 ( DWORD dwFlags, 00918 DWORD dwAppID, 00919 LPDPLCONNECTION lpConn ) 00920 { 00921 LPDPLAYX_LOBBYDATA lpDplData; 00922 00923 /* Parameter check */ 00924 if( dwFlags || !lpConn ) 00925 { 00926 ERR("invalid parameters.\n"); 00927 return DPERR_INVALIDPARAMS; 00928 } 00929 00930 /* Store information */ 00931 if( lpConn->dwSize != sizeof(DPLCONNECTION) ) 00932 { 00933 ERR(": old/new DPLCONNECTION type? Size=%lu vs. expected=%u bytes\n", 00934 lpConn->dwSize, sizeof( DPLCONNECTION ) ); 00935 00936 return DPERR_INVALIDPARAMS; 00937 } 00938 00939 DPLAYX_AquireSemaphore(); 00940 00941 if ( ! DPLAYX_IsAppIdLobbied( dwAppID, &lpDplData ) ) 00942 { 00943 DPLAYX_ReleaseSemaphore(); 00944 00945 return DPERR_NOTLOBBIED; 00946 } 00947 00948 /* Free the existing memory */ 00949 DPLAYX_PrivHeapFree( lpDplData->lpConn ); 00950 00951 lpDplData->lpConn = DPLAYX_PrivHeapAlloc( HEAP_ZERO_MEMORY, 00952 DPLAYX_SizeOfLobbyDataW( lpConn ) ); 00953 00954 DPLAYX_CopyConnStructW( lpDplData->lpConn, lpConn ); 00955 00956 00957 DPLAYX_ReleaseSemaphore(); 00958 00959 /* FIXME: Send a message - I think */ 00960 00961 return DP_OK; 00962 } 00963 00964 DWORD DPLAYX_SizeOfLobbyDataA( LPDPLCONNECTION lpConn ) 00965 { 00966 DWORD dwTotalSize = sizeof( DPLCONNECTION ); 00967 00968 /* Just a safety check */ 00969 if( lpConn == NULL ) 00970 { 00971 ERR( "lpConn is NULL\n" ); 00972 return 0; 00973 } 00974 00975 if( lpConn->lpSessionDesc != NULL ) 00976 { 00977 dwTotalSize += sizeof( DPSESSIONDESC2 ); 00978 00979 if( lpConn->lpSessionDesc->lpszSessionNameA ) 00980 { 00981 dwTotalSize += strlen( lpConn->lpSessionDesc->lpszSessionNameA ) + 1; 00982 } 00983 00984 if( lpConn->lpSessionDesc->lpszPasswordA ) 00985 { 00986 dwTotalSize += strlen( lpConn->lpSessionDesc->lpszPasswordA ) + 1; 00987 } 00988 } 00989 00990 if( lpConn->lpPlayerName != NULL ) 00991 { 00992 dwTotalSize += sizeof( DPNAME ); 00993 00994 if( lpConn->lpPlayerName->lpszShortNameA ) 00995 { 00996 dwTotalSize += strlen( lpConn->lpPlayerName->lpszShortNameA ) + 1; 00997 } 00998 00999 if( lpConn->lpPlayerName->lpszLongNameA ) 01000 { 01001 dwTotalSize += strlen( lpConn->lpPlayerName->lpszLongNameA ) + 1; 01002 } 01003 01004 } 01005 01006 dwTotalSize += lpConn->dwAddressSize; 01007 01008 return dwTotalSize; 01009 } 01010 01011 DWORD DPLAYX_SizeOfLobbyDataW( LPDPLCONNECTION lpConn ) 01012 { 01013 DWORD dwTotalSize = sizeof( DPLCONNECTION ); 01014 01015 /* Just a safety check */ 01016 if( lpConn == NULL ) 01017 { 01018 ERR( "lpConn is NULL\n" ); 01019 return 0; 01020 } 01021 01022 if( lpConn->lpSessionDesc != NULL ) 01023 { 01024 dwTotalSize += sizeof( DPSESSIONDESC2 ); 01025 01026 if( lpConn->lpSessionDesc->lpszSessionName ) 01027 { 01028 dwTotalSize += sizeof( WCHAR ) * 01029 ( strlenW( lpConn->lpSessionDesc->lpszSessionName ) + 1 ); 01030 } 01031 01032 if( lpConn->lpSessionDesc->lpszPassword ) 01033 { 01034 dwTotalSize += sizeof( WCHAR ) * 01035 ( strlenW( lpConn->lpSessionDesc->lpszPassword ) + 1 ); 01036 } 01037 } 01038 01039 if( lpConn->lpPlayerName != NULL ) 01040 { 01041 dwTotalSize += sizeof( DPNAME ); 01042 01043 if( lpConn->lpPlayerName->lpszShortName ) 01044 { 01045 dwTotalSize += sizeof( WCHAR ) * 01046 ( strlenW( lpConn->lpPlayerName->lpszShortName ) + 1 ); 01047 } 01048 01049 if( lpConn->lpPlayerName->lpszLongName ) 01050 { 01051 dwTotalSize += sizeof( WCHAR ) * 01052 ( strlenW( lpConn->lpPlayerName->lpszLongName ) + 1 ); 01053 } 01054 01055 } 01056 01057 dwTotalSize += lpConn->dwAddressSize; 01058 01059 return dwTotalSize; 01060 } 01061 01062 01063 01064 static LPDPSESSIONDESC2 DPLAYX_CopyAndAllocateSessionDesc2A( LPCDPSESSIONDESC2 lpSessionSrc ) 01065 { 01066 LPDPSESSIONDESC2 lpSessionDest = 01067 HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof( *lpSessionSrc ) ); 01068 DPLAYX_CopyIntoSessionDesc2A( lpSessionDest, lpSessionSrc ); 01069 01070 return lpSessionDest; 01071 } 01072 01073 /* Copy an ANSI session desc structure to the given buffer */ 01074 BOOL DPLAYX_CopyIntoSessionDesc2A( LPDPSESSIONDESC2 lpSessionDest, 01075 LPCDPSESSIONDESC2 lpSessionSrc ) 01076 { 01077 CopyMemory( lpSessionDest, lpSessionSrc, sizeof( *lpSessionSrc ) ); 01078 01079 if( lpSessionSrc->lpszSessionNameA ) 01080 { 01081 if ((lpSessionDest->lpszSessionNameA = HeapAlloc( GetProcessHeap(), 0, 01082 strlen(lpSessionSrc->lpszSessionNameA)+1 ))) 01083 strcpy( lpSessionDest->lpszSessionNameA, lpSessionSrc->lpszSessionNameA ); 01084 } 01085 if( lpSessionSrc->lpszPasswordA ) 01086 { 01087 if ((lpSessionDest->lpszPasswordA = HeapAlloc( GetProcessHeap(), 0, 01088 strlen(lpSessionSrc->lpszPasswordA)+1 ))) 01089 strcpy( lpSessionDest->lpszPasswordA, lpSessionSrc->lpszPasswordA ); 01090 } 01091 01092 return TRUE; 01093 } 01094 01095 /* Start the index at 0. index will be updated to equal that which should 01096 be passed back into this function for the next element */ 01097 LPDPSESSIONDESC2 DPLAYX_CopyAndAllocateLocalSession( UINT* index ) 01098 { 01099 for( ; (*index) < numSupportedSessions; (*index)++ ) 01100 { 01101 if( sessionData[(*index)].dwSize != 0 ) 01102 { 01103 return DPLAYX_CopyAndAllocateSessionDesc2A( &sessionData[(*index)++] ); 01104 } 01105 } 01106 01107 /* No more sessions */ 01108 return NULL; 01109 } 01110 01111 /* Start the index at 0. index will be updated to equal that which should 01112 be passed back into this function for the next element */ 01113 BOOL DPLAYX_CopyLocalSession( UINT* index, LPDPSESSIONDESC2 lpsd ) 01114 { 01115 for( ; (*index) < numSupportedSessions; (*index)++ ) 01116 { 01117 if( sessionData[(*index)].dwSize != 0 ) 01118 { 01119 return DPLAYX_CopyIntoSessionDesc2A( lpsd, &sessionData[(*index)++] ); 01120 } 01121 } 01122 01123 /* No more sessions */ 01124 return FALSE; 01125 } 01126 01127 void DPLAYX_SetLocalSession( LPCDPSESSIONDESC2 lpsd ) 01128 { 01129 UINT i; 01130 01131 /* FIXME: Is this an error if it exists already? */ 01132 01133 /* Crude/wrong implementation for now. Just always add to first empty spot */ 01134 for( i=0; i < numSupportedSessions; i++ ) 01135 { 01136 /* Is this one empty? */ 01137 if( sessionData[i].dwSize == 0 ) 01138 { 01139 DPLAYX_CopyIntoSessionDesc2A( &sessionData[i], lpsd ); 01140 break; 01141 } 01142 } 01143 01144 } 01145 01146 BOOL DPLAYX_WaitForConnectionSettings( BOOL bWait ) 01147 { 01148 LPDPLAYX_LOBBYDATA lpLobbyData; 01149 01150 DPLAYX_AquireSemaphore(); 01151 01152 if( !DPLAYX_IsAppIdLobbied( 0, &lpLobbyData ) ) 01153 { 01154 DPLAYX_ReleaseSemaphore(); 01155 return FALSE; 01156 } 01157 01158 lpLobbyData->bWaitForConnectionSettings = bWait; 01159 01160 DPLAYX_ReleaseSemaphore(); 01161 01162 return TRUE; 01163 } 01164 01165 BOOL DPLAYX_AnyLobbiesWaitingForConnSettings(void) 01166 { 01167 UINT i; 01168 BOOL bFound = FALSE; 01169 01170 DPLAYX_AquireSemaphore(); 01171 01172 for( i=0; i < numSupportedLobbies; i++ ) 01173 { 01174 if( ( lobbyData[ i ].dwAppID != 0 ) && /* lobby initialized */ 01175 ( lobbyData[ i ].bWaitForConnectionSettings ) /* Waiting */ 01176 ) 01177 { 01178 bFound = TRUE; 01179 break; 01180 } 01181 } 01182 01183 DPLAYX_ReleaseSemaphore(); 01184 01185 return bFound; 01186 } 01187 01188 BOOL DPLAYX_SetLobbyMsgThreadId( DWORD dwAppId, DWORD dwThreadId ) 01189 { 01190 LPDPLAYX_LOBBYDATA lpLobbyData; 01191 01192 DPLAYX_AquireSemaphore(); 01193 01194 if( !DPLAYX_IsAppIdLobbied( dwAppId, &lpLobbyData ) ) 01195 { 01196 DPLAYX_ReleaseSemaphore(); 01197 return FALSE; 01198 } 01199 01200 lpLobbyData->dwLobbyMsgThreadId = dwThreadId; 01201 01202 DPLAYX_ReleaseSemaphore(); 01203 01204 return TRUE; 01205 } 01206 01207 /* NOTE: This is potentially not thread safe. You are not guaranteed to end up 01208 with the correct string printed in the case where the HRESULT is not 01209 known. You will just get the last hr passed in. This can change 01210 over time if this method is used a lot :) */ 01211 LPCSTR DPLAYX_HresultToString(HRESULT hr) 01212 { 01213 static char szTempStr[12]; 01214 01215 switch (hr) 01216 { 01217 case DP_OK: 01218 return "DP_OK"; 01219 case DPERR_ALREADYINITIALIZED: 01220 return "DPERR_ALREADYINITIALIZED"; 01221 case DPERR_ACCESSDENIED: 01222 return "DPERR_ACCESSDENIED"; 01223 case DPERR_ACTIVEPLAYERS: 01224 return "DPERR_ACTIVEPLAYERS"; 01225 case DPERR_BUFFERTOOSMALL: 01226 return "DPERR_BUFFERTOOSMALL"; 01227 case DPERR_CANTADDPLAYER: 01228 return "DPERR_CANTADDPLAYER"; 01229 case DPERR_CANTCREATEGROUP: 01230 return "DPERR_CANTCREATEGROUP"; 01231 case DPERR_CANTCREATEPLAYER: 01232 return "DPERR_CANTCREATEPLAYER"; 01233 case DPERR_CANTCREATESESSION: 01234 return "DPERR_CANTCREATESESSION"; 01235 case DPERR_CAPSNOTAVAILABLEYET: 01236 return "DPERR_CAPSNOTAVAILABLEYET"; 01237 case DPERR_EXCEPTION: 01238 return "DPERR_EXCEPTION"; 01239 case DPERR_GENERIC: 01240 return "DPERR_GENERIC"; 01241 case DPERR_INVALIDFLAGS: 01242 return "DPERR_INVALIDFLAGS"; 01243 case DPERR_INVALIDOBJECT: 01244 return "DPERR_INVALIDOBJECT"; 01245 case DPERR_INVALIDPARAMS: 01246 return "DPERR_INVALIDPARAMS"; 01247 case DPERR_INVALIDPLAYER: 01248 return "DPERR_INVALIDPLAYER"; 01249 case DPERR_INVALIDGROUP: 01250 return "DPERR_INVALIDGROUP"; 01251 case DPERR_NOCAPS: 01252 return "DPERR_NOCAPS"; 01253 case DPERR_NOCONNECTION: 01254 return "DPERR_NOCONNECTION"; 01255 case DPERR_OUTOFMEMORY: 01256 return "DPERR_OUTOFMEMORY"; 01257 case DPERR_NOMESSAGES: 01258 return "DPERR_NOMESSAGES"; 01259 case DPERR_NONAMESERVERFOUND: 01260 return "DPERR_NONAMESERVERFOUND"; 01261 case DPERR_NOPLAYERS: 01262 return "DPERR_NOPLAYERS"; 01263 case DPERR_NOSESSIONS: 01264 return "DPERR_NOSESSIONS"; 01265 case DPERR_PENDING: 01266 return "DPERR_PENDING"; 01267 case DPERR_SENDTOOBIG: 01268 return "DPERR_SENDTOOBIG"; 01269 case DPERR_TIMEOUT: 01270 return "DPERR_TIMEOUT"; 01271 case DPERR_UNAVAILABLE: 01272 return "DPERR_UNAVAILABLE"; 01273 case DPERR_UNSUPPORTED: 01274 return "DPERR_UNSUPPORTED"; 01275 case DPERR_BUSY: 01276 return "DPERR_BUSY"; 01277 case DPERR_USERCANCEL: 01278 return "DPERR_USERCANCEL"; 01279 case DPERR_NOINTERFACE: 01280 return "DPERR_NOINTERFACE"; 01281 case DPERR_CANNOTCREATESERVER: 01282 return "DPERR_CANNOTCREATESERVER"; 01283 case DPERR_PLAYERLOST: 01284 return "DPERR_PLAYERLOST"; 01285 case DPERR_SESSIONLOST: 01286 return "DPERR_SESSIONLOST"; 01287 case DPERR_UNINITIALIZED: 01288 return "DPERR_UNINITIALIZED"; 01289 case DPERR_NONEWPLAYERS: 01290 return "DPERR_NONEWPLAYERS"; 01291 case DPERR_INVALIDPASSWORD: 01292 return "DPERR_INVALIDPASSWORD"; 01293 case DPERR_CONNECTING: 01294 return "DPERR_CONNECTING"; 01295 case DPERR_CONNECTIONLOST: 01296 return "DPERR_CONNECTIONLOST"; 01297 case DPERR_UNKNOWNMESSAGE: 01298 return "DPERR_UNKNOWNMESSAGE"; 01299 case DPERR_CANCELFAILED: 01300 return "DPERR_CANCELFAILED"; 01301 case DPERR_INVALIDPRIORITY: 01302 return "DPERR_INVALIDPRIORITY"; 01303 case DPERR_NOTHANDLED: 01304 return "DPERR_NOTHANDLED"; 01305 case DPERR_CANCELLED: 01306 return "DPERR_CANCELLED"; 01307 case DPERR_ABORTED: 01308 return "DPERR_ABORTED"; 01309 case DPERR_BUFFERTOOLARGE: 01310 return "DPERR_BUFFERTOOLARGE"; 01311 case DPERR_CANTCREATEPROCESS: 01312 return "DPERR_CANTCREATEPROCESS"; 01313 case DPERR_APPNOTSTARTED: 01314 return "DPERR_APPNOTSTARTED"; 01315 case DPERR_INVALIDINTERFACE: 01316 return "DPERR_INVALIDINTERFACE"; 01317 case DPERR_NOSERVICEPROVIDER: 01318 return "DPERR_NOSERVICEPROVIDER"; 01319 case DPERR_UNKNOWNAPPLICATION: 01320 return "DPERR_UNKNOWNAPPLICATION"; 01321 case DPERR_NOTLOBBIED: 01322 return "DPERR_NOTLOBBIED"; 01323 case DPERR_SERVICEPROVIDERLOADED: 01324 return "DPERR_SERVICEPROVIDERLOADED"; 01325 case DPERR_ALREADYREGISTERED: 01326 return "DPERR_ALREADYREGISTERED"; 01327 case DPERR_NOTREGISTERED: 01328 return "DPERR_NOTREGISTERED"; 01329 case DPERR_AUTHENTICATIONFAILED: 01330 return "DPERR_AUTHENTICATIONFAILED"; 01331 case DPERR_CANTLOADSSPI: 01332 return "DPERR_CANTLOADSSPI"; 01333 case DPERR_ENCRYPTIONFAILED: 01334 return "DPERR_ENCRYPTIONFAILED"; 01335 case DPERR_SIGNFAILED: 01336 return "DPERR_SIGNFAILED"; 01337 case DPERR_CANTLOADSECURITYPACKAGE: 01338 return "DPERR_CANTLOADSECURITYPACKAGE"; 01339 case DPERR_ENCRYPTIONNOTSUPPORTED: 01340 return "DPERR_ENCRYPTIONNOTSUPPORTED"; 01341 case DPERR_CANTLOADCAPI: 01342 return "DPERR_CANTLOADCAPI"; 01343 case DPERR_NOTLOGGEDIN: 01344 return "DPERR_NOTLOGGEDIN"; 01345 case DPERR_LOGONDENIED: 01346 return "DPERR_LOGONDENIED"; 01347 default: 01348 /* For errors not in the list, return HRESULT as a string 01349 This part is not thread safe */ 01350 WARN( "Unknown error 0x%08lx\n", hr ); 01351 wsprintfA( szTempStr, "0x%08lx", hr ); 01352 return szTempStr; 01353 } 01354 } Generated on Sat May 26 2012 04:20:10 for ReactOS by
1.7.6.1
|