|
|
/*++
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:
--*/ #ifndef UNICODE
#define UNICODE 1
#endif
#ifndef _UNICODE
#define _UNICODE 1
#endif
//
// "C" Include files
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
//
// Windows Include files
//
#include <windows.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"
static const WCHAR cszServiceKeyName[] = {L"SYSTEM\\CurrentControlSet\\Services"}; static const WCHAR cszPerflibKeyName[] = {L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib"}; static const WCHAR cszLastCounter[] = {L"Last Counter"}; static const WCHAR cszFirstHelp[] = {L"First Help"}; static const WCHAR cszLastHelp[] = {L"Last Help"}; static const WCHAR cszBaseIndex[] = {L"Base Index"}; static const WCHAR cszPerformance[] = {L"\\Performance"}; static const WCHAR cszDisablePerformanceCounters[] = {L"Disable Performance Counters"};
// headings in save file
static const WCHAR cszFmtSectionHeader[] = {L"\r\n\r\n[%s]"}; static const WCHAR cszFmtServiceSectionHeader[] = {L"\r\n\r\n[PERF_%s]"}; static const WCHAR cszFmtServiceSectionName[] = {L"PERF_%s"}; static const WCHAR cszFmtStringSectionHeader[] = {L"\r\n\r\n[PerfStrings_%s]"}; static const WCHAR cszFmtExtCtrString[] = {L"\r\n%d=%s"}; static const WCHAR cszFmtDecimalParam[] = {L"\r\n%s=%d"}; static const WCHAR cszFmtNoParam[] = {L"\r\n%s="};
static const WCHAR cszExtensiblePerfStrings[] = {L"Strings"}; static const WCHAR cszPerfCounterServices[] = {L"PerfCounterServices"}; static const WCHAR cszNoPerfCounterServices[] = {L"NoPerfCounterServices"}; static const WCHAR cszPerflib[] = {L"Perflib"};
// external forward definitions
LPWSTR *BuildNameTable( HKEY hKeyRegistry, // handle to registry db with counter names
LPWSTR lpszLangId, // unicode value of Language subkey
PDWORD pdwLastItem // size of array in elements
);
DWORD UpdatePerfNameFilesX ( IN LPCWSTR szNewCtrFilePath, // data file with new base counter strings
IN LPCWSTR szNewHlpFilePath, // data file with new base counter strings
IN LPWSTR szLanguageID, // Lang ID to update
IN ULONG_PTR dwFlags // flags
);
DWORD static DumpNameTable ( IN HANDLE hOutputFile, IN LPCWSTR szLangId, IN LPCWSTR *pszNameTable, IN DWORD dwStartIndex, IN DWORD dwLastIndex ) { DWORD ndx; WCHAR szOutputBuffer[4096]; DWORD dwSize, dwSizeWritten;
dwSize = swprintf (szOutputBuffer, cszFmtStringSectionHeader, szLangId); dwSize *= sizeof (WCHAR);
WriteFile (hOutputFile, szOutputBuffer, dwSize, &dwSizeWritten, NULL);
for (ndx = dwStartIndex; ndx <= dwLastIndex; ndx++) { if (pszNameTable[ndx] != NULL) { dwSize = swprintf (szOutputBuffer, cszFmtExtCtrString, ndx, pszNameTable[ndx] ); dwSize *= sizeof (WCHAR); WriteFile (hOutputFile, szOutputBuffer, dwSize, &dwSizeWritten, NULL); } }
return ERROR_SUCCESS; }
DWORD static DumpPerfServiceEntries ( IN HANDLE hOutputFile, IN LPCWSTR szServiceName ) { LONG lStatus = ERROR_SUCCESS; WCHAR szPerfSubKeyName[MAX_PATH+20]; HKEY hKeyPerformance; HKEY hKeyServices = NULL; DWORD dwItemSize, dwType, dwValue; DWORD dwRegAccessMask; DWORD dwRetStatus = ERROR_SUCCESS;
DWORD dwSize, dwSizeWritten; WCHAR szOutputBuffer[4096];
// try read-only then
dwRegAccessMask = KEY_READ; lStatus = RegOpenKeyExW (HKEY_LOCAL_MACHINE, cszServiceKeyName, 0L, dwRegAccessMask, &hKeyServices);
if (lStatus == ERROR_SUCCESS) { //try to open the perfkey under this key.
lstrcpy (szPerfSubKeyName, szServiceName); lstrcat (szPerfSubKeyName, cszPerformance);
lStatus = RegOpenKeyExW ( hKeyServices, szPerfSubKeyName, 0L, dwRegAccessMask, &hKeyPerformance);
if (lStatus == ERROR_SUCCESS) { // key found so service has perf data
dwSize = swprintf (szOutputBuffer, cszFmtServiceSectionHeader, szServiceName); dwSize *= sizeof (WCHAR); WriteFile (hOutputFile, szOutputBuffer, dwSize, &dwSizeWritten, NULL);
// now check to see if the strings have been loaded
dwType = dwValue = 0; dwItemSize = sizeof (dwValue); lStatus = RegQueryValueExW ( hKeyPerformance, cszFirstCounter, NULL, &dwType, (LPBYTE)&dwValue, &dwItemSize); TRACE((WINPERF_DBG_TRACE_INFO), (& LoadPerfGuid, __LINE__, LOADPERF_DUMPPERFSERVICEENTRIES, ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2), lStatus, TRACE_WSTR(szServiceName), TRACE_WSTR(cszFirstCounter), TRACE_DWORD(dwValue), NULL)); if ((lStatus == ERROR_SUCCESS) && ((dwType == REG_DWORD) || dwType == REG_BINARY)) { dwSize = swprintf (szOutputBuffer, cszFmtDecimalParam, cszFirstCounter, dwValue); dwSize *= sizeof (WCHAR); WriteFile (hOutputFile, szOutputBuffer, dwSize, &dwSizeWritten, NULL); }
dwType = dwValue = 0; dwItemSize = sizeof (dwValue); lStatus = RegQueryValueExW ( hKeyPerformance, cszFirstHelp, NULL, &dwType, (LPBYTE)&dwValue, &dwItemSize); TRACE((WINPERF_DBG_TRACE_INFO), (& LoadPerfGuid, __LINE__, LOADPERF_DUMPPERFSERVICEENTRIES, ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2), lStatus, TRACE_WSTR(szServiceName), TRACE_WSTR(cszFirstHelp), TRACE_DWORD(dwValue), NULL)); if ((lStatus == ERROR_SUCCESS) && ((dwType == REG_DWORD) || dwType == REG_BINARY)) { dwSize = swprintf (szOutputBuffer, cszFmtDecimalParam, cszFirstHelp, dwValue); dwSize *= sizeof (WCHAR); WriteFile (hOutputFile, szOutputBuffer, dwSize, &dwSizeWritten, NULL); }
dwType = dwValue = 0; dwItemSize = sizeof (dwValue); lStatus = RegQueryValueExW ( hKeyPerformance, cszLastCounter, NULL, &dwType, (LPBYTE)&dwValue, &dwItemSize); TRACE((WINPERF_DBG_TRACE_INFO), (& LoadPerfGuid, __LINE__, LOADPERF_DUMPPERFSERVICEENTRIES, ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2), lStatus, TRACE_WSTR(szServiceName), TRACE_WSTR(cszLastCounter), TRACE_DWORD(dwValue), NULL)); if ((lStatus == ERROR_SUCCESS) && ((dwType == REG_DWORD) || dwType == REG_BINARY)) { dwSize = swprintf (szOutputBuffer, cszFmtDecimalParam, cszLastCounter, dwValue); dwSize *= sizeof (WCHAR); WriteFile (hOutputFile, szOutputBuffer, dwSize, &dwSizeWritten, NULL); }
dwType = dwValue = 0; dwItemSize = sizeof (dwValue); lStatus = RegQueryValueExW ( hKeyPerformance, cszLastHelp, NULL, &dwType, (LPBYTE)&dwValue, &dwItemSize); TRACE((WINPERF_DBG_TRACE_INFO), (& LoadPerfGuid, __LINE__, LOADPERF_DUMPPERFSERVICEENTRIES, ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2), lStatus, TRACE_WSTR(szServiceName), TRACE_WSTR(cszLastHelp), TRACE_DWORD(dwValue), NULL)); if ((lStatus == ERROR_SUCCESS) && ((dwType == REG_DWORD) || dwType == REG_BINARY)) { dwSize = swprintf (szOutputBuffer, cszFmtDecimalParam, cszLastHelp, dwValue); dwSize *= sizeof (WCHAR); WriteFile (hOutputFile, szOutputBuffer, dwSize, &dwSizeWritten, NULL); }
dwType = dwValue = 0; dwItemSize = sizeof (dwValue); lStatus = RegQueryValueExW ( hKeyPerformance, cszDisablePerformanceCounters, NULL, &dwType, (LPBYTE)&dwValue, &dwItemSize); TRACE((WINPERF_DBG_TRACE_INFO), (& LoadPerfGuid, __LINE__, LOADPERF_DUMPPERFSERVICEENTRIES, ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2), lStatus, TRACE_WSTR(szServiceName), TRACE_WSTR(cszDisablePerformanceCounters), TRACE_DWORD(dwValue), NULL)); if ((lStatus == ERROR_SUCCESS) && ((dwType == REG_DWORD) || dwType == REG_BINARY)) { dwSize = swprintf (szOutputBuffer, cszFmtDecimalParam, cszDisablePerformanceCounters, dwValue); dwSize *= sizeof (WCHAR); WriteFile (hOutputFile, szOutputBuffer, dwSize, &dwSizeWritten, NULL); }
RegCloseKey (hKeyPerformance); } else { dwRetStatus = lStatus; TRACE((WINPERF_DBG_TRACE_ERROR), (& LoadPerfGuid, __LINE__, LOADPERF_DUMPPERFSERVICEENTRIES, ARG_DEF(ARG_TYPE_WSTR, 1), lStatus, TRACE_WSTR(szServiceName), NULL)); }
RegCloseKey (hKeyServices); } else { dwRetStatus = lStatus; TRACE((WINPERF_DBG_TRACE_ERROR), (& LoadPerfGuid, __LINE__, LOADPERF_DUMPPERFSERVICEENTRIES, ARG_DEF(ARG_TYPE_WSTR, 1), lStatus, TRACE_WSTR(cszServiceKeyName), NULL)); }
return dwRetStatus; }
DWORD static DumpPerflibEntries ( IN HANDLE hOutputFile, IN LPDWORD pdwFirstExtCtrIndex
) { HKEY hKeyPerflib = NULL; DWORD dwStatus; DWORD dwItemSize, dwType, dwValue;
DWORD dwSize, dwSizeWritten; WCHAR szOutputBuffer[4096];
dwStatus = RegOpenKeyExW (HKEY_LOCAL_MACHINE, cszPerflibKeyName, 0L, KEY_READ, &hKeyPerflib);
if (dwStatus == ERROR_SUCCESS) { dwSize = swprintf (szOutputBuffer, cszFmtSectionHeader, cszPerflib); dwSize *= 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(cszPerflibKeyName), NULL)); }
if (dwStatus == ERROR_SUCCESS) { dwType = dwValue = 0; dwItemSize = sizeof (dwValue); dwStatus = RegQueryValueEx ( hKeyPerflib, cszBaseIndex, NULL, &dwType, (LPBYTE)&dwValue, &dwItemSize); TRACE((WINPERF_DBG_TRACE_INFO), (& LoadPerfGuid, __LINE__, LOADPERF_DUMPPERFLIBENTRIES, ARG_DEF(ARG_TYPE_WSTR, 1), dwStatus, TRACE_WSTR(cszBaseIndex), TRACE_DWORD(dwValue), NULL)); if ((dwStatus == ERROR_SUCCESS) && (dwType == REG_DWORD)) { dwSize = swprintf (szOutputBuffer, cszFmtDecimalParam, cszBaseIndex, dwValue); dwSize *= sizeof (WCHAR); WriteFile (hOutputFile, szOutputBuffer, dwSize, &dwSizeWritten, NULL); *pdwFirstExtCtrIndex = dwValue + 1; } }
if (dwStatus == ERROR_SUCCESS) { dwType = dwValue = 0; dwItemSize = sizeof (dwValue); dwStatus = RegQueryValueEx ( hKeyPerflib, cszLastCounter, NULL, &dwType, (LPBYTE)&dwValue, &dwItemSize); TRACE((WINPERF_DBG_TRACE_INFO), (& LoadPerfGuid, __LINE__, LOADPERF_DUMPPERFLIBENTRIES, ARG_DEF(ARG_TYPE_WSTR, 1), dwStatus, TRACE_WSTR(cszLastCounter), TRACE_DWORD(dwValue), NULL)); if ((dwStatus == ERROR_SUCCESS) && (dwType == REG_DWORD)) { dwSize = swprintf (szOutputBuffer, cszFmtDecimalParam, cszLastCounter, dwValue); dwSize *= sizeof (WCHAR); WriteFile (hOutputFile, szOutputBuffer, dwSize, &dwSizeWritten, NULL); } }
if (dwStatus == ERROR_SUCCESS) { dwType = dwValue = 0; dwItemSize = sizeof (dwValue); dwStatus = RegQueryValueEx ( hKeyPerflib, cszLastHelp, NULL, &dwType, (LPBYTE)&dwValue, &dwItemSize); TRACE((WINPERF_DBG_TRACE_INFO), (& LoadPerfGuid, __LINE__, LOADPERF_DUMPPERFLIBENTRIES, ARG_DEF(ARG_TYPE_WSTR, 1), dwStatus, TRACE_WSTR(cszLastHelp), TRACE_DWORD(dwValue), NULL)); if ((dwStatus == ERROR_SUCCESS) && (dwType == REG_DWORD)) { dwSize = swprintf (szOutputBuffer, cszFmtDecimalParam, cszLastHelp, dwValue); dwSize *= sizeof (WCHAR); WriteFile (hOutputFile, szOutputBuffer, dwSize, &dwSizeWritten, NULL); } }
if (hKeyPerflib != NULL) RegCloseKey (hKeyPerflib);
return dwStatus; }
DWORD static BuildServiceLists ( IN LPWSTR mszPerfServiceList, IN LPDWORD pcchPerfServiceListSize, IN LPWSTR mszNoPerfServiceList, IN LPDWORD pcchNoPerfServiceListSize ) { LONG lStatus = ERROR_SUCCESS; LONG lEnumStatus = ERROR_SUCCESS; DWORD dwServiceIndex = 0; WCHAR szServiceSubKeyName[MAX_PATH]; WCHAR szPerfSubKeyName[MAX_PATH+20]; 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;
// try read-only then
dwRegAccessMask = KEY_READ; lStatus = RegOpenKeyExW (HKEY_LOCAL_MACHINE, cszServiceKeyName, 0L, dwRegAccessMask, &hKeyServices);
if (lStatus == ERROR_SUCCESS) { szNextNoPerfChar = mszNoPerfServiceList; szNextPerfChar = mszPerfServiceList; dwNoPerfSizeRem = *pcchPerfServiceListSize; dwPerfSizeRem = *pcchNoPerfServiceListSize; dwPerfSizeUsed = 0; dwNoPerfSizeUsed = 0;
while ((lEnumStatus = RegEnumKeyExW ( hKeyServices, dwServiceIndex, szServiceSubKeyName, &dwNameSize, NULL, NULL, NULL, NULL)) == ERROR_SUCCESS) {
//try to open the perfkey under this key.
lstrcpy (szPerfSubKeyName, szServiceSubKeyName); lstrcat (szPerfSubKeyName, cszPerformance);
lStatus = RegOpenKeyExW ( hKeyServices, szPerfSubKeyName, 0L, dwRegAccessMask, &hKeyPerformance);
if (lStatus == 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); lStatus = RegQueryValueExW ( hKeyPerformance, cszFirstCounter, NULL, &dwType, (LPBYTE)&dwValue, &dwItemSize); if ((lStatus == 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; }
TRACE((WINPERF_DBG_TRACE_INFO), (& LoadPerfGuid, __LINE__, LOADPERF_BUILDSERVICELISTS, ARG_DEF(ARG_TYPE_WSTR, 1), lStatus, TRACE_WSTR(szServiceSubKeyName), TRACE_DWORD(bServiceHasPerfCounters), NULL));
if (bServiceHasPerfCounters != FALSE) { // add to the perf service list
if ((dwNameSize + 1)< dwPerfSizeRem) { // add to list
lstrcpyW (szNextPerfChar, szServiceSubKeyName); szNextPerfChar += dwNameSize; *szNextPerfChar = 0; szNextPerfChar++; dwPerfSizeRem -= dwNameSize + 1; } else { dwRetStatus = ERROR_MORE_DATA; } dwPerfSizeUsed += dwNameSize + 1; } else { // add to the no perf list
if ((dwNameSize + 1) < dwNoPerfSizeRem) { // add to list
lstrcpyW (szNextNoPerfChar, szServiceSubKeyName); szNextNoPerfChar += dwNameSize; *szNextNoPerfChar = 0; szNextNoPerfChar++; dwNoPerfSizeRem -= dwNameSize + 1; } else { dwRetStatus = ERROR_MORE_DATA; } dwNoPerfSizeUsed += dwNameSize + 1; } // reset for next loop
dwServiceIndex++; dwNameSize = MAX_PATH; }
// zero term the MSZ
if (1 < dwPerfSizeRem) { *szNextPerfChar = 0; szNextPerfChar++; dwPerfSizeRem -= 1; } else { dwRetStatus = ERROR_MORE_DATA; } dwPerfSizeUsed += 1;
// zero term the no perf list
if (1 < dwNoPerfSizeRem) { // add to list
*szNextNoPerfChar = 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), lStatus, TRACE_WSTR(cszServiceKeyName), NULL)); }
if (hKeyServices != NULL) RegCloseKey (hKeyServices);
*pcchPerfServiceListSize = dwPerfSizeUsed; *pcchNoPerfServiceListSize = dwNoPerfSizeUsed;
return dwRetStatus; }
DWORD BackupPerfRegistryToFileW ( IN LPCWSTR szFileName, IN LPCWSTR szCommentString ) { HANDLE hOutFile; 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;
LPWSTR szLangId = (LPWSTR)L"009";
DBG_UNREFERENCED_PARAMETER (szCommentString);
WinPerfStartTrace(NULL);
// 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); dwNewFileNameLen = dwOrigFileNameLen + 4; szNewFileName = HeapAlloc ( GetProcessHeap(), HEAP_ZERO_MEMORY, (dwNewFileNameLen +1) * sizeof(WCHAR)); if (szNewFileName != NULL) { lstrcpyW (szNewFileName, szFileName); for (dwFileNameSN = 1; dwFileNameSN < 1000; dwFileNameSN++) { swprintf (&szNewFileName[dwOrigFileNameLen], (LPCWSTR)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, &dwFirstExtCtrIndex); }
if (dwStatus == ERROR_SUCCESS) { do { if (mszPerfServiceList != NULL) { HeapFree (GetProcessHeap(), 0, mszPerfServiceList); mszPerfServiceList = NULL; }
if (mszNoPerfServiceList != NULL) { HeapFree (GetProcessHeap(), 0, mszNoPerfServiceList); mszNoPerfServiceList = NULL; }
// build service lists
dwPerfServiceListSize += 32768; dwNoPerfServiceListSize += 65536; mszPerfServiceList = HeapAlloc ( GetProcessHeap(), HEAP_ZERO_MEMORY, (dwPerfServiceListSize) * sizeof(WCHAR));
mszNoPerfServiceList = HeapAlloc ( GetProcessHeap(), HEAP_ZERO_MEMORY, (dwNoPerfServiceListSize) * sizeof(WCHAR));
if ((mszNoPerfServiceList == NULL) || (mszPerfServiceList == NULL)) { dwStatus = ERROR_OUTOFMEMORY; break; }
if (dwStatus == ERROR_SUCCESS) { dwStatus = BuildServiceLists ( mszPerfServiceList, &dwPerfServiceListSize, mszNoPerfServiceList, &dwNoPerfServiceListSize); if (dwStatus == ERROR_SUCCESS) break; // and continue on
} } while (dwPerfServiceListSize < 4194304); }
// 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);
if (dwStatus != ERROR_SUCCESS) break; } }
// dump perf string entries
if (dwStatus == ERROR_SUCCESS) { // build Name table
// get ENGLISH string list
lpCounterText = BuildNameTable ( HKEY_LOCAL_MACHINE, // use only local machine
(LPWSTR)szLangId, &dwLastElement);
if (lpCounterText != NULL) { dwStatus = DumpNameTable ( hOutFile, szLangId, lpCounterText, 0, // dump the entire table for complete restore
dwLastElement ); } else { dwStatus = GetLastError(); } }
// free buffers
if (lpCounterText != NULL) { HeapFree (GetProcessHeap(), 0, lpCounterText); lpCounterText = NULL; }
if (mszNoPerfServiceList != NULL) { HeapFree (GetProcessHeap(), 0, mszNoPerfServiceList); mszNoPerfServiceList = NULL; }
if (mszPerfServiceList != NULL) { HeapFree (GetProcessHeap(), 0, mszPerfServiceList); mszPerfServiceList = NULL; }
if (szNewFileName != NULL) { HeapFree (GetProcessHeap(), 0, szNewFileName); szNewFileName = NULL; }
// close file handles
if (hOutFile != INVALID_HANDLE_VALUE) { CloseHandle (hOutFile); }
return dwStatus; }
DWORD RestorePerfRegistryFromFileW ( IN LPCWSTR szFileName, IN LPCWSTR szLangId ) { LONG lStatus = ERROR_SUCCESS; LONG lEnumStatus = ERROR_SUCCESS; DWORD dwServiceIndex = 0; WCHAR szServiceSubKeyName[MAX_PATH]; WCHAR szPerfSubKeyName[MAX_PATH+20]; DWORD dwNameSize = MAX_PATH; HKEY hKeyPerformance; HKEY hKeyServices = NULL; HKEY hKeyPerflib = NULL; DWORD dwItemSize; DWORD dwRegAccessMask; DWORD dwRetStatus = ERROR_SUCCESS; UINT nValue; DWORD dwnValue; BOOL bServiceRegistryOk = TRUE;
WCHAR wPerfSection[MAX_PATH * 2];
LPWSTR szLocalLangId;
WinPerfStartTrace(NULL);
if (szLangId == NULL) { szLocalLangId = (LPWSTR)L"009"; } else { szLocalLangId = (LPWSTR)szLangId; }
lStatus = RegOpenKeyExW (HKEY_LOCAL_MACHINE, cszServiceKeyName, 0L, KEY_READ, &hKeyServices);
if (lStatus == ERROR_SUCCESS) { // enum service list
while ((lEnumStatus = RegEnumKeyExW ( hKeyServices, dwServiceIndex, szServiceSubKeyName, &dwNameSize, NULL, NULL, NULL, NULL)) == ERROR_SUCCESS) {
//try to open the perfkey under this key.
lstrcpy (szPerfSubKeyName, szServiceSubKeyName); lstrcat (szPerfSubKeyName, cszPerformance);
bServiceRegistryOk = TRUE; dwRegAccessMask = KEY_READ | KEY_WRITE; // look for a performance subkey
lStatus = RegOpenKeyExW ( hKeyServices, szPerfSubKeyName, 0L, dwRegAccessMask, &hKeyPerformance);
if (lStatus == ERROR_SUCCESS) { // key found so service has perf data
// if performance subkey then
dwItemSize = swprintf (wPerfSection, cszFmtServiceSectionName, szServiceSubKeyName); // look into the file for a perf entry for this service
nValue = GetPrivateProfileIntW ( wPerfSection, cszFirstCounter, -1, szFileName);
if (nValue != (UINT) -1) { // if found in file then update registry with values from file
lStatus = RegSetValueExW (hKeyPerformance, cszFirstCounter, 0L, REG_DWORD, (const BYTE *) & nValue, sizeof(nValue)); dwnValue = nValue; TRACE((WINPERF_DBG_TRACE_INFO), (& LoadPerfGuid, __LINE__, LOADPERF_RESTOREPERFREGISTRYFROMFILEW, ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2), lStatus, TRACE_WSTR(szServiceSubKeyName), TRACE_WSTR(cszFirstCounter), 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, cszFirstHelp, -1, szFileName);
if (nValue != (UINT)-1) { // if found in file then update registry with values from file
lStatus = RegSetValueExW (hKeyPerformance, cszFirstHelp, 0L, REG_DWORD, (const BYTE *)&nValue, sizeof(nValue)); dwnValue = nValue; TRACE((WINPERF_DBG_TRACE_INFO), (& LoadPerfGuid, __LINE__, LOADPERF_RESTOREPERFREGISTRYFROMFILEW, ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2), lStatus, TRACE_WSTR(szServiceSubKeyName), TRACE_WSTR(cszFirstHelp), 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, cszLastCounter, -1, szFileName);
if (nValue != (UINT)-1) { // if found in file then update registry with values from file
lStatus = RegSetValueExW (hKeyPerformance, cszLastCounter, 0L, REG_DWORD, (const BYTE *)&nValue, sizeof(nValue)); dwnValue = nValue; TRACE((WINPERF_DBG_TRACE_INFO), (& LoadPerfGuid, __LINE__, LOADPERF_RESTOREPERFREGISTRYFROMFILEW, ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2), lStatus, TRACE_WSTR(szServiceSubKeyName), TRACE_WSTR(cszLastCounter), 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, cszLastHelp, -1, szFileName);
if (nValue != (UINT)-1) { // if found in file then update registry with values from file
lStatus = RegSetValueExW (hKeyPerformance, cszLastHelp, 0L, REG_DWORD, (const BYTE *)&nValue, sizeof(nValue)); dwnValue = nValue; TRACE((WINPERF_DBG_TRACE_INFO), (& LoadPerfGuid, __LINE__, LOADPERF_RESTOREPERFREGISTRYFROMFILEW, ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2), lStatus, TRACE_WSTR(szServiceSubKeyName), TRACE_WSTR(cszLastHelp), 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) { // an error occurred so delete the first/last counter/help values
RegDeleteValue (hKeyPerformance, cszFirstCounter); RegDeleteValue (hKeyPerformance, cszFirstHelp); RegDeleteValue (hKeyPerformance, cszLastCounter); RegDeleteValue (hKeyPerformance, cszLastHelp); } // 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), lStatus, TRACE_WSTR(szServiceSubKeyName), NULL)); }
// reset for next loop
dwServiceIndex++; dwNameSize = MAX_PATH; } // end enum service list
} else { TRACE((WINPERF_DBG_TRACE_ERROR), (& LoadPerfGuid, __LINE__, LOADPERF_RESTOREPERFREGISTRYFROMFILEW, ARG_DEF(ARG_TYPE_WSTR, 1), lStatus, TRACE_WSTR(cszServiceKeyName), NULL)); }
if (hKeyServices != NULL) RegCloseKey (hKeyServices);
if (dwRetStatus == ERROR_SUCCESS) { // merge registry string values:
dwRetStatus = UpdatePerfNameFilesX ( szFileName, NULL, szLocalLangId, LODCTR_UPNF_RESTORE);
if (dwRetStatus == ERROR_SUCCESS) { // update the keys in the registry
lStatus = RegOpenKeyExW (HKEY_LOCAL_MACHINE, cszPerflibKeyName, 0L, KEY_ALL_ACCESS, &hKeyPerflib); if (lStatus != ERROR_SUCCESS) { TRACE((WINPERF_DBG_TRACE_ERROR), (& LoadPerfGuid, __LINE__, LOADPERF_RESTOREPERFREGISTRYFROMFILEW, ARG_DEF(ARG_TYPE_WSTR, 1), lStatus, TRACE_WSTR(cszPerflibKeyName), NULL)); }
if (lStatus == ERROR_SUCCESS) { nValue = GetPrivateProfileIntW ( cszPerflib, cszLastCounter, -1, szFileName);
if (nValue != (UINT)-1) { // if found in file then update registry with values from file
lStatus = RegSetValueExW (hKeyPerflib, cszLastCounter, 0L, REG_DWORD, (const BYTE *)&nValue, sizeof(nValue)); dwnValue = nValue; TRACE((WINPERF_DBG_TRACE_INFO), (& LoadPerfGuid, __LINE__, LOADPERF_RESTOREPERFREGISTRYFROMFILEW, ARG_DEF(ARG_TYPE_WSTR, 1), lStatus, TRACE_WSTR(cszLastCounter), TRACE_DWORD(dwnValue), NULL)); } }
if (lStatus == ERROR_SUCCESS) { // look into the file for a perf entry for this service
nValue = GetPrivateProfileIntW ( cszPerflib, cszLastHelp, -1, szFileName);
if (nValue != (UINT)-1) { // if found in file then update registry with values from file
lStatus = RegSetValueExW (hKeyPerflib, cszLastHelp, 0L, REG_DWORD, (const BYTE *)&nValue, sizeof(nValue)); dwnValue = nValue; TRACE((WINPERF_DBG_TRACE_INFO), (& LoadPerfGuid, __LINE__, LOADPERF_RESTOREPERFREGISTRYFROMFILEW, ARG_DEF(ARG_TYPE_WSTR, 1), lStatus, TRACE_WSTR(cszLastHelp), TRACE_DWORD(dwnValue), NULL)); } }
if (lStatus == ERROR_SUCCESS) { // look into the file for a perf entry for this service
nValue = GetPrivateProfileIntW ( cszPerflib, cszBaseIndex, -1, szFileName);
if (nValue != (UINT)-1) { // if found in file then update registry with values from file
lStatus = RegSetValueExW (hKeyPerflib, cszBaseIndex, 0L, REG_DWORD, (const BYTE *)&nValue, sizeof(nValue)); dwnValue = nValue; TRACE((WINPERF_DBG_TRACE_INFO), (& LoadPerfGuid, __LINE__, LOADPERF_RESTOREPERFREGISTRYFROMFILEW, ARG_DEF(ARG_TYPE_WSTR, 1), lStatus, TRACE_WSTR(cszBaseIndex), TRACE_DWORD(dwnValue), NULL)); } }
if (hKeyPerflib != NULL) RegCloseKey (hKeyPerflib); } dwRetStatus = lStatus; }
return dwRetStatus; }
|