792 lines
17 KiB
C
792 lines
17 KiB
C
|
/*++
|
|||
|
|
|||
|
|
|||
|
Copyright (c) 1991 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
Predefh.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module contains routines for opening the Win32 Registry API's
|
|||
|
predefined handles.
|
|||
|
|
|||
|
A predefined handle is used as a root to an absolute or relative
|
|||
|
sub-tree in the real Nt Registry. An absolute predefined handle maps
|
|||
|
to a specific key within the Registry. A relative predefined handle
|
|||
|
maps to a key relative to some additional information such as the
|
|||
|
current user.
|
|||
|
|
|||
|
Predefined handles are strictly part of the Win32 Registry API. The
|
|||
|
Nt Registry API knows nothing about them.
|
|||
|
|
|||
|
A predefined handle can be used anywhere that a non-predefined handle
|
|||
|
(i.e. one returned from RegCreateKey(), RegOpenKey() or
|
|||
|
RegConnectRegistry()) can be used.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
David J. Gilman (davegi) 15-Nov-1991
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include <rpc.h>
|
|||
|
#include "regrpc.h"
|
|||
|
#include "localreg.h"
|
|||
|
#include "regclass.h"
|
|||
|
#include "ntconreg.h"
|
|||
|
#include "regsec.h"
|
|||
|
#ifdef LOCAL
|
|||
|
#include "tsappcmp.h"
|
|||
|
|
|||
|
#if defined(LEAK_TRACK)
|
|||
|
#include "regleak.h"
|
|||
|
#endif // LEAK_TRACK
|
|||
|
#endif
|
|||
|
|
|||
|
//
|
|||
|
// Determine the length of a Unicode string w/o the trailing NULL.
|
|||
|
//
|
|||
|
|
|||
|
#define LENGTH( str ) ( sizeof( str ) - sizeof( UNICODE_NULL ))
|
|||
|
|
|||
|
//
|
|||
|
// Nt Registry name space.
|
|||
|
//
|
|||
|
|
|||
|
#define MACHINE L"\\REGISTRY\\MACHINE"
|
|||
|
|
|||
|
#define USER L"\\REGISTRY\\USER"
|
|||
|
|
|||
|
#define CLASSES L"\\REGISTRY\\MACHINE\\SOFTWARE\\CLASSES"
|
|||
|
|
|||
|
#define CLASSES_SUFFIX L"\\SOFTWARE\\CLASSES"
|
|||
|
|
|||
|
#define CURRENTCONFIG L"\\REGISTRY\\MACHINE\\SYSTEM\\CURRENTCONTROLSET\\HARDWARE PROFILES\\CURRENT"
|
|||
|
|
|||
|
|
|||
|
|
|||
|
UNICODE_STRING MachineStringKey = {
|
|||
|
LENGTH( MACHINE ),
|
|||
|
LENGTH( MACHINE ),
|
|||
|
MACHINE
|
|||
|
};
|
|||
|
|
|||
|
UNICODE_STRING UserStringKey = {
|
|||
|
LENGTH( USER ),
|
|||
|
LENGTH( USER ),
|
|||
|
USER
|
|||
|
};
|
|||
|
|
|||
|
UNICODE_STRING ClassesStringKey = {
|
|||
|
LENGTH( CLASSES ),
|
|||
|
LENGTH( CLASSES ),
|
|||
|
CLASSES
|
|||
|
};
|
|||
|
|
|||
|
UNICODE_STRING CurrentConfigStringKey = {
|
|||
|
LENGTH( CURRENTCONFIG ),
|
|||
|
LENGTH( CURRENTCONFIG ),
|
|||
|
CURRENTCONFIG
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
InitSecurityAcls(PSECURITY_DESCRIPTOR *SecurityDescriptor)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Gives GENERIC_ALL to admins and denies WRITE_OWNER | WRITE_DAC from everyone
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
|
|||
|
SID_IDENTIFIER_AUTHORITY WorldAuthority = SECURITY_WORLD_SID_AUTHORITY;
|
|||
|
PSID BuiltInAdministrators = NULL;
|
|||
|
PSID Everyone = NULL;
|
|||
|
NTSTATUS Status;
|
|||
|
ULONG AclSize;
|
|||
|
ACL *Acl;
|
|||
|
|
|||
|
*SecurityDescriptor = NULL;
|
|||
|
|
|||
|
Status = RtlAllocateAndInitializeSid(
|
|||
|
&WorldAuthority,
|
|||
|
1,
|
|||
|
SECURITY_WORLD_RID,
|
|||
|
0,0,0,0,0,0,0,
|
|||
|
&Everyone );
|
|||
|
if( !NT_SUCCESS(Status) ) {
|
|||
|
goto Exit;
|
|||
|
}
|
|||
|
|
|||
|
Status = RtlAllocateAndInitializeSid(
|
|||
|
&NtAuthority,
|
|||
|
2,
|
|||
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|||
|
DOMAIN_ALIAS_RID_ADMINS,
|
|||
|
0,0,0,0,0,0,
|
|||
|
&BuiltInAdministrators );
|
|||
|
|
|||
|
if( !NT_SUCCESS(Status) ) {
|
|||
|
goto Exit;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
AclSize = sizeof (ACL) +
|
|||
|
(2 * (sizeof (ACCESS_ALLOWED_ACE) - sizeof (ULONG))) +
|
|||
|
GetLengthSid(BuiltInAdministrators) +
|
|||
|
GetLengthSid(Everyone);
|
|||
|
|
|||
|
*SecurityDescriptor = (PSECURITY_DESCRIPTOR)RtlAllocateHeap( RtlProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH + AclSize);
|
|||
|
if (!*SecurityDescriptor) {
|
|||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|||
|
goto Exit;
|
|||
|
}
|
|||
|
|
|||
|
Acl = (ACL *)((BYTE *)(*SecurityDescriptor) + SECURITY_DESCRIPTOR_MIN_LENGTH);
|
|||
|
|
|||
|
Status = RtlCreateAcl( Acl,
|
|||
|
AclSize,
|
|||
|
ACL_REVISION);
|
|||
|
if( !NT_SUCCESS(Status) ) {
|
|||
|
goto Exit;
|
|||
|
}
|
|||
|
|
|||
|
Status = RtlAddAccessAllowedAce(Acl,
|
|||
|
ACL_REVISION,
|
|||
|
(KEY_ALL_ACCESS & ~(WRITE_OWNER | WRITE_DAC)),
|
|||
|
Everyone);
|
|||
|
if( !NT_SUCCESS(Status) ) {
|
|||
|
goto Exit;
|
|||
|
}
|
|||
|
|
|||
|
Status = RtlAddAccessAllowedAce(Acl,
|
|||
|
ACL_REVISION,
|
|||
|
GENERIC_ALL,
|
|||
|
BuiltInAdministrators);
|
|||
|
if( !NT_SUCCESS(Status) ) {
|
|||
|
goto Exit;
|
|||
|
}
|
|||
|
|
|||
|
Status = RtlCreateSecurityDescriptor(
|
|||
|
*SecurityDescriptor,
|
|||
|
SECURITY_DESCRIPTOR_REVISION
|
|||
|
);
|
|||
|
if( !NT_SUCCESS(Status) ) {
|
|||
|
goto Exit;
|
|||
|
}
|
|||
|
|
|||
|
Status = RtlSetDaclSecurityDescriptor( *SecurityDescriptor,
|
|||
|
TRUE,
|
|||
|
Acl,
|
|||
|
FALSE);
|
|||
|
|
|||
|
Exit:
|
|||
|
if( Everyone ) {
|
|||
|
RtlFreeSid( Everyone );
|
|||
|
}
|
|||
|
|
|||
|
if( BuiltInAdministrators ) {
|
|||
|
RtlFreeSid( BuiltInAdministrators );
|
|||
|
}
|
|||
|
|
|||
|
return Status;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
error_status_t
|
|||
|
OpenClassesRoot(
|
|||
|
IN PREGISTRY_SERVER_NAME ServerName,
|
|||
|
IN REGSAM samDesired,
|
|||
|
OUT PRPC_HKEY phKey
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Attempts to open the the HKEY_CLASSES_ROOT predefined handle.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ServerName - Not used.
|
|||
|
samDesired - This access mask describes the desired security access
|
|||
|
for the key.
|
|||
|
phKey - Returns a handle to the key \REGISTRY\MACHINE\SOFTWARE\CLASSES.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Returns ERROR_SUCCESS (0) for success; error-code for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
|
|||
|
OBJECT_ATTRIBUTES Obja;
|
|||
|
NTSTATUS Status;
|
|||
|
UNICODE_STRING UsersHive;
|
|||
|
UNICODE_STRING UsersMergedHive;
|
|||
|
error_status_t Res;
|
|||
|
|
|||
|
UNREFERENCED_PARAMETER( ServerName );
|
|||
|
|
|||
|
//
|
|||
|
// Impersonate the client.
|
|||
|
//
|
|||
|
|
|||
|
RPC_IMPERSONATE_CLIENT( NULL );
|
|||
|
|
|||
|
#ifdef LOCAL
|
|||
|
//
|
|||
|
// Multiuser CLASSES key so each user has their own key. If opening
|
|||
|
// CLASSES in execute mode - open it under HKEY_CURRENT_USER else
|
|||
|
// just let it fall thru here and open the global one.
|
|||
|
//
|
|||
|
if (gpfnTermsrvOpenUserClasses) {
|
|||
|
Status = gpfnTermsrvOpenUserClasses(samDesired,phKey);
|
|||
|
} else {
|
|||
|
*phKey = NULL;
|
|||
|
}
|
|||
|
if (!(*phKey)) {
|
|||
|
#endif // LOCAL
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Initialize the SECURITY_DESCRIPTOR.
|
|||
|
//
|
|||
|
Status = InitSecurityAcls(&SecurityDescriptor);
|
|||
|
|
|||
|
if( ! NT_SUCCESS( Status )) {
|
|||
|
goto error_exit;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#ifdef LOCAL
|
|||
|
|
|||
|
if (gbCombinedClasses) {
|
|||
|
// first try for a per-user HKCR
|
|||
|
Res = OpenCombinedClassesRoot( samDesired, phKey );
|
|||
|
|
|||
|
if ( NT_SUCCESS( Res ) ) {
|
|||
|
goto error_exit;
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
//
|
|||
|
// Initialize the OBJECT_ATTRIBUTES structure so that it creates
|
|||
|
// (opens) the key "\REGISTRY\MACHINE\SOFTWARE\CLASSES" with a Security
|
|||
|
// Descriptor that allows everyone complete access.
|
|||
|
//
|
|||
|
|
|||
|
InitializeObjectAttributes(
|
|||
|
&Obja,
|
|||
|
&ClassesStringKey,
|
|||
|
OBJ_CASE_INSENSITIVE,
|
|||
|
NULL,
|
|||
|
SecurityDescriptor
|
|||
|
);
|
|||
|
|
|||
|
Status = NtCreateKey(
|
|||
|
phKey,
|
|||
|
samDesired, // MAXIMUM_ALLOWED,
|
|||
|
&Obja,
|
|||
|
0,
|
|||
|
NULL,
|
|||
|
REG_OPTION_NON_VOLATILE,
|
|||
|
NULL
|
|||
|
);
|
|||
|
#ifdef LOCAL
|
|||
|
}
|
|||
|
#endif // LOCAL
|
|||
|
|
|||
|
#if DBG
|
|||
|
if( ! NT_SUCCESS( Status )) {
|
|||
|
DbgPrint(
|
|||
|
"Winreg Server: "
|
|||
|
"Creating HKEY_CLASSES_ROOT failed, status = 0x%x\n",
|
|||
|
Status
|
|||
|
);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
error_exit:
|
|||
|
|
|||
|
if( SecurityDescriptor != NULL ) {
|
|||
|
RtlFreeHeap( RtlProcessHeap(), 0, SecurityDescriptor );
|
|||
|
}
|
|||
|
RPC_REVERT_TO_SELF();
|
|||
|
return (error_status_t)RtlNtStatusToDosError( Status );
|
|||
|
}
|
|||
|
|
|||
|
error_status_t
|
|||
|
OpenCurrentUser(
|
|||
|
IN PREGISTRY_SERVER_NAME ServerName,
|
|||
|
IN REGSAM samDesired,
|
|||
|
OUT PRPC_HKEY phKey
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Attempts to open the the HKEY_CURRENT_USER predefined handle.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ServerName - Not used.
|
|||
|
samDesired - This access mask describes the desired security access
|
|||
|
for the key.
|
|||
|
phKey - Returns a handle to the key \REGISTRY\USER\*.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Returns ERROR_SUCCESS (0) for success; error-code for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
NTSTATUS Status;
|
|||
|
|
|||
|
UNREFERENCED_PARAMETER( ServerName );
|
|||
|
|
|||
|
//
|
|||
|
// Impersonate the client.
|
|||
|
//
|
|||
|
|
|||
|
RPC_IMPERSONATE_CLIENT( NULL );
|
|||
|
|
|||
|
//
|
|||
|
// Open the registry key.
|
|||
|
//
|
|||
|
|
|||
|
Status = RtlOpenCurrentUser( samDesired, /* MAXIMUM_ALLOWED, */ phKey );
|
|||
|
|
|||
|
RPC_REVERT_TO_SELF();
|
|||
|
//
|
|||
|
// Map the returned status
|
|||
|
//
|
|||
|
|
|||
|
return (error_status_t)RtlNtStatusToDosError( Status );
|
|||
|
}
|
|||
|
|
|||
|
error_status_t
|
|||
|
OpenLocalMachine(
|
|||
|
IN PREGISTRY_SERVER_NAME ServerName,
|
|||
|
IN REGSAM samDesired,
|
|||
|
OUT PRPC_HKEY phKey
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Attempt to open the the HKEY_LOCAL_MACHINE predefined handle.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ServerName - Not used.
|
|||
|
samDesired - This access mask describes the desired security access
|
|||
|
for the key.
|
|||
|
phKey - Returns a handle to the key \REGISTRY\MACHINE.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Returns ERROR_SUCCESS (0) for success; error-code for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
OBJECT_ATTRIBUTES Obja;
|
|||
|
NTSTATUS Status;
|
|||
|
|
|||
|
UNREFERENCED_PARAMETER( ServerName );
|
|||
|
|
|||
|
//
|
|||
|
// Impersonate the client.
|
|||
|
//
|
|||
|
|
|||
|
RPC_IMPERSONATE_CLIENT( NULL );
|
|||
|
|
|||
|
InitializeObjectAttributes(
|
|||
|
&Obja,
|
|||
|
&MachineStringKey,
|
|||
|
OBJ_CASE_INSENSITIVE,
|
|||
|
NULL,
|
|||
|
NULL
|
|||
|
);
|
|||
|
|
|||
|
Status = NtOpenKey(
|
|||
|
phKey,
|
|||
|
samDesired, // MAXIMUM_ALLOWED,
|
|||
|
&Obja
|
|||
|
);
|
|||
|
#if DBG
|
|||
|
if( ! NT_SUCCESS( Status )) {
|
|||
|
DbgPrint(
|
|||
|
"Winreg Server: "
|
|||
|
"Opening HKEY_LOCAL_MACHINE failed, status = 0x%x\n",
|
|||
|
Status
|
|||
|
);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
if ( NT_SUCCESS( Status ) )
|
|||
|
{
|
|||
|
if (! REGSEC_CHECK_REMOTE( phKey ) )
|
|||
|
{
|
|||
|
*phKey = REGSEC_FLAG_HANDLE( *phKey, CHECK_MACHINE_PATHS );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
RPC_REVERT_TO_SELF();
|
|||
|
|
|||
|
return (error_status_t)RtlNtStatusToDosError( Status );
|
|||
|
}
|
|||
|
|
|||
|
error_status_t
|
|||
|
OpenUsers(
|
|||
|
IN PREGISTRY_SERVER_NAME ServerName,
|
|||
|
IN REGSAM samDesired,
|
|||
|
OUT PRPC_HKEY phKey
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Attempts to open the the HKEY_USERS predefined handle.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ServerName - Not used.
|
|||
|
samDesired - This access mask describes the desired security access
|
|||
|
for the key.
|
|||
|
phKey - Returns a handle to the key \REGISTRY\USER.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Returns ERROR_SUCCESS (0) for success; error-code for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
OBJECT_ATTRIBUTES Obja;
|
|||
|
NTSTATUS Status;
|
|||
|
|
|||
|
UNREFERENCED_PARAMETER( ServerName );
|
|||
|
|
|||
|
//
|
|||
|
// Impersonate the client.
|
|||
|
//
|
|||
|
|
|||
|
RPC_IMPERSONATE_CLIENT( NULL );
|
|||
|
|
|||
|
InitializeObjectAttributes(
|
|||
|
&Obja,
|
|||
|
&UserStringKey,
|
|||
|
OBJ_CASE_INSENSITIVE,
|
|||
|
NULL,
|
|||
|
NULL
|
|||
|
);
|
|||
|
|
|||
|
Status = NtOpenKey(
|
|||
|
phKey,
|
|||
|
samDesired, // MAXIMUM_ALLOWED,
|
|||
|
&Obja
|
|||
|
);
|
|||
|
#if DBG
|
|||
|
if( ! NT_SUCCESS( Status )) {
|
|||
|
DbgPrint(
|
|||
|
"Winreg Server: "
|
|||
|
"Opening HKEY_USERS failed, status = 0x%x\n",
|
|||
|
Status
|
|||
|
);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
if ( NT_SUCCESS( Status ) )
|
|||
|
{
|
|||
|
if (! REGSEC_CHECK_REMOTE( phKey ) )
|
|||
|
{
|
|||
|
*phKey = REGSEC_FLAG_HANDLE( *phKey, CHECK_USER_PATHS );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
RPC_REVERT_TO_SELF();
|
|||
|
|
|||
|
return (error_status_t)RtlNtStatusToDosError( Status );
|
|||
|
}
|
|||
|
|
|||
|
error_status_t
|
|||
|
OpenCurrentConfig(
|
|||
|
IN PREGISTRY_SERVER_NAME ServerName,
|
|||
|
IN REGSAM samDesired,
|
|||
|
OUT PRPC_HKEY phKey
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Attempts to open the the HKEY_CURRENT_CONFIG predefined handle.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ServerName - Not used.
|
|||
|
samDesired - This access mask describes the desired security access
|
|||
|
for the key.
|
|||
|
phKey - Returns a handle to the key \REGISTRY\MACHINE\SYSTEM\CURRENTCONTROLSET\HARDWARE PROFILES\CURRENT
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Returns ERROR_SUCCESS (0) for success; error-code for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
OBJECT_ATTRIBUTES Obja;
|
|||
|
NTSTATUS Status;
|
|||
|
|
|||
|
UNREFERENCED_PARAMETER( ServerName );
|
|||
|
|
|||
|
//
|
|||
|
// Impersonate the client.
|
|||
|
//
|
|||
|
|
|||
|
RPC_IMPERSONATE_CLIENT( NULL );
|
|||
|
|
|||
|
InitializeObjectAttributes(
|
|||
|
&Obja,
|
|||
|
&CurrentConfigStringKey,
|
|||
|
OBJ_CASE_INSENSITIVE,
|
|||
|
NULL,
|
|||
|
NULL
|
|||
|
);
|
|||
|
|
|||
|
Status = NtOpenKey(
|
|||
|
phKey,
|
|||
|
samDesired, // MAXIMUM_ALLOWED,
|
|||
|
&Obja
|
|||
|
);
|
|||
|
#if DBG
|
|||
|
if( ! NT_SUCCESS( Status )) {
|
|||
|
DbgPrint(
|
|||
|
"Winreg Server: "
|
|||
|
"Opening HKEY_CURRENT_CONFIG failed, status = 0x%x\n",
|
|||
|
Status
|
|||
|
);
|
|||
|
}
|
|||
|
#endif
|
|||
|
RPC_REVERT_TO_SELF();
|
|||
|
|
|||
|
return (error_status_t)RtlNtStatusToDosError( Status );
|
|||
|
}
|
|||
|
error_status_t
|
|||
|
OpenPerformanceData(
|
|||
|
IN PREGISTRY_SERVER_NAME ServerName,
|
|||
|
IN REGSAM samDesired,
|
|||
|
OUT PRPC_HKEY phKey
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Attempts to open the the HKEY_PERFORMANCE_DATA predefined handle.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ServerName - Not used.
|
|||
|
samDesired - Not used.
|
|||
|
phKey - Returns a the predefined handle HKEY_PERFORMANCE_DATA.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Returns ERROR_SUCCESS (0) for success;
|
|||
|
or a DOS (not NT) error-code for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
IO_STATUS_BLOCK IoStatusBlock;
|
|||
|
RTL_RELATIVE_NAME RelativeName;
|
|||
|
UNICODE_STRING DeviceNameU;
|
|||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|||
|
STRING DeviceName;
|
|||
|
NTSTATUS status;
|
|||
|
|
|||
|
if ( 0 ) {
|
|||
|
DBG_UNREFERENCED_PARAMETER(ServerName);
|
|||
|
DBG_UNREFERENCED_PARAMETER(samDesired);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Impersonate the client.
|
|||
|
//
|
|||
|
|
|||
|
RPC_IMPERSONATE_CLIENT( NULL );
|
|||
|
|
|||
|
if ( ! REGSEC_CHECK_REMOTE( phKey ) )
|
|||
|
{
|
|||
|
RPC_REVERT_TO_SELF();
|
|||
|
return( ERROR_ACCESS_DENIED );
|
|||
|
}
|
|||
|
|
|||
|
// check if we are in the middle of Lodctr/unlodctr.
|
|||
|
// if so, don't open the performance data stuff.
|
|||
|
{
|
|||
|
HANDLE hFileMapping = NULL;
|
|||
|
WCHAR MapFileName[] = L"Perflib Busy";
|
|||
|
DWORD *lpData;
|
|||
|
BOOL bBusy = FALSE;
|
|||
|
|
|||
|
hFileMapping = OpenFileMappingW (FILE_MAP_READ, TRUE, (LPCWSTR)MapFileName);
|
|||
|
if (hFileMapping) {
|
|||
|
// someone is running lodctr perhaps find out by reading the first DWORD
|
|||
|
lpData = MapViewOfFile (hFileMapping,
|
|||
|
FILE_MAP_READ, 0L, 0L, 0L);
|
|||
|
if (lpData) {
|
|||
|
// successfully mapped so read it
|
|||
|
// 1 = busy, 0 = not
|
|||
|
bBusy = (BOOL)(*lpData);
|
|||
|
UnmapViewOfFile (lpData);
|
|||
|
}
|
|||
|
CloseHandle (hFileMapping);
|
|||
|
if (bBusy) {
|
|||
|
*phKey = (RPC_HKEY) HKEY_PERFORMANCE_DATA;
|
|||
|
RPC_REVERT_TO_SELF();
|
|||
|
return ERROR_SUCCESS;
|
|||
|
}
|
|||
|
} else {
|
|||
|
// no lodctr so continue
|
|||
|
}
|
|||
|
}
|
|||
|
status = PerfOpenKey();
|
|||
|
|
|||
|
RPC_REVERT_TO_SELF();
|
|||
|
|
|||
|
*phKey = (RPC_HKEY) HKEY_PERFORMANCE_DATA;
|
|||
|
return ERROR_SUCCESS;
|
|||
|
|
|||
|
RPC_REVERT_TO_SELF();
|
|||
|
return status;
|
|||
|
}
|
|||
|
|
|||
|
error_status_t
|
|||
|
OpenPerformanceText(
|
|||
|
IN PREGISTRY_SERVER_NAME ServerName,
|
|||
|
IN REGSAM samDesired,
|
|||
|
OUT PRPC_HKEY phKey
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Attempts to open the the HKEY_PERFORMANCE_TEXT predefined handle.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ServerName - Not used.
|
|||
|
samDesired - Not used.
|
|||
|
phKey - Returns the predefined handle HKEY_PERFORMANCE_TEXT.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Returns ERROR_SUCCESS (0) for success;
|
|||
|
or a DOS (not NT) error-code for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
error_status_t Status = ERROR_SUCCESS;
|
|||
|
|
|||
|
// No need to call OpenPerformanceData for getting text (HWC 4/1994)
|
|||
|
// Status = OpenPerformanceData(ServerName, samDesired, phKey);
|
|||
|
// if (Status==ERROR_SUCCESS) {
|
|||
|
*phKey = HKEY_PERFORMANCE_TEXT;
|
|||
|
// }
|
|||
|
return(Status);
|
|||
|
}
|
|||
|
|
|||
|
error_status_t
|
|||
|
OpenPerformanceNlsText(
|
|||
|
IN PREGISTRY_SERVER_NAME ServerName,
|
|||
|
IN REGSAM samDesired,
|
|||
|
OUT PRPC_HKEY phKey
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Attempts to open the the HKEY_PERFORMANCE_TEXT predefined handle.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ServerName - Not used.
|
|||
|
samDesired - Not used.
|
|||
|
phKey - Returns the predefined handle HKEY_PERFORMANCE_NLSTEXT.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Returns ERROR_SUCCESS (0) for success;
|
|||
|
or a DOS (not NT) error-code for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
error_status_t Status = ERROR_SUCCESS;
|
|||
|
|
|||
|
// No need to call OpenPerformanceData for getting text (HWC 4/1994)
|
|||
|
// Status = OpenPerformanceData(ServerName, samDesired, phKey);
|
|||
|
// if (Status==ERROR_SUCCESS) {
|
|||
|
*phKey = HKEY_PERFORMANCE_NLSTEXT;
|
|||
|
// }
|
|||
|
return(Status);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
error_status_t
|
|||
|
OpenDynData(
|
|||
|
IN PREGISTRY_SERVER_NAME ServerName,
|
|||
|
IN REGSAM samDesired,
|
|||
|
OUT PRPC_HKEY phKey
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Attempts to open the the HKEY_DYN_DATA predefined handle.
|
|||
|
|
|||
|
There is currently no HKEY_DYN_DATA on NT, thus this
|
|||
|
function always returns ERROR_CALL_NOT_IMPLEMENTED.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ServerName - Not used.
|
|||
|
samDesired - This access mask describes the desired security access
|
|||
|
for the key.
|
|||
|
phKey - Returns a handle to the key HKEY_DYN_DATA
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Returns ERROR_SUCCESS (0) for success; error-code for failure.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
return((error_status_t)ERROR_CALL_NOT_IMPLEMENTED);
|
|||
|
}
|