1 /* 2 * Copyright (C) 2003, 2004 Stefan Leichter 3 * Copyright (C) 2005, 2006 Detlef Riekenberg 4 * Copyright (C) 2006 Dmitry Timoshkov 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include <stdarg.h> 22 #include <assert.h> 23 24 #define NONAMELESSSTRUCT 25 #define NONAMELESSUNION 26 27 #include "windef.h" 28 #include "winbase.h" 29 #include "winerror.h" 30 #include "wingdi.h" 31 #include "winnls.h" 32 #include "winuser.h" 33 #include "winreg.h" 34 #include "winspool.h" 35 #include "commdlg.h" 36 #include "wine/test.h" 37 38 #define MAGIC_DEAD 0xdeadbeef 39 #define DEFAULT_PRINTER_SIZE 1000 40 41 static CHAR defaultspooldirectory[] = "DefaultSpoolDirectory"; 42 static CHAR does_not_exist_dll[]= "does_not_exist.dll"; 43 static CHAR does_not_exist[] = "does_not_exist"; 44 static CHAR empty[] = ""; 45 static CHAR env_x64[] = "Windows x64"; 46 static CHAR env_x86[] = "Windows NT x86"; 47 static CHAR env_win9x_case[] = "windowS 4.0"; 48 static CHAR illegal_name[] = "illegal,name"; 49 static CHAR invalid_env[] = "invalid_env"; 50 static CHAR LocalPortA[] = "Local Port"; 51 static CHAR portname_com1[] = "COM1:"; 52 static CHAR portname_file[] = "FILE:"; 53 static CHAR portname_lpt1[] = "LPT1:"; 54 static CHAR server_does_not_exist[] = "\\\\does_not_exist"; 55 static CHAR version_dll[] = "version.dll"; 56 static CHAR winetest[] = "winetest"; 57 static CHAR xcv_localport[] = ",XcvMonitor Local Port"; 58 59 static const WCHAR cmd_MonitorUIW[] = {'M','o','n','i','t','o','r','U','I',0}; 60 static const WCHAR cmd_PortIsValidW[] = {'P','o','r','t','I','s','V','a','l','i','d',0}; 61 static WCHAR emptyW[] = {0}; 62 63 static WCHAR portname_com1W[] = {'C','O','M','1',':',0}; 64 static WCHAR portname_com2W[] = {'C','O','M','2',':',0}; 65 static WCHAR portname_fileW[] = {'F','I','L','E',':',0}; 66 static WCHAR portname_lpt1W[] = {'L','P','T','1',':',0}; 67 static WCHAR portname_lpt2W[] = {'L','P','T','2',':',0}; 68 69 static HANDLE hwinspool; 70 static BOOL (WINAPI * pAddPortExA)(LPSTR, DWORD, LPBYTE, LPSTR); 71 static BOOL (WINAPI * pEnumPrinterDriversW)(LPWSTR, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD); 72 static BOOL (WINAPI * pGetDefaultPrinterA)(LPSTR, LPDWORD); 73 static DWORD (WINAPI * pGetPrinterDataExA)(HANDLE, LPCSTR, LPCSTR, LPDWORD, LPBYTE, DWORD, LPDWORD); 74 static BOOL (WINAPI * pGetPrinterDriverW)(HANDLE, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD); 75 static BOOL (WINAPI * pGetPrinterW)(HANDLE, DWORD, LPBYTE, DWORD, LPDWORD); 76 static BOOL (WINAPI * pSetDefaultPrinterA)(LPCSTR); 77 static DWORD (WINAPI * pXcvDataW)(HANDLE, LPCWSTR, PBYTE, DWORD, PBYTE, DWORD, PDWORD, PDWORD); 78 79 /* ################################ */ 80 81 struct monitor_entry { 82 LPSTR env; 83 CHAR dllname[32]; 84 }; 85 86 static LPSTR default_printer = NULL; 87 static LPSTR local_server = NULL; 88 static LPSTR tempdirA = NULL; 89 static LPSTR tempfileA = NULL; 90 static LPWSTR tempdirW = NULL; 91 static LPWSTR tempfileW = NULL; 92 93 static BOOL is_spooler_deactivated(DWORD res, DWORD lasterror) 94 { 95 if (!res && lasterror == RPC_S_SERVER_UNAVAILABLE) 96 { 97 static int deactivated_spooler_reported = 0; 98 if (!deactivated_spooler_reported) 99 { 100 deactivated_spooler_reported = 1; 101 skip("The service 'Spooler' is required for many tests\n"); 102 } 103 return TRUE; 104 } 105 return FALSE; 106 } 107 108 static BOOL is_access_denied(DWORD res, DWORD lasterror) 109 { 110 if (!res && lasterror == ERROR_ACCESS_DENIED) 111 { 112 static int access_denied_reported = 0; 113 if (!access_denied_reported) 114 { 115 access_denied_reported = 1; 116 skip("More access rights are required for many tests\n"); 117 } 118 return TRUE; 119 } 120 return FALSE; 121 } 122 123 static BOOL on_win9x = FALSE; 124 125 static BOOL check_win9x(void) 126 { 127 if (pGetPrinterW) 128 { 129 SetLastError(0xdeadbeef); 130 pGetPrinterW(NULL, 0, NULL, 0, NULL); 131 return (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED); 132 } 133 else 134 { 135 return TRUE; 136 } 137 } 138 139 static void find_default_printer(VOID) 140 { 141 static char buffer[DEFAULT_PRINTER_SIZE]; 142 DWORD needed; 143 DWORD res; 144 LPSTR ptr; 145 146 if ((default_printer == NULL) && (pGetDefaultPrinterA)) 147 { 148 /* w2k and above */ 149 needed = sizeof(buffer); 150 res = pGetDefaultPrinterA(buffer, &needed); 151 if(res) default_printer = buffer; 152 trace("default_printer: '%s'\n", default_printer ? default_printer : "(null)"); 153 } 154 if (default_printer == NULL) 155 { 156 HKEY hwindows; 157 DWORD type; 158 /* NT 3.x and above */ 159 if (RegOpenKeyExA(HKEY_CURRENT_USER, 160 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows", 161 0, KEY_QUERY_VALUE, &hwindows) == NO_ERROR) { 162 163 needed = sizeof(buffer); 164 if (RegQueryValueExA(hwindows, "device", NULL, &type, (LPBYTE)buffer, &needed) == NO_ERROR) { 165 ptr = strchr(buffer, ','); 166 if (ptr) { 167 ptr[0] = '\0'; 168 default_printer = buffer; 169 } 170 } 171 RegCloseKey(hwindows); 172 } 173 trace("default_printer: '%s'\n", default_printer ? default_printer : "(null)"); 174 } 175 if (default_printer == NULL) 176 { 177 /* win9x */ 178 needed = sizeof(buffer); 179 res = GetProfileStringA("windows", "device", "*", buffer, needed); 180 if(res) { 181 ptr = strchr(buffer, ','); 182 if (ptr) { 183 ptr[0] = '\0'; 184 default_printer = buffer; 185 } 186 } 187 trace("default_printer: '%s'\n", default_printer ? default_printer : "(null)"); 188 } 189 } 190 191 192 static struct monitor_entry * find_installed_monitor(void) 193 { 194 MONITOR_INFO_2A mi2a; 195 static struct monitor_entry * entry = NULL; 196 DWORD num_tests; 197 DWORD i = 0; 198 199 static struct monitor_entry monitor_table[] = { 200 {env_win9x_case, "localspl.dll"}, 201 {env_x86, "localspl.dll"}, 202 {env_x64, "localspl.dll"}, 203 {env_win9x_case, "localmon.dll"}, 204 {env_x86, "localmon.dll"}, 205 {env_win9x_case, "tcpmon.dll"}, 206 {env_x86, "tcpmon.dll"}, 207 {env_win9x_case, "usbmon.dll"}, 208 {env_x86, "usbmon.dll"}, 209 {env_win9x_case, "mspp32.dll"}, 210 {env_x86, "win32spl.dll"}, 211 {env_x86, "redmonnt.dll"}, 212 {env_x86, "redmon35.dll"}, 213 {env_win9x_case, "redmon95.dll"}, 214 {env_x86, "pdfcmnnt.dll"}, 215 {env_win9x_case, "pdfcmn95.dll"}, 216 }; 217 218 if (entry) return entry; 219 220 num_tests = ARRAY_SIZE(monitor_table); 221 222 /* cleanup */ 223 DeleteMonitorA(NULL, env_x64, winetest); 224 DeleteMonitorA(NULL, env_x86, winetest); 225 DeleteMonitorA(NULL, env_win9x_case, winetest); 226 227 /* find a usable monitor from the table */ 228 mi2a.pName = winetest; 229 while ((entry == NULL) && (i < num_tests)) { 230 entry = &monitor_table[i]; 231 i++; 232 mi2a.pEnvironment = entry->env; 233 mi2a.pDLLName = entry->dllname; 234 235 if (AddMonitorA(NULL, 2, (LPBYTE) &mi2a)) { 236 /* we got one */ 237 trace("using '%s', '%s'\n", entry->env, entry->dllname); 238 DeleteMonitorA(NULL, entry->env, winetest); 239 } 240 else 241 { 242 entry = NULL; 243 } 244 } 245 return entry; 246 } 247 248 249 /* ########################### */ 250 251 static void find_local_server(VOID) 252 { 253 static char buffer[MAX_PATH]; 254 DWORD res; 255 DWORD size; 256 257 size = sizeof(buffer) - 3 ; 258 buffer[0] = '\\'; 259 buffer[1] = '\\'; 260 buffer[2] = '\0'; 261 262 SetLastError(0xdeadbeef); 263 res = GetComputerNameA(&buffer[2], &size); 264 trace("returned %d with %d and %d: '%s'\n", res, GetLastError(), size, buffer); 265 266 ok( res != 0, "returned %d with %d and %d: '%s' (expected '!= 0')\n", 267 res, GetLastError(), size, buffer); 268 269 if (res) local_server = buffer; 270 } 271 272 /* ########################### */ 273 274 static void find_tempfile(VOID) 275 { 276 static CHAR buffer_dirA[MAX_PATH]; 277 static CHAR buffer_fileA[MAX_PATH]; 278 static WCHAR buffer_dirW[MAX_PATH]; 279 static WCHAR buffer_fileW[MAX_PATH]; 280 DWORD res; 281 int resint; 282 283 memset(buffer_dirA, 0, MAX_PATH - 1); 284 buffer_dirA[MAX_PATH - 1] = '\0'; 285 SetLastError(0xdeadbeef); 286 res = GetTempPathA(MAX_PATH, buffer_dirA); 287 ok(res, "returned %u with %u and '%s' (expected '!= 0')\n", res, GetLastError(), buffer_dirA); 288 if (res == 0) return; 289 290 memset(buffer_fileA, 0, MAX_PATH - 1); 291 buffer_fileA[MAX_PATH - 1] = '\0'; 292 SetLastError(0xdeadbeef); 293 res = GetTempFileNameA(buffer_dirA, winetest, 0, buffer_fileA); 294 ok(res, "returned %u with %u and '%s' (expected '!= 0')\n", res, GetLastError(), buffer_fileA); 295 if (res == 0) return; 296 297 SetLastError(0xdeadbeef); 298 resint = MultiByteToWideChar(CP_ACP, 0, buffer_dirA, -1, buffer_dirW, MAX_PATH); 299 ok(res, "returned %u with %u (expected '!= 0')\n", resint, GetLastError()); 300 if (resint == 0) return; 301 302 SetLastError(0xdeadbeef); 303 resint = MultiByteToWideChar(CP_ACP, 0, buffer_fileA, -1, buffer_fileW, MAX_PATH); 304 ok(res, "returned %u with %u (expected '!= 0')\n", resint, GetLastError()); 305 if (resint == 0) return; 306 307 tempdirA = buffer_dirA; 308 tempfileA = buffer_fileA; 309 tempdirW = buffer_dirW; 310 tempfileW = buffer_fileW; 311 trace("tempfile: '%s'\n", tempfileA); 312 } 313 314 /* ########################### */ 315 316 static void test_AddMonitor(void) 317 { 318 MONITOR_INFO_2A mi2a; 319 struct monitor_entry * entry = NULL; 320 DWORD res; 321 322 entry = find_installed_monitor(); 323 324 SetLastError(MAGIC_DEAD); 325 res = AddMonitorA(NULL, 1, NULL); 326 ok(!res && (GetLastError() == ERROR_INVALID_LEVEL), 327 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n", 328 res, GetLastError()); 329 330 SetLastError(MAGIC_DEAD); 331 res = AddMonitorA(NULL, 3, NULL); 332 ok(!res && (GetLastError() == ERROR_INVALID_LEVEL), 333 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n", 334 res, GetLastError()); 335 336 if (0) 337 { 338 /* This test crashes win9x on vmware (works with win9x on qemu 0.8.1) */ 339 SetLastError(MAGIC_DEAD); 340 res = AddMonitorA(NULL, 2, NULL); 341 /* NT: unchanged, 9x: ERROR_PRIVILEGE_NOT_HELD */ 342 ok(!res && 343 ((GetLastError() == MAGIC_DEAD) || 344 (GetLastError() == ERROR_PRIVILEGE_NOT_HELD)), 345 "returned %d with %d (expected '0' with: MAGIC_DEAD or " 346 "ERROR_PRIVILEGE_NOT_HELD)\n", res, GetLastError()); 347 } 348 349 ZeroMemory(&mi2a, sizeof(MONITOR_INFO_2A)); 350 SetLastError(MAGIC_DEAD); 351 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a); 352 if (is_spooler_deactivated(res, GetLastError())) return; 353 if (is_access_denied(res, GetLastError())) return; 354 355 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_INVALID_ENVIRONMENT */ 356 ok(!res && ((GetLastError() == ERROR_INVALID_PARAMETER) || 357 (GetLastError() == ERROR_INVALID_ENVIRONMENT)), 358 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or " 359 "ERROR_INVALID_ENVIRONMENT)\n", res, GetLastError()); 360 361 if (!entry) { 362 skip("No usable Monitor found\n"); 363 return; 364 } 365 366 if (0) 367 { 368 /* The test is deactivated, because when mi2a.pName is NULL, the subkey 369 HKLM\System\CurrentControlSet\Control\Print\Monitors\C:\WINDOWS\SYSTEM 370 or HKLM\System\CurrentControlSet\Control\Print\Monitors\ì 371 is created on win9x and we do not want to hit this bug here. */ 372 373 mi2a.pEnvironment = entry->env; 374 SetLastError(MAGIC_DEAD); 375 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a); 376 ok(res, "AddMonitor error %d\n", GetLastError()); 377 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_PRIVILEGE_NOT_HELD */ 378 } 379 380 mi2a.pEnvironment = entry->env; 381 mi2a.pName = empty; 382 SetLastError(MAGIC_DEAD); 383 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a); 384 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_PRIVILEGE_NOT_HELD */ 385 ok( !res && 386 ((GetLastError() == ERROR_INVALID_PARAMETER) || 387 (GetLastError() == ERROR_PRIVILEGE_NOT_HELD)), 388 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or " 389 "ERROR_PRIVILEGE_NOT_HELD)\n", 390 res, GetLastError()); 391 392 mi2a.pName = winetest; 393 SetLastError(MAGIC_DEAD); 394 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a); 395 /* NT: ERROR_INVALID_PARAMETER, 9x: ERROR_PRIVILEGE_NOT_HELD */ 396 ok( !res && 397 ((GetLastError() == ERROR_INVALID_PARAMETER) || 398 (GetLastError() == ERROR_PRIVILEGE_NOT_HELD)), 399 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or " 400 "ERROR_PRIVILEGE_NOT_HELD)\n", 401 res, GetLastError()); 402 403 mi2a.pDLLName = empty; 404 SetLastError(MAGIC_DEAD); 405 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a); 406 ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER), 407 "returned %d with %d (expected '0' with ERROR_INVALID_PARAMETER)\n", 408 res, GetLastError()); 409 410 mi2a.pDLLName = does_not_exist_dll; 411 SetLastError(MAGIC_DEAD); 412 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a); 413 /* NT: ERROR_MOD_NOT_FOUND, 9x: ERROR_INVALID_PARAMETER */ 414 ok( !res && 415 ((GetLastError() == ERROR_MOD_NOT_FOUND) || 416 (GetLastError() == ERROR_INVALID_PARAMETER)), 417 "returned %d with %d (expected '0' with: ERROR_MOD_NOT_FOUND or " 418 "ERROR_INVALID_PARAMETER)\n", res, GetLastError()); 419 420 mi2a.pDLLName = version_dll; 421 SetLastError(MAGIC_DEAD); 422 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a); 423 /* NT: ERROR_PROC_NOT_FOUND, 9x: ERROR_INVALID_PARAMETER */ 424 ok( !res && 425 ((GetLastError() == ERROR_PROC_NOT_FOUND) || 426 (GetLastError() == ERROR_INVALID_PARAMETER)), 427 "returned %d with %d (expected '0' with: ERROR_PROC_NOT_FOUND or " 428 "ERROR_INVALID_PARAMETER)\n", res, GetLastError()); 429 if (res) DeleteMonitorA(NULL, entry->env, winetest); 430 431 /* Test AddMonitor with real options */ 432 mi2a.pDLLName = entry->dllname; 433 SetLastError(MAGIC_DEAD); 434 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a); 435 /* Some apps depend on the result of GetLastError() also on success of AddMonitor */ 436 ok(res && (GetLastError() == ERROR_SUCCESS), 437 "returned %d with %d (expected '!= 0' with ERROR_SUCCESS)\n", res, GetLastError()); 438 439 /* add a monitor twice */ 440 SetLastError(MAGIC_DEAD); 441 res = AddMonitorA(NULL, 2, (LPBYTE) &mi2a); 442 /* NT: ERROR_PRINT_MONITOR_ALREADY_INSTALLED (3006), 9x: ERROR_ALREADY_EXISTS (183) */ 443 ok( !res && 444 ((GetLastError() == ERROR_PRINT_MONITOR_ALREADY_INSTALLED) || 445 (GetLastError() == ERROR_ALREADY_EXISTS)), 446 "returned %d with %d (expected '0' with: " 447 "ERROR_PRINT_MONITOR_ALREADY_INSTALLED or ERROR_ALREADY_EXISTS)\n", 448 res, GetLastError()); 449 450 DeleteMonitorA(NULL, entry->env, winetest); 451 SetLastError(MAGIC_DEAD); 452 res = AddMonitorA(empty, 2, (LPBYTE) &mi2a); 453 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError()); 454 455 /* cleanup */ 456 DeleteMonitorA(NULL, entry->env, winetest); 457 458 } 459 460 /* ########################### */ 461 462 static void test_AddPort(void) 463 { 464 DWORD res; 465 466 SetLastError(0xdeadbeef); 467 res = AddPortA(NULL, 0, NULL); 468 if (is_spooler_deactivated(res, GetLastError())) return; 469 /* NT: RPC_X_NULL_REF_POINTER, 9x: ERROR_INVALID_PARAMETER */ 470 ok( !res && ((GetLastError() == RPC_X_NULL_REF_POINTER) || 471 (GetLastError() == ERROR_INVALID_PARAMETER)), 472 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or " 473 "ERROR_INVALID_PARAMETER)\n", res, GetLastError()); 474 475 476 SetLastError(0xdeadbeef); 477 res = AddPortA(NULL, 0, empty); 478 /* Allowed only for (Printer-)Administrators */ 479 if (is_access_denied(res, GetLastError())) return; 480 481 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */ 482 ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) || 483 (GetLastError() == ERROR_INVALID_PARAMETER)), 484 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or " 485 "ERROR_INVALID_PARAMETER)\n", res, GetLastError()); 486 487 488 SetLastError(0xdeadbeef); 489 res = AddPortA(NULL, 0, does_not_exist); 490 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */ 491 ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) || 492 (GetLastError() == ERROR_INVALID_PARAMETER)), 493 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or " 494 "ERROR_INVALID_PARAMETER)\n", res, GetLastError()); 495 496 } 497 498 /* ########################### */ 499 500 static void test_AddPortEx(void) 501 { 502 PORT_INFO_2A pi; 503 DWORD res; 504 505 506 if (!pAddPortExA) { 507 win_skip("AddPortEx not supported\n"); 508 return; 509 } 510 511 /* start test with a clean system */ 512 DeletePortA(NULL, 0, tempfileA); 513 514 pi.pPortName = tempfileA; 515 SetLastError(0xdeadbeef); 516 res = pAddPortExA(NULL, 1, (LPBYTE) &pi, LocalPortA); 517 if (is_spooler_deactivated(res, GetLastError())) return; 518 519 /* Allowed only for (Printer-)Administrators. 520 W2K+XP: ERROR_INVALID_PARAMETER */ 521 if (!res && (GetLastError() == ERROR_INVALID_PARAMETER)) { 522 skip("ACCESS_DENIED (ERROR_INVALID_PARAMETER)\n"); 523 return; 524 } 525 ok( res, "got %u with %u (expected '!= 0')\n", res, GetLastError()); 526 527 /* add a port that already exists */ 528 SetLastError(0xdeadbeef); 529 res = pAddPortExA(NULL, 1, (LPBYTE) &pi, LocalPortA); 530 ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER), 531 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n", 532 res, GetLastError()); 533 DeletePortA(NULL, 0, tempfileA); 534 535 536 /* the Monitorname must match */ 537 SetLastError(0xdeadbeef); 538 res = pAddPortExA(NULL, 1, (LPBYTE) &pi, NULL); 539 ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER), 540 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n", 541 res, GetLastError()); 542 if (res) DeletePortA(NULL, 0, tempfileA); 543 544 SetLastError(0xdeadbeef); 545 res = pAddPortExA(NULL, 1, (LPBYTE) &pi, empty); 546 ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER), 547 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n", 548 res, GetLastError()); 549 if (res) DeletePortA(NULL, 0, tempfileA); 550 551 SetLastError(0xdeadbeef); 552 res = pAddPortExA(NULL, 1, (LPBYTE) &pi, does_not_exist); 553 ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER), 554 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n", 555 res, GetLastError()); 556 if (res) DeletePortA(NULL, 0, tempfileA); 557 558 559 /* We need a Portname */ 560 SetLastError(0xdeadbeef); 561 res = pAddPortExA(NULL, 1, NULL, LocalPortA); 562 ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER), 563 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n", 564 res, GetLastError()); 565 566 pi.pPortName = NULL; 567 SetLastError(0xdeadbeef); 568 res = pAddPortExA(NULL, 1, (LPBYTE) &pi, LocalPortA); 569 ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER), 570 "got %u with %u (expected '0' with ERROR_INVALID_PARAMETER)\n", 571 res, GetLastError()); 572 if (res) DeletePortA(NULL, 0, tempfileA); 573 574 575 /* level 2 is documented as supported for Printmonitors, 576 but that is not supported for "Local Port" (localspl.dll) and 577 AddPortEx fails with ERROR_INVALID_LEVEL */ 578 579 pi.pPortName = tempfileA; 580 pi.pMonitorName = LocalPortA; 581 pi.pDescription = winetest; 582 pi.fPortType = PORT_TYPE_WRITE; 583 584 SetLastError(0xdeadbeef); 585 res = pAddPortExA(NULL, 2, (LPBYTE) &pi, LocalPortA); 586 ok( !res && (GetLastError() == ERROR_INVALID_LEVEL), 587 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n", 588 res, GetLastError()); 589 if (res) DeletePortA(NULL, 0, tempfileA); 590 591 592 /* invalid levels */ 593 SetLastError(0xdeadbeef); 594 res = pAddPortExA(NULL, 0, (LPBYTE) &pi, LocalPortA); 595 ok( !res && (GetLastError() == ERROR_INVALID_LEVEL), 596 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n", 597 res, GetLastError()); 598 599 SetLastError(0xdeadbeef); 600 res = pAddPortExA(NULL, 3, (LPBYTE) &pi, LocalPortA); 601 ok( !res && (GetLastError() == ERROR_INVALID_LEVEL), 602 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n", 603 res, GetLastError()); 604 605 606 /* cleanup */ 607 DeletePortA(NULL, 0, tempfileA); 608 609 } 610 611 /* ########################### */ 612 613 static void test_ConfigurePort(void) 614 { 615 DWORD res; 616 617 618 SetLastError(0xdeadbeef); 619 res = ConfigurePortA(NULL, 0, NULL); 620 if (is_spooler_deactivated(res, GetLastError())) return; 621 /* NT: RPC_X_NULL_REF_POINTER, 9x: ERROR_INVALID_PARAMETER */ 622 ok( !res && ((GetLastError() == RPC_X_NULL_REF_POINTER) || 623 (GetLastError() == ERROR_INVALID_PARAMETER)), 624 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or " 625 "ERROR_INVALID_PARAMETER)\n", res, GetLastError()); 626 627 SetLastError(0xdeadbeef); 628 res = ConfigurePortA(NULL, 0, empty); 629 /* Allowed only for (Printer-)Administrators */ 630 if (is_access_denied(res, GetLastError())) return; 631 632 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */ 633 ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) || 634 (GetLastError() == ERROR_INVALID_PARAMETER)), 635 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or " 636 "ERROR_INVALID_PARAMETER)\n", res, GetLastError()); 637 638 639 SetLastError(0xdeadbeef); 640 res = ConfigurePortA(NULL, 0, does_not_exist); 641 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */ 642 ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) || 643 (GetLastError() == ERROR_INVALID_PARAMETER)), 644 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or " 645 "ERROR_INVALID_PARAMETER)\n", res, GetLastError()); 646 647 648 /* Testing-Results: 649 - Case of Portnames is ignored 650 - Portname without ":" => NT: ERROR_NOT_SUPPORTED, 9x: Dialog comes up 651 - Empty Servername (LPT1:) => NT: ERROR_NOT_SUPPORTED, 9x: Dialog comes up 652 653 - Port not present => 9x: ERROR_INVALID_PARAMETER, NT:ERROR_NOT_SUPPORTED 654 - "FILE:" => 9x:Success, NT:ERROR_CANCELED 655 - Cancel ("Local Port") => ERROR_CANCELED 656 - Cancel ("Redirected Port") => Success 657 */ 658 if (winetest_interactive > 0) { 659 SetLastError(0xdeadbeef); 660 res = ConfigurePortA(NULL, 0, portname_com1); 661 trace("'%s' returned %d with %d\n", portname_com1, res, GetLastError()); 662 663 SetLastError(0xdeadbeef); 664 res = ConfigurePortA(NULL, 0, portname_lpt1); 665 trace("'%s' returned %d with %d\n", portname_lpt1, res, GetLastError()); 666 667 SetLastError(0xdeadbeef); 668 res = ConfigurePortA(NULL, 0, portname_file); 669 trace("'%s' returned %d with %d\n", portname_file, res, GetLastError()); 670 } 671 } 672 673 /* ########################### */ 674 675 static void test_ClosePrinter(void) 676 { 677 HANDLE printer = 0; 678 BOOL res; 679 680 /* NULL is handled */ 681 SetLastError(0xdeadbeef); 682 res = ClosePrinter(NULL); 683 ok(!res && (GetLastError() == ERROR_INVALID_HANDLE), 684 "got %d with %d (expected FALSE with ERROR_INVALID_HANDLE)\n", 685 res, GetLastError()); 686 687 /* A random value as HANDLE is handled */ 688 SetLastError(0xdeadbeef); 689 res = ClosePrinter( (void *) -1); 690 if (is_spooler_deactivated(res, GetLastError())) return; 691 ok(!res && (GetLastError() == ERROR_INVALID_HANDLE), 692 "got %d with %d (expected FALSE with ERROR_INVALID_HANDLE)\n", 693 res, GetLastError()); 694 695 696 /* Normal use (The Spooler service is needed) */ 697 SetLastError(0xdeadbeef); 698 res = OpenPrinterA(default_printer, &printer, NULL); 699 if (is_spooler_deactivated(res, GetLastError())) return; 700 if (res) 701 { 702 SetLastError(0xdeadbeef); 703 res = ClosePrinter(printer); 704 ok(res, "got %d with %d (expected TRUE)\n", res, GetLastError()); 705 706 707 /* double free is handled */ 708 SetLastError(0xdeadbeef); 709 res = ClosePrinter(printer); 710 ok(!res && (GetLastError() == ERROR_INVALID_HANDLE), 711 "got %d with %d (expected FALSE with ERROR_INVALID_HANDLE)\n", 712 res, GetLastError()); 713 714 } 715 } 716 717 /* ########################### */ 718 719 static void test_DeleteMonitor(void) 720 { 721 MONITOR_INFO_2A mi2a; 722 struct monitor_entry * entry = NULL; 723 DWORD res; 724 725 726 entry = find_installed_monitor(); 727 728 if (!entry) { 729 skip("No usable Monitor found\n"); 730 return; 731 } 732 733 mi2a.pName = winetest; 734 mi2a.pEnvironment = entry->env; 735 mi2a.pDLLName = entry->dllname; 736 737 /* Testing DeleteMonitor with real options */ 738 AddMonitorA(NULL, 2, (LPBYTE) &mi2a); 739 740 SetLastError(MAGIC_DEAD); 741 res = DeleteMonitorA(NULL, entry->env, winetest); 742 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError()); 743 744 /* Delete the Monitor twice */ 745 SetLastError(MAGIC_DEAD); 746 res = DeleteMonitorA(NULL, entry->env, winetest); 747 /* NT: ERROR_UNKNOWN_PRINT_MONITOR (3000), 9x: ERROR_INVALID_PARAMETER (87) */ 748 ok( !res && 749 ((GetLastError() == ERROR_UNKNOWN_PRINT_MONITOR) || 750 (GetLastError() == ERROR_INVALID_PARAMETER)), 751 "returned %d with %d (expected '0' with: ERROR_UNKNOWN_PRINT_MONITOR" 752 " or ERROR_INVALID_PARAMETER)\n", res, GetLastError()); 753 754 /* the environment */ 755 AddMonitorA(NULL, 2, (LPBYTE) &mi2a); 756 SetLastError(MAGIC_DEAD); 757 res = DeleteMonitorA(NULL, NULL, winetest); 758 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError()); 759 760 AddMonitorA(NULL, 2, (LPBYTE) &mi2a); 761 SetLastError(MAGIC_DEAD); 762 res = DeleteMonitorA(NULL, empty, winetest); 763 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError()); 764 765 AddMonitorA(NULL, 2, (LPBYTE) &mi2a); 766 SetLastError(MAGIC_DEAD); 767 res = DeleteMonitorA(NULL, invalid_env, winetest); 768 ok( res || GetLastError() == ERROR_INVALID_ENVIRONMENT /* Vista/W2K8 */, 769 "returned %d with %d\n", res, GetLastError()); 770 771 /* the monitor-name */ 772 AddMonitorA(NULL, 2, (LPBYTE) &mi2a); 773 SetLastError(MAGIC_DEAD); 774 res = DeleteMonitorA(NULL, entry->env, NULL); 775 /* NT: ERROR_INVALID_PARAMETER (87), 9x: ERROR_INVALID_NAME (123)*/ 776 ok( !res && 777 ((GetLastError() == ERROR_INVALID_PARAMETER) || 778 (GetLastError() == ERROR_INVALID_NAME)), 779 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or " 780 "ERROR_INVALID_NAME)\n", res, GetLastError()); 781 782 AddMonitorA(NULL, 2, (LPBYTE) &mi2a); 783 SetLastError(MAGIC_DEAD); 784 res = DeleteMonitorA(NULL, entry->env, empty); 785 /* NT: ERROR_INVALID_PARAMETER (87), 9x: ERROR_INVALID_NAME (123)*/ 786 ok( !res && 787 ((GetLastError() == ERROR_INVALID_PARAMETER) || 788 (GetLastError() == ERROR_INVALID_NAME)), 789 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or " 790 "ERROR_INVALID_NAME)\n", res, GetLastError()); 791 792 AddMonitorA(NULL, 2, (LPBYTE) &mi2a); 793 SetLastError(MAGIC_DEAD); 794 res = DeleteMonitorA(empty, entry->env, winetest); 795 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError()); 796 797 /* cleanup */ 798 DeleteMonitorA(NULL, entry->env, winetest); 799 } 800 801 /* ########################### */ 802 803 static void test_DeletePort(void) 804 { 805 DWORD res; 806 807 SetLastError(0xdeadbeef); 808 res = DeletePortA(NULL, 0, NULL); 809 if (is_spooler_deactivated(res, GetLastError())) return; 810 811 SetLastError(0xdeadbeef); 812 res = DeletePortA(NULL, 0, empty); 813 /* Allowed only for (Printer-)Administrators */ 814 if (is_access_denied(res, GetLastError())) return; 815 816 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */ 817 ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) || 818 (GetLastError() == ERROR_INVALID_PARAMETER)), 819 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or " 820 "ERROR_INVALID_PARAMETER)\n", res, GetLastError()); 821 822 823 SetLastError(0xdeadbeef); 824 res = DeletePortA(NULL, 0, does_not_exist); 825 /* XP: ERROR_NOT_SUPPORTED, NT351 and 9x: ERROR_INVALID_PARAMETER */ 826 ok( !res && ((GetLastError() == ERROR_NOT_SUPPORTED) || 827 (GetLastError() == ERROR_INVALID_PARAMETER)), 828 "returned %d with %d (expected '0' with ERROR_NOT_SUPPORTED or " 829 "ERROR_INVALID_PARAMETER)\n", res, GetLastError()); 830 831 } 832 833 /* ########################### */ 834 835 static void test_EnumForms(LPSTR pName) 836 { 837 DWORD res; 838 HANDLE hprinter = 0; 839 LPBYTE buffer; 840 DWORD cbBuf; 841 DWORD pcbNeeded; 842 DWORD pcReturned; 843 DWORD level; 844 UINT i; 845 const char *formtype; 846 static const char * const formtypes[] = { "FORM_USER", "FORM_BUILTIN", "FORM_PRINTER", "FORM_flag_unknown" }; 847 #define FORMTYPE_MAX 2 848 PFORM_INFO_1A pFI_1a; 849 PFORM_INFO_2A pFI_2a; 850 851 res = OpenPrinterA(pName, &hprinter, NULL); 852 if (is_spooler_deactivated(res, GetLastError())) return; 853 if (!res || !hprinter) 854 { 855 /* opening the local Printserver is not supported on win9x */ 856 if (pName) skip("Failed to open '%s' (not supported on win9x)\n", pName); 857 return; 858 } 859 860 /* valid levels are 1 and 2 */ 861 for(level = 0; level < 4; level++) { 862 cbBuf = 0xdeadbeef; 863 pcReturned = 0xdeadbeef; 864 SetLastError(0xdeadbeef); 865 res = EnumFormsA(hprinter, level, NULL, 0, &cbBuf, &pcReturned); 866 867 /* EnumForms is not implemented on win9x */ 868 if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) continue; 869 870 /* EnumForms for the server is not implemented on all NT-versions */ 871 if (!res && (GetLastError() == ERROR_INVALID_HANDLE) && !pName) continue; 872 873 /* Level 2 for EnumForms is not supported on all systems */ 874 if (!res && (GetLastError() == ERROR_INVALID_LEVEL) && (level == 2)) continue; 875 876 /* use only a short test when testing an invalid level */ 877 if(!level || (level > 2)) { 878 ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) || 879 (res && (pcReturned == 0)), 880 "(%d) returned %d with %d and 0x%08x (expected '0' with " 881 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n", 882 level, res, GetLastError(), pcReturned); 883 continue; 884 } 885 886 ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), 887 "(%d) returned %d with %d (expected '0' with " 888 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError()); 889 890 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf *2); 891 if (buffer == NULL) continue; 892 893 SetLastError(0xdeadbeef); 894 res = EnumFormsA(hprinter, level, buffer, cbBuf, &pcbNeeded, &pcReturned); 895 ok(res, "(%d) returned %d with %d (expected '!=0')\n", 896 level, res, GetLastError()); 897 898 if (winetest_debug > 1) { 899 trace("dumping %d forms level %d\n", pcReturned, level); 900 pFI_1a = (PFORM_INFO_1A)buffer; 901 pFI_2a = (PFORM_INFO_2A)buffer; 902 for (i = 0; i < pcReturned; i++) 903 { 904 /* first part is same in FORM_INFO_1 and FORM_INFO_2 */ 905 formtype = (pFI_1a->Flags <= FORMTYPE_MAX) ? formtypes[pFI_1a->Flags] : formtypes[3]; 906 trace("%u (%s): %.03fmm x %.03fmm, %s\n", i, pFI_1a->pName, 907 (float)pFI_1a->Size.cx/1000, (float)pFI_1a->Size.cy/1000, formtype); 908 909 if (level == 1) pFI_1a ++; 910 else { 911 /* output additional FORM_INFO_2 fields */ 912 trace("\tkeyword=%s strtype=%u muidll=%s resid=%u dispname=%s langid=%u\n", 913 pFI_2a->pKeyword, pFI_2a->StringType, pFI_2a->pMuiDll, 914 pFI_2a->dwResourceId, pFI_2a->pDisplayName, pFI_2a->wLangId); 915 916 /* offset pointer pFI_1a by 1*sizeof(FORM_INFO_2A) Bytes */ 917 pFI_2a ++; 918 pFI_1a = (PFORM_INFO_1A)pFI_2a; 919 } 920 } 921 } 922 923 SetLastError(0xdeadbeef); 924 res = EnumFormsA(hprinter, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned); 925 ok( res, "(%d) returned %d with %d (expected '!=0')\n", 926 level, res, GetLastError()); 927 928 SetLastError(0xdeadbeef); 929 res = EnumFormsA(hprinter, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned); 930 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), 931 "(%d) returned %d with %d (expected '0' with " 932 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError()); 933 934 935 SetLastError(0xdeadbeef); 936 res = EnumFormsA(hprinter, level, NULL, cbBuf, &pcbNeeded, &pcReturned); 937 ok( !res && (GetLastError() == ERROR_INVALID_USER_BUFFER) , 938 "(%d) returned %d with %d (expected '0' with " 939 "ERROR_INVALID_USER_BUFFER)\n", level, res, GetLastError()); 940 941 942 SetLastError(0xdeadbeef); 943 res = EnumFormsA(hprinter, level, buffer, cbBuf, NULL, &pcReturned); 944 ok( !res && (GetLastError() == RPC_X_NULL_REF_POINTER) , 945 "(%d) returned %d with %d (expected '0' with " 946 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError()); 947 948 SetLastError(0xdeadbeef); 949 res = EnumFormsA(hprinter, level, buffer, cbBuf, &pcbNeeded, NULL); 950 ok( !res && (GetLastError() == RPC_X_NULL_REF_POINTER) , 951 "(%d) returned %d with %d (expected '0' with " 952 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError()); 953 954 SetLastError(0xdeadbeef); 955 res = EnumFormsA(0, level, buffer, cbBuf, &pcbNeeded, &pcReturned); 956 ok( !res && (GetLastError() == ERROR_INVALID_HANDLE) , 957 "(%d) returned %d with %d (expected '0' with " 958 "ERROR_INVALID_HANDLE)\n", level, res, GetLastError()); 959 960 HeapFree(GetProcessHeap(), 0, buffer); 961 } /* for(level ... */ 962 963 ClosePrinter(hprinter); 964 } 965 966 /* ########################### */ 967 968 static void test_EnumMonitors(void) 969 { 970 DWORD res; 971 LPBYTE buffer; 972 DWORD cbBuf; 973 DWORD pcbNeeded; 974 DWORD pcReturned; 975 DWORD level; 976 977 /* valid levels are 1 and 2 */ 978 for(level = 0; level < 4; level++) { 979 cbBuf = MAGIC_DEAD; 980 pcReturned = MAGIC_DEAD; 981 SetLastError(MAGIC_DEAD); 982 res = EnumMonitorsA(NULL, level, NULL, 0, &cbBuf, &pcReturned); 983 if (is_spooler_deactivated(res, GetLastError())) return; 984 /* not implemented yet in wine */ 985 if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) continue; 986 987 988 /* use only a short test when testing an invalid level */ 989 if(!level || (level > 2)) { 990 ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) || 991 (res && (pcReturned == 0)), 992 "(%d) returned %d with %d and 0x%08x (expected '0' with " 993 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n", 994 level, res, GetLastError(), pcReturned); 995 continue; 996 } 997 998 /* Level 2 is not supported on win9x */ 999 if (!res && (GetLastError() == ERROR_INVALID_LEVEL)) { 1000 skip("Level %d not supported\n", level); 1001 continue; 1002 } 1003 1004 ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), 1005 "(%d) returned %d with %d (expected '0' with " 1006 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError()); 1007 1008 if (!cbBuf) { 1009 skip("no valid buffer size returned\n"); 1010 continue; 1011 } 1012 1013 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf *2); 1014 if (buffer == NULL) continue; 1015 1016 SetLastError(MAGIC_DEAD); 1017 pcbNeeded = MAGIC_DEAD; 1018 res = EnumMonitorsA(NULL, level, buffer, cbBuf, &pcbNeeded, &pcReturned); 1019 ok(res, "(%d) returned %d with %d (expected '!=0')\n", 1020 level, res, GetLastError()); 1021 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", 1022 level, pcbNeeded, cbBuf); 1023 /* We can validate the returned Data with the Registry here */ 1024 1025 1026 SetLastError(MAGIC_DEAD); 1027 pcReturned = MAGIC_DEAD; 1028 pcbNeeded = MAGIC_DEAD; 1029 res = EnumMonitorsA(NULL, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned); 1030 ok(res, "(%d) returned %d with %d (expected '!=0')\n", level, 1031 res, GetLastError()); 1032 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level, 1033 pcbNeeded, cbBuf); 1034 1035 SetLastError(MAGIC_DEAD); 1036 pcbNeeded = MAGIC_DEAD; 1037 res = EnumMonitorsA(NULL, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned); 1038 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), 1039 "(%d) returned %d with %d (expected '0' with " 1040 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError()); 1041 1042 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level, 1043 pcbNeeded, cbBuf); 1044 1045 /* 1046 Do not add the next test: 1047 w2k+: RPC_X_NULL_REF_POINTER 1048 NT3.5: ERROR_INVALID_USER_BUFFER 1049 win9x: crash in winspool.drv 1050 1051 res = EnumMonitorsA(NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned); 1052 */ 1053 1054 SetLastError(MAGIC_DEAD); 1055 pcbNeeded = MAGIC_DEAD; 1056 pcReturned = MAGIC_DEAD; 1057 res = EnumMonitorsA(NULL, level, buffer, cbBuf, NULL, &pcReturned); 1058 ok( res || GetLastError() == RPC_X_NULL_REF_POINTER, 1059 "(%d) returned %d with %d (expected '!=0' or '0' with " 1060 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError()); 1061 1062 pcbNeeded = MAGIC_DEAD; 1063 pcReturned = MAGIC_DEAD; 1064 SetLastError(MAGIC_DEAD); 1065 res = EnumMonitorsA(NULL, level, buffer, cbBuf, &pcbNeeded, NULL); 1066 ok( res || GetLastError() == RPC_X_NULL_REF_POINTER, 1067 "(%d) returned %d with %d (expected '!=0' or '0' with " 1068 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError()); 1069 1070 HeapFree(GetProcessHeap(), 0, buffer); 1071 } /* for(level ... */ 1072 } 1073 1074 /* ########################### */ 1075 1076 static void test_EnumPorts(void) 1077 { 1078 DWORD res; 1079 DWORD level; 1080 LPBYTE buffer; 1081 DWORD cbBuf; 1082 DWORD pcbNeeded; 1083 DWORD pcReturned; 1084 1085 /* valid levels are 1 and 2 */ 1086 for(level = 0; level < 4; level++) { 1087 1088 cbBuf = 0xdeadbeef; 1089 pcReturned = 0xdeadbeef; 1090 SetLastError(0xdeadbeef); 1091 res = EnumPortsA(NULL, level, NULL, 0, &cbBuf, &pcReturned); 1092 if (is_spooler_deactivated(res, GetLastError())) return; 1093 1094 /* use only a short test when testing an invalid level */ 1095 if(!level || (level > 2)) { 1096 /* NT: ERROR_INVALID_LEVEL, 9x: success */ 1097 ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) || 1098 (res && (pcReturned == 0)), 1099 "(%d) returned %d with %d and 0x%08x (expected '0' with " 1100 "ERROR_INVALID_LEVEL or '!=0' and 0x0)\n", 1101 level, res, GetLastError(), pcReturned); 1102 continue; 1103 } 1104 1105 1106 /* Level 2 is not supported on NT 3.x */ 1107 if (!res && (GetLastError() == ERROR_INVALID_LEVEL)) { 1108 skip("Level %d not supported\n", level); 1109 continue; 1110 } 1111 1112 ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), 1113 "(%d) returned %d with %d (expected '0' with " 1114 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError()); 1115 1116 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf *2); 1117 if (buffer == NULL) continue; 1118 1119 pcbNeeded = 0xdeadbeef; 1120 SetLastError(0xdeadbeef); 1121 res = EnumPortsA(NULL, level, buffer, cbBuf, &pcbNeeded, &pcReturned); 1122 ok(res, "(%d) returned %d with %d (expected '!=0')\n", level, res, GetLastError()); 1123 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level, pcbNeeded, cbBuf); 1124 /* ToDo: Compare the returned Data with the Registry / "win.ini",[Ports] here */ 1125 1126 pcbNeeded = 0xdeadbeef; 1127 pcReturned = 0xdeadbeef; 1128 SetLastError(0xdeadbeef); 1129 res = EnumPortsA(NULL, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned); 1130 ok(res, "(%d) returned %d with %d (expected '!=0')\n", level, res, GetLastError()); 1131 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level, pcbNeeded, cbBuf); 1132 1133 pcbNeeded = 0xdeadbeef; 1134 SetLastError(0xdeadbeef); 1135 res = EnumPortsA(NULL, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned); 1136 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), 1137 "(%d) returned %d with %d (expected '0' with " 1138 "ERROR_INSUFFICIENT_BUFFER)\n", level, res, GetLastError()); 1139 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level, pcbNeeded, cbBuf); 1140 1141 /* 1142 Do not add this test: 1143 res = EnumPortsA(NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned); 1144 w2k+: RPC_X_NULL_REF_POINTER 1145 NT3.5: ERROR_INVALID_USER_BUFFER 1146 win9x: crash in winspool.drv 1147 */ 1148 1149 SetLastError(0xdeadbeef); 1150 res = EnumPortsA(NULL, level, buffer, cbBuf, NULL, &pcReturned); 1151 /* NT: RPC_X_NULL_REF_POINTER (1780), 9x: success */ 1152 ok( (!res && (GetLastError() == RPC_X_NULL_REF_POINTER) ) || 1153 ( res && (GetLastError() == ERROR_SUCCESS) ), 1154 "(%d) returned %d with %d (expected '0' with " 1155 "RPC_X_NULL_REF_POINTER or '!=0' with NO_ERROR)\n", 1156 level, res, GetLastError()); 1157 1158 1159 SetLastError(0xdeadbeef); 1160 res = EnumPortsA(NULL, level, buffer, cbBuf, &pcbNeeded, NULL); 1161 /* NT: RPC_X_NULL_REF_POINTER (1780), 9x: success */ 1162 ok( (!res && (GetLastError() == RPC_X_NULL_REF_POINTER) ) || 1163 ( res && (GetLastError() == ERROR_SUCCESS) ), 1164 "(%d) returned %d with %d (expected '0' with " 1165 "RPC_X_NULL_REF_POINTER or '!=0' with NO_ERROR)\n", 1166 level, res, GetLastError()); 1167 1168 HeapFree(GetProcessHeap(), 0, buffer); 1169 } 1170 } 1171 1172 /* ########################### */ 1173 1174 static void test_EnumPrinterDrivers(void) 1175 { 1176 static char env_all[] = "all"; 1177 1178 DWORD res; 1179 LPBYTE buffer; 1180 DWORD cbBuf; 1181 DWORD pcbNeeded; 1182 DWORD pcReturned; 1183 DWORD level; 1184 1185 /* 1-3 for w95/w98/NT4; 1-3+6 for me; 1-6 for w2k/xp/2003; 1-6+8 for vista */ 1186 for(level = 0; level < 10; level++) { 1187 cbBuf = 0xdeadbeef; 1188 pcReturned = 0xdeadbeef; 1189 SetLastError(0xdeadbeef); 1190 res = EnumPrinterDriversA(NULL, NULL, level, NULL, 0, &cbBuf, &pcReturned); 1191 if (is_spooler_deactivated(res, GetLastError())) return; 1192 1193 /* use only a short test when testing an invalid level */ 1194 if(!level || (level == 7) || (level > 8)) { 1195 1196 ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) || 1197 (res && (pcReturned == 0)), 1198 "(%d) got %u with %u and 0x%x " 1199 "(expected '0' with ERROR_INVALID_LEVEL or '!=0' and 0x0)\n", 1200 level, res, GetLastError(), pcReturned); 1201 continue; 1202 } 1203 1204 /* some levels are not supported on all windows versions */ 1205 if (!res && (GetLastError() == ERROR_INVALID_LEVEL)) { 1206 skip("Level %d not supported\n", level); 1207 continue; 1208 } 1209 1210 ok( ((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) || 1211 (res && (default_printer == NULL)), 1212 "(%u) got %u with %u for %s (expected '0' with " 1213 "ERROR_INSUFFICIENT_BUFFER or '!= 0' without a printer)\n", 1214 level, res, GetLastError(), default_printer); 1215 1216 if (!cbBuf) { 1217 skip("no valid buffer size returned\n"); 1218 continue; 1219 } 1220 1221 /* EnumPrinterDriversA returns the same number of bytes as EnumPrinterDriversW */ 1222 if (!on_win9x && pEnumPrinterDriversW) 1223 { 1224 DWORD double_needed; 1225 DWORD double_returned; 1226 pEnumPrinterDriversW(NULL, NULL, level, NULL, 0, &double_needed, &double_returned); 1227 ok(double_needed == cbBuf, "level %d: EnumPrinterDriversA returned different size %d than EnumPrinterDriversW (%d)\n", level, cbBuf, double_needed); 1228 } 1229 1230 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf + 4); 1231 if (buffer == NULL) continue; 1232 1233 SetLastError(0xdeadbeef); 1234 pcbNeeded = 0xdeadbeef; 1235 res = EnumPrinterDriversA(NULL, NULL, level, buffer, cbBuf, &pcbNeeded, &pcReturned); 1236 ok(res, "(%u) got %u with %u (expected '!=0')\n", level, res, GetLastError()); 1237 ok(pcbNeeded == cbBuf, "(%d) returned %d (expected %d)\n", level, pcbNeeded, cbBuf); 1238 1239 /* validate the returned data here */ 1240 if (level > 1) { 1241 LPDRIVER_INFO_2A di = (LPDRIVER_INFO_2A) buffer; 1242 1243 ok( strrchr(di->pDriverPath, '\\') != NULL, 1244 "(%u) got %s for %s (expected a full path)\n", 1245 level, di->pDriverPath, di->pName); 1246 1247 } 1248 1249 SetLastError(0xdeadbeef); 1250 pcReturned = 0xdeadbeef; 1251 pcbNeeded = 0xdeadbeef; 1252 res = EnumPrinterDriversA(NULL, NULL, level, buffer, cbBuf+1, &pcbNeeded, &pcReturned); 1253 ok(res, "(%u) got %u with %u (expected '!=0')\n", level, res, GetLastError()); 1254 ok(pcbNeeded == cbBuf, "(%u) returned %u (expected %u)\n", level, pcbNeeded, cbBuf); 1255 1256 SetLastError(0xdeadbeef); 1257 pcbNeeded = 0xdeadbeef; 1258 res = EnumPrinterDriversA(NULL, NULL, level, buffer, cbBuf-1, &pcbNeeded, &pcReturned); 1259 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), 1260 "(%u) got %u with %u (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n", 1261 level, res, GetLastError()); 1262 ok(pcbNeeded == cbBuf, "(%u) returned %u (expected %u)\n", level, pcbNeeded, cbBuf); 1263 1264 /* 1265 Do not add the next test: 1266 NT: ERROR_INVALID_USER_BUFFER 1267 win9x: crash or 100% CPU 1268 1269 res = EnumPrinterDriversA(NULL, NULL, level, NULL, cbBuf, &pcbNeeded, &pcReturned); 1270 */ 1271 1272 SetLastError(0xdeadbeef); 1273 pcbNeeded = 0xdeadbeef; 1274 pcReturned = 0xdeadbeef; 1275 res = EnumPrinterDriversA(NULL, NULL, level, buffer, cbBuf, NULL, &pcReturned); 1276 ok( res || GetLastError() == RPC_X_NULL_REF_POINTER, 1277 "(%u) got %u with %u (expected '!=0' or '0' with " 1278 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError()); 1279 1280 pcbNeeded = 0xdeadbeef; 1281 pcReturned = 0xdeadbeef; 1282 SetLastError(0xdeadbeef); 1283 res = EnumPrinterDriversA(NULL, NULL, level, buffer, cbBuf, &pcbNeeded, NULL); 1284 ok( res || GetLastError() == RPC_X_NULL_REF_POINTER, 1285 "(%u) got %u with %u (expected '!=0' or '0' with " 1286 "RPC_X_NULL_REF_POINTER)\n", level, res, GetLastError()); 1287 1288 HeapFree(GetProcessHeap(), 0, buffer); 1289 } /* for(level ... */ 1290 1291 pcbNeeded = 0; 1292 pcReturned = 0; 1293 SetLastError(0xdeadbeef); 1294 res = EnumPrinterDriversA(NULL, env_all, 1, NULL, 0, &pcbNeeded, &pcReturned); 1295 if (res) 1296 { 1297 skip("no printer drivers found\n"); 1298 return; 1299 } 1300 if (GetLastError() == ERROR_INVALID_ENVIRONMENT) 1301 { 1302 win_skip("NT4 and below don't support the 'all' environment value\n"); 1303 return; 1304 } 1305 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "unexpected error %u\n", GetLastError()); 1306 1307 buffer = HeapAlloc(GetProcessHeap(), 0, pcbNeeded); 1308 res = EnumPrinterDriversA(NULL, env_all, 1, buffer, pcbNeeded, &pcbNeeded, &pcReturned); 1309 ok(res, "EnumPrinterDriversA failed %u\n", GetLastError()); 1310 if (res && pcReturned > 0) 1311 { 1312 DRIVER_INFO_1A *di_1 = (DRIVER_INFO_1A *)buffer; 1313 ok((LPBYTE) di_1->pName == NULL || (LPBYTE) di_1->pName < buffer || 1314 (LPBYTE) di_1->pName >= (LPBYTE)(di_1 + pcReturned), 1315 "Driver Information not in sequence; pName %p, top of data %p\n", 1316 di_1->pName, di_1 + pcReturned); 1317 } 1318 1319 HeapFree(GetProcessHeap(), 0, buffer); 1320 } 1321 1322 /* ########################### */ 1323 1324 static void test_EnumPrintProcessors(void) 1325 { 1326 DWORD res; 1327 LPBYTE buffer; 1328 DWORD cbBuf; 1329 DWORD pcbNeeded; 1330 DWORD pcReturned; 1331 1332 1333 cbBuf = 0xdeadbeef; 1334 pcReturned = 0xdeadbeef; 1335 SetLastError(0xdeadbeef); 1336 res = EnumPrintProcessorsA(NULL, NULL, 1, NULL, 0, &cbBuf, &pcReturned); 1337 if (is_spooler_deactivated(res, GetLastError())) return; 1338 1339 if (res && !cbBuf) { 1340 skip("No Printprocessor installed\n"); 1341 return; 1342 } 1343 1344 ok((!res) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), 1345 "got %u with %u (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n", 1346 res, GetLastError()); 1347 1348 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf + 4); 1349 if (buffer == NULL) 1350 return; 1351 1352 SetLastError(0xdeadbeef); 1353 pcbNeeded = 0xdeadbeef; 1354 res = EnumPrintProcessorsA(NULL, NULL, 1, buffer, cbBuf, &pcbNeeded, &pcReturned); 1355 ok(res, "got %u with %u (expected '!=0')\n", res, GetLastError()); 1356 /* validate the returned data here. */ 1357 1358 1359 SetLastError(0xdeadbeef); 1360 pcReturned = 0xdeadbeef; 1361 pcbNeeded = 0xdeadbeef; 1362 res = EnumPrintProcessorsA(NULL, NULL, 1, buffer, cbBuf+1, &pcbNeeded, &pcReturned); 1363 ok(res, "got %u with %u (expected '!=0')\n", res, GetLastError()); 1364 1365 SetLastError(0xdeadbeef); 1366 pcbNeeded = 0xdeadbeef; 1367 res = EnumPrintProcessorsA(NULL, NULL, 1, buffer, cbBuf-1, &pcbNeeded, &pcReturned); 1368 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), 1369 "got %u with %u (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n", 1370 res, GetLastError()); 1371 1372 /* only level 1 is valid */ 1373 if (0) { 1374 /* both tests crash on win98se */ 1375 SetLastError(0xdeadbeef); 1376 pcbNeeded = 0xdeadbeef; 1377 pcReturned = 0xdeadbeef; 1378 res = EnumPrintProcessorsA(NULL, NULL, 0, buffer, cbBuf, &pcbNeeded, &pcReturned); 1379 ok( !res && (GetLastError() == ERROR_INVALID_LEVEL), 1380 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n", 1381 res, GetLastError()); 1382 1383 SetLastError(0xdeadbeef); 1384 pcbNeeded = 0xdeadbeef; 1385 res = EnumPrintProcessorsA(NULL, NULL, 2, buffer, cbBuf, &pcbNeeded, &pcReturned); 1386 ok( !res && (GetLastError() == ERROR_INVALID_LEVEL), 1387 "got %u with %u (expected '0' with ERROR_INVALID_LEVEL)\n", 1388 res, GetLastError()); 1389 } 1390 1391 /* an empty environment is ignored */ 1392 SetLastError(0xdeadbeef); 1393 pcbNeeded = 0xdeadbeef; 1394 res = EnumPrintProcessorsA(NULL, empty, 1, buffer, cbBuf, &pcbNeeded, &pcReturned); 1395 ok(res, "got %u with %u (expected '!=0')\n", res, GetLastError()); 1396 1397 /* the environment is checked */ 1398 SetLastError(0xdeadbeef); 1399 pcbNeeded = 0xdeadbeef; 1400 res = EnumPrintProcessorsA(NULL, invalid_env, 1, buffer, cbBuf, &pcbNeeded, &pcReturned); 1401 /* NT5: ERROR_INVALID_ENVIRONMENT, NT4: res != 0, 9x: ERROR_INVALID_PARAMETER */ 1402 ok( broken(res) || /* NT4 */ 1403 (GetLastError() == ERROR_INVALID_ENVIRONMENT) || 1404 (GetLastError() == ERROR_INVALID_PARAMETER), 1405 "got %u with %u (expected '0' with ERROR_INVALID_ENVIRONMENT or " 1406 "ERROR_INVALID_PARAMETER)\n", res, GetLastError()); 1407 1408 1409 /* failure-Codes for NULL */ 1410 if (0) { 1411 /* this test crashes on win98se */ 1412 SetLastError(0xdeadbeef); 1413 pcbNeeded = 0xdeadbeef; 1414 pcReturned = 0xdeadbeef; 1415 res = EnumPrintProcessorsA(NULL, NULL, 1, NULL, cbBuf, &pcbNeeded, &pcReturned); 1416 ok( !res && (GetLastError() == ERROR_INVALID_USER_BUFFER) , 1417 "got %u with %u (expected '0' with ERROR_INVALID_USER_BUFFER)\n", 1418 res, GetLastError()); 1419 } 1420 1421 SetLastError(0xdeadbeef); 1422 pcbNeeded = 0xdeadbeef; 1423 pcReturned = 0xdeadbeef; 1424 res = EnumPrintProcessorsA(NULL, NULL, 1, buffer, cbBuf, NULL, &pcReturned); 1425 /* the NULL is ignored on win9x */ 1426 ok( broken(res) || (!res && (GetLastError() == RPC_X_NULL_REF_POINTER)), 1427 "got %u with %u (expected '0' with RPC_X_NULL_REF_POINTER)\n", 1428 res, GetLastError()); 1429 1430 pcbNeeded = 0xdeadbeef; 1431 pcReturned = 0xdeadbeef; 1432 SetLastError(0xdeadbeef); 1433 res = EnumPrintProcessorsA(NULL, NULL, 1, buffer, cbBuf, &pcbNeeded, NULL); 1434 /* the NULL is ignored on win9x */ 1435 ok( broken(res) || (!res && (GetLastError() == RPC_X_NULL_REF_POINTER)), 1436 "got %u with %u (expected '0' with RPC_X_NULL_REF_POINTER)\n", 1437 res, GetLastError()); 1438 1439 HeapFree(GetProcessHeap(), 0, buffer); 1440 1441 } 1442 1443 /* ########################### */ 1444 1445 static void test_GetDefaultPrinter(void) 1446 { 1447 BOOL retval; 1448 DWORD exact = DEFAULT_PRINTER_SIZE; 1449 DWORD size; 1450 char buffer[DEFAULT_PRINTER_SIZE]; 1451 1452 if (!pGetDefaultPrinterA) return; 1453 /* only supported on NT like OSes starting with win2k */ 1454 1455 SetLastError(ERROR_SUCCESS); 1456 retval = pGetDefaultPrinterA(buffer, &exact); 1457 if (!retval || !exact || !*buffer || 1458 (ERROR_SUCCESS != GetLastError())) { 1459 if ((ERROR_FILE_NOT_FOUND == GetLastError()) || 1460 (ERROR_INVALID_NAME == GetLastError())) 1461 trace("this test requires a default printer to be set\n"); 1462 else { 1463 ok( 0, "function call GetDefaultPrinterA failed unexpected!\n" 1464 "function returned %s\n" 1465 "last error 0x%08x\n" 1466 "returned buffer size 0x%08x\n" 1467 "returned buffer content %s\n", 1468 retval ? "true" : "false", GetLastError(), exact, buffer); 1469 } 1470 return; 1471 } 1472 SetLastError(ERROR_SUCCESS); 1473 retval = pGetDefaultPrinterA(NULL, NULL); 1474 ok( !retval, "function result wrong! False expected\n"); 1475 ok( ERROR_INVALID_PARAMETER == GetLastError(), 1476 "Last error wrong! ERROR_INVALID_PARAMETER expected, got 0x%08x\n", 1477 GetLastError()); 1478 1479 SetLastError(ERROR_SUCCESS); 1480 retval = pGetDefaultPrinterA(buffer, NULL); 1481 ok( !retval, "function result wrong! False expected\n"); 1482 ok( ERROR_INVALID_PARAMETER == GetLastError(), 1483 "Last error wrong! ERROR_INVALID_PARAMETER expected, got 0x%08x\n", 1484 GetLastError()); 1485 1486 SetLastError(ERROR_SUCCESS); 1487 size = 0; 1488 retval = pGetDefaultPrinterA(NULL, &size); 1489 ok( !retval, "function result wrong! False expected\n"); 1490 ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(), 1491 "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n", 1492 GetLastError()); 1493 ok( size == exact, "Parameter size wrong! %d expected got %d\n", 1494 exact, size); 1495 1496 SetLastError(ERROR_SUCCESS); 1497 size = DEFAULT_PRINTER_SIZE; 1498 retval = pGetDefaultPrinterA(NULL, &size); 1499 ok( !retval, "function result wrong! False expected\n"); 1500 ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(), 1501 "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n", 1502 GetLastError()); 1503 ok( size == exact, "Parameter size wrong! %d expected got %d\n", 1504 exact, size); 1505 1506 size = 0; 1507 retval = pGetDefaultPrinterA(buffer, &size); 1508 ok( !retval, "function result wrong! False expected\n"); 1509 ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(), 1510 "Last error wrong! ERROR_INSUFFICIENT_BUFFER expected, got 0x%08x\n", 1511 GetLastError()); 1512 ok( size == exact, "Parameter size wrong! %d expected got %d\n", 1513 exact, size); 1514 1515 size = exact; 1516 retval = pGetDefaultPrinterA(buffer, &size); 1517 ok( retval, "function result wrong! True expected\n"); 1518 ok( size == exact, "Parameter size wrong! %d expected got %d\n", 1519 exact, size); 1520 } 1521 1522 static void test_GetPrinterDriverDirectory(void) 1523 { 1524 LPBYTE buffer = NULL; 1525 DWORD cbBuf = 0, pcbNeeded = 0; 1526 BOOL res; 1527 1528 1529 SetLastError(MAGIC_DEAD); 1530 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, 0, &cbBuf); 1531 if (is_spooler_deactivated(res, GetLastError())) return; 1532 1533 trace("first call returned 0x%04x, with %d: buffer size 0x%08x\n", 1534 res, GetLastError(), cbBuf); 1535 1536 ok((res == 0) && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), 1537 "returned %d with lasterror=%d (expected '0' with " 1538 "ERROR_INSUFFICIENT_BUFFER)\n", res, GetLastError()); 1539 1540 if (!cbBuf) { 1541 skip("no valid buffer size returned\n"); 1542 return; 1543 } 1544 1545 buffer = HeapAlloc( GetProcessHeap(), 0, cbBuf*2); 1546 if (buffer == NULL) return ; 1547 1548 res = GetPrinterDriverDirectoryA(NULL, NULL, 1, buffer, cbBuf, &pcbNeeded); 1549 ok( res, "expected result != 0, got %d\n", res); 1550 ok( cbBuf == pcbNeeded, "pcbNeeded set to %d instead of %d\n", 1551 pcbNeeded, cbBuf); 1552 1553 res = GetPrinterDriverDirectoryA(NULL, NULL, 1, buffer, cbBuf*2, &pcbNeeded); 1554 ok( res, "expected result != 0, got %d\n", res); 1555 ok( cbBuf == pcbNeeded, "pcbNeeded set to %d instead of %d\n", 1556 pcbNeeded, cbBuf); 1557 1558 SetLastError(MAGIC_DEAD); 1559 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, buffer, cbBuf-1, &pcbNeeded); 1560 ok( !res , "expected result == 0, got %d\n", res); 1561 ok( cbBuf == pcbNeeded, "pcbNeeded set to %d instead of %d\n", 1562 pcbNeeded, cbBuf); 1563 1564 ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(), 1565 "last error set to %d instead of ERROR_INSUFFICIENT_BUFFER\n", 1566 GetLastError()); 1567 1568 /* 1569 Do not add the next test: 1570 XPsp2: crash in this app, when the spooler is not running 1571 NT3.5: ERROR_INVALID_USER_BUFFER 1572 win9x: ERROR_INVALID_PARAMETER 1573 1574 pcbNeeded = MAGIC_DEAD; 1575 SetLastError(MAGIC_DEAD); 1576 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, cbBuf, &pcbNeeded); 1577 */ 1578 1579 SetLastError(MAGIC_DEAD); 1580 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, buffer, cbBuf, NULL); 1581 /* w7 with deactivated spooler: ERROR_INVALID_PARAMETER, 1582 NT: RPC_X_NULL_REF_POINTER */ 1583 ok( res || (GetLastError() == RPC_X_NULL_REF_POINTER) || 1584 (GetLastError() == ERROR_INVALID_PARAMETER), 1585 "returned %d with %d (expected '!=0' or '0' with RPC_X_NULL_REF_POINTER " 1586 "or '0' with ERROR_INVALID_PARAMETER)\n", res, GetLastError()); 1587 1588 SetLastError(MAGIC_DEAD); 1589 res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, cbBuf, NULL); 1590 /* w7 with deactivated spooler: ERROR_INVALID_PARAMETER, 1591 NT: RPC_X_NULL_REF_POINTER */ 1592 ok( res || (GetLastError() == RPC_X_NULL_REF_POINTER) || 1593 (GetLastError() == ERROR_INVALID_PARAMETER), 1594 "returned %d with %d (expected '!=0' or '0' with RPC_X_NULL_REF_POINTER " 1595 "or '0' with ERROR_INVALID_PARAMETER)\n", res, GetLastError()); 1596 1597 /* with a valid buffer, but level is too large */ 1598 buffer[0] = '\0'; 1599 SetLastError(MAGIC_DEAD); 1600 res = GetPrinterDriverDirectoryA(NULL, NULL, 2, buffer, cbBuf, &pcbNeeded); 1601 1602 /* Level not checked in win9x and wine:*/ 1603 if((res != FALSE) && buffer[0]) 1604 { 1605 trace("Level '2' not checked '%s'\n", buffer); 1606 } 1607 else 1608 { 1609 ok( !res && (GetLastError() == ERROR_INVALID_LEVEL), 1610 "returned %d with lasterror=%d (expected '0' with " 1611 "ERROR_INVALID_LEVEL)\n", res, GetLastError()); 1612 } 1613 1614 /* printing environments are case insensitive */ 1615 /* "Windows 4.0" is valid for win9x and NT */ 1616 buffer[0] = '\0'; 1617 SetLastError(MAGIC_DEAD); 1618 res = GetPrinterDriverDirectoryA(NULL, env_win9x_case, 1, 1619 buffer, cbBuf*2, &pcbNeeded); 1620 1621 if(!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { 1622 cbBuf = pcbNeeded; 1623 buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, cbBuf*2); 1624 if (buffer == NULL) return ; 1625 1626 SetLastError(MAGIC_DEAD); 1627 res = GetPrinterDriverDirectoryA(NULL, env_win9x_case, 1, 1628 buffer, cbBuf*2, &pcbNeeded); 1629 } 1630 1631 ok(res && buffer[0], "returned %d with " 1632 "lasterror=%d and len=%d (expected '1' with 'len > 0')\n", 1633 res, GetLastError(), lstrlenA((char *)buffer)); 1634 1635 buffer[0] = '\0'; 1636 SetLastError(MAGIC_DEAD); 1637 res = GetPrinterDriverDirectoryA(NULL, env_x86, 1, 1638 buffer, cbBuf*2, &pcbNeeded); 1639 1640 if(!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { 1641 cbBuf = pcbNeeded; 1642 buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, cbBuf*2); 1643 if (buffer == NULL) return ; 1644 1645 buffer[0] = '\0'; 1646 SetLastError(MAGIC_DEAD); 1647 res = GetPrinterDriverDirectoryA(NULL, env_x86, 1, 1648 buffer, cbBuf*2, &pcbNeeded); 1649 } 1650 1651 /* "Windows NT x86" is invalid for win9x */ 1652 ok( (res && buffer[0]) || 1653 (!res && (GetLastError() == ERROR_INVALID_ENVIRONMENT)), 1654 "returned %d with lasterror=%d and len=%d (expected '!= 0' with " 1655 "'len > 0' or '0' with ERROR_INVALID_ENVIRONMENT)\n", 1656 res, GetLastError(), lstrlenA((char *)buffer)); 1657 1658 /* A setup program (PDFCreator_0.8.0) use empty strings */ 1659 SetLastError(MAGIC_DEAD); 1660 res = GetPrinterDriverDirectoryA(empty, empty, 1, buffer, cbBuf*2, &pcbNeeded); 1661 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError() ); 1662 1663 SetLastError(MAGIC_DEAD); 1664 res = GetPrinterDriverDirectoryA(NULL, empty, 1, buffer, cbBuf*2, &pcbNeeded); 1665 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError() ); 1666 1667 SetLastError(MAGIC_DEAD); 1668 res = GetPrinterDriverDirectoryA(empty, NULL, 1, buffer, cbBuf*2, &pcbNeeded); 1669 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError() ); 1670 1671 HeapFree( GetProcessHeap(), 0, buffer); 1672 } 1673 1674 /* ##### */ 1675 1676 static void test_GetPrintProcessorDirectory(void) 1677 { 1678 LPBYTE buffer = NULL; 1679 DWORD cbBuf = 0; 1680 DWORD pcbNeeded = 0; 1681 BOOL res; 1682 1683 1684 SetLastError(0xdeadbeef); 1685 res = GetPrintProcessorDirectoryA(NULL, NULL, 1, NULL, 0, &cbBuf); 1686 if (is_spooler_deactivated(res, GetLastError())) return; 1687 1688 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), 1689 "returned %d with %d (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n", 1690 res, GetLastError()); 1691 1692 buffer = HeapAlloc(GetProcessHeap(), 0, cbBuf*2); 1693 if(buffer == NULL) return; 1694 1695 buffer[0] = '\0'; 1696 SetLastError(0xdeadbeef); 1697 res = GetPrintProcessorDirectoryA(NULL, NULL, 1, buffer, cbBuf, &pcbNeeded); 1698 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError()); 1699 1700 SetLastError(0xdeadbeef); 1701 buffer[0] = '\0'; 1702 res = GetPrintProcessorDirectoryA(NULL, NULL, 1, buffer, cbBuf*2, &pcbNeeded); 1703 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError()); 1704 1705 /* Buffer too small */ 1706 buffer[0] = '\0'; 1707 SetLastError(0xdeadbeef); 1708 res = GetPrintProcessorDirectoryA( NULL, NULL, 1, buffer, cbBuf-1, &pcbNeeded); 1709 ok( !res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER), 1710 "returned %d with %d (expected '0' with ERROR_INSUFFICIENT_BUFFER)\n", 1711 res, GetLastError()); 1712 1713 if (0) 1714 { 1715 /* XPsp2: the program will crash here, when the spooler is not running */ 1716 /* GetPrinterDriverDirectory has the same bug */ 1717 pcbNeeded = 0; 1718 SetLastError(0xdeadbeef); 1719 res = GetPrintProcessorDirectoryA( NULL, NULL, 1, NULL, cbBuf, &pcbNeeded); 1720 /* NT: ERROR_INVALID_USER_BUFFER, 9x: res != 0 */ 1721 ok( (!res && (GetLastError() == ERROR_INVALID_USER_BUFFER)) || 1722 broken(res), 1723 "returned %d with %d (expected '0' with ERROR_INVALID_USER_BUFFER)\n", 1724 res, GetLastError()); 1725 } 1726 1727 buffer[0] = '\0'; 1728 SetLastError(0xdeadbeef); 1729 res = GetPrintProcessorDirectoryA( NULL, NULL, 1, buffer, cbBuf, NULL); 1730 /* w7 with deactivated spooler: ERROR_INVALID_PARAMETER, 1731 NT: RPC_X_NULL_REF_POINTER, 9x: res != 0 */ 1732 ok( !res && ((GetLastError() == RPC_X_NULL_REF_POINTER) || 1733 (GetLastError() == ERROR_INVALID_PARAMETER)), 1734 "returned %d with %d (expected '0' with RPC_X_NULL_REF_POINTER " 1735 "or with ERROR_INVALID_PARAMETER)\n", res, GetLastError()); 1736 1737 buffer[0] = '\0'; 1738 SetLastError(0xdeadbeef); 1739 res = GetPrintProcessorDirectoryA( NULL, NULL, 1, NULL, cbBuf, NULL); 1740 /* w7 with deactivated spooler: ERROR_INVALID_PARAMETER, 1741 NT: RPC_X_NULL_REF_POINTER, 9x: res != 0 */ 1742 ok( !res && ((GetLastError() == RPC_X_NULL_REF_POINTER) || 1743 (GetLastError() == ERROR_INVALID_PARAMETER)), 1744 "returned %d with %d (expected '0' with RPC_X_NULL_REF_POINTER " 1745 "or with ERROR_INVALID_PARAMETER)\n", res, GetLastError()); 1746 1747 /* with a valid buffer, but level is invalid */ 1748 buffer[0] = '\0'; 1749 SetLastError(0xdeadbeef); 1750 res = GetPrintProcessorDirectoryA(NULL, NULL, 0, buffer, cbBuf, &pcbNeeded); 1751 /* Level is ignored in win9x*/ 1752 ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) || 1753 broken(res && buffer[0]), 1754 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n", 1755 res, GetLastError()); 1756 1757 buffer[0] = '\0'; 1758 SetLastError(0xdeadbeef); 1759 res = GetPrintProcessorDirectoryA(NULL, NULL, 2, buffer, cbBuf, &pcbNeeded); 1760 /* Level is ignored on win9x*/ 1761 ok( (!res && (GetLastError() == ERROR_INVALID_LEVEL)) || 1762 broken(res && buffer[0]), 1763 "returned %d with %d (expected '0' with ERROR_INVALID_LEVEL)\n", 1764 res, GetLastError()); 1765 1766 /* Empty environment is the same as the default environment */ 1767 buffer[0] = '\0'; 1768 SetLastError(0xdeadbeef); 1769 res = GetPrintProcessorDirectoryA(NULL, empty, 1, buffer, cbBuf*2, &pcbNeeded); 1770 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError()); 1771 1772 /* "Windows 4.0" is valid for win9x and NT */ 1773 buffer[0] = '\0'; 1774 SetLastError(0xdeadbeef); 1775 res = GetPrintProcessorDirectoryA(NULL, env_win9x_case, 1, buffer, cbBuf*2, &pcbNeeded); 1776 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError()); 1777 1778 1779 /* "Windows NT x86" is invalid for win9x */ 1780 buffer[0] = '\0'; 1781 SetLastError(0xdeadbeef); 1782 res = GetPrintProcessorDirectoryA(NULL, env_x86, 1, buffer, cbBuf*2, &pcbNeeded); 1783 ok( res || (GetLastError() == ERROR_INVALID_ENVIRONMENT), 1784 "returned %d with %d (expected '!= 0' or '0' with " 1785 "ERROR_INVALID_ENVIRONMENT)\n", res, GetLastError()); 1786 1787 /* invalid on all systems */ 1788 buffer[0] = '\0'; 1789 SetLastError(0xdeadbeef); 1790 res = GetPrintProcessorDirectoryA(NULL, invalid_env, 1, buffer, cbBuf*2, &pcbNeeded); 1791 ok( !res && (GetLastError() == ERROR_INVALID_ENVIRONMENT), 1792 "returned %d with %d (expected '0' with ERROR_INVALID_ENVIRONMENT)\n", 1793 res, GetLastError()); 1794 1795 /* Empty servername is the same as the local computer */ 1796 buffer[0] = '\0'; 1797 SetLastError(0xdeadbeef); 1798 res = GetPrintProcessorDirectoryA(empty, NULL, 1, buffer, cbBuf*2, &pcbNeeded); 1799 ok(res, "returned %d with %d (expected '!= 0')\n", res, GetLastError()); 1800 1801 /* invalid on all systems */ 1802 buffer[0] = '\0'; 1803 SetLastError(0xdeadbeef); 1804 res = GetPrintProcessorDirectoryA(server_does_not_exist, NULL, 1, buffer, cbBuf*2, &pcbNeeded); 1805 ok( !res, "expected failure\n"); 1806 ok( GetLastError() == RPC_S_SERVER_UNAVAILABLE || /* NT */ 1807 GetLastError() == ERROR_INVALID_PARAMETER || /* 9x */ 1808 GetLastError() == RPC_S_INVALID_NET_ADDR, /* Some Vista */ 1809 "unexpected last error %d\n", GetLastError()); 1810 1811 HeapFree(GetProcessHeap(), 0, buffer); 1812 } 1813 1814 /* ##### */ 1815 1816 static void test_OpenPrinter(void) 1817 { 1818 PRINTER_DEFAULTSA defaults; 1819 HANDLE hprinter; 1820 DWORD res; 1821 1822 SetLastError(MAGIC_DEAD); 1823 res = OpenPrinterA(NULL, NULL, NULL); 1824 if (is_spooler_deactivated(res, GetLastError())) return; 1825 1826 ok(!res && (GetLastError() == ERROR_INVALID_PARAMETER), 1827 "returned %d with %d (expected '0' with ERROR_INVALID_PARAMETER)\n", 1828 res, GetLastError()); 1829 1830 1831 /* Get Handle for the local Printserver (NT only)*/ 1832 hprinter = (HANDLE) MAGIC_DEAD; 1833 SetLastError(MAGIC_DEAD); 1834 res = OpenPrinterA(NULL, &hprinter, NULL); 1835 if (is_spooler_deactivated(res, GetLastError())) return; 1836 ok(res || GetLastError() == ERROR_INVALID_PARAMETER, 1837 "returned %d with %d (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n", 1838 res, GetLastError()); 1839 if(res) { 1840 ClosePrinter(hprinter); 1841 1842 defaults.pDatatype=NULL; 1843 defaults.pDevMode=NULL; 1844 1845 defaults.DesiredAccess=0; 1846 hprinter = (HANDLE) MAGIC_DEAD; 1847 SetLastError(MAGIC_DEAD); 1848 res = OpenPrinterA(NULL, &hprinter, &defaults); 1849 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError()); 1850 if (res) ClosePrinter(hprinter); 1851 1852 defaults.DesiredAccess=-1; 1853 hprinter = (HANDLE) MAGIC_DEAD; 1854 SetLastError(MAGIC_DEAD); 1855 res = OpenPrinterA(NULL, &hprinter, &defaults); 1856 todo_wine { 1857 ok(!res && GetLastError() == ERROR_ACCESS_DENIED, 1858 "returned %d with %d (expected '0' with ERROR_ACCESS_DENIED)\n", 1859 res, GetLastError()); 1860 } 1861 if (res) ClosePrinter(hprinter); 1862 1863 } 1864 1865 1866 if (local_server != NULL) { 1867 hprinter = (HANDLE) 0xdeadbeef; 1868 SetLastError(0xdeadbeef); 1869 res = OpenPrinterA(local_server, &hprinter, NULL); 1870 ok(res || GetLastError() == ERROR_INVALID_PARAMETER, 1871 "returned %d with %d (expected '!=0' or '0' with ERROR_INVALID_PARAMETER)\n", 1872 res, GetLastError()); 1873 if(res) ClosePrinter(hprinter); 1874 } 1875 1876 /* Invalid Printername */ 1877 hprinter = (HANDLE) MAGIC_DEAD; 1878 SetLastError(MAGIC_DEAD); 1879 res = OpenPrinterA(illegal_name, &hprinter, NULL); 1880 ok(!res && ((GetLastError() == ERROR_INVALID_PRINTER_NAME) || 1881 (GetLastError() == ERROR_INVALID_PARAMETER) ), 1882 "returned %d with %d (expected '0' with: ERROR_INVALID_PARAMETER or" 1883 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError()); 1884 if(res) ClosePrinter(hprinter); 1885 1886 hprinter = (HANDLE) MAGIC_DEAD; 1887 SetLastError(MAGIC_DEAD); 1888 res = OpenPrinterA(empty, &hprinter, NULL); 1889 /* NT: ERROR_INVALID_PRINTER_NAME, 9x: ERROR_INVALID_PARAMETER */ 1890 ok( !res && 1891 ((GetLastError() == ERROR_INVALID_PRINTER_NAME) || 1892 (GetLastError() == ERROR_INVALID_PARAMETER) ), 1893 "returned %d with %d (expected '0' with: ERROR_INVALID_PRINTER_NAME" 1894 " or ERROR_INVALID_PARAMETER)\n", res, GetLastError()); 1895 if(res) ClosePrinter(hprinter); 1896 1897 1898 /* get handle for the default printer */ 1899 if (default_printer) 1900 { 1901 hprinter = (HANDLE) MAGIC_DEAD; 1902 SetLastError(MAGIC_DEAD); 1903 res = OpenPrinterA(default_printer, &hprinter, NULL); 1904 if((!res) && (GetLastError() == RPC_S_SERVER_UNAVAILABLE)) 1905 { 1906 trace("The service 'Spooler' is required for '%s'\n", default_printer); 1907 return; 1908 } 1909 ok(res, "returned %d with %d (expected '!=0')\n", res, GetLastError()); 1910 if(res) ClosePrinter(hprinter); 1911 1912 SetLastError(MAGIC_DEAD); 1913 res = OpenPrinterA(default_printer, NULL, NULL); 1914 /* NT: FALSE with ERROR_INVALID_PARAMETER, 9x: TRUE */ 1915 ok(res || (GetLastError() == ERROR_INVALID_PARAMETER), 1916 "returned %d with %d (expected '!=0' or '0' with " 1917 "ERROR_INVALID_PARAMETER)\n", res, GetLastError()); 1918 1919 defaults.pDatatype=NULL; 1920 defaults.pDevMode=NULL; 1921 defaults.DesiredAccess=0; 1922 1923 hprinter = (HANDLE) MAGIC_DEAD; 1924 SetLastError(MAGIC_DEAD); 1925 res = OpenPrinterA(default_printer, &hprinter, &defaults); 1926 ok(res || GetLastError() == ERROR_ACCESS_DENIED, 1927 "returned %d with %d (expected '!=0' or '0' with " 1928 "ERROR_ACCESS_DENIED)\n", res, GetLastError()); 1929 if(res) ClosePrinter(hprinter); 1930 1931 defaults.pDatatype = empty; 1932 1933 hprinter = (HANDLE) MAGIC_DEAD; 1934 SetLastError(MAGIC_DEAD); 1935 res = OpenPrinterA(default_printer, &hprinter, &defaults); 1936 /* stop here, when a remote Printserver has no RPC-Service running */ 1937 if (is_spooler_deactivated(res, GetLastError())) return; 1938 ok(res || ((GetLastError() == ERROR_INVALID_DATATYPE) || 1939 (GetLastError() == ERROR_ACCESS_DENIED)), 1940 "returned %d with %d (expected '!=0' or '0' with: " 1941 "ERROR_INVALID_DATATYPE or ERROR_ACCESS_DENIED)\n", 1942 res, GetLastError()); 1943 if(res) ClosePrinter(hprinter); 1944 1945 1946 defaults.pDatatype=NULL; 1947 defaults.DesiredAccess=PRINTER_ACCESS_USE; 1948 1949 hprinter = (HANDLE) MAGIC_DEAD; 1950 SetLastError(MAGIC_DEAD); 1951 res = OpenPrinterA(default_printer, &hprinter, &defaults); 1952 ok(res || GetLastError() == ERROR_ACCESS_DENIED, 1953 "returned %d with %d (expected '!=0' or '0' with " 1954 "ERROR_ACCESS_DENIED)\n", res, GetLastError()); 1955 if(res) ClosePrinter(hprinter); 1956 1957 1958 defaults.DesiredAccess=PRINTER_ALL_ACCESS; 1959 hprinter = (HANDLE) MAGIC_DEAD; 1960 SetLastError(MAGIC_DEAD); 1961 res = OpenPrinterA(default_printer, &hprinter, &defaults); 1962 ok(res || GetLastError() == ERROR_ACCESS_DENIED, 1963 "returned %d with %d (expected '!=0' or '0' with " 1964 "ERROR_ACCESS_DENIED)\n", res, GetLastError()); 1965 if(res) ClosePrinter(hprinter); 1966 } 1967 1968 } 1969 1970 1971 static void test_SetDefaultPrinter(void) 1972 { 1973 DWORD res; 1974 DWORD size = DEFAULT_PRINTER_SIZE; 1975 CHAR buffer[DEFAULT_PRINTER_SIZE]; 1976 CHAR org_value[DEFAULT_PRINTER_SIZE]; 1977 1978 if (!default_printer) 1979 { 1980 skip("There is no default printer installed\n"); 1981 return; 1982 } 1983 1984 if (!pSetDefaultPrinterA) return; 1985 /* only supported on win2k and above */ 1986 1987 /* backup the original value */ 1988 org_value[0] = '\0'; 1989 SetLastError(MAGIC_DEAD); 1990 res = GetProfileStringA("windows", "device", NULL, org_value, size); 1991 ok(res, "GetProfileString error %d\n", GetLastError()); 1992 1993 /* first part: with the default Printer */ 1994 SetLastError(MAGIC_DEAD); 1995 res = pSetDefaultPrinterA("no_printer_with_this_name"); 1996 if (is_spooler_deactivated(res, GetLastError())) return; 1997 1998 /* Not implemented in wine */ 1999 if (!res && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) { 2000 trace("SetDefaultPrinterA() not implemented yet.\n"); 2001 return; 2002 } 2003 2004 ok(!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME), 2005 "returned %d with %d (expected '0' with " 2006 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError()); 2007 2008 WriteProfileStringA("windows", "device", org_value); 2009 SetLastError(MAGIC_DEAD); 2010 res = pSetDefaultPrinterA(""); 2011 ok(res || GetLastError() == ERROR_INVALID_PRINTER_NAME, 2012 "returned %d with %d (expected '!=0' or '0' with " 2013 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError()); 2014 2015 WriteProfileStringA("windows", "device", org_value); 2016 SetLastError(MAGIC_DEAD); 2017 res = pSetDefaultPrinterA(NULL); 2018 ok(res || GetLastError() == ERROR_INVALID_PRINTER_NAME, 2019 "returned %d with %d (expected '!=0' or '0' with " 2020 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError()); 2021 2022 WriteProfileStringA("windows", "device", org_value); 2023 SetLastError(MAGIC_DEAD); 2024 res = pSetDefaultPrinterA(default_printer); 2025 ok(res || GetLastError() == ERROR_INVALID_PRINTER_NAME, 2026 "returned %d with %d (expected '!=0' or '0' with " 2027 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError()); 2028 2029 2030 /* second part: always without a default Printer */ 2031 WriteProfileStringA("windows", "device", NULL); 2032 SetLastError(MAGIC_DEAD); 2033 res = pSetDefaultPrinterA("no_printer_with_this_name"); 2034 2035 ok(!res && (GetLastError() == ERROR_INVALID_PRINTER_NAME), 2036 "returned %d with %d (expected '0' with " 2037 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError()); 2038 2039 WriteProfileStringA("windows", "device", NULL); 2040 SetLastError(MAGIC_DEAD); 2041 res = pSetDefaultPrinterA(""); 2042 if (is_spooler_deactivated(res, GetLastError())) 2043 goto restore_old_printer; 2044 2045 /* we get ERROR_INVALID_PRINTER_NAME when no printer is installed */ 2046 ok(res || GetLastError() == ERROR_INVALID_PRINTER_NAME, 2047 "returned %d with %d (expected '!=0' or '0' with " 2048 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError()); 2049 2050 WriteProfileStringA("windows", "device", NULL); 2051 SetLastError(MAGIC_DEAD); 2052 res = pSetDefaultPrinterA(NULL); 2053 /* we get ERROR_INVALID_PRINTER_NAME when no printer is installed */ 2054 ok(res || GetLastError() == ERROR_INVALID_PRINTER_NAME, 2055 "returned %d with %d (expected '!=0' or '0' with " 2056 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError()); 2057 2058 WriteProfileStringA("windows", "device", NULL); 2059 SetLastError(MAGIC_DEAD); 2060 res = pSetDefaultPrinterA(default_printer); 2061 ok(res || GetLastError() == ERROR_INVALID_PRINTER_NAME, 2062 "returned %d with %d (expected '!=0' or '0' with " 2063 "ERROR_INVALID_PRINTER_NAME)\n", res, GetLastError()); 2064 2065 /* restore the original value */ 2066 restore_old_printer: 2067 res = pSetDefaultPrinterA(default_printer); /* the nice way */ 2068 ok(res, "SetDefaultPrinter error %d\n", GetLastError()); 2069 WriteProfileStringA("windows", "device", org_value); /* the old way */ 2070 2071 buffer[0] = '\0'; 2072 SetLastError(MAGIC_DEAD); 2073 res = GetProfileStringA("windows", "device", NULL, buffer, size); 2074 ok(res, "GetProfileString error %d\n", GetLastError()); 2075 ok(!lstrcmpA(org_value, buffer), "'%s' (expected '%s')\n", buffer, org_value); 2076 2077 } 2078 2079 /* ########################### */ 2080 2081 static void test_XcvDataW_MonitorUI(void) 2082 { 2083 DWORD res; 2084 HANDLE hXcv; 2085 BYTE buffer[MAX_PATH + 4]; 2086 DWORD needed; 2087 DWORD status; 2088 DWORD len; 2089 PRINTER_DEFAULTSA pd; 2090 2091 /* api is not present before w2k */ 2092 if (pXcvDataW == NULL) return; 2093 2094 pd.pDatatype = NULL; 2095 pd.pDevMode = NULL; 2096 pd.DesiredAccess = SERVER_ACCESS_ADMINISTER; 2097 2098 hXcv = NULL; 2099 SetLastError(0xdeadbeef); 2100 res = OpenPrinterA(xcv_localport, &hXcv, &pd); 2101 if (is_spooler_deactivated(res, GetLastError())) return; 2102 if (is_access_denied(res, GetLastError())) return; 2103 2104 ok(res, "returned %d with %u and handle %p (expected '!= 0')\n", res, GetLastError(), hXcv); 2105 if (!res) return; 2106 2107 /* ask for needed size */ 2108 needed = (DWORD) 0xdeadbeef; 2109 status = (DWORD) 0xdeadbeef; 2110 SetLastError(0xdeadbeef); 2111 res = pXcvDataW(hXcv, cmd_MonitorUIW, NULL, 0, NULL, 0, &needed, &status); 2112 ok( res && (status == ERROR_INSUFFICIENT_BUFFER) && (needed <= MAX_PATH), 2113 "returned %d with %u and %u for status %u (expected '!= 0' and " 2114 "'<= MAX_PATH' for status ERROR_INSUFFICIENT_BUFFER)\n", 2115 res, GetLastError(), needed, status); 2116 2117 if (needed > MAX_PATH) { 2118 ClosePrinter(hXcv); 2119 skip("buffer overflow (%u)\n", needed); 2120 return; 2121 } 2122 len = needed; /* Size is in bytes */ 2123 2124 /* the command is required */ 2125 needed = (DWORD) 0xdeadbeef; 2126 status = (DWORD) 0xdeadbeef; 2127 SetLastError(0xdeadbeef); 2128 res = pXcvDataW(hXcv, emptyW, NULL, 0, NULL, 0, &needed, &status); 2129 ok( res && (status == ERROR_INVALID_PARAMETER), 2130 "returned %d with %u and %u for status %u (expected '!= 0' with " 2131 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), needed, status); 2132 2133 needed = (DWORD) 0xdeadbeef; 2134 status = (DWORD) 0xdeadbeef; 2135 SetLastError(0xdeadbeef); 2136 res = pXcvDataW(hXcv, NULL, NULL, 0, buffer, MAX_PATH, &needed, &status); 2137 ok( !res && (GetLastError() == RPC_X_NULL_REF_POINTER), 2138 "returned %d with %u and %u for status %u (expected '0' with " 2139 "RPC_X_NULL_REF_POINTER)\n", res, GetLastError(), needed, status); 2140 2141 /* "PDWORD needed" is checked before RPC-Errors */ 2142 needed = (DWORD) 0xdeadbeef; 2143 status = (DWORD) 0xdeadbeef; 2144 SetLastError(0xdeadbeef); 2145 res = pXcvDataW(hXcv, cmd_MonitorUIW, NULL, 0, buffer, len, NULL, &status); 2146 ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER), 2147 "returned %d with %u and %u for status %u (expected '0' with " 2148 "ERROR_INVALID_PARAMETER)\n", res, GetLastError(), needed, status); 2149 2150 needed = (DWORD) 0xdeadbeef; 2151 status = (DWORD) 0xdeadbeef; 2152 SetLastError(0xdeadbeef); 2153 res = pXcvDataW(hXcv, cmd_MonitorUIW, NULL, 0, NULL, len, &needed, &status); 2154 ok( !res && (GetLastError() == RPC_X_NULL_REF_POINTER), 2155 "returned %d with %u and %u for status %u (expected '0' with " 2156 "RPC_X_NULL_REF_POINTER)\n", res, GetLastError(), needed, status); 2157 2158 needed = (DWORD) 0xdeadbeef; 2159 status = (DWORD) 0xdeadbeef; 2160 SetLastError(0xdeadbeef); 2161 res = pXcvDataW(hXcv, cmd_MonitorUIW, NULL, 0, buffer, len, &needed, NULL); 2162 ok( !res && (GetLastError() == RPC_X_NULL_REF_POINTER), 2163 "returned %d with %u and %u for status %u (expected '0' with " 2164 "RPC_X_NULL_REF_POINTER)\n", res, GetLastError(), needed, status); 2165 2166 /* off by one: larger */ 2167 needed = (DWORD) 0xdeadbeef; 2168 status = (DWORD) 0xdeadbeef; 2169 SetLastError(0xdeadbeef); 2170 res = pXcvDataW(hXcv, cmd_MonitorUIW, NULL, 0, buffer, len+1, &needed, &status); 2171 ok( res && (status == ERROR_SUCCESS), 2172 "returned %d with %u and %u for status %u (expected '!= 0' for status " 2173 "ERROR_SUCCESS)\n", res, GetLastError(), needed, status); 2174 2175 /* off by one: smaller */ 2176 /* the buffer is not modified for NT4, w2k, XP */ 2177 needed = (DWORD) 0xdeadbeef; 2178 status = (DWORD) 0xdeadbeef; 2179 SetLastError(0xdeadbeef); 2180 res = pXcvDataW(hXcv, cmd_MonitorUIW, NULL, 0, buffer, len-1, &needed, &status); 2181 ok( res && (status == ERROR_INSUFFICIENT_BUFFER), 2182 "returned %d with %u and %u for status %u (expected '!= 0' for status " 2183 "ERROR_INSUFFICIENT_BUFFER)\n", res, GetLastError(), needed, status); 2184 2185 2186 /* Normal use. The DLL-Name without a Path is returned */ 2187 memset(buffer, 0, len); 2188 needed = (DWORD) 0xdeadbeef; 2189 status = (DWORD) 0xdeadbeef; 2190 SetLastError(0xdeadbeef); 2191 res = pXcvDataW(hXcv, cmd_MonitorUIW, NULL, 0, buffer, len, &needed, &status); 2192 ok( res && (status == ERROR_SUCCESS), 2193 "returned %d with %u and %u for status %u (expected '!= 0' for status " 2194 "ERROR_SUCCESS)\n", res, GetLastError(), needed, status); 2195 2196 ClosePrinter(hXcv); 2197 } 2198 2199 /* ########################### */ 2200 2201 static void test_XcvDataW_PortIsValid(void) 2202 { 2203 DWORD res; 2204 HANDLE hXcv; 2205 DWORD needed; 2206 DWORD status; 2207 PRINTER_DEFAULTSA pd; 2208 2209 /* api is not present before w2k */ 2210 if (pXcvDataW == NULL) return; 2211 2212 pd.pDatatype = NULL; 2213 pd.pDevMode = NULL; 2214 pd.DesiredAccess = SERVER_ACCESS_ADMINISTER; 2215 2216 hXcv = NULL; 2217 SetLastError(0xdeadbeef); 2218 res = OpenPrinterA(xcv_localport, &hXcv, &pd); 2219 if (is_spooler_deactivated(res, GetLastError())) return; 2220 if (is_access_denied(res, GetLastError())) return; 2221 2222 ok(res, "returned %d with %u and handle %p (expected '!= 0')\n", res, GetLastError(), hXcv); 2223 if (!res) return; 2224 2225 2226 /* "PDWORD needed" is always required */ 2227 needed = (DWORD) 0xdeadbeef; 2228 status = (DWORD) 0xdeadbeef; 2229 SetLastError(0xdeadbeef); 2230 res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) portname_lpt1W, sizeof(portname_lpt1W), NULL, 0, NULL, &status); 2231 ok( !res && (GetLastError() == ERROR_INVALID_PARAMETER), 2232 "returned %d with %u and %u for status %u (expected '!= 0' with ERROR_INVALID_PARAMETER)\n", 2233 res, GetLastError(), needed, status); 2234 2235 /* an empty name is not allowed */ 2236 needed = (DWORD) 0xdeadbeef; 2237 status = (DWORD) 0xdeadbeef; 2238 SetLastError(0xdeadbeef); 2239 res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) emptyW, sizeof(emptyW), NULL, 0, &needed, &status); 2240 ok( res && ((status == ERROR_FILE_NOT_FOUND) || (status == ERROR_PATH_NOT_FOUND)), 2241 "returned %d with %u and %u for status %u (expected '!= 0' for status: " 2242 "ERROR_FILE_NOT_FOUND or ERROR_PATH_NOT_FOUND)\n", 2243 res, GetLastError(), needed, status); 2244 2245 /* a directory is not allowed */ 2246 needed = (DWORD) 0xdeadbeef; 2247 status = (DWORD) 0xdeadbeef; 2248 SetLastError(0xdeadbeef); 2249 res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) tempdirW, (lstrlenW(tempdirW) + 1) * sizeof(WCHAR), NULL, 0, &needed, &status); 2250 /* XP: ERROR_PATH_NOT_FOUND, w2k ERROR_ACCESS_DENIED */ 2251 ok( res && ((status == ERROR_PATH_NOT_FOUND) || (status == ERROR_ACCESS_DENIED)), 2252 "returned %d with %u and %u for status %u (expected '!= 0' for status: " 2253 "ERROR_PATH_NOT_FOUND or ERROR_ACCESS_DENIED)\n", 2254 res, GetLastError(), needed, status); 2255 2256 /* more valid well known ports */ 2257 needed = (DWORD) 0xdeadbeef; 2258 status = (DWORD) 0xdeadbeef; 2259 SetLastError(0xdeadbeef); 2260 res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) portname_lpt1W, sizeof(portname_lpt1W), NULL, 0, &needed, &status); 2261 ok( res && (status == ERROR_SUCCESS), 2262 "returned %d with %u and %u for status %u (expected '!= 0' for ERROR_SUCCESS)\n", 2263 res, GetLastError(), needed, status); 2264 2265 needed = (DWORD) 0xdeadbeef; 2266 status = (DWORD) 0xdeadbeef; 2267 SetLastError(0xdeadbeef); 2268 res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) portname_lpt2W, sizeof(portname_lpt2W), NULL, 0, &needed, &status); 2269 ok( res && (status == ERROR_SUCCESS), 2270 "returned %d with %u and %u for status %u (expected '!= 0' for ERROR_SUCCESS)\n", 2271 res, GetLastError(), needed, status); 2272 2273 needed = (DWORD) 0xdeadbeef; 2274 status = (DWORD) 0xdeadbeef; 2275 SetLastError(0xdeadbeef); 2276 res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) portname_com1W, sizeof(portname_com1W), NULL, 0, &needed, &status); 2277 ok( res && (status == ERROR_SUCCESS), 2278 "returned %d with %u and %u for status %u (expected '!= 0' for ERROR_SUCCESS)\n", 2279 res, GetLastError(), needed, status); 2280 2281 needed = (DWORD) 0xdeadbeef; 2282 status = (DWORD) 0xdeadbeef; 2283 SetLastError(0xdeadbeef); 2284 res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) portname_com2W, sizeof(portname_com2W), NULL, 0, &needed, &status); 2285 ok( res && (status == ERROR_SUCCESS), 2286 "returned %d with %u and %u for status %u (expected '!= 0' for ERROR_SUCCESS)\n", 2287 res, GetLastError(), needed, status); 2288 2289 needed = (DWORD) 0xdeadbeef; 2290 status = (DWORD) 0xdeadbeef; 2291 SetLastError(0xdeadbeef); 2292 res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) portname_fileW, sizeof(portname_fileW), NULL, 0, &needed, &status); 2293 ok( res && (status == ERROR_SUCCESS), 2294 "returned %d with %u and %u for status %u (expected '!= 0' with ERROR_SUCCESS)\n", 2295 res, GetLastError(), needed, status); 2296 2297 2298 /* a normal, writable file is allowed */ 2299 needed = (DWORD) 0xdeadbeef; 2300 status = (DWORD) 0xdeadbeef; 2301 SetLastError(0xdeadbeef); 2302 res = pXcvDataW(hXcv, cmd_PortIsValidW, (PBYTE) tempfileW, (lstrlenW(tempfileW) + 1) * sizeof(WCHAR), NULL, 0, &needed, &status); 2303 ok( res && (status == ERROR_SUCCESS), 2304 "returned %d with %u and %u for status %u (expected '!= 0' with ERROR_SUCCESS)\n", 2305 res, GetLastError(), needed, status); 2306 2307 ClosePrinter(hXcv); 2308 } 2309 2310 /* ########################### */ 2311 2312 static void test_GetPrinter(void) 2313 { 2314 HANDLE hprn; 2315 BOOL ret; 2316 BYTE *buf; 2317 INT level; 2318 DWORD needed, filled; 2319 2320 if (!default_printer) 2321 { 2322 skip("There is no default printer installed\n"); 2323 return; 2324 } 2325 2326 hprn = 0; 2327 ret = OpenPrinterA(default_printer, &hprn, NULL); 2328 if (!ret) 2329 { 2330 skip("Unable to open the default printer (%s)\n", default_printer); 2331 return; 2332 } 2333 ok(hprn != 0, "wrong hprn %p\n", hprn); 2334 2335 for (level = 1; level <= 9; level++) 2336 { 2337 SetLastError(0xdeadbeef); 2338 needed = (DWORD)-1; 2339 ret = GetPrinterA(hprn, level, NULL, 0, &needed); 2340 if (ret) 2341 { 2342 win_skip("Level %d is not supported on Win9x/WinMe\n", level); 2343 ok(GetLastError() == ERROR_SUCCESS, "wrong error %d\n", GetLastError()); 2344 ok(needed == 0,"Expected 0, got %d\n", needed); 2345 continue; 2346 } 2347 ok(!ret, "level %d: GetPrinter should fail\n", level); 2348 /* Not all levels are supported on all Windows-Versions */ 2349 if (GetLastError() == ERROR_INVALID_LEVEL || 2350 GetLastError() == ERROR_NOT_SUPPORTED /* Win9x/WinMe */) 2351 { 2352 skip("Level %d not supported\n", level); 2353 continue; 2354 } 2355 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %d\n", GetLastError()); 2356 ok(needed > 0,"not expected needed buffer size %d\n", needed); 2357 2358 /* GetPrinterA returns the same number of bytes as GetPrinterW */ 2359 if (!on_win9x && !ret && pGetPrinterW && level != 6 && level != 7) 2360 { 2361 DWORD double_needed; 2362 ret = pGetPrinterW(hprn, level, NULL, 0, &double_needed); 2363 ok(!ret, "level %d: GetPrinter error %d\n", level, GetLastError()); 2364 ok(double_needed == needed, "level %d: GetPrinterA returned different size %d than GetPrinterW (%d)\n", level, needed, double_needed); 2365 } 2366 2367 buf = HeapAlloc(GetProcessHeap(), 0, needed); 2368 2369 SetLastError(0xdeadbeef); 2370 filled = -1; 2371 ret = GetPrinterA(hprn, level, buf, needed, &filled); 2372 ok(ret, "level %d: GetPrinter error %d\n", level, GetLastError()); 2373 ok(needed == filled, "needed %d != filled %d\n", needed, filled); 2374 2375 if (level == 2) 2376 { 2377 PRINTER_INFO_2A *pi_2 = (PRINTER_INFO_2A *)buf; 2378 2379 ok(pi_2->pPrinterName!= NULL, "not expected NULL ptr\n"); 2380 ok(pi_2->pDriverName!= NULL, "not expected NULL ptr\n"); 2381 2382 trace("pPrinterName %s\n", pi_2->pPrinterName); 2383 trace("pDriverName %s\n", pi_2->pDriverName); 2384 } 2385 2386 HeapFree(GetProcessHeap(), 0, buf); 2387 } 2388 2389 SetLastError(0xdeadbeef); 2390 ret = ClosePrinter(hprn); 2391 ok(ret, "ClosePrinter error %d\n", GetLastError()); 2392 } 2393 2394 /* ########################### */ 2395 2396 static void test_GetPrinterData(void) 2397 { 2398 HANDLE hprn = 0; 2399 DWORD res; 2400 DWORD type; 2401 CHAR buffer[MAX_PATH + 1]; 2402 DWORD needed; 2403 DWORD len; 2404 2405 /* ToDo: test parameter validation, test with the default printer */ 2406 2407 SetLastError(0xdeadbeef); 2408 res = OpenPrinterA(NULL, &hprn, NULL); 2409 if (!res) 2410 { 2411 /* printserver not available on win9x */ 2412 if (!on_win9x) 2413 win_skip("Unable to open the printserver: %d\n", GetLastError()); 2414 return; 2415 } 2416 2417 memset(buffer, '#', sizeof(buffer)); 2418 buffer[MAX_PATH] = 0; 2419 type = 0xdeadbeef; 2420 needed = 0xdeadbeef; 2421 SetLastError(0xdeadbeef); 2422 res = GetPrinterDataA(hprn, defaultspooldirectory, &type, (LPBYTE) buffer, sizeof(buffer), &needed); 2423 2424 len = lstrlenA(buffer) + sizeof(CHAR); 2425 /* NT4 and w2k require a buffer to save the UNICODE result also for the ANSI function */ 2426 ok( !res && (type == REG_SZ) && ((needed == len) || (needed == (len * sizeof(WCHAR)))), 2427 "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n", 2428 res, type, needed, buffer, len); 2429 2430 needed = 0xdeadbeef; 2431 SetLastError(0xdeadbeef); 2432 res = GetPrinterDataA(hprn, defaultspooldirectory, NULL, NULL, 0, &needed); 2433 ok( (res == ERROR_MORE_DATA) && ((needed == len) || (needed == (len * sizeof(WCHAR)))), 2434 "got %d, needed: %d (expected ERROR_MORE_DATA and %d)\n", res, needed, len); 2435 2436 /* ToDo: test SPLREG_* */ 2437 2438 SetLastError(0xdeadbeef); 2439 res = ClosePrinter(hprn); 2440 ok(res, "ClosePrinter error %d\n", GetLastError()); 2441 } 2442 2443 /* ########################### */ 2444 2445 static void test_GetPrinterDataEx(void) 2446 { 2447 HANDLE hprn = 0; 2448 DWORD res; 2449 DWORD type; 2450 CHAR buffer[MAX_PATH + 1]; 2451 DWORD needed; 2452 DWORD len; 2453 2454 /* not present before w2k */ 2455 if (!pGetPrinterDataExA) { 2456 win_skip("GetPrinterDataEx not found\n"); 2457 return; 2458 } 2459 2460 /* ToDo: test parameter validation, test with the default printer */ 2461 2462 SetLastError(0xdeadbeef); 2463 res = OpenPrinterA(NULL, &hprn, NULL); 2464 if (!res) 2465 { 2466 win_skip("Unable to open the printserver: %d\n", GetLastError()); 2467 return; 2468 } 2469 2470 /* keyname is ignored, when hprn is a HANDLE for a printserver */ 2471 memset(buffer, '#', sizeof(buffer)); 2472 buffer[MAX_PATH] = 0; 2473 type = 0xdeadbeef; 2474 needed = 0xdeadbeef; 2475 SetLastError(0xdeadbeef); 2476 res = pGetPrinterDataExA(hprn, NULL, defaultspooldirectory, &type, 2477 (LPBYTE) buffer, sizeof(buffer), &needed); 2478 2479 len = lstrlenA(buffer) + sizeof(CHAR); 2480 /* NT4 and w2k require a buffer to save the UNICODE result also for the ANSI function */ 2481 ok( !res && (type == REG_SZ) && ((needed == len) || (needed == (len * sizeof(WCHAR)))), 2482 "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n", 2483 res, type, needed, buffer, len); 2484 2485 memset(buffer, '#', sizeof(buffer)); 2486 buffer[MAX_PATH] = 0; 2487 type = 0xdeadbeef; 2488 needed = 0xdeadbeef; 2489 SetLastError(0xdeadbeef); 2490 res = pGetPrinterDataExA(hprn, "", defaultspooldirectory, &type, 2491 (LPBYTE) buffer, sizeof(buffer), &needed); 2492 len = lstrlenA(buffer) + sizeof(CHAR); 2493 ok( !res && (type == REG_SZ) && ((needed == len) || (needed == (len * sizeof(WCHAR)))), 2494 "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n", 2495 res, type, needed, buffer, len); 2496 2497 memset(buffer, '#', sizeof(buffer)); 2498 buffer[MAX_PATH] = 0; 2499 type = 0xdeadbeef; 2500 needed = 0xdeadbeef; 2501 SetLastError(0xdeadbeef); 2502 /* Wine uses GetPrinterDataEx with "PrinterDriverData" to implement GetPrinterData */ 2503 res = pGetPrinterDataExA(hprn, "PrinterDriverData", defaultspooldirectory, 2504 &type, (LPBYTE) buffer, sizeof(buffer), &needed); 2505 len = lstrlenA(buffer) + sizeof(CHAR); 2506 ok( !res && (type == REG_SZ) && ((needed == len) || (needed == (len * sizeof(WCHAR)))), 2507 "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n", 2508 res, type, needed, buffer, len); 2509 2510 2511 memset(buffer, '#', sizeof(buffer)); 2512 buffer[MAX_PATH] = 0; 2513 type = 0xdeadbeef; 2514 needed = 0xdeadbeef; 2515 SetLastError(0xdeadbeef); 2516 res = pGetPrinterDataExA(hprn, does_not_exist, defaultspooldirectory, &type, 2517 (LPBYTE) buffer, sizeof(buffer), &needed); 2518 len = lstrlenA(buffer) + sizeof(CHAR); 2519 ok( !res && (type == REG_SZ) && ((needed == len) || (needed == (len * sizeof(WCHAR)))), 2520 "got %d, type %d, needed: %d and '%s' (expected ERROR_SUCCESS, REG_SZ and %d)\n", 2521 res, type, needed, buffer, len); 2522 2523 needed = 0xdeadbeef; 2524 SetLastError(0xdeadbeef); 2525 /* vista and w2k8 have a bug in GetPrinterDataEx: 2526 the current LastError value is returned as result */ 2527 res = pGetPrinterDataExA(hprn, NULL, defaultspooldirectory, NULL, NULL, 0, &needed); 2528 ok( ((res == ERROR_MORE_DATA) || broken(res == 0xdeadbeef)) && 2529 ((needed == len) || (needed == (len * sizeof(WCHAR)))), 2530 "got %d, needed: %d (expected ERROR_MORE_DATA and %d)\n", res, needed, len); 2531 2532 needed = 0xdeadbeef; 2533 SetLastError(0xdeaddead); 2534 res = pGetPrinterDataExA(hprn, NULL, defaultspooldirectory, NULL, NULL, 0, &needed); 2535 ok( ((res == ERROR_MORE_DATA) || broken(res == 0xdeaddead)) && 2536 ((needed == len) || (needed == (len * sizeof(WCHAR)))), 2537 "got %d, needed: %d (expected ERROR_MORE_DATA and %d)\n", res, needed, len); 2538 2539 SetLastError(0xdeadbeef); 2540 res = ClosePrinter(hprn); 2541 ok(res, "ClosePrinter error %d\n", GetLastError()); 2542 } 2543 2544 /* ########################### */ 2545 2546 static void test_GetPrinterDriver(void) 2547 { 2548 HANDLE hprn; 2549 BOOL ret; 2550 BYTE *buf; 2551 INT level; 2552 DWORD needed, filled; 2553 2554 if (!default_printer) 2555 { 2556 skip("There is no default printer installed\n"); 2557 return; 2558 } 2559 2560 hprn = 0; 2561 ret = OpenPrinterA(default_printer, &hprn, NULL); 2562 if (!ret) 2563 { 2564 skip("Unable to open the default printer (%s)\n", default_printer); 2565 return; 2566 } 2567 ok(hprn != 0, "wrong hprn %p\n", hprn); 2568 2569 for (level = -1; level <= 7; level++) 2570 { 2571 SetLastError(0xdeadbeef); 2572 needed = (DWORD)-1; 2573 ret = GetPrinterDriverA(hprn, NULL, level, NULL, 0, &needed); 2574 ok(!ret, "level %d: GetPrinterDriver should fail\n", level); 2575 if (level >= 1 && level <= 6) 2576 { 2577 /* Not all levels are supported on all Windows-Versions */ 2578 if(GetLastError() == ERROR_INVALID_LEVEL) continue; 2579 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "wrong error %d\n", GetLastError()); 2580 ok(needed > 0,"not expected needed buffer size %d\n", needed); 2581 } 2582 else 2583 { 2584 /* ERROR_OUTOFMEMORY found on win9x */ 2585 ok( ((GetLastError() == ERROR_INVALID_LEVEL) || 2586 (GetLastError() == ERROR_OUTOFMEMORY)), 2587 "%d: returned %d with %d (expected '0' with: " 2588 "ERROR_INVALID_LEVEL or ERROR_OUTOFMEMORY)\n", 2589 level, ret, GetLastError()); 2590 /* needed is modified in win9x. The modified Value depends on the 2591 default Printer. testing for "needed == (DWORD)-1" will fail */ 2592 continue; 2593 } 2594 2595 /* GetPrinterDriverA returns the same number of bytes as GetPrinterDriverW */ 2596 if (!on_win9x && !ret && pGetPrinterDriverW) 2597 { 2598 DWORD double_needed; 2599 ret = pGetPrinterDriverW(hprn, NULL, level, NULL, 0, &double_needed); 2600 ok(!ret, "level %d: GetPrinterDriver error %d\n", level, GetLastError()); 2601 ok(double_needed == needed, "GetPrinterDriverA returned different size %d than GetPrinterDriverW (%d)\n", needed, double_needed); 2602 } 2603 2604 buf = HeapAlloc(GetProcessHeap(), 0, needed); 2605 2606 SetLastError(0xdeadbeef); 2607 filled = -1; 2608 ret = GetPrinterDriverA(hprn, NULL, level, buf, needed, &filled); 2609 ok(ret, "level %d: GetPrinterDriver error %d\n", level, GetLastError()); 2610 ok(needed == filled, "needed %d != filled %d\n", needed, filled); 2611 2612 if (level == 2) 2613 { 2614 DRIVER_INFO_2A *di_2 = (DRIVER_INFO_2A *)buf; 2615 DWORD calculated = sizeof(*di_2); 2616 HANDLE hf; 2617 2618 /* MSDN is wrong: The Drivers on the win9x-CD's have cVersion=0x0400 2619 NT351: 1, NT4.0+w2k(Kernelmode): 2, w2k-win7(Usermode): 3, win8 and above(Usermode): 4 */ 2620 ok( (di_2->cVersion <= 4) || 2621 (di_2->cVersion == 0x0400), "di_2->cVersion = %d\n", di_2->cVersion); 2622 ok(di_2->pName != NULL, "not expected NULL ptr\n"); 2623 ok(di_2->pEnvironment != NULL, "not expected NULL ptr\n"); 2624 ok(di_2->pDriverPath != NULL, "not expected NULL ptr\n"); 2625 ok(di_2->pDataFile != NULL, "not expected NULL ptr\n"); 2626 ok(di_2->pConfigFile != NULL, "not expected NULL ptr\n"); 2627 2628 trace("cVersion %d\n", di_2->cVersion); 2629 trace("pName %s\n", di_2->pName); 2630 calculated += strlen(di_2->pName) + 1; 2631 trace("pEnvironment %s\n", di_2->pEnvironment); 2632 calculated += strlen(di_2->pEnvironment) + 1; 2633 trace("pDriverPath %s\n", di_2->pDriverPath); 2634 calculated += strlen(di_2->pDriverPath) + 1; 2635 trace("pDataFile %s\n", di_2->pDataFile); 2636 calculated += strlen(di_2->pDataFile) + 1; 2637 trace("pConfigFile %s\n", di_2->pConfigFile); 2638 calculated += strlen(di_2->pConfigFile) + 1; 2639 2640 hf = CreateFileA(di_2->pDriverPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 2641 if(hf != INVALID_HANDLE_VALUE) 2642 CloseHandle(hf); 2643 todo_wine 2644 ok(hf != INVALID_HANDLE_VALUE, "Could not open %s\n", di_2->pDriverPath); 2645 2646 hf = CreateFileA(di_2->pDataFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 2647 if(hf != INVALID_HANDLE_VALUE) 2648 CloseHandle(hf); 2649 ok(hf != INVALID_HANDLE_VALUE, "Could not open %s\n", di_2->pDataFile); 2650 2651 hf = CreateFileA(di_2->pConfigFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 2652 if(hf != INVALID_HANDLE_VALUE) 2653 CloseHandle(hf); 2654 todo_wine 2655 ok(hf != INVALID_HANDLE_VALUE, "Could not open %s\n", di_2->pConfigFile); 2656 2657 /* XP allocates memory for both ANSI and unicode names */ 2658 ok(filled >= calculated,"calculated %d != filled %d\n", calculated, filled); 2659 2660 /* Obscure test - demonstrate that Windows zero fills the buffer, even on failure */ 2661 ret = GetPrinterDriverA(hprn, NULL, level, buf, needed - 2, &filled); 2662 ok(!ret, "level %d: GetPrinterDriver succeeded with less buffer than it should\n", level); 2663 ok(di_2->pDataFile == NULL || 2664 broken(di_2->pDataFile != NULL), /* Win9x/WinMe */ 2665 "Even on failure, GetPrinterDriver clears the buffer to zeros\n"); 2666 } 2667 2668 HeapFree(GetProcessHeap(), 0, buf); 2669 } 2670 2671 SetLastError(0xdeadbeef); 2672 ret = ClosePrinter(hprn); 2673 ok(ret, "ClosePrinter error %d\n", GetLastError()); 2674 } 2675 2676 static void test_DEVMODEA(const DEVMODEA *dm, LONG dmSize, LPCSTR exp_prn_name) 2677 { 2678 /* On NT3.51, some fields in DEVMODEA are empty/zero 2679 (dmDeviceName, dmSpecVersion, dmDriverVersion and dmDriverExtra) 2680 We skip the Tests on this Platform */ 2681 if (dm->dmSpecVersion || dm->dmDriverVersion || dm->dmDriverExtra) { 2682 /* The 0-terminated Printername can be larger (MAX_PATH) than CCHDEVICENAME */ 2683 ok(!strncmp(exp_prn_name, (LPCSTR)dm->dmDeviceName, CCHDEVICENAME -1) || 2684 !strncmp(exp_prn_name, (LPCSTR)dm->dmDeviceName, CCHDEVICENAME -2), /* XP+ */ 2685 "expected '%s', got '%s'\n", exp_prn_name, dm->dmDeviceName); 2686 ok(dm->dmSize + dm->dmDriverExtra == dmSize, 2687 "%u != %d\n", dm->dmSize + dm->dmDriverExtra, dmSize); 2688 } 2689 trace("dmFields %08x\n", dm->dmFields); 2690 } 2691 2692 static void test_DocumentProperties(void) 2693 { 2694 HANDLE hprn; 2695 LONG dm_size, ret; 2696 DEVMODEA *dm; 2697 char empty_str[] = ""; 2698 2699 if (!default_printer) 2700 { 2701 skip("There is no default printer installed\n"); 2702 return; 2703 } 2704 2705 hprn = 0; 2706 ret = OpenPrinterA(default_printer, &hprn, NULL); 2707 if (!ret) 2708 { 2709 skip("Unable to open the default printer (%s)\n", default_printer); 2710 return; 2711 } 2712 ok(hprn != 0, "wrong hprn %p\n", hprn); 2713 2714 dm_size = DocumentPropertiesA(0, hprn, NULL, NULL, NULL, 0); 2715 trace("DEVMODEA required size %d\n", dm_size); 2716 ok(dm_size >= sizeof(DEVMODEA), "unexpected DocumentPropertiesA ret value %d\n", dm_size); 2717 2718 dm = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dm_size); 2719 2720 ret = DocumentPropertiesA(0, hprn, NULL, dm, dm, DM_OUT_BUFFER); 2721 ok(ret == IDOK, "DocumentPropertiesA ret value %d != expected IDOK\n", ret); 2722 2723 ret = DocumentPropertiesA(0, hprn, empty_str, dm, dm, DM_OUT_BUFFER); 2724 ok(ret == IDOK, "DocumentPropertiesA ret value %d != expected IDOK\n", ret); 2725 2726 test_DEVMODEA(dm, dm_size, default_printer); 2727 2728 HeapFree(GetProcessHeap(), 0, dm); 2729 2730 SetLastError(0xdeadbeef); 2731 ret = ClosePrinter(hprn); 2732 ok(ret, "ClosePrinter error %d\n", GetLastError()); 2733 } 2734 2735 static void test_EnumPrinters(void) 2736 { 2737 DWORD neededA, neededW, num; 2738 DWORD ret; 2739 2740 SetLastError(0xdeadbeef); 2741 neededA = -1; 2742 ret = EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &neededA, &num); 2743 if (is_spooler_deactivated(ret, GetLastError())) return; 2744 if (!ret) 2745 { 2746 /* We have 1 or more printers */ 2747 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "gle %d\n", GetLastError()); 2748 ok(neededA > 0, "Expected neededA to show the number of needed bytes\n"); 2749 } 2750 else 2751 { 2752 /* We don't have any printers defined */ 2753 ok(GetLastError() == S_OK, "gle %d\n", GetLastError()); 2754 ok(neededA == 0, "Expected neededA to be zero\n"); 2755 } 2756 ok(num == 0, "num %d\n", num); 2757 2758 SetLastError(0xdeadbeef); 2759 neededW = -1; 2760 ret = EnumPrintersW(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &neededW, &num); 2761 /* EnumPrintersW is not supported on all platforms */ 2762 if (!ret && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) 2763 { 2764 win_skip("EnumPrintersW is not implemented\n"); 2765 return; 2766 } 2767 2768 if (!ret) 2769 { 2770 /* We have 1 or more printers */ 2771 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "gle %d\n", GetLastError()); 2772 ok(neededW > 0, "Expected neededW to show the number of needed bytes\n"); 2773 } 2774 else 2775 { 2776 /* We don't have any printers defined */ 2777 ok(GetLastError() == S_OK, "gle %d\n", GetLastError()); 2778 ok(neededW == 0, "Expected neededW to be zero\n"); 2779 } 2780 ok(num == 0, "num %d\n", num); 2781 2782 /* Outlook2003 relies on the buffer size returned by EnumPrintersA being big enough 2783 to hold the buffer returned by EnumPrintersW */ 2784 ok(neededA == neededW, "neededA %d neededW %d\n", neededA, neededW); 2785 } 2786 2787 static void test_DeviceCapabilities(void) 2788 { 2789 HANDLE hComdlg32; 2790 BOOL (WINAPI *pPrintDlgA)(PRINTDLGA *); 2791 PRINTDLGA prn_dlg; 2792 DEVMODEA *dm; 2793 DEVNAMES *dn; 2794 const char *driver, *device, *port; 2795 WORD *papers; 2796 POINT *paper_size; 2797 POINTS ext; 2798 struct 2799 { 2800 char name[64]; 2801 } *paper_name; 2802 INT n_papers, n_paper_size, n_paper_names, n_copies, ret; 2803 DWORD fields; 2804 2805 hComdlg32 = LoadLibraryA("comdlg32.dll"); 2806 assert(hComdlg32); 2807 pPrintDlgA = (void *)GetProcAddress(hComdlg32, "PrintDlgA"); 2808 assert(pPrintDlgA); 2809 2810 memset(&prn_dlg, 0, sizeof(prn_dlg)); 2811 prn_dlg.lStructSize = sizeof(prn_dlg); 2812 prn_dlg.Flags = PD_RETURNDEFAULT; 2813 ret = pPrintDlgA(&prn_dlg); 2814 FreeLibrary(hComdlg32); 2815 if (!ret) 2816 { 2817 skip("PrintDlg returned no default printer\n"); 2818 return; 2819 } 2820 ok(prn_dlg.hDevMode != 0, "PrintDlg returned hDevMode == NULL\n"); 2821 ok(prn_dlg.hDevNames != 0, "PrintDlg returned hDevNames == NULL\n"); 2822 2823 dm = GlobalLock(prn_dlg.hDevMode); 2824 ok(dm != NULL, "GlobalLock(prn_dlg.hDevMode) failed\n"); 2825 trace("dmDeviceName \"%s\"\n", dm->dmDeviceName); 2826 2827 dn = GlobalLock(prn_dlg.hDevNames); 2828 ok(dn != NULL, "GlobalLock(prn_dlg.hDevNames) failed\n"); 2829 ok(dn->wDriverOffset, "expected not 0 wDriverOffset\n"); 2830 ok(dn->wDeviceOffset, "expected not 0 wDeviceOffset\n"); 2831 ok(dn->wOutputOffset, "expected not 0 wOutputOffset\n"); 2832 ok(dn->wDefault == DN_DEFAULTPRN, "expected DN_DEFAULTPRN got %x\n", dn->wDefault); 2833 driver = (const char *)dn + dn->wDriverOffset; 2834 device = (const char *)dn + dn->wDeviceOffset; 2835 port = (const char *)dn + dn->wOutputOffset; 2836 trace("driver \"%s\" device \"%s\" port \"%s\"\n", driver, device, port); 2837 2838 test_DEVMODEA(dm, dm->dmSize + dm->dmDriverExtra, device); 2839 2840 n_papers = DeviceCapabilitiesA(device, port, DC_PAPERS, NULL, NULL); 2841 ok(n_papers > 0, "DeviceCapabilitiesA DC_PAPERS failed\n"); 2842 papers = HeapAlloc(GetProcessHeap(), 0, sizeof(*papers) * n_papers); 2843 ret = DeviceCapabilitiesA(device, port, DC_PAPERS, (LPSTR)papers, NULL); 2844 ok(ret == n_papers, "expected %d, got %d\n", n_papers, ret); 2845 #ifdef VERBOSE 2846 for (ret = 0; ret < n_papers; ret++) 2847 trace("papers[%d] = %d\n", ret, papers[ret]); 2848 #endif 2849 HeapFree(GetProcessHeap(), 0, papers); 2850 2851 n_paper_size = DeviceCapabilitiesA(device, port, DC_PAPERSIZE, NULL, NULL); 2852 ok(n_paper_size > 0, "DeviceCapabilitiesA DC_PAPERSIZE failed\n"); 2853 ok(n_paper_size == n_papers, "n_paper_size %d != n_papers %d\n", n_paper_size, n_papers); 2854 paper_size = HeapAlloc(GetProcessHeap(), 0, sizeof(*paper_size) * n_paper_size); 2855 ret = DeviceCapabilitiesA(device, port, DC_PAPERSIZE, (LPSTR)paper_size, NULL); 2856 ok(ret == n_paper_size, "expected %d, got %d\n", n_paper_size, ret); 2857 #ifdef VERBOSE 2858 for (ret = 0; ret < n_paper_size; ret++) 2859 trace("paper_size[%d] = %d x %d\n", ret, paper_size[ret].x, paper_size[ret].y); 2860 #endif 2861 HeapFree(GetProcessHeap(), 0, paper_size); 2862 2863 n_paper_names = DeviceCapabilitiesA(device, port, DC_PAPERNAMES, NULL, NULL); 2864 ok(n_paper_names > 0, "DeviceCapabilitiesA DC_PAPERNAMES failed\n"); 2865 ok(n_paper_names == n_papers, "n_paper_names %d != n_papers %d\n", n_paper_names, n_papers); 2866 paper_name = HeapAlloc(GetProcessHeap(), 0, sizeof(*paper_name) * n_paper_names); 2867 ret = DeviceCapabilitiesA(device, port, DC_PAPERNAMES, (LPSTR)paper_name, NULL); 2868 ok(ret == n_paper_names, "expected %d, got %d\n", n_paper_names, ret); 2869 #ifdef VERBOSE 2870 for (ret = 0; ret < n_paper_names; ret++) 2871 trace("paper_name[%u] = %s\n", ret, paper_name[ret].name); 2872 #endif 2873 HeapFree(GetProcessHeap(), 0, paper_name); 2874 2875 n_copies = DeviceCapabilitiesA(device, port, DC_COPIES, NULL, dm); 2876 ok(n_copies > 0, "DeviceCapabilitiesA DC_COPIES failed\n"); 2877 trace("n_copies = %d\n", n_copies); 2878 2879 /* these capabilities are not available on all printer drivers */ 2880 if (0) 2881 { 2882 ret = DeviceCapabilitiesA(device, port, DC_MAXEXTENT, NULL, NULL); 2883 ok(ret != -1, "DeviceCapabilitiesA DC_MAXEXTENT failed\n"); 2884 ext = MAKEPOINTS(ret); 2885 trace("max ext = %d x %d\n", ext.x, ext.y); 2886 2887 ret = DeviceCapabilitiesA(device, port, DC_MINEXTENT, NULL, NULL); 2888 ok(ret != -1, "DeviceCapabilitiesA DC_MINEXTENT failed\n"); 2889 ext = MAKEPOINTS(ret); 2890 trace("min ext = %d x %d\n", ext.x, ext.y); 2891 } 2892 2893 fields = DeviceCapabilitiesA(device, port, DC_FIELDS, NULL, NULL); 2894 ok(fields != (DWORD)-1, "DeviceCapabilitiesA DC_FIELDS failed\n"); 2895 ok(fields == (dm->dmFields | DM_FORMNAME) || 2896 fields == ((dm->dmFields | DM_FORMNAME | DM_PAPERSIZE) & ~(DM_PAPERLENGTH|DM_PAPERWIDTH)) || 2897 broken(fields == dm->dmFields), /* Win9x/WinMe */ 2898 "fields %x, dm->dmFields %x\n", fields, dm->dmFields); 2899 2900 GlobalUnlock(prn_dlg.hDevMode); 2901 GlobalFree(prn_dlg.hDevMode); 2902 GlobalUnlock(prn_dlg.hDevNames); 2903 GlobalFree(prn_dlg.hDevNames); 2904 } 2905 2906 static void test_OpenPrinter_defaults(void) 2907 { 2908 HANDLE printer; 2909 BOOL ret; 2910 DWORD needed; 2911 short default_size; 2912 ADDJOB_INFO_1A *add_job; 2913 JOB_INFO_2A *job_info; 2914 DEVMODEA my_dm; 2915 PRINTER_DEFAULTSA prn_def; 2916 PRINTER_INFO_2A *pi; 2917 2918 if (!default_printer) 2919 { 2920 skip("There is no default printer installed\n"); 2921 return; 2922 } 2923 2924 /* Printer opened with NULL defaults. Retrieve default paper size 2925 and confirm that jobs have this size. */ 2926 2927 ret = OpenPrinterA( default_printer, &printer, NULL ); 2928 if (!ret) 2929 { 2930 skip("Unable to open the default printer (%s)\n", default_printer); 2931 return; 2932 } 2933 2934 ret = GetPrinterA( printer, 2, NULL, 0, &needed ); 2935 ok( !ret, "got %d\n", ret ); 2936 pi = HeapAlloc( GetProcessHeap(), 0, needed ); 2937 ret = GetPrinterA( printer, 2, (BYTE *)pi, needed, &needed ); 2938 ok( ret, "GetPrinterA() failed le=%d\n", GetLastError() ); 2939 default_size = pi->pDevMode->u1.s1.dmPaperSize; 2940 HeapFree( GetProcessHeap(), 0, pi ); 2941 2942 needed = 0; 2943 SetLastError( 0xdeadbeef ); 2944 ret = AddJobA( printer, 1, NULL, 0, &needed ); 2945 ok( !ret, "got %d\n", ret ); 2946 if (GetLastError() == ERROR_NOT_SUPPORTED) /* win8 */ 2947 { 2948 win_skip( "AddJob is not supported on this platform\n" ); 2949 ClosePrinter( printer ); 2950 return; 2951 } 2952 ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError() ); 2953 ok( needed > sizeof(ADDJOB_INFO_1A), "AddJob needs %u bytes\n", needed); 2954 add_job = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, needed ); 2955 ret = AddJobA( printer, 1, (BYTE *)add_job, needed, &needed ); 2956 ok( ret, "AddJobA() failed le=%d\n", GetLastError() ); 2957 2958 ret = GetJobA( printer, add_job->JobId, 2, NULL, 0, &needed ); 2959 ok( !ret, "got %d\n", ret ); 2960 job_info = HeapAlloc( GetProcessHeap(), 0, needed ); 2961 ret = GetJobA( printer, add_job->JobId, 2, (BYTE *)job_info, needed, &needed ); 2962 ok( ret, "GetJobA() failed le=%d\n", GetLastError() ); 2963 2964 todo_wine 2965 ok( job_info->pDevMode != NULL, "got NULL DEVMODEA\n"); 2966 if (job_info->pDevMode) 2967 ok( job_info->pDevMode->u1.s1.dmPaperSize == default_size, "got %d default %d\n", 2968 job_info->pDevMode->u1.s1.dmPaperSize, default_size ); 2969 2970 HeapFree( GetProcessHeap(), 0, job_info ); 2971 ScheduleJob( printer, add_job->JobId ); /* remove the empty job */ 2972 HeapFree( GetProcessHeap(), 0, add_job ); 2973 ClosePrinter( printer ); 2974 2975 /* Printer opened with something other than the default paper size. */ 2976 2977 memset( &my_dm, 0, sizeof(my_dm) ); 2978 my_dm.dmSize = sizeof(my_dm); 2979 my_dm.dmFields = DM_PAPERSIZE; 2980 my_dm.u1.s1.dmPaperSize = (default_size == DMPAPER_A4) ? DMPAPER_LETTER : DMPAPER_A4; 2981 2982 prn_def.pDatatype = NULL; 2983 prn_def.pDevMode = &my_dm; 2984 prn_def.DesiredAccess = PRINTER_ACCESS_USE; 2985 2986 ret = OpenPrinterA( default_printer, &printer, &prn_def ); 2987 ok( ret, "OpenPrinterA() failed le=%d\n", GetLastError() ); 2988 2989 /* GetPrinter stills returns default size */ 2990 ret = GetPrinterA( printer, 2, NULL, 0, &needed ); 2991 ok( !ret, "got %d\n", ret ); 2992 pi = HeapAlloc( GetProcessHeap(), 0, needed ); 2993 ret = GetPrinterA( printer, 2, (BYTE *)pi, needed, &needed ); 2994 ok( ret, "GetPrinterA() failed le=%d\n", GetLastError() ); 2995 ok( pi->pDevMode->u1.s1.dmPaperSize == default_size, "got %d default %d\n", 2996 pi->pDevMode->u1.s1.dmPaperSize, default_size ); 2997 2998 HeapFree( GetProcessHeap(), 0, pi ); 2999 3000 /* However the GetJobA has the new size */ 3001 ret = AddJobA( printer, 1, NULL, 0, &needed ); 3002 ok( !ret, "got %d\n", ret ); 3003 add_job = HeapAlloc( GetProcessHeap(), 0, needed ); 3004 ret = AddJobA( printer, 1, (BYTE *)add_job, needed, &needed ); 3005 ok( ret, "AddJobA() failed le=%d\n", GetLastError() ); 3006 3007 ret = GetJobA( printer, add_job->JobId, 2, NULL, 0, &needed ); 3008 ok( !ret, "got %d\n", ret ); 3009 job_info = HeapAlloc( GetProcessHeap(), 0, needed ); 3010 ret = GetJobA( printer, add_job->JobId, 2, (BYTE *)job_info, needed, &needed ); 3011 ok( ret, "GetJobA() failed le=%d\n", GetLastError() ); 3012 3013 ok( job_info->pDevMode->dmFields == DM_PAPERSIZE, "got %08x\n", 3014 job_info->pDevMode->dmFields ); 3015 ok( job_info->pDevMode->u1.s1.dmPaperSize == my_dm.u1.s1.dmPaperSize, 3016 "got %d new size %d\n", 3017 job_info->pDevMode->u1.s1.dmPaperSize, my_dm.u1.s1.dmPaperSize ); 3018 3019 HeapFree( GetProcessHeap(), 0, job_info ); 3020 ScheduleJob( printer, add_job->JobId ); /* remove the empty job */ 3021 HeapFree( GetProcessHeap(), 0, add_job ); 3022 ClosePrinter( printer ); 3023 } 3024 3025 static void test_IsValidDevmodeW(void) 3026 { 3027 static const struct 3028 { 3029 DWORD dmFields; 3030 WORD dmSize; 3031 BOOL ret; 3032 } test[] = 3033 { 3034 { 0, FIELD_OFFSET(DEVMODEW, dmFields) + 0, FALSE }, 3035 { 0, FIELD_OFFSET(DEVMODEW, dmFields) + 1, FALSE }, 3036 { 0, FIELD_OFFSET(DEVMODEW, dmFields) + 2, FALSE }, 3037 { 0, FIELD_OFFSET(DEVMODEW, dmFields) + 3, FALSE }, 3038 { 0, FIELD_OFFSET(DEVMODEW, dmFields) + 4, TRUE }, 3039 3040 { DM_ORIENTATION, FIELD_OFFSET(DEVMODEW, u1.s1.dmOrientation) + 0, FALSE }, 3041 { DM_ORIENTATION, FIELD_OFFSET(DEVMODEW, u1.s1.dmOrientation) + 1, FALSE }, 3042 { DM_ORIENTATION, FIELD_OFFSET(DEVMODEW, u1.s1.dmOrientation) + 2, TRUE }, 3043 3044 { DM_NUP, FIELD_OFFSET(DEVMODEW, u2.dmNup) + 0, FALSE }, 3045 { DM_NUP, FIELD_OFFSET(DEVMODEW, u2.dmNup) + 1, FALSE }, 3046 { DM_NUP, FIELD_OFFSET(DEVMODEW, u2.dmNup) + 2, FALSE }, 3047 { DM_NUP, FIELD_OFFSET(DEVMODEW, u2.dmNup) + 3, FALSE }, 3048 { DM_NUP, FIELD_OFFSET(DEVMODEW, u2.dmNup) + 4, TRUE }, 3049 3050 }; 3051 DEVMODEW dm; 3052 int i; 3053 BOOL ret; 3054 3055 ret = IsValidDevmodeW(NULL, 0); 3056 ok(!ret, "got %d\n", ret); 3057 3058 ret = IsValidDevmodeW(NULL, sizeof(DEVMODEW)); 3059 ok(!ret, "got %d\n", ret); 3060 3061 memset(&dm, 0, sizeof(dm)); 3062 3063 for (i = 0; i < ARRAY_SIZE(test); i++) 3064 { 3065 dm.dmSize = test[i].dmSize; 3066 dm.dmFields = test[i].dmFields; 3067 ret = IsValidDevmodeW(&dm, dm.dmSize); 3068 ok(ret == test[i].ret, "%d: got %d\n", i, ret); 3069 } 3070 } 3071 3072 START_TEST(info) 3073 { 3074 hwinspool = LoadLibraryA("winspool.drv"); 3075 pAddPortExA = (void *) GetProcAddress(hwinspool, "AddPortExA"); 3076 pEnumPrinterDriversW = (void *) GetProcAddress(hwinspool, "EnumPrinterDriversW"); 3077 pGetDefaultPrinterA = (void *) GetProcAddress(hwinspool, "GetDefaultPrinterA"); 3078 pGetPrinterDataExA = (void *) GetProcAddress(hwinspool, "GetPrinterDataExA"); 3079 pGetPrinterDriverW = (void *) GetProcAddress(hwinspool, "GetPrinterDriverW"); 3080 pGetPrinterW = (void *) GetProcAddress(hwinspool, "GetPrinterW"); 3081 pSetDefaultPrinterA = (void *) GetProcAddress(hwinspool, "SetDefaultPrinterA"); 3082 pXcvDataW = (void *) GetProcAddress(hwinspool, "XcvDataW"); 3083 3084 on_win9x = check_win9x(); 3085 if (on_win9x) 3086 win_skip("Several W-functions are not available on Win9x/WinMe\n"); 3087 3088 find_default_printer(); 3089 find_local_server(); 3090 find_tempfile(); 3091 3092 test_AddMonitor(); 3093 test_AddPort(); 3094 test_AddPortEx(); 3095 test_ConfigurePort(); 3096 test_ClosePrinter(); 3097 test_DeleteMonitor(); 3098 test_DeletePort(); 3099 test_DeviceCapabilities(); 3100 test_DocumentProperties(); 3101 test_EnumForms(NULL); 3102 if (default_printer) test_EnumForms(default_printer); 3103 test_EnumMonitors(); 3104 3105 if (!winetest_interactive) 3106 skip("ROSTESTS-211: Skipping test_EnumPorts().\n"); 3107 else 3108 test_EnumPorts(); 3109 3110 test_EnumPrinterDrivers(); 3111 test_EnumPrinters(); 3112 3113 if (!winetest_interactive) 3114 skip("ROSTESTS-211: Skipping test_EnumPrintProcessors().\n"); 3115 else 3116 test_EnumPrintProcessors(); 3117 3118 test_GetDefaultPrinter(); 3119 test_GetPrinterDriverDirectory(); 3120 test_GetPrintProcessorDirectory(); 3121 test_IsValidDevmodeW(); 3122 test_OpenPrinter(); 3123 test_OpenPrinter_defaults(); 3124 test_GetPrinter(); 3125 test_GetPrinterData(); 3126 test_GetPrinterDataEx(); 3127 test_GetPrinterDriver(); 3128 test_SetDefaultPrinter(); 3129 test_XcvDataW_MonitorUI(); 3130 test_XcvDataW_PortIsValid(); 3131 3132 /* Cleanup our temporary file */ 3133 DeleteFileA(tempfileA); 3134 } 3135