windows-nt/Source/XPSP1/NT/printscan/print/spooler/spoolss/client/init.c
2020-09-26 16:20:57 +08:00

263 lines
7.6 KiB
C

/*++
Copyright (c) 1990-1994 Microsoft Corporation
All rights reserved
Module Name:
Init.c
Abstract:
Holds initialization code for winspool.drv
Author:
Environment:
User Mode -Win32
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
#include "client.h"
CRITICAL_SECTION ClientSection;
// bLoadedBySpooler indicates if this instance of winspool.drv is loaded in the spooler
// process. This flag is used to avoid unnecessary RPC.
BOOL bLoadedBySpooler;
// The following function pointers hold the spooler's server side function pointers.
// This list includes most of the calls made inside the spooler except OpenPrinter and
// ClosePrinter. We cant extend RPC elimination to cover (Open/Close)Printer unless
// "ALL" spooler APIs use RPC elimination inside the spooler.
DWORD (*fpYReadPrinter)(HANDLE, LPBYTE, DWORD, LPDWORD, BOOL);
DWORD (*fpYSplReadPrinter)(HANDLE, LPBYTE *, DWORD, BOOL);
DWORD (*fpYWritePrinter)(HANDLE, LPBYTE, DWORD, LPDWORD, BOOL);
DWORD (*fpYSeekPrinter)(HANDLE, LARGE_INTEGER, PLARGE_INTEGER, DWORD, BOOL, BOOL);
DWORD (*fpYGetPrinterDriver2)(HANDLE, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD,
DWORD, DWORD, PDWORD, PDWORD, BOOL);
DWORD (*fpYGetPrinterDriverDirectory)(LPWSTR, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD, BOOL);
VOID (*fpYDriverUnloadComplete)(LPWSTR);
DWORD (*fpYFlushPrinter)(HANDLE,LPVOID,DWORD,LPDWORD,DWORD,BOOL);
DWORD (*fpYEndDocPrinter)(HANDLE,BOOL);
DWORD (*fpYSetPort)(LPWSTR, LPWSTR, LPPORT_CONTAINER, BOOL);
DWORD (*fpYSetJob)(HANDLE, DWORD, LPJOB_CONTAINER, DWORD, BOOL);
VOID InitializeGlobalVariables()
/*++
Function Description -- Initializes bLoadedBySpooler and function pointers.
Parameters - NONE
Return Values - NONE
--*/
{
TCHAR szSysDir[MAX_PATH];
LPTSTR pszSpoolerName = NULL, pszModuleName = NULL, pszSysDir = (LPTSTR) szSysDir;
BOOL bAllocSysDir = FALSE;
DWORD dwNeeded, dwSize;
HANDLE hLib;
// Preliminary initializations
bLoadedBySpooler = FALSE;
fpYReadPrinter = fpYWritePrinter = NULL;
fpYSplReadPrinter = NULL;
fpYSeekPrinter = NULL;
fpYGetPrinterDriver2 = NULL;
fpYGetPrinterDriverDirectory = NULL;
fpYDriverUnloadComplete = NULL;
fpYFlushPrinter = NULL;
fpYEndDocPrinter = NULL;
hSurrogateProcess = NULL;
dwSize = MAX_PATH * sizeof(TCHAR);
// Get system directory
if (!(dwNeeded = GetSystemDirectory(pszSysDir, MAX_PATH))) {
goto CleanUp;
}
if (dwNeeded > dwSize) {
if (pszSysDir = (LPTSTR) AllocSplMem(dwNeeded)) {
bAllocSysDir = TRUE;
if (!GetSystemDirectory(pszSysDir, dwNeeded / sizeof(TCHAR))) {
goto CleanUp;
}
} else {
goto CleanUp;
}
}
dwSize = (_tcslen(pszSysDir) + 1 + _tcslen(TEXT("\\spoolsv.exe"))) * sizeof(TCHAR);
if ((!(pszSpoolerName = (LPTSTR) AllocSplMem(dwSize))) ||
(!(pszModuleName = (LPTSTR) AllocSplMem(dwSize)))) {
goto CleanUp;
}
// Get spooler name
_tcscpy(pszSpoolerName, pszSysDir);
_tcscat(pszSpoolerName, TEXT("\\spoolsv.exe"));
// Get module name. GetModuleFileName truncates the string if it is bigger than
// the allocated buffer. There shouldn't be an executable spoolsv.exe* in the
// system directory, which could be mistaken for the spooler.
if (!GetModuleFileName(NULL, pszModuleName, dwSize / sizeof(TCHAR))) {
goto CleanUp;
}
if (!_tcsicmp(pszSpoolerName, pszModuleName)) {
// winspool.drv has been loaded by the spooler
bLoadedBySpooler = TRUE;
if (hLib = LoadLibrary(pszSpoolerName)) {
fpYReadPrinter = (DWORD (*)(HANDLE, LPBYTE, DWORD, LPDWORD, BOOL))
GetProcAddress(hLib, "YReadPrinter");
fpYSplReadPrinter = (DWORD (*)(HANDLE, LPBYTE *, DWORD, BOOL))
GetProcAddress(hLib, "YSplReadPrinter");
fpYWritePrinter = (DWORD (*)(HANDLE, LPBYTE, DWORD, LPDWORD, BOOL))
GetProcAddress(hLib, "YWritePrinter");
fpYSeekPrinter = (DWORD (*)(HANDLE, LARGE_INTEGER, PLARGE_INTEGER,
DWORD, BOOL, BOOL))
GetProcAddress(hLib, "YSeekPrinter");
fpYGetPrinterDriver2 = (DWORD (*)(HANDLE, LPWSTR, DWORD, LPBYTE, DWORD,
LPDWORD, DWORD, DWORD, PDWORD, PDWORD, BOOL))
GetProcAddress(hLib, "YGetPrinterDriver2");
fpYGetPrinterDriverDirectory = (DWORD (*)(LPWSTR, LPWSTR, DWORD, LPBYTE, DWORD,
LPDWORD, BOOL))
GetProcAddress(hLib, "YGetPrinterDriverDirectory");
fpYDriverUnloadComplete = (VOID (*)(LPWSTR))
GetProcAddress(hLib, "YDriverUnloadComplete");
fpYFlushPrinter = (DWORD (*)(HANDLE,LPVOID,DWORD,LPDWORD,DWORD,BOOL))
GetProcAddress(hLib,"YFlushPrinter");
fpYEndDocPrinter = (DWORD (*)(HANDLE,BOOL))
GetProcAddress(hLib,"YEndDocPrinter");
fpYSetPort = (DWORD (*)(LPWSTR,LPWSTR,LPPORT_CONTAINER,BOOL))
GetProcAddress(hLib,"YSetPort");
fpYSetJob = (DWORD (*)(HANDLE, DWORD, LPJOB_CONTAINER, DWORD, BOOL))
GetProcAddress(hLib,"YSetJob");
// We can leave spoolsv.exe loaded since it is in the spooler process
}
}
CleanUp:
if (pszSpoolerName) {
FreeSplMem(pszSpoolerName);
}
if (pszModuleName) {
FreeSplMem(pszModuleName);
}
if (bAllocSysDir) {
FreeSplMem(pszSysDir);
}
return;
}
//
// This entry point is called on DLL initialisation.
// We need to know the module handle so we can load resources.
//
BOOL DllMain(
IN PVOID hmod,
IN DWORD Reason,
IN PCONTEXT pctx OPTIONAL)
{
DBG_UNREFERENCED_PARAMETER(pctx);
switch (Reason) {
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls((HMODULE)hmod);
hInst = hmod;
__try {
if( !bSplLibInit(NULL) ) {
return FALSE;
}
} __except(EXCEPTION_EXECUTE_HANDLER) {
SetLastError(GetExceptionCode());
return FALSE;
}
InitializeGlobalVariables();
__try {
InitializeCriticalSection(&ClientSection);
} __except(EXCEPTION_EXECUTE_HANDLER) {
SetLastError(GetExceptionCode());
return FALSE;
}
__try {
InitializeCriticalSection(&ListAccessSem);
} __except(EXCEPTION_EXECUTE_HANDLER) {
DeleteCriticalSection(&ClientSection);
SetLastError(GetExceptionCode());
return FALSE;
}
__try {
InitializeCriticalSection(&ProcessHndlCS);
} __except(EXCEPTION_EXECUTE_HANDLER) {
DeleteCriticalSection(&ClientSection);
DeleteCriticalSection(&ListAccessSem);
SetLastError(GetExceptionCode());
return FALSE;
}
break;
case DLL_PROCESS_DETACH:
vSplLibFree();
DeleteCriticalSection( &ClientSection );
DeleteCriticalSection( &ListAccessSem );
DeleteCriticalSection( &ProcessHndlCS);
break;
}
return TRUE;
}