mirror of
https://github.com/reactos/reactos.git
synced 2024-10-06 17:35:07 +00:00
- 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. svn path=/trunk/; revision=26705
This commit is contained in:
parent
57ddb7b014
commit
47687d1136
|
@ -496,6 +496,19 @@ BOOLEAN
|
|||
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)
|
||||
{
|
||||
|
|
|
@ -283,63 +283,6 @@ CmiRemoveRegistryHive(PEREGISTRY_HIVE RegistryHive)
|
|||
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 @@ CmiFlushRegistryHive(PEREGISTRY_HIVE RegistryHive)
|
|||
{
|
||||
BOOLEAN Success;
|
||||
NTSTATUS Status;
|
||||
ULONG Disposition;
|
||||
|
||||
ASSERT(!IsNoFileHive(RegistryHive));
|
||||
|
||||
|
@ -361,7 +305,16 @@ CmiFlushRegistryHive(PEREGISTRY_HIVE RegistryHive)
|
|||
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;
|
||||
|
|
|
@ -1007,6 +1007,14 @@ CmpInitializeRegistryNode(
|
|||
//
|
||||
// Wrapper Routines
|
||||
//
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CmpCreateEvent(
|
||||
IN EVENT_TYPE EventType,
|
||||
OUT PHANDLE EventHandle,
|
||||
OUT PKEVENT *Event
|
||||
);
|
||||
|
||||
PVOID
|
||||
NTAPI
|
||||
CmpAllocate(
|
||||
|
@ -1060,6 +1068,8 @@ CmpFileFlush(
|
|||
//
|
||||
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 CM_SYSTEM_CONTROL_VECTOR CmControlVector[];
|
|||
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;
|
||||
|
||||
//
|
||||
|
|
|
@ -38,6 +38,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] =
|
||||
{
|
||||
RTL_CONSTANT_STRING(L"System"),
|
||||
|
|
|
@ -226,3 +226,357 @@ CmpInitializeHive(OUT PCMHIVE *RegistryHive,
|
|||
*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;
|
||||
}
|
||||
|
|
|
@ -13,25 +13,6 @@
|
|||
#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 *****************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
|
|
|
@ -15,6 +15,41 @@
|
|||
|
||||
/* 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
|
||||
CmpAllocate(IN ULONG Size,
|
||||
|
|
Loading…
Reference in a new issue