Author: ion
Date: Sat May 12 02:51:11 2007
New Revision: 26705
URL:
http://svn.reactos.org/svn/reactos?rev=26705&view=rev
Log:
- Copy CmOpenHiveFiles to cminit.c and rename to CmpOpenHiveFiles. Extend the
functionality of the routine:
- Allow caller to have full power over handles and filenames being used instead of
hard-coding a pointer to the registry hive.
- Setup proper I/O flags to disable compression and open for random access,
backup-intent and allow disabling buffering.
- Allow proper access mask/share mode when booting off read-only media.
- Call the FS driver with FSCTL_MARK_AS_SYSTEM_HIVE if instructed.
- Call with FSCTL_SET_COMPRESSION to make sure compression is off.
- Allow creating the hive if it doesn't exist already.
- Consider 0-byte opened hives as new hives.
- Allow caller to request volume sector size and validate with hive cluster size.
- Make .log hives hidden.
- Implemement CmpCreateEvent to allowed for overlapped I/O registry operations.
- Move more globals to cmdata.c.
Modified:
trunk/reactos/ntoskrnl/cm/cm.h
trunk/reactos/ntoskrnl/cm/regfile.c
trunk/reactos/ntoskrnl/config/cm.h
trunk/reactos/ntoskrnl/config/cmdata.c
trunk/reactos/ntoskrnl/config/cminit.c
trunk/reactos/ntoskrnl/config/cmsysini.c
trunk/reactos/ntoskrnl/config/cmwraprs.c
Modified: trunk/reactos/ntoskrnl/cm/cm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/cm.h?rev=26705…
==============================================================================
--- trunk/reactos/ntoskrnl/cm/cm.h (original)
+++ trunk/reactos/ntoskrnl/cm/cm.h Sat May 12 02:51:11 2007
@@ -496,6 +496,19 @@
NTAPI
CmpCreateRegistryRoot(VOID);
+NTSTATUS
+NTAPI
+CmpOpenHiveFiles(IN PUNICODE_STRING BaseName,
+ IN PWCHAR Extension OPTIONAL,
+ IN PHANDLE Primary,
+ IN PHANDLE Log,
+ IN PULONG PrimaryDisposition,
+ IN PULONG LogDisposition,
+ IN BOOLEAN CreateAllowed,
+ IN BOOLEAN MarkAsSystemHive,
+ IN BOOLEAN NoBuffering,
+ OUT PULONG ClusterSize OPTIONAL);
+
#if 0
static __inline PVOID xHvGetCell(char *file, int line, PHHIVE Hive, HCELL_INDEX Cell)
{
Modified: trunk/reactos/ntoskrnl/cm/regfile.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/regfile.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/cm/regfile.c (original)
+++ trunk/reactos/ntoskrnl/cm/regfile.c Sat May 12 02:51:11 2007
@@ -283,63 +283,6 @@
return STATUS_SUCCESS;
}
-
-NTSTATUS
-CmOpenHiveFiles(PEREGISTRY_HIVE RegistryHive)
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- IO_STATUS_BLOCK IoStatusBlock;
- NTSTATUS Status;
-
- InitializeObjectAttributes(&ObjectAttributes,
- &RegistryHive->HiveFileName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
-
- Status = ZwCreateFile(&RegistryHive->HiveHandle,
- FILE_ALL_ACCESS,
- &ObjectAttributes,
- &IoStatusBlock,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- 0,
- FILE_OPEN,
- FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
- NULL,
- 0);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
-
- InitializeObjectAttributes(&ObjectAttributes,
- &RegistryHive->LogFileName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
-
- Status = ZwCreateFile(&RegistryHive->LogHandle,
- FILE_ALL_ACCESS,
- &ObjectAttributes,
- &IoStatusBlock,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- 0,
- FILE_SUPERSEDE,
- FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
- NULL,
- 0);
- if (!NT_SUCCESS(Status))
- {
- ZwClose(RegistryHive->HiveHandle);
- return(Status);
- }
-
- return STATUS_SUCCESS;
-}
-
-
VOID
CmCloseHiveFiles(PEREGISTRY_HIVE RegistryHive)
{
@@ -353,6 +296,7 @@
{
BOOLEAN Success;
NTSTATUS Status;
+ ULONG Disposition;
ASSERT(!IsNoFileHive(RegistryHive));
@@ -361,7 +305,16 @@
return(STATUS_SUCCESS);
}
- Status = CmOpenHiveFiles(RegistryHive);
+ Status = CmpOpenHiveFiles(&RegistryHive->HiveFileName,
+ L".LOG",
+ &RegistryHive->HiveHandle,
+ &RegistryHive->LogHandle,
+ &Disposition,
+ &Disposition,
+ FALSE,
+ FALSE,
+ TRUE,
+ NULL);
if (!NT_SUCCESS(Status))
{
return Status;
Modified: trunk/reactos/ntoskrnl/config/cm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cm.h?rev=2…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cm.h (original)
+++ trunk/reactos/ntoskrnl/config/cm.h Sat May 12 02:51:11 2007
@@ -1007,6 +1007,14 @@
//
// Wrapper Routines
//
+NTSTATUS
+NTAPI
+CmpCreateEvent(
+ IN EVENT_TYPE EventType,
+ OUT PHANDLE EventHandle,
+ OUT PKEVENT *Event
+);
+
PVOID
NTAPI
CmpAllocate(
@@ -1060,6 +1068,8 @@
//
extern BOOLEAN CmpSpecialBootCondition;
extern BOOLEAN CmpFlushOnLockRelease;
+extern BOOLEAN CmpShareSystemHives;
+extern BOOLEAN CmpMiniNTBoot;
extern EX_PUSH_LOCK CmpHiveListHeadLock;
extern LIST_ENTRY CmpHiveListHead;
extern POBJECT_TYPE CmpKeyObjectType;
@@ -1080,6 +1090,14 @@
extern ULONG CmpConfigurationAreaSize;
extern PCM_FULL_RESOURCE_DESCRIPTOR CmpConfigurationData;
extern UNICODE_STRING CmTypeName[];
+extern HIVE_LIST_ENTRY CmpMachineHiveList[5];
+extern UNICODE_STRING CmSymbolicLinkValueName;
+extern UNICODE_STRING CmpSystemStartOptions;
+extern UNICODE_STRING CmpLoadOptions;
+extern BOOLEAN CmSelfHeal;
+extern BOOLEAN CmpSelfHeal;
+extern ULONG CmpBootType;
+extern HANDLE CmpRegistryRootHandle;
extern BOOLEAN ExpInTextModeSetup;
//
Modified: trunk/reactos/ntoskrnl/config/cmdata.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmdata.c?r…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmdata.c (original)
+++ trunk/reactos/ntoskrnl/config/cmdata.c Sat May 12 02:51:11 2007
@@ -37,6 +37,22 @@
PCM_FULL_RESOURCE_DESCRIPTOR CmpConfigurationData;
EX_PUSH_LOCK CmpHiveListHeadLock;
+
+HIVE_LIST_ENTRY CmpMachineHiveList[5];
+
+UNICODE_STRING CmSymbolicLinkValueName =
+ RTL_CONSTANT_STRING(L"SymbolicLinkValue");
+
+UNICODE_STRING CmpSystemStartOptions;
+UNICODE_STRING CmpLoadOptions;
+
+BOOLEAN CmpShareSystemHives;
+BOOLEAN CmSelfHeal = TRUE;
+BOOLEAN CmpSelfHeal = TRUE;
+BOOLEAN CmpMiniNTBoot;
+ULONG CmpBootType;
+
+HANDLE CmpRegistryRootHandle;
UNICODE_STRING CmTypeName[MaximumType + 1] =
{
Modified: trunk/reactos/ntoskrnl/config/cminit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cminit.c?r…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cminit.c (original)
+++ trunk/reactos/ntoskrnl/config/cminit.c Sat May 12 02:51:11 2007
@@ -226,3 +226,357 @@
*RegistryHive = (PCMHIVE)Hive;
return STATUS_SUCCESS;
}
+
+NTSTATUS
+NTAPI
+CmpOpenHiveFiles(IN PUNICODE_STRING BaseName,
+ IN PWCHAR Extension OPTIONAL,
+ IN PHANDLE Primary,
+ IN PHANDLE Log,
+ IN PULONG PrimaryDisposition,
+ IN PULONG LogDisposition,
+ IN BOOLEAN CreateAllowed,
+ IN BOOLEAN MarkAsSystemHive,
+ IN BOOLEAN NoBuffering,
+ OUT PULONG ClusterSize OPTIONAL)
+{
+ HANDLE EventHandle;
+ PKEVENT Event;
+ NTSTATUS Status;
+ UNICODE_STRING FullName, ExtensionName;
+ PWCHAR NameBuffer;
+ USHORT Length;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ ULONG AttributeFlags, ShareMode, DesiredAccess, CreateDisposition, IoFlags;
+ USHORT CompressionState;
+ FILE_STANDARD_INFORMATION FileInformation;
+ FILE_FS_SIZE_INFORMATION FsSizeInformation;
+
+ /* Create event */
+ Status = CmpCreateEvent(NotificationEvent, &EventHandle, &Event);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Initialize the full name */
+ RtlInitEmptyUnicodeString(&FullName, NULL, 0);
+ Length = BaseName->Length;
+
+ /* Check if we have an extension */
+ if (Extension)
+ {
+ /* Update the name length */
+ Length += wcslen(Extension) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
+
+ /* Allocate the buffer for the full name */
+ NameBuffer = ExAllocatePoolWithTag(PagedPool, Length, TAG_CM);
+ if (!NameBuffer)
+ {
+ /* Fail */
+ ObDereferenceObject(Event);
+ ZwClose(EventHandle);
+ return STATUS_NO_MEMORY;
+ }
+
+ /* Build the full name */
+ FullName.Buffer = NameBuffer;
+ FullName.MaximumLength = Length;
+ RtlAppendUnicodeStringToString(&FullName, BaseName);
+ }
+ else
+ {
+ /* The base name is the full name */
+ FullName = *BaseName;
+ NameBuffer = NULL;
+ }
+
+ /* Initialize the attributes */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &FullName,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL);
+
+ /* Check if we can create the hive */
+ if ((CreateAllowed) && !(CmpShareSystemHives))
+ {
+ /* Open only or create */
+ CreateDisposition = FILE_OPEN_IF;
+ }
+ else
+ {
+ /* Open only */
+ CreateDisposition = FILE_OPEN;
+ }
+
+ /* Setup the flags */
+ IoFlags = FILE_OPEN_FOR_BACKUP_INTENT |
+ FILE_NO_COMPRESSION |
+ FILE_RANDOM_ACCESS |
+ (NoBuffering) ? FILE_NO_INTERMEDIATE_BUFFERING : 0;
+
+ /* Set share and access modes */
+ if ((CmpMiniNTBoot) && (CmpShareSystemHives))
+ {
+ /* We're on Live CD or otherwise sharing */
+ DesiredAccess = FILE_READ_DATA;
+ ShareMode = FILE_SHARE_READ;
+ }
+ else
+ {
+ /* We want to write exclusively */
+ ShareMode = 0;
+ DesiredAccess = FILE_READ_DATA | FILE_WRITE_DATA;
+ }
+
+ /* Default attributes */
+ AttributeFlags = FILE_ATTRIBUTE_NORMAL;
+
+ /* Now create the file */
+ Status = ZwCreateFile(Primary,
+ DesiredAccess,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ NULL,
+ AttributeFlags,
+ ShareMode,
+ CreateDisposition,
+ FILE_SYNCHRONOUS_IO_NONALERT | IoFlags,
+ NULL,
+ 0);
+ if ((NT_SUCCESS(Status)) && (MarkAsSystemHive))
+ {
+ /* We opened it, mark it as a system hive */
+ Status = ZwFsControlFile(*Primary,
+ EventHandle,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ FSCTL_MARK_AS_SYSTEM_HIVE,
+ NULL,
+ 0,
+ NULL,
+ 0);
+ if (Status == STATUS_PENDING)
+ {
+ /* Wait for completion */
+ KeWaitForSingleObject(Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ Status = IoStatusBlock.Status;
+ }
+
+ /* If we don't support it, ignore the failure */
+ if (Status == STATUS_INVALID_DEVICE_REQUEST) Status = STATUS_SUCCESS;
+
+ /* If we failed, close the handle */
+ if (!NT_SUCCESS(Status)) ZwClose(*Primary);
+ }
+
+ /* Check if anything failed until now */
+ if (!NT_SUCCESS(Status))
+ {
+ /* Close handles and free buffers */
+ if (NameBuffer) ExFreePool(NameBuffer);
+ ObDereferenceObject(Event);
+ ZwClose(EventHandle);
+ return Status;
+ }
+
+ /* Disable compression */
+ CompressionState = 0;
+ Status = ZwFsControlFile(*Primary,
+ EventHandle,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ FSCTL_SET_COMPRESSION,
+ &CompressionState,
+ sizeof(CompressionState),
+ NULL,
+ 0);
+ if (Status == STATUS_PENDING)
+ {
+ /* Wait for completion */
+ KeWaitForSingleObject(Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ }
+
+ /* Get the disposition */
+ *PrimaryDisposition = IoStatusBlock.Information;
+ if (IoStatusBlock.Information != FILE_CREATED)
+ {
+ /* Check how large the file is */
+ Status = ZwQueryInformationFile(*Primary,
+ &IoStatusBlock,
+ &FileInformation,
+ sizeof(FileInformation),
+ FileStandardInformation);
+ if (NT_SUCCESS(Status))
+ {
+ /* Check if it's 0 bytes */
+ if (!FileInformation.EndOfFile.QuadPart)
+ {
+ /* Assume it's a new file */
+ *PrimaryDisposition = FILE_CREATED;
+ }
+ }
+ }
+
+ /* Check if the caller wants cluster size returned */
+ if (ClusterSize)
+ {
+ /* Query it */
+ Status = ZwQueryVolumeInformationFile(*Primary,
+ &IoStatusBlock,
+ &FsSizeInformation,
+ sizeof(FsSizeInformation),
+ FileFsSizeInformation);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Close handles and free buffers */
+ if (NameBuffer) ExFreePool(NameBuffer);
+ ObDereferenceObject(Event);
+ ZwClose(EventHandle);
+ return Status;
+ }
+
+ /* Check if the sector size is invalid */
+ if (FsSizeInformation.BytesPerSector > HBLOCK_SIZE)
+ {
+ /* Close handles and free buffers */
+ if (NameBuffer) ExFreePool(NameBuffer);
+ ObDereferenceObject(Event);
+ ZwClose(EventHandle);
+ return STATUS_CANNOT_LOAD_REGISTRY_FILE;
+ }
+
+ /* Return cluster size */
+ *ClusterSize = max(1, FsSizeInformation.BytesPerSector / HSECTOR_SIZE);
+ }
+
+ /* Check if we don't need to create a log file */
+ if (!Extension)
+ {
+ /* We're done, close handles and free buffers */
+ if (NameBuffer) ExFreePool(NameBuffer);
+ ObDereferenceObject(Event);
+ ZwClose(EventHandle);
+ return STATUS_SUCCESS;
+ }
+
+ /* Check if we can create the hive */
+ CreateDisposition = CmpShareSystemHives ? FILE_OPEN : FILE_OPEN_IF;
+ if (*PrimaryDisposition == FILE_CREATED)
+ {
+ /* Over-write the existing log file, since this is a new hive */
+ CreateDisposition = FILE_SUPERSEDE;
+ }
+
+ /* Setup the name */
+ RtlInitUnicodeString(&ExtensionName, Extension);
+ RtlAppendUnicodeStringToString(&FullName, &ExtensionName);
+
+ /* Initialize the attributes */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &FullName,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL);
+
+ /* Setup the flags */
+ IoFlags = FILE_NO_COMPRESSION | FILE_NO_INTERMEDIATE_BUFFERING;
+
+ /* Check if this is a log file */
+ if (!_wcsnicmp(Extension, L".log", 4))
+ {
+ /* Hide log files */
+ AttributeFlags |= FILE_ATTRIBUTE_HIDDEN;
+ }
+
+ /* Now create the file */
+ Status = ZwCreateFile(Log,
+ DesiredAccess,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ NULL,
+ AttributeFlags,
+ ShareMode,
+ CreateDisposition,
+ IoFlags,
+ NULL,
+ 0);
+ if ((NT_SUCCESS(Status)) && (MarkAsSystemHive))
+ {
+ /* We opened it, mark it as a system hive */
+ Status = ZwFsControlFile(*Log,
+ EventHandle,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ FSCTL_MARK_AS_SYSTEM_HIVE,
+ NULL,
+ 0,
+ NULL,
+ 0);
+ if (Status == STATUS_PENDING)
+ {
+ /* Wait for completion */
+ KeWaitForSingleObject(Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ Status = IoStatusBlock.Status;
+ }
+
+ /* If we don't support it, ignore the failure */
+ if (Status == STATUS_INVALID_DEVICE_REQUEST) Status = STATUS_SUCCESS;
+
+ /* If we failed, close the handle */
+ if (!NT_SUCCESS(Status)) ZwClose(*Log);
+ }
+
+ /* Check if anything failed until now */
+ if (!NT_SUCCESS(Status))
+ {
+ /* Clear the handle */
+ *Log = NULL;
+ }
+ else
+ {
+ /* Disable compression */
+ Status = ZwFsControlFile(*Log,
+ EventHandle,
+ NULL,
+ NULL,
+ &IoStatusBlock,
+ FSCTL_SET_COMPRESSION,
+ &CompressionState,
+ sizeof(CompressionState),
+ NULL,
+ 0);
+ if (Status == STATUS_PENDING)
+ {
+ /* Wait for completion */
+ KeWaitForSingleObject(Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ }
+
+ /* Return the disposition */
+ *LogDisposition = IoStatusBlock.Information;
+ }
+
+ /* We're done, close handles and free buffers */
+ if (NameBuffer) ExFreePool(NameBuffer);
+ ObDereferenceObject(Event);
+ ZwClose(EventHandle);
+ return STATUS_SUCCESS;
+}
Modified: trunk/reactos/ntoskrnl/config/cmsysini.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmsysini.c…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmsysini.c (original)
+++ trunk/reactos/ntoskrnl/config/cmsysini.c Sat May 12 02:51:11 2007
@@ -12,25 +12,6 @@
#include "cm.h"
#define NDEBUG
#include "debug.h"
-
-/* GLOBALS *******************************************************************/
-
-HIVE_LIST_ENTRY CmpMachineHiveList[5];
-
-UNICODE_STRING CmSymbolicLinkValueName =
- RTL_CONSTANT_STRING(L"SymbolicLinkValue");
-
-UNICODE_STRING CmpSystemStartOptions;
-UNICODE_STRING CmpLoadOptions;
-
-BOOLEAN CmpShareSystemHives;
-BOOLEAN CmSelfHeal = TRUE;
-BOOLEAN CmpSelfHeal = TRUE;
-ULONG CmpBootType;
-
-HANDLE CmpRegistryRootHandle;
-
-extern BOOLEAN ExpInTextModeSetup;
/* FUNCTIONS *****************************************************************/
Modified: trunk/reactos/ntoskrnl/config/cmwraprs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmwraprs.c…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmwraprs.c (original)
+++ trunk/reactos/ntoskrnl/config/cmwraprs.c Sat May 12 02:51:11 2007
@@ -14,6 +14,41 @@
#include "debug.h"
/* FUNCTIONS *****************************************************************/
+
+NTSTATUS
+NTAPI
+CmpCreateEvent(IN EVENT_TYPE EventType,
+ OUT PHANDLE EventHandle,
+ OUT PKEVENT *Event)
+{
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+
+ /* Create the event */
+ InitializeObjectAttributes(&ObjectAttributes,
+ NULL,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL);
+ Status = ZwCreateEvent(EventHandle,
+ EVENT_ALL_ACCESS,
+ &ObjectAttributes,
+ EventType,
+ FALSE);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Get a pointer to the object itself */
+ Status = ObReferenceObjectByHandle(*EventHandle,
+ EVENT_ALL_ACCESS,
+ NULL,
+ KernelMode,
+ (PVOID*)Event,
+ NULL);
+ if (!NT_SUCCESS(Status)) ZwClose(*EventHandle);
+
+ /* Return status */
+ return Status;
+}
PVOID
NTAPI