mirror of
https://github.com/reactos/reactos.git
synced 2024-11-18 21:13:52 +00:00
278 lines
8.4 KiB
C
278 lines
8.4 KiB
C
/*
|
|
* PROJECT: ReactOS Standard Print Processor
|
|
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
|
* PURPOSE: Main functions
|
|
* COPYRIGHT: Copyright 2015-2017 Colin Finck (colin@reactos.org)
|
|
*/
|
|
|
|
#include "precomp.h"
|
|
|
|
// Local Constants
|
|
static PCWSTR _pwszDatatypes[] = {
|
|
L"RAW",
|
|
0
|
|
};
|
|
|
|
|
|
/**
|
|
* @name ClosePrintProcessor
|
|
*
|
|
* Closes a Print Processor Handle that has previously been opened through OpenPrintProcessor.
|
|
*
|
|
* @param hPrintProcessor
|
|
* The return value of a previous successful OpenPrintProcessor call.
|
|
*
|
|
* @return
|
|
* TRUE if the Print Processor Handle was successfully closed, FALSE otherwise.
|
|
* A more specific error code can be obtained through GetLastError.
|
|
*/
|
|
BOOL WINAPI
|
|
ClosePrintProcessor(HANDLE hPrintProcessor)
|
|
{
|
|
DWORD dwErrorCode;
|
|
PWINPRINT_HANDLE pHandle;
|
|
|
|
TRACE("ClosePrintProcessor(%p)\n", hPrintProcessor);
|
|
|
|
// Sanity checks
|
|
if (!hPrintProcessor)
|
|
{
|
|
dwErrorCode = ERROR_INVALID_HANDLE;
|
|
goto Cleanup;
|
|
}
|
|
|
|
pHandle = (PWINPRINT_HANDLE)hPrintProcessor;
|
|
|
|
// Free all structure fields for which memory has been allocated.
|
|
if (pHandle->pwszDatatype)
|
|
DllFreeSplStr(pHandle->pwszDatatype);
|
|
|
|
if (pHandle->pwszDocumentName)
|
|
DllFreeSplStr(pHandle->pwszDocumentName);
|
|
|
|
if (pHandle->pwszOutputFile)
|
|
DllFreeSplStr(pHandle->pwszOutputFile);
|
|
|
|
if (pHandle->pwszPrinterPort)
|
|
DllFreeSplStr(pHandle->pwszPrinterPort);
|
|
|
|
// Finally free the WINSPOOL_HANDLE structure itself.
|
|
DllFreeSplMem(pHandle);
|
|
dwErrorCode = ERROR_SUCCESS;
|
|
|
|
Cleanup:
|
|
SetLastError(dwErrorCode);
|
|
return (dwErrorCode == ERROR_SUCCESS);
|
|
}
|
|
|
|
BOOL WINAPI
|
|
ControlPrintProcessor(HANDLE hPrintProcessor, DWORD Command)
|
|
{
|
|
TRACE("ControlPrintProcessor(%p, %lu)\n", hPrintProcessor, Command);
|
|
|
|
UNIMPLEMENTED;
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
* @name EnumPrintProcessorDatatypesW
|
|
*
|
|
* Obtains an array of all datatypes supported by this Print Processor.
|
|
*
|
|
* @param pName
|
|
* Server Name. Ignored here, because every caller of EnumPrintProcessorDatatypesW is interested in this Print Processor's information.
|
|
*
|
|
* @param pPrintProcessorName
|
|
* Print Processor Name. Ignored here, because every caller of EnumPrintProcessorDatatypesW is interested in this Print Processor's information.
|
|
*
|
|
* @param Level
|
|
* The level of the structure supplied through pDatatypes. This must be 1.
|
|
*
|
|
* @param pDatatypes
|
|
* Pointer to the buffer that receives an array of DATATYPES_INFO_1W structures.
|
|
* Can be NULL if you just want to know the required size of the buffer.
|
|
*
|
|
* @param cbBuf
|
|
* Size of the buffer you supplied for pDatatypes, in bytes.
|
|
*
|
|
* @param pcbNeeded
|
|
* Pointer to a variable that receives the required size of the buffer for pDatatypes, in bytes.
|
|
* This parameter mustn't be NULL!
|
|
*
|
|
* @param pcReturned
|
|
* Pointer to a variable that receives the number of elements of the DATATYPES_INFO_1W array.
|
|
* This parameter mustn't be NULL!
|
|
*
|
|
* @return
|
|
* TRUE if we successfully copied the array into pDatatypes, FALSE otherwise.
|
|
* A more specific error code can be obtained through GetLastError.
|
|
*/
|
|
BOOL WINAPI
|
|
EnumPrintProcessorDatatypesW(PWSTR pName, PWSTR pPrintProcessorName, DWORD Level, PBYTE pDatatypes, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
|
|
{
|
|
DWORD cbDatatype;
|
|
DWORD dwDatatypeCount = 0;
|
|
DWORD dwOffsets[_countof(_pwszDatatypes)];
|
|
PCWSTR* pCurrentDatatype;
|
|
PDWORD pCurrentOffset = dwOffsets;
|
|
|
|
TRACE("EnumPrintProcessorDatatypesW(%S, %S, %lu, %p, %lu, %p, %p)\n", pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned);
|
|
|
|
// Sanity checks
|
|
if (Level != 1 || !pcbNeeded || !pcReturned)
|
|
return FALSE;
|
|
|
|
// Count the required buffer size and the number of datatypes.
|
|
*pcbNeeded = 0;
|
|
*pcReturned = 0;
|
|
|
|
for (pCurrentDatatype = _pwszDatatypes; *pCurrentDatatype; pCurrentDatatype++)
|
|
{
|
|
cbDatatype = (wcslen(*pCurrentDatatype) + 1) * sizeof(WCHAR);
|
|
*pcbNeeded += sizeof(DATATYPES_INFO_1W) + cbDatatype;
|
|
|
|
// Also calculate the offset in the output buffer of the pointer to this datatype string.
|
|
*pCurrentOffset = dwDatatypeCount * sizeof(DATATYPES_INFO_1W) + FIELD_OFFSET(DATATYPES_INFO_1W, pName);
|
|
|
|
dwDatatypeCount++;
|
|
pCurrentOffset++;
|
|
}
|
|
|
|
// Check if the supplied buffer is large enough.
|
|
if (cbBuf < *pcbNeeded)
|
|
{
|
|
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
|
return FALSE;
|
|
}
|
|
|
|
// Check if a buffer was supplied at all.
|
|
if (!pDatatypes)
|
|
{
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
// Copy over all datatypes.
|
|
*pCurrentOffset = MAXDWORD;
|
|
PackStrings(_pwszDatatypes, pDatatypes, dwOffsets, &pDatatypes[*pcbNeeded]);
|
|
|
|
*pcReturned = dwDatatypeCount;
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
DWORD WINAPI
|
|
GetPrintProcessorCapabilities(PWSTR pValueName, DWORD dwAttributes, PBYTE pData, DWORD nSize, PDWORD pcbNeeded)
|
|
{
|
|
TRACE("GetPrintProcessorCapabilities(%S, %lu, %p, %lu, %p)\n", pValueName, dwAttributes, pData, nSize, pcbNeeded);
|
|
|
|
UNIMPLEMENTED;
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @name OpenPrintProcessor
|
|
*
|
|
* Prepares this Print Processor for processing a document.
|
|
*
|
|
* @param pPrinterName
|
|
* String in the format "\\COMPUTERNAME\Port:, Port" that is passed to OpenPrinterW for writing to the Print Monitor on the specified port.
|
|
*
|
|
* @param pPrintProcessorOpenData
|
|
* Pointer to a PRINTPROCESSOROPENDATA structure containing details about the print job to be processed.
|
|
*
|
|
* @return
|
|
* A Print Processor handle on success or NULL in case of a failure. This handle has to be passed to PrintDocumentOnPrintProcessor to do the actual processing.
|
|
* A more specific error code can be obtained through GetLastError.
|
|
*/
|
|
HANDLE WINAPI
|
|
OpenPrintProcessor(PWSTR pPrinterName, PPRINTPROCESSOROPENDATA pPrintProcessorOpenData)
|
|
{
|
|
DWORD dwErrorCode;
|
|
HANDLE hReturnValue = NULL;
|
|
PWINPRINT_HANDLE pHandle = NULL;
|
|
|
|
TRACE("OpenPrintProcessor(%S, %p)\n", pPrinterName, pPrintProcessorOpenData);
|
|
|
|
// Sanity checks
|
|
// This time a datatype needs to be given. We can't fall back to a default here.
|
|
if (!pPrintProcessorOpenData || !pPrintProcessorOpenData->pDatatype || !*pPrintProcessorOpenData->pDatatype)
|
|
{
|
|
dwErrorCode = ERROR_INVALID_PARAMETER;
|
|
goto Cleanup;
|
|
}
|
|
|
|
// Create a new WINPRINT_HANDLE structure and fill the relevant fields.
|
|
pHandle = DllAllocSplMem(sizeof(WINPRINT_HANDLE));
|
|
|
|
// Check what datatype was given.
|
|
if (wcsicmp(pPrintProcessorOpenData->pDatatype, L"RAW") == 0)
|
|
{
|
|
pHandle->Datatype = RAW;
|
|
}
|
|
else
|
|
{
|
|
dwErrorCode = ERROR_INVALID_DATATYPE;
|
|
goto Cleanup;
|
|
}
|
|
|
|
// Fill the relevant fields.
|
|
pHandle->dwJobID = pPrintProcessorOpenData->JobId;
|
|
pHandle->pwszDatatype = AllocSplStr(pPrintProcessorOpenData->pDatatype);
|
|
pHandle->pwszDocumentName = AllocSplStr(pPrintProcessorOpenData->pDocumentName);
|
|
pHandle->pwszOutputFile = AllocSplStr(pPrintProcessorOpenData->pOutputFile);
|
|
pHandle->pwszPrinterPort = AllocSplStr(pPrinterName);
|
|
|
|
// We were successful! Return the handle and don't let the cleanup routine free it.
|
|
dwErrorCode = ERROR_SUCCESS;
|
|
hReturnValue = pHandle;
|
|
pHandle = NULL;
|
|
|
|
Cleanup:
|
|
if (pHandle)
|
|
DllFreeSplMem(pHandle);
|
|
|
|
SetLastError(dwErrorCode);
|
|
return hReturnValue;
|
|
}
|
|
|
|
/**
|
|
* @name PrintDocumentOnPrintProcessor
|
|
*
|
|
* Prints a document on this Print Processor after a handle for the document has been opened through OpenPrintProcessor.
|
|
*
|
|
* @param hPrintProcessor
|
|
* The return value of a previous successful OpenPrintProcessor call.
|
|
*
|
|
* @param pDocumentName
|
|
* String in the format "Printer, Job N" describing the spooled job that is to be processed.
|
|
*
|
|
* @return
|
|
* TRUE if the document was successfully processed by this Print Processor, FALSE otherwise.
|
|
* A more specific error code can be obtained through GetLastError.
|
|
*/
|
|
BOOL WINAPI
|
|
PrintDocumentOnPrintProcessor(HANDLE hPrintProcessor, PWSTR pDocumentName)
|
|
{
|
|
DWORD dwErrorCode;
|
|
PWINPRINT_HANDLE pHandle;
|
|
|
|
TRACE("PrintDocumentOnPrintProcessor(%p, %S)\n", hPrintProcessor, pDocumentName);
|
|
|
|
// Sanity checks
|
|
if (!hPrintProcessor)
|
|
{
|
|
dwErrorCode = ERROR_INVALID_HANDLE;
|
|
goto Cleanup;
|
|
}
|
|
|
|
pHandle = (PWINPRINT_HANDLE)hPrintProcessor;
|
|
|
|
// Call the corresponding Print function for the datatype.
|
|
if (pHandle->Datatype == RAW)
|
|
dwErrorCode = PrintRawJob(pHandle, pDocumentName);
|
|
|
|
Cleanup:
|
|
SetLastError(dwErrorCode);
|
|
return (dwErrorCode == ERROR_SUCCESS);
|
|
}
|