NTSTATUS STDCALL
NtCreateKey(OUT PHANDLE KeyHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN ULONG TitleIndex,
- IN PUNICODE_STRING Class,
- IN ULONG CreateOptions,
- OUT PULONG Disposition)
+ IN ACCESS_MASK DesiredAccess,
+ IN POBJECT_ATTRIBUTES ObjectAttributes,
+ IN ULONG TitleIndex,
+ IN PUNICODE_STRING Class,
+ IN ULONG CreateOptions,
+ OUT PULONG Disposition)
{
UNICODE_STRING RemainingPath;
PKEY_OBJECT KeyObject;
PWSTR End;
DPRINT("NtCreateKey (Name %wZ KeyHandle %x Root %x)\n",
- ObjectAttributes->ObjectName,
- KeyHandle,
- ObjectAttributes->RootDirectory);
+ ObjectAttributes->ObjectName,
+ KeyHandle,
+ ObjectAttributes->RootDirectory);
/* FIXME: check for standard handle prefix and adjust objectAttributes accordingly */
- Status = ObFindObject(ObjectAttributes, &Object, &RemainingPath, CmiKeyType);
-
+ Status = ObFindObject(ObjectAttributes,
+ &Object,
+ &RemainingPath,
+ CmiKeyType);
if (!NT_SUCCESS(Status))
{
- return Status;
+ return(Status);
}
DPRINT("RemainingPath %wZ\n", &RemainingPath);
if (((PKEY_OBJECT) Object)->Flags & KO_MARKED_FOR_DELETE)
{
ObDereferenceObject(Object);
- return STATUS_UNSUCCESSFUL;
+ return(STATUS_UNSUCCESSFUL);
}
if (Disposition)
(PVOID*)&KeyObject);
if (!NT_SUCCESS(Status))
- return(Status);
+ {
+ return(Status);
+ }
KeyObject->ParentKey = Object;
KeyObject->NumberOfSubKeys = 0;
KeyObject->SizeOfSubKeys = 0;
KeyObject->SubKeys = NULL;
-// KeAcquireSpinLock(&Key->RegistryHive->RegLock, &OldIrql);
+
+ /* Acquire hive lock */
+ ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE);
+
/* add key to subkeys of parent if needed */
Status = CmiAddSubKey(KeyObject->RegistryHive,
KeyObject->ParentKey,
if (!NT_SUCCESS(Status))
{
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
ObDereferenceObject(Object);
return STATUS_UNSUCCESSFUL;
}
CmiAddKeyToList(KeyObject->ParentKey, KeyObject);
-// KeReleaseSpinLock(&KeyObject->RegistryHive->RegLock, OldIrql);
+
+ /* Release hive lock */
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
ObDereferenceObject(Object);
return Status;
}
+ /* Acquire hive lock */
+ ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE);
+
VERIFY_KEY_OBJECT(KeyObject);
/* Set the marked for delete bit in the key object */
/* FIXME: I think that ObDeleteHandle should dereference the object */
ObDereferenceObject(KeyObject);
+ /* Release hive lock */
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
+
return STATUS_SUCCESS;
}
PDATA_CELL pClassData;
DPRINT("KH %x I %d KIC %x KI %x L %d RL %x\n",
- KeyHandle,
- Index,
- KeyInformationClass,
- KeyInformation,
- Length,
- ResultLength);
-
+ KeyHandle,
+ Index,
+ KeyInformationClass,
+ KeyInformation,
+ Length,
+ ResultLength);
+
/* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle,
KEY_ENUMERATE_SUB_KEYS,
if (!NT_SUCCESS(Status))
{
DPRINT("ObReferenceObjectByHandle() failed with status %x\n", Status);
- return Status;
+ return(Status);
}
+ /* Acquire hive lock */
+ ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE);
+
VERIFY_KEY_OBJECT(KeyObject);
/* Get pointer to KeyCell */
KeyCell = KeyObject->KeyCell;
RegistryHive = KeyObject->RegistryHive;
-
+
/* Get pointer to SubKey */
if (Index >= KeyCell->NumberOfSubKeys)
- {
- if (RegistryHive == CmiVolatileHive)
- {
- ObDereferenceObject (KeyObject);
- DPRINT("No more volatile entries\n");
- return STATUS_NO_MORE_ENTRIES;
- }
- else
- {
- ULONG i;
- PKEY_OBJECT CurKey = NULL;
-
- /* Search volatile keys */
- for (i = 0; i < KeyObject->NumberOfSubKeys; i++)
- {
- CurKey = KeyObject->SubKeys[i];
- if (CurKey->RegistryHive == CmiVolatileHive)
- {
- if (Index-- == KeyObject->NumberOfSubKeys)
- break;
- }
- }
- if(Index >= KeyCell->NumberOfSubKeys)
- {
- ObDereferenceObject (KeyObject);
- DPRINT("No more non-volatile entries\n");
- return STATUS_NO_MORE_ENTRIES;
- }
- SubKeyCell = CurKey->KeyCell;
- }
- }
+ {
+ if (RegistryHive == CmiVolatileHive)
+ {
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
+ ObDereferenceObject(KeyObject);
+ DPRINT("No more volatile entries\n");
+ return(STATUS_NO_MORE_ENTRIES);
+ }
+ else
+ {
+ ULONG i;
+ PKEY_OBJECT CurKey = NULL;
+
+ /* Search volatile keys */
+ for (i = 0; i < KeyObject->NumberOfSubKeys; i++)
+ {
+ CurKey = KeyObject->SubKeys[i];
+ if (CurKey->RegistryHive == CmiVolatileHive)
+ {
+ if (Index-- == KeyObject->NumberOfSubKeys)
+ break;
+ }
+ }
+ if (Index >= KeyCell->NumberOfSubKeys)
+ {
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
+ ObDereferenceObject(KeyObject);
+ DPRINT("No more non-volatile entries\n");
+ return(STATUS_NO_MORE_ENTRIES);
+ }
+ SubKeyCell = CurKey->KeyCell;
+ }
+ }
else
- {
- HashTableBlock = CmiGetBlock(RegistryHive, KeyCell->HashTableOffset, NULL);
- SubKeyCell = CmiGetKeyFromHashByIndex(RegistryHive,
- HashTableBlock,
- Index);
- }
+ {
+ HashTableBlock = CmiGetBlock(RegistryHive, KeyCell->HashTableOffset, NULL);
+ SubKeyCell = CmiGetKeyFromHashByIndex(RegistryHive,
+ HashTableBlock,
+ Index);
+ }
if (SubKeyCell == NULL)
- {
- ObDereferenceObject (KeyObject);
- DPRINT("No more entries\n");
- return STATUS_NO_MORE_ENTRIES;
- }
+ {
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
+ ObDereferenceObject(KeyObject);
+ DPRINT("No more entries\n");
+ return(STATUS_NO_MORE_ENTRIES);
+ }
Status = STATUS_SUCCESS;
switch (KeyInformationClass)
break;
}
CmiReleaseBlock(RegistryHive, SubKeyCell);
- ObDereferenceObject (KeyObject);
+
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
+ ObDereferenceObject(KeyObject);
DPRINT("Returning status %x\n", Status);
- return Status;
+ return(Status);
}
PKEY_VALUE_FULL_INFORMATION ValueFullInformation;
DPRINT("KH %x I %d KVIC %x KVI %x L %d RL %x\n",
- KeyHandle,
- Index,
- KeyValueInformationClass,
- KeyValueInformation,
- Length,
- ResultLength);
+ KeyHandle,
+ Index,
+ KeyValueInformationClass,
+ KeyValueInformation,
+ Length,
+ ResultLength);
/* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle,
return Status;
}
+ /* Acquire hive lock */
+ ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE);
+
VERIFY_KEY_OBJECT(KeyObject);
/* Get pointer to KeyCell */
KeyCell = KeyObject->KeyCell;
RegistryHive = KeyObject->RegistryHive;
-
+
/* Get Value block of interest */
Status = CmiGetValueFromKeyByIndex(RegistryHive,
KeyCell,
if (!NT_SUCCESS(Status))
{
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
return Status;
}
- else if (ValueCell != NULL)
+
+ if (ValueCell != NULL)
{
switch (KeyValueInformationClass)
{
{
Status = STATUS_UNSUCCESSFUL;
}
+
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
return Status;
NTSTATUS STDCALL
NtFlushKey(IN HANDLE KeyHandle)
{
- NTSTATUS Status;
- PKEY_OBJECT KeyObject;
- PREGISTRY_HIVE RegistryHive;
- WCHAR LogName[MAX_PATH];
- UNICODE_STRING TmpFileName;
- HANDLE FileHandle;
- // HANDLE FileHandleLog;
- OBJECT_ATTRIBUTES ObjectAttributes;
- // KIRQL OldIrql;
- LARGE_INTEGER fileOffset;
- DWORD * pEntDword;
- ULONG i;
+ NTSTATUS Status;
+ PKEY_OBJECT KeyObject;
+ PREGISTRY_HIVE RegistryHive;
+ WCHAR LogName[MAX_PATH];
+ UNICODE_STRING TmpFileName;
+ HANDLE FileHandle;
+// HANDLE FileHandleLog;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ LARGE_INTEGER fileOffset;
+ DWORD * pEntDword;
+ ULONG i;
DPRINT("KeyHandle %x\n", KeyHandle);
- /* Verify that the handle is valid and is a registry key */
- Status = ObReferenceObjectByHandle(KeyHandle,
+ /* Verify that the handle is valid and is a registry key */
+ Status = ObReferenceObjectByHandle(KeyHandle,
KEY_QUERY_VALUE,
CmiKeyType,
UserMode,
return Status;
}
+ /* Acquire hive lock */
+ ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE);
+
VERIFY_KEY_OBJECT(KeyObject);
RegistryHive = KeyObject->RegistryHive;
-// KeAcquireSpinLock(&RegistryHive->RegLock, &OldIrql);
+
/* Then write changed blocks in .log */
wcscpy(LogName,RegistryHive->Filename.Buffer);
wcscat(LogName,L".log");
RtlInitUnicodeString (&TmpFileName, LogName);
InitializeObjectAttributes(&ObjectAttributes,
- &TmpFileName,
- 0,
- NULL,
- NULL);
+ &TmpFileName,
+ 0,
+ NULL,
+ NULL);
/* BEGIN FIXME : actually (26 November 200) vfatfs.sys can't create new files
so we can't create log file
NULL,
0,
FILE_SYNCHRONOUS_IO_NONALERT);
-
if (!NT_SUCCESS(Status))
{
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
return Status;
}
RegistryHive->HiveHeader->Version++;
- Status = ZwWriteFile(FileHandle,
- 0,
- 0,
- 0,
- 0,
- RegistryHive->HiveHeader,
- sizeof(HIVE_HEADER),
- 0,
- 0);
-
+ Status = ZwWriteFile(FileHandle,
+ 0,
+ 0,
+ 0,
+ 0,
+ RegistryHive->HiveHeader,
+ sizeof(HIVE_HEADER),
+ 0,
+ 0);
if (!NT_SUCCESS(Status))
{
ZwClose(FileHandle);
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
return Status;
}
/* Update changed blocks in file */
fileOffset.u.HighPart = 0;
for (i = 0; i < RegistryHive->BlockListSize ; i++)
- {
- if (RegistryHive->BlockList[i]->DateModified.dwHighDateTime
+ {
+ if (RegistryHive->BlockList[i]->DateModified.dwHighDateTime
> RegistryHive->HiveHeader->DateModified.dwHighDateTime
- || (RegistryHive->BlockList[i]->DateModified.dwHighDateTime
+ || (RegistryHive->BlockList[i]->DateModified.dwHighDateTime
== RegistryHive->HiveHeader->DateModified.dwHighDateTime
- && RegistryHive->BlockList[i]->DateModified.dwLowDateTime
- > RegistryHive->HiveHeader->DateModified.dwLowDateTime
- )
- )
+ && RegistryHive->BlockList[i]->DateModified.dwLowDateTime
+ > RegistryHive->HiveHeader->DateModified.dwLowDateTime))
+ {
+ fileOffset.u.LowPart = RegistryHive->BlockList[i]->BlockOffset+4096;
+ Status = NtWriteFile(FileHandle,
+ 0,
+ 0,
+ 0,
+ 0,
+ RegistryHive->BlockList[i],
+ RegistryHive->BlockList[i]->BlockSize,
+ &fileOffset,
+ 0);
+ if (!NT_SUCCESS(Status))
{
- fileOffset.u.LowPart = RegistryHive->BlockList[i]->BlockOffset+4096;
- Status = NtWriteFile(FileHandle,
- 0,
- 0,
- 0,
- 0,
- RegistryHive->BlockList[i],
- RegistryHive->BlockList[i]->BlockSize ,
- &fileOffset,
- 0);
-
- if (!NT_SUCCESS(Status))
- {
- ZwClose(FileHandle);
- ObDereferenceObject(KeyObject);
- return Status;
- }
+ ZwClose(FileHandle);
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
+ ObDereferenceObject(KeyObject);
+ return(Status);
}
- }
+ }
+ }
/* Change version in header */
RegistryHive->HiveHeader->VersionOld = RegistryHive->HiveHeader->Version;
/* Write new header */
fileOffset.u.LowPart = 0;
- Status = ZwWriteFile(FileHandle,
- 0,
- 0,
- 0,
- 0,
- RegistryHive->HiveHeader,
- sizeof(HIVE_HEADER),
- &fileOffset,
- 0);
+ Status = ZwWriteFile(FileHandle,
+ 0,
+ 0,
+ 0,
+ 0,
+ RegistryHive->HiveHeader,
+ sizeof(HIVE_HEADER),
+ &fileOffset,
+ 0);
if (!NT_SUCCESS(Status))
{
ZwClose(FileHandle);
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
return Status;
}
ZwClose(FileHandle);
-// KeReleaseSpinLock(&RegistryHive->RegLock, OldIrql);
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
return STATUS_SUCCESS;
}
NTSTATUS Status;
DPRINT("KH %x KIC %x KI %x L %d RL %x\n",
- KeyHandle,
- KeyInformationClass,
- KeyInformation,
- Length,
- ResultLength);
-
+ KeyHandle,
+ KeyInformationClass,
+ KeyInformation,
+ Length,
+ ResultLength);
+
/* Verify that the handle is valid and is a registry key */
Status = ObReferenceObjectByHandle(KeyHandle,
KEY_READ,
UserMode,
(PVOID *) &KeyObject,
NULL);
-
if (!NT_SUCCESS(Status))
{
return Status;
}
+ /* Acquire hive lock */
+ ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE);
+
VERIFY_KEY_OBJECT(KeyObject);
/* Get pointer to KeyCell */
break;
}
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
return Status;
}
+
NTSTATUS STDCALL
NtQueryValueKey(IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName,
return Status;
}
+ /* Acquire hive lock */
+ ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE);
+
VERIFY_KEY_OBJECT(KeyObject);
/* Get pointer to KeyCell */
KeyCell = KeyObject->KeyCell;
RegistryHive = KeyObject->RegistryHive;
- /* Get Value block of interest */
- Status = CmiScanKeyForValue(RegistryHive,
- KeyCell,
- ValueName2,
- &ValueCell,NULL);
+ /* Get Value block of interest */
+ Status = CmiScanKeyForValue(RegistryHive,
+ KeyCell,
+ ValueName2,
+ &ValueCell,
+ NULL);
if (!NT_SUCCESS(Status))
{
DPRINT("CmiScanKeyForValue() failed with status %x\n", Status);
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
- return Status;
+ return(Status);
}
else if (ValueCell != NULL)
{
mbstowcs(ValueFullInformation->Name, ValueCell->Name,ValueCell->NameSize*2);
ValueFullInformation->Name[ValueCell->NameSize] = 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
- {
- RtlCopyMemory((PCHAR) ValueFullInformation
- + ValueFullInformation->DataOffset,
- &ValueCell->DataOffset,
- ValueCell->DataSize & LONG_MAX);
- }
+ {
+ RtlCopyMemory((PCHAR) ValueFullInformation
+ + ValueFullInformation->DataOffset,
+ &ValueCell->DataOffset,
+ ValueCell->DataSize & LONG_MAX);
+ }
}
break;
}
Status = STATUS_OBJECT_NAME_NOT_FOUND;
}
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
-
+
return Status;
}
PDATA_CELL NewDataCell;
PHBIN pBin;
ULONG DesiredAccess;
-// KIRQL OldIrql;
DPRINT("KeyHandle %x ValueName %S Type %d\n",
KeyHandle, ValueName? ValueName->Buffer : NULL, Type);
if (!NT_SUCCESS(Status))
return(Status);
+ /* Acquire hive lock */
+ ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE);
+
VERIFY_KEY_OBJECT(KeyObject);
/* Get pointer to key cell */
{
DPRINT1("Value not found. Status 0x%X\n", Status);
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
return(Status);
}
-// KeAcquireSpinLock(&RegistryHive->RegLock, &OldIrql);
-
if (ValueCell == NULL)
{
Status = CmiAddValueToKey(RegistryHive,
{
DPRINT1("Cannot add value. Status 0x%X\n", Status);
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
return(Status);
}
}
}
-// KeReleaseSpinLock(&RegistryHive->RegLock, OldIrql);
-
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
ObDereferenceObject(KeyObject);
DPRINT("Return Status 0x%X\n", Status);
NTSTATUS STDCALL
NtDeleteValueKey(IN HANDLE KeyHandle,
- IN PUNICODE_STRING ValueName)
+ IN PUNICODE_STRING ValueName)
{
- PREGISTRY_HIVE RegistryHive;
CHAR ValueName2[MAX_PATH];
PKEY_OBJECT KeyObject;
- PKEY_CELL KeyCell;
NTSTATUS Status;
-// KIRQL OldIrql;
wcstombs(ValueName2, ValueName->Buffer, ValueName->Length >> 1);
ValueName2[ValueName->Length>>1] = 0;
UserMode,
(PVOID *)&KeyObject,
NULL);
-
if (!NT_SUCCESS(Status))
{
return Status;
}
+ /* Acquire hive lock */
+ ExAcquireResourceExclusiveLite(&KeyObject->RegistryHive->HiveResource, TRUE);
+
VERIFY_KEY_OBJECT(KeyObject);
- /* Get pointer to KeyCell */
- KeyCell = KeyObject->KeyCell;
- RegistryHive = KeyObject->RegistryHive;
-// KeAcquireSpinLock(&RegistryHive->RegLock, &OldIrql);
- Status = CmiDeleteValueFromKey(RegistryHive, KeyCell, ValueName2);
-// KeReleaseSpinLock(&RegistryHive->RegLock, OldIrql);
+ Status = CmiDeleteValueFromKey(KeyObject->RegistryHive,
+ KeyObject->KeyCell,
+ ValueName2);
+
+ /* Release hive lock */
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
+
ObDereferenceObject(KeyObject);
return Status;
NTSTATUS STDCALL
NtQueryMultipleValueKey(IN HANDLE KeyHandle,
- IN OUT PKEY_VALUE_ENTRY ValueList,
- IN ULONG NumberOfValues,
- OUT PVOID Buffer,
- IN OUT PULONG Length,
- OUT PULONG ReturnLength)
+ IN OUT PKEY_VALUE_ENTRY ValueList,
+ IN ULONG NumberOfValues,
+ OUT PVOID Buffer,
+ IN OUT PULONG Length,
+ OUT PULONG ReturnLength)
{
PREGISTRY_HIVE RegistryHive;
UCHAR ValueName[MAX_PATH];
return(Status);
}
+ /* Acquire hive lock */
+ ExAcquireResourceSharedLite(&KeyObject->RegistryHive->HiveResource, TRUE);
+
VERIFY_KEY_OBJECT(KeyObject);
/* Get pointer to KeyCell */
*ReturnLength = BufferLength;
+ /* Release hive lock */
+ ExReleaseResourceLite(&KeyObject->RegistryHive->HiveResource);
+
ObDereferenceObject(KeyObject);
DPRINT("Return Status 0x%X\n", Status);
- return Status;
+ return(Status);
}
ULONG CreateDisposition;
IO_STATUS_BLOCK IoSB;
HANDLE FileHandle;
- DWORD FreeOffset;
+ ULONG FreeOffset;
NTSTATUS Status;
- //BOOLEAN Success;
PHBIN tmpBin;
ULONG i, j;
- IO_STATUS_BLOCK Iosb;
-
DPRINT("CmiInitPermanentRegistryHive(%p, %S, %d) - Entered.\n", RegistryHive, Filename, CreateNew);
/* Duplicate Filename */
Status = RtlCreateUnicodeString(&RegistryHive->Filename, Filename);
- if (!NT_SUCCESS(Status)) {
+ if (!NT_SUCCESS(Status))
+ {
DPRINT("CmiInitPermanentRegistryHive() - Failed 1.\n");
return Status;
}
CreateDisposition = FILE_OPEN;
Status = NtCreateFile(&FileHandle,
- FILE_ALL_ACCESS,
- &ObjectAttributes,
- &IoSB,
- NULL,
- FILE_ATTRIBUTE_NORMAL,
- 0,
- CreateDisposition,
- FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
- NULL,
- 0);
-
- if ((CreateNew) && (IoSB.Information == FILE_CREATED))
+ FILE_ALL_ACCESS,
+ &ObjectAttributes,
+ &IoSB,
+ NULL,
+ FILE_ATTRIBUTE_NORMAL,
+ 0,
+ CreateDisposition,
+ FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
+ NULL,
+ 0);
+ if (!NT_SUCCESS(Status))
{
- Status = CmiCreateNewRegFile(FileHandle);
+ RtlFreeUnicodeString(&RegistryHive->Filename);
+ DPRINT1("NtCreateFile() failed (Status %lx)\n", Status);
+ return(Status);
}
- if (!NT_SUCCESS(Status))
+ if ((CreateNew) && (IoSB.Information == FILE_CREATED))
{
- RtlFreeUnicodeString(&RegistryHive->Filename);
- DPRINT("CmiCreateNewRegFile() - Failed with status %x.\n", Status);
- return Status;
+ Status = CmiCreateNewRegFile(FileHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ RtlFreeUnicodeString(&RegistryHive->Filename);
+ DPRINT1("CmiCreateNewRegFile() - Failed with status %x.\n", Status);
+ return(Status);
+ }
}
Status = ObReferenceObjectByHandle(FileHandle,
if (!NT_SUCCESS(Status))
{
- ZwClose(FileHandle);
+ NtClose(FileHandle);
RtlFreeUnicodeString(&RegistryHive->Filename);
DPRINT("CmiInitPermanentRegistryHive() - ObReferenceObjectByHandle Failed with status %x.\n", Status);
return Status;
FileOffset.u.HighPart = 0;
FileOffset.u.LowPart = 0;
DPRINT(" Attempting to ZwReadFile(%d) for %d bytes into %p\n", FileHandle, sizeof(HIVE_HEADER), RegistryHive->HiveHeader);
- Status = ZwReadFile(FileHandle,
+ Status = NtReadFile(FileHandle,
0,
0,
0,
-// 0,
- &Iosb,
+ &IoSB,
RegistryHive->HiveHeader,
sizeof(HIVE_HEADER),
&FileOffset,
return Status;
}
- Status = ZwQueryInformationFile(FileHandle,
- &IoSB,
- &fsi,
- sizeof(fsi),
- FileStandardInformation);
+ Status = NtQueryInformationFile(FileHandle,
+ &IoSB,
+ &fsi,
+ sizeof(fsi),
+ FileStandardInformation);
assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status));
RegistryHive->FileSize = fsi.EndOfFile.u.LowPart;
#ifdef WIN32_REGDBG
// assert(RegistryHive->FileSize);
- if (RegistryHive->FileSize) {
- RegistryHive->BlockListSize = (RegistryHive->FileSize / 4096) - 1;
- } else {
- ObDereferenceObject(RegistryHive->FileObject);
- RtlFreeUnicodeString(&RegistryHive->Filename);
- DPRINT("CmiInitPermanentRegistryHive() - Failed, zero length hive file.\n");
- return STATUS_INSUFFICIENT_RESOURCES;
+ if (RegistryHive->FileSize)
+ {
+ RegistryHive->BlockListSize = (RegistryHive->FileSize / 4096) - 1;
+ }
+ else
+ {
+ ObDereferenceObject(RegistryHive->FileObject);
+ RtlFreeUnicodeString(&RegistryHive->Filename);
+ DPRINT("CmiInitPermanentRegistryHive() - Failed, zero length hive file.\n");
+ return STATUS_INSUFFICIENT_RESOURCES;
}
#else
RegistryHive->BlockListSize = (RegistryHive->FileSize / 4096) - 1;
FileOffset.u.LowPart = 4096;
DPRINT(" Attempting to ZwReadFile(%d) for %d bytes into %p\n", FileHandle, RegistryHive->FileSize - 4096, (PVOID)RegistryHive->BlockList[0]);
- Status = ZwReadFile(FileHandle,
+ Status = NtReadFile(FileHandle,
0,
0,
0,
-// 0,
- &Iosb,
+ &IoSB,
(PVOID) RegistryHive->BlockList[0],
RegistryHive->FileSize - 4096,
- &FileOffset,
- 0);
+ &FileOffset,
+ 0);
assertmsg(NT_SUCCESS(Status), ("Status: 0x%X\n", Status));
+ NtClose(FileHandle);
#endif
RegistryHive->FreeListSize = 0;
{
DPRINT("Bad BlockId %x, offset %x\n", tmpBin->BlockId, BlockOffset);
//KeBugCheck(0);
- return STATUS_INSUFFICIENT_RESOURCES;
+ return STATUS_INSUFFICIENT_RESOURCES;
}
assertmsg((tmpBin->BlockSize % 4096) == 0, ("BlockSize (0x%.08x) must be multiplum of 4K\n", tmpBin->BlockSize));
DPRINT("CmiInitPermanentRegistryHive(%p, %S, %d) - Finished.\n", RegistryHive, Filename, CreateNew);
- return STATUS_SUCCESS;
+ return(STATUS_SUCCESS);
}
BOOLEAN CreateNew)
{
PREGISTRY_HIVE Hive;
+ KIRQL oldlvl;
NTSTATUS Status;
DPRINT("CmiCreateRegistryHive(Filename %S)\n", Filename);
Hive = ExAllocatePool(NonPagedPool, sizeof(REGISTRY_HIVE));
if (Hive == NULL)
- return STATUS_INSUFFICIENT_RESOURCES;
+ return(STATUS_INSUFFICIENT_RESOURCES);
DPRINT("Hive %x\n", Hive);
if (Hive->HiveHeader == NULL)
{
ExFreePool(Hive);
- return STATUS_INSUFFICIENT_RESOURCES;
+ return(STATUS_INSUFFICIENT_RESOURCES);
}
if (Filename != NULL)
return(Status);
}
- KeInitializeSemaphore(&Hive->RegSem, 1, 1);
-
+ ExInitializeResourceLite(&Hive->HiveResource);
+
+ /* Add the new hive to the hive list */
+ KeAcquireSpinLock(&CmiHiveListLock,&oldlvl);
+ InsertHeadList(&CmiHiveListHead, &Hive->HiveList);
+ KeReleaseSpinLock(&CmiHiveListLock,oldlvl);
+
VERIFY_REGISTRY_HIVE(Hive);
*RegistryHive = Hive;
}
+NTSTATUS
+CmiRemoveRegistryHive(PREGISTRY_HIVE RegistryHive)
+{
+ KIRQL oldlvl;
+
+ /* Remove hive from hive list */
+ KeAcquireSpinLock(&CmiHiveListLock,&oldlvl);
+ RemoveEntryList(&RegistryHive->HiveList);
+ KeReleaseSpinLock(&CmiHiveListLock,oldlvl);
+
+
+ /* FIXME: Remove attached keys and values */
+
+
+ /* Release hive header */
+ ExFreePool(RegistryHive->HiveHeader);
+
+ /* Release hive */
+ ExFreePool(RegistryHive);
+
+ return(STATUS_SUCCESS);
+}
+
+
ULONG
CmiGetMaxNameLength(PREGISTRY_HIVE RegistryHive,
PKEY_CELL KeyCell)
-/* $Id: registry.c,v 1.77 2002/11/13 05:18:03 robd Exp $
+/* $Id: registry.c,v 1.78 2002/11/26 15:31:41 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
PREGISTRY_HIVE CmiVolatileHive = NULL;
KSPIN_LOCK CmiKeyListLock;
+LIST_ENTRY CmiHiveListHead;
+KSPIN_LOCK CmiHiveListLock;
+
static PKEY_OBJECT CmiRootKey = NULL;
static PKEY_OBJECT CmiMachineKey = NULL;
static PKEY_OBJECT CmiUserKey = NULL;
{KEY_READ, KEY_WRITE, KEY_EXECUTE, KEY_ALL_ACCESS};
+
VOID
CmiCheckKey(BOOLEAN Verbose,
HANDLE Key);
CmiKeyType->DuplicationNotify = NULL;
RtlInitUnicodeString(&CmiKeyType->TypeName, L"Key");
+ /* Initialize the hive list */
+ InitializeListHead(&CmiHiveListHead);
+ KeInitializeSpinLock(&CmiHiveListLock);
+
/* Build volatile registry store */
Status = CmiCreateRegistryHive(NULL, &CmiVolatileHive, FALSE);
assert(NT_SUCCESS(Status));
- /* Build the Root Key Object */
+ /* Create '\Registry' key. */
RtlInitUnicodeString(&RootKeyName, REG_ROOT_KEY_NAME);
InitializeObjectAttributes(&ObjectAttributes, &RootKeyName, 0, NULL, NULL);
Status = ObCreateObject(&RootKeyHandle,
/* Create initial predefined symbolic links */
- /* HKEY_LOCAL_MACHINE */
+ /* Create '\Registry\Machine' key. */
Status = ObCreateObject(&KeyHandle,
STANDARD_RIGHTS_REQUIRED,
NULL,
CmiAddKeyToList(CmiRootKey, NewKey);
CmiMachineKey = NewKey;
- /* HKEY_USERS */
+ /* Create '\Registry\User' key. */
Status = ObCreateObject(&KeyHandle,
STANDARD_RIGHTS_REQUIRED,
NULL,
CmiAddKeyToList(CmiRootKey, NewKey);
CmiUserKey = NewKey;
- /* Create '\\Registry\\Machine\\HARDWARE' key. */
+ /* Create '\Registry\Machine\HARDWARE' key. */
Status = ObCreateObject(&KeyHandle,
STANDARD_RIGHTS_REQUIRED,
NULL,
CmiAddKeyToList(CmiMachineKey, NewKey);
CmiHardwareKey = NewKey;
- /* Create '\\Registry\\Machine\\HARDWARE\\DESCRIPTION' key. */
+ /* Create '\Registry\Machine\HARDWARE\DESCRIPTION' key. */
Status = ObCreateObject(&KeyHandle,
STANDARD_RIGHTS_REQUIRED,
NULL,
memcpy(NewKey->Name, "DESCRIPTION", strlen("DESCRIPTION"));
CmiAddKeyToList(CmiHardwareKey, NewKey);
- /* Create '\\Registry\\Machine\\HARDWARE\\DEVICEMAP' key. */
+ /* Create '\Registry\Machine\HARDWARE\DEVICEMAP' key. */
Status = ObCreateObject(&KeyHandle,
STANDARD_RIGHTS_REQUIRED,
NULL,
memcpy(NewKey->Name, "DEVICEMAP", strlen("DEVICEMAP"));
CmiAddKeyToList(CmiHardwareKey,NewKey);
- /* Create '\\Registry\\Machine\\HARDWARE\\RESOURCEMAP' key. */
+ /* Create '\Registry\Machine\HARDWARE\RESOURCEMAP' key. */
Status = ObCreateObject(&KeyHandle,
STANDARD_RIGHTS_REQUIRED,
NULL,
PCHAR p1, p2;
ULONG PiceStart;
- /* FIXME: Store current command line */
+ /* FIXME: Store system start options */
+
+
/* Create the 'CurrentControlSet' link. */
CmiCreateCurrentControlSetLink();
if ((NewKey->SubKeys == NULL) && (NewKey->KeyCell->NumberOfSubKeys != 0))
{
- /* FIXME: Cleanup from CmiCreateRegistryHive() */
DPRINT("NumberOfSubKeys %d\n", NewKey->KeyCell->NumberOfSubKeys);
ZwClose(NewKey);
+ CmiRemoveRegistryHive(RegistryHive);
return(STATUS_INSUFFICIENT_RESOURCES);
}
if ((NewKey->Name == NULL) && (strlen(KeyName) != 0))
{
- /* FIXME: Cleanup from CmiCreateRegistryHive() */
DPRINT("strlen(KeyName) %d\n", strlen(KeyName));
if (NewKey->SubKeys != NULL)
ExFreePool(NewKey->SubKeys);
ZwClose(NewKey);
+ CmiRemoveRegistryHive(RegistryHive);
return(STATUS_INSUFFICIENT_RESOURCES);
}
NTSTATUS
CmiInitHives(BOOLEAN SetUpBoot)
{
+ PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING KeyName;
+ UNICODE_STRING ValueName;
+ HANDLE KeyHandle;
+
NTSTATUS Status;
+ WCHAR ConfigPath[MAX_PATH];
+
+ ULONG BufferSize;
+ ULONG ResultSize;
+ PWSTR EndPtr;
+
+
DPRINT("CmiInitHives() called\n");
+ if (SetUpBoot == TRUE)
+ {
+ RtlInitUnicodeStringFromLiteral(&KeyName,
+ L"\\Registry\\Machine\\HARDWARE");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = NtOpenKey(&KeyHandle,
+ KEY_ALL_ACCESS,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtOpenKey() failed (Status %lx)\n", Status);
+ return(Status);
+ }
+
+ RtlInitUnicodeStringFromLiteral(&ValueName,
+ L"InstallPath");
+
+ BufferSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 4096;
+ ValueInfo = ExAllocatePool(PagedPool,
+ BufferSize);
+ if (ValueInfo == NULL)
+ {
+ NtClose(KeyHandle);
+ return(STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ Status = NtQueryValueKey(KeyHandle,
+ &ValueName,
+ KeyValuePartialInformation,
+ ValueInfo,
+ BufferSize,
+ &ResultSize);
+ NtClose(KeyHandle);
+ if (ValueInfo == NULL)
+ {
+ ExFreePool(ValueInfo);
+ return(Status);
+ }
+
+ RtlCopyMemory(ConfigPath,
+ ValueInfo->Data,
+ ValueInfo->DataLength);
+ ConfigPath[ValueInfo->DataLength / sizeof(WCHAR)] = (WCHAR)0;
+ ExFreePool(ValueInfo);
+ }
+ else
+ {
+ wcscpy(ConfigPath, L"\\SystemRoot\\system32\\config");
+ }
+ DPRINT1("ConfigPath: %S\n", ConfigPath);
+
+ EndPtr = ConfigPath + wcslen(ConfigPath);
+
CmiDoVerify = TRUE;
- /* FIXME: Delete temporary \Registry\Machine\System */
+ /* FIXME: Save boot log */
+
+ /* FIXME: Rename \Registry\Machine\System */
/* Connect the SYSTEM hive */
- /* FIXME: Don't overwrite the existing 'System' hive yet */
-// Status = CmiInitializeHive(SYSTEM_REG_FILE, REG_SYSTEM_KEY_NAME, "System", CmiMachineKey);
+// Status = CmiInitializeHive(SYSTEM_REG_FILE, REG_SYSTEM_KEY_NAME, "System", CmiMachineKey, SetUpBoot);
// assert(NT_SUCCESS(Status));
+ /* FIXME: Synchronize old and new system hive (??) */
+
+ /* FIXME: Delete old system hive */
+
/* Connect the SOFTWARE hive */
- Status = CmiInitializeHive(SOFTWARE_REG_FILE, REG_SOFTWARE_KEY_NAME, "Software", CmiMachineKey, SetUpBoot);
+ wcscpy(EndPtr, REG_SOFTWARE_FILE_NAME);
+ DPRINT1("ConfigPath: %S\n", ConfigPath);
+
+// Status = CmiInitializeHive(SOFTWARE_REG_FILE, REG_SOFTWARE_KEY_NAME, "Software", CmiMachineKey, SetUpBoot);
+ Status = CmiInitializeHive(ConfigPath,
+ REG_SOFTWARE_KEY_NAME,
+ "Software",
+ CmiMachineKey,
+ SetUpBoot);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
+ }
//assert(NT_SUCCESS(Status));
/* Connect the SAM hive */
- Status = CmiInitializeHive(SAM_REG_FILE,REG_SAM_KEY_NAME, "Sam", CmiMachineKey, SetUpBoot);
+ wcscpy(EndPtr, REG_SAM_FILE_NAME);
+ DPRINT1("ConfigPath: %S\n", ConfigPath);
+
+// Status = CmiInitializeHive(SAM_REG_FILE, REG_SAM_KEY_NAME, "Sam", CmiMachineKey, SetUpBoot);
+ Status = CmiInitializeHive(ConfigPath,
+ REG_SAM_KEY_NAME,
+ "Sam",
+ CmiMachineKey,
+ SetUpBoot);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
+ }
//assert(NT_SUCCESS(Status));
/* Connect the SECURITY hive */
- Status = CmiInitializeHive(SEC_REG_FILE, REG_SEC_KEY_NAME, "Security", CmiMachineKey, SetUpBoot);
+ wcscpy(EndPtr, REG_SEC_FILE_NAME);
+ DPRINT1("ConfigPath: %S\n", ConfigPath);
+// Status = CmiInitializeHive(SEC_REG_FILE, REG_SEC_KEY_NAME, "Security", CmiMachineKey, SetUpBoot);
+ Status = CmiInitializeHive(ConfigPath,
+ REG_SEC_KEY_NAME,
+ "Security",
+ CmiMachineKey,
+ SetUpBoot);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
+ }
//assert(NT_SUCCESS(Status));
/* Connect the DEFAULT hive */
- Status = CmiInitializeHive(USER_REG_FILE, REG_USER_KEY_NAME, ".Default", CmiUserKey, SetUpBoot);
+ wcscpy(EndPtr, REG_USER_FILE_NAME);
+ DPRINT1("ConfigPath: %S\n", ConfigPath);
+
+// Status = CmiInitializeHive(USER_REG_FILE, REG_USER_KEY_NAME, ".Default", CmiUserKey, SetUpBoot);
+ Status = CmiInitializeHive(ConfigPath,
+ REG_USER_KEY_NAME,
+ ".Default",
+ CmiUserKey,
+ SetUpBoot);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
+ }
//assert(NT_SUCCESS(Status));
/* FIXME : initialize standards symbolic links */
// CmiCheckRegistry(TRUE);
+ /* FIXME: Start automatic hive syncronization */
+
DPRINT("CmiInitHives() done\n");
return(STATUS_SUCCESS);
VOID
CmShutdownRegistry(VOID)
{
- DPRINT("CmShutdownRegistry() called\n");
+ PREGISTRY_HIVE Hive;
+ PLIST_ENTRY Entry;
+ KIRQL oldlvl;
+
+ DPRINT1("CmShutdownRegistry() called\n");
+
+ /* FIXME: Stop automatic hive syncronization */
+
+ KeAcquireSpinLock(&CmiHiveListLock,&oldlvl);
+ Entry = CmiHiveListHead.Flink;
+ while (Entry != &CmiHiveListHead)
+ {
+ Hive = CONTAINING_RECORD(Entry, REGISTRY_HIVE, HiveList);
+
+ if (Hive->Flags & HIVE_VOLATILE)
+ {
+ DPRINT1("Volatile hive\n");
+ }
+ else
+ {
+ DPRINT1("Flush non-volatile hive '%wZ'\n", &Hive->Filename);
+
+ /* Flush non-volatile hive */
+
+ /* Dereference file */
+ ObDereferenceObject(Hive->FileObject);
+ Hive->FileObject = NULL;
+ }
+
+ Entry = Entry->Flink;
+ }
+ KeReleaseSpinLock(&CmiHiveListLock,oldlvl);
+
+DPRINT1(" *** System stopped ***\n");
+for (;;);
/* Note:
* Don't call UNIMPLEMENTED() here since this function is