ReactOS 0.4.15-dev-7924-g5949c20
mntpoint.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/file/mntpoint.c
5 * PURPOSE: File volume mount point functions
6 * PROGRAMMER: Pierre Schweitzer (pierre@reactos.org)
7 */
8
9#include <k32.h>
10#define NDEBUG
11#include <debug.h>
12
13/*
14 * @implemented
15 */
16static BOOL
18 OUT LPWSTR lpszVolumeName,
19 IN DWORD cchBufferLength)
20{
21 BOOL Ret;
23 PWSTR FoundVolume;
25 UNICODE_STRING NtPathName;
27 PMOUNTMGR_MOUNT_POINT MountPoint;
28 ULONG CurrentMntPt, FoundVolumeLen;
29 PMOUNTMGR_MOUNT_POINTS MountPoints;
31 HANDLE VolumeHandle, MountMgrHandle;
32 struct
33 {
36 } MountDevName;
37
38 /* It makes no sense on a non-local drive */
39 if (GetDriveTypeW(lpszRootPath) == DRIVE_REMOTE)
40 {
42 return FALSE;
43 }
44
45 /* Get the NT path */
46 if (!RtlDosPathNameToNtPathName_U(lpszRootPath, &NtPathName, NULL, NULL))
47 {
49 return FALSE;
50 }
51
52 /* If it's a root path - likely - drop backslash to open volume */
53 if (NtPathName.Buffer[(NtPathName.Length / sizeof(WCHAR)) - 1] == L'\\')
54 {
55 NtPathName.Buffer[(NtPathName.Length / sizeof(WCHAR)) - 1] = UNICODE_NULL;
56 NtPathName.Length -= sizeof(WCHAR);
57 }
58
59 /* If that's a DOS volume, upper case the letter */
60 if (NtPathName.Length >= 2 * sizeof(WCHAR))
61 {
62 if (NtPathName.Buffer[(NtPathName.Length / sizeof(WCHAR)) - 1] == L':')
63 {
64 NtPathName.Buffer[(NtPathName.Length / sizeof(WCHAR)) - 2] = _toupper(NtPathName.Buffer[(NtPathName.Length / sizeof(WCHAR)) - 2]);
65 }
66 }
67
68 /* Attempt to open the volume */
75 if (!NT_SUCCESS(Status))
76 {
77 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
79 return FALSE;
80 }
81
82 /* Query the device name - that's what we'll translate */
84 0, &MountDevName, sizeof(MountDevName), &BytesReturned,
85 NULL))
86 {
88 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
89 return FALSE;
90 }
91
92 /* No longer need the volume */
94 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
95
96 /* We'll keep the device name for later usage */
97 NtPathName.Length = MountDevName.NameLength;
98 NtPathName.MaximumLength = MountDevName.NameLength + sizeof(UNICODE_NULL);
99 NtPathName.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, NtPathName.MaximumLength);
100 if (NtPathName.Buffer == NULL)
101 {
103 return FALSE;
104 }
105
106 RtlCopyMemory(NtPathName.Buffer, MountDevName.Name, NtPathName.Length);
107 NtPathName.Buffer[NtPathName.Length / sizeof(WCHAR)] = UNICODE_NULL;
108
109 /* Allocate the structure for querying the mount mgr */
110 MountPoint = RtlAllocateHeap(RtlGetProcessHeap(), 0,
111 NtPathName.Length + sizeof(MOUNTMGR_MOUNT_POINT));
112 if (MountPoint == NULL)
113 {
114 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
116 return FALSE;
117 }
118
119 /* 0 everything, we provide a device name */
120 RtlZeroMemory(MountPoint, sizeof(MOUNTMGR_MOUNT_POINT));
121 MountPoint->DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
122 MountPoint->DeviceNameLength = NtPathName.Length;
123 RtlCopyMemory((PVOID)((ULONG_PTR)MountPoint + sizeof(MOUNTMGR_MOUNT_POINT)), NtPathName.Buffer, NtPathName.Length);
124
125 /* Allocate a dummy output buffer to probe for size */
126 MountPoints = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(MOUNTMGR_MOUNT_POINTS));
127 if (MountPoints == NULL)
128 {
129 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
130 RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint);
132 return FALSE;
133 }
134
135 /* Open a handle to the mount manager */
136 MountMgrHandle = CreateFileW(MOUNTMGR_DOS_DEVICE_NAME, 0,
140 if (MountMgrHandle == INVALID_HANDLE_VALUE)
141 {
142 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
143 RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints);
144 RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint);
145 return FALSE;
146 }
147
148 /* Query the names associated to our device name */
149 Ret = DeviceIoControl(MountMgrHandle, IOCTL_MOUNTMGR_QUERY_POINTS,
150 MountPoint, NtPathName.Length + sizeof(MOUNTMGR_MOUNT_POINT),
151 MountPoints, sizeof(MOUNTMGR_MOUNT_POINTS), &BytesReturned,
152 NULL);
153 /* As long as the buffer is too small, keep looping */
154 while (!Ret && GetLastError() == ERROR_MORE_DATA)
155 {
157
158 /* Get the size we've to allocate */
159 BufferSize = MountPoints->Size;
160 /* Reallocate the buffer with enough room */
161 RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints);
162 MountPoints = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize);
163 if (MountPoints == NULL)
164 {
165 CloseHandle(MountMgrHandle);
166 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
167 RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint);
169 return FALSE;
170 }
171
172 /* Reissue the request, it should work now! */
173 Ret = DeviceIoControl(MountMgrHandle, IOCTL_MOUNTMGR_QUERY_POINTS,
174 MountPoint, NtPathName.Length + sizeof(MOUNTMGR_MOUNT_POINT),
175 MountPoints, BufferSize, &BytesReturned, NULL);
176 }
177
178 /* We're done, no longer need the mount manager */
179 CloseHandle(MountMgrHandle);
180 /* Nor our input buffer */
181 RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoint);
182
183 /* If the mount manager failed, just quit */
184 if (!Ret)
185 {
186 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
187 RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints);
189 return FALSE;
190 }
191
192 CurrentMntPt = 0;
193 /* If there were no associated mount points, we'll return the device name */
194 if (MountPoints->NumberOfMountPoints == 0)
195 {
196 FoundVolume = NtPathName.Buffer;
197 FoundVolumeLen = NtPathName.Length;
198 }
199 /* Otherwise, find one which is matching */
200 else
201 {
202 for (; CurrentMntPt < MountPoints->NumberOfMountPoints; ++CurrentMntPt)
203 {
205
206 /* Make a string of it, to easy the checks */
207 SymbolicLink.Length = MountPoints->MountPoints[CurrentMntPt].SymbolicLinkNameLength;
208 SymbolicLink.MaximumLength = SymbolicLink.Length;
209 SymbolicLink.Buffer = (PVOID)((ULONG_PTR)MountPoints + MountPoints->MountPoints[CurrentMntPt].SymbolicLinkNameOffset);
210 /* If that's a NT volume name (GUID form), keep it! */
212 {
213 FoundVolume = SymbolicLink.Buffer;
214 FoundVolumeLen = SymbolicLink.Length;
215
216 break;
217 }
218 }
219 }
220
221 /* We couldn't find anything matching, return an error */
222 if (CurrentMntPt == MountPoints->NumberOfMountPoints)
223 {
224 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
225 RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints);
227 return FALSE;
228 }
229
230 /* We found a matching volume, have we enough memory to return it? */
231 if (cchBufferLength * sizeof(WCHAR) < FoundVolumeLen + 2 * sizeof(WCHAR))
232 {
233 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
234 RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints);
236 return FALSE;
237 }
238
239 /* Copy it back! */
240 RtlCopyMemory(lpszVolumeName, FoundVolume, FoundVolumeLen);
241 /* Make it compliant */
242 lpszVolumeName[1] = L'\\';
243 /* And transform it as root path */
244 lpszVolumeName[FoundVolumeLen / sizeof(WCHAR)] = L'\\';
245 lpszVolumeName[FoundVolumeLen / sizeof(WCHAR) + 1] = UNICODE_NULL;
246
247 /* We're done! */
248 RtlFreeHeap(RtlGetProcessHeap(), 0, NtPathName.Buffer);
249 RtlFreeHeap(RtlGetProcessHeap(), 0, MountPoints);
250 return TRUE;
251}
252
253/*
254 * @implemented
255 */
256BOOL
258 OUT LPWSTR lpszVolumeName,
259 IN DWORD cchBufferLength,
260 OUT LPBOOL IsAMountPoint)
261{
262 WCHAR Old;
264 HANDLE ReparseHandle;
265 UNICODE_STRING SubstituteName;
266 PREPARSE_DATA_BUFFER ReparseBuffer;
267
268 /* Try to open the reparse point */
269 ReparseHandle = CreateFileW(lpszMountPoint, 0,
274 /* It failed! */
275 if (ReparseHandle == INVALID_HANDLE_VALUE)
276 {
277 /* Report it's not a mount point (it's not a reparse point) */
278 if (IsAMountPoint != NULL)
279 {
280 *IsAMountPoint = FALSE;
281 }
282
283 /* And zero output */
284 if (lpszVolumeName != NULL && cchBufferLength >= 1)
285 {
286 lpszVolumeName[0] = UNICODE_NULL;
287 }
288
289 return FALSE;
290 }
291
292 /* This is a mount point! */
293 if (IsAMountPoint != NULL)
294 {
295 *IsAMountPoint = TRUE;
296 }
297
298 /* Prepare a buffer big enough to read its data */
299 ReparseBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
300 if (ReparseBuffer == NULL)
301 {
302 CloseHandle(ReparseHandle);
304
305 /* Zero output */
306 if (lpszVolumeName != NULL && cchBufferLength >= 1)
307 {
308 lpszVolumeName[0] = UNICODE_NULL;
309 }
310
311 return FALSE;
312 }
313
314 /* Dump the reparse point data */
315 if (!DeviceIoControl(ReparseHandle, FSCTL_GET_REPARSE_POINT, NULL, 0,
317 NULL))
318 {
319 RtlFreeHeap(RtlGetProcessHeap(), 0, ReparseBuffer);
320 CloseHandle(ReparseHandle);
321
322 /* Zero output */
323 if (lpszVolumeName != NULL && cchBufferLength >= 1)
324 {
325 lpszVolumeName[0] = UNICODE_NULL;
326 }
327
328 return FALSE;
329 }
330
331 /* We no longer need the reparse point */
332 CloseHandle(ReparseHandle);
333
334 /* We only handle mount points */
335 if (ReparseBuffer->ReparseTag != IO_REPARSE_TAG_MOUNT_POINT)
336 {
337 RtlFreeHeap(RtlGetProcessHeap(), 0, ReparseBuffer);
338
339 /* Zero output */
340 if (lpszVolumeName != NULL && cchBufferLength >= 1)
341 {
342 lpszVolumeName[0] = UNICODE_NULL;
343 }
344
345 return FALSE;
346 }
347
348 /* Do we have enough room for copying substitue name? */
349 if ((ReparseBuffer->MountPointReparseBuffer.SubstituteNameLength + sizeof(UNICODE_NULL)) > cchBufferLength * sizeof(WCHAR))
350 {
351 RtlFreeHeap(RtlGetProcessHeap(), 0, ReparseBuffer);
353
354 /* Zero output */
355 if (lpszVolumeName != NULL && cchBufferLength >= 1)
356 {
357 lpszVolumeName[0] = UNICODE_NULL;
358 }
359
360 return FALSE;
361 }
362
363 /* Copy the link target */
364 RtlCopyMemory(lpszVolumeName,
365 &ReparseBuffer->MountPointReparseBuffer.PathBuffer[ReparseBuffer->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)],
366 ReparseBuffer->MountPointReparseBuffer.SubstituteNameLength);
367 /* Make it DOS valid */
368 Old = lpszVolumeName[1];
369 /* We want a root path */
370 lpszVolumeName[1] = L'\\';
371 /* And null terminate obviously */
372 lpszVolumeName[ReparseBuffer->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR)] = UNICODE_NULL;
373
374 /* Make it a string to easily check it */
375 SubstituteName.Length = ReparseBuffer->MountPointReparseBuffer.SubstituteNameLength;
376 SubstituteName.MaximumLength = SubstituteName.Length;
377 SubstituteName.Buffer = lpszVolumeName;
378
379 /* No longer need the data? */
380 RtlFreeHeap(RtlGetProcessHeap(), 0, ReparseBuffer);
381
382 /* Is that a dos volume name with backslash? */
383 if (MOUNTMGR_IS_DOS_VOLUME_NAME_WB(&SubstituteName))
384 {
385 return TRUE;
386 }
387
388 /* No, so restore previous name and return to the caller */
389 lpszVolumeName[1] = Old;
391 return FALSE;
392}
393
394/*
395 * @implemented
396 */
397BOOL
399 OUT LPWSTR lpszVolumeName,
400 IN DWORD cchBufferLength,
401 OUT LPBOOL IsAMountPoint)
402{
403 BOOL Ret;
404 UNICODE_STRING MountPoint;
405
406 /* Assume it's a mount point (likely for non reparse points) */
407 if (IsAMountPoint != NULL)
408 {
409 *IsAMountPoint = 1;
410 }
411
412 /* Make a string with the mount point name */
413 RtlInitUnicodeString(&MountPoint, lpszMountPoint);
414 /* Not a root path? */
415 if (MountPoint.Buffer[(MountPoint.Length / sizeof(WCHAR)) - 1] != L'\\')
416 {
418 /* Zero output */
419 if (lpszVolumeName != NULL && cchBufferLength >= 1)
420 {
421 lpszVolumeName[0] = UNICODE_NULL;
422 }
423
424 return FALSE;
425 }
426
427 /* Does it look like <letter>:\? */
428 if (MountPoint.Length == 3 * sizeof(WCHAR))
429 {
430 /* Try to get volume name for root path */
431 Ret = GetVolumeNameForRoot(lpszMountPoint, lpszVolumeName, cchBufferLength);
432 /* It failed? */
433 if (!Ret)
434 {
435 /* If wasn't a drive letter, so maybe a reparse point? */
436 if (MountPoint.Buffer[1] != ':')
437 {
438 Ret = BasepGetVolumeNameFromReparsePoint(lpszMountPoint, lpszVolumeName, cchBufferLength, IsAMountPoint);
439 }
440 /* It was, so zero output */
441 else if (lpszVolumeName != NULL && cchBufferLength >= 1)
442 {
443 lpszVolumeName[0] = UNICODE_NULL;
444 }
445 }
446 }
447 else
448 {
449 /* Try to get volume name for root path */
450 Ret = GetVolumeNameForRoot(lpszMountPoint, lpszVolumeName, cchBufferLength);
451 /* It failed? */
452 if (!Ret)
453 {
454 /* It was a DOS volume as UNC name, so fail and zero output */
455 if (MountPoint.Length == 14 && MountPoint.Buffer[0] == '\\' && MountPoint.Buffer[1] == '\\' &&
456 (MountPoint.Buffer[2] == '.' || MountPoint.Buffer[2] == '?') && MountPoint.Buffer[3] == L'\\' &&
457 MountPoint.Buffer[5] == ':')
458 {
459 if (lpszVolumeName != NULL && cchBufferLength >= 1)
460 {
461 lpszVolumeName[0] = UNICODE_NULL;
462 }
463 }
464 /* Maybe it's a reparse point? */
465 else
466 {
467 Ret = BasepGetVolumeNameFromReparsePoint(lpszMountPoint, lpszVolumeName, cchBufferLength, IsAMountPoint);
468 }
469 }
470 }
471
472 return Ret;
473}
474
494BOOL
495WINAPI
498 IN DWORD VolumeNameLength)
499{
500 BOOL Ret;
501
502 /* Just query our internal function */
504 VolumeNameLength, NULL);
505 if (!Ret && VolumeName != NULL && VolumeNameLength >= 1)
506 {
508 }
509
510 return Ret;
511}
512
513/*
514 * @implemented
515 */
516BOOL
517WINAPI
519 IN LPSTR lpszVolumeName,
520 IN DWORD cchBufferLength)
521{
522 BOOL Ret;
524 UNICODE_STRING VolumeNameU;
525 PUNICODE_STRING VolumeMountPointU;
526
527 /* Convert mount point to unicode */
528 VolumeMountPointU = Basep8BitStringToStaticUnicodeString(lpszVolumeMountPoint);
529 if (VolumeMountPointU == NULL)
530 {
531 return FALSE;
532 }
533
534 /* Initialize the strings we'll use for convention */
535 VolumeName.Buffer = lpszVolumeName;
536 VolumeName.Length = 0;
537 VolumeName.MaximumLength = cchBufferLength - 1;
538
539 VolumeNameU.Length = 0;
540 VolumeNameU.MaximumLength = (cchBufferLength - 1) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
541 /* Allocate a buffer big enough to contain the returned name */
542 VolumeNameU.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, VolumeNameU.MaximumLength);
543 if (VolumeNameU.Buffer == NULL)
544 {
546 return FALSE;
547 }
548
549 /* Query -W */
550 Ret = GetVolumeNameForVolumeMountPointW(VolumeMountPointU->Buffer, VolumeNameU.Buffer, cchBufferLength);
551 /* If it succeed, perform -A conversion */
552 if (Ret)
553 {
555
556 /* Reinit our string for length */
557 RtlInitUnicodeString(&VolumeNameU, VolumeNameU.Buffer);
558 /* Convert to ANSI */
560 /* If conversion failed, force failure, otherwise, just null terminate */
561 if (!NT_SUCCESS(Status))
562 {
563 Ret = FALSE;
565 }
566 else
567 {
569 }
570 }
571
572 /* Internal buffer no longer needed */
573 RtlFreeHeap(RtlGetProcessHeap(), 0, VolumeNameU.Buffer);
574
575 return Ret;
576}
577
578/*
579 * @unimplemented
580 */
581BOOL
582WINAPI
583SetVolumeMountPointW(IN LPCWSTR lpszVolumeMountPoint,
584 IN LPCWSTR lpszVolumeName)
585{
586 STUB;
587 return 0;
588}
589
590/*
591 * @unimplemented
592 */
593BOOL
594WINAPI
595SetVolumeMountPointA(IN LPCSTR lpszVolumeMountPoint,
596 IN LPCSTR lpszVolumeName)
597{
598 STUB;
599 return 0;
600}
601
602/*
603 * @unimplemented
604 */
605BOOL
606WINAPI
607DeleteVolumeMountPointA(IN LPCSTR lpszVolumeMountPoint)
608{
609 STUB;
610 return 0;
611}
612
613/*
614 * @unimplemented
615 */
616BOOL
617WINAPI
618DeleteVolumeMountPointW(IN LPCWSTR lpszVolumeMountPoint)
619{
620 STUB;
621 return 0;
622}
623
624/*
625 * @unimplemented
626 */
627HANDLE
628WINAPI
630 IN LPWSTR lpszVolumeMountPoint,
631 IN DWORD cchBufferLength)
632{
633 STUB;
634 return 0;
635}
636
637/*
638 * @unimplemented
639 */
640HANDLE
641WINAPI
643 IN LPSTR lpszVolumeMountPoint,
644 IN DWORD cchBufferLength)
645{
646 STUB;
647 return 0;
648}
649
650/*
651 * @unimplemented
652 */
653BOOL
654WINAPI
655FindNextVolumeMountPointA(IN HANDLE hFindVolumeMountPoint,
656 IN LPSTR lpszVolumeMountPoint,
657 DWORD cchBufferLength)
658{
659 STUB;
660 return 0;
661}
662
663/*
664 * @unimplemented
665 */
666BOOL
667WINAPI
668FindNextVolumeMountPointW(IN HANDLE hFindVolumeMountPoint,
669 IN LPWSTR lpszVolumeMountPoint,
670 DWORD cchBufferLength)
671{
672 STUB;
673 return 0;
674}
675
676/*
677 * @unimplemented
678 */
679BOOL
680WINAPI
681FindVolumeMountPointClose(IN HANDLE hFindVolumeMountPoint)
682{
683 STUB;
684 return 0;
685}
686
687/* EOF */
LONG NTSTATUS
Definition: precomp.h:26
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define BufferSize
Definition: mmc.h:75
BOOL WINAPI DeviceIoControl(IN HANDLE hDevice, IN DWORD dwIoControlCode, IN LPVOID lpInBuffer OPTIONAL, IN DWORD nInBufferSize OPTIONAL, OUT LPVOID lpOutBuffer OPTIONAL, IN DWORD nOutBufferSize OPTIONAL, OUT LPDWORD lpBytesReturned OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: deviceio.c:136
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define CloseHandle
Definition: compat.h:739
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define OPEN_EXISTING
Definition: compat.h:775
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define MAX_PATH
Definition: compat.h:34
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define FILE_SHARE_READ
Definition: compat.h:136
UINT WINAPI GetDriveTypeW(IN LPCWSTR lpRootPathName)
Definition: disk.c:497
PUNICODE_STRING WINAPI Basep8BitStringToStaticUnicodeString(IN LPCSTR String)
Definition: utils.c:188
static const WCHAR SymbolicLink[]
Definition: interface.c:31
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _Inout_opt_ PUNICODE_STRING VolumeName
Definition: fltkernel.h:1117
_Must_inspect_result_ _Out_ PHANDLE VolumeHandle
Definition: fltkernel.h:2283
#define FILE_SYNCHRONOUS_IO_ALERT
Definition: from_kernel.h:30
Status
Definition: gdiplustypes.h:25
#define _toupper(_Char)
Definition: ctype.h:655
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define STUB
Definition: kernel32.h:27
BOOL WINAPI FindVolumeMountPointClose(IN HANDLE hFindVolumeMountPoint)
Definition: mntpoint.c:681
BOOL WINAPI FindNextVolumeMountPointA(IN HANDLE hFindVolumeMountPoint, IN LPSTR lpszVolumeMountPoint, DWORD cchBufferLength)
Definition: mntpoint.c:655
BOOL WINAPI GetVolumeNameForVolumeMountPointA(IN LPCSTR lpszVolumeMountPoint, IN LPSTR lpszVolumeName, IN DWORD cchBufferLength)
Definition: mntpoint.c:518
BOOL WINAPI DeleteVolumeMountPointA(IN LPCSTR lpszVolumeMountPoint)
Definition: mntpoint.c:607
BOOL WINAPI FindNextVolumeMountPointW(IN HANDLE hFindVolumeMountPoint, IN LPWSTR lpszVolumeMountPoint, DWORD cchBufferLength)
Definition: mntpoint.c:668
BOOL WINAPI SetVolumeMountPointA(IN LPCSTR lpszVolumeMountPoint, IN LPCSTR lpszVolumeName)
Definition: mntpoint.c:595
BOOL WINAPI SetVolumeMountPointW(IN LPCWSTR lpszVolumeMountPoint, IN LPCWSTR lpszVolumeName)
Definition: mntpoint.c:583
BOOL WINAPI GetVolumeNameForVolumeMountPointW(IN LPCWSTR VolumeMountPoint, OUT LPWSTR VolumeName, IN DWORD VolumeNameLength)
Definition: mntpoint.c:496
BOOL BasepGetVolumeNameForVolumeMountPoint(IN LPCWSTR lpszMountPoint, OUT LPWSTR lpszVolumeName, IN DWORD cchBufferLength, OUT LPBOOL IsAMountPoint)
Definition: mntpoint.c:398
static BOOL GetVolumeNameForRoot(IN LPCWSTR lpszRootPath, OUT LPWSTR lpszVolumeName, IN DWORD cchBufferLength)
Definition: mntpoint.c:17
BOOL BasepGetVolumeNameFromReparsePoint(IN LPCWSTR lpszMountPoint, OUT LPWSTR lpszVolumeName, IN DWORD cchBufferLength, OUT LPBOOL IsAMountPoint)
Definition: mntpoint.c:257
HANDLE WINAPI FindFirstVolumeMountPointA(IN LPCSTR lpszRootPathName, IN LPSTR lpszVolumeMountPoint, IN DWORD cchBufferLength)
Definition: mntpoint.c:642
HANDLE WINAPI FindFirstVolumeMountPointW(IN LPCWSTR lpszRootPathName, IN LPWSTR lpszVolumeMountPoint, IN DWORD cchBufferLength)
Definition: mntpoint.c:629
BOOL WINAPI DeleteVolumeMountPointW(IN LPCWSTR lpszVolumeMountPoint)
Definition: mntpoint.c:618
#define FILE_FLAG_OPEN_REPARSE_POINT
Definition: disk.h:39
#define FILE_FLAG_BACKUP_SEMANTICS
Definition: disk.h:41
struct _MOUNTDEV_NAME MOUNTDEV_NAME
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
struct _MOUNTMGR_MOUNT_POINT MOUNTMGR_MOUNT_POINT
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define IOCTL_MOUNTMGR_QUERY_POINTS
Definition: mountmgr.h:30
#define MOUNTMGR_DOS_DEVICE_NAME
Definition: mountmgr.h:11
#define MOUNTMGR_IS_NT_VOLUME_NAME(s)
Definition: mountmgr.h:136
#define MOUNTMGR_IS_DOS_VOLUME_NAME_WB(s)
Definition: mountmgr.h:134
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)
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3952
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define UNICODE_NULL
#define ANSI_NULL
#define L(x)
Definition: ntvdm.h:50
#define FSCTL_GET_REPARSE_POINT
Definition: winioctl.h:97
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
MOUNTMGR_MOUNT_POINT MountPoints[1]
Definition: imports.h:177
USHORT DeviceNameLength
Definition: imports.h:171
USHORT SymbolicLinkNameLength
Definition: imports.h:167
ULONG SymbolicLinkNameOffset
Definition: imports.h:166
struct _REPARSE_DATA_BUFFER::@318::@321 MountPointReparseBuffer
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint16_t * PWSTR
Definition: typedefs.h:56
void * PVOID
Definition: typedefs.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_ ULONG _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesReturned
Definition: wdfiotarget.h:1052
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define DRIVE_REMOTE
Definition: winbase.h:253
BOOL * LPBOOL
Definition: windef.h:162
#define WINAPI
Definition: msvc.h:6
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
#define ERROR_FILENAME_EXCED_RANGE
Definition: winerror.h:263
#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE
Definition: iotypes.h:7213
#define IO_REPARSE_TAG_MOUNT_POINT
Definition: iotypes.h:7231
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185