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