ReactOS  0.4.14-dev-1034-g1e60116
mntmgr.h File Reference
#include <ntifs.h>
#include <mountdev.h>
#include <ntddvol.h>
#include <ntdddisk.h>
#include <wdmguid.h>
#include <ndk/psfuncs.h>
#include <section_attribs.h>
Include dependency graph for mntmgr.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _DEVICE_EXTENSION
 
struct  _DEVICE_INFORMATION
 
struct  _SYMLINK_INFORMATION
 
struct  _SAVED_LINK_INFORMATION
 
struct  _UNIQUE_ID_REPLICATE
 
struct  _DATABASE_ENTRY
 
struct  _ASSOCIATED_DEVICE_ENTRY
 
struct  _DEVICE_INFORMATION_ENTRY
 
struct  _ONLINE_NOTIFICATION_WORK_ITEM
 
struct  _RECONCILE_WORK_ITEM_CONTEXT
 
struct  _RECONCILE_WORK_ITEM
 
struct  _MIGRATE_WORK_ITEM
 
struct  _UNIQUE_ID_WORK_ITEM
 

Macros

#define AllocatePool(Size)   ExAllocatePoolWithTag(PagedPool, Size, 'AtnM')
 
#define FreePool(P)   ExFreePoolWithTag(P, 'AtnM')
 
#define MAX(a, b)   ((a > b) ? a : b)
 
#define LETTER_POSITION   0xC
 
#define COLON_POSITION   0xD
 
#define DRIVE_LETTER_LENGTH   0x1C
 

Typedefs

typedef struct _DEVICE_EXTENSION DEVICE_EXTENSION
 
typedef struct _DEVICE_EXTENSIONPDEVICE_EXTENSION
 
typedef struct _DEVICE_INFORMATION DEVICE_INFORMATION
 
typedef struct _DEVICE_INFORMATIONPDEVICE_INFORMATION
 
typedef struct _SYMLINK_INFORMATION SYMLINK_INFORMATION
 
typedef struct _SYMLINK_INFORMATIONPSYMLINK_INFORMATION
 
typedef struct _SAVED_LINK_INFORMATION SAVED_LINK_INFORMATION
 
typedef struct _SAVED_LINK_INFORMATIONPSAVED_LINK_INFORMATION
 
typedef struct _UNIQUE_ID_REPLICATE UNIQUE_ID_REPLICATE
 
typedef struct _UNIQUE_ID_REPLICATEPUNIQUE_ID_REPLICATE
 
typedef struct _DATABASE_ENTRY DATABASE_ENTRY
 
typedef struct _DATABASE_ENTRYPDATABASE_ENTRY
 
typedef struct _ASSOCIATED_DEVICE_ENTRY ASSOCIATED_DEVICE_ENTRY
 
typedef struct _ASSOCIATED_DEVICE_ENTRYPASSOCIATED_DEVICE_ENTRY
 
typedef struct _DEVICE_INFORMATION_ENTRY DEVICE_INFORMATION_ENTRY
 
typedef struct _DEVICE_INFORMATION_ENTRYPDEVICE_INFORMATION_ENTRY
 
typedef struct _ONLINE_NOTIFICATION_WORK_ITEM ONLINE_NOTIFICATION_WORK_ITEM
 
typedef struct _ONLINE_NOTIFICATION_WORK_ITEMPONLINE_NOTIFICATION_WORK_ITEM
 
typedef struct _RECONCILE_WORK_ITEM_CONTEXT RECONCILE_WORK_ITEM_CONTEXT
 
typedef struct _RECONCILE_WORK_ITEM_CONTEXTPRECONCILE_WORK_ITEM_CONTEXT
 
typedef struct _RECONCILE_WORK_ITEM RECONCILE_WORK_ITEM
 
typedef struct _RECONCILE_WORK_ITEMPRECONCILE_WORK_ITEM
 
typedef struct _MIGRATE_WORK_ITEM MIGRATE_WORK_ITEM
 
typedef struct _MIGRATE_WORK_ITEMPMIGRATE_WORK_ITEM
 
typedef struct _UNIQUE_ID_WORK_ITEM UNIQUE_ID_WORK_ITEM
 
typedef struct _UNIQUE_ID_WORK_ITEMPUNIQUE_ID_WORK_ITEM
 

Functions

VOID NTAPI MountMgrCancel (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS MountMgrMountedDeviceArrival (IN PDEVICE_EXTENSION Extension, IN PUNICODE_STRING SymbolicName, IN BOOLEAN FromVolume)
 
VOID MountMgrMountedDeviceRemoval (IN PDEVICE_EXTENSION Extension, IN PUNICODE_STRING DeviceName)
 
NTSTATUS FindDeviceInfo (IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName, IN BOOLEAN DeviceNameGiven, OUT PDEVICE_INFORMATION *DeviceInformation)
 
VOID MountMgrFreeDeadDeviceInfo (IN PDEVICE_INFORMATION DeviceInformation)
 
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)
 
BOOLEAN HasDriveLetter (IN PDEVICE_INFORMATION DeviceInformation)
 
INIT_FUNCTION BOOLEAN MountmgrReadNoAutoMount (IN PUNICODE_STRING RegistryPath)
 
VOID ReconcileThisDatabaseWithMaster (IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation)
 
NTSTATUS WaitForRemoteDatabaseSemaphore (IN PDEVICE_EXTENSION DeviceExtension)
 
VOID ReleaseRemoteDatabaseSemaphore (IN PDEVICE_EXTENSION DeviceExtension)
 
VOID ChangeRemoteDatabaseUniqueId (IN PDEVICE_INFORMATION DeviceInformation, IN PMOUNTDEV_UNIQUE_ID OldUniqueId, IN PMOUNTDEV_UNIQUE_ID NewUniqueId)
 
VOID ReconcileAllDatabasesWithMaster (IN PDEVICE_EXTENSION DeviceExtension)
 
VOID DeleteFromLocalDatabase (IN PUNICODE_STRING SymbolicLink, IN PMOUNTDEV_UNIQUE_ID UniqueId)
 
VOID DeleteRegistryDriveLetter (IN PMOUNTDEV_UNIQUE_ID UniqueId)
 
VOID DeleteNoDriveLetterEntry (IN PMOUNTDEV_UNIQUE_ID UniqueId)
 
NTSTATUS QueryVolumeName (IN HANDLE RootDirectory, IN PFILE_REPARSE_POINT_INFORMATION ReparsePointInformation, IN PUNICODE_STRING FileName OPTIONAL, OUT PUNICODE_STRING SymbolicName, OUT PUNICODE_STRING VolumeName)
 
HANDLE OpenRemoteDatabase (IN PDEVICE_INFORMATION DeviceInformation, IN BOOLEAN MigrateDatabase)
 
PDATABASE_ENTRY GetRemoteDatabaseEntry (IN HANDLE Database, IN LONG StartingOffset)
 
NTSTATUS WriteRemoteDatabaseEntry (IN HANDLE Database, IN LONG Offset, IN PDATABASE_ENTRY Entry)
 
NTSTATUS CloseRemoteDatabase (IN HANDLE Database)
 
NTSTATUS AddRemoteDatabaseEntry (IN HANDLE Database, IN PDATABASE_ENTRY Entry)
 
NTSTATUS DeleteRemoteDatabaseEntry (IN HANDLE Database, IN LONG StartingOffset)
 
VOID NTAPI ReconcileThisDatabaseWithMasterWorker (IN PVOID Parameter)
 
VOID IssueUniqueIdChangeNotifyWorker (IN PUNIQUE_ID_WORK_ITEM WorkItem, IN PMOUNTDEV_UNIQUE_ID UniqueId)
 
VOID WaitForOnlinesToComplete (IN PDEVICE_EXTENSION DeviceExtension)
 
VOID RegisterForTargetDeviceNotification (IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation)
 
VOID SendOnlineNotification (IN PUNICODE_STRING SymbolicName)
 
VOID IssueUniqueIdChangeNotify (IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName, IN PMOUNTDEV_UNIQUE_ID UniqueId)
 
VOID PostOnlineNotification (IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName)
 
VOID MountMgrNotify (IN PDEVICE_EXTENSION DeviceExtension)
 
VOID MountMgrNotifyNameChange (IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName, IN BOOLEAN ValidateVolume)
 
VOID MountMgrUniqueIdChangeRoutine (IN PDEVICE_EXTENSION DeviceExtension, IN PMOUNTDEV_UNIQUE_ID OldUniqueId, IN PMOUNTDEV_UNIQUE_ID NewUniqueId)
 
VOID CreateNoDriveLetterEntry (IN PMOUNTDEV_UNIQUE_ID UniqueId)
 
BOOLEAN HasNoDriveLetterEntry (IN PMOUNTDEV_UNIQUE_ID UniqueId)
 
VOID UpdateReplicatedUniqueIds (IN PDEVICE_INFORMATION DeviceInformation, IN PDATABASE_ENTRY DatabaseEntry)
 
BOOLEAN IsUniqueIdPresent (IN PDEVICE_EXTENSION DeviceExtension, IN PDATABASE_ENTRY DatabaseEntry)
 
NTSTATUS MountMgrCreatePointWorker (IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicLinkName, IN PUNICODE_STRING DeviceName)
 
NTSTATUS QueryPointsFromSymbolicLinkName (IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName, IN PIRP Irp)
 
NTSTATUS QueryPointsFromMemory (IN PDEVICE_EXTENSION DeviceExtension, IN PIRP Irp, IN PMOUNTDEV_UNIQUE_ID UniqueId OPTIONAL, IN PUNICODE_STRING SymbolicName OPTIONAL)
 
NTSTATUS GlobalCreateSymbolicLink (IN PUNICODE_STRING DosName, IN PUNICODE_STRING DeviceName)
 
NTSTATUS GlobalDeleteSymbolicLink (IN PUNICODE_STRING DosName)
 
NTSTATUS QuerySuggestedLinkName (IN PUNICODE_STRING SymbolicName, OUT PUNICODE_STRING SuggestedLinkName, OUT PBOOLEAN UseOnlyIfThereAreNoOtherLinks)
 
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)
 
PSAVED_LINK_INFORMATION RemoveSavedLinks (IN PDEVICE_EXTENSION DeviceExtension, IN PMOUNTDEV_UNIQUE_ID UniqueId)
 
BOOLEAN RedirectSavedLink (IN PSAVED_LINK_INFORMATION SavedLinkInformation, IN PUNICODE_STRING DosName, IN PUNICODE_STRING NewLink)
 
VOID SendLinkCreated (IN PUNICODE_STRING SymbolicName)
 
NTSTATUS CreateNewVolumeName (OUT PUNICODE_STRING VolumeName, IN PGUID VolumeGuid OPTIONAL)
 
BOOLEAN IsDriveLetter (PUNICODE_STRING SymbolicName)
 
VOID DeleteSymbolicLinkNameFromMemory (IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicLink, IN BOOLEAN MarkOffline)
 
NTSTATUS MountMgrQuerySymbolicLink (IN PUNICODE_STRING SymbolicName, IN OUT PUNICODE_STRING LinkTarget)
 

Variables

UNICODE_STRING DosDevicesMount
 
PDEVICE_OBJECT gdeviceObject
 
UNICODE_STRING ReparseIndex
 
UNICODE_STRING DeviceFloppy
 
UNICODE_STRING DeviceMount
 
UNICODE_STRING DeviceCdRom
 
UNICODE_STRING SafeVolumes
 
UNICODE_STRING DosDevices
 
UNICODE_STRING DosGlobal
 
UNICODE_STRING Global
 
UNICODE_STRING Volume
 
KEVENT UnloadEvent
 
LONG Unloading
 
INIT_FUNCTION DRIVER_INITIALIZE DriverEntry
 
PWSTR DatabasePath
 
PWSTR OfflinePath
 
DRIVER_DISPATCH MountMgrDeviceControl
 

Macro Definition Documentation

◆ AllocatePool

#define AllocatePool (   Size)    ExAllocatePoolWithTag(PagedPool, Size, 'AtnM')

Definition at line 153 of file mntmgr.h.

◆ COLON_POSITION

#define COLON_POSITION   0xD

Definition at line 160 of file mntmgr.h.

◆ DRIVE_LETTER_LENGTH

#define DRIVE_LETTER_LENGTH   0x1C

Definition at line 161 of file mntmgr.h.

◆ FreePool

#define FreePool (   P)    ExFreePoolWithTag(P, 'AtnM')

Definition at line 154 of file mntmgr.h.

◆ LETTER_POSITION

#define LETTER_POSITION   0xC

Definition at line 159 of file mntmgr.h.

◆ MAX

#define MAX (   a,
  b 
)    ((a > b) ? a : b)

Definition at line 157 of file mntmgr.h.

Typedef Documentation

◆ ASSOCIATED_DEVICE_ENTRY

◆ DATABASE_ENTRY

◆ DEVICE_EXTENSION

◆ DEVICE_INFORMATION

◆ DEVICE_INFORMATION_ENTRY

◆ MIGRATE_WORK_ITEM

◆ ONLINE_NOTIFICATION_WORK_ITEM

◆ PASSOCIATED_DEVICE_ENTRY

◆ PDATABASE_ENTRY

◆ PDEVICE_EXTENSION

◆ PDEVICE_INFORMATION

◆ PDEVICE_INFORMATION_ENTRY

◆ PMIGRATE_WORK_ITEM

◆ PONLINE_NOTIFICATION_WORK_ITEM

◆ PRECONCILE_WORK_ITEM

◆ PRECONCILE_WORK_ITEM_CONTEXT

◆ PSAVED_LINK_INFORMATION

◆ PSYMLINK_INFORMATION

◆ PUNIQUE_ID_REPLICATE

◆ PUNIQUE_ID_WORK_ITEM

◆ RECONCILE_WORK_ITEM

◆ RECONCILE_WORK_ITEM_CONTEXT

◆ SAVED_LINK_INFORMATION

◆ SYMLINK_INFORMATION

◆ UNIQUE_ID_REPLICATE

◆ UNIQUE_ID_WORK_ITEM

Function Documentation

◆ AddRemoteDatabaseEntry()

NTSTATUS AddRemoteDatabaseEntry ( IN HANDLE  Database,
IN PDATABASE_ENTRY  Entry 
)

Definition at line 64 of file database.c.

66 {
69 
70  /* Get size to append data */
72 
73  return ZwWriteFile(Database, NULL, NULL, NULL,
75  Entry->EntrySize, &Size, NULL);
76 }
smooth NULL
Definition: ftsmooth.c:416
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
base of all file and directory entries
Definition: entries.h:82
LONG GetRemoteDatabaseSize(IN HANDLE Database)
Definition: database.c:40

Referenced by ChangeRemoteDatabaseUniqueId(), MountMgrVolumeMountPointCreated(), and ReconcileThisDatabaseWithMasterWorker().

◆ ChangeRemoteDatabaseUniqueId()

VOID ChangeRemoteDatabaseUniqueId ( IN PDEVICE_INFORMATION  DeviceInformation,
IN PMOUNTDEV_UNIQUE_ID  OldUniqueId,
IN PMOUNTDEV_UNIQUE_ID  NewUniqueId 
)

Definition at line 1909 of file database.c.

1912 {
1913  LONG Offset = 0;
1914  HANDLE Database;
1915  PDATABASE_ENTRY Entry, NewEntry;
1917 
1918  /* Open the remote database */
1919  Database = OpenRemoteDatabase(DeviceInformation, FALSE);
1920  if (!Database)
1921  {
1922  return;
1923  }
1924 
1925  /* Get all the entries */
1926  do
1927  {
1929  if (!Entry)
1930  {
1931  break;
1932  }
1933 
1934  /* Not the correct entry, skip it */
1935  if (Entry->UniqueIdLength != OldUniqueId->UniqueIdLength)
1936  {
1937  Offset += Entry->EntrySize;
1938  FreePool(Entry);
1939  continue;
1940  }
1941 
1942  /* Not the correct entry, skip it */
1943  if (RtlCompareMemory(OldUniqueId->UniqueId,
1944  (PVOID)((ULONG_PTR)Entry + Entry->UniqueIdOffset),
1945  Entry->UniqueIdLength) != Entry->UniqueIdLength)
1946  {
1947  Offset += Entry->EntrySize;
1948  FreePool(Entry);
1949  continue;
1950  }
1951 
1952  /* Here, we have the correct entry */
1953  NewEntry = AllocatePool(Entry->EntrySize + NewUniqueId->UniqueIdLength - OldUniqueId->UniqueIdLength);
1954  if (!NewEntry)
1955  {
1956  Offset += Entry->EntrySize;
1957  FreePool(Entry);
1958  continue;
1959  }
1960 
1961  /* Recreate the entry from the previous one */
1962  NewEntry->EntrySize = Entry->EntrySize + NewUniqueId->UniqueIdLength - OldUniqueId->UniqueIdLength;
1963  NewEntry->EntryReferences = Entry->EntryReferences;
1964  NewEntry->SymbolicNameOffset = sizeof(DATABASE_ENTRY);
1965  NewEntry->SymbolicNameLength = Entry->SymbolicNameLength;
1966  NewEntry->UniqueIdOffset = Entry->SymbolicNameLength + sizeof(DATABASE_ENTRY);
1967  NewEntry->UniqueIdLength = NewUniqueId->UniqueIdLength;
1968  RtlCopyMemory((PVOID)((ULONG_PTR)NewEntry + NewEntry->SymbolicNameOffset),
1969  (PVOID)((ULONG_PTR)Entry + Entry->SymbolicNameOffset),
1970  NewEntry->SymbolicNameLength);
1971  RtlCopyMemory((PVOID)((ULONG_PTR)NewEntry + NewEntry->UniqueIdOffset),
1972  NewUniqueId->UniqueId, NewEntry->UniqueIdLength);
1973 
1974  /* Delete old entry */
1976  if (!NT_SUCCESS(Status))
1977  {
1978  FreePool(Entry);
1979  FreePool(NewEntry);
1980  break;
1981  }
1982 
1983  /* And replace with new one */
1984  Status = AddRemoteDatabaseEntry(Database, NewEntry);
1985  FreePool(Entry);
1986  FreePool(NewEntry);
1987  } while (NT_SUCCESS(Status));
1988 
1990 
1991  return;
1992 }
USHORT UniqueIdOffset
Definition: mntmgr.h:91
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
NTSTATUS DeleteRemoteDatabaseEntry(IN HANDLE Database, IN LONG StartingOffset)
Definition: database.c:233
struct _Entry Entry
Definition: kefuncs.h:627
ULONG EntryReferences
Definition: mntmgr.h:88
ULONG EntrySize
Definition: mntmgr.h:87
LONG NTSTATUS
Definition: precomp.h:26
USHORT SymbolicNameLength
Definition: mntmgr.h:90
#define FreePool(P)
Definition: mntmgr.h:154
uint32_t ULONG_PTR
Definition: typedefs.h:64
HANDLE OpenRemoteDatabase(IN PDEVICE_INFORMATION DeviceInformation, IN BOOLEAN MigrateDatabase)
Definition: database.c:1836
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
long LONG
Definition: pedump.c:60
USHORT UniqueIdLength
Definition: mntmgr.h:92
NTSTATUS CloseRemoteDatabase(IN HANDLE Database)
Definition: database.c:82
struct _DATABASE_ENTRY DATABASE_ENTRY
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
USHORT SymbolicNameOffset
Definition: mntmgr.h:89
Definition: mntmgr.h:85
#define AllocatePool(Size)
Definition: mntmgr.h:153
Status
Definition: gdiplustypes.h:24
PDATABASE_ENTRY GetRemoteDatabaseEntry(IN HANDLE Database, IN LONG StartingOffset)
Definition: database.c:125
NTSTATUS AddRemoteDatabaseEntry(IN HANDLE Database, IN PDATABASE_ENTRY Entry)
Definition: database.c:64
return STATUS_SUCCESS
Definition: btrfs.c:2938
base of all file and directory entries
Definition: entries.h:82
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465

Referenced by MountMgrUniqueIdChangeRoutine().

◆ CloseRemoteDatabase()

NTSTATUS CloseRemoteDatabase ( IN HANDLE  Database)

Definition at line 82 of file database.c.

83 {
84  return ZwClose(Database);
85 }
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)

Referenced by ChangeRemoteDatabaseUniqueId(), MountMgrVolumeMountPointCreated(), MountMgrVolumeMountPointDeleted(), and ReconcileThisDatabaseWithMasterWorker().

◆ CreateNewVolumeName()

NTSTATUS CreateNewVolumeName ( OUT PUNICODE_STRING  VolumeName,
IN PGUID VolumeGuid  OPTIONAL 
)

Definition at line 462 of file symlink.c.

464 {
465  GUID Guid;
468 
469  /* If no GUID was provided, then create one */
470  if (!VolumeGuid)
471  {
473  if (!NT_SUCCESS(Status))
474  {
475  return Status;
476  }
477  }
478  else
479  {
480  RtlCopyMemory(&Guid, VolumeGuid, sizeof(GUID));
481  }
482 
483  /* Convert GUID to string */
485  if (!NT_SUCCESS(Status))
486  {
487  return Status;
488  }
489 
490  /* Size for volume namespace, literal GUID, and null char */
491  VolumeName->MaximumLength = 0x14 + 0x4C + sizeof(UNICODE_NULL);
492  VolumeName->Buffer = AllocatePool(0x14 + 0x4C + sizeof(UNICODE_NULL));
493  if (!VolumeName->Buffer)
494  {
496  }
497  else
498  {
503  }
504 
505  ExFreePoolWithTag(GuidString.Buffer, 0);
506 
507  return Status;
508 }
static PWSTR GuidString
Definition: apphelp.c:91
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
USHORT MaximumLength
Definition: env_spec_w32.h:370
LONG NTSTATUS
Definition: precomp.h:26
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define UNICODE_NULL
static GUID * Guid
Definition: apphelp.c:93
NTKERNELAPI NTSTATUS ExUuidCreate(OUT UUID *Uuid)
Definition: uuid.c:385
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define AllocatePool(Size)
Definition: mntmgr.h:153
Status
Definition: gdiplustypes.h:24
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
_Must_inspect_result_ _Inout_opt_ PUNICODE_STRING VolumeName
Definition: fltkernel.h:1117
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by MountMgrMountedDeviceArrival(), and QuerySymbolicLinkNamesFromStorage().

◆ CreateNoDriveLetterEntry()

VOID CreateNoDriveLetterEntry ( IN PMOUNTDEV_UNIQUE_ID  UniqueId)

Definition at line 269 of file uniqueid.c.

270 {
271  UUID Guid;
272  PWCHAR String;
274 
275  /* Entry with no drive letter are made that way:
276  * Instead of having a path with the letter,
277  * you have GUID with the unique ID.
278  */
279  if (!NT_SUCCESS(ExUuidCreate(&Guid)))
280  {
281  return;
282  }
283 
284  /* Convert to string */
286  {
287  return;
288  }
289 
290  /* No letter entries must start with #, so allocate a proper string */
291  String = AllocatePool(GuidString.Length + 2 * sizeof(WCHAR));
292  if (!String)
293  {
294  ExFreePoolWithTag(GuidString.Buffer, 0);
295  return;
296  }
297 
298  /* Write the complete string */
299  String[0] = L'#';
300  RtlCopyMemory(String + 1, GuidString.Buffer, GuidString.Length);
301  String[GuidString.Length / sizeof(WCHAR)] = UNICODE_NULL;
302 
303  /* Don't need that one anymore */
304  ExFreePoolWithTag(GuidString.Buffer, 0);
305 
306  /* Write the entry */
308  DatabasePath,
309  String,
310  REG_BINARY,
311  UniqueId->UniqueId,
312  UniqueId->UniqueIdLength);
313 
314  FreePool(String);
315 
316  return;
317 }
static PWSTR GuidString
Definition: apphelp.c:91
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define REG_BINARY
Definition: nt_native.h:1496
static WCHAR String[]
Definition: stringtable.c:55
uint16_t * PWCHAR
Definition: typedefs.h:55
#define FreePool(P)
Definition: mntmgr.h:154
#define UNICODE_NULL
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG, PCWSTR, PCWSTR, ULONG, PVOID, ULONG)
static GUID * Guid
Definition: apphelp.c:93
NTKERNELAPI NTSTATUS ExUuidCreate(OUT UUID *Uuid)
Definition: uuid.c:385
__wchar_t WCHAR
Definition: xmlstorage.h:180
#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 AllocatePool(Size)
Definition: mntmgr.h:153
PWSTR DatabasePath
Definition: database.c:31
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by CreateNewDriveLetterName(), MountMgrDeletePoints(), MountMgrDeletePointsDbOnly(), MountMgrMountedDeviceArrival(), MountMgrNextDriveLetterWorker(), and ProcessSuggestedDriveLetters().

◆ DeleteFromLocalDatabase()

VOID DeleteFromLocalDatabase ( IN PUNICODE_STRING  SymbolicLink,
IN PMOUNTDEV_UNIQUE_ID  UniqueId 
)

Definition at line 351 of file database.c.

353 {
355 
358  QueryTable[0].Name = SymbolicLink->Buffer;
359 
361  DatabasePath,
362  QueryTable,
363  UniqueId,
364  NULL);
365 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4035
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
NTSTATUS NTAPI DeleteFromLocalDatabaseRoutine(IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
Definition: database.c:322
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
smooth NULL
Definition: ftsmooth.c:416
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
PWSTR DatabasePath
Definition: database.c:31
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
static const WCHAR SymbolicLink[]
Definition: interface.c:31

Referenced by MountMgrMountedDeviceArrival().

◆ DeleteNoDriveLetterEntry()

VOID DeleteNoDriveLetterEntry ( IN PMOUNTDEV_UNIQUE_ID  UniqueId)

Definition at line 2098 of file database.c.

2099 {
2101 
2104 
2106  DatabasePath,
2107  QueryTable,
2108  UniqueId,
2109  NULL);
2110 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4035
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
smooth NULL
Definition: ftsmooth.c:416
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
PWSTR DatabasePath
Definition: database.c:31
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
NTSTATUS NTAPI DeleteNoDriveLetterEntryRoutine(IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
Definition: database.c:2065

Referenced by MountMgrCreatePointWorker(), and MountMgrDeletePoints().

◆ DeleteRegistryDriveLetter()

VOID DeleteRegistryDriveLetter ( IN PMOUNTDEV_UNIQUE_ID  UniqueId)

Definition at line 2046 of file database.c.

2047 {
2049 
2052 
2054  DatabasePath,
2055  QueryTable,
2056  UniqueId,
2057  NULL);
2058 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4035
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
smooth NULL
Definition: ftsmooth.c:416
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
PWSTR DatabasePath
Definition: database.c:31
NTSTATUS NTAPI DeleteDriveLetterRoutine(IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
Definition: database.c:1999
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by MountMgrCreatePointWorker().

◆ DeleteRemoteDatabaseEntry()

NTSTATUS DeleteRemoteDatabaseEntry ( IN HANDLE  Database,
IN LONG  StartingOffset 
)

Definition at line 233 of file database.c.

235 {
236  ULONG EndSize;
237  PVOID TmpBuffer;
239  ULONG DatabaseSize;
242  LARGE_INTEGER EndEntriesOffset;
243 
244  /* First, get database size */
245  DatabaseSize = GetRemoteDatabaseSize(Database);
246  if (!DatabaseSize)
247  {
249  }
250 
251  /* Then, get the entry to remove */
253  if (!Entry)
254  {
256  }
257 
258  /* Validate parameters: ensure we won't get negative size */
259  if (Entry->EntrySize + StartingOffset > DatabaseSize)
260  {
261  /* If we get invalid parameters, truncate the whole database
262  * starting the wrong entry. We can't rely on the rest
263  */
264  FreePool(Entry);
266  }
267 
268  /* Now, get the size of the remaining entries (those after the one to remove) */
269  EndSize = DatabaseSize - Entry->EntrySize - StartingOffset;
270  /* Allocate a buffer big enough to hold them */
271  TmpBuffer = AllocatePool(EndSize);
272  if (!TmpBuffer)
273  {
274  FreePool(Entry);
276  }
277 
278  /* Get the offset of the entry right after the one to delete */
279  EndEntriesOffset.QuadPart = Entry->EntrySize + StartingOffset;
280  /* We don't need the entry any more */
281  FreePool(Entry);
282 
283  /* Read the ending entries */
284  Status = ZwReadFile(Database, NULL, NULL, NULL, &IoStatusBlock,
285  TmpBuffer, EndSize, &EndEntriesOffset, NULL);
286  if (!NT_SUCCESS(Status))
287  {
288  FreePool(TmpBuffer);
289  return Status;
290  }
291 
292  /* Ensure nothing went wrong - we don't want to corrupt the DB */
293  if (IoStatusBlock.Information != EndSize)
294  {
295  FreePool(TmpBuffer);
297  }
298 
299  /* Remove the entry */
301  if (!NT_SUCCESS(Status))
302  {
303  FreePool(TmpBuffer);
304  return Status;
305  }
306 
307  /* Now, shift the ending entries to erase the entry */
308  EndEntriesOffset.QuadPart = StartingOffset;
309  Status = ZwWriteFile(Database, NULL, NULL, NULL, &IoStatusBlock,
310  TmpBuffer, EndSize, &EndEntriesOffset, NULL);
311 
312  FreePool(TmpBuffer);
313 
314  return Status;
315 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:282
NTSTATUS TruncateRemoteDatabase(IN HANDLE Database, IN LONG NewSize)
Definition: database.c:91
struct _Entry Entry
Definition: kefuncs.h:627
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
#define FreePool(P)
Definition: mntmgr.h:154
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Definition: mntmgr.h:85
#define AllocatePool(Size)
Definition: mntmgr.h:153
Status
Definition: gdiplustypes.h:24
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
PDATABASE_ENTRY GetRemoteDatabaseEntry(IN HANDLE Database, IN LONG StartingOffset)
Definition: database.c:125
unsigned int ULONG
Definition: retypes.h:1
base of all file and directory entries
Definition: entries.h:82
LONGLONG QuadPart
Definition: typedefs.h:113
LONG GetRemoteDatabaseSize(IN HANDLE Database)
Definition: database.c:40

Referenced by ChangeRemoteDatabaseUniqueId(), MountMgrVolumeMountPointDeleted(), and ReconcileThisDatabaseWithMasterWorker().

◆ DeleteSymbolicLinkNameFromMemory()

VOID DeleteSymbolicLinkNameFromMemory ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PUNICODE_STRING  SymbolicLink,
IN BOOLEAN  MarkOffline 
)

Definition at line 864 of file symlink.c.

867 {
868  PLIST_ENTRY DeviceEntry, SymbolEntry;
869  PDEVICE_INFORMATION DeviceInformation;
870  PSYMLINK_INFORMATION SymlinkInformation;
871 
872  /* First of all, ensure we have devices */
873  if (IsListEmpty(&(DeviceExtension->DeviceListHead)))
874  {
875  return;
876  }
877 
878  /* Then, look for the symbolic name */
879  for (DeviceEntry = DeviceExtension->DeviceListHead.Flink;
880  DeviceEntry != &(DeviceExtension->DeviceListHead);
881  DeviceEntry = DeviceEntry->Flink)
882  {
883  DeviceInformation = CONTAINING_RECORD(DeviceEntry, DEVICE_INFORMATION, DeviceListEntry);
884 
885  for (SymbolEntry = DeviceInformation->SymbolicLinksListHead.Flink;
886  SymbolEntry != &(DeviceInformation->SymbolicLinksListHead);
887  SymbolEntry = SymbolEntry->Flink)
888  {
889  SymlinkInformation = CONTAINING_RECORD(SymbolEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
890 
891  /* One we have found it */
892  if (RtlCompareUnicodeString(SymbolicLink, &(SymlinkInformation->Name), TRUE) == 0)
893  {
894  /* Check if caller just want it to be offline */
895  if (MarkOffline)
896  {
897  SymlinkInformation->Online = FALSE;
898  }
899  else
900  {
901  /* If not, delete it & notify */
902  SendLinkDeleted(&(DeviceInformation->SymbolicName), SymbolicLink);
903  RemoveEntryList(&(SymlinkInformation->SymbolicLinksListEntry));
904 
905  FreePool(SymlinkInformation->Name.Buffer);
906  FreePool(SymlinkInformation);
907  }
908 
909  /* No need to go farther */
910  return;
911  }
912  }
913  }
914 
915  return;
916 }
#define TRUE
Definition: types.h:120
#define FreePool(P)
Definition: mntmgr.h:154
_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
PVOID DeviceExtension
Definition: env_spec_w32.h:418
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:120
LIST_ENTRY SymbolicLinksListHead
Definition: mntmgr.h:45
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
Definition: typedefs.h:118
static const WCHAR SymbolicLink[]
Definition: interface.c:31

Referenced by MountMgrDeletePoints(), and MountMgrDeletePointsDbOnly().

◆ FindDeviceInfo()

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

Definition at line 642 of file mountmgr.c.

646 {
648  PLIST_ENTRY NextEntry;
651 
652  /* If a device name was given, use it */
653  if (DeviceNameGiven)
654  {
655  DeviceName.Length = SymbolicName->Length;
656  DeviceName.Buffer = SymbolicName->Buffer;
657  }
658  else
659  {
660  /* Otherwise, query it */
662  &DeviceName,
663  NULL, NULL,
664  NULL, NULL,
665  NULL, NULL);
666  if (!NT_SUCCESS(Status))
667  {
668  return Status;
669  }
670  }
671 
672  /* Look for device information matching devive */
673  for (NextEntry = DeviceExtension->DeviceListHead.Flink;
674  NextEntry != &(DeviceExtension->DeviceListHead);
675  NextEntry = NextEntry->Flink)
676  {
677  DeviceInfo = CONTAINING_RECORD(NextEntry,
679  DeviceListEntry);
680 
681  if (RtlEqualUnicodeString(&DeviceName, &(DeviceInfo->DeviceName), TRUE))
682  {
683  break;
684  }
685  }
686 
687  /* Release our buffer if required */
688  if (!DeviceNameGiven)
689  {
690  FreePool(DeviceName.Buffer);
691  }
692 
693  /* Return found information */
694  if (NextEntry == &(DeviceExtension->DeviceListHead))
695  {
697  }
698 
699  *DeviceInformation = DeviceInfo;
700  return STATUS_SUCCESS;
701 }
#define TRUE
Definition: types.h:120
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
LONG NTSTATUS
Definition: precomp.h:26
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define FreePool(P)
Definition: mntmgr.h:154
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _DeviceInfo DeviceInfo
Definition: typedefs.h:118
Status
Definition: gdiplustypes.h:24
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
NTSTATUS QueryDeviceInformation(IN PUNICODE_STRING SymbolicName, OUT PUNICODE_STRING DeviceName OPTIONAL, OUT PMOUNTDEV_UNIQUE_ID *UniqueId OPTIONAL, OUT PBOOLEAN Removable OPTIONAL, OUT PBOOLEAN GptDriveLetter OPTIONAL, OUT PBOOLEAN HasGuid OPTIONAL, IN OUT LPGUID StableGuid OPTIONAL, OUT PBOOLEAN Valid OPTIONAL)
Definition: mountmgr.c:195
return STATUS_SUCCESS
Definition: btrfs.c:2938
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)

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

◆ GetRemoteDatabaseEntry()

PDATABASE_ENTRY GetRemoteDatabaseEntry ( IN HANDLE  Database,
IN LONG  StartingOffset 
)

Definition at line 125 of file database.c.

127 {
133 
134  /* Get the entry at the given position */
135  ByteOffset.QuadPart = StartingOffset;
136  Status = ZwReadFile(Database,
137  NULL,
138  NULL,
139  NULL,
140  &IoStatusBlock,
141  &EntrySize,
142  sizeof(EntrySize),
143  &ByteOffset,
144  NULL);
145  if (!NT_SUCCESS(Status))
146  {
147  return NULL;
148  }
149 
150  /* If entry doesn't exist, truncate database */
151  if (!EntrySize)
152  {
154  return NULL;
155  }
156 
157  /* Allocate the entry */
159  if (!Entry)
160  {
161  return NULL;
162  }
163 
164  /* Effectively read the entry */
165  Status = ZwReadFile(Database,
166  NULL,
167  NULL,
168  NULL,
169  &IoStatusBlock,
170  Entry,
171  EntrySize,
172  &ByteOffset,
173  NULL);
174  /* If it fails or returns inconsistent data, drop it (= truncate) */
175  if (!NT_SUCCESS(Status) ||
177  (EntrySize < sizeof(DATABASE_ENTRY)) )
178  {
180  FreePool(Entry);
181  return NULL;
182  }
183 
184  /* Validate entry */
185  if (MAX(Entry->SymbolicNameOffset + Entry->SymbolicNameLength,
186  Entry->UniqueIdOffset + Entry->UniqueIdLength) > (LONG)EntrySize)
187  {
189  FreePool(Entry);
190  return NULL;
191  }
192 
193  return Entry;
194 }
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:282
NTSTATUS TruncateRemoteDatabase(IN HANDLE Database, IN LONG NewSize)
Definition: database.c:91
struct _Entry Entry
Definition: kefuncs.h:627
LONG NTSTATUS
Definition: precomp.h:26
_In_ UCHAR EntrySize
Definition: iofuncs.h:640
#define FreePool(P)
Definition: mntmgr.h:154
long LONG
Definition: pedump.c:60
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Definition: mntmgr.h:85
#define AllocatePool(Size)
Definition: mntmgr.h:153
Status
Definition: gdiplustypes.h:24
T MAX(T a, T b)
Definition: polytest.cpp:85
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned int ULONG
Definition: retypes.h:1
base of all file and directory entries
Definition: entries.h:82
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:716

Referenced by ChangeRemoteDatabaseUniqueId(), DeleteRemoteDatabaseEntry(), MountMgrVolumeMountPointCreated(), MountMgrVolumeMountPointDeleted(), and ReconcileThisDatabaseWithMasterWorker().

◆ GlobalCreateSymbolicLink()

NTSTATUS GlobalCreateSymbolicLink ( IN PUNICODE_STRING  DosName,
IN PUNICODE_STRING  DeviceName 
)

Definition at line 111 of file symlink.c.

113 {
115  UNICODE_STRING GlobalName;
116 
117  /* First create the global string */
118  Status = CreateStringWithGlobal(DosName, &GlobalName);
119  if (!NT_SUCCESS(Status))
120  {
121  return Status;
122  }
123 
124  /* Then, create the symlink */
125  Status = IoCreateSymbolicLink(&GlobalName, DeviceName);
126 
127  FreePool(GlobalName.Buffer);
128 
129  return Status;
130 }
LONG NTSTATUS
Definition: precomp.h:26
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define FreePool(P)
Definition: mntmgr.h:154
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:24
_Out_ PUNICODE_STRING DosName
Definition: rtlfuncs.h:1270

Referenced by CreateNewDriveLetterName(), DriverEntry(), MountMgrCreatePointWorker(), MountMgrMountedDeviceArrival(), and RedirectSavedLink().

◆ GlobalDeleteSymbolicLink()

NTSTATUS GlobalDeleteSymbolicLink ( IN PUNICODE_STRING  DosName)

Definition at line 136 of file symlink.c.

137 {
139  UNICODE_STRING GlobalName;
140 
141  /* Recreate the string (to find the link) */
142  Status = CreateStringWithGlobal(DosName, &GlobalName);
143  if (!NT_SUCCESS(Status))
144  {
145  return Status;
146  }
147 
148  /* And delete the link */
149  Status = IoDeleteSymbolicLink(&GlobalName);
150 
151  FreePool(GlobalName.Buffer);
152 
153  return Status;
154 }
LONG NTSTATUS
Definition: precomp.h:26
#define FreePool(P)
Definition: mntmgr.h:154
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:24
_Out_ PUNICODE_STRING DosName
Definition: rtlfuncs.h:1270

Referenced by MountMgrCreatePointWorker(), MountMgrDeletePoints(), MountMgrFreeMountedDeviceInfo(), MountMgrFreeSavedLink(), MountMgrMountedDeviceArrival(), MountMgrMountedDeviceRemoval(), MountMgrUnload(), and RedirectSavedLink().

◆ HasDriveLetter()

BOOLEAN HasDriveLetter ( IN PDEVICE_INFORMATION  DeviceInformation)

Definition at line 88 of file mountmgr.c.

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

Referenced by MountMgrCreatePointWorker(), and ProcessSuggestedDriveLetters().

◆ HasNoDriveLetterEntry()

BOOLEAN HasNoDriveLetterEntry ( IN PMOUNTDEV_UNIQUE_ID  UniqueId)

Definition at line 354 of file uniqueid.c.

355 {
356  BOOLEAN EntryPresent = FALSE;
358 
361  QueryTable[0].EntryContext = &EntryPresent;
362 
364  DatabasePath,
365  QueryTable,
366  UniqueId,
367  NULL);
368 
369  return EntryPresent;
370 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4035
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
NTSTATUS NTAPI CheckForNoDriveLetterEntry(IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
Definition: uniqueid.c:324
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
PWSTR DatabasePath
Definition: database.c:31
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by MountMgrMountedDeviceArrival(), MountMgrNextDriveLetterWorker(), and ProcessSuggestedDriveLetters().

◆ IsDriveLetter()

BOOLEAN IsDriveLetter ( PUNICODE_STRING  SymbolicName)

Definition at line 922 of file symlink.c.

923 {
924  WCHAR Letter, Colon;
925 
926  /* We must have a precise length */
927  if (SymbolicName->Length != DosDevices.Length + 2 * sizeof(WCHAR))
928  {
929  return FALSE;
930  }
931 
932  /* Must start with the DosDevices prefix */
934  {
935  return FALSE;
936  }
937 
938  /* Check if letter is correct */
940  if ((Letter < L'A' || Letter > L'Z') && Letter != (WCHAR)-1)
941  {
942  return FALSE;
943  }
944 
945  /* And finally it must end with a colon */
946  Colon = SymbolicName->Buffer[DosDevices.Length / sizeof(WCHAR) + 1];
947  if (Colon != L':')
948  {
949  return FALSE;
950  }
951 
952  return TRUE;
953 }
#define TRUE
Definition: types.h:120
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
__wchar_t WCHAR
Definition: xmlstorage.h:180
static const WCHAR L[]
Definition: oid.c:1250
WCHAR Letter
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)

Referenced by DeleteDriveLetterRoutine(), HasDriveLetter(), MountMgrCreatePointWorker(), MountMgrDeletePoints(), MountMgrDeletePointsDbOnly(), MountMgrMountedDeviceArrival(), MountMgrNextDriveLetterWorker(), and QuerySymbolicLinkNamesFromStorage().

◆ IssueUniqueIdChangeNotify()

VOID IssueUniqueIdChangeNotify ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PUNICODE_STRING  DeviceName,
IN PMOUNTDEV_UNIQUE_ID  UniqueId 
)

Definition at line 661 of file notify.c.

664 {
666  PVOID IrpBuffer = NULL;
669  PUNIQUE_ID_WORK_ITEM WorkItem = NULL;
670 
671  /* Get the associated device object */
674  &FileObject,
675  &DeviceObject);
676  if (!NT_SUCCESS(Status))
677  {
678  return;
679  }
680 
681  /* And then, get attached device */
683 
685 
686  /* Allocate a work item */
687  WorkItem = AllocatePool(sizeof(UNIQUE_ID_WORK_ITEM));
688  if (!WorkItem)
689  {
691  return;
692  }
693 
694  WorkItem->Event = NULL;
695  WorkItem->WorkItem = IoAllocateWorkItem(DeviceExtension->DeviceObject);
696  if (!WorkItem->WorkItem)
697  {
699  goto Cleanup;
700  }
701 
702  WorkItem->DeviceExtension = DeviceExtension;
703  WorkItem->StackSize = DeviceObject->StackSize;
704  /* Already provide the IRP */
706 
708 
709  if (!WorkItem->Irp)
710  {
711  goto Cleanup;
712  }
713 
714  /* Ensure it has enough space */
715  IrpBuffer = AllocatePool(sizeof(MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT) + 1024);
716  if (!IrpBuffer)
717  {
718  goto Cleanup;
719  }
720 
721  WorkItem->DeviceName.Length = DeviceName->Length;
722  WorkItem->DeviceName.MaximumLength = DeviceName->Length + sizeof(WCHAR);
723  WorkItem->DeviceName.Buffer = AllocatePool(WorkItem->DeviceName.MaximumLength);
724  if (!WorkItem->DeviceName.Buffer)
725  {
726  goto Cleanup;
727  }
728 
729  RtlCopyMemory(WorkItem->DeviceName.Buffer, DeviceName->Buffer, DeviceName->Length);
730  WorkItem->DeviceName.Buffer[DeviceName->Length / sizeof(WCHAR)] = UNICODE_NULL;
731 
732  WorkItem->IrpBuffer = IrpBuffer;
733  WorkItem->IrpBufferLength = sizeof(MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT) + 1024;
734 
735  /* Add the worker in the list */
737  InsertHeadList(&(DeviceExtension->UniqueIdWorkerItemListHead), &(WorkItem->UniqueIdWorkerItemListEntry));
739 
740  /* And call the worker */
741  IssueUniqueIdChangeNotifyWorker(WorkItem, UniqueId);
742 
743  return;
744 
745 Cleanup:
746  if (IrpBuffer)
747  {
748  FreePool(IrpBuffer);
749  }
750 
751  if (WorkItem->Irp)
752  {
753  IoFreeIrp(WorkItem->Irp);
754  }
755 
756  if (WorkItem->WorkItem)
757  {
758  IoFreeWorkItem(WorkItem->WorkItem);
759  }
760 
761  if (WorkItem)
762  {
763  FreePool(WorkItem);
764  }
765 }
UNICODE_STRING DeviceName
Definition: mntmgr.h:147
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
USHORT MaximumLength
Definition: env_spec_w32.h:370
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
WCHAR DeviceName[]
Definition: adapter.cpp:21
PDEVICE_EXTENSION DeviceExtension
Definition: mntmgr.h:143
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
#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
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
PIO_WORKITEM WorkItem
Definition: mntmgr.h:142
VOID IssueUniqueIdChangeNotifyWorker(IN PUNIQUE_ID_WORK_ITEM WorkItem, IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: notify.c:591
#define UNICODE_NULL
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
ULONG IrpBufferLength
Definition: mntmgr.h:148
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
struct _MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
* PFILE_OBJECT
Definition: iotypes.h:1955
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
LIST_ENTRY UniqueIdWorkerItemListEntry
Definition: mntmgr.h:141
static const WCHAR Cleanup[]
Definition: register.c:80
#define AllocatePool(Size)
Definition: mntmgr.h:153
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define IO_NO_INCREMENT
Definition: iotypes.h:566
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615

Referenced by MountMgrMountedDeviceArrival().

◆ IssueUniqueIdChangeNotifyWorker()

VOID IssueUniqueIdChangeNotifyWorker ( IN PUNIQUE_ID_WORK_ITEM  WorkItem,
IN PMOUNTDEV_UNIQUE_ID  UniqueId 
)

Definition at line 591 of file notify.c.

593 {
594  PIRP Irp;
597  PIO_STACK_LOCATION Stack;
599 
600  /* Get the device object */
601  Status = IoGetDeviceObjectPointer(&(WorkItem->DeviceName),
603  &FileObject,
604  &DeviceObject);
605  if (!NT_SUCCESS(Status))
606  {
607  RemoveWorkItem(WorkItem);
608  return;
609  }
610 
611  /* And then, the attached device */
613 
614  /* Initialize the IRP */
615  Irp = WorkItem->Irp;
616  IoInitializeIrp(Irp, IoSizeOfIrp(WorkItem->StackSize), (CCHAR)WorkItem->StackSize);
617 
618  if (InterlockedExchange((PLONG)&(WorkItem->Event), 0) != 0)
619  {
622  RemoveWorkItem(WorkItem);
623  return;
624  }
625 
626  Irp->AssociatedIrp.SystemBuffer = WorkItem->IrpBuffer;
627  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
628  RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, UniqueId, UniqueId->UniqueIdLength + sizeof(USHORT));
629 
631 
632  Stack->Parameters.DeviceIoControl.InputBufferLength = UniqueId->UniqueIdLength + sizeof(USHORT);
633  Stack->Parameters.DeviceIoControl.OutputBufferLength = WorkItem->IrpBufferLength;
634  Stack->Parameters.DeviceIoControl.Type3InputBuffer = 0;
635  Stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY;
637 
638  Status = IoSetCompletionRoutineEx(WorkItem->DeviceExtension->DeviceObject,
639  Irp,
641  WorkItem,
642  TRUE, TRUE, TRUE);
643  if (!NT_SUCCESS(Status))
644  {
647  RemoveWorkItem(WorkItem);
648  return;
649  }
650 
651  /* Call the driver */
655 }
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY
Definition: imports.h:86
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
_In_ PIRP Irp
Definition: csq.h:116
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
VOID NTAPI IoInitializeIrp(IN PIRP Irp, IN USHORT PacketSize, IN CCHAR StackSize)
Definition: irp.c:1854
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
char CCHAR
Definition: typedefs.h:51
NTSTATUS NTAPI IoSetCompletionRoutineEx(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_COMPLETION_ROUTINE CompletionRoutine, IN PVOID Context, IN BOOLEAN InvokeOnSuccess, IN BOOLEAN InvokeOnError, IN BOOLEAN InvokeOnCancel)
Definition: iocomp.c:220
* PFILE_OBJECT
Definition: iotypes.h:1955
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
#define InterlockedExchange
Definition: armddk.h:54
NTSTATUS NTAPI UniqueIdChangeNotifyCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: notify.c:569
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
unsigned short USHORT
Definition: pedump.c:61
#define IoSizeOfIrp(_StackSize)
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
VOID RemoveWorkItem(IN PUNIQUE_ID_WORK_ITEM WorkItem)
Definition: notify.c:481
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
signed int * PLONG
Definition: retypes.h:5
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52

Referenced by IssueUniqueIdChangeNotify(), and UniqueIdChangeNotifyWorker().

◆ IsUniqueIdPresent()

BOOLEAN IsUniqueIdPresent ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PDATABASE_ENTRY  DatabaseEntry 
)

Definition at line 221 of file uniqueid.c.

223 {
224  PLIST_ENTRY NextEntry;
225  PDEVICE_INFORMATION DeviceInformation;
226 
227  /* If no device, no unique ID (O'rly?!)
228  * ./)/).
229  * (°-°)
230  * (___) ORLY?
231  * " "
232  */
233  if (IsListEmpty(&(DeviceExtension->DeviceListHead)))
234  {
235  return FALSE;
236  }
237 
238  /* Now we know that we have devices, find the one */
239  for (NextEntry = DeviceExtension->DeviceListHead.Flink;
240  NextEntry != &(DeviceExtension->DeviceListHead);
241  NextEntry = NextEntry->Flink)
242  {
243  DeviceInformation = CONTAINING_RECORD(NextEntry,
245  DeviceListEntry);
246 
247  if (DeviceInformation->UniqueId->UniqueIdLength != DatabaseEntry->UniqueIdLength)
248  {
249  continue;
250  }
251 
252  /* It's matching! */
253  if (RtlCompareMemory((PVOID)((ULONG_PTR)DatabaseEntry + DatabaseEntry->UniqueIdOffset),
254  DeviceInformation->UniqueId->UniqueId,
255  DatabaseEntry->UniqueIdLength) == DatabaseEntry->UniqueIdLength)
256  {
257  return TRUE;
258  }
259  }
260 
261  /* No luck... */
262  return FALSE;
263 }
#define TRUE
Definition: types.h:120
USHORT UniqueIdLength
Definition: imports.h:138
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
uint32_t ULONG_PTR
Definition: typedefs.h:64
PVOID DeviceExtension
Definition: env_spec_w32.h:418
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:120
Definition: typedefs.h:118
PMOUNTDEV_UNIQUE_ID UniqueId
Definition: mntmgr.h:49
UCHAR UniqueId[1]
Definition: imports.h:139
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465

Referenced by ReconcileThisDatabaseWithMasterWorker().

◆ MountMgrCancel()

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

Definition at line 1682 of file mountmgr.c.

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

Referenced by MountMgrChangeNotify(), and MountMgrCleanup().

◆ MountMgrCreatePointWorker()

NTSTATUS MountMgrCreatePointWorker ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PUNICODE_STRING  SymbolicLinkName,
IN PUNICODE_STRING  DeviceName 
)

Definition at line 35 of file point.c.

38 {
40  PLIST_ENTRY DeviceEntry;
41  PMOUNTDEV_UNIQUE_ID UniqueId;
42  PSYMLINK_INFORMATION SymlinkInformation;
43  UNICODE_STRING SymLink, TargetDeviceName;
44  PDEVICE_INFORMATION DeviceInformation = NULL, DeviceInfo;
45 
46  /* Get device name */
48  &TargetDeviceName,
49  NULL, NULL, NULL,
50  NULL, NULL, NULL);
51  if (!NT_SUCCESS(Status))
52  {
53  return Status;
54  }
55 
56  /* First of all, try to find device */
57  for (DeviceEntry = DeviceExtension->DeviceListHead.Flink;
58  DeviceEntry != &(DeviceExtension->DeviceListHead);
59  DeviceEntry = DeviceEntry->Flink)
60  {
61  DeviceInformation = CONTAINING_RECORD(DeviceEntry, DEVICE_INFORMATION, DeviceListEntry);
62 
63  if (RtlEqualUnicodeString(&TargetDeviceName, &(DeviceInformation->DeviceName), TRUE))
64  {
65  break;
66  }
67  }
68 
69  /* Copy symbolic link name and null terminate it */
70  SymLink.Buffer = AllocatePool(SymbolicLinkName->Length + sizeof(UNICODE_NULL));
71  if (!SymLink.Buffer)
72  {
73  FreePool(TargetDeviceName.Buffer);
75  }
76 
77  RtlCopyMemory(SymLink.Buffer, SymbolicLinkName->Buffer, SymbolicLinkName->Length);
78  SymLink.Buffer[SymbolicLinkName->Length / sizeof(WCHAR)] = UNICODE_NULL;
79  SymLink.Length = SymbolicLinkName->Length;
80  SymLink.MaximumLength = SymbolicLinkName->Length + sizeof(UNICODE_NULL);
81 
82  /* If we didn't find device */
83  if (DeviceEntry == &(DeviceExtension->DeviceListHead))
84  {
85  /* Then, try with unique ID */
86  Status = QueryDeviceInformation(SymbolicLinkName,
87  NULL, &UniqueId,
88  NULL, NULL, NULL,
89  NULL, NULL);
90  if (!NT_SUCCESS(Status))
91  {
92  FreePool(TargetDeviceName.Buffer);
93  FreePool(SymLink.Buffer);
94  return Status;
95  }
96 
97  /* Create a link to the device */
98  Status = GlobalCreateSymbolicLink(&SymLink, &TargetDeviceName);
99  if (!NT_SUCCESS(Status))
100  {
101  FreePool(UniqueId);
102  FreePool(TargetDeviceName.Buffer);
103  FreePool(SymLink.Buffer);
104  return Status;
105  }
106 
107  /* If caller provided driver letter, delete it */
108  if (IsDriveLetter(&SymLink))
109  {
110  DeleteRegistryDriveLetter(UniqueId);
111  }
112 
113  /* Device will be identified with its unique ID */
115  DatabasePath,
116  SymLink.Buffer,
117  REG_BINARY,
118  UniqueId->UniqueId,
119  UniqueId->UniqueIdLength);
120 
121  FreePool(UniqueId);
122  FreePool(TargetDeviceName.Buffer);
123  FreePool(SymLink.Buffer);
124  return Status;
125  }
126 
127  /* If call provided a driver letter whereas device already has one
128  * fail, this is not doable
129  */
130  if (IsDriveLetter(&SymLink) && HasDriveLetter(DeviceInformation))
131  {
132  FreePool(TargetDeviceName.Buffer);
133  FreePool(SymLink.Buffer);
135  }
136 
137  /* Now, create a link */
138  Status = GlobalCreateSymbolicLink(&SymLink, &TargetDeviceName);
139  FreePool(TargetDeviceName.Buffer);
140  if (!NT_SUCCESS(Status))
141  {
142  FreePool(SymLink.Buffer);
143  return Status;
144  }
145 
146  /* Associate Unique ID <-> symbolic name */
147  UniqueId = DeviceInformation->UniqueId;
149  DatabasePath,
150  SymLink.Buffer,
151  REG_BINARY,
152  UniqueId->UniqueId,
153  UniqueId->UniqueIdLength);
154  if (!NT_SUCCESS(Status))
155  {
156  GlobalDeleteSymbolicLink(&SymLink);
157  FreePool(SymLink.Buffer);
158  return Status;
159  }
160 
161  /* Now, prepare to save the link with the device */
162  SymlinkInformation = AllocatePool(sizeof(SYMLINK_INFORMATION));
163  if (!SymlinkInformation)
164  {
166  GlobalDeleteSymbolicLink(&SymLink);
167  FreePool(SymLink.Buffer);
168  return Status;
169  }
170 
171  SymlinkInformation->Name.Length = SymLink.Length;
172  SymlinkInformation->Name.MaximumLength = SymLink.Length + sizeof(UNICODE_NULL);
173  SymlinkInformation->Name.Buffer = AllocatePool(SymlinkInformation->Name.MaximumLength);
174  if (!SymlinkInformation->Name.Buffer)
175  {
177  FreePool(SymlinkInformation);
178  GlobalDeleteSymbolicLink(&SymLink);
179  FreePool(SymLink.Buffer);
180  return Status;
181  }
182 
183  /* Save the link and mark it online */
184  RtlCopyMemory(SymlinkInformation->Name.Buffer, SymLink.Buffer, SymlinkInformation->Name.Length);
185  SymlinkInformation->Name.Buffer[SymlinkInformation->Name.Length / sizeof(WCHAR)] = UNICODE_NULL;
186  SymlinkInformation->Online = TRUE;
187  InsertTailList(&DeviceInformation->SymbolicLinksListHead, &SymlinkInformation->SymbolicLinksListEntry);
188  SendLinkCreated(&(SymlinkInformation->Name));
189 
190  /* If we have a drive letter */
191  if (IsDriveLetter(&SymLink))
192  {
193  /* Then, delete the no drive letter entry */
194  DeleteNoDriveLetterEntry(UniqueId);
195 
196  /* And post online notification if asked */
197  if (!DeviceInformation->SkipNotifications)
198  {
200  }
201  }
202 
203  /* If that's a volume with automatic drive letter, it's now time to resync databases */
204  if (MOUNTMGR_IS_VOLUME_NAME(&SymLink) && DeviceExtension->AutomaticDriveLetter)
205  {
206  for (DeviceEntry = DeviceExtension->DeviceListHead.Flink;
207  DeviceEntry != &(DeviceExtension->DeviceListHead);
208  DeviceEntry = DeviceEntry->Flink)
209  {
210  DeviceInfo = CONTAINING_RECORD(DeviceEntry, DEVICE_INFORMATION, DeviceListEntry);
211 
212  /* If there's one, ofc! */
213  if (!DeviceInfo->NoDatabase)
214  {
216  }
217  }
218  }
219 
220  /* Notify & quit */
221  FreePool(SymLink.Buffer);
223 
224  if (!DeviceInformation->ManuallyRegistered)
225  {
227  }
228 
229  return Status;
230 }
VOID DeleteRegistryDriveLetter(IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: database.c:2046
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define REG_BINARY
Definition: nt_native.h:1496
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSTATUS GlobalDeleteSymbolicLink(IN PUNICODE_STRING DosName)
Definition: symlink.c:136
LONG NTSTATUS
Definition: precomp.h:26
USHORT UniqueIdLength
Definition: imports.h:138
BOOLEAN IsDriveLetter(PUNICODE_STRING SymbolicName)
Definition: symlink.c:922
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define InsertTailList(ListHead, Entry)
VOID DeleteNoDriveLetterEntry(IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: database.c:2098
#define FreePool(P)
Definition: mntmgr.h:154
UNICODE_STRING SymbolicName
Definition: mntmgr.h:48
VOID ReconcileThisDatabaseWithMaster(IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation)
Definition: database.c:1613
#define UNICODE_NULL
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG, PCWSTR, PCWSTR, ULONG, PVOID, ULONG)
#define MOUNTMGR_IS_VOLUME_NAME(s)
Definition: mountmgr.h:61
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
NTSTATUS QueryDeviceInformation(IN PUNICODE_STRING SymbolicName, OUT PUNICODE_STRING DeviceName OPTIONAL, OUT PMOUNTDEV_UNIQUE_ID *UniqueId OPTIONAL, OUT PBOOLEAN Removable OPTIONAL, OUT PBOOLEAN GptDriveLetter OPTIONAL, OUT PBOOLEAN HasGuid OPTIONAL, IN OUT LPGUID StableGuid OPTIONAL, OUT PBOOLEAN Valid OPTIONAL)
Definition: mountmgr.c:195
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
BOOLEAN SkipNotifications
Definition: mntmgr.h:58
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
LIST_ENTRY SymbolicLinksListHead
Definition: mntmgr.h:45
struct _DeviceInfo DeviceInfo
VOID MountMgrNotify(IN PDEVICE_EXTENSION DeviceExtension)
Definition: notify.c:313
Definition: typedefs.h:118
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
BOOLEAN ManuallyRegistered
Definition: mntmgr.h:53
#define AllocatePool(Size)
Definition: mntmgr.h:153
PWSTR DatabasePath
Definition: database.c:31
Status
Definition: gdiplustypes.h:24
VOID PostOnlineNotification(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName)
Definition: notify.c:145
NTSTATUS GlobalCreateSymbolicLink(IN PUNICODE_STRING DosName, IN PUNICODE_STRING DeviceName)
Definition: symlink.c:111
BOOLEAN HasDriveLetter(IN PDEVICE_INFORMATION DeviceInformation)
Definition: mountmgr.c:88
UNICODE_STRING DeviceName
Definition: mntmgr.h:50
VOID SendLinkCreated(IN PUNICODE_STRING SymbolicName)
Definition: symlink.c:160
PMOUNTDEV_UNIQUE_ID UniqueId
Definition: mntmgr.h:49
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
UCHAR UniqueId[1]
Definition: imports.h:139
VOID MountMgrNotifyNameChange(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName, IN BOOLEAN ValidateVolume)
Definition: notify.c:353

Referenced by MountMgrCreatePoint(), MountMgrNextDriveLetterWorker(), ProcessSuggestedDriveLetters(), and WriteUniqueIdToMaster().

◆ MountMgrFreeDeadDeviceInfo()

VOID MountMgrFreeDeadDeviceInfo ( IN PDEVICE_INFORMATION  DeviceInformation)

Definition at line 707 of file mountmgr.c.

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

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

◆ MountMgrMountedDeviceArrival()

NTSTATUS MountMgrMountedDeviceArrival ( IN PDEVICE_EXTENSION  Extension,
IN PUNICODE_STRING  SymbolicName,
IN BOOLEAN  FromVolume 
)

Definition at line 937 of file mountmgr.c.

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

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

◆ MountMgrMountedDeviceRemoval()

VOID MountMgrMountedDeviceRemoval ( IN PDEVICE_EXTENSION  Extension,
IN PUNICODE_STRING  DeviceName 
)

Definition at line 1452 of file mountmgr.c.

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

Referenced by MountMgrMountedDeviceNotification(), and MountMgrTargetDeviceNotification().

◆ MountMgrNotify()

VOID MountMgrNotify ( IN PDEVICE_EXTENSION  DeviceExtension)

Definition at line 313 of file notify.c.

314 {
315  PIRP Irp;
316  KIRQL OldIrql;
317  LIST_ENTRY CopyList;
318  PLIST_ENTRY NextEntry;
319 
320  /* Increase the epic number */
321  DeviceExtension->EpicNumber++;
322 
323  InitializeListHead(&CopyList);
324 
325  /* Copy all the pending IRPs for notification */
327  while (!IsListEmpty(&(DeviceExtension->IrpListHead)))
328  {
329  NextEntry = RemoveHeadList(&(DeviceExtension->IrpListHead));
330  Irp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
332  InsertTailList(&CopyList, &(Irp->Tail.Overlay.ListEntry));
333  }
335 
336  /* Then, notify them one by one */
337  while (!IsListEmpty(&CopyList))
338  {
339  NextEntry = RemoveHeadList(&CopyList);
340  Irp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
341 
342  *((PULONG)Irp->AssociatedIrp.SystemBuffer) = DeviceExtension->EpicNumber;
343  Irp->IoStatus.Information = sizeof(DeviceExtension->EpicNumber);
344 
346  }
347 }
_In_ PIRP Irp
Definition: csq.h:116
VOID NTAPI IoAcquireCancelSpinLock(OUT PKIRQL Irql)
Definition: util.c:56
IRP
Definition: iotypes.h:2463
#define InsertTailList(ListHead, Entry)
IoSetCancelRoutine(Irp, CancelRoutine)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
UCHAR KIRQL
Definition: env_spec_w32.h:591
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
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
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
Definition: typedefs.h:118
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
unsigned int * PULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566

Referenced by MountMgrCreatePointWorker(), MountMgrDeletePoints(), and MountMgrVolumeMountPointChanged().

◆ MountMgrNotifyNameChange()

VOID MountMgrNotifyNameChange ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PUNICODE_STRING  DeviceName,
IN BOOLEAN  ValidateVolume 
)

Definition at line 353 of file notify.c.

356 {
357  PIRP Irp;
358  KEVENT Event;
360  PLIST_ENTRY NextEntry;
362  PIO_STACK_LOCATION Stack;
365  PDEVICE_RELATIONS DeviceRelations;
366  PDEVICE_INFORMATION DeviceInformation;
367  TARGET_DEVICE_CUSTOM_NOTIFICATION DeviceNotification;
368 
369  /* If we have to validate volume */
370  if (ValidateVolume)
371  {
372  /* Then, ensure we can find the device */
373  NextEntry = DeviceExtension->DeviceListHead.Flink;
374  while (NextEntry != &(DeviceExtension->DeviceListHead))
375  {
376  DeviceInformation = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
377  if (RtlCompareUnicodeString(DeviceName, &(DeviceInformation->DeviceName), TRUE) == 0)
378  {
379  break;
380  }
381  }
382 
383  /* No need to notify for a PnP device or if we didn't find the device */
384  if (NextEntry == &(DeviceExtension->DeviceListHead) ||
385  !DeviceInformation->ManuallyRegistered)
386  {
387  return;
388  }
389  }
390 
391  /* Then, get device object */
394  &FileObject,
395  &DeviceObject);
396  if (!NT_SUCCESS(Status))
397  {
398  return;
399  }
400 
402 
404 
405  /* Set up empty IRP (yes, yes!) */
407  DeviceObject,
408  NULL,
409  0,
410  NULL,
411  0,
412  FALSE,
413  &Event,
414  &IoStatusBlock);
415  if (!Irp)
416  {
419  return;
420  }
421 
423 
424  Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
425  Irp->IoStatus.Information = 0;
426 
427  /* Properly set it, we want to query device relations */
428  Stack->MajorFunction = IRP_MJ_PNP;
430  Stack->Parameters.QueryDeviceRelations.Type = TargetDeviceRelation;
431  Stack->FileObject = FileObject;
432 
433  /* And call driver */
435  if (Status == STATUS_PENDING)
436  {
439  }
440 
443 
444  if (!NT_SUCCESS(Status))
445  {
446  return;
447  }
448 
449  /* Validate device return */
450  DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
451  if (DeviceRelations->Count < 1)
452  {
453  ExFreePool(DeviceRelations);
454  return;
455  }
456 
457  DeviceObject = DeviceRelations->Objects[0];
458  ExFreePool(DeviceRelations);
459 
460  /* Set up real notification */
461  DeviceNotification.Version = 1;
462  DeviceNotification.Size = sizeof(TARGET_DEVICE_CUSTOM_NOTIFICATION);
463  DeviceNotification.Event = GUID_IO_VOLUME_NAME_CHANGE;
464  DeviceNotification.FileObject = NULL;
465  DeviceNotification.NameBufferOffset = -1;
466 
467  /* And report */
469  &DeviceNotification,
470  NULL, NULL);
471 
473 
474  return;
475 }
#define TRUE
Definition: types.h:120
struct _TARGET_DEVICE_CUSTOM_NOTIFICATION TARGET_DEVICE_CUSTOM_NOTIFICATION
_In_ PIRP Irp
Definition: csq.h:116
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2055
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
WCHAR DeviceName[]
Definition: adapter.cpp:21
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_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
* PFILE_OBJECT
Definition: iotypes.h:1955
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
Definition: typedefs.h:118
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
BOOLEAN ManuallyRegistered
Definition: mntmgr.h:53
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
PFILE_OBJECT FileObject
Definition: iotypes.h:2813
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IRP_MN_QUERY_DEVICE_RELATIONS
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
UNICODE_STRING DeviceName
Definition: mntmgr.h:50
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
struct _FILE_OBJECT * FileObject
Definition: iotypes.h:975
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
NTSTATUS NTAPI IoReportTargetDeviceChangeAsynchronous(IN PDEVICE_OBJECT PhysicalDeviceObject, IN PVOID NotificationStructure, IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback OPTIONAL, IN PVOID Context OPTIONAL)
Definition: pnpreport.c:519
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by MountMgrCreatePointWorker(), MountMgrDeletePoints(), MountMgrQueryDosVolumePaths(), and MountMgrVolumeMountPointChanged().

◆ MountMgrQuerySymbolicLink()

NTSTATUS MountMgrQuerySymbolicLink ( IN PUNICODE_STRING  SymbolicName,
IN OUT PUNICODE_STRING  LinkTarget 
)

Definition at line 959 of file symlink.c.

961 {
963  HANDLE LinkHandle;
965 
966  /* Open the symbolic link */
968  SymbolicName,
970  NULL,
971  NULL);
972 
973  Status = ZwOpenSymbolicLinkObject(&LinkHandle,
974  GENERIC_READ,
976  if (!NT_SUCCESS(Status))
977  {
978  return Status;
979  }
980 
981  /* Query its target */
982  Status = ZwQuerySymbolicLinkObject(LinkHandle,
983  LinkTarget,
984  NULL);
985 
986  ZwClose(LinkHandle);
987 
988  if (!NT_SUCCESS(Status))
989  {
990  return Status;
991  }
992 
993  if (LinkTarget->Length <= sizeof(WCHAR))
994  {
995  return Status;
996  }
997 
998  /* If it's not finished by \, just return */
999  if (LinkTarget->Buffer[LinkTarget->Length / sizeof(WCHAR) - 1] != L'\\')
1000  {
1001  return Status;
1002  }
1003 
1004  /* Otherwise, ensure to drop the tailing \ */
1005  LinkTarget->Length -= sizeof(WCHAR);
1007 
1008  return Status;
1009 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
LONG NTSTATUS
Definition: precomp.h:26
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
_Inout_ PUNICODE_STRING LinkTarget
Definition: zwfuncs.h:292
#define UNICODE_NULL
smooth NULL
Definition: ftsmooth.c:416
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const WCHAR L[]
Definition: oid.c:1250
#define GENERIC_READ
Definition: compat.h:124
Status
Definition: gdiplustypes.h:24
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSYSAPI NTSTATUS NTAPI ZwOpenSymbolicLinkObject(_Out_ PHANDLE SymbolicLinkHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)

Referenced by MountMgrVolumeMountPointCreated(), and MountMgrVolumeMountPointDeleted().

◆ MountmgrReadNoAutoMount()

INIT_FUNCTION BOOLEAN MountmgrReadNoAutoMount ( IN PUNICODE_STRING  RegistryPath)

Definition at line 904 of file mountmgr.c.

905 {
907  ULONG Result, Default = 0;
909 
911 
912  /* Simply read data from register */
914  QueryTable[0].Name = L"NoAutoMount";
918  QueryTable[0].DefaultLength = sizeof(ULONG);
919 
922  QueryTable,
923  NULL,
924  NULL);
925  if (!NT_SUCCESS(Status))
926  {
927  return (Default != 0);
928  }
929 
930  return (Result != 0);
931 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4035
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
LONG NTSTATUS
Definition: precomp.h:26
smooth NULL
Definition: ftsmooth.c:416
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#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
Status
Definition: gdiplustypes.h:24
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:28
#define REG_NONE
Definition: nt_native.h:1492
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144

Referenced by DriverEntry().

◆ MountMgrUniqueIdChangeRoutine()

VOID MountMgrUniqueIdChangeRoutine ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PMOUNTDEV_UNIQUE_ID  OldUniqueId,
IN PMOUNTDEV_UNIQUE_ID  NewUniqueId 
)

Definition at line 71 of file uniqueid.c.

74 {
76  BOOLEAN ResyncNeeded;
77  PUNIQUE_ID_REPLICATE DuplicateId;
78  PDEVICE_INFORMATION DeviceInformation;
80  PMOUNTDEV_UNIQUE_ID UniqueId, NewDuplicateId;
81  PLIST_ENTRY ListHead, NextEntry, ReplicatedHead, NextReplicated;
82 
83  /* Synchronise with remote databases */
86 
89  QueryTable[0].EntryContext = NewUniqueId;
90 
91  /* Write new data */
94  QueryTable,
95  OldUniqueId,
96  NULL);
97 
98  /* Browse all the devices to find the one that
99  * owns the old unique ID
100  */
101  ListHead = &(DeviceExtension->DeviceListHead);
102  NextEntry = ListHead->Flink;
103  while (ListHead != NextEntry)
104  {
105  DeviceInformation = CONTAINING_RECORD(NextEntry,
107  DeviceListEntry);
108 
109  if (DeviceInformation->UniqueId->UniqueIdLength == OldUniqueId->UniqueIdLength &&
110  RtlCompareMemory(OldUniqueId->UniqueId,
111  DeviceInformation->UniqueId->UniqueId,
112  OldUniqueId->UniqueIdLength) == OldUniqueId->UniqueIdLength)
113  {
114  break;
115  }
116 
117  NextEntry = NextEntry->Flink;
118  }
119 
120  /* If we didn't find any release everything and quit */
121  if (ListHead == NextEntry)
122  {
124  1, FALSE);
125 
126  if (NT_SUCCESS(Status))
127  {
129  }
130 
131  return;
132  }
133 
134  /* If lock failed, then, just update this database */
135  if (!NT_SUCCESS(Status))
136  {
139  1, FALSE);
140  return;
141  }
142 
143  /* Allocate new unique ID */
144  UniqueId = AllocatePool(NewUniqueId->UniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
145  if (!UniqueId)
146  {
148  1, FALSE);
150  return;
151  }
152 
153  /* Release old one */
154  FreePool(DeviceInformation->UniqueId);
155  /* And set new one */
156  DeviceInformation->UniqueId = UniqueId;
157  UniqueId->UniqueIdLength = NewUniqueId->UniqueIdLength;
158  RtlCopyMemory(UniqueId->UniqueId, NewUniqueId->UniqueId, NewUniqueId->UniqueIdLength);
159 
160  /* Now, check if it's required to update replicated unique IDs as well */
161  ListHead = &(DeviceExtension->DeviceListHead);
162  NextEntry = ListHead->Flink;
163  while (ListHead != NextEntry)
164  {
165  DeviceInformation = CONTAINING_RECORD(NextEntry,
167  DeviceListEntry);
168  ResyncNeeded = FALSE;
169 
170  ReplicatedHead = &(DeviceInformation->ReplicatedUniqueIdsListHead);
171  NextReplicated = ReplicatedHead->Flink;
172  while (ReplicatedHead != NextReplicated)
173  {
174  DuplicateId = CONTAINING_RECORD(NextReplicated,
176  ReplicatedUniqueIdsListEntry);
177 
178  if (DuplicateId->UniqueId->UniqueIdLength == OldUniqueId->UniqueIdLength)
179  {
180  if (RtlCompareMemory(DuplicateId->UniqueId->UniqueId,
181  OldUniqueId->UniqueId,
182  OldUniqueId->UniqueIdLength) == OldUniqueId->UniqueIdLength)
183  {
184  /* It was our old unique ID */
185  NewDuplicateId = AllocatePool(NewUniqueId->UniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
186  if (NewDuplicateId)
187  {
188  /* Update it */
189  ResyncNeeded = TRUE;
190  FreePool(DuplicateId->UniqueId);
191 
192  DuplicateId->UniqueId = NewDuplicateId;
193  DuplicateId->UniqueId->UniqueIdLength = NewUniqueId->UniqueIdLength;
194  RtlCopyMemory(NewDuplicateId->UniqueId, NewUniqueId->UniqueId, NewUniqueId->UniqueIdLength);
195  }
196  }
197  }
198 
199  NextReplicated = NextReplicated->Flink;
200  }
201 
202  /* If resync is required on this device, do it */
203  if (ResyncNeeded)
204  {
205  ChangeRemoteDatabaseUniqueId(DeviceInformation, OldUniqueId, NewUniqueId);
206  }
207 
208  NextEntry = NextEntry->Flink;
209  }
210 
213 
214  return;
215 }
PMOUNTDEV_UNIQUE_ID UniqueId
Definition: mntmgr.h:82
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4035
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
LONG NTSTATUS
Definition: precomp.h:26
USHORT UniqueIdLength
Definition: imports.h:138
NTSTATUS NTAPI ChangeUniqueIdRoutine(IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
Definition: uniqueid.c:36
#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
VOID ReconcileThisDatabaseWithMaster(IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation)
Definition: database.c:1613
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
VOID ChangeRemoteDatabaseUniqueId(IN PDEVICE_INFORMATION DeviceInformation, IN PMOUNTDEV_UNIQUE_ID OldUniqueId, IN PMOUNTDEV_UNIQUE_ID NewUniqueId)
Definition: database.c:1909
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Definition: typedefs.h:118
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define AllocatePool(Size)
Definition: mntmgr.h:153
PWSTR DatabasePath
Definition: database.c:31
Status
Definition: gdiplustypes.h:24
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
NTSTATUS WaitForRemoteDatabaseSemaphore(IN PDEVICE_EXTENSION DeviceExtension)
Definition: database.c:371
LIST_ENTRY ReplicatedUniqueIdsListHead
Definition: mntmgr.h:46
#define IO_NO_INCREMENT
Definition: iotypes.h:566
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
VOID ReleaseRemoteDatabaseSemaphore(IN PDEVICE_EXTENSION DeviceExtension)
Definition: database.c:391
PMOUNTDEV_UNIQUE_ID UniqueId
Definition: mntmgr.h:49
UCHAR UniqueId[1]
Definition: imports.h:139
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465

Referenced by UniqueIdChangeNotifyWorker().

◆ OpenRemoteDatabase()

HANDLE OpenRemoteDatabase ( IN PDEVICE_INFORMATION  DeviceInformation,
IN BOOLEAN  MigrateDatabase 
)

Definition at line 1836 of file database.c.

1838 {
1839  HANDLE Database;
1840  NTSTATUS Status;
1844  UNICODE_STRING DeviceRemoteDatabase;
1845 
1846  Database = 0;
1847 
1848  /* Get database name */
1849  DeviceRemoteDatabase.Length = DeviceInformation->DeviceName.Length + RemoteDatabase.Length;
1850  DeviceRemoteDatabase.MaximumLength = DeviceRemoteDatabase.Length + sizeof(WCHAR);
1851  DeviceRemoteDatabase.Buffer = AllocatePool(DeviceRemoteDatabase.MaximumLength);
1852  if (!DeviceRemoteDatabase.Buffer)
1853  {
1854  return 0;
1855  }
1856 
1857  RtlCopyMemory(DeviceRemoteDatabase.Buffer, DeviceInformation->DeviceName.Buffer, DeviceInformation->DeviceName.Length);
1858  RtlCopyMemory(DeviceRemoteDatabase.Buffer + (DeviceInformation->DeviceName.Length / sizeof(WCHAR)),
1860  DeviceRemoteDatabase.Buffer[DeviceRemoteDatabase.Length / sizeof(WCHAR)] = UNICODE_NULL;
1861 
1862  /* Open database */
1864  &DeviceRemoteDatabase,
1866  NULL,
1867  NULL);
1868 
1869  /* Disable hard errors */
1871 
1877  &IoStatusBlock,
1878  NULL,
1880  0,
1881  (!MigrateDatabase || DeviceInformation->Migrated == 0) ? FILE_OPEN_IF : FILE_OPEN,
1883  NULL,
1884  0,
1886  NULL,
1889  {
1890  DPRINT1("Attempt to exploit CVE-2015-1769. See CORE-10216\n");
1891  }
1892 
1893  /* If base it to be migrated and was opened successfully, go ahead */
1894  if (MigrateDatabase && NT_SUCCESS(Status))
1895  {
1896  CreateRemoteDatabase(DeviceInformation, &Database);
1897  }
1898 
1900  FreePool(DeviceRemoteDatabase.Buffer);
1901 
1902  return Database;
1903 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define FILE_WRITE_EA
Definition: nt_native.h:640
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define FILE_OPEN_IF
Definition: from_kernel.h:56
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
LONG NTSTATUS
Definition: precomp.h:26
UNICODE_STRING RemoteDatabase
Definition: database.c:34
#define FILE_APPEND_DATA
Definition: nt_native.h:634
#define FreePool(P)
Definition: mntmgr.h:154
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
#define STATUS_STOPPED_ON_SYMLINK
Definition: ntstatus.h:212
#define IO_STOP_ON_SYMLINK
Definition: iotypes.h:6997
#define FILE_SYNCHRONOUS_IO_ALERT
Definition: from_kernel.h:30
#define UNICODE_NULL
#define IO_NO_PARAMETER_CHECKING
Definition: iotypes.h:509
#define FILE_READ_DATA
Definition: nt_native.h:628
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define FILE_WRITE_DATA
Definition: nt_native.h:631
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define READ_CONTROL
Definition: nt_native.h:58
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
BOOLEAN NTAPI IoSetThreadHardErrorMode(IN BOOLEAN HardErrorEnabled)
Definition: error.c:707
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define SYNCHRONIZE
Definition: nt_native.h:61
#define AllocatePool(Size)
Definition: mntmgr.h:153
Status
Definition: gdiplustypes.h:24
#define FILE_OPEN
Definition: from_kernel.h:54
#define FILE_READ_EA
Definition: nt_native.h:638
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
NTSTATUS CreateRemoteDatabase(IN PDEVICE_INFORMATION DeviceInformation, IN OUT PHANDLE Database)
Definition: database.c:1789
#define DPRINT1
Definition: precomp.h:8
NTSTATUS NTAPI IoCreateFile(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG Disposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength, IN CREATE_FILE_TYPE CreateFileType, IN PVOID ExtraCreateParameters OPTIONAL, IN ULONG Options)
Definition: file.c:3009
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106

Referenced by ChangeRemoteDatabaseUniqueId(), MountMgrVolumeMountPointCreated(), MountMgrVolumeMountPointDeleted(), and ReconcileThisDatabaseWithMasterWorker().

◆ PostOnlineNotification()

VOID PostOnlineNotification ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PUNICODE_STRING  SymbolicName 
)

Definition at line 145 of file notify.c.

147 {
148  KIRQL OldIrql;
150 
151  /* Allocate a notification work item */
152  WorkItem = AllocatePool(sizeof(ONLINE_NOTIFICATION_WORK_ITEM));
153  if (!WorkItem)
154  {
155  return;
156  }
157 
159  WorkItem->DeviceExtension = DeviceExtension;
160  WorkItem->SymbolicName.Length = SymbolicName->Length;
161  WorkItem->SymbolicName.MaximumLength = SymbolicName->Length + sizeof(WCHAR);
163  if (!WorkItem->SymbolicName.Buffer)
164  {
165  FreePool(WorkItem);
166  return;
167  }
168 
170  WorkItem->SymbolicName.Buffer[SymbolicName->Length / sizeof(WCHAR)] = UNICODE_NULL;
171 
172  KeAcquireSpinLock(&(DeviceExtension->WorkerLock), &OldIrql);
173  DeviceExtension->OnlineNotificationCount++;
174 
175  /* If no worker are active */
176  if (DeviceExtension->OnlineNotificationWorkerActive == 0)
177  {
178  /* Queue that one for execution */
179  DeviceExtension->OnlineNotificationWorkerActive = 1;
181  }
182  else
183  {
184  /* Otherwise, just put it in the queue list */
185  InsertTailList(&(DeviceExtension->OnlineNotificationListHead), &(WorkItem->WorkItem.List));
186  }
187 
188  KeReleaseSpinLock(&(DeviceExtension->WorkerLock), OldIrql);
189 
190  return;
191 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
LIST_ENTRY List
Definition: extypes.h:203
USHORT MaximumLength
Definition: env_spec_w32.h:370
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
#define InsertTailList(ListHead, Entry)
#define FreePool(P)
Definition: mntmgr.h:154
UCHAR KIRQL
Definition: env_spec_w32.h:591
WORK_QUEUE_ITEM WorkItem
Definition: mntmgr.h:110
#define UNICODE_NULL
VOID NTAPI SendOnlineNotificationWorker(IN PVOID Parameter)
Definition: notify.c:96
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
__wchar_t WCHAR
Definition: xmlstorage.h:180
PDEVICE_EXTENSION DeviceExtension
Definition: mntmgr.h:111
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define AllocatePool(Size)
Definition: mntmgr.h:153
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
UNICODE_STRING SymbolicName
Definition: mntmgr.h:112

Referenced by MountMgrCreatePointWorker(), MountMgrVolumeMountPointCreated(), OnlineMountedVolumes(), and ReconcileThisDatabaseWithMasterWorker().

◆ QueryDeviceInformation()

NTSTATUS QueryDeviceInformation ( IN PUNICODE_STRING  SymbolicName,
OUT PUNICODE_STRING DeviceName  OPTIONAL,
OUT PMOUNTDEV_UNIQUE_ID *UniqueId  OPTIONAL,
OUT PBOOLEAN Removable  OPTIONAL,
OUT PBOOLEAN GptDriveLetter  OPTIONAL,
OUT PBOOLEAN HasGuid  OPTIONAL,
IN OUT LPGUID StableGuid  OPTIONAL,
OUT PBOOLEAN Valid  OPTIONAL 
)

Definition at line 195 of file mountmgr.c.

203 {
204  PIRP Irp;
205  USHORT Size;
206  KEVENT Event;
207  BOOLEAN IsRemovable;
211  PIO_STACK_LOCATION Stack;
212  NTSTATUS Status, IntStatus;
216  STORAGE_DEVICE_NUMBER StorageDeviceNumber;
218 
219  /* Get device associated with the symbolic name */
222  &FileObject,
223  &DeviceObject);
224  if (!NT_SUCCESS(Status))
225  {
226  return Status;
227  }
228 
229  /* The associate FO can't have a file name */
230  if (FileObject->FileName.Length)
231  {
234  }
235 
236  /* Check if it's removable & return to the user (if asked to) */
237  IsRemovable = (FileObject->DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA);
238  if (Removable)
239  {
240  *Removable = IsRemovable;
241  }
242 
243  /* Get the attached device */
245 
246  /* If we've been asked for a GPT drive letter */
247  if (GptDriveLetter)
248  {
249  /* Consider it has one */
250  *GptDriveLetter = TRUE;
251 
252  if (!IsRemovable)
253  {
254  /* Query the GPT attributes */
257  DeviceObject,
258  NULL,
259  0,
260  &GptAttributes,
261  sizeof(GptAttributes),
262  FALSE,
263  &Event,
264  &IoStatusBlock);
265  if (!Irp)
266  {
270  }
271 
273  if (Status == STATUS_PENDING)
274  {
277  }
278 
279  /* In case of failure, don't fail, that's no vital */
280  if (!NT_SUCCESS(Status))
281  {
283  }
284  /* Check if it has a drive letter */
285  else if (!(GptAttributes.GptAttributes &
286  GPT_BASIC_DATA_ATTRIBUTE_NO_DRIVE_LETTER))
287  {
288  *GptDriveLetter = FALSE;
289  }
290  }
291  }
292 
293  /* If caller wants to know if there's valid contents */
294  if (Valid)
295  {
296  /* Suppose it's not OK */
297  *Valid = FALSE;
298 
299  if (!IsRemovable)
300  {
301  /* Query partitions information */
304  DeviceObject,
305  NULL,
306  0,
307  &PartitionInfo,
308  sizeof(PartitionInfo),
309  FALSE,
310  &Event,
311  &IoStatusBlock);
312  if (!Irp)
313  {
317  }
318 
320  if (Status == STATUS_PENDING)
321  {
324  }
325 
326  /* Once again here, failure isn't major */
327  if (!NT_SUCCESS(Status))
328  {
330  }
331  /* Verify we know something in */
332  else if (PartitionInfo.PartitionStyle == PARTITION_STYLE_MBR &&
333  IsRecognizedPartition(PartitionInfo.Mbr.PartitionType))
334  {
335  *Valid = TRUE;
336  }
337 
338  /* It looks correct, ensure it is & query device number */
339  if (*Valid)
340  {
343  DeviceObject,
344  NULL,
345  0,
346  &StorageDeviceNumber,
347  sizeof(StorageDeviceNumber),
348  FALSE,
349  &Event,
350  &IoStatusBlock);
351  if (!Irp)
352  {
356  }
357 
359  if (Status == STATUS_PENDING)
360  {
363  }
364 
365  if (!NT_SUCCESS(Status))
366  {
368  }
369  else
370  {
371  *Valid = FALSE;
372  }
373  }
374  }
375  }
376 
377  /* If caller needs device name */
378  if (DeviceName)
379  {
380  /* Allocate a buffer just to request length */
381  Name = AllocatePool(sizeof(MOUNTDEV_NAME));
382  if (!Name)
383  {
387  }
388 
389  /* Query device name */
392  DeviceObject,
393  NULL,
394  0,
395  Name,
396  sizeof(MOUNTDEV_NAME),
397  FALSE,
398  &Event,
399  &IoStatusBlock);
400  if (!Irp)
401  {
402  FreePool(Name);
406  }
407 
409  Stack->FileObject = FileObject;
410 
412  if (Status == STATUS_PENDING)
413  {
416  }
417 
418  /* Now, we've got the correct length */
420  {
421  Size = Name->NameLength + sizeof(MOUNTDEV_NAME);
422 
423  FreePool(Name);
424 
425  /* Allocate proper size */
427  if (!Name)
428  {
432  }
433 
434  /* And query name (for real that time) */
437  DeviceObject,
438  NULL,
439  0,
440  Name,
441  Size,
442  FALSE,
443  &Event,
444  &IoStatusBlock);
445  if (!Irp)
446  {
447  FreePool(Name);
451  }
452 
454  Stack->FileObject = FileObject;
455 
457  if (Status == STATUS_PENDING)
458  {
461  }
462  }
463 
464  if (NT_SUCCESS(Status))
465  {
466  /* Copy back found name to the caller */
467  DeviceName->Length = Name->NameLength;
468  DeviceName->MaximumLength = Name->NameLength + sizeof(WCHAR);
469  DeviceName->Buffer = AllocatePool(DeviceName->MaximumLength);
470  if (!DeviceName->Buffer)
471  {
473  }
474  else
475  {
476  RtlCopyMemory(DeviceName->Buffer, Name->Name, Name->NameLength);
477  DeviceName->Buffer[Name->NameLength / sizeof(WCHAR)] = UNICODE_NULL;
478  }
479  }
480 
481  FreePool(Name);
482  }
483 
484  if (!NT_SUCCESS(Status))
485  {
488  return Status;
489  }
490 
491  /* If caller wants device unique ID */
492  if (UniqueId)
493  {
494  /* Prepare buffer to probe length */
496  if (!Id)
497  {
501  }
502 
503  /* Query unique ID length */
506  DeviceObject,
507  NULL,
508  0,
509  Id,
510  sizeof(MOUNTDEV_UNIQUE_ID),
511  FALSE,
512  &Event,
513  &IoStatusBlock);
514  if (!Irp)
515  {
516  FreePool(Id);
520  }
521 
523  Stack->FileObject = FileObject;
524 
526  if (Status == STATUS_PENDING)
527  {