400 lines
13 KiB
C
400 lines
13 KiB
C
|
|
/*************************************************************************
|
|
* 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()
|
|
|