|
|
/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
cmwraper.c
Abstract:
Provides wrapper routines to support ntos\config routines called from user-mode.
Author:
John Vert (jvert) 26-Mar-1992
Revision History:
--*/ #include "edithive.h"
#include "nturtl.h"
#include "stdlib.h"
#include "stdio.h"
extern ULONG UsedStorage;
CCHAR KiFindFirstSetRight[256] = { 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0};
ULONG MmSizeOfPagedPoolInBytes = 0xffffffff; // stub out
ULONG DbgPrint ( IN PCH Format, ... ) { va_list arglist; UCHAR Buffer[512]; STRING Output;
//
// Format the output into a buffer and then print it.
//
va_start(arglist, Format); Output.Length = _vsnprintf(Buffer, sizeof(Buffer), Format, arglist); Output.Buffer = Buffer; printf("%s", Buffer); return 0; }
//
// Structure that describes the mapping of generic access rights to object
// specific access rights for registry key and keyroot objects.
//
GENERIC_MAPPING CmpKeyMapping = { KEY_READ, KEY_WRITE, KEY_EXECUTE, KEY_ALL_ACCESS }; BOOLEAN CmpNoWrite = FALSE; PCMHIVE CmpMasterHive = NULL; LIST_ENTRY CmpHiveListHead; // List of CMHIVEs
NTSTATUS MyCmpInitHiveFromFile( IN PUNICODE_STRING FileName, OUT PCMHIVE *CmHive, OUT PBOOLEAN Allocate );
VOID CmpLazyFlush( VOID ) { }
VOID CmpFreeSecurityDescriptor( IN PHHIVE Hive, IN HCELL_INDEX Cell ) { return; }
VOID CmpReportNotify( UNICODE_STRING Name, PHHIVE Hive, HCELL_INDEX Cell, ULONG Filter ) { }
VOID CmpLockRegistry(VOID) { return; }
BOOLEAN CmpTryLockRegistryExclusive( IN BOOLEAN CanWait ) { return TRUE; }
VOID CmpUnlockRegistry( ) { }
BOOLEAN CmpTestRegistryLock() { return TRUE; }
BOOLEAN CmpTestRegistryLockExclusive() { return TRUE; } LONG KeReleaseMutex ( IN PKMUTEX Mutex, IN BOOLEAN Wait ) { return(0); } NTSTATUS KeWaitForSingleObject ( IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL ) { return(STATUS_SUCCESS); }
BOOLEAN CmpValidateHiveSecurityDescriptors( IN PHHIVE Hive ) { PCM_KEY_NODE RootNode; PCM_KEY_SECURITY SecurityCell; HCELL_INDEX ListAnchor; HCELL_INDEX NextCell; HCELL_INDEX LastCell; BOOLEAN ValidHive = TRUE;
KdPrint(("CmpValidateHiveSecurityDescriptor: Hive = %lx\n",(ULONG)Hive)); RootNode = (PCM_KEY_NODE) HvGetCell(Hive, Hive->BaseBlock->RootCell); ListAnchor = NextCell = RootNode->u1.s1.Security;
do { SecurityCell = (PCM_KEY_SECURITY) HvGetCell(Hive, NextCell); if (NextCell != ListAnchor) { //
// Check to make sure that our Blink points to where we just
// came from.
//
if (SecurityCell->Blink != LastCell) { KdPrint((" Invalid Blink (%ld) on security cell %ld\n",SecurityCell->Blink, NextCell)); KdPrint((" should point to %ld\n", LastCell)); ValidHive = FALSE; } } KdPrint(("CmpValidSD: SD shared by %d nodes\n",SecurityCell->ReferenceCount)); // SetUsed(Hive, NextCell);
LastCell = NextCell; NextCell = SecurityCell->Flink; } while ( NextCell != ListAnchor ); return(TRUE); }
VOID KeBugCheck( IN ULONG BugCheckCode ) { printf("BugCheck: code = %08lx\n", BugCheckCode); exit(1); }
VOID KeBugCheckEx( IN ULONG BugCheckCode, IN ULONG Arg1, IN ULONG Arg2, IN ULONG Arg3, IN ULONG Arg4 ) { printf("BugCheck: code = %08lx\n", BugCheckCode); printf("Args =%08lx %08lx %08lx %08lx\n", Arg1, Arg2, Arg3, Arg4); exit(1); }
VOID KeQuerySystemTime( OUT PLARGE_INTEGER SystemTime ) { NtQuerySystemTime(SystemTime); }
#ifdef POOL_TAGGING
PVOID ExAllocatePoolWithTag( IN POOL_TYPE PoolType, IN ULONG NumberOfBytes, IN ULONG Tag ) { PVOID Address = NULL; ULONG Size; NTSTATUS status;
Size = ROUND_UP(NumberOfBytes, HBLOCK_SIZE); status = NtAllocateVirtualMemory( NtCurrentProcess(), &Address, 0, &Size, MEM_COMMIT, PAGE_READWRITE ); if (!NT_SUCCESS(status)) { return NULL; } return Address; } #else
PVOID ExAllocatePool( IN POOL_TYPE PoolType, IN ULONG NumberOfBytes ) { PVOID Address = NULL; ULONG Size; NTSTATUS status;
Size = ROUND_UP(NumberOfBytes, HBLOCK_SIZE); status = NtAllocateVirtualMemory( NtCurrentProcess(), &Address, 0, &Size, MEM_COMMIT, PAGE_READWRITE ); if (!NT_SUCCESS(status)) { return NULL; } return Address; } #endif
VOID ExFreePool( IN PVOID P ) { ULONG size; size = HBLOCK_SIZE;
// if it was really more than 1 page, well, too bad
NtFreeVirtualMemory( NtCurrentProcess(), &P, &size, MEM_DECOMMIT ); return; }
NTSTATUS CmpWorkerCommand( IN OUT PREGISTRY_COMMAND Command )
/*++
Routine Description:
This routine just encapsulates all the necessary synchronization for sending a command to the worker thread.
Arguments:
Command - Supplies a pointer to an initialized REGISTRY_COMMAND structure which will be copied into the global communication structure.
Return Value:
NTSTATUS = Command.Status
--*/
{ PCMHIVE CmHive; PUNICODE_STRING FileName; ULONG i;
switch (Command->Command) {
case REG_CMD_FLUSH_KEY: return CmFlushKey(Command->Hive, Command->Cell); break;
case REG_CMD_FILE_SET_SIZE: return CmpDoFileSetSize( Command->Hive, Command->FileType, Command->FileSize ); break;
case REG_CMD_HIVE_OPEN:
//
// Open the file.
//
FileName = Command->FileAttributes->ObjectName;
return MyCmpInitHiveFromFile(FileName, &Command->CmHive, &Command->Allocate);
break;
case REG_CMD_HIVE_CLOSE:
//
// Close the files associated with this hive.
//
CmHive = Command->CmHive;
for (i=0; i<HFILE_TYPE_MAX; i++) { if (CmHive->FileHandles[i] != NULL) { NtClose(CmHive->FileHandles[i]); } } return STATUS_SUCCESS; break;
case REG_CMD_SHUTDOWN:
//
// shut down the registry
//
break;
default: return STATUS_INVALID_PARAMETER; } }
NTSTATUS MyCmpInitHiveFromFile( IN PUNICODE_STRING FileName, OUT PCMHIVE *CmHive, OUT PBOOLEAN Allocate )
/*++
Routine Description:
This routine opens a file and log, allocates a CMHIVE, and initializes it.
Arguments:
FileName - Supplies name of file to be loaded.
CmHive - Returns pointer to initialized hive (if successful)
Allocate - Returns whether the hive was allocated or existing.
Return Value:
NTSTATUS
--*/
{ PCMHIVE NewHive; ULONG Disposition; ULONG SecondaryDisposition; HANDLE PrimaryHandle; HANDLE LogHandle; NTSTATUS Status; ULONG FileType; ULONG Operation;
BOOLEAN Success;
*CmHive = NULL;
Status = CmpOpenHiveFiles(FileName, L".log", &PrimaryHandle, &LogHandle, &Disposition, &SecondaryDisposition, TRUE, NULL ); if (!NT_SUCCESS(Status)) { return(Status); }
if (LogHandle == NULL) { FileType = HFILE_TYPE_PRIMARY; } else { FileType = HFILE_TYPE_LOG; }
if (Disposition == FILE_CREATED) { Operation = HINIT_CREATE; *Allocate = TRUE; } else { Operation = HINIT_FILE; *Allocate = FALSE; }
Success = CmpInitializeHive(&NewHive, Operation, FALSE, FileType, NULL, PrimaryHandle, NULL, LogHandle, NULL, NULL); if (!Success) { NtClose(PrimaryHandle); if (LogHandle != NULL) { NtClose(LogHandle); } return(STATUS_REGISTRY_CORRUPT); } else { *CmHive = NewHive; return(STATUS_SUCCESS); } }
NTSTATUS CmpLinkHiveToMaster( PUNICODE_STRING LinkName, HANDLE RootDirectory, PCMHIVE CmHive, BOOLEAN Allocate, PSECURITY_DESCRIPTOR SecurityDescriptor ) { return( STATUS_SUCCESS ); }
BOOLEAN CmpFileSetSize( PHHIVE Hive, ULONG FileType, ULONG FileSize ) /*++
Routine Description:
This routine sets the size of a file. It must not return until the size is guaranteed, therefore, it does a flush.
It is environment specific.
This routine will force execution to the correct thread context.
Arguments:
Hive - Hive we are doing I/O for
FileType - which supporting file to use
FileSize - 32 bit value to set the file's size to
Return Value:
FALSE if failure TRUE if success
--*/ { NTSTATUS status;
status = CmpDoFileSetSize(Hive, FileType, FileSize); if (!NT_SUCCESS(status)) { KdPrint(("CmpFileSetSize:\n\t")); KdPrint(("Failure: status = %08lx ", status)); return FALSE; }
return TRUE; }
|