From Eugene Ingerman:

Create default registry files is they don't exist
Modularized registry.c into more files, more manageable
Bug fix in IoCreateFile that didn't return IoStatusBlock
'dir' now works in Bochs - corrected parsing in VfatOpenFile

svn path=/trunk/; revision=1969
This commit is contained in:
Jason Filby 2001-06-14 21:05:08 +00:00
parent e180745ffa
commit 2f3eb30871
9 changed files with 3249 additions and 3101 deletions

View file

@ -1,4 +1,4 @@
/* $Id: create.c,v 1.25 2001/05/04 01:21:45 rex Exp $
/* $Id: create.c,v 1.26 2001/06/14 21:05:08 jfilby Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -598,7 +598,8 @@ VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
CHECKPOINT;
ParentFcb = Temp;
}
if( *current != L'\0' ){ //the file name is directory. there will be no last part.
/* searching for last path component */
DPRINT ("search for (%S) in (%S)\n", current, Fcb ? Fcb->PathName : L"");
Status = FindFile (DeviceExt, Fcb, ParentFcb, current, NULL, NULL);
@ -621,6 +622,7 @@ VfatOpenFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
Fcb = ParentFcb;
ParentFcb = Temp;
ParentFcb->ObjectName = &(wcschr (ParentFcb->ObjectName, '\\'))[1];
}
}
FileObject->Flags = FileObject->Flags |

View file

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.43 2001/06/12 17:50:27 chorns Exp $
# $Id: Makefile,v 1.44 2001/06/14 21:05:07 jfilby Exp $
#
# ReactOS Operating System
#
@ -268,7 +268,11 @@ OBJECTS_SE = \
# Configuration Manager (Registry)
OBJECTS_CM = \
cm/registry.o
cm/registry.o \
cm/ntfunc.o \
cm/rtlfunc.o \
cm/regfile.o \
cm/regobj.o
# Debugger Support (Dbg)
OBJECTS_DBG = \

261
reactos/ntoskrnl/cm/cm.h Normal file
View file

@ -0,0 +1,261 @@
#ifndef __INCLUDE_CM_H
#define __INCLUDE_CM_H
#include <windows.h>
#include <ddk/ntddk.h>
#include <internal/config.h>
#include <internal/ob.h>
#include <limits.h>
#include <string.h>
#include <internal/pool.h>
#include <internal/registry.h>
#define NDEBUG
#include <internal/debug.h>
#define KO_MARKED_FOR_DELETE 0x00000001
// BLOCK_OFFSET = offset in file after header block
typedef DWORD BLOCK_OFFSET;
/* header for registry hive file : */
typedef struct _HEADER_BLOCK
{
ULONG BlockId; /* ="regf" */
ULONG Version; /* file version ?*/
ULONG VersionOld; /* file version ?*/
FILETIME DateModified; /* please don't replace with LARGE_INTEGER !*/
ULONG Unused3; /* registry format version ? */
ULONG Unused4; /* registry format version ? */
ULONG Unused5; /* registry format version ? */
ULONG Unused6; /* registry format version ? */
BLOCK_OFFSET RootKeyBlock;
ULONG BlockSize;
ULONG Unused7;
WCHAR FileName[64]; /* end of file name */
ULONG Unused8[83];
ULONG Checksum;
} HEADER_BLOCK, *PHEADER_BLOCK;
typedef struct _HEAP_BLOCK
{
ULONG BlockId; /* = "hbin" */
BLOCK_OFFSET BlockOffset; /* block offset of this heap */
ULONG BlockSize; /* size in bytes, 4k multiple */
ULONG Unused1;
FILETIME DateModified; /* please don't replace with LARGE_INTEGER !*/
ULONG Unused2;
} HEAP_BLOCK, *PHEAP_BLOCK;
// each sub_block begin with this struct :
// in a free subblock, higher bit of SubBlockSize is set
typedef struct _FREE_SUB_BLOCK
{
LONG SubBlockSize;/* <0 if used, >0 if free */
} FREE_SUB_BLOCK, *PFREE_SUB_BLOCK;
typedef struct _KEY_BLOCK
{
LONG SubBlockSize;
USHORT SubBlockId;
USHORT Type;
FILETIME LastWriteTime; /* please don't replace with LARGE_INTEGER !*/
ULONG UnUsed1;
BLOCK_OFFSET ParentKeyOffset;
ULONG NumberOfSubKeys;
ULONG UnUsed2;
BLOCK_OFFSET HashTableOffset;
ULONG UnUsed3;
ULONG NumberOfValues;
BLOCK_OFFSET ValuesOffset;
BLOCK_OFFSET SecurityKeyOffset;
BLOCK_OFFSET ClassNameOffset;
ULONG Unused4[5];
USHORT NameSize;
USHORT ClassSize; /* size of ClassName in bytes */
UCHAR Name[0]; /* warning : not zero terminated */
} KEY_BLOCK, *PKEY_BLOCK;
// hash record :
// HashValue=four letters of value's name
typedef struct _HASH_RECORD
{
BLOCK_OFFSET KeyOffset;
ULONG HashValue;
} HASH_RECORD, *PHASH_RECORD;
typedef struct _HASH_TABLE_BLOCK
{
LONG SubBlockSize;
USHORT SubBlockId;
USHORT HashTableSize;
HASH_RECORD Table[0];
} HASH_TABLE_BLOCK, *PHASH_TABLE_BLOCK;
typedef struct _VALUE_LIST_BLOCK
{
LONG SubBlockSize;
BLOCK_OFFSET Values[0];
} VALUE_LIST_BLOCK, *PVALUE_LIST_BLOCK;
typedef struct _VALUE_BLOCK
{
LONG SubBlockSize;
USHORT SubBlockId; // "kv"
USHORT NameSize; // length of Name
LONG DataSize; // length of datas in the subblock pointed by DataOffset
BLOCK_OFFSET DataOffset;// datas are here if high bit of DataSize is set
ULONG DataType;
USHORT Flags;
USHORT Unused1;
UCHAR Name[0]; /* warning : not zero terminated */
} VALUE_BLOCK, *PVALUE_BLOCK;
typedef struct _DATA_BLOCK
{
LONG SubBlockSize;
UCHAR Data[0];
} DATA_BLOCK, *PDATA_BLOCK;
typedef struct _REGISTRY_FILE
{
PWSTR Filename;
ULONG FileSize;
PFILE_OBJECT FileObject;
PHEADER_BLOCK HeaderBlock;
// ULONG NumberOfBlocks;
ULONG BlockListSize;
PHEAP_BLOCK *BlockList;
ULONG FreeListSize;
ULONG FreeListMax;
PFREE_SUB_BLOCK *FreeList;
BLOCK_OFFSET *FreeListOffset;
// KSPIN_LOCK RegLock;
KSEMAPHORE RegSem;
// NTSTATUS (*Extend)(ULONG NewSize);
// PVOID (*Flush)(VOID);
} REGISTRY_FILE, *PREGISTRY_FILE;
/* Type defining the Object Manager Key Object */
typedef struct _KEY_OBJECT
{
CSHORT Type;
CSHORT Size;
ULONG Flags;
USHORT NameSize; // length of Name
UCHAR *Name;
PREGISTRY_FILE RegistryFile;
BLOCK_OFFSET BlockOffset;
PKEY_BLOCK KeyBlock;
struct _KEY_OBJECT *ParentKey;
ULONG NumberOfSubKeys; /* subkeys loaded in SubKeys */
ULONG SizeOfSubKeys; /* space allocated in SubKeys */
struct _KEY_OBJECT **SubKeys; /* list of subkeys loaded */
} KEY_OBJECT, *PKEY_OBJECT;
NTSTATUS CmiObjectParse(PVOID ParsedObject,
PVOID *NextObject,
PUNICODE_STRING FullPath,
PWSTR *Path,
POBJECT_TYPE ObjectType,
ULONG Attribute);
NTSTATUS CmiObjectCreate(PVOID ObjectBody,
PVOID Parent,
PWSTR RemainingPath,
struct _OBJECT_ATTRIBUTES* ObjectAttributes);
void CmiObjectDelete(PVOID DeletedObject);
VOID CmiAddKeyToList(PKEY_OBJECT ParentKey,PKEY_OBJECT NewKey);
NTSTATUS CmiRemoveKeyFromList(PKEY_OBJECT NewKey);
PKEY_OBJECT CmiScanKeyList(PKEY_OBJECT Parent,
PCHAR KeyNameBuf,
ULONG Attributes);
PREGISTRY_FILE CmiCreateRegistry(PWSTR Filename);
ULONG CmiGetMaxNameLength(PREGISTRY_FILE RegistryFile,
PKEY_BLOCK KeyBlock);
ULONG CmiGetMaxClassLength(PREGISTRY_FILE RegistryFile,
PKEY_BLOCK KeyBlock);
ULONG CmiGetMaxValueNameLength(PREGISTRY_FILE RegistryFile,
PKEY_BLOCK KeyBlock);
ULONG CmiGetMaxValueDataLength(PREGISTRY_FILE RegistryFile,
PKEY_BLOCK KeyBlock);
NTSTATUS CmiScanForSubKey(IN PREGISTRY_FILE RegistryFile,
IN PKEY_BLOCK KeyBlock,
OUT PKEY_BLOCK *SubKeyBlock,
OUT BLOCK_OFFSET *BlockOffset,
IN PCHAR KeyName,
IN ACCESS_MASK DesiredAccess,
IN ULONG Attributes);
NTSTATUS CmiAddSubKey(IN PREGISTRY_FILE RegistryFile,
IN PKEY_OBJECT Parent,
OUT PKEY_OBJECT SubKey,
IN PWSTR NewSubKeyName,
IN USHORT NewSubKeyNameSize,
IN ULONG TitleIndex,
IN PUNICODE_STRING Class,
IN ULONG CreateOptions);
NTSTATUS CmiScanKeyForValue(IN PREGISTRY_FILE RegistryFile,
IN PKEY_BLOCK KeyBlock,
IN PCHAR ValueName,
OUT PVALUE_BLOCK *ValueBlock,
OUT BLOCK_OFFSET *VBOffset);
NTSTATUS CmiGetValueFromKeyByIndex(IN PREGISTRY_FILE RegistryFile,
IN PKEY_BLOCK KeyBlock,
IN ULONG Index,
OUT PVALUE_BLOCK *ValueBlock);
NTSTATUS CmiAddValueToKey(IN PREGISTRY_FILE RegistryFile,
IN PKEY_BLOCK KeyBlock,
IN PCHAR ValueNameBuf,
OUT PVALUE_BLOCK *pValueBlock,
OUT BLOCK_OFFSET *pVBOffset);
NTSTATUS CmiDeleteValueFromKey(IN PREGISTRY_FILE RegistryFile,
IN PKEY_BLOCK KeyBlock,
IN PCHAR ValueName);
NTSTATUS CmiAllocateHashTableBlock(IN PREGISTRY_FILE RegistryFile,
OUT PHASH_TABLE_BLOCK *HashBlock,
OUT BLOCK_OFFSET *HBOffset,
IN ULONG HashTableSize);
PKEY_BLOCK CmiGetKeyFromHashByIndex(PREGISTRY_FILE RegistryFile,
PHASH_TABLE_BLOCK HashBlock,
ULONG Index);
NTSTATUS CmiAddKeyToHashTable(PREGISTRY_FILE RegistryFile,
PHASH_TABLE_BLOCK HashBlock,
PKEY_BLOCK NewKeyBlock,
BLOCK_OFFSET NKBOffset);
NTSTATUS CmiAllocateValueBlock(IN PREGISTRY_FILE RegistryFile,
OUT PVALUE_BLOCK *ValueBlock,
OUT BLOCK_OFFSET *VBOffset,
IN PCHAR ValueNameBuf);
NTSTATUS CmiDestroyValueBlock(PREGISTRY_FILE RegistryFile,
PVALUE_BLOCK ValueBlock, BLOCK_OFFSET VBOffset);
NTSTATUS CmiAllocateBlock(PREGISTRY_FILE RegistryFile,
PVOID *Block,
LONG BlockSize,
BLOCK_OFFSET * pBlockOffset);
NTSTATUS CmiDestroyBlock(PREGISTRY_FILE RegistryFile,
PVOID Block,BLOCK_OFFSET Offset);
PVOID CmiGetBlock(PREGISTRY_FILE RegistryFile,
BLOCK_OFFSET BlockOffset,
OUT PHEAP_BLOCK * ppHeap);
VOID CmiLockBlock(PREGISTRY_FILE RegistryFile,
PVOID Block);
VOID CmiReleaseBlock(PREGISTRY_FILE RegistryFile,
PVOID Block);
NTSTATUS
CmiAddFree(PREGISTRY_FILE RegistryFile,
PFREE_SUB_BLOCK FreeBlock,BLOCK_OFFSET FreeOffset);
#endif /*__INCLUDE_CM_H*/

1283
reactos/ntoskrnl/cm/ntfunc.c Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,253 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/cm/regobj.c
* PURPOSE: Registry object manipulation routines.
* UPDATE HISTORY:
*/
#include "cm.h"
extern POBJECT_TYPE CmiKeyType;
extern KSPIN_LOCK CmiKeyListLock;
NTSTATUS CmiObjectParse(PVOID ParsedObject,
PVOID *NextObject,
PUNICODE_STRING FullPath,
PWSTR *Path,
POBJECT_TYPE ObjectType,
ULONG Attributes)
{
CHAR cPath[MAX_PATH];
PWSTR end;
PKEY_OBJECT FoundObject;
PKEY_OBJECT ParsedKey=ParsedObject;
PKEY_BLOCK SubKeyBlock;
BLOCK_OFFSET BlockOffset;
NTSTATUS Status;
*NextObject = NULL;
if ((*Path) == NULL)
{
return STATUS_UNSUCCESSFUL;
}
if((*Path[0])=='\\')
{
end = wcschr((*Path)+1, '\\');
if (end != NULL)
*end = 0;
wcstombs(cPath,(*Path)+1,wcslen((*Path)+1));
cPath[wcslen( (*Path)+1)]=0;
}
else
{
end = wcschr((*Path), '\\');
if (end != NULL)
*end = 0;
wcstombs(cPath,(*Path),wcslen((*Path)));
cPath[wcslen( (*Path))]=0;
}
FoundObject = CmiScanKeyList(ParsedKey,cPath,Attributes);
if (FoundObject == NULL)
{
Status = CmiScanForSubKey(ParsedKey->RegistryFile,
ParsedKey->KeyBlock,
&SubKeyBlock,
&BlockOffset,
cPath,
0,
Attributes);
if(!NT_SUCCESS(Status) || SubKeyBlock == NULL)
{
if (end != NULL)
{
*end = '\\';
}
return STATUS_UNSUCCESSFUL;
}
/* Create new key object and put into linked list */
DPRINT("CmiObjectParse %s\n",cPath);
FoundObject = ObCreateObject(NULL,
STANDARD_RIGHTS_REQUIRED,
NULL,
CmiKeyType);
if (FoundObject == NULL)
{
//FIXME : return the good error code
return STATUS_UNSUCCESSFUL;
}
FoundObject->Flags = 0;
FoundObject->Name = SubKeyBlock->Name;
FoundObject->NameSize = SubKeyBlock->NameSize;
FoundObject->KeyBlock = SubKeyBlock;
FoundObject->BlockOffset = BlockOffset;
FoundObject->RegistryFile = ParsedKey->RegistryFile;
CmiAddKeyToList(ParsedKey,FoundObject);
}
else
ObReferenceObjectByPointer(FoundObject,
STANDARD_RIGHTS_REQUIRED,
NULL,
UserMode);
DPRINT("CmiObjectParse %s\n",FoundObject->Name);
if (end != NULL)
{
*end = '\\';
*Path = end;
}
else
{
*Path = NULL;
}
*NextObject = FoundObject;
return STATUS_SUCCESS;
}
NTSTATUS CmiObjectCreate(PVOID ObjectBody,
PVOID Parent,
PWSTR RemainingPath,
struct _OBJECT_ATTRIBUTES* ObjectAttributes)
{
PKEY_OBJECT pKey=ObjectBody;
pKey->ParentKey = Parent;
if (RemainingPath)
{
if(RemainingPath[0]== L'\\')
{
pKey->Name = (PCHAR) (&RemainingPath[1]);
pKey->NameSize = wcslen(RemainingPath)-1;
}
else
{
pKey->Name = (PCHAR) RemainingPath;
pKey->NameSize = wcslen(RemainingPath);
}
}
else
pKey->NameSize = 0;
return STATUS_SUCCESS;
}
void
CmiObjectDelete(PVOID DeletedObject)
{
PKEY_OBJECT KeyObject;
DPRINT("delete object key\n");
KeyObject = (PKEY_OBJECT) DeletedObject;
if(!NT_SUCCESS(CmiRemoveKeyFromList(KeyObject)))
{
DPRINT1("Key not found in parent list ???\n");
}
if (KeyObject->Flags & KO_MARKED_FOR_DELETE)
{
DPRINT1("delete really key\n");
CmiDestroyBlock(KeyObject->RegistryFile,
KeyObject->KeyBlock,
KeyObject->BlockOffset);
}
else
{
CmiReleaseBlock(KeyObject->RegistryFile,
KeyObject->KeyBlock);
}
}
void
CmiAddKeyToList(PKEY_OBJECT ParentKey,PKEY_OBJECT NewKey)
{
KIRQL OldIrql;
KeAcquireSpinLock(&CmiKeyListLock, &OldIrql);
if (ParentKey->SizeOfSubKeys <= ParentKey->NumberOfSubKeys)
{
PKEY_OBJECT *tmpSubKeys = ExAllocatePool(PagedPool
, (ParentKey->NumberOfSubKeys+1) * sizeof(DWORD));
if(ParentKey->NumberOfSubKeys > 0)
memcpy(tmpSubKeys,ParentKey->SubKeys
,ParentKey->NumberOfSubKeys*sizeof(DWORD));
if(ParentKey->SubKeys) ExFreePool(ParentKey->SubKeys);
ParentKey->SubKeys=tmpSubKeys;
ParentKey->SizeOfSubKeys = ParentKey->NumberOfSubKeys+1;
}
/* FIXME : please maintain the list in alphabetic order */
/* to allow a dichotomic search */
ParentKey->SubKeys[ParentKey->NumberOfSubKeys++] = NewKey;
ObReferenceObjectByPointer(ParentKey,
STANDARD_RIGHTS_REQUIRED,
NULL,
UserMode);
NewKey->ParentKey = ParentKey;
KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
}
NTSTATUS
CmiRemoveKeyFromList(PKEY_OBJECT KeyToRemove)
{
KIRQL OldIrql;
PKEY_OBJECT ParentKey;
DWORD Index;
ParentKey=KeyToRemove->ParentKey;
KeAcquireSpinLock(&CmiKeyListLock, &OldIrql);
/* FIXME : if list maintained in alphabetic order, use dichotomic search */
for (Index=0; Index < ParentKey->NumberOfSubKeys; Index++)
{
if(ParentKey->SubKeys[Index] == KeyToRemove)
{
if (Index < ParentKey->NumberOfSubKeys-1)
memmove(&ParentKey->SubKeys[Index]
,&ParentKey->SubKeys[Index+1]
,(ParentKey->NumberOfSubKeys-Index-1)*sizeof(PKEY_OBJECT));
ParentKey->NumberOfSubKeys--;
KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
ObDereferenceObject(ParentKey);
return STATUS_SUCCESS;
}
}
KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
return STATUS_UNSUCCESSFUL;
}
PKEY_OBJECT
CmiScanKeyList(PKEY_OBJECT Parent,
PCHAR KeyName,
ULONG Attributes)
{
KIRQL OldIrql;
PKEY_OBJECT CurKey;
DWORD Index;
WORD NameSize;
NameSize=strlen(KeyName);
KeAcquireSpinLock(&CmiKeyListLock, &OldIrql);
/* FIXME : if list maintained in alphabetic order, use dichotomic search */
for (Index=0; Index < Parent->NumberOfSubKeys; Index++)
{
CurKey=Parent->SubKeys[Index];
if (Attributes & OBJ_CASE_INSENSITIVE)
{
if( NameSize == CurKey->NameSize
&& !_strnicmp(KeyName,CurKey->Name,NameSize))
{
KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
return CurKey;
}
}
else
{
if( NameSize == CurKey->NameSize
&& !strncmp(KeyName,CurKey->Name,NameSize))
{
KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
return CurKey;
}
}
}
KeReleaseSpinLock(&CmiKeyListLock, OldIrql);
return NULL;
}

View file

@ -0,0 +1,233 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/cm/rtlfunc.c
* PURPOSE: Rtlxxx function for registry access
* UPDATE HISTORY:
*/
#include "cm.h"
NTSTATUS STDCALL
RtlCheckRegistryKey(IN ULONG RelativeTo,
IN PWSTR Path)
{
HANDLE KeyHandle;
NTSTATUS Status;
Status = RtlpGetRegistryHandle(RelativeTo,
Path,
FALSE,
&KeyHandle);
if (!NT_SUCCESS(Status))
return Status;
NtClose(KeyHandle);
return STATUS_SUCCESS;
}
NTSTATUS
STDCALL
RtlCreateRegistryKey (
IN ULONG RelativeTo,
IN PWSTR Path
)
{
HANDLE KeyHandle;
NTSTATUS Status;
Status = RtlpGetRegistryHandle(RelativeTo,
Path,
TRUE,
&KeyHandle);
if (!NT_SUCCESS(Status))
return Status;
NtClose(KeyHandle);
return STATUS_SUCCESS;
}
NTSTATUS
STDCALL
RtlDeleteRegistryValue (
IN ULONG RelativeTo,
IN PWSTR Path,
IN PWSTR ValueName
)
{
HANDLE KeyHandle;
NTSTATUS Status;
UNICODE_STRING Name;
Status = RtlpGetRegistryHandle(RelativeTo,
Path,
TRUE,
&KeyHandle);
if (!NT_SUCCESS(Status))
return Status;
RtlInitUnicodeString(&Name,
ValueName);
NtDeleteValueKey(KeyHandle,
&Name);
NtClose(KeyHandle);
return STATUS_SUCCESS;
}
NTSTATUS
STDCALL
RtlQueryRegistryValues (
IN ULONG RelativeTo,
IN PWSTR Path,
IN PRTL_QUERY_REGISTRY_TABLE QueryTable,
IN PVOID Context,
IN PVOID Environment
)
{
UNIMPLEMENTED;
}
NTSTATUS
STDCALL
RtlWriteRegistryValue (
IN ULONG RelativeTo,
IN PWSTR Path,
IN PWSTR ValueName,
IN ULONG ValueType,
IN PVOID ValueData,
IN ULONG ValueLength
)
{
HANDLE KeyHandle;
NTSTATUS Status;
UNICODE_STRING Name;
Status = RtlpGetRegistryHandle(RelativeTo,
Path,
TRUE,
&KeyHandle);
if (!NT_SUCCESS(Status))
return Status;
RtlInitUnicodeString(&Name,
ValueName);
NtSetValueKey(KeyHandle,
&Name,
0,
ValueType,
ValueData,
ValueLength);
NtClose(KeyHandle);
return STATUS_SUCCESS;
}
NTSTATUS STDCALL
RtlFormatCurrentUserKeyPath(IN OUT PUNICODE_STRING KeyPath)
{
return STATUS_UNSUCCESSFUL;
}
/* ------------------------------------------ Private Implementation */
NTSTATUS
RtlpGetRegistryHandle(ULONG RelativeTo,
PWSTR Path,
BOOLEAN Create,
PHANDLE KeyHandle)
{
UNICODE_STRING KeyName;
WCHAR KeyBuffer[MAX_PATH];
OBJECT_ATTRIBUTES ObjectAttributes;
NTSTATUS Status;
if (RelativeTo & RTL_REGISTRY_HANDLE)
{
*KeyHandle = (HANDLE)Path;
return STATUS_SUCCESS;
}
if (RelativeTo & RTL_REGISTRY_OPTIONAL)
RelativeTo &= ~RTL_REGISTRY_OPTIONAL;
if (RelativeTo >= RTL_REGISTRY_MAXIMUM)
return STATUS_INVALID_PARAMETER;
KeyName.Length = 0;
KeyName.MaximumLength = MAX_PATH;
KeyName.Buffer = KeyBuffer;
KeyBuffer[0] = 0;
switch (RelativeTo)
{
case RTL_REGISTRY_SERVICES:
RtlAppendUnicodeToString(&KeyName,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\");
break;
case RTL_REGISTRY_CONTROL:
RtlAppendUnicodeToString(&KeyName,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\");
break;
case RTL_REGISTRY_WINDOWS_NT:
RtlAppendUnicodeToString(&KeyName,
L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\");
break;
case RTL_REGISTRY_DEVICEMAP:
RtlAppendUnicodeToString(&KeyName,
L"\\Registry\\Machine\\Hardware\\DeviceMap\\");
break;
case RTL_REGISTRY_USER:
Status = RtlFormatCurrentUserKeyPath(&KeyName);
if (!NT_SUCCESS(Status))
return Status;
break;
}
if (Path[0] != L'\\')
RtlAppendUnicodeToString(&KeyName,
L"\\");
RtlAppendUnicodeToString(&KeyName,
Path);
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
if (Create == TRUE)
{
Status = NtCreateKey(KeyHandle,
KEY_ALL_ACCESS,
&ObjectAttributes,
0,
NULL,
0,
NULL);
}
else
{
Status = NtOpenKey(KeyHandle,
KEY_ALL_ACCESS,
&ObjectAttributes);
}
return Status;
}

View file

@ -1,4 +1,4 @@
/* $Id: create.c,v 1.43 2001/06/04 11:26:11 chorns Exp $
/* $Id: create.c,v 1.44 2001/06/14 21:05:07 jfilby Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -356,7 +356,8 @@ IoCreateFile(
{
return (STATUS_UNSUCCESSFUL);
}
Irp->UserIosb = IoStatusBlock; //return iostatus
Irp->AssociatedIrp.SystemBuffer = EaBuffer;
Irp->Tail.Overlay.AuxiliaryBuffer = (PCHAR)ExtraCreateParameters;
@ -395,6 +396,7 @@ IoCreateFile(
* immediately.
*/
Status = IofCallDriver(FileObject->DeviceObject, Irp );
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event,