Implemented device enumeration in QueryDosDeviceW().

svn path=/trunk/; revision=5969
This commit is contained in:
Eric Kohl 2003-09-03 22:28:40 +00:00
parent 89fc578c5f
commit fef7f78541

View file

@ -1,4 +1,4 @@
/* $Id: dosdev.c,v 1.8 2003/09/03 16:16:04 ekohl Exp $ /* $Id: dosdev.c,v 1.9 2003/09/03 22:28:40 ekohl Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * PROJECT: ReactOS system libraries
@ -30,29 +30,39 @@ DefineDosDeviceA(
LPCSTR lpTargetPath LPCSTR lpTargetPath
) )
{ {
ULONG i; UNICODE_STRING DeviceNameU;
UNICODE_STRING TargetPathU;
BOOL Result;
WCHAR DeviceNameW[MAX_PATH]; if (!RtlCreateUnicodeStringFromAsciiz (&DeviceNameU,
WCHAR TargetPathW[MAX_PATH]; (LPSTR)lpDeviceName))
{
SetLastError (ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
i = 0; if (!RtlCreateUnicodeStringFromAsciiz (&TargetPathU,
while ((*lpDeviceName)!=0 && i < MAX_PATH) (LPSTR)lpTargetPath))
{ {
DeviceNameW[i] = *lpDeviceName; RtlFreeHeap (RtlGetProcessHeap (),
lpDeviceName++; 0,
i++; DeviceNameU.Buffer);
} SetLastError (ERROR_NOT_ENOUGH_MEMORY);
DeviceNameW[i] = 0; return 0;
}
i = 0; Result = DefineDosDeviceW (dwFlags,
while ((*lpTargetPath)!=0 && i < MAX_PATH) DeviceNameU.Buffer,
{ TargetPathU.Buffer);
TargetPathW[i] = *lpTargetPath;
lpTargetPath++; RtlFreeHeap (RtlGetProcessHeap (),
i++; 0,
} TargetPathU.Buffer);
TargetPathW[i] = 0; RtlFreeHeap (RtlGetProcessHeap (),
return DefineDosDeviceW(dwFlags,DeviceNameW,TargetPathW); 0,
DeviceNameU.Buffer);
return Result;
} }
@ -110,7 +120,7 @@ QueryDosDeviceA(
ucchMax); ucchMax);
if (Length != 0) if (Length != 0)
{ {
TargetPathU.Length = (Length - 1) * sizeof(WCHAR); TargetPathU.Length = Length * sizeof(WCHAR);
TargetPathA.Length = 0; TargetPathA.Length = 0;
TargetPathA.MaximumLength = (USHORT)ucchMax; TargetPathA.MaximumLength = (USHORT)ucchMax;
@ -146,13 +156,19 @@ QueryDosDeviceW(
DWORD ucchMax DWORD ucchMax
) )
{ {
PDIRECTORY_BASIC_INFORMATION DirInfo;
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING UnicodeString; UNICODE_STRING UnicodeString;
HANDLE DirectoryHandle; HANDLE DirectoryHandle;
HANDLE DeviceHandle; HANDLE DeviceHandle;
ULONG ReturnedLength; ULONG ReturnLength;
ULONG NameLength;
ULONG Length; ULONG Length;
ULONG Context;
BOOLEAN RestartScan;
NTSTATUS Status; NTSTATUS Status;
UCHAR Buffer[512];
PWSTR Ptr;
/* Open the '\??' directory */ /* Open the '\??' directory */
RtlInitUnicodeString (&UnicodeString, RtlInitUnicodeString (&UnicodeString,
@ -200,46 +216,98 @@ QueryDosDeviceW(
UnicodeString.MaximumLength = (USHORT)ucchMax * sizeof(WCHAR); UnicodeString.MaximumLength = (USHORT)ucchMax * sizeof(WCHAR);
UnicodeString.Buffer = lpTargetPath; UnicodeString.Buffer = lpTargetPath;
ReturnedLength = 0; ReturnLength = 0;
Status = NtQuerySymbolicLinkObject (DeviceHandle, Status = NtQuerySymbolicLinkObject (DeviceHandle,
&UnicodeString, &UnicodeString,
&ReturnedLength); &ReturnLength);
NtClose (DeviceHandle); NtClose (DeviceHandle);
NtClose (DirectoryHandle);
if (!NT_SUCCESS (Status)) if (!NT_SUCCESS (Status))
{ {
DPRINT ("NtQuerySymbolicLinkObject() failed (Status %lx)\n", Status); DPRINT ("NtQuerySymbolicLinkObject() failed (Status %lx)\n", Status);
NtClose (DirectoryHandle);
SetLastErrorByStatus (Status); SetLastErrorByStatus (Status);
return 0; return 0;
} }
DPRINT ("ReturnedLength: %lu\n", ReturnedLength); DPRINT ("ReturnLength: %lu\n", ReturnLength);
DPRINT ("TargetLength: %hu\n", UnicodeString.Length); DPRINT ("TargetLength: %hu\n", UnicodeString.Length);
DPRINT ("Target: '%wZ'\n", &UnicodeString); DPRINT ("Target: '%wZ'\n", &UnicodeString);
Length = ReturnedLength / sizeof(WCHAR); Length = ReturnLength / sizeof(WCHAR);
if (Length <= ucchMax) if (Length < ucchMax)
{ {
lpTargetPath[Length] = 0; /* Append null-charcter */
lpTargetPath[Length] = UNICODE_NULL;
Length++;
} }
else else
{ {
DPRINT ("Buffer is too small\n"); DPRINT ("Buffer is too small\n");
NtClose (DirectoryHandle);
SetLastErrorByStatus (STATUS_BUFFER_TOO_SMALL); SetLastErrorByStatus (STATUS_BUFFER_TOO_SMALL);
return 0; return 0;
} }
} }
else else
{ {
/* FIXME */ RestartScan = TRUE;
DPRINT1 ("Not implemented yet\n"); Context = 0;
NtClose (DirectoryHandle); Ptr = lpTargetPath;
SetLastErrorByStatus (STATUS_NOT_IMPLEMENTED); DirInfo = (PDIRECTORY_BASIC_INFORMATION)Buffer;
return 0;
}
NtClose (DirectoryHandle); while (TRUE)
{
Status = NtQueryDirectoryObject (DirectoryHandle,
Buffer,
sizeof (Buffer),
TRUE,
RestartScan,
&Context,
&ReturnLength);
if (!NT_SUCCESS(Status))
{
if (Status == STATUS_NO_MORE_ENTRIES)
{
/* Terminate the buffer */
*Ptr = UNICODE_NULL;
Length++;
Status = STATUS_SUCCESS;
}
else
{
Length = 0;
}
SetLastErrorByStatus (Status);
break;
}
if (!wcscmp (DirInfo->ObjectTypeName.Buffer, L"SymbolicLink"))
{
DPRINT ("Name: '%wZ'\n", &DirInfo->ObjectName);
NameLength = DirInfo->ObjectName.Length / sizeof(WCHAR);
if (Length + NameLength + 1 >= ucchMax)
{
Length = 0;
SetLastErrorByStatus (STATUS_BUFFER_TOO_SMALL);
break;
}
memcpy (Ptr,
DirInfo->ObjectName.Buffer,
DirInfo->ObjectName.Length);
Ptr += NameLength;
Length += NameLength;
*Ptr = UNICODE_NULL;
Ptr++;
Length++;
}
RestartScan = FALSE;
}
NtClose (DirectoryHandle);
}
return Length; return Length;
} }