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.
1558 lines
59 KiB
1558 lines
59 KiB
/*++
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
common.c
|
|
|
|
Abstract:
|
|
Utility routines used by Lodctr and/or UnLodCtr
|
|
|
|
|
|
Author:
|
|
Bob Watson (a-robw) 12 Feb 93
|
|
|
|
Revision History:
|
|
--*/
|
|
//
|
|
// Windows Include files
|
|
//
|
|
#include <windows.h>
|
|
#include "strsafe.h"
|
|
#include "stdlib.h"
|
|
#include <accctrl.h>
|
|
#include <aclapi.h>
|
|
#include <winperf.h>
|
|
#include <initguid.h>
|
|
#include <guiddef.h>
|
|
#include "wmistr.h"
|
|
#include "evntrace.h"
|
|
//
|
|
// local include files
|
|
//
|
|
#define _INIT_WINPERFP_
|
|
#include "winperfp.h"
|
|
#include "ldprfmsg.h"
|
|
#include "common.h"
|
|
//
|
|
// Text string Constant definitions
|
|
//
|
|
LPCWSTR NamesKey = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib";
|
|
LPCWSTR DefaultLangId = L"009";
|
|
LPCSTR aszDefaultLangId = "009";
|
|
LPCWSTR DefaultLangTag = L"000";
|
|
LPCWSTR Counters = L"Counters";
|
|
LPCWSTR Help = L"Help";
|
|
LPCWSTR VersionStr = L"Version";
|
|
LPCWSTR BaseIndex = L"Base Index";
|
|
LPCWSTR LastHelp = L"Last Help";
|
|
LPCWSTR LastCounter = L"Last Counter";
|
|
LPCWSTR FirstHelp = L"First Help";
|
|
LPCWSTR FirstCounter = L"First Counter";
|
|
LPCWSTR Busy = L"Updating";
|
|
LPCWSTR Slash = L"\\";
|
|
LPCWSTR BlankString = L" ";
|
|
LPCWSTR DriverPathRoot = L"SYSTEM\\CurrentControlSet\\Services";
|
|
LPCWSTR Performance = L"Performance";
|
|
LPCWSTR CounterNameStr = L"Counter ";
|
|
LPCWSTR HelpNameStr = L"Explain ";
|
|
LPCWSTR AddCounterNameStr = L"Addcounter ";
|
|
LPCWSTR AddHelpNameStr = L"Addexplain ";
|
|
LPCWSTR szObjectList = L"Object List";
|
|
LPCWSTR szLibraryValidationCode = L"Library Validation Code";
|
|
LPCWSTR DisablePerformanceCounters = L"Disable Performance Counters";
|
|
LPCWSTR szDisplayName = L"DisplayName";
|
|
LPCWSTR szPerfIniPath = L"PerfIniFile";
|
|
LPCSTR szInfo = "info";
|
|
LPCSTR szSymbolFile = "symbolfile";
|
|
LPCSTR szNotFound = "NotFound";
|
|
LPCSTR szLanguages = "languages";
|
|
LPCWSTR szLangCH = L"004";
|
|
LPCWSTR szLangCHT = L"0404";
|
|
LPCWSTR szLangCHS = L"0804";
|
|
LPCWSTR szLangCHH = L"0C04";
|
|
LPCWSTR szLangPT = L"016";
|
|
LPCWSTR szLangPT_BR = L"0416";
|
|
LPCWSTR szLangPT_PT = L"0816";
|
|
LPCWSTR szDatExt = L".DAT";
|
|
LPCWSTR szBakExt = L".BAK";
|
|
LPCWSTR wszInfo = L"info";
|
|
LPCWSTR wszDriverName = L"drivername";
|
|
LPCWSTR wszNotFound = L"NotFound";
|
|
LPCSTR aszDriverName = "drivername";
|
|
|
|
BOOLEAN g_bCheckTraceLevel = FALSE;
|
|
|
|
// Global (to this module) Buffers
|
|
//
|
|
static HANDLE hMod = NULL; // process handle
|
|
HANDLE hEventLog = NULL;
|
|
HANDLE hLoadPerfMutex = NULL;
|
|
//
|
|
// local static data
|
|
//
|
|
BOOL
|
|
__stdcall
|
|
DllEntryPoint(
|
|
IN HANDLE DLLHandle,
|
|
IN DWORD Reason,
|
|
IN LPVOID ReservedAndUnused
|
|
)
|
|
{
|
|
BOOL bReturn = FALSE;
|
|
|
|
ReservedAndUnused;
|
|
DisableThreadLibraryCalls(DLLHandle);
|
|
|
|
switch(Reason) {
|
|
case DLL_PROCESS_ATTACH:
|
|
hMod = DLLHandle; // use DLL handle , not APP handle
|
|
|
|
// register eventlog source
|
|
hEventLog = RegisterEventSourceW(NULL, (LPCWSTR) L"LoadPerf");
|
|
bReturn = TRUE;
|
|
break;
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
if (hEventLog != NULL) {
|
|
if (DeregisterEventSource(hEventLog)) {
|
|
hEventLog = NULL;
|
|
}
|
|
}
|
|
if (hLoadPerfMutex != NULL) {
|
|
CloseHandle(hLoadPerfMutex);
|
|
hLoadPerfMutex = NULL;
|
|
}
|
|
bReturn = TRUE;
|
|
break;
|
|
|
|
case DLL_THREAD_ATTACH:
|
|
case DLL_THREAD_DETACH:
|
|
bReturn = TRUE;
|
|
break;
|
|
}
|
|
return bReturn;
|
|
}
|
|
|
|
LPCWSTR
|
|
GetFormatResource(
|
|
UINT wStringId
|
|
)
|
|
/*++
|
|
Returns an ANSI string for use as a format string in a printf fn.
|
|
--*/
|
|
{
|
|
LPCWSTR szReturn = BlankString;
|
|
static WCHAR TextFormat[DISP_BUFF_SIZE];
|
|
|
|
if (! hMod) {
|
|
hMod = (HINSTANCE) GetModuleHandle(NULL); // get instance ID of this module;
|
|
}
|
|
if (hMod) {
|
|
if ((LoadStringW(hMod, wStringId, TextFormat, DISP_BUFF_SIZE)) > 0) {
|
|
szReturn = (LPCWSTR) TextFormat;
|
|
}
|
|
}
|
|
return szReturn;
|
|
}
|
|
|
|
VOID
|
|
DisplayCommandHelp(
|
|
UINT iFirstLine,
|
|
UINT iLastLine
|
|
)
|
|
/*++
|
|
|
|
DisplayCommandHelp
|
|
|
|
displays usage of command line arguments
|
|
|
|
Arguments
|
|
|
|
NONE
|
|
|
|
Return Value
|
|
|
|
NONE
|
|
|
|
--*/
|
|
{
|
|
UINT iThisLine;
|
|
WCHAR StringBuffer[DISP_BUFF_SIZE];
|
|
CHAR OemStringBuffer[DISP_BUFF_SIZE];
|
|
int nStringBufferLen;
|
|
int nOemStringBufferLen;
|
|
|
|
if (! hMod) {
|
|
hMod = (HINSTANCE) GetModuleHandle(NULL);
|
|
}
|
|
if (hMod) {
|
|
for (iThisLine = iFirstLine; iThisLine <= iLastLine; iThisLine++) {
|
|
ZeroMemory(StringBuffer, DISP_BUFF_SIZE * sizeof(WCHAR));
|
|
ZeroMemory(OemStringBuffer, DISP_BUFF_SIZE * sizeof(CHAR));
|
|
|
|
nStringBufferLen = LoadStringW(hMod, iThisLine, StringBuffer, DISP_BUFF_SIZE);
|
|
if (nStringBufferLen > 0) {
|
|
nOemStringBufferLen = DISP_BUFF_SIZE;
|
|
WideCharToMultiByte(CP_OEMCP,
|
|
0,
|
|
StringBuffer,
|
|
nStringBufferLen,
|
|
OemStringBuffer,
|
|
nOemStringBufferLen,
|
|
NULL,
|
|
NULL);
|
|
fprintf(stdout, "\n%s", OemStringBuffer);
|
|
}
|
|
}
|
|
} // else do nothing
|
|
} // DisplayCommandHelp
|
|
|
|
BOOL
|
|
TrimSpaces(
|
|
LPWSTR szString
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Trims leading and trailing spaces from szString argument, modifying
|
|
the buffer passed in
|
|
|
|
Arguments:
|
|
IN OUT LPWSTR szString
|
|
buffer to process
|
|
|
|
Return Value:
|
|
TRUE if string was modified
|
|
FALSE if not
|
|
--*/
|
|
{
|
|
LPWSTR szSource = szString;
|
|
LPWSTR szDest = szString;
|
|
LPWSTR szLast = szString;
|
|
BOOL bChars = FALSE;
|
|
|
|
if (szString != NULL) {
|
|
while (* szSource != L'\0') {
|
|
// skip leading non-space chars
|
|
if (! iswspace(* szSource)) {
|
|
szLast = szDest;
|
|
bChars = TRUE;
|
|
}
|
|
if (bChars) {
|
|
// remember last non-space character
|
|
// copy source to destination & increment both
|
|
* szDest ++ = * szSource ++;
|
|
}
|
|
else {
|
|
szSource ++;
|
|
}
|
|
}
|
|
if (bChars) {
|
|
* ++ szLast = L'\0'; // terminate after last non-space char
|
|
}
|
|
else {
|
|
// string was all spaces so return an empty (0-len) string
|
|
* szString = L'\0';
|
|
}
|
|
}
|
|
return (szLast != szSource);
|
|
}
|
|
|
|
BOOL
|
|
IsDelimiter(
|
|
WCHAR cChar,
|
|
WCHAR cDelimiter
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
compares the characte to the delimiter. If the delimiter is
|
|
a whitespace character then any whitespace char will match
|
|
otherwise an exact match is required
|
|
--*/
|
|
{
|
|
if (iswspace(cDelimiter)) {
|
|
// delimiter is whitespace so any whitespace char will do
|
|
return(iswspace(cChar));
|
|
}
|
|
else {
|
|
// delimiter is not white space so use an exact match
|
|
return (cChar == cDelimiter);
|
|
}
|
|
}
|
|
|
|
LPCWSTR
|
|
GetItemFromString(
|
|
LPCWSTR szEntry,
|
|
DWORD dwItem,
|
|
WCHAR cDelimiter
|
|
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
returns nth item from a list delimited by the cDelimiter Char.
|
|
Leaves (double)quoted strings intact.
|
|
|
|
Arguments:
|
|
IN LPWTSTR szEntry
|
|
Source string returned to parse
|
|
IN DWORD dwItem
|
|
1-based index indicating which item to return. (i.e. 1= first item
|
|
in list, 2= second, etc.)
|
|
IN WCHAR cDelimiter
|
|
character used to separate items. Note if cDelimiter is WhiteSpace
|
|
(e.g. a tab or a space) then any white space will serve as a delim.
|
|
|
|
Return Value:
|
|
pointer to buffer containing desired entry in string. Note, this
|
|
routine may only be called 4 times before the string
|
|
buffer is re-used. (i.e. don't use this function more than
|
|
4 times in single function call!!)
|
|
--*/
|
|
{
|
|
static WCHAR szReturnBuffer[4][MAX_PATH];
|
|
static LONG dwBuff;
|
|
LPWSTR szSource, szDest;
|
|
DWORD dwThisItem;
|
|
DWORD dwStrLeft;
|
|
|
|
dwBuff = ++ dwBuff % 4; // wrap buffer index
|
|
|
|
szSource = (LPWSTR) szEntry;
|
|
szDest = & szReturnBuffer[dwBuff][0];
|
|
|
|
// clear previous contents
|
|
ZeroMemory(szDest, MAX_PATH * sizeof(WCHAR));
|
|
|
|
// find desired entry in string
|
|
dwThisItem = 1;
|
|
while (dwThisItem < dwItem) {
|
|
if (* szSource != L'\0') {
|
|
while (! IsDelimiter(* szSource, cDelimiter) && (* szSource != L'\0')) {
|
|
if (* szSource == cDoubleQuote) {
|
|
// if this is a quote, then go to the close quote
|
|
szSource ++;
|
|
while ((* szSource != cDoubleQuote) && (* szSource != L'\0')) szSource ++;
|
|
}
|
|
if (* szSource != L'\0') szSource ++;
|
|
}
|
|
}
|
|
dwThisItem ++;
|
|
if (* szSource != L'\0') szSource ++;
|
|
}
|
|
|
|
// copy this entry to the return buffer
|
|
if (* szSource != L'\0') {
|
|
dwStrLeft = MAX_PATH - 1;
|
|
while (! IsDelimiter(* szSource, cDelimiter) && (* szSource != L'\0')) {
|
|
if (* szSource == cDoubleQuote) {
|
|
// if this is a quote, then go to the close quote
|
|
// don't copy quotes!
|
|
szSource ++;
|
|
while ((* szSource != cDoubleQuote) && (* szSource != L'\0')) {
|
|
* szDest ++ = * szSource ++;
|
|
dwStrLeft --;
|
|
if (! dwStrLeft) break; // dest is full (except for term NULL
|
|
}
|
|
if (* szSource != L'\0') szSource ++;
|
|
}
|
|
else {
|
|
* szDest ++ = * szSource ++;
|
|
dwStrLeft --;
|
|
if (! dwStrLeft) break; // dest is full (except for term NULL
|
|
}
|
|
}
|
|
* szDest = L'\0';
|
|
}
|
|
|
|
// remove any leading and/or trailing spaces
|
|
TrimSpaces(& szReturnBuffer[dwBuff][0]);
|
|
return & szReturnBuffer[dwBuff][0];
|
|
}
|
|
|
|
void
|
|
ReportLoadPerfEvent(
|
|
WORD EventType,
|
|
DWORD EventID,
|
|
DWORD dwDataCount,
|
|
DWORD dwData1,
|
|
DWORD dwData2,
|
|
DWORD dwData3,
|
|
DWORD dwData4,
|
|
WORD wStringCount,
|
|
LPWSTR szString1,
|
|
LPWSTR szString2,
|
|
LPWSTR szString3
|
|
)
|
|
{
|
|
DWORD dwData[5];
|
|
LPWSTR szMessageArray[4];
|
|
BOOL bResult = FALSE;
|
|
WORD wLocalStringCount = 0;
|
|
DWORD dwLastError = GetLastError();
|
|
|
|
if (dwDataCount > 4) dwDataCount = 4;
|
|
if (wStringCount > 3) wStringCount = 3;
|
|
|
|
if (dwDataCount > 0) dwData[0] = dwData1;
|
|
if (dwDataCount > 1) dwData[1] = dwData2;
|
|
if (dwDataCount > 2) dwData[2] = dwData3;
|
|
if (dwDataCount > 3) dwData[3] = dwData4;
|
|
dwDataCount *= sizeof(DWORD);
|
|
|
|
if (wStringCount > 0 && szString1) {
|
|
szMessageArray[wLocalStringCount] = szString1;
|
|
wLocalStringCount ++;
|
|
}
|
|
if (wStringCount > 1 && szString2) {
|
|
szMessageArray[wLocalStringCount] = szString2;
|
|
wLocalStringCount ++;
|
|
}
|
|
if (wStringCount > 2 && szString3) {
|
|
szMessageArray[wLocalStringCount] = szString3;
|
|
wLocalStringCount ++;
|
|
}
|
|
|
|
if (hEventLog == NULL) {
|
|
hEventLog = RegisterEventSourceW(NULL, (LPCWSTR) L"LoadPerf");
|
|
}
|
|
|
|
if (dwDataCount > 0 && wLocalStringCount > 0) {
|
|
bResult = ReportEventW(hEventLog,
|
|
EventType, // event type
|
|
0, // category (not used)
|
|
EventID, // event,
|
|
NULL, // SID (not used),
|
|
wLocalStringCount, // number of strings
|
|
dwDataCount, // sizeof raw data
|
|
szMessageArray, // message text array
|
|
(LPVOID) & dwData[0]); // raw data
|
|
}
|
|
else if (dwDataCount > 0) {
|
|
bResult = ReportEventW(hEventLog,
|
|
EventType, // event type
|
|
0, // category (not used)
|
|
EventID, // event,
|
|
NULL, // SID (not used),
|
|
0, // number of strings
|
|
dwDataCount, // sizeof raw data
|
|
NULL, // message text array
|
|
(LPVOID) & dwData[0]); // raw data
|
|
}
|
|
else if (wLocalStringCount > 0) {
|
|
bResult = ReportEventW(hEventLog,
|
|
EventType, // event type
|
|
0, // category (not used)
|
|
EventID, // event,
|
|
NULL, // SID (not used),
|
|
wLocalStringCount, // number of strings
|
|
0, // sizeof raw data
|
|
szMessageArray, // message text array
|
|
NULL); // raw data
|
|
}
|
|
else {
|
|
bResult = ReportEventW(hEventLog,
|
|
EventType, // event type
|
|
0, // category (not used)
|
|
EventID, // event,
|
|
NULL, // SID (not used),
|
|
0, // number of strings
|
|
0, // sizeof raw data
|
|
NULL, // message text array
|
|
NULL); // raw data
|
|
}
|
|
#if 0
|
|
if (! bResult) {
|
|
DbgPrint("LOADPERF(%5d,%5d)::(%d,0x%08X,%d)(%d,%d,%d,%d,%d)(%d,\"%ws\",\"%ws\",\"%ws\")\n",
|
|
GetCurrentProcessId(), GetCurrentThreadId(),
|
|
EventType, EventID, GetLastError(),
|
|
dwDataCount, dwData1, dwData2, dwData3, dwData4,
|
|
wStringCount, szString1, szString2, szString3);
|
|
}
|
|
#endif
|
|
SetLastError(dwLastError);
|
|
}
|
|
|
|
BOOLEAN LoadPerfGrabMutex()
|
|
{
|
|
BOOL bResult = TRUE;
|
|
HANDLE hLocalMutex = NULL;
|
|
DWORD dwWaitStatus = 0;
|
|
SECURITY_ATTRIBUTES SecurityAttributes;
|
|
PSECURITY_DESCRIPTOR pSD = NULL;
|
|
EXPLICIT_ACCESSW ea[3];
|
|
SID_IDENTIFIER_AUTHORITY authNT = SECURITY_NT_AUTHORITY;
|
|
SID_IDENTIFIER_AUTHORITY authWorld = SECURITY_WORLD_SID_AUTHORITY;
|
|
PSID psidSystem = NULL;
|
|
PSID psidAdmin = NULL;
|
|
PSID psidEveryone = NULL;
|
|
PACL pAcl = NULL;
|
|
|
|
if (hLoadPerfMutex == NULL) {
|
|
ZeroMemory(ea, 3 * sizeof(EXPLICIT_ACCESS));
|
|
|
|
// Get the system sid
|
|
//
|
|
bResult = AllocateAndInitializeSid(& authNT, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, & psidSystem);
|
|
if (! bResult) {
|
|
dwWaitStatus = GetLastError();
|
|
TRACE((WINPERF_DBG_TRACE_ERROR),
|
|
(& LoadPerfGuid,
|
|
__LINE__,
|
|
LOADPERF_LOADPERFGRABMUTEX,
|
|
0,
|
|
dwWaitStatus,
|
|
NULL));
|
|
goto Cleanup;
|
|
}
|
|
|
|
// Set the access rights for system sid
|
|
//
|
|
ea[0].grfAccessPermissions = MUTEX_ALL_ACCESS;
|
|
ea[0].grfAccessMode = SET_ACCESS;
|
|
ea[0].grfInheritance = NO_INHERITANCE;
|
|
ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
|
ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
|
|
ea[0].Trustee.ptstrName = (LPWSTR) psidSystem;
|
|
|
|
// Get the Admin sid
|
|
//
|
|
bResult = AllocateAndInitializeSid(& authNT,
|
|
2,
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_ADMINS,
|
|
0, 0, 0, 0, 0, 0,
|
|
& psidAdmin);
|
|
if (! bResult) {
|
|
dwWaitStatus = GetLastError();
|
|
TRACE((WINPERF_DBG_TRACE_ERROR),
|
|
(& LoadPerfGuid,
|
|
__LINE__,
|
|
LOADPERF_LOADPERFGRABMUTEX,
|
|
0,
|
|
dwWaitStatus,
|
|
NULL));
|
|
goto Cleanup;
|
|
}
|
|
|
|
// Set the access rights for Admin sid
|
|
//
|
|
ea[1].grfAccessPermissions = MUTEX_ALL_ACCESS;
|
|
ea[1].grfAccessMode = SET_ACCESS;
|
|
ea[1].grfInheritance = NO_INHERITANCE;
|
|
ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
|
ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
|
|
ea[1].Trustee.ptstrName = (LPWSTR) psidAdmin;
|
|
|
|
// Get the World sid
|
|
//
|
|
bResult = AllocateAndInitializeSid(& authWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, & psidEveryone);
|
|
if (! bResult) {
|
|
dwWaitStatus = GetLastError();
|
|
TRACE((WINPERF_DBG_TRACE_ERROR),
|
|
(& LoadPerfGuid,
|
|
__LINE__,
|
|
LOADPERF_LOADPERFGRABMUTEX,
|
|
0,
|
|
dwWaitStatus,
|
|
NULL));
|
|
goto Cleanup;
|
|
}
|
|
|
|
// Set the access rights for world
|
|
//
|
|
ea[2].grfAccessPermissions = READ_CONTROL | SYNCHRONIZE | MUTEX_MODIFY_STATE;
|
|
ea[2].grfAccessMode = SET_ACCESS;
|
|
ea[2].grfInheritance = NO_INHERITANCE;
|
|
ea[2].Trustee.TrusteeForm = TRUSTEE_IS_SID;
|
|
ea[2].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
|
|
ea[2].Trustee.ptstrName = (LPWSTR) psidEveryone;
|
|
|
|
// Create a new ACL that contains the new ACEs.
|
|
//
|
|
dwWaitStatus = SetEntriesInAclW(3, ea, NULL, & pAcl);
|
|
if (dwWaitStatus != ERROR_SUCCESS) {
|
|
bResult = FALSE;
|
|
TRACE((WINPERF_DBG_TRACE_ERROR),
|
|
(& LoadPerfGuid,
|
|
__LINE__,
|
|
LOADPERF_LOADPERFGRABMUTEX,
|
|
0,
|
|
dwWaitStatus,
|
|
NULL));
|
|
goto Cleanup;
|
|
}
|
|
|
|
// Initialize a security descriptor.
|
|
//
|
|
pSD = (PSECURITY_DESCRIPTOR)
|
|
LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
|
|
if (pSD == NULL) {
|
|
dwWaitStatus = GetLastError();
|
|
bResult = FALSE;
|
|
TRACE((WINPERF_DBG_TRACE_ERROR),
|
|
(& LoadPerfGuid,
|
|
__LINE__,
|
|
LOADPERF_LOADPERFGRABMUTEX,
|
|
0,
|
|
dwWaitStatus,
|
|
NULL));
|
|
goto Cleanup;
|
|
}
|
|
|
|
bResult = InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
|
|
if (! bResult) {
|
|
dwWaitStatus = GetLastError();
|
|
TRACE((WINPERF_DBG_TRACE_ERROR),
|
|
(& LoadPerfGuid,
|
|
__LINE__,
|
|
LOADPERF_LOADPERFGRABMUTEX,
|
|
0,
|
|
dwWaitStatus,
|
|
NULL));
|
|
goto Cleanup;
|
|
}
|
|
|
|
// Add the ACL to the security descriptor.
|
|
//
|
|
bResult = SetSecurityDescriptorDacl(pSD, TRUE, pAcl, FALSE);
|
|
if (! bResult) {
|
|
dwWaitStatus = GetLastError();
|
|
TRACE((WINPERF_DBG_TRACE_ERROR),
|
|
(& LoadPerfGuid,
|
|
__LINE__,
|
|
LOADPERF_LOADPERFGRABMUTEX,
|
|
0,
|
|
dwWaitStatus,
|
|
NULL));
|
|
goto Cleanup;
|
|
}
|
|
|
|
SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
|
|
SecurityAttributes.bInheritHandle = TRUE;
|
|
SecurityAttributes.lpSecurityDescriptor = pSD;
|
|
|
|
__try {
|
|
hLocalMutex = CreateMutexW(& SecurityAttributes, FALSE, L"LOADPERF_MUTEX");
|
|
if (hLocalMutex == NULL) {
|
|
bResult = FALSE;
|
|
dwWaitStatus = GetLastError();
|
|
TRACE((WINPERF_DBG_TRACE_ERROR),
|
|
(& LoadPerfGuid,
|
|
__LINE__,
|
|
LOADPERF_LOADPERFGRABMUTEX,
|
|
0,
|
|
dwWaitStatus,
|
|
NULL));
|
|
}
|
|
else if (InterlockedCompareExchangePointer(& hLoadPerfMutex, hLocalMutex, NULL) != NULL) {
|
|
CloseHandle(hLocalMutex);
|
|
hLocalMutex = NULL;
|
|
}
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
|
bResult = FALSE;
|
|
dwWaitStatus = GetLastError();
|
|
TRACE((WINPERF_DBG_TRACE_FATAL),
|
|
(& LoadPerfGuid,
|
|
__LINE__,
|
|
LOADPERF_LOADPERFGRABMUTEX,
|
|
0,
|
|
dwWaitStatus,
|
|
NULL));
|
|
}
|
|
}
|
|
|
|
__try {
|
|
dwWaitStatus = WaitForSingleObject(hLoadPerfMutex, H_MUTEX_TIMEOUT);
|
|
}
|
|
__except (EXCEPTION_EXECUTE_HANDLER) {
|
|
bResult = FALSE;
|
|
dwWaitStatus = GetLastError();
|
|
TRACE((WINPERF_DBG_TRACE_FATAL),
|
|
(& LoadPerfGuid,
|
|
__LINE__,
|
|
LOADPERF_LOADPERFGRABMUTEX,
|
|
0,
|
|
dwWaitStatus,
|
|
NULL));
|
|
}
|
|
if (dwWaitStatus != WAIT_OBJECT_0 && dwWaitStatus != WAIT_ABANDONED) {
|
|
bResult = FALSE;
|
|
TRACE((WINPERF_DBG_TRACE_FATAL),
|
|
(& LoadPerfGuid,
|
|
__LINE__,
|
|
LOADPERF_LOADPERFGRABMUTEX,
|
|
0,
|
|
dwWaitStatus,
|
|
NULL));
|
|
}
|
|
|
|
Cleanup:
|
|
if (psidSystem) FreeSid(psidSystem);
|
|
if (psidAdmin) FreeSid(psidAdmin);
|
|
if (psidEveryone) FreeSid(psidEveryone);
|
|
if (pAcl) LocalFree(pAcl);
|
|
if (pSD) LocalFree(pSD);
|
|
if (! bResult) SetLastError(dwWaitStatus);
|
|
|
|
return bResult ? TRUE : FALSE;
|
|
}
|
|
|
|
#define LODWORD(ll) ((DWORD) ((LONGLONG) ll & 0x00000000FFFFFFFF))
|
|
#define HIDWORD(ll) ((DWORD) (((LONGLONG) ll >> 32) & 0x00000000FFFFFFFF))
|
|
#define MAKELONGLONG(low, high) ((LONGLONG) (((DWORD) (low)) | ((LONGLONG) ((DWORD) (high))) << 32))
|
|
|
|
LPWSTR g_szInfPath = NULL;
|
|
|
|
LPWSTR
|
|
LoadPerfGetLanguage(LPWSTR szLang, BOOL bPrimary)
|
|
{
|
|
LPWSTR szRtnLang = szLang;
|
|
|
|
if (bPrimary) {
|
|
if (lstrcmpiW(szLang, szLangCHT) == 0 || lstrcmpiW(szLang, szLangCHS) == 0
|
|
|| lstrcmpiW(szLang, szLangCHH) == 0) {
|
|
szRtnLang = (LPWSTR) szLangCH;
|
|
}
|
|
else if (lstrcmpiW(szLang, szLangPT_PT) == 0 || lstrcmpiW(szLang, szLangPT_BR) == 0) {
|
|
szRtnLang = (LPWSTR) szLangPT;
|
|
}
|
|
}
|
|
else if (lstrcmpiW(szLang, szLangCH) == 0) {
|
|
DWORD dwLangId = GetUserDefaultUILanguage();
|
|
|
|
if (dwLangId == 0x0404 || dwLangId == 0x0C04) szRtnLang = (LPWSTR) szLangCHT;
|
|
else if (dwLangId == 0x0804) szRtnLang = (LPWSTR) szLangCHS;
|
|
else szRtnLang = (LPWSTR) szLangCH;
|
|
}
|
|
else if (lstrcmpiW(szLang, szLangPT) == 0) {
|
|
DWORD dwLangId = GetUserDefaultUILanguage();
|
|
|
|
if (dwLangId == 0x0416) szRtnLang = (LPWSTR) szLangPT_BR;
|
|
else if (dwLangId == 0x0816) szRtnLang = (LPWSTR) szLangPT_PT;
|
|
else szRtnLang = (LPWSTR) szLangPT;
|
|
}
|
|
|
|
return szRtnLang;
|
|
}
|
|
|
|
LPWSTR
|
|
LoadPerfGetInfPath()
|
|
{
|
|
LPWSTR szReturn = NULL;
|
|
DWORD dwInfPath = 0;
|
|
HRESULT hError = S_OK;
|
|
|
|
if (g_szInfPath == NULL) {
|
|
dwInfPath = GetSystemWindowsDirectoryW(NULL, 0);
|
|
if (dwInfPath > 0) {
|
|
dwInfPath += 6;
|
|
if (dwInfPath < MAX_PATH) dwInfPath = MAX_PATH;
|
|
g_szInfPath = MemoryAllocate(dwInfPath * sizeof(WCHAR));
|
|
if (g_szInfPath != NULL) {
|
|
GetSystemWindowsDirectoryW(g_szInfPath, dwInfPath);
|
|
hError = StringCchCatW(g_szInfPath, dwInfPath, Slash);
|
|
if (SUCCEEDED(hError)) {
|
|
hError = StringCchCatW(g_szInfPath, dwInfPath, L"inf");
|
|
if (SUCCEEDED(hError)) {
|
|
hError = StringCchCatW(g_szInfPath, dwInfPath, Slash);
|
|
}
|
|
}
|
|
if (SUCCEEDED(hError)) {
|
|
szReturn = g_szInfPath;
|
|
}
|
|
else {
|
|
SetLastError(HRESULT_CODE(hError));
|
|
}
|
|
}
|
|
else {
|
|
SetLastError(ERROR_OUTOFMEMORY);
|
|
}
|
|
}
|
|
else {
|
|
SetLastError(ERROR_INVALID_DATA);
|
|
}
|
|
if (szReturn == NULL) {
|
|
MemoryFree(g_szInfPath);
|
|
g_szInfPath = NULL;
|
|
}
|
|
}
|
|
else {
|
|
szReturn = g_szInfPath;
|
|
}
|
|
return szReturn;
|
|
}
|
|
|
|
BOOL
|
|
LoadPerfGetIncludeFileName(
|
|
LPCSTR szIniFile,
|
|
DWORD dwFileSize,
|
|
DWORD dwUnicode,
|
|
LPWSTR * szIncFile,
|
|
LPWSTR * szService
|
|
)
|
|
// Caller LoadPerfBackupIniFile() should free allocated szIncFile and szService.
|
|
{
|
|
LPSTR szIncName = NULL;
|
|
LPSTR szPath = NULL;
|
|
LPSTR szDrive = NULL;
|
|
LPSTR szDir = NULL;
|
|
LPSTR aszIncFile = NULL;
|
|
LPSTR aszService = NULL;
|
|
DWORD dwSize = 0;
|
|
BOOL bReturn = FALSE;
|
|
HRESULT hr = S_OK;
|
|
|
|
if (szIncFile == NULL || szService == NULL) {
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return FALSE;
|
|
}
|
|
|
|
* szIncFile = NULL;
|
|
* szService = NULL;
|
|
|
|
dwSize = 6 * dwFileSize;
|
|
szIncName = MemoryAllocate(dwSize * sizeof(CHAR));
|
|
if (szIncName != NULL) {
|
|
LPWSTR wszIniFile = NULL;
|
|
|
|
szPath = (LPSTR) (szIncName + dwFileSize);
|
|
szDrive = (LPSTR) (szPath + dwFileSize);
|
|
szDir = (LPSTR) (szDrive + dwFileSize);
|
|
aszIncFile = (LPSTR) (szDir + dwFileSize);
|
|
aszService = (LPSTR) (aszIncFile + dwFileSize);
|
|
|
|
if (dwUnicode != 0) {
|
|
wszIniFile = LoadPerfMultiByteToWideChar(CP_ACP, (LPSTR) szIniFile);
|
|
}
|
|
if (wszIniFile == NULL) {
|
|
dwSize = GetPrivateProfileStringA(szInfo, aszDriverName, szNotFound, aszService, dwFileSize, szIniFile);
|
|
if (lstrcmpiA(aszService, szNotFound) != 0) {
|
|
* szService = LoadPerfMultiByteToWideChar(CP_ACP, aszService);
|
|
bReturn = TRUE;
|
|
}
|
|
else {
|
|
// name not found, default returned so return NULL string
|
|
SetLastError(ERROR_BAD_DRIVER);
|
|
}
|
|
}
|
|
else {
|
|
* szService = MemoryAllocate(dwFileSize * sizeof(WCHAR));
|
|
if (* szService != NULL) {
|
|
dwSize = GetPrivateProfileStringW(
|
|
wszInfo, wszDriverName, wszNotFound, * szService, dwFileSize, wszIniFile);
|
|
if (lstrcmpiW(* szService, wszNotFound) == 0) {
|
|
// name not found, default returned so return NULL string
|
|
SetLastError(ERROR_BAD_DRIVER);
|
|
}
|
|
else {
|
|
bReturn = TRUE;
|
|
}
|
|
}
|
|
MemoryFree(wszIniFile);
|
|
}
|
|
|
|
dwSize = GetPrivateProfileStringA(szInfo, szSymbolFile, szNotFound, szIncName, dwFileSize, szIniFile);
|
|
if (dwSize == 0 || lstrcmpiA(szIncName, szNotFound) == 0) {
|
|
SetLastError(ERROR_BAD_DRIVER);
|
|
goto Cleanup;
|
|
}
|
|
_splitpath(szIniFile, szDrive, szDir, NULL, NULL);
|
|
hr = StringCchCopyA(szPath, dwFileSize, szDrive);
|
|
if (SUCCEEDED(hr)) {
|
|
hr = StringCchCatA(szPath, dwFileSize, szDir);
|
|
}
|
|
if (FAILED(hr)) {
|
|
goto Cleanup;
|
|
}
|
|
dwSize = SearchPathA(szPath, szIncName, NULL, dwFileSize, aszIncFile, NULL);
|
|
if (dwSize == 0) {
|
|
dwSize = SearchPathA(NULL, szIncName, NULL, dwFileSize, aszIncFile, NULL);
|
|
}
|
|
if (dwSize != 0) {
|
|
* szIncFile = LoadPerfMultiByteToWideChar(CP_ACP, aszIncFile);
|
|
}
|
|
|
|
bReturn = (dwSize > 0) ? TRUE : FALSE;
|
|
}
|
|
|
|
Cleanup:
|
|
TRACE((WINPERF_DBG_TRACE_INFO),
|
|
(& LoadPerfGuid,
|
|
__LINE__,
|
|
LOADPERF_GETINCLUDEFILENAME,
|
|
ARG_DEF(ARG_TYPE_STR, 1) | ARG_DEF(ARG_TYPE_STR, 2) | ARG_DEF(ARG_TYPE_STR, 3),
|
|
GetLastError(),
|
|
TRACE_STR(szIniFile),
|
|
TRACE_STR(aszIncFile),
|
|
TRACE_STR(aszService),
|
|
NULL));
|
|
MemoryFree(szIncName);
|
|
return bReturn;
|
|
}
|
|
|
|
BOOL
|
|
LoadPerfCheckAndCreatePath(
|
|
LPWSTR szPath
|
|
)
|
|
{
|
|
BOOL bReturn = CreateDirectoryW(szPath, NULL);
|
|
TRACE((WINPERF_DBG_TRACE_INFO),
|
|
(& LoadPerfGuid,
|
|
__LINE__,
|
|
LOADPERF_CHECKANDCREATEPATH,
|
|
ARG_DEF(ARG_TYPE_WSTR, 1),
|
|
GetLastError(),
|
|
TRACE_WSTR(szPath),
|
|
NULL));
|
|
if (bReturn == FALSE) {
|
|
bReturn = (GetLastError() == ERROR_ALREADY_EXISTS) ? (TRUE) : (FALSE);
|
|
}
|
|
return bReturn;
|
|
}
|
|
|
|
BOOL
|
|
LoadPerfCheckAndCopyFile(
|
|
LPCWSTR szThisFile,
|
|
LPWSTR szBackupFile
|
|
)
|
|
{
|
|
DWORD Status = ERROR_SUCCESS;
|
|
BOOL bReturn = FALSE;
|
|
HANDLE hFile1 = NULL;
|
|
|
|
hFile1 = CreateFileW(szThisFile,
|
|
GENERIC_READ,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL);
|
|
if (hFile1 == NULL || hFile1 == INVALID_HANDLE_VALUE) {
|
|
Status = GetLastError();
|
|
}
|
|
else {
|
|
CloseHandle(hFile1);
|
|
bReturn = CopyFileW(szThisFile, szBackupFile, FALSE);
|
|
if (bReturn != TRUE) {
|
|
Status = GetLastError();
|
|
}
|
|
}
|
|
TRACE((WINPERF_DBG_TRACE_INFO),
|
|
(& LoadPerfGuid,
|
|
__LINE__,
|
|
LOADPERF_GETINCLUDEFILENAME,
|
|
ARG_DEF(ARG_TYPE_WSTR, 1) | ARG_DEF(ARG_TYPE_WSTR, 2),
|
|
Status,
|
|
TRACE_WSTR(szThisFile),
|
|
TRACE_WSTR(szBackupFile),
|
|
NULL));
|
|
return bReturn;
|
|
}
|
|
|
|
void
|
|
LoadPerfRemovePreviousIniFile(
|
|
LPWSTR szIniName,
|
|
LPWSTR szDriverName
|
|
)
|
|
{
|
|
LPWSTR szInfPath = LoadPerfGetInfPath();
|
|
LPWSTR szIniPath = NULL;
|
|
LPWSTR szIniFile = NULL;
|
|
HANDLE hIniFile = NULL;
|
|
DWORD Status = ERROR_SUCCESS;
|
|
DWORD dwLength;
|
|
BOOL bContinue;
|
|
BOOL bDelete;
|
|
WIN32_FIND_DATAW FindFile;
|
|
HRESULT hr = S_OK;
|
|
|
|
if (szInfPath == NULL) {
|
|
Status = ERROR_INVALID_PARAMETER;
|
|
goto Cleanup;
|
|
}
|
|
dwLength = lstrlenW(szInfPath) + lstrlenW(szDriverName) + lstrlenW(szIniName) + 10;
|
|
if (dwLength < MAX_PATH) dwLength = MAX_PATH;
|
|
szIniPath = MemoryAllocate(2 * dwLength * sizeof(WCHAR));
|
|
if (szIniPath == NULL) {
|
|
Status = ERROR_OUTOFMEMORY;
|
|
goto Cleanup;
|
|
}
|
|
|
|
szIniFile = szIniPath + dwLength;
|
|
|
|
hr = StringCchPrintfW(szIniPath, dwLength, L"%ws0*", szInfPath);
|
|
if (SUCCEEDED(hr)) {
|
|
hIniFile = FindFirstFileExW(szIniPath, FindExInfoStandard, & FindFile, FindExSearchLimitToDirectories, NULL, 0);
|
|
if (hIniFile == NULL || hIniFile == INVALID_HANDLE_VALUE) {
|
|
TRACE((WINPERF_DBG_TRACE_INFO),
|
|
(& LoadPerfGuid,
|
|
__LINE__,
|
|
LOADPERF_GETINCLUDEFILENAME,
|
|
ARG_DEF(ARG_TYPE_WSTR, 1),
|
|
GetLastError(),
|
|
TRACE_WSTR(szIniPath),
|
|
NULL));
|
|
Status = ERROR_RESOURCE_LANG_NOT_FOUND;
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
else {
|
|
Status = HRESULT_CODE(hr);
|
|
goto Cleanup;
|
|
}
|
|
|
|
bContinue = TRUE;
|
|
while (bContinue) {
|
|
hr = StringCchPrintfW(szIniFile, dwLength, L"%ws%ws\\%ws\\%ws",
|
|
szInfPath, FindFile.cFileName, szDriverName, szIniName);
|
|
if (SUCCEEDED(hr)) {
|
|
bDelete = DeleteFileW(szIniFile);
|
|
dwLength = bDelete ? (ERROR_SUCCESS) : (GetLastError());
|
|
TRACE((WINPERF_DBG_TRACE_INFO),
|
|
(& LoadPerfGuid,
|
|
__LINE__,
|
|
LOADPERF_GETINCLUDEFILENAME,
|
|
ARG_DEF(ARG_TYPE_WSTR, 1),
|
|
dwLength,
|
|
TRACE_WSTR(szIniFile),
|
|
NULL));
|
|
}
|
|
bContinue = FindNextFileW(hIniFile, & FindFile);
|
|
}
|
|
|
|
Cleanup:
|
|
MemoryFree(szIniPath);
|
|
if (hIniFile != NULL && hIniFile != INVALID_HANDLE_VALUE) FindClose(hIniFile);
|
|
if (Status != ERROR_SUCCESS) SetLastError(Status);
|
|
return;
|
|
}
|
|
|
|
BOOL
|
|
LoadPerfBackupIniFile(
|
|
LPCWSTR szIniFile,
|
|
LPWSTR szLangId,
|
|
LPWSTR * szIniName,
|
|
LPWSTR * szDriverName,
|
|
BOOL bExtFile
|
|
)
|
|
// Caller InstallPerfDllW() should free allocated szIniName and szDriverName.
|
|
// Caller UpdatePerfNameFilesX() passes in NULL szIniName and szDriverName. No need to allocate.
|
|
{
|
|
BOOL bReturn = TRUE;
|
|
LPWSTR szIniFileName = NULL;
|
|
LPWSTR szIncFileName = NULL;
|
|
LPWSTR szInfPath = NULL;
|
|
LPWSTR szIncPath = NULL;
|
|
LPWSTR szDriver = NULL;
|
|
LPWSTR szIniTarget = NULL;
|
|
LPWSTR szIncTarget = NULL;
|
|
LPSTR szLangList = NULL;
|
|
LPSTR szLang = NULL;
|
|
LPSTR aszIniFile = NULL;
|
|
DWORD dwFileSize = 0;
|
|
DWORD dwSize;
|
|
DWORD dwUnicode = 0;
|
|
HRESULT hr;
|
|
|
|
if (szIniFile == NULL || lstrlenW(szIniFile) == 0) return FALSE;
|
|
if ((szInfPath = LoadPerfGetInfPath()) == NULL) return FALSE;
|
|
|
|
if (szIniName != NULL) * szIniName = NULL;
|
|
if (szDriverName != NULL) * szDriverName = NULL;
|
|
|
|
dwFileSize = LoadPerfGetFileSize((LPWSTR) szIniFile, & dwUnicode, TRUE);
|
|
if (dwFileSize < SMALL_BUFFER_SIZE) dwFileSize = SMALL_BUFFER_SIZE;
|
|
|
|
aszIniFile = LoadPerfWideCharToMultiByte(CP_ACP, (LPWSTR) szIniFile);
|
|
if (aszIniFile == NULL) return FALSE;
|
|
|
|
for (szIniFileName = (LPWSTR) szIniFile + lstrlenW(szIniFile) - 1;
|
|
szIniFileName != NULL && szIniFileName != szIniFile
|
|
&& (* szIniFileName) != cNull
|
|
&& (* szIniFileName) != cBackslash;
|
|
szIniFileName --);
|
|
if (szIniFileName != NULL && (* szIniFileName) == cBackslash) {
|
|
szIniFileName ++;
|
|
}
|
|
if (szIniFileName != NULL) {
|
|
if (szIniName != NULL) {
|
|
dwSize = lstrlenW(szIniFileName) + 1;
|
|
* szIniName = MemoryAllocate(sizeof(WCHAR) * dwSize);
|
|
if (* szIniName != NULL) {
|
|
hr = StringCchCopyW(* szIniName, dwSize, szIniFileName);
|
|
}
|
|
}
|
|
szIniTarget = MemoryAllocate(dwFileSize * sizeof(WCHAR));
|
|
if (szIniTarget == NULL) {
|
|
bReturn = FALSE;
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
|
|
if (bExtFile) {
|
|
bReturn = LoadPerfGetIncludeFileName(aszIniFile, dwFileSize, dwUnicode, & szIncPath, & szDriver);
|
|
if (bReturn != TRUE) goto Cleanup;
|
|
if (szDriver != NULL) {
|
|
if (szDriverName != NULL) {
|
|
dwSize = lstrlenW(szDriver) + 1;
|
|
* szDriverName = MemoryAllocate(sizeof(WCHAR) * dwSize);
|
|
if (* szDriverName != NULL) {
|
|
hr = StringCchCopyW(* szDriverName, dwSize, szDriver);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (szIncPath != NULL) {
|
|
for (szIncFileName = szIncPath + lstrlenW(szIncPath) - 1;
|
|
szIncFileName != NULL && szIncFileName != szIncPath
|
|
&& (* szIncFileName) != cNull
|
|
&& (* szIncFileName) != cBackslash;
|
|
szIncFileName --);
|
|
if (szIncFileName != NULL && (* szIncFileName) == cBackslash) {
|
|
szIncFileName ++;
|
|
}
|
|
}
|
|
|
|
hr = StringCchPrintfW(szIniTarget, dwFileSize, L"%sinc", szInfPath);
|
|
bReturn = LoadPerfCheckAndCreatePath(szIniTarget);
|
|
if (bReturn != TRUE) goto Cleanup;
|
|
|
|
hr = StringCchPrintfW(szIniTarget, dwFileSize, L"%sinc%s%ws%s", szInfPath, Slash, szDriver, Slash);
|
|
bReturn = LoadPerfCheckAndCreatePath(szIniTarget);
|
|
if (bReturn != TRUE) goto Cleanup;
|
|
|
|
if (szIncFileName != NULL) {
|
|
hr = StringCchCatW(szIniTarget, dwFileSize, szIncFileName);
|
|
bReturn = LoadPerfCheckAndCopyFile(szIncPath, szIniTarget);
|
|
}
|
|
if (bReturn != TRUE) goto Cleanup;
|
|
|
|
szLangList = MemoryAllocate(dwFileSize * sizeof(CHAR));
|
|
if (szLangList == NULL) {
|
|
bReturn = FALSE;
|
|
goto Cleanup;
|
|
}
|
|
|
|
LoadPerfRemovePreviousIniFile(szIniFileName, szDriver);
|
|
|
|
dwSize = GetPrivateProfileStringA(szLanguages, NULL, aszDefaultLangId, szLangList, dwFileSize, aszIniFile);
|
|
for (szLang = szLangList;
|
|
bReturn && szLang != NULL && szLang[0] != '\0';
|
|
szLang += (lstrlenA(szLang) + 1)) {
|
|
LPWSTR szTmpLang = LoadPerfMultiByteToWideChar(CP_ACP, szLang);
|
|
if (szTmpLang != NULL) {
|
|
LPWSTR szThisLang = LoadPerfGetLanguage(szTmpLang, FALSE);
|
|
|
|
ZeroMemory(szIniTarget, sizeof(WCHAR) * dwFileSize);
|
|
hr = StringCchPrintfW(szIniTarget, dwFileSize, L"%s%s%s", szInfPath, szThisLang, Slash);
|
|
bReturn = LoadPerfCheckAndCreatePath(szIniTarget);
|
|
if (bReturn != TRUE) goto Cleanup;
|
|
|
|
hr = StringCchPrintfW(szIniTarget, dwFileSize, L"%s%s%s%ws%s",
|
|
szInfPath, szThisLang, Slash, szDriver, Slash);
|
|
bReturn = LoadPerfCheckAndCreatePath(szIniTarget);
|
|
if (bReturn) {
|
|
hr = StringCchCatW(szIniTarget, dwFileSize, szIniFileName);
|
|
bReturn = LoadPerfCheckAndCopyFile(szIniFile, szIniTarget);
|
|
}
|
|
MemoryFree(szTmpLang);
|
|
}
|
|
else {
|
|
bReturn = FALSE;
|
|
}
|
|
}
|
|
}
|
|
else if (szLangId != NULL && szIniFileName != NULL) {
|
|
LPWSTR szThisLang = LoadPerfGetLanguage(szLangId, FALSE);
|
|
|
|
hr = StringCchPrintfW(szIniTarget, dwFileSize, L"%s%s%s", szInfPath, szThisLang, Slash);
|
|
bReturn = LoadPerfCheckAndCreatePath(szIniTarget);
|
|
if (bReturn) {
|
|
hr = StringCchCatW(szIniTarget, dwFileSize, szIniFileName);
|
|
bReturn = LoadPerfCheckAndCopyFile(szIniFile, szIniTarget);
|
|
}
|
|
}
|
|
else {
|
|
bReturn = FALSE;
|
|
}
|
|
|
|
Cleanup:
|
|
MemoryFree(aszIniFile);
|
|
MemoryFree(szIncPath);
|
|
MemoryFree(szDriver);
|
|
MemoryFree(szIniTarget);
|
|
MemoryFree(szLangList);
|
|
return bReturn;
|
|
}
|
|
|
|
typedef struct _LOADPERF_LANG_INFO {
|
|
WORD dwLCID;
|
|
int cpAnsi;
|
|
int cpOem;
|
|
int cpMac;
|
|
LPCWSTR szName;
|
|
LPCWSTR szShotName;
|
|
} LOADPERF_LANG_INFO, * PLOADPERF_LANG_INFO;
|
|
|
|
const LOADPERF_LANG_INFO LocaleTable[] = {
|
|
{ 0x0401, 1256, 720, 10004, L"Arabic (Saudi Arabia)", L"ARA" },
|
|
// { 0x0801, 1256, 720, 10004, L"Arabic (Iraq)", L"ARI" },
|
|
// { 0x0c01, 1256, 720, 10004, L"Arabic (Egypt)", L"ARE" },
|
|
// { 0x1001, 1256, 720, 10004, L"Arabic (Libya)", L"ARL" },
|
|
// { 0x1401, 1256, 720, 10004, L"Arabic (Algeria)", L"ARG" },
|
|
// { 0x1801, 1256, 720, 10004, L"Arabic (Morocco)", L"ARM" },
|
|
// { 0x1c01, 1256, 720, 10004, L"Arabic (Tunisia)", L"ART" },
|
|
// { 0x2001, 1256, 720, 10004, L"Arabic (Oman)", L"ARO" },
|
|
// { 0x2401, 1256, 720, 10004, L"Arabic (Yemen)", L"ARY" },
|
|
// { 0x2801, 1256, 720, 10004, L"Arabic (Syria)", L"ARS" },
|
|
// { 0x2c01, 1256, 720, 10004, L"Arabic (Jordan)", L"ARJ" },
|
|
// { 0x3001, 1256, 720, 10004, L"Arabic (Lebanon)", L"ARB" },
|
|
// { 0x3401, 1256, 720, 10004, L"Arabic (Kuwait)", L"ARK" },
|
|
// { 0x3801, 1256, 720, 10004, L"Arabic (U.A.E.)", L"ARU" },
|
|
// { 0x3c01, 1256, 720, 10004, L"Arabic (Bahrain)", L"ARH" },
|
|
// { 0x4001, 1256, 720, 10004, L"Arabic (Qatar)", L"ARQ" },
|
|
{ 0x0402, 1251, 866, 10007, L"Bulgarian (Bulgaria)", L"BGR" },
|
|
// { 0x0403, 1252, 850, 10000, L"Catalan (Spain)", L"CAT" },
|
|
{ 0x0404, 950, 950, 10002, L"Chinese(Taiwan) (Taiwan)", L"CHT" },
|
|
{ 0x0804, 936, 936, 10008, L"Chinese(PRC) (People's Republic of China)", L"CHS" },
|
|
// { 0x0c04, 936, 936, 10002, L"Chinese(Hong Kong) (Hong Kong)", L"ZHH" },
|
|
// { 0x1004, 936, 936, 10008, L"Chinese(Singapore) (Singapore)", L"ZHI" },
|
|
// { 0x1404, 936, 936, 10002, L"Chinese(Macau) (Macau)", L"ZHM" },
|
|
{ 0x0405, 1250, 852, 10029, L"Czech (Czech Republic)", L"CSY" },
|
|
{ 0x0406, 1252, 850, 10000, L"Danish (Denmark)", L"DAN" },
|
|
{ 0x0407, 1252, 850, 10000, L"German (Germany)", L"DEU" },
|
|
// { 0x0807, 1252, 850, 10000, L"German (Switzerland)", L"DES" },
|
|
// { 0x0c07, 1252, 850, 10000, L"German (Austria)", L"DEA" },
|
|
// { 0x1007, 1252, 850, 10000, L"German (Luxembourg)", L"DEL" },
|
|
// { 0x1407, 1252, 850, 10000, L"German (Liechtenstein)", L"DEC" },
|
|
{ 0x0408, 1253, 737, 10006, L"Greek (Greece)", L"ELL" },
|
|
// { 0x2008, 1253, 869, 10006, L"Greek 2 (Greece)", L"ELL" },
|
|
{ 0x0409, 1252, 437, 10000, L"English (United States)", L"ENU" },
|
|
// { 0x0809, 1252, 850, 10000, L"English (United Kingdom)", L"ENG" },
|
|
// { 0x0c09, 1252, 850, 10000, L"English (Australia)", L"ENA" },
|
|
// { 0x1009, 1252, 850, 10000, L"English (Canada)", L"ENC" },
|
|
// { 0x1409, 1252, 850, 10000, L"English (New Zealand)", L"ENZ" },
|
|
// { 0x1809, 1252, 850, 10000, L"English (Ireland)", L"ENI" },
|
|
// { 0x1c09, 1252, 437, 10000, L"English (South Africa)", L"ENS" },
|
|
// { 0x2009, 1252, 850, 10000, L"English (Jamaica)", L"ENJ" },
|
|
// { 0x2409, 1252, 850, 10000, L"English (Caribbean)", L"ENB" },
|
|
// { 0x2809, 1252, 850, 10000, L"English (Belize)", L"ENL" },
|
|
// { 0x2c09, 1252, 850, 10000, L"English (Trinidad y Tobago)", L"ENT" },
|
|
// { 0x3009, 1252, 437, 10000, L"English (Zimbabwe)", L"ENW" },
|
|
// { 0x3409, 1252, 437, 10000, L"English (Republic of the Philippines)", L"ENP" },
|
|
// { 0x040a, 1252, 850, 10000, L"Spanish - Traditional Sort (Spain)", L"ESP" },
|
|
// { 0x080a, 1252, 850, 10000, L"Spanish (Mexico)", L"ESM" },
|
|
{ 0x0c0a, 1252, 850, 10000, L"Spanish - International Sort (Spain)", L"ESN" },
|
|
// { 0x100a, 1252, 850, 10000, L"Spanish (Guatemala)", L"ESG" },
|
|
// { 0x140a, 1252, 850, 10000, L"Spanish (Costa Rica)", L"ESC" },
|
|
// { 0x180a, 1252, 850, 10000, L"Spanish (Panama)", L"ESA" },
|
|
// { 0x1c0a, 1252, 850, 10000, L"Spanish (Dominican Republic)", L"ESD" },
|
|
// { 0x200a, 1252, 850, 10000, L"Spanish (Venezuela)", L"ESV" },
|
|
// { 0x240a, 1252, 850, 10000, L"Spanish (Colombia)", L"ESO" },
|
|
// { 0x280a, 1252, 850, 10000, L"Spanish (Peru)", L"ESR" },
|
|
// { 0x2c0a, 1252, 850, 10000, L"Spanish (Argentina)", L"ESS" },
|
|
// { 0x300a, 1252, 850, 10000, L"Spanish (Ecuador)", L"ESF" },
|
|
// { 0x340a, 1252, 850, 10000, L"Spanish (Chile)", L"ESL" },
|
|
// { 0x380a, 1252, 850, 10000, L"Spanish (Uruguay)", L"ESY" },
|
|
// { 0x3c0a, 1252, 850, 10000, L"Spanish (Paraguay)", L"ESZ" },
|
|
// { 0x400a, 1252, 850, 10000, L"Spanish (Bolivia)", L"ESB" },
|
|
// { 0x440a, 1252, 850, 10000, L"Spanish (El Salvador)", L"ESE" },
|
|
// { 0x480a, 1252, 850, 10000, L"Spanish (Honduras)", L"ESH" },
|
|
// { 0x4c0a, 1252, 850, 10000, L"Spanish (Nicaragua)", L"ESI" },
|
|
// { 0x500a, 1252, 850, 10000, L"Spanish (Puerto Rico)", L"ESU" },
|
|
{ 0x040b, 1252, 850, 10000, L"Finnish (Finland)", L"FIN" },
|
|
{ 0x040c, 1252, 850, 10000, L"French (France)", L"FRA" },
|
|
// { 0x080c, 1252, 850, 10000, L"French (Belgium)", L"FRB" },
|
|
// { 0x0c0c, 1252, 850, 10000, L"French (Canada)", L"FRC" },
|
|
// { 0x100c, 1252, 850, 10000, L"French (Switzerland)", L"FRS" },
|
|
// { 0x140c, 1252, 850, 10000, L"French (Luxembourg)", L"FRL" },
|
|
// { 0x180c, 1252, 850, 10000, L"French (Principality of Monaco)", L"FRM" },
|
|
{ 0x040d, 1255, 862, 10005, L"Hebrew (Israel)", L"HEB" },
|
|
{ 0x040e, 1250, 852, 10029, L"Hungarian (Hungary)", L"HUN" },
|
|
// { 0x040f, 1252, 850, 10079, L"Icelandic (Iceland)", L"ISL" },
|
|
{ 0x0410, 1252, 850, 10000, L"Italian (Italy)", L"ITA" },
|
|
// { 0x0810, 1252, 850, 10000, L"Italian (Switzerland)", L"ITS" },
|
|
{ 0x0411, 932, 932, 10001, L"Japanese (Japan)", L"JPN" },
|
|
{ 0x0412, 949, 949, 10003, L"Korean (Korea)", L"KOR" },
|
|
{ 0x0413, 1252, 850, 10000, L"Dutch (Netherlands)", L"NLD" },
|
|
// { 0x0813, 1252, 850, 10000, L"Dutch (Belgium)", L"NLB" },
|
|
{ 0x0414, 1252, 850, 10000, L"Norwegian (Bokml) (Norway)", L"NOR" },
|
|
// { 0x0814, 1252, 850, 10000, L"Norwegian (Nynorsk) (Norway)", L"NON" },
|
|
{ 0x0415, 1250, 852, 10029, L"Polish (Poland)", L"PLK" },
|
|
{ 0x0416, 1252, 850, 10000, L"Portuguese (Brazil)", L"PTB" },
|
|
{ 0x0816, 1252, 850, 10000, L"Portuguese (Portugal)", L"PTG" },
|
|
{ 0x0418, 1250, 852, 10029, L"Romanian (Romania)", L"ROM" },
|
|
{ 0x0419, 1251, 866, 10007, L"Russian (Russia)", L"RUS" },
|
|
{ 0x041a, 1250, 852, 10082, L"Croatian (Croatia)", L"HRV" },
|
|
// { 0x081a, 1250, 852, 10029, L"Serbian (Latin) (Serbia)", L"SRL" },
|
|
// { 0x0c1a, 1251, 855, 10007, L"Serbian (Cyrillic) (Serbia)", L"SRB" },
|
|
{ 0x041b, 1250, 852, 10029, L"Slovak (Slovakia)", L"SKY" },
|
|
// { 0x041c, 1250, 852, 10029, L"Albanian (Albania)", L"SQI" },
|
|
{ 0x041d, 1252, 850, 10000, L"Swedish (Sweden)", L"SVE" },
|
|
// { 0x081d, 1252, 850, 10000, L"Swedish (Finland)", L"SVF" },
|
|
{ 0x041e, 874, 874, 10000, L"Thai (Thailand)", L"THA" },
|
|
{ 0x041f, 1254, 857, 10081, L"Turkish (Turkey)", L"TRK" },
|
|
// { 0x0420, 1256, 720, 10004, L"Urdu (Islamic Republic of Pakistan)", L"URP" },
|
|
// { 0x0421, 1252, 850, 10000, L"Indonesian (Indonesia)", L"IND" },
|
|
// { 0x0422, 1251, 866, 10017, L"Ukrainian (Ukraine)", L"UKR" },
|
|
// { 0x0423, 1251, 866, 10007, L"Belarusian (Belarus)", L"BEL" },
|
|
{ 0x0424, 1250, 852, 10029, L"Slovenian (Slovenia)", L"SLV" },
|
|
{ 0x0425, 1257, 775, 10029, L"Estonian (Estonia)", L"ETI" },
|
|
{ 0x0426, 1257, 775, 10029, L"Latvian (Latvia)", L"LVI" },
|
|
{ 0x0427, 1257, 775, 10029, L"Lithuanian (Lithuania)", L"LTH" }
|
|
// { 0x0827, 1257, 775, 10029, L"Classic Lithuanian (Lithuania)", L"LTC" },
|
|
// { 0x0429, 1256, 720, 10004, L"Farsi (Iran)", L"FAR" },
|
|
// { 0x042a, 1258, 1258, 10000, L"Vietnamese (Viet Nam)", L"VIT" },
|
|
// { 0x042b, 1252, 850, 10000, L"Armenian (Republic of Armenia)", L"HYE" },
|
|
// { 0x042c, 1250, 852, 10029, L"Azeri (Azerbaijan)", L"AZE" },
|
|
// { 0x082c, 1251, 866, 10007, L"Azeri (Azerbaijan)", L"AZE" },
|
|
// { 0x042d, 1252, 850, 10000, L"Basque (Spain)", L"EUQ" },
|
|
// { 0x042f, 1251, 866, 10007, L"Macedonian (Former Yugoslav Republic of Macedonia)", L"MKI" },
|
|
// { 0x0436, 1252, 850, 10000, L"Afrikaans (South Africa)", L"AFK" },
|
|
// { 0x0437, 1252, 850, 10000, L"Georgian (Georgia)", L"KAT" },
|
|
// { 0x0438, 1252, 850, 10079, L"Faeroese (Faeroe Islands)", L"FOS" },
|
|
// { 0x0439, 1252, 850, 10000, L"Hindi (India)", L"HIN" },
|
|
// { 0x043e, 1252, 850, 10000, L"Malay (Malaysia)", L"MSL" },
|
|
// { 0x083e, 1252, 850, 10000, L"Malay (Brunei Darussalam)", L"MSB" },
|
|
// { 0x043f, 1251, 866, 10007, L"Kazak (Kazakstan)", L"KAZ" },
|
|
// { 0x0441, 1252, 437, 10000, L"Swahili (Kenya)", L"SWK" },
|
|
// { 0x0443, 1250, 852, 10029, L"Uzbek (Republic of Uzbekistan)", L"UZB" },
|
|
// { 0x0843, 1251, 866, 10007, L"Uzbek (Republic of Uzbekistan)", L"UZB" },
|
|
// { 0x0444, 1251, 866, 10007, L"Tatar (Tatarstan)", L"TAT" },
|
|
// { 0x0445, 1252, 850, 10000, L"Bengali (India)", L"BEN" },
|
|
// { 0x0446, 1252, 850, 10000, L"Punjabi (India)", L"PAN" },
|
|
// { 0x0447, 1252, 850, 10000, L"Gujarati (India)", L"GUJ" },
|
|
// { 0x0448, 1252, 850, 10000, L"Oriya (India)", L"ORI" },
|
|
// { 0x0449, 1252, 850, 10000, L"Tamil (India)", L"TAM" },
|
|
// { 0x044a, 1252, 850, 10000, L"Telugu (India)", L"TEL" },
|
|
// { 0x044b, 1252, 850, 10000, L"Kannada (India)", L"KAN" },
|
|
// { 0x044c, 1252, 850, 10000, L"Malayalam (India)", L"MAL" },
|
|
// { 0x044d, 1252, 850, 10000, L"Assamese (India)", L"ASM" },
|
|
// { 0x044e, 1252, 850, 10000, L"Marathi (India)", L"MAR" },
|
|
// { 0x044f, 1252, 850, 10000, L"Sanskrit (India)", L"SAN" },
|
|
// { 0x0457, 1252, 850, 10000, L"Konkani (India)", L"KOK" }
|
|
};
|
|
const DWORD dwLocaleSize = sizeof(LocaleTable) / sizeof(LOADPERF_LANG_INFO);
|
|
|
|
WORD
|
|
LoadPerfGetLCIDFromString(
|
|
LPWSTR szLangId
|
|
)
|
|
{
|
|
WORD dwLangId = 0;
|
|
DWORD dwLangLen = lstrlenW(szLangId);
|
|
DWORD i;
|
|
WCHAR szDigit;
|
|
|
|
for (i = 0; i < dwLangLen; i ++) {
|
|
dwLangId <<= 4;
|
|
szDigit = szLangId[i];
|
|
if (szDigit >= L'0' && szDigit <= L'9') {
|
|
dwLangId += (szDigit - L'0');
|
|
}
|
|
else if (szDigit >= L'a' && szDigit <= L'f') {
|
|
dwLangId += (10 + szDigit - L'a');
|
|
}
|
|
else if (szDigit >= L'A' && szDigit <= L'F') {
|
|
dwLangId += (10 + szDigit - L'A');
|
|
}
|
|
else {
|
|
dwLangId = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return dwLangId;
|
|
}
|
|
|
|
int
|
|
LoadPerfGetCodePage(
|
|
LPWSTR szLCID
|
|
)
|
|
{
|
|
int CP_Ansi = CP_ACP;
|
|
int CP_Oem = CP_OEMCP;
|
|
int dwStart = 0;
|
|
int dwEnd = dwLocaleSize - 1;
|
|
int dwThis;
|
|
WORD thisLCID;
|
|
WORD thisprimaryLCID;
|
|
WORD primaryLCID;
|
|
|
|
thisLCID = LoadPerfGetLCIDFromString(szLCID);
|
|
thisprimaryLCID = PRIMARYLANGID(thisLCID);
|
|
|
|
while (dwStart <= dwEnd) {
|
|
dwThis = (dwEnd + dwStart) / 2;
|
|
primaryLCID = PRIMARYLANGID(LocaleTable[dwThis].dwLCID);
|
|
if (LocaleTable[dwThis].dwLCID == thisLCID) {
|
|
CP_Ansi = LocaleTable[dwThis].cpAnsi;
|
|
CP_Oem = LocaleTable[dwThis].cpOem;
|
|
break;
|
|
}
|
|
else if (primaryLCID < thisprimaryLCID) {
|
|
dwStart = dwThis + 1;
|
|
}
|
|
else {
|
|
dwEnd = dwThis - 1;
|
|
}
|
|
}
|
|
if (dwStart > dwEnd) {
|
|
dwStart = 0;
|
|
dwEnd = dwLocaleSize - 1;
|
|
while (dwStart <= dwEnd) {
|
|
dwThis = (dwEnd + dwStart) / 2;
|
|
primaryLCID = PRIMARYLANGID(LocaleTable[dwThis].dwLCID);
|
|
if (primaryLCID == thisprimaryLCID) {
|
|
CP_Ansi = LocaleTable[dwThis].cpAnsi;
|
|
CP_Oem = LocaleTable[dwThis].cpOem;
|
|
break;
|
|
}
|
|
else if (primaryLCID < thisprimaryLCID) {
|
|
dwStart = dwThis + 1;
|
|
}
|
|
else {
|
|
dwEnd = dwThis - 1;
|
|
}
|
|
}
|
|
}
|
|
return CP_Ansi;
|
|
}
|
|
|
|
LPSTR
|
|
LoadPerfWideCharToMultiByte(
|
|
UINT CodePage,
|
|
LPWSTR wszString
|
|
)
|
|
{
|
|
// Callers need to free returned string buffer.
|
|
// LoadPerfBackupIniFile()
|
|
// LodctrSetServiceAsTructed()
|
|
// LoadIncludeFile()
|
|
// CreateObjectList()
|
|
// LoadLanguageList()
|
|
|
|
LPSTR aszString = NULL;
|
|
int dwValue = WideCharToMultiByte(CodePage, 0, wszString, -1, NULL, 0, NULL, NULL);
|
|
if (dwValue != 0) {
|
|
aszString = MemoryAllocate((dwValue + 1) * sizeof(CHAR));
|
|
if (aszString != NULL) {
|
|
WideCharToMultiByte(CodePage, 0, wszString, -1, aszString, dwValue + 1, NULL, NULL);
|
|
}
|
|
}
|
|
return aszString;
|
|
}
|
|
|
|
LPWSTR
|
|
LoadPerfMultiByteToWideChar(
|
|
UINT CodePage,
|
|
LPSTR aszString
|
|
)
|
|
{
|
|
// Callers need to free returned string buffer.
|
|
// UnloadPerfCounterTextStringsA()
|
|
// LoadPerfGetIncludeFileName(), which relies on caller LoadPerfBackupIniFile() to free this.
|
|
// LoadPerfBackupIniFile()
|
|
// BuildLanguageTables()
|
|
// LoadIncludeFile(). The string is part of SYMBOL_TABLE_ENTRY structure and will be freed at the end
|
|
// of LoadPerfInstallPerfDll().
|
|
// GetValue(), which relies on AddEntryToLanguage() (which calls GetValueFromIniKey() then calls GetValue())
|
|
// to free memory lpLocalStringBuff.
|
|
// CreateObjectList()
|
|
// LoadLanguageLists()
|
|
// InstallPerfDllA()
|
|
// LoadPerfCounterTextStringsA()
|
|
// UpdatePerfNameFilesA()
|
|
// SetServiceAsTrustedA()
|
|
|
|
LPWSTR wszString = NULL;
|
|
int dwValue = MultiByteToWideChar(CodePage, 0, aszString, -1, NULL, 0);
|
|
if (dwValue != 0) {
|
|
wszString = MemoryAllocate((dwValue + 1) * sizeof(WCHAR));
|
|
if (wszString != NULL) {
|
|
MultiByteToWideChar(CodePage, 0, aszString, -1, wszString, dwValue + 1);
|
|
}
|
|
}
|
|
return wszString;
|
|
}
|
|
|
|
DWORD
|
|
LoadPerfGetFileSize(
|
|
LPWSTR szFileName,
|
|
LPDWORD pdwUnicode,
|
|
BOOL bUnicode
|
|
)
|
|
{
|
|
DWORD dwFileSize = 0;
|
|
HANDLE hFile = NULL;
|
|
|
|
if (bUnicode) {
|
|
hFile = CreateFileW(
|
|
szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
}
|
|
else {
|
|
hFile = CreateFileA(
|
|
(LPSTR) szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
}
|
|
if (hFile != NULL && hFile != INVALID_HANDLE_VALUE) {
|
|
dwFileSize = GetFileSize(hFile, NULL);
|
|
|
|
if (pdwUnicode != NULL) {
|
|
DWORD dwRead = dwFileSize;
|
|
DWORD dwType = IS_TEXT_UNICODE_NULL_BYTES;
|
|
LPBYTE pBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwFileSize);
|
|
BOOL bResult;
|
|
|
|
* pdwUnicode = 0;
|
|
if (pBuffer != NULL) {
|
|
bResult = ReadFile(hFile, (LPVOID) pBuffer, dwFileSize, & dwRead, NULL);
|
|
if (bResult) {
|
|
bResult = IsTextUnicode((LPVOID) pBuffer, dwRead, & dwType);
|
|
* pdwUnicode = bResult ? 1 : 0;
|
|
}
|
|
HeapFree(GetProcessHeap(), 0, pBuffer);
|
|
}
|
|
}
|
|
CloseHandle(hFile);
|
|
}
|
|
return dwFileSize;
|
|
}
|
|
|
|
LPCWSTR cszWmiLoadEventName = L"WMI_SysEvent_LodCtr";
|
|
LPCWSTR cszWmiUnloadEventName = L"WMI_SysEvent_UnLodCtr";
|
|
|
|
DWORD LoadPerfSignalWmiWithNewData(DWORD dwEventId)
|
|
{
|
|
HANDLE hEvent;
|
|
DWORD dwStatus = ERROR_SUCCESS;
|
|
|
|
LPWSTR szEventName = NULL;
|
|
|
|
switch (dwEventId) {
|
|
case WMI_LODCTR_EVENT:
|
|
szEventName = (LPWSTR) cszWmiLoadEventName;
|
|
break;
|
|
|
|
case WMI_UNLODCTR_EVENT:
|
|
szEventName = (LPWSTR) cszWmiUnloadEventName;
|
|
break;
|
|
|
|
default:
|
|
dwStatus = ERROR_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
|
|
if (dwStatus == ERROR_SUCCESS) {
|
|
hEvent = OpenEventW(EVENT_MODIFY_STATE | SYNCHRONIZE, FALSE, szEventName);
|
|
if (hEvent != NULL) {
|
|
// set event
|
|
SetEvent(hEvent);
|
|
CloseHandle(hEvent);
|
|
}
|
|
else {
|
|
dwStatus = GetLastError();
|
|
}
|
|
|
|
}
|
|
return dwStatus;
|
|
}
|