3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/kernel32/file/dosdev.c
6 * PURPOSE: Dos device functions
7 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
12 /* INCLUDES ******************************************************************/
17 #include <kernel32/kernel32.h>
20 /* FUNCTIONS *****************************************************************/
33 UNICODE_STRING DeviceNameU;
34 UNICODE_STRING TargetPathU;
37 if (!RtlCreateUnicodeStringFromAsciiz (&DeviceNameU,
40 SetLastError (ERROR_NOT_ENOUGH_MEMORY);
44 if (!RtlCreateUnicodeStringFromAsciiz (&TargetPathU,
47 RtlFreeHeap (RtlGetProcessHeap (),
50 SetLastError (ERROR_NOT_ENOUGH_MEMORY);
54 Result = DefineDosDeviceW (dwFlags,
58 RtlFreeHeap (RtlGetProcessHeap (),
61 RtlFreeHeap (RtlGetProcessHeap (),
95 UNICODE_STRING DeviceNameU;
96 UNICODE_STRING TargetPathU;
97 ANSI_STRING TargetPathA;
100 if (!RtlCreateUnicodeStringFromAsciiz (&DeviceNameU,
101 (LPSTR)lpDeviceName))
103 SetLastError (ERROR_NOT_ENOUGH_MEMORY);
107 TargetPathU.Length = 0;
108 TargetPathU.MaximumLength = (USHORT)ucchMax * sizeof(WCHAR);
109 TargetPathU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
111 TargetPathU.MaximumLength);
112 if (TargetPathU.Buffer == NULL)
114 SetLastError (ERROR_NOT_ENOUGH_MEMORY);
118 Length = QueryDosDeviceW (DeviceNameU.Buffer,
123 TargetPathU.Length = Length * sizeof(WCHAR);
125 TargetPathA.Length = 0;
126 TargetPathA.MaximumLength = (USHORT)ucchMax;
127 TargetPathA.Buffer = lpTargetPath;
129 RtlUnicodeStringToAnsiString (&TargetPathA,
133 DPRINT ("TargetPathU: '%wZ'\n", &TargetPathU);
134 DPRINT ("TargetPathA: '%Z'\n", &TargetPathA);
137 RtlFreeHeap (RtlGetProcessHeap (),
140 RtlFreeHeap (RtlGetProcessHeap (),
154 LPCWSTR lpDeviceName,
159 PDIRECTORY_BASIC_INFORMATION DirInfo;
160 OBJECT_ATTRIBUTES ObjectAttributes;
161 UNICODE_STRING UnicodeString;
162 HANDLE DirectoryHandle;
173 /* Open the '\??' directory */
174 RtlInitUnicodeString (&UnicodeString,
176 InitializeObjectAttributes (&ObjectAttributes,
178 OBJ_CASE_INSENSITIVE,
181 Status = NtOpenDirectoryObject (&DirectoryHandle,
184 if (!NT_SUCCESS (Status))
186 DPRINT ("NtOpenDirectoryObject() failed (Status %lx)\n", Status);
187 SetLastErrorByStatus (Status);
193 if (lpDeviceName != NULL)
195 /* Open the lpDeviceName link object */
196 RtlInitUnicodeString (&UnicodeString,
197 (PWSTR)lpDeviceName);
198 InitializeObjectAttributes (&ObjectAttributes,
200 OBJ_CASE_INSENSITIVE,
203 Status = NtOpenSymbolicLinkObject (&DeviceHandle,
206 if (!NT_SUCCESS (Status))
208 DPRINT ("NtOpenSymbolicLinkObject() failed (Status %lx)\n", Status);
209 NtClose (DirectoryHandle);
210 SetLastErrorByStatus (Status);
214 /* Query link target */
215 UnicodeString.Length = 0;
216 UnicodeString.MaximumLength = (USHORT)ucchMax * sizeof(WCHAR);
217 UnicodeString.Buffer = lpTargetPath;
220 Status = NtQuerySymbolicLinkObject (DeviceHandle,
223 NtClose (DeviceHandle);
224 NtClose (DirectoryHandle);
225 if (!NT_SUCCESS (Status))
227 DPRINT ("NtQuerySymbolicLinkObject() failed (Status %lx)\n", Status);
228 SetLastErrorByStatus (Status);
232 DPRINT ("ReturnLength: %lu\n", ReturnLength);
233 DPRINT ("TargetLength: %hu\n", UnicodeString.Length);
234 DPRINT ("Target: '%wZ'\n", &UnicodeString);
236 Length = ReturnLength / sizeof(WCHAR);
237 if (Length < ucchMax)
239 /* Append null-charcter */
240 lpTargetPath[Length] = UNICODE_NULL;
245 DPRINT ("Buffer is too small\n");
246 SetLastErrorByStatus (STATUS_BUFFER_TOO_SMALL);
255 DirInfo = (PDIRECTORY_BASIC_INFORMATION)Buffer;
259 Status = NtQueryDirectoryObject (DirectoryHandle,
266 if (!NT_SUCCESS(Status))
268 if (Status == STATUS_NO_MORE_ENTRIES)
270 /* Terminate the buffer */
274 Status = STATUS_SUCCESS;
280 SetLastErrorByStatus (Status);
284 if (!wcscmp (DirInfo->ObjectTypeName.Buffer, L"SymbolicLink"))
286 DPRINT ("Name: '%wZ'\n", &DirInfo->ObjectName);
288 NameLength = DirInfo->ObjectName.Length / sizeof(WCHAR);
289 if (Length + NameLength + 1 >= ucchMax)
292 SetLastErrorByStatus (STATUS_BUFFER_TOO_SMALL);
297 DirInfo->ObjectName.Buffer,
298 DirInfo->ObjectName.Length);
300 Length += NameLength;
309 NtClose (DirectoryHandle);