Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1795 lines
73 KiB

/*++
Copyright (c) 1991-1999 Microsoft Corporation
Module Name:
dumpload.c
Abstract:
functions to dump and load the contents of the performance related registry
entries
Author:
Bob Watson (bobw) 13 Jun 99
Revision History:
--*/
//
// Windows Include files
//
#include <windows.h>
#include "strsafe.h"
#include "stdlib.h"
#include <winperf.h>
#include <loadperf.h>
#include "wmistr.h"
#include "evntrace.h"
//
// application include files
//
#include "winperfp.h"
#include "common.h"
#include "ldprfmsg.h"
#define DUMPLOAD_SERVICE_SIZE 32768
#define DUMPLOAD_NOSERVICE_SIZE 65536
#define DUMPLOAD_MAX_SERVICE_SIZE 4194304
// headings in save file
LPCWSTR cszFmtSectionHeader = L"\r\n\r\n[%s]";
LPCWSTR cszFmtServiceSectionHeader = L"\r\n\r\n[PERF_%s]";
LPCWSTR cszFmtServiceSectionName = L"PERF_%s";
LPCWSTR cszFmtStringSectionHeader = L"\r\n\r\n[PerfStrings_%s]";
LPCWSTR cszFmtExtCtrString = L"\r\n%d=%s";
LPCWSTR cszFmtDecimalParam = L"\r\n%s=%d";
LPCWSTR cszFmtNoParam = L"\r\n%s=";
LPCWSTR cszExtensiblePerfStrings = L"Strings";
LPCWSTR cszPerfCounterServices = L"PerfCounterServices";
LPCWSTR cszNoPerfCounterServices = L"NoPerfCounterServices";
LPCWSTR cszPerflib = L"Perflib";
DWORD
DumpNameTable(
HANDLE hOutputFile,
LPCWSTR szLangId,
LPCWSTR * pszNameTable,
DWORD dwStartIndex,
DWORD dwLastIndex
)
{
DWORD dwStatus = ERROR_SUCCESS;
DWORD ndx = 0;
LPWSTR szOutputBuffer = NULL;
DWORD dwBufSize = SMALL_BUFFER_SIZE;
DWORD dwSize = 0;
DWORD dwSizeWritten = 0;
HRESULT hr;
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_DUMPNAMETABLE,
ARG_DEF(ARG_TYPE_WSTR, 1),
ERROR_SUCCESS,
TRACE_WSTR(szLangId),
TRACE_DWORD(dwStartIndex),
TRACE_DWORD(dwLastIndex),
NULL));
szOutputBuffer = MemoryAllocate(sizeof(WCHAR) * dwBufSize);
if (szOutputBuffer == NULL) {
dwStatus = GetLastError();
goto Cleanup;
}
hr = StringCchPrintfW(szOutputBuffer, dwBufSize, cszFmtStringSectionHeader, szLangId);
dwSize = lstrlenW(szOutputBuffer) * sizeof(WCHAR);
WriteFile(hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
for (ndx = dwStartIndex; ndx <= dwLastIndex; ndx++) {
if (pszNameTable[ndx] != NULL) {
if (dwBufSize <= (DWORD) (lstrlenW(pszNameTable[ndx]) + 11)) {
MemoryFree((LPVOID) szOutputBuffer);
dwBufSize = (DWORD) (lstrlenW(pszNameTable[ndx]) + 11);
szOutputBuffer = MemoryAllocate(dwBufSize * sizeof(WCHAR));
if (szOutputBuffer == NULL) {
dwStatus = GetLastError();
goto Cleanup;
}
}
ZeroMemory(szOutputBuffer, dwBufSize * sizeof(WCHAR));
hr = StringCchPrintfW(szOutputBuffer, dwBufSize, cszFmtExtCtrString, ndx, pszNameTable[ndx]);
dwSize = lstrlenW(szOutputBuffer) * sizeof(WCHAR);
WriteFile(hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
}
}
Cleanup:
MemoryFree(szOutputBuffer);
return dwStatus;
}
DWORD
DumpPerfServiceEntries(
HANDLE hOutputFile,
LPCWSTR szServiceName,
LPDWORD pdwFirstCounter,
LPDWORD pdwFirstHelp,
LPDWORD pdwLastCounter,
LPDWORD pdwLastHelp,
LPDWORD pdwDisablePerfCounters,
LPWSTR szPerfIniFile,
DWORD dwPerfIniFile,
LPWSTR mszObjectList,
DWORD dwObjectList,
BOOL bRemove
)
{
DWORD dwPerfSubKeyName = 0;
LPWSTR szPerfSubKeyName = NULL;
HKEY hKeyPerformance = NULL;
DWORD dwItemSize, dwType, dwValue;
DWORD dwRegAccessMask;
DWORD dwRetStatus = ERROR_SUCCESS;
DWORD dwSize, dwSizeWritten;
LPWSTR szOutputBuffer = NULL;
HRESULT hr;
szOutputBuffer = MemoryAllocate(sizeof(WCHAR) * SMALL_BUFFER_SIZE);
if (szOutputBuffer == NULL) {
dwRetStatus = GetLastError();
goto Cleanup;
}
// try read-only then
if (bRemove) {
dwRegAccessMask = KEY_READ | KEY_WRITE;
}
else {
dwRegAccessMask = KEY_READ;
}
dwPerfSubKeyName = lstrlenW(DriverPathRoot) + lstrlenW(Slash)
+ lstrlenW(szServiceName) + lstrlenW(Slash)
+ lstrlenW(Performance) + 1;
szPerfSubKeyName = MemoryAllocate(dwPerfSubKeyName * sizeof(WCHAR));
if (szPerfSubKeyName != NULL) {
hr = StringCchPrintfW(szPerfSubKeyName, dwPerfSubKeyName, L"%s%s%s%s%s",
DriverPathRoot, Slash, szServiceName, Slash, Performance);
__try {
dwRetStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szPerfSubKeyName, 0L, dwRegAccessMask, & hKeyPerformance);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwRetStatus = GetExceptionCode();
}
}
else {
dwRetStatus = ERROR_OUTOFMEMORY;
}
if (dwRetStatus == ERROR_SUCCESS) {
// key found so service has perf data
if (hOutputFile != NULL) {
ZeroMemory(szOutputBuffer, SMALL_BUFFER_SIZE * sizeof(WCHAR));
hr = StringCchPrintfW(szOutputBuffer, SMALL_BUFFER_SIZE, cszFmtServiceSectionHeader, szServiceName);
dwSize = lstrlenW(szOutputBuffer) * sizeof(WCHAR);
WriteFile(hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
}
// now check to see if the strings have been loaded
dwType = dwValue = 0;
dwItemSize = sizeof(dwValue);
__try {
dwRetStatus = RegQueryValueExW(hKeyPerformance,
FirstCounter,
NULL,
& dwType,
(LPBYTE) & dwValue,
& dwItemSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwRetStatus = GetExceptionCode();
}
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_DUMPPERFSERVICEENTRIES,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
dwRetStatus,
TRACE_WSTR(szServiceName),
TRACE_WSTR(FirstCounter),
TRACE_DWORD(dwValue),
NULL));
if (dwRetStatus == ERROR_SUCCESS && (dwType == REG_DWORD || dwType == REG_BINARY)) {
if (pdwFirstCounter != NULL) {
* pdwFirstCounter = dwValue;
}
if (hOutputFile != NULL) {
ZeroMemory(szOutputBuffer, SMALL_BUFFER_SIZE * sizeof(WCHAR));
hr = StringCchPrintfW(szOutputBuffer, SMALL_BUFFER_SIZE, cszFmtDecimalParam, FirstCounter, dwValue);
dwSize = lstrlenW(szOutputBuffer) * sizeof(WCHAR);
WriteFile(hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
}
}
dwType = dwValue = 0;
dwItemSize = sizeof(dwValue);
__try {
dwRetStatus = RegQueryValueExW(hKeyPerformance,
FirstHelp,
NULL,
& dwType,
(LPBYTE) & dwValue,
& dwItemSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwRetStatus = GetExceptionCode();
}
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_DUMPPERFSERVICEENTRIES,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
dwRetStatus,
TRACE_WSTR(szServiceName),
TRACE_WSTR(FirstHelp),
TRACE_DWORD(dwValue),
NULL));
if (dwRetStatus == ERROR_SUCCESS && (dwType == REG_DWORD || dwType == REG_BINARY)) {
if (pdwFirstHelp != NULL) {
* pdwFirstHelp = dwValue;
}
if (hOutputFile != NULL) {
ZeroMemory(szOutputBuffer, SMALL_BUFFER_SIZE * sizeof(WCHAR));
hr = StringCchPrintfW(szOutputBuffer, SMALL_BUFFER_SIZE, cszFmtDecimalParam, FirstHelp, dwValue);
dwSize = lstrlenW(szOutputBuffer) * sizeof(WCHAR);
WriteFile(hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
}
}
dwType = dwValue = 0;
dwItemSize = sizeof(dwValue);
__try {
dwRetStatus = RegQueryValueExW(hKeyPerformance,
LastCounter,
NULL,
& dwType,
(LPBYTE) & dwValue,
& dwItemSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwRetStatus = GetExceptionCode();
}
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_DUMPPERFSERVICEENTRIES,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
dwRetStatus,
TRACE_WSTR(szServiceName),
TRACE_WSTR(LastCounter),
TRACE_DWORD(dwValue),
NULL));
if (dwRetStatus == ERROR_SUCCESS && (dwType == REG_DWORD || dwType == REG_BINARY)) {
if (pdwLastCounter != NULL) {
* pdwLastCounter = dwValue;
}
if (hOutputFile != NULL) {
ZeroMemory(szOutputBuffer, SMALL_BUFFER_SIZE * sizeof(WCHAR));
hr = StringCchPrintfW(szOutputBuffer, SMALL_BUFFER_SIZE, cszFmtDecimalParam, LastCounter, dwValue);
dwSize = lstrlenW(szOutputBuffer) * sizeof(WCHAR);
WriteFile(hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
}
}
dwType = dwValue = 0;
dwItemSize = sizeof(dwValue);
__try {
dwRetStatus = RegQueryValueExW(hKeyPerformance,
LastHelp,
NULL,
& dwType,
(LPBYTE) & dwValue,
& dwItemSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwRetStatus = GetExceptionCode();
}
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_DUMPPERFSERVICEENTRIES,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
dwRetStatus,
TRACE_WSTR(szServiceName),
TRACE_WSTR(LastHelp),
TRACE_DWORD(dwValue),
NULL));
if (dwRetStatus == ERROR_SUCCESS && (dwType == REG_DWORD || dwType == REG_BINARY)) {
if (pdwLastHelp != NULL) {
* pdwLastHelp = dwValue;
}
if (hOutputFile != NULL) {
ZeroMemory(szOutputBuffer, SMALL_BUFFER_SIZE * sizeof(WCHAR));
hr = StringCchPrintfW(szOutputBuffer, SMALL_BUFFER_SIZE, cszFmtDecimalParam, LastHelp, dwValue);
dwSize = lstrlenW(szOutputBuffer) * sizeof(WCHAR);
WriteFile(hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
}
}
dwType = dwValue = 0;
dwItemSize = sizeof(dwValue);
__try {
dwRetStatus = RegQueryValueExW(hKeyPerformance,
DisablePerformanceCounters,
NULL,
& dwType,
(LPBYTE) & dwValue,
& dwItemSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwRetStatus = GetExceptionCode();
}
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_DUMPPERFSERVICEENTRIES,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
dwRetStatus,
TRACE_WSTR(szServiceName),
TRACE_WSTR(DisablePerformanceCounters),
TRACE_DWORD(dwValue),
NULL));
if (dwRetStatus == ERROR_SUCCESS && (dwType == REG_DWORD || dwType == REG_BINARY)) {
if (pdwDisablePerfCounters != NULL) {
* pdwDisablePerfCounters = dwValue;
}
if (hOutputFile != NULL) {
ZeroMemory(szOutputBuffer, SMALL_BUFFER_SIZE * sizeof(WCHAR));
hr = StringCchPrintfW(szOutputBuffer, SMALL_BUFFER_SIZE, cszFmtDecimalParam, DisablePerformanceCounters, dwValue);
dwSize = lstrlenW(szOutputBuffer) * sizeof (WCHAR);
WriteFile(hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
}
}
else {
dwRetStatus = ERROR_SUCCESS;
}
if (szPerfIniFile != NULL) {
dwType = 0;
dwItemSize = sizeof(WCHAR) * dwPerfIniFile;
__try {
dwRetStatus = RegQueryValueExW(hKeyPerformance,
szPerfIniPath,
NULL,
& dwType,
(LPBYTE) szPerfIniFile,
& dwItemSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwRetStatus = GetExceptionCode();
}
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_DUMPPERFSERVICEENTRIES,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
dwRetStatus,
TRACE_WSTR(szServiceName),
TRACE_WSTR(DisablePerformanceCounters),
TRACE_DWORD(dwValue),
NULL));
}
if (mszObjectList != NULL) {
dwType = 0;
dwItemSize = sizeof(WCHAR) * dwObjectList;
__try {
dwRetStatus = RegQueryValueExW(hKeyPerformance,
szObjectList,
NULL,
& dwType,
(LPBYTE) mszObjectList,
& dwItemSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwRetStatus = GetExceptionCode();
}
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_DUMPPERFSERVICEENTRIES,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
dwRetStatus,
TRACE_WSTR(szServiceName),
TRACE_WSTR(DisablePerformanceCounters),
TRACE_DWORD(dwValue),
NULL));
if (dwRetStatus == ERROR_SUCCESS && dwType != REG_MULTI_SZ) {
LPWSTR szChar = mszObjectList;
while ((szChar != NULL) && (* szChar != cNull)) {
if (* szChar == cSpace) * szChar = cNull;
szChar ++;
}
}
else {
dwRetStatus = ERROR_SUCCESS;
}
}
if (bRemove) {
RegDeleteValueW(hKeyPerformance, FirstCounter);
RegDeleteValueW(hKeyPerformance, LastCounter);
RegDeleteValueW(hKeyPerformance, FirstHelp);
RegDeleteValueW(hKeyPerformance, LastHelp);
RegDeleteValueW(hKeyPerformance, szObjectList);
}
RegCloseKey (hKeyPerformance);
}
else {
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_DUMPPERFSERVICEENTRIES,
ARG_DEF(ARG_TYPE_WSTR, 1),
dwRetStatus,
TRACE_WSTR(szServiceName),
NULL));
}
Cleanup:
MemoryFree(szPerfSubKeyName);
return dwRetStatus;
}
DWORD
DumpPerflibEntries(
HANDLE hOutputFile,
LPDWORD pdwBaseIndex,
LPDWORD pdwLastCounter,
LPDWORD pdwLastHelp,
LPDWORD pdwFirstExtCtrIndex
)
{
HKEY hKeyPerflib = NULL;
DWORD dwStatus = ERROR_SUCCESS;
DWORD dwItemSize, dwType, dwValue;
DWORD dwSize, dwSizeWritten;
LPWSTR szOutputBuffer = NULL;
HRESULT hr;
szOutputBuffer = MemoryAllocate(sizeof(WCHAR) * SMALL_BUFFER_SIZE);
if (szOutputBuffer == NULL) {
dwStatus = ERROR_OUTOFMEMORY;
}
if (dwStatus == ERROR_SUCCESS) {
__try {
dwStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, NamesKey, 0L, KEY_READ, & hKeyPerflib);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwStatus = GetExceptionCode();
}
}
if (dwStatus == ERROR_SUCCESS) {
if (hOutputFile != NULL) {
ZeroMemory(szOutputBuffer, SMALL_BUFFER_SIZE * sizeof(WCHAR));
hr = StringCchPrintfW(szOutputBuffer, SMALL_BUFFER_SIZE, cszFmtSectionHeader, cszPerflib);
dwSize = lstrlenW(szOutputBuffer) * sizeof(WCHAR);
WriteFile (hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
}
}
else {
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_DUMPPERFLIBENTRIES,
ARG_DEF(ARG_TYPE_WSTR, 1),
dwStatus,
TRACE_WSTR(NamesKey),
NULL));
}
if (dwStatus == ERROR_SUCCESS) {
dwType = dwValue = 0;
dwItemSize = sizeof(dwValue);
__try {
dwStatus = RegQueryValueExW(hKeyPerflib, BaseIndex, NULL, & dwType, (LPBYTE) & dwValue, & dwItemSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwStatus = GetExceptionCode();
}
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_DUMPPERFLIBENTRIES,
ARG_DEF(ARG_TYPE_WSTR, 1),
dwStatus,
TRACE_WSTR(BaseIndex),
TRACE_DWORD(dwValue),
NULL));
if ((dwStatus == ERROR_SUCCESS) && (dwType == REG_DWORD)) {
if (pdwBaseIndex != NULL) {
* pdwBaseIndex = dwValue;
}
if (hOutputFile != NULL) {
ZeroMemory(szOutputBuffer, SMALL_BUFFER_SIZE * sizeof(WCHAR));
hr = StringCchPrintfW(szOutputBuffer, SMALL_BUFFER_SIZE, cszFmtDecimalParam, BaseIndex, dwValue);
dwSize = lstrlenW(szOutputBuffer) * sizeof(WCHAR);
WriteFile(hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
}
if (pdwFirstExtCtrIndex != NULL) {
* pdwFirstExtCtrIndex = dwValue + 1;
}
}
}
if (dwStatus == ERROR_SUCCESS) {
dwType = dwValue = 0;
dwItemSize = sizeof(dwValue);
__try {
dwStatus = RegQueryValueExW(hKeyPerflib, LastCounter, NULL, & dwType, (LPBYTE) & dwValue, & dwItemSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwStatus = GetExceptionCode();
}
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_DUMPPERFLIBENTRIES,
ARG_DEF(ARG_TYPE_WSTR, 1),
dwStatus,
TRACE_WSTR(LastCounter),
TRACE_DWORD(dwValue),
NULL));
if ((dwStatus == ERROR_SUCCESS) && (dwType == REG_DWORD)) {
if (pdwLastCounter != NULL) {
* pdwLastCounter = dwValue;
}
if (hOutputFile != NULL) {
ZeroMemory(szOutputBuffer, SMALL_BUFFER_SIZE * sizeof(WCHAR));
hr = StringCchPrintfW(szOutputBuffer, SMALL_BUFFER_SIZE, cszFmtDecimalParam, LastCounter, dwValue);
dwSize = lstrlenW(szOutputBuffer) * sizeof(WCHAR);
WriteFile(hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
}
}
}
if (dwStatus == ERROR_SUCCESS) {
dwType = dwValue = 0;
dwItemSize = sizeof(dwValue);
__try {
dwStatus = RegQueryValueExW(hKeyPerflib, LastHelp, NULL, & dwType, (LPBYTE) & dwValue, & dwItemSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwStatus = GetExceptionCode();
}
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_DUMPPERFLIBENTRIES,
ARG_DEF(ARG_TYPE_WSTR, 1),
dwStatus,
TRACE_WSTR(LastHelp),
TRACE_DWORD(dwValue),
NULL));
if ((dwStatus == ERROR_SUCCESS) && (dwType == REG_DWORD)) {
if (pdwLastHelp != NULL) {
* pdwLastHelp = dwValue;
}
if (hOutputFile != NULL) {
ZeroMemory(szOutputBuffer, SMALL_BUFFER_SIZE * sizeof(WCHAR));
hr = StringCchPrintfW(szOutputBuffer, SMALL_BUFFER_SIZE, cszFmtDecimalParam, LastHelp, dwValue);
dwSize = lstrlenW(szOutputBuffer) * sizeof(WCHAR);
WriteFile(hOutputFile, szOutputBuffer, dwSize, & dwSizeWritten, NULL);
}
}
}
if (hKeyPerflib != NULL) RegCloseKey(hKeyPerflib);
MemoryFree(szOutputBuffer);
return dwStatus;
}
DWORD
BuildServiceLists(
LPWSTR mszPerfServiceList,
LPDWORD pcchPerfServiceListSize,
LPWSTR mszNoPerfServiceList,
LPDWORD pcchNoPerfServiceListSize
)
{
LONG lEnumStatus = ERROR_SUCCESS;
DWORD dwServiceIndex = 0;
LPWSTR szServiceSubKeyName = NULL;
LPWSTR szPerfSubKeyName = NULL;
DWORD dwNameSize = MAX_PATH;
HKEY hKeyPerformance;
HKEY hKeyServices = NULL;
DWORD dwItemSize, dwType, dwValue;
DWORD dwRegAccessMask;
DWORD bServiceHasPerfCounters;
DWORD dwRetStatus = ERROR_SUCCESS;
LPWSTR szNextNoPerfChar, szNextPerfChar;
DWORD dwNoPerfSizeRem, dwPerfSizeRem;
DWORD dwPerfSizeUsed = 0, dwNoPerfSizeUsed = 0;
HRESULT hr;
// try read-only then
dwRegAccessMask = KEY_READ;
szServiceSubKeyName = MemoryAllocate(MAX_PATH * sizeof(WCHAR));
szPerfSubKeyName = MemoryAllocate((MAX_PATH + 32) * sizeof(WCHAR));
if (szServiceSubKeyName == NULL || szPerfSubKeyName == NULL) {
dwRetStatus = ERROR_OUTOFMEMORY;
goto Cleanup;
}
__try {
dwRetStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, DriverPathRoot, 0L, dwRegAccessMask, & hKeyServices);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwRetStatus = GetExceptionCode();
}
if (dwRetStatus == ERROR_SUCCESS) {
szNextNoPerfChar = mszNoPerfServiceList;
szNextPerfChar = mszPerfServiceList;
dwNoPerfSizeRem = * pcchPerfServiceListSize;
dwPerfSizeRem = * pcchNoPerfServiceListSize;
dwPerfSizeUsed = 0;
dwNoPerfSizeUsed = 0;
dwNameSize = MAX_PATH;
ZeroMemory(szServiceSubKeyName, MAX_PATH * sizeof(WCHAR));
ZeroMemory(szPerfSubKeyName, (MAX_PATH + 32) * sizeof(WCHAR));
while ((lEnumStatus = RegEnumKeyExW(hKeyServices,
dwServiceIndex,
szServiceSubKeyName,
& dwNameSize,
NULL,
NULL,
NULL,
NULL)) == ERROR_SUCCESS) {
//try to open the perfkey under this key.
hr = StringCchPrintfW(szPerfSubKeyName, MAX_PATH + 32, L"%s%s%s", szServiceSubKeyName, Slash, Performance);
__try {
dwRetStatus = RegOpenKeyExW(hKeyServices, szPerfSubKeyName, 0L, dwRegAccessMask, & hKeyPerformance);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwRetStatus = GetExceptionCode();
}
if (dwRetStatus == ERROR_SUCCESS) {
// key found so service has perf data
// now check to see if the strings have been loaded
dwType = dwValue = 0;
dwItemSize = sizeof(dwValue);
__try {
dwRetStatus = RegQueryValueExW(hKeyPerformance,
FirstCounter,
NULL,
& dwType,
(LPBYTE) & dwValue,
& dwItemSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwRetStatus = GetExceptionCode();
}
if (dwRetStatus == ERROR_SUCCESS && (dwType == REG_DWORD || dwType == REG_BINARY)) {
bServiceHasPerfCounters = TRUE;
}
else {
bServiceHasPerfCounters = FALSE;
}
RegCloseKey (hKeyPerformance);
}
else {
// key not found so service doesn't have perfdata
bServiceHasPerfCounters = FALSE;
dwRetStatus = ERROR_SUCCESS;
}
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_BUILDSERVICELISTS,
ARG_DEF(ARG_TYPE_WSTR, 1),
dwRetStatus,
TRACE_WSTR(szServiceSubKeyName),
TRACE_DWORD(bServiceHasPerfCounters),
NULL));
if (bServiceHasPerfCounters != FALSE) {
// add to the perf service list
if ((dwNameSize + 1) < dwPerfSizeRem) {
// add to list
hr = StringCchCopyW(szNextPerfChar, dwPerfSizeRem, szServiceSubKeyName);
szNextPerfChar += dwNameSize;
* szNextPerfChar = L'\0';
szNextPerfChar ++;
dwPerfSizeRem -= dwNameSize + 1;
}
else {
dwPerfSizeRem = 0;
dwRetStatus = ERROR_MORE_DATA;
}
dwPerfSizeUsed += dwNameSize + 1;
}
else {
// add to the no perf list
if ((dwNameSize + 1) < dwNoPerfSizeRem) {
// add to list
hr = StringCchCopyW(szNextNoPerfChar, dwNoPerfSizeRem, szServiceSubKeyName);
szNextNoPerfChar += dwNameSize;
* szNextNoPerfChar = L'\0';
szNextNoPerfChar ++;
dwNoPerfSizeRem -= dwNameSize + 1;
}
else {
dwNoPerfSizeRem = 0;
dwRetStatus = ERROR_MORE_DATA;
}
dwNoPerfSizeUsed += dwNameSize + 1;
}
// reset for next loop
dwServiceIndex ++;
dwNameSize = MAX_PATH;
ZeroMemory(szServiceSubKeyName, MAX_PATH * sizeof(WCHAR));
ZeroMemory(szPerfSubKeyName, (MAX_PATH + 32) * sizeof(WCHAR));
}
// zero term the MSZ
if (1 < dwPerfSizeRem) {
* szNextPerfChar = L'\0';
szNextPerfChar ++;
dwPerfSizeRem -= 1;
}
else {
dwRetStatus = ERROR_MORE_DATA;
}
dwPerfSizeUsed += 1;
// zero term the no perf list
if (1 < dwNoPerfSizeRem) {
// add to list
* szNextNoPerfChar = L'\0';
szNextNoPerfChar ++;
dwNoPerfSizeRem -= 1;
}
else {
dwRetStatus = ERROR_MORE_DATA;
}
dwNoPerfSizeUsed += 1;
}
else {
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_BUILDSERVICELISTS,
ARG_DEF(ARG_TYPE_WSTR, 1),
dwRetStatus,
TRACE_WSTR(DriverPathRoot),
NULL));
}
Cleanup:
if (hKeyServices != NULL) RegCloseKey(hKeyServices);
MemoryFree(szServiceSubKeyName);
MemoryFree(szPerfSubKeyName);
if (dwRetStatus == ERROR_SUCCESS || dwRetStatus == ERROR_MORE_DATA) {
* pcchPerfServiceListSize = dwPerfSizeUsed;
* pcchNoPerfServiceListSize = dwNoPerfSizeUsed;
}
return dwRetStatus;
}
DWORD
BackupPerfRegistryToFileW(
IN LPCWSTR szFileName,
IN LPCWSTR szCommentString
)
{
HANDLE hOutFile = NULL;
DWORD dwStatus = ERROR_SUCCESS;
LPWSTR szNewFileName = NULL;
DWORD dwNewFileNameLen;
DWORD dwOrigFileNameLen;
DWORD dwFileNameSN;
LPWSTR mszPerfServiceList = NULL;
DWORD dwPerfServiceListSize = 0;
LPWSTR mszNoPerfServiceList = NULL;
DWORD dwNoPerfServiceListSize = 0;
LPWSTR * lpCounterText = NULL;
DWORD dwLastElement = 0;
DWORD dwFirstExtCtrIndex = 0;
LPWSTR szThisServiceName;
HRESULT hr;
DBG_UNREFERENCED_PARAMETER(szCommentString);
WinPerfStartTrace(NULL);
if (szFileName == NULL) {
dwStatus = ERROR_INVALID_PARAMETER;
}
else {
__try {
dwNewFileNameLen = lstrlenW(szFileName);
if (dwNewFileNameLen == 0) dwStatus = ERROR_INVALID_PARAMETER;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwStatus = ERROR_INVALID_PARAMETER;
}
}
if (dwStatus == ERROR_SUCCESS) {
// open output file
hOutFile = CreateFileW(szFileName,
GENERIC_WRITE,
0, // no sharing
NULL, // default security
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
NULL);
// if the file open failed
if (hOutFile == INVALID_HANDLE_VALUE) {
// see if it's because the file already exists
dwStatus = GetLastError();
if (dwStatus == ERROR_FILE_EXISTS) {
// then try appending a serial number to the name
dwOrigFileNameLen = lstrlenW(szFileName) + 1;
dwNewFileNameLen = dwOrigFileNameLen + 4;
szNewFileName = MemoryAllocate(dwNewFileNameLen * sizeof(WCHAR));
if (szNewFileName != NULL) {
hr = StringCchCopyW(szNewFileName, dwOrigFileNameLen, szFileName);
for (dwFileNameSN = 1; dwFileNameSN < 1000; dwFileNameSN++) {
hr = StringCchPrintfW(& szNewFileName[dwOrigFileNameLen - 1],
dwNewFileNameLen,
L"_%3.3d",
dwFileNameSN);
hOutFile = CreateFileW(szNewFileName,
GENERIC_WRITE,
0, // no sharing
NULL, // default security
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
NULL);
// if the file open failed
if (hOutFile == INVALID_HANDLE_VALUE) {
dwStatus = GetLastError();
if (dwStatus != ERROR_FILE_EXISTS) {
// some other error occurred so bail out
break;
}
else {
continue; // with the next try
}
}
else {
// found one not in use so continue on
dwStatus = ERROR_SUCCESS;
break;
}
}
}
else {
dwStatus = ERROR_OUTOFMEMORY;
}
}
}
else {
// file opened so continue
dwStatus = ERROR_SUCCESS;
}
}
if (dwStatus == ERROR_SUCCESS) {
// dump perflib key entires
dwStatus = DumpPerflibEntries(hOutFile, NULL, NULL, NULL, & dwFirstExtCtrIndex);
}
if (dwStatus == ERROR_SUCCESS) {
do {
MemoryFree(mszPerfServiceList);
mszPerfServiceList = NULL;
MemoryFree(mszNoPerfServiceList);
mszNoPerfServiceList = NULL;
// build service lists
dwPerfServiceListSize += DUMPLOAD_SERVICE_SIZE;
dwNoPerfServiceListSize += DUMPLOAD_NOSERVICE_SIZE;
mszPerfServiceList = MemoryAllocate(dwPerfServiceListSize * sizeof(WCHAR));
mszNoPerfServiceList = MemoryAllocate(dwNoPerfServiceListSize * sizeof(WCHAR));
if (mszNoPerfServiceList == NULL || mszPerfServiceList == NULL) {
dwStatus = ERROR_OUTOFMEMORY;
break;
}
if (dwStatus != ERROR_OUTOFMEMORY) {
dwStatus = BuildServiceLists(mszPerfServiceList,
& dwPerfServiceListSize,
mszNoPerfServiceList,
& dwNoPerfServiceListSize);
}
} while (dwStatus == ERROR_MORE_DATA && dwPerfServiceListSize < DUMPLOAD_MAX_SERVICE_SIZE);
}
// dump service entries for those services with perf counters
if (dwStatus == ERROR_SUCCESS) {
for (szThisServiceName = mszPerfServiceList;
* szThisServiceName != 0;
szThisServiceName += lstrlenW(szThisServiceName) + 1) {
dwStatus = DumpPerfServiceEntries(hOutFile,
szThisServiceName,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
0,
NULL,
0,
FALSE);
if (dwStatus != ERROR_SUCCESS) break;
}
}
// dump perf string entries
if (dwStatus == ERROR_SUCCESS) {
WCHAR szLangId[8];
DWORD dwIndex = 0;
DWORD dwCopyIndex = 0;
DWORD dwTmpStatus = ERROR_SUCCESS;
DWORD dwBufferSize;
HKEY hPerflibRoot = NULL;
__try {
dwStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, NamesKey, RESERVED, KEY_READ, & hPerflibRoot);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwStatus = GetExceptionCode();
}
while (dwStatus == ERROR_SUCCESS) {
dwBufferSize = 8;
ZeroMemory(szLangId, 8 * sizeof(WCHAR));
dwStatus = RegEnumKeyExW(hPerflibRoot,
dwIndex,
szLangId,
& dwBufferSize,
NULL,
NULL,
NULL,
NULL);
if (dwStatus == ERROR_SUCCESS) {
lpCounterText = BuildNameTable(HKEY_LOCAL_MACHINE, (LPWSTR) szLangId, & dwLastElement);
if (lpCounterText != NULL) {
__try {
dwStatus = DumpNameTable(hOutFile, szLangId, lpCounterText, 0, dwLastElement);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwStatus = GetExceptionCode();
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_BACKUPPERFREGISTRYTOFILEW,
ARG_DEF(ARG_TYPE_WSTR, 1),
dwStatus,
TRACE_WSTR(szLangId),
TRACE_DWORD(dwLastElement),
NULL));
}
MemoryFree(lpCounterText);
lpCounterText = NULL;
}
else {
dwStatus = GetLastError();
}
if (dwStatus == ERROR_SUCCESS) {
dwCopyIndex ++;
}
else {
dwTmpStatus = dwStatus;
dwStatus = ERROR_SUCCESS;
}
}
dwIndex ++;
}
if (dwStatus == ERROR_NO_MORE_ITEMS) dwStatus = ERROR_SUCCESS;
if (dwStatus == ERROR_SUCCESS && dwCopyIndex == 0) {
dwStatus = dwTmpStatus;
}
if (hPerflibRoot != NULL) RegCloseKey(hPerflibRoot);
}
// free buffers
MemoryFree(lpCounterText);
MemoryFree(mszNoPerfServiceList);
MemoryFree(mszPerfServiceList);
MemoryFree(szNewFileName);
// close file handles
if (hOutFile != NULL && hOutFile != INVALID_HANDLE_VALUE) {
CloseHandle (hOutFile);
}
return dwStatus;
}
DWORD
LoadPerfRepairPerfRegistry()
{
DWORD dwStatus = ERROR_SUCCESS;
DWORD dwBaseIndex = 0;
DWORD dwLastCounter = 0;
DWORD dwLastHelp = 0;
HKEY hKeyPerflib = NULL;
DWORD dwValue = 0;
DWORD dwIndex = 0;
DWORD dw1Size = 0;
DWORD dwSize = 0;
LPWSTR szInfPath = NULL;
LPWSTR szLangID = NULL;
LPWSTR szCtrFile = NULL;
LPWSTR szHlpFile = NULL;
HANDLE hCtrFile = NULL;
HANDLE hHlpFile = NULL;
WIN32_FIND_DATAW FindCtrFile;
WIN32_FIND_DATAW FindHlpFile;
PLANG_ENTRY LangList = NULL;
PLANG_ENTRY pThisLang = NULL;
LPWSTR mszService = NULL;
DWORD dwService = 0;
LPWSTR mszObjectList = NULL;
DWORD dwObjectList = 0;
LPWSTR mszNonService = NULL;
DWORD dwNonService = 0;
LPWSTR szThisService = NULL;
PSERVICE_ENTRY ServiceList = NULL;
PSERVICE_ENTRY pThisService = NULL;
HRESULT hr;
if (LoadPerfGrabMutex() == FALSE) {
return GetLastError();
}
dwStatus = DumpPerflibEntries(NULL, & dwBaseIndex, & dwLastCounter, & dwLastHelp, NULL);
if (dwStatus != ERROR_SUCCESS) goto Cleanup;
__try {
dwStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, NamesKey, RESERVED, KEY_WRITE | KEY_READ, & hKeyPerflib);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwStatus = GetExceptionCode();
}
if (dwStatus != ERROR_SUCCESS) {
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_REPAIRPERFREGISTRY,
ARG_DEF(ARG_TYPE_WSTR, 1),
dwStatus,
TRACE_WSTR(NamesKey),
NULL));
goto Cleanup;
}
if ((szInfPath = LoadPerfGetInfPath()) == NULL) {
dwStatus = GetLastError();
goto Cleanup;
}
// String format <szInfPath><lang-id>\PERFD<langid>.DAT
// The buffer size will be lstrlenW(szInfPath) + 18
//
dw1Size = lstrlenW(szInfPath) + 20;
if (dw1Size < MAX_PATH) dw1Size = MAX_PATH;
dwSize = dw1Size + dw1Size + 8;
szCtrFile = MemoryAllocate(dwSize * sizeof(WCHAR));
if (szCtrFile == NULL) {
dwStatus = ERROR_OUTOFMEMORY;
goto Cleanup;
}
szHlpFile = (LPWSTR) (szCtrFile + dw1Size);
szLangID = (LPWSTR) (szHlpFile + dw1Size);
dwIndex = 0;
dwSize = 8;
dwStatus = RegEnumKeyExW(hKeyPerflib, dwIndex, szLangID, & dwSize, NULL, NULL, NULL, NULL);
while (dwStatus == ERROR_SUCCESS) {
LPWSTR szThisLang = LoadPerfGetLanguage(szLangID, FALSE);
DWORD dwLast;
pThisLang = (PLANG_ENTRY) MemoryAllocate(sizeof(LANG_ENTRY) + sizeof(WCHAR) * (lstrlenW(szThisLang) + 1));
if (pThisLang == NULL) {
dwStatus = ERROR_OUTOFMEMORY;
goto Cleanup;
}
pThisLang->szLang = (LPWSTR) (((LPBYTE) pThisLang) + sizeof(LANG_ENTRY));
hr = StringCchCopyW(pThisLang->szLang, (lstrlenW(szThisLang) + 1), szThisLang);
pThisLang->dwLang = LoadPerfGetLCIDFromString(pThisLang->szLang);
pThisLang->dwLastCounter = dwLastCounter;
pThisLang->dwLastHelp = dwLastHelp;
pThisLang->lpText = BuildNameTable(HKEY_LOCAL_MACHINE, szLangID, & dwLast);
pThisLang->pNext = LangList;
LangList = pThisLang;
dwIndex ++;
dwSize = 8;
ZeroMemory(szLangID, 8 * sizeof(WCHAR));
dwStatus = RegEnumKeyExW(hKeyPerflib, dwIndex, szLangID, & dwSize, NULL, NULL, NULL, NULL);
}
if (dwStatus == ERROR_NO_MORE_ITEMS) dwStatus = ERROR_SUCCESS;
if (dwStatus != ERROR_SUCCESS) goto Cleanup;
dwValue = dwBaseIndex - 1;
__try {
dwStatus = RegSetValueExW(hKeyPerflib, LastCounter, RESERVED, REG_DWORD, (LPBYTE) & dwValue, sizeof(DWORD));
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwStatus = GetExceptionCode();
}
if (dwStatus != ERROR_SUCCESS) {
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_REPAIRPERFREGISTRY,
ARG_DEF(ARG_TYPE_WSTR, 1),
dwStatus,
TRACE_WSTR(LastCounter),
TRACE_DWORD(dwValue),
NULL));
goto Cleanup;
}
dwValue = dwBaseIndex;
__try {
dwStatus = RegSetValueExW(hKeyPerflib, LastHelp, RESERVED, REG_DWORD, (LPBYTE) & dwValue, sizeof(DWORD));
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwStatus = GetExceptionCode();
}
if (dwStatus != ERROR_SUCCESS) {
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_REPAIRPERFREGISTRY,
ARG_DEF(ARG_TYPE_WSTR, 1),
dwStatus,
TRACE_WSTR(LastHelp),
TRACE_DWORD(dwValue),
NULL));
goto Cleanup;
}
dwIndex = 0;
dwSize = 8;
dwStatus = RegEnumKeyExW(hKeyPerflib, dwIndex, szLangID, & dwSize, NULL, NULL, NULL, NULL);
while (dwStatus == ERROR_SUCCESS) {
LPWSTR szThisLang = LoadPerfGetLanguage(szLangID, FALSE);
DWORD dwLast;
ZeroMemory(szCtrFile, dw1Size * sizeof(WCHAR));
hr = StringCchPrintfW(szCtrFile, dw1Size, L"%s%s%s*d%s%s", szInfPath, szThisLang, Slash, szThisLang, szDatExt);
ZeroMemory(szHlpFile, dw1Size * sizeof(WCHAR));
hr = StringCchPrintfW(szHlpFile, dw1Size, L"%s%s%s*i%s%s", szInfPath, szThisLang, Slash, szThisLang, szDatExt);
hCtrFile = FindFirstFileW(szCtrFile, & FindCtrFile);
hHlpFile = FindFirstFileW(szHlpFile, & FindHlpFile);
if (hCtrFile == INVALID_HANDLE_VALUE || hHlpFile == INVALID_HANDLE_VALUE) {
szThisLang = (LPWSTR) DefaultLangId;
ZeroMemory(szCtrFile, dw1Size * sizeof(WCHAR));
hr = StringCchPrintfW(szCtrFile, dw1Size, L"%s%s%s*d%s%s", szInfPath, szThisLang, Slash, szThisLang, szDatExt);
ZeroMemory(szHlpFile, dw1Size * sizeof(WCHAR));
hr = StringCchPrintfW(szHlpFile, dw1Size, L"%s%s%s*i%s%s", szInfPath, szThisLang, Slash, szThisLang, szDatExt);
hCtrFile = FindFirstFileW(szCtrFile, & FindCtrFile);
hHlpFile = FindFirstFileW(szHlpFile, & FindHlpFile);
}
if (hCtrFile != INVALID_HANDLE_VALUE && hHlpFile != INVALID_HANDLE_VALUE) {
ZeroMemory(szCtrFile, dw1Size * sizeof(WCHAR));
hr = StringCchPrintfW(szCtrFile, dw1Size, L"%s%s%s%s", szInfPath, szThisLang, Slash, FindCtrFile.cFileName);
ZeroMemory(szHlpFile, dw1Size * sizeof(WCHAR));
hr = StringCchPrintfW(szHlpFile, dw1Size, L"%s%s%s%s", szInfPath, szThisLang, Slash, FindHlpFile.cFileName);
FindClose(hCtrFile);
FindClose(hHlpFile);
dwStatus = UpdatePerfNameFilesX(szCtrFile, szHlpFile, szLangID, LODCTR_UPNF_REPAIR);
}
else {
dwStatus = GetLastError();
}
if (dwStatus == ERROR_SUCCESS) {
dwIndex ++;
dwSize = 8;
ZeroMemory(szLangID, 8 * sizeof(WCHAR));
dwStatus = RegEnumKeyExW(hKeyPerflib, dwIndex, szLangID, & dwSize, NULL, NULL, NULL, NULL);
}
}
if (dwStatus == ERROR_NO_MORE_ITEMS) dwStatus = ERROR_SUCCESS;
if (dwStatus != ERROR_SUCCESS) goto Cleanup;
do {
MemoryFree(mszService);
mszService = NULL;
MemoryFree(mszNonService);
mszNonService = NULL;
dwService += DUMPLOAD_SERVICE_SIZE;
dwNonService += DUMPLOAD_NOSERVICE_SIZE;
mszService = MemoryAllocate(dwService * sizeof(WCHAR));
mszNonService = MemoryAllocate(dwNonService * sizeof(WCHAR));
if (mszService == NULL || mszNonService == NULL) {
dwStatus = ERROR_OUTOFMEMORY;
break;
}
if (dwStatus == ERROR_SUCCESS) {
dwStatus = BuildServiceLists(mszService, & dwService, mszNonService, & dwNonService);
}
}
while (dwStatus == ERROR_MORE_DATA && dwService < DUMPLOAD_MAX_SERVICE_SIZE);
if (dwStatus != ERROR_SUCCESS) goto Cleanup;
dwObjectList = LOADPERF_BUFF_SIZE;
mszObjectList = MemoryAllocate(dwObjectList * sizeof(WCHAR));
if (mszObjectList == NULL) {
dwStatus = ERROR_OUTOFMEMORY;
goto Cleanup;
}
for (szThisService = mszService;
szThisService != NULL && szThisService[0] != cNull && dwStatus == ERROR_SUCCESS;
szThisService += (lstrlenW(szThisService) + 1)) {
pThisService = (PSERVICE_ENTRY) MemoryAllocate(sizeof(SERVICE_ENTRY)
+ sizeof(WCHAR) * (MAX_PATH + lstrlenW(szThisService) + 1));
if (pThisService == NULL) {
dwStatus = ERROR_OUTOFMEMORY;
goto Cleanup;
}
pThisService->pNext = ServiceList;
ServiceList = pThisService;
pThisService->szIniFile = (LPWSTR) (((LPBYTE) pThisService) + sizeof(SERVICE_ENTRY));
pThisService->szService = (LPWSTR) (((LPBYTE) pThisService->szIniFile) + sizeof(WCHAR) * MAX_PATH);
hr = StringCchCopyW(pThisService->szService, lstrlenW(szThisService) + 1, szThisService);
ZeroMemory(mszObjectList, dwObjectList * sizeof(WCHAR));
dwStatus = DumpPerfServiceEntries(NULL,
pThisService->szService,
& pThisService->dwFirstCounter,
& pThisService->dwFirstHelp,
& pThisService->dwLastCounter,
& pThisService->dwLastHelp,
& pThisService->dwDisable,
pThisService->szIniFile,
MAX_PATH,
mszObjectList,
dwObjectList,
TRUE);
if (dwStatus == ERROR_SUCCESS) {
LPWSTR szObjectId = mszObjectList;
pThisService->dwNumObjects = 0;
while ((szObjectId != NULL) && (* szObjectId != cNull)) {
if (pThisService->dwNumObjects
>= MAX_PERF_OBJECTS_IN_QUERY_FUNCTION) {
break;
}
pThisService->dwObjects[pThisService->dwNumObjects] =
wcstoul(szObjectId, NULL, 10) - pThisService->dwFirstCounter;
pThisService->dwNumObjects ++;
szObjectId += (lstrlenW(szObjectId) + 1);
}
}
}
for (pThisService = ServiceList; pThisService != NULL; pThisService = pThisService->pNext) {
if (pThisService->szIniFile[0] != cNull) {
dwStatus = LoadPerfInstallPerfDll(LODCTR_UPNF_REPAIR,
NULL,
pThisService->szService,
pThisService->szIniFile,
NULL,
NULL,
LOADPERF_FLAGS_LOAD_REGISTRY_ONLY);
}
else {
dwStatus = LoadPerfInstallPerfDll(LODCTR_UPNF_REPAIR | LODCTR_UPNF_NOINI,
NULL,
pThisService->szService,
NULL,
LangList,
pThisService,
LOADPERF_FLAGS_LOAD_REGISTRY_ONLY);
}
if (dwStatus != ERROR_SUCCESS) {
ReportLoadPerfEvent(
EVENTLOG_WARNING_TYPE,
(DWORD) LDPRFMSG_REPAIR_SERVICE_FAIL,
2, dwStatus, __LINE__, 0, 0,
1, (LPWSTR) pThisService->szService, NULL, NULL);
}
}
Cleanup:
if (hKeyPerflib != NULL) RegCloseKey(hKeyPerflib);
MemoryFree(szCtrFile);
MemoryFree(mszObjectList);
MemoryFree(mszService);
MemoryFree(mszNonService);
pThisLang = LangList;
while (pThisLang != NULL) {
PLANG_ENTRY pTmpLang = pThisLang;
pThisLang = pThisLang->pNext;
MemoryFree(pTmpLang->lpText);
MemoryFree(pTmpLang);
}
pThisService = ServiceList;
while (pThisService != NULL) {
PSERVICE_ENTRY pTmpService = pThisService;
pThisService = pThisService->pNext;
MemoryFree(pTmpService);
}
ReleaseMutex(hLoadPerfMutex);
return dwStatus;
}
DWORD
RestorePerfRegistryFromFileW(
IN LPCWSTR szFileName,
IN LPCWSTR szLangId
)
{
LONG lEnumStatus = ERROR_SUCCESS;
DWORD dwServiceIndex = 0;
LPWSTR szServiceSubKeyName = NULL;
LPWSTR szPerfSubKeyName = NULL;
LPWSTR wPerfSection = NULL;
DWORD dwNameSize = MAX_PATH;
HKEY hKeyPerformance;
HKEY hKeyServices = NULL;
HKEY hKeyPerflib = NULL;
DWORD dwRegAccessMask;
DWORD dwRetStatus = ERROR_SUCCESS;
UINT nValue;
DWORD dwnValue;
BOOL bServiceRegistryOk = TRUE;
WCHAR szLocalLangId[8];
HRESULT hr;
WinPerfStartTrace(NULL);
if (szFileName == NULL) {
// this is the case to repair performance registry.
//
dwRetStatus = LoadPerfRepairPerfRegistry();
goto Cleanup;
}
else {
__try {
DWORD dwName = lstrlenW(szFileName);
if (dwName == 0) dwRetStatus = ERROR_INVALID_PARAMETER;
if (szLangId != NULL) {
dwName = lstrlenW(szLangId);
if (dwName == 0) dwRetStatus = ERROR_INVALID_PARAMETER;
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwRetStatus = ERROR_INVALID_PARAMETER;
}
}
if (dwRetStatus != ERROR_SUCCESS) goto Cleanup;
szServiceSubKeyName = MemoryAllocate(MAX_PATH * sizeof(WCHAR));
szPerfSubKeyName = MemoryAllocate((MAX_PATH + 32) * sizeof(WCHAR));
wPerfSection = MemoryAllocate((MAX_PATH + 32) * sizeof(WCHAR));
if (szServiceSubKeyName == NULL || szPerfSubKeyName == NULL || wPerfSection == NULL) {
dwRetStatus = ERROR_OUTOFMEMORY;
goto Cleanup;
}
__try {
dwRetStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, DriverPathRoot, 0L, KEY_READ, & hKeyServices);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwRetStatus = GetExceptionCode();
}
if (dwRetStatus == ERROR_SUCCESS) {
// enum service list
dwNameSize = MAX_PATH;
ZeroMemory(szServiceSubKeyName, MAX_PATH * sizeof(WCHAR));
ZeroMemory(szPerfSubKeyName, (MAX_PATH + 32) * sizeof(WCHAR));
while ((lEnumStatus = RegEnumKeyExW(hKeyServices,
dwServiceIndex,
szServiceSubKeyName,
& dwNameSize,
NULL, NULL, NULL, NULL)) == ERROR_SUCCESS) {
//try to open the perfkey under this key.
hr = StringCchPrintfW(szPerfSubKeyName, MAX_PATH + 32, L"%ws%ws%ws", szServiceSubKeyName, Slash, Performance);
bServiceRegistryOk = TRUE;
dwRegAccessMask = KEY_READ | KEY_WRITE;
// look for a performance subkey
__try {
dwRetStatus = RegOpenKeyExW(hKeyServices, szPerfSubKeyName, 0L, dwRegAccessMask, & hKeyPerformance);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwRetStatus = GetExceptionCode();
}
if (dwRetStatus == ERROR_SUCCESS) {
// key found so service has perf data
// if performance subkey then
hr = StringCchPrintfW(wPerfSection, MAX_PATH + 32, cszFmtServiceSectionName, szServiceSubKeyName);
// look into the file for a perf entry for this service
nValue = GetPrivateProfileIntW(wPerfSection, FirstCounter, -1, szFileName);
if (nValue != (UINT) -1) {
// if found in file then update registry with values from file
__try {
dwRetStatus = RegSetValueExW(hKeyPerformance,
FirstCounter,
0L,
REG_DWORD,
(const BYTE *) & nValue,
sizeof(nValue));
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwRetStatus = GetExceptionCode();
}
dwnValue = nValue;
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2)
| ARG_DEF(ARG_TYPE_WSTR, 3),
dwRetStatus,
TRACE_WSTR(szFileName),
TRACE_WSTR(szServiceSubKeyName),
TRACE_WSTR(FirstCounter),
TRACE_DWORD(dwnValue),
NULL));
// now read the other values
}
else {
// there's one or more missing entries so
// remove the whole entry
bServiceRegistryOk = FALSE;
}
// look into the file for a perf entry for this service
nValue = GetPrivateProfileIntW(wPerfSection, FirstHelp, -1, szFileName);
if (nValue != (UINT) -1) {
// if found in file then update registry with values from file
__try {
dwRetStatus = RegSetValueExW(hKeyPerformance,
FirstHelp,
0L,
REG_DWORD,
(const BYTE *) & nValue,
sizeof(nValue));
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwRetStatus = GetExceptionCode();
}
dwnValue = nValue;
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2)
| ARG_DEF(ARG_TYPE_WSTR, 3),
dwRetStatus,
TRACE_WSTR(szFileName),
TRACE_WSTR(szServiceSubKeyName),
TRACE_WSTR(FirstHelp),
TRACE_DWORD(dwnValue),
NULL));
// now read the other values
}
else {
// there's one or more missing entries so
// remove the whole entry
bServiceRegistryOk = FALSE;
}
// look into the file for a perf entry for this service
nValue = GetPrivateProfileIntW(wPerfSection, LastCounter, -1, szFileName);
if (nValue != (UINT) -1) {
// if found in file then update registry with values from file
__try {
dwRetStatus = RegSetValueExW(hKeyPerformance,
LastCounter,
0L,
REG_DWORD,
(const BYTE *) & nValue,
sizeof(nValue));
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwRetStatus = GetExceptionCode();
}
dwnValue = nValue;
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2)
| ARG_DEF(ARG_TYPE_WSTR, 3),
dwRetStatus,
TRACE_WSTR(szFileName),
TRACE_WSTR(szServiceSubKeyName),
TRACE_WSTR(LastCounter),
TRACE_DWORD(dwnValue),
NULL));
// now read the other values
}
else {
// there's one or more missing entries so
// remove the whole entry
bServiceRegistryOk = FALSE;
}
// look into the file for a perf entry for this service
nValue = GetPrivateProfileIntW(wPerfSection, LastHelp, -1, szFileName);
if (nValue != (UINT) -1) {
// if found in file then update registry with values from file
__try {
dwRetStatus = RegSetValueExW(hKeyPerformance,
LastHelp,
0L,
REG_DWORD,
(const BYTE *) & nValue,
sizeof(nValue));
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwRetStatus = GetExceptionCode();
}
dwnValue = nValue;
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2)
| ARG_DEF(ARG_TYPE_WSTR, 3),
dwRetStatus,
TRACE_WSTR(szFileName),
TRACE_WSTR(szServiceSubKeyName),
TRACE_WSTR(LastHelp),
TRACE_DWORD(dwnValue),
NULL));
// now read the other values
}
else {
// there's one or more missing entries so
// remove the whole entry
bServiceRegistryOk = FALSE;
}
if (! bServiceRegistryOk) {
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
ERROR_SUCCESS,
TRACE_WSTR(szFileName),
TRACE_WSTR(szServiceSubKeyName),
NULL));
// an error occurred so delete the first/last counter/help values
RegDeleteValueW(hKeyPerformance, FirstCounter);
RegDeleteValueW(hKeyPerformance, FirstHelp);
RegDeleteValueW(hKeyPerformance, LastCounter);
RegDeleteValueW(hKeyPerformance, LastHelp);
} // else continiue
RegCloseKey (hKeyPerformance);
} // else this service has no perf data so skip
else {
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
ARG_DEF(ARG_TYPE_WSTR, 1),
dwRetStatus,
TRACE_WSTR(szServiceSubKeyName),
NULL));
if (dwRetStatus != ERROR_FILE_NOT_FOUND && dwRetStatus != ERROR_NO_MORE_ITEMS) break;
}
// reset for next loop
dwServiceIndex ++;
dwNameSize = MAX_PATH;
ZeroMemory(szServiceSubKeyName, MAX_PATH * sizeof(WCHAR));
ZeroMemory(szPerfSubKeyName, (MAX_PATH + 32) * sizeof(WCHAR));
} // end enum service list
if (dwRetStatus == ERROR_NO_MORE_ITEMS || dwRetStatus == ERROR_FILE_NOT_FOUND) dwRetStatus = ERROR_SUCCESS;
}
else {
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
ARG_DEF(ARG_TYPE_WSTR, 1),
dwRetStatus,
TRACE_WSTR(DriverPathRoot),
NULL));
}
if (hKeyServices != NULL) RegCloseKey(hKeyServices);
if (dwRetStatus == ERROR_SUCCESS) {
__try {
dwRetStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, NamesKey, RESERVED, KEY_ALL_ACCESS, & hKeyPerflib);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwRetStatus = GetExceptionCode();
}
if (dwRetStatus != ERROR_SUCCESS) {
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
ARG_DEF(ARG_TYPE_WSTR, 1),
dwRetStatus,
TRACE_WSTR(NamesKey),
NULL));
}
if (szLangId != NULL) {
// merge registry string values:
hr = StringCchCopyW(szLocalLangId, 8, szLangId);
dwRetStatus = UpdatePerfNameFilesX(szFileName, NULL, szLocalLangId, LODCTR_UPNF_RESTORE);
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
dwRetStatus,
TRACE_WSTR(szFileName),
TRACE_WSTR(szLocalLangId),
NULL));
}
else if (dwRetStatus == ERROR_SUCCESS) {
DWORD dwIndex = 0;
DWORD dwBufferSize;
while (dwRetStatus == ERROR_SUCCESS) {
dwBufferSize = 8;
ZeroMemory(szLocalLangId, 8 * sizeof(WCHAR));
dwRetStatus = RegEnumKeyExW(hKeyPerflib,
dwIndex,
szLocalLangId,
& dwBufferSize,
NULL,
NULL,
NULL,
NULL);
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
ARG_DEF(ARG_TYPE_WSTR, 1),
dwRetStatus,
TRACE_WSTR(szLocalLangId),
TRACE_DWORD(dwIndex),
TRACE_DWORD(dwBufferSize),
NULL));
if (dwRetStatus == ERROR_SUCCESS) {
dwRetStatus = UpdatePerfNameFilesX(szFileName, NULL, szLocalLangId, LODCTR_UPNF_RESTORE);
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
dwRetStatus,
TRACE_WSTR(szFileName),
TRACE_WSTR(szLocalLangId),
NULL));
}
dwIndex ++;
}
if (dwRetStatus == ERROR_NO_MORE_ITEMS) {
dwRetStatus = ERROR_SUCCESS;
}
}
if (dwRetStatus == ERROR_SUCCESS) {
// update the keys in the registry
if (dwRetStatus == ERROR_SUCCESS) {
nValue = GetPrivateProfileIntW(cszPerflib, LastCounter, -1, szFileName);
if (nValue != (UINT) -1) {
// if found in file then update registry with values from file
__try {
dwRetStatus = RegSetValueExW(hKeyPerflib,
LastCounter,
0L,
REG_DWORD,
(const BYTE *) & nValue,
sizeof(nValue));
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwRetStatus = GetExceptionCode();
}
dwnValue = nValue;
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
ARG_DEF(ARG_TYPE_WSTR, 1),
dwRetStatus,
TRACE_WSTR(LastCounter),
TRACE_DWORD(dwnValue),
NULL));
}
}
if (dwRetStatus == ERROR_SUCCESS) {
// look into the file for a perf entry for this service
nValue = GetPrivateProfileIntW(cszPerflib, LastHelp, -1, szFileName);
if (nValue != (UINT) -1) {
// if found in file then update registry with values from file
__try {
dwRetStatus = RegSetValueExW(hKeyPerflib,
LastHelp,
0L,
REG_DWORD,
(const BYTE *) & nValue,
sizeof(nValue));
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwRetStatus = GetExceptionCode();
}
dwnValue = nValue;
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
ARG_DEF(ARG_TYPE_WSTR, 1),
dwRetStatus,
TRACE_WSTR(LastHelp),
TRACE_DWORD(dwnValue),
NULL));
}
}
if (dwRetStatus == ERROR_SUCCESS) {
// look into the file for a perf entry for this service
nValue = GetPrivateProfileIntW(cszPerflib, BaseIndex, -1, szFileName);
if (nValue != (UINT) -1) {
// if found in file then update registry with values from file
__try {
dwRetStatus = RegSetValueExW(hKeyPerflib,
BaseIndex,
0L,
REG_DWORD,
(const BYTE *) & nValue,
sizeof(nValue));
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwRetStatus = GetExceptionCode();
}
dwnValue = nValue;
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_RESTOREPERFREGISTRYFROMFILEW,
ARG_DEF(ARG_TYPE_WSTR, 1),
dwRetStatus,
TRACE_WSTR(BaseIndex),
TRACE_DWORD(dwnValue),
NULL));
}
}
}
if (hKeyPerflib != NULL && hKeyPerflib != INVALID_HANDLE_VALUE) RegCloseKey(hKeyPerflib);
dwRetStatus = dwRetStatus;
}
Cleanup:
MemoryFree(szServiceSubKeyName);
MemoryFree(szPerfSubKeyName);
MemoryFree(wPerfSection);
return dwRetStatus;
}