Source code of Windows XP (NT5)
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.

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