ReactOS 0.4.15-dev-8434-g155a7c7
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 736 of file device.c.

737{
739 PLIST_ENTRY NextEntry;
740 UNICODE_STRING SystemVolumeName;
741 PDEVICE_INFORMATION DeviceInformation;
742 MOUNTMGR_DRIVE_LETTER_INFORMATION DriveLetterInformation;
743
744 /* First, get system volume name */
745 Status = MountMgrQuerySystemVolumeName(&SystemVolumeName);
746
747 /* If there are no device, it's all done */
748 if (IsListEmpty(&(DeviceExtension->DeviceListHead)))
749 {
750 if (NT_SUCCESS(Status))
751 {
752 FreePool(SystemVolumeName.Buffer);
753 }
754
755 return;
756 }
757
758 /* Now, for all the devices... */
759 for (NextEntry = DeviceExtension->DeviceListHead.Flink;
760 NextEntry != &(DeviceExtension->DeviceListHead);
761 NextEntry = NextEntry->Flink)
762 {
763 DeviceInformation = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
764
765 /* If the device doesn't have a letter assigned, do it! */
766 if (!DeviceInformation->LetterAssigned)
767 {
768 MountMgrNextDriveLetterWorker(DeviceExtension,
769 &(DeviceInformation->DeviceName),
770 &DriveLetterInformation);
771 }
772
773 /* If it's the system volume */
774 if (NT_SUCCESS(Status) && RtlEqualUnicodeString(&SystemVolumeName, &(DeviceInformation->DeviceName), TRUE))
775 {
776 /* Keep track of it */
777 DeviceExtension->DriveLetterData = AllocatePool(DeviceInformation->UniqueId->UniqueIdLength +
778 sizeof(MOUNTDEV_UNIQUE_ID));
779 if (DeviceExtension->DriveLetterData)
780 {
781 RtlCopyMemory(DeviceExtension->DriveLetterData,
782 DeviceInformation->UniqueId,
783 DeviceInformation->UniqueId->UniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
784 }
785
786 /* Ensure it gets mounted if automount is disabled */
787 if (DeviceExtension->NoAutoMount)
788 {
789 /* Temporarily re-enable automount for the
790 * worker to mount and set a drive letter */
791 DeviceExtension->NoAutoMount = FALSE;
792
793 MountMgrNextDriveLetterWorker(DeviceExtension,
794 &(DeviceInformation->DeviceName),
795 &DriveLetterInformation);
796
797 /* And re-disable automount */
798 DeviceExtension->NoAutoMount = TRUE;
799 }
800 }
801 }
802
803 if (NT_SUCCESS(Status))
804 {
805 FreePool(SystemVolumeName.Buffer);
806 }
807}
#define TRUE
Definition: types.h:120
NTSTATUS MountMgrQuerySystemVolumeName(OUT PUNICODE_STRING SystemVolumeName)
Definition: device.c:707
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:138
#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 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_PENDING
Definition: ntstatus.h:82
#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:317
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 1820 of file device.c.

1822{
1823 ULONG Link;
1825 BOOLEAN CreateNoDrive;
1827 PMOUNTDEV_UNIQUE_ID UniqueId;
1828 PMOUNTMGR_MOUNT_POINT MountPoint;
1829 PMOUNTMGR_MOUNT_POINTS MountPoints;
1831
1833
1834 /* Validate input */
1835 if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_MOUNT_POINT))
1836 {
1838 }
1839
1840 /* Query points */
1841 MountPoint = (PMOUNTMGR_MOUNT_POINT)Irp->AssociatedIrp.SystemBuffer;
1842 CreateNoDrive = (MountPoint->SymbolicLinkNameOffset && MountPoint->SymbolicLinkNameLength);
1843
1844 Status = MountMgrQueryPoints(DeviceExtension, Irp);
1845 if (!NT_SUCCESS(Status))
1846 {
1847 return Status;
1848 }
1849
1850 /* For all the points matching the request */
1851 MountPoints = (PMOUNTMGR_MOUNT_POINTS)Irp->AssociatedIrp.SystemBuffer;
1852 for (Link = 0; Link < MountPoints->NumberOfMountPoints; Link++)
1853 {
1857 if (!SymbolicName.Buffer)
1858 {
1860 }
1861
1863 (PWSTR)((ULONG_PTR)MountPoints + MountPoints->MountPoints[Link].SymbolicLinkNameOffset),
1866
1867 /* Create a no drive entry for the drive letters */
1868 if (CreateNoDrive && IsDriveLetter(&SymbolicName))
1869 {
1870 UniqueId = AllocatePool(MountPoints->MountPoints[Link].UniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
1871 if (UniqueId)
1872 {
1873 UniqueId->UniqueIdLength = MountPoints->MountPoints[Link].UniqueIdLength;
1874 RtlCopyMemory(UniqueId->UniqueId,
1875 (PMOUNTDEV_UNIQUE_ID)((ULONG_PTR)MountPoints + MountPoints->MountPoints[Link].UniqueIdOffset),
1876 MountPoints->MountPoints[Link].UniqueIdLength);
1877
1878 CreateNoDriveLetterEntry(UniqueId);
1879 FreePool(UniqueId);
1880 }
1881 }
1882
1883 /* If there are no link any more, and no need to create a no drive entry */
1884 if (Link == 0 && !CreateNoDrive)
1885 {
1886 /* Then, delete everything */
1887 UniqueId = AllocatePool(MountPoints->MountPoints[Link].UniqueIdLength);
1888 if (UniqueId)
1889 {
1890 RtlCopyMemory(UniqueId,
1891 (PMOUNTDEV_UNIQUE_ID)((ULONG_PTR)MountPoints + MountPoints->MountPoints[Link].UniqueIdOffset),
1892 MountPoints->MountPoints[Link].UniqueIdLength);
1893
1894 DeleteNoDriveLetterEntry(UniqueId);
1895 FreePool(UniqueId);
1896 }
1897 }
1898
1899 /* Delete all the information about the mount point */
1904
1905 /* Notify the change */
1906 DeviceName.Length = DeviceName.MaximumLength =
1907 MountPoints->MountPoints[Link].DeviceNameLength;
1908 DeviceName.Buffer = (PWSTR)((ULONG_PTR)MountPoints + MountPoints->MountPoints[Link].DeviceNameOffset);
1909 MountMgrNotifyNameChange(DeviceExtension, &DeviceName, TRUE);
1910 }
1911
1912 MountMgrNotify(DeviceExtension);
1913
1914 return Status;
1915}
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:1675
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:139
MOUNTMGR_MOUNT_POINT MountPoints[1]
Definition: imports.h:177
USHORT DeviceNameLength
Definition: imports.h:171
USHORT SymbolicLinkNameLength
Definition: imports.h:167
ULONG SymbolicLinkNameOffset
Definition: imports.h:166
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 1921 of file device.c.

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

Referenced by MountMgrDeviceControl().

◆ MountMgrDeviceControl()

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

Definition at line 2666 of file device.c.

2668{
2670 NTSTATUS Status, LockStatus;
2671 PDEVICE_EXTENSION DeviceExtension;
2672
2674 DeviceExtension = DeviceObject->DeviceExtension;
2675
2676 KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
2677
2678 switch (Stack->Parameters.DeviceIoControl.IoControlCode)
2679 {
2681 Status = MountMgrCreatePoint(DeviceExtension, Irp);
2682 break;
2683
2685 Status = MountMgrDeletePoints(DeviceExtension, Irp);
2686 break;
2687
2689 Status = MountMgrQueryPoints(DeviceExtension, Irp);
2690 break;
2691
2693 Status = MountMgrDeletePointsDbOnly(DeviceExtension, Irp);
2694 break;
2695
2697 Status = MountMgrNextDriveLetter(DeviceExtension, Irp);
2698 break;
2699
2701 // NOTE: On Win7+, this is handled during driver re-initialization.
2702 DeviceExtension->AutomaticDriveLetter = TRUE;
2703 MountMgrAssignDriveLetters(DeviceExtension);
2704 ReconcileAllDatabasesWithMaster(DeviceExtension);
2705 WaitForOnlinesToComplete(DeviceExtension);
2707 break;
2708
2710 KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
2711
2712 LockStatus = WaitForRemoteDatabaseSemaphore(DeviceExtension);
2713 KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
2714 Status = MountMgrVolumeMountPointCreated(DeviceExtension, Irp, LockStatus);
2715 if (NT_SUCCESS(LockStatus))
2716 {
2717 ReleaseRemoteDatabaseSemaphore(DeviceExtension);
2718 }
2719
2720 break;
2721
2723 KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
2724
2725 LockStatus = WaitForRemoteDatabaseSemaphore(DeviceExtension);
2726 KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
2727 Status = MountMgrVolumeMountPointDeleted(DeviceExtension, Irp, LockStatus);
2728 if (NT_SUCCESS(LockStatus))
2729 {
2730 ReleaseRemoteDatabaseSemaphore(DeviceExtension);
2731 }
2732
2733 break;
2734
2736 Status = MountMgrChangeNotify(DeviceExtension, Irp);
2737 break;
2738
2740 Status = MountMgrKeepLinksWhenOffline(DeviceExtension, Irp);
2741 break;
2742
2744 Status = MountMgrCheckUnprocessedVolumes(DeviceExtension, Irp);
2745 goto Complete;
2746
2748 KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
2749 Status = MountMgrVolumeArrivalNotification(DeviceExtension, Irp);
2750 goto Complete;
2751
2753 Status = MountMgrQueryDosVolumePath(DeviceExtension, Irp);
2754 break;
2755
2757 Status = MountMgrQueryDosVolumePaths(DeviceExtension, Irp);
2758 break;
2759
2761 Status = MountMgrScrubRegistry(DeviceExtension);
2762 break;
2763
2765 Status = MountMgrQueryAutoMount(DeviceExtension, Irp);
2766 break;
2767
2769 Status = MountMgrSetAutoMount(DeviceExtension, Irp);
2770 break;
2771
2772 default:
2774 }
2775
2776 KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
2777
2778 if (Status != STATUS_PENDING)
2779 {
2780 goto Complete;
2781 }
2782
2783 return Status;
2784
2785Complete:
2786 Irp->IoStatus.Status = Status;
2788
2789 return Status;
2790}
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:2453
NTSTATUS MountMgrVolumeArrivalNotification(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:1632
NTSTATUS MountMgrDeletePoints(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:1820
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:2214
NTSTATUS MountMgrScrubRegistry(IN PDEVICE_EXTENSION DeviceExtension)
Definition: device.c:221
NTSTATUS MountMgrQueryDosVolumePaths(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:1439
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:1921
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:736
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:813
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:124
#define IOCTL_MOUNTMGR_CREATE_POINT
Definition: imports.h:118
#define IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION
Definition: imports.h:130
#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:34
#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 (Target->DeviceNameLength + sizeof(USHORT) > Stack->Parameters.DeviceIoControl.InputBufferLength)
1607 {
1609 }
1610
1612 SymbolicName.MaximumLength = Target->DeviceNameLength;
1613 SymbolicName.Buffer = Target->DeviceName;
1614
1615 /* Find the associated device */
1616 Status = FindDeviceInfo(DeviceExtension, &SymbolicName, FALSE, &DeviceInformation);
1617 if (!NT_SUCCESS(Status))
1618 {
1619 return Status;
1620 }
1621
1622 /* Mark we want to keep links */
1623 DeviceInformation->KeepLinks = TRUE;
1624
1625 return STATUS_SUCCESS;
1626}
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
unsigned short USHORT
Definition: pedump.c:61
BOOLEAN KeepLinks
Definition: mntmgr.h:51
_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;
640 if (DriveLetterTarget->DeviceNameLength + sizeof(USHORT) > Stack->Parameters.DeviceIoControl.InputBufferLength)
641 {
643 }
644
645 /* Call the worker */
646 DeviceName.Buffer = DriveLetterTarget->DeviceName;
647 DeviceName.Length =
648 DeviceName.MaximumLength = DriveLetterTarget->DeviceNameLength;
649
651 &DriveLetterInformation);
652 if (NT_SUCCESS(Status))
653 {
654 *(PMOUNTMGR_DRIVE_LETTER_INFORMATION)Irp->AssociatedIrp.SystemBuffer =
655 DriveLetterInformation;
656 Irp->IoStatus.Information = sizeof(MOUNTMGR_DRIVE_LETTER_INFORMATION);
657 }
658
659 return Status;
660}
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
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
NTSTATUS QueryDeviceInformation(_In_ PUNICODE_STRING SymbolicName, _Out_opt_ PUNICODE_STRING DeviceName, _Out_opt_ PMOUNTDEV_UNIQUE_ID *UniqueId, _Out_opt_ PBOOLEAN Removable, _Out_opt_ PBOOLEAN GptDriveLetter, _Out_opt_ PBOOLEAN HasGuid, _Inout_opt_ LPGUID StableGuid, _Out_opt_ PBOOLEAN IsFT)
Definition: mountmgr.c:274
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 813 of file device.c.

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

Referenced by MountMgrDeviceControl().

◆ MountMgrQueryDosVolumePaths()

NTSTATUS MountMgrQueryDosVolumePaths ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 1439 of file device.c.

1441{
1444 LIST_ENTRY Devices;
1445 BOOLEAN NeedNotification;
1448 ULONG Attempts, OutputLength;
1451 RECONCILE_WORK_ITEM_CONTEXT ReconcileContext;
1452 PDEVICE_INFORMATION DeviceInformation, ListDeviceInfo, FailedDevice;
1453
1455
1456 /* Validate input size */
1457 if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_TARGET_NAME))
1458 {
1460 }
1461
1462 /* Ensure we have received UNICODE_STRING */
1463 Target = (PMOUNTMGR_TARGET_NAME)Irp->AssociatedIrp.SystemBuffer;
1464 if (Target->DeviceNameLength & 1)
1465 {
1467 }
1468
1469 /* Validate the entry structure size */
1470 if (Target->DeviceNameLength + FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) > Stack->Parameters.DeviceIoControl.InputBufferLength)
1471 {
1473 }
1474
1475 /* Ensure we can at least return needed size */
1476 if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
1477 {
1479 }
1480
1481 /* Construct string for query */
1482 SymbolicName.Length = Target->DeviceNameLength;
1483 SymbolicName.MaximumLength = Target->DeviceNameLength + sizeof(UNICODE_NULL);
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 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 = Output->MultiSzLength + sizeof(ULONG);
1568
1569 /* If it cannot fit, just return need size and quit */
1570 if (OutputLength > Stack->Parameters.DeviceIoControl.OutputBufferLength)
1571 {
1572 Irp->IoStatus.Information = sizeof(ULONG);
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:1149
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
@ Output
Definition: arc.h:85
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 1675 of file device.c.

1677{
1680 PMOUNTDEV_UNIQUE_ID UniqueId;
1681 PMOUNTMGR_MOUNT_POINT MountPoint;
1683
1685
1686 /* Validate input... */
1687 if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_MOUNT_POINT))
1688 {
1690 }
1691
1692 MountPoint = (PMOUNTMGR_MOUNT_POINT)Irp->AssociatedIrp.SystemBuffer;
1693 if (!MountPoint->SymbolicLinkNameLength)
1694 {
1695 MountPoint->SymbolicLinkNameOffset = 0;
1696 }
1697
1698 if (!MountPoint->UniqueIdLength)
1699 {
1700 MountPoint->UniqueIdOffset = 0;
1701 }
1702
1703 if (!MountPoint->DeviceNameLength)
1704 {
1705 MountPoint->DeviceNameOffset = 0;
1706 }
1707
1708 /* Addresses can't be odd */
1709 if ((MountPoint->SymbolicLinkNameOffset & 1) ||
1710 (MountPoint->SymbolicLinkNameLength & 1))
1711 {
1713 }
1714
1715 if ((MountPoint->UniqueIdOffset & 1) ||
1716 (MountPoint->UniqueIdLength & 1))
1717 {
1719 }
1720
1721 if ((MountPoint->DeviceNameOffset & 1) ||
1722 (MountPoint->DeviceNameLength & 1))
1723 {
1725 }
1726
1727 /* We can't go beyond */
1728 if (((ULONG)MountPoint->SymbolicLinkNameLength + MountPoint->UniqueIdLength +
1729 MountPoint->DeviceNameLength) > Stack->Parameters.DeviceIoControl.InputBufferLength)
1730 {
1732 }
1733
1734 if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTMGR_MOUNT_POINTS))
1735 {
1737 }
1738
1739 /* If caller provided a Symlink, use it */
1740 if (MountPoint->SymbolicLinkNameLength != 0)
1741 {
1742 if (MountPoint->SymbolicLinkNameLength > MAXSHORT)
1743 {
1745 }
1746
1750 if (!SymbolicName.Buffer)
1751 {
1753 }
1754
1756 (PWSTR)((ULONG_PTR)MountPoint + MountPoint->SymbolicLinkNameOffset),
1759
1760 /* Query links using it */
1763 }
1764 /* If user provided an unique ID */
1765 else if (MountPoint->UniqueIdLength != 0)
1766 {
1767 UniqueId = AllocatePool(MountPoint->UniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
1768 if (!UniqueId)
1769 {
1771 }
1772
1773 UniqueId->UniqueIdLength = MountPoint->UniqueIdLength;
1774 RtlCopyMemory(UniqueId->UniqueId,
1775 (PVOID)((ULONG_PTR)MountPoint + MountPoint->UniqueIdOffset),
1776 MountPoint->UniqueIdLength);
1777
1778 /* Query links using it */
1779 Status = QueryPointsFromMemory(DeviceExtension, Irp, UniqueId, NULL);
1780 FreePool(UniqueId);
1781 }
1782 /* If caller provided a device name */
1783 else if (MountPoint->DeviceNameLength != 0)
1784 {
1785 if (MountPoint->DeviceNameLength > MAXSHORT)
1786 {
1788 }
1789
1790 DeviceName.Length = MountPoint->DeviceNameLength;
1791 DeviceName.MaximumLength = MountPoint->DeviceNameLength + sizeof(WCHAR);
1792 DeviceName.Buffer = AllocatePool(DeviceName.MaximumLength);
1793 if (!DeviceName.Buffer)
1794 {
1796 }
1797
1799 (PWSTR)((ULONG_PTR)MountPoint + MountPoint->DeviceNameOffset),
1800 DeviceName.Length);
1801 DeviceName.Buffer[DeviceName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1802
1803 /* Query links using it */
1804 Status = QueryPointsFromMemory(DeviceExtension, Irp, NULL, &DeviceName);
1805 FreePool(DeviceName.Buffer);
1806 }
1807 else
1808 {
1809 /* Otherwise, query all links */
1810 Status = QueryPointsFromMemory(DeviceExtension, Irp, NULL, NULL);
1811 }
1812
1813 return Status;
1814}
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 707 of file device.c.

708{
710
714 QueryTable[0].Name = L"SystemPartition";
715
716 SystemVolumeName->Buffer = NULL;
717
719 L"\\Registry\\Machine\\System\\Setup",
721 SystemVolumeName,
722 NULL);
723
724 if (SystemVolumeName->Buffer)
725 {
726 return STATUS_SUCCESS;
727 }
728
729 return STATUS_UNSUCCESSFUL;
730}
NTSTATUS NTAPI MountMgrQuerySystemVolumeNameQueryRoutine(IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
Definition: device.c:667
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:4220
#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 667 of file device.c.

673{
674 UNICODE_STRING ValueString;
675 PUNICODE_STRING SystemVolumeName;
676
680
681 if (ValueType != REG_SZ)
682 {
683 return STATUS_SUCCESS;
684 }
685
686 RtlInitUnicodeString(&ValueString, ValueData);
687 SystemVolumeName = Context;
688
689 /* Return a string containing system volume name */
690 SystemVolumeName->Length = ValueString.Length;
691 SystemVolumeName->MaximumLength = ValueString.Length + sizeof(WCHAR);
692 SystemVolumeName->Buffer = AllocatePool(SystemVolumeName->MaximumLength);
693 if (SystemVolumeName->Buffer)
694 {
695 RtlCopyMemory(SystemVolumeName->Buffer, ValueData, ValueString.Length);
696 SystemVolumeName->Buffer[ValueString.Length / sizeof(WCHAR)] = UNICODE_NULL;
697 }
698
699 return STATUS_SUCCESS;
700
701}
_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:4219
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 1149 of file device.c.

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

1044{
1045 HANDLE Handle;
1047 PLIST_ENTRY SymlinksEntry;
1049 PREPARSE_DATA_BUFFER ReparseData;
1051 UNICODE_STRING FullName, SubstituteName;
1052 PSYMLINK_INFORMATION SymlinkInformation;
1053
1054 /* Initialize & allocate a string big enough to contain our complete mount point name */
1055 FullName.Length = 0;
1056 FullName.MaximumLength = AssociatedDeviceEntry->String.Length
1057 + AssociatedDeviceEntry->DeviceInformation->DeviceName.Length
1058 + sizeof(WCHAR)
1059 + sizeof(UNICODE_NULL);
1061 if (!FullName.Buffer)
1062 {
1064 }
1065
1066 /* Create the path */
1067 RtlAppendUnicodeStringToString(&FullName, &AssociatedDeviceEntry->DeviceInformation->DeviceName);
1068 FullName.Buffer[FullName.Length / sizeof(WCHAR)] = L'\\';
1069 RtlAppendUnicodeStringToString(&FullName, &AssociatedDeviceEntry->String);
1071
1072 /* Open it to query the reparse point */
1074 &FullName,
1076 NULL,
1077 NULL);
1084
1085 if (!NT_SUCCESS(Status))
1086 {
1087 *Invalid = TRUE;
1088 return STATUS_SUCCESS;
1089 }
1090
1091 /* Allocate a buffer big enough to read reparse data */
1093 if (ReparseData == NULL)
1094 {
1095 ZwClose(Handle);
1097 }
1098
1099 /* Query reparse data */
1101 NULL, NULL, NULL,
1104 NULL, 0,
1106 ZwClose(Handle);
1107
1108 if (!NT_SUCCESS(Status))
1109 {
1110 FreePool(ReparseData);
1111 *Invalid = TRUE;
1112 return STATUS_SUCCESS;
1113 }
1114
1115 /* Create a string with the substitute name */
1116 SubstituteName.Length = ReparseData->SymbolicLinkReparseBuffer.SubstituteNameLength;
1117 SubstituteName.MaximumLength = SubstituteName.Length;
1118 SubstituteName.Buffer = (PWSTR)((ULONG_PTR)ReparseData->SymbolicLinkReparseBuffer.PathBuffer + ReparseData->SymbolicLinkReparseBuffer.SubstituteNameOffset);
1119
1120 /* If that's a volume name that matches our associated device, that's a success! */
1121 if (MOUNTMGR_IS_VOLUME_NAME(&SubstituteName))
1122 {
1123 if (SubstituteName.Length == 98 && SubstituteName.Buffer[1] == L'?')
1124 {
1125 for (SymlinksEntry = DeviceInformation->SymbolicLinksListHead.Flink;
1126 SymlinksEntry != &(DeviceInformation->SymbolicLinksListHead);
1127 SymlinksEntry = SymlinksEntry->Flink)
1128 {
1129 SymlinkInformation = CONTAINING_RECORD(SymlinksEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
1130
1131 if (RtlEqualUnicodeString(&SubstituteName, &SymlinkInformation->Name, TRUE))
1132 {
1133 FreePool(ReparseData);
1134 return STATUS_SUCCESS;
1135 }
1136 }
1137 }
1138 }
1139
1140 FreePool(ReparseData);
1141 *Invalid = TRUE;
1142 return STATUS_SUCCESS;
1143}
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::@312::@314 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:1648

Referenced by MountMgrQueryVolumePaths().

◆ MountMgrVolumeArrivalNotification()

NTSTATUS MountMgrVolumeArrivalNotification ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 1632 of file device.c.

1634{
1636 BOOLEAN OldState;
1640
1642
1643 /* Validate input */
1644 if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_TARGET_NAME))
1645 {
1647 }
1648
1649 Target = (PMOUNTMGR_TARGET_NAME)Irp->AssociatedIrp.SystemBuffer;
1650 if (Target->DeviceNameLength + sizeof(USHORT) > Stack->Parameters.DeviceIoControl.InputBufferLength)
1651 {
1653 }
1654
1656 SymbolicName.MaximumLength = Target->DeviceNameLength;
1657 SymbolicName.Buffer = Target->DeviceName;
1658
1659 /* Disable hard errors */
1662
1663 /* Call real worker */
1665
1667
1668 return Status;
1669}
#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 1988 of file device.c.

1994{
1995 HANDLE Handle;
1999 ULONG Length, SavedLength;
2000 BOOLEAN FOReferenced = FALSE;
2003 PDEVICE_INFORMATION DeviceInformation;
2004 OBJECT_NAME_INFORMATION ObjectNameInfo;
2005 FILE_FS_DEVICE_INFORMATION FsDeviceInfo;
2006 PFILE_NAME_INFORMATION FileNameInfo = NULL;
2007 PMOUNTMGR_VOLUME_MOUNT_POINT VolumeMountPoint;
2008 POBJECT_NAME_INFORMATION ObjectNameInfoPtr = NULL;
2009 UNICODE_STRING SourceVolumeName, TargetDeviceName;
2010
2012
2013 /* Validate input */
2014 if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_VOLUME_MOUNT_POINT))
2015 {
2017 }
2018
2019 VolumeMountPoint = (PMOUNTMGR_VOLUME_MOUNT_POINT)Irp->AssociatedIrp.SystemBuffer;
2020
2021 if (((ULONG)VolumeMountPoint->SourceVolumeNameLength + VolumeMountPoint->TargetVolumeNameLength) <
2022 Stack->Parameters.DeviceIoControl.InputBufferLength)
2023 {
2025 }
2026
2027 /* Get source volume name */
2028 SourceVolumeName.Length =
2029 SourceVolumeName.MaximumLength = VolumeMountPoint->SourceVolumeNameLength;
2030 SourceVolumeName.Buffer = (PWSTR)((ULONG_PTR)VolumeMountPoint + VolumeMountPoint->SourceVolumeNameOffset);
2031
2033 &SourceVolumeName,
2035 NULL,
2036 NULL);
2037
2038 /* Open it */
2045 if (!NT_SUCCESS(Status))
2046 {
2047 return Status;
2048 }
2049
2050 TargetDeviceName.Buffer = NULL;
2051
2052 /* Query its attributes */
2055 &FsDeviceInfo,
2056 sizeof(FsDeviceInfo),
2058 if (!NT_SUCCESS(Status))
2059 {
2060 goto Cleanup;
2061 }
2062
2063 if (FsDeviceInfo.DeviceType != FILE_DEVICE_DISK && FsDeviceInfo.DeviceType != FILE_DEVICE_VIRTUAL_DISK)
2064 {
2065 goto Cleanup;
2066 }
2067
2069 {
2070 goto Cleanup;
2071 }
2072
2073 /* Reference it */
2075 if (!NT_SUCCESS(Status))
2076 {
2077 goto Cleanup;
2078 }
2079 FOReferenced = TRUE;
2080
2081 /* Get file name */
2082 FileNameInfo = AllocatePool(sizeof(FILE_NAME_INFORMATION));
2083 if (!FileNameInfo)
2084 {
2086 goto Cleanup;
2087 }
2088
2089 Status = ZwQueryInformationFile(Handle, &IoStatusBlock, FileNameInfo,
2090 sizeof(FILE_NAME_INFORMATION),
2093 {
2094 /* Now we have real length, use it */
2095 Length = FileNameInfo->FileNameLength;
2096 FreePool(FileNameInfo);
2097
2098 FileNameInfo = AllocatePool(sizeof(FILE_NAME_INFORMATION) + Length);
2099 if (!FileNameInfo)
2100 {
2102 goto Cleanup;
2103 }
2104
2105 /* Really query file name */
2106 Status = ZwQueryInformationFile(Handle, &IoStatusBlock, FileNameInfo,
2107 sizeof(FILE_NAME_INFORMATION) + Length,
2109 }
2110
2111 if (!NT_SUCCESS(Status))
2112 {
2113 goto Cleanup;
2114 }
2115
2116 /* Get symbolic name */
2117 ObjectNameInfoPtr = &ObjectNameInfo;
2118 SavedLength = sizeof(OBJECT_NAME_INFORMATION);
2119 Status = ObQueryNameString(FileObject->DeviceObject, ObjectNameInfoPtr, sizeof(OBJECT_NAME_INFORMATION), &Length);
2121 {
2122 /* Once again, with proper size, it works better */
2123 ObjectNameInfoPtr = AllocatePool(Length);
2124 if (!ObjectNameInfoPtr)
2125 {
2127 goto Cleanup;
2128 }
2129
2130 SavedLength = Length;
2131 Status = ObQueryNameString(FileObject->DeviceObject, ObjectNameInfoPtr, SavedLength, &Length);
2132 }
2133
2134 if (!NT_SUCCESS(Status))
2135 {
2136 goto Cleanup;
2137 }
2138
2139 /* Now, query the device name */
2140 Status = QueryDeviceInformation(&ObjectNameInfoPtr->Name, SourceDeviceName,
2141 NULL, NULL, NULL, NULL, NULL, NULL);
2142 if (!NT_SUCCESS(Status))
2143 {
2144 goto Cleanup;
2145 }
2146
2147 /* For target volume name, use input */
2148 TargetVolumeName->Length =
2149 TargetVolumeName->MaximumLength = VolumeMountPoint->TargetVolumeNameLength;
2150 TargetVolumeName->Buffer = (PWSTR)((ULONG_PTR)VolumeMountPoint + VolumeMountPoint->TargetVolumeNameOffset);
2151
2152 /* Query its device name */
2153 Status = QueryDeviceInformation(TargetVolumeName, &TargetDeviceName,
2154 NULL, NULL, NULL, NULL, NULL, NULL);
2155 if (!NT_SUCCESS(Status))
2156 {
2157 goto Cleanup;
2158 }
2159
2160 /* Return symbolic name */
2161 SourceSymbolicName->Length =
2162 SourceSymbolicName->MaximumLength = (USHORT)FileNameInfo->FileNameLength;
2163 SourceSymbolicName->Buffer = (PWSTR)FileNameInfo;
2164 /* memmove allows memory overlap */
2165 RtlMoveMemory(SourceSymbolicName->Buffer, FileNameInfo->FileName, SourceSymbolicName->Length);
2166 FileNameInfo = NULL;
2167
2168 /* Notify the change */
2169 MountMgrNotify(DeviceExtension);
2170 MountMgrNotifyNameChange(DeviceExtension, &TargetDeviceName, TRUE);
2171
2172 /* If we are locked, sync databases if possible */
2173 if (NT_SUCCESS(LockStatus))
2174 {
2175 Status = FindDeviceInfo(DeviceExtension, SourceDeviceName, FALSE, &DeviceInformation);
2176 if (NT_SUCCESS(Status))
2177 {
2178 ReconcileThisDatabaseWithMaster(DeviceExtension, DeviceInformation);
2179 }
2180 else
2181 {
2183 }
2184 }
2185
2186Cleanup:
2187 if (TargetDeviceName.Buffer)
2188 {
2189 FreePool(TargetDeviceName.Buffer);
2190 }
2191
2192 if (ObjectNameInfoPtr && ObjectNameInfoPtr != &ObjectNameInfo)
2193 {
2194 FreePool(ObjectNameInfoPtr);
2195 }
2196
2197 if (FileNameInfo)
2198 {
2199 FreePool(FileNameInfo);
2200 }
2201
2202 if (FOReferenced)
2203 {
2205 }
2206
2207 return Status;
2208}
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 2214 of file device.c.

2217{
2218 LONG Offset;
2219 BOOLEAN Found;
2222 PMOUNTDEV_UNIQUE_ID UniqueId;
2223 PDATABASE_ENTRY DatabaseEntry;
2224 PASSOCIATED_DEVICE_ENTRY AssociatedEntry;
2225 PDEVICE_INFORMATION DeviceInformation, TargetDeviceInformation;
2226 UNICODE_STRING LinkTarget, SourceDeviceName, SourceSymbolicName, TargetVolumeName, VolumeName, DbName;
2227
2228 /* Initialize string */
2229 LinkTarget.Length = 0;
2232 if (LinkTarget.Buffer == NULL)
2233 {
2235 }
2236
2237 /* If the mount point was created, then, it changed!
2238 * Also use it to query some information
2239 */
2240 Status = MountMgrVolumeMountPointChanged(DeviceExtension, Irp, LockStatus, &SourceDeviceName, &SourceSymbolicName, &TargetVolumeName);
2241 /* Pending means DB are under synchronization, bail out */
2242 if (Status == STATUS_PENDING)
2243 {
2245 FreePool(SourceDeviceName.Buffer);
2246 FreePool(SourceSymbolicName.Buffer);
2247 return STATUS_SUCCESS;
2248 }
2249 else if (!NT_SUCCESS(Status))
2250 {
2252 return Status;
2253 }
2254
2255 /* Query the device information */
2256 Status = FindDeviceInfo(DeviceExtension, &SourceDeviceName, FALSE, &DeviceInformation);
2257 if (!NT_SUCCESS(Status))
2258 {
2259 /* If it failed, first try to get volume name */
2260 Status = QueryVolumeName(0, NULL, &SourceDeviceName, &LinkTarget, &VolumeName);
2261 if (!NT_SUCCESS(Status))
2262 {
2263 /* Then, try to read the symlink */
2264 Status = MountMgrQuerySymbolicLink(&SourceDeviceName, &LinkTarget);
2265 if (!NT_SUCCESS(Status))
2266 {
2268 FreePool(SourceDeviceName.Buffer);
2269 FreePool(SourceSymbolicName.Buffer);
2270 return Status;
2271 }
2272 }
2273 else
2274 {
2276 }
2277
2278 FreePool(SourceDeviceName.Buffer);
2279
2280 SourceDeviceName.Length = LinkTarget.Length;
2281 SourceDeviceName.MaximumLength = LinkTarget.MaximumLength;
2282 SourceDeviceName.Buffer = LinkTarget.Buffer;
2283
2284 /* Now that we have the correct source, reattempt to query information */
2285 Status = FindDeviceInfo(DeviceExtension, &SourceDeviceName, FALSE, &DeviceInformation);
2286 if (!NT_SUCCESS(Status))
2287 {
2288 FreePool(SourceDeviceName.Buffer);
2289 FreePool(SourceSymbolicName.Buffer);
2290 return Status;
2291 }
2292 }
2293
2294 FreePool(SourceDeviceName.Buffer);
2295
2296 /* Get information about target device */
2297 Status = FindDeviceInfo(DeviceExtension, &TargetVolumeName, FALSE, &TargetDeviceInformation);
2298 if (!NT_SUCCESS(Status))
2299 {
2300 FreePool(SourceSymbolicName.Buffer);
2301 return Status;
2302 }
2303
2304 /* Notify if not disabled */
2305 if (!TargetDeviceInformation->SkipNotifications)
2306 {
2307 PostOnlineNotification(DeviceExtension, &TargetDeviceInformation->SymbolicName);
2308 }
2309
2310 /* Open the remote database */
2311 RemoteDatabase = OpenRemoteDatabase(DeviceInformation, TRUE);
2312 if (RemoteDatabase == 0)
2313 {
2314 FreePool(SourceSymbolicName.Buffer);
2316 }
2317
2318 /* Browse all the entries */
2319 Offset = 0;
2320 Found = FALSE;
2321 for (;;)
2322 {
2324 if (DatabaseEntry == NULL)
2325 {
2326 break;
2327 }
2328
2329 /* Try to find ourselves */
2330 DbName.MaximumLength = DatabaseEntry->SymbolicNameLength;
2331 DbName.Length = DbName.MaximumLength;
2332 DbName.Buffer = (PWSTR)((ULONG_PTR)DatabaseEntry + DatabaseEntry->SymbolicNameOffset);
2333 if (RtlEqualUnicodeString(&TargetVolumeName, &DbName, TRUE))
2334 {
2335 /* Reference ourselves and update the entry */
2336 ++DatabaseEntry->EntryReferences;
2338 FreePool(DatabaseEntry);
2339 Found = TRUE;
2340 break;
2341 }
2342
2343 Offset += DatabaseEntry->EntrySize;
2344 FreePool(DatabaseEntry);
2345 }
2346
2347 /* We couldn't find ourselves, we'll have to add ourselves */
2348 if (!Found)
2349 {
2351 PUNIQUE_ID_REPLICATE UniqueIdReplicate;
2352
2353 /* Query the device unique ID */
2354 Status = QueryDeviceInformation(&TargetVolumeName, NULL, &UniqueId, NULL, NULL, NULL, NULL, NULL);
2355 if (!NT_SUCCESS(Status))
2356 {
2357 FreePool(SourceSymbolicName.Buffer);
2359 return Status;
2360 }
2361
2362 /* Allocate a database entry */
2363 EntrySize = UniqueId->UniqueIdLength + TargetVolumeName.Length + sizeof(DATABASE_ENTRY);
2364 DatabaseEntry = AllocatePool(EntrySize);
2365 if (DatabaseEntry == NULL)
2366 {
2367 FreePool(UniqueId);
2368 FreePool(SourceSymbolicName.Buffer);
2371 }
2372
2373 /* Fill it in */
2374 DatabaseEntry->EntrySize = EntrySize;
2375 DatabaseEntry->EntryReferences = 1;
2376 DatabaseEntry->SymbolicNameOffset = sizeof(DATABASE_ENTRY);
2377 DatabaseEntry->SymbolicNameLength = TargetVolumeName.Length;
2378 DatabaseEntry->UniqueIdOffset = TargetVolumeName.Length + sizeof(DATABASE_ENTRY);
2379 DatabaseEntry->UniqueIdLength = UniqueId->UniqueIdLength;
2380 RtlCopyMemory((PVOID)((ULONG_PTR)DatabaseEntry + sizeof(DATABASE_ENTRY)), TargetVolumeName.Buffer, DatabaseEntry->SymbolicNameLength);
2381 RtlCopyMemory((PVOID)((ULONG_PTR)DatabaseEntry + DatabaseEntry->UniqueIdOffset), UniqueId->UniqueId, UniqueId->UniqueIdLength);
2382
2383 /* And write it down */
2385 FreePool(DatabaseEntry);
2386 if (!NT_SUCCESS(Status))
2387 {
2388 FreePool(UniqueId);
2389 FreePool(SourceSymbolicName.Buffer);
2391 return Status;
2392 }
2393
2394 /* And now, allocate an Unique ID item */
2395 UniqueIdReplicate = AllocatePool(sizeof(UNIQUE_ID_REPLICATE));
2396 if (UniqueIdReplicate == NULL)
2397 {
2398 FreePool(UniqueId);
2399 FreePool(SourceSymbolicName.Buffer);
2401 return Status;
2402 }
2403
2404 /* To associate it with the device */
2405 UniqueIdReplicate->UniqueId = UniqueId;
2406 InsertTailList(&DeviceInformation->ReplicatedUniqueIdsListHead, &UniqueIdReplicate->ReplicatedUniqueIdsListEntry);
2407 }
2408
2409 /* We're done with the remote database */
2411
2412 /* Check we were find writing the entry */
2413 if (!NT_SUCCESS(Status))
2414 {
2415 FreePool(SourceSymbolicName.Buffer);
2416 return Status;
2417 }
2418
2419 /* This is the end, allocate an associated entry */
2420 AssociatedEntry = AllocatePool(sizeof(ASSOCIATED_DEVICE_ENTRY));
2421 if (AssociatedEntry == NULL)
2422 {
2423 FreePool(SourceSymbolicName.Buffer);
2425 }
2426
2427 /* Initialize its source name string */
2428 AssociatedEntry->String.Length = SourceSymbolicName.Length;
2429 AssociatedEntry->String.MaximumLength = AssociatedEntry->String.Length + sizeof(UNICODE_NULL);
2430 AssociatedEntry->String.Buffer = AllocatePool(AssociatedEntry->String.MaximumLength);
2431 if (AssociatedEntry->String.Buffer == NULL)
2432 {
2433 FreePool(AssociatedEntry);
2434 FreePool(SourceSymbolicName.Buffer);
2436 }
2437
2438 /* Copy data & insert in list */
2439 RtlCopyMemory(AssociatedEntry->String.Buffer, SourceSymbolicName.Buffer, SourceSymbolicName.Length);
2440 AssociatedEntry->String.Buffer[SourceSymbolicName.Length / sizeof(WCHAR)] = UNICODE_NULL;
2441 AssociatedEntry->DeviceInformation = DeviceInformation;
2442 InsertTailList(&TargetDeviceInformation->AssociatedDevicesHead, &AssociatedEntry->AssociatedDevicesEntry);
2443
2444 /* We're done! */
2445 FreePool(SourceSymbolicName.Buffer);
2446 return STATUS_SUCCESS;
2447}
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:1988
_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 2453 of file device.c.

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