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