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.

997 lines
17 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1998 - 1998
  3. All rights reserved.
  4. Module Name:
  5. splperst.cxx
  6. Abstract:
  7. Implementation of spooler persisting code
  8. IPrnStream & IStream
  9. Author:
  10. Adina Trufinescu (AdinaTru) 4-Nov-1998
  11. Revision History:
  12. Lazar Ivanov (LazarI) Jul-2000 - moved from printui.
  13. --*/
  14. #include "precomp.h"
  15. #pragma hdrstop
  16. #include "prnprst.hxx"
  17. #include <initguid.h>
  18. #include "winprtp.h"
  19. class TPrnPersist: public IPrnStream,
  20. public IStream
  21. {
  22. public:
  23. TPrnPersist(
  24. VOID
  25. );
  26. ~TPrnPersist(
  27. VOID
  28. );
  29. //
  30. // IUnknown
  31. //
  32. STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
  33. STDMETHODIMP_(ULONG) AddRef();
  34. STDMETHODIMP_(ULONG) Release();
  35. //
  36. // IPrnStream
  37. //
  38. STDMETHODIMP
  39. BindPrinterAndFile(
  40. IN LPCTSTR pszPrinter,
  41. LPCTSTR pszFile
  42. );
  43. STDMETHODIMP
  44. StorePrinterInfo(
  45. IN DWORD Flag
  46. );
  47. STDMETHODIMP
  48. RestorePrinterInfo(
  49. IN DWORD Flag
  50. );
  51. STDMETHODIMP
  52. QueryPrinterInfo(
  53. IN PrinterPersistentQueryFlag Flag,
  54. OUT PersistentInfo *pPrstInfo
  55. );
  56. //
  57. // IStream
  58. //
  59. HRESULT STDMETHODCALLTYPE
  60. Read( // IMPLEMENTED
  61. VOID * pv,
  62. ULONG cb,
  63. ULONG * pcbRead
  64. );
  65. HRESULT STDMETHODCALLTYPE
  66. Write( //IMPLEMENTED
  67. VOID const* pv,
  68. ULONG cb,
  69. ULONG * pcbWritten
  70. );
  71. HRESULT STDMETHODCALLTYPE
  72. Seek( //IMPLEMENTED
  73. LARGE_INTEGER dlibMove,
  74. DWORD dwOrigin,
  75. ULARGE_INTEGER * plibNewPosition
  76. );
  77. HRESULT STDMETHODCALLTYPE
  78. SetSize(
  79. ULARGE_INTEGER nSize
  80. );
  81. HRESULT STDMETHODCALLTYPE
  82. CopyTo( //NOT_IMPLEMENTED
  83. LPSTREAM pStrm,
  84. ULARGE_INTEGER cb,
  85. ULARGE_INTEGER * pcbRead,
  86. ULARGE_INTEGER * pcbWritten
  87. );
  88. HRESULT STDMETHODCALLTYPE
  89. Commit( //NOT_IMPLEMENTED
  90. IN DWORD dwFlags
  91. );
  92. HRESULT STDMETHODCALLTYPE
  93. Revert( //NOT_IMPLEMENTED
  94. VOID
  95. );
  96. HRESULT STDMETHODCALLTYPE
  97. LockRegion( //NOT_IMPLEMENTED
  98. ULARGE_INTEGER cbOffset,
  99. ULARGE_INTEGER cbLength,
  100. DWORD dwFlags
  101. );
  102. HRESULT STDMETHODCALLTYPE
  103. UnlockRegion( //NOT_IMPLEMENTED
  104. ULARGE_INTEGER cbOffset,
  105. ULARGE_INTEGER cbLength,
  106. DWORD dwFlags
  107. );
  108. HRESULT STDMETHODCALLTYPE
  109. Stat( //NOT_IMPLEMENTED
  110. STATSTG * pStatStg,
  111. DWORD dwFlags
  112. );
  113. HRESULT STDMETHODCALLTYPE
  114. Clone( //NOT_IMPLEMENTED
  115. OUT LPSTREAM * ppStrm
  116. );
  117. private:
  118. LONG m_cRef;
  119. TPrinterPersist *_pPrnPersist;
  120. };
  121. TPrnPersist::
  122. TPrnPersist(
  123. VOID
  124. ): m_cRef(1),
  125. _pPrnPersist(NULL)
  126. {
  127. }
  128. TPrnPersist::
  129. ~TPrnPersist(
  130. VOID
  131. )
  132. {
  133. if( _pPrnPersist )
  134. {
  135. delete _pPrnPersist;
  136. }
  137. }
  138. STDMETHODIMP TPrnPersist::QueryInterface(REFIID riid, void **ppv)
  139. {
  140. if( !ppv )
  141. {
  142. return E_INVALIDARG;
  143. }
  144. *ppv = NULL;
  145. if( IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IPrnStream) )
  146. {
  147. *ppv = static_cast<IPrnStream*>(this);
  148. }
  149. else if( IsEqualIID(riid, IID_IStream) )
  150. {
  151. *ppv = static_cast<IStream*>(this);
  152. }
  153. else
  154. {
  155. return E_NOINTERFACE;
  156. }
  157. reinterpret_cast<IUnknown*>(*ppv)->AddRef();
  158. return S_OK;
  159. }
  160. STDMETHODIMP_(ULONG) TPrnPersist::AddRef()
  161. {
  162. return InterlockedIncrement(&m_cRef);
  163. }
  164. STDMETHODIMP_(ULONG) TPrnPersist::Release()
  165. {
  166. ULONG cRefs = InterlockedDecrement(&m_cRef);
  167. if( 0 == cRefs )
  168. {
  169. delete this;
  170. }
  171. return cRefs;
  172. }
  173. /*++
  174. Name:
  175. TPrnPersist::BindPrinterAndFile
  176. Description:
  177. Creates a PrnStream object if it don't exists and bind it to a printer and a file
  178. Arguments:
  179. printer name
  180. file name
  181. Return Value:
  182. S_OK if succeeded
  183. --*/
  184. STDMETHODIMP
  185. TPrnPersist::
  186. BindPrinterAndFile(
  187. IN LPCTSTR pszPrinter,
  188. IN LPCTSTR pszFile
  189. )
  190. {
  191. HRESULT hr = E_FAIL;
  192. //
  193. // Create the PrnStream location object if this is the first call.
  194. //
  195. if (!_pPrnPersist)
  196. {
  197. _pPrnPersist = new TPrinterPersist;
  198. }
  199. //
  200. // Invoke the BindPrinterAndFile method if the printer stream
  201. // object was create successfully.
  202. //
  203. if (_pPrnPersist != NULL)
  204. {
  205. DBGMSG(DBG_TRACE , ("TPrnPersist::BindPrinterAndFile \n"));
  206. hr = _pPrnPersist->BindPrinterAndFile(pszPrinter, pszFile);
  207. }
  208. else
  209. {
  210. hr = E_OUTOFMEMORY;
  211. }
  212. DBGMSG(DBG_TRACE , ("TPrnPersist::BindPrinterAndFile %x \n" , hr));
  213. return hr;
  214. }
  215. /*++
  216. Name:
  217. TPrnPersist::StorePrinterInfo
  218. Description:
  219. Creates a PrnStream object if it don't exists and invoke StorePrinterInfo
  220. Arguments:
  221. flags that specifies what settings to store
  222. Return Value:
  223. S_OK if succeeded
  224. --*/
  225. STDMETHODIMP
  226. TPrnPersist::
  227. StorePrinterInfo(
  228. IN DWORD Flag
  229. )
  230. {
  231. TStatusH hr;
  232. hr DBGNOCHK = E_FAIL;
  233. DWORD StoredFlags;
  234. //
  235. // Create the PrnStream location object if this is the first call.
  236. //
  237. if (!_pPrnPersist)
  238. {
  239. _pPrnPersist = new TPrinterPersist;
  240. }
  241. //
  242. // Invoke the stote info method if the printer stream
  243. // object was create successfully.
  244. //
  245. DBGMSG(DBG_TRACE , ("TPrnPersist::StorePrinterInfo Flag %x \n" , Flag));
  246. if(_pPrnPersist != NULL)
  247. {
  248. if (VALID_PTR(_pPrnPersist))
  249. {
  250. //
  251. // Winlogon calls this function for TS. We need to catch any possbile exception,
  252. // otherwise we may cause BSOD.
  253. //
  254. __try
  255. {
  256. hr DBGCHK = _pPrnPersist->StorePrinterInfo(Flag, StoredFlags);
  257. }
  258. __except(EXCEPTION_EXECUTE_HANDLER)
  259. {
  260. DBGMSG(DBG_WARNING, ("TPrnPersist::StorePrinterInfo exception %x\n", GetExceptionCode()));
  261. hr DBGCHK = E_FAIL;
  262. }
  263. }
  264. else
  265. {
  266. hr DBGCHK = MakePrnPersistHResult(PRN_PERSIST_ERROR_UNBOUND);
  267. }
  268. }
  269. else
  270. {
  271. hr DBGCHK = E_OUTOFMEMORY;
  272. }
  273. return hr;
  274. }
  275. /*++
  276. Name:
  277. TPrnPersist::RestorePrinterInfo
  278. Description:
  279. Creates a PrnStream object if it don't exists and invoke RestorePrinterInfo
  280. Arguments:
  281. flags that specifies what settings to restore
  282. Return Value:
  283. S_OK if succeeded
  284. --*/
  285. STDMETHODIMP
  286. TPrnPersist::
  287. RestorePrinterInfo(
  288. IN DWORD Flag
  289. )
  290. {
  291. TStatusH hr;
  292. //
  293. // Create the Prnstream location object if this is the first call.
  294. //
  295. if (!_pPrnPersist)
  296. {
  297. _pPrnPersist = new TPrinterPersist;
  298. }
  299. //
  300. // Invoke the restore info method if the printer stream
  301. // object was created successfully.
  302. //
  303. if(_pPrnPersist != NULL)
  304. {
  305. if (VALID_PTR(_pPrnPersist))
  306. {
  307. //
  308. // Winlogon calls this function on the machine where TS runs. If the file from which
  309. // we restore the settings is corrupted, we must protect us against AVs that can occur
  310. // while accessing bad data.
  311. //
  312. __try
  313. {
  314. hr DBGCHK = _pPrnPersist->SafeRestorePrinterInfo(Flag);
  315. }
  316. __except(EXCEPTION_EXECUTE_HANDLER)
  317. {
  318. DBGMSG(DBG_WARNING, ("TPrnPersist::SafeRestorePrinterInfo exception %x\n", GetExceptionCode()));
  319. hr DBGCHK = E_FAIL;
  320. }
  321. }
  322. else
  323. {
  324. hr DBGCHK = MakePrnPersistHResult(PRN_PERSIST_ERROR_UNBOUND);
  325. }
  326. }
  327. else
  328. {
  329. hr DBGCHK = E_OUTOFMEMORY;
  330. }
  331. return hr;
  332. }
  333. /*++
  334. Name:
  335. TPrnPersist::QueryPrinterInfo
  336. Description:
  337. Creates a PrnStream object if it don't exists and invoke QueryPrinterInfo
  338. Arguments:
  339. flags that specifies what settings to query
  340. Return Value:
  341. S_OK if succeeded
  342. --*/
  343. STDMETHODIMP
  344. TPrnPersist::
  345. QueryPrinterInfo(
  346. IN PrinterPersistentQueryFlag Flag,
  347. OUT PersistentInfo *pPrstInfo
  348. )
  349. {
  350. TStatusH hr;
  351. hr DBGNOCHK = E_FAIL;
  352. //
  353. // Create the Prnstream location object if this is the first call.
  354. //
  355. if (!_pPrnPersist)
  356. {
  357. _pPrnPersist = new TPrinterPersist;
  358. }
  359. //
  360. // Invoke the query info method if the printer stream
  361. // object was create successfully.
  362. //
  363. if(_pPrnPersist != NULL)
  364. {
  365. if (VALID_PTR(_pPrnPersist))
  366. {
  367. __try
  368. {
  369. hr DBGCHK = _pPrnPersist->QueryPrinterInfo(Flag , pPrstInfo);
  370. }
  371. __except(EXCEPTION_EXECUTE_HANDLER)
  372. {
  373. DBGMSG(DBG_WARNING, ("TPrnPersist::QueryPrinterInfo exception %x\n", GetExceptionCode()));
  374. hr DBGCHK = E_FAIL;
  375. }
  376. }
  377. else
  378. {
  379. hr DBGCHK = MakePrnPersistHResult(PRN_PERSIST_ERROR_UNBOUND);
  380. }
  381. }
  382. else
  383. {
  384. hr DBGCHK = E_OUTOFMEMORY;
  385. }
  386. return hr;
  387. }
  388. /*++
  389. Name:
  390. TPrnPersist::Read
  391. Description:
  392. Creates a PrnStream object if it don't exists and invoke Read
  393. Arguments:
  394. pv - The buffer that the bytes are read into
  395. cb - The offset in the stream to begin reading from.
  396. pcbRead - The number of bytes to read
  397. Return Value:
  398. S_OK if succeeded
  399. --*/
  400. STDMETHODIMP
  401. TPrnPersist::
  402. Read(
  403. VOID * pv,
  404. ULONG cb,
  405. ULONG * pcbRead
  406. )
  407. {
  408. HRESULT hr = E_FAIL;
  409. //
  410. // Create the Prnstream location object if this is the first call.
  411. //
  412. if (!_pPrnPersist)
  413. {
  414. _pPrnPersist = new TPrinterPersist;
  415. }
  416. //
  417. // Invoke the read method if the printer stream
  418. // object was create successfully.
  419. //
  420. if(_pPrnPersist != NULL)
  421. {
  422. if (VALID_PTR(_pPrnPersist))
  423. {
  424. hr = _pPrnPersist->Read(pv, cb, pcbRead);
  425. }
  426. else
  427. {
  428. hr = MakePrnPersistHResult(PRN_PERSIST_ERROR_UNBOUND);
  429. }
  430. }
  431. else
  432. {
  433. hr = E_OUTOFMEMORY;
  434. }
  435. return hr;
  436. }
  437. /*++
  438. Name:
  439. TPrnPersist::Write
  440. Description:
  441. Creates a PrnStream object if it don't exists and invoke Write
  442. Arguments:
  443. pv - The buffer to write from.
  444. cb - The offset in the array to begin writing from
  445. pcbRead - The number of bytes to write
  446. Return Value:
  447. S_OK if succeeded
  448. --*/
  449. STDMETHODIMP
  450. TPrnPersist::
  451. Write(
  452. VOID const* pv,
  453. ULONG cb,
  454. ULONG * pcbWritten
  455. )
  456. {
  457. HRESULT hr = E_FAIL;
  458. //
  459. // Create the Prnstream location object if this is the first call.
  460. //
  461. if (!_pPrnPersist)
  462. {
  463. _pPrnPersist = new TPrinterPersist;
  464. }
  465. //
  466. // Invoke the write method if the printer stream
  467. // object was create successfully.
  468. //
  469. if(_pPrnPersist != NULL)
  470. {
  471. if (VALID_PTR(_pPrnPersist))
  472. {
  473. hr = _pPrnPersist->Write(pv, cb, pcbWritten);
  474. }
  475. else
  476. {
  477. hr = MakePrnPersistHResult(PRN_PERSIST_ERROR_UNBOUND);
  478. }
  479. }
  480. else
  481. {
  482. hr = E_OUTOFMEMORY;
  483. }
  484. return hr;
  485. }
  486. /*++
  487. Name:
  488. TPrnPersist::Seek
  489. Description:
  490. Creates a PrnStream object if it don't exists and invoke Seek
  491. Arguments:
  492. dlibMove - The offset relative to dwOrigin
  493. dwOrigin - The origin of the offset
  494. plibNewPosition - Pointer to value of the new seek pointer from the beginning of the stream
  495. Return Value:
  496. S_OK if succeeded
  497. --*/
  498. STDMETHODIMP
  499. TPrnPersist::
  500. Seek(
  501. LARGE_INTEGER dlibMove,
  502. DWORD dwOrigin,
  503. ULARGE_INTEGER * plibNewPosition
  504. )
  505. {
  506. HRESULT hr = E_FAIL;
  507. //
  508. // Create the Prnstream location object if this is the first call.
  509. //
  510. if (!_pPrnPersist)
  511. {
  512. _pPrnPersist = new TPrinterPersist;
  513. }
  514. //
  515. // Invoke the seek method if the printer stream
  516. // object was create successfully.
  517. //
  518. if(_pPrnPersist != NULL)
  519. {
  520. if (VALID_PTR(_pPrnPersist))
  521. {
  522. hr = _pPrnPersist->Seek(dlibMove, dwOrigin, plibNewPosition);
  523. }
  524. else
  525. {
  526. hr = MakePrnPersistHResult(PRN_PERSIST_ERROR_UNBOUND);
  527. }
  528. }
  529. else
  530. {
  531. hr = E_OUTOFMEMORY;
  532. }
  533. return hr;
  534. }
  535. /*++
  536. Name:
  537. TPrnPersist::SetSize
  538. Description:
  539. Arguments:
  540. Return Value:
  541. E_NOTIMPL
  542. --*/
  543. STDMETHODIMP
  544. TPrnPersist::
  545. SetSize(
  546. ULARGE_INTEGER nSize
  547. )
  548. {
  549. return E_NOTIMPL;
  550. }
  551. /*++
  552. Name:
  553. TPrnPersist::CopyTo
  554. Description:
  555. Arguments:
  556. Return Value:
  557. E_NOTIMPL
  558. --*/
  559. STDMETHODIMP
  560. TPrnPersist::
  561. CopyTo(
  562. LPSTREAM pStrm,
  563. ULARGE_INTEGER cb,
  564. ULARGE_INTEGER * pcbRead,
  565. ULARGE_INTEGER * pcbWritten
  566. )
  567. {
  568. return E_NOTIMPL;
  569. }
  570. /*++
  571. Name:
  572. TPrnPersist::Commit
  573. Description:
  574. Arguments:
  575. Return Value:
  576. E_NOTIMPL
  577. --*/
  578. STDMETHODIMP
  579. TPrnPersist::
  580. Commit(
  581. IN DWORD dwFlags
  582. )
  583. {
  584. return E_NOTIMPL;
  585. }
  586. /*++
  587. Name:
  588. TPrnPersist::Revert
  589. Description:
  590. Arguments:
  591. Return Value:
  592. E_NOTIMPL
  593. --*/
  594. STDMETHODIMP
  595. TPrnPersist::
  596. Revert(
  597. VOID
  598. )
  599. {
  600. return E_NOTIMPL;
  601. }
  602. /*++
  603. Name:
  604. TPrnPersist::LockRegion
  605. Description:
  606. Arguments:
  607. Return Value:
  608. E_NOTIMPL
  609. --*/
  610. STDMETHODIMP
  611. TPrnPersist::
  612. LockRegion(
  613. ULARGE_INTEGER cbOffset,
  614. ULARGE_INTEGER cbLength,
  615. DWORD dwFlags
  616. )
  617. {
  618. return E_NOTIMPL;
  619. }
  620. /*++
  621. Name:
  622. TPrnPersist::UnlockRegion
  623. Description:
  624. Arguments:
  625. Return Value:
  626. E_NOTIMPL
  627. --*/
  628. STDMETHODIMP
  629. TPrnPersist::
  630. UnlockRegion(
  631. ULARGE_INTEGER cbOffset,
  632. ULARGE_INTEGER cbLength,
  633. DWORD dwFlags
  634. )
  635. {
  636. return E_NOTIMPL;
  637. }
  638. /*++
  639. Name:
  640. TPrnPersist::Stat
  641. Description:
  642. Arguments:
  643. Return Value:
  644. E_NOTIMPL
  645. --*/
  646. STDMETHODIMP
  647. TPrnPersist::
  648. Stat(
  649. STATSTG * pStatStg,
  650. DWORD dwFlags
  651. )
  652. {
  653. return E_NOTIMPL;
  654. }
  655. /*++
  656. Name:
  657. TPrnPersist::Clone
  658. Description:
  659. Arguments:
  660. Return Value:
  661. E_NOTIMPL
  662. --*/
  663. STDMETHODIMP
  664. TPrnPersist::
  665. Clone(
  666. LPSTREAM * ppStrm
  667. )
  668. {
  669. return E_NOTIMPL;
  670. }
  671. #ifdef __cplusplus
  672. extern "C" {
  673. #endif
  674. // forward declarations....
  675. HRESULT TPrnPersist_CreateInstance(REFIID riid, void **ppv);
  676. BOOL WebPnpEntry(LPCTSTR lpszCmdLine);
  677. BOOL WebPnpPostEntry(BOOL fConnection, LPCTSTR lpszBinFile, LPCTSTR lpszPortName, LPCTSTR lpszPrtName);
  678. /*++
  679. Name:
  680. TPrnPersist_CreateInstance
  681. Description:
  682. creates an instance of TPrnPersist
  683. Arguments:
  684. Return Value:
  685. S_OK on sucsess or OLE error on failure.
  686. --*/
  687. HRESULT TPrnPersist_CreateInstance(
  688. IN REFIID riid,
  689. OUT void **ppv
  690. )
  691. {
  692. HRESULT hr = E_INVALIDARG;
  693. if( ppv )
  694. {
  695. *ppv = NULL;
  696. TPrnPersist *pObj = new TPrnPersist;
  697. if( pObj )
  698. {
  699. hr = pObj->QueryInterface( riid, ppv );
  700. pObj->Release( );
  701. }
  702. else
  703. {
  704. hr = E_OUTOFMEMORY;
  705. }
  706. }
  707. return hr;
  708. }
  709. /*++
  710. Name:
  711. PrintUIWebPnpEntry
  712. Description:
  713. wrapper around WebPnpEntry
  714. Arguments:
  715. Return Value:
  716. S_OK on sucsess or OLE error on failure.
  717. --*/
  718. HRESULT PrintUIWebPnpEntry(
  719. LPCTSTR lpszCmdLine
  720. )
  721. {
  722. return WebPnpEntry(lpszCmdLine) ? S_OK : E_FAIL;
  723. }
  724. /*++
  725. Name:
  726. PrintUIWebPnpPostEntry
  727. Description:
  728. wrapper around WebPnpPostEntry
  729. Arguments:
  730. Return Value:
  731. S_OK on sucsess or OLE error on failure.
  732. --*/
  733. HRESULT PrintUIWebPnpPostEntry(BOOL fConnection, LPCTSTR lpszBinFile, LPCTSTR lpszPortName, LPCTSTR lpszPrtName)
  734. {
  735. return WebPnpPostEntry(fConnection, lpszBinFile, lpszPortName, lpszPrtName) ? S_OK : E_FAIL;
  736. }
  737. /*++
  738. Name:
  739. PrintUICreateInstance
  740. Description:
  741. wrapper around TPrnPersist_CreateInstance
  742. Arguments:
  743. Return Value:
  744. S_OK on sucsess or OLE error on failure.
  745. --*/
  746. HRESULT PrintUICreateInstance(REFIID riid, void **ppv)
  747. {
  748. return TPrnPersist_CreateInstance(riid, ppv);
  749. }
  750. #ifdef __cplusplus
  751. }
  752. #endif