-- v2: localspl: Add lpr port extension. localspl: Add unixname port extension. localspl: Add pipe port extension. localspl: Fix parameters validation in FILE StartDocPort. localspl: Add printer port redirection extension.
From: Piotr Caban piotr@codeweavers.com
--- dlls/localspl/provider.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/dlls/localspl/provider.c b/dlls/localspl/provider.c index fcddd2a7018..f34653291c1 100644 --- a/dlls/localspl/provider.c +++ b/dlls/localspl/provider.c @@ -3240,6 +3240,7 @@ static BOOL WINAPI fpScheduleJob(HANDLE hprinter, DWORD job_id) BOOL ret_startdoc = FALSE, ret_open = FALSE, ret = TRUE; printer_t *printer = (printer_t *)hprinter; const WCHAR *port_name, *port; + WCHAR output[1024]; DOC_INFO_1W info; monitor_t *mon; BYTE buf[4096]; @@ -3247,6 +3248,7 @@ static BOOL WINAPI fpScheduleJob(HANDLE hprinter, DWORD job_id) DWORD r, w; job_t *job; HANDLE hf; + HKEY hkey;
TRACE("%p %ld\n", hprinter, job_id);
@@ -3280,10 +3282,22 @@ static BOOL WINAPI fpScheduleJob(HANDLE hprinter, DWORD job_id) }
/* TODO: use print processor */ - if (isalpha(port[0]) && port[1] == ':') + port_name = port; + if ((isalpha(port[0]) && port[1] == ':') || + !wcsncmp(port, L"FILE:", ARRAY_SIZE(L"FILE:") - 1)) + { port_name = L"FILE:"; - else - port_name = port; + } + else if (!RegOpenKeyW(HKEY_CURRENT_USER, L"Software\Wine\Printing\Spooler", &hkey)) + { + DWORD type, count = sizeof(output); + if (!RegQueryValueExW(hkey, port, NULL, &type, (BYTE *)output, &count)) + { + TRACE("overriding port %s -> %s\n", debugstr_w(port), debugstr_w(output)); + port_name = output; + } + RegCloseKey(hkey); + }
if (!(mon = monitor_load_by_port(port_name)) || !mon->monitor.pfnOpenPort || !mon->monitor.pfnStartDocPort || !mon->monitor.pfnWritePort ||
From: Piotr Caban piotr@codeweavers.com
--- dlls/localspl/localmon.c | 2 +- dlls/localspl/tests/localmon.c | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/dlls/localspl/localmon.c b/dlls/localspl/localmon.c index a982d359058..43e6197fa47 100644 --- a/dlls/localspl/localmon.c +++ b/dlls/localspl/localmon.c @@ -509,7 +509,7 @@ static BOOL WINAPI localmon_StartDocPort(HANDLE hport, WCHAR *printer_name,
if (!doc_info || !doc_info->pOutputFile) { - FIXME("set error\n"); + SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
diff --git a/dlls/localspl/tests/localmon.c b/dlls/localspl/tests/localmon.c index edc0b1f7cbb..931de81a503 100644 --- a/dlls/localspl/tests/localmon.c +++ b/dlls/localspl/tests/localmon.c @@ -914,9 +914,18 @@ static void test_file_port(void) ok(!res, "WritePort succeeded\n"); ok(GetLastError() == ERROR_INVALID_HANDLE, "GetLastError() = %lu\n", GetLastError());
- doc_info.pDocName = (WCHAR *)L"not used"; + SetLastError(0xdeadbeef); + res = pStartDocPort(hport, printer_name, 1, 1, NULL); + ok(!res, "StartDocPort succeeded\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError() = %lu\n", GetLastError()); + + memset(&doc_info, 0, sizeof(doc_info)); + SetLastError(0xdeadbeef); + res = pStartDocPort(hport, printer_name, 1, 1, (BYTE *)&doc_info); + ok(!res, "StartDocPort succeeded\n"); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError() = %lu\n", GetLastError()); + doc_info.pOutputFile = tempfileW; - doc_info.pDatatype = (WCHAR *)L"not used"; res = pStartDocPort(hport, printer_name, 1, 1, (BYTE *)&doc_info); ok(res, "StartDocPort failed (%lu)\n", GetLastError());
From: Piotr Caban piotr@codeweavers.com
--- dlls/localspl/Makefile.in | 2 + dlls/localspl/cups.c | 227 +++++++++++++++++++++++++++++++ dlls/localspl/localmon.c | 59 ++++++-- dlls/localspl/localspl_private.h | 29 ++++ dlls/localspl/provider.c | 4 + 5 files changed, 313 insertions(+), 8 deletions(-) create mode 100644 dlls/localspl/cups.c
diff --git a/dlls/localspl/Makefile.in b/dlls/localspl/Makefile.in index ab1d5a79d64..61ca097d9e4 100644 --- a/dlls/localspl/Makefile.in +++ b/dlls/localspl/Makefile.in @@ -1,9 +1,11 @@ MODULE = localspl.dll +UNIXLIB = localspl.so IMPORTS = spoolss user32 advapi32
EXTRADLLFLAGS = -Wb,--prefer-native
C_SRCS = \ + cups.c \ localmon.c \ provider.c
diff --git a/dlls/localspl/cups.c b/dlls/localspl/cups.c new file mode 100644 index 00000000000..25c485e220e --- /dev/null +++ b/dlls/localspl/cups.c @@ -0,0 +1,227 @@ +/* + * CUPS functions + * + * Copyright 2021 Huw Davies + * Copyright 2022 Piotr Caban + * + * 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 + */ +#if 0 +#pragma makedep unix +#endif + +#include "config.h" + +#include <stdarg.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <signal.h> +#include <sys/wait.h> + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "wine/debug.h" + +#include "localspl_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(localspl); + +typedef struct _doc_t +{ + BOOL (*write_doc)(struct _doc_t *, const BYTE *buf, unsigned int size); + BOOL (*end_doc)(struct _doc_t *); + + union + { + struct + { + pid_t pid; + int fd; + } pipe; + }; +} doc_t; + +static BOOL pipe_write_doc(doc_t *doc, const BYTE *buf, unsigned int size) +{ + return write(doc->pipe.fd, buf, size) == size; +} + +static BOOL pipe_end_doc(doc_t *doc) +{ + pid_t wret; + int status; + + close(doc->pipe.fd); + + do { + wret = waitpid(doc->pipe.pid, &status, 0); + } while (wret < 0 && errno == EINTR); + if (wret < 0) + { + ERR("waitpid() failed!\n"); + return FALSE; + } + if (!WIFEXITED(status) || WEXITSTATUS(status)) + { + ERR("child process failed! %d\n", status); + return FALSE; + } + + return TRUE; +} + +static BOOL pipe_start_doc(doc_t *doc, const WCHAR *cmd) +{ + char *cmdA; + int fds[2]; + DWORD len; + + doc->write_doc = pipe_write_doc; + doc->end_doc = pipe_end_doc; + + len = wcslen(cmd); + cmdA = malloc(len * 3 + 1); + ntdll_wcstoumbs(cmd, len + 1, cmdA, len * 3 + 1, FALSE); + + TRACE("printing with: %s\n", cmdA); + + if (pipe(fds)) + { + ERR("pipe() failed!\n"); + free(cmdA); + return FALSE; + } + + if ((doc->pipe.pid = fork()) == 0) + { + close(0); + dup2(fds[0], 0); + close(fds[1]); + + /* reset signals that we previously set to SIG_IGN */ + signal(SIGPIPE, SIG_DFL); + + execl("/bin/sh", "/bin/sh", "-c", cmdA, NULL); + _exit(1); + } + close(fds[0]); + free(cmdA); + if (doc->pipe.pid == -1) + { + ERR("fork() failed!\n"); + close(fds[1]); + return FALSE; + } + + doc->pipe.fd = fds[1]; + return TRUE; +} + +static NTSTATUS start_doc(void *args) +{ + const struct start_doc_params *params = args; + doc_t *doc = malloc(sizeof(*doc)); + BOOL ret = FALSE; + + if (!doc) return STATUS_NO_MEMORY; + + if (params->type == PORT_IS_PIPE) + ret = pipe_start_doc(doc, params->port + 1 /* strlen("|") */); + + if (ret) + *params->doc = (size_t)doc; + else + free(doc); + return ret; +} + +static NTSTATUS write_doc(void *args) +{ + const struct write_doc_params *params = args; + doc_t *doc = (doc_t *)(size_t)params->doc; + + return doc->write_doc(doc, params->buf, params->size); +} + +static NTSTATUS end_doc(void *args) +{ + const struct end_doc_params *params = args; + doc_t *doc = (doc_t *)(size_t)params->doc; + NTSTATUS ret; + + ret = doc->end_doc(doc); + free(doc); + return ret; +} + +const unixlib_entry_t __wine_unix_call_funcs[] = +{ + start_doc, + write_doc, + end_doc, +}; + +#ifdef _WIN64 + +typedef ULONG PTR32; + +static NTSTATUS wow64_start_doc(void *args) +{ + struct + { + unsigned int type; + const PTR32 port; + INT64 *doc; + } const *params32 = args; + + struct start_doc_params params = + { + params32->type, + ULongToPtr(params32->port), + params32->doc, + }; + + return start_doc(¶ms); +} + +static NTSTATUS wow64_write_doc(void *args) +{ + struct + { + INT64 doc; + const PTR32 buf; + unsigned int size; + } const *params32 = args; + + struct write_doc_params params = + { + params32->doc, + ULongToPtr(params32->buf), + params32->size, + }; + + return write_doc(¶ms); +} + +const unixlib_entry_t __wine_unix_call_wow64_funcs[] = +{ + wow64_start_doc, + wow64_write_doc, + end_doc, +}; + +#endif /* _WIN64 */ diff --git a/dlls/localspl/localmon.c b/dlls/localspl/localmon.c index 43e6197fa47..9f403b9e85e 100644 --- a/dlls/localspl/localmon.c +++ b/dlls/localspl/localmon.c @@ -66,6 +66,7 @@ typedef struct { struct list entry; DWORD type; HANDLE hfile; + INT64 doc_handle; WCHAR nameW[1]; } port_t;
@@ -95,7 +96,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( hinstDLL ); localspl_instance = hinstDLL; - break; + return !__wine_init_unix_call(); } return TRUE; } @@ -249,7 +250,7 @@ getports_cleanup: * */
-static DWORD get_type_from_name(LPCWSTR name) +static DWORD get_type_from_name(LPCWSTR name, BOOL check_filename) { HANDLE hfile;
@@ -274,6 +275,9 @@ static DWORD get_type_from_name(LPCWSTR name) if (!wcsncmp(name, L"LPR:", ARRAY_SIZE(L"LPR:") - 1)) return PORT_IS_LPR;
+ if (!check_filename) + return PORT_IS_UNKNOWN; + /* Must be a file or a directory. Does the file exist ? */ hfile = CreateFileW(name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); TRACE("%p for OPEN_EXISTING on %s\n", hfile, debugstr_w(name)); @@ -301,9 +305,12 @@ static DWORD get_type_from_local_name(LPCWSTR nameW) LPWSTR myname = NULL; DWORD needed = 0; DWORD numentries = 0; - DWORD id = 0; + DWORD id;
- TRACE("(%s)\n", debugstr_w(myname)); + TRACE("(%s)\n", debugstr_w(nameW)); + + if ((id = get_type_from_name(nameW, FALSE)) >= PORT_IS_WINE) + return id;
needed = get_ports_from_reg(1, NULL, 0, &numentries); pi = malloc(needed); @@ -313,17 +320,17 @@ static DWORD get_type_from_local_name(LPCWSTR nameW) if (pi && needed && numentries > 0) { /* we got a number of valid ports. */
- while ((myname == NULL) && (id < numentries)) + for (id = 0; id < numentries; id++) { if (lstrcmpiW(nameW, pi[id].pName) == 0) { TRACE("(%lu) found %s\n", id, debugstr_w(pi[id].pName)); myname = pi[id].pName; + break; } - id++; } }
- id = (myname) ? get_type_from_name(myname) : PORT_IS_UNKNOWN; + id = myname ? get_type_from_name(myname, TRUE) : PORT_IS_UNKNOWN;
free(pi); return id; @@ -478,6 +485,7 @@ static BOOL WINAPI localmon_OpenPortW(LPWSTR pName, PHANDLE phPort)
port->type = type; port->hfile = INVALID_HANDLE_VALUE; + port->doc_handle = 0; lstrcpyW(port->nameW, pName); *phPort = port;
@@ -498,6 +506,19 @@ static BOOL WINAPI localmon_StartDocPort(HANDLE hport, WCHAR *printer_name, TRACE("(%p %s %ld %ld %p)\n", hport, debugstr_w(printer_name), job_id, level, doc_info);
+ if (port->type == PORT_IS_PIPE) + { + struct start_doc_params params; + + if (port->doc_handle) + return TRUE; + + params.type = port->type; + params.port = port->nameW; + params.doc = &port->doc_handle; + return UNIX_CALL(start_doc, ¶ms); + } + if (port->type != PORT_IS_FILE) { SetLastError(ERROR_CALL_NOT_IMPLEMENTED); @@ -525,6 +546,19 @@ static BOOL WINAPI localmon_WritePort(HANDLE hport, BYTE *buf, DWORD size,
TRACE("(%p %p %lu %p)\n", hport, buf, size, written);
+ if (port->type == PORT_IS_PIPE) + { + struct write_doc_params params; + BOOL ret; + + params.doc = port->doc_handle; + params.buf = buf; + params.size = size; + ret = UNIX_CALL(write_doc, ¶ms); + *written = ret ? size : 0; + return ret; + } + return WriteFile(port->hfile, buf, size, written, NULL); }
@@ -534,6 +568,15 @@ static BOOL WINAPI localmon_EndDocPort(HANDLE hport)
TRACE("(%p)\n", hport);
+ if (port->type == PORT_IS_PIPE) + { + struct end_doc_params params; + + params.doc = port->doc_handle; + port->doc_handle = 0; + return UNIX_CALL(end_doc, ¶ms); + } + CloseHandle(port->hfile); port->hfile = INVALID_HANDLE_VALUE; return TRUE; @@ -712,7 +755,7 @@ static DWORD WINAPI localmon_XcvDataPort(HANDLE hXcv, LPCWSTR pszDataName, PBYTE
if (!lstrcmpW(pszDataName, L"PortIsValid")) { TRACE("InputData (%ld): %s\n", cbInputData, debugstr_w( (LPWSTR) pInputData)); - res = get_type_from_name((LPCWSTR) pInputData); + res = get_type_from_name((LPCWSTR) pInputData, TRUE); TRACE("detected as %lu\n", res); /* names, that we have recognized, are valid */ if (res) return ERROR_SUCCESS; diff --git a/dlls/localspl/localspl_private.h b/dlls/localspl/localspl_private.h index b82dfa2dedf..b76071f049a 100644 --- a/dlls/localspl/localspl_private.h +++ b/dlls/localspl/localspl_private.h @@ -22,6 +22,8 @@ #define __WINE_LOCALSPL_PRIVATE__
#include <windef.h> +#include "winternl.h" +#include "wine/unixlib.h"
extern HINSTANCE localspl_instance DECLSPEC_HIDDEN;
@@ -165,5 +167,32 @@ extern HINSTANCE localspl_instance DECLSPEC_HIDDEN; #define PORT_IS_CUPS 7 #define PORT_IS_LPR 8
+struct start_doc_params +{ + unsigned int type; + const WCHAR *port; + INT64 *doc; +}; + +struct write_doc_params +{ + INT64 doc; + const BYTE *buf; + unsigned int size; +}; + +struct end_doc_params +{ + INT64 doc; +}; + +#define UNIX_CALL(func, params) WINE_UNIX_CALL(unix_ ## func, params) + +enum cups_funcs +{ + unix_start_doc, + unix_write_doc, + unix_end_doc, +};
#endif /* __WINE_LOCALSPL_PRIVATE__ */ diff --git a/dlls/localspl/provider.c b/dlls/localspl/provider.c index f34653291c1..e79d8f23350 100644 --- a/dlls/localspl/provider.c +++ b/dlls/localspl/provider.c @@ -987,6 +987,10 @@ static monitor_t * monitor_load_by_port(LPCWSTR portname)
TRACE("(%s)\n", debugstr_w(portname));
+ /* wine specific ports */ + if (portname[0] == '|') + return monitor_load(L"Local Port", NULL); + /* Try the Local Monitor first */ if (RegOpenKeyW(HKEY_LOCAL_MACHINE, winnt_cv_portsW, &hroot) == ERROR_SUCCESS) { if (RegQueryValueExW(hroot, portname, NULL, NULL, NULL, &len) == ERROR_SUCCESS) {
From: Piotr Caban piotr@codeweavers.com
--- dlls/localspl/cups.c | 35 +++++++++++++++++++++++++++++++++++ dlls/localspl/localmon.c | 6 +++--- dlls/localspl/provider.c | 2 +- 3 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/dlls/localspl/cups.c b/dlls/localspl/cups.c index 25c485e220e..fa685e26289 100644 --- a/dlls/localspl/cups.c +++ b/dlls/localspl/cups.c @@ -52,6 +52,10 @@ typedef struct _doc_t pid_t pid; int fd; } pipe; + struct + { + int fd; + } unixname; }; } doc_t;
@@ -131,6 +135,35 @@ static BOOL pipe_start_doc(doc_t *doc, const WCHAR *cmd) return TRUE; }
+static BOOL unixname_write_doc(doc_t *doc, const BYTE *buf, unsigned int size) +{ + return write(doc->unixname.fd, buf, size) == size; +} + +static BOOL unixname_end_doc(doc_t *doc) +{ + close(doc->unixname.fd); + return TRUE; +} + +static BOOL unixname_start_doc(doc_t *doc, const WCHAR *output) +{ + char *outputA; + DWORD len; + + doc->write_doc = unixname_write_doc; + doc->end_doc = unixname_end_doc; + + len = wcslen(output); + outputA = malloc(len * 3 + 1); + ntdll_wcstoumbs(output, len + 1, outputA, len * 3 + 1, FALSE); + + doc->unixname.fd = open(outputA, O_CREAT | O_TRUNC | O_WRONLY, 0666); + free(outputA); + + return doc->unixname.fd != -1; +} + static NTSTATUS start_doc(void *args) { const struct start_doc_params *params = args; @@ -141,6 +174,8 @@ static NTSTATUS start_doc(void *args)
if (params->type == PORT_IS_PIPE) ret = pipe_start_doc(doc, params->port + 1 /* strlen("|") */); + else if (params->type == PORT_IS_UNIXNAME) + ret = unixname_start_doc(doc, params->port);
if (ret) *params->doc = (size_t)doc; diff --git a/dlls/localspl/localmon.c b/dlls/localspl/localmon.c index 9f403b9e85e..d2712cde995 100644 --- a/dlls/localspl/localmon.c +++ b/dlls/localspl/localmon.c @@ -506,7 +506,7 @@ static BOOL WINAPI localmon_StartDocPort(HANDLE hport, WCHAR *printer_name, TRACE("(%p %s %ld %ld %p)\n", hport, debugstr_w(printer_name), job_id, level, doc_info);
- if (port->type == PORT_IS_PIPE) + if (port->type == PORT_IS_PIPE || port->type == PORT_IS_UNIXNAME) { struct start_doc_params params;
@@ -546,7 +546,7 @@ static BOOL WINAPI localmon_WritePort(HANDLE hport, BYTE *buf, DWORD size,
TRACE("(%p %p %lu %p)\n", hport, buf, size, written);
- if (port->type == PORT_IS_PIPE) + if (port->type == PORT_IS_PIPE || port->type == PORT_IS_UNIXNAME) { struct write_doc_params params; BOOL ret; @@ -568,7 +568,7 @@ static BOOL WINAPI localmon_EndDocPort(HANDLE hport)
TRACE("(%p)\n", hport);
- if (port->type == PORT_IS_PIPE) + if (port->type == PORT_IS_PIPE || port->type == PORT_IS_UNIXNAME) { struct end_doc_params params;
diff --git a/dlls/localspl/provider.c b/dlls/localspl/provider.c index e79d8f23350..7b5a94b52f6 100644 --- a/dlls/localspl/provider.c +++ b/dlls/localspl/provider.c @@ -988,7 +988,7 @@ static monitor_t * monitor_load_by_port(LPCWSTR portname) TRACE("(%s)\n", debugstr_w(portname));
/* wine specific ports */ - if (portname[0] == '|') + if (portname[0] == '|' || portname[0] == '/') return monitor_load(L"Local Port", NULL);
/* Try the Local Monitor first */
From: Piotr Caban piotr@codeweavers.com
--- dlls/localspl/cups.c | 16 ++++++++++++++++ dlls/localspl/localmon.c | 9 ++++++--- 2 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/dlls/localspl/cups.c b/dlls/localspl/cups.c index fa685e26289..47362c1f138 100644 --- a/dlls/localspl/cups.c +++ b/dlls/localspl/cups.c @@ -164,6 +164,20 @@ static BOOL unixname_start_doc(doc_t *doc, const WCHAR *output) return doc->unixname.fd != -1; }
+static BOOL lpr_start_doc(doc_t *doc, const WCHAR *printer_name) +{ + static const WCHAR lpr[] = { 'l','p','r',' ','-','P',''' }; + static const WCHAR quote[] = { ''',0 }; + int printer_len = wcslen(printer_name); + WCHAR *cmd; + + cmd = malloc(printer_len * sizeof(WCHAR) + sizeof(lpr) + sizeof(quote)); + memcpy(cmd, lpr, sizeof(lpr)); + memcpy(cmd + ARRAY_SIZE(lpr), printer_name, printer_len * sizeof(WCHAR)); + memcpy(cmd + ARRAY_SIZE(lpr) + printer_len, quote, sizeof(quote)); + return pipe_start_doc(doc, cmd); +} + static NTSTATUS start_doc(void *args) { const struct start_doc_params *params = args; @@ -176,6 +190,8 @@ static NTSTATUS start_doc(void *args) ret = pipe_start_doc(doc, params->port + 1 /* strlen("|") */); else if (params->type == PORT_IS_UNIXNAME) ret = unixname_start_doc(doc, params->port); + else if (params->type == PORT_IS_LPR) + ret = lpr_start_doc(doc, params->port + 4 /* strlen("lpr:") */);
if (ret) *params->doc = (size_t)doc; diff --git a/dlls/localspl/localmon.c b/dlls/localspl/localmon.c index d2712cde995..8cef23787e7 100644 --- a/dlls/localspl/localmon.c +++ b/dlls/localspl/localmon.c @@ -506,7 +506,8 @@ static BOOL WINAPI localmon_StartDocPort(HANDLE hport, WCHAR *printer_name, TRACE("(%p %s %ld %ld %p)\n", hport, debugstr_w(printer_name), job_id, level, doc_info);
- if (port->type == PORT_IS_PIPE || port->type == PORT_IS_UNIXNAME) + if (port->type == PORT_IS_PIPE || port->type == PORT_IS_UNIXNAME || + port->type == PORT_IS_LPR) { struct start_doc_params params;
@@ -546,7 +547,8 @@ static BOOL WINAPI localmon_WritePort(HANDLE hport, BYTE *buf, DWORD size,
TRACE("(%p %p %lu %p)\n", hport, buf, size, written);
- if (port->type == PORT_IS_PIPE || port->type == PORT_IS_UNIXNAME) + if (port->type == PORT_IS_PIPE || port->type == PORT_IS_UNIXNAME || + port->type == PORT_IS_LPR) { struct write_doc_params params; BOOL ret; @@ -568,7 +570,8 @@ static BOOL WINAPI localmon_EndDocPort(HANDLE hport)
TRACE("(%p)\n", hport);
- if (port->type == PORT_IS_PIPE || port->type == PORT_IS_UNIXNAME) + if (port->type == PORT_IS_PIPE || port->type == PORT_IS_UNIXNAME || + port->type == PORT_IS_LPR) { struct end_doc_params params;
On Tue Nov 29 13:56:48 2022 +0000, Piotr Caban wrote:
The patches are introducing new test failures, I'll fix it.
Fixed.
This merge request was approved by Huw Davies.