1 /* 2 * PROJECT: ReactOS Print Spooler Service 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: Functions related to Printer Drivers 5 * COPYRIGHT: Copyright 2015 Colin Finck (colin@reactos.org) 6 */ 7 8 #include "precomp.h" 9 #include "marshalling/printerdrivers.h" 10 11 DWORD 12 _RpcAddPrinterDriver(WINSPOOL_HANDLE pName, WINSPOOL_DRIVER_CONTAINER* pDriverContainer) 13 { 14 DWORD dwErrorCode; 15 PBYTE pDriverInfo = NULL; 16 17 switch ( pDriverContainer->Level ) 18 { 19 case 8: 20 { 21 WINSPOOL_DRIVER_INFO_8 *pdi = pDriverContainer->DriverInfo.Level8; 22 PDRIVER_INFO_8W pdi8w = DllAllocSplMem(sizeof(DRIVER_INFO_8W)); 23 pDriverInfo = (PBYTE)pdi8w; 24 25 pdi8w->pszPrintProcessor = pdi->pPrintProcessor; 26 pdi8w->pszVendorSetup = pdi->pVendorSetup; 27 pdi8w->pszzColorProfiles = pdi->pszzColorProfiles; 28 pdi8w->pszInfPath = pdi->pInfPath; 29 pdi8w->pszzCoreDriverDependencies = pdi->pszzCoreDriverDependencies; 30 pdi8w->ftMinInboxDriverVerDate = pdi->ftMinInboxDriverVerDate; 31 pdi8w->dwlMinInboxDriverVerVersion = pdi->dwlMinInboxDriverVerVersion; 32 } 33 case 6: 34 { 35 WINSPOOL_DRIVER_INFO_6 *pdi = pDriverContainer->DriverInfo.Level6; 36 PDRIVER_INFO_6W pdi6w; 37 38 if ( pDriverInfo == NULL ) 39 { 40 pdi6w = DllAllocSplMem(sizeof(DRIVER_INFO_6W)); 41 pDriverInfo = (PBYTE)pdi6w; 42 } 43 else 44 { 45 pdi6w = (PDRIVER_INFO_6W)pDriverInfo; 46 } 47 48 pdi6w->pszMfgName = pdi->pMfgName; 49 pdi6w->pszOEMUrl = pdi->pOEMUrl; 50 pdi6w->pszHardwareID = pdi->pHardwareID; 51 pdi6w->pszProvider = pdi->pProvider; 52 pdi6w->ftDriverDate = pdi->ftDriverDate; 53 pdi6w->dwlDriverVersion = pdi->dwlDriverVersion; 54 } 55 case 4: 56 { 57 WINSPOOL_DRIVER_INFO_4 *pdi = pDriverContainer->DriverInfo.Level4; 58 PDRIVER_INFO_4W pdi4w; 59 60 if ( pDriverInfo == NULL ) 61 { 62 pdi4w = DllAllocSplMem(sizeof(DRIVER_INFO_4W)); 63 pDriverInfo = (PBYTE)pdi4w; 64 } 65 else 66 { 67 pdi4w = (PDRIVER_INFO_4W)pDriverInfo; 68 } 69 70 pdi4w->pszzPreviousNames = pdi->pszzPreviousNames; 71 } 72 case 3: 73 { 74 WINSPOOL_DRIVER_INFO_3 *pdi = pDriverContainer->DriverInfo.Level3; 75 PDRIVER_INFO_3W pdi3w; 76 77 if ( pDriverInfo == NULL ) 78 { 79 pdi3w = DllAllocSplMem(sizeof(DRIVER_INFO_3W)); 80 pDriverInfo = (PBYTE)pdi3w; 81 } 82 else 83 { 84 pdi3w = (PDRIVER_INFO_3W)pDriverInfo; 85 } 86 87 pdi3w->pHelpFile = pdi->pHelpFile; 88 pdi3w->pDependentFiles = pdi->pDependentFiles; 89 pdi3w->pMonitorName = pdi->pMonitorName; 90 pdi3w->pDefaultDataType = pdi->pDefaultDataType; 91 pdi3w->pDependentFiles = pdi->pDependentFiles; 92 } 93 case 2: 94 { 95 WINSPOOL_DRIVER_INFO_2 *pdi = pDriverContainer->DriverInfo.Level2; 96 PDRIVER_INFO_2W pdi2w; 97 98 if ( pDriverInfo == NULL ) 99 { 100 pdi2w = DllAllocSplMem(sizeof(DRIVER_INFO_2W)); 101 pDriverInfo = (PBYTE)pdi2w; 102 } 103 else 104 { 105 pdi2w = (PDRIVER_INFO_2W)pDriverInfo; 106 } 107 108 pdi2w->pName = pdi->pName; 109 pdi2w->pEnvironment = pdi->pEnvironment; 110 pdi2w->pDriverPath = pdi->pDriverPath; 111 pdi2w->pDataFile = pdi->pDataFile; 112 pdi2w->pConfigFile = pdi->pConfigFile; 113 } 114 break; 115 // 116 // At this point pDriverInfo is null. 117 // 118 default: 119 return ERROR_INVALID_LEVEL; 120 } 121 122 dwErrorCode = RpcImpersonateClient(NULL); 123 if (dwErrorCode != ERROR_SUCCESS) 124 { 125 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode); 126 return dwErrorCode; 127 } 128 129 if (!AddPrinterDriverW( pName, pDriverContainer->Level, pDriverInfo )) 130 dwErrorCode = GetLastError(); 131 132 if ( pDriverInfo ) DllFreeSplMem( pDriverInfo ); 133 134 RpcRevertToSelf(); 135 return dwErrorCode; 136 } 137 138 DWORD 139 _RpcAddPrinterDriverEx(WINSPOOL_HANDLE pName, WINSPOOL_DRIVER_CONTAINER* pDriverContainer, DWORD dwFileCopyFlags) 140 { 141 DWORD dwErrorCode; 142 PBYTE pDriverInfo = NULL; 143 144 switch ( pDriverContainer->Level ) 145 { 146 case 8: 147 { 148 WINSPOOL_DRIVER_INFO_8 *pdi = pDriverContainer->DriverInfo.Level8; 149 PDRIVER_INFO_8W pdi8w = DllAllocSplMem(sizeof(DRIVER_INFO_8W)); 150 pDriverInfo = (PBYTE)pdi8w; 151 152 pdi8w->pszPrintProcessor = pdi->pPrintProcessor; 153 pdi8w->pszVendorSetup = pdi->pVendorSetup; 154 pdi8w->pszzColorProfiles = pdi->pszzColorProfiles; 155 pdi8w->pszInfPath = pdi->pInfPath; 156 pdi8w->pszzCoreDriverDependencies = pdi->pszzCoreDriverDependencies; 157 pdi8w->ftMinInboxDriverVerDate = pdi->ftMinInboxDriverVerDate; 158 pdi8w->dwlMinInboxDriverVerVersion = pdi->dwlMinInboxDriverVerVersion; 159 } 160 case 6: 161 { 162 WINSPOOL_DRIVER_INFO_6 *pdi = pDriverContainer->DriverInfo.Level6; 163 PDRIVER_INFO_6W pdi6w; 164 165 if ( pDriverInfo == NULL ) 166 { 167 pdi6w = DllAllocSplMem(sizeof(DRIVER_INFO_6W)); 168 pDriverInfo = (PBYTE)pdi6w; 169 } 170 else 171 { 172 pdi6w = (PDRIVER_INFO_6W)pDriverInfo; 173 } 174 175 pdi6w->pszMfgName = pdi->pMfgName; 176 pdi6w->pszOEMUrl = pdi->pOEMUrl; 177 pdi6w->pszHardwareID = pdi->pHardwareID; 178 pdi6w->pszProvider = pdi->pProvider; 179 pdi6w->ftDriverDate = pdi->ftDriverDate; 180 pdi6w->dwlDriverVersion = pdi->dwlDriverVersion; 181 } 182 case 4: 183 { 184 WINSPOOL_DRIVER_INFO_4 *pdi = pDriverContainer->DriverInfo.Level4; 185 PDRIVER_INFO_4W pdi4w; 186 187 if ( pDriverInfo == NULL ) 188 { 189 pdi4w = DllAllocSplMem(sizeof(DRIVER_INFO_4W)); 190 pDriverInfo = (PBYTE)pdi4w; 191 } 192 else 193 { 194 pdi4w = (PDRIVER_INFO_4W)pDriverInfo; 195 } 196 197 pdi4w->pszzPreviousNames = pdi->pszzPreviousNames; 198 } 199 case 3: 200 { 201 WINSPOOL_DRIVER_INFO_3 *pdi = pDriverContainer->DriverInfo.Level3; 202 PDRIVER_INFO_3W pdi3w; 203 204 if ( pDriverInfo == NULL ) 205 { 206 pdi3w = DllAllocSplMem(sizeof(DRIVER_INFO_3W)); 207 pDriverInfo = (PBYTE)pdi3w; 208 } 209 else 210 { 211 pdi3w = (PDRIVER_INFO_3W)pDriverInfo; 212 } 213 214 pdi3w->pHelpFile = pdi->pHelpFile; 215 pdi3w->pDependentFiles = pdi->pDependentFiles; 216 pdi3w->pMonitorName = pdi->pMonitorName; 217 pdi3w->pDefaultDataType = pdi->pDefaultDataType; 218 pdi3w->pDependentFiles = pdi->pDependentFiles; 219 } 220 case 2: 221 { 222 WINSPOOL_DRIVER_INFO_2 *pdi = pDriverContainer->DriverInfo.Level2; 223 PDRIVER_INFO_2W pdi2w; 224 225 if ( pDriverInfo == NULL ) 226 { 227 pdi2w = DllAllocSplMem(sizeof(DRIVER_INFO_2W)); 228 pDriverInfo = (PBYTE)pdi2w; 229 } 230 else 231 { 232 pdi2w = (PDRIVER_INFO_2W)pDriverInfo; 233 } 234 235 pdi2w->pName = pdi->pName; 236 pdi2w->pEnvironment = pdi->pEnvironment; 237 pdi2w->pDriverPath = pdi->pDriverPath; 238 pdi2w->pDataFile = pdi->pDataFile; 239 pdi2w->pConfigFile = pdi->pConfigFile; 240 } 241 break; 242 // 243 // At this point pDriverInfo is null. 244 // 245 default: 246 return ERROR_INVALID_LEVEL; 247 } 248 249 dwErrorCode = RpcImpersonateClient(NULL); 250 if (dwErrorCode != ERROR_SUCCESS) 251 { 252 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode); 253 return dwErrorCode; 254 } 255 256 if (!AddPrinterDriverExW( pName, pDriverContainer->Level, pDriverInfo, dwFileCopyFlags )) 257 dwErrorCode = GetLastError(); 258 259 if ( pDriverInfo ) DllFreeSplMem( pDriverInfo ); 260 261 RpcRevertToSelf(); 262 return dwErrorCode; 263 } 264 265 DWORD 266 _RpcDeletePrinterDriver(WINSPOOL_HANDLE pName, WCHAR* pEnvironment, WCHAR* pDriverName) 267 { 268 DWORD dwErrorCode; 269 270 dwErrorCode = RpcImpersonateClient(NULL); 271 if (dwErrorCode != ERROR_SUCCESS) 272 { 273 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode); 274 return dwErrorCode; 275 } 276 277 if (!DeletePrinterDriverW(pName, pEnvironment, pDriverName)) 278 dwErrorCode = GetLastError(); 279 280 RpcRevertToSelf(); 281 return dwErrorCode; 282 } 283 284 DWORD 285 _RpcDeletePrinterDriverEx(WINSPOOL_HANDLE pName, WCHAR* pEnvironment, WCHAR* pDriverName, DWORD dwDeleteFlag, DWORD dwVersionNum) 286 { 287 DWORD dwErrorCode; 288 289 dwErrorCode = RpcImpersonateClient(NULL); 290 if (dwErrorCode != ERROR_SUCCESS) 291 { 292 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode); 293 return dwErrorCode; 294 } 295 296 if (!DeletePrinterDriverExW(pName, pEnvironment, pDriverName, dwDeleteFlag, dwVersionNum)) 297 dwErrorCode = GetLastError(); 298 299 RpcRevertToSelf(); 300 return dwErrorCode; 301 } 302 303 DWORD 304 _RpcEnumPrinterDrivers(WINSPOOL_HANDLE pName, WCHAR* pEnvironment, DWORD Level, BYTE* pDrivers, DWORD cbBuf, DWORD* pcbNeeded, DWORD* pcReturned) 305 { 306 DWORD dwErrorCode; 307 PBYTE pPrinterDriversEnumAligned; 308 309 dwErrorCode = RpcImpersonateClient(NULL); 310 if (dwErrorCode != ERROR_SUCCESS) 311 { 312 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode); 313 return dwErrorCode; 314 } 315 316 pPrinterDriversEnumAligned = AlignRpcPtr(pDrivers, &cbBuf); 317 318 if (EnumPrinterDriversW(pName, pEnvironment, Level, pPrinterDriversEnumAligned, cbBuf, pcbNeeded, pcReturned)) 319 { 320 // Replace absolute pointer addresses in the output by relative offsets. 321 ASSERT(Level <= 6 || Level == 8); 322 MarshallDownStructuresArray(pPrinterDriversEnumAligned, *pcReturned, pPrinterDriverMarshalling[Level]->pInfo, pPrinterDriverMarshalling[Level]->cbStructureSize, TRUE); 323 } 324 else 325 { 326 dwErrorCode = GetLastError(); 327 } 328 329 RpcRevertToSelf(); 330 UndoAlignRpcPtr(pDrivers, pPrinterDriversEnumAligned, cbBuf, pcbNeeded); 331 332 return dwErrorCode; 333 } 334 335 DWORD 336 _RpcGetPrinterDriver(WINSPOOL_PRINTER_HANDLE hPrinter, WCHAR* pEnvironment, DWORD Level, BYTE* pDriver, DWORD cbBuf, DWORD* pcbNeeded) 337 { 338 DWORD dwErrorCode; 339 PBYTE pDriverAligned; 340 341 TRACE("_RpcGetPrinterDriver(%p, %lu, %lu, %p, %lu, %p)\n", hPrinter, pEnvironment, Level, pDriver, cbBuf, pcbNeeded); 342 343 dwErrorCode = RpcImpersonateClient(NULL); 344 if (dwErrorCode != ERROR_SUCCESS) 345 { 346 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode); 347 return dwErrorCode; 348 } 349 350 pDriverAligned = AlignRpcPtr(pDriver, &cbBuf); 351 352 if (GetPrinterDriverW(hPrinter, pEnvironment, Level, pDriverAligned, cbBuf, pcbNeeded)) 353 { 354 // Replace relative offset addresses in the output by absolute pointers. 355 ASSERT(Level <= 6 || Level == 8); 356 MarshallDownStructure(pDriverAligned, pPrinterDriverMarshalling[Level]->pInfo, pPrinterDriverMarshalling[Level]->cbStructureSize, TRUE); 357 } 358 else 359 { 360 dwErrorCode = GetLastError(); 361 } 362 363 RpcRevertToSelf(); 364 UndoAlignRpcPtr(pDriver, pDriverAligned, cbBuf, pcbNeeded); 365 366 return dwErrorCode; 367 } 368 369 BOOL WINAPI YGetPrinterDriver2( 370 HANDLE hPrinter, 371 LPWSTR pEnvironment, 372 DWORD Level, 373 LPBYTE pDriver, 374 DWORD cbBuf, 375 LPDWORD pcbNeeded, 376 DWORD dwClientMajorVersion, 377 DWORD dwClientMinorVersion, 378 PDWORD pdwServerMajorVersion, 379 PDWORD pdwServerMinorVersion, 380 BOOL bRPC ) // Seems that all Y fuctions have this. 381 { 382 DWORD dwErrorCode; 383 PBYTE pDriverAligned; 384 385 FIXME("_Rpc(Y)GetPrinterDriver2(%p, %lu, %lu, %p, %lu, %p, %lu, %lu, %p, %p)\n", hPrinter, pEnvironment, Level, pDriver, cbBuf, pcbNeeded, dwClientMajorVersion, dwClientMinorVersion, pdwServerMajorVersion, pdwServerMinorVersion); 386 387 if ( bRPC ) 388 { 389 dwErrorCode = RpcImpersonateClient(NULL); 390 if (dwErrorCode != ERROR_SUCCESS) 391 { 392 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode); 393 return dwErrorCode; 394 } 395 } 396 397 pDriverAligned = AlignRpcPtr(pDriver, &cbBuf); 398 399 if (GetPrinterDriverExW(hPrinter, pEnvironment, Level, pDriverAligned, cbBuf, pcbNeeded, dwClientMajorVersion, dwClientMinorVersion, pdwServerMajorVersion, pdwServerMinorVersion)) 400 { 401 // Replace relative offset addresses in the output by absolute pointers. 402 ASSERT(Level <= 6 || Level == 8); 403 MarshallDownStructure(pDriverAligned, pPrinterDriverMarshalling[Level]->pInfo, pPrinterDriverMarshalling[Level]->cbStructureSize, TRUE); 404 } 405 else 406 { 407 dwErrorCode = GetLastError(); 408 } 409 410 if ( bRPC ) RpcRevertToSelf(); 411 UndoAlignRpcPtr(pDriver, pDriverAligned, cbBuf, pcbNeeded); 412 413 return dwErrorCode; 414 } 415 416 DWORD 417 _RpcGetPrinterDriver2(WINSPOOL_PRINTER_HANDLE hPrinter, WCHAR* pEnvironment, DWORD Level, BYTE* pDriver, DWORD cbBuf, DWORD* pcbNeeded, DWORD dwClientMajorVersion, DWORD dwClientMinorVersion, DWORD* pdwServerMaxVersion, DWORD* pdwServerMinVersion) 418 { 419 DWORD dwErrorCode; 420 PBYTE pDriverAligned; 421 422 FIXME("_RpcGetPrinterDriver2(%p, %lu, %lu, %p, %lu, %p, %lu, %lu, %p, %p)\n", hPrinter, pEnvironment, Level, pDriver, cbBuf, pcbNeeded, dwClientMajorVersion, dwClientMinorVersion, pdwServerMaxVersion, pdwServerMinVersion); 423 424 dwErrorCode = RpcImpersonateClient(NULL); 425 if (dwErrorCode != ERROR_SUCCESS) 426 { 427 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode); 428 return dwErrorCode; 429 } 430 431 pDriverAligned = AlignRpcPtr(pDriver, &cbBuf); 432 433 if (GetPrinterDriverExW(hPrinter, pEnvironment, Level, pDriverAligned, cbBuf, pcbNeeded, dwClientMajorVersion, dwClientMinorVersion, pdwServerMaxVersion, pdwServerMinVersion)) 434 { 435 // Replace relative offset addresses in the output by absolute pointers. 436 ASSERT(Level <= 6 || Level == 8); 437 MarshallDownStructure(pDriverAligned, pPrinterDriverMarshalling[Level]->pInfo, pPrinterDriverMarshalling[Level]->cbStructureSize, TRUE); 438 } 439 else 440 { 441 dwErrorCode = GetLastError(); 442 } 443 444 RpcRevertToSelf(); 445 UndoAlignRpcPtr(pDriver, pDriverAligned, cbBuf, pcbNeeded); 446 447 return dwErrorCode; 448 } 449 450 DWORD 451 _RpcGetPrinterDriverDirectory(WINSPOOL_HANDLE pName, WCHAR* pEnvironment, DWORD Level, BYTE* pDriverDirectory, DWORD cbBuf, DWORD* pcbNeeded) 452 { 453 DWORD dwErrorCode; 454 455 dwErrorCode = RpcImpersonateClient(NULL); 456 if (dwErrorCode != ERROR_SUCCESS) 457 { 458 ERR("RpcImpersonateClient failed with error %lu!\n", dwErrorCode); 459 return dwErrorCode; 460 } 461 462 if (!GetPrinterDriverDirectoryW(pName, pEnvironment, Level, pDriverDirectory, cbBuf, pcbNeeded)) 463 dwErrorCode = GetLastError(); 464 465 RpcRevertToSelf(); 466 return dwErrorCode; 467 } 468