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.

979 lines
18 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1995 - 1999
  3. All rights reserved.
  4. Module Name:
  5. folder.hxx
  6. Abstract:
  7. Holds TServerNotify definitions.
  8. Author:
  9. Albert Ting (AlbertT) 30-Oct-1995
  10. Revision History:
  11. --*/
  12. #ifndef _FOLDER_HXX
  13. #define _FOLDER_HXX
  14. class TFolder;
  15. /********************************************************************
  16. Class summary:
  17. TFolder: This objects represents the print folder (local or
  18. remote) that a user opens in the UI. It uses TConnectionNotify
  19. to watch for new changes, and then creates TServers to hold
  20. the server/printer data.
  21. Destruction refcounted.
  22. TConnectionNotify: if the Folder is local, then TFolder creates
  23. and owns this. This object is responsible for telling
  24. TFolder (via ConnectionNotifyClient) that the registry has
  25. changed and TFolder should walk through its TServers, either
  26. adding new ones or deleting old ones. (Compare EnumPrinters
  27. with INFO_4 vs TFolder's linked list.)
  28. Destruction sync'd with TFolder.
  29. VDataSource: watch set of printers. This class is responsible for
  30. keeping and updating data about a server/printer. It also
  31. sends out notifications to the shell when something changes.
  32. It uses TPrinter to get the data. TDSServer and VDSConnection
  33. derive from this class.
  34. Destruction refcounted.
  35. TDSServer: watch a server with >=0 printers.
  36. The single data source will return many printers. It
  37. will internally enumerate masq printers, but it won't
  38. return them via Get/EnumPrinters.
  39. Inherits from VDataSource.
  40. VDSConnection: watch a connection with 1 printer. This is
  41. needed is true connects don't appear on the server, and
  42. masq printers appear but are inaccurate.
  43. Inherits from VDataSource.
  44. TDSCTrue: watch a VDSConnection (true connect)
  45. Inherits from VDSConnection since we gather information
  46. from a separate handle.
  47. TDSCMasq: watch a VDSConnection (masq connect).
  48. Inherits from VDSConnection since we gather information
  49. from a separate handle.
  50. TNotifyHandler:
  51. Utility class. Holder of IFolderNotify* handlers allowing to be
  52. chained in a linked list.
  53. ********************************************************************/
  54. /********************************************************************
  55. TConnectionNotify
  56. Watch the registry looking for new printer addition. When
  57. a new connection has been created, add the the TServer (actually
  58. a printer) to pFolder.
  59. Client constructs with a registry path off of HKEY_CURRENT_USER
  60. and passes in a callback. When the registry node changes, the
  61. callback is triggered.
  62. ********************************************************************/
  63. class TConnectionNotify : public MNotifyWork
  64. {
  65. SIGNATURE( 'regn' )
  66. SAFE_NEW
  67. public:
  68. TConnectionNotify(
  69. TFolder* pFolder
  70. );
  71. ~TConnectionNotify(
  72. VOID
  73. );
  74. BOOL
  75. bValid(
  76. VOID
  77. ) const;
  78. private:
  79. TFolder *_pFolder;
  80. CAutoHandleHKEY _shKeyConnections;
  81. CAutoHandleNT _shEvent;
  82. BOOL _bRegistered;
  83. BOOL
  84. bSetupNotify(
  85. VOID
  86. );
  87. /********************************************************************
  88. Virtual definition MNotifyWork.
  89. ********************************************************************/
  90. HANDLE
  91. hEvent(
  92. VOID
  93. ) const;
  94. VOID
  95. vProcessNotifyWork(
  96. TNotify* pNotify
  97. );
  98. };
  99. inline
  100. BOOL
  101. TConnectionNotify::
  102. bValid(
  103. VOID
  104. ) const
  105. {
  106. return _shEvent != NULL && MNotifyWork::bValid();
  107. }
  108. /********************************************************************
  109. VDataSource
  110. VDataSource uses the name constructor class factory idiom.
  111. Instead of using the normal ctr, client should use pNew(),
  112. which instantiates a derieved, concrete class of VDataSource.
  113. ********************************************************************/
  114. class VDataSource : public MPrinterClient {
  115. SIGNATURE( 'daso' )
  116. SAFE_NEW
  117. public:
  118. enum CONNECT_TYPE {
  119. kServer,
  120. kTrue,
  121. kMasq
  122. };
  123. VAR( TString, strDataSource );
  124. VAR( CONNECT_TYPE, ConnectType );
  125. DLINK( VDataSource, DataSource );
  126. /********************************************************************
  127. Separate constructor/destructor since we always build
  128. a derived class of VDataSource (based on ConnectType).
  129. ********************************************************************/
  130. static
  131. VDataSource*
  132. pNew(
  133. TFolder* pFolder,
  134. LPCTSTR pszServer,
  135. CONNECT_TYPE ConnectType
  136. );
  137. VOID
  138. vDelete(
  139. VOID
  140. );
  141. BOOL
  142. bValid(
  143. VOID
  144. ) const;
  145. HANDLE
  146. hItemFindByName(
  147. LPCTSTR pszPrinter
  148. ) const;
  149. BOOL
  150. bSkipItem(
  151. HANDLE hItem
  152. ) const;
  153. /********************************************************************
  154. Overrides that derived classes can define.
  155. ********************************************************************/
  156. virtual
  157. BOOL
  158. bRefresh(
  159. VOID
  160. ) = 0;
  161. virtual
  162. BOOL
  163. bReopen(
  164. VOID
  165. ) = 0;
  166. virtual
  167. BOOL
  168. bGetPrinter(
  169. LPCTSTR pszPrinter,
  170. PFOLDER_PRINTER_DATA pData,
  171. DWORD cbData,
  172. PDWORD pcbNeeded
  173. ) const;
  174. virtual
  175. BOOL
  176. bAdministrator(
  177. VOID
  178. ) const = 0;
  179. virtual
  180. COUNTB
  181. cbSinglePrinterData(
  182. HANDLE hItem
  183. ) const;
  184. virtual
  185. VOID
  186. vPackSinglePrinterData(
  187. HANDLE hItem,
  188. PBYTE& pBegin,
  189. PBYTE& pEnd
  190. ) const;
  191. virtual
  192. COUNTB
  193. cbAllPrinterData(
  194. VOID
  195. ) const;
  196. virtual
  197. COUNT
  198. cPackAllPrinterData(
  199. PBYTE& pBegin,
  200. PBYTE& pEnd
  201. ) const;
  202. protected:
  203. TFolder* _pFolder;
  204. COUNT _cIgnoreNotifications;
  205. LONG _lItems;
  206. VDataSource(
  207. TFolder* pFolder,
  208. LPCTSTR pszDataSource,
  209. CONNECT_TYPE ConnectType
  210. );
  211. ~VDataSource(
  212. VOID
  213. );
  214. virtual
  215. VOID
  216. vContainerChanged(
  217. CONTAINER_CHANGE ContainerChange,
  218. INFO Info
  219. );
  220. virtual
  221. BOOL
  222. bGetPrintLib(
  223. TRefLock<TPrintLib> &refLock
  224. ) const;
  225. /********************************************************************
  226. Data retrieval.
  227. ********************************************************************/
  228. virtual
  229. LPCTSTR
  230. pszGetPrinterName(
  231. HANDLE hItem
  232. ) const = 0;
  233. virtual
  234. LPCTSTR
  235. pszGetCommentString(
  236. HANDLE hItem
  237. ) const;
  238. virtual
  239. LPCTSTR
  240. pszGetLocationString(
  241. HANDLE hItem
  242. ) const;
  243. virtual
  244. LPCTSTR
  245. pszGetModelString(
  246. HANDLE hItem
  247. ) const;
  248. virtual
  249. LPCTSTR
  250. VDataSource::
  251. pszGetPortString(
  252. HANDLE hItem
  253. ) const;
  254. private:
  255. /********************************************************************
  256. Change callbacks and support.
  257. ********************************************************************/
  258. virtual
  259. VOID
  260. vReloadItems(
  261. VOID
  262. ) = 0;
  263. virtual
  264. VOID
  265. vRefreshComplete(
  266. VOID
  267. ) const = 0;
  268. virtual
  269. FOLDER_NOTIFY_TYPE
  270. uItemCreate(
  271. LPCTSTR pszPrinter,
  272. BOOL bNotify
  273. ) = 0;
  274. /********************************************************************
  275. MPrinterClient / MDataClient virtual definitions.
  276. ********************************************************************/
  277. VOID
  278. vItemChanged(
  279. ITEM_CHANGE ItemChange,
  280. HITEM hItem,
  281. INFO Info,
  282. INFO InfoNew
  283. );
  284. VDataNotify*
  285. pNewNotify(
  286. MDataClient* pDataClient
  287. ) const;
  288. VDataRefresh*
  289. pNewRefresh(
  290. MDataClient* pDataClient
  291. ) const;
  292. VOID
  293. vRefZeroed(
  294. VOID
  295. );
  296. };
  297. inline
  298. BOOL
  299. VDataSource::
  300. bValid(
  301. VOID
  302. ) const
  303. {
  304. return _pPrinter != NULL && MPrinterClient::bValid();
  305. }
  306. /********************************************************************
  307. TDSServer
  308. Watch a server for printers. We can also watch a particular
  309. printer (\\server\share) and it will act like a server with
  310. just one printer.
  311. ********************************************************************/
  312. class TDSServer : public VDataSource {
  313. friend
  314. VDataSource*
  315. VDataSource::pNew(
  316. TFolder* pFolder,
  317. LPCTSTR pszServer,
  318. CONNECT_TYPE ConnectType
  319. );
  320. SIGNATURE( 'dssv' )
  321. private:
  322. BOOL _bDiscardRefresh;
  323. TDSServer(
  324. TFolder* pFolder,
  325. LPCTSTR pszDataSource
  326. );
  327. BOOL
  328. bRefresh(
  329. VOID
  330. );
  331. BOOL
  332. bReopen(
  333. VOID
  334. );
  335. /********************************************************************
  336. Data retrieval.
  337. ********************************************************************/
  338. LPCTSTR
  339. pszGetPrinterName(
  340. HANDLE hItem
  341. ) const;
  342. BOOL
  343. bAdministrator(
  344. VOID
  345. ) const;
  346. BOOL
  347. bGetPrinter(
  348. LPCTSTR pszPrinter,
  349. PFOLDER_PRINTER_DATA pData,
  350. DWORD cbData,
  351. PDWORD pcbNeeded
  352. ) const;
  353. /********************************************************************
  354. Change callbacks and support.
  355. ********************************************************************/
  356. VOID
  357. vContainerChanged(
  358. CONTAINER_CHANGE ContainerChange,
  359. INFO Info
  360. );
  361. VOID
  362. vReloadItems(
  363. VOID
  364. );
  365. VOID
  366. vRefreshComplete(
  367. VOID
  368. ) const;
  369. FOLDER_NOTIFY_TYPE
  370. uItemCreate(
  371. LPCTSTR pszPrinter,
  372. BOOL bNotify
  373. );
  374. };
  375. /********************************************************************
  376. VDSConnection
  377. Watch a connection.
  378. ********************************************************************/
  379. class VDSConnection : public VDataSource {
  380. SIGNATURE( 'dscn' )
  381. public:
  382. static
  383. BOOL
  384. bStaticInitShutdown(
  385. BOOL bShutdown = FALSE
  386. );
  387. protected:
  388. VDSConnection(
  389. TFolder* pFolder,
  390. LPCTSTR pszDataSource,
  391. CONNECT_TYPE ConnectType
  392. );
  393. private:
  394. friend
  395. VDataSource*
  396. VDataSource::pNew(
  397. TFolder* pFolder,
  398. LPCTSTR pszServer,
  399. CONNECT_TYPE ConnectType
  400. );
  401. CONNECT_STATUS _ConnectStatus;
  402. static TString *gpstrConnectStatusOpen;
  403. static TString *gpstrConnectStatusOpenError;
  404. static TString *gpstrConnectStatusAccessDenied;
  405. static TString *gpstrConnectStatusInvalidPrinterName;
  406. BOOL
  407. bRefresh(
  408. VOID
  409. );
  410. BOOL
  411. bReopen(
  412. VOID
  413. );
  414. /********************************************************************
  415. Data retrieval.
  416. ********************************************************************/
  417. LPCTSTR
  418. pszGetPrinterName(
  419. HANDLE hItem
  420. ) const;
  421. LPCTSTR
  422. pszGetCommentString(
  423. HANDLE hItem
  424. ) const;
  425. LPCTSTR
  426. pszGetStatusString(
  427. HANDLE hItem
  428. ) const;
  429. BOOL
  430. bAdministrator(
  431. VOID
  432. ) const;
  433. BOOL
  434. bGetPrinter(
  435. LPCTSTR pszPrinter,
  436. PFOLDER_PRINTER_DATA pData,
  437. DWORD cbData,
  438. PDWORD pcbNeeded
  439. ) const;
  440. COUNTB
  441. cbSinglePrinterData(
  442. HANDLE hItem
  443. ) const;
  444. VOID
  445. vPackSinglePrinterData(
  446. HANDLE hItem,
  447. PBYTE& pBegin,
  448. PBYTE& pEnd
  449. ) const;
  450. COUNTB
  451. cbAllPrinterData(
  452. VOID
  453. ) const;
  454. COUNT
  455. cPackAllPrinterData(
  456. PBYTE& pBegin,
  457. PBYTE& pEnd
  458. ) const;
  459. BOOL
  460. bUseFakePrinterData(
  461. VOID
  462. ) const;
  463. /********************************************************************
  464. Change callbacks and support.
  465. ********************************************************************/
  466. VOID
  467. vContainerChanged(
  468. CONTAINER_CHANGE ContainerChange,
  469. INFO Info
  470. );
  471. VOID
  472. vReloadItems(
  473. VOID
  474. );
  475. VOID
  476. vRefreshComplete(
  477. VOID
  478. ) const;
  479. FOLDER_NOTIFY_TYPE
  480. uItemCreate(
  481. LPCTSTR pszPrinter,
  482. BOOL bNotify
  483. );
  484. VOID
  485. vUpdateConnectStatus(
  486. CONNECT_STATUS ConnectStatusNew
  487. );
  488. };
  489. /********************************************************************
  490. TDSCTrue: watch a true connection.
  491. ********************************************************************/
  492. class TDSCTrue : public VDSConnection {
  493. friend
  494. VDataSource*
  495. VDataSource::pNew(
  496. TFolder* pFolder,
  497. LPCTSTR pszServer,
  498. CONNECT_TYPE ConnectType
  499. );
  500. private:
  501. TDSCTrue(
  502. TFolder *pFolder,
  503. LPCTSTR pszDataSource
  504. );
  505. ~TDSCTrue(
  506. VOID
  507. );
  508. BOOL
  509. bValid(
  510. VOID
  511. ) const;
  512. };
  513. inline
  514. BOOL
  515. TDSCTrue::
  516. bValid(
  517. VOID
  518. ) const
  519. {
  520. return VDSConnection::bValid();
  521. }
  522. /********************************************************************
  523. TDSCMasq: watch a masq or 'false' connection.
  524. ********************************************************************/
  525. class TDSCMasq : public VDSConnection {
  526. friend
  527. VDataSource*
  528. VDataSource::pNew(
  529. TFolder* pFolder,
  530. LPCTSTR pszServer,
  531. CONNECT_TYPE ConnectType
  532. );
  533. private:
  534. TDSCMasq(
  535. TFolder *pFolder,
  536. LPCTSTR pszDataSource
  537. );
  538. ~TDSCMasq(
  539. VOID
  540. );
  541. BOOL
  542. bValid(
  543. VOID
  544. ) const;
  545. };
  546. inline
  547. BOOL
  548. TDSCMasq::
  549. bValid(
  550. VOID
  551. ) const
  552. {
  553. return VDSConnection::bValid();
  554. }
  555. /********************************************************************
  556. TFolder
  557. Watch a server. If the server is local (NULL) then we have
  558. to watch printer connections also. Too bad the spooler wasn't
  559. architected to do this for us... maybe the next one will.
  560. ********************************************************************/
  561. class TFolder : public MRefCom
  562. {
  563. SIGNATURE( 'fold' )
  564. SAFE_NEW
  565. class TNotifyHandler {
  566. SIGNATURE( 'tnhd' )
  567. SAFE_NEW
  568. //
  569. // To prevent accidental copying of this object
  570. //
  571. TNotifyHandler( const TNotifyHandler& );
  572. TNotifyHandler& operator =( const TNotifyHandler& );
  573. public:
  574. TNotifyHandler(
  575. IFolderNotify *pClientNotify
  576. );
  577. ~TNotifyHandler(
  578. VOID
  579. );
  580. VAR( BOOL, bValid );
  581. VAR( IFolderNotify*, pClientNotify );
  582. DLINK( TNotifyHandler, Link );
  583. };
  584. public:
  585. VAR( BOOL, bValid );
  586. VAR( TConnectionNotify*, pConnectionNotify );
  587. DLINK_BASE( VDataSource, DataSource, DataSource );
  588. VAR( CCSLock, CritSec );
  589. VAR( TRefLock<TPrintLib>, pPrintLib );
  590. DLINK_BASE( TNotifyHandler, Handlers, Link );
  591. VAR( TString, strLocalDataSource );
  592. DLINK( TFolder, Link );
  593. TFolder(
  594. IN LPCTSTR pszDataSource
  595. );
  596. ~TFolder(
  597. VOID
  598. );
  599. HRESULT
  600. pLookupNotifyHandler(
  601. IN IFolderNotify *pClientNotify,
  602. OUT TNotifyHandler **ppHandler
  603. );
  604. HRESULT
  605. RegisterNotifyHandler(
  606. IN IFolderNotify *pClientNotify
  607. );
  608. HRESULT
  609. UnregisterNotifyHandler(
  610. IN IFolderNotify *pClientNotify
  611. );
  612. BOOL
  613. bNotifyAllClients(
  614. IN FOLDER_NOTIFY_TYPE NotifyType,
  615. IN LPCWSTR pszName,
  616. IN LPCWSTR pszNewName
  617. );
  618. BOOL
  619. bLocal(
  620. VOID
  621. ) const;
  622. //
  623. // Called when the system needs to refresh a window because
  624. // of a large change.
  625. //
  626. VOID
  627. vRefreshUI(
  628. VOID
  629. );
  630. VOID
  631. vCleanup(
  632. VOID
  633. );
  634. VOID
  635. vAddDataSource(
  636. LPCTSTR pszPrinter,
  637. VDataSource::CONNECT_TYPE ConnectType,
  638. BOOL bNotify
  639. );
  640. VOID
  641. vAddMasqDataSource(
  642. LPCTSTR pszPrinter,
  643. BOOL bNotify
  644. );
  645. VOID
  646. vDeleteMasqDataSource(
  647. LPCTSTR pszPrinter
  648. );
  649. VOID
  650. vRevalidateMasqPrinters(
  651. VOID
  652. );
  653. static
  654. VOID
  655. vDefaultPrinterChanged(
  656. VOID
  657. );
  658. static
  659. VOID
  660. vCheckDeleteDefault(
  661. LPCTSTR pszDeleted
  662. );
  663. /********************************************************************
  664. Connection notify override.
  665. We receive change notification callbacks from this virtual
  666. function definition.
  667. ********************************************************************/
  668. VOID
  669. vConnectionNotifyChange(
  670. BOOL bNotify
  671. );
  672. private:
  673. VDataSource*
  674. pFindDataSource(
  675. LPCTSTR pszPrinter,
  676. VDataSource::CONNECT_TYPE ConnectType
  677. ) const;
  678. /********************************************************************
  679. MRefCom override.
  680. ********************************************************************/
  681. VOID
  682. vRefZeroed(
  683. VOID
  684. );
  685. };
  686. /********************************************************************
  687. class TFolderList
  688. ********************************************************************/
  689. class TFolderList {
  690. SIGNATURE( 'fldl' )
  691. SAFE_NEW
  692. //
  693. // To prevent accidental copying of this object
  694. //
  695. TFolderList( const TFolderList& );
  696. TFolderList& operator =( const TFolderList& );
  697. public:
  698. TFolderList( );
  699. ~TFolderList( );
  700. static HRESULT
  701. RegisterDataSource(
  702. IN LPCTSTR pszDataSource,
  703. IN IFolderNotify *pClientNotify,
  704. OUT LPHANDLE phFolder,
  705. OUT PBOOL pbAdministrator OPTIONAL
  706. );
  707. static HRESULT
  708. UnregisterDataSource(
  709. IN LPCTSTR pszDataSource,
  710. IN IFolderNotify *pClientNotify,
  711. OUT LPHANDLE phFolder
  712. );
  713. static BOOL
  714. bValidFolderObject(
  715. IN const TFolder *pFolder
  716. );
  717. BOOL
  718. bValid(
  719. VOID
  720. ) const;
  721. //
  722. // This global lock serializes the calls to the external PrintUI cache
  723. // private APIs.
  724. //
  725. static CCSLock *gpFolderLock;
  726. private:
  727. static HRESULT
  728. pLookupFolder(
  729. IN LPCTSTR pszDataSource,
  730. OUT TFolder **ppFolder
  731. );
  732. DLINK_BASE( TFolder, Folders, Link ); // List of the registered folders
  733. static TFolderList *gpFolders; // Global TFolder cashe for the library
  734. };
  735. #endif // ndef _FOLDER_HXX