From 94c0c4bab2c3f80298e8f71b8f9bb49013d841a8 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Thu, 15 Jun 2000 18:39:25 +0000 Subject: [PATCH] Improved symbolic links (reparsing). Implemented SystemRoot and DosDevices links. svn path=/trunk/; revision=1182 --- reactos/include/ddk/obtypes.h | 17 +++++++-- reactos/include/internal/ob.h | 3 +- reactos/ntoskrnl/io/iomgr.c | 29 ++++++++++----- reactos/ntoskrnl/io/symlink.c | 41 ++++++++++++++++----- reactos/ntoskrnl/ke/main.c | 21 ++++++++++- reactos/ntoskrnl/ldr/loader.c | 14 +++++--- reactos/ntoskrnl/ob/namespc.c | 29 ++++++++++----- reactos/ntoskrnl/ob/object.c | 68 +++++++++++++++++++++++++++-------- 8 files changed, 173 insertions(+), 49 deletions(-) diff --git a/reactos/include/ddk/obtypes.h b/reactos/include/ddk/obtypes.h index 0f183660809..47c171ce3f2 100644 --- a/reactos/include/ddk/obtypes.h +++ b/reactos/include/ddk/obtypes.h @@ -1,6 +1,6 @@ #ifndef _INCLUDE_DDK_OBTYPES_H #define _INCLUDE_DDK_OBTYPES_H -/* $Id: obtypes.h,v 1.7 2000/05/01 14:15:01 ea Exp $ */ +/* $Id: obtypes.h,v 1.8 2000/06/15 18:37:33 ekohl Exp $ */ struct _DIRECTORY_OBJECT; struct _OBJECT_ATTRIBUTES; @@ -79,11 +79,22 @@ typedef struct _OBJECT_TYPE * should be return when a leaf is reached and Path should be * left unchanged as a reault. */ - PVOID (*Parse)(PVOID ParsedObject, PWSTR* Path); +// PVOID (*Parse)(PVOID ParsedObject, PWSTR* Path); + + /* + * RETURNS + * STATUS_SUCCESS NextObject was found + * STATUS_UNSUCCESSFUL NextObject not found + * STATUS_REPARSE Path changed, restart parsing the path + */ + NTSTATUS (*Parse)(PVOID ParsedObject, + PVOID *NextObject, + PUNICODE_STRING FullPath, + PWSTR *Path); /* */ - NTSTATUS (*Security)(PVOID Object, + NTSTATUS (*Security)(PVOID Object, ULONG InfoClass, PVOID Info, PULONG InfoLength); diff --git a/reactos/include/internal/ob.h b/reactos/include/internal/ob.h index 1e58c204f06..d635a17d173 100644 --- a/reactos/include/internal/ob.h +++ b/reactos/include/internal/ob.h @@ -104,7 +104,8 @@ VOID ObCreateHandleTable(PEPROCESS Parent, PEPROCESS Process); NTSTATUS ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes, PVOID* ReturnedObject, - PWSTR* RemainingPath); + PUNICODE_STRING RemainingPath); +// PWSTR* RemainingPath); ULONG ObGetReferenceCount(PVOID Object); ULONG ObGetHandleCount(PVOID Object); diff --git a/reactos/ntoskrnl/io/iomgr.c b/reactos/ntoskrnl/io/iomgr.c index 6be5881188b..65c3071bcfb 100644 --- a/reactos/ntoskrnl/io/iomgr.c +++ b/reactos/ntoskrnl/io/iomgr.c @@ -1,4 +1,4 @@ -/* $Id: iomgr.c,v 1.10 2000/05/09 16:13:49 ekohl Exp $ +/* $Id: iomgr.c,v 1.11 2000/06/15 18:38:19 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -109,15 +109,16 @@ VOID IoInit (VOID) HANDLE handle; UNICODE_STRING UnicodeString; ANSI_STRING AnsiString; + UNICODE_STRING DeviceName; /* * Register iomgr types: DeviceObjectType */ IoDeviceObjectType = ExAllocatePool ( - NonPagedPool, + NonPagedPool, sizeof (OBJECT_TYPE) ); - + IoDeviceObjectType->TotalObjects = 0; IoDeviceObjectType->TotalHandles = 0; IoDeviceObjectType->MaxObjects = ULONG_MAX; @@ -126,14 +127,14 @@ VOID IoInit (VOID) IoDeviceObjectType->NonpagedPoolCharge = sizeof (DEVICE_OBJECT); IoDeviceObjectType->Dump = NULL; IoDeviceObjectType->Open = NULL; - IoDeviceObjectType->Close = NULL; + IoDeviceObjectType->Close = NULL; IoDeviceObjectType->Delete = NULL; IoDeviceObjectType->Parse = NULL; IoDeviceObjectType->Security = NULL; IoDeviceObjectType->QueryName = NULL; IoDeviceObjectType->OkayToClose = NULL; IoDeviceObjectType->Create = IopCreateDevice; - + RtlInitAnsiString ( & AnsiString, "Device" @@ -151,7 +152,7 @@ VOID IoInit (VOID) NonPagedPool, sizeof (OBJECT_TYPE) ); - + IoFileObjectType->TotalObjects = 0; IoFileObjectType->TotalHandles = 0; IoFileObjectType->MaxObjects = ULONG_MAX; @@ -167,7 +168,7 @@ VOID IoInit (VOID) IoFileObjectType->QueryName = NULL; IoFileObjectType->OkayToClose = NULL; IoFileObjectType->Create = IopCreateFile; - + RtlInitAnsiString ( & AnsiString, "File" @@ -202,6 +203,7 @@ VOID IoInit (VOID) 0, & attr ); + /* * Create the \?? directory */ @@ -226,13 +228,22 @@ VOID IoInit (VOID) 0, & attr ); - /* + /* * Initialize remaining subsubsystem */ IoInitCancelHandling (); IoInitSymbolicLinkImplementation (); IoInitFileSystemImplementation (); + + /* + * Create link from \DosDevices to \?? directory + */ + RtlInitUnicodeString (&UnicodeString, + L"\\DosDevices"); + RtlInitUnicodeString (&DeviceName, + L"\\??"); + IoCreateSymbolicLink (&UnicodeString, + &DeviceName); } - /* EOF */ diff --git a/reactos/ntoskrnl/io/symlink.c b/reactos/ntoskrnl/io/symlink.c index 57ade022b06..4696b4dabeb 100644 --- a/reactos/ntoskrnl/io/symlink.c +++ b/reactos/ntoskrnl/io/symlink.c @@ -1,4 +1,4 @@ -/* $Id: symlink.c,v 1.13 2000/06/13 15:51:13 ekohl Exp $ +/* $Id: symlink.c,v 1.14 2000/06/15 18:38:19 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -76,19 +76,22 @@ IopCreateSymbolicLink ( * * ARGUMENTS * - * RETURNN VALUE + * RETURN VALUE * * REVISIONS */ -PVOID +NTSTATUS IopParseSymbolicLink ( - PVOID Object, - PWSTR * RemainingPath + PVOID Object, + PVOID * NextObject, + PUNICODE_STRING FullPath, + PWSTR * RemainingPath ) { NTSTATUS Status; PSYMLNK_OBJECT SymlinkObject = (PSYMLNK_OBJECT) Object; PVOID ReturnedObject; + UNICODE_STRING TargetPath; Status = ObReferenceObjectByName( SymlinkObject->Target.ObjectName, @@ -102,11 +105,33 @@ IopParseSymbolicLink ( ); if (NT_SUCCESS(Status)) { - return ReturnedObject; + *NextObject = ReturnedObject; + return STATUS_SUCCESS; } - return NULL; -} + /* build the expanded path */ + TargetPath.MaximumLength = SymlinkObject->TargetName.Length + sizeof(WCHAR); + if (RemainingPath && *RemainingPath) + TargetPath.MaximumLength += (wcslen (*RemainingPath) * sizeof(WCHAR)); + TargetPath.Length = TargetPath.MaximumLength - sizeof(WCHAR); + TargetPath.Buffer = ExAllocatePool (NonPagedPool, + TargetPath.MaximumLength); + wcscpy (TargetPath.Buffer, SymlinkObject->TargetName.Buffer); + if (RemainingPath && *RemainingPath) + wcscat (TargetPath.Buffer, *RemainingPath); + + /* transfer target path buffer into FullPath */ + RtlFreeUnicodeString (FullPath); + FullPath->Length = TargetPath.Length; + FullPath->MaximumLength = TargetPath.MaximumLength; + FullPath->Buffer = TargetPath.Buffer; + + /* reinitialize RemainingPath for reparsing */ + *RemainingPath = FullPath->Buffer; + + *NextObject = NULL; + return STATUS_REPARSE; +} /********************************************************************** * NAME INTERNAL diff --git a/reactos/ntoskrnl/ke/main.c b/reactos/ntoskrnl/ke/main.c index 43427e58b39..7cc5a4f3b29 100644 --- a/reactos/ntoskrnl/ke/main.c +++ b/reactos/ntoskrnl/ke/main.c @@ -1,4 +1,4 @@ -/* $Id: main.c,v 1.46 2000/06/04 19:50:12 ekohl Exp $ +/* $Id: main.c,v 1.47 2000/06/15 18:39:04 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -49,6 +49,21 @@ PrintString (char* fmt,...) HalDisplayString (buffer); } +static void +CreateSystemRootLink (LPWSTR Device) +{ + UNICODE_STRING LinkName; + UNICODE_STRING DeviceName; + + RtlInitUnicodeString (&LinkName, + L"\\SystemRoot"); + + RtlInitUnicodeString (&DeviceName, + Device); + + IoCreateSymbolicLink (&LinkName, + &DeviceName); +} void set_breakpoint(unsigned int i, unsigned int addr, unsigned int type, unsigned int len) @@ -276,6 +291,10 @@ asmlinkage void _main(boot_param* _bp) start = start + bp.module_length[i]; } + /* Create the SystemRoot symbolic link */ + /* Hardcoded to 'C:\reactos' but this will change. */ + CreateSystemRootLink (L"\\Device\\Harddisk0\\Partition1\\reactos"); + /* * Load Auto configured drivers */ diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c index 50d6725ab34..bc466444624 100644 --- a/reactos/ntoskrnl/ldr/loader.c +++ b/reactos/ntoskrnl/ldr/loader.c @@ -1,4 +1,4 @@ -/* $Id: loader.c,v 1.54 2000/05/09 16:14:07 ekohl Exp $ +/* $Id: loader.c,v 1.55 2000/06/15 18:38:37 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -176,8 +176,7 @@ static VOID LdrLoadAutoConfigDriver (LPWSTR RelativeDriverName) DbgPrint("Loading %S\n",RelativeDriverName); - LdrGetSystemDirectory(TmpFileName, (MAX_PATH * sizeof(WCHAR))); - wcscat(TmpFileName, L"\\drivers\\"); + wcscpy(TmpFileName, L"\\SystemRoot\\system32\\drivers\\"); wcscat(TmpFileName, RelativeDriverName); RtlInitUnicodeString (&DriverName, TmpFileName); @@ -399,7 +398,8 @@ LdrOpenModule(PUNICODE_STRING Filename) UNICODE_STRING ModuleName; OBJECT_ATTRIBUTES ObjectAttributes; PMODULE_OBJECT ModuleObject; - PWSTR RemainingPath; + UNICODE_STRING RemainingPath; +// PWSTR RemainingPath; wcscpy(NameBuffer, MODULE_ROOT_NAME); if (wcsrchr(Filename->Buffer, '\\') != 0) @@ -416,17 +416,21 @@ LdrOpenModule(PUNICODE_STRING Filename) 0, NULL, NULL); + Status = ObFindObject(&ObjectAttributes, (PVOID *) &ModuleObject, &RemainingPath); CHECKPOINT; - if (NT_SUCCESS(Status) && (RemainingPath == NULL || *RemainingPath == 0)) + if (NT_SUCCESS(Status) && (RemainingPath.Buffer == NULL || *(RemainingPath.Buffer) == 0)) { DPRINT("Module %wZ at %p\n", Filename, ModuleObject); + RtlFreeUnicodeString (&RemainingPath); return ModuleObject; } + RtlFreeUnicodeString (&RemainingPath); + return NULL; } diff --git a/reactos/ntoskrnl/ob/namespc.c b/reactos/ntoskrnl/ob/namespc.c index e6dab5056eb..84c8f9cd9f4 100644 --- a/reactos/ntoskrnl/ob/namespc.c +++ b/reactos/ntoskrnl/ob/namespc.c @@ -37,7 +37,8 @@ NTSTATUS STDCALL ObReferenceObjectByName(PUNICODE_STRING ObjectPath, PVOID* ObjectPtr) { PVOID Object; - PWSTR RemainingPath; + UNICODE_STRING RemainingPath; +// PWSTR RemainingPath; OBJECT_ATTRIBUTES ObjectAttributes; InitializeObjectAttributes(&ObjectAttributes, @@ -49,13 +50,15 @@ NTSTATUS STDCALL ObReferenceObjectByName(PUNICODE_STRING ObjectPath, &Object, &RemainingPath); - if (RemainingPath != NULL || + if (RemainingPath.Buffer != NULL || Object == NULL) { *ObjectPtr = NULL; + RtlFreeUnicodeString (&RemainingPath); return(STATUS_UNSUCCESSFUL); } *ObjectPtr = Object; + RtlFreeUnicodeString (&RemainingPath); return(STATUS_SUCCESS); } @@ -129,17 +132,25 @@ PVOID ObpFindEntryDirectory(PDIRECTORY_OBJECT DirectoryObject, } -PVOID ObpParseDirectory(PVOID Object, PWSTR* Path) +NTSTATUS +ObpParseDirectory ( + PVOID Object, + PVOID * NextObject, + PUNICODE_STRING FullPath, + PWSTR * Path + ) { PWSTR end; PVOID FoundObject; DPRINT("ObpParseDirectory(Object %x, Path %x, *Path %S)\n", Object,Path,*Path); - + + *NextObject = NULL; + if ((*Path) == NULL) { - return(NULL); + return STATUS_UNSUCCESSFUL; } end = wcschr((*Path)+1, '\\'); @@ -156,7 +167,7 @@ PVOID ObpParseDirectory(PVOID Object, PWSTR* Path) { *end = '\\'; } - return(NULL); + return STATUS_UNSUCCESSFUL; } ObReferenceObjectByPointer(FoundObject, @@ -173,8 +184,10 @@ PVOID ObpParseDirectory(PVOID Object, PWSTR* Path) { *Path = NULL; } - - return(FoundObject); + + *NextObject = FoundObject; + + return STATUS_SUCCESS; } NTSTATUS ObpCreateDirectory(PVOID ObjectBody, diff --git a/reactos/ntoskrnl/ob/object.c b/reactos/ntoskrnl/ob/object.c index 07162647e50..0d3944b6296 100644 --- a/reactos/ntoskrnl/ob/object.c +++ b/reactos/ntoskrnl/ob/object.c @@ -1,4 +1,4 @@ -/* $Id: object.c,v 1.23 2000/05/09 21:30:06 ekohl Exp $ +/* $Id: object.c,v 1.24 2000/06/15 18:39:25 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -71,25 +71,38 @@ VOID ObInitializeObject(POBJECT_HEADER ObjectHeader, * DESCRIPTION * * ARGUMENTS + * ObjectAttributes + * + * ReturnedObject + * + * RemainigPath + * Pointer to a unicode string that will contain the + * remaining path if the function returns successfully. + * The caller must free the buffer after use by calling + * RtlFreeUnicodeString (). * * RETURN VALUE */ NTSTATUS ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes, PVOID* ReturnedObject, - PWSTR* RemainingPath) + PUNICODE_STRING RemainingPath) { PVOID NextObject; PVOID CurrentObject; + PVOID RootObject; POBJECT_HEADER CurrentHeader; NTSTATUS Status; PWSTR Path; PWSTR current; + UNICODE_STRING PathString; DPRINT("ObFindObject(ObjectAttributes %x, ReturnedObject %x, " "RemainingPath %x)\n",ObjectAttributes,ReturnedObject,RemainingPath); DPRINT("ObjectAttributes->ObjectName->Buffer %x\n", ObjectAttributes->ObjectName->Buffer); - + + RtlInitUnicodeString (RemainingPath, NULL); + if (ObjectAttributes->RootDirectory == NULL) { ObReferenceObjectByPointer(NameSpaceRoot, @@ -125,7 +138,18 @@ NTSTATUS ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes, return(STATUS_UNSUCCESSFUL); } - current = Path; + if (Path) + { + RtlCreateUnicodeString (&PathString, Path); + current = PathString.Buffer; + } + else + { + RtlInitUnicodeString (&PathString, NULL); + current = NULL; + } + + RootObject = CurrentObject; while (TRUE) { @@ -136,8 +160,17 @@ NTSTATUS ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes, DPRINT("Current object can't parse\n"); break; } - NextObject = CurrentHeader->ObjectType->Parse(CurrentObject, - ¤t); + Status = CurrentHeader->ObjectType->Parse(CurrentObject, + &NextObject, + &PathString, + ¤t); + if (Status == STATUS_REPARSE) + { + /* reparse the object path */ + NextObject = RootObject; + current = PathString.Buffer; + } + if (NextObject == NULL) { break; @@ -146,7 +179,9 @@ NTSTATUS ObFindObject(POBJECT_ATTRIBUTES ObjectAttributes, CurrentObject = NextObject; } - *RemainingPath = current; + if (current) + RtlCreateUnicodeString (RemainingPath, current); + RtlFreeUnicodeString (&PathString); *ReturnedObject = CurrentObject; return(STATUS_SUCCESS); @@ -169,7 +204,7 @@ PVOID STDCALL ObCreateObject(PHANDLE Handle, POBJECT_TYPE Type) { PVOID Parent = NULL; - PWSTR RemainingPath = NULL; + UNICODE_STRING RemainingPath; POBJECT_HEADER Header; NTSTATUS Status; @@ -190,13 +225,16 @@ PVOID STDCALL ObCreateObject(PHANDLE Handle, &Parent, &RemainingPath); } - + else + { + RtlInitUnicodeString (&RemainingPath, NULL); + } Header = (POBJECT_HEADER)ExAllocatePool(NonPagedPool, OBJECT_ALLOC_SIZE(Type)); - ObInitializeObject(Header, - Handle, - DesiredAccess, - Type, + ObInitializeObject(Header, + Handle, + DesiredAccess, + Type, ObjectAttributes); if (Header->ObjectType != NULL && Header->ObjectType->Create != NULL) @@ -205,16 +243,18 @@ PVOID STDCALL ObCreateObject(PHANDLE Handle, DPRINT("Calling %x\n", Header->ObjectType->Create); Status = Header->ObjectType->Create(HEADER_TO_BODY(Header), Parent, - RemainingPath, + RemainingPath.Buffer, ObjectAttributes); if (!NT_SUCCESS(Status)) { ObDereferenceObject( Parent ); RtlFreeUnicodeString( &Header->Name ); + RtlFreeUnicodeString( &RemainingPath ); ExFreePool( Header ); return(NULL); } } + RtlFreeUnicodeString( &RemainingPath ); return(HEADER_TO_BODY(Header)); }