-/* $Id: symlink.c,v 1.31 2002/09/08 10:23:26 chorns Exp $
+/* $Id: symlink.c,v 1.32 2003/02/25 16:48:32 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
/* INCLUDES *****************************************************************/
-#include <limits.h>
#include <ddk/ntddk.h>
-#include <internal/pool.h>
+#include <internal/se.h>
#define NDEBUG
#include <internal/debug.h>
-/* GLOBALS ******************************************************************/
-
-typedef struct
-{
- CSHORT Type;
- CSHORT Size;
- UNICODE_STRING TargetName;
- OBJECT_ATTRIBUTES Target;
-} SYMLNK_OBJECT, *PSYMLNK_OBJECT;
-
-POBJECT_TYPE IoSymbolicLinkType = NULL;
-
-static GENERIC_MAPPING IopSymbolicLinkMapping = {
- 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
- * IopCreateSymbolicLink
- *
- * DESCRIPTION
- *
- * ARGUMENTS
- *
- * RETURNN VALUE
- * Status.
- *
- * REVISIONS
- */
-NTSTATUS STDCALL
-IopCreateSymbolicLink(PVOID Object,
- PVOID Parent,
- PWSTR RemainingPath,
- POBJECT_ATTRIBUTES ObjectAttributes)
-{
- return(STATUS_SUCCESS);
-}
+/* FUNCTIONS ****************************************************************/
/**********************************************************************
- * NAME INTERNAL
- * IopParseSymbolicLink
+ * NAME EXPORTED
+ * IoCreateSymbolicLink
*
* DESCRIPTION
*
* RETURN VALUE
*
* REVISIONS
+ *
*/
NTSTATUS STDCALL
-IopParseSymbolicLink(PVOID Object,
- PVOID * NextObject,
- PUNICODE_STRING FullPath,
- PWSTR * RemainingPath,
- ULONG Attributes)
+IoCreateSymbolicLink(PUNICODE_STRING SymbolicLinkName,
+ PUNICODE_STRING DeviceName)
{
- PSYMLNK_OBJECT SymlinkObject = (PSYMLNK_OBJECT) Object;
- UNICODE_STRING TargetPath;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE Handle;
+ NTSTATUS Status;
- DPRINT("IopParseSymbolicLink (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;
- }
+ assert_irql(PASSIVE_LEVEL);
- /* 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);
- }
+ DPRINT("IoCreateSymbolicLink(SymbolicLinkName %wZ, DeviceName %wZ)\n",
+ SymbolicLinkName,
+ DeviceName);
- /* transfer target path buffer into FullPath */
- RtlFreeUnicodeString(FullPath);
- FullPath->Length = TargetPath.Length;
- FullPath->MaximumLength = TargetPath.MaximumLength;
- FullPath->Buffer = TargetPath.Buffer;
+ InitializeObjectAttributes(&ObjectAttributes,
+ SymbolicLinkName,
+ OBJ_PERMANENT,
+ NULL,
+ SePublicDefaultSd);
- /* reinitialize RemainingPath for reparsing */
- *RemainingPath = FullPath->Buffer;
+ Status = NtCreateSymbolicLinkObject(&Handle,
+ SYMBOLIC_LINK_ALL_ACCESS,
+ &ObjectAttributes,
+ DeviceName);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtCreateSymbolicLinkObject() failed (Status %lx)\n", Status);
+ return(Status);
+ }
- *NextObject = NULL;
- return STATUS_REPARSE;
-}
+ NtClose(Handle);
-/**********************************************************************
- * NAME INTERNAL
- * IoInitSymbolicLinkImplementation
- *
- * DESCRIPTION
- *
- * ARGUMENTS
- * None.
- *
- * RETURNN VALUE
- * None.
- *
- * REVISIONS
- */
-VOID IoInitSymbolicLinkImplementation (VOID)
-{
- IoSymbolicLinkType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
-
- IoSymbolicLinkType->Tag = TAG('S', 'Y', 'M', 'T');
- IoSymbolicLinkType->TotalObjects = 0;
- IoSymbolicLinkType->TotalHandles = 0;
- IoSymbolicLinkType->MaxObjects = ULONG_MAX;
- IoSymbolicLinkType->MaxHandles = ULONG_MAX;
- IoSymbolicLinkType->PagedPoolCharge = 0;
- IoSymbolicLinkType->NonpagedPoolCharge = sizeof (SYMLNK_OBJECT);
- IoSymbolicLinkType->Mapping = &IopSymbolicLinkMapping;
- IoSymbolicLinkType->Dump = NULL;
- IoSymbolicLinkType->Open = NULL;
- IoSymbolicLinkType->Close = NULL;
- IoSymbolicLinkType->Delete = NULL;
- IoSymbolicLinkType->Parse = IopParseSymbolicLink;
- IoSymbolicLinkType->Security = NULL;
- IoSymbolicLinkType->QueryName = NULL;
- IoSymbolicLinkType->OkayToClose = NULL;
- IoSymbolicLinkType->Create = IopCreateSymbolicLink;
- IoSymbolicLinkType->DuplicationNotify = NULL;
-
- RtlInitUnicodeStringFromLiteral(&IoSymbolicLinkType->TypeName,
- L"SymbolicLink");
+ return(STATUS_SUCCESS);
}
/**********************************************************************
* NAME EXPORTED
- * NtOpenSymbolicLinkObject
+ * IoCreateUnprotectedSymbolicLink
*
* DESCRIPTION
*
*
*/
NTSTATUS STDCALL
-NtOpenSymbolicLinkObject(OUT PHANDLE LinkHandle,
- IN ACCESS_MASK DesiredAccess,
- IN POBJECT_ATTRIBUTES ObjectAttributes)
+IoCreateUnprotectedSymbolicLink(PUNICODE_STRING SymbolicLinkName,
+ PUNICODE_STRING DeviceName)
{
- DPRINT("NtOpenSymbolicLinkObject (Name %wZ)\n",
- ObjectAttributes->ObjectName);
+ SECURITY_DESCRIPTOR SecurityDescriptor;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE Handle;
+ NTSTATUS Status;
- return(ObOpenObjectByName(ObjectAttributes,
- IoSymbolicLinkType,
- NULL,
- UserMode,
- DesiredAccess,
- NULL,
- LinkHandle));
-}
+ assert_irql(PASSIVE_LEVEL);
+ DPRINT("IoCreateUnprotectedSymbolicLink(SymbolicLinkName %wZ, DeviceName %wZ)\n",
+ SymbolicLinkName,
+ DeviceName);
-/**********************************************************************
- * 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,
- IoSymbolicLinkType,
- UserMode,
- (PVOID *)&SymlinkObject,
- NULL);
+ Status = RtlCreateSecurityDescriptor(&SecurityDescriptor,
+ SECURITY_DESCRIPTOR_REVISION);
if (!NT_SUCCESS(Status))
{
+ DPRINT1("RtlCreateSecurityDescriptor() failed (Status %lx)\n", Status);
return(Status);
}
-
- RtlCopyUnicodeString(LinkTarget,
- SymlinkObject->Target.ObjectName);
- if (ReturnedLength != NULL)
+
+ Status = RtlSetDaclSecurityDescriptor(&SecurityDescriptor,
+ TRUE,
+ NULL,
+ TRUE);
+ if (!NT_SUCCESS(Status))
{
- *ReturnedLength = SymlinkObject->Target.Length;
+ DPRINT1("RtlSetDaclSecurityDescriptor() failed (Status %lx)\n", Status);
+ return(Status);
}
- ObDereferenceObject(SymlinkObject);
-
- return(STATUS_SUCCESS);
-}
-
-
-/**********************************************************************
- * NAME EXPORTED
- * IoCreateUnprotectedSymbolicLink
- *
- * DESCRIPTION
- *
- * ARGUMENTS
- *
- * RETURN VALUE
- *
- * REVISIONS
- *
- */
-NTSTATUS STDCALL
-IoCreateUnprotectedSymbolicLink(PUNICODE_STRING SymbolicLinkName,
- PUNICODE_STRING DeviceName)
-{
- return(IoCreateSymbolicLink(SymbolicLinkName,
- DeviceName));
-}
+ InitializeObjectAttributes(&ObjectAttributes,
+ SymbolicLinkName,
+ OBJ_PERMANENT,
+ NULL,
+ &SecurityDescriptor);
-/**********************************************************************
- * NAME EXPORTED
- * IoCreateSymbolicLink
- *
- * DESCRIPTION
- *
- * ARGUMENTS
- *
- * RETURN VALUE
- *
- * REVISIONS
- *
- */
-NTSTATUS STDCALL
-IoCreateSymbolicLink(PUNICODE_STRING SymbolicLinkName,
- PUNICODE_STRING DeviceName)
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- PSYMLNK_OBJECT SymbolicLink;
- NTSTATUS Status;
-
- assert_irql(PASSIVE_LEVEL);
+ Status = NtCreateSymbolicLinkObject(&Handle,
+ SYMBOLIC_LINK_ALL_ACCESS,
+ &ObjectAttributes,
+ DeviceName);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NtCreateSymbolicLinkObject() failed (Status %lx)\n", Status);
+ return(Status);
+ }
- DPRINT(
- "IoCreateSymbolicLink(SymbolicLinkName %S, DeviceName %S)\n",
- SymbolicLinkName->Buffer,
- DeviceName->Buffer
- );
+ NtClose(Handle);
- InitializeObjectAttributes(
- & ObjectAttributes,
- SymbolicLinkName,
- OBJ_PERMANENT,
- NULL,
- NULL
- );
- Status = ObCreateObject(
- NULL,
- SYMBOLIC_LINK_ALL_ACCESS,
- & ObjectAttributes,
- IoSymbolicLinkType,
- (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;
+ return(STATUS_SUCCESS);
}
return(Status);
}
-
-/**********************************************************************
- * NAME (EXPORTED as Zw)
- * 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 %S)\n",
- SymbolicLinkHandle,
- DesiredAccess,
- ObjectAttributes,
- DeviceName->Buffer);
-
- Status = ObCreateObject(SymbolicLinkHandle,
- DesiredAccess,
- ObjectAttributes,
- IoSymbolicLinkType,
- (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);
-}
-
/* EOF */
--- /dev/null
+/* $Id: symlink.c,v 1.1 2003/02/25 16:49:08 ekohl Exp $
+ *
+ * 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 <limits.h>
+#include <ddk/ntddk.h>
+#include <internal/ob.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+/* 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 */