From: Piotr Caban piotr@codeweavers.com
--- dlls/localspl/localmon.c | 111 +++++++++++++++++++++++++++++---------- 1 file changed, 83 insertions(+), 28 deletions(-)
diff --git a/dlls/localspl/localmon.c b/dlls/localspl/localmon.c index 381b36dd2e2..a982d359058 100644 --- a/dlls/localspl/localmon.c +++ b/dlls/localspl/localmon.c @@ -65,6 +65,7 @@ static CRITICAL_SECTION xcv_handles_cs = { &xcv_handles_cs_debug, -1, 0, 0, 0, 0 typedef struct { struct list entry; DWORD type; + HANDLE hfile; WCHAR nameW[1]; } port_t;
@@ -385,31 +386,6 @@ static BOOL WINAPI localmon_AddPortExW(LPWSTR pName, DWORD level, LPBYTE pBuffer return (res == ERROR_SUCCESS); }
-/***************************************************** - * localmon_ClosePort [exported through MONITOREX] - * - * Close a - * - * PARAMS - * hPort [i] The Handle to close - * - * RETURNS - * Success: TRUE - * Failure: FALSE - * - */ -static BOOL WINAPI localmon_ClosePort(HANDLE hPort) -{ - port_t * port = hPort; - - TRACE("(%p)\n", port); - EnterCriticalSection(&port_handles_cs); - list_remove(&port->entry); - LeaveCriticalSection(&port_handles_cs); - free(port); - return TRUE; -} - /***************************************************** * localmon_EnumPortsW [exported through MONITOREX] * @@ -501,6 +477,7 @@ static BOOL WINAPI localmon_OpenPortW(LPWSTR pName, PHANDLE phPort) if (!port) return FALSE;
port->type = type; + port->hfile = INVALID_HANDLE_VALUE; lstrcpyW(port->nameW, pName); *phPort = port;
@@ -512,6 +489,84 @@ static BOOL WINAPI localmon_OpenPortW(LPWSTR pName, PHANDLE phPort) return TRUE; }
+static BOOL WINAPI localmon_StartDocPort(HANDLE hport, WCHAR *printer_name, + DWORD job_id, DWORD level, BYTE *info) +{ + DOC_INFO_1W *doc_info = (DOC_INFO_1W *)info; + port_t *port = hport; + + TRACE("(%p %s %ld %ld %p)\n", hport, debugstr_w(printer_name), + job_id, level, doc_info); + + if (port->type != PORT_IS_FILE) + { + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return FALSE; + } + + if (port->hfile != INVALID_HANDLE_VALUE) + return TRUE; + + if (!doc_info || !doc_info->pOutputFile) + { + FIXME("set error\n"); + return FALSE; + } + + port->hfile = CreateFileW(doc_info->pOutputFile, GENERIC_WRITE, + FILE_SHARE_READ, NULL, OPEN_ALWAYS, 0, NULL); + return port->hfile != INVALID_HANDLE_VALUE; +} + +static BOOL WINAPI localmon_WritePort(HANDLE hport, BYTE *buf, DWORD size, + DWORD *written) +{ + port_t *port = hport; + + TRACE("(%p %p %lu %p)\n", hport, buf, size, written); + + return WriteFile(port->hfile, buf, size, written, NULL); +} + +static BOOL WINAPI localmon_EndDocPort(HANDLE hport) +{ + port_t *port = hport; + + TRACE("(%p)\n", hport); + + CloseHandle(port->hfile); + port->hfile = INVALID_HANDLE_VALUE; + return TRUE; +} + +/***************************************************** + * localmon_ClosePort [exported through MONITOREX] + * + * Close a Port + * + * PARAMS + * hport [i] The Handle to close + * + * RETURNS + * Success: TRUE + * Failure: FALSE + * + */ +static BOOL WINAPI localmon_ClosePort(HANDLE hport) +{ + port_t *port = hport; + + TRACE("(%p)\n", port); + + localmon_EndDocPort(hport); + + EnterCriticalSection(&port_handles_cs); + list_remove(&port->entry); + LeaveCriticalSection(&port_handles_cs); + free(port); + return TRUE; +} + /***************************************************** * localmon_XcvClosePort [exported through MONITOREX] * @@ -755,10 +810,10 @@ LPMONITOREX WINAPI InitializePrintMonitor(LPWSTR regroot) localmon_EnumPortsW, localmon_OpenPortW, NULL, /* localmon_OpenPortExW */ - NULL, /* localmon_StartDocPortW */ - NULL, /* localmon_WritePortW */ + localmon_StartDocPort, + localmon_WritePort, NULL, /* localmon_ReadPortW */ - NULL, /* localmon_EndDocPortW */ + localmon_EndDocPort, localmon_ClosePort, NULL, /* Use AddPortUI in localui.dll */ localmon_AddPortExW,
From: Piotr Caban piotr@codeweavers.com
--- dlls/localspl/tests/Makefile.in | 2 +- dlls/localspl/tests/localmon.c | 70 +++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-)
diff --git a/dlls/localspl/tests/Makefile.in b/dlls/localspl/tests/Makefile.in index 2c2785fae16..9638788307e 100644 --- a/dlls/localspl/tests/Makefile.in +++ b/dlls/localspl/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = localspl.dll -IMPORTS = advapi32 +IMPORTS = advapi32 winspool
C_SRCS = \ localmon.c diff --git a/dlls/localspl/tests/localmon.c b/dlls/localspl/tests/localmon.c index 9f10ed8e3bf..edc0b1f7cbb 100644 --- a/dlls/localspl/tests/localmon.c +++ b/dlls/localspl/tests/localmon.c @@ -874,6 +874,75 @@ static void test_OpenPort(void)
}
+static void test_file_port(void) +{ + WCHAR printer_name[256]; + DOC_INFO_1W doc_info; + HANDLE hport, hf; + BYTE buf[16]; + DWORD no; + BOOL res; + + if ((!pOpenPort && !pOpenPort2) || !pClosePort || !pStartDocPort || + !pWritePort || !pEndDocPort) + { + win_skip("FILE: port\n"); + return; + } + + no = ARRAY_SIZE(printer_name); + if (!GetDefaultPrinterW(printer_name, &no)) + { + skip("no default printer\n"); + return; + } + + SetLastError(0xdeadbeef); + res = call_OpenPort(tempfileW, &hport); + ok(!res, "OpenPort succeeded\n"); + ok(GetLastError() == 0xdeadbeef, "GetLastError() = %lu\n", GetLastError()); + + res = call_OpenPort((WCHAR *)L"FILE", &hport); + ok(!res, "OpenPort succeeded\n"); + ok(GetLastError() == 0xdeadbeef, "GetLastError() = %lu\n", GetLastError()); + + res = call_OpenPort((WCHAR *)L"FILE:", &hport); + ok(res, "OpenPort failed (%lu)\n", GetLastError()); + + SetLastError(0xdeadbeef); + res = pWritePort(hport, (BYTE *)"test", 4, &no); + ok(!res, "WritePort succeeded\n"); + ok(GetLastError() == ERROR_INVALID_HANDLE, "GetLastError() = %lu\n", GetLastError()); + + doc_info.pDocName = (WCHAR *)L"not used"; + 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()); + + res = pStartDocPort(hport, printer_name, 1, 1, (BYTE *)&doc_info); + ok(res, "StartDocPort failed (%lu)\n", GetLastError()); + + res = pWritePort(hport, (BYTE *)"test", 4, &no); + ok(res, "WritePort failed (%lu)\n", GetLastError()); + ok(no == 4, "no = %ld\n", no); + + res = pEndDocPort(hport); + ok(res, "EndDocPort failed (%lu)\n", GetLastError()); + res = pEndDocPort(hport); + ok(res, "EndDocPort failed (%lu)\n", GetLastError()); + + hf = CreateFileW(tempfileW, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + ok(hf != INVALID_HANDLE_VALUE, "CreateFile failed (%lu)\n", GetLastError()); + res = ReadFile(hf, buf, sizeof(buf), &no, NULL); + ok(res, "ReadFile failed (%lu)\n", GetLastError()); + ok(no == 4, "no = %ld\n", no); + CloseHandle(hf); + + res = pClosePort(hport); + ok(res, "ClosePort failed (%lu)\n", GetLastError()); +} + /* ########################### */
static void test_XcvClosePort(void) @@ -1611,6 +1680,7 @@ START_TEST(localmon) test_DeletePort(); test_EnumPorts(); test_OpenPort(); + test_file_port();
if ( !hXcv ) { skip("Xcv not supported\n");
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=126829
Your paranoid android.
=== debian11 (32 bit report) ===
winhttp: notification.c:117: Test failed: 988: expected status 0x80000 got 0x200000 notification: Timeout
This merge request was approved by Huw Davies.