Exemple #1
0
PDH_FUNCTION
PdhExpandCounterPathA (
    IN      LPCSTR  szWildCardPath,
    IN      LPSTR   mszExpandedPathList,
    IN      LPDWORD pcchPathListLength
)
{
    LPWSTR              szWideWildCardPath = NULL;
    DWORD               dwSize;
    PDH_STATUS          pdhStatus;

    __try {
        dwSize = lstrlenA (szWildCardPath);
        szWideWildCardPath = G_ALLOC (GPTR, ((dwSize+1) * sizeof (WCHAR)));
        if (szWideWildCardPath == NULL) {
            pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
        } else {
            mbstowcs (szWideWildCardPath, szWildCardPath, (dwSize+1));
            pdhStatus = PdhiExpandCounterPath (
                szWideWildCardPath,
                (LPVOID)mszExpandedPathList,
                pcchPathListLength,
                FALSE);
        }
    } __except (EXCEPTION_EXECUTE_HANDLER) {
        pdhStatus = PDH_INVALID_ARGUMENT;
    }

    if (szWideWildCardPath != NULL) G_FREE (szWideWildCardPath);

    return pdhStatus;
}
Exemple #2
0
static
PDH_STATUS
PdhiExpandCounterPath (
    IN      LPCWSTR szWildCardPath,
    IN      LPVOID  pExpandedPathList,
    IN      LPDWORD pcchPathListLength,
    IN      BOOL    bUnicode
)
{
    PPERF_MACHINE       pMachine;
    PPDHI_COUNTER_PATH  pWildCounterPath = NULL;
    WCHAR               szWorkBuffer[MAX_PATH];
    WCHAR               szCounterName[MAX_PATH];
    WCHAR               szInstanceName[MAX_PATH];
    LPWSTR              szEndOfObjectString;
    LPWSTR              szInstanceString;
    LPWSTR              szCounterString;
    LPVOID              szNextUserString;
    PERF_OBJECT_TYPE    *pObjectDef;
    PERF_OBJECT_TYPE    *pParentObjectDef;
    PERF_COUNTER_DEFINITION *pCounterDef;
    PERF_INSTANCE_DEFINITION *pInstanceDef;
    PERF_INSTANCE_DEFINITION *pParentInstanceDef;

    DWORD               dwBufferRemaining;
    DWORD               dwSize;
    DWORD               dwSizeReturned = 0;
    PDH_STATUS          pdhStatus = ERROR_SUCCESS;

    DWORD               dwCtrNdx, dwInstNdx;
    BOOL                bMoreData = FALSE;

    // allocate buffers
    pWildCounterPath = G_ALLOC (GPTR, PDHI_COUNTER_PATH_BUFFER_SIZE);

    if (pWildCounterPath == NULL) {
      // unable to allocate memory so bail out
      pdhStatus = PDH_MEMORY_ALLOCATION_FAILURE;
    } else {
      __try {
        dwBufferRemaining = *pcchPathListLength;
        szNextUserString = pExpandedPathList;
      } __except (EXCEPTION_EXECUTE_HANDLER) {
        pdhStatus = PDH_INVALID_ARGUMENT;
      }
    }

    if (pdhStatus == ERROR_SUCCESS) {
      // Parse wild card Path 
                  
      dwSize = G_SIZE (pWildCounterPath);
      if (ParseFullPathNameW (szWildCardPath, &dwSize, pWildCounterPath)) {
        // get the machine referenced in the path
        pMachine = GetMachine (pWildCounterPath->szMachineName, 0);
        if (pMachine != NULL) {
          if (wcsncmp (cszDoubleBackSlash, szWildCardPath, 2) == 0) {
            // the caller wants the machine name in the path so
            // copy it to the work buffer
            lstrcpyW (szWorkBuffer, pWildCounterPath->szMachineName);
          } else {
            *szWorkBuffer = 0;
          }
          // append the object name (since wild card objects are not
          // currently supported.

          lstrcatW (szWorkBuffer, cszBackSlash);
          lstrcatW (szWorkBuffer, pWildCounterPath->szObjectName);
          szEndOfObjectString = &szWorkBuffer[lstrlenW(szWorkBuffer)];
          
          // get object pointer (since objects are not wild)
          pObjectDef = GetObjectDefByName (
            pMachine->pSystemPerfData,
            pMachine->dwLastPerfString,
            pMachine->szPerfStrings,
            pWildCounterPath->szObjectName);

          if (pObjectDef != NULL) {
            // for each counters and identify matches
            pCounterDef = FirstCounter (pObjectDef);
            for (dwCtrNdx = 0; dwCtrNdx < pObjectDef->NumCounters; dwCtrNdx++) {
              // for each counter check instances (if supported) 
              //  and keep matches
              if ((pCounterDef->CounterNameTitleIndex > 0) &&
                  (pCounterDef->CounterNameTitleIndex < pMachine->dwLastPerfString ) &&
                  (!((pCounterDef->CounterType & PERF_DISPLAY_NOSHOW) &&
                     // this is a hack because this type is not defined correctly
                    (pCounterDef->CounterType != PERF_AVERAGE_BULK)))) {
                // look up name of each object & store size
                lstrcpyW (szCounterName,
                  pMachine->szPerfStrings[pCounterDef->CounterNameTitleIndex]);
                if (WildStringMatchW(pWildCounterPath->szCounterName, szCounterName)) {
                  // if this object has instances, then walk down
                  // the instance list and save any matches
                  if (pObjectDef->NumInstances != PERF_NO_INSTANCES) {
                    // then walk instances to find matches
                    pInstanceDef = FirstInstance (pObjectDef);
                    if (pObjectDef->NumInstances > 0) {
                      for (dwInstNdx = 0;
                        dwInstNdx < (DWORD)pObjectDef->NumInstances;
                        dwInstNdx++) {
                        szInstanceString = szEndOfObjectString;
                        if (pInstanceDef->ParentObjectTitleIndex > 0) {
                          // then add in parent instance name
                          pParentObjectDef = GetObjectDefByTitleIndex (
                            pMachine->pSystemPerfData,
                            pInstanceDef->ParentObjectTitleIndex);
                          if (pParentObjectDef != NULL) {
                            pParentInstanceDef = GetInstance (
                              pParentObjectDef,
                              pInstanceDef->ParentObjectInstance);
                            if (pParentInstanceDef != NULL) {
                              GetInstanceNameStr (pParentInstanceDef,
                                szInstanceName,
                                pObjectDef->CodePage);
                              if (WildStringMatchW (pWildCounterPath->szParentName, szInstanceName)) {
                                // add this string
                                szInstanceString = szEndOfObjectString;
                                lstrcpyW (szInstanceString, cszLeftParen);
                                lstrcatW (szInstanceString, szInstanceName);
                                lstrcatW (szInstanceString, cszSlash);
                              } else {
                                // get next instance and continue 
                                pInstanceDef = NextInstance(pInstanceDef);
                                continue;
                              }
                            } else {
                              // unable to locate parent instance
                              // so cancel this one, then 
                              // get next instance and continue 
                              pInstanceDef = NextInstance(pInstanceDef);
                              continue;
                            }
                          } else {
                            // unable to locate parent object
                            // so cancel this one, then 
                            // get next instance and continue 
                            pInstanceDef = NextInstance(pInstanceDef);
                            continue;
                          }
                        } else {
                          // no parent name so continue
                          szInstanceString = szEndOfObjectString;
                          lstrcpyW (szInstanceString, cszSlash);
                        }
                        GetInstanceNameStr (pInstanceDef,
                          szInstanceName,
                          pObjectDef->CodePage);

                        //
                        //  BUGBUG: need to do something with indexes.
                        //
                        // if this instance name matches, then keep it
                        if (WildStringMatchW (pWildCounterPath->szInstanceName, szInstanceName)) {
                          lstrcatW (szInstanceString, szInstanceName);
                          lstrcatW (szInstanceString, cszRightParenBackSlash);
                          // now append this counter name
                          lstrcatW (szInstanceString, szCounterName);

                          // add it to the user's buffer if there's room
                          dwSize = lstrlenW(szWorkBuffer) + 1;
                          if (!bMoreData && (dwSize  < dwBufferRemaining)) {
                            if (bUnicode) {
                                lstrcpyW ((LPWSTR)szNextUserString, szWorkBuffer);
                                (LPBYTE)szNextUserString += dwSize * sizeof(WCHAR);
                            } else {
                                wcstombs ((LPSTR)szNextUserString, szWorkBuffer, dwSize);
                                (LPBYTE)szNextUserString += dwSize * sizeof(CHAR);
                            }
                            dwSizeReturned += dwSize;
                            dwBufferRemaining -= dwSize;
                          } else {
                            // they've run out of buffer so just update the size required
                            bMoreData = TRUE;
                            dwSizeReturned += dwSize;
                          }
                        } else {
                          // they don't want this instance so skip it
                        }
                        pInstanceDef = NextInstance (pInstanceDef);
                      } // end for each instance in object
                    } else {
                      // this object supports instances, 
                      // but doesn't currently have any
                      // so do nothing.
                    }
                  } else {
                    // this object does not use instances so copy this
                    // counter to the caller's buffer.
                    szCounterString = szEndOfObjectString;
                    lstrcpyW (szCounterString, cszBackSlash);
                    lstrcatW (szCounterString, szCounterName);
                    dwSize = lstrlenW(szWorkBuffer) + 1;
                    if (!bMoreData && (dwSize  < dwBufferRemaining)) {
                      if (bUnicode) {
                        lstrcpyW ((LPWSTR)szNextUserString, szWorkBuffer);
                        (LPBYTE)szNextUserString += dwSize * sizeof(WCHAR);
                      } else {
                        wcstombs ((LPSTR)szNextUserString, szWorkBuffer, dwSize);
                        (LPBYTE)szNextUserString += dwSize * sizeof(CHAR);
                      }
                      dwSizeReturned += dwSize;
                      dwBufferRemaining -= dwSize;
                    } else {
                      // they've run out of buffer so bail out of this loop
                      bMoreData = TRUE;
                      dwSizeReturned += dwSize;
                    }
                  }
                } else {
                  // this counter doesn't match so skip it
                }
              } else {
                // this counter string is not available
              }
              pCounterDef = NextCounter(pCounterDef);
            } // end for each counter in this object
            if (bUnicode) {
                *(LPWSTR)szNextUserString = 0;  // MSZ terminator
            } else {
                *(LPSTR)szNextUserString = 0;  // MSZ terminator
            }
            *pcchPathListLength = dwSizeReturned;
            if (bMoreData) {
              pdhStatus = PDH_MORE_DATA;
            } else {
              pdhStatus = ERROR_SUCCESS;
            }
          } else {
            // unable to find object
            pdhStatus = PDH_INVALID_PATH;
          }
        } else {
          // unable to connect to machine.
          pdhStatus = PDH_CANNOT_CONNECT_MACHINE;
        }
      } else {
        // unable to read input path string
          pdhStatus = PDH_INVALID_PATH;
      }
    }

    if (pWildCounterPath != NULL) G_FREE (pWildCounterPath);

    return pdhStatus;
}
Exemple #3
0
PDH_FUNCTION
WriteTextLogHeader (
    IN  PLOG_INFO   pLog
)
{
    LONG      pdhStatus = ERROR_SUCCESS;
    PLOG_COUNTER_INFO   pThisCounter;
    CHAR            cDelim;
    CHAR            szLeadDelim[4];
    DWORD           dwLeadSize;
    CHAR            szTrailDelim[4];
    DWORD           dwTrailSize;
    DWORD           dwBytesWritten;
    PPDH_COUNTER_INFO_A  pCtrInfo;
    DWORD           dwCtrInfoSize;
    BOOL            bResult;

    pCtrInfo = G_ALLOC (8192);

    if (pCtrInfo == NULL) {
        return PDH_MEMORY_ALLOCATION_FAILURE;
    }

    cDelim = (LOWORD(pLog->dwLogFormat) == OPD_CSV_FILE) ? COMMA_DELIMITER :
            TAB_DELIMITER;

    szLeadDelim[0] = cDelim;
    szLeadDelim[1] = DOUBLE_QUOTE;
    szLeadDelim[2] = 0;
    szLeadDelim[3] = 0;
    dwLeadSize = 2;

    szTrailDelim[0] = DOUBLE_QUOTE;
    szTrailDelim[1] = 0;
    szTrailDelim[2] = 0;
    szTrailDelim[3] = 0;
    dwTrailSize = 1;


    // write the logfile header record
    bResult = WriteFile (pLog->hLogFileHandle,
        (LPCVOID)&szTrailDelim[0],
        1,
        &dwBytesWritten,
        NULL);

    if (!bResult) {
        pdhStatus = GetLastError();
    }

    if (pdhStatus == ERROR_SUCCESS) {
        // write the time stamp title
        bResult = WriteFile (pLog->hLogFileHandle,
            (LPCVOID)szTimeStampLabel,
            dwTimeStampLabelLength,
            &dwBytesWritten,
            NULL);

        if (!bResult) {
            pdhStatus = GetLastError();
        }
    }

    if (pdhStatus == ERROR_SUCCESS) {
        // check each counter in the list of counters for this query and
        // write them to the file

        // output the path names
        pThisCounter = pFirstCounter;

        if (pThisCounter != NULL) {
            do {
                // write  the leading delimiter
                bResult = WriteFile (pLog->hLogFileHandle,
                    (LPCVOID)szLeadDelim,
                    dwLeadSize,
                    &dwBytesWritten,
                    NULL);

                if (!bResult) {
                    pdhStatus = GetLastError();
                    break; // out of the Do Loop
                }

                // get the counter path information from the counter
                dwCtrInfoSize = 8192;
                pdhStatus = PdhGetCounterInfoA (
                    pThisCounter->hCounter,
                    FALSE,
                    &dwCtrInfoSize,
                    pCtrInfo);

                if (pdhStatus == ERROR_SUCCESS) {
                    // write the counter name
                    bResult = WriteFile (pLog->hLogFileHandle,
                        (LPCVOID)pCtrInfo->szFullPath,
                        lstrlen(pCtrInfo->szFullPath),
                        &dwBytesWritten,
                        NULL);

                    if (!bResult) {
                        pdhStatus = GetLastError();
                        break; // out of the Do Loop
                    }
                } else {
                    // unable to get counter information so bail here
                    break;
                }

                // write  the trailing delimiter
                bResult = WriteFile (pLog->hLogFileHandle,
                    (LPCVOID)szTrailDelim,
                    dwTrailSize,
                    &dwBytesWritten,
                    NULL);


                if (!bResult) {
                    pdhStatus = GetLastError();
                    break; // out of the Do Loop
                }

                pThisCounter = pThisCounter->next;
            } while (pThisCounter != NULL);
        }
    }

    if (pdhStatus == ERROR_SUCCESS) {
        // write  the record terminator
        bResult = WriteFile (pLog->hLogFileHandle,
            (LPCVOID)szRecordTerminator,
            dwRecordTerminatorLength,
            &dwBytesWritten,
            NULL);
        if (!bResult) {
            pdhStatus = GetLastError();
        }
    }

    G_FREE (pCtrInfo);

    return pdhStatus;
}
Exemple #4
0
static
DWORD
AddUniqueStringToMultiSz (
    IN  LPVOID  mszDest,
    IN  LPSTR   szSource,
    IN  BOOL    bUnicodeDest
)
/*++

Routine Description:

    searches the Multi-SZ list, mszDest for szSource and appends it
        to mszDest if it wasn't found

Arguments:

    OUT LPVOID  mszDest     Multi-SZ list to get new string
    IN  LPSTR   szSource    string to add if it's not already in list

ReturnValue:

    The new length of the destination string including both
    trailing NULL characters if the string was added, or 0 if the
    string is already in the list.

--*/
{
    LPVOID  szDestElem;
    DWORD   dwReturnLength;
    LPWSTR  wszSource = NULL;
    DWORD   dwLength;

    // check arguments

    if ((mszDest == NULL) || (szSource == NULL)) return 0; // invalid buffers
    if (*szSource == '\0') return 0;    // no source string to add

    // if unicode list, make a unicode copy of the string to compare
    // and ultimately copy if it's not already in the list

    if (bUnicodeDest) {
        dwLength = lstrlenA(szSource) + 1;
        wszSource = G_ALLOC (dwLength * sizeof(WCHAR));
        if (wszSource != NULL) {
            dwReturnLength = mbstowcs (wszSource, szSource, dwLength);
        } else {
            // unable to allocate memory for the temp string
            dwReturnLength = 0;
        }
    } else {
        // just use the ANSI version of the source file name
        dwReturnLength = 1;
    }

    if (dwReturnLength > 0) {
        // go to end of dest string
        //
        for (szDestElem = mszDest;
                (bUnicodeDest ? (*(LPWSTR)szDestElem != 0) :
                    (*(LPSTR)szDestElem != 0));
                ) {
            if (bUnicodeDest) {
                // bail out if string already in lsit
                if (lstrcmpiW((LPCWSTR)szDestElem, wszSource) == 0) {
                    return 0;
                } else {
                    // goto the next item
                    szDestElem = (LPVOID)((LPWSTR)szDestElem +
                        (lstrlenW((LPCWSTR)szDestElem)+1));
                }
            }  else {
                // bail out if string already in lsit
                if (lstrcmpiA((LPSTR)szDestElem, szSource) == 0) {
                    return 0;
                } else {
                    // goto the next item
                    szDestElem = (LPVOID)((LPSTR)szDestElem +
                        (lstrlenA((LPCSTR)szDestElem)+1));
                }
            }
        }

        // if here, then add string
        // szDestElem is at end of list

        if (bUnicodeDest) {
            lstrcpyW ((LPWSTR)szDestElem, wszSource);
            szDestElem = (LPVOID)((LPWSTR)szDestElem + lstrlenW(wszSource) + 1);
            *((LPWSTR)szDestElem)++ = L'\0';
            dwReturnLength = (DWORD)((LPWSTR)szDestElem - (LPWSTR)mszDest);
        } else {
            lstrcpyA ((LPSTR)szDestElem, szSource);
            szDestElem = (LPVOID)((LPSTR)szDestElem + lstrlenA(szDestElem) + 1);
            *((LPSTR)szDestElem)++ = '\0'; // add second NULL
            dwReturnLength = (DWORD)((LPSTR)szDestElem - (LPSTR)mszDest);
        }
    }

    return dwReturnLength;
}
Exemple #5
0
BOOL
LoggingProc (
    IN    LPLOG_THREAD_DATA pArg
)
{
    HQUERY          hQuery;
    HCOUNTER        hThisCounter;
    DWORD           dwDelay;
    DWORD           dwSampleInterval, dwSampleTime;
    PDH_STATUS      pdhStatus;
    DWORD           dwNumCounters;
    LONG            lStatus;
    TCHAR           szDefaultDir[MAX_PATH];
    TCHAR           szBaseName[MAX_PATH];

    LPTSTR          szThisPath;
    DWORD           dwLogType = OPD_CSV_FILE;
    BOOL            bRun = FALSE;
    DWORD           dwSamplesUntilNewFile;
    TCHAR           szCurrentLogFile[MAX_PATH];
    LONG            lWaitStatus;
    LPTSTR          szStringArray[4];
    DWORD           dwFileSizeLimit;
    LONGLONG        llFileSizeLimit;
    LONGLONG        llFileSize;
    PLOG_COUNTER_INFO   pCtrInfo;

    // read registry values

    if (!LoadDataFromRegistry (pArg, szDefaultDir, szBaseName, szCurrentLogFile)) {
        // unable to initialize the query from the registry
        return FALSE;
    }

    // convert to milliseconds for use in timeouts
    dwSampleInterval = pArg->dwTimeInterval * 1000L;

    // open query and add counters from info file

    pdhStatus = PdhOpenQuery (NULL, 0, &hQuery); // from current activity
    if (pdhStatus == ERROR_SUCCESS) {
        dwNumCounters = 0;
        for (szThisPath = pArg->mszCounterList;
            *szThisPath != 0;
            szThisPath += lstrlen(szThisPath) + 1) {
            pdhStatus = PdhAddCounter (hQuery, 
                (LPTSTR)szThisPath, dwNumCounters++, &hThisCounter);

            if (pdhStatus == ERROR_SUCCESS) {
                // then add this handle to the list
                pCtrInfo = G_ALLOC (sizeof (LOG_COUNTER_INFO));
                if (pCtrInfo != NULL) {
                    // insert at front of list since the order isn't 
                    // important and this is simpler than walking the 
                    // list each time.
                    pCtrInfo->hCounter = hThisCounter;
                    pCtrInfo->next = pFirstCounter;
                    pFirstCounter = pCtrInfo;
                }
            }
        }
    
        // to make sure we get to log the data
        SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_HIGHEST);

        bRun = TRUE;
        while (bRun) {
            // Get the current Log filename
            if (pArg->dwRenameIntervalCount != 0) {
                // then this is an autonamed file
                // so make current name
                BuildCurrentLogFileName (
                    szBaseName,
                    szDefaultDir,
                    szCurrentLogFile,
                    &pArg->dwCurrentSerialNumber,
                    pArg->dwAutoNameFormat,
                    pArg->dwLogType);
                // reset loop counter
                switch (pArg->dwRenameIntervalUnits) {
                case OPD_RENAME_KBYTES:
                    dwFileSizeLimit = pArg->dwRenameIntervalCount * 1024;
                    dwSamplesUntilNewFile = 0;
                    break;

                case OPD_RENAME_MBYTES:
                    dwFileSizeLimit = pArg->dwRenameIntervalCount * 1024 * 1024;
                    dwSamplesUntilNewFile = 0;
                    break;

                case OPD_RENAME_HOURS:
                case OPD_RENAME_DAYS:
                case OPD_RENAME_MONTHS:
                default:
                    dwSamplesUntilNewFile = GetSamplesInRenameInterval(
                        pArg->dwTimeInterval,
                        pArg->dwRenameIntervalCount,
                        pArg->dwRenameIntervalUnits);
                    dwFileSizeLimit = 0;
                    break;
                }
            } else {
                // filename is left as read from the registry
                dwSamplesUntilNewFile = 0;
                dwFileSizeLimit = 0;
            }
            llFileSizeLimit = dwFileSizeLimit;
            // open log file using this query
            dwLogType = pArg->dwLogType;
            pdhStatus = OpenLogW (
                szCurrentLogFile,
                LOG_WRITE_ACCESS | LOG_CREATE_ALWAYS,
                &dwLogType,
                hQuery,
                0);

            if (pdhStatus == ERROR_SUCCESS) {
                szStringArray[0] = pArg->szQueryName;
                szStringArray[1] = szCurrentLogFile;
                ReportEvent (hEventLog,
                    EVENTLOG_INFORMATION_TYPE,
                    0,
                    PERFLOG_LOGGING_QUERY,
                    NULL,
                    2,
                    0,
                    szStringArray,
                    NULL);
                // start sampling immediately
                dwDelay = 0;
                while ((lWaitStatus = WaitForSingleObject (pArg->hExitEvent, dwDelay)) == WAIT_TIMEOUT) {
                    // the event flag will be set when the sampling should exit. if 
                    // the wait times out, then that means it's time to collect and
                    // log another sample of data.
                    // the argument received the time it took to take the 
                    // sample so the delay can be adjusted accordingly
                    dwSampleTime = 0;
                    pdhStatus = UpdateLog (&dwSampleTime);

                    if (pdhStatus == ERROR_SUCCESS) {
                        // see if it's time to rename the file
                        if (dwSamplesUntilNewFile) {
                            if (!--dwSamplesUntilNewFile) break;
                        } else if (llFileSizeLimit) {
                            // see if the file is too big
                            pdhStatus = GetLogFileSize (&llFileSize);
                            if (pdhStatus == ERROR_SUCCESS) {
                                if (llFileSizeLimit <= llFileSize) break;
                            }
                        }
                        // compute new timeout value
                        if (dwSampleTime < dwSampleInterval) {
                            dwDelay = dwSampleInterval - dwSampleTime;
                        } else {
                            dwDelay = 0;
                        }
                    } else {
                        // unable to update the log so log event and exit
                        ReportEvent (hEventLog,
                            EVENTLOG_ERROR_TYPE,
                            0,
                            PERFLOG_UNABLE_UPDATE_LOG,
                            NULL,
                            0,
                            sizeof(DWORD),
                            NULL,
                            (LPVOID)&pdhStatus);

                        bRun = FALSE;
                        break;
                    }

                } // end while wait keeps timing out
                if (lWaitStatus == WAIT_OBJECT_0) {
                    // then the loop was terminated by the Exit event
                    // so clear the "run" flag to exit the loop & thread
                    bRun = FALSE;
                }
                CloseLog (0);

            } else {
                // unable to open log file so log event log message
                bRun = FALSE; // exit now
            }
        } // end while (bRun)
        PdhCloseQuery (hQuery);

        // update log serial number if necssary
        if (pArg->dwAutoNameFormat == OPD_NAME_NNNNNN) {
            lStatus = RegSetValueEx (
                pArg->hKeyQuery,
                TEXT("Log File Serial Number"),
                0L,
                REG_DWORD,
                (LPBYTE)&pArg->dwCurrentSerialNumber,
                sizeof(DWORD));
        }
    } else {
        // unable to open query so write event log message
    }
    
    return bRun;
}
Exemple #6
0
BOOL
LoadDataFromRegistry (
    IN  LPLOG_THREAD_DATA   pArg,
    IN  LPTSTR              szDefaultDir,
    IN  LPTSTR              szBaseName,
    IN  LPTSTR              szCurrentLogFile
)
{
    LONG            lStatus;
    DWORD           dwType;
    DWORD           dwSize;
    DWORD           dwData;
    LPTSTR          szStringArray[2];

    // get size of buffer required by counter list,
    // then allocate the buffer and retrieve the counter list

    dwType = 0;
    dwData = 0;
    dwSize = 0;
    lStatus = RegQueryValueEx (
        pArg->hKeyQuery,
        TEXT("Counter List"),
        NULL,
        &dwType,
        (LPBYTE)NULL,
        &dwSize);

    pArg->mszCounterList = (LPTSTR)G_ALLOC(dwSize);

    if (pArg->mszCounterList != NULL) {
        dwType = 0;
        lStatus = RegQueryValueEx (
            pArg->hKeyQuery,
            TEXT("Counter List"),
            NULL,
            &dwType,
            (LPBYTE)pArg->mszCounterList,
            &dwSize);

        if ((lStatus != ERROR_SUCCESS) || (dwSize == 0)) {
            // no counter list retrieved so there's not much
            // point in continuing
            szStringArray[0] = pArg->szQueryName;
            ReportEvent (hEventLog,
                EVENTLOG_ERROR_TYPE,
                0,
                PERFLOG_UNABLE_READ_COUNTER_LIST,
                NULL,
                1,
                sizeof(DWORD),
                szStringArray,
                (LPVOID)&lStatus);
            return FALSE;
        }
    } else {    
        szStringArray[0] = pArg->szQueryName;
        ReportEvent (hEventLog,
            EVENTLOG_ERROR_TYPE,
            0,
            PERFLOG_UNABLE_ALLOC_COUNTER_LIST,
            NULL,
            1,
            sizeof(DWORD),
            szStringArray,
            (LPVOID)&lStatus);
        return FALSE;
    }

    dwType = 0;
    dwData = 0;
    dwSize = sizeof(DWORD);
    lStatus = RegQueryValueEx (
        pArg->hKeyQuery,
        TEXT("Auto Name Interval"),
        NULL,
        &dwType,
        (LPBYTE)&dwData,
        &dwSize);
    if (lStatus != ERROR_SUCCESS) {
        dwData = 0; // default is no autonaming
    } else if (dwType != REG_DWORD) {
        dwData = 0; // default is no autonaming
    } // else assume success
    
    pArg->dwRenameIntervalCount = dwData;
    
    dwType = 0;
    dwData = 0;
    dwSize = sizeof(DWORD);
    lStatus = RegQueryValueEx (
        pArg->hKeyQuery,
        TEXT("Auto Rename Units"),
        NULL,
        &dwType,
        (LPBYTE)&dwData,
        &dwSize);
    if (lStatus != ERROR_SUCCESS) {
        dwData = OPD_RENAME_DAYS; // default is days
    } else if (dwType != REG_DWORD) {
        dwData = OPD_RENAME_DAYS; // default is days
    } // else assume success

    pArg->dwRenameIntervalUnits = dwData;

    dwType = 0;
    dwData = 0;
    dwSize = sizeof(DWORD);
    lStatus = RegQueryValueEx (
        pArg->hKeyQuery,
        TEXT("Log File Auto Format"),
        NULL,
        &dwType,
        (LPBYTE)&dwData,
        &dwSize);
    if (lStatus != ERROR_SUCCESS) {
        dwData = OPD_NAME_NNNNNN; // default is a serial number
    } else if (dwType != REG_DWORD) {
        dwData = OPD_NAME_NNNNNN; // default is a serial number
    } // else assume success

    pArg->dwAutoNameFormat = dwData;

    dwType = 0;
    dwData = 0;
    dwSize = sizeof(DWORD);
    lStatus = RegQueryValueEx (
        pArg->hKeyQuery,
        TEXT("Log File Type"),
        NULL,
        &dwType,
        (LPBYTE)&dwData,
        &dwSize);
    if (lStatus != ERROR_SUCCESS) {
        dwData = OPD_CSV_FILE; // default is a CSV file
    } else if (dwType != REG_DWORD) {
        dwData = OPD_CSV_FILE; // default is a CSV file
    } // else assume success

    pArg->dwLogType = dwData;

    dwType = 0;
    dwData = 0;
    dwSize = sizeof(DWORD);
    lStatus = RegQueryValueEx (
        pArg->hKeyQuery,
        TEXT("Sample Interval"),
        NULL,
        &dwType,
        (LPBYTE)&dwData,
        &dwSize);
    if (lStatus != ERROR_SUCCESS) {
        dwData = SECONDS_IN_MINUTE; // default is 1 Minute samples
    } else if (dwType != REG_DWORD) {
        dwData = SECONDS_IN_MINUTE; // default is 1 Minute samples
    } // else assume success

    pArg->dwTimeInterval = dwData;

    // get filename or components if auto name

    if (pArg->dwRenameIntervalCount > 0) {
        // this is an autoname file so get components
        dwType = 0;
        *szDefaultDir = 0;
        dwSize = MAX_PATH * sizeof(TCHAR);
        lStatus = RegQueryValueEx (
            pArg->hKeyQuery,
            TEXT("Log Default Directory"),
            NULL,
            &dwType,
            (LPBYTE)&szDefaultDir[0],
            &dwSize);
        if (lStatus != ERROR_SUCCESS) {
            *szDefaultDir = 0;
        } // else assume success

        dwType = 0;
        *szBaseName = 0;
        dwSize = MAX_PATH * sizeof(TCHAR);
        lStatus = RegQueryValueEx (
            pArg->hKeyQuery,
            TEXT("Base Filename"),
            NULL,
            &dwType,
            (LPBYTE)&szBaseName[0],
            &dwSize);
        if (lStatus != ERROR_SUCCESS) {
            // apply default
            lstrcpy (szBaseName, TEXT("perfdata"));
        } // else assume success
    } else {
        // this is a manual name file so read name
        dwType = 0;
        *szCurrentLogFile = 0;
        dwSize = MAX_PATH * sizeof(TCHAR);
        lStatus = RegQueryValueEx (
            pArg->hKeyQuery,
            TEXT("Log Filename"),
            NULL,
            &dwType,
            (LPBYTE)&szCurrentLogFile[0],
            &dwSize);
        if (lStatus != ERROR_SUCCESS) {
            // apply default
            lstrcpy (szCurrentLogFile, TEXT("c:\\perfdata.log"));
        } // else assume success
    }

    dwType = 0;
    dwData = 0;
    dwSize = sizeof(DWORD);
    lStatus = RegQueryValueEx (
        pArg->hKeyQuery,
        TEXT("Log File Serial Number"),
        NULL,
        &dwType,
        (LPBYTE)&dwData,
        &dwSize);
    if (lStatus != ERROR_SUCCESS) {
        dwData = 1; // default is to start at 1
    } else if (dwType != REG_DWORD) {
        dwData = 1; // default is to start at 1
    } // else assume success

    pArg->dwCurrentSerialNumber = dwData;
    return TRUE;
}
Exemple #7
0
void
PerfDataLogServiceStart (
    IN  DWORD   argc,
    IN  LPTSTR  *argv
)
{
    LONG                lStatus;
    HKEY                hKeyLogQueries;
    HKEY                hKeyThisLogQuery;
    DWORD               dwQueryIndex;
    TCHAR               szQueryNameBuffer[MAX_PATH];
    DWORD               dwQueryNameBufferSize;
    TCHAR               szQueryClassBuffer[MAX_PATH];
    DWORD               dwQueryClassBufferSize;
    LPLOG_THREAD_DATA   lpThreadData;
    HANDLE              hThread;
    LPTSTR              szStringArray[2];
    DWORD               dwThreadId;

    ssPerfLogStatus.dwServiceType       = SERVICE_WIN32_OWN_PROCESS;
    ssPerfLogStatus.dwCurrentState      = SERVICE_START_PENDING;
    ssPerfLogStatus.dwControlsAccepted  = SERVICE_ACCEPT_STOP |
//        SERVICE_ACCEPT_PAUSE_CONTINUE |
        SERVICE_ACCEPT_SHUTDOWN;
    ssPerfLogStatus.dwWin32ExitCode = 0;
    ssPerfLogStatus.dwServiceSpecificExitCode = 0;
    ssPerfLogStatus.dwCheckPoint = 0;
    ssPerfLogStatus.dwWaitHint = 0;

    hPerfLogStatus = RegisterServiceCtrlHandler (
        TEXT("PerfDataLog"), PerfDataLogServiceControlHandler);

    if (hPerfLogStatus == (SERVICE_STATUS_HANDLE)0) {
        lStatus = GetLastError();
        ReportEvent (hEventLog,
            EVENTLOG_ERROR_TYPE,
            0,
            PERFLOG_UNABLE_REGISTER_HANDLER,
            NULL,
            0,
            sizeof(DWORD),
            NULL,
            (LPVOID)&lStatus);
        // this is fatal so bail out
        return;
    }

    // registered the service successfully, so load the log queries
    // assign the handle buffer
    pThreadHandleArray = &LocalThreadArray[0];
    dwMaxHandleCount = LOCAL_HANDLE_COUNT;
    // open (each) query
    lStatus = RegOpenKeyEx (
        HKEY_LOCAL_MACHINE,
        TEXT("SYSTEM\\CurrentControlSet\\Services\\PerfDataLog\\Log Queries"),
        0L,
        KEY_READ,
        &hKeyLogQueries);

    if (lStatus != ERROR_SUCCESS) {
        // unable to read the log query information from the registry
        lStatus = GetLastError();
        ReportEvent (hEventLog,
            EVENTLOG_ERROR_TYPE,
            0,
            PERFLOG_UNABLE_OPEN_LOG_QUERY,
            NULL,
            0,
            sizeof(DWORD),
            NULL,
            (LPVOID)&lStatus);

        // we can't start the service with out the evnt log.
        ssPerfLogStatus.dwCurrentState    = SERVICE_STOPPED;
        SetServiceStatus (hPerfLogStatus, &ssPerfLogStatus);

        return;
    }

    // enumerate and start the queries in the registry
    dwQueryIndex = 0;
    *szQueryNameBuffer = 0;
    dwQueryNameBufferSize = MAX_PATH;
    *szQueryClassBuffer;
    dwQueryClassBufferSize = MAX_PATH;
    while ((lStatus = RegEnumKeyEx (
        hKeyLogQueries,
        dwQueryIndex,
        szQueryNameBuffer,
        &dwQueryNameBufferSize,
        NULL,
        szQueryClassBuffer,
        &dwQueryClassBufferSize,
        NULL)) != ERROR_NO_MORE_ITEMS) {

        // open this key
        lStatus = RegOpenKeyEx (
            hKeyLogQueries,
            szQueryNameBuffer,
            0L,
            KEY_READ | KEY_WRITE,
            &hKeyThisLogQuery);

        if (lStatus != ERROR_SUCCESS) {
            szStringArray[0] = szQueryNameBuffer;
            ReportEvent (hEventLog,
                EVENTLOG_WARNING_TYPE,
                0,
                PERFLOG_UNABLE_READ_LOG_QUERY,
                NULL,
                1,
                sizeof(DWORD),
                szStringArray,
                   (LPVOID)&lStatus);
            // skip to next item
            goto CONTINUE_ENUM_LOOP;
        }

        // update the service status
        ssPerfLogStatus.dwCheckPoint++;
        SetServiceStatus (hPerfLogStatus, &ssPerfLogStatus);

        // allocate a thread info block.
        lpThreadData = G_ALLOC (sizeof(LOG_THREAD_DATA));
        if (lpThreadData == NULL) {
            lStatus = GetLastError();
            szStringArray[0] = szQueryNameBuffer;
            ReportEvent (hEventLog,
                EVENTLOG_WARNING_TYPE,
                0,
                PERFLOG_UNABLE_ALLOCATE_DATABLOCK,
                NULL,
                1,
                sizeof(DWORD),
                szStringArray,
                (LPVOID)&lStatus);
            goto CONTINUE_ENUM_LOOP;
        }

        // initialize the thread data block
        lpThreadData->hKeyQuery = hKeyThisLogQuery;
        lpThreadData->hExitEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
        lpThreadData->bReloadNewConfig = FALSE;
        lstrcpy (lpThreadData->szQueryName, szQueryNameBuffer);

        // start logging thread
        hThread = CreateThread (
            NULL, 0, LoggingThreadProc,
            (LPVOID)lpThreadData, 0, &dwThreadId);

        if (hThread != NULL) {
            // add it to the list and continue
            if (pFirstThread == NULL) {
                // then this is the first thread so add it
                lpThreadData->next = NULL;
                pFirstThread = lpThreadData;
            } else {
                // insert this at the head of the list since
                // that's the easiest and the order isn't
                // really important
                lpThreadData->next = pFirstThread;
                pFirstThread = lpThreadData;
            }
            // add thread to array for termination wait
            if (dwHandleCount < dwMaxHandleCount) {
                pThreadHandleArray[dwHandleCount++] = hThread;
            } else {
                // realloc buffer and try again
                // this will be added when multi-query
                // support is added. for now we'll ignore
                // ones that don't fit.
            }
            lpThreadData = NULL; //clear for next lap
        } else {
            // unable to start thread
            lStatus = GetLastError();
            szStringArray[0] = szQueryNameBuffer;
            ReportEvent (hEventLog,
                EVENTLOG_WARNING_TYPE,
                0,
                PERFLOG_UNABLE_START_THREAD,
                NULL,
                1,
                sizeof(DWORD),
                szStringArray,
                (LPVOID)&lStatus);
        }
CONTINUE_ENUM_LOOP:
        // prepare for next loop
        dwQueryIndex++;
        // for now we just do the first item in the list
        // the full multiple log query feature will be
        // added later.
        if (dwQueryIndex > 0) break;
        // otherwise we would continue here
        *szQueryNameBuffer = 0;
        dwQueryNameBufferSize = MAX_PATH;
        *szQueryClassBuffer;
        dwQueryClassBufferSize = MAX_PATH;
    } // end enumeration of log queries

    // service is now started
    ssPerfLogStatus.dwCurrentState    = SERVICE_RUNNING;
    ssPerfLogStatus.dwCheckPoint++;
    SetServiceStatus (hPerfLogStatus, &ssPerfLogStatus);

    // wait for (all) timing and logging threads to complete
    lStatus = WaitForMultipleObjects (dwHandleCount,
        pThreadHandleArray, TRUE, INFINITE);

    ssPerfLogStatus.dwCurrentState    = SERVICE_STOP_PENDING;
    SetServiceStatus (hPerfLogStatus, &ssPerfLogStatus);

    // when here, all logging threads have terminated so the
    // memory can be released and the service can exit and shutdown.
    for (dwQueryIndex = 0; dwQueryIndex < dwHandleCount; dwQueryIndex++) {
        CloseHandle (pThreadHandleArray[dwQueryIndex]);
    }

    // release the dynamic memory
    FreeThreadData (pFirstThread);

    // and update the service status
    ssPerfLogStatus.dwCurrentState    = SERVICE_STOPPED;
    SetServiceStatus (hPerfLogStatus, &ssPerfLogStatus);

    if (hEventLog != NULL) CloseHandle (hEventLog);

    return;
}
//
//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
//  PURPOSE:  Processes messages for the main window.
//
//  MESSAGES:
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//    WM_DISPLAYCHANGE - message sent to Plug & Play systems when the display changes
//    WM_RBUTTONDOWN - Right mouse click -- put up context menu here if appropriate
//    WM_NCRBUTTONUP - User has clicked the right button on the application's system menu
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
   int wmId, wmEvent;
   PAINTSTRUCT ps;
   HDC hdc;
   POINT pnt;
   HMENU hMenu;
   BOOL bGotHelp;

   switch (message)
   {
   case WM_CREATE:
      // clear timer flags
      TimerID = 0;
      TimerRunning = FALSE;

      // enable "Start" menu selection
      hAppMenu = GetMenu (hWnd);
      hTestMenu  = GetSubMenu (hAppMenu, 1);
      EnableMenuItem (hTestMenu, IDM_STOP, MF_BYCOMMAND | MF_GRAYED);
      EnableMenuItem (hTestMenu, IDM_START, MF_BYCOMMAND | MF_ENABLED);
      break;

   case WM_COMMAND:
      wmId    = LOWORD(wParam); // Remember, these are...
      wmEvent = HIWORD(wParam); // ...different for Win32!

      //Parse the menu selections:
      switch (wmId)
      {

      case IDM_EXIT:
         DestroyWindow (hWnd);
         break;

      case IDM_START:
         if (!TimerRunning)
         {
            TimerID = SetTimer (hWnd, LEAK_TIMER, TIME_INTERVAL, NULL);
            if (TimerID != 0)
            {
               TimerRunning = TRUE;
               EnableMenuItem (hTestMenu, IDM_START,
                               MF_BYCOMMAND | MF_GRAYED);
               EnableMenuItem (hTestMenu, IDM_STOP,
                               MF_BYCOMMAND | MF_ENABLED);
            }
            else
            {
               //unable to start timer
               MessageBeep (MB_ICONEXCLAMATION);
            }
         }
         InvalidateRect (hWnd, NULL, TRUE);
         break;

      case IDM_STOP:
         if (TimerRunning)
         {
            KillTimer (hWnd, LEAK_TIMER);
            TimerID = 0;
            TimerRunning = FALSE;
            EnableMenuItem (hTestMenu, IDM_STOP,
                            MF_BYCOMMAND | MF_GRAYED);
            EnableMenuItem (hTestMenu, IDM_START,
                            MF_BYCOMMAND | MF_ENABLED);
         }
         InvalidateRect (hWnd, NULL, TRUE);
         break;

      case IDM_RESET:
         FreeAllocatedMemory();
         InvalidateRect (hWnd, NULL, TRUE);
         break;

      case IDM_ABOUT:
         DialogBox(hInst, "AboutBox", hWnd, (DLGPROC)About);
         break;

      case IDM_HELPTOPICS: // Only called in Windows 95
         bGotHelp = WinHelp (hWnd, APPNAME".HLP", HELP_FINDER,(DWORD)0);
         if (!bGotHelp)
         {
            MessageBox (GetFocus(), GetStringRes(IDS_NO_HELP),
                        szAppName, MB_OK|MB_ICONHAND);
         }
         break;

      default:
         return (DefWindowProc(hWnd, message, wParam, lParam));
      }
      break;

   case WM_TIMER:
      {
         PMEMORY_ALLOC_BLOCK     pMab, pNewMab;

         pNewMab = (PMEMORY_ALLOC_BLOCK)G_ALLOC (GPTR, ALLOCATION_SIZE);

         if (pNewMab != NULL)
         {
            // save this pointer
            pNewMab->pNext = NULL;
            if (mabListHead.pNext == NULL)
            {
               // this is the first entry
               mabListHead.pNext = pNewMab;
            }
            else
            {
               // go to end of list
               pMab = mabListHead.pNext;
               while (pMab->pNext != NULL) pMab = pMab->pNext;
               pMab->pNext = pNewMab;
            }
            InvalidateRect (hWnd, NULL, TRUE);
         }
      }
      break;

   case WM_RBUTTONDOWN: // RightClick in windows client area...
      pnt.x = LOWORD(lParam);
      pnt.y = HIWORD(lParam);
      ClientToScreen(hWnd, (LPPOINT) &pnt);
      // This is where you would determine the appropriate 'context'
      // menu to bring up. Since this app has no real functionality,
      // we will just bring up the 'Help' menu:
      hMenu = GetSubMenu (GetMenu (hWnd), 2);
      if (hMenu)
      {
         TrackPopupMenu (hMenu, 0, pnt.x, pnt.y, 0, hWnd, NULL);
      }
      else
      {
         // Couldn't find the menu...
         MessageBeep(0);
      }
      break;


   case WM_DISPLAYCHANGE: // Only comes through on plug'n'play systems
      {
         SIZE  szScreen;
         DWORD dwBitsPerPixel = (DWORD)wParam;

         szScreen.cx = LOWORD(lParam);
         szScreen.cy = HIWORD(lParam);

         MessageBox (GetFocus(), GetStringRes(IDS_DISPLAYCHANGED),
                     szAppName, 0);
      }
      break;

   case WM_PAINT:
      {
         MEMORYSTATUS    MemoryStatusData;
         LONGLONG            llInUse;
         DWORD                   dwPercentUsed;

         int     nX, nY;
         LONG    lTextOutReturn;
         int     nStringLength;
         CHAR            szOutputString[100];

         hdc = BeginPaint (hWnd, &ps);
         // Add any drawing code here...
         GlobalMemoryStatus (& MemoryStatusData);

         llInUse = (LONGLONG)(MemoryStatusData.dwTotalPageFile -
                              MemoryStatusData.dwAvailPageFile + 5 );
         llInUse *= 1000;
         llInUse /= MemoryStatusData.dwTotalPageFile;
         llInUse /= 10;

         dwPercentUsed = (DWORD)llInUse;

         nX = 0;
         nY = 0;
         _snprintf_s(szOutputString, 100, _TRUNCATE, "Reported Memory Load: \t%3.1d%%",
                  MemoryStatusData.dwMemoryLoad);
         nStringLength = lstrlen (szOutputString) * sizeof (CHAR);
         lTextOutReturn = TabbedTextOut (hdc, nX, nY,
                                         szOutputString, nStringLength, 0, NULL, 0);
         nY += HIWORD (lTextOutReturn);

         _snprintf_s(szOutputString, 100, _TRUNCATE, "Page file in use:  \t%3.1d%%",
                  dwPercentUsed);
         nStringLength = lstrlen (szOutputString) * sizeof (CHAR);
         lTextOutReturn = TabbedTextOut(hdc, nX, nY,
                                         szOutputString, nStringLength, 0, NULL, 0);
         nY += HIWORD(lTextOutReturn);

         EndPaint (hWnd, &ps);
      }
      break;

   case WM_DESTROY:
      FreeAllocatedMemory();
      // Tell WinHelp we don't need it any more...
      WinHelp(hWnd, APPNAME".HLP", HELP_QUIT,(DWORD)0);
      PostQuitMessage(0);
      break;

   default:
      return (DefWindowProc(hWnd, message, wParam, lParam));
   }
   return (0);
}