1 /* 2 * PROJECT: ReactOS Spooler API 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: Functions related to Printer Drivers 5 * COPYRIGHT: Copyright 2015-2017 Colin Finck (colin@reactos.org) 6 */ 7 8 #include "precomp.h" 9 #include <marshalling/printerdrivers.h> 10 11 extern const WCHAR wszCurrentEnvironment[]; 12 13 static int multi_sz_lenA(const char *str) 14 { 15 const char *ptr = str; 16 if(!str) return 0; 17 do 18 { 19 ptr += lstrlenA(ptr) + 1; 20 } while(*ptr); 21 22 return ptr - str + 1; 23 } 24 25 static int multi_sz_lenW(const WCHAR *str) 26 { 27 const WCHAR *ptr = str; 28 if (!str) return 0; 29 do 30 { 31 ptr += lstrlenW(ptr) + 1; 32 } while (*ptr); 33 34 return (ptr - str + 1); 35 } 36 37 BOOL WINAPI 38 AddPrinterDriverA(PSTR pName, DWORD Level, PBYTE pDriverInfo) 39 { 40 TRACE("AddPrinterDriverA(%s, %lu, %p)\n", pName, Level, pDriverInfo); 41 return AddPrinterDriverExA(pName, Level, pDriverInfo, APD_COPY_NEW_FILES); 42 } 43 44 BOOL WINAPI 45 AddPrinterDriverExA(PSTR pName, DWORD Level, PBYTE pDriverInfo, DWORD dwFileCopyFlags) 46 { 47 PDRIVER_INFO_8A pdiA; 48 DRIVER_INFO_8W diW; 49 LPWSTR nameW = NULL; 50 DWORD lenA; 51 DWORD len; 52 BOOL res = FALSE; 53 54 TRACE("AddPrinterDriverExA(%s, %d, %p, 0x%x)\n", debugstr_a(pName), Level, pDriverInfo, dwFileCopyFlags); 55 56 pdiA = (DRIVER_INFO_8A *) pDriverInfo; 57 ZeroMemory(&diW, sizeof(diW)); 58 59 if (Level < 2 || Level == 5 || Level == 7 || Level > 8) 60 { 61 SetLastError(ERROR_INVALID_LEVEL); 62 return FALSE; 63 } 64 65 if (pdiA == NULL) 66 { 67 SetLastError(ERROR_INVALID_PARAMETER); 68 return FALSE; 69 } 70 71 /* convert servername to unicode */ 72 if (pName) 73 { 74 len = MultiByteToWideChar(CP_ACP, 0, pName, -1, NULL, 0); 75 nameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 76 MultiByteToWideChar(CP_ACP, 0, pName, -1, nameW, len); 77 } 78 79 /* common fields */ 80 diW.cVersion = pdiA->cVersion; 81 82 if (pdiA->pName) 83 { 84 len = MultiByteToWideChar(CP_ACP, 0, pdiA->pName, -1, NULL, 0); 85 diW.pName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 86 MultiByteToWideChar(CP_ACP, 0, pdiA->pName, -1, diW.pName, len); 87 } 88 89 if (pdiA->pEnvironment) 90 { 91 len = MultiByteToWideChar(CP_ACP, 0, pdiA->pEnvironment, -1, NULL, 0); 92 diW.pEnvironment = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 93 MultiByteToWideChar(CP_ACP, 0, pdiA->pEnvironment, -1, diW.pEnvironment, len); 94 } 95 96 if (pdiA->pDriverPath) 97 { 98 len = MultiByteToWideChar(CP_ACP, 0, pdiA->pDriverPath, -1, NULL, 0); 99 diW.pDriverPath = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 100 MultiByteToWideChar(CP_ACP, 0, pdiA->pDriverPath, -1, diW.pDriverPath, len); 101 } 102 103 if (pdiA->pDataFile) 104 { 105 len = MultiByteToWideChar(CP_ACP, 0, pdiA->pDataFile, -1, NULL, 0); 106 diW.pDataFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 107 MultiByteToWideChar(CP_ACP, 0, pdiA->pDataFile, -1, diW.pDataFile, len); 108 } 109 110 if (pdiA->pConfigFile) 111 { 112 len = MultiByteToWideChar(CP_ACP, 0, pdiA->pConfigFile, -1, NULL, 0); 113 diW.pConfigFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 114 MultiByteToWideChar(CP_ACP, 0, pdiA->pConfigFile, -1, diW.pConfigFile, len); 115 } 116 117 if ((Level > 2) && pdiA->pHelpFile) 118 { 119 len = MultiByteToWideChar(CP_ACP, 0, pdiA->pHelpFile, -1, NULL, 0); 120 diW.pHelpFile = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 121 MultiByteToWideChar(CP_ACP, 0, pdiA->pHelpFile, -1, diW.pHelpFile, len); 122 } 123 124 if ((Level > 2) && pdiA->pDependentFiles) 125 { 126 lenA = multi_sz_lenA(pdiA->pDependentFiles); 127 len = MultiByteToWideChar(CP_ACP, 0, pdiA->pDependentFiles, lenA, NULL, 0); 128 diW.pDependentFiles = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 129 MultiByteToWideChar(CP_ACP, 0, pdiA->pDependentFiles, lenA, diW.pDependentFiles, len); 130 } 131 132 if ((Level > 2) && pdiA->pMonitorName) 133 { 134 len = MultiByteToWideChar(CP_ACP, 0, pdiA->pMonitorName, -1, NULL, 0); 135 diW.pMonitorName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 136 MultiByteToWideChar(CP_ACP, 0, pdiA->pMonitorName, -1, diW.pMonitorName, len); 137 } 138 139 if ((Level > 2) && pdiA->pDefaultDataType) 140 { 141 len = MultiByteToWideChar(CP_ACP, 0, pdiA->pDefaultDataType, -1, NULL, 0); 142 diW.pDefaultDataType = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 143 MultiByteToWideChar(CP_ACP, 0, pdiA->pDefaultDataType, -1, diW.pDefaultDataType, len); 144 } 145 146 if ((Level > 3) && pdiA->pszzPreviousNames) 147 { 148 lenA = multi_sz_lenA(pdiA->pszzPreviousNames); 149 len = MultiByteToWideChar(CP_ACP, 0, pdiA->pszzPreviousNames, lenA, NULL, 0); 150 diW.pszzPreviousNames = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 151 MultiByteToWideChar(CP_ACP, 0, pdiA->pszzPreviousNames, lenA, diW.pszzPreviousNames, len); 152 } 153 154 if (Level > 5) 155 { 156 diW.ftDriverDate = pdiA->ftDriverDate; 157 diW.dwlDriverVersion = pdiA->dwlDriverVersion; 158 } 159 160 if ((Level > 5) && pdiA->pszMfgName) 161 { 162 len = MultiByteToWideChar(CP_ACP, 0, pdiA->pszMfgName, -1, NULL, 0); 163 diW.pszMfgName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 164 MultiByteToWideChar(CP_ACP, 0, pdiA->pszMfgName, -1, diW.pszMfgName, len); 165 } 166 167 if ((Level > 5) && pdiA->pszOEMUrl) 168 { 169 len = MultiByteToWideChar(CP_ACP, 0, pdiA->pszOEMUrl, -1, NULL, 0); 170 diW.pszOEMUrl = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 171 MultiByteToWideChar(CP_ACP, 0, pdiA->pszOEMUrl, -1, diW.pszOEMUrl, len); 172 } 173 174 if ((Level > 5) && pdiA->pszHardwareID) 175 { 176 len = MultiByteToWideChar(CP_ACP, 0, pdiA->pszHardwareID, -1, NULL, 0); 177 diW.pszHardwareID = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 178 MultiByteToWideChar(CP_ACP, 0, pdiA->pszHardwareID, -1, diW.pszHardwareID, len); 179 } 180 181 if ((Level > 5) && pdiA->pszProvider) 182 { 183 len = MultiByteToWideChar(CP_ACP, 0, pdiA->pszProvider, -1, NULL, 0); 184 diW.pszProvider = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 185 MultiByteToWideChar(CP_ACP, 0, pdiA->pszProvider, -1, diW.pszProvider, len); 186 } 187 188 if ((Level > 7) && pdiA->pszPrintProcessor) 189 { 190 len = MultiByteToWideChar(CP_ACP, 0, pdiA->pszPrintProcessor, -1, NULL, 0); 191 diW.pszPrintProcessor = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 192 MultiByteToWideChar(CP_ACP, 0, pdiA->pszPrintProcessor, -1, diW.pszPrintProcessor, len); 193 } 194 195 if ((Level > 7) && pdiA->pszVendorSetup) 196 { 197 len = MultiByteToWideChar(CP_ACP, 0, pdiA->pszVendorSetup, -1, NULL, 0); 198 diW.pszVendorSetup = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 199 MultiByteToWideChar(CP_ACP, 0, pdiA->pszVendorSetup, -1, diW.pszVendorSetup, len); 200 } 201 202 if ((Level > 7) && pdiA->pszzColorProfiles) 203 { 204 lenA = multi_sz_lenA(pdiA->pszzColorProfiles); 205 len = MultiByteToWideChar(CP_ACP, 0, pdiA->pszzColorProfiles, lenA, NULL, 0); 206 diW.pszzColorProfiles = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 207 MultiByteToWideChar(CP_ACP, 0, pdiA->pszzColorProfiles, lenA, diW.pszzColorProfiles, len); 208 } 209 210 if ((Level > 7) && pdiA->pszInfPath) 211 { 212 len = MultiByteToWideChar(CP_ACP, 0, pdiA->pszInfPath, -1, NULL, 0); 213 diW.pszInfPath = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 214 MultiByteToWideChar(CP_ACP, 0, pdiA->pszInfPath, -1, diW.pszInfPath, len); 215 } 216 217 if ((Level > 7) && pdiA->pszzCoreDriverDependencies) 218 { 219 lenA = multi_sz_lenA(pdiA->pszzCoreDriverDependencies); 220 len = MultiByteToWideChar(CP_ACP, 0, pdiA->pszzCoreDriverDependencies, lenA, NULL, 0); 221 diW.pszzCoreDriverDependencies = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 222 MultiByteToWideChar(CP_ACP, 0, pdiA->pszzCoreDriverDependencies, lenA, diW.pszzCoreDriverDependencies, len); 223 } 224 225 if (Level > 7) 226 { 227 diW.dwPrinterDriverAttributes = pdiA->dwPrinterDriverAttributes; 228 diW.ftMinInboxDriverVerDate = pdiA->ftMinInboxDriverVerDate; 229 diW.dwlMinInboxDriverVerVersion = pdiA->dwlMinInboxDriverVerVersion; 230 } 231 232 res = AddPrinterDriverExW(nameW, Level, (LPBYTE) &diW, dwFileCopyFlags); 233 234 TRACE("got %u with %u\n", res, GetLastError()); 235 if (nameW) HeapFree(GetProcessHeap(), 0, nameW); 236 if (diW.pName) HeapFree(GetProcessHeap(), 0, diW.pName); 237 if (diW.pEnvironment) HeapFree(GetProcessHeap(), 0, diW.pEnvironment); 238 if (diW.pDriverPath) HeapFree(GetProcessHeap(), 0, diW.pDriverPath); 239 if (diW.pDataFile) HeapFree(GetProcessHeap(), 0, diW.pDataFile); 240 if (diW.pConfigFile) HeapFree(GetProcessHeap(), 0, diW.pConfigFile); 241 if (diW.pHelpFile) HeapFree(GetProcessHeap(), 0, diW.pHelpFile); 242 if (diW.pDependentFiles) HeapFree(GetProcessHeap(), 0, diW.pDependentFiles); 243 if (diW.pMonitorName) HeapFree(GetProcessHeap(), 0, diW.pMonitorName); 244 if (diW.pDefaultDataType) HeapFree(GetProcessHeap(), 0, diW.pDefaultDataType); 245 if (diW.pszzPreviousNames) HeapFree(GetProcessHeap(), 0, diW.pszzPreviousNames); 246 if (diW.pszMfgName) HeapFree(GetProcessHeap(), 0, diW.pszMfgName); 247 if (diW.pszOEMUrl) HeapFree(GetProcessHeap(), 0, diW.pszOEMUrl); 248 if (diW.pszHardwareID) HeapFree(GetProcessHeap(), 0, diW.pszHardwareID); 249 if (diW.pszProvider) HeapFree(GetProcessHeap(), 0, diW.pszProvider); 250 if (diW.pszPrintProcessor) HeapFree(GetProcessHeap(), 0, diW.pszPrintProcessor); 251 if (diW.pszVendorSetup) HeapFree(GetProcessHeap(), 0, diW.pszVendorSetup); 252 if (diW.pszzColorProfiles) HeapFree(GetProcessHeap(), 0, diW.pszzColorProfiles); 253 if (diW.pszInfPath) HeapFree(GetProcessHeap(), 0, diW.pszInfPath); 254 if (diW.pszzCoreDriverDependencies) HeapFree(GetProcessHeap(), 0, diW.pszzCoreDriverDependencies); 255 256 TRACE("=> %u with %u\n", res, GetLastError()); 257 return res; 258 } 259 260 BOOL WINAPI 261 AddPrinterDriverExW(PWSTR pName, DWORD Level, PBYTE pDriverInfo, DWORD dwFileCopyFlags) 262 { 263 DWORD dwErrorCode = ERROR_SUCCESS; 264 WINSPOOL_DRIVER_INFO_8 * pdi = NULL; 265 WINSPOOL_DRIVER_CONTAINER pDriverContainer; 266 267 TRACE("AddPrinterDriverExW(%S, %lu, %p, %lu)\n", pName, Level, pDriverInfo, dwFileCopyFlags); 268 269 pDriverContainer.Level = Level; 270 271 switch (Level) 272 { 273 case 8: 274 { 275 PDRIVER_INFO_8W pdi8w = (PDRIVER_INFO_8W)pDriverInfo; 276 pdi = HeapAlloc(hProcessHeap, 0, sizeof(WINSPOOL_DRIVER_INFO_8)); 277 278 pdi->pPrintProcessor = pdi8w->pszPrintProcessor; 279 pdi->pVendorSetup = pdi8w->pszVendorSetup; 280 281 pdi->pszzColorProfiles = pdi8w->pszzColorProfiles; 282 pdi->cchColorProfiles = 0; 283 if ( pdi8w->pszzColorProfiles && *pdi8w->pszzColorProfiles ) 284 { 285 pdi->cchColorProfiles = multi_sz_lenW( pdi8w->pszzColorProfiles ); 286 } 287 288 pdi->pInfPath = pdi8w->pszInfPath; 289 290 pdi->pszzCoreDriverDependencies = pdi8w->pszzCoreDriverDependencies; 291 pdi->cchCoreDependencies = 0; 292 if ( pdi8w->pszzCoreDriverDependencies && *pdi8w->pszzCoreDriverDependencies ) 293 { 294 pdi->cchCoreDependencies = multi_sz_lenW( pdi8w->pszzCoreDriverDependencies ); 295 } 296 297 pdi->ftMinInboxDriverVerDate = pdi8w->ftMinInboxDriverVerDate; 298 pdi->dwlMinInboxDriverVerVersion = pdi8w->dwlMinInboxDriverVerVersion; 299 } 300 case 6: 301 { 302 PDRIVER_INFO_6W pdi6w = (PDRIVER_INFO_6W)pDriverInfo; 303 if ( pdi == NULL ) pdi = HeapAlloc(hProcessHeap, 0, sizeof(WINSPOOL_DRIVER_INFO_6)); 304 305 pdi->pMfgName = pdi6w->pszMfgName; 306 pdi->pOEMUrl = pdi6w->pszOEMUrl; 307 pdi->pHardwareID = pdi6w->pszHardwareID; 308 pdi->pProvider = pdi6w->pszProvider; 309 pdi->ftDriverDate = pdi6w->ftDriverDate; 310 pdi->dwlDriverVersion = pdi6w->dwlDriverVersion; 311 } 312 case 4: 313 { 314 PDRIVER_INFO_4W pdi4w = (PDRIVER_INFO_4W)pDriverInfo; 315 if ( pdi == NULL ) pdi = HeapAlloc(hProcessHeap, 0, sizeof(WINSPOOL_DRIVER_INFO_4)); 316 317 pdi->pszzPreviousNames = pdi4w->pszzPreviousNames; 318 pdi->cchPreviousNames = 0; 319 if ( pdi4w->pDependentFiles && *pdi4w->pDependentFiles ) 320 { 321 pdi->cchPreviousNames = multi_sz_lenW( pdi4w->pDependentFiles ); 322 } 323 } 324 case 3: 325 { 326 PDRIVER_INFO_3W pdi3w = (PDRIVER_INFO_3W)pDriverInfo; 327 if ( pdi == NULL ) pdi = HeapAlloc(hProcessHeap, 0, sizeof(WINSPOOL_DRIVER_INFO_3)); 328 329 pdi->pHelpFile = pdi3w->pHelpFile; 330 pdi->pDependentFiles = pdi3w->pDependentFiles; 331 pdi->pMonitorName = pdi3w->pMonitorName; 332 pdi->pDefaultDataType = pdi3w->pDefaultDataType; 333 334 pdi->pDependentFiles = pdi3w->pDependentFiles; 335 pdi->cchDependentFiles = 0; 336 if ( pdi3w->pDependentFiles && *pdi3w->pDependentFiles ) 337 { 338 pdi->cchDependentFiles = multi_sz_lenW( pdi3w->pDependentFiles ); 339 } 340 } 341 case 2: 342 { 343 PDRIVER_INFO_2W pdi2w = (PDRIVER_INFO_2W)pDriverInfo; 344 if ( pdi == NULL ) pdi = HeapAlloc(hProcessHeap, 0, sizeof(WINSPOOL_DRIVER_INFO_2)); 345 346 pdi->pName = pdi2w->pName; 347 348 pdi->pEnvironment = pdi2w->pEnvironment; 349 if ( !pdi2w->pEnvironment || !*pdi2w->pEnvironment ) 350 { 351 pdi2w->pEnvironment = (PWSTR)wszCurrentEnvironment; 352 } 353 354 pdi->pDriverPath = pdi2w->pDriverPath; 355 pdi->pDataFile = pdi2w->pDataFile; 356 pdi->pConfigFile = pdi2w->pConfigFile; 357 } 358 break; 359 360 default: 361 SetLastError(ERROR_INVALID_LEVEL); 362 return FALSE; 363 } 364 365 pDriverContainer.DriverInfo.Level8 = pdi; 366 367 RpcTryExcept 368 { 369 dwErrorCode = _RpcAddPrinterDriverEx( pName, &pDriverContainer, dwFileCopyFlags ); 370 } 371 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 372 { 373 dwErrorCode = RpcExceptionCode(); 374 ERR("_RpcAddPrinterDriverEx failed with exception code %lu!\n", dwErrorCode); 375 } 376 RpcEndExcept; 377 378 if ( pdi ) HeapFree( GetProcessHeap(), 0, pdi ); 379 380 SetLastError(dwErrorCode); 381 return (dwErrorCode == ERROR_SUCCESS); 382 } 383 384 BOOL WINAPI 385 AddPrinterDriverW(PWSTR pName, DWORD Level, PBYTE pDriverInfo) 386 { 387 TRACE("AddPrinterDriverW(%S, %lu, %p)\n", pName, Level, pDriverInfo); 388 return AddPrinterDriverExW(pName, Level, pDriverInfo, APD_COPY_NEW_FILES); 389 } 390 391 BOOL WINAPI 392 DeletePrinterDriverA(PSTR pName, PSTR pEnvironment, PSTR pDriverName) 393 { 394 TRACE("DeletePrinterDriverA(%s, %s, %s)\n", pName, pEnvironment, pDriverName); 395 return DeletePrinterDriverExA(pName, pEnvironment, pDriverName, 0, 0); 396 } 397 398 BOOL WINAPI 399 DeletePrinterDriverExA(PSTR pName, PSTR pEnvironment, PSTR pDriverName, DWORD dwDeleteFlag, DWORD dwVersionFlag) 400 { 401 DWORD dwErrorCode; 402 UNICODE_STRING NameW, EnvW, DriverW; 403 BOOL ret; 404 405 TRACE("DeletePrinterDriverExA(%s, %s, %s, %lu, %lu)\n", pName, pEnvironment, pDriverName, dwDeleteFlag, dwVersionFlag); 406 407 AsciiToUnicode(&NameW, pName); 408 AsciiToUnicode(&EnvW, pEnvironment); 409 AsciiToUnicode(&DriverW, pDriverName); 410 411 ret = DeletePrinterDriverExW(NameW.Buffer, EnvW.Buffer, DriverW.Buffer, dwDeleteFlag, dwVersionFlag); 412 413 dwErrorCode = GetLastError(); 414 415 RtlFreeUnicodeString(&DriverW); 416 RtlFreeUnicodeString(&EnvW); 417 RtlFreeUnicodeString(&NameW); 418 419 SetLastError(dwErrorCode); 420 return ret; 421 } 422 423 BOOL WINAPI 424 DeletePrinterDriverExW(PWSTR pName, PWSTR pEnvironment, PWSTR pDriverName, DWORD dwDeleteFlag, DWORD dwVersionFlag) 425 { 426 DWORD dwErrorCode; 427 428 TRACE("DeletePrinterDriverExW(%S, %S, %S, %lu, %lu)\n", pName, pEnvironment, pDriverName, dwDeleteFlag, dwVersionFlag); 429 430 if ( !pDriverName || !*pDriverName ) 431 { 432 SetLastError(ERROR_INVALID_PARAMETER); 433 return FALSE; 434 } 435 436 if ( !pEnvironment || !*pEnvironment ) 437 { 438 pEnvironment = (PWSTR)wszCurrentEnvironment; 439 } 440 441 // Do the RPC call. 442 RpcTryExcept 443 { 444 dwErrorCode = _RpcDeletePrinterDriverEx(pName, pEnvironment, pDriverName, dwDeleteFlag, dwVersionFlag); 445 } 446 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 447 { 448 dwErrorCode = RpcExceptionCode(); 449 ERR("_RpcDeletePrinterDriverEx failed with exception code %lu!\n", dwErrorCode); 450 } 451 RpcEndExcept; 452 453 SetLastError(dwErrorCode); 454 return (dwErrorCode == ERROR_SUCCESS); 455 456 } 457 458 BOOL WINAPI 459 DeletePrinterDriverW(PWSTR pName, PWSTR pEnvironment, PWSTR pDriverName) 460 { 461 TRACE("DeletePrinterDriverW(%S, %S, %S)\n", pName, pEnvironment, pDriverName); 462 return DeletePrinterDriverExW(pName, pEnvironment, pDriverName, 0, 0); 463 } 464 465 BOOL WINAPI 466 EnumPrinterDriversA(PSTR pName, PSTR pEnvironment, DWORD Level, PBYTE pDriverInfo, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned) 467 { 468 BOOL ret = FALSE; 469 DWORD dwErrorCode, i; 470 UNICODE_STRING pNameW, pEnvironmentW; 471 PWSTR pwstrNameW, pwstrEnvironmentW; 472 PDRIVER_INFO_1W pdi1w = (PDRIVER_INFO_1W)pDriverInfo; 473 PDRIVER_INFO_8W pdi8w = (PDRIVER_INFO_8W)pDriverInfo; 474 475 FIXME("EnumPrinterDriversA(%s, %s, %lu, %p, %lu, %p, %p)\n", pName, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded, pcReturned); 476 477 pwstrNameW = AsciiToUnicode(&pNameW, pName); 478 pwstrEnvironmentW = AsciiToUnicode(&pEnvironmentW, pEnvironment); 479 480 ret = EnumPrinterDriversW( pwstrNameW, pwstrEnvironmentW, Level, pDriverInfo, cbBuf, pcbNeeded, pcReturned ); 481 482 dwErrorCode = GetLastError(); 483 484 if (ret) 485 { 486 for ( i = 0; i < *pcReturned; i++ ) 487 { 488 switch (Level) 489 { 490 case 1: 491 { 492 dwErrorCode = UnicodeToAnsiInPlace(pdi1w[i].pName); 493 if (dwErrorCode != ERROR_SUCCESS) 494 { 495 goto Cleanup; 496 } 497 break; 498 } 499 case 8: 500 { 501 dwErrorCode = UnicodeToAnsiInPlace(pdi8w[i].pszPrintProcessor); 502 if (dwErrorCode != ERROR_SUCCESS) 503 { 504 goto Cleanup; 505 } 506 dwErrorCode = UnicodeToAnsiInPlace(pdi8w[i].pszVendorSetup); 507 if (dwErrorCode != ERROR_SUCCESS) 508 { 509 goto Cleanup; 510 } 511 dwErrorCode = UnicodeToAnsiZZInPlace(pdi8w[i].pszzColorProfiles); 512 if (dwErrorCode != ERROR_SUCCESS) 513 { 514 goto Cleanup; 515 } 516 dwErrorCode = UnicodeToAnsiInPlace(pdi8w[i].pszInfPath); 517 if (dwErrorCode != ERROR_SUCCESS) 518 { 519 goto Cleanup; 520 } 521 dwErrorCode = UnicodeToAnsiZZInPlace(pdi8w[i].pszzCoreDriverDependencies); 522 if (dwErrorCode != ERROR_SUCCESS) 523 { 524 goto Cleanup; 525 } 526 } 527 case 6: 528 { 529 dwErrorCode = UnicodeToAnsiInPlace(pdi8w[i].pszMfgName); 530 if (dwErrorCode != ERROR_SUCCESS) 531 { 532 goto Cleanup; 533 } 534 535 dwErrorCode = UnicodeToAnsiInPlace(pdi8w[i].pszOEMUrl); 536 if (dwErrorCode != ERROR_SUCCESS) 537 { 538 goto Cleanup; 539 } 540 541 dwErrorCode = UnicodeToAnsiInPlace(pdi8w[i].pszHardwareID); 542 if (dwErrorCode != ERROR_SUCCESS) 543 { 544 goto Cleanup; 545 } 546 547 dwErrorCode = UnicodeToAnsiInPlace(pdi8w[i].pszProvider); 548 if (dwErrorCode != ERROR_SUCCESS) 549 { 550 goto Cleanup; 551 } 552 } 553 case 4: 554 { 555 dwErrorCode = UnicodeToAnsiZZInPlace(pdi8w[i].pszzPreviousNames); 556 if (dwErrorCode != ERROR_SUCCESS) 557 { 558 goto Cleanup; 559 } 560 } 561 case 3: 562 { 563 dwErrorCode = UnicodeToAnsiInPlace(pdi8w[i].pHelpFile); 564 if (dwErrorCode != ERROR_SUCCESS) 565 { 566 goto Cleanup; 567 } 568 569 dwErrorCode = UnicodeToAnsiZZInPlace(pdi8w[i].pDependentFiles); 570 if (dwErrorCode != ERROR_SUCCESS) 571 { 572 goto Cleanup; 573 } 574 575 dwErrorCode = UnicodeToAnsiInPlace(pdi8w[i].pMonitorName); 576 if (dwErrorCode != ERROR_SUCCESS) 577 { 578 goto Cleanup; 579 } 580 581 dwErrorCode = UnicodeToAnsiInPlace(pdi8w[i].pDefaultDataType); 582 if (dwErrorCode != ERROR_SUCCESS) 583 { 584 goto Cleanup; 585 } 586 } 587 case 2: 588 case 5: 589 { 590 dwErrorCode = UnicodeToAnsiInPlace(pdi8w[i].pName); 591 if (dwErrorCode != ERROR_SUCCESS) 592 { 593 goto Cleanup; 594 } 595 596 dwErrorCode = UnicodeToAnsiInPlace(pdi8w[i].pEnvironment); 597 if (dwErrorCode != ERROR_SUCCESS) 598 { 599 goto Cleanup; 600 } 601 602 dwErrorCode = UnicodeToAnsiInPlace(pdi8w[i].pDriverPath); 603 if (dwErrorCode != ERROR_SUCCESS) 604 { 605 goto Cleanup; 606 } 607 608 dwErrorCode = UnicodeToAnsiInPlace(pdi8w[i].pDataFile); 609 if (dwErrorCode != ERROR_SUCCESS) 610 { 611 goto Cleanup; 612 } 613 614 dwErrorCode = UnicodeToAnsiInPlace(pdi8w[i].pConfigFile); 615 if (dwErrorCode != ERROR_SUCCESS) 616 { 617 goto Cleanup; 618 } 619 } 620 } 621 } 622 dwErrorCode = ERROR_SUCCESS; 623 } 624 Cleanup: 625 RtlFreeUnicodeString(&pNameW); 626 RtlFreeUnicodeString(&pEnvironmentW); 627 SetLastError(dwErrorCode); 628 FIXME("EnumPrinterDriversA Exit %d Err %d\n",ret,GetLastError()); 629 return ret; 630 } 631 632 BOOL WINAPI 633 EnumPrinterDriversW(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pDriverInfo, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned) 634 { 635 DWORD dwErrorCode; 636 637 FIXME("EnumPrinterDriversW(%S, %S, %lu, %p, %lu, %p, %p)\n", pName, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded, pcReturned); 638 639 // Dismiss invalid levels already at this point. 640 if (Level < 1 || Level == 7 || Level > 8) 641 { 642 dwErrorCode = ERROR_INVALID_LEVEL; 643 goto Cleanup; 644 } 645 646 if ( !pEnvironment || !*pEnvironment ) 647 { 648 pEnvironment = (PWSTR)wszCurrentEnvironment; 649 } 650 651 if (cbBuf && pDriverInfo) 652 ZeroMemory(pDriverInfo, cbBuf); 653 654 // Do the RPC call 655 RpcTryExcept 656 { 657 dwErrorCode = _RpcEnumPrinterDrivers( pName, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded, pcReturned ); 658 } 659 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 660 { 661 dwErrorCode = RpcExceptionCode(); 662 ERR("_RpcEnumPrinterDrivers failed with exception code %lu!\n", dwErrorCode); 663 } 664 RpcEndExcept; 665 666 if (dwErrorCode == ERROR_SUCCESS) 667 { 668 // Replace relative offset addresses in the output by absolute pointers. 669 ASSERT(Level <= 6 || Level == 8); 670 MarshallUpStructuresArray(cbBuf, pDriverInfo, *pcReturned, pPrinterDriverMarshalling[Level]->pInfo, pPrinterDriverMarshalling[Level]->cbStructureSize, TRUE); 671 } 672 673 Cleanup: 674 SetLastError(dwErrorCode); FIXME("EnumPrinterDriversW Exit Err %d\n",dwErrorCode); 675 return (dwErrorCode == ERROR_SUCCESS); 676 677 } 678 679 BOOL WINAPI 680 GetPrinterDriverA(HANDLE hPrinter, LPSTR pEnvironment, DWORD Level, LPBYTE pDriverInfo, DWORD cbBuf, LPDWORD pcbNeeded) 681 { 682 DWORD dwErrorCode; 683 /* 684 * We are mapping multiple different pointers to the same pDriverInfo pointer here so that 685 * we can use the same incoming pointer for different Levels 686 */ 687 PDRIVER_INFO_1W pdi1w = (PDRIVER_INFO_1W)pDriverInfo; 688 PDRIVER_INFO_8W pdi8w = (PDRIVER_INFO_8W)pDriverInfo; 689 690 DWORD cch; 691 PWSTR pwszEnvironment = NULL; 692 693 TRACE("GetPrinterDriverA(%p, %s, %lu, %p, %lu, %p)\n", hPrinter, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded); 694 695 // Check for invalid levels here for early error return. Should be 1-6 & 8. 696 if (Level < 1 || Level == 7 || Level > 8) 697 { 698 dwErrorCode = ERROR_INVALID_LEVEL; 699 ERR("Invalid Level! %d\n",Level); 700 goto Cleanup; 701 } 702 703 if (pEnvironment) 704 { 705 // Convert pEnvironment to a Unicode string pwszEnvironment. 706 cch = strlen(pEnvironment); 707 708 pwszEnvironment = HeapAlloc(hProcessHeap, 0, (cch + 1) * sizeof(WCHAR)); 709 if (!pwszEnvironment) 710 { 711 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY; 712 ERR("HeapAlloc failed!\n"); 713 goto Cleanup; 714 } 715 716 MultiByteToWideChar(CP_ACP, 0, pEnvironment, -1, pwszEnvironment, cch + 1); 717 } 718 719 if (!GetPrinterDriverW(hPrinter, pwszEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded)) 720 { 721 dwErrorCode = GetLastError(); 722 goto Cleanup; 723 } 724 725 // Do Unicode to ANSI conversions for strings based on Level 726 switch (Level) 727 { 728 case 1: 729 { 730 dwErrorCode = UnicodeToAnsiInPlace(pdi1w->pName); 731 if (dwErrorCode != ERROR_SUCCESS) 732 { 733 goto Cleanup; 734 } 735 break; 736 } 737 case 8: 738 { 739 dwErrorCode = UnicodeToAnsiInPlace(pdi8w->pszPrintProcessor); 740 if (dwErrorCode != ERROR_SUCCESS) 741 { 742 goto Cleanup; 743 } 744 dwErrorCode = UnicodeToAnsiInPlace(pdi8w->pszVendorSetup); 745 if (dwErrorCode != ERROR_SUCCESS) 746 { 747 goto Cleanup; 748 } 749 dwErrorCode = UnicodeToAnsiZZInPlace(pdi8w->pszzColorProfiles); 750 if (dwErrorCode != ERROR_SUCCESS) 751 { 752 goto Cleanup; 753 } 754 dwErrorCode = UnicodeToAnsiInPlace(pdi8w->pszInfPath); 755 if (dwErrorCode != ERROR_SUCCESS) 756 { 757 goto Cleanup; 758 } 759 dwErrorCode = UnicodeToAnsiZZInPlace(pdi8w->pszzCoreDriverDependencies); 760 if (dwErrorCode != ERROR_SUCCESS) 761 { 762 goto Cleanup; 763 } 764 } 765 case 6: 766 { 767 dwErrorCode = UnicodeToAnsiInPlace(pdi8w->pszMfgName); 768 if (dwErrorCode != ERROR_SUCCESS) 769 { 770 goto Cleanup; 771 } 772 773 dwErrorCode = UnicodeToAnsiInPlace(pdi8w->pszOEMUrl); 774 if (dwErrorCode != ERROR_SUCCESS) 775 { 776 goto Cleanup; 777 } 778 779 dwErrorCode = UnicodeToAnsiInPlace(pdi8w->pszHardwareID); 780 if (dwErrorCode != ERROR_SUCCESS) 781 { 782 goto Cleanup; 783 } 784 785 dwErrorCode = UnicodeToAnsiInPlace(pdi8w->pszProvider); 786 if (dwErrorCode != ERROR_SUCCESS) 787 { 788 goto Cleanup; 789 } 790 } 791 case 4: 792 { 793 dwErrorCode = UnicodeToAnsiZZInPlace(pdi8w->pszzPreviousNames); 794 if (dwErrorCode != ERROR_SUCCESS) 795 { 796 goto Cleanup; 797 } 798 } 799 case 3: 800 { 801 dwErrorCode = UnicodeToAnsiInPlace(pdi8w->pHelpFile); 802 if (dwErrorCode != ERROR_SUCCESS) 803 { 804 goto Cleanup; 805 } 806 807 dwErrorCode = UnicodeToAnsiZZInPlace(pdi8w->pDependentFiles); 808 if (dwErrorCode != ERROR_SUCCESS) 809 { 810 goto Cleanup; 811 } 812 813 dwErrorCode = UnicodeToAnsiInPlace(pdi8w->pMonitorName); 814 if (dwErrorCode != ERROR_SUCCESS) 815 { 816 goto Cleanup; 817 } 818 819 dwErrorCode = UnicodeToAnsiInPlace(pdi8w->pDefaultDataType); 820 if (dwErrorCode != ERROR_SUCCESS) 821 { 822 goto Cleanup; 823 } 824 } 825 case 2: 826 case 5: 827 { 828 dwErrorCode = UnicodeToAnsiInPlace(pdi8w->pConfigFile); 829 if (dwErrorCode != ERROR_SUCCESS) 830 { 831 goto Cleanup; 832 } 833 dwErrorCode = UnicodeToAnsiInPlace(pdi8w->pDataFile); 834 835 if (dwErrorCode != ERROR_SUCCESS) 836 { 837 goto Cleanup; 838 } 839 840 dwErrorCode = UnicodeToAnsiInPlace(pdi8w->pDriverPath); 841 if (dwErrorCode != ERROR_SUCCESS) 842 { 843 goto Cleanup; 844 } 845 846 dwErrorCode = UnicodeToAnsiInPlace(pdi8w->pEnvironment); 847 if (dwErrorCode != ERROR_SUCCESS) 848 { 849 goto Cleanup; 850 } 851 852 dwErrorCode = UnicodeToAnsiInPlace(pdi8w->pName); 853 if (dwErrorCode != ERROR_SUCCESS) 854 { 855 goto Cleanup; 856 } 857 } 858 } 859 860 dwErrorCode = ERROR_SUCCESS; 861 862 Cleanup: 863 if (pwszEnvironment) 864 { 865 HeapFree(hProcessHeap, 0, pwszEnvironment); 866 } 867 868 SetLastError(dwErrorCode); 869 return (dwErrorCode == ERROR_SUCCESS); 870 } 871 872 BOOL WINAPI 873 GetPrinterDriverW(HANDLE hPrinter, LPWSTR pEnvironment, DWORD Level, LPBYTE pDriverInfo, DWORD cbBuf, LPDWORD pcbNeeded) 874 { 875 DWORD dwErrorCode; 876 PSPOOLER_HANDLE pHandle = (PSPOOLER_HANDLE)hPrinter; 877 878 TRACE("GetPrinterDriverW(%p, %S, %lu, %p, %lu, %p)\n", hPrinter, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded); 879 880 // Sanity checks. 881 if (!pHandle) 882 { 883 dwErrorCode = ERROR_INVALID_HANDLE; 884 goto Cleanup; 885 } 886 887 // Dismiss invalid levels already at this point. 888 if (Level > 8 || Level == 7 || Level < 1) 889 { 890 dwErrorCode = ERROR_INVALID_LEVEL; 891 goto Cleanup; 892 } 893 894 if ( !pEnvironment || !*pEnvironment ) 895 { 896 pEnvironment = (PWSTR)wszCurrentEnvironment; 897 } 898 899 if (cbBuf && pDriverInfo) 900 ZeroMemory(pDriverInfo, cbBuf); 901 902 // Do the RPC call 903 RpcTryExcept 904 { 905 dwErrorCode = _RpcGetPrinterDriver(pHandle->hPrinter, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded); 906 } 907 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 908 { 909 dwErrorCode = RpcExceptionCode(); 910 ERR("_RpcGetPrinterDriver failed with exception code %lu!\n", dwErrorCode); 911 } 912 RpcEndExcept; 913 914 if (dwErrorCode == ERROR_SUCCESS) 915 { 916 // Replace relative offset addresses in the output by absolute pointers. 917 ASSERT(Level <= 6 || Level == 8); 918 MarshallUpStructure(cbBuf, pDriverInfo, pPrinterDriverMarshalling[Level]->pInfo, pPrinterDriverMarshalling[Level]->cbStructureSize, TRUE); 919 } 920 921 Cleanup: 922 SetLastError(dwErrorCode); 923 return (dwErrorCode == ERROR_SUCCESS); 924 } 925 926 BOOL WINAPI 927 GetPrinterDriverDirectoryA(PSTR pName, PSTR pEnvironment, DWORD Level, PBYTE pDriverDirectory, DWORD cbBuf, PDWORD pcbNeeded) 928 { 929 UNICODE_STRING nameW, environmentW; 930 BOOL ret; 931 DWORD pcbNeededW; 932 INT len = cbBuf * sizeof(WCHAR)/sizeof(CHAR); 933 WCHAR *driverDirectoryW = NULL; 934 935 TRACE("GetPrinterDriverDirectoryA(%s, %s, %d, %p, %d, %p)\n", debugstr_a(pName), debugstr_a(pEnvironment), Level, pDriverDirectory, cbBuf, pcbNeeded); 936 937 if (len) driverDirectoryW = HeapAlloc( GetProcessHeap(), 0, len ); 938 939 if (pName) 940 { 941 RtlCreateUnicodeStringFromAsciiz(&nameW, pName); 942 } 943 else 944 { 945 nameW.Buffer = NULL; 946 } 947 if (pEnvironment) 948 { 949 RtlCreateUnicodeStringFromAsciiz(&environmentW, pEnvironment); 950 } 951 else 952 { 953 environmentW.Buffer = NULL; 954 } 955 956 ret = GetPrinterDriverDirectoryW( nameW.Buffer, environmentW.Buffer, Level, (LPBYTE)driverDirectoryW, len, &pcbNeededW ); 957 958 if (ret) 959 { 960 DWORD needed = WideCharToMultiByte( CP_ACP, 0, driverDirectoryW, -1, (LPSTR)pDriverDirectory, cbBuf, NULL, NULL); 961 962 if ( pcbNeeded ) 963 *pcbNeeded = needed; 964 965 ret = needed <= cbBuf; 966 } 967 else 968 { 969 if (pcbNeeded) *pcbNeeded = pcbNeededW * sizeof(CHAR)/sizeof(WCHAR); 970 } 971 972 TRACE("required: 0x%x/%d\n", pcbNeeded ? *pcbNeeded : 0, pcbNeeded ? *pcbNeeded : 0); 973 974 HeapFree( GetProcessHeap(), 0, driverDirectoryW ); 975 RtlFreeUnicodeString(&environmentW); 976 RtlFreeUnicodeString(&nameW); 977 978 return ret; 979 } 980 981 BOOL WINAPI 982 GetPrinterDriverDirectoryW(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pDriverDirectory, DWORD cbBuf, PDWORD pcbNeeded) 983 { 984 DWORD dwErrorCode; 985 986 TRACE("GetPrinterDriverDirectoryW(%S, %S, %lu, %p, %lu, %p)\n", pName, pEnvironment, Level, pDriverDirectory, cbBuf, pcbNeeded); 987 988 if (Level != 1) 989 { 990 dwErrorCode = ERROR_INVALID_LEVEL; 991 goto Cleanup; 992 } 993 994 if ( !pEnvironment || !*pEnvironment ) 995 { 996 pEnvironment = (PWSTR)wszCurrentEnvironment; 997 } 998 999 // Do the RPC call. 1000 RpcTryExcept 1001 { 1002 dwErrorCode = _RpcGetPrinterDriverDirectory(pName, pEnvironment, Level, pDriverDirectory, cbBuf, pcbNeeded); 1003 } 1004 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 1005 { 1006 dwErrorCode = RpcExceptionCode(); 1007 ERR("_RpcGetPrinterDriverDirectory failed with exception code %lu!\n", dwErrorCode); 1008 } 1009 RpcEndExcept; 1010 1011 Cleanup: 1012 SetLastError(dwErrorCode); 1013 return (dwErrorCode == ERROR_SUCCESS); 1014 } 1015