|
|
/*++
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; }
|