//============================================================================= // This include file contains definitions of structures and classes used to // implement the categories, as well as the rows and columns of information // displayed and saved in MSInfo (regardless of the data source). //============================================================================= #pragma once #include "version5extension.h" //----------------------------------------------------------------------------- // A prototype for a function used for sorting the contents of the list. //----------------------------------------------------------------------------- extern int CALLBACK ListSortFunc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort); //----------------------------------------------------------------------------- // An enumeration for all the available places we might get data. Also an // enumeration for environments a category supports. //----------------------------------------------------------------------------- typedef enum { LIVE_DATA, NFO_410, NFO_500, XML_SNAPSHOT, XML_DELTA, NFO_700 } DataSourceType; typedef enum { ALL_ENVIRONMENTS, NT_ONLY, MILLENNIUM_ONLY } CategoryEnvironment; //----------------------------------------------------------------------------- // A column description - this is used internally to the CMSInfoCategory // category, and won't concern the calling code. //----------------------------------------------------------------------------- class CMSInfoColumn { public: CMSInfoColumn(); CMSInfoColumn(UINT uiCaption, UINT uiWidth, BOOL fSorts = TRUE, BOOL fLexical = TRUE, BOOL fAdvanced = FALSE); virtual ~CMSInfoColumn(); UINT m_uiCaption; CString m_strCaption; UINT m_uiWidth; BOOL m_fSorts; BOOL m_fLexical; BOOL m_fAdvanced; CMSInfoColumn(LPCTSTR szCaption, UINT uiWidth, BOOL fSorts = TRUE, BOOL fLexical = TRUE, BOOL fAdvanced = FALSE) : m_uiCaption(0), m_strCaption(szCaption), m_uiWidth(uiWidth), m_fSorts(fSorts), m_fLexical(fLexical), m_fAdvanced(fAdvanced) { } }; //----------------------------------------------------------------------------- // The CMSInfoCategory class corresponds to a category in the tree view. This // is an abstract base class for subclasses which implement categories for // various situations (such as live WMI data, XML Snapshot, XML Delta, etc.). // // Note - the view functionality (BASIC/ADVANCED) is included in this base // class because it's used by so many of the subclasses. Subclasses which // don't use the view (XML Delta, for example) should make all of their // columns basic. //----------------------------------------------------------------------------- class CMSInfoFile; class CMSInfoTextFile; class CMSInfoPrintHelper; class CMSInfoCategory { friend class CDataSource; // TBD fix this friend class CManageExtensionCategories; public: CMSInfoCategory() : m_uiCaption(0), m_pParent(NULL), m_pPrevSibling(NULL), m_pFirstChild(NULL), m_pNextSibling(NULL), m_acolumns(NULL), m_astrData(NULL), m_adwData(NULL), m_afRowAdvanced(NULL), m_hrError(S_OK), m_fDynamicColumns(TRUE), m_iSortColumn(-1), m_hti(NULL), m_fSkipCategory(FALSE), m_fShowCategory(TRUE) { } CMSInfoCategory(UINT uiCaption, LPCTSTR szName, CMSInfoCategory * pParent, CMSInfoCategory * pPrevious, CMSInfoColumn * pColumns = NULL, BOOL fDynamicColumns = TRUE, CategoryEnvironment environment = ALL_ENVIRONMENTS) : m_uiCaption(uiCaption), m_pParent(pParent), m_pPrevSibling(pPrevious), m_pFirstChild(NULL), m_pNextSibling(NULL), m_acolumns(pColumns), m_astrData(NULL), m_adwData(NULL), m_afRowAdvanced(NULL), m_strName(szName), m_hrError(S_OK), m_fDynamicColumns(fDynamicColumns), m_iRowCount(0), m_iColCount(0), m_iSortColumn(-1), m_hti(NULL), m_fSkipCategory(FALSE), m_fShowCategory(TRUE) { for (CMSInfoColumn * pColumn = m_acolumns; (pColumn && (pColumn->m_uiCaption || !pColumn->m_strCaption.IsEmpty())); m_iColCount++, pColumn++); if (m_acolumns && m_acolumns->m_fSorts) { m_iSortColumn = 0; m_fSortAscending = TRUE; m_fSortLexical = m_acolumns->m_fLexical; } // Check to see if this category belongs in this environment. if (environment != ALL_ENVIRONMENTS) { OSVERSIONINFO osv; osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if (GetVersionEx(&osv)) { if (environment == NT_ONLY) m_fSkipCategory = (osv.dwPlatformId != VER_PLATFORM_WIN32_NT); else m_fSkipCategory = (osv.dwPlatformId == VER_PLATFORM_WIN32_NT); } } } virtual ~CMSInfoCategory() { DeleteAllContent(); }; // Navigation functions for moving around in the category tree. Note, these // are included for convenience (and for cases with no UI), since you should // be able to do all of this using the actual tree control. virtual CMSInfoCategory * GetParent() { return m_pParent; }; virtual CMSInfoCategory * GetFirstChild() { CMSInfoCategory * pChild = m_pFirstChild; while (pChild && (pChild->m_fSkipCategory || !pChild->m_fShowCategory)) pChild = pChild->m_pNextSibling; return pChild; }; virtual CMSInfoCategory * GetNextSibling() { CMSInfoCategory * pNext = m_pNextSibling; while (pNext && (pNext->m_fSkipCategory || !pNext->m_fShowCategory)) pNext = pNext->m_pNextSibling; return pNext; }; virtual CMSInfoCategory * GetPrevSibling() { CMSInfoCategory * pPrev = m_pPrevSibling; while (pPrev && (pPrev->m_fSkipCategory || !pPrev->m_fShowCategory)) pPrev = pPrev->m_pPrevSibling; return pPrev; }; // Return the count of categories in the subtree with this category as the root. int GetCategoryCount() { int nCount = 1; CMSInfoCategory * pChild = GetFirstChild(); while (pChild) { nCount += pChild->GetCategoryCount(); pChild = pChild->GetNextSibling(); } return nCount; } // This function is used to control whether or not this category (and all // of its children) are shown or not. This will be called by the code which // processes the "/categories" command line flag. void SetShowCategory(BOOL fShow, BOOL fSetParent = TRUE) { // If we are supposed to show this category, then we had better // make sure all the parents are shown too. if (fShow && fSetParent) for (CMSInfoCategory * pParent = m_pParent; pParent; pParent = pParent->m_pParent) pParent->m_fShowCategory = TRUE; // Set the new flag for this category and each of this category's children. m_fShowCategory = fShow; for (CMSInfoCategory * pChild = m_pFirstChild; pChild; pChild = pChild->m_pNextSibling) pChild->SetShowCategory(fShow, FALSE); } // These functions are useful for associating a HTREEITEM with the // given category (very useful in find operations). protected: HTREEITEM m_hti; public: void SetHTREEITEM(HTREEITEM hti) { m_hti = hti; }; HTREEITEM GetHTREEITEM() { return m_hti; }; // Functions to get information for the data stored in this category. virtual void GetNames(CString * pstrCaption, CString * pstrName); virtual BOOL GetCategoryDimensions(int * piColumnCount, int * piRowCount); virtual BOOL IsRowAdvanced(int iRow); virtual BOOL IsColumnAdvanced(int iColumn); virtual BOOL GetColumnInfo(int iColumn, CString * pstrCaption, UINT * puiWidth, BOOL * pfSorts, BOOL * pfLexical); virtual BOOL GetData(int iRow, int iCol, CString ** ppstrData, DWORD * pdwData); virtual void SetColumnWidth(int iCol, int iWidth); // Return from where this category is getting its data. Also a function // to reset the state of the category (in case it's going to be reused, // and it's static). virtual DataSourceType GetDataSourceType() = 0; virtual void ResetCategory() { }; // Get the current HRESULT for this category (set during refresh, for instance). virtual HRESULT GetHRESULT() { return m_hrError; }; virtual void GetErrorText(CString * pstrTitle, CString * pstrMessage); virtual CString GetHelpTopic() { return CString(_T("")); }; // Saving to disk and printing Functions a-stephl // Functions that take as parameters file HANDLES or HDC's are the ones that will normally be // called by the shell; the functions that take CMSInfo objects as parameters are used for // recursing the operation over the category's children public: static BOOL SaveNFO(HANDLE hFile,CMSInfoCategory* pCategory, BOOL fRecursive); virtual void Print(HDC hDC, BOOL bRecursive,int nStartPage = 0, int nEndPage = 0, LPTSTR lpMachineName = NULL); virtual BOOL SaveAsText(HANDLE hFile, BOOL bRecursive, LPTSTR lpMachineName = NULL); //virtual BOOL SaveAsXml(HANDLE hFile, BOOL bRecursive); virtual BOOL SaveXML(HANDLE hFile); protected: virtual BOOL SaveToNFO(CMSInfoFile* pFile); virtual void SaveElements(CMSInfoFile *pFile); virtual BOOL SaveAsText(CMSInfoTextFile* pTxtFile, BOOL bRecursive); //virtual BOOL SaveAsXml(CMSInfoTextFile* pTxtFile, BOOL bRecursive); virtual void Print(CMSInfoPrintHelper* pPrintHelper, BOOL bRecursive); virtual BOOL SaveXML(CMSInfoTextFile* pTxtFile); public: CMSInfoCategory * m_pParent; CMSInfoCategory * m_pFirstChild; CMSInfoCategory * m_pNextSibling; CMSInfoCategory * m_pPrevSibling; int m_iSortColumn; // currently sorting by this column BOOL m_fSortLexical; // sort the current column lexically BOOL m_fSortAscending; // sort the current column ascending protected: BOOL m_fSkipCategory; // skip this category (wrong environment) BOOL m_fShowCategory; // show this category (defaults to true) int m_iRowCount, m_iColCount; // dimensions of the data CMSInfoColumn * m_acolumns; // should be [m_iColCount] BOOL m_fDynamicColumns; // true if m_acolumns should be deleted CString * m_astrData; // should be [m_iRowCount * m_iColCount] DWORD * m_adwData; // should be [m_iRowCount * m_iColCount] BOOL * m_afRowAdvanced; // should be [m_iRowCount] UINT m_uiCaption; // resource ID for the caption string, used to load... CString m_strCaption; // the caption (display) string CString m_strName; // internal category name (non-localized) HRESULT m_hrError; // HRESULT for a possible category-wide error void DeleteAllContent(); void DeleteContent(); void AllocateAllContent(int iRowCount, int iColCount); void AllocateContent(int iRowCount); void SetData(int iRow, int iCol, const CString & strData, DWORD dwData); void SetAdvancedFlag(int iRow, BOOL fAdvanced); }; //----------------------------------------------------------------------------- // The CMSInfoLiveCategory class implements categories for live data view. // This is done primarily by adding a Refresh() function and a constructor // which takes a function pointer for refreshing the category and pointers // to category relatives. // // This class has a member variable which is a pointer to a refresh function. // This function returns an HRESULT, and takes the following values: // // pWMI a CWMIHelper object, which abstracts data access // dwIndex a category specific value which the refresh function can // use to determine which of multiple categories to refresh // pfCancel a flag indicating that the refresh should be cancelled // which should be checked frequently during the refresh // aColValues an array of CPtrList objects, which should contain the // results of the refresh, in the form of a list of CMSIValue // instances (each list is for a given column, and should contain // entries equal to the number of rows) // iColCount the number of entries in the aColValues array // ppCache a pointer to a void pointer which the function can use to save // cached information - changes to this pointer will be saved // through multiple calls to the refresh function (note: if the // refresh function is called with a NULL value for pWMI, the // function should free whatever's been allocated into the // ppCache pointer) //----------------------------------------------------------------------------- struct CMSIValue { CMSIValue(LPCTSTR szValue, DWORD dwValue, BOOL fAdvanced = FALSE) : m_strValue(szValue), m_dwValue(dwValue), m_fAdvanced(fAdvanced) { } CString m_strValue; DWORD m_dwValue; BOOL m_fAdvanced; }; class CLiveDataSource; class CWMIHelper; typedef HRESULT (*RefreshFunction)(CWMIHelper * pWMI, DWORD dwIndex, volatile BOOL * pfCancel, CPtrList * aColValues, int iColCount, void ** ppCache); class CMSInfoLiveCategory : public CMSInfoCategory { friend DWORD WINAPI ThreadRefresh(void * pArg); friend class CXMLDataSource; friend class CXMLSnapshotCategory; public: // Functions overridden from the base class: virtual ~CMSInfoLiveCategory(); virtual DataSourceType GetDataSourceType() { return LIVE_DATA; }; void GetErrorText(CString * pstrTitle, CString * pstrMessage); // Functions specific to the subclass: CMSInfoLiveCategory(UINT uiCaption, LPCTSTR szName, RefreshFunction pFunction, DWORD dwRefreshIndex, CMSInfoCategory * pParent, CMSInfoCategory * pPrevious, const CString & strHelpTopic = _T(""), CMSInfoColumn * pColumns = NULL, BOOL fDynamicColumns = TRUE, CategoryEnvironment environment = ALL_ENVIRONMENTS); CMSInfoLiveCategory(CMSInfoLiveCategory & copyfrom); CMSInfoLiveCategory(INTERNAL_CATEGORY * pinternalcat); virtual BOOL Refresh(CLiveDataSource * pSource, BOOL fRecursive); BOOL RefreshSynchronous(CLiveDataSource * pSource, BOOL fRecursive); BOOL RefreshSynchronousUI(CLiveDataSource * pSource, BOOL fRecursive, UINT uiMessage, HWND hwnd); BOOL EverBeenRefreshed() { return (m_dwLastRefresh != 0); } void ResetCategory() { m_dwLastRefresh = 0; }; void SetMachine(LPCTSTR szMachine) { m_strMachine = szMachine; m_hrError = S_OK; }; CString GetHelpTopic() { return m_strHelpTopic; }; protected: DWORD m_dwLastRefresh; DWORD m_dwRefreshIndex; RefreshFunction m_pRefreshFunction; CString m_strMachine; CString m_strHelpTopic; }; //----------------------------------------------------------------------------- // The CMSInfoHistoryCategory class implements categories for the view // of history data. //----------------------------------------------------------------------------- class CMSInfoHistoryCategory : public CMSInfoLiveCategory { public: CMSInfoHistoryCategory(UINT uiCaption, LPCTSTR szName, CMSInfoCategory * pParent, CMSInfoCategory * pPrevious, CMSInfoColumn * pColumns = NULL, BOOL fDynamicColumns = TRUE) : CMSInfoLiveCategory(uiCaption, szName, NULL, 0, pParent, pPrevious, _T(""), pColumns, fDynamicColumns, ALL_ENVIRONMENTS), m_iDeltaIndex(-1) { } void UpdateDeltaIndex(int iIndex) { m_dwLastRefresh = 0; CMSInfoHistoryCategory * pChild = (CMSInfoHistoryCategory *)GetFirstChild(); while (pChild) { pChild->UpdateDeltaIndex(iIndex); pChild = (CMSInfoHistoryCategory *)pChild->GetNextSibling(); } m_iDeltaIndex = iIndex; } BOOL Refresh(CLiveDataSource * pSource, BOOL fRecursive); public: CPtrList m_aValList[5]; void ClearLines(); /*void InsertChangeLine(int nDays, LPCTSTR szType, LPCTSTR szName, LPCTSTR szProperty, LPCTSTR szFromVal, LPCTSTR szToVal); void InsertAddLine(int nDays, LPCTSTR szType, LPCTSTR szName); void InsertRemoveLine(int nDays, LPCTSTR szType, LPCTSTR szName); void InsertLine(int nDays, LPCTSTR szType, LPCTSTR szName, LPCTSTR szProperty, LPCTSTR szDetails = NULL);*/ void InsertChangeLine(CTime tm, LPCTSTR szType, LPCTSTR szName, LPCTSTR szProperty, LPCTSTR szFromVal, LPCTSTR szToVal); void InsertAddLine(CTime tm, LPCTSTR szType, LPCTSTR szName); void InsertRemoveLine(CTime tm, LPCTSTR szType, LPCTSTR szName); void InsertLine(CTime tm, LPCTSTR szType, LPCTSTR szName, LPCTSTR szProperty, LPCTSTR szDetails = NULL); void CommitLines(); int m_iDeltaIndex; private: };