ReactOS  0.4.15-dev-3181-g4acf100
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)
 
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)
 
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 40 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 108 of file mountmgr.c.

112 {
114 
115  /* Allocate a big enough buffer to contain the symbolic link */
116  DriveLetter->MaximumLength = DosDevices.Length + 3 * sizeof(WCHAR);
117  DriveLetter->Buffer = AllocatePool(DriveLetter->MaximumLength);
118  if (!DriveLetter->Buffer)
119  {
121  }
122 
123  /* Copy prefix */
124  RtlCopyUnicodeString(DriveLetter, &DosDevices);
125 
126  /* Update string to reflect real contents */
127  DriveLetter->Length = DosDevices.Length + 2 * sizeof(WCHAR);
128  DriveLetter->Buffer[DosDevices.Length / sizeof(WCHAR) + 2] = UNICODE_NULL;
129  DriveLetter->Buffer[DosDevices.Length / sizeof(WCHAR) + 1] = L':';
130 
131  /* If caller wants a no drive entry */
132  if (Letter == (UCHAR)-1)
133  {
134  /* Then, create a no letter entry */
135  CreateNoDriveLetterEntry(UniqueId);
136  FreePool(DriveLetter->Buffer);
137  return STATUS_UNSUCCESSFUL;
138  }
139  else if (Letter)
140  {
141  /* Use the letter given by the caller */
142  DriveLetter->Buffer[DosDevices.Length / sizeof(WCHAR)] = (WCHAR)Letter;
144  if (NT_SUCCESS(Status))
145  {
146  return Status;
147  }
148  }
149 
150  /* If caller didn't provide a letter, let's find one for him */
151 
153  {
154  /* If the device is a floppy, start with letter A */
155  Letter = 'A';
156  }
158  {
159  /* If the device is a CD-ROM, start with letter D */
160  Letter = 'D';
161  }
162  else
163  {
164  /* Finally, if it's a disk, use C */
165  Letter = 'C';
166  }
167 
168  /* Try to affect a letter (up to Z, ofc) until it's possible */
169  for (; Letter <= 'Z'; Letter++)
170  {
171  DriveLetter->Buffer[DosDevices.Length / sizeof(WCHAR)] = (WCHAR)Letter;
173  if (NT_SUCCESS(Status))
174  {
175  DPRINT("Assigned drive %c: to %wZ\n", Letter, DeviceName);
176  return Status;
177  }
178  }
179 
180  /* We failed to allocate a letter */
181  FreePool(DriveLetter->Buffer);
182  DPRINT("Failed to create a drive letter for %wZ\n", DeviceName);
183  return Status;
184 }
#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
#define FreePool(P)
Definition: mntmgr.h:154
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3272
#define UNICODE_NULL
UNICODE_STRING DeviceFloppy
Definition: symlink.c:34
Status
Definition: gdiplustypes.h:24
__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
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)
#define DPRINT
Definition: sndvol32.h:71
UNICODE_STRING DeviceCdRom
Definition: symlink.c:35

Referenced by MountMgrMountedDeviceArrival().

◆ DriverEntry()

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

Definition at line 1793 of file mountmgr.c.

1795 {
1796  NTSTATUS Status;
1798  PDEVICE_EXTENSION DeviceExtension;
1799 
1801 
1803  sizeof(DEVICE_EXTENSION),
1804  &DeviceMount,
1807  FALSE,
1808  &DeviceObject);
1809  if (!NT_SUCCESS(Status))
1810  {
1811  return Status;
1812  }
1813 
1814  DriverObject->DriverUnload = MountMgrUnload;
1815 
1816  DeviceExtension = DeviceObject->DeviceExtension;
1817  RtlZeroMemory(DeviceExtension, sizeof(DEVICE_EXTENSION));
1818  DeviceExtension->DeviceObject = DeviceObject;
1819  DeviceExtension->DriverObject = DriverObject;
1820 
1821  InitializeListHead(&(DeviceExtension->DeviceListHead));
1822  InitializeListHead(&(DeviceExtension->OfflineDeviceListHead));
1823 
1824  KeInitializeSemaphore(&(DeviceExtension->DeviceLock), 1, 1);
1825  KeInitializeSemaphore(&(DeviceExtension->RemoteDatabaseLock), 1, 1);
1826 
1827  InitializeListHead(&(DeviceExtension->IrpListHead));
1828  DeviceExtension->EpicNumber = 1;
1829 
1830  InitializeListHead(&(DeviceExtension->SavedLinksListHead));
1831 
1832  InitializeListHead(&(DeviceExtension->WorkerQueueListHead));
1833  KeInitializeSemaphore(&(DeviceExtension->WorkerSemaphore), 0, MAXLONG);
1834  DeviceExtension->WorkerReferences = -1;
1835  KeInitializeSpinLock(&(DeviceExtension->WorkerLock));
1836 
1837  InitializeListHead(&(DeviceExtension->UniqueIdWorkerItemListHead));
1838  InitializeListHead(&(DeviceExtension->OnlineNotificationListHead));
1839  DeviceExtension->OnlineNotificationCount = 1;
1840 
1841  DeviceExtension->RegistryPath.Length = RegistryPath->Length;
1842  DeviceExtension->RegistryPath.MaximumLength = RegistryPath->Length + sizeof(WCHAR);
1843  DeviceExtension->RegistryPath.Buffer = AllocatePool(DeviceExtension->RegistryPath.MaximumLength);
1844  if (!DeviceExtension->RegistryPath.Buffer)
1845  {
1848  }
1849 
1850  RtlCopyUnicodeString(&(DeviceExtension->RegistryPath), RegistryPath);
1851 
1852  DeviceExtension->NoAutoMount = MountmgrReadNoAutoMount(&(DeviceExtension->RegistryPath));
1853 
1855 
1856  /* Register for device arrival & removal. Ask to be notified for already
1857  * present devices
1858  */
1862  DriverObject,
1864  DeviceExtension,
1865  &(DeviceExtension->NotificationEntry));
1866 
1867  if (!NT_SUCCESS(Status))
1868  {
1870  return Status;
1871  }
1872 
1873  DriverObject->MajorFunction[IRP_MJ_CREATE] =
1874  DriverObject->MajorFunction[IRP_MJ_CLOSE] = MountMgrCreateClose;
1876  DriverObject->MajorFunction[IRP_MJ_CLEANUP] = MountMgrCleanup;
1877  DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = MountMgrShutdown;
1878 
1880 
1882  if (!NT_SUCCESS(Status))
1883  {
1885  }
1886 
1887  return Status;
1888 }
PWSTR DatabasePath
Definition: database.c:31
NTSTATUS NTAPI MountMgrCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: mountmgr.c:1646
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define FILE_DEVICE_NETWORK
Definition: winioctl.h:124
#define MAXLONG
Definition: umtypes.h:116
#define IRP_MJ_SHUTDOWN
NTSTATUS NTAPI MountMgrShutdown(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: mountmgr.c:1756
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
#define PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES
Definition: iotypes.h:1239
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
BOOLEAN MountmgrReadNoAutoMount(IN PUNICODE_STRING RegistryPath)
Definition: mountmgr.c:898
#define FALSE
Definition: types.h:117
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:238
UNICODE_STRING DeviceMount
Definition: symlink.c:31
NTSYSAPI NTSTATUS NTAPI RtlCreateRegistryKey(_In_ ULONG RelativeTo, _In_ PWSTR Path)
PDEVICE_OBJECT gdeviceObject
Definition: mountmgr.c:35
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
Status
Definition: gdiplustypes.h:24
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
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define AllocatePool(Size)
Definition: mntmgr.h:153
UNICODE_STRING DosDevicesMount
Definition: symlink.c:32
DRIVER_DISPATCH MountMgrDeviceControl
Definition: mntmgr.h:340
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
NTSTATUS NTAPI MountMgrMountedDeviceNotification(IN PVOID NotificationStructure, IN PVOID Context)
Definition: mountmgr.c:1610
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
NTSTATUS NTAPI MountMgrCleanup(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: mountmgr.c:1695
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
NTSTATUS NTAPI IoRegisterPlugPlayNotification(_In_ IO_NOTIFICATION_EVENT_CATEGORY EventCategory, _In_ ULONG EventCategoryFlags, _In_opt_ PVOID EventCategoryData, _In_ PDRIVER_OBJECT DriverObject, _In_ PDRIVER_NOTIFICATION_CALLBACK_ROUTINE CallbackRoutine, _Inout_opt_ PVOID Context, _Out_ PVOID *NotificationEntry)
Definition: pnpnotify.c:345
VOID NTAPI MountMgrUnload(IN struct _DRIVER_OBJECT *DriverObject)
Definition: mountmgr.c:794
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
GUID MountedDevicesGuid
Definition: mountmgr.c:33

◆ FindDeviceInfo()

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

Definition at line 636 of file mountmgr.c.

640 {
642  PLIST_ENTRY NextEntry;
645 
646  /* If a device name was given, use it */
647  if (DeviceNameGiven)
648  {
649  DeviceName.Length = SymbolicName->Length;
650  DeviceName.Buffer = SymbolicName->Buffer;
651  }
652  else
653  {
654  /* Otherwise, query it */
656  &DeviceName,
657  NULL, NULL,
658  NULL, NULL,
659  NULL, NULL);
660  if (!NT_SUCCESS(Status))
661  {
662  return Status;
663  }
664  }
665 
666  /* Look for device information matching devive */
667  for (NextEntry = DeviceExtension->DeviceListHead.Flink;
668  NextEntry != &(DeviceExtension->DeviceListHead);
669  NextEntry = NextEntry->Flink)
670  {
671  DeviceInfo = CONTAINING_RECORD(NextEntry,
673  DeviceListEntry);
674 
675  if (RtlEqualUnicodeString(&DeviceName, &(DeviceInfo->DeviceName), TRUE))
676  {
677  break;
678  }
679  }
680 
681  /* Release our buffer if required */
682  if (!DeviceNameGiven)
683  {
684  FreePool(DeviceName.Buffer);
685  }
686 
687  /* Return found information */
688  if (NextEntry == &(DeviceExtension->DeviceListHead))
689  {
691  }
692 
693  *DeviceInformation = DeviceInfo;
694  return STATUS_SUCCESS;
695 }
#define TRUE
Definition: types.h:120
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
LONG NTSTATUS
Definition: precomp.h:26
#define FreePool(P)
Definition: mntmgr.h:154
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3272
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
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _DeviceInfo DeviceInfo
Definition: typedefs.h:119
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define NULL
Definition: types.h:112
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:190
#define STATUS_SUCCESS
Definition: shellext.h:65
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 83 of file mountmgr.c.

84 {
85  PLIST_ENTRY NextEntry;
86  PSYMLINK_INFORMATION SymlinkInfo;
87 
88  /* Browse all the symlinks to check if there is at least a drive letter */
89  for (NextEntry = DeviceInformation->SymbolicLinksListHead.Flink;
90  NextEntry != &DeviceInformation->SymbolicLinksListHead;
91  NextEntry = NextEntry->Flink)
92  {
93  SymlinkInfo = CONTAINING_RECORD(NextEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
94 
95  if (IsDriveLetter(&SymlinkInfo->Name) && SymlinkInfo->Online)
96  {
97  return TRUE;
98  }
99  }
100 
101  return FALSE;
102 }
#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 46 of file mountmgr.c.

47 {
51 
52  /* Prepare to look in the registry to see if
53  * given volume is offline
54  */
60  QueryTable[0].DefaultLength = sizeof(ULONG);
62 
63  Default = 0;
64 
65  /* Query status */
68  QueryTable,
69  NULL,
70  NULL);
71  if (!NT_SUCCESS(Status))
72  {
73  IsOffline = 0;
74  }
75 
76  return (IsOffline != 0);
77 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4155
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
PWSTR OfflinePath
Definition: database.c:32
LONG NTSTATUS
Definition: precomp.h:26
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
BOOLEAN IsOffline(PUNICODE_STRING SymbolicName)
Definition: mountmgr.c:46
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#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 1676 of file mountmgr.c.

1678 {
1680 
1681  RemoveEntryList(&(Irp->Tail.Overlay.ListEntry));
1682 
1683  IoReleaseCancelSpinLock(Irp->CancelIrql);
1684 
1685  Irp->IoStatus.Information = 0;
1686  Irp->IoStatus.Status = STATUS_CANCELLED;
1688 }
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ PIRP Irp
Definition: csq.h:116
#define IoCompleteRequest
Definition: irp.c:1240
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
#define IO_NO_INCREMENT
Definition: iotypes.h:598

Referenced by MountMgrChangeNotify(), and MountMgrCleanup().

◆ MountMgrCleanup()

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

Definition at line 1695 of file mountmgr.c.

1697 {
1698  PIRP ListIrp;
1699  KIRQL OldIrql;
1700  PLIST_ENTRY NextEntry;
1703  PDEVICE_EXTENSION DeviceExtension;
1704 
1705  DeviceExtension = DeviceObject->DeviceExtension;
1707  FileObject = Stack->FileObject;
1708 
1710 
1711  /* If IRP list if empty, it's OK */
1712  if (IsListEmpty(&(DeviceExtension->IrpListHead)))
1713  {
1715 
1716  Irp->IoStatus.Status = STATUS_SUCCESS;
1717  Irp->IoStatus.Information = 0;
1719 
1720  return STATUS_SUCCESS;
1721  }
1722 
1723  /* Otherwise, cancel all the IRPs */
1724  NextEntry = DeviceExtension->IrpListHead.Flink;
1725  do
1726  {
1727  ListIrp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
1729  {
1730  ListIrp->Cancel = TRUE;
1731  ListIrp->CancelIrql = OldIrql;
1732  ListIrp->CancelRoutine = NULL;
1733  MountMgrCancel(DeviceObject, ListIrp);
1734 
1736  }
1737 
1738  NextEntry = NextEntry->Flink;
1739  }
1740  while (NextEntry != &(DeviceExtension->IrpListHead));
1741 
1743 
1744  Irp->IoStatus.Status = STATUS_SUCCESS;
1745  Irp->IoStatus.Information = 0;
1747 
1748  return STATUS_SUCCESS;
1749 }
#define TRUE
Definition: types.h:120
VOID NTAPI MountMgrCancel(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: mountmgr.c:1676
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
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:636
UCHAR KIRQL
Definition: env_spec_w32.h:591
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ PIRP Irp
Definition: csq.h:116
#define IoCompleteRequest
Definition: irp.c:1240
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
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
KIRQL OldIrql
Definition: mm.h:1502
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
* PFILE_OBJECT
Definition: iotypes.h:1998
Definition: typedefs.h:119
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define NULL
Definition: types.h:112
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by DriverEntry().

◆ MountMgrCreateClose()

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

Definition at line 1646 of file mountmgr.c.

1648 {
1651 
1653 
1655 
1656  /* Allow driver opening for communication
1657  * as long as it's not taken for a directory
1658  */
1659  if (Stack->MajorFunction == IRP_MJ_CREATE &&
1660  Stack->Parameters.Create.Options & FILE_DIRECTORY_FILE)
1661  {
1663  }
1664 
1665  Irp->IoStatus.Status = Status;
1666  Irp->IoStatus.Information = 0;
1668  return Status;
1669 }
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
LONG NTSTATUS
Definition: precomp.h:26
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:636
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169
_In_ PIRP Irp
Definition: csq.h:116
#define IoCompleteRequest
Definition: irp.c:1240
Status
Definition: gdiplustypes.h:24
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by DriverEntry().

◆ MountMgrFreeDeadDeviceInfo()

VOID MountMgrFreeDeadDeviceInfo ( IN PDEVICE_INFORMATION  DeviceInformation)

Definition at line 701 of file mountmgr.c.

702 {
703  FreePool(DeviceInformation->SymbolicName.Buffer);
704  FreePool(DeviceInformation);
705 }
#define FreePool(P)
Definition: mntmgr.h:154

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

◆ MountMgrFreeMountedDeviceInfo()

VOID MountMgrFreeMountedDeviceInfo ( IN PDEVICE_INFORMATION  DeviceInformation)

Definition at line 711 of file mountmgr.c.

712 {
713  PLIST_ENTRY NextEntry;
714  PSYMLINK_INFORMATION SymLink;
715  PUNIQUE_ID_REPLICATE UniqueId;
717 
718  /* Purge symbolic links list */
719  while (!IsListEmpty(&(DeviceInformation->SymbolicLinksListHead)))
720  {
721  NextEntry = RemoveHeadList(&(DeviceInformation->SymbolicLinksListHead));
722  SymLink = CONTAINING_RECORD(NextEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
723 
724  GlobalDeleteSymbolicLink(&(SymLink->Name));
725  FreePool(SymLink->Name.Buffer);
726  }
727 
728  /* Purge replicated unique IDs list */
729  while (!IsListEmpty(&(DeviceInformation->ReplicatedUniqueIdsListHead)))
730  {
731  NextEntry = RemoveHeadList(&(DeviceInformation->ReplicatedUniqueIdsListHead));
732  UniqueId = CONTAINING_RECORD(NextEntry, UNIQUE_ID_REPLICATE, ReplicatedUniqueIdsListEntry);
733 
734  FreePool(UniqueId->UniqueId);
735  FreePool(UniqueId);
736  }
737 
738  while (!IsListEmpty(&(DeviceInformation->AssociatedDevicesHead)))
739  {
740  NextEntry = RemoveHeadList(&(DeviceInformation->AssociatedDevicesHead));
741  AssociatedDevice = CONTAINING_RECORD(NextEntry, ASSOCIATED_DEVICE_ENTRY, AssociatedDevicesEntry);
742 
743  FreePool(AssociatedDevice->String.Buffer);
745  }
746 
747  /* Free the rest of the buffers */
748  FreePool(DeviceInformation->SymbolicName.Buffer);
749  if (DeviceInformation->KeepLinks)
750  {
751  FreePool(DeviceInformation->UniqueId);
752  }
753  FreePool(DeviceInformation->DeviceName.Buffer);
754 
755  /* Finally, stop waiting for notifications for this device */
756  if (DeviceInformation->TargetDeviceNotificationEntry)
757  {
758  IoUnregisterPlugPlayNotification(DeviceInformation->TargetDeviceNotificationEntry);
759  }
760 }
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
NTSTATUS NTAPI IoUnregisterPlugPlayNotification(_In_ PVOID NotificationEntry)
Definition: pnpnotify.c:479
_In_ WDFDEVICE AssociatedDevice
Definition: wdfinterrupt.h:173
Definition: typedefs.h:119

◆ MountMgrFreeSavedLink()

VOID MountMgrFreeSavedLink ( IN PSAVED_LINK_INFORMATION  SavedLinkInformation)

Definition at line 766 of file mountmgr.c.

767 {
768  PLIST_ENTRY NextEntry;
769  PSYMLINK_INFORMATION SymlinkInformation;
770 
771  /* For all the saved links */
772  while (!IsListEmpty(&(SavedLinkInformation->SymbolicLinksListHead)))
773  {
774  NextEntry = RemoveHeadList(&(SavedLinkInformation->SymbolicLinksListHead));
775  SymlinkInformation = CONTAINING_RECORD(NextEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
776 
777  /* Remove from system & free */
778  GlobalDeleteSymbolicLink(&(SymlinkInformation->Name));
779  FreePool(SymlinkInformation->Name.Buffer);
780  FreePool(SymlinkInformation);
781  }
782 
783  /* And free unique ID & entry */
784  FreePool(SavedLinkInformation->UniqueId);
785  FreePool(SavedLinkInformation);
786 }
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 931 of file mountmgr.c.

934 {
935  WCHAR Letter;
936  GUID StableGuid;
937  HANDLE LinkHandle;
938  ULONG SymLinkCount, i;
939  PLIST_ENTRY NextEntry;
940  PUNICODE_STRING SymLinks;
941  NTSTATUS Status, IntStatus;
943  PSYMLINK_INFORMATION SymlinkInformation;
944  PMOUNTDEV_UNIQUE_ID UniqueId, NewUniqueId;
945  PSAVED_LINK_INFORMATION SavedLinkInformation;
946  PDEVICE_INFORMATION DeviceInformation, CurrentDevice;
947  WCHAR CSymLinkBuffer[RTL_NUMBER_OF(Cunc)], LinkTargetBuffer[MAX_PATH];
948  UNICODE_STRING TargetDeviceName, SuggestedLinkName, DeviceName, VolumeName, DriveLetter, LinkTarget, CSymLink;
949  BOOLEAN HasGuid, HasGptDriveLetter, Valid, UseOnlyIfThereAreNoOtherLinks, IsDrvLetter, IsOff, IsVolumeName, LinkError;
950 
951  /* New device = new structure to represent it */
952  DeviceInformation = AllocatePool(sizeof(DEVICE_INFORMATION));
953  if (!DeviceInformation)
954  {
956  }
957 
958  /* Initialise device structure */
959  RtlZeroMemory(DeviceInformation, sizeof(DEVICE_INFORMATION));
960  InitializeListHead(&(DeviceInformation->SymbolicLinksListHead));
961  InitializeListHead(&(DeviceInformation->ReplicatedUniqueIdsListHead));
962  InitializeListHead(&(DeviceInformation->AssociatedDevicesHead));
963  DeviceInformation->SymbolicName.Length = SymbolicName->Length;
964  DeviceInformation->SymbolicName.MaximumLength = SymbolicName->Length + sizeof(UNICODE_NULL);
965  DeviceInformation->SymbolicName.Buffer = AllocatePool(DeviceInformation->SymbolicName.MaximumLength);
966  if (!DeviceInformation->SymbolicName.Buffer)
967  {
968  FreePool(DeviceInformation);
970  }
971 
972  /* Copy symbolic name */
974  DeviceInformation->SymbolicName.Buffer[DeviceInformation->SymbolicName.Length / sizeof(WCHAR)] = UNICODE_NULL;
975  DeviceInformation->ManuallyRegistered = ManuallyRegistered;
976  DeviceInformation->DeviceExtension = DeviceExtension;
977 
978  /* Query as much data as possible about device */
980  &TargetDeviceName,
981  &UniqueId,
982  &(DeviceInformation->Removable),
983  &HasGptDriveLetter,
984  &HasGuid,
985  &StableGuid,
986  &Valid);
987  if (!NT_SUCCESS(Status))
988  {
989  KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
990 
991  for (NextEntry = DeviceExtension->OfflineDeviceListHead.Flink;
992  NextEntry != &(DeviceExtension->OfflineDeviceListHead);
993  NextEntry = NextEntry->Flink)
994  {
995  CurrentDevice = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
996 
997  if (RtlEqualUnicodeString(&(DeviceInformation->SymbolicName), &(CurrentDevice->SymbolicName), TRUE))
998  {
999  break;
1000  }
1001  }
1002 
1003  if (NextEntry != &(DeviceExtension->OfflineDeviceListHead))
1004  {
1005  MountMgrFreeDeadDeviceInfo(DeviceInformation);
1006  }
1007  else
1008  {
1009  InsertTailList(&(DeviceExtension->OfflineDeviceListHead), &(DeviceInformation->DeviceListEntry));
1010  }
1011 
1012  KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
1013 
1014  return Status;
1015  }
1016 
1017  /* Save gathered data */
1018  DeviceInformation->UniqueId = UniqueId;
1019  DeviceInformation->DeviceName = TargetDeviceName;
1020  DeviceInformation->KeepLinks = FALSE;
1021 
1022  /* If we found system partition, mark it */
1023  if (DeviceExtension->DriveLetterData && UniqueId->UniqueIdLength == DeviceExtension->DriveLetterData->UniqueIdLength)
1024  {
1025  if (RtlCompareMemory(UniqueId->UniqueId, DeviceExtension->DriveLetterData->UniqueId, UniqueId->UniqueIdLength)
1026  == UniqueId->UniqueIdLength)
1027  {
1028  IoSetSystemPartition(&TargetDeviceName);
1029  }
1030  }
1031 
1032  /* Check suggested link name */
1033  Status = QuerySuggestedLinkName(&(DeviceInformation->SymbolicName),
1034  &SuggestedLinkName,
1035  &UseOnlyIfThereAreNoOtherLinks);
1036  if (!NT_SUCCESS(Status))
1037  {
1038  SuggestedLinkName.Buffer = NULL;
1039  }
1040 
1041  /* If it's OK, set it and save its letter (if any) */
1042  if (SuggestedLinkName.Buffer && IsDriveLetter(&SuggestedLinkName))
1043  {
1044  DeviceInformation->SuggestedDriveLetter = (UCHAR)SuggestedLinkName.Buffer[LETTER_POSITION];
1045  }
1046 
1047  /* Acquire driver exclusively */
1048  KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
1049 
1050  /* Check if we already have device in to prevent double registration */
1051  for (NextEntry = DeviceExtension->DeviceListHead.Flink;
1052  NextEntry != &(DeviceExtension->DeviceListHead);
1053  NextEntry = NextEntry->Flink)
1054  {
1055  CurrentDevice = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
1056 
1057  if (RtlEqualUnicodeString(&(CurrentDevice->DeviceName), &TargetDeviceName, TRUE))
1058  {
1059  break;
1060  }
1061  }
1062 
1063  /* If we found it, clear ours, and return success, all correct */
1064  if (NextEntry != &(DeviceExtension->DeviceListHead))
1065  {
1066  if (SuggestedLinkName.Buffer)
1067  {
1068  FreePool(SuggestedLinkName.Buffer);
1069  }
1070 
1071  FreePool(UniqueId);
1072  FreePool(TargetDeviceName.Buffer);
1073  FreePool(DeviceInformation->DeviceName.Buffer);
1074  FreePool(DeviceInformation);
1075 
1076  KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
1077 
1078  return STATUS_SUCCESS;
1079  }
1080 
1081  /* Check if there are symlinks associated with our device in registry */
1082  Status = QuerySymbolicLinkNamesFromStorage(DeviceExtension,
1083  DeviceInformation,
1084  (SuggestedLinkName.Buffer) ? &SuggestedLinkName : NULL,
1085  UseOnlyIfThereAreNoOtherLinks,
1086  &SymLinks,
1087  &SymLinkCount,
1088  HasGuid,
1089  &StableGuid);
1090 
1091  /* If our device is a CD-ROM */
1092  if (RtlPrefixUnicodeString(&DeviceCdRom, &TargetDeviceName, TRUE))
1093  {
1094  LinkTarget.Length = 0;
1095  LinkTarget.MaximumLength = sizeof(LinkTargetBuffer);
1096  LinkTarget.Buffer = LinkTargetBuffer;
1097 
1098  RtlCopyMemory(CSymLinkBuffer, Cunc, sizeof(Cunc));
1099  RtlInitUnicodeString(&CSymLink, CSymLinkBuffer);
1100 
1101  /* Start checking all letters that could have been associated */
1102  for (Letter = L'D'; Letter <= L'Z'; Letter++)
1103  {
1104  CSymLink.Buffer[Cunc_LETTER_POSITION] = Letter;
1105 
1107  &CSymLink,
1109  NULL,
1110  NULL);
1111 
1112  /* Try to open the associated symlink */
1114  if (!NT_SUCCESS(Status))
1115  {
1116  continue;
1117  }
1118 
1119  /* And query its target */
1120  Status = ZwQuerySymbolicLinkObject(LinkHandle, &LinkTarget, NULL);
1121  ZwClose(LinkHandle);
1122 
1123  if (!NT_SUCCESS(Status))
1124  {
1125  continue;
1126  }
1127 
1128  IntStatus = STATUS_UNSUCCESSFUL;
1129  if (!RtlEqualUnicodeString(&LinkTarget, &DeviceInformation->DeviceName, FALSE))
1130  {
1131  continue;
1132  }
1133 
1134  /* This link is matching our device, whereas it's not supposed to have any
1135  * symlink associated.
1136  * Delete it
1137  */
1138  if (!SymLinkCount)
1139  {
1140  IoDeleteSymbolicLink(&CSymLink);
1141  continue;
1142  }
1143 
1144  /* Now, for all the symlinks, check for ours */
1145  for (i = 0; i < SymLinkCount; i++)
1146  {
1147  if (IsDriveLetter(&(SymLinks[i])))
1148  {
1149  /* If it exists, that's correct */
1150  if (SymLinks[i].Buffer[LETTER_POSITION] == Letter)
1151  {
1152  IntStatus = STATUS_SUCCESS;
1153  }
1154  }
1155  }
1156 
1157  /* Useless link, delete it */
1158  if (IntStatus == STATUS_UNSUCCESSFUL)
1159  {
1160  IoDeleteSymbolicLink(&CSymLink);
1161  }
1162  }
1163  }
1164 
1165  /* Suggested name is no longer required */
1166  if (SuggestedLinkName.Buffer)
1167  {
1168  FreePool(SuggestedLinkName.Buffer);
1169  }
1170 
1171  /* If if failed, ensure we don't take symlinks into account */
1172  if (!NT_SUCCESS(Status))
1173  {
1174  SymLinks = NULL;
1175  SymLinkCount = 0;
1176  }
1177 
1178  /* Now we queried them, remove the symlinks */
1179  SavedLinkInformation = RemoveSavedLinks(DeviceExtension, UniqueId);
1180 
1181  IsDrvLetter = FALSE;
1182  IsOff = FALSE;
1183  IsVolumeName = FALSE;
1184  /* For all the symlinks */
1185  for (i = 0; i < SymLinkCount; i++)
1186  {
1187  /* Check if our device is a volume */
1188  if (MOUNTMGR_IS_VOLUME_NAME(&(SymLinks[i])))
1189  {
1190  IsVolumeName = TRUE;
1191  }
1192  /* If it has a drive letter */
1193  else if (IsDriveLetter(&(SymLinks[i])))
1194  {
1195  if (IsDrvLetter)
1196  {
1197  DeleteFromLocalDatabase(&(SymLinks[i]), UniqueId);
1198  continue;
1199  }
1200  else
1201  {
1202  IsDrvLetter = TRUE;
1203  }
1204  }
1205 
1206  /* And recreate the symlink to our device */
1207  Status = GlobalCreateSymbolicLink(&(SymLinks[i]), &TargetDeviceName);
1208  if (!NT_SUCCESS(Status))
1209  {
1210  LinkError = TRUE;
1211 
1212  if ((SavedLinkInformation && !RedirectSavedLink(SavedLinkInformation, &(SymLinks[i]), &TargetDeviceName)) ||
1213  !SavedLinkInformation)
1214  {
1215  Status = QueryDeviceInformation(&(SymLinks[i]), &DeviceName, NULL, NULL, NULL, NULL, NULL, NULL);
1216  if (NT_SUCCESS(Status))
1217  {
1218  LinkError = RtlEqualUnicodeString(&TargetDeviceName, &DeviceName, TRUE);
1219  FreePool(DeviceName.Buffer);
1220  }
1221 
1222  if (!LinkError)
1223  {
1224  if (IsDriveLetter(&(SymLinks[i])))
1225  {
1226  IsDrvLetter = FALSE;
1227  DeleteFromLocalDatabase(&(SymLinks[i]), UniqueId);
1228  }
1229 
1230  FreePool(SymLinks[i].Buffer);
1231  continue;
1232  }
1233  }
1234  }
1235 
1236  /* Check if was offline */
1237  if (IsOffline(&(SymLinks[i])))
1238  {
1239  IsOff = TRUE;
1240  }
1241 
1242  /* Finally, associate this symlink with the device */
1243  SymlinkInformation = AllocatePool(sizeof(SYMLINK_INFORMATION));
1244  if (!SymlinkInformation)
1245  {
1246  GlobalDeleteSymbolicLink(&(SymLinks[i]));
1247  FreePool(SymLinks[i].Buffer);
1248  continue;
1249  }
1250 
1251  SymlinkInformation->Name = SymLinks[i];
1252  SymlinkInformation->Online = TRUE;
1253 
1254  InsertTailList(&(DeviceInformation->SymbolicLinksListHead),
1255  &(SymlinkInformation->SymbolicLinksListEntry));
1256  }
1257 
1258  /* Now, for all the recreated symlinks, notify their recreation */
1259  for (NextEntry = DeviceInformation->SymbolicLinksListHead.Flink;
1260  NextEntry != &(DeviceInformation->SymbolicLinksListHead);
1261  NextEntry = NextEntry->Flink)
1262  {
1263  SymlinkInformation = CONTAINING_RECORD(NextEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
1264 
1265  SendLinkCreated(&(SymlinkInformation->Name));
1266  }
1267 
1268  /* If we had saved links, it's time to free them */
1269  if (SavedLinkInformation)
1270  {
1271  MountMgrFreeSavedLink(SavedLinkInformation);
1272  }
1273 
1274  /* If our device doesn't have a volume name */
1275  if (!IsVolumeName)
1276  {
1277  /* It's time to create one */
1279  if (NT_SUCCESS(Status))
1280  {
1281  /* Write it to global database */
1283  DatabasePath,
1285  REG_BINARY,
1286  UniqueId->UniqueId,
1287  UniqueId->UniqueIdLength);
1288 
1289  /* And create the symlink */
1290  GlobalCreateSymbolicLink(&VolumeName, &TargetDeviceName);
1291 
1292  SymlinkInformation = AllocatePool(sizeof(SYMLINK_INFORMATION));
1293  if (!SymlinkInformation)
1294  {
1296  }
1297  /* Finally, associate it with the device and notify creation */
1298  else
1299  {
1300  SymlinkInformation->Name = VolumeName;
1301  SymlinkInformation->Online = TRUE;
1302  InsertTailList(&(DeviceInformation->SymbolicLinksListHead),
1303  &(SymlinkInformation->SymbolicLinksListEntry));
1304 
1306  }
1307  }
1308  }
1309 
1310  /* If we found a drive letter, then, ignore the suggested one */
1311  if (IsDrvLetter)
1312  {
1313  DeviceInformation->SuggestedDriveLetter = 0;
1314  }
1315  /* Else, it's time to set up one */
1316  else if ((DeviceExtension->NoAutoMount || DeviceInformation->Removable) &&
1317  DeviceExtension->AutomaticDriveLetter &&
1318  (HasGptDriveLetter || DeviceInformation->SuggestedDriveLetter) &&
1319  !HasNoDriveLetterEntry(UniqueId))
1320  {
1321  /* Create a new drive letter */
1322  Status = CreateNewDriveLetterName(&DriveLetter, &TargetDeviceName,
1323  DeviceInformation->SuggestedDriveLetter,
1324  NULL);
1325  if (!NT_SUCCESS(Status))
1326  {
1327  CreateNoDriveLetterEntry(UniqueId);
1328  }
1329  else
1330  {
1331  /* Save it to global database */
1333  DatabasePath,
1334  DriveLetter.Buffer,
1335  REG_BINARY,
1336  UniqueId->UniqueId,
1337  UniqueId->UniqueIdLength);
1338 
1339  /* Associate it with the device and notify creation */
1340  SymlinkInformation = AllocatePool(sizeof(SYMLINK_INFORMATION));
1341  if (!SymlinkInformation)
1342  {
1343  FreePool(DriveLetter.Buffer);
1344  }
1345  else
1346  {
1347  SymlinkInformation->Name = DriveLetter;
1348  SymlinkInformation->Online = TRUE;
1349  InsertTailList(&(DeviceInformation->SymbolicLinksListHead),
1350  &(SymlinkInformation->SymbolicLinksListEntry));
1351 
1352  SendLinkCreated(&DriveLetter);
1353  }
1354  }
1355  }
1356 
1357  /* If that's a PnP device, register for notifications */
1358  if (!ManuallyRegistered)
1359  {
1360  RegisterForTargetDeviceNotification(DeviceExtension, DeviceInformation);
1361  }
1362 
1363  /* Finally, insert the device into our devices list */
1364  InsertTailList(&(DeviceExtension->DeviceListHead), &(DeviceInformation->DeviceListEntry));
1365 
1366  /* Copy device unique ID */
1367  NewUniqueId = AllocatePool(UniqueId->UniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
1368  if (NewUniqueId)
1369  {
1370  NewUniqueId->UniqueIdLength = UniqueId->UniqueIdLength;
1371  RtlCopyMemory(NewUniqueId->UniqueId, UniqueId->UniqueId, UniqueId->UniqueIdLength);
1372  }
1373 
1374  /* If device's offline or valid, skip its notifications */
1375  if (IsOff || Valid)
1376  {
1377  DeviceInformation->SkipNotifications = TRUE;
1378  }
1379 
1380  /* In case device is valid and is set to no automount,
1381  * set it offline.
1382  */
1383  if (DeviceExtension->NoAutoMount || IsDrvLetter)
1384  {
1385  IsOff = !DeviceInformation->SkipNotifications;
1386  }
1387  else
1388  {
1389  IsOff = FALSE;
1390  }
1391 
1392  /* Finally, release the exclusive lock */
1393  KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
1394 
1395  /* If device is not offline, notify its arrival */
1396  if (!IsOff)
1397  {
1399  }
1400 
1401  /* If we had symlinks (from storage), free them */
1402  if (SymLinks)
1403  {
1404  FreePool(SymLinks);
1405  }
1406 
1407  /* Notify about unique id change */
1408  if (NewUniqueId)
1409  {
1410  IssueUniqueIdChangeNotify(DeviceExtension, SymbolicName, NewUniqueId);
1411  FreePool(NewUniqueId);
1412  }
1413 
1414  /* If this drive was set to have a drive letter automatically
1415  * Now it's back, local databases sync will be required
1416  */
1417  if (DeviceExtension->AutomaticDriveLetter)
1418  {
1419  KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
1420 
1421  ReconcileThisDatabaseWithMaster(DeviceExtension, DeviceInformation);
1422 
1423  NextEntry = DeviceExtension->DeviceListHead.Flink;
1424  CurrentDevice = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
1425  while (CurrentDevice != DeviceInformation)
1426  {
1427  if (!CurrentDevice->NoDatabase)
1428  {
1429  ReconcileThisDatabaseWithMaster(DeviceExtension, CurrentDevice);
1430  }
1431 
1432  NextEntry = NextEntry->Flink;
1433  CurrentDevice = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
1434  }
1435 
1436  KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
1437  }
1438 
1439  return STATUS_SUCCESS;
1440 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
PWSTR DatabasePath
Definition: database.c:31
#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
VOID DeleteFromLocalDatabase(IN PUNICODE_STRING SymbolicLink, IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: database.c:351
VOID MountMgrFreeDeadDeviceInfo(IN PDEVICE_INFORMATION DeviceInformation)
Definition: mountmgr.c:701
#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:273
#define LETTER_POSITION
Definition: mntmgr.h:159
#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:766
BOOLEAN HasNoDriveLetterEntry(IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: uniqueid.c:354
_Inout_ PUNICODE_STRING LinkTarget
Definition: zwfuncs.h:292
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3272
#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
unsigned char BOOLEAN
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
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI IoSetSystemPartition(IN PUNICODE_STRING VolumeNameString)
Definition: volume.c:1226
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:46
#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:39
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:108
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
VOID ReconcileThisDatabaseWithMaster(IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation)
Definition: database.c:1613
PSAVED_LINK_INFORMATION RemoveSavedLinks(IN PDEVICE_EXTENSION DeviceExtension, IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: symlink.c:640
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
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
#define NULL
Definition: types.h:112
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:598
#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
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
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:190
#define STATUS_SUCCESS
Definition: shellext.h:65
VOID SendLinkCreated(IN PUNICODE_STRING SymbolicName)
Definition: symlink.c:160
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:660
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:40
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 1610 of file mountmgr.c.

1612 {
1613  BOOLEAN OldState;
1614  PDEVICE_EXTENSION DeviceExtension;
1616 
1617  /* Notification for a device arrived */
1618  /* Disable hard errors */
1621 
1622  DeviceExtension = Context;
1624 
1625  /* Dispatch according to the event */
1627  {
1628  MountMgrMountedDeviceArrival(DeviceExtension, Notification->SymbolicLinkName, FALSE);
1629  }
1631  {
1632  MountMgrMountedDeviceRemoval(DeviceExtension, Notification->SymbolicLinkName);
1633  }
1634 
1635  /* Reset hard errors */
1637 
1638  return STATUS_SUCCESS;
1639 }
_In_ PVOID NotificationStructure
Definition: iofuncs.h:1206
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:931
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:1446
BOOLEAN NTAPI PsGetThreadHardErrorsAreDisabled(IN PETHREAD Thread)
Definition: thread.c:695
_In_ PWDFDEVICE_INIT _In_ PFN_WDF_DEVICE_SHUTDOWN_NOTIFICATION Notification
Definition: wdfcontrol.h:113
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
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by DriverEntry().

◆ MountMgrMountedDeviceRemoval()

VOID MountMgrMountedDeviceRemoval ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PUNICODE_STRING  DeviceName 
)

Definition at line 1446 of file mountmgr.c.

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

Referenced by MountMgrMountedDeviceNotification().

◆ MountmgrReadNoAutoMount()

BOOLEAN MountmgrReadNoAutoMount ( IN PUNICODE_STRING  RegistryPath)

Definition at line 898 of file mountmgr.c.

899 {
901  ULONG Result, Default = 0;
903 
905 
906  /* Simply read data from register */
908  QueryTable[0].Name = L"NoAutoMount";
912  QueryTable[0].DefaultLength = sizeof(ULONG);
913 
915  RegistryPath->Buffer,
916  QueryTable,
917  NULL,
918  NULL);
919  if (!NT_SUCCESS(Status))
920  {
921  return (Default != 0);
922  }
923 
924  return (Result != 0);
925 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4155
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
_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
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const WCHAR L[]
Definition: oid.c:1250
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define NULL
Definition: types.h:112
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 1756 of file mountmgr.c.

1758 {
1759  PDEVICE_EXTENSION DeviceExtension;
1760 
1761  DeviceExtension = DeviceObject->DeviceExtension;
1762 
1764 
1766 
1767  /* Wait for workers */
1768  if (InterlockedIncrement(&(DeviceExtension->WorkerReferences)) > 0)
1769  {
1770  KeReleaseSemaphore(&(DeviceExtension->WorkerSemaphore),
1772  1,
1773  FALSE);
1775  }
1776  else
1777  {
1778  InterlockedDecrement(&(DeviceExtension->WorkerReferences));
1779  }
1780 
1781  Irp->IoStatus.Status = STATUS_SUCCESS;
1782  Irp->IoStatus.Information = 0;
1784 
1785  return STATUS_SUCCESS;
1786 }
#define TRUE
Definition: types.h:120
KEVENT UnloadEvent
Definition: mountmgr.c:36
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
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
#define IoCompleteRequest
Definition: irp.c:1240
#define InterlockedDecrement
Definition: armddk.h:52
#define InterlockedExchange
Definition: armddk.h:54
#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 NULL
Definition: types.h:112
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define STATUS_SUCCESS
Definition: shellext.h:65
LONG Unloading
Definition: mountmgr.c:37

Referenced by DriverEntry().

◆ MountMgrUnload()

VOID NTAPI MountMgrUnload ( IN struct _DRIVER_OBJECT DriverObject)

Definition at line 794 of file mountmgr.c.

795 {
796  PLIST_ENTRY NextEntry;
798  PDEVICE_EXTENSION DeviceExtension;
799  PDEVICE_INFORMATION DeviceInformation;
800  PSAVED_LINK_INFORMATION SavedLinkInformation;
801 
803 
804  /* Don't get notification any longer */
806 
807  /* Free registry buffer */
808  DeviceExtension = gdeviceObject->DeviceExtension;
809  if (DeviceExtension->RegistryPath.Buffer)
810  {
811  FreePool(DeviceExtension->RegistryPath.Buffer);
812  DeviceExtension->RegistryPath.Buffer = NULL;
813  }
814 
816 
818 
819  /* Wait for workers to finish */
820  if (InterlockedIncrement(&DeviceExtension->WorkerReferences) > 0)
821  {
822  KeReleaseSemaphore(&(DeviceExtension->WorkerSemaphore),
823  IO_NO_INCREMENT, 1, FALSE);
824 
826  }
827  else
828  {
829  InterlockedDecrement(&(DeviceExtension->WorkerReferences));
830  }
831 
832  /* Don't get any notification any longerĀ² */
833  IoUnregisterPlugPlayNotification(DeviceExtension->NotificationEntry);
834 
835  /* Acquire the driver exclusively */
836  KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode,
837  FALSE, NULL);
838 
839  /* Clear offline devices list */
840  while (!IsListEmpty(&(DeviceExtension->OfflineDeviceListHead)))
841  {
842  NextEntry = RemoveHeadList(&(DeviceExtension->OfflineDeviceListHead));
843  DeviceInformation = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
844  MountMgrFreeDeadDeviceInfo(DeviceInformation);
845  }
846 
847  /* Clear saved links list */
848  while (!IsListEmpty(&(DeviceExtension->SavedLinksListHead)))
849  {
850  NextEntry = RemoveHeadList(&(DeviceExtension->SavedLinksListHead));
851  SavedLinkInformation = CONTAINING_RECORD(NextEntry, SAVED_LINK_INFORMATION, SavedLinksListEntry);
852  MountMgrFreeSavedLink(SavedLinkInformation);
853  }
854 
855  /* Clear workers list */
856  while (!IsListEmpty(&(DeviceExtension->UniqueIdWorkerItemListHead)))
857  {
858  NextEntry = RemoveHeadList(&(DeviceExtension->UniqueIdWorkerItemListHead));
859  WorkItem = CONTAINING_RECORD(NextEntry, UNIQUE_ID_WORK_ITEM, UniqueIdWorkerItemListEntry);
860 
862  WorkItem->Event = &UnloadEvent;
863 
864  KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT,
865  1, FALSE);
866 
867  IoCancelIrp(WorkItem->Irp);
869 
870  IoFreeIrp(WorkItem->Irp);
871  FreePool(WorkItem->DeviceName.Buffer);
872  FreePool(WorkItem->IrpBuffer);
874 
875  KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode,
876  FALSE, NULL);
877  }
878 
879  /* If we have drive letter data, release */
880  if (DeviceExtension->DriveLetterData)
881  {
882  FreePool(DeviceExtension->DriveLetterData);
883  DeviceExtension->DriveLetterData = NULL;
884  }
885 
886  /* Release driver & quit */
887  KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
888 
891 }
VOID MountMgrFreeDeadDeviceInfo(IN PDEVICE_INFORMATION DeviceInformation)
Definition: mountmgr.c:701
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
KEVENT UnloadEvent
Definition: mountmgr.c:36
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:766
#define FALSE
Definition: types.h:117
PVOID DeviceExtension
Definition: env_spec_w32.h:418
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
PDEVICE_OBJECT gdeviceObject
Definition: mountmgr.c:35
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
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
VOID NTAPI IoUnregisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1725
NTSTATUS NTAPI IoUnregisterPlugPlayNotification(_In_ PVOID NotificationEntry)
Definition: pnpnotify.c:479
#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
#define NULL
Definition: types.h:112
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:598
_Must_inspect_result_ _In_ PWDF_WORKITEM_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWORKITEM * WorkItem
Definition: wdfworkitem.h:110
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
LONG Unloading
Definition: mountmgr.c:37

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 190 of file mountmgr.c.

198 {
199  PIRP Irp;
200  USHORT Size;
201  KEVENT Event;
202  BOOLEAN IsRemovable;
207  NTSTATUS Status, IntStatus;
211  STORAGE_DEVICE_NUMBER StorageDeviceNumber;
213 
214  /* Get device associated with the symbolic name */
217  &FileObject,
218  &DeviceObject);
219  if (!NT_SUCCESS(Status))
220  {
221  return Status;
222  }
223 
224  /* The associate FO can't have a file name */
225  if (FileObject->FileName.Length)
226  {
229  }
230 
231  /* Check if it's removable & return to the user (if asked to) */
232  IsRemovable = (FileObject->DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA);
233  if (Removable)
234  {
235  *Removable = IsRemovable;
236  }
237 
238  /* Get the attached device */
240 
241  /* If we've been asked for a GPT drive letter */
242  if (GptDriveLetter)
243  {
244  /* Consider it has one */
245  *GptDriveLetter = TRUE;
246 
247  if (!IsRemovable)
248  {
249  /* Query the GPT attributes */
252  DeviceObject,
253  NULL,
254  0,
255  &GptAttributes,
256  sizeof(GptAttributes),
257  FALSE,
258  &Event,
259  &IoStatusBlock);
260  if (!Irp)
261  {
265  }
266 
268  if (Status == STATUS_PENDING)
269  {
272  }
273 
274  /* In case of failure, don't fail, that's no vital */
275  if (!NT_SUCCESS(Status))
276  {
278  }
279  /* Check if it has a drive letter */
280  else if (GptAttributes.GptAttributes & GPT_BASIC_DATA_ATTRIBUTE_NO_DRIVE_LETTER)
281  {
282  *GptDriveLetter = FALSE;
283  }
284  }
285  }
286 
287  /* If caller wants to know if there's valid contents */
288  if (Valid)
289  {
290  /* Suppose it's not OK */
291  *Valid = FALSE;
292 
293  if (!IsRemovable)
294  {
295  /* Query partitions information */
298  DeviceObject,
299  NULL,
300  0,
301  &PartitionInfo,
302  sizeof(PartitionInfo),
303  FALSE,
304  &Event,
305  &IoStatusBlock);
306  if (!Irp)
307  {
311  }
312 
314  if (Status == STATUS_PENDING)
315  {
318  }
319 
320  /* Once again here, failure isn't major */
321  if (!NT_SUCCESS(Status))
322  {
324  }
325  /* Verify we know something in */
326  else if (PartitionInfo.PartitionStyle == PARTITION_STYLE_MBR &&
327  IsRecognizedPartition(PartitionInfo.Mbr.PartitionType))
328  {
329  *Valid = TRUE;
330  }
331 
332  /* It looks correct, ensure it is & query device number */
333  if (*Valid)
334  {
337  DeviceObject,
338  NULL,
339  0,
340  &StorageDeviceNumber,
341  sizeof(StorageDeviceNumber),
342  FALSE,
343  &Event,
344  &IoStatusBlock);
345  if (!Irp)
346  {
350  }
351 
353  if (Status == STATUS_PENDING)
354  {
357  }
358 
359  if (!NT_SUCCESS(Status))
360  {
362  }
363  else
364  {
365  *Valid = FALSE;
366  }
367  }
368  }
369  }
370 
371  /* If caller needs device name */
372  if (DeviceName)
373  {
374  /* Allocate a buffer just to request length */
375  Name = AllocatePool(sizeof(MOUNTDEV_NAME));
376  if (!Name)
377  {
381  }
382 
383  /* Query device name */
386  DeviceObject,
387  NULL,
388  0,
389  Name,
390  sizeof(MOUNTDEV_NAME),
391  FALSE,
392  &Event,
393  &IoStatusBlock);
394  if (!Irp)
395  {
396  FreePool(Name);
400  }
401 
403  Stack->FileObject = FileObject;
404 
406  if (Status == STATUS_PENDING)
407  {
410  }
411 
412  /* Now, we've got the correct length */
414  {
415  Size = Name->NameLength + sizeof(MOUNTDEV_NAME);
416 
417  FreePool(Name);
418 
419  /* Allocate proper size */
421  if (!Name)
422  {
426  }
427 
428  /* And query name (for real that time) */
431  DeviceObject,
432  NULL,
433  0,
434  Name,
435  Size,
436  FALSE,
437  &Event,
438  &IoStatusBlock);
439  if (!Irp)
440  {
441  FreePool(Name);
445  }
446 
448  Stack->FileObject = FileObject;
449 
451  if (Status == STATUS_PENDING)
452  {
455  }
456  }
457 
458  if (NT_SUCCESS(Status))
459  {
460  /* Copy back found name to the caller */
461  DeviceName->Length = Name->NameLength;
462  DeviceName->MaximumLength = Name->NameLength + sizeof(WCHAR);
463  DeviceName->Buffer = AllocatePool(DeviceName->MaximumLength);
464  if (!DeviceName->Buffer)
465  {
467  }
468  else
469  {
470  RtlCopyMemory(DeviceName->Buffer, Name->Name, Name->NameLength);
471  DeviceName->Buffer[Name->NameLength / sizeof(WCHAR)] = UNICODE_NULL;
472  }
473  }
474 
475  FreePool(Name);
476  }
477 
478  if (!NT_SUCCESS(Status))
479  {
482  return Status;
483  }
484 
485  /* If caller wants device unique ID */
486  if (UniqueId)
487  {
488  /* Prepare buffer to probe length */
490  if (!Id)
491  {
495  }
496 
497  /* Query unique ID length */
500  DeviceObject,
501  NULL,
502  0,
503  Id,
504  sizeof(MOUNTDEV_UNIQUE_ID),
505  FALSE,
506  &Event,
507  &IoStatusBlock);
508  if (!Irp)
509  {
510  FreePool(Id);
514  }
515 
517  Stack->FileObject = FileObject;
518 
520  if (Status == STATUS_PENDING)
521  {
524  }
525 
526  /* Retry with appropriate length */
528  {
529  Size = Id->UniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID);
530 
531  FreePool(Id);
532 
533  /* Allocate the correct buffer */
534  Id = AllocatePool(Size);
535  if (!Id)
536  {
540  }
541 
542  /* Query unique ID */
545  DeviceObject,
546  NULL,
547  0,
548  Id,
549  Size,
550  FALSE,
551  &Event,
552  &IoStatusBlock);
553  if (!Irp)
554  {
555  FreePool(Id);
559  }
560 
562  Stack->FileObject = FileObject;
563 
565  if (Status == STATUS_PENDING)
566  {
569  }
570  }
571 
572  /* Hands back unique ID */
573  if (NT_SUCCESS(Status))
574  {
575  *UniqueId = Id;
576  }
577  else
578  {
579  /* In case of failure, also free the rest */
580  FreePool(Id);
581  if (DeviceName->Length)
582  {
583  FreePool(DeviceName->Buffer);
584  }
585 
588 
589  return Status;
590  }
591  }
592 
593  /* If user wants to know about GUID */
594  if (HasGuid)
595  {
596  /* Query device stable GUID */
599  DeviceObject,
600  NULL,
601  0,
602  StableGuid,
603  sizeof(GUID),
604  FALSE,
605  &Event,
606  &IoStatusBlock);
607  if (!Irp)
608  {
612  }
613 
615  Stack->FileObject = FileObject;
616 
617  IntStatus = IoCallDriver(DeviceObject, Irp);
618  if (IntStatus == STATUS_PENDING)
619  {
621  IntStatus = IoStatusBlock.Status;
622  }
623 
624  *HasGuid = NT_SUCCESS(IntStatus);
625  }
626 
629  return Status;
630 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define TRUE
Definition: types.h:120
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
LONG NTSTATUS
Definition: precomp.h:26
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
#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
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:636
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
Definition: imports.h:80
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3272
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
_In_ PIRP Irp
Definition: csq.h:116
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
struct NameRec_ * Name
Definition: cdprocs.h:459
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:467
struct _MOUNTDEV_NAME MOUNTDEV_NAME
unsigned char BOOLEAN
#define IOCTL_STORAGE_GET_DEVICE_NUMBER
Definition: ntddstor.h:143
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
#define IOCTL_MOUNTDEV_QUERY_STABLE_GUID
Definition: imports.h:255
Status
Definition: gdiplustypes.h:24
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
#define ObDereferenceObject
Definition: obfuncs.h:203
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2105
* PFILE_OBJECT
Definition: iotypes.h:1998
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define AllocatePool(Size)
Definition: mntmgr.h:153
#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
#define NULL
Definition: types.h:112
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
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
#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 39 of file mountmgr.c.

Referenced by MountMgrMountedDeviceArrival().

◆ gdeviceObject

PDEVICE_OBJECT gdeviceObject

Definition at line 35 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 33 of file mountmgr.c.

Referenced by DriverEntry().

◆ UnloadEvent

KEVENT UnloadEvent

Definition at line 36 of file mountmgr.c.

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

◆ Unloading

LONG Unloading

Definition at line 37 of file mountmgr.c.

Referenced by MountMgrShutdown(), and MountMgrUnload().