746 lines
20 KiB
C++
746 lines
20 KiB
C++
|
/*****************************************************************************\
|
||
|
* 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"
|
||
|
|
||
|
#ifdef WINNT32
|
||
|
|
||
|
extern "C" {
|
||
|
|
||
|
BOOL
|
||
|
BuildOtherNamesFromMachineName(
|
||
|
LPWSTR **ppszMyOtherNames,
|
||
|
DWORD *cOtherNames
|
||
|
);
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
/*****************************************************************************\
|
||
|
* _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 ();
|
||
|
|
||
|
#ifdef WINNT32
|
||
|
if (OpenPrinter (NULL, &hServer, NULL)) {
|
||
|
|
||
|
if (ERROR_SUCCESS != GetPrinterData (hServer,
|
||
|
SPLREG_DEFAULT_SPOOL_DIRECTORY,
|
||
|
&dwType,
|
||
|
(LPBYTE) g_szDefSplDir,
|
||
|
cbSize,
|
||
|
&cbSize)) {
|
||
|
}
|
||
|
|
||
|
ClosePrinter (hServer);
|
||
|
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
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;
|
||
|
|
||
|
#if 0
|
||
|
HINSTANCE hWinInet;
|
||
|
|
||
|
// Initialize the WinInet API function-ptrs.
|
||
|
//
|
||
|
if (hWinInet = LoadLibrary(g_szWinInetDll)) {
|
||
|
|
||
|
g_pfnHttpQueryInfo = (PFNHTTPQUERYINFO) GetProcAddress(hWinInet, g_szHttpQueryInfo);
|
||
|
g_pfnInternetOpenUrl = (PFNINTERNETOPENURL) GetProcAddress(hWinInet, g_szInternetOpenUrl);
|
||
|
g_pfnInternetErrorDlg = (PFNINTERNETERRORDLG) GetProcAddress(hWinInet, g_szInternetErrorDlg);
|
||
|
g_pfnHttpSendRequest = (PFNHTTPSENDREQUEST) GetProcAddress(hWinInet, g_szHttpSendRequest);
|
||
|
g_pfnHttpSendRequestEx = (PFNHTTPSENDREQUESTEX) GetProcAddress(hWinInet, g_szHttpSendRequestEx);
|
||
|
g_pfnInternetReadFile = (PFNINTERNETREADFILE) GetProcAddress(hWinInet, g_szInternetReadFile);
|
||
|
g_pfnInternetWriteFile = (PFNINTERNETWRITEFILE) GetProcAddress(hWinInet, g_szInternetWriteFile);
|
||
|
g_pfnInternetCloseHandle = (PFNINTERNETCLOSEHANDLE) GetProcAddress(hWinInet, g_szInternetCloseHandle);
|
||
|
g_pfnInternetOpen = (PFNINTERNETOPEN) GetProcAddress(hWinInet, g_szInternetOpen);
|
||
|
g_pfnInternetConnect = (PFNINTERNETCONNECT) GetProcAddress(hWinInet, g_szInternetConnect);
|
||
|
g_pfnHttpOpenRequest = (PFNHTTPOPENREQUEST) GetProcAddress(hWinInet, g_szHttpOpenRequest);
|
||
|
g_pfnHttpAddRequestHeaders = (PFNHTTPADDREQUESTHEADERS)GetProcAddress(hWinInet, g_szHttpAddRequestHeaders);
|
||
|
g_pfnHttpEndRequest = (PFNHTTPENDREQUEST) GetProcAddress(hWinInet, g_szHttpEndRequest);
|
||
|
g_pfnInternetSetOption = (PFNINTERNETSETOPTION) GetProcAddress(hWinInet, g_szInternetSetOption);
|
||
|
|
||
|
|
||
|
// Check for any failures.
|
||
|
//
|
||
|
if (g_pfnHttpQueryInfo &&
|
||
|
g_pfnInternetOpenUrl &&
|
||
|
g_pfnInternetErrorDlg &&
|
||
|
g_pfnHttpSendRequest &&
|
||
|
g_pfnHttpSendRequestEx &&
|
||
|
g_pfnInternetReadFile &&
|
||
|
g_pfnInternetWriteFile &&
|
||
|
g_pfnInternetCloseHandle &&
|
||
|
g_pfnInternetOpen &&
|
||
|
g_pfnInternetConnect &&
|
||
|
g_pfnHttpOpenRequest &&
|
||
|
g_pfnHttpAddRequestHeaders &&
|
||
|
g_pfnHttpEndRequest &&
|
||
|
g_pfnInternetSetOption) {
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
FreeLibrary(hWinInet);
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
/*****************************************************************************\
|
||
|
* _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;
|
||
|
|
||
|
|
||
|
// 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;
|
||
|
|
||
|
// !!!
|
||
|
// Load spoolss here if we need to call spooler functions
|
||
|
// from the print provider.
|
||
|
//
|
||
|
|
||
|
|
||
|
// Initialize the crit-sect for synchronizing port access.
|
||
|
//
|
||
|
semInitCrit();
|
||
|
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exit_load:
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*****************************************************************************\
|
||
|
* _init_unload_provider (Local Routine)
|
||
|
*
|
||
|
* This performs the unloading/freeing of resources allocated by the
|
||
|
* provider.
|
||
|
*
|
||
|
\*****************************************************************************/
|
||
|
#if 0
|
||
|
// This piece of code is not needed since the dll is never get reloaded by spooler twice.
|
||
|
// -weihaic
|
||
|
|
||
|
BOOL _init_unload_provider(VOID)
|
||
|
{
|
||
|
|
||
|
// Free the critical-section.
|
||
|
//
|
||
|
semFreeCrit();
|
||
|
|
||
|
// Free the Registry
|
||
|
//
|
||
|
memFree (g_szRegProvider, sizeof (TCHAR) * (lstrlen (g_szRegProvider) + 1));
|
||
|
|
||
|
#ifdef WINNT32
|
||
|
memFree (g_szRegPrintProviders, sizeof (TCHAR) * (lstrlen (g_szRegPrintProviders) + 1));
|
||
|
#endif
|
||
|
|
||
|
// Free the monitor-port-list
|
||
|
//
|
||
|
memFree(g_pPortList, sizeof(INIMONPORTLIST));
|
||
|
|
||
|
|
||
|
// !!!
|
||
|
// Unload spoolss here if it's been loaded.
|
||
|
//
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/*****************************************************************************\
|
||
|
* _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;
|
||
|
|
||
|
// 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.
|
||
|
//
|
||
|
if (! (g_szRegProvider = (LPTSTR) memAlloc ((1 + lstrlen (lpszRegPath)) * sizeof (TCHAR)))) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
lstrcpy(g_szRegProvider, lpszRegPath);
|
||
|
|
||
|
#ifdef WINNT32
|
||
|
|
||
|
// Copy the registry key of all the printer providers
|
||
|
|
||
|
if (! (g_szRegPrintProviders = (LPTSTR) memAlloc ((1 + lstrlen (lpszRegPath)) * sizeof (TCHAR)))) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
lstrcpy(g_szRegPrintProviders, lpszRegPath);
|
||
|
pEnd = wcsrchr (g_szRegPrintProviders, L'\\');
|
||
|
|
||
|
if ( pEnd )
|
||
|
{
|
||
|
*pEnd = 0;
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
// 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) {
|
||
|
#ifdef WINNT32
|
||
|
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;
|
||
|
#else
|
||
|
return TRUE;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
/*****************************************************************************\
|
||
|
* 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.
|
||
|
*
|
||
|
* NOTE: The (pszFullRegistryPath) is really a LPTSTR as far as Win9X is
|
||
|
* concerned.
|
||
|
*
|
||
|
\*****************************************************************************/
|
||
|
#ifdef WINNT32
|
||
|
|
||
|
static PRINTPROVIDOR pfnPPList[] = {
|
||
|
#else
|
||
|
|
||
|
static LPCVOID pfnPPList[] = {
|
||
|
#endif
|
||
|
|
||
|
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,
|
||
|
#ifdef WINNT32
|
||
|
NULL,
|
||
|
NULL,
|
||
|
#else
|
||
|
stubConfigurePort,
|
||
|
PPDeletePort,
|
||
|
#endif
|
||
|
stubCreatePrinterIC,
|
||
|
stubPlayGdiScriptOnPrinterIC,
|
||
|
stubDeletePrinterIC,
|
||
|
stubAddPrinterConnection,
|
||
|
stubDeletePrinterConnection,
|
||
|
stubPrinterMessageBox,
|
||
|
stubAddMonitor,
|
||
|
stubDeleteMonitor
|
||
|
|
||
|
#ifndef WIN9X
|
||
|
,
|
||
|
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
|
||
|
#endif
|
||
|
|
||
|
};
|
||
|
|
||
|
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));
|
||
|
|
||
|
#ifdef WINNT32
|
||
|
// Initialise synchronisation objects
|
||
|
|
||
|
if (!_init_create_sync())
|
||
|
return FALSE;
|
||
|
|
||
|
// Initialize other names
|
||
|
|
||
|
if (!BuildOtherNamesFromMachineName(&g_ppszOtherNames, &g_cOtherNames))
|
||
|
return FALSE;
|
||
|
g_bUpgrade = SplIsUpgrade();
|
||
|
|
||
|
#endif
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*****************************************************************************\
|
||
|
* DllEntryPoint
|
||
|
*
|
||
|
* This is the main entry-point for the library.
|
||
|
*
|
||
|
\*****************************************************************************/
|
||
|
extern "C" {
|
||
|
|
||
|
BOOL WINAPI DllEntryPoint(
|
||
|
HINSTANCE hInstDll,
|
||
|
DWORD dwAttach,
|
||
|
LPVOID lpcReserved)
|
||
|
{
|
||
|
static BOOL s_bIsSpoolerProcess = FALSE;
|
||
|
BOOL bRet = TRUE;
|
||
|
|
||
|
|
||
|
switch (dwAttach) {
|
||
|
|
||
|
case DLL_PROCESS_ATTACH:
|
||
|
|
||
|
|
||
|
// Set the global-instance variable.
|
||
|
//
|
||
|
g_hInst = hInstDll;
|
||
|
|
||
|
s_bIsSpoolerProcess = TRUE;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case DLL_PROCESS_DETACH:
|
||
|
|
||
|
#if 0
|
||
|
// This code is not needed since the dll is never get loaded twice by spooler
|
||
|
// -weihaic
|
||
|
//
|
||
|
if (s_bIsSpoolerProcess)
|
||
|
_init_unload_provider();
|
||
|
#endif
|
||
|
|
||
|
#ifdef WINNT32
|
||
|
DeleteCriticalSection( &g_csCreateSection );
|
||
|
CloseHandle( g_eResetConnections );
|
||
|
#endif
|
||
|
|
||
|
if (g_pcsEndBrowserSessionLock)
|
||
|
{
|
||
|
delete g_pcsEndBrowserSessionLock;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case DLL_THREAD_ATTACH:
|
||
|
case DLL_THREAD_DETACH:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return bRet;
|
||
|
}
|
||
|
|
||
|
}
|