|
|
// GathSrc.cpp - Implementation of the WBEM Data Source and Folder Objects
//
// Copyright (c) 1998-1999 Microsoft Corporation
#include <io.h>
#include "StdAfx.h"
#include "DataSrc.h"
#include "gather.h"
#include "Resource.h"
#include "resrc1.h"
#include <atlbase.h> // Last to prevent a #error statement about <windows.h>
LPCTSTR cszDefaultNFT = _T("default.nft"); LPCTSTR cszClsid = _T("Clsid"); LPCTSTR cszInprocServerKey = _T("InprocServer32"); LPCTSTR cszDefaultDirectory = _T("Microsoft Shared\\MSInfo"); LPCTSTR cszProgramFiles = _T("C:\\Program Files"); LPCTSTR cszRegistryRoot = _T("Software\\Microsoft\\Shared Tools\\MSInfo"); LPCTSTR cszDirectoryKey = _T("Path");
/*
* GetInprocServerDirectory - Return the directory portion of the InprocServer32 * Subkey of HKEY_CLASSES_ROOT\Clsid\<cszClassID> * * History: a-jsari 10/24/97 Initial version */ static inline BOOL GetInprocServerDirectory(LPCTSTR cszClassID, LPTSTR szDirectoryBuffer, DWORD &dwSize) { CRegKey rkDirectory; CRegKey rkSubdirectory;
long lResult = rkDirectory.Open(HKEY_CLASSES_ROOT, _T("Clsid"), KEY_QUERY_VALUE); ASSERT(lResult == ERROR_SUCCESS); if (lResult != ERROR_SUCCESS) return FALSE; lResult = rkSubdirectory.Open(rkDirectory, cszClassID, KEY_QUERY_VALUE); ASSERT(lResult == ERROR_SUCCESS); if (lResult != ERROR_SUCCESS) return FALSE; lResult = rkDirectory.Open(rkSubdirectory, cszInprocServerKey, KEY_QUERY_VALUE); ASSERT(lResult == ERROR_SUCCESS); if (lResult != ERROR_SUCCESS) return FALSE; // Pointer == NULL: Get the default value
lResult = rkDirectory.QueryValue(szDirectoryBuffer, NULL, &dwSize); ASSERT(lResult == ERROR_SUCCESS); if (lResult != ERROR_SUCCESS) return FALSE; unsigned short ch = '\\'; LPTSTR szEnd = ::_tcsrchr(szDirectoryBuffer, ch); ASSERT(szEnd != NULL); if (szEnd == NULL) return FALSE; *szEnd = 0; return TRUE; }
/*
* GetDefaultMSInfoDirectory - Get the location of the Program Files directory from the * Registry and append our known path to it. * * History: a-jsari 11/21/97 Initial version */ void CMSInfoFile::GetDefaultMSInfoDirectory(LPTSTR szDefaultDirectory, DWORD dwSize) { CRegKey keyProgramFiles; long lResult;
do { lResult = keyProgramFiles.Open(HKEY_LOCAL_MACHINE, cszWindowsCurrentKey); ASSERT(lResult == ERROR_SUCCESS); if (lResult != ERROR_SUCCESS) break; lResult = keyProgramFiles.QueryValue(szDefaultDirectory, cszCommonFilesValue, &dwSize); ASSERT(lResult == ERROR_SUCCESS); } while (FALSE); if (lResult != ERROR_SUCCESS) { _tcscpy(szDefaultDirectory, cszProgramFiles); } _tcsncat(szDefaultDirectory, cszDefaultDirectory, dwSize); }
/*
* CWBEMDataSource - Constructor. Defaults to loading all .nft files in the * DLL file's directory. Alternately, loads the szTemplateFile as a * template file. * * History: a-jsari 10/15/97 Initial version. */ CWBEMDataSource::CWBEMDataSource(LPCTSTR szMachineName) : m_pGatherer(new CDataGatherer), m_strMachineName(_T("")), CDataSource(szMachineName), m_fEverRefreshed(FALSE), m_pThreadRefresh(NULL) { BOOL fGathererResult;
// m_pGatherer is deleted in the CWBEMDataSource destructor.
ASSERT(m_pGatherer); if (m_pGatherer == NULL) ::AfxThrowMemoryException();
if (szMachineName != NULL) { if ((*szMachineName == (TCHAR)'\\' || *szMachineName == (TCHAR)'/') && (szMachineName[1] == (TCHAR)'\\' || szMachineName[1] == (TCHAR)'/')) szMachineName += 2; } m_strMachineName = szMachineName;
fGathererResult = m_pGatherer->Create(szMachineName);
if (fGathererResult == FALSE) { CString strErrorMessage, strTitle; DWORD dwError = m_pGatherer->GetLastError();
AFX_MANAGE_STATE(::AfxGetStaticModuleState()); // Needed for AfxGetMainWnd()
switch (dwError) { case GATH_ERR_ALLOCATIONFAILED: case GATH_ERR_NOWBEMOUTOFMEM: ::AfxThrowMemoryException(); break; case GATH_ERR_NOWBEMCONNECT: strErrorMessage.Format(IDS_NOGATHERER, szMachineName); break; case GATH_ERR_NOWBEMLOCATOR: strErrorMessage.Format(IDS_NOLOCATOR, szMachineName); break; case GATH_ERR_NOWBEMACCESSDENIED: strErrorMessage.Format(IDS_GATHERACCESS, szMachineName); break; case GATH_ERR_NOWBEMBADSERVER: strErrorMessage.Format(IDS_BADSERVER, szMachineName); break; case GATH_ERR_NOWBEMNETWORKFAILURE: strErrorMessage.Format(IDS_NETWORKERROR, szMachineName); break; case GATH_ERR_BADCATEGORYID: strErrorMessage.LoadString(IDS_UNEXPECTED); break; } strTitle.LoadString( IDS_DESCRIPTION); ::MessageBox( ::AfxGetMainWnd()->GetSafeHwnd(), strErrorMessage, strTitle, MB_OK);
delete m_pGatherer; ::AfxThrowUserException(); }
m_pThreadRefresh = new CThreadingRefresh(m_pGatherer); }
#if FALSE
BOOL fGathererResult; CString strFile; TCHAR szTemplateBuffer[MAX_PATH];
// m_pGatherer is deleted in the CWBEMDataSource destructor.
ASSERT(m_pGatherer); if (m_pGatherer == NULL) ::AfxThrowMemoryException();
int wBufferSize = sizeof(szTemplateBuffer) / sizeof(TCHAR); // Change directory to the directory where our snap-in DLL lives.
ChangeToTemplateDirectory(szTemplateBuffer, wBufferSize); do { // Load the default file and all .nft files in the current directory.
// Remove a leading \\ or a leading // from the machine name.
if (szMachineName != NULL) { if ((*szMachineName == (TCHAR)'\\' || *szMachineName == (TCHAR)'/') && (szMachineName[1] == (TCHAR)'\\' || szMachineName[1] == (TCHAR)'/')) szMachineName += 2; } m_strMachineName = szMachineName; strFile = szTemplateBuffer; fGathererResult = m_pGatherer->Create(strFile, szMachineName); if (fGathererResult == FALSE) break;
// Read all subsidiary template files.
CFileFind ffTemplate; if (ffTemplate.FindFile(_T("*.nft"))) { BOOL fResult; do { fResult = ffTemplate.FindNextFile(); if (!fResult) { DWORD dwError = ::GetLastError(); ASSERT(dwError == ERROR_NO_MORE_FILES); } strFile = ffTemplate.GetFileName(); // Don't reload the default template file.
if (strFile.CompareNoCase(cszDefaultNFT) == 0) continue; // fGathererResult = m_pGatherer->AddTemplateFile(ffTemplate.GetFilePath());
if (fGathererResult == FALSE) break; } while (fResult); } else { fGathererResult = FALSE; break; } } while (FALSE);
if (fGathererResult == FALSE) { CString strErrorMessage, strTitle; DWORD dwError = m_pGatherer->GetLastError();
AFX_MANAGE_STATE(::AfxGetStaticModuleState()); // Needed for AfxGetMainWnd
switch (dwError) { case GATH_ERR_ALLOCATIONFAILED: case GATH_ERR_NOWBEMOUTOFMEM: ::AfxThrowMemoryException(); break; case GATH_ERR_NOWBEMCONNECT: strErrorMessage.Format(IDS_NOGATHERER, szMachineName); break; case GATH_ERR_NOWBEMLOCATOR: strErrorMessage.Format(IDS_NOLOCATOR, szMachineName); break; case GATH_ERR_NOWBEMACCESSDENIED: strErrorMessage.Format(IDS_GATHERACCESS, szMachineName); break; case GATH_ERR_NOWBEMBADSERVER: strErrorMessage.Format(IDS_BADSERVER, szMachineName); break; case GATH_ERR_NOWBEMNETWORKFAILURE: strErrorMessage.Format(IDS_NETWORKERROR, szMachineName); break; case GATH_ERR_BADCATEGORYID: strErrorMessage.LoadString(IDS_UNEXPECTED); break; } strTitle.LoadString(IDS_DESCRIPTION); ::MessageBox( ::AfxGetMainWnd()->GetSafeHwnd(), strErrorMessage, strTitle, MB_OK); delete m_pGatherer; ::AfxThrowUserException(); } } #endif
/*
* ~CWBEMDataSource - Destructor - Delete the gatherer pointer. * * History: a-jsari 10/15/97 Initial version */ CWBEMDataSource::~CWBEMDataSource() { delete m_pGatherer;
if (m_pThreadRefresh) { delete m_pThreadRefresh; m_pThreadRefresh = NULL; } }
/*
* GetNodeName - Return the node name for the root node. * * History: a-jsari 1/16/98 Initial version. */ BOOL CWBEMDataSource::GetNodeName(CString &strName) { AFX_MANAGE_STATE(::AfxGetStaticModuleState());
if (m_strMachineName.GetLength() > 0) strName.Format(IDS_NODENAME, (LPCTSTR)m_strMachineName); else { CString strLocal;
VERIFY(strLocal.LoadString(IDS_LOCALMACHINE)); strName.Format(IDS_NODENAME, (LPCTSTR)strLocal); } return TRUE; }
/*
* SetMachineName - Sets the name of the connected machine. * * History: a-jsari 1/16/98 Initial version. */ BOOL CWBEMDataSource::SetMachineName(const CString &strMachine) { BOOL fReturn;
m_strMachineName = strMachine; fReturn = m_pGatherer->SetConnect(strMachine); if (fReturn == FALSE) { CString strErrorMessage, strTitle; DWORD dwError = m_pGatherer->GetLastError();
// Needed for AfxGetMainWnd and LoadString/Format
AFX_MANAGE_STATE(::AfxGetStaticModuleState()); switch (dwError) { case GATH_ERR_NOWBEMCONNECT: strErrorMessage.Format(IDS_NOGATHERER, (LPCTSTR)strMachine); break; case GATH_ERR_NOWBEMLOCATOR: strErrorMessage.Format(IDS_NOLOCATOR, (LPCTSTR)strMachine); break; case GATH_ERR_NOWBEMACCESSDENIED: strErrorMessage.Format(IDS_GATHERACCESS, (LPCTSTR)strMachine); break; case GATH_ERR_NOWBEMBADSERVER: strErrorMessage.Format(IDS_BADSERVER, (LPCTSTR)strMachine); break; case GATH_ERR_NOWBEMNETWORKFAILURE: strErrorMessage.Format(IDS_NETWORKERROR, (LPCTSTR)strMachine); break; default: VERIFY(strErrorMessage.LoadString(IDS_UNEXPECTED)); ASSERT(FALSE); break; }
strTitle.LoadString(IDS_DESCRIPTION); ::MessageBox( ::AfxGetMainWnd()->GetSafeHwnd(), strErrorMessage, strTitle, MB_OK); } return fReturn; }
/*
* Find - Locate in the tree, by path and line number, the string contained * in strSearch. * * History: a-jsari 12/11/97 Initial version */ BOOL CWBEMDataSource::Find(const CString &strSearch, long lFindOptions) { BOOL fReturn; MSI_FIND_STRUCT mfsFind;
StartSearch(); mfsFind.m_fSearchData = (lFindOptions & FIND_OPTION_CATEGORY_ONLY) == 0;
if ((lFindOptions & FIND_OPTION_REPEAT_SEARCH) == 0) { if ((lFindOptions & FIND_OPTION_ONE_CATEGORY) != 0) { // Set our path to the selected node.
ASSERT(m_pfLast != NULL); m_pfLast->InternalName(m_strPath); m_iLine = -1; } else { m_strPath = _T(""); } m_strParentPath = m_strPath; m_iLine = -1; } else { // The root path does not have specific lines. (This if statement will
// fail if we cancel a find and then repeat it, when we don't want to
// increment the initial line to search.)
// We do want to increment the line, even when the path is empty. Otherwise,
// we can't get past a match on the root category when we do a find next.
// [old code] if (!m_strPath.IsEmpty()) ++m_iLine;
++m_iLine; } mfsFind.m_strSearch = strSearch; mfsFind.m_fCaseSensitive = FALSE; mfsFind.m_fSearchCategories = TRUE; mfsFind.m_strParentPath = m_strParentPath; mfsFind.m_strPath = m_strPath; mfsFind.m_iLine = m_iLine; mfsFind.m_pfCancel = &m_fCanceled;
fReturn = m_pGatherer->Find(&mfsFind); if (mfsFind.m_fFound) { m_strPath = mfsFind.m_strPath; m_iLine = mfsFind.m_iLine; return TRUE; } return FALSE; }
#if 0
/*
* StopSearch - Ends the current search * * History: a-jsari 1/19/98 Initial version */ BOOL CWBEMDataSource::StopSearch() { return FALSE; } #endif
/*
* GetRootNode - Return the root CFolder pointer. * * History: a-jsari 10/15/97 Initial version */ CFolder *CWBEMDataSource::GetRootNode() { if (!m_RootFolder) { // Deleted in the CWBEMDataSource destructor
m_RootFolder = new CWBEMFolder(m_pGatherer->GetRootDataCategory(), this); if (m_RootFolder == NULL) AfxThrowMemoryException(); } return CDataSource::GetRootNode(); }
/*
* SetDataComplexity - Set the gatherer's data complexity. * * History: a-jsari 12/3/97 Initial version. */ BOOL CWBEMDataSource::SetDataComplexity(enum DataComplexity Complexity) { CDataSource::SetDataComplexity(Complexity); return m_pGatherer->SetDataComplexity(Complexity); }
/*
* Save - Save information about the data source to a stream. * * History: a-jsari 11/13/97 Initial version */ HRESULT CWBEMDataSource::Save(IStream *pStm) { unsigned wValue; ULONG cWrite; HRESULT hResult;
USES_CONVERSION; wValue = GetType(); hResult = pStm->Write(&wValue, sizeof(wValue), &cWrite); ASSERT(SUCCEEDED(hResult) && (cWrite == sizeof(wValue))); wValue = m_strMachineName.GetLength(); hResult = pStm->Write(&wValue, sizeof(wValue), &cWrite); wValue *= sizeof(WCHAR); ASSERT(SUCCEEDED(hResult) && (cWrite == sizeof(wValue))); if (wValue != 0) { // Write the machine name as a wide character string to avoid
// conversion issues.
LPWSTR pszMachine = T2W(const_cast<LPTSTR>((LPCTSTR)m_strMachineName)); hResult = pStm->Write(pszMachine, wValue, &cWrite); ASSERT(SUCCEEDED(hResult) && (cWrite == wValue)); } return hResult; }
/*
* CWBEMFolder - Construct a folder. * * History: a-jsari 10/15/97 Initial version */ CWBEMFolder::CWBEMFolder(CDataCategory *pCategory, CDataSource *pDataSource, CFolder *pParentNode) :CListViewFolder(pDataSource, pParentNode), m_pCategory(pCategory), m_fBeenRefreshed(FALSE) { ASSERT(pDataSource != NULL); ASSERT(pDataSource->GetType() == CDataSource::GATHERER); if (pParentNode) ASSERT(pParentNode->GetType() == CDataSource::GATHERER); }
/*
* ~CWBEMFolder - Destruct the folder. * * History: a-jsari 10/15/97 Initial version */ CWBEMFolder::~CWBEMFolder() { delete m_pCategory; }
/*
* GetColumns - Return the number of columns. * * History: a-jsari 10/15/97 Initial version */ unsigned CWBEMFolder::GetColumns() const { ASSERT(m_pCategory != NULL); if (m_pCategory == NULL) return 0;
if (m_pCategory->GetResultType() != CDataCategory::LISTVIEW) return 0; return (int) dynamic_cast<CDataListCategory *>(m_pCategory)->GetColumnCount(); }
/*
* GetColumnTextAndWidth - Return the column width and text of the specified column. * * History: a-jsari 10/15/97 Initial version */ BOOL CWBEMFolder::GetColumnTextAndWidth(unsigned iColumn, CString &strName, unsigned &uWidth) const { if (m_pCategory->GetResultType() != CDataCategory::LISTVIEW) { ASSERT(FALSE); return FALSE; } BOOL fResult; fResult = dynamic_cast<CDataListCategory *>(m_pCategory)-> GetColumnCaption((DWORD)iColumn, strName); ASSERT(fResult); if (!fResult) return FALSE; fResult = dynamic_cast<CDataListCategory *>(m_pCategory)-> GetColumnWidth((DWORD)iColumn, (DWORD &)uWidth); ASSERT(fResult); return fResult; }
/*
* GetSubElement - Return the name of the sub-element indexed by iRow, iColumn * * History: a-jsari 10/15/97 Initial version */ BOOL CWBEMFolder::GetSubElement(unsigned iRow, unsigned iColumn, CString &szName) const { DWORD dwSortIndex; if (m_pCategory->GetResultType() != CDataCategory::LISTVIEW) { ASSERT(FALSE); return FALSE; }
// dwSortIndex ignored - should be stored in sort array
return dynamic_cast<CDataListCategory *>(m_pCategory)->GetValue(iRow, iColumn, szName, dwSortIndex); }
/*
* GetSortType - Return the type of sorting which goes on for each column. * * History: a-jsari 12/1/97 Initial version */ BOOL CWBEMFolder::GetSortType(unsigned iColumn, MSIColumnSortType &stColumn) const { if (m_pCategory->GetResultType() != CDataCategory::LISTVIEW) { ASSERT(FALSE); return 0; } if (!dynamic_cast<CDataListCategory *>(m_pCategory)->GetColumnSort((DWORD)iColumn, stColumn)) stColumn = NOSORT; return TRUE; }
/*
* GetSortIndex - Returns the index of a specific Row/Column indexed element. * * History: a-jsari 12/1/97 Initial version. */ DWORD CWBEMFolder::GetSortIndex(unsigned iRow, unsigned iColumn) const { DWORD dwSortIndex; CString szName;
if (m_pCategory->GetResultType() != CDataCategory::LISTVIEW) { ASSERT(FALSE); return 0; } VERIFY(dynamic_cast<CDataListCategory *>(m_pCategory)->GetValue(iRow, iColumn, szName, dwSortIndex)); return dwSortIndex; }
/*
* GetRows - returns the number of rows in the folder. * * History: a-jsari 10/15/97 Initial version */ unsigned CWBEMFolder::GetRows() const { // Add NULL check to fix 277774.
if (m_pCategory == NULL || m_pCategory->GetResultType() != CDataCategory::LISTVIEW) return 0; return (int) dynamic_cast<CDataListCategory *>(m_pCategory)->GetRowCount(); }
/*
* GetNextNode - Return the folder's next sibling pointer, creating a CFolder * from the CDataCategory pointer if necessary. * * History: a-jsari 10/15/97 Initial version */ CFolder *CWBEMFolder::GetNextNode() { // If we haven't tested this next pointer before, create the next CFolder.
if (fNextTested == FALSE) { fNextTested = TRUE; ASSERT(m_pCategory != NULL); if (m_pCategory == NULL) return NULL;
CDataCategory *NextCategory = m_pCategory->GetNextSibling(); if (NextCategory) { m_NextFolder = new CWBEMFolder(NextCategory, m_pDataSource, GetParentNode()); if (m_NextFolder == NULL) AfxThrowMemoryException(); } } return m_NextFolder; }
/*
* GetChildNode - Return the CFolder which represents the child's category. * * History: a-jsari 10/15/97 Initial version */ CFolder *CWBEMFolder::GetChildNode() { // If we haven't tested this child pointer, create the child CFolder.
if (fChildTested == FALSE) { fChildTested = TRUE; ASSERT(m_pCategory != NULL); if (m_pCategory == NULL) return FALSE;
CDataCategory *ChildCategory = m_pCategory->GetChild(); if (ChildCategory) { m_ChildFolder = new CWBEMFolder(ChildCategory, m_pDataSource, this); if (m_ChildFolder == NULL) AfxThrowMemoryException(); } } return m_ChildFolder; }
/*
* HasDynamicChildren - Return a flag describing whether any of the children of * the folder have any dynamic data items. * * History: a-jsari 10/15/97 Initial version */ BOOL CWBEMFolder::HasDynamicChildren() const { return m_pCategory->HasDynamicChildren(TRUE); }
/*
* IsDynamic - Determine whether the category has any dynamic data items. * * History: a-jsari 10/15/97 Initial version */ BOOL CWBEMFolder::IsDynamic() const { return m_pCategory->IsDynamic(); }
/*
* Refresh - Refresh this node in the tree. * * History: a-jsari 10/15/97 Initial version */
BOOL CWBEMFolder::Refresh(BOOL fRecursive) { ASSERT(m_pCategory != NULL); if (m_pCategory == NULL) return FALSE;
if (DataSource() && CDataSource::GATHERER == DataSource()->GetType()) { CWBEMDataSource * pSource = reinterpret_cast<CWBEMDataSource *>(DataSource()); if (pSource && pSource->m_pThreadRefresh) { pSource->m_pThreadRefresh->RefreshAll(this, NULL); return TRUE; } }
return m_pCategory->Refresh(fRecursive); }
/*
* GetColumnComplexity - Return the Complexity for the given column. * * History: a-jsari 12/23/97 Initial version */ DataComplexity CWBEMFolder::GetColumnComplexity(unsigned iColumn) { DataComplexity dcCurrent = BASIC;//ASSUMPTION :To avoid uninitialized memory warning by Prefix.
ASSERT(iColumn < GetColumns()); VERIFY(reinterpret_cast<CDataListCategory *>(m_pCategory)->GetColumnDataComplexity(iColumn, dcCurrent)); return dcCurrent; }
/*
* GetRowComplexity - Return the Complexity for the given row. * * History: a-jsari 12/23/97 Initial version */ DataComplexity CWBEMFolder::GetRowComplexity(unsigned iRow) { DataComplexity dcCurrent = BASIC;//ASSUMPTION :To avoid uninitialized memory warning by Prefix.
ASSERT(iRow < GetRows()); VERIFY(reinterpret_cast<CDataListCategory *>(m_pCategory)->GetRowDataComplexity(iRow, dcCurrent)); return dcCurrent; }
|