360 lines
14 KiB
C++
360 lines
14 KiB
C++
//=============================================================================
|
|
// File: gather.h
|
|
// Author: a-jammar
|
|
// Covers: CDataGatherer, CDataCategory, CDataListCategory
|
|
//
|
|
// Copyright (c) 1998-1999 Microsoft Corporation
|
|
//
|
|
// This header file defines the interface between the data gathering portion
|
|
// of MSInfo and the code which implements the user interface and MMC snap-in
|
|
// code. The data gathering functionality is broken up into three classes.
|
|
// The CDataGatherer object is created first and given a template file
|
|
// describing the categories and a string indicating the computer from which
|
|
// information should be gathered. A member function (GetRootDataCategory) is
|
|
// called to return a pointer to a CDataCategory or CDataListCategory object.
|
|
// The CDataCategory class implements basic category behavior like getting
|
|
// the category name, refreshing the category, and find child or sibling
|
|
// categories. CDataListCategory is derived from CDataCategory, and implement
|
|
// behavior specific to a category showing a list view, such as getting a row
|
|
// count and returning text for a specific column and row.
|
|
//
|
|
// This header file also defines error codes returned by the classes.
|
|
//=============================================================================
|
|
|
|
#pragma once
|
|
#include <afxcmn.h>
|
|
|
|
// This enumeration is used to indicate how a column in a CDataListCategory
|
|
// should be sorted. NOSORT indicates that sorting by that column should not
|
|
// be allowed. LEXICAL means to use a standard string sorting (built into
|
|
// the list view). BYVALUE means to sort by the DWORD value returned by
|
|
// the CDataListCategory::GetValue member function. Note: this type is
|
|
// defined here rather than inside the CDataListCategory class because the
|
|
// type is used by multiple classes.
|
|
|
|
enum MSIColumnSortType { NOSORT, LEXICAL, BYVALUE };
|
|
|
|
// Another enumeration used by multiple classes, this one specified the
|
|
// complexity of data (the level of complexity can be controlled by the user).
|
|
|
|
enum DataComplexity { BASIC, ADVANCED };
|
|
|
|
// The following structure is used as a parameter in CDataGatherer::Find().
|
|
// The m_strPath parameter identifies a node in the namespace using a
|
|
// backslash delimited path (starting at the root node) of category
|
|
// names to the specific node.
|
|
|
|
struct MSI_FIND_STRUCT
|
|
{
|
|
CString m_strSearch; // [IN] string to search for, Find() may change
|
|
CString m_strParentPath; // [IN] if not empty, don't search above this in tree
|
|
BOOL m_fCaseSensitive; // [IN] if TRUE, do case sensitive search
|
|
BOOL m_fSearchData; // [IN] if TRUE, search data items
|
|
BOOL m_fSearchCategories; // [IN] if TRUE, search category names
|
|
volatile BOOL *m_pfCancel; // [IN] if not NULL, monitor for TRUE value and cancel
|
|
|
|
CString m_strPath; // [IN/OUT] path to category to start search
|
|
int m_iLine; // [IN/OUT] line # to start search, -1 for cat name
|
|
|
|
BOOL m_fFound; // [OUT] m_strPath & m_iLine tell where
|
|
BOOL m_fNotFound; // [OUT] couldn't find the string
|
|
BOOL m_fCancelled; // [OUT] *m_pCancel set to TRUE, find cancelled
|
|
};
|
|
|
|
// Forward declarations.
|
|
|
|
class CDataCategory;
|
|
class CTemplateFile;
|
|
class CRefreshFunctions;
|
|
class CDataProvider;
|
|
struct INTERNAL_CATEGORY;
|
|
struct GATH_FIELD;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// CDataGatherer
|
|
//
|
|
// This class encapsulates the data gathering used in the MSInfo snap-in.
|
|
// Typically one object of this type would be created and passed a template
|
|
// file. The template file would specify what information is to be shown,
|
|
// This object could then be used to get the root data category.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
extern DWORD WINAPI ThreadRefresh(void * pArg);
|
|
class CDataGatherer
|
|
{
|
|
friend class CDataCategory;
|
|
friend class CDataListCategory;
|
|
friend class CTemplateFileFunctions;
|
|
friend class CRefreshFunctions;
|
|
friend class CDataProvider;
|
|
friend struct INTERNAL_CATEGORY;
|
|
friend DWORD WINAPI ThreadRefresh(void * pArg);
|
|
public:
|
|
CDataGatherer();
|
|
~CDataGatherer();
|
|
|
|
// Creation functions, allowing various combinations of specifying a
|
|
// template file and a machine on the network to gather info for.
|
|
// No machine name means that the local machine is used. No template
|
|
// file results in no categories.
|
|
|
|
BOOL Create(LPCTSTR szMachine = NULL);
|
|
|
|
// Set a different network machine.
|
|
|
|
BOOL SetConnect(LPCTSTR szMachine = NULL);
|
|
|
|
// Method to refresh the gathered information. Also, a method to set the
|
|
// complexity of the information displayed to the user.
|
|
|
|
BOOL Refresh(volatile BOOL *pfCancel = NULL);
|
|
BOOL SetDataComplexity(DataComplexity complexity = BASIC);
|
|
void ResetCategoryRefresh();
|
|
|
|
// This function is used to control what data categories are actually
|
|
// shown or saved by this gatherer.
|
|
|
|
BOOL SetCategories(const CString & strCategory) { m_strCategory = strCategory; return TRUE; };
|
|
|
|
// The following method is used to retrieve the root category. It will
|
|
// allocate a new category and return a pointer to it. The caller is
|
|
// responsible for deallocating the category.
|
|
|
|
CDataCategory * GetRootDataCategory();
|
|
|
|
// The following methods are used to find specific nodes in the
|
|
// category tree. GetCategoryPath returns a backslash delimited path
|
|
// (starting at the root node) of category names to the node identified
|
|
// by strIdentifier. IsChildPath is used to determine if the passed
|
|
// category pointer is a child category of the passed category path.
|
|
|
|
BOOL GetCategoryPath(const CString & strIdentifier, CString & strPath);
|
|
BOOL IsChildPath(INTERNAL_CATEGORY * pInternalCat, const CString & strParentPath);
|
|
|
|
// Find is used to search for a specific string in the category names
|
|
// or data. The MSI_FIND_STRUCT contains information about the find,
|
|
// including where to start the search. Find may be used as a find
|
|
// next by using the last matched location and incrementing the line number.
|
|
// If Find returns TRUE, information about the search can be read from the
|
|
// struct. If it returns FALSE, and error occurred and the struct is invalid.
|
|
|
|
BOOL Find(MSI_FIND_STRUCT *pFind);
|
|
|
|
// This method is used to get more information about the last error
|
|
// in a gatherer or category member function call. This will return
|
|
// an error code, or zero for OK. Note that a successful method
|
|
// call will reset the value returned by this method.
|
|
|
|
DWORD GetLastError();
|
|
DWORD GetLastError(DWORD dwID);
|
|
|
|
// This is made a public member so that other classes can call it to force
|
|
// the connection to another computer.
|
|
|
|
CDataProvider * GetProvider();
|
|
|
|
// Include a debug only method to dump the contents of this category.
|
|
|
|
#ifdef _DEBUG
|
|
void Dump();
|
|
#endif
|
|
|
|
private:
|
|
BOOL m_fInitialized;
|
|
DWORD m_dwNextFreeID;
|
|
DWORD m_dwRootID;
|
|
DWORD m_dwLastError;
|
|
DataComplexity m_complexity;
|
|
CMapWordToPtr m_mapCategories; // map of IDs to internal category representations
|
|
CDataProvider * m_pProvider; // pointer to class encapsulating WBEM functionality
|
|
CString m_strDeferredProvider; // name of machine for deferred provider creation
|
|
CStringList m_strlistDeferredTemplates;
|
|
BOOL m_fDeferredPending;
|
|
DWORD m_dwDeferredError;
|
|
BOOL m_fTemplatesLoaded;
|
|
CString m_strCategory;
|
|
|
|
// The relative enumeration is used in conjunction with the GetRelative
|
|
// member function to retrieve a category pointer to a relative.
|
|
|
|
enum Relative { PARENT, CHILD, NEXT_SIBLING, PREV_SIBLING };
|
|
CDataCategory * GetRelative(DWORD dwID, Relative relative);
|
|
|
|
// These private methods are called by CDataCategory (and derived) objects.
|
|
// Since the CDataGatherer object stores all of the category information,
|
|
// all but the first of these are simply called by similarly named member
|
|
// functions of the category classes - see definitions there.
|
|
|
|
BOOL RefreshCategory(DWORD dwID, BOOL fRecursive, volatile BOOL *pfCancel, BOOL fSoftRefresh = FALSE);
|
|
int m_cInRefresh; // used to track how deep in recursion we are
|
|
|
|
BOOL IsValidDataCategory(DWORD dwID);
|
|
BOOL IsCategoryDynamic(DWORD dwID);
|
|
BOOL HasDynamicChildren(DWORD dwID, BOOL fRecursive);
|
|
BOOL GetName(DWORD dwID, CString & strName);
|
|
|
|
// These methods return information about columns.
|
|
|
|
DWORD GetColumnCount(DWORD dwID);
|
|
BOOL GetColumnCaption(DWORD dwID, DWORD nColumn, CString &strCaption);
|
|
BOOL GetColumnWidth(DWORD dwID, DWORD nColumn, DWORD &cxWidth);
|
|
BOOL GetColumnSort(DWORD dwID, DWORD nColumn, MSIColumnSortType &sorttype);
|
|
BOOL GetColumnDataComplexity(DWORD dwID, DWORD nColumn, DataComplexity & complexity);
|
|
|
|
// These methods return information about rows.
|
|
|
|
DWORD GetRowCount(DWORD dwID);
|
|
BOOL GetRowDataComplexity(DWORD dwID, DWORD nRow, DataComplexity & complexity);
|
|
|
|
// GetValue returns the string and DWORD value for the specified row and column.
|
|
|
|
BOOL GetValue(DWORD dwID, DWORD nRow, DWORD nColumn, CString &strValue, DWORD &dwValue);
|
|
|
|
// These private methods are used internally within this class and by the
|
|
// CTemplateFile friend class or the CRefreshFunctions friend class.
|
|
|
|
CDataCategory * BuildDataCategory(DWORD dwID);
|
|
INTERNAL_CATEGORY * GetInternalRep(DWORD dwID);
|
|
void SetLastError(DWORD dwError);
|
|
void SetLastError(DWORD dwError, DWORD dwID);
|
|
void SetLastErrorHR(HRESULT hrError);
|
|
void SetLastErrorHR(HRESULT hrError, DWORD dwID);
|
|
void ResetLastError();
|
|
CString GetErrorText();
|
|
CString GetErrorText(DWORD dwID);
|
|
void RemoveAllCategories();
|
|
GATH_FIELD * GetColumnField(DWORD dwID, DWORD nColumn);
|
|
BOOL FindCategoryByIdentifer(const CString & strIdentifier, CString & strPath, DWORD dwID);
|
|
DWORD FindCategoryByPath(const CString & strPath);
|
|
BOOL RecursiveFind(INTERNAL_CATEGORY * pCat, MSI_FIND_STRUCT *pFind, int & iLine, CString & strPath);
|
|
void GetCategoryPath(INTERNAL_CATEGORY * pCat, CString & strPath);
|
|
void LoadTemplates();
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// CDataCategory
|
|
//
|
|
// This class encapsulates the concept of a category. A category has a one-to-
|
|
// one correspondence with a node in the MMC namespace. The root CDataCategory
|
|
// object is found through a CDataGatherer object, and can be used to navigate
|
|
// though the tree of categories. The CDataCategory object can also be used
|
|
// to refresh data and a derived class can be used to return results.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
class CDataCategory
|
|
{
|
|
friend class CDataGatherer;
|
|
public:
|
|
CDataCategory();
|
|
virtual ~CDataCategory();
|
|
|
|
// This member function is used to retrieve the CDataGatherer object which
|
|
// created this CDataCategory (or derived class) object.
|
|
|
|
CDataGatherer * GetGatherer();
|
|
|
|
// Methods to retrieve basic information about this category.
|
|
|
|
BOOL GetName(CString &strName);
|
|
BOOL IsValid();
|
|
|
|
// The following methods are used to determine if this category is a
|
|
// dynamic category or if it has children which are dynamic. A dynamic
|
|
// category is one which has been generated during the refresh, and which
|
|
// may disappear after another refresh. For instance, there might be a
|
|
// category with is repeated for each user attached to a share. Note: the
|
|
// bRecursive parameter to HasDynamicChildren is used to search down through
|
|
// the tree if it is TRUE. Otherwise only the immediate children are examined.
|
|
|
|
BOOL IsDynamic();
|
|
BOOL HasDynamicChildren(BOOL fRecursive = FALSE);
|
|
|
|
// Category types. Note: later on we might end up adding { HTML, OCX }.
|
|
|
|
enum CatType { NONE, LISTVIEW };
|
|
|
|
// Methods to navigate through the tree of categories. The category
|
|
// object is allocated and a pointer to it returned. The caller is
|
|
// responsible for deallocating the object.
|
|
|
|
CDataCategory * GetParent();
|
|
CDataCategory * GetChild();
|
|
CDataCategory * GetNextSibling();
|
|
CDataCategory * GetPrevSibling();
|
|
|
|
// Refresh the information in this category.
|
|
|
|
BOOL Refresh(BOOL fRecursive = FALSE, volatile BOOL *pfCancel = NULL, BOOL fSoftRefresh = TRUE);
|
|
BOOL HasBeenRefreshed();
|
|
|
|
// Get information about the results pane for this category.
|
|
|
|
virtual CatType GetResultType() { return NONE; };
|
|
|
|
protected:
|
|
CDataGatherer * m_pGatherer; // CDataGatherer which created this object
|
|
DWORD m_dwID; // internal object ID (passed to CDataGatherer methods)
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// CDataListCategory
|
|
//
|
|
// This class extends CDataCategory for categories which show results in
|
|
// a list view.
|
|
//-----------------------------------------------------------------------------
|
|
|
|
class CDataListCategory : private CDataCategory
|
|
{
|
|
public:
|
|
CDataListCategory();
|
|
virtual ~CDataListCategory();
|
|
|
|
// We'll override GetResultType to return CDataCategory::LISTVIEW.
|
|
|
|
virtual CatType GetResultType() { return LISTVIEW; };
|
|
|
|
// Here are the methods specific to retrieving data from this category
|
|
// for the list view.
|
|
|
|
DWORD GetColumnCount();
|
|
DWORD GetRowCount();
|
|
BOOL GetColumnCaption(DWORD nColumn, CString &strCaption);
|
|
BOOL GetColumnWidth(DWORD nColumn, DWORD &cxWidth);
|
|
BOOL GetColumnDataComplexity(DWORD nColumn, DataComplexity & complexity);
|
|
BOOL GetRowDataComplexity(DWORD nRow, DataComplexity & complexity);
|
|
|
|
// This method returns the sorting type for the column. See comment
|
|
// for MSIColumnSortType at the beginning of this file.
|
|
|
|
BOOL GetColumnSort(DWORD nColumn, MSIColumnSortType & sorttype);
|
|
|
|
// This method returns the value for the requested row and column. Both
|
|
// the string value to display and a DWORD value possibly used for sorting
|
|
// are returned.
|
|
|
|
BOOL GetValue(DWORD nRow, DWORD nColumn, CString &strValue, DWORD &dwValue);
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// These error codes are returned by CDataGatherer::GetLastError().
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#define GATH_ERR_NOERROR 0x00000000L
|
|
#define GATH_ERR_ALLOCATIONFAILED 0x80000002L
|
|
#define GATH_ERR_BADCATEGORYID 0x80000003L
|
|
#define GATH_ERR_NOWBEMCONNECT 0x80000004L
|
|
#define GATH_ERR_NOWBEMLOCATOR 0x80000005L
|
|
#define GATH_ERR_NOTINITIALIZED 0x80000008L
|
|
#define GATH_ERR_BADCATIDENTIFIER 0x80000009L
|
|
#define GATH_ERR_FINDDATANOTFOUND 0x8000000AL
|
|
#define GATH_ERR_NOWBEMOUTOFMEM 0x8000000BL
|
|
#define GATH_ERR_NOWBEMACCESSDENIED 0x8000000CL
|
|
#define GATH_ERR_NOWBEMBADSERVER 0x8000000DL
|
|
#define GATH_ERR_NOWBEMNETWORKFAILURE 0x8000000EL
|
|
|
|
// Obsolete error messages (template information moved to DLLs).
|
|
//
|
|
// #define GATH_ERR_BADTEMPLATENAME 0x80000001L
|
|
// #define GATH_ERR_TEMPLATEVERSION 0x80000006L
|
|
// #define GATH_ERR_TEMPLATEFORMAT 0x80000007L
|