ReactOS  0.4.15-dev-976-g0f66c66
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 {
333  PIRP Irp;
334  KEVENT Event;
339  PDEVICE_OBJECT DeviceObject, FileDeviceObject;
340 
341  /* Get device object */
344  &FileObject,
345  &DeviceObject);
346  if (!NT_SUCCESS(Status))
347  {
348  return FALSE;
349  }
350 
351  /* Get attached device */
352  FileDeviceObject = FileObject->DeviceObject;
353  DeviceObject = IoGetAttachedDeviceReference(FileDeviceObject);
354 
355  /* FT volume can't be removable */
356  if (FileDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
357  {
360  return FALSE;
361  }
362 
364 
365  /* Get partition information */
368  DeviceObject,
369  NULL,
370  0,
371  &PartitionInfo,
372  sizeof(PartitionInfo),
373  FALSE,
374  &Event,
375  &IoStatusBlock);
376  if (!Irp)
377  {
379  return FALSE;
380  }
381 
383  if (Status == STATUS_PENDING)
384  {
387  }
388 
390  if (!NT_SUCCESS(Status))
391  {
392  return FALSE;
393  }
394 
395  /* Check if this is a FT volume */
396  return IsFTPartition(PartitionInfo.PartitionType);
397 }
_In_ PIRP Irp
Definition: csq.h:116
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define FALSE
Definition: types.h:117
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:439
smooth NULL
Definition: ftsmooth.c:416
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:588
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2101
* PFILE_OBJECT
Definition: iotypes.h:1962
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
Status
Definition: gdiplustypes.h:24
#define IOCTL_DISK_GET_PARTITION_INFO
Definition: ntdddisk.h:106
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1569
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define IsFTPartition(PartitionType)
Definition: ntdddisk.h:307
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881

Referenced by MountMgrNextDriveLetterWorker().

◆ MountMgrAssignDriveLetters()

VOID MountMgrAssignDriveLetters ( IN PDEVICE_EXTENSION  DeviceExtension)

Definition at line 763 of file device.c.

764 {
766  PLIST_ENTRY NextEntry;
767  UNICODE_STRING SystemVolumeName;
768  PDEVICE_INFORMATION DeviceInformation;
769  MOUNTMGR_DRIVE_LETTER_INFORMATION DriveLetterInformation;
770 
771  /* First, get system volume name */
772  Status = MountMgrQuerySystemVolumeName(&SystemVolumeName);
773 
774  /* If there are no device, it's all done */
775  if (IsListEmpty(&(DeviceExtension->DeviceListHead)))
776  {
777  if (NT_SUCCESS(Status))
778  {
779  FreePool(SystemVolumeName.Buffer);
780  }
781 
782  return;
783  }
784 
785  /* Now, for all the devices... */
786  for (NextEntry = DeviceExtension->DeviceListHead.Flink;
787  NextEntry != &(DeviceExtension->DeviceListHead);
788  NextEntry = NextEntry->Flink)
789  {
790  DeviceInformation = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
791 
792  /* If the device doesn't have a letter assigned, do it! */
793  if (!DeviceInformation->LetterAssigned)
794  {
795  MountMgrNextDriveLetterWorker(DeviceExtension,
796  &(DeviceInformation->DeviceName),
797  &DriveLetterInformation);
798  }
799 
800  /* If it was the system volume */
801  if (NT_SUCCESS(Status) && RtlEqualUnicodeString(&SystemVolumeName, &(DeviceInformation->DeviceName), TRUE))
802  {
803  /* Keep track of it */
804  DeviceExtension->DriveLetterData = AllocatePool(DeviceInformation->UniqueId->UniqueIdLength +
805  sizeof(MOUNTDEV_UNIQUE_ID));
806  if (DeviceExtension->DriveLetterData)
807  {
808  RtlCopyMemory(DeviceExtension->DriveLetterData,
809  DeviceInformation->UniqueId,
810  DeviceInformation->UniqueId->UniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
811  }
812 
813  /* If it was not automount, ensure it gets mounted */
814  if (!DeviceExtension->NoAutoMount)
815  {
816  DeviceExtension->NoAutoMount = TRUE;
817 
818  MountMgrNextDriveLetterWorker(DeviceExtension,
819  &(DeviceInformation->DeviceName),
820  &DriveLetterInformation);
821 
822  DeviceExtension->NoAutoMount = FALSE;
823  }
824  }
825  }
826 
827  if (NT_SUCCESS(Status))
828  {
829  FreePool(SystemVolumeName.Buffer);
830  }
831 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
NTSTATUS MountMgrNextDriveLetterWorker(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName, OUT PMOUNTMGR_DRIVE_LETTER_INFORMATION DriveLetterInfo)
Definition: device.c:457
#define TRUE
Definition: types.h:120
BOOLEAN LetterAssigned
Definition: mntmgr.h:55
LONG NTSTATUS
Definition: precomp.h:26
USHORT UniqueIdLength
Definition: imports.h:138
#define FreePool(P)
Definition: mntmgr.h:154
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define FALSE
Definition: types.h:117
NTSTATUS MountMgrQuerySystemVolumeName(OUT PUNICODE_STRING SystemVolumeName)
Definition: device.c:734
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:24
Definition: typedefs.h:119
#define AllocatePool(Size)
Definition: mntmgr.h:153
UNICODE_STRING DeviceName
Definition: mntmgr.h:50
PMOUNTDEV_UNIQUE_ID UniqueId
Definition: mntmgr.h:49
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)

Referenced by MountMgrDeviceControl().

◆ MountMgrChangeNotify()

NTSTATUS MountMgrChangeNotify ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 37 of file device.c.

39 {
40  KIRQL OldIrql;
42  PIO_STACK_LOCATION Stack;
43  PMOUNTMGR_CHANGE_NOTIFY_INFO ChangeNotify;
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 }
VOID NTAPI MountMgrCancel(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: mountmgr.c:1682
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI IoAcquireCancelSpinLock(OUT PKIRQL Irql)
Definition: util.c:56
#define InsertTailList(ListHead, Entry)
IoSetCancelRoutine(Irp, CancelRoutine)
UCHAR KIRQL
Definition: env_spec_w32.h:591
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
struct _MOUNTMGR_CHANGE_NOTIFY_INFO MOUNTMGR_CHANGE_NOTIFY_INFO
Status
Definition: gdiplustypes.h:24
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2779
return STATUS_SUCCESS
Definition: btrfs.c:3014
IoMarkIrpPending(Irp)
struct _MOUNTMGR_CHANGE_NOTIFY_INFO * PMOUNTMGR_CHANGE_NOTIFY_INFO

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 }
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
UNICODE_STRING SymbolicName
Definition: mntmgr.h:48
#define FALSE
Definition: types.h:117
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:24
Definition: typedefs.h:119
BOOLEAN ManuallyRegistered
Definition: mntmgr.h:53
VOID MountMgrFreeDeadDeviceInfo(IN PDEVICE_INFORMATION DeviceInformation)
Definition: mountmgr.c:707
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
#define IO_NO_INCREMENT
Definition: iotypes.h:570
NTSTATUS MountMgrMountedDeviceArrival(IN PDEVICE_EXTENSION Extension, IN PUNICODE_STRING SymbolicName, IN BOOLEAN FromVolume)
Definition: mountmgr.c:937
return STATUS_SUCCESS
Definition: btrfs.c:3014

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;
253  PIO_STACK_LOCATION Stack;
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 }
USHORT MaximumLength
Definition: env_spec_w32.h:370
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
WCHAR DeviceName[]
Definition: adapter.cpp:21
NTSTATUS MountMgrCreatePointWorker(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicLinkName, IN PUNICODE_STRING DeviceName)
Definition: point.c:35
uint32_t ULONG_PTR
Definition: typedefs.h:65
void * PVOID
Definition: retypes.h:9
struct Point Point
T MAX(T a, T b)
Definition: polytest.cpp:85
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
unsigned int ULONG
Definition: retypes.h:1
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2779
struct _MOUNTMGR_CREATE_POINT_INPUT * PMOUNTMGR_CREATE_POINT_INPUT

Referenced by MountMgrDeviceControl().

◆ MountMgrDeletePoints()

NTSTATUS MountMgrDeletePoints ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 1840 of file device.c.

1842 {
1843  ULONG Link;
1844  NTSTATUS Status;
1845  BOOLEAN CreateNoDrive;
1846  PIO_STACK_LOCATION Stack;
1847  PMOUNTDEV_UNIQUE_ID UniqueId;
1848  PMOUNTMGR_MOUNT_POINT MountPoint;
1849  PMOUNTMGR_MOUNT_POINTS MountPoints;
1851 
1853 
1854  /* Validate input */
1855  if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_MOUNT_POINT))
1856  {
1857  return STATUS_INVALID_PARAMETER;
1858  }
1859 
1860  /* Query points */
1861  MountPoint = (PMOUNTMGR_MOUNT_POINT)Irp->AssociatedIrp.SystemBuffer;
1862  CreateNoDrive = (MountPoint->SymbolicLinkNameOffset && MountPoint->SymbolicLinkNameLength);
1863 
1864  Status = MountMgrQueryPoints(DeviceExtension, Irp);
1865  if (!NT_SUCCESS(Status))
1866  {
1867  return Status;
1868  }
1869 
1870  /* For all the points matching the request */
1871  MountPoints = (PMOUNTMGR_MOUNT_POINTS)Irp->AssociatedIrp.SystemBuffer;
1872  for (Link = 0; Link < MountPoints->NumberOfMountPoints; Link++)
1873  {
1877  if (!SymbolicName.Buffer)
1878  {
1880  }
1881 
1883  (PWSTR)((ULONG_PTR)MountPoints + MountPoints->MountPoints[Link].SymbolicLinkNameOffset),
1886 
1887  /* Create a no drive entry for the drive letters */
1888  if (CreateNoDrive && IsDriveLetter(&SymbolicName))
1889  {
1890  UniqueId = AllocatePool(MountPoints->MountPoints[Link].UniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
1891  if (UniqueId)
1892  {
1893  UniqueId->UniqueIdLength = MountPoints->MountPoints[Link].UniqueIdLength;
1894  RtlCopyMemory(UniqueId->UniqueId,
1895  (PMOUNTDEV_UNIQUE_ID)((ULONG_PTR)MountPoints + MountPoints->MountPoints[Link].UniqueIdOffset),
1896  MountPoints->MountPoints[Link].UniqueIdLength);
1897 
1898  CreateNoDriveLetterEntry(UniqueId);
1899  FreePool(UniqueId);
1900  }
1901  }
1902 
1903  /* If there are no link any more, and no need to create a no drive entry */
1904  if (Link == 0 && !CreateNoDrive)
1905  {
1906  /* Then, delete everything */
1907  UniqueId = AllocatePool(MountPoints->MountPoints[Link].UniqueIdLength);
1908  if (UniqueId)
1909  {
1910  RtlCopyMemory(UniqueId,
1911  (PMOUNTDEV_UNIQUE_ID)((ULONG_PTR)MountPoints + MountPoints->MountPoints[Link].UniqueIdOffset),
1912  MountPoints->MountPoints[Link].UniqueIdLength);
1913 
1914  DeleteNoDriveLetterEntry(UniqueId);
1915  FreePool(UniqueId);
1916  }
1917  }
1918 
1919  /* Delete all the information about the mount point */
1924 
1925  /* Notify the change */
1926  DeviceName.Length = DeviceName.MaximumLength =
1927  MountPoints->MountPoints[Link].DeviceNameLength;
1928  DeviceName.Buffer = (PWSTR)((ULONG_PTR)MountPoints + MountPoints->MountPoints[Link].DeviceNameOffset);
1929  MountMgrNotifyNameChange(DeviceExtension, &DeviceName, TRUE);
1930  }
1931 
1932  MountMgrNotify(DeviceExtension);
1933 
1934  return Status;
1935 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
USHORT MaximumLength
Definition: env_spec_w32.h:370
struct _MOUNTMGR_MOUNT_POINTS * PMOUNTMGR_MOUNT_POINTS
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
uint16_t * PWSTR
Definition: typedefs.h:56
NTSTATUS GlobalDeleteSymbolicLink(IN PUNICODE_STRING DosName)
Definition: symlink.c:136
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
LONG NTSTATUS
Definition: precomp.h:26
USHORT UniqueIdLength
Definition: imports.h:138
BOOLEAN IsDriveLetter(PUNICODE_STRING SymbolicName)
Definition: symlink.c:922
VOID DeleteSymbolicLinkNameFromMemory(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicLink, IN BOOLEAN MarkOffline)
Definition: symlink.c:864
WCHAR DeviceName[]
Definition: adapter.cpp:21
VOID DeleteNoDriveLetterEntry(IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: database.c:2098
#define FreePool(P)
Definition: mntmgr.h:154
static int Link(const char **args)
Definition: vfdcmd.c:2414
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
unsigned char BOOLEAN
USHORT DeviceNameLength
Definition: imports.h:171
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _MOUNTMGR_MOUNT_POINT * PMOUNTMGR_MOUNT_POINT
#define for
Definition: utility.h:88
VOID CreateNoDriveLetterEntry(IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: uniqueid.c:269
NTSTATUS MountMgrQueryPoints(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:1695
Status
Definition: gdiplustypes.h:24
VOID MountMgrNotify(IN PDEVICE_EXTENSION DeviceExtension)
Definition: notify.c:313
NTSYSAPI NTSTATUS WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR)
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define AllocatePool(Size)
Definition: mntmgr.h:153
PWSTR DatabasePath
Definition: database.c:31
MOUNTMGR_MOUNT_POINT MountPoints[1]
Definition: imports.h:177
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
ULONG SymbolicLinkNameOffset
Definition: imports.h:166
unsigned int ULONG
Definition: retypes.h:1
USHORT SymbolicLinkNameLength
Definition: imports.h:167
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2779
UCHAR UniqueId[1]
Definition: imports.h:139
VOID MountMgrNotifyNameChange(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName, IN BOOLEAN ValidateVolume)
Definition: notify.c:353

Referenced by MountMgrDeviceControl().

◆ MountMgrDeletePointsDbOnly()

NTSTATUS MountMgrDeletePointsDbOnly ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 1941 of file device.c.

1943 {
1944  ULONG Link;
1945  NTSTATUS Status;
1947  PMOUNTDEV_UNIQUE_ID UniqueId;
1948  PMOUNTMGR_MOUNT_POINTS MountPoints;
1949 
1950  /* Query points */
1951  Status = MountMgrQueryPoints(DeviceExtension, Irp);
1952  if (!NT_SUCCESS(Status))
1953  {
1954  return Status;
1955  }
1956 
1957  MountPoints = (PMOUNTMGR_MOUNT_POINTS)Irp->AssociatedIrp.SystemBuffer;
1958  if (MountPoints->NumberOfMountPoints == 0)
1959  {
1960  return Status;
1961  }
1962 
1963  /* For all the mount points */
1964  for (Link = 0; Link < MountPoints->NumberOfMountPoints; Link++)
1965  {
1969  if (!SymbolicName.Buffer)
1970  {
1972  }
1973 
1975  (PWSTR)((ULONG_PTR)MountPoints + MountPoints->MountPoints[Link].SymbolicLinkNameOffset),
1978 
1979  /* If the only mount point is a drive letter, then create a no letter drive entry */
1980  if (MountPoints->NumberOfMountPoints == 1 && IsDriveLetter(&SymbolicName))
1981  {
1982  UniqueId = AllocatePool(MountPoints->MountPoints[Link].UniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
1983  if (UniqueId)
1984  {
1985  UniqueId->UniqueIdLength = MountPoints->MountPoints[Link].UniqueIdLength;
1986  RtlCopyMemory(UniqueId->UniqueId,
1987  (PMOUNTDEV_UNIQUE_ID)((ULONG_PTR)MountPoints + MountPoints->MountPoints[Link].UniqueIdOffset),
1988  MountPoints->MountPoints[Link].UniqueIdLength);
1989 
1990  CreateNoDriveLetterEntry(UniqueId);
1991  FreePool(UniqueId);
1992  }
1993  }
1994 
1995  /* Simply delete mount point from DB */
1999  }
2000 
2001  return Status;
2002 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
USHORT MaximumLength
Definition: env_spec_w32.h:370
struct _MOUNTMGR_MOUNT_POINTS * PMOUNTMGR_MOUNT_POINTS
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
uint16_t * PWSTR
Definition: typedefs.h:56
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
LONG NTSTATUS
Definition: precomp.h:26
USHORT UniqueIdLength
Definition: imports.h:138
BOOLEAN IsDriveLetter(PUNICODE_STRING SymbolicName)
Definition: symlink.c:922
VOID DeleteSymbolicLinkNameFromMemory(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicLink, IN BOOLEAN MarkOffline)
Definition: symlink.c:864
#define FreePool(P)
Definition: mntmgr.h:154
static int Link(const char **args)
Definition: vfdcmd.c:2414
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define UNICODE_NULL
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID CreateNoDriveLetterEntry(IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: uniqueid.c:269
NTSTATUS MountMgrQueryPoints(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:1695
Status
Definition: gdiplustypes.h:24
NTSYSAPI NTSTATUS WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR)
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define AllocatePool(Size)
Definition: mntmgr.h:153
PWSTR DatabasePath
Definition: database.c:31
MOUNTMGR_MOUNT_POINT MountPoints[1]
Definition: imports.h:177
ULONG SymbolicLinkNameOffset
Definition: imports.h:166
unsigned int ULONG
Definition: retypes.h:1
USHORT SymbolicLinkNameLength
Definition: imports.h:167
UCHAR UniqueId[1]
Definition: imports.h:139

Referenced by MountMgrDeviceControl().

◆ MountMgrDeviceControl()

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

Definition at line 2686 of file device.c.

2688 {
2689  PIO_STACK_LOCATION Stack;
2690  NTSTATUS Status, LockStatus;
2691  PDEVICE_EXTENSION DeviceExtension;
2692 
2694  DeviceExtension = DeviceObject->DeviceExtension;
2695 
2696  KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
2697 
2698  switch (Stack->Parameters.DeviceIoControl.IoControlCode)
2699  {
2701  Status = MountMgrCreatePoint(DeviceExtension, Irp);
2702  break;
2703 
2705  Status = MountMgrDeletePoints(DeviceExtension, Irp);
2706  break;
2707 
2709  Status = MountMgrQueryPoints(DeviceExtension, Irp);
2710  break;
2711 
2713  Status = MountMgrDeletePointsDbOnly(DeviceExtension, Irp);
2714  break;
2715 
2717  Status = MountMgrNextDriveLetter(DeviceExtension, Irp);
2718  break;
2719 
2721  DeviceExtension->AutomaticDriveLetter = TRUE;
2723 
2724  MountMgrAssignDriveLetters(DeviceExtension);
2725  ReconcileAllDatabasesWithMaster(DeviceExtension);
2726  WaitForOnlinesToComplete(DeviceExtension);
2727  break;
2728 
2730  KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
2731 
2732  LockStatus = WaitForRemoteDatabaseSemaphore(DeviceExtension);
2733  KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
2734  Status = MountMgrVolumeMountPointCreated(DeviceExtension, Irp, LockStatus);
2735  if (NT_SUCCESS(LockStatus))
2736  {
2737  ReleaseRemoteDatabaseSemaphore(DeviceExtension);
2738  }
2739 
2740  break;
2741 
2743  KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
2744 
2745  LockStatus = WaitForRemoteDatabaseSemaphore(DeviceExtension);
2746  KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
2747  Status = MountMgrVolumeMountPointDeleted(DeviceExtension, Irp, LockStatus);
2748  if (NT_SUCCESS(LockStatus))
2749  {
2750  ReleaseRemoteDatabaseSemaphore(DeviceExtension);
2751  }
2752 
2753  break;
2754 
2756  Status = MountMgrChangeNotify(DeviceExtension, Irp);
2757  break;
2758 
2760  Status = MountMgrKeepLinksWhenOffline(DeviceExtension, Irp);
2761  break;
2762 
2764  Status = MountMgrCheckUnprocessedVolumes(DeviceExtension, Irp);
2765  goto Complete;
2766 
2768  KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
2769  Status = MountMgrVolumeArrivalNotification(DeviceExtension, Irp);
2770  goto Complete;
2771 
2773  Status = MountMgrQueryDosVolumePath(DeviceExtension, Irp);
2774  break;
2775 
2777  Status = MountMgrQueryDosVolumePaths(DeviceExtension, Irp);
2778  break;
2779 
2781  Status = MountMgrScrubRegistry(DeviceExtension);
2782  break;
2783 
2785  Status = MountMgrQueryAutoMount(DeviceExtension, Irp);
2786  break;
2787 
2789  Status = MountMgrSetAutoMount(DeviceExtension, Irp);
2790  break;
2791 
2794  DPRINT1("Winism! Rewrite the caller!\n");
2795  default:
2797  }
2798 
2799  KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
2800 
2801  if (Status != STATUS_PENDING)
2802  {
2803  goto Complete;
2804  }
2805 
2806  return Status;
2807 
2808 Complete:
2809  Irp->IoStatus.Status = Status;
2811 
2812  return Status;
2813 }
#define IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH
Definition: mountmgr.h:127
#define IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_DELETED
Definition: mountmgr.h:40
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define IOCTL_MOUNTMGR_VOLUME_MOUNT_POINT_CREATED
Definition: mountmgr.h:38
LONG NTSTATUS
Definition: precomp.h:26
#define IOCTL_MOUNTMGR_AUTO_DL_ASSIGNMENTS
Definition: mountmgr.h:36
#define IOCTL_MOUNTMGR_SET_AUTO_MOUNT
Definition: mountmgr.h:154
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define IOCTL_MOUNTMGR_CREATE_POINT
Definition: imports.h:118
NTSTATUS MountMgrCheckUnprocessedVolumes(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:288
NTSTATUS MountMgrQueryAutoMount(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:136
#define IOCTL_MOUNTMGR_CHECK_UNPROCESSED_VOLUMES
Definition: mountmgr.h:46
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define IOCTL_MOUNTMGR_QUERY_UNIX_DRIVE
Definition: mountmgr.h:16
#define IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION
Definition: imports.h:130
NTSTATUS MountMgrVolumeMountPointCreated(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp, IN NTSTATUS LockStatus)
Definition: device.c:2234
NTSTATUS MountMgrCreatePoint(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:249
#define IOCTL_MOUNTMGR_KEEP_LINKS_WHEN_OFFLINE
Definition: mountmgr.h:44
NTSTATUS MountMgrVolumeArrivalNotification(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:1652
#define IOCTL_MOUNTMGR_QUERY_POINTS
Definition: mountmgr.h:30
NTSTATUS MountMgrChangeNotify(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:37
#define IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATHS
Definition: mountmgr.h:129
#define FALSE
Definition: types.h:117
#define IOCTL_MOUNTMGR_NEXT_DRIVE_LETTER
Definition: mountmgr.h:34
NTSTATUS MountMgrDeletePoints(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:1840
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
NTSTATUS MountMgrVolumeMountPointDeleted(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp, IN NTSTATUS LockStatus)
Definition: device.c:2473
NTSTATUS MountMgrQueryDosVolumePaths(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:1459
#define IOCTL_MOUNTMGR_CHANGE_NOTIFY
Definition: mountmgr.h:42
NTSTATUS MountMgrKeepLinksWhenOffline(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:1608
NTSTATUS MountMgrDeletePointsDbOnly(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:1941
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
NTSTATUS MountMgrQueryPoints(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:1695
Status
Definition: gdiplustypes.h:24
#define IOCTL_MOUNTMGR_DEFINE_UNIX_DRIVE
Definition: mountmgr.h:15
#define IOCTL_MOUNTMGR_QUERY_AUTO_MOUNT
Definition: mountmgr.h:152
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1569
NTSTATUS MountMgrSetAutoMount(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:104
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
NTSTATUS MountMgrNextDriveLetter(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:648
NTSTATUS MountMgrScrubRegistry(IN PDEVICE_EXTENSION DeviceExtension)
Definition: device.c:221
VOID MountMgrAssignDriveLetters(IN PDEVICE_EXTENSION DeviceExtension)
Definition: device.c:763
#define DPRINT1
Definition: precomp.h:8
NTSTATUS WaitForRemoteDatabaseSemaphore(IN PDEVICE_EXTENSION DeviceExtension)
Definition: database.c:371
#define IOCTL_MOUNTMGR_DELETE_POINTS_DBONLY
Definition: mountmgr.h:32
#define IO_NO_INCREMENT
Definition: iotypes.h:570
#define IOCTL_MOUNTMGR_SCRUB_REGISTRY
Definition: mountmgr.h:150
NTSTATUS MountMgrQueryDosVolumePath(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp)
Definition: device.c:837
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2779
VOID ReleaseRemoteDatabaseSemaphore(IN PDEVICE_EXTENSION DeviceExtension)
Definition: database.c:391
VOID ReconcileAllDatabasesWithMaster(IN PDEVICE_EXTENSION DeviceExtension)
Definition: database.c:1659
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define IOCTL_MOUNTMGR_DELETE_POINTS
Definition: imports.h:124
VOID WaitForOnlinesToComplete(IN PDEVICE_EXTENSION DeviceExtension)
Definition: notify.c:197

◆ MountMgrKeepLinksWhenOffline()

NTSTATUS MountMgrKeepLinksWhenOffline ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 1608 of file device.c.

1610 {
1611  NTSTATUS Status;
1612  PIO_STACK_LOCATION Stack;
1615  PDEVICE_INFORMATION DeviceInformation;
1616 
1618 
1619  /* Validate input */
1620  if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_TARGET_NAME))
1621  {
1622  return STATUS_INVALID_PARAMETER;
1623  }
1624 
1625  Target = (PMOUNTMGR_TARGET_NAME)Irp->AssociatedIrp.SystemBuffer;
1626  if (Target->DeviceNameLength + sizeof(USHORT) > Stack->Parameters.DeviceIoControl.InputBufferLength)
1627  {
1628  return STATUS_INVALID_PARAMETER;
1629  }
1630 
1632  SymbolicName.MaximumLength = Target->DeviceNameLength;
1633  SymbolicName.Buffer = Target->DeviceName;
1634 
1635  /* Find the associated device */
1636  Status = FindDeviceInfo(DeviceExtension, &SymbolicName, FALSE, &DeviceInformation);
1637  if (!NT_SUCCESS(Status))
1638  {
1639  return Status;
1640  }
1641 
1642  /* Mark we want to keep links */
1643  DeviceInformation->KeepLinks = TRUE;
1644 
1645  return STATUS_SUCCESS;
1646 }
USHORT MaximumLength
Definition: env_spec_w32.h:370
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
LONG NTSTATUS
Definition: precomp.h:26
#define FALSE
Definition: types.h:117
struct _MOUNTMGR_TARGET_NAME * PMOUNTMGR_TARGET_NAME
NTSTATUS FindDeviceInfo(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName, IN BOOLEAN DeviceNameGiven, OUT PDEVICE_INFORMATION *DeviceInformation)
Definition: mountmgr.c:642
BOOLEAN KeepLinks
Definition: mntmgr.h:51
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_Must_inspect_result_ typedef _In_ ULONG _In_ BOOLEAN Target
Definition: iotypes.h:1072
Status
Definition: gdiplustypes.h:24
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
unsigned short USHORT
Definition: pedump.c:61
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2779
return STATUS_SUCCESS
Definition: btrfs.c:3014

Referenced by MountMgrDeviceControl().

◆ MountMgrNextDriveLetter()

NTSTATUS MountMgrNextDriveLetter ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 648 of file device.c.

650 {
652  PIO_STACK_LOCATION Stack;
654  PMOUNTMGR_DRIVE_LETTER_TARGET DriveLetterTarget;
655  MOUNTMGR_DRIVE_LETTER_INFORMATION DriveLetterInformation;
656 
658 
659  /* Validate input */
660  if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_DRIVE_LETTER_TARGET) ||
661  Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTMGR_DRIVE_LETTER_INFORMATION))
662  {
664  }
665 
666  DriveLetterTarget = (PMOUNTMGR_DRIVE_LETTER_TARGET)Irp->AssociatedIrp.SystemBuffer;
667  if (DriveLetterTarget->DeviceNameLength + sizeof(USHORT) > Stack->Parameters.DeviceIoControl.InputBufferLength)
668  {
670  }
671 
672  /* Call the worker */
673  DeviceName.Buffer = DriveLetterTarget->DeviceName;
674  DeviceName.Length =
675  DeviceName.MaximumLength = DriveLetterTarget->DeviceNameLength;
676 
677  Status = MountMgrNextDriveLetterWorker(DeviceExtension, &DeviceName,
678  &DriveLetterInformation);
679  if (NT_SUCCESS(Status))
680  {
681  *(PMOUNTMGR_DRIVE_LETTER_INFORMATION)Irp->AssociatedIrp.SystemBuffer =
682  DriveLetterInformation;
683  Irp->IoStatus.Information = sizeof(MOUNTMGR_DRIVE_LETTER_INFORMATION);
684  }
685 
686  return Status;
687 }
struct _MOUNTMGR_DRIVE_LETTER_INFORMATION * PMOUNTMGR_DRIVE_LETTER_INFORMATION
NTSTATUS MountMgrNextDriveLetterWorker(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName, OUT PMOUNTMGR_DRIVE_LETTER_INFORMATION DriveLetterInfo)
Definition: device.c:457
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
WCHAR DeviceName[]
Definition: adapter.cpp:21
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:24
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
unsigned short USHORT
Definition: pedump.c:61
struct _MOUNTMGR_DRIVE_LETTER_TARGET * PMOUNTMGR_DRIVE_LETTER_TARGET
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2779

Referenced by MountMgrDeviceControl().

◆ MountMgrNextDriveLetterWorker()

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

Definition at line 457 of file device.c.

460 {
462  UCHAR DriveLetter;
463  PLIST_ENTRY NextEntry;
464  PMOUNTDEV_UNIQUE_ID UniqueId;
465  BOOLEAN Removable, GptDriveLetter;
466  PDEVICE_INFORMATION DeviceInformation;
467  WCHAR NameBuffer[DRIVE_LETTER_LENGTH];
468  PSYMLINK_INFORMATION SymlinkInformation;
469  UNICODE_STRING TargetDeviceName, SymbolicName;
470 
471  /* First, process suggested letters */
472  if (!DeviceExtension->ProcessedSuggestions)
473  {
474  ProcessSuggestedDriveLetters(DeviceExtension);
475  DeviceExtension->ProcessedSuggestions = TRUE;
476  }
477 
478  /* Then, get information about the device */
479  Status = QueryDeviceInformation(DeviceName, &TargetDeviceName, NULL, &Removable, &GptDriveLetter, NULL, NULL, NULL);
480  if (!NT_SUCCESS(Status))
481  {
482  return Status;
483  }
484 
485  /* Ensure we have such device */
486  NextEntry = DeviceExtension->DeviceListHead.Flink;
487  while (NextEntry != &(DeviceExtension->DeviceListHead))
488  {
489  DeviceInformation = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
490 
491  if (RtlCompareUnicodeString(&(DeviceInformation->DeviceName), &TargetDeviceName, TRUE) == 0)
492  {
493  break;
494  }
495 
496  NextEntry = NextEntry->Flink;
497  }
498 
499  if (NextEntry == &(DeviceExtension->DeviceListHead))
500  {
501  FreePool(TargetDeviceName.Buffer);
503  }
504 
505  /* Now, mark we have assigned a letter (assumption) */
506  DeviceInformation->LetterAssigned =
507  DriveLetterInfo->DriveLetterWasAssigned = TRUE;
508 
509  /* Browse all the symlinks to check if there is already a drive letter */
510  NextEntry = DeviceInformation->SymbolicLinksListHead.Flink;
511  while (NextEntry != &(DeviceInformation->SymbolicLinksListHead))
512  {
513  SymlinkInformation = CONTAINING_RECORD(NextEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
514 
515  /* If this is a drive letter and it is online, forget about new drive letter */
516  if (IsDriveLetter(&(SymlinkInformation->Name)) && SymlinkInformation->Online)
517  {
518  DriveLetterInfo->DriveLetterWasAssigned = FALSE;
519  DriveLetterInfo->CurrentDriveLetter = (CHAR)SymlinkInformation->Name.Buffer[LETTER_POSITION];
520  break;
521  }
522 
523  NextEntry = NextEntry->Flink;
524  }
525 
526  /* If we didn't find a drive letter online
527  * ensure this is not a no drive entry
528  * by querying GPT attributes & database
529  */
530  if (NextEntry == &(DeviceInformation->SymbolicLinksListHead))
531  {
532  if (!GptDriveLetter || HasNoDriveLetterEntry(DeviceInformation->UniqueId))
533  {
534  DriveLetterInfo->DriveLetterWasAssigned = FALSE;
535  DriveLetterInfo->CurrentDriveLetter = 0;
536 
537  goto Release;
538  }
539  }
540 
541  /* No, ensure that the device is not automounted nor removable */
542  if (!DeviceExtension->NoAutoMount && !Removable)
543  {
544  if (DriveLetterInfo->DriveLetterWasAssigned)
545  {
546  DriveLetterInfo->DriveLetterWasAssigned = FALSE;
547  DriveLetterInfo->CurrentDriveLetter = 0;
548 
549  goto Release;
550  }
551  }
552 
553  if (!DriveLetterInfo->DriveLetterWasAssigned)
554  {
555  goto Release;
556  }
557 
558  /* Now everything is fine, start processing */
559 
560  if (RtlPrefixUnicodeString(&DeviceFloppy, &TargetDeviceName, TRUE))
561  {
562  /* If the device is a floppy, start with letter A */
563  DriveLetter = 'A';
564  }
565  else if (RtlPrefixUnicodeString(&DeviceCdRom, &TargetDeviceName, TRUE))
566  {
567  /* If the device is a CD-ROM, start with letter D */
568  DriveLetter = 'D';
569  }
570  else
571  {
572  /* Finally, if it's a disk, use C */
573  DriveLetter = 'C';
574  }
575 
576  /* We cannot set NO drive letter */
577  ASSERT(DeviceInformation->SuggestedDriveLetter != (UCHAR)-1);
578 
579  /* If we don't have suggested letter but it's a FT volume, fail */
580  if (!DeviceInformation->SuggestedDriveLetter && IsFtVolume(&(DeviceInformation->DeviceName)))
581  {
582  DriveLetterInfo->DriveLetterWasAssigned = FALSE;
583  DriveLetterInfo->CurrentDriveLetter = 0;
584 
585  goto Release;
586  }
587 
588  /* Prepare buffer */
590  NameBuffer[COLON_POSITION] = L':';
591  SymbolicName.Buffer = NameBuffer;
594 
595  /* It's all prepared, create mount point */
596  if (DeviceInformation->SuggestedDriveLetter)
597  {
598  DriveLetterInfo->CurrentDriveLetter = DeviceInformation->SuggestedDriveLetter;
599  NameBuffer[LETTER_POSITION] = DeviceInformation->SuggestedDriveLetter;
600 
601  Status = MountMgrCreatePointWorker(DeviceExtension, &SymbolicName, &TargetDeviceName);
602  if (NT_SUCCESS(Status))
603  {
604  goto Release;
605  }
606  }
607 
608  /* It failed with this letter... Try another one! */
609  for (DriveLetterInfo->CurrentDriveLetter = DriveLetter;
610  DriveLetterInfo->CurrentDriveLetter <= L'Z';
611  DriveLetterInfo->CurrentDriveLetter++)
612  {
613  NameBuffer[LETTER_POSITION] = DriveLetterInfo->CurrentDriveLetter;
614 
615  Status = MountMgrCreatePointWorker(DeviceExtension, &SymbolicName, &TargetDeviceName);
616  if (NT_SUCCESS(Status))
617  {
618  break;
619  }
620  }
621 
622  /* We failed setting a letter */
623  if (DriveLetterInfo->CurrentDriveLetter > L'Z')
624  {
625  DriveLetterInfo->DriveLetterWasAssigned = FALSE;
626  DriveLetterInfo->CurrentDriveLetter = 0;
627 
628  /* Try at least to add a no drive letter entry */
629  Status = QueryDeviceInformation(&TargetDeviceName, NULL, &UniqueId, NULL, NULL, NULL, NULL, NULL);
630  if (NT_SUCCESS(Status))
631  {
632  CreateNoDriveLetterEntry(UniqueId);
633  FreePool(UniqueId);
634  }
635  }
636 
637 Release:
638  FreePool(TargetDeviceName.Buffer);
639 
640  return STATUS_SUCCESS;
641 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
UNICODE_STRING DosDevices
Definition: symlink.c:33
_In_ BOOLEAN Release
Definition: classpnp.h:1122
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define TRUE
Definition: types.h:120
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
BOOLEAN LetterAssigned
Definition: mntmgr.h:55
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN IsDriveLetter(PUNICODE_STRING SymbolicName)
Definition: symlink.c:922
BOOLEAN IsFtVolume(IN PUNICODE_STRING SymbolicName)
Definition: device.c:331
#define LETTER_POSITION
Definition: mntmgr.h:159
WCHAR DeviceName[]
Definition: adapter.cpp:21
NTSTATUS MountMgrCreatePointWorker(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicLinkName, IN PUNICODE_STRING DeviceName)
Definition: point.c:35
#define FreePool(P)
Definition: mntmgr.h:154
BOOLEAN HasNoDriveLetterEntry(IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: uniqueid.c:354
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
UNICODE_STRING DeviceFloppy
Definition: symlink.c:34
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
NTSTATUS QueryDeviceInformation(IN PUNICODE_STRING SymbolicName, OUT PUNICODE_STRING DeviceName OPTIONAL, OUT PMOUNTDEV_UNIQUE_ID *UniqueId OPTIONAL, OUT PBOOLEAN Removable OPTIONAL, OUT PBOOLEAN GptDriveLetter OPTIONAL, OUT PBOOLEAN HasGuid OPTIONAL, IN OUT LPGUID StableGuid OPTIONAL, OUT PBOOLEAN Valid OPTIONAL)
Definition: mountmgr.c:195
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
LIST_ENTRY SymbolicLinksListHead
Definition: mntmgr.h:45
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
VOID CreateNoDriveLetterEntry(IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: uniqueid.c:269
Status
Definition: gdiplustypes.h:24
static const WCHAR L[]
Definition: oid.c:1250
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
Definition: typedefs.h:119
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define COLON_POSITION
Definition: mntmgr.h:160
VOID ProcessSuggestedDriveLetters(IN PDEVICE_EXTENSION DeviceExtension)
Definition: device.c:403
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
UNICODE_STRING DeviceName
Definition: mntmgr.h:50
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define CHAR(Char)
PMOUNTDEV_UNIQUE_ID UniqueId
Definition: mntmgr.h:49
#define DRIVE_LETTER_LENGTH
Definition: mntmgr.h:161
UCHAR SuggestedDriveLetter
Definition: mntmgr.h:52
Definition: arc.h:81
UNICODE_STRING DeviceCdRom
Definition: symlink.c:35

Referenced by MountMgrAssignDriveLetters(), and MountMgrNextDriveLetter().

◆ MountMgrQueryAutoMount()

NTSTATUS MountMgrQueryAutoMount ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 136 of file device.c.

138 {
139  PIO_STACK_LOCATION Stack;
140  PMOUNTMGR_QUERY_AUTO_MOUNT QueryState;
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 }
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
struct _MOUNTMGR_QUERY_AUTO_MOUNT * PMOUNTMGR_QUERY_AUTO_MOUNT
MOUNTMGR_AUTO_MOUNT_STATE CurrentState
Definition: mountmgr.h:163
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2779
return STATUS_SUCCESS
Definition: btrfs.c:3014

Referenced by MountMgrDeviceControl().

◆ MountMgrQueryDosVolumePath()

NTSTATUS MountMgrQueryDosVolumePath ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 837 of file device.c.

839 {
841  ULONG DevicesFound;
842  PIO_STACK_LOCATION Stack;
843  PLIST_ENTRY SymlinksEntry;
846  PWSTR DeviceString, OldBuffer;
847  USHORT DeviceLength, OldLength;
848  PDEVICE_INFORMATION DeviceInformation;
849  PSYMLINK_INFORMATION SymlinkInformation;
850  PASSOCIATED_DEVICE_ENTRY AssociatedDevice;
851 
853 
854  /* Validate input size */
855  if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_TARGET_NAME))
856  {
858  }
859 
860  /* Ensure we have received UNICODE_STRING */
861  Target = (PMOUNTMGR_TARGET_NAME)Irp->AssociatedIrp.SystemBuffer;
862  if (Target->DeviceNameLength & 1)
863  {
865  }
866 
867  /* Validate the entry structure size */
868  if (Target->DeviceNameLength + sizeof(UNICODE_NULL) > Stack->Parameters.DeviceIoControl.InputBufferLength)
869  {
871  }
872 
873  /* Ensure we can at least return needed size */
874  if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
875  {
877  }
878 
879  /* Construct string for query */
880  SymbolicName.Length = Target->DeviceNameLength;
881  SymbolicName.MaximumLength = Target->DeviceNameLength + sizeof(UNICODE_NULL);
882  SymbolicName.Buffer = Target->DeviceName;
883 
884  /* Find device with our info */
885  Status = FindDeviceInfo(DeviceExtension, &SymbolicName, FALSE, &DeviceInformation);
886  if (!NT_SUCCESS(Status))
887  {
888  return Status;
889  }
890 
891  DeviceLength = 0;
892  DeviceString = NULL;
893  DevicesFound = 0;
894 
895  /* Try to find associated device info */
896  while (TRUE)
897  {
898  for (SymlinksEntry = DeviceInformation->SymbolicLinksListHead.Flink;
899  SymlinksEntry != &(DeviceInformation->SymbolicLinksListHead);
900  SymlinksEntry = SymlinksEntry->Flink)
901  {
902  SymlinkInformation = CONTAINING_RECORD(SymlinksEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
903 
904  /* Try to find with drive letter */
905  if (MOUNTMGR_IS_DRIVE_LETTER(&SymlinkInformation->Name) && SymlinkInformation->Online)
906  {
907  break;
908  }
909  }
910 
911  /* We didn't find, break */
912  if (SymlinksEntry == &(DeviceInformation->SymbolicLinksListHead))
913  {
914  break;
915  }
916 
917  /* It doesn't have associated device, go to fallback method */
918  if (IsListEmpty(&DeviceInformation->AssociatedDevicesHead))
919  {
920  goto TryWithVolumeName;
921  }
922 
923  /* Create a string with the information about the device */
924  AssociatedDevice = CONTAINING_RECORD(&(DeviceInformation->SymbolicLinksListHead), ASSOCIATED_DEVICE_ENTRY, AssociatedDevicesEntry);
925  OldLength = DeviceLength;
926  OldBuffer = DeviceString;
927  DeviceLength += AssociatedDevice->String.Length;
928  DeviceString = AllocatePool(DeviceLength);
929  if (!DeviceString)
930  {
931  if (OldBuffer)
932  {
933  FreePool(OldBuffer);
934  }
935 
937  }
938 
939  /* Store our info and previous if any */
940  RtlCopyMemory(DeviceString, AssociatedDevice->String.Buffer, AssociatedDevice->String.Length);
941  if (OldBuffer)
942  {
943  RtlCopyMemory(&DeviceString[AssociatedDevice->String.Length / sizeof(WCHAR)], OldBuffer, OldLength);
944  FreePool(OldBuffer);
945  }
946 
947  /* Count and continue looking */
948  ++DevicesFound;
949  DeviceInformation = AssociatedDevice->DeviceInformation;
950 
951  /* If too many devices, try another way */
952  if (DevicesFound > MAX_DEVICES) /* 1000 */
953  {
954  goto TryWithVolumeName;
955  }
956  }
957 
958  /* Reallocate our string, so that we can prepend disk letter */
959  OldBuffer = DeviceString;
960  OldLength = DeviceLength;
961  DeviceLength += 2 * sizeof(WCHAR);
962  DeviceString = AllocatePool(DeviceLength);
963  if (!DeviceString)
964  {
965  if (OldBuffer)
966  {
967  FreePool(OldBuffer);
968  }
969 
971  }
972 
973  /* Get the letter */
974  DeviceString[0] = SymlinkInformation->Name.Buffer[LETTER_POSITION];
975  DeviceString[1] = L':';
976 
977  /* And copy the rest */
978  if (OldBuffer)
979  {
980  RtlCopyMemory(&DeviceString[2], OldBuffer, OldLength);
981  FreePool(OldBuffer);
982  }
983 
984 TryWithVolumeName:
985  /* If we didn't find anything, try differently */
986  if (DeviceLength < 2 * sizeof(WCHAR) || DeviceString[1] != L':')
987  {
988  if (DeviceString)
989  {
990  FreePool(DeviceString);
991  DeviceLength = 0;
992  }
993 
994  /* Try to find a volume name matching */
995  for (SymlinksEntry = DeviceInformation->SymbolicLinksListHead.Flink;
996  SymlinksEntry != &(DeviceInformation->SymbolicLinksListHead);
997  SymlinksEntry = SymlinksEntry->Flink)
998  {
999  SymlinkInformation = CONTAINING_RECORD(SymlinksEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
1000 
1001  if (MOUNTMGR_IS_VOLUME_NAME(&SymlinkInformation->Name))
1002  {
1003  break;
1004  }
1005  }
1006 
1007  /* If found copy */
1008  if (SymlinksEntry != &(DeviceInformation->SymbolicLinksListHead))
1009  {
1010  DeviceLength = SymlinkInformation->Name.Length;
1011  DeviceString = AllocatePool(DeviceLength);
1012  if (!DeviceString)
1013  {
1015  }
1016 
1017  RtlCopyMemory(DeviceString, SymlinkInformation->Name.Buffer, DeviceLength);
1018  /* Ensure we are in the right namespace; [1] can be ? */
1019  DeviceString[1] = L'\\';
1020  }
1021  }
1022 
1023  /* If we found something */
1024  if (DeviceString)
1025  {
1026  /* At least, we will return our length */
1027  ((PMOUNTMGR_VOLUME_PATHS)Irp->AssociatedIrp.SystemBuffer)->MultiSzLength = DeviceLength;
1028  /* MOUNTMGR_VOLUME_PATHS is a string + a ULONG */
1029  Irp->IoStatus.Information = DeviceLength + sizeof(ULONG);
1030 
1031  /* If we have enough room for copying the string */
1032  if (sizeof(ULONG) + DeviceLength <= Stack->Parameters.DeviceIoControl.OutputBufferLength)
1033  {
1034  /* Copy it */
1035  if (DeviceLength)
1036  {
1037  RtlCopyMemory(((PMOUNTMGR_VOLUME_PATHS)Irp->AssociatedIrp.SystemBuffer)->MultiSz, DeviceString, DeviceLength);
1038  }
1039 
1040  /* And double zero at its end - this is needed in case of multiple paths which are separated by a single 0 */
1041  FreePool(DeviceString);
1042  ((PMOUNTMGR_VOLUME_PATHS)Irp->AssociatedIrp.SystemBuffer)->MultiSz[DeviceLength / sizeof(WCHAR)] = 0;
1043  ((PMOUNTMGR_VOLUME_PATHS)Irp->AssociatedIrp.SystemBuffer)->MultiSz[DeviceLength / sizeof(WCHAR) + 1] = 0;
1044 
1045  return STATUS_SUCCESS;
1046  }
1047  else
1048  {
1049  /* Just return appropriate size and leave */
1050  FreePool(DeviceString);
1051  Irp->IoStatus.Information = sizeof(ULONG);
1052  return STATUS_BUFFER_OVERFLOW;
1053  }
1054  }
1055 
1056  /* Fail */
1057  return STATUS_NOT_FOUND;
1058 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
USHORT MaximumLength
Definition: env_spec_w32.h:370
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
uint16_t * PWSTR
Definition: typedefs.h:56
#define MAX_DEVICES
Definition: device.c:28
PDEVICE_INFORMATION DeviceInformation
Definition: mntmgr.h:98
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
LONG NTSTATUS
Definition: precomp.h:26
#define LETTER_POSITION
Definition: mntmgr.h:159
#define FreePool(P)
Definition: mntmgr.h:154
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
#define MOUNTMGR_IS_VOLUME_NAME(s)
Definition: mountmgr.h:61
struct _MOUNTMGR_TARGET_NAME * PMOUNTMGR_TARGET_NAME
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS FindDeviceInfo(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName, IN BOOLEAN DeviceNameGiven, OUT PDEVICE_INFORMATION *DeviceInformation)
Definition: mountmgr.c:642
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define STATUS_NOT_FOUND
Definition: shellext.h:72
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Definition: mntmgr.h:95
LIST_ENTRY SymbolicLinksListHead
Definition: mntmgr.h:45
struct _MOUNTMGR_VOLUME_PATHS * PMOUNTMGR_VOLUME_PATHS
_Must_inspect_result_ typedef _In_ ULONG _In_ BOOLEAN Target
Definition: iotypes.h:1072
#define MOUNTMGR_IS_DRIVE_LETTER(s)
Definition: mountmgr.h:53
Status
Definition: gdiplustypes.h:24
static const WCHAR L[]
Definition: oid.c:1250
Definition: typedefs.h:119
UNICODE_STRING String
Definition: mntmgr.h:99
#define AllocatePool(Size)
Definition: mntmgr.h:153
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
unsigned short USHORT
Definition: pedump.c:61
unsigned int ULONG
Definition: retypes.h:1
LIST_ENTRY AssociatedDevicesHead
Definition: mntmgr.h:47
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2779
return STATUS_SUCCESS
Definition: btrfs.c:3014

Referenced by MountMgrDeviceControl().

◆ MountMgrQueryDosVolumePaths()

NTSTATUS MountMgrQueryDosVolumePaths ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 1459 of file device.c.

1461 {
1462  NTSTATUS Status;
1464  LIST_ENTRY Devices;
1465  BOOLEAN NeedNotification;
1466  PIO_STACK_LOCATION Stack;
1468  ULONG Attempts, OutputLength;
1471  RECONCILE_WORK_ITEM_CONTEXT ReconcileContext;
1472  PDEVICE_INFORMATION DeviceInformation, ListDeviceInfo, FailedDevice;
1473 
1475 
1476  /* Validate input size */
1477  if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_TARGET_NAME))
1478  {
1479  return STATUS_INVALID_PARAMETER;
1480  }
1481 
1482  /* Ensure we have received UNICODE_STRING */
1483  Target = (PMOUNTMGR_TARGET_NAME)Irp->AssociatedIrp.SystemBuffer;
1484  if (Target->DeviceNameLength & 1)
1485  {
1486  return STATUS_INVALID_PARAMETER;
1487  }
1488 
1489  /* Validate the entry structure size */
1490  if (Target->DeviceNameLength + FIELD_OFFSET(MOUNTMGR_TARGET_NAME, DeviceName) > Stack->Parameters.DeviceIoControl.InputBufferLength)
1491  {
1492  return STATUS_INVALID_PARAMETER;
1493  }
1494 
1495  /* Ensure we can at least return needed size */
1496  if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG))
1497  {
1498  return STATUS_INVALID_PARAMETER;
1499  }
1500 
1501  /* Construct string for query */
1502  SymbolicName.Length = Target->DeviceNameLength;
1503  SymbolicName.MaximumLength = Target->DeviceNameLength + sizeof(UNICODE_NULL);
1504  SymbolicName.Buffer = Target->DeviceName;
1505 
1506  /* Find device with our info */
1507  Status = FindDeviceInfo(DeviceExtension, &SymbolicName, FALSE, &DeviceInformation);
1508  if (!NT_SUCCESS(Status))
1509  {
1510  return Status;
1511  }
1512 
1513  NeedNotification = FALSE;
1514  Attempts = 0;
1515  for (;;)
1516  {
1517  FailedDevice = NULL;
1518  InitializeListHead(&Devices);
1519 
1520  /* Query paths */
1521  Status = MountMgrQueryVolumePaths(DeviceExtension, DeviceInformation, &Devices, &Paths, &FailedDevice);
1522  if (NT_SUCCESS(Status))
1523  {
1524  break;
1525  }
1526 
1527  /* If it failed for generic reason (memory, whatever), bail out (ie, FailedDevice not set) */
1528  if (FailedDevice == NULL)
1529  {
1530  return Status;
1531  }
1532 
1533  /* If PnP, let's notify in case of success */
1534  if (!DeviceInformation->ManuallyRegistered)
1535  {
1536  NeedNotification = TRUE;
1537  }
1538 
1539  /* Reconcile database */
1540  ReconcileContext.DeviceExtension = DeviceExtension;
1541  ReconcileContext.DeviceInformation = FailedDevice;
1542  KeReleaseSemaphore(&DeviceExtension->DeviceLock, IO_NO_INCREMENT, 1, FALSE);
1543  ReconcileThisDatabaseWithMasterWorker(&ReconcileContext);
1544  KeWaitForSingleObject(&DeviceExtension->DeviceLock, Executive, KernelMode, FALSE, NULL);
1545 
1546  /* Look for our device, to check it's online */
1547  for (Entry = DeviceExtension->DeviceListHead.Flink;
1548  Entry != &DeviceExtension->DeviceListHead;
1549  Entry = Entry->Flink)
1550  {
1551  ListDeviceInfo = CONTAINING_RECORD(Entry, DEVICE_INFORMATION, DeviceListEntry);
1552  /* It's online, it's OK! */
1553  if (ListDeviceInfo == DeviceInformation)
1554  {
1555  break;
1556  }
1557  }
1558 
1559  /* It's not online, it's not good */
1560  if (Entry == &DeviceExtension->DeviceListHead)
1561  {
1563  }
1564 
1565  /* Increase attempts count */
1566  ++Attempts;
1567  /* Don't look forever and fail if we get out of attempts */
1568  if (Attempts >= 1000)
1569  {
1570  return Status;
1571  }
1572  }
1573 
1574  /* We need to notify? Go ahead */
1575  if (NeedNotification)
1576  {
1577  MountMgrNotifyNameChange(DeviceExtension, &SymbolicName, FALSE);
1578  }
1579 
1580  /* Get output buffer */
1581  Output = (PMOUNTMGR_VOLUME_PATHS)Irp->AssociatedIrp.SystemBuffer;
1582 
1583  /* Set required size */
1584  Output->MultiSzLength = Paths->MultiSzLength;
1585 
1586  /* Compute total length */
1587  OutputLength = Output->MultiSzLength + sizeof(ULONG);
1588 
1589  /* If it cannot fit, just return need size and quit */
1590  if (OutputLength > Stack->Parameters.DeviceIoControl.OutputBufferLength)
1591  {
1592  Irp->IoStatus.Information = sizeof(ULONG);
1593  FreePool(Paths);
1594  return STATUS_BUFFER_OVERFLOW;
1595  }
1596 
1597  /* Copy data and quit */
1598  Irp->IoStatus.Information = OutputLength;
1599  RtlCopyMemory(Output->MultiSz, Paths->MultiSz, Output->MultiSzLength);
1600  FreePool(Paths);
1601  return STATUS_SUCCESS;
1602 }
VOID NTAPI ReconcileThisDatabaseWithMasterWorker(IN PVOID Parameter)
Definition: database.c:560
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
struct _Entry Entry
Definition: kefuncs.h:627
USHORT MaximumLength
Definition: env_spec_w32.h:370
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
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:1169
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
LONG NTSTATUS
Definition: precomp.h:26
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define FreePool(P)
Definition: mntmgr.h:154
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
struct _MOUNTMGR_TARGET_NAME * PMOUNTMGR_TARGET_NAME
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS FindDeviceInfo(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName, IN BOOLEAN DeviceNameGiven, OUT PDEVICE_INFORMATION *DeviceInformation)
Definition: mountmgr.c:642
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
PDEVICE_INFORMATION DeviceInformation
Definition: mntmgr.h:118
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _MOUNTMGR_VOLUME_PATHS * PMOUNTMGR_VOLUME_PATHS
_Must_inspect_result_ typedef _In_ ULONG _In_ BOOLEAN Target
Definition: iotypes.h:1072
Status
Definition: gdiplustypes.h:24
Definition: arc.h:85
Definition: typedefs.h:119
BOOLEAN ManuallyRegistered
Definition: mntmgr.h:53
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:570
PDEVICE_EXTENSION DeviceExtension
Definition: mntmgr.h:117
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2779
return STATUS_SUCCESS
Definition: btrfs.c:3014
base of all file and directory entries
Definition: entries.h:82
VOID MountMgrNotifyNameChange(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName, IN BOOLEAN ValidateVolume)
Definition: notify.c:353

Referenced by MountMgrDeviceControl().

◆ MountMgrQueryPoints()

NTSTATUS MountMgrQueryPoints ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 1695 of file device.c.

1697 {
1698  NTSTATUS Status;
1699  PIO_STACK_LOCATION Stack;
1700  PMOUNTDEV_UNIQUE_ID UniqueId;
1701  PMOUNTMGR_MOUNT_POINT MountPoint;
1703 
1705 
1706  /* Validate input... */
1707  if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_MOUNT_POINT))
1708  {
1709  return STATUS_INVALID_PARAMETER;
1710  }
1711 
1712  MountPoint = (PMOUNTMGR_MOUNT_POINT)Irp->AssociatedIrp.SystemBuffer;
1713  if (!MountPoint->SymbolicLinkNameLength)
1714  {
1715  MountPoint->SymbolicLinkNameOffset = 0;
1716  }
1717 
1718  if (!MountPoint->UniqueIdLength)
1719  {
1720  MountPoint->UniqueIdOffset = 0;
1721  }
1722 
1723  if (!MountPoint->DeviceNameLength)
1724  {
1725  MountPoint->DeviceNameOffset = 0;
1726  }
1727 
1728  /* Addresses can't be odd */
1729  if ((MountPoint->SymbolicLinkNameOffset & 1) ||
1730  (MountPoint->SymbolicLinkNameLength & 1))
1731  {
1732  return STATUS_INVALID_PARAMETER;
1733  }
1734 
1735  if ((MountPoint->UniqueIdOffset & 1) ||
1736  (MountPoint->UniqueIdLength & 1))
1737  {
1738  return STATUS_INVALID_PARAMETER;
1739  }
1740 
1741  if ((MountPoint->DeviceNameOffset & 1) ||
1742  (MountPoint->DeviceNameLength & 1))
1743  {
1744  return STATUS_INVALID_PARAMETER;
1745  }
1746 
1747  /* We can't go beyond */
1748  if (((ULONG)MountPoint->SymbolicLinkNameLength + MountPoint->UniqueIdLength +
1749  MountPoint->DeviceNameLength) > Stack->Parameters.DeviceIoControl.InputBufferLength)
1750  {
1751  return STATUS_INVALID_PARAMETER;
1752  }
1753 
1754  if (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTMGR_MOUNT_POINTS))
1755  {
1756  return STATUS_INVALID_PARAMETER;
1757  }
1758 
1759  /* If caller provided a Symlink, use it */
1760  if (MountPoint->SymbolicLinkNameLength != 0)
1761  {
1762  if (MountPoint->SymbolicLinkNameLength > MAXSHORT)
1763  {
1764  return STATUS_INVALID_PARAMETER;
1765  }
1766 
1768  SymbolicName.MaximumLength = MountPoint->SymbolicLinkNameLength + sizeof(WCHAR);
1770  if (!SymbolicName.Buffer)
1771  {
1773  }
1774 
1776  (PWSTR)((ULONG_PTR)MountPoint + MountPoint->SymbolicLinkNameOffset),
1779 
1780  /* Query links using it */
1783  }
1784  /* If user provided an unique ID */
1785  else if (MountPoint->UniqueIdLength != 0)
1786  {
1787  UniqueId = AllocatePool(MountPoint->UniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
1788  if (!UniqueId)
1789  {
1791  }
1792 
1793  UniqueId->UniqueIdLength = MountPoint->UniqueIdLength;
1794  RtlCopyMemory(UniqueId->UniqueId,
1795  (PVOID)((ULONG_PTR)MountPoint + MountPoint->UniqueIdOffset),
1796  MountPoint->UniqueIdLength);
1797 
1798  /* Query links using it */
1799  Status = QueryPointsFromMemory(DeviceExtension, Irp, UniqueId, NULL);
1800  FreePool(UniqueId);
1801  }
1802  /* If caller provided a device name */
1803  else if (MountPoint->DeviceNameLength != 0)
1804  {
1805  if (MountPoint->DeviceNameLength > MAXSHORT)
1806  {
1807  return STATUS_INVALID_PARAMETER;
1808  }
1809 
1810  DeviceName.Length = MountPoint->DeviceNameLength;
1811  DeviceName.MaximumLength = MountPoint->DeviceNameLength + sizeof(WCHAR);
1812  DeviceName.Buffer = AllocatePool(DeviceName.MaximumLength);
1813  if (!DeviceName.Buffer)
1814  {
1816  }
1817 
1818  RtlCopyMemory(DeviceName.Buffer,
1819  (PWSTR)((ULONG_PTR)MountPoint + MountPoint->DeviceNameOffset),
1820  DeviceName.Length);
1821  DeviceName.Buffer[DeviceName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1822 
1823  /* Query links using it */
1824  Status = QueryPointsFromMemory(DeviceExtension, Irp, NULL, &DeviceName);
1825  FreePool(DeviceName.Buffer);
1826  }
1827  else
1828  {
1829  /* Otherwise, query all links */
1830  Status = QueryPointsFromMemory(DeviceExtension, Irp, NULL, NULL);
1831  }
1832 
1833  return Status;
1834 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
USHORT MaximumLength
Definition: env_spec_w32.h:370
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
uint16_t * PWSTR
Definition: typedefs.h:56
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
LONG NTSTATUS
Definition: precomp.h:26
USHORT UniqueIdLength
Definition: imports.h:138
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define FreePool(P)
Definition: mntmgr.h:154
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define UNICODE_NULL
smooth NULL
Definition: ftsmooth.c:416
USHORT DeviceNameLength
Definition: imports.h:171
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
struct _MOUNTMGR_MOUNT_POINT * PMOUNTMGR_MOUNT_POINT
NTSTATUS QueryPointsFromSymbolicLinkName(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName, IN PIRP Irp)
Definition: point.c:463
Status
Definition: gdiplustypes.h:24
#define AllocatePool(Size)
Definition: mntmgr.h:153
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define MAXSHORT
Definition: umtypes.h:114
ULONG SymbolicLinkNameOffset
Definition: imports.h:166
unsigned int ULONG
Definition: retypes.h:1
USHORT SymbolicLinkNameLength
Definition: imports.h:167
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2779
UCHAR UniqueId[1]
Definition: imports.h:139
NTSTATUS QueryPointsFromMemory(IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp, IN PMOUNTDEV_UNIQUE_ID UniqueId OPTIONAL, IN PUNICODE_STRING SymbolicName OPTIONAL)
Definition: point.c:236

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

◆ MountMgrQuerySystemVolumeName()

NTSTATUS MountMgrQuerySystemVolumeName ( OUT PUNICODE_STRING  SystemVolumeName)

Definition at line 734 of file device.c.

735 {
737 
741  QueryTable[0].Name = L"SystemPartition";
742 
743  SystemVolumeName->Buffer = NULL;
744 
746  L"\\Registry\\Machine\\System\\Setup",
747  QueryTable,
748  SystemVolumeName,
749  NULL);
750 
751  if (SystemVolumeName->Buffer)
752  {
753  return STATUS_SUCCESS;
754  }
755 
756  return STATUS_UNSUCCESSFUL;
757 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4142
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI MountMgrQuerySystemVolumeNameQueryRoutine(IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
Definition: device.c:694
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
static const WCHAR L[]
Definition: oid.c:1250
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define RTL_QUERY_REGISTRY_REQUIRED
Definition: nt_native.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 694 of file device.c.

700 {
701  UNICODE_STRING ValueString;
702  PUNICODE_STRING SystemVolumeName;
703 
707 
708  if (ValueType != REG_SZ)
709  {
710  return STATUS_SUCCESS;
711  }
712 
713  RtlInitUnicodeString(&ValueString, ValueData);
714  SystemVolumeName = Context;
715 
716  /* Return a string containing system volume name */
717  SystemVolumeName->Length = ValueString.Length;
718  SystemVolumeName->MaximumLength = ValueString.Length + sizeof(WCHAR);
719  SystemVolumeName->Buffer = AllocatePool(SystemVolumeName->MaximumLength);
720  if (SystemVolumeName->Buffer)
721  {
722  RtlCopyMemory(SystemVolumeName->Buffer, ValueData, ValueString.Length);
723  SystemVolumeName->Buffer[ValueString.Length / sizeof(WCHAR)] = UNICODE_NULL;
724  }
725 
726  return STATUS_SUCCESS;
727 
728 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
_In_ PCWSTR _In_z_ PCWSTR _In_ ULONG ValueType
Definition: rtlfuncs.h:4154
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
#define UNICODE_NULL
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4142
__wchar_t WCHAR
Definition: xmlstorage.h:180
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:311
_In_ GUID _In_ PVOID _In_ ULONG ValueLength
Definition: hubbusif.h:311
#define AllocatePool(Size)
Definition: mntmgr.h:153
struct tagContext Context
Definition: acpixf.h:1034
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define REG_SZ
Definition: layer.c:22

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 1169 of file device.c.

1174 {
1175  ULONG Written;
1176  NTSTATUS Status;
1178  PSYMLINK_INFORMATION SymlinkInformation;
1179  PDEVICE_INFORMATION_ENTRY DeviceInfoEntry;
1180  PASSOCIATED_DEVICE_ENTRY AssociatedDeviceEntry;
1181  PMOUNTMGR_VOLUME_PATHS * Paths = NULL, * CurrentPath;
1182  ULONG OutputPathLength, NumberOfPaths, ReturnedPaths;
1183 
1184  /* We return at least null char */
1185  OutputPathLength = sizeof(UNICODE_NULL);
1186 
1187  for (Entry = DeviceInformation->SymbolicLinksListHead.Flink;
1188  Entry != &(DeviceInformation->SymbolicLinksListHead);
1189  Entry = Entry->Flink)
1190  {
1191  SymlinkInformation = CONTAINING_RECORD(Entry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
1192 
1193  /* Try to find the drive letter (ie, DOS device) */
1194  if (MOUNTMGR_IS_DRIVE_LETTER(&SymlinkInformation->Name) && SymlinkInformation->Online)
1195  {
1196  /* We'll return the letter */
1197  OutputPathLength = 4 * sizeof(WCHAR);
1198  break;
1199  }
1200  }
1201 
1202  /* We didn't find any */
1203  if (Entry == &(DeviceInformation->SymbolicLinksListHead))
1204  {
1205  SymlinkInformation = NULL;
1206  }
1207 
1208  /* Do we have any device info to return? */
1209  for (Entry = DeviceInfoList->Flink; Entry != DeviceInfoList; Entry = Entry->Flink)
1210  {
1211  DeviceInfoEntry = CONTAINING_RECORD(Entry, DEVICE_INFORMATION_ENTRY, DeviceInformationEntry);
1212 
1213  /* Matching current device */
1214  if (DeviceInfoEntry->DeviceInformation == DeviceInformation)
1215  {
1216  /* Allocate the output buffer */
1217  *VolumePaths = AllocatePool(sizeof(ULONG) + OutputPathLength);
1218  if (*VolumePaths == NULL)
1219  {
1221  }
1222 
1223  /* Set size */
1224  (*VolumePaths)->MultiSzLength = OutputPathLength;
1225  /* If we have a drive letter, return it */
1226  if (SymlinkInformation != NULL)
1227  {
1228  (*VolumePaths)->MultiSz[0] = SymlinkInformation->Name.Buffer[LETTER_POSITION];
1229  (*VolumePaths)->MultiSz[1] = L':';
1230  (*VolumePaths)->MultiSz[2] = UNICODE_NULL;
1231  (*VolumePaths)->MultiSz[3] = UNICODE_NULL;
1232  }
1233  else
1234  {
1235  (*VolumePaths)->MultiSz[0] = UNICODE_NULL;
1236  }
1237 
1238  return STATUS_SUCCESS;
1239  }
1240  }
1241 
1242  /* Allocate a new device entry */
1243  DeviceInfoEntry = AllocatePool(sizeof(DEVICE_INFORMATION_ENTRY));
1244  if (DeviceInfoEntry == NULL)
1245  {
1247  }
1248 
1249  /* Add it to the list */
1250  DeviceInfoEntry->DeviceInformation = DeviceInformation;
1251  InsertTailList(DeviceInfoList, &DeviceInfoEntry->DeviceInformationEntry);
1252 
1253  NumberOfPaths = 0;
1254  /* Count the amount of devices we will have to handle */
1255  if (!IsListEmpty(&DeviceInformation->AssociatedDevicesHead))
1256  {
1257  for (Entry = DeviceInformation->AssociatedDevicesHead.Flink;
1258  Entry != &DeviceInformation->AssociatedDevicesHead;
1259  Entry = Entry->Flink)
1260  {
1261  ++NumberOfPaths;
1262  }
1263 
1264  ASSERT(NumberOfPaths != 0);
1265  /* And allocate a big enough buffer */
1266  Paths = AllocatePool(NumberOfPaths * sizeof(PMOUNTMGR_VOLUME_PATHS));
1267  if (Paths == NULL)
1268  {
1269  RemoveEntryList(&DeviceInfoEntry->DeviceInformationEntry);
1270  FreePool(DeviceInfoEntry);
1272  }
1273  }
1274 
1275  /* Start the hot loop to gather all the paths and be able to compute total output length! */
1276  ReturnedPaths = 0;
1277  CurrentPath = Paths;
1278  for (Entry = DeviceInformation->AssociatedDevicesHead.Flink;
1279  Entry != &DeviceInformation->AssociatedDevicesHead;
1280  Entry = Entry->Flink)
1281  {
1282  USHORT InnerStrings;
1283  BOOLEAN Invalid = FALSE;
1284 
1285  AssociatedDeviceEntry = CONTAINING_RECORD(Entry, ASSOCIATED_DEVICE_ENTRY, AssociatedDevicesEntry);
1286 
1287  /* Validate the fact its a mount point by query reparse data */
1288  Status = MountMgrValidateBackPointer(AssociatedDeviceEntry, DeviceInformation, &Invalid);
1289 
1290  /* If we found an invalid device, that's a failure */
1291  if (Invalid)
1292  {
1293  *FailedDevice = AssociatedDeviceEntry->DeviceInformation;
1295  }
1296 
1297  /* Check whether we failed, if so, bail out */
1298  if (!NT_SUCCESS(Status))
1299  {
1300  ULONG i;
1301 
1302  for (i = 0; i < ReturnedPaths; ++i)
1303  {
1304  FreePool(Paths[i]);
1305  }
1306 
1307  if (Paths != NULL)
1308  {
1309  FreePool(Paths);
1310  }
1311  RemoveEntryList(&DeviceInfoEntry->DeviceInformationEntry);
1312  FreePool(DeviceInfoEntry);
1313  return Status;
1314  }
1315 
1316  /* Query associated paths (hello ourselves :-)) */
1317  Status = MountMgrQueryVolumePaths(DeviceExtension,
1318  AssociatedDeviceEntry->DeviceInformation,
1319  DeviceInfoList,
1320  CurrentPath,
1321  FailedDevice);
1322  if (!NT_SUCCESS(Status))
1323  {
1324  ULONG i;
1325 
1326  for (i = 0; i < ReturnedPaths; ++i)
1327  {
1328  FreePool(Paths[i]);
1329  }
1330 
1331  if (Paths != NULL)
1332  {
1333  FreePool(Paths);
1334  }
1335  RemoveEntryList(&DeviceInfoEntry->DeviceInformationEntry);
1336  FreePool(DeviceInfoEntry);
1337  return Status;
1338  }
1339 
1340  /* Count the number of strings we have in the multi string buffer */
1341  InnerStrings = 0;
1342  if ((*CurrentPath)->MultiSzLength != sizeof(UNICODE_NULL))
1343  {
1344  ULONG i;
1345  PWSTR MultiSz = (*CurrentPath)->MultiSz;
1346 
1347  for (i = 0; i < (*CurrentPath)->MultiSzLength / sizeof(WCHAR); ++i, ++MultiSz)
1348  {
1349  if (*MultiSz == UNICODE_NULL)
1350  {
1351  ++InnerStrings;
1352  }
1353  }
1354  }
1355 
1356  /* We returned one more path (ie, one more allocated buffer) */
1357  ++ReturnedPaths;
1358  /* Move the next pointer to use in the array */
1359  ++CurrentPath;
1360  /* Multiply String.Length by the number of found paths, we always add it after a path */
1361  OutputPathLength += (*CurrentPath)->MultiSzLength + InnerStrings * AssociatedDeviceEntry->String.Length - sizeof(UNICODE_NULL);
1362  }
1363 
1364  /* Allocate the output buffer */
1365  *VolumePaths = AllocatePool(sizeof(ULONG) + OutputPathLength);
1366  if (*VolumePaths == NULL)
1367  {
1368  ULONG i;
1369 
1370  for (i = 0; i < ReturnedPaths; ++i)
1371  {
1372  FreePool(Paths[i]);
1373  }
1374 
1375  if (Paths != NULL)
1376  {
1377  FreePool(Paths);
1378  }
1379  RemoveEntryList(&DeviceInfoEntry->DeviceInformationEntry);
1380  FreePool(DeviceInfoEntry);
1382  }
1383 
1384  Written = 0;
1385  /* If we had found a DOS letter, that's the first thing we return */
1386  (*VolumePaths)->MultiSzLength = OutputPathLength;
1387  if (SymlinkInformation != NULL)
1388  {
1389  (*VolumePaths)->MultiSz[0] = SymlinkInformation->Name.Buffer[LETTER_POSITION];
1390  (*VolumePaths)->MultiSz[1] = L':';
1391  (*VolumePaths)->MultiSz[2] = UNICODE_NULL;
1392  Written = 3;
1393  }
1394 
1395  /* Now, browse again all our paths to return them */
1396  CurrentPath = Paths;
1397  for (Entry = DeviceInformation->AssociatedDevicesHead.Flink;
1398  Entry != &DeviceInformation->AssociatedDevicesHead;
1399  Entry = Entry->Flink)
1400  {
1401  AssociatedDeviceEntry = CONTAINING_RECORD(Entry, ASSOCIATED_DEVICE_ENTRY, AssociatedDevicesEntry);
1402 
1403  /* If we had a path... */
1404  if ((*CurrentPath)->MultiSzLength != sizeof(UNICODE_NULL))
1405  {
1406  ULONG i, Offset;
1407  PWSTR MultiSz;
1408 
1409  /* This offset is used to "jump" into MultiSz, so, start with the string begin (ie, skip MultiSzLength) */
1410  Offset = sizeof(ULONG);
1411  /* Browse every single letter, and skip last UNICODE_NULL */
1412  for (i = 0; i < (*CurrentPath)->MultiSzLength / sizeof(WCHAR) - 1; ++i)
1413  {
1414  /* Get the letter */
1415  MultiSz = (PWSTR)((ULONG_PTR)(*CurrentPath) + Offset);
1416  /* If it was part of the path, just return it */
1417  if (*MultiSz != UNICODE_NULL)
1418  {
1419  (*VolumePaths)->MultiSz[Written] = *MultiSz;
1420  }
1421  else
1422  {
1423  /* Otherwise, as planed, return our whole associated device name */
1424  RtlCopyMemory(&(*VolumePaths)->MultiSz[Written],
1425  AssociatedDeviceEntry->String.Buffer,
1426  AssociatedDeviceEntry->String.Length);
1427  Written += AssociatedDeviceEntry->String.Length / sizeof(WCHAR);
1428  /* And don't forget to nullify */
1429  (*VolumePaths)->MultiSz[Written] = UNICODE_NULL;
1430  }
1431 
1432  /* We at least return a letter or a null char */
1433  ++Written;
1434  /* Move to the next letter */
1435  Offset += sizeof(WCHAR);
1436  }
1437  }
1438 
1439  FreePool(*CurrentPath);
1440  ++CurrentPath;
1441  }
1442 
1443  /* MultiSz: don't forget last null char */
1444  (*VolumePaths)->MultiSz[Written] = UNICODE_NULL;
1445  /* Cleanup everything and return success! */
1446  if (Paths != NULL)
1447  {
1448  FreePool(Paths);
1449  }
1450  RemoveEntryList(&DeviceInfoEntry->DeviceInformationEntry);
1451  FreePool(DeviceInfoEntry);
1452  return STATUS_SUCCESS;
1453 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _Entry Entry
Definition: kefuncs.h:627
uint16_t * PWSTR
Definition: typedefs.h:56
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:1169
PDEVICE_INFORMATION DeviceInformation
Definition: mntmgr.h:98
LONG NTSTATUS
Definition: precomp.h:26
#define LETTER_POSITION
Definition: mntmgr.h:159
#define InsertTailList(ListHead, Entry)
#define FreePool(P)
Definition: mntmgr.h:154
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:65
LIST_ENTRY DeviceInformationEntry
Definition: mntmgr.h:104
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
NTSTATUS MountMgrValidateBackPointer(IN PASSOCIATED_DEVICE_ENTRY AssociatedDeviceEntry, IN PDEVICE_INFORMATION DeviceInformation, OUT PBOOLEAN Invalid)
Definition: device.c:1064
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
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Definition: mntmgr.h:95
#define MOUNTMGR_IS_DRIVE_LETTER(s)
Definition: mountmgr.h:53
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
Status
Definition: gdiplustypes.h:24
static const WCHAR L[]
Definition: oid.c:1250
Definition: typedefs.h:119
UNICODE_STRING String
Definition: mntmgr.h:99
#define AllocatePool(Size)
Definition: mntmgr.h:153
PDEVICE_INFORMATION DeviceInformation
Definition: mntmgr.h:105
unsigned short USHORT
Definition: pedump.c:61
unsigned int ULONG
Definition: retypes.h:1
Definition: mntmgr.h:102
return STATUS_SUCCESS
Definition: btrfs.c:3014
base of all file and directory entries
Definition: entries.h:82

Referenced by MountMgrQueryDosVolumePaths().

◆ MountMgrScrubRegistry()

NTSTATUS MountMgrScrubRegistry ( IN PDEVICE_EXTENSION  DeviceExtension)

Definition at line 221 of file device.c.

222 {
226 
227  do
228  {
232  Continue = FALSE;
233 
235  DatabasePath,
236  QueryTable,
237  DeviceExtension,
238  NULL);
239  }
240  while (Continue);
241 
242  return Status;
243 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4142
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
LONG NTSTATUS
Definition: precomp.h:26
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
volatile int Continue
Definition: gdblib.c:102
Status
Definition: gdiplustypes.h:24
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
PWSTR DatabasePath
Definition: database.c:31
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
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 104 of file device.c.

106 {
107  PIO_STACK_LOCATION Stack;
108  PMOUNTMGR_SET_AUTO_MOUNT SetState;
109 
111 
112  if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_SET_AUTO_MOUNT))
113  {
114  Irp->IoStatus.Information = 0;
116  }
117 
118  /* Only change if there's a real difference */
119  SetState = (PMOUNTMGR_SET_AUTO_MOUNT)Irp->AssociatedIrp.SystemBuffer;
120  if (SetState->NewState == !DeviceExtension->NoAutoMount)
121  {
122  Irp->IoStatus.Information = 0;
123  return STATUS_SUCCESS;
124  }
125 
126  /* Set new state; ! on purpose */
127  DeviceExtension->NoAutoMount = !SetState->NewState;
128  Irp->IoStatus.Information = 0;
129  return MountmgrWriteNoAutoMount(DeviceExtension);
130 }
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
MOUNTMGR_AUTO_MOUNT_STATE NewState
Definition: mountmgr.h:167
struct _MOUNTMGR_SET_AUTO_MOUNT * PMOUNTMGR_SET_AUTO_MOUNT
if(!(yy_init))
Definition: macro.lex.yy.c:714
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
NTSTATUS MountmgrWriteNoAutoMount(IN PDEVICE_EXTENSION DeviceExtension)
Definition: device.c:87
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2779
return STATUS_SUCCESS
Definition: btrfs.c:3014

Referenced by MountMgrDeviceControl().

◆ MountMgrValidateBackPointer()

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

Definition at line 1064 of file device.c.

1067 {
1068  HANDLE Handle;
1069  NTSTATUS Status;
1070  PLIST_ENTRY SymlinksEntry;
1072  PREPARSE_DATA_BUFFER ReparseData;
1074  UNICODE_STRING FullName, SubstituteName;
1075  PSYMLINK_INFORMATION SymlinkInformation;
1076 
1077  /* Initialize & allocate a string big enough to contain our complete mount point name */
1078  FullName.Length = AssociatedDeviceEntry->String.Length + AssociatedDeviceEntry->DeviceInformation->DeviceName.Length + sizeof(WCHAR);
1081  if (!FullName.Buffer)
1082  {
1084  }
1085 
1086  /* Create the path */
1087  RtlCopyMemory(FullName.Buffer, AssociatedDeviceEntry->DeviceInformation->DeviceName.Buffer, AssociatedDeviceEntry->DeviceInformation->DeviceName.Length);
1088  FullName.Buffer[AssociatedDeviceEntry->DeviceInformation->DeviceName.Length / sizeof(WCHAR)] = L'\\';
1089  RtlCopyMemory(&FullName.Buffer[AssociatedDeviceEntry->DeviceInformation->DeviceName.Length / sizeof(WCHAR) + 1], AssociatedDeviceEntry->String.Buffer, AssociatedDeviceEntry->String.Length);
1091 
1092  /* Open it to query the reparse point */
1094  &FullName,
1096  NULL,
1097  NULL);
1104 
1105  if (!NT_SUCCESS(Status))
1106  {
1107  *Invalid = TRUE;
1108  return STATUS_SUCCESS;
1109  }
1110 
1111  /* Allocate a buffer big enough to read reparse data */
1113  if (ReparseData == NULL)
1114  {
1115  ZwClose(Handle);
1117  }
1118 
1119  /* Query reparse data */
1121  NULL, NULL, NULL,
1122  &IoStatusBlock,
1124  NULL, 0,
1125  ReparseData, MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
1126  ZwClose(Handle);
1127 
1128  if (!NT_SUCCESS(Status))
1129  {
1130  FreePool(ReparseData);
1131  *Invalid = TRUE;
1132  return STATUS_SUCCESS;
1133  }
1134 
1135  /* Create a string with the substitute name */
1136  SubstituteName.Length = ReparseData->SymbolicLinkReparseBuffer.SubstituteNameLength;
1137  SubstituteName.MaximumLength = SubstituteName.Length;
1138  SubstituteName.Buffer = (PWSTR)((ULONG_PTR)ReparseData->SymbolicLinkReparseBuffer.PathBuffer + ReparseData->SymbolicLinkReparseBuffer.SubstituteNameOffset);
1139 
1140  /* If that's a volume name that matches our associated device, that's a success! */
1141  if (MOUNTMGR_IS_VOLUME_NAME(&SubstituteName))
1142  {
1143  if (SubstituteName.Length == 98 && SubstituteName.Buffer[1] == L'?')
1144  {
1145  for (SymlinksEntry = DeviceInformation->SymbolicLinksListHead.Flink;
1146  SymlinksEntry != &(DeviceInformation->SymbolicLinksListHead);
1147  SymlinksEntry = SymlinksEntry->Flink)
1148  {
1149  SymlinkInformation = CONTAINING_RECORD(SymlinksEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
1150 
1151  if (RtlEqualUnicodeString(&SubstituteName, &SymlinkInformation->Name, TRUE))
1152  {
1153  FreePool(ReparseData);
1154  return STATUS_SUCCESS;
1155  }
1156  }
1157  }
1158  }
1159 
1160  FreePool(ReparseData);
1161  *Invalid = TRUE;
1162  return STATUS_SUCCESS;
1163 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define TRUE
Definition: types.h:120
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:56
LONG NTSTATUS
Definition: precomp.h:26
unsigned short Length
Definition: sprintf.c:451
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FSCTL_GET_REPARSE_POINT
Definition: winioctl.h:97
#define FreePool(P)
Definition: mntmgr.h:154
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define FILE_SHARE_READ
Definition: compat.h:136
uint32_t ULONG_PTR
Definition: typedefs.h:65
void * Buffer
Definition: sprintf.c:453
#define UNICODE_NULL
#define MOUNTMGR_IS_VOLUME_NAME(s)
Definition: mountmgr.h:61
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)
smooth NULL
Definition: ftsmooth.c:416
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _REPARSE_DATA_BUFFER::@312::@314 SymbolicLinkReparseBuffer
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
_In_ HANDLE Handle
Definition: extypes.h:390
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ PSTRING FullName
Definition: rtlfuncs.h:1649
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
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)
Status
Definition: gdiplustypes.h:24
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
static const WCHAR L[]
Definition: oid.c:1250
Definition: typedefs.h:119
#define SYNCHRONIZE
Definition: nt_native.h:61
#define AllocatePool(Size)
Definition: mntmgr.h:153
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
return STATUS_SUCCESS
Definition: btrfs.c:3014
unsigned short MaximumLength
Definition: sprintf.c:452
#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE
Definition: iotypes.h:6864
#define FILE_OPEN_REPARSE_POINT
Definition: from_kernel.h:46
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)

Referenced by MountMgrQueryVolumePaths().

◆ MountMgrVolumeArrivalNotification()

NTSTATUS MountMgrVolumeArrivalNotification ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PIRP  Irp 
)

Definition at line 1652 of file device.c.

1654 {
1655  NTSTATUS Status;
1656  BOOLEAN OldState;
1657  PIO_STACK_LOCATION Stack;
1660 
1662 
1663  /* Validate input */
1664  if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_TARGET_NAME))
1665  {
1666  return STATUS_INVALID_PARAMETER;
1667  }
1668 
1669  Target = (PMOUNTMGR_TARGET_NAME)Irp->AssociatedIrp.SystemBuffer;
1670  if (Target->DeviceNameLength + sizeof(USHORT) > Stack->Parameters.DeviceIoControl.InputBufferLength)
1671  {
1672  return STATUS_INVALID_PARAMETER;
1673  }
1674 
1676  SymbolicName.MaximumLength = Target->DeviceNameLength;
1677  SymbolicName.Buffer = Target->DeviceName;
1678 
1679  /* Disable hard errors */
1682 
1683  /* Call real worker */
1684  Status = MountMgrMountedDeviceArrival(DeviceExtension, &SymbolicName, TRUE);
1685 
1687 
1688  return Status;
1689 }
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
USHORT MaximumLength
Definition: env_spec_w32.h:370
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
LONG NTSTATUS
Definition: precomp.h:26
struct _MOUNTMGR_TARGET_NAME * PMOUNTMGR_TARGET_NAME
unsigned char BOOLEAN
if(!(yy_init))
Definition: macro.lex.yy.c:714
VOID NTAPI PsSetThreadHardErrorsAreDisabled(IN PETHREAD Thread, IN BOOLEAN HardErrorsAreDisabled)
Definition: thread.c:898
_Must_inspect_result_ typedef _In_ ULONG _In_ BOOLEAN Target
Definition: iotypes.h:1072
Status
Definition: gdiplustypes.h:24
BOOLEAN NTAPI PsGetThreadHardErrorsAreDisabled(IN PETHREAD Thread)
Definition: thread.c:695
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
unsigned short USHORT
Definition: pedump.c:61
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2779
NTSTATUS MountMgrMountedDeviceArrival(IN PDEVICE_EXTENSION Extension, IN PUNICODE_STRING SymbolicName, IN BOOLEAN FromVolume)
Definition: mountmgr.c:937

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 2008 of file device.c.

2014 {
2015  HANDLE Handle;
2016  NTSTATUS Status;
2018  PIO_STACK_LOCATION Stack;
2019  ULONG Length, SavedLength;
2020  BOOLEAN FOReferenced = FALSE;
2023  PDEVICE_INFORMATION DeviceInformation;
2024  OBJECT_NAME_INFORMATION ObjectNameInfo;
2025  FILE_FS_DEVICE_INFORMATION FsDeviceInfo;
2026  PFILE_NAME_INFORMATION FileNameInfo = NULL;
2027  PMOUNTMGR_VOLUME_MOUNT_POINT VolumeMountPoint;
2028  POBJECT_NAME_INFORMATION ObjectNameInfoPtr = NULL;
2029  UNICODE_STRING SourceVolumeName, TargetDeviceName;
2030 
2032 
2033  /* Validate input */
2034  if (Stack->Parameters.DeviceIoControl.InputBufferLength < sizeof(MOUNTMGR_VOLUME_MOUNT_POINT))
2035  {
2036  return STATUS_INVALID_PARAMETER;
2037  }
2038 
2039  VolumeMountPoint = (PMOUNTMGR_VOLUME_MOUNT_POINT)Irp->AssociatedIrp.SystemBuffer;
2040 
2041  if (((ULONG)VolumeMountPoint->SourceVolumeNameLength + VolumeMountPoint->TargetVolumeNameLength) <
2042  Stack->Parameters.DeviceIoControl.InputBufferLength)
2043  {
2044  return STATUS_INVALID_PARAMETER;
2045  }
2046 
2047  /* Get source volume name */
2048  SourceVolumeName.Length =
2049  SourceVolumeName.MaximumLength = VolumeMountPoint->SourceVolumeNameLength;
2050  SourceVolumeName.Buffer = (PWSTR)((ULONG_PTR)VolumeMountPoint + VolumeMountPoint->SourceVolumeNameOffset);
2051 
2053  &SourceVolumeName,
2055  NULL,
2056  NULL);
2057 
2058  /* Open it */
2062  &IoStatusBlock,
2065  if (!NT_SUCCESS(Status))
2066  {
2067  return Status;
2068  }
2069 
2070  TargetDeviceName.Buffer = NULL;
2071 
2072  /* Query its attributes */
2074  &IoStatusBlock,
2075  &FsDeviceInfo,
2076  sizeof(FsDeviceInfo),
2078  if (!NT_SUCCESS(Status))
2079  {
2080  goto Cleanup;
2081  }
2082 
2083  if (FsDeviceInfo.DeviceType != FILE_DEVICE_DISK && FsDeviceInfo.DeviceType != FILE_DEVICE_VIRTUAL_DISK)
2084  {
2085  goto Cleanup;
2086  }
2087 
2089  {
2090  goto Cleanup;
2091  }
2092 
2093  /* Reference it */
2095  if (!NT_SUCCESS(Status))
2096  {
2097  goto Cleanup;
2098  }
2099  FOReferenced = TRUE;
2100 
2101  /* Get file name */
2102  FileNameInfo = AllocatePool(sizeof(FILE_NAME_INFORMATION));
2103  if (!FileNameInfo)
2104  {
2106  goto Cleanup;
2107  }
2108 
2109  Status = ZwQueryInformationFile(Handle, &IoStatusBlock, FileNameInfo,
2110  sizeof(FILE_NAME_INFORMATION),
2113  {
2114  /* Now we have real length, use it */
2115  Length = FileNameInfo->FileNameLength;
2116  FreePool(FileNameInfo);
2117 
2118  FileNameInfo = AllocatePool(sizeof(FILE_NAME_INFORMATION) + Length);
2119  if (!FileNameInfo)
2120  {
2122  goto Cleanup;
2123  }
2124 
2125  /* Really query file name */
2126  Status = ZwQueryInformationFile(Handle, &IoStatusBlock, FileNameInfo,
2127  sizeof(FILE_NAME_INFORMATION) + Length,
2129  }
2130 
2131  if (!NT_SUCCESS(Status))
2132  {
2133  goto Cleanup;
2134  }
2135 
2136  /* Get symbolic name */
2137  ObjectNameInfoPtr = &ObjectNameInfo;
2138  SavedLength = sizeof(OBJECT_NAME_INFORMATION);
2139  Status = ObQueryNameString(FileObject->DeviceObject, ObjectNameInfoPtr, sizeof(OBJECT_NAME_INFORMATION), &Length);
2141  {
2142  /* Once again, with proper size, it works better */
2143  ObjectNameInfoPtr = AllocatePool(Length);
2144  if (!ObjectNameInfoPtr)
2145  {
2147  goto Cleanup;
2148  }
2149 
2150  SavedLength = Length;
2151  Status = ObQueryNameString(FileObject->DeviceObject, ObjectNameInfoPtr, SavedLength, &Length);
2152  }
2153 
2154  if (!NT_SUCCESS(Status))
2155  {
2156  goto Cleanup;
2157  }
2158 
2159  /* Now, query the device name */
2160  Status = QueryDeviceInformation(&ObjectNameInfoPtr->Name, SourceDeviceName,
2161  NULL, NULL, NULL, NULL, NULL, NULL);
2162  if (!NT_SUCCESS(Status))
2163  {
2164  goto Cleanup;
2165  }
2166 
2167  /* For target volume name, use input */
2168  TargetVolumeName->Length =
2169  TargetVolumeName->MaximumLength = VolumeMountPoint->TargetVolumeNameLength;
2170  TargetVolumeName->Buffer = (PWSTR)((ULONG_PTR)VolumeMountPoint + VolumeMountPoint->TargetVolumeNameOffset);
2171 
2172  /* Query its device name */
2173  Status = QueryDeviceInformation(TargetVolumeName, &TargetDeviceName,
2174  NULL, NULL, NULL, NULL, NULL, NULL);
2175  if (!NT_SUCCESS(Status))
2176  {
2177  goto Cleanup;
2178  }
2179 
2180  /* Return symbolic name */
2181  SourceSymbolicName->Length =
2182  SourceSymbolicName->MaximumLength = (USHORT)FileNameInfo->FileNameLength;
2183  SourceSymbolicName->Buffer = (PWSTR)FileNameInfo;
2184  /* memmove allows memory overlap */
2185  RtlMoveMemory(SourceSymbolicName->Buffer, FileNameInfo->FileName, SourceSymbolicName->Length);
2186  FileNameInfo = NULL;
2187 
2188  /* Notify the change */
2189  MountMgrNotify(DeviceExtension);
2190  MountMgrNotifyNameChange(DeviceExtension, &TargetDeviceName, TRUE);
2191 
2192  /* If we are locked, sync databases if possible */
2193  if (NT_SUCCESS(LockStatus))
2194  {
2195  Status = FindDeviceInfo(DeviceExtension, SourceDeviceName, FALSE, &DeviceInformation);
2196  if (NT_SUCCESS(Status))
2197  {
2198  ReconcileThisDatabaseWithMaster(DeviceExtension, DeviceInformation);
2199  }
2200  else
2201  {
2203  }
2204  }
2205 
2206 Cleanup:
2207  if (TargetDeviceName.Buffer)
2208  {
2209  FreePool(TargetDeviceName.Buffer);
2210  }
2211 
2212  if (ObjectNameInfoPtr && ObjectNameInfoPtr != &ObjectNameInfo)
2213  {
2214  FreePool(ObjectNameInfoPtr);
2215  }
2216 
2217  if (FileNameInfo)
2218  {
2219  FreePool(FileNameInfo);
2220  }
2221 
2222  if (FOReferenced)
2223  {
2225  }
2226 
2227  return Status;
2228 }
struct _MOUNTMGR_VOLUME_MOUNT_POINT * PMOUNTMGR_VOLUME_MOUNT_POINT
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define FILE_DEVICE_DISK
Definition: winioctl.h:112
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
USHORT MaximumLength
Definition: env_spec_w32.h:370
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
uint16_t * PWSTR
Definition: typedefs.h:56
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI ObQueryNameString(IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength)
Definition: obname.c:1209
#define FILE_DEVICE_VIRTUAL_DISK
Definition: winioctl.h:141
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
UNICODE_STRING Name
Definition: nt_native.h:1270
#define FreePool(P)
Definition: mntmgr.h:154
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define FILE_SHARE_READ
Definition: compat.h:136
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG_PTR
Definition: typedefs.h:65
VOID ReconcileThisDatabaseWithMaster(IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation)
Definition: database.c:1613
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:496
#define FALSE
Definition: types.h:117
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
unsigned char BOOLEAN
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS FindDeviceInfo(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName, IN BOOLEAN DeviceNameGiven, OUT PDEVICE_INFORMATION *DeviceInformation)
Definition: mountmgr.c:642
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:588
NTSTATUS QueryDeviceInformation(IN PUNICODE_STRING SymbolicName, OUT PUNICODE_STRING DeviceName OPTIONAL, OUT PMOUNTDEV_UNIQUE_ID *UniqueId OPTIONAL, OUT PBOOLEAN Removable OPTIONAL, OUT PBOOLEAN GptDriveLetter OPTIONAL, OUT PBOOLEAN HasGuid OPTIONAL, IN OUT LPGUID StableGuid OPTIONAL, OUT PBOOLEAN Valid OPTIONAL)
Definition: mountmgr.c:195
_In_ HANDLE Handle
Definition: extypes.h:390
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
* PFILE_OBJECT
Definition: iotypes.h:1962
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
NTSYSAPI NTSTATUS NTAPI ZwQueryVolumeInformationFile(IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FsInformation, IN ULONG Length, IN FS_INFORMATION_CLASS FsInformationClass)
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)
Status
Definition: gdiplustypes.h:24
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
VOID MountMgrNotify(IN PDEVICE_EXTENSION DeviceExtension)
Definition: notify.c:313
#define FILE_REMOTE_DEVICE
Definition: nt_native.h:811
static const WCHAR Cleanup[]
Definition: register.c:80
#define SYNCHRONIZE
Definition: nt_native.h:61
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
#define AllocatePool(Size)
Definition: mntmgr.h:153
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
unsigned short USHORT
Definition: pedump.c:61
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
unsigned int ULONG
Definition: retypes.h:1
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2779
#define FILE_OPEN_REPARSE_POINT
Definition: from_kernel.h:46
VOID MountMgrNotifyNameChange(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName, IN BOOLEAN ValidateVolume)
Definition: notify.c:353

Referenced by MountMgrVolumeMountPointCreated(), and MountMgrVolumeMountPointDeleted().

◆ MountMgrVolumeMountPointCreated()

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

Definition at line 2234 of file device.c.

2237 {
2238  LONG Offset;
2239  BOOLEAN Found;
2240  NTSTATUS Status;
2242  PMOUNTDEV_UNIQUE_ID UniqueId;
2243  PDATABASE_ENTRY DatabaseEntry;
2244  PASSOCIATED_DEVICE_ENTRY AssociatedEntry;
2245  PDEVICE_INFORMATION DeviceInformation, TargetDeviceInformation;
2246  UNICODE_STRING LinkTarget, SourceDeviceName, SourceSymbolicName, TargetVolumeName, VolumeName, DbName;
2247 
2248  /* Initialize string */
2249  LinkTarget.Length = 0;
2250  LinkTarget.MaximumLength = 0xC8;
2252  if (LinkTarget.Buffer == NULL)
2253  {
2255  }
2256 
2257  /* If the mount point was created, then, it changed!
2258  * Also use it to query some information
2259  */
2260  Status = MountMgrVolumeMountPointChanged(DeviceExtension, Irp, LockStatus, &SourceDeviceName, &SourceSymbolicName, &TargetVolumeName);
2261  /* Pending means DB are under synchronization, bail out */
2262  if (Status == STATUS_PENDING)
2263  {
2265  FreePool(SourceDeviceName.Buffer);
2266  FreePool(SourceSymbolicName.Buffer);
2267  return STATUS_SUCCESS;
2268  }
2269  else if (!NT_SUCCESS(Status))
2270  {
2272  return Status;
2273  }
2274 
2275  /* Query the device information */
2276  Status = FindDeviceInfo(DeviceExtension, &SourceDeviceName, FALSE, &DeviceInformation);
2277  if (!NT_SUCCESS(Status))
2278  {
2279  /* If it failed, first try to get volume name */
2280  Status = QueryVolumeName(0, NULL, &SourceDeviceName, &LinkTarget, &VolumeName);
2281  if (!NT_SUCCESS(Status))
2282  {
2283  /* Then, try to read the symlink */
2284  Status = MountMgrQuerySymbolicLink(&SourceDeviceName, &LinkTarget);
2285  if (!NT_SUCCESS(Status))
2286  {
2288  FreePool(SourceDeviceName.Buffer);
2289  FreePool(SourceSymbolicName.Buffer);
2290  return Status;
2291  }
2292  }
2293  else
2294  {
2296  }
2297 
2298  FreePool(SourceDeviceName.Buffer);
2299 
2300  SourceDeviceName.Length = LinkTarget.Length;
2301  SourceDeviceName.MaximumLength = LinkTarget.MaximumLength;
2302  SourceDeviceName.Buffer = LinkTarget.Buffer;
2303 
2304  /* Now that we have the correct source, reattempt to query information */
2305  Status = FindDeviceInfo(DeviceExtension, &SourceDeviceName, FALSE, &DeviceInformation);
2306  if (!NT_SUCCESS(Status))
2307  {
2308  FreePool(SourceDeviceName.Buffer);
2309  FreePool(SourceSymbolicName.Buffer);
2310  return Status;
2311  }
2312  }
2313 
2314  FreePool(SourceDeviceName.Buffer);
2315 
2316  /* Get information about target device */
2317  Status = FindDeviceInfo(DeviceExtension, &TargetVolumeName, FALSE, &TargetDeviceInformation);
2318  if (!NT_SUCCESS(Status))
2319  {
2320  FreePool(SourceSymbolicName.Buffer);
2321  return Status;
2322  }
2323 
2324  /* Notify if not disabled */
2325  if (!TargetDeviceInformation->SkipNotifications)
2326  {
2327  PostOnlineNotification(DeviceExtension, &TargetDeviceInformation->SymbolicName);
2328  }
2329 
2330  /* Open the remote database */
2331  RemoteDatabase = OpenRemoteDatabase(DeviceInformation, TRUE);
2332  if (RemoteDatabase == 0)
2333  {
2334  FreePool(SourceSymbolicName.Buffer);
2336  }
2337 
2338  /* Browse all the entries */
2339  Offset = 0;
2340  Found = FALSE;
2341  for (;;)
2342  {
2343  DatabaseEntry = GetRemoteDatabaseEntry(RemoteDatabase, Offset);
2344  if (DatabaseEntry == NULL)
2345  {
2346  break;
2347  }
2348 
2349  /* Try to find ourselves */
2350  DbName.MaximumLength = DatabaseEntry->SymbolicNameLength;
2351  DbName.Length = DbName.MaximumLength;
2352  DbName.Buffer = (PWSTR)((ULONG_PTR)DatabaseEntry + DatabaseEntry->SymbolicNameOffset);
2353  if (RtlEqualUnicodeString(&TargetVolumeName, &DbName, TRUE))
2354  {
2355  /* Reference ourselves and update the entry */
2356  ++DatabaseEntry->EntryReferences;
2358  FreePool(DatabaseEntry);
2359  Found = TRUE;
2360  break;
2361  }
2362 
2363  Offset += DatabaseEntry->EntrySize;
2364  FreePool(DatabaseEntry);
2365  }
2366 
2367  /* We couldn't find ourselves, we'll have to add ourselves */
2368  if (!Found)
2369  {
2370  ULONG EntrySize;
2371  PUNIQUE_ID_REPLICATE UniqueIdReplicate;
2372 
2373  /* Query the device unique ID */
2374  Status = QueryDeviceInformation(&TargetVolumeName, NULL, &UniqueId, NULL, NULL, NULL, NULL, NULL);
2375  if (!NT_SUCCESS(Status))
2376  {
2377  FreePool(SourceSymbolicName.Buffer);
2379  return Status;
2380  }
2381 
2382  /* Allocate a database entry */
2383  EntrySize = UniqueId->UniqueIdLength + TargetVolumeName.Length + sizeof(DATABASE_ENTRY);
2384  DatabaseEntry = AllocatePool(EntrySize);
2385  if (DatabaseEntry == NULL)
2386  {
2387  FreePool(UniqueId);
2388  FreePool(SourceSymbolicName.Buffer);
2391  }
2392 
2393  /* Fill it in */
2394  DatabaseEntry->EntrySize = EntrySize;
2395  DatabaseEntry->EntryReferences = 1;
2396  DatabaseEntry->SymbolicNameOffset = sizeof(DATABASE_ENTRY);
2397  DatabaseEntry->SymbolicNameLength = TargetVolumeName.Length;
2398  DatabaseEntry->UniqueIdOffset = TargetVolumeName.Length + sizeof(DATABASE_ENTRY);
2399  DatabaseEntry->UniqueIdLength = UniqueId->UniqueIdLength;
2400  RtlCopyMemory((PVOID)((ULONG_PTR)DatabaseEntry + sizeof(DATABASE_ENTRY)), TargetVolumeName.Buffer, DatabaseEntry->SymbolicNameLength);
2401  RtlCopyMemory((PVOID)((ULONG_PTR)DatabaseEntry + DatabaseEntry->UniqueIdOffset), UniqueId->UniqueId, UniqueId->UniqueIdLength);
2402 
2403  /* And write it down */
2404  Status = AddRemoteDatabaseEntry(RemoteDatabase, DatabaseEntry);
2405  FreePool(DatabaseEntry);
2406  if (!NT_SUCCESS(Status))
2407  {
2408  FreePool(UniqueId);
2409  FreePool(SourceSymbolicName.Buffer);
2411  return Status;
2412  }
2413 
2414  /* And now, allocate an Unique ID item */
2415  UniqueIdReplicate = AllocatePool(sizeof(UNIQUE_ID_REPLICATE));
2416  if (UniqueIdReplicate == NULL)
2417  {
2418  FreePool(UniqueId);
2419  FreePool(SourceSymbolicName.Buffer);
2421  return Status;
2422  }
2423 
2424  /* To associate it with the device */
2425  UniqueIdReplicate->UniqueId = UniqueId;
2426  InsertTailList(&DeviceInformation->ReplicatedUniqueIdsListHead, &UniqueIdReplicate->ReplicatedUniqueIdsListEntry);
2427  }
2428 
2429  /* We're done with the remote database */
2431 
2432  /* Check we were find writing the entry */
2433  if (!NT_SUCCESS(Status))
2434  {
2435  FreePool(SourceSymbolicName.Buffer);
2436  return Status;
2437  }
2438 
2439  /* This is the end, allocate an associated entry */
2440  AssociatedEntry = AllocatePool(sizeof(ASSOCIATED_DEVICE_ENTRY));
2441  if (AssociatedEntry == NULL)
2442  {
2443  FreePool(SourceSymbolicName.Buffer);
2445  }
2446 
2447  /* Initialize its source name string */
2448  AssociatedEntry->String.Length = SourceSymbolicName.Length;
2449  AssociatedEntry->String.MaximumLength = AssociatedEntry->String.Length + sizeof(UNICODE_NULL);
2450  AssociatedEntry->String.Buffer = AllocatePool(AssociatedEntry->String.MaximumLength);
2451  if (AssociatedEntry->String.Buffer == NULL)
2452  {
2453  FreePool(AssociatedEntry);
2454  FreePool(SourceSymbolicName.Buffer);
2456  }
2457 
2458  /* Copy data & insert in list */
2459  RtlCopyMemory(AssociatedEntry->String.Buffer, SourceSymbolicName.Buffer, SourceSymbolicName.Length);
2460  AssociatedEntry->String.Buffer[SourceSymbolicName.Length / sizeof(WCHAR)] = UNICODE_NULL;
2461  AssociatedEntry->DeviceInformation = DeviceInformation;
2462  InsertTailList(&TargetDeviceInformation->AssociatedDevicesHead, &AssociatedEntry->AssociatedDevicesEntry);
2463 
2464  /* We're done! */
2465  FreePool(SourceSymbolicName.Buffer);
2466  return STATUS_SUCCESS;
2467 }
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:2008
USHORT UniqueIdOffset
Definition: mntmgr.h:91
PMOUNTDEV_UNIQUE_ID UniqueId
Definition: mntmgr.h:82
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
ULONG EntryReferences
Definition: mntmgr.h:88
USHORT MaximumLength
Definition: env_spec_w32.h:370
ULONG EntrySize
Definition: mntmgr.h:87
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
uint16_t * PWSTR
Definition: typedefs.h:56
NTSTATUS MountMgrQuerySymbolicLink(IN PUNICODE_STRING SymbolicName, IN OUT PUNICODE_STRING LinkTarget)
Definition: symlink.c:959
PDEVICE_INFORMATION DeviceInformation
Definition: mntmgr.h:98
LONG NTSTATUS
Definition: precomp.h:26
USHORT UniqueIdLength
Definition: imports.h:138
UNICODE_STRING RemoteDatabase
Definition: database.c:34
#define InsertTailList(ListHead, Entry)
USHORT SymbolicNameLength
Definition: mntmgr.h:90
_In_ UCHAR EntrySize
Definition: iofuncs.h:640
#define FreePool(P)
Definition: mntmgr.h:154
UNICODE_STRING SymbolicName
Definition: mntmgr.h:48
LIST_ENTRY AssociatedDevicesEntry
Definition: mntmgr.h:97
uint32_t ULONG_PTR
Definition: typedefs.h:65
_Inout_ PUNICODE_STRING LinkTarget
Definition: zwfuncs.h:292
HANDLE OpenRemoteDatabase(IN PDEVICE_INFORMATION DeviceInformation, IN BOOLEAN MigrateDatabase)
Definition: database.c:1836
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
long LONG
Definition: pedump.c:60
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
USHORT UniqueIdLength
Definition: mntmgr.h:92
NTSTATUS FindDeviceInfo(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName, IN BOOLEAN DeviceNameGiven, OUT PDEVICE_INFORMATION *DeviceInformation)
Definition: mountmgr.c:642
return Found
Definition: dirsup.c:1270
NTSTATUS QueryDeviceInformation(IN PUNICODE_STRING SymbolicName, OUT PUNICODE_STRING DeviceName OPTIONAL, OUT PMOUNTDEV_UNIQUE_ID *UniqueId OPTIONAL, OUT PBOOLEAN Removable OPTIONAL, OUT PBOOLEAN GptDriveLetter OPTIONAL, OUT PBOOLEAN HasGuid OPTIONAL, IN OUT LPGUID StableGuid OPTIONAL, OUT PBOOLEAN Valid OPTIONAL)
Definition: mountmgr.c:195
NTSTATUS CloseRemoteDatabase(IN HANDLE Database)
Definition: database.c:82
struct _DATABASE_ENTRY DATABASE_ENTRY
BOOLEAN SkipNotifications
Definition: mntmgr.h:58
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
Definition: mntmgr.h:95
USHORT SymbolicNameOffset
Definition: mntmgr.h:89
Definition: mntmgr.h:85
Status
Definition: gdiplustypes.h:24
UNICODE_STRING String
Definition: mntmgr.h:99
#define AllocatePool(Size)
Definition: mntmgr.h:153
VOID PostOnlineNotification(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName)
Definition: notify.c:145
NTSTATUS WriteRemoteDatabaseEntry(IN HANDLE Database, IN LONG Offset, IN PDATABASE_ENTRY Entry)
Definition: database.c:200
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
_Must_inspect_result_ _Inout_opt_ PUNICODE_STRING VolumeName
Definition: fltkernel.h:1117
PDATABASE_ENTRY GetRemoteDatabaseEntry(IN HANDLE Database, IN LONG StartingOffset)
Definition: database.c:125
LIST_ENTRY ReplicatedUniqueIdsListHead
Definition: mntmgr.h:46
unsigned int ULONG
Definition: retypes.h:1
LIST_ENTRY AssociatedDevicesHead
Definition: mntmgr.h:47
NTSTATUS AddRemoteDatabaseEntry(IN HANDLE Database, IN PDATABASE_ENTRY Entry)
Definition: database.c:64
return STATUS_SUCCESS
Definition: btrfs.c:3014
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
UCHAR UniqueId[1]
Definition: imports.h:139
LIST_ENTRY ReplicatedUniqueIdsListEntry
Definition: mntmgr.h:81

Referenced by MountMgrDeviceControl().

◆ MountMgrVolumeMountPointDeleted()

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

Definition at line 2473 of file device.c.

2476 {
2477  LONG Offset;
2478  NTSTATUS Status;
2481  PDATABASE_ENTRY DatabaseEntry;
2482  PUNIQUE_ID_REPLICATE UniqueIdReplicate;
2483  PASSOCIATED_DEVICE_ENTRY AssociatedEntry;
2484  PDEVICE_INFORMATION DeviceInformation, TargetDeviceInformation;
2485  UNICODE_STRING LinkTarget, SourceDeviceName, SourceSymbolicName, TargetVolumeName, VolumeName, DbName;
2486 
2487  /* Initialize string */
2488  LinkTarget.Length = 0;
2489  LinkTarget.MaximumLength = 0xC8;
2491  if (LinkTarget.Buffer == NULL)
2492  {
2494  }
2495 
2496  /* If the mount point was deleted, then, it changed!
2497  * Also use it to query some information
2498  */
2499  Status = MountMgrVolumeMountPointChanged(DeviceExtension, Irp, LockStatus, &SourceDeviceName, &SourceSymbolicName, &TargetVolumeName);
2500  /* Pending means DB are under synchronization, bail out */
2501  if (Status == STATUS_PENDING)
2502  {
2504  FreePool(SourceDeviceName.Buffer);
2505  FreePool(SourceSymbolicName.Buffer);
2506  return STATUS_SUCCESS;
2507  }
2508  else if (!NT_SUCCESS(Status))
2509  {
2511  return Status;
2512  }
2513 
2514  /* Query the device information */
2515  Status = FindDeviceInfo(DeviceExtension, &SourceDeviceName, FALSE, &DeviceInformation);
2516  if (!NT_SUCCESS(Status))
2517  {
2518  /* If it failed, first try to get volume name */
2519  Status = QueryVolumeName(0, NULL, &SourceDeviceName, &LinkTarget, &VolumeName);
2520  if (!NT_SUCCESS(Status))
2521  {
2522  /* Then, try to read the symlink */
2523  Status = MountMgrQuerySymbolicLink(&SourceDeviceName, &LinkTarget);
2524  if (!NT_SUCCESS(Status))
2525  {
2527  FreePool(SourceDeviceName.Buffer);
2528  FreePool(SourceSymbolicName.Buffer);
2529  return Status;
2530  }
2531  }
2532  else
2533  {
2535  }
2536 
2537  FreePool(SourceDeviceName.Buffer);
2538 
2539  SourceDeviceName.Length = LinkTarget.Length;
2540  SourceDeviceName.MaximumLength = LinkTarget.MaximumLength;
2541  SourceDeviceName.Buffer = LinkTarget.Buffer;
2542 
2543  /* Now that we have the correct source, reattempt to query information */
2544  Status = FindDeviceInfo(DeviceExtension, &SourceDeviceName, FALSE, &DeviceInformation);
2545  if (!NT_SUCCESS(Status))
2546  {
2547  FreePool(SourceDeviceName.Buffer);
2548  FreePool(SourceSymbolicName.Buffer);
2549  return Status;
2550  }
2551  }
2552 
2553  FreePool(SourceDeviceName.Buffer);
2554 
2555  /* Get information about target device */
2556  Status = FindDeviceInfo(DeviceExtension, &TargetVolumeName, FALSE, &TargetDeviceInformation);
2557  if (!NT_SUCCESS(Status))
2558  {
2559  FreePool(SourceSymbolicName.Buffer);
2560  return Status;
2561  }
2562 
2563  /* Open the remote database */
2564  RemoteDatabase = OpenRemoteDatabase(DeviceInformation, TRUE);
2565  if (RemoteDatabase == 0)
2566  {
2567  FreePool(SourceSymbolicName.Buffer);
2569  }
2570 
2571  /* Browse all the entries */
2572  Offset = 0;
2573  for (;;)
2574  {
2575  DatabaseEntry = GetRemoteDatabaseEntry(RemoteDatabase, Offset);
2576  if (DatabaseEntry == NULL)
2577  {
2578  /* We didn't find ourselves, that's infortunate! */
2579  FreePool(SourceSymbolicName.Buffer);
2581  return STATUS_INVALID_PARAMETER;
2582  }
2583 
2584  /* Try to find ourselves */
2585  DbName.MaximumLength = DatabaseEntry->SymbolicNameLength;
2586  DbName.Length = DbName.MaximumLength;
2587  DbName.Buffer = (PWSTR)((ULONG_PTR)DatabaseEntry + DatabaseEntry->SymbolicNameOffset);
2588  if (RtlEqualUnicodeString(&TargetVolumeName, &DbName, TRUE))
2589  {
2590  break;
2591  }
2592 
2593  Offset += DatabaseEntry->EntrySize;
2594  FreePool(DatabaseEntry);
2595  }
2596 
2597  /* Dereference ourselves */
2598  DatabaseEntry->EntryReferences--;
2599  if (DatabaseEntry->EntryReferences == 0)
2600  {
2601  /* If we're still referenced, just update the entry */
2603  }
2604  else
2605  {
2606  /* Otherwise, delete the entry */
2608  if (!NT_SUCCESS(Status))
2609  {
2610  FreePool(DatabaseEntry);
2611  FreePool(SourceSymbolicName.Buffer);
2613  return Status;
2614  }
2615 
2616  /* Also, delete our unique ID replicated record */
2617  for (Entry = DeviceInformation->ReplicatedUniqueIdsListHead.Flink;
2618  Entry != &DeviceInformation->ReplicatedUniqueIdsListHead;
2619  Entry = Entry->Flink)
2620  {
2621  UniqueIdReplicate = CONTAINING_RECORD(Entry, UNIQUE_ID_REPLICATE, ReplicatedUniqueIdsListEntry);
2622 
2623  if (UniqueIdReplicate->UniqueId->UniqueIdLength == DatabaseEntry->UniqueIdLength &&
2624  RtlCompareMemory(UniqueIdReplicate->UniqueId->UniqueId,
2625  (PVOID)((ULONG_PTR)DatabaseEntry + DatabaseEntry->UniqueIdOffset),
2626  DatabaseEntry->UniqueIdLength) == DatabaseEntry->UniqueIdLength)
2627  {
2628  break;
2629  }
2630  }
2631 
2632  /* It has to exist! */
2633  if (Entry == &DeviceInformation->ReplicatedUniqueIdsListHead)
2634  {
2635  FreePool(DatabaseEntry);
2636  FreePool(SourceSymbolicName.Buffer);
2638  return STATUS_UNSUCCESSFUL;
2639  }
2640 
2641  /* Remove it and free it */
2642  RemoveEntryList(&UniqueIdReplicate->ReplicatedUniqueIdsListEntry);
2643  FreePool(UniqueIdReplicate->UniqueId);
2644  FreePool(UniqueIdReplicate);
2645  }
2646 
2647  /* We're done with the remote database */
2648  FreePool(DatabaseEntry);
2650 
2651  /* Check write operation succeed */
2652  if (!NT_SUCCESS(Status))
2653  {
2654  FreePool(SourceSymbolicName.Buffer);
2655  return Status;
2656  }
2657 
2658  /* Try to find our associated device entry */
2659  for (Entry = TargetDeviceInformation->AssociatedDevicesHead.Flink;
2660  Entry != &TargetDeviceInformation->AssociatedDevicesHead;
2661  Entry = Entry->Flink)
2662  {
2663  AssociatedEntry = CONTAINING_RECORD(Entry, ASSOCIATED_DEVICE_ENTRY, AssociatedDevicesEntry);
2664 
2665  /* If found, delete it */
2666  if (AssociatedEntry->DeviceInformation == DeviceInformation &&
2667  RtlEqualUnicodeString(&AssociatedEntry->String, &SourceSymbolicName, TRUE))
2668  {
2669  RemoveEntryList(&AssociatedEntry->AssociatedDevicesEntry);
2670  FreePool(AssociatedEntry->String.Buffer);
2671  FreePool(AssociatedEntry);
2672  break;
2673  }
2674  }
2675 
2676  /* We're done! */
2677  FreePool(SourceSymbolicName.Buffer);
2678  return STATUS_SUCCESS;
2679 }
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:2008
USHORT UniqueIdOffset
Definition: mntmgr.h:91
PMOUNTDEV_UNIQUE_ID UniqueId
Definition: mntmgr.h:82
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS DeleteRemoteDatabaseEntry(IN HANDLE Database, IN LONG StartingOffset)
Definition: database.c:233
struct _Entry Entry
Definition: kefuncs.h:627
ULONG EntryReferences
Definition: mntmgr.h:88
USHORT MaximumLength
Definition: env_spec_w32.h:370
ULONG EntrySize
Definition: mntmgr.h:87
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
uint16_t * PWSTR
Definition: typedefs.h:56
NTSTATUS MountMgrQuerySymbolicLink(IN PUNICODE_STRING SymbolicName, IN OUT PUNICODE_STRING LinkTarget)
Definition: symlink.c:959
PDEVICE_INFORMATION DeviceInformation
Definition: mntmgr.h:98
LONG NTSTATUS
Definition: precomp.h:26
USHORT UniqueIdLength
Definition: imports.h:138
UNICODE_STRING RemoteDatabase
Definition: database.c:34
USHORT SymbolicNameLength
Definition: mntmgr.h:90
#define FreePool(P)
Definition: mntmgr.h:154
LIST_ENTRY AssociatedDevicesEntry
Definition: mntmgr.h:97
uint32_t ULONG_PTR
Definition: typedefs.h:65
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
_Inout_ PUNICODE_STRING LinkTarget
Definition: zwfuncs.h:292
HANDLE OpenRemoteDatabase(IN PDEVICE_INFORMATION DeviceInformation, IN BOOLEAN MigrateDatabase)
Definition: database.c:1836
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
smooth NULL
Definition: ftsmooth.c:416
USHORT UniqueIdLength
Definition: mntmgr.h:92
NTSTATUS FindDeviceInfo(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName, IN BOOLEAN DeviceNameGiven, OUT PDEVICE_INFORMATION *DeviceInformation)
Definition: mountmgr.c:642
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
NTSTATUS CloseRemoteDatabase(IN HANDLE Database)
Definition: database.c:82
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
Definition: mntmgr.h:95
USHORT SymbolicNameOffset
Definition: mntmgr.h:89
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
Definition: mntmgr.h:85
Status
Definition: gdiplustypes.h:24
Definition: typedefs.h:119
UNICODE_STRING String
Definition: mntmgr.h:99
#define AllocatePool(Size)
Definition: mntmgr.h:153
NTSTATUS WriteRemoteDatabaseEntry(IN HANDLE Database, IN LONG Offset, IN PDATABASE_ENTRY Entry)
Definition: database.c:200
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
_Must_inspect_result_ _Inout_opt_ PUNICODE_STRING VolumeName
Definition: fltkernel.h:1117
PDATABASE_ENTRY GetRemoteDatabaseEntry(IN HANDLE Database, IN LONG StartingOffset)
Definition: database.c:125
LIST_ENTRY ReplicatedUniqueIdsListHead
Definition: mntmgr.h:46
LIST_ENTRY AssociatedDevicesHead
Definition: mntmgr.h:47
return STATUS_SUCCESS
Definition: btrfs.c:3014
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
UCHAR UniqueId[1]
Definition: imports.h:139
LIST_ENTRY ReplicatedUniqueIdsListEntry
Definition: mntmgr.h:81
base of all file and directory entries
Definition: entries.h:82
#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",
94  REG_DWORD,
95  &Value,
96  sizeof(Value));
97 
98 }
IN UCHAR Value
Definition: halp.h:394
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG, PCWSTR, PCWSTR, ULONG, PVOID, ULONG)
static const WCHAR L[]
Definition: oid.c:1250
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
unsigned int ULONG
Definition: retypes.h:1
#define REG_DWORD
Definition: sdbapi.c:596

Referenced by MountMgrSetAutoMount().

◆ ProcessSuggestedDriveLetters()

VOID ProcessSuggestedDriveLetters ( IN PDEVICE_EXTENSION  DeviceExtension)

Definition at line 403 of file device.c.

404 {
405  WCHAR NameBuffer[DRIVE_LETTER_LENGTH / sizeof(WCHAR)];
406  PLIST_ENTRY NextEntry;
408  PDEVICE_INFORMATION DeviceInformation;
409 
410  /* No devices? Nothing to do! */
411  if (IsListEmpty(&(DeviceExtension->DeviceListHead)))
412  {
413  return;
414  }
415 
416  /* For all the devices */
417  for (NextEntry = DeviceExtension->DeviceListHead.Flink;
418  NextEntry != &(DeviceExtension->DeviceListHead);
419  NextEntry = NextEntry->Flink)
420  {
421  DeviceInformation = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
422 
423  /* If no drive letter */
424  if (DeviceInformation->SuggestedDriveLetter == (UCHAR)-1)
425  {
426  /* Ensure it has no entry yet */
427  if (!HasDriveLetter(DeviceInformation) &&
428  !HasNoDriveLetterEntry(DeviceInformation->UniqueId))
429  {
430  /* And create one */
431  CreateNoDriveLetterEntry(DeviceInformation->UniqueId);
432  }
433 
434  DeviceInformation->SuggestedDriveLetter = 0;
435  }
436  /* Suggested letter & no entry */
437  else if (DeviceInformation->SuggestedDriveLetter &&
438  !HasNoDriveLetterEntry(DeviceInformation->UniqueId))
439  {
440  /* Just create a mount point */
441  SymbolicName.Buffer = NameBuffer;
443  NameBuffer[LETTER_POSITION] = DeviceInformation->SuggestedDriveLetter;
444  NameBuffer[COLON_POSITION] = L':';
447 
448  MountMgrCreatePointWorker(DeviceExtension, &SymbolicName, &(DeviceInformation->DeviceName));
449  }
450  }
451 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
UNICODE_STRING DosDevices
Definition: symlink.c:33
USHORT MaximumLength
Definition: env_spec_w32.h:370
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
#define LETTER_POSITION
Definition: mntmgr.h:159
NTSTATUS MountMgrCreatePointWorker(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicLinkName, IN PUNICODE_STRING DeviceName)
Definition: point.c:35
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
BOOLEAN HasNoDriveLetterEntry(IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: uniqueid.c:354
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char UCHAR
Definition: xmlstorage.h:181
VOID CreateNoDriveLetterEntry(IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: uniqueid.c:269
static const WCHAR L[]
Definition: oid.c:1250
Definition: typedefs.h:119
#define COLON_POSITION
Definition: mntmgr.h:160
BOOLEAN HasDriveLetter(IN PDEVICE_INFORMATION DeviceInformation)
Definition: mountmgr.c:88
UNICODE_STRING DeviceName
Definition: mntmgr.h:50
PMOUNTDEV_UNIQUE_ID UniqueId
Definition: mntmgr.h:49
#define DRIVE_LETTER_LENGTH
Definition: mntmgr.h:161
UCHAR SuggestedDriveLetter
Definition: mntmgr.h:52

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;
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 */
205  DatabasePath,
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
#define TRUE
Definition: types.h:120
_In_ PCWSTR _In_z_ PCWSTR _In_ ULONG ValueType
Definition: rtlfuncs.h:4154
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
#define FALSE
Definition: types.h:117
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4142
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:311
struct _DeviceInfo DeviceInfo
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
volatile int Continue
Definition: gdblib.c:102
char * PBOOLEAN
Definition: retypes.h:11
Status
Definition: gdiplustypes.h:24
_In_ GUID _In_ PVOID _In_ ULONG ValueLength
Definition: hubbusif.h:311
NTSYSAPI NTSTATUS WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR)
Definition: typedefs.h:119
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
PWSTR DatabasePath
Definition: database.c:31