ReactOS 0.4.16-dev-965-gf669426
device.c File Reference
#include "mntmgr.h"
#include <debug.h>
Include dependency graph for device.c:

Go to the source code of this file.

Macros

#define MAX_DEVICES   0x3E8 /* Matches 1000 devices */
 
#define NDEBUG
 

Functions

NTSTATUS MountMgrChangeNotify (IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
 
NTSTATUS MountmgrWriteNoAutoMount (IN PDEVICE_EXTENSION DeviceExtension)
 
NTSTATUS MountMgrSetAutoMount (IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
 
NTSTATUS MountMgrQueryAutoMount (IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
 
NTSTATUS NTAPI ScrubRegistryRoutine (IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
 
NTSTATUS MountMgrScrubRegistry (IN PDEVICE_EXTENSION DeviceExtension)
 
NTSTATUS MountMgrCreatePoint (IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
 
NTSTATUS MountMgrCheckUnprocessedVolumes (IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
 
BOOLEAN IsFtVolume (IN PUNICODE_STRING SymbolicName)
 
VOID ProcessSuggestedDriveLetters (IN PDEVICE_EXTENSION DeviceExtension)
 
NTSTATUS MountMgrNextDriveLetterWorker (IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName, OUT PMOUNTMGR_DRIVE_LETTER_INFORMATION DriveLetterInfo)
 
NTSTATUS MountMgrNextDriveLetter (IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
 
NTSTATUS NTAPI MountMgrQuerySystemVolumeNameQueryRoutine (IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
 
NTSTATUS MountMgrQuerySystemVolumeName (OUT PUNICODE_STRING SystemVolumeName)
 
VOID MountMgrAssignDriveLetters (IN PDEVICE_EXTENSION DeviceExtension)
 
NTSTATUS MountMgrQueryDosVolumePath (IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
 
NTSTATUS MountMgrValidateBackPointer (IN PASSOCIATED_DEVICE_ENTRY AssociatedDeviceEntry, IN PDEVICE_INFORMATION DeviceInformation, OUT PBOOLEAN Invalid)
 
NTSTATUS MountMgrQueryVolumePaths (IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation, IN PLIST_ENTRY DeviceInfoList, OUT PMOUNTMGR_VOLUME_PATHS *VolumePaths, OUT PDEVICE_INFORMATION *FailedDevice)
 
NTSTATUS MountMgrQueryDosVolumePaths (IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
 
NTSTATUS MountMgrKeepLinksWhenOffline (IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
 
NTSTATUS MountMgrVolumeArrivalNotification (IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
 
NTSTATUS MountMgrQueryPoints (IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
 
NTSTATUS MountMgrDeletePoints (IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
 
NTSTATUS MountMgrDeletePointsDbOnly (IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
 
NTSTATUS MountMgrVolumeMountPointChanged (IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp, IN NTSTATUS LockStatus, OUT PUNICODE_STRING SourceDeviceName, OUT PUNICODE_STRING SourceSymbolicName, OUT PUNICODE_STRING TargetVolumeName)
 
NTSTATUS MountMgrVolumeMountPointCreated (IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp, IN NTSTATUS LockStatus)
 
NTSTATUS MountMgrVolumeMountPointDeleted (IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp, IN NTSTATUS LockStatus)
 
NTSTATUS NTAPI MountMgrDeviceControl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 

Macro Definition Documentation

◆ MAX_DEVICES

#define MAX_DEVICES   0x3E8 /* Matches 1000 devices */

Definition at line 28 of file device.c.

◆ NDEBUG

#define NDEBUG

Definition at line 30 of file device.c.

Function Documentation

◆ IsFtVolume()

BOOLEAN IsFtVolume ( IN PUNICODE_STRING  SymbolicName)

Definition at line 331 of file device.c.

332{
336 PDEVICE_OBJECT DeviceObject, FileDeviceObject;
337
338 /* Get device object */
341 &FileObject,
342 &DeviceObject);
343 if (!NT_SUCCESS(Status))
344 return FALSE;
345
346 /* Get attached device */
347 FileDeviceObject = FileObject->DeviceObject;
348 DeviceObject = IoGetAttachedDeviceReference(FileDeviceObject);
349
350 /* FT volume can't be removable */
351 if (FileDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
352 {
355 return FALSE;
356 }
357
359
360 /* Get partition information */
361 Status = MountMgrSendSyncDeviceIoCtl(IOCTL_DISK_GET_PARTITION_INFO,
363 NULL,
364 0,
366 sizeof(PartitionInfo),
367 NULL);
368
370 if (!NT_SUCCESS(Status))
371 return FALSE;
372
373 /* Check if this is a FT volume */
374 return IsFTPartition(PartitionInfo.PartitionType);
375}
LONG NTSTATUS
Definition: precomp.h:26
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
Status
Definition: gdiplustypes.h:25
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4677
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define IsFTPartition(PartitionType)
Definition: ntdddisk.h:315
#define IOCTL_DISK_GET_PARTITION_INFO
Definition: ntdddisk.h:106
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2105
* PFILE_OBJECT
Definition: iotypes.h:1998
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by MountMgrNextDriveLetterWorker().

◆ MountMgrAssignDriveLetters()

VOID MountMgrAssignDriveLetters ( IN PDEVICE_EXTENSION  DeviceExtension)

Definition at line 737 of file device.c.

738{
740 PLIST_ENTRY NextEntry;
741 UNICODE_STRING SystemVolumeName;
742 PDEVICE_INFORMATION DeviceInformation;
743 MOUNTMGR_DRIVE_LETTER_INFORMATION DriveLetterInformation;
744
745 /* First, get system volume name */
746 Status = MountMgrQuerySystemVolumeName(&SystemVolumeName);
747
748 /* If there are no device, it's all done */
749 if (IsListEmpty(&(DeviceExtension->DeviceListHead)))
750 {
751 if (NT_SUCCESS(Status))
752 {
753 FreePool(SystemVolumeName.Buffer);
754 }
755
756 return;
757 }
758
759 /* Now, for all the devices... */
760 for (NextEntry = DeviceExtension->DeviceListHead.Flink;
761 NextEntry != &(DeviceExtension->DeviceListHead);
762 NextEntry = NextEntry->Flink)
763 {
764 DeviceInformation = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
765
766 /* If the device doesn't have a letter assigned, do it! */
767 if (!DeviceInformation->LetterAssigned)
768 {
769 MountMgrNextDriveLetterWorker(DeviceExtension,
770 &(DeviceInformation->DeviceName),
771 &DriveLetterInformation);
772 }
773
774 /* If it's the system volume */
775 if (NT_SUCCESS(Status) && RtlEqualUnicodeString(&SystemVolumeName, &(DeviceInformation->DeviceName), TRUE))
776 {
777 /* Keep track of it */
778 DeviceExtension->DriveLetterData = AllocatePool(DeviceInformation->UniqueId->UniqueIdLength +
779 sizeof(MOUNTDEV_UNIQUE_ID));
780 if (DeviceExtension->DriveLetterData)
781 {
782 RtlCopyMemory(DeviceExtension->DriveLetterData,
783 DeviceInformation->UniqueId,
784 DeviceInformation->UniqueId->UniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
785 }
786
787 /* Ensure it gets mounted if automount is disabled */
788 if (DeviceExtension->NoAutoMount)
789 {
790 /* Temporarily re-enable automount for the
791 * worker to mount and set a drive letter */
792 DeviceExtension->NoAutoMount = FALSE;
793
794 MountMgrNextDriveLetterWorker(DeviceExtension,
795 &(DeviceInformation->DeviceName),
796 &DriveLetterInformation);
797
798 /* And re-disable automount */
799 DeviceExtension->NoAutoMount = TRUE;
800 }
801 }
802 }
803
804 if (NT_SUCCESS(Status))
805 {
806 FreePool(SystemVolumeName.Buffer);
807 }
808}
#define TRUE
Definition: types.h:120
NTSTATUS MountMgrQuerySystemVolumeName(OUT PUNICODE_STRING SystemVolumeName)
Definition: device.c:708
NTSTATUS MountMgrNextDriveLetterWorker(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName, OUT PMOUNTMGR_DRIVE_LETTER_INFORMATION DriveLetterInfo)
Definition: device.c:435
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define AllocatePool(Size)
Definition: mntmgr.h:153
#define FreePool(P)
Definition: mntmgr.h:154
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
BOOLEAN LetterAssigned
Definition: mntmgr.h:55
PMOUNTDEV_UNIQUE_ID UniqueId
Definition: mntmgr.h:49
UNICODE_STRING DeviceName
Definition: mntmgr.h:50
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
USHORT UniqueIdLength
Definition: imports.h:136
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by MountMgrDeviceControl().

◆ MountMgrChangeNotify()

NTSTATUS MountMgrChangeNotify ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 37 of file device.c.

39{
44
45 /* Get the I/O buffer */
47 ChangeNotify = (PMOUNTMGR_CHANGE_NOTIFY_INFO)Irp->AssociatedIrp.SystemBuffer;
48
49 /* Validate it */
50 if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTMGR_CHANGE_NOTIFY_INFO) ||
51 Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_CHANGE_NOTIFY_INFO))
52 {
54 }
55
56 /* If epic number doesn't match, just return now one */
57 if (DeviceExtension->EpicNumber != ChangeNotify->EpicNumber)
58 {
59 ChangeNotify->EpicNumber = DeviceExtension->EpicNumber;
60 Irp->IoStatus.Information = sizeof(MOUNTMGR_CHANGE_NOTIFY_INFO);
61 return STATUS_SUCCESS;
62 }
63
64 /* If IRP is to be canceled, forget about that */
66 if (Irp->Cancel)
67 {
69 }
70 /* Otherwise queue the IRP to be notified with the next epic number change */
71 else
72 {
73 InsertTailList(&(DeviceExtension->IrpListHead), &(Irp->Tail.Overlay.ListEntry));
77 }
79
80 return Status;
81}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_PENDING
Definition: d3dkmdt.h:43
#define InsertTailList(ListHead, Entry)
UCHAR KIRQL
Definition: env_spec_w32.h:591
IoMarkIrpPending(Irp)
IoSetCancelRoutine(Irp, CancelRoutine)
if(dx< 0)
Definition: linetemp.h:194
VOID NTAPI MountMgrCancel(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: mountmgr.c:1592
struct _MOUNTMGR_CHANGE_NOTIFY_INFO * PMOUNTMGR_CHANGE_NOTIFY_INFO
struct _MOUNTMGR_CHANGE_NOTIFY_INFO MOUNTMGR_CHANGE_NOTIFY_INFO
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
VOID NTAPI IoAcquireCancelSpinLock(OUT PKIRQL Irql)
Definition: util.c:56
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by MountMgrDeviceControl().

◆ MountMgrCheckUnprocessedVolumes()

NTSTATUS MountMgrCheckUnprocessedVolumes ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 288 of file device.c.

290{
291 PLIST_ENTRY NextEntry;
292 PDEVICE_INFORMATION DeviceInformation;
293 NTSTATUS ArrivalStatus, Status = STATUS_SUCCESS;
294
296
297 /* No offline volumes, nothing more to do */
298 if (IsListEmpty(&(DeviceExtension->OfflineDeviceListHead)))
299 {
300 KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
301 return STATUS_SUCCESS;
302 }
303
304 KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
305
306 /* Reactivate all the offline volumes */
307 while (!IsListEmpty(&(DeviceExtension->OfflineDeviceListHead)))
308 {
309 NextEntry = RemoveHeadList(&(DeviceExtension->OfflineDeviceListHead));
310 DeviceInformation = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
311
312 ArrivalStatus = MountMgrMountedDeviceArrival(DeviceExtension,
313 &(DeviceInformation->SymbolicName),
314 DeviceInformation->ManuallyRegistered);
315 /* Then, remove them dead information */
316 MountMgrFreeDeadDeviceInfo(DeviceInformation);
317
318 if (NT_SUCCESS(Status))
319 {
320 Status = ArrivalStatus;
321 }
322 }
323
324 return Status;
325}
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
VOID MountMgrFreeDeadDeviceInfo(IN PDEVICE_INFORMATION DeviceInformation)
Definition: mountmgr.c:626
NTSTATUS MountMgrMountedDeviceArrival(IN PDEVICE_EXTENSION Extension, IN PUNICODE_STRING SymbolicName, IN BOOLEAN FromVolume)
Definition: mountmgr.c:855
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
UNICODE_STRING SymbolicName
Definition: mntmgr.h:48
BOOLEAN ManuallyRegistered
Definition: mntmgr.h:53
#define IO_NO_INCREMENT
Definition: iotypes.h:598

Referenced by MountMgrDeviceControl().

◆ MountMgrCreatePoint()

NTSTATUS MountMgrCreatePoint ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 249 of file device.c.

251{
252 ULONG MaxLength;
256
258
259 if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_CREATE_POINT_INPUT))
260 {
262 }
263
264 Point = (PMOUNTMGR_CREATE_POINT_INPUT)Irp->AssociatedIrp.SystemBuffer;
265
266 MaxLength = MAX((Point->DeviceNameOffset + Point->DeviceNameLength),
267 (Point->SymbolicLinkNameLength + Point->SymbolicLinkNameOffset));
268 if (MaxLength > Stack->Parameters.DeviceIoControl.InputBufferLength)
269 {
271 }
272
273 /* Get all the strings and call the worker */
274 SymbolicName.Length = Point->SymbolicLinkNameLength;
275 SymbolicName.MaximumLength = Point->SymbolicLinkNameLength;
276 DeviceName.Length = Point->DeviceNameLength;
277 DeviceName.MaximumLength = Point->DeviceNameLength;
278 SymbolicName.Buffer = (PVOID)((ULONG_PTR)Point + Point->SymbolicLinkNameOffset);
279 DeviceName.Buffer = (PVOID)((ULONG_PTR)Point + Point->DeviceNameOffset);
280
281 return MountMgrCreatePointWorker(DeviceExtension, &SymbolicName, &DeviceName);
282}
#define MAX(x, y)
Definition: rdesktop.h:175
NTSTATUS MountMgrCreatePointWorker(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicLinkName, IN PUNICODE_STRING DeviceName)
Definition: point.c:35
struct _MOUNTMGR_CREATE_POINT_INPUT * PMOUNTMGR_CREATE_POINT_INPUT
USHORT MaximumLength
Definition: env_spec_w32.h:370
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275

Referenced by MountMgrDeviceControl().

◆ MountMgrDeletePoints()

NTSTATUS MountMgrDeletePoints ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 1822 of file device.c.

1824{
1825 ULONG Link;
1827 BOOLEAN CreateNoDrive;
1829 PMOUNTDEV_UNIQUE_ID UniqueId;
1830 PMOUNTMGR_MOUNT_POINT MountPoint;
1831 PMOUNTMGR_MOUNT_POINTS MountPoints;
1833
1835
1836 /* Validate input */
1837 if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_MOUNT_POINT))
1838 {
1840 }
1841
1842 /* Query points */
1843 MountPoint = (PMOUNTMGR_MOUNT_POINT)Irp->AssociatedIrp.SystemBuffer;
1844 CreateNoDrive = (MountPoint->SymbolicLinkNameOffset && MountPoint->SymbolicLinkNameLength);
1845
1846 Status = MountMgrQueryPoints(DeviceExtension, Irp);
1847 if (!NT_SUCCESS(Status))
1848 {
1849 return Status;
1850 }
1851
1852 /* For all the points matching the request */
1853 MountPoints = (PMOUNTMGR_MOUNT_POINTS)Irp->AssociatedIrp.SystemBuffer;
1854 for (Link = 0; Link < MountPoints->NumberOfMountPoints; Link++)
1855 {
1859 if (!SymbolicName.Buffer)
1860 {
1862 }
1863
1865 (PWSTR)((ULONG_PTR)MountPoints + MountPoints->MountPoints[Link].SymbolicLinkNameOffset),
1868
1869 /* Create a no drive entry for the drive letters */
1870 if (CreateNoDrive && IsDriveLetter(&SymbolicName))
1871 {
1872 UniqueId = AllocatePool(MountPoints->MountPoints[Link].UniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
1873 if (UniqueId)
1874 {
1875 UniqueId->UniqueIdLength = MountPoints->MountPoints[Link].UniqueIdLength;
1876 RtlCopyMemory(UniqueId->UniqueId,
1877 (PMOUNTDEV_UNIQUE_ID)((ULONG_PTR)MountPoints + MountPoints->MountPoints[Link].UniqueIdOffset),
1878 MountPoints->MountPoints[Link].UniqueIdLength);
1879
1880 CreateNoDriveLetterEntry(UniqueId);
1881 FreePool(UniqueId);
1882 }
1883 }
1884
1885 /* If there are no link any more, and no need to create a no drive entry */
1886 if (Link == 0 && !CreateNoDrive)
1887 {
1888 /* Then, delete everything */
1889 UniqueId = AllocatePool(MountPoints->MountPoints[Link].UniqueIdLength);
1890 if (UniqueId)
1891 {
1892 RtlCopyMemory(UniqueId,
1893 (PMOUNTDEV_UNIQUE_ID)((ULONG_PTR)MountPoints + MountPoints->MountPoints[Link].UniqueIdOffset),
1894 MountPoints->MountPoints[Link].UniqueIdLength);
1895
1896 DeleteNoDriveLetterEntry(UniqueId);
1897 FreePool(UniqueId);
1898 }
1899 }
1900
1901 /* Delete all the information about the mount point */
1906
1907 /* Notify the change */
1908 DeviceName.Length = DeviceName.MaximumLength =
1909 MountPoints->MountPoints[Link].DeviceNameLength;
1910 DeviceName.Buffer = (PWSTR)((ULONG_PTR)MountPoints + MountPoints->MountPoints[Link].DeviceNameOffset);
1911 MountMgrNotifyNameChange(DeviceExtension, &DeviceName, TRUE);
1912 }
1913
1914 MountMgrNotify(DeviceExtension);
1915
1916 return Status;
1917}
unsigned char BOOLEAN
VOID DeleteNoDriveLetterEntry(IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: database.c:2100
PWSTR DatabasePath
Definition: database.c:31
NTSTATUS MountMgrQueryPoints(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:1677
NTSYSAPI NTSTATUS WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR)
NTSTATUS GlobalDeleteSymbolicLink(IN PUNICODE_STRING DosName)
Definition: symlink.c:145
VOID MountMgrNotifyNameChange(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName, IN BOOLEAN ValidateVolume)
Definition: notify.c:328
BOOLEAN IsDriveLetter(PUNICODE_STRING SymbolicName)
Definition: symlink.c:812
VOID MountMgrNotify(IN PDEVICE_EXTENSION DeviceExtension)
Definition: notify.c:288
VOID DeleteSymbolicLinkNameFromMemory(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicLink, IN BOOLEAN MarkOffline)
Definition: symlink.c:754
VOID CreateNoDriveLetterEntry(IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: uniqueid.c:269
#define for
Definition: utility.h:88
struct _MOUNTMGR_MOUNT_POINT * PMOUNTMGR_MOUNT_POINT
struct _MOUNTMGR_MOUNT_POINTS * PMOUNTMGR_MOUNT_POINTS
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define UNICODE_NULL
UCHAR UniqueId[1]
Definition: imports.h:137
MOUNTMGR_MOUNT_POINT MountPoints[1]
Definition: imports.h:175
USHORT DeviceNameLength
Definition: imports.h:169
USHORT SymbolicLinkNameLength
Definition: imports.h:165
ULONG SymbolicLinkNameOffset
Definition: imports.h:164
uint16_t * PWSTR
Definition: typedefs.h:56
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
static int Link(const char **args)
Definition: vfdcmd.c:2414
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by MountMgrDeviceControl().

◆ MountMgrDeletePointsDbOnly()

NTSTATUS MountMgrDeletePointsDbOnly ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 1923 of file device.c.

1925{
1926 ULONG Link;
1929 PMOUNTDEV_UNIQUE_ID UniqueId;
1930 PMOUNTMGR_MOUNT_POINTS MountPoints;
1931
1932 /* Query points */
1933 Status = MountMgrQueryPoints(DeviceExtension, Irp);
1934 if (!NT_SUCCESS(Status))
1935 {
1936 return Status;
1937 }
1938
1939 MountPoints = (PMOUNTMGR_MOUNT_POINTS)Irp->AssociatedIrp.SystemBuffer;
1940 if (MountPoints->NumberOfMountPoints == 0)
1941 {
1942 return Status;
1943 }
1944
1945 /* For all the mount points */
1946 for (Link = 0; Link < MountPoints->NumberOfMountPoints; Link++)
1947 {
1951 if (!SymbolicName.Buffer)
1952 {
1954 }
1955
1957 (PWSTR)((ULONG_PTR)MountPoints + MountPoints->MountPoints[Link].SymbolicLinkNameOffset),
1960
1961 /* If the only mount point is a drive letter, then create a no letter drive entry */
1962 if (MountPoints->NumberOfMountPoints == 1 && IsDriveLetter(&SymbolicName))
1963 {
1964 UniqueId = AllocatePool(MountPoints->MountPoints[Link].UniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
1965 if (UniqueId)
1966 {
1967 UniqueId->UniqueIdLength = MountPoints->MountPoints[Link].UniqueIdLength;
1968 RtlCopyMemory(UniqueId->UniqueId,
1969 (PMOUNTDEV_UNIQUE_ID)((ULONG_PTR)MountPoints + MountPoints->MountPoints[Link].UniqueIdOffset),
1970 MountPoints->MountPoints[Link].UniqueIdLength);
1971
1972 CreateNoDriveLetterEntry(UniqueId);
1973 FreePool(UniqueId);
1974 }
1975 }
1976
1977 /* Simply delete mount point from DB */
1981 }
1982
1983 return Status;
1984}

Referenced by MountMgrDeviceControl().

◆ MountMgrDeviceControl()

NTSTATUS NTAPI MountMgrDeviceControl ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 2668 of file device.c.

2670{
2672 NTSTATUS Status, LockStatus;
2673 PDEVICE_EXTENSION DeviceExtension;
2674
2676 DeviceExtension = DeviceObject->DeviceExtension;
2677
2678 KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
2679
2680 switch (Stack->Parameters.DeviceIoControl.IoControlCode)
2681 {
2683 Status = MountMgrCreatePoint(DeviceExtension, Irp);
2684 break;
2685
2687 Status = MountMgrDeletePoints(DeviceExtension, Irp);
2688 break;
2689
2691 Status = MountMgrQueryPoints(DeviceExtension, Irp);
2692 break;
2693
2695 Status = MountMgrDeletePointsDbOnly(DeviceExtension, Irp);
2696 break;
2697
2699 Status = MountMgrNextDriveLetter(DeviceExtension, Irp);
2700 break;
2701
2703 // NOTE: On Win7+, this is handled during driver re-initialization.
2704 DeviceExtension->AutomaticDriveLetter = TRUE;
2705 MountMgrAssignDriveLetters(DeviceExtension);
2706 ReconcileAllDatabasesWithMaster(DeviceExtension);
2707 WaitForOnlinesToComplete(DeviceExtension);
2709 break;
2710
2712 KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
2713
2714 LockStatus = WaitForRemoteDatabaseSemaphore(DeviceExtension);
2715 KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
2716 Status = MountMgrVolumeMountPointCreated(DeviceExtension, Irp, LockStatus);
2717 if (NT_SUCCESS(LockStatus))
2718 {
2719 ReleaseRemoteDatabaseSemaphore(DeviceExtension);
2720 }
2721
2722 break;
2723
2725 KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
2726
2727 LockStatus = WaitForRemoteDatabaseSemaphore(DeviceExtension);
2728 KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
2729 Status = MountMgrVolumeMountPointDeleted(DeviceExtension, Irp, LockStatus);
2730 if (NT_SUCCESS(LockStatus))
2731 {
2732 ReleaseRemoteDatabaseSemaphore(DeviceExtension);
2733 }
2734
2735 break;
2736
2738 Status = MountMgrChangeNotify(DeviceExtension, Irp);
2739 break;
2740
2742 Status = MountMgrKeepLinksWhenOffline(DeviceExtension, Irp);
2743 break;
2744
2746 Status = MountMgrCheckUnprocessedVolumes(DeviceExtension, Irp);
2747 goto Complete;
2748
2750 KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
2751 Status = MountMgrVolumeArrivalNotification(DeviceExtension, Irp);
2752 goto Complete;
2753
2755 Status = MountMgrQueryDosVolumePath(DeviceExtension, Irp);
2756 break;
2757
2759 Status = MountMgrQueryDosVolumePaths(DeviceExtension, Irp);
2760 break;
2761
2763 Status = MountMgrScrubRegistry(DeviceExtension);
2764 break;
2765
2767 Status = MountMgrQueryAutoMount(DeviceExtension, Irp);
2768 break;
2769
2771 Status = MountMgrSetAutoMount(DeviceExtension, Irp);
2772 break;
2773
2774 default:
2776 }
2777
2778 KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
2779
2780 if (Status != STATUS_PENDING)
2781 {
2782 goto Complete;
2783 }
2784
2785 return Status;
2786
2787Complete:
2788 Irp->IoStatus.Status = Status;
2790
2791 return Status;
2792}
NTSTATUS WaitForRemoteDatabaseSemaphore(IN PDEVICE_EXTENSION DeviceExtension)
Definition: database.c:371
VOID ReleaseRemoteDatabaseSemaphore(IN PDEVICE_EXTENSION DeviceExtension)
Definition: database.c:391
VOID ReconcileAllDatabasesWithMaster(IN PDEVICE_EXTENSION DeviceExtension)
Definition: database.c:1659
NTSTATUS MountMgrVolumeMountPointDeleted(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp, IN NTSTATUS LockStatus)
Definition: device.c:2455
NTSTATUS MountMgrVolumeArrivalNotification(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:1633
NTSTATUS MountMgrDeletePoints(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:1822
NTSTATUS MountMgrKeepLinksWhenOffline(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:1588
NTSTATUS MountMgrVolumeMountPointCreated(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp, IN NTSTATUS LockStatus)
Definition: device.c:2216
NTSTATUS MountMgrScrubRegistry(IN PDEVICE_EXTENSION DeviceExtension)
Definition: device.c:221
NTSTATUS MountMgrQueryDosVolumePaths(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:1438
NTSTATUS MountMgrChangeNotify(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:37
NTSTATUS MountMgrQueryAutoMount(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:136
NTSTATUS MountMgrDeletePointsDbOnly(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:1923
NTSTATUS MountMgrCheckUnprocessedVolumes(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:288
NTSTATUS MountMgrNextDriveLetter(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:621
VOID MountMgrAssignDriveLetters(IN PDEVICE_EXTENSION DeviceExtension)
Definition: device.c:737
NTSTATUS MountMgrCreatePoint(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:249
NTSTATUS MountMgrQueryDosVolumePath(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:814
NTSTATUS MountMgrSetAutoMount(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:103
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
pRequest Complete(RequestStatus)
VOID WaitForOnlinesToComplete(IN PDEVICE_EXTENSION DeviceExtension)
Definition: notify.c:174
#define IOCTL_MOUNTMGR_DELETE_POINTS
Definition: imports.h:122
#define IOCTL_MOUNTMGR_CREATE_POINT
Definition: imports.h:116
#define IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION
Definition: imports.h:128
#define IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH
Definition: mountmgr.h:147
#define IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATHS
Definition: mountmgr.h:149
#define IOCTL_MOUNTMGR_AUTO_DL_ASSIGNMENTS
Definition: mountmgr.h:55
#define IOCTL_MOUNTMGR_QUERY_POINTS
Definition: mountmgr.h:49
#define IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED
Definition: mountmgr.h:59
#define IOCTL_MOUNTMGR_CHECK_UNPROCESSED_VOLUMES
Definition: mountmgr.h:65
#define IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER
Definition: mountmgr.h:53
#define IOCTL_MOUNTMGR_DELETE_POINTS_DBONLY
Definition: mountmgr.h:51
#define IOCTL_MOUNTMGR_KEEP_LINKS_WHEN_OFFLINE
Definition: mountmgr.h:63
#define IOCTL_MOUNTMGR_SCRUB_REGISTRY
Definition: mountmgr.h:170
#define IOCTL_MOUNTMGR_CHANGE_NOTIFY
Definition: mountmgr.h:61
#define IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED
Definition: mountmgr.h:57
#define IOCTL_MOUNTMGR_QUERY_AUTO_MOUNT
Definition: mountmgr.h:172
#define IOCTL_MOUNTMGR_SET_AUTO_MOUNT
Definition: mountmgr.h:174
#define KernelMode
Definition: asm.h:38
#define IoCompleteRequest
Definition: irp.c:1240
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
@ Executive
Definition: ketypes.h:415

◆ MountMgrKeepLinksWhenOffline()

NTSTATUS MountMgrKeepLinksWhenOffline ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 1588 of file device.c.

1590{
1595 PDEVICE_INFORMATION DeviceInformation;
1596
1598
1599 /* Validate input */
1600 if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_TARGET_NAME))
1601 {
1603 }
1604
1605 Target = (PMOUNTMGR_TARGET_NAME)Irp->AssociatedIrp.SystemBuffer;
1606 if (FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + Target->DeviceNameLength >
1607 Stack->Parameters.DeviceIoControl.InputBufferLength)
1608 {
1610 }
1611
1613 SymbolicName.MaximumLength = Target->DeviceNameLength;
1614 SymbolicName.Buffer = Target->DeviceName;
1615
1616 /* Find the associated device */
1617 Status = FindDeviceInfo(DeviceExtension, &SymbolicName, FALSE, &DeviceInformation);
1618 if (!NT_SUCCESS(Status))
1619 {
1620 return Status;
1621 }
1622
1623 /* Mark we want to keep links */
1624 DeviceInformation->KeepLinks = TRUE;
1625
1626 return STATUS_SUCCESS;
1627}
NTSTATUS FindDeviceInfo(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName, IN BOOLEAN DeviceNameGiven, OUT PDEVICE_INFORMATION *DeviceInformation)
Definition: mountmgr.c:561
struct _MOUNTMGR_TARGET_NAME * PMOUNTMGR_TARGET_NAME
BOOLEAN KeepLinks
Definition: mntmgr.h:51
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306

Referenced by MountMgrDeviceControl().

◆ MountMgrNextDriveLetter()

NTSTATUS MountMgrNextDriveLetter ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 621 of file device.c.

623{
627 PMOUNTMGR_DRIVE_LETTER_TARGET DriveLetterTarget;
628 MOUNTMGR_DRIVE_LETTER_INFORMATION DriveLetterInformation;
629
631
632 /* Validate input */
633 if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_DRIVE_LETTER_TARGET) ||
634 Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTMGR_DRIVE_LETTER_INFORMATION))
635 {
637 }
638
639 DriveLetterTarget = (PMOUNTMGR_DRIVE_LETTER_TARGET)Irp->AssociatedIrp.SystemBuffer;
641 Stack->Parameters.DeviceIoControl.InputBufferLength)
642 {
644 }
645
646 /* Call the worker */
647 DeviceName.Buffer = DriveLetterTarget->DeviceName;
648 DeviceName.Length =
649 DeviceName.MaximumLength = DriveLetterTarget->DeviceNameLength;
650
652 &DriveLetterInformation);
653 if (NT_SUCCESS(Status))
654 {
655 *(PMOUNTMGR_DRIVE_LETTER_INFORMATION)Irp->AssociatedIrp.SystemBuffer =
656 DriveLetterInformation;
657 Irp->IoStatus.Information = sizeof(MOUNTMGR_DRIVE_LETTER_INFORMATION);
658 }
659
660 return Status;
661}
struct _MOUNTMGR_DRIVE_LETTER_INFORMATION * PMOUNTMGR_DRIVE_LETTER_INFORMATION
struct _MOUNTMGR_DRIVE_LETTER_TARGET * PMOUNTMGR_DRIVE_LETTER_TARGET

Referenced by MountMgrDeviceControl().

◆ MountMgrNextDriveLetterWorker()

NTSTATUS MountMgrNextDriveLetterWorker ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PUNICODE_STRING  DeviceName,
OUT PMOUNTMGR_DRIVE_LETTER_INFORMATION  DriveLetterInfo 
)

Definition at line 435 of file device.c.

438{
440 UCHAR DriveLetter;
441 PLIST_ENTRY NextEntry;
442 PMOUNTDEV_UNIQUE_ID UniqueId;
443 BOOLEAN Removable, GptDriveLetter;
444 PDEVICE_INFORMATION DeviceInformation;
445 WCHAR NameBuffer[DRIVE_LETTER_LENGTH];
446 PSYMLINK_INFORMATION SymlinkInformation;
447 UNICODE_STRING TargetDeviceName, SymbolicName;
448
449 /* First, process suggested letters */
450 if (!DeviceExtension->ProcessedSuggestions)
451 {
452 ProcessSuggestedDriveLetters(DeviceExtension);
453 DeviceExtension->ProcessedSuggestions = TRUE;
454 }
455
456 /* Then, get information about the device */
457 Status = QueryDeviceInformation(DeviceName, &TargetDeviceName, NULL, &Removable, &GptDriveLetter, NULL, NULL, NULL);
458 if (!NT_SUCCESS(Status))
459 {
460 return Status;
461 }
462
463 /* Ensure we have such device */
464 NextEntry = DeviceExtension->DeviceListHead.Flink;
465 while (NextEntry != &(DeviceExtension->DeviceListHead))
466 {
467 DeviceInformation = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
468
469 if (RtlCompareUnicodeString(&(DeviceInformation->DeviceName), &TargetDeviceName, TRUE) == 0)
470 {
471 break;
472 }
473
474 NextEntry = NextEntry->Flink;
475 }
476
477 if (NextEntry == &(DeviceExtension->DeviceListHead))
478 {
479 FreePool(TargetDeviceName.Buffer);
481 }
482
483 /* Now, assume we will assign a letter */
484 DeviceInformation->LetterAssigned =
485 DriveLetterInfo->DriveLetterWasAssigned = TRUE;
486
487 /* Browse all the symlinks to check if there is already a drive letter */
488 NextEntry = DeviceInformation->SymbolicLinksListHead.Flink;
489 while (NextEntry != &(DeviceInformation->SymbolicLinksListHead))
490 {
491 SymlinkInformation = CONTAINING_RECORD(NextEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
492
493 /* If this is a drive letter and it is online, forget about new drive letter */
494 if (IsDriveLetter(&(SymlinkInformation->Name)) && SymlinkInformation->Online)
495 {
496 DriveLetterInfo->DriveLetterWasAssigned = FALSE;
497 DriveLetterInfo->CurrentDriveLetter = (CHAR)SymlinkInformation->Name.Buffer[LETTER_POSITION];
498 break;
499 }
500
501 NextEntry = NextEntry->Flink;
502 }
503
504 /* If we didn't find a drive letter online, ensure this is not
505 * a no-drive entry by querying GPT attributes & database */
506 if (NextEntry == &(DeviceInformation->SymbolicLinksListHead))
507 {
508 if (!GptDriveLetter || HasNoDriveLetterEntry(DeviceInformation->UniqueId))
509 {
510 DriveLetterInfo->DriveLetterWasAssigned = FALSE;
511 DriveLetterInfo->CurrentDriveLetter = 0;
512 goto Release;
513 }
514 }
515
516 /* If automount is disabled, and the device is not removable
517 * but needs a drive letter, don't assign one and bail out */
518 if (DeviceExtension->NoAutoMount && !Removable)
519 {
520 if (DriveLetterInfo->DriveLetterWasAssigned)
521 {
522 DriveLetterInfo->DriveLetterWasAssigned = FALSE;
523 DriveLetterInfo->CurrentDriveLetter = 0;
524 goto Release;
525 }
526 }
527
528 /* Stop now if we don't need to assign the drive a letter */
529 if (!DriveLetterInfo->DriveLetterWasAssigned)
530 goto Release;
531
532 /* Now everything is fine, begin drive letter assignment */
533
534 if (RtlPrefixUnicodeString(&DeviceFloppy, &TargetDeviceName, TRUE))
535 {
536 /* If the device is a floppy, start with letter A */
537 DriveLetter = 'A';
538 }
539 else if (RtlPrefixUnicodeString(&DeviceCdRom, &TargetDeviceName, TRUE))
540 {
541 /* If the device is a CD-ROM, start with letter D */
542 DriveLetter = 'D';
543 }
544 else
545 {
546 /* Finally, if it's a disk, use C */
547 DriveLetter = 'C';
548 }
549
550 /* We cannot set NO drive letter */
551 ASSERT(DeviceInformation->SuggestedDriveLetter != (UCHAR)-1);
552
553 /* If we don't have suggested letter but it's a FT volume, fail */
554 if (!DeviceInformation->SuggestedDriveLetter && IsFtVolume(&(DeviceInformation->DeviceName)))
555 {
556 DriveLetterInfo->DriveLetterWasAssigned = FALSE;
557 DriveLetterInfo->CurrentDriveLetter = 0;
558 goto Release;
559 }
560
561 /* Prepare buffer */
563 NameBuffer[COLON_POSITION] = L':';
564 SymbolicName.Buffer = NameBuffer;
567
568 /* It's all prepared, create mount point */
569 if (DeviceInformation->SuggestedDriveLetter)
570 {
571 DriveLetterInfo->CurrentDriveLetter = DeviceInformation->SuggestedDriveLetter;
572 NameBuffer[LETTER_POSITION] = DeviceInformation->SuggestedDriveLetter;
573
574 Status = MountMgrCreatePointWorker(DeviceExtension, &SymbolicName, &TargetDeviceName);
575 if (NT_SUCCESS(Status))
576 {
577 goto Release;
578 }
579 }
580
581 /* It failed with this letter... Try another one! */
582 for (DriveLetterInfo->CurrentDriveLetter = DriveLetter;
583 DriveLetterInfo->CurrentDriveLetter <= L'Z';
584 DriveLetterInfo->CurrentDriveLetter++)
585 {
586 NameBuffer[LETTER_POSITION] = DriveLetterInfo->CurrentDriveLetter;
587
588 Status = MountMgrCreatePointWorker(DeviceExtension, &SymbolicName, &TargetDeviceName);
589 if (NT_SUCCESS(Status))
590 {
591 break;
592 }
593 }
594
595 /* We failed setting a letter */
596 if (DriveLetterInfo->CurrentDriveLetter > L'Z')
597 {
598 DriveLetterInfo->DriveLetterWasAssigned = FALSE;
599 DriveLetterInfo->CurrentDriveLetter = 0;
600
601 /* Try at least to add a no drive letter entry */
602 Status = QueryDeviceInformation(&TargetDeviceName, NULL, &UniqueId, NULL, NULL, NULL, NULL, NULL);
603 if (NT_SUCCESS(Status))
604 {
605 CreateNoDriveLetterEntry(UniqueId);
606 FreePool(UniqueId);
607 }
608 }
609
610Release:
611 FreePool(TargetDeviceName.Buffer);
612
613 return STATUS_SUCCESS;
614}
#define CHAR(Char)
_In_ BOOLEAN Release
Definition: cdrom.h:920
BOOL NTAPI QueryDeviceInformation(_In_ PWCHAR DriveRoot, _Out_ PVOID DeviceInformation, _In_ ULONG BufferSize)
Retrieves disk device information.
Definition: query.c:79
BOOLEAN IsFtVolume(IN PUNICODE_STRING SymbolicName)
Definition: device.c:331
VOID ProcessSuggestedDriveLetters(IN PDEVICE_EXTENSION DeviceExtension)
Definition: device.c:381
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
UNICODE_STRING DeviceFloppy
Definition: symlink.c:43
#define COLON_POSITION
Definition: mntmgr.h:160
UNICODE_STRING DeviceCdRom
Definition: symlink.c:44
#define DRIVE_LETTER_LENGTH
Definition: mntmgr.h:161
#define LETTER_POSITION
Definition: mntmgr.h:159
UNICODE_STRING DosDevices
Definition: symlink.c:42
BOOLEAN HasNoDriveLetterEntry(IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: uniqueid.c:354
#define ASSERT(a)
Definition: mode.c:44
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
#define L(x)
Definition: ntvdm.h:50
@ Removable
Definition: arc.h:81
UCHAR SuggestedDriveLetter
Definition: mntmgr.h:52
LIST_ENTRY SymbolicLinksListHead
Definition: mntmgr.h:45
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by MountMgrAssignDriveLetters(), and MountMgrNextDriveLetter().

◆ MountMgrQueryAutoMount()

NTSTATUS MountMgrQueryAutoMount ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 136 of file device.c.

138{
141
143
144 if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTMGR_QUERY_AUTO_MOUNT))
145 {
146 Irp->IoStatus.Information = 0;
148 }
149
150 QueryState = (PMOUNTMGR_QUERY_AUTO_MOUNT)Irp->AssociatedIrp.SystemBuffer;
151 QueryState->CurrentState = !DeviceExtension->NoAutoMount;
152 Irp->IoStatus.Information = sizeof(MOUNTMGR_QUERY_AUTO_MOUNT);
153
154 return STATUS_SUCCESS;
155}
struct _MOUNTMGR_QUERY_AUTO_MOUNT * PMOUNTMGR_QUERY_AUTO_MOUNT
MOUNTMGR_AUTO_MOUNT_STATE CurrentState
Definition: mountmgr.h:183

Referenced by MountMgrDeviceControl().

◆ MountMgrQueryDosVolumePath()

NTSTATUS MountMgrQueryDosVolumePath ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 814 of file device.c.

816{
818 ULONG DevicesFound;
820 PLIST_ENTRY SymlinksEntry;
824 PWSTR DeviceString, OldBuffer;
825 USHORT DeviceLength, OldLength;
826 PDEVICE_INFORMATION DeviceInformation;
827 PSYMLINK_INFORMATION SymlinkInformation;
829
831
832 /* Validate input size */
833 if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_TARGET_NAME))
834 {
836 }
837
838 /* Ensure we have received UNICODE_STRING */
839 Target = (PMOUNTMGR_TARGET_NAME)Irp->AssociatedIrp.SystemBuffer;
840 if (Target->DeviceNameLength & 1)
841 {
843 }
844
845 /* Validate the entry structure size */
846 if (FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + Target->DeviceNameLength >
847 Stack->Parameters.DeviceIoControl.InputBufferLength)
848 {
850 }
851
852 /* Ensure we can at least return needed size */
853 if (Stack->Parameters.DeviceIoControl.OutputBufferLength < FIELD_OFFSET(MOUNTMGR_VOLUME_PATHS, MultiSz))
854 {
856 }
857
858 /* Construct string for query */
860 SymbolicName.MaximumLength = Target->DeviceNameLength;
861 SymbolicName.Buffer = Target->DeviceName;
862
863 /* Find device with our info */
864 Status = FindDeviceInfo(DeviceExtension, &SymbolicName, FALSE, &DeviceInformation);
865 if (!NT_SUCCESS(Status))
866 {
867 return Status;
868 }
869
870 DeviceLength = 0;
871 DeviceString = NULL;
872 DevicesFound = 0;
873
874 /* Try to find associated device info */
875 while (TRUE)
876 {
877 for (SymlinksEntry = DeviceInformation->SymbolicLinksListHead.Flink;
878 SymlinksEntry != &(DeviceInformation->SymbolicLinksListHead);
879 SymlinksEntry = SymlinksEntry->Flink)
880 {
881 SymlinkInformation = CONTAINING_RECORD(SymlinksEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
882
883 /* Try to find with drive letter */
884 if (MOUNTMGR_IS_DRIVE_LETTER(&SymlinkInformation->Name) && SymlinkInformation->Online)
885 {
886 break;
887 }
888 }
889
890 /* If we've found a device via drive letter, do default processing */
891 if (SymlinksEntry != &(DeviceInformation->SymbolicLinksListHead))
892 break;
893
894 /* If it doesn't have an associated device, go to fallback method */
895 if (IsListEmpty(&DeviceInformation->AssociatedDevicesHead))
896 goto TryWithVolumeName;
897
898 /* Create a string with the information about the device */
899 AssociatedDevice = CONTAINING_RECORD(&(DeviceInformation->AssociatedDevicesHead), ASSOCIATED_DEVICE_ENTRY, AssociatedDevicesEntry);
900 OldLength = DeviceLength;
901 OldBuffer = DeviceString;
902 DeviceLength += AssociatedDevice->String.Length;
903 DeviceString = AllocatePool(DeviceLength);
904 if (!DeviceString)
905 {
906 if (OldBuffer)
907 {
908 FreePool(OldBuffer);
909 }
910
912 }
913
914 /* Store our info and previous if any */
915 RtlCopyMemory(DeviceString, AssociatedDevice->String.Buffer, AssociatedDevice->String.Length);
916 if (OldBuffer)
917 {
918 RtlCopyMemory(&DeviceString[AssociatedDevice->String.Length / sizeof(WCHAR)], OldBuffer, OldLength);
919 FreePool(OldBuffer);
920 }
921
922 /* Count and continue looking */
923 ++DevicesFound;
924 DeviceInformation = AssociatedDevice->DeviceInformation;
925
926 /* If too many devices, try another way */
927 if (DevicesFound > MAX_DEVICES) /* 1000 */
928 {
929 goto TryWithVolumeName;
930 }
931 }
932
933 /* Reallocate our string, so that we can prepend disk letter */
934 OldBuffer = DeviceString;
935 OldLength = DeviceLength;
936 DeviceLength += 2 * sizeof(WCHAR);
937 DeviceString = AllocatePool(DeviceLength);
938 if (!DeviceString)
939 {
940 if (OldBuffer)
941 {
942 FreePool(OldBuffer);
943 }
944
946 }
947
948 /* Get the letter */
949 DeviceString[0] = SymlinkInformation->Name.Buffer[LETTER_POSITION];
950 DeviceString[1] = L':';
951
952 /* And copy the rest */
953 if (OldBuffer)
954 {
955 RtlCopyMemory(&DeviceString[2], OldBuffer, OldLength);
956 FreePool(OldBuffer);
957 }
958
959TryWithVolumeName:
960 /* If we didn't find anything, try differently */
961 if (DeviceLength < 2 * sizeof(WCHAR) || DeviceString[1] != L':')
962 {
963 if (DeviceString)
964 {
965 FreePool(DeviceString);
966 DeviceString = NULL;
967 DeviceLength = 0;
968 }
969
970 /* Try to find a volume name matching */
971 for (SymlinksEntry = DeviceInformation->SymbolicLinksListHead.Flink;
972 SymlinksEntry != &(DeviceInformation->SymbolicLinksListHead);
973 SymlinksEntry = SymlinksEntry->Flink)
974 {
975 SymlinkInformation = CONTAINING_RECORD(SymlinksEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
976
977 if (MOUNTMGR_IS_VOLUME_NAME(&SymlinkInformation->Name))
978 {
979 break;
980 }
981 }
982
983 /* If found copy */
984 if (SymlinksEntry != &(DeviceInformation->SymbolicLinksListHead))
985 {
986 DeviceLength = SymlinkInformation->Name.Length;
987 DeviceString = AllocatePool(DeviceLength);
988 if (!DeviceString)
989 {
991 }
992
993 RtlCopyMemory(DeviceString, SymlinkInformation->Name.Buffer, DeviceLength);
994 /* Ensure we are in the Win32 namespace; [1] can be '?' */
995 DeviceString[1] = L'\\';
996 }
997 }
998
999 /* If we didn't find something, fail */
1000 if (!DeviceString)
1001 return STATUS_NOT_FOUND;
1002
1003 /* Get the output buffer */
1004 Output = (PMOUNTMGR_VOLUME_PATHS)Irp->AssociatedIrp.SystemBuffer;
1005
1006 /* At least, we will return our length */
1007 Output->MultiSzLength = DeviceLength + 2 * sizeof(UNICODE_NULL);
1008 Irp->IoStatus.Information = FIELD_OFFSET(MOUNTMGR_VOLUME_PATHS, MultiSz) + Output->MultiSzLength;
1009
1010 /* If we have enough room for copying the string */
1011 if (Irp->IoStatus.Information <= Stack->Parameters.DeviceIoControl.OutputBufferLength)
1012 {
1013 /* Copy it */
1014 if (DeviceLength)
1015 {
1016 RtlCopyMemory(Output->MultiSz, DeviceString, DeviceLength);
1017 }
1018
1019 /* And double-NUL at its end - this is needed in case of
1020 * multiple paths which are separated by a single NUL */
1021 FreePool(DeviceString);
1022 Output->MultiSz[DeviceLength / sizeof(WCHAR)] = UNICODE_NULL;
1023 Output->MultiSz[DeviceLength / sizeof(WCHAR) + 1] = UNICODE_NULL;
1024
1025 return STATUS_SUCCESS;
1026 }
1027 else
1028 {
1029 /* Just return the size needed and leave */
1030 FreePool(DeviceString);
1031 Irp->IoStatus.Information = FIELD_OFFSET(MOUNTMGR_VOLUME_PATHS, MultiSz);
1033 }
1034}
#define MAX_DEVICES
Definition: device.c:28
#define MOUNTMGR_IS_VOLUME_NAME(s)
Definition: mountmgr.h:81
struct _MOUNTMGR_VOLUME_PATHS * PMOUNTMGR_VOLUME_PATHS
#define MOUNTMGR_IS_DRIVE_LETTER(s)
Definition: mountmgr.h:73
unsigned short USHORT
Definition: pedump.c:61
@ Output
Definition: arc.h:85
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
Definition: mntmgr.h:96
LIST_ENTRY AssociatedDevicesHead
Definition: mntmgr.h:47
_In_ WDFDEVICE AssociatedDevice
Definition: wdfinterrupt.h:173

Referenced by MountMgrDeviceControl().

◆ MountMgrQueryDosVolumePaths()

NTSTATUS MountMgrQueryDosVolumePaths ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 1438 of file device.c.

1440{
1443 LIST_ENTRY Devices;
1444 BOOLEAN NeedNotification;
1447 ULONG Attempts, OutputLength;
1450 RECONCILE_WORK_ITEM_CONTEXT ReconcileContext;
1451 PDEVICE_INFORMATION DeviceInformation, ListDeviceInfo, FailedDevice;
1452
1454
1455 /* Validate input size */
1456 if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_TARGET_NAME))
1457 {
1459 }
1460
1461 /* Ensure we have received UNICODE_STRING */
1462 Target = (PMOUNTMGR_TARGET_NAME)Irp->AssociatedIrp.SystemBuffer;
1463 if (Target->DeviceNameLength & 1)
1464 {
1466 }
1467
1468 /* Validate the entry structure size */
1469 if (FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + Target->DeviceNameLength >
1470 Stack->Parameters.DeviceIoControl.InputBufferLength)
1471 {
1473 }
1474
1475 /* Ensure we can at least return needed size */
1476 if (Stack->Parameters.DeviceIoControl.OutputBufferLength < FIELD_OFFSET(MOUNTMGR_VOLUME_PATHS, MultiSz))
1477 {
1479 }
1480
1481 /* Construct string for query */
1483 SymbolicName.MaximumLength = Target->DeviceNameLength;
1484 SymbolicName.Buffer = Target->DeviceName;
1485
1486 /* Find device with our info */
1487 Status = FindDeviceInfo(DeviceExtension, &SymbolicName, FALSE, &DeviceInformation);
1488 if (!NT_SUCCESS(Status))
1489 {
1490 return Status;
1491 }
1492
1493 NeedNotification = FALSE;
1494 Attempts = 0;
1495 for (;;)
1496 {
1497 FailedDevice = NULL;
1498 InitializeListHead(&Devices);
1499
1500 /* Query paths */
1501 Status = MountMgrQueryVolumePaths(DeviceExtension, DeviceInformation, &Devices, &Paths, &FailedDevice);
1502 if (NT_SUCCESS(Status))
1503 {
1504 break;
1505 }
1506
1507 /* If it failed for generic reason (memory, whatever), bail out (ie, FailedDevice not set) */
1508 if (FailedDevice == NULL)
1509 {
1510 return Status;
1511 }
1512
1513 /* If PnP, let's notify in case of success */
1514 if (!DeviceInformation->ManuallyRegistered)
1515 {
1516 NeedNotification = TRUE;
1517 }
1518
1519 /* Reconcile database */
1520 ReconcileContext.DeviceExtension = DeviceExtension;
1521 ReconcileContext.DeviceInformation = FailedDevice;
1522 KeReleaseSemaphore(&DeviceExtension->DeviceLock, IO_NO_INCREMENT, 1, FALSE);
1523 ReconcileThisDatabaseWithMasterWorker(&ReconcileContext);
1524 KeWaitForSingleObject(&DeviceExtension->DeviceLock, Executive, KernelMode, FALSE, NULL);
1525
1526 /* Look for our device, to check it's online */
1527 for (Entry = DeviceExtension->DeviceListHead.Flink;
1528 Entry != &DeviceExtension->DeviceListHead;
1529 Entry = Entry->Flink)
1530 {
1531 ListDeviceInfo = CONTAINING_RECORD(Entry, DEVICE_INFORMATION, DeviceListEntry);
1532 /* It's online, it's OK! */
1533 if (ListDeviceInfo == DeviceInformation)
1534 {
1535 break;
1536 }
1537 }
1538
1539 /* It's not online, it's not good */
1540 if (Entry == &DeviceExtension->DeviceListHead)
1541 {
1543 }
1544
1545 /* Increase attempts count */
1546 ++Attempts;
1547 /* Don't look forever and fail if we get out of attempts */
1548 if (Attempts >= 1000)
1549 {
1550 return Status;
1551 }
1552 }
1553
1554 /* We need to notify? Go ahead */
1555 if (NeedNotification)
1556 {
1557 MountMgrNotifyNameChange(DeviceExtension, &SymbolicName, FALSE);
1558 }
1559
1560 /* Get the output buffer */
1561 Output = (PMOUNTMGR_VOLUME_PATHS)Irp->AssociatedIrp.SystemBuffer;
1562
1563 /* Set required size */
1564 Output->MultiSzLength = Paths->MultiSzLength;
1565
1566 /* Compute total length */
1567 OutputLength = FIELD_OFFSET(MOUNTMGR_VOLUME_PATHS, MultiSz) + Output->MultiSzLength;
1568
1569 /* If it cannot fit, just return the size needed and leave */
1570 if (OutputLength > Stack->Parameters.DeviceIoControl.OutputBufferLength)
1571 {
1572 Irp->IoStatus.Information = FIELD_OFFSET(MOUNTMGR_VOLUME_PATHS, MultiSz);
1573 FreePool(Paths);
1575 }
1576
1577 /* Copy data and quit */
1578 Irp->IoStatus.Information = OutputLength;
1579 RtlCopyMemory(Output->MultiSz, Paths->MultiSz, Output->MultiSzLength);
1580 FreePool(Paths);
1581 return STATUS_SUCCESS;
1582}
VOID NTAPI ReconcileThisDatabaseWithMasterWorker(IN PVOID Parameter)
Definition: database.c:560
NTSTATUS MountMgrQueryVolumePaths(IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation, IN PLIST_ENTRY DeviceInfoList, OUT PMOUNTMGR_VOLUME_PATHS *VolumePaths, OUT PDEVICE_INFORMATION *FailedDevice)
Definition: device.c:1148
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
base of all file and directory entries
Definition: entries.h:83
PDEVICE_INFORMATION DeviceInformation
Definition: mntmgr.h:118
PDEVICE_EXTENSION DeviceExtension
Definition: mntmgr.h:117

Referenced by MountMgrDeviceControl().

◆ MountMgrQueryPoints()

NTSTATUS MountMgrQueryPoints ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 1677 of file device.c.

1679{
1682 PMOUNTDEV_UNIQUE_ID UniqueId;
1683 PMOUNTMGR_MOUNT_POINT MountPoint;
1685
1687
1688 /* Validate input... */
1689 if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_MOUNT_POINT))
1690 {
1692 }
1693
1694 MountPoint = (PMOUNTMGR_MOUNT_POINT)Irp->AssociatedIrp.SystemBuffer;
1695 if (!MountPoint->SymbolicLinkNameLength)
1696 {
1697 MountPoint->SymbolicLinkNameOffset = 0;
1698 }
1699
1700 if (!MountPoint->UniqueIdLength)
1701 {
1702 MountPoint->UniqueIdOffset = 0;
1703 }
1704
1705 if (!MountPoint->DeviceNameLength)
1706 {
1707 MountPoint->DeviceNameOffset = 0;
1708 }
1709
1710 /* Addresses can't be odd */
1711 if ((MountPoint->SymbolicLinkNameOffset & 1) ||
1712 (MountPoint->SymbolicLinkNameLength & 1))
1713 {
1715 }
1716
1717 if ((MountPoint->UniqueIdOffset & 1) ||
1718 (MountPoint->UniqueIdLength & 1))
1719 {
1721 }
1722
1723 if ((MountPoint->DeviceNameOffset & 1) ||
1724 (MountPoint->DeviceNameLength & 1))
1725 {
1727 }
1728
1729 /* We can't go beyond */
1730 if (((ULONG)MountPoint->SymbolicLinkNameLength + MountPoint->UniqueIdLength +
1731 MountPoint->DeviceNameLength) > Stack->Parameters.DeviceIoControl.InputBufferLength)
1732 {
1734 }
1735
1736 if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTMGR_MOUNT_POINTS))
1737 {
1739 }
1740
1741 /* If caller provided a Symlink, use it */
1742 if (MountPoint->SymbolicLinkNameLength != 0)
1743 {
1744 if (MountPoint->SymbolicLinkNameLength > MAXSHORT)
1745 {
1747 }
1748
1752 if (!SymbolicName.Buffer)
1753 {
1755 }
1756
1758 (PWSTR)((ULONG_PTR)MountPoint + MountPoint->SymbolicLinkNameOffset),
1761
1762 /* Query links using it */
1765 }
1766 /* If user provided an unique ID */
1767 else if (MountPoint->UniqueIdLength != 0)
1768 {
1769 UniqueId = AllocatePool(MountPoint->UniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
1770 if (!UniqueId)
1771 {
1773 }
1774
1775 UniqueId->UniqueIdLength = MountPoint->UniqueIdLength;
1776 RtlCopyMemory(UniqueId->UniqueId,
1777 (PVOID)((ULONG_PTR)MountPoint + MountPoint->UniqueIdOffset),
1778 MountPoint->UniqueIdLength);
1779
1780 /* Query links using it */
1781 Status = QueryPointsFromMemory(DeviceExtension, Irp, UniqueId, NULL);
1782 FreePool(UniqueId);
1783 }
1784 /* If caller provided a device name */
1785 else if (MountPoint->DeviceNameLength != 0)
1786 {
1787 if (MountPoint->DeviceNameLength > MAXSHORT)
1788 {
1790 }
1791
1792 DeviceName.Length = MountPoint->DeviceNameLength;
1793 DeviceName.MaximumLength = MountPoint->DeviceNameLength + sizeof(WCHAR);
1794 DeviceName.Buffer = AllocatePool(DeviceName.MaximumLength);
1795 if (!DeviceName.Buffer)
1796 {
1798 }
1799
1801 (PWSTR)((ULONG_PTR)MountPoint + MountPoint->DeviceNameOffset),
1802 DeviceName.Length);
1803 DeviceName.Buffer[DeviceName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1804
1805 /* Query links using it */
1806 Status = QueryPointsFromMemory(DeviceExtension, Irp, NULL, &DeviceName);
1807 FreePool(DeviceName.Buffer);
1808 }
1809 else
1810 {
1811 /* Otherwise, query all links */
1812 Status = QueryPointsFromMemory(DeviceExtension, Irp, NULL, NULL);
1813 }
1814
1815 return Status;
1816}
NTSTATUS QueryPointsFromSymbolicLinkName(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName, IN PIRP Irp)
Definition: point.c:463
NTSTATUS QueryPointsFromMemory(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp, IN PMOUNTDEV_UNIQUE_ID UniqueId OPTIONAL, IN PUNICODE_STRING SymbolicName OPTIONAL)
Definition: point.c:236
#define MAXSHORT
Definition: umtypes.h:114

Referenced by MountMgrDeletePoints(), MountMgrDeletePointsDbOnly(), and MountMgrDeviceControl().

◆ MountMgrQuerySystemVolumeName()

NTSTATUS MountMgrQuerySystemVolumeName ( OUT PUNICODE_STRING  SystemVolumeName)

Definition at line 708 of file device.c.

709{
711
715 QueryTable[0].Name = L"SystemPartition";
716
717 SystemVolumeName->Buffer = NULL;
718
720 L"\\Registry\\Machine\\System\\Setup",
722 SystemVolumeName,
723 NULL);
724
725 if (SystemVolumeName->Buffer)
726 {
727 return STATUS_SUCCESS;
728 }
729
730 return STATUS_UNSUCCESSFUL;
731}
NTSTATUS NTAPI MountMgrQuerySystemVolumeNameQueryRoutine(IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
Definition: device.c:668
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4203
#define RTL_QUERY_REGISTRY_REQUIRED
Definition: nt_native.h:132
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132

Referenced by MountMgrAssignDriveLetters().

◆ MountMgrQuerySystemVolumeNameQueryRoutine()

NTSTATUS NTAPI MountMgrQuerySystemVolumeNameQueryRoutine ( IN PWSTR  ValueName,
IN ULONG  ValueType,
IN PVOID  ValueData,
IN ULONG  ValueLength,
IN PVOID  Context,
IN PVOID  EntryContext 
)

Definition at line 668 of file device.c.

674{
675 UNICODE_STRING ValueString;
676 PUNICODE_STRING SystemVolumeName;
677
681
682 if (ValueType != REG_SZ)
683 {
684 return STATUS_SUCCESS;
685 }
686
687 RtlInitUnicodeString(&ValueString, ValueData);
688 SystemVolumeName = Context;
689
690 /* Return a string containing system volume name */
691 SystemVolumeName->Length = ValueString.Length;
692 SystemVolumeName->MaximumLength = ValueString.Length + sizeof(WCHAR);
693 SystemVolumeName->Buffer = AllocatePool(SystemVolumeName->MaximumLength);
694 if (SystemVolumeName->Buffer)
695 {
696 RtlCopyMemory(SystemVolumeName->Buffer, ValueData, ValueString.Length);
697 SystemVolumeName->Buffer[ValueString.Length / sizeof(WCHAR)] = UNICODE_NULL;
698 }
699
700 return STATUS_SUCCESS;
701
702}
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:312
#define REG_SZ
Definition: layer.c:22
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4202
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:282
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:275

Referenced by MountMgrQuerySystemVolumeName().

◆ MountMgrQueryVolumePaths()

NTSTATUS MountMgrQueryVolumePaths ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PDEVICE_INFORMATION  DeviceInformation,
IN PLIST_ENTRY  DeviceInfoList,
OUT PMOUNTMGR_VOLUME_PATHS VolumePaths,
OUT PDEVICE_INFORMATION FailedDevice 
)

Definition at line 1148 of file device.c.

1153{
1154 ULONG Written;
1157 PSYMLINK_INFORMATION SymlinkInformation;
1158 PDEVICE_INFORMATION_ENTRY DeviceInfoEntry;
1159 PASSOCIATED_DEVICE_ENTRY AssociatedDeviceEntry;
1160 PMOUNTMGR_VOLUME_PATHS * Paths = NULL, * CurrentPath;
1161 ULONG OutputPathLength, NumberOfPaths, ReturnedPaths;
1162
1163 /* We return at least null char */
1164 OutputPathLength = sizeof(UNICODE_NULL);
1165
1166 for (Entry = DeviceInformation->SymbolicLinksListHead.Flink;
1167 Entry != &(DeviceInformation->SymbolicLinksListHead);
1168 Entry = Entry->Flink)
1169 {
1170 SymlinkInformation = CONTAINING_RECORD(Entry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
1171
1172 /* Try to find the drive letter (ie, DOS device) */
1173 if (MOUNTMGR_IS_DRIVE_LETTER(&SymlinkInformation->Name) && SymlinkInformation->Online)
1174 {
1175 /* We'll return the letter */
1176 OutputPathLength = 4 * sizeof(WCHAR);
1177 break;
1178 }
1179 }
1180
1181 /* We didn't find any */
1182 if (Entry == &(DeviceInformation->SymbolicLinksListHead))
1183 {
1184 SymlinkInformation = NULL;
1185 }
1186
1187 /* Do we have any device info to return? */
1188 for (Entry = DeviceInfoList->Flink; Entry != DeviceInfoList; Entry = Entry->Flink)
1189 {
1190 DeviceInfoEntry = CONTAINING_RECORD(Entry, DEVICE_INFORMATION_ENTRY, DeviceInformationEntry);
1191
1192 /* Matching current device */
1193 if (DeviceInfoEntry->DeviceInformation == DeviceInformation)
1194 {
1195 /* Allocate the output buffer */
1196 *VolumePaths = AllocatePool(sizeof(ULONG) + OutputPathLength);
1197 if (*VolumePaths == NULL)
1198 {
1200 }
1201
1202 /* Set size */
1203 (*VolumePaths)->MultiSzLength = OutputPathLength;
1204 /* If we have a drive letter, return it */
1205 if (SymlinkInformation != NULL)
1206 {
1207 (*VolumePaths)->MultiSz[0] = SymlinkInformation->Name.Buffer[LETTER_POSITION];
1208 (*VolumePaths)->MultiSz[1] = L':';
1209 (*VolumePaths)->MultiSz[2] = UNICODE_NULL;
1210 (*VolumePaths)->MultiSz[3] = UNICODE_NULL;
1211 }
1212 else
1213 {
1214 (*VolumePaths)->MultiSz[0] = UNICODE_NULL;
1215 }
1216
1217 return STATUS_SUCCESS;
1218 }
1219 }
1220
1221 /* Allocate a new device entry */
1222 DeviceInfoEntry = AllocatePool(sizeof(DEVICE_INFORMATION_ENTRY));
1223 if (DeviceInfoEntry == NULL)
1224 {
1226 }
1227
1228 /* Add it to the list */
1229 DeviceInfoEntry->DeviceInformation = DeviceInformation;
1230 InsertTailList(DeviceInfoList, &DeviceInfoEntry->DeviceInformationEntry);
1231
1232 NumberOfPaths = 0;
1233 /* Count the amount of devices we will have to handle */
1234 if (!IsListEmpty(&DeviceInformation->AssociatedDevicesHead))
1235 {
1236 for (Entry = DeviceInformation->AssociatedDevicesHead.Flink;
1237 Entry != &DeviceInformation->AssociatedDevicesHead;
1238 Entry = Entry->Flink)
1239 {
1240 ++NumberOfPaths;
1241 }
1242
1243 ASSERT(NumberOfPaths != 0);
1244 /* And allocate a big enough buffer */
1245 Paths = AllocatePool(NumberOfPaths * sizeof(PMOUNTMGR_VOLUME_PATHS));
1246 if (Paths == NULL)
1247 {
1248 RemoveEntryList(&DeviceInfoEntry->DeviceInformationEntry);
1249 FreePool(DeviceInfoEntry);
1251 }
1252 }
1253
1254 /* Start the hot loop to gather all the paths and be able to compute total output length! */
1255 ReturnedPaths = 0;
1256 CurrentPath = Paths;
1257 for (Entry = DeviceInformation->AssociatedDevicesHead.Flink;
1258 Entry != &DeviceInformation->AssociatedDevicesHead;
1259 Entry = Entry->Flink)
1260 {
1261 USHORT InnerStrings;
1263
1264 AssociatedDeviceEntry = CONTAINING_RECORD(Entry, ASSOCIATED_DEVICE_ENTRY, AssociatedDevicesEntry);
1265
1266 /* Validate the fact its a mount point by query reparse data */
1267 Status = MountMgrValidateBackPointer(AssociatedDeviceEntry, DeviceInformation, &Invalid);
1268
1269 /* If we found an invalid device, that's a failure */
1270 if (Invalid)
1271 {
1272 *FailedDevice = AssociatedDeviceEntry->DeviceInformation;
1274 }
1275
1276 /* Check whether we failed, if so, bail out */
1277 if (!NT_SUCCESS(Status))
1278 {
1279 ULONG i;
1280
1281 for (i = 0; i < ReturnedPaths; ++i)
1282 {
1283 FreePool(Paths[i]);
1284 }
1285
1286 if (Paths != NULL)
1287 {
1288 FreePool(Paths);
1289 }
1290 RemoveEntryList(&DeviceInfoEntry->DeviceInformationEntry);
1291 FreePool(DeviceInfoEntry);
1292 return Status;
1293 }
1294
1295 /* Query associated paths (hello ourselves :-)) */
1296 Status = MountMgrQueryVolumePaths(DeviceExtension,
1297 AssociatedDeviceEntry->DeviceInformation,
1298 DeviceInfoList,
1299 CurrentPath,
1300 FailedDevice);
1301 if (!NT_SUCCESS(Status))
1302 {
1303 ULONG i;
1304
1305 for (i = 0; i < ReturnedPaths; ++i)
1306 {
1307 FreePool(Paths[i]);
1308 }
1309
1310 if (Paths != NULL)
1311 {
1312 FreePool(Paths);
1313 }
1314 RemoveEntryList(&DeviceInfoEntry->DeviceInformationEntry);
1315 FreePool(DeviceInfoEntry);
1316 return Status;
1317 }
1318
1319 /* Count the number of strings we have in the multi string buffer */
1320 InnerStrings = 0;
1321 if ((*CurrentPath)->MultiSzLength != sizeof(UNICODE_NULL))
1322 {
1323 ULONG i;
1324 PWSTR MultiSz = (*CurrentPath)->MultiSz;
1325
1326 for (i = 0; i < (*CurrentPath)->MultiSzLength / sizeof(WCHAR); ++i, ++MultiSz)
1327 {
1328 if (*MultiSz == UNICODE_NULL)
1329 {
1330 ++InnerStrings;
1331 }
1332 }
1333 }
1334
1335 /* We returned one more path (ie, one more allocated buffer) */
1336 ++ReturnedPaths;
1337 /* Move the next pointer to use in the array */
1338 ++CurrentPath;
1339 /* Multiply String.Length by the number of found paths, we always add it after a path */
1340 OutputPathLength += (*CurrentPath)->MultiSzLength + InnerStrings * AssociatedDeviceEntry->String.Length - sizeof(UNICODE_NULL);
1341 }
1342
1343 /* Allocate the output buffer */
1344 *VolumePaths = AllocatePool(sizeof(ULONG) + OutputPathLength);
1345 if (*VolumePaths == NULL)
1346 {
1347 ULONG i;
1348
1349 for (i = 0; i < ReturnedPaths; ++i)
1350 {
1351 FreePool(Paths[i]);
1352 }
1353
1354 if (Paths != NULL)
1355 {
1356 FreePool(Paths);
1357 }
1358 RemoveEntryList(&DeviceInfoEntry->DeviceInformationEntry);
1359 FreePool(DeviceInfoEntry);
1361 }
1362
1363 Written = 0;
1364 /* If we had found a DOS letter, that's the first thing we return */
1365 (*VolumePaths)->MultiSzLength = OutputPathLength;
1366 if (SymlinkInformation != NULL)
1367 {
1368 (*VolumePaths)->MultiSz[0] = SymlinkInformation->Name.Buffer[LETTER_POSITION];
1369 (*VolumePaths)->MultiSz[1] = L':';
1370 (*VolumePaths)->MultiSz[2] = UNICODE_NULL;
1371 Written = 3;
1372 }
1373
1374 /* Now, browse again all our paths to return them */
1375 CurrentPath = Paths;
1376 for (Entry = DeviceInformation->AssociatedDevicesHead.Flink;
1377 Entry != &DeviceInformation->AssociatedDevicesHead;
1378 Entry = Entry->Flink)
1379 {
1380 AssociatedDeviceEntry = CONTAINING_RECORD(Entry, ASSOCIATED_DEVICE_ENTRY, AssociatedDevicesEntry);
1381
1382 /* If we had a path... */
1383 if ((*CurrentPath)->MultiSzLength != sizeof(UNICODE_NULL))
1384 {
1385 ULONG i, Offset;
1386 PWSTR MultiSz;
1387
1388 /* This offset is used to "jump" into MultiSz, so, start with the string begin (ie, skip MultiSzLength) */
1389 Offset = sizeof(ULONG);
1390 /* Browse every single letter, and skip last UNICODE_NULL */
1391 for (i = 0; i < (*CurrentPath)->MultiSzLength / sizeof(WCHAR) - 1; ++i)
1392 {
1393 /* Get the letter */
1394 MultiSz = (PWSTR)((ULONG_PTR)(*CurrentPath) + Offset);
1395 /* If it was part of the path, just return it */
1396 if (*MultiSz != UNICODE_NULL)
1397 {
1398 (*VolumePaths)->MultiSz[Written] = *MultiSz;
1399 }
1400 else
1401 {
1402 /* Otherwise, as planed, return our whole associated device name */
1403 RtlCopyMemory(&(*VolumePaths)->MultiSz[Written],
1404 AssociatedDeviceEntry->String.Buffer,
1405 AssociatedDeviceEntry->String.Length);
1406 Written += AssociatedDeviceEntry->String.Length / sizeof(WCHAR);
1407 /* And don't forget to nullify */
1408 (*VolumePaths)->MultiSz[Written] = UNICODE_NULL;
1409 }
1410
1411 /* We at least return a letter or a null char */
1412 ++Written;
1413 /* Move to the next letter */
1414 Offset += sizeof(WCHAR);
1415 }
1416 }
1417
1418 FreePool(*CurrentPath);
1419 ++CurrentPath;
1420 }
1421
1422 /* MultiSz: don't forget last null char */
1423 (*VolumePaths)->MultiSz[Written] = UNICODE_NULL;
1424 /* Cleanup everything and return success! */
1425 if (Paths != NULL)
1426 {
1427 FreePool(Paths);
1428 }
1429 RemoveEntryList(&DeviceInfoEntry->DeviceInformationEntry);
1430 FreePool(DeviceInfoEntry);
1431 return STATUS_SUCCESS;
1432}
@ Invalid
Definition: asmpp.cpp:30
NTSTATUS MountMgrValidateBackPointer(IN PASSOCIATED_DEVICE_ENTRY AssociatedDeviceEntry, IN PDEVICE_INFORMATION DeviceInformation, OUT PBOOLEAN Invalid)
Definition: device.c:1040
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
UNICODE_STRING String
Definition: mntmgr.h:99
PDEVICE_INFORMATION DeviceInformation
Definition: mntmgr.h:98
Definition: mntmgr.h:103
PDEVICE_INFORMATION DeviceInformation
Definition: mntmgr.h:105
LIST_ENTRY DeviceInformationEntry
Definition: mntmgr.h:104

Referenced by MountMgrQueryDosVolumePaths(), and MountMgrQueryVolumePaths().

◆ MountMgrScrubRegistry()

NTSTATUS MountMgrScrubRegistry ( IN PDEVICE_EXTENSION  DeviceExtension)

Definition at line 221 of file device.c.

222{
224 BOOLEAN Continue;
226
227 do
228 {
231 QueryTable[0].EntryContext = &Continue;
232 Continue = FALSE;
233
237 DeviceExtension,
238 NULL);
239 }
240 while (Continue);
241
242 return Status;
243}
NTSTATUS NTAPI ScrubRegistryRoutine(IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
Definition: device.c:162

Referenced by MountMgrDeviceControl().

◆ MountMgrSetAutoMount()

NTSTATUS MountMgrSetAutoMount ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 103 of file device.c.

105{
108
110
111 if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_SET_AUTO_MOUNT))
112 {
113 Irp->IoStatus.Information = 0;
115 }
116
117 /* Change the state only if there is a real difference
118 * with the user-provided NewState (normalized) */
119 SetState = (PMOUNTMGR_SET_AUTO_MOUNT)Irp->AssociatedIrp.SystemBuffer;
120 if ((SetState->NewState != Enabled) == DeviceExtension->NoAutoMount)
121 {
122 Irp->IoStatus.Information = 0;
123 return STATUS_SUCCESS;
124 }
125
126 /* Set new state */
127 DeviceExtension->NoAutoMount = (SetState->NewState != Enabled);
128 Irp->IoStatus.Information = 0;
129 return MountmgrWriteNoAutoMount(DeviceExtension);
130}
NTSTATUS MountmgrWriteNoAutoMount(IN PDEVICE_EXTENSION DeviceExtension)
Definition: device.c:87
@ Enabled
Definition: mountmgr.h:179
struct _MOUNTMGR_SET_AUTO_MOUNT * PMOUNTMGR_SET_AUTO_MOUNT
MOUNTMGR_AUTO_MOUNT_STATE NewState
Definition: mountmgr.h:187

Referenced by MountMgrDeviceControl().

◆ MountMgrValidateBackPointer()

NTSTATUS MountMgrValidateBackPointer ( IN PASSOCIATED_DEVICE_ENTRY  AssociatedDeviceEntry,
IN PDEVICE_INFORMATION  DeviceInformation,
OUT PBOOLEAN  Invalid 
)

Definition at line 1040 of file device.c.

1043{
1044 HANDLE Handle;
1046 PLIST_ENTRY SymlinksEntry;
1048 PREPARSE_DATA_BUFFER ReparseData;
1050 UNICODE_STRING FullName, SubstituteName;
1051 PSYMLINK_INFORMATION SymlinkInformation;
1052
1053 /* Initialize & allocate a string big enough to contain our complete mount point name */
1054 FullName.Length = 0;
1055 FullName.MaximumLength = AssociatedDeviceEntry->String.Length
1056 + AssociatedDeviceEntry->DeviceInformation->DeviceName.Length
1057 + sizeof(WCHAR)
1058 + sizeof(UNICODE_NULL);
1060 if (!FullName.Buffer)
1061 {
1063 }
1064
1065 /* Create the path */
1066 RtlAppendUnicodeStringToString(&FullName, &AssociatedDeviceEntry->DeviceInformation->DeviceName);
1067 FullName.Buffer[FullName.Length / sizeof(WCHAR)] = L'\\';
1068 RtlAppendUnicodeStringToString(&FullName, &AssociatedDeviceEntry->String);
1070
1071 /* Open it to query the reparse point */
1073 &FullName,
1075 NULL,
1076 NULL);
1083
1084 if (!NT_SUCCESS(Status))
1085 {
1086 *Invalid = TRUE;
1087 return STATUS_SUCCESS;
1088 }
1089
1090 /* Allocate a buffer big enough to read reparse data */
1092 if (ReparseData == NULL)
1093 {
1094 ZwClose(Handle);
1096 }
1097
1098 /* Query reparse data */
1100 NULL, NULL, NULL,
1103 NULL, 0,
1105 ZwClose(Handle);
1106
1107 if (!NT_SUCCESS(Status))
1108 {
1109 FreePool(ReparseData);
1110 *Invalid = TRUE;
1111 return STATUS_SUCCESS;
1112 }
1113
1114 /* Create a string with the substitute name */
1115 SubstituteName.Length = ReparseData->SymbolicLinkReparseBuffer.SubstituteNameLength;
1116 SubstituteName.MaximumLength = SubstituteName.Length;
1117 SubstituteName.Buffer = (PWSTR)((ULONG_PTR)ReparseData->SymbolicLinkReparseBuffer.PathBuffer + ReparseData->SymbolicLinkReparseBuffer.SubstituteNameOffset);
1118
1119 /* If that's a volume name that matches our associated device, that's a success! */
1120 if (MOUNTMGR_IS_VOLUME_NAME(&SubstituteName))
1121 {
1122 if (SubstituteName.Length == 98 && SubstituteName.Buffer[1] == L'?')
1123 {
1124 for (SymlinksEntry = DeviceInformation->SymbolicLinksListHead.Flink;
1125 SymlinksEntry != &(DeviceInformation->SymbolicLinksListHead);
1126 SymlinksEntry = SymlinksEntry->Flink)
1127 {
1128 SymlinkInformation = CONTAINING_RECORD(SymlinksEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
1129
1130 if (RtlEqualUnicodeString(&SubstituteName, &SymlinkInformation->Name, TRUE))
1131 {
1132 FreePool(ReparseData);
1133 return STATUS_SUCCESS;
1134 }
1135 }
1136 }
1137 }
1138
1139 FreePool(ReparseData);
1140 *Invalid = TRUE;
1141 return STATUS_SUCCESS;
1142}
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define FILE_SHARE_READ
Definition: compat.h:136
#define FILE_OPEN_REPARSE_POINT
Definition: from_kernel.h:46
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
ULONG Handle
Definition: gdb_input.c:15
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSYSAPI NTSTATUS NTAPI ZwOpenFile(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _Out_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG ShareAccess, _In_ ULONG OpenOptions)
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
NTSYSAPI NTSTATUS NTAPI ZwFsControlFile(IN HANDLE DeviceHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG IoControlCode, IN PVOID InputBuffer, IN ULONG InputBufferSize, OUT PVOID OutputBuffer, IN ULONG OutputBufferSize)
#define FSCTL_GET_REPARSE_POINT
Definition: winioctl.h:746
struct _REPARSE_DATA_BUFFER::@333::@335 SymbolicLinkReparseBuffer
unsigned short Length
Definition: sprintf.c:451
void * Buffer
Definition: sprintf.c:453
unsigned short MaximumLength
Definition: sprintf.c:452
#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE
Definition: iotypes.h:7213
_In_ PSTRING FullName
Definition: rtlfuncs.h:1665

Referenced by MountMgrQueryVolumePaths().

◆ MountMgrVolumeArrivalNotification()

NTSTATUS MountMgrVolumeArrivalNotification ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 1633 of file device.c.

1635{
1637 BOOLEAN OldState;
1641
1643
1644 /* Validate input */
1645 if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_TARGET_NAME))
1646 {
1648 }
1649
1650 Target = (PMOUNTMGR_TARGET_NAME)Irp->AssociatedIrp.SystemBuffer;
1651 if (FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) + Target->DeviceNameLength >
1652 Stack->Parameters.DeviceIoControl.InputBufferLength)
1653 {
1655 }
1656
1658 SymbolicName.MaximumLength = Target->DeviceNameLength;
1659 SymbolicName.Buffer = Target->DeviceName;
1660
1661 /* Disable hard errors */
1664
1665 /* Call real worker */
1667
1669
1670 return Status;
1671}
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
VOID NTAPI PsSetThreadHardErrorsAreDisabled(IN PETHREAD Thread, IN BOOLEAN HardErrorsAreDisabled)
Definition: thread.c:898
BOOLEAN NTAPI PsGetThreadHardErrorsAreDisabled(IN PETHREAD Thread)
Definition: thread.c:695

Referenced by MountMgrDeviceControl().

◆ MountMgrVolumeMountPointChanged()

NTSTATUS MountMgrVolumeMountPointChanged ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp,
IN NTSTATUS  LockStatus,
OUT PUNICODE_STRING  SourceDeviceName,
OUT PUNICODE_STRING  SourceSymbolicName,
OUT PUNICODE_STRING  TargetVolumeName 
)

Definition at line 1990 of file device.c.

1996{
1997 HANDLE Handle;
2001 ULONG Length, SavedLength;
2002 BOOLEAN FOReferenced = FALSE;
2005 PDEVICE_INFORMATION DeviceInformation;
2006 OBJECT_NAME_INFORMATION ObjectNameInfo;
2007 FILE_FS_DEVICE_INFORMATION FsDeviceInfo;
2008 PFILE_NAME_INFORMATION FileNameInfo = NULL;
2009 PMOUNTMGR_VOLUME_MOUNT_POINT VolumeMountPoint;
2010 POBJECT_NAME_INFORMATION ObjectNameInfoPtr = NULL;
2011 UNICODE_STRING SourceVolumeName, TargetDeviceName;
2012
2014
2015 /* Validate input */
2016 if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_VOLUME_MOUNT_POINT))
2017 {
2019 }
2020
2021 VolumeMountPoint = (PMOUNTMGR_VOLUME_MOUNT_POINT)Irp->AssociatedIrp.SystemBuffer;
2022
2023 if (((ULONG)VolumeMountPoint->SourceVolumeNameLength + VolumeMountPoint->TargetVolumeNameLength) <
2024 Stack->Parameters.DeviceIoControl.InputBufferLength)
2025 {
2027 }
2028
2029 /* Get source volume name */
2030 SourceVolumeName.Length =
2031 SourceVolumeName.MaximumLength = VolumeMountPoint->SourceVolumeNameLength;
2032 SourceVolumeName.Buffer = (PWSTR)((ULONG_PTR)VolumeMountPoint + VolumeMountPoint->SourceVolumeNameOffset);
2033
2035 &SourceVolumeName,
2037 NULL,
2038 NULL);
2039
2040 /* Open it */
2047 if (!NT_SUCCESS(Status))
2048 {
2049 return Status;
2050 }
2051
2052 TargetDeviceName.Buffer = NULL;
2053
2054 /* Query its attributes */
2057 &FsDeviceInfo,
2058 sizeof(FsDeviceInfo),
2060 if (!NT_SUCCESS(Status))
2061 {
2062 goto Cleanup;
2063 }
2064
2065 if (FsDeviceInfo.DeviceType != FILE_DEVICE_DISK && FsDeviceInfo.DeviceType != FILE_DEVICE_VIRTUAL_DISK)
2066 {
2067 goto Cleanup;
2068 }
2069
2071 {
2072 goto Cleanup;
2073 }
2074
2075 /* Reference it */
2077 if (!NT_SUCCESS(Status))
2078 {
2079 goto Cleanup;
2080 }
2081 FOReferenced = TRUE;
2082
2083 /* Get file name */
2084 FileNameInfo = AllocatePool(sizeof(FILE_NAME_INFORMATION));
2085 if (!FileNameInfo)
2086 {
2088 goto Cleanup;
2089 }
2090
2091 Status = ZwQueryInformationFile(Handle, &IoStatusBlock, FileNameInfo,
2092 sizeof(FILE_NAME_INFORMATION),
2095 {
2096 /* Now we have real length, use it */
2097 Length = FileNameInfo->FileNameLength;
2098 FreePool(FileNameInfo);
2099
2100 FileNameInfo = AllocatePool(sizeof(FILE_NAME_INFORMATION) + Length);
2101 if (!FileNameInfo)
2102 {
2104 goto Cleanup;
2105 }
2106
2107 /* Really query file name */
2108 Status = ZwQueryInformationFile(Handle, &IoStatusBlock, FileNameInfo,
2109 sizeof(FILE_NAME_INFORMATION) + Length,
2111 }
2112
2113 if (!NT_SUCCESS(Status))
2114 {
2115 goto Cleanup;
2116 }
2117
2118 /* Get symbolic name */
2119 ObjectNameInfoPtr = &ObjectNameInfo;
2120 SavedLength = sizeof(OBJECT_NAME_INFORMATION);
2121 Status = ObQueryNameString(FileObject->DeviceObject, ObjectNameInfoPtr, sizeof(OBJECT_NAME_INFORMATION), &Length);
2123 {
2124 /* Once again, with proper size, it works better */
2125 ObjectNameInfoPtr = AllocatePool(Length);
2126 if (!ObjectNameInfoPtr)
2127 {
2129 goto Cleanup;
2130 }
2131
2132 SavedLength = Length;
2133 Status = ObQueryNameString(FileObject->DeviceObject, ObjectNameInfoPtr, SavedLength, &Length);
2134 }
2135
2136 if (!NT_SUCCESS(Status))
2137 {
2138 goto Cleanup;
2139 }
2140
2141 /* Now, query the device name */
2142 Status = QueryDeviceInformation(&ObjectNameInfoPtr->Name, SourceDeviceName,
2143 NULL, NULL, NULL, NULL, NULL, NULL);
2144 if (!NT_SUCCESS(Status))
2145 {
2146 goto Cleanup;
2147 }
2148
2149 /* For target volume name, use input */
2150 TargetVolumeName->Length =
2151 TargetVolumeName->MaximumLength = VolumeMountPoint->TargetVolumeNameLength;
2152 TargetVolumeName->Buffer = (PWSTR)((ULONG_PTR)VolumeMountPoint + VolumeMountPoint->TargetVolumeNameOffset);
2153
2154 /* Query its device name */
2155 Status = QueryDeviceInformation(TargetVolumeName, &TargetDeviceName,
2156 NULL, NULL, NULL, NULL, NULL, NULL);
2157 if (!NT_SUCCESS(Status))
2158 {
2159 goto Cleanup;
2160 }
2161
2162 /* Return symbolic name */
2163 SourceSymbolicName->Length =
2164 SourceSymbolicName->MaximumLength = (USHORT)FileNameInfo->FileNameLength;
2165 SourceSymbolicName->Buffer = (PWSTR)FileNameInfo;
2166 /* memmove allows memory overlap */
2167 RtlMoveMemory(SourceSymbolicName->Buffer, FileNameInfo->FileName, SourceSymbolicName->Length);
2168 FileNameInfo = NULL;
2169
2170 /* Notify the change */
2171 MountMgrNotify(DeviceExtension);
2172 MountMgrNotifyNameChange(DeviceExtension, &TargetDeviceName, TRUE);
2173
2174 /* If we are locked, sync databases if possible */
2175 if (NT_SUCCESS(LockStatus))
2176 {
2177 Status = FindDeviceInfo(DeviceExtension, SourceDeviceName, FALSE, &DeviceInformation);
2178 if (NT_SUCCESS(Status))
2179 {
2180 ReconcileThisDatabaseWithMaster(DeviceExtension, DeviceInformation);
2181 }
2182 else
2183 {
2185 }
2186 }
2187
2188Cleanup:
2189 if (TargetDeviceName.Buffer)
2190 {
2191 FreePool(TargetDeviceName.Buffer);
2192 }
2193
2194 if (ObjectNameInfoPtr && ObjectNameInfoPtr != &ObjectNameInfo)
2195 {
2196 FreePool(ObjectNameInfoPtr);
2197 }
2198
2199 if (FileNameInfo)
2200 {
2201 FreePool(FileNameInfo);
2202 }
2203
2204 if (FOReferenced)
2205 {
2207 }
2208
2209 return Status;
2210}
static const WCHAR Cleanup[]
Definition: register.c:80
VOID ReconcileThisDatabaseWithMaster(IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation)
Definition: database.c:1613
@ FileNameInformation
Definition: from_kernel.h:70
@ FileFsDeviceInformation
Definition: from_kernel.h:222
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
struct _MOUNTMGR_VOLUME_MOUNT_POINT * PMOUNTMGR_VOLUME_MOUNT_POINT
#define FILE_REMOTE_DEVICE
Definition: nt_native.h:811
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
NTSYSAPI NTSTATUS NTAPI ZwQueryVolumeInformationFile(IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FsInformation, IN ULONG Length, IN FS_INFORMATION_CLASS FsInformationClass)
NTSTATUS NTAPI ObQueryNameString(IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength)
Definition: obname.c:1207
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
#define FILE_DEVICE_DISK
Definition: winioctl.h:52
#define FILE_DEVICE_VIRTUAL_DISK
Definition: winioctl.h:81
UNICODE_STRING Name
Definition: nt_native.h:1270
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133

Referenced by MountMgrVolumeMountPointCreated(), and MountMgrVolumeMountPointDeleted().

◆ MountMgrVolumeMountPointCreated()

NTSTATUS MountMgrVolumeMountPointCreated ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp,
IN NTSTATUS  LockStatus 
)

Definition at line 2216 of file device.c.

2219{
2220 LONG Offset;
2221 BOOLEAN Found;
2224 PMOUNTDEV_UNIQUE_ID UniqueId;
2225 PDATABASE_ENTRY DatabaseEntry;
2226 PASSOCIATED_DEVICE_ENTRY AssociatedEntry;
2227 PDEVICE_INFORMATION DeviceInformation, TargetDeviceInformation;
2228 UNICODE_STRING LinkTarget, SourceDeviceName, SourceSymbolicName, TargetVolumeName, VolumeName, DbName;
2229
2230 /* Initialize string */
2231 LinkTarget.Length = 0;
2234 if (LinkTarget.Buffer == NULL)
2235 {
2237 }
2238
2239 /* If the mount point was created, then, it changed!
2240 * Also use it to query some information
2241 */
2242 Status = MountMgrVolumeMountPointChanged(DeviceExtension, Irp, LockStatus, &SourceDeviceName, &SourceSymbolicName, &TargetVolumeName);
2243 /* Pending means DB are under synchronization, bail out */
2244 if (Status == STATUS_PENDING)
2245 {
2247 FreePool(SourceDeviceName.Buffer);
2248 FreePool(SourceSymbolicName.Buffer);
2249 return STATUS_SUCCESS;
2250 }
2251 else if (!NT_SUCCESS(Status))
2252 {
2254 return Status;
2255 }
2256
2257 /* Query the device information */
2258 Status = FindDeviceInfo(DeviceExtension, &SourceDeviceName, FALSE, &DeviceInformation);
2259 if (!NT_SUCCESS(Status))
2260 {
2261 /* If it failed, first try to get volume name */
2262 Status = QueryVolumeName(0, NULL, &SourceDeviceName, &LinkTarget, &VolumeName);
2263 if (!NT_SUCCESS(Status))
2264 {
2265 /* Then, try to read the symlink */
2266 Status = MountMgrQuerySymbolicLink(&SourceDeviceName, &LinkTarget);
2267 if (!NT_SUCCESS(Status))
2268 {
2270 FreePool(SourceDeviceName.Buffer);
2271 FreePool(SourceSymbolicName.Buffer);
2272 return Status;
2273 }
2274 }
2275 else
2276 {
2278 }
2279
2280 FreePool(SourceDeviceName.Buffer);
2281
2282 SourceDeviceName.Length = LinkTarget.Length;
2283 SourceDeviceName.MaximumLength = LinkTarget.MaximumLength;
2284 SourceDeviceName.Buffer = LinkTarget.Buffer;
2285
2286 /* Now that we have the correct source, reattempt to query information */
2287 Status = FindDeviceInfo(DeviceExtension, &SourceDeviceName, FALSE, &DeviceInformation);
2288 if (!NT_SUCCESS(Status))
2289 {
2290 FreePool(SourceDeviceName.Buffer);
2291 FreePool(SourceSymbolicName.Buffer);
2292 return Status;
2293 }
2294 }
2295
2296 FreePool(SourceDeviceName.Buffer);
2297
2298 /* Get information about target device */
2299 Status = FindDeviceInfo(DeviceExtension, &TargetVolumeName, FALSE, &TargetDeviceInformation);
2300 if (!NT_SUCCESS(Status))
2301 {
2302 FreePool(SourceSymbolicName.Buffer);
2303 return Status;
2304 }
2305
2306 /* Notify if not disabled */
2307 if (!TargetDeviceInformation->SkipNotifications)
2308 {
2309 PostOnlineNotification(DeviceExtension, &TargetDeviceInformation->SymbolicName);
2310 }
2311
2312 /* Open the remote database */
2313 RemoteDatabase = OpenRemoteDatabase(DeviceInformation, TRUE);
2314 if (RemoteDatabase == 0)
2315 {
2316 FreePool(SourceSymbolicName.Buffer);
2318 }
2319
2320 /* Browse all the entries */
2321 Offset = 0;
2322 Found = FALSE;
2323 for (;;)
2324 {
2326 if (DatabaseEntry == NULL)
2327 {
2328 break;
2329 }
2330
2331 /* Try to find ourselves */
2332 DbName.MaximumLength = DatabaseEntry->SymbolicNameLength;
2333 DbName.Length = DbName.MaximumLength;
2334 DbName.Buffer = (PWSTR)((ULONG_PTR)DatabaseEntry + DatabaseEntry->SymbolicNameOffset);
2335 if (RtlEqualUnicodeString(&TargetVolumeName, &DbName, TRUE))
2336 {
2337 /* Reference ourselves and update the entry */
2338 ++DatabaseEntry->EntryReferences;
2340 FreePool(DatabaseEntry);
2341 Found = TRUE;
2342 break;
2343 }
2344
2345 Offset += DatabaseEntry->EntrySize;
2346 FreePool(DatabaseEntry);
2347 }
2348
2349 /* We couldn't find ourselves, we'll have to add ourselves */
2350 if (!Found)
2351 {
2353 PUNIQUE_ID_REPLICATE UniqueIdReplicate;
2354
2355 /* Query the device unique ID */
2356 Status = QueryDeviceInformation(&TargetVolumeName, NULL, &UniqueId, NULL, NULL, NULL, NULL, NULL);
2357 if (!NT_SUCCESS(Status))
2358 {
2359 FreePool(SourceSymbolicName.Buffer);
2361 return Status;
2362 }
2363
2364 /* Allocate a database entry */
2365 EntrySize = UniqueId->UniqueIdLength + TargetVolumeName.Length + sizeof(DATABASE_ENTRY);
2366 DatabaseEntry = AllocatePool(EntrySize);
2367 if (DatabaseEntry == NULL)
2368 {
2369 FreePool(UniqueId);
2370 FreePool(SourceSymbolicName.Buffer);
2373 }
2374
2375 /* Fill it in */
2376 DatabaseEntry->EntrySize = EntrySize;
2377 DatabaseEntry->EntryReferences = 1;
2378 DatabaseEntry->SymbolicNameOffset = sizeof(DATABASE_ENTRY);
2379 DatabaseEntry->SymbolicNameLength = TargetVolumeName.Length;
2380 DatabaseEntry->UniqueIdOffset = TargetVolumeName.Length + sizeof(DATABASE_ENTRY);
2381 DatabaseEntry->UniqueIdLength = UniqueId->UniqueIdLength;
2382 RtlCopyMemory((PVOID)((ULONG_PTR)DatabaseEntry + sizeof(DATABASE_ENTRY)), TargetVolumeName.Buffer, DatabaseEntry->SymbolicNameLength);
2383 RtlCopyMemory((PVOID)((ULONG_PTR)DatabaseEntry + DatabaseEntry->UniqueIdOffset), UniqueId->UniqueId, UniqueId->UniqueIdLength);
2384
2385 /* And write it down */
2387 FreePool(DatabaseEntry);
2388 if (!NT_SUCCESS(Status))
2389 {
2390 FreePool(UniqueId);
2391 FreePool(SourceSymbolicName.Buffer);
2393 return Status;
2394 }
2395
2396 /* And now, allocate an Unique ID item */
2397 UniqueIdReplicate = AllocatePool(sizeof(UNIQUE_ID_REPLICATE));
2398 if (UniqueIdReplicate == NULL)
2399 {
2400 FreePool(UniqueId);
2401 FreePool(SourceSymbolicName.Buffer);
2403 return Status;
2404 }
2405
2406 /* To associate it with the device */
2407 UniqueIdReplicate->UniqueId = UniqueId;
2408 InsertTailList(&DeviceInformation->ReplicatedUniqueIdsListHead, &UniqueIdReplicate->ReplicatedUniqueIdsListEntry);
2409 }
2410
2411 /* We're done with the remote database */
2413
2414 /* Check we were find writing the entry */
2415 if (!NT_SUCCESS(Status))
2416 {
2417 FreePool(SourceSymbolicName.Buffer);
2418 return Status;
2419 }
2420
2421 /* This is the end, allocate an associated entry */
2422 AssociatedEntry = AllocatePool(sizeof(ASSOCIATED_DEVICE_ENTRY));
2423 if (AssociatedEntry == NULL)
2424 {
2425 FreePool(SourceSymbolicName.Buffer);
2427 }
2428
2429 /* Initialize its source name string */
2430 AssociatedEntry->String.Length = SourceSymbolicName.Length;
2431 AssociatedEntry->String.MaximumLength = AssociatedEntry->String.Length + sizeof(UNICODE_NULL);
2432 AssociatedEntry->String.Buffer = AllocatePool(AssociatedEntry->String.MaximumLength);
2433 if (AssociatedEntry->String.Buffer == NULL)
2434 {
2435 FreePool(AssociatedEntry);
2436 FreePool(SourceSymbolicName.Buffer);
2438 }
2439
2440 /* Copy data & insert in list */
2441 RtlCopyMemory(AssociatedEntry->String.Buffer, SourceSymbolicName.Buffer, SourceSymbolicName.Length);
2442 AssociatedEntry->String.Buffer[SourceSymbolicName.Length / sizeof(WCHAR)] = UNICODE_NULL;
2443 AssociatedEntry->DeviceInformation = DeviceInformation;
2444 InsertTailList(&TargetDeviceInformation->AssociatedDevicesHead, &AssociatedEntry->AssociatedDevicesEntry);
2445
2446 /* We're done! */
2447 FreePool(SourceSymbolicName.Buffer);
2448 return STATUS_SUCCESS;
2449}
return Found
Definition: dirsup.c:1270
NTSTATUS CloseRemoteDatabase(IN HANDLE Database)
Definition: database.c:82
NTSTATUS AddRemoteDatabaseEntry(IN HANDLE Database, IN PDATABASE_ENTRY Entry)
Definition: database.c:64
NTSTATUS WriteRemoteDatabaseEntry(IN HANDLE Database, IN LONG Offset, IN PDATABASE_ENTRY Entry)
Definition: database.c:200
HANDLE OpenRemoteDatabase(IN PDEVICE_INFORMATION DeviceInformation, IN BOOLEAN MigrateDatabase)
Definition: database.c:1837
PDATABASE_ENTRY GetRemoteDatabaseEntry(IN HANDLE Database, IN LONG StartingOffset)
Definition: database.c:125
UNICODE_STRING RemoteDatabase
Definition: database.c:34
NTSTATUS QueryVolumeName(IN HANDLE RootDirectory, IN PFILE_REPARSE_POINT_INFORMATION ReparsePointInformation, IN PUNICODE_STRING FileName OPTIONAL, OUT PUNICODE_STRING SymbolicName, OUT PUNICODE_STRING VolumeName)
Definition: database.c:1292
NTSTATUS MountMgrVolumeMountPointChanged(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp, IN NTSTATUS LockStatus, OUT PUNICODE_STRING SourceDeviceName, OUT PUNICODE_STRING SourceSymbolicName, OUT PUNICODE_STRING TargetVolumeName)
Definition: device.c:1990
_Must_inspect_result_ _Inout_opt_ PUNICODE_STRING VolumeName
Definition: fltkernel.h:1117
NTSTATUS MountMgrQuerySymbolicLink(IN PUNICODE_STRING SymbolicName, IN OUT PUNICODE_STRING LinkTarget)
Definition: symlink.c:849
struct _DATABASE_ENTRY DATABASE_ENTRY
VOID PostOnlineNotification(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName)
Definition: notify.c:122
long LONG
Definition: pedump.c:60
LIST_ENTRY AssociatedDevicesEntry
Definition: mntmgr.h:97
Definition: mntmgr.h:86
USHORT UniqueIdOffset
Definition: mntmgr.h:91
USHORT SymbolicNameLength
Definition: mntmgr.h:90
USHORT UniqueIdLength
Definition: mntmgr.h:92
ULONG EntrySize
Definition: mntmgr.h:87
ULONG EntryReferences
Definition: mntmgr.h:88
USHORT SymbolicNameOffset
Definition: mntmgr.h:89
BOOLEAN SkipNotifications
Definition: mntmgr.h:58
LIST_ENTRY ReplicatedUniqueIdsListHead
Definition: mntmgr.h:46
PMOUNTDEV_UNIQUE_ID UniqueId
Definition: mntmgr.h:82
LIST_ENTRY ReplicatedUniqueIdsListEntry
Definition: mntmgr.h:81
_In_ UCHAR EntrySize
Definition: iofuncs.h:642
_Inout_ PUNICODE_STRING LinkTarget
Definition: zwfuncs.h:292

Referenced by MountMgrDeviceControl().

◆ MountMgrVolumeMountPointDeleted()

NTSTATUS MountMgrVolumeMountPointDeleted ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp,
IN NTSTATUS  LockStatus 
)

Definition at line 2455 of file device.c.

2458{
2459 LONG Offset;
2463 PDATABASE_ENTRY DatabaseEntry;
2464 PUNIQUE_ID_REPLICATE UniqueIdReplicate;
2465 PASSOCIATED_DEVICE_ENTRY AssociatedEntry;
2466 PDEVICE_INFORMATION DeviceInformation, TargetDeviceInformation;
2467 UNICODE_STRING LinkTarget, SourceDeviceName, SourceSymbolicName, TargetVolumeName, VolumeName, DbName;
2468
2469 /* Initialize string */
2470 LinkTarget.Length = 0;
2473 if (LinkTarget.Buffer == NULL)
2474 {
2476 }
2477
2478 /* If the mount point was deleted, then, it changed!
2479 * Also use it to query some information
2480 */
2481 Status = MountMgrVolumeMountPointChanged(DeviceExtension, Irp, LockStatus, &SourceDeviceName, &SourceSymbolicName, &TargetVolumeName);
2482 /* Pending means DB are under synchronization, bail out */
2483 if (Status == STATUS_PENDING)
2484 {
2486 FreePool(SourceDeviceName.Buffer);
2487 FreePool(SourceSymbolicName.Buffer);
2488 return STATUS_SUCCESS;
2489 }
2490 else if (!NT_SUCCESS(Status))
2491 {
2493 return Status;
2494 }
2495
2496 /* Query the device information */
2497 Status = FindDeviceInfo(DeviceExtension, &SourceDeviceName, FALSE, &DeviceInformation);
2498 if (!NT_SUCCESS(Status))
2499 {
2500 /* If it failed, first try to get volume name */
2501 Status = QueryVolumeName(0, NULL, &SourceDeviceName, &LinkTarget, &VolumeName);
2502 if (!NT_SUCCESS(Status))
2503 {
2504 /* Then, try to read the symlink */
2505 Status = MountMgrQuerySymbolicLink(&SourceDeviceName, &LinkTarget);
2506 if (!NT_SUCCESS(Status))
2507 {
2509 FreePool(SourceDeviceName.Buffer);
2510 FreePool(SourceSymbolicName.Buffer);
2511 return Status;
2512 }
2513 }
2514 else
2515 {
2517 }
2518
2519 FreePool(SourceDeviceName.Buffer);
2520
2521 SourceDeviceName.Length = LinkTarget.Length;
2522 SourceDeviceName.MaximumLength = LinkTarget.MaximumLength;
2523 SourceDeviceName.Buffer = LinkTarget.Buffer;
2524
2525 /* Now that we have the correct source, reattempt to query information */
2526 Status = FindDeviceInfo(DeviceExtension, &SourceDeviceName, FALSE, &DeviceInformation);
2527 if (!NT_SUCCESS(Status))
2528 {
2529 FreePool(SourceDeviceName.Buffer);
2530 FreePool(SourceSymbolicName.Buffer);
2531 return Status;
2532 }
2533 }
2534
2535 FreePool(SourceDeviceName.Buffer);
2536
2537 /* Get information about target device */
2538 Status = FindDeviceInfo(DeviceExtension, &TargetVolumeName, FALSE, &TargetDeviceInformation);
2539 if (!NT_SUCCESS(Status))
2540 {
2541 FreePool(SourceSymbolicName.Buffer);
2542 return Status;
2543 }
2544
2545 /* Open the remote database */
2546 RemoteDatabase = OpenRemoteDatabase(DeviceInformation, TRUE);
2547 if (RemoteDatabase == 0)
2548 {
2549 FreePool(SourceSymbolicName.Buffer);
2551 }
2552
2553 /* Browse all the entries */
2554 Offset = 0;
2555 for (;;)
2556 {
2558 if (DatabaseEntry == NULL)
2559 {
2560 /* We didn't find ourselves, that's infortunate! */
2561 FreePool(SourceSymbolicName.Buffer);
2564 }
2565
2566 /* Try to find ourselves */
2567 DbName.MaximumLength = DatabaseEntry->SymbolicNameLength;
2568 DbName.Length = DbName.MaximumLength;
2569 DbName.Buffer = (PWSTR)((ULONG_PTR)DatabaseEntry + DatabaseEntry->SymbolicNameOffset);
2570 if (RtlEqualUnicodeString(&TargetVolumeName, &DbName, TRUE))
2571 {
2572 break;
2573 }
2574
2575 Offset += DatabaseEntry->EntrySize;
2576 FreePool(DatabaseEntry);
2577 }
2578
2579 /* Dereference ourselves */
2580 DatabaseEntry->EntryReferences--;
2581 if (DatabaseEntry->EntryReferences == 0)
2582 {
2583 /* If we're still referenced, just update the entry */
2585 }
2586 else
2587 {
2588 /* Otherwise, delete the entry */
2590 if (!NT_SUCCESS(Status))
2591 {
2592 FreePool(DatabaseEntry);
2593 FreePool(SourceSymbolicName.Buffer);
2595 return Status;
2596 }
2597
2598 /* Also, delete our unique ID replicated record */
2599 for (Entry = DeviceInformation->ReplicatedUniqueIdsListHead.Flink;
2600 Entry != &DeviceInformation->ReplicatedUniqueIdsListHead;
2601 Entry = Entry->Flink)
2602 {
2603 UniqueIdReplicate = CONTAINING_RECORD(Entry, UNIQUE_ID_REPLICATE, ReplicatedUniqueIdsListEntry);
2604
2605 if (UniqueIdReplicate->UniqueId->UniqueIdLength == DatabaseEntry->UniqueIdLength &&
2606 RtlCompareMemory(UniqueIdReplicate->UniqueId->UniqueId,
2607 (PVOID)((ULONG_PTR)DatabaseEntry + DatabaseEntry->UniqueIdOffset),
2608 DatabaseEntry->UniqueIdLength) == DatabaseEntry->UniqueIdLength)
2609 {
2610 break;
2611 }
2612 }
2613
2614 /* It has to exist! */
2615 if (Entry == &DeviceInformation->ReplicatedUniqueIdsListHead)
2616 {
2617 FreePool(DatabaseEntry);
2618 FreePool(SourceSymbolicName.Buffer);
2620 return STATUS_UNSUCCESSFUL;
2621 }
2622
2623 /* Remove it and free it */
2624 RemoveEntryList(&UniqueIdReplicate->ReplicatedUniqueIdsListEntry);
2625 FreePool(UniqueIdReplicate->UniqueId);
2626 FreePool(UniqueIdReplicate);
2627 }
2628
2629 /* We're done with the remote database */
2630 FreePool(DatabaseEntry);
2632
2633 /* Check write operation succeed */
2634 if (!NT_SUCCESS(Status))
2635 {
2636 FreePool(SourceSymbolicName.Buffer);
2637 return Status;
2638 }
2639
2640 /* Try to find our associated device entry */
2641 for (Entry = TargetDeviceInformation->AssociatedDevicesHead.Flink;
2642 Entry != &TargetDeviceInformation->AssociatedDevicesHead;
2643 Entry = Entry->Flink)
2644 {
2645 AssociatedEntry = CONTAINING_RECORD(Entry, ASSOCIATED_DEVICE_ENTRY, AssociatedDevicesEntry);
2646
2647 /* If found, delete it */
2648 if (AssociatedEntry->DeviceInformation == DeviceInformation &&
2649 RtlEqualUnicodeString(&AssociatedEntry->String, &SourceSymbolicName, TRUE))
2650 {
2651 RemoveEntryList(&AssociatedEntry->AssociatedDevicesEntry);
2652 FreePool(AssociatedEntry->String.Buffer);
2653 FreePool(AssociatedEntry);
2654 break;
2655 }
2656 }
2657
2658 /* We're done! */
2659 FreePool(SourceSymbolicName.Buffer);
2660 return STATUS_SUCCESS;
2661}
NTSTATUS DeleteRemoteDatabaseEntry(IN HANDLE Database, IN LONG StartingOffset)
Definition: database.c:233
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465

Referenced by MountMgrDeviceControl().

◆ MountmgrWriteNoAutoMount()

NTSTATUS MountmgrWriteNoAutoMount ( IN PDEVICE_EXTENSION  DeviceExtension)

Definition at line 87 of file device.c.

88{
89 ULONG Value = DeviceExtension->NoAutoMount;
90
92 DeviceExtension->RegistryPath.Buffer,
93 L"NoAutoMount",
95 &Value,
96 sizeof(Value));
97}
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG, PCWSTR, PCWSTR, ULONG, PVOID, ULONG)
#define REG_DWORD
Definition: sdbapi.c:596
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

Referenced by MountMgrSetAutoMount().

◆ ProcessSuggestedDriveLetters()

VOID ProcessSuggestedDriveLetters ( IN PDEVICE_EXTENSION  DeviceExtension)

Definition at line 381 of file device.c.

382{
383 WCHAR NameBuffer[DRIVE_LETTER_LENGTH / sizeof(WCHAR)];
384 PLIST_ENTRY NextEntry;
386 PDEVICE_INFORMATION DeviceInformation;
387
388 /* No devices? Nothing to do! */
389 if (IsListEmpty(&(DeviceExtension->DeviceListHead)))
390 {
391 return;
392 }
393
394 /* For all the devices */
395 for (NextEntry = DeviceExtension->DeviceListHead.Flink;
396 NextEntry != &(DeviceExtension->DeviceListHead);
397 NextEntry = NextEntry->Flink)
398 {
399 DeviceInformation = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
400
401 /* If no drive letter */
402 if (DeviceInformation->SuggestedDriveLetter == (UCHAR)-1)
403 {
404 /* Ensure it has no entry yet */
405 if (!HasDriveLetter(DeviceInformation) &&
406 !HasNoDriveLetterEntry(DeviceInformation->UniqueId))
407 {
408 /* And create one */
409 CreateNoDriveLetterEntry(DeviceInformation->UniqueId);
410 }
411
412 DeviceInformation->SuggestedDriveLetter = 0;
413 }
414 /* Suggested letter & no entry */
415 else if (DeviceInformation->SuggestedDriveLetter &&
416 !HasNoDriveLetterEntry(DeviceInformation->UniqueId))
417 {
418 /* Just create a mount point */
419 SymbolicName.Buffer = NameBuffer;
421 NameBuffer[LETTER_POSITION] = DeviceInformation->SuggestedDriveLetter;
422 NameBuffer[COLON_POSITION] = L':';
425
426 MountMgrCreatePointWorker(DeviceExtension, &SymbolicName, &(DeviceInformation->DeviceName));
427 }
428 }
429}
BOOLEAN HasDriveLetter(IN PDEVICE_INFORMATION DeviceInformation)
Definition: mountmgr.c:167

Referenced by MountMgrNextDriveLetterWorker().

◆ ScrubRegistryRoutine()

NTSTATUS NTAPI ScrubRegistryRoutine ( IN PWSTR  ValueName,
IN ULONG  ValueType,
IN PVOID  ValueData,
IN ULONG  ValueLength,
IN PVOID  Context,
IN PVOID  EntryContext 
)

Definition at line 162 of file device.c.

168{
170 PLIST_ENTRY NextEntry;
172 PBOOLEAN Continue = EntryContext;
173 PDEVICE_EXTENSION DeviceExtension = Context;
174
175 if (ValueType != REG_BINARY)
176 {
177 return STATUS_SUCCESS;
178 }
179
180 /* Delete values for devices that don't have the matching unique ID */
181 if (!IsListEmpty(&(DeviceExtension->DeviceListHead)))
182 {
183 for (NextEntry = DeviceExtension->DeviceListHead.Flink;
184 NextEntry != &(DeviceExtension->DeviceListHead);
185 NextEntry = NextEntry->Flink)
186 {
187 DeviceInfo = CONTAINING_RECORD(NextEntry,
189 DeviceListEntry);
190
191 if (!DeviceInfo->UniqueId || DeviceInfo->UniqueId->UniqueIdLength != ValueLength)
192 {
193 continue;
194 }
195
197 {
198 return STATUS_SUCCESS;
199 }
200 }
201 }
202
203 /* Wrong unique ID, scrub it */
206 ValueName);
207 if (!NT_SUCCESS(Status))
208 {
209 *Continue = TRUE;
210 return STATUS_UNSUCCESSFUL;
211 }
212
213 *Continue = FALSE;
214 return Status;
215}
#define REG_BINARY
Definition: nt_native.h:1496
unsigned char * PBOOLEAN
Definition: typedefs.h:53

Referenced by MountMgrScrubRegistry().