mirror of https://github.com/lianthony/NT4.0
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
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 );
|
|
}
|