Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

378 lines
15 KiB

/*++
Copyright (C) 1995 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 "pdhidef.h"
#include "pdhdlgs.h"
#include "pdh.h"
#define PDHI_COUNTER_PATH_BUFFER_SIZE (DWORD)(sizeof(PDHI_COUNTER_PATH) + (5 * MAX_PATH))
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_STATUS
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;
PERF_OBJECT_TYPE *pObjectDef;
PERF_OBJECT_TYPE *pParentObjectDef;
PERF_COUNTER_DEFINITION *pCounterDef;
PERF_INSTANCE_DEFINITION *pInstanceDef;
PERF_INSTANCE_DEFINITION *pParentInstanceDef;
DWORD dwBufferRemaining;
DWORD dwSize;
DWORD dwSizeReturned = 0;
PDH_STATUS pdhStatus = ERROR_SUCCESS;
DWORD dwCtrNdx, dwInstNdx;
BOOL bMoreData = FALSE;
// allocate buffers
pWildCounterPath = G_ALLOC (GPTR, 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 = G_SIZE (pWildCounterPath);
if (ParseFullPathNameW (szWildCardPath, &dwSize, pWildCounterPath)) {
// 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)];
// get object pointer (since objects are not wild)
pObjectDef = GetObjectDefByName (
pMachine->pSystemPerfData,
pMachine->dwLastPerfString,
pMachine->szPerfStrings,
pWildCounterPath->szObjectName);
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,
pMachine->szPerfStrings[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, cszSlash);
}
GetInstanceNameStr (pInstanceDef,
szInstanceName,
pObjectDef->CodePage);
//
// BUGBUG: need to do something with indexes.
//
// 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
dwSize = lstrlenW(szWorkBuffer) + 1;
if (!bMoreData && (dwSize < dwBufferRemaining)) {
if (bUnicode) {
lstrcpyW ((LPWSTR)szNextUserString, szWorkBuffer);
(LPBYTE)szNextUserString += dwSize * sizeof(WCHAR);
} else {
wcstombs ((LPSTR)szNextUserString, szWorkBuffer, dwSize);
(LPBYTE)szNextUserString += dwSize * sizeof(CHAR);
}
dwSizeReturned += dwSize;
dwBufferRemaining -= dwSize;
} else {
// they've run out of buffer so just update the size required
bMoreData = TRUE;
dwSizeReturned += 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);
dwSize = lstrlenW(szWorkBuffer) + 1;
if (!bMoreData && (dwSize < dwBufferRemaining)) {
if (bUnicode) {
lstrcpyW ((LPWSTR)szNextUserString, szWorkBuffer);
(LPBYTE)szNextUserString += dwSize * sizeof(WCHAR);
} else {
wcstombs ((LPSTR)szNextUserString, szWorkBuffer, dwSize);
(LPBYTE)szNextUserString += dwSize * sizeof(CHAR);
}
dwSizeReturned += dwSize;
dwBufferRemaining -= dwSize;
} else {
// they've run out of buffer so bail out of this loop
bMoreData = TRUE;
dwSizeReturned += 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
}
*pcchPathListLength = dwSizeReturned;
if (bMoreData) {
pdhStatus = PDH_MORE_DATA;
} else {
pdhStatus = ERROR_SUCCESS;
}
} else {
// unable to find object
pdhStatus = PDH_INVALID_PATH;
}
} else {
// unable to connect to machine.
pdhStatus = PDH_CANNOT_CONNECT_MACHINE;
}
} else {
// unable to read input path string
pdhStatus = PDH_INVALID_PATH;
}
}
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;
__try {
dwSize = lstrlenA (szWildCardPath);
szWideWildCardPath = G_ALLOC (GPTR, ((dwSize+1) * sizeof (WCHAR)));
if (szWideWildCardPath == NULL) {
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
} else {
mbstowcs (szWideWildCardPath, szWildCardPath, (dwSize+1));
pdhStatus = PdhiExpandCounterPath (
szWideWildCardPath,
(LPVOID)mszExpandedPathList,
pcchPathListLength,
FALSE);
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
pdhStatus = PDH_INVALID_ARGUMENT;
}
if (szWideWildCardPath != NULL) G_FREE (szWideWildCardPath);
return pdhStatus;
}