/*++ Copyright (C) 1995-1999 Microsoft Corporation Module Name: log_ctrl.c Abstract: Log file control interface helper functions --*/ #include #include #include #include #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; }