ReactOS  0.4.15-dev-976-g0f66c66
mountmgr.c File Reference
#include "mntmgr.h"
#include <debug.h>
Include dependency graph for mountmgr.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define Cunc_LETTER_POSITION   4
 

Functions

BOOLEAN IsOffline (PUNICODE_STRING SymbolicName)
 
BOOLEAN HasDriveLetter (IN PDEVICE_INFORMATION DeviceInformation)
 
NTSTATUS CreateNewDriveLetterName (OUT PUNICODE_STRING DriveLetter, IN PUNICODE_STRING DeviceName, IN UCHAR Letter, IN PMOUNTDEV_UNIQUE_ID UniqueId OPTIONAL)
 
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)
 
NTSTATUS FindDeviceInfo (IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName, IN BOOLEAN DeviceNameGiven, OUT PDEVICE_INFORMATION *DeviceInformation)
 
VOID MountMgrFreeDeadDeviceInfo (IN PDEVICE_INFORMATION DeviceInformation)
 
VOID MountMgrFreeMountedDeviceInfo (IN PDEVICE_INFORMATION DeviceInformation)
 
VOID MountMgrFreeSavedLink (IN PSAVED_LINK_INFORMATION SavedLinkInformation)
 
VOID NTAPI MountMgrUnload (IN struct _DRIVER_OBJECT *DriverObject)
 
INIT_FUNCTION BOOLEAN MountmgrReadNoAutoMount (IN PUNICODE_STRING RegistryPath)
 
NTSTATUS MountMgrMountedDeviceArrival (IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName, IN BOOLEAN ManuallyRegistered)
 
VOID MountMgrMountedDeviceRemoval (IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName)
 
NTSTATUS NTAPI MountMgrMountedDeviceNotification (IN PVOID NotificationStructure, IN PVOID Context)
 
NTSTATUS NTAPI MountMgrCreateClose (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
VOID NTAPI MountMgrCancel (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI MountMgrCleanup (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI MountMgrShutdown (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
INIT_FUNCTION NTSTATUS NTAPI DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
 

Variables

GUID MountedDevicesGuid = {0x53F5630D, 0xB6BF, 0x11D0, {0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B}}
 
PDEVICE_OBJECT gdeviceObject
 
KEVENT UnloadEvent
 
LONG Unloading
 
static const WCHAR Cunc [] = L"\\??\\C:"
 

Macro Definition Documentation

◆ Cunc_LETTER_POSITION

#define Cunc_LETTER_POSITION   4

Definition at line 45 of file mountmgr.c.

◆ NDEBUG

#define NDEBUG

Definition at line 29 of file mountmgr.c.

Function Documentation

◆ CreateNewDriveLetterName()

NTSTATUS CreateNewDriveLetterName ( OUT PUNICODE_STRING  DriveLetter,
IN PUNICODE_STRING  DeviceName,
IN UCHAR  Letter,
IN PMOUNTDEV_UNIQUE_ID UniqueId  OPTIONAL 
)

Definition at line 113 of file mountmgr.c.

117 {
119 
120  /* Allocate a big enough buffer to contain the symbolic link */
121  DriveLetter->MaximumLength = DosDevices.Length + 3 * sizeof(WCHAR);
122  DriveLetter->Buffer = AllocatePool(DriveLetter->MaximumLength);
123  if (!DriveLetter->Buffer)
124  {
126  }
127 
128  /* Copy prefix */
129  RtlCopyUnicodeString(DriveLetter, &DosDevices);
130 
131  /* Update string to reflect real contents */
132  DriveLetter->Length = DosDevices.Length + 2 * sizeof(WCHAR);
133  DriveLetter->Buffer[DosDevices.Length / sizeof(WCHAR) + 2] = UNICODE_NULL;
134  DriveLetter->Buffer[DosDevices.Length / sizeof(WCHAR) + 1] = L':';
135 
136  /* If caller wants a no drive entry */
137  if (Letter == (UCHAR)-1)
138  {
139  /* Then, create a no letter entry */
140  CreateNoDriveLetterEntry(UniqueId);
141  FreePool(DriveLetter->Buffer);
142  return STATUS_UNSUCCESSFUL;
143  }
144  else if (Letter)
145  {
146  /* Use the letter given by the caller */
147  DriveLetter->Buffer[DosDevices.Length / sizeof(WCHAR)] = (WCHAR)Letter;
149  if (NT_SUCCESS(Status))
150  {
151  return Status;
152  }
153  }
154 
155  /* If caller didn't provide a letter, let's find one for him */
156 
158  {
159  /* If the device is a floppy, start with letter A */
160  Letter = 'A';
161  }
163  {
164  /* If the device is a CD-ROM, start with letter D */
165  Letter = 'D';
166  }
167  else
168  {
169  /* Finally, if it's a disk, use C */
170  Letter = 'C';
171  }
172 
173  /* Try to affect a letter (up to Z, ofc) until it's possible */
174  for (; Letter <= 'Z'; Letter++)
175  {
176  DriveLetter->Buffer[DosDevices.Length / sizeof(WCHAR)] = (WCHAR)Letter;
178  if (NT_SUCCESS(Status))
179  {
180  DPRINT("Assigned drive %c: to %wZ\n", Letter, DeviceName);
181  return Status;
182  }
183  }
184 
185  /* We failed to allocate a letter */
186  FreePool(DriveLetter->Buffer);
187  DPRINT("Failed to create a drive letter for %wZ\n", DeviceName);
188  return Status;
189 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
UNICODE_STRING DosDevices
Definition: symlink.c:33
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define FreePool(P)
Definition: mntmgr.h:154
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define UNICODE_NULL
UNICODE_STRING DeviceFloppy
Definition: symlink.c:34
void DPRINT(...)
Definition: polytest.cpp:61
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
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
WCHAR Letter
#define AllocatePool(Size)
Definition: mntmgr.h:153
NTSTATUS GlobalCreateSymbolicLink(IN PUNICODE_STRING DosName, IN PUNICODE_STRING DeviceName)
Definition: symlink.c:111
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
UNICODE_STRING DeviceCdRom
Definition: symlink.c:35

Referenced by MountMgrMountedDeviceArrival().

◆ DriverEntry()

INIT_FUNCTION NTSTATUS NTAPI DriverEntry ( IN PDRIVER_OBJECT  DriverObject,
IN PUNICODE_STRING  RegistryPath 
)

Definition at line 1799 of file mountmgr.c.

1801 {
1802  NTSTATUS Status;
1805 
1807 
1809  sizeof(DEVICE_EXTENSION),
1810  &DeviceMount,
1813  FALSE,
1814  &DeviceObject);
1815  if (!NT_SUCCESS(Status))
1816  {
1817  return Status;
1818  }
1819 
1821 
1824  DeviceExtension->DeviceObject = DeviceObject;
1825  DeviceExtension->DriverObject = DriverObject;
1826 
1827  InitializeListHead(&(DeviceExtension->DeviceListHead));
1828  InitializeListHead(&(DeviceExtension->OfflineDeviceListHead));
1829 
1830  KeInitializeSemaphore(&(DeviceExtension->DeviceLock), 1, 1);
1831  KeInitializeSemaphore(&(DeviceExtension->RemoteDatabaseLock), 1, 1);
1832 
1833  InitializeListHead(&(DeviceExtension->IrpListHead));
1834  DeviceExtension->EpicNumber = 1;
1835 
1836  InitializeListHead(&(DeviceExtension->SavedLinksListHead));
1837 
1838  InitializeListHead(&(DeviceExtension->WorkerQueueListHead));
1839  KeInitializeSemaphore(&(DeviceExtension->WorkerSemaphore), 0, MAXLONG);
1840  DeviceExtension->WorkerReferences = -1;
1841  KeInitializeSpinLock(&(DeviceExtension->WorkerLock));
1842 
1843  InitializeListHead(&(DeviceExtension->UniqueIdWorkerItemListHead));
1844  InitializeListHead(&(DeviceExtension->OnlineNotificationListHead));
1845  DeviceExtension->OnlineNotificationCount = 1;
1846 
1847  DeviceExtension->RegistryPath.Length = RegistryPath->Length;
1848  DeviceExtension->RegistryPath.MaximumLength = RegistryPath->Length + sizeof(WCHAR);
1849  DeviceExtension->RegistryPath.Buffer = AllocatePool(DeviceExtension->RegistryPath.MaximumLength);
1850  if (!DeviceExtension->RegistryPath.Buffer)
1851  {
1854  }
1855 
1857 
1858  DeviceExtension->NoAutoMount = MountmgrReadNoAutoMount(&(DeviceExtension->RegistryPath));
1859 
1861 
1862  /* Register for device arrival & removal. Ask to be notified for already
1863  * present devices
1864  */
1868  DriverObject,
1871  &(DeviceExtension->NotificationEntry));
1872 
1873  if (!NT_SUCCESS(Status))
1874  {
1876  return Status;
1877  }
1878 
1884 
1886 
1888  if (!NT_SUCCESS(Status))
1889  {
1891  }
1892 
1893  return Status;
1894 }
NTSTATUS NTAPI MountMgrCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: mountmgr.c:1652
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define FILE_DEVICE_NETWORK
Definition: winioctl.h:123
#define MAXLONG
Definition: umtypes.h:116
#define IRP_MJ_SHUTDOWN
NTSTATUS NTAPI MountMgrShutdown(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: mountmgr.c:1762
LONG NTSTATUS
Definition: precomp.h:26
#define PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES
Definition: iotypes.h:1203
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define FALSE
Definition: types.h:117
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:238
PVOID DeviceExtension
Definition: env_spec_w32.h:418
UNICODE_STRING DeviceMount
Definition: symlink.c:31
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
NTSYSAPI NTSTATUS NTAPI RtlCreateRegistryKey(_In_ ULONG RelativeTo, _In_ PWSTR Path)
PDEVICE_OBJECT gdeviceObject
Definition: mountmgr.c:40
_In_z_ PWSTR RegistryPath
Definition: classp.h:1930
VOID NTAPI KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, IN LONG Count, IN LONG Limit)
Definition: semphobj.c:22
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
Status
Definition: gdiplustypes.h:24
PDRIVER_UNLOAD DriverUnload
Definition: iotypes.h:2187
NTSTATUS NTAPI IoRegisterPlugPlayNotification(IN IO_NOTIFICATION_EVENT_CATEGORY EventCategory, IN ULONG EventCategoryFlags, IN PVOID EventCategoryData OPTIONAL, IN PDRIVER_OBJECT DriverObject, IN PDRIVER_NOTIFICATION_CALLBACK_ROUTINE CallbackRoutine, IN PVOID Context, OUT PVOID *NotificationEntry)
Definition: pnpnotify.c:249
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define AllocatePool(Size)
Definition: mntmgr.h:153
PWSTR DatabasePath
Definition: database.c:31
UNICODE_STRING DosDevicesMount
Definition: symlink.c:32
DRIVER_DISPATCH MountMgrDeviceControl
Definition: mntmgr.h:340
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1569
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
NTSTATUS NTAPI MountMgrMountedDeviceNotification(IN PVOID NotificationStructure, IN PVOID Context)
Definition: mountmgr.c:1616
NTSTATUS GlobalCreateSymbolicLink(IN PUNICODE_STRING DosName, IN PUNICODE_STRING DeviceName)
Definition: symlink.c:111
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
NTSTATUS NTAPI IoRegisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1694
#define IRP_MJ_CLEANUP
INIT_FUNCTION BOOLEAN MountmgrReadNoAutoMount(IN PUNICODE_STRING RegistryPath)
Definition: mountmgr.c:904
NTSTATUS NTAPI MountMgrCleanup(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: mountmgr.c:1701
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2188
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
VOID NTAPI MountMgrUnload(IN struct _DRIVER_OBJECT *DriverObject)
Definition: mountmgr.c:800
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
GUID MountedDevicesGuid
Definition: mountmgr.c:38

◆ FindDeviceInfo()

NTSTATUS FindDeviceInfo ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PUNICODE_STRING  SymbolicName,
IN BOOLEAN  DeviceNameGiven,
OUT PDEVICE_INFORMATION DeviceInformation 
)

Definition at line 642 of file mountmgr.c.

646 {
648  PLIST_ENTRY NextEntry;
651 
652  /* If a device name was given, use it */
653  if (DeviceNameGiven)
654  {
655  DeviceName.Length = SymbolicName->Length;
656  DeviceName.Buffer = SymbolicName->Buffer;
657  }
658  else
659  {
660  /* Otherwise, query it */
662  &DeviceName,
663  NULL, NULL,
664  NULL, NULL,
665  NULL, NULL);
666  if (!NT_SUCCESS(Status))
667  {
668  return Status;
669  }
670  }
671 
672  /* Look for device information matching devive */
673  for (NextEntry = DeviceExtension->DeviceListHead.Flink;
674  NextEntry != &(DeviceExtension->DeviceListHead);
675  NextEntry = NextEntry->Flink)
676  {
677  DeviceInfo = CONTAINING_RECORD(NextEntry,
679  DeviceListEntry);
680 
681  if (RtlEqualUnicodeString(&DeviceName, &(DeviceInfo->DeviceName), TRUE))
682  {
683  break;
684  }
685  }
686 
687  /* Release our buffer if required */
688  if (!DeviceNameGiven)
689  {
690  FreePool(DeviceName.Buffer);
691  }
692 
693  /* Return found information */
694  if (NextEntry == &(DeviceExtension->DeviceListHead))
695  {
697  }
698 
699  *DeviceInformation = DeviceInfo;
700  return STATUS_SUCCESS;
701 }
#define TRUE
Definition: types.h:120
_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
PVOID DeviceExtension
Definition: env_spec_w32.h:418
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 _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _DeviceInfo DeviceInfo
Status
Definition: gdiplustypes.h:24
Definition: typedefs.h:119
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
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
return STATUS_SUCCESS
Definition: btrfs.c:3014
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)

Referenced by MountMgrKeepLinksWhenOffline(), MountMgrQueryDosVolumePath(), MountMgrQueryDosVolumePaths(), MountMgrVolumeMountPointChanged(), MountMgrVolumeMountPointCreated(), MountMgrVolumeMountPointDeleted(), OnlineMountedVolumes(), QueryUniqueIdFromMaster(), and ReconcileThisDatabaseWithMasterWorker().

◆ HasDriveLetter()

BOOLEAN HasDriveLetter ( IN PDEVICE_INFORMATION  DeviceInformation)

Definition at line 88 of file mountmgr.c.

89 {
90  PLIST_ENTRY NextEntry;
91  PSYMLINK_INFORMATION SymlinkInfo;
92 
93  /* Browse all the symlinks to check if there is at least a drive letter */
94  for (NextEntry = DeviceInformation->SymbolicLinksListHead.Flink;
95  NextEntry != &DeviceInformation->SymbolicLinksListHead;
96  NextEntry = NextEntry->Flink)
97  {
98  SymlinkInfo = CONTAINING_RECORD(NextEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
99 
100  if (IsDriveLetter(&SymlinkInfo->Name) && SymlinkInfo->Online)
101  {
102  return TRUE;
103  }
104  }
105 
106  return FALSE;
107 }
#define TRUE
Definition: types.h:120
BOOLEAN IsDriveLetter(PUNICODE_STRING SymbolicName)
Definition: symlink.c:922
#define FALSE
Definition: types.h:117
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
Definition: typedefs.h:119

Referenced by MountMgrCreatePointWorker(), and ProcessSuggestedDriveLetters().

◆ IsOffline()

BOOLEAN IsOffline ( PUNICODE_STRING  SymbolicName)

Definition at line 51 of file mountmgr.c.

52 {
56 
57  /* Prepare to look in the registry to see if
58  * given volume is offline
59  */
65  QueryTable[0].DefaultLength = sizeof(ULONG);
67 
68  Default = 0;
69 
70  /* Query status */
73  QueryTable,
74  NULL,
75  NULL);
76  if (!NT_SUCCESS(Status))
77  {
78  IsOffline = 0;
79  }
80 
81  return (IsOffline != 0);
82 }
_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)
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
LONG NTSTATUS
Definition: precomp.h:26
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOLEAN IsOffline(PUNICODE_STRING SymbolicName)
Definition: mountmgr.c:51
Status
Definition: gdiplustypes.h:24
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
PWSTR OfflinePath
Definition: database.c:32
#define REG_DWORD
Definition: sdbapi.c:596
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144

Referenced by MountMgrMountedDeviceArrival().

◆ MountMgrCancel()

VOID NTAPI MountMgrCancel ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 1682 of file mountmgr.c.

1684 {
1686 
1687  RemoveEntryList(&(Irp->Tail.Overlay.ListEntry));
1688 
1689  IoReleaseCancelSpinLock(Irp->CancelIrql);
1690 
1691  Irp->IoStatus.Information = 0;
1692  Irp->IoStatus.Status = STATUS_CANCELLED;
1694 }
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define IoCompleteRequest
Definition: irp.c:1240
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1569
#define IO_NO_INCREMENT
Definition: iotypes.h:570

Referenced by MountMgrChangeNotify(), and MountMgrCleanup().

◆ MountMgrCleanup()

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

Definition at line 1701 of file mountmgr.c.

1703 {
1704  PIRP ListIrp;
1705  KIRQL OldIrql;
1706  PLIST_ENTRY NextEntry;
1708  PIO_STACK_LOCATION Stack;
1710 
1713  FileObject = Stack->FileObject;
1714 
1716 
1717  /* If IRP list if empty, it's OK */
1718  if (IsListEmpty(&(DeviceExtension->IrpListHead)))
1719  {
1721 
1722  Irp->IoStatus.Status = STATUS_SUCCESS;
1723  Irp->IoStatus.Information = 0;
1725 
1726  return STATUS_SUCCESS;
1727  }
1728 
1729  /* Otherwise, cancel all the IRPs */
1730  NextEntry = DeviceExtension->IrpListHead.Flink;
1731  do
1732  {
1733  ListIrp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
1735  {
1736  ListIrp->Cancel = TRUE;
1737  ListIrp->CancelIrql = OldIrql;
1738  ListIrp->CancelRoutine = NULL;
1739  MountMgrCancel(DeviceObject, ListIrp);
1740 
1742  }
1743 
1744  NextEntry = NextEntry->Flink;
1745  }
1746  while (NextEntry != &(DeviceExtension->IrpListHead));
1747 
1749 
1750  Irp->IoStatus.Status = STATUS_SUCCESS;
1751  Irp->IoStatus.Information = 0;
1753 
1754  return STATUS_SUCCESS;
1755 }
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
VOID NTAPI MountMgrCancel(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: mountmgr.c:1682
VOID NTAPI IoAcquireCancelSpinLock(OUT PKIRQL Irql)
Definition: util.c:56
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
UCHAR KIRQL
Definition: env_spec_w32.h:591
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:588
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
* PFILE_OBJECT
Definition: iotypes.h:1962
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
Definition: typedefs.h:119
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1569
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
PFILE_OBJECT FileObject
Definition: iotypes.h:2820
#define IO_NO_INCREMENT
Definition: iotypes.h:570
return STATUS_SUCCESS
Definition: btrfs.c:3014

Referenced by DriverEntry().

◆ MountMgrCreateClose()

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

Definition at line 1652 of file mountmgr.c.

1654 {
1655  PIO_STACK_LOCATION Stack;
1657 
1659 
1661 
1662  /* Allow driver opening for communication
1663  * as long as it's not taken for a directory
1664  */
1665  if (Stack->MajorFunction == IRP_MJ_CREATE &&
1666  Stack->Parameters.Create.Options & FILE_DIRECTORY_FILE)
1667  {
1669  }
1670 
1671  Irp->IoStatus.Status = Status;
1672  Irp->IoStatus.Information = 0;
1674  return Status;
1675 }
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169
#define IoCompleteRequest
Definition: irp.c:1240
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1569
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define IO_NO_INCREMENT
Definition: iotypes.h:570
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2779
return STATUS_SUCCESS
Definition: btrfs.c:3014
HRESULT Create([out]ITransactionReceiver **ppReceiver)

Referenced by DriverEntry().

◆ MountMgrFreeDeadDeviceInfo()

VOID MountMgrFreeDeadDeviceInfo ( IN PDEVICE_INFORMATION  DeviceInformation)

Definition at line 707 of file mountmgr.c.

708 {
709  FreePool(DeviceInformation->SymbolicName.Buffer);
710  FreePool(DeviceInformation);
711 }
#define FreePool(P)
Definition: mntmgr.h:154

Referenced by MountMgrCheckUnprocessedVolumes(), MountMgrMountedDeviceArrival(), MountMgrMountedDeviceRemoval(), and MountMgrUnload().

◆ MountMgrFreeMountedDeviceInfo()

VOID MountMgrFreeMountedDeviceInfo ( IN PDEVICE_INFORMATION  DeviceInformation)

Definition at line 717 of file mountmgr.c.

718 {
719  PLIST_ENTRY NextEntry;
720  PSYMLINK_INFORMATION SymLink;
721  PUNIQUE_ID_REPLICATE UniqueId;
722  PASSOCIATED_DEVICE_ENTRY AssociatedDevice;
723 
724  /* Purge symbolic links list */
725  while (!IsListEmpty(&(DeviceInformation->SymbolicLinksListHead)))
726  {
727  NextEntry = RemoveHeadList(&(DeviceInformation->SymbolicLinksListHead));
728  SymLink = CONTAINING_RECORD(NextEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
729 
730  GlobalDeleteSymbolicLink(&(SymLink->Name));
731  FreePool(SymLink->Name.Buffer);
732  }
733 
734  /* Purge replicated unique IDs list */
735  while (!IsListEmpty(&(DeviceInformation->ReplicatedUniqueIdsListHead)))
736  {
737  NextEntry = RemoveHeadList(&(DeviceInformation->ReplicatedUniqueIdsListHead));
738  UniqueId = CONTAINING_RECORD(NextEntry, UNIQUE_ID_REPLICATE, ReplicatedUniqueIdsListEntry);
739 
740  FreePool(UniqueId->UniqueId);
741  FreePool(UniqueId);
742  }
743 
744  while (!IsListEmpty(&(DeviceInformation->AssociatedDevicesHead)))
745  {
746  NextEntry = RemoveHeadList(&(DeviceInformation->AssociatedDevicesHead));
747  AssociatedDevice = CONTAINING_RECORD(NextEntry, ASSOCIATED_DEVICE_ENTRY, AssociatedDevicesEntry);
748 
749  FreePool(AssociatedDevice->String.Buffer);
750  FreePool(AssociatedDevice);
751  }
752 
753  /* Free the rest of the buffers */
754  FreePool(DeviceInformation->SymbolicName.Buffer);
755  if (DeviceInformation->KeepLinks)
756  {
757  FreePool(DeviceInformation->UniqueId);
758  }
759  FreePool(DeviceInformation->DeviceName.Buffer);
760 
761  /* Finally, stop waiting for notifications for this device */
762  if (DeviceInformation->TargetDeviceNotificationEntry)
763  {
764  IoUnregisterPlugPlayNotification(DeviceInformation->TargetDeviceNotificationEntry);
765  }
766 }
NTSTATUS NTAPI IoUnregisterPlugPlayNotification(IN PVOID NotificationEntry)
Definition: pnpnotify.c:371
PMOUNTDEV_UNIQUE_ID UniqueId
Definition: mntmgr.h:82
NTSTATUS GlobalDeleteSymbolicLink(IN PUNICODE_STRING DosName)
Definition: symlink.c:136
#define FreePool(P)
Definition: mntmgr.h:154
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
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
Definition: mntmgr.h:95
Definition: typedefs.h:119
UNICODE_STRING String
Definition: mntmgr.h:99

◆ MountMgrFreeSavedLink()

VOID MountMgrFreeSavedLink ( IN PSAVED_LINK_INFORMATION  SavedLinkInformation)

Definition at line 772 of file mountmgr.c.

773 {
774  PLIST_ENTRY NextEntry;
775  PSYMLINK_INFORMATION SymlinkInformation;
776 
777  /* For all the saved links */
778  while (!IsListEmpty(&(SavedLinkInformation->SymbolicLinksListHead)))
779  {
780  NextEntry = RemoveHeadList(&(SavedLinkInformation->SymbolicLinksListHead));
781  SymlinkInformation = CONTAINING_RECORD(NextEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
782 
783  /* Remove from system & free */
784  GlobalDeleteSymbolicLink(&(SymlinkInformation->Name));
785  FreePool(SymlinkInformation->Name.Buffer);
786  FreePool(SymlinkInformation);
787  }
788 
789  /* And free unique ID & entry */
790  FreePool(SavedLinkInformation->UniqueId);
791  FreePool(SavedLinkInformation);
792 }
NTSTATUS GlobalDeleteSymbolicLink(IN PUNICODE_STRING DosName)
Definition: symlink.c:136
#define FreePool(P)
Definition: mntmgr.h:154
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
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
Definition: typedefs.h:119

Referenced by MountMgrMountedDeviceArrival(), and MountMgrUnload().

◆ MountMgrMountedDeviceArrival()

NTSTATUS MountMgrMountedDeviceArrival ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PUNICODE_STRING  SymbolicName,
IN BOOLEAN  ManuallyRegistered 
)

Definition at line 937 of file mountmgr.c.

940 {
941  WCHAR Letter;
942  GUID StableGuid;
943  HANDLE LinkHandle;
944  ULONG SymLinkCount, i;
945  PLIST_ENTRY NextEntry;
946  PUNICODE_STRING SymLinks;
947  NTSTATUS Status, IntStatus;
949  PSYMLINK_INFORMATION SymlinkInformation;
950  PMOUNTDEV_UNIQUE_ID UniqueId, NewUniqueId;
951  PSAVED_LINK_INFORMATION SavedLinkInformation;
952  PDEVICE_INFORMATION DeviceInformation, CurrentDevice;
953  WCHAR CSymLinkBuffer[RTL_NUMBER_OF(Cunc)], LinkTargetBuffer[MAX_PATH];
954  UNICODE_STRING TargetDeviceName, SuggestedLinkName, DeviceName, VolumeName, DriveLetter, LinkTarget, CSymLink;
955  BOOLEAN HasGuid, HasGptDriveLetter, Valid, UseOnlyIfThereAreNoOtherLinks, IsDrvLetter, IsOff, IsVolumeName, LinkError;
956 
957  /* New device = new structure to represent it */
958  DeviceInformation = AllocatePool(sizeof(DEVICE_INFORMATION));
959  if (!DeviceInformation)
960  {
962  }
963 
964  /* Initialise device structure */
965  RtlZeroMemory(DeviceInformation, sizeof(DEVICE_INFORMATION));
966  InitializeListHead(&(DeviceInformation->SymbolicLinksListHead));
967  InitializeListHead(&(DeviceInformation->ReplicatedUniqueIdsListHead));
968  InitializeListHead(&(DeviceInformation->AssociatedDevicesHead));
969  DeviceInformation->SymbolicName.Length = SymbolicName->Length;
970  DeviceInformation->SymbolicName.MaximumLength = SymbolicName->Length + sizeof(UNICODE_NULL);
971  DeviceInformation->SymbolicName.Buffer = AllocatePool(DeviceInformation->SymbolicName.MaximumLength);
972  if (!DeviceInformation->SymbolicName.Buffer)
973  {
974  FreePool(DeviceInformation);
976  }
977 
978  /* Copy symbolic name */
980  DeviceInformation->SymbolicName.Buffer[DeviceInformation->SymbolicName.Length / sizeof(WCHAR)] = UNICODE_NULL;
981  DeviceInformation->ManuallyRegistered = ManuallyRegistered;
982  DeviceInformation->DeviceExtension = DeviceExtension;
983 
984  /* Query as much data as possible about device */
986  &TargetDeviceName,
987  &UniqueId,
988  &(DeviceInformation->Removable),
989  &HasGptDriveLetter,
990  &HasGuid,
991  &StableGuid,
992  &Valid);
993  if (!NT_SUCCESS(Status))
994  {
996 
997  for (NextEntry = DeviceExtension->OfflineDeviceListHead.Flink;
998  NextEntry != &(DeviceExtension->OfflineDeviceListHead);
999  NextEntry = NextEntry->Flink)
1000  {
1001  CurrentDevice = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
1002 
1003  if (RtlEqualUnicodeString(&(DeviceInformation->SymbolicName), &(CurrentDevice->SymbolicName), TRUE))
1004  {
1005  break;
1006  }
1007  }
1008 
1009  if (NextEntry != &(DeviceExtension->OfflineDeviceListHead))
1010  {
1011  MountMgrFreeDeadDeviceInfo(DeviceInformation);
1012  }
1013  else
1014  {
1015  InsertTailList(&(DeviceExtension->OfflineDeviceListHead), &(DeviceInformation->DeviceListEntry));
1016  }
1017 
1019 
1020  return Status;
1021  }
1022 
1023  /* Save gathered data */
1024  DeviceInformation->UniqueId = UniqueId;
1025  DeviceInformation->DeviceName = TargetDeviceName;
1026  DeviceInformation->KeepLinks = FALSE;
1027 
1028  /* If we found system partition, mark it */
1029  if (DeviceExtension->DriveLetterData && UniqueId->UniqueIdLength == DeviceExtension->DriveLetterData->UniqueIdLength)
1030  {
1031  if (RtlCompareMemory(UniqueId->UniqueId, DeviceExtension->DriveLetterData->UniqueId, UniqueId->UniqueIdLength)
1032  == UniqueId->UniqueIdLength)
1033  {
1034  IoSetSystemPartition(&TargetDeviceName);
1035  }
1036  }
1037 
1038  /* Check suggested link name */
1039  Status = QuerySuggestedLinkName(&(DeviceInformation->SymbolicName),
1040  &SuggestedLinkName,
1041  &UseOnlyIfThereAreNoOtherLinks);
1042  if (!NT_SUCCESS(Status))
1043  {
1044  SuggestedLinkName.Buffer = NULL;
1045  }
1046 
1047  /* If it's OK, set it and save its letter (if any) */
1048  if (SuggestedLinkName.Buffer && IsDriveLetter(&SuggestedLinkName))
1049  {
1050  DeviceInformation->SuggestedDriveLetter = (UCHAR)SuggestedLinkName.Buffer[LETTER_POSITION];
1051  }
1052 
1053  /* Acquire driver exclusively */
1055 
1056  /* Check if we already have device in to prevent double registration */
1057  for (NextEntry = DeviceExtension->DeviceListHead.Flink;
1058  NextEntry != &(DeviceExtension->DeviceListHead);
1059  NextEntry = NextEntry->Flink)
1060  {
1061  CurrentDevice = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
1062 
1063  if (RtlEqualUnicodeString(&(CurrentDevice->DeviceName), &TargetDeviceName, TRUE))
1064  {
1065  break;
1066  }
1067  }
1068 
1069  /* If we found it, clear ours, and return success, all correct */
1070  if (NextEntry != &(DeviceExtension->DeviceListHead))
1071  {
1072  if (SuggestedLinkName.Buffer)
1073  {
1074  FreePool(SuggestedLinkName.Buffer);
1075  }
1076 
1077  FreePool(UniqueId);
1078  FreePool(TargetDeviceName.Buffer);
1079  FreePool(DeviceInformation->DeviceName.Buffer);
1080  FreePool(DeviceInformation);
1081 
1083 
1084  return STATUS_SUCCESS;
1085  }
1086 
1087  /* Check if there are symlinks associated with our device in registry */
1089  DeviceInformation,
1090  (SuggestedLinkName.Buffer) ? &SuggestedLinkName : NULL,
1091  UseOnlyIfThereAreNoOtherLinks,
1092  &SymLinks,
1093  &SymLinkCount,
1094  HasGuid,
1095  &StableGuid);
1096 
1097  /* If our device is a CD-ROM */
1098  if (RtlPrefixUnicodeString(&DeviceCdRom, &TargetDeviceName, TRUE))
1099  {
1100  LinkTarget.Length = 0;
1101  LinkTarget.MaximumLength = sizeof(LinkTargetBuffer);
1102  LinkTarget.Buffer = LinkTargetBuffer;
1103 
1104  RtlCopyMemory(CSymLinkBuffer, Cunc, sizeof(Cunc));
1105  RtlInitUnicodeString(&CSymLink, CSymLinkBuffer);
1106 
1107  /* Start checking all letters that could have been associated */
1108  for (Letter = L'D'; Letter <= L'Z'; Letter++)
1109  {
1110  CSymLink.Buffer[Cunc_LETTER_POSITION] = Letter;
1111 
1113  &CSymLink,
1115  NULL,
1116  NULL);
1117 
1118  /* Try to open the associated symlink */
1120  if (!NT_SUCCESS(Status))
1121  {
1122  continue;
1123  }
1124 
1125  /* And query its target */
1126  Status = ZwQuerySymbolicLinkObject(LinkHandle, &LinkTarget, NULL);
1127  ZwClose(LinkHandle);
1128 
1129  if (!NT_SUCCESS(Status))
1130  {
1131  continue;
1132  }
1133 
1134  IntStatus = STATUS_UNSUCCESSFUL;
1135  if (!RtlEqualUnicodeString(&LinkTarget, &DeviceInformation->DeviceName, FALSE))
1136  {
1137  continue;
1138  }
1139 
1140  /* This link is matching our device, whereas it's not supposed to have any
1141  * symlink associated.
1142  * Delete it
1143  */
1144  if (!SymLinkCount)
1145  {
1146  IoDeleteSymbolicLink(&CSymLink);
1147  continue;
1148  }
1149 
1150  /* Now, for all the symlinks, check for ours */
1151  for (i = 0; i < SymLinkCount; i++)
1152  {
1153  if (IsDriveLetter(&(SymLinks[i])))
1154  {
1155  /* If it exists, that's correct */
1156  if (SymLinks[i].Buffer[LETTER_POSITION] == Letter)
1157  {
1158  IntStatus = STATUS_SUCCESS;
1159  }
1160  }
1161  }
1162 
1163  /* Useless link, delete it */
1164  if (IntStatus == STATUS_UNSUCCESSFUL)
1165  {
1166  IoDeleteSymbolicLink(&CSymLink);
1167  }
1168  }
1169  }
1170 
1171  /* Suggested name is no longer required */
1172  if (SuggestedLinkName.Buffer)
1173  {
1174  FreePool(SuggestedLinkName.Buffer);
1175  }
1176 
1177  /* If if failed, ensure we don't take symlinks into account */
1178  if (!NT_SUCCESS(Status))
1179  {
1180  SymLinks = NULL;
1181  SymLinkCount = 0;
1182  }
1183 
1184  /* Now we queried them, remove the symlinks */
1185  SavedLinkInformation = RemoveSavedLinks(DeviceExtension, UniqueId);
1186 
1187  IsDrvLetter = FALSE;
1188  IsOff = FALSE;
1189  IsVolumeName = FALSE;
1190  /* For all the symlinks */
1191  for (i = 0; i < SymLinkCount; i++)
1192  {
1193  /* Check if our device is a volume */
1194  if (MOUNTMGR_IS_VOLUME_NAME(&(SymLinks[i])))
1195  {
1196  IsVolumeName = TRUE;
1197  }
1198  /* If it has a drive letter */
1199  else if (IsDriveLetter(&(SymLinks[i])))
1200  {
1201  if (IsDrvLetter)
1202  {
1203  DeleteFromLocalDatabase(&(SymLinks[i]), UniqueId);
1204  continue;
1205  }
1206  else
1207  {
1208  IsDrvLetter = TRUE;
1209  }
1210  }
1211 
1212  /* And recreate the symlink to our device */
1213  Status = GlobalCreateSymbolicLink(&(SymLinks[i]), &TargetDeviceName);
1214  if (!NT_SUCCESS(Status))
1215  {
1216  LinkError = TRUE;
1217 
1218  if ((SavedLinkInformation && !RedirectSavedLink(SavedLinkInformation, &(SymLinks[i]), &TargetDeviceName)) ||
1219  !SavedLinkInformation)
1220  {
1221  Status = QueryDeviceInformation(&(SymLinks[i]), &DeviceName, NULL, NULL, NULL, NULL, NULL, NULL);
1222  if (NT_SUCCESS(Status))
1223  {
1224  LinkError = RtlEqualUnicodeString(&TargetDeviceName, &DeviceName, TRUE);
1225  FreePool(DeviceName.Buffer);
1226  }
1227 
1228  if (!LinkError)
1229  {
1230  if (IsDriveLetter(&(SymLinks[i])))
1231  {
1232  IsDrvLetter = FALSE;
1233  DeleteFromLocalDatabase(&(SymLinks[i]), UniqueId);
1234  }
1235 
1236  FreePool(SymLinks[i].Buffer);
1237  continue;
1238  }
1239  }
1240  }
1241 
1242  /* Check if was offline */
1243  if (IsOffline(&(SymLinks[i])))
1244  {
1245  IsOff = TRUE;
1246  }
1247 
1248  /* Finally, associate this symlink with the device */
1249  SymlinkInformation = AllocatePool(sizeof(SYMLINK_INFORMATION));
1250  if (!SymlinkInformation)
1251  {
1252  GlobalDeleteSymbolicLink(&(SymLinks[i]));
1253  FreePool(SymLinks[i].Buffer);
1254  continue;
1255  }
1256 
1257  SymlinkInformation->Name = SymLinks[i];
1258  SymlinkInformation->Online = TRUE;
1259 
1260  InsertTailList(&(DeviceInformation->SymbolicLinksListHead),
1261  &(SymlinkInformation->SymbolicLinksListEntry));
1262  }
1263 
1264  /* Now, for all the recreated symlinks, notify their recreation */
1265  for (NextEntry = DeviceInformation->SymbolicLinksListHead.Flink;
1266  NextEntry != &(DeviceInformation->SymbolicLinksListHead);
1267  NextEntry = NextEntry->Flink)
1268  {
1269  SymlinkInformation = CONTAINING_RECORD(NextEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
1270 
1271  SendLinkCreated(&(SymlinkInformation->Name));
1272  }
1273 
1274  /* If we had saved links, it's time to free them */
1275  if (SavedLinkInformation)
1276  {
1277  MountMgrFreeSavedLink(SavedLinkInformation);
1278  }
1279 
1280  /* If our device doesn't have a volume name */
1281  if (!IsVolumeName)
1282  {
1283  /* It's time to create one */
1285  if (NT_SUCCESS(Status))
1286  {
1287  /* Write it to global database */
1289  DatabasePath,
1291  REG_BINARY,
1292  UniqueId->UniqueId,
1293  UniqueId->UniqueIdLength);
1294 
1295  /* And create the symlink */
1296  GlobalCreateSymbolicLink(&VolumeName, &TargetDeviceName);
1297 
1298  SymlinkInformation = AllocatePool(sizeof(SYMLINK_INFORMATION));
1299  if (!SymlinkInformation)
1300  {
1302  }
1303  /* Finally, associate it with the device and notify creation */
1304  else
1305  {
1306  SymlinkInformation->Name = VolumeName;
1307  SymlinkInformation->Online = TRUE;
1308  InsertTailList(&(DeviceInformation->SymbolicLinksListHead),
1309  &(SymlinkInformation->SymbolicLinksListEntry));
1310 
1312  }
1313  }
1314  }
1315 
1316  /* If we found a drive letter, then, ignore the suggested one */
1317  if (IsDrvLetter)
1318  {
1319  DeviceInformation->SuggestedDriveLetter = 0;
1320  }
1321  /* Else, it's time to set up one */
1322  else if ((DeviceExtension->NoAutoMount || DeviceInformation->Removable) &&
1323  DeviceExtension->AutomaticDriveLetter &&
1324  (HasGptDriveLetter || DeviceInformation->SuggestedDriveLetter) &&
1325  !HasNoDriveLetterEntry(UniqueId))
1326  {
1327  /* Create a new drive letter */
1328  Status = CreateNewDriveLetterName(&DriveLetter, &TargetDeviceName,
1329  DeviceInformation->SuggestedDriveLetter,
1330  NULL);
1331  if (!NT_SUCCESS(Status))
1332  {
1333  CreateNoDriveLetterEntry(UniqueId);
1334  }
1335  else
1336  {
1337  /* Save it to global database */
1339  DatabasePath,
1340  DriveLetter.Buffer,
1341  REG_BINARY,
1342  UniqueId->UniqueId,
1343  UniqueId->UniqueIdLength);
1344 
1345  /* Associate it with the device and notify creation */
1346  SymlinkInformation = AllocatePool(sizeof(SYMLINK_INFORMATION));
1347  if (!SymlinkInformation)
1348  {
1349  FreePool(DriveLetter.Buffer);
1350  }
1351  else
1352  {
1353  SymlinkInformation->Name = DriveLetter;
1354  SymlinkInformation->Online = TRUE;
1355  InsertTailList(&(DeviceInformation->SymbolicLinksListHead),
1356  &(SymlinkInformation->SymbolicLinksListEntry));
1357 
1358  SendLinkCreated(&DriveLetter);
1359  }
1360  }
1361  }
1362 
1363  /* If that's a PnP device, register for notifications */
1364  if (!ManuallyRegistered)
1365  {
1367  }
1368 
1369  /* Finally, insert the device into our devices list */
1370  InsertTailList(&(DeviceExtension->DeviceListHead), &(DeviceInformation->DeviceListEntry));
1371 
1372  /* Copy device unique ID */
1373  NewUniqueId = AllocatePool(UniqueId->UniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
1374  if (NewUniqueId)
1375  {
1376  NewUniqueId->UniqueIdLength = UniqueId->UniqueIdLength;
1377  RtlCopyMemory(NewUniqueId->UniqueId, UniqueId->UniqueId, UniqueId->UniqueIdLength);
1378  }
1379 
1380  /* If device's offline or valid, skip its notifications */
1381  if (IsOff || Valid)
1382  {
1383  DeviceInformation->SkipNotifications = TRUE;
1384  }
1385 
1386  /* In case device is valid and is set to no automount,
1387  * set it offline.
1388  */
1389  if (DeviceExtension->NoAutoMount || IsDrvLetter)
1390  {
1391  IsOff = !DeviceInformation->SkipNotifications;
1392  }
1393  else
1394  {
1395  IsOff = FALSE;
1396  }
1397 
1398  /* Finally, release the exclusive lock */
1400 
1401  /* If device is not offline, notify its arrival */
1402  if (!IsOff)
1403  {
1405  }
1406 
1407  /* If we had symlinks (from storage), free them */
1408  if (SymLinks)
1409  {
1410  FreePool(SymLinks);
1411  }
1412 
1413  /* Notify about unique id change */
1414  if (NewUniqueId)
1415  {
1417  FreePool(NewUniqueId);
1418  }
1419 
1420  /* If this drive was set to have a drive letter automatically
1421  * Now it's back, local databases sync will be required
1422  */
1423  if (DeviceExtension->AutomaticDriveLetter)
1424  {
1426 
1428 
1429  NextEntry = DeviceExtension->DeviceListHead.Flink;
1430  CurrentDevice = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
1431  while (CurrentDevice != DeviceInformation)
1432  {
1433  if (!CurrentDevice->NoDatabase)
1434  {
1436  }
1437 
1438  NextEntry = NextEntry->Flink;
1439  CurrentDevice = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
1440  }
1441 
1443  }
1444 
1445  return STATUS_SUCCESS;
1446 }
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
VOID DeleteFromLocalDatabase(IN PUNICODE_STRING SymbolicLink, IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: database.c:351
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
USHORT MaximumLength
Definition: env_spec_w32.h:370
VOID MountMgrFreeDeadDeviceInfo(IN PDEVICE_INFORMATION DeviceInformation)
Definition: mountmgr.c:707
#define REG_BINARY
Definition: nt_native.h:1496
#define TRUE
Definition: types.h:120
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSTATUS GlobalDeleteSymbolicLink(IN PUNICODE_STRING DosName)
Definition: symlink.c:136
VOID SendOnlineNotification(IN PUNICODE_STRING SymbolicName)
Definition: notify.c:38
_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 RegisterForTargetDeviceNotification(IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation)
Definition: notify.c:275
#define LETTER_POSITION
Definition: mntmgr.h:159
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define InsertTailList(ListHead, Entry)
NTSTATUS CreateNewVolumeName(OUT PUNICODE_STRING VolumeName, IN PGUID VolumeGuid OPTIONAL)
Definition: symlink.c:462
#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 OBJ_KERNEL_HANDLE
Definition: winternl.h:231
UNICODE_STRING SymbolicName
Definition: mntmgr.h:48
VOID MountMgrFreeSavedLink(IN PSAVED_LINK_INFORMATION SavedLinkInformation)
Definition: mountmgr.c:772
BOOLEAN HasNoDriveLetterEntry(IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: uniqueid.c:354
_Inout_ PUNICODE_STRING LinkTarget
Definition: zwfuncs.h:292
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
VOID ReconcileThisDatabaseWithMaster(IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation)
Definition: database.c:1613
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG, PCWSTR, PCWSTR, ULONG, PVOID, ULONG)
#define MOUNTMGR_IS_VOLUME_NAME(s)
Definition: mountmgr.h:61
BOOLEAN NoDatabase
Definition: mntmgr.h:57
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
PDEVICE_EXTENSION DeviceExtension
Definition: mntmgr.h:62
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 NTAPI IoSetSystemPartition(IN PUNICODE_STRING VolumeNameString)
Definition: volume.c:1231
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
BOOLEAN KeepLinks
Definition: mntmgr.h:51
BOOLEAN SkipNotifications
Definition: mntmgr.h:58
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define MAX_PATH
Definition: compat.h:34
LIST_ENTRY SymbolicLinksListHead
Definition: mntmgr.h:45
NTSTATUS QuerySuggestedLinkName(IN PUNICODE_STRING SymbolicName, OUT PUNICODE_STRING SuggestedLinkName, OUT PBOOLEAN UseOnlyIfThereAreNoOtherLinks)
Definition: symlink.c:684
NTSTATUS QuerySymbolicLinkNamesFromStorage(IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation, IN PUNICODE_STRING SuggestedLinkName, IN BOOLEAN UseOnlyIfThereAreNoOtherLinks, OUT PUNICODE_STRING *SymLinks, OUT PULONG SymLinkCount, IN BOOLEAN HasGuid, IN LPGUID Guid)
Definition: symlink.c:514
BOOLEAN IsOffline(PUNICODE_STRING SymbolicName)
Definition: mountmgr.c:51
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
unsigned char UCHAR
Definition: xmlstorage.h:181
VOID CreateNoDriveLetterEntry(IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: uniqueid.c:269
static const WCHAR Cunc[]
Definition: mountmgr.c:44
Status
Definition: gdiplustypes.h:24
static const WCHAR L[]
Definition: oid.c:1250
NTSTATUS CreateNewDriveLetterName(OUT PUNICODE_STRING DriveLetter, IN PUNICODE_STRING DeviceName, IN UCHAR Letter, IN PMOUNTDEV_UNIQUE_ID UniqueId OPTIONAL)
Definition: mountmgr.c:113
WCHAR Letter
Definition: typedefs.h:119
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
BOOLEAN ManuallyRegistered
Definition: mntmgr.h:53
#define AllocatePool(Size)
Definition: mntmgr.h:153
PWSTR DatabasePath
Definition: database.c:31
PSAVED_LINK_INFORMATION RemoveSavedLinks(IN PDEVICE_EXTENSION DeviceExtension, IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: symlink.c:640
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
BOOLEAN Removable
Definition: mntmgr.h:54
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
NTSTATUS GlobalCreateSymbolicLink(IN PUNICODE_STRING DosName, IN PUNICODE_STRING DeviceName)
Definition: symlink.c:111
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
UNICODE_STRING DeviceName
Definition: mntmgr.h:50
_Must_inspect_result_ _Inout_opt_ PUNICODE_STRING VolumeName
Definition: fltkernel.h:1117
LIST_ENTRY ReplicatedUniqueIdsListHead
Definition: mntmgr.h:46
LIST_ENTRY DeviceListEntry
Definition: mntmgr.h:44
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:570
#define SYMBOLIC_LINK_QUERY
Definition: nt_native.h:1265
LIST_ENTRY AssociatedDevicesHead
Definition: mntmgr.h:47
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
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
VOID SendLinkCreated(IN PUNICODE_STRING SymbolicName)
Definition: symlink.c:160
return STATUS_SUCCESS
Definition: btrfs.c:3014
PMOUNTDEV_UNIQUE_ID UniqueId
Definition: mntmgr.h:49
VOID IssueUniqueIdChangeNotify(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName, IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: notify.c:662
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
UCHAR UniqueId[1]
Definition: imports.h:139
#define Cunc_LETTER_POSITION
Definition: mountmgr.c:45
UCHAR SuggestedDriveLetter
Definition: mntmgr.h:52
NTSYSAPI NTSTATUS NTAPI ZwOpenSymbolicLinkObject(_Out_ PHANDLE SymbolicLinkHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
UNICODE_STRING DeviceCdRom
Definition: symlink.c:35
BOOLEAN RedirectSavedLink(IN PSAVED_LINK_INFORMATION SavedLinkInformation, IN PUNICODE_STRING DosName, IN PUNICODE_STRING NewLink)
Definition: symlink.c:827

Referenced by MountMgrCheckUnprocessedVolumes(), MountMgrMountedDeviceNotification(), and MountMgrVolumeArrivalNotification().

◆ MountMgrMountedDeviceNotification()

NTSTATUS NTAPI MountMgrMountedDeviceNotification ( IN PVOID  NotificationStructure,
IN PVOID  Context 
)

Definition at line 1616 of file mountmgr.c.

1618 {
1619  BOOLEAN OldState;
1622 
1623  /* Notification for a device arrived */
1624  /* Disable hard errors */
1627 
1629  Notification = NotificationStructure;
1630 
1631  /* Dispatch according to the event */
1632  if (IsEqualGUID(&(Notification->Event), &GUID_DEVICE_INTERFACE_ARRIVAL))
1633  {
1635  }
1636  else if (IsEqualGUID(&(Notification->Event), &GUID_DEVICE_INTERFACE_REMOVAL))
1637  {
1639  }
1640 
1641  /* Reset hard errors */
1643 
1644  return STATUS_SUCCESS;
1645 }
_In_ PVOID NotificationStructure
Definition: iofuncs.h:1203
const GUID GUID_DEVICE_INTERFACE_ARRIVAL
Definition: deviface.c:14
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
NTSTATUS MountMgrMountedDeviceArrival(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName, IN BOOLEAN ManuallyRegistered)
Definition: mountmgr.c:937
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
VOID NTAPI PsSetThreadHardErrorsAreDisabled(IN PETHREAD Thread, IN BOOLEAN HardErrorsAreDisabled)
Definition: thread.c:898
VOID MountMgrMountedDeviceRemoval(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName)
Definition: mountmgr.c:1452
BOOLEAN NTAPI PsGetThreadHardErrorsAreDisabled(IN PETHREAD Thread)
Definition: thread.c:695
const GUID GUID_DEVICE_INTERFACE_REMOVAL
Definition: deviface.c:15
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4112
struct tagContext Context
Definition: acpixf.h:1034
return STATUS_SUCCESS
Definition: btrfs.c:3014

Referenced by DriverEntry().

◆ MountMgrMountedDeviceRemoval()

VOID MountMgrMountedDeviceRemoval ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PUNICODE_STRING  DeviceName 
)

Definition at line 1452 of file mountmgr.c.

1454 {
1455  PLIST_ENTRY NextEntry, DeviceEntry;
1456  PUNIQUE_ID_REPLICATE UniqueIdReplicate;
1457  PSYMLINK_INFORMATION SymlinkInformation;
1458  PASSOCIATED_DEVICE_ENTRY AssociatedDevice;
1459  PSAVED_LINK_INFORMATION SavedLinkInformation = NULL;
1460  PDEVICE_INFORMATION DeviceInformation, CurrentDevice;
1461 
1462  /* Acquire device exclusively */
1464 
1465  /* Look for the leaving device */
1466  for (NextEntry = DeviceExtension->DeviceListHead.Flink;
1467  NextEntry != &(DeviceExtension->DeviceListHead);
1468  NextEntry = NextEntry->Flink)
1469  {
1470  DeviceInformation = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
1471 
1472  if (!RtlCompareUnicodeString(&(DeviceInformation->SymbolicName), DeviceName, TRUE))
1473  {
1474  break;
1475  }
1476  }
1477 
1478  /* If we found it */
1479  if (NextEntry != &(DeviceExtension->DeviceListHead))
1480  {
1481  /* If it's asked to keep links, then, prepare to save them */
1482  if (DeviceInformation->KeepLinks)
1483  {
1484  SavedLinkInformation = AllocatePool(sizeof(SAVED_LINK_INFORMATION));
1485  if (!SavedLinkInformation)
1486  {
1487  DeviceInformation->KeepLinks = FALSE;
1488  }
1489  }
1490 
1491  /* If it's possible (and asked), start to save them */
1492  if (DeviceInformation->KeepLinks)
1493  {
1494  InsertTailList(&(DeviceExtension->SavedLinksListHead), &(SavedLinkInformation->SavedLinksListEntry));
1495  InitializeListHead(&(SavedLinkInformation->SymbolicLinksListHead));
1496  SavedLinkInformation->UniqueId = DeviceInformation->UniqueId;
1497  }
1498 
1499  /* For all the symlinks */
1500  while (!IsListEmpty(&(DeviceInformation->SymbolicLinksListHead)))
1501  {
1502  NextEntry = RemoveHeadList(&(DeviceInformation->SymbolicLinksListHead));
1503  SymlinkInformation = CONTAINING_RECORD(NextEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
1504 
1505  /* If we have to, save the link */
1506  if (DeviceInformation->KeepLinks)
1507  {
1508  InsertTailList(&(SavedLinkInformation->SymbolicLinksListHead), &(SymlinkInformation->SymbolicLinksListEntry));
1509  }
1510  /* Otherwise, just release it */
1511  else
1512  {
1513  GlobalDeleteSymbolicLink(&(SymlinkInformation->Name));
1514  FreePool(SymlinkInformation->Name.Buffer);
1515  FreePool(SymlinkInformation);
1516  }
1517  }
1518 
1519  /* Free all the replicated unique IDs */
1520  while (!IsListEmpty(&(DeviceInformation->ReplicatedUniqueIdsListHead)))
1521  {
1522  NextEntry = RemoveHeadList(&(DeviceInformation->ReplicatedUniqueIdsListHead));
1523  UniqueIdReplicate = CONTAINING_RECORD(NextEntry, UNIQUE_ID_REPLICATE, ReplicatedUniqueIdsListEntry);
1524 
1525 
1526  FreePool(UniqueIdReplicate->UniqueId);
1527  FreePool(UniqueIdReplicate);
1528  }
1529 
1530  while (!IsListEmpty(&(DeviceInformation->AssociatedDevicesHead)))
1531  {
1532  NextEntry = RemoveHeadList(&(DeviceInformation->AssociatedDevicesHead));
1533  AssociatedDevice = CONTAINING_RECORD(NextEntry, ASSOCIATED_DEVICE_ENTRY, AssociatedDevicesEntry);
1534 
1535  DeviceInformation->NoDatabase = TRUE;
1536  FreePool(AssociatedDevice->String.Buffer);
1537  FreePool(AssociatedDevice);
1538  }
1539 
1540  /* Remove device from the device list */
1541  RemoveEntryList(&(DeviceInformation->DeviceListEntry));
1542 
1543  /* If there are still devices, check if some were associated with ours */
1544  if (!IsListEmpty(&(DeviceInformation->DeviceListEntry)))
1545  {
1546  for (NextEntry = DeviceExtension->DeviceListHead.Flink;
1547  NextEntry != &(DeviceExtension->DeviceListHead);
1548  NextEntry = NextEntry->Flink)
1549  {
1550  CurrentDevice = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
1551 
1552  /* And then, remove them */
1553  DeviceEntry = CurrentDevice->AssociatedDevicesHead.Flink;
1554  while (DeviceEntry != &(CurrentDevice->AssociatedDevicesHead))
1555  {
1556  AssociatedDevice = CONTAINING_RECORD(NextEntry, ASSOCIATED_DEVICE_ENTRY, AssociatedDevicesEntry);
1557  DeviceEntry = DeviceEntry->Flink;
1558 
1559  if (AssociatedDevice->DeviceInformation != DeviceInformation)
1560  {
1561  continue;
1562  }
1563 
1564  RemoveEntryList(&(AssociatedDevice->AssociatedDevicesEntry));
1565  FreePool(AssociatedDevice->String.Buffer);
1566  FreePool(AssociatedDevice);
1567  }
1568  }
1569  }
1570 
1571  /* Finally, clean up device name, symbolic name */
1572  FreePool(DeviceInformation->SymbolicName.Buffer);
1573  if (!DeviceInformation->KeepLinks)
1574  {
1575  FreePool(DeviceInformation->UniqueId);
1576  }
1577  FreePool(DeviceInformation->DeviceName.Buffer);
1578 
1579  /* Unregister notifications */
1580  if (DeviceInformation->TargetDeviceNotificationEntry)
1581  {
1583  }
1584 
1585  /* And leave */
1586  FreePool(DeviceInformation);
1587  }
1588  else
1589  {
1590  /* We didn't find device, perhaps because it was offline */
1591  for (NextEntry = DeviceExtension->OfflineDeviceListHead.Flink;
1592  NextEntry != &(DeviceExtension->OfflineDeviceListHead);
1593  NextEntry = NextEntry->Flink)
1594  {
1595  DeviceInformation = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
1596 
1597  /* It was, remove it */
1598  if (RtlCompareUnicodeString(&(DeviceInformation->SymbolicName), DeviceName, TRUE) == 0)
1599  {
1600  RemoveEntryList(&(DeviceInformation->DeviceListEntry));
1601  MountMgrFreeDeadDeviceInfo(DeviceInformation);
1602  break;
1603  }
1604  }
1605  }
1606 
1607  /* Release driver */
1609 }
NTSTATUS NTAPI IoUnregisterPlugPlayNotification(IN PVOID NotificationEntry)
Definition: pnpnotify.c:371
PMOUNTDEV_UNIQUE_ID UniqueId
Definition: mntmgr.h:82
VOID MountMgrFreeDeadDeviceInfo(IN PDEVICE_INFORMATION DeviceInformation)
Definition: mountmgr.c:707
#define TRUE
Definition: types.h:120
NTSTATUS GlobalDeleteSymbolicLink(IN PUNICODE_STRING DosName)
Definition: symlink.c:136
PDEVICE_INFORMATION DeviceInformation
Definition: mntmgr.h:98
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define InsertTailList(ListHead, Entry)
#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
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
UNICODE_STRING SymbolicName
Definition: mntmgr.h:48
LIST_ENTRY AssociatedDevicesEntry
Definition: mntmgr.h:97
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define FALSE
Definition: types.h:117
BOOLEAN NoDatabase
Definition: mntmgr.h:57
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
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
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
BOOLEAN KeepLinks
Definition: mntmgr.h:51
Definition: mntmgr.h:95
LIST_ENTRY SymbolicLinksListHead
Definition: mntmgr.h:45
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
Definition: typedefs.h:119
UNICODE_STRING String
Definition: mntmgr.h:99
#define AllocatePool(Size)
Definition: mntmgr.h:153
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
UNICODE_STRING DeviceName
Definition: mntmgr.h:50
LIST_ENTRY ReplicatedUniqueIdsListHead
Definition: mntmgr.h:46
LIST_ENTRY DeviceListEntry
Definition: mntmgr.h:44
#define IO_NO_INCREMENT
Definition: iotypes.h:570
LIST_ENTRY AssociatedDevicesHead
Definition: mntmgr.h:47
PVOID TargetDeviceNotificationEntry
Definition: mntmgr.h:61
PMOUNTDEV_UNIQUE_ID UniqueId
Definition: mntmgr.h:49

Referenced by MountMgrMountedDeviceNotification(), and MountMgrTargetDeviceNotification().

◆ MountmgrReadNoAutoMount()

INIT_FUNCTION BOOLEAN MountmgrReadNoAutoMount ( IN PUNICODE_STRING  RegistryPath)

Definition at line 904 of file mountmgr.c.

905 {
907  ULONG Result, Default = 0;
909 
911 
912  /* Simply read data from register */
914  QueryTable[0].Name = L"NoAutoMount";
918  QueryTable[0].DefaultLength = sizeof(ULONG);
919 
921  RegistryPath->Buffer,
922  QueryTable,
923  NULL,
924  NULL);
925  if (!NT_SUCCESS(Status))
926  {
927  return (Default != 0);
928  }
929 
930  return (Result != 0);
931 }
_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
smooth NULL
Definition: ftsmooth.c:416
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
_In_z_ PWSTR RegistryPath
Definition: classp.h:1930
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:24
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 RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define REG_NONE
Definition: nt_native.h:1492
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144

Referenced by DriverEntry().

◆ MountMgrShutdown()

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

Definition at line 1762 of file mountmgr.c.

1764 {
1766 
1768 
1770 
1772 
1773  /* Wait for workers */
1774  if (InterlockedIncrement(&(DeviceExtension->WorkerReferences)) > 0)
1775  {
1776  KeReleaseSemaphore(&(DeviceExtension->WorkerSemaphore),
1778  1,
1779  FALSE);
1781  }
1782  else
1783  {
1784  InterlockedDecrement(&(DeviceExtension->WorkerReferences));
1785  }
1786 
1787  Irp->IoStatus.Status = STATUS_SUCCESS;
1788  Irp->IoStatus.Information = 0;
1790 
1791  return STATUS_SUCCESS;
1792 }
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
KEVENT UnloadEvent
Definition: mountmgr.c:41
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
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
#define InterlockedDecrement
Definition: armddk.h:52
#define InterlockedExchange
Definition: armddk.h:54
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1569
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define InterlockedIncrement
Definition: armddk.h:53
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
return STATUS_SUCCESS
Definition: btrfs.c:3014
LONG Unloading
Definition: mountmgr.c:42

Referenced by DriverEntry().

◆ MountMgrUnload()

VOID NTAPI MountMgrUnload ( IN struct _DRIVER_OBJECT DriverObject)

Definition at line 800 of file mountmgr.c.

801 {
802  PLIST_ENTRY NextEntry;
803  PUNIQUE_ID_WORK_ITEM WorkItem;
805  PDEVICE_INFORMATION DeviceInformation;
806  PSAVED_LINK_INFORMATION SavedLinkInformation;
807 
809 
810  /* Don't get notification any longer */
812 
813  /* Free registry buffer */
815  if (DeviceExtension->RegistryPath.Buffer)
816  {
817  FreePool(DeviceExtension->RegistryPath.Buffer);
818  DeviceExtension->RegistryPath.Buffer = NULL;
819  }
820 
822 
824 
825  /* Wait for workers to finish */
826  if (InterlockedIncrement(&DeviceExtension->WorkerReferences) > 0)
827  {
828  KeReleaseSemaphore(&(DeviceExtension->WorkerSemaphore),
829  IO_NO_INCREMENT, 1, FALSE);
830 
832  }
833  else
834  {
835  InterlockedDecrement(&(DeviceExtension->WorkerReferences));
836  }
837 
838  /* Don't get any notification any longerĀ² */
840 
841  /* Acquire the driver exclusively */
843  FALSE, NULL);
844 
845  /* Clear offline devices list */
846  while (!IsListEmpty(&(DeviceExtension->OfflineDeviceListHead)))
847  {
848  NextEntry = RemoveHeadList(&(DeviceExtension->OfflineDeviceListHead));
849  DeviceInformation = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
850  MountMgrFreeDeadDeviceInfo(DeviceInformation);
851  }
852 
853  /* Clear saved links list */
854  while (!IsListEmpty(&(DeviceExtension->SavedLinksListHead)))
855  {
856  NextEntry = RemoveHeadList(&(DeviceExtension->SavedLinksListHead));
857  SavedLinkInformation = CONTAINING_RECORD(NextEntry, SAVED_LINK_INFORMATION, SavedLinksListEntry);
858  MountMgrFreeSavedLink(SavedLinkInformation);
859  }
860 
861  /* Clear workers list */
862  while (!IsListEmpty(&(DeviceExtension->UniqueIdWorkerItemListHead)))
863  {
864  NextEntry = RemoveHeadList(&(DeviceExtension->UniqueIdWorkerItemListHead));
865  WorkItem = CONTAINING_RECORD(NextEntry, UNIQUE_ID_WORK_ITEM, UniqueIdWorkerItemListEntry);
866 
868  WorkItem->Event = &UnloadEvent;
869 
871  1, FALSE);
872 
873  IoCancelIrp(WorkItem->Irp);
875 
876  IoFreeIrp(WorkItem->Irp);
877  FreePool(WorkItem->DeviceName.Buffer);
878  FreePool(WorkItem->IrpBuffer);
879  FreePool(WorkItem);
880 
882  FALSE, NULL);
883  }
884 
885  /* If we have drive letter data, release */
886  if (DeviceExtension->DriveLetterData)
887  {
888  FreePool(DeviceExtension->DriveLetterData);
889  DeviceExtension->DriveLetterData = NULL;
890  }
891 
892  /* Release driver & quit */
894 
897 }
NTSTATUS NTAPI IoUnregisterPlugPlayNotification(IN PVOID NotificationEntry)
Definition: pnpnotify.c:371
UNICODE_STRING DeviceName
Definition: mntmgr.h:147
VOID MountMgrFreeDeadDeviceInfo(IN PDEVICE_INFORMATION DeviceInformation)
Definition: mountmgr.c:707
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
KEVENT UnloadEvent
Definition: mountmgr.c:41
NTSTATUS GlobalDeleteSymbolicLink(IN PUNICODE_STRING DosName)
Definition: symlink.c:136
#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
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
VOID MountMgrFreeSavedLink(IN PSAVED_LINK_INFORMATION SavedLinkInformation)
Definition: mountmgr.c:772
#define FALSE
Definition: types.h:117
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
PDEVICE_OBJECT gdeviceObject
Definition: mountmgr.c:40
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
VOID NTAPI IoUnregisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1725
#define InterlockedDecrement
Definition: armddk.h:52
Definition: typedefs.h:119
#define InterlockedExchange
Definition: armddk.h:54
UNICODE_STRING DosDevicesMount
Definition: symlink.c:32
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define InterlockedIncrement
Definition: armddk.h:53
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
BOOLEAN NTAPI IoCancelIrp(IN PIRP Irp)
Definition: irp.c:1101
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define IO_NO_INCREMENT
Definition: iotypes.h:570
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
LONG Unloading
Definition: mountmgr.c:42

Referenced by DriverEntry().

◆ QueryDeviceInformation()

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 at line 195 of file mountmgr.c.

203 {
204  PIRP Irp;
205  USHORT Size;
206  KEVENT Event;
207  BOOLEAN IsRemovable;
211  PIO_STACK_LOCATION Stack;
212  NTSTATUS Status, IntStatus;
216  STORAGE_DEVICE_NUMBER StorageDeviceNumber;
218 
219  /* Get device associated with the symbolic name */
222  &FileObject,
223  &DeviceObject);
224  if (!NT_SUCCESS(Status))
225  {
226  return Status;
227  }
228 
229  /* The associate FO can't have a file name */
230  if (FileObject->FileName.Length)
231  {
234  }
235 
236  /* Check if it's removable & return to the user (if asked to) */
237  IsRemovable = (FileObject->DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA);
238  if (Removable)
239  {
240  *Removable = IsRemovable;
241  }
242 
243  /* Get the attached device */
245 
246  /* If we've been asked for a GPT drive letter */
247  if (GptDriveLetter)
248  {
249  /* Consider it has one */
250  *GptDriveLetter = TRUE;
251 
252  if (!IsRemovable)
253  {
254  /* Query the GPT attributes */
257  DeviceObject,
258  NULL,
259  0,
260  &GptAttributes,
261  sizeof(GptAttributes),
262  FALSE,
263  &Event,
264  &IoStatusBlock);
265  if (!Irp)
266  {
270  }
271 
273  if (Status == STATUS_PENDING)
274  {
277  }
278 
279  /* In case of failure, don't fail, that's no vital */
280  if (!NT_SUCCESS(Status))
281  {
283  }
284  /* Check if it has a drive letter */
285  else if (!(GptAttributes.GptAttributes &
286  GPT_BASIC_DATA_ATTRIBUTE_NO_DRIVE_LETTER))
287  {
288  *GptDriveLetter = FALSE;
289  }
290  }
291  }
292 
293  /* If caller wants to know if there's valid contents */
294  if (Valid)
295  {
296  /* Suppose it's not OK */
297  *Valid = FALSE;
298 
299  if (!IsRemovable)
300  {
301  /* Query partitions information */
304  DeviceObject,
305  NULL,
306  0,
307  &PartitionInfo,
308  sizeof(PartitionInfo),
309  FALSE,
310  &Event,
311  &IoStatusBlock);
312  if (!Irp)
313  {
317  }
318 
320  if (Status == STATUS_PENDING)
321  {
324  }
325 
326  /* Once again here, failure isn't major */
327  if (!NT_SUCCESS(Status))
328  {
330  }
331  /* Verify we know something in */
332  else if (PartitionInfo.PartitionStyle == PARTITION_STYLE_MBR &&
333  IsRecognizedPartition(PartitionInfo.Mbr.PartitionType))
334  {
335  *Valid = TRUE;
336  }
337 
338  /* It looks correct, ensure it is & query device number */
339  if (*Valid)
340  {
343  DeviceObject,
344  NULL,
345  0,
346  &StorageDeviceNumber,
347  sizeof(StorageDeviceNumber),
348  FALSE,
349  &Event,
350  &IoStatusBlock);
351  if (!Irp)
352  {
356  }
357 
359  if (Status == STATUS_PENDING)
360  {
363  }
364 
365  if (!NT_SUCCESS(Status))
366  {
368  }
369  else
370  {
371  *Valid = FALSE;
372  }
373  }
374  }
375  }
376 
377  /* If caller needs device name */
378  if (DeviceName)
379  {
380  /* Allocate a buffer just to request length */
381  Name = AllocatePool(sizeof(MOUNTDEV_NAME));
382  if (!Name)
383  {
387  }
388 
389  /* Query device name */
392  DeviceObject,
393  NULL,
394  0,
395  Name,
396  sizeof(MOUNTDEV_NAME),
397  FALSE,
398  &Event,
399  &IoStatusBlock);
400  if (!Irp)
401  {
402  FreePool(Name);
406  }
407 
409  Stack->FileObject = FileObject;
410 
412  if (Status == STATUS_PENDING)
413  {
416  }
417 
418  /* Now, we've got the correct length */
420  {
421  Size = Name->NameLength + sizeof(MOUNTDEV_NAME);
422 
423  FreePool(Name);
424 
425  /* Allocate proper size */
427  if (!Name)
428  {
432  }
433 
434  /* And query name (for real that time) */
437  DeviceObject,
438  NULL,
439  0,
440  Name,
441  Size,
442  FALSE,
443  &Event,
444  &IoStatusBlock);
445  if (!Irp)
446  {
447  FreePool(Name);
451  }
452 
454  Stack->FileObject = FileObject;
455 
457  if (Status == STATUS_PENDING)
458  {
461  }
462  }
463 
464  if (NT_SUCCESS(Status))
465  {
466  /* Copy back found name to the caller */
467  DeviceName->Length = Name->NameLength;
468  DeviceName->MaximumLength = Name->NameLength + sizeof(WCHAR);
469  DeviceName->Buffer = AllocatePool(DeviceName->MaximumLength);
470  if (!DeviceName->Buffer)
471  {
473  }
474  else
475  {
476  RtlCopyMemory(DeviceName->Buffer, Name->Name, Name->NameLength);
477  DeviceName->Buffer[Name->NameLength / sizeof(WCHAR)] = UNICODE_NULL;
478  }
479  }
480 
481  FreePool(Name);
482  }
483 
484  if (!NT_SUCCESS(Status))
485  {
488  return Status;
489  }
490 
491  /* If caller wants device unique ID */
492  if (UniqueId)
493  {
494  /* Prepare buffer to probe length */
496  if (!Id)
497  {
501  }
502 
503  /* Query unique ID length */
506  DeviceObject,
507  NULL,
508  0,
509  Id,
510  sizeof(MOUNTDEV_UNIQUE_ID),
511  FALSE,
512  &Event,
513  &IoStatusBlock);
514  if (!Irp)
515  {
516  FreePool(Id);
520  }
521 
523  Stack->FileObject = FileObject;
524 
526  if (Status == STATUS_PENDING)
527  {
530  }
531 
532  /* Retry with appropriate length */
534  {
535  Size = Id->UniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID);
536 
537  FreePool(Id);
538 
539  /* Allocate the correct buffer */
540  Id = AllocatePool(Size);
541  if (!Id)
542  {
546  }
547 
548  /* Query unique ID */
551  DeviceObject,
552  NULL,
553  0,
554  Id,
555  Size,
556  FALSE,
557  &Event,
558  &IoStatusBlock);
559  if (!Irp)
560  {
561  FreePool(Id);
565  }
566 
568  Stack->FileObject = FileObject;
569 
571  if (Status == STATUS_PENDING)
572  {
575  }
576  }
577 
578  /* Hands back unique ID */
579  if (NT_SUCCESS(Status))
580  {
581  *UniqueId = Id;
582  }
583  else
584  {
585  /* In case of failure, also free the rest */
586  FreePool(Id);
587  if (DeviceName->Length)
588  {
589  FreePool(DeviceName->Buffer);
590  }
591 
594 
595  return Status;
596  }
597  }
598 
599  /* If user wants to know about GUID */
600  if (HasGuid)
601  {
602  /* Query device stable GUID */
605  DeviceObject,
606  NULL,
607  0,
608  StableGuid,
609  sizeof(GUID),
610  FALSE,
611  &Event,
612  &IoStatusBlock);
613  if (!Irp)
614  {
618  }
619 
621  Stack->FileObject = FileObject;
622 
623  IntStatus = IoCallDriver(DeviceObject, Irp);
624  if (IntStatus == STATUS_PENDING)
625  {
627  IntStatus = IoStatusBlock.Status;
628  }
629 
630  *HasGuid = NT_SUCCESS(IntStatus);
631  }
632 
635  return Status;
636 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
_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
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
DWORD Id
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
#define IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
Definition: imports.h:80
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
struct NameRec_ * Name
Definition: cdprocs.h:459
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:439
struct _MOUNTDEV_NAME MOUNTDEV_NAME
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define IOCTL_STORAGE_GET_DEVICE_NUMBER
Definition: ntddstor.h:132
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:588
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
#define IOCTL_MOUNTDEV_QUERY_STABLE_GUID
Definition: imports.h:255
struct _MOUNTDEV_UNIQUE_ID MOUNTDEV_UNIQUE_ID
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define IsRecognizedPartition(PartitionType)
Definition: ntdddisk.h:342
_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
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
#define AllocatePool(Size)
Definition: mntmgr.h:153
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1569
PFILE_OBJECT FileObject
Definition: iotypes.h:2820
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#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
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
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define IOCTL_VOLUME_GET_GPT_ATTRIBUTES
Definition: ntddvol.h:56
#define IOCTL_DISK_GET_PARTITION_INFO_EX
Definition: ntddk_ex.h:206
Definition: arc.h:81

Referenced by FindDeviceInfo(), MountMgrCreatePointWorker(), MountMgrMountedDeviceArrival(), MountMgrNextDriveLetterWorker(), MountMgrVolumeMountPointChanged(), MountMgrVolumeMountPointCreated(), QueryPointsFromMemory(), QueryPointsFromSymbolicLinkName(), USBD_GetDeviceInformationEx(), and USBH_GetDeviceType().

Variable Documentation

◆ Cunc

const WCHAR Cunc[] = L"\\??\\C:"
static

Definition at line 44 of file mountmgr.c.

Referenced by MountMgrMountedDeviceArrival().

◆ gdeviceObject

PDEVICE_OBJECT gdeviceObject

Definition at line 40 of file mountmgr.c.

Referenced by DriverEntry(), and MountMgrUnload().

◆ MountedDevicesGuid

GUID MountedDevicesGuid = {0x53F5630D, 0xB6BF, 0x11D0, {0x94, 0xF2, 0x00, 0xA0, 0xC9, 0x1E, 0xFB, 0x8B}}

Definition at line 38 of file mountmgr.c.

Referenced by DriverEntry().

◆ UnloadEvent

KEVENT UnloadEvent

Definition at line 41 of file mountmgr.c.

Referenced by MountMgrShutdown(), MountMgrUnload(), and WorkerThread().

◆ Unloading

LONG Unloading

Definition at line 42 of file mountmgr.c.

Referenced by MountMgrShutdown(), and MountMgrUnload().