Author: cfinck
Date: Tue Jul 7 17:06:48 2015
New Revision: 68375
URL:
http://svn.reactos.org/svn/reactos?rev=68375&view=rev
Log:
[LOCALSPL]
- Initialize all Print Monitors on startup and keep a list of them.
- Implement LocalEnumMonitors and LocalEnumPorts.
- Check the result of the initialization functions.
[SPOOLSS]
- Implement support for multiple Print Providers.
Initialize them on startup and keep a list here as well.
- Implement all functions that had simple stubs in the C code. This still needs to be done
for the remaining functions stubbed in the .spec file.
But generally spoken, this always boils down to 3 cases:
* Forward the call to the Local Spooler (for general functions like
GetPrintProcessorDirectory).
* Forward the call to the Print Provider we used for OpenPrinter (for functions like
SetJob).
* Forward the call to all Print Providers and collect the results (for functions like
EnumPrinters).
Added:
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/monitors.c
(with props)
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/monitors.c
(with props)
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/ports.c
(with props)
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/CMakeLists.txt
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/jobs.c
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/main.c
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/memory.c
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/ports.c
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/precomp.h
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/printers.c
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/printprocessors.c
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/spoolss.spec
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/CMakeLists.txt
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/jobs.c
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/main.c
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/precomp.h
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/printers.c
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/printprocessors.c
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/CMakeLists.txt [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/CMakeLists.txt [iso-8859-1]
Tue Jul 7 17:06:48 2015
@@ -6,6 +6,7 @@
jobs.c
main.c
memory.c
+ monitors.c
ports.c
precomp.h
printers.c
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/jobs.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/jobs.c [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/jobs.c [iso-8859-1]
Tue Jul 7 17:06:48 2015
@@ -8,31 +8,76 @@
#include "precomp.h"
BOOL WINAPI
-AddJobW(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcbNeeded)
+AddJobW(HANDLE hPrinter, DWORD Level, PBYTE pData, DWORD cbBuf, PDWORD pcbNeeded)
{
- return LocalSplFuncs.fpAddJob(hPrinter, Level, pData, cbBuf, pcbNeeded);
+ PSPOOLSS_PRINTER_HANDLE pHandle = (PSPOOLSS_PRINTER_HANDLE)hPrinter;
+
+ // Sanity checks.
+ if (!pHandle)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ return pHandle->pPrintProvider->PrintProvider.fpAddJob(pHandle->hPrinter,
Level, pData, cbBuf, pcbNeeded);
}
BOOL WINAPI
EnumJobsW(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, PBYTE pJob, DWORD
cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
{
- return LocalSplFuncs.fpEnumJobs(hPrinter, FirstJob, NoJobs, Level, pJob, cbBuf,
pcbNeeded, pcReturned);
+ PSPOOLSS_PRINTER_HANDLE pHandle = (PSPOOLSS_PRINTER_HANDLE)hPrinter;
+
+ // Sanity checks.
+ if (!pHandle)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ return pHandle->pPrintProvider->PrintProvider.fpEnumJobs(pHandle->hPrinter,
FirstJob, NoJobs, Level, pJob, cbBuf, pcbNeeded, pcReturned);
}
BOOL WINAPI
-GetJobW(HANDLE hPrinter, DWORD JobId, DWORD Level, LPBYTE pJob, DWORD cbBuf, LPDWORD
pcbNeeded)
+GetJobW(HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pJob, DWORD cbBuf, PDWORD
pcbNeeded)
{
- return LocalSplFuncs.fpGetJob(hPrinter, JobId, Level, pJob, cbBuf, pcbNeeded);
+ PSPOOLSS_PRINTER_HANDLE pHandle = (PSPOOLSS_PRINTER_HANDLE)hPrinter;
+
+ // Sanity checks.
+ if (!pHandle)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ return pHandle->pPrintProvider->PrintProvider.fpGetJob(pHandle->hPrinter,
JobId, Level, pJob, cbBuf, pcbNeeded);
}
BOOL WINAPI
ScheduleJob(HANDLE hPrinter, DWORD dwJobID)
{
- return LocalSplFuncs.fpScheduleJob(hPrinter, dwJobID);
+ PSPOOLSS_PRINTER_HANDLE pHandle = (PSPOOLSS_PRINTER_HANDLE)hPrinter;
+
+ // Sanity checks.
+ if (!pHandle)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ return
pHandle->pPrintProvider->PrintProvider.fpScheduleJob(pHandle->hPrinter,
dwJobID);
}
BOOL WINAPI
SetJobW(HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pJobInfo, DWORD Command)
{
- return LocalSplFuncs.fpSetJob(hPrinter, JobId, Level, pJobInfo, Command);
+ PSPOOLSS_PRINTER_HANDLE pHandle = (PSPOOLSS_PRINTER_HANDLE)hPrinter;
+
+ // Sanity checks.
+ if (!pHandle)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ return pHandle->pPrintProvider->PrintProvider.fpSetJob(pHandle->hPrinter,
JobId, Level, pJobInfo, Command);
}
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/main.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/main.c [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/main.c [iso-8859-1]
Tue Jul 7 17:06:48 2015
@@ -7,9 +7,179 @@
#include "precomp.h"
+// Global Variables
HANDLE hProcessHeap;
-PRINTPROVIDOR LocalSplFuncs;
-
+LIST_ENTRY PrintProviderList;
+
+
+static DWORD
+_AddPrintProviderToList(PCWSTR pwszFileName)
+{
+ DWORD dwErrorCode;
+ HINSTANCE hinstPrintProvider;
+ PInitializePrintProvidor pfnInitializePrintProvidor;
+ PSPOOLSS_PRINT_PROVIDER pPrintProvider = NULL;
+
+ // Try to load it.
+ hinstPrintProvider = LoadLibraryW(pwszFileName);
+ if (!hinstPrintProvider)
+ {
+ dwErrorCode = GetLastError();
+ ERR("LoadLibraryW failed for \"%S\" with error %lu!\n",
pwszFileName, dwErrorCode);
+ goto Cleanup;
+ }
+
+ // Get the initialization routine.
+ pfnInitializePrintProvidor =
(PInitializePrintProvidor)GetProcAddress(hinstPrintProvider,
"InitializePrintProvidor");
+ if (!pfnInitializePrintProvidor)
+ {
+ dwErrorCode = GetLastError();
+ ERR("GetProcAddress failed for \"%S\" with error %lu!\n",
pwszFileName, dwErrorCode);
+ goto Cleanup;
+ }
+
+ // Create a new SPOOLSS_PRINT_PROVIDER structure for it.
+ pPrintProvider = DllAllocSplMem(sizeof(SPOOLSS_PRINT_PROVIDER));
+ if (!pPrintProvider)
+ {
+ dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
+ goto Cleanup;
+ }
+
+ // Call the Print Provider initialization function.
+ if (!pfnInitializePrintProvidor(&pPrintProvider->PrintProvider,
sizeof(PRINTPROVIDOR), NULL))
+ {
+ dwErrorCode = GetLastError();
+ ERR("InitializePrintProvidor failed for \"%S\" with error
%lu!\n", pwszFileName, dwErrorCode);
+ goto Cleanup;
+ }
+
+ // Add this Print Provider to the list.
+ InsertTailList(&PrintProviderList, &pPrintProvider->Entry);
+
+ // Don't let the cleanup routine free this.
+ pPrintProvider = NULL;
+ dwErrorCode = ERROR_SUCCESS;
+
+Cleanup:
+ if (pPrintProvider)
+ DllFreeSplMem(pPrintProvider);
+
+ return dwErrorCode;
+}
+
+static BOOL
+_InitializePrintProviderList()
+{
+ DWORD cbFileName;
+ DWORD cchMaxSubKey;
+ DWORD cchPrintProviderName;
+ DWORD dwErrorCode;
+ DWORD dwSubKeys;
+ DWORD i;
+ HKEY hKey = NULL;
+ HKEY hSubKey = NULL;
+ PWSTR pwszPrintProviderName = NULL;
+ WCHAR wszFileName[MAX_PATH];
+
+ // Initialize an empty list for our Print Providers.
+ InitializeListHead(&PrintProviderList);
+
+ // First add the Local Spooler.
+ // This one must exist and must be the first one in the list.
+ dwErrorCode = _AddPrintProviderToList(L"localspl");
+ if (dwErrorCode != ERROR_SUCCESS)
+ {
+ ERR("The Local Spooler could not be loaded!\n");
+ goto Cleanup;
+ }
+
+ // Now add additional Print Providers from the registry.
+ // First of all, open the key containing print providers.
+ dwErrorCode = (DWORD)RegOpenKeyExW(HKEY_LOCAL_MACHINE,
L"SYSTEM\\CurrentControlSet\\Control\\Print\\Providers", 0, KEY_READ,
&hKey);
+ if (dwErrorCode != ERROR_SUCCESS)
+ {
+ ERR("RegOpenKeyExW failed with status %lu!\n", dwErrorCode);
+ goto Cleanup;
+ }
+
+ // Get the number of Print Providers and maximum sub key length.
+ dwErrorCode = (DWORD)RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &dwSubKeys,
&cchMaxSubKey, NULL, NULL, NULL, NULL, NULL, NULL);
+ if (dwErrorCode != ERROR_SUCCESS)
+ {
+ ERR("RegQueryInfoKeyW failed with status %lu!\n", dwErrorCode);
+ goto Cleanup;
+ }
+
+ // Allocate a temporary buffer for the Print Provider names.
+ pwszPrintProviderName = DllAllocSplMem((cchMaxSubKey + 1) * sizeof(WCHAR));
+ if (!pwszPrintProviderName)
+ {
+ dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
+ goto Cleanup;
+ }
+
+ // Loop through all available Print Providers.
+ for (i = 0; i < dwSubKeys; i++)
+ {
+ // Cleanup tasks from the previous run
+ if (hSubKey)
+ {
+ RegCloseKey(hSubKey);
+ hSubKey = NULL;
+ }
+
+ // Get the name of this Print Provider.
+ cchPrintProviderName = cchMaxSubKey + 1;
+ dwErrorCode = (DWORD)RegEnumKeyExW(hKey, i, pwszPrintProviderName,
&cchPrintProviderName, NULL, NULL, NULL, NULL);
+ if (dwErrorCode != ERROR_SUCCESS)
+ {
+ ERR("RegEnumKeyExW failed for iteration %lu with status %lu!\n", i,
dwErrorCode);
+ continue;
+ }
+
+ // Open this Print Provider's registry key.
+ dwErrorCode = (DWORD)RegOpenKeyExW(hKey, pwszPrintProviderName, 0, KEY_READ,
&hSubKey);
+ if (dwErrorCode != ERROR_SUCCESS)
+ {
+ ERR("RegOpenKeyExW failed for Print Provider \"%S\" with
status %lu!\n", pwszPrintProviderName, dwErrorCode);
+ continue;
+ }
+
+ // Get the file name of the Print Provider.
+ cbFileName = MAX_PATH * sizeof(WCHAR);
+ dwErrorCode = (DWORD)RegQueryValueExW(hKey, L"Driver", NULL, NULL,
(PBYTE)wszFileName, &cbFileName);
+ if (dwErrorCode != ERROR_SUCCESS)
+ {
+ ERR("RegQueryValueExW failed with status %lu!\n", dwErrorCode);
+ continue;
+ }
+
+ // Load and add it to the list.
+ dwErrorCode = _AddPrintProviderToList(wszFileName);
+ if (dwErrorCode != ERROR_SUCCESS)
+ continue;
+ }
+
+ dwErrorCode = ERROR_SUCCESS;
+
+Cleanup:
+ // Inside the loop
+ if (hSubKey)
+ RegCloseKey(hSubKey);
+
+ // Outside the loop
+ if (pwszPrintProviderName)
+ DllFreeSplMem(pwszPrintProviderName);
+
+ if (hKey)
+ RegCloseKey(hKey);
+
+ SetLastError(dwErrorCode);
+ return (dwErrorCode == ERROR_SUCCESS);
+}
BOOL WINAPI
DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
@@ -18,7 +188,7 @@
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hinstDLL);
- hProcessHeap = GetProcessHeap();
+ hProcessHeap = GetProcessHeap();
break;
}
@@ -28,32 +198,7 @@
BOOL WINAPI
InitializeRouter(HANDLE SpoolerStatusHandle)
{
- HINSTANCE hinstLocalSpl;
- PInitializePrintProvidor pfnInitializePrintProvidor;
-
- // Only initialize localspl.dll for now.
- // This function should later look for all available print providers in the registry
and initialize all of them.
- hinstLocalSpl = LoadLibraryW(L"localspl");
- if (!hinstLocalSpl)
- {
- ERR("LoadLibraryW for localspl failed with error %lu!\n",
GetLastError());
- return FALSE;
- }
-
- pfnInitializePrintProvidor = (PInitializePrintProvidor)GetProcAddress(hinstLocalSpl,
"InitializePrintProvidor");
- if (!pfnInitializePrintProvidor)
- {
- ERR("GetProcAddress failed with error %lu!\n", GetLastError());
- return FALSE;
- }
-
- if (!pfnInitializePrintProvidor(&LocalSplFuncs, sizeof(PRINTPROVIDOR), NULL))
- {
- ERR("InitializePrintProvidor failed for localspl with error %lu!\n",
GetLastError());
- return FALSE;
- }
-
- return TRUE;
+ return _InitializePrintProviderList();
}
BOOL WINAPI
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/memory.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/memory.c [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/memory.c [iso-8859-1]
Tue Jul 7 17:06:48 2015
@@ -9,17 +9,17 @@
/**
-* @name AllocSplStr
-*
-* Allocates memory for a Unicode string and copies the input string into it.
-* Equivalent of wcsdup, but the returned buffer is allocated from the spooler heap and
must be freed with DllFreeSplStr.
-*
-* @param pwszInput
-* The input string to copy
-*
-* @return
-* Pointer to the copied string or NULL if no memory could be allocated.
-*/
+ * @name AllocSplStr
+ *
+ * Allocates memory for a Unicode string and copies the input string into it.
+ * Equivalent of wcsdup, but the returned buffer is allocated from the spooler heap and
must be freed with DllFreeSplStr.
+ *
+ * @param pwszInput
+ * The input string to copy
+ *
+ * @return
+ * Pointer to the copied string or NULL if no memory could be allocated.
+ */
PWSTR WINAPI
AllocSplStr(PCWSTR pwszInput)
{
Added:
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/monitors.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/monitors.c (added)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/monitors.c [iso-8859-1]
Tue Jul 7 17:06:48 2015
@@ -0,0 +1,68 @@
+/*
+ * PROJECT: ReactOS Spooler Router
+ * LICENSE: GNU LGPL v2.1 or any later version as published by the Free Software
Foundation
+ * PURPOSE: Functions related to Print Monitors
+ * COPYRIGHT: Copyright 2015 Colin Finck <colin(a)reactos.org>
+ */
+
+#include "precomp.h"
+
+BOOL WINAPI
+EnumMonitorsW(PWSTR pName, DWORD Level, PBYTE pMonitors, DWORD cbBuf, PDWORD pcbNeeded,
PDWORD pcReturned)
+{
+ BOOL bReturnValue;
+ DWORD cbCallBuffer;
+ DWORD cbNeeded;
+ DWORD dwReturned;
+ PBYTE pCallBuffer;
+ PSPOOLSS_PRINT_PROVIDER pPrintProvider;
+ PLIST_ENTRY pEntry;
+
+ // Sanity checks.
+ if ((cbBuf && !pMonitors) || !pcbNeeded || !pcReturned)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ // Begin counting.
+ *pcbNeeded = 0;
+ *pcReturned = 0;
+
+ // At the beginning, we have the full buffer available.
+ cbCallBuffer = cbBuf;
+ pCallBuffer = pMonitors;
+
+ // Loop through all Print Provider.
+ for (pEntry = PrintProviderList.Flink; pEntry != &PrintProviderList; pEntry =
pEntry->Flink)
+ {
+ pPrintProvider = CONTAINING_RECORD(pEntry, SPOOLSS_PRINT_PROVIDER, Entry);
+
+ // Check if this Print Provider provides an EnumMonitors function.
+ if (!pPrintProvider->PrintProvider.fpEnumMonitors)
+ continue;
+
+ // Call the EnumMonitors function of this Print Provider.
+ bReturnValue = pPrintProvider->PrintProvider.fpEnumMonitors(pName, Level,
pCallBuffer, cbCallBuffer, &cbNeeded, &dwReturned);
+
+ // Add the returned counts to the total values.
+ *pcbNeeded += cbNeeded;
+ *pcReturned += dwReturned;
+
+ // Reduce the available buffer size for the next call without risking an
underflow.
+ if (cbNeeded < cbCallBuffer)
+ cbCallBuffer -= cbNeeded;
+ else
+ cbCallBuffer = 0;
+
+ // Advance the buffer if the caller provided it.
+ if (pCallBuffer)
+ pCallBuffer += cbNeeded;
+
+ // Check if we shall not ask other Print Providers.
+ if (bReturnValue == ROUTER_STOP_ROUTING)
+ break;
+ }
+
+ return bReturnValue;
+}
Propchange:
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/monitors.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/ports.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/ports.c [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/ports.c [iso-8859-1]
Tue Jul 7 17:06:48 2015
@@ -1,7 +1,7 @@
/*
* PROJECT: ReactOS Spooler Router
* LICENSE: GNU LGPL v2.1 or any later version as published by the Free Software
Foundation
- * PURPOSE: Functions related to ports
+ * PURPOSE: Functions related to Ports of the Print Monitors
* COPYRIGHT: Copyright 2015 Colin Finck <colin(a)reactos.org>
*/
@@ -10,5 +10,55 @@
BOOL WINAPI
EnumPortsW(PWSTR pName, DWORD Level, PBYTE pPorts, DWORD cbBuf, PDWORD pcbNeeded, PDWORD
pcReturned)
{
- return FALSE;
+ BOOL bReturnValue;
+ DWORD cbCallBuffer;
+ DWORD cbNeeded;
+ DWORD dwReturned;
+ PBYTE pCallBuffer;
+ PSPOOLSS_PRINT_PROVIDER pPrintProvider;
+ PLIST_ENTRY pEntry;
+
+ // Sanity checks.
+ if ((cbBuf && !pPorts) || !pcbNeeded || !pcReturned)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ // Begin counting.
+ *pcbNeeded = 0;
+ *pcReturned = 0;
+
+ // At the beginning, we have the full buffer available.
+ cbCallBuffer = cbBuf;
+ pCallBuffer = pPorts;
+
+ // Loop through all Print Provider.
+ for (pEntry = PrintProviderList.Flink; pEntry != &PrintProviderList; pEntry =
pEntry->Flink)
+ {
+ pPrintProvider = CONTAINING_RECORD(pEntry, SPOOLSS_PRINT_PROVIDER, Entry);
+
+ // Call the EnumPorts function of this Print Provider.
+ bReturnValue = pPrintProvider->PrintProvider.fpEnumPorts(pName, Level,
pCallBuffer, cbCallBuffer, &cbNeeded, &dwReturned);
+
+ // Add the returned counts to the total values.
+ *pcbNeeded += cbNeeded;
+ *pcReturned += dwReturned;
+
+ // Reduce the available buffer size for the next call without risking an
underflow.
+ if (cbNeeded < cbCallBuffer)
+ cbCallBuffer -= cbNeeded;
+ else
+ cbCallBuffer = 0;
+
+ // Advance the buffer if the caller provided it.
+ if (pCallBuffer)
+ pCallBuffer += cbNeeded;
+
+ // Check if we shall not ask other Print Providers.
+ if (bReturnValue == ROUTER_STOP_ROUTING)
+ break;
+ }
+
+ return bReturnValue;
}
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/precomp.h
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/precomp.h [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/precomp.h [iso-8859-1]
Tue Jul 7 17:06:48 2015
@@ -15,17 +15,40 @@
#include <winreg.h>
#include <winspool.h>
#include <winsplp.h>
+#include <ndk/rtlfuncs.h>
#include <spoolss.h>
#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(spoolss);
-// Function pointer to InitializePrintProvidor of a provider DLL
+// Function pointers
typedef BOOL (WINAPI *PInitializePrintProvidor)(LPPRINTPROVIDOR, DWORD, LPWSTR);
+
+// Structures
+/**
+ * Describes a Print Provider.
+ */
+typedef struct _SPOOLSS_PRINT_PROVIDER
+{
+ LIST_ENTRY Entry;
+ PRINTPROVIDOR PrintProvider;
+}
+SPOOLSS_PRINT_PROVIDER, *PSPOOLSS_PRINT_PROVIDER;
+
+/*
+ * Describes a handle returned by OpenPrinterW.
+ * We can't just pass the handle returned by the Print Provider, because spoolss has
to remember which Print Provider opened this handle.
+ */
+typedef struct _SPOOLSS_PRINTER_HANDLE
+{
+ PSPOOLSS_PRINT_PROVIDER pPrintProvider; /** Pointer to the Print Provider
that opened this printer. */
+ HANDLE hPrinter; /** The handle returned by
fpOpenPrinter of the Print Provider and passed to subsequent Print Provider functions. */
+}
+SPOOLSS_PRINTER_HANDLE, *PSPOOLSS_PRINTER_HANDLE;
// main.c
extern HANDLE hProcessHeap;
-extern PRINTPROVIDOR LocalSplFuncs;
+extern LIST_ENTRY PrintProviderList;
#endif
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/printers.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/printers.c [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/printers.c [iso-8859-1]
Tue Jul 7 17:06:48 2015
@@ -11,71 +11,262 @@
BOOL WINAPI
ClosePrinter(HANDLE hPrinter)
{
+ BOOL bReturnValue;
+ PSPOOLSS_PRINTER_HANDLE pHandle = (PSPOOLSS_PRINTER_HANDLE)hPrinter;
+
+ // Sanity checks.
+ if (!pHandle)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ // FIXME: Call FindClosePrinterChangeNotification for all created change
notifications (according to MSDN).
+
+ // Call CloseHandle of the Print Provider.
+ bReturnValue =
pHandle->pPrintProvider->PrintProvider.fpClosePrinter(pHandle->hPrinter);
+
+ // Free our handle information.
+ DllFreeSplMem(pHandle);
+
+ return bReturnValue;
+}
+
+BOOL WINAPI
+EndDocPrinter(HANDLE hPrinter)
+{
+ PSPOOLSS_PRINTER_HANDLE pHandle = (PSPOOLSS_PRINTER_HANDLE)hPrinter;
+
+ // Sanity checks.
+ if (!pHandle)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ return
pHandle->pPrintProvider->PrintProvider.fpEndDocPrinter(pHandle->hPrinter);
+}
+
+BOOL WINAPI
+EndPagePrinter(HANDLE hPrinter)
+{
+ PSPOOLSS_PRINTER_HANDLE pHandle = (PSPOOLSS_PRINTER_HANDLE)hPrinter;
+
+ // Sanity checks.
+ if (!pHandle)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ return
pHandle->pPrintProvider->PrintProvider.fpEndPagePrinter(pHandle->hPrinter);
+}
+
+BOOL WINAPI
+EnumPrintersW(DWORD Flags, PWSTR Name, DWORD Level, PBYTE pPrinterEnum, DWORD cbBuf,
PDWORD pcbNeeded, PDWORD pcReturned)
+{
+ BOOL bReturnValue;
+ DWORD cbCallBuffer;
+ DWORD cbNeeded;
+ DWORD dwReturned;
+ PBYTE pCallBuffer;
+ PSPOOLSS_PRINT_PROVIDER pPrintProvider;
+ PLIST_ENTRY pEntry;
+
+ // Sanity checks.
+ if ((cbBuf && !pPrinterEnum) || !pcbNeeded || !pcReturned)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ // Begin counting.
+ *pcbNeeded = 0;
+ *pcReturned = 0;
+
+ // At the beginning, we have the full buffer available.
+ cbCallBuffer = cbBuf;
+ pCallBuffer = pPrinterEnum;
+
+ // Loop through all Print Provider.
+ for (pEntry = PrintProviderList.Flink; pEntry != &PrintProviderList; pEntry =
pEntry->Flink)
+ {
+ pPrintProvider = CONTAINING_RECORD(pEntry, SPOOLSS_PRINT_PROVIDER, Entry);
+
+ // Call the EnumPrinters function of this Print Provider.
+ bReturnValue = pPrintProvider->PrintProvider.fpEnumPrinters(Flags, Name,
Level, pCallBuffer, cbCallBuffer, &cbNeeded, &dwReturned);
+
+ // Add the returned counts to the total values.
+ *pcbNeeded += cbNeeded;
+ *pcReturned += dwReturned;
+
+ // Reduce the available buffer size for the next call without risking an
underflow.
+ if (cbNeeded < cbCallBuffer)
+ cbCallBuffer -= cbNeeded;
+ else
+ cbCallBuffer = 0;
+
+ // Advance the buffer if the caller provided it.
+ if (pCallBuffer)
+ pCallBuffer += cbNeeded;
+ }
+
+ return bReturnValue;
+}
+
+BOOL WINAPI
+GetPrinterDriverW(HANDLE hPrinter, PWSTR pEnvironment, DWORD Level, PBYTE pDriverInfo,
DWORD cbBuf, PDWORD pcbNeeded)
+{
+ PSPOOLSS_PRINTER_HANDLE pHandle = (PSPOOLSS_PRINTER_HANDLE)hPrinter;
+
+ // Sanity checks.
+ if (!pHandle)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ return
pHandle->pPrintProvider->PrintProvider.fpGetPrinterDriver(pHandle->hPrinter,
pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded);
+}
+
+BOOL WINAPI
+GetPrinterW(HANDLE hPrinter, DWORD Level, PBYTE pPrinter, DWORD cbBuf, PDWORD pcbNeeded)
+{
+ PSPOOLSS_PRINTER_HANDLE pHandle = (PSPOOLSS_PRINTER_HANDLE)hPrinter;
+
+ // Sanity checks.
+ if (!pHandle)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ return
pHandle->pPrintProvider->PrintProvider.fpGetPrinter(pHandle->hPrinter, Level,
pPrinter, cbBuf, pcbNeeded);
+}
+
+BOOL WINAPI
+OpenPrinterW(PWSTR pPrinterName, PHANDLE phPrinter, PPRINTER_DEFAULTSW pDefault)
+{
+ BOOL bReturnValue;
+ HANDLE hPrinter;
+ PLIST_ENTRY pEntry;
+ PSPOOLSS_PRINTER_HANDLE pHandle;
+ PSPOOLSS_PRINT_PROVIDER pPrintProvider;
+
+ // Sanity checks.
+ if (!pPrinterName || !phPrinter)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ // Loop through all Print Providers to find one able to open this Printer.
+ for (pEntry = PrintProviderList.Flink; pEntry != &PrintProviderList; pEntry =
pEntry->Flink)
+ {
+ pPrintProvider = CONTAINING_RECORD(pEntry, SPOOLSS_PRINT_PROVIDER, Entry);
+
+ bReturnValue = pPrintProvider->PrintProvider.fpOpenPrinter(pPrinterName,
&hPrinter, pDefault);
+ if (bReturnValue == ROUTER_SUCCESS)
+ {
+ // This Print Provider has opened this Printer.
+ // Store this information and return a handle.
+ pHandle = DllAllocSplMem(sizeof(SPOOLSS_PRINTER_HANDLE));
+ if (!pHandle)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ ERR("DllAllocSplMem failed with error %lu!\n",
GetLastError());
+ return FALSE;
+ }
+
+ pHandle->pPrintProvider = pPrintProvider;
+ pHandle->hPrinter = hPrinter;
+ *phPrinter = (HANDLE)pHandle;
+
+ SetLastError(ERROR_SUCCESS);
+ return TRUE;
+ }
+ else if (bReturnValue == ROUTER_STOP_ROUTING)
+ {
+ ERR("A Print Provider returned ROUTER_STOP_ROUTING for Printer
\"%S\"!\n", pPrinterName);
+ return FALSE;
+ }
+ }
+
+ // We found no Print Provider able to open this Printer.
return FALSE;
}
BOOL WINAPI
-EndDocPrinter(HANDLE hPrinter)
-{
- return FALSE;
-}
-
-BOOL WINAPI
-EndPagePrinter(HANDLE hPrinter)
-{
- return FALSE;
-}
-
-BOOL WINAPI
-EnumPrintersW(DWORD Flags, LPWSTR Name, DWORD Level, LPBYTE pPrinterEnum, DWORD cbBuf,
LPDWORD pcbNeeded, LPDWORD pcReturned)
-{
- return LocalSplFuncs.fpEnumPrinters(Flags, Name, Level, pPrinterEnum, cbBuf,
pcbNeeded, pcReturned);
-}
-
-BOOL WINAPI
-GetPrinterDriverW(HANDLE hPrinter, LPWSTR pEnvironment, DWORD Level, LPBYTE pDriverInfo,
DWORD cbBuf, LPDWORD pcbNeeded)
-{
- return FALSE;
-}
-
-BOOL WINAPI
-GetPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, DWORD cbBuf, LPDWORD
pcbNeeded)
-{
- return FALSE;
-}
-
-BOOL WINAPI
-OpenPrinterW(LPWSTR pPrinterName, LPHANDLE phPrinter, LPPRINTER_DEFAULTSW pDefault)
-{
- return LocalSplFuncs.fpOpenPrinter(pPrinterName, phPrinter, pDefault);
-}
-
-BOOL WINAPI
ReadPrinter(HANDLE hPrinter, PVOID pBuf, DWORD cbBuf, PDWORD pNoBytesRead)
{
- return FALSE;
+ PSPOOLSS_PRINTER_HANDLE pHandle = (PSPOOLSS_PRINTER_HANDLE)hPrinter;
+
+ // Sanity checks.
+ if (!pHandle)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ return
pHandle->pPrintProvider->PrintProvider.fpReadPrinter(pHandle->hPrinter, pBuf,
cbBuf, pNoBytesRead);
}
DWORD WINAPI
-StartDocPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo)
-{
- return 0;
+StartDocPrinterW(HANDLE hPrinter, DWORD Level, PBYTE pDocInfo)
+{
+ PSPOOLSS_PRINTER_HANDLE pHandle = (PSPOOLSS_PRINTER_HANDLE)hPrinter;
+
+ // Sanity checks.
+ if (!pHandle)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ return
pHandle->pPrintProvider->PrintProvider.fpStartDocPrinter(pHandle->hPrinter,
Level, pDocInfo);
}
BOOL WINAPI
StartPagePrinter(HANDLE hPrinter)
{
- return FALSE;
-}
-
-BOOL WINAPI
-WritePrinter(HANDLE hPrinter, LPVOID pBuf, DWORD cbBuf, LPDWORD pcWritten)
-{
- return FALSE;
+ PSPOOLSS_PRINTER_HANDLE pHandle = (PSPOOLSS_PRINTER_HANDLE)hPrinter;
+
+ // Sanity checks.
+ if (!pHandle)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ return
pHandle->pPrintProvider->PrintProvider.fpStartPagePrinter(pHandle->hPrinter);
+}
+
+BOOL WINAPI
+WritePrinter(HANDLE hPrinter, PVOID pBuf, DWORD cbBuf, PDWORD pcWritten)
+{
+ PSPOOLSS_PRINTER_HANDLE pHandle = (PSPOOLSS_PRINTER_HANDLE)hPrinter;
+
+ // Sanity checks.
+ if (!pHandle)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ return
pHandle->pPrintProvider->PrintProvider.fpWritePrinter(pHandle->hPrinter, pBuf,
cbBuf, pcWritten);
}
BOOL WINAPI
XcvDataW(HANDLE hXcv, PCWSTR pszDataName, PBYTE pInputData, DWORD cbInputData, PBYTE
pOutputData, DWORD cbOutputData, PDWORD pcbOutputNeeded, PDWORD pdwStatus)
{
- return FALSE;
-}
+ PSPOOLSS_PRINTER_HANDLE pHandle = (PSPOOLSS_PRINTER_HANDLE)hXcv;
+
+ // Sanity checks.
+ if (!pHandle)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ return pHandle->pPrintProvider->PrintProvider.fpXcvData(pHandle->hPrinter,
pszDataName, pInputData, cbInputData, pOutputData, cbOutputData, pcbOutputNeeded,
pdwStatus);
+}
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/printprocessors.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/printprocessors.c [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/printprocessors.c [iso-8859-1]
Tue Jul 7 17:06:48 2015
@@ -8,19 +8,25 @@
#include "precomp.h"
BOOL WINAPI
-EnumPrintProcessorDatatypesW(LPWSTR pName, LPWSTR pPrintProcessorName, DWORD Level,
LPBYTE pDatatypes, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
+EnumPrintProcessorDatatypesW(PWSTR pName, PWSTR pPrintProcessorName, DWORD Level, PBYTE
pDatatypes, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
{
- return LocalSplFuncs.fpEnumPrintProcessorDatatypes(pName, pPrintProcessorName, Level,
pDatatypes, cbBuf, pcbNeeded, pcReturned);
+ // Always call this function on the Local Spooler.
+ PSPOOLSS_PRINT_PROVIDER pPrintProvider =
CONTAINING_RECORD(&PrintProviderList.Flink, SPOOLSS_PRINT_PROVIDER, Entry);
+ return pPrintProvider->PrintProvider.fpEnumPrintProcessorDatatypes(pName,
pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned);
}
BOOL WINAPI
-EnumPrintProcessorsW(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE
pPrintProcessorInfo, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
+EnumPrintProcessorsW(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE
pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
{
- return LocalSplFuncs.fpEnumPrintProcessors(pName, pEnvironment, Level,
pPrintProcessorInfo, cbBuf, pcbNeeded, pcReturned);
+ // Always call this function on the Local Spooler.
+ PSPOOLSS_PRINT_PROVIDER pPrintProvider =
CONTAINING_RECORD(&PrintProviderList.Flink, SPOOLSS_PRINT_PROVIDER, Entry);
+ return pPrintProvider->PrintProvider.fpEnumPrintProcessors(pName, pEnvironment,
Level, pPrintProcessorInfo, cbBuf, pcbNeeded, pcReturned);
}
BOOL WINAPI
-GetPrintProcessorDirectoryW(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE
pPrintProcessorInfo, DWORD cbBuf, LPDWORD pcbNeeded)
+GetPrintProcessorDirectoryW(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE
pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded)
{
- return LocalSplFuncs.fpGetPrintProcessorDirectory(pName, pEnvironment, Level,
pPrintProcessorInfo, cbBuf, pcbNeeded);
+ // Always call this function on the Local Spooler.
+ PSPOOLSS_PRINT_PROVIDER pPrintProvider =
CONTAINING_RECORD(&PrintProviderList.Flink, SPOOLSS_PRINT_PROVIDER, Entry);
+ return pPrintProvider->PrintProvider.fpGetPrintProcessorDirectory(pName,
pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded);
}
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/spoolss.spec
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/spoolss.spec [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/base/spoolss/spoolss.spec [iso-8859-1]
Tue Jul 7 17:06:48 2015
@@ -60,16 +60,16 @@
@ stdcall EndPagePrinter(long)
@ stub EnumFormsW
@ stdcall EnumJobsW(long long long long ptr long ptr ptr)
-@ stub EnumMonitorsW
+@ stdcall EnumMonitorsW(wstr long ptr long ptr ptr)
@ stub EnumPerMachineConnectionsW
-@ stdcall EnumPortsW(ptr long ptr long ptr ptr)
+@ stdcall EnumPortsW(wstr long ptr long ptr ptr)
@ stub EnumPrinterDataExW
@ stub EnumPrinterDataW
@ stub EnumPrinterDriversW
@ stub EnumPrinterKeyW
-@ stdcall EnumPrintersW(long ptr long ptr long ptr ptr)
-@ stdcall EnumPrintProcessorDatatypesW(ptr ptr long ptr long ptr ptr)
-@ stdcall EnumPrintProcessorsW(ptr ptr long ptr long ptr ptr)
+@ stdcall EnumPrintersW(long wstr long ptr long ptr ptr)
+@ stdcall EnumPrintProcessorDatatypesW(wstr wstr long ptr long ptr ptr)
+@ stdcall EnumPrintProcessorsW(wstr wstr long ptr long ptr ptr)
@ stub FindClosePrinterChangeNotification
@ stub FlushPrinter
@ stub FormatPrinterForRegistryKey
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/CMakeLists.txt [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/CMakeLists.txt [iso-8859-1]
Tue Jul 7 17:06:48 2015
@@ -6,6 +6,8 @@
list(APPEND SOURCE
jobs.c
main.c
+ monitors.c
+ ports.c
precomp.h
printers.c
printprocessors.c
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/jobs.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/jobs.c [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/jobs.c [iso-8859-1]
Tue Jul 7 17:06:48 2015
@@ -102,7 +102,7 @@
return TRUE;
}
-void
+BOOL
InitializeGlobalJobList()
{
const WCHAR wszPath[] = L"\\PRINTERS\\?????.SHD";
@@ -110,6 +110,7 @@
const DWORD cchFolders = sizeof("\\PRINTERS\\") - 1;
const DWORD cchPattern = sizeof("?????") - 1;
+ DWORD dwErrorCode;
DWORD dwJobID;
HANDLE hFind;
PLOCAL_JOB pJob = NULL;
@@ -133,6 +134,7 @@
if (hFind == INVALID_HANDLE_VALUE)
{
// No unfinished jobs found.
+ dwErrorCode = ERROR_SUCCESS;
goto Cleanup;
}
@@ -159,6 +161,7 @@
// Add it to the Global Job List.
if (!InsertElementSkiplist(&GlobalJobList, pJob))
{
+ dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
ERR("InsertElementSkiplist failed for job %lu for the
GlobalJobList!\n", pJob->dwJobID);
goto Cleanup;
}
@@ -166,16 +169,22 @@
// Add it to the Printer's Job List.
if (!InsertElementSkiplist(&pJob->pPrinter->JobList, pJob))
{
+ dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
ERR("InsertElementSkiplist failed for job %lu for the Printer's Job
List!\n", pJob->dwJobID);
goto Cleanup;
}
}
while (FindNextFileW(hFind, &FindData));
+
+ dwErrorCode = ERROR_SUCCESS;
Cleanup:
// Outside the loop
if (hFind)
FindClose(hFind);
+
+ SetLastError(dwErrorCode);
+ return (dwErrorCode == ERROR_SUCCESS);
}
void
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/main.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/main.c [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/main.c [iso-8859-1]
Tue Jul 7 17:06:48 2015
@@ -22,6 +22,8 @@
#else
#error Unsupported architecture
#endif
+
+const DWORD cbCurrentEnvironment = sizeof(wszCurrentEnvironment);
const WCHAR wszDefaultDocumentName[] = L"Local Downlevel Document";
@@ -70,8 +72,8 @@
NULL, // fpGetForm
NULL, // fpSetForm
NULL, // fpEnumForms
- NULL, // fpEnumMonitors
- NULL, // fpEnumPorts
+ LocalEnumMonitors, // fpEnumMonitors
+ LocalEnumPorts, // fpEnumPorts
NULL, // fpAddPort
NULL, // fpConfigurePort
NULL, // fpDeletePort
@@ -142,13 +144,15 @@
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hinstDLL);
_GetSpoolDirectory();
- InitializePrintProcessorList();
- InitializePrinterList();
- InitializeGlobalJobList();
- break;
+
+ return InitializePrintMonitorList() &&
+ InitializePrintProcessorList() &&
+ InitializePrinterList() &&
+ InitializeGlobalJobList();
+
+ default:
+ return TRUE;
}
-
- return TRUE;
}
BOOL WINAPI
Added:
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/monitors.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/monitors.c (added)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/monitors.c [iso-8859-1]
Tue Jul 7 17:06:48 2015
@@ -0,0 +1,314 @@
+/*
+ * PROJECT: ReactOS Local Spooler
+ * LICENSE: GNU LGPL v2.1 or any later version as published by the Free Software
Foundation
+ * PURPOSE: Functions related to Print Monitors
+ * COPYRIGHT: Copyright 2015 Colin Finck <colin(a)reactos.org>
+ */
+
+#include "precomp.h"
+
+// Local Variables
+LIST_ENTRY PrintMonitorList;
+
+BOOL
+InitializePrintMonitorList()
+{
+ const WCHAR wszMonitorsPath[] =
L"SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors";
+ const DWORD cchMonitorsPath = _countof(wszMonitorsPath) - 1;
+
+ DWORD cchMaxSubKey;
+ DWORD cchPrintMonitorName;
+ DWORD dwErrorCode;
+ DWORD dwSubKeys;
+ DWORD i;
+ HINSTANCE hinstPrintMonitor = NULL;
+ HKEY hKey = NULL;
+ HKEY hSubKey = NULL;
+ MONITORINIT MonitorInit;
+ PInitializePrintMonitor pfnInitializePrintMonitor;
+ PInitializePrintMonitor2 pfnInitializePrintMonitor2;
+ PLOCAL_PRINT_MONITOR pPrintMonitor = NULL;
+ PWSTR pwszRegistryPath = NULL;
+
+ // Initialize an empty list for our Print Monitors.
+ InitializeListHead(&PrintMonitorList);
+
+ // Open the key containing Print Monitors.
+ dwErrorCode = (DWORD)RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszMonitorsPath, 0, KEY_READ,
&hKey);
+ if (dwErrorCode != ERROR_SUCCESS)
+ {
+ ERR("RegOpenKeyExW failed with status %lu!\n", dwErrorCode);
+ goto Cleanup;
+ }
+
+ // Get the number of Print Providers and maximum sub key length.
+ dwErrorCode = (DWORD)RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &dwSubKeys,
&cchMaxSubKey, NULL, NULL, NULL, NULL, NULL, NULL);
+ if (dwErrorCode != ERROR_SUCCESS)
+ {
+ ERR("RegQueryInfoKeyW failed with status %lu!\n", dwErrorCode);
+ goto Cleanup;
+ }
+
+ // Loop through all available Print Providers.
+ for (i = 0; i < dwSubKeys; i++)
+ {
+ // Cleanup tasks from the previous run
+ if (hSubKey)
+ {
+ RegCloseKey(hSubKey);
+ hSubKey = NULL;
+ }
+
+ if (pwszRegistryPath)
+ {
+ DllFreeSplMem(pwszRegistryPath);
+ pwszRegistryPath = NULL;
+ }
+
+ if (pPrintMonitor)
+ {
+ if (pPrintMonitor->pwszFileName)
+ DllFreeSplMem(pPrintMonitor->pwszFileName);
+
+ if (pPrintMonitor->pwszName)
+ DllFreeSplMem(pPrintMonitor->pwszName);
+
+ DllFreeSplMem(pPrintMonitor);
+ pPrintMonitor = NULL;
+ }
+
+ // Create a new LOCAL_PRINT_MONITOR structure for it.
+ pPrintMonitor = DllAllocSplMem(sizeof(LOCAL_PRINT_MONITOR));
+ if (!pPrintMonitor)
+ {
+ dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
+ goto Cleanup;
+ }
+
+ // Allocate memory for the Print Monitor Name.
+ pPrintMonitor->pwszName = DllAllocSplMem((cchMaxSubKey + 1) * sizeof(WCHAR));
+ if (!pPrintMonitor->pwszName)
+ {
+ dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
+ goto Cleanup;
+ }
+
+ // Get the name of this Print Monitor.
+ cchPrintMonitorName = cchMaxSubKey + 1;
+ dwErrorCode = (DWORD)RegEnumKeyExW(hKey, i, pPrintMonitor->pwszName,
&cchPrintMonitorName, NULL, NULL, NULL, NULL);
+ if (dwErrorCode != ERROR_SUCCESS)
+ {
+ ERR("RegEnumKeyExW failed for iteration %lu with status %lu!\n", i,
dwErrorCode);
+ continue;
+ }
+
+ // Open this Print Monitor's registry key.
+ dwErrorCode = (DWORD)RegOpenKeyExW(hKey, pPrintMonitor->pwszName, 0, KEY_READ,
&hSubKey);
+ if (dwErrorCode != ERROR_SUCCESS)
+ {
+ ERR("RegOpenKeyExW failed for Print Provider \"%S\" with
status %lu!\n", pPrintMonitor->pwszName, dwErrorCode);
+ continue;
+ }
+
+ // Get the file name of the Print Monitor.
+ pPrintMonitor->pwszFileName = AllocAndRegQueryWSZ(hSubKey,
L"Driver");
+ if (!pPrintMonitor->pwszFileName)
+ continue;
+
+ // Try to load it.
+ hinstPrintMonitor = LoadLibraryW(pPrintMonitor->pwszFileName);
+ if (!hinstPrintMonitor)
+ {
+ ERR("LoadLibraryW failed for \"%S\" with error %lu!\n",
pPrintMonitor->pwszFileName, GetLastError());
+ continue;
+ }
+
+ // Try to find a Level 2 initialization routine first.
+ pfnInitializePrintMonitor2 =
(PInitializePrintMonitor2)GetProcAddress(hinstPrintMonitor,
"InitializePrintMonitor2");
+ if (pfnInitializePrintMonitor2)
+ {
+ // Prepare a MONITORINIT structure.
+ MonitorInit.cbSize = sizeof(MONITORINIT);
+ MonitorInit.bLocal = TRUE;
+
+ // TODO: Fill the other fields.
+
+ // Call the Level 2 initialization routine.
+ pPrintMonitor->pMonitor =
(PMONITOR2)pfnInitializePrintMonitor2(&MonitorInit, &pPrintMonitor->hMonitor);
+ if (!pPrintMonitor->pMonitor)
+ {
+ ERR("InitializePrintMonitor2 failed for \"%S\" with error
%lu!\n", pPrintMonitor->pwszFileName, GetLastError());
+ continue;
+ }
+
+ pPrintMonitor->bIsLevel2 = TRUE;
+ }
+ else
+ {
+ // Try to find a Level 1 initialization routine then.
+ pfnInitializePrintMonitor =
(PInitializePrintMonitor)GetProcAddress(hinstPrintMonitor,
"InitializePrintMonitor");
+ if (pfnInitializePrintMonitor)
+ {
+ // Construct the registry path.
+ pwszRegistryPath = DllAllocSplMem((cchMonitorsPath + 1 +
cchPrintMonitorName + 1) * sizeof(WCHAR));
+ if (!pwszRegistryPath)
+ {
+ dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ ERR("DllAllocSplMem failed with error %lu!\n",
GetLastError());
+ goto Cleanup;
+ }
+
+ CopyMemory(pwszRegistryPath, wszMonitorsPath, cchMonitorsPath *
sizeof(WCHAR));
+ pwszRegistryPath[cchMonitorsPath] = L'\\';
+ CopyMemory(&pwszRegistryPath[cchMonitorsPath + 1],
pPrintMonitor->pwszName, (cchPrintMonitorName + 1) * sizeof(WCHAR));
+
+ // Call the Level 1 initialization routine.
+ pPrintMonitor->pMonitor =
(LPMONITOREX)pfnInitializePrintMonitor(pwszRegistryPath);
+ if (!pPrintMonitor->pMonitor)
+ {
+ ERR("InitializePrintMonitor failed for \"%S\" with
error %lu!\n", pPrintMonitor->pwszFileName, GetLastError());
+ continue;
+ }
+ }
+ else
+ {
+ ERR("No initialization routine found for \"%S\"!\n",
pPrintMonitor->pwszFileName);
+ continue;
+ }
+ }
+
+ // Add this Print Monitor to the list.
+ InsertTailList(&PrintMonitorList, &pPrintMonitor->Entry);
+
+ // Don't let the cleanup routine free this.
+ pPrintMonitor = NULL;
+ }
+
+ dwErrorCode = ERROR_SUCCESS;
+
+Cleanup:
+ // Inside the loop
+ if (hSubKey)
+ RegCloseKey(hSubKey);
+
+ if (pwszRegistryPath)
+ DllFreeSplMem(pwszRegistryPath);
+
+ if (pPrintMonitor)
+ {
+ if (pPrintMonitor->pwszFileName)
+ DllFreeSplMem(pPrintMonitor->pwszFileName);
+
+ if (pPrintMonitor->pwszName)
+ DllFreeSplMem(pPrintMonitor->pwszName);
+
+ DllFreeSplMem(pPrintMonitor);
+ }
+
+ // Outside the loop
+ if (hKey)
+ RegCloseKey(hKey);
+
+ SetLastError(dwErrorCode);
+ return (dwErrorCode == ERROR_SUCCESS);
+}
+
+BOOL WINAPI
+LocalEnumMonitors(PWSTR pName, DWORD Level, PBYTE pMonitors, DWORD cbBuf, PDWORD
pcbNeeded, PDWORD pcReturned)
+{
+ DWORD cbFileName;
+ DWORD cbMonitorName;
+ DWORD dwErrorCode;
+ PBYTE pStart;
+ PBYTE pEnd;
+ PLIST_ENTRY pEntry;
+ PLOCAL_PRINT_MONITOR pPrintMonitor;
+ MONITOR_INFO_2W MonitorInfo2; // MONITOR_INFO_1W is a subset of
MONITOR_INFO_2W, so we can handle both in one function here.
+
+ // Sanity checks.
+ if (Level > 2)
+ {
+ dwErrorCode = ERROR_INVALID_LEVEL;
+ goto Cleanup;
+ }
+
+ if ((cbBuf && !pMonitors) || !pcbNeeded || !pcReturned)
+ {
+ dwErrorCode = ERROR_INVALID_PARAMETER;
+ goto Cleanup;
+ }
+
+ // Begin counting.
+ *pcbNeeded = 0;
+ *pcReturned = 0;
+
+ // Count the required buffer size and the number of monitors.
+ for (pEntry = PrintMonitorList.Flink; pEntry != &PrintMonitorList; pEntry =
pEntry->Flink)
+ {
+ pPrintMonitor = CONTAINING_RECORD(pEntry, LOCAL_PRINT_MONITOR, Entry);
+
+ cbMonitorName = (wcslen(pPrintMonitor->pwszName) + 1) * sizeof(WCHAR);
+ cbFileName = (wcslen(pPrintMonitor->pwszFileName) + 1) * sizeof(WCHAR);
+
+ if (Level == 1)
+ *pcbNeeded += sizeof(MONITOR_INFO_1W) + cbMonitorName;
+ else
+ *pcbNeeded += sizeof(MONITOR_INFO_2W) + cbMonitorName + cbCurrentEnvironment
+ cbFileName;
+ }
+
+ // Check if the supplied buffer is large enough.
+ if (cbBuf < *pcbNeeded)
+ {
+ dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
+ goto Cleanup;
+ }
+
+ // Put the strings at the end of the buffer.
+ pStart = pMonitors;
+ pEnd = &pMonitors[cbBuf];
+
+ for (pEntry = PrintMonitorList.Flink; pEntry != &PrintMonitorList; pEntry =
pEntry->Flink)
+ {
+ pPrintMonitor = CONTAINING_RECORD(pEntry, LOCAL_PRINT_MONITOR, Entry);
+
+ // Copy the monitor name.
+ cbMonitorName = (wcslen(pPrintMonitor->pwszName) + 1) * sizeof(WCHAR);
+ pEnd -= cbMonitorName;
+ MonitorInfo2.pName = (PWSTR)pEnd;
+ CopyMemory(pEnd, pPrintMonitor->pwszName, cbMonitorName);
+
+ if (Level == 1)
+ {
+ // Finally copy the structure.
+ CopyMemory(pStart, &MonitorInfo2, sizeof(MONITOR_INFO_1W));
+ pStart += sizeof(MONITOR_INFO_1W);
+ }
+ else
+ {
+ // Copy the environment.
+ pEnd -= cbCurrentEnvironment;
+ MonitorInfo2.pEnvironment = (PWSTR)pEnd;
+ CopyMemory(pEnd, wszCurrentEnvironment, cbCurrentEnvironment);
+
+ // Copy the file name.
+ cbFileName = (wcslen(pPrintMonitor->pwszFileName) + 1) * sizeof(WCHAR);
+ pEnd -= cbFileName;
+ MonitorInfo2.pDLLName = (PWSTR)pEnd;
+ CopyMemory(pEnd, pPrintMonitor->pwszFileName, cbFileName);
+
+ // Finally copy the structure.
+ CopyMemory(pStart, &MonitorInfo2, sizeof(MONITOR_INFO_2W));
+ pStart += sizeof(MONITOR_INFO_2W);
+ }
+
+ (*pcReturned)++;
+ }
+
+ dwErrorCode = ERROR_SUCCESS;
+
+Cleanup:
+ SetLastError(dwErrorCode);
+ return (dwErrorCode == ERROR_SUCCESS);
+}
Propchange:
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/monitors.c
------------------------------------------------------------------------------
svn:eol-style = native
Added:
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/ports.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/ports.c (added)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/ports.c [iso-8859-1]
Tue Jul 7 17:06:48 2015
@@ -0,0 +1,64 @@
+/*
+ * PROJECT: ReactOS Local Spooler
+ * LICENSE: GNU LGPL v2.1 or any later version as published by the Free Software
Foundation
+ * PURPOSE: Functions related to Ports of the Print Monitors
+ * COPYRIGHT: Copyright 2015 Colin Finck <colin(a)reactos.org>
+ */
+
+#include "precomp.h"
+
+
+BOOL WINAPI
+LocalEnumPorts(PWSTR pName, DWORD Level, PBYTE pPorts, DWORD cbBuf, PDWORD pcbNeeded,
PDWORD pcReturned)
+{
+ BOOL bReturnValue;
+ DWORD cbCallBuffer;
+ DWORD cbNeeded;
+ DWORD dwReturned;
+ PBYTE pCallBuffer;
+ PLOCAL_PRINT_MONITOR pPrintMonitor;
+ PLIST_ENTRY pEntry;
+
+ // Sanity checks.
+ if ((cbBuf && !pPorts) || !pcbNeeded || !pcReturned)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ // Begin counting.
+ *pcbNeeded = 0;
+ *pcReturned = 0;
+
+ // At the beginning, we have the full buffer available.
+ cbCallBuffer = cbBuf;
+ pCallBuffer = pPorts;
+
+ // Loop through all Print Monitors.
+ for (pEntry = PrintMonitorList.Flink; pEntry != &PrintMonitorList; pEntry =
pEntry->Flink)
+ {
+ pPrintMonitor = CONTAINING_RECORD(pEntry, LOCAL_PRINT_MONITOR, Entry);
+
+ // Call the EnumPorts function of this Print Monitor.
+ if (pPrintMonitor->bIsLevel2)
+ bReturnValue =
((PMONITOR2)pPrintMonitor->pMonitor)->pfnEnumPorts(pPrintMonitor->hMonitor,
pName, Level, pCallBuffer, cbCallBuffer, &cbNeeded, &dwReturned);
+ else
+ bReturnValue =
((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnEnumPorts(pName, Level,
pCallBuffer, cbCallBuffer, &cbNeeded, &dwReturned);
+
+ // Add the returned counts to the total values.
+ *pcbNeeded += cbNeeded;
+ *pcReturned += dwReturned;
+
+ // Reduce the available buffer size for the next call without risking an
underflow.
+ if (cbNeeded < cbCallBuffer)
+ cbCallBuffer -= cbNeeded;
+ else
+ cbCallBuffer = 0;
+
+ // Advance the buffer if the caller provided it.
+ if (pCallBuffer)
+ pCallBuffer += cbNeeded;
+ }
+
+ return bReturnValue;
+}
Propchange:
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/ports.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/precomp.h
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/precomp.h [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/precomp.h [iso-8859-1]
Tue Jul 7 17:06:48 2015
@@ -45,6 +45,8 @@
typedef DWORD (WINAPI *PGetPrintProcessorCapabilities)(LPWSTR, DWORD, LPBYTE, DWORD,
LPDWORD);
typedef HANDLE (WINAPI *POpenPrintProcessor)(LPWSTR, PPRINTPROCESSOROPENDATA);
typedef BOOL (WINAPI *PPrintDocumentOnPrintProcessor)(HANDLE, LPWSTR);
+typedef LPMONITOREX(WINAPI *PInitializePrintMonitor)(PWSTR);
+typedef LPMONITOR2(WINAPI *PInitializePrintMonitor2)(PMONITORINIT, PHANDLE);
// Structures
/**
@@ -141,6 +143,21 @@
PVOID pSpecificHandle;
}
LOCAL_HANDLE, *PLOCAL_HANDLE;
+
+/**
+ * Describes a Print Monitor.
+ */
+typedef struct _LOCAL_PRINT_MONITOR
+{
+ LIST_ENTRY Entry;
+ PWSTR pwszName; /** Name of the Print Monitor as read from the
registry. */
+ PWSTR pwszFileName; /** DLL File Name of the Print Monitor. */
+ BOOL bIsLevel2; /** Whether this Print Monitor supplies an
InitializePrintMonitor2 API (preferred) instead of InitializePrintMonitor. */
+ PVOID pMonitor; /** For bIsLevel2 == TRUE: LPMONITOR2 pointer
returned by InitializePrintMonitor2.
+ For bIsLevel2 == FALSE: LPMONITOREX pointer
returned by InitializePrintMonitor. */
+ HANDLE hMonitor; /** Only used when bIsLevel2 == TRUE: Handle
returned by InitializePrintMonitor2. */
+}
+LOCAL_PRINT_MONITOR, *PLOCAL_PRINT_MONITOR;
/**
* Describes the header of a print job serialized into a shadow file (.SHD)
@@ -184,7 +201,7 @@
// jobs.c
extern SKIPLIST GlobalJobList;
BOOL GetNextJobID(PDWORD dwJobID);
-void InitializeGlobalJobList();
+BOOL InitializeGlobalJobList();
void InitializePrinterJobList(PLOCAL_PRINTER pPrinter);
BOOL WINAPI LocalAddJob(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD
pcbNeeded);
BOOL WINAPI LocalEnumJobs(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level,
PBYTE pStart, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned);
@@ -196,14 +213,23 @@
// main.c
extern const WCHAR wszCurrentEnvironment[];
+extern const DWORD cbCurrentEnvironment;
extern const WCHAR wszDefaultDocumentName[];
extern const WCHAR* wszPrintProviderInfo[3];
extern WCHAR wszSpoolDirectory[MAX_PATH];
extern DWORD cchSpoolDirectory;
+// monitors.c
+extern LIST_ENTRY PrintMonitorList;
+BOOL InitializePrintMonitorList();
+BOOL WINAPI LocalEnumMonitors(PWSTR pName, DWORD Level, PBYTE pMonitors, DWORD cbBuf,
PDWORD pcbNeeded, PDWORD pcReturned);
+
+// ports.c
+BOOL WINAPI LocalEnumPorts(PWSTR pName, DWORD Level, PBYTE pPorts, DWORD cbBuf, PDWORD
pcbNeeded, PDWORD pcReturned);
+
// printers.c
extern SKIPLIST PrinterList;
-void InitializePrinterList();
+BOOL InitializePrinterList();
BOOL WINAPI LocalEnumPrinters(DWORD Flags, LPWSTR Name, DWORD Level, LPBYTE pPrinterEnum,
DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned);
BOOL WINAPI LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW
pDefault);
DWORD WINAPI LocalStartDocPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo);
@@ -216,7 +242,7 @@
// printprocessors.c
BOOL FindDatatype(PLOCAL_PRINT_PROCESSOR pPrintProcessor, PWSTR pwszDatatype);
PLOCAL_PRINT_PROCESSOR FindPrintProcessor(PWSTR pwszName);
-void InitializePrintProcessorList();
+BOOL InitializePrintProcessorList();
BOOL WINAPI LocalEnumPrintProcessorDatatypes(LPWSTR pName, LPWSTR pPrintProcessorName,
DWORD Level, LPBYTE pDatatypes, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned);
BOOL WINAPI LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level,
LPBYTE pPrintProcessorInfo, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned);
BOOL WINAPI LocalGetPrintProcessorDirectory(LPWSTR pName, LPWSTR pEnvironment, DWORD
Level, LPBYTE pPrintProcessorInfo, DWORD cbBuf, LPDWORD pcbNeeded);
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/printers.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/printers.c [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/printers.c [iso-8859-1]
Tue Jul 7 17:06:48 2015
@@ -33,18 +33,18 @@
* The list is searchable by name and returns information about the printers, including
their job queues.
* During this process, the job queues are also initialized.
*/
-void
+BOOL
InitializePrinterList()
{
const WCHAR wszPrintersKey[] =
L"SYSTEM\\CurrentControlSet\\Control\\Print\\Printers";
DWORD cbData;
DWORD cchPrinterName;
+ DWORD dwErrorCode;
DWORD dwSubKeys;
DWORD i;
HKEY hKey = NULL;
HKEY hSubKey = NULL;
- LONG lStatus;
PLOCAL_PRINTER pPrinter = NULL;
PLOCAL_PRINT_PROCESSOR pPrintProcessor;
PWSTR pwszPrintProcessor = NULL;
@@ -54,18 +54,18 @@
InitializeSkiplist(&PrinterList, DllAllocSplMem, _PrinterListCompareRoutine,
(PSKIPLIST_FREE_ROUTINE)DllFreeSplMem);
// Open our printers registry key. Each subkey is a local printer there.
- lStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszPrintersKey, 0, KEY_READ, &hKey);
- if (lStatus != ERROR_SUCCESS)
- {
- ERR("RegOpenKeyExW failed with status %ld!\n", lStatus);
+ dwErrorCode = (DWORD)RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszPrintersKey, 0, KEY_READ,
&hKey);
+ if (dwErrorCode != ERROR_SUCCESS)
+ {
+ ERR("RegOpenKeyExW failed with status %lu!\n", dwErrorCode);
goto Cleanup;
}
// Get the number of subkeys.
- lStatus = RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &dwSubKeys, NULL, NULL, NULL,
NULL, NULL, NULL, NULL);
- if (lStatus != ERROR_SUCCESS)
- {
- ERR("RegQueryInfoKeyW failed with status %ld!\n", lStatus);
+ dwErrorCode = (DWORD)RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &dwSubKeys, NULL,
NULL, NULL, NULL, NULL, NULL, NULL);
+ if (dwErrorCode != ERROR_SUCCESS)
+ {
+ ERR("RegQueryInfoKeyW failed with status %lu!\n", dwErrorCode);
goto Cleanup;
}
@@ -105,23 +105,23 @@
// Get the name of this printer.
cchPrinterName = _countof(wszPrinterName);
- lStatus = RegEnumKeyExW(hKey, i, wszPrinterName, &cchPrinterName, NULL, NULL,
NULL, NULL);
- if (lStatus == ERROR_MORE_DATA)
+ dwErrorCode = (DWORD)RegEnumKeyExW(hKey, i, wszPrinterName, &cchPrinterName,
NULL, NULL, NULL, NULL);
+ if (dwErrorCode == ERROR_MORE_DATA)
{
// This printer name exceeds the maximum length and is invalid.
continue;
}
- else if (lStatus != ERROR_SUCCESS)
- {
- ERR("RegEnumKeyExW failed for iteration %lu with status %ld!\n", i,
lStatus);
+ else if (dwErrorCode != ERROR_SUCCESS)
+ {
+ ERR("RegEnumKeyExW failed for iteration %lu with status %lu!\n", i,
dwErrorCode);
continue;
}
// Open this Printer's registry key.
- lStatus = RegOpenKeyExW(hKey, wszPrinterName, 0, KEY_READ, &hSubKey);
- if (lStatus != ERROR_SUCCESS)
- {
- ERR("RegOpenKeyExW failed for Printer \"%S\" with status
%ld!\n", wszPrinterName, lStatus);
+ dwErrorCode = (DWORD)RegOpenKeyExW(hKey, wszPrinterName, 0, KEY_READ,
&hSubKey);
+ if (dwErrorCode != ERROR_SUCCESS)
+ {
+ ERR("RegOpenKeyExW failed for Printer \"%S\" with status
%lu!\n", wszPrinterName, dwErrorCode);
continue;
}
@@ -142,6 +142,7 @@
pPrinter = DllAllocSplMem(sizeof(LOCAL_PRINTER));
if (!pPrinter)
{
+ dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
goto Cleanup;
}
@@ -174,28 +175,28 @@
// Get the default DevMode.
cbData = sizeof(DEVMODEW);
- lStatus = RegQueryValueExW(hSubKey, L"Default DevMode", NULL, NULL,
(PBYTE)&pPrinter->DefaultDevMode, &cbData);
- if (lStatus != ERROR_SUCCESS || cbData != sizeof(DEVMODEW))
- {
- ERR("Couldn't query a valid DevMode for Printer \"%S\",
status is %ld, cbData is %lu!\n", wszPrinterName, lStatus, cbData);
+ dwErrorCode = (DWORD)RegQueryValueExW(hSubKey, L"Default DevMode",
NULL, NULL, (PBYTE)&pPrinter->DefaultDevMode, &cbData);
+ if (dwErrorCode != ERROR_SUCCESS || cbData != sizeof(DEVMODEW))
+ {
+ ERR("Couldn't query a valid DevMode for Printer \"%S\",
status is %lu, cbData is %lu!\n", wszPrinterName, dwErrorCode, cbData);
continue;
}
// Get the Attributes.
cbData = sizeof(DWORD);
- lStatus = RegQueryValueExW(hSubKey, L"Attributes", NULL, NULL,
(PBYTE)&pPrinter->dwAttributes, &cbData);
- if (lStatus != ERROR_SUCCESS)
- {
- ERR("Couldn't query Attributes for Printer \"%S\", status
is %ld!\n", wszPrinterName, lStatus);
+ dwErrorCode = (DWORD)RegQueryValueExW(hSubKey, L"Attributes", NULL,
NULL, (PBYTE)&pPrinter->dwAttributes, &cbData);
+ if (dwErrorCode != ERROR_SUCCESS)
+ {
+ ERR("Couldn't query Attributes for Printer \"%S\", status
is %lu!\n", wszPrinterName, dwErrorCode);
continue;
}
// Get the Status.
cbData = sizeof(DWORD);
- lStatus = RegQueryValueExW(hSubKey, L"Status", NULL, NULL,
(PBYTE)&pPrinter->dwStatus, &cbData);
- if (lStatus != ERROR_SUCCESS)
- {
- ERR("Couldn't query Status for Printer \"%S\", status is
%ld!\n", wszPrinterName, lStatus);
+ dwErrorCode = (DWORD)RegQueryValueExW(hSubKey, L"Status", NULL, NULL,
(PBYTE)&pPrinter->dwStatus, &cbData);
+ if (dwErrorCode != ERROR_SUCCESS)
+ {
+ ERR("Couldn't query Status for Printer \"%S\", status is
%lu!\n", wszPrinterName, dwErrorCode);
continue;
}
@@ -209,6 +210,8 @@
// Don't let the cleanup routines free this.
pPrinter = NULL;
}
+
+ dwErrorCode = ERROR_SUCCESS;
Cleanup:
// Inside the loop
@@ -238,6 +241,9 @@
// Outside the loop
if (hKey)
RegCloseKey(hKey);
+
+ SetLastError(dwErrorCode);
+ return (dwErrorCode == ERROR_SUCCESS);
}
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/printprocessors.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/printprocessors.c [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/printprocessors.c [iso-8859-1]
Tue Jul 7 17:06:48 2015
@@ -111,7 +111,7 @@
*
* Initializes a singly linked list of locally available Print Processors.
*/
-void
+BOOL
InitializePrintProcessorList()
{
DWORD cbDatatypes;
@@ -119,15 +119,14 @@
DWORD cchPrintProcessorPath;
DWORD cchMaxSubKey;
DWORD cchPrintProcessorName;
+ DWORD dwErrorCode;
DWORD dwSubKeys;
DWORD i;
HINSTANCE hinstPrintProcessor;
HKEY hKey = NULL;
HKEY hSubKey = NULL;
HKEY hSubSubKey = NULL;
- LONG lStatus;
PLOCAL_PRINT_PROCESSOR pPrintProcessor = NULL;
- PWSTR pwszPrintProcessorName = NULL;
WCHAR wszFileName[MAX_PATH];
WCHAR wszPrintProcessorPath[MAX_PATH];
@@ -136,36 +135,32 @@
// Prepare the path to the Print Processor directory.
if (!LocalGetPrintProcessorDirectory(NULL, NULL, 1, (PBYTE)wszPrintProcessorPath,
sizeof(wszPrintProcessorPath), &cchPrintProcessorPath))
- goto Cleanup;
+ {
+ dwErrorCode = GetLastError();
+ goto Cleanup;
+ }
cchPrintProcessorPath /= sizeof(WCHAR);
wszPrintProcessorPath[cchPrintProcessorPath++] = L'\\';
// Open the environment registry key.
- if (_OpenEnvironment(NULL, &hKey) != ERROR_SUCCESS)
+ dwErrorCode = _OpenEnvironment(NULL, &hKey);
+ if (dwErrorCode != ERROR_SUCCESS)
goto Cleanup;
// Open the "Print Processors" subkey.
- lStatus = RegOpenKeyExW(hKey, L"Print Processors", 0, KEY_READ,
&hSubKey);
- if (lStatus != ERROR_SUCCESS)
- {
- ERR("RegOpenKeyExW failed with status %ld!\n", lStatus);
+ dwErrorCode = (DWORD)RegOpenKeyExW(hKey, L"Print Processors", 0, KEY_READ,
&hSubKey);
+ if (dwErrorCode != ERROR_SUCCESS)
+ {
+ ERR("RegOpenKeyExW failed with status %lu!\n", dwErrorCode);
goto Cleanup;
}
// Get the number of Print Processors and maximum sub key length.
- lStatus = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, &dwSubKeys,
&cchMaxSubKey, NULL, NULL, NULL, NULL, NULL, NULL);
- if (lStatus != ERROR_SUCCESS)
- {
- ERR("RegQueryInfoKeyW failed with status %ld!\n", lStatus);
- goto Cleanup;
- }
-
- // Allocate a temporary buffer for the Print Processor names.
- pwszPrintProcessorName = DllAllocSplMem((cchMaxSubKey + 1) * sizeof(WCHAR));
- if (!pwszPrintProcessorName)
- {
- ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
+ dwErrorCode = (DWORD)RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, &dwSubKeys,
&cchMaxSubKey, NULL, NULL, NULL, NULL, NULL, NULL);
+ if (dwErrorCode != ERROR_SUCCESS)
+ {
+ ERR("RegQueryInfoKeyW failed with status %lu!\n", dwErrorCode);
goto Cleanup;
}
@@ -191,36 +186,54 @@
pPrintProcessor = NULL;
}
+ // Create a new LOCAL_PRINT_PROCESSOR structure for it.
+ pPrintProcessor = DllAllocSplMem(sizeof(LOCAL_PRINT_PROCESSOR));
+ if (!pPrintProcessor)
+ {
+ dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
+ goto Cleanup;
+ }
+
+ // Allocate memory for the Print Monitor Name.
+ pPrintProcessor->pwszName = DllAllocSplMem((cchMaxSubKey + 1) *
sizeof(WCHAR));
+ if (!pPrintProcessor->pwszName)
+ {
+ dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
+ goto Cleanup;
+ }
+
// Get the name of this Print Processor.
cchPrintProcessorName = cchMaxSubKey + 1;
- lStatus = RegEnumKeyExW(hSubKey, i, pwszPrintProcessorName,
&cchPrintProcessorName, NULL, NULL, NULL, NULL);
- if (lStatus != ERROR_SUCCESS)
- {
- ERR("RegEnumKeyExW failed with status %ld!\n", lStatus);
+ dwErrorCode = (DWORD)RegEnumKeyExW(hSubKey, i, pPrintProcessor->pwszName,
&cchPrintProcessorName, NULL, NULL, NULL, NULL);
+ if (dwErrorCode != ERROR_SUCCESS)
+ {
+ ERR("RegEnumKeyExW failed with status %ld!\n", dwErrorCode);
continue;
}
// Open this Print Processor's registry key.
- lStatus = RegOpenKeyExW(hSubKey, pwszPrintProcessorName, 0, KEY_READ,
&hSubSubKey);
- if (lStatus != ERROR_SUCCESS)
- {
- ERR("RegOpenKeyExW failed for Print Processor \"%S\" with
status %ld!\n", pwszPrintProcessorName, lStatus);
+ dwErrorCode = (DWORD)RegOpenKeyExW(hSubKey, pPrintProcessor->pwszName, 0,
KEY_READ, &hSubSubKey);
+ if (dwErrorCode != ERROR_SUCCESS)
+ {
+ ERR("RegOpenKeyExW failed for Print Processor \"%S\" with
status %lu!\n", pPrintProcessor->pwszName, dwErrorCode);
continue;
}
// Get the file name of the Print Processor.
cbFileName = sizeof(wszFileName);
- lStatus = RegQueryValueExW(hSubSubKey, L"Driver", NULL, NULL,
(PBYTE)wszFileName, &cbFileName);
- if (lStatus != ERROR_SUCCESS)
- {
- ERR("RegQueryValueExW failed for Print Processor \"%S\" with
status %ld!\n", pwszPrintProcessorName, lStatus);
+ dwErrorCode = (DWORD)RegQueryValueExW(hSubSubKey, L"Driver", NULL,
NULL, (PBYTE)wszFileName, &cbFileName);
+ if (dwErrorCode != ERROR_SUCCESS)
+ {
+ ERR("RegQueryValueExW failed for Print Processor \"%S\" with
status %lu!\n", pPrintProcessor->pwszName, dwErrorCode);
continue;
}
// Verify that our buffer is large enough.
if (cchPrintProcessorPath + cbFileName / sizeof(WCHAR) > MAX_PATH)
{
- ERR("Print Processor directory \"%S\" for Print Processor
\"%S\" is too long!\n", wszFileName, pwszPrintProcessorName);
+ ERR("Print Processor directory \"%S\" for Print Processor
\"%S\" is too long!\n", wszFileName, pPrintProcessor->pwszName);
continue;
}
@@ -229,15 +242,11 @@
// Try to load it.
hinstPrintProcessor = LoadLibraryW(wszPrintProcessorPath);
- if (lStatus != ERROR_SUCCESS)
+ if (!hinstPrintProcessor)
{
ERR("LoadLibraryW failed for \"%S\" with error %lu!\n",
wszPrintProcessorPath, GetLastError());
continue;
}
-
- // Create a new LOCAL_PRINT_PROCESSOR structure for it.
- pPrintProcessor = DllAllocSplMem(sizeof(LOCAL_PRINT_PROCESSOR));
- pPrintProcessor->pwszName = AllocSplStr(pwszPrintProcessorName);
// Get and verify all its function pointers.
pPrintProcessor->pfnClosePrintProcessor =
(PClosePrintProcessor)GetProcAddress(hinstPrintProcessor,
"ClosePrintProcessor");
@@ -287,6 +296,7 @@
pPrintProcessor->pDatatypesInfo1 = DllAllocSplMem(cbDatatypes);
if (!pPrintProcessor->pDatatypesInfo1)
{
+ dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
goto Cleanup;
}
@@ -303,6 +313,8 @@
// Don't let the cleanup routines free this.
pPrintProcessor = NULL;
}
+
+ dwErrorCode = ERROR_SUCCESS;
Cleanup:
// Inside the loop
@@ -321,14 +333,14 @@
}
// Outside the loop
- if (pwszPrintProcessorName)
- DllFreeSplStr(pwszPrintProcessorName);
-
if (hSubKey)
RegCloseKey(hSubKey);
if (hKey)
RegCloseKey(hKey);
+
+ SetLastError(dwErrorCode);
+ return (dwErrorCode == ERROR_SUCCESS);
}
/**