- Move NtCreateKey to regobj.c, delete ntfunc.c, now all those routines exist solely for creating keys.

- Move NtOpenKey to ntapi.c and rewrite it to use the new parse routine. It's now 6 lines of code instead of 80.
- Fix a bug in CmpDereferenceNameCnotrolBlockWithLock.
- Fix bugs during reference and dereference of KCB.
- Fix KCB structure.
- CmpDelayDerefKCBWorker is now called, don't make it assert anymore, just print out that it's not completed.
- Remove debug output from new parse routine, since it's now called for each key open.
- Add one more case to handle: opening the root \REGISTRY node.
- Don't dereference KCBs in the parse routine anymore: we have some bugs related to this and it would make ReactOS crash.

svn path=/trunk/; revision=31094
This commit is contained in:
Aleksey Bragin 2007-12-08 21:00:45 +00:00
parent f7d91421f8
commit 60fad32ecf
8 changed files with 310 additions and 397 deletions

View file

@ -1,289 +0,0 @@
/*
* PROJECT: ReactOS Kernel
* COPYRIGHT: GPL - See COPYING in the top level directory
* FILE: ntoskrnl/cm/ntfunc.c
* PURPOSE: Ntxxx function for registry access
*
* PROGRAMMERS: Hartmut Birr
* Casper Hornstrup
* Alex Ionescu
* Rex Jolliff
* Eric Kohl
* Filip Navara
* Thomas Weidenmueller
*/
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
#include "cm.h"
/* GLOBALS ******************************************************************/
NTSTATUS
NTAPI
CmpCreateHandle(PVOID ObjectBody,
ACCESS_MASK GrantedAccess,
ULONG HandleAttributes,
PHANDLE HandleReturn);
/* FUNCTIONS ****************************************************************/
NTSTATUS
NTAPI
NtCreateKey(OUT PHANDLE KeyHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN ULONG TitleIndex,
IN PUNICODE_STRING Class,
IN ULONG CreateOptions,
OUT PULONG Disposition)
{
UNICODE_STRING RemainingPath = {0}, ReturnedPath = {0};
ULONG LocalDisposition;
PCM_KEY_BODY KeyObject, Parent;
NTSTATUS Status = STATUS_SUCCESS;
UNICODE_STRING ObjectName;
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
ULONG i;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
HANDLE hKey;
PCM_KEY_NODE Node, ParentNode;
CM_PARSE_CONTEXT ParseContext = {0};
PAGED_CODE();
/* Setup the parse context */
ParseContext.CreateOperation = TRUE;
ParseContext.CreateOptions = CreateOptions;
if (Class) ParseContext.Class = *Class;
/* Capture all the info */
Status = ObpCaptureObjectAttributes(ObjectAttributes,
PreviousMode,
FALSE,
&ObjectCreateInfo,
&ObjectName);
if (!NT_SUCCESS(Status)) return Status;
/* Find the key object */
Status = CmFindObject(&ObjectCreateInfo,
&ObjectName,
(PVOID*)&Parent,
&ReturnedPath,
CmpKeyObjectType,
NULL,
NULL);
if (!NT_SUCCESS(Status)) goto Cleanup;
/* Check if we found the entire path */
RemainingPath = ReturnedPath;
if (!RemainingPath.Length)
{
/* Check if the parent has been deleted */
if (Parent->KeyControlBlock->Delete)
{
/* Fail */
DPRINT1("Object marked for delete!\n");
Status = STATUS_UNSUCCESSFUL;
goto Cleanup;
}
/* Create a new handle to the parent */
Status = CmpCreateHandle(Parent,
DesiredAccess,
ObjectCreateInfo.Attributes,
&hKey);
if (!NT_SUCCESS(Status)) goto Cleanup;
/* Tell the caller we did this */
LocalDisposition = REG_OPENED_EXISTING_KEY;
goto SuccessReturn;
}
/* Loop every leading slash */
while ((RemainingPath.Length) &&
(*RemainingPath.Buffer == OBJ_NAME_PATH_SEPARATOR))
{
/* And remove it */
RemainingPath.Length -= sizeof(WCHAR);
RemainingPath.MaximumLength -= sizeof(WCHAR);
RemainingPath.Buffer++;
}
/* Loop every terminating slash */
while ((RemainingPath.Length) &&
(RemainingPath.Buffer[(RemainingPath.Length / sizeof(WCHAR)) - 1] ==
OBJ_NAME_PATH_SEPARATOR))
{
/* And remove it */
RemainingPath.Length -= sizeof(WCHAR);
RemainingPath.MaximumLength -= sizeof(WCHAR);
}
/* Now loop the entire path */
for (i = 0; i < RemainingPath.Length / sizeof(WCHAR); i++)
{
/* And check if we found slahes */
if (RemainingPath.Buffer[i] == OBJ_NAME_PATH_SEPARATOR)
{
/* We don't create trees -- parent key doesn't exist, so fail */
Status = STATUS_OBJECT_NAME_NOT_FOUND;
goto Cleanup;
}
}
/* Now check if we're left with no name by this point */
if (!(RemainingPath.Length) || (RemainingPath.Buffer[0] == UNICODE_NULL))
{
/* Then fail since we can't do anything */
Status = STATUS_OBJECT_NAME_NOT_FOUND;
goto Cleanup;
}
/* Lock the registry */
CmpLockRegistry();
/* Create the key */
Status = CmpDoCreate(Parent->KeyControlBlock->KeyHive,
Parent->KeyControlBlock->KeyCell,
NULL,
&RemainingPath,
KernelMode,
&ParseContext,
Parent->KeyControlBlock,
(PVOID*)&KeyObject);
if (!NT_SUCCESS(Status)) goto Cleanup;
/* If we got here, this is a new key */
LocalDisposition = REG_CREATED_NEW_KEY;
/* Get the parent node and the child node */
ParentNode = (PCM_KEY_NODE)HvGetCell(KeyObject->KeyControlBlock->ParentKcb->KeyHive,
KeyObject->KeyControlBlock->ParentKcb->KeyCell);
Node = (PCM_KEY_NODE)HvGetCell(KeyObject->KeyControlBlock->KeyHive,
KeyObject->KeyControlBlock->KeyCell);
/* Inherit some information */
Node->Parent = KeyObject->KeyControlBlock->ParentKcb->KeyCell;
Node->Security = ParentNode->Security;
KeyObject->KeyControlBlock->ValueCache.ValueList = Node->ValueList.List;
KeyObject->KeyControlBlock->ValueCache.Count = Node->ValueList.Count;
/* Link child to parent */
InsertTailList(&Parent->KeyControlBlock->KeyBodyListHead, &KeyObject->KeyBodyList);
/* Create the actual handle to the object */
Status = CmpCreateHandle(KeyObject,
DesiredAccess,
ObjectCreateInfo.Attributes,
&hKey);
/* Free the create information */
ObpFreeAndReleaseCapturedAttributes(OBJECT_TO_OBJECT_HEADER(KeyObject)->ObjectCreateInfo);
OBJECT_TO_OBJECT_HEADER(KeyObject)->ObjectCreateInfo = NULL;
if (!NT_SUCCESS(Status)) goto Cleanup;
/* Add the keep-alive reference */
ObReferenceObject(KeyObject);
/* Unlock registry */
CmpUnlockRegistry();
/* Force a lazy flush */
CmpLazyFlush();
SuccessReturn:
/* Return data to user */
*KeyHandle = hKey;
if (Disposition) *Disposition = LocalDisposition;
Cleanup:
/* Cleanup */
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
if (ObjectName.Buffer) ObpFreeObjectNameBuffer(&ObjectName);
RtlFreeUnicodeString(&ReturnedPath);
if (Parent) ObDereferenceObject(Parent);
return Status;
}
NTSTATUS
NTAPI
NtOpenKey(OUT PHANDLE KeyHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes)
{
UNICODE_STRING RemainingPath = {0};
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
PCM_KEY_BODY Object = NULL;
HANDLE hKey = NULL;
NTSTATUS Status = STATUS_SUCCESS;
UNICODE_STRING ObjectName;
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
PAGED_CODE();
/* Capture all the info */
Status = ObpCaptureObjectAttributes(ObjectAttributes,
PreviousMode,
FALSE,
&ObjectCreateInfo,
&ObjectName);
if (!NT_SUCCESS(Status)) return Status;
/* Loop every terminating slash */
while ((ObjectName.Length) &&
(ObjectName.Buffer[(ObjectName.Length / sizeof(WCHAR)) - 1] ==
OBJ_NAME_PATH_SEPARATOR))
{
/* And remove it */
ObjectName.Length -= sizeof(WCHAR);
ObjectName.MaximumLength -= sizeof(WCHAR);
}
/* Find the key */
Status = CmFindObject(&ObjectCreateInfo,
&ObjectName,
(PVOID*)&Object,
&RemainingPath,
CmpKeyObjectType,
NULL,
NULL);
if (!NT_SUCCESS(Status)) goto openkey_cleanup;
/* Make sure we don't have any remaining path */
if ((RemainingPath.Buffer) && (RemainingPath.Buffer[0] != UNICODE_NULL))
{
/* Fail */
Status = STATUS_OBJECT_NAME_NOT_FOUND;
goto openkey_cleanup;
}
/* Check if the key has been deleted */
if (Object->KeyControlBlock->Delete)
{
/* Fail */
Status = STATUS_UNSUCCESSFUL;
goto openkey_cleanup;
}
/* Create the actual handle */
Status = CmpCreateHandle(Object,
DesiredAccess,
ObjectCreateInfo.Attributes,
&hKey);
openkey_cleanup:
/* Cleanup */
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
if (ObjectName.Buffer) ObpFreeObjectNameBuffer(&ObjectName);
RtlFreeUnicodeString(&RemainingPath);
if (Object) ObDereferenceObject(Object);
/* Return information and status to user */
*KeyHandle = hKey;
return Status;
}
/* EOF */

View file

@ -875,4 +875,181 @@ CmiGetLinkTarget(PCMHIVE RegistryHive,
return(STATUS_SUCCESS);
}
NTSTATUS
NTAPI
NtCreateKey(OUT PHANDLE KeyHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN ULONG TitleIndex,
IN PUNICODE_STRING Class,
IN ULONG CreateOptions,
OUT PULONG Disposition)
{
UNICODE_STRING RemainingPath = {0}, ReturnedPath = {0};
ULONG LocalDisposition;
PCM_KEY_BODY KeyObject, Parent;
NTSTATUS Status = STATUS_SUCCESS;
UNICODE_STRING ObjectName;
OBJECT_CREATE_INFORMATION ObjectCreateInfo;
ULONG i;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
HANDLE hKey;
PCM_KEY_NODE Node, ParentNode;
CM_PARSE_CONTEXT ParseContext = {0};
PAGED_CODE();
/* Setup the parse context */
ParseContext.CreateOperation = TRUE;
ParseContext.CreateOptions = CreateOptions;
if (Class) ParseContext.Class = *Class;
/* Capture all the info */
Status = ObpCaptureObjectAttributes(ObjectAttributes,
PreviousMode,
FALSE,
&ObjectCreateInfo,
&ObjectName);
if (!NT_SUCCESS(Status)) return Status;
/* Find the key object */
Status = CmFindObject(&ObjectCreateInfo,
&ObjectName,
(PVOID*)&Parent,
&ReturnedPath,
CmpKeyObjectType,
NULL,
NULL);
if (!NT_SUCCESS(Status)) goto Cleanup;
/* Check if we found the entire path */
RemainingPath = ReturnedPath;
if (!RemainingPath.Length)
{
/* Check if the parent has been deleted */
if (Parent->KeyControlBlock->Delete)
{
/* Fail */
DPRINT1("Object marked for delete!\n");
Status = STATUS_UNSUCCESSFUL;
goto Cleanup;
}
/* Create a new handle to the parent */
Status = CmpCreateHandle(Parent,
DesiredAccess,
ObjectCreateInfo.Attributes,
&hKey);
if (!NT_SUCCESS(Status)) goto Cleanup;
/* Tell the caller we did this */
LocalDisposition = REG_OPENED_EXISTING_KEY;
goto SuccessReturn;
}
/* Loop every leading slash */
while ((RemainingPath.Length) &&
(*RemainingPath.Buffer == OBJ_NAME_PATH_SEPARATOR))
{
/* And remove it */
RemainingPath.Length -= sizeof(WCHAR);
RemainingPath.MaximumLength -= sizeof(WCHAR);
RemainingPath.Buffer++;
}
/* Loop every terminating slash */
while ((RemainingPath.Length) &&
(RemainingPath.Buffer[(RemainingPath.Length / sizeof(WCHAR)) - 1] ==
OBJ_NAME_PATH_SEPARATOR))
{
/* And remove it */
RemainingPath.Length -= sizeof(WCHAR);
RemainingPath.MaximumLength -= sizeof(WCHAR);
}
/* Now loop the entire path */
for (i = 0; i < RemainingPath.Length / sizeof(WCHAR); i++)
{
/* And check if we found slahes */
if (RemainingPath.Buffer[i] == OBJ_NAME_PATH_SEPARATOR)
{
/* We don't create trees -- parent key doesn't exist, so fail */
Status = STATUS_OBJECT_NAME_NOT_FOUND;
goto Cleanup;
}
}
/* Now check if we're left with no name by this point */
if (!(RemainingPath.Length) || (RemainingPath.Buffer[0] == UNICODE_NULL))
{
/* Then fail since we can't do anything */
Status = STATUS_OBJECT_NAME_NOT_FOUND;
goto Cleanup;
}
/* Lock the registry */
CmpLockRegistry();
/* Create the key */
Status = CmpDoCreate(Parent->KeyControlBlock->KeyHive,
Parent->KeyControlBlock->KeyCell,
NULL,
&RemainingPath,
KernelMode,
&ParseContext,
Parent->KeyControlBlock,
(PVOID*)&KeyObject);
if (!NT_SUCCESS(Status)) goto Cleanup;
/* If we got here, this is a new key */
LocalDisposition = REG_CREATED_NEW_KEY;
/* Get the parent node and the child node */
ParentNode = (PCM_KEY_NODE)HvGetCell(KeyObject->KeyControlBlock->ParentKcb->KeyHive,
KeyObject->KeyControlBlock->ParentKcb->KeyCell);
Node = (PCM_KEY_NODE)HvGetCell(KeyObject->KeyControlBlock->KeyHive,
KeyObject->KeyControlBlock->KeyCell);
/* Inherit some information */
Node->Parent = KeyObject->KeyControlBlock->ParentKcb->KeyCell;
Node->Security = ParentNode->Security;
KeyObject->KeyControlBlock->ValueCache.ValueList = Node->ValueList.List;
KeyObject->KeyControlBlock->ValueCache.Count = Node->ValueList.Count;
/* Link child to parent */
InsertTailList(&Parent->KeyControlBlock->KeyBodyListHead, &KeyObject->KeyBodyList);
/* Create the actual handle to the object */
Status = CmpCreateHandle(KeyObject,
DesiredAccess,
ObjectCreateInfo.Attributes,
&hKey);
/* Free the create information */
ObpFreeAndReleaseCapturedAttributes(OBJECT_TO_OBJECT_HEADER(KeyObject)->ObjectCreateInfo);
OBJECT_TO_OBJECT_HEADER(KeyObject)->ObjectCreateInfo = NULL;
if (!NT_SUCCESS(Status)) goto Cleanup;
/* Add the keep-alive reference */
ObReferenceObject(KeyObject);
/* Unlock registry */
CmpUnlockRegistry();
/* Force a lazy flush */
CmpLazyFlush();
SuccessReturn:
/* Return data to user */
*KeyHandle = hKey;
if (Disposition) *Disposition = LocalDisposition;
Cleanup:
/* Cleanup */
ObpReleaseCapturedAttributes(&ObjectCreateInfo);
if (ObjectName.Buffer) ObpFreeObjectNameBuffer(&ObjectName);
RtlFreeUnicodeString(&ReturnedPath);
if (Parent) ObDereferenceObject(Parent);
return Status;
}
/* EOF */

View file

@ -231,11 +231,14 @@ typedef struct _CM_KEY_CONTROL_BLOCK
{
USHORT RefCount;
USHORT Flags;
ULONG ExtFlags:8;
ULONG PrivateAlloc:1;
ULONG Delete:1;
ULONG DelayedCloseIndex:12;
ULONG TotalLevels:10;
struct
{
ULONG ExtFlags:8;
ULONG PrivateAlloc:1;
ULONG Delete:1;
ULONG DelayedCloseIndex:12;
ULONG TotalLevels:10;
};
union
{
CM_KEY_HASH KeyHash;
@ -251,9 +254,12 @@ typedef struct _CM_KEY_CONTROL_BLOCK
PCM_NAME_CONTROL_BLOCK NameBlock;
PCM_KEY_SECURITY_CACHE CachedSecurity;
CACHED_CHILD_LIST ValueCache;
PCM_INDEX_HINT_BLOCK IndexHint;
ULONG HashKey;
ULONG SubKeyCount;
union
{
PCM_INDEX_HINT_BLOCK IndexHint;
ULONG HashKey;
ULONG SubKeyCount;
};
union
{
LIST_ENTRY KeyBodyListHead;

View file

@ -107,6 +107,8 @@ CmpDelayDerefKCBWorker(IN PVOID Context)
ASSERT(CmpDelayDerefKCBWorkItemActive);
/* FIXME: TODO */
DPRINT1("CmpDelayDerefKCBWorker has work to do!\n");
return;
ASSERT(FALSE);
}
@ -307,3 +309,4 @@ CmpRemoveFromDelayedClose(IN PCM_KEY_CONTROL_BLOCK Kcb)
}

View file

@ -312,9 +312,10 @@ NTAPI
CmpDereferenceNameControlBlockWithLock(IN PCM_NAME_CONTROL_BLOCK Ncb)
{
PCM_NAME_HASH Current, *Next;
ULONG ConvKey = Ncb->ConvKey;
/* Lock the NCB */
CmpAcquireNcbLockExclusive(Ncb);
CmpAcquireNcbLockExclusiveByKey(ConvKey);
/* Decrease the reference count */
if (!(--Ncb->RefCount))
@ -342,7 +343,7 @@ CmpDereferenceNameControlBlockWithLock(IN PCM_NAME_CONTROL_BLOCK Ncb)
}
/* Release the lock */
CmpReleaseNcbLock(Ncb);
CmpReleaseNcbLockByKey(ConvKey);
}
BOOLEAN
@ -363,13 +364,13 @@ CmpReferenceKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
/* Increase the reference count while we release the lock */
InterlockedIncrement((PLONG)&Kcb->RefCount);
/* Go from shared to exclusive */
CmpConvertKcbSharedToExclusive(Kcb);
/* Decrement the reference count; the lock is now held again */
InterlockedDecrement((PLONG)&Kcb->RefCount);
/* Check if we still control the index */
if (Kcb->DelayedCloseIndex == 1)
{
@ -387,7 +388,7 @@ CmpReferenceKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
}
/* Increase the reference count */
if (InterlockedIncrement((PLONG)&Kcb->RefCount) == 0)
if ((InterlockedIncrement((PLONG)&Kcb->RefCount) & 0xFFFF) == 0)
{
/* We've overflown to 64K references, bail out */
InterlockedDecrement((PLONG)&Kcb->RefCount);
@ -511,9 +512,9 @@ CmpDereferenceKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
/* Get the ref count and update it */
OldRefCount = *(PLONG)&Kcb->RefCount;
NewRefCount = OldRefCount - 1;
/* Check if we still have refenreces */
if( (NewRefCount & 0xffff) > 0)
/* Check if we still have references */
if( (NewRefCount & 0xFFFF) > 0)
{
/* Do the dereference */
if (InterlockedCompareExchange((PLONG)&Kcb->RefCount,
@ -544,7 +545,7 @@ CmpDereferenceKeyControlBlockWithLock(IN PCM_KEY_CONTROL_BLOCK Kcb,
(CmpTestRegistryLockExclusive() == TRUE));
/* Check if this is the last reference */
if (InterlockedDecrement((PLONG)&Kcb->RefCount) == 0)
if ((InterlockedDecrement((PLONG)&Kcb->RefCount) & 0xFFFF) == 0)
{
/* Check if we should do a direct delete */
if (((CmpHoldLazyFlush) &&
@ -783,7 +784,7 @@ CmpCreateKeyControlBlock(IN PHHIVE Hive,
}
}
}
/* Sanity check */
ASSERT((!Kcb) || (Kcb->Delete == FALSE));
@ -821,3 +822,4 @@ EnlistKeyBodyWithKCB(IN PCM_KEY_BODY KeyBody,
/* FIXME: Implement once we don't link parents to children anymore */
}

View file

@ -782,7 +782,7 @@ CmpCreateLinkNode(IN PHHIVE Hive,
/* Release it */
HvReleaseCell(Context->ChildHive.KeyHive, ChildCell);
/* Set the parent adn flags */
/* Set the parent and flags */
KeyNode->Parent = LinkCell;
KeyNode->Flags |= KEY_HIVE_ENTRY | KEY_NO_DELETE;
@ -977,7 +977,6 @@ CmpParseKey2(IN PVOID ParseObject,
PULONG LockedKcbs = NULL;
BOOLEAN Result, Last;
PAGED_CODE();
DPRINT1("New style parse routine called: %wZ %wZ!\n", CompleteName, RemainingName);
/* Loop path separators at the end */
while ((RemainingName->Length) &&
@ -1003,7 +1002,6 @@ CmpParseKey2(IN PVOID ParseObject,
/* Grab the KCB */
Kcb = ((PCM_KEY_BODY)ParseObject)->KeyControlBlock;
DPRINT1("KCB Parse: %p\n", Kcb);
/* Lookup in the cache */
Status = CmpBuildHashStackAndLookupCache(ParseObject,
@ -1019,9 +1017,6 @@ CmpParseKey2(IN PVOID ParseObject,
/* This is now the parent */
ParentKcb = Kcb;
DPRINT1("ParentKcb Parse: %p\n", ParentKcb);
DPRINT1("Hive Parse: %p\n", Hive);
DPRINT1("Cell Parse: %p\n", Cell);
/* Check if everything was found cached */
if (!TotalRemainingSubkeys) ASSERTMSG("Caching not implemented", FALSE);
@ -1032,9 +1027,6 @@ CmpParseKey2(IN PVOID ParseObject,
/* Check if this is a symlink */
if (Kcb->Flags & KEY_SYM_LINK)
{
DPRINT1("Parsing sym link: %lx %lx %lx\n", Kcb->Flags, Status,
CompleteName);
/* Get the next name */
Result = CmpGetNextName(&Current, &NextName, &Last);
Current.Buffer = NextName.Buffer;
@ -1071,10 +1063,6 @@ CmpParseKey2(IN PVOID ParseObject,
/* Couldn't find symlink */
Status = STATUS_OBJECT_NAME_NOT_FOUND;
}
/* Not implemented */
DPRINT1("Parsing sym link: %lx %wZ %wZ\n", Status,
CompleteName, &Current);
/* We're done */
goto Quickie;
@ -1083,7 +1071,6 @@ CmpParseKey2(IN PVOID ParseObject,
/* Get the key node */
Node = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
if (!Node) return STATUS_INSUFFICIENT_RESOURCES;
DPRINT1("Node Parse: %p\n", Node);
/* Start parsing */
Status = STATUS_NOT_IMPLEMENTED;
@ -1091,7 +1078,6 @@ CmpParseKey2(IN PVOID ParseObject,
{
/* Get the next component */
Result = CmpGetNextName(&Current, &NextName, &Last);
DPRINT1("Result Parse: %p\n", Result);
if ((Result) && (NextName.Length))
{
/* See if this is a sym link */
@ -1099,13 +1085,11 @@ CmpParseKey2(IN PVOID ParseObject,
{
/* Find the subkey */
NextCell = CmpFindSubKeyByName(Hive, Node, &NextName);
DPRINT1("NextCell Parse: %lx %wZ\n", NextCell, &NextName);
if (NextCell != HCELL_NIL)
{
/* Get the new node */
Cell = NextCell;
Node = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
DPRINT1("Node Parse: %p\n", Node);
if (!Node) ASSERT(FALSE);
/* Check if this was the last key */
@ -1115,13 +1099,11 @@ CmpParseKey2(IN PVOID ParseObject,
if (Node->Flags & KEY_HIVE_EXIT)
{
/* Handle it */
DPRINT1("Exit node\n");
CmpHandleExitNode(&Hive,
&Cell,
&Node,
&HiveToRelease,
&CellToRelease);
DPRINT1("Node Parse: %p\n", Node);
if (!Node) ASSERT(FALSE);
}
@ -1139,9 +1121,6 @@ CmpParseKey2(IN PVOID ParseObject,
Object);
if (Status == STATUS_REPARSE)
{
DPRINT1("Parsing sym link: %lx %lx\n", Status,
CompleteName);
/* Parse the symlink */
if (!CmpGetSymbolicLink(Hive,
CompleteName,
@ -1151,15 +1130,9 @@ CmpParseKey2(IN PVOID ParseObject,
/* Symlink parse failed */
Status = STATUS_OBJECT_NAME_NOT_FOUND;
}
/* Not implemented */
DPRINT1("Parsing sym link: %lx %wZ\n", Status,
CompleteName);
while (TRUE);
}
/* We are done */
DPRINT1("Open of last key\n");
break;
}
@ -1167,13 +1140,11 @@ CmpParseKey2(IN PVOID ParseObject,
if (Node->Flags & KEY_HIVE_EXIT)
{
/* Handle it */
DPRINT1("Exit node: %lx\n", Node->Flags);
CmpHandleExitNode(&Hive,
&Cell,
&Node,
&HiveToRelease,
&CellToRelease);
DPRINT1("Node Parse: %p\n", Node);
if (!Node) ASSERT(FALSE);
}
@ -1185,10 +1156,9 @@ CmpParseKey2(IN PVOID ParseObject,
0,
&NextName);
if (!Kcb) ASSERT(FALSE);
DPRINT1("Kcb Parse: %p\n", Kcb);
/* Dereference the parent and set the new one */
CmpDereferenceKeyControlBlock(ParentKcb);
//CmpDereferenceKeyControlBlock(ParentKcb);
ParentKcb = Kcb;
}
else
@ -1211,7 +1181,6 @@ CmpParseKey2(IN PVOID ParseObject,
ParseContext,
ParentKcb,
Object);
DPRINT1("Link created: %lx\n", Status);
}
else
{
@ -1242,9 +1211,6 @@ CmpParseKey2(IN PVOID ParseObject,
}
else
{
DPRINT1("Parsing sym link: %lx %lx\n", Status,
CompleteName);
/* Save the next name */
Current.Buffer = NextName.Buffer;
@ -1280,20 +1246,47 @@ CmpParseKey2(IN PVOID ParseObject,
/* Couldn't find symlink */
Status = STATUS_OBJECT_NAME_NOT_FOUND;
}
/* Not implemented */
DPRINT1("Parsing sym link: %lx %wZ %wZ\n", Status,
CompleteName, &Current);
/* We're done */
break;
}
}
else if ((Result) && (Last))
{
/* Opening root: unexpected */
DPRINT1("Unexpected: Opening root\n");
while (TRUE);
/* Opening the root. Is this an exit node? */
if (Node->Flags & KEY_HIVE_EXIT)
{
/* Handle it */
CmpHandleExitNode(&Hive,
&Cell,
&Node,
&HiveToRelease,
&CellToRelease);
if (!Node) ASSERT(FALSE);
}
/* FIXME: This hack seems required? */
RtlInitUnicodeString(&NextName, L"\\REGISTRY");
/* Do the open */
Status = CmpDoOpen(Hive,
Cell,
Node,
AccessState,
AccessMode,
Attributes,
ParseContext,
0,
&Kcb,
&NextName,
Object);
if (Status == STATUS_REPARSE)
{
/* Nothing to do */
}
/* We're done */
break;
}
else
{
@ -1305,7 +1298,7 @@ CmpParseKey2(IN PVOID ParseObject,
/* Dereference the parent if it exists */
Quickie:
if (ParentKcb) CmpDereferenceKeyControlBlock(ParentKcb);
//if (ParentKcb) CmpDereferenceKeyControlBlock(ParentKcb);
/* Unlock the registry */
CmpUnlockRegistry();

View file

@ -18,6 +18,25 @@ BOOLEAN CmFirstTime = TRUE;
/* FUNCTIONS *****************************************************************/
NTSTATUS
NTAPI
NtOpenKey(OUT PHANDLE KeyHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes)
{
CM_PARSE_CONTEXT ParseContext = {0};
PAGED_CODE();
/* Just let the object manager handle this */
return ObOpenObjectByName(ObjectAttributes,
CmpKeyObjectType,
ExGetPreviousMode(),
NULL,
DesiredAccess,
&ParseContext,
KeyHandle);
}
NTSTATUS
NTAPI
NtDeleteKey(IN HANDLE KeyHandle)
@ -470,28 +489,12 @@ NtFlushKey(IN HANDLE KeyHandle)
return Status;
}
NTSTATUS
NTAPI
NtCompactKeys(IN ULONG Count,
IN PHANDLE KeyArray)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
NTAPI
NtCompressKey(IN HANDLE Key)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
NTAPI
NtLoadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
IN POBJECT_ATTRIBUTES FileObjectAttributes)
{
/* Call the newer API */
return NtLoadKey2(KeyObjectAttributes, FileObjectAttributes, 0);
}
@ -501,6 +504,7 @@ NtLoadKey2(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
IN POBJECT_ATTRIBUTES FileObjectAttributes,
IN ULONG Flags)
{
/* Call the newer API */
return NtLoadKeyEx(KeyObjectAttributes, FileObjectAttributes, Flags, NULL);
}
@ -555,6 +559,34 @@ NtLoadKeyEx(IN POBJECT_ATTRIBUTES TargetKey,
return Status;
}
NTSTATUS
NTAPI
NtNotifyChangeKey(IN HANDLE KeyHandle,
IN HANDLE Event,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG CompletionFilter,
IN BOOLEAN WatchTree,
OUT PVOID Buffer,
IN ULONG Length,
IN BOOLEAN Asynchronous)
{
/* Call the newer API */
return NtNotifyChangeMultipleKeys(KeyHandle,
0,
NULL,
Event,
ApcRoutine,
ApcContext,
IoStatusBlock,
CompletionFilter,
WatchTree,
Buffer,
Length,
Asynchronous);
}
NTSTATUS
NTAPI
NtInitializeRegistry(IN USHORT Flag)
@ -617,6 +649,23 @@ NtInitializeRegistry(IN USHORT Flag)
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
NtCompactKeys(IN ULONG Count,
IN PHANDLE KeyArray)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
NTAPI
NtCompressKey(IN HANDLE Key)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
NTAPI
NtLockProductActivationKeys(IN PULONG pPrivateVer,
@ -653,33 +702,6 @@ NtNotifyChangeMultipleKeys(IN HANDLE MasterKeyHandle,
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
NTAPI
NtNotifyChangeKey(IN HANDLE KeyHandle,
IN HANDLE Event,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG CompletionFilter,
IN BOOLEAN WatchTree,
OUT PVOID Buffer,
IN ULONG Length,
IN BOOLEAN Asynchronous)
{
return NtNotifyChangeMultipleKeys(KeyHandle,
0,
NULL,
Event,
ApcRoutine,
ApcContext,
IoStatusBlock,
CompletionFilter,
WatchTree,
Buffer,
Length,
Asynchronous);
}
NTSTATUS
NTAPI
NtQueryMultipleValueKey(IN HANDLE KeyHandle,

View file

@ -139,7 +139,6 @@
<file>ntapi.c</file>
</directory>
<directory name="cm">
<file>ntfunc.c</file>
<file>regobj.c</file>
</directory>
<directory name="dbgk">