Windows-Server-2003/sdktools/pdh/pdhdll/vbfuncs.c

895 lines
29 KiB
C

/*++
Copyright (C) 1995-1999 Microsoft Corporation
Module Name:
vbfuncs.c
Abstract:
Visual Basic interface functions exposed in pdh.dll
--*/
#include <windows.h>
#include "strsafe.h"
#include <winperf.h>
#include <pdh.h>
#include "pdhidef.h"
#include "pdhmsg.h"
#include "strings.h"
#define INITIAL_VB_LIST_SIZE (4096 * 4)
#define EXTEND_VB_LIST_SIZE (4096 * 2)
typedef struct _VB_STRING_LIST {
LPSTR mszList; // pointer to buffer containing strings
LPSTR szTermChar; // pointer to "next" char to use
DWORD dwNumEntries; // number of strings
DWORD dwSize; // max size (in chars) of buffer
DWORD dwRemaining; // # of chars left
DWORD dwLastEntryRead; // index of last string read indicating index of....
DWORD dwLastItemLength; // length of last item read
LPSTR szLastItemRead; // pointer to START of last item read
} VB_STRING_LIST, FAR * LPVB_STRING_LIST;
VB_STRING_LIST PdhivbList = { NULL, NULL, 0, 0, 0};
BOOL
PdhiAddStringToVbList(
LPSTR szString
)
{
DWORD dwSize1, dwSize2;
VB_STRING_LIST * pVbList;
BOOL bReturn = FALSE;
if (WAIT_FOR_AND_LOCK_MUTEX(hPdhDataMutex) == ERROR_SUCCESS) {
dwSize1 = lstrlenA(szString) + 1;
pVbList = & PdhivbList;
if (dwSize1 > pVbList->dwRemaining) {
LPSTR lpTmp = pVbList->mszList;
dwSize2 = (DWORD) (pVbList->szTermChar - pVbList->mszList);
pVbList->dwSize += EXTEND_VB_LIST_SIZE;
pVbList->mszList = G_REALLOC(lpTmp, pVbList->dwSize);
if (pVbList->mszList == NULL) {
G_FREE(lpTmp);
ZeroMemory(pVbList, sizeof(VB_STRING_LIST));
RELEASE_MUTEX(hPdhDataMutex);
goto Cleanup;
}
else {
// update values
pVbList->szLastItemRead = pVbList->mszList;
pVbList->szTermChar = pVbList->mszList + dwSize2;
pVbList->dwRemaining += EXTEND_VB_LIST_SIZE;
}
}
// copy new string
StringCchCopyA(pVbList->szTermChar, pVbList->dwSize, szString);
pVbList->dwNumEntries ++;
pVbList->szTermChar += dwSize1;
pVbList->dwRemaining -= dwSize1;
RELEASE_MUTEX(hPdhDataMutex);
bReturn = TRUE;
}
Cleanup:
return bReturn;
}
void
PdhiDialogCallBack(
DWORD_PTR dwArg
)
{
// add strings in buffer to list boxpfdh
LPTSTR NewCounterName;
LPTSTR NewCounterName2;
LPTSTR szExpandedPath;
DWORD dwSize1, dwSize2;
PDH_STATUS pdhStatus = ERROR_SUCCESS;
PPDH_BROWSE_DLG_CONFIG pDlgConfig;
pDlgConfig = (PPDH_BROWSE_DLG_CONFIG)dwArg;
if (pDlgConfig->CallBackStatus == PDH_MORE_DATA) {
// transfer buffer is too small for selection so extend it and
// try again.
if (pDlgConfig->szReturnPathBuffer != NULL) {
G_FREE (pDlgConfig->szReturnPathBuffer);
}
pDlgConfig->cchReturnPathLength += EXTEND_VB_LIST_SIZE;
pDlgConfig->szReturnPathBuffer =
G_ALLOC ((pDlgConfig->cchReturnPathLength * sizeof (CHAR)));
if (pDlgConfig->szReturnPathBuffer != NULL) {
pdhStatus = PDH_RETRY;
} else {
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
}
} else {
for (NewCounterName = pDlgConfig->szReturnPathBuffer;
(*NewCounterName != 0) && (pdhStatus == ERROR_SUCCESS);
NewCounterName += (lstrlen(NewCounterName) + 1)) {
if (strstr (NewCounterName, caszSplat) == NULL) {
// this is a regular path entry so add it to the VB List
if (!PdhiAddStringToVbList (NewCounterName)) {
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
}
} else {
szExpandedPath = G_ALLOC (INITIAL_VB_LIST_SIZE);
if (szExpandedPath != NULL) {
// there's a wild card path character so expand it then enter them
// clear the list buffer
*(LPDWORD)szExpandedPath = 0;
dwSize1 = dwSize2 = INITIAL_VB_LIST_SIZE;
PdhExpandCounterPath (NewCounterName, szExpandedPath, &dwSize2);
if (dwSize2 < dwSize1) {
// then the returned buffer fit
for (NewCounterName2 = szExpandedPath;
*NewCounterName2 != 0;
NewCounterName2 += (lstrlen(NewCounterName2) + 1)) {
if (!PdhiAddStringToVbList (NewCounterName2)) {
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
break; //out of loop
}
}
} else {
pdhStatus = PDH_INSUFFICIENT_BUFFER;
}
G_FREE (szExpandedPath);
} else {
SetLastError (PDH_MEMORY_ALLOCATION_FAILURE);
}
}
}
// clear buffer
ZeroMemory(pDlgConfig->szReturnPathBuffer,
(pDlgConfig->cchReturnPathLength * sizeof(CHAR)));
}
pDlgConfig->CallBackStatus = pdhStatus;
return;
}
double
PdhVbGetDoubleCounterValue(
IN PDH_HCOUNTER hCounter,
IN LPDWORD pdwCounterStatus
)
/*++
Routine Description:
retrieves the current value of the specified counter and returns the
formatted version to the caller.
Arguments:
IN HCOUNTER hCounter
pointer to the counter to get the data for
IN LPDWORD pdwCounterStatus
status value of this counter. This value should be checked to
insure the data is valid. If the status is not successful, then
the data returned cannot be trusted and should not be used
Return Value:
a double precesion floating point value of the current counter value
formatted and computed as required by the counter type.
--*/
{
PDH_STATUS pdhStatus;
PDH_FMT_COUNTERVALUE pdhValue;
DWORD dwCounterType;
double dReturn;
pdhStatus = PdhGetFormattedCounterValue (
hCounter, PDH_FMT_DOUBLE | PDH_FMT_NOCAP100, &dwCounterType, &pdhValue);
if (pdhStatus == ERROR_SUCCESS) {
// the function was successful so return the counter status
// and the returned value
pdhStatus = pdhValue.CStatus;
dReturn = pdhValue.doubleValue;
} else {
// the function returned an error so return the
// error in the status field & 0.0 for a value
dReturn = 0.0f;
}
if (pdwCounterStatus != NULL) {
__try {
*pdwCounterStatus = pdhStatus;
} __except (EXCEPTION_EXECUTE_HANDLER) {
// unable to write to status variable
// don't worry about it, since it's optional and there's not much
// we can do here anyway.
}
}
return dReturn;
}
DWORD
PdhVbGetOneCounterPath(
IN LPSTR szPathBuffer,
IN DWORD cchBufferLength,
IN DWORD dwDetailLevel,
IN LPCSTR szCaption
)
/*++
Routine Description:
Retrieves one path string from the buffer of stored counter paths
assembled by the most recent call to PdhVbCreateCounterPathList
Arguments:
LPSTR szPathBuffer
string buffer to return selected counter path in
DWORD cchBufferLength
size of string buffer in characters
DWORD dwDetailLevel
detail level to filter the counters by
LPCSTR szCaption
string to display in the caption bar
Return Value:
returns the length of the path string in characters returned
to the caller.
--*/
{
PDH_BROWSE_DLG_CONFIG_A BrowseConfig;
PDH_STATUS PdhStatus = ERROR_SUCCESS;
DWORD dwReturn = 0;
// test access to caller supplied buffer
__try {
CHAR cChar;
if ((cchBufferLength > 0) && (szPathBuffer != NULL)) {
cChar = szPathBuffer[0];
szPathBuffer[0] = '\0';
szPathBuffer[0] = cChar;
cChar = szPathBuffer[cchBufferLength - 1];
szPathBuffer[cchBufferLength - 1] = '\0';
szPathBuffer[cchBufferLength - 1] = cChar;
}
else {
PdhStatus = PDH_INVALID_ARGUMENT;
}
if (szCaption != NULL) {
cChar = * ((CHAR volatile *) szCaption);
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {
PdhStatus = PDH_INVALID_ARGUMENT;
}
if (PdhStatus == ERROR_SUCCESS) {
ZeroMemory(& BrowseConfig, sizeof(PDH_BROWSE_DLG_CONFIG_A));
BrowseConfig.bIncludeInstanceIndex = FALSE;
BrowseConfig.bSingleCounterPerAdd = TRUE;
BrowseConfig.bSingleCounterPerDialog = TRUE;
BrowseConfig.bLocalCountersOnly = FALSE;
BrowseConfig.bWildCardInstances = FALSE;
BrowseConfig.bDisableMachineSelection = FALSE;
BrowseConfig.bHideDetailBox = (dwDetailLevel > 0 ? TRUE : FALSE);
BrowseConfig.hWndOwner = NULL; // there should be some way to get this
BrowseConfig.szReturnPathBuffer = szPathBuffer;
BrowseConfig.cchReturnPathLength = cchBufferLength;
BrowseConfig.pCallBack = NULL;
BrowseConfig.dwCallBackArg = 0;
// default is to show ALL counters
BrowseConfig.dwDefaultDetailLevel = (dwDetailLevel > 0 ? dwDetailLevel : PERF_DETAIL_WIZARD);
BrowseConfig.szDialogBoxCaption = (LPSTR) szCaption;
PdhStatus = PdhBrowseCountersA(& BrowseConfig);
}
if (PdhStatus == ERROR_SUCCESS) {
dwReturn = lstrlenA(szPathBuffer);
}
else {
dwReturn = 0;
}
return dwReturn;
}
DWORD
PdhVbCreateCounterPathList(
IN DWORD dwDetailLevel,
IN LPCSTR szCaption
)
/*++
Routine Description:
Displays the counter browsing dialog box and allows the user to select
multiple counter paths. As the paths are selected, they are stored
in an internal buffer for later retrieval by the caller.
NOTE, that calling this function will clear any previous selections.
Arguments:
DWORD dwDetailLevel
detail level to filter the counters by
LPCSTR szCaption
string to display in the caption bar
Return Value:
returns the number of path strings selected by the user that must
be retrieved by the caller.
--*/
{
PDH_STATUS PdhStatus = ERROR_SUCCESS;
PDH_BROWSE_DLG_CONFIG_A BrowseConfig;
DWORD dwReturn = 0;
// test access to caller supplied buffer
__try {
CHAR cChar;
if (szCaption != NULL) {
cChar = * ((CHAR volatile *) szCaption);
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {
PdhStatus = PDH_INVALID_ARGUMENT;
}
if (PdhStatus == ERROR_SUCCESS) {
PdhStatus = WAIT_FOR_AND_LOCK_MUTEX(hPdhDataMutex);
if (PdhStatus == ERROR_SUCCESS) {
if (PdhivbList.mszList != NULL) {
G_FREE(PdhivbList.mszList);
ZeroMemory((LPVOID) & PdhivbList, sizeof(VB_STRING_LIST));
}
PdhivbList.mszList = G_ALLOC(INITIAL_VB_LIST_SIZE);
if (PdhivbList.mszList != NULL) {
PdhivbList.szLastItemRead = PdhivbList.mszList;
PdhivbList.szTermChar = PdhivbList.mszList;
PdhivbList.dwRemaining = INITIAL_VB_LIST_SIZE;
PdhivbList.dwSize = INITIAL_VB_LIST_SIZE;
PdhivbList.dwLastEntryRead = 0;
PdhivbList.dwLastItemLength = 0;
}
else {
PdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
}
RELEASE_MUTEX(hPdhDataMutex);
}
}
if (PdhStatus == ERROR_SUCCESS) {
ZeroMemory(& BrowseConfig, sizeof(PDH_BROWSE_DLG_CONFIG_A));
BrowseConfig.bIncludeInstanceIndex = FALSE;
BrowseConfig.bSingleCounterPerAdd = FALSE;
BrowseConfig.bSingleCounterPerDialog = FALSE;
BrowseConfig.bLocalCountersOnly = FALSE;
BrowseConfig.bWildCardInstances = FALSE;
BrowseConfig.bDisableMachineSelection = FALSE;
BrowseConfig.bHideDetailBox = (dwDetailLevel > 0 ? TRUE : FALSE);
BrowseConfig.hWndOwner = NULL; // there should be some way to get this
BrowseConfig.szReturnPathBuffer = G_ALLOC (INITIAL_VB_LIST_SIZE);
if (BrowseConfig.szReturnPathBuffer != NULL) {
BrowseConfig.cchReturnPathLength = (BrowseConfig.szReturnPathBuffer != NULL ? INITIAL_VB_LIST_SIZE : 0);
BrowseConfig.pCallBack = (CounterPathCallBack) PdhiDialogCallBack;
BrowseConfig.dwCallBackArg = (DWORD_PTR) & BrowseConfig;
// default is to show ALL counters
BrowseConfig.dwDefaultDetailLevel = (dwDetailLevel > 0 ? dwDetailLevel : PERF_DETAIL_WIZARD);
BrowseConfig.szDialogBoxCaption = (LPSTR)szCaption;
PdhStatus = PdhBrowseCountersA(& BrowseConfig);
if (BrowseConfig.szReturnPathBuffer != NULL) {
G_FREE(BrowseConfig.szReturnPathBuffer);
}
dwReturn = PdhivbList.dwNumEntries;
}
else {
SetLastError(PDH_MEMORY_ALLOCATION_FAILURE);
dwReturn = 0;
}
}
return dwReturn;
}
DWORD
PdhVbGetCounterPathFromList(
IN DWORD dwIndex, // starting at 1 for VB types
IN LPSTR szBuffer, // return buffer
IN DWORD dwBufferSize // size in chars of buffer
)
/*++
Routine Description:
Displays the counter browsing dialog box and allows the user to select
multiple counter paths. As the paths are selected, they are stored
in an internal buffer for later retrieval by the caller.
NOTE, that calling this function will clear any previous selections.
Arguments:
DWORD dwIndex
The "1-based" index of the counter path to retrieve from
the list of selected counter paths generated by the previous
call to PdhVbCreateCounterPathList.
LPSTR szBuffer
string buffer to return the selected string in
DWORD dwBufferSize
size of the szBuffer in characters
Return Value:
Returns the number of characters copied to the calling function
--*/
{
DWORD dwBuffIndex; // 0-based index for "c"
DWORD dwThisIndex;
DWORD dwCharsCopied; // size of string not counting term NULL
BOOL bContinue = TRUE;
dwBuffIndex = dwIndex - 1;
dwCharsCopied = 0;
// validate the arguments
__try {
if (dwBufferSize > 0) {
// try writing to ouput buffer
szBuffer[0] = '\0';
szBuffer[dwBufferSize - 1] = '\0';
}
else {
bContinue = FALSE;
}
if (dwBuffIndex >= PdhivbList.dwNumEntries) {
bContinue = FALSE;
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {
bContinue = FALSE;
}
if (WAIT_FOR_AND_LOCK_MUTEX(hPdhDataMutex) == ERROR_SUCCESS) {
if (bContinue) {
if (PdhivbList.szLastItemRead == NULL) {
PdhivbList.szLastItemRead = PdhivbList.mszList;
PdhivbList.dwLastEntryRead = 0;
PdhivbList.dwLastItemLength = 0;
}
if (PdhivbList.szLastItemRead != NULL) {
if (PdhivbList.dwLastItemLength == 0) {
PdhivbList.dwLastItemLength = lstrlen(PdhivbList.szLastItemRead) + 1;
}
}
else {
bContinue = FALSE;
}
}
if (bContinue) {
// see if this is the next entry
if (dwBuffIndex == (PdhivbList.dwLastEntryRead + 1)) {
PdhivbList.szLastItemRead += PdhivbList.dwLastItemLength;
PdhivbList.dwLastItemLength = lstrlen(PdhivbList.szLastItemRead) + 1;
PdhivbList.dwLastEntryRead ++;
if (PdhivbList.dwLastItemLength < dwBufferSize) {
StringCchCopyA(szBuffer, dwBufferSize, PdhivbList.szLastItemRead);
dwCharsCopied = PdhivbList.dwLastItemLength - 1;
}
}
else if (dwBuffIndex == PdhivbList.dwLastEntryRead) {
// it's this one (again)
if (PdhivbList.dwLastItemLength < dwBufferSize) {
StringCchCopyA(szBuffer, dwBufferSize, PdhivbList.szLastItemRead);
dwCharsCopied = PdhivbList.dwLastItemLength - 1;
}
}
else {
// walk the list to the desired entry (ugh!)
PdhivbList.szLastItemRead = PdhivbList.mszList;
for (dwThisIndex = 0; dwThisIndex < dwBuffIndex; dwThisIndex++) {
PdhivbList.szLastItemRead += lstrlen(PdhivbList.szLastItemRead) + 1;
}
PdhivbList.dwLastItemLength = lstrlen(PdhivbList.szLastItemRead) + 1;
PdhivbList.dwLastEntryRead = dwThisIndex;
if (PdhivbList.dwLastItemLength < dwBufferSize) {
StringCchCopyA(szBuffer, dwBufferSize, PdhivbList.szLastItemRead);
dwCharsCopied = PdhivbList.dwLastItemLength - 1;
}
}
}
RELEASE_MUTEX(hPdhDataMutex);
}
return dwCharsCopied;
}
DWORD
PdhVbGetCounterPathElements(
IN LPCSTR szPathString,
IN LPSTR szMachineName,
IN LPSTR szObjectName,
IN LPSTR szInstanceName,
IN LPSTR szParentInstance,
IN LPSTR szCounterName,
IN DWORD dwBufferSize
)
/*++
Routine Description:
breaks the counter path provided in the szPathString argument and
returns the components in the buffers provided by the caller.
The buffers must be at least "dwBufferSize" in length.
Arguments:
LPCSTR szPathString
pointer to the full counter path that is to be parsed into
component strings
LPSTR szMachineName
caller supplied buffer that is to receive the machine name.
The buffer must be at least dwBufferSize in length.
LPSTR szObjectName
caller supplied buffer that is to receive the object name.
The buffer must be at least dwBufferSize in length.
LPSTR szInstanceName
caller supplied buffer that is to receive the Instance name.
The buffer must be at least dwBufferSize in length.
LPSTR szParentInstance
caller supplied buffer that is to receive the parent instance name.
The buffer must be at least dwBufferSize in length.
LPSTR szCounterName
caller supplied buffer that is to receive the counter name.
The buffer must be at least dwBufferSize in length.
DWORD dwBufferSize
The buffer size of the caller supplied string buffers in characters
Return Value:
ERROR_SUCCESS if the counter string is successfully parsed, otherwise
a PDH error if not.
PDH_INVALID_ARGUMENT if one or more of the string buffers is not
the correct size
PDH_INSUFFICIENT_BUFFER if one or more of the counter path elements
is too large for the return buffer length.
PDH_MEMORY_ALLOCATION_FAILURE if a temporary memory buffer could not
be allocated.
--*/
{
PPDH_COUNTER_PATH_ELEMENTS_A pInfo;
PDH_STATUS pdhStatus = ERROR_SUCCESS;
DWORD dwSize;
// validate the return arguments
__try {
CHAR cChar;
if (szPathString != NULL) {
cChar = * ((CHAR volatile *) szPathString);
if (cChar == 0) {
pdhStatus = PDH_INVALID_ARGUMENT;
}
}
else {
pdhStatus = PDH_INVALID_ARGUMENT;
}
if (pdhStatus == ERROR_SUCCESS){
if (szMachineName != NULL) {
szMachineName[0] = '\0';
szMachineName[dwBufferSize - 1] = '\0';
}
else {
pdhStatus = PDH_INVALID_ARGUMENT;
}
}
if (pdhStatus == ERROR_SUCCESS){
if (szObjectName != NULL) {
szObjectName[0] = '\0';
szObjectName[dwBufferSize - 1] = '\0';
}
else {
pdhStatus = PDH_INVALID_ARGUMENT;
}
}
if (pdhStatus == ERROR_SUCCESS){
if (szInstanceName != NULL) {
szInstanceName[0] = '\0';
szInstanceName[dwBufferSize - 1] = '\0';
}
else {
pdhStatus = PDH_INVALID_ARGUMENT;
}
}
if (pdhStatus == ERROR_SUCCESS){
if (szParentInstance != NULL) {
szParentInstance[0] = '\0';
szParentInstance[dwBufferSize - 1] = '\0';
}
else {
pdhStatus = PDH_INVALID_ARGUMENT;
}
}
if (pdhStatus == ERROR_SUCCESS){
if (szCounterName != NULL) {
szCounterName[0] = '\0';
szCounterName[dwBufferSize - 1] = '\0';
} else {
pdhStatus = PDH_INVALID_ARGUMENT;
}
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {
pdhStatus = PDH_INVALID_ARGUMENT;
}
if (pdhStatus == ERROR_SUCCESS) {
// allocate temp buffer for component strings
dwSize = (5 * dwBufferSize) + sizeof(PDH_COUNTER_INFO_A);
pInfo = G_ALLOC (dwSize);
if (pInfo != NULL) {
pdhStatus = PdhParseCounterPathA(szPathString, pInfo, & dwSize, 0);
if (pdhStatus == ERROR_SUCCESS) {
// move from local structure to user args if the strings will fit
if (pInfo->szMachineName != NULL) {
if (FAILED(StringCchCopyA(szMachineName, dwBufferSize, pInfo->szMachineName))) {
pdhStatus = PDH_INSUFFICIENT_BUFFER;
}
}
if (pInfo->szObjectName != NULL) {
if (FAILED(StringCchCopyA(szObjectName, dwBufferSize, pInfo->szObjectName))) {
pdhStatus = PDH_INSUFFICIENT_BUFFER;
}
}
if (pInfo->szInstanceName != NULL) {
if (FAILED(StringCchCopyA(szInstanceName, dwBufferSize, pInfo->szInstanceName))) {
pdhStatus = PDH_INSUFFICIENT_BUFFER;
}
}
if (pInfo->szParentInstance != NULL) {
if (FAILED(StringCchCopyA(szParentInstance, dwBufferSize, pInfo->szParentInstance))) {
pdhStatus = PDH_INSUFFICIENT_BUFFER;
}
}
if (pInfo->szCounterName != NULL) {
if (FAILED(StringCchCopyA(szCounterName, dwBufferSize, pInfo->szCounterName))) {
pdhStatus = PDH_INSUFFICIENT_BUFFER;
}
}
} // else pass error to caller
G_FREE (pInfo);
}
else {
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
}
} // else pass error to caller
return pdhStatus;
}
DWORD
PdhVbAddCounter(
IN PDH_HQUERY hQuery,
IN LPCSTR szFullCounterPath,
IN PDH_HCOUNTER * hCounter
)
/*++
Routine Description:
Creates and initializes a counter structure and attaches it to the
specified query by calling the C function.
Arguments:
IN HQUERY hQuery
handle of the query to attach this counter to once the counter
entry has been successfully created.
IN LPCSTR szFullCounterPath
pointer to the path string that describes the counter to add to
the query referenced above. This string must specify a single
counter. Wildcard path strings are not permitted.
IN HCOUNTER *phCounter
pointer to the buffer that will get the handle value of the
successfully created counter entry.
Return Value:
Returns ERROR_SUCCESS if a new query was created and initialized,
and a PDH_ error value if not.
PDH_INVALID_ARGUMENT is returned when one or more of the arguements
is invalid or incorrect.
PDH_MEMORY_ALLOCATION_FAILURE is returned when a memory buffer could
not be allocated.
PDH_INVALID_HANDLE is returned if the query handle is not valid.
PDH_CSTATUS_NO_COUNTER is returned if the specified counter was
not found
PDH_CSTATUS_NO_OBJECT is returned if the specified object could
not be found
PDH_CSTATUS_NO_MACHINE is returned if a machine entry could not
be created.
PDH_CSTATUS_BAD_COUNTERNAME is returned if the counter name path
string could not be parsed or interpreted
PDH_CSTATUS_NO_COUNTERNAME is returned if an empty counter name
path string is passed in
PDH_FUNCTION_NOT_FOUND is returned if the calculation function
for this counter could not be determined.
--*/
{
DWORD dwReturn = ERROR_SUCCESS;
PDH_HCOUNTER hLocalCounter = NULL;
if ((hCounter == NULL) || (szFullCounterPath == NULL)) {
dwReturn = PDH_INVALID_ARGUMENT;
}
else {
dwReturn = PdhAddCounterA(hQuery, szFullCounterPath, 0, & hLocalCounter);
}
if (dwReturn == ERROR_SUCCESS) {
__try {
* hCounter = hLocalCounter;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwReturn = PDH_INVALID_ARGUMENT;
}
}
return dwReturn;
}
DWORD
PdhVbOpenQuery(
IN PDH_HQUERY * phQuery
)
/*++
Routine Description:
allocates a new query structure for a VB app by calling the "C"
function with the rest of the arguments supplied
Arguments:
IN HQUERY *phQuery
pointer to the buffer that will receive the query handle opened.
Return Value:
Returns ERROR_SUCCESS if a new query was created and initialized,
and a PDH_ error value if not.
PDH_INVALID_ARGUMENT is returned when one or more of the arguements
is invalid or incorrect.
PDH_MEMORY_ALLOCATION_FAILURE is returned when a memory buffer could
not be allocated.
--*/
{
DWORD dwReturn = ERROR_SUCCESS;
PDH_HQUERY hLocalQuery = NULL;
if (phQuery == NULL) {
dwReturn = PDH_INVALID_ARGUMENT;
}
else {
dwReturn = PdhOpenQuery(NULL, 0, & hLocalQuery);
}
if (dwReturn == ERROR_SUCCESS) {
__try {
* phQuery = hLocalQuery;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwReturn = PDH_INVALID_ARGUMENT;
}
}
return dwReturn;
}
DWORD
PdhVbIsGoodStatus(
IN LONG lStatus
)
/*++
Routine Description:
Checks the status severity of the PDH status value
passed into the function as a binary Good (TRUE)/Bad (FALSE)
value.
Arguments:
IN LONG lStatus
Status code to test
Return Value:
TRUE if the status code is Success or Informational severity
FALSE if the status code is Error or Warning severity
--*/
{
BOOL bReturn;
if (lStatus == ERROR_SUCCESS) {
bReturn = TRUE;
}
else if (IsSuccessSeverity(lStatus)) {
bReturn = TRUE;
}
else if (IsInformationalSeverity(lStatus)) {
bReturn = TRUE;
}
else {
bReturn = FALSE;
}
return (DWORD) bReturn;
}
DWORD
PdhVbOpenLog(
IN LPCSTR szLogFileName,
IN DWORD dwAccessFlags,
IN LPDWORD lpdwLogType,
IN HQUERY hQuery,
IN DWORD dwMaxSize,
IN LPCSTR szUserCaption,
IN PDH_HLOG * phLog
)
/*++
Routine Description:
Arguments:
IN LPCSTR szLogFileName,
IN DWORD dwAccessFlags,
IN LPDWORD lpdwLogType,
IN HQUERY hQuery,
IN DWORD dwMaxSize,
IN LPCSTR szUserCaption,
IN HLOG * phLog
Return Value:
TRUE if the status code is Success or Informational severity
FALSE if the status code is Error or Warning severity
--*/
{
return PdhOpenLogA(szLogFileName, dwAccessFlags, lpdwLogType, hQuery, dwMaxSize, szUserCaption, phLog);
}
DWORD
PdhVbUpdateLog(
IN PDH_HLOG hLog,
IN LPCSTR szUserString
)
/*++
Routine Description:
Arguments:
IN HLOG hLog,
IN LPCWSTR szUserString
Return Value:
TRUE if the status code is Success or Informational severity
FALSE if the status code is Error or Warning severity
--*/
{
return PdhUpdateLogA(hLog, szUserString);
}
DWORD
PdhVbGetLogFileSize(
IN PDH_HLOG hLog,
IN LONG * lSize
)
/*++
Routine Description:
Arguments:
IN HLOG hLog,
IN LONGLONG * llSize
Return Value:
TRUE if the status code is Success or Informational severity
FALSE if the status code is Error or Warning severity
--*/
{
PDH_STATUS pdhStatus;
LONGLONG llTemp;
pdhStatus = PdhGetLogFileSize(hLog, & llTemp);
if (pdhStatus == ERROR_SUCCESS) {
if (llTemp > 0x0000000080000000) {
// file size is larger than a long value
pdhStatus = PDH_INSUFFICIENT_BUFFER;
}
else {
__try {
* lSize = (LONG) (llTemp & 0x000000007FFFFFFF);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
pdhStatus = PDH_INVALID_ARGUMENT;
}
}
}
return pdhStatus;
}