windows-nt/Source/XPSP1/NT/sdktools/pdh/pdhdll/dllinit.c
2020-09-26 16:20:57 +08:00

442 lines
12 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1995-1999 Microsoft Corporation
Module Name:
dllinit.c
Abstract:
This module contians the DLL attach/detach event entry point for
the pdh.dll
Author:
Bob Watson (a-robw) Jul 95
Revision History:
--*/
#include <windows.h>
#include <assert.h>
#include "pdhitype.h"
#include "pdhidef.h"
#include "pdhmsg.h"
#include "strings.h"
#include "pdhp.h"
HANDLE ThisDLLHandle = NULL;
WCHAR szStaticLocalMachineName[MAX_PATH] = {0};
HANDLE hPdhDataMutex = NULL;
HANDLE hPdhContextMutex = NULL;
HANDLE hPdhHeap = NULL;
HANDLE hEventLog = NULL;
LONGLONG llRemoteRetryTime = RETRY_TIME_INTERVAL;
BOOL bEnableRemotePdhAccess = TRUE;
DWORD dwPdhiLocalDefaultDataSource = DATA_SOURCE_REGISTRY;
LONG dwCurrentRealTimeDataSource = 0;
BOOL bProcessIsDetaching = FALSE;
LPWSTR
GetStringResource (
DWORD dwResId
)
{
LPWSTR szReturnString = NULL;
LPWSTR szTmpString = NULL;
DWORD dwStrLen = (2048 * sizeof(WCHAR));
szReturnString = (LPWSTR) G_ALLOC (dwStrLen);
if (szReturnString != NULL) {
dwStrLen /= sizeof(WCHAR);
dwStrLen = LoadStringW (
ThisDLLHandle,
(UINT)dwResId,
szReturnString,
dwStrLen);
if (dwStrLen > 0) {
// then realloc down to the size used
dwStrLen++; // to include the NULL
dwStrLen *= sizeof (WCHAR);
szTmpString = szReturnString;
szReturnString = G_REALLOC (szReturnString, dwStrLen);
if (szReturnString == NULL) {
G_FREE(szTmpString);
szTmpString = NULL;
}
} else {
// free the memory since the look up failed
G_FREE (szReturnString);
szReturnString = NULL;
}
} //else allocation failed
return szReturnString;
}
STATIC_BOOL
PdhiOpenEventLog (
HANDLE *phEventLogHandle
)
{
HANDLE hReturn;
BOOL bReturn;
if ((hReturn = RegisterEventSourceW (
NULL, // on the local machine
cszAppShortName // for the PDH.DLL
)) != NULL) {
*phEventLogHandle = hReturn;
bReturn = TRUE;
} else {
bReturn = FALSE;
}
return bReturn;
}
STATIC_BOOL
PdhiGetRegistryDefaults ()
{
DWORD dwStatus;
DWORD dwType, dwSize, dwValue;
HKEY hKeyPDH;
// the local data source is not initialized so use it
dwStatus = RegOpenKeyExW (
HKEY_LOCAL_MACHINE,
cszPdhKey,
0L,
KEY_READ,
&hKeyPDH);
if (dwStatus == ERROR_SUCCESS) {
//
// get the default null data source
//
dwValue = 0;
dwType = 0;
dwSize = sizeof (dwValue);
dwStatus = RegQueryValueExW (
hKeyPDH,
cszDefaultNullDataSource,
NULL,
&dwType,
(LPBYTE)&dwValue,
&dwSize);
if (!(dwStatus == ERROR_SUCCESS) || !(dwType == REG_DWORD)) {
dwValue = DATA_SOURCE_REGISTRY;
} else {
// check the value for validity
switch (dwValue) {
case DATA_SOURCE_WBEM:
case DATA_SOURCE_REGISTRY:
// this is OK
break;
case DATA_SOURCE_LOGFILE:
default:
// these are not OK so insert default
dwValue = DATA_SOURCE_REGISTRY;
break;
}
}
dwPdhiLocalDefaultDataSource = dwValue;
//
// get the retry timeout
//
dwValue = 0;
dwType = 0;
dwSize = sizeof (dwValue);
dwStatus = RegQueryValueExW (
hKeyPDH,
cszRemoteMachineRetryTime,
NULL,
&dwType,
(LPBYTE)&dwValue,
&dwSize);
if (!(dwStatus == ERROR_SUCCESS) || !(dwType == REG_DWORD)) {
dwValue = 0;
} else {
// check the value for validity
// must be 30 seconds or more yet no more than an hour
if ((dwValue <= 30) || (dwValue > 3600)) {
dwValue = 0;
}
}
if (dwValue != 0) {
// convert to 100NS units
llRemoteRetryTime = dwValue * 10000000;
} else {
// use default
llRemoteRetryTime = RETRY_TIME_INTERVAL;
}
//
// get the remote access mode
//
dwValue = 0;
dwType = 0;
dwSize = sizeof (dwValue);
dwStatus = RegQueryValueExW (
hKeyPDH,
cszEnableRemotePdhAccess,
NULL,
&dwType,
(LPBYTE)&dwValue,
&dwSize);
if (!(dwStatus == ERROR_SUCCESS) || !(dwType == REG_DWORD)) {
dwValue = TRUE;
} else {
// check the value for validity
if (dwValue != 0) {
dwValue = TRUE;
}
}
bEnableRemotePdhAccess = (BOOL)dwValue;
// close the registry key
RegCloseKey (hKeyPDH);
}
return TRUE;
}
STATIC_BOOL
PdhiCloseEventLog (
HANDLE * phEventLogHandle
)
{
BOOL bReturn;
if (*phEventLogHandle != NULL) {
bReturn = DeregisterEventSource (*phEventLogHandle);
*phEventLogHandle = NULL;
} else {
// it's already closed so that's OK
bReturn = TRUE;
}
return bReturn;
}
HRESULT
PdhiPlaInitMutex()
{
HRESULT hr = ERROR_SUCCESS;
BOOL bResult = TRUE;
PSECURITY_DESCRIPTOR SD = NULL;
SECURITY_ATTRIBUTES sa;
PSID AuthenticatedUsers = NULL;
PSID BuiltInAdministrators = NULL;
PSID NetworkService = NULL;
DWORD dwAclSize;
ACL *Acl;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
bResult = AllocateAndInitializeSid(
&NtAuthority,
2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0,0,0,0,0,0,
&BuiltInAdministrators);
if( !bResult ){goto cleanup;}
bResult = AllocateAndInitializeSid(
&NtAuthority,
1,
SECURITY_AUTHENTICATED_USER_RID,
0,0,0,0,0,0,0,
&AuthenticatedUsers);
if( !bResult ){goto cleanup;}
bResult = AllocateAndInitializeSid(
&NtAuthority,
1,
SECURITY_NETWORK_SERVICE_RID,
0,0,0,0,0,0,0,
&NetworkService);
if( !bResult ){goto cleanup;}
dwAclSize = sizeof (ACL) +
(3 * (sizeof (ACCESS_ALLOWED_ACE) - sizeof (ULONG))) +
GetLengthSid(AuthenticatedUsers) +
GetLengthSid(BuiltInAdministrators) +
GetLengthSid(NetworkService);
SD = (PSECURITY_DESCRIPTOR)G_ALLOC(SECURITY_DESCRIPTOR_MIN_LENGTH + dwAclSize);
if( NULL == SD ){ goto cleanup; }
ZeroMemory( SD, sizeof(SD) );
Acl = (ACL *)((BYTE *)SD + SECURITY_DESCRIPTOR_MIN_LENGTH);
bResult = InitializeAcl( Acl, dwAclSize, ACL_REVISION);
if( !bResult ){goto cleanup;}
bResult = AddAccessAllowedAce(Acl, ACL_REVISION, SYNCHRONIZE | GENERIC_READ, AuthenticatedUsers );
if( !bResult ){goto cleanup;}
bResult = AddAccessAllowedAce(Acl, ACL_REVISION, MUTEX_ALL_ACCESS , NetworkService );
if( !bResult ){goto cleanup;}
bResult = AddAccessAllowedAce(Acl, ACL_REVISION, GENERIC_ALL, BuiltInAdministrators );
if( !bResult ){goto cleanup;}
bResult = InitializeSecurityDescriptor(SD, SECURITY_DESCRIPTOR_REVISION);
if( !bResult ){goto cleanup;}
bResult = SetSecurityDescriptorDacl(SD, TRUE, Acl, FALSE);
if( !bResult ){goto cleanup;}
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = SD;
sa.bInheritHandle = FALSE;
hPdhPlaMutex = CreateMutexW( &sa, FALSE, PDH_PLA_MUTEX );
cleanup:
if( hPdhPlaMutex == NULL || !bResult ){
hr = GetLastError();
}
if( NULL != AuthenticatedUsers ){
FreeSid(AuthenticatedUsers);
}
if( NULL != BuiltInAdministrators){
FreeSid(BuiltInAdministrators);
}
if( NULL != NetworkService){
FreeSid(NetworkService);
}
G_FREE(SD);
return hr;
}
BOOL
_stdcall
PdhDllInitRoutine(
IN HANDLE DLLHandle,
IN DWORD Reason,
IN LPVOID ReservedAndUnused
)
{
BOOL bStatus;
BOOL bReturn = TRUE;
OSVERSIONINFOW os;
ReservedAndUnused;
switch(Reason) {
case DLL_PROCESS_ATTACH:
bProcessIsDetaching = FALSE;
{
DWORD dwBufferLength = 0;
ThisDLLHandle = DLLHandle;
// make sure this is the correct operating system
memset (&os, 0, sizeof(os));
os.dwOSVersionInfoSize = sizeof(os);
bReturn = GetVersionExW (&os);
if (bReturn) {
// check for windows NT v4.0
if (os.dwPlatformId != VER_PLATFORM_WIN32_NT) {
// not WINDOWS NT
bReturn = FALSE;
} else if (os.dwMajorVersion < 4) {
// it's windows NT, but an old one
bReturn = FALSE;
}
} else {
// unable to read version so give up
}
if (bReturn) {
// disable thread init calls
DisableThreadLibraryCalls (DLLHandle);
// initialize the event log so events can be reported
bStatus = PdhiOpenEventLog (&hEventLog);
bStatus = PdhiGetRegistryDefaults ();
// initialize the local computer name buffer
if (szStaticLocalMachineName[0] == 0) {
// initialize the computer name for this computer
szStaticLocalMachineName[0] = BACKSLASH_L;
szStaticLocalMachineName[1] = BACKSLASH_L;
dwBufferLength = (sizeof(szStaticLocalMachineName) / sizeof(WCHAR)) - 2;
GetComputerNameW (&szStaticLocalMachineName[2], &dwBufferLength);
}
hPdhDataMutex = CreateMutexW (NULL, FALSE, NULL);
hPdhContextMutex = CreateMutexW(NULL, FALSE, NULL);
hPdhHeap = HeapCreate (0, 0, 0);
if (hPdhHeap == NULL) {
// unable to create our own heap, so use the
// process heap
hPdhHeap = GetProcessHeap();
assert (hPdhHeap != NULL);
}
PdhiPlaInitMutex();
}
}
break;
case DLL_PROCESS_DETACH:
// close all pending loggers
//
bProcessIsDetaching = (ReservedAndUnused != NULL)
? (TRUE) : (FALSE);
PdhiCloseAllLoggers();
// walk down query list and close (at least disconnect) queries.
PdhiQueryCleanup ();
FreeAllMachines(bProcessIsDetaching);
PdhiFreeAllWbemServers ();
if (hPdhDataMutex != NULL) {
bStatus = CloseHandle (hPdhDataMutex);
assert (bStatus);
hPdhDataMutex = NULL;
}
if (hPdhContextMutex != NULL) {
bStatus = CloseHandle (hPdhContextMutex);
assert (bStatus);
hPdhContextMutex = NULL;
}
if (hPdhHeap != GetProcessHeap()) {
HeapDestroy (hPdhHeap);
hPdhHeap = NULL;
}
// lastly close the event log interface
bStatus = PdhiCloseEventLog (&hEventLog);
bReturn = TRUE;
break ;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
bReturn = TRUE;
break;
}
return (bReturn);
}