Author: cfinck
Date: Mon Jul 13 10:18:07 2015
New Revision: 68397
URL:
http://svn.reactos.org/svn/reactos?rev=68397&view=rev
Log:
[LOCALSPL]
- Rewrite LocalOpenPrinter to also properly support opening Port and Xcv handles.
- Manage a list of Ports and their associated Print Monitors.
- const-ify some parameters.
Modified:
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/monitors.c
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/ports.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/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]
Mon Jul 13 10:18:07 2015
@@ -218,7 +218,7 @@
// Check if this is a printer handle.
pHandle = (PLOCAL_HANDLE)hPrinter;
- if (pHandle->HandleType != Printer)
+ if (pHandle->HandleType != HandleType_Printer)
{
dwErrorCode = ERROR_INVALID_HANDLE;
goto Cleanup;
@@ -579,7 +579,7 @@
// Check if this is a printer handle.
pHandle = (PLOCAL_HANDLE)hPrinter;
- if (pHandle->HandleType != Printer)
+ if (pHandle->HandleType != HandleType_Printer)
{
dwErrorCode = ERROR_INVALID_HANDLE;
goto Cleanup;
@@ -853,7 +853,7 @@
// Check if this is a printer handle.
pHandle = (PLOCAL_HANDLE)hPrinter;
- if (pHandle->HandleType != Printer)
+ if (pHandle->HandleType != HandleType_Printer)
{
dwErrorCode = ERROR_INVALID_HANDLE;
goto Cleanup;
@@ -918,7 +918,7 @@
// Check if this is a printer handle.
pHandle = (PLOCAL_HANDLE)hPrinter;
- if (pHandle->HandleType != Printer)
+ if (pHandle->HandleType != HandleType_Printer)
{
dwErrorCode = ERROR_INVALID_HANDLE;
goto Cleanup;
@@ -1015,7 +1015,7 @@
// Check if this is a printer handle.
pHandle = (PLOCAL_HANDLE)hPrinter;
- if (pHandle->HandleType != Printer)
+ if (pHandle->HandleType != HandleType_Printer)
{
dwErrorCode = ERROR_INVALID_HANDLE;
goto Cleanup;
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]
Mon Jul 13 10:18:07 2015
@@ -146,6 +146,7 @@
_GetSpoolDirectory();
return InitializePrintMonitorList() &&
+ InitializePortList() &&
InitializePrintProcessorList() &&
InitializePrinterList() &&
InitializeGlobalJobList();
Modified:
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 [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/monitors.c [iso-8859-1]
Mon Jul 13 10:18:07 2015
@@ -7,8 +7,26 @@
#include "precomp.h"
-// Local Variables
+// Global Variables
LIST_ENTRY PrintMonitorList;
+
+
+PLOCAL_PRINT_MONITOR
+FindPrintMonitor(PCWSTR pwszName)
+{
+ PLIST_ENTRY pEntry;
+ PLOCAL_PRINT_MONITOR pPrintMonitor;
+
+ for (pEntry = PrintMonitorList.Flink; pEntry != &PrintMonitorList; pEntry =
pEntry->Flink)
+ {
+ pPrintMonitor = CONTAINING_RECORD(pEntry, LOCAL_PRINT_MONITOR, Entry);
+
+ if (_wcsicmp(pPrintMonitor->pwszName, pwszName) == 0)
+ return pPrintMonitor;
+ }
+
+ return NULL;
+}
BOOL
InitializePrintMonitorList()
Modified:
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 [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/ports.c [iso-8859-1]
Mon Jul 13 10:18:07 2015
@@ -7,6 +7,128 @@
#include "precomp.h"
+// Local Variables
+static LIST_ENTRY _PortList;
+
+
+PLOCAL_PRINT_MONITOR
+FindPrintMonitorByPort(PCWSTR pwszName)
+{
+ PLIST_ENTRY pEntry;
+ PLOCAL_PORT pPort;
+
+ for (pEntry = _PortList.Flink; pEntry != &_PortList; pEntry = pEntry->Flink)
+ {
+ pPort = CONTAINING_RECORD(pEntry, LOCAL_PORT, Entry);
+
+ if (_wcsicmp(pPort->pwszName, pwszName) == 0)
+ return pPort->pPrintMonitor;
+ }
+
+ return NULL;
+}
+
+BOOL
+InitializePortList()
+{
+ BOOL bReturnValue;
+ DWORD cbNeeded;
+ DWORD cbPortName;
+ DWORD dwErrorCode;
+ DWORD dwReturned;
+ DWORD i;
+ PLOCAL_PORT pPort;
+ PLOCAL_PRINT_MONITOR pPrintMonitor;
+ PLIST_ENTRY pEntry;
+ PPORT_INFO_1W p;
+ PPORT_INFO_1W pPortInfo1 = NULL;
+
+ // Initialize an empty list for our Ports.
+ InitializeListHead(&_PortList);
+
+ // Loop through all Print Monitors.
+ for (pEntry = PrintMonitorList.Flink; pEntry != &PrintMonitorList; pEntry =
pEntry->Flink)
+ {
+ // Cleanup from the previous run.
+ if (pPortInfo1)
+ {
+ DllFreeSplMem(pPortInfo1);
+ pPortInfo1 = NULL;
+ }
+
+ pPrintMonitor = CONTAINING_RECORD(pEntry, LOCAL_PRINT_MONITOR, Entry);
+
+ // Determine the required buffer size for EnumPorts.
+ if (pPrintMonitor->bIsLevel2)
+ bReturnValue =
((PMONITOR2)pPrintMonitor->pMonitor)->pfnEnumPorts(pPrintMonitor->hMonitor, NULL,
1, NULL, 0, &cbNeeded, &dwReturned);
+ else
+ bReturnValue =
((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnEnumPorts(NULL, 1, NULL, 0,
&cbNeeded, &dwReturned);
+
+ // Check the returned error code.
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ {
+ ERR("Print Monitor \"%S\" failed with error %lu on
EnumPorts!\n", pPrintMonitor->pwszName, GetLastError());
+ continue;
+ }
+
+ // Allocate a buffer large enough.
+ pPortInfo1 = DllAllocSplMem(cbNeeded);
+ if (!pPortInfo1)
+ {
+ dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
+ goto Cleanup;
+ }
+
+ // Get the ports handled by this monitor.
+ if (pPrintMonitor->bIsLevel2)
+ bReturnValue =
((PMONITOR2)pPrintMonitor->pMonitor)->pfnEnumPorts(pPrintMonitor->hMonitor, NULL,
1, (PBYTE)pPortInfo1, cbNeeded, &cbNeeded, &dwReturned);
+ else
+ bReturnValue =
((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnEnumPorts(NULL, 1,
(PBYTE)pPortInfo1, cbNeeded, &cbNeeded, &dwReturned);
+
+ // Check the return value.
+ if (!bReturnValue)
+ {
+ ERR("Print Monitor \"%S\" failed with error %lu on
EnumPorts!\n", pPrintMonitor->pwszName, GetLastError());
+ continue;
+ }
+
+ // Loop through all returned ports.
+ p = pPortInfo1;
+
+ for (i = 0; i < dwReturned; i++)
+ {
+ cbPortName = (wcslen(p->pName) + 1) * sizeof(WCHAR);
+
+ // Create a new LOCAL_PORT structure for it.
+ pPort = DllAllocSplMem(sizeof(LOCAL_PORT) + cbPortName);
+ if (!pPort)
+ {
+ dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ ERR("DllAllocSplMem failed with error %lu!\n",
GetLastError());
+ goto Cleanup;
+ }
+
+ pPort->pPrintMonitor = pPrintMonitor;
+ pPort->pwszName = (PWSTR)((PBYTE)pPort + sizeof(LOCAL_PORT));
+ CopyMemory(pPort->pwszName, p->pName, cbPortName);
+
+ // Insert it into the list and advance to the next port.
+ InsertTailList(&_PortList, &pPort->Entry);
+ p++;
+ }
+ }
+
+ dwErrorCode = ERROR_SUCCESS;
+
+Cleanup:
+ // Inside the loop
+ if (pPortInfo1)
+ DllFreeSplMem(pPortInfo1);
+
+ SetLastError(dwErrorCode);
+ return (dwErrorCode == ERROR_SUCCESS);
+}
BOOL WINAPI
LocalEnumPorts(PWSTR pName, DWORD Level, PBYTE pPorts, DWORD cbBuf, PDWORD pcbNeeded,
PDWORD pcReturned)
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]
Mon Jul 13 10:18:07 2015
@@ -139,7 +139,12 @@
*/
typedef struct _LOCAL_HANDLE
{
- enum { Printer, Monitor, Port } HandleType;
+ enum {
+ HandleType_Port,
+ HandleType_Printer,
+ HandleType_Xcv
+ }
+ HandleType;
PVOID pSpecificHandle;
}
LOCAL_HANDLE, *PLOCAL_HANDLE;
@@ -158,6 +163,17 @@
HANDLE hMonitor; /** Only used when bIsLevel2 == TRUE: Handle
returned by InitializePrintMonitor2. */
}
LOCAL_PRINT_MONITOR, *PLOCAL_PRINT_MONITOR;
+
+/**
+ * Describes a Port handled by a Print Monitor.
+ */
+typedef struct _LOCAL_PORT
+{
+ LIST_ENTRY Entry;
+ PWSTR pwszName; /** The name of the port (including the
trailing colon). */
+ PLOCAL_PRINT_MONITOR pPrintMonitor; /** The Print Monitor handling this port. */
+}
+LOCAL_PORT, *PLOCAL_PORT;
/**
* Describes the header of a print job serialized into a shadow file (.SHD)
@@ -221,10 +237,13 @@
// monitors.c
extern LIST_ENTRY PrintMonitorList;
+PLOCAL_PRINT_MONITOR FindPrintMonitor(PCWSTR pwszName);
BOOL InitializePrintMonitorList();
BOOL WINAPI LocalEnumMonitors(PWSTR pName, DWORD Level, PBYTE pMonitors, DWORD cbBuf,
PDWORD pcbNeeded, PDWORD pcReturned);
// ports.c
+PLOCAL_PRINT_MONITOR FindPrintMonitorByPort(PCWSTR pwszName);
+BOOL InitializePortList();
BOOL WINAPI LocalEnumPorts(PWSTR pName, DWORD Level, PBYTE pPorts, DWORD cbBuf, PDWORD
pcbNeeded, PDWORD pcReturned);
// printers.c
@@ -240,8 +259,8 @@
BOOL WINAPI LocalClosePrinter(HANDLE hPrinter);
// printprocessors.c
-BOOL FindDatatype(PLOCAL_PRINT_PROCESSOR pPrintProcessor, PWSTR pwszDatatype);
-PLOCAL_PRINT_PROCESSOR FindPrintProcessor(PWSTR pwszName);
+BOOL FindDatatype(const PLOCAL_PRINT_PROCESSOR pPrintProcessor, PCWSTR pwszDatatype);
+PLOCAL_PRINT_PROCESSOR FindPrintProcessor(PCWSTR pwszName);
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);
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]
Mon Jul 13 10:18:07 2015
@@ -477,18 +477,25 @@
BOOL WINAPI
LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDefault)
{
+ BOOL bReturnValue;
DWORD cchComputerName;
- DWORD cchPrinterName;
+ DWORD cchFirstParameter;
DWORD dwErrorCode;
DWORD dwJobID;
+ HANDLE hExternalHandle;
PWSTR p = lpPrinterName;
- PWSTR pwszPrinterName = NULL;
+ PWSTR pwszFirstParameter = NULL;
+ PWSTR pwszSecondParameter = NULL;
PLOCAL_JOB pJob;
- PLOCAL_HANDLE pHandle;
+ PLOCAL_HANDLE pHandle = NULL;
+ PLOCAL_PRINT_MONITOR pPrintMonitor;
PLOCAL_PRINTER pPrinter;
PLOCAL_PRINTER_HANDLE pPrinterHandle = NULL;
WCHAR wszComputerName[MAX_COMPUTERNAME_LENGTH + 1];
+ // TODO: lpPrinterName == NULL is supported and means access to the local printer
server.
+ // Not sure yet if that is passed down to localspl.dll or processed in advance.
+
// Sanity checks
if (!lpPrinterName || !phPrinter)
{
@@ -496,6 +503,7 @@
goto Cleanup;
}
+ // Skip any server name in the first parameter.
// Does lpPrinterName begin with two backslashes to indicate a server name?
if (lpPrinterName[0] == L'\\' && lpPrinterName[1] == L'\\')
{
@@ -511,9 +519,6 @@
goto Cleanup;
}
- // Null-terminate the string here to enable comparison.
- *p = 0;
-
// Get the local computer name for comparison.
cchComputerName = _countof(wszComputerName);
if (!GetComputerNameW(wszComputerName, &cchComputerName))
@@ -523,8 +528,10 @@
goto Cleanup;
}
- // Now compare this with the local computer name and reject if it doesn't
match, because this print provider only supports local printers.
- if (wcsicmp(lpPrinterName, wszComputerName) != 0)
+ // Now compare this string excerpt with the local computer name.
+ // The input parameter may not be writable, so we can't null-terminate the
input string at this point.
+ // This print provider only supports local printers, so both strings have to
match.
+ if (p - lpPrinterName != cchComputerName || _wcsnicmp(lpPrinterName,
wszComputerName, cchComputerName) != 0)
{
dwErrorCode = ERROR_INVALID_PRINTER_NAME;
goto Cleanup;
@@ -534,30 +541,155 @@
lpPrinterName = p + 1;
}
- // Look for a comma. If it exists, it indicates the end of the printer name.
- p = wcschr(lpPrinterName, L',');
- if (p)
- cchPrinterName = p - lpPrinterName;
+ // Look for a comma. If it exists, it indicates the end of the first parameter.
+ pwszSecondParameter = wcschr(lpPrinterName, L',');
+ if (pwszSecondParameter)
+ cchFirstParameter = pwszSecondParameter - p;
else
- cchPrinterName = wcslen(lpPrinterName);
-
- // No printer name and no comma? This is invalid!
- if (!cchPrinterName && !p)
+ cchFirstParameter = wcslen(lpPrinterName);
+
+ // We must have at least one parameter.
+ if (!cchFirstParameter && !pwszSecondParameter)
{
dwErrorCode = ERROR_INVALID_PRINTER_NAME;
goto Cleanup;
}
- // Do we have a printer name?
- if (cchPrinterName)
+ // Do we have a first parameter?
+ if (cchFirstParameter)
{
// Yes, extract it.
- pwszPrinterName = DllAllocSplMem((cchPrinterName + 1) * sizeof(WCHAR));
- CopyMemory(pwszPrinterName, lpPrinterName, cchPrinterName * sizeof(WCHAR));
- pwszPrinterName[cchPrinterName] = 0;
-
- // Retrieve the associated printer from the list.
- pPrinter = LookupElementSkiplist(&PrinterList, &pwszPrinterName, NULL);
+ pwszFirstParameter = DllAllocSplMem((cchFirstParameter + 1) * sizeof(WCHAR));
+ CopyMemory(pwszFirstParameter, lpPrinterName, cchFirstParameter *
sizeof(WCHAR));
+ pwszFirstParameter[cchFirstParameter] = 0;
+ }
+
+ // Do we have a second parameter?
+ if (pwszSecondParameter)
+ {
+ // Yes, skip the comma at the beginning.
+ ++pwszSecondParameter;
+
+ // Skip whitespace as well.
+ while (*pwszSecondParameter == L' ')
+ ++pwszSecondParameter;
+ }
+
+ // Create a new handle.
+ pHandle = DllAllocSplMem(sizeof(LOCAL_HANDLE));
+ if (!pHandle)
+ {
+ dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
+ goto Cleanup;
+ }
+
+ // Now we can finally check the type of handle actually requested.
+ if (pwszFirstParameter && pwszSecondParameter &&
wcsncmp(pwszSecondParameter, L"Port", 4) == 0)
+ {
+ // The caller wants a port handle and provided a string like:
+ // "LPT1:, Port"
+ // "\\COMPUTERNAME\LPT1:, Port"
+
+ // Look for this port in our Print Monitor Port list.
+ pPrintMonitor = FindPrintMonitorByPort(pwszFirstParameter);
+ if (!pPrintMonitor)
+ {
+ // The supplied port is unknown to all our Print Monitors.
+ dwErrorCode = ERROR_INVALID_PRINTER_NAME;
+ goto Cleanup;
+ }
+
+ // Call the monitor's OpenPort function.
+ if (pPrintMonitor->bIsLevel2)
+ bReturnValue =
((PMONITOR2)pPrintMonitor->pMonitor)->pfnOpenPort(pPrintMonitor->hMonitor,
pwszFirstParameter, &hExternalHandle);
+ else
+ bReturnValue =
((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnOpenPort(pwszFirstParameter,
&hExternalHandle);
+
+ if (!bReturnValue)
+ {
+ // The OpenPort function failed. Return its last error.
+ dwErrorCode = GetLastError();
+ goto Cleanup;
+ }
+
+ // Return the Port handle through our general handle.
+ pHandle->HandleType = HandleType_Port;
+ pHandle->pSpecificHandle = hExternalHandle;
+ }
+ else if (!pwszFirstParameter && pwszSecondParameter &&
wcsncmp(pwszSecondParameter, L"Xcv", 3) == 0)
+ {
+ // The caller wants an Xcv handle and provided a string like:
+ // ", XcvMonitor Local Port"
+ // "\\COMPUTERNAME\, XcvMonitor Local Port"
+ // ", XcvPort LPT1:"
+ // "\\COMPUTERNAME\, XcvPort LPT1:"
+
+ // Skip the "Xcv" string.
+ pwszSecondParameter += 3;
+
+ // Is XcvMonitor or XcvPort requested?
+ if (wcsncmp(pwszSecondParameter, L"Monitor ", 8) == 0)
+ {
+ // Skip the "Monitor " string.
+ pwszSecondParameter += 8;
+
+ // Look for this monitor in our Print Monitor list.
+ pPrintMonitor = FindPrintMonitor(pwszSecondParameter);
+ if (!pPrintMonitor)
+ {
+ // The caller supplied a non-existing Monitor name.
+ dwErrorCode = ERROR_INVALID_PRINTER_NAME;
+ goto Cleanup;
+ }
+ }
+ else if (wcsncmp(pwszSecondParameter, L"Port ", 5) == 0)
+ {
+ // Skip the "Port " string.
+ pwszSecondParameter += 5;
+
+ // Look for this port in our Print Monitor Port list.
+ pPrintMonitor = FindPrintMonitorByPort(pwszSecondParameter);
+ if (!pPrintMonitor)
+ {
+ // The supplied port is unknown to all our Print Monitors.
+ dwErrorCode = ERROR_INVALID_PRINTER_NAME;
+ goto Cleanup;
+ }
+ }
+ else
+ {
+ dwErrorCode = ERROR_INVALID_PRINTER_NAME;
+ goto Cleanup;
+ }
+
+ // Call the monitor's XcvOpenPort function.
+ if (pPrintMonitor->bIsLevel2)
+ bReturnValue =
((PMONITOR2)pPrintMonitor->pMonitor)->pfnXcvOpenPort(pPrintMonitor->hMonitor,
pwszSecondParameter, SERVER_EXECUTE, &hExternalHandle);
+ else
+ bReturnValue =
((LPMONITOREX)pPrintMonitor->pMonitor)->Monitor.pfnXcvOpenPort(pwszSecondParameter,
SERVER_EXECUTE, &hExternalHandle);
+
+ if (!bReturnValue)
+ {
+ // The XcvOpenPort function failed. Return its last error.
+ dwErrorCode = GetLastError();
+ goto Cleanup;
+ }
+
+ // Return the Xcv handle through our general handle.
+ pHandle->HandleType = HandleType_Xcv;
+ pHandle->pSpecificHandle = hExternalHandle;
+ }
+ else
+ {
+ // The caller wants a Printer or Printer Job handle and provided a string like:
+ // "HP DeskJet"
+ // "\\COMPUTERNAME\HP DeskJet"
+ // "HP DeskJet, Job 5"
+ // "\\COMPUTERNAME\HP DeskJet, Job 5"
+
+ // Retrieve the printer from the list.
+ pPrinter = LookupElementSkiplist(&PrinterList, &pwszFirstParameter,
NULL);
if (!pPrinter)
{
// The printer does not exist.
@@ -567,6 +699,13 @@
// Create a new printer handle.
pPrinterHandle = DllAllocSplMem(sizeof(LOCAL_PRINTER_HANDLE));
+ if (!pPrinterHandle)
+ {
+ dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
+ goto Cleanup;
+ }
+
pPrinterHandle->pPrinter = pPrinter;
// Check if a datatype was given.
@@ -593,34 +732,25 @@
else
pPrinterHandle->pDevMode =
DuplicateDevMode(pPrinter->pDefaultDevMode);
- // Did we have a comma? Then the user may want a handle to an existing job
instead of creating a new job.
- if (p)
- {
- ++p;
-
- // Skip whitespace.
- do
- {
- ++p;
- }
- while (*p == ' ');
-
+ // Check if the caller wants a handle to an existing job.
+ if (pwszSecondParameter)
+ {
// The "Job " string has to follow now.
- if (wcscmp(p, L"Job ") != 0)
+ if (wcsncmp(pwszSecondParameter, L"Job ", 4) != 0)
{
dwErrorCode = ERROR_INVALID_PRINTER_NAME;
goto Cleanup;
}
// Skip the "Job " string.
- p += sizeof("Job ") - 1;
+ pwszSecondParameter += 4;
// Skip even more whitespace.
- while (*p == ' ')
- ++p;
+ while (*pwszSecondParameter == ' ')
+ ++pwszSecondParameter;
// Finally extract the desired Job ID.
- dwJobID = wcstoul(p, NULL, 10);
+ dwJobID = wcstoul(pwszSecondParameter, NULL, 10);
if (!IS_VALID_JOB_ID(dwJobID))
{
// The user supplied an invalid Job ID.
@@ -640,70 +770,36 @@
pPrinterHandle->pStartedJob = pJob;
}
- // Create a new handle that references a printer.
- pHandle = DllAllocSplMem(sizeof(LOCAL_HANDLE));
- pHandle->HandleType = Printer;
+ // Return the Printer handle through our general handle.
+ pHandle->HandleType = HandleType_Printer;
pHandle->pSpecificHandle = pPrinterHandle;
}
- else
- {
- // No printer name, but we have a comma!
- // This may be a request to a XcvMonitor or XcvPort handle.
- ++p;
-
- // Skip whitespace.
- do
- {
- ++p;
- }
- while (*p == ' ');
-
- // Check if this is a request to a XcvMonitor.
- if (wcscmp(p, L"XcvMonitor ") == 0)
- {
- // Skip the "XcvMonitor " string.
- p += sizeof("XcvMonitor ") - 1;
-
- ///////////// TODO /////////////////////
- pHandle = DllAllocSplMem(sizeof(LOCAL_HANDLE));
- pHandle->HandleType = Monitor;
- //pHandle->pSpecificHandle = pMonitorHandle;
- }
- else if (wcscmp(p, L"XcvPort ") == 0)
- {
- // Skip the "XcvPort " string.
- p += sizeof("XcvPort ") - 1;
-
- //////////// TODO //////////////////////
- pHandle = DllAllocSplMem(sizeof(LOCAL_HANDLE));
- pHandle->HandleType = Port;
- //pHandle->pSpecificHandle = pPortHandle;
- }
- else
- {
- dwErrorCode = ERROR_INVALID_PRINTER_NAME;
- goto Cleanup;
- }
- }
-
+
+ // We were successful! Return the handle.
*phPrinter = (HANDLE)pHandle;
dwErrorCode = ERROR_SUCCESS;
// Don't let the cleanup routines free this.
+ pHandle = NULL;
pPrinterHandle = NULL;
- pwszPrinterName = NULL;
Cleanup:
+ if (pHandle)
+ DllFreeSplMem(pHandle);
+
if (pPrinterHandle)
{
if (pPrinterHandle->pwszDatatype)
DllFreeSplStr(pPrinterHandle->pwszDatatype);
+ if (pPrinterHandle->pDevMode)
+ DllFreeSplMem(pPrinterHandle->pDevMode);
+
DllFreeSplMem(pPrinterHandle);
}
- if (pwszPrinterName)
- DllFreeSplMem(pwszPrinterName);
+ if (pwszFirstParameter)
+ DllFreeSplMem(pwszFirstParameter);
SetLastError(dwErrorCode);
return (dwErrorCode == ERROR_SUCCESS);
@@ -734,7 +830,7 @@
// Check if this is a printer handle.
pHandle = (PLOCAL_HANDLE)hPrinter;
- if (pHandle->HandleType != Printer)
+ if (pHandle->HandleType != HandleType_Printer)
{
dwErrorCode = ERROR_INVALID_HANDLE;
goto Cleanup;
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]
Mon Jul 13 10:18:07 2015
@@ -73,7 +73,7 @@
}
BOOL
-FindDatatype(PLOCAL_PRINT_PROCESSOR pPrintProcessor, PWSTR pwszDatatype)
+FindDatatype(const PLOCAL_PRINT_PROCESSOR pPrintProcessor, PCWSTR pwszDatatype)
{
DWORD i;
PDATATYPES_INFO_1W pCurrentDatatype = pPrintProcessor->pDatatypesInfo1;
@@ -90,7 +90,7 @@
}
PLOCAL_PRINT_PROCESSOR
-FindPrintProcessor(PWSTR pwszName)
+FindPrintProcessor(PCWSTR pwszName)
{
PLIST_ENTRY pEntry;
PLOCAL_PRINT_PROCESSOR pPrintProcessor;