Author: cfinck
Date: Wed Aug 15 20:38:16 2007
New Revision: 28361
URL:
http://svn.reactos.org/svn/reactos?rev=28361&view=rev
Log:
Revert Fireball's changes in r28292.
This makes Firefox 1.5 "working" again, but now we have the hivesys.inf bug
again, so the Norwegian keyboard layout has to be commented out in hivesys.inf.
Modified:
branches/ros-branch-0_3_3-new/reactos/boot/bootdata/hivesys.inf
branches/ros-branch-0_3_3-new/reactos/ntoskrnl/cm/cm.h
branches/ros-branch-0_3_3-new/reactos/ntoskrnl/cm/ntfunc.c
branches/ros-branch-0_3_3-new/reactos/ntoskrnl/cm/registry.c
branches/ros-branch-0_3_3-new/reactos/ntoskrnl/config/cmindex.c
branches/ros-branch-0_3_3-new/reactos/ntoskrnl/config/cmparse.c
Modified: branches/ros-branch-0_3_3-new/reactos/boot/bootdata/hivesys.inf
URL:
http://svn.reactos.org/svn/reactos/branches/ros-branch-0_3_3-new/reactos/bo…
==============================================================================
--- branches/ros-branch-0_3_3-new/reactos/boot/bootdata/hivesys.inf (original)
+++ branches/ros-branch-0_3_3-new/reactos/boot/bootdata/hivesys.inf Wed Aug 15 20:38:16
2007
@@ -88,8 +88,8 @@
HKLM,"SYSTEM\CurrentControlSet\Control\KeyboardLayouts\00000422","Layout
Text",0x00000000,"Ukrainian"
HKLM,"SYSTEM\CurrentControlSet\Control\KeyboardLayouts\00000455","Layout
File",0x00000000,"kbdbur.dll"
HKLM,"SYSTEM\CurrentControlSet\Control\KeyboardLayouts\00000455","Layout
Text",0x00000000,"Burmese"
-HKLM,"SYSTEM\CurrentControlSet\Control\KeyboardLayouts\00000414","Layout
File",0x00000000,"kbdno.dll"
-HKLM,"SYSTEM\CurrentControlSet\Control\KeyboardLayouts\00000414","Layout
Text",0x00000000,"Norwegian"
+;HKLM,"SYSTEM\CurrentControlSet\Control\KeyboardLayouts\00000414","Layout
File",0x00000000,"kbdno.dll"
+;HKLM,"SYSTEM\CurrentControlSet\Control\KeyboardLayouts\00000414","Layout
Text",0x00000000,"Norwegian"
; Network
HKLM,"SYSTEM\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}",,0x00000000,"Network
Adapters"
Modified: branches/ros-branch-0_3_3-new/reactos/ntoskrnl/cm/cm.h
URL:
http://svn.reactos.org/svn/reactos/branches/ros-branch-0_3_3-new/reactos/nt…
==============================================================================
--- branches/ros-branch-0_3_3-new/reactos/ntoskrnl/cm/cm.h (original)
+++ branches/ros-branch-0_3_3-new/reactos/ntoskrnl/cm/cm.h Wed Aug 15 20:38:16 2007
@@ -294,21 +294,6 @@
NTSTATUS
CmiInitHives(BOOLEAN SetupBoot);
-NTSTATUS
-NTAPI
-CmpDoCreate(
- IN PHHIVE Hive,
- IN HCELL_INDEX Cell,
- IN PACCESS_STATE AccessState,
- IN PUNICODE_STRING Name,
- IN KPROCESSOR_MODE AccessMode,
- IN PUNICODE_STRING Class,
- IN ULONG CreateOptions,
- IN PKEY_OBJECT Parent,
- IN PVOID OriginatingHive OPTIONAL,
- OUT PVOID *Object
-);
-
HCELL_INDEX
NTAPI
CmpFindValueByName(
Modified: branches/ros-branch-0_3_3-new/reactos/ntoskrnl/cm/ntfunc.c
URL:
http://svn.reactos.org/svn/reactos/branches/ros-branch-0_3_3-new/reactos/nt…
==============================================================================
--- branches/ros-branch-0_3_3-new/reactos/ntoskrnl/cm/ntfunc.c (original)
+++ branches/ros-branch-0_3_3-new/reactos/ntoskrnl/cm/ntfunc.c Wed Aug 15 20:38:16 2007
@@ -138,6 +138,7 @@
OUT PULONG Disposition)
{
UNICODE_STRING RemainingPath = {0};
+ BOOLEAN FreeRemainingPath = TRUE;
ULONG LocalDisposition;
PKEY_OBJECT KeyObject;
NTSTATUS Status = STATUS_SUCCESS;
@@ -302,27 +303,53 @@
DPRINT("RemainingPath %S ParentObject 0x%p\n", RemainingPath.Buffer,
Object);
+ Status = ObCreateObject(PreviousMode,
+ CmpKeyObjectType,
+ NULL,
+ PreviousMode,
+ NULL,
+ sizeof(KEY_OBJECT),
+ 0,
+ 0,
+ (PVOID*)&KeyObject);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("ObCreateObject() failed!\n");
+ PostCreateKeyInfo.Object = NULL;
+ PostCreateKeyInfo.Status = Status;
+ CmiCallRegisteredCallbacks(RegNtPostCreateKey, &PostCreateKeyInfo);
+
+ goto Cleanup;
+ }
+
+ KeyObject->ParentKey = Object;
+ KeyObject->RegistryHive = KeyObject->ParentKey->RegistryHive;
+ KeyObject->Flags = 0;
+ KeyObject->SubKeyCounts = 0;
+ KeyObject->SizeOfSubKeys = 0;
+ KeyObject->SubKeys = NULL;
+
/* Acquire hive lock */
KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
- /* Create the key */
- Status = CmpDoCreate(&((PKEY_OBJECT)Object)->RegistryHive->Hive,
- ((PKEY_OBJECT)Object)->KeyCellOffset,
- NULL,
- &RemainingPath,
- KernelMode,
- Class,
- CreateOptions,
- (PKEY_OBJECT)Object,
- NULL,
- (PVOID*)&KeyObject);
+ InsertTailList(&CmiKeyObjectListHead, &KeyObject->ListEntry);
+
+ /* add key to subkeys of parent if needed */
+ Status = CmiAddSubKey(KeyObject->RegistryHive,
+ KeyObject->ParentKey,
+ KeyObject,
+ &RemainingPath,
+ TitleIndex,
+ &CapturedClass,
+ CreateOptions);
if (!NT_SUCCESS(Status))
{
DPRINT1("CmiAddSubKey() failed (Status %lx)\n", Status);
/* Release hive lock */
ExReleaseResourceLite(&CmpRegistryLock);
KeLeaveCriticalRegion();
+ ObDereferenceObject(KeyObject);
PostCreateKeyInfo.Object = NULL;
PostCreateKeyInfo.Status = STATUS_UNSUCCESSFUL;
@@ -332,8 +359,15 @@
goto Cleanup;
}
- InsertTailList(&CmiKeyObjectListHead, &KeyObject->ListEntry);
- RtlCreateUnicodeString(&KeyObject->Name, Start);
+ if (Start == RemainingPath.Buffer)
+ {
+ KeyObject->Name = RemainingPath;
+ FreeRemainingPath = FALSE;
+ }
+ else
+ {
+ RtlCreateUnicodeString(&KeyObject->Name, Start);
+ }
KeyObject->KeyCell->Parent = KeyObject->ParentKey->KeyCellOffset;
KeyObject->KeyCell->SecurityKeyOffset =
KeyObject->ParentKey->KeyCell->SecurityKeyOffset;
@@ -403,7 +437,7 @@
PreviousMode);
}
if (ObjectName.Buffer) ObpFreeObjectNameBuffer(&ObjectName);
- RtlFreeUnicodeString(&RemainingPath);
+ if (FreeRemainingPath) RtlFreeUnicodeString(&RemainingPath);
if (Object != NULL) ObDereferenceObject(Object);
return Status;
Modified: branches/ros-branch-0_3_3-new/reactos/ntoskrnl/cm/registry.c
URL:
http://svn.reactos.org/svn/reactos/branches/ros-branch-0_3_3-new/reactos/nt…
==============================================================================
--- branches/ros-branch-0_3_3-new/reactos/ntoskrnl/cm/registry.c (original)
+++ branches/ros-branch-0_3_3-new/reactos/ntoskrnl/cm/registry.c Wed Aug 15 20:38:16 2007
@@ -263,19 +263,39 @@
DPRINT("RemainingPath %wZ ParentKey %p\n",
&RemainingPath, ParentKey);
+ Status = ObCreateObject(KernelMode,
+ CmpKeyObjectType,
+ NULL,
+ KernelMode,
+ NULL,
+ sizeof(KEY_OBJECT),
+ 0,
+ 0,
+ (PVOID*)&NewKey);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1 ("ObCreateObject() failed (Status %lx)\n", Status);
+ ObDereferenceObject (ParentKey);
+ RtlFreeUnicodeString(&RemainingPath);
+ return Status;
+ }
+
+ NewKey->Flags = 0;
+ NewKey->SubKeyCounts = 0;
+ NewKey->SubKeys = NULL;
+ NewKey->SizeOfSubKeys = 0;
+ InsertTailList(&CmiKeyObjectListHead, &NewKey->ListEntry);
+
DPRINT ("SubName %S\n", SubName);
- /* Create the key */
- Status = CmpDoCreate(&ParentKey->RegistryHive->Hive,
- ParentKey->KeyCellOffset,
- NULL,
- &RemainingPath,
- KernelMode,
- NULL,
- REG_OPTION_VOLATILE,
- ParentKey,
- NULL,
- (PVOID*)&NewKey);
+ Status = CmiAddSubKey(ParentKey->RegistryHive,
+ ParentKey,
+ NewKey,
+ &RemainingPath,
+ 0,
+ NULL,
+ REG_OPTION_VOLATILE);
if (!NT_SUCCESS(Status))
{
DPRINT1("CmiAddSubKey() failed (Status %lx)\n", Status);
Modified: branches/ros-branch-0_3_3-new/reactos/ntoskrnl/config/cmindex.c
URL:
http://svn.reactos.org/svn/reactos/branches/ros-branch-0_3_3-new/reactos/nt…
==============================================================================
--- branches/ros-branch-0_3_3-new/reactos/ntoskrnl/config/cmindex.c (original)
+++ branches/ros-branch-0_3_3-new/reactos/ntoskrnl/config/cmindex.c Wed Aug 15 20:38:16
2007
@@ -14,16 +14,6 @@
#include "debug.h"
/* GLOBALS *******************************************************************/
-
-ULONG CmpMaxFastIndexPerHblock =
- (HBLOCK_SIZE - (sizeof(HBIN) +
- sizeof(HCELL) +
- FIELD_OFFSET(CM_KEY_FAST_INDEX, List))) / sizeof(CM_INDEX);
-
-ULONG CmpMaxIndexPerHblock =
- (HBLOCK_SIZE - (sizeof(HBIN) +
- sizeof(HCELL) +
- FIELD_OFFSET(CM_KEY_INDEX, List))) / sizeof(HCELL_INDEX) - 1;
/* FUNCTIONS *****************************************************************/
@@ -932,396 +922,6 @@
/* Free the search name and return failure */
if (IsCompressed) ExFreePool(SearchName.Buffer);
return FALSE;
-}
-
-HCELL_INDEX
-NTAPI
-CmpAddToLeaf(IN PHHIVE Hive,
- IN HCELL_INDEX LeafCell,
- IN HCELL_INDEX NewKey,
- IN PUNICODE_STRING Name)
-{
- PCM_KEY_INDEX Leaf;
- PCM_KEY_FAST_INDEX FastLeaf;
- ULONG Size, OldSize, EntrySize, i, j;
- HCELL_INDEX NewCell, Child;
- LONG Result;
-
- /* Mark the leaf dirty */
- HvMarkCellDirty(Hive, LeafCell);
-
- /* Get the leaf cell */
- Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, LeafCell);
- if (!Leaf)
- {
- /* Shouldn't happen */
- ASSERT(FALSE);
- return HCELL_NIL;
- }
-
- /* Release it */
- HvReleaseCell(Hive, LeafCell);
-
- /* Check if this is an index leaf */
- if (Leaf->Signature == CM_KEY_INDEX_LEAF)
- {
- /* This is an old-style leaf */
- FastLeaf = NULL;
- EntrySize = sizeof(HCELL_INDEX);
- }
- else
- {
- /* Sanity check */
- ASSERT((Leaf->Signature == CM_KEY_FAST_LEAF) ||
- (Leaf->Signature == CM_KEY_HASH_LEAF));
-
- /* This is a new-style optimized fast (or hash) leaf */
- FastLeaf = (PCM_KEY_FAST_INDEX)Leaf;
- EntrySize = sizeof(CM_INDEX);
- }
-
- /* Get the current size of the leaf */
- OldSize = HvGetCellSize(Hive, Leaf);
-
- /* Calculate the size of the free entries */
- Size = OldSize;
- Size -= EntrySize * Leaf->Count + FIELD_OFFSET(CM_KEY_INDEX, List);
-
- /* Assume we'll re-use the same leaf */
- NewCell = LeafCell;
-
- /* Check if we're out of space */
- if ((Size / EntrySize) < 1)
- {
- /* Grow the leaf by 1.5x, making sure we can at least fit this entry */
- Size = OldSize + OldSize / 2;
- if (Size < (OldSize + EntrySize)) Size = OldSize + EntrySize;
-
- /* Re-allocate the leaf */
- NewCell = HvReallocateCell(Hive, LeafCell, Size);
- if (NewCell == HCELL_NIL) return HCELL_NIL;
-
- /* Get the leaf cell */
- Leaf = (PCM_KEY_INDEX)HvGetCell(Hive, NewCell);
- if (!Leaf)
- {
- /* This shouldn't happen */
- ASSERT(FALSE);
- return HCELL_NIL;
- }
-
- /* Release the cell */
- HvReleaseCell(Hive, NewCell);
-
- /* Update the fast leaf pointer if we had one */
- if (FastLeaf) FastLeaf = (PCM_KEY_FAST_INDEX)Leaf;
- }
-
- /* Find the insertion point for our entry */
- i = CmpFindSubKeyInLeaf(Hive, Leaf, Name, &Child);
- if (i & 0x80000000) return HCELL_NIL;
- ASSERT(Child == HCELL_NIL);
-
- /* Check if we're not last */
- if (i != Leaf->Count)
- {
- /* Find out where we should go */
- Result = CmpCompareInIndex(Hive,
- Name,
- i,
- Leaf,
- &Child);
- if (Result == 2) return HCELL_NIL;
- ASSERT(Result != 0);
-
- /* Check if we come after */
- if (Result > 0)
- {
- /* We do, insert us after the key */
- ASSERT(Result == 1);
- i++;
- }
-
- /* Check if we're still not last */
- if (i != Leaf->Count)
- {
- /* Check if we had a fast leaf or not */
- if (FastLeaf)
- {
- /* Copy the fast indexes */
- RtlMoveMemory(&FastLeaf->List[i + 1],
- &FastLeaf->List[i],
- (FastLeaf->Count - i) * sizeof(CM_INDEX));
- }
- else
- {
- /* Copy the indexes themselves */
- RtlMoveMemory(&Leaf->List[i + 1],
- &Leaf->List[i],
- (Leaf->Count - i) * sizeof(HCELL_INDEX));
- }
- }
- }
-
- /* Check if this is a new-style leaf */
- if (FastLeaf)
- {
- /* Set our cell */
- FastLeaf->List[i].Cell = NewKey;
-
- /* Check if this is a hash leaf */
- if( FastLeaf->Signature == CM_KEY_HASH_LEAF )
- {
- /* Set our hash key */
- FastLeaf->List[i].HashKey = CmpComputeHashKey(0, Name, FALSE);
- }
- else
- {
- /* First, clear the name */
- FastLeaf->List[i].NameHint[0] = 0;
- FastLeaf->List[i].NameHint[1] = 0;
- FastLeaf->List[i].NameHint[2] = 0;
- FastLeaf->List[i].NameHint[3] = 0;
-
- /* Now, figure out if we can fit */
- if (Name->Length / sizeof(WCHAR) < 4)
- {
- /* We can fit, use our length */
- j = Name->Length / sizeof(WCHAR);
- }
- else
- {
- /* We can't, use a maximum of 4 */
- j = 4;
- }
-
- /* Now fill out the name hint */
- do
- {
- /* Look for invalid characters and break out if we found one */
- if ((USHORT)Name->Buffer[j - 1] > (UCHAR)-1) break;
-
- /* Otherwise, copy the a character */
- FastLeaf->List[i].NameHint[j - 1] = (UCHAR)Name->Buffer[j - 1];
- } while (--j > 0);
- }
- }
- else
- {
- /* This is an old-style leaf, just set our index directly */
- Leaf->List[i] = NewKey;
- }
-
- /* Update the leaf count and return the new cell */
- Leaf->Count += 1;
- return NewCell;
-}
-
-BOOLEAN
-NTAPI
-CmpAddSubKey(IN PHHIVE Hive,
- IN HCELL_INDEX Parent,
- IN HCELL_INDEX Child)
-{
- PCM_KEY_NODE KeyNode;
- PCM_KEY_INDEX Index;
- UNICODE_STRING Name;
- HCELL_INDEX IndexCell = HCELL_NIL, CellToRelease = HCELL_NIL, LeafCell;
- PHCELL_INDEX RootPointer = NULL;
- ULONG Type;
- BOOLEAN IsCompressed;
- PAGED_CODE();
-
- /* Get the key node */
- KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, Child);
- if (!KeyNode)
- {
- /* Shouldn't happen */
- ASSERT(FALSE);
- return FALSE;
- }
-
- /* Check if the name is compressed */
- if (KeyNode->Flags & KEY_COMP_NAME)
- {
- /* Remember for later */
- IsCompressed = TRUE;
-
- /* Create the compressed name and allocate it */
- Name.Length = CmpCompressedNameSize(KeyNode->Name, KeyNode->NameLength);
- Name.MaximumLength = Name.Length;
- Name.Buffer = Hive->Allocate(Name.Length, TRUE);
- if (!Name.Buffer)
- {
- /* Release the cell and fail */
- HvReleaseCell(Hive, Child);
- ASSERT(FALSE);
- return FALSE;
- }
-
- /* Copy the compressed name */
- CmpCopyCompressedName(Name.Buffer,
- Name.MaximumLength,
- KeyNode->Name,
- KeyNode->NameLength);
- }
- else
- {
- /* Remember for later */
- IsCompressed = FALSE;
-
- /* Build the unicode string */
- Name.Length = KeyNode->NameLength;
- Name.MaximumLength = KeyNode->NameLength;
- Name.Buffer = &KeyNode->Name[0];
- }
-
- /* Release the cell */
- HvReleaseCell(Hive, Child);
-
- /* Get the parent node */
- KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, Parent);
- if (!KeyNode)
- {
- /* Not handled */
- ASSERT(FALSE);
- }
-
- /* Find out the type of the cell, and check if this is the first subkey */
- Type = HvGetCellType(Child);
- if (!KeyNode->SubKeyCounts[Type])
- {
- /* Allocate a fast leaf */
- IndexCell = HvAllocateCell(Hive, sizeof(CM_KEY_FAST_INDEX), Type);
- if (IndexCell == HCELL_NIL)
- {
- /* Not handled */
- ASSERT(FALSE);
- }
-
- /* Get the leaf cell */
- Index = (PCM_KEY_INDEX)HvGetCell(Hive, IndexCell);
- if (!Index)
- {
- /* Shouldn't happen */
- ASSERT(FALSE);
- }
-
- /* Now check what kind of hive we're dealing with */
- if (Hive->Version >= 5)
- {
- /* XP Hive: Use hash leaf */
- Index->Signature = CM_KEY_HASH_LEAF;
- }
- else if (Hive->Version >= 3)
- {
- /* Windows 2000 and ReactOS: Use fast leaf */
- Index->Signature = CM_KEY_FAST_LEAF;
- }
- else
- {
- /* NT 4: Use index leaf */
- Index->Signature = CM_KEY_INDEX_LEAF;
- }
-
- /* Setup the index list */
- Index->Count = 0;
- KeyNode->SubKeyLists[Type] = IndexCell;
- }
- else
- {
- /* We already have an index, get it */
- Index = (PCM_KEY_INDEX)HvGetCell(Hive, KeyNode->SubKeyLists[Type]);
- if (!Index)
- {
- /* Not handled */
- ASSERT(FALSE);
- }
-
- /* Remember to release the cell later */
- CellToRelease = KeyNode->SubKeyLists[Type];
-
- /* Check if this is a fast leaf that's gotten too full */
- if ((Index->Signature == CM_KEY_FAST_LEAF) &&
- (Index->Count >= CmpMaxFastIndexPerHblock))
- {
- /* Not handled yet */
- DPRINT1("Fast->Slow Leaf Conversion not yet implemented!\n");
- ASSERT(FALSE);
- }
- else if (((Index->Signature == CM_KEY_INDEX_LEAF) ||
- (Index->Signature == CM_KEY_HASH_LEAF)) &&
- (Index->Count >= CmpMaxIndexPerHblock))
- {
- /* This is an old/hashed leaf that's gotten too large, root it */
- IndexCell = HvAllocateCell(Hive,
- sizeof(CM_KEY_INDEX) +
- sizeof(HCELL_INDEX),
- Type);
- if (IndexCell == HCELL_NIL)
- {
- /* Not handled */
- ASSERT(FALSE);
- }
-
- /* Get the index cell */
- Index = (PCM_KEY_INDEX)HvGetCell(Hive, IndexCell);
- if (!Index)
- {
- /* Shouldn't happen */
- ASSERT(FALSE);
- }
-
- /* Mark the index as a root, and set the index cell */
- Index->Signature = CM_KEY_INDEX_ROOT;
- Index->Count = 1;
- Index->List[0] = KeyNode->SubKeyLists[Type];
- KeyNode->SubKeyLists[Type] = IndexCell;
- }
- }
-
- /* Now we can choose the leaf cell */
- LeafCell = KeyNode->SubKeyLists[Type];
-
- /* Check if we turned the index into a root */
- if (Index->Signature == CM_KEY_INDEX_ROOT)
- {
- /* Not handled yet */
- DPRINT1("Leaf->Root Index Conversion not yet implemented!\n");
- ASSERT(FALSE);
- }
-
- /* Add our leaf cell */
- LeafCell = CmpAddToLeaf(Hive, LeafCell, Child, &Name);
- if (LeafCell == HCELL_NIL)
- {
- /* Not handled */
- ASSERT(FALSE);
- }
-
- /* Update the key counts */
- KeyNode->SubKeyCounts[Type]++;
-
- /* Check if caller wants us to return the leaf */
- if (RootPointer)
- {
- /* Return it */
- *RootPointer = LeafCell;
- }
- else
- {
- /* Otherwise, mark it as the list index for the cell */
- KeyNode->SubKeyLists[Type] = LeafCell;
- }
-
- /* If the name was compressed, free our copy */
- if (IsCompressed) Hive->Free(Name.Buffer);
-
- /* Release all our cells */
- if (IndexCell != HCELL_NIL) HvReleaseCell(Hive, IndexCell);
- if (CellToRelease != HCELL_NIL) HvReleaseCell(Hive, CellToRelease);
- HvReleaseCell(Hive, Parent);
- return TRUE;
}
BOOLEAN
Modified: branches/ros-branch-0_3_3-new/reactos/ntoskrnl/config/cmparse.c
URL:
http://svn.reactos.org/svn/reactos/branches/ros-branch-0_3_3-new/reactos/nt…
==============================================================================
--- branches/ros-branch-0_3_3-new/reactos/ntoskrnl/config/cmparse.c (original)
+++ branches/ros-branch-0_3_3-new/reactos/ntoskrnl/config/cmparse.c Wed Aug 15 20:38:16
2007
@@ -73,329 +73,3 @@
*LastName = !RemainingName->Length;
return NameValid;
}
-
-NTSTATUS
-NTAPI
-CmpDoCreateChild(IN PHHIVE Hive,
- IN HCELL_INDEX ParentCell,
- IN PSECURITY_DESCRIPTOR ParentDescriptor OPTIONAL,
- IN PACCESS_STATE AccessState,
- IN PUNICODE_STRING Name,
- IN KPROCESSOR_MODE AccessMode,
- IN PUNICODE_STRING Class,
- IN PKEY_OBJECT Parent,
- IN ULONG CreateOptions,
- OUT PHCELL_INDEX KeyCell,
- OUT PVOID *Object)
-{
- NTSTATUS Status = STATUS_SUCCESS;
- PKEY_OBJECT KeyBody;
- HCELL_INDEX ClassCell = HCELL_NIL;
- PCM_KEY_NODE KeyNode;
- PCELL_DATA CellData;
- ULONG StorageType;
- LARGE_INTEGER SystemTime;
- BOOLEAN Hack = FALSE;
-
- /* ReactOS Hack */
- if (Name->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
- {
- /* Skip initial path separator */
- Name->Buffer++;
- Name->Length -= sizeof(OBJ_NAME_PATH_SEPARATOR);
- Name->MaximumLength -= sizeof(OBJ_NAME_PATH_SEPARATOR);
- Hack = TRUE;
- }
-
- /* Get the storage type */
- StorageType = HvStable;
- if (CreateOptions & REG_OPTION_VOLATILE) StorageType = HvVolatile;
-
- /* Allocate the child */
- *KeyCell = HvAllocateCell(Hive,
- FIELD_OFFSET(CM_KEY_NODE, Name) +
- CmpNameSize(Hive, Name),
- StorageType);
- if (*KeyCell == HCELL_NIL)
- {
- /* Fail */
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto Quickie;
- }
-
- /* Get the key node */
- KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, *KeyCell);
- if (!KeyNode)
- {
- /* Fail, this should never happen */
- ASSERT(FALSE);
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto Quickie;
- }
-
- /* Release the cell */
- HvReleaseCell(Hive, *KeyCell);
-
- /* Check if we have a class name */
- if (Class->Length > 0)
- {
- /* Allocate a class cell */
- ClassCell = HvAllocateCell(Hive, Class->Length, StorageType);
- if (ClassCell == HCELL_NIL)
- {
- /* Fail */
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto Quickie;
- }
- }
-
- /* Allocate the Cm Object */
- Status = ObCreateObject(AccessMode,
- CmpKeyObjectType,
- NULL,
- AccessMode,
- NULL,
- sizeof(KEY_OBJECT),
- 0,
- 0,
- Object);
- if (!NT_SUCCESS(Status)) goto Quickie;
- KeyBody = (PKEY_OBJECT)(*Object);
-
- /* Check if we had a class */
- if (Class->Length > 0)
- {
- /* Get the class cell */
- CellData = HvGetCell(Hive, ClassCell);
- if (!CellData)
- {
- /* Fail, this should never happen */
- ASSERT(FALSE);
- Status = STATUS_INSUFFICIENT_RESOURCES;
- ObDereferenceObject(*Object);
- goto Quickie;
- }
-
- /* Release the cell */
- HvReleaseCell(Hive, ClassCell);
-
- /* Copy the class data */
- RtlCopyMemory(&CellData->u.KeyString[0],
- Class->Buffer,
- Class->Length);
- }
-
- /* Fill out the key node */
- KeyNode->Signature = CM_KEY_NODE_SIGNATURE;
- KeyNode->Flags = CreateOptions;
- KeQuerySystemTime(&SystemTime);
- KeyNode->LastWriteTime = SystemTime;
- KeyNode->Spare = 0;
- KeyNode->Parent = ParentCell;
- KeyNode->SubKeyCounts[HvStable] = 0;
- KeyNode->SubKeyCounts[HvVolatile] = 0;
- KeyNode->SubKeyLists[HvStable] = HCELL_NIL;
- KeyNode->SubKeyLists[HvVolatile] = HCELL_NIL;
- KeyNode->ValueList.Count = 0;
- KeyNode->ValueList.List = HCELL_NIL;
- KeyNode->Security = HCELL_NIL;
- KeyNode->Class = ClassCell;
- KeyNode->ClassLength = Class->Length;
- KeyNode->MaxValueDataLen = 0;
- KeyNode->MaxNameLen = 0;
- KeyNode->MaxValueNameLen = 0;
- KeyNode->MaxClassLen = 0;
- KeyNode->NameLength = CmpCopyName(Hive, KeyNode->Name, Name);
- if (KeyNode->NameLength < Name->Length) KeyNode->Flags |= KEY_COMP_NAME;
-
- /* Now fill out the Cm object */
- KeyBody->KeyCell = KeyNode;
- KeyBody->KeyCellOffset = *KeyCell;
- KeyBody->Flags = 0;
- KeyBody->SubKeyCounts = 0;
- KeyBody->SubKeys = NULL;
- KeyBody->SizeOfSubKeys = 0;
- KeyBody->ParentKey = Parent;
- KeyBody->RegistryHive = KeyBody->ParentKey->RegistryHive;
- InsertTailList(&CmiKeyObjectListHead, &KeyBody->ListEntry);
-
-Quickie:
- /* Check if we got here because of failure */
- if (!NT_SUCCESS(Status))
- {
- /* Free any cells we might've allocated */
- if (Class->Length > 0) HvFreeCell(Hive, ClassCell);
- HvFreeCell(Hive, *KeyCell);
- }
-
- /* Check if we applied ReactOS hack */
- if (Hack)
- {
- /* Restore name */
- Name->Buffer--;
- Name->Length += sizeof(OBJ_NAME_PATH_SEPARATOR);
- Name->MaximumLength += sizeof(OBJ_NAME_PATH_SEPARATOR);
- }
-
- /* Return status */
- return Status;
-}
-
-NTSTATUS
-NTAPI
-CmpDoCreate(IN PHHIVE Hive,
- IN HCELL_INDEX Cell,
- IN PACCESS_STATE AccessState,
- IN PUNICODE_STRING Name,
- IN KPROCESSOR_MODE AccessMode,
- IN PUNICODE_STRING Class OPTIONAL,
- IN ULONG CreateOptions,
- IN PKEY_OBJECT Parent,
- IN PCMHIVE OriginatingHive OPTIONAL,
- OUT PVOID *Object)
-{
- NTSTATUS Status;
- PCELL_DATA CellData;
- HCELL_INDEX KeyCell;
- ULONG ParentType;
- PKEY_OBJECT KeyBody;
- PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
- LARGE_INTEGER TimeStamp;
- PCM_KEY_NODE KeyNode;
- UNICODE_STRING LocalClass = {0};
- if (!Class) Class = &LocalClass;
-
- /* Acquire the flusher lock */
- //ExAcquirePushLockShared((PVOID)&((PCMHIVE)Hive)->FlusherLock);
-
- /* Check if the parent is being deleted */
- #define KO_MARKED_FOR_DELETE 0x00000001
- if (Parent->Flags & KO_MARKED_FOR_DELETE)
- {
- /* It has, quit */
- ASSERT(FALSE);
- Status = STATUS_OBJECT_NAME_NOT_FOUND;
- goto Exit;
- }
-
- /* Get the parent node */
- KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
- if (!KeyNode)
- {
- /* Fail */
- ASSERT(FALSE);
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto Exit;
- }
-
- /* Make sure nobody added us yet */
- if (CmpFindSubKeyByName(Hive, KeyNode, Name) != HCELL_NIL)
- {
- /* Fail */
- ASSERT(FALSE);
- Status = STATUS_REPARSE;
- goto Exit;
- }
-
- /* Sanity check */
- ASSERT(Cell == Parent->KeyCellOffset);
-
- /* Get the parent type */
- ParentType = HvGetCellType(Cell);
- if ((ParentType == HvVolatile) && !(CreateOptions &
REG_OPTION_VOLATILE))
- {
- /* Children of volatile parents must also be volatile */
- ASSERT(FALSE);
- Status = STATUS_CHILD_MUST_BE_VOLATILE;
- goto Exit;
- }
-
- /* Don't allow children under symlinks */
- if (Parent->Flags & KEY_SYM_LINK)
- {
- /* Fail */
- ASSERT(FALSE);
- Status = STATUS_ACCESS_DENIED;
- goto Exit;
- }
-
- /* Make the cell dirty for now */
- HvMarkCellDirty(Hive, Cell);
-
- /* Do the actual create operation */
- Status = CmpDoCreateChild(Hive,
- Cell,
- SecurityDescriptor,
- AccessState,
- Name,
- AccessMode,
- Class,
- Parent,
- CreateOptions,
- &KeyCell,
- Object);
- if (NT_SUCCESS(Status))
- {
- /* Get the key body */
- KeyBody = (PKEY_OBJECT)(*Object);
-
- /* Now add the subkey */
- if (!CmpAddSubKey(Hive, Cell, KeyCell))
- {
- /* Failure! We don't handle this yet! */
- ASSERT(FALSE);
- }
-
- /* Get the key node */
- KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, Cell);
- if (!KeyNode)
- {
- /* Fail, this shouldn't happen */
- ASSERT(FALSE);
- }
-
- /* Sanity checks */
- ASSERT(KeyBody->ParentKey->KeyCellOffset == Cell);
- ASSERT(&KeyBody->ParentKey->RegistryHive->Hive == Hive);
- ASSERT(KeyBody->ParentKey == Parent);
-
- /* Update the timestamp */
- KeQuerySystemTime(&TimeStamp);
- KeyNode->LastWriteTime = TimeStamp;
-
- /* Check if we need to update name maximum */
- if (KeyNode->MaxNameLen < Name->Length)
- {
- /* Do it */
- KeyNode->MaxNameLen = Name->Length;
- }
-
- /* Check if we need toupdate class length maximum */
- if (KeyNode->MaxClassLen < Class->Length)
- {
- /* Update it */
- KeyNode->MaxClassLen = Class->Length;
- }
-
- /* Check if we're creating a symbolic link */
- if (CreateOptions & REG_OPTION_CREATE_LINK)
- {
- /* Get the cell data */
- CellData = HvGetCell(Hive, KeyCell);
- if (!CellData)
- {
- /* This shouldn't happen */
- ASSERT(FALSE);
- }
-
- /* Update the flags */
- CellData->u.KeyNode.Flags |= KEY_SYM_LINK;
- HvReleaseCell(Hive, KeyCell);
- }
- }
-
-Exit:
- /* Release the flusher lock and return status */
- //ExReleasePushLock((PVOID)&((PCMHIVE)Hive)->FlusherLock);
- return Status;
-}