Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1122 lines
27 KiB

#include "precomp.h"
#include "arrtempl.h" // for CDeleteMe
#include "md5wbem.h" // for MD5
#include "winmgmt.h"
#include "wbemdelta.h"
#include <tchar.h>
#include <vector>
#include <map>
CPerfLib::CPerfLib(TCHAR * SvcName):
m_wstrServiceName(NULL),
m_wstrFull(NULL),
m_hKey(NULL),
m_bOK(FALSE),
m_pwcsLibrary(NULL),
m_pwcsOpenProc(NULL),
m_pwcsCollectProc(NULL),
m_pwcsCloseProc(NULL)
{
if (SvcName)
{
DWORD dwLen = _tcslen(SvcName);
DWORD dwLenPrefix = _tcslen(_T("SYSTEM\\CurrentControlSet\\Services\\"));
TCHAR * pStart = SvcName+dwLenPrefix;
TCHAR * pNameEnd = _tcschr(pStart,_T('\\'));
if (pNameEnd)
{
ULONG_PTR NameLength = (ULONG_PTR)pNameEnd-(ULONG_PTR)pStart;
NameLength/=sizeof(TCHAR);
m_wstrServiceName = new TCHAR[NameLength+1];
if (!m_wstrServiceName)
{
return; // OUT_OF_MEMORY
}
m_wstrServiceName[NameLength]=0;
memcpy(m_wstrServiceName,pStart,NameLength*sizeof(TCHAR));
m_wstrFull = new TCHAR[dwLen+1];
if (m_wstrFull)
{
lstrcpy(m_wstrFull, SvcName);
m_hKey = NULL;
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE,
m_wstrFull,
NULL,
KEY_READ,
&m_hKey))
{
m_pwcsLibrary = NULL;
m_pwcsOpenProc = NULL;
m_pwcsCollectProc = NULL;
m_pwcsCloseProc = NULL;
m_bOK = TRUE;
}
}
}
}
}
CPerfLib::~CPerfLib()
{
if (m_wstrServiceName)
delete [] m_wstrServiceName;
if (m_wstrFull)
delete [] m_wstrFull;
if (m_pwcsLibrary)
delete [] m_pwcsLibrary;
if (m_pwcsOpenProc)
delete [] m_pwcsOpenProc; // not needed as a member
if (m_pwcsCollectProc)
delete [] m_pwcsCollectProc; // not needed as a member
if (m_pwcsCloseProc)
delete [] m_pwcsCloseProc; // not needed as a member
if (m_hKey)
RegCloseKey(m_hKey);
}
HRESULT CPerfLib::GetFileSignature( CheckLibStruct * pCheckLib )
{
HRESULT hr = WBEM_S_NO_ERROR;
if (!pCheckLib){
return WBEM_E_INVALID_PARAMETER;
}
// Get the current library's file time
// ===================================
HANDLE hFile = NULL;
DWORD dwRet = 0;
WCHAR wszFullPath[MAX_PATH];
WCHAR* pwcsTemp = NULL;
if ( 0 != SearchPathW( NULL, m_pwcsLibrary, NULL, MAX_PATH, wszFullPath, &pwcsTemp ) )
{
hFile = CreateFileW( wszFullPath, GENERIC_READ,FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if ( INVALID_HANDLE_VALUE != hFile )
{
DWORD dwFileSizeLow = 0;
DWORD dwFileSizeHigh = 0;
__int32 nFileSize = 0;
DWORD dwNumRead = 0;
BYTE* aBuffer = NULL;
dwFileSizeLow = GetFileSize( hFile, &dwFileSizeHigh );
nFileSize = ( dwFileSizeHigh << 32 ) + dwFileSizeLow;
FILETIME ft;
if (GetFileTime(hFile,&ft,NULL,NULL))
{
HANDLE hFileMap = NULL;
hFileMap = CreateFileMapping(hFile,NULL,PAGE_READONLY,dwFileSizeHigh,dwFileSizeLow,NULL);
if (hFileMap)
{
aBuffer = (BYTE *)MapViewOfFile(hFileMap,
FILE_MAP_READ,
0,0,0);
if (aBuffer)
{
//
// do the real work
//
MD5 md5;
BYTE aSignature[16];
md5.Transform( aBuffer, nFileSize, aSignature );
// return our data
memcpy(pCheckLib->Signature,aSignature,sizeof(aSignature));
pCheckLib->FileTime = ft;
pCheckLib->FileSize = nFileSize;
UnmapViewOfFile(aBuffer);
}
else
{
hr = WBEM_E_OUT_OF_MEMORY;
}
CloseHandle(hFileMap);
}
else
{
hr = WBEM_E_OUT_OF_MEMORY;
}
/*
aBuffer = new BYTE[nFileSize];
CDeleteMe<BYTE> dmBuffer( aBuffer );
if ( NULL != aBuffer )
{
if ( ReadFile( hFile, aBuffer, nFileSize, &dwNumRead, FALSE ) )
{
MD5 md5;
BYTE aSignature[16];
md5.Transform( aBuffer, dwNumRead, aSignature );
// return our data
memcpy(pCheckLib->Signature,aSignature,sizeof(aSignature));
pCheckLib->FileTime = ft;
pCheckLib->FileSize = nFileSize;
}
else
{
hr = WBEM_E_TOO_MUCH_DATA;
}
}
else
{
hr = WBEM_E_OUT_OF_MEMORY;
}
*/
}
else
{
hr = WBEM_E_FAILED;
}
CloseHandle( hFile );
}
else
{
hr = WBEM_E_FAILED;
}
}
else
{
hr = WBEM_E_NOT_FOUND;
}
return hr;
}
LONG
GetBinary(HKEY hKey, TCHAR * Value, BYTE ** ppBuff, DWORD * pdwSize)
{
LONG lRet;
DWORD dwType;
DWORD dwSize = 0;
// null Value is allowed
if (!ppBuff || !pdwSize)
return ERROR_INVALID_PARAMETER;
lRet = RegQueryValueEx(hKey,
Value,
NULL,
&dwType,
NULL,
&dwSize);
if ((ERROR_SUCCESS == lRet) &&
(REG_BINARY == dwType))
{
*pdwSize = dwSize;
if (dwSize > 0)
{
*ppBuff = new BYTE[dwSize];
if (*ppBuff){
lRet = RegQueryValueEx(hKey,
Value,
NULL,
&dwType,
(BYTE *)(*ppBuff),
&dwSize);
} else {
lRet = ERROR_OUTOFMEMORY;
}
}
}
else
{
lRet = ERROR_INVALID_PARAMETER;
}
return lRet;
}
LONG
GetDWORD(HKEY hKey, TCHAR * Value ,DWORD * pDword)
{
LONG lRet;
DWORD dwType = 0;
DWORD dwSize = sizeof(DWORD);
if (!pDword)
return ERROR_INVALID_PARAMETER;
lRet = RegQueryValueEx(hKey,
Value,
NULL,
&dwType,
(BYTE *)pDword,
&dwSize);
if ((REG_DWORD == dwType) &&
(ERROR_SUCCESS == lRet))
return lRet;
else
return ERROR_INVALID_PARAMETER;
}
LONG
GetStr(HKEY hKey, TCHAR * Value ,TCHAR ** ppStr)
{
LONG lRet;
DWORD dwType;
DWORD dwSize = 0;
if (!ppStr)
return ERROR_INVALID_PARAMETER;
lRet = RegQueryValueEx(hKey,
Value,
NULL,
&dwType,
NULL,
&dwSize);
if ((ERROR_SUCCESS == lRet) &&
((REG_SZ == dwType) || (REG_EXPAND_SZ == dwType)))
{
if (dwSize > 0)
{
TCHAR * pString = new TCHAR[dwSize];
if (pString)
{
lRet = RegQueryValueEx(hKey,
Value,
NULL,
&dwType,
(BYTE *)(pString),
&dwSize);
if (ERROR_SUCCESS == lRet)
{
if (REG_EXPAND_SZ == dwType)
{
TCHAR * pExpanded = new TCHAR[dwSize + MAX_PATH];
if (pExpanded)
{
if(ExpandEnvironmentStrings(pString,pExpanded,(dwSize + MAX_PATH)))
{
*ppStr = pExpanded;
delete [] pString;
}
else
{
delete [] pString;
lRet = ERROR_OUTOFMEMORY;
}
}
else
{
delete [] pString;
lRet = ERROR_OUTOFMEMORY;
}
}
else
{
*ppStr = pString;
}
}
else
{
goto empty_string;
}
}
else
{
lRet = ERROR_OUTOFMEMORY;
}
}
else // empty string
{
empty_string:
*ppStr = new TCHAR[sizeof(_T(""))];
if (*ppStr) {
lstrcpy(*ppStr,_T(""));
} else {
lRet = ERROR_OUTOFMEMORY;
}
}
}
else
{
lRet = ERROR_INVALID_PARAMETER;
}
return lRet;
}
int CPerfLib::CheckFileSignature(HKEY hKey)
{
int hr = Perf_SeemsNew;
int nRet = 0;
BYTE cCurrentMD5[16];
BYTE* cStoredMD5 = NULL;
// Get the stored file signature
// =============================
CheckLibStruct StoredLibStruct;
int nRet1;
int nRet2;
int nRet3;
DWORD dwSize;
nRet1 = GetBinary( hKey, ADAP_PERFLIB_SIGNATURE, (PBYTE*)&cStoredMD5, &dwSize );
CDeleteMe<BYTE> dmStoredMD5( cStoredMD5 );
if (cStoredMD5 && (dwSize == sizeof(StoredLibStruct.Signature)))
{
memcpy(&StoredLibStruct.Signature,cStoredMD5,sizeof(StoredLibStruct.Signature));
BYTE * pFileTime = NULL;
nRet2 = GetBinary( hKey, ADAP_PERFLIB_TIME, (PBYTE*)&pFileTime, &dwSize );
CDeleteMe<BYTE> dmFileTime( pFileTime );
if (pFileTime)
{
memcpy(&StoredLibStruct.FileTime,pFileTime,sizeof(FILETIME));
}
nRet3 = GetDWORD(hKey, ADAP_PERFLIB_SIZE,&StoredLibStruct.FileSize);
if((ERROR_SUCCESS == nRet1) &&
(ERROR_SUCCESS == nRet2) &&
(ERROR_SUCCESS == nRet3))
{
// Get the current library's signature
// ===================================
CheckLibStruct CurrentLibStruct;
memset(&CurrentLibStruct,0,sizeof(CheckLibStruct));
if (SUCCEEDED(GetFileSignature( &CurrentLibStruct )))
{
if ( (StoredLibStruct.FileSize == CurrentLibStruct.FileSize) &&
(0 == memcmp( &StoredLibStruct.Signature, &CurrentLibStruct.Signature, sizeof(CurrentLibStruct.Signature) )) &&
(0 == memcmp( &StoredLibStruct.FileTime, &CurrentLibStruct.FileTime, sizeof(FILETIME))) )
{
hr = Perf_NotChanged;
}
else
{
hr = Perf_SeemsNew;
//DBG_PRINTFA((pBuff,"no FileSize or Signature or FIleSuze\n"));
}
}
else
{
hr = Perf_SeemsNew;
//DBG_PRINTFA((pBuff,"no GetFileSignature\n"));
}
}
else
{
hr = Perf_SeemsNew;
//DBG_PRINTFA((pBuff,"no triple regkey\n"));
}
}
else
{
//DBG_PRINTFA((pBuff,"no ADAP_PERFLIB_SIGNATURE\n"));
}
return hr;
}
int
CPerfLib::VerifyLoaded()
{
int hr = Perf_Invalid;
LONG lRet;
{
DWORD dwFirstCtr = 0,
dwLastCtr = 0;
TCHAR * wszObjList = NULL;
if ( ( ERROR_SUCCESS == GetStr( GetHKey(), L"Object List", &wszObjList )) ||
( ( ERROR_SUCCESS == GetDWORD( GetHKey(), L"First Counter", &dwFirstCtr )) &&
( ERROR_SUCCESS == GetDWORD( GetHKey(), L"Last Counter", &dwLastCtr ))))
{
hr = InitializeEntryPoints(GetHKey());
if (wszObjList)
{
delete [] wszObjList;
}
} else { // more special cases
if ( (0 == _tcsicmp(m_wstrServiceName,_T("TCPIP"))) ||
(0 == _tcsicmp(m_wstrServiceName,_T("TAPISRV"))) ||
(0 == _tcsicmp(m_wstrServiceName,_T("PERFOS" ))) ||
(0 == _tcsicmp(m_wstrServiceName,_T("PERFPROC"))) ||
(0 == _tcsicmp(m_wstrServiceName,_T("PERFDISK"))) ||
(0 == _tcsicmp(m_wstrServiceName,_T("PERFNET"))) ||
(0 == _tcsicmp(m_wstrServiceName,_T("SPOOLER"))) ||
(0 == _tcsicmp(m_wstrServiceName,_T("MSFTPSvc"))) ||
(0 == _tcsicmp(m_wstrServiceName,_T("RemoteAccess"))) ||
(0 == _tcsicmp(m_wstrServiceName,_T("WINS"))) ||
(0 == _tcsicmp(m_wstrServiceName,_T("MacSrv"))) ||
(0 == _tcsicmp(m_wstrServiceName,_T("AppleTalk"))) ||
(0 == _tcsicmp(m_wstrServiceName,_T("NM"))) ||
(0 == _tcsicmp(m_wstrServiceName,_T("RSVP"))) )
{
hr = InitializeEntryPoints(GetHKey());
}
}
}
return hr;
}
int
CPerfLib::InitializeEntryPoints(HKEY hKey)
{
int hr = Perf_SeemsNew;
// see if someone disabled this library
DWORD dwDisable = 0;
if ( ERROR_SUCCESS == GetDWORD( hKey, _T("Disable Performance Counters"), &dwDisable ) &&
(dwDisable != 0) )
{
hr = Perf_Disabled;
}
if ((ERROR_SUCCESS == GetDWORD( hKey, _T("WbemAdapStatus"), &dwDisable))
&& (0xFFFFFFFF == dwDisable))
{
hr = Perf_Disabled;
}
// the perflib is OK for the world, see if it os OK for US
if (SUCCEEDED(hr)){
if (!(( ERROR_SUCCESS == GetStr( hKey, _T("Library"), &m_pwcsLibrary ) ) &&
( ERROR_SUCCESS == GetStr( hKey, _T("Open"), &m_pwcsOpenProc ) )&&
( ERROR_SUCCESS == GetStr( hKey, _T("Collect"), &m_pwcsCollectProc ) ) &&
( ERROR_SUCCESS == GetStr( hKey, _T("Close"), &m_pwcsCloseProc ) ) ))
{
hr = Perf_Invalid;
}
else
{
hr = Perf_SetupOK;
}
}
return hr;
}
int
CPerfLib::VerifyLoadable()
{
if (!m_bOK)
return Perf_Invalid;
int hr;
hr = VerifyLoaded();
if ( Perf_SetupOK == hr )
{
hr = CheckFileSignature(GetHKey());
}
return hr;
}
TCHAR * g_ExcludeList[] = {
_T("WMIAPRPL")
};
//
//
// GetListofSvcs
//
////////////////////////////////////////////////////////////
HRESULT
GetListOfSvcs(LIST_ENTRY * pListServices)
{
LONG lRet;
HKEY hKey;
HRESULT hRes = WBEM_NO_ERROR;
lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
SVC_KEY,
0,KEY_READ,
&hKey);
if (ERROR_SUCCESS == lRet)
{
DWORD dwIndex = 0;
TCHAR KeyName[MAX_PATH];
TCHAR * pKeyName = KeyName;
DWORD dwKeyNameSize = (sizeof(KeyName)/sizeof(TCHAR));
FILETIME FileTime;
while (ERROR_SUCCESS == lRet)
{
if (pKeyName != KeyName)
{
delete [] pKeyName;
pKeyName = KeyName;
}
dwKeyNameSize = (sizeof(KeyName)/sizeof(TCHAR));
lRet = RegEnumKeyEx(hKey,
dwIndex,
pKeyName,
&dwKeyNameSize,
NULL,NULL,NULL,
&FileTime);
if (ERROR_INSUFFICIENT_BUFFER == lRet)
{
pKeyName = new TCHAR[dwKeyNameSize];
if (pKeyName)
{
lRet = RegEnumKeyEx(hKey,
dwIndex,
pKeyName,
&dwKeyNameSize,
NULL,NULL,NULL,
&FileTime);
}
else
{
lRet = ERROR_OUTOFMEMORY;
}
}
if (ERROR_SUCCESS == lRet)
{
dwIndex++;
DWORD i;
DWORD NumExcluded = sizeof(g_ExcludeList)/sizeof(TCHAR *);
for (i=0; i<NumExcluded; i++)
{
if (0 == _tcsicmp(g_ExcludeList[i],pKeyName)){
break;
}
}
// if we pass all the Excluded Array then we are OK to add
if (i == NumExcluded)
{
DWORD dwSize = _tcslen(pKeyName);
LinkString * pLinkString = (LinkString *)new BYTE[sizeof(LinkString) + dwSize*sizeof(TCHAR)];
if (pLinkString)
{
pLinkString->Size = dwSize;
_tcscpy(pLinkString->pString,pKeyName);
InsertTailList(pListServices,&pLinkString->Entry);
}
else
{
lRet = ERROR_OUTOFMEMORY;
}
}
}
//
// the lack of the else case here will prevent the loop
// from completing if only one key is BAD
//
}
if (pKeyName != KeyName)
{
delete [] pKeyName;
pKeyName = KeyName;
}
if (ERROR_NO_MORE_ITEMS != lRet)
{
hRes = WBEM_E_FAILED;
}
RegCloseKey(hKey);
}
else
{
hRes = WBEM_E_FAILED;
}
return hRes;
}
//
//
// GetSvcWithPerf
//
///////////////////////////////////////////////////////////
#define FIXED_SIZE (sizeof(_T("System\\CurrentControlSet\\Services\\%s\\Performance")))
HRESULT
GetSvcWithPerf(/*IN OUT*/ LIST_ENTRY * pListHead)
{
TCHAR KeyPath[MAX_PATH+1];
TCHAR * pKeyPath = KeyPath;
LIST_ENTRY LocalListHead;
InitializeListHead(&LocalListHead);
// now change the head to the list
// assume the list is NOT EMPTY
LIST_ENTRY * pEntry = pListHead->Flink; // point to the first item
RemoveEntryList(pListHead); // remove the head
InitializeListHead(pListHead); // clear the head
InsertTailList(pEntry,&LocalListHead); // put in the same place the New Local head
HRESULT hRes = WBEM_NO_ERROR;
DWORD i;
for (pEntry = LocalListHead.Flink;
pEntry != &LocalListHead;
pEntry = pEntry->Flink)
{
LinkString * pLinkString = (LinkString *) pEntry;
if ((FIXED_SIZE + pLinkString->Size) < MAX_PATH )
{
_stprintf(KeyPath,_T("System\\CurrentControlSet\\Services\\%s\\Performance"),pLinkString->pString);
}
else
{
if (pKeyPath != KeyPath && pKeyPath)
{
delete [] pKeyPath;
}
pKeyPath = new TCHAR[1 + FIXED_SIZE + pLinkString->Size];
if (pKeyPath)
{
_stprintf(pKeyPath,_T("System\\CurrentControlSet\\Services\\%s\\Performance"),pLinkString->pString);
}
else
{
hRes = WBEM_E_OUT_OF_MEMORY;
break;
}
}
LONG lRes;
HKEY hKey;
lRes = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
pKeyPath,
NULL,KEY_READ,
&hKey);
if (ERROR_SUCCESS == lRes)
{
DWORD nSize = _tcslen(pKeyPath);
LinkString * pLinkString2 = (LinkString *)new BYTE[sizeof(LinkString) + nSize*sizeof(TCHAR)];
if (pLinkString2)
{
pLinkString2->Size = nSize;
_tcscpy(pLinkString2->pString,pKeyPath);
InsertTailList(pListHead,&pLinkString2->Entry);
}
else
{
lRes = ERROR_OUTOFMEMORY;
}
RegCloseKey(hKey);
}
}
for (pEntry = LocalListHead.Flink;
pEntry != &LocalListHead;
pEntry = pEntry->Flink)
{
BYTE * pByte = (BYTE *)pEntry;
RemoveEntryList(pEntry);
pEntry = pEntry->Flink;
delete [] pByte;
};
if (pKeyPath != KeyPath)
{
delete [] pKeyPath;
}
return hRes;
}
//
//
// Known Service implementation
//
///////////////////////////////////////////////////////////
bool
WCmp::operator()(WString pFirst,WString pSec) const
{
if (!pFirst || !pSec)
return false;
int res = _wcsicmp(pFirst,pSec);
return (res<0);
}
CSvcs::CSvcs():
m_cRef(1)
{
}
CSvcs::~CSvcs()
{
}
DWORD
CSvcs::Add(WCHAR * pService)
{
if (pService)
{
try
{
MapSvc::iterator it = m_SetServices.find(pService);
if (it == m_SetServices.end()) // not in the std::map
{
m_SetServices[pService] = true; // add to the map
}
return 0;
}
catch (CX_MemoryException)
{
return ERROR_OUTOFMEMORY;
}
}
else
return ERROR_INVALID_PARAMETER;
}
BOOL
CSvcs::Find(WCHAR * pService)
{
if (pService)
{
MapSvc::iterator it = m_SetServices.find(pService);
if (it != m_SetServices.end())
{
return TRUE;
}
}
return FALSE;
}
DWORD
CSvcs::Load()
{
// get the MULTI_SZ key
LONG lRet;
HKEY hKey;
lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
WBEM_REG_WINMGMT,
NULL,
KEY_READ,
&hKey);
if (ERROR_SUCCESS == lRet)
{
DWORD dwSize = 0;
DWORD dwType = REG_MULTI_SZ;
lRet = RegQueryValueEx(hKey,
KNOWN_SERVICES,
NULL,
&dwType,
NULL,
&dwSize);
if (ERROR_SUCCESS == lRet && (dwSize > 0))
{
TCHAR * pStr = new TCHAR[dwSize];
if (pStr)
{
CDeleteMe<TCHAR> cdm(pStr);
lRet = RegQueryValueEx(hKey,
KNOWN_SERVICES,
NULL,
&dwType,
(BYTE *)pStr,
&dwSize);
if ((ERROR_SUCCESS == lRet) &&
(REG_MULTI_SZ == dwType))
{
DWORD dwLen = 0;
while(dwLen = lstrlen(pStr))
{
try
{
m_SetServices[pStr] = true;
}
catch (CX_MemoryException)
{
lRet = ERROR_OUTOFMEMORY;
break;
}
pStr += (dwLen+1);
}
}
}
else
{
lRet = ERROR_OUTOFMEMORY;
}
}
RegCloseKey(hKey);
}
return lRet;
}
// already in winmgmt.h
/*
#define FULL_DREDGE 2
#define PARTIAL_DREDGE 1
#define NO_DREDGE 0
*/
//
//
// DeltaDredge
//
// both params are unused
// operation
// reads a registry key containing the known Services
// enumerates the registry keys, and figure-out which ones
// are the one with "performance" subkey
//
///////////////////////////////////////////////////////////
DWORD WINAPI
DeltaDredge(DWORD dwNumServicesArgs,
LPWSTR *lpServiceArgVectors)
{
DWORD bDredge = NO_DREDGE;
CSvcs KnownSvc;
if (ERROR_SUCCESS == KnownSvc.Load())
{
LIST_ENTRY ListServices;
InitializeListHead(&ListServices);
HRESULT hRes;
hRes = GetListOfSvcs(&ListServices);
if (SUCCEEDED(hRes))
{
hRes = GetSvcWithPerf(&ListServices);
if (SUCCEEDED(hRes))
{
DWORD Status = 0;
try
{
CSvcs OKServices; // this constructor throws
LIST_ENTRY * pListEntry;
DWORD i=0;
for (pListEntry = ListServices.Flink;
pListEntry != &ListServices;
pListEntry = pListEntry->Flink)
{
LinkString * pLString = (LinkString *)pListEntry;
CPerfLib PerfLib(pLString->pString);
if (!PerfLib.IsOK())
{
continue;
}
int PerfStatus = PerfLib.VerifyLoadable();
#ifdef DEBUG_ADAP
DBG_PRINTFA((pBuff,"%d Service %S status %d\n",i,pLString->pString,PerfStatus));
#endif
switch (PerfStatus)
{
case CPerfLib::Perf_Invalid:
case CPerfLib::Perf_Disabled:
//
// nothing to do with an invalid library
// or with a disabled library
//
#ifdef DEBUG_ADAP
DBG_PRINTFA((pBuff,"Invalid or Disabled Service %S\n",PerfLib.GetServiceName()));
#endif
DEBUGTRACE((LOG_WMIADAP,"Invalid registration or Disabled Service %S\n",PerfLib.GetServiceName()));
break;
case CPerfLib::Perf_NotChanged:
//
// this is what we want to hear
//
OKServices.Add(PerfLib.GetServiceName());
break;
case CPerfLib::Perf_SeemsNew:
//
// now we have to do a dredge
//
#ifdef DEBUG_ADAP
DBG_PRINTFA((pBuff,"NewOrChanged Service %S\n",PerfLib.GetServiceName()));
#endif
DEBUGTRACE((LOG_WMIADAP,"NewOrChanged Service %S\n",PerfLib.GetServiceName()));
bDredge = PARTIAL_DREDGE;
break;
default:
//
// never here
//
break;
}
i++;
}
if (NO_DREDGE == bDredge)
{
//
// if here, someone might have changed the registry directly
//
if (OKServices.GetMap().size() != KnownSvc.GetMap().size())
{
#ifdef DEBUG_ADAP
DBG_PRINTFA((pBuff,"Registry-listed Services and KnownSvcs are not of the same size\n"));
#endif
ERRORTRACE((LOG_WMIADAP,"Registry-listed Services and KnownSvcs are not of the same size\n"));
bDredge = PARTIAL_DREDGE;
}
else // same size -> are they the same ?
{
MapSvc::iterator it1 = OKServices.GetMap().begin();
MapSvc::iterator it2 = KnownSvc.GetMap().begin();
while (it1 != OKServices.GetMap().end())
{
#ifdef DEBUG_ADAP
DBG_PRINTFA((pBuff," %S =?= %S \n",(const WCHAR *)(*it1).first,(const WCHAR *)(*it2).first));
#endif
if (0 != _wcsicmp((*it1).first,(*it2).first))
{
bDredge = PARTIAL_DREDGE;
break;
}
++it1;
++it2;
}
}
}
}
catch (CX_MemoryException & )
{
bDredge = PARTIAL_DREDGE;
}
}
}
LIST_ENTRY * pListEntry;
for (pListEntry = ListServices.Flink;
pListEntry != &ListServices;
)
{
BYTE * pByte = (BYTE *)pListEntry;
RemoveEntryList(pListEntry);
pListEntry = pListEntry->Flink;
delete [] pByte;
}
}
else
{
//
// There is no valid KNOWN_SERVICES key --- FULL Dredge
//
bDredge = FULL_DREDGE;
}
return bDredge;
}
DWORD WINAPI
DeltaDredge2(DWORD dwNumServicesArgs,
LPWSTR *lpServiceArgVectors)
{
DWORD bDredge = FULL_DREDGE;
// check the MULTI_SZ key
LONG lRet;
HKEY hKey;
lRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
WBEM_REG_WINMGMT,
NULL,
KEY_READ,
&hKey);
if (ERROR_SUCCESS == lRet)
{
DWORD dwSize = 0;
DWORD dwType = REG_MULTI_SZ;
lRet = RegQueryValueEx(hKey,
KNOWN_SERVICES,
NULL,
&dwType,
NULL,
&dwSize);
if (ERROR_SUCCESS == lRet && (dwSize > 2)) // empty MULTI_SZ is 2 bytes
{
bDredge = NO_DREDGE;
}
RegCloseKey(hKey);
}
return bDredge;
}