Author: ion Date: Fri May 11 08:59:38 2007 New Revision: 26692
URL: http://svn.reactos.org/svn/reactos?rev=26692&view=rev Log: - Remove unusued, complex hive checking code from regfile.c. - Implement CmpInitializeHive based on Cm Rewrite but keep code compatible with the current EREGISTRY_HIVE structure in the current Cm. - Remove CmiCreateVolatileHive and CmiCreateTemp since they're unused. - Implement CmpCreateRootNode based on CmRewrite and CmCreateRootNode in cmlib, CmpCopyName and CmpNameSize from Cm Rewrite and use them. - Use CmpInitializeHive + CmpCreateRootNode for the master volatile hive.
Modified: trunk/reactos/ntoskrnl/cm/regfile.c trunk/reactos/ntoskrnl/cm/registry.c trunk/reactos/ntoskrnl/config/cm.h trunk/reactos/ntoskrnl/config/cmname.c
Modified: trunk/reactos/ntoskrnl/cm/regfile.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/regfile.c?rev=2... ============================================================================== --- trunk/reactos/ntoskrnl/cm/regfile.c (original) +++ trunk/reactos/ntoskrnl/cm/regfile.c Fri May 11 08:59:38 2007 @@ -15,9 +15,7 @@ #include <internal/debug.h>
#include "cm.h" - -/* uncomment to enable hive checks (incomplete and probably buggy) */ -//#define HIVE_CHECK +#include "..\config\cm.h"
/* LOCAL MACROS *************************************************************/
@@ -164,276 +162,6 @@
return(Status); } - - -#ifdef HIVE_CHECK - -static ULONG -CmiCalcChecksum(PULONG Buffer) -{ - ULONG Sum = 0; - ULONG i; - - for (i = 0; i < 127; i++) - Sum ^= Buffer[i]; - if (Sum == (ULONG)-1) - Sum = (ULONG)-2; - if (Sum == 0) - Sum = 1; - - return(Sum); -} - -static NTSTATUS -CmiCheckAndFixHive(PEREGISTRY_HIVE RegistryHive) -{ - OBJECT_ATTRIBUTES ObjectAttributes; - FILE_STANDARD_INFORMATION fsi; - IO_STATUS_BLOCK IoStatusBlock; - HANDLE HiveHandle = INVALID_HANDLE_VALUE; - HANDLE LogHandle = INVALID_HANDLE_VALUE; - PHBASE_BLOCK HiveHeader = NULL; - PHBASE_BLOCK LogHeader = NULL; - LARGE_INTEGER FileOffset; - ULONG FileSize; - ULONG BufferSize; - ULONG BitmapSize; - RTL_BITMAP BlockBitMap; - NTSTATUS Status; - - DPRINT("CmiCheckAndFixHive() called\n"); - - /* Try to open the hive file */ - InitializeObjectAttributes(&ObjectAttributes, - &RegistryHive->HiveFileName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - Status = ZwCreateFile(&HiveHandle, - FILE_READ_DATA | FILE_READ_ATTRIBUTES, - &ObjectAttributes, - &IoStatusBlock, - NULL, - FILE_ATTRIBUTE_NORMAL, - 0, - FILE_OPEN, - FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, - NULL, - 0); - if (Status == STATUS_OBJECT_NAME_NOT_FOUND) - { - return(STATUS_SUCCESS); - } - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwCreateFile() failed (Status %lx)\n", Status); - return(Status); - } - - /* Try to open the log file */ - InitializeObjectAttributes(&ObjectAttributes, - &RegistryHive->LogFileName, - OBJ_CASE_INSENSITIVE, - NULL, - NULL); - - Status = ZwCreateFile(&LogHandle, - FILE_READ_DATA | FILE_READ_ATTRIBUTES, - &ObjectAttributes, - &IoStatusBlock, - NULL, - FILE_ATTRIBUTE_NORMAL, - 0, - FILE_OPEN, - FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, - NULL, - 0); - if (Status == STATUS_OBJECT_NAME_NOT_FOUND) - { - LogHandle = INVALID_HANDLE_VALUE; - } - else if (!NT_SUCCESS(Status)) - { - DPRINT("ZwCreateFile() failed (Status %lx)\n", Status); - ZwClose(HiveHandle); - return(Status); - } - - /* Allocate hive header */ - HiveHeader = ExAllocatePool(PagedPool, - sizeof(HBASE_BLOCK)); - if (HiveHeader == NULL) - { - DPRINT("ExAllocatePool() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto ByeBye; - } - - /* Read hive base block */ - FileOffset.QuadPart = 0ULL; - Status = ZwReadFile(HiveHandle, - 0, - 0, - 0, - &IoStatusBlock, - HiveHeader, - sizeof(HBASE_BLOCK), - &FileOffset, - 0); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwReadFile() failed (Status %lx)\n", Status); - goto ByeBye; - } - - if (LogHandle == INVALID_HANDLE_VALUE) - { - if (HiveHeader->Checksum != CmiCalcChecksum((PULONG)HiveHeader) || - HiveHeader->Sequence1 != HiveHeader->Sequence2) - { - /* There is no way to fix the hive without log file - BSOD! */ - DPRINT("Hive header inconsistent and no log file available!\n"); - KEBUGCHECK(CONFIG_LIST_FAILED); - } - - Status = STATUS_SUCCESS; - goto ByeBye; - } - else - { - /* Allocate hive header */ - LogHeader = ExAllocatePool(PagedPool, - HV_LOG_HEADER_SIZE); - if (LogHeader == NULL) - { - DPRINT("ExAllocatePool() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto ByeBye; - } - - /* Read log file header */ - FileOffset.QuadPart = 0ULL; - Status = ZwReadFile(LogHandle, - 0, - 0, - 0, - &IoStatusBlock, - LogHeader, - HV_LOG_HEADER_SIZE, - &FileOffset, - 0); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwReadFile() failed (Status %lx)\n", Status); - goto ByeBye; - } - - /* Check log file header integrity */ - if (LogHeader->Checksum != CmiCalcChecksum((PULONG)LogHeader) || - LogHeader->Sequence1 != LogHeader->Sequence2) - { - if (HiveHeader->Checksum != CmiCalcChecksum((PULONG)HiveHeader) || - HiveHeader->Sequence1 != HiveHeader->Sequence2) - { - DPRINT("Hive file and log file are inconsistent!\n"); - KEBUGCHECK(CONFIG_LIST_FAILED); - } - - /* Log file damaged but hive is okay */ - Status = STATUS_SUCCESS; - goto ByeBye; - } - - if (HiveHeader->Sequence1 == HiveHeader->Sequence2 && - HiveHeader->Sequence1 == LogHeader->Sequence1) - { - /* Hive and log file are up-to-date */ - Status = STATUS_SUCCESS; - goto ByeBye; - } - - /* - * Hive needs an update! - */ - - /* Get file size */ - Status = ZwQueryInformationFile(LogHandle, - &IoStatusBlock, - &fsi, - sizeof(fsi), - FileStandardInformation); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwQueryInformationFile() failed (Status %lx)\n", Status); - goto ByeBye; - } - FileSize = fsi.EndOfFile.u.LowPart; - - /* Calculate bitmap and block size */ - BitmapSize = ROUND_UP((FileSize / HV_BLOCK_SIZE) - 1, sizeof(ULONG) * 8) / 8; - BufferSize = HV_LOG_HEADER_SIZE + sizeof(ULONG) + BitmapSize; - BufferSize = ROUND_UP(BufferSize, HV_BLOCK_SIZE); - - /* Reallocate log header block */ - ExFreePool(LogHeader); - LogHeader = ExAllocatePool(PagedPool, - BufferSize); - if (LogHeader == NULL) - { - DPRINT("ExAllocatePool() failed\n"); - Status = STATUS_INSUFFICIENT_RESOURCES; - goto ByeBye; - } - - /* Read log file header */ - FileOffset.QuadPart = 0ULL; - Status = ZwReadFile(LogHandle, - 0, - 0, - 0, - &IoStatusBlock, - LogHeader, - BufferSize, - &FileOffset, - 0); - if (!NT_SUCCESS(Status)) - { - DPRINT("ZwReadFile() failed (Status %lx)\n", Status); - goto ByeBye; - } - - /* Initialize bitmap */ - RtlInitializeBitMap(&BlockBitMap, - (PVOID)((ULONG_PTR)LogHeader + HV_BLOCK_SIZE + sizeof(ULONG)), - BitmapSize * 8); - - /* FIXME: Update dirty blocks */ - - - /* FIXME: Update hive header */ - - - Status = STATUS_SUCCESS; - } - - - /* Clean up the mess */ -ByeBye: - if (HiveHeader != NULL) - ExFreePool(HiveHeader); - - if (LogHeader != NULL) - ExFreePool(LogHeader); - - if (LogHandle != INVALID_HANDLE_VALUE) - ZwClose(LogHandle); - - ZwClose(HiveHandle); - - return(Status); -} -#endif
static NTSTATUS CmiInitNonVolatileRegistryHive (PEREGISTRY_HIVE RegistryHive, @@ -476,18 +204,6 @@ Filename); wcscat(RegistryHive->LogFileName.Buffer, L".log"); - -#ifdef HIVE_CHECK - /* Check and eventually fix a hive */ - Status = CmiCheckAndFixHive(RegistryHive); - if (!NT_SUCCESS(Status)) - { - RtlFreeUnicodeString(&RegistryHive->HiveFileName); - RtlFreeUnicodeString(&RegistryHive->LogFileName); - DPRINT1("CmiCheckAndFixHive() failed (Status %lx)\n", Status); - return(Status); - } -#endif
InitializeObjectAttributes(&ObjectAttributes, &RegistryHive->HiveFileName, @@ -603,71 +319,143 @@ return STATUS_SUCCESS; }
+ULONG +NTAPI +CmCheckRegistry(IN PEREGISTRY_HIVE RegistryHive, + IN ULONG Flags) +{ + /* FIXME: HACK! */ + return 0; +}
NTSTATUS -CmiCreateTempHive(PEREGISTRY_HIVE *RegistryHive) -{ - PEREGISTRY_HIVE Hive; - NTSTATUS Status; - - *RegistryHive = NULL; - - Hive = ExAllocatePool (NonPagedPool, - sizeof(EREGISTRY_HIVE)); - if (Hive == NULL) - return STATUS_INSUFFICIENT_RESOURCES; - - RtlZeroMemory (Hive, - sizeof(EREGISTRY_HIVE)); - - DPRINT("Hive 0x%p\n", Hive); - - Status = HvInitialize(&Hive->Hive, HV_OPERATION_CREATE_HIVE, 0, 0, 0, 0, - CmpAllocate, CmpFree, - CmpFileRead, CmpFileWrite, CmpFileSetSize, - CmpFileFlush, NULL); - if (!NT_SUCCESS(Status)) - { - ExFreePool (Hive); - return Status; - } - - if (!CmCreateRootNode (&Hive->Hive, L"")) - { - HvFree (&Hive->Hive); - ExFreePool (Hive); - return STATUS_INSUFFICIENT_RESOURCES; - } - - Hive->Flags = HIVE_NO_FILE; - - /* Acquire hive list lock exclusively */ - KeEnterCriticalRegion(); - ExAcquireResourceExclusiveLite (&CmiRegistryLock, TRUE); - - /* Add the new hive to the hive list */ - InsertTailList (&CmiHiveListHead, - &Hive->HiveList); - - /* Release hive list lock */ - ExReleaseResourceLite (&CmiRegistryLock); - KeLeaveCriticalRegion(); - - VERIFY_REGISTRY_HIVE (Hive); - - *RegistryHive = Hive; - - return STATUS_SUCCESS; -} - - -NTSTATUS -CmiCreateVolatileHive(PEREGISTRY_HIVE *RegistryHive) -{ - DPRINT ("CmiCreateVolatileHive() called\n"); - return CmiCreateTempHive(RegistryHive); -} - +NTAPI +CmpInitializeHive(OUT PEREGISTRY_HIVE *RegistryHive, + IN ULONG OperationType, + IN ULONG HiveFlags, + IN ULONG FileType, + IN PVOID HiveData OPTIONAL, + IN HANDLE Primary, + IN HANDLE Log, + IN HANDLE External, + IN PUNICODE_STRING FileName OPTIONAL, + IN ULONG CheckFlags) +{ + PEREGISTRY_HIVE Hive; + IO_STATUS_BLOCK IoStatusBlock; + FILE_FS_SIZE_INFORMATION FileSizeInformation; + NTSTATUS Status; + ULONG Cluster; + + /* Assume failure */ + *RegistryHive = NULL; + + /* + * The following are invalid: + * An external hive that is also internal. + * A log hive that's not a primary hive too. + * A volatile hive that's linked to permanent storage. + * An in-memory initialization without hive data. + * A log hive that's not linked to a correct file type. + */ + if (((External) && ((Primary) || (Log))) || + ((Log) && !(Primary)) || + ((HiveFlags & HIVE_VOLATILE) && ((Primary) || (External) || (Log))) || + ((OperationType == HINIT_MEMORY) && (!HiveData)) || + ((Log) && (FileType != HFILE_TYPE_LOG))) + { + /* Fail the request */ + return STATUS_INVALID_PARAMETER; + } + + /* Check if this is a primary hive */ + if (Primary) + { + /* Get the cluster size */ + Status = ZwQueryVolumeInformationFile(Primary, + &IoStatusBlock, + &FileSizeInformation, + sizeof(FILE_FS_SIZE_INFORMATION), + FileFsSizeInformation); + if (!NT_SUCCESS(Status)) return Status; + + /* Make sure it's not larger then the block size */ + if (FileSizeInformation.BytesPerSector > HBLOCK_SIZE) + { + /* Fail */ + return STATUS_REGISTRY_IO_FAILED; + } + + /* Otherwise, calculate the cluster */ + Cluster = FileSizeInformation.BytesPerSector / HSECTOR_SIZE; + Cluster = max(1, Cluster); + } + else + { + /* Otherwise use cluster 1 */ + Cluster = 1; + } + + /* Allocate and clear the hive */ + Hive = ExAllocatePoolWithTag(NonPagedPool, sizeof(EREGISTRY_HIVE), TAG_CM); + if (!Hive) return STATUS_INSUFFICIENT_RESOURCES; + RtlZeroMemory(Hive, sizeof(EREGISTRY_HIVE)); + + /* Initialize it */ + Status = HvInitialize(&Hive->Hive, + OperationType, + HiveFlags, + FileType, + (ULONG_PTR)HiveData, + Cluster, + CmpAllocate, + CmpFree, + CmpFileRead, + CmpFileWrite, + CmpFileSetSize, + CmpFileFlush, + FileName); + if (!NT_SUCCESS(Status)) + { + /* Clear allocations and fail */ + ExFreePool(Hive); + return Status; + } + + /* Set flag */ + Hive->Flags = HIVE_NO_FILE; + + /* Check if we should verify the registry */ + if ((OperationType == HINIT_FILE) || + (OperationType == HINIT_MEMORY) || + (OperationType == HINIT_MEMORY_INPLACE) || + (OperationType == HINIT_MAPFILE)) + { + /* Verify integrity */ + if (CmCheckRegistry(Hive, TRUE)) + { + /* Free all alocations */ + ExFreePool(Hive); + return STATUS_REGISTRY_CORRUPT; + } + } + + /* Acquire hive list lock exclusively */ + KeEnterCriticalRegion(); + ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE); + + /* Add the new hive to the hive list */ + InsertTailList(&CmiHiveListHead, &Hive->HiveList); + + /* Release hive list lock */ + ExReleaseResourceLite(&CmiRegistryLock); + KeLeaveCriticalRegion(); + + /* Return the hive and success */ + VERIFY_REGISTRY_HIVE(Hive); + *RegistryHive = Hive; + return STATUS_SUCCESS; +}
NTSTATUS CmiLoadHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
Modified: trunk/reactos/ntoskrnl/cm/registry.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/registry.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/cm/registry.c (original) +++ trunk/reactos/ntoskrnl/cm/registry.c Fri May 11 08:59:38 2007 @@ -19,6 +19,7 @@ #include <internal/debug.h>
#include "cm.h" +#include "..\config\cm.h"
#if defined (ALLOC_PRAGMA) #pragma alloc_text(INIT, CmInitSystem1) @@ -77,6 +78,30 @@ NTSTATUS NTAPI CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock); + +NTSTATUS +NTAPI +CmpInitializeHive(PEREGISTRY_HIVE *RegistryHive, + ULONG OperationType, + ULONG HiveFlags, + ULONG FileType, + PVOID HiveData OPTIONAL, + HANDLE Primary, + HANDLE Log, + HANDLE External, + PUNICODE_STRING FileName OPTIONAL, + ULONG CheckFlags); + +USHORT +NTAPI +CmpCopyName(IN PHHIVE Hive, + IN PWCHAR Destination, + IN PUNICODE_STRING Source); + +USHORT +NTAPI +CmpNameSize(IN PHHIVE Hive, + IN PUNICODE_STRING Name);
static VOID STDCALL CmiHiveSyncDpcRoutine(PKDPC Dpc, @@ -305,13 +330,77 @@
BOOLEAN NTAPI +CmpCreateRootNode(IN PHHIVE Hive, + IN PCWSTR Name, + OUT PHCELL_INDEX Index) +{ + UNICODE_STRING KeyName; + PCM_KEY_NODE KeyCell; + LARGE_INTEGER SystemTime; + PAGED_CODE(); + + /* Initialize the node name and allocate it */ + RtlInitUnicodeString(&KeyName, Name); + *Index = HvAllocateCell(Hive, + FIELD_OFFSET(CM_KEY_NODE, Name) + + CmpNameSize(Hive, &KeyName), + HvStable); // FIXME: , HCELL_NIL); + if (*Index == HCELL_NIL) return FALSE; + + /* Set the cell index and get the data */ + Hive->HiveHeader->RootCell = *Index; + KeyCell = (PCM_KEY_NODE)HvGetCell(Hive, *Index); + if (!KeyCell) return FALSE; + + /* Setup the cell */ + KeyCell->Id = (USHORT)CM_KEY_NODE_SIGNATURE;; + KeyCell->Flags = KEY_HIVE_ENTRY | KEY_NO_DELETE; + KeQuerySystemTime(&SystemTime); + KeyCell->LastWriteTime = SystemTime; + KeyCell->Parent = HCELL_NIL; + KeyCell->SubKeyCounts[HvStable] = 0; + KeyCell->SubKeyCounts[HvVolatile] = 0; + KeyCell->SubKeyLists[HvStable] = HCELL_NIL; + KeyCell->SubKeyLists[HvVolatile] = HCELL_NIL; + KeyCell->ValueList.Count = 0; + KeyCell->ValueList.List = HCELL_NIL; + KeyCell->SecurityKeyOffset = HCELL_NIL; + KeyCell->ClassNameOffset = HCELL_NIL; + KeyCell->ClassSize = 0; + + /* Copy the name (this will also set the length) */ + KeyCell->NameSize = CmpCopyName(Hive, (PWCHAR)KeyCell->Name, &KeyName); + + /* Check if the name was compressed */ + if (KeyCell->NameSize < KeyName.Length) + { + /* Set the flag */ + KeyCell->Flags |= KEY_COMP_NAME; + } + + /* Return success */ + HvReleaseCell(Hive, *Index); + return TRUE; +} + +BOOLEAN +NTAPI CmpCreateRegistryRoot(VOID) { UNICODE_STRING KeyName; OBJECT_ATTRIBUTES ObjectAttributes; PKEY_OBJECT RootKey; HANDLE RootKeyHandle; + HCELL_INDEX RootIndex; NTSTATUS Status; + PAGED_CODE(); + + /* Setup the root node */ + if (!CmpCreateRootNode(&CmiVolatileHive->Hive, L"REGISTRY", &RootIndex)) + { + /* We failed */ + return FALSE; + }
/* Create '\Registry' key. */ RtlInitUnicodeString(&KeyName, REG_ROOT_KEY_NAME); @@ -333,8 +422,8 @@
/* Setup the root key */ RootKey->RegistryHive = CmiVolatileHive; - RootKey->KeyCellOffset = CmiVolatileHive->Hive.HiveHeader->RootCell; - RootKey->KeyCell = HvGetCell(&CmiVolatileHive->Hive, RootKey->KeyCellOffset); + RootKey->KeyCellOffset = RootIndex; + RootKey->KeyCell = HvGetCell(&CmiVolatileHive->Hive, RootIndex); RootKey->ParentKey = RootKey; RootKey->Flags = 0; RootKey->SubKeyCounts = 0; @@ -421,8 +510,17 @@ KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 1, Status, 0); }
- /* Build volatile registry store */ - Status = CmiCreateVolatileHive(&CmiVolatileHive); + /* Build the master hive */ + Status = CmpInitializeHive(&CmiVolatileHive, + HINIT_CREATE, + HIVE_VOLATILE, + HFILE_TYPE_PRIMARY, + NULL, + NULL, + NULL, + NULL, + NULL, + 0); if (!NT_SUCCESS(Status)) { /* Bugcheck */ @@ -433,7 +531,7 @@ if (!CmpCreateRegistryRoot()) { /* Bugcheck */ - KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 4, 0, 0); + KEBUGCHECKEX(CONFIG_INITIALIZATION_FAILED, 1, 3, 0, 0); }
/* Create '\Registry\Machine' key. */
Modified: trunk/reactos/ntoskrnl/config/cm.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cm.h?rev=26... ============================================================================== --- trunk/reactos/ntoskrnl/config/cm.h (original) +++ trunk/reactos/ntoskrnl/config/cm.h Fri May 11 08:59:38 2007 @@ -84,7 +84,7 @@ // // Cell Masks // -#define HCELL_NIL 0 +#define HCELL_NIL -1 #define HCELL_CACHED 1
// @@ -157,6 +157,8 @@ PAGE_SIZE / sizeof(CM_KEY_CONTROL_BLOCK) #define CM_DELAYS_PER_PAGE \ PAGE_SIZE / sizeof(CM_DELAYED_CLOSE_ENTRY) + +#ifndef __INCLUDE_CM_H
// // Key Hash @@ -984,3 +986,5 @@ // Inlined functions // #include "cm_x.h" + +#endif
Modified: trunk/reactos/ntoskrnl/config/cmname.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmname.c?re... ============================================================================== --- trunk/reactos/ntoskrnl/config/cmname.c (original) +++ trunk/reactos/ntoskrnl/config/cmname.c Fri May 11 08:59:38 2007 @@ -17,6 +17,62 @@
/* FUNCTIONS *****************************************************************/
+USHORT +NTAPI +CmpCopyName(IN PHHIVE Hive, + IN PWCHAR Destination, + IN PUNICODE_STRING Source) +{ + ULONG i; + + /* Check for old hives */ + if (Hive->Version == 1) + { + /* Just copy the source directly */ + RtlCopyMemory(Destination, Source->Buffer, Source->Length); + return Source->Length; + } + + /* For new versions, check for compressed name */ + for (i = 0; i < (Source->Length / sizeof(WCHAR)); i++) + { + /* Check if the name is non compressed */ + if (Source->Buffer[i] > (UCHAR)-1) + { + /* Do the copy */ + RtlCopyMemory(Destination, Source->Buffer, Source->Length); + return Source->Length; + } + + /* Copy this character */ + Destination[i] = Source->Buffer[i]; + } + + /* Compressed name, return length */ + return Source->Length / sizeof(WCHAR); +} + +USHORT +NTAPI +CmpNameSize(IN PHHIVE Hive, + IN PUNICODE_STRING Name) +{ + ULONG i; + + /* For old hives, just retun the length */ + if (Hive->Version == 1) return Name->Length; + + /* For new versions, check for compressed name */ + for (i = 0; i < (Name->Length / sizeof(WCHAR)); i++) + { + /* Check if the name is non compressed */ + if (Name->Buffer[i] > (UCHAR)-1) return Name->Length; + } + + /* Compressed name, return length */ + return Name->Length / sizeof(WCHAR); +} + LONG NTAPI CmpCompareCompressedName(IN PUNICODE_STRING SearchName,