ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

dplayx_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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.