From: Colin Finck Date: Wed, 8 Jul 2015 12:35:35 +0000 (+0000) Subject: [LOCALSPL] X-Git-Tag: backups/colins-printing-for-freedom@73041~31 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=7ed643eb9c06a94772c5a66f00b5cba98c28a8d4 [LOCALSPL] Bugfix: Copy the full DevMode including the extra data by the driver. svn path=/branches/colins-printing-for-freedom/; revision=68379 --- diff --git a/reactos/win32ss/printing/providers/localspl/jobs.c b/reactos/win32ss/printing/providers/localspl/jobs.c index fd7c7fc77c0..47ca6afe5aa 100644 --- a/reactos/win32ss/printing/providers/localspl/jobs.c +++ b/reactos/win32ss/printing/providers/localspl/jobs.c @@ -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); diff --git a/reactos/win32ss/printing/providers/localspl/precomp.h b/reactos/win32ss/printing/providers/localspl/precomp.h index 7447ef4f897..1153081ba35 100644 --- a/reactos/win32ss/printing/providers/localspl/precomp.h +++ b/reactos/win32ss/printing/providers/localspl/precomp.h @@ -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 diff --git a/reactos/win32ss/printing/providers/localspl/printers.c b/reactos/win32ss/printing/providers/localspl/printers.c index b121dea6269..05407352c88 100644 --- a/reactos/win32ss/printing/providers/localspl/printers.c +++ b/reactos/win32ss/printing/providers/localspl/printers.c @@ -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) diff --git a/reactos/win32ss/printing/providers/localspl/tools.c b/reactos/win32ss/printing/providers/localspl/tools.c index ef6ef5006b5..06f3c1bbf0e 100644 --- a/reactos/win32ss/printing/providers/localspl/tools.c +++ b/reactos/win32ss/printing/providers/localspl/tools.c @@ -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; +}