Author: cfinck
Date: Wed Jul 22 12:44:22 2015
New Revision: 68550
URL:
http://svn.reactos.org/svn/reactos?rev=68550&view=rev
Log:
[LOCALSPL]
This is where things get dirty. StartDocPort of the Print Monitor needs the Printer Name
and Job ID of the job to print on this port.
But StartDocPort is called by LocalStartDocPrinter, whose parameters are fixed and
don't include this information.
Therefore, I have no way to pass these parameters to a port handle directly. Instead, I
need to store a pointer to the job in the port structure itself and let the next port
handle pick up this information in LocalStartDocPrinter.
Surprisingly, Windows doesn't seem to do any better here. For testing, I stalled
execution inside my own Print Processor and called StartDocPrinter from another thread.
It then picked up and "stole" the stored job information. When the Print
Processor resumed execution, the job information wasn't present anymore and its
StartDocPrinter call crashed. So even Windows definitely stores this information only for
a single StartDocPrinter call.
Having solved this, I could finally implement OpenPrinter, StartDocPrinter, ReadPrinter,
WritePrinter and ClosePrinter for Port handles as well as OpenPrinter and ClosePrinter for
Xcv handles.
Modified:
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/printingthread.c
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]
Wed Jul 22 12:44:22 2015
@@ -48,37 +48,48 @@
typedef LPMONITOREX(WINAPI *PInitializePrintMonitor)(PWSTR);
typedef LPMONITOR2(WINAPI *PInitializePrintMonitor2)(PMONITORINIT, PHANDLE);
+// Forward declarations
+typedef struct _LOCAL_HANDLE LOCAL_HANDLE, *PLOCAL_HANDLE;
+typedef struct _LOCAL_JOB LOCAL_JOB, *PLOCAL_JOB;
+typedef struct _LOCAL_PORT LOCAL_PORT, *PLOCAL_PORT;
+typedef struct _LOCAL_PORT_HANDLE LOCAL_PORT_HANDLE, *PLOCAL_PORT_HANDLE;
+typedef struct _LOCAL_PRINT_MONITOR LOCAL_PRINT_MONITOR, *PLOCAL_PRINT_MONITOR;
+typedef struct _LOCAL_PRINT_PROCESSOR LOCAL_PRINT_PROCESSOR, *PLOCAL_PRINT_PROCESSOR;
+typedef struct _LOCAL_PRINTER LOCAL_PRINTER, *PLOCAL_PRINTER;
+typedef struct _LOCAL_PRINTER_HANDLE LOCAL_PRINTER_HANDLE, *PLOCAL_PRINTER_HANDLE;
+typedef struct _LOCAL_XCV_HANDLE LOCAL_XCV_HANDLE, *PLOCAL_XCV_HANDLE;
+typedef struct _SHD_HEADER SHD_HEADER, *PSHD_HEADER;
+
// Structures
/**
* Describes a Print Monitor.
*/
-typedef struct _LOCAL_PRINT_MONITOR
+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;
+ 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. */
+};
/**
* Describes a Port handled by a Print Monitor.
*/
-typedef struct _LOCAL_PORT
+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;
+ PWSTR pwszName; /** The name of the port (including the
trailing colon). */
+ PLOCAL_PRINT_MONITOR pPrintMonitor; /** The Print Monitor handling this port.
*/
+ PLOCAL_JOB pNextJobToProcess; /** The Print Job that will be processed
by the next created Port handle. */
+};
/**
* Describes a Print Processor.
*/
-typedef struct _LOCAL_PRINT_PROCESSOR
+struct _LOCAL_PRINT_PROCESSOR
{
LIST_ENTRY Entry;
PWSTR pwszName;
@@ -90,14 +101,13 @@
PGetPrintProcessorCapabilities pfnGetPrintProcessorCapabilities;
POpenPrintProcessor pfnOpenPrintProcessor;
PPrintDocumentOnPrintProcessor pfnPrintDocumentOnPrintProcessor;
-}
-LOCAL_PRINT_PROCESSOR, *PLOCAL_PRINT_PROCESSOR;
+};
/**
* Describes a printer and manages its print jobs.
* Created once for every printer at startup.
*/
-typedef struct _LOCAL_PRINTER
+struct _LOCAL_PRINTER
{
// This sort key must be the first element for LookupElementSkiplist to work!
PWSTR pwszPrinterName;
@@ -111,14 +121,13 @@
PLOCAL_PRINT_PROCESSOR pPrintProcessor;
PLOCAL_PORT pPort;
SKIPLIST JobList;
-}
-LOCAL_PRINTER, *PLOCAL_PRINTER;
+};
/**
* Describes an entire print job associated to a specific printer through the Printer
member.
* Created with every valid call to LocalStartDocPrinter.
*/
-typedef struct _LOCAL_JOB
+struct _LOCAL_JOB
{
// This sort key must be the first element for LookupElementSkiplist to work!
DWORD dwJobID; /** Internal and external ID of this Job
*/
@@ -143,49 +152,60 @@
DWORD dwStatus; /** JOB_STATUS_* flags of the Job */
PWSTR pwszMachineName; /** Name of the machine that submitted
the Job (prepended with two backslashes) */
PDEVMODEW pDevMode; /** Associated Device Mode to this Job
*/
-}
-LOCAL_JOB, *PLOCAL_JOB;
-
-/**
- * Describes a template for new print jobs for a specific printer.
- * Created with every valid call to LocalOpenPrinter.
- *
- * This is needed, because you can supply defaults in a LocalOpenPrinter call, which
affect all subsequent print jobs
- * started with the same handle and a call to LocalStartDocPrinter.
- */
-typedef struct _LOCAL_PRINTER_HANDLE
+};
+
+/**
+ * Specific handle returned by LocalOpenPrinter for every valid call that opens a Printer
or Print Job.
+ */
+struct _LOCAL_PRINTER_HANDLE
{
BOOL bStartedDoc : 1; /** Whether StartDocPrinter has already
been called. */
HANDLE hSPLFile; /** Handle to an opened SPL file for
Printer Job handles. */
- PLOCAL_PRINTER pPrinter;
- PLOCAL_JOB pJob;
- PWSTR pwszDatatype;
- PDEVMODEW pDevMode;
-}
-LOCAL_PRINTER_HANDLE, *PLOCAL_PRINTER_HANDLE;
+ PLOCAL_PRINTER pPrinter; /** Printer associated with this handle.
*/
+ PLOCAL_JOB pJob; /** Print Job associated with this
handle. This can be the specified Job if this is a Print Job handle or the started job
through LocalStartDocPrinter. */
+ PWSTR pwszDatatype; /** Datatype used for newly started jobs.
*/
+ PDEVMODEW pDevMode; /** DevMode used for newly started jobs.
*/
+};
+
+/**
+ * Specific handle returned by LocalOpenPrinter for every valid call that opens a Port.
+ */
+struct _LOCAL_PORT_HANDLE
+{
+ HANDLE hPort; /** Handle returned by pfnOpenPort. */
+ PLOCAL_PORT pPort; /** Port associated with this handle. */
+};
+
+/**
+ * Specific handle returned by LocalOpenPrinter for every valid call that opens an
XcvMonitor or XcvPort.
+ */
+struct _LOCAL_XCV_HANDLE
+{
+ HANDLE hXcv; /** Handle returned by pfnXcvOpenPort.
*/
+ PLOCAL_PRINT_MONITOR pPrintMonitor; /** Print Monitor associated with this
handle. */
+};
/**
* Describes a handle returned by LocalOpenPrinter.
* Suitable for all things that can be opened through LocalOpenPrinter.
*/
-typedef struct _LOCAL_HANDLE
+struct _LOCAL_HANDLE
{
enum {
- HandleType_Port,
- HandleType_Printer,
- HandleType_Xcv
+ HandleType_Port, /** pSpecificHandle is a
PLOCAL_PORT_HANDLE. */
+ HandleType_Printer, /** pSpecificHandle is a
PLOCAL_PRINTER_HANDLE. */
+ HandleType_Xcv /** pSpecificHandle is a
PLOCAL_XCV_HANDLE. */
}
HandleType;
PVOID pSpecificHandle;
-}
-LOCAL_HANDLE, *PLOCAL_HANDLE;
+};
/**
* Describes the header of a print job serialized into a shadow file (.SHD)
* Documented in
http://www.undocprint.org/formats/winspool/shd
* Compatible with Windows Server 2003
*/
-typedef struct _SHD_HEADER
+struct _SHD_HEADER
{
DWORD dwSignature;
DWORD cbHeader;
@@ -215,8 +235,7 @@
DWORD dwUnknown5;
DWORD offMachineName;
DWORD dwSPLSize;
-}
-SHD_HEADER, *PSHD_HEADER;
+};
// jobs.c
extern SKIPLIST GlobalJobList;
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]
Wed Jul 22 12:44:22 2015
@@ -505,9 +505,11 @@
PLOCAL_JOB pJob;
PLOCAL_HANDLE pHandle = NULL;
PLOCAL_PORT pPort;
+ PLOCAL_PORT_HANDLE pPortHandle = NULL;
PLOCAL_PRINT_MONITOR pPrintMonitor;
PLOCAL_PRINTER pPrinter;
PLOCAL_PRINTER_HANDLE pPrinterHandle = NULL;
+ PLOCAL_XCV_HANDLE pXcvHandle = NULL;
WCHAR wszComputerName[MAX_COMPUTERNAME_LENGTH + 1];
WCHAR wszFullPath[MAX_PATH];
@@ -635,9 +637,21 @@
goto Cleanup;
}
+ // Create a new LOCAL_PORT_HANDLE.
+ pPortHandle = DllAllocSplMem(sizeof(LOCAL_PORT_HANDLE));
+ if (!pPortHandle)
+ {
+ dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
+ goto Cleanup;
+ }
+
+ pPortHandle->hPort = hExternalHandle;
+ pPortHandle->pPort = pPort;
+
// Return the Port handle through our general handle.
pHandle->HandleType = HandleType_Port;
- pHandle->pSpecificHandle = hExternalHandle;
+ pHandle->pSpecificHandle = pPortHandle;
}
else if (!pwszFirstParameter && pwszSecondParameter &&
wcsncmp(pwszSecondParameter, L"Xcv", 3) == 0)
{
@@ -700,9 +714,21 @@
goto Cleanup;
}
+ // Create a new LOCAL_XCV_HANDLE.
+ pXcvHandle = DllAllocSplMem(sizeof(LOCAL_XCV_HANDLE));
+ if (!pXcvHandle)
+ {
+ dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+ ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
+ goto Cleanup;
+ }
+
+ pXcvHandle->hXcv = hExternalHandle;
+ pXcvHandle->pPrintMonitor = pPrintMonitor;
+
// Return the Xcv handle through our general handle.
pHandle->HandleType = HandleType_Xcv;
- pHandle->pSpecificHandle = hExternalHandle;
+ pHandle->pSpecificHandle = pXcvHandle;
}
else
{
@@ -721,7 +747,7 @@
goto Cleanup;
}
- // Create a new printer handle.
+ // Create a new LOCAL_PRINTER_HANDLE.
pPrinterHandle = DllAllocSplMem(sizeof(LOCAL_PRINTER_HANDLE));
if (!pPrinterHandle)
{
@@ -845,12 +871,44 @@
BOOL WINAPI
LocalReadPrinter(HANDLE hPrinter, PVOID pBuf, DWORD cbBuf, PDWORD pNoBytesRead)
{
+ BOOL bReturnValue;
DWORD dwErrorCode;
PLOCAL_HANDLE pHandle = (PLOCAL_HANDLE)hPrinter;
+ PLOCAL_PORT_HANDLE pPortHandle;
PLOCAL_PRINTER_HANDLE pPrinterHandle;
// Sanity checks.
- if (!pHandle || pHandle->HandleType != HandleType_Printer)
+ if (!pHandle)
+ {
+ dwErrorCode = ERROR_INVALID_HANDLE;
+ goto Cleanup;
+ }
+
+ // Port handles are an entirely different thing.
+ if (pHandle->HandleType == HandleType_Port)
+ {
+ pPortHandle = (PLOCAL_PORT_HANDLE)pHandle->pSpecificHandle;
+
+ // Call the monitor's ReadPort function.
+ if (pPortHandle->pPort->pPrintMonitor->bIsLevel2)
+ bReturnValue =
((PMONITOR2)pPortHandle->pPort->pPrintMonitor->pMonitor)->pfnReadPort(pPortHandle->hPort,
pBuf, cbBuf, pNoBytesRead);
+ else
+ bReturnValue =
((LPMONITOREX)pPortHandle->pPort->pPrintMonitor->pMonitor)->Monitor.pfnReadPort(pPortHandle->hPort,
pBuf, cbBuf, pNoBytesRead);
+
+ if (!bReturnValue)
+ {
+ // The ReadPort function failed. Return its last error.
+ dwErrorCode = GetLastError();
+ goto Cleanup;
+ }
+
+ // We were successful!
+ dwErrorCode = ERROR_SUCCESS;
+ goto Cleanup;
+ }
+
+ // The remaining function deals with Printer handles only.
+ if (pHandle->HandleType != HandleType_Printer)
{
dwErrorCode = ERROR_INVALID_HANDLE;
goto Cleanup;
@@ -884,22 +942,62 @@
DWORD WINAPI
LocalStartDocPrinter(HANDLE hPrinter, DWORD Level, PBYTE pDocInfo)
{
+ BOOL bReturnValue;
DWORD dwErrorCode;
DWORD dwReturnValue = 0;
PDOC_INFO_1W pDocInfo1 = (PDOC_INFO_1W)pDocInfo;
+ PLOCAL_JOB pJob;
PLOCAL_HANDLE pHandle = (PLOCAL_HANDLE)hPrinter;
+ PLOCAL_PORT_HANDLE pPortHandle;
PLOCAL_PRINTER_HANDLE pPrinterHandle;
// Sanity checks.
+ if (!pHandle)
+ {
+ dwErrorCode = ERROR_INVALID_HANDLE;
+ goto Cleanup;
+ }
+
+ // Port handles are an entirely different thing.
+ if (pHandle->HandleType == HandleType_Port)
+ {
+ pPortHandle = (PLOCAL_PORT_HANDLE)pHandle->pSpecificHandle;
+
+ // This call should come from a Print Processor and the job this port is going to
print was assigned to us before opening the Print Processor.
+ // Claim it exclusively for this port handle.
+ pJob = pPortHandle->pPort->pNextJobToProcess;
+ pPortHandle->pPort->pNextJobToProcess = NULL;
+ ASSERT(pJob);
+
+ // Call the monitor's StartDocPort function.
+ if (pPortHandle->pPort->pPrintMonitor->bIsLevel2)
+ bReturnValue =
((PMONITOR2)pPortHandle->pPort->pPrintMonitor->pMonitor)->pfnStartDocPort(pPortHandle->hPort,
pJob->pPrinter->pwszPrinterName, pJob->dwJobID, Level, pDocInfo);
+ else
+ bReturnValue =
((LPMONITOREX)pPortHandle->pPort->pPrintMonitor->pMonitor)->Monitor.pfnStartDocPort(pPortHandle->hPort,
pJob->pPrinter->pwszPrinterName, pJob->dwJobID, Level, pDocInfo);
+
+ if (!bReturnValue)
+ {
+ // The StartDocPort function failed. Return its last error.
+ dwErrorCode = GetLastError();
+ goto Cleanup;
+ }
+
+ // We were successful!
+ dwErrorCode = ERROR_SUCCESS;
+ dwReturnValue = pJob->dwJobID;
+ goto Cleanup;
+ }
+
+ // The remaining function deals with Printer handles only.
+ if (pHandle->HandleType != HandleType_Printer)
+ {
+ dwErrorCode = ERROR_INVALID_HANDLE;
+ goto Cleanup;
+ }
+
if (!pDocInfo1)
{
dwErrorCode = ERROR_INVALID_PARAMETER;
- goto Cleanup;
- }
-
- if (!pHandle || pHandle->HandleType != HandleType_Printer)
- {
- dwErrorCode = ERROR_INVALID_HANDLE;
goto Cleanup;
}
@@ -989,14 +1087,46 @@
}
BOOL WINAPI
-LocalWritePrinter(HANDLE hPrinter, LPVOID pBuf, DWORD cbBuf, LPDWORD pcWritten)
+LocalWritePrinter(HANDLE hPrinter, PVOID pBuf, DWORD cbBuf, PDWORD pcWritten)
{
+ BOOL bReturnValue;
DWORD dwErrorCode;
PLOCAL_HANDLE pHandle = (PLOCAL_HANDLE)hPrinter;
+ PLOCAL_PORT_HANDLE pPortHandle;
PLOCAL_PRINTER_HANDLE pPrinterHandle;
// Sanity checks.
- if (!pHandle || pHandle->HandleType != HandleType_Printer)
+ if (!pHandle)
+ {
+ dwErrorCode = ERROR_INVALID_HANDLE;
+ goto Cleanup;
+ }
+
+ // Port handles are an entirely different thing.
+ if (pHandle->HandleType == HandleType_Port)
+ {
+ pPortHandle = (PLOCAL_PORT_HANDLE)pHandle->pSpecificHandle;
+
+ // Call the monitor's WritePort function.
+ if (pPortHandle->pPort->pPrintMonitor->bIsLevel2)
+ bReturnValue =
((PMONITOR2)pPortHandle->pPort->pPrintMonitor->pMonitor)->pfnWritePort(pPortHandle->hPort,
pBuf, cbBuf, pcWritten);
+ else
+ bReturnValue =
((LPMONITOREX)pPortHandle->pPort->pPrintMonitor->pMonitor)->Monitor.pfnWritePort(pPortHandle->hPort,
pBuf, cbBuf, pcWritten);
+
+ if (!bReturnValue)
+ {
+ // The WritePort function failed. Return its last error.
+ dwErrorCode = GetLastError();
+ goto Cleanup;
+ }
+
+ // We were successful!
+ dwErrorCode = ERROR_SUCCESS;
+ goto Cleanup;
+ }
+
+ // The remaining function deals with Printer handles only.
+ if (pHandle->HandleType != HandleType_Printer)
{
dwErrorCode = ERROR_INVALID_HANDLE;
goto Cleanup;
@@ -1054,12 +1184,44 @@
BOOL WINAPI
LocalEndDocPrinter(HANDLE hPrinter)
{
+ BOOL bReturnValue;
DWORD dwErrorCode;
PLOCAL_HANDLE pHandle = (PLOCAL_HANDLE)hPrinter;
+ PLOCAL_PORT_HANDLE pPortHandle;
PLOCAL_PRINTER_HANDLE pPrinterHandle;
// Sanity checks.
- if (!pHandle || pHandle->HandleType != HandleType_Printer)
+ if (!pHandle)
+ {
+ dwErrorCode = ERROR_INVALID_HANDLE;
+ goto Cleanup;
+ }
+
+ // Port handles are an entirely different thing.
+ if (pHandle->HandleType == HandleType_Port)
+ {
+ pPortHandle = (PLOCAL_PORT_HANDLE)pHandle->pSpecificHandle;
+
+ // Call the monitor's EndDocPort function.
+ if (pPortHandle->pPort->pPrintMonitor->bIsLevel2)
+ bReturnValue =
((PMONITOR2)pPortHandle->pPort->pPrintMonitor->pMonitor)->pfnEndDocPort(pPortHandle->hPort);
+ else
+ bReturnValue =
((LPMONITOREX)pPortHandle->pPort->pPrintMonitor->pMonitor)->Monitor.pfnEndDocPort(pPortHandle->hPort);
+
+ if (!bReturnValue)
+ {
+ // The EndDocPort function failed. Return its last error.
+ dwErrorCode = GetLastError();
+ goto Cleanup;
+ }
+
+ // We were successful!
+ dwErrorCode = ERROR_SUCCESS;
+ goto Cleanup;
+ }
+
+ // The remaining function deals with Printer handles only.
+ if (pHandle->HandleType != HandleType_Printer)
{
dwErrorCode = ERROR_INVALID_HANDLE;
goto Cleanup;
@@ -1090,7 +1252,9 @@
LocalClosePrinter(HANDLE hPrinter)
{
PLOCAL_HANDLE pHandle = (PLOCAL_HANDLE)hPrinter;
+ PLOCAL_PORT_HANDLE pPortHandle;
PLOCAL_PRINTER_HANDLE pPrinterHandle;
+ PLOCAL_XCV_HANDLE pXcvHandle;
if (!pHandle)
{
@@ -1100,7 +1264,13 @@
if (pHandle->HandleType == HandleType_Port)
{
- // TODO
+ pPortHandle = (PLOCAL_PORT_HANDLE)pHandle->pSpecificHandle;
+
+ // Call the monitor's ClosePort function.
+ if (pPortHandle->pPort->pPrintMonitor->bIsLevel2)
+
((PMONITOR2)pPortHandle->pPort->pPrintMonitor->pMonitor)->pfnClosePort(pPortHandle->hPort);
+ else
+
((LPMONITOREX)pPortHandle->pPort->pPrintMonitor->pMonitor)->Monitor.pfnClosePort(pPortHandle->hPort);
}
else if (pHandle->HandleType == HandleType_Printer)
{
@@ -1113,16 +1283,20 @@
// Free memory for the fields.
DllFreeSplMem(pPrinterHandle->pDevMode);
DllFreeSplStr(pPrinterHandle->pwszDatatype);
-
- // Free memory for the printer handle itself.
- DllFreeSplMem(pPrinterHandle);
}
else if (pHandle->HandleType == HandleType_Xcv)
{
- // TODO
- }
-
- // Free memory for the handle itself.
+ pXcvHandle = (PLOCAL_XCV_HANDLE)pHandle->pSpecificHandle;
+
+ // Call the monitor's XcvClosePort function.
+ if (pXcvHandle->pPrintMonitor->bIsLevel2)
+
((PMONITOR2)pXcvHandle->pPrintMonitor->pMonitor)->pfnXcvClosePort(pXcvHandle->hXcv);
+ else
+
((LPMONITOREX)pXcvHandle->pPrintMonitor->pMonitor)->Monitor.pfnXcvClosePort(pXcvHandle->hXcv);
+ }
+
+ // Free memory for the handle and the specific handle.
+ DllFreeSplMem(pHandle->pSpecificHandle);
DllFreeSplMem(pHandle);
return TRUE;
Modified:
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/printingthread.c
URL:
http://svn.reactos.org/svn/reactos/branches/colins-printing-for-freedom/rea…
==============================================================================
---
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/printingthread.c [iso-8859-1]
(original)
+++
branches/colins-printing-for-freedom/reactos/win32ss/printing/providers/localspl/printingthread.c [iso-8859-1]
Wed Jul 22 12:44:22 2015
@@ -47,6 +47,11 @@
OpenData.pOutputFile = NULL;
OpenData.pParameters = pJob->pwszPrintProcessorParameters;
OpenData.pPrinterName = pJob->pPrinter->pwszPrinterName;
+
+ // Associate our job to the port. The next port handle created through
LocalOpenPrinter will pick this up.
+ // LocalStartDocPrinter needs this information to call StartDocPort of the Print
Monitor, but as the parameters
+ // for LocalOpenPrinter and LocalStartDocPrinter are fixed, we can only pass over the
information this way.
+ pJob->pPrinter->pPort->pNextJobToProcess = pJob;
// Open a handle to the Print Processor.
hPrintProcessor = pPrintProcessor->pfnOpenPrintProcessor(pwszPrinterPort,
&OpenData);