#include "serverblock.h" #include "..\ClientChannel\channel.h" #include "..\Utilities\Util.h" #include "..\DynamicLink\utilities.h" #ifndef TESTCOMPILE //#include "..\User2ResourceDLL\global.h" #include "..\DynamicLink\global.h" #else // mess // Display error void error() { LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL );// Display the string. MessageBox( NULL, lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION ); LocalFree( lpMsgBuf ); } void msg(char *lpMsgBuf) { MessageBox( NULL, lpMsgBuf, "wwGetLastError", MB_OK|MB_ICONINFORMATION ); } #endif // Buffer // Create buffer, needs optimilisation. hFileMapping is inheritable BOOL AllocBuffer( DWORD length, HANDLE *hFileMapping, char **hView, char **Offset, char *BufferName ) { SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; *hFileMapping = CreateFileMapping((HANDLE)0xFFFFFFFF,&sa,PAGE_READWRITE,0,length,BufferName); if ((*hFileMapping) == NULL) { error(); msg( "AllocBuffer: hFileMapping" ); ExitProcess(-1); } *hView = (char *) MapViewOfFile(*hFileMapping, FILE_MAP_WRITE, 0, 0, length); if ((*hView) == NULL) { error(); msg( "AllocBuffer: hView" ); CloseHandle(hFileMapping); ExitProcess(-1); } *Offset = (char *) 0; return( TRUE ); } PSERVER_INFO_BLOCK Empty_ServerInfoBlock() { PSERVER_INFO_BLOCK pServerInfoBlock; pServerInfoBlock = (PSERVER_INFO_BLOCK) rmalloc (sizeof(SERVER_INFO_BLOCK)); if( pServerInfoBlock == NULL ) { msg( "Empty_ServerInfoBlock" ); } pServerInfoBlock->n_Clients = 0; return( pServerInfoBlock ); } BOOL AddClient_to_ServerInfoBlock( PSERVER_INFO_BLOCK pSIB, DWORD *dwServerId, HANDLE *hServerReady, HANDLE *hClientReady, HANDLE *hFileMapping, DWORD *offset) { BOOL ok; int Client_n; SECURITY_ATTRIBUTES sa; if( (pSIB->n_Clients) == MAXIMUM_CLIENTS ) { msg( "AddClient_to_ServerInfoBlock: too many clients" ); ExitProcess(-1); } Client_n = pSIB->n_Clients; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; #ifdef COMPILATION_FOR_WINNT sa.bInheritHandle = TRUE; #else sa.bInheritHandle = TRUE; #endif // Synchronisation pSIB->hServerReady[Client_n] = CreateEvent( &sa, FALSE, FALSE, NULL); if( !(pSIB->hServerReady[Client_n]) ) { msg( "AddClient_to_ServerInfoBlock: error" ); ExitProcess(-1); } //pSIB->hClientKilledOrReady[Client_n + CLIENT_KILLED] = hClient; // hClient unknown pSIB->hClientKilledOrReady[(Client_n * 2) + CLIENT_READY] = CreateEvent( &sa, FALSE, FALSE, NULL); if( !(pSIB->hClientKilledOrReady[(Client_n * 2) + CLIENT_READY]) ) { msg( "AddClient_to_ServerInfoBlock: error" ); ExitProcess(-1); } // Buffer ok = AllocBuffer( MESSAGE_SIZE, &(pSIB->hFileMapping[Client_n]), &(pSIB->hView[Client_n]), &(pSIB->Offset[Client_n]), NULL); if( !ok ) { msg ( "AddClient_to_ServerInfoBlock: error" ); ExitProcess(-1); } // Client Process ID // Unknown at this point // Administration data (pSIB->n_Clients)++; // Return results *dwServerId = GetCurrentProcessId(); *hServerReady = pSIB->hServerReady[Client_n]; *hClientReady = pSIB->hClientKilledOrReady[(Client_n * 2) + CLIENT_READY]; *hFileMapping = pSIB->hFileMapping[Client_n]; *offset = (DWORD) pSIB->Offset[Client_n]; return( TRUE ); } BOOL UpdateClient_in_ServerInfoBlock( PSERVER_INFO_BLOCK pSIB, HANDLE hClient, DWORD dwClientId) { int Client_n; #ifdef COMPILATION_FOR_WINNT BOOL ok; #endif if( pSIB->n_Clients == 0 ) { msg( "UpdateClient_in_ServerInfoBlock: empty" ); ExitProcess(-1); } Client_n = (pSIB->n_Clients) - 1; // Set additional information pSIB->hClientKilledOrReady[(Client_n * 2) + CLIENT_KILLED] = hClient; pSIB->ProcessId[Client_n] = dwClientId; #ifdef COMPILATION_FOR_WINNT // Undo inheritance of events ok = SetHandleInformation(pSIB->hServerReady[Client_n], HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); if( !ok ) { error(); msg( "UpdateClient_in_ServerInfoBlock: 1" ); ExitProcess(-1); } ok = SetHandleInformation(pSIB->hClientKilledOrReady[(Client_n * 2) + CLIENT_READY], HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); if( !ok ) { error(); msg( "UpdateClient_in_ServerInfoBlock: 2" ); ExitProcess(-1); } ok = SetHandleInformation(pSIB->hFileMapping[Client_n], HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); if( !ok ) { msg( "UpdateClient_in_ServerInfoBlock: 3" ); error(); ExitProcess(-1); } #else // A Win95/98 Solution needed. The problem is that not all handles // should be inherited by child processes. Only these are needed // because otherwise unnecessary resources could be keeped // occupied. #endif return( TRUE ); } BOOL RemoveClient_from_ServerInfoBlock( PSERVER_INFO_BLOCK pSIB, int Client_i ) { int i; if( !((0 <= Client_i) && (Client_i < (pSIB->n_Clients))) ) { msg( "RemoveClient_from_ServerInfoBlock: no clients to remove" ); ExitProcess(-1); } // 0 <= Client_i < pSIB->n_Clients // Buffer UnmapViewOfFile( pSIB->hView[Client_i] ); CloseHandle( pSIB->hFileMapping[Client_i] ); // Syncrhonisation CloseHandle( pSIB->hServerReady[Client_i] ); CloseHandle( pSIB->hClientKilledOrReady[(Client_i * 2) + CLIENT_READY] ); CloseHandle( pSIB->hClientKilledOrReady[(Client_i * 2) + CLIENT_KILLED] ); // Administration // pSIB->n_Clients = Client_n; // Movement for( i = Client_i + 1; i < (pSIB->n_Clients); i++) { pSIB->hServerReady[i-1] = pSIB->hServerReady[i]; pSIB->hClientKilledOrReady[2*(i-1)+CLIENT_READY] = pSIB->hClientKilledOrReady[2*i+CLIENT_READY]; pSIB->hClientKilledOrReady[2*(i-1)+CLIENT_KILLED] = pSIB->hClientKilledOrReady[2*i+CLIENT_KILLED]; pSIB->hFileMapping[i-1] = pSIB->hFileMapping[i]; pSIB->hView[i-1] = pSIB->hView[i]; pSIB->Offset[i-1] = pSIB->Offset[i]; pSIB->ProcessId[i-1] = pSIB->ProcessId[i]; } pSIB->n_Clients = pSIB->n_Clients - 1; return( TRUE ); } BOOL AddInitialSyncs_to_ServerInfoBlock( PSERVER_INFO_BLOCK pSIB ) { //pSIB = Empty_ServerInfoBlock(); /* ** It is guaranteed by the server that the buffer is allocated and ** initialized immediately after the GLOBAL_SERVER_READY--event is ** created. */ AllocBuffer( MESSAGE_SIZE, &(pSIB->hFileMapping[0]), &(pSIB->hView[0]), &(pSIB->Offset[0]), GLOBAL_BUFFER_NAME ); // initialize buffer *((DWORD *) ((pSIB->hView[0])+GLOBAL_BUFFER_SERVER_ID)) = GetCurrentProcessId(); pSIB->hServerReady[LOCAL_SERVER_READY] = CreateEvent( NULL, FALSE, FALSE, LOCAL_SERVER_READY_NAME); //pSIB->hServerReady[LOCAL_SERVER_READY] = CreateMutex(NULL, TRUE, LOCAL_SERVER_READY_NAME); if( !(pSIB->hServerReady[LOCAL_SERVER_READY]) ) { msg( "AddInitialSyncs_to_ServerInfoBlock: error" ); ExitProcess(-1); } pSIB->hClientKilledOrReady[GLOBAL_SERVER_READY] = CreateEvent( NULL, FALSE, TRUE, GLOBAL_SERVER_READY_NAME); //pSIB->hClientKilledOrReady[GLOBAL_SERVER_READY] = CreateMutex(NULL, FALSE, GLOBAL_SERVER_READY_NAME); if( !(pSIB->hClientKilledOrReady[GLOBAL_SERVER_READY]) ) { msg( "AddInitialSyncs_to_ServerInfoBlock: error" ); ExitProcess(-1); } pSIB->hClientKilledOrReady[LOCAL_CLIENT_READY] = CreateEvent( NULL, FALSE, FALSE, LOCAL_CLIENT_READY_NAME); //pSIB->hClientKilledOrReady[LOCAL_CLIENT_READY] = CreateMutex(NULL, TRUE, LOCAL_CLIENT_READY_NAME); if( !(pSIB->hClientKilledOrReady[LOCAL_CLIENT_READY]) ) { msg( "AddInitialSyncs_to_ServerInfoBlock: error" ); ExitProcess(-1); } pSIB->n_Clients = N_OF_RESERVED_ENTRIES_INITIAL_BLOCK / 2; return( TRUE ); }