1182 lines
41 KiB
C
1182 lines
41 KiB
C
/*++
|
||
|
||
Copyright (C) 1995-1999 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
log_ctrl.c
|
||
|
||
Abstract:
|
||
|
||
Log file control interface helper functions
|
||
|
||
--*/
|
||
|
||
#include <windows.h>
|
||
#include <stdlib.h>
|
||
#include <assert.h>
|
||
#include <pdh.h>
|
||
#include "pdhidef.h"
|
||
#include "pdhmsg.h"
|
||
#include "strings.h"
|
||
|
||
#define PDH_LOGSVC_CTRL_FNMASK ((DWORD)(PDH_LOGSVC_CTRL_ADD \
|
||
| PDH_LOGSVC_CTRL_REMOVE \
|
||
| PDH_LOGSVC_CTRL_INFO \
|
||
))
|
||
|
||
|
||
//
|
||
// Internal Logging utility functions
|
||
//
|
||
LONG
|
||
GetCurrentServiceState (
|
||
SC_HANDLE hService,
|
||
BOOL * bStopped,
|
||
BOOL * bPaused)
|
||
{
|
||
SERVICE_STATUS ssData;
|
||
LONG lStatus = ERROR_SUCCESS;
|
||
|
||
BOOL bServiceStopped = FALSE;
|
||
BOOL bServicePaused = FALSE;
|
||
|
||
if (ControlService (
|
||
hService, SERVICE_CONTROL_INTERROGATE,
|
||
&ssData)) {
|
||
switch (ssData.dwCurrentState) {
|
||
|
||
case SERVICE_STOPPED:
|
||
bServiceStopped = TRUE;
|
||
bServicePaused = FALSE;
|
||
break;
|
||
|
||
case SERVICE_START_PENDING:
|
||
bServiceStopped = TRUE;
|
||
bServicePaused = FALSE;
|
||
break;
|
||
|
||
case SERVICE_STOP_PENDING:
|
||
bServiceStopped = FALSE;
|
||
bServicePaused = FALSE;
|
||
break;
|
||
|
||
case SERVICE_RUNNING:
|
||
bServiceStopped = FALSE;
|
||
bServicePaused = FALSE;
|
||
break;
|
||
|
||
case SERVICE_CONTINUE_PENDING:
|
||
bServiceStopped = FALSE;
|
||
bServicePaused = FALSE;
|
||
break;
|
||
|
||
case SERVICE_PAUSE_PENDING:
|
||
bServiceStopped = FALSE;
|
||
bServicePaused = FALSE;
|
||
break;
|
||
|
||
case SERVICE_PAUSED:
|
||
bServiceStopped = FALSE;
|
||
bServicePaused = TRUE;
|
||
break;
|
||
|
||
default:
|
||
;// no op
|
||
}
|
||
} else {
|
||
bServiceStopped = TRUE;
|
||
bServicePaused = TRUE;
|
||
}
|
||
|
||
*bStopped = bServiceStopped;
|
||
*bPaused = bServicePaused;
|
||
|
||
return lStatus;
|
||
}
|
||
|
||
STATIC_PDH_FUNCTION
|
||
PdhiSetLogQueryState (
|
||
IN LPCWSTR szMachineName,
|
||
IN LPCWSTR szQueryName,
|
||
IN DWORD dwFlags
|
||
)
|
||
{
|
||
DBG_UNREFERENCED_PARAMETER(szMachineName);
|
||
DBG_UNREFERENCED_PARAMETER(szQueryName);
|
||
DBG_UNREFERENCED_PARAMETER(dwFlags);
|
||
|
||
return ERROR_SUCCESS;
|
||
}
|
||
|
||
STATIC_PDH_FUNCTION
|
||
PdhiGetLogQueryState (
|
||
IN SC_HANDLE hService,
|
||
IN LPCWSTR szMachineName,
|
||
IN LPCWSTR szQueryName,
|
||
IN LPDWORD pdwFlags
|
||
)
|
||
{
|
||
BOOL bStopped, bPaused;
|
||
DWORD dwStatus;
|
||
|
||
UNREFERENCED_PARAMETER(szMachineName);
|
||
UNREFERENCED_PARAMETER(szQueryName);
|
||
|
||
// first get service status
|
||
GetCurrentServiceState (hService, &bStopped, &bPaused);
|
||
|
||
if (bStopped) {
|
||
dwStatus = PDH_LOGSVC_STATUS_STOPPED;
|
||
} else if (bPaused) {
|
||
dwStatus = PDH_LOGSVC_STATUS_PAUSED;
|
||
} else {
|
||
dwStatus = PDH_LOGSVC_STATUS_RUNNING;
|
||
}
|
||
|
||
if (dwStatus == PDH_LOGSVC_STATUS_RUNNING) {
|
||
// get status of specific query
|
||
// connect to machine, if necssary
|
||
// open registry key of log service
|
||
// read value of query status
|
||
// adjust status, if necessary
|
||
}
|
||
|
||
// return status of query
|
||
*pdwFlags = dwStatus;
|
||
|
||
return ERROR_SUCCESS;
|
||
}
|
||
|
||
STATIC_PDH_FUNCTION
|
||
PdhiLogServiceAddCommandT (
|
||
IN LPCWSTR szMachineName,
|
||
IN LPCWSTR szQueryName,
|
||
IN DWORD dwFlags,
|
||
IN LPVOID pInfoBuffer,
|
||
IN LPDWORD pdwBufferSize,
|
||
IN BOOL bWideChar
|
||
)
|
||
{
|
||
UNREFERENCED_PARAMETER(szMachineName);
|
||
UNREFERENCED_PARAMETER(szQueryName);
|
||
UNREFERENCED_PARAMETER(dwFlags);
|
||
UNREFERENCED_PARAMETER(pInfoBuffer);
|
||
UNREFERENCED_PARAMETER(pdwBufferSize);
|
||
UNREFERENCED_PARAMETER(bWideChar);
|
||
|
||
return PDH_NOT_IMPLEMENTED;
|
||
}
|
||
|
||
STATIC_PDH_FUNCTION
|
||
PdhiLogServiceRemoveCommandT (
|
||
IN LPCWSTR szMachineName,
|
||
IN LPCWSTR szQueryName,
|
||
IN DWORD dwFlags,
|
||
IN LPVOID pInfoBuffer,
|
||
IN LPDWORD pdwBufferSize,
|
||
IN BOOL bWideChar
|
||
)
|
||
{
|
||
UNREFERENCED_PARAMETER(szMachineName);
|
||
UNREFERENCED_PARAMETER(szQueryName);
|
||
UNREFERENCED_PARAMETER(dwFlags);
|
||
UNREFERENCED_PARAMETER(pInfoBuffer);
|
||
UNREFERENCED_PARAMETER(pdwBufferSize);
|
||
UNREFERENCED_PARAMETER(bWideChar);
|
||
|
||
return PDH_NOT_IMPLEMENTED;
|
||
}
|
||
|
||
STATIC_PDH_FUNCTION
|
||
PdhiLogServiceInfoCommandT (
|
||
IN LPCWSTR szMachineName,
|
||
IN LPCWSTR szQueryName,
|
||
IN DWORD dwFlags,
|
||
IN LPVOID pInfoBuffer,
|
||
IN LPDWORD pdwBufferSize,
|
||
IN BOOL bWideChar
|
||
)
|
||
{
|
||
|
||
LONG lStatus = ERROR_SUCCESS;
|
||
PDH_STATUS pdhStatus = ERROR_SUCCESS;
|
||
|
||
DWORD dwRegValType;
|
||
DWORD dwRegValue;
|
||
DWORD dwRegValueSize;
|
||
|
||
WCHAR szTempFilePath[MAX_PATH];
|
||
WCHAR szRegString[MAX_PATH];
|
||
WCHAR szDriveName[MAX_PATH];
|
||
|
||
HKEY hKeyMachine = NULL;
|
||
HKEY hKeyLogSettings = NULL;
|
||
HKEY hKeyLogQuery = NULL;
|
||
|
||
CHAR *pNextChar = NULL;
|
||
WCHAR *pNextWideChar = NULL;
|
||
|
||
DWORD dwCharSize;
|
||
|
||
DWORD dwSize;
|
||
DWORD dwRequiredSize = sizeof(PDH_LOG_SERVICE_QUERY_INFO_W);
|
||
DWORD dwRemainingSize = 0;
|
||
|
||
UNREFERENCED_PARAMETER(dwFlags);
|
||
|
||
dwCharSize = bWideChar ? sizeof(WCHAR) : sizeof(CHAR);
|
||
|
||
setlocale( LC_ALL, "" ); // to make wcstombs work predictably
|
||
|
||
if (*pdwBufferSize < sizeof(PDH_LOG_SERVICE_QUERY_INFO_W)) {
|
||
// then then this is either too small or a size request in either
|
||
// case we won't copy any data and only estimate the size required
|
||
dwRemainingSize = 0;
|
||
} else {
|
||
dwRemainingSize = *pdwBufferSize - sizeof(PDH_LOG_SERVICE_QUERY_INFO_W);
|
||
}
|
||
|
||
// get root key to registry
|
||
if (szMachineName != NULL) {
|
||
lStatus = RegConnectRegistryW (
|
||
(LPWSTR)szMachineName,
|
||
HKEY_LOCAL_MACHINE,
|
||
&hKeyMachine);
|
||
if (lStatus != ERROR_SUCCESS) {
|
||
pdhStatus = PDH_CANNOT_CONNECT_MACHINE;
|
||
}
|
||
} else {
|
||
// use predefined key handle
|
||
hKeyMachine = HKEY_LOCAL_MACHINE;
|
||
lStatus = ERROR_SUCCESS;
|
||
}
|
||
|
||
if (pInfoBuffer == NULL) {
|
||
if (pdhStatus == ERROR_SUCCESS) {
|
||
pdhStatus = PDH_INVALID_ARGUMENT;
|
||
}
|
||
lStatus = ERROR_INVALID_PARAMETER;
|
||
}
|
||
|
||
if (lStatus == ERROR_SUCCESS) {
|
||
// open registry key to service
|
||
lStatus = RegOpenKeyExW (
|
||
hKeyMachine,
|
||
cszLogQueries,
|
||
0,
|
||
KEY_READ,
|
||
&hKeyLogSettings);
|
||
if (lStatus != ERROR_SUCCESS) {
|
||
pdhStatus = PDH_LOGSVC_NOT_OPENED;
|
||
}
|
||
}
|
||
|
||
if (lStatus == ERROR_SUCCESS) {
|
||
// open registry to specified log query
|
||
lStatus = RegOpenKeyExW (
|
||
hKeyLogSettings,
|
||
(szQueryName != NULL ? szQueryName : cszDefault),
|
||
0,
|
||
KEY_READ,
|
||
&hKeyLogQuery);
|
||
|
||
if (lStatus != ERROR_SUCCESS) {
|
||
pdhStatus = PDH_LOGSVC_QUERY_NOT_FOUND;
|
||
}
|
||
}
|
||
|
||
// continue
|
||
|
||
if (lStatus == ERROR_SUCCESS) {
|
||
|
||
// initialize string pointers
|
||
if (bWideChar && (pInfoBuffer != NULL)) {
|
||
pNextWideChar = (WCHAR *)(&((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)[1]);
|
||
} else {
|
||
pNextChar = (CHAR *)(&((PPDH_LOG_SERVICE_QUERY_INFO_A)pInfoBuffer)[1]);
|
||
}
|
||
|
||
// read log file format
|
||
dwRegValType = 0;
|
||
dwRegValue = 0;
|
||
dwRegValueSize = sizeof(DWORD);
|
||
lStatus = RegQueryValueExW (
|
||
hKeyLogQuery,
|
||
cszLogFileType,
|
||
NULL,
|
||
&dwRegValType,
|
||
(LPBYTE)&dwRegValue,
|
||
&dwRegValueSize);
|
||
if (*pdwBufferSize >= sizeof(PDH_LOG_SERVICE_QUERY_INFO_W)) {
|
||
// this data goes into the fixed portion of the structure
|
||
if ((lStatus == ERROR_SUCCESS) && (dwRegValType == REG_DWORD)) {
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->dwFileType = dwRegValue;
|
||
} else {
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->dwFileType = PDH_LOG_TYPE_UNDEFINED;
|
||
}
|
||
}
|
||
|
||
//read sample interval
|
||
dwRegValType = 0;
|
||
dwRegValue = 0;
|
||
dwRegValueSize = sizeof(DWORD);
|
||
lStatus = RegQueryValueExW (
|
||
hKeyLogQuery,
|
||
cszAutoNameInterval,
|
||
NULL,
|
||
&dwRegValType,
|
||
(LPBYTE)&dwRegValue,
|
||
&dwRegValueSize);
|
||
|
||
if (*pdwBufferSize >= sizeof(PDH_LOG_SERVICE_QUERY_INFO_W)) {
|
||
// this data goes into the fixed portion of the structure
|
||
if ((lStatus == ERROR_SUCCESS) && (dwRegValType == REG_DWORD)) {
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->PdlAutoNameInterval = dwRegValue;
|
||
} else {
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->PdlAutoNameInterval = 0;
|
||
dwRegValue = 0;
|
||
}
|
||
}
|
||
|
||
if (dwRegValue == 0) {
|
||
// initialize the rest of the manual name field(s)
|
||
dwRegValType = 0;
|
||
dwRegValueSize = MAX_PATH * sizeof(WCHAR);
|
||
memset (szRegString, 0, dwRegValueSize);
|
||
lStatus = RegQueryValueExW (
|
||
hKeyLogQuery,
|
||
cszLogFileName,
|
||
NULL,
|
||
&dwRegValType,
|
||
(LPBYTE)&szRegString[0],
|
||
&dwRegValueSize);
|
||
|
||
if ((lStatus == ERROR_SUCCESS) && (dwRegValType == REG_SZ)) {
|
||
dwRequiredSize += dwRegValueSize / (sizeof(WCHAR) / dwCharSize);
|
||
if (dwRequiredSize <= *pdwBufferSize) {
|
||
if (bWideChar) {
|
||
// copy widestrings
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->szBaseFileName = pNextWideChar;
|
||
lstrcpyW (pNextWideChar, szRegString);
|
||
pNextWideChar += dwRegValueSize / sizeof (WCHAR);
|
||
} else {
|
||
// convert to ansi char
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_A)pInfoBuffer)->szBaseFileName = pNextChar;
|
||
wcstombs (pNextChar, szRegString, (dwRegValueSize /sizeof(WCHAR)));
|
||
pNextChar += dwRegValueSize / sizeof (WCHAR);
|
||
}
|
||
dwRemainingSize -= dwRegValueSize / (sizeof(WCHAR) / dwCharSize);
|
||
} else if (*pdwBufferSize >= sizeof(PDH_LOG_SERVICE_QUERY_INFO_W)) {
|
||
// no room for this string, but keep the required
|
||
// total;
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->szBaseFileName = NULL;
|
||
} else {
|
||
// it's an empty buffer
|
||
}
|
||
} else {
|
||
if (*pdwBufferSize >= sizeof(PDH_LOG_SERVICE_QUERY_INFO_W)) {
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->szBaseFileName = NULL;
|
||
}
|
||
}
|
||
|
||
// if the filename doesn't specify a directory, then use the
|
||
lstrcpyW (szTempFilePath, szRegString);
|
||
|
||
_wsplitpath ((LPCWSTR)szTempFilePath, szDriveName, szRegString,
|
||
NULL, NULL);
|
||
if ((lstrlenW(szDriveName) == 0) && (lstrlenW(szRegString) == 0)) {
|
||
// default log file directory
|
||
dwRegValType = 0;
|
||
dwRegValueSize = MAX_PATH * sizeof(WCHAR);
|
||
memset (szRegString, 0, dwRegValueSize);
|
||
lStatus = RegQueryValueExW (
|
||
hKeyLogQuery,
|
||
cszLogDefaultDir,
|
||
NULL,
|
||
&dwRegValType,
|
||
(LPBYTE)&szRegString[0],
|
||
&dwRegValueSize);
|
||
|
||
} else {
|
||
// the file parsing function leaves the trailing backslash
|
||
// so remove it before concatenating it.
|
||
dwSize = lstrlenW(szRegString);
|
||
if (dwSize > 0) {
|
||
if (szRegString[dwSize-1] == L'\\') {
|
||
szRegString[dwSize-1] = 0;
|
||
}
|
||
lStatus = ERROR_SUCCESS;
|
||
dwRegValType = REG_SZ;
|
||
dwRegValueSize = dwSize;
|
||
} else {
|
||
lStatus = ERROR_FILE_NOT_FOUND;
|
||
}
|
||
}
|
||
|
||
if ((lStatus == ERROR_SUCCESS) && (dwRegValType == REG_SZ)) {
|
||
dwRequiredSize += dwRegValueSize / (sizeof(WCHAR) / dwCharSize);
|
||
if (dwRequiredSize <= *pdwBufferSize) {
|
||
if (bWideChar) {
|
||
// copy widestrings
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->szDefaultDir = pNextWideChar;
|
||
lstrcpyW (pNextWideChar, szRegString);
|
||
pNextWideChar += dwRegValueSize / sizeof (WCHAR);
|
||
} else {
|
||
// convert to ansi char
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_A)pInfoBuffer)->szDefaultDir = pNextChar;
|
||
wcstombs (pNextChar, szRegString, (dwRegValueSize /sizeof(WCHAR)));
|
||
pNextChar += dwRegValueSize / sizeof (WCHAR);
|
||
}
|
||
dwRemainingSize -= dwRegValueSize / (sizeof(WCHAR) / dwCharSize);
|
||
} else if (*pdwBufferSize >= sizeof(PDH_LOG_SERVICE_QUERY_INFO_W)) {
|
||
// no room for this string, but keep the required
|
||
// total;
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->szDefaultDir = NULL;
|
||
} else {
|
||
// no buffer for this
|
||
}
|
||
} else {
|
||
if (*pdwBufferSize >= sizeof(PDH_LOG_SERVICE_QUERY_INFO_W)) {
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->szDefaultDir = NULL;
|
||
}
|
||
}
|
||
} else {
|
||
// get values for controls
|
||
dwRegValType = 0;
|
||
dwRegValueSize = MAX_PATH * sizeof(WCHAR);
|
||
memset (szRegString, 0, dwRegValueSize);
|
||
lStatus = RegQueryValueExW (
|
||
hKeyLogQuery,
|
||
cszLogDefaultDir,
|
||
NULL,
|
||
&dwRegValType,
|
||
(LPBYTE)&szRegString[0],
|
||
&dwRegValueSize);
|
||
|
||
if ((lStatus == ERROR_SUCCESS) && (dwRegValType == REG_SZ)) {
|
||
dwRequiredSize += dwRegValueSize / (sizeof(WCHAR) / dwCharSize);
|
||
if (dwRequiredSize <= *pdwBufferSize) {
|
||
if (bWideChar) {
|
||
// copy widestrings
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->szDefaultDir = pNextWideChar;
|
||
lstrcpyW (pNextWideChar, szRegString);
|
||
pNextWideChar += dwRegValueSize / sizeof (WCHAR);
|
||
} else {
|
||
// convert to ansi char
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_A)pInfoBuffer)->szDefaultDir = pNextChar;
|
||
wcstombs (pNextChar, szRegString, (dwRegValueSize/sizeof(WCHAR)));
|
||
pNextChar += dwRegValueSize / sizeof (WCHAR);
|
||
}
|
||
dwRemainingSize -= dwRegValueSize / (sizeof(WCHAR) / dwCharSize);
|
||
} else if (*pdwBufferSize >= sizeof(PDH_LOG_SERVICE_QUERY_INFO_W)) {
|
||
// no room for this string, but keep the required
|
||
// total;
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->szDefaultDir = NULL;
|
||
} else {
|
||
// no room for anything
|
||
}
|
||
} else {
|
||
if (*pdwBufferSize >= sizeof(PDH_LOG_SERVICE_QUERY_INFO_W)) {
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->szDefaultDir = NULL;
|
||
}
|
||
}
|
||
|
||
// base filename
|
||
dwRegValType = 0;
|
||
dwRegValueSize = MAX_PATH * sizeof(WCHAR);
|
||
memset (szRegString, 0, dwRegValueSize);
|
||
lStatus = RegQueryValueExW (
|
||
hKeyLogQuery,
|
||
cszBaseFileName,
|
||
NULL,
|
||
&dwRegValType,
|
||
(LPBYTE)&szRegString[0],
|
||
&dwRegValueSize);
|
||
|
||
|
||
if ((lStatus == ERROR_SUCCESS) && (dwRegValType == REG_SZ)) {
|
||
dwRequiredSize += dwRegValueSize / (sizeof(WCHAR) / dwCharSize);
|
||
if (dwRequiredSize <= *pdwBufferSize) {
|
||
if (bWideChar) {
|
||
// copy widestrings
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->szBaseFileName = pNextWideChar;
|
||
lstrcpyW (pNextWideChar, szRegString);
|
||
pNextWideChar += dwRegValueSize / sizeof (WCHAR);
|
||
} else {
|
||
// convert to ansi char
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_A)pInfoBuffer)->szBaseFileName = pNextChar;
|
||
wcstombs (pNextChar, szRegString, (dwRegValueSize/sizeof(WCHAR)));
|
||
pNextChar += dwRegValueSize / sizeof (WCHAR);
|
||
}
|
||
dwRemainingSize -= dwRegValueSize / (sizeof(WCHAR) / dwCharSize);
|
||
} else if (*pdwBufferSize >= sizeof(PDH_LOG_SERVICE_QUERY_INFO_W)) {
|
||
// no room for this string, but keep the required
|
||
// total;
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->szBaseFileName = NULL;
|
||
} else {
|
||
// no buffer
|
||
}
|
||
} else {
|
||
if (*pdwBufferSize >= sizeof(PDH_LOG_SERVICE_QUERY_INFO_W)) {
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->szBaseFileName = NULL;
|
||
}
|
||
}
|
||
|
||
// get auto name format
|
||
dwRegValType = 0;
|
||
dwRegValue = 0;
|
||
dwRegValueSize = sizeof(DWORD);
|
||
lStatus = RegQueryValueExW (
|
||
hKeyLogQuery,
|
||
cszLogFileAutoFormat,
|
||
NULL,
|
||
&dwRegValType,
|
||
(LPBYTE)&dwRegValue,
|
||
&dwRegValueSize);
|
||
|
||
if (*pdwBufferSize >= sizeof(PDH_LOG_SERVICE_QUERY_INFO_W)) {
|
||
if ((lStatus == ERROR_SUCCESS) && (dwRegValType == REG_DWORD)) {
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->PdlAutoNameFormat = dwRegValue;
|
||
} else {
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->PdlAutoNameFormat = PDH_LOGSVC_NAME_UNDEFINED;
|
||
}
|
||
}
|
||
|
||
dwRegValType = 0;
|
||
dwRegValue = 0;
|
||
dwRegValueSize = sizeof(DWORD);
|
||
lStatus = RegQueryValueExW (
|
||
hKeyLogQuery,
|
||
cszAutoRenameUnits,
|
||
NULL,
|
||
&dwRegValType,
|
||
(LPBYTE)&dwRegValue,
|
||
&dwRegValueSize);
|
||
|
||
if (*pdwBufferSize >= sizeof(PDH_LOG_SERVICE_QUERY_INFO_W)) {
|
||
if ((lStatus == ERROR_SUCCESS) && (dwRegValType == REG_DWORD)) {
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->PdlAutoNameUnits = dwRegValue;
|
||
} else {
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->PdlAutoNameUnits = PDH_LOGSVC_RENAME_UNDEFINED;
|
||
}
|
||
}
|
||
|
||
dwRegValType = 0;
|
||
dwRegValueSize = MAX_PATH * sizeof(WCHAR);
|
||
memset (szRegString, 0, dwRegValueSize);
|
||
lStatus = RegQueryValueExW (
|
||
hKeyLogQuery,
|
||
cszCommandFile,
|
||
NULL,
|
||
&dwRegValType,
|
||
(LPBYTE)&szRegString[0],
|
||
&dwRegValueSize);
|
||
|
||
if ((lStatus == ERROR_SUCCESS) && (dwRegValType == REG_SZ)) {
|
||
dwRequiredSize += dwRegValueSize / (sizeof(WCHAR) / dwCharSize);
|
||
if (dwRequiredSize <= *pdwBufferSize) {
|
||
if (bWideChar) {
|
||
// copy widestrings
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->PdlCommandFilename = pNextWideChar;
|
||
lstrcpyW (pNextWideChar, szRegString);
|
||
pNextWideChar += dwRegValueSize / sizeof (WCHAR);
|
||
} else {
|
||
// convert to ansi char
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_A)pInfoBuffer)->PdlCommandFilename = pNextChar;
|
||
wcstombs (pNextChar, szRegString, (dwRegValueSize/sizeof(WCHAR)));
|
||
pNextChar += dwRegValueSize / sizeof (WCHAR);
|
||
}
|
||
dwRemainingSize -= dwRegValueSize / (sizeof(WCHAR) / dwCharSize);
|
||
} else if (*pdwBufferSize >= sizeof(PDH_LOG_SERVICE_QUERY_INFO_W)) {
|
||
// no room for this string, but keep the required
|
||
// total;
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->PdlCommandFilename = NULL;
|
||
} else {
|
||
// no buffer
|
||
}
|
||
} else {
|
||
if (*pdwBufferSize >= sizeof(PDH_LOG_SERVICE_QUERY_INFO_W)) {
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->PdlCommandFilename = NULL;
|
||
}
|
||
}
|
||
}
|
||
|
||
// get counter string!
|
||
|
||
// find out buffer size required
|
||
dwRegValType = 0;
|
||
dwRegValue = 0;
|
||
dwRegValueSize = 0;
|
||
lStatus = RegQueryValueExW (
|
||
hKeyLogQuery,
|
||
cszCounterList,
|
||
NULL,
|
||
&dwRegValType,
|
||
NULL,
|
||
&dwRegValueSize);
|
||
|
||
if (dwRegValueSize > 0) {
|
||
// there's room in the caller's buffer so go ahead and
|
||
// fill it
|
||
dwRequiredSize += dwRegValueSize / (sizeof(WCHAR) / dwCharSize);
|
||
if (dwRequiredSize <= *pdwBufferSize) {
|
||
|
||
dwRegValueSize = dwRemainingSize;
|
||
dwRegValType = 0;
|
||
dwRegValue = 0;
|
||
if (bWideChar) {
|
||
lStatus = RegQueryValueExW (
|
||
hKeyLogQuery,
|
||
cszCounterList,
|
||
NULL,
|
||
&dwRegValType,
|
||
(LPBYTE)pNextWideChar,
|
||
&dwRegValueSize);
|
||
|
||
if (lStatus == ERROR_SUCCESS) {
|
||
// assign pointer to buffer
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->PdlCounterList = pNextWideChar;
|
||
pNextWideChar += dwRegValueSize / sizeof (WCHAR);
|
||
dwRemainingSize -= dwRegValueSize;
|
||
} else {
|
||
// assign null pointer
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->PdlCounterList = NULL;
|
||
}
|
||
} else {
|
||
lStatus = RegQueryValueExA (
|
||
hKeyLogQuery,
|
||
caszCounterList,
|
||
NULL,
|
||
&dwRegValType,
|
||
(LPBYTE)pNextChar,
|
||
&dwRegValueSize);
|
||
|
||
if (lStatus == ERROR_SUCCESS) {
|
||
// assign pointer to buffer
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_A)pInfoBuffer)->PdlCounterList = pNextChar;
|
||
pNextChar += dwRegValueSize;
|
||
dwRemainingSize -= dwRegValueSize;
|
||
} else {
|
||
// assign null pointer
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_A)pInfoBuffer)->PdlCounterList = NULL;
|
||
}
|
||
}
|
||
} else {
|
||
// no room so don't copy anything
|
||
}
|
||
} else if (*pdwBufferSize >= sizeof(PDH_LOG_SERVICE_QUERY_INFO_W)) {
|
||
// no counters defined so return NULL
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->PdlCounterList = NULL;
|
||
} else {
|
||
// no buffer
|
||
}
|
||
} //end if registry opened ok
|
||
|
||
// close open registry keys
|
||
|
||
if (hKeyMachine != NULL) RegCloseKey (hKeyMachine);
|
||
if (hKeyLogSettings != NULL) RegCloseKey (hKeyLogSettings);
|
||
if (hKeyLogQuery != NULL) RegCloseKey (hKeyLogQuery);
|
||
|
||
// test to see if the buffer estimate and pointer location line up
|
||
// assuming it was big enough in the first place
|
||
assert ((dwRequiredSize <= *pdwBufferSize) ?
|
||
((pNextChar != NULL) ? (dwRequiredSize == ((DWORD)pNextChar - (DWORD)pInfoBuffer)) :
|
||
(dwRequiredSize == ((DWORD)pNextWideChar - (DWORD)pInfoBuffer))) : TRUE);
|
||
|
||
if (lStatus == ERROR_SUCCESS) {
|
||
if (*pdwBufferSize >= sizeof(PDH_LOG_SERVICE_QUERY_INFO_W)) {
|
||
// if there's enough buffer to write this...
|
||
if (*pdwBufferSize >= dwRequiredSize) {
|
||
// and there was enough for the requested data
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->dwSize = dwRequiredSize;
|
||
} else {
|
||
// return the amount used
|
||
((PPDH_LOG_SERVICE_QUERY_INFO_W)pInfoBuffer)->dwSize = *pdwBufferSize;
|
||
}
|
||
}
|
||
}
|
||
|
||
// save required size
|
||
*pdwBufferSize = dwRequiredSize;
|
||
|
||
return pdhStatus;
|
||
}
|
||
|
||
PDH_FUNCTION
|
||
PdhLogServiceCommandA (
|
||
IN LPCSTR szMachineName,
|
||
IN LPCSTR szQueryName,
|
||
IN DWORD dwFlags,
|
||
IN LPDWORD pdwStatus
|
||
)
|
||
{
|
||
LPWSTR wszQueryName = NULL;
|
||
LPWSTR wszMachineName = NULL;
|
||
PDH_STATUS pdhStatus = ERROR_SUCCESS;
|
||
|
||
// test access to query name
|
||
|
||
if (szQueryName != NULL) {
|
||
DWORD dwNameLength = 0;
|
||
try {
|
||
CHAR cTest;
|
||
|
||
cTest = szQueryName[0];
|
||
dwNameLength = lstrlenA (szQueryName);
|
||
} except (EXCEPTION_EXECUTE_HANDLER) {
|
||
// unable to access name argument
|
||
pdhStatus = PDH_INVALID_ARGUMENT;
|
||
}
|
||
if (pdhStatus == ERROR_SUCCESS) {
|
||
// allocate wide name buffer
|
||
wszQueryName = G_ALLOC ((dwNameLength + 1) * sizeof (WCHAR));
|
||
if (wszQueryName != NULL) {
|
||
mbstowcs (wszQueryName, szQueryName, dwNameLength);
|
||
} else {
|
||
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
} else {
|
||
// make a null arg for the function
|
||
wszQueryName = NULL;
|
||
}
|
||
|
||
if ((szMachineName != NULL) && (pdhStatus == ERROR_SUCCESS)) {
|
||
DWORD dwNameLength = 0;
|
||
try {
|
||
CHAR cTest;
|
||
|
||
cTest = szMachineName[0];
|
||
dwNameLength = lstrlenA (szMachineName);
|
||
} except (EXCEPTION_EXECUTE_HANDLER) {
|
||
// unable to access name argument
|
||
pdhStatus = PDH_INVALID_ARGUMENT;
|
||
}
|
||
if (pdhStatus == ERROR_SUCCESS) {
|
||
// allocate wide name buffer
|
||
wszMachineName = G_ALLOC ((dwNameLength + 1) * sizeof (WCHAR));
|
||
if (wszMachineName != NULL) {
|
||
mbstowcs (wszMachineName, szMachineName, dwNameLength);
|
||
} else {
|
||
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
} else {
|
||
// make a null arg for the function
|
||
wszMachineName = NULL;
|
||
}
|
||
|
||
if (pdhStatus == ERROR_SUCCESS) {
|
||
// call wide string version
|
||
pdhStatus = PdhLogServiceCommandW (
|
||
wszMachineName,
|
||
wszQueryName,
|
||
dwFlags,
|
||
pdwStatus);
|
||
}
|
||
|
||
if (wszQueryName != NULL) G_FREE (wszQueryName);
|
||
if (wszMachineName != NULL) G_FREE (wszMachineName);
|
||
|
||
return pdhStatus;
|
||
}
|
||
|
||
PDH_FUNCTION
|
||
PdhLogServiceCommandW (
|
||
IN LPCWSTR szMachineName,
|
||
IN LPCWSTR szQueryName,
|
||
IN DWORD dwFlags,
|
||
IN LPDWORD pdwStatus
|
||
)
|
||
{
|
||
SC_HANDLE hSC = NULL;
|
||
SC_HANDLE hService = NULL;
|
||
SERVICE_STATUS ssData;
|
||
DWORD dwTimeout;
|
||
DWORD dwStatus;
|
||
BOOL bStopped = FALSE;
|
||
BOOL bPaused = FALSE;
|
||
LONG lStatus = ERROR_SUCCESS;
|
||
BOOL bWait;
|
||
LPWSTR szLocalQueryName = NULL;
|
||
|
||
// test arguments
|
||
try {
|
||
WCHAR wcTest;
|
||
DWORD dwTest;
|
||
|
||
if (szMachineName != NULL) {
|
||
wcTest = szMachineName[0];
|
||
} // null is valid for the local machine
|
||
|
||
if (szQueryName != NULL) {
|
||
wcTest = szQueryName[0];
|
||
} // null is a valid query name.
|
||
|
||
if (pdwStatus != NULL) {
|
||
dwTest = *pdwStatus;
|
||
*pdwStatus = 0;
|
||
*pdwStatus = dwTest;
|
||
}
|
||
} except (EXCEPTION_EXECUTE_HANDLER) {
|
||
lStatus = PDH_INVALID_ARGUMENT;
|
||
}
|
||
|
||
if (lStatus == ERROR_SUCCESS) {
|
||
if ((dwFlags & PDH_LOGSVC_TRACE_LOG) == PDH_LOGSVC_TRACE_LOG) {
|
||
lStatus = PDH_NOT_IMPLEMENTED;
|
||
} else {
|
||
// this must be a perf log command
|
||
// open SC database
|
||
hSC = OpenSCManagerW (szMachineName, NULL, SC_MANAGER_ALL_ACCESS);
|
||
|
||
if (hSC == NULL) {
|
||
// open service
|
||
hService = OpenServiceW (hSC, cszPerfDataLog,
|
||
SERVICE_START | SERVICE_STOP | SERVICE_USER_DEFINED_CONTROL);
|
||
} // else hService will still be NULL so get the last error below
|
||
|
||
if (hService != NULL) {
|
||
// determine wait flag value
|
||
bWait = (dwFlags & PDH_LOGSVC_NO_WAIT) ? FALSE : TRUE;
|
||
|
||
if (szQueryName == NULL) {
|
||
if ((dwFlags & PDH_LOGSVC_ALL_QUERIES) == PDH_LOGSVC_ALL_QUERIES) {
|
||
// start / stop the service and all log queries
|
||
if ((dwFlags & PDH_LOGSVC_CMD_START) == PDH_LOGSVC_CMD_START) {
|
||
// start the service and start all logs set to run
|
||
StartService (hService, 0, NULL);
|
||
if ( bWait ) {
|
||
// wait for the service to start before returning
|
||
dwTimeout = 20;
|
||
while (dwTimeout) {
|
||
GetCurrentServiceState (hService, &bStopped, &bPaused);
|
||
if (bStopped) {
|
||
Sleep(500);
|
||
} else {
|
||
break;
|
||
}
|
||
--dwTimeout;
|
||
}
|
||
if (bStopped) {
|
||
dwStatus = PDH_LOGSVC_STATUS_STOPPED;
|
||
} else if (bPaused) {
|
||
dwStatus = PDH_LOGSVC_STATUS_PAUSED;
|
||
} else {
|
||
dwStatus = PDH_LOGSVC_STATUS_RUNNING;
|
||
}
|
||
} else {
|
||
dwStatus = PDH_LOGSVC_STATUS_PENDING;
|
||
}
|
||
|
||
} else if ((dwFlags & PDH_LOGSVC_CMD_STOP) == PDH_LOGSVC_CMD_STOP) {
|
||
ControlService (hService, SERVICE_CONTROL_STOP, &ssData);
|
||
if ( bWait ) {
|
||
// wait for the service to stop before returning
|
||
dwTimeout = 20;
|
||
while (dwTimeout) {
|
||
GetCurrentServiceState (hService, &bStopped, &bPaused);
|
||
if (!bStopped) {
|
||
Sleep(500);
|
||
} else {
|
||
break;
|
||
}
|
||
--dwTimeout;
|
||
}
|
||
if (bStopped) {
|
||
dwStatus = PDH_LOGSVC_STATUS_STOPPED;
|
||
} else if (bPaused) {
|
||
dwStatus = PDH_LOGSVC_STATUS_PAUSED;
|
||
} else {
|
||
dwStatus = PDH_LOGSVC_STATUS_RUNNING;
|
||
}
|
||
}
|
||
} else {
|
||
// unknown operation
|
||
lStatus = PDH_UNKNOWN_LOGSVC_COMMAND;
|
||
}
|
||
} else {
|
||
// this is just a generic log command.
|
||
szLocalQueryName = (LPWSTR)cszDefault;
|
||
}
|
||
}
|
||
|
||
if (szLocalQueryName != NULL) {
|
||
// then this command is for a named service
|
||
lStatus = PdhiSetLogQueryState (
|
||
szMachineName,
|
||
szLocalQueryName,
|
||
(dwFlags & (PDH_LOGSVC_CMD_START | PDH_LOGSVC_CMD_STOP)));
|
||
if (lStatus == ERROR_SUCCESS) {
|
||
// service entry was updated to desired status
|
||
|
||
if (!ControlService (hService,
|
||
SERVICE_CONTROL_PARAMCHANGE, &ssData)) {
|
||
lStatus = GetLastError ();
|
||
}
|
||
lStatus = PdhiGetLogQueryState (
|
||
hService, szMachineName,
|
||
szLocalQueryName, &dwStatus);
|
||
}
|
||
}
|
||
|
||
|
||
CloseServiceHandle (hService);
|
||
} else {
|
||
lStatus = GetLastError();
|
||
assert (lStatus != 0);
|
||
}
|
||
// close handles
|
||
if (hSC != NULL) CloseServiceHandle (hSC);
|
||
}
|
||
}
|
||
|
||
return lStatus;
|
||
|
||
}
|
||
|
||
PDH_FUNCTION
|
||
PdhLogServiceControlA (
|
||
IN LPCSTR szMachineName,
|
||
IN LPCSTR szQueryName,
|
||
IN DWORD dwFlags,
|
||
IN PPDH_LOG_SERVICE_QUERY_INFO_A pInfoBuffer,
|
||
IN LPDWORD pdwBufferSize
|
||
)
|
||
{
|
||
LPWSTR wszQueryName = NULL;
|
||
LPWSTR wszMachineName = NULL;
|
||
PDH_STATUS pdhStatus = ERROR_SUCCESS;
|
||
DWORD dwCmdFn;
|
||
|
||
// test access to query name
|
||
|
||
if (szQueryName != NULL) {
|
||
DWORD dwNameLength = 0;
|
||
try {
|
||
CHAR cTest;
|
||
|
||
cTest = szQueryName[0];
|
||
dwNameLength = lstrlenA (szQueryName);
|
||
} except (EXCEPTION_EXECUTE_HANDLER) {
|
||
// unable to access name argument
|
||
pdhStatus = PDH_INVALID_ARGUMENT;
|
||
}
|
||
if (pdhStatus == ERROR_SUCCESS) {
|
||
// allocate wide name buffer
|
||
wszQueryName = G_ALLOC ((dwNameLength + 1) * sizeof (WCHAR));
|
||
if (wszQueryName != NULL) {
|
||
mbstowcs (wszQueryName, szQueryName, dwNameLength);
|
||
} else {
|
||
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
} else {
|
||
// make a null arg for the function
|
||
wszQueryName = NULL;
|
||
}
|
||
|
||
if ((szMachineName != NULL) && (pdhStatus == ERROR_SUCCESS)) {
|
||
DWORD dwNameLength = 0;
|
||
try {
|
||
CHAR cTest;
|
||
|
||
cTest = szMachineName[0];
|
||
dwNameLength = lstrlenA (szMachineName);
|
||
} except (EXCEPTION_EXECUTE_HANDLER) {
|
||
// unable to access name argument
|
||
pdhStatus = PDH_INVALID_ARGUMENT;
|
||
}
|
||
if (pdhStatus == ERROR_SUCCESS) {
|
||
// allocate wide name buffer
|
||
wszMachineName = G_ALLOC ((dwNameLength + 1) * sizeof (WCHAR));
|
||
if (wszMachineName != NULL) {
|
||
mbstowcs (wszMachineName, szMachineName, dwNameLength);
|
||
} else {
|
||
pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
|
||
}
|
||
}
|
||
} else {
|
||
// make a null arg for the function
|
||
wszMachineName = NULL;
|
||
}
|
||
|
||
if (pdhStatus == ERROR_SUCCESS) {
|
||
try {
|
||
DWORD dwTest;
|
||
|
||
if (pdwBufferSize != NULL) {
|
||
dwTest = *pdwBufferSize;
|
||
*pdwBufferSize = 0;
|
||
*pdwBufferSize = dwTest;
|
||
} else {
|
||
// null is NOT valid
|
||
pdhStatus = PDH_INVALID_ARGUMENT;
|
||
}
|
||
} except (EXCEPTION_EXECUTE_HANDLER) {
|
||
pdhStatus = PDH_INVALID_ARGUMENT;
|
||
}
|
||
}
|
||
|
||
if (pdhStatus == ERROR_SUCCESS) {
|
||
// dispatch to "action" function based on command code
|
||
dwCmdFn = dwFlags & PDH_LOGSVC_CTRL_FNMASK;
|
||
switch (dwCmdFn) {
|
||
case PDH_LOGSVC_CTRL_ADD:
|
||
// call universal string version
|
||
pdhStatus = PdhiLogServiceAddCommandT (
|
||
wszMachineName,
|
||
wszQueryName,
|
||
dwFlags,
|
||
(LPVOID)pInfoBuffer,
|
||
pdwBufferSize,
|
||
FALSE);
|
||
break;
|
||
|
||
case PDH_LOGSVC_CTRL_REMOVE:
|
||
// call universal string version
|
||
pdhStatus = PdhiLogServiceRemoveCommandT (
|
||
wszMachineName,
|
||
wszQueryName,
|
||
dwFlags,
|
||
(LPVOID)pInfoBuffer,
|
||
pdwBufferSize,
|
||
FALSE);
|
||
break;
|
||
|
||
case PDH_LOGSVC_CTRL_INFO:
|
||
// call universal string version
|
||
pdhStatus = PdhiLogServiceInfoCommandT (
|
||
wszMachineName,
|
||
wszQueryName,
|
||
dwFlags,
|
||
(LPVOID)pInfoBuffer,
|
||
pdwBufferSize,
|
||
FALSE);
|
||
break;
|
||
|
||
default:
|
||
pdhStatus = PDH_INVALID_ARGUMENT;
|
||
break;
|
||
}
|
||
|
||
}
|
||
|
||
if (wszQueryName != NULL) G_FREE (wszQueryName);
|
||
if (wszMachineName != NULL) G_FREE (wszMachineName);
|
||
|
||
return pdhStatus;
|
||
}
|
||
|
||
PDH_FUNCTION
|
||
PdhLogServiceControlW (
|
||
IN LPCWSTR szMachineName,
|
||
IN LPCWSTR szQueryName,
|
||
IN DWORD dwFlags,
|
||
IN PPDH_LOG_SERVICE_QUERY_INFO_W pInfoBuffer,
|
||
IN LPDWORD pdwBufferSize
|
||
)
|
||
{
|
||
PDH_STATUS pdhStatus = ERROR_SUCCESS;
|
||
DWORD dwCmdFn;
|
||
|
||
// test access to query name
|
||
|
||
if (szQueryName != NULL) {
|
||
WCHAR cTest;
|
||
try {
|
||
cTest = szQueryName[0];
|
||
if (cTest == 0) {
|
||
pdhStatus = PDH_INVALID_ARGUMENT;
|
||
}
|
||
} except (EXCEPTION_EXECUTE_HANDLER) {
|
||
// unable to access name argument
|
||
pdhStatus = PDH_INVALID_ARGUMENT;
|
||
}
|
||
} else {
|
||
// NULL is OK
|
||
}
|
||
|
||
// test access to machine name
|
||
|
||
if ((szMachineName != NULL) && (pdhStatus == ERROR_SUCCESS)) {
|
||
WCHAR cTest;
|
||
try {
|
||
cTest = szMachineName[0];
|
||
if (cTest == 0) {
|
||
pdhStatus = PDH_INVALID_ARGUMENT;
|
||
}
|
||
} except (EXCEPTION_EXECUTE_HANDLER) {
|
||
// unable to access name argument
|
||
pdhStatus = PDH_INVALID_ARGUMENT;
|
||
}
|
||
} else {
|
||
// NULL is OK
|
||
}
|
||
|
||
if (pdhStatus == ERROR_SUCCESS) {
|
||
try {
|
||
DWORD dwTest;
|
||
|
||
if (pdwBufferSize != NULL) {
|
||
dwTest = *pdwBufferSize;
|
||
*pdwBufferSize = 0;
|
||
*pdwBufferSize = dwTest;
|
||
} else {
|
||
// null is NOT valid
|
||
pdhStatus = PDH_INVALID_ARGUMENT;
|
||
}
|
||
} except (EXCEPTION_EXECUTE_HANDLER) {
|
||
pdhStatus = PDH_INVALID_ARGUMENT;
|
||
}
|
||
}
|
||
|
||
if (pdhStatus == ERROR_SUCCESS) {
|
||
// dispatch to "action" function based on command code
|
||
dwCmdFn = dwFlags & PDH_LOGSVC_CTRL_FNMASK;
|
||
switch (dwCmdFn) {
|
||
case PDH_LOGSVC_CTRL_ADD:
|
||
// call universal string version
|
||
pdhStatus = PdhiLogServiceAddCommandT (
|
||
szMachineName,
|
||
szQueryName,
|
||
dwFlags,
|
||
(LPVOID)pInfoBuffer,
|
||
pdwBufferSize,
|
||
TRUE);
|
||
break;
|
||
|
||
case PDH_LOGSVC_CTRL_REMOVE:
|
||
// call universal string version
|
||
pdhStatus = PdhiLogServiceRemoveCommandT (
|
||
szMachineName,
|
||
szQueryName,
|
||
dwFlags,
|
||
(LPVOID)pInfoBuffer,
|
||
pdwBufferSize,
|
||
TRUE);
|
||
break;
|
||
|
||
case PDH_LOGSVC_CTRL_INFO:
|
||
// call universal string version
|
||
pdhStatus = PdhiLogServiceInfoCommandT (
|
||
szMachineName,
|
||
szQueryName,
|
||
dwFlags,
|
||
(LPVOID)pInfoBuffer,
|
||
pdwBufferSize,
|
||
TRUE);
|
||
break;
|
||
|
||
default:
|
||
pdhStatus = PDH_INVALID_ARGUMENT;
|
||
break;
|
||
}
|
||
|
||
}
|
||
|
||
return pdhStatus;
|
||
}
|