From a1f144f35b057783959e7c9f862ea38e6334cc00 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Wed, 3 Sep 2003 16:16:04 +0000 Subject: [PATCH] Implemented/fixed QueryDosDevice[A/W]. svn path=/trunk/; revision=5967 --- reactos/lib/kernel32/file/dosdev.c | 212 +++++++++++++++++++++++------ 1 file changed, 169 insertions(+), 43 deletions(-) diff --git a/reactos/lib/kernel32/file/dosdev.c b/reactos/lib/kernel32/file/dosdev.c index 6c64ea2d9db..84705f76ff0 100644 --- a/reactos/lib/kernel32/file/dosdev.c +++ b/reactos/lib/kernel32/file/dosdev.c @@ -1,4 +1,4 @@ -/* $Id: dosdev.c,v 1.7 2003/07/10 18:50:51 chorns Exp $ +/* $Id: dosdev.c,v 1.8 2003/09/03 16:16:04 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -9,8 +9,15 @@ * Created 01/11/98 */ +/* INCLUDES ******************************************************************/ + #include +#define NDEBUG +#include + + +/* FUNCTIONS *****************************************************************/ /* * @implemented @@ -49,46 +56,6 @@ DefineDosDeviceA( } - -/* - * @implemented - */ -DWORD -STDCALL -QueryDosDeviceA( - LPCSTR lpDeviceName, - LPSTR lpTargetPath, - DWORD ucchMax - ) -{ - ULONG i; - - WCHAR DeviceNameW[MAX_PATH]; - WCHAR TargetPathW[MAX_PATH]; - - - - i = 0; - while ((*lpDeviceName)!=0 && i < MAX_PATH) - { - DeviceNameW[i] = *lpDeviceName; - lpDeviceName++; - i++; - } - DeviceNameW[i] = 0; - - i = 0; - while ((*lpTargetPath)!=0 && i < MAX_PATH) - { - TargetPathW[i] = *lpTargetPath; - lpTargetPath++; - i++; - } - TargetPathW[i] = 0; - return QueryDosDeviceW(DeviceNameW,TargetPathW,ucchMax); -} - - /* * @unimplemented */ @@ -105,7 +72,71 @@ DefineDosDeviceW( /* - * @unimplemented + * @implemented + */ +DWORD +STDCALL +QueryDosDeviceA( + LPCSTR lpDeviceName, + LPSTR lpTargetPath, + DWORD ucchMax + ) +{ + UNICODE_STRING DeviceNameU; + UNICODE_STRING TargetPathU; + ANSI_STRING TargetPathA; + DWORD Length; + + if (!RtlCreateUnicodeStringFromAsciiz (&DeviceNameU, + (LPSTR)lpDeviceName)) + { + SetLastError (ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + + TargetPathU.Length = 0; + TargetPathU.MaximumLength = (USHORT)ucchMax * sizeof(WCHAR); + TargetPathU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (), + 0, + TargetPathU.MaximumLength); + if (TargetPathU.Buffer == NULL) + { + SetLastError (ERROR_NOT_ENOUGH_MEMORY); + return 0; + } + + Length = QueryDosDeviceW (DeviceNameU.Buffer, + TargetPathU.Buffer, + ucchMax); + if (Length != 0) + { + TargetPathU.Length = (Length - 1) * sizeof(WCHAR); + + TargetPathA.Length = 0; + TargetPathA.MaximumLength = (USHORT)ucchMax; + TargetPathA.Buffer = lpTargetPath; + + RtlUnicodeStringToAnsiString (&TargetPathA, + &TargetPathU, + FALSE); + + DPRINT ("TargetPathU: '%wZ'\n", &TargetPathU); + DPRINT ("TargetPathA: '%Z'\n", &TargetPathA); + } + + RtlFreeHeap (RtlGetProcessHeap (), + 0, + TargetPathU.Buffer); + RtlFreeHeap (RtlGetProcessHeap (), + 0, + DeviceNameU.Buffer); + + return Length; +} + + +/* + * @implemented */ DWORD STDCALL @@ -115,7 +146,102 @@ QueryDosDeviceW( DWORD ucchMax ) { - return FALSE; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING UnicodeString; + HANDLE DirectoryHandle; + HANDLE DeviceHandle; + ULONG ReturnedLength; + ULONG Length; + NTSTATUS Status; + + /* Open the '\??' directory */ + RtlInitUnicodeString (&UnicodeString, + L"\\??"); + InitializeObjectAttributes (&ObjectAttributes, + &UnicodeString, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = NtOpenDirectoryObject (&DirectoryHandle, + DIRECTORY_QUERY, + &ObjectAttributes); + if (!NT_SUCCESS (Status)) + { + DPRINT ("NtOpenDirectoryObject() failed (Status %lx)\n", Status); + SetLastErrorByStatus (Status); + return 0; + } + + Length = 0; + + if (lpDeviceName != NULL) + { + /* Open the lpDeviceName link object */ + RtlInitUnicodeString (&UnicodeString, + (PWSTR)lpDeviceName); + InitializeObjectAttributes (&ObjectAttributes, + &UnicodeString, + OBJ_CASE_INSENSITIVE, + DirectoryHandle, + NULL); + Status = NtOpenSymbolicLinkObject (&DeviceHandle, + SYMBOLIC_LINK_QUERY, + &ObjectAttributes); + if (!NT_SUCCESS (Status)) + { + DPRINT ("NtOpenSymbolicLinkObject() failed (Status %lx)\n", Status); + NtClose (DirectoryHandle); + SetLastErrorByStatus (Status); + return 0; + } + + /* Query link target */ + UnicodeString.Length = 0; + UnicodeString.MaximumLength = (USHORT)ucchMax * sizeof(WCHAR); + UnicodeString.Buffer = lpTargetPath; + + ReturnedLength = 0; + Status = NtQuerySymbolicLinkObject (DeviceHandle, + &UnicodeString, + &ReturnedLength); + NtClose (DeviceHandle); + if (!NT_SUCCESS (Status)) + { + DPRINT ("NtQuerySymbolicLinkObject() failed (Status %lx)\n", Status); + NtClose (DirectoryHandle); + SetLastErrorByStatus (Status); + return 0; + } + + DPRINT ("ReturnedLength: %lu\n", ReturnedLength); + DPRINT ("TargetLength: %hu\n", UnicodeString.Length); + DPRINT ("Target: '%wZ'\n", &UnicodeString); + + Length = ReturnedLength / sizeof(WCHAR); + if (Length <= ucchMax) + { + lpTargetPath[Length] = 0; + } + else + { + DPRINT ("Buffer is too small\n"); + NtClose (DirectoryHandle); + SetLastErrorByStatus (STATUS_BUFFER_TOO_SMALL); + return 0; + } + } + else + { + /* FIXME */ + DPRINT1 ("Not implemented yet\n"); + NtClose (DirectoryHandle); + SetLastErrorByStatus (STATUS_NOT_IMPLEMENTED); + return 0; + } + + NtClose (DirectoryHandle); + + return Length; } /* EOF */