windows-nt/Source/XPSP1/NT/sdktools/pdh/pdhui/wildcard.c
2020-09-26 16:20:57 +08:00

1027 lines
38 KiB
C

/*++
Copyright (C) 1995-1999 Microsoft Corporation
Module Name:
wildcard.c
Abstract:
counter name wild card expansion functions
--*/
#include <windows.h>
#include <winperf.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <tchar.h>
#include "mbctype.h"
#include "pdhidef.h"
#include "pdhdlgs.h"
#include "pdh.h"
#include "pdhui.h"
#include "perftype.h"
#include "perfdata.h"
#pragma warning ( disable : 4213)
#define PDHI_COUNTER_PATH_BUFFER_SIZE (DWORD)(sizeof(PDHI_COUNTER_PATH) + (5 * MAX_PATH))
DWORD DataSourceTypeA(LPCSTR szDataSource);
DWORD DataSourceTypeW(LPCWSTR szDataSource);
STATIC_BOOL
WildStringMatchW (
LPWSTR szWildString,
LPWSTR szMatchString
)
{
BOOL bReturn;
if (szWildString == NULL) {
// every thing matches a null wild card string
bReturn = TRUE;
} else if (*szWildString == SPLAT_L) {
// every thing matches this
bReturn = TRUE;
} else {
// for now just do a case insensitive comparison.
// later, this can be made more selective to support
// partial wildcard string matches
bReturn = (BOOL)(lstrcmpiW(szWildString, szMatchString) == 0);
}
return bReturn;
}
STATIC_PDH_FUNCTION
PdhiExpandWildcardPath (
IN HLOG hDataSource,
IN LPCWSTR szWildCardPath,
IN LPVOID pExpandedPathList,
IN LPDWORD pcchPathListLength,
IN DWORD dwFlags,
IN BOOL bUnicode
)
/*
Flags:
NoExpandCounters
NoExpandInstances
CheckCostlyCounters
*/
{
PDH_COUNTER_PATH_ELEMENTS_W pPathElem;
PPDHI_COUNTER_PATH pWildCounterPath = NULL;
PDH_STATUS pdhStatus = ERROR_SUCCESS;
DWORD dwDetailLevel = PERF_DETAIL_WIZARD;
DWORD dwBufferRemaining = 0;
LPVOID szNextUserString = NULL;
DWORD dwSize;
DWORD dwSizeReturned = 0;
DWORD dwRetry;
LPWSTR mszObjectList = NULL;
DWORD dwObjectListSize = 0;
LPWSTR szThisObject;
LPWSTR mszCounterList = NULL;
DWORD dwCounterListSize = 0;
LPWSTR szThisCounter;
LPWSTR mszInstanceList = NULL;
DWORD dwInstanceListSize = 0;
LPWSTR szThisInstance;
WCHAR szTempPathBuffer[MAX_PATH * 2];
DWORD szTempPathBufferSize;
BOOL bMoreData = FALSE;
BOOL bNoInstances = FALSE;\
LIST_ENTRY InstList;
PLIST_ENTRY pHead;
PLIST_ENTRY pNext;
PPDHI_INSTANCE pInst;
// allocate buffers
pWildCounterPath = G_ALLOC (PDHI_COUNTER_PATH_BUFFER_SIZE);
if (pWildCounterPath == NULL) {
// unable to allocate memory so bail out
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
} else {
__try {
dwBufferRemaining = *pcchPathListLength;
szNextUserString = pExpandedPathList;
} __except (EXCEPTION_EXECUTE_HANDLER) {
pdhStatus = PDH_INVALID_ARGUMENT;
}
}
if (pdhStatus == ERROR_SUCCESS) {
// Parse wild card Path
dwSize = (DWORD)G_SIZE (pWildCounterPath);
if (ParseFullPathNameW (szWildCardPath, &dwSize, pWildCounterPath, FALSE)) {
if (pWildCounterPath->szObjectName == NULL) {
pdhStatus = PDH_INVALID_PATH;
} else if (*pWildCounterPath->szObjectName == SPLAT_L) {
//then the object is wild so get the list
// of objects supported by this machine
dwObjectListSize = 2048; // starting buffer size
dwRetry = 10;
do {
if (mszObjectList != NULL) G_FREE(mszObjectList);
mszObjectList = G_ALLOC (dwObjectListSize * sizeof(WCHAR));
if (mszObjectList != NULL) {
pdhStatus = PdhEnumObjectsHW (
hDataSource,
pWildCounterPath->szMachineName,
mszObjectList,
&dwObjectListSize,
dwDetailLevel,
TRUE);
dwRetry--;
} else {
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
}
} while ( (dwRetry)
&& ( pdhStatus == PDH_MORE_DATA
|| pdhStatus == PDH_INSUFFICIENT_BUFFER));
} else {
dwObjectListSize = lstrlenW(pWildCounterPath->szObjectName) + 2;
mszObjectList = G_ALLOC(dwObjectListSize * sizeof (WCHAR));
if (mszObjectList != NULL) {
lstrcpyW (mszObjectList, pWildCounterPath->szObjectName);
// add the MSZ terminator
mszObjectList[dwObjectListSize-1] = 0;
pdhStatus = ERROR_SUCCESS;
} else {
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
}
}
} else {
pdhStatus = PDH_INVALID_PATH;
}
}
if (pdhStatus == ERROR_SUCCESS) {
pPathElem.szMachineName = pWildCounterPath->szMachineName;
// for each object
for (szThisObject = mszObjectList;
*szThisObject != 0;
szThisObject += lstrlenW(szThisObject) + 1) {
dwCounterListSize = 8192; // starting buffer size
dwInstanceListSize = 16384; // starting buffer size
dwRetry = 10;
do {
if (mszCounterList != NULL) G_FREE(mszCounterList);
if (mszInstanceList != NULL) G_FREE(mszInstanceList);
mszCounterList = G_ALLOC ((dwCounterListSize * sizeof(WCHAR)));
if (mszCounterList != NULL) {
mszInstanceList = G_ALLOC (dwInstanceListSize * sizeof(WCHAR));
if (mszInstanceList != NULL) {
pdhStatus = PdhEnumObjectItemsHW (
hDataSource,
pWildCounterPath->szMachineName,
szThisObject,
mszCounterList,
&dwCounterListSize,
mszInstanceList,
&dwInstanceListSize,
dwDetailLevel,
0);
dwRetry--;
} else {
G_FREE (mszCounterList);
mszCounterList = NULL;
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
}
} else {
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
}
} while ( (dwRetry)
&& ( pdhStatus == PDH_MORE_DATA
|| pdhStatus == PDH_INSUFFICIENT_BUFFER));
pPathElem.szObjectName = szThisObject;
if (pdhStatus == ERROR_SUCCESS) {
if (pWildCounterPath->szCounterName == NULL) {
pdhStatus = PDH_INVALID_PATH;
} else if ((*pWildCounterPath->szCounterName != SPLAT_L) || (dwFlags & PDH_NOEXPANDCOUNTERS)) {
if (mszCounterList != NULL) G_FREE(mszCounterList);
dwCounterListSize = lstrlenW(pWildCounterPath->szCounterName) + 2;
mszCounterList = G_ALLOC (dwCounterListSize * sizeof(WCHAR));
if (mszCounterList != NULL) {
lstrcpyW (mszCounterList, pWildCounterPath->szCounterName);
mszCounterList[dwCounterListSize-1] = 0;
} else {
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
}
} else {
// enum wild counters
}
if ((pWildCounterPath->szInstanceName == NULL) && (pdhStatus == ERROR_SUCCESS)){
bNoInstances = TRUE;
dwInstanceListSize = 2;
mszInstanceList = G_ALLOC (dwInstanceListSize * sizeof(WCHAR));
if (mszInstanceList != NULL) {
mszInstanceList [0] =0;
mszInstanceList [dwInstanceListSize-1] = 0;
} else {
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
}
} else if ((*pWildCounterPath->szInstanceName != SPLAT_L) || (dwFlags & PDH_NOEXPANDINSTANCES)) {
if (mszInstanceList != NULL) G_FREE(mszInstanceList);
dwInstanceListSize = lstrlenW(pWildCounterPath->szInstanceName) + 2;
mszInstanceList = G_ALLOC (dwInstanceListSize * sizeof(WCHAR));
if (mszInstanceList != NULL) {
lstrcpyW (mszInstanceList, pWildCounterPath->szInstanceName);
mszInstanceList [dwInstanceListSize-1] = 0;
} else {
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
}
} else {
// enum wild instance
}
}
if (mszInstanceList != NULL) {
InitializeListHead(& InstList);
szThisInstance = mszInstanceList;
do {
PdhiFindInstance(& InstList, szThisInstance, TRUE, &pInst);
szThisInstance += lstrlenW(szThisInstance) + 1;
} while (* szThisInstance != 0);
szThisInstance = mszInstanceList;
do {
if (bNoInstances) {
pPathElem.szInstanceName = NULL;
} else {
pPathElem.szInstanceName = szThisInstance;
}
pPathElem.szParentInstance = NULL; // included in the instance name
pInst = NULL;
PdhiFindInstance(
& InstList, szThisInstance, FALSE, & pInst);
if (pInst == NULL || pInst->dwTotal == 1
|| pInst->dwCount <= 1) {
pPathElem.dwInstanceIndex = (DWORD) -1; // included in the instance name
}
else {
pInst->dwCount --;
pPathElem.dwInstanceIndex = pInst->dwCount;
}
for (szThisCounter = mszCounterList;
*szThisCounter != 0;
szThisCounter += lstrlenW(szThisCounter) +1) {
pPathElem.szCounterName = szThisCounter;
//make path string and add to list if it will fit
szTempPathBufferSize = sizeof (szTempPathBuffer) / sizeof (szTempPathBuffer[0]);
pdhStatus = PdhMakeCounterPathW (
&pPathElem,
szTempPathBuffer,
&szTempPathBufferSize,
0);
if (pdhStatus == ERROR_SUCCESS) {
// add the string if it will fit
if (bUnicode) {
dwSize = lstrlenW((LPWSTR) szTempPathBuffer) + 1;
if (!bMoreData && (dwSize <= dwBufferRemaining)) {
lstrcpyW ((LPWSTR)szNextUserString, szTempPathBuffer);
(LPBYTE) szNextUserString += dwSize * sizeof(WCHAR);
dwBufferRemaining -= dwSize;
}
else {
dwBufferRemaining = 0;
bMoreData = TRUE;
}
}
else {
dwSize = dwBufferRemaining;
if (PdhiConvertUnicodeToAnsi(_getmbcp(),
szTempPathBuffer,
szNextUserString,
& dwSize) == ERROR_SUCCESS) {
(LPBYTE)szNextUserString += dwSize * sizeof(CHAR);
dwBufferRemaining -= dwSize;
}
else {
dwBufferRemaining = 0;
bMoreData = TRUE;
}
}
dwSizeReturned += dwSize;
} // end if path created OK
} // end for each counter
szThisInstance += lstrlenW(szThisInstance) +1;
} while (*szThisInstance != 0);
if (! IsListEmpty(& InstList)) {
pHead = & InstList;
pNext = pHead->Flink;
while (pNext != pHead) {
pInst = CONTAINING_RECORD(pNext, PDHI_INSTANCE, Entry);
pNext = pNext->Flink;
RemoveEntryList(& pInst->Entry);
G_FREE(pInst);
}
}
} // else no instances to do
} // end for each object found
} // end if object enumeration successful
if ((dwSizeReturned > 0) && (dwBufferRemaining >= 1)) {
dwSize = 1;
if (szNextUserString) {
if (bUnicode) {
* (LPWSTR) szNextUserString = 0;
(LPBYTE) szNextUserString += dwSize * sizeof(WCHAR);
} else {
* (LPSTR) szNextUserString = 0;
(LPBYTE) szNextUserString += dwSize * sizeof(CHAR);
}
}
dwSizeReturned += dwSize;
dwBufferRemaining -= dwSize;
}
*pcchPathListLength = dwSizeReturned;
if (mszCounterList != NULL) G_FREE(mszCounterList);
if (mszInstanceList != NULL) G_FREE(mszInstanceList);
if (mszObjectList != NULL) G_FREE(mszObjectList);
if (pWildCounterPath != NULL) G_FREE(pWildCounterPath);
if (bMoreData) pdhStatus = PDH_MORE_DATA;
return (pdhStatus);
}
STATIC_PDH_FUNCTION
PdhiExpandCounterPath (
IN LPCWSTR szWildCardPath,
IN LPVOID pExpandedPathList,
IN LPDWORD pcchPathListLength,
IN BOOL bUnicode
)
{
PPERF_MACHINE pMachine;
PPDHI_COUNTER_PATH pWildCounterPath = NULL;
WCHAR szWorkBuffer[MAX_PATH];
WCHAR szCounterName[MAX_PATH];
WCHAR szInstanceName[MAX_PATH];
LPWSTR szEndOfObjectString;
LPWSTR szInstanceString;
LPWSTR szCounterString;
LPVOID szNextUserString = NULL;
PERF_OBJECT_TYPE *pObjectDef;
PERF_OBJECT_TYPE *pParentObjectDef;
PERF_COUNTER_DEFINITION *pCounterDef;
PERF_INSTANCE_DEFINITION *pInstanceDef;
PERF_INSTANCE_DEFINITION *pParentInstanceDef;
DWORD dwLocalPathLength = 0;
DWORD dwBufferRemaining = 0;
DWORD dwSize;
DWORD dwSizeReturned = 0;
PDH_STATUS pdhStatus = ERROR_SUCCESS;
DWORD dwCtrNdx, dwInstNdx;
BOOL bMoreData = FALSE;
if ((szWildCardPath == NULL) ||
(pExpandedPathList == NULL) ||
(pcchPathListLength == NULL)) {
pdhStatus = PDH_INVALID_ARGUMENT;
} else {
// allocate buffers
pWildCounterPath = G_ALLOC (PDHI_COUNTER_PATH_BUFFER_SIZE);
if (pWildCounterPath == NULL) {
// unable to allocate memory so bail out
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
} else {
__try {
dwLocalPathLength = *pcchPathListLength;
dwBufferRemaining = dwLocalPathLength;
szNextUserString = pExpandedPathList;
} __except (EXCEPTION_EXECUTE_HANDLER) {
pdhStatus = PDH_INVALID_ARGUMENT;
}
}
}
if (pdhStatus == ERROR_SUCCESS) {
pdhStatus = WAIT_FOR_AND_LOCK_MUTEX (hPdhDataMutex);
}
if (pdhStatus == ERROR_SUCCESS) {
// Parse wild card Path
dwSize = (DWORD)G_SIZE (pWildCounterPath);
if (ParseFullPathNameW (szWildCardPath, &dwSize, pWildCounterPath, FALSE)) {
// get the machine referenced in the path
pMachine = GetMachine (pWildCounterPath->szMachineName, 0);
if (pMachine != NULL) {
if (wcsncmp (cszDoubleBackSlash, szWildCardPath, 2) == 0) {
// the caller wants the machine name in the path so
// copy it to the work buffer
lstrcpyW (szWorkBuffer, pWildCounterPath->szMachineName);
} else {
*szWorkBuffer = 0;
}
// append the object name (since wild card objects are not
// currently supported.
lstrcatW (szWorkBuffer, cszBackSlash);
lstrcatW (szWorkBuffer, pWildCounterPath->szObjectName);
szEndOfObjectString = &szWorkBuffer[lstrlenW(szWorkBuffer)];
if (pMachine->dwStatus == ERROR_SUCCESS) {
// get object pointer (since objects are not wild)
pObjectDef = GetObjectDefByName (
pMachine->pSystemPerfData,
pMachine->dwLastPerfString,
pMachine->szPerfStrings,
pWildCounterPath->szObjectName);
} else {
pObjectDef = NULL;
}
if (pObjectDef != NULL) {
// for each counters and identify matches
pCounterDef = FirstCounter (pObjectDef);
for (dwCtrNdx = 0; dwCtrNdx < pObjectDef->NumCounters; dwCtrNdx++) {
// for each counter check instances (if supported)
// and keep matches
if ((pCounterDef->CounterNameTitleIndex > 0) &&
(pCounterDef->CounterNameTitleIndex < pMachine->dwLastPerfString ) &&
(!((pCounterDef->CounterType & PERF_DISPLAY_NOSHOW) &&
// this is a hack because this type is not defined correctly
(pCounterDef->CounterType != PERF_AVERAGE_BULK)))) {
// look up name of each object & store size
lstrcpyW (szCounterName,
PdhiLookupPerfNameByIndex (
pMachine,
pCounterDef->CounterNameTitleIndex));
if (WildStringMatchW(pWildCounterPath->szCounterName, szCounterName)) {
// if this object has instances, then walk down
// the instance list and save any matches
if (pObjectDef->NumInstances != PERF_NO_INSTANCES) {
// then walk instances to find matches
pInstanceDef = FirstInstance (pObjectDef);
if (pObjectDef->NumInstances > 0) {
for (dwInstNdx = 0;
dwInstNdx < (DWORD)pObjectDef->NumInstances;
dwInstNdx++) {
szInstanceString = szEndOfObjectString;
if (pInstanceDef->ParentObjectTitleIndex > 0) {
// then add in parent instance name
pParentObjectDef = GetObjectDefByTitleIndex (
pMachine->pSystemPerfData,
pInstanceDef->ParentObjectTitleIndex);
if (pParentObjectDef != NULL) {
pParentInstanceDef = GetInstance (
pParentObjectDef,
pInstanceDef->ParentObjectInstance);
if (pParentInstanceDef != NULL) {
GetInstanceNameStr (pParentInstanceDef,
szInstanceName,
pObjectDef->CodePage);
if (WildStringMatchW (pWildCounterPath->szParentName, szInstanceName)) {
// add this string
szInstanceString = szEndOfObjectString;
lstrcpyW (szInstanceString, cszLeftParen);
lstrcatW (szInstanceString, szInstanceName);
lstrcatW (szInstanceString, cszSlash);
} else {
// get next instance and continue
pInstanceDef = NextInstance(pInstanceDef);
continue;
}
} else {
// unable to locate parent instance
// so cancel this one, then
// get next instance and continue
pInstanceDef = NextInstance(pInstanceDef);
continue;
}
} else {
// unable to locate parent object
// so cancel this one, then
// get next instance and continue
pInstanceDef = NextInstance(pInstanceDef);
continue;
}
} else {
// no parent name so continue
szInstanceString = szEndOfObjectString;
lstrcpyW (szInstanceString, cszLeftParen);
}
GetInstanceNameStr (pInstanceDef,
szInstanceName,
pObjectDef->CodePage);
// if this instance name matches, then keep it
if (WildStringMatchW (pWildCounterPath->szInstanceName, szInstanceName)) {
lstrcatW (szInstanceString, szInstanceName);
lstrcatW (szInstanceString, cszRightParenBackSlash);
// now append this counter name
lstrcatW (szInstanceString, szCounterName);
// add it to the user's buffer if there's room
if (bUnicode) {
dwSize = lstrlenW(szWorkBuffer) + 1;
if (!bMoreData && (dwSize <= dwBufferRemaining)) {
lstrcpyW ((LPWSTR)szNextUserString, szWorkBuffer);
(LPBYTE)szNextUserString += dwSize * sizeof(WCHAR);
}
else {
bMoreData = TRUE;
}
} else {
dwSize = dwBufferRemaining;
if (PdhiConvertUnicodeToAnsi(_getmbcp(),
szWorkBuffer, szNextUserString, & dwSize)
== ERROR_SUCCESS) {
(LPBYTE)szNextUserString += dwSize * sizeof(CHAR);
}
else {
bMoreData = TRUE;
}
}
dwSizeReturned += dwSize;
if (! bMoreData) {
dwBufferRemaining -= dwSize;
}
} else {
// they don't want this instance so skip it
}
pInstanceDef = NextInstance (pInstanceDef);
} // end for each instance in object
} else {
// this object supports instances,
// but doesn't currently have any
// so do nothing.
}
} else {
// this object does not use instances so copy this
// counter to the caller's buffer.
szCounterString = szEndOfObjectString;
lstrcpyW (szCounterString, cszBackSlash);
lstrcatW (szCounterString, szCounterName);
if (bUnicode) {
dwSize = lstrlenW(szWorkBuffer) + 1;
if (!bMoreData && (dwSize < dwBufferRemaining)) {
lstrcpyW ((LPWSTR)szNextUserString, szWorkBuffer);
(LPBYTE)szNextUserString += dwSize * sizeof(WCHAR);
}
else {
bMoreData = TRUE;
}
} else {
dwSize = dwBufferRemaining;
if (PdhiConvertUnicodeToAnsi(_getmbcp(),
szWorkBuffer, szNextUserString, & dwSize)
== ERROR_SUCCESS) {
(LPBYTE)szNextUserString += dwSize * sizeof(CHAR);
}
else {
bMoreData = TRUE;
}
}
dwSizeReturned += dwSize;
if (! bMoreData) {
dwBufferRemaining -= dwSize;
}
}
} else {
// this counter doesn't match so skip it
}
} else {
// this counter string is not available
}
pCounterDef = NextCounter(pCounterDef);
} // end for each counter in this object
if (bUnicode) {
*(LPWSTR)szNextUserString = 0; // MSZ terminator
} else {
*(LPSTR)szNextUserString = 0; // MSZ terminator
}
dwLocalPathLength = dwSizeReturned;
if (bMoreData) {
pdhStatus = PDH_MORE_DATA;
} else {
pdhStatus = ERROR_SUCCESS;
}
} else {
// unable to find object
pdhStatus = PDH_INVALID_PATH;
}
pMachine->dwRefCount--;
RELEASE_MUTEX (pMachine->hMutex);
} else {
// unable to connect to machine.
pdhStatus = GetLastError();
}
} else {
// unable to read input path string
pdhStatus = PDH_INVALID_PATH;
}
RELEASE_MUTEX (hPdhDataMutex);
__try {
*pcchPathListLength = dwLocalPathLength;
} __except (EXCEPTION_EXECUTE_HANDLER) {
pdhStatus = PDH_INVALID_ARGUMENT;
}
}
if (pWildCounterPath != NULL) G_FREE (pWildCounterPath);
return pdhStatus;
}
PDH_FUNCTION
PdhExpandCounterPathW (
IN LPCWSTR szWildCardPath,
IN LPWSTR mszExpandedPathList,
IN LPDWORD pcchPathListLength
)
/*++
Expands any wild card characters in the following fields of the
counter path string in the szWildCardPath argument and returns the
matching counter paths in the buffer referenced by the
mszExpandedPathList argument
The input path is defined as one of the following formats:
\\machine\object(parent/instance#index)\counter
\\machine\object(parent/instance)\counter
\\machine\object(instance#index)\counter
\\machine\object(instance)\counter
\\machine\object\counter
\object(parent/instance#index)\counter
\object(parent/instance)\counter
\object(instance#index)\counter
\object(instance)\counter
\object\counter
Input paths that include the machine will be expanded to also
include the machine and use the specified machine to resolve the
wild card matches. Input paths that do not contain a machine name
will use the local machine to resolve wild card matches.
The following fields may contain either a valid name or a wild card
character ("*"). Partial string matches (e.g. "pro*") are not
supported.
parent returns all instances of the specified object that
match the other specified fields
instance returns all instances of the specified object and
parent object if specified
index returns all duplicate matching instance names
counter returns all counters of the specified object
--*/
{
return PdhiExpandCounterPath (
szWildCardPath,
(LPVOID)mszExpandedPathList,
pcchPathListLength,
TRUE);
}
PDH_FUNCTION
PdhExpandCounterPathA (
IN LPCSTR szWildCardPath,
IN LPSTR mszExpandedPathList,
IN LPDWORD pcchPathListLength
)
{
LPWSTR szWideWildCardPath = NULL;
DWORD dwSize;
PDH_STATUS pdhStatus = ERROR_SUCCESS;
DWORD dwLocalListSize = 0;
if ((szWildCardPath == NULL) || (pcchPathListLength == NULL)) {
pdhStatus = PDH_INVALID_ARGUMENT;
}
else if (* szWildCardPath == '\0') {
pdhStatus = PDH_INVALID_ARGUMENT;
} else {
__try {
dwLocalListSize = *pcchPathListLength;
dwSize = lstrlenA (szWildCardPath);
szWideWildCardPath = G_ALLOC (((dwSize+1) * sizeof (WCHAR)));
if (szWideWildCardPath == NULL) {
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
} else {
MultiByteToWideChar(_getmbcp(),
0,
szWildCardPath,
dwSize,
(LPWSTR) szWideWildCardPath,
dwSize + 1);
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
pdhStatus = PDH_INVALID_ARGUMENT;
}
}
if (pdhStatus == ERROR_SUCCESS && szWideWildCardPath != NULL) {
pdhStatus = PdhiExpandCounterPath (
szWideWildCardPath,
(LPVOID)mszExpandedPathList,
&dwLocalListSize,
FALSE);
__try {
* pcchPathListLength = dwLocalListSize;
} __except (EXCEPTION_EXECUTE_HANDLER) {
pdhStatus = PDH_INVALID_ARGUMENT;
}
}
if (szWideWildCardPath != NULL) G_FREE (szWideWildCardPath);
return pdhStatus;
}
PDH_FUNCTION
PdhExpandWildCardPathHW (
IN HLOG hDataSource,
IN LPCWSTR szWildCardPath,
IN LPWSTR mszExpandedPathList,
IN LPDWORD pcchPathListLength,
IN DWORD dwFlags
)
{
PDH_STATUS pdhStatus = ERROR_SUCCESS;
DWORD dwLocalBufferSize;
if ((szWildCardPath == NULL) || (pcchPathListLength == NULL)) {
pdhStatus = PDH_INVALID_ARGUMENT;
}
else {
__try {
dwLocalBufferSize = * pcchPathListLength;
} __except (EXCEPTION_EXECUTE_HANDLER) {
pdhStatus = PDH_INVALID_ARGUMENT;
}
}
if (pdhStatus == ERROR_SUCCESS) {
pdhStatus = PdhiExpandWildcardPath (
hDataSource,
szWildCardPath,
(LPVOID) mszExpandedPathList,
& dwLocalBufferSize,
dwFlags,
TRUE);
__try {
* pcchPathListLength = dwLocalBufferSize;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
pdhStatus = PDH_INVALID_ARGUMENT;
}
}
return pdhStatus;
}
PDH_FUNCTION
PdhExpandWildCardPathW (
IN LPCWSTR szDataSource,
IN LPCWSTR szWildCardPath,
IN LPWSTR mszExpandedPathList,
IN LPDWORD pcchPathListLength,
IN DWORD dwFlags
)
/*++
Expands any wild card characters in the following fields of the
counter path string in the szWildCardPath argument and returns the
matching counter paths in the buffer referenced by the
mszExpandedPathList argument
The input path is defined as one of the following formats:
\\machine\object(parent/instance#index)\counter
\\machine\object(parent/instance)\counter
\\machine\object(instance#index)\counter
\\machine\object(instance)\counter
\\machine\object\counter
\object(parent/instance#index)\counter
\object(parent/instance)\counter
\object(instance#index)\counter
\object(instance)\counter
\object\counter
Input paths that include the machine will be expanded to also
include the machine and use the specified machine to resolve the
wild card matches. Input paths that do not contain a machine name
will use the local machine to resolve wild card matches.
The following fields may contain either a valid name or a wild card
character ("*"). Partial string matches (e.g. "pro*") are not
supported.
parent returns all instances of the specified object that
match the other specified fields
instance returns all instances of the specified object and
parent object if specified
index returns all duplicate matching instance names
counter returns all counters of the specified object
--*/
{
PDH_STATUS pdhStatus = ERROR_SUCCESS;
DWORD dwLocalBufferSize;
DWORD dwDataSource = 0;
HLOG hDataSource = H_REALTIME_DATASOURCE;
__try {
if (szDataSource != NULL) {
// test for read access to the name
if (* szDataSource == 0) {
pdhStatus = PDH_INVALID_ARGUMENT;
}
} // else NULL is a valid arg
if (pdhStatus == ERROR_SUCCESS) {
dwDataSource = DataSourceTypeW(szDataSource);
dwLocalBufferSize = * pcchPathListLength;
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
pdhStatus = PDH_INVALID_ARGUMENT;
}
if (pdhStatus == ERROR_SUCCESS) {
if (dwDataSource == DATA_SOURCE_WBEM) {
hDataSource = H_WBEM_DATASOURCE;
}
else if (dwDataSource == DATA_SOURCE_LOGFILE) {
DWORD dwLogType = 0;
pdhStatus = PdhOpenLogW(
szDataSource,
PDH_LOG_READ_ACCESS | PDH_LOG_OPEN_EXISTING,
& dwLogType,
NULL,
0,
NULL,
& hDataSource);
}
if (pdhStatus == ERROR_SUCCESS) {
pdhStatus = PdhExpandWildCardPathHW (
hDataSource,
szWildCardPath,
mszExpandedPathList,
pcchPathListLength,
dwFlags);
if (dwDataSource == DATA_SOURCE_LOGFILE) {
PdhCloseLog(hDataSource, 0);
}
}
}
return pdhStatus;
}
PDH_FUNCTION
PdhExpandWildCardPathHA (
IN HLOG hDataSource,
IN LPCSTR szWildCardPath,
IN LPSTR mszExpandedPathList,
IN LPDWORD pcchPathListLength,
IN DWORD dwFlags
)
{
LPWSTR szWideWildCardPath = NULL;
DWORD dwSize;
PDH_STATUS pdhStatus = ERROR_SUCCESS;
DWORD dwLocalBufferSize;
if ((szWildCardPath == NULL) || (pcchPathListLength == NULL)) {
pdhStatus = PDH_INVALID_ARGUMENT;
}
else if (* szWildCardPath == '\0') {
pdhStatus = PDH_INVALID_ARGUMENT;
}
else {
__try {
dwSize = lstrlenA(szWildCardPath);
szWideWildCardPath = G_ALLOC(((dwSize + 1) * sizeof(WCHAR)));
if (szWideWildCardPath == NULL) {
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
}
else {
MultiByteToWideChar(_getmbcp(),
0,
szWildCardPath,
dwSize,
(LPWSTR) szWideWildCardPath,
dwSize + 1);
}
dwLocalBufferSize = * pcchPathListLength;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
pdhStatus = PDH_INVALID_ARGUMENT;
}
}
if (pdhStatus == ERROR_SUCCESS) {
pdhStatus = PdhiExpandWildcardPath (
hDataSource,
szWideWildCardPath,
(LPVOID) mszExpandedPathList,
& dwLocalBufferSize,
dwFlags,
FALSE);
__try {
* pcchPathListLength = dwLocalBufferSize;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
pdhStatus = PDH_INVALID_ARGUMENT;
}
}
if (szWideWildCardPath != NULL) G_FREE(szWideWildCardPath);
return pdhStatus;
}
PDH_FUNCTION
PdhExpandWildCardPathA (
IN LPCSTR szDataSource,
IN LPCSTR szWildCardPath,
IN LPSTR mszExpandedPathList,
IN LPDWORD pcchPathListLength,
IN DWORD dwFlags
)
{
PDH_STATUS pdhStatus = ERROR_SUCCESS;
HLOG hDataSource = H_REALTIME_DATASOURCE;
DWORD dwDataSource = 0;
__try {
if (szDataSource != NULL) {
// test for read access to the name
if (* szDataSource == 0) {
pdhStatus = PDH_INVALID_ARGUMENT;
}
} // else NULL is a valid arg
if (pdhStatus == ERROR_SUCCESS) {
dwDataSource = DataSourceTypeA(szDataSource);
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {
pdhStatus = PDH_INVALID_ARGUMENT;
}
if (pdhStatus == ERROR_SUCCESS) {
if (dwDataSource == DATA_SOURCE_WBEM) {
hDataSource = H_WBEM_DATASOURCE;
}
else if (dwDataSource == DATA_SOURCE_LOGFILE) {
DWORD dwLogType = 0;
pdhStatus = PdhOpenLogA(
szDataSource,
PDH_LOG_READ_ACCESS | PDH_LOG_OPEN_EXISTING,
& dwLogType,
NULL,
0,
NULL,
& hDataSource);
}
if (pdhStatus == ERROR_SUCCESS) {
pdhStatus = PdhExpandWildCardPathHA (
hDataSource,
szWildCardPath,
mszExpandedPathList,
pcchPathListLength,
dwFlags);
if (dwDataSource == DATA_SOURCE_LOGFILE) {
PdhCloseLog(hDataSource, 0);
}
}
}
return pdhStatus;
}