It's bugfixing time!

[LOCALSPL]
- A Print Job has more optional fields than I thought. Only do a wcslen on them if they are not NULL.
- Make the code for checking changed fields more robust. Add checks for NULL to the Find and Compare functions.
- Fix some wrong parameters given to CopyMemory.
- Set the pPort field of a LOCAL_PRINTER structure.

[WINSPOOL]
Only pass the datatype from the DOC_INFO_1W structure of StartDocPrinterW to SetJobW if it's not NULL.
For StartDocPrinterW, this means that the datatype shall not be changed while SetJobW would return ERROR_INVALID_DATATYPE if none was passed.

svn path=/branches/colins-printing-for-freedom/; revision=68471
This commit is contained in:
Colin Finck 2015-07-20 15:21:03 +00:00
parent 9995ecdc6c
commit 087c85a5d3
7 changed files with 176 additions and 85 deletions

View file

@ -89,7 +89,9 @@ _StartDocPrinterSpooled(PSPOOLER_HANDLE pHandle, PDOC_INFO_1W pDocInfo1, PADDJOB
}
// Add our document information.
pJobInfo1->pDatatype = pDocInfo1->pDatatype;
if (pDocInfo1->pDatatype)
pJobInfo1->pDatatype = pDocInfo1->pDatatype;
pJobInfo1->pDocument = pDocInfo1->pDocName;
// Set the new job information.

View file

@ -14,6 +14,36 @@ SKIPLIST GlobalJobList;
static DWORD _dwLastJobID;
/**
* @name _EqualStrings
*
* Returns whether two strings are equal.
* Unlike wcscmp, this function also works with NULL strings.
*
* @param pwszA
* First string to compare.
*
* @param pwszB
* Second string to compare.
*
* @return
* TRUE if the strings are equal, FALSE if they differ.
*/
static __inline BOOL
_EqualStrings(PCWSTR pwszA, PCWSTR pwszB)
{
if (!pwszA && !pwszB)
return TRUE;
if (pwszA && !pwszB)
return FALSE;
if (!pwszA && pwszB)
return FALSE;
return (wcscmp(pwszA, pwszB) == 0);
}
static BOOL
_GetNextJobID(PDWORD dwJobID)
{
@ -112,8 +142,8 @@ GetJobFilePath(PCWSTR pwszExtension, DWORD dwJobID, PWSTR pwszOutput)
if (pwszOutput)
{
CopyMemory(pwszOutput, wszSpoolDirectory, cchSpoolDirectory);
CopyMemory(&pwszOutput[cchSpoolDirectory], wszPrintersPath, cchPrintersPath);
CopyMemory(pwszOutput, wszSpoolDirectory, cchSpoolDirectory * sizeof(WCHAR));
CopyMemory(&pwszOutput[cchSpoolDirectory], wszPrintersPath, cchPrintersPath * sizeof(WCHAR));
swprintf(&pwszOutput[cchSpoolDirectory + cchPrintersPath], L"%05lu.", dwJobID);
CopyMemory(&pwszOutput[cchSpoolDirectory + cchPrintersPath + cchSpoolerFile], pwszExtension, (cchExtension + 1) * sizeof(WCHAR));
}
@ -291,7 +321,7 @@ CreateJob(PLOCAL_PRINTER_HANDLE pPrinterHandle)
cchMachineName = wcslen(pwszMachineName);
pJob->pwszMachineName = DllAllocSplMem((cchMachineName + cchDoubleBackslash + 1) * sizeof(WCHAR));
CopyMemory(pJob->pwszMachineName, wszDoubleBackslash, cchDoubleBackslash * sizeof(WCHAR));
CopyMemory(pJob->pwszMachineName + cchDoubleBackslash, pwszMachineName, (cchMachineName + 1) * sizeof(WCHAR));
CopyMemory(&pJob->pwszMachineName[cchDoubleBackslash], pwszMachineName, (cchMachineName + 1) * sizeof(WCHAR));
// Add the job to the Global Job List.
if (!InsertElementSkiplist(&GlobalJobList, pJob))
@ -406,18 +436,24 @@ static DWORD
_LocalGetJobLevel1(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE* ppStart, PBYTE* ppEnd, DWORD cbBuf, PDWORD pcbNeeded)
{
DWORD cbDatatype = (wcslen(pJob->pwszDatatype) + 1) * sizeof(WCHAR);
DWORD cbDocumentName = (wcslen(pJob->pwszDocumentName) + 1) * sizeof(WCHAR);
DWORD cbDocumentName = 0;
DWORD cbMachineName = (wcslen(pJob->pwszMachineName) + 1) * sizeof(WCHAR);
DWORD cbPrinterName = (wcslen(pJob->pPrinter->pwszPrinterName) + 1) * sizeof(WCHAR);
DWORD cbStatus = 0;
DWORD cbUserName = (wcslen(pJob->pwszUserName) + 1) * sizeof(WCHAR);
DWORD cbUserName = 0;
DWORD dwErrorCode;
JOB_INFO_1W JobInfo1 = { 0 };
// A Status Message is optional.
// Calculate the lengths of the optional values.
if (pJob->pwszDocumentName)
cbDocumentName = (wcslen(pJob->pwszDocumentName) + 1) * sizeof(WCHAR);
if (pJob->pwszStatus)
cbStatus = (wcslen(pJob->pwszStatus) + 1) * sizeof(WCHAR);
if (pJob->pwszUserName)
cbUserName = (wcslen(pJob->pwszUserName) + 1) * sizeof(WCHAR);
// Check if the supplied buffer is large enough.
*pcbNeeded += sizeof(JOB_INFO_1W) + cbDatatype + cbDocumentName + cbMachineName + cbPrinterName + cbStatus + cbUserName;
if (cbBuf < *pcbNeeded)
@ -431,10 +467,6 @@ _LocalGetJobLevel1(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE*
JobInfo1.pDatatype = (PWSTR)*ppEnd;
CopyMemory(*ppEnd, pJob->pwszDatatype, cbDatatype);
*ppEnd -= cbDocumentName;
JobInfo1.pDocument = (PWSTR)*ppEnd;
CopyMemory(*ppEnd, pJob->pwszDocumentName, cbDocumentName);
*ppEnd -= cbMachineName;
JobInfo1.pMachineName = (PWSTR)*ppEnd;
CopyMemory(*ppEnd, pJob->pwszMachineName, cbMachineName);
@ -443,6 +475,14 @@ _LocalGetJobLevel1(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE*
JobInfo1.pPrinterName = (PWSTR)*ppEnd;
CopyMemory(*ppEnd, pJob->pPrinter->pwszPrinterName, cbPrinterName);
// Copy the optional values.
if (cbDocumentName)
{
*ppEnd -= cbDocumentName;
JobInfo1.pDocument = (PWSTR)*ppEnd;
CopyMemory(*ppEnd, pJob->pwszDocumentName, cbDocumentName);
}
if (cbStatus)
{
*ppEnd -= cbStatus;
@ -450,9 +490,12 @@ _LocalGetJobLevel1(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE*
CopyMemory(*ppEnd, pJob->pwszStatus, cbStatus);
}
*ppEnd -= cbUserName;
JobInfo1.pUserName = (PWSTR)*ppEnd;
CopyMemory(*ppEnd, pJob->pwszUserName, cbUserName);
if (cbUserName)
{
*ppEnd -= cbUserName;
JobInfo1.pUserName = (PWSTR)*ppEnd;
CopyMemory(*ppEnd, pJob->pwszUserName, cbUserName);
}
// Fill the rest of the structure.
JobInfo1.JobId = pJob->dwJobID;
@ -475,15 +518,15 @@ _LocalGetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE*
{
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 cbDocumentName = 0;
DWORD cbDriverName = (wcslen(pJob->pPrinter->pwszPrinterDriver) + 1) * sizeof(WCHAR);
DWORD cbMachineName = (wcslen(pJob->pwszMachineName) + 1) * sizeof(WCHAR);
DWORD cbNotifyName = (wcslen(pJob->pwszNotifyName) + 1) * sizeof(WCHAR);
DWORD cbNotifyName = 0;
DWORD cbPrinterName = (wcslen(pJob->pPrinter->pwszPrinterName) + 1) * sizeof(WCHAR);
DWORD cbPrintProcessor = (wcslen(pJob->pPrintProcessor->pwszName) + 1) * sizeof(WCHAR);
DWORD cbPrintProcessorParameters = 0;
DWORD cbStatus = 0;
DWORD cbUserName = (wcslen(pJob->pwszUserName) + 1) * sizeof(WCHAR);
DWORD cbUserName = 0;
DWORD dwErrorCode;
FILETIME ftNow;
FILETIME ftSubmitted;
@ -491,13 +534,22 @@ _LocalGetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE*
ULARGE_INTEGER uliNow;
ULARGE_INTEGER uliSubmitted;
// Print Processor Parameters and Status Message are optional.
// Calculate the lengths of the optional values.
if (pJob->pwszDocumentName)
cbDocumentName = (wcslen(pJob->pwszDocumentName) + 1) * sizeof(WCHAR);
if (pJob->pwszNotifyName)
cbNotifyName = (wcslen(pJob->pwszNotifyName) + 1) * sizeof(WCHAR);
if (pJob->pwszPrintProcessorParameters)
cbPrintProcessorParameters = (wcslen(pJob->pwszPrintProcessorParameters) + 1) * sizeof(WCHAR);
if (pJob->pwszStatus)
cbStatus = (wcslen(pJob->pwszStatus) + 1) * sizeof(WCHAR);
if (pJob->pwszUserName)
cbUserName = (wcslen(pJob->pwszUserName) + 1) * sizeof(WCHAR);
// Check if the supplied buffer is large enough.
*pcbNeeded += sizeof(JOB_INFO_2W) + cbDatatype + cbDevMode + cbDocumentName + cbDriverName + cbMachineName + cbNotifyName + cbPrinterName + cbPrintProcessor + cbPrintProcessorParameters + cbStatus + cbUserName;
if (cbBuf < *pcbNeeded)
@ -515,10 +567,6 @@ _LocalGetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE*
JobInfo2.pDevMode = (PDEVMODEW)*ppEnd;
CopyMemory(*ppEnd, pJob->pDevMode, cbDevMode);
*ppEnd -= cbDocumentName;
JobInfo2.pDocument = (PWSTR)*ppEnd;
CopyMemory(*ppEnd, pJob->pwszDocumentName, cbDocumentName);
*ppEnd -= cbDriverName;
JobInfo2.pDriverName = (PWSTR)*ppEnd;
CopyMemory(*ppEnd, pJob->pPrinter->pwszPrinterDriver, cbDriverName);
@ -527,10 +575,6 @@ _LocalGetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE*
JobInfo2.pMachineName = (PWSTR)*ppEnd;
CopyMemory(*ppEnd, pJob->pwszMachineName, cbMachineName);
*ppEnd -= cbNotifyName;
JobInfo2.pNotifyName = (PWSTR)*ppEnd;
CopyMemory(*ppEnd, pJob->pwszNotifyName, cbNotifyName);
*ppEnd -= cbPrinterName;
JobInfo2.pPrinterName = (PWSTR)*ppEnd;
CopyMemory(*ppEnd, pJob->pPrinter->pwszPrinterName, cbPrinterName);
@ -539,6 +583,21 @@ _LocalGetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE*
JobInfo2.pPrintProcessor = (PWSTR)*ppEnd;
CopyMemory(*ppEnd, pJob->pPrintProcessor->pwszName, cbPrintProcessor);
// Copy the optional values.
if (cbDocumentName)
{
*ppEnd -= cbDocumentName;
JobInfo2.pDocument = (PWSTR)*ppEnd;
CopyMemory(*ppEnd, pJob->pwszDocumentName, cbDocumentName);
}
if (cbNotifyName)
{
*ppEnd -= cbNotifyName;
JobInfo2.pNotifyName = (PWSTR)*ppEnd;
CopyMemory(*ppEnd, pJob->pwszNotifyName, cbNotifyName);
}
if (cbPrintProcessorParameters)
{
*ppEnd -= cbPrintProcessorParameters;
@ -553,9 +612,12 @@ _LocalGetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PBYTE*
CopyMemory(*ppEnd, pJob->pwszStatus, cbStatus);
}
*ppEnd -= cbUserName;
JobInfo2.pUserName = (PWSTR)*ppEnd;
CopyMemory(*ppEnd, pJob->pwszUserName, cbUserName);
if (cbUserName)
{
*ppEnd -= cbUserName;
JobInfo2.pUserName = (PWSTR)*ppEnd;
CopyMemory(*ppEnd, pJob->pwszUserName, cbUserName);
}
// Time in JOB_INFO_2W is the number of milliseconds elapsed since the job was submitted. Calculate this time.
if (!SystemTimeToFileTime(&pJob->stSubmitted, &ftSubmitted))
@ -658,7 +720,7 @@ _LocalSetJobLevel1(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PJOB_I
}
// Check if the datatype has changed.
if (wcscmp(pJob->pwszDatatype, pJobInfo->pDatatype) != 0)
if (!_EqualStrings(pJob->pwszDatatype, pJobInfo->pDatatype))
{
// Use the new value.
if (!ReallocSplStr(&pJob->pwszDatatype, pJobInfo->pDatatype))
@ -669,8 +731,8 @@ _LocalSetJobLevel1(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PJOB_I
}
}
// Check if the document name has changed.
if (wcscmp(pJob->pwszDocumentName, pJobInfo->pDocument) != 0)
// Check if the document name has changed. An empty string is permitted here!
if (!_EqualStrings(pJob->pwszDocumentName, pJobInfo->pDocument))
{
// Use the new value.
if (!ReallocSplStr(&pJob->pwszDocumentName, pJobInfo->pDocument))
@ -681,8 +743,8 @@ _LocalSetJobLevel1(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PJOB_I
}
}
// Check if the status message has changed.
if ((!pJob->pwszStatus && pJobInfo->pStatus) || wcscmp(pJob->pwszStatus, pJobInfo->pStatus) != 0)
// Check if the status message has changed. An empty string is permitted here!
if (!_EqualStrings(pJob->pwszStatus, pJobInfo->pStatus))
{
// Use the new value.
if (!ReallocSplStr(&pJob->pwszStatus, pJobInfo->pStatus))
@ -693,8 +755,8 @@ _LocalSetJobLevel1(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PJOB_I
}
}
// Check if the user name has changed.
if (wcscmp(pJob->pwszUserName, pJobInfo->pUserName) != 0)
// Check if the user name has changed. An empty string is permitted here!
if (!_EqualStrings(pJob->pwszUserName, pJobInfo->pUserName) != 0)
{
// The new user name doesn't need to exist, so no additional verification is required.
@ -763,7 +825,7 @@ _LocalSetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PJOB_I
}
// Check if the datatype has changed.
if (wcscmp(pJob->pwszDatatype, pJobInfo->pDatatype) != 0)
if (!_EqualStrings(pJob->pwszDatatype, pJobInfo->pDatatype))
{
// Use the new value.
if (!ReallocSplStr(&pJob->pwszDatatype, pJobInfo->pDatatype))
@ -774,8 +836,8 @@ _LocalSetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PJOB_I
}
}
// Check if the document name has changed.
if (wcscmp(pJob->pwszDocumentName, pJobInfo->pDocument) != 0)
// Check if the document name has changed. An empty string is permitted here!
if (!_EqualStrings(pJob->pwszDocumentName, pJobInfo->pDocument))
{
// Use the new value.
if (!ReallocSplStr(&pJob->pwszDocumentName, pJobInfo->pDocument))
@ -786,8 +848,8 @@ _LocalSetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PJOB_I
}
}
// Check if the notify name has changed.
if (wcscmp(pJob->pwszNotifyName, pJobInfo->pNotifyName) != 0)
// Check if the notify name has changed. An empty string is permitted here!
if (!_EqualStrings(pJob->pwszNotifyName, pJobInfo->pNotifyName))
{
// The new notify name doesn't need to exist, so no additional verification is required.
@ -800,8 +862,8 @@ _LocalSetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PJOB_I
}
}
// Check if the (optional) Print Processor Parameters have changed.
if ((!pJob->pwszPrintProcessorParameters && pJobInfo->pParameters) || wcscmp(pJob->pwszPrintProcessorParameters, pJobInfo->pParameters) != 0)
// Check if the Print Processor Parameters have changed. An empty string is permitted here!
if (!_EqualStrings(pJob->pwszPrintProcessorParameters, pJobInfo->pParameters))
{
// Use the new value.
if (!ReallocSplStr(&pJob->pwszPrintProcessorParameters, pJobInfo->pParameters))
@ -812,8 +874,8 @@ _LocalSetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PJOB_I
}
}
// Check if the (optional) Status Message has changed.
if ((!pJob->pwszStatus && pJobInfo->pStatus) || wcscmp(pJob->pwszStatus, pJobInfo->pStatus) != 0)
// Check if the Status Message has changed. An empty string is permitted here!
if (!_EqualStrings(pJob->pwszStatus, pJobInfo->pStatus))
{
// Use the new value.
if (!ReallocSplStr(&pJob->pwszStatus, pJobInfo->pStatus))
@ -824,8 +886,8 @@ _LocalSetJobLevel2(PLOCAL_PRINTER_HANDLE pPrinterHandle, PLOCAL_JOB pJob, PJOB_I
}
}
// Check if the user name has changed.
if (wcscmp(pJob->pwszUserName, pJobInfo->pUserName) != 0)
// Check if the user name has changed. An empty string is permitted here!
if (!_EqualStrings(pJob->pwszUserName, pJobInfo->pUserName))
{
// The new user name doesn't need to exist, so no additional verification is required.
@ -1201,15 +1263,21 @@ ReadJobShadowFile(PCWSTR pwszFilePath)
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));
pJob->pwszNotifyName = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offNotifyName));
CopyMemory(&pJob->stSubmitted, &pShadowFile->stSubmitted, sizeof(SYSTEMTIME));
// Copy the optional values.
if (pShadowFile->offDocumentName)
pJob->pwszDocumentName = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offDocumentName));
if (pShadowFile->offNotifyName)
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));
if (pShadowFile->offUserName)
pJob->pwszUserName = AllocSplStr((PCWSTR)((ULONG_PTR)pShadowFile + pShadowFile->offUserName));
// Jobs read from shadow files were always added using AddJob.
pJob->bAddedJob = TRUE;
@ -1230,17 +1298,17 @@ BOOL
WriteJobShadowFile(PWSTR pwszFilePath, const PLOCAL_JOB pJob)
{
BOOL bReturnValue = FALSE;
DWORD cbDatatype;
DWORD cbDevMode;
DWORD cbDocumentName;
DWORD cbDatatype = (wcslen(pJob->pwszDatatype) + 1) * sizeof(WCHAR);
DWORD cbDevMode = pJob->pDevMode->dmSize + pJob->pDevMode->dmDriverExtra;
DWORD cbDocumentName = 0;
DWORD cbFileSize;
DWORD cbMachineName;
DWORD cbNotifyName;
DWORD cbPrinterDriver;
DWORD cbPrinterName;
DWORD cbPrintProcessor;
DWORD cbMachineName = (wcslen(pJob->pwszMachineName) + 1) * sizeof(WCHAR);
DWORD cbNotifyName = 0;
DWORD cbPrinterDriver = (wcslen(pJob->pPrinter->pwszPrinterDriver) + 1) * sizeof(WCHAR);
DWORD cbPrinterName = (wcslen(pJob->pPrinter->pwszPrinterName) + 1) * sizeof(WCHAR);
DWORD cbPrintProcessor = (wcslen(pJob->pPrintProcessor->pwszName) + 1) * sizeof(WCHAR);
DWORD cbPrintProcessorParameters = 0;
DWORD cbUserName;
DWORD cbUserName = 0;
DWORD cbWritten;
DWORD dwCurrentOffset;
HANDLE hSHDFile = INVALID_HANDLE_VALUE;
@ -1255,21 +1323,19 @@ WriteJobShadowFile(PWSTR pwszFilePath, const PLOCAL_JOB pJob)
goto Cleanup;
}
// 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);
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);
// Calculate the lengths of the optional values and the total size of the shadow file.
if (pJob->pwszDocumentName)
cbDocumentName = (wcslen(pJob->pwszDocumentName) + 1) * sizeof(WCHAR);
if (pJob->pwszNotifyName)
cbNotifyName = (wcslen(pJob->pwszNotifyName) + 1) * sizeof(WCHAR);
// Print Processor Parameters are optional.
if (pJob->pwszPrintProcessorParameters)
cbPrintProcessorParameters = (wcslen(pJob->pwszPrintProcessorParameters) + 1) * sizeof(WCHAR);
if (pJob->pwszUserName)
cbUserName = (wcslen(pJob->pwszUserName) + 1) * sizeof(WCHAR);
cbFileSize = sizeof(SHD_HEADER) + cbDatatype + cbDocumentName + cbDevMode + cbMachineName + cbNotifyName + cbPrinterDriver + cbPrinterName + cbPrintProcessor + cbPrintProcessorParameters + cbUserName;
// Allocate memory for it.
@ -1306,10 +1372,6 @@ WriteJobShadowFile(PWSTR pwszFilePath, const PLOCAL_JOB pJob)
pShadowFile->offDatatype = dwCurrentOffset;
dwCurrentOffset += cbDatatype;
CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pwszDocumentName, cbDocumentName);
pShadowFile->offDocumentName = dwCurrentOffset;
dwCurrentOffset += cbDocumentName;
CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pDevMode, cbDevMode);
pShadowFile->offDevMode = dwCurrentOffset;
dwCurrentOffset += cbDevMode;
@ -1323,10 +1385,6 @@ WriteJobShadowFile(PWSTR pwszFilePath, const PLOCAL_JOB pJob)
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;
@ -1335,6 +1393,21 @@ WriteJobShadowFile(PWSTR pwszFilePath, const PLOCAL_JOB pJob)
pShadowFile->offPrintProcessor = dwCurrentOffset;
dwCurrentOffset += cbPrintProcessor;
// Copy the optional values.
if (cbDocumentName)
{
CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pwszDocumentName, cbDocumentName);
pShadowFile->offDocumentName = dwCurrentOffset;
dwCurrentOffset += cbDocumentName;
}
if (cbNotifyName)
{
CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pwszNotifyName, cbNotifyName);
pShadowFile->offNotifyName = dwCurrentOffset;
dwCurrentOffset += cbNotifyName;
}
if (cbPrintProcessorParameters)
{
CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pwszPrintProcessorParameters, cbPrintProcessorParameters);
@ -1342,9 +1415,12 @@ WriteJobShadowFile(PWSTR pwszFilePath, const PLOCAL_JOB pJob)
dwCurrentOffset += cbPrintProcessorParameters;
}
CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pwszUserName, cbUserName);
pShadowFile->offUserName = dwCurrentOffset;
dwCurrentOffset += cbUserName;
if (cbUserName)
{
CopyMemory((PBYTE)pShadowFile + dwCurrentOffset, pJob->pwszUserName, cbUserName);
pShadowFile->offUserName = dwCurrentOffset;
dwCurrentOffset += cbUserName;
}
// Write the file.
if (!WriteFile(hSHDFile, pShadowFile, cbFileSize, &cbWritten, NULL))

View file

@ -17,6 +17,9 @@ FindPrintMonitor(PCWSTR pwszName)
PLIST_ENTRY pEntry;
PLOCAL_PRINT_MONITOR pPrintMonitor;
if (!pwszName)
return NULL;
for (pEntry = PrintMonitorList.Flink; pEntry != &PrintMonitorList; pEntry = pEntry->Flink)
{
pPrintMonitor = CONTAINING_RECORD(pEntry, LOCAL_PRINT_MONITOR, Entry);

View file

@ -17,6 +17,9 @@ FindPort(PCWSTR pwszName)
PLIST_ENTRY pEntry;
PLOCAL_PORT pPort;
if (!pwszName)
return NULL;
for (pEntry = _PortList.Flink; pEntry != &_PortList; pEntry = pEntry->Flink)
{
pPort = CONTAINING_RECORD(pEntry, LOCAL_PORT, Entry);

View file

@ -129,9 +129,9 @@ typedef struct _LOCAL_JOB
PLOCAL_PRINT_PROCESSOR pPrintProcessor; /** Associated Print Processor to this Job */
DWORD dwPriority; /** Priority of this Job from MIN_PRIORITY to MAX_PRIORITY, default being DEF_PRIORITY */
SYSTEMTIME stSubmitted; /** Time of the submission of this Job */
PWSTR pwszUserName; /** User that submitted the Job */
PWSTR pwszNotifyName; /** User that shall be notified about the status of the Job */
PWSTR pwszDocumentName; /** Name of the Document that is printed */
PWSTR pwszUserName; /** Optional; User that submitted the Job */
PWSTR pwszNotifyName; /** Optional; User that shall be notified about the status of the Job */
PWSTR pwszDocumentName; /** Optional; Name of the Document that is printed */
PWSTR pwszDatatype; /** Datatype of the Document */
PWSTR pwszOutputFile; /** Output File to spool the Job to */
PWSTR pwszPrintProcessorParameters; /** Optional; Parameters for the chosen Print Processor */

View file

@ -167,6 +167,7 @@ InitializePrinterList()
pPrinter->pwszPrinterName = AllocSplStr(wszPrinterName);
pPrinter->pPrintProcessor = pPrintProcessor;
pPrinter->pPort = pPort;
InitializePrinterJobList(pPrinter);
// Get the printer driver.

View file

@ -78,6 +78,9 @@ FindDatatype(const PLOCAL_PRINT_PROCESSOR pPrintProcessor, PCWSTR pwszDatatype)
DWORD i;
PDATATYPES_INFO_1W pCurrentDatatype = pPrintProcessor->pDatatypesInfo1;
if (!pwszDatatype)
return FALSE;
for (i = 0; i < pPrintProcessor->dwDatatypeCount; i++)
{
if (wcsicmp(pCurrentDatatype->pName, pwszDatatype) == 0)
@ -95,6 +98,9 @@ FindPrintProcessor(PCWSTR pwszName)
PLIST_ENTRY pEntry;
PLOCAL_PRINT_PROCESSOR pPrintProcessor;
if (!pwszName)
return NULL;
for (pEntry = _PrintProcessorList.Flink; pEntry != &_PrintProcessorList; pEntry = pEntry->Flink)
{
pPrintProcessor = CONTAINING_RECORD(pEntry, LOCAL_PRINT_PROCESSOR, Entry);