2007-12-15 18:14:41 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS Kernel
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
|
|
* FILE: ntoskrnl/config/cmwraprs.c
|
|
|
|
* PURPOSE: Configuration Manager - Wrappers for Hive Operations
|
|
|
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
|
|
|
#include "ntoskrnl.h"
|
|
|
|
#define NDEBUG
|
|
|
|
#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
|
2010-01-13 22:35:43 +00:00
|
|
|
CmpAllocate(IN SIZE_T Size,
|
2007-12-15 18:14:41 +00:00
|
|
|
IN BOOLEAN Paged,
|
|
|
|
IN ULONG Tag)
|
|
|
|
{
|
|
|
|
return ExAllocatePoolWithTag(Paged ? PagedPool : NonPagedPool,
|
|
|
|
Size,
|
|
|
|
Tag);
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
CmpFree(IN PVOID Ptr,
|
|
|
|
IN ULONG Quota)
|
|
|
|
{
|
|
|
|
ExFreePool(Ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
|
|
|
CmpFileRead(IN PHHIVE RegistryHive,
|
|
|
|
IN ULONG FileType,
|
|
|
|
IN PULONG FileOffset,
|
|
|
|
OUT PVOID Buffer,
|
|
|
|
IN SIZE_T BufferLength)
|
|
|
|
{
|
|
|
|
PCMHIVE CmHive = (PCMHIVE)RegistryHive;
|
|
|
|
HANDLE HiveHandle = CmHive->FileHandles[FileType];
|
|
|
|
LARGE_INTEGER _FileOffset;
|
|
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
2017-11-12 21:02:45 +00:00
|
|
|
/* Just return success if no file is associated with this hive */
|
|
|
|
if (HiveHandle == NULL)
|
|
|
|
return TRUE;
|
|
|
|
|
2007-12-15 18:14:41 +00:00
|
|
|
_FileOffset.QuadPart = *FileOffset;
|
2017-10-25 11:57:27 +00:00
|
|
|
Status = ZwReadFile(HiveHandle, NULL, NULL, NULL, &IoStatusBlock,
|
|
|
|
Buffer, (ULONG)BufferLength, &_FileOffset, NULL);
|
2022-11-02 00:10:04 +00:00
|
|
|
/* We do synchronous I/O for simplicity - see CmpOpenHiveFiles. */
|
|
|
|
ASSERT(Status != STATUS_PENDING);
|
2007-12-15 18:14:41 +00:00
|
|
|
return NT_SUCCESS(Status) ? TRUE : FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
|
|
|
CmpFileWrite(IN PHHIVE RegistryHive,
|
|
|
|
IN ULONG FileType,
|
|
|
|
IN PULONG FileOffset,
|
|
|
|
IN PVOID Buffer,
|
|
|
|
IN SIZE_T BufferLength)
|
|
|
|
{
|
|
|
|
PCMHIVE CmHive = (PCMHIVE)RegistryHive;
|
|
|
|
HANDLE HiveHandle = CmHive->FileHandles[FileType];
|
|
|
|
LARGE_INTEGER _FileOffset;
|
|
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
2017-11-12 21:02:45 +00:00
|
|
|
/* Just return success if no file is associated with this hive */
|
|
|
|
if (HiveHandle == NULL)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
/* Don't do anything if we're not supposed to */
|
|
|
|
if (CmpNoWrite)
|
|
|
|
return TRUE;
|
|
|
|
|
2007-12-15 18:14:41 +00:00
|
|
|
_FileOffset.QuadPart = *FileOffset;
|
2017-10-28 15:02:24 +00:00
|
|
|
Status = ZwWriteFile(HiveHandle, NULL, NULL, NULL, &IoStatusBlock,
|
|
|
|
Buffer, (ULONG)BufferLength, &_FileOffset, NULL);
|
2022-11-02 00:10:04 +00:00
|
|
|
/* We do synchronous I/O for simplicity - see CmpOpenHiveFiles.
|
|
|
|
* Windows optimizes here by starting an async write for each 64k chunk,
|
|
|
|
* then waiting for all writes to complete at once.
|
|
|
|
*/
|
|
|
|
ASSERT(Status != STATUS_PENDING);
|
2007-12-15 18:14:41 +00:00
|
|
|
return NT_SUCCESS(Status) ? TRUE : FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
2022-10-26 17:00:08 +00:00
|
|
|
CmpFileSetSize(
|
|
|
|
_In_ PHHIVE RegistryHive,
|
|
|
|
_In_ ULONG FileType,
|
|
|
|
_In_ ULONG FileSize,
|
|
|
|
_In_ ULONG OldFileSize)
|
2007-12-15 18:14:41 +00:00
|
|
|
{
|
|
|
|
PCMHIVE CmHive = (PCMHIVE)RegistryHive;
|
|
|
|
HANDLE HiveHandle = CmHive->FileHandles[FileType];
|
|
|
|
FILE_END_OF_FILE_INFORMATION EndOfFileInfo;
|
|
|
|
FILE_ALLOCATION_INFORMATION FileAllocationInfo;
|
|
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
2022-10-26 17:00:08 +00:00
|
|
|
BOOLEAN HardErrors;
|
2007-12-15 18:14:41 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
|
2017-11-12 21:02:45 +00:00
|
|
|
/* Just return success if no file is associated with this hive */
|
|
|
|
if (HiveHandle == NULL)
|
2022-10-26 17:00:08 +00:00
|
|
|
{
|
|
|
|
DPRINT1("No hive handle associated with the given hive\n");
|
2017-11-12 21:02:45 +00:00
|
|
|
return TRUE;
|
2022-10-26 17:00:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Disable hard errors so that we don't deadlock
|
|
|
|
* when touching with the hive files.
|
|
|
|
*/
|
|
|
|
HardErrors = IoSetThreadHardErrorMode(FALSE);
|
2017-11-12 21:02:45 +00:00
|
|
|
|
2007-12-15 18:14:41 +00:00
|
|
|
EndOfFileInfo.EndOfFile.QuadPart = FileSize;
|
|
|
|
Status = ZwSetInformationFile(HiveHandle,
|
|
|
|
&IoStatusBlock,
|
|
|
|
&EndOfFileInfo,
|
|
|
|
sizeof(FILE_END_OF_FILE_INFORMATION),
|
|
|
|
FileEndOfFileInformation);
|
2022-10-26 17:00:08 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("ZwSetInformationFile failed to set new size of end of file (Status 0x%lx)\n", Status);
|
|
|
|
IoSetThreadHardErrorMode(HardErrors);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2007-12-15 18:14:41 +00:00
|
|
|
|
|
|
|
FileAllocationInfo.AllocationSize.QuadPart = FileSize;
|
|
|
|
Status = ZwSetInformationFile(HiveHandle,
|
|
|
|
&IoStatusBlock,
|
|
|
|
&FileAllocationInfo,
|
|
|
|
sizeof(FILE_ALLOCATION_INFORMATION),
|
|
|
|
FileAllocationInformation);
|
2022-10-26 17:00:08 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("ZwSetInformationFile failed to set new of allocation file (Status 0x%lx)\n", Status);
|
|
|
|
IoSetThreadHardErrorMode(HardErrors);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Reset the hard errors back */
|
|
|
|
IoSetThreadHardErrorMode(HardErrors);
|
2007-12-15 18:14:41 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
|
|
|
CmpFileFlush(IN PHHIVE RegistryHive,
|
|
|
|
IN ULONG FileType,
|
|
|
|
IN OUT PLARGE_INTEGER FileOffset,
|
|
|
|
IN ULONG Length)
|
|
|
|
{
|
|
|
|
PCMHIVE CmHive = (PCMHIVE)RegistryHive;
|
|
|
|
HANDLE HiveHandle = CmHive->FileHandles[FileType];
|
|
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
2017-11-12 21:02:45 +00:00
|
|
|
/* Just return success if no file is associated with this hive */
|
|
|
|
if (HiveHandle == NULL)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
/* Don't do anything if we're not supposed to */
|
|
|
|
if (CmpNoWrite)
|
|
|
|
return TRUE;
|
|
|
|
|
2007-12-15 18:14:41 +00:00
|
|
|
Status = ZwFlushBuffersFile(HiveHandle, &IoStatusBlock);
|
2022-11-02 00:10:04 +00:00
|
|
|
|
|
|
|
/* This operation is always synchronous */
|
|
|
|
ASSERT(Status != STATUS_PENDING);
|
|
|
|
ASSERT(Status == IoStatusBlock.Status);
|
|
|
|
|
2007-12-15 18:14:41 +00:00
|
|
|
return NT_SUCCESS(Status) ? TRUE : FALSE;
|
|
|
|
}
|