ReactOS 0.4.15-dev-8434-g155a7c7
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

 _IRQL_requires_ (PASSIVE_LEVEL)
 Sends a synchronous IOCTL to the specified device object.
 
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_opt_ PUNICODE_STRING DeviceName, _Out_opt_ PMOUNTDEV_UNIQUE_ID *UniqueId, _Out_opt_ PBOOLEAN Removable, _Out_opt_ PBOOLEAN GptDriveLetter, _Out_opt_ PBOOLEAN HasGuid, _Inout_opt_ LPGUID StableGuid, _Out_opt_ PBOOLEAN IsFT)
 
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 PDRIVER_OBJECT DriverObject)
 
BOOLEAN MountmgrReadNoAutoMount (_In_ PUNICODE_STRING RegistryPath)
 Retrieves the "NoAutoMount" setting.
 
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

◆ _IRQL_requires_()

_IRQL_requires_ ( PASSIVE_LEVEL  )

Sends a synchronous IOCTL to the specified device object.

Parameters
[in]IoControlCodeThe IOCTL to send to the device.
[in]DeviceObjectPointer to the device object that will handle the IOCTL.
[in]InputBufferOptional pointer to a buffer containing input data for the IOCTL. When specified, the buffer should be at least of InputBufferLength size.
[in]InputBufferLengthSize in bytes, of the buffer pointed by InputBuffer.
[out]OutputBufferOptional pointer to a buffer that will receive output data from the IOCTL. When specified, the buffer should be at least of OutputBufferLength size.
[in]OutputBufferLengthSize in bytes, of the buffer pointed by OutputBuffer.
[in]FileObjectOptional pointer to a file object that may be necessary for the IOCTL.
Returns
An NTSTATUS code indicating success or failure of this function.
Note
Must be called at PASSIVE_LEVEL with all APCs enabled.

Definition at line 75 of file mountmgr.c.

85{
89 PIRP Irp;
90
91 /* We must be at passive level as we are using an on-stack event, and
92 * APCs must be enabled for allowing the Special Kernel APC queued by
93 * the IO Manager to run for completing the IRP */
96
97 /* Initialize the on-stack notification event and build the threaded IRP */
105 FALSE,
106 &Event,
108 if (!Irp)
110
111 /* Set up the FileObject for the IOCTL if required */
112 if (FileObject)
114
115 /* Finally, call the driver and wait for IRP completion if necessary */
117 if (Status == STATUS_PENDING)
118 {
121 }
122
123 return Status;
124}
LONG NTSTATUS
Definition: precomp.h:26
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define ASSERT_IRQL_EQUAL(x)
Definition: debug.h:43
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
Status
Definition: gdiplustypes.h:25
#define ASSERT(a)
Definition: mode.c:44
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define KernelMode
Definition: asm.h:34
@ NotificationEvent
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 IoCallDriver
Definition: irp.c:1225
BOOLEAN NTAPI KeAreAllApcsDisabled(VOID)
Definition: apc.c:985
#define STATUS_PENDING
Definition: ntstatus.h:82
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_In_ WDFREQUEST _In_ size_t _In_ size_t _In_ ULONG IoControlCode
Definition: wdfio.h:325
_In_ WDFREQUEST _In_ size_t OutputBufferLength
Definition: wdfio.h:320
_In_ WDFREQUEST _In_ size_t _In_ size_t InputBufferLength
Definition: wdfio.h:322
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
@ Executive
Definition: ketypes.h:415

◆ CreateNewDriveLetterName()

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

Definition at line 192 of file mountmgr.c.

196{
198
199 /* Allocate a big enough buffer to contain the symbolic link */
200 DriveLetter->MaximumLength = DosDevices.Length + 3 * sizeof(WCHAR);
201 DriveLetter->Buffer = AllocatePool(DriveLetter->MaximumLength);
202 if (!DriveLetter->Buffer)
203 {
205 }
206
207 /* Copy prefix */
208 RtlCopyUnicodeString(DriveLetter, &DosDevices);
209
210 /* Update string to reflect real contents */
211 DriveLetter->Length = DosDevices.Length + 2 * sizeof(WCHAR);
212 DriveLetter->Buffer[DosDevices.Length / sizeof(WCHAR) + 2] = UNICODE_NULL;
213 DriveLetter->Buffer[DosDevices.Length / sizeof(WCHAR) + 1] = L':';
214
215 /* If caller wants a no drive entry */
216 if (Letter == (UCHAR)-1)
217 {
218 /* Then, create a no letter entry */
219 CreateNoDriveLetterEntry(UniqueId);
220 FreePool(DriveLetter->Buffer);
221 return STATUS_UNSUCCESSFUL;
222 }
223 else if (Letter)
224 {
225 /* Use the letter given by the caller */
226 DriveLetter->Buffer[DosDevices.Length / sizeof(WCHAR)] = (WCHAR)Letter;
228 if (NT_SUCCESS(Status))
229 {
230 return Status;
231 }
232 }
233
234 /* If caller didn't provide a letter, let's find one for him */
235
237 {
238 /* If the device is a floppy, start with letter A */
239 Letter = 'A';
240 }
242 {
243 /* If the device is a CD-ROM, start with letter D */
244 Letter = 'D';
245 }
246 else
247 {
248 /* Finally, if it's a disk, use C */
249 Letter = 'C';
250 }
251
252 /* Try to affect a letter (up to Z, ofc) until it's possible */
253 for (; Letter <= 'Z'; Letter++)
254 {
255 DriveLetter->Buffer[DosDevices.Length / sizeof(WCHAR)] = (WCHAR)Letter;
257 if (NT_SUCCESS(Status))
258 {
259 DPRINT("Assigned drive %c: to %wZ\n", Letter, DeviceName);
260 return Status;
261 }
262 }
263
264 /* We failed to allocate a letter */
265 FreePool(DriveLetter->Buffer);
266 DPRINT("Failed to create a drive letter for %wZ\n", DeviceName);
267 return Status;
268}
WCHAR Letter
#define TRUE
Definition: types.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
NTSTATUS GlobalCreateSymbolicLink(IN PUNICODE_STRING DosName, IN PUNICODE_STRING DeviceName)
Definition: symlink.c:120
UNICODE_STRING DeviceFloppy
Definition: symlink.c:43
UNICODE_STRING DeviceCdRom
Definition: symlink.c:44
#define AllocatePool(Size)
Definition: mntmgr.h:153
#define FreePool(P)
Definition: mntmgr.h:154
UNICODE_STRING DosDevices
Definition: symlink.c:42
VOID CreateNoDriveLetterEntry(IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: uniqueid.c:269
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
#define UNICODE_NULL
#define L(x)
Definition: ntvdm.h:50
#define DPRINT
Definition: sndvol32.h:73
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by MountMgrMountedDeviceArrival().

◆ DriverEntry()

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

Definition at line 1709 of file mountmgr.c.

1711{
1714 PDEVICE_EXTENSION DeviceExtension;
1715
1717
1719 sizeof(DEVICE_EXTENSION),
1720 &DeviceMount,
1723 FALSE,
1724 &DeviceObject);
1725 if (!NT_SUCCESS(Status))
1726 {
1727 return Status;
1728 }
1729
1730 DriverObject->DriverUnload = MountMgrUnload;
1731
1732 DeviceExtension = DeviceObject->DeviceExtension;
1733 RtlZeroMemory(DeviceExtension, sizeof(DEVICE_EXTENSION));
1734 DeviceExtension->DeviceObject = DeviceObject;
1735 DeviceExtension->DriverObject = DriverObject;
1736
1737 InitializeListHead(&(DeviceExtension->DeviceListHead));
1738 InitializeListHead(&(DeviceExtension->OfflineDeviceListHead));
1739
1740 KeInitializeSemaphore(&(DeviceExtension->DeviceLock), 1, 1);
1741 KeInitializeSemaphore(&(DeviceExtension->RemoteDatabaseLock), 1, 1);
1742
1743 InitializeListHead(&(DeviceExtension->IrpListHead));
1744 DeviceExtension->EpicNumber = 1;
1745
1746 InitializeListHead(&(DeviceExtension->SavedLinksListHead));
1747
1748 InitializeListHead(&(DeviceExtension->WorkerQueueListHead));
1749 KeInitializeSemaphore(&(DeviceExtension->WorkerSemaphore), 0, MAXLONG);
1750 DeviceExtension->WorkerReferences = -1;
1751 KeInitializeSpinLock(&(DeviceExtension->WorkerLock));
1752
1753 InitializeListHead(&(DeviceExtension->UniqueIdWorkerItemListHead));
1754 InitializeListHead(&(DeviceExtension->OnlineNotificationListHead));
1755 DeviceExtension->OnlineNotificationCount = 1;
1756
1757 DeviceExtension->RegistryPath.Length = RegistryPath->Length;
1758 DeviceExtension->RegistryPath.MaximumLength = RegistryPath->Length + sizeof(WCHAR);
1759 DeviceExtension->RegistryPath.Buffer = AllocatePool(DeviceExtension->RegistryPath.MaximumLength);
1760 if (!DeviceExtension->RegistryPath.Buffer)
1761 {
1764 }
1765
1766 RtlCopyUnicodeString(&(DeviceExtension->RegistryPath), RegistryPath);
1767
1768 DeviceExtension->NoAutoMount = MountmgrReadNoAutoMount(&(DeviceExtension->RegistryPath));
1769
1771
1772 /* Register for device arrival & removal. Ask to be notified for already
1773 * present devices
1774 */
1780 DeviceExtension,
1781 &(DeviceExtension->NotificationEntry));
1782
1783 if (!NT_SUCCESS(Status))
1784 {
1786 return Status;
1787 }
1788
1789 DriverObject->MajorFunction[IRP_MJ_CREATE] =
1794
1796
1798 if (!NT_SUCCESS(Status))
1799 {
1801 }
1802
1803 return Status;
1804}
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
PWSTR DatabasePath
Definition: database.c:31
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
DRIVER_DISPATCH MountMgrDeviceControl
Definition: mntmgr.h:344
UNICODE_STRING DosDevicesMount
Definition: symlink.c:41
UNICODE_STRING DeviceMount
Definition: symlink.c:40
NTSTATUS NTAPI MountMgrShutdown(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: mountmgr.c:1672
NTSTATUS NTAPI MountMgrMountedDeviceNotification(IN PVOID NotificationStructure, IN PVOID Context)
Definition: mountmgr.c:1526
VOID NTAPI MountMgrUnload(IN PDRIVER_OBJECT DriverObject)
Definition: mountmgr.c:719
GUID MountedDevicesGuid
Definition: mountmgr.c:33
PDEVICE_OBJECT gdeviceObject
Definition: mountmgr.c:35
NTSTATUS NTAPI MountMgrCleanup(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: mountmgr.c:1611
BOOLEAN MountmgrReadNoAutoMount(_In_ PUNICODE_STRING RegistryPath)
Retrieves the "NoAutoMount" setting.
Definition: mountmgr.c:824
NTSTATUS NTAPI MountMgrCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: mountmgr.c:1562
NTSYSAPI NTSTATUS NTAPI RtlCreateRegistryKey(_In_ ULONG RelativeTo, _In_ PWSTR Path)
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
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
NTSTATUS NTAPI IoRegisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1694
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
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
#define FILE_DEVICE_NETWORK
Definition: winioctl.h:63
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
VOID NTAPI KeInitializeSemaphore(IN PKSEMAPHORE Semaphore, IN LONG Count, IN LONG Limit)
Definition: semphobj.c:22
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define MAXLONG
Definition: umtypes.h:116
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
@ EventCategoryDeviceInterfaceChange
Definition: iotypes.h:1226
#define IRP_MJ_SHUTDOWN
#define IRP_MJ_CLEANUP
#define PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES
Definition: iotypes.h:1239

◆ FindDeviceInfo()

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

Definition at line 561 of file mountmgr.c.

565{
567 PLIST_ENTRY NextEntry;
570
571 /* If a device name was given, use it */
572 if (DeviceNameGiven)
573 {
576 }
577 else
578 {
579 /* Otherwise, query it */
581 &DeviceName,
582 NULL, NULL,
583 NULL, NULL,
584 NULL, NULL);
585 if (!NT_SUCCESS(Status))
586 {
587 return Status;
588 }
589 }
590
591 /* Look for device information matching devive */
592 for (NextEntry = DeviceExtension->DeviceListHead.Flink;
593 NextEntry != &(DeviceExtension->DeviceListHead);
594 NextEntry = NextEntry->Flink)
595 {
596 DeviceInfo = CONTAINING_RECORD(NextEntry,
598 DeviceListEntry);
599
600 if (RtlEqualUnicodeString(&DeviceName, &(DeviceInfo->DeviceName), TRUE))
601 {
602 break;
603 }
604 }
605
606 /* Release our buffer if required */
607 if (!DeviceNameGiven)
608 {
609 FreePool(DeviceName.Buffer);
610 }
611
612 /* Return found information */
613 if (NextEntry == &(DeviceExtension->DeviceListHead))
614 {
616 }
617
618 *DeviceInformation = DeviceInfo;
619 return STATUS_SUCCESS;
620}
NTSTATUS QueryDeviceInformation(_In_ PUNICODE_STRING SymbolicName, _Out_opt_ PUNICODE_STRING DeviceName, _Out_opt_ PMOUNTDEV_UNIQUE_ID *UniqueId, _Out_opt_ PBOOLEAN Removable, _Out_opt_ PBOOLEAN GptDriveLetter, _Out_opt_ PBOOLEAN HasGuid, _Inout_opt_ LPGUID StableGuid, _Out_opt_ PBOOLEAN IsFT)
Definition: mountmgr.c:274
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4677
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define STATUS_SUCCESS
Definition: shellext.h:65
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149

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

◆ HasDriveLetter()

BOOLEAN HasDriveLetter ( IN PDEVICE_INFORMATION  DeviceInformation)

Definition at line 167 of file mountmgr.c.

168{
169 PLIST_ENTRY NextEntry;
170 PSYMLINK_INFORMATION SymlinkInfo;
171
172 /* Browse all the symlinks to check if there is at least a drive letter */
173 for (NextEntry = DeviceInformation->SymbolicLinksListHead.Flink;
174 NextEntry != &DeviceInformation->SymbolicLinksListHead;
175 NextEntry = NextEntry->Flink)
176 {
177 SymlinkInfo = CONTAINING_RECORD(NextEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
178
179 if (IsDriveLetter(&SymlinkInfo->Name) && SymlinkInfo->Online)
180 {
181 return TRUE;
182 }
183 }
184
185 return FALSE;
186}
BOOLEAN IsDriveLetter(PUNICODE_STRING SymbolicName)
Definition: symlink.c:812

Referenced by MountMgrCreatePointWorker(), and ProcessSuggestedDriveLetters().

◆ IsOffline()

BOOLEAN IsOffline ( PUNICODE_STRING  SymbolicName)

Definition at line 130 of file mountmgr.c.

131{
135
136 /* Prepare to look in the registry to see if
137 * given volume is offline
138 */
144 QueryTable[0].DefaultLength = sizeof(ULONG);
146
147 Default = 0;
148
149 /* Query status */
153 NULL,
154 NULL);
155 if (!NT_SUCCESS(Status))
156 {
157 IsOffline = 0;
158 }
159
160 return (IsOffline != 0);
161}
PWSTR OfflinePath
Definition: database.c:32
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
BOOLEAN IsOffline(PUNICODE_STRING SymbolicName)
Definition: mountmgr.c:130
@ Default
Definition: stdole2.idl:392
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4220
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
#define REG_DWORD
Definition: sdbapi.c:596
uint32_t ULONG
Definition: typedefs.h:59

Referenced by IsOffline(), and MountMgrMountedDeviceArrival().

◆ MountMgrCancel()

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

Definition at line 1592 of file mountmgr.c.

1594{
1596
1597 RemoveEntryList(&(Irp->Tail.Overlay.ListEntry));
1598
1599 IoReleaseCancelSpinLock(Irp->CancelIrql);
1600
1601 Irp->IoStatus.Information = 0;
1602 Irp->IoStatus.Status = STATUS_CANCELLED;
1604}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define IoCompleteRequest
Definition: irp.c:1240
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
#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 1611 of file mountmgr.c.

1613{
1614 PIRP ListIrp;
1615 KIRQL OldIrql;
1616 PLIST_ENTRY NextEntry;
1619 PDEVICE_EXTENSION DeviceExtension;
1620
1621 DeviceExtension = DeviceObject->DeviceExtension;
1623 FileObject = Stack->FileObject;
1624
1626
1627 /* If IRP list if empty, it's OK */
1628 if (IsListEmpty(&(DeviceExtension->IrpListHead)))
1629 {
1631
1632 Irp->IoStatus.Status = STATUS_SUCCESS;
1633 Irp->IoStatus.Information = 0;
1635
1636 return STATUS_SUCCESS;
1637 }
1638
1639 /* Otherwise, cancel all the IRPs */
1640 NextEntry = DeviceExtension->IrpListHead.Flink;
1641 do
1642 {
1643 ListIrp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
1645 {
1646 ListIrp->Cancel = TRUE;
1647 ListIrp->CancelIrql = OldIrql;
1648 ListIrp->CancelRoutine = NULL;
1649 MountMgrCancel(DeviceObject, ListIrp);
1650
1652 }
1653
1654 NextEntry = NextEntry->Flink;
1655 }
1656 while (NextEntry != &(DeviceExtension->IrpListHead));
1657
1659
1660 Irp->IoStatus.Status = STATUS_SUCCESS;
1661 Irp->IoStatus.Information = 0;
1663
1664 return STATUS_SUCCESS;
1665}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID NTAPI MountMgrCancel(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: mountmgr.c:1592
VOID NTAPI IoAcquireCancelSpinLock(OUT PKIRQL Irql)
Definition: util.c:56
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
* PFILE_OBJECT
Definition: iotypes.h:1998
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by DriverEntry().

◆ MountMgrCreateClose()

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

Definition at line 1562 of file mountmgr.c.

1564{
1567
1569
1571
1572 /* Allow driver opening for communication
1573 * as long as it's not taken for a directory
1574 */
1575 if (Stack->MajorFunction == IRP_MJ_CREATE &&
1576 Stack->Parameters.Create.Options & FILE_DIRECTORY_FILE)
1577 {
1579 }
1580
1581 Irp->IoStatus.Status = Status;
1582 Irp->IoStatus.Information = 0;
1584 return Status;
1585}
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169

Referenced by DriverEntry().

◆ MountMgrFreeDeadDeviceInfo()

VOID MountMgrFreeDeadDeviceInfo ( IN PDEVICE_INFORMATION  DeviceInformation)

Definition at line 626 of file mountmgr.c.

627{
628 FreePool(DeviceInformation->SymbolicName.Buffer);
629 FreePool(DeviceInformation);
630}

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

◆ MountMgrFreeMountedDeviceInfo()

VOID MountMgrFreeMountedDeviceInfo ( IN PDEVICE_INFORMATION  DeviceInformation)

Definition at line 636 of file mountmgr.c.

637{
638 PLIST_ENTRY NextEntry;
639 PSYMLINK_INFORMATION SymLink;
640 PUNIQUE_ID_REPLICATE UniqueId;
642
643 /* Purge symbolic links list */
644 while (!IsListEmpty(&(DeviceInformation->SymbolicLinksListHead)))
645 {
646 NextEntry = RemoveHeadList(&(DeviceInformation->SymbolicLinksListHead));
647 SymLink = CONTAINING_RECORD(NextEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
648
649 GlobalDeleteSymbolicLink(&(SymLink->Name));
650 FreePool(SymLink->Name.Buffer);
651 }
652
653 /* Purge replicated unique IDs list */
654 while (!IsListEmpty(&(DeviceInformation->ReplicatedUniqueIdsListHead)))
655 {
656 NextEntry = RemoveHeadList(&(DeviceInformation->ReplicatedUniqueIdsListHead));
657 UniqueId = CONTAINING_RECORD(NextEntry, UNIQUE_ID_REPLICATE, ReplicatedUniqueIdsListEntry);
658
659 FreePool(UniqueId->UniqueId);
660 FreePool(UniqueId);
661 }
662
663 while (!IsListEmpty(&(DeviceInformation->AssociatedDevicesHead)))
664 {
665 NextEntry = RemoveHeadList(&(DeviceInformation->AssociatedDevicesHead));
666 AssociatedDevice = CONTAINING_RECORD(NextEntry, ASSOCIATED_DEVICE_ENTRY, AssociatedDevicesEntry);
667
668 FreePool(AssociatedDevice->String.Buffer);
670 }
671
672 /* Free the rest of the buffers */
673 FreePool(DeviceInformation->SymbolicName.Buffer);
674 if (DeviceInformation->KeepLinks)
675 {
676 FreePool(DeviceInformation->UniqueId);
677 }
678 FreePool(DeviceInformation->DeviceName.Buffer);
679
680 /* Finally, stop waiting for notifications for this device */
681 if (DeviceInformation->TargetDeviceNotificationEntry)
682 {
683 IoUnregisterPlugPlayNotification(DeviceInformation->TargetDeviceNotificationEntry);
684 }
685}
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
NTSTATUS GlobalDeleteSymbolicLink(IN PUNICODE_STRING DosName)
Definition: symlink.c:145
NTSTATUS NTAPI IoUnregisterPlugPlayNotification(_In_ PVOID NotificationEntry)
Definition: pnpnotify.c:479
Definition: mntmgr.h:96
PMOUNTDEV_UNIQUE_ID UniqueId
Definition: mntmgr.h:82
_In_ WDFDEVICE AssociatedDevice
Definition: wdfinterrupt.h:173

◆ MountMgrFreeSavedLink()

VOID MountMgrFreeSavedLink ( IN PSAVED_LINK_INFORMATION  SavedLinkInformation)

Definition at line 691 of file mountmgr.c.

692{
693 PLIST_ENTRY NextEntry;
694 PSYMLINK_INFORMATION SymlinkInformation;
695
696 /* For all the saved links */
697 while (!IsListEmpty(&(SavedLinkInformation->SymbolicLinksListHead)))
698 {
699 NextEntry = RemoveHeadList(&(SavedLinkInformation->SymbolicLinksListHead));
700 SymlinkInformation = CONTAINING_RECORD(NextEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
701
702 /* Remove from system & free */
703 GlobalDeleteSymbolicLink(&(SymlinkInformation->Name));
704 FreePool(SymlinkInformation->Name.Buffer);
705 FreePool(SymlinkInformation);
706 }
707
708 /* And free unique ID & entry */
709 FreePool(SavedLinkInformation->UniqueId);
710 FreePool(SavedLinkInformation);
711}

Referenced by MountMgrMountedDeviceArrival(), and MountMgrUnload().

◆ MountMgrMountedDeviceArrival()

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

Definition at line 855 of file mountmgr.c.

858{
860 GUID StableGuid;
861 HANDLE LinkHandle;
862 ULONG SymLinkCount, i;
863 PLIST_ENTRY NextEntry;
864 PUNICODE_STRING SymLinks;
865 NTSTATUS Status, IntStatus;
867 PSYMLINK_INFORMATION SymlinkInformation;
868 PMOUNTDEV_UNIQUE_ID UniqueId, NewUniqueId;
869 PSAVED_LINK_INFORMATION SavedLinkInformation;
870 PDEVICE_INFORMATION DeviceInformation, CurrentDevice;
871 WCHAR CSymLinkBuffer[RTL_NUMBER_OF(Cunc)], LinkTargetBuffer[MAX_PATH];
872 UNICODE_STRING TargetDeviceName, SuggestedLinkName, DeviceName, VolumeName, DriveLetter, LinkTarget, CSymLink;
873 BOOLEAN HasGuid, HasGptDriveLetter, IsFT, UseOnlyIfThereAreNoOtherLinks;
874 BOOLEAN IsDrvLetter, IsOff, IsVolumeName, SetOnline;
875
876 /* New device = new structure to represent it */
877 DeviceInformation = AllocatePool(sizeof(DEVICE_INFORMATION));
878 if (!DeviceInformation)
879 {
881 }
882
883 /* Initialise device structure */
884 RtlZeroMemory(DeviceInformation, sizeof(DEVICE_INFORMATION));
885 InitializeListHead(&(DeviceInformation->SymbolicLinksListHead));
886 InitializeListHead(&(DeviceInformation->ReplicatedUniqueIdsListHead));
887 InitializeListHead(&(DeviceInformation->AssociatedDevicesHead));
888 DeviceInformation->SymbolicName.Length = SymbolicName->Length;
889 DeviceInformation->SymbolicName.MaximumLength = SymbolicName->Length + sizeof(UNICODE_NULL);
890 DeviceInformation->SymbolicName.Buffer = AllocatePool(DeviceInformation->SymbolicName.MaximumLength);
891 if (!DeviceInformation->SymbolicName.Buffer)
892 {
893 FreePool(DeviceInformation);
895 }
896
897 /* Copy symbolic name */
899 DeviceInformation->SymbolicName.Buffer[DeviceInformation->SymbolicName.Length / sizeof(WCHAR)] = UNICODE_NULL;
900 DeviceInformation->ManuallyRegistered = ManuallyRegistered;
901 DeviceInformation->DeviceExtension = DeviceExtension;
902
903 /* Query as much data as possible about device */
905 &TargetDeviceName,
906 &UniqueId,
907 &(DeviceInformation->Removable),
908 &HasGptDriveLetter,
909 &HasGuid,
910 &StableGuid,
911 &IsFT);
912 if (!NT_SUCCESS(Status))
913 {
914 KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
915
916 for (NextEntry = DeviceExtension->OfflineDeviceListHead.Flink;
917 NextEntry != &(DeviceExtension->OfflineDeviceListHead);
918 NextEntry = NextEntry->Flink)
919 {
920 CurrentDevice = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
921
922 if (RtlEqualUnicodeString(&(DeviceInformation->SymbolicName), &(CurrentDevice->SymbolicName), TRUE))
923 {
924 break;
925 }
926 }
927
928 if (NextEntry != &(DeviceExtension->OfflineDeviceListHead))
929 {
930 MountMgrFreeDeadDeviceInfo(DeviceInformation);
931 }
932 else
933 {
934 InsertTailList(&(DeviceExtension->OfflineDeviceListHead), &(DeviceInformation->DeviceListEntry));
935 }
936
937 KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
938
939 return Status;
940 }
941
942 /* Save gathered data */
943 DeviceInformation->UniqueId = UniqueId;
944 DeviceInformation->DeviceName = TargetDeviceName;
945 DeviceInformation->KeepLinks = FALSE;
946
947 /* If we found system partition, mark it */
948 if (DeviceExtension->DriveLetterData && UniqueId->UniqueIdLength == DeviceExtension->DriveLetterData->UniqueIdLength)
949 {
950 if (RtlCompareMemory(UniqueId->UniqueId, DeviceExtension->DriveLetterData->UniqueId, UniqueId->UniqueIdLength)
951 == UniqueId->UniqueIdLength)
952 {
953 IoSetSystemPartition(&TargetDeviceName);
954 }
955 }
956
957 /* Check suggested link name */
958 Status = QuerySuggestedLinkName(&(DeviceInformation->SymbolicName),
959 &SuggestedLinkName,
960 &UseOnlyIfThereAreNoOtherLinks);
961 if (!NT_SUCCESS(Status))
962 {
963 SuggestedLinkName.Buffer = NULL;
964 }
965
966 /* If it's OK, set it and save its letter (if any) */
967 if (SuggestedLinkName.Buffer && IsDriveLetter(&SuggestedLinkName))
968 {
969 DeviceInformation->SuggestedDriveLetter = (UCHAR)SuggestedLinkName.Buffer[LETTER_POSITION];
970 }
971
972 /* Acquire driver exclusively */
973 KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
974
975 /* Check if we already have device in to prevent double registration */
976 for (NextEntry = DeviceExtension->DeviceListHead.Flink;
977 NextEntry != &(DeviceExtension->DeviceListHead);
978 NextEntry = NextEntry->Flink)
979 {
980 CurrentDevice = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
981
982 if (RtlEqualUnicodeString(&(CurrentDevice->DeviceName), &TargetDeviceName, TRUE))
983 {
984 break;
985 }
986 }
987
988 /* If we found it, clear ours, and return success, all correct */
989 if (NextEntry != &(DeviceExtension->DeviceListHead))
990 {
991 if (SuggestedLinkName.Buffer)
992 {
993 FreePool(SuggestedLinkName.Buffer);
994 }
995
996 FreePool(UniqueId);
997 FreePool(TargetDeviceName.Buffer);
998 FreePool(DeviceInformation->DeviceName.Buffer);
999 FreePool(DeviceInformation);
1000
1001 KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
1002
1003 return STATUS_SUCCESS;
1004 }
1005
1006 /* Check if there are symlinks associated with our device in registry */
1007 Status = QuerySymbolicLinkNamesFromStorage(DeviceExtension,
1008 DeviceInformation,
1009 (SuggestedLinkName.Buffer) ? &SuggestedLinkName : NULL,
1010 UseOnlyIfThereAreNoOtherLinks,
1011 &SymLinks,
1012 &SymLinkCount,
1013 HasGuid,
1014 &StableGuid);
1015
1016 /* If our device is a CD-ROM */
1017 if (RtlPrefixUnicodeString(&DeviceCdRom, &TargetDeviceName, TRUE))
1018 {
1019 LinkTarget.Length = 0;
1020 LinkTarget.MaximumLength = sizeof(LinkTargetBuffer);
1021 LinkTarget.Buffer = LinkTargetBuffer;
1022
1023 RtlCopyMemory(CSymLinkBuffer, Cunc, sizeof(Cunc));
1024 RtlInitUnicodeString(&CSymLink, CSymLinkBuffer);
1025
1026 /* Start checking all letters that could have been associated */
1027 for (Letter = L'D'; Letter <= L'Z'; Letter++)
1028 {
1030
1032 &CSymLink,
1034 NULL,
1035 NULL);
1036
1037 /* Try to open the associated symlink */
1039 if (!NT_SUCCESS(Status))
1040 {
1041 continue;
1042 }
1043
1044 /* And query its target */
1045 Status = ZwQuerySymbolicLinkObject(LinkHandle, &LinkTarget, NULL);
1046 ZwClose(LinkHandle);
1047
1048 if (!NT_SUCCESS(Status))
1049 {
1050 continue;
1051 }
1052
1053 IntStatus = STATUS_UNSUCCESSFUL;
1054 if (!RtlEqualUnicodeString(&LinkTarget, &DeviceInformation->DeviceName, FALSE))
1055 {
1056 continue;
1057 }
1058
1059 /* This link is matching our device, whereas it's not supposed to have any
1060 * symlink associated.
1061 * Delete it
1062 */
1063 if (!SymLinkCount)
1064 {
1065 IoDeleteSymbolicLink(&CSymLink);
1066 continue;
1067 }
1068
1069 /* Now, for all the symlinks, check for ours */
1070 for (i = 0; i < SymLinkCount; i++)
1071 {
1072 if (IsDriveLetter(&(SymLinks[i])))
1073 {
1074 /* If it exists, that's correct */
1075 if (SymLinks[i].Buffer[LETTER_POSITION] == Letter)
1076 {
1077 IntStatus = STATUS_SUCCESS;
1078 }
1079 }
1080 }
1081
1082 /* Useless link, delete it */
1083 if (IntStatus == STATUS_UNSUCCESSFUL)
1084 {
1085 IoDeleteSymbolicLink(&CSymLink);
1086 }
1087 }
1088 }
1089
1090 /* Suggested name is no longer required */
1091 if (SuggestedLinkName.Buffer)
1092 {
1093 FreePool(SuggestedLinkName.Buffer);
1094 }
1095
1096 /* If if failed, ensure we don't take symlinks into account */
1097 if (!NT_SUCCESS(Status))
1098 {
1099 SymLinks = NULL;
1100 SymLinkCount = 0;
1101 }
1102
1103 /* Now we queried them, remove the symlinks */
1104 SavedLinkInformation = RemoveSavedLinks(DeviceExtension, UniqueId);
1105
1106 IsDrvLetter = FALSE;
1107 IsOff = FALSE;
1108 IsVolumeName = FALSE;
1109 /* For all the symlinks */
1110 for (i = 0; i < SymLinkCount; i++)
1111 {
1112 /* Check if our device is a volume */
1113 if (MOUNTMGR_IS_VOLUME_NAME(&(SymLinks[i])))
1114 {
1115 IsVolumeName = TRUE;
1116 }
1117 /* If it has a drive letter */
1118 else if (IsDriveLetter(&(SymLinks[i])))
1119 {
1120 if (IsDrvLetter)
1121 {
1122 DeleteFromLocalDatabase(&(SymLinks[i]), UniqueId);
1123 continue;
1124 }
1125 else
1126 {
1127 IsDrvLetter = TRUE;
1128 }
1129 }
1130
1131 /* And recreate the symlink to our device */
1132 Status = GlobalCreateSymbolicLink(&(SymLinks[i]), &TargetDeviceName);
1133 if (!NT_SUCCESS(Status))
1134 {
1135 BOOLEAN LinkError = TRUE;
1136
1137 if ((SavedLinkInformation && !RedirectSavedLink(SavedLinkInformation, &(SymLinks[i]), &TargetDeviceName)) ||
1138 !SavedLinkInformation)
1139 {
1141 if (NT_SUCCESS(Status))
1142 {
1143 LinkError = RtlEqualUnicodeString(&TargetDeviceName, &DeviceName, TRUE);
1144 FreePool(DeviceName.Buffer);
1145 }
1146
1147 if (!LinkError)
1148 {
1149 if (IsDriveLetter(&(SymLinks[i])))
1150 {
1151 IsDrvLetter = FALSE;
1152 DeleteFromLocalDatabase(&(SymLinks[i]), UniqueId);
1153 }
1154
1155 FreePool(SymLinks[i].Buffer);
1156 continue;
1157 }
1158 }
1159 }
1160
1161 /* Check if was offline */
1162 if (IsOffline(&(SymLinks[i])))
1163 {
1164 IsOff = TRUE;
1165 }
1166
1167 /* Finally, associate this symlink with the device */
1168 SymlinkInformation = AllocatePool(sizeof(SYMLINK_INFORMATION));
1169 if (!SymlinkInformation)
1170 {
1171 GlobalDeleteSymbolicLink(&(SymLinks[i]));
1172 FreePool(SymLinks[i].Buffer);
1173 continue;
1174 }
1175
1176 SymlinkInformation->Name = SymLinks[i];
1177 SymlinkInformation->Online = TRUE;
1178
1179 InsertTailList(&(DeviceInformation->SymbolicLinksListHead),
1180 &(SymlinkInformation->SymbolicLinksListEntry));
1181 }
1182
1183 /* Now, for all the recreated symlinks, notify their recreation */
1184 for (NextEntry = DeviceInformation->SymbolicLinksListHead.Flink;
1185 NextEntry != &(DeviceInformation->SymbolicLinksListHead);
1186 NextEntry = NextEntry->Flink)
1187 {
1188 SymlinkInformation = CONTAINING_RECORD(NextEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
1189
1190 SendLinkCreated(&(SymlinkInformation->Name));
1191 }
1192
1193 /* If we had saved links, it's time to free them */
1194 if (SavedLinkInformation)
1195 {
1196 MountMgrFreeSavedLink(SavedLinkInformation);
1197 }
1198
1199 /* If our device doesn't have a volume name */
1200 if (!IsVolumeName)
1201 {
1202 /* It's time to create one */
1204 if (NT_SUCCESS(Status))
1205 {
1206 /* Write it to global database */
1210 REG_BINARY,
1211 UniqueId->UniqueId,
1212 UniqueId->UniqueIdLength);
1213
1214 /* And create the symlink */
1215 GlobalCreateSymbolicLink(&VolumeName, &TargetDeviceName);
1216
1217 SymlinkInformation = AllocatePool(sizeof(SYMLINK_INFORMATION));
1218 if (!SymlinkInformation)
1219 {
1221 }
1222 /* Finally, associate it with the device and notify creation */
1223 else
1224 {
1225 SymlinkInformation->Name = VolumeName;
1226 SymlinkInformation->Online = TRUE;
1227 InsertTailList(&(DeviceInformation->SymbolicLinksListHead),
1228 &(SymlinkInformation->SymbolicLinksListEntry));
1229
1231 }
1232 }
1233 }
1234
1235 /* If we found a drive letter, then, ignore the suggested one */
1236 if (IsDrvLetter)
1237 {
1238 DeviceInformation->SuggestedDriveLetter = 0;
1239 }
1240 /* Else, it's time to set up one */
1241 else if ((!DeviceExtension->NoAutoMount || DeviceInformation->Removable) &&
1242 DeviceExtension->AutomaticDriveLetter &&
1243 (HasGptDriveLetter || DeviceInformation->SuggestedDriveLetter) &&
1244 !HasNoDriveLetterEntry(UniqueId))
1245 {
1246 /* Create a new drive letter */
1247 Status = CreateNewDriveLetterName(&DriveLetter, &TargetDeviceName,
1248 DeviceInformation->SuggestedDriveLetter,
1249 NULL);
1250 if (!NT_SUCCESS(Status))
1251 {
1252 CreateNoDriveLetterEntry(UniqueId);
1253 }
1254 else
1255 {
1256 /* Save it to global database */
1259 DriveLetter.Buffer,
1260 REG_BINARY,
1261 UniqueId->UniqueId,
1262 UniqueId->UniqueIdLength);
1263
1264 /* Associate it with the device and notify creation */
1265 SymlinkInformation = AllocatePool(sizeof(SYMLINK_INFORMATION));
1266 if (!SymlinkInformation)
1267 {
1268 FreePool(DriveLetter.Buffer);
1269 }
1270 else
1271 {
1272 SymlinkInformation->Name = DriveLetter;
1273 SymlinkInformation->Online = TRUE;
1274 InsertTailList(&(DeviceInformation->SymbolicLinksListHead),
1275 &(SymlinkInformation->SymbolicLinksListEntry));
1276
1277 SendLinkCreated(&DriveLetter);
1278 }
1279 }
1280 }
1281
1282 /* If that's a PnP device, register for notifications */
1283 if (!ManuallyRegistered)
1284 {
1285 RegisterForTargetDeviceNotification(DeviceExtension, DeviceInformation);
1286 }
1287
1288 /* Finally, insert the device into our devices list */
1289 InsertTailList(&(DeviceExtension->DeviceListHead), &(DeviceInformation->DeviceListEntry));
1290
1291 /* Copy device unique ID */
1292 NewUniqueId = AllocatePool(UniqueId->UniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
1293 if (NewUniqueId)
1294 {
1295 NewUniqueId->UniqueIdLength = UniqueId->UniqueIdLength;
1296 RtlCopyMemory(NewUniqueId->UniqueId, UniqueId->UniqueId, UniqueId->UniqueIdLength);
1297 }
1298
1299 /* Skip online notifications if the device is offline or a FT volume */
1300 if (IsOff || IsFT)
1301 DeviceInformation->SkipNotifications = TRUE;
1302
1303 /* If automount is enabled or the device was already mounted, send now
1304 * the online notification if needed; otherwise, defer its posting */
1305 if (!DeviceExtension->NoAutoMount || IsDrvLetter)
1306 SetOnline = !DeviceInformation->SkipNotifications;
1307 else
1308 SetOnline = FALSE;
1309
1310 /* Finally, release the exclusive lock */
1311 KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
1312
1313 /* Set the device online now if necessary */
1314 if (SetOnline)
1316
1317 /* If we had symlinks (from storage), free them */
1318 if (SymLinks)
1319 {
1320 FreePool(SymLinks);
1321 }
1322
1323 /* Notify about unique id change */
1324 if (NewUniqueId)
1325 {
1326 IssueUniqueIdChangeNotify(DeviceExtension, SymbolicName, NewUniqueId);
1327 FreePool(NewUniqueId);
1328 }
1329
1330 /* If this drive was set to have a drive letter automatically
1331 * Now it's back, local databases sync will be required
1332 */
1333 if (DeviceExtension->AutomaticDriveLetter)
1334 {
1335 KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
1336
1337 ReconcileThisDatabaseWithMaster(DeviceExtension, DeviceInformation);
1338
1339 NextEntry = DeviceExtension->DeviceListHead.Flink;
1340 CurrentDevice = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
1341 while (CurrentDevice != DeviceInformation)
1342 {
1343 if (!CurrentDevice->NoDatabase)
1344 {
1345 ReconcileThisDatabaseWithMaster(DeviceExtension, CurrentDevice);
1346 }
1347
1348 NextEntry = NextEntry->Flink;
1349 CurrentDevice = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
1350 }
1351
1352 KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
1353 }
1354
1355 return STATUS_SUCCESS;
1356}
unsigned char BOOLEAN
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define MAX_PATH
Definition: compat.h:34
VOID ReconcileThisDatabaseWithMaster(IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation)
Definition: database.c:1613
VOID DeleteFromLocalDatabase(IN PUNICODE_STRING SymbolicLink, IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: database.c:351
#define InsertTailList(ListHead, Entry)
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
_Must_inspect_result_ _Inout_opt_ PUNICODE_STRING VolumeName
Definition: fltkernel.h:1117
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
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG, PCWSTR, PCWSTR, ULONG, PVOID, ULONG)
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:451
VOID SendLinkCreated(IN PUNICODE_STRING SymbolicName)
Definition: symlink.c:169
VOID SendOnlineNotification(IN PUNICODE_STRING SymbolicName)
Definition: notify.c:38
NTSTATUS CreateNewVolumeName(OUT PUNICODE_STRING VolumeName, IN PGUID VolumeGuid OPTIONAL)
Definition: symlink.c:399
VOID RegisterForTargetDeviceNotification(IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation)
Definition: notify.c:250
#define LETTER_POSITION
Definition: mntmgr.h:159
VOID IssueUniqueIdChangeNotify(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName, IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: notify.c:637
NTSTATUS QuerySuggestedLinkName(IN PUNICODE_STRING SymbolicName, OUT PUNICODE_STRING SuggestedLinkName, OUT PBOOLEAN UseOnlyIfThereAreNoOtherLinks)
Definition: symlink.c:621
PSAVED_LINK_INFORMATION RemoveSavedLinks(IN PDEVICE_EXTENSION DeviceExtension, IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: symlink.c:577
BOOLEAN HasNoDriveLetterEntry(IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: uniqueid.c:354
BOOLEAN RedirectSavedLink(IN PSAVED_LINK_INFORMATION SavedLinkInformation, IN PUNICODE_STRING DosName, IN PUNICODE_STRING NewLink)
Definition: symlink.c:717
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
static const WCHAR Cunc[]
Definition: mountmgr.c:39
#define Cunc_LETTER_POSITION
Definition: mountmgr.c:40
NTSTATUS CreateNewDriveLetterName(OUT PUNICODE_STRING DriveLetter, IN PUNICODE_STRING DeviceName, IN UCHAR Letter, IN PMOUNTDEV_UNIQUE_ID UniqueId OPTIONAL)
Definition: mountmgr.c:192
VOID MountMgrFreeDeadDeviceInfo(IN PDEVICE_INFORMATION DeviceInformation)
Definition: mountmgr.c:626
VOID MountMgrFreeSavedLink(IN PSAVED_LINK_INFORMATION SavedLinkInformation)
Definition: mountmgr.c:691
#define MOUNTMGR_IS_VOLUME_NAME(s)
Definition: mountmgr.h:81
NTSYSAPI NTSTATUS NTAPI ZwOpenSymbolicLinkObject(_Out_ PHANDLE SymbolicLinkHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#define SYMBOLIC_LINK_QUERY
Definition: nt_native.h:1265
#define REG_BINARY
Definition: nt_native.h:1496
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI IoSetSystemPartition(IN PUNICODE_STRING VolumeNameString)
Definition: volume.c:1226
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
PDEVICE_EXTENSION DeviceExtension
Definition: mntmgr.h:62
UNICODE_STRING SymbolicName
Definition: mntmgr.h:48
BOOLEAN ManuallyRegistered
Definition: mntmgr.h:53
BOOLEAN KeepLinks
Definition: mntmgr.h:51
BOOLEAN NoDatabase
Definition: mntmgr.h:57
UCHAR SuggestedDriveLetter
Definition: mntmgr.h:52
PMOUNTDEV_UNIQUE_ID UniqueId
Definition: mntmgr.h:49
BOOLEAN SkipNotifications
Definition: mntmgr.h:58
UNICODE_STRING DeviceName
Definition: mntmgr.h:50
LIST_ENTRY ReplicatedUniqueIdsListHead
Definition: mntmgr.h:46
LIST_ENTRY AssociatedDevicesHead
Definition: mntmgr.h:47
LIST_ENTRY SymbolicLinksListHead
Definition: mntmgr.h:45
LIST_ENTRY DeviceListEntry
Definition: mntmgr.h:44
USHORT UniqueIdLength
Definition: imports.h:138
UCHAR UniqueId[1]
Definition: imports.h:139
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_Inout_ PUNICODE_STRING LinkTarget
Definition: zwfuncs.h:292

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

◆ MountMgrMountedDeviceNotification()

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

Definition at line 1526 of file mountmgr.c.

1528{
1529 BOOLEAN OldState;
1530 PDEVICE_EXTENSION DeviceExtension;
1532
1533 /* Notification for a device arrived */
1534 /* Disable hard errors */
1537
1538 DeviceExtension = Context;
1540
1541 /* Dispatch according to the event */
1543 {
1544 MountMgrMountedDeviceArrival(DeviceExtension, Notification->SymbolicLinkName, FALSE);
1545 }
1547 {
1548 MountMgrMountedDeviceRemoval(DeviceExtension, Notification->SymbolicLinkName);
1549 }
1550
1551 /* Reset hard errors */
1553
1554 return STATUS_SUCCESS;
1555}
const GUID GUID_DEVICE_INTERFACE_ARRIVAL
Definition: deviface.c:14
const GUID GUID_DEVICE_INTERFACE_REMOVAL
Definition: deviface.c:15
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
NTSTATUS MountMgrMountedDeviceArrival(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName, IN BOOLEAN ManuallyRegistered)
Definition: mountmgr.c:855
VOID MountMgrMountedDeviceRemoval(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName)
Definition: mountmgr.c:1362
VOID NTAPI PsSetThreadHardErrorsAreDisabled(IN PETHREAD Thread, IN BOOLEAN HardErrorsAreDisabled)
Definition: thread.c:898
BOOLEAN NTAPI PsGetThreadHardErrorsAreDisabled(IN PETHREAD Thread)
Definition: thread.c:695
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
_In_ PWDFDEVICE_INIT _In_ PFN_WDF_DEVICE_SHUTDOWN_NOTIFICATION Notification
Definition: wdfcontrol.h:115
_In_ PVOID NotificationStructure
Definition: iofuncs.h:1206

Referenced by DriverEntry().

◆ MountMgrMountedDeviceRemoval()

VOID MountMgrMountedDeviceRemoval ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PUNICODE_STRING  DeviceName 
)

Definition at line 1362 of file mountmgr.c.

1364{
1365 PLIST_ENTRY NextEntry, DeviceEntry;
1366 PUNIQUE_ID_REPLICATE UniqueIdReplicate;
1367 PSYMLINK_INFORMATION SymlinkInformation;
1369 PSAVED_LINK_INFORMATION SavedLinkInformation = NULL;
1370 PDEVICE_INFORMATION DeviceInformation, CurrentDevice;
1371
1372 /* Acquire device exclusively */
1373 KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
1374
1375 /* Look for the leaving device */
1376 for (NextEntry = DeviceExtension->DeviceListHead.Flink;
1377 NextEntry != &(DeviceExtension->DeviceListHead);
1378 NextEntry = NextEntry->Flink)
1379 {
1380 DeviceInformation = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
1381
1382 if (!RtlCompareUnicodeString(&(DeviceInformation->SymbolicName), DeviceName, TRUE))
1383 {
1384 break;
1385 }
1386 }
1387
1388 /* If we found it */
1389 if (NextEntry != &(DeviceExtension->DeviceListHead))
1390 {
1391 /* If it's asked to keep links, then, prepare to save them */
1392 if (DeviceInformation->KeepLinks)
1393 {
1394 SavedLinkInformation = AllocatePool(sizeof(SAVED_LINK_INFORMATION));
1395 if (!SavedLinkInformation)
1396 {
1397 DeviceInformation->KeepLinks = FALSE;
1398 }
1399 }
1400
1401 /* If it's possible (and asked), start to save them */
1402 if (DeviceInformation->KeepLinks)
1403 {
1404 InsertTailList(&(DeviceExtension->SavedLinksListHead), &(SavedLinkInformation->SavedLinksListEntry));
1405 InitializeListHead(&(SavedLinkInformation->SymbolicLinksListHead));
1406 SavedLinkInformation->UniqueId = DeviceInformation->UniqueId;
1407 }
1408
1409 /* For all the symlinks */
1410 while (!IsListEmpty(&(DeviceInformation->SymbolicLinksListHead)))
1411 {
1412 NextEntry = RemoveHeadList(&(DeviceInformation->SymbolicLinksListHead));
1413 SymlinkInformation = CONTAINING_RECORD(NextEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
1414
1415 /* If we have to, save the link */
1416 if (DeviceInformation->KeepLinks)
1417 {
1418 InsertTailList(&(SavedLinkInformation->SymbolicLinksListHead), &(SymlinkInformation->SymbolicLinksListEntry));
1419 }
1420 /* Otherwise, just release it */
1421 else
1422 {
1423 GlobalDeleteSymbolicLink(&(SymlinkInformation->Name));
1424 FreePool(SymlinkInformation->Name.Buffer);
1425 FreePool(SymlinkInformation);
1426 }
1427 }
1428
1429 /* Free all the replicated unique IDs */
1430 while (!IsListEmpty(&(DeviceInformation->ReplicatedUniqueIdsListHead)))
1431 {
1432 NextEntry = RemoveHeadList(&(DeviceInformation->ReplicatedUniqueIdsListHead));
1433 UniqueIdReplicate = CONTAINING_RECORD(NextEntry, UNIQUE_ID_REPLICATE, ReplicatedUniqueIdsListEntry);
1434
1435
1436 FreePool(UniqueIdReplicate->UniqueId);
1437 FreePool(UniqueIdReplicate);
1438 }
1439
1440 while (!IsListEmpty(&(DeviceInformation->AssociatedDevicesHead)))
1441 {
1442 NextEntry = RemoveHeadList(&(DeviceInformation->AssociatedDevicesHead));
1443 AssociatedDevice = CONTAINING_RECORD(NextEntry, ASSOCIATED_DEVICE_ENTRY, AssociatedDevicesEntry);
1444
1445 DeviceInformation->NoDatabase = TRUE;
1446 FreePool(AssociatedDevice->String.Buffer);
1448 }
1449
1450 /* Remove device from the device list */
1451 RemoveEntryList(&(DeviceInformation->DeviceListEntry));
1452
1453 /* If there are still devices, check if some were associated with ours */
1454 if (!IsListEmpty(&(DeviceInformation->DeviceListEntry)))
1455 {
1456 for (NextEntry = DeviceExtension->DeviceListHead.Flink;
1457 NextEntry != &(DeviceExtension->DeviceListHead);
1458 NextEntry = NextEntry->Flink)
1459 {
1460 CurrentDevice = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
1461
1462 /* And then, remove them */
1463 DeviceEntry = CurrentDevice->AssociatedDevicesHead.Flink;
1464 while (DeviceEntry != &(CurrentDevice->AssociatedDevicesHead))
1465 {
1466 AssociatedDevice = CONTAINING_RECORD(NextEntry, ASSOCIATED_DEVICE_ENTRY, AssociatedDevicesEntry);
1467 DeviceEntry = DeviceEntry->Flink;
1468
1469 if (AssociatedDevice->DeviceInformation != DeviceInformation)
1470 {
1471 continue;
1472 }
1473
1474 RemoveEntryList(&(AssociatedDevice->AssociatedDevicesEntry));
1475 FreePool(AssociatedDevice->String.Buffer);
1477 }
1478 }
1479 }
1480
1481 /* Finally, clean up device name, symbolic name */
1482 FreePool(DeviceInformation->SymbolicName.Buffer);
1483 if (!DeviceInformation->KeepLinks)
1484 {
1485 FreePool(DeviceInformation->UniqueId);
1486 }
1487 FreePool(DeviceInformation->DeviceName.Buffer);
1488
1489 /* Unregister notifications */
1490 if (DeviceInformation->TargetDeviceNotificationEntry)
1491 {
1493 }
1494
1495 /* And leave */
1496 FreePool(DeviceInformation);
1497 }
1498 else
1499 {
1500 /* We didn't find device, perhaps because it was offline */
1501 for (NextEntry = DeviceExtension->OfflineDeviceListHead.Flink;
1502 NextEntry != &(DeviceExtension->OfflineDeviceListHead);
1503 NextEntry = NextEntry->Flink)
1504 {
1505 DeviceInformation = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
1506
1507 /* It was, remove it */
1508 if (RtlCompareUnicodeString(&(DeviceInformation->SymbolicName), DeviceName, TRUE) == 0)
1509 {
1510 RemoveEntryList(&(DeviceInformation->DeviceListEntry));
1511 MountMgrFreeDeadDeviceInfo(DeviceInformation);
1512 break;
1513 }
1514 }
1515 }
1516
1517 /* Release driver */
1518 KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
1519}
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
PVOID TargetDeviceNotificationEntry
Definition: mntmgr.h:61

Referenced by MountMgrMountedDeviceNotification().

◆ MountmgrReadNoAutoMount()

BOOLEAN MountmgrReadNoAutoMount ( _In_ PUNICODE_STRING  RegistryPath)

Retrieves the "NoAutoMount" setting.

Returns
TRUE if AutoMount is disabled; FALSE if AutoMount is enabled.

Definition at line 824 of file mountmgr.c.

826{
828 ULONG Result, Default = 0;
830
831 /* Retrieve data from registry */
834 QueryTable[0].Name = L"NoAutoMount";
838 QueryTable[0].DefaultLength = sizeof(Default);
839
841 RegistryPath->Buffer,
843 NULL,
844 NULL);
845 if (!NT_SUCCESS(Status))
846 Result = Default;
847
848 return (Result != 0);
849}
_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:409

Referenced by DriverEntry().

◆ MountMgrShutdown()

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

Definition at line 1672 of file mountmgr.c.

1674{
1675 PDEVICE_EXTENSION DeviceExtension;
1676
1677 DeviceExtension = DeviceObject->DeviceExtension;
1678
1680
1682
1683 /* Wait for workers */
1684 if (InterlockedIncrement(&(DeviceExtension->WorkerReferences)) > 0)
1685 {
1686 KeReleaseSemaphore(&(DeviceExtension->WorkerSemaphore),
1688 1,
1689 FALSE);
1691 }
1692 else
1693 {
1694 InterlockedDecrement(&(DeviceExtension->WorkerReferences));
1695 }
1696
1697 Irp->IoStatus.Status = STATUS_SUCCESS;
1698 Irp->IoStatus.Information = 0;
1700
1701 return STATUS_SUCCESS;
1702}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedExchange
Definition: armddk.h:54
#define InterlockedDecrement
Definition: armddk.h:52
LONG Unloading
Definition: mountmgr.c:37
KEVENT UnloadEvent
Definition: mountmgr.c:36

Referenced by DriverEntry().

◆ MountMgrUnload()

VOID NTAPI MountMgrUnload ( IN PDRIVER_OBJECT  DriverObject)

Definition at line 719 of file mountmgr.c.

720{
721 PLIST_ENTRY NextEntry;
723 PDEVICE_EXTENSION DeviceExtension;
724 PDEVICE_INFORMATION DeviceInformation;
725 PSAVED_LINK_INFORMATION SavedLinkInformation;
726
728
729 /* Don't get notification any longer */
731
732 /* Free registry buffer */
733 DeviceExtension = gdeviceObject->DeviceExtension;
734 if (DeviceExtension->RegistryPath.Buffer)
735 {
736 FreePool(DeviceExtension->RegistryPath.Buffer);
737 DeviceExtension->RegistryPath.Buffer = NULL;
738 }
739
741
743
744 /* Wait for workers to finish */
745 if (InterlockedIncrement(&DeviceExtension->WorkerReferences) > 0)
746 {
747 KeReleaseSemaphore(&(DeviceExtension->WorkerSemaphore),
749
751 }
752 else
753 {
754 InterlockedDecrement(&(DeviceExtension->WorkerReferences));
755 }
756
757 /* Don't get any notification any longer² */
758 IoUnregisterPlugPlayNotification(DeviceExtension->NotificationEntry);
759
760 /* Acquire the driver exclusively */
761 KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode,
762 FALSE, NULL);
763
764 /* Clear offline devices list */
765 while (!IsListEmpty(&(DeviceExtension->OfflineDeviceListHead)))
766 {
767 NextEntry = RemoveHeadList(&(DeviceExtension->OfflineDeviceListHead));
768 DeviceInformation = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
769 MountMgrFreeDeadDeviceInfo(DeviceInformation);
770 }
771
772 /* Clear saved links list */
773 while (!IsListEmpty(&(DeviceExtension->SavedLinksListHead)))
774 {
775 NextEntry = RemoveHeadList(&(DeviceExtension->SavedLinksListHead));
776 SavedLinkInformation = CONTAINING_RECORD(NextEntry, SAVED_LINK_INFORMATION, SavedLinksListEntry);
777 MountMgrFreeSavedLink(SavedLinkInformation);
778 }
779
780 /* Clear workers list */
781 while (!IsListEmpty(&(DeviceExtension->UniqueIdWorkerItemListHead)))
782 {
783 NextEntry = RemoveHeadList(&(DeviceExtension->UniqueIdWorkerItemListHead));
784 WorkItem = CONTAINING_RECORD(NextEntry, UNIQUE_ID_WORK_ITEM, UniqueIdWorkerItemListEntry);
785
787 WorkItem->Event = &UnloadEvent;
788
789 KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT,
790 1, FALSE);
791
792 IoCancelIrp(WorkItem->Irp);
794
795 IoFreeIrp(WorkItem->Irp);
796 FreePool(WorkItem->DeviceName.Buffer);
797 FreePool(WorkItem->IrpBuffer);
799
800 KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode,
801 FALSE, NULL);
802 }
803
804 /* If we have drive letter data, release */
805 if (DeviceExtension->DriveLetterData)
806 {
807 FreePool(DeviceExtension->DriveLetterData);
808 DeviceExtension->DriveLetterData = NULL;
809 }
810
811 /* Release driver & quit */
812 KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
813
816}
VOID NTAPI KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
VOID NTAPI IoUnregisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1725
BOOLEAN NTAPI IoCancelIrp(IN PIRP Irp)
Definition: irp.c:1101
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
PVOID DeviceExtension
Definition: env_spec_w32.h:418
_Must_inspect_result_ _In_ PWDF_WORKITEM_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWORKITEM * WorkItem
Definition: wdfworkitem.h:115

Referenced by DriverEntry().

◆ QueryDeviceInformation()

NTSTATUS QueryDeviceInformation ( _In_ PUNICODE_STRING  SymbolicName,
_Out_opt_ PUNICODE_STRING  DeviceName,
_Out_opt_ PMOUNTDEV_UNIQUE_ID UniqueId,
_Out_opt_ PBOOLEAN  Removable,
_Out_opt_ PBOOLEAN  GptDriveLetter,
_Out_opt_ PBOOLEAN  HasGuid,
_Inout_opt_ LPGUID  StableGuid,
_Out_opt_ PBOOLEAN  IsFT 
)

Definition at line 274 of file mountmgr.c.

283{
285 USHORT Size;
286 BOOLEAN IsRemovable;
292 STORAGE_DEVICE_NUMBER StorageDeviceNumber;
294
295 /* Get device associated with the symbolic name */
298 &FileObject,
299 &DeviceObject);
300 if (!NT_SUCCESS(Status))
301 {
302 return Status;
303 }
304
305 /* The associate FO can't have a file name */
306 if (FileObject->FileName.Length)
307 {
310 }
311
312 /* Check if it's removable & return to the user (if asked to) */
313 IsRemovable = (FileObject->DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA);
314 if (Removable)
315 {
316 *Removable = IsRemovable;
317 }
318
319 /* Get the attached device */
321
322 /* If we've been asked for a GPT drive letter */
323 if (GptDriveLetter)
324 {
325 /* Consider it has one */
326 *GptDriveLetter = TRUE;
327
328 if (!IsRemovable)
329 {
330 /* Query the GPT attributes */
331 Status = MountMgrSendSyncDeviceIoCtl(IOCTL_VOLUME_GET_GPT_ATTRIBUTES,
333 NULL,
334 0,
335 &GptAttributes,
336 sizeof(GptAttributes),
337 NULL);
338 /* Failure isn't major */
339 if (!NT_SUCCESS(Status))
340 {
342 }
343 /* Check if it has a drive letter */
344 else if (GptAttributes.GptAttributes & GPT_BASIC_DATA_ATTRIBUTE_NO_DRIVE_LETTER)
345 {
346 *GptDriveLetter = FALSE;
347 }
348 }
349 }
350
351 /* If caller wants to know if this is a FT volume */
352 if (IsFT)
353 {
354 /* Suppose it's not */
355 *IsFT = FALSE;
356
357 /* FT volume can't be removable */
358 if (!IsRemovable)
359 {
360 /* Query partition information */
361 Status = MountMgrSendSyncDeviceIoCtl(IOCTL_DISK_GET_PARTITION_INFO_EX,
363 NULL,
364 0,
366 sizeof(PartitionInfo),
367 NULL);
368 /* Failure isn't major */
369 if (!NT_SUCCESS(Status))
370 {
372 }
373 /* Check if this is a FT volume */
374 else if ((PartitionInfo.PartitionStyle == PARTITION_STYLE_MBR) &&
375 IsFTPartition(PartitionInfo.Mbr.PartitionType))
376 {
377 *IsFT = TRUE;
378 }
379
380 /* It looks like a FT volume. Verify it is really one by checking
381 * that it does NOT lie on a specific storage device (i.e. it is
382 * not a basic volume). */
383 if (*IsFT)
384 {
385 Status = MountMgrSendSyncDeviceIoCtl(IOCTL_STORAGE_GET_DEVICE_NUMBER,
387 NULL,
388 0,
389 &StorageDeviceNumber,
390 sizeof(StorageDeviceNumber),
391 NULL);
392 if (!NT_SUCCESS(Status))
394 else
395 *IsFT = FALSE; // Succeeded, so this cannot be a FT volume.
396 }
397 }
398 }
399
400 /* If caller needs device name */
401 if (DeviceName)
402 {
403 /* Allocate a buffer just to request length */
405 if (!Name)
406 {
410 }
411
412 /* Query device name */
413 Status = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_QUERY_DEVICE_NAME,
415 NULL,
416 0,
417 Name,
418 sizeof(MOUNTDEV_NAME),
419 FileObject);
420 /* Retry with appropriate length */
422 {
423 Size = Name->NameLength + sizeof(MOUNTDEV_NAME);
424
425 FreePool(Name);
426
427 /* Allocate proper size */
429 if (!Name)
430 {
434 }
435
436 /* And query name (for real that time) */
437 Status = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_QUERY_DEVICE_NAME,
439 NULL,
440 0,
441 Name,
442 Size,
443 FileObject);
444 }
445
446 if (NT_SUCCESS(Status))
447 {
448 /* Copy back found name to the caller */
449 DeviceName->Length = Name->NameLength;
450 DeviceName->MaximumLength = Name->NameLength + sizeof(WCHAR);
451 DeviceName->Buffer = AllocatePool(DeviceName->MaximumLength);
452 if (!DeviceName->Buffer)
453 {
455 }
456 else
457 {
458 RtlCopyMemory(DeviceName->Buffer, Name->Name, Name->NameLength);
459 DeviceName->Buffer[Name->NameLength / sizeof(WCHAR)] = UNICODE_NULL;
460 }
461 }
462
463 FreePool(Name);
464 }
465
466 if (!NT_SUCCESS(Status))
467 {
470 return Status;
471 }
472
473 /* If caller wants device unique ID */
474 if (UniqueId)
475 {
476 /* Prepare buffer to probe length */
478 if (!Id)
479 {
483 }
484
485 /* Query unique ID length */
486 Status = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_QUERY_UNIQUE_ID,
488 NULL,
489 0,
490 Id,
491 sizeof(MOUNTDEV_UNIQUE_ID),
492 FileObject);
493 /* Retry with appropriate length */
495 {
496 Size = Id->UniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID);
497
498 FreePool(Id);
499
500 /* Allocate the correct buffer */
502 if (!Id)
503 {
507 }
508
509 /* Query unique ID */
510 Status = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_QUERY_UNIQUE_ID,
512 NULL,
513 0,
514 Id,
515 Size,
516 FileObject);
517 }
518
519 /* Hands back unique ID */
520 if (NT_SUCCESS(Status))
521 {
522 *UniqueId = Id;
523 }
524 else
525 {
526 /* In case of failure, also free the rest */
527 FreePool(Id);
528 if (DeviceName->Length)
529 FreePool(DeviceName->Buffer);
530
533 return Status;
534 }
535 }
536
537 /* If user wants to know about GUID */
538 if (HasGuid)
539 {
540 /* Query device stable GUID */
541 NTSTATUS IntStatus;
542 IntStatus = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_QUERY_STABLE_GUID,
544 NULL,
545 0,
546 StableGuid,
547 sizeof(GUID),
548 FileObject);
549 *HasGuid = NT_SUCCESS(IntStatus);
550 }
551
554 return Status;
555}
DWORD Id
struct NameRec_ * Name
Definition: cdprocs.h:460
#define IOCTL_DISK_GET_PARTITION_INFO_EX
Definition: ntddk_ex.h:206
struct _MOUNTDEV_NAME MOUNTDEV_NAME
struct _MOUNTDEV_UNIQUE_ID MOUNTDEV_UNIQUE_ID
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
#define IOCTL_MOUNTDEV_QUERY_STABLE_GUID
Definition: imports.h:255
#define IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
Definition: imports.h:80
@ PARTITION_STYLE_MBR
Definition: imports.h:201
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define IsFTPartition(PartitionType)
Definition: ntdddisk.h:315
#define IOCTL_STORAGE_GET_DEVICE_NUMBER
Definition: ntddstor.h:143
#define IOCTL_VOLUME_GET_GPT_ATTRIBUTES
Definition: ntddvol.h:133
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
unsigned short USHORT
Definition: pedump.c:61
@ Removable
Definition: arc.h:81
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_In_ ULONG _In_ struct _SET_PARTITION_INFORMATION_EX * PartitionInfo
Definition: iofuncs.h:2105
#define ObDereferenceObject
Definition: obfuncs.h:203

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().