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 static ULONG gDebugChannel
= kernel32file
;
19 /* FUNCTIONS *****************************************************************/
32 UNICODE_STRING DeviceNameU
;
33 UNICODE_STRING TargetPathU
;
36 if (!RtlCreateUnicodeStringFromAsciiz (&DeviceNameU
,
39 SetLastError (ERROR_NOT_ENOUGH_MEMORY
);
43 if (!RtlCreateUnicodeStringFromAsciiz (&TargetPathU
,
46 RtlFreeHeap (RtlGetProcessHeap (),
49 SetLastError (ERROR_NOT_ENOUGH_MEMORY
);
53 Result
= DefineDosDeviceW (dwFlags
,
57 RtlFreeHeap (RtlGetProcessHeap (),
60 RtlFreeHeap (RtlGetProcessHeap (),
95 UNICODE_STRING DeviceNameU
;
96 UNICODE_STRING TargetPathU
;
97 ANSI_STRING TargetPathA
;
104 if (!RtlCreateUnicodeStringFromAsciiz (&DeviceNameU
,
105 (LPSTR
)lpDeviceName
))
107 SetLastError (ERROR_NOT_ENOUGH_MEMORY
);
111 Buffer
= RtlAllocateHeap (RtlGetProcessHeap (),
113 ucchMax
* sizeof(WCHAR
));
118 RtlFreeHeap (RtlGetProcessHeap (),
122 SetLastError (ERROR_NOT_ENOUGH_MEMORY
);
126 Length
= QueryDosDeviceW (lpDeviceName
? DeviceNameU
.Buffer
: NULL
,
131 TargetPathA
.Buffer
= lpTargetPath
;
132 TargetPathU
.Buffer
= Buffer
;
137 CurrentLength
= min (ucchMax
, MAXUSHORT
/ 2);
138 TargetPathU
.MaximumLength
= TargetPathU
.Length
= (USHORT
)CurrentLength
* sizeof(WCHAR
);
140 TargetPathA
.Length
= 0;
141 TargetPathA
.MaximumLength
= (USHORT
)CurrentLength
;
143 RtlUnicodeStringToAnsiString (&TargetPathA
,
146 ucchMax
-= CurrentLength
;
147 TargetPathA
.Buffer
+= TargetPathA
.Length
;
148 TargetPathU
.Buffer
+= TargetPathU
.Length
/ sizeof(WCHAR
);
152 RtlFreeHeap (RtlGetProcessHeap (),
157 RtlFreeHeap (RtlGetProcessHeap (),
171 LPCWSTR lpDeviceName
,
176 POBJECT_DIRECTORY_INFORMATION DirInfo
;
177 OBJECT_ATTRIBUTES ObjectAttributes
;
178 UNICODE_STRING UnicodeString
;
179 HANDLE DirectoryHandle
;
190 /* Open the '\??' directory */
191 RtlInitUnicodeString (&UnicodeString
,
193 InitializeObjectAttributes (&ObjectAttributes
,
195 OBJ_CASE_INSENSITIVE
,
198 Status
= NtOpenDirectoryObject (&DirectoryHandle
,
201 if (!NT_SUCCESS (Status
))
203 WARN ("NtOpenDirectoryObject() failed (Status %lx)\n", Status
);
204 SetLastErrorByStatus (Status
);
210 if (lpDeviceName
!= NULL
)
212 /* Open the lpDeviceName link object */
213 RtlInitUnicodeString (&UnicodeString
,
214 (PWSTR
)lpDeviceName
);
215 InitializeObjectAttributes (&ObjectAttributes
,
217 OBJ_CASE_INSENSITIVE
,
220 Status
= NtOpenSymbolicLinkObject (&DeviceHandle
,
223 if (!NT_SUCCESS (Status
))
225 WARN ("NtOpenSymbolicLinkObject() failed (Status %lx)\n", Status
);
226 NtClose (DirectoryHandle
);
227 SetLastErrorByStatus (Status
);
231 /* Query link target */
232 UnicodeString
.Length
= 0;
233 UnicodeString
.MaximumLength
= (USHORT
)ucchMax
* sizeof(WCHAR
);
234 UnicodeString
.Buffer
= lpTargetPath
;
237 Status
= NtQuerySymbolicLinkObject (DeviceHandle
,
240 NtClose (DeviceHandle
);
241 NtClose (DirectoryHandle
);
242 if (!NT_SUCCESS (Status
))
244 WARN ("NtQuerySymbolicLinkObject() failed (Status %lx)\n", Status
);
245 SetLastErrorByStatus (Status
);
249 TRACE ("ReturnLength: %lu\n", ReturnLength
);
250 TRACE ("TargetLength: %hu\n", UnicodeString
.Length
);
251 TRACE ("Target: '%wZ'\n", &UnicodeString
);
253 Length
= ReturnLength
/ sizeof(WCHAR
);
254 if (Length
< ucchMax
)
256 /* Append null-charcter */
257 lpTargetPath
[Length
] = UNICODE_NULL
;
262 TRACE ("Buffer is too small\n");
263 SetLastErrorByStatus (STATUS_BUFFER_TOO_SMALL
);
272 DirInfo
= (POBJECT_DIRECTORY_INFORMATION
)Buffer
;
276 Status
= NtQueryDirectoryObject (DirectoryHandle
,
283 if (!NT_SUCCESS(Status
))
285 if (Status
== STATUS_NO_MORE_ENTRIES
)
287 /* Terminate the buffer */
291 Status
= STATUS_SUCCESS
;
297 SetLastErrorByStatus (Status
);
301 if (!wcscmp (DirInfo
->TypeName
.Buffer
, L
"SymbolicLink"))
303 TRACE ("Name: '%wZ'\n", &DirInfo
->Name
);
305 NameLength
= DirInfo
->Name
.Length
/ sizeof(WCHAR
);
306 if (Length
+ NameLength
+ 1 >= ucchMax
)
309 SetLastErrorByStatus (STATUS_BUFFER_TOO_SMALL
);
314 DirInfo
->Name
.Buffer
,
315 DirInfo
->Name
.Length
);
317 Length
+= NameLength
;
326 NtClose (DirectoryHandle
);