windows-nt/Source/XPSP1/NT/admin/pchealth/sysinfo/control/version5extension.h
2020-09-26 16:20:57 +08:00

328 lines
12 KiB
C++

//=============================================================================
// Contains definitions for reading in version 5.0 MSInfo extensions.
//=============================================================================
#pragma once
//-----------------------------------------------------------------------------
// Constants used in the data gathering files.
//-----------------------------------------------------------------------------
#define NODE_KEYWORD "node"
#define COLUMN_KEYWORD "columns"
#define LINE_KEYWORD "line"
#define ENUMLINE_KEYWORD "enumlines"
#define FIELD_KEYWORD "field"
#define STATIC_SOURCE "static"
#define TEMPLATE_FILE_TAG "MSINFO,0000"
#define SORT_VALUE "VALUE"
#define SORT_LEXICAL "LEXICAL"
#define COMPLEXITY_ADVANCED "ADVANCED"
#define COMPLEXITY_BASIC "BASIC"
#define DEPENDENCY_JOIN "dependency"
#define SQL_FILTER "WQL:"
//-----------------------------------------------------------------------------
// These structures are used by the INTERNAL_CATEGORY structure to store both
// the specification for what information is shown as well as the actually
// data to be shown (refreshed on command).
//-----------------------------------------------------------------------------
// GATH_VALUE is used to store a list of strings. A list of column names or a
// list of arguments would use the GATH_VALUE struct. Note, a next pointer is
// not needed because these structures will be allocated contiguously (in
// an array).
struct GATH_VALUE
{
GATH_VALUE();
~GATH_VALUE();
CString m_strText;
DWORD m_dwValue;
GATH_VALUE * m_pNext;
};
// A GATH_FIELD is used to store the specification for a text string. It contains
// a format string (a printf style string) and a GATH_VALUE pointer to a list of
// arguments for the format string.
struct GATH_FIELD
{
GATH_FIELD();
~GATH_FIELD();
CString m_strSource; // WBEM class containing information
CString m_strFormat; // printf-type format string
unsigned short m_usWidth; // width (if this field is for a column)
MSIColumnSortType m_sort; // how to sort this column
DataComplexity m_datacomplexity; // is this column BASIC or ADVANCED
GATH_VALUE * m_pArgs; // arguments for m_strFormat
GATH_FIELD * m_pNext; // next field in the list
};
// A GATH_LINESPEC is used to specify what is shown on a line in the listview. It
// contains a string for a class to enumerate. If this string is empty, then
// the struct merely represents a single line in the display. The GATH_FIELD pointer
// is to a list of the fields (one for each column), and the m_pNext pointer is
// to the next line to be displayed. If m_strEnumerateClass is not empty, then
// the class specified is enumerated, and the lines pointed to by m_pEnumeratedGroup
// are repeated for each instance of the class. Note, if a class is to be enumerated,
// the m_pFields pointer must be null (since this line won't display anything
// itself, but enumerate a class for another group of lines).
//
// m_pConstraintFields is a pointer to a linked list of fields which serve as
// constraints for the enumeration. These can be used to filter the enumerated
// instances or to perform joins to related classes so they are enumerated as
// well is the primary class. m_pConstraintFields should only be non-NULL when
// m_pEnumeratedGroup is non-NULL.
struct GATH_LINESPEC
{
GATH_LINESPEC();
~GATH_LINESPEC();
CString m_strEnumerateClass;
DataComplexity m_datacomplexity;
GATH_FIELD * m_pFields;
GATH_LINESPEC * m_pEnumeratedGroup;
GATH_FIELD * m_pConstraintFields;
GATH_LINESPEC * m_pNext;
};
// The GATH_LINE struct contains the actual data to be displayed on a line. The
// refresh operation will take list of GATH_LINESPEC structs and create a list
// of GATH_LINE structs. The m_aValue pointer is to a list of values to be
// displayed (one per column).
struct GATH_LINE
{
GATH_LINE();
~GATH_LINE();
GATH_VALUE * m_aValue;
DataComplexity m_datacomplexity;
};
//-----------------------------------------------------------------------------
// The following structure is used within this object to store information
// about the categories. Specifically, this structure will be allocated for
// each category, and a pointer stored in m_mapCategories. This representation
// will not be used outside this object, rather, a CDataCategory object will
// be used.
//-----------------------------------------------------------------------------
struct INTERNAL_CATEGORY
{
INTERNAL_CATEGORY();
~INTERNAL_CATEGORY();
GATH_VALUE m_categoryName; // realized name of category
GATH_FIELD m_fieldName; // field used to get name
CString m_strEnumerateClass; // if !(empty or "static"), this category repeated
CString m_strIdentifier; // non-localized internal name
CString m_strNoInstances; // message to use if there are no instances
BOOL m_fListView; // is this cat a list view
BOOL m_fDynamic; // was this cat enumerated
BOOL m_fIncluded; // should this cat be included
DWORD m_dwID; // the ID for this cat
DWORD m_dwParentID; // my parent
DWORD m_dwChildID; // my first child
DWORD m_dwDynamicChildID; // my first dynamically created child
DWORD m_dwNextID; // my next sibling
DWORD m_dwPrevID; // my previous sibling
DWORD m_dwColCount; // number of columns
GATH_FIELD * m_pColSpec; // list of fields to make col names
GATH_VALUE * m_aCols; // realized list of columns
GATH_LINESPEC* m_pLineSpec; // list of line specifiers
DWORD m_dwLineCount; // number of lines (NOT number of line specs)
GATH_LINE * * m_apLines; // realized list of lines
BOOL m_fRefreshed; // has the category ever been refreshed
DWORD m_dwLastError; // last error specific to this category
};
//-----------------------------------------------------------------------------
// A class to contain the template functions.
//-----------------------------------------------------------------------------
class CTemplateFileFunctions
{
public:
static DWORD ParseTemplateIntoVersion5Categories(const CString & strExtension, CMapWordToPtr & mapVersion5Categories);
static DWORD ReadTemplateFile(CFile * pFile, CMapWordToPtr & mapVersion5Categories);
static BOOL ReadHeaderInfo(CFile * pFile);
static BOOL VerifyUNICODEFile(CFile * pFile);
static BOOL VerifyAndAdvanceFile(CFile * pFile, const CString & strVerify);
static DWORD ReadNodeRecursive(CFile * pFile, CMapWordToPtr & mapCategories, DWORD dwParentID, DWORD dwPrevID);
static INTERNAL_CATEGORY * GetInternalRep(CMapWordToPtr & mapCategories, DWORD dwID);
static INTERNAL_CATEGORY * CreateCategory(CMapWordToPtr & mapCategories, DWORD dwNewID, DWORD dwParentID, DWORD dwPrevID);
static BOOL ReadArgument(CFile * pFile, CString & strSource);
static BOOL ReadField(CFile * pFile, GATH_FIELD & field);
static GATH_LINESPEC * ReadLineEnumRecursive(CFile * pFile, CMapWordToPtr & mapCategories);
static BOOL ReadColumnInfo(CFile * pFile, CMapWordToPtr & mapCategories, DWORD dwID);
static GATH_LINESPEC * ReadLineInfo(CFile * pFile);
static BOOL GetKeyword(CFile * pFile, CString & strKeyword);
};
//-----------------------------------------------------------------------------
// A class to contain the refresh functions.
//-----------------------------------------------------------------------------
class CWMIHelper;
class CRefreshFunctions
{
public:
static BOOL RefreshLines(CWMIHelper * pWMI, GATH_LINESPEC * pLineSpec, DWORD dwColumns, CPtrList & listLinePtrs, volatile BOOL * pfCancel);
static BOOL RefreshOneLine(CWMIHelper * pWMI, GATH_LINE * pLine, GATH_LINESPEC * pLineSpec, DWORD dwColCount);
static BOOL RefreshValue(CWMIHelper * pWMI, GATH_VALUE * pVal, GATH_FIELD * pField);
static BOOL GetValue(CWMIHelper * pWMI, TCHAR cFormat, TCHAR *szFormatFragment, CString &strResult, DWORD &dwResult, GATH_FIELD *pField, int iArgNumber);
};
//-----------------------------------------------------------------------------
// The CMSIObject class is a thin wrapper for the IWbemClassObject interface.
// We use this so we can return a custom label for a null object (if there
// are no instances, we sometimes want to show some caption).
//-----------------------------------------------------------------------------
typedef enum { MOS_NO_INSTANCES, MOS_MSG_INSTANCE, MOS_INSTANCE } MSIObjectState;
struct IWbemClassObject;
class CMSIObject
{
public:
CMSIObject(IWbemClassObject * pObject, const CString & strLabel, HRESULT hres, CWMIHelper * pWMI, MSIObjectState objState);
~CMSIObject();
HRESULT Get(BSTR property, LONG lFlags, VARIANT *pVal, VARTYPE *pvtType, LONG *plFlavor);
HRESULT GetErrorLabel(CString & strError);
MSIObjectState IsValid();
private:
IWbemClassObject * m_pObject;
CString m_strLabel;
HRESULT m_hresCreation;
CWMIHelper * m_pWMI;
MSIObjectState m_objState;
};
//-----------------------------------------------------------------------------
// The CMSIEnumerator class encapsulates the WBEM enumerator interface, or
// implements our own form of enumerator (such as for the LNK command in the
// template file).
//-----------------------------------------------------------------------------
struct IEnumWbemClassObject;
class CMSIEnumerator
{
public:
CMSIEnumerator();
~CMSIEnumerator();
HRESULT Create(const CString & strClass, const GATH_FIELD * pConstraints, CWMIHelper * pWMI);
HRESULT Next(CMSIObject ** ppObject);
HRESULT Reset(const GATH_FIELD * pConstraints);
private:
typedef enum { CLASS, WQL, LNK, INTERNAL } EnumType;
private:
EnumType m_enumtype;
BOOL m_fOnlyDups;
BOOL m_fGotDuplicate;
BOOL m_fMinOfOne;
int m_iMinOfOneCount;
CString m_strClass;
CString m_strObjPath;
CString m_strAssocClass;
CString m_strResultClass;
CString m_strLNKObject;
CString m_strNoInstanceLabel;
IEnumWbemClassObject * m_pEnum;
CWMIHelper * m_pWMI;
const GATH_FIELD * m_pConstraints;
HRESULT m_hresCreation;
IWbemClassObject * m_pSavedDup;
CString m_strSavedDup;
CStringList * m_pstrList;
private:
BOOL AssocObjectOK(IWbemClassObject * pObject, CString & strAssociatedObject);
HRESULT ParseLNKCommand(const CString & strStatement, CString & strObjPath, CString & strAssocClass, CString & strResultClass);
void ProcessEnumString(CString & strStatement, BOOL & fMinOfOne, BOOL & fOnlyDups, CWMIHelper * pWMI, CString & strNoInstanceLabel, BOOL fMakeDoubleBackslashes = FALSE);
HRESULT CreateInternalEnum(const CString & strInternal, CWMIHelper * pWMI);
HRESULT InternalNext(IWbemClassObject ** ppWBEMObject);
};
//-----------------------------------------------------------------------------
// A class to map a DWORD to refresh data (used by the refresh function).
//-----------------------------------------------------------------------------
class CMapExtensionRefreshData
{
public:
CMapExtensionRefreshData() : m_dwIndex(0) { };
~CMapExtensionRefreshData()
{
GATH_LINESPEC * pLineSpec;
WORD key;
for (POSITION pos = m_map.GetStartPosition(); pos != NULL;)
{
m_map.GetNextAssoc(pos, key, (void * &) pLineSpec);
if (pLineSpec)
delete pLineSpec;
}
m_map.RemoveAll();
CString * pstr;
for (pos = m_mapStrings.GetStartPosition(); pos != NULL;)
{
m_mapStrings.GetNextAssoc(pos, key, (void * &) pstr);
if (pstr)
delete pstr;
}
m_mapStrings.RemoveAll();
}
DWORD Insert(GATH_LINESPEC * pLineSpec)
{
if (pLineSpec == NULL)
return 0;
m_dwIndex += 1;
m_map.SetAt((WORD) m_dwIndex, (void *) pLineSpec);
return m_dwIndex;
}
void InsertString(DWORD dwID, const CString & strInsert)
{
CString * pstr = new CString(strInsert);
m_mapStrings.SetAt((WORD) dwID, (void *) pstr);
}
GATH_LINESPEC * Lookup(DWORD dwIndex)
{
GATH_LINESPEC * pReturn;
if (m_map.Lookup((WORD) dwIndex, (void * &) pReturn))
return pReturn;
return NULL;
}
CString * LookupString(DWORD dwIndex)
{
CString * pstrReturn;
if (m_mapStrings.Lookup((WORD) dwIndex, (void * &) pstrReturn))
return pstrReturn;
return NULL;;
}
private:
DWORD m_dwIndex;
CMapWordToPtr m_map;
CMapWordToPtr m_mapStrings;
};
extern CMapExtensionRefreshData gmapExtensionRefreshData;