Module: wine Branch: master Commit: f63a9b592ce29bb5cd081d441ab4dbdc1b373478 URL: https://gitlab.winehq.org/wine/wine/-/commit/f63a9b592ce29bb5cd081d441ab4dbd...
Author: Piotr Caban piotr@codeweavers.com Date: Wed Oct 26 13:33:37 2022 +0200
winprint: Implement RAW print processor.
---
dlls/winprint/Makefile.in | 1 + dlls/winprint/printproc.c | 161 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 147 insertions(+), 15 deletions(-)
diff --git a/dlls/winprint/Makefile.in b/dlls/winprint/Makefile.in index 002004b1d0d..57851fc5b04 100644 --- a/dlls/winprint/Makefile.in +++ b/dlls/winprint/Makefile.in @@ -1,4 +1,5 @@ MODULE = winprint.dll +IMPORTS = winspool
C_SRCS = \ printproc.c diff --git a/dlls/winprint/printproc.c b/dlls/winprint/printproc.c index 7cc8759d801..d7d9cce9d93 100644 --- a/dlls/winprint/printproc.c +++ b/dlls/winprint/printproc.c @@ -18,6 +18,20 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+/* Missing datatypes support: + * RAW [FF appended] + * RAW [FF auto] + * NT EMF 1.003 + * NT EMF 1.006 + * NT EMF 1.007 + * NT EMF 1.008 + * TEXT + * XPS2GDI + * + * Implement print processor features like e.g. printing multiple copies. */ + +#include <stdlib.h> + #include "windows.h" #include "winspool.h" #include "ddk/winsplp.h" @@ -26,34 +40,133 @@
WINE_DEFAULT_DEBUG_CHANNEL(winprint);
+#define PP_MAGIC 0x952173fd + +struct pp_data +{ + DWORD magic; + HANDLE hport; + WCHAR *doc_name; + WCHAR *out_file; +}; + +static struct pp_data* get_handle_data(HANDLE pp) +{ + struct pp_data *ret = (struct pp_data *)pp; + + if (!ret || ret->magic != PP_MAGIC) + { + SetLastError(ERROR_INVALID_HANDLE); + return NULL; + } + return ret; +} + BOOL WINAPI EnumPrintProcessorDatatypesW(WCHAR *server, WCHAR *name, DWORD level, BYTE *datatypes, DWORD size, DWORD *needed, DWORD *no) { - FIXME("%s, %s, %ld, %p, %ld, %p, %p\n", debugstr_w(server), debugstr_w(name), + static const WCHAR raw[] = L"RAW"; + + DATATYPES_INFO_1W *info = (DATATYPES_INFO_1W *)datatypes; + + TRACE("%s, %s, %ld, %p, %ld, %p, %p\n", debugstr_w(server), debugstr_w(name), level, datatypes, size, needed, no); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + + if (!needed || !no) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + *no = 0; + *needed = sizeof(*info) + sizeof(raw); + + if (level != 1 || !datatypes) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if (size < *needed) + { + SetLastError(ERROR_INSUFFICIENT_BUFFER); + return FALSE; + } + + *no = 1; + info->pName = (WCHAR*)(info + 1); + memcpy(info + 1, raw, sizeof(raw)); + return TRUE; }
HANDLE WINAPI OpenPrintProcessor(WCHAR *port, PRINTPROCESSOROPENDATA *open_data) { - FIXME("%s, %p\n", debugstr_w(port), open_data); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return NULL; -} + struct pp_data *data; + HANDLE hport;
-BOOL WINAPI ClosePrintProcessor(HANDLE pp) -{ - FIXME("%p\n", pp); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + TRACE("%s, %p\n", debugstr_w(port), open_data); + + if (!port || !open_data || !open_data->pDatatype) + { + SetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + if (!wcscmp(open_data->pDatatype, L"RAW")) + { + SetLastError(ERROR_INVALID_DATATYPE); + return NULL; + } + + if (!OpenPrinterW(port, &hport, NULL)) + return NULL; + + data = LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, sizeof(*data)); + if (!data) + return NULL; + data->magic = PP_MAGIC; + data->hport = hport; + data->doc_name = wcsdup(open_data->pDocumentName); + data->out_file = wcsdup(open_data->pOutputFile); + return (HANDLE)data; }
BOOL WINAPI PrintDocumentOnPrintProcessor(HANDLE pp, WCHAR *doc_name) { - FIXME("%p, %s\n", pp, debugstr_w(doc_name)); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + struct pp_data *data = get_handle_data(pp); + HANDLE spool_data; + DOC_INFO_1W info; + BYTE buf[0x1000]; + DWORD r, w; + + TRACE("%p, %s\n", pp, debugstr_w(doc_name)); + + if (!data) + return FALSE; + + if (!OpenPrinterW(doc_name, &spool_data, NULL)) + return FALSE; + + info.pDocName = data->doc_name; + info.pOutputFile = data->out_file; + info.pDatatype = (WCHAR *)L"RAW"; + if (!StartDocPrinterW(data->hport, 1, (BYTE *)&info)) + { + ClosePrinter(spool_data); + return FALSE; + } + + while (ReadPrinter(spool_data, buf, sizeof(buf), &r) && r) + { + if (!WritePrinter(data->hport, buf, r, &w) || r != w) + { + ClosePrinter(spool_data); + EndDocPrinter(data->hport); + return FALSE; + } + } + ClosePrinter(spool_data); + + return EndDocPrinter(data->hport); }
BOOL WINAPI ControlPrintProcessor(HANDLE pp, DWORD cmd) @@ -62,3 +175,21 @@ BOOL WINAPI ControlPrintProcessor(HANDLE pp, DWORD cmd) SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return FALSE; } + +BOOL WINAPI ClosePrintProcessor(HANDLE pp) +{ + struct pp_data *data = get_handle_data(pp); + + TRACE("%p\n", pp); + + if (!data) + return FALSE; + + ClosePrinter(data->hport); + free(data->doc_name); + free(data->out_file); + + memset(data, 0, sizeof(*data)); + LocalFree(data); + return TRUE; +}