[LOCALSPL]
authorColin Finck <colin@reactos.org>
Wed, 8 Jul 2015 12:35:35 +0000 (12:35 +0000)
committerColin Finck <colin@reactos.org>
Wed, 8 Jul 2015 12:35:35 +0000 (12:35 +0000)
Bugfix: Copy the full DevMode including the extra data by the driver.

svn path=/branches/colins-printing-for-freedom/; revision=68379

reactos/win32ss/printing/providers/localspl/jobs.c
reactos/win32ss/printing/providers/localspl/precomp.h
reactos/win32ss/printing/providers/localspl/printers.c
reactos/win32ss/printing/providers/localspl/tools.c

index fd7c7fc..47ca6af 100644 (file)
@@ -279,7 +279,7 @@ LocalAddJob(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcb
     pJob->dwStatus = JOB_STATUS_SPOOLING;
     pJob->pwszDatatype = AllocSplStr(pPrinterHandle->pwszDatatype);
     pJob->pwszDocumentName = AllocSplStr(wszDefaultDocumentName);
-    CopyMemory(&pJob->DevMode, &pPrinterHandle->DevMode, sizeof(DEVMODEW));
+    pJob->pDevMode = DuplicateDevMode(pPrinterHandle->pDevMode);
     GetSystemTime(&pJob->stSubmitted);
 
     // Get the user name for the Job.
@@ -440,6 +440,7 @@ static DWORD
 _LocalGetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE* ppStart, PBYTE* ppEnd, DWORD cbBuf, PDWORD pcbNeeded)
 {
     DWORD cbDatatype = (wcslen(pJob->pwszDatatype) + 1) * sizeof(WCHAR);
+    DWORD cbDevMode = pJob->pDevMode->dmSize + pJob->pDevMode->dmDriverExtra;
     DWORD cbDocumentName = (wcslen(pJob->pwszDocumentName) + 1) * sizeof(WCHAR);
     DWORD cbDriverName = (wcslen(pJob->pPrinter->pwszPrinterDriver) + 1) * sizeof(WCHAR);
     DWORD cbMachineName = (wcslen(pJob->pwszMachineName) + 1) * sizeof(WCHAR);
@@ -464,7 +465,7 @@ _LocalGetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE*
         cbStatus = (wcslen(pJob->pwszStatus) + 1) * sizeof(WCHAR);
 
     // Check if the supplied buffer is large enough.
-    *pcbNeeded += sizeof(JOB_INFO_2W) + cbDatatype + sizeof(DEVMODEW) + cbDocumentName + cbDriverName + cbMachineName + cbNotifyName + cbPrinterName + cbPrintProcessor + cbPrintProcessorParameters + cbStatus + cbUserName;
+    *pcbNeeded += sizeof(JOB_INFO_2W) + cbDatatype + cbDevMode + cbDocumentName + cbDriverName + cbMachineName + cbNotifyName + cbPrinterName + cbPrintProcessor + cbPrintProcessorParameters + cbStatus + cbUserName;
     if (cbBuf < *pcbNeeded)
     {
         dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
@@ -476,9 +477,9 @@ _LocalGetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE*
     JobInfo2.pDatatype = (PWSTR)*ppEnd;
     CopyMemory(*ppEnd, pJob->pwszDatatype, cbDatatype);
 
-    *ppEnd -= sizeof(DEVMODEW);
+    *ppEnd -= cbDevMode;
     JobInfo2.pDevMode = (PDEVMODEW)*ppEnd;
-    CopyMemory(*ppEnd, &pJob->DevMode, sizeof(DEVMODEW));
+    CopyMemory(*ppEnd, pJob->pDevMode, cbDevMode);
 
     *ppEnd -= cbDocumentName;
     JobInfo2.pDocument = (PWSTR)*ppEnd;
@@ -1136,6 +1137,7 @@ ReadJobShadowFile(PCWSTR pwszFilePath)
     pJob->dwUntilTime = pShadowFile->dwUntilTime;    
     pJob->pPrinter = pPrinter;
     pJob->pPrintProcessor = pPrintProcessor;
+    pJob->pDevMode = DuplicateDevMode((PDEVMODEW)((ULONG_PTR)pShadowFile + pShadowFile->offDevMode));
     pJob->pwszDatatype = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offDatatype));
     pJob->pwszDocumentName = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offDocumentName));
     pJob->pwszMachineName = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offMachineName));
@@ -1145,9 +1147,7 @@ ReadJobShadowFile(PCWSTR pwszFilePath)
         pJob->pwszPrintProcessorParameters = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offPrintProcessorParameters));
 
     pJob->pwszUserName = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offUserName));
-
     CopyMemory(&pJob->stSubmitted, &pShadowFile->stSubmitted, sizeof(SYSTEMTIME));
-    CopyMemory(&pJob->DevMode, (PDEVMODEW)((ULONG_PTR)pShadowFile + pShadowFile->offDevMode), sizeof(DEVMODEW));
 
     pReturnValue = pJob;
 
@@ -1166,6 +1166,7 @@ WriteJobShadowFile(PWSTR pwszFilePath, const PLOCAL_JOB pJob)
 {
     BOOL bReturnValue = FALSE;
     DWORD cbDatatype;
+    DWORD cbDevMode;
     DWORD cbDocumentName;
     DWORD cbFileSize;
     DWORD cbMachineName;
@@ -1191,6 +1192,7 @@ WriteJobShadowFile(PWSTR pwszFilePath, const PLOCAL_JOB pJob)
 
     // Compute the total size of the shadow file.
     cbDatatype = (wcslen(pJob->pwszDatatype) + 1) * sizeof(WCHAR);
+    cbDevMode = pJob->pDevMode->dmSize + pJob->pDevMode->dmDriverExtra;
     cbDocumentName = (wcslen(pJob->pwszDocumentName) + 1) * sizeof(WCHAR);
     cbMachineName = (wcslen(pJob->pwszMachineName) + 1) * sizeof(WCHAR);
     cbNotifyName = (wcslen(pJob->pwszNotifyName) + 1) * sizeof(WCHAR);
@@ -1203,7 +1205,7 @@ WriteJobShadowFile(PWSTR pwszFilePath, const PLOCAL_JOB pJob)
     if (pJob->pwszPrintProcessorParameters)
         cbPrintProcessorParameters = (wcslen(pJob->pwszPrintProcessorParameters) + 1) * sizeof(WCHAR);
 
-    cbFileSize = sizeof(SHD_HEADER) + cbDatatype + cbDocumentName + sizeof(DEVMODEW) + cbMachineName + cbNotifyName + cbPrinterDriver + cbPrinterName + cbPrintProcessor + cbPrintProcessorParameters + cbUserName;
+    cbFileSize = sizeof(SHD_HEADER) + cbDatatype + cbDocumentName + cbDevMode + cbMachineName + cbNotifyName + cbPrinterDriver + cbPrinterName + cbPrintProcessor + cbPrintProcessorParameters + cbUserName;
 
     // Allocate memory for it.
     pShadowFile = DllAllocSplMem(cbFileSize);
@@ -1243,9 +1245,9 @@ WriteJobShadowFile(PWSTR pwszFilePath, const PLOCAL_JOB pJob)
     pShadowFile->offDocumentName = dwCurrentOffset;
     dwCurrentOffset += cbDocumentName;
 
-    CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, &pJob->DevMode, sizeof(DEVMODEW));
+    CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pDevMode, cbDevMode);
     pShadowFile->offDevMode = dwCurrentOffset;
-    dwCurrentOffset += sizeof(DEVMODEW);
+    dwCurrentOffset += cbDevMode;
 
     // offDriverName is only written, but automatically determined through offPrinterName when reading.
     CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pPrinter->pwszPrinterDriver, cbPrinterDriver);
index 7447ef4..1153081 100644 (file)
@@ -81,7 +81,7 @@ typedef struct _LOCAL_PRINTER
     PWSTR pwszPrinterDriver;
     PWSTR pwszDescription;
     PWSTR pwszDefaultDatatype;
-    DEVMODEW DefaultDevMode;
+    PDEVMODEW pDefaultDevMode;
     PLOCAL_PRINT_PROCESSOR pPrintProcessor;
     SKIPLIST JobList;
 }
@@ -113,7 +113,7 @@ typedef struct _LOCAL_JOB
     DWORD dwUntilTime;                          // Latest time in minutes since 12:00 AM UTC when this document can be printed
     DWORD dwStatus;                             // JOB_STATUS_* flags of the Job
     PWSTR pwszMachineName;                      // Name of the machine that submitted the Job (prepended with two backslashes)
-    DEVMODEW DevMode;                           // Associated Device Mode to this Job
+    PDEVMODEW pDevMode;                         // Associated Device Mode to this Job
 }
 LOCAL_JOB, *PLOCAL_JOB;
 
@@ -129,7 +129,7 @@ typedef struct _LOCAL_PRINTER_HANDLE
     PLOCAL_PRINTER pPrinter;
     PLOCAL_JOB pStartedJob;
     PWSTR pwszDatatype;
-    DEVMODEW DevMode;
+    PDEVMODEW pDevMode;
 }
 LOCAL_PRINTER_HANDLE, *PLOCAL_PRINTER_HANDLE;
 
@@ -249,5 +249,6 @@ BOOL WINAPI LocalGetPrintProcessorDirectory(LPWSTR pName, LPWSTR pEnvironment, D
 
 // tools.c
 PWSTR AllocAndRegQueryWSZ(HKEY hKey, PCWSTR pwszValueName);
+PDEVMODEW DuplicateDevMode(PDEVMODEW pInput);
 
 #endif
index b121dea..0540735 100644 (file)
@@ -81,6 +81,9 @@ InitializePrinterList()
 
         if (pPrinter)
         {
+            if (pPrinter->pDefaultDevMode)
+                DllFreeSplMem(pPrinter->pDefaultDevMode);
+
             if (pPrinter->pwszDefaultDatatype)
                 DllFreeSplStr(pPrinter->pwszDefaultDatatype);
 
@@ -173,12 +176,28 @@ InitializePrinterList()
             continue;
         }
 
+        // Determine the size of the DevMode.
+        dwErrorCode = (DWORD)RegQueryValueExW(hSubKey, L"Default DevMode", NULL, NULL, NULL, &cbData);
+        if (dwErrorCode != ERROR_SUCCESS)
+        {
+            ERR("Couldn't query the size of the DevMode for Printer \"%S\", status is %lu, cbData is %lu!\n", wszPrinterName, dwErrorCode, cbData);
+            continue;
+        }
+
+        // Allocate enough memory for the DevMode.
+        pPrinter->pDefaultDevMode = DllAllocSplMem(cbData);
+        if (!pPrinter->pDefaultDevMode)
+        {
+            dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
+            ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
+            goto Cleanup;
+        }
+
         // Get the default DevMode.
-        cbData = sizeof(DEVMODEW);
-        dwErrorCode = (DWORD)RegQueryValueExW(hSubKey, L"Default DevMode", NULL, NULL, (PBYTE)&pPrinter->DefaultDevMode, &cbData);
-        if (dwErrorCode != ERROR_SUCCESS || cbData != sizeof(DEVMODEW))
+        dwErrorCode = (DWORD)RegQueryValueExW(hSubKey, L"Default DevMode", NULL, NULL, (PBYTE)pPrinter->pDefaultDevMode, &cbData);
+        if (dwErrorCode != ERROR_SUCCESS)
         {
-            ERR("Couldn't query a valid DevMode for Printer \"%S\", status is %lu, cbData is %lu!\n", wszPrinterName, dwErrorCode, cbData);
+            ERR("Couldn't query a DevMode for Printer \"%S\", status is %lu, cbData is %lu!\n", wszPrinterName, dwErrorCode, cbData);
             continue;
         }
 
@@ -220,6 +239,9 @@ Cleanup:
 
     if (pPrinter)
     {
+        if (pPrinter->pDefaultDevMode)
+            DllFreeSplMem(pPrinter->pDefaultDevMode);
+
         if (pPrinter->pwszDefaultDatatype)
             DllFreeSplStr(pPrinter->pwszDefaultDatatype);
 
@@ -567,9 +589,9 @@ LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDef
 
         // Check if a DevMode was given, otherwise use the default.
         if (pDefault && pDefault->pDevMode)
-            CopyMemory(&pPrinterHandle->DevMode, pDefault->pDevMode, sizeof(DEVMODEW));
+            pPrinterHandle->pDevMode = DuplicateDevMode(pDefault->pDevMode);
         else
-            CopyMemory(&pPrinterHandle->DevMode, &pPrinter->DefaultDevMode, sizeof(DEVMODEW));
+            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)
@@ -753,7 +775,7 @@ LocalStartDocPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo)
     }
 
     // Copy over printer defaults.
-    CopyMemory(&pJob->DevMode, &pPrinterHandle->DevMode, sizeof(DEVMODEW));
+    pJob->pDevMode = DuplicateDevMode(pPrinterHandle->pDevMode);
 
     // Copy over supplied information.
     if (pDocumentInfo1->pDocName)
index ef6ef50..06f3c1b 100644 (file)
@@ -56,3 +56,22 @@ AllocAndRegQueryWSZ(HKEY hKey, PCWSTR pwszValueName)
 
     return pwszValue;
 }
+
+PDEVMODEW
+DuplicateDevMode(PDEVMODEW pInput)
+{
+    PDEVMODEW pOutput;
+
+    // Allocate a buffer for this DevMode.
+    pOutput = DllAllocSplMem(pInput->dmSize + pInput->dmDriverExtra);
+    if (!pOutput)
+    {
+        ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
+        return NULL;
+    }
+
+    // Copy it.
+    CopyMemory(pOutput, pInput, pInput->dmSize + pInput->dmDriverExtra);
+
+    return pOutput;
+}