windows-nt/Source/XPSP1/NT/enduser/troubleshoot/msinfo/gather.h
2020-09-26 16:20:57 +08:00

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