2 * Unit test suite for localspl API functions: local print monitor
4 * Copyright 2006-2007 Detlef Riekenberg
5 * Copyright 2019 Dmitry Timoshkov
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #include "ddk/winsplp.h"
34 #include "wine/test.h"
40 static HMODULE hlocalmon
;
42 static LPMONITOREX (WINAPI
*pInitializePrintMonitor
)(LPWSTR
);
43 static LPMONITOR2 (WINAPI
*pInitializePrintMonitor2
)(PMONITORINIT
, LPHANDLE
);
45 static LPMONITOREX pm
;
46 static LPMONITOR2 pm2
;
47 static BOOL (WINAPI
*pEnumPorts
)(LPWSTR
, DWORD
, LPBYTE
, DWORD
, LPDWORD
, LPDWORD
);
48 static BOOL (WINAPI
*pEnumPorts2
)(HANDLE
, LPWSTR
, DWORD
, LPBYTE
, DWORD
, LPDWORD
, LPDWORD
);
49 static BOOL (WINAPI
*pOpenPort
)(LPWSTR
, PHANDLE
);
50 static BOOL (WINAPI
*pOpenPort2
)(HANDLE
, LPWSTR
, PHANDLE
);
51 static BOOL (WINAPI
*pOpenPortEx
)(LPWSTR
, LPWSTR
, PHANDLE
, struct _MONITOR
*);
52 static BOOL (WINAPI
*pOpenPortEx2
)(HANDLE
, HANDLE
, LPWSTR
, LPWSTR
, PHANDLE
, struct _MONITOR2
*);
53 static BOOL (WINAPI
*pStartDocPort
)(HANDLE
, LPWSTR
, DWORD
, DWORD
, LPBYTE
);
54 static BOOL (WINAPI
*pWritePort
)(HANDLE hPort
, LPBYTE
, DWORD
, LPDWORD
);
55 static BOOL (WINAPI
*pReadPort
)(HANDLE hPort
, LPBYTE
, DWORD
, LPDWORD
);
56 static BOOL (WINAPI
*pEndDocPort
)(HANDLE
);
57 static BOOL (WINAPI
*pClosePort
)(HANDLE
);
58 static BOOL (WINAPI
*pAddPort
)(LPWSTR
, HWND
, LPWSTR
);
59 static BOOL (WINAPI
*pAddPort2
)(HANDLE
, LPWSTR
, HWND
, LPWSTR
);
60 static BOOL (WINAPI
*pAddPortEx
)(LPWSTR
, DWORD
, LPBYTE
, LPWSTR
);
61 static BOOL (WINAPI
*pAddPortEx2
)(HANDLE
, LPWSTR
, DWORD
, LPBYTE
, LPWSTR
);
62 static BOOL (WINAPI
*pConfigurePort
)(LPWSTR
, HWND
, LPWSTR
);
63 static BOOL (WINAPI
*pConfigurePort2
)(HANDLE
, LPWSTR
, HWND
, LPWSTR
);
64 static BOOL (WINAPI
*pDeletePort
)(LPWSTR
, HWND
, LPWSTR
);
65 static BOOL (WINAPI
*pDeletePort2
)(HANDLE
, LPWSTR
, HWND
, LPWSTR
);
66 static BOOL (WINAPI
*pGetPrinterDataFromPort
)(HANDLE
, DWORD
, LPWSTR
, LPWSTR
, DWORD
, LPWSTR
, DWORD
, LPDWORD
);
67 static BOOL (WINAPI
*pSetPortTimeOuts
)(HANDLE
, LPCOMMTIMEOUTS
, DWORD
);
68 static BOOL (WINAPI
*pXcvOpenPort
)(LPCWSTR
, ACCESS_MASK
, PHANDLE
);
69 static BOOL (WINAPI
*pXcvOpenPort2
)(HANDLE
, LPCWSTR
, ACCESS_MASK
, PHANDLE
);
70 static DWORD (WINAPI
*pXcvDataPort
)(HANDLE
, LPCWSTR
, PBYTE
, DWORD
, PBYTE
, DWORD
, PDWORD
);
71 static BOOL (WINAPI
*pXcvClosePort
)(HANDLE
);
74 static HANDLE hXcv_noaccess
;
76 /* ########################### */
78 static const WCHAR cmd_AddPortW
[] = {'A','d','d','P','o','r','t',0};
79 static const WCHAR cmd_ConfigureLPTPortCommandOKW
[] = {'C','o','n','f','i','g','u','r','e',
80 'L','P','T','P','o','r','t',
81 'C','o','m','m','a','n','d','O','K',0};
82 static const WCHAR cmd_DeletePortW
[] = {'D','e','l','e','t','e','P','o','r','t',0};
83 static const WCHAR cmd_GetTransmissionRetryTimeoutW
[] = {'G','e','t',
84 'T','r','a','n','s','m','i','s','s','i','o','n',
85 'R','e','t','r','y','T','i','m','e','o','u','t',0};
87 static const WCHAR cmd_MonitorUIW
[] = {'M','o','n','i','t','o','r','U','I',0};
88 static const WCHAR cmd_MonitorUI_lcaseW
[] = {'m','o','n','i','t','o','r','u','i',0};
89 static const WCHAR cmd_PortIsValidW
[] = {'P','o','r','t','I','s','V','a','l','i','d',0};
90 static WCHAR does_not_existW
[] = {'d','o','e','s','_','n','o','t','_','e','x','i','s','t',0};
91 static const CHAR emptyA
[] = "";
92 static WCHAR emptyW
[] = {0};
93 static WCHAR LocalPortW
[] = {'L','o','c','a','l',' ','P','o','r','t',0};
94 static WCHAR Monitors_LocalPortW
[] = {
95 'S','y','s','t','e','m','\\',
96 'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
97 'C','o','n','t','r','o','l','\\',
98 'P','r','i','n','t','\\',
99 'M','o','n','i','t','o','r','s','\\',
100 'L','o','c','a','l',' ','P','o','r','t',0};
102 static const CHAR num_0A
[] = "0";
103 static WCHAR num_0W
[] = {'0',0};
104 static const CHAR num_1A
[] = "1";
105 static WCHAR num_1W
[] = {'1',0};
106 static const CHAR num_999999A
[] = "999999";
107 static WCHAR num_999999W
[] = {'9','9','9','9','9','9',0};
108 static const CHAR num_1000000A
[] = "1000000";
109 static WCHAR num_1000000W
[] = {'1','0','0','0','0','0','0',0};
111 static const WCHAR portname_comW
[] = {'C','O','M',0};
112 static WCHAR portname_com1W
[] = {'C','O','M','1',':',0};
113 static WCHAR portname_com2W
[] = {'C','O','M','2',':',0};
114 static WCHAR portname_fileW
[] = {'F','I','L','E',':',0};
115 static const WCHAR portname_lptW
[] = {'L','P','T',0};
116 static WCHAR portname_lpt1W
[] = {'L','P','T','1',':',0};
117 static WCHAR portname_lpt2W
[] = {'L','P','T','2',':',0};
118 static WCHAR server_does_not_existW
[] = {'\\','\\','d','o','e','s','_','n','o','t','_','e','x','i','s','t',0};
120 static const CHAR TransmissionRetryTimeoutA
[] = {'T','r','a','n','s','m','i','s','s','i','o','n',
121 'R','e','t','r','y','T','i','m','e','o','u','t',0};
123 static const CHAR WinNT_CV_WindowsA
[] = {'S','o','f','t','w','a','r','e','\\',
124 'M','i','c','r','o','s','o','f','t','\\',
125 'W','i','n','d','o','w','s',' ','N','T','\\',
126 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
127 'W','i','n','d','o','w','s',0};
128 static WCHAR wineW
[] = {'W','i','n','e',0};
130 static WCHAR tempdirW
[MAX_PATH
];
131 static WCHAR tempfileW
[MAX_PATH
];
133 #define PORTNAME_PREFIX 3
134 #define PORTNAME_MINSIZE 5
135 #define PORTNAME_MAXSIZE 10
136 static WCHAR have_com
[PORTNAME_MAXSIZE
];
137 static WCHAR have_lpt
[PORTNAME_MAXSIZE
];
138 static WCHAR have_file
[PORTNAME_MAXSIZE
];
140 /* ########################### */
142 static LONG WINAPI
CreateKey(HANDLE hcKey
, LPCWSTR pszSubKey
, DWORD dwOptions
,
143 REGSAM samDesired
, PSECURITY_ATTRIBUTES pSecurityAttributes
,
144 PHANDLE phckResult
, PDWORD pdwDisposition
, HANDLE hSpooler
)
146 ok(0, "should not be called\n");
147 return ERROR_CALL_NOT_IMPLEMENTED
;
150 static LONG WINAPI
OpenKey(HANDLE hcKey
, LPCWSTR pszSubKey
, REGSAM samDesired
,
151 PHANDLE phkResult
, HANDLE hSpooler
)
153 ok(0, "should not be called\n");
154 return ERROR_CALL_NOT_IMPLEMENTED
;
157 static LONG WINAPI
CloseKey(HANDLE hcKey
, HANDLE hSpooler
)
159 ok(0, "should not be called\n");
160 return ERROR_CALL_NOT_IMPLEMENTED
;
163 static LONG WINAPI
DeleteKey(HANDLE hcKey
, LPCWSTR pszSubKey
, HANDLE hSpooler
)
165 ok(0, "should not be called\n");
166 return ERROR_CALL_NOT_IMPLEMENTED
;
169 static LONG WINAPI
EnumKey(HANDLE hcKey
, DWORD dwIndex
, LPWSTR pszName
,
170 PDWORD pcchName
, PFILETIME pftLastWriteTime
, HANDLE hSpooler
)
172 ok(0, "should not be called\n");
173 return ERROR_CALL_NOT_IMPLEMENTED
;
176 static LONG WINAPI
QueryInfoKey(HANDLE hcKey
, PDWORD pcSubKeys
, PDWORD pcbKey
,
177 PDWORD pcValues
, PDWORD pcbValue
, PDWORD pcbData
,
178 PDWORD pcbSecurityDescriptor
, PFILETIME pftLastWriteTime
,
181 ok(0, "should not be called\n");
182 return ERROR_CALL_NOT_IMPLEMENTED
;
185 static LONG WINAPI
SetValue(HANDLE hcKey
, LPCWSTR pszValue
, DWORD dwType
,
186 const BYTE
* pData
, DWORD cbData
, HANDLE hSpooler
)
188 ok(0, "should not be called\n");
189 return ERROR_CALL_NOT_IMPLEMENTED
;
192 static LONG WINAPI
DeleteValue(HANDLE hcKey
, LPCWSTR pszValue
, HANDLE hSpooler
)
194 ok(0, "should not be called\n");
195 return ERROR_CALL_NOT_IMPLEMENTED
;
198 static LONG WINAPI
EnumValue(HANDLE hcKey
, DWORD dwIndex
, LPWSTR pszValue
,
199 PDWORD pcbValue
, PDWORD pType
, PBYTE pData
, PDWORD pcbData
,
202 ok(0, "should not be called\n");
203 return ERROR_CALL_NOT_IMPLEMENTED
;
206 static LONG WINAPI
QueryValue(HANDLE hcKey
, LPCWSTR pszValue
, PDWORD pType
,
207 PBYTE pData
, PDWORD pcbData
, HANDLE hSpooler
)
209 return ERROR_CALL_NOT_IMPLEMENTED
;
212 static MONITORREG monreg
=
227 static DWORD
delete_port(LPWSTR portname
)
232 res
= pDeletePort(NULL
, 0, portname
);
236 res
= pXcvDataPort(hXcv
, cmd_DeletePortW
, (PBYTE
) portname
, (lstrlenW(portname
) + 1) * sizeof(WCHAR
), NULL
, 0, NULL
);
241 /* ########################### */
243 static void find_installed_ports(void)
245 PORT_INFO_1W
* pi
= NULL
;
246 WCHAR nameW
[PORTNAME_MAXSIZE
];
256 if (!pEnumPorts
) return;
258 res
= pEnumPorts(NULL
, 1, NULL
, 0, &needed
, &returned
);
259 if (!res
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
)) {
260 pi
= HeapAlloc(GetProcessHeap(), 0, needed
);
262 res
= pEnumPorts(NULL
, 1, (LPBYTE
) pi
, needed
, &needed
, &returned
);
265 skip("no ports found\n");
266 HeapFree(GetProcessHeap(), 0, pi
);
271 while (id
< returned
) {
272 res
= lstrlenW(pi
[id
].pName
);
273 if ((res
>= PORTNAME_MINSIZE
) && (res
< PORTNAME_MAXSIZE
) &&
274 (pi
[id
].pName
[res
-1] == ':')) {
275 /* copy only the prefix ("LPT" or "COM") */
276 memcpy(&nameW
, pi
[id
].pName
, PORTNAME_PREFIX
* sizeof(WCHAR
));
277 nameW
[PORTNAME_PREFIX
] = '\0';
279 if (!have_com
[0] && (lstrcmpiW(nameW
, portname_comW
) == 0)) {
280 memcpy(&have_com
, pi
[id
].pName
, (res
+1) * sizeof(WCHAR
));
283 if (!have_lpt
[0] && (lstrcmpiW(nameW
, portname_lptW
) == 0)) {
284 memcpy(&have_lpt
, pi
[id
].pName
, (res
+1) * sizeof(WCHAR
));
287 if (!have_file
[0] && (lstrcmpiW(pi
[id
].pName
, portname_fileW
) == 0)) {
288 memcpy(&have_file
, pi
[id
].pName
, (res
+1) * sizeof(WCHAR
));
294 HeapFree(GetProcessHeap(), 0, pi
);
297 /* ########################### */
299 static void test_AddPort(void)
303 /* moved to localui.dll since w2k */
304 if (!pAddPort
) return;
308 /* NT4 crash on this test */
309 pAddPort(NULL
, 0, NULL
);
312 /* Testing-Results (localmon.dll from NT4.0):
313 - The Servername is ignored
314 - Case of MonitorName is ignored
317 SetLastError(0xdeadbeef);
318 res
= pAddPort(NULL
, 0, emptyW
);
319 ok(!res
, "returned %d with %u (expected '0')\n", res
, GetLastError());
321 SetLastError(0xdeadbeef);
322 res
= pAddPort(NULL
, 0, does_not_existW
);
323 ok(!res
, "returned %d with %u (expected '0')\n", res
, GetLastError());
327 /* ########################### */
329 static void test_AddPortEx(void)
338 if ((!pDeletePort
) && (!hXcv
)) {
339 skip("No API to delete a Port\n");
343 /* start test with clean ports */
344 delete_port(tempfileW
);
346 pi
.pPortName
= tempfileW
;
348 /* tests crash with native localspl.dll in w2k,
349 but works with native localspl.dll in wine */
350 SetLastError(0xdeadbeef);
351 res
= pAddPortEx(NULL
, 1, (LPBYTE
) &pi
, LocalPortW
);
352 trace("returned %u with %u\n", res
, GetLastError() );
353 ok( res
, "got %u with %u (expected '!= 0')\n", res
, GetLastError());
355 /* port already exists: */
356 SetLastError(0xdeadbeef);
357 res
= pAddPortEx(NULL
, 1, (LPBYTE
) &pi
, LocalPortW
);
358 trace("returned %u with %u\n", res
, GetLastError() );
359 ok( !res
&& (GetLastError() == ERROR_INVALID_PARAMETER
),
360 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
361 res
, GetLastError());
362 delete_port(tempfileW
);
365 /* NULL for pMonitorName is documented for Printmonitors, but
366 localspl.dll fails always with ERROR_INVALID_PARAMETER */
367 SetLastError(0xdeadbeef);
368 res
= pAddPortEx(NULL
, 1, (LPBYTE
) &pi
, NULL
);
369 trace("returned %u with %u\n", res
, GetLastError() );
370 ok( !res
&& (GetLastError() == ERROR_INVALID_PARAMETER
),
371 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
372 res
, GetLastError());
373 if (res
) delete_port(tempfileW
);
376 SetLastError(0xdeadbeef);
377 res
= pAddPortEx(NULL
, 1, (LPBYTE
) &pi
, emptyW
);
378 trace("returned %u with %u\n", res
, GetLastError() );
379 ok( !res
&& (GetLastError() == ERROR_INVALID_PARAMETER
),
380 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
381 res
, GetLastError());
382 if (res
) delete_port(tempfileW
);
385 SetLastError(0xdeadbeef);
386 res
= pAddPortEx(NULL
, 1, (LPBYTE
) &pi
, does_not_existW
);
387 trace("returned %u with %u\n", res
, GetLastError() );
388 ok( !res
&& (GetLastError() == ERROR_INVALID_PARAMETER
),
389 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
390 res
, GetLastError());
391 if (res
) delete_port(tempfileW
);
395 SetLastError(0xdeadbeef);
396 res
= pAddPortEx(NULL
, 1, (LPBYTE
) &pi
, LocalPortW
);
397 ok( !res
&& (GetLastError() == ERROR_INVALID_PARAMETER
),
398 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n",
399 res
, GetLastError());
401 /* level 2 is documented as supported for Printmonitors,
402 but localspl.dll fails always with ERROR_INVALID_LEVEL */
404 pi
.pPortName
= tempfileW
;
405 pi
.pMonitorName
= LocalPortW
;
406 pi
.pDescription
= wineW
;
407 pi
.fPortType
= PORT_TYPE_WRITE
;
409 SetLastError(0xdeadbeef);
410 res
= pAddPortEx(NULL
, 2, (LPBYTE
) &pi
, LocalPortW
);
411 ok( !res
&& (GetLastError() == ERROR_INVALID_LEVEL
),
412 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
413 res
, GetLastError());
414 if (res
) delete_port(tempfileW
);
418 SetLastError(0xdeadbeef);
419 res
= pAddPortEx(NULL
, 0, (LPBYTE
) &pi
, LocalPortW
);
420 ok( !res
&& (GetLastError() == ERROR_INVALID_LEVEL
),
421 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
422 res
, GetLastError());
423 if (res
) delete_port(tempfileW
);
426 SetLastError(0xdeadbeef);
427 res
= pAddPortEx(NULL
, 3, (LPBYTE
) &pi
, LocalPortW
);
428 ok( !res
&& (GetLastError() == ERROR_INVALID_LEVEL
),
429 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n",
430 res
, GetLastError());
431 if (res
) delete_port(tempfileW
);
434 delete_port(tempfileW
);
437 /* ########################### */
439 static void test_ClosePort(void)
448 if (!pOpenPort
|| !pClosePort
) return;
453 hPort
= (HANDLE
) 0xdeadbeef;
454 res
= pOpenPort(nameW
, &hPort
);
455 hPort2
= (HANDLE
) 0xdeadbeef;
456 res2
= pOpenPort(nameW
, &hPort2
);
458 if (res2
&& (hPort2
!= hPort
)) {
459 SetLastError(0xdeadbeef);
460 res2
= pClosePort(hPort2
);
461 ok(res2
, "got %u with %u (expected '!= 0')\n", res2
, GetLastError());
465 SetLastError(0xdeadbeef);
466 res
= pClosePort(hPort
);
467 ok(res
, "got %u with %u (expected '!= 0')\n", res
, GetLastError());
475 hPort
= (HANDLE
) 0xdeadbeef;
476 res
= pOpenPort(nameW
, &hPort
);
477 hPort2
= (HANDLE
) 0xdeadbeef;
478 res2
= pOpenPort(nameW
, &hPort2
);
480 if (res2
&& (hPort2
!= hPort
)) {
481 SetLastError(0xdeadbeef);
482 res2
= pClosePort(hPort2
);
483 ok(res2
, "got %u with %u (expected '!= 0')\n", res2
, GetLastError());
487 SetLastError(0xdeadbeef);
488 res
= pClosePort(hPort
);
489 ok(res
, "got %u with %u (expected '!= 0')\n", res
, GetLastError());
497 hPort
= (HANDLE
) 0xdeadbeef;
498 res
= pOpenPort(nameW
, &hPort
);
499 hPort2
= (HANDLE
) 0xdeadbeef;
500 res2
= pOpenPort(nameW
, &hPort2
);
502 if (res2
&& (hPort2
!= hPort
)) {
503 SetLastError(0xdeadbeef);
504 res2
= pClosePort(hPort2
);
505 ok(res2
, "got %u with %u (expected '!= 0')\n", res2
, GetLastError());
509 SetLastError(0xdeadbeef);
510 res
= pClosePort(hPort
);
511 ok(res
, "got %u with %u (expected '!= 0')\n", res
, GetLastError());
517 /* an invalid HANDLE crash native localspl.dll */
519 SetLastError(0xdeadbeef);
520 res
= pClosePort(NULL
);
521 trace("got %u with %u\n", res
, GetLastError());
523 SetLastError(0xdeadbeef);
524 res
= pClosePort( (HANDLE
) 0xdeadbeef);
525 trace("got %u with %u\n", res
, GetLastError());
527 SetLastError(0xdeadbeef);
528 res
= pClosePort(INVALID_HANDLE_VALUE
);
529 trace("got %u with %u\n", res
, GetLastError());
534 /* ########################### */
536 static void test_ConfigurePort(void)
540 /* moved to localui.dll since w2k */
541 if (!pConfigurePort
) return;
545 /* NT4 crash on this test */
546 pConfigurePort(NULL
, 0, NULL
);
549 /* Testing-Results (localmon.dll from NT4.0):
550 - Case of Portname is ignored
551 - "COM1:" and "COM01:" are the same (Compared by value)
552 - Portname without ":" => Dialog "Nothing to configure" comes up; Success
553 - "LPT1:", "LPT0:" and "LPT:" are the same (Numbers in "LPT:" are ignored)
554 - Empty Servername (LPT1:) => Dialog comes up (Servername is ignored)
555 - "FILE:" => Dialog "Nothing to configure" comes up; Success
556 - Empty Portname => => Dialog "Nothing to configure" comes up; Success
557 - Port "does_not_exist" => Dialog "Nothing to configure" comes up; Success
559 if (winetest_interactive
> 0) {
561 SetLastError(0xdeadbeef);
562 res
= pConfigurePort(NULL
, 0, portname_com1W
);
563 trace("returned %d with %u\n", res
, GetLastError());
565 SetLastError(0xdeadbeef);
566 res
= pConfigurePort(NULL
, 0, portname_lpt1W
);
567 trace("returned %d with %u\n", res
, GetLastError());
569 SetLastError(0xdeadbeef);
570 res
= pConfigurePort(NULL
, 0, portname_fileW
);
571 trace("returned %d with %u\n", res
, GetLastError());
575 /* ########################### */
577 static void test_DeletePort(void)
581 /* moved to localui.dll since w2k */
582 if (!pDeletePort
) return;
586 /* NT4 crash on this test */
587 pDeletePort(NULL
, 0, NULL
);
590 /* Testing-Results (localmon.dll from NT4.0):
591 - Case of Portname is ignored (returned '1' on Success)
592 - "COM1:" and "COM01:" are different (Compared as string)
593 - server_does_not_exist (LPT1:) => Port deleted, Success (Servername is ignored)
594 - Empty Portname => => FALSE (LastError not changed)
595 - Port "does_not_exist" => FALSE (LastError not changed)
598 SetLastError(0xdeadbeef);
599 res
= pDeletePort(NULL
, 0, emptyW
);
600 ok(!res
, "returned %d with %u (expected '0')\n", res
, GetLastError());
602 SetLastError(0xdeadbeef);
603 res
= pDeletePort(NULL
, 0, does_not_existW
);
604 ok(!res
, "returned %d with %u (expected '0')\n", res
, GetLastError());
608 /* ########################### */
610 static void test_EnumPorts(void)
619 if (!pEnumPorts
) return;
621 /* valid levels are 1 and 2 */
622 for(level
= 0; level
< 4; level
++) {
625 pcReturned
= 0xdeadbeef;
626 SetLastError(0xdeadbeef);
627 res
= pEnumPorts(NULL
, level
, NULL
, 0, &cbBuf
, &pcReturned
);
629 /* use only a short test, when we test with an invalid level */
630 if(!level
|| (level
> 2)) {
631 /* NT4 fails with ERROR_INVALID_LEVEL (as expected)
632 XP succeeds with ERROR_SUCCESS () */
633 ok( (cbBuf
== 0) && (pcReturned
== 0),
634 "(%d) returned %d with %u and %d, %d (expected 0, 0)\n",
635 level
, res
, GetLastError(), cbBuf
, pcReturned
);
639 ok( !res
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
640 "(%d) returned %d with %u and %d, %d (expected '0' with "
641 "ERROR_INSUFFICIENT_BUFFER)\n",
642 level
, res
, GetLastError(), cbBuf
, pcReturned
);
644 buffer
= HeapAlloc(GetProcessHeap(), 0, cbBuf
* 2);
645 if (buffer
== NULL
) continue;
647 pcbNeeded
= 0xdeadbeef;
648 pcReturned
= 0xdeadbeef;
649 SetLastError(0xdeadbeef);
650 res
= pEnumPorts(NULL
, level
, buffer
, cbBuf
, &pcbNeeded
, &pcReturned
);
651 ok( res
, "(%d) returned %d with %u and %d, %d (expected '!= 0')\n",
652 level
, res
, GetLastError(), pcbNeeded
, pcReturned
);
653 /* We can compare the returned Data with the Registry / "win.ini",[Ports] here */
655 pcbNeeded
= 0xdeadbeef;
656 pcReturned
= 0xdeadbeef;
657 SetLastError(0xdeadbeef);
658 res
= pEnumPorts(NULL
, level
, buffer
, cbBuf
+1, &pcbNeeded
, &pcReturned
);
659 ok( res
, "(%d) returned %d with %u and %d, %d (expected '!= 0')\n",
660 level
, res
, GetLastError(), pcbNeeded
, pcReturned
);
662 pcbNeeded
= 0xdeadbeef;
663 pcReturned
= 0xdeadbeef;
664 SetLastError(0xdeadbeef);
665 res
= pEnumPorts(NULL
, level
, buffer
, cbBuf
-1, &pcbNeeded
, &pcReturned
);
666 ok( !res
&& (GetLastError() == ERROR_INSUFFICIENT_BUFFER
),
667 "(%d) returned %d with %u and %d, %d (expected '0' with "
668 "ERROR_INSUFFICIENT_BUFFER)\n",
669 level
, res
, GetLastError(), pcbNeeded
, pcReturned
);
673 /* The following tests crash this app with native localmon/localspl */
674 pEnumPorts(NULL
, level
, NULL
, cbBuf
, &pcbNeeded
, &pcReturned
);
675 pEnumPorts(NULL
, level
, buffer
, cbBuf
, NULL
, &pcReturned
);
676 pEnumPorts(NULL
, level
, buffer
, cbBuf
, &pcbNeeded
, NULL
);
679 /* The Servername is ignored */
680 pcbNeeded
= 0xdeadbeef;
681 pcReturned
= 0xdeadbeef;
682 SetLastError(0xdeadbeef);
683 res
= pEnumPorts(emptyW
, level
, buffer
, cbBuf
+1, &pcbNeeded
, &pcReturned
);
684 ok( res
, "(%d) returned %d with %u and %d, %d (expected '!= 0')\n",
685 level
, res
, GetLastError(), pcbNeeded
, pcReturned
);
687 pcbNeeded
= 0xdeadbeef;
688 pcReturned
= 0xdeadbeef;
689 SetLastError(0xdeadbeef);
690 res
= pEnumPorts(server_does_not_existW
, level
, buffer
, cbBuf
+1, &pcbNeeded
, &pcReturned
);
691 ok( res
, "(%d) returned %d with %u and %d, %d (expected '!= 0')\n",
692 level
, res
, GetLastError(), pcbNeeded
, pcReturned
);
694 HeapFree(GetProcessHeap(), 0, buffer
);
698 /* ########################### */
701 static void test_InitializePrintMonitor(void)
705 if (!pInitializePrintMonitor
) return;
707 SetLastError(0xdeadbeef);
708 res
= pInitializePrintMonitor(NULL
);
709 /* The Parameter was unchecked before w2k */
710 ok( res
|| (GetLastError() == ERROR_INVALID_PARAMETER
),
711 "returned %p with %u\n (expected '!= NULL' or: NULL with "
712 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
714 SetLastError(0xdeadbeef);
715 res
= pInitializePrintMonitor(emptyW
);
716 ok( res
|| (GetLastError() == ERROR_INVALID_PARAMETER
),
717 "returned %p with %u\n (expected '!= NULL' or: NULL with "
718 "ERROR_INVALID_PARAMETER)\n", res
, GetLastError());
720 /* Every call with a non-empty string returns the same Pointer */
721 SetLastError(0xdeadbeef);
722 res
= pInitializePrintMonitor(Monitors_LocalPortW
);
724 "returned %p with %u (expected %p)\n", res
, GetLastError(), pm
);
725 ok(res
->dwMonitorSize
== sizeof(MONITOR
), "wrong dwMonitorSize %u\n", res
->dwMonitorSize
);
728 static void test_InitializePrintMonitor2(void)
734 if (!pInitializePrintMonitor2
) return;
736 memset(&init
, 0, sizeof(init
));
737 init
.cbSize
= sizeof(init
);
738 init
.hckRegistryRoot
= 0;
739 init
.pMonitorReg
= &monreg
;
742 monitor2
= pInitializePrintMonitor2(&init
, &hmon
);
743 ok(monitor2
!= NULL
, "InitializePrintMonitor2 error %u\n", GetLastError());
744 ok(monitor2
->cbSize
>= FIELD_OFFSET(MONITOR2
, pfnSendRecvBidiDataFromPort
), "wrong cbSize %u\n", monitor2
->cbSize
);
747 /* ########################### */
749 static void test_OpenPort(void)
757 if (!pOpenPort
|| !pClosePort
) return;
762 hPort
= (HANDLE
) 0xdeadbeef;
763 SetLastError(0xdeadbeef);
764 res
= pOpenPort(nameW
, &hPort
);
765 ok( res
, "got %u with %u and %p (expected '!= 0')\n",
766 res
, GetLastError(), hPort
);
768 /* the same HANDLE is returned for a second OpenPort in native localspl */
769 hPort2
= (HANDLE
) 0xdeadbeef;
770 SetLastError(0xdeadbeef);
771 res2
= pOpenPort(nameW
, &hPort2
);
772 ok( res2
, "got %u with %u and %p (expected '!= 0')\n",
773 res2
, GetLastError(), hPort2
);
775 if (res
) pClosePort(hPort
);
776 if (res2
&& (hPort2
!= hPort
)) pClosePort(hPort2
);
782 hPort
= (HANDLE
) 0xdeadbeef;
783 SetLastError(0xdeadbeef);
784 res
= pOpenPort(nameW
, &hPort
);
785 ok( res
|| (GetLastError() == ERROR_ACCESS_DENIED
),
786 "got %u with %u and %p (expected '!= 0' or '0' with ERROR_ACCESS_DENIED)\n",
787 res
, GetLastError(), hPort
);
789 /* the same HANDLE is returned for a second OpenPort in native localspl */
790 hPort2
= (HANDLE
) 0xdeadbeef;
791 SetLastError(0xdeadbeef);
792 res2
= pOpenPort(nameW
, &hPort2
);
793 ok( res2
|| (GetLastError() == ERROR_ACCESS_DENIED
),
794 "got %u with %u and %p (expected '!= 0' or '0' with ERROR_ACCESS_DENIED)\n",
795 res2
, GetLastError(), hPort2
);
797 if (res
) pClosePort(hPort
);
798 if (res2
&& (hPort2
!= hPort
)) pClosePort(hPort2
);
804 hPort
= (HANDLE
) 0xdeadbeef;
805 SetLastError(0xdeadbeef);
806 res
= pOpenPort(nameW
, &hPort
);
807 ok( res
, "got %u with %u and %p (expected '!= 0')\n",
808 res
, GetLastError(), hPort
);
810 /* a different HANDLE is returned for a second OpenPort */
811 hPort2
= (HANDLE
) 0xdeadbeef;
812 SetLastError(0xdeadbeef);
813 res2
= pOpenPort(nameW
, &hPort2
);
814 ok( res2
&& (hPort2
!= hPort
),
815 "got %u with %u and %p (expected '!= 0' and '!= %p')\n",
816 res2
, GetLastError(), hPort2
, hPort
);
818 if (res
) pClosePort(hPort
);
819 if (res2
&& (hPort2
!= hPort
)) pClosePort(hPort2
);
823 /* this test crash native localspl (w2k+xp) */
825 hPort
= (HANDLE
) 0xdeadbeef;
826 SetLastError(0xdeadbeef);
827 res
= pOpenPort(nameW
, NULL
);
828 trace("got %u with %u and %p\n", res
, GetLastError(), hPort
);
832 hPort
= (HANDLE
) 0xdeadbeef;
833 SetLastError(0xdeadbeef);
834 res
= pOpenPort(does_not_existW
, &hPort
);
835 ok (!res
&& (hPort
== (HANDLE
) 0xdeadbeef),
836 "got %u with 0x%x and %p (expected '0' and 0xdeadbeef)\n", res
, GetLastError(), hPort
);
837 if (res
) pClosePort(hPort
);
839 hPort
= (HANDLE
) 0xdeadbeef;
840 SetLastError(0xdeadbeef);
841 res
= pOpenPort(emptyW
, &hPort
);
842 ok (!res
&& (hPort
== (HANDLE
) 0xdeadbeef),
843 "got %u with 0x%x and %p (expected '0' and 0xdeadbeef)\n", res
, GetLastError(), hPort
);
844 if (res
) pClosePort(hPort
);
847 /* NULL as name crash native localspl (w2k+xp) */
849 hPort
= (HANDLE
) 0xdeadbeef;
850 SetLastError(0xdeadbeef);
851 res
= pOpenPort(NULL
, &hPort
);
852 trace("got %u with %u and %p\n", res
, GetLastError(), hPort
);
857 /* ########################### */
859 static void test_XcvClosePort(void)
867 /* crash with native localspl.dll (w2k+xp) */
869 pXcvClosePort(INVALID_HANDLE_VALUE
);
873 SetLastError(0xdeadbeef);
874 hXcv2
= (HANDLE
) 0xdeadbeef;
875 res
= pXcvOpenPort(emptyW
, SERVER_ACCESS_ADMINISTER
, &hXcv2
);
876 ok(res
, "returned %d with %u and %p (expected '!= 0')\n", res
, GetLastError(), hXcv2
);
879 SetLastError(0xdeadbeef);
880 res
= pXcvClosePort(hXcv2
);
881 ok(res
, "returned %d with %u (expected '!= 0')\n", res
, GetLastError());
885 /* test for "Double Free": crash with native localspl.dll (w2k+xp) */
886 pXcvClosePort(hXcv2
);
891 /* ########################### */
893 static void test_XcvDataPort_AddPort(void)
898 * The following tests crash with native localspl.dll on w2k and xp,
899 * but it works, when the native dll (w2k and xp) is used in wine.
900 * also tested (same crash): replacing emptyW with portname_lpt1W
901 * and replacing "NULL, 0, NULL" with "buffer, MAX_PATH, &needed"
903 * We need to use a different API (AddPortEx) instead
907 /* create a Port for a normal, writable file */
908 SetLastError(0xdeadbeef);
909 res
= pXcvDataPort(hXcv
, cmd_AddPortW
, (PBYTE
) tempfileW
, (lstrlenW(tempfileW
) + 1) * sizeof(WCHAR
), NULL
, 0, NULL
);
910 ok( res
== ERROR_SUCCESS
, "returned %d with %u (expected ERROR_SUCCESS)\n", res
, GetLastError());
912 /* add our testport again */
913 SetLastError(0xdeadbeef);
914 res
= pXcvDataPort(hXcv
, cmd_AddPortW
, (PBYTE
) tempfileW
, (lstrlenW(tempfileW
) + 1) * sizeof(WCHAR
), NULL
, 0, NULL
);
915 ok( res
== ERROR_ALREADY_EXISTS
, "returned %d with %u (expected ERROR_ALREADY_EXISTS)\n", res
, GetLastError());
917 /* create a well-known Port */
918 SetLastError(0xdeadbeef);
919 res
= pXcvDataPort(hXcv
, cmd_AddPortW
, (PBYTE
) portname_lpt1W
, (lstrlenW(portname_lpt1W
) + 1) * sizeof(WCHAR
), NULL
, 0, NULL
);
920 ok( res
== ERROR_ALREADY_EXISTS
, "returned %d with %u (expected ERROR_ALREADY_EXISTS)\n", res
, GetLastError());
922 /* ERROR_ALREADY_EXISTS is also returned from native localspl.dll on wine,
923 when "RPT1:" was already installed for redmonnt.dll:
924 res = pXcvDataPort(hXcv, cmd_AddPortW, (PBYTE) portname_rpt1W, ...
928 SetLastError(0xdeadbeef);
929 res
= pXcvDataPort(hXcv
, cmd_DeletePortW
, (PBYTE
) tempfileW
, (lstrlenW(tempfileW
) + 1) * sizeof(WCHAR
), NULL
, 0, NULL
);
930 ok( res
== ERROR_SUCCESS
, "returned %d with %u (expected ERROR_SUCCESS)\n", res
, GetLastError());
935 /* ########################### */
937 static void test_XcvDataPort_ConfigureLPTPortCommandOK(void)
946 /* Read the original value from the registry */
947 res
= RegOpenKeyExA(HKEY_LOCAL_MACHINE
, WinNT_CV_WindowsA
, 0, KEY_ALL_ACCESS
, &hroot
);
948 if (res
== ERROR_ACCESS_DENIED
) {
949 skip("ACCESS_DENIED\n");
953 if (res
!= ERROR_SUCCESS
) {
954 /* unable to open the registry: skip the test */
955 skip("got %d\n", res
);
959 needed
= sizeof(org_value
)-1 ;
960 res
= RegQueryValueExA(hroot
, TransmissionRetryTimeoutA
, NULL
, NULL
, (PBYTE
) org_value
, &needed
);
961 ok( (res
== ERROR_SUCCESS
) || (res
== ERROR_FILE_NOT_FOUND
),
962 "returned %u and %u for \"%s\" (expected ERROR_SUCCESS or "
963 "ERROR_FILE_NOT_FOUND)\n", res
, needed
, org_value
);
965 RegDeleteValueA(hroot
, TransmissionRetryTimeoutA
);
968 needed
= (DWORD
) 0xdeadbeef;
969 SetLastError(0xdeadbeef);
970 res
= pXcvDataPort(hXcv
, cmd_ConfigureLPTPortCommandOKW
, (PBYTE
) num_0W
, sizeof(num_0W
), NULL
, 0, &needed
);
971 if (res
== ERROR_INVALID_PARAMETER
) {
972 skip("'ConfigureLPTPortCommandOK' not supported\n");
975 ok( res
== ERROR_SUCCESS
, "returned %d with %u (expected ERROR_SUCCESS)\n", res
, GetLastError());
976 needed
= sizeof(buffer
)-1 ;
977 res
= RegQueryValueExA(hroot
, TransmissionRetryTimeoutA
, NULL
, NULL
, (PBYTE
) buffer
, &needed
);
978 ok( (res
== ERROR_SUCCESS
) && (lstrcmpA(buffer
, num_0A
) == 0),
979 "returned %d and '%s' (expected ERROR_SUCCESS and '%s')\n",
980 res
, buffer
, num_0A
);
984 needed
= (DWORD
) 0xdeadbeef;
985 SetLastError(0xdeadbeef);
986 res
= pXcvDataPort(hXcv
, cmd_ConfigureLPTPortCommandOKW
, (PBYTE
) num_1W
, sizeof(num_1W
), NULL
, 0, &needed
);
987 ok( res
== ERROR_SUCCESS
, "returned %d with %u (expected ERROR_SUCCESS)\n", res
, GetLastError());
988 needed
= sizeof(buffer
)-1 ;
989 res
= RegQueryValueExA(hroot
, TransmissionRetryTimeoutA
, NULL
, NULL
, (PBYTE
) buffer
, &needed
);
990 ok( (res
== ERROR_SUCCESS
) && (lstrcmpA(buffer
, num_1A
) == 0),
991 "returned %d and '%s' (expected ERROR_SUCCESS and '%s')\n",
992 res
, buffer
, num_1A
);
994 /* set to "999999" */
995 needed
= (DWORD
) 0xdeadbeef;
996 SetLastError(0xdeadbeef);
997 res
= pXcvDataPort(hXcv
, cmd_ConfigureLPTPortCommandOKW
, (PBYTE
) num_999999W
, sizeof(num_999999W
), NULL
, 0, &needed
);
998 ok( res
== ERROR_SUCCESS
, "returned %d with %u (expected ERROR_SUCCESS)\n", res
, GetLastError());
999 needed
= sizeof(buffer
)-1 ;
1000 res
= RegQueryValueExA(hroot
, TransmissionRetryTimeoutA
, NULL
, NULL
, (PBYTE
) buffer
, &needed
);
1001 ok( (res
== ERROR_SUCCESS
) && (lstrcmpA(buffer
, num_999999A
) == 0),
1002 "returned %d and '%s' (expected ERROR_SUCCESS and '%s')\n",
1003 res
, buffer
, num_999999A
);
1005 /* set to "1000000" */
1006 needed
= (DWORD
) 0xdeadbeef;
1007 SetLastError(0xdeadbeef);
1008 res
= pXcvDataPort(hXcv
, cmd_ConfigureLPTPortCommandOKW
, (PBYTE
) num_1000000W
, sizeof(num_1000000W
), NULL
, 0, &needed
);
1009 ok( res
== ERROR_SUCCESS
, "returned %d with %u (expected ERROR_SUCCESS)\n", res
, GetLastError());
1010 needed
= sizeof(buffer
)-1 ;
1011 res
= RegQueryValueExA(hroot
, TransmissionRetryTimeoutA
, NULL
, NULL
, (PBYTE
) buffer
, &needed
);
1012 ok( (res
== ERROR_SUCCESS
) && (lstrcmpA(buffer
, num_1000000A
) == 0),
1013 "returned %d and '%s' (expected ERROR_SUCCESS and '%s')\n",
1014 res
, buffer
, num_1000000A
);
1016 /* using cmd_ConfigureLPTPortCommandOKW with does_not_existW:
1017 the string "does_not_exist" is written to the registry */
1020 /* restore the original value */
1021 RegDeleteValueA(hroot
, TransmissionRetryTimeoutA
);
1023 res
= RegSetValueExA(hroot
, TransmissionRetryTimeoutA
, 0, REG_SZ
, (PBYTE
)org_value
, lstrlenA(org_value
)+1);
1024 ok(res
== ERROR_SUCCESS
, "unable to restore original value (got %u): %s\n", res
, org_value
);
1031 /* ########################### */
1033 static void test_XcvDataPort_DeletePort(void)
1039 /* cleanup: just to make sure */
1040 needed
= (DWORD
) 0xdeadbeef;
1041 SetLastError(0xdeadbeef);
1042 res
= pXcvDataPort(hXcv
, cmd_DeletePortW
, (PBYTE
) tempfileW
, (lstrlenW(tempfileW
) + 1) * sizeof(WCHAR
), NULL
, 0, &needed
);
1043 ok( !res
|| (res
== ERROR_FILE_NOT_FOUND
),
1044 "returned %d with %u (expected ERROR_SUCCESS or ERROR_FILE_NOT_FOUND)\n",
1045 res
, GetLastError());
1048 /* ToDo: cmd_AddPortW for tempfileW, then cmd_DeletePortW for the existing Port */
1051 /* try to delete a nonexistent Port */
1052 needed
= (DWORD
) 0xdeadbeef;
1053 SetLastError(0xdeadbeef);
1054 res
= pXcvDataPort(hXcv
, cmd_DeletePortW
, (PBYTE
) tempfileW
, (lstrlenW(tempfileW
) + 1) * sizeof(WCHAR
), NULL
, 0, &needed
);
1055 ok( res
== ERROR_FILE_NOT_FOUND
,
1056 "returned %d with %u (expected ERROR_FILE_NOT_FOUND)\n", res
, GetLastError());
1058 /* emptyW as Portname: ERROR_FILE_NOT_FOUND is returned */
1059 /* NULL as Portname: Native localspl.dll crashed */
1063 /* ########################### */
1065 static void test_XcvDataPort_GetTransmissionRetryTimeout(void)
1075 /* ask for needed size */
1076 needed
= (DWORD
) 0xdeadbeef;
1077 SetLastError(0xdeadbeef);
1078 res
= pXcvDataPort(hXcv
, cmd_GetTransmissionRetryTimeoutW
, NULL
, 0, NULL
, 0, &needed
);
1079 if (res
== ERROR_INVALID_PARAMETER
) {
1080 skip("'GetTransmissionRetryTimeout' not supported\n");
1083 len
= sizeof(DWORD
);
1084 ok( (res
== ERROR_INSUFFICIENT_BUFFER
) && (needed
== len
),
1085 "returned %d with %u and %u (expected ERROR_INSUFFICIENT_BUFFER "
1086 "and '%u')\n", res
, GetLastError(), needed
, len
);
1089 /* Read the original value from the registry */
1090 res
= RegOpenKeyExA(HKEY_LOCAL_MACHINE
, WinNT_CV_WindowsA
, 0, KEY_ALL_ACCESS
, &hroot
);
1091 if (res
== ERROR_ACCESS_DENIED
) {
1092 skip("ACCESS_DENIED\n");
1096 if (res
!= ERROR_SUCCESS
) {
1097 /* unable to open the registry: skip the test */
1098 skip("got %d\n", res
);
1102 org_value
[0] = '\0';
1103 needed
= sizeof(org_value
)-1 ;
1104 res
= RegQueryValueExA(hroot
, TransmissionRetryTimeoutA
, NULL
, NULL
, (PBYTE
) org_value
, &needed
);
1105 ok( (res
== ERROR_SUCCESS
) || (res
== ERROR_FILE_NOT_FOUND
),
1106 "returned %u and %u for \"%s\" (expected ERROR_SUCCESS or "
1107 "ERROR_FILE_NOT_FOUND)\n", res
, needed
, org_value
);
1109 /* Get default value (documented as 90 in the w2k reskit, but that is wrong) */
1110 RegDeleteValueA(hroot
, TransmissionRetryTimeoutA
);
1111 needed
= (DWORD
) 0xdeadbeef;
1112 buffer
[0] = 0xdeadbeef;
1113 SetLastError(0xdeadbeef);
1114 res
= pXcvDataPort(hXcv
, cmd_GetTransmissionRetryTimeoutW
, NULL
, 0, (PBYTE
) buffer
, len
, &needed
);
1115 ok( (res
== ERROR_SUCCESS
) && (buffer
[0] == 45),
1116 "returned %d with %u and %u for %d\n (expected ERROR_SUCCESS "
1117 "for '45')\n", res
, GetLastError(), needed
, buffer
[0]);
1119 /* the default timeout is returned, when the value is empty */
1120 res
= RegSetValueExA(hroot
, TransmissionRetryTimeoutA
, 0, REG_SZ
, (PBYTE
)emptyA
, 1);
1121 ok(res
== ERROR_SUCCESS
, "expected ERROR_SUCCESS, got %u\n", GetLastError());
1122 needed
= (DWORD
) 0xdeadbeef;
1123 buffer
[0] = 0xdeadbeef;
1124 SetLastError(0xdeadbeef);
1125 res
= pXcvDataPort(hXcv
, cmd_GetTransmissionRetryTimeoutW
, NULL
, 0, (PBYTE
) buffer
, len
, &needed
);
1126 ok( (res
== ERROR_SUCCESS
) && (buffer
[0] == 45),
1127 "returned %d with %u and %u for %d\n (expected ERROR_SUCCESS "
1128 "for '45')\n", res
, GetLastError(), needed
, buffer
[0]);
1130 /* the dialog is limited (1 - 999999), but that is done somewhere else */
1131 res
= RegSetValueExA(hroot
, TransmissionRetryTimeoutA
, 0, REG_SZ
, (PBYTE
)num_0A
, lstrlenA(num_0A
)+1);
1132 ok(res
== ERROR_SUCCESS
, "expected ERROR_SUCCESS, got %u\n", GetLastError());
1133 needed
= (DWORD
) 0xdeadbeef;
1134 buffer
[0] = 0xdeadbeef;
1135 SetLastError(0xdeadbeef);
1136 res
= pXcvDataPort(hXcv
, cmd_GetTransmissionRetryTimeoutW
, NULL
, 0, (PBYTE
) buffer
, len
, &needed
);
1137 ok( (res
== ERROR_SUCCESS
) && (buffer
[0] == 0),
1138 "returned %d with %u and %u for %d\n (expected ERROR_SUCCESS "
1139 "for '0')\n", res
, GetLastError(), needed
, buffer
[0]);
1142 res
= RegSetValueExA(hroot
, TransmissionRetryTimeoutA
, 0, REG_SZ
, (PBYTE
)num_1A
, lstrlenA(num_1A
)+1);
1143 ok(res
== ERROR_SUCCESS
, "expected ERROR_SUCCESS, got %u\n", GetLastError());
1144 needed
= (DWORD
) 0xdeadbeef;
1145 buffer
[0] = 0xdeadbeef;
1146 SetLastError(0xdeadbeef);
1147 res
= pXcvDataPort(hXcv
, cmd_GetTransmissionRetryTimeoutW
, NULL
, 0, (PBYTE
) buffer
, len
, &needed
);
1148 ok( (res
== ERROR_SUCCESS
) && (buffer
[0] == 1),
1149 "returned %d with %u and %u for %d\n (expected 'ERROR_SUCCESS' "
1150 "for '1')\n", res
, GetLastError(), needed
, buffer
[0]);
1152 res
= RegSetValueExA(hroot
, TransmissionRetryTimeoutA
, 0, REG_SZ
, (PBYTE
)num_999999A
, lstrlenA(num_999999A
)+1);
1153 ok(res
== ERROR_SUCCESS
, "expected ERROR_SUCCESS, got %u\n", GetLastError());
1154 needed
= (DWORD
) 0xdeadbeef;
1155 buffer
[0] = 0xdeadbeef;
1156 SetLastError(0xdeadbeef);
1157 res
= pXcvDataPort(hXcv
, cmd_GetTransmissionRetryTimeoutW
, NULL
, 0, (PBYTE
) buffer
, len
, &needed
);
1158 ok( (res
== ERROR_SUCCESS
) && (buffer
[0] == 999999),
1159 "returned %d with %u and %u for %d\n (expected ERROR_SUCCESS "
1160 "for '999999')\n", res
, GetLastError(), needed
, buffer
[0]);
1163 res
= RegSetValueExA(hroot
, TransmissionRetryTimeoutA
, 0, REG_SZ
, (PBYTE
)num_1000000A
, lstrlenA(num_1000000A
)+1);
1164 ok(res
== ERROR_SUCCESS
, "expected ERROR_SUCCESS, got %u\n", GetLastError());
1165 needed
= (DWORD
) 0xdeadbeef;
1166 buffer
[0] = 0xdeadbeef;
1167 SetLastError(0xdeadbeef);
1168 res
= pXcvDataPort(hXcv
, cmd_GetTransmissionRetryTimeoutW
, NULL
, 0, (PBYTE
) buffer
, len
, &needed
);
1169 ok( (res
== ERROR_SUCCESS
) && (buffer
[0] == 1000000),
1170 "returned %d with %u and %u for %d\n (expected ERROR_SUCCESS "
1171 "for '1000000')\n", res
, GetLastError(), needed
, buffer
[0]);
1173 /* restore the original value */
1174 RegDeleteValueA(hroot
, TransmissionRetryTimeoutA
);
1176 res
= RegSetValueExA(hroot
, TransmissionRetryTimeoutA
, 0, REG_SZ
, (PBYTE
)org_value
, lstrlenA(org_value
)+1);
1177 ok(res
== ERROR_SUCCESS
, "unable to restore original value (got %u): %s\n", res
, org_value
);
1183 /* ########################### */
1185 static void test_XcvDataPort_MonitorUI(void)
1188 BYTE buffer
[MAX_PATH
+ 2];
1193 /* ask for needed size */
1194 needed
= (DWORD
) 0xdeadbeef;
1195 SetLastError(0xdeadbeef);
1196 res
= pXcvDataPort(hXcv
, cmd_MonitorUIW
, NULL
, 0, NULL
, 0, &needed
);
1197 if (res
== ERROR_INVALID_PARAMETER
) {
1198 skip("'MonitorUI' nor supported\n");
1201 ok( (res
== ERROR_INSUFFICIENT_BUFFER
) && (needed
<= MAX_PATH
),
1202 "returned %d with %u and 0x%x (expected 'ERROR_INSUFFICIENT_BUFFER' "
1203 " and '<= MAX_PATH')\n", res
, GetLastError(), needed
);
1205 if (needed
> MAX_PATH
) {
1206 skip("buffer overflow (%u)\n", needed
);
1211 /* the command is required */
1212 needed
= (DWORD
) 0xdeadbeef;
1213 SetLastError(0xdeadbeef);
1214 res
= pXcvDataPort(hXcv
, emptyW
, NULL
, 0, NULL
, 0, &needed
);
1215 ok( res
== ERROR_INVALID_PARAMETER
, "returned %d with %u and 0x%x "
1216 "(expected 'ERROR_INVALID_PARAMETER')\n", res
, GetLastError(), needed
);
1219 /* crash with native localspl.dll (w2k+xp) */
1220 pXcvDataPort(hXcv
, NULL
, NULL
, 0, buffer
, MAX_PATH
, &needed
);
1221 pXcvDataPort(hXcv
, cmd_MonitorUIW
, NULL
, 0, NULL
, len
, &needed
);
1222 pXcvDataPort(hXcv
, cmd_MonitorUIW
, NULL
, 0, buffer
, len
, NULL
);
1226 /* hXcv is ignored for the command "MonitorUI" */
1227 needed
= (DWORD
) 0xdeadbeef;
1228 SetLastError(0xdeadbeef);
1229 res
= pXcvDataPort(NULL
, cmd_MonitorUIW
, NULL
, 0, buffer
, len
, &needed
);
1230 ok( res
== ERROR_SUCCESS
, "returned %d with %u and 0x%x "
1231 "(expected 'ERROR_SUCCESS')\n", res
, GetLastError(), needed
);
1234 /* pszDataName is case-sensitive */
1235 memset(buffer
, 0, len
);
1236 needed
= (DWORD
) 0xdeadbeef;
1237 SetLastError(0xdeadbeef);
1238 res
= pXcvDataPort(hXcv
, cmd_MonitorUI_lcaseW
, NULL
, 0, buffer
, len
, &needed
);
1239 ok( res
== ERROR_INVALID_PARAMETER
, "returned %d with %u and 0x%x "
1240 "(expected 'ERROR_INVALID_PARAMETER')\n", res
, GetLastError(), needed
);
1242 /* off by one: larger */
1243 needed
= (DWORD
) 0xdeadbeef;
1244 SetLastError(0xdeadbeef);
1245 res
= pXcvDataPort(hXcv
, cmd_MonitorUIW
, NULL
, 0, buffer
, len
+1, &needed
);
1246 ok( res
== ERROR_SUCCESS
, "returned %d with %u and 0x%x "
1247 "(expected 'ERROR_SUCCESS')\n", res
, GetLastError(), needed
);
1250 /* off by one: smaller */
1251 /* the buffer is not modified for NT4, w2k, XP */
1252 needed
= (DWORD
) 0xdeadbeef;
1253 SetLastError(0xdeadbeef);
1254 res
= pXcvDataPort(hXcv
, cmd_MonitorUIW
, NULL
, 0, buffer
, len
-1, &needed
);
1255 ok( res
== ERROR_INSUFFICIENT_BUFFER
, "returned %d with %u and 0x%x "
1256 "(expected 'ERROR_INSUFFICIENT_BUFFER')\n", res
, GetLastError(), needed
);
1258 /* Normal use. The DLL-Name without a Path is returned */
1259 memset(buffer
, 0, len
);
1260 needed
= (DWORD
) 0xdeadbeef;
1261 SetLastError(0xdeadbeef);
1262 res
= pXcvDataPort(hXcv
, cmd_MonitorUIW
, NULL
, 0, buffer
, len
, &needed
);
1263 ok( res
== ERROR_SUCCESS
, "returned %d with %u and 0x%x "
1264 "(expected 'ERROR_SUCCESS')\n", res
, GetLastError(), needed
);
1267 /* small check without access-rights: */
1268 if (!hXcv_noaccess
) return;
1270 /* The ACCESS_MASK is ignored for "MonitorUI" */
1271 memset(buffer
, 0, len
);
1272 needed
= (DWORD
) 0xdeadbeef;
1273 SetLastError(0xdeadbeef);
1274 res
= pXcvDataPort(hXcv_noaccess
, cmd_MonitorUIW
, NULL
, 0, buffer
, sizeof(buffer
), &needed
);
1275 ok( res
== ERROR_SUCCESS
, "returned %d with %u and 0x%x "
1276 "(expected 'ERROR_SUCCESS')\n", res
, GetLastError(), needed
);
1279 /* ########################### */
1281 static void test_XcvDataPort_PortIsValid(void)
1286 /* normal use: "LPT1:" */
1287 needed
= (DWORD
) 0xdeadbeef;
1288 SetLastError(0xdeadbeef);
1289 res
= pXcvDataPort(hXcv
, cmd_PortIsValidW
, (PBYTE
) portname_lpt1W
, sizeof(portname_lpt1W
), NULL
, 0, &needed
);
1290 if (res
== ERROR_INVALID_PARAMETER
) {
1291 skip("'PostIsValid' not supported\n");
1294 ok( res
== ERROR_SUCCESS
, "returned %d with %u (expected ERROR_SUCCESS)\n", res
, GetLastError());
1298 /* crash with native localspl.dll (w2k+xp) */
1299 pXcvDataPort(hXcv
, cmd_PortIsValidW
, NULL
, 0, NULL
, 0, &needed
);
1303 /* hXcv is ignored for the command "PortIsValid" */
1304 needed
= (DWORD
) 0xdeadbeef;
1305 SetLastError(0xdeadbeef);
1306 res
= pXcvDataPort(NULL
, cmd_PortIsValidW
, (PBYTE
) portname_lpt1W
, sizeof(portname_lpt1W
), NULL
, 0, NULL
);
1307 ok( res
== ERROR_SUCCESS
, "returned %d with %u (expected ERROR_SUCCESS)\n", res
, GetLastError());
1309 /* needed is ignored */
1310 needed
= (DWORD
) 0xdeadbeef;
1311 SetLastError(0xdeadbeef);
1312 res
= pXcvDataPort(hXcv
, cmd_PortIsValidW
, (PBYTE
) portname_lpt1W
, sizeof(portname_lpt1W
), NULL
, 0, NULL
);
1313 ok( res
== ERROR_SUCCESS
, "returned %d with %u (expected ERROR_SUCCESS)\n", res
, GetLastError());
1316 /* cbInputData is ignored */
1317 needed
= (DWORD
) 0xdeadbeef;
1318 SetLastError(0xdeadbeef);
1319 res
= pXcvDataPort(hXcv
, cmd_PortIsValidW
, (PBYTE
) portname_lpt1W
, 0, NULL
, 0, &needed
);
1320 ok( res
== ERROR_SUCCESS
,
1321 "returned %d with %u and 0x%x (expected ERROR_SUCCESS)\n",
1322 res
, GetLastError(), needed
);
1324 needed
= (DWORD
) 0xdeadbeef;
1325 SetLastError(0xdeadbeef);
1326 res
= pXcvDataPort(hXcv
, cmd_PortIsValidW
, (PBYTE
) portname_lpt1W
, 1, NULL
, 0, &needed
);
1327 ok( res
== ERROR_SUCCESS
,
1328 "returned %d with %u and 0x%x (expected ERROR_SUCCESS)\n",
1329 res
, GetLastError(), needed
);
1331 needed
= (DWORD
) 0xdeadbeef;
1332 SetLastError(0xdeadbeef);
1333 res
= pXcvDataPort(hXcv
, cmd_PortIsValidW
, (PBYTE
) portname_lpt1W
, sizeof(portname_lpt1W
) -1, NULL
, 0, &needed
);
1334 ok( res
== ERROR_SUCCESS
,
1335 "returned %d with %u and 0x%x (expected ERROR_SUCCESS)\n",
1336 res
, GetLastError(), needed
);
1338 needed
= (DWORD
) 0xdeadbeef;
1339 SetLastError(0xdeadbeef);
1340 res
= pXcvDataPort(hXcv
, cmd_PortIsValidW
, (PBYTE
) portname_lpt1W
, sizeof(portname_lpt1W
) -2, NULL
, 0, &needed
);
1341 ok( res
== ERROR_SUCCESS
,
1342 "returned %d with %u and 0x%x (expected ERROR_SUCCESS)\n",
1343 res
, GetLastError(), needed
);
1346 /* an empty name is not allowed */
1347 needed
= (DWORD
) 0xdeadbeef;
1348 SetLastError(0xdeadbeef);
1349 res
= pXcvDataPort(hXcv
, cmd_PortIsValidW
, (PBYTE
) emptyW
, sizeof(emptyW
), NULL
, 0, &needed
);
1350 ok( res
== ERROR_PATH_NOT_FOUND
,
1351 "returned %d with %u and 0x%x (expected ERROR_PATH_NOT_FOUND)\n",
1352 res
, GetLastError(), needed
);
1355 /* a directory is not allowed */
1356 needed
= (DWORD
) 0xdeadbeef;
1357 SetLastError(0xdeadbeef);
1358 res
= pXcvDataPort(hXcv
, cmd_PortIsValidW
, (PBYTE
) tempdirW
, (lstrlenW(tempdirW
) + 1) * sizeof(WCHAR
), NULL
, 0, &needed
);
1359 /* XP(admin): ERROR_INVALID_NAME, XP(user): ERROR_PATH_NOT_FOUND, w2k ERROR_ACCESS_DENIED */
1360 ok( (res
== ERROR_INVALID_NAME
) || (res
== ERROR_PATH_NOT_FOUND
) ||
1361 (res
== ERROR_ACCESS_DENIED
), "returned %d with %u and 0x%x "
1362 "(expected ERROR_INVALID_NAME, ERROR_PATH_NOT_FOUND or ERROR_ACCESS_DENIED)\n",
1363 res
, GetLastError(), needed
);
1366 /* test more valid well known Ports: */
1367 needed
= (DWORD
) 0xdeadbeef;
1368 SetLastError(0xdeadbeef);
1369 res
= pXcvDataPort(hXcv
, cmd_PortIsValidW
, (PBYTE
) portname_lpt2W
, sizeof(portname_lpt2W
), NULL
, 0, &needed
);
1370 ok( res
== ERROR_SUCCESS
,
1371 "returned %d with %u and 0x%x (expected ERROR_SUCCESS)\n",
1372 res
, GetLastError(), needed
);
1375 needed
= (DWORD
) 0xdeadbeef;
1376 SetLastError(0xdeadbeef);
1377 res
= pXcvDataPort(hXcv
, cmd_PortIsValidW
, (PBYTE
) portname_com1W
, sizeof(portname_com1W
), NULL
, 0, &needed
);
1378 ok( res
== ERROR_SUCCESS
,
1379 "returned %d with %u and 0x%x (expected ERROR_SUCCESS)\n",
1380 res
, GetLastError(), needed
);
1383 needed
= (DWORD
) 0xdeadbeef;
1384 SetLastError(0xdeadbeef);
1385 res
= pXcvDataPort(hXcv
, cmd_PortIsValidW
, (PBYTE
) portname_com2W
, sizeof(portname_com2W
), NULL
, 0, &needed
);
1386 ok( res
== ERROR_SUCCESS
,
1387 "returned %d with %u and 0x%x (expected ERROR_SUCCESS)\n",
1388 res
, GetLastError(), needed
);
1391 needed
= (DWORD
) 0xdeadbeef;
1392 SetLastError(0xdeadbeef);
1393 res
= pXcvDataPort(hXcv
, cmd_PortIsValidW
, (PBYTE
) portname_fileW
, sizeof(portname_fileW
), NULL
, 0, &needed
);
1394 ok( res
== ERROR_SUCCESS
,
1395 "returned %d with %u and 0x%x (expected ERROR_SUCCESS)\n",
1396 res
, GetLastError(), needed
);
1399 /* a normal, writable file is allowed */
1400 needed
= (DWORD
) 0xdeadbeef;
1401 SetLastError(0xdeadbeef);
1402 res
= pXcvDataPort(hXcv
, cmd_PortIsValidW
, (PBYTE
) tempfileW
, (lstrlenW(tempfileW
) + 1) * sizeof(WCHAR
), NULL
, 0, &needed
);
1403 ok( res
== ERROR_SUCCESS
,
1404 "returned %d with %u and 0x%x (expected ERROR_SUCCESS)\n",
1405 res
, GetLastError(), needed
);
1408 /* small check without access-rights: */
1409 if (!hXcv_noaccess
) return;
1411 /* The ACCESS_MASK from XcvOpenPort is ignored in "PortIsValid" */
1412 needed
= (DWORD
) 0xdeadbeef;
1413 SetLastError(0xdeadbeef);
1414 res
= pXcvDataPort(hXcv_noaccess
, cmd_PortIsValidW
, (PBYTE
) portname_lpt1W
, sizeof(portname_lpt1W
), NULL
, 0, &needed
);
1415 ok( res
== ERROR_SUCCESS
, "returned %d with %u (expected ERROR_SUCCESS)\n", res
, GetLastError());
1419 /* ########################### */
1421 static void test_XcvOpenPort(void)
1429 /* crash with native localspl.dll (w2k+xp) */
1430 pXcvOpenPort(NULL
, SERVER_ACCESS_ADMINISTER
, &hXcv2
);
1431 pXcvOpenPort(emptyW
, SERVER_ACCESS_ADMINISTER
, NULL
);
1435 /* The returned handle is the result from a previous "spoolss.dll,DllAllocSplMem" */
1436 SetLastError(0xdeadbeef);
1437 hXcv2
= (HANDLE
) 0xdeadbeef;
1438 res
= pXcvOpenPort(emptyW
, SERVER_ACCESS_ADMINISTER
, &hXcv2
);
1439 ok(res
, "returned %d with %u and %p (expected '!= 0')\n", res
, GetLastError(), hXcv2
);
1440 if (res
) pXcvClosePort(hXcv2
);
1443 /* The ACCESS_MASK is not checked in XcvOpenPort */
1444 SetLastError(0xdeadbeef);
1445 hXcv2
= (HANDLE
) 0xdeadbeef;
1446 res
= pXcvOpenPort(emptyW
, 0, &hXcv2
);
1447 ok(res
, "returned %d with %u and %p (expected '!= 0')\n", res
, GetLastError(), hXcv2
);
1448 if (res
) pXcvClosePort(hXcv2
);
1451 /* A copy of pszObject is saved in the Memory-Block */
1452 SetLastError(0xdeadbeef);
1453 hXcv2
= (HANDLE
) 0xdeadbeef;
1454 res
= pXcvOpenPort(portname_lpt1W
, SERVER_ALL_ACCESS
, &hXcv2
);
1455 ok(res
, "returned %d with %u and %p (expected '!= 0')\n", res
, GetLastError(), hXcv2
);
1456 if (res
) pXcvClosePort(hXcv2
);
1458 SetLastError(0xdeadbeef);
1459 hXcv2
= (HANDLE
) 0xdeadbeef;
1460 res
= pXcvOpenPort(portname_fileW
, SERVER_ALL_ACCESS
, &hXcv2
);
1461 ok(res
, "returned %d with %u and %p (expected '!= 0')\n", res
, GetLastError(), hXcv2
);
1462 if (res
) pXcvClosePort(hXcv2
);
1466 /* ########################### */
1468 #define GET_MONITOR_FUNC(name) \
1469 if (pm) p##name = pm->Monitor.pfn##name; \
1470 else if (pm2) p##name = pm2->pfn##name;
1472 #define GET_MONITOR_FUNC2(name) \
1473 if (pm) p##name = pm->Monitor.pfn##name; \
1474 else if (pm2) p##name##2 = pm2->pfn##name;
1476 START_TEST(localmon
)
1481 LoadLibraryA("winspool.drv");
1482 /* This DLL does not exist on Win9x */
1483 hdll
= LoadLibraryA("localspl.dll");
1485 skip("localspl.dll cannot be loaded, most likely running on Win9x\n");
1490 tempfileW
[0] = '\0';
1491 res
= GetTempPathW(MAX_PATH
, tempdirW
);
1492 ok(res
!= 0, "with %u\n", GetLastError());
1493 res
= GetTempFileNameW(tempdirW
, wineW
, 0, tempfileW
);
1494 ok(res
!= 0, "with %u\n", GetLastError());
1496 pInitializePrintMonitor
= (void *) GetProcAddress(hdll
, "InitializePrintMonitor");
1497 pInitializePrintMonitor2
= (void *) GetProcAddress(hdll
, "InitializePrintMonitor2");
1499 if (!pInitializePrintMonitor
) {
1500 /* The Monitor for "Local Ports" was in a separate dll before w2k */
1501 hlocalmon
= LoadLibraryA("localmon.dll");
1503 pInitializePrintMonitor
= (void *) GetProcAddress(hlocalmon
, "InitializePrintMonitor");
1506 if (!pInitializePrintMonitor
&& !pInitializePrintMonitor2
) {
1507 skip("InitializePrintMonitor or InitializePrintMonitor2 not found\n");
1511 /* Native localmon.dll / localspl.dll need a valid Port-Entry in:
1512 a) since xp: HKLM\Software\Microsoft\Windows NT\CurrentVersion\Ports
1513 b) up to w2k: Section "Ports" in win.ini
1514 or InitializePrintMonitor fails. */
1515 if (pInitializePrintMonitor
)
1516 pm
= pInitializePrintMonitor(Monitors_LocalPortW
);
1517 else if (pInitializePrintMonitor2
) {
1520 memset(&init
, 0, sizeof(init
));
1521 init
.cbSize
= sizeof(init
);
1522 init
.hckRegistryRoot
= 0;
1523 init
.pMonitorReg
= &monreg
;
1526 pm2
= pInitializePrintMonitor2(&init
, &hmon
);
1527 ok(pm2
!= NULL
, "InitializePrintMonitor2 error %u\n", GetLastError());
1528 ok(pm2
->cbSize
>= FIELD_OFFSET(MONITOR2
, pfnSendRecvBidiDataFromPort
), "wrong cbSize %u\n", pm2
->cbSize
);
1533 ok(pm
->dwMonitorSize
== sizeof(MONITOR
), "wrong dwMonitorSize %u\n", pm
->dwMonitorSize
);
1534 numentries
= (pm
->dwMonitorSize
) / sizeof(VOID
*);
1535 /* NT4: 14, since w2k: 17 */
1536 ok( numentries
== 14 || numentries
== 17,
1537 "dwMonitorSize (%u) => %u Functions\n", pm
->dwMonitorSize
, numentries
);
1540 numentries
= (pm2
->cbSize
) / sizeof(VOID
*);
1541 ok( numentries
>= 20,
1542 "cbSize (%u) => %u Functions\n", pm2
->cbSize
, numentries
);
1545 GET_MONITOR_FUNC2(EnumPorts
);
1546 GET_MONITOR_FUNC2(OpenPort
);
1547 GET_MONITOR_FUNC2(OpenPortEx
);
1548 GET_MONITOR_FUNC(StartDocPort
);
1549 GET_MONITOR_FUNC(WritePort
);
1550 GET_MONITOR_FUNC(ReadPort
);
1551 GET_MONITOR_FUNC(EndDocPort
);
1552 GET_MONITOR_FUNC(ClosePort
);
1553 GET_MONITOR_FUNC2(AddPort
);
1554 GET_MONITOR_FUNC2(AddPortEx
);
1555 GET_MONITOR_FUNC2(ConfigurePort
);
1556 GET_MONITOR_FUNC2(DeletePort
);
1557 GET_MONITOR_FUNC(GetPrinterDataFromPort
);
1558 GET_MONITOR_FUNC(SetPortTimeOuts
);
1559 GET_MONITOR_FUNC2(XcvOpenPort
);
1560 GET_MONITOR_FUNC(XcvDataPort
);
1561 GET_MONITOR_FUNC(XcvClosePort
);
1563 if ((pXcvOpenPort
) && (pXcvDataPort
) && (pXcvClosePort
)) {
1564 SetLastError(0xdeadbeef);
1565 res
= pXcvOpenPort(emptyW
, SERVER_ACCESS_ADMINISTER
, &hXcv
);
1566 ok(res
, "hXcv: %d with %u and %p (expected '!= 0')\n", res
, GetLastError(), hXcv
);
1568 SetLastError(0xdeadbeef);
1569 res
= pXcvOpenPort(emptyW
, 0, &hXcv_noaccess
);
1570 ok(res
, "hXcv_noaccess: %d with %u and %p (expected '!= 0')\n", res
, GetLastError(), hXcv_noaccess
);
1574 test_InitializePrintMonitor();
1575 test_InitializePrintMonitor2();
1577 find_installed_ports();
1582 test_ConfigurePort();
1588 skip("Xcv not supported\n");
1592 test_XcvClosePort();
1593 test_XcvDataPort_AddPort();
1594 test_XcvDataPort_ConfigureLPTPortCommandOK();
1595 test_XcvDataPort_DeletePort();
1596 test_XcvDataPort_GetTransmissionRetryTimeout();
1597 test_XcvDataPort_MonitorUI();
1598 test_XcvDataPort_PortIsValid();
1601 pXcvClosePort(hXcv
);
1603 if (hXcv_noaccess
) pXcvClosePort(hXcv_noaccess
);
1605 /* Cleanup our temporary file */
1606 DeleteFileW(tempfileW
);