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.

3808 lines
84 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. yspool.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. swilson 1-Jun-95 Converted winspool.c to yspool: the merging point of KM & RPC paths
  14. --*/
  15. #include "precomp.h"
  16. #include "server.h"
  17. #include "client.h"
  18. #include "yspool.h"
  19. #include "clusrout.h"
  20. LPWSTR szNull = L"";
  21. BOOL
  22. OldGetPrinterDriverW(
  23. HANDLE hPrinter,
  24. LPWSTR pEnvironment,
  25. DWORD Level,
  26. LPBYTE pDriverInfo,
  27. DWORD cbBuf,
  28. LPDWORD pcbNeeded
  29. );
  30. #define YRevertToSelf(rpc) (rpc != NATIVE_CALL ? RpcRevertToSelf() : 0)
  31. DWORD ServerHandleCount = 0;
  32. BOOL
  33. YImpersonateClient(CALL_ROUTE Route);
  34. VOID
  35. PrinterHandleRundown(
  36. HANDLE hPrinter);
  37. BOOL
  38. GetPrinterDriverExW(
  39. HANDLE hPrinter,
  40. LPWSTR pEnvironment,
  41. DWORD Level,
  42. LPBYTE pDriverInfo,
  43. DWORD cbBuf,
  44. LPDWORD pcbNeeded,
  45. DWORD dwClientMajorVersion,
  46. DWORD dwClientMinorVersion,
  47. PDWORD pdwServerMajorVersion,
  48. PDWORD pdwServerMinorVersion);
  49. BOOL
  50. OpenPrinterExW(
  51. LPWSTR pPrinterName,
  52. HANDLE *pHandle,
  53. LPPRINTER_DEFAULTS pDefault,
  54. PSPLCLIENT_CONTAINER pSplClientContainer
  55. );
  56. HANDLE
  57. AddPrinterExW(
  58. LPWSTR pName,
  59. DWORD Level,
  60. LPBYTE pPrinter,
  61. LPBYTE pClientInfo,
  62. DWORD dwLevel
  63. );
  64. BOOL
  65. SpoolerInit(
  66. VOID);
  67. /*++
  68. Name:
  69. IsValidMultiSz
  70. Description:
  71. This function accepts strings of length 0 or 1 as valid multi sz. The code in yspool
  72. that calls this function uses szNull instead of pszString subsequently, if cch is 0 or 1.
  73. Theoretically, a string with one character is not a valid multi sz.
  74. Arguments:
  75. pszString - array of WCHARs
  76. cch - count of WCHARs in the array
  77. Return Value:
  78. TRUE - the multi sz is valid
  79. FALSE - the string does not represent a valid multi sz
  80. --*/
  81. BOOL
  82. IsValidMultiSz(
  83. IN PWSTR pszString,
  84. IN DWORD cch
  85. )
  86. {
  87. DWORD Error = ERROR_INVALID_PARAMETER;
  88. if (cch == 0 || cch == 1)
  89. {
  90. Error = ERROR_SUCCESS;
  91. }
  92. else
  93. {
  94. if (pszString[cch - 1] == L'\0' && pszString[cch - 2] == L'\0')
  95. {
  96. Error = ERROR_SUCCESS;
  97. }
  98. }
  99. return Error == ERROR_SUCCESS;
  100. }
  101. BOOL
  102. InvalidDevModeContainer(
  103. LPDEVMODE_CONTAINER pDevModeContainer
  104. )
  105. {
  106. BOOL bRetValue = TRUE;
  107. if(pDevModeContainer)
  108. {
  109. bRetValue = FALSE;
  110. if (pDevModeContainer->pDevMode)
  111. {
  112. bRetValue = !BoolFromHResult(SplIsValidDevmodeW((PDEVMODE) pDevModeContainer->pDevMode,
  113. pDevModeContainer->cbBuf));
  114. }
  115. }
  116. return bRetValue;
  117. }
  118. BOOL
  119. InvalidSecurityContainer(
  120. PSECURITY_CONTAINER pSecurityContainer
  121. )
  122. {
  123. SECURITY_DESCRIPTOR_CONTROL SecurityDescriptorControl;
  124. DWORD dwRevision;
  125. if(!pSecurityContainer ||
  126. (pSecurityContainer->pSecurity &&
  127. !RtlValidRelativeSecurityDescriptor((SECURITY_DESCRIPTOR *)pSecurityContainer->pSecurity,
  128. pSecurityContainer->cbBuf,
  129. 0)))
  130. {
  131. return TRUE;
  132. }
  133. return FALSE;
  134. }
  135. BOOL
  136. ValidatePortVarContainer(
  137. PPORT_VAR_CONTAINER pPortVarContainer
  138. )
  139. {
  140. return !!pPortVarContainer;
  141. }
  142. BOOL
  143. ValidatePortContainer(
  144. LPPORT_CONTAINER pPortContainer
  145. )
  146. {
  147. return pPortContainer && pPortContainer->PortInfo.pPortInfo1;
  148. }
  149. BOOL
  150. ValidatePrinterContainer(
  151. PPRINTER_CONTAINER pPrinterContainer
  152. )
  153. {
  154. return pPrinterContainer && pPrinterContainer->PrinterInfo.pPrinterInfo1;
  155. }
  156. BOOL
  157. ValidateMonitorContainer(
  158. LPMONITOR_CONTAINER pMonitorContainer
  159. )
  160. {
  161. return pMonitorContainer && pMonitorContainer->MonitorInfo.pMonitorInfo2;
  162. }
  163. DWORD
  164. YEnumPrinters(
  165. DWORD Flags,
  166. LPWSTR Name,
  167. DWORD Level,
  168. LPBYTE pPrinterEnum,
  169. DWORD cbBuf,
  170. LPDWORD pcbNeeded,
  171. LPDWORD pcReturned,
  172. CALL_ROUTE Route
  173. )
  174. { FieldInfo* pFieldInfo;
  175. DWORD cReturned, cbStruct;
  176. DWORD Error=ERROR_INVALID_NAME;
  177. DWORD BufferSize=cbBuf;
  178. BOOL bRet;
  179. LPBYTE pAlignedBuff;
  180. switch (Level) {
  181. case STRESSINFOLEVEL:
  182. pFieldInfo = PrinterInfoStressFields;
  183. cbStruct = sizeof(PRINTER_INFO_STRESS);
  184. break;
  185. case 1:
  186. pFieldInfo = PrinterInfo1Fields;
  187. cbStruct = sizeof(PRINTER_INFO_1);
  188. break;
  189. case 2:
  190. pFieldInfo = PrinterInfo2Fields;
  191. cbStruct = sizeof(PRINTER_INFO_2);
  192. break;
  193. case 4:
  194. pFieldInfo = PrinterInfo4Fields;
  195. cbStruct = sizeof(PRINTER_INFO_4);
  196. break;
  197. case 5:
  198. pFieldInfo = PrinterInfo5Fields;
  199. cbStruct = sizeof(PRINTER_INFO_5);
  200. break;
  201. default:
  202. return ERROR_INVALID_LEVEL;
  203. }
  204. if (!YImpersonateClient(Route))
  205. return GetLastError();
  206. pAlignedBuff = AlignRpcPtr(pPrinterEnum, &cbBuf);
  207. if ( pPrinterEnum && !pAlignedBuff ){
  208. YRevertToSelf(Route);
  209. return GetLastError();
  210. }
  211. bRet = EnumPrinters(Flags, Name, Level, pAlignedBuff,
  212. cbBuf, pcbNeeded, pcReturned);
  213. YRevertToSelf(Route);
  214. if (bRet) {
  215. bRet = MarshallDownStructuresArray(pAlignedBuff, *pcReturned, pFieldInfo, cbStruct, Route);
  216. }
  217. UndoAlignRpcPtr(pPrinterEnum, pAlignedBuff, cbBuf, pcbNeeded);
  218. return bRet ? ERROR_SUCCESS : GetLastError();
  219. }
  220. DWORD
  221. YOpenPrinter(
  222. LPWSTR pPrinterName,
  223. HANDLE *phPrinter,
  224. LPWSTR pDatatype,
  225. LPDEVMODE_CONTAINER pDevModeContainer,
  226. DWORD AccessRequired,
  227. CALL_ROUTE Route
  228. )
  229. {
  230. PRINTER_DEFAULTS Defaults;
  231. BOOL bRet;
  232. if (!YImpersonateClient(Route))
  233. return GetLastError();
  234. if ( InvalidDevModeContainer(pDevModeContainer) ) {
  235. YRevertToSelf(Route);
  236. return ERROR_INVALID_PARAMETER;
  237. }
  238. Defaults.pDatatype = pDatatype;
  239. Defaults.pDevMode = (LPDEVMODE)pDevModeContainer->pDevMode;
  240. Defaults.DesiredAccess = AccessRequired;
  241. bRet = OpenPrinterW(pPrinterName, phPrinter, &Defaults);
  242. YRevertToSelf(Route);
  243. if (bRet) {
  244. InterlockedIncrement ( &ServerHandleCount );
  245. return ERROR_SUCCESS;
  246. } else {
  247. *phPrinter = NULL;
  248. return GetLastError();
  249. }
  250. }
  251. DWORD
  252. YOpenPrinterEx(
  253. LPWSTR pPrinterName,
  254. HANDLE *phPrinter,
  255. LPWSTR pDatatype,
  256. LPDEVMODE_CONTAINER pDevModeContainer,
  257. DWORD AccessRequired,
  258. CALL_ROUTE Route,
  259. PSPLCLIENT_CONTAINER pSplClientContainer
  260. )
  261. {
  262. PRINTER_DEFAULTS Defaults;
  263. BOOL bRet;
  264. if (!YImpersonateClient(Route))
  265. return GetLastError();
  266. if ( InvalidDevModeContainer(pDevModeContainer) ) {
  267. YRevertToSelf(Route);
  268. return ERROR_INVALID_PARAMETER;
  269. }
  270. Defaults.pDatatype = pDatatype;
  271. Defaults.pDevMode = (LPDEVMODE)pDevModeContainer->pDevMode;
  272. Defaults.DesiredAccess = AccessRequired;
  273. bRet = OpenPrinterExW(pPrinterName,
  274. phPrinter,
  275. &Defaults,
  276. pSplClientContainer);
  277. YRevertToSelf(Route);
  278. if (bRet) {
  279. InterlockedIncrement ( &ServerHandleCount );
  280. return ERROR_SUCCESS;
  281. } else {
  282. *phPrinter = NULL;
  283. return GetLastError();
  284. }
  285. }
  286. DWORD
  287. YResetPrinter(
  288. HANDLE hPrinter,
  289. LPWSTR pDatatype,
  290. LPDEVMODE_CONTAINER pDevModeContainer,
  291. CALL_ROUTE Route
  292. )
  293. {
  294. PRINTER_DEFAULTS Defaults;
  295. BOOL bRet;
  296. if (!YImpersonateClient(Route))
  297. return GetLastError();
  298. if ( InvalidDevModeContainer(pDevModeContainer) ) {
  299. YRevertToSelf(Route);
  300. return ERROR_INVALID_PARAMETER;
  301. }
  302. Defaults.pDatatype = pDatatype;
  303. Defaults.pDevMode = (LPDEVMODE)pDevModeContainer->pDevMode;
  304. //
  305. // You cannot change the Access Mask on a Printer Spool Object
  306. // We will always ignore this parameter and set it to zero
  307. // We get some random garbage otherwise.
  308. //
  309. Defaults.DesiredAccess = 0;
  310. bRet = ResetPrinter(hPrinter, &Defaults);
  311. YRevertToSelf(Route);
  312. if (bRet)
  313. return ERROR_SUCCESS;
  314. else
  315. return GetLastError();
  316. }
  317. DWORD
  318. YSetJob(
  319. HANDLE hPrinter,
  320. DWORD JobId,
  321. JOB_CONTAINER *pJobContainer,
  322. DWORD Command,
  323. CALL_ROUTE Route
  324. )
  325. /*++
  326. Routine Description:
  327. This function will modify the settings of the specified Print Job.
  328. Arguments:
  329. lpJob - Points to a valid JOB structure containing at least a valid
  330. lpPrinter, and JobId.
  331. Command - Specifies the operation to perform on the specified Job. A value
  332. of FALSE indicates that only the elements of the JOB structure are to
  333. be examined and set.
  334. Return Value:
  335. TRUE - The operation was successful.
  336. FALSE/NULL - The operation failed. Extended error status is available
  337. using GetLastError.
  338. --*/
  339. {
  340. BOOL bRet;
  341. if (!YImpersonateClient(Route))
  342. return GetLastError();
  343. bRet = SetJob(hPrinter, JobId, pJobContainer ? pJobContainer->Level : 0,
  344. pJobContainer ? (LPBYTE)pJobContainer->JobInfo.Level1 : NULL,
  345. Command);
  346. YRevertToSelf(Route);
  347. if (bRet)
  348. return ERROR_SUCCESS;
  349. else
  350. return GetLastError();
  351. }
  352. DWORD
  353. YGetJob(
  354. HANDLE hPrinter,
  355. DWORD JobId,
  356. DWORD Level,
  357. LPBYTE pJob,
  358. DWORD cbBuf,
  359. LPDWORD pcbNeeded,
  360. CALL_ROUTE Route
  361. )
  362. /*++
  363. Routine Description:
  364. This function will retrieve the settings of the specified Print Job.
  365. Arguments:
  366. lpJob - Points to a valid JOB structure containing at least a valid
  367. lpPrinter, and JobId.
  368. Return Value:
  369. TRUE - The operation was successful.
  370. FALSE/NULL - The operation failed. Extended error status is available
  371. using GetLastError.
  372. --*/
  373. {
  374. BOOL bRet;
  375. SIZE_T cbStruct;
  376. FieldInfo *pFieldInfo;
  377. LPBYTE pAlignedBuff;
  378. switch (Level) {
  379. case 1:
  380. pFieldInfo = JobInfo1Fields;
  381. cbStruct = sizeof(JOB_INFO_1);
  382. break;
  383. case 2:
  384. pFieldInfo = JobInfo2Fields;
  385. cbStruct = sizeof(JOB_INFO_2);
  386. break;
  387. case 3:
  388. pFieldInfo = JobInfo3Fields;
  389. cbStruct = sizeof(JOB_INFO_3);
  390. break;
  391. default:
  392. return ERROR_INVALID_LEVEL;
  393. }
  394. if (!YImpersonateClient(Route))
  395. return GetLastError();
  396. pAlignedBuff = AlignRpcPtr(pJob, &cbBuf);
  397. if (pJob && !pAlignedBuff){
  398. YRevertToSelf(Route);
  399. return GetLastError();
  400. }
  401. bRet = GetJob(hPrinter, JobId, Level, pAlignedBuff, cbBuf, pcbNeeded);
  402. YRevertToSelf(Route);
  403. if (bRet) {
  404. if (Route) {
  405. bRet = MarshallDownStructure(pAlignedBuff, pFieldInfo, cbStruct, Route);
  406. }
  407. }
  408. UndoAlignRpcPtr(pJob, pAlignedBuff, cbBuf, pcbNeeded);
  409. return bRet ? ERROR_SUCCESS : GetLastError();
  410. }
  411. DWORD
  412. YEnumJobs(
  413. HANDLE hPrinter,
  414. DWORD FirstJob,
  415. DWORD NoJobs,
  416. DWORD Level,
  417. LPBYTE pJob,
  418. DWORD cbBuf,
  419. LPDWORD pcbNeeded,
  420. LPDWORD pcReturned,
  421. CALL_ROUTE Route
  422. )
  423. {
  424. FieldInfo *pFieldInfo;
  425. DWORD cReturned, cbStruct;
  426. BOOL bRet;
  427. LPBYTE pAlignedBuff;
  428. switch (Level) {
  429. case 1:
  430. pFieldInfo = JobInfo1Fields;
  431. cbStruct = sizeof(JOB_INFO_1);
  432. break;
  433. case 2:
  434. pFieldInfo = JobInfo2Fields;
  435. cbStruct = sizeof(JOB_INFO_2);
  436. break;
  437. case 3:
  438. pFieldInfo = JobInfo3Fields;
  439. cbStruct = sizeof(JOB_INFO_3);
  440. break;
  441. default:
  442. return ERROR_INVALID_LEVEL;
  443. }
  444. if (!YImpersonateClient(Route))
  445. return GetLastError();
  446. pAlignedBuff = AlignRpcPtr(pJob, &cbBuf);
  447. if (pJob && !pAlignedBuff){
  448. YRevertToSelf(Route);
  449. return GetLastError();
  450. }
  451. bRet = EnumJobs(hPrinter, FirstJob, NoJobs, Level, pAlignedBuff,
  452. cbBuf, pcbNeeded, pcReturned);
  453. YRevertToSelf(Route);
  454. if (bRet) {
  455. bRet = MarshallDownStructuresArray(pAlignedBuff, *pcReturned, pFieldInfo, cbStruct, Route);
  456. }
  457. UndoAlignRpcPtr(pJob, pAlignedBuff, cbBuf, pcbNeeded);
  458. return bRet ? ERROR_SUCCESS : GetLastError();
  459. }
  460. DWORD
  461. YAddPrinter(
  462. LPWSTR pName,
  463. PPRINTER_CONTAINER pPrinterContainer,
  464. PDEVMODE_CONTAINER pDevModeContainer,
  465. PSECURITY_CONTAINER pSecurityContainer,
  466. HANDLE *phPrinter,
  467. CALL_ROUTE Route
  468. )
  469. {
  470. if (!YImpersonateClient(Route))
  471. return GetLastError();
  472. if(!ValidatePrinterContainer(pPrinterContainer) ||
  473. InvalidDevModeContainer(pDevModeContainer))
  474. {
  475. YRevertToSelf(Route);
  476. return ERROR_INVALID_PARAMETER;
  477. }
  478. if (pPrinterContainer->Level == 2)
  479. {
  480. if(!pPrinterContainer->PrinterInfo.pPrinterInfo2 ||
  481. (pSecurityContainer->pSecurity &&
  482. InvalidSecurityContainer(pSecurityContainer)))
  483. {
  484. return ERROR_INVALID_PARAMETER;
  485. }
  486. pPrinterContainer->PrinterInfo.pPrinterInfo2->pDevMode =
  487. (LPDEVMODE)pDevModeContainer->pDevMode;
  488. pPrinterContainer->PrinterInfo.pPrinterInfo2->pSecurityDescriptor =
  489. (PSECURITY_DESCRIPTOR)pSecurityContainer->pSecurity;
  490. }
  491. *phPrinter = AddPrinter(pName, pPrinterContainer->Level,
  492. (LPBYTE)pPrinterContainer->PrinterInfo.pPrinterInfo1);
  493. YRevertToSelf(Route);
  494. if (*phPrinter) {
  495. InterlockedIncrement( &ServerHandleCount );
  496. return ERROR_SUCCESS;
  497. } else
  498. return GetLastError();
  499. }
  500. DWORD
  501. YAddPrinterEx(
  502. LPWSTR pName,
  503. PPRINTER_CONTAINER pPrinterContainer,
  504. PDEVMODE_CONTAINER pDevModeContainer,
  505. PSECURITY_CONTAINER pSecurityContainer,
  506. HANDLE *phPrinter,
  507. CALL_ROUTE Route,
  508. PSPLCLIENT_CONTAINER pSplClientContainer
  509. )
  510. {
  511. if (!YImpersonateClient(Route))
  512. return GetLastError();
  513. if(!ValidatePrinterContainer(pPrinterContainer) ||
  514. InvalidDevModeContainer(pDevModeContainer))
  515. {
  516. YRevertToSelf(Route);
  517. return ERROR_INVALID_PARAMETER;
  518. }
  519. if (pPrinterContainer->Level == 2)
  520. {
  521. if(!pPrinterContainer->PrinterInfo.pPrinterInfo2 ||
  522. (pSecurityContainer->pSecurity &&
  523. InvalidSecurityContainer(pSecurityContainer)))
  524. {
  525. return ERROR_INVALID_PARAMETER;
  526. }
  527. pPrinterContainer->PrinterInfo.pPrinterInfo2->pDevMode =
  528. (LPDEVMODE)pDevModeContainer->pDevMode;
  529. pPrinterContainer->PrinterInfo.pPrinterInfo2->pSecurityDescriptor =
  530. (PSECURITY_DESCRIPTOR)pSecurityContainer->pSecurity;
  531. }
  532. *phPrinter = AddPrinterExW(pName,
  533. pPrinterContainer->Level,
  534. (LPBYTE)pPrinterContainer->PrinterInfo.pPrinterInfo1,
  535. (LPBYTE)pSplClientContainer->ClientInfo.pClientInfo1,
  536. pSplClientContainer->Level);
  537. YRevertToSelf(Route);
  538. if (*phPrinter) {
  539. InterlockedIncrement( &ServerHandleCount );
  540. return ERROR_SUCCESS;
  541. } else
  542. return GetLastError();
  543. }
  544. DWORD
  545. YDeletePrinter(
  546. HANDLE hPrinter,
  547. CALL_ROUTE Route
  548. )
  549. {
  550. BOOL bRet;
  551. if (!YImpersonateClient(Route))
  552. return GetLastError();
  553. bRet = DeletePrinter(hPrinter);
  554. YRevertToSelf(Route);
  555. if (bRet)
  556. return ERROR_SUCCESS;
  557. else
  558. return GetLastError();
  559. }
  560. DWORD
  561. YAddPrinterConnection(
  562. LPWSTR pName,
  563. CALL_ROUTE Route
  564. )
  565. {
  566. BOOL bRet;
  567. if (!YImpersonateClient(Route))
  568. return GetLastError();
  569. bRet = AddPrinterConnection(pName);
  570. YRevertToSelf(Route);
  571. if (bRet)
  572. return ERROR_SUCCESS;
  573. else
  574. return GetLastError();
  575. }
  576. DWORD
  577. YDeletePrinterConnection(
  578. LPWSTR pName,
  579. CALL_ROUTE Route
  580. )
  581. {
  582. BOOL bRet;
  583. if (!YImpersonateClient(Route))
  584. return GetLastError();
  585. bRet = DeletePrinterConnection(pName);
  586. YRevertToSelf(Route);
  587. if (bRet)
  588. return ERROR_SUCCESS;
  589. else
  590. return GetLastError();
  591. }
  592. DWORD
  593. YSetPrinter(
  594. HANDLE hPrinter,
  595. PPRINTER_CONTAINER pPrinterContainer,
  596. PDEVMODE_CONTAINER pDevModeContainer,
  597. PSECURITY_CONTAINER pSecurityContainer,
  598. DWORD Command,
  599. CALL_ROUTE Route
  600. )
  601. {
  602. BOOL bRet;
  603. if (!YImpersonateClient(Route))
  604. return GetLastError();
  605. if(!pPrinterContainer ||
  606. (pPrinterContainer->Level && !ValidatePrinterContainer(pPrinterContainer)) ||
  607. InvalidDevModeContainer(pDevModeContainer))
  608. {
  609. YRevertToSelf(Route);
  610. return ERROR_INVALID_PARAMETER;
  611. }
  612. if (InvalidSecurityContainer(pSecurityContainer)) {
  613. YRevertToSelf(Route);
  614. return ERROR_INVALID_PARAMETER;
  615. }
  616. switch (pPrinterContainer->Level) {
  617. case 2:
  618. pPrinterContainer->PrinterInfo.pPrinterInfo2->pDevMode =
  619. (LPDEVMODE)pDevModeContainer->pDevMode;
  620. pPrinterContainer->PrinterInfo.pPrinterInfo2->pSecurityDescriptor =
  621. (PSECURITY_DESCRIPTOR)pSecurityContainer->pSecurity;
  622. break;
  623. case 3:
  624. pPrinterContainer->PrinterInfo.pPrinterInfo3->pSecurityDescriptor =
  625. (PSECURITY_DESCRIPTOR)pSecurityContainer->pSecurity;
  626. break;
  627. case 8:
  628. pPrinterContainer->PrinterInfo.pPrinterInfo8->pDevMode =
  629. (LPDEVMODE)pDevModeContainer->pDevMode;
  630. break;
  631. case 9:
  632. pPrinterContainer->PrinterInfo.pPrinterInfo9->pDevMode =
  633. (LPDEVMODE)pDevModeContainer->pDevMode;
  634. break;
  635. default:
  636. break;
  637. }
  638. bRet = SetPrinter(hPrinter, pPrinterContainer->Level,
  639. (LPBYTE)pPrinterContainer->PrinterInfo.pPrinterInfo1,
  640. Command);
  641. YRevertToSelf(Route);
  642. if (bRet)
  643. return ERROR_SUCCESS;
  644. else
  645. return GetLastError();
  646. }
  647. DWORD
  648. YGetPrinter(
  649. HANDLE hPrinter,
  650. DWORD Level,
  651. LPBYTE pPrinter,
  652. DWORD cbBuf,
  653. LPDWORD pcbNeeded,
  654. CALL_ROUTE Route
  655. )
  656. {
  657. FieldInfo *pFieldInfo;
  658. BOOL ReturnValue;
  659. DWORD *pOffsets;
  660. SIZE_T cbStruct;
  661. LPBYTE pAlignedBuff;
  662. *pcbNeeded = 0;
  663. switch (Level) {
  664. case STRESSINFOLEVEL:
  665. pFieldInfo = PrinterInfoStressFields;
  666. cbStruct = sizeof(PRINTER_INFO_STRESS);
  667. break;
  668. case 1:
  669. pFieldInfo = PrinterInfo1Fields;
  670. cbStruct = sizeof(PRINTER_INFO_1);
  671. break;
  672. case 2:
  673. pFieldInfo = PrinterInfo2Fields;
  674. cbStruct = sizeof(PRINTER_INFO_2);
  675. break;
  676. case 3:
  677. pFieldInfo = PrinterInfo3Fields;
  678. cbStruct = sizeof(PRINTER_INFO_3);
  679. break;
  680. case 4:
  681. pFieldInfo = PrinterInfo4Fields;
  682. cbStruct = sizeof(PRINTER_INFO_4);
  683. break;
  684. case 5:
  685. pFieldInfo = PrinterInfo5Fields;
  686. cbStruct = sizeof(PRINTER_INFO_5);
  687. break;
  688. case 6:
  689. pFieldInfo = PrinterInfo6Fields;
  690. cbStruct = sizeof(PRINTER_INFO_6);
  691. break;
  692. case 7:
  693. pFieldInfo = PrinterInfo7Fields;
  694. cbStruct = sizeof(PRINTER_INFO_7);
  695. break;
  696. case 8:
  697. pFieldInfo = PrinterInfo8Fields;
  698. cbStruct = sizeof(PRINTER_INFO_8);
  699. break;
  700. case 9:
  701. pFieldInfo = PrinterInfo9Fields;
  702. cbStruct = sizeof(PRINTER_INFO_9);
  703. break;
  704. default:
  705. return ERROR_INVALID_LEVEL;
  706. }
  707. if (!YImpersonateClient(Route))
  708. return GetLastError();
  709. pAlignedBuff = AlignRpcPtr(pPrinter, &cbBuf);
  710. if (pPrinter && !pAlignedBuff){
  711. YRevertToSelf(Route);
  712. return GetLastError();
  713. }
  714. ReturnValue = GetPrinter(hPrinter, Level, pAlignedBuff, cbBuf, pcbNeeded);
  715. YRevertToSelf(Route);
  716. if (ReturnValue) {
  717. ReturnValue = MarshallDownStructure(pAlignedBuff, pFieldInfo, cbStruct, Route);
  718. }
  719. UndoAlignRpcPtr(pPrinter, pAlignedBuff, cbBuf, pcbNeeded);
  720. return ReturnValue ? ERROR_SUCCESS : GetLastError();
  721. }
  722. DWORD
  723. YAddPrinterDriver(
  724. LPWSTR pName,
  725. LPDRIVER_CONTAINER pDriverContainer,
  726. CALL_ROUTE Route
  727. )
  728. {
  729. PDRIVER_INFO_4 pDriverInfo4 = NULL;
  730. BOOL bRet = FALSE;
  731. LPRPC_DRIVER_INFO_4W pRpcDriverInfo4;
  732. if(!pDriverContainer)
  733. {
  734. return ERROR_INVALID_PARAMETER;
  735. }
  736. if (!YImpersonateClient(Route))
  737. return GetLastError();
  738. switch (pDriverContainer->Level) {
  739. case 2:
  740. bRet = AddPrinterDriver(pName,
  741. pDriverContainer->Level,
  742. (LPBYTE)pDriverContainer->DriverInfo.Level2);
  743. break;
  744. case 3:
  745. case 4:
  746. if (!pDriverContainer->DriverInfo.Level4)
  747. {
  748. SetLastError(ERROR_INVALID_PARAMETER);
  749. goto Error;
  750. }
  751. pDriverInfo4 = (PDRIVER_INFO_4) AllocSplMem(sizeof(DRIVER_INFO_4));
  752. if ( !pDriverInfo4 ) {
  753. goto Error;
  754. }
  755. pRpcDriverInfo4 = (LPRPC_DRIVER_INFO_4W) pDriverContainer->DriverInfo.Level4;
  756. if (!pRpcDriverInfo4 ||
  757. !IsValidMultiSz(pRpcDriverInfo4->pDependentFiles, pRpcDriverInfo4->cchDependentFiles) ||
  758. pDriverContainer->Level != 3 && !IsValidMultiSz(pRpcDriverInfo4->pszzPreviousNames, pRpcDriverInfo4->cchPreviousNames))
  759. {
  760. FreeSplMem(pDriverInfo4);
  761. SetLastError(ERROR_INVALID_PARAMETER);
  762. goto Error;
  763. }
  764. pDriverInfo4->cVersion = pRpcDriverInfo4->cVersion;
  765. pDriverInfo4->pName = pRpcDriverInfo4->pName;
  766. pDriverInfo4->pEnvironment = pRpcDriverInfo4->pEnvironment;
  767. pDriverInfo4->pDriverPath = pRpcDriverInfo4->pDriverPath;
  768. pDriverInfo4->pDataFile = pRpcDriverInfo4->pDataFile;
  769. pDriverInfo4->pConfigFile = pRpcDriverInfo4->pConfigFile;
  770. pDriverInfo4->pHelpFile = pRpcDriverInfo4->pHelpFile;
  771. pDriverInfo4->pMonitorName = pRpcDriverInfo4->pMonitorName;
  772. pDriverInfo4->pDefaultDataType = pRpcDriverInfo4->pDefaultDataType;
  773. //
  774. // Use szNULL if the DependentFiles string contains nothing
  775. //
  776. if ((pRpcDriverInfo4->cchDependentFiles == 0) ||
  777. (pRpcDriverInfo4->cchDependentFiles == 1)) {
  778. pDriverInfo4->pDependentFiles = szNull;
  779. } else {
  780. pDriverInfo4->pDependentFiles = pRpcDriverInfo4->pDependentFiles
  781. ;
  782. }
  783. if ( pDriverContainer->Level == 4 ) {
  784. if ( pRpcDriverInfo4->cchPreviousNames == 0 ||
  785. pRpcDriverInfo4->cchPreviousNames == 1 )
  786. pDriverInfo4->pszzPreviousNames = szNull;
  787. else
  788. pDriverInfo4->pszzPreviousNames
  789. = pRpcDriverInfo4->pszzPreviousNames;
  790. }
  791. bRet = AddPrinterDriver(pName,
  792. pDriverContainer->Level,
  793. (LPBYTE) pDriverInfo4);
  794. FreeSplMem(pDriverInfo4);
  795. break;
  796. default:
  797. YRevertToSelf(Route);
  798. return ERROR_INVALID_LEVEL;
  799. }
  800. Error:
  801. YRevertToSelf(Route);
  802. if (bRet)
  803. return ERROR_SUCCESS;
  804. else
  805. return GetLastError();
  806. }
  807. DWORD
  808. YAddPrinterDriverEx(
  809. LPWSTR pName,
  810. LPDRIVER_CONTAINER pDriverContainer,
  811. DWORD dwFileCopyFlags,
  812. CALL_ROUTE Route
  813. )
  814. {
  815. BOOL bRet = FALSE;
  816. PDRIVER_INFO_6 pDriverInfo6 = NULL;
  817. LPRPC_DRIVER_INFO_6W pRpcDriverInfo6;
  818. if(!pDriverContainer)
  819. {
  820. return ERROR_INVALID_PARAMETER;
  821. }
  822. if (!YImpersonateClient(Route))
  823. return GetLastError();
  824. switch (pDriverContainer->Level) {
  825. case 2:
  826. bRet = AddPrinterDriverEx(pName,
  827. pDriverContainer->Level,
  828. (LPBYTE)pDriverContainer->DriverInfo.Level2,
  829. dwFileCopyFlags);
  830. break;
  831. case 3:
  832. case 4:
  833. case 6:
  834. if (!pDriverContainer->DriverInfo.Level6)
  835. {
  836. SetLastError(ERROR_INVALID_PARAMETER);
  837. goto Error;
  838. }
  839. pDriverInfo6 = (PDRIVER_INFO_6) AllocSplMem(sizeof(DRIVER_INFO_6));
  840. if ( !pDriverInfo6 ) {
  841. bRet = FALSE;
  842. goto Error;
  843. }
  844. pRpcDriverInfo6 = (LPRPC_DRIVER_INFO_6W) pDriverContainer->DriverInfo.Level6;
  845. if (!pRpcDriverInfo6 ||
  846. !IsValidMultiSz(pRpcDriverInfo6->pDependentFiles, pRpcDriverInfo6->cchDependentFiles) ||
  847. pDriverContainer->Level != 3 && !IsValidMultiSz(pRpcDriverInfo6->pszzPreviousNames, pRpcDriverInfo6->cchPreviousNames))
  848. {
  849. FreeSplMem(pRpcDriverInfo6);
  850. SetLastError(ERROR_INVALID_PARAMETER);
  851. goto Error;
  852. }
  853. pDriverInfo6->cVersion = pRpcDriverInfo6->cVersion;
  854. pDriverInfo6->pName = pRpcDriverInfo6->pName;
  855. pDriverInfo6->pEnvironment = pRpcDriverInfo6->pEnvironment;
  856. pDriverInfo6->pDriverPath = pRpcDriverInfo6->pDriverPath;
  857. pDriverInfo6->pDataFile = pRpcDriverInfo6->pDataFile;
  858. pDriverInfo6->pConfigFile = pRpcDriverInfo6->pConfigFile;
  859. pDriverInfo6->pHelpFile = pRpcDriverInfo6->pHelpFile;
  860. pDriverInfo6->pMonitorName = pRpcDriverInfo6->pMonitorName;
  861. pDriverInfo6->pDefaultDataType = pRpcDriverInfo6->pDefaultDataType;
  862. //
  863. // Use szNULL if the DependentFiles string contains nothing
  864. //
  865. if ((pRpcDriverInfo6->cchDependentFiles == 0) ||
  866. (pRpcDriverInfo6->cchDependentFiles == 1)) {
  867. pDriverInfo6->pDependentFiles = szNull;
  868. } else {
  869. pDriverInfo6->pDependentFiles = pRpcDriverInfo6->pDependentFiles;
  870. }
  871. if ( pDriverContainer->Level == 4 || pDriverContainer->Level == 6 ) {
  872. if ( pRpcDriverInfo6->cchPreviousNames == 0 ||
  873. pRpcDriverInfo6->cchPreviousNames == 1 )
  874. pDriverInfo6->pszzPreviousNames = szNull;
  875. else
  876. pDriverInfo6->pszzPreviousNames
  877. = pRpcDriverInfo6->pszzPreviousNames;
  878. }
  879. if ( pDriverContainer->Level == 6 ) {
  880. pDriverInfo6->ftDriverDate = pRpcDriverInfo6->ftDriverDate;
  881. pDriverInfo6->dwlDriverVersion = pRpcDriverInfo6->dwlDriverVersion;
  882. pDriverInfo6->pszMfgName = pRpcDriverInfo6->pMfgName;
  883. pDriverInfo6->pszOEMUrl = pRpcDriverInfo6->pOEMUrl;
  884. pDriverInfo6->pszHardwareID = pRpcDriverInfo6->pHardwareID;
  885. pDriverInfo6->pszProvider = pRpcDriverInfo6->pProvider;
  886. }
  887. bRet = AddPrinterDriverEx(pName,
  888. pDriverContainer->Level,
  889. (LPBYTE) pDriverInfo6,
  890. dwFileCopyFlags);
  891. FreeSplMem(pDriverInfo6);
  892. break;
  893. default:
  894. YRevertToSelf(Route);
  895. return ERROR_INVALID_LEVEL;
  896. }
  897. Error:
  898. YRevertToSelf(Route);
  899. if (bRet)
  900. return ERROR_SUCCESS;
  901. else
  902. return GetLastError();
  903. }
  904. DWORD
  905. YAddDriverCatalog(
  906. HANDLE hPrinter,
  907. DRIVER_INFCAT_CONTAINER *pDriverInfCatContainer,
  908. DWORD dwCatalogCopyFlags,
  909. CALL_ROUTE Route
  910. )
  911. {
  912. BOOL bRet = FALSE;
  913. if (!pDriverInfCatContainer)
  914. {
  915. SetLastError(ERROR_INVALID_PARAMETER);
  916. goto Cleanup;
  917. }
  918. if (!YImpersonateClient(Route))
  919. {
  920. goto Cleanup;
  921. }
  922. switch (pDriverInfCatContainer->dwLevel)
  923. {
  924. case 1:
  925. bRet = AddDriverCatalog(hPrinter,
  926. pDriverInfCatContainer->dwLevel,
  927. pDriverInfCatContainer->DriverInfCatInfo.pDriverInfCatInfo1,
  928. dwCatalogCopyFlags);
  929. break;
  930. case 2:
  931. bRet = AddDriverCatalog(hPrinter,
  932. pDriverInfCatContainer->dwLevel,
  933. pDriverInfCatContainer->DriverInfCatInfo.pDriverInfCatInfo2,
  934. dwCatalogCopyFlags);
  935. break;
  936. default:
  937. SetLastError(ERROR_INVALID_LEVEL);
  938. break;
  939. }
  940. YRevertToSelf(Route);
  941. Cleanup:
  942. if (bRet)
  943. return ERROR_SUCCESS;
  944. else
  945. return GetLastError();
  946. }
  947. DWORD
  948. YEnumPrinterDrivers(
  949. LPWSTR pName,
  950. LPWSTR pEnvironment,
  951. DWORD Level,
  952. LPBYTE pDrivers,
  953. DWORD cbBuf,
  954. LPDWORD pcbNeeded,
  955. LPDWORD pcReturned,
  956. CALL_ROUTE Route
  957. )
  958. {
  959. DWORD cReturned, cbStruct;
  960. BOOL bRet;
  961. FieldInfo *pFieldInfo;
  962. LPBYTE pAlignedBuff;
  963. switch (Level) {
  964. case 1:
  965. pFieldInfo = DriverInfo1Fields;
  966. cbStruct = sizeof(DRIVER_INFO_1);
  967. break;
  968. case 2:
  969. pFieldInfo = DriverInfo2Fields;
  970. cbStruct = sizeof(DRIVER_INFO_2);
  971. break;
  972. case 3:
  973. pFieldInfo = DriverInfo3Fields;
  974. cbStruct = sizeof(DRIVER_INFO_3);
  975. break;
  976. case 4:
  977. pFieldInfo = DriverInfo4Fields;
  978. cbStruct = sizeof(DRIVER_INFO_4);
  979. break;
  980. case 5:
  981. pFieldInfo = DriverInfo5Fields;
  982. cbStruct = sizeof(DRIVER_INFO_5);
  983. break;
  984. case 6:
  985. pFieldInfo = DriverInfo6Fields;
  986. cbStruct = sizeof(DRIVER_INFO_6);
  987. break;
  988. }
  989. if (!YImpersonateClient(Route))
  990. return GetLastError();
  991. pAlignedBuff = AlignRpcPtr(pDrivers, &cbBuf);
  992. if (pDrivers && !pAlignedBuff){
  993. YRevertToSelf(Route);
  994. return GetLastError();
  995. }
  996. bRet = EnumPrinterDrivers(pName, pEnvironment, Level, pAlignedBuff,
  997. cbBuf, pcbNeeded, pcReturned);
  998. YRevertToSelf(Route);
  999. if (bRet) {
  1000. bRet = MarshallDownStructuresArray(pAlignedBuff, *pcReturned, pFieldInfo, cbStruct, Route);
  1001. }
  1002. UndoAlignRpcPtr(pDrivers, pAlignedBuff, cbBuf, pcbNeeded);
  1003. return bRet ? ERROR_SUCCESS : GetLastError();
  1004. }
  1005. DWORD
  1006. YGetPrinterDriver(
  1007. HANDLE hPrinter,
  1008. LPWSTR pEnvironment,
  1009. DWORD Level,
  1010. LPBYTE pDriverInfo,
  1011. DWORD cbBuf,
  1012. LPDWORD pcbNeeded,
  1013. CALL_ROUTE Route
  1014. )
  1015. {
  1016. FieldInfo *pFieldInfo;
  1017. BOOL bRet;
  1018. DWORD dwServerMajorVersion;
  1019. DWORD dwServerMinorVersion;
  1020. SIZE_T cbStruct;
  1021. LPBYTE pAlignedBuff;
  1022. switch (Level) {
  1023. case 1:
  1024. pFieldInfo = DriverInfo1Fields;
  1025. cbStruct = sizeof(DRIVER_INFO_1);
  1026. break;
  1027. case 2:
  1028. pFieldInfo = DriverInfo2Fields;
  1029. cbStruct = sizeof(DRIVER_INFO_2);
  1030. break;
  1031. case 3:
  1032. pFieldInfo = DriverInfo3Fields;
  1033. cbStruct = sizeof(DRIVER_INFO_3);
  1034. break;
  1035. case 4:
  1036. pFieldInfo = DriverInfo4Fields;
  1037. cbStruct = sizeof(DRIVER_INFO_4);
  1038. break;
  1039. case 6:
  1040. pFieldInfo = DriverInfo6Fields;
  1041. cbStruct = sizeof(DRIVER_INFO_6);
  1042. break;
  1043. default:
  1044. return ERROR_INVALID_LEVEL;
  1045. }
  1046. if (!YImpersonateClient(Route))
  1047. return GetLastError();
  1048. pAlignedBuff = AlignRpcPtr(pDriverInfo, &cbBuf);
  1049. if (pDriverInfo && !pAlignedBuff){
  1050. YRevertToSelf(Route);
  1051. return GetLastError();
  1052. }
  1053. if ( Route ) {
  1054. //
  1055. // If they are Remote using the old api the don't want versioning
  1056. //
  1057. bRet = OldGetPrinterDriverW(hPrinter, pEnvironment, Level, pAlignedBuff,
  1058. cbBuf, pcbNeeded);
  1059. } else {
  1060. bRet = GetPrinterDriverExW(hPrinter, pEnvironment, Level, pAlignedBuff,
  1061. cbBuf, pcbNeeded, (DWORD)-1, (DWORD)-1,
  1062. &dwServerMajorVersion, &dwServerMinorVersion);
  1063. }
  1064. YRevertToSelf(Route);
  1065. if (bRet) {
  1066. bRet = MarshallDownStructure(pAlignedBuff, pFieldInfo, cbStruct, Route);
  1067. }
  1068. UndoAlignRpcPtr(pDriverInfo, pAlignedBuff, cbBuf, pcbNeeded);
  1069. return bRet ? ERROR_SUCCESS : GetLastError();
  1070. }
  1071. DWORD
  1072. YGetPrinterDriverDirectory(
  1073. LPWSTR pName,
  1074. LPWSTR pEnvironment,
  1075. DWORD Level,
  1076. LPBYTE pDriverInfo,
  1077. DWORD cbBuf,
  1078. LPDWORD pcbNeeded,
  1079. CALL_ROUTE Route
  1080. )
  1081. {
  1082. BOOL bRet;
  1083. if (!YImpersonateClient(Route))
  1084. return GetLastError();
  1085. bRet = GetPrinterDriverDirectory(pName, pEnvironment, Level,
  1086. pDriverInfo, cbBuf, pcbNeeded);
  1087. YRevertToSelf(Route);
  1088. if (bRet) {
  1089. return ERROR_SUCCESS;
  1090. } else
  1091. return GetLastError();
  1092. }
  1093. DWORD
  1094. YDeletePrinterDriver(
  1095. LPWSTR pName,
  1096. LPWSTR pEnvironment,
  1097. LPWSTR pDriverName,
  1098. CALL_ROUTE Route
  1099. )
  1100. {
  1101. BOOL bRet;
  1102. if (!YImpersonateClient(Route))
  1103. return GetLastError();
  1104. bRet = DeletePrinterDriverW(pName, pEnvironment, pDriverName);
  1105. YRevertToSelf(Route);
  1106. if (bRet) {
  1107. return ERROR_SUCCESS;
  1108. } else
  1109. return GetLastError();
  1110. }
  1111. DWORD
  1112. YDeletePrinterDriverEx(
  1113. LPWSTR pName,
  1114. LPWSTR pEnvironment,
  1115. LPWSTR pDriverName,
  1116. DWORD dwDeleteFlag,
  1117. DWORD dwVersionNum,
  1118. CALL_ROUTE Route
  1119. )
  1120. {
  1121. BOOL bRet;
  1122. if (!YImpersonateClient(Route))
  1123. return GetLastError();
  1124. bRet = DeletePrinterDriverExW(pName, pEnvironment, pDriverName,
  1125. dwDeleteFlag, dwVersionNum);
  1126. YRevertToSelf(Route);
  1127. if (bRet) {
  1128. return ERROR_SUCCESS;
  1129. } else
  1130. return GetLastError();
  1131. }
  1132. DWORD
  1133. YAddPerMachineConnection(
  1134. LPWSTR pServer,
  1135. LPCWSTR pPrinterName,
  1136. LPCWSTR pPrintServer,
  1137. LPCWSTR pProvider,
  1138. CALL_ROUTE Route
  1139. )
  1140. {
  1141. BOOL bRet;
  1142. if (!YImpersonateClient(Route))
  1143. return GetLastError();
  1144. bRet = AddPerMachineConnection(pServer, pPrinterName, pPrintServer, pProvider);
  1145. YRevertToSelf(Route);
  1146. if (bRet) {
  1147. return ERROR_SUCCESS;
  1148. } else
  1149. return GetLastError();
  1150. }
  1151. DWORD
  1152. YDeletePerMachineConnection(
  1153. LPWSTR pServer,
  1154. LPCWSTR pPrinterName,
  1155. CALL_ROUTE Route
  1156. )
  1157. {
  1158. BOOL bRet;
  1159. if (!YImpersonateClient(Route))
  1160. return GetLastError();
  1161. bRet = DeletePerMachineConnection(pServer, pPrinterName);
  1162. YRevertToSelf(Route);
  1163. if (bRet) {
  1164. return ERROR_SUCCESS;
  1165. } else
  1166. return GetLastError();
  1167. }
  1168. DWORD
  1169. YEnumPerMachineConnections(
  1170. LPWSTR pServer,
  1171. LPBYTE pPrinterEnum,
  1172. DWORD cbBuf,
  1173. LPDWORD pcbNeeded,
  1174. LPDWORD pcReturned,
  1175. CALL_ROUTE Route
  1176. )
  1177. {
  1178. DWORD cReturned, cbStruct;
  1179. FieldInfo *pFieldInfo;
  1180. BOOL bRet;
  1181. LPBYTE pAlignedBuff;
  1182. pFieldInfo = PrinterInfo4Fields;
  1183. cbStruct = sizeof(PRINTER_INFO_4);
  1184. if (!YImpersonateClient(Route))
  1185. return GetLastError();
  1186. pAlignedBuff = AlignRpcPtr(pPrinterEnum, &cbBuf);
  1187. if (pPrinterEnum && !pAlignedBuff){
  1188. YRevertToSelf(Route);
  1189. return GetLastError();
  1190. }
  1191. bRet = EnumPerMachineConnections(pServer,
  1192. pAlignedBuff,
  1193. cbBuf,
  1194. pcbNeeded,
  1195. pcReturned);
  1196. YRevertToSelf(Route);
  1197. if (bRet) {
  1198. bRet = MarshallDownStructuresArray(pAlignedBuff, *pcReturned, pFieldInfo, cbStruct, Route );
  1199. }
  1200. UndoAlignRpcPtr(pPrinterEnum, pAlignedBuff, cbBuf, pcbNeeded);
  1201. return bRet ? ERROR_SUCCESS : GetLastError();
  1202. }
  1203. DWORD
  1204. YAddPrintProcessor(
  1205. LPWSTR pName,
  1206. LPWSTR pEnvironment,
  1207. LPWSTR pPathName,
  1208. LPWSTR pPrintProcessorName,
  1209. CALL_ROUTE Route
  1210. )
  1211. {
  1212. BOOL bRet;
  1213. if (!YImpersonateClient(Route))
  1214. return GetLastError();
  1215. bRet = AddPrintProcessor(pName, pEnvironment, pPathName,
  1216. pPrintProcessorName);
  1217. YRevertToSelf(Route);
  1218. if (bRet) {
  1219. return ERROR_SUCCESS;
  1220. } else {
  1221. return GetLastError();
  1222. }
  1223. }
  1224. DWORD
  1225. YEnumPrintProcessors(
  1226. LPWSTR pName,
  1227. LPWSTR pEnvironment,
  1228. DWORD Level,
  1229. LPBYTE pPrintProcessors,
  1230. DWORD cbBuf,
  1231. LPDWORD pcbNeeded,
  1232. LPDWORD pcReturned,
  1233. CALL_ROUTE Route
  1234. )
  1235. {
  1236. DWORD cReturned, cbStruct;
  1237. FieldInfo *pFieldInfo;
  1238. BOOL bRet;
  1239. LPBYTE pAlignedBuff;
  1240. switch (Level) {
  1241. case 1:
  1242. pFieldInfo = PrintProcessorInfo1Fields;
  1243. cbStruct = sizeof(PRINTPROCESSOR_INFO_1);
  1244. break;
  1245. default:
  1246. return ERROR_INVALID_LEVEL;
  1247. }
  1248. if (!YImpersonateClient(Route))
  1249. return GetLastError();
  1250. pAlignedBuff = AlignRpcPtr(pPrintProcessors, &cbBuf);
  1251. if (pPrintProcessors && !pAlignedBuff){
  1252. YRevertToSelf(Route);
  1253. return GetLastError();
  1254. }
  1255. bRet = EnumPrintProcessors(pName, pEnvironment, Level,
  1256. pAlignedBuff, cbBuf, pcbNeeded, pcReturned);
  1257. YRevertToSelf(Route);
  1258. if (bRet) {
  1259. bRet = MarshallDownStructuresArray(pAlignedBuff, *pcReturned, pFieldInfo, cbStruct ,Route );
  1260. }
  1261. UndoAlignRpcPtr(pPrintProcessors, pAlignedBuff, cbBuf, pcbNeeded);
  1262. return bRet ? ERROR_SUCCESS : GetLastError();
  1263. }
  1264. DWORD
  1265. YGetPrintProcessorDirectory(
  1266. LPWSTR pName,
  1267. LPWSTR pEnvironment,
  1268. DWORD Level,
  1269. LPBYTE pPrintProcessorInfo,
  1270. DWORD cbBuf,
  1271. LPDWORD pcbNeeded,
  1272. CALL_ROUTE Route
  1273. )
  1274. {
  1275. BOOL bRet;
  1276. if (!YImpersonateClient(Route))
  1277. return GetLastError();
  1278. bRet = GetPrintProcessorDirectory(pName, pEnvironment, Level,
  1279. pPrintProcessorInfo, cbBuf, pcbNeeded);
  1280. YRevertToSelf(Route);
  1281. if (bRet) {
  1282. return ERROR_SUCCESS;
  1283. } else
  1284. return GetLastError();
  1285. }
  1286. DWORD
  1287. YEnumPrintProcessorDatatypes(
  1288. LPWSTR pName,
  1289. LPWSTR pPrintProcessorName,
  1290. DWORD Level,
  1291. LPBYTE pDatatypes,
  1292. DWORD cbBuf,
  1293. LPDWORD pcbNeeded,
  1294. LPDWORD pcReturned,
  1295. CALL_ROUTE Route
  1296. )
  1297. {
  1298. DWORD cReturned,cbStruct;
  1299. FieldInfo *pFieldInfo;
  1300. BOOL bRet;
  1301. LPBYTE pAlignedBuff;
  1302. switch (Level) {
  1303. case 1:
  1304. pFieldInfo = DatatypeInfo1Fields;
  1305. cbStruct = sizeof(DATATYPES_INFO_1);
  1306. break;
  1307. default:
  1308. return ERROR_INVALID_LEVEL;
  1309. }
  1310. if (!YImpersonateClient(Route))
  1311. return GetLastError();
  1312. pAlignedBuff = AlignRpcPtr(pDatatypes, &cbBuf);
  1313. if (pDatatypes && !pAlignedBuff){
  1314. YRevertToSelf(Route);
  1315. return GetLastError();
  1316. }
  1317. bRet = EnumPrintProcessorDatatypes(pName, pPrintProcessorName,
  1318. Level, pAlignedBuff, cbBuf,
  1319. pcbNeeded, pcReturned);
  1320. YRevertToSelf(Route);
  1321. if (bRet) {
  1322. bRet = MarshallDownStructuresArray(pAlignedBuff, *pcReturned, pFieldInfo, cbStruct, Route);
  1323. }
  1324. UndoAlignRpcPtr(pDatatypes, pAlignedBuff, cbBuf, pcbNeeded);
  1325. return bRet ? ERROR_SUCCESS : GetLastError();
  1326. }
  1327. DWORD
  1328. YStartDocPrinter(
  1329. HANDLE hPrinter,
  1330. LPDOC_INFO_CONTAINER pDocInfoContainer,
  1331. LPDWORD pJobId,
  1332. CALL_ROUTE Route
  1333. )
  1334. {
  1335. LPWSTR pChar;
  1336. if( !pDocInfoContainer || pDocInfoContainer->Level != 1 ){
  1337. RaiseException( ERROR_INVALID_USER_BUFFER,
  1338. EXCEPTION_NONCONTINUABLE,
  1339. 0,
  1340. NULL );
  1341. }
  1342. try
  1343. {
  1344. if(pDocInfoContainer->DocInfo.pDocInfo1)
  1345. {
  1346. if( pDocInfoContainer->DocInfo.pDocInfo1->pDocName )
  1347. {
  1348. for( pChar = pDocInfoContainer->DocInfo.pDocInfo1->pDocName;
  1349. *pChar;
  1350. ++pChar )
  1351. ;
  1352. }
  1353. if( pDocInfoContainer->DocInfo.pDocInfo1->pOutputFile )
  1354. {
  1355. for( pChar = pDocInfoContainer->DocInfo.pDocInfo1->pOutputFile;
  1356. *pChar;
  1357. ++pChar )
  1358. ;
  1359. }
  1360. if( pDocInfoContainer->DocInfo.pDocInfo1->pDatatype )
  1361. {
  1362. for( pChar = pDocInfoContainer->DocInfo.pDocInfo1->pDatatype;
  1363. *pChar;
  1364. ++pChar )
  1365. ;
  1366. }
  1367. }
  1368. }
  1369. except( EXCEPTION_EXECUTE_HANDLER )
  1370. {
  1371. RaiseException( ERROR_INVALID_USER_BUFFER,
  1372. EXCEPTION_NONCONTINUABLE,
  1373. 0,
  1374. NULL );
  1375. }
  1376. if (!YImpersonateClient(Route))
  1377. return GetLastError();
  1378. *pJobId = StartDocPrinter(hPrinter, pDocInfoContainer->Level,
  1379. (LPBYTE)pDocInfoContainer->DocInfo.pDocInfo1);
  1380. YRevertToSelf(Route);
  1381. if (*pJobId)
  1382. return ERROR_SUCCESS;
  1383. else
  1384. return GetLastError();
  1385. }
  1386. DWORD
  1387. YStartPagePrinter(
  1388. HANDLE hPrinter,
  1389. CALL_ROUTE Route
  1390. )
  1391. {
  1392. BOOL bRet;
  1393. if (!YImpersonateClient(Route))
  1394. return GetLastError();
  1395. bRet = StartPagePrinter(hPrinter);
  1396. YRevertToSelf(Route);
  1397. if (bRet)
  1398. return ERROR_SUCCESS;
  1399. else
  1400. return GetLastError();
  1401. }
  1402. DWORD
  1403. YWritePrinter(
  1404. HANDLE hPrinter,
  1405. LPBYTE pBuf,
  1406. DWORD cbBuf,
  1407. LPDWORD pcWritten,
  1408. CALL_ROUTE Route
  1409. )
  1410. {
  1411. BOOL bRet;
  1412. if (!YImpersonateClient(Route))
  1413. return GetLastError();
  1414. bRet = WritePrinter(hPrinter, pBuf, cbBuf, pcWritten);
  1415. YRevertToSelf(Route);
  1416. if (bRet)
  1417. return ERROR_SUCCESS;
  1418. else
  1419. return GetLastError();
  1420. }
  1421. DWORD
  1422. YSeekPrinter(
  1423. HANDLE hPrinter,
  1424. LARGE_INTEGER liDistanceToMove,
  1425. PLARGE_INTEGER pliNewPointer,
  1426. DWORD dwMoveMethod,
  1427. BOOL bWritePrinter,
  1428. CALL_ROUTE Route
  1429. )
  1430. {
  1431. BOOL bRet;
  1432. if (!YImpersonateClient(Route))
  1433. return GetLastError();
  1434. bRet = SeekPrinter( hPrinter,
  1435. liDistanceToMove,
  1436. pliNewPointer,
  1437. dwMoveMethod,
  1438. bWritePrinter );
  1439. YRevertToSelf(Route);
  1440. if (bRet)
  1441. return ERROR_SUCCESS;
  1442. else
  1443. return GetLastError();
  1444. }
  1445. DWORD
  1446. YFlushPrinter(
  1447. HANDLE hPrinter,
  1448. LPBYTE pBuf,
  1449. DWORD cbBuf,
  1450. LPDWORD pcWritten,
  1451. DWORD cSleep,
  1452. CALL_ROUTE Route
  1453. )
  1454. {
  1455. BOOL bRet;
  1456. if (!YImpersonateClient(Route))
  1457. return GetLastError();
  1458. bRet = FlushPrinter(hPrinter, pBuf, cbBuf, pcWritten, cSleep);
  1459. YRevertToSelf(Route);
  1460. if (bRet)
  1461. return ERROR_SUCCESS;
  1462. else
  1463. return GetLastError();
  1464. }
  1465. DWORD
  1466. YEndPagePrinter(
  1467. HANDLE hPrinter,
  1468. CALL_ROUTE Route
  1469. )
  1470. {
  1471. BOOL bRet;
  1472. if (!YImpersonateClient(Route))
  1473. return GetLastError();
  1474. bRet = EndPagePrinter(hPrinter);
  1475. YRevertToSelf(Route);
  1476. if (bRet)
  1477. return ERROR_SUCCESS;
  1478. else
  1479. return GetLastError();
  1480. }
  1481. DWORD
  1482. YAbortPrinter(
  1483. HANDLE hPrinter,
  1484. CALL_ROUTE Route
  1485. )
  1486. {
  1487. BOOL bRet;
  1488. if (!YImpersonateClient(Route))
  1489. return GetLastError();
  1490. bRet = AbortPrinter(hPrinter);
  1491. YRevertToSelf(Route);
  1492. if (bRet)
  1493. return ERROR_SUCCESS;
  1494. else
  1495. return GetLastError();
  1496. }
  1497. DWORD
  1498. YReadPrinter(
  1499. HANDLE hPrinter,
  1500. LPBYTE pBuf,
  1501. DWORD cbBuf,
  1502. LPDWORD pRead,
  1503. CALL_ROUTE Route
  1504. )
  1505. {
  1506. BOOL bRet;
  1507. if (!YImpersonateClient(Route))
  1508. return GetLastError();
  1509. bRet = ReadPrinter(hPrinter, pBuf, cbBuf, pRead);
  1510. YRevertToSelf(Route);
  1511. if (bRet)
  1512. return ERROR_SUCCESS;
  1513. else
  1514. return GetLastError();
  1515. }
  1516. DWORD
  1517. YSplReadPrinter(
  1518. HANDLE hPrinter,
  1519. LPBYTE *pBuf,
  1520. DWORD cbBuf,
  1521. CALL_ROUTE Route
  1522. )
  1523. {
  1524. BOOL bRet;
  1525. // Currently SplReadPrinter is internal and does not come thru RPC.
  1526. if (!YImpersonateClient(Route))
  1527. return GetLastError();
  1528. bRet = SplReadPrinter(hPrinter, pBuf, cbBuf);
  1529. YRevertToSelf(Route);
  1530. if (bRet)
  1531. return ERROR_SUCCESS;
  1532. else
  1533. return GetLastError();
  1534. }
  1535. VOID StartDriverUnload( LPVOID pDriverFile )
  1536. {
  1537. SplDriverUnloadComplete((LPWSTR) pDriverFile);
  1538. if (pDriverFile) {
  1539. FreeSplMem(pDriverFile);
  1540. }
  1541. return;
  1542. }
  1543. VOID
  1544. YDriverUnloadComplete(
  1545. LPWSTR pDriverFile
  1546. )
  1547. {
  1548. HANDLE hThread;
  1549. DWORD dwThreadId;
  1550. LPWSTR pDriverFileCopy = NULL;
  1551. // Copy the string for passing it to another thread
  1552. if (pDriverFile && *pDriverFile) {
  1553. pDriverFileCopy = AllocSplStr(pDriverFile);
  1554. }
  1555. if (!pDriverFileCopy) {
  1556. return;
  1557. }
  1558. // Create a thread to process driver unload and return ASAP
  1559. hThread = CreateThread(NULL,
  1560. LARGE_INITIAL_STACK_COMMIT,
  1561. (LPTHREAD_START_ROUTINE) StartDriverUnload,
  1562. (LPVOID) pDriverFileCopy,
  1563. 0,
  1564. &dwThreadId);
  1565. if (hThread) {
  1566. CloseHandle(hThread);
  1567. } else {
  1568. // thread did not spawn, free resources
  1569. FreeSplStr(pDriverFileCopy);
  1570. }
  1571. return;
  1572. }
  1573. DWORD
  1574. YEndDocPrinter(
  1575. HANDLE hPrinter,
  1576. CALL_ROUTE Route
  1577. )
  1578. {
  1579. BOOL bRet;
  1580. if (!YImpersonateClient(Route))
  1581. return GetLastError();
  1582. bRet = EndDocPrinter(hPrinter);
  1583. YRevertToSelf(Route);
  1584. if (bRet)
  1585. return ERROR_SUCCESS;
  1586. else
  1587. return GetLastError();
  1588. }
  1589. DWORD
  1590. YAddJob(
  1591. HANDLE hPrinter,
  1592. DWORD Level,
  1593. LPBYTE pAddJob,
  1594. DWORD cbBuf,
  1595. LPDWORD pcbNeeded,
  1596. CALL_ROUTE Route
  1597. )
  1598. {
  1599. BOOL bRet;
  1600. LPBYTE pAlignedBuff;
  1601. DWORD cbStruct;
  1602. FieldInfo *pFieldInfo;
  1603. switch (Level) {
  1604. case 1:
  1605. pFieldInfo = AddJobFields;
  1606. cbStruct = sizeof(ADDJOB_INFO_1W);
  1607. break;
  1608. case 2:
  1609. case 3:
  1610. pFieldInfo = AddJob2Fields;
  1611. cbStruct = sizeof(ADDJOB_INFO_2W);
  1612. break;
  1613. default:
  1614. return ERROR_INVALID_LEVEL;
  1615. }
  1616. if (!YImpersonateClient(Route))
  1617. return GetLastError();
  1618. pAlignedBuff = AlignRpcPtr(pAddJob, &cbBuf);
  1619. if (pAddJob && !pAlignedBuff){
  1620. YRevertToSelf(Route);
  1621. return GetLastError();
  1622. }
  1623. bRet = AddJob(hPrinter, Level, pAlignedBuff, cbBuf, pcbNeeded);
  1624. YRevertToSelf(Route);
  1625. if (bRet) {
  1626. if (Route) {
  1627. bRet = MarshallDownStructure(pAlignedBuff, pFieldInfo, sizeof(cbStruct), Route);
  1628. }
  1629. }
  1630. UndoAlignRpcPtr(pAddJob, pAlignedBuff, cbBuf, pcbNeeded);
  1631. return bRet ? ERROR_SUCCESS : GetLastError();
  1632. }
  1633. DWORD
  1634. YScheduleJob(
  1635. HANDLE hPrinter,
  1636. DWORD JobId,
  1637. CALL_ROUTE Route
  1638. )
  1639. {
  1640. BOOL bRet;
  1641. if (!YImpersonateClient(Route))
  1642. return GetLastError();
  1643. bRet = ScheduleJob(hPrinter, JobId);
  1644. YRevertToSelf(Route);
  1645. if (bRet)
  1646. return ERROR_SUCCESS;
  1647. else
  1648. return GetLastError();
  1649. }
  1650. DWORD
  1651. YGetPrinterData(
  1652. HANDLE hPrinter,
  1653. LPTSTR pValueName,
  1654. LPDWORD pType,
  1655. LPBYTE pData,
  1656. DWORD nSize,
  1657. LPDWORD pcbNeeded,
  1658. CALL_ROUTE Route
  1659. )
  1660. {
  1661. DWORD dwRet;
  1662. if (!YImpersonateClient(Route))
  1663. return GetLastError();
  1664. dwRet = GetPrinterData(hPrinter, pValueName, pType,
  1665. pData, nSize, pcbNeeded);
  1666. YRevertToSelf(Route);
  1667. return dwRet;
  1668. }
  1669. DWORD
  1670. YGetPrinterDataEx(
  1671. HANDLE hPrinter,
  1672. LPCTSTR pKeyName,
  1673. LPCTSTR pValueName,
  1674. LPDWORD pType,
  1675. LPBYTE pData,
  1676. DWORD nSize,
  1677. LPDWORD pcbNeeded,
  1678. CALL_ROUTE Route
  1679. )
  1680. {
  1681. DWORD dwRet;
  1682. if (!YImpersonateClient(Route))
  1683. return GetLastError();
  1684. dwRet = GetPrinterDataEx(hPrinter, pKeyName,pValueName, pType,
  1685. pData, nSize, pcbNeeded);
  1686. YRevertToSelf(Route);
  1687. return dwRet;
  1688. }
  1689. DWORD
  1690. YEnumPrinterData(
  1691. HANDLE hPrinter,
  1692. DWORD dwIndex, // index of value to query
  1693. LPWSTR pValueName, // address of buffer for value string
  1694. DWORD cbValueName, // size of value buffer
  1695. LPDWORD pcbValueName, // address for size of value buffer
  1696. LPDWORD pType, // address of buffer for type code
  1697. LPBYTE pData, // address of buffer for value data
  1698. DWORD cbData, // size of data buffer
  1699. LPDWORD pcbData, // address for size of data buffer
  1700. CALL_ROUTE Route // where this call comes from
  1701. )
  1702. {
  1703. DWORD dwRet;
  1704. if (!YImpersonateClient(Route))
  1705. return GetLastError();
  1706. dwRet = EnumPrinterData(hPrinter,
  1707. dwIndex,
  1708. pValueName,
  1709. cbValueName,
  1710. pcbValueName,
  1711. pType,
  1712. pData,
  1713. cbData,
  1714. pcbData);
  1715. YRevertToSelf(Route);
  1716. return dwRet;
  1717. }
  1718. DWORD
  1719. YEnumPrinterDataEx(
  1720. HANDLE hPrinter,
  1721. LPCWSTR pKeyName, // address of key name
  1722. LPBYTE pEnumValues,
  1723. DWORD cbEnumValues,
  1724. LPDWORD pcbEnumValues,
  1725. LPDWORD pnEnumValues,
  1726. CALL_ROUTE Route
  1727. )
  1728. {
  1729. DWORD dwRet;
  1730. DWORD cReturned;
  1731. PPRINTER_ENUM_VALUES pEnumValue = (PPRINTER_ENUM_VALUES) pEnumValues;
  1732. LPBYTE pAlignedBuff;
  1733. if (!YImpersonateClient(Route))
  1734. return GetLastError();
  1735. pAlignedBuff = AlignRpcPtr(pEnumValues, &cbEnumValues);
  1736. if (pEnumValues && !pAlignedBuff){
  1737. YRevertToSelf(Route);
  1738. return GetLastError();
  1739. }
  1740. dwRet = EnumPrinterDataEx( hPrinter,
  1741. pKeyName,
  1742. pAlignedBuff,
  1743. cbEnumValues,
  1744. pcbEnumValues,
  1745. pnEnumValues);
  1746. YRevertToSelf(Route);
  1747. if (dwRet == ERROR_SUCCESS) {
  1748. if (!MarshallDownStructuresArray((LPBYTE) pAlignedBuff,
  1749. *pnEnumValues,
  1750. PrinterEnumValuesFields,
  1751. sizeof(PRINTER_ENUM_VALUES),
  1752. Route) ) {
  1753. dwRet = GetLastError();
  1754. }
  1755. }
  1756. UndoAlignRpcPtr(pEnumValues, pAlignedBuff, cbEnumValues, pcbEnumValues);
  1757. return dwRet;
  1758. }
  1759. DWORD
  1760. YEnumPrinterKey(
  1761. HANDLE hPrinter,
  1762. LPCWSTR pKeyName, // address of key name
  1763. LPWSTR pSubkey, // address of buffer for value string
  1764. DWORD cbSubkey, // size of value buffer
  1765. LPDWORD pcbSubkey, // address for size of value buffer
  1766. CALL_ROUTE Route // where this call comes from
  1767. )
  1768. {
  1769. DWORD dwRet;
  1770. if (!YImpersonateClient(Route))
  1771. return GetLastError();
  1772. dwRet = EnumPrinterKey( hPrinter,
  1773. pKeyName,
  1774. pSubkey,
  1775. cbSubkey,
  1776. pcbSubkey);
  1777. YRevertToSelf(Route);
  1778. return dwRet;
  1779. }
  1780. DWORD
  1781. YDeletePrinterData(
  1782. HANDLE hPrinter,
  1783. LPWSTR pValueName,
  1784. CALL_ROUTE Route
  1785. )
  1786. {
  1787. DWORD dwRet;
  1788. if (!YImpersonateClient(Route))
  1789. return GetLastError();
  1790. dwRet = DeletePrinterData(hPrinter, pValueName);
  1791. YRevertToSelf(Route);
  1792. return dwRet;
  1793. }
  1794. DWORD
  1795. YDeletePrinterDataEx(
  1796. HANDLE hPrinter,
  1797. LPCWSTR pKeyName,
  1798. LPCWSTR pValueName,
  1799. CALL_ROUTE Route
  1800. )
  1801. {
  1802. DWORD dwRet;
  1803. if (!YImpersonateClient(Route))
  1804. return GetLastError();
  1805. dwRet = DeletePrinterDataEx(hPrinter, pKeyName, pValueName);
  1806. YRevertToSelf(Route);
  1807. return dwRet;
  1808. }
  1809. DWORD
  1810. YDeletePrinterKey(
  1811. HANDLE hPrinter,
  1812. LPCWSTR pKeyName,
  1813. CALL_ROUTE Route
  1814. )
  1815. {
  1816. DWORD dwRet;
  1817. if (!YImpersonateClient(Route))
  1818. return GetLastError();
  1819. dwRet = DeletePrinterKey(hPrinter, pKeyName);
  1820. YRevertToSelf(Route);
  1821. return dwRet;
  1822. }
  1823. DWORD
  1824. YSetPrinterData(
  1825. HANDLE hPrinter,
  1826. LPTSTR pValueName,
  1827. DWORD Type,
  1828. LPBYTE pData,
  1829. DWORD cbData,
  1830. CALL_ROUTE Route
  1831. )
  1832. {
  1833. DWORD dwRet;
  1834. if (!YImpersonateClient(Route))
  1835. return GetLastError();
  1836. dwRet = SetPrinterData(hPrinter, pValueName, Type, pData, cbData);
  1837. YRevertToSelf(Route);
  1838. return dwRet;
  1839. }
  1840. DWORD
  1841. YSetPrinterDataEx(
  1842. HANDLE hPrinter,
  1843. LPCTSTR pKeyName,
  1844. LPCTSTR pValueName,
  1845. DWORD Type,
  1846. LPBYTE pData,
  1847. DWORD cbData,
  1848. CALL_ROUTE Route
  1849. )
  1850. {
  1851. DWORD dwRet;
  1852. if (!YImpersonateClient(Route))
  1853. return GetLastError();
  1854. dwRet = SetPrinterDataEx(hPrinter, pKeyName, pValueName, Type, pData, cbData);
  1855. YRevertToSelf(Route);
  1856. return dwRet;
  1857. }
  1858. DWORD
  1859. YWaitForPrinterChange(
  1860. HANDLE hPrinter,
  1861. DWORD Flags,
  1862. LPDWORD pFlags,
  1863. CALL_ROUTE Route
  1864. )
  1865. {
  1866. if (!YImpersonateClient(Route))
  1867. return GetLastError();
  1868. *pFlags = WaitForPrinterChange(hPrinter, Flags);
  1869. YRevertToSelf(Route);
  1870. if (*pFlags) {
  1871. return ERROR_SUCCESS;
  1872. } else
  1873. return GetLastError();
  1874. }
  1875. DWORD
  1876. YClosePrinter(
  1877. LPHANDLE phPrinter,
  1878. CALL_ROUTE Route
  1879. )
  1880. {
  1881. BOOL bRet;
  1882. if (!YImpersonateClient(Route))
  1883. return GetLastError();
  1884. bRet = ClosePrinter(*phPrinter);
  1885. YRevertToSelf(Route);
  1886. *phPrinter = NULL; // NULL out handle so Route knows to close it down.
  1887. if (bRet) {
  1888. InterlockedDecrement( &ServerHandleCount );
  1889. return ERROR_SUCCESS;
  1890. } else
  1891. return GetLastError();
  1892. }
  1893. VOID
  1894. PRINTER_HANDLE_rundown(
  1895. HANDLE hPrinter
  1896. )
  1897. {
  1898. DBGMSG(DBG_INFO, ("Printer Handle rundown called\n"));
  1899. PrinterHandleRundown(hPrinter);
  1900. }
  1901. DWORD
  1902. YAddForm(
  1903. HANDLE hPrinter,
  1904. PFORM_CONTAINER pFormInfoContainer,
  1905. CALL_ROUTE Route
  1906. )
  1907. {
  1908. BOOL bRet;
  1909. if(!pFormInfoContainer)
  1910. {
  1911. return ERROR_INVALID_PARAMETER;
  1912. }
  1913. if (!YImpersonateClient(Route))
  1914. return GetLastError();
  1915. bRet = AddForm(hPrinter, pFormInfoContainer->Level,
  1916. (LPBYTE)pFormInfoContainer->FormInfo.pFormInfo1);
  1917. YRevertToSelf(Route);
  1918. if (bRet) {
  1919. return ERROR_SUCCESS;
  1920. } else
  1921. return GetLastError();
  1922. }
  1923. DWORD
  1924. YDeleteForm(
  1925. HANDLE hPrinter,
  1926. LPWSTR pFormName,
  1927. CALL_ROUTE Route
  1928. )
  1929. {
  1930. BOOL bRet;
  1931. if (!YImpersonateClient(Route))
  1932. return GetLastError();
  1933. bRet = DeleteForm(hPrinter, pFormName);
  1934. YRevertToSelf(Route);
  1935. if (bRet) {
  1936. return ERROR_SUCCESS;
  1937. } else
  1938. return GetLastError();
  1939. }
  1940. DWORD
  1941. YGetForm(
  1942. PRINTER_HANDLE hPrinter,
  1943. LPWSTR pFormName,
  1944. DWORD Level,
  1945. LPBYTE pForm,
  1946. DWORD cbBuf,
  1947. LPDWORD pcbNeeded,
  1948. CALL_ROUTE Route
  1949. )
  1950. {
  1951. BOOL bRet;
  1952. LPBYTE pAlignedBuff;
  1953. if (!YImpersonateClient(Route))
  1954. return GetLastError();
  1955. pAlignedBuff = AlignRpcPtr(pForm, &cbBuf);
  1956. if (pForm && !pAlignedBuff){
  1957. YRevertToSelf(Route);
  1958. return GetLastError();
  1959. }
  1960. bRet = GetForm(hPrinter, pFormName, Level, pAlignedBuff, cbBuf, pcbNeeded);
  1961. YRevertToSelf(Route);
  1962. if (bRet) {
  1963. bRet = MarshallDownStructure(pAlignedBuff, FormInfo1Fields, sizeof(FORM_INFO_1), Route);
  1964. }
  1965. UndoAlignRpcPtr(pForm, pAlignedBuff, cbBuf, pcbNeeded);
  1966. return bRet ? ERROR_SUCCESS : GetLastError();
  1967. }
  1968. DWORD
  1969. YSetForm(
  1970. PRINTER_HANDLE hPrinter,
  1971. LPWSTR pFormName,
  1972. PFORM_CONTAINER pFormInfoContainer,
  1973. CALL_ROUTE Route
  1974. )
  1975. {
  1976. BOOL bRet;
  1977. if (!YImpersonateClient(Route))
  1978. return GetLastError();
  1979. bRet = SetForm(hPrinter, pFormName, pFormInfoContainer->Level,
  1980. (LPBYTE)pFormInfoContainer->FormInfo.pFormInfo1);
  1981. YRevertToSelf(Route);
  1982. if (bRet) {
  1983. return ERROR_SUCCESS;
  1984. } else
  1985. return GetLastError();
  1986. }
  1987. DWORD
  1988. YEnumForms(
  1989. PRINTER_HANDLE hPrinter,
  1990. DWORD Level,
  1991. LPBYTE pForm,
  1992. DWORD cbBuf,
  1993. LPDWORD pcbNeeded,
  1994. LPDWORD pcReturned,
  1995. CALL_ROUTE Route
  1996. )
  1997. {
  1998. BOOL bRet;
  1999. DWORD cReturned, cbStruct;
  2000. FieldInfo *pFieldInfo;
  2001. LPBYTE pAlignedBuff;
  2002. switch (Level) {
  2003. case 1:
  2004. pFieldInfo = FormInfo1Fields;
  2005. cbStruct = sizeof(FORM_INFO_1);
  2006. break;
  2007. default:
  2008. return ERROR_INVALID_LEVEL;
  2009. }
  2010. if (!YImpersonateClient(Route))
  2011. return GetLastError();
  2012. pAlignedBuff = AlignRpcPtr(pForm, &cbBuf);
  2013. if (pForm && !pAlignedBuff){
  2014. YRevertToSelf(Route);
  2015. return GetLastError();
  2016. }
  2017. bRet = EnumForms(hPrinter, Level, pAlignedBuff, cbBuf, pcbNeeded, pcReturned);
  2018. YRevertToSelf(Route);
  2019. if (bRet) {
  2020. bRet = MarshallDownStructuresArray(pAlignedBuff, *pcReturned, pFieldInfo, cbStruct, Route);
  2021. }
  2022. UndoAlignRpcPtr(pForm, pAlignedBuff, cbBuf, pcbNeeded);
  2023. return bRet ? ERROR_SUCCESS : GetLastError();
  2024. }
  2025. DWORD
  2026. YEnumPorts(
  2027. LPWSTR pName,
  2028. DWORD Level,
  2029. LPBYTE pPort,
  2030. DWORD cbBuf,
  2031. LPDWORD pcbNeeded,
  2032. LPDWORD pcReturned,
  2033. CALL_ROUTE Route
  2034. )
  2035. {
  2036. BOOL bRet;
  2037. DWORD cReturned, cbStruct;
  2038. FieldInfo *pFieldInfo;
  2039. LPBYTE pAlignedBuff;
  2040. switch (Level) {
  2041. case 1:
  2042. pFieldInfo = PortInfo1Fields;
  2043. cbStruct = sizeof(PORT_INFO_1);
  2044. break;
  2045. case 2:
  2046. pFieldInfo = PortInfo2Fields;
  2047. cbStruct = sizeof(PORT_INFO_2);
  2048. break;
  2049. default:
  2050. return ERROR_INVALID_LEVEL;
  2051. }
  2052. if (!YImpersonateClient(Route))
  2053. return GetLastError();
  2054. pAlignedBuff = AlignRpcPtr(pPort, &cbBuf);
  2055. if (pPort && !pAlignedBuff){
  2056. YRevertToSelf(Route);
  2057. return GetLastError();
  2058. }
  2059. bRet = EnumPorts(pName, Level, pAlignedBuff, cbBuf, pcbNeeded, pcReturned);
  2060. YRevertToSelf(Route);
  2061. if (bRet) {
  2062. bRet = MarshallDownStructuresArray(pAlignedBuff, *pcReturned, pFieldInfo, cbStruct, Route);
  2063. }
  2064. UndoAlignRpcPtr(pPort, pAlignedBuff, cbBuf, pcbNeeded);
  2065. return bRet ? ERROR_SUCCESS : GetLastError();
  2066. }
  2067. DWORD
  2068. YEnumMonitors(
  2069. LPWSTR pName,
  2070. DWORD Level,
  2071. LPBYTE pMonitor,
  2072. DWORD cbBuf,
  2073. LPDWORD pcbNeeded,
  2074. LPDWORD pcReturned,
  2075. CALL_ROUTE Route
  2076. )
  2077. {
  2078. BOOL bRet;
  2079. DWORD cReturned, cbStruct;
  2080. FieldInfo *pFieldInfo;
  2081. LPBYTE pAlignedBuff;
  2082. switch (Level) {
  2083. case 1:
  2084. pFieldInfo = MonitorInfo1Fields;
  2085. cbStruct = sizeof(MONITOR_INFO_1);
  2086. break;
  2087. case 2:
  2088. pFieldInfo = MonitorInfo2Fields;
  2089. cbStruct = sizeof(MONITOR_INFO_2);
  2090. break;
  2091. default:
  2092. return ERROR_INVALID_LEVEL;
  2093. }
  2094. if (!YImpersonateClient(Route))
  2095. return GetLastError();
  2096. pAlignedBuff = AlignRpcPtr(pMonitor, &cbBuf);
  2097. if (pMonitor && !pAlignedBuff){
  2098. YRevertToSelf(Route);
  2099. return GetLastError();
  2100. }
  2101. bRet = EnumMonitors(pName, Level, pAlignedBuff, cbBuf, pcbNeeded, pcReturned);
  2102. YRevertToSelf(Route);
  2103. if (bRet) {
  2104. bRet = MarshallDownStructuresArray(pAlignedBuff, *pcReturned, pFieldInfo, cbStruct, Route);
  2105. }
  2106. UndoAlignRpcPtr(pMonitor, pAlignedBuff, cbBuf, pcbNeeded);
  2107. return bRet ? ERROR_SUCCESS : GetLastError();
  2108. }
  2109. DWORD
  2110. YAddPort(
  2111. LPWSTR pName,
  2112. HWND hWnd,
  2113. LPWSTR pMonitorName,
  2114. CALL_ROUTE Route
  2115. )
  2116. {
  2117. BOOL bRet;
  2118. if (!YImpersonateClient(Route))
  2119. return GetLastError();
  2120. bRet = AddPort(pName, hWnd, pMonitorName);
  2121. YRevertToSelf(Route);
  2122. if (bRet)
  2123. return ERROR_SUCCESS;
  2124. else
  2125. return GetLastError();
  2126. }
  2127. DWORD
  2128. YConfigurePort(
  2129. LPWSTR pName,
  2130. HWND hWnd,
  2131. LPWSTR pPortName,
  2132. CALL_ROUTE Route
  2133. )
  2134. {
  2135. BOOL bRet;
  2136. if (!YImpersonateClient(Route))
  2137. return GetLastError();
  2138. bRet = ConfigurePort(pName, hWnd, pPortName);
  2139. YRevertToSelf(Route);
  2140. if (bRet)
  2141. return ERROR_SUCCESS;
  2142. else
  2143. return GetLastError();
  2144. }
  2145. DWORD
  2146. YDeletePort(
  2147. LPWSTR pName,
  2148. HWND hWnd,
  2149. LPWSTR pPortName,
  2150. CALL_ROUTE Route
  2151. )
  2152. {
  2153. BOOL bRet;
  2154. if (!YImpersonateClient(Route))
  2155. return GetLastError();
  2156. bRet = DeletePort(pName, hWnd, pPortName);
  2157. YRevertToSelf(Route);
  2158. if (bRet)
  2159. return ERROR_SUCCESS;
  2160. else
  2161. return GetLastError();
  2162. }
  2163. DWORD
  2164. YXcvData(
  2165. HANDLE hXcv,
  2166. PCWSTR pszDataName,
  2167. PBYTE pInputData,
  2168. DWORD cbInputData,
  2169. PBYTE pOutputData,
  2170. DWORD cbOutputData,
  2171. PDWORD pcbOutputNeeded,
  2172. PDWORD pdwStatus,
  2173. CALL_ROUTE Route
  2174. )
  2175. {
  2176. BOOL bRet;
  2177. if (!YImpersonateClient(Route))
  2178. return GetLastError();
  2179. bRet = XcvData( hXcv,
  2180. pszDataName,
  2181. pInputData,
  2182. cbInputData,
  2183. pOutputData,
  2184. cbOutputData,
  2185. pcbOutputNeeded,
  2186. pdwStatus);
  2187. YRevertToSelf(Route);
  2188. if (bRet)
  2189. return ERROR_SUCCESS;
  2190. else
  2191. return GetLastError();
  2192. }
  2193. DWORD
  2194. YCreatePrinterIC(
  2195. HANDLE hPrinter,
  2196. HANDLE *pHandle,
  2197. LPDEVMODE_CONTAINER pDevModeContainer,
  2198. CALL_ROUTE Route
  2199. )
  2200. {
  2201. if (!YImpersonateClient(Route))
  2202. return GetLastError();
  2203. if ( InvalidDevModeContainer(pDevModeContainer) ) {
  2204. YRevertToSelf(Route);
  2205. return ERROR_INVALID_PARAMETER;
  2206. }
  2207. *pHandle = CreatePrinterIC(hPrinter,
  2208. (LPDEVMODEW)pDevModeContainer->pDevMode);
  2209. YRevertToSelf(Route);
  2210. if (*pHandle)
  2211. return ERROR_SUCCESS;
  2212. else
  2213. return GetLastError();
  2214. }
  2215. DWORD
  2216. YPlayGdiScriptOnPrinterIC(
  2217. GDI_HANDLE hPrinterIC,
  2218. LPBYTE pIn,
  2219. DWORD cIn,
  2220. LPBYTE pOut,
  2221. DWORD cOut,
  2222. DWORD ul,
  2223. CALL_ROUTE Route
  2224. )
  2225. {
  2226. BOOL bRet;
  2227. if (!YImpersonateClient(Route))
  2228. return GetLastError();
  2229. bRet = PlayGdiScriptOnPrinterIC(hPrinterIC, pIn, cIn, pOut, cOut, ul);
  2230. YRevertToSelf(Route);
  2231. if (bRet)
  2232. return ERROR_SUCCESS;
  2233. else
  2234. return GetLastError();
  2235. }
  2236. DWORD
  2237. YDeletePrinterIC(
  2238. GDI_HANDLE *phPrinterIC,
  2239. BOOL bImpersonate,
  2240. CALL_ROUTE Route
  2241. )
  2242. {
  2243. BOOL bRet;
  2244. if (bImpersonate && !YImpersonateClient(Route))
  2245. return GetLastError();
  2246. bRet = DeletePrinterIC(*phPrinterIC);
  2247. if (bImpersonate)
  2248. YRevertToSelf(Route);
  2249. if (bRet) {
  2250. *phPrinterIC = NULL; // NULL out handle so Route knows to close it down.
  2251. return ERROR_SUCCESS;
  2252. } else
  2253. return GetLastError();
  2254. }
  2255. DWORD
  2256. YPrinterMessageBox(
  2257. PRINTER_HANDLE hPrinter,
  2258. DWORD Error,
  2259. HWND hWnd,
  2260. LPWSTR pText,
  2261. LPWSTR pCaption,
  2262. DWORD dwType,
  2263. CALL_ROUTE Route
  2264. )
  2265. {
  2266. return PrinterMessageBox(hPrinter, Error, hWnd, pText, pCaption, dwType);
  2267. }
  2268. DWORD
  2269. YAddMonitor(
  2270. LPWSTR pName,
  2271. PMONITOR_CONTAINER pMonitorContainer,
  2272. CALL_ROUTE Route
  2273. )
  2274. {
  2275. BOOL bRet;
  2276. if(!ValidateMonitorContainer(pMonitorContainer))
  2277. {
  2278. return ERROR_INVALID_PARAMETER;
  2279. }
  2280. if (!YImpersonateClient(Route))
  2281. return GetLastError();
  2282. bRet = AddMonitor(pName, pMonitorContainer->Level,
  2283. (LPBYTE)pMonitorContainer->MonitorInfo.pMonitorInfo1);
  2284. YRevertToSelf(Route);
  2285. if (bRet)
  2286. return ERROR_SUCCESS;
  2287. else
  2288. return GetLastError();
  2289. }
  2290. DWORD
  2291. YDeleteMonitor(
  2292. LPWSTR pName,
  2293. LPWSTR pEnvironment,
  2294. LPWSTR pMonitorName,
  2295. CALL_ROUTE Route
  2296. )
  2297. {
  2298. BOOL bRet;
  2299. if (!YImpersonateClient(Route))
  2300. return GetLastError();
  2301. bRet = DeleteMonitor(pName, pEnvironment, pMonitorName);
  2302. YRevertToSelf(Route);
  2303. if (bRet) {
  2304. return ERROR_SUCCESS;
  2305. } else
  2306. return GetLastError();
  2307. }
  2308. DWORD
  2309. YDeletePrintProcessor(
  2310. LPWSTR pName,
  2311. LPWSTR pEnvironment,
  2312. LPWSTR pPrintProcessorName,
  2313. CALL_ROUTE Route
  2314. )
  2315. {
  2316. BOOL bRet;
  2317. if (!YImpersonateClient(Route))
  2318. return GetLastError();
  2319. bRet = DeletePrintProcessor(pName, pEnvironment, pPrintProcessorName);
  2320. YRevertToSelf(Route);
  2321. if (bRet) {
  2322. return ERROR_SUCCESS;
  2323. } else
  2324. return GetLastError();
  2325. }
  2326. DWORD
  2327. YAddPrintProvidor(
  2328. LPWSTR pName,
  2329. PPROVIDOR_CONTAINER pProvidorContainer,
  2330. CALL_ROUTE Route
  2331. )
  2332. {
  2333. BOOL bRet;
  2334. DWORD cchOrder;
  2335. LPBYTE pProvidorInfo;
  2336. PROVIDOR_INFO_2W ProvidorInfo2;
  2337. LPRPC_PROVIDOR_INFO_2W pRpcProvidorInfo;
  2338. if(!pProvidorContainer)
  2339. {
  2340. return ERROR_INVALID_PARAMETER;
  2341. }
  2342. if (!YImpersonateClient(Route))
  2343. return GetLastError();
  2344. switch (pProvidorContainer->Level) {
  2345. case 1:
  2346. pProvidorInfo = (LPBYTE) pProvidorContainer->ProvidorInfo.pProvidorInfo1;
  2347. break;
  2348. case 2:
  2349. pRpcProvidorInfo = (LPRPC_PROVIDOR_INFO_2W)pProvidorContainer->ProvidorInfo.pRpcProvidorInfo2;
  2350. cchOrder = pRpcProvidorInfo->cchOrder;
  2351. if (!IsValidMultiSz(pRpcProvidorInfo->pOrder, cchOrder))
  2352. {
  2353. YRevertToSelf(Route);
  2354. return ERROR_INVALID_PARAMETER;
  2355. }
  2356. ProvidorInfo2.pOrder = (cchOrder == 0 || cchOrder == 1)
  2357. ? szNull
  2358. : pRpcProvidorInfo->pOrder;
  2359. pProvidorInfo = (LPBYTE) &ProvidorInfo2;
  2360. break;
  2361. default:
  2362. YRevertToSelf(Route);
  2363. return ERROR_INVALID_LEVEL;
  2364. }
  2365. bRet = AddPrintProvidor(pName, pProvidorContainer->Level,
  2366. pProvidorInfo);
  2367. YRevertToSelf(Route);
  2368. if (bRet)
  2369. return ERROR_SUCCESS;
  2370. else
  2371. return GetLastError();
  2372. }
  2373. DWORD
  2374. YDeletePrintProvidor(
  2375. LPWSTR pName,
  2376. LPWSTR pEnvironment,
  2377. LPWSTR pPrintProvidorName,
  2378. CALL_ROUTE Route
  2379. )
  2380. {
  2381. BOOL bRet;
  2382. if (!YImpersonateClient(Route))
  2383. return GetLastError();
  2384. bRet = DeletePrintProvidor(pName, pEnvironment, pPrintProvidorName);
  2385. YRevertToSelf(Route);
  2386. if (bRet) {
  2387. return ERROR_SUCCESS;
  2388. } else
  2389. return GetLastError();
  2390. }
  2391. DWORD
  2392. YGetPrinterDriver2(
  2393. HANDLE hPrinter,
  2394. LPWSTR pEnvironment,
  2395. DWORD Level,
  2396. LPBYTE pDriverInfo,
  2397. DWORD cbBuf,
  2398. LPDWORD pcbNeeded,
  2399. DWORD dwClientMajorVersion,
  2400. DWORD dwClientMinorVersion,
  2401. PDWORD pdwServerMajorVersion,
  2402. PDWORD pdwServerMinorVersion,
  2403. CALL_ROUTE Route
  2404. )
  2405. {
  2406. FieldInfo *pFieldInfo;
  2407. BOOL bRet;
  2408. SIZE_T cbStruct;
  2409. LPBYTE pAlignedBuff;
  2410. switch (Level) {
  2411. case 1:
  2412. pFieldInfo = DriverInfo1Fields;
  2413. cbStruct = sizeof(DRIVER_INFO_1);
  2414. break;
  2415. case 2:
  2416. pFieldInfo = DriverInfo2Fields;
  2417. cbStruct = sizeof(DRIVER_INFO_2);
  2418. break;
  2419. case 3:
  2420. pFieldInfo = DriverInfo3Fields;
  2421. cbStruct = sizeof(DRIVER_INFO_3);
  2422. break;
  2423. case 4:
  2424. pFieldInfo = DriverInfo4Fields;
  2425. cbStruct = sizeof(DRIVER_INFO_4);
  2426. break;
  2427. case 5:
  2428. pFieldInfo = DriverInfo5Fields;
  2429. cbStruct = sizeof(DRIVER_INFO_5);
  2430. break;
  2431. case 6:
  2432. pFieldInfo = DriverInfo6Fields;
  2433. cbStruct = sizeof(DRIVER_INFO_6);
  2434. break;
  2435. case DRIVER_INFO_VERSION_LEVEL:
  2436. pFieldInfo = DriverInfoVersionFields;
  2437. cbStruct = sizeof(DRIVER_INFO_VERSION);
  2438. break;
  2439. default:
  2440. return ERROR_INVALID_LEVEL;
  2441. }
  2442. //
  2443. // Determine if we want the most recent driver
  2444. //
  2445. if (!YImpersonateClient(Route))
  2446. return GetLastError();
  2447. pAlignedBuff = AlignRpcPtr(pDriverInfo, &cbBuf);
  2448. if (pDriverInfo && !pAlignedBuff){
  2449. YRevertToSelf(Route);
  2450. return GetLastError();
  2451. }
  2452. bRet = GetPrinterDriverExW(hPrinter, pEnvironment, Level, pAlignedBuff,
  2453. cbBuf, pcbNeeded, dwClientMajorVersion,
  2454. dwClientMinorVersion, pdwServerMajorVersion,
  2455. pdwServerMinorVersion);
  2456. YRevertToSelf(Route);
  2457. if (bRet) {
  2458. bRet = MarshallDownStructure(pAlignedBuff, pFieldInfo, cbStruct, Route);
  2459. }
  2460. UndoAlignRpcPtr(pDriverInfo, pAlignedBuff, cbBuf, pcbNeeded);
  2461. return bRet ? ERROR_SUCCESS : GetLastError();
  2462. }
  2463. DWORD
  2464. YAddPortEx(
  2465. LPWSTR pName,
  2466. LPPORT_CONTAINER pPortContainer,
  2467. LPPORT_VAR_CONTAINER pPortVarContainer,
  2468. LPWSTR pMonitorName,
  2469. CALL_ROUTE Route
  2470. )
  2471. {
  2472. BOOL bRet;
  2473. DWORD Level;
  2474. PPORT_INFO_FF pPortInfoFF;
  2475. PPORT_INFO_1 pPortInfo1;
  2476. if(!ValidatePortContainer(pPortContainer))
  2477. {
  2478. return ERROR_INVALID_PARAMETER;
  2479. }
  2480. Level = pPortContainer->Level;
  2481. switch (Level){
  2482. case 1:
  2483. pPortInfo1 = pPortContainer->PortInfo.pPortInfo1;
  2484. if (!YImpersonateClient(Route))
  2485. return GetLastError();
  2486. bRet = AddPortEx(pName, Level, (LPBYTE)pPortInfo1, pMonitorName);
  2487. YRevertToSelf(Route);
  2488. break;
  2489. case (DWORD)-1:
  2490. pPortInfoFF = pPortContainer->PortInfo.pPortInfoFF;
  2491. if(!ValidatePortVarContainer(pPortVarContainer))
  2492. {
  2493. return(ERROR_INVALID_PARAMETER);
  2494. }
  2495. pPortInfoFF->cbMonitorData = pPortVarContainer->cbMonitorData;
  2496. pPortInfoFF->pMonitorData = pPortVarContainer->pMonitorData;
  2497. if (!YImpersonateClient(Route))
  2498. return GetLastError();
  2499. bRet = AddPortEx(pName, Level, (LPBYTE)pPortInfoFF, pMonitorName);
  2500. YRevertToSelf(Route);
  2501. break;
  2502. default:
  2503. SetLastError(ERROR_INVALID_LEVEL);
  2504. return ERROR_INVALID_PARAMETER;
  2505. }
  2506. if (bRet) {
  2507. return ERROR_SUCCESS;
  2508. } else
  2509. return GetLastError();
  2510. }
  2511. DWORD
  2512. YSpoolerInit(
  2513. LPWSTR pName,
  2514. CALL_ROUTE Route
  2515. )
  2516. {
  2517. BOOL bRet;
  2518. if (!YImpersonateClient(Route))
  2519. return GetLastError();
  2520. bRet = SpoolerInit();
  2521. YRevertToSelf(Route);
  2522. if (bRet) {
  2523. return ERROR_SUCCESS;
  2524. } else
  2525. return GetLastError();
  2526. }
  2527. DWORD
  2528. YResetPrinterEx(
  2529. HANDLE hPrinter,
  2530. LPWSTR pDatatype,
  2531. LPDEVMODE_CONTAINER pDevModeContainer,
  2532. DWORD dwFlag,
  2533. CALL_ROUTE Route
  2534. )
  2535. {
  2536. PRINTER_DEFAULTS Defaults;
  2537. BOOL bRet;
  2538. if (!YImpersonateClient(Route))
  2539. return GetLastError();
  2540. if ( InvalidDevModeContainer(pDevModeContainer) ) {
  2541. YRevertToSelf(Route);
  2542. return ERROR_INVALID_PARAMETER;
  2543. }
  2544. if (pDatatype) {
  2545. Defaults.pDatatype = pDatatype;
  2546. }else {
  2547. if (dwFlag & RESET_PRINTER_DATATYPE) {
  2548. Defaults.pDatatype = (LPWSTR)-1;
  2549. }else {
  2550. Defaults.pDatatype = NULL;
  2551. }
  2552. }
  2553. if ((LPDEVMODE)pDevModeContainer->pDevMode) {
  2554. Defaults.pDevMode = (LPDEVMODE)pDevModeContainer->pDevMode;
  2555. }else {
  2556. if (dwFlag & RESET_PRINTER_DEVMODE) {
  2557. Defaults.pDevMode = (LPDEVMODE)-1;
  2558. }else{
  2559. Defaults.pDevMode = NULL;
  2560. }
  2561. }
  2562. //
  2563. // You cannot change the Access Mask on a Printer Spool Object
  2564. // We will always ignore this parameter and set it to zero
  2565. // We get some random garbage otherwise.
  2566. //
  2567. Defaults.DesiredAccess = 0;
  2568. bRet = ResetPrinter(hPrinter, &Defaults);
  2569. YRevertToSelf(Route);
  2570. if (bRet)
  2571. return ERROR_SUCCESS;
  2572. else
  2573. return GetLastError();
  2574. }
  2575. DWORD
  2576. YSetAllocFailCount(
  2577. HANDLE hPrinter,
  2578. DWORD dwFailCount,
  2579. LPDWORD lpdwAllocCount,
  2580. LPDWORD lpdwFreeCount,
  2581. LPDWORD lpdwFailCountHit,
  2582. CALL_ROUTE Route
  2583. )
  2584. {
  2585. BOOL bRet;
  2586. if (!YImpersonateClient(Route))
  2587. return GetLastError();
  2588. bRet = SetAllocFailCount( hPrinter, dwFailCount, lpdwAllocCount, lpdwFreeCount, lpdwFailCountHit );
  2589. YRevertToSelf(Route);
  2590. if (bRet)
  2591. return ERROR_SUCCESS;
  2592. else
  2593. return GetLastError();
  2594. }
  2595. BOOL
  2596. YImpersonateClient(
  2597. CALL_ROUTE Route
  2598. )
  2599. {
  2600. DWORD Status;
  2601. if (Route != NATIVE_CALL) {
  2602. Status = RpcImpersonateClient(NULL);
  2603. SPLASSERT( Status == RPC_S_OK || Status == RPC_S_NO_CONTEXT_AVAILABLE );
  2604. if ( Status != RPC_S_OK ) {
  2605. SetLastError( Status );
  2606. return FALSE;
  2607. }
  2608. }
  2609. return TRUE; // If not RPC, then we should continue w/out doing anything
  2610. }
  2611. DWORD
  2612. YSetPort(
  2613. LPWSTR pName,
  2614. LPWSTR pPortName,
  2615. LPPORT_CONTAINER pPortContainer,
  2616. CALL_ROUTE Route
  2617. )
  2618. {
  2619. BOOL bRet;
  2620. if(!ValidatePortContainer(pPortContainer))
  2621. {
  2622. return ERROR_INVALID_PARAMETER;
  2623. }
  2624. switch (pPortContainer->Level) {
  2625. case 3:
  2626. if ( !YImpersonateClient(Route) )
  2627. return GetLastError();
  2628. bRet = SetPort(pName,
  2629. pPortName,
  2630. pPortContainer->Level,
  2631. (LPBYTE)pPortContainer->PortInfo.pPortInfo1);
  2632. YRevertToSelf(Route);
  2633. break;
  2634. default:
  2635. SetLastError(ERROR_INVALID_LEVEL);
  2636. return ERROR_INVALID_PARAMETER;
  2637. }
  2638. return bRet ? ERROR_SUCCESS : GetLastError();
  2639. }
  2640. DWORD
  2641. YClusterSplOpen(
  2642. LPCTSTR pszServer,
  2643. LPCTSTR pszResource,
  2644. PHANDLE phSpooler,
  2645. LPCTSTR pszName,
  2646. LPCTSTR pszAddress,
  2647. CALL_ROUTE Route
  2648. )
  2649. {
  2650. BOOL bRet;
  2651. if (!YImpersonateClient(Route))
  2652. return GetLastError();
  2653. bRet = ClusterSplOpen( pszServer,
  2654. pszResource,
  2655. phSpooler,
  2656. pszName,
  2657. pszAddress );
  2658. YRevertToSelf(Route);
  2659. if (bRet) {
  2660. return ERROR_SUCCESS;
  2661. } else
  2662. return GetLastError();
  2663. }
  2664. DWORD
  2665. YClusterSplClose(
  2666. PHANDLE phPrinter,
  2667. CALL_ROUTE Route
  2668. )
  2669. {
  2670. BOOL bRet;
  2671. if (!YImpersonateClient(Route))
  2672. return GetLastError();
  2673. bRet = ClusterSplClose( *phPrinter );
  2674. YRevertToSelf(Route);
  2675. *phPrinter = NULL; // NULL out handle so Route knows to close it down.
  2676. if (bRet) {
  2677. return ERROR_SUCCESS;
  2678. } else
  2679. return GetLastError();
  2680. }
  2681. DWORD
  2682. YClusterSplIsAlive(
  2683. HANDLE hSpooler,
  2684. CALL_ROUTE Route
  2685. )
  2686. {
  2687. BOOL bRet;
  2688. if (!YImpersonateClient(Route))
  2689. return GetLastError();
  2690. bRet = ClusterSplIsAlive( hSpooler );
  2691. YRevertToSelf(Route);
  2692. if (bRet) {
  2693. return ERROR_SUCCESS;
  2694. } else
  2695. return GetLastError();
  2696. }
  2697. DWORD
  2698. YGetSpoolFileInfo(
  2699. HANDLE hPrinter,
  2700. DWORD dwAppProcessId,
  2701. DWORD dwLevel,
  2702. LPBYTE pSpoolFileInfo,
  2703. DWORD cbBuf,
  2704. LPDWORD pcbNeeded,
  2705. CALL_ROUTE Route
  2706. )
  2707. {
  2708. HANDLE hAppProcess;
  2709. BOOL bReturn = FALSE;
  2710. // Open the application before impersonating the user
  2711. hAppProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwAppProcessId);
  2712. if (!YImpersonateClient(Route)) {
  2713. goto CleanUp;
  2714. }
  2715. bReturn = SplGetSpoolFileInfo(hPrinter, hAppProcess, dwLevel,
  2716. pSpoolFileInfo, cbBuf, pcbNeeded);
  2717. YRevertToSelf(Route);
  2718. CleanUp:
  2719. if (hAppProcess) {
  2720. CloseHandle(hAppProcess);
  2721. }
  2722. if (bReturn) {
  2723. return ERROR_SUCCESS;
  2724. } else {
  2725. return GetLastError();
  2726. }
  2727. }
  2728. DWORD
  2729. YGetSpoolFileInfo2(
  2730. HANDLE hPrinter,
  2731. DWORD dwAppProcessId,
  2732. DWORD dwLevel,
  2733. LPFILE_INFO_CONTAINER pSplFileInfoContainer,
  2734. CALL_ROUTE Route
  2735. )
  2736. {
  2737. HANDLE hAppProcess;
  2738. BOOL bReturn = FALSE;
  2739. DWORD cbNeeded = 0;
  2740. LPBYTE pSpoolFileInfo;
  2741. DWORD cbSize;
  2742. DWORD dwLastError = ERROR_SUCCESS;
  2743. switch (dwLevel){
  2744. case 1:
  2745. if(!pSplFileInfoContainer || !pSplFileInfoContainer->FileInfo.Level1)
  2746. {
  2747. return ERROR_INVALID_HANDLE;
  2748. }
  2749. pSpoolFileInfo = (LPBYTE)pSplFileInfoContainer->FileInfo.Level1;
  2750. cbSize = sizeof(SPOOL_FILE_INFO_1);
  2751. break;
  2752. default:
  2753. return ERROR_INVALID_LEVEL;
  2754. }
  2755. // Open the application before impersonating the user
  2756. if ( hAppProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwAppProcessId) ) {
  2757. if (YImpersonateClient(Route)) {
  2758. bReturn = SplGetSpoolFileInfo(hPrinter, hAppProcess, dwLevel,
  2759. pSpoolFileInfo,
  2760. cbSize, &cbNeeded);
  2761. YRevertToSelf(Route);
  2762. }
  2763. }
  2764. if ( !bReturn ) {
  2765. dwLastError = GetLastError();
  2766. //
  2767. // Ensure that if someone didn't set a last error, but failed the call,
  2768. // we still return an error.
  2769. //
  2770. if (dwLastError == ERROR_SUCCESS) {
  2771. dwLastError = ERROR_INVALID_HANDLE;
  2772. }
  2773. }
  2774. if (hAppProcess) {
  2775. CloseHandle(hAppProcess);
  2776. }
  2777. return dwLastError;
  2778. }
  2779. DWORD
  2780. YCommitSpoolData(
  2781. HANDLE hPrinter,
  2782. DWORD dwAppProcessId,
  2783. DWORD cbCommit,
  2784. DWORD dwLevel,
  2785. LPBYTE pSpoolFileInfo,
  2786. DWORD cbBuf,
  2787. LPDWORD pcbNeeded,
  2788. CALL_ROUTE Route
  2789. )
  2790. {
  2791. HANDLE hAppProcess;
  2792. BOOL bReturn = FALSE;
  2793. // Open the application before impersonating the user
  2794. hAppProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwAppProcessId);
  2795. if (!YImpersonateClient(Route)) {
  2796. goto CleanUp;
  2797. }
  2798. bReturn = SplCommitSpoolData(hPrinter, hAppProcess, cbCommit,
  2799. dwLevel, pSpoolFileInfo, cbBuf, pcbNeeded);
  2800. YRevertToSelf(Route);
  2801. CleanUp:
  2802. if (hAppProcess) {
  2803. CloseHandle(hAppProcess);
  2804. }
  2805. if (bReturn) {
  2806. return ERROR_SUCCESS;
  2807. } else {
  2808. return GetLastError();
  2809. }
  2810. }
  2811. DWORD
  2812. YCommitSpoolData2(
  2813. HANDLE hPrinter,
  2814. DWORD dwAppProcessId,
  2815. DWORD cbCommit,
  2816. DWORD dwLevel,
  2817. LPFILE_INFO_CONTAINER pSplFileInfoContainer,
  2818. CALL_ROUTE Route
  2819. )
  2820. {
  2821. HANDLE hAppProcess;
  2822. BOOL bReturn = FALSE;
  2823. DWORD cbNeeded = 0;
  2824. LPBYTE pSpoolFileInfo;
  2825. DWORD cbSize;
  2826. DWORD dwLastError = ERROR_SUCCESS;
  2827. switch (dwLevel){
  2828. case 1:
  2829. if(!pSplFileInfoContainer || !pSplFileInfoContainer->FileInfo.Level1)
  2830. {
  2831. return ERROR_INVALID_HANDLE;
  2832. }
  2833. pSpoolFileInfo = (LPBYTE)pSplFileInfoContainer->FileInfo.Level1;
  2834. cbSize = sizeof(SPOOL_FILE_INFO_1);
  2835. break;
  2836. default:
  2837. return ERROR_INVALID_LEVEL;
  2838. }
  2839. // Open the application before impersonating the user
  2840. if ( hAppProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, dwAppProcessId) ) {
  2841. if (YImpersonateClient(Route)) {
  2842. bReturn = SplCommitSpoolData(hPrinter, hAppProcess, cbCommit,
  2843. dwLevel, pSpoolFileInfo,
  2844. cbSize, &cbNeeded);
  2845. YRevertToSelf(Route);
  2846. }
  2847. }
  2848. if ( !bReturn ) {
  2849. dwLastError = GetLastError();
  2850. //
  2851. // Make sure that there is a failure return if there is no last error.
  2852. //
  2853. if (dwLastError == ERROR_SUCCESS) {
  2854. dwLastError = ERROR_INVALID_HANDLE;
  2855. }
  2856. }
  2857. if (hAppProcess) {
  2858. CloseHandle(hAppProcess);
  2859. }
  2860. return dwLastError;
  2861. }
  2862. DWORD
  2863. YCloseSpoolFileHandle(
  2864. HANDLE hPrinter,
  2865. CALL_ROUTE Route
  2866. )
  2867. {
  2868. BOOL bReturn = FALSE;
  2869. if (!YImpersonateClient(Route)) {
  2870. goto CleanUp;
  2871. }
  2872. bReturn = SplCloseSpoolFileHandle(hPrinter);
  2873. YRevertToSelf(Route);
  2874. CleanUp:
  2875. if (bReturn) {
  2876. return ERROR_SUCCESS;
  2877. } else {
  2878. return GetLastError();
  2879. }
  2880. }
  2881. DWORD
  2882. YSendRecvBidiData(
  2883. IN HANDLE hPrinter,
  2884. IN LPCWSTR pAction,
  2885. IN PBIDI_REQUEST_CONTAINER pReqData,
  2886. OUT PBIDI_RESPONSE_CONTAINER* ppResData,
  2887. CALL_ROUTE Route
  2888. )
  2889. {
  2890. DWORD dwRet;
  2891. if (!YImpersonateClient(Route))
  2892. {
  2893. dwRet = GetLastError();
  2894. }
  2895. else
  2896. {
  2897. //
  2898. // Do we need to verify the Data in pReqData ???
  2899. //
  2900. dwRet = SendRecvBidiData(hPrinter,
  2901. pAction,
  2902. pReqData,
  2903. ppResData);
  2904. YRevertToSelf(Route);
  2905. }
  2906. return (dwRet);
  2907. }