X-Git-Url: http://git.jankratochvil.net/?p=reactos.git;a=blobdiff_plain;f=ntoskrnl%2Fob%2Fsymlink.c;fp=ntoskrnl%2Fob%2Fsymlink.c;h=83cf74f316b27982fa0e1b906e44bba3e2a0f55a;hp=0000000000000000000000000000000000000000;hb=7c0db166f81fbe8c8b913d7f26048e337d383605;hpb=e3ed2d773259cc445c7ff8181ebd934931365328 diff --git a/ntoskrnl/ob/symlink.c b/ntoskrnl/ob/symlink.c new file mode 100644 index 0000000..83cf74f --- /dev/null +++ b/ntoskrnl/ob/symlink.c @@ -0,0 +1,339 @@ +/* $Id$ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/ob/symlink.c + * PURPOSE: Implements symbolic links + * PROGRAMMER: David Welch (welch@mcmail.com) + * UPDATE HISTORY: + * Created 22/05/98 + */ + +/* INCLUDES *****************************************************************/ + +#include +#include +#include + +#define NDEBUG +#include + +/* GLOBALS ******************************************************************/ + +typedef struct +{ + CSHORT Type; + CSHORT Size; + UNICODE_STRING TargetName; + OBJECT_ATTRIBUTES Target; +} SYMLNK_OBJECT, *PSYMLNK_OBJECT; + +POBJECT_TYPE ObSymbolicLinkType = NULL; + +static GENERIC_MAPPING ObpSymbolicLinkMapping = { + STANDARD_RIGHTS_READ|SYMBOLIC_LINK_QUERY, + STANDARD_RIGHTS_WRITE, + STANDARD_RIGHTS_EXECUTE|SYMBOLIC_LINK_QUERY, + SYMBOLIC_LINK_ALL_ACCESS}; + +#define TAG_SYMLINK_TTARGET TAG('S', 'Y', 'T', 'T') +#define TAG_SYMLINK_TARGET TAG('S', 'Y', 'M', 'T') + +/* FUNCTIONS ****************************************************************/ + + +/********************************************************************** + * NAME INTERNAL + * ObpCreateSymbolicLink + * + * DESCRIPTION + * + * ARGUMENTS + * + * RETURNN VALUE + * Status. + * + * REVISIONS + */ +NTSTATUS STDCALL +ObpCreateSymbolicLink(PVOID Object, + PVOID Parent, + PWSTR RemainingPath, + POBJECT_ATTRIBUTES ObjectAttributes) +{ + return(STATUS_SUCCESS); +} + + +/********************************************************************** + * NAME INTERNAL + * ObpDeleteSymbolicLink + * + * DESCRIPTION + * + * ARGUMENTS + * + * RETURNN VALUE + * Status. + * + * REVISIONS + */ +VOID STDCALL +ObpDeleteSymbolicLink(PVOID ObjectBody) +{ + PSYMLNK_OBJECT SymlinkObject = (PSYMLNK_OBJECT)ObjectBody; + + RtlFreeUnicodeString(&SymlinkObject->TargetName); +} + + +/********************************************************************** + * NAME INTERNAL + * ObpParseSymbolicLink + * + * DESCRIPTION + * + * ARGUMENTS + * + * RETURN VALUE + * + * REVISIONS + */ +NTSTATUS STDCALL +ObpParseSymbolicLink(PVOID Object, + PVOID * NextObject, + PUNICODE_STRING FullPath, + PWSTR * RemainingPath, + ULONG Attributes) +{ + PSYMLNK_OBJECT SymlinkObject = (PSYMLNK_OBJECT) Object; + UNICODE_STRING TargetPath; + + DPRINT("ObpParseSymbolicLink (RemainingPath %S)\n", *RemainingPath); + + /* + * Stop parsing if the entire path has been parsed and + * the desired object is a symbolic link object. + */ + if (((*RemainingPath == NULL) || (**RemainingPath == 0)) && + (Attributes & OBJ_OPENLINK)) + { + DPRINT("Parsing stopped!\n"); + *NextObject = NULL; + return(STATUS_SUCCESS); + } + + /* 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 = ExAllocatePoolWithTag(NonPagedPool, + TargetPath.MaximumLength, + TAG_SYMLINK_TTARGET); + 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 + * ObInitSymbolicLinkImplementation + * + * DESCRIPTION + * + * ARGUMENTS + * None. + * + * RETURNN VALUE + * None. + * + * REVISIONS + */ +VOID ObInitSymbolicLinkImplementation (VOID) +{ + ObSymbolicLinkType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE)); + + ObSymbolicLinkType->Tag = TAG('S', 'Y', 'M', 'T'); + ObSymbolicLinkType->TotalObjects = 0; + ObSymbolicLinkType->TotalHandles = 0; + ObSymbolicLinkType->MaxObjects = ULONG_MAX; + ObSymbolicLinkType->MaxHandles = ULONG_MAX; + ObSymbolicLinkType->PagedPoolCharge = 0; + ObSymbolicLinkType->NonpagedPoolCharge = sizeof(SYMLNK_OBJECT); + ObSymbolicLinkType->Mapping = &ObpSymbolicLinkMapping; + ObSymbolicLinkType->Dump = NULL; + ObSymbolicLinkType->Open = NULL; + ObSymbolicLinkType->Close = NULL; + ObSymbolicLinkType->Delete = ObpDeleteSymbolicLink; + ObSymbolicLinkType->Parse = ObpParseSymbolicLink; + ObSymbolicLinkType->Security = NULL; + ObSymbolicLinkType->QueryName = NULL; + ObSymbolicLinkType->OkayToClose = NULL; + ObSymbolicLinkType->Create = ObpCreateSymbolicLink; + ObSymbolicLinkType->DuplicationNotify = NULL; + + RtlInitUnicodeStringFromLiteral(&ObSymbolicLinkType->TypeName, + L"SymbolicLink"); + + ObpCreateTypeObject(ObSymbolicLinkType); +} + + +/********************************************************************** + * NAME EXPORTED + * NtCreateSymbolicLinkObject + * + * DESCRIPTION + * + * ARGUMENTS + * + * RETURN VALUE + * + * REVISIONS + * + */ +NTSTATUS STDCALL +NtCreateSymbolicLinkObject(OUT PHANDLE SymbolicLinkHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes, + IN PUNICODE_STRING DeviceName) +{ + PSYMLNK_OBJECT SymbolicLink; + NTSTATUS Status; + + assert_irql(PASSIVE_LEVEL); + + DPRINT("NtCreateSymbolicLinkObject(SymbolicLinkHandle %p, DesiredAccess %ul, ObjectAttributes %p, DeviceName %wZ)\n", + SymbolicLinkHandle, + DesiredAccess, + ObjectAttributes, + DeviceName); + + Status = ObCreateObject(SymbolicLinkHandle, + DesiredAccess, + ObjectAttributes, + ObSymbolicLinkType, + (PVOID*)&SymbolicLink); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + + SymbolicLink->TargetName.Length = 0; + SymbolicLink->TargetName.MaximumLength = + ((wcslen(DeviceName->Buffer) + 1) * sizeof(WCHAR)); + SymbolicLink->TargetName.Buffer = + ExAllocatePoolWithTag(NonPagedPool, + SymbolicLink->TargetName.MaximumLength, + TAG_SYMLINK_TARGET); + RtlCopyUnicodeString(&SymbolicLink->TargetName, + DeviceName); + + DPRINT("DeviceName %S\n", SymbolicLink->TargetName.Buffer); + + InitializeObjectAttributes(&SymbolicLink->Target, + &SymbolicLink->TargetName, + 0, + NULL, + NULL); + + DPRINT("%s() = STATUS_SUCCESS\n",__FUNCTION__); + ObDereferenceObject(SymbolicLink); + + return(STATUS_SUCCESS); +} + + +/********************************************************************** + * NAME EXPORTED + * NtOpenSymbolicLinkObject + * + * DESCRIPTION + * + * ARGUMENTS + * + * RETURN VALUE + * + * REVISIONS + * + */ +NTSTATUS STDCALL +NtOpenSymbolicLinkObject(OUT PHANDLE LinkHandle, + IN ACCESS_MASK DesiredAccess, + IN POBJECT_ATTRIBUTES ObjectAttributes) +{ + DPRINT("NtOpenSymbolicLinkObject (Name %wZ)\n", + ObjectAttributes->ObjectName); + + return(ObOpenObjectByName(ObjectAttributes, + ObSymbolicLinkType, + NULL, + KeGetPreviousMode(), + DesiredAccess, + NULL, + LinkHandle)); +} + + +/********************************************************************** + * NAME EXPORTED + * NtQuerySymbolicLinkObject + * + * DESCRIPTION + * + * ARGUMENTS + * + * RETURN VALUE + * + * REVISIONS + * + */ +NTSTATUS STDCALL +NtQuerySymbolicLinkObject(IN HANDLE LinkHandle, + IN OUT PUNICODE_STRING LinkTarget, + OUT PULONG ReturnedLength OPTIONAL) +{ + PSYMLNK_OBJECT SymlinkObject; + NTSTATUS Status; + + Status = ObReferenceObjectByHandle(LinkHandle, + SYMBOLIC_LINK_QUERY, + ObSymbolicLinkType, + KeGetPreviousMode(), + (PVOID *)&SymlinkObject, + NULL); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + + RtlCopyUnicodeString(LinkTarget, + SymlinkObject->Target.ObjectName); + if (ReturnedLength != NULL) + { + *ReturnedLength = SymlinkObject->Target.Length; + } + ObDereferenceObject(SymlinkObject); + + return(STATUS_SUCCESS); +} + +/* EOF */