/************************************************************************* * Microsoft Windows NT * * * * Copyright(c) Microsoft Corp., 1994 * * * * Revision History: * * * * Jan. 23,94 Koti Created * * * * Description: * * * * This file contains functions for starting and stopping LPD service * * * *************************************************************************/ #include "lpd.h" // Globals: SERVICE_STATUS ssSvcStatusGLB; SERVICE_STATUS_HANDLE hSvcHandleGLB = 0; HANDLE hEventShutdownGLB; HANDLE hEventLastThreadGLB; HANDLE hLogHandleGLB; // head of the linked list of SOCKCONN structures (one link per connection) SOCKCONN scConnHeadGLB; // to guard access to linked list of pscConn CRITICAL_SECTION csConnSemGLB; // max users that can be connected concurrently DWORD dwMaxUsersGLB; DWORD MaxQueueLength; BOOL fJobRemovalEnabledGLB=TRUE; BOOL fAllowPrintResumeGLB=TRUE; BOOL fAlwaysRawGLB=FALSE; DWORD dwRecvTimeout; BOOL fShuttingDownGLB=FALSE; CHAR szNTVersion[8]; CHAR *g_ppszStrings[ LPD_CSTRINGS ]; // Info shared by all threads, protected by CRITICAL_SECTION. COMMON_LPD Common; /***************************************************************************** * * * LoadStrings(): * * Load a bunch of strings defined in the .mc file. * * * * Returns: * * TRUE if everything went ok * * FALSE if a string couldn't be loaded * * * * Parameters: * * None * * * * History: * * June.27, 96 Frankbee Created * * * *****************************************************************************/ BOOL LoadStrings() { DWORD dwSuccess; HMODULE hModule; DWORD dwID; hModule = LoadLibrary( TEXT(LPD_SERVICE_NAME) ); if (hModule == NULL) { return(FALSE); } memset( g_ppszStrings, 0, LPD_CSTRINGS * sizeof( CHAR * ) ); for ( dwID = LPD_FIRST_STRING; dwID <= LPD_LAST_STRING; dwID++ ) { // &g_ppszStrings[(dwID - LPD_FIRST_STRING)][0], dwSuccess = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE, hModule, // search local process dwID, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)(g_ppszStrings + (dwID - LPD_FIRST_STRING)), 1, NULL ); if (!dwSuccess){ DEBUG_PRINT(("lpd:init.c:29, dwID=%d FormatMessage failed\n", dwID)); goto error; } } FreeLibrary( hModule ); return TRUE; error: FreeStrings(); FreeLibrary( hModule ); return FALSE; } /***************************************************************************** * * * FreeStrings(): * * Frees the strings loaded by LoadStrings() * * * * Returns: * * VOID * * * Parameters: * * None * * * * History: * * June.27, 96 Frankbee Created * * * *****************************************************************************/ VOID FreeStrings() { int i; for ( i = 0; i < LPD_CSTRINGS; i++ ) (LocalFree)( g_ppszStrings[i] ); // // clear the string table for debug builds to prevent access after // FreeStrings() // #if DBG memset( g_ppszStrings, 0, LPD_CSTRINGS * sizeof( CHAR * ) ); #endif } /***************************************************************************** * * * InitStuff(): * * This function initializes hEventShutdown and other global vars * * * * Returns: * * TRUE if everything went ok * * FALSE if something went wrong * * * * Parameters: * * None * * * * History: * * Jan.23, 94 Koti Created * * * *****************************************************************************/ BOOL InitStuff( ) { USHORT usVersion; UCHAR uchTemp; #ifdef DBG // MohsinA, 06-Mar-97. lpd isn't starting. beginlogging( MOSH_LOG_FILE ); #endif if ( !LoadStrings() ) { LPD_DEBUG( "LoadStrings() failed in InitStuf\n" ); return FALSE; } if ( !InitLogging() ) { LPD_DEBUG( "InitLogging() FAILed, continuing anyway ...\n" ); } #if DBG InitializeListHead(&DbgMemList); #endif // main thread blocks for ever on this event, before doing a shutdown hEventShutdownGLB = CreateEvent( NULL, FALSE, FALSE, NULL ); // when the main thread is ready to shutdown, if there are any active // threads servicing clients, then main thread blocks on this event // (the last thread to leave sets the event) hEventLastThreadGLB = CreateEvent( NULL, FALSE, FALSE, NULL ); if ( ( hEventShutdownGLB == (HANDLE)NULL ) || ( hEventLastThreadGLB == (HANDLE)NULL ) ) { LPD_DEBUG( "CreateEvent() failed in InitStuff\n" ); return( FALSE ); } scConnHeadGLB.pNext = NULL; // == Doubly linked list, // == isempty() iff scConnHeadGLB.pNext == &scConnHeadGLB. // == && scConnHeadGLB.pPrev == &scConnHeadGLB. // scConnHeadGLB.pNext = scConnHeadGLB.pPrev = &scConnHeadGLB; // scConnHeadGLB.cbClients = 0; // Obselete. memset( &Common, 0, sizeof(Common) ); // csConnSemGLB is the critical section object (guards access to // scConnHeadGLB, head of the psc linked list) InitializeCriticalSection( &csConnSemGLB ); // perform debug build initialization DBG_INIT(); ReadRegistryValues(); // store the version number of NT usVersion = (USHORT)GetVersion(); uchTemp = (UCHAR)usVersion; // low byte => major version number usVersion >>= 8; // high byte => minor version number sprintf( szNTVersion,"%d.%d",uchTemp,(UCHAR)usVersion ); return( TRUE ); } // end InitStuff( ) /***************************************************************************** * * * ReadRegistryValues(): * * This function initializes all variables that we read via registry. If * * there is a problem and we can't read the registry, we ignore the * * problem and initialize the variables with our defaults. * * * * Returns: * * Nothing * * * * Parameters: * * None * * * * History: * * Jan.30, 94 Koti Created * * * *****************************************************************************/ VOID ReadRegistryValues( VOID ) { HKEY hLpdKey; DWORD dwErrcode; DWORD dwType, dwValue, dwValueSize; // first set defaults dwMaxUsersGLB = LPD_MAX_USERS; MaxQueueLength = LPD_MAX_QUEUE_LENGTH; fJobRemovalEnabledGLB = TRUE; fAllowPrintResumeGLB = TRUE; fAlwaysRawGLB = FALSE; dwRecvTimeout = RECV_TIMEOUT; dwErrcode = RegOpenKeyEx( HKEY_LOCAL_MACHINE, LPD_PARMS_REGISTRY_PATH, 0, KEY_ALL_ACCESS, &hLpdKey ); if ( dwErrcode != ERROR_SUCCESS ) { return; } // Read in the dwMaxUsersGLB parm dwValueSize = sizeof( DWORD ); dwErrcode = RegQueryValueEx( hLpdKey, LPD_PARMNAME_MAXUSERS, NULL, &dwType, (LPBYTE)&dwValue, &dwValueSize ); if ( (dwErrcode == ERROR_SUCCESS) && (dwType == REG_DWORD) ) { dwMaxUsersGLB = dwValue; } // // Read in the MaxQueueLength // dwValueSize = sizeof( DWORD ); dwErrcode = RegQueryValueEx( hLpdKey, LPD_PARMNAME_MAX_QUEUE_LENGTH, NULL, &dwType, (LPBYTE)&dwValue, &dwValueSize ); if ( (dwErrcode == ERROR_SUCCESS) && (dwType == REG_DWORD) ) { MaxQueueLength = dwValue; } // // Read in the fJobRemovalEnabledGLB parm dwValueSize = sizeof( DWORD ); dwErrcode = RegQueryValueEx( hLpdKey, LPD_PARMNAME_JOBREMOVAL, NULL, &dwType, (LPBYTE)&dwValue, &dwValueSize ); if ( (dwErrcode == ERROR_SUCCESS) && (dwType == REG_DWORD) && ( dwValue == 0 ) ) { fJobRemovalEnabledGLB = FALSE; } // Read in the fAllowPrintResumeGLB parm dwValueSize = sizeof( DWORD ); dwErrcode = RegQueryValueEx( hLpdKey, LPD_PARMNAME_PRINTRESUME, NULL, &dwType, (LPBYTE)&dwValue, &dwValueSize ); if ( (dwErrcode == ERROR_SUCCESS) && (dwType == REG_DWORD) && ( dwValue == 0 ) ) { fAllowPrintResumeGLB = FALSE; } // Read in the fAlwaysRawGLB parm dwValueSize = sizeof( DWORD ); dwErrcode = RegQueryValueEx( hLpdKey, LPD_PARMNAME_ALWAYSRAW, NULL, &dwType, (LPBYTE)&dwValue, &dwValueSize ); if ( (dwErrcode == ERROR_SUCCESS) && (dwType == REG_DWORD) && ( dwValue == 1 ) ) { fAlwaysRawGLB = TRUE; } // Read in the dwRecvTimeout parm dwValueSize = sizeof( DWORD ); dwErrcode = RegQueryValueEx( hLpdKey, LPD_PARMNAME_RECV_TIMEOUT, NULL, &dwType, (LPBYTE)&dwValue, &dwValueSize ); if ( (dwErrcode == ERROR_SUCCESS) && (dwType == REG_DWORD) ) { dwRecvTimeout = dwValue; } RegCloseKey (hLpdKey); } // end ReadRegistryValues()