ReactOS  0.4.12-dev-685-gf36cbf7
dosdev.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS system libraries
4  * FILE: dll/win32/kernel32/client/dosdev.c
5  * PURPOSE: Dos device functions
6  * PROGRAMMER: Ariadne (ariadne@xs4all.nl)
7  * UPDATE HISTORY:
8  * Created 01/11/98
9  */
10 
11 /* INCLUDES ******************************************************************/
12 
13 #include <k32.h>
14 
15 #define NDEBUG
16 #include <debug.h>
17 #include <dbt.h>
19 
20 /* FUNCTIONS *****************************************************************/
21 
22 /*
23  * @implemented
24  */
25 BOOL
26 WINAPI
28  DWORD dwFlags,
29  LPCSTR lpDeviceName,
30  LPCSTR lpTargetPath
31  )
32 {
33  UNICODE_STRING DeviceNameU = {0};
34  UNICODE_STRING TargetPathU = {0};
35  BOOL Result;
36 
37  if (lpDeviceName &&
38  !RtlCreateUnicodeStringFromAsciiz(&DeviceNameU, lpDeviceName))
39  {
41  return 0;
42  }
43 
44  if (lpTargetPath &&
45  !RtlCreateUnicodeStringFromAsciiz(&TargetPathU, lpTargetPath))
46  {
47  if (DeviceNameU.Buffer)
48  {
49  RtlFreeUnicodeString(&DeviceNameU);
50  }
52  return 0;
53  }
54 
56  DeviceNameU.Buffer,
57  TargetPathU.Buffer);
58 
59  if (TargetPathU.Buffer)
60  {
61  RtlFreeUnicodeString(&TargetPathU);
62  }
63 
64  if (DeviceNameU.Buffer)
65  {
66  RtlFreeUnicodeString(&DeviceNameU);
67  }
68  return Result;
69 }
70 
71 
72 /*
73  * @implemented
74  */
75 BOOL
76 WINAPI
78  DWORD dwFlags,
79  LPCWSTR lpDeviceName,
80  LPCWSTR lpTargetPath
81  )
82 {
83  ULONG ArgumentCount;
85  BASE_API_MESSAGE ApiMessage;
86  PBASE_DEFINE_DOS_DEVICE DefineDosDeviceRequest = &ApiMessage.Data.DefineDosDeviceRequest;
87  PCSR_CAPTURE_BUFFER CaptureBuffer;
88  UNICODE_STRING NtTargetPathU;
89  UNICODE_STRING DeviceNameU;
90  UNICODE_STRING DeviceUpcaseNameU;
91  HANDLE hUser32;
93  BOOL Result = TRUE;
94  DWORD dwRecipients;
95  typedef long (WINAPI *BSM_type)(DWORD, LPDWORD, UINT, WPARAM, LPARAM);
96  BSM_type BSM_ptr;
97 
98  if ( (dwFlags & 0xFFFFFFF0) ||
101  {
103  return FALSE;
104  }
105 
106  ArgumentCount = 1;
107  BufferSize = 0;
108  if (!lpTargetPath)
109  {
110  RtlInitUnicodeString(&NtTargetPathU,
111  NULL);
112  }
113  else
114  {
116  {
117  RtlInitUnicodeString(&NtTargetPathU,
118  lpTargetPath);
119  }
120  else
121  {
122  if (!RtlDosPathNameToNtPathName_U(lpTargetPath,
123  &NtTargetPathU,
124  NULL,
125  NULL))
126  {
127  WARN("RtlDosPathNameToNtPathName_U() failed\n");
129  return FALSE;
130  }
131  }
132  ArgumentCount = 2;
133  BufferSize += NtTargetPathU.Length;
134  }
135 
136  RtlInitUnicodeString(&DeviceNameU,
137  lpDeviceName);
138  RtlUpcaseUnicodeString(&DeviceUpcaseNameU,
139  &DeviceNameU,
140  TRUE);
141  BufferSize += DeviceUpcaseNameU.Length;
142 
143  CaptureBuffer = CsrAllocateCaptureBuffer(ArgumentCount,
144  BufferSize);
145  if (!CaptureBuffer)
146  {
148  Result = FALSE;
149  }
150  else
151  {
152  DefineDosDeviceRequest->Flags = dwFlags;
153 
154  CsrCaptureMessageBuffer(CaptureBuffer,
155  DeviceUpcaseNameU.Buffer,
156  DeviceUpcaseNameU.Length,
157  (PVOID*)&DefineDosDeviceRequest->DeviceName.Buffer);
158 
159  DefineDosDeviceRequest->DeviceName.Length =
160  DeviceUpcaseNameU.Length;
161  DefineDosDeviceRequest->DeviceName.MaximumLength =
162  DeviceUpcaseNameU.Length;
163 
164  if (NtTargetPathU.Buffer)
165  {
166  CsrCaptureMessageBuffer(CaptureBuffer,
167  NtTargetPathU.Buffer,
168  NtTargetPathU.Length,
169  (PVOID*)&DefineDosDeviceRequest->TargetPath.Buffer);
170  }
171  DefineDosDeviceRequest->TargetPath.Length =
172  NtTargetPathU.Length;
173  DefineDosDeviceRequest->TargetPath.MaximumLength =
174  NtTargetPathU.Length;
175 
177  CaptureBuffer,
179  sizeof(*DefineDosDeviceRequest));
180  CsrFreeCaptureBuffer(CaptureBuffer);
181 
182  if (!NT_SUCCESS(ApiMessage.Status))
183  {
184  WARN("CsrClientCallServer() failed (Status %lx)\n", ApiMessage.Status);
185  BaseSetLastNTError(ApiMessage.Status);
186  Result = FALSE;
187  }
188  else
189  {
190  if (! (dwFlags & DDD_NO_BROADCAST_SYSTEM) &&
191  DeviceUpcaseNameU.Length == 2 * sizeof(WCHAR) &&
192  DeviceUpcaseNameU.Buffer[1] == L':' &&
193  ( (DeviceUpcaseNameU.Buffer[0] - L'A') < 26 ))
194  {
195  hUser32 = LoadLibraryA("user32.dll");
196  if (hUser32)
197  {
198  BSM_ptr = (BSM_type)
199  GetProcAddress(hUser32, "BroadcastSystemMessageW");
200  if (BSM_ptr)
201  {
202  dwRecipients = BSM_APPLICATIONS;
203  dbcv.dbcv_size = sizeof(DEV_BROADCAST_VOLUME);
205  dbcv.dbcv_reserved = 0;
206  dbcv.dbcv_unitmask |=
207  (1 << (DeviceUpcaseNameU.Buffer[0] - L'A'));
208  dbcv.dbcv_flags = DBTF_NET;
209  (void) BSM_ptr(BSF_SENDNOTIFYMESSAGE | BSF_FLUSHDISK,
210  &dwRecipients,
213  (LPARAM)&dbcv);
214  }
215  FreeLibrary(hUser32);
216  }
217  }
218  }
219  }
220 
221  if (NtTargetPathU.Buffer &&
222  NtTargetPathU.Buffer != lpTargetPath)
223  {
224  RtlFreeHeap(RtlGetProcessHeap(),
225  0,
226  NtTargetPathU.Buffer);
227  }
228  RtlFreeUnicodeString(&DeviceUpcaseNameU);
229  return Result;
230 }
231 
232 
233 /*
234  * @implemented
235  */
236 DWORD
237 WINAPI
239  LPCSTR lpDeviceName,
240  LPSTR lpTargetPath,
241  DWORD ucchMax
242  )
243 {
244  UNICODE_STRING DeviceNameU;
245  UNICODE_STRING TargetPathU;
246  ANSI_STRING TargetPathA;
247  DWORD Length;
248  DWORD CurrentLength;
249  PWCHAR Buffer;
250 
251  if (lpDeviceName)
252  {
253  if (!RtlCreateUnicodeStringFromAsciiz(&DeviceNameU,
254  (LPSTR)lpDeviceName))
255  {
257  return 0;
258  }
259  }
260  Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, ucchMax * sizeof(WCHAR));
261  if (Buffer == NULL)
262  {
263  if (lpDeviceName)
264  {
265  RtlFreeHeap(RtlGetProcessHeap(), 0, DeviceNameU.Buffer);
266  }
268  return 0;
269  }
270 
271  Length = QueryDosDeviceW(lpDeviceName ? DeviceNameU.Buffer : NULL,
272  Buffer, ucchMax);
273  if (Length != 0)
274  {
275  TargetPathA.Buffer = lpTargetPath;
276  TargetPathU.Buffer = Buffer;
277  ucchMax = Length;
278 
279  while (ucchMax)
280  {
281  CurrentLength = min(ucchMax, MAXUSHORT / 2);
282  TargetPathU.MaximumLength = TargetPathU.Length = (USHORT)CurrentLength * sizeof(WCHAR);
283 
284  TargetPathA.Length = 0;
285  TargetPathA.MaximumLength = (USHORT)CurrentLength;
286 
287  RtlUnicodeStringToAnsiString(&TargetPathA, &TargetPathU, FALSE);
288  ucchMax -= CurrentLength;
289  TargetPathA.Buffer += TargetPathA.Length;
290  TargetPathU.Buffer += TargetPathU.Length / sizeof(WCHAR);
291  }
292  }
293 
294  RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
295  if (lpDeviceName)
296  {
297  RtlFreeHeap(RtlGetProcessHeap(), 0, DeviceNameU.Buffer);
298  }
299  return Length;
300 }
301 
302 
303 /*
304  * @implemented
305  */
306 DWORD
307 WINAPI
309  LPCWSTR lpDeviceName,
310  LPWSTR lpTargetPath,
311  DWORD ucchMax
312  )
313 {
320  ULONG NameLength;
321  ULONG Length;
322  ULONG Context;
325  UCHAR Buffer[512];
326  PWSTR Ptr;
327 
328  /* Open the '\??' directory */
331  &UnicodeString,
333  NULL,
334  NULL);
338  if (!NT_SUCCESS(Status))
339  {
340  WARN("NtOpenDirectoryObject() failed (Status %lx)\n", Status);
342  return 0;
343  }
344 
345  Length = 0;
346 
347  if (lpDeviceName != NULL)
348  {
349  /* Open the lpDeviceName link object */
350  RtlInitUnicodeString(&UnicodeString, (PWSTR)lpDeviceName);
352  &UnicodeString,
355  NULL);
359  if (!NT_SUCCESS(Status))
360  {
361  WARN("NtOpenSymbolicLinkObject() failed (Status %lx)\n", Status);
364  return 0;
365  }
366 
367  /* Query link target */
368  UnicodeString.Length = 0;
369  UnicodeString.MaximumLength = (USHORT)ucchMax * sizeof(WCHAR);
370  UnicodeString.Buffer = lpTargetPath;
371 
372  ReturnLength = 0;
374  &UnicodeString,
375  &ReturnLength);
378  if (!NT_SUCCESS(Status))
379  {
380  WARN("NtQuerySymbolicLinkObject() failed (Status %lx)\n", Status);
382  return 0;
383  }
384 
385  TRACE("ReturnLength: %lu\n", ReturnLength);
386  TRACE("TargetLength: %hu\n", UnicodeString.Length);
387  TRACE("Target: '%wZ'\n", &UnicodeString);
388 
389  Length = UnicodeString.Length / sizeof(WCHAR);
390  if (Length < ucchMax)
391  {
392  /* Append null-character */
393  lpTargetPath[Length] = UNICODE_NULL;
394  Length++;
395  }
396  else
397  {
398  TRACE("Buffer is too small\n");
400  return 0;
401  }
402  }
403  else
404  {
405  RestartScan = TRUE;
406  Context = 0;
407  Ptr = lpTargetPath;
409 
410  while (TRUE)
411  {
413  Buffer,
414  sizeof(Buffer),
415  TRUE,
416  RestartScan,
417  &Context,
418  &ReturnLength);
419  if (!NT_SUCCESS(Status))
420  {
422  {
423  /* Terminate the buffer */
424  *Ptr = UNICODE_NULL;
425  Length++;
426 
428  }
429  else
430  {
431  Length = 0;
432  }
434  break;
435  }
436 
437  if (!wcscmp(DirInfo->TypeName.Buffer, L"SymbolicLink"))
438  {
439  TRACE("Name: '%wZ'\n", &DirInfo->Name);
440 
441  NameLength = DirInfo->Name.Length / sizeof(WCHAR);
442  if (Length + NameLength + 1 >= ucchMax)
443  {
444  Length = 0;
446  break;
447  }
448 
449  memcpy(Ptr, DirInfo->Name.Buffer, DirInfo->Name.Length);
450  Ptr += NameLength;
451  Length += NameLength;
452  *Ptr = UNICODE_NULL;
453  Ptr++;
454  Length++;
455  }
456 
457  RestartScan = FALSE;
458  }
459 
461  }
462 
463  return Length;
464 }
465 
466 /* EOF */
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
UNICODE_STRING TargetPath
Definition: basemsg.h:257
VOID NTAPI CsrFreeCaptureBuffer(IN PCSR_CAPTURE_BUFFER CaptureBuffer)
Definition: capture.c:189
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
#define TRUE
Definition: types.h:120
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
_Inout_ PUSB_DEVICE_HANDLE DeviceHandle
Definition: hubbusif.h:121
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:47
*BytesInUnicodeString PWCH UnicodeString
Definition: rtlfuncs.h:1980
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:193
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ BOOLEAN _In_ ULONG _In_opt_ PULONG _In_ BOOLEAN RestartScan
Definition: fltkernel.h:2298
USHORT MaximumLength
Definition: env_spec_w32.h:370
PCSR_CAPTURE_BUFFER NTAPI CsrAllocateCaptureBuffer(IN ULONG ArgumentCount, IN ULONG BufferSize)
Definition: capture.c:90
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define DDD_REMOVE_DEFINITION
Definition: winbase.h:505
#define DWORD
Definition: msvc.h:34
uint16_t * PWSTR
Definition: typedefs.h:54
NTSTATUS NTAPI NtOpenDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:359
NTSTATUS NTAPI CsrClientCallServer(IN OUT PCSR_API_MESSAGE ApiMessage, IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer OPTIONAL, IN CSR_API_NUMBER ApiNumber, IN ULONG DataLength)
Definition: connect.c:360
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
#define WARN(fmt,...)
Definition: debug.h:111
LONG NTSTATUS
Definition: precomp.h:26
#define DDD_NO_BROADCAST_SYSTEM
Definition: winbase.h:507
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:603
static HANDLE DirectoryHandle
Definition: ObType.c:48
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
uint16_t * PWCHAR
Definition: typedefs.h:54
char * LPSTR
Definition: xmlstorage.h:182
NTSTATUS NTAPI NtQueryDirectoryObject(IN HANDLE DirectoryHandle, OUT PVOID Buffer, IN ULONG BufferLength, IN BOOLEAN ReturnSingleEntry, IN BOOLEAN RestartScan, IN OUT PULONG Context, OUT PULONG ReturnLength OPTIONAL)
Definition: obdir.c:456
#define WCHAR
Definition: msvc.h:43
DWORD dbcv_reserved
Definition: dbt.h:103
union _BASE_API_MESSAGE::@3377 Data
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
UINT_PTR WPARAM
Definition: windef.h:207
struct _OBJECT_DIRECTORY_INFORMATION * POBJECT_DIRECTORY_INFORMATION
BASE_DEFINE_DOS_DEVICE DefineDosDeviceRequest
Definition: basemsg.h:300
NTSTATUS Status
Definition: csrmsg.h:112
VOID NTAPI CsrCaptureMessageBuffer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer, IN PVOID MessageBuffer OPTIONAL, IN ULONG MessageLength, OUT PVOID *CapturedData)
Definition: capture.c:169
#define UNICODE_NULL
DWORD dbcv_devicetype
Definition: dbt.h:102
DEBUG_CHANNEL(kernel32file)
#define kernel32file
Definition: kernel32.h:6
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
UNICODE_STRING DeviceName
Definition: basemsg.h:256
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
DWORD WINAPI QueryDosDeviceW(LPCWSTR lpDeviceName, LPWSTR lpTargetPath, DWORD ucchMax)
Definition: dosdev.c:308
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz(_Out_ PUNICODE_STRING Destination, _In_ PCSZ Source)
Definition: bufpool.h:45
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
const char * LPCSTR
Definition: xmlstorage.h:183
#define CSR_CREATE_API_NUMBER(ServerId, ApiId)
Definition: csrmsg.h:37
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:585
USHORT MaximumLength
Definition: env_spec_w32.h:377
DWORD dbcv_unitmask
Definition: dbt.h:104
#define TRACE(s)
Definition: solgame.cpp:4
#define FreeLibrary(x)
Definition: compat.h:405
unsigned int BOOL
Definition: ntddk_ex.h:94
#define BASESRV_SERVERDLL_INDEX
Definition: basemsg.h:15
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
DWORD WINAPI QueryDosDeviceA(LPCSTR lpDeviceName, LPSTR lpTargetPath, DWORD ucchMax)
Definition: dosdev.c:238
#define BufferSize
Definition: classpnp.h:419
unsigned long DWORD
Definition: ntddk_ex.h:95
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define BSF_FLUSHDISK
Definition: dbt.h:53
#define SetLastError(x)
Definition: compat.h:409
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define DBT_DEVTYP_VOLUME
Definition: dbt.h:21
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
unsigned char UCHAR
Definition: xmlstorage.h:181
#define WPARAM
Definition: msvc.h:37
#define LPDWORD
Definition: nt_native.h:46
static const WCHAR L[]
Definition: oid.c:1250
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define WINAPI
Definition: msvc.h:20
BOOL WINAPI DefineDosDeviceW(DWORD dwFlags, LPCWSTR lpDeviceName, LPCWSTR lpTargetPath)
Definition: dosdev.c:77
Status
Definition: gdiplustypes.h:24
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
BOOL WINAPI DefineDosDeviceA(DWORD dwFlags, LPCSTR lpDeviceName, LPCSTR lpTargetPath)
Definition: dosdev.c:27
#define DDD_RAW_TARGET_PATH
Definition: winbase.h:504
unsigned short USHORT
Definition: pedump.c:61
#define long
Definition: qsort.c:33
#define DBT_DEVICEARRIVAL
Definition: dbt.h:12
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
#define min(a, b)
Definition: monoChain.cc:55
struct _DEV_BROADCAST_VOLUME DEV_BROADCAST_VOLUME
#define MAXUSHORT
Definition: typedefs.h:81
#define WM_DEVICECHANGE
Definition: winuser.h:1787
struct tagContext Context
Definition: acpixf.h:1020
unsigned int ULONG
Definition: retypes.h:1
#define SYMBOLIC_LINK_QUERY
Definition: nt_native.h:1265
#define DIRECTORY_QUERY
Definition: nt_native.h:1254
#define DBTF_NET
Definition: dbt.h:44
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define GetProcAddress(x, y)
Definition: compat.h:410
WCHAR * LPWSTR
Definition: xmlstorage.h:184
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define UINT
Definition: msvc.h:27
return STATUS_SUCCESS
Definition: btrfs.c:2725
#define BSM_APPLICATIONS
Definition: dbt.h:48
NTSYSAPI BOOLEAN NTAPI RtlDosPathNameToNtPathName_U(_In_opt_z_ PCWSTR DosPathName, _Out_ PUNICODE_STRING NtPathName, _Out_opt_ PCWSTR *NtFileNamePart, _Out_opt_ PRTL_RELATIVE_NAME_U DirectoryInfo)
#define DDD_EXACT_MATCH_ON_REMOVE
Definition: winbase.h:506
#define LPARAM
Definition: msvc.h:38
UNICODE_STRING TypeName
Definition: obtypes.h:279