/*++ 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); 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 // StrNCatBuff(pszSpoolerName, dwSize / sizeof(WCHAR), pszSysDir, TEXT("\\spoolsv.exe"), NULL); // // 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) { DWORD LastError; 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(); if (!InitializeCriticalSectionAndSpinCount(&ClientSection, 0x80000000)) { return FALSE; } if (!InitializeCriticalSectionAndSpinCount(&ListAccessSem, 0x80000000)) { LastError = GetLastError(); DeleteCriticalSection(&ClientSection); SetLastError(LastError); return FALSE; } if (!InitializeCriticalSectionAndSpinCount(&ProcessHndlCS, 0x80000000)) { LastError = GetLastError(); DeleteCriticalSection(&ClientSection); DeleteCriticalSection(&ListAccessSem); SetLastError(LastError); return FALSE; } break; case DLL_PROCESS_DETACH: vSplLibFree(); DeleteCriticalSection( &ClientSection ); DeleteCriticalSection( &ListAccessSem ); DeleteCriticalSection( &ProcessHndlCS); break; } return TRUE; }