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.
 
 
 
 
 
 

5877 lines
222 KiB

/*++
Copyright (c) 1991-1999 Microsoft Corporation
Module Name:
lodctr.c
Abstract:
Program to read the contents of the file specified in the command line
and update the registry accordingly
Author:
Bob Watson (a-robw) 10 Feb 93
Revision History:
a-robw 25-Feb-93 revised calls to make it compile as a UNICODE or
an ANSI app.
Bob Watson (bobw) 10 Mar 99 added event log messages
--*/
//
// Windows Include files
//
#include <windows.h>
#include "strsafe.h"
#include "stdlib.h"
#define __LOADPERF__
#include <loadperf.h>
#include <winperf.h>
#include "wmistr.h"
#include "evntrace.h"
//
// application include files
//
#include "winperfp.h"
#include "common.h"
#include "lodctr.h"
#include "ldprfmsg.h"
typedef struct _DllValidationData {
FILETIME CreationDate;
LONGLONG FileSize;
} DllValidationData, * pDllValidationData;
#define OLD_VERSION 0x010000
#define MAX_GUID_TABLE_SIZE 16
#define tohexdigit(x) ((CHAR) (((x) < 10) ? ((x) + L'0') : ((x) + L'a' - 10)))
// string constants
LPCWSTR szDataFileRoot = L"%systemroot%\\system32\\Perf";
LPCSTR szMofFileName = "MofFile";
LPCWSTR szName = L"_NAME";
LPCWSTR szHelp = L"_HELP";
LPCWSTR sz_DFormat = L" %d";
LPCWSTR szDFormat = L"%d";
LPCSTR szText = "text";
LPCWSTR wszText = L"text";
LPCSTR szObjects = "objects";
LPCWSTR MapFileName = L"Perflib Busy";
LPCWSTR szPerflib = L"Perflib";
LPCWSTR cszLibrary = L"Library";
LPCSTR caszOpen = "Open";
LPCSTR caszCollect = "Collect";
LPCSTR caszClose = "Close";
LPCSTR szTrusted = "Trusted";
int __cdecl
My_vfwprintf(
FILE * str,
const wchar_t * format,
va_list argptr
);
__inline
void __cdecl
OUTPUT_MESSAGE(
BOOL bQuietMode,
const WCHAR * format,
...
)
{
va_list args;
va_start(args, format);
if (! bQuietMode) {
My_vfwprintf(stdout, format, args);
}
va_end(args);
}
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
)
/*++
BuildNameTable
Arguments:
hKeyRegistry
Handle to an open registry (this can be local or remote.) and
is the value returned by RegConnectRegistry or a default key.
lpszLangId
The unicode id of the language to look up. (default is 409)
Return Value:
pointer to an allocated table. (the caller must MemoryFree it when finished!)
the table is an array of pointers to zero terminated strings. NULL is
returned if an error occured.
--*/
{
LPWSTR * lpReturnValue = NULL;
LPWSTR * lpCounterId;
LPWSTR lpCounterNames;
LPWSTR lpHelpText;
LPWSTR lpThisName;
LONG lWin32Status;
DWORD dwLastError;
DWORD dwValueType;
DWORD dwArraySize;
DWORD dwBufferSize;
DWORD dwCounterSize;
DWORD dwHelpSize;
DWORD dwThisCounter;
DWORD dwLastId;
DWORD dwLastHelpId;
DWORD dwLastCounterId;
DWORD dwLastCounterIdUsed;
DWORD dwLastHelpIdUsed;
HKEY hKeyValue = NULL;
HKEY hKeyNames = NULL;
LPWSTR CounterNameBuffer = NULL;
LPWSTR HelpNameBuffer = NULL;
HRESULT hr;
// check for null arguments and insert defaults if necessary
if (lpszLangId == NULL) {
lpszLangId = (LPWSTR) DefaultLangId;
}
// open registry to get number of items for computing array size
__try {
lWin32Status = RegOpenKeyExW(hKeyRegistry, NamesKey, RESERVED, KEY_READ, & hKeyValue);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lWin32Status = GetExceptionCode();
}
if (lWin32Status != ERROR_SUCCESS) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_UNABLE_OPEN_KEY, // event,
2, lWin32Status, __LINE__, 0, 0,
1, (LPWSTR) NamesKey, NULL, NULL);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LODCTR_BUILDNAMETABLE,
ARG_DEF(ARG_TYPE_WSTR, 1),
lWin32Status,
TRACE_WSTR(NamesKey),
NULL));
goto BNT_BAILOUT;
}
// get number of items
dwBufferSize = sizeof(dwLastHelpId);
__try {
lWin32Status = RegQueryValueExW(hKeyValue,
LastHelp,
RESERVED,
& dwValueType,
(LPBYTE) & dwLastHelpId,
& dwBufferSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lWin32Status = GetExceptionCode();
}
if ((lWin32Status != ERROR_SUCCESS) || (dwValueType != REG_DWORD)) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_UNABLE_READ_VALUE, // event,
2, lWin32Status, __LINE__, 0, 0,
1, (LPWSTR) LastHelp, NULL, NULL);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LODCTR_BUILDNAMETABLE,
ARG_DEF(ARG_TYPE_WSTR, 1),
lWin32Status,
TRACE_WSTR(LastHelp),
NULL));
goto BNT_BAILOUT;
}
// get number of items
dwBufferSize = sizeof(dwLastId);
__try {
lWin32Status = RegQueryValueExW(hKeyValue,
LastCounter,
RESERVED,
& dwValueType,
(LPBYTE) & dwLastCounterId,
& dwBufferSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lWin32Status = GetExceptionCode();
}
if ((lWin32Status != ERROR_SUCCESS) || (dwValueType != REG_DWORD)) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_UNABLE_READ_VALUE, // event,
2, lWin32Status, __LINE__, 0, 0,
1, (LPWSTR) LastCounter, NULL, NULL);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LODCTR_BUILDNAMETABLE,
ARG_DEF(ARG_TYPE_WSTR, 1),
lWin32Status,
TRACE_WSTR(LastCounter),
NULL));
goto BNT_BAILOUT;
}
dwLastId = (dwLastCounterId < dwLastHelpId) ? (dwLastHelpId) : (dwLastCounterId);
// compute size of pointer array
dwArraySize = (dwLastId + 1) * sizeof(LPWSTR);
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LODCTR_BUILDNAMETABLE,
0,
lWin32Status,
TRACE_DWORD(dwLastCounterId),
TRACE_DWORD(dwLastHelpId),
NULL));
hKeyNames = HKEY_PERFORMANCE_DATA;
dwBufferSize = lstrlenW(CounterNameStr) + lstrlenW(HelpNameStr) + lstrlenW(lpszLangId) + 1;
if (dwBufferSize < MAX_PATH) dwBufferSize = MAX_PATH;
CounterNameBuffer = MemoryAllocate(2 * dwBufferSize * sizeof(WCHAR));
if (CounterNameBuffer == NULL) {
lWin32Status = ERROR_OUTOFMEMORY;
SetLastError(lWin32Status);
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_MEMORY_ALLOCATION_FAILURE, // event,
1, __LINE__, 0, 0, 0,
0, NULL, NULL, NULL);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LODCTR_BUILDNAMETABLE,
0,
ERROR_OUTOFMEMORY,
NULL));
goto BNT_BAILOUT;
}
HelpNameBuffer = CounterNameBuffer + dwBufferSize;
hr = StringCchPrintfW(CounterNameBuffer, dwBufferSize, L"%ws%ws", CounterNameStr, lpszLangId);
hr = StringCchPrintfW(HelpNameBuffer, dwBufferSize, L"%ws%ws", HelpNameStr, lpszLangId);
// get size of counter names and add that to the arrays
dwBufferSize = 0;
__try {
lWin32Status = RegQueryValueExW(hKeyNames,
CounterNameBuffer,
RESERVED,
& dwValueType,
NULL,
& dwBufferSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lWin32Status = GetExceptionCode();
}
if (lWin32Status != ERROR_SUCCESS) {
ReportLoadPerfEvent(
EVENTLOG_WARNING_TYPE, // error type
(DWORD) LDPRFMSG_UNABLE_READ_COUNTER_STRINGS, // event,
2, lWin32Status, __LINE__, 0, 0,
1, (LPWSTR) lpszLangId, NULL, NULL);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LODCTR_BUILDNAMETABLE,
ARG_DEF(ARG_TYPE_WSTR, 1),
lWin32Status,
TRACE_WSTR(Counters),
NULL));
goto BNT_BAILOUT;
}
dwCounterSize = dwBufferSize;
// get size of counter names and add that to the arrays
dwBufferSize = 0;
__try {
lWin32Status = RegQueryValueExW(hKeyNames,
HelpNameBuffer,
RESERVED,
& dwValueType,
NULL,
& dwBufferSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lWin32Status = GetExceptionCode();
}
if (lWin32Status != ERROR_SUCCESS) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_UNABLE_READ_HELP_STRINGS, // event,
2, lWin32Status, __LINE__, 0, 0,
1, (LPWSTR) lpszLangId, NULL, NULL);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LODCTR_BUILDNAMETABLE,
ARG_DEF(ARG_TYPE_WSTR, 1),
lWin32Status,
TRACE_WSTR(Help),
NULL));
goto BNT_BAILOUT;
}
dwHelpSize = dwBufferSize;
lpReturnValue = MemoryAllocate(dwArraySize + dwCounterSize + dwHelpSize);
if (lpReturnValue == NULL) {
lWin32Status = ERROR_OUTOFMEMORY;
SetLastError(lWin32Status);
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_MEMORY_ALLOCATION_FAILURE, // event,
1, __LINE__, 0, 0, 0,
0, NULL, NULL, NULL);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LODCTR_BUILDNAMETABLE,
0,
ERROR_OUTOFMEMORY,
NULL));
goto BNT_BAILOUT;
}
// initialize pointers into buffer
lpCounterId = lpReturnValue;
lpCounterNames = (LPWSTR) ((LPBYTE) lpCounterId + dwArraySize);
lpHelpText = (LPWSTR) ((LPBYTE) lpCounterNames + dwCounterSize);
// read counters into memory
dwBufferSize = dwCounterSize;
__try {
lWin32Status = RegQueryValueExW(hKeyNames,
CounterNameBuffer,
RESERVED,
& dwValueType,
(LPVOID) lpCounterNames,
& dwBufferSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lWin32Status = GetExceptionCode();
}
if (lWin32Status != ERROR_SUCCESS) {
ReportLoadPerfEvent(
EVENTLOG_WARNING_TYPE, // error type
(DWORD) LDPRFMSG_UNABLE_READ_COUNTER_STRINGS, // event,
2, lWin32Status, __LINE__, 0, 0,
1, (LPWSTR) lpszLangId, NULL, NULL);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LODCTR_BUILDNAMETABLE,
ARG_DEF(ARG_TYPE_WSTR, 1),
lWin32Status,
TRACE_WSTR(Counters),
NULL));
goto BNT_BAILOUT;
}
dwBufferSize = dwHelpSize;
__try {
lWin32Status = RegQueryValueExW(hKeyNames,
HelpNameBuffer,
RESERVED,
& dwValueType,
(LPVOID) lpHelpText,
& dwBufferSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lWin32Status = GetExceptionCode();
}
if (lWin32Status != ERROR_SUCCESS) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_UNABLE_READ_HELP_STRINGS, // event,
2, lWin32Status, __LINE__, 0, 0,
1, (LPWSTR) lpszLangId, NULL, NULL);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LODCTR_BUILDNAMETABLE,
ARG_DEF(ARG_TYPE_WSTR, 1),
lWin32Status,
TRACE_WSTR(Help),
NULL));
goto BNT_BAILOUT;
}
dwLastCounterIdUsed = 0;
dwLastHelpIdUsed = 0;
// load counter array items
for (lpThisName = lpCounterNames; * lpThisName != L'\0'; lpThisName += (lstrlenW(lpThisName) + 1) ) {
// first string should be an integer (in decimal unicode digits)
dwThisCounter = wcstoul(lpThisName, NULL, 10);
if (dwThisCounter == 0 || dwThisCounter > dwLastId) {
lWin32Status = ERROR_INVALID_DATA;
SetLastError(lWin32Status);
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_REGISTRY_COUNTER_STRINGS_CORRUPT, // event,
4, dwThisCounter, dwLastCounterId, dwLastId, __LINE__,
1, lpThisName, NULL, NULL);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LODCTR_BUILDNAMETABLE,
ARG_DEF(ARG_TYPE_WSTR, 1),
lWin32Status,
TRACE_WSTR(lpThisName),
TRACE_DWORD(dwThisCounter),
TRACE_DWORD(dwLastId),
NULL));
goto BNT_BAILOUT; // bad entry
}
// point to corresponding counter name
lpThisName += (lstrlenW(lpThisName) + 1);
// and load array element;
lpCounterId[dwThisCounter] = lpThisName;
if (dwThisCounter > dwLastCounterIdUsed) dwLastCounterIdUsed = dwThisCounter;
}
for (lpThisName = lpHelpText; * lpThisName != L'\0'; lpThisName += (lstrlenW(lpThisName) + 1) ) {
// first string should be an integer (in decimal unicode digits)
dwThisCounter = wcstoul(lpThisName, NULL, 10);
if (dwThisCounter == 0 || dwThisCounter > dwLastId) {
lWin32Status = ERROR_INVALID_DATA;
SetLastError(lWin32Status);
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_REGISTRY_HELP_STRINGS_CORRUPT, // event,
4, dwThisCounter, dwLastHelpId, dwLastId, __LINE__,
1, lpThisName, NULL, NULL);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LODCTR_BUILDNAMETABLE,
ARG_DEF(ARG_TYPE_WSTR, 1),
lWin32Status,
TRACE_WSTR(lpThisName),
TRACE_DWORD(dwThisCounter),
TRACE_DWORD(dwLastId),
NULL));
goto BNT_BAILOUT; // bad entry
}
// point to corresponding counter name
lpThisName += (lstrlenW(lpThisName) + 1);
// and load array element;
lpCounterId[dwThisCounter] = lpThisName;
if (dwThisCounter > dwLastHelpIdUsed) dwLastHelpIdUsed= dwThisCounter;
}
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LODCTR_BUILDNAMETABLE,
ARG_DEF(ARG_TYPE_WSTR, 1),
lWin32Status,
TRACE_WSTR(lpszLangId),
TRACE_DWORD(dwLastCounterIdUsed),
TRACE_DWORD(dwLastHelpIdUsed),
TRACE_DWORD(dwLastId),
NULL));
// check the registry for consistency
// the last help string index should be the last ID used
if (dwLastCounterIdUsed > dwLastId) {
lWin32Status = ERROR_INVALID_DATA;
SetLastError(lWin32Status);
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_REGISTRY_INDEX_CORRUPT, // event,
3, dwLastId, dwLastCounterIdUsed, __LINE__, 0,
0, NULL, NULL, NULL);
goto BNT_BAILOUT; // bad registry
}
if (dwLastHelpIdUsed > dwLastId) {
lWin32Status = ERROR_INVALID_DATA;
SetLastError(lWin32Status);
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_REGISTRY_INDEX_CORRUPT, // event,
3, dwLastId, dwLastHelpIdUsed, __LINE__, 0,
0, NULL, NULL, NULL);
goto BNT_BAILOUT; // bad registry
}
if (pdwLastItem) * pdwLastItem = dwLastId;
BNT_BAILOUT:
if (hKeyValue) RegCloseKey (hKeyValue);
if (hKeyNames && hKeyNames != HKEY_PERFORMANCE_DATA) RegCloseKey (hKeyNames);
MemoryFree(CounterNameBuffer);
if (lWin32Status != ERROR_SUCCESS) {
dwLastError = GetLastError();
MemoryFree(lpReturnValue);
lpReturnValue = NULL;
}
return lpReturnValue;
}
BOOL
MakeBackupCopyOfLanguageFiles(
LPCWSTR szLangId
)
{
LPWSTR szOldFileName = NULL;
LPWSTR szTmpFileName = NULL;
LPWSTR szNewFileName = NULL;
BOOL bStatus = FALSE;
DWORD dwStatus;
HANDLE hOutFile;
HRESULT hr;
UNREFERENCED_PARAMETER(szLangId);
szOldFileName = MemoryAllocate((MAX_PATH + 1) * sizeof(WCHAR));
szTmpFileName = MemoryAllocate((MAX_PATH + 1) * sizeof(WCHAR));
szNewFileName = MemoryAllocate((MAX_PATH + 1) * sizeof(WCHAR));
if (szOldFileName == NULL || szTmpFileName == NULL || szNewFileName == NULL) {
dwStatus = ERROR_OUTOFMEMORY;
goto Cleanup;
}
ExpandEnvironmentStringsW(szDataFileRoot, szOldFileName, MAX_PATH);
hr = StringCchPrintfW(szNewFileName, MAX_PATH + 1, L"%wsStringBackup.INI", szOldFileName);
hr = StringCchPrintfW(szTmpFileName, MAX_PATH + 1, L"%wsStringBackup.TMP", szOldFileName);
// see if the file already exists
hOutFile = CreateFileW(szTmpFileName,
GENERIC_READ,
0, // no sharing
NULL, // default security
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hOutFile != INVALID_HANDLE_VALUE) {
CloseHandle(hOutFile);
bStatus = DeleteFileW(szTmpFileName);
}
// create backup of file
//
dwStatus = BackupPerfRegistryToFileW(szTmpFileName, NULL);
if (dwStatus == ERROR_SUCCESS) {
bStatus = CopyFileW(szTmpFileName, szNewFileName, FALSE);
if (bStatus) {
DeleteFileW(szTmpFileName);
}
}
else {
bStatus = FALSE;
}
Cleanup:
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_MAKEBACKUPCOPYOFLANGUAGEFILES,
ARG_DEF(ARG_TYPE_WSTR, 1),
GetLastError(),
TRACE_WSTR(szNewFileName),
NULL));
MemoryFree(szOldFileName);
MemoryFree(szTmpFileName);
MemoryFree(szNewFileName);
if (! bStatus) SetLastError(dwStatus);
return bStatus;
}
BOOL
GetFileFromCommandLine(
LPWSTR lpCommandLine,
LPWSTR * lpFileName,
DWORD dwFileName,
DWORD_PTR * pdwFlags
)
/*++
GetFileFromCommandLine
parses the command line to retrieve the ini filename that should be
the first and only argument.
Arguments
lpCommandLine pointer to command line (returned by GetCommandLine)
lpFileName pointer to buffer that will recieve address of the
validated filename entered on the command line
pdwFlags pointer to dword containing flag bits
Return Value
TRUE if a valid filename was returned
FALSE if the filename is not valid or missing
error is returned in GetLastError
--*/
{
INT iNumArgs;
LPWSTR lpExeName = NULL;
LPWSTR lpCmdLineName = NULL;
LPWSTR lpIniFileName = NULL;
LPWSTR lpMofFlag = NULL;
HANDLE hFileHandle;
DWORD lStatus = ERROR_SUCCESS;
BOOL bReturn = FALSE;
DWORD NameBuffer;
DWORD dwCpuArg, dwIniArg;
HRESULT hr;
// check for valid arguments
if (lpCommandLine == NULL || lpFileName == NULL || pdwFlags == NULL) {
lStatus = ERROR_INVALID_PARAMETER;
goto Cleanup;
}
// allocate memory for parsing operation
NameBuffer = lstrlenW(lpCommandLine);
if (NameBuffer < MAX_PATH) NameBuffer = MAX_PATH;
lpExeName = MemoryAllocate(4 * NameBuffer * sizeof(WCHAR));
if (lpExeName == NULL) {
lStatus = (ERROR_OUTOFMEMORY);
goto Cleanup;
}
lpCmdLineName = (LPWSTR) (lpExeName + NameBuffer);
lpIniFileName = (LPWSTR) (lpCmdLineName + NameBuffer);
lpMofFlag = (LPWSTR) (lpIniFileName + NameBuffer);
// check for mof Flag
hr = StringCchCopyW(lpMofFlag, NameBuffer, GetItemFromString(lpCommandLine, 2, cSpace));
* pdwFlags |= LOADPERF_FLAGS_LOAD_REGISTRY_ONLY; // default unless a switch is found
if (lpMofFlag[0] == cHyphen || lpMofFlag[0] == cSlash) {
if (lpMofFlag[1] == cQuestion) {
// ask for usage
goto Cleanup;
}
else if (lpMofFlag[1] == cM || lpMofFlag[1] == cm) {
// ignore MOF flag. LODCTR only used to update perfromance registry, no MOF.
//
}
dwCpuArg = 3;
dwIniArg = 4;
}
else {
dwCpuArg = 2;
dwIniArg = 3;
}
// Get INI File name
hr = StringCchCopyW(lpCmdLineName, NameBuffer, GetItemFromString(lpCommandLine, dwIniArg, cSpace));
if (lstrlenW(lpCmdLineName) == 0) {
// then no computer name was specified so try to get the
// ini file from the 2nd entry
hr = StringCchCopyW(lpCmdLineName, NameBuffer, GetItemFromString(lpCommandLine, dwCpuArg, cSpace));
if (lstrlenW(lpCmdLineName) == 0) {
// no ini file found
iNumArgs = 1;
}
else {
// fill in a blank computer name
iNumArgs = 2;
}
}
else {
// the computer name must be present so fetch it
hr = StringCchCopyW(lpMofFlag, NameBuffer, GetItemFromString(lpCommandLine, dwCpuArg, cSpace));
iNumArgs = 3;
}
if (iNumArgs != 2 && iNumArgs != 3) {
// wrong number of arguments
lStatus = ERROR_INVALID_PARAMETER;
goto Cleanup;
}
if (SearchPathW(NULL, lpCmdLineName, NULL, FILE_NAME_BUFFER_SIZE, lpIniFileName, NULL) > 0) {
hFileHandle = CreateFileW(lpIniFileName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFileHandle != NULL && hFileHandle != INVALID_HANDLE_VALUE) {
CloseHandle(hFileHandle);
// file exists, so return name and success
hr = StringCchCopyW(* lpFileName, dwFileName, lpIniFileName);
bReturn = TRUE;
}
else {
// filename was on command line, but not valid so return
// false, but send name back for error message
hr = StringCchCopyW(* lpFileName, dwFileName, lpIniFileName);
lStatus = GetLastError();
}
}
else {
hr = StringCchCopyW(* lpFileName, dwFileName, lpCmdLineName);
lStatus = ERROR_OPEN_FAILED;
}
Cleanup:
MemoryFree(lpExeName);
if (! bReturn) SetLastError(lStatus);
return bReturn;
}
BOOL
LodctrSetSericeAsTrusted(
LPCWSTR lpIniFile,
LPCWSTR szMachineName,
LPCWSTR szServiceName
)
{
DWORD dwRetSize;
DWORD dwStatus;
BOOL bReturn = FALSE;
LPSTR aszIniFile = LoadPerfWideCharToMultiByte(CP_ACP, (LPWSTR) lpIniFile);
LPSTR szParam = NULL;
if (aszIniFile != NULL) {
DWORD dwFileSize = LoadPerfGetFileSize((LPWSTR) lpIniFile, NULL, TRUE);
if (dwFileSize < SMALL_BUFFER_SIZE) dwFileSize = SMALL_BUFFER_SIZE;
szParam = MemoryAllocate(dwFileSize * sizeof(CHAR));
if (szParam != NULL) {
dwRetSize = GetPrivateProfileStringA(szInfo, szTrusted, szNotFound, szParam, dwFileSize, aszIniFile);
if (lstrcmpiA(szParam, szNotFound) != 0) {
// Trusted string found so set
dwStatus = SetServiceAsTrustedW(NULL, szServiceName);
if (dwStatus != ERROR_SUCCESS) {
SetLastError(dwStatus);
}
else {
bReturn = TRUE;
}
}
else {
// Service is not trusted to have a good Perf DLL
SetLastError(ERROR_SUCCESS);
}
MemoryFree(szParam);
}
else {
SetLastError(ERROR_OUTOFMEMORY);
}
MemoryFree(aszIniFile);
}
else {
SetLastError(ERROR_OUTOFMEMORY);
}
return bReturn;
}
BOOL
BuildLanguageTables(
DWORD dwMode,
LPWSTR lpIniFile,
LPWSTR lpDriverName,
PLANGUAGE_LIST_ELEMENT * pFirstElem
)
/*++
BuildLanguageTables
Creates a list of structures that will hold the text for
each supported language
Arguments
lpIniFile
Filename with data
pFirstElem
pointer to first list entry
ReturnValue
TRUE if all OK
FALSE if not
--*/
{
LPSTR lpEnumeratedLangs = NULL;
LPSTR lpThisLang = NULL;
LPWSTR lpSrchPath = NULL;
LPSTR lpIniPath = NULL;
LPWSTR lpInfPath = LoadPerfGetInfPath();
HANDLE hFile = NULL;
WIN32_FIND_DATAW FindFile;
PLANGUAGE_LIST_ELEMENT pThisElem;
DWORD dwSize;
BOOL bReturn = FALSE;
DWORD dwStatus = ERROR_SUCCESS;
BOOL bFind = TRUE;
DWORD dwPathSize = 0;
DWORD dwFileSize = 0;
LPSTR aszIniFile = NULL;
HRESULT hr;
BOOL bLocalizedBuild = (GetSystemDefaultUILanguage() != 0x0409) ? TRUE : FALSE;
if (lpIniFile == NULL || pFirstElem == NULL || lpInfPath == NULL) {
dwStatus = ERROR_INVALID_PARAMETER;
goto Cleanup;
}
dwPathSize = lstrlenW(lpInfPath) + lstrlenW(lpIniFile) + 6; // "0404\"
if (dwPathSize < MAX_PATH) dwPathSize = MAX_PATH;
lpSrchPath = MemoryAllocate(sizeof(WCHAR) * dwPathSize + sizeof(CHAR) * dwPathSize);
if (lpSrchPath == NULL) {
dwStatus = ERROR_OUTOFMEMORY;
goto Cleanup;
}
lpIniPath = (LPSTR) (((LPWSTR) lpSrchPath) + dwPathSize);
if (! (dwMode & LODCTR_UPNF_NOBACKUP)) {
hr = StringCchPrintfW(lpSrchPath, dwPathSize, L"%ws0*", lpInfPath);
hFile = FindFirstFileExW(lpSrchPath,
FindExInfoStandard,
& FindFile,
FindExSearchLimitToDirectories,
NULL,
0);
if (hFile == NULL || hFile == INVALID_HANDLE_VALUE) {
dwStatus = ERROR_RESOURCE_LANG_NOT_FOUND;
goto Cleanup;
}
}
bFind = TRUE;
while (bFind) {
ZeroMemory(lpIniPath, dwPathSize * sizeof(CHAR));
if (dwMode & LODCTR_UPNF_NOBACKUP) {
hr = StringCchPrintfA(lpIniPath, dwPathSize, "%ws", lpIniFile);
}
else {
hr = StringCchPrintfA(lpIniPath, dwPathSize, "%ws%ws%ws%ws%ws%ws",
lpInfPath, FindFile.cFileName, Slash, lpDriverName, Slash, lpIniFile);
}
if (lpEnumeratedLangs == NULL) {
dwFileSize = LoadPerfGetFileSize((LPWSTR) lpIniPath, NULL, FALSE);
if (dwFileSize < SMALL_BUFFER_SIZE) dwFileSize = SMALL_BUFFER_SIZE;
lpEnumeratedLangs = MemoryAllocate(dwFileSize * sizeof(CHAR));
if (lpEnumeratedLangs == NULL) {
dwStatus = ERROR_OUTOFMEMORY;
goto Cleanup;
}
}
else {
ZeroMemory(lpEnumeratedLangs, dwFileSize * sizeof(CHAR));
}
dwSize = GetPrivateProfileStringA(szLanguages,
NULL, // return all values in multi-sz string
aszDefaultLangId, // english as the default
lpEnumeratedLangs,
dwFileSize,
lpIniPath);
if (dwSize == 0) {
dwStatus = ERROR_RESOURCE_LANG_NOT_FOUND;
goto Cleanup;
}
for (lpThisLang = lpEnumeratedLangs;
lpThisLang != NULL && * lpThisLang != '\0';
lpThisLang += (lstrlenA(lpThisLang) + 1)) {
LPWSTR wszAllocLang = LoadPerfMultiByteToWideChar(CP_ACP, lpThisLang);
LPWSTR wszThisLang = NULL;
if (wszAllocLang == NULL) continue;
if ((! bLocalizedBuild) && (LoadPerfGetLCIDFromString(wszAllocLang) == 0x0004)) {
// Asshume that this is MUI build, so we should not use generic "004" LangId.
// Instead, we should use "0804" or "0404" to separate CHT and CHS cases.
//
wszThisLang = FindFile.cFileName;
}
else {
wszThisLang = wszAllocLang;
}
for (pThisElem = * pFirstElem; pThisElem != NULL; pThisElem = pThisElem->pNextLang) {
if (lstrcmpiW(pThisElem->LangId, wszThisLang) == 0) {
break;
}
}
if (pThisElem != NULL) {
// already support this language in INI file
//
continue;
}
pThisElem = MemoryAllocate(sizeof(LANGUAGE_LIST_ELEMENT) + (lstrlenW(wszThisLang) + 1) * sizeof(WCHAR));
if (pThisElem == NULL) {
dwStatus = ERROR_OUTOFMEMORY;
continue;
}
// The following code is to build pFirstElem list. pFirstElem list will be returned back
// to LoadPerfInstallPerfDll() function (LangList), then uses in UpdateRegistry().
// Allocated memory will be freed at the end of LoadPerfInstallPerfDll().
//
pThisElem->pNextLang = * pFirstElem;
* pFirstElem = pThisElem;
pThisElem->LangId = (LPWSTR) (((LPBYTE) pThisElem) + sizeof(LANGUAGE_LIST_ELEMENT));
hr = StringCchCopyW(pThisElem->LangId, lstrlenW(wszThisLang) + 1, wszThisLang);
pThisElem->dwLangId = LoadPerfGetLCIDFromString(pThisElem->LangId);
pThisElem->pFirstName = NULL;
pThisElem->pThisName = NULL;
pThisElem->dwNumElements = 0;
pThisElem->NameBuffer = NULL;
pThisElem->HelpBuffer = NULL;
pThisElem->dwNameBuffSize = 0;
pThisElem->dwHelpBuffSize = 0;
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_BUILDLANGUAGETABLES,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
ERROR_SUCCESS,
TRACE_WSTR(lpIniFile),
TRACE_WSTR(pThisElem->LangId),
NULL));
MemoryFree(wszAllocLang);
}
if (dwMode & LODCTR_UPNF_NOBACKUP) {
bFind = FALSE;
}
else {
bFind = FindNextFileW(hFile, & FindFile);
}
}
if (* pFirstElem == NULL) {
// then no languages were found
dwStatus = ERROR_RESOURCE_LANG_NOT_FOUND;
}
else {
bReturn = TRUE;
}
Cleanup:
if (hFile != NULL && hFile != INVALID_HANDLE_VALUE) FindClose(hFile);
MemoryFree(lpSrchPath);
MemoryFree(lpEnumeratedLangs);
if (! bReturn) {
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_BUILDLANGUAGETABLES,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
dwStatus,
TRACE_WSTR(lpIniFile),
TRACE_WSTR(lpDriverName),
NULL));
SetLastError(dwStatus);
}
return bReturn;
}
BOOL
LoadIncludeFile(
BOOL bQuietMode,
DWORD dwMode,
LPWSTR lpIniFile,
LPWSTR lpDriverName,
PSYMBOL_TABLE_ENTRY * pTable
)
/*++
LoadIncludeFile
Reads the include file that contains symbolic name definitions and
loads a table with the values defined
Arguments
lpIniFile
Ini file with include file name
pTable
address of pointer to table structure created
Return Value
TRUE if table read or if no table defined
FALSE if error encountere reading table
--*/
{
INT iNumArgs;
DWORD dwSize;
DWORD dwFileSize;
BOOL bReUse;
PSYMBOL_TABLE_ENTRY pThisSymbol = NULL;
LPWSTR szInfPath = LoadPerfGetInfPath();
LPSTR lpIncludeFileName = NULL;
LPSTR lpIncludeFile = NULL;
LPSTR lpIniPath = NULL;
LPSTR lpLineBuffer = NULL;
LPSTR lpAnsiSymbol = NULL;
LPSTR aszIniFile = NULL;
FILE * fIncludeFile = NULL;
DWORD dwLen;
BOOL bReturn = FALSE;
DWORD dwStatus = ERROR_SUCCESS;
HRESULT hr;
if (pTable == NULL || szInfPath == NULL || lpIniFile == NULL) {
dwStatus = ERROR_INVALID_PARAMETER;
goto Cleanup;
}
aszIniFile = LoadPerfWideCharToMultiByte(CP_ACP, lpIniFile);
if (aszIniFile == NULL) {
dwStatus = ERROR_OUTOFMEMORY;
goto Cleanup;
}
dwFileSize = LoadPerfGetFileSize(lpIniFile, NULL, TRUE);
if (dwFileSize < SMALL_BUFFER_SIZE) dwFileSize = SMALL_BUFFER_SIZE;
lpIncludeFileName = MemoryAllocate(3 * dwFileSize * sizeof (CHAR));
if (lpIncludeFileName == NULL) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_MEMORY_ALLOCATION_FAILURE, // event,
1, __LINE__, 0, 0, 0,
0, NULL, NULL, NULL);
dwStatus = ERROR_OUTOFMEMORY;
goto Cleanup;
}
lpLineBuffer = (LPSTR) (lpIncludeFileName + dwFileSize);
lpAnsiSymbol = (LPSTR) (lpLineBuffer + dwFileSize);
// get name of include file (if present)
dwSize = GetPrivateProfileStringA(szInfo,
szSymbolFile,
szNotFound,
lpIncludeFileName,
dwFileSize,
aszIniFile);
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LOADINCLUDEFILE,
ARG_DEF(ARG_TYPE_STR, 1) | ARG_DEF(ARG_TYPE_STR, 2),
ERROR_SUCCESS,
TRACE_STR(aszIniFile),
TRACE_STR(lpIncludeFileName),
NULL));
if (lstrcmpiA(lpIncludeFileName, szNotFound) == 0) {
// no symbol file defined
* pTable = NULL;
dwStatus = ERROR_INVALID_DATA;
bReturn = TRUE;
goto Cleanup;
}
dwSize = lstrlenW(szInfPath) + lstrlenW(lpDriverName) + 10;
if (dwSize < (DWORD) (lstrlenW(lpIniFile) + 1)) dwSize = lstrlenW(lpIniFile) + 1;
if (dwSize < MAX_PATH) dwSize = MAX_PATH;
lpIniPath = MemoryAllocate(2 * dwSize * sizeof(CHAR));
if (lpIniPath == NULL) {
dwStatus = ERROR_OUTOFMEMORY;
goto Cleanup;
}
lpIncludeFile = (LPSTR) (lpIniPath + dwSize);
// if here, then a symbol file was defined and is now stored in
// lpIncludeFileName
// get path for the ini file and search that first
if (dwMode & LODCTR_UPNF_NOBACKUP) {
DWORD dwPathSize = lstrlenW(lpIniFile) + 1;
LPSTR szDrive = NULL;
LPSTR szDir = NULL;
if (dwPathSize < MAX_PATH) dwPathSize = MAX_PATH;
szDrive = MemoryAllocate(2 * dwPathSize * sizeof(CHAR));
if (szDrive == NULL) {
dwStatus = ERROR_OUTOFMEMORY;
goto Cleanup;
}
szDir = (LPSTR) (szDrive + dwPathSize);
_splitpath(aszIniFile, szDrive, szDir, NULL, NULL);
hr = StringCchPrintfA(lpIniPath, dwSize, "%s%s", szDrive, szDir);
MemoryFree(szDrive);
}
else {
hr = StringCchPrintfA(lpIniPath, dwSize, "%wsinc%ws%ws", szInfPath, Slash, lpDriverName);
}
dwLen = SearchPathA(lpIniPath, lpIncludeFileName, NULL, dwSize, lpIncludeFile, NULL);
if (dwLen == 0) {
// include file not found with the ini file so search the std. path
dwLen = SearchPathA(NULL, lpIncludeFileName, NULL, dwSize, lpIncludeFile, NULL);
}
if (dwLen > 0) {
// file name expanded and found so open
fIncludeFile = fopen(lpIncludeFile, "rt");
if (fIncludeFile == NULL) {
OUTPUT_MESSAGE(bQuietMode, GetFormatResource(LC_ERR_OPEN_INCLUDE), lpIncludeFileName);
* pTable = NULL;
dwStatus = ERROR_OPEN_FAILED;
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LOADINCLUDEFILE,
ARG_DEF(ARG_TYPE_STR, 1) | ARG_DEF(ARG_TYPE_STR, 2),
ERROR_OPEN_FAILED,
TRACE_STR(aszIniFile),
TRACE_STR(lpIncludeFile),
NULL));
goto Cleanup;
}
}
else {
// unable to find the include filename
// error is already in GetLastError
OUTPUT_MESSAGE(bQuietMode, GetFormatResource(LC_ERR_OPEN_INCLUDE), lpIncludeFileName);
* pTable = NULL;
dwStatus = ERROR_BAD_PATHNAME;
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LOADINCLUDEFILE,
ARG_DEF(ARG_TYPE_STR, 1) | ARG_DEF(ARG_TYPE_STR, 2),
ERROR_BAD_PATHNAME,
TRACE_STR(aszIniFile),
TRACE_STR(lpIncludeFileName),
NULL));
goto Cleanup;
}
//
// read ANSI Characters from include file
//
bReUse = FALSE;
while (fgets(lpLineBuffer, dwFileSize, fIncludeFile) != NULL) {
if (strlen(lpLineBuffer) > 8) {
if (! bReUse) {
// Build pTable list here. pTable list will be returned back to LoadPerfInstallPerfDll(),
// used in UpdateRegistry(), then freed at the end of LoadPerfInstallPerfDll().
//
if (* pTable) {
// then add to list
pThisSymbol->pNext = MemoryAllocate(sizeof(SYMBOL_TABLE_ENTRY));
pThisSymbol = pThisSymbol->pNext;
}
else { // allocate first element
* pTable = MemoryAllocate(sizeof(SYMBOL_TABLE_ENTRY));
pThisSymbol = * pTable;
}
if (pThisSymbol == NULL) {
dwStatus = ERROR_OUTOFMEMORY;
goto Cleanup;
}
}
// all the memory is allocated so load the fields
pThisSymbol->pNext = NULL;
iNumArgs = sscanf(lpLineBuffer, "#define %s %d", lpAnsiSymbol, & pThisSymbol->Value);
if (iNumArgs != 2) {
pThisSymbol->SymbolName = LoadPerfMultiByteToWideChar(CP_ACP, "");
pThisSymbol->Value = (DWORD) -1L;
bReUse = TRUE;
}
else {
pThisSymbol->SymbolName = LoadPerfMultiByteToWideChar(CP_ACP, lpAnsiSymbol);
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LOADINCLUDEFILE,
ARG_DEF(ARG_TYPE_STR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
ERROR_SUCCESS,
TRACE_STR(lpIncludeFileName),
TRACE_WSTR(pThisSymbol->SymbolName),
TRACE_DWORD(pThisSymbol->Value),
NULL));
bReUse = FALSE;
}
}
}
bReturn = TRUE;
Cleanup:
MemoryFree(aszIniFile);
MemoryFree(lpIncludeFileName);
MemoryFree(lpIniPath);
if (fIncludeFile != NULL) fclose(fIncludeFile);
if (! bReturn) {
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LOADINCLUDEFILE,
ARG_DEF(ARG_TYPE_WSTR, 1),
GetLastError(),
TRACE_WSTR(lpIniFile),
NULL));
SetLastError(dwStatus);
}
return bReturn;
}
BOOL
ParseTextId(
LPWSTR lpTextId,
PSYMBOL_TABLE_ENTRY pFirstSymbol,
PDWORD pdwOffset,
LPWSTR * lpLangId,
PDWORD pdwType
)
/*++
ParseTextId
decodes Text Id key from .INI file
syntax for this process is:
{<DecimalNumber>} {"NAME"}
{<SymbolInTable>}_<LangIdString>_{"HELP"}
e.g. 0_009_NAME
OBJECT_1_009_HELP
Arguments
lpTextId
string to decode
pFirstSymbol
pointer to first entry in symbol table (NULL if no table)
pdwOffset
address of DWORD to recive offest value
lpLangId
address of pointer to Language Id string
(NOTE: this will point into the string lpTextID which will be
modified by this routine)
pdwType
pointer to dword that will recieve the type of string i.e.
HELP or NAME
Return Value
TRUE text Id decoded successfully
FALSE unable to decode string
NOTE: the string in lpTextID will be modified by this procedure
--*/
{
BOOL bReturn = FALSE;
DWORD Status = ERROR_SUCCESS;
LPWSTR lpThisChar;
PSYMBOL_TABLE_ENTRY pThisSymbol;
// check for valid return arguments
if (pdwOffset == NULL || lpLangId == NULL || pdwType == NULL) {
Status = ERROR_INVALID_PARAMETER;
goto Cleanup;
}
// search string from right to left in order to identify the
// components of the string.
lpThisChar = lpTextId + lstrlenW(lpTextId); // point to end of string
while (lpThisChar > lpTextId && * lpThisChar != cUnderscore) {
lpThisChar --;
}
if (lpThisChar <= lpTextId) {
// underscore not found in string
Status = ERROR_INVALID_DATA;
goto Cleanup;
}
// first underscore found
if (lstrcmpiW(lpThisChar, szName) == 0) {
// name found, so set type
* pdwType = TYPE_NAME;
}
else if (lstrcmpiW(lpThisChar, szHelp) == 0) {
// help text found, so set type
* pdwType = TYPE_HELP;
}
else {
// bad format
Status = ERROR_INVALID_DATA;
goto Cleanup;
}
// set the current underscore to \0 and look for language ID
* lpThisChar-- = L'\0';
while (lpThisChar > lpTextId && * lpThisChar != cUnderscore) {
lpThisChar --;
}
if (lpThisChar <= lpTextId) {
// underscore not found in string
Status = ERROR_INVALID_DATA;
goto Cleanup;
}
// set lang ID string pointer to current char ('_') + 1
* lpLangId = lpThisChar + 1;
// set this underscore to a NULL and try to decode the remaining text
* lpThisChar = L'\0';
// see if the first part of the string is a decimal digit
if (swscanf(lpTextId, sz_DFormat, pdwOffset) != 1) {
// it's not a digit, so try to decode it as a symbol in the
// loaded symbol table
for (pThisSymbol=pFirstSymbol;
pThisSymbol != NULL && * pThisSymbol->SymbolName != L'\0';
pThisSymbol = pThisSymbol->pNext) {
if (lstrcmpiW(lpTextId, pThisSymbol->SymbolName) == 0) {
// a matching symbol was found, so insert it's value
// and return (that's all that needs to be done
* pdwOffset = pThisSymbol->Value;
bReturn = TRUE;
break;
}
}
if (! bReturn) {
// if here, then no matching symbol was found, and it's not
// a number, so return an error
Status = ERROR_BAD_TOKEN_TYPE;
}
}
else {
// symbol was prefixed with a decimal number
bReturn = TRUE;
}
Cleanup:
if (! bReturn) {
SetLastError(Status);
}
return bReturn;
}
PLANGUAGE_LIST_ELEMENT
FindLanguage(
PLANGUAGE_LIST_ELEMENT pFirstLang,
LPCWSTR pLangId
)
/*++
FindLanguage
searchs the list of languages and returns a pointer to the language
list entry that matches the pLangId string argument
Arguments
pFirstLang
pointer to first language list element
pLangId
pointer to text string with language ID to look up
Return Value
Pointer to matching language list entry
or NULL if no match
--*/
{
PLANGUAGE_LIST_ELEMENT pRtnLang = NULL;
PLANGUAGE_LIST_ELEMENT pThisLang;
DWORD dwLang = LoadPerfGetLCIDFromString((LPWSTR) pLangId);
DWORD dwSubLang;
for (pThisLang = pFirstLang; pThisLang; pThisLang = pThisLang->pNextLang) {
if (pThisLang->dwLangId == dwLang) {
// match found so return pointer
pRtnLang = pThisLang;
break;
}
}
if (pRtnLang == NULL) {
dwSubLang = (dwLang == PRIMARYLANGID(GetUserDefaultUILanguage()))
? (GetUserDefaultUILanguage()) : (PRIMARYLANGID(dwLang));
if (dwSubLang != dwLang) {
for (pThisLang = pFirstLang; pThisLang; pThisLang = pThisLang->pNextLang) {
if (pThisLang->dwLangId == dwSubLang) {
// match found so return pointer
pRtnLang = pThisLang;
break;
}
}
}
}
return pRtnLang;
}
BOOL
GetValueW(
PLANGUAGE_LIST_ELEMENT pLang,
LPWSTR lpLocalSectionBuff,
LPWSTR * lpLocalStringBuff
)
{
LPWSTR lpPosition;
LPWSTR szThisLang = LoadPerfGetLanguage(pLang->LangId, FALSE);
BOOL bReturn = FALSE;
DWORD dwSize;
HRESULT hr;
if (lpLocalStringBuff != NULL && szThisLang != NULL) {
* lpLocalStringBuff = NULL;
lpPosition = wcschr(lpLocalSectionBuff, wEquals);
if (lpPosition) {
lpPosition ++;
// make sure the "=" isn't the last char
dwSize = (* lpPosition != L'\0') ? (lstrlenW(lpPosition) + 1) : (2);
* lpLocalStringBuff = MemoryAllocate(dwSize * sizeof(WCHAR));
if (* lpLocalStringBuff != NULL) {
hr = (* lpPosition != L'\0')
? StringCchCopyW(* lpLocalStringBuff, dwSize, lpPosition)
: StringCchCopyW(* lpLocalStringBuff, dwSize, L" ");
bReturn = TRUE;
}
else {
SetLastError(ERROR_OUTOFMEMORY);
}
}
else {
//ErrorFinfing the "="
// bad format
SetLastError(ERROR_INVALID_DATA);
}
}
return bReturn;
}
BOOL
GetValueFromIniKeyW(
PLANGUAGE_LIST_ELEMENT pLang,
LPWSTR lpValueKey,
LPWSTR lpTextSection,
DWORD * pdwLastReadOffset,
DWORD dwTryCount,
LPWSTR * lpLocalStringBuff
)
{
LPWSTR lpLocalSectionBuff;
DWORD dwIndex;
DWORD dwLastReadOffset;
BOOL bRetVal = FALSE;
if (lpTextSection != NULL && lpValueKey != NULL ) {
dwLastReadOffset = * pdwLastReadOffset;
lpLocalSectionBuff = lpTextSection;
lpLocalSectionBuff += dwLastReadOffset;
while(* lpLocalSectionBuff != L'\0') {
dwLastReadOffset += (lstrlenW(lpTextSection + dwLastReadOffset) + 1);
lpLocalSectionBuff = lpTextSection + dwLastReadOffset;
* pdwLastReadOffset = dwLastReadOffset;
}
// search next N entries in buffer for entry
// this should usually work since the file
// is scanned sequentially so it's tried first
for (dwIndex = 0; dwIndex < dwTryCount; dwIndex ++) {
// see if this is the correct entry
// and return it if it is
if (wcsstr(lpLocalSectionBuff, lpValueKey)) {
bRetVal = GetValueW(pLang, lpLocalSectionBuff, lpLocalStringBuff);
//Set the lastReadOffset First
dwLastReadOffset += (lstrlenW(lpTextSection + dwLastReadOffset) + 1);
* pdwLastReadOffset = dwLastReadOffset;
break; // out of the for loop
}
else {
// this isn't the correct one so go to the next
// entry in the file
dwLastReadOffset += (lstrlenW(lpTextSection + dwLastReadOffset) + 1);
lpLocalSectionBuff = lpTextSection + dwLastReadOffset;
* pdwLastReadOffset = dwLastReadOffset;
}
}
if (! bRetVal) {
//Cannont Find the key using lastReadOffset
//try again from the beggining of the Array
dwLastReadOffset = 0;
lpLocalSectionBuff = lpTextSection;
* pdwLastReadOffset = dwLastReadOffset;
while (* lpLocalSectionBuff != L'\0') {
if (wcsstr(lpLocalSectionBuff, lpValueKey)) {
bRetVal = GetValueW(pLang, lpLocalSectionBuff, lpLocalStringBuff);
break;
}
else {
// go to the next entry
dwLastReadOffset += (lstrlenW(lpTextSection + dwLastReadOffset) + 1);
lpLocalSectionBuff = lpTextSection + dwLastReadOffset;
* pdwLastReadOffset = dwLastReadOffset;
}
}
}
}
return bRetVal;
}
BOOL
GetValueA(
PLANGUAGE_LIST_ELEMENT pLang,
LPSTR lpLocalSectionBuff,
LPWSTR * lpLocalStringBuff
)
{
LPSTR lpPosition;
LPWSTR szThisLang = LoadPerfGetLanguage(pLang->LangId, FALSE);
BOOL bReturn = FALSE;
if (lpLocalStringBuff != NULL && szThisLang != NULL) {
* lpLocalStringBuff = NULL;
lpPosition = strchr(lpLocalSectionBuff, cEquals);
if (lpPosition) {
lpPosition ++;
// make sure the "=" isn't the last char
if (* lpPosition != '\0') {
//Found the "equals" sign
* lpLocalStringBuff = LoadPerfMultiByteToWideChar(LoadPerfGetCodePage(szThisLang), lpPosition);
}
else {
// empty string, return a pseudo blank string
* lpLocalStringBuff = LoadPerfMultiByteToWideChar(LoadPerfGetCodePage(szThisLang), " ");
}
bReturn = TRUE;
}
else {
//ErrorFinfing the "="
// bad format
SetLastError(ERROR_INVALID_DATA);
}
}
return bReturn;
}
BOOL
GetValueFromIniKeyA(
PLANGUAGE_LIST_ELEMENT pLang,
LPSTR lpValueKey,
LPSTR lpTextSection,
DWORD * pdwLastReadOffset,
DWORD dwTryCount,
LPWSTR * lpLocalStringBuff
)
{
LPSTR lpLocalSectionBuff;
DWORD dwIndex;
DWORD dwLastReadOffset;
BOOL bRetVal = FALSE;
if (lpTextSection != NULL && lpValueKey != NULL ) {
dwLastReadOffset = * pdwLastReadOffset;
lpLocalSectionBuff = lpTextSection;
lpLocalSectionBuff += dwLastReadOffset;
while(! (* lpLocalSectionBuff)) {
dwLastReadOffset += (lstrlenA(lpTextSection + dwLastReadOffset) + 1);
lpLocalSectionBuff = lpTextSection + dwLastReadOffset;
* pdwLastReadOffset = dwLastReadOffset;
}
// search next N entries in buffer for entry
// this should usually work since the file
// is scanned sequentially so it's tried first
for (dwIndex = 0; dwIndex < dwTryCount; dwIndex++) {
// see if this is the correct entry
// and return it if it is
if (strstr(lpLocalSectionBuff, lpValueKey)) {
bRetVal = GetValueA(pLang, lpLocalSectionBuff, lpLocalStringBuff);
//Set the lastReadOffset First
dwLastReadOffset += (lstrlenA(lpTextSection + dwLastReadOffset) + 1);
* pdwLastReadOffset = dwLastReadOffset;
break; // out of the for loop
}
else {
// this isn't the correct one so go to the next
// entry in the file
dwLastReadOffset += (lstrlenA(lpTextSection + dwLastReadOffset) + 1);
lpLocalSectionBuff = lpTextSection + dwLastReadOffset;
* pdwLastReadOffset = dwLastReadOffset;
}
}
if (! bRetVal) {
//Cannont Find the key using lastReadOffset
//try again from the beggining of the Array
dwLastReadOffset = 0;
lpLocalSectionBuff = lpTextSection;
* pdwLastReadOffset = dwLastReadOffset;
while (* lpLocalSectionBuff != '\0') {
if (strstr(lpLocalSectionBuff, lpValueKey)) {
bRetVal = GetValueA(pLang, lpLocalSectionBuff, lpLocalStringBuff);
break;
}
else {
// go to the next entry
dwLastReadOffset += (lstrlenA(lpTextSection + dwLastReadOffset) + 1);
lpLocalSectionBuff = lpTextSection + dwLastReadOffset;
* pdwLastReadOffset = dwLastReadOffset;
}
}
}
}
return bRetVal;
}
BOOL
AddEntryToLanguage(
PLANGUAGE_LIST_ELEMENT pLang,
LPWSTR lpValueKey,
LPWSTR lpTextSection,
DWORD dwUnicode,
DWORD * pdwLastReadOffset,
DWORD dwTryCount,
DWORD dwType,
DWORD dwOffset,
DWORD dwFileSize
)
/*++
AddEntryToLanguage
Add a text entry to the list of text entries for the specified language
Arguments
pLang
pointer to language structure to update
lpValueKey
value key to look up in .ini file
dwOffset
numeric offset of name in registry
lpIniFile
ini file
Return Value
TRUE if added successfully
FALSE if error
(see GetLastError for status)
--*/
{
LPWSTR lpLocalStringBuff = NULL;
LPSTR aszValueKey = (LPSTR) lpValueKey;
LPSTR aszTextSection = (LPSTR) lpTextSection;
DWORD dwBufferSize = 0;
DWORD dwStatus = ERROR_SUCCESS;
BOOL bRetVal;
BOOL bReturn = FALSE;
HRESULT hr;
if ((dwType == TYPE_NAME && dwOffset < FIRST_EXT_COUNTER_INDEX)
|| (dwType == TYPE_HELP && dwOffset < FIRST_EXT_HELP_INDEX)) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE,
(DWORD) LDPRFMSG_CORRUPT_INDEX,
3, dwOffset, dwType, __LINE__, 0,
1, lpValueKey, NULL, NULL);
if (dwUnicode == 0) {
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_ADDENTRYTOLANGUAGE,
ARG_DEF(ARG_TYPE_STR, 1) | ARG_DEF(ARG_TYPE_STR, 2),
ERROR_BADKEY,
TRACE_STR(aszTextSection),
TRACE_STR(aszValueKey),
TRACE_DWORD(dwType),
TRACE_DWORD(dwOffset),
NULL));
}
else {
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_ADDENTRYTOLANGUAGE,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
ERROR_BADKEY,
TRACE_WSTR(lpTextSection),
TRACE_WSTR(lpValueKey),
TRACE_DWORD(dwType),
TRACE_DWORD(dwOffset),
NULL));
}
dwStatus = ERROR_BADKEY;
goto Cleanup;
}
if (lpValueKey != NULL) {
if (dwUnicode == 0) {
bRetVal = GetValueFromIniKeyA(pLang,
aszValueKey,
aszTextSection,
pdwLastReadOffset,
dwTryCount,
& lpLocalStringBuff);
}
else {
bRetVal = GetValueFromIniKeyW(pLang,
lpValueKey,
lpTextSection,
pdwLastReadOffset,
dwTryCount,
& lpLocalStringBuff);
}
if (! bRetVal || lpLocalStringBuff == NULL) {
DWORD dwLastReadOffset = * pdwLastReadOffset;
if (dwUnicode == 0) {
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_ADDENTRYTOLANGUAGE,
ARG_DEF(ARG_TYPE_STR, 1) | ARG_DEF(ARG_TYPE_STR, 2),
ERROR_BADKEY,
TRACE_STR(aszTextSection),
TRACE_STR(aszValueKey),
TRACE_DWORD(dwLastReadOffset),
NULL));
}
else {
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_ADDENTRYTOLANGUAGE,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
ERROR_BADKEY,
TRACE_WSTR(lpTextSection),
TRACE_WSTR(lpValueKey),
TRACE_DWORD(dwLastReadOffset),
NULL));
}
dwStatus = ERROR_BADKEY;
goto Cleanup;
}
else if (lstrcmpiW(lpLocalStringBuff, wszNotFound) == 0) {
if (dwUnicode == 0) {
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_ADDENTRYTOLANGUAGE,
ARG_DEF(ARG_TYPE_STR, 1) | ARG_DEF(ARG_TYPE_STR, 2),
ERROR_BADKEY,
TRACE_STR(aszTextSection),
TRACE_STR(aszValueKey),
NULL));
}
else {
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_ADDENTRYTOLANGUAGE,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
ERROR_BADKEY,
TRACE_WSTR(lpTextSection),
TRACE_WSTR(lpValueKey),
NULL));
}
dwStatus = ERROR_BADKEY;
goto Cleanup;
}
}
else {
dwBufferSize = lstrlenW(lpTextSection) + 1;
lpLocalStringBuff = MemoryAllocate(dwBufferSize * sizeof(WCHAR));
if (!lpLocalStringBuff) {
dwStatus = ERROR_OUTOFMEMORY;
goto Cleanup;
}
hr = StringCchCopyW(lpLocalStringBuff, dwBufferSize, lpTextSection);
}
// key found, so load structure
if (! pLang->pThisName) {
// this is the first
pLang->pThisName = MemoryAllocate(sizeof(NAME_ENTRY) +
(lstrlenW(lpLocalStringBuff) + 1) * sizeof (WCHAR));
if (!pLang->pThisName) {
dwStatus = ERROR_OUTOFMEMORY;
goto Cleanup;
}
else {
pLang->pFirstName = pLang->pThisName;
}
}
else {
pLang->pThisName->pNext = MemoryAllocate(sizeof(NAME_ENTRY) +
(lstrlenW(lpLocalStringBuff) + 1) * sizeof (WCHAR));
if (!pLang->pThisName->pNext) {
dwStatus = ERROR_OUTOFMEMORY;
goto Cleanup;
}
else {
pLang->pThisName = pLang->pThisName->pNext;
}
}
// pLang->pThisName now points to an uninitialized structre
pLang->pThisName->pNext = NULL;
pLang->pThisName->dwOffset = dwOffset;
pLang->pThisName->dwType = dwType;
pLang->pThisName->lpText = (LPWSTR) & (pLang->pThisName[1]);
hr = StringCchCopyW(pLang->pThisName->lpText, lstrlenW(lpLocalStringBuff) + 1, lpLocalStringBuff);
bReturn = TRUE;
Cleanup:
MemoryFree(lpLocalStringBuff);
SetLastError(dwStatus);
return (bReturn);
}
BOOL
CreateObjectList(
LPWSTR lpIniFile,
DWORD dwFirstDriverCounter,
PSYMBOL_TABLE_ENTRY pFirstSymbol,
LPWSTR lpszObjectList,
DWORD dwObjectList,
LPDWORD pdwObjectGuidTableEntries
)
{
WCHAR szDigits[32];
LPWSTR szLangId;
LPWSTR szTempString;
LPSTR szGuidStringBuffer;
LPSTR szThisKey;
DWORD dwSize;
DWORD dwObjectCount = 0;
DWORD dwId;
DWORD dwType;
DWORD dwObjectGuidIndex = 0;
DWORD dwObjects[MAX_PERF_OBJECTS_IN_QUERY_FUNCTION];
DWORD dwBufferSize = 0;
LPSTR szObjectSectionEntries = NULL;
BOOL bResult = FALSE;
DWORD dwStatus = ERROR_SUCCESS;
LPSTR aszIniFile = NULL;
HRESULT hr;
if (lpIniFile == NULL) {
dwStatus = ERROR_INVALID_PARAMETER;
goto Cleanup;
}
aszIniFile = LoadPerfWideCharToMultiByte(CP_ACP, lpIniFile);
if (aszIniFile == NULL) {
dwStatus = ERROR_OUTOFMEMORY;
goto Cleanup;
}
dwBufferSize = LoadPerfGetFileSize(lpIniFile, NULL, TRUE);
if (dwBufferSize != 0xFFFFFFFF) {
dwBufferSize *= sizeof(WCHAR);
}
else {
dwBufferSize = 0;
}
if (dwBufferSize < SMALL_BUFFER_SIZE) {
dwBufferSize = SMALL_BUFFER_SIZE;
}
szObjectSectionEntries = MemoryAllocate(dwBufferSize * sizeof(CHAR));
if (szObjectSectionEntries == NULL) {
dwStatus = ERROR_OUTOFMEMORY;
goto Cleanup;
}
dwSize = GetPrivateProfileStringA(
szObjects,
NULL,
szNotFound,
szObjectSectionEntries,
dwBufferSize,
aszIniFile);
* lpszObjectList = L'\0';
dwObjectCount = 0;
if (lstrcmpiA(szObjectSectionEntries, szNotFound) != 0) {
// then some entries were found so read each one, compute the
// index value and save in the string buffer passed by the caller
for (szThisKey = szObjectSectionEntries; * szThisKey != '\0'; szThisKey += (lstrlenA(szThisKey) + 1)) {
// ParstTextId modifies the string so we need to make a work copy
szTempString = LoadPerfMultiByteToWideChar(CP_ACP, szThisKey);
if(szTempString == NULL) continue;
if (ParseTextId(szTempString, pFirstSymbol, & dwId, & szLangId, & dwType)) {
// then dwID is the id of an object supported by this DLL
for (dwSize = 0; dwSize < dwObjectCount; dwSize ++) {
if ((dwId + dwFirstDriverCounter) == dwObjects[dwSize]) {
break;
}
}
if (dwSize >= dwObjectCount) {
if (dwObjectCount < MAX_PERF_OBJECTS_IN_QUERY_FUNCTION) {
if (dwObjectCount != 0) {
hr = StringCchCatW(lpszObjectList, dwObjectList, BlankString);
}
dwObjects[dwObjectCount] = dwId + dwFirstDriverCounter;
_ultow((dwId + dwFirstDriverCounter), szDigits, 10);
hr = StringCchCatW(lpszObjectList, dwObjectList, szDigits);
dwObjectCount ++;
}
else {
// Too manu objects defined in INI file. Ignore.
continue;
}
}
//
// now see if this object has a GUID string
//
szGuidStringBuffer = MemoryAllocate(dwBufferSize * sizeof(CHAR));
if (szGuidStringBuffer == NULL) {
MemoryFree(szTempString);
continue;
}
MemoryFree(szGuidStringBuffer);
}
MemoryFree(szTempString);
}
// save size of Guid Table
* pdwObjectGuidTableEntries = dwObjectGuidIndex;
}
else {
// log message that object list is not used
TRACE((WINPERF_DBG_TRACE_WARNING),
(& LoadPerfGuid,
__LINE__,
LOADPERF_CREATEOBJECTLIST,
ARG_DEF(ARG_TYPE_WSTR, 1),
ERROR_SUCCESS,
TRACE_WSTR(lpIniFile),
TRACE_DWORD(dwFirstDriverCounter),
NULL));
}
bResult = TRUE;
Cleanup:
MemoryFree(szObjectSectionEntries);
MemoryFree(aszIniFile);
if (! bResult) SetLastError(dwStatus);
return bResult;
}
BOOL
LoadLanguageLists(
BOOL bQuietMode,
LPWSTR lpIniFile,
LPWSTR lpDriverName,
DWORD dwMode,
DWORD dwFirstCounter,
DWORD dwFirstHelp,
PSYMBOL_TABLE_ENTRY pFirstSymbol,
PLANGUAGE_LIST_ELEMENT pFirstLang
)
/*++
LoadLanguageLists
Reads in the name and explain text definitions from the ini file and
builds a list of these items for each of the supported languages and
then combines all the entries into a sorted MULTI_SZ string buffer.
Arguments
lpIniFile
file containing the definitions to add to the registry
dwFirstCounter
starting counter name index number
dwFirstHelp
starting help text index number
pFirstLang
pointer to first element in list of language elements
Return Value
TRUE if all is well
FALSE if not
error is returned in GetLastError
--*/
{
LPSTR lpTextIdArray = NULL;
LPWSTR lpLocalKey = NULL;
LPWSTR lpThisLocalKey = NULL;
LPSTR lpThisIniFile = NULL;
LPWSTR lpwThisIniFile = NULL;
LPSTR lpThisKey = NULL;
LPSTR lpTextSectionArray = NULL;
LPWSTR lpInfPath = LoadPerfGetInfPath();
DWORD dwSize;
LPWSTR lpLang;
DWORD dwOffset;
DWORD dwType;
DWORD dwUnicode;
PLANGUAGE_LIST_ELEMENT pThisLang;
DWORD dwBufferSize;
DWORD dwPathSize;
DWORD dwSuccessCount = 0;
DWORD dwErrorCount = 0;
DWORD dwLastReadOffset = 0;
DWORD dwTryCount = 4; // Init this value with 4
// (at least 4 times to try maching Key and Value)
HRESULT hr;
pThisLang = pFirstLang;
while (pThisLang != NULL) {
// if you have more languages then increase this try limit to
// 4 + No. of langs
dwTryCount ++;
pThisLang = pThisLang->pNextLang;
}
if (lpIniFile == NULL || lpInfPath == NULL) {
dwErrorCount = 1;
SetLastError(ERROR_INVALID_PARAMETER);
goto Cleanup;
}
dwPathSize = lstrlenW(lpInfPath) + lstrlenW(lpDriverName) + lstrlenW(lpIniFile) + 10;
if (dwPathSize < MAX_PATH) dwPathSize = MAX_PATH;
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LOADLANGUAGELISTS,
ARG_DEF(ARG_TYPE_WSTR, 1),
ERROR_SUCCESS,
TRACE_WSTR(lpIniFile),
TRACE_DWORD(dwFirstCounter),
TRACE_DWORD(dwFirstHelp),
NULL));
for (pThisLang = pFirstLang; pThisLang != NULL; pThisLang = pThisLang->pNextLang) {
WORD wLangTable = LoadPerfGetLCIDFromString(pThisLang->LangId);
WORD wLangId;
BOOL bAddEntry;
if (dwMode & LODCTR_UPNF_NOBACKUP) {
lpThisIniFile = LoadPerfWideCharToMultiByte(CP_ACP, lpIniFile);
if (lpThisIniFile == NULL) {
continue;
}
}
else {
LPWSTR szThisLang = LoadPerfGetLanguage(pThisLang->LangId, FALSE);
lpThisIniFile = MemoryAllocate(dwPathSize * sizeof(CHAR));
if (lpThisIniFile == NULL) {
continue;
}
hr = StringCchPrintfA(lpThisIniFile, dwPathSize, "%ws%ws%ws%ws%ws%ws",
lpInfPath, szThisLang, Slash, lpDriverName, Slash, lpIniFile);
}
lpwThisIniFile = LoadPerfMultiByteToWideChar(CP_ACP, lpThisIniFile);
dwBufferSize = LoadPerfGetFileSize((LPWSTR) lpThisIniFile, & dwUnicode, FALSE);
if (dwBufferSize == 0) {
if (! (dwMode & LODCTR_UPNF_NOBACKUP)) {
ZeroMemory(lpThisIniFile, dwPathSize * sizeof(CHAR));
hr = StringCchPrintfA(lpThisIniFile, dwPathSize, "%ws%ws%ws%ws%ws%ws",
lpInfPath, DefaultLangId, Slash, lpDriverName, Slash, lpIniFile);
dwBufferSize = LoadPerfGetFileSize((LPWSTR) lpThisIniFile, & dwUnicode, FALSE);
}
}
if (dwBufferSize == 0xFFFFFFFF) {
dwBufferSize = 0;
}
if(dwBufferSize < SMALL_BUFFER_SIZE) dwBufferSize = SMALL_BUFFER_SIZE;
lpTextIdArray = MemoryAllocate(dwBufferSize * sizeof(CHAR));
lpTextSectionArray = MemoryAllocate(dwBufferSize * sizeof(WCHAR));
if (lpTextIdArray == NULL || lpTextSectionArray == NULL) {
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LOADLANGUAGELISTS,
ARG_DEF(ARG_TYPE_WSTR, 1),
ERROR_OUTOFMEMORY,
TRACE_WSTR(lpIniFile),
TRACE_DWORD(dwFirstCounter),
TRACE_DWORD(dwFirstHelp),
NULL));
dwErrorCount = 1;
SetLastError(ERROR_OUTOFMEMORY);
goto Cleanup;
}
// get list of text keys to look up
dwSize = GetPrivateProfileStringA(szText, // [text] section of .INI file
NULL, // return all keys
szNotFound,
lpTextIdArray, // return buffer
dwBufferSize,
lpThisIniFile); // .INI file name
if ((lstrcmpiA(lpTextIdArray, szNotFound)) == 0) {
// key not found, default returned
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LOADLANGUAGELISTS,
ARG_DEF(ARG_TYPE_WSTR, 1),
ERROR_NO_SUCH_GROUP,
TRACE_WSTR(lpIniFile),
TRACE_DWORD(dwFirstCounter),
TRACE_DWORD(dwFirstHelp),
NULL));
dwErrorCount ++;
SetLastError(ERROR_NO_SUCH_GROUP);
goto Cleanup;
}
// get the the [text] section from the ini file
if (dwUnicode == 0) {
dwSize = GetPrivateProfileSectionA(szText, // [text] section of .INI file
lpTextSectionArray, // return buffer
dwBufferSize * sizeof(WCHAR),
lpThisIniFile); // .INI file name
}
else {
dwSize = GetPrivateProfileSectionW(wszText, // [text] section of .INI file
(LPWSTR) lpTextSectionArray, // return buffer
dwBufferSize,
lpwThisIniFile); // .INI file name
}
// do each key returned
dwLastReadOffset = 0;
for (lpThisKey = lpTextIdArray;
lpThisKey != NULL && * lpThisKey != '\0';
lpThisKey += (lstrlenA(lpThisKey) + 1)) {
lpLocalKey = LoadPerfMultiByteToWideChar(CP_ACP, lpThisKey);
lpThisLocalKey = LoadPerfMultiByteToWideChar(CP_ACP, lpThisKey);
if (lpLocalKey == NULL || lpThisLocalKey == NULL) {
MemoryFree(lpLocalKey);
MemoryFree(lpThisLocalKey);
lpLocalKey = lpThisLocalKey = NULL;
continue;
}
// parse key to see if it's in the correct format
if (ParseTextId(lpLocalKey, pFirstSymbol, & dwOffset, & lpLang, & dwType)) {
// so get pointer to language entry structure
bAddEntry = FALSE;
wLangId = LoadPerfGetLCIDFromString(lpLang);
if (wLangId == wLangTable) {
bAddEntry = TRUE;
}
else if (PRIMARYLANGID(wLangTable) == wLangId) {
bAddEntry = TRUE;
}
else if (PRIMARYLANGID(wLangId) == wLangTable) {
bAddEntry = (GetUserDefaultUILanguage() == wLangId) ? TRUE : FALSE;
}
if (bAddEntry) {
if (! AddEntryToLanguage(pThisLang,
(dwUnicode == 0) ? ((LPWSTR) lpThisKey) : (lpThisLocalKey),
(LPWSTR) lpTextSectionArray,
dwUnicode,
& dwLastReadOffset,
dwTryCount,
dwType,
(dwOffset + ((dwType == TYPE_NAME)
? dwFirstCounter
: dwFirstHelp)),
dwBufferSize)) {
OUTPUT_MESSAGE(bQuietMode,
GetFormatResource(LC_ERRADDTOLANG),
lpLocalKey,
lpLang,
GetLastError());
dwErrorCount ++;
}
else {
dwSuccessCount ++;
}
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LOADLANGUAGELISTS,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
ERROR_SUCCESS,
TRACE_WSTR(lpLocalKey),
TRACE_WSTR(lpLang),
TRACE_DWORD(dwOffset),
TRACE_DWORD(dwType),
NULL));
}
}
else { // unable to parse ID string
OUTPUT_MESSAGE(bQuietMode, GetFormatResource(LC_BAD_KEY), lpLocalKey);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LOADLANGUAGELISTS,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
ERROR_BADKEY,
TRACE_WSTR(lpLocalKey),
TRACE_WSTR(lpLang),
NULL));
}
MemoryFree(lpLocalKey);
MemoryFree(lpThisLocalKey);
lpLocalKey = lpThisLocalKey = NULL;
}
MemoryFree(lpTextIdArray);
MemoryFree(lpTextSectionArray);
lpTextIdArray = lpTextSectionArray = NULL;
}
Cleanup:
MemoryFree(lpwThisIniFile);
MemoryFree(lpThisIniFile);
MemoryFree(lpTextIdArray);
MemoryFree(lpLocalKey);
MemoryFree(lpThisLocalKey);
MemoryFree(lpTextSectionArray);
return (BOOL) (dwErrorCount == 0);
}
BOOL
SortLanguageTables(
PLANGUAGE_LIST_ELEMENT pFirstLang,
PDWORD pdwLastName,
PDWORD pdwLastHelp
)
/*++
SortLangageTables
walks list of languages loaded, allocates and loads a sorted multi_SZ
buffer containing new entries to be added to current names/help text
Arguments
pFirstLang
pointer to first element in list of languages
ReturnValue
TRUE everything done as expected
FALSE error occurred, status in GetLastError
--*/
{
PLANGUAGE_LIST_ELEMENT pThisLang;
BOOL bSorted;
LPWSTR pNameBufPos, pHelpBufPos;
PNAME_ENTRY pThisName, pPrevName;
DWORD dwHelpSize, dwNameSize, dwSize;
DWORD dwCurrentLastName;
DWORD dwCurrentLastHelp;
BOOL bReturn = FALSE;
DWORD dwStatus = ERROR_SUCCESS;
HRESULT hr;
if (pdwLastName == NULL || pdwLastHelp == NULL) {
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_SORTLANGUAGETABLES,
0,
ERROR_BAD_ARGUMENTS,
NULL));
dwStatus = ERROR_BAD_ARGUMENTS;
goto Cleanup;
}
for (pThisLang = pFirstLang; pThisLang != NULL; pThisLang = pThisLang->pNextLang) {
// do each language in list
// sort elements in list by value (offset) so that lowest is first
if (pThisLang->pFirstName == NULL) {
// no elements in this list, continue the next one
continue;
}
bSorted = FALSE;
while (!bSorted) {
// point to start of list
pPrevName = pThisLang->pFirstName;
if (pPrevName) {
pThisName = pPrevName->pNext;
}
else {
break; // no elements in this list
}
if (!pThisName) {
break; // only one element in the list
}
bSorted = TRUE; // assume that it's sorted
// go until end of list
while (pThisName->pNext) {
if (pThisName->dwOffset > pThisName->pNext->dwOffset) {
// switch 'em
PNAME_ENTRY pA, pB;
pPrevName->pNext = pThisName->pNext;
pA = pThisName->pNext;
pB = pThisName->pNext->pNext;
pThisName->pNext = pB;
pA->pNext = pThisName;
pThisName = pA;
bSorted = FALSE;
}
//move to next entry
pPrevName = pThisName;
pThisName = pThisName->pNext;
}
// if bSorted = TRUE , then we walked all the way down
// the list without changing anything so that's the end.
}
// with the list sorted, build the MULTI_SZ strings for the
// help and name text strings
// compute buffer size
dwNameSize = dwHelpSize = 0;
dwCurrentLastName = 0;
dwCurrentLastHelp = 0;
for (pThisName = pThisLang->pFirstName; pThisName != NULL; pThisName = pThisName->pNext) {
// compute buffer requirements for this entry
dwSize = SIZE_OF_OFFSET_STRING;
dwSize += lstrlenW(pThisName->lpText);
dwSize += 1; // null
dwSize *= sizeof(WCHAR); // adjust for character size
// add to appropriate size register
if (pThisName->dwType == TYPE_NAME) {
dwNameSize += dwSize;
if (pThisName->dwOffset > dwCurrentLastName) {
dwCurrentLastName = pThisName->dwOffset;
}
}
else if (pThisName->dwType == TYPE_HELP) {
dwHelpSize += dwSize;
if (pThisName->dwOffset > dwCurrentLastHelp) {
dwCurrentLastHelp = pThisName->dwOffset;
}
}
}
// allocate buffers for the Multi_SZ strings
pThisLang->NameBuffer = MemoryAllocate(dwNameSize);
pThisLang->HelpBuffer = MemoryAllocate(dwHelpSize);
if (!pThisLang->NameBuffer || !pThisLang->HelpBuffer) {
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_SORTLANGUAGETABLES,
ARG_DEF(ARG_TYPE_WSTR, 1),
ERROR_OUTOFMEMORY,
TRACE_WSTR(pThisLang->LangId),
TRACE_DWORD(pThisLang->dwNumElements),
TRACE_DWORD(dwCurrentLastName),
TRACE_DWORD(dwCurrentLastHelp),
NULL));
dwStatus = ERROR_OUTOFMEMORY;
goto Cleanup;
}
// fill in buffers with sorted strings
pNameBufPos = (LPWSTR) pThisLang->NameBuffer;
pHelpBufPos = (LPWSTR) pThisLang->HelpBuffer;
for (pThisName = pThisLang->pFirstName; pThisName != NULL; pThisName = pThisName->pNext) {
if (pThisName->dwType == TYPE_NAME) {
// load number as first 0-term. string
hr = StringCchPrintfW(pNameBufPos, dwNameSize, szDFormat, pThisName->dwOffset);
dwSize = lstrlenW(pNameBufPos) + 1;
dwNameSize -= dwSize;
pNameBufPos += dwSize; // save NULL term.
// load the text to match
hr = StringCchCopyW(pNameBufPos, dwNameSize, pThisName->lpText);
dwSize = lstrlenW(pNameBufPos) + 1;
dwNameSize -= dwSize;
pNameBufPos += dwSize;
}
else if (pThisName->dwType == TYPE_HELP) {
// load number as first 0-term. string
hr = StringCchPrintfW(pHelpBufPos, dwHelpSize, szDFormat, pThisName->dwOffset);
dwSize = lstrlenW(pHelpBufPos) + 1;
dwHelpSize -= dwSize;
pHelpBufPos += dwSize; // save NULL term.
// load the text to match
hr = StringCchCopyW(pHelpBufPos, dwHelpSize, pThisName->lpText);
dwSize = lstrlenW(pHelpBufPos) + 1;
dwHelpSize -= dwSize;
pHelpBufPos += dwSize;
}
}
// add additional NULL at end of string to terminate MULTI_SZ
* pHelpBufPos = L'\0';
* pNameBufPos = L'\0';
// compute size of MULTI_SZ strings
pThisLang->dwNameBuffSize = (DWORD) ((PBYTE) pNameBufPos - (PBYTE) pThisLang->NameBuffer) + sizeof(WCHAR);
pThisLang->dwHelpBuffSize = (DWORD) ((PBYTE) pHelpBufPos - (PBYTE) pThisLang->HelpBuffer) + sizeof(WCHAR);
if (* pdwLastName < dwCurrentLastName) {
* pdwLastName = dwCurrentLastName;
}
if (* pdwLastHelp < dwCurrentLastHelp) {
* pdwLastHelp = dwCurrentLastHelp;
}
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_SORTLANGUAGETABLES,
ARG_DEF(ARG_TYPE_WSTR, 1),
ERROR_SUCCESS,
TRACE_WSTR(pThisLang->LangId),
TRACE_DWORD(pThisLang->dwNumElements),
TRACE_DWORD(dwCurrentLastName),
TRACE_DWORD(dwCurrentLastHelp),
NULL));
}
dwCurrentLastName = * pdwLastName;
dwCurrentLastHelp = * pdwLastHelp;
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_SORTLANGUAGETABLES,
0,
ERROR_SUCCESS,
TRACE_DWORD(dwCurrentLastName),
TRACE_DWORD(dwCurrentLastHelp),
NULL));
if (dwCurrentLastHelp != dwCurrentLastName + 1) {
TRACE((WINPERF_DBG_TRACE_WARNING),
(& LoadPerfGuid,
__LINE__,
LOADPERF_SORTLANGUAGETABLES,
0,
ERROR_SUCCESS,
TRACE_DWORD(dwCurrentLastName),
TRACE_DWORD(dwCurrentLastHelp),
NULL));
dwCurrentLastHelp = dwCurrentLastName + 1;
* pdwLastHelp = dwCurrentLastHelp;
}
bReturn = TRUE;
Cleanup:
if (! bReturn) {
SetLastError(dwStatus);
}
return bReturn;
}
BOOL
GetInstalledLanguageList(
HKEY hPerflibRoot,
LPWSTR * mszLangList
)
/*++
returns a list of language sub keys found under the perflib key
GetInstalledLanguageList() build mszLandList MULTI_SZ string from performance registry setting.
Caller UpdateRegistry() should free the memory.
--*/
{
BOOL bReturn = TRUE;
LONG lStatus;
DWORD dwIndex = 0;
LPWSTR szBuffer;
DWORD dwBufSize = MAX_PATH;
LPWSTR szRetBuffer = NULL;
LPWSTR szTmpBuffer;
DWORD dwAllocSize = MAX_PATH;
DWORD dwRetBufSize = 0;
DWORD dwLastBufSize = 0;
LPWSTR szNextString;
HRESULT hr;
dwBufSize = MAX_PATH;
szBuffer = MemoryAllocate(dwBufSize * sizeof(WCHAR));
dwAllocSize = MAX_PATH;
szRetBuffer = MemoryAllocate(dwAllocSize * sizeof(WCHAR));
if (szBuffer == NULL || szRetBuffer == NULL) {
SetLastError(ERROR_OUTOFMEMORY);
bReturn = FALSE;
}
if (bReturn) {
while ((lStatus = RegEnumKeyExW(hPerflibRoot, dwIndex, szBuffer, & dwBufSize, NULL, NULL, NULL, NULL))
== ERROR_SUCCESS) {
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_GETINSTALLEDLANGUAGELIST,
ARG_DEF(ARG_TYPE_WSTR, 1),
ERROR_SUCCESS,
TRACE_WSTR(szBuffer),
TRACE_DWORD(dwIndex),
TRACE_DWORD(dwLastBufSize),
TRACE_DWORD(dwRetBufSize),
NULL));
dwRetBufSize += (lstrlenW(szBuffer) + 1);
if (dwRetBufSize >= dwAllocSize) {
szTmpBuffer = szRetBuffer;
dwAllocSize = dwRetBufSize + MAX_PATH;
szRetBuffer = MemoryResize(szTmpBuffer, dwAllocSize * sizeof(WCHAR));
}
if (szRetBuffer == NULL) {
MemoryFree(szTmpBuffer);
bReturn = FALSE;
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_GETINSTALLEDLANGUAGELIST,
ARG_DEF(ARG_TYPE_WSTR, 1),
ERROR_OUTOFMEMORY,
TRACE_WSTR(szBuffer),
TRACE_DWORD(dwIndex),
TRACE_DWORD(dwLastBufSize),
TRACE_DWORD(dwRetBufSize),
NULL));
SetLastError(ERROR_OUTOFMEMORY);
break;
}
szNextString = (LPWSTR) (szRetBuffer + dwLastBufSize);
hr = StringCchCopyW(szNextString, dwAllocSize - dwLastBufSize, szBuffer);
dwLastBufSize = dwRetBufSize;
dwIndex ++;
dwBufSize = MAX_PATH;
RtlZeroMemory(szBuffer, dwBufSize * sizeof(WCHAR));
}
}
if (bReturn) {
WCHAR szLangId[8];
DWORD dwSubLangId = GetUserDefaultUILanguage();
DWORD dwLangId = PRIMARYLANGID(dwSubLangId);
BOOL bFound = FALSE;
bFound = FALSE;
for (szNextString = szRetBuffer; * szNextString != L'\0'; szNextString += (lstrlenW(szNextString) + 1)) {
if (lstrcmpiW(szNextString, DefaultLangId) == 0) {
bFound = TRUE;
break;
}
}
if (! bFound) {
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_GETINSTALLEDLANGUAGELIST,
ARG_DEF(ARG_TYPE_WSTR, 1),
ERROR_SUCCESS,
TRACE_WSTR(DefaultLangId),
TRACE_DWORD(dwIndex),
TRACE_DWORD(dwLastBufSize),
TRACE_DWORD(dwRetBufSize),
NULL));
dwRetBufSize += (lstrlenW(DefaultLangId) + 1);
if (dwRetBufSize >= dwAllocSize) {
szTmpBuffer = szRetBuffer;
dwAllocSize = dwRetBufSize + MAX_PATH;
szRetBuffer = MemoryResize(szTmpBuffer, dwAllocSize * sizeof(WCHAR));
}
if (szRetBuffer == NULL) {
MemoryFree(szTmpBuffer);
bReturn = FALSE;
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_GETINSTALLEDLANGUAGELIST,
ARG_DEF(ARG_TYPE_WSTR, 1),
ERROR_OUTOFMEMORY,
TRACE_WSTR(DefaultLangId),
TRACE_DWORD(dwIndex),
TRACE_DWORD(dwLastBufSize),
TRACE_DWORD(dwRetBufSize),
NULL));
SetLastError(ERROR_OUTOFMEMORY);
}
else {
szNextString = (LPWSTR) (szRetBuffer + dwLastBufSize);
hr = StringCchCopyW(szNextString, dwAllocSize - dwLastBufSize, DefaultLangId);
dwLastBufSize = dwRetBufSize;
dwIndex ++;
}
}
if (dwLangId != 0x009) {
WCHAR nDigit;
DWORD dwThisLang;
ZeroMemory(szLangId, 8 * sizeof(WCHAR));
nDigit = (WCHAR) (dwLangId >> 8);
szLangId[0] = tohexdigit(nDigit);
nDigit = (WCHAR) (dwLangId & 0XF0) >> 4;
szLangId[1] = tohexdigit(nDigit);
nDigit = (WCHAR) (dwLangId & 0xF);
szLangId[2] = tohexdigit(nDigit);
bFound = FALSE;
for (szNextString = szRetBuffer; * szNextString != L'\0'; szNextString += (lstrlenW(szNextString) + 1)) {
dwThisLang = LoadPerfGetLCIDFromString(szNextString);
if (dwThisLang == dwSubLangId || PRIMARYLANGID(dwThisLang) == dwLangId) {
bFound = TRUE;
break;
}
}
if (! bFound) {
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_GETINSTALLEDLANGUAGELIST,
ARG_DEF(ARG_TYPE_WSTR, 1),
ERROR_SUCCESS,
TRACE_WSTR(szLangId),
TRACE_DWORD(dwIndex),
TRACE_DWORD(dwLastBufSize),
TRACE_DWORD(dwRetBufSize),
NULL));
dwRetBufSize += (lstrlenW(szLangId) + 1);
if (dwRetBufSize >= dwAllocSize) {
szTmpBuffer = szRetBuffer;
dwAllocSize = dwRetBufSize + MAX_PATH;
szRetBuffer = MemoryResize(szTmpBuffer, dwAllocSize * sizeof(WCHAR));
}
if (szRetBuffer == NULL) {
MemoryFree(szTmpBuffer);
bReturn = FALSE;
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_GETINSTALLEDLANGUAGELIST,
ARG_DEF(ARG_TYPE_WSTR, 1),
ERROR_OUTOFMEMORY,
TRACE_WSTR(szLangId),
TRACE_DWORD(dwIndex),
TRACE_DWORD(dwLastBufSize),
TRACE_DWORD(dwRetBufSize),
NULL));
SetLastError(ERROR_OUTOFMEMORY);
}
else {
szNextString = (LPWSTR) (szRetBuffer + dwLastBufSize);
hr = StringCchCopyW(szNextString, dwAllocSize - dwLastBufSize, szLangId);
dwLastBufSize = dwRetBufSize;
dwIndex ++;
}
}
}
}
if (bReturn) {
// add terminating null char
dwRetBufSize ++;
if (dwRetBufSize > dwAllocSize) {
szTmpBuffer = szRetBuffer;
dwAllocSize = dwRetBufSize;
szRetBuffer = MemoryResize(szTmpBuffer, dwRetBufSize * sizeof(WCHAR));
if (szRetBuffer == NULL) {
MemoryFree(szTmpBuffer);
SetLastError(ERROR_OUTOFMEMORY);
bReturn = FALSE;
}
}
if (szRetBuffer != NULL) {
szNextString = (LPWSTR) (szRetBuffer + dwLastBufSize);
* szNextString = L'\0';
}
}
if (bReturn) {
* mszLangList = szRetBuffer;
}
else {
* mszLangList = NULL;
MemoryFree(szRetBuffer);
}
MemoryFree(szBuffer);
return bReturn;
}
BOOL
CheckNameTable(
LPWSTR lpNameStr,
LPWSTR lpHelpStr,
LPDWORD pdwLastCounter,
LPDWORD pdwLastHelp,
BOOL bUpdate
)
{
BOOL bResult = TRUE;
BOOL bChanged = FALSE;
LPWSTR lpThisId;
DWORD dwThisId;
DWORD dwLastCounter = * pdwLastCounter;
DWORD dwLastHelp = * pdwLastHelp;
DWORD dwLastId = (dwLastCounter > dwLastHelp)
? (dwLastCounter) : (dwLastHelp);
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_CHECKNAMETABLE,
0,
ERROR_SUCCESS,
TRACE_DWORD(dwLastCounter),
TRACE_DWORD(dwLastHelp),
NULL));
for (lpThisId = lpNameStr; * lpThisId != L'\0'; lpThisId += (lstrlenW(lpThisId) + 1)) {
dwThisId = wcstoul(lpThisId, NULL, 10);
if ((dwThisId == 0) || (dwThisId != 1 && dwThisId % 2 != 0)) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_REGISTRY_COUNTER_STRINGS_CORRUPT,
4, dwThisId, dwLastCounter, dwLastId, __LINE__,
1, lpThisId, NULL, NULL);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_CHECKNAMETABLE,
ARG_DEF(ARG_TYPE_WSTR, 1),
ERROR_BADKEY,
TRACE_WSTR(lpThisId),
TRACE_DWORD(dwThisId),
TRACE_DWORD(dwLastCounter),
TRACE_DWORD(dwLastHelp),
NULL));
SetLastError(ERROR_BADKEY);
bResult = FALSE;
break;
}
else if (dwThisId > dwLastId || dwThisId > dwLastCounter) {
if (bUpdate) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_REGISTRY_COUNTER_STRINGS_CORRUPT,
4, dwThisId, dwLastCounter, dwLastId, __LINE__,
1, lpThisId, NULL, NULL);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_CHECKNAMETABLE,
ARG_DEF(ARG_TYPE_WSTR, 1),
ERROR_BADKEY,
TRACE_WSTR(lpThisId),
TRACE_DWORD(dwThisId),
TRACE_DWORD(dwLastCounter),
TRACE_DWORD(dwLastHelp),
NULL));
SetLastError(ERROR_BADKEY);
bResult = FALSE;
break;
}
else {
bChanged = TRUE;
if (dwThisId > dwLastCounter) dwLastCounter = dwThisId;
if (dwLastCounter > dwLastId) dwLastId = dwLastCounter;
}
}
lpThisId += (lstrlenW(lpThisId) + 1);
}
if (! bResult) goto Cleanup;
for (lpThisId = lpHelpStr; * lpThisId != L'\0'; lpThisId += (lstrlenW(lpThisId) + 1)) {
dwThisId = wcstoul(lpThisId, NULL, 10);
if ((dwThisId == 0) || (dwThisId != 1 && dwThisId % 2 == 0)) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_REGISTRY_HELP_STRINGS_CORRUPT,
4, dwThisId, dwLastHelp, dwLastId, __LINE__,
1, lpThisId, NULL, NULL);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_CHECKNAMETABLE,
ARG_DEF(ARG_TYPE_WSTR, 1),
ERROR_BADKEY,
TRACE_WSTR(lpThisId),
TRACE_DWORD(dwThisId),
TRACE_DWORD(dwLastCounter),
TRACE_DWORD(dwLastHelp),
NULL));
SetLastError(ERROR_BADKEY);
bResult = FALSE;
break;
}
else if (dwThisId > dwLastId || dwThisId > dwLastHelp) {
if (bUpdate) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_REGISTRY_HELP_STRINGS_CORRUPT,
4, dwThisId, dwLastHelp, dwLastId, __LINE__,
1, lpThisId, NULL, NULL);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_CHECKNAMETABLE,
ARG_DEF(ARG_TYPE_WSTR, 1),
ERROR_BADKEY,
TRACE_WSTR(lpThisId),
TRACE_DWORD(dwThisId),
TRACE_DWORD(dwLastCounter),
TRACE_DWORD(dwLastHelp),
NULL));
SetLastError(ERROR_BADKEY);
bResult = FALSE;
break;
}
else {
bChanged = TRUE;
if (dwThisId > dwLastHelp) dwLastHelp = dwThisId;
if (dwLastHelp > dwLastId) dwLastId = dwLastHelp;
}
}
lpThisId += (lstrlenW(lpThisId) + 1);
}
Cleanup:
if (bResult) {
if (bChanged) {
ReportLoadPerfEvent(
EVENTLOG_WARNING_TYPE,
(DWORD) LDPRFMSG_CORRUPT_PERFLIB_INDEX,
4, * pdwLastCounter, * pdwLastHelp, dwLastCounter, dwLastHelp,
0, NULL, NULL, NULL);
* pdwLastCounter = dwLastCounter;
* pdwLastHelp = dwLastHelp;
}
}
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_CHECKNAMETABLE,
0,
GetLastError(),
TRACE_DWORD(dwLastCounter),
TRACE_DWORD(dwLastHelp),
NULL));
return bResult;
}
BOOL
UpdateEachLanguage(
BOOL bQuietMode,
HKEY hPerflibRoot,
LPWSTR mszInstalledLangList,
LPDWORD pdwLastCounter,
LPDWORD pdwLastHelp,
PLANGUAGE_LIST_ELEMENT pFirstLang,
DWORD dwMode,
BOOL bUpdate
)
/*++
UpdateEachLanguage
Goes through list of languages and adds the sorted MULTI_SZ strings
to the existing counter and explain text in the registry.
Also updates the "Last Counter and Last Help" values
Arguments
hPerflibRoot handle to Perflib key in the registry
mszInstalledLangList
MSZ string of installed language keys
pFirstLanguage pointer to first language entry
Return Value
TRUE all went as planned
FALSE an error occured, use GetLastError to find out what it was.
--*/
{
PLANGUAGE_LIST_ELEMENT pThisLang;
LPWSTR pHelpBuffer = NULL;
LPWSTR pNameBuffer = NULL;
LPWSTR pNewName = NULL;
LPWSTR pNewHelp = NULL;
DWORD dwLastCounter = * pdwLastCounter;
DWORD dwLastHelp = * pdwLastHelp;
DWORD dwBufferSize;
DWORD dwValueType;
DWORD dwCounterSize;
DWORD dwHelpSize;
HKEY hKeyThisLang = NULL;
LONG lStatus;
LPWSTR CounterNameBuffer = NULL;
LPWSTR HelpNameBuffer = NULL;
LPWSTR AddCounterNameBuffer = NULL;
LPWSTR AddHelpNameBuffer = NULL;
LPWSTR szThisLang;
BOOL bResult = TRUE;
HRESULT hr;
if (bUpdate && ((dwMode & LODCTR_UPNF_REPAIR) == 0)) {
// this isn't possible on 3.1
MakeBackupCopyOfLanguageFiles(NULL);
}
CounterNameBuffer = MemoryAllocate(4 * MAX_PATH * sizeof(WCHAR));
if (CounterNameBuffer == NULL) {
lStatus = ERROR_OUTOFMEMORY;
goto Cleanup;
}
HelpNameBuffer = CounterNameBuffer + MAX_PATH;
AddCounterNameBuffer = HelpNameBuffer + MAX_PATH;
AddHelpNameBuffer = AddCounterNameBuffer + MAX_PATH;
for (szThisLang = mszInstalledLangList; *szThisLang != L'\0'; szThisLang += (lstrlenW(szThisLang) + 1)) {
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEEACHLANGUAGE,
ARG_DEF(ARG_TYPE_WSTR, 1),
ERROR_SUCCESS,
TRACE_WSTR(szThisLang),
NULL));
hr = StringCchPrintfW(CounterNameBuffer, MAX_PATH, L"%ws%ws", CounterNameStr, szThisLang);
hr = StringCchPrintfW(HelpNameBuffer, MAX_PATH, L"%ws%ws", HelpNameStr, szThisLang);
hr = StringCchPrintfW(AddCounterNameBuffer, MAX_PATH, L"%ws%ws", AddCounterNameStr, szThisLang);
hr = StringCchPrintfW(AddHelpNameBuffer, MAX_PATH, L"%ws%ws", AddHelpNameStr, szThisLang);
// make sure this language is loaded
__try {
lStatus = RegOpenKeyExW(hPerflibRoot, szThisLang, RESERVED, KEY_READ, & hKeyThisLang);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lStatus = GetExceptionCode();
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEEACHLANGUAGE,
ARG_DEF(ARG_TYPE_WSTR, 1),
lStatus,
TRACE_WSTR(szThisLang),
NULL));
}
// we just need the open status, not the key handle so
// close this handle and set the one we need.
if (lStatus == ERROR_SUCCESS) {
RegCloseKey(hKeyThisLang);
}
else if (lStatus == ERROR_FILE_NOT_FOUND) {
// Somehow language subkey is not there under
// "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PERFLIB".
// This should be a rare case, but seems like a common scenario during upgrade
// from NT4 to XP and .NET server.
// We should still treat this as success and try update it.
//
lStatus = ERROR_SUCCESS;
}
hKeyThisLang = HKEY_PERFORMANCE_DATA;
if (bUpdate) {
// look up the new strings to add
pThisLang = FindLanguage(pFirstLang, szThisLang);
if (pThisLang == NULL) {
// try default language if available
pThisLang = FindLanguage(pFirstLang, DefaultLangTag);
}
else if (pThisLang->NameBuffer == NULL || pThisLang->HelpBuffer == NULL) {
TRACE((WINPERF_DBG_TRACE_WARNING),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEEACHLANGUAGE,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
LDPRFMSG_CORRUPT_INCLUDE_FILE,
TRACE_WSTR(pThisLang->LangId),
TRACE_WSTR(szThisLang),
NULL));
pThisLang = FindLanguage(pFirstLang, DefaultLangTag);
}
if (pThisLang == NULL) {
// try english language if available
pThisLang = FindLanguage(pFirstLang, DefaultLangId);
}
else if (pThisLang->NameBuffer == NULL || pThisLang->HelpBuffer == NULL) {
TRACE((WINPERF_DBG_TRACE_WARNING),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEEACHLANGUAGE,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
LDPRFMSG_CORRUPT_INCLUDE_FILE,
TRACE_WSTR(pThisLang->LangId),
TRACE_WSTR(szThisLang),
NULL));
pThisLang = FindLanguage(pFirstLang, DefaultLangId);
}
if (pThisLang == NULL) {
// unable to add this language so continue
lStatus = ERROR_NO_MATCH;
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEEACHLANGUAGE,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2) | ARG_DEF(ARG_TYPE_WSTR, 3),
lStatus,
TRACE_WSTR(szThisLang),
TRACE_WSTR(DefaultLangTag),
TRACE_WSTR(DefaultLangId),
TRACE_DWORD(dwLastCounter),
TRACE_DWORD(dwLastHelp),
NULL));
}
else {
if (pThisLang->NameBuffer == NULL || pThisLang->HelpBuffer == NULL) {
ReportLoadPerfEvent(
EVENTLOG_WARNING_TYPE, // error type
(DWORD) LDPRFMSG_CORRUPT_INCLUDE_FILE, // event,
1, __LINE__, 0, 0, 0,
1, pThisLang->LangId, NULL, NULL);
TRACE((WINPERF_DBG_TRACE_WARNING),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEEACHLANGUAGE,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
LDPRFMSG_CORRUPT_INCLUDE_FILE,
TRACE_WSTR(pThisLang->LangId),
TRACE_WSTR(szThisLang),
NULL));
lStatus = LDPRFMSG_CORRUPT_INCLUDE_FILE;
}
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEEACHLANGUAGE,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
lStatus,
TRACE_WSTR(pThisLang->LangId),
TRACE_WSTR(szThisLang),
TRACE_DWORD(dwLastCounter),
TRACE_DWORD(dwLastHelp),
NULL));
}
}
if (lStatus == ERROR_SUCCESS) {
// get size of counter names
dwBufferSize = 0;
__try {
lStatus = RegQueryValueExW(hKeyThisLang,
CounterNameBuffer,
RESERVED,
& dwValueType,
NULL,
& dwBufferSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lStatus = GetExceptionCode();
}
if (lStatus != ERROR_SUCCESS) {
// this means the language is not installed in the system.
continue;
}
dwCounterSize = dwBufferSize;
// get size of help text
dwBufferSize = 0;
__try {
lStatus = RegQueryValueExW(hKeyThisLang,
HelpNameBuffer,
RESERVED,
& dwValueType,
NULL,
& dwBufferSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lStatus = GetExceptionCode();
}
if (lStatus != ERROR_SUCCESS) {
// this means the language is not installed in the system.
continue;
}
dwHelpSize = dwBufferSize;
// allocate new buffers
if (bUpdate) {
dwCounterSize += pThisLang->dwNameBuffSize;
dwHelpSize += pThisLang->dwHelpBuffSize;
}
pNameBuffer = MemoryAllocate(dwCounterSize);
pHelpBuffer = MemoryAllocate(dwHelpSize);
if (pNameBuffer == NULL || pHelpBuffer== NULL) {
lStatus = ERROR_OUTOFMEMORY;
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEEACHLANGUAGE,
0,
ERROR_OUTOFMEMORY,
NULL));
bResult = FALSE;
goto Cleanup;
}
// load current buffers into memory
// read counter names into buffer. Counter names will be stored as
// a MULTI_SZ string in the format of "###" "Name"
dwBufferSize = dwCounterSize;
__try {
lStatus = RegQueryValueExW(hKeyThisLang,
CounterNameBuffer,
RESERVED,
& dwValueType,
(LPVOID) pNameBuffer,
& dwBufferSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lStatus = GetExceptionCode();
}
if (lStatus != ERROR_SUCCESS) {
// this means the language is not installed in the system.
continue;
}
if (bUpdate) {
// set pointer to location in buffer where new string should be
// appended: end of buffer - 1 (second null at end of MULTI_SZ
pNewName = (LPWSTR) ((PBYTE) pNameBuffer + dwBufferSize - sizeof(WCHAR));
// adjust buffer length to take into account 2nd null from 1st
// buffer that has been overwritten
dwCounterSize -= sizeof(WCHAR);
}
// read explain text into buffer. Counter names will be stored as
// a MULTI_SZ string in the format of "###" "Text..."
dwBufferSize = dwHelpSize;
__try {
lStatus = RegQueryValueExW(hKeyThisLang,
HelpNameBuffer,
RESERVED,
& dwValueType,
(LPVOID) pHelpBuffer,
& dwBufferSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lStatus = GetExceptionCode();
}
if (lStatus != ERROR_SUCCESS) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_UNABLE_READ_HELP_STRINGS, // event,
2, lStatus, __LINE__, 0, 0,
1, szThisLang, NULL, NULL);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEEACHLANGUAGE,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
lStatus,
TRACE_WSTR(szThisLang),
TRACE_WSTR(Help),
NULL));
bResult = FALSE;
goto Cleanup;
}
if (bUpdate) {
// set pointer to location in buffer where new string should be
// appended: end of buffer - 1 (second null at end of MULTI_SZ
pNewHelp = (LPWSTR) ((PBYTE)pHelpBuffer + dwBufferSize - sizeof(WCHAR));
// adjust buffer length to take into account 2nd null from 1st
// buffer that has been overwritten
dwHelpSize -= sizeof(WCHAR);
}
if (bUpdate) {
// append new strings to end of current strings
memcpy(pNewHelp, pThisLang->HelpBuffer, pThisLang->dwHelpBuffSize);
memcpy(pNewName, pThisLang->NameBuffer, pThisLang->dwNameBuffSize);
}
if (! CheckNameTable(pNameBuffer, pHelpBuffer, & dwLastCounter, & dwLastHelp, bUpdate)) {
bResult = FALSE;
goto Cleanup;
}
if (bUpdate) {
// write to the file thru PerfLib
dwBufferSize = dwCounterSize;
__try {
lStatus = RegQueryValueExW(hKeyThisLang,
AddCounterNameBuffer,
RESERVED,
& dwValueType,
(LPVOID) pNameBuffer,
& dwBufferSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lStatus = GetExceptionCode();
}
if (lStatus != ERROR_SUCCESS) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_UNABLE_UPDATE_COUNTER_STRINGS, // event,
2, lStatus, __LINE__, 0, 0,
1, pThisLang->LangId, NULL, NULL);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEEACHLANGUAGE,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
lStatus,
TRACE_WSTR(pThisLang->LangId),
TRACE_WSTR(AddCounterNameBuffer),
NULL));
bResult = FALSE;
goto Cleanup;
}
dwBufferSize = dwHelpSize;
__try {
lStatus = RegQueryValueExW(hKeyThisLang,
AddHelpNameBuffer,
RESERVED,
& dwValueType,
(LPVOID) pHelpBuffer,
& dwBufferSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lStatus = GetExceptionCode();
}
if (lStatus != ERROR_SUCCESS) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_UNABLE_UPDATE_HELP_STRINGS, // event,
2, lStatus, __LINE__, 0, 0,
1, pThisLang->LangId, NULL, NULL);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEEACHLANGUAGE,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
lStatus,
TRACE_WSTR(pThisLang->LangId),
TRACE_WSTR(AddHelpNameBuffer),
NULL));
bResult = FALSE;
goto Cleanup;
}
}
MemoryFree(pNameBuffer);
MemoryFree(pHelpBuffer);
pNameBuffer = NULL;
pHelpBuffer = NULL;
}
else {
OUTPUT_MESSAGE(bQuietMode, GetFormatResource (LC_UNABLEOPENLANG), szThisLang);
}
}
Cleanup:
MemoryFree(pNameBuffer);
MemoryFree(pHelpBuffer);
MemoryFree(CounterNameBuffer);
if (! bResult) {
SetLastError(lStatus);
}
else if (! bUpdate) {
* pdwLastCounter = dwLastCounter;
* pdwLastHelp = dwLastHelp;
}
return bResult;
}
BOOL
UpdateRegistry(
BOOL bQuietMode,
DWORD dwMode,
LPWSTR lpDriverName,
LPWSTR lpIniFile,
LPWSTR lp009IniFile,
PLANG_ENTRY pLanguages,
PSERVICE_ENTRY pService,
PLANGUAGE_LIST_ELEMENT pFirstLang,
PSYMBOL_TABLE_ENTRY pFirstSymbol,
LPDWORD pdwObjectGuidTableSize,
LPDWORD pdwIndexValues
)
/*++
UpdateRegistry
- checks, and if not busy, sets the "busy" key in the registry
- Reads in the text and help definitions from the .ini file
- Reads in the current contents of the HELP and COUNTER names
- Builds a sorted MULTI_SZ struct containing the new definitions
- Appends the new MULTI_SZ to the current as read from the registry
- loads the new MULTI_SZ string into the registry
- updates the keys in the driver's entry and Perflib's entry in the
registry (e.g. first, last, etc)
- deletes the DisablePerformanceCounters value if it's present in
order to re-enable the perf counter DLL
- clears the "busy" key
Arguments
lpIniFile
pathname to .ini file conatining definitions
hKeyMachine
handle to HKEY_LOCAL_MACHINE in registry on system to
update counters for.
lpDriverName
Name of device driver to load counters for
pFirstLang
pointer to first element in language structure list
pFirstSymbol
pointer to first element in symbol definition list
Return Value
TRUE if registry updated successfully
FALSE if registry not updated
(This routine will print an error message to stdout if an error
is encountered).
--*/
{
HKEY hDriverPerf = NULL;
HKEY hPerflib = NULL;
LPWSTR lpDriverKeyPath;
HKEY hKeyMachine = NULL;
DWORD dwType;
DWORD dwSize;
DWORD dwFirstDriverCounter;
DWORD dwFirstDriverHelp;
DWORD dwLastDriverCounter;
DWORD dwLastPerflibCounter;
DWORD dwLastPerflibHelp;
DWORD dwPerflibBaseIndex;
DWORD dwLastCounter;
DWORD dwLastHelp;
BOOL bStatus = FALSE;
LONG lStatus = ERROR_SUCCESS;
LPWSTR lpszObjectList = NULL;
DWORD dwObjectList = 0;
LPWSTR mszLangList = NULL;
DWORD dwWaitStatus;
HANDLE hLocalMutex = NULL;
HRESULT hr;
SetLastError(ERROR_SUCCESS);
if (! (dwMode & LODCTR_UPNF_NOINI)) {
dwObjectList = LoadPerfGetFileSize(lp009IniFile, NULL, TRUE);
if (dwObjectList == 0xFFFFFFFF) {
dwObjectList = 0;
}
}
if (dwObjectList < SMALL_BUFFER_SIZE) {
dwObjectList = SMALL_BUFFER_SIZE;
}
// allocate temporary buffers
dwSize = lstrlenW(DriverPathRoot) + lstrlenW(Slash) + lstrlenW(lpDriverName)
+ lstrlenW(Slash) + lstrlenW(Performance) + 1;
if (dwSize < MAX_PATH) dwSize = MAX_PATH;
lpDriverKeyPath = MemoryAllocate(dwSize * sizeof(WCHAR));
lpszObjectList = MemoryAllocate(dwObjectList * sizeof(WCHAR));
if (lpDriverKeyPath == NULL || lpszObjectList == NULL) {
lStatus = ERROR_OUTOFMEMORY;
goto UpdateRegExit;
}
// build driver key path string
hr = StringCchPrintfW(lpDriverKeyPath, dwSize, L"%ws%ws%ws%ws%ws",
DriverPathRoot, Slash, lpDriverName, Slash, Performance);
// check if we need to connect to remote machine
hKeyMachine = HKEY_LOCAL_MACHINE;
// open keys to registry
// open key to driver's performance key
__try {
lStatus = RegOpenKeyExW(hKeyMachine, lpDriverKeyPath, RESERVED, KEY_WRITE | KEY_READ, & hDriverPerf);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lStatus = GetExceptionCode();
}
if (lStatus != ERROR_SUCCESS) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_UNABLE_OPEN_KEY, // event,
2, lStatus, __LINE__, 0, 0,
1, (LPWSTR) lpDriverKeyPath, NULL, NULL);
OUTPUT_MESSAGE(bQuietMode, GetFormatResource(LC_ERR_OPEN_DRIVERPERF1), lpDriverKeyPath);
OUTPUT_MESSAGE(bQuietMode, GetFormatResource(LC_ERR_OPEN_DRIVERPERF2), lStatus);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEREGISTRY,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
lStatus,
TRACE_WSTR(lpIniFile),
TRACE_WSTR(lpDriverName),
NULL));
goto UpdateRegExit;
}
// open key to perflib's "root" key
__try {
lStatus = RegOpenKeyExW(hKeyMachine, NamesKey, RESERVED, KEY_WRITE | KEY_READ, & hPerflib);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lStatus = GetExceptionCode();
}
if (lStatus != ERROR_SUCCESS) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_UNABLE_OPEN_KEY, // event,
2, lStatus, __LINE__, 0, 0,
1, (LPWSTR) NamesKey, NULL, NULL);
OUTPUT_MESSAGE(bQuietMode, GetFormatResource(LC_ERR_OPEN_PERFLIB), lStatus);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEREGISTRY,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
lStatus,
TRACE_WSTR(lpDriverName),
TRACE_WSTR(NamesKey),
NULL));
goto UpdateRegExit;
}
// get "LastCounter" values from PERFLIB
dwType = 0;
dwLastPerflibCounter = 0;
dwSize = sizeof(dwLastPerflibCounter);
__try {
lStatus = RegQueryValueExW(hPerflib,
LastCounter,
RESERVED,
& dwType,
(LPBYTE) & dwLastPerflibCounter,
& dwSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lStatus = GetExceptionCode();
}
if (lStatus != ERROR_SUCCESS) {
// this request should always succeed, if not then worse things
// will happen later on, so quit now and avoid the trouble.
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_UNABLE_QUERY_VALUE, // event,
2, lStatus, __LINE__, 0, 0,
2, (LPWSTR) LastCounter, (LPWSTR) NamesKey, NULL);
OUTPUT_MESSAGE(bQuietMode, GetFormatResource(LC_ERR_READLASTPERFLIB), lStatus);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEREGISTRY,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
lStatus,
TRACE_WSTR(NamesKey),
TRACE_WSTR(LastCounter),
NULL));
goto UpdateRegExit;
}
// get "LastHelp" value now
dwType = 0;
dwLastPerflibHelp = 0;
dwSize = sizeof(dwLastPerflibHelp);
__try {
lStatus = RegQueryValueExW(hPerflib,
LastHelp,
RESERVED,
& dwType,
(LPBYTE) & dwLastPerflibHelp,
& dwSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lStatus = GetExceptionCode();
}
if (lStatus != ERROR_SUCCESS) {
// this request should always succeed, if not then worse things
// will happen later on, so quit now and avoid the trouble.
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_UNABLE_QUERY_VALUE, // event,
2, lStatus, __LINE__, 0, 0,
2, (LPWSTR) LastHelp, (LPWSTR) NamesKey, NULL);
OUTPUT_MESSAGE(bQuietMode, GetFormatResource(LC_ERR_READLASTPERFLIB), lStatus);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEREGISTRY,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
lStatus,
TRACE_WSTR(NamesKey),
TRACE_WSTR(LastHelp),
NULL));
goto UpdateRegExit;
}
// get "Base Index" value now
dwType = 0;
dwPerflibBaseIndex = 0;
dwSize = sizeof(dwPerflibBaseIndex);
__try {
lStatus = RegQueryValueExW(hPerflib,
BaseIndex,
RESERVED,
& dwType,
(LPBYTE) & dwPerflibBaseIndex,
& dwSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lStatus = GetExceptionCode();
}
if (lStatus != ERROR_SUCCESS) {
// this request should always succeed, if not then worse things
// will happen later on, so quit now and avoid the trouble.
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_UNABLE_QUERY_VALUE, // event,
2, lStatus, __LINE__, 0, 0,
2, (LPWSTR) BaseIndex, (LPWSTR) NamesKey, NULL);
OUTPUT_MESSAGE(bQuietMode, GetFormatResource (LC_ERR_READLASTPERFLIB), lStatus);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEREGISTRY,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
lStatus,
TRACE_WSTR(NamesKey),
TRACE_WSTR(BaseIndex),
NULL));
goto UpdateRegExit;
}
// see if this driver's counter names have already been installed
// by checking to see if LastCounter's value is less than Perflib's
// Last Counter
dwType = 0;
dwLastDriverCounter = 0;
dwSize = sizeof(dwLastDriverCounter);
__try {
lStatus = RegQueryValueExW(hDriverPerf,
LastCounter,
RESERVED,
& dwType,
(LPBYTE) & dwLastDriverCounter,
& dwSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lStatus = GetExceptionCode();
}
if (lStatus == ERROR_SUCCESS) {
// if key found, then compare with perflib value and exit this
// procedure if the driver's last counter is <= to perflib's last
//
// if key not found, then continue with installation
// on the assumption that the counters have not been installed
if (dwLastDriverCounter <= dwLastPerflibCounter) {
OUTPUT_MESSAGE(bQuietMode, GetFormatResource(LC_ERR_ALREADY_IN), lpDriverName);
lStatus = ERROR_ALREADY_EXISTS;
goto UpdateRegExit;
}
}
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEREGISTRY,
ARG_DEF(ARG_TYPE_WSTR, 1),
lStatus,
TRACE_WSTR(lpDriverName),
TRACE_DWORD(dwLastPerflibCounter),
TRACE_DWORD(dwLastPerflibHelp),
TRACE_DWORD(dwPerflibBaseIndex),
NULL));
// set the "busy" indicator under the PERFLIB key
dwSize = (lstrlenW(lpDriverName) + 1) * sizeof(WCHAR);
__try {
lStatus = RegSetValueExW(hPerflib,
Busy,
RESERVED,
REG_SZ,
(LPBYTE) lpDriverName,
dwSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lStatus = GetExceptionCode();
}
if (lStatus != ERROR_SUCCESS) {
OUTPUT_MESSAGE(bQuietMode, GetFormatResource (LC_ERR_UNABLESETBUSY), lStatus);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEREGISTRY,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
lStatus,
TRACE_WSTR(NamesKey),
TRACE_WSTR(Busy),
NULL));
goto UpdateRegExit;
}
dwLastCounter = dwLastPerflibCounter;
dwLastHelp = dwLastPerflibHelp;
// get the list of installed languages on this machine
bStatus = GetInstalledLanguageList(hPerflib, & mszLangList);
if (! bStatus) {
OUTPUT_MESSAGE(bQuietMode, GetFormatResource(LC_ERR_UPDATELANG), GetLastError());
lStatus = GetLastError();
goto UpdateRegExit;
}
bStatus = UpdateEachLanguage(bQuietMode,
hPerflib,
mszLangList,
& dwLastCounter,
& dwLastHelp,
pFirstLang,
dwMode,
FALSE);
if (! bStatus) {
OUTPUT_MESSAGE(bQuietMode, GetFormatResource(LC_ERR_UPDATELANG), GetLastError());
lStatus = GetLastError();
goto UpdateRegExit;
}
// increment (by 2) the last counters so they point to the first
// unused index after the existing names and then
// set the first driver counters
bStatus = FALSE;
dwFirstDriverCounter = dwLastCounter + 2;
dwFirstDriverHelp = dwLastHelp + 2;
if (dwFirstDriverHelp != dwFirstDriverCounter + 1) {
TRACE((WINPERF_DBG_TRACE_WARNING),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEREGISTRY,
ARG_DEF(ARG_TYPE_WSTR, 1),
lStatus,
TRACE_WSTR(lpDriverName),
TRACE_DWORD(dwPerflibBaseIndex),
TRACE_DWORD(dwFirstDriverCounter),
TRACE_DWORD(dwFirstDriverHelp),
NULL));
dwFirstDriverHelp = dwFirstDriverCounter + 1;
}
if ((dwPerflibBaseIndex < PERFLIB_BASE_INDEX)
|| (dwFirstDriverCounter < dwPerflibBaseIndex)
|| (dwFirstDriverHelp < dwPerflibBaseIndex)) {
// potential CounterIndex/HelpIndex overlap with Base counters,
//
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_REGISTRY_BASEINDEX_CORRUPT, // event,
4, dwPerflibBaseIndex, dwFirstDriverCounter, dwFirstDriverHelp, __LINE__,
1, lpDriverName, NULL, NULL);
lStatus = ERROR_BADKEY;
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEREGISTRY,
ARG_DEF(ARG_TYPE_WSTR, 1),
lStatus,
TRACE_WSTR(lpDriverName),
TRACE_DWORD(dwPerflibBaseIndex),
TRACE_DWORD(dwFirstDriverCounter),
TRACE_DWORD(dwFirstDriverHelp),
NULL));
goto UpdateRegExit;
}
// load .INI file definitions into language tables
if (dwMode & LODCTR_UPNF_NOINI) {
PLANGUAGE_LIST_ELEMENT pThisLang = NULL;
PLANG_ENTRY pLangEntry = NULL;
PLANG_ENTRY p009LangEntry = NULL;
DWORD dwErrorCount = 0;
DWORD dwIndex;
DWORD dwNewIndex;
for (pThisLang = pFirstLang; pThisLang != NULL; pThisLang = pThisLang->pNextLang) {
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LOADLANGUAGELISTS,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
ERROR_SUCCESS,
TRACE_WSTR(lpDriverName),
TRACE_WSTR(pThisLang->LangId),
TRACE_DWORD(dwFirstDriverCounter),
TRACE_DWORD(dwFirstDriverHelp),
NULL));
for (pLangEntry = pLanguages; pLangEntry != NULL; pLangEntry = pLangEntry->pNext) {
if (lstrcmpiW(pThisLang->LangId, pLangEntry->szLang) == 0) {
break;
}
else if (lstrcmpiW(pLangEntry->szLang, DefaultLangId) == 0) {
p009LangEntry = pLangEntry;
}
}
if (pLangEntry == NULL) {
pLangEntry = p009LangEntry;
}
else if (pLangEntry->lpText == NULL) {
// no text for selected language, use 009 ones.
//
pLangEntry = p009LangEntry;
}
if (pLangEntry == NULL) {
dwErrorCount ++;
continue;
}
else if (pLangEntry->lpText == NULL) {
dwErrorCount ++;
continue;
}
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LOADLANGUAGELISTS,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
ERROR_SUCCESS,
TRACE_WSTR(lpDriverName),
TRACE_WSTR(pLangEntry->szLang),
TRACE_DWORD(pService->dwFirstCounter),
TRACE_DWORD(pService->dwFirstHelp),
TRACE_DWORD(pService->dwLastCounter),
TRACE_DWORD(pService->dwLastHelp),
TRACE_DWORD(pLangEntry->dwLastCounter),
TRACE_DWORD(pLangEntry->dwLastHelp),
NULL));
for (dwIndex = pService->dwFirstCounter; dwIndex <= pService->dwLastHelp; dwIndex ++) {
if (dwIndex > pLangEntry->dwLastHelp) {
dwErrorCount ++;
break;
}
dwNewIndex = dwIndex + dwFirstDriverCounter
- pService->dwFirstCounter;
dwType = (((dwIndex - pService->dwFirstCounter) % 2) == 0)
? (TYPE_NAME) : (TYPE_HELP);
if (pLangEntry->lpText[dwIndex] != NULL) {
__try {
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LOADLANGUAGELISTS,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2) | ARG_DEF(ARG_TYPE_WSTR, 3),
ERROR_SUCCESS,
TRACE_WSTR(lpDriverName),
TRACE_WSTR(pThisLang->LangId),
TRACE_WSTR(pLangEntry->lpText[dwIndex]),
TRACE_DWORD(dwIndex),
TRACE_DWORD(dwNewIndex),
TRACE_DWORD(dwType),
NULL));
bStatus = AddEntryToLanguage(pThisLang,
NULL,
pLangEntry->lpText[dwIndex],
0,
NULL,
0,
dwType,
dwNewIndex,
0);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lStatus = GetExceptionCode();
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEREGISTRY,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
lStatus,
TRACE_WSTR(lpDriverName),
TRACE_WSTR(pThisLang->LangId),
TRACE_DWORD(dwType),
TRACE_DWORD(dwIndex),
TRACE_DWORD(dwNewIndex),
NULL));
bStatus = FALSE;
SetLastError(lStatus);
}
if (! bStatus) {
OUTPUT_MESSAGE(bQuietMode,
GetFormatResource(LC_ERRADDTOLANG),
pLangEntry->lpText[dwIndex],
pThisLang->LangId,
GetLastError());
lStatus = GetLastError();
dwErrorCount ++;
}
}
else {
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LOADLANGUAGELISTS,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
ERROR_SUCCESS,
TRACE_WSTR(lpDriverName),
TRACE_WSTR(pThisLang->LangId),
TRACE_DWORD(dwIndex),
TRACE_DWORD(dwNewIndex),
TRACE_DWORD(dwType),
NULL));
}
}
}
bStatus = (dwErrorCount == 0) ? (TRUE) : (FALSE);
if (! bStatus) {
goto UpdateRegExit;
}
}
else {
bStatus = LoadLanguageLists(bQuietMode,
lpIniFile,
lpDriverName,
dwMode,
dwFirstDriverCounter,
dwFirstDriverHelp,
pFirstSymbol,
pFirstLang);
if (! bStatus) {
// error message is displayed by LoadLanguageLists so just abort
// error is in GetLastError already
lStatus = GetLastError();
goto UpdateRegExit;
}
}
if (dwMode & LODCTR_UPNF_NOINI) {
WCHAR szDigits[32];
DWORD dwObjectId;
for (dwObjectId = 0; dwObjectId < pService->dwNumObjects; dwObjectId ++) {
ZeroMemory(szDigits, sizeof(WCHAR) * 32);
_ultow((dwFirstDriverCounter + pService->dwObjects[dwObjectId]), szDigits,
10);
if (dwObjectId > 0) {
hr = StringCchCatW(lpszObjectList, dwObjectList, BlankString);
hr = StringCchCatW(lpszObjectList, dwObjectList, szDigits);
}
else {
hr = StringCchCopyW(lpszObjectList, dwObjectList, szDigits);
}
}
}
else {
bStatus = CreateObjectList(lp009IniFile,
dwFirstDriverCounter,
pFirstSymbol,
lpszObjectList,
dwObjectList,
pdwObjectGuidTableSize);
if (! bStatus) {
// error message is displayed by CreateObjectList so just abort
// error is in GetLastError already
lStatus = GetLastError();
goto UpdateRegExit;
}
}
// all the symbols and definitions have been loaded into internal
// tables. so now they need to be sorted and merged into a multiSZ string
// this routine also updates the "last" counters
bStatus = SortLanguageTables(pFirstLang, & dwLastCounter, & dwLastHelp);
if (! bStatus) {
OUTPUT_MESSAGE(bQuietMode, GetFormatResource(LC_UNABLESORTTABLES), GetLastError());
lStatus = GetLastError();
goto UpdateRegExit;
}
if (dwLastCounter < dwLastPerflibCounter || dwLastHelp < dwLastPerflibHelp) {
// potential CounterIndex/HelpIndex overlap with Base counters,
//
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_REGISTRY_BASEINDEX_CORRUPT, // event,
4, dwLastPerflibCounter, dwLastCounter, dwLastHelp, __LINE__,
1 , lpDriverName, NULL, NULL);
bStatus = FALSE;
lStatus = ERROR_BADKEY;
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEREGISTRY,
ARG_DEF(ARG_TYPE_WSTR, 1),
lStatus,
TRACE_WSTR(lpDriverName),
TRACE_DWORD(dwLastPerflibCounter),
TRACE_DWORD(dwLastPerflibHelp),
TRACE_DWORD(dwLastCounter),
TRACE_DWORD(dwLastHelp),
NULL));
goto UpdateRegExit;
}
bStatus = UpdateEachLanguage(bQuietMode,
hPerflib,
mszLangList,
& dwLastCounter,
& dwLastHelp,
pFirstLang,
dwMode,
TRUE);
if (! bStatus) {
OUTPUT_MESSAGE(bQuietMode, GetFormatResource(LC_ERR_UPDATELANG), GetLastError());
lStatus = GetLastError();
goto UpdateRegExit;
}
bStatus = FALSE;
dwLastPerflibCounter = dwLastCounter;
dwLastPerflibHelp = dwLastHelp;
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEREGISTRY,
ARG_DEF(ARG_TYPE_WSTR, 1),
lStatus,
TRACE_WSTR(lpDriverName),
TRACE_DWORD(dwFirstDriverCounter),
TRACE_DWORD(dwFirstDriverHelp),
TRACE_DWORD(dwLastPerflibCounter),
TRACE_DWORD(dwLastPerflibHelp),
NULL));
if (dwLastCounter < dwFirstDriverCounter) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_CORRUPT_INDEX_RANGE, // event,
3, dwFirstDriverCounter, dwLastCounter, __LINE__, 0,
2, (LPWSTR) Counters, (LPWSTR) lpDriverKeyPath, NULL);
lStatus = ERROR_BADKEY;
goto UpdateRegExit;
}
if (dwLastHelp < dwFirstDriverHelp) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_CORRUPT_INDEX_RANGE, // event,
3, dwFirstDriverHelp, dwLastHelp, __LINE__, 0,
2, (LPWSTR) Help, (LPWSTR) lpDriverKeyPath, NULL);
lStatus = ERROR_BADKEY;
goto UpdateRegExit;
}
// update last counters for driver and perflib
// perflib...
__try {
lStatus = RegSetValueExW(hPerflib,
LastCounter,
RESERVED,
REG_DWORD,
(LPBYTE) & dwLastPerflibCounter,
sizeof(DWORD));
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lStatus = GetExceptionCode();
}
if (lStatus != ERROR_SUCCESS) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_UNABLE_UPDATE_VALUE, // event,
3, lStatus, dwLastPerflibCounter, __LINE__, 0,
2, (LPWSTR) LastCounter, (LPWSTR) NamesKey, NULL);
OUTPUT_MESSAGE(bQuietMode, GetFormatResource (LC_UNABLESETVALUE), LastCounter, szPerflib);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEREGISTRY,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
lStatus,
TRACE_WSTR(NamesKey),
TRACE_WSTR(LastCounter),
TRACE_DWORD(dwLastPerflibCounter),
NULL));
}
__try {
lStatus = RegSetValueExW(hPerflib,
LastHelp,
RESERVED,
REG_DWORD,
(LPBYTE) & dwLastPerflibHelp,
sizeof(DWORD));
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lStatus = GetExceptionCode();
}
if (lStatus != ERROR_SUCCESS) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_UNABLE_UPDATE_VALUE, // event,
3, lStatus, dwLastPerflibHelp, __LINE__, 0,
2, (LPWSTR) LastHelp, (LPWSTR) NamesKey, NULL);
OUTPUT_MESSAGE(bQuietMode, GetFormatResource (LC_UNABLESETVALUE), LastHelp, szPerflib);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEREGISTRY,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
lStatus,
TRACE_WSTR(NamesKey),
TRACE_WSTR(LastHelp),
TRACE_DWORD(dwLastPerflibHelp),
NULL));
}
// and the driver
__try {
lStatus = RegSetValueExW(hDriverPerf,
LastCounter,
RESERVED,
REG_DWORD,
(LPBYTE) & dwLastPerflibCounter,
sizeof(DWORD));
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lStatus = GetExceptionCode();
}
if (lStatus != ERROR_SUCCESS) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_UNABLE_UPDATE_VALUE, // event,
3, lStatus, dwLastPerflibCounter, __LINE__, 0,
2, (LPWSTR) LastCounter, (LPWSTR) lpDriverKeyPath, NULL);
OUTPUT_MESSAGE(bQuietMode, GetFormatResource(LC_UNABLESETVALUE), LastCounter, lpDriverName);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEREGISTRY,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
lStatus,
TRACE_WSTR(lpDriverName),
TRACE_WSTR(LastCounter),
TRACE_DWORD(dwLastPerflibCounter),
NULL));
}
__try {
lStatus = RegSetValueExW(hDriverPerf,
LastHelp,
RESERVED,
REG_DWORD,
(LPBYTE) & dwLastPerflibHelp,
sizeof(DWORD));
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lStatus = GetExceptionCode();
}
if (lStatus != ERROR_SUCCESS) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_UNABLE_UPDATE_VALUE, // event,
3, lStatus, dwLastPerflibHelp, __LINE__, 0,
2, (LPWSTR) LastHelp, (LPWSTR) lpDriverKeyPath, NULL);
OUTPUT_MESSAGE(bQuietMode, GetFormatResource(LC_UNABLESETVALUE), LastHelp, lpDriverName);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEREGISTRY,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
lStatus,
TRACE_WSTR(lpDriverName),
TRACE_WSTR(LastHelp),
TRACE_DWORD(dwLastPerflibHelp),
NULL));
}
__try {
lStatus = RegSetValueExW(hDriverPerf,
FirstCounter,
RESERVED,
REG_DWORD,
(LPBYTE) & dwFirstDriverCounter,
sizeof(DWORD));
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lStatus = GetExceptionCode();
}
if (lStatus != ERROR_SUCCESS) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_UNABLE_UPDATE_VALUE, // event,
3, lStatus, dwFirstDriverCounter, __LINE__, 0,
2, (LPWSTR) FirstCounter, (LPWSTR) lpDriverKeyPath, NULL);
OUTPUT_MESSAGE(bQuietMode, GetFormatResource(LC_UNABLESETVALUE), FirstCounter, lpDriverName);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEREGISTRY,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
lStatus,
TRACE_WSTR(lpDriverName),
TRACE_WSTR(FirstCounter),
TRACE_DWORD(dwFirstDriverCounter),
NULL));
}
__try {
lStatus = RegSetValueExW(hDriverPerf,
FirstHelp,
RESERVED,
REG_DWORD,
(LPBYTE) & dwFirstDriverHelp,
sizeof(DWORD));
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lStatus = GetExceptionCode();
}
if (lStatus != ERROR_SUCCESS) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_UNABLE_UPDATE_VALUE, // event,
3, lStatus, dwFirstDriverHelp, __LINE__, 0,
2, (LPWSTR) FirstHelp, (LPWSTR) lpDriverKeyPath, NULL);
OUTPUT_MESSAGE(bQuietMode, GetFormatResource(LC_UNABLESETVALUE), FirstHelp, lpDriverName);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEREGISTRY,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
lStatus,
TRACE_WSTR(lpDriverName),
TRACE_WSTR(FirstHelp),
TRACE_DWORD(dwFirstDriverHelp),
NULL));
}
if (*lpszObjectList != L'\0') {
__try {
lStatus = RegSetValueExW(hDriverPerf,
szObjectList,
RESERVED,
REG_SZ,
(LPBYTE) lpszObjectList,
(lstrlenW(lpszObjectList) + 1) * sizeof (WCHAR));
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lStatus = GetExceptionCode();
}
if (lStatus != ERROR_SUCCESS) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_UNABLE_UPDATE_VALUE, // event,
2, lStatus, __LINE__, 0, 0,
2, (LPWSTR) szObjectList, (LPWSTR) lpDriverKeyPath, NULL);
OUTPUT_MESSAGE(bQuietMode, GetFormatResource(LC_UNABLESETVALUE), szObjectList, lpDriverName);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEREGISTRY,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
lStatus,
TRACE_WSTR(lpDriverName),
TRACE_WSTR(szObjectList),
NULL));
}
}
bStatus = TRUE;
pdwIndexValues[0] = dwFirstDriverCounter; // first Counter
pdwIndexValues[1] = dwLastPerflibCounter; // last Counter
pdwIndexValues[2] = dwFirstDriverHelp; // first Help
pdwIndexValues[3] = dwLastPerflibHelp; // last Help
// remove "DisablePerformanceCounter" value so perf counters are re-enabled.
lStatus = RegDeleteValueW(hDriverPerf, DisablePerformanceCounters);
UpdateRegExit:
if (hPerflib != NULL && hPerflib != INVALID_HANDLE_VALUE) {
DWORD lTmpStatus = ERROR_SUCCESS;
__try {
lTmpStatus = RegDeleteValueW(hPerflib, Busy);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
lTmpStatus = GetExceptionCode();
}
if (lTmpStatus != ERROR_SUCCESS) {
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEREGISTRY,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
lTmpStatus,
TRACE_WSTR(lpDriverName),
TRACE_WSTR(Busy),
NULL));
}
}
// MemoryFree temporary buffers
// free any guid string buffers here
// TODO: add this code
MemoryFree(lpDriverKeyPath);
MemoryFree(lpszObjectList);
MemoryFree(mszLangList);
if (hDriverPerf != NULL && hDriverPerf != INVALID_HANDLE_VALUE) RegCloseKey(hDriverPerf);
if (hPerflib != NULL && hPerflib != INVALID_HANDLE_VALUE) RegCloseKey(hPerflib);
if (hKeyMachine != NULL && hKeyMachine != HKEY_LOCAL_MACHINE) RegCloseKey(hKeyMachine);
if (! bStatus) SetLastError(lStatus);
return bStatus;
}
DWORD
LoadPerfInstallPerfDll(
DWORD dwMode,
LPCWSTR szComputerName,
LPWSTR lpDriverName,
LPCWSTR lpIniFile,
PLANG_ENTRY pLanguages,
PSERVICE_ENTRY pService,
ULONG_PTR dwFlags
)
{
LPWSTR lp009IniFile = NULL;
LPWSTR lpInfPath = NULL;
DWORD dwObjectGuidTableSize = 0;
DWORD dwObjectIndex;
PLANGUAGE_LIST_ELEMENT LangList = NULL;
PLANGUAGE_LIST_ELEMENT pThisElem = NULL;
PSYMBOL_TABLE_ENTRY SymbolTable = NULL;
DWORD ErrorCode = ERROR_SUCCESS;
DWORD dwIndexValues[4] = {0,0,0,0};
HKEY hKeyMachine = HKEY_LOCAL_MACHINE;
HKEY hKeyDriver = NULL;
BOOL bResult = TRUE;
BOOL bQuietMode = (BOOL) ((dwFlags & LOADPERF_FLAGS_DISPLAY_USER_MSGS) == 0);
LPWSTR szServiceName = NULL;
LPWSTR szServiceDisplayName = NULL;
DWORD dwSize;
HRESULT hr;
if (lpDriverName == NULL) {
ErrorCode = ERROR_BAD_DRIVER;
goto EndOfMain;
}
else if (* lpDriverName == L'\0') {
ErrorCode = ERROR_BAD_DRIVER;
goto EndOfMain;
}
else if (dwMode & LODCTR_UPNF_NOINI) {
if (pLanguages == NULL || pService == NULL) {
ErrorCode = ERROR_INVALID_PARAMETER;
goto EndOfMain;
}
}
else if (dwMode & LODCTR_UPNF_NOBACKUP) {
if (lpIniFile == NULL) {
ErrorCode = ERROR_INVALID_PARAMETER;
goto EndOfMain;
}
else if (* lpIniFile == L'\0') {
ErrorCode = ERROR_INVALID_PARAMETER;
goto EndOfMain;
}
else {
lp009IniFile = MemoryAllocate((lstrlenW(lpIniFile) + 1) * sizeof(WCHAR));
if (lp009IniFile == NULL) {
ErrorCode = ERROR_OUTOFMEMORY;
goto EndOfMain;
}
hr = StringCchCopyW(lp009IniFile, lstrlenW(lpIniFile) + 1, lpIniFile);
}
}
else if (lpIniFile != NULL && lpIniFile[0] != L'\0') {
lpInfPath = LoadPerfGetInfPath();
if (lpInfPath == NULL) {
ErrorCode = GetLastError();
goto EndOfMain;
}
dwSize = lstrlenW(lpInfPath) + lstrlenW(DefaultLangId) + lstrlenW(Slash)
+ lstrlenW(lpDriverName) + lstrlenW(Slash) + lstrlenW(lpIniFile) + 1;
if (dwSize < MAX_PATH) dwSize = MAX_PATH;
lp009IniFile = MemoryAllocate(dwSize * sizeof(WCHAR));
if (lp009IniFile == NULL) {
ErrorCode = ERROR_OUTOFMEMORY;
goto EndOfMain;
}
hr = StringCchPrintfW(lp009IniFile, dwSize, L"%ws%ws%ws%ws%ws%ws",
lpInfPath, DefaultLangId, Slash, lpDriverName, Slash, lpIniFile);
}
else { // lpIniFile == NULL
OUTPUT_MESSAGE(bQuietMode, GetFormatResource(LC_NO_INIFILE), lpIniFile);
ErrorCode = ERROR_OPEN_FAILED;
goto EndOfMain;
}
//
// Set the table size to the max first after we have passed the above
//
dwObjectGuidTableSize = MAX_GUID_TABLE_SIZE;
hKeyMachine = HKEY_LOCAL_MACHINE;
dwSize = lstrlenW(DriverPathRoot) + lstrlenW(Slash) + lstrlenW(lpDriverName) + 1;
if (dwSize < MAX_PATH) dwSize = MAX_PATH;
szServiceName = MemoryAllocate(2 * dwSize * sizeof(WCHAR));
if (szServiceName == NULL) {
ErrorCode = ERROR_OUTOFMEMORY;
goto EndOfMain;
}
szServiceDisplayName = szServiceName + dwSize;
hr = StringCchPrintfW(szServiceName, dwSize, L"%ws%ws%ws", DriverPathRoot, Slash, lpDriverName);
ErrorCode = RegOpenKeyExW(hKeyMachine, szServiceName, RESERVED, KEY_READ | KEY_WRITE, & hKeyDriver);
if (ErrorCode == ERROR_SUCCESS) {
DWORD dwType = 0;
DWORD dwBufferSize = dwSize * sizeof(WCHAR);
__try {
ErrorCode = RegQueryValueExW(hKeyDriver,
szDisplayName,
RESERVED,
& dwType,
(LPBYTE) szServiceDisplayName,
& dwBufferSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
ErrorCode = GetExceptionCode();
}
}
if (ErrorCode != ERROR_SUCCESS) {
hr = StringCchCopyW(szServiceDisplayName, dwSize, lpDriverName);
}
if ((! (dwMode & LODCTR_UPNF_REPAIR)) && (hKeyDriver != NULL)) {
HKEY hKeyDriverPerf = NULL;
__try {
ErrorCode = RegOpenKeyExW(hKeyDriver, Performance, RESERVED, KEY_READ | KEY_WRITE, & hKeyDriverPerf);
}
__except(EXCEPTION_EXECUTE_HANDLER) {
ErrorCode = GetExceptionCode();
}
if (ErrorCode == ERROR_SUCCESS) {
LPWSTR szIniName = (LPWSTR) lpIniFile;
if (dwMode & LODCTR_UPNF_NOBACKUP) {
for (szIniName = (LPWSTR) lpIniFile + lstrlenW(lpIniFile) - 1;
szIniName != NULL && szIniName != lpIniFile
&& (* szIniName) != cNull
&& (* szIniName) != cBackslash;
szIniName --);
if (szIniName != NULL && (* szIniName) == cBackslash) {
szIniName ++;
}
else {
szIniName = (LPWSTR) lpIniFile;
}
}
__try {
ErrorCode = RegSetValueExW(hKeyDriverPerf,
szPerfIniPath,
RESERVED,
REG_SZ,
(LPBYTE) szIniName,
sizeof(WCHAR) * lstrlenW(lpIniFile));
}
__except(EXCEPTION_EXECUTE_HANDLER) {
ErrorCode = GetExceptionCode();
}
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_INSTALLPERFDLL,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2)
| ARG_DEF(ARG_TYPE_WSTR, 3),
ErrorCode,
TRACE_WSTR(lpIniFile),
TRACE_WSTR(lp009IniFile),
TRACE_WSTR(szIniName),
NULL));
RegCloseKey(hKeyDriverPerf);
}
}
if (hKeyDriver != NULL && hKeyDriver != HKEY_LOCAL_MACHINE) {
RegCloseKey(hKeyDriver);
}
if (hKeyMachine != NULL && hKeyMachine != HKEY_LOCAL_MACHINE) {
RegCloseKey(hKeyMachine);
}
ErrorCode = ERROR_SUCCESS;
if (dwMode & LODCTR_UPNF_NOINI) {
PLANG_ENTRY pThisLang = pLanguages;
while (pThisLang != NULL) {
// This is to build LangList. UpdateRegistry() takes LangList as a parameter and uses it.
// Memory will be freed at the end of LoadPerfInstallPerfDll().
//
pThisElem = MemoryAllocate(sizeof(LANGUAGE_LIST_ELEMENT)
+ sizeof(WCHAR) * (lstrlenW(pThisLang->szLang) + 1));
if (pThisElem == NULL) {
ErrorCode = ERROR_OUTOFMEMORY;
goto EndOfMain;
}
pThisElem->pNextLang = LangList;
LangList = pThisElem;
pThisElem->LangId = (LPWSTR)
(((LPBYTE) pThisElem) + sizeof(LANGUAGE_LIST_ELEMENT));
hr = StringCchCopyW(pThisElem->LangId, lstrlenW(pThisLang->szLang) + 1, pThisLang->szLang);
pThisElem->dwLangId = LoadPerfGetLCIDFromString(pThisElem->LangId);
pThisElem->pFirstName = NULL;
pThisElem->pThisName = NULL;
pThisElem->dwNumElements = 0;
pThisElem->NameBuffer = NULL;
pThisElem->HelpBuffer = NULL;
pThisElem->dwNameBuffSize = 0;
pThisElem->dwHelpBuffSize = 0;
pThisLang = pThisLang->pNext;
}
}
else {
bResult = BuildLanguageTables(dwMode, (LPWSTR) lpIniFile, lpDriverName, & LangList);
dwSize = bResult ? 1 : 0;
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_INSTALLPERFDLL,
ARG_DEF(ARG_TYPE_WSTR, 1),
GetLastError(),
TRACE_WSTR(lpIniFile),
TRACE_DWORD(dwSize),
NULL));
if (! bResult) {
OUTPUT_MESSAGE(bQuietMode, GetFormatResource(LC_LANGLIST_ERR), lpIniFile);
ErrorCode = GetLastError();
goto EndOfMain;
}
bResult = LoadIncludeFile(bQuietMode, dwMode, (LPWSTR) lp009IniFile, lpDriverName, & SymbolTable);
dwSize = bResult ? 1 : 0;
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_INSTALLPERFDLL,
ARG_DEF(ARG_TYPE_WSTR, 1),
GetLastError(),
TRACE_WSTR(lp009IniFile),
TRACE_DWORD(dwSize),
NULL));
if (! bResult) {
// open errors displayed in routine
ErrorCode = GetLastError();
goto EndOfMain;
}
}
if (LangList != NULL) {
bResult = UpdateRegistry(bQuietMode,
dwMode,
lpDriverName,
(LPWSTR) lpIniFile,
lp009IniFile,
pLanguages,
pService,
LangList,
SymbolTable,
& dwObjectGuidTableSize,
(LPDWORD) dwIndexValues);
dwSize = bResult ? 1 : 0;
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_LOADINCLUDEFILE,
ARG_DEF(ARG_TYPE_WSTR, 1),
GetLastError(),
TRACE_WSTR(lpIniFile),
TRACE_DWORD(dwSize),
NULL));
if (! bResult) {
ErrorCode = GetLastError();
goto EndOfMain;
}
}
else {
bResult = FALSE;
ErrorCode = ERROR_INVALID_DATA;
goto EndOfMain;
}
LodctrSetSericeAsTrusted(lp009IniFile, NULL, lpDriverName);
// signal WMI with this change, ignore WMI return error.
LoadPerfSignalWmiWithNewData (WMI_LODCTR_EVENT);
EndOfMain:
if ((dwMode & LODCTR_UPNF_REPAIR) == 0) {
if (ErrorCode != ERROR_SUCCESS) {
if (ErrorCode == ERROR_ALREADY_EXISTS) {
ReportLoadPerfEvent(
EVENTLOG_INFORMATION_TYPE, // error type
(DWORD) LDPRFMSG_ALREADY_EXIST, // event,
1, __LINE__, 0, 0, 0,
2, (LPWSTR) lpDriverName, (LPWSTR) szServiceDisplayName, NULL);
ErrorCode = ERROR_SUCCESS;
}
else if (lpDriverName != NULL) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_LOAD_FAILURE, // event,
2, ErrorCode, __LINE__, 0, 0,
2, (LPWSTR) lpDriverName, (szServiceDisplayName != NULL) ? (szServiceDisplayName) : (lpDriverName), NULL);
}
else if (lpIniFile != NULL) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_LOAD_FAILURE, // event,
2, ErrorCode, __LINE__, 0, 0,
2, (LPWSTR) lpIniFile, (LPWSTR) lpIniFile, NULL);
}
else {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_LOAD_FAILURE, // event,
2, ErrorCode, __LINE__, 0, 0,
0, NULL, NULL, NULL);
}
}
else {
// log success message
ReportLoadPerfEvent(
EVENTLOG_INFORMATION_TYPE, // error type
(DWORD) LDPRFMSG_LOAD_SUCCESS, // event,
4, dwIndexValues[0], dwIndexValues[1], dwIndexValues[2], dwIndexValues[3],
2, (LPWSTR) lpDriverName, (LPWSTR) szServiceDisplayName, NULL);
}
}
else if (ErrorCode != ERROR_SUCCESS) {
ReportLoadPerfEvent(
EVENTLOG_ERROR_TYPE, // error type
(DWORD) LDPRFMSG_LOAD_FAILURE, // event,
2, ErrorCode, __LINE__, 0, 0,
1, (LPWSTR) lpDriverName, (szServiceDisplayName != NULL) ? (szServiceDisplayName) : (lpDriverName), NULL);
}
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_INSTALLPERFDLL,
ARG_DEF(ARG_TYPE_WSTR, 1),
ErrorCode,
TRACE_WSTR(lpDriverName),
NULL));
while (LangList != NULL) {
PLANGUAGE_LIST_ELEMENT pTmpLang = LangList;
PNAME_ENTRY pThisName = pTmpLang->pFirstName;
while (pThisName != NULL) {
PNAME_ENTRY pTmpName = pThisName;
pThisName = pTmpName->pNext;
MemoryFree(pTmpName);
}
MemoryFree(pTmpLang->NameBuffer);
MemoryFree(pTmpLang->HelpBuffer);
LangList = LangList->pNextLang;
MemoryFree(pTmpLang);
}
while (SymbolTable != NULL) {
PSYMBOL_TABLE_ENTRY pThisSym = SymbolTable;
SymbolTable = pThisSym->pNext;
MemoryFree(pThisSym->SymbolName);
MemoryFree(pThisSym);
}
MemoryFree(lp009IniFile);
MemoryFree(szServiceName);
return (ErrorCode);
}
LOADPERF_FUNCTION
InstallPerfDllW(
IN LPCWSTR szComputerName,
IN LPCWSTR lpIniFile,
IN ULONG_PTR dwFlags
)
{
DWORD lStatus = ERROR_SUCCESS;
LPWSTR szIniName = NULL;
LPWSTR szDriverName = NULL;
DWORD dwMode = 0;
DBG_UNREFERENCED_PARAMETER(szComputerName);
WinPerfStartTrace(NULL);
if (LoadPerfGrabMutex() == FALSE) {
return GetLastError();
}
if (lpIniFile == NULL) {
lStatus = ERROR_INVALID_PARAMETER;
}
else {
__try {
DWORD dwName = lstrlenW(lpIniFile);
if (dwName == 0) lStatus = ERROR_INVALID_PARAMETER;
}
__except(EXCEPTION_EXECUTE_HANDLER) {
lStatus = ERROR_INVALID_PARAMETER;
}
}
if (lStatus == ERROR_SUCCESS) {
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_INSTALLPERFDLL,
ARG_DEF(ARG_TYPE_WSTR, 1),
ERROR_SUCCESS,
TRACE_WSTR(lpIniFile),
NULL));
#if 0
if (LoadPerfBackupIniFile(lpIniFile, NULL, & szIniName, & szDriverName, TRUE) == FALSE) {
dwMode |= LODCTR_UPNF_NOBACKUP;
MemoryFree(szIniName);
szIniName = (LPWSTR) lpIniFile;
}
#else
// ignore LoadPerfBackupIniFile return code and use input .INI and .H files instead.
//
LoadPerfBackupIniFile(lpIniFile, NULL, & szIniName, & szDriverName, TRUE);
dwMode |= LODCTR_UPNF_NOBACKUP;
MemoryFree(szIniName);
szIniName = (LPWSTR) lpIniFile;
#endif
// Ignore szComputerName parameter. LOADPERF can only update local performance registry.
// No remote installation support.
//
lStatus = LoadPerfInstallPerfDll(dwMode, NULL, szDriverName, szIniName, NULL, NULL, dwFlags);
if (szIniName != lpIniFile) MemoryFree(szIniName);
MemoryFree(szDriverName);
}
ReleaseMutex(hLoadPerfMutex);
return lStatus;
}
LOADPERF_FUNCTION
InstallPerfDllA(
IN LPCSTR szComputerName,
IN LPCSTR szIniFile,
IN ULONG_PTR dwFlags
)
{
LPWSTR lpWideFileName = NULL;
DWORD lReturn = ERROR_SUCCESS;
DBG_UNREFERENCED_PARAMETER(szComputerName);
if (szIniFile != NULL) {
__try {
lpWideFileName = LoadPerfMultiByteToWideChar(CP_ACP, (LPSTR) szIniFile);
if (lpWideFileName == NULL) {
lReturn = ERROR_OUTOFMEMORY;
}
}
__except(EXCEPTION_EXECUTE_HANDLER) {
lReturn = ERROR_INVALID_PARAMETER;
}
}
else {
lReturn = ERROR_INVALID_PARAMETER;
}
if (lReturn == ERROR_SUCCESS) {
// Ignore szComputerName parameter. LOADPERF can only update local performance registry.
// No remote installation support.
//
lReturn = InstallPerfDllW(NULL, lpWideFileName, dwFlags);
}
MemoryFree(lpWideFileName);
return lReturn;
}
LOADPERF_FUNCTION
LoadPerfCounterTextStringsW(
IN LPWSTR lpCommandLine,
IN BOOL bQuietMode
)
/*++
LoadPerfCounterTexStringsW
loads the perf counter strings into the registry and updates
the perf counter text registry values
Arguments
command line string in the following format:
"/?" displays the usage text
"file.ini" loads the perf strings found in file.ini
"\\machine file.ini" loads the perf strings found onto machine
ReturnValue
0 (ERROR_SUCCESS) if command was processed
Non-Zero if command error was detected.
--*/
{
LPWSTR lpIniFile = NULL;
DWORD ErrorCode = ERROR_SUCCESS;
ULONG_PTR dwFlags = 0;
WinPerfStartTrace(NULL);
if (lpCommandLine == NULL) {
ErrorCode = ERROR_INVALID_PARAMETER;
}
else {
__try {
DWORD dwSize = lstrlenW(lpCommandLine);
if (dwSize == 0) ErrorCode = ERROR_INVALID_PARAMETER;
}
__except(EXCEPTION_EXECUTE_HANDLER) {
ErrorCode = ERROR_INVALID_PARAMETER;
}
}
if (ErrorCode != ERROR_SUCCESS) goto Cleanup;
dwFlags |= (bQuietMode ? 0 : LOADPERF_FLAGS_DISPLAY_USER_MSGS);
lpIniFile = MemoryAllocate(MAX_PATH * sizeof(WCHAR));
if (lpIniFile == NULL) {
ErrorCode = ERROR_OUTOFMEMORY;
goto Cleanup;
}
// init last error value
SetLastError(ERROR_SUCCESS);
// read command line to determine what to do
if (GetFileFromCommandLine(lpCommandLine, & lpIniFile, MAX_PATH, & dwFlags)) {
dwFlags |= LOADPERF_FLAGS_LOAD_REGISTRY_ONLY; // don't do mof's even if they want
// call installation function
// LOADPERF can only update local performance registry. No remote installation support.
//
ErrorCode = InstallPerfDllW(NULL, lpIniFile, dwFlags);
}
else {
DWORD dwError = GetLastError();
if (dwError == ERROR_OPEN_FAILED) {
OUTPUT_MESSAGE(bQuietMode, GetFormatResource(LC_NO_INIFILE), lpIniFile);
}
else {
//Incorrect Command Format
// display command line usage
if (! bQuietMode) {
DisplayCommandHelp(LC_FIRST_CMD_HELP, LC_LAST_CMD_HELP);
}
}
ErrorCode = ERROR_INVALID_PARAMETER;
}
Cleanup:
MemoryFree(lpIniFile);
return (ErrorCode);
}
LOADPERF_FUNCTION
LoadPerfCounterTextStringsA(
IN LPSTR lpAnsiCommandLine,
IN BOOL bQuietMode
)
{
LPWSTR lpWideCommandLine = NULL;
DWORD lReturn = ERROR_SUCCESS;
if (lpAnsiCommandLine == NULL) {
lReturn = ERROR_INVALID_PARAMETER;
}
else {
__try {
DWORD dwSize = lstrlenA(lpAnsiCommandLine);
if (dwSize == 0) {
lReturn = ERROR_INVALID_PARAMETER;
}
else {
lpWideCommandLine = LoadPerfMultiByteToWideChar(CP_ACP, lpAnsiCommandLine);
if (lpWideCommandLine == NULL) lReturn = ERROR_OUTOFMEMORY;
}
}
__except(EXCEPTION_EXECUTE_HANDLER) {
lReturn = ERROR_INVALID_PARAMETER;
}
}
if (lReturn == ERROR_SUCCESS) {
lReturn = LoadPerfCounterTextStringsW(lpWideCommandLine, bQuietMode);
}
MemoryFree(lpWideCommandLine);
return lReturn;
}
LOADPERF_FUNCTION
UpdatePerfNameFilesX(
LPCWSTR szNewCtrFilePath, // data file with new base counter strings
LPCWSTR szNewHlpFilePath, // data file with new base counter strings
LPWSTR szLanguageID, // Lang ID to update
ULONG_PTR dwFlags // flags
)
{
DWORD dwReturn = ERROR_SUCCESS;
LPWSTR szCtrNameIn = NULL;
LPWSTR szHlpNameIn = NULL;
BOOL bAllocCtrString = FALSE;
LPWSTR szNewCtrStrings = NULL;
LPWSTR szNewHlpStrings = NULL;
LPWSTR szNewCtrMSZ = NULL;
LPWSTR szNewHlpMSZ = NULL;
DWORD dwLength = 0;
LPWSTR * pszNewNameTable = NULL;
LPWSTR * pszOldNameTable = NULL;
LPWSTR lpThisName;
LPWSTR szThisCtrString = NULL;
LPWSTR szThisHlpString = NULL;
LPWSTR szLangSection = NULL;
DWORD dwOldLastEntry = 0;
DWORD dwNewLastEntry = 0;
DWORD dwStringSize;
DWORD dwHlpFileSize = 0;
DWORD dwCtrFileSize = 0;
DWORD dwThisCounter;
DWORD dwSize;
DWORD dwLastBaseValue = 0;
DWORD dwType;
DWORD dwIndex;
HANDLE hCtrFileIn = INVALID_HANDLE_VALUE;
HANDLE hCtrFileMap = NULL;
HANDLE hHlpFileIn = INVALID_HANDLE_VALUE;
HANDLE hHlpFileMap = NULL;
HKEY hKeyPerflib;
HRESULT hr;
WinPerfStartTrace(NULL);
if (LoadPerfGrabMutex() == FALSE) {
return GetLastError();
}
if ((! (dwFlags & LODCTR_UPNF_RESTORE)) && (! (dwFlags & LODCTR_UPNF_REPAIR))) {
if (LoadPerfBackupIniFile(szNewCtrFilePath, szLanguageID, NULL, NULL, FALSE) == FALSE) {
dwReturn = ERROR_INVALID_PARAMETER;
}
if (LoadPerfBackupIniFile(szNewHlpFilePath, szLanguageID, NULL, NULL, FALSE) == FALSE) {
dwReturn = ERROR_INVALID_PARAMETER;
}
}
if (szNewCtrFilePath == NULL) dwReturn = ERROR_INVALID_PARAMETER;
if ((szNewHlpFilePath == NULL) && !(dwFlags & LODCTR_UPNF_RESTORE)) dwReturn = ERROR_INVALID_PARAMETER;
if (szLanguageID == NULL) dwReturn = ERROR_INVALID_PARAMETER;
if (dwReturn == ERROR_SUCCESS) {
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEPERFNAMEFILES,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
ERROR_SUCCESS,
TRACE_WSTR(szNewCtrFilePath),
TRACE_WSTR(szLanguageID),
NULL));
}
if ((dwReturn == ERROR_SUCCESS) && ! (dwFlags & LODCTR_UPNF_RESTORE)) {
if (dwFlags & LODCTR_UPNF_REPAIR) {
dwLength = lstrlenW(szNewCtrFilePath);
}
else {
// save the original files, unless it's a restoration
MakeBackupCopyOfLanguageFiles(szLanguageID);
dwLength = lstrlenW(szNewCtrFilePath);
if (dwLength > 0) dwLength = lstrlenW(szNewHlpFilePath);
}
}
else {
dwLength = 0;
SetLastError(dwReturn);
}
if (dwLength > 0) {
// create input filenames
dwSize = lstrlenW(szNewCtrFilePath) + lstrlenW(szNewHlpFilePath) + 1;
if (dwSize < MAX_PATH) dwSize = MAX_PATH;
szCtrNameIn = MemoryAllocate(dwSize * sizeof(WCHAR));
szHlpNameIn = MemoryAllocate(dwSize * sizeof(WCHAR));
if (szCtrNameIn != NULL && szHlpNameIn != NULL) {
if (! (dwFlags & LODCTR_UPNF_REPAIR)) {
DWORD dwTmp = dwSize;
dwReturn = ERROR_SUCCESS;
dwLength = ExpandEnvironmentStringsW(szNewCtrFilePath, szCtrNameIn, dwSize);
while (dwReturn == ERROR_SUCCESS && dwLength > dwSize) {
dwSize = dwLength;
MemoryFree(szCtrNameIn);
szCtrNameIn = MemoryAllocate(dwLength * sizeof(WCHAR));
if (szCtrNameIn == NULL) {
dwReturn = ERROR_OUTOFMEMORY;
}
else {
dwLength = ExpandEnvironmentStringsW(szNewCtrFilePath, szCtrNameIn, dwSize);
}
}
if (dwReturn == ERROR_SUCCESS) {
dwSize = dwTmp;
dwLength = ExpandEnvironmentStringsW(szNewHlpFilePath, szHlpNameIn, dwSize);
while (dwReturn == ERROR_SUCCESS && dwLength > dwSize) {
dwSize = dwLength;
MemoryFree(szHlpNameIn);
szHlpNameIn = MemoryAllocate(dwLength * sizeof(WCHAR));
if (szHlpNameIn == NULL) {
dwReturn = ERROR_OUTOFMEMORY;
}
else {
dwLength = ExpandEnvironmentStringsW(szNewHlpFilePath, szHlpNameIn, dwSize);
}
}
}
}
else {
hr = StringCchCopyW(szCtrNameIn, dwSize, szNewCtrFilePath);
hr = StringCchCopyW(szHlpNameIn, dwSize, szNewHlpFilePath);
}
}
else {
dwReturn = ERROR_OUTOFMEMORY;
}
if (dwReturn == ERROR_SUCCESS) {
// open and map new files
hCtrFileIn = CreateFileW(szCtrNameIn,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hCtrFileIn != INVALID_HANDLE_VALUE) {
// map file
dwCtrFileSize = GetFileSize(hCtrFileIn, NULL);
if (dwCtrFileSize == 0xFFFFFFFF){
dwReturn =GetLastError();
}
else {
hCtrFileMap = CreateFileMappingW(hCtrFileIn, NULL, PAGE_READONLY, 0, 0, NULL);
if (hCtrFileMap != NULL) {
szNewCtrStrings = (LPWSTR) MapViewOfFileEx(hCtrFileMap, FILE_MAP_READ, 0, 0, 0, NULL);
if (szNewCtrStrings == NULL) {
dwReturn = GetLastError();
}
}
else {
dwReturn = GetLastError();
}
}
}
else {
dwReturn = GetLastError();
}
}
if (dwReturn == ERROR_SUCCESS) {
// open and map new files
hHlpFileIn = CreateFileW(szHlpNameIn,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hHlpFileIn != INVALID_HANDLE_VALUE) {
// map file
dwHlpFileSize = GetFileSize(hHlpFileIn, NULL);
if (dwHlpFileSize == 0xFFFFFFFF){
dwReturn = GetLastError();
}
else {
hHlpFileMap = CreateFileMappingW(hHlpFileIn, NULL, PAGE_READONLY, 0, 0, NULL);
if (hHlpFileMap != NULL) {
szNewHlpStrings = (LPWSTR)MapViewOfFileEx(hHlpFileMap, FILE_MAP_READ, 0, 0, 0, NULL);
if (szNewHlpStrings == NULL) {
dwReturn = GetLastError();
}
}
else {
dwReturn = GetLastError();
}
}
}
else {
dwReturn = GetLastError();
}
}
}
else if (dwFlags & LODCTR_UPNF_RESTORE) {
dwSize = lstrlenW(szNewCtrFilePath) + 1;
if (dwSize < MAX_PATH) dwSize = MAX_PATH;
szCtrNameIn = MemoryAllocate(dwSize * sizeof (WCHAR));
if (szCtrNameIn != NULL) {
dwReturn = ERROR_SUCCESS;
dwLength = ExpandEnvironmentStringsW(szNewCtrFilePath, szCtrNameIn, dwSize);
while (dwReturn == ERROR_SUCCESS && dwLength > dwSize) {
dwSize = dwLength;
MemoryFree(szCtrNameIn);
szCtrNameIn = MemoryAllocate(dwLength * sizeof(WCHAR));
if (szCtrNameIn == NULL) {
dwReturn = ERROR_OUTOFMEMORY;
}
else {
dwLength = ExpandEnvironmentStringsW(szNewCtrFilePath, szCtrNameIn, dwSize);
}
}
}
if (szCtrNameIn != NULL) {
dwNewLastEntry = GetPrivateProfileIntW((LPCWSTR) L"Perflib", (LPCWSTR) L"Last Help", -1, szCtrNameIn);
if (dwNewLastEntry != (DWORD) -1) {
// get the input file size
hCtrFileIn = CreateFileW(szCtrNameIn,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hCtrFileIn != INVALID_HANDLE_VALUE) {
// map file
dwCtrFileSize = GetFileSize(hCtrFileIn, NULL);
}
else {
dwCtrFileSize = 64 * LOADPERF_BUFF_SIZE; // assign 64k if unable to read it
}
// load new values from ini file
bAllocCtrString = TRUE;
szNewCtrStrings = (LPWSTR) MemoryAllocate(dwCtrFileSize * sizeof(WCHAR));
if (szNewCtrStrings) {
dwLength = lstrlenW(szLanguageID) + 16;
szLangSection = MemoryAllocate(dwLength * sizeof(WCHAR));
if (szLangSection == NULL) {
dwReturn = ERROR_OUTOFMEMORY;
}
else {
hr = StringCchPrintfW(szLangSection, dwLength, L"Perfstrings_%ws", szLanguageID);
dwSize = GetPrivateProfileSectionW(szLangSection,
szNewCtrStrings,
dwCtrFileSize,
szCtrNameIn);
if (dwSize == 0) {
hr = StringCchCopyW(szLangSection, dwLength, (LPCWSTR) L"Perfstrings_009");
dwSize = GetPrivateProfileSectionW(szLangSection,
szNewCtrStrings,
dwCtrFileSize,
szCtrNameIn);
}
if (dwSize == 0) {
dwReturn = ERROR_FILE_INVALID;
}
else {
// set file sizes
dwHlpFileSize = 0;
dwCtrFileSize = (dwSize + 2) * sizeof(WCHAR);
}
}
}
else {
dwReturn = ERROR_OUTOFMEMORY;
}
}
else {
// unable to open input file or file is invalid
dwReturn = ERROR_FILE_INVALID;
}
}
else if (dwReturn == ERROR_SUCCESS) {
dwReturn = ERROR_OUTOFMEMORY;
}
}
if ((dwReturn == ERROR_SUCCESS) && (! (dwFlags & LODCTR_UPNF_RESTORE))) {
if (! (dwFlags & LODCTR_UPNF_REPAIR)) {
// build name table of current strings
pszOldNameTable = BuildNameTable(HKEY_LOCAL_MACHINE, szLanguageID, & dwOldLastEntry);
if (pszOldNameTable == NULL) {
dwReturn = GetLastError();
}
}
else {
dwOldLastEntry = 0;
}
dwNewLastEntry = (dwOldLastEntry == 0) ? (PERFLIB_BASE_INDEX) : (dwOldLastEntry);
}
else if (dwFlags & LODCTR_UPNF_RESTORE) {
dwOldLastEntry = dwNewLastEntry;
}
if (dwReturn == ERROR_SUCCESS) {
// build name table of new strings
pszNewNameTable = (LPWSTR *) MemoryAllocate((dwNewLastEntry + 2) * sizeof(LPWSTR));// allow for index offset
if (pszNewNameTable != NULL) {
for (lpThisName = szNewCtrStrings; * lpThisName != L'\0'; lpThisName += (lstrlenW(lpThisName) + 1)) {
// first string should be an integer (in decimal unicode digits)
dwThisCounter = wcstoul(lpThisName, NULL, 10);
if (dwThisCounter == 0 || dwThisCounter > dwNewLastEntry) {
ReportLoadPerfEvent(
EVENTLOG_WARNING_TYPE, // error type
(DWORD) LDPRFMSG_REGISTRY_HELP_STRINGS_CORRUPT, // event,
4, dwThisCounter, dwNewLastEntry, dwNewLastEntry, __LINE__,
1, lpThisName, NULL, NULL);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEPERFNAMEFILES,
ARG_DEF(ARG_TYPE_WSTR, 1),
ERROR_INVALID_DATA,
TRACE_WSTR(lpThisName),
TRACE_DWORD(dwThisCounter),
TRACE_DWORD(dwNewLastEntry),
NULL));
continue; // bad entry, try next
}
// point to corresponding counter name
if (dwFlags & LODCTR_UPNF_RESTORE) {
// point to string that follows the "=" char
lpThisName = wcschr(lpThisName, L'=');
if (lpThisName != NULL) {
lpThisName ++;
}
else {
continue;
}
}
else {
// string is next in MSZ
lpThisName += (lstrlenW(lpThisName) + 1);
}
// and load array element;
pszNewNameTable[dwThisCounter] = lpThisName;
}
if (dwReturn == ERROR_SUCCESS && (! (dwFlags & LODCTR_UPNF_RESTORE))) {
for (lpThisName = szNewHlpStrings; * lpThisName != L'\0'; lpThisName += (lstrlenW(lpThisName) + 1)) {
// first string should be an integer (in decimal unicode digits)
dwThisCounter = wcstoul(lpThisName, NULL, 10);
if (dwThisCounter == 0 || dwThisCounter > dwNewLastEntry) {
ReportLoadPerfEvent(
EVENTLOG_WARNING_TYPE, // error type
(DWORD) LDPRFMSG_REGISTRY_HELP_STRINGS_CORRUPT, // event,
4, dwThisCounter, dwNewLastEntry, dwNewLastEntry, __LINE__,
1, lpThisName, NULL, NULL);
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEPERFNAMEFILES,
ARG_DEF(ARG_TYPE_WSTR, 1),
ERROR_INVALID_DATA,
TRACE_WSTR(lpThisName),
TRACE_DWORD(dwThisCounter),
TRACE_DWORD(dwNewLastEntry),
NULL));
continue; // bad entry, try next
}
// point to corresponding counter name
lpThisName += (lstrlenW(lpThisName) + 1);
// and load array element;
pszNewNameTable[dwThisCounter] = lpThisName;
}
}
if (dwReturn == ERROR_SUCCESS) {
// allocate string buffers for the resulting string
// we want to make sure there's plenty of room so we'll make it
// the size of the input file + the current buffer
dwStringSize = dwHlpFileSize;
dwStringSize += dwCtrFileSize;
if (pszOldNameTable != NULL) {
dwStringSize += MemorySize(pszOldNameTable);
}
szNewCtrMSZ = MemoryAllocate(dwStringSize * sizeof(WCHAR));
szNewHlpMSZ = MemoryAllocate(dwStringSize * sizeof(WCHAR));
if (szNewCtrMSZ == NULL || szNewHlpMSZ == NULL) {
dwReturn = ERROR_OUTOFMEMORY;
}
}
}
else {
dwReturn = ERROR_OUTOFMEMORY;
}
}
if (dwReturn == ERROR_SUCCESS) {
// write new strings into registry
__try {
dwReturn = RegOpenKeyExW(HKEY_LOCAL_MACHINE, NamesKey, RESERVED, KEY_READ, & hKeyPerflib);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwReturn = GetExceptionCode();
}
dwSize = sizeof(dwLastBaseValue);
dwLastBaseValue = 0;
if (dwReturn == ERROR_SUCCESS) {
__try {
dwReturn = RegQueryValueExW(hKeyPerflib,
BaseIndex,
RESERVED,
& dwType,
(LPBYTE) & dwLastBaseValue,
& dwSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwReturn = GetExceptionCode();
}
if (dwLastBaseValue == 0) {
dwReturn = ERROR_BADDB;
}
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEPERFNAMEFILES,
ARG_DEF(ARG_TYPE_WSTR, 1),
dwReturn,
TRACE_WSTR(BaseIndex),
TRACE_DWORD(dwLastBaseValue),
NULL));
RegCloseKey(hKeyPerflib);
}
}
else {
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEPERFNAMEFILES,
ARG_DEF(ARG_TYPE_WSTR, 1),
dwReturn,
TRACE_WSTR(NamesKey),
NULL));
}
if (dwReturn == ERROR_SUCCESS) {
DWORD dwLoopLimit;
// the strings should be mapped by now
// pszNewNameTable contains the new strings from the
// source path and pszOldNameTable contains the strings
// from the original system. The merge will consist of
// taking all base values from the new table and the
// extended values from the old table.
dwIndex = 1;
szThisCtrString = szNewCtrMSZ;
szThisHlpString = szNewHlpMSZ;
dwCtrFileSize = dwStringSize;
dwHlpFileSize = dwStringSize;
// index 1 is a special case and belongs in the counter string
// after that even numbers (starting w/ #2) go into the counter string
// and odd numbers (starting w/ #3) go into the help string
hr = StringCchPrintfW(szThisCtrString, dwCtrFileSize, L"%d", dwIndex);
dwCtrFileSize -= (lstrlenW(szThisCtrString) + 1);
szThisCtrString += (lstrlenW(szThisCtrString) + 1);
hr = StringCchPrintfW(szThisCtrString, dwCtrFileSize, L"%ws", pszNewNameTable[dwIndex]);
dwCtrFileSize -= (lstrlenW(szThisCtrString) + 1);
szThisCtrString += (lstrlenW(szThisCtrString) + 1);
dwIndex ++;
if (dwFlags & LODCTR_UPNF_RESTORE) {
// restore ALL strings from the input file only if this
// is a restoration
dwLoopLimit = dwOldLastEntry;
}
else {
// only update the system counters from the input file
dwLoopLimit = dwLastBaseValue;
}
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEPERFNAMEFILES,
0,
ERROR_SUCCESS,
TRACE_DWORD(dwOldLastEntry),
TRACE_DWORD(dwLastBaseValue),
NULL));
for (/*dwIndex from above*/; dwIndex <= dwLoopLimit; dwIndex++) {
if (pszNewNameTable[dwIndex] != NULL) {
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEPERFNAMEFILES,
ARG_DEF(ARG_TYPE_WSTR, 1),
ERROR_SUCCESS,
TRACE_WSTR(pszNewNameTable[dwIndex]),
TRACE_DWORD(dwIndex),
NULL));
if (dwIndex & 0x01) {
// then it's a help string
hr = StringCchPrintfW(szThisHlpString, dwHlpFileSize, L"%d", dwIndex);
dwHlpFileSize -= (lstrlenW(szThisHlpString) + 1);
szThisHlpString += (lstrlenW(szThisHlpString) + 1);
hr = StringCchPrintfW(szThisHlpString, dwHlpFileSize, L"%ws", pszNewNameTable[dwIndex]);
dwHlpFileSize -= (lstrlenW(szThisHlpString) + 1);
szThisHlpString += (lstrlenW(szThisHlpString) + 1);
}
else {
// it's a counter string
hr = StringCchPrintfW(szThisCtrString, dwCtrFileSize, L"%d", dwIndex);
dwCtrFileSize -= (lstrlenW(szThisCtrString) + 1);
szThisCtrString += (lstrlenW(szThisCtrString) + 1);
hr = StringCchPrintfW(szThisCtrString, dwCtrFileSize, L"%ws", pszNewNameTable[dwIndex]);
dwCtrFileSize -= (lstrlenW(szThisCtrString) + 1);
szThisCtrString += (lstrlenW(szThisCtrString) + 1);
}
} // else just skip it
}
for (/*dwIndex from last run */;dwIndex <= dwOldLastEntry; dwIndex++) {
if (pszOldNameTable[dwIndex] != NULL) {
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEPERFNAMEFILES,
ARG_DEF(ARG_TYPE_WSTR, 1),
ERROR_SUCCESS,
TRACE_WSTR(pszOldNameTable[dwIndex]),
TRACE_DWORD(dwIndex),
NULL));
if (dwIndex & 0x01) {
// then it's a help string
hr = StringCchPrintfW(szThisHlpString, dwHlpFileSize, L"%d", dwIndex);
dwHlpFileSize -= (lstrlenW(szThisHlpString) + 1);
szThisHlpString += (lstrlenW(szThisHlpString) + 1);
hr = StringCchPrintfW(szThisHlpString, dwHlpFileSize, L"%ws", pszOldNameTable[dwIndex]);
dwHlpFileSize -= (lstrlenW(szThisHlpString) + 1);
szThisHlpString += (lstrlenW(szThisHlpString) + 1);
} else {
// it's a counter string
hr = StringCchPrintfW(szThisCtrString, dwCtrFileSize, L"%d", dwIndex);
dwCtrFileSize -= (lstrlenW(szThisCtrString) + 1);
szThisCtrString += (lstrlenW(szThisCtrString) + 1);
hr = StringCchPrintfW(szThisCtrString, dwCtrFileSize, L"%ws", pszOldNameTable[dwIndex]);
dwCtrFileSize -= (lstrlenW(szThisCtrString) + 1);
szThisCtrString += (lstrlenW(szThisCtrString) + 1);
}
} // else just skip it
}
// terminate the MSZ
* szThisCtrString ++ = L'\0';
* szThisHlpString ++ = L'\0';
}
// close mapped memory sections:
if (bAllocCtrString) {
MemoryFree(szNewCtrStrings);
MemoryFree(szNewHlpStrings);
}
else {
if (szNewCtrStrings != NULL) UnmapViewOfFile(szNewCtrStrings);
if (szNewHlpStrings != NULL) UnmapViewOfFile(szNewHlpStrings);
}
if (hCtrFileMap != NULL) CloseHandle(hCtrFileMap);
if (hCtrFileIn != NULL) CloseHandle(hCtrFileIn);
if (hHlpFileMap != NULL) CloseHandle(hHlpFileMap);
if (hHlpFileIn != NULL) CloseHandle(hHlpFileIn);
if (dwReturn == ERROR_SUCCESS) {
// write new values to registry
LPWSTR AddCounterNameBuffer = NULL;
LPWSTR AddHelpNameBuffer = NULL;
dwLength = lstrlenW(AddCounterNameStr) + lstrlenW(AddHelpNameStr) + lstrlenW(szLanguageID) + 1;
AddCounterNameBuffer = MemoryAllocate(2 * dwLength * sizeof(WCHAR));
if (AddCounterNameBuffer != NULL) {
AddHelpNameBuffer = AddCounterNameBuffer + dwLength;
hr = StringCchPrintfW(AddCounterNameBuffer, dwLength, L"%ws%ws", AddCounterNameStr, szLanguageID);
hr = StringCchPrintfW(AddHelpNameBuffer, dwLength, L"%ws%ws", AddHelpNameStr, szLanguageID);
// because these are perf counter strings, RegQueryValueEx
// is used instead of RegSetValueEx as one might expect.
dwSize = (DWORD)((DWORD_PTR)szThisCtrString - (DWORD_PTR)szNewCtrMSZ);
__try {
dwReturn = RegQueryValueExW(HKEY_PERFORMANCE_DATA,
AddCounterNameBuffer,
RESERVED,
& dwType,
(LPVOID) szNewCtrMSZ,
& dwSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwReturn = GetExceptionCode();
}
if (dwReturn != ERROR_SUCCESS) {
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEPERFNAMEFILES,
ARG_DEF(ARG_TYPE_WSTR, 1),
dwReturn,
TRACE_WSTR(AddCounterNameBuffer),
TRACE_DWORD(dwSize),
NULL));
}
dwSize = (DWORD) ((DWORD_PTR) szThisHlpString - (DWORD_PTR) szNewHlpMSZ);
__try {
dwReturn = RegQueryValueExW(HKEY_PERFORMANCE_DATA,
AddHelpNameBuffer,
RESERVED,
& dwType,
(LPVOID) szNewHlpMSZ,
& dwSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwReturn = GetExceptionCode();
}
if (dwReturn != ERROR_SUCCESS) {
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_UPDATEPERFNAMEFILES,
ARG_DEF(ARG_TYPE_WSTR, 1),
dwReturn,
TRACE_WSTR(AddHelpNameBuffer),
TRACE_DWORD(dwSize),
NULL));
}
MemoryFree(AddCounterNameBuffer);
}
else {
dwReturn = ERROR_OUTOFMEMORY;
}
}
MemoryFree(szCtrNameIn);
MemoryFree(szHlpNameIn);
MemoryFree(pszNewNameTable);
MemoryFree(pszOldNameTable);
MemoryFree(szNewCtrMSZ);
MemoryFree(szNewHlpMSZ);
MemoryFree(szLangSection);
ReleaseMutex(hLoadPerfMutex);
return dwReturn;
}
// exported version of the above function
LOADPERF_FUNCTION
UpdatePerfNameFilesW(
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 dwStatus = ERROR_SUCCESS;
DWORD dwSize;
if (szNewCtrFilePath != NULL) {
__try {
dwSize = lstrlenW(szNewCtrFilePath);
if (dwSize == 0) dwStatus = ERROR_INVALID_PARAMETER;
}
__except(EXCEPTION_EXECUTE_HANDLER) {
dwStatus = ERROR_INVALID_PARAMETER;
}
}
else {
dwStatus = ERROR_INVALID_PARAMETER;
}
if (szNewHlpFilePath != NULL) {
__try {
dwSize = lstrlenW(szNewHlpFilePath);
if (dwSize == 0) dwStatus = ERROR_INVALID_PARAMETER;
}
__except(EXCEPTION_EXECUTE_HANDLER) {
dwStatus = ERROR_INVALID_PARAMETER;
}
}
else if (! (dwFlags & LODCTR_UPNF_RESTORE)) {
// this parameter can only be NULL if this flag bit is set.
dwStatus = ERROR_INVALID_PARAMETER;
}
if (szLanguageID != NULL) {
__try {
dwSize = lstrlenW(szLanguageID);
if (dwSize == 0) dwStatus = ERROR_INVALID_PARAMETER;
}
__except(EXCEPTION_EXECUTE_HANDLER) {
dwStatus = ERROR_INVALID_PARAMETER;
}
}
else {
dwStatus = ERROR_INVALID_PARAMETER;
}
if (dwStatus == ERROR_SUCCESS) {
dwStatus = UpdatePerfNameFilesX(szNewCtrFilePath, // data file with new base counter strings
szNewHlpFilePath, // data file with new base counter strings
szLanguageID, // Lang ID to update
dwFlags); // flags
}
return dwStatus;
}
LOADPERF_FUNCTION
UpdatePerfNameFilesA(
IN LPCSTR szNewCtrFilePath, // data file with new base counter strings
IN LPCSTR szNewHlpFilePath, // data file with new base counter strings
IN LPSTR szLanguageID, // Lang ID to update
IN ULONG_PTR dwFlags // flags
)
{
DWORD dwError = ERROR_SUCCESS;
LPWSTR wszNewCtrFilePath = NULL;
LPWSTR wszNewHlpFilePath = NULL;
LPWSTR wszLanguageID = NULL;
DWORD dwLength;
if (szNewCtrFilePath != NULL) {
__try {
dwLength = lstrlenA(szNewCtrFilePath);
if (dwLength == 0) {
dwError = ERROR_INVALID_PARAMETER;
}
else {
wszNewCtrFilePath = LoadPerfMultiByteToWideChar(CP_ACP, (LPSTR) szNewCtrFilePath);
}
}
__except(EXCEPTION_EXECUTE_HANDLER) {
dwError = ERROR_INVALID_PARAMETER;
}
}
else {
dwError = ERROR_INVALID_PARAMETER;
}
if (szNewHlpFilePath != NULL) {
__try {
dwLength = lstrlenA(szNewHlpFilePath);
if (dwLength == 0) {
dwError = ERROR_INVALID_PARAMETER;
}
else {
wszNewHlpFilePath = LoadPerfMultiByteToWideChar(CP_ACP, (LPSTR) szNewHlpFilePath);
}
}
__except(EXCEPTION_EXECUTE_HANDLER) {
dwError = ERROR_INVALID_PARAMETER;
}
}
else if (! (dwFlags & LODCTR_UPNF_RESTORE)) {
// this parameter can only be NULL if this flag bit is set.
dwError = ERROR_INVALID_PARAMETER;
}
if (szLanguageID != NULL) {
__try {
dwLength = lstrlenA(szLanguageID);
if (dwLength == 0) {
dwError = ERROR_INVALID_PARAMETER;
}
else {
wszLanguageID = LoadPerfMultiByteToWideChar(CP_ACP, (LPSTR) szLanguageID);
}
}
__except(EXCEPTION_EXECUTE_HANDLER) {
dwError = ERROR_INVALID_PARAMETER;
}
}
else {
dwError = ERROR_INVALID_PARAMETER;
}
if (dwError == ERROR_SUCCESS) {
if (wszNewCtrFilePath == NULL || wszLanguageID == NULL) {
dwError = ERROR_OUTOFMEMORY;
}
else if (szNewHlpFilePath != NULL && wszNewHlpFilePath == NULL) {
dwError = ERROR_OUTOFMEMORY;
}
if (dwError == ERROR_SUCCESS) {
dwError = UpdatePerfNameFilesX(wszNewCtrFilePath, wszNewHlpFilePath, wszLanguageID, dwFlags);
}
}
MemoryFree(wszNewCtrFilePath);
MemoryFree(wszNewHlpFilePath);
MemoryFree(wszLanguageID);
return dwError;
}
LOADPERF_FUNCTION
SetServiceAsTrustedW(
IN LPCWSTR szMachineName, // reserved, MBZ
IN LPCWSTR szServiceName
)
{
HKEY hKeyService_Perf = NULL;
DWORD dwReturn = ERROR_SUCCESS;
HKEY hKeyLM = HKEY_LOCAL_MACHINE; // until remote machine access is supported
LPWSTR szPerfKeyString = NULL;
LPWSTR szLibName = NULL;
LPWSTR szExpLibName = NULL;
LPWSTR szFullPathName = NULL;
DWORD dwSize, dwType;
HANDLE hFile;
DllValidationData dvdLibrary;
LARGE_INTEGER liSize;
BOOL bStatus;
HRESULT hr;
WinPerfStartTrace(NULL);
if (szMachineName != NULL) {
// reserved for future use
dwReturn = ERROR_INVALID_PARAMETER;
}
else if (szServiceName == NULL) {
dwReturn = ERROR_INVALID_PARAMETER;
}
else {
__try {
dwSize = lstrlenW(szServiceName);
if (dwSize == 0) dwReturn = ERROR_INVALID_PARAMETER;
}
__except(EXCEPTION_EXECUTE_HANDLER) {
dwReturn = ERROR_INVALID_PARAMETER;
}
}
if (dwReturn != ERROR_SUCCESS) goto Cleanup;
szPerfKeyString = MemoryAllocate(sizeof(WCHAR) * SMALL_BUFFER_SIZE * 4);
if (szPerfKeyString == NULL) {
dwReturn = ERROR_OUTOFMEMORY;
goto Cleanup;
}
szLibName = (LPWSTR) (szPerfKeyString + SMALL_BUFFER_SIZE);
szExpLibName = (LPWSTR) (szLibName + SMALL_BUFFER_SIZE);
szFullPathName = (LPWSTR) (szExpLibName + SMALL_BUFFER_SIZE);
// build path to performance subkey
hr = StringCchPrintfW(szPerfKeyString,
SMALL_BUFFER_SIZE,
L"%ws%ws%ws%ws%ws",
DriverPathRoot,
Slash,
szServiceName,
Slash,
Performance);
// open performance key under the service key
__try {
dwReturn = RegOpenKeyExW(hKeyLM, szPerfKeyString, 0L, KEY_READ | KEY_WRITE, & hKeyService_Perf);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwReturn = GetExceptionCode();
}
if (dwReturn == ERROR_SUCCESS) {
// get library name
dwType = 0;
dwSize = SMALL_BUFFER_SIZE * sizeof(WCHAR);
__try {
dwReturn = RegQueryValueExW(hKeyService_Perf, cszLibrary, NULL, & dwType, (LPBYTE) szLibName, & dwSize);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwReturn = GetExceptionCode();
}
if (dwReturn == ERROR_SUCCESS) {
// expand path name if necessary
if (dwType == REG_EXPAND_SZ) {
dwSize = ExpandEnvironmentStringsW(szLibName, szExpLibName, SMALL_BUFFER_SIZE);
}
else {
hr = StringCchCopyW(szExpLibName, SMALL_BUFFER_SIZE, szLibName);
// dwSize is same as returned from Fn Call.
}
if (dwSize != 0) {
// find DLL file
dwSize = SearchPathW(NULL, szExpLibName, NULL, SMALL_BUFFER_SIZE, szFullPathName, NULL);
if (dwSize > 0) {
hFile = CreateFileW(szFullPathName,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile != INVALID_HANDLE_VALUE) {
// read file date/time & size
bStatus = GetFileTime(hFile, & dvdLibrary.CreationDate, NULL, NULL);
if (bStatus) {
WORD dateCreate;
WORD timeCreate;
FileTimeToDosDateTime(& dvdLibrary.CreationDate, & dateCreate, & timeCreate);
DosDateTimeToFileTime(dateCreate, timeCreate, & dvdLibrary.CreationDate);
liSize.LowPart = GetFileSize( hFile, (DWORD *) & liSize.HighPart);
dvdLibrary.FileSize = liSize.QuadPart;
// set registry value
__try {
dwReturn = RegSetValueExW(hKeyService_Perf,
szLibraryValidationCode,
0L,
REG_BINARY,
(LPBYTE) & dvdLibrary,
sizeof(dvdLibrary));
}
__except (EXCEPTION_EXECUTE_HANDLER) {
dwReturn = GetExceptionCode();
}
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_SETSERVICEASTRUSTED,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2) | ARG_DEF(ARG_TYPE_WSTR, 3),
dwReturn,
TRACE_WSTR(szServiceName),
TRACE_WSTR(szExpLibName),
TRACE_WSTR(szLibraryValidationCode),
NULL));
}
else {
dwReturn = GetLastError();
}
CloseHandle (hFile);
}
else {
dwReturn = GetLastError();
}
}
else {
dwReturn = ERROR_FILE_NOT_FOUND;
}
}
else {
// unable to expand environment strings
dwReturn = GetLastError();
}
}
else {
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_SETSERVICEASTRUSTED,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
dwReturn,
TRACE_WSTR(szServiceName),
TRACE_WSTR(cszLibrary),
NULL));
}
// close key
RegCloseKey (hKeyService_Perf);
}
if (dwReturn == ERROR_SUCCESS) {
TRACE((WINPERF_DBG_TRACE_INFO),
(& LoadPerfGuid,
__LINE__,
LOADPERF_SETSERVICEASTRUSTED,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
ERROR_SUCCESS,
TRACE_WSTR(szServiceName),
TRACE_WSTR(Performance),
NULL));
}
else {
TRACE((WINPERF_DBG_TRACE_ERROR),
(& LoadPerfGuid,
__LINE__,
LOADPERF_SETSERVICEASTRUSTED,
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
dwReturn,
TRACE_WSTR(szServiceName),
TRACE_WSTR(Performance),
NULL));
}
Cleanup:
MemoryFree(szPerfKeyString);
return dwReturn;
}
LOADPERF_FUNCTION
SetServiceAsTrustedA(
IN LPCSTR szMachineName, // reserved, MBZ
IN LPCSTR szServiceName
)
{
LPWSTR lpWideServiceName = NULL;
DWORD lReturn = ERROR_SUCCESS;
if (szMachineName != NULL) {
// reserved for future use
lReturn = ERROR_INVALID_PARAMETER;
}
else if (szServiceName == NULL) {
lReturn = ERROR_INVALID_PARAMETER;
}
else {
__try {
DWORD dwStrLen = lstrlenA(szServiceName);
if (dwStrLen == 0) lReturn = ERROR_INVALID_PARAMETER;
}
__except(EXCEPTION_EXECUTE_HANDLER) {
lReturn = ERROR_INVALID_PARAMETER;
}
}
if (lReturn == ERROR_SUCCESS) {
//length of string including terminator
lpWideServiceName = LoadPerfMultiByteToWideChar(CP_ACP, (LPSTR) szServiceName);
if (lpWideServiceName != NULL) {
lReturn = SetServiceAsTrustedW(NULL, lpWideServiceName);
}
else {
lReturn = ERROR_OUTOFMEMORY;
}
}
MemoryFree(lpWideServiceName);
return lReturn;
}
int __cdecl
My_vfwprintf(
FILE * str,
const wchar_t * format,
va_list argptr
)
{
HANDLE hOut;
int iReturn = 0;
HRESULT hr;
static WCHAR szBufferMessage[LOADPERF_BUFF_SIZE];
if (str == stderr) {
hOut = GetStdHandle(STD_ERROR_HANDLE);
}
else {
hOut = GetStdHandle(STD_OUTPUT_HANDLE);
}
if ((GetFileType(hOut) & ~ FILE_TYPE_REMOTE) == FILE_TYPE_CHAR) {
hr = StringCchVPrintfW(szBufferMessage, LOADPERF_BUFF_SIZE, format, argptr);
if (SUCCEEDED(hr)) {
iReturn = lstrlenW(szBufferMessage);
WriteConsoleW(hOut, szBufferMessage, iReturn, & iReturn, NULL);
}
else {
iReturn = -1;
}
}
else {
iReturn = vfwprintf(str, format, argptr);
}
return iReturn;
}