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.

872 lines
23 KiB

  1. /*++
  2. Copyright (c) 1990-1994 Microsoft Corporation
  3. All rights reserved
  4. Module Name:
  5. spooler.c
  6. Abstract:
  7. Author:
  8. Environment:
  9. User Mode -Win32
  10. Revision History:
  11. --*/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. #include "winsprlp.h"
  15. //
  16. // RPC Buffer size 64K
  17. //
  18. #define BUFFER_SIZE 0x10000
  19. DWORD
  20. StartDocPrinterW(
  21. HANDLE hPrinter,
  22. DWORD Level,
  23. LPBYTE pDocInfo)
  24. {
  25. LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
  26. if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
  27. SetLastError(ERROR_INVALID_HANDLE);
  28. return FALSE;
  29. }
  30. return (*pPrintHandle->pProvidor->PrintProvidor.fpStartDocPrinter)
  31. (pPrintHandle->hPrinter,
  32. Level, pDocInfo);
  33. }
  34. BOOL
  35. StartPagePrinter(
  36. HANDLE hPrinter
  37. )
  38. {
  39. LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
  40. if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
  41. SetLastError(ERROR_INVALID_HANDLE);
  42. return FALSE;
  43. }
  44. return (*pPrintHandle->pProvidor->PrintProvidor.fpStartPagePrinter)
  45. (pPrintHandle->hPrinter);
  46. }
  47. BOOL
  48. SplCommitSpoolData(
  49. HANDLE hPrinter,
  50. HANDLE hAppProcess,
  51. DWORD cbCommit,
  52. DWORD dwLevel,
  53. LPBYTE pSpoolFileInfo,
  54. DWORD cbBuf,
  55. LPDWORD pcbNeeded
  56. )
  57. /*++
  58. Function Description: Commits data written into the spool file. creates a new temp
  59. file handle for remote printing.
  60. Parameters: hPrinter - printer handle
  61. hAppProcess - application process handle
  62. cbCommit - number of bytes to commit (incremental)
  63. dwLevel - spoolfileinfo level
  64. pSpoolFileInfo - pointer to buffer
  65. cbBuf - buffer size
  66. pcbNeeded - pointer to return required buffer size
  67. Return Values: TRUE if sucessful;
  68. FALSE otherwise
  69. --*/
  70. {
  71. BOOL bReturn = FALSE;
  72. DWORD cbTotalWritten, cbWritten, cbRead, cbToRead;
  73. BYTE *Buffer = NULL;
  74. HANDLE hFile, hSpoolerProcess = NULL, hFileApp = INVALID_HANDLE_VALUE;
  75. PSPOOL_FILE_INFO_1 pSpoolFileInfo1;
  76. LPPRINTHANDLE pPrintHandle = (LPPRINTHANDLE)hPrinter;
  77. // Check Handle validity
  78. if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
  79. SetLastError(ERROR_INVALID_HANDLE);
  80. return bReturn;
  81. }
  82. // Check for valid level and sufficient buffer
  83. switch (dwLevel) {
  84. case 1:
  85. if (cbBuf < sizeof(SPOOL_FILE_INFO_1)) {
  86. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  87. *pcbNeeded = sizeof(SPOOL_FILE_INFO_1);
  88. goto CleanUp;
  89. }
  90. pSpoolFileInfo1 = (PSPOOL_FILE_INFO_1)pSpoolFileInfo;
  91. break;
  92. default:
  93. SetLastError(ERROR_INVALID_LEVEL);
  94. goto CleanUp;
  95. }
  96. // Initialize spoolfileinfo1 struct
  97. pSpoolFileInfo1->dwVersion = 1;
  98. pSpoolFileInfo1->hSpoolFile = INVALID_HANDLE_VALUE;
  99. pSpoolFileInfo1->dwAttributes = SPOOL_FILE_PERSISTENT;
  100. if (pPrintHandle->pProvidor == pLocalProvidor) {
  101. bReturn = (pLocalProvidor->PrintProvidor.fpCommitSpoolData)(pPrintHandle->hPrinter,
  102. cbCommit);
  103. return bReturn;
  104. }
  105. // For remote printing send the temp file across the wire using WritePrinter
  106. if (pPrintHandle->hFileSpooler == INVALID_HANDLE_VALUE) {
  107. SetLastError(ERROR_INVALID_HANDLE);
  108. return bReturn;
  109. }
  110. hFile = pPrintHandle->hFileSpooler;
  111. if (SetFilePointer(hFile, 0, NULL, FILE_BEGIN) == 0xffffffff) {
  112. goto CleanUp;
  113. }
  114. //
  115. // Use a Buffer to send Data over RPC.
  116. //
  117. Buffer = AllocSplMem(BUFFER_SIZE);
  118. if ( !Buffer ) {
  119. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  120. goto CleanUp;
  121. }
  122. while ((cbToRead = min(cbCommit, BUFFER_SIZE)) &&
  123. ReadFile(hFile, Buffer, cbToRead, &cbRead, NULL)) {
  124. cbCommit -= cbRead;
  125. for (cbTotalWritten = 0;
  126. cbTotalWritten < cbRead;
  127. cbTotalWritten += cbWritten) {
  128. if (!(*pPrintHandle->pProvidor->PrintProvidor.fpWritePrinter)
  129. (pPrintHandle->hPrinter,
  130. (LPBYTE)Buffer + cbTotalWritten,
  131. cbRead - cbTotalWritten,
  132. &cbWritten)) {
  133. goto CleanUp;
  134. }
  135. }
  136. }
  137. if (Buffer) {
  138. FreeSplMem(Buffer);
  139. Buffer = NULL;
  140. }
  141. if ((cbToRead != 0) ||
  142. (SetFilePointer(hFile, 0, NULL, FILE_BEGIN) == 0xffffffff)) {
  143. goto CleanUp;
  144. }
  145. if ((hSpoolerProcess = GetCurrentProcess()) &&
  146. DuplicateHandle(hSpoolerProcess,
  147. pPrintHandle->hFileSpooler,
  148. hAppProcess,
  149. &hFileApp,
  150. 0,
  151. TRUE,
  152. DUPLICATE_SAME_ACCESS)) {
  153. pSpoolFileInfo1->dwVersion = 1;
  154. pSpoolFileInfo1->hSpoolFile = hFileApp;
  155. pSpoolFileInfo1->dwAttributes = SPOOL_FILE_TEMPORARY;
  156. bReturn = TRUE;
  157. }
  158. CleanUp:
  159. if (Buffer) {
  160. FreeSplMem(Buffer);
  161. }
  162. if (hSpoolerProcess) {
  163. CloseHandle(hSpoolerProcess);
  164. }
  165. return bReturn;
  166. }
  167. BOOL
  168. SplCloseSpoolFileHandle(
  169. HANDLE hPrinter
  170. )
  171. /*++
  172. Function Description: Closes the remote spool file handle for remote printing.
  173. Parameters: hPrinter - printer handle
  174. Return Values: TRUE if sucessful;
  175. FALSE otherwise
  176. --*/
  177. {
  178. LPPRINTHANDLE pPrintHandle = (LPPRINTHANDLE)hPrinter;
  179. // Check Handle validity
  180. if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
  181. SetLastError(ERROR_INVALID_HANDLE);
  182. return FALSE;
  183. }
  184. if (pPrintHandle->pProvidor == pLocalProvidor) {
  185. return (pLocalProvidor->PrintProvidor.fpCloseSpoolFileHandle)(pPrintHandle->hPrinter);
  186. } else if ((pPrintHandle->hFileSpooler != INVALID_HANDLE_VALUE)) {
  187. // close temp files for remote printing
  188. CloseHandle(pPrintHandle->hFileSpooler);
  189. pPrintHandle->hFileSpooler = INVALID_HANDLE_VALUE;
  190. if (pPrintHandle->szTempSpoolFile) {
  191. HANDLE hToken = RevertToPrinterSelf();
  192. if (!DeleteFile(pPrintHandle->szTempSpoolFile)) {
  193. MoveFileEx(pPrintHandle->szTempSpoolFile, NULL,
  194. MOVEFILE_DELAY_UNTIL_REBOOT);
  195. }
  196. if (hToken)
  197. {
  198. ImpersonatePrinterClient(hToken);
  199. }
  200. FreeSplMem(pPrintHandle->szTempSpoolFile);
  201. pPrintHandle->szTempSpoolFile = NULL;
  202. }
  203. }
  204. return TRUE;
  205. }
  206. BOOL
  207. SplGetSpoolFileInfo(
  208. HANDLE hPrinter,
  209. HANDLE hAppProcess,
  210. DWORD dwLevel,
  211. LPBYTE pSpoolFileInfo,
  212. DWORD cbBuf,
  213. LPDWORD pcbNeeded
  214. )
  215. /*++
  216. Function Description: Get spool file info for the job in hPrinter. For local jobs
  217. localspl returns the hFile. For remote jobs a temp file is created
  218. by the router. The file handle is dupped into the application.
  219. Parameters: hPrinter - printer handle
  220. hAppProcess - application process handle
  221. dwLevel - spool file info level
  222. pSpoolFileInfo - pointer to buffer
  223. cbBuf - buffer size
  224. pcbNeeded - pointer to return required buffer size
  225. Return Values: TRUE if sucessful;
  226. FALSE otherwise
  227. --*/
  228. {
  229. HANDLE hFileSpooler = NULL, hFileApp = NULL;
  230. HANDLE hSpoolerProcess = NULL;
  231. BOOL bReturn = FALSE;
  232. DWORD dwSpoolerProcessID;
  233. LPWSTR pSpoolDir = NULL;
  234. PSPOOL_FILE_INFO_1 pSpoolFileInfo1;
  235. LPPRINTHANDLE pPrintHandle = (LPPRINTHANDLE)hPrinter;
  236. // Check Handle validity
  237. if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
  238. SetLastError(ERROR_INVALID_HANDLE);
  239. goto CleanUp;
  240. }
  241. // Check for valid level and sufficient buffer
  242. switch (dwLevel) {
  243. case 1:
  244. if (cbBuf < sizeof(SPOOL_FILE_INFO_1)) {
  245. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  246. *pcbNeeded = sizeof(SPOOL_FILE_INFO_1);
  247. goto CleanUp;
  248. }
  249. pSpoolFileInfo1 = (PSPOOL_FILE_INFO_1)pSpoolFileInfo;
  250. break;
  251. default:
  252. SetLastError(ERROR_INVALID_LEVEL);
  253. goto CleanUp;
  254. }
  255. if (!(hSpoolerProcess = GetCurrentProcess())) {
  256. // Cant get a pseudo handle to the spooler
  257. goto CleanUp;
  258. }
  259. if ((pPrintHandle->pProvidor != pLocalProvidor) &&
  260. (pPrintHandle->hFileSpooler != INVALID_HANDLE_VALUE)) {
  261. // Return cached temp file handle.
  262. bReturn = DuplicateHandle(hSpoolerProcess,
  263. pPrintHandle->hFileSpooler,
  264. hAppProcess,
  265. &hFileApp,
  266. 0,
  267. TRUE,
  268. DUPLICATE_SAME_ACCESS);
  269. if (bReturn) {
  270. pSpoolFileInfo1->dwVersion = 1;
  271. pSpoolFileInfo1->hSpoolFile = hFileApp;
  272. pSpoolFileInfo1->dwAttributes = SPOOL_FILE_TEMPORARY;
  273. }
  274. goto CleanUp;
  275. }
  276. if (pPrintHandle->pProvidor == pLocalProvidor) {
  277. bReturn = (pLocalProvidor->PrintProvidor.fpGetSpoolFileInfo)(pPrintHandle->hPrinter,
  278. NULL,
  279. &hFileApp,
  280. hSpoolerProcess,
  281. hAppProcess);
  282. if (bReturn) {
  283. pSpoolFileInfo1->dwVersion = 1;
  284. pSpoolFileInfo1->hSpoolFile = hFileApp;
  285. pSpoolFileInfo1->dwAttributes = SPOOL_FILE_PERSISTENT;
  286. }
  287. goto CleanUp;
  288. } else {
  289. bReturn = (pLocalProvidor->PrintProvidor.fpGetSpoolFileInfo)(NULL, &pSpoolDir,
  290. NULL, NULL, NULL);
  291. }
  292. // Remote Printing, create a temp file in the spool directory
  293. if (bReturn) {
  294. HANDLE hToken;
  295. //
  296. // Revert to system context to ensure that we can open the file.
  297. //
  298. hToken = RevertToPrinterSelf();
  299. if ((pPrintHandle->szTempSpoolFile = AllocSplMem(MAX_PATH * sizeof(WCHAR))) &&
  300. GetTempFileName(pSpoolDir, L"SPL", 0, pPrintHandle->szTempSpoolFile) &&
  301. ((pPrintHandle->hFileSpooler = CreateFile(pPrintHandle->szTempSpoolFile,
  302. GENERIC_READ | GENERIC_WRITE,
  303. FILE_SHARE_READ | FILE_SHARE_WRITE,
  304. NULL,
  305. CREATE_ALWAYS,
  306. 0, NULL)) != INVALID_HANDLE_VALUE) &&
  307. DuplicateHandle(hSpoolerProcess,
  308. pPrintHandle->hFileSpooler,
  309. hAppProcess,
  310. &hFileApp,
  311. 0,
  312. TRUE,
  313. DUPLICATE_SAME_ACCESS)) {
  314. pSpoolFileInfo1->dwVersion = 1;
  315. pSpoolFileInfo1->hSpoolFile = hFileApp;
  316. pSpoolFileInfo1->dwAttributes = SPOOL_FILE_TEMPORARY;
  317. } else {
  318. bReturn = FALSE;
  319. }
  320. if (hToken)
  321. {
  322. ImpersonatePrinterClient(hToken);
  323. }
  324. }
  325. CleanUp:
  326. if (hSpoolerProcess) {
  327. CloseHandle(hSpoolerProcess);
  328. }
  329. if (pSpoolDir) {
  330. FreeSplMem(pSpoolDir);
  331. }
  332. return bReturn;
  333. }
  334. BOOL
  335. WritePrinter(
  336. HANDLE hPrinter,
  337. LPVOID pBuf,
  338. DWORD cbBuf,
  339. LPDWORD pcWritten
  340. )
  341. {
  342. LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
  343. if (!pPrintHandle ||
  344. (pPrintHandle->signature != PRINTHANDLE_SIGNATURE) ||
  345. (pPrintHandle->hFileSpooler != INVALID_HANDLE_VALUE)) {
  346. SetLastError(ERROR_INVALID_HANDLE);
  347. return FALSE;
  348. }
  349. return (*pPrintHandle->pProvidor->PrintProvidor.fpWritePrinter) (pPrintHandle->hPrinter,
  350. pBuf, cbBuf, pcWritten);
  351. }
  352. BOOL
  353. SeekPrinter(
  354. HANDLE hPrinter,
  355. LARGE_INTEGER liDistanceToMove,
  356. PLARGE_INTEGER pliNewPointer,
  357. DWORD dwMoveMethod,
  358. BOOL bWritePrinter
  359. )
  360. {
  361. LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
  362. LARGE_INTEGER liNewPointer;
  363. if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
  364. SetLastError(ERROR_INVALID_HANDLE);
  365. return FALSE;
  366. }
  367. //
  368. // Allow a NULL pliNewPointer to be passed in.
  369. //
  370. if( !pliNewPointer ){
  371. pliNewPointer = &liNewPointer;
  372. }
  373. return (*pPrintHandle->pProvidor->PrintProvidor.fpSeekPrinter) (
  374. pPrintHandle->hPrinter,
  375. liDistanceToMove,
  376. pliNewPointer,
  377. dwMoveMethod,
  378. bWritePrinter );
  379. }
  380. BOOL
  381. FlushPrinter(
  382. HANDLE hPrinter,
  383. LPVOID pBuf,
  384. DWORD cbBuf,
  385. LPDWORD pcWritten,
  386. DWORD cSleep
  387. )
  388. /*++
  389. Function Description: FlushPrinter is typically used by the driver to send a burst of zeros
  390. to the printer and introduce a delay in the i/o line to the printer.
  391. The spooler does not schedule any job for cSleep milliseconds.
  392. Parameters: hPrinter - printer handle
  393. pBuf - buffer to be sent to the printer
  394. cbBuf - size of the buffer
  395. pcWritten - pointer to return the number of bytes written
  396. cSleep - sleep time in milliseconds.
  397. Return Values: TRUE if successful;
  398. FALSE otherwise
  399. --*/
  400. {
  401. LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
  402. //
  403. // Check for valid printer handle
  404. //
  405. if (!pPrintHandle ||
  406. (pPrintHandle->signature != PRINTHANDLE_SIGNATURE) ||
  407. (pPrintHandle->hFileSpooler != INVALID_HANDLE_VALUE))
  408. {
  409. SetLastError(ERROR_INVALID_HANDLE);
  410. return FALSE;
  411. }
  412. return (*pPrintHandle->pProvidor->PrintProvidor.fpFlushPrinter) (pPrintHandle->hPrinter,
  413. pBuf,
  414. cbBuf,
  415. pcWritten,
  416. cSleep);
  417. }
  418. BOOL
  419. EndPagePrinter(
  420. HANDLE hPrinter
  421. )
  422. {
  423. LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
  424. if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
  425. SetLastError(ERROR_INVALID_HANDLE);
  426. return FALSE;
  427. }
  428. return (*pPrintHandle->pProvidor->PrintProvidor.fpEndPagePrinter) (pPrintHandle->hPrinter);
  429. }
  430. BOOL
  431. AbortPrinter(
  432. HANDLE hPrinter
  433. )
  434. {
  435. LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
  436. if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
  437. SetLastError(ERROR_INVALID_HANDLE);
  438. return FALSE;
  439. }
  440. return (*pPrintHandle->pProvidor->PrintProvidor.fpAbortPrinter) (pPrintHandle->hPrinter);
  441. }
  442. BOOL
  443. ReadPrinter(
  444. HANDLE hPrinter,
  445. LPVOID pBuf,
  446. DWORD cbBuf,
  447. LPDWORD pRead
  448. )
  449. {
  450. LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
  451. if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
  452. SetLastError(ERROR_INVALID_HANDLE);
  453. return FALSE;
  454. }
  455. return (*pPrintHandle->pProvidor->PrintProvidor.fpReadPrinter)
  456. (pPrintHandle->hPrinter, pBuf, cbBuf, pRead);
  457. }
  458. BOOL
  459. SplReadPrinter(
  460. HANDLE hPrinter,
  461. LPBYTE *pBuf,
  462. DWORD cbBuf
  463. )
  464. {
  465. LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
  466. if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
  467. SetLastError(ERROR_INVALID_HANDLE);
  468. return FALSE;
  469. }
  470. return (*pPrintHandle->pProvidor->PrintProvidor.fpSplReadPrinter)
  471. (pPrintHandle->hPrinter, pBuf, cbBuf);
  472. }
  473. BOOL
  474. EndDocPrinter(
  475. HANDLE hPrinter
  476. )
  477. {
  478. LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
  479. if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
  480. SetLastError(ERROR_INVALID_HANDLE);
  481. return FALSE;
  482. }
  483. return (*pPrintHandle->pProvidor->PrintProvidor.fpEndDocPrinter) (pPrintHandle->hPrinter);
  484. }
  485. HANDLE
  486. CreatePrinterIC(
  487. HANDLE hPrinter,
  488. LPDEVMODEW pDevMode
  489. )
  490. {
  491. LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
  492. HANDLE ReturnValue;
  493. PGDIHANDLE pGdiHandle;
  494. if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
  495. SetLastError(ERROR_INVALID_HANDLE);
  496. return FALSE;
  497. }
  498. pGdiHandle = AllocSplMem(sizeof(GDIHANDLE));
  499. if (!pGdiHandle) {
  500. DBGMSG(DBG_WARN, ("Failed to alloc GDI handle."));
  501. return FALSE;
  502. }
  503. ReturnValue = (HANDLE)(*pPrintHandle->pProvidor->PrintProvidor.fpCreatePrinterIC)
  504. (pPrintHandle->hPrinter,
  505. pDevMode);
  506. if (ReturnValue) {
  507. pGdiHandle->signature = GDIHANDLE_SIGNATURE;
  508. pGdiHandle->pProvidor = pPrintHandle->pProvidor;
  509. pGdiHandle->hGdi = ReturnValue;
  510. return pGdiHandle;
  511. }
  512. FreeSplMem(pGdiHandle);
  513. return FALSE;
  514. }
  515. BOOL
  516. PlayGdiScriptOnPrinterIC(
  517. HANDLE hPrinterIC,
  518. LPBYTE pIn,
  519. DWORD cIn,
  520. LPBYTE pOut,
  521. DWORD cOut,
  522. DWORD ul
  523. )
  524. {
  525. PGDIHANDLE pGdiHandle=(PGDIHANDLE)hPrinterIC;
  526. if (!pGdiHandle || pGdiHandle->signature != GDIHANDLE_SIGNATURE) {
  527. SetLastError(ERROR_INVALID_HANDLE);
  528. return FALSE;
  529. }
  530. return (*pGdiHandle->pProvidor->PrintProvidor.fpPlayGdiScriptOnPrinterIC)
  531. (pGdiHandle->hGdi, pIn, cIn, pOut, cOut, ul);
  532. }
  533. BOOL
  534. DeletePrinterIC(
  535. HANDLE hPrinterIC
  536. )
  537. {
  538. LPGDIHANDLE pGdiHandle=(LPGDIHANDLE)hPrinterIC;
  539. if (!pGdiHandle || pGdiHandle->signature != GDIHANDLE_SIGNATURE) {
  540. SetLastError(ERROR_INVALID_HANDLE);
  541. return FALSE;
  542. }
  543. if ((*pGdiHandle->pProvidor->PrintProvidor.fpDeletePrinterIC) (pGdiHandle->hGdi)) {
  544. FreeSplMem(pGdiHandle);
  545. return TRUE;
  546. }
  547. return FALSE;
  548. }
  549. DWORD
  550. PrinterMessageBox(
  551. HANDLE hPrinter,
  552. DWORD Error,
  553. HWND hWnd,
  554. LPWSTR pText,
  555. LPWSTR pCaption,
  556. DWORD dwType
  557. )
  558. {
  559. LPPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
  560. if (!pPrintHandle || pPrintHandle->signature != PRINTHANDLE_SIGNATURE) {
  561. SetLastError(ERROR_INVALID_HANDLE);
  562. return FALSE;
  563. }
  564. return (*pPrintHandle->pProvidor->PrintProvidor.fpPrinterMessageBox)
  565. (hPrinter, Error, hWnd, pText, pCaption, dwType);
  566. }
  567. DWORD
  568. SendRecvBidiData(
  569. IN HANDLE hPrinter,
  570. IN LPCTSTR pAction,
  571. IN PBIDI_REQUEST_CONTAINER pReqData,
  572. OUT PBIDI_RESPONSE_CONTAINER* ppResData
  573. )
  574. {
  575. DWORD dwRet = ERROR_SUCCESS;
  576. LPPRINTHANDLE pPrintHandle = (LPPRINTHANDLE)hPrinter;
  577. //
  578. // Check for valid printer handle
  579. //
  580. if (!pPrintHandle ||
  581. (pPrintHandle->signature != PRINTHANDLE_SIGNATURE) ||
  582. (pPrintHandle->hFileSpooler != INVALID_HANDLE_VALUE))
  583. {
  584. dwRet = ERROR_INVALID_HANDLE;
  585. }
  586. else
  587. {
  588. dwRet = (*pPrintHandle->pProvidor->PrintProvidor.fpSendRecvBidiData)(pPrintHandle->hPrinter,
  589. pAction,
  590. pReqData,
  591. ppResData);
  592. }
  593. return (dwRet);
  594. }
  595. /*++
  596. Routine Name:
  597. SplPromptUIInUsersSession
  598. Routine Description:
  599. Pops message boxes in the user's session.
  600. For Whistler this function shows only message boxes in Spoolsv.exe.
  601. Arguments:
  602. hPrinter -- printer handle
  603. JobId -- job ID
  604. pUIParams -- UI parameters
  605. pResponse -- user's response
  606. Return Value:
  607. TRUE if succeeded
  608. Last Error:
  609. Win32 error
  610. --*/
  611. BOOL
  612. SplPromptUIInUsersSession(
  613. IN HANDLE hPrinter,
  614. IN DWORD JobId,
  615. IN PSHOWUIPARAMS pUIParams,
  616. OUT DWORD *pResponse
  617. )
  618. {
  619. typedef BOOL (*FPPROMPT_UI)(HANDLE, DWORD, PSHOWUIPARAMS, DWORD*);
  620. FPPROMPT_UI fpPromptUIPerSessionUser;
  621. BOOL bRetValue = FALSE;
  622. PPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
  623. if (pPrintHandle && pPrintHandle->signature == PRINTHANDLE_SIGNATURE)
  624. {
  625. if (pPrintHandle->pProvidor == pLocalProvidor &&
  626. (fpPromptUIPerSessionUser = (FPPROMPT_UI)GetProcAddress(pLocalProvidor->hModule,
  627. "LclPromptUIPerSessionUser")))
  628. {
  629. bRetValue = (*fpPromptUIPerSessionUser)(pPrintHandle->hPrinter, JobId, pUIParams, pResponse);
  630. }
  631. else
  632. {
  633. SetLastError(ERROR_NOT_SUPPORTED);
  634. }
  635. }
  636. else
  637. {
  638. SetLastError(ERROR_INVALID_HANDLE);
  639. }
  640. return bRetValue;
  641. }
  642. /*++
  643. Routine Name:
  644. SplIsSessionZero
  645. Routine Description:
  646. Determine is user that submitted a certain job runs in Session 0.
  647. It is used by Canon monitor to determine when to show
  648. resource template base UI versus calling SplPromptUIInUsersSession.
  649. Arguments:
  650. hPrinter -- printer handle
  651. JobId -- job ID
  652. pIsSessionZero -- TRUE if user runs in Session 0
  653. Return Value:
  654. Win32 last error
  655. Last Error:
  656. --*/
  657. DWORD
  658. SplIsSessionZero(
  659. IN HANDLE hPrinter,
  660. IN DWORD JobId,
  661. OUT BOOL *pIsSessionZero
  662. )
  663. {
  664. typedef DWORD (*FPISSESSIONZERO)(HANDLE, DWORD, BOOL*);
  665. FPISSESSIONZERO fpIsSessionZero;
  666. DWORD dwRetValue = ERROR_SUCCESS;
  667. PPRINTHANDLE pPrintHandle=(LPPRINTHANDLE)hPrinter;
  668. if (pPrintHandle && pPrintHandle->signature == PRINTHANDLE_SIGNATURE)
  669. {
  670. if (pPrintHandle->pProvidor == pLocalProvidor &&
  671. (fpIsSessionZero = (FPISSESSIONZERO)GetProcAddress(pLocalProvidor->hModule,
  672. "LclIsSessionZero")))
  673. {
  674. dwRetValue = (*fpIsSessionZero)(pPrintHandle->hPrinter, JobId, pIsSessionZero);
  675. }
  676. else
  677. {
  678. dwRetValue = ERROR_NOT_SUPPORTED;
  679. }
  680. }
  681. else
  682. {
  683. dwRetValue = ERROR_INVALID_HANDLE;
  684. }
  685. return dwRetValue;
  686. }