Implemented packing of value names
authorEric Kohl <eric.kohl@reactos.org>
Sat, 30 Nov 2002 14:46:27 +0000 (14:46 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Sat, 30 Nov 2002 14:46:27 +0000 (14:46 +0000)
svn path=/trunk/; revision=3811

reactos/ntoskrnl/cm/cm.h
reactos/ntoskrnl/cm/ntfunc.c
reactos/ntoskrnl/cm/regfile.c
reactos/ntoskrnl/cm/registry.c
reactos/ntoskrnl/cm/regobj.c
reactos/ntoskrnl/cm/rtlfunc.c

index 3799acc..8364585 100644 (file)
@@ -42,9 +42,6 @@
 #define  REG_KEY_CELL_ID               0x6b6e
 #define  REG_HASH_TABLE_BLOCK_ID       0x666c
 #define  REG_VALUE_CELL_ID             0x6b76
 #define  REG_KEY_CELL_ID               0x6b6e
 #define  REG_HASH_TABLE_BLOCK_ID       0x666c
 #define  REG_VALUE_CELL_ID             0x6b76
-#define  REG_LINK_KEY_CELL_TYPE        0x10
-#define  REG_KEY_CELL_TYPE             0x20
-#define  REG_ROOT_KEY_CELL_TYPE        0x2c
 #define  REG_HIVE_ID                   0x66676572
 
 #define  REGISTRY_FILE_MAGIC    "REGEDIT4"
 #define  REG_HIVE_ID                   0x66676572
 
 #define  REGISTRY_FILE_MAGIC    "REGEDIT4"
@@ -191,6 +188,12 @@ typedef struct _KEY_CELL
   UCHAR  Name[0];
 } __attribute__((packed)) KEY_CELL, *PKEY_CELL;
 
   UCHAR  Name[0];
 } __attribute__((packed)) KEY_CELL, *PKEY_CELL;
 
+/* KEY_CELL.Type constants */
+#define  REG_LINK_KEY_CELL_TYPE        0x10
+#define  REG_KEY_CELL_TYPE             0x20
+#define  REG_ROOT_KEY_CELL_TYPE        0x2c
+
+
 // hash record :
 // HashValue=four letters of value's name
 typedef struct _HASH_RECORD
 // hash record :
 // HashValue=four letters of value's name
 typedef struct _HASH_RECORD
@@ -226,6 +229,10 @@ typedef struct _VALUE_CELL
   UCHAR  Name[0]; /* warning : not zero terminated */
 } __attribute__((packed)) VALUE_CELL, *PVALUE_CELL;
 
   UCHAR  Name[0]; /* warning : not zero terminated */
 } __attribute__((packed)) VALUE_CELL, *PVALUE_CELL;
 
+/* VALUE_CELL.Flags constants */
+#define REG_VALUE_NAME_PACKED             0x0001
+
+
 typedef struct _DATA_CELL
 {
   LONG  CellSize;
 typedef struct _DATA_CELL
 {
   LONG  CellSize;
@@ -427,7 +434,7 @@ CmiAddSubKey(IN PREGISTRY_HIVE  RegistryHive,
 NTSTATUS
 CmiScanKeyForValue(IN PREGISTRY_HIVE  RegistryHive,
   IN PKEY_CELL  KeyCell,
 NTSTATUS
 CmiScanKeyForValue(IN PREGISTRY_HIVE  RegistryHive,
   IN PKEY_CELL  KeyCell,
-  IN PCHAR  ValueName,
+  IN PUNICODE_STRING  ValueName,
   OUT PVALUE_CELL  *ValueCell,
   OUT BLOCK_OFFSET *VBOffset);
 
   OUT PVALUE_CELL  *ValueCell,
   OUT BLOCK_OFFSET *VBOffset);
 
@@ -440,14 +447,14 @@ CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE  RegistryHive,
 NTSTATUS
 CmiAddValueToKey(IN PREGISTRY_HIVE  RegistryHive,
   IN PKEY_CELL  KeyCell,
 NTSTATUS
 CmiAddValueToKey(IN PREGISTRY_HIVE  RegistryHive,
   IN PKEY_CELL  KeyCell,
-  IN PCHAR  ValueNameBuf,
-       OUT PVALUE_CELL *pValueCell,
-       OUT BLOCK_OFFSET *pVBOffset);
+  IN PUNICODE_STRING ValueName,
+  OUT PVALUE_CELL *pValueCell,
+  OUT BLOCK_OFFSET *pVBOffset);
 
 NTSTATUS
 CmiDeleteValueFromKey(IN PREGISTRY_HIVE  RegistryHive,
   IN PKEY_CELL  KeyCell,
 
 NTSTATUS
 CmiDeleteValueFromKey(IN PREGISTRY_HIVE  RegistryHive,
   IN PKEY_CELL  KeyCell,
-  IN PCHAR  ValueName);
+  IN PUNICODE_STRING ValueName);
 
 NTSTATUS
 CmiAllocateHashTableBlock(IN PREGISTRY_HIVE  RegistryHive,
 
 NTSTATUS
 CmiAllocateHashTableBlock(IN PREGISTRY_HIVE  RegistryHive,
@@ -468,9 +475,9 @@ CmiAddKeyToHashTable(PREGISTRY_HIVE  RegistryHive,
 
 NTSTATUS
 CmiAllocateValueCell(IN PREGISTRY_HIVE  RegistryHive,
 
 NTSTATUS
 CmiAllocateValueCell(IN PREGISTRY_HIVE  RegistryHive,
- OUT PVALUE_CELL  *ValueCell,
- OUT BLOCK_OFFSET  *VBOffset,
IN PCHAR  ValueNameBuf);
 OUT PVALUE_CELL  *ValueCell,
 OUT BLOCK_OFFSET  *VBOffset,
 IN PUNICODE_STRING ValueName);
 
 NTSTATUS
 CmiDestroyValueCell(PREGISTRY_HIVE  RegistryHive,
 
 NTSTATUS
 CmiDestroyValueCell(PREGISTRY_HIVE  RegistryHive,
@@ -509,4 +516,19 @@ CmiAddFree(PREGISTRY_HIVE  RegistryHive,
 NTSTATUS
 CmiInitHives(BOOLEAN SetUpBoot);
 
 NTSTATUS
 CmiInitHives(BOOLEAN SetUpBoot);
 
+ULONG
+CmiGetPackedNameLength(IN PUNICODE_STRING Name,
+                      OUT PBOOLEAN Packable);
+
+BOOLEAN
+CmiComparePackedNames(IN PUNICODE_STRING Name,
+                     IN PCHAR NameBuffer,
+                     IN USHORT NameBufferSize,
+                     IN BOOLEAN NamePacked);
+
+VOID
+CmiCopyPackedName(PWCHAR NameBuffer,
+                 PCHAR PackedNameBuffer,
+                 ULONG PackedNameSize);
+
 #endif /*__INCLUDE_CM_H*/
 #endif /*__INCLUDE_CM_H*/
index dd9d8ea..71ede9d 100644 (file)
@@ -515,8 +515,16 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
       switch (KeyValueInformationClass)
         {
         case KeyValueBasicInformation:
       switch (KeyValueInformationClass)
         {
         case KeyValueBasicInformation:
-          *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) + 
-            (ValueCell->NameSize + 1) * sizeof(WCHAR);
+          if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
+            {
+              *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) + 
+                (ValueCell->NameSize + 1) * sizeof(WCHAR);
+            }
+          else
+            {
+              *ResultLength = sizeof(KEY_VALUE_BASIC_INFORMATION) + 
+                ValueCell->NameSize + sizeof(WCHAR);
+            }
           if (Length < *ResultLength)
             {
               Status = STATUS_BUFFER_OVERFLOW;
           if (Length < *ResultLength)
             {
               Status = STATUS_BUFFER_OVERFLOW;
@@ -527,12 +535,24 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
                 KeyValueInformation;
               ValueBasicInformation->TitleIndex = 0;
               ValueBasicInformation->Type = ValueCell->DataType;
                 KeyValueInformation;
               ValueBasicInformation->TitleIndex = 0;
               ValueBasicInformation->Type = ValueCell->DataType;
-              ValueBasicInformation->NameLength =
-                (ValueCell->NameSize + 1) * sizeof(WCHAR);
-              mbstowcs(ValueBasicInformation->Name,
-                ValueCell->Name,
-                                 ValueCell->NameSize * 2);
-              ValueBasicInformation->Name[ValueCell->NameSize] = 0;
+              if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
+                {
+                  ValueBasicInformation->NameLength =
+                    (ValueCell->NameSize + 1) * sizeof(WCHAR);
+                  CmiCopyPackedName(ValueBasicInformation->Name,
+                                    ValueCell->Name,
+                                    ValueCell->NameSize);
+                  ValueBasicInformation->Name[ValueCell->NameSize] = 0;
+                }
+              else
+                {
+                  ValueBasicInformation->NameLength =
+                    ValueCell->NameSize + sizeof(WCHAR);
+                  RtlCopyMemory(ValueBasicInformation->Name,
+                                ValueCell->Name,
+                                ValueCell->NameSize * sizeof(WCHAR));
+                  ValueBasicInformation->Name[ValueCell->NameSize / sizeof(WCHAR)] = 0;
+                }
             }
           break;
 
             }
           break;
 
@@ -569,8 +589,18 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
           break;
 
         case KeyValueFullInformation:
           break;
 
         case KeyValueFullInformation:
-          *ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) + 
-            ValueCell->NameSize * sizeof(WCHAR) + (ValueCell->DataSize & LONG_MAX);
+          if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
+            {
+              *ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) + 
+                (ValueCell->NameSize + 1) * sizeof(WCHAR) +
+                (ValueCell->DataSize & LONG_MAX);
+            }
+          else
+            {
+              *ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION) + 
+                ValueCell->NameSize + sizeof(WCHAR) +
+                (ValueCell->DataSize & LONG_MAX);
+            }
           if (Length < *ResultLength)
             {
               Status = STATUS_BUFFER_OVERFLOW;
           if (Length < *ResultLength)
             {
               Status = STATUS_BUFFER_OVERFLOW;
@@ -581,34 +611,56 @@ NtEnumerateValueKey(IN HANDLE KeyHandle,
                 KeyValueInformation;
               ValueFullInformation->TitleIndex = 0;
               ValueFullInformation->Type = ValueCell->DataType;
                 KeyValueInformation;
               ValueFullInformation->TitleIndex = 0;
               ValueFullInformation->Type = ValueCell->DataType;
-              ValueFullInformation->DataOffset = 
-                (DWORD)ValueFullInformation->Name - (DWORD) ValueFullInformation
-                + (ValueCell->NameSize + 1) * sizeof(WCHAR);
+              if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
+                {
+                  ValueFullInformation->DataOffset = 
+                    (DWORD)ValueFullInformation->Name - (DWORD) ValueFullInformation
+                    + (ValueCell->NameSize + 1) * sizeof(WCHAR);
+                }
+              else
+                {
+                  ValueFullInformation->DataOffset = 
+                    (DWORD)ValueFullInformation->Name - (DWORD) ValueFullInformation
+                    + ValueCell->NameSize + sizeof(WCHAR);
+                }
               ValueFullInformation->DataOffset =
               ValueFullInformation->DataOffset =
-                           (ValueFullInformation->DataOffset + 3) & 0xfffffffc;
+                (ValueFullInformation->DataOffset + 3) & 0xfffffffc;
               ValueFullInformation->DataLength = ValueCell->DataSize & LONG_MAX;
               ValueFullInformation->DataLength = ValueCell->DataSize & LONG_MAX;
-              ValueFullInformation->NameLength =
-                (ValueCell->NameSize + 1) * sizeof(WCHAR);
-              mbstowcs(ValueFullInformation->Name,
-                ValueCell->Name,
-                               ValueCell->NameSize * 2);
-              ValueFullInformation->Name[ValueCell->NameSize] = 0;
+              if (ValueCell->Flags & REG_VALUE_NAME_PACKED)
+                {
+                  ValueFullInformation->NameLength =
+                    (ValueCell->NameSize + 1) * sizeof(WCHAR);
+
+                  CmiCopyPackedName(ValueFullInformation->Name,
+                                   ValueCell->Name,
+                                   ValueCell->NameSize);
+                  ValueFullInformation->Name[ValueCell->NameSize] = 0;
+                }
+              else
+                {
+                  ValueFullInformation->NameLength =
+                    ValueCell->NameSize + sizeof(WCHAR);
+                  RtlCopyMemory(ValueFullInformation->Name,
+                               ValueCell->Name,
+                               ValueCell->NameSize);
+                  ValueFullInformation->Name[ValueCell->NameSize / sizeof(WCHAR)] = 0;
+                }
               if (ValueCell->DataSize > 0)
               if (ValueCell->DataSize > 0)
-                     {
-                       DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL);
-                       RtlCopyMemory((PCHAR) ValueFullInformation
-                                     + ValueFullInformation->DataOffset,
-                         DataCell->Data,
-                         ValueCell->DataSize & LONG_MAX);
-                       CmiReleaseBlock(RegistryHive, DataCell);
-                     }
+                {
+                  DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL);
+                  RtlCopyMemory((PCHAR) ValueFullInformation
+                    + ValueFullInformation->DataOffset,
+                    DataCell->Data,
+                    ValueCell->DataSize & LONG_MAX);
+                  CmiReleaseBlock(RegistryHive, DataCell);
+                }
               else
               else
-                     {
-                       RtlCopyMemory((PCHAR) ValueFullInformation
-                                     + ValueFullInformation->DataOffset,
-                         &ValueCell->DataOffset,
-                         ValueCell->DataSize & LONG_MAX);
-                     }
+                {
+                  RtlCopyMemory((PCHAR) ValueFullInformation
+                    + ValueFullInformation->DataOffset,
+                    &ValueCell->DataOffset,
+                    ValueCell->DataSize & LONG_MAX);
+                }
             }
           break;
         }
             }
           break;
         }
@@ -859,7 +911,7 @@ NtOpenKey(OUT PHANDLE KeyHandle,
   NTSTATUS Status;
   PVOID Object;
 
   NTSTATUS Status;
   PVOID Object;
 
-  DPRINT("KH %x  DA %x  OA %x  OA->ON %x\n",
+  DPRINT("NtOpenFile(KH %x  DA %x  OA %x  OA->ON '%wZ'\n",
         KeyHandle,
         DesiredAccess,
         ObjectAttributes,
         KeyHandle,
         DesiredAccess,
         ObjectAttributes,
@@ -877,7 +929,7 @@ NtOpenKey(OUT PHANDLE KeyHandle,
 
   VERIFY_KEY_OBJECT((PKEY_OBJECT) Object);
 
 
   VERIFY_KEY_OBJECT((PKEY_OBJECT) Object);
 
-  DPRINT("RemainingPath.Buffer %x\n", RemainingPath.Buffer);
+  DPRINT("RemainingPath '%wZ'\n", &RemainingPath);
 
   if ((RemainingPath.Buffer != NULL) && (RemainingPath.Buffer[0] != 0))
     {
 
   if ((RemainingPath.Buffer != NULL) && (RemainingPath.Buffer[0] != 0))
     {
@@ -1081,14 +1133,10 @@ NtQueryValueKey(IN HANDLE KeyHandle,
   PKEY_VALUE_BASIC_INFORMATION  ValueBasicInformation;
   PKEY_VALUE_PARTIAL_INFORMATION  ValuePartialInformation;
   PKEY_VALUE_FULL_INFORMATION  ValueFullInformation;
   PKEY_VALUE_BASIC_INFORMATION  ValueBasicInformation;
   PKEY_VALUE_PARTIAL_INFORMATION  ValuePartialInformation;
   PKEY_VALUE_FULL_INFORMATION  ValueFullInformation;
-  char ValueName2[MAX_PATH];
 
   DPRINT("NtQueryValueKey(KeyHandle %x  ValueName %S  Length %x)\n",
     KeyHandle, ValueName->Buffer, Length);
 
 
   DPRINT("NtQueryValueKey(KeyHandle %x  ValueName %S  Length %x)\n",
     KeyHandle, ValueName->Buffer, Length);
 
-  wcstombs(ValueName2, ValueName->Buffer, ValueName->Length >> 1);
-  ValueName2[ValueName->Length >> 1] = 0;
-
   /* Verify that the handle is valid and is a registry key */
   Status = ObReferenceObjectByHandle(KeyHandle,
                KEY_QUERY_VALUE,
   /* Verify that the handle is valid and is a registry key */
   Status = ObReferenceObjectByHandle(KeyHandle,
                KEY_QUERY_VALUE,
@@ -1115,7 +1163,7 @@ NtQueryValueKey(IN HANDLE KeyHandle,
   /* Get Value block of interest */
   Status = CmiScanKeyForValue(RegistryHive,
                              KeyCell,
   /* Get Value block of interest */
   Status = CmiScanKeyForValue(RegistryHive,
                              KeyCell,
-                             ValueName2,
+                             ValueName,
                              &ValueCell,
                              NULL);
   if (!NT_SUCCESS(Status))
                              &ValueCell,
                              NULL);
   if (!NT_SUCCESS(Status))
@@ -1159,39 +1207,39 @@ NtQueryValueKey(IN HANDLE KeyHandle,
             }
           else
             {
             }
           else
             {
-              ValuePartialInformation = (PKEY_VALUE_PARTIAL_INFORMATION) 
+              ValuePartialInformation = (PKEY_VALUE_PARTIAL_INFORMATION)
                 KeyValueInformation;
               ValuePartialInformation->TitleIndex = 0;
               ValuePartialInformation->Type = ValueCell->DataType;
               ValuePartialInformation->DataLength = ValueCell->DataSize & LONG_MAX;
               if (ValueCell->DataSize > 0)
                 KeyValueInformation;
               ValuePartialInformation->TitleIndex = 0;
               ValuePartialInformation->Type = ValueCell->DataType;
               ValuePartialInformation->DataLength = ValueCell->DataSize & LONG_MAX;
               if (ValueCell->DataSize > 0)
-                     {
-                       DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL);
-                       RtlCopyMemory(ValuePartialInformation->Data, 
+                {
+                  DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL);
+                  RtlCopyMemory(ValuePartialInformation->Data,
                     DataCell->Data,
                     ValueCell->DataSize & LONG_MAX);
                     DataCell->Data,
                     ValueCell->DataSize & LONG_MAX);
-                       CmiReleaseBlock(RegistryHive, DataCell);
-                     }
+                  CmiReleaseBlock(RegistryHive, DataCell);
+                }
               else
               else
-                     {
-                       RtlCopyMemory(ValuePartialInformation->Data, 
-                    &ValueCell->DataOffset, 
+                {
+                  RtlCopyMemory(ValuePartialInformation->Data,
+                    &ValueCell->DataOffset,
                     ValueCell->DataSize & LONG_MAX);
                     ValueCell->DataSize & LONG_MAX);
-                     }
+                }
             }
           break;
 
         case KeyValueFullInformation:
           *ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION)
             }
           break;
 
         case KeyValueFullInformation:
           *ResultLength = sizeof(KEY_VALUE_FULL_INFORMATION)
-                                               + (ValueCell->NameSize -1) * sizeof(WCHAR)
-                                               + (ValueCell->DataSize & LONG_MAX);
+            + (ValueCell->NameSize -1) * sizeof(WCHAR)
+            + (ValueCell->DataSize & LONG_MAX);
           if (Length < *ResultLength)
             {
               Status = STATUS_BUFFER_TOO_SMALL;
             }
           else
             {
           if (Length < *ResultLength)
             {
               Status = STATUS_BUFFER_TOO_SMALL;
             }
           else
             {
-              ValueFullInformation = (PKEY_VALUE_FULL_INFORMATION) 
+              ValueFullInformation = (PKEY_VALUE_FULL_INFORMATION)
                 KeyValueInformation;
               ValueFullInformation->TitleIndex = 0;
               ValueFullInformation->Type = ValueCell->DataType;
                 KeyValueInformation;
               ValueFullInformation->TitleIndex = 0;
               ValueFullInformation->Type = ValueCell->DataType;
@@ -1251,17 +1299,13 @@ NtSetValueKey(IN HANDLE KeyHandle,
   PKEY_CELL  KeyCell;
   PVALUE_CELL  ValueCell;
   BLOCK_OFFSET VBOffset;
   PKEY_CELL  KeyCell;
   PVALUE_CELL  ValueCell;
   BLOCK_OFFSET VBOffset;
-  char ValueName2[MAX_PATH];
   PDATA_CELL DataCell;
   PDATA_CELL NewDataCell;
   PHBIN pBin;
   ULONG DesiredAccess;
 
   PDATA_CELL DataCell;
   PDATA_CELL NewDataCell;
   PHBIN pBin;
   ULONG DesiredAccess;
 
-  DPRINT("KeyHandle %x  ValueName %S  Type %d\n",
-    KeyHandle, ValueName? ValueName->Buffer : NULL, Type);
-
-  wcstombs(ValueName2,ValueName->Buffer, ValueName->Length >> 1);
-  ValueName2[ValueName->Length>>1] = 0;
+  DPRINT("NtSetValueKey(KeyHandle %x  ValueName %S  Type %d)\n",
+        KeyHandle, ValueName? ValueName->Buffer : NULL, Type);
 
   DesiredAccess = KEY_SET_VALUE;
   if (Type == REG_LINK)
 
   DesiredAccess = KEY_SET_VALUE;
   if (Type == REG_LINK)
@@ -1287,7 +1331,7 @@ NtSetValueKey(IN HANDLE KeyHandle,
   RegistryHive = KeyObject->RegistryHive;
   Status = CmiScanKeyForValue(RegistryHive,
                              KeyCell,
   RegistryHive = KeyObject->RegistryHive;
   Status = CmiScanKeyForValue(RegistryHive,
                              KeyCell,
-                             ValueName2,
+                             ValueName,
                              &ValueCell,
                              &VBOffset);
   if (!NT_SUCCESS(Status))
                              &ValueCell,
                              &VBOffset);
   if (!NT_SUCCESS(Status))
@@ -1301,9 +1345,10 @@ NtSetValueKey(IN HANDLE KeyHandle,
 
   if (ValueCell == NULL)
     {
 
   if (ValueCell == NULL)
     {
+      DPRINT("Allocate new value cell\n");
       Status = CmiAddValueToKey(RegistryHive,
                                KeyCell,
       Status = CmiAddValueToKey(RegistryHive,
                                KeyCell,
-                               ValueName2,
+                               ValueName,
                                &ValueCell,
                                &VBOffset);
     }
                                &ValueCell,
                                &VBOffset);
     }
@@ -1316,70 +1361,92 @@ NtSetValueKey(IN HANDLE KeyHandle,
       ObDereferenceObject(KeyObject);
       return(Status);
     }
       ObDereferenceObject(KeyObject);
       return(Status);
     }
-  else
-    {
-      DPRINT("DataSize (%d)\n", DataSize);
 
 
+  DPRINT("DataSize %lu\n", DataSize);
+  DPRINT("ValueCell %p\n", ValueCell);
+  DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize);
+
+  if (DataSize <= 4)
+    {
       /* If datasize <= 4 then write in valueblock directly */
       /* If datasize <= 4 then write in valueblock directly */
-      if (DataSize <= 4)
+      DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize);
+      if ((ValueCell->DataSize >= 0) &&
+         (DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL)))
        {
        {
-         DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize);
-         if ((ValueCell->DataSize >= 0) &&
-             (DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL)))
-           {
-             CmiDestroyBlock(RegistryHive, DataCell, ValueCell->DataOffset);
-           }
-
-         RtlCopyMemory(&ValueCell->DataOffset, Data, DataSize);
-         ValueCell->DataSize = DataSize | 0x80000000;
-         ValueCell->DataType = Type;
-         RtlMoveMemory(&ValueCell->DataOffset, Data, DataSize);
+         CmiDestroyBlock(RegistryHive, DataCell, ValueCell->DataOffset);
        }
        }
+
+      RtlCopyMemory(&ValueCell->DataOffset, Data, DataSize);
+      ValueCell->DataSize = DataSize | 0x80000000;
+      ValueCell->DataType = Type;
+      RtlMoveMemory(&ValueCell->DataOffset, Data, DataSize);
+    }
+  else if (DataSize <= (ULONG) (ValueCell->DataSize & 0x7fffffff))
+    {
       /* If new data size is <= current then overwrite current data */
       /* If new data size is <= current then overwrite current data */
-      else if (DataSize <= (ULONG) (ValueCell->DataSize & 0x7fffffff))
+      DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset,&pBin);
+      RtlCopyMemory(DataCell->Data, Data, DataSize);
+      ValueCell->DataSize = DataSize;
+      ValueCell->DataType = Type;
+      CmiReleaseBlock(RegistryHive, DataCell);
+
+      /* Update time of heap */
+      if (IsPermanentHive(RegistryHive))
        {
        {
-         DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset,&pBin);
-         RtlCopyMemory(DataCell->Data, Data, DataSize);
-         ValueCell->DataSize = DataSize;
-         ValueCell->DataType = Type;
-         CmiReleaseBlock(RegistryHive, DataCell);
-         /* Update time of heap */
-         if (IsPermanentHive(RegistryHive))
-           {
-             ZwQuerySystemTime((PTIME) &pBin->DateModified);
-           }
+         ZwQuerySystemTime((PTIME) &pBin->DateModified);
        }
        }
-      else
-       {
-         BLOCK_OFFSET NewOffset;
+    }
+  else
+    {
+      /*
+       * New data size is larger than the current, destroy current
+       * data block and allocate a new one.
+       */
+      BLOCK_OFFSET NewOffset;
 
 
-         /* Destroy current data block and allocate a new one */
-         if ((ValueCell->DataSize >= 0) &&
-             (DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL)))
-           {
-             CmiDestroyBlock(RegistryHive, DataCell, ValueCell->DataOffset);
-           }
-         Status = CmiAllocateBlock(RegistryHive,
-                                   (PVOID *)&NewDataCell,
-                                   DataSize,
-                                   &NewOffset);
-         RtlCopyMemory(&NewDataCell->Data[0], Data, DataSize);
-         ValueCell->DataSize = DataSize;
-         ValueCell->DataType = Type;
-         CmiReleaseBlock(RegistryHive, NewDataCell);
-         ValueCell->DataOffset = NewOffset;
-       }
+      DPRINT("ValueCell->DataSize %lu\n", ValueCell->DataSize);
 
 
-      if (strcmp(ValueName2, "SymbolicLinkValue") == 0)
+      if ((ValueCell->DataSize >= 0) &&
+         (DataCell = CmiGetBlock(RegistryHive, ValueCell->DataOffset, NULL)))
        {
        {
-         KeyCell->Type = REG_LINK_KEY_CELL_TYPE;
+         CmiDestroyBlock(RegistryHive, DataCell, ValueCell->DataOffset);
+         ValueCell->DataSize = 0;
+         ValueCell->DataType = 0;
+         ValueCell->DataOffset = 0xffffffff;
        }
 
        }
 
-      /* Update time of heap */
-      if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, VBOffset, &pBin))
+      Status = CmiAllocateBlock(RegistryHive,
+                               (PVOID *)&NewDataCell,
+                               DataSize,
+                               &NewOffset);
+      if (!NT_SUCCESS(Status))
        {
        {
-         ZwQuerySystemTime((PTIME) &pBin->DateModified);
+         DPRINT("CmiAllocateBlock() failed (Status %lx)\n", Status);
+
+         ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
+         ObDereferenceObject(KeyObject);
+
+         return(Status);
        }
        }
+
+      RtlCopyMemory(&NewDataCell->Data[0], Data, DataSize);
+      ValueCell->DataSize = DataSize;
+      ValueCell->DataType = Type;
+      CmiReleaseBlock(RegistryHive, NewDataCell);
+      ValueCell->DataOffset = NewOffset;
+    }
+
+  /* Mark link key */
+  if ((_wcsicmp(ValueName->Buffer, L"SymbolicLinkValue") == 0) &&
+      (Type == REG_LINK))
+    {
+      KeyCell->Type = REG_LINK_KEY_CELL_TYPE;
+    }
+
+  /* Update time of heap */
+  if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, VBOffset, &pBin))
+    {
+      ZwQuerySystemTime((PTIME) &pBin->DateModified);
     }
 
   ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
     }
 
   ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
@@ -1395,13 +1462,9 @@ NTSTATUS STDCALL
 NtDeleteValueKey(IN HANDLE KeyHandle,
                 IN PUNICODE_STRING ValueName)
 {
 NtDeleteValueKey(IN HANDLE KeyHandle,
                 IN PUNICODE_STRING ValueName)
 {
-  CHAR ValueName2[MAX_PATH];
   PKEY_OBJECT KeyObject;
   NTSTATUS Status;
 
   PKEY_OBJECT KeyObject;
   NTSTATUS Status;
 
-  wcstombs(ValueName2, ValueName->Buffer, ValueName->Length >> 1);
-  ValueName2[ValueName->Length>>1] = 0;
-
   /* Verify that the handle is valid and is a registry key */
   Status = ObReferenceObjectByHandle(KeyHandle,
                KEY_QUERY_VALUE,
   /* Verify that the handle is valid and is a registry key */
   Status = ObReferenceObjectByHandle(KeyHandle,
                KEY_QUERY_VALUE,
@@ -1421,7 +1484,7 @@ NtDeleteValueKey(IN HANDLE KeyHandle,
 
   Status = CmiDeleteValueFromKey(KeyObject->RegistryHive,
                                 KeyObject->KeyCell,
 
   Status = CmiDeleteValueFromKey(KeyObject->RegistryHive,
                                 KeyObject->KeyCell,
-                                ValueName2);
+                                ValueName);
 
   /* Release hive lock */
   ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
 
   /* Release hive lock */
   ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
@@ -1452,12 +1515,12 @@ NtLoadKey2(IN PHANDLE KeyHandle,
 NTSTATUS STDCALL
 NtNotifyChangeKey(
        IN      HANDLE  KeyHandle,
 NTSTATUS STDCALL
 NtNotifyChangeKey(
        IN      HANDLE  KeyHandle,
-       IN      HANDLE  Event,
-       IN      PIO_APC_ROUTINE  ApcRoutine  OPTIONAL, 
-       IN      PVOID    ApcContext  OPTIONAL, 
+       IN      HANDLE  Event,
+       IN      PIO_APC_ROUTINE  ApcRoutine  OPTIONAL,
+       IN      PVOID  ApcContext  OPTIONAL,
        OUT     PIO_STATUS_BLOCK  IoStatusBlock,
        IN      ULONG  CompletionFilter,
        OUT     PIO_STATUS_BLOCK  IoStatusBlock,
        IN      ULONG  CompletionFilter,
-       IN      BOOLEAN  Asynchroneous, 
+       IN      BOOLEAN  Asynchroneous,
        OUT     PVOID  ChangeBuffer,
        IN      ULONG  Length,
        IN      BOOLEAN  WatchSubtree)
        OUT     PVOID  ChangeBuffer,
        IN      ULONG  Length,
        IN      BOOLEAN  WatchSubtree)
@@ -1475,7 +1538,6 @@ NtQueryMultipleValueKey(IN HANDLE KeyHandle,
                        OUT PULONG ReturnLength)
 {
   PREGISTRY_HIVE RegistryHive;
                        OUT PULONG ReturnLength)
 {
   PREGISTRY_HIVE RegistryHive;
-  UCHAR ValueName[MAX_PATH];
   PVALUE_CELL ValueCell;
   PKEY_OBJECT KeyObject;
   PDATA_CELL DataCell;
   PVALUE_CELL ValueCell;
   PKEY_OBJECT KeyObject;
   PDATA_CELL DataCell;
@@ -1511,17 +1573,12 @@ NtQueryMultipleValueKey(IN HANDLE KeyHandle,
 
   for (i = 0; i < NumberOfValues; i++)
     {
 
   for (i = 0; i < NumberOfValues; i++)
     {
-      wcstombs(ValueName,
-              ValueList[i].ValueName->Buffer,
-              ValueList[i].ValueName->Length >> 1);
-      ValueName[ValueList[i].ValueName->Length >> 1] = 0;
-
-      DPRINT("ValueName: '%s'\n", ValueName);
+      DPRINT("ValueName: '%wZ'\n", ValueList[i].ValueName);
 
       /* Get Value block of interest */
       Status = CmiScanKeyForValue(RegistryHive,
                          KeyCell,
 
       /* Get Value block of interest */
       Status = CmiScanKeyForValue(RegistryHive,
                          KeyCell,
-                         ValueName,
+                         ValueList[i].ValueName,
                          &ValueCell,
                          NULL);
 
                          &ValueCell,
                          NULL);
 
index 4587dc2..b3d5fbf 100644 (file)
@@ -1204,7 +1204,7 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
           /* Reallocate the hash table block */
           Status = CmiAllocateHashTableBlock(RegistryHive,
             &NewHashBlock,
           /* Reallocate the hash table block */
           Status = CmiAllocateHashTableBlock(RegistryHive,
             &NewHashBlock,
-                                         &HTOffset,
+            &HTOffset,
             HashBlock->HashTableSize +
             REG_EXTEND_HASH_TABLE_SIZE);
 
             HashBlock->HashTableSize +
             REG_EXTEND_HASH_TABLE_SIZE);
 
@@ -1219,7 +1219,7 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
             &HashBlock->Table[0],
             sizeof(NewHashBlock->Table[0]) * HashBlock->HashTableSize);
           CmiDestroyBlock(RegistryHive, HashBlock, KeyCell->HashTableOffset);
             &HashBlock->Table[0],
             sizeof(NewHashBlock->Table[0]) * HashBlock->HashTableSize);
           CmiDestroyBlock(RegistryHive, HashBlock, KeyCell->HashTableOffset);
-               KeyCell->HashTableOffset = HTOffset;
+          KeyCell->HashTableOffset = HTOffset;
           HashBlock = NewHashBlock;
         }
     }
           HashBlock = NewHashBlock;
         }
     }
@@ -1237,13 +1237,12 @@ CmiAddSubKey(PREGISTRY_HIVE RegistryHive,
 NTSTATUS
 CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
        IN PKEY_CELL KeyCell,
 NTSTATUS
 CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
        IN PKEY_CELL KeyCell,
-       IN PCHAR ValueName,
+       IN PUNICODE_STRING ValueName,
        OUT PVALUE_CELL *ValueCell,
        OUT BLOCK_OFFSET *VBOffset)
 {
   PVALUE_LIST_CELL ValueListCell;
   PVALUE_CELL CurValueCell;
        OUT PVALUE_CELL *ValueCell,
        OUT BLOCK_OFFSET *VBOffset)
 {
   PVALUE_LIST_CELL ValueListCell;
   PVALUE_CELL CurValueCell;
-  ULONG Length;
   ULONG i;
 
   ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL);
   ULONG i;
 
   ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL);
@@ -1261,17 +1260,17 @@ CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
   for (i = 0; i < KeyCell->NumberOfValues; i++)
     {
       CurValueCell = CmiGetBlock(RegistryHive,
   for (i = 0; i < KeyCell->NumberOfValues; i++)
     {
       CurValueCell = CmiGetBlock(RegistryHive,
-        ValueListCell->Values[i],
-        NULL);
-      /* FIXME: perhaps we must not ignore case if NtCreateKey has not been */
-      /*        called with OBJ_CASE_INSENSITIVE flag ? */
-      Length = strlen(ValueName);
+                                ValueListCell->Values[i],
+                                NULL);
+
       if ((CurValueCell != NULL) &&
       if ((CurValueCell != NULL) &&
-          (CurValueCell->NameSize == Length) &&
-          (_strnicmp(CurValueCell->Name, ValueName, Length) == 0))
+         CmiComparePackedNames(ValueName,
+                               CurValueCell->Name,
+                               CurValueCell->NameSize,
+                               CurValueCell->Flags & REG_VALUE_NAME_PACKED))
         {
           *ValueCell = CurValueCell;
         {
           *ValueCell = CurValueCell;
-               if (VBOffset)
+          if (VBOffset)
             *VBOffset = ValueListCell->Values[i];
           //DPRINT("Found value %s\n", ValueName);
           break;
             *VBOffset = ValueListCell->Values[i];
           //DPRINT("Found value %s\n", ValueName);
           break;
@@ -1280,7 +1279,7 @@ CmiScanKeyForValue(IN PREGISTRY_HIVE RegistryHive,
     }
 
   CmiReleaseBlock(RegistryHive, ValueListCell);
     }
 
   CmiReleaseBlock(RegistryHive, ValueListCell);
-  
+
   return STATUS_SUCCESS;
 }
 
   return STATUS_SUCCESS;
 }
 
@@ -1293,7 +1292,7 @@ CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive,
 {
   PVALUE_LIST_CELL ValueListCell;
   PVALUE_CELL CurValueCell;
 {
   PVALUE_LIST_CELL ValueListCell;
   PVALUE_CELL CurValueCell;
+
   ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL);
 
   *ValueCell = NULL;
   ValueListCell = CmiGetBlock(RegistryHive, KeyCell->ValuesOffset, NULL);
 
   *ValueCell = NULL;
@@ -1321,7 +1320,7 @@ CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive,
 
   CmiReleaseBlock(RegistryHive, CurValueCell);
   CmiReleaseBlock(RegistryHive, ValueListCell);
 
   CmiReleaseBlock(RegistryHive, CurValueCell);
   CmiReleaseBlock(RegistryHive, ValueListCell);
-  
+
   return STATUS_SUCCESS;
 }
 
   return STATUS_SUCCESS;
 }
 
@@ -1329,7 +1328,7 @@ CmiGetValueFromKeyByIndex(IN PREGISTRY_HIVE RegistryHive,
 NTSTATUS
 CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
        IN PKEY_CELL KeyCell,
 NTSTATUS
 CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
        IN PKEY_CELL KeyCell,
-       IN PCHAR ValueNameBuf,
+       IN PUNICODE_STRING ValueName,
        OUT PVALUE_CELL *pValueCell,
        OUT BLOCK_OFFSET *pVBOffset)
 {
        OUT PVALUE_CELL *pValueCell,
        OUT BLOCK_OFFSET *pVBOffset)
 {
@@ -1343,7 +1342,7 @@ CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
   Status = CmiAllocateValueCell(RegistryHive,
                &NewValueCell,
                &VBOffset,
   Status = CmiAllocateValueCell(RegistryHive,
                &NewValueCell,
                &VBOffset,
-               ValueNameBuf);
+               ValueName);
   *pVBOffset = VBOffset;
 
   if (!NT_SUCCESS(Status))
   *pVBOffset = VBOffset;
 
   if (!NT_SUCCESS(Status))
@@ -1407,7 +1406,7 @@ CmiAddValueToKey(IN PREGISTRY_HIVE RegistryHive,
 NTSTATUS
 CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
                      IN PKEY_CELL KeyCell,
 NTSTATUS
 CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
                      IN PKEY_CELL KeyCell,
-                     IN PCHAR ValueName)
+                     IN PUNICODE_STRING ValueName)
 {
   PVALUE_LIST_CELL ValueListCell;
   PVALUE_CELL CurValueCell;
 {
   PVALUE_LIST_CELL ValueListCell;
   PVALUE_CELL CurValueCell;
@@ -1425,9 +1424,12 @@ CmiDeleteValueFromKey(IN PREGISTRY_HIVE RegistryHive,
   for (i = 0; i < KeyCell->NumberOfValues; i++)
     {
       CurValueCell = CmiGetBlock(RegistryHive, ValueListCell->Values[i], NULL);
   for (i = 0; i < KeyCell->NumberOfValues; i++)
     {
       CurValueCell = CmiGetBlock(RegistryHive, ValueListCell->Values[i], NULL);
+
       if ((CurValueCell != NULL) &&
       if ((CurValueCell != NULL) &&
-          (CurValueCell->NameSize == strlen(ValueName)) &&
-          (memcmp(CurValueCell->Name, ValueName, strlen(ValueName)) == 0))
+         CmiComparePackedNames(ValueName,
+                               CurValueCell->Name,
+                               CurValueCell->NameSize,
+                               CurValueCell->Flags & REG_VALUE_NAME_PACKED))
         {
           if ((KeyCell->NumberOfValues - 1) < i)
             {
         {
           if ((KeyCell->NumberOfValues - 1) < i)
             {
@@ -1539,20 +1541,25 @@ NTSTATUS
 CmiAllocateValueCell(PREGISTRY_HIVE RegistryHive,
   PVALUE_CELL *ValueCell,
   BLOCK_OFFSET *VBOffset,
 CmiAllocateValueCell(PREGISTRY_HIVE RegistryHive,
   PVALUE_CELL *ValueCell,
   BLOCK_OFFSET *VBOffset,
-  IN PCHAR ValueNameBuf)
+  IN PUNICODE_STRING ValueName)
 {
   PVALUE_CELL NewValueCell;
 {
   PVALUE_CELL NewValueCell;
-  ULONG NewValueSize;
   NTSTATUS Status;
   NTSTATUS Status;
+  BOOLEAN Packable;
+  ULONG NameSize;
+  ULONG i;
 
   Status = STATUS_SUCCESS;
 
 
   Status = STATUS_SUCCESS;
 
-  NewValueSize = sizeof(VALUE_CELL) + strlen(ValueNameBuf);
-  Status = CmiAllocateBlock(RegistryHive,
-    (PVOID*) &NewValueCell,
-    NewValueSize,
-    VBOffset);
+  NameSize = CmiGetPackedNameLength(ValueName,
+                                   &Packable);
+
+  DPRINT("ValueName->Length %lu  NameSize %lu\n", ValueName->Length, NameSize);
 
 
+  Status = CmiAllocateBlock(RegistryHive,
+                           (PVOID*) &NewValueCell,
+                           sizeof(VALUE_CELL) + NameSize,
+                           VBOffset);
   if ((NewValueCell == NULL) || (!NT_SUCCESS(Status)))
     {
       Status = STATUS_INSUFFICIENT_RESOURCES;
   if ((NewValueCell == NULL) || (!NT_SUCCESS(Status)))
     {
       Status = STATUS_INSUFFICIENT_RESOURCES;
@@ -1560,8 +1567,22 @@ CmiAllocateValueCell(PREGISTRY_HIVE RegistryHive,
   else
     {
       NewValueCell->Id = REG_VALUE_CELL_ID;
   else
     {
       NewValueCell->Id = REG_VALUE_CELL_ID;
-      NewValueCell->NameSize = strlen(ValueNameBuf);
-      memcpy(NewValueCell->Name, ValueNameBuf, strlen(ValueNameBuf));
+      NewValueCell->NameSize = NameSize;
+      if (Packable)
+       {
+         /* Pack the value name */
+         for (i = 0; i < NameSize; i++)
+           NewValueCell->Name[i] = (CHAR)ValueName->Buffer[i];
+         NewValueCell->Flags |= REG_VALUE_NAME_PACKED;
+       }
+      else
+        {
+         /* Copy the value name */
+         RtlCopyMemory(NewValueCell->Name,
+                       ValueName->Buffer,
+                       NameSize);
+         NewValueCell->Flags = 0;
+       }
       NewValueCell->DataType = 0;
       NewValueCell->DataSize = 0;
       NewValueCell->DataOffset = 0xffffffff;
       NewValueCell->DataType = 0;
       NewValueCell->DataSize = 0;
       NewValueCell->DataOffset = 0xffffffff;
@@ -1669,9 +1690,9 @@ CmiAddBin(PREGISTRY_HIVE RegistryHive,
 
 NTSTATUS
 CmiAllocateBlock(PREGISTRY_HIVE RegistryHive,
 
 NTSTATUS
 CmiAllocateBlock(PREGISTRY_HIVE RegistryHive,
-       PVOID *Block,
-       LONG BlockSize,
-  BLOCK_OFFSET * pBlockOffset)
+                PVOID *Block,
+                LONG BlockSize,
+                BLOCK_OFFSET * pBlockOffset)
 {
   PCELL_HEADER NewBlock;
   NTSTATUS Status;
 {
   PCELL_HEADER NewBlock;
   NTSTATUS Status;
@@ -1687,86 +1708,88 @@ CmiAllocateBlock(PREGISTRY_HIVE RegistryHive,
     {
       NewBlock = ExAllocatePool(NonPagedPool, BlockSize);
 
     {
       NewBlock = ExAllocatePool(NonPagedPool, BlockSize);
 
-           if (NewBlock == NULL)
-                   {
-                     Status = STATUS_INSUFFICIENT_RESOURCES;
-                   }
-           else
-                   {
-                     RtlZeroMemory(NewBlock, BlockSize);
-                     NewBlock->CellSize = BlockSize;
-                     CmiLockBlock(RegistryHive, NewBlock);
-                     *Block = NewBlock;
-                     if (pBlockOffset)
-            *pBlockOffset = (BLOCK_OFFSET) NewBlock;
-                   }
+      if (NewBlock == NULL)
+       {
+         Status = STATUS_INSUFFICIENT_RESOURCES;
+       }
+      else
+       {
+         RtlZeroMemory(NewBlock, BlockSize);
+         NewBlock->CellSize = BlockSize;
+         CmiLockBlock(RegistryHive, NewBlock);
+         *Block = NewBlock;
+         if (pBlockOffset)
+           *pBlockOffset = (BLOCK_OFFSET) NewBlock;
+       }
     }
   else
     {
     }
   else
     {
-           ULONG i;
+      ULONG i;
 
 
-           /* first search in free blocks */
-           NewBlock = NULL;
-           for (i = 0; i < RegistryHive->FreeListSize; i++)
-                   {
-                     if (RegistryHive->FreeList[i]->CellSize >= BlockSize)
-                             {
-              PVOID Temp;
-                                                       NewBlock = RegistryHive->FreeList[i];
-
-                                                       if (pBlockOffset)
-                                       *pBlockOffset = RegistryHive->FreeListOffset[i];
-
-                                /* Update time of heap */
-               Temp = CmiGetBlock(RegistryHive, RegistryHive->FreeListOffset[i], &pBin);
-
-                                if (Temp)
-                                  ZwQuerySystemTime((PTIME) &pBin->DateModified);
-
-                                if ((i + 1) < RegistryHive->FreeListSize)
-                 {
-                                    RtlMoveMemory(&RegistryHive->FreeList[i],
-                     &RegistryHive->FreeList[i + 1],
-                                            sizeof(RegistryHive->FreeList[0])
-                       * (RegistryHive->FreeListSize - i - 1));
-                                    RtlMoveMemory(&RegistryHive->FreeListOffset[i],
-                                            &RegistryHive->FreeListOffset[i + 1],
-                                            sizeof(RegistryHive->FreeListOffset[0])
-                       * (RegistryHive->FreeListSize - i - 1));
-                 }
-                                RegistryHive->FreeListSize--;
-                                break;
-                             }
-                   }
+      /* first search in free blocks */
+      NewBlock = NULL;
+      for (i = 0; i < RegistryHive->FreeListSize; i++)
+       {
+         if (RegistryHive->FreeList[i]->CellSize >= BlockSize)
+           {
+             PVOID Temp;
 
 
-           /* Need to extend hive file : */
-           if (NewBlock == NULL)
-                   {
-                     /* Add a new block */
-                     Status = CmiAddBin(RegistryHive, (PVOID *) &NewBlock , pBlockOffset);
-                   }
+             NewBlock = RegistryHive->FreeList[i];
+             if (pBlockOffset)
+               *pBlockOffset = RegistryHive->FreeListOffset[i];
 
 
-           if (NT_SUCCESS(Status))
-                   {
-                     *Block = NewBlock;
-
-                     /* Split the block in two parts */
-                     if (NewBlock->CellSize > BlockSize)
-                             {
-                                                       NewBlock = (PCELL_HEADER) ((ULONG_PTR) NewBlock+BlockSize);
-                                                       NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - BlockSize;
-                                                       CmiAddFree(RegistryHive, NewBlock, *pBlockOffset + BlockSize);
-                             }
-                     else if (NewBlock->CellSize < BlockSize)
-            {
-                               return STATUS_UNSUCCESSFUL;
-            }
-                     RtlZeroMemory(*Block, BlockSize);
-                     ((PCELL_HEADER) (*Block))->CellSize = -BlockSize;
-                     CmiLockBlock(RegistryHive, *Block);
-                   }
-         }
-  return  Status;
+             /* Update time of heap */
+             Temp = CmiGetBlock(RegistryHive, RegistryHive->FreeListOffset[i], &pBin);
+
+             if (Temp)
+               ZwQuerySystemTime((PTIME) &pBin->DateModified);
+
+             if ((i + 1) < RegistryHive->FreeListSize)
+               {
+                 RtlMoveMemory(&RegistryHive->FreeList[i],
+                               &RegistryHive->FreeList[i + 1],
+                               sizeof(RegistryHive->FreeList[0])
+                                 * (RegistryHive->FreeListSize - i - 1));
+                 RtlMoveMemory(&RegistryHive->FreeListOffset[i],
+                               &RegistryHive->FreeListOffset[i + 1],
+                               sizeof(RegistryHive->FreeListOffset[0])
+                                 * (RegistryHive->FreeListSize - i - 1));
+               }
+             RegistryHive->FreeListSize--;
+             break;
+           }
+       }
+
+      /* Need to extend hive file : */
+      if (NewBlock == NULL)
+       {
+         /* Add a new block */
+         Status = CmiAddBin(RegistryHive, (PVOID *) &NewBlock , pBlockOffset);
+       }
+
+      if (NT_SUCCESS(Status))
+       {
+         *Block = NewBlock;
+
+         /* Split the block in two parts */
+         if (NewBlock->CellSize > BlockSize)
+           {
+             NewBlock = (PCELL_HEADER) ((ULONG_PTR) NewBlock+BlockSize);
+             NewBlock->CellSize = ((PCELL_HEADER) (*Block))->CellSize - BlockSize;
+             CmiAddFree(RegistryHive, NewBlock, *pBlockOffset + BlockSize);
+           }
+         else if (NewBlock->CellSize < BlockSize)
+           {
+             return(STATUS_UNSUCCESSFUL);
+           }
+
+         RtlZeroMemory(*Block, BlockSize);
+         ((PCELL_HEADER) (*Block))->CellSize = -BlockSize;
+         CmiLockBlock(RegistryHive, *Block);
+       }
+    }
+
+  return(Status);
 }
 
 
 }
 
 
@@ -1781,27 +1804,27 @@ CmiDestroyBlock(PREGISTRY_HIVE RegistryHive,
   Status = STATUS_SUCCESS;
 
   if (IsVolatileHive(RegistryHive))
   Status = STATUS_SUCCESS;
 
   if (IsVolatileHive(RegistryHive))
-         {
-           CmiReleaseBlock(RegistryHive, Block);
-           ExFreePool(Block);
-         }
+    {
+      CmiReleaseBlock(RegistryHive, Block);
+      ExFreePool(Block);
+    }
   else
   else
-         {
-           PCELL_HEADER pFree = Block;
+    {
+      PCELL_HEADER pFree = Block;
 
 
-           if (pFree->CellSize < 0)
-             pFree->CellSize = -pFree->CellSize;
+      if (pFree->CellSize < 0)
+        pFree->CellSize = -pFree->CellSize;
 
 
-           CmiAddFree(RegistryHive, Block, Offset);
-           CmiReleaseBlock(RegistryHive, Block);
+      CmiAddFree(RegistryHive, Block, Offset);
+      CmiReleaseBlock(RegistryHive, Block);
 
 
-           /* Update time of heap */
-           if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, Offset,&pBin))
-             ZwQuerySystemTime((PTIME) &pBin->DateModified);
+      /* Update time of heap */
+      if (IsPermanentHive(RegistryHive) && CmiGetBlock(RegistryHive, Offset,&pBin))
+       ZwQuerySystemTime((PTIME) &pBin->DateModified);
 
 
-             /* FIXME: Set first dword to block_offset of another free block ? */
-             /* FIXME: Concatenate with previous and next block if free */
-         }
+      /* FIXME: Set first dword to block_offset of another free block ? */
+      /* FIXME: Concatenate with previous and next block if free */
+    }
 
   return Status;
 }
 
   return Status;
 }
@@ -1825,29 +1848,29 @@ CmiAddFree(PREGISTRY_HIVE RegistryHive,
     FreeBlock, FreeOffset);
 DPRINT("\n");
   if ((RegistryHive->FreeListSize + 1) > RegistryHive->FreeListMax)
     FreeBlock, FreeOffset);
 DPRINT("\n");
   if ((RegistryHive->FreeListSize + 1) > RegistryHive->FreeListMax)
-         {
+    {
 DPRINT("\n");
 DPRINT("\n");
-           tmpList = ExAllocatePool(PagedPool,
+      tmpList = ExAllocatePool(PagedPool,
                          sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax + 32));
 DPRINT("\n");
 
                          sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax + 32));
 DPRINT("\n");
 
-           if (tmpList == NULL)
-        return STATUS_INSUFFICIENT_RESOURCES;
+      if (tmpList == NULL)
+       return STATUS_INSUFFICIENT_RESOURCES;
 DPRINT("\n");
 
 DPRINT("\n");
 
-           tmpListOffset = ExAllocatePool(PagedPool,
+      tmpListOffset = ExAllocatePool(PagedPool,
                          sizeof(BLOCK_OFFSET *) * (RegistryHive->FreeListMax + 32));
 DPRINT("\n");
 
                          sizeof(BLOCK_OFFSET *) * (RegistryHive->FreeListMax + 32));
 DPRINT("\n");
 
-           if (tmpListOffset == NULL)
-        {
-          ExFreePool(tmpList);
-          return STATUS_INSUFFICIENT_RESOURCES;
-        }
+      if (tmpListOffset == NULL)
+       {
+         ExFreePool(tmpList);
+         return STATUS_INSUFFICIENT_RESOURCES;
+       }
 DPRINT("\n");
 
 DPRINT("\n");
 
-           if (RegistryHive->FreeListMax)
-           {
+      if (RegistryHive->FreeListMax)
+       {
 DPRINT("\n");
         RtlMoveMemory(tmpList, RegistryHive->FreeList,
           sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax));
 DPRINT("\n");
         RtlMoveMemory(tmpList, RegistryHive->FreeList,
           sizeof(PCELL_HEADER) * (RegistryHive->FreeListMax));
@@ -1986,3 +2009,80 @@ CmiReleaseBlock(PREGISTRY_HIVE RegistryHive,
       /* FIXME: Implement */
     }
 }
       /* FIXME: Implement */
     }
 }
+
+
+ULONG
+CmiGetPackedNameLength(IN PUNICODE_STRING Name,
+                      OUT PBOOLEAN Packable)
+{
+  ULONG i;
+
+  if (Packable != NULL)
+    *Packable = TRUE;
+
+  for (i = 0; i < Name->Length; i++)
+    {
+      if (Name->Buffer[i] > 0xFF)
+       {
+         if (Packable != NULL)
+           *Packable = FALSE;
+         return(Name->Length);
+       }
+    }
+
+  return(Name->Length / sizeof(WCHAR));
+}
+
+
+BOOLEAN
+CmiComparePackedNames(IN PUNICODE_STRING Name,
+                     IN PCHAR NameBuffer,
+                     IN USHORT NameBufferSize,
+                     IN BOOLEAN NamePacked)
+{
+  PWCHAR UNameBuffer;
+  ULONG i;
+
+  if (NamePacked)
+    {
+      if (Name->Length != NameBufferSize * sizeof(WCHAR))
+       {
+       return(FALSE);
+       }
+
+      for (i = 0; i < Name->Length / sizeof(WCHAR); i++)
+       {
+         if (RtlUpcaseUnicodeChar(Name->Buffer[i]) != RtlUpcaseUnicodeChar((WCHAR)NameBuffer[i]))
+           return(FALSE);
+       }
+    }
+  else
+    {
+      if (Name->Length != NameBufferSize)
+       return(FALSE);
+
+      UNameBuffer = (PWCHAR)NameBuffer;
+
+      for (i = 0; i < Name->Length / sizeof(WCHAR); i++)
+       {
+         if (RtlUpcaseUnicodeChar(Name->Buffer[i]) != RtlUpcaseUnicodeChar(UNameBuffer[i]))
+           return(FALSE);
+       }
+    }
+
+  return(TRUE);
+}
+
+
+VOID
+CmiCopyPackedName(PWCHAR NameBuffer,
+                 PCHAR PackedNameBuffer,
+                 ULONG PackedNameSize)
+{
+  ULONG i;
+
+  for (i = 0; i < PackedNameSize; i++)
+    NameBuffer[i] = (WCHAR)PackedNameBuffer[i];
+}
+
+/* EOF */
index 2d002d1..dbc0399 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: registry.c,v 1.78 2002/11/26 15:31:41 ekohl Exp $
+/* $Id: registry.c,v 1.79 2002/11/30 14:46:27 ekohl Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -20,6 +20,7 @@
 #include <string.h>
 #include <internal/pool.h>
 #include <internal/registry.h>
 #include <string.h>
 #include <internal/pool.h>
 #include <internal/registry.h>
+#include <reactos/bugcodes.h>
 
 #define NDEBUG
 #include <internal/debug.h>
 
 #define NDEBUG
 #include <internal/debug.h>
@@ -204,7 +205,7 @@ CmiCheckByName(BOOLEAN Verbose,
   wcscpy(KeyPathBuffer, L"\\Registry\\");
   wcscat(KeyPathBuffer, KeyName);
 
   wcscpy(KeyPathBuffer, L"\\Registry\\");
   wcscat(KeyPathBuffer, KeyName);
 
-       RtlInitUnicodeString(&KeyPath, KeyPathBuffer);
+  RtlInitUnicodeString(&KeyPath, KeyPathBuffer);
 
   InitializeObjectAttributes(&ObjectAttributes,
                &KeyPath,
 
   InitializeObjectAttributes(&ObjectAttributes,
                &KeyPath,
@@ -219,11 +220,11 @@ CmiCheckByName(BOOLEAN Verbose,
   if (CHECKED)
     {
       if (!NT_SUCCESS(Status))
   if (CHECKED)
     {
       if (!NT_SUCCESS(Status))
-                               {
+       {
           DbgPrint("KeyPath %wZ  Status: %.08x", KeyPath, Status);
           DbgPrint("KeyPath %S  Status: %.08x", KeyPath.Buffer, Status);
           assert(NT_SUCCESS(Status));
           DbgPrint("KeyPath %wZ  Status: %.08x", KeyPath, Status);
           DbgPrint("KeyPath %S  Status: %.08x", KeyPath.Buffer, Status);
           assert(NT_SUCCESS(Status));
-                               }
+       }
     }
 
   CmiCheckKey(Verbose, Key);
     }
 
   CmiCheckKey(Verbose, Key);
@@ -484,6 +485,7 @@ CmInit2(PCHAR CommandLine)
 {
   PCHAR p1, p2;
   ULONG PiceStart;
 {
   PCHAR p1, p2;
   ULONG PiceStart;
+  NTSTATUS Status;
 
   /* FIXME: Store system start options */
 
 
   /* FIXME: Store system start options */
 
@@ -515,12 +517,17 @@ CmInit2(PCHAR CommandLine)
       p1 = p2;
     }
 #ifndef WIN32_REGDBG
       p1 = p2;
     }
 #ifndef WIN32_REGDBG
-  RtlWriteRegistryValue(RTL_REGISTRY_SERVICES,
-                       L"\\Pice",
-                       L"Start",
-                       REG_DWORD,
-                       &PiceStart,
-                       sizeof(ULONG));
+  Status = RtlWriteRegistryValue(RTL_REGISTRY_SERVICES,
+                                L"\\Pice",
+                                L"Start",
+                                REG_DWORD,
+                                &PiceStart,
+                                sizeof(ULONG));
+  if (!NT_SUCCESS(Status))
+    {
+
+      KeBugCheck(CONFIG_INITIALIZATION_FAILED);
+    }
 #endif
 }
 
 #endif
 }
 
@@ -602,12 +609,12 @@ CmiCreateCurrentControlSetLink(VOID)
 
   RtlInitUnicodeStringFromLiteral(&LinkValue,
                       L"SymbolicLinkValue");
 
   RtlInitUnicodeStringFromLiteral(&LinkValue,
                       L"SymbolicLinkValue");
-  Status=NtSetValueKey(KeyHandle,
-                      &LinkValue,
-                      0,
-                      REG_LINK,
-                      (PVOID)TargetNameBuffer,
-                      TargetNameLength);
+  Status = NtSetValueKey(KeyHandle,
+                        &LinkValue,
+                        0,
+                        REG_LINK,
+                        (PVOID)TargetNameBuffer,
+                        TargetNameLength);
   if (!NT_SUCCESS(Status))
     {
       DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
   if (!NT_SUCCESS(Status))
     {
       DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
index cb20844..5a73f31 100644 (file)
@@ -168,6 +168,8 @@ CmiObjectParse(PVOID ParsedObject,
       if ((FoundObject->KeyCell->Type == REG_LINK_KEY_CELL_TYPE) &&
          !((Attributes & OBJ_OPENLINK) && (end == NULL)))
        {
       if ((FoundObject->KeyCell->Type == REG_LINK_KEY_CELL_TYPE) &&
          !((Attributes & OBJ_OPENLINK) && (end == NULL)))
        {
+         DPRINT("Found link\n");
+
          RtlInitUnicodeString(&LinkPath, NULL);
          Status = CmiGetLinkTarget(FoundObject->RegistryHive,
                                    FoundObject->KeyCell,
          RtlInitUnicodeString(&LinkPath, NULL);
          Status = CmiGetLinkTarget(FoundObject->RegistryHive,
                                    FoundObject->KeyCell,
@@ -436,18 +438,22 @@ CmiGetLinkTarget(PREGISTRY_HIVE RegistryHive,
                 PKEY_CELL KeyCell,
                 PUNICODE_STRING TargetPath)
 {
                 PKEY_CELL KeyCell,
                 PUNICODE_STRING TargetPath)
 {
+  UNICODE_STRING LinkName = UNICODE_STRING_INITIALIZER(L"SymbolicLinkValue");
   PVALUE_CELL ValueCell;
   PDATA_CELL DataCell;
   NTSTATUS Status;
 
   PVALUE_CELL ValueCell;
   PDATA_CELL DataCell;
   NTSTATUS Status;
 
+  DPRINT("CmiGetLinkTarget() called\n");
+
   /* Get Value block of interest */
   Status = CmiScanKeyForValue(RegistryHive,
                              KeyCell,
   /* Get Value block of interest */
   Status = CmiScanKeyForValue(RegistryHive,
                              KeyCell,
-                             "SymbolicLinkValue",
+                             &LinkName,
                              &ValueCell,
                              NULL);
   if (!NT_SUCCESS(Status))
     {
                              &ValueCell,
                              NULL);
   if (!NT_SUCCESS(Status))
     {
+      DPRINT1("CmiScanKeyForValue() failed (Status %lx)\n", Status);
       return(Status);
     }
 
       return(Status);
     }
 
@@ -485,6 +491,8 @@ CmiGetLinkTarget(PREGISTRY_HIVE RegistryHive,
       TargetPath->Buffer[TargetPath->Length / sizeof(WCHAR)] = 0;
     }
 
       TargetPath->Buffer[TargetPath->Length / sizeof(WCHAR)] = 0;
     }
 
+  DPRINT("TargetPath '%wZ'\n", TargetPath);
+
   return(STATUS_SUCCESS);
 }
 
   return(STATUS_SUCCESS);
 }
 
index 9678f62..7e36694 100644 (file)
@@ -6,6 +6,8 @@
  * UPDATE HISTORY:
 */
 
  * UPDATE HISTORY:
 */
 
+/* INCLUDES *****************************************************************/
+
 #ifdef WIN32_REGDBG
 #include "cm_win32.h"
 #else
 #ifdef WIN32_REGDBG
 #include "cm_win32.h"
 #else
@@ -23,6 +25,9 @@
 #include "cm.h"
 #endif
 
 #include "cm.h"
 #endif
 
+
+/* FUNCTIONS ****************************************************************/
+
 NTSTATUS STDCALL
 RtlCheckRegistryKey(IN ULONG RelativeTo,
                    IN PWSTR Path)
 NTSTATUS STDCALL
 RtlCheckRegistryKey(IN ULONG RelativeTo,
                    IN PWSTR Path)