From: Colin Finck Date: Sat, 27 Jun 2015 15:37:14 +0000 (+0000) Subject: [LOCALSPL] X-Git-Tag: backups/colins-printing-for-freedom@73041~41 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=b0bc4bb807b8fb7dc0f2e95ba2be5e0fe5c73751 [LOCALSPL] - Write the shadow file after changing job details. - dwUnknown2 in the shadow file header is actually the offset of the Print Processor Parameters. - Process all known fields of the shadow file in ReadJobShadowFile and WriteJobShadowFile. svn path=/branches/colins-printing-for-freedom/; revision=68292 --- diff --git a/reactos/win32ss/printing/providers/localspl/jobs.c b/reactos/win32ss/printing/providers/localspl/jobs.c index cd5f68b3198..1ffe281ffbb 100644 --- a/reactos/win32ss/printing/providers/localspl/jobs.c +++ b/reactos/win32ss/printing/providers/localspl/jobs.c @@ -831,10 +831,14 @@ Cleanup: BOOL WINAPI LocalSetJob(HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pJobInfo, DWORD Command) { + const WCHAR wszFolder[] = L"\\PRINTERS\\"; + const DWORD cchFolder = _countof(wszFolder) - 1; + DWORD dwErrorCode; PLOCAL_HANDLE pHandle; PLOCAL_JOB pJob; PLOCAL_PRINTER_HANDLE pPrinterHandle; + WCHAR wszFullPath[MAX_PATH]; // Check if this is a printer handle. pHandle = (PLOCAL_HANDLE)hPrinter; @@ -868,6 +872,14 @@ LocalSetJob(HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pJobInfo, DWORD Com if (dwErrorCode != ERROR_SUCCESS) goto Cleanup; + // Construct the full path to the shadow file. + CopyMemory(wszFullPath, wszSpoolDirectory, cchSpoolDirectory * sizeof(WCHAR)); + CopyMemory(&wszFullPath[cchSpoolDirectory], wszFolder, cchFolder * sizeof(WCHAR)); + swprintf(&wszFullPath[cchSpoolDirectory + cchFolder], L"%05lu.SHD", JobId); + + // Write the job data into the shadow file. + WriteJobShadowFile(wszFullPath, pJob); + // Perform an additional command if desired. if (Command) { @@ -983,8 +995,10 @@ ReadJobShadowFile(PCWSTR pwszFilePath) PLOCAL_JOB pJob; PLOCAL_JOB pReturnValue = NULL; PLOCAL_PRINTER pPrinter; + PLOCAL_PRINT_PROCESSOR pPrintProcessor; PSHD_HEADER pShadowFile = NULL; PWSTR pwszPrinterName; + PWSTR pwszPrintProcessor; // Try to open the file. hFile = CreateFileW(pwszFilePath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); @@ -1022,7 +1036,16 @@ ReadJobShadowFile(PCWSTR pwszFilePath) pPrinter = LookupElementSkiplist(&PrinterList, &pwszPrinterName, NULL); if (!pPrinter) { - ERR("Shadow file \"%S\" references a non-existing printer!\n", pwszFilePath); + ERR("Shadow file \"%S\" references a non-existing printer \"%S\"!\n", pwszFilePath, pwszPrinterName); + goto Cleanup; + } + + // Retrieve the associated Print Processor from the list. + pwszPrintProcessor = (PWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offPrintProcessor); + pPrintProcessor = FindPrintProcessor(pwszPrintProcessor); + if (!pPrintProcessor) + { + ERR("Shadow file \"%S\" references a non-existing Print Processor \"%S\"!\n", pwszFilePath, pwszPrintProcessor); goto Cleanup; } @@ -1035,12 +1058,22 @@ ReadJobShadowFile(PCWSTR pwszFilePath) } pJob->dwJobID = pShadowFile->dwJobID; - pJob->dwTotalPages = pShadowFile->dwTotalPages; pJob->dwPriority = pShadowFile->dwPriority; + pJob->dwStartTime = pShadowFile->dwStartTime; + pJob->dwTotalPages = pShadowFile->dwTotalPages; + pJob->dwUntilTime = pShadowFile->dwUntilTime; pJob->pPrinter = pPrinter; + pJob->pPrintProcessor = pPrintProcessor; pJob->pwszDatatype = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offDatatype)); pJob->pwszDocumentName = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offDocumentName)); - pJob->pwszOutputFile = NULL; + pJob->pwszMachineName = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offMachineName)); + pJob->pwszNotifyName = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offNotifyName)); + + if (pShadowFile->offPrintProcessorParameters) + 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)); @@ -1057,31 +1090,48 @@ Cleanup: } BOOL -WriteJobShadowFile(PCWSTR pwszFilePath, const PLOCAL_JOB pJob) +WriteJobShadowFile(PWSTR pwszFilePath, const PLOCAL_JOB pJob) { BOOL bReturnValue = FALSE; DWORD cbDatatype; DWORD cbDocumentName; DWORD cbFileSize; + DWORD cbMachineName; + DWORD cbNotifyName; + DWORD cbPrinterDriver; DWORD cbPrinterName; + DWORD cbPrintProcessor; + DWORD cbPrintProcessorParameters = 0; + DWORD cbUserName; DWORD cbWritten; DWORD dwCurrentOffset; - HANDLE hFile = INVALID_HANDLE_VALUE; + HANDLE hSHDFile = INVALID_HANDLE_VALUE; + HANDLE hSPLFile = INVALID_HANDLE_VALUE; PSHD_HEADER pShadowFile = NULL; - // Try to open the file. - hFile = CreateFileW(pwszFilePath, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, 0, NULL); - if (hFile == INVALID_HANDLE_VALUE) + // Try to open the SHD file. + hSHDFile = CreateFileW(pwszFilePath, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, 0, NULL); + if (hSHDFile == INVALID_HANDLE_VALUE) { ERR("CreateFileW failed with error %lu for file \"%S\"!\n", GetLastError(), pwszFilePath); goto Cleanup; } // Compute the total size of the shadow file. - cbPrinterName = (wcslen(pJob->pPrinter->pwszPrinterName) + 1) * sizeof(WCHAR); cbDatatype = (wcslen(pJob->pwszDatatype) + 1) * sizeof(WCHAR); cbDocumentName = (wcslen(pJob->pwszDocumentName) + 1) * sizeof(WCHAR); - cbFileSize = sizeof(SHD_HEADER) + cbPrinterName + cbDatatype + cbDocumentName + sizeof(DEVMODEW); + cbMachineName = (wcslen(pJob->pwszMachineName) + 1) * sizeof(WCHAR); + cbNotifyName = (wcslen(pJob->pwszNotifyName) + 1) * sizeof(WCHAR); + cbPrinterDriver = (wcslen(pJob->pPrinter->pwszPrinterDriver) + 1) * sizeof(WCHAR); + cbPrinterName = (wcslen(pJob->pPrinter->pwszPrinterName) + 1) * sizeof(WCHAR); + cbPrintProcessor = (wcslen(pJob->pPrintProcessor->pwszName) + 1) * sizeof(WCHAR); + cbUserName = (wcslen(pJob->pwszUserName) + 1) * sizeof(WCHAR); + + // Print Processor Parameters are optional. + 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; // Allocate memory for it. pShadowFile = DllAllocSplMem(cbFileSize); @@ -1097,18 +1147,22 @@ WriteJobShadowFile(PCWSTR pwszFilePath, const PLOCAL_JOB pJob) // Copy the values. pShadowFile->dwJobID = pJob->dwJobID; - pShadowFile->dwTotalPages = pJob->dwTotalPages; pShadowFile->dwPriority = pJob->dwPriority; + pShadowFile->dwStartTime = pJob->dwStartTime; + pShadowFile->dwTotalPages = pJob->dwTotalPages; + pShadowFile->dwUntilTime = pJob->dwUntilTime; CopyMemory(&pShadowFile->stSubmitted, &pJob->stSubmitted, sizeof(SYSTEMTIME)); + // Determine the file size of the .SPL file + wcscpy(wcsrchr(pwszFilePath, L'.'), L".SPL"); + hSPLFile = CreateFileW(pwszFilePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + if (hSPLFile != INVALID_HANDLE_VALUE) + pShadowFile->dwSPLSize = GetFileSize(hSPLFile, NULL); + // Add the extra values that are stored as offsets in the shadow file. // The first value begins right after the shadow file header. dwCurrentOffset = sizeof(SHD_HEADER); - CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pPrinter->pwszPrinterName, cbPrinterName); - pShadowFile->offPrinterName = dwCurrentOffset; - dwCurrentOffset += cbPrinterName; - CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pwszDatatype, cbDatatype); pShadowFile->offDatatype = dwCurrentOffset; dwCurrentOffset += cbDatatype; @@ -1121,8 +1175,40 @@ WriteJobShadowFile(PCWSTR pwszFilePath, const PLOCAL_JOB pJob) pShadowFile->offDevMode = dwCurrentOffset; dwCurrentOffset += sizeof(DEVMODEW); + // offDriverName is only written, but automatically determined through offPrinterName when reading. + CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pPrinter->pwszPrinterDriver, cbPrinterDriver); + pShadowFile->offDriverName = dwCurrentOffset; + dwCurrentOffset += cbPrinterDriver; + + CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pwszMachineName, cbMachineName); + pShadowFile->offMachineName = dwCurrentOffset; + dwCurrentOffset += cbMachineName; + + CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pwszNotifyName, cbNotifyName); + pShadowFile->offNotifyName = dwCurrentOffset; + dwCurrentOffset += cbNotifyName; + + CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pPrinter->pwszPrinterName, cbPrinterName); + pShadowFile->offPrinterName = dwCurrentOffset; + dwCurrentOffset += cbPrinterName; + + CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pPrintProcessor->pwszName, cbPrintProcessor); + pShadowFile->offPrintProcessor = dwCurrentOffset; + dwCurrentOffset += cbPrintProcessor; + + if (cbPrintProcessorParameters) + { + CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pwszPrintProcessorParameters, cbPrintProcessorParameters); + pShadowFile->offPrintProcessorParameters = dwCurrentOffset; + dwCurrentOffset += cbPrintProcessorParameters; + } + + CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pwszUserName, cbUserName); + pShadowFile->offUserName = dwCurrentOffset; + dwCurrentOffset += cbUserName; + // Write the file. - if (!WriteFile(hFile, pShadowFile, cbFileSize, &cbWritten, NULL)) + if (!WriteFile(hSHDFile, pShadowFile, cbFileSize, &cbWritten, NULL)) { ERR("WriteFile failed with error %lu for file \"%S\"!\n", GetLastError(), pwszFilePath); goto Cleanup; @@ -1134,8 +1220,11 @@ Cleanup: if (pShadowFile) DllFreeSplMem(pShadowFile); - if (hFile != INVALID_HANDLE_VALUE) - CloseHandle(hFile); + if (hSHDFile != INVALID_HANDLE_VALUE) + CloseHandle(hSHDFile); + + if (hSPLFile != INVALID_HANDLE_VALUE) + CloseHandle(hSPLFile); return bReturnValue; } diff --git a/reactos/win32ss/printing/providers/localspl/precomp.h b/reactos/win32ss/printing/providers/localspl/precomp.h index a15226b608a..a7f45db7f03 100644 --- a/reactos/win32ss/printing/providers/localspl/precomp.h +++ b/reactos/win32ss/printing/providers/localspl/precomp.h @@ -164,7 +164,7 @@ typedef struct _SHD_HEADER DWORD offDevMode; DWORD offPrintProcessor; DWORD offDatatype; - DWORD dwUnknown2; + DWORD offPrintProcessorParameters; SYSTEMTIME stSubmitted; DWORD dwStartTime; DWORD dwUntilTime; @@ -191,7 +191,7 @@ BOOL WINAPI LocalEnumJobs(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD L BOOL WINAPI LocalGetJob(HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pStart, DWORD cbBuf, LPDWORD pcbNeeded); BOOL WINAPI LocalSetJob(HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pJobInfo, DWORD Command); PLOCAL_JOB ReadJobShadowFile(PCWSTR pwszFilePath); -BOOL WriteJobShadowFile(PCWSTR pwszFilePath, const PLOCAL_JOB pJob); +BOOL WriteJobShadowFile(PWSTR pwszFilePath, const PLOCAL_JOB pJob); // main.c extern const WCHAR wszCurrentEnvironment[];