Leaked source code of windows server 2003
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.
 
 
 
 
 
 

774 lines
31 KiB

/*++
Copyright (C) 1995-1999 Microsoft Corporation
Module Name:
wildcard.c
Abstract:
counter name wild card expansion functions
--*/
#include <windows.h>
#include <winperf.h>
#include "mbctype.h"
#include "strsafe.h"
#include "pdh.h"
#include "pdhmsg.h"
#include "pdhidef.h"
#include "pdhdlgs.h"
#include "strings.h"
#include "perftype.h"
#include "perfdata.h"
#pragma warning ( disable : 4213)
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(
HLOG hDataSource,
LPCWSTR szWildCardPath,
LPVOID pExpandedPathList,
LPDWORD pcchPathListLength,
DWORD dwFlags,
BOOL bUnicode
)
/*
Flags:
NoExpandCounters
NoExpandInstances
CheckCostlyCounters
*/
{
PDH_COUNTER_PATH_ELEMENTS_W pPathElem;
PPDHI_COUNTER_PATH pWildCounterPath = NULL;
PDH_STATUS pdhStatus = ERROR_SUCCESS;
DWORD dwBufferRemaining = 0;
LPVOID szNextUserString = NULL;
DWORD dwPathSize = 0;
DWORD dwSize = 0;
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;
LPWSTR szTempPathBuffer = NULL;
DWORD szTempPathBufferSize = SMALL_BUFFER_SIZE;
BOOL bMoreData = FALSE;
BOOL bNoInstances = FALSE;
DWORD dwSuccess = 0;
LIST_ENTRY InstList;
PLIST_ENTRY pHead;
PLIST_ENTRY pNext;
PPDHI_INSTANCE pInst;
PPERF_MACHINE pMachine = NULL;
dwPathSize = lstrlenW(szWildCardPath) + 1;
if (dwPathSize < MAX_PATH) dwPathSize = MAX_PATH;
dwSize = sizeof(PDHI_COUNTER_PATH) + 2 * dwPathSize * sizeof(WCHAR);
pWildCounterPath = G_ALLOC(dwSize);
szTempPathBufferSize = SMALL_BUFFER_SIZE;
szTempPathBuffer = G_ALLOC(szTempPathBufferSize * sizeof(WCHAR));
if (pWildCounterPath == NULL || szTempPathBuffer == 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
if (ParseFullPathNameW(szWildCardPath, & dwSize, pWildCounterPath, FALSE)) {
if (pWildCounterPath->szObjectName == NULL) {
pdhStatus = PDH_INVALID_PATH;
}
else if (* pWildCounterPath->szObjectName == SPLAT_L) {
BOOL bFirstTime = TRUE;
//then the object is wild so get the list
// of objects supported by this machine
dwObjectListSize = SMALL_BUFFER_SIZE; // starting buffer size
dwRetry = 10;
do {
G_FREE(mszObjectList);
mszObjectList = G_ALLOC(dwObjectListSize * sizeof(WCHAR));
if (mszObjectList != NULL) {
pdhStatus = PdhEnumObjectsHW(hDataSource,
pWildCounterPath->szMachineName,
mszObjectList,
& dwObjectListSize,
PERF_DETAIL_WIZARD,
bFirstTime);
if (bFirstTime) bFirstTime = FALSE;
dwRetry --;
}
else {
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
}
}
while (dwRetry && pdhStatus == PDH_MORE_DATA);
}
else {
if (hDataSource == H_REALTIME_DATASOURCE) {
DWORD dwObjectId;
pMachine = GetMachine(pWildCounterPath->szMachineName, 0, PDH_GM_UPDATE_PERFNAME_ONLY);
if (pMachine == NULL) {
pdhStatus = GetLastError();
}
else if (pMachine->dwStatus != ERROR_SUCCESS) {
pdhStatus = pMachine->dwStatus;
pMachine->dwRefCount --;
RELEASE_MUTEX(pMachine->hMutex);
}
else {
dwObjectId = GetObjectId(pMachine, pWildCounterPath->szObjectName, NULL);
pMachine->dwRefCount --;
RELEASE_MUTEX(pMachine->hMutex);
if (dwObjectId == (DWORD) -1) {
pdhStatus = PDH_CSTATUS_NO_OBJECT;
}
else {
DWORD dwGetMachineFlags = (dwFlags & PDH_REFRESHCOUNTERS) ? (PDH_GM_UPDATE_PERFDATA) : (0);
pMachine = GetMachine(pWildCounterPath->szMachineName, dwObjectId, dwGetMachineFlags);
if (pMachine != NULL) {
pMachine->dwRefCount --;
RELEASE_MUTEX(pMachine->hMutex);
}
}
}
}
if (pdhStatus == ERROR_SUCCESS) {
dwObjectListSize = lstrlenW(pWildCounterPath->szObjectName) + 2;
mszObjectList = G_ALLOC(dwObjectListSize * sizeof (WCHAR));
if (mszObjectList != NULL) {
StringCchCopyW(mszObjectList, dwObjectListSize, pWildCounterPath->szObjectName);
// add the MSZ terminator
mszObjectList[dwObjectListSize - 2] = L'\0';
mszObjectList[dwObjectListSize - 1] = L'\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 != L'\0';
szThisObject += (lstrlenW(szThisObject) + 1)) {
G_FREE(mszCounterList);
G_FREE(mszInstanceList);
mszCounterList = NULL;
mszInstanceList = NULL;
dwCounterListSize = MEDIUM_BUFFER_SIZE; // starting buffer size
dwInstanceListSize = MEDIUM_BUFFER_SIZE; // starting buffer size
dwRetry = 10;
do {
G_FREE(mszCounterList);
G_FREE(mszInstanceList);
mszCounterList = G_ALLOC(dwCounterListSize * sizeof(WCHAR));
mszInstanceList = G_ALLOC(dwInstanceListSize * sizeof(WCHAR));
if (mszCounterList != NULL && mszInstanceList != NULL) {
pdhStatus = PdhEnumObjectItemsHW(hDataSource,
pWildCounterPath->szMachineName,
szThisObject,
mszCounterList,
& dwCounterListSize,
mszInstanceList,
& dwInstanceListSize,
PERF_DETAIL_WIZARD,
0);
dwRetry--;
}
else {
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
}
}
while (dwRetry && pdhStatus == PDH_MORE_DATA);
pPathElem.szObjectName = szThisObject;
if (pdhStatus == ERROR_SUCCESS) {
if (pWildCounterPath->szCounterName == NULL) {
pdhStatus = PDH_INVALID_PATH;
}
else if ((* pWildCounterPath->szCounterName != SPLAT_L) || (dwFlags & PDH_NOEXPANDCOUNTERS)) {
G_FREE(mszCounterList);
dwCounterListSize = lstrlenW(pWildCounterPath->szCounterName) + 2;
mszCounterList = G_ALLOC(dwCounterListSize * sizeof(WCHAR));
if (mszCounterList != NULL) {
StringCchCopyW(mszCounterList, dwCounterListSize, pWildCounterPath->szCounterName);
mszCounterList[dwCounterListSize - 1] = L'\0';
}
else {
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
}
}
if ((pWildCounterPath->szInstanceName == NULL) && (pdhStatus == ERROR_SUCCESS)){
G_FREE(mszInstanceList);
bNoInstances = TRUE;
dwInstanceListSize = 2;
mszInstanceList = G_ALLOC(dwInstanceListSize * sizeof(WCHAR));
if (mszInstanceList != NULL) {
mszInstanceList[0] = mszInstanceList[1] = L'\0';
}
else {
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
}
}
else if ((* pWildCounterPath->szInstanceName != SPLAT_L) || (dwFlags & PDH_NOEXPANDINSTANCES)) {
G_FREE(mszInstanceList);
dwInstanceListSize = lstrlenW(pWildCounterPath->szInstanceName) + 2;
if (pWildCounterPath->szParentName != NULL) {
dwInstanceListSize += lstrlenW(pWildCounterPath->szParentName) + 1;
}
if (pWildCounterPath->dwIndex != 0 && pWildCounterPath->dwIndex != PERF_NO_UNIQUE_ID) {
dwInstanceListSize += 16;
}
mszInstanceList = G_ALLOC(dwInstanceListSize * sizeof(WCHAR));
if (mszInstanceList != NULL) {
if (pWildCounterPath->szParentName != NULL) {
StringCchPrintfW(mszInstanceList, dwInstanceListSize, L"%ws/%ws",
pWildCounterPath->szParentName, pWildCounterPath->szInstanceName);
}
else {
StringCchCopyW(mszInstanceList, dwInstanceListSize, pWildCounterPath->szInstanceName);
}
if (pWildCounterPath->dwIndex != 0 && pWildCounterPath->dwIndex != PERF_NO_UNIQUE_ID) {
WCHAR szDigits[16];
StringCchCatW(mszInstanceList, dwInstanceListSize, cszPoundSign);
ZeroMemory(szDigits, 16 * sizeof(WCHAR));
_ltow((long) pWildCounterPath->dwIndex, szDigits, 10);
StringCchCatW(mszInstanceList, dwInstanceListSize, szDigits);
}
mszInstanceList [dwInstanceListSize - 1] = L'\0';
}
else {
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
}
}
}
if (pdhStatus != ERROR_SUCCESS) continue;
if (mszInstanceList != NULL) {
if (! bNoInstances && mszInstanceList[0] == L'\0') {
pdhStatus = PDH_CSTATUS_NO_INSTANCE;
continue;
}
InitializeListHead(& InstList);
for (szThisInstance = mszInstanceList;
* szThisInstance != L'\0';
szThisInstance += (lstrlenW(szThisInstance) + 1)) {
PdhiFindInstance(& InstList, szThisInstance, TRUE, &pInst);
}
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 != L'\0';
szThisCounter += (lstrlenW(szThisCounter) + 1)) {
pPathElem.szCounterName = szThisCounter;
//make path string and add to list if it will fit
szTempPathBufferSize = SMALL_BUFFER_SIZE;
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)) {
StringCchCopyW((LPWSTR) szNextUserString, dwBufferRemaining, szTempPathBuffer);
(LPBYTE) szNextUserString += dwSize * sizeof(WCHAR);
dwBufferRemaining -= dwSize;
dwSuccess ++;
}
else {
dwBufferRemaining = 0;
bMoreData = TRUE;
}
}
else {
dwSize = dwBufferRemaining;
if (PdhiConvertUnicodeToAnsi(_getmbcp(),
szTempPathBuffer,
szNextUserString,
& dwSize) == ERROR_SUCCESS) {
(LPBYTE)szNextUserString += dwSize * sizeof(CHAR);
dwBufferRemaining -= dwSize;
dwSuccess ++;
}
else {
dwBufferRemaining = 0;
bMoreData = TRUE;
}
}
dwSizeReturned += dwSize;
} // end if path created OK
} // end for each counter
if (* szThisInstance != L'\0') {
szThisInstance += (lstrlenW(szThisInstance) + 1);
}
}
while (* szThisInstance != L'\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 (dwSuccess > 0) {
pdhStatus = (bMoreData) ? (PDH_MORE_DATA) : (ERROR_SUCCESS);
}
if (dwSizeReturned > 0) {
dwSize = 1;
if (dwBufferRemaining >= 1) {
if (szNextUserString) {
if (bUnicode) {
* (LPWSTR) szNextUserString = L'\0';
(LPBYTE) szNextUserString += dwSize * sizeof(WCHAR);
}
else {
* (LPSTR) szNextUserString = '\0';
(LPBYTE) szNextUserString += dwSize * sizeof(CHAR);
}
}
}
dwSizeReturned += dwSize;
dwBufferRemaining -= dwSize;
}
* pcchPathListLength = dwSizeReturned;
G_FREE(mszCounterList);
G_FREE(mszInstanceList);
G_FREE(mszObjectList);
G_FREE(pWildCounterPath);
G_FREE(szTempPathBuffer);
if (bMoreData) pdhStatus = PDH_MORE_DATA;
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 PdhExpandWildCardPathW(NULL, szWildCardPath, mszExpandedPathList, pcchPathListLength, 0);
}
PDH_FUNCTION
PdhExpandCounterPathA(
IN LPCSTR szWildCardPath,
IN LPSTR mszExpandedPathList,
IN LPDWORD pcchPathListLength
)
{
return PdhExpandWildCardPathA(NULL, szWildCardPath, mszExpandedPathList, pcchPathListLength, 0);
}
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 {
if (* szWildCardPath == L'\0' || lstrlenW(szWildCardPath) > PDH_MAX_COUNTER_PATH) {
pdhStatus = PDH_INVALID_ARGUMENT;
}
else {
dwLocalBufferSize = * pcchPathListLength;
if (dwLocalBufferSize > 0) {
if (mszExpandedPathList != NULL) {
mszExpandedPathList[0] = L'\0';
mszExpandedPathList[dwLocalBufferSize - 1] = L'\0';
}
else {
pdhStatus = PDH_INVALID_ARGUMENT;
}
}
}
}
__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 == L'\0') {
pdhStatus = PDH_INVALID_ARGUMENT;
}
else if (lstrlenW(szDataSource) > PDH_MAX_DATASOURCE_PATH) {
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;
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 {
dwLocalBufferSize = * pcchPathListLength;
if (dwLocalBufferSize > 0) {
if (mszExpandedPathList != NULL) {
mszExpandedPathList[0] = L'\0';
mszExpandedPathList[dwLocalBufferSize - 1] = L'\0';
}
else {
pdhStatus = PDH_INVALID_ARGUMENT;
}
}
if (pdhStatus == ERROR_SUCCESS) {
if (* szWildCardPath == '\0' || lstrlenA(szWildCardPath) > PDH_MAX_COUNTER_PATH) {
pdhStatus = PDH_INVALID_ARGUMENT;
}
else {
szWideWildCardPath = PdhiMultiByteToWideChar(_getmbcp(), (LPSTR) szWildCardPath);
if (szWideWildCardPath == NULL) {
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
}
}
}
}
__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;
}
}
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 if (lstrlenA(szDataSource) > PDH_MAX_DATASOURCE_PATH) {
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;
}