Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

884 lines
21 KiB

/*++
Copyright (c) 1990 - 1995 Microsoft Corporation
Module Name:
winspool.c
Abstract:
This module provides all the public exported APIs relating to Printer
and Job management for the Print Providor Routing layer
Author:
Dave Snipp (DaveSn) 15-Mar-1991
[Notes:]
optional-notes
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
//
// Globals
//
LPPROVIDOR pLocalProvidor;
MODULE_DEBUG_INIT( DBG_ERROR | DBG_WARNING, DBG_ERROR );
HANDLE hEventInit;
BOOL Initialized=FALSE;
LPWSTR szPrintKey = L"System\\CurrentControlSet\\Control\\Print";
LPWSTR szEnvironment = LOCAL_ENVIRONMENT;
LPWSTR szRegistryProvidors = L"System\\CurrentControlSet\\Control\\Print\\Providers";
LPWSTR szLocalSplDll = L"localspl.dll";
LPWSTR szOrder = L"Order";
BOOL
AddPrinterDriverW(
LPWSTR pName,
DWORD Level,
LPBYTE pDriverInfo
)
{
LPPROVIDOR pProvidor;
if (!Initialized) {
WaitForSingleObject(hEventInit, INFINITE);
}
pProvidor = pLocalProvidor;
while (pProvidor) {
if ((*pProvidor->PrintProvidor.fpAddPrinterDriver) (pName, Level, pDriverInfo)) {
return TRUE;
} else if (GetLastError() != ERROR_INVALID_NAME) {
return FALSE;
}
pProvidor = pProvidor->pNext;
}
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
BOOL
EnumPrinterDriversW(
LPWSTR pName,
LPWSTR pEnvironment,
DWORD Level,
LPBYTE pDrivers,
DWORD cbBuf,
LPDWORD pcbNeeded,
LPDWORD pcReturned
)
{
PROVIDOR *pProvidor;
if ((pDrivers == NULL) && (cbBuf != 0)) {
SetLastError(ERROR_INVALID_USER_BUFFER);
return FALSE;
}
if (!Initialized) {
WaitForSingleObject(hEventInit, INFINITE);
}
if (!pEnvironment || !*pEnvironment)
pEnvironment = szEnvironment;
pProvidor = pLocalProvidor;
while (pProvidor) {
if (!(*pProvidor->PrintProvidor.fpEnumPrinterDrivers) (pName, pEnvironment, Level,
pDrivers, cbBuf,
pcbNeeded, pcReturned)) {
if (GetLastError() != ERROR_INVALID_NAME)
return FALSE;
} else
return TRUE;
pProvidor = pProvidor->pNext;
}
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
BOOL
GetPrinterDriverDirectoryW(
LPWSTR pName,
LPWSTR pEnvironment,
DWORD Level,
LPBYTE pDriverInfo,
DWORD cbBuf,
LPDWORD pcbNeeded
)
{
LPPROVIDOR pProvidor;
DWORD Error;
if ((pDriverInfo == NULL) && (cbBuf != 0)) {
SetLastError(ERROR_INVALID_USER_BUFFER);
return FALSE;
}
if (!Initialized) {
WaitForSingleObject(hEventInit, INFINITE);
}
if (!pEnvironment || !*pEnvironment)
pEnvironment = szEnvironment;
pProvidor = pLocalProvidor;
while (pProvidor) {
if ((*pProvidor->PrintProvidor.fpGetPrinterDriverDirectory)
(pName, pEnvironment, Level, pDriverInfo,
cbBuf, pcbNeeded)) {
return TRUE;
} else if ((Error=GetLastError()) != ERROR_INVALID_NAME) {
return FALSE;
}
pProvidor = pProvidor->pNext;
}
return FALSE;
}
BOOL
DeletePrinterDriverW(
LPWSTR pName,
LPWSTR pEnvironment,
LPWSTR pDriverName
)
{
LPPROVIDOR pProvidor;
DWORD Error;
if (!Initialized) {
WaitForSingleObject(hEventInit, INFINITE);
}
if (!pEnvironment || !*pEnvironment)
pEnvironment = szEnvironment;
pProvidor = pLocalProvidor;
while (pProvidor) {
if ((*pProvidor->PrintProvidor.fpDeletePrinterDriver)
(pName, pEnvironment, pDriverName)) {
return TRUE;
} else if ((Error=GetLastError()) != ERROR_INVALID_NAME) {
return FALSE;
}
pProvidor = pProvidor->pNext;
}
return FALSE;
}
BOOL
AddPrintProcessorW(
LPWSTR pName,
LPWSTR pEnvironment,
LPWSTR pPathName,
LPWSTR pPrintProcessorName
)
{
LPPROVIDOR pProvidor;
if (!Initialized) {
WaitForSingleObject(hEventInit, INFINITE);
}
if (!pEnvironment || !*pEnvironment)
pEnvironment = szEnvironment;
pProvidor = pLocalProvidor;
while (pProvidor) {
if ((*pProvidor->PrintProvidor.fpAddPrintProcessor) (pName, pEnvironment,
pPathName,
pPrintProcessorName)) {
return TRUE;
} else if (GetLastError() != ERROR_INVALID_NAME) {
return FALSE;
}
pProvidor = pProvidor->pNext;
}
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
BOOL
EnumPrintProcessorsW(
LPWSTR pName,
LPWSTR pEnvironment,
DWORD Level,
LPBYTE pPrintProcessors,
DWORD cbBuf,
LPDWORD pcbNeeded,
LPDWORD pcReturned
)
{
LPPROVIDOR pProvidor;
if ((pPrintProcessors == NULL) && (cbBuf != 0)) {
SetLastError(ERROR_INVALID_USER_BUFFER);
return FALSE;
}
if (!Initialized) {
WaitForSingleObject(hEventInit, INFINITE);
}
if (!pEnvironment || !*pEnvironment)
pEnvironment = szEnvironment;
pProvidor = pLocalProvidor;
while (pProvidor) {
if (!(*pProvidor->PrintProvidor.fpEnumPrintProcessors) (pName, pEnvironment, Level,
pPrintProcessors, cbBuf,
pcbNeeded, pcReturned)) {
if (GetLastError() != ERROR_INVALID_NAME)
return FALSE;
} else
return TRUE;
pProvidor = pProvidor->pNext;
}
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
BOOL
GetPrintProcessorDirectoryW(
LPWSTR pName,
LPWSTR pEnvironment,
DWORD Level,
LPBYTE pPrintProcessorInfo,
DWORD cbBuf,
LPDWORD pcbNeeded
)
{
LPPROVIDOR pProvidor;
DWORD Error;
if ((pPrintProcessorInfo == NULL) && (cbBuf != 0)) {
SetLastError(ERROR_INVALID_USER_BUFFER);
return FALSE;
}
if (!Initialized) {
WaitForSingleObject(hEventInit, INFINITE);
}
if (!pEnvironment || !*pEnvironment)
pEnvironment = szEnvironment;
pProvidor = pLocalProvidor;
while (pProvidor) {
if ((*pProvidor->PrintProvidor.fpGetPrintProcessorDirectory)
(pName, pEnvironment, Level,
pPrintProcessorInfo,
cbBuf, pcbNeeded)) {
return TRUE;
} else if ((Error=GetLastError()) != ERROR_INVALID_NAME) {
return FALSE;
}
pProvidor = pProvidor->pNext;
}
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
BOOL
EnumPrintProcessorDatatypesW(
LPWSTR pName,
LPWSTR pPrintProcessorName,
DWORD Level,
LPBYTE pDatatypes,
DWORD cbBuf,
LPDWORD pcbNeeded,
LPDWORD pcReturned
)
{
LPPROVIDOR pProvidor;
if ((pDatatypes == NULL) && (cbBuf != 0)) {
SetLastError(ERROR_INVALID_USER_BUFFER);
return FALSE;
}
if (!Initialized) {
WaitForSingleObject(hEventInit, INFINITE);
}
pProvidor = pLocalProvidor;
while (pProvidor) {
if (!(*pProvidor->PrintProvidor.fpEnumPrintProcessorDatatypes)
(pName, pPrintProcessorName,
Level, pDatatypes, cbBuf,
pcbNeeded, pcReturned)) {
if (GetLastError() != ERROR_INVALID_NAME)
return FALSE;
} else
return TRUE;
pProvidor = pProvidor->pNext;
}
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
BOOL
AddFormW(
HANDLE hPrinter,
DWORD Level,
LPBYTE pForm
)
{
LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
return (*pPrintHandle->pProvidor->PrintProvidor.fpAddForm) (pPrintHandle->hPrinter,
Level, pForm);
}
BOOL
DeleteFormW(
HANDLE hPrinter,
LPWSTR pFormName
)
{
LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
return (*pPrintHandle->pProvidor->PrintProvidor.fpDeleteForm) (pPrintHandle->hPrinter,
pFormName);
}
BOOL
GetFormW(
HANDLE hPrinter,
LPWSTR pFormName,
DWORD Level,
LPBYTE pForm,
DWORD cbBuf,
LPDWORD pcbNeeded
)
{
LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if ((pForm == NULL) && (cbBuf != 0)) {
SetLastError(ERROR_INVALID_USER_BUFFER);
return FALSE;
}
return (*pPrintHandle->pProvidor->PrintProvidor.fpGetForm) (pPrintHandle->hPrinter,
pFormName, Level, pForm,
cbBuf, pcbNeeded);
}
BOOL
SetFormW(
HANDLE hPrinter,
LPWSTR pFormName,
DWORD Level,
LPBYTE pForm
)
{
LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
return (*pPrintHandle->pProvidor->PrintProvidor.fpSetForm) (pPrintHandle->hPrinter,
pFormName, Level, pForm);
}
BOOL
EnumFormsW(
HANDLE hPrinter,
DWORD Level,
LPBYTE pForm,
DWORD cbBuf,
LPDWORD pcbNeeded,
LPDWORD pcReturned
)
{
LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if ((pForm == NULL) && (cbBuf != 0)) {
SetLastError(ERROR_INVALID_USER_BUFFER);
return FALSE;
}
return (*pPrintHandle->pProvidor->PrintProvidor.fpEnumForms) (pPrintHandle->hPrinter,
Level, pForm, cbBuf,
pcbNeeded, pcReturned);
}
BOOL
DeletePrintProcessorW(
LPWSTR pName,
LPWSTR pEnvironment,
LPWSTR pPrintProcessorName
)
{
LPPROVIDOR pProvidor;
DWORD Error;
if (!Initialized) {
WaitForSingleObject(hEventInit, INFINITE);
}
if (!pEnvironment || !*pEnvironment)
pEnvironment = szEnvironment;
pProvidor = pLocalProvidor;
while (pProvidor) {
if ((*pProvidor->PrintProvidor.fpDeletePrintProcessor)
(pName, pEnvironment, pPrintProcessorName)) {
return TRUE;
} else if ((Error=GetLastError()) != ERROR_INVALID_NAME) {
return FALSE;
}
pProvidor = pProvidor->pNext;
}
return FALSE;
}
BOOL
AddPrintProvidorW(
LPWSTR pName,
DWORD Level,
LPBYTE pProvidorInfo
)
{
WCHAR ProvidorName[MAX_PATH];
HKEY hKey;
HKEY hKeyProvidors;
HANDLE hToken;
LONG Error;
BOOL rc = FALSE;
LPPROVIDOR_INFO_1W pProvidorInfo1=(LPPROVIDOR_INFO_1W)pProvidorInfo;
LPWSTR lpMem = NULL;
LPWSTR lpNewMem = NULL;
DWORD dwRequired = 0;
DWORD dwReturned = 0;
wcscpy(ProvidorName, szRegistryProvidors);
wcscat(ProvidorName, L"\\");
wcscat(ProvidorName, pProvidorInfo1->pName);
hToken = RevertToPrinterSelf();
// We'll create the "Providors" Key to start with.
// If it exists, we'll return a handle to the key
// We are interested in creating a subkey. If anything
// fails, lilke creating a value etc, we'll cleandelete
// up by deleting the subkey only. For the "Providors"
// key, we'll just close it.
Error = RegCreateKeyEx(HKEY_LOCAL_MACHINE, szRegistryProvidors, 0,
NULL, 0, KEY_ALL_ACCESS, NULL, &hKeyProvidors, NULL);
if (Error == ERROR_SUCCESS) {
Error = RegCreateKeyEx(HKEY_LOCAL_MACHINE, ProvidorName, 0,
NULL, 0, KEY_WRITE, NULL, &hKey, NULL);
if (Error == ERROR_SUCCESS) {
Error = RegSetValueEx(hKey, L"Name", 0, REG_SZ,
(LPBYTE)pProvidorInfo1->pDLLName,
(wcslen(pProvidorInfo1->pDLLName) + 1)*sizeof(WCHAR));
if (Error == ERROR_SUCCESS) {
Error = RegQueryValueEx(hKeyProvidors, szOrder, 0,
NULL, NULL, &dwRequired);
// There are two cases which mean success
// Case 1 - "Order" doesn't exist - ERROR_FILE_NOT_FOUND
// Case 2 - "Order" exists - insufficient memory - ERROR_SUCCESS
if ((Error == ERROR_SUCCESS) ||
(Error == ERROR_FILE_NOT_FOUND)) {
if (Error == ERROR_SUCCESS) {
if (dwRequired != 0) {
lpMem = (LPWSTR)AllocSplMem(dwRequired);
if (lpMem == NULL) {
DeleteSubKeyTree(hKeyProvidors,
pProvidorInfo1->pName);
RegDeleteKey(hKeyProvidors,
pProvidorInfo1->pName);
RegCloseKey(hKeyProvidors);
return(FALSE);
}
}
// This shouldn't fail !!
// but why take chances !!
Error = RegQueryValueEx(hKeyProvidors, szOrder, 0,
NULL, (LPBYTE)lpMem, &dwRequired);
// If it does fail, quit,
// there is nothing we can do
if (Error != ERROR_SUCCESS) {
if (lpMem) {
FreeSplMem(lpMem);
}
DeleteSubKeyTree(hKeyProvidors,
pProvidorInfo1->pName);
RegDeleteKey(hKeyProvidors,
pProvidorInfo1->pName);
RegCloseKey(hKeyProvidors);
return(FALSE);
}
} // end extra processing for ERROR_SUCCESS
lpNewMem = (LPWSTR)AppendOrderEntry(lpMem, dwRequired,
pProvidorInfo1->pName,&dwReturned);
if (lpNewMem) {
Error = RegSetValueEx(hKeyProvidors, szOrder, 0,
REG_MULTI_SZ, (LPBYTE)lpNewMem, dwReturned);
FreeSplMem(lpNewMem);
} else
Error = GetLastError();
if (lpMem) {
FreeSplMem(lpMem);
}
}
}
RegCloseKey(hKey);
}
RegCloseKey(hKeyProvidors);
}
if (Error != ERROR_SUCCESS)
SetLastError(Error);
ImpersonatePrinterClient(hToken);
return (Error == ERROR_SUCCESS);
}
BOOL
DeletePrintProvidorW(
LPWSTR pName,
LPWSTR pEnvironment,
LPWSTR pPrintProvidorName
)
{
LONG Error;
HANDLE hToken;
HKEY hKey;
BOOL RetVal;
LPWSTR lpMem = NULL;
LPWSTR lpNewMem = NULL;
DWORD dwRequired = 0;
DWORD dwReturned = 0;
DWORD dwAllocated;
hToken = RevertToPrinterSelf();
Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szRegistryProvidors,
0, KEY_ALL_ACCESS, &hKey);
if (Error == ERROR_SUCCESS) {
// update the "Order" value of szRegistryProvidors
// this is new!!
Error = RegQueryValueEx(hKey, szOrder, NULL, NULL,
NULL, &dwRequired);
if (Error == ERROR_SUCCESS)
{
if (dwRequired != 0) {
lpMem = (LPWSTR)AllocSplMem(dwRequired);
dwAllocated = dwRequired;
if (lpMem == NULL) {
RegCloseKey(hKey);
return(FALSE);
}
}
Error = RegQueryValueEx(hKey, szOrder, NULL, NULL,
(LPBYTE)lpMem, &dwRequired);
// RegQueryValueEx shouldn't fail, but if
// it does exit FALSE
if (Error != ERROR_SUCCESS) {
if (lpMem) {
FreeSplMem(lpMem);
}
RegCloseKey(hKey);
return(FALSE);
}
lpNewMem = RemoveOrderEntry(lpMem, dwRequired,
pPrintProvidorName, &dwReturned);
if (lpNewMem) {
Error = RegSetValueEx(hKey, szOrder, 0, REG_MULTI_SZ,
(LPBYTE)lpNewMem, dwReturned);
if (Error != ERROR_SUCCESS) {
FreeSplMem(lpNewMem);
if (lpMem) {
FreeSplMem(lpMem);
}
RegCloseKey(hKey);
return(FALSE); // Couldn't reset the
// Order value - return FALSE
}
FreeSplMem(lpNewMem);
}
if (lpMem) {
FreeSplMem(lpMem);
}
// Now, we delete the subkey and all its children
// Remember, you can't delete a key unless you delete its
// subkeys.
RetVal = DeleteSubKeyTree(hKey, pPrintProvidorName);
if (RetVal == FALSE) {
RegCloseKey(hKey);
return(FALSE);
}
}
RegCloseKey(hKey);
}
if (Error != ERROR_SUCCESS) {
SetLastError(Error);
}
ImpersonatePrinterClient(hToken);
return(Error == ERROR_SUCCESS);
}
BOOL
OldGetPrinterDriverW(
HANDLE hPrinter,
LPWSTR pEnvironment,
DWORD Level,
LPBYTE pDriverInfo,
DWORD cbBuf,
LPDWORD pcbNeeded
)
{
LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if ((pDriverInfo == NULL) && (cbBuf != 0)) {
SetLastError(ERROR_INVALID_USER_BUFFER);
return FALSE;
}
if (!pEnvironment || !*pEnvironment)
pEnvironment = szEnvironment;
return (*pPrintHandle->pProvidor->PrintProvidor.fpGetPrinterDriver)
(pPrintHandle->hPrinter, pEnvironment,
Level, pDriverInfo, cbBuf, pcbNeeded);
}
BOOL
GetPrinterDriverExW(
HANDLE hPrinter,
LPWSTR pEnvironment,
DWORD Level,
LPBYTE pDriverInfo,
DWORD cbBuf,
LPDWORD pcbNeeded,
DWORD dwClientMajorVersion,
DWORD dwClientMinorVersion,
PDWORD pdwServerMajorVersion,
PDWORD pdwServerMinorVersion
)
{
LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
if ((pDriverInfo == NULL) && (cbBuf != 0)) {
SetLastError(ERROR_INVALID_USER_BUFFER);
return FALSE;
}
if (!pEnvironment || !*pEnvironment)
pEnvironment = szEnvironment;
if (pPrintHandle->pProvidor->PrintProvidor.fpGetPrinterDriverEx) {
DBGMSG(DBG_TRACE, ("Calling the fpGetPrinterDriverEx function\n"));
return (*pPrintHandle->pProvidor->PrintProvidor.fpGetPrinterDriverEx)
(pPrintHandle->hPrinter, pEnvironment,
Level, pDriverInfo, cbBuf, pcbNeeded,
dwClientMajorVersion, dwClientMinorVersion,
pdwServerMajorVersion, pdwServerMinorVersion);
} else {
//
// The print providor does not support versioning of drivers
//
DBGMSG(DBG_TRACE, ("Calling the fpGetPrinterDriver function\n"));
*pdwServerMajorVersion = 0;
*pdwServerMinorVersion = 0;
return (*pPrintHandle->pProvidor->PrintProvidor.fpGetPrinterDriver)
(pPrintHandle->hPrinter, pEnvironment,
Level, pDriverInfo, cbBuf, pcbNeeded);
}
}
BOOL
GetPrinterDriverW(
HANDLE hPrinter,
LPWSTR pEnvironment,
DWORD Level,
LPBYTE pDriverInfo,
DWORD cbBuf,
LPDWORD pcbNeeded
)
{
DWORD dwServerMajorVersion;
DWORD dwServerMinorVersion;
return GetPrinterDriverExW( hPrinter,
pEnvironment,
Level,
pDriverInfo,
cbBuf,
pcbNeeded,
(DWORD)-1,
(DWORD)-1,
&dwServerMajorVersion,
&dwServerMinorVersion );
}