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

/*++
Copyright (C) Microsoft Corporation, 1995 - 1999
All rights reserved.
Module Name:
data.hxx
Abstract:
Queries the printer for Item data.
Author:
Albert Ting (AlbertT) 27-Jan-1995
Revision History:
--*/
#ifndef _DATA_HXX
#define _DATA_HXX
class VDataNotify;
class VDataRefresh;
class MDataClient;
class TPrintLib;
/********************************************************************
The FieldTable translates a DATA_INDEX index into a field value.
The DATA_INDEX is used in GetInfo.
********************************************************************/
typedef struct FIELD_TABLE {
UINT cFields;
PFIELD pFields;
} *PFIELD_TABLE;
/********************************************************************
ITEM and PRINTER changes.
When a change occurs, a callback is called with a ITEM_CHANGE or
CONTAINER_CHANGE parameter that indicates how the object changed.
********************************************************************/
enum ITEM_CHANGE {
kItemNull, // Prevent 0 message value.
kItemCreate, // Item being created.
kItemDelete, // Item being deleted.
kItemPosition, // Item position changed.
kItemInfo, // Affects list/icon and report view.
kItemAttributes, // Affects report view only (not list/icon view).
kItemName, // Item name changed.
kItemSecurity, // Item security change.
};
enum CONTAINER_CHANGE {
kContainerNull,
kContainerConnectStatus, // Connect state changed -> add to title bar
kContainerErrorStatus, // Error occured -> add to status bar
kContainerServerName, // Server name changed
kContainerName, // Container name changed
kContainerStatus, // Container status changed -> add to title bar
kContainerAttributes, // Attributes changed
kContainerStateVar, // StateVar additions
kContainerNewBlock, // New data block available
/********************************************************************
The following are synchronous, but may be called from
any thread.
********************************************************************/
//
// UI should release all references to VData data. This occurs
// either at the start of a refresh, or when VData is being deleted.
// Called from any thread.
// INFO = VOID
//
kContainerClearItems,
//
// Refresh data has been completely sent to UI thread; called from
// UI thread only.
// INFO = VOID
//
kContainerRefreshComplete,
//
// Reload based on new hBlock; called from UI thread only.
// INFO = cItems.
//
// A drastic change has occured to the datastore. The data object
// now contains INFO new items. During this call, the client
// should release all pointer references to old objects and
// reload the UI with the new objects.
//
// It will get a RefreshComplete when the reload has completed.
//
kContainerReloadItems
};
/********************************************************************
Connect status codes and map.
Note: if you change or move any of the CONNECT_STATUS k* contants,
you must update the CONNECT_STATUS_MAP. Used by queue.cxx code.
********************************************************************/
enum CONNECT_STATUS {
kConnectStatusNull = 0,
kConnectStatusInvalidPrinterName,
kConnectStatusAccessDenied,
kConnectStatusOpenError,
kConnectStatusOpen,
kConnectStatusInitialize,
kConnectStatusRefresh,
kConnectStatusCommand,
kConnectStatusPoll
};
#define CONNECT_STATUS_MAP { \
0, \
IDS_SB_INVALID_PRINTER_NAME, \
IDS_SB_ACCESS_DENIED, \
IDS_SB_OPEN_ERROR, \
IDS_SB_OPEN, \
IDS_SB_INITIALIZE, \
IDS_SB_REFRESH, \
IDS_SB_COMMAND, \
IDS_SB_POLL \
}
typedef HANDLE HITEM, *PHITEM; // Opaque packet holding job item info.
typedef UINT DATA_INDEX, *PDATA_INDEX; // Selector for printer data.
/********************************************************************
MDataClient
User of Data structure supports this interface. Both the
Queue and Printer support this interface.
The support could be placed in Queue only, allowing Data to
talk through Printer.Queue, but the lifetime of Queue is managed
through Printer, so we must still talk through printer.
(The lifetime of Printer is identical to Data.)
********************************************************************/
class VInfoClient {
public:
/********************************************************************
Callbacks for VData
vContainerChanged( ContainerChange, Info )
Indicates something Container wide has changed.
May be called from UI, Notify, or Worker thread.
vItemChanged( ItemChange, hItem, Info, InfoNew );
Indicates that a single Item has changed and needs to be
refreshed.
Only called from UI thread.
********************************************************************/
//
// Something printer wide has changed. Notify the UI thread.
// This call must return quickly, and can not use any
// SendMessages since it acquires the printer critical section.
//
virtual
VOID
vContainerChanged(
CONTAINER_CHANGE ContainerChange,
INFO Info
) = 0;
//
// A single Item has changed (or possibly moved). Notify the
// UI that it needs to refresh. Always called from UI thread.
//
virtual
VOID
vItemChanged(
ITEM_CHANGE ItemChange,
HITEM hItem,
INFO Info,
INFO InfoNew
) = 0;
/********************************************************************
Saving and restoring selections.
********************************************************************/
//
// When all Items change, the client needs to save its solections,
// refresh, then restore selections. After we call vContainerChanged
// with new Items, we restore the selections.
//
// These calls are _non-reentrant_ since they are called from the
// UI thread.
//
virtual
VOID
vSaveSelections(
VOID
) = 0;
virtual
VOID
vRestoreSelections(
VOID
) = 0;
/********************************************************************
Creation of TData{Refresh/Notify}.
********************************************************************/
virtual
VDataNotify*
pNewNotify(
MDataClient* pDataClient
) const = 0;
virtual
VDataRefresh*
pNewRefresh(
MDataClient* pDataClient
) const = 0;
};
class MDataClient : public VInfoClient {
SIGNATURE( 'dtc' )
public:
virtual
LPTSTR
pszServerName(
size_t cchBuffer,
LPTSTR pszServerBuffer
) const = 0;
virtual
LPTSTR
pszPrinterName(
size_t cchBuffer,
LPTSTR pszServerBuffer
) const = 0;
virtual
HANDLE
hPrinter(
VOID
) const = 0;
virtual
HANDLE
hPrinterNew(
VOID
) const = 0;
virtual
BOOL
bGetPrintLib(
TRefLock<TPrintLib> &refLock
) const = 0;
};
/********************************************************************
VData provides an abstraction layer for retrieving data and
notifications from a printer. The TPrinter object gets the
hPrinter and hEvent, then allows VData to reference them.
The state of the notification is managed through the following
worker functions:
svStart - Begins the notification
svEnd - Ends the notification
svRefresh - Refreshs data about the connection
These worker functions return a STATEVAR. The printer/
notification is managed as a simple state machine. When
a call fails, the StateVar indicates what should happen
next (it is not intended to return error code information).
The VData will retrieve a Item buffer using GetItem. To retrieve
specific field data about a Item (such as page count, time
submitted, etc.), call GetInfo with the field index.
GetItem - Gets an hItem based on Item order index.
GetInfo - Gets info about a particular hItem.
GetId - Gets Item id about a particular hItem.
GetNaturalIndex - Gets the natural index of a ItemId.
For example,
hItem = pData->GetItem( NaturalIndex );
if( hItem ){
Info = GetInfo( hItem, DataIndexForName );
}
if( Info.pszData ){
OutputDebugString( Info.pszData );
}
The VData* type _must_ call vRefreshComplete (inherited from
VData*) as soon as a refresh has occurred, but before it
re-initializes the notification scheme. This allows the client
to know the boundary between pre-refresh notifications and
post-refresh.
********************************************************************/
class VData : public MNotifyWork {
SIGNATURE( 'dtv' )
public:
CAutoHandlePrinterNotify m_shNotify;
/********************************************************************
Creation and deletion should be handled from pNew and
vDelete rather than the regular new and delete, since
we create a derived class that is determined at runtime.
********************************************************************/
static
STATEVAR
svNew(
IN MDataClient* pDataClient,
IN STATEVAR StateVar,
OUT VData*& pData
);
VOID
vDelete(
VOID
);
BOOL
bValid(
VOID
) const;
COUNT
cItems(
VOID
) const
{
return UIGuard._cItems;
}
/********************************************************************
Data retrievers: called from UI thread.
********************************************************************/
virtual
HITEM
GetItem(
NATURAL_INDEX NaturalIndex
) const = 0;
virtual
HITEM
GetNextItem(
HITEM hItem
) const = 0;
virtual
INFO
GetInfo(
HITEM hItem,
DATA_INDEX DataIndex
) const = 0;
virtual
IDENT
GetId(
HITEM hItem
) const = 0;
virtual
NATURAL_INDEX
GetNaturalIndex(
IDENT id,
PHITEM phItem
) const = 0;
/********************************************************************
Item block manipulators.
vBlockProcess - A block that has been given to the client via
vBlockAdd should now be consumed by calling vBlockProcess.
********************************************************************/
VOID
vBlockProcess(
VOID
);
/********************************************************************
Executes in worker threads.
********************************************************************/
virtual
STATEVAR
svNotifyStart(
STATEVAR StateVar
) = 0;
virtual
STATEVAR
svNotifyEnd(
STATEVAR StateVar
) = 0;
virtual
STATEVAR
svRefresh(
STATEVAR StateVar
) = 0;
protected:
struct UI_GUARD {
COUNT _cItems;
} UIGuard;
class TBlock {
friend VData;
SIGNATURE( 'dabl' )
SAFE_NEW
ALWAYS_VALID
private:
DLINK( TBlock, Block );
DWORD _dwParam1;
DWORD _dwParam2;
HANDLE _hBlock;
TBlock(
DWORD dwParam1,
DWORD dwParam2,
HANDLE hBlock
);
~TBlock(
VOID
);
};
MDataClient* _pDataClient;
PFIELD_TABLE _pFieldTable;
DLINK_BASE( TBlock, Block, Block );
TRefLock<TPrintLib> _pPrintLib;
VData(
MDataClient* pDataClient,
PFIELD_TABLE pFieldTable
);
virtual
~VData(
VOID
);
VOID
vBlockAdd(
DWORD dwParam1,
DWORD dwParam2,
HANDLE hBlock
);
virtual
VOID
vBlockDelete(
HANDLE hBlock
) = 0;
virtual
VOID
vBlockProcessImp(
DWORD dwParam1,
DWORD dwParam2,
HBLOCK hBlock
) = 0;
private:
//
// Virtual definition for MNotifyWork.
//
HANDLE
hEvent(
VOID
) const;
static
CCSLock&
csData(
VOID
)
{
return *gpCritSec;
}
};
/********************************************************************
VDataRefresh implements the downlevel version: it receives
a single DWORD value for notifications and completely refreshes
all Items when a change occurs.
********************************************************************/
class VDataRefresh : public VData {
SIGNATURE( 'dtrv' )
public:
VDataRefresh(
MDataClient* pDataClient,
PFIELD_TABLE pFieldTable,
DWORD fdwWatch
);
~VDataRefresh(
VOID
);
/********************************************************************
Exported services (statics) for related data refresh functions.
********************************************************************/
static
BOOL
bEnumJobs(
IN HANDLE hPrinter,
IN DWORD dwLevel,
IN OUT PVOID* ppvBuffer, CHANGE
IN OUT PDWORD pcbBuffer,
OUT PDWORD pcJobs
);
static
BOOL
bEnumPrinters(
IN DWORD dwFlags,
IN LPCTSTR pszServer,
IN DWORD dwLevel,
IN OUT PVOID* ppvBuffer,
IN OUT PDWORD pcbBuffer,
OUT PDWORD pcPrinters
);
static
BOOL
bEnumDrivers(
IN LPCTSTR pszServer,
IN LPCTSTR pszEnvironment,
IN DWORD dwLevel,
IN OUT PVOID *ppvBuffer, CHANGE
IN OUT PDWORD pcbBuffer,
OUT PDWORD pcDrivers
);
static
BOOL
bGetPrinter(
IN HANDLE hPrinter,
IN DWORD dwLevel,
IN OUT PVOID* ppvBuffer,
IN OUT PDWORD pcbBuffer
);
static
BOOL
bGetJob(
IN HANDLE hPrinter,
IN DWORD dwJobId,
IN DWORD dwLevel,
IN OUT PVOID* ppvBuffer,
IN OUT PDWORD pcbBuffer
);
static
BOOL
bGetPrinterDriver(
IN HANDLE hPrinter,
IN LPCTSTR pszEnvironment,
IN DWORD dwLevel,
IN OUT PVOID* ppvBuffer,
IN OUT PDWORD pcbBuffer
);
static
BOOL
bGetDefaultDevMode(
IN HANDLE hPrinter,
IN LPCTSTR pszPrinterName,
OUT PDEVMODE *ppDevMode,
IN BOOL bFillWithDefault = FALSE
);
static
BOOL
bEnumPorts(
IN LPCTSTR pszServer,
IN DWORD dwLevel,
IN OUT PVOID *ppvPorts, CHANGE
IN OUT PDWORD pcbPorts,
OUT PDWORD pcPorts
);
static
BOOL
bEnumPortsMaxLevel(
IN LPCTSTR pszServer,
IN PDWORD pdwLevel,
IN OUT PVOID *ppvPorts, CHANGE
IN OUT PDWORD pcbPorts,
OUT PDWORD pcPorts
);
static
BOOL
bEnumMonitors(
IN LPCTSTR pszServer,
IN DWORD dwLevel,
IN OUT PVOID *ppvMonitors, CHANGE
IN OUT PDWORD pcbMonitors,
OUT PDWORD pcMonitors
);
/********************************************************************
Executes in worker threads.
********************************************************************/
STATEVAR
svNotifyStart(
STATEVAR StateVar
);
STATEVAR
svNotifyEnd(
STATEVAR StateVar
);
protected:
enum _CONSTANTS {
kInitialJobHint = 0x400,
kInitialPrinterHint = 0x400,
kInitialDriverHint = 0x400,
kExtraJobBufferBytes = 0x80,
kExtraPrinterBufferBytes = 0x80,
kMaxPrinterInfo2 = 0x1000,
kInitialDriverInfo3Hint = 0x400,
kEnumPortsHint = 0x1000,
kEnumMonitorsHint = 0x400,
};
private:
DWORD _fdwWatch;
struct EXEC_GUARD {
//
// We need a separate hPrinter for notifications since downlevel
// print providers that don't support F*PCN will default to
// WaitForPrinterChange. The WPC call is synchronous and
// may take a long time (10 sec->1 min). Since RPC synchronizes
// handle access, this make the Get/Enum call very slow.
//
VAR( HANDLE, hPrinterWait );
} ExecGuard;
/********************************************************************
Notify support (callbacks when object is notified).
********************************************************************/
VOID
vProcessNotifyWork(
TNotify* pNotify
);
};
/********************************************************************
There are two flavors: Jobs and Printers
TDataRJob: Handles print queues (item unit = print job).
TDataRPrinter: Handles server view/print folder (item = printer)
********************************************************************/
class TDataRJob : public VDataRefresh {
SIGNATURE( 'dtrj' )
public:
enum CONSTANTS {
kfdwWatch = PRINTER_CHANGE_JOB | PRINTER_CHANGE_PRINTER
};
TDataRJob(
MDataClient* pDataClient
);
~TDataRJob(
VOID
);
/********************************************************************
Data retrievers.
********************************************************************/
HITEM
GetItem(
NATURAL_INDEX NaturalIndex
) const;
HITEM
GetNextItem(
HITEM hItem
) const;
INFO
GetInfo(
HITEM hItem,
DATA_INDEX DataIndex
) const;
IDENT
GetId(
HITEM hItem
) const;
NATURAL_INDEX
GetNaturalIndex(
IDENT id,
PHITEM phItem
) const;
/********************************************************************
Block manipulators.
********************************************************************/
VOID
vBlockDelete(
HBLOCK hBlock
);
VOID
vBlockProcessImp(
DWORD dwParam1,
DWORD dwParam2,
HBLOCK hBlock
);
/********************************************************************
Executes in worker threads.
********************************************************************/
STATEVAR
svRefresh(
STATEVAR StateVar
);
private:
//
// All fields here are guarded by ExecGuard.
//
struct EXEC_GUARD {
VAR( COUNTB, cbJobHint );
} ExecGuard;
//
// All fields here are accessed only from the UI thread.
//
struct UI_GUARD {
VAR( PJOB_INFO_2, pJobs );
} UIGuard;
};
class TDataRPrinter: public VDataRefresh {
SIGNATURE( 'dtrp' )
public:
//
// Keep it simple: we could just watch for PRINTER_CHANGE_ADD_PRINTER
// and PRINTER_CHANGE_DELETE_PRINTER in the non-details view,
// but that only helps us w/ NT 3.1, 3.5 servers. (3.51 support
// FFPCN, and lm/wfw/win95 trigger full notifications anyway).
//
enum CONSTANTS {
kfdwWatch = PRINTER_CHANGE_PRINTER
};
TDataRPrinter(
MDataClient* pDataClient
);
~TDataRPrinter(
VOID
);
static
BOOL
bSinglePrinter(
LPCTSTR pszDataSource
);
/********************************************************************
Data retrievers.
********************************************************************/
HITEM
GetItem(
NATURAL_INDEX NaturalIndex
) const;
HITEM
GetNextItem(
HITEM hItem
) const;
INFO
GetInfo(
HITEM hItem,
DATA_INDEX DataIndex
) const;
IDENT
GetId(
HITEM hItem
) const;
NATURAL_INDEX
GetNaturalIndex(
IDENT id,
PHITEM phItem
) const;
/********************************************************************
Block manipulators.
********************************************************************/
VOID
vBlockDelete(
HBLOCK hBlock
);
VOID
vBlockProcessImp(
DWORD dwParam1,
DWORD dwParam2,
HBLOCK hBlock
);
/********************************************************************
Executes in worker threads.
********************************************************************/
STATEVAR
svRefresh(
STATEVAR StateVar
);
private:
//
// Used to determine whether EnumPrinters or GetPrinter
// should be called.
//
BOOL _bSinglePrinter;
//
// All fields here are guarded by ExecGuard.
//
struct EXEC_GUARD {
VAR( COUNTB, cbPrinterHint );
} ExecGuard;
//
// All fields here are accessed only from the UI thread.
//
struct UI_GUARD {
VAR( PPRINTER_INFO_2, pPrinters );
} UIGuard;
};
/********************************************************************
VDataNotify implements the uplevel version: with eacph
notification, it receives information about the change and
doesn't need to refresh the entire buffer.
********************************************************************/
class VDataNotify : public VData {
SIGNATURE( 'dtnv' )
public:
VDataNotify(
MDataClient* pDataClient,
PFIELD_TABLE pFieldTable,
DWORD TypeItem
);
~VDataNotify(
VOID
);
class TItemData {
public:
VAR( IDENT, Id );
VAR( VDataNotify*, pDataNotify );
DLINK( TItemData, ItemData );
static TItemData*
pNew(
VDataNotify* pDataNotify,
IDENT Id
);
VOID
vDelete(
VOID
);
//
// Must be last, since variable size.
//
INFO _aInfo[1];
private:
//
// Not defined; always use pNew since this isn't a
// first-class class.
//
TItemData();
};
/********************************************************************
Data retrievers.
********************************************************************/
HITEM
GetItem(
NATURAL_INDEX NaturalIndex
) const;
HITEM
GetNextItem(
HITEM hItem
) const;
INFO
GetInfo(
HITEM hItem,
DATA_INDEX DataIndex
) const;
IDENT
GetId(
HITEM hItem
) const;
NATURAL_INDEX
GetNaturalIndex(
IDENT id,
PHITEM phItem
) const;
/********************************************************************
Block manipulators.
********************************************************************/
VOID
vBlockDelete(
HBLOCK hBlock
);
VOID
vBlockProcessImp(
DWORD dwParam1,
DWORD dwParam2,
HBLOCK hBlock
);
/********************************************************************
Executes in worker threads.
********************************************************************/
STATEVAR
svNotifyStart(
STATEVAR StateVar
);
STATEVAR
svNotifyEnd(
STATEVAR StateVar
);
STATEVAR
svRefresh(
STATEVAR StateVar
);
protected:
//
// The linked list data structure is not very efficient if we
// continually need to look up Ids. Each data field from the
// notification comes in single pieces (name, size, etc.), but
// they are clumped, so the cache prevents duplicate lookups.
//
// Since we are in the UI thread, we don't have to worry about
// items being deleted while the cache is used.
//
typedef struct CACHE {
TItemData* pItemData;
IDENT Id;
NATURAL_INDEX NaturalIndex;
BOOL bNew;
} PCACHE;
//
// All fields here are accessed only from the UI thread.
//
struct UI_GUARD {
DLINK_BASE( TItemData, ItemData, ItemData );
} UIGuard;
//
// Allow a derived class to override the creation of a new
// pItemData. In the normal case, just call the TItemData->pNew.
//
virtual
TItemData*
pNewItemData(
VDataNotify* pDataNotify,
IDENT Id
)
{
return TItemData::pNew( pDataNotify, Id );
}
/********************************************************************
Standard method of updating a pInfo.
********************************************************************/
VOID
vUpdateInfoData(
IN const PPRINTER_NOTIFY_INFO_DATA pData,
IN TABLE Table,
IN PINFO pInfo
);
private:
enum PROCESS_TYPE {
kProcessRefresh,
kProcessIncremental
};
//
// Indicates the *_NOTIFY_TYPE that applies to items.
//
DWORD _TypeItem;
/********************************************************************
Notify support (callbacks when object is notified).
********************************************************************/
VOID
vProcessNotifyWork(
TNotify* pNotify
);
virtual
PPRINTER_NOTIFY_OPTIONS
pNotifyOptions(
VOID
) = 0;
//
// Returns TRUE if item should be deleted.
//
virtual
BOOL
bUpdateInfo(
const PPRINTER_NOTIFY_INFO_DATA pData,
DATA_INDEX DataIndex,
CACHE& Cache
) = 0;
/*++
Routine Description:
Requests the child update a particular item.
Arguments:
pData - New data about the item stored in Cache.
DataIndex - DataIndex that pData refers to.
Cache - Cached information about the item, including
pItemData, Id, NaturalIndex, and bNew (indicates whether
the item is a new one or not; set when a new item is
added and for all subsequent notifications that
immediately follow it in the same notification block.
Return Value:
TRUE if item should be deleted, FALSE otherwise.
--*/
/********************************************************************
Private member functions.
********************************************************************/
TItemData*
GetItem(
IDENT Id,
NATURAL_INDEX* pNaturalIndex
);
BOOL
bItemProcess(
const PPRINTER_NOTIFY_INFO_DATA pData,
CACHE& Cache
);
VOID
vContainerProcess(
const PPRINTER_NOTIFY_INFO_DATA pData
);
VOID
vDeleteAllItemData(
VOID
);
#if DBG
VOID
vDbgOutputInfo(
const PPRINTER_NOTIFY_INFO pInfo
);
#endif
friend VDataNotify::TItemData;
};
/********************************************************************
DataNotify tables.
Define the visible columns in the UI, and also the extra fields
that follow it.
We maintain two conceptual arrays, and therefore two index types
(one for each array):
COLUMN: Array of Fields corresponding to the UI columns.
DATA_INDEX: Array of Fields corresponding to a Item's data
structure.
The DATA_INDEX array is a superset of the COLUMN array: i.e., for all
valid COLUMN, aFieldColumn[COLUMN] == aFieldIndex[COLUMN].
The entire next block is highly self-dependent. Adding/deleting,
or changing a field must be done very carefully.
These definitions are in the classes next to the constants.
********************************************************************/
/********************************************************************
There are two flavors: Jobs and Printers
TDataRJob: Handles print queues (job unit = print job).
TDataRPrinter: Handles server view/print folder (job unit = printer)
********************************************************************/
class TDataNJob : public VDataNotify {
friend TDataRJob;
SIGNATURE( 'dtnj' )
public:
enum CONSTANTS {
kFieldOtherSize = 4,
kTypeSize = 2,
#define JOB_COLUMN_FIELDS \
JOB_NOTIFY_FIELD_DOCUMENT, \
JOB_NOTIFY_FIELD_STATUS_STRING, \
JOB_NOTIFY_FIELD_USER_NAME, \
JOB_NOTIFY_FIELD_TOTAL_PAGES, \
JOB_NOTIFY_FIELD_TOTAL_BYTES, \
JOB_NOTIFY_FIELD_SUBMITTED, \
JOB_NOTIFY_FIELD_PORT_NAME
kColumnFieldsSize = 7,
#define JOB_INDEX_EXTRA_FIELDS \
JOB_NOTIFY_FIELD_PAGES_PRINTED, \
JOB_NOTIFY_FIELD_BYTES_PRINTED, \
JOB_NOTIFY_FIELD_POSITION, \
JOB_NOTIFY_FIELD_STATUS
kIndexExtraFieldsSize = 4,
kIndexPagesPrinted = kColumnFieldsSize,
kIndexBytesPrinted = kColumnFieldsSize + 1,
kIndexStatus = kColumnFieldsSize + 3,
kFieldTableSize = kColumnFieldsSize +
kIndexExtraFieldsSize
};
TDataNJob(
MDataClient* pDataClient
);
~TDataNJob(
VOID
);
private:
static PRINTER_NOTIFY_OPTIONS gNotifyOptions;
static FIELD gaFieldOther[kFieldOtherSize];
static PRINTER_NOTIFY_OPTIONS_TYPE gaNotifyOptionsType[kTypeSize];
static FIELD_TABLE gFieldTable;
static FIELD gaFields[kFieldTableSize+1];
PPRINTER_NOTIFY_OPTIONS
pNotifyOptions(
VOID
)
{
return &gNotifyOptions;
}
BOOL
bUpdateInfo(
const PPRINTER_NOTIFY_INFO_DATA pData,
DATA_INDEX DataIndex,
CACHE& Cache
);
};
class TDataNPrinter: public VDataNotify {
friend TDataRPrinter;
SIGNATURE( 'dtnp' )
public:
enum CONSTANTS {
kTypeSize = 1,
#define PRINTER_COLUMN_FIELDS \
PRINTER_NOTIFY_FIELD_PRINTER_NAME, \
PRINTER_NOTIFY_FIELD_CJOBS, \
PRINTER_NOTIFY_FIELD_STATUS, \
PRINTER_NOTIFY_FIELD_COMMENT, \
PRINTER_NOTIFY_FIELD_LOCATION, \
PRINTER_NOTIFY_FIELD_DRIVER_NAME, \
PRINTER_NOTIFY_FIELD_PORT_NAME, \
PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR
kIndexPrinterName = 0,
kIndexCJobs,
kIndexStatus,
kIndexComment,
kIndexLocation,
kIndexModel,
kIndexPort,
kIndexSecurity,
kColumnFieldsSize = 8,
#define PRINTER_INDEX_EXTRA_FIELDS \
PRINTER_NOTIFY_FIELD_ATTRIBUTES
kIndexExtraFieldsSize = 1,
kIndexAttributes = kColumnFieldsSize,
kFieldTableSize = kColumnFieldsSize +
kIndexExtraFieldsSize
};
TDataNPrinter(
MDataClient* pDataClient
);
~TDataNPrinter(
VOID
);
private:
static PRINTER_NOTIFY_OPTIONS gNotifyOptions;
static PRINTER_NOTIFY_OPTIONS_TYPE gaNotifyOptionsType[kTypeSize];
static FIELD_TABLE gFieldTable;
static FIELD gaFields[kFieldTableSize+1];
TItemData*
pNewItemData(
VDataNotify* pDataNotify,
IDENT Id
);
PPRINTER_NOTIFY_OPTIONS
pNotifyOptions(
VOID
)
{
return &gNotifyOptions;
}
BOOL
bUpdateInfo(
const PPRINTER_NOTIFY_INFO_DATA pData,
DATA_INDEX DataIndex,
CACHE& Cache
);
};
#endif // ndef _DATA_HXX