From: Piotr Caban piotr@codeweavers.com
--- configure | 2 ++ configure.ac | 1 + dlls/winprint/Makefile.in | 4 +++ dlls/winprint/printproc.c | 64 +++++++++++++++++++++++++++++++++++++ dlls/winprint/winprint.spec | 6 ++++ loader/wine.inf.in | 2 ++ 6 files changed, 79 insertions(+) create mode 100644 dlls/winprint/Makefile.in create mode 100644 dlls/winprint/printproc.c create mode 100644 dlls/winprint/winprint.spec
diff --git a/configure b/configure index ca543e4503e..d9ca458a03d 100755 --- a/configure +++ b/configure @@ -1471,6 +1471,7 @@ enable_winhttp enable_wininet enable_winmm enable_winnls32 +enable_winprint enable_winscard enable_winspool_drv enable_winsta @@ -21915,6 +21916,7 @@ wine_fn_config_makefile dlls/winmm enable_winmm wine_fn_config_makefile dlls/winmm/tests enable_tests wine_fn_config_makefile dlls/winnls.dll16 enable_win16 wine_fn_config_makefile dlls/winnls32 enable_winnls32 +wine_fn_config_makefile dlls/winprint enable_winprint wine_fn_config_makefile dlls/winscard enable_winscard wine_fn_config_makefile dlls/winsock.dll16 enable_win16 wine_fn_config_makefile dlls/winspool.drv enable_winspool_drv diff --git a/configure.ac b/configure.ac index c15df1090b4..c4beea8ea10 100644 --- a/configure.ac +++ b/configure.ac @@ -3201,6 +3201,7 @@ WINE_CONFIG_MAKEFILE(dlls/winmm) WINE_CONFIG_MAKEFILE(dlls/winmm/tests) WINE_CONFIG_MAKEFILE(dlls/winnls.dll16,enable_win16) WINE_CONFIG_MAKEFILE(dlls/winnls32) +WINE_CONFIG_MAKEFILE(dlls/winprint) WINE_CONFIG_MAKEFILE(dlls/winscard) WINE_CONFIG_MAKEFILE(dlls/winsock.dll16,enable_win16) WINE_CONFIG_MAKEFILE(dlls/winspool.drv) diff --git a/dlls/winprint/Makefile.in b/dlls/winprint/Makefile.in new file mode 100644 index 00000000000..002004b1d0d --- /dev/null +++ b/dlls/winprint/Makefile.in @@ -0,0 +1,4 @@ +MODULE = winprint.dll + +C_SRCS = \ + printproc.c diff --git a/dlls/winprint/printproc.c b/dlls/winprint/printproc.c new file mode 100644 index 00000000000..7cc8759d801 --- /dev/null +++ b/dlls/winprint/printproc.c @@ -0,0 +1,64 @@ +/* + * Print processor implementation. + * + * Copyright 2022 Piotr Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "windows.h" +#include "winspool.h" +#include "ddk/winsplp.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(winprint); + +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), + level, datatypes, size, needed, no); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +HANDLE WINAPI OpenPrintProcessor(WCHAR *port, PRINTPROCESSOROPENDATA *open_data) +{ + FIXME("%s, %p\n", debugstr_w(port), open_data); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return NULL; +} + +BOOL WINAPI ClosePrintProcessor(HANDLE pp) +{ + FIXME("%p\n", pp); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI PrintDocumentOnPrintProcessor(HANDLE pp, WCHAR *doc_name) +{ + FIXME("%p, %s\n", pp, debugstr_w(doc_name)); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} + +BOOL WINAPI ControlPrintProcessor(HANDLE pp, DWORD cmd) +{ + FIXME("%p, %ld\n", pp, cmd); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; +} diff --git a/dlls/winprint/winprint.spec b/dlls/winprint/winprint.spec new file mode 100644 index 00000000000..b7b4642b695 --- /dev/null +++ b/dlls/winprint/winprint.spec @@ -0,0 +1,6 @@ +@ stdcall ClosePrintProcessor(ptr) +@ stdcall ControlPrintProcessor(ptr long) +@ stdcall EnumPrintProcessorDatatypesW(ptr ptr long ptr long ptr ptr) +@ stub GetPrintProcessorCapabilities +@ stdcall OpenPrintProcessor(ptr ptr) +@ stdcall PrintDocumentOnPrintProcessor(ptr ptr) diff --git a/loader/wine.inf.in b/loader/wine.inf.in index e7b435ed0f0..127d1f9ad6a 100644 --- a/loader/wine.inf.in +++ b/loader/wine.inf.in @@ -2149,6 +2149,7 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G" 16427,System\OLE DB,msdasql.dll 16427,System\ADO,msado15.dll 66000,3,wineps.drv +55,,winprint.dll 12,,*.sys,- 11,,*.msstyles,- 11,,* @@ -2211,6 +2212,7 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G" 16427,System\OLE DB,msdasql.dll 16427,System\ADO,msado15.dll 66000,3,wineps.drv +55,,winprint.dll 12,,*.sys 11,,*
From: Piotr Caban piotr@codeweavers.com
--- 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..06b72929a08 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; +}