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.

1445 lines
33 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1995 - 1999
  3. All rights reserved.
  4. Module Name:
  5. data.hxx
  6. Abstract:
  7. Queries the printer for Item data.
  8. Author:
  9. Albert Ting (AlbertT) 27-Jan-1995
  10. Revision History:
  11. --*/
  12. #ifndef _DATA_HXX
  13. #define _DATA_HXX
  14. class VDataNotify;
  15. class VDataRefresh;
  16. class MDataClient;
  17. class TPrintLib;
  18. /********************************************************************
  19. The FieldTable translates a DATA_INDEX index into a field value.
  20. The DATA_INDEX is used in GetInfo.
  21. ********************************************************************/
  22. typedef struct FIELD_TABLE {
  23. UINT cFields;
  24. PFIELD pFields;
  25. } *PFIELD_TABLE;
  26. /********************************************************************
  27. ITEM and PRINTER changes.
  28. When a change occurs, a callback is called with a ITEM_CHANGE or
  29. CONTAINER_CHANGE parameter that indicates how the object changed.
  30. ********************************************************************/
  31. enum ITEM_CHANGE {
  32. kItemNull, // Prevent 0 message value.
  33. kItemCreate, // Item being created.
  34. kItemDelete, // Item being deleted.
  35. kItemPosition, // Item position changed.
  36. kItemInfo, // Affects list/icon and report view.
  37. kItemAttributes, // Affects report view only (not list/icon view).
  38. kItemName, // Item name changed.
  39. kItemSecurity, // Item security change.
  40. };
  41. enum CONTAINER_CHANGE {
  42. kContainerNull,
  43. kContainerConnectStatus, // Connect state changed -> add to title bar
  44. kContainerErrorStatus, // Error occured -> add to status bar
  45. kContainerServerName, // Server name changed
  46. kContainerName, // Container name changed
  47. kContainerStatus, // Container status changed -> add to title bar
  48. kContainerAttributes, // Attributes changed
  49. kContainerStateVar, // StateVar additions
  50. kContainerNewBlock, // New data block available
  51. /********************************************************************
  52. The following are synchronous, but may be called from
  53. any thread.
  54. ********************************************************************/
  55. //
  56. // UI should release all references to VData data. This occurs
  57. // either at the start of a refresh, or when VData is being deleted.
  58. // Called from any thread.
  59. // INFO = VOID
  60. //
  61. kContainerClearItems,
  62. //
  63. // Refresh data has been completely sent to UI thread; called from
  64. // UI thread only.
  65. // INFO = VOID
  66. //
  67. kContainerRefreshComplete,
  68. //
  69. // Reload based on new hBlock; called from UI thread only.
  70. // INFO = cItems.
  71. //
  72. // A drastic change has occured to the datastore. The data object
  73. // now contains INFO new items. During this call, the client
  74. // should release all pointer references to old objects and
  75. // reload the UI with the new objects.
  76. //
  77. // It will get a RefreshComplete when the reload has completed.
  78. //
  79. kContainerReloadItems
  80. };
  81. /********************************************************************
  82. Connect status codes and map.
  83. Note: if you change or move any of the CONNECT_STATUS k* contants,
  84. you must update the CONNECT_STATUS_MAP. Used by queue.cxx code.
  85. ********************************************************************/
  86. enum CONNECT_STATUS {
  87. kConnectStatusNull = 0,
  88. kConnectStatusInvalidPrinterName,
  89. kConnectStatusAccessDenied,
  90. kConnectStatusOpenError,
  91. kConnectStatusOpen,
  92. kConnectStatusInitialize,
  93. kConnectStatusRefresh,
  94. kConnectStatusCommand,
  95. kConnectStatusPoll
  96. };
  97. #define CONNECT_STATUS_MAP { \
  98. 0, \
  99. IDS_SB_INVALID_PRINTER_NAME, \
  100. IDS_SB_ACCESS_DENIED, \
  101. IDS_SB_OPEN_ERROR, \
  102. IDS_SB_OPEN, \
  103. IDS_SB_INITIALIZE, \
  104. IDS_SB_REFRESH, \
  105. IDS_SB_COMMAND, \
  106. IDS_SB_POLL \
  107. }
  108. typedef HANDLE HITEM, *PHITEM; // Opaque packet holding job item info.
  109. typedef UINT DATA_INDEX, *PDATA_INDEX; // Selector for printer data.
  110. /********************************************************************
  111. MDataClient
  112. User of Data structure supports this interface. Both the
  113. Queue and Printer support this interface.
  114. The support could be placed in Queue only, allowing Data to
  115. talk through Printer.Queue, but the lifetime of Queue is managed
  116. through Printer, so we must still talk through printer.
  117. (The lifetime of Printer is identical to Data.)
  118. ********************************************************************/
  119. class VInfoClient {
  120. public:
  121. /********************************************************************
  122. Callbacks for VData
  123. vContainerChanged( ContainerChange, Info )
  124. Indicates something Container wide has changed.
  125. May be called from UI, Notify, or Worker thread.
  126. vItemChanged( ItemChange, hItem, Info, InfoNew );
  127. Indicates that a single Item has changed and needs to be
  128. refreshed.
  129. Only called from UI thread.
  130. ********************************************************************/
  131. //
  132. // Something printer wide has changed. Notify the UI thread.
  133. // This call must return quickly, and can not use any
  134. // SendMessages since it acquires the printer critical section.
  135. //
  136. virtual
  137. VOID
  138. vContainerChanged(
  139. CONTAINER_CHANGE ContainerChange,
  140. INFO Info
  141. ) = 0;
  142. //
  143. // A single Item has changed (or possibly moved). Notify the
  144. // UI that it needs to refresh. Always called from UI thread.
  145. //
  146. virtual
  147. VOID
  148. vItemChanged(
  149. ITEM_CHANGE ItemChange,
  150. HITEM hItem,
  151. INFO Info,
  152. INFO InfoNew
  153. ) = 0;
  154. /********************************************************************
  155. Saving and restoring selections.
  156. ********************************************************************/
  157. //
  158. // When all Items change, the client needs to save its solections,
  159. // refresh, then restore selections. After we call vContainerChanged
  160. // with new Items, we restore the selections.
  161. //
  162. // These calls are _non-reentrant_ since they are called from the
  163. // UI thread.
  164. //
  165. virtual
  166. VOID
  167. vSaveSelections(
  168. VOID
  169. ) = 0;
  170. virtual
  171. VOID
  172. vRestoreSelections(
  173. VOID
  174. ) = 0;
  175. /********************************************************************
  176. Creation of TData{Refresh/Notify}.
  177. ********************************************************************/
  178. virtual
  179. VDataNotify*
  180. pNewNotify(
  181. MDataClient* pDataClient
  182. ) const = 0;
  183. virtual
  184. VDataRefresh*
  185. pNewRefresh(
  186. MDataClient* pDataClient
  187. ) const = 0;
  188. };
  189. class MDataClient : public VInfoClient {
  190. SIGNATURE( 'dtc' )
  191. public:
  192. virtual
  193. LPTSTR
  194. pszServerName(
  195. size_t cchBuffer,
  196. LPTSTR pszServerBuffer
  197. ) const = 0;
  198. virtual
  199. LPTSTR
  200. pszPrinterName(
  201. size_t cchBuffer,
  202. LPTSTR pszServerBuffer
  203. ) const = 0;
  204. virtual
  205. HANDLE
  206. hPrinter(
  207. VOID
  208. ) const = 0;
  209. virtual
  210. HANDLE
  211. hPrinterNew(
  212. VOID
  213. ) const = 0;
  214. virtual
  215. BOOL
  216. bGetPrintLib(
  217. TRefLock<TPrintLib> &refLock
  218. ) const = 0;
  219. };
  220. /********************************************************************
  221. VData provides an abstraction layer for retrieving data and
  222. notifications from a printer. The TPrinter object gets the
  223. hPrinter and hEvent, then allows VData to reference them.
  224. The state of the notification is managed through the following
  225. worker functions:
  226. svStart - Begins the notification
  227. svEnd - Ends the notification
  228. svRefresh - Refreshs data about the connection
  229. These worker functions return a STATEVAR. The printer/
  230. notification is managed as a simple state machine. When
  231. a call fails, the StateVar indicates what should happen
  232. next (it is not intended to return error code information).
  233. The VData will retrieve a Item buffer using GetItem. To retrieve
  234. specific field data about a Item (such as page count, time
  235. submitted, etc.), call GetInfo with the field index.
  236. GetItem - Gets an hItem based on Item order index.
  237. GetInfo - Gets info about a particular hItem.
  238. GetId - Gets Item id about a particular hItem.
  239. GetNaturalIndex - Gets the natural index of a ItemId.
  240. For example,
  241. hItem = pData->GetItem( NaturalIndex );
  242. if( hItem ){
  243. Info = GetInfo( hItem, DataIndexForName );
  244. }
  245. if( Info.pszData ){
  246. OutputDebugString( Info.pszData );
  247. }
  248. The VData* type _must_ call vRefreshComplete (inherited from
  249. VData*) as soon as a refresh has occurred, but before it
  250. re-initializes the notification scheme. This allows the client
  251. to know the boundary between pre-refresh notifications and
  252. post-refresh.
  253. ********************************************************************/
  254. class VData : public MNotifyWork {
  255. SIGNATURE( 'dtv' )
  256. public:
  257. CAutoHandlePrinterNotify m_shNotify;
  258. /********************************************************************
  259. Creation and deletion should be handled from pNew and
  260. vDelete rather than the regular new and delete, since
  261. we create a derived class that is determined at runtime.
  262. ********************************************************************/
  263. static
  264. STATEVAR
  265. svNew(
  266. IN MDataClient* pDataClient,
  267. IN STATEVAR StateVar,
  268. OUT VData*& pData
  269. );
  270. VOID
  271. vDelete(
  272. VOID
  273. );
  274. BOOL
  275. bValid(
  276. VOID
  277. ) const;
  278. COUNT
  279. cItems(
  280. VOID
  281. ) const
  282. {
  283. return UIGuard._cItems;
  284. }
  285. /********************************************************************
  286. Data retrievers: called from UI thread.
  287. ********************************************************************/
  288. virtual
  289. HITEM
  290. GetItem(
  291. NATURAL_INDEX NaturalIndex
  292. ) const = 0;
  293. virtual
  294. HITEM
  295. GetNextItem(
  296. HITEM hItem
  297. ) const = 0;
  298. virtual
  299. INFO
  300. GetInfo(
  301. HITEM hItem,
  302. DATA_INDEX DataIndex
  303. ) const = 0;
  304. virtual
  305. IDENT
  306. GetId(
  307. HITEM hItem
  308. ) const = 0;
  309. virtual
  310. NATURAL_INDEX
  311. GetNaturalIndex(
  312. IDENT id,
  313. PHITEM phItem
  314. ) const = 0;
  315. /********************************************************************
  316. Item block manipulators.
  317. vBlockProcess - A block that has been given to the client via
  318. vBlockAdd should now be consumed by calling vBlockProcess.
  319. ********************************************************************/
  320. VOID
  321. vBlockProcess(
  322. VOID
  323. );
  324. /********************************************************************
  325. Executes in worker threads.
  326. ********************************************************************/
  327. virtual
  328. STATEVAR
  329. svNotifyStart(
  330. STATEVAR StateVar
  331. ) = 0;
  332. virtual
  333. STATEVAR
  334. svNotifyEnd(
  335. STATEVAR StateVar
  336. ) = 0;
  337. virtual
  338. STATEVAR
  339. svRefresh(
  340. STATEVAR StateVar
  341. ) = 0;
  342. protected:
  343. struct UI_GUARD {
  344. COUNT _cItems;
  345. } UIGuard;
  346. class TBlock {
  347. friend VData;
  348. SIGNATURE( 'dabl' )
  349. SAFE_NEW
  350. ALWAYS_VALID
  351. private:
  352. DLINK( TBlock, Block );
  353. DWORD _dwParam1;
  354. DWORD _dwParam2;
  355. HANDLE _hBlock;
  356. TBlock(
  357. DWORD dwParam1,
  358. DWORD dwParam2,
  359. HANDLE hBlock
  360. );
  361. ~TBlock(
  362. VOID
  363. );
  364. };
  365. MDataClient* _pDataClient;
  366. PFIELD_TABLE _pFieldTable;
  367. DLINK_BASE( TBlock, Block, Block );
  368. TRefLock<TPrintLib> _pPrintLib;
  369. VData(
  370. MDataClient* pDataClient,
  371. PFIELD_TABLE pFieldTable
  372. );
  373. virtual
  374. ~VData(
  375. VOID
  376. );
  377. VOID
  378. vBlockAdd(
  379. DWORD dwParam1,
  380. DWORD dwParam2,
  381. HANDLE hBlock
  382. );
  383. virtual
  384. VOID
  385. vBlockDelete(
  386. HANDLE hBlock
  387. ) = 0;
  388. virtual
  389. VOID
  390. vBlockProcessImp(
  391. DWORD dwParam1,
  392. DWORD dwParam2,
  393. HBLOCK hBlock
  394. ) = 0;
  395. private:
  396. //
  397. // Virtual definition for MNotifyWork.
  398. //
  399. HANDLE
  400. hEvent(
  401. VOID
  402. ) const;
  403. static
  404. CCSLock&
  405. csData(
  406. VOID
  407. )
  408. {
  409. return *gpCritSec;
  410. }
  411. };
  412. /********************************************************************
  413. VDataRefresh implements the downlevel version: it receives
  414. a single DWORD value for notifications and completely refreshes
  415. all Items when a change occurs.
  416. ********************************************************************/
  417. class VDataRefresh : public VData {
  418. SIGNATURE( 'dtrv' )
  419. public:
  420. VDataRefresh(
  421. MDataClient* pDataClient,
  422. PFIELD_TABLE pFieldTable,
  423. DWORD fdwWatch
  424. );
  425. ~VDataRefresh(
  426. VOID
  427. );
  428. /********************************************************************
  429. Exported services (statics) for related data refresh functions.
  430. ********************************************************************/
  431. static
  432. BOOL
  433. bEnumJobs(
  434. IN HANDLE hPrinter,
  435. IN DWORD dwLevel,
  436. IN OUT PVOID* ppvBuffer, CHANGE
  437. IN OUT PDWORD pcbBuffer,
  438. OUT PDWORD pcJobs
  439. );
  440. static
  441. BOOL
  442. bEnumPrinters(
  443. IN DWORD dwFlags,
  444. IN LPCTSTR pszServer,
  445. IN DWORD dwLevel,
  446. IN OUT PVOID* ppvBuffer,
  447. IN OUT PDWORD pcbBuffer,
  448. OUT PDWORD pcPrinters
  449. );
  450. static
  451. BOOL
  452. bEnumDrivers(
  453. IN LPCTSTR pszServer,
  454. IN LPCTSTR pszEnvironment,
  455. IN DWORD dwLevel,
  456. IN OUT PVOID *ppvBuffer, CHANGE
  457. IN OUT PDWORD pcbBuffer,
  458. OUT PDWORD pcDrivers
  459. );
  460. static
  461. BOOL
  462. bGetPrinter(
  463. IN HANDLE hPrinter,
  464. IN DWORD dwLevel,
  465. IN OUT PVOID* ppvBuffer,
  466. IN OUT PDWORD pcbBuffer
  467. );
  468. static
  469. BOOL
  470. bGetJob(
  471. IN HANDLE hPrinter,
  472. IN DWORD dwJobId,
  473. IN DWORD dwLevel,
  474. IN OUT PVOID* ppvBuffer,
  475. IN OUT PDWORD pcbBuffer
  476. );
  477. static
  478. BOOL
  479. bGetPrinterDriver(
  480. IN HANDLE hPrinter,
  481. IN LPCTSTR pszEnvironment,
  482. IN DWORD dwLevel,
  483. IN OUT PVOID* ppvBuffer,
  484. IN OUT PDWORD pcbBuffer
  485. );
  486. static
  487. BOOL
  488. bGetDefaultDevMode(
  489. IN HANDLE hPrinter,
  490. IN LPCTSTR pszPrinterName,
  491. OUT PDEVMODE *ppDevMode,
  492. IN BOOL bFillWithDefault = FALSE
  493. );
  494. static
  495. BOOL
  496. bEnumPorts(
  497. IN LPCTSTR pszServer,
  498. IN DWORD dwLevel,
  499. IN OUT PVOID *ppvPorts, CHANGE
  500. IN OUT PDWORD pcbPorts,
  501. OUT PDWORD pcPorts
  502. );
  503. static
  504. BOOL
  505. bEnumPortsMaxLevel(
  506. IN LPCTSTR pszServer,
  507. IN PDWORD pdwLevel,
  508. IN OUT PVOID *ppvPorts, CHANGE
  509. IN OUT PDWORD pcbPorts,
  510. OUT PDWORD pcPorts
  511. );
  512. static
  513. BOOL
  514. bEnumMonitors(
  515. IN LPCTSTR pszServer,
  516. IN DWORD dwLevel,
  517. IN OUT PVOID *ppvMonitors, CHANGE
  518. IN OUT PDWORD pcbMonitors,
  519. OUT PDWORD pcMonitors
  520. );
  521. /********************************************************************
  522. Executes in worker threads.
  523. ********************************************************************/
  524. STATEVAR
  525. svNotifyStart(
  526. STATEVAR StateVar
  527. );
  528. STATEVAR
  529. svNotifyEnd(
  530. STATEVAR StateVar
  531. );
  532. protected:
  533. enum _CONSTANTS {
  534. kInitialJobHint = 0x400,
  535. kInitialPrinterHint = 0x400,
  536. kInitialDriverHint = 0x400,
  537. kExtraJobBufferBytes = 0x80,
  538. kExtraPrinterBufferBytes = 0x80,
  539. kMaxPrinterInfo2 = 0x1000,
  540. kInitialDriverInfo3Hint = 0x400,
  541. kEnumPortsHint = 0x1000,
  542. kEnumMonitorsHint = 0x400,
  543. };
  544. private:
  545. DWORD _fdwWatch;
  546. struct EXEC_GUARD {
  547. //
  548. // We need a separate hPrinter for notifications since downlevel
  549. // print providers that don't support F*PCN will default to
  550. // WaitForPrinterChange. The WPC call is synchronous and
  551. // may take a long time (10 sec->1 min). Since RPC synchronizes
  552. // handle access, this make the Get/Enum call very slow.
  553. //
  554. VAR( HANDLE, hPrinterWait );
  555. } ExecGuard;
  556. /********************************************************************
  557. Notify support (callbacks when object is notified).
  558. ********************************************************************/
  559. VOID
  560. vProcessNotifyWork(
  561. TNotify* pNotify
  562. );
  563. };
  564. /********************************************************************
  565. There are two flavors: Jobs and Printers
  566. TDataRJob: Handles print queues (item unit = print job).
  567. TDataRPrinter: Handles server view/print folder (item = printer)
  568. ********************************************************************/
  569. class TDataRJob : public VDataRefresh {
  570. SIGNATURE( 'dtrj' )
  571. public:
  572. enum CONSTANTS {
  573. kfdwWatch = PRINTER_CHANGE_JOB | PRINTER_CHANGE_PRINTER
  574. };
  575. TDataRJob(
  576. MDataClient* pDataClient
  577. );
  578. ~TDataRJob(
  579. VOID
  580. );
  581. /********************************************************************
  582. Data retrievers.
  583. ********************************************************************/
  584. HITEM
  585. GetItem(
  586. NATURAL_INDEX NaturalIndex
  587. ) const;
  588. HITEM
  589. GetNextItem(
  590. HITEM hItem
  591. ) const;
  592. INFO
  593. GetInfo(
  594. HITEM hItem,
  595. DATA_INDEX DataIndex
  596. ) const;
  597. IDENT
  598. GetId(
  599. HITEM hItem
  600. ) const;
  601. NATURAL_INDEX
  602. GetNaturalIndex(
  603. IDENT id,
  604. PHITEM phItem
  605. ) const;
  606. /********************************************************************
  607. Block manipulators.
  608. ********************************************************************/
  609. VOID
  610. vBlockDelete(
  611. HBLOCK hBlock
  612. );
  613. VOID
  614. vBlockProcessImp(
  615. DWORD dwParam1,
  616. DWORD dwParam2,
  617. HBLOCK hBlock
  618. );
  619. /********************************************************************
  620. Executes in worker threads.
  621. ********************************************************************/
  622. STATEVAR
  623. svRefresh(
  624. STATEVAR StateVar
  625. );
  626. private:
  627. //
  628. // All fields here are guarded by ExecGuard.
  629. //
  630. struct EXEC_GUARD {
  631. VAR( COUNTB, cbJobHint );
  632. } ExecGuard;
  633. //
  634. // All fields here are accessed only from the UI thread.
  635. //
  636. struct UI_GUARD {
  637. VAR( PJOB_INFO_2, pJobs );
  638. } UIGuard;
  639. };
  640. class TDataRPrinter: public VDataRefresh {
  641. SIGNATURE( 'dtrp' )
  642. public:
  643. //
  644. // Keep it simple: we could just watch for PRINTER_CHANGE_ADD_PRINTER
  645. // and PRINTER_CHANGE_DELETE_PRINTER in the non-details view,
  646. // but that only helps us w/ NT 3.1, 3.5 servers. (3.51 support
  647. // FFPCN, and lm/wfw/win95 trigger full notifications anyway).
  648. //
  649. enum CONSTANTS {
  650. kfdwWatch = PRINTER_CHANGE_PRINTER
  651. };
  652. TDataRPrinter(
  653. MDataClient* pDataClient
  654. );
  655. ~TDataRPrinter(
  656. VOID
  657. );
  658. static
  659. BOOL
  660. bSinglePrinter(
  661. LPCTSTR pszDataSource
  662. );
  663. /********************************************************************
  664. Data retrievers.
  665. ********************************************************************/
  666. HITEM
  667. GetItem(
  668. NATURAL_INDEX NaturalIndex
  669. ) const;
  670. HITEM
  671. GetNextItem(
  672. HITEM hItem
  673. ) const;
  674. INFO
  675. GetInfo(
  676. HITEM hItem,
  677. DATA_INDEX DataIndex
  678. ) const;
  679. IDENT
  680. GetId(
  681. HITEM hItem
  682. ) const;
  683. NATURAL_INDEX
  684. GetNaturalIndex(
  685. IDENT id,
  686. PHITEM phItem
  687. ) const;
  688. /********************************************************************
  689. Block manipulators.
  690. ********************************************************************/
  691. VOID
  692. vBlockDelete(
  693. HBLOCK hBlock
  694. );
  695. VOID
  696. vBlockProcessImp(
  697. DWORD dwParam1,
  698. DWORD dwParam2,
  699. HBLOCK hBlock
  700. );
  701. /********************************************************************
  702. Executes in worker threads.
  703. ********************************************************************/
  704. STATEVAR
  705. svRefresh(
  706. STATEVAR StateVar
  707. );
  708. private:
  709. //
  710. // Used to determine whether EnumPrinters or GetPrinter
  711. // should be called.
  712. //
  713. BOOL _bSinglePrinter;
  714. //
  715. // All fields here are guarded by ExecGuard.
  716. //
  717. struct EXEC_GUARD {
  718. VAR( COUNTB, cbPrinterHint );
  719. } ExecGuard;
  720. //
  721. // All fields here are accessed only from the UI thread.
  722. //
  723. struct UI_GUARD {
  724. VAR( PPRINTER_INFO_2, pPrinters );
  725. } UIGuard;
  726. };
  727. /********************************************************************
  728. VDataNotify implements the uplevel version: with eacph
  729. notification, it receives information about the change and
  730. doesn't need to refresh the entire buffer.
  731. ********************************************************************/
  732. class VDataNotify : public VData {
  733. SIGNATURE( 'dtnv' )
  734. public:
  735. VDataNotify(
  736. MDataClient* pDataClient,
  737. PFIELD_TABLE pFieldTable,
  738. DWORD TypeItem
  739. );
  740. ~VDataNotify(
  741. VOID
  742. );
  743. class TItemData {
  744. public:
  745. VAR( IDENT, Id );
  746. VAR( VDataNotify*, pDataNotify );
  747. DLINK( TItemData, ItemData );
  748. static TItemData*
  749. pNew(
  750. VDataNotify* pDataNotify,
  751. IDENT Id
  752. );
  753. VOID
  754. vDelete(
  755. VOID
  756. );
  757. //
  758. // Must be last, since variable size.
  759. //
  760. INFO _aInfo[1];
  761. private:
  762. //
  763. // Not defined; always use pNew since this isn't a
  764. // first-class class.
  765. //
  766. TItemData();
  767. };
  768. /********************************************************************
  769. Data retrievers.
  770. ********************************************************************/
  771. HITEM
  772. GetItem(
  773. NATURAL_INDEX NaturalIndex
  774. ) const;
  775. HITEM
  776. GetNextItem(
  777. HITEM hItem
  778. ) const;
  779. INFO
  780. GetInfo(
  781. HITEM hItem,
  782. DATA_INDEX DataIndex
  783. ) const;
  784. IDENT
  785. GetId(
  786. HITEM hItem
  787. ) const;
  788. NATURAL_INDEX
  789. GetNaturalIndex(
  790. IDENT id,
  791. PHITEM phItem
  792. ) const;
  793. /********************************************************************
  794. Block manipulators.
  795. ********************************************************************/
  796. VOID
  797. vBlockDelete(
  798. HBLOCK hBlock
  799. );
  800. VOID
  801. vBlockProcessImp(
  802. DWORD dwParam1,
  803. DWORD dwParam2,
  804. HBLOCK hBlock
  805. );
  806. /********************************************************************
  807. Executes in worker threads.
  808. ********************************************************************/
  809. STATEVAR
  810. svNotifyStart(
  811. STATEVAR StateVar
  812. );
  813. STATEVAR
  814. svNotifyEnd(
  815. STATEVAR StateVar
  816. );
  817. STATEVAR
  818. svRefresh(
  819. STATEVAR StateVar
  820. );
  821. protected:
  822. //
  823. // The linked list data structure is not very efficient if we
  824. // continually need to look up Ids. Each data field from the
  825. // notification comes in single pieces (name, size, etc.), but
  826. // they are clumped, so the cache prevents duplicate lookups.
  827. //
  828. // Since we are in the UI thread, we don't have to worry about
  829. // items being deleted while the cache is used.
  830. //
  831. typedef struct CACHE {
  832. TItemData* pItemData;
  833. IDENT Id;
  834. NATURAL_INDEX NaturalIndex;
  835. BOOL bNew;
  836. } PCACHE;
  837. //
  838. // All fields here are accessed only from the UI thread.
  839. //
  840. struct UI_GUARD {
  841. DLINK_BASE( TItemData, ItemData, ItemData );
  842. } UIGuard;
  843. //
  844. // Allow a derived class to override the creation of a new
  845. // pItemData. In the normal case, just call the TItemData->pNew.
  846. //
  847. virtual
  848. TItemData*
  849. pNewItemData(
  850. VDataNotify* pDataNotify,
  851. IDENT Id
  852. )
  853. {
  854. return TItemData::pNew( pDataNotify, Id );
  855. }
  856. /********************************************************************
  857. Standard method of updating a pInfo.
  858. ********************************************************************/
  859. VOID
  860. vUpdateInfoData(
  861. IN const PPRINTER_NOTIFY_INFO_DATA pData,
  862. IN TABLE Table,
  863. IN PINFO pInfo
  864. );
  865. private:
  866. enum PROCESS_TYPE {
  867. kProcessRefresh,
  868. kProcessIncremental
  869. };
  870. //
  871. // Indicates the *_NOTIFY_TYPE that applies to items.
  872. //
  873. DWORD _TypeItem;
  874. /********************************************************************
  875. Notify support (callbacks when object is notified).
  876. ********************************************************************/
  877. VOID
  878. vProcessNotifyWork(
  879. TNotify* pNotify
  880. );
  881. virtual
  882. PPRINTER_NOTIFY_OPTIONS
  883. pNotifyOptions(
  884. VOID
  885. ) = 0;
  886. //
  887. // Returns TRUE if item should be deleted.
  888. //
  889. virtual
  890. BOOL
  891. bUpdateInfo(
  892. const PPRINTER_NOTIFY_INFO_DATA pData,
  893. DATA_INDEX DataIndex,
  894. CACHE& Cache
  895. ) = 0;
  896. /*++
  897. Routine Description:
  898. Requests the child update a particular item.
  899. Arguments:
  900. pData - New data about the item stored in Cache.
  901. DataIndex - DataIndex that pData refers to.
  902. Cache - Cached information about the item, including
  903. pItemData, Id, NaturalIndex, and bNew (indicates whether
  904. the item is a new one or not; set when a new item is
  905. added and for all subsequent notifications that
  906. immediately follow it in the same notification block.
  907. Return Value:
  908. TRUE if item should be deleted, FALSE otherwise.
  909. --*/
  910. /********************************************************************
  911. Private member functions.
  912. ********************************************************************/
  913. TItemData*
  914. GetItem(
  915. IDENT Id,
  916. NATURAL_INDEX* pNaturalIndex
  917. );
  918. BOOL
  919. bItemProcess(
  920. const PPRINTER_NOTIFY_INFO_DATA pData,
  921. CACHE& Cache
  922. );
  923. VOID
  924. vContainerProcess(
  925. const PPRINTER_NOTIFY_INFO_DATA pData
  926. );
  927. VOID
  928. vDeleteAllItemData(
  929. VOID
  930. );
  931. #if DBG
  932. VOID
  933. vDbgOutputInfo(
  934. const PPRINTER_NOTIFY_INFO pInfo
  935. );
  936. #endif
  937. friend VDataNotify::TItemData;
  938. };
  939. /********************************************************************
  940. DataNotify tables.
  941. Define the visible columns in the UI, and also the extra fields
  942. that follow it.
  943. We maintain two conceptual arrays, and therefore two index types
  944. (one for each array):
  945. COLUMN: Array of Fields corresponding to the UI columns.
  946. DATA_INDEX: Array of Fields corresponding to a Item's data
  947. structure.
  948. The DATA_INDEX array is a superset of the COLUMN array: i.e., for all
  949. valid COLUMN, aFieldColumn[COLUMN] == aFieldIndex[COLUMN].
  950. The entire next block is highly self-dependent. Adding/deleting,
  951. or changing a field must be done very carefully.
  952. These definitions are in the classes next to the constants.
  953. ********************************************************************/
  954. /********************************************************************
  955. There are two flavors: Jobs and Printers
  956. TDataRJob: Handles print queues (job unit = print job).
  957. TDataRPrinter: Handles server view/print folder (job unit = printer)
  958. ********************************************************************/
  959. class TDataNJob : public VDataNotify {
  960. friend TDataRJob;
  961. SIGNATURE( 'dtnj' )
  962. public:
  963. enum CONSTANTS {
  964. kFieldOtherSize = 4,
  965. kTypeSize = 2,
  966. #define JOB_COLUMN_FIELDS \
  967. JOB_NOTIFY_FIELD_DOCUMENT, \
  968. JOB_NOTIFY_FIELD_STATUS_STRING, \
  969. JOB_NOTIFY_FIELD_USER_NAME, \
  970. JOB_NOTIFY_FIELD_TOTAL_PAGES, \
  971. JOB_NOTIFY_FIELD_TOTAL_BYTES, \
  972. JOB_NOTIFY_FIELD_SUBMITTED, \
  973. JOB_NOTIFY_FIELD_PORT_NAME
  974. kColumnFieldsSize = 7,
  975. #define JOB_INDEX_EXTRA_FIELDS \
  976. JOB_NOTIFY_FIELD_PAGES_PRINTED, \
  977. JOB_NOTIFY_FIELD_BYTES_PRINTED, \
  978. JOB_NOTIFY_FIELD_POSITION, \
  979. JOB_NOTIFY_FIELD_STATUS
  980. kIndexExtraFieldsSize = 4,
  981. kIndexPagesPrinted = kColumnFieldsSize,
  982. kIndexBytesPrinted = kColumnFieldsSize + 1,
  983. kIndexStatus = kColumnFieldsSize + 3,
  984. kFieldTableSize = kColumnFieldsSize +
  985. kIndexExtraFieldsSize
  986. };
  987. TDataNJob(
  988. MDataClient* pDataClient
  989. );
  990. ~TDataNJob(
  991. VOID
  992. );
  993. private:
  994. static PRINTER_NOTIFY_OPTIONS gNotifyOptions;
  995. static FIELD gaFieldOther[kFieldOtherSize];
  996. static PRINTER_NOTIFY_OPTIONS_TYPE gaNotifyOptionsType[kTypeSize];
  997. static FIELD_TABLE gFieldTable;
  998. static FIELD gaFields[kFieldTableSize+1];
  999. PPRINTER_NOTIFY_OPTIONS
  1000. pNotifyOptions(
  1001. VOID
  1002. )
  1003. {
  1004. return &gNotifyOptions;
  1005. }
  1006. BOOL
  1007. bUpdateInfo(
  1008. const PPRINTER_NOTIFY_INFO_DATA pData,
  1009. DATA_INDEX DataIndex,
  1010. CACHE& Cache
  1011. );
  1012. };
  1013. class TDataNPrinter: public VDataNotify {
  1014. friend TDataRPrinter;
  1015. SIGNATURE( 'dtnp' )
  1016. public:
  1017. enum CONSTANTS {
  1018. kTypeSize = 1,
  1019. #define PRINTER_COLUMN_FIELDS \
  1020. PRINTER_NOTIFY_FIELD_PRINTER_NAME, \
  1021. PRINTER_NOTIFY_FIELD_CJOBS, \
  1022. PRINTER_NOTIFY_FIELD_STATUS, \
  1023. PRINTER_NOTIFY_FIELD_COMMENT, \
  1024. PRINTER_NOTIFY_FIELD_LOCATION, \
  1025. PRINTER_NOTIFY_FIELD_DRIVER_NAME, \
  1026. PRINTER_NOTIFY_FIELD_PORT_NAME, \
  1027. PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR
  1028. kIndexPrinterName = 0,
  1029. kIndexCJobs,
  1030. kIndexStatus,
  1031. kIndexComment,
  1032. kIndexLocation,
  1033. kIndexModel,
  1034. kIndexPort,
  1035. kIndexSecurity,
  1036. kColumnFieldsSize = 8,
  1037. #define PRINTER_INDEX_EXTRA_FIELDS \
  1038. PRINTER_NOTIFY_FIELD_ATTRIBUTES
  1039. kIndexExtraFieldsSize = 1,
  1040. kIndexAttributes = kColumnFieldsSize,
  1041. kFieldTableSize = kColumnFieldsSize +
  1042. kIndexExtraFieldsSize
  1043. };
  1044. TDataNPrinter(
  1045. MDataClient* pDataClient
  1046. );
  1047. ~TDataNPrinter(
  1048. VOID
  1049. );
  1050. private:
  1051. static PRINTER_NOTIFY_OPTIONS gNotifyOptions;
  1052. static PRINTER_NOTIFY_OPTIONS_TYPE gaNotifyOptionsType[kTypeSize];
  1053. static FIELD_TABLE gFieldTable;
  1054. static FIELD gaFields[kFieldTableSize+1];
  1055. TItemData*
  1056. pNewItemData(
  1057. VDataNotify* pDataNotify,
  1058. IDENT Id
  1059. );
  1060. PPRINTER_NOTIFY_OPTIONS
  1061. pNotifyOptions(
  1062. VOID
  1063. )
  1064. {
  1065. return &gNotifyOptions;
  1066. }
  1067. BOOL
  1068. bUpdateInfo(
  1069. const PPRINTER_NOTIFY_INFO_DATA pData,
  1070. DATA_INDEX DataIndex,
  1071. CACHE& Cache
  1072. );
  1073. };
  1074. #endif // ndef _DATA_HXX