Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1485 lines
38 KiB

  1. /*++
  2. Copyright (c) 1990 - 1995 Microsoft Corporation
  3. Module Name:
  4. winspool.c
  5. Abstract:
  6. This module provides all the public exported APIs relating to Printer
  7. and Job management for the Print Providor Routing layer
  8. Author:
  9. Dave Snipp (DaveSn) 15-Mar-1991
  10. [Notes:]
  11. optional-notes
  12. Revision History:
  13. --*/
  14. #include "precomp.h"
  15. #pragma hdrstop
  16. #include "local.h"
  17. //
  18. // Globals
  19. //
  20. LPPROVIDOR pLocalProvidor;
  21. MODULE_DEBUG_INIT( DBG_ERROR, DBG_ERROR );
  22. LPWSTR szRegistryProvidors = L"System\\CurrentControlSet\\Control\\Print\\Providers";
  23. LPWSTR szPrintKey = L"System\\CurrentControlSet\\Control\\Print";
  24. LPWSTR szLocalSplDll = L"localspl.dll";
  25. LPWSTR szOrder = L"Order";
  26. LPWSTR szEnvironment = LOCAL_ENVIRONMENT;
  27. //
  28. // Strings for handling the AddPrinterDrivers policy
  29. //
  30. LPWSTR szLanManProvider = L"LanMan Print Services";
  31. LPWSTR szAPDRelPath = L"LanMan Print Services\\Servers";
  32. LPWSTR szAPDValueName = L"AddPrinterDrivers";
  33. BOOL
  34. AddPrinterDriverW(
  35. LPWSTR pName,
  36. DWORD Level,
  37. LPBYTE pDriverInfo
  38. )
  39. {
  40. LPPROVIDOR pProvidor;
  41. WaitForSpoolerInitialization();
  42. pProvidor = pLocalProvidor;
  43. while (pProvidor) {
  44. if ((*pProvidor->PrintProvidor.fpAddPrinterDriver) (pName, Level, pDriverInfo)) {
  45. return TRUE;
  46. } else if (GetLastError() != ERROR_INVALID_NAME) {
  47. return FALSE;
  48. }
  49. pProvidor = pProvidor->pNext;
  50. }
  51. SetLastError(ERROR_INVALID_PARAMETER);
  52. return FALSE;
  53. }
  54. BOOL
  55. AddPrinterDriverExW(
  56. LPWSTR pName,
  57. DWORD Level,
  58. LPBYTE pDriverInfo,
  59. DWORD dwFileCopyFlags
  60. )
  61. {
  62. LPPROVIDOR pProvidor;
  63. WaitForSpoolerInitialization();
  64. pProvidor = pLocalProvidor;
  65. while (pProvidor) {
  66. if ((*pProvidor->PrintProvidor.fpAddPrinterDriverEx) (pName,
  67. Level,
  68. pDriverInfo,
  69. dwFileCopyFlags)) {
  70. return TRUE;
  71. } else if (GetLastError() != ERROR_INVALID_NAME) {
  72. return FALSE;
  73. }
  74. pProvidor = pProvidor->pNext;
  75. }
  76. SetLastError(ERROR_INVALID_PARAMETER);
  77. return FALSE;
  78. }
  79. BOOL
  80. AddDriverCatalog(
  81. HANDLE hPrinter,
  82. DWORD dwLevel,
  83. VOID *pvDriverInfCatInfo,
  84. DWORD dwCatalogCopyFlags
  85. )
  86. {
  87. HRESULT hRetval = E_FAIL;
  88. LPPRINTHANDLE pPrintHandle = (LPPRINTHANDLE)hPrinter;
  89. hRetval = pPrintHandle && (PRINTHANDLE_SIGNATURE == pPrintHandle->signature) ? S_OK : HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE);
  90. if (SUCCEEDED(hRetval))
  91. {
  92. hRetval = (*pPrintHandle->pProvidor->PrintProvidor.fpAddDriverCatalog) (pPrintHandle->hPrinter,
  93. dwLevel, pvDriverInfCatInfo, dwCatalogCopyFlags);
  94. }
  95. if (FAILED(hRetval))
  96. {
  97. SetLastError(HRESULT_CODE(hRetval));
  98. }
  99. return hRetval;
  100. }
  101. BOOL
  102. EnumPrinterDriversW(
  103. LPWSTR pName,
  104. LPWSTR pEnvironment,
  105. DWORD Level,
  106. LPBYTE pDrivers,
  107. DWORD cbBuf,
  108. LPDWORD pcbNeeded,
  109. LPDWORD pcReturned
  110. )
  111. {
  112. PROVIDOR *pProvidor;
  113. if ((pDrivers == NULL) && (cbBuf != 0)) {
  114. SetLastError(ERROR_INVALID_USER_BUFFER);
  115. return FALSE;
  116. }
  117. WaitForSpoolerInitialization();
  118. if (!pEnvironment || !*pEnvironment)
  119. pEnvironment = szEnvironment;
  120. pProvidor = pLocalProvidor;
  121. while (pProvidor) {
  122. if (!(*pProvidor->PrintProvidor.fpEnumPrinterDrivers) (pName, pEnvironment, Level,
  123. pDrivers, cbBuf,
  124. pcbNeeded, pcReturned)) {
  125. if (GetLastError() != ERROR_INVALID_NAME)
  126. return FALSE;
  127. } else
  128. return TRUE;
  129. pProvidor = pProvidor->pNext;
  130. }
  131. SetLastError(ERROR_INVALID_PARAMETER);
  132. return FALSE;
  133. }
  134. BOOL
  135. GetPrinterDriverDirectoryW(
  136. LPWSTR pName,
  137. LPWSTR pEnvironment,
  138. DWORD Level,
  139. LPBYTE pDriverInfo,
  140. DWORD cbBuf,
  141. LPDWORD pcbNeeded
  142. )
  143. {
  144. LPPROVIDOR pProvidor;
  145. DWORD Error;
  146. if ((pDriverInfo == NULL) && (cbBuf != 0)) {
  147. SetLastError(ERROR_INVALID_USER_BUFFER);
  148. return FALSE;
  149. }
  150. WaitForSpoolerInitialization();
  151. if (!pEnvironment || !*pEnvironment)
  152. pEnvironment = szEnvironment;
  153. pProvidor = pLocalProvidor;
  154. while (pProvidor) {
  155. if ((*pProvidor->PrintProvidor.fpGetPrinterDriverDirectory)
  156. (pName, pEnvironment, Level, pDriverInfo,
  157. cbBuf, pcbNeeded)) {
  158. return TRUE;
  159. } else if ((Error=GetLastError()) != ERROR_INVALID_NAME) {
  160. return FALSE;
  161. }
  162. pProvidor = pProvidor->pNext;
  163. }
  164. return FALSE;
  165. }
  166. BOOL
  167. DeletePrinterDriverW(
  168. LPWSTR pName,
  169. LPWSTR pEnvironment,
  170. LPWSTR pDriverName
  171. )
  172. {
  173. LPPROVIDOR pProvidor;
  174. DWORD Error;
  175. WaitForSpoolerInitialization();
  176. if (!pEnvironment || !*pEnvironment)
  177. pEnvironment = szEnvironment;
  178. pProvidor = pLocalProvidor;
  179. while (pProvidor) {
  180. if ((*pProvidor->PrintProvidor.fpDeletePrinterDriver)
  181. (pName, pEnvironment, pDriverName)) {
  182. return TRUE;
  183. } else if ((Error=GetLastError()) != ERROR_INVALID_NAME) {
  184. return FALSE;
  185. }
  186. pProvidor = pProvidor->pNext;
  187. }
  188. return FALSE;
  189. }
  190. BOOL
  191. DeletePrinterDriverExW(
  192. LPWSTR pName,
  193. LPWSTR pEnvironment,
  194. LPWSTR pDriverName,
  195. DWORD dwDeleteFlag,
  196. DWORD dwVersionNum
  197. )
  198. {
  199. LPPROVIDOR pProvidor;
  200. WaitForSpoolerInitialization();
  201. if (!pEnvironment || !*pEnvironment)
  202. pEnvironment = szEnvironment;
  203. pProvidor = pLocalProvidor;
  204. while (pProvidor) {
  205. if ((*pProvidor->PrintProvidor.fpDeletePrinterDriverEx)
  206. (pName, pEnvironment, pDriverName, dwDeleteFlag, dwVersionNum)) {
  207. return TRUE;
  208. }
  209. if (GetLastError() != ERROR_INVALID_NAME) {
  210. return FALSE;
  211. }
  212. pProvidor = pProvidor->pNext;
  213. }
  214. return FALSE;
  215. }
  216. BOOL
  217. AddPrintProcessorW(
  218. LPWSTR pName,
  219. LPWSTR pEnvironment,
  220. LPWSTR pPathName,
  221. LPWSTR pPrintProcessorName
  222. )
  223. {
  224. LPPROVIDOR pProvidor;
  225. WaitForSpoolerInitialization();
  226. if (!pEnvironment || !*pEnvironment)
  227. pEnvironment = szEnvironment;
  228. pProvidor = pLocalProvidor;
  229. while (pProvidor) {
  230. if ((*pProvidor->PrintProvidor.fpAddPrintProcessor) (pName, pEnvironment,
  231. pPathName,
  232. pPrintProcessorName)) {
  233. return TRUE;
  234. } else if (GetLastError() != ERROR_INVALID_NAME) {
  235. return FALSE;
  236. }
  237. pProvidor = pProvidor->pNext;
  238. }
  239. SetLastError(ERROR_INVALID_PARAMETER);
  240. return FALSE;
  241. }
  242. BOOL
  243. EnumPrintProcessorsW(
  244. LPWSTR pName,
  245. LPWSTR pEnvironment,
  246. DWORD Level,
  247. LPBYTE pPrintProcessors,
  248. DWORD cbBuf,
  249. LPDWORD pcbNeeded,
  250. LPDWORD pcReturned
  251. )
  252. {
  253. LPPROVIDOR pProvidor;
  254. if ((pPrintProcessors == NULL) && (cbBuf != 0)) {
  255. SetLastError(ERROR_INVALID_USER_BUFFER);
  256. return FALSE;
  257. }
  258. WaitForSpoolerInitialization();
  259. if (!pEnvironment || !*pEnvironment)
  260. pEnvironment = szEnvironment;
  261. pProvidor = pLocalProvidor;
  262. while (pProvidor) {
  263. if (!(*pProvidor->PrintProvidor.fpEnumPrintProcessors) (pName, pEnvironment, Level,
  264. pPrintProcessors, cbBuf,
  265. pcbNeeded, pcReturned)) {
  266. if (GetLastError() != ERROR_INVALID_NAME)
  267. return FALSE;
  268. } else
  269. return TRUE;
  270. pProvidor = pProvidor->pNext;
  271. }
  272. SetLastError(ERROR_INVALID_PARAMETER);
  273. return FALSE;
  274. }
  275. BOOL
  276. GetPrintProcessorDirectoryW(
  277. LPWSTR pName,
  278. LPWSTR pEnvironment,
  279. DWORD Level,
  280. LPBYTE pPrintProcessorInfo,
  281. DWORD cbBuf,
  282. LPDWORD pcbNeeded
  283. )
  284. {
  285. LPPROVIDOR pProvidor;
  286. DWORD Error;
  287. if ((pPrintProcessorInfo == NULL) && (cbBuf != 0)) {
  288. SetLastError(ERROR_INVALID_USER_BUFFER);
  289. return FALSE;
  290. }
  291. WaitForSpoolerInitialization();
  292. if (!pEnvironment || !*pEnvironment)
  293. pEnvironment = szEnvironment;
  294. pProvidor = pLocalProvidor;
  295. while (pProvidor) {
  296. if ((*pProvidor->PrintProvidor.fpGetPrintProcessorDirectory)
  297. (pName, pEnvironment, Level,
  298. pPrintProcessorInfo,
  299. cbBuf, pcbNeeded)) {
  300. return TRUE;
  301. } else if ((Error=GetLastError()) != ERROR_INVALID_NAME) {
  302. return FALSE;
  303. }
  304. pProvidor = pProvidor->pNext;
  305. }
  306. SetLastError(ERROR_INVALID_PARAMETER);
  307. return FALSE;
  308. }
  309. BOOL
  310. EnumPrintProcessorDatatypesW(
  311. LPWSTR pName,
  312. LPWSTR pPrintProcessorName,
  313. DWORD Level,
  314. LPBYTE pDatatypes,
  315. DWORD cbBuf,
  316. LPDWORD pcbNeeded,
  317. LPDWORD pcReturned
  318. )
  319. {
  320. LPPROVIDOR pProvidor;
  321. if ((pDatatypes == NULL) && (cbBuf != 0)) {
  322. SetLastError(ERROR_INVALID_USER_BUFFER);
  323. return FALSE;
  324. }
  325. WaitForSpoolerInitialization();
  326. pProvidor = pLocalProvidor;
  327. while (pProvidor) {
  328. if (!(*pProvidor->PrintProvidor.fpEnumPrintProcessorDatatypes)
  329. (pName, pPrintProcessorName,
  330. Level, pDatatypes, cbBuf,
  331. pcbNeeded, pcReturned)) {
  332. if (GetLastError() != ERROR_INVALID_NAME)
  333. return FALSE;
  334. } else
  335. return TRUE;
  336. pProvidor = pProvidor->pNext;
  337. }
  338. SetLastError(ERROR_INVALID_PARAMETER);
  339. return FALSE;
  340. }
  341. BOOL
  342. AddFormW(
  343. HANDLE hPrinter,
  344. DWORD Level,
  345. LPBYTE pForm
  346. )
  347. {
  348. LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
  349. if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
  350. SetLastError(ERROR_INVALID_HANDLE);
  351. return FALSE;
  352. }
  353. return (*pPrintHandle->pProvidor->PrintProvidor.fpAddForm) (pPrintHandle->hPrinter,
  354. Level, pForm);
  355. }
  356. BOOL
  357. DeleteFormW(
  358. HANDLE hPrinter,
  359. LPWSTR pFormName
  360. )
  361. {
  362. LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
  363. if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
  364. SetLastError(ERROR_INVALID_HANDLE);
  365. return FALSE;
  366. }
  367. return (*pPrintHandle->pProvidor->PrintProvidor.fpDeleteForm) (pPrintHandle->hPrinter,
  368. pFormName);
  369. }
  370. BOOL
  371. GetFormW(
  372. HANDLE hPrinter,
  373. LPWSTR pFormName,
  374. DWORD Level,
  375. LPBYTE pForm,
  376. DWORD cbBuf,
  377. LPDWORD pcbNeeded
  378. )
  379. {
  380. LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
  381. if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
  382. SetLastError(ERROR_INVALID_HANDLE);
  383. return FALSE;
  384. }
  385. if ((pForm == NULL) && (cbBuf != 0)) {
  386. SetLastError(ERROR_INVALID_USER_BUFFER);
  387. return FALSE;
  388. }
  389. return (*pPrintHandle->pProvidor->PrintProvidor.fpGetForm) (pPrintHandle->hPrinter,
  390. pFormName, Level, pForm,
  391. cbBuf, pcbNeeded);
  392. }
  393. BOOL
  394. SetFormW(
  395. HANDLE hPrinter,
  396. LPWSTR pFormName,
  397. DWORD Level,
  398. LPBYTE pForm
  399. )
  400. {
  401. LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
  402. if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
  403. SetLastError(ERROR_INVALID_HANDLE);
  404. return FALSE;
  405. }
  406. return (*pPrintHandle->pProvidor->PrintProvidor.fpSetForm) (pPrintHandle->hPrinter,
  407. pFormName, Level, pForm);
  408. }
  409. BOOL
  410. EnumFormsW(
  411. HANDLE hPrinter,
  412. DWORD Level,
  413. LPBYTE pForm,
  414. DWORD cbBuf,
  415. LPDWORD pcbNeeded,
  416. LPDWORD pcReturned
  417. )
  418. {
  419. LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
  420. if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
  421. SetLastError(ERROR_INVALID_HANDLE);
  422. return FALSE;
  423. }
  424. if ((pForm == NULL) && (cbBuf != 0)) {
  425. SetLastError(ERROR_INVALID_USER_BUFFER);
  426. return FALSE;
  427. }
  428. return (*pPrintHandle->pProvidor->PrintProvidor.fpEnumForms) (pPrintHandle->hPrinter,
  429. Level, pForm, cbBuf,
  430. pcbNeeded, pcReturned);
  431. }
  432. BOOL
  433. DeletePrintProcessorW(
  434. LPWSTR pName,
  435. LPWSTR pEnvironment,
  436. LPWSTR pPrintProcessorName
  437. )
  438. {
  439. LPPROVIDOR pProvidor;
  440. DWORD Error;
  441. WaitForSpoolerInitialization();
  442. if (!pEnvironment || !*pEnvironment)
  443. pEnvironment = szEnvironment;
  444. pProvidor = pLocalProvidor;
  445. while (pProvidor) {
  446. if ((*pProvidor->PrintProvidor.fpDeletePrintProcessor)
  447. (pName, pEnvironment, pPrintProcessorName)) {
  448. return TRUE;
  449. } else if ((Error=GetLastError()) != ERROR_INVALID_NAME) {
  450. return FALSE;
  451. }
  452. pProvidor = pProvidor->pNext;
  453. }
  454. return FALSE;
  455. }
  456. LPPROVIDOR FindProvidor(
  457. HKEY hProvidors,
  458. LPWSTR pName
  459. )
  460. /*++
  461. Function Description: Retrieves providor struct for a providor name.
  462. Parameters: hProvidors - handle to the Providors key
  463. pName - name of the providor
  464. Return Values: pProvidor if one is found; NULL otherwise
  465. --*/
  466. {
  467. LPPROVIDOR pProvidor;
  468. WCHAR szDllName[MAX_PATH];
  469. DWORD dwError;
  470. DWORD cbDllName;
  471. HKEY hProvidor = NULL;
  472. szDllName[0] = L'\0';
  473. cbDllName = COUNTOF(szDllName);
  474. // Search the registry for the DLL Name to compare with lpName
  475. if ((dwError = RegOpenKeyEx(hProvidors, pName, 0, KEY_READ, &hProvidor)) ||
  476. (dwError = RegQueryValueEx(hProvidor, L"Name", NULL, NULL,
  477. (LPBYTE)szDllName, &cbDllName)))
  478. {
  479. SetLastError(dwError);
  480. if (hProvidor)
  481. {
  482. RegCloseKey(hProvidor);
  483. }
  484. return NULL;
  485. }
  486. RegCloseKey(hProvidor);
  487. // Loop thru the list of providors for the name of the dll
  488. for (pProvidor = pLocalProvidor;
  489. pProvidor;
  490. pProvidor = pProvidor->pNext)
  491. {
  492. if (!_wcsicmp(pProvidor->lpName, szDllName))
  493. {
  494. break;
  495. }
  496. }
  497. return pProvidor;
  498. }
  499. // Struct to maintain the new order of the providors
  500. typedef struct _ProvidorList {
  501. struct _ProvidorList *pNext;
  502. LPPROVIDOR pProvidor;
  503. } ProvidorList;
  504. BOOL AddNodeToProvidorList(
  505. LPPROVIDOR pProvidor,
  506. ProvidorList **pStart
  507. )
  508. /*++
  509. Function Description: Adds a node to the list of providors. Avoids duplicate entries in
  510. the list
  511. Parameters: pProvidor - providor to be added
  512. pStart - pointer to the pointer to the start of the list
  513. Return Values: TRUE if successful; FALSE otherwise
  514. --*/
  515. {
  516. BOOL bReturn = FALSE;
  517. ProvidorList **pTemp, *pNew;
  518. // No providor found
  519. if (!pProvidor) {
  520. goto CleanUp;
  521. }
  522. for (pTemp = pStart; *pTemp; pTemp = &((*pTemp)->pNext))
  523. {
  524. if ((*pTemp)->pProvidor == pProvidor)
  525. {
  526. // Duplicates in the order string is an error
  527. goto CleanUp;
  528. }
  529. }
  530. // Add new node
  531. if (pNew = AllocSplMem(sizeof(ProvidorList)))
  532. {
  533. pNew->pNext = NULL;
  534. pNew->pProvidor = pProvidor;
  535. *pTemp = pNew;
  536. bReturn = TRUE;
  537. }
  538. CleanUp:
  539. return bReturn;
  540. }
  541. BOOL UpdateProvidorOrder(
  542. HKEY hProvidors,
  543. LPWSTR pOrder
  544. )
  545. /*++
  546. Function Description: Updates the order of the providors in spooler and the registry.
  547. Parameters: hProvidors - handle to Providors registry key
  548. pOrder - multisz order of providors
  549. Return Values: TRUE if successful; FALSE otherwise
  550. --*/
  551. {
  552. BOOL bReturn = FALSE, bRegChange = FALSE;
  553. DWORD dwError, dwRequired, dwBytes, dwOldCount, dwNewCount;
  554. LPWSTR pOldOrder = NULL, pStr;
  555. LPPROVIDOR pProvidor;
  556. // Maintain a list of the new order, so that error recovery is quick
  557. ProvidorList *pStart = NULL, *pTemp;
  558. // Loop thru the providor names in the new order
  559. for (pStr = pOrder, dwBytes = 0;
  560. pStr && *pStr;
  561. pStr += (wcslen(pStr) + 1))
  562. {
  563. pProvidor = FindProvidor(hProvidors, pStr);
  564. if (!AddNodeToProvidorList(pProvidor, &pStart)) {
  565. goto CleanUp;
  566. }
  567. dwBytes += (wcslen(pStr) + 1) * sizeof(WCHAR);
  568. }
  569. // Add the sizeof the last NULL char
  570. dwBytes += sizeof(WCHAR);
  571. // Make sure that all the providors are present in the list
  572. for (dwOldCount = 0, pProvidor = pLocalProvidor;
  573. pProvidor;
  574. ++dwOldCount, pProvidor = pProvidor->pNext) ;
  575. // Add 1 for the local providor which does not appear on the list
  576. for (dwNewCount = 1, pTemp = pStart;
  577. pTemp;
  578. ++dwNewCount, pTemp = pTemp->pNext) ;
  579. if (dwNewCount == dwOldCount) {
  580. // Update the registry
  581. if (dwError = RegSetValueEx(hProvidors, szOrder, 0,
  582. REG_MULTI_SZ, (LPBYTE)pOrder, dwBytes))
  583. {
  584. SetLastError(dwError);
  585. goto CleanUp;
  586. }
  587. // Change the order in the spooler structure
  588. for (pTemp = pStart, pProvidor = pLocalProvidor;
  589. pTemp;
  590. pTemp = pTemp->pNext, pProvidor = pProvidor->pNext)
  591. {
  592. pProvidor->pNext = pTemp->pProvidor;
  593. }
  594. pProvidor->pNext = NULL;
  595. bReturn = TRUE;
  596. } else {
  597. // All the providors are not listed in the order
  598. SetLastError(ERROR_INVALID_PARAMETER);
  599. }
  600. CleanUp:
  601. // Free the temp list
  602. while (pTemp = pStart) {
  603. pStart = pTemp->pNext;
  604. FreeSplMem(pTemp);
  605. }
  606. return bReturn;
  607. }
  608. BOOL AddNewProvidor(
  609. HKEY hProvidors,
  610. PPROVIDOR_INFO_1W pProvidorInfo
  611. )
  612. /*++
  613. Function Description: This function updates the registry with the new providor info and the
  614. new providor order. The new providor is appended to the current order.
  615. This order can be changed by calling AddPrintProvidor with
  616. Providor_info_2. The providor is immediately used for routing.
  617. Parameters: hProvidors - providors registry key
  618. pProvidorInfo - ProvidorInfo1 struct
  619. Return Values: TRUE if successful; FALSE otherwise
  620. --*/
  621. {
  622. BOOL bReturn = FALSE, bOrderUpdated = FALSE, bPresent = FALSE;
  623. DWORD dwError, dwRequired, dwReturned, dwOldSize, dwDisposition = 0;
  624. DWORD cchProvidorNameLen = MAX_PATH+COUNTOF(szRegistryProvidors);
  625. WCHAR szProvidorName[MAX_PATH+COUNTOF(szRegistryProvidors)];
  626. LPWSTR pOldOrder = NULL, pNewOrder = NULL;
  627. HKEY hNewProvidor = NULL;
  628. LPPROVIDOR pNewProvidor, pProvidor, pLastProvidor;
  629. if (!pProvidorInfo->pName || !pProvidorInfo->pDLLName ||
  630. !(*pProvidorInfo->pName) || !(*pProvidorInfo->pDLLName)) {
  631. SetLastError(ERROR_INVALID_PARAMETER);
  632. goto CleanUp;
  633. }
  634. for (pProvidor = pLocalProvidor; // Local Providor is always present
  635. pProvidor;
  636. pProvidor = pProvidor->pNext)
  637. {
  638. pLastProvidor = pProvidor;
  639. if (!lstrcmpi(pProvidor->lpName, pProvidorInfo->pDLLName))
  640. {
  641. //
  642. // This should return error, but it breaks some programs that
  643. // assume they can always add a provider
  644. //
  645. //SetLastError(ERROR_ALREADY_EXISTS);
  646. bReturn = TRUE;
  647. goto CleanUp;
  648. }
  649. }
  650. // Update the registry with new providor key
  651. if ((dwError = RegCreateKeyEx(hProvidors, pProvidorInfo->pName, 0, NULL, 0,
  652. KEY_ALL_ACCESS, NULL, &hNewProvidor, &dwDisposition)) ||
  653. (dwError = RegSetValueEx(hNewProvidor, L"Name", 0, REG_SZ,
  654. (LPBYTE)pProvidorInfo->pDLLName,
  655. (wcslen(pProvidorInfo->pDLLName)+1) * sizeof(WCHAR))))
  656. {
  657. SetLastError(dwError);
  658. goto CleanUp;
  659. }
  660. // Close the handle
  661. RegCloseKey(hNewProvidor);
  662. hNewProvidor = NULL;
  663. // Append to the order value
  664. dwRequired = 0;
  665. dwError = RegQueryValueEx(hProvidors, szOrder, NULL, NULL, NULL, &dwRequired);
  666. switch (dwError) {
  667. case ERROR_SUCCESS:
  668. if ((dwOldSize = dwRequired) &&
  669. (pOldOrder = AllocSplMem(dwRequired)) &&
  670. !(dwError = RegQueryValueEx(hProvidors, szOrder, NULL, NULL,
  671. (LPBYTE) pOldOrder, &dwRequired)))
  672. {
  673. break;
  674. }
  675. else
  676. {
  677. if (dwError) {
  678. SetLastError(dwError);
  679. }
  680. goto CleanUp;
  681. }
  682. case ERROR_FILE_NOT_FOUND:
  683. break;
  684. default:
  685. SetLastError(dwError);
  686. goto CleanUp;
  687. }
  688. // Append the new providor to the current order
  689. pNewOrder = (LPWSTR)AppendOrderEntry(pOldOrder, dwRequired,
  690. pProvidorInfo->pName, &dwReturned);
  691. if (!pNewOrder ||
  692. (dwError = RegSetValueEx(hProvidors, szOrder, 0,
  693. REG_MULTI_SZ, (LPBYTE)pNewOrder, dwReturned)))
  694. {
  695. if (dwError) {
  696. SetLastError(dwError);
  697. }
  698. goto CleanUp;
  699. }
  700. bOrderUpdated = TRUE;
  701. // Initialize the providor and update the spooler structure
  702. StringCchPrintf(szProvidorName,
  703. cchProvidorNameLen,
  704. L"%ws\\%ws",
  705. szRegistryProvidors,
  706. pProvidorInfo->pName);
  707. pNewProvidor = InitializeProvidor(pProvidorInfo->pDLLName, szProvidorName);
  708. if (pNewProvidor)
  709. {
  710. pNewProvidor->pNext = NULL;
  711. pLastProvidor->pNext = pNewProvidor;
  712. bReturn = TRUE;
  713. }
  714. CleanUp:
  715. // Roll back if anything fails
  716. if (!bReturn)
  717. {
  718. // Remove the new providor key if it was created
  719. if (dwDisposition == REG_CREATED_NEW_KEY)
  720. {
  721. DeleteSubKeyTree(hProvidors, pProvidorInfo->pName);
  722. RegDeleteKey(hProvidors, pProvidorInfo->pName);
  723. }
  724. // Restore the old order if it has been changed
  725. if (bOrderUpdated) {
  726. if (pOldOrder)
  727. {
  728. RegSetValueEx(hProvidors, szOrder, 0,
  729. REG_MULTI_SZ, (LPBYTE)pOldOrder, dwOldSize);
  730. }
  731. else
  732. {
  733. RegDeleteValue(hProvidors, szOrder);
  734. }
  735. }
  736. }
  737. // Free allocated memory
  738. if (pOldOrder) {
  739. FreeSplMem(pOldOrder);
  740. }
  741. if (pNewOrder) {
  742. FreeSplMem(pNewOrder);
  743. }
  744. if (hNewProvidor) {
  745. RegCloseKey(hNewProvidor);
  746. }
  747. return bReturn;
  748. }
  749. BOOL AddPrintProvidorW(
  750. LPWSTR pName,
  751. DWORD dwLevel,
  752. LPBYTE pProvidorInfo
  753. )
  754. /*++
  755. Function Description: This function adds and initializes a print providor. It also updates the
  756. registry and the order of print providors.
  757. Parameters: pName - server name for routing (currently ignored)
  758. dwLevel - providor info level
  759. pProvidorInfo - providor info buffer
  760. Return Values: TRUE if successful; FALSE otherwise
  761. --*/
  762. {
  763. BOOL bReturn = FALSE;
  764. DWORD dwError = ERROR_SUCCESS;
  765. HANDLE hToken;
  766. HKEY hProvidors = NULL;
  767. WaitForSpoolerInitialization();
  768. EnterRouterSem();
  769. // Revert to spooler security context before accessing the registry
  770. //
  771. // This is a really bad idea, as it enables any user to get system
  772. // priveleges without even trying.
  773. //
  774. // hToken = RevertToPrinterSelf();
  775. // Check for invalid parameters
  776. if (!pProvidorInfo)
  777. {
  778. SetLastError(ERROR_INVALID_PARAMETER);
  779. goto CleanUp;
  780. }
  781. if (dwError = RegCreateKeyEx(HKEY_LOCAL_MACHINE, szRegistryProvidors, 0,
  782. NULL, 0, KEY_ALL_ACCESS, NULL, &hProvidors, NULL))
  783. {
  784. SetLastError(dwError);
  785. goto CleanUp;
  786. }
  787. switch (dwLevel) {
  788. case 1:
  789. bReturn = AddNewProvidor(hProvidors,
  790. (PPROVIDOR_INFO_1W) pProvidorInfo);
  791. break;
  792. case 2:
  793. bReturn = UpdateProvidorOrder(hProvidors,
  794. ((PPROVIDOR_INFO_2W) pProvidorInfo)->pOrder);
  795. break;
  796. default:
  797. SetLastError(ERROR_INVALID_LEVEL);
  798. break;
  799. }
  800. CleanUp:
  801. if (hProvidors) {
  802. RegCloseKey(hProvidors);
  803. }
  804. if (!bReturn && !GetLastError()) {
  805. // Last error should be set by individual functions. In the event that something
  806. // is not already set, return a placeholder error code
  807. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  808. }
  809. LeaveRouterSem();
  810. // ImpersonatePrinterClient(hToken);
  811. return bReturn;
  812. }
  813. BOOL DeletePrintProvidorW(
  814. LPWSTR pName,
  815. LPWSTR pEnvironment,
  816. LPWSTR pProvidorName
  817. )
  818. /*++
  819. Function Description: Deletes a print providor by updating the registry and the
  820. removing it from the list of routing providors.
  821. Parameters: pName - server name for routing (currently ignored)
  822. pEnvironment - environment name (currently ignored)
  823. pProvidorName - providor name
  824. Return Values: TRUE if successful; FALSE otherwise
  825. --*/
  826. {
  827. BOOL bReturn = FALSE;
  828. DWORD dwError = ERROR_SUCCESS, dwRequired, dwReturned;
  829. LPWSTR pOldOrder = NULL, pNewOrder = NULL;
  830. HANDLE hToken;
  831. HKEY hProvidors = NULL;
  832. BOOL bSaveAPDPolicy = FALSE;
  833. DWORD APDValue;
  834. LPPROVIDOR pProvidor, pTemp;
  835. WaitForSpoolerInitialization();
  836. EnterRouterSem();
  837. // Revert to spooler security context before accessing the registry
  838. //
  839. // Or rather, Don't.
  840. //
  841. //hToken = RevertToPrinterSelf();
  842. // Check for invalid parameters
  843. if (!pProvidorName || !*pProvidorName)
  844. {
  845. SetLastError(ERROR_INVALID_PARAMETER);
  846. goto CleanUp;
  847. }
  848. if (dwError = RegCreateKeyEx(HKEY_LOCAL_MACHINE, szRegistryProvidors, 0,
  849. NULL, 0, KEY_ALL_ACCESS, NULL, &hProvidors, NULL))
  850. {
  851. SetLastError(dwError);
  852. goto CleanUp;
  853. }
  854. // Save the pProvidor before deleting the registry entry
  855. if (!(pProvidor = FindProvidor(hProvidors, pProvidorName)))
  856. {
  857. goto CleanUp;
  858. }
  859. // Update the order
  860. dwRequired = 0;
  861. if (dwError = RegQueryValueEx(hProvidors, szOrder, NULL, NULL, NULL, &dwRequired))
  862. {
  863. SetLastError(dwError);
  864. goto CleanUp;
  865. }
  866. if (!dwRequired ||
  867. !(pOldOrder = AllocSplMem(dwRequired)) ||
  868. (dwError = RegQueryValueEx(hProvidors, szOrder, NULL, NULL,
  869. (LPBYTE) pOldOrder, &dwRequired)))
  870. {
  871. if (dwError) {
  872. SetLastError(dwError);
  873. }
  874. goto CleanUp;
  875. }
  876. // Remove the providor from the current order
  877. pNewOrder = (LPWSTR)RemoveOrderEntry(pOldOrder, dwRequired,
  878. pProvidorName, &dwReturned);
  879. if (!pNewOrder ||
  880. (dwError = RegSetValueEx(hProvidors, szOrder, 0,
  881. REG_MULTI_SZ, (LPBYTE)pNewOrder, dwReturned)))
  882. {
  883. if (dwError) {
  884. SetLastError(dwError);
  885. }
  886. goto CleanUp;
  887. }
  888. //
  889. // The AddPrinterDrivers policy has the registry value in the wrong place
  890. // under the lanman print services key. The lanman provider is deleted
  891. // during upgrade from Windows 2000 to XP. We save the AddPrinterDrivers
  892. // value and restore it after we delete the registry tree for the provider.
  893. //
  894. if (!_wcsicmp(szLanManProvider, pProvidorName))
  895. {
  896. bSaveAPDPolicy = GetAPDPolicy(hProvidors,
  897. szAPDRelPath,
  898. szAPDValueName,
  899. &APDValue) == ERROR_SUCCESS;
  900. }
  901. //
  902. // Delete the registry key
  903. //
  904. DeleteSubKeyTree(hProvidors, pProvidorName);
  905. //
  906. // Restore the AddPrinterDrivers policy if needed.
  907. //
  908. if (bSaveAPDPolicy)
  909. {
  910. SetAPDPolicy(hProvidors,
  911. szAPDRelPath,
  912. szAPDValueName,
  913. APDValue);
  914. }
  915. // Remove from the linked list of providors for routing
  916. for (pTemp = pLocalProvidor;
  917. pTemp->pNext; // Local Providor is always present and cant be deleted
  918. pTemp = pTemp->pNext)
  919. {
  920. if (pTemp->pNext == pProvidor) {
  921. // dont release the library and the struct since they may be used in
  922. // other threads
  923. pTemp->pNext = pProvidor->pNext;
  924. break;
  925. }
  926. }
  927. bReturn = TRUE;
  928. CleanUp:
  929. if (!bReturn && !GetLastError()) {
  930. // Last error should be set by individual functions. In the event that something
  931. // is not already set, return a placeholder error code
  932. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  933. }
  934. // Free allocated memory
  935. if (pOldOrder) {
  936. FreeSplMem(pOldOrder);
  937. }
  938. if (pNewOrder) {
  939. FreeSplMem(pNewOrder);
  940. }
  941. if (hProvidors) {
  942. RegCloseKey(hProvidors);
  943. }
  944. LeaveRouterSem();
  945. // ImpersonatePrinterClient(hToken);
  946. return bReturn;
  947. }
  948. BOOL
  949. OldGetPrinterDriverW(
  950. HANDLE hPrinter,
  951. LPWSTR pEnvironment,
  952. DWORD Level,
  953. LPBYTE pDriverInfo,
  954. DWORD cbBuf,
  955. LPDWORD pcbNeeded
  956. )
  957. {
  958. LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
  959. if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
  960. SetLastError(ERROR_INVALID_HANDLE);
  961. return FALSE;
  962. }
  963. if ((pDriverInfo == NULL) && (cbBuf != 0)) {
  964. SetLastError(ERROR_INVALID_USER_BUFFER);
  965. return FALSE;
  966. }
  967. if (!pEnvironment || !*pEnvironment)
  968. pEnvironment = szEnvironment;
  969. return (*pPrintHandle->pProvidor->PrintProvidor.fpGetPrinterDriver)
  970. (pPrintHandle->hPrinter, pEnvironment,
  971. Level, pDriverInfo, cbBuf, pcbNeeded);
  972. }
  973. BOOL
  974. GetPrinterDriverExW(
  975. HANDLE hPrinter,
  976. LPWSTR pEnvironment,
  977. DWORD Level,
  978. LPBYTE pDriverInfo,
  979. DWORD cbBuf,
  980. LPDWORD pcbNeeded,
  981. DWORD dwClientMajorVersion,
  982. DWORD dwClientMinorVersion,
  983. PDWORD pdwServerMajorVersion,
  984. PDWORD pdwServerMinorVersion
  985. )
  986. {
  987. LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
  988. if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
  989. SetLastError(ERROR_INVALID_HANDLE);
  990. return FALSE;
  991. }
  992. if ((pDriverInfo == NULL) && (cbBuf != 0)) {
  993. SetLastError(ERROR_INVALID_USER_BUFFER);
  994. return FALSE;
  995. }
  996. if (!pEnvironment || !*pEnvironment)
  997. pEnvironment = szEnvironment;
  998. if (pPrintHandle->pProvidor->PrintProvidor.fpGetPrinterDriverEx) {
  999. DBGMSG(DBG_TRACE, ("Calling the fpGetPrinterDriverEx function\n"));
  1000. return (*pPrintHandle->pProvidor->PrintProvidor.fpGetPrinterDriverEx)
  1001. (pPrintHandle->hPrinter, pEnvironment,
  1002. Level, pDriverInfo, cbBuf, pcbNeeded,
  1003. dwClientMajorVersion, dwClientMinorVersion,
  1004. pdwServerMajorVersion, pdwServerMinorVersion);
  1005. } else {
  1006. //
  1007. // The print providor does not support versioning of drivers
  1008. //
  1009. DBGMSG(DBG_TRACE, ("Calling the fpGetPrinterDriver function\n"));
  1010. *pdwServerMajorVersion = 0;
  1011. *pdwServerMinorVersion = 0;
  1012. return (*pPrintHandle->pProvidor->PrintProvidor.fpGetPrinterDriver)
  1013. (pPrintHandle->hPrinter, pEnvironment,
  1014. Level, pDriverInfo, cbBuf, pcbNeeded);
  1015. }
  1016. }
  1017. BOOL
  1018. GetPrinterDriverW(
  1019. HANDLE hPrinter,
  1020. LPWSTR pEnvironment,
  1021. DWORD Level,
  1022. LPBYTE pDriverInfo,
  1023. DWORD cbBuf,
  1024. LPDWORD pcbNeeded
  1025. )
  1026. {
  1027. DWORD dwServerMajorVersion;
  1028. DWORD dwServerMinorVersion;
  1029. return GetPrinterDriverExW( hPrinter,
  1030. pEnvironment,
  1031. Level,
  1032. pDriverInfo,
  1033. cbBuf,
  1034. pcbNeeded,
  1035. (DWORD)-1,
  1036. (DWORD)-1,
  1037. &dwServerMajorVersion,
  1038. &dwServerMinorVersion );
  1039. }
  1040. BOOL
  1041. XcvDataW(
  1042. HANDLE hXcv,
  1043. PCWSTR pszDataName,
  1044. PBYTE pInputData,
  1045. DWORD cbInputData,
  1046. PBYTE pOutputData,
  1047. DWORD cbOutputData,
  1048. PDWORD pcbOutputNeeded,
  1049. PDWORD pdwStatus
  1050. )
  1051. {
  1052. LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hXcv;
  1053. if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
  1054. SetLastError(ERROR_INVALID_HANDLE);
  1055. return FALSE;
  1056. }
  1057. return (*pPrintHandle->pProvidor->PrintProvidor.fpXcvData)( pPrintHandle->hPrinter,
  1058. pszDataName,
  1059. pInputData,
  1060. cbInputData,
  1061. pOutputData,
  1062. cbOutputData,
  1063. pcbOutputNeeded,
  1064. pdwStatus);
  1065. }
  1066. /*++
  1067. Routine Name:
  1068. GetJobAttributes
  1069. Routine Description:
  1070. GetJobAttributes gets information about the job.
  1071. This includes nup and reverse printing options.
  1072. Arguments:
  1073. pPrinterName -- name of the printer.
  1074. pDevmode -- Devmode to be passed to the driver
  1075. pAttributeInfo -- buffer to place information about the job
  1076. Return Value:
  1077. TRUE if successful, FALSE otherwise.
  1078. --*/
  1079. BOOL
  1080. GetJobAttributes(
  1081. LPWSTR pPrinterName,
  1082. LPDEVMODEW pDevmode,
  1083. PATTRIBUTE_INFO_3 pAttributeInfo
  1084. )
  1085. {
  1086. HANDLE hDrvPrinter = NULL;
  1087. BOOL bReturn = FALSE, bDefault = FALSE;
  1088. FARPROC pfnDrvQueryJobAttributes;
  1089. HINSTANCE hDrvLib = NULL;
  1090. fnWinSpoolDrv fnList;
  1091. // Get the pointer to the client side functions from the router
  1092. if (!SplInitializeWinSpoolDrv(&fnList)) {
  1093. return FALSE;
  1094. }
  1095. // Get a client side printer handle to pass to the driver
  1096. if (!(* (fnList.pfnOpenPrinter))(pPrinterName, &hDrvPrinter, NULL)) {
  1097. //ODS(("Open printer failed\nPrinter %ws\n",pPrinterName));
  1098. goto CleanUp;
  1099. }
  1100. // Load the driver config file
  1101. if (!(hDrvLib = (* (fnList.pfnLoadPrinterDriver))(hDrvPrinter))) {
  1102. //ODS(("DriverDLL could not be loaded\n"));
  1103. goto CleanUp;
  1104. }
  1105. // Call the DrvQueryJobAtributes function in the driver
  1106. if (pfnDrvQueryJobAttributes = GetProcAddress(hDrvLib, "DrvQueryJobAttributes")) {
  1107. if (!(* pfnDrvQueryJobAttributes) (hDrvPrinter,
  1108. pDevmode,
  1109. 3,
  1110. (LPBYTE) pAttributeInfo)) {
  1111. if (!(* pfnDrvQueryJobAttributes) (hDrvPrinter,
  1112. pDevmode,
  1113. 2,
  1114. (LPBYTE) pAttributeInfo)) {
  1115. if (!(* pfnDrvQueryJobAttributes) (hDrvPrinter,
  1116. pDevmode,
  1117. 1,
  1118. (LPBYTE) pAttributeInfo)) {
  1119. bDefault = TRUE;
  1120. } else {
  1121. pAttributeInfo->dwColorOptimization = 0;
  1122. }
  1123. } else {
  1124. pAttributeInfo->dmPrintQuality = pDevmode->dmPrintQuality;
  1125. pAttributeInfo->dmYResolution = pDevmode->dmYResolution;
  1126. }
  1127. }
  1128. } else {
  1129. bDefault = TRUE;
  1130. }
  1131. if (bDefault) {
  1132. // Set default values for old drivers that don't export the function
  1133. pAttributeInfo->dwJobNumberOfPagesPerSide = 1;
  1134. pAttributeInfo->dwDrvNumberOfPagesPerSide = 1;
  1135. pAttributeInfo->dwNupBorderFlags = 0;
  1136. pAttributeInfo->dwJobPageOrderFlags = 0;
  1137. pAttributeInfo->dwDrvPageOrderFlags = 0;
  1138. pAttributeInfo->dwJobNumberOfCopies = pDevmode->dmCopies;
  1139. pAttributeInfo->dwDrvNumberOfCopies = pDevmode->dmCopies;
  1140. pAttributeInfo->dwColorOptimization = 0;
  1141. }
  1142. bReturn = TRUE;
  1143. CleanUp:
  1144. if (hDrvPrinter) {
  1145. (* (fnList.pfnClosePrinter))(hDrvPrinter);
  1146. }
  1147. if (hDrvLib) {
  1148. (* (fnList.pfnRefCntUnloadDriver))(hDrvLib, TRUE);
  1149. }
  1150. return bReturn;
  1151. }