mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
Use ERESOURCE instead of spinlock to protect the hive list.
Use worker thread to run hive flush routine at dispatch level. - Changes by Hartmut Birr! Delete a key's hash block when the key is deleted. Update pointers and offsets in a key object when the key cell is deleted. svn path=/trunk/; revision=4134
This commit is contained in:
parent
0430d6bf60
commit
848ea5c2e0
4 changed files with 121 additions and 68 deletions
|
@ -332,7 +332,7 @@ extern POBJECT_TYPE CmiKeyType;
|
||||||
extern KSPIN_LOCK CmiKeyListLock;
|
extern KSPIN_LOCK CmiKeyListLock;
|
||||||
|
|
||||||
extern LIST_ENTRY CmiHiveListHead;
|
extern LIST_ENTRY CmiHiveListHead;
|
||||||
extern KSPIN_LOCK CmiHiveListLock;
|
extern ERESOURCE CmiHiveListLock;
|
||||||
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -143,6 +143,7 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
CreateOptions);
|
CreateOptions);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
/* Release hive lock */
|
||||||
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
ObDereferenceObject(Object);
|
ObDereferenceObject(Object);
|
||||||
|
@ -171,6 +172,8 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
|
|
||||||
CmiAddKeyToList(KeyObject->ParentKey, KeyObject);
|
CmiAddKeyToList(KeyObject->ParentKey, KeyObject);
|
||||||
|
|
||||||
|
VERIFY_KEY_OBJECT(KeyObject);
|
||||||
|
|
||||||
/* Release hive lock */
|
/* Release hive lock */
|
||||||
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
|
|
||||||
|
@ -180,8 +183,6 @@ NtCreateKey(OUT PHANDLE KeyHandle,
|
||||||
if (Disposition)
|
if (Disposition)
|
||||||
*Disposition = REG_CREATED_NEW_KEY;
|
*Disposition = REG_CREATED_NEW_KEY;
|
||||||
|
|
||||||
VERIFY_KEY_OBJECT(KeyObject);
|
|
||||||
|
|
||||||
CmiSyncHives();
|
CmiSyncHives();
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -197,6 +198,7 @@ NtDeleteKey(IN HANDLE KeyHandle)
|
||||||
DPRINT("KeyHandle %x\n", KeyHandle);
|
DPRINT("KeyHandle %x\n", KeyHandle);
|
||||||
|
|
||||||
/* Verify that the handle is valid and is a registry key */
|
/* Verify that the handle is valid and is a registry key */
|
||||||
|
CHECKPOINT1;
|
||||||
Status = ObReferenceObjectByHandle(KeyHandle,
|
Status = ObReferenceObjectByHandle(KeyHandle,
|
||||||
KEY_WRITE,
|
KEY_WRITE,
|
||||||
CmiKeyType,
|
CmiKeyType,
|
||||||
|
@ -205,28 +207,32 @@ NtDeleteKey(IN HANDLE KeyHandle)
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
CHECKPOINT1;
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CHECKPOINT1;
|
||||||
/* Acquire hive lock */
|
/* Acquire hive lock */
|
||||||
ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE);
|
ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE);
|
||||||
|
CHECKPOINT1;
|
||||||
|
|
||||||
VERIFY_KEY_OBJECT(KeyObject);
|
VERIFY_KEY_OBJECT(KeyObject);
|
||||||
|
|
||||||
/* Set the marked for delete bit in the key object */
|
/* Set the marked for delete bit in the key object */
|
||||||
KeyObject->Flags |= KO_MARKED_FOR_DELETE;
|
KeyObject->Flags |= KO_MARKED_FOR_DELETE;
|
||||||
|
CHECKPOINT1;
|
||||||
|
|
||||||
/* Release hive lock */
|
/* Release hive lock */
|
||||||
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
|
||||||
|
|
||||||
DPRINT("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
|
DPRINT1("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
|
||||||
|
|
||||||
/* Dereference the object */
|
/* Dereference the object */
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
if(KeyObject->RegistryHive != KeyObject->ParentKey->RegistryHive)
|
if(KeyObject->RegistryHive != KeyObject->ParentKey->RegistryHive)
|
||||||
ObDereferenceObject(KeyObject);
|
ObDereferenceObject(KeyObject);
|
||||||
|
|
||||||
DPRINT("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
|
DPRINT1("PointerCount %lu\n", ObGetObjectPointerCount((PVOID)KeyObject));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note:
|
* Note:
|
||||||
|
|
|
@ -809,7 +809,6 @@ CmiCreateRegistryHive(PWSTR Filename,
|
||||||
BOOLEAN CreateNew)
|
BOOLEAN CreateNew)
|
||||||
{
|
{
|
||||||
PREGISTRY_HIVE Hive;
|
PREGISTRY_HIVE Hive;
|
||||||
KIRQL oldlvl;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("CmiCreateRegistryHive(Filename %S)\n", Filename);
|
DPRINT("CmiCreateRegistryHive(Filename %S)\n", Filename);
|
||||||
|
@ -851,10 +850,14 @@ CmiCreateRegistryHive(PWSTR Filename,
|
||||||
|
|
||||||
ExInitializeResourceLite(&Hive->HiveResource);
|
ExInitializeResourceLite(&Hive->HiveResource);
|
||||||
|
|
||||||
|
/* Acquire hive list lock exclusively */
|
||||||
|
ExAcquireResourceExclusiveLite(&CmiHiveListLock, TRUE);
|
||||||
|
|
||||||
/* Add the new hive to the hive list */
|
/* Add the new hive to the hive list */
|
||||||
KeAcquireSpinLock(&CmiHiveListLock,&oldlvl);
|
|
||||||
InsertHeadList(&CmiHiveListHead, &Hive->HiveList);
|
InsertHeadList(&CmiHiveListHead, &Hive->HiveList);
|
||||||
KeReleaseSpinLock(&CmiHiveListLock,oldlvl);
|
|
||||||
|
/* Release hive list lock */
|
||||||
|
ExReleaseResourceLite(&CmiHiveListLock);
|
||||||
|
|
||||||
VERIFY_REGISTRY_HIVE(Hive);
|
VERIFY_REGISTRY_HIVE(Hive);
|
||||||
|
|
||||||
|
@ -869,12 +872,14 @@ CmiCreateRegistryHive(PWSTR Filename,
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
CmiRemoveRegistryHive(PREGISTRY_HIVE RegistryHive)
|
CmiRemoveRegistryHive(PREGISTRY_HIVE RegistryHive)
|
||||||
{
|
{
|
||||||
KIRQL oldlvl;
|
/* Acquire hive list lock exclusively */
|
||||||
|
ExAcquireResourceExclusiveLite(&CmiHiveListLock, TRUE);
|
||||||
|
|
||||||
/* Remove hive from hive list */
|
/* Remove hive from hive list */
|
||||||
KeAcquireSpinLock(&CmiHiveListLock,&oldlvl);
|
|
||||||
RemoveEntryList(&RegistryHive->HiveList);
|
RemoveEntryList(&RegistryHive->HiveList);
|
||||||
KeReleaseSpinLock(&CmiHiveListLock,oldlvl);
|
|
||||||
|
/* Release hive list lock */
|
||||||
|
ExReleaseResourceLite(&CmiHiveListLock);
|
||||||
|
|
||||||
|
|
||||||
/* FIXME: Remove attached keys and values */
|
/* FIXME: Remove attached keys and values */
|
||||||
|
@ -1385,46 +1390,56 @@ CmiRemoveSubKey(PREGISTRY_HIVE RegistryHive,
|
||||||
DPRINT1("CmiRemoveSubKey() called\n");
|
DPRINT1("CmiRemoveSubKey() called\n");
|
||||||
|
|
||||||
/* Remove the key from the parent key's hash block */
|
/* Remove the key from the parent key's hash block */
|
||||||
HashBlock = CmiGetBlock(RegistryHive,
|
if (ParentKey->KeyCell->HashTableOffset != -1)
|
||||||
ParentKey->KeyCell->HashTableOffset,
|
|
||||||
NULL);
|
|
||||||
if (HashBlock != NULL)
|
|
||||||
{
|
{
|
||||||
CmiRemoveKeyFromHashTable(RegistryHive,
|
DPRINT1("ParentKey HashTableOffset %lx\n", ParentKey->KeyCell->HashTableOffset)
|
||||||
HashBlock,
|
HashBlock = CmiGetBlock(RegistryHive,
|
||||||
SubKey->BlockOffset);
|
ParentKey->KeyCell->HashTableOffset,
|
||||||
CmiMarkBlockDirty(RegistryHive,
|
NULL);
|
||||||
ParentKey->KeyCell->HashTableOffset);
|
DPRINT1("ParentKey HashBlock %p\n", HashBlock)
|
||||||
|
if (HashBlock != NULL)
|
||||||
|
{
|
||||||
|
CmiRemoveKeyFromHashTable(RegistryHive,
|
||||||
|
HashBlock,
|
||||||
|
SubKey->BlockOffset);
|
||||||
|
CmiMarkBlockDirty(RegistryHive,
|
||||||
|
ParentKey->KeyCell->HashTableOffset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove the key's hash block */
|
/* Remove the key's hash block */
|
||||||
DPRINT1("HashTableOffset %lx\n", SubKey->KeyCell->HashTableOffset)
|
if (SubKey->KeyCell->HashTableOffset != -1)
|
||||||
if (SubKey->KeyCell->HashTableOffset != 0)
|
|
||||||
{
|
{
|
||||||
|
DPRINT1("SubKey HashTableOffset %lx\n", SubKey->KeyCell->HashTableOffset)
|
||||||
HashBlock = CmiGetBlock(RegistryHive,
|
HashBlock = CmiGetBlock(RegistryHive,
|
||||||
SubKey->KeyCell->HashTableOffset,
|
SubKey->KeyCell->HashTableOffset,
|
||||||
NULL);
|
NULL);
|
||||||
DPRINT1("HashBlock %p\n", HashBlock)
|
DPRINT1("SubKey HashBlock %p\n", HashBlock)
|
||||||
if (HashBlock != NULL)
|
if (HashBlock != NULL)
|
||||||
{
|
{
|
||||||
CmiDestroyBlock(RegistryHive,
|
CmiDestroyBlock(RegistryHive,
|
||||||
HashBlock,
|
HashBlock,
|
||||||
SubKey->KeyCell->HashTableOffset);
|
SubKey->KeyCell->HashTableOffset);
|
||||||
|
SubKey->KeyCell->HashTableOffset = -1;
|
||||||
}
|
}
|
||||||
SubKey->KeyCell->HashTableOffset = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECKPOINT1;
|
/* Decrement the number of the parent key's sub keys */
|
||||||
/* Remove the key from the parent key's hash block */
|
if (ParentKey != NULL)
|
||||||
ParentKey->KeyCell->NumberOfSubKeys--;
|
{
|
||||||
CmiMarkBlockDirty(RegistryHive,
|
DPRINT1("ParentKey %p\n", ParentKey)
|
||||||
ParentKey->BlockOffset);
|
ParentKey->KeyCell->NumberOfSubKeys--;
|
||||||
|
NtQuerySystemTime((PTIME)&ParentKey->KeyCell->LastWriteTime);
|
||||||
|
CmiMarkBlockDirty(RegistryHive,
|
||||||
|
ParentKey->BlockOffset);
|
||||||
|
}
|
||||||
|
|
||||||
CHECKPOINT1;
|
|
||||||
/* Destroy key cell */
|
/* Destroy key cell */
|
||||||
CmiDestroyBlock(RegistryHive,
|
CmiDestroyBlock(RegistryHive,
|
||||||
SubKey->KeyCell,
|
SubKey->KeyCell,
|
||||||
SubKey->BlockOffset);
|
SubKey->BlockOffset);
|
||||||
|
SubKey->BlockOffset = -1;
|
||||||
|
SubKey->KeyCell = NULL;
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: registry.c,v 1.82 2003/02/09 11:57:14 ekohl Exp $
|
/* $Id: registry.c,v 1.83 2003/02/10 21:24:45 ekohl Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -35,7 +35,7 @@ PREGISTRY_HIVE CmiVolatileHive = NULL;
|
||||||
KSPIN_LOCK CmiKeyListLock;
|
KSPIN_LOCK CmiKeyListLock;
|
||||||
|
|
||||||
LIST_ENTRY CmiHiveListHead;
|
LIST_ENTRY CmiHiveListHead;
|
||||||
KSPIN_LOCK CmiHiveListLock;
|
ERESOURCE CmiHiveListLock;
|
||||||
|
|
||||||
volatile BOOLEAN CmiHiveSyncEnabled = FALSE;
|
volatile BOOLEAN CmiHiveSyncEnabled = FALSE;
|
||||||
volatile BOOLEAN CmiHiveSyncPending = FALSE;
|
volatile BOOLEAN CmiHiveSyncPending = FALSE;
|
||||||
|
@ -157,37 +157,37 @@ CmiCheckValues(BOOLEAN Verbose,
|
||||||
Index = 0;
|
Index = 0;
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
BufferSize = sizeof(KEY_NODE_INFORMATION) + 4096;
|
BufferSize = sizeof(KEY_NODE_INFORMATION) + 4096;
|
||||||
ValueInfo = ExAllocatePool(PagedPool, BufferSize);
|
ValueInfo = ExAllocatePool(PagedPool, BufferSize);
|
||||||
|
|
||||||
Status = NtEnumerateValueKey(Key,
|
Status = NtEnumerateValueKey(Key,
|
||||||
Index,
|
Index,
|
||||||
KeyNodeInformation,
|
KeyNodeInformation,
|
||||||
ValueInfo,
|
ValueInfo,
|
||||||
BufferSize,
|
BufferSize,
|
||||||
&ResultSize);
|
&ResultSize);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ExFreePool(ValueInfo);
|
ExFreePool(ValueInfo);
|
||||||
if (Status == STATUS_NO_MORE_ENTRIES)
|
if (Status == STATUS_NO_MORE_ENTRIES)
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
wcsncpy(Name,
|
wcsncpy(Name,
|
||||||
ValueInfo->Name,
|
ValueInfo->Name,
|
||||||
ValueInfo->NameLength / sizeof(WCHAR));
|
ValueInfo->NameLength / sizeof(WCHAR));
|
||||||
|
|
||||||
if (Verbose)
|
if (Verbose)
|
||||||
{
|
{
|
||||||
DbgPrint("Value: %S\n", Name);
|
DbgPrint("Value: %S\n", Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: Check info. */
|
/* FIXME: Check info. */
|
||||||
|
|
||||||
ExFreePool(ValueInfo);
|
ExFreePool(ValueInfo);
|
||||||
|
|
||||||
Index++;
|
Index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(NT_SUCCESS(Status));
|
assert(NT_SUCCESS(Status));
|
||||||
|
@ -264,7 +264,7 @@ CmInitializeRegistry(VOID)
|
||||||
PKEY_OBJECT NewKey;
|
PKEY_OBJECT NewKey;
|
||||||
HANDLE KeyHandle;
|
HANDLE KeyHandle;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* Initialize the Key object type */
|
/* Initialize the Key object type */
|
||||||
CmiKeyType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
|
CmiKeyType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
|
||||||
assert(CmiKeyType);
|
assert(CmiKeyType);
|
||||||
|
@ -289,7 +289,7 @@ CmInitializeRegistry(VOID)
|
||||||
|
|
||||||
/* Initialize the hive list */
|
/* Initialize the hive list */
|
||||||
InitializeListHead(&CmiHiveListHead);
|
InitializeListHead(&CmiHiveListHead);
|
||||||
KeInitializeSpinLock(&CmiHiveListLock);
|
ExInitializeResourceLite(&CmiHiveListLock);
|
||||||
|
|
||||||
/* Build volatile registry store */
|
/* Build volatile registry store */
|
||||||
Status = CmiCreateRegistryHive(NULL, &CmiVolatileHive, FALSE);
|
Status = CmiCreateRegistryHive(NULL, &CmiVolatileHive, FALSE);
|
||||||
|
@ -845,7 +845,7 @@ CmiInitHives(BOOLEAN SetUpBoot)
|
||||||
}
|
}
|
||||||
wcscat(ConfigPath, L"\\system32\\config");
|
wcscat(ConfigPath, L"\\system32\\config");
|
||||||
|
|
||||||
DPRINT1("ConfigPath: %S\n", ConfigPath);
|
DPRINT("ConfigPath: %S\n", ConfigPath);
|
||||||
|
|
||||||
EndPtr = ConfigPath + wcslen(ConfigPath);
|
EndPtr = ConfigPath + wcslen(ConfigPath);
|
||||||
|
|
||||||
|
@ -944,14 +944,15 @@ CmShutdownRegistry(VOID)
|
||||||
{
|
{
|
||||||
PREGISTRY_HIVE Hive;
|
PREGISTRY_HIVE Hive;
|
||||||
PLIST_ENTRY Entry;
|
PLIST_ENTRY Entry;
|
||||||
// KIRQL oldlvl;
|
|
||||||
|
|
||||||
DPRINT1("CmShutdownRegistry() called\n");
|
DPRINT1("CmShutdownRegistry() called\n");
|
||||||
|
|
||||||
/* Stop automatic hive synchronization */
|
/* Stop automatic hive synchronization */
|
||||||
CmiHiveSyncEnabled = FALSE;
|
CmiHiveSyncEnabled = FALSE;
|
||||||
|
|
||||||
// KeAcquireSpinLock(&CmiHiveListLock,&oldlvl);
|
/* Acquire hive list lock exclusively */
|
||||||
|
ExAcquireResourceExclusiveLite(&CmiHiveListLock, TRUE);
|
||||||
|
|
||||||
Entry = CmiHiveListHead.Flink;
|
Entry = CmiHiveListHead.Flink;
|
||||||
while (Entry != &CmiHiveListHead)
|
while (Entry != &CmiHiveListHead)
|
||||||
{
|
{
|
||||||
|
@ -976,27 +977,27 @@ CmShutdownRegistry(VOID)
|
||||||
|
|
||||||
Entry = Entry->Flink;
|
Entry = Entry->Flink;
|
||||||
}
|
}
|
||||||
// KeReleaseSpinLock(&CmiHiveListLock,oldlvl);
|
|
||||||
|
|
||||||
DPRINT1("CmShutdownRegistry() called\n");
|
/* Release hive list lock */
|
||||||
|
ExReleaseResourceLite(&CmiHiveListLock);
|
||||||
|
|
||||||
|
DPRINT1("CmShutdownRegistry() done\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static VOID STDCALL
|
VOID STDCALL
|
||||||
CmiHiveSyncDpcRoutine(PKDPC Dpc,
|
CmiHiveSyncRoutine(PVOID DeferredContext)
|
||||||
PVOID DeferredContext,
|
|
||||||
PVOID SystemArgument1,
|
|
||||||
PVOID SystemArgument2)
|
|
||||||
{
|
{
|
||||||
PREGISTRY_HIVE Hive;
|
PREGISTRY_HIVE Hive;
|
||||||
PLIST_ENTRY Entry;
|
PLIST_ENTRY Entry;
|
||||||
KIRQL oldlvl;
|
|
||||||
|
|
||||||
DPRINT1("CmiHiveSyncDpcRoutine() called\n");
|
DPRINT1("CmiHiveSyncRoutine() called\n");
|
||||||
|
|
||||||
CmiHiveSyncPending = FALSE;
|
CmiHiveSyncPending = FALSE;
|
||||||
|
|
||||||
KeAcquireSpinLock(&CmiHiveListLock,&oldlvl);
|
/* Acquire hive list lock exclusively */
|
||||||
|
ExAcquireResourceExclusiveLite(&CmiHiveListLock, TRUE);
|
||||||
|
|
||||||
Entry = CmiHiveListHead.Flink;
|
Entry = CmiHiveListHead.Flink;
|
||||||
while (Entry != &CmiHiveListHead)
|
while (Entry != &CmiHiveListHead)
|
||||||
{
|
{
|
||||||
|
@ -1017,7 +1018,38 @@ CmiHiveSyncDpcRoutine(PKDPC Dpc,
|
||||||
|
|
||||||
Entry = Entry->Flink;
|
Entry = Entry->Flink;
|
||||||
}
|
}
|
||||||
KeReleaseSpinLock(&CmiHiveListLock,oldlvl);
|
|
||||||
|
/* Release hive list lock */
|
||||||
|
ExReleaseResourceLite(&CmiHiveListLock);
|
||||||
|
|
||||||
|
DPRINT("DeferredContext %x\n", DeferredContext);
|
||||||
|
ExFreePool(DeferredContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static VOID STDCALL
|
||||||
|
CmiHiveSyncDpcRoutine(PKDPC Dpc,
|
||||||
|
PVOID DeferredContext,
|
||||||
|
PVOID SystemArgument1,
|
||||||
|
PVOID SystemArgument2)
|
||||||
|
{
|
||||||
|
PWORK_QUEUE_ITEM WorkQueueItem;
|
||||||
|
|
||||||
|
WorkQueueItem = ExAllocatePool(NonPagedPool,
|
||||||
|
sizeof(WORK_QUEUE_ITEM));
|
||||||
|
if (WorkQueueItem == NULL)
|
||||||
|
{
|
||||||
|
DbgPrint("Failed to allocate work item\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ExInitializeWorkItem(WorkQueueItem,
|
||||||
|
CmiHiveSyncRoutine,
|
||||||
|
WorkQueueItem);
|
||||||
|
|
||||||
|
DPRINT("DeferredContext %x\n", WorkQueueItem);
|
||||||
|
ExQueueWorkItem(WorkQueueItem,
|
||||||
|
CriticalWorkQueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue