Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

586 lines
16 KiB

/*****************************************************************************\
* MODULE: ppinit.c
*
* This module contains the initialization routines for the Print-Provider.
* The spooler calls InitializePrintProvider() to retreive the list of
* calls that the Print-Processor supports.
*
*
* Copyright (C) 1996-1997 Microsoft Corporation
* Copyright (C) 1996-1997 Hewlett Packard
*
* History:
* 07-Oct-1996 HWP-Guys Initiated port from win95 to winNT
*
\*****************************************************************************/
#include "precomp.h"
#include "priv.h"
/*****************************************************************************\
* _init_provider_worker (Local Routine)
*
*
\*****************************************************************************/
void _init_provider_worker ()
{
// Get the default spool directory
HANDLE hServer = NULL;
DWORD dwType = REG_SZ;
DWORD cbSize = MAX_PATH * sizeof (TCHAR);
g_szDefSplDir[0] = 0;
semEnterCrit ();
if (OpenPrinter (NULL, &hServer, NULL)) {
if (ERROR_SUCCESS != GetPrinterData (hServer,
SPLREG_DEFAULT_SPOOL_DIRECTORY,
&dwType,
(LPBYTE) g_szDefSplDir,
cbSize,
&cbSize)) {
}
ClosePrinter (hServer);
}
SplClean ();
semLeaveCrit ();
}
/*****************************************************************************\
* _init_write_displayname (Local Routine)
*
*
\*****************************************************************************/
BOOL _init_write_displayname(VOID)
{
LONG lRet;
HKEY hkPath;
DWORD dwType;
DWORD cbSize;
if (!LoadString (g_hInst,
IDS_DISPLAY_NAME,
g_szDisplayStr,
MAX_PATH)) {
g_szDisplayStr[0] = 0;
}
// Open the key to the Print-Providor.
//
lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
g_szRegProvider,
0,
KEY_READ | KEY_WRITE,
&hkPath);
if (lRet == ERROR_SUCCESS) {
// Look for the "displayname". If it doesn't exist, then write it.
//
dwType = REG_SZ;
cbSize = 0;
lRet = RegQueryValueEx(hkPath,
g_szDisplayName,
NULL,
&dwType,
(LPBYTE)NULL,
&cbSize);
// Write the string.
//
if ((lRet != ERROR_SUCCESS) || (cbSize == 0)) {
dwType = REG_SZ;
cbSize = (lstrlen(g_szDisplayStr) + 1) * sizeof(TCHAR);
lRet = RegSetValueEx(hkPath,
g_szDisplayName,
0,
dwType,
(LPBYTE)g_szDisplayStr,
cbSize);
}
RegCloseKey(hkPath);
}
if (lRet != ERROR_SUCCESS) {
SetLastError (lRet);
return FALSE;
}
else
return TRUE;
}
/*****************************************************************************\
* _init_find_filename (Local Routine)
*
*
\*****************************************************************************/
LPTSTR _init_find_filename(
LPCTSTR lpszPathName)
{
LPTSTR lpszFileName;
if (lpszPathName == NULL)
return NULL;
// Look for the filename in the path, by starting at the end
// and looking for the ('\') char.
//
if (!(lpszFileName = utlStrChrR(lpszPathName, TEXT('\\'))))
lpszFileName = (LPTSTR)lpszPathName;
else
lpszFileName++;
return lpszFileName;
}
/*****************************************************************************\
* _init_load_netapi (Local Routine)
*
* Initialize INET API pointers.
*
\*****************************************************************************/
BOOL _init_load_netapi(VOID)
{
g_pfnHttpQueryInfo = (PFNHTTPQUERYINFO) HttpQueryInfoA;
g_pfnInternetOpenUrl = (PFNINTERNETOPENURL) InternetOpenUrlA;
g_pfnInternetErrorDlg = (PFNINTERNETERRORDLG) InternetErrorDlg;
g_pfnHttpSendRequest = (PFNHTTPSENDREQUEST) HttpSendRequestA;
g_pfnHttpSendRequestEx = (PFNHTTPSENDREQUESTEX) HttpSendRequestExA;
g_pfnInternetReadFile = (PFNINTERNETREADFILE) InternetReadFile;
g_pfnInternetWriteFile = (PFNINTERNETWRITEFILE) InternetWriteFile;
g_pfnInternetCloseHandle = (PFNINTERNETCLOSEHANDLE) InternetCloseHandle;
g_pfnInternetOpen = (PFNINTERNETOPEN) InternetOpenA;
g_pfnInternetConnect = (PFNINTERNETCONNECT) InternetConnectA;
g_pfnHttpOpenRequest = (PFNHTTPOPENREQUEST) HttpOpenRequestA;
g_pfnHttpAddRequestHeaders = (PFNHTTPADDREQUESTHEADERS)HttpAddRequestHeadersA;
g_pfnHttpEndRequest = (PFNHTTPENDREQUEST) HttpEndRequestA;
g_pfnInternetSetOption = (PFNINTERNETSETOPTION) InternetSetOptionA;
return TRUE;
}
/*****************************************************************************\
* _init_load_provider (Local Routine)
*
* This performs the startup initialization for the print-provider.
*
\*****************************************************************************/
BOOL _init_load_provider()
{
LPTSTR lpszFileName;
TCHAR szBuf[MAX_PATH];
DWORD i = MAX_COMPUTERNAME_LENGTH + 1;
BOOL bRet = FALSE;
// Get the module name for this process.
//
if (!GetModuleFileName(NULL, szBuf, MAX_PATH))
goto exit_load;
// Get the filename from the full module-name. and check that
// it's the spooler.
//
if (lpszFileName = _init_find_filename(szBuf)) {
if (lstrcmpi(lpszFileName, g_szProcessName) == 0) {
// Initialize the computer name.
//
if (!GetComputerName(g_szMachine, &i))
goto exit_load;
// Initialize the internet API pointers.
//
if (_init_load_netapi() == FALSE)
goto exit_load;
//
// Assume success.
//
bRet = TRUE;
//
// Try and initialize the crit-sect for synchronizing port access.
//
__try {
InitializeCriticalSection(&g_csMonitorSection);
}
__except (1) {
bRet = FALSE;
SetLastError (ERROR_INVALID_HANDLE);
}
return bRet;
}
}
exit_load:
return bRet;
}
/*****************************************************************************\
* _init_load_ports (Local Routine)
*
* This performs the port initialization for the print-provider.
*
\*****************************************************************************/
BOOL _init_load_ports(
LPTSTR lpszRegPath)
{
LONG lStat;
HKEY hkPath;
HKEY hkPortNames;
TCHAR szPortName[MAX_PATH];
BOOL bRet = FALSE;
LPTSTR pEnd = NULL;
size_t uSize = 0;
//
// Make sure there is a registry-path pointing to the
// INET provider entry.
//
if (lpszRegPath == NULL)
return FALSE;
//
// Copy the string to global-memory. We will need this if we require
// the need to write to the registry when creating new ports.
//
uSize = 1 + lstrlen (lpszRegPath);
if (! (g_szRegProvider = (LPTSTR) memAlloc (uSize * sizeof (TCHAR)))) {
return FALSE;
}
StringCchCopy(g_szRegProvider, uSize, lpszRegPath);
//
// Copy the registry key of all the printer providers
//
if (! (g_szRegPrintProviders = (LPTSTR) memAlloc (uSize * sizeof (TCHAR)))) {
return FALSE;
}
StringCchCopy(g_szRegPrintProviders, uSize, lpszRegPath);
pEnd = wcsrchr (g_szRegPrintProviders, L'\\');
if ( pEnd )
{
*pEnd = 0;
}
// Open registry key for Provider-Name.
//
lStat = RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpszRegPath, 0, KEY_READ, &hkPath);
if (lStat == ERROR_SUCCESS) {
bRet = TRUE;
// Open the "ports" key for enumeration of the ports. We need to
// build up this list at the provider initialization time so that
// we can return the list of ports if called to EnumPorts().
//
lStat = RegOpenKeyEx(hkPath, g_szRegPorts, 0, KEY_READ, &hkPortNames);
if (lStat == ERROR_SUCCESS) {
DWORD dwSize;
DWORD i = 0;
while (lStat == ERROR_SUCCESS) {
dwSize = sizeof(szPortName) / sizeof (TCHAR);
lStat = RegEnumKey (hkPortNames,
i,
szPortName,
dwSize);
if (lStat == ERROR_SUCCESS) {
// Do not short-cut this call to InetmonAddPort(),
// as this will leave the crit-sect unprotected.
//
PPAddPort(szPortName, NULL, NULL);
}
i++;
}
RegCloseKey(hkPortNames);
} else {
DBG_MSG(DBG_LEV_INFO, (TEXT("RegOpenKeyEx(%s) failed: Error = %lu"), g_szRegPorts, lStat));
SetLastError(lStat);
}
RegCloseKey(hkPath);
} else {
DBG_MSG(DBG_LEV_WARN, (TEXT("RegOpenKeyEx(%s) failed: Error = %lu"), lpszRegPath, lStat));
SetLastError(lStat);
}
return bRet;
}
/*****************************************************************************\
* _init_create_sync (Local Routine)
*
* This creates the events and Critical Section needed for handling the synchronisation
* in the monitor.
*
\*****************************************************************************/
_inline BOOL _init_create_sync(VOID)
{
BOOL bRet = TRUE;
g_dwConCount = 0;
__try {
InitializeCriticalSection(&g_csCreateSection);
}
__except (1) {
bRet = FALSE;
SetLastError (ERROR_INVALID_HANDLE);
}
if (bRet) {
g_eResetConnections = CreateEvent( NULL, TRUE, TRUE, NULL );
if (g_eResetConnections == NULL)
bRet = FALSE;
}
return bRet;
}
/*****************************************************************************\
* InitializePrintProvider (API)
*
* The spooler calls this routine to initialize the Print-Provider. The list
* of functions in the table are passed back to the spooler for it to use
* when interfacing with the provider.
*
\*****************************************************************************/
static PRINTPROVIDOR pfnPPList[] = {
PPOpenPrinter,
PPSetJob,
PPGetJob,
PPEnumJobs,
stubAddPrinter,
stubDeletePrinter,
PPSetPrinter,
PPGetPrinter,
PPEnumPrinters,
stubAddPrinterDriver,
stubEnumPrinterDrivers,
stubGetPrinterDriver,
stubGetPrinterDriverDirectory,
stubDeletePrinterDriver,
stubAddPrintProcessor,
stubEnumPrintProcessors,
stubGetPrintProcessorDirectory,
stubDeletePrintProcessor,
stubEnumPrintProcessorDatatypes,
PPStartDocPrinter,
PPStartPagePrinter,
PPWritePrinter,
PPEndPagePrinter,
PPAbortPrinter,
stubReadPrinter,
PPEndDocPrinter,
PPAddJob,
PPScheduleJob,
stubGetPrinterData,
stubSetPrinterData,
stubWaitForPrinterChange,
PPClosePrinter,
stubAddForm,
stubDeleteForm,
stubGetForm,
stubSetForm,
stubEnumForms,
stubEnumMonitors,
PPEnumPorts,
stubAddPort,
NULL,
NULL,
stubCreatePrinterIC,
stubPlayGdiScriptOnPrinterIC,
stubDeletePrinterIC,
stubAddPrinterConnection,
stubDeletePrinterConnection,
stubPrinterMessageBox,
stubAddMonitor,
stubDeleteMonitor,
NULL, // stubResetPrinter,
NULL, // stubGetPrinterDriverEx should not be called as specified in spoolss\dll\nullpp.c
PPFindFirstPrinterChangeNotification,
PPFindClosePrinterChangeNotification,
NULL, // stubAddPortEx,
NULL, // stubShutDown,
NULL, // stubRefreshPrinterChangeNotification,
NULL, // stubOpenPrinterEx,
NULL, // stubAddPrinterEx,
NULL, // stubSetPort,
NULL, // stubEnumPrinterData,
NULL, // stubDeletePrinterData,
NULL, // fpClusterSplOpen
NULL, // fpClusterSplClose
NULL, // fpClusterSplIsAlive
NULL, // fpSetPrinterDataEx
NULL, // fpGetPrinterDataEx
NULL, // fpEnumPrinterDataEx
NULL, // fpEnumPrinterKey
NULL, // fpDeletePrinterDataEx
NULL, // fpDeletePrinterKey
NULL, // fpSeekPrinter
NULL, // fpDeletePrinterDriverEx
NULL, // fpAddPerMachineConnection
NULL, // fpDeletePerMachineConnection
NULL, // fpEnumPerMachineConnections
PPXcvData, // fpXcvData
NULL, // fpAddPrinterDriverEx
NULL, // fpSplReadPrinter
NULL, // fpDriverUnloadComplete
NULL, // fpGetSpoolFileInfo
NULL, // fpCommitSpoolData
NULL, // fpCloseSpoolFileHandle
NULL, // fpFlushPrinter
NULL, // fpSendRecvBidiData
NULL, // fpAddDriverCatalog
};
BOOL WINAPI InitializePrintProvidor(
LPPRINTPROVIDOR pPP,
DWORD cEntries,
LPWSTR pszFullRegistryPath)
{
HANDLE hThread;
DWORD dwThreadId;
g_pcsEndBrowserSessionLock = new CCriticalSection ();
if (!g_pcsEndBrowserSessionLock || g_pcsEndBrowserSessionLock->bValid () == FALSE) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (_init_load_provider() == FALSE) {
DBG_ASSERT(FALSE, (TEXT("Assert: Failed module initialization")));
return FALSE;
}
if (!pszFullRegistryPath || !*pszFullRegistryPath) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
gpInetMon = new CInetMon;
if (!gpInetMon || gpInetMon->bValid() == FALSE) {
if (gpInetMon) {
delete gpInetMon;
}
return FALSE;
}
if (gpInetMon && !gpInetMon->bValid ()) {
delete gpInetMon;
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
DBG_MSG(DBG_LEV_CALLTREE, (TEXT("Call: InitializePrintProvidor")));
memcpy(pPP, pfnPPList, min(sizeof(pfnPPList), (int)cEntries));
// Initialise synchronisation objects
if (!_init_create_sync())
return FALSE;
g_bUpgrade = SplIsUpgrade();
if (_init_load_ports((LPTSTR)pszFullRegistryPath) == FALSE) {
DBG_ASSERT(FALSE, (TEXT("Assert: Failed port initialization")));
return FALSE;
}
if (!_init_write_displayname())
return FALSE;
if (hThread = CreateThread (NULL,
0,
(LPTHREAD_START_ROUTINE) _init_provider_worker,
NULL,
0,
&dwThreadId)) {
CloseHandle (hThread);
return TRUE;
}
else
return FALSE;
}
/*****************************************************************************\
* DllMain
*
* This is the main entry-point for the library.
*
\*****************************************************************************/
extern "C"
BOOL WINAPI DllMain(
HINSTANCE hInstDll,
DWORD dwAttach,
LPVOID lpcReserved)
{
switch (dwAttach)
{
case DLL_PROCESS_ATTACH:
g_hInst = hInstDll;
DisableThreadLibraryCalls(hInstDll);
break;
case DLL_PROCESS_DETACH:
DeleteCriticalSection(&g_csCreateSection);
DeleteCriticalSection(&g_csMonitorSection);
CloseHandle(g_eResetConnections);
delete g_pcsEndBrowserSessionLock;
break;
}
return TRUE;
}