ReactOS  0.4.15-dev-2961-gecb0c09
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)
 
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
 
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 }
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
LONG GetRemoteDatabaseSize(IN HANDLE Database)
Definition: database.c:40
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
base of all file and directory entries
Definition: entries.h:82

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 1911 of file database.c.

1914 {
1915  LONG Offset = 0;
1916  HANDLE Database;
1917  PDATABASE_ENTRY Entry, NewEntry;
1919 
1920  /* Open the remote database */
1921  Database = OpenRemoteDatabase(DeviceInformation, FALSE);
1922  if (!Database)
1923  {
1924  return;
1925  }
1926 
1927  /* Get all the entries */
1928  do
1929  {
1931  if (!Entry)
1932  {
1933  break;
1934  }
1935 
1936  /* Not the correct entry, skip it */
1937  if (Entry->UniqueIdLength != OldUniqueId->UniqueIdLength)
1938  {
1939  Offset += Entry->EntrySize;
1940  FreePool(Entry);
1941  continue;
1942  }
1943 
1944  /* Not the correct entry, skip it */
1945  if (RtlCompareMemory(OldUniqueId->UniqueId,
1946  (PVOID)((ULONG_PTR)Entry + Entry->UniqueIdOffset),
1947  Entry->UniqueIdLength) != Entry->UniqueIdLength)
1948  {
1949  Offset += Entry->EntrySize;
1950  FreePool(Entry);
1951  continue;
1952  }
1953 
1954  /* Here, we have the correct entry */
1955  NewEntry = AllocatePool(Entry->EntrySize + NewUniqueId->UniqueIdLength - OldUniqueId->UniqueIdLength);
1956  if (!NewEntry)
1957  {
1958  Offset += Entry->EntrySize;
1959  FreePool(Entry);
1960  continue;
1961  }
1962 
1963  /* Recreate the entry from the previous one */
1964  NewEntry->EntrySize = Entry->EntrySize + NewUniqueId->UniqueIdLength - OldUniqueId->UniqueIdLength;
1965  NewEntry->EntryReferences = Entry->EntryReferences;
1966  NewEntry->SymbolicNameOffset = sizeof(DATABASE_ENTRY);
1967  NewEntry->SymbolicNameLength = Entry->SymbolicNameLength;
1968  NewEntry->UniqueIdOffset = Entry->SymbolicNameLength + sizeof(DATABASE_ENTRY);
1969  NewEntry->UniqueIdLength = NewUniqueId->UniqueIdLength;
1970  RtlCopyMemory((PVOID)((ULONG_PTR)NewEntry + NewEntry->SymbolicNameOffset),
1971  (PVOID)((ULONG_PTR)Entry + Entry->SymbolicNameOffset),
1972  NewEntry->SymbolicNameLength);
1973  RtlCopyMemory((PVOID)((ULONG_PTR)NewEntry + NewEntry->UniqueIdOffset),
1974  NewUniqueId->UniqueId, NewEntry->UniqueIdLength);
1975 
1976  /* Delete old entry */
1978  if (!NT_SUCCESS(Status))
1979  {
1980  FreePool(Entry);
1981  FreePool(NewEntry);
1982  break;
1983  }
1984 
1985  /* And replace with new one */
1986  Status = AddRemoteDatabaseEntry(Database, NewEntry);
1987  FreePool(Entry);
1988  FreePool(NewEntry);
1989  } while (NT_SUCCESS(Status));
1990 
1992 
1993  return;
1994 }
USHORT UniqueIdOffset
Definition: mntmgr.h:91
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
HANDLE OpenRemoteDatabase(IN PDEVICE_INFORMATION DeviceInformation, IN BOOLEAN MigrateDatabase)
Definition: database.c:1837
USHORT SymbolicNameLength
Definition: mntmgr.h:90
#define FreePool(P)
Definition: mntmgr.h:154
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
USHORT UniqueIdLength
Definition: mntmgr.h:92
struct _DATABASE_ENTRY DATABASE_ENTRY
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
USHORT SymbolicNameOffset
Definition: mntmgr.h:89
Definition: mntmgr.h:85
NTSTATUS AddRemoteDatabaseEntry(IN HANDLE Database, IN PDATABASE_ENTRY Entry)
Definition: database.c:64
#define AllocatePool(Size)
Definition: mntmgr.h:153
NTSTATUS DeleteRemoteDatabaseEntry(IN HANDLE Database, IN LONG StartingOffset)
Definition: database.c:233
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
NTSTATUS CloseRemoteDatabase(IN HANDLE Database)
Definition: database.c:82
PDATABASE_ENTRY GetRemoteDatabaseEntry(IN HANDLE Database, IN LONG StartingOffset)
Definition: database.c:125
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
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:93
#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
NTKERNELAPI NTSTATUS ExUuidCreate(OUT UUID *Uuid)
Definition: uuid.c:380
Status
Definition: gdiplustypes.h:24
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_Must_inspect_result_ _In_ WDFOBJECT _In_ CONST GUID * Guid
Definition: wdfobject.h:760
#define AllocatePool(Size)
Definition: mntmgr.h:153
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 RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

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 }
PWSTR DatabasePath
Definition: database.c:31
static PWSTR GuidString
Definition: apphelp.c:93
#define REG_BINARY
Definition: nt_native.h:1496
uint16_t * PWCHAR
Definition: typedefs.h:56
#define FreePool(P)
Definition: mntmgr.h:154
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2430
#define UNICODE_NULL
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG, PCWSTR, PCWSTR, ULONG, PVOID, ULONG)
NTKERNELAPI NTSTATUS ExUuidCreate(OUT UUID *Uuid)
Definition: uuid.c:380
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_Must_inspect_result_ _In_ WDFOBJECT _In_ CONST GUID * Guid
Definition: wdfobject.h:760
static const WCHAR L[]
Definition: oid.c:1250
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define AllocatePool(Size)
Definition: mntmgr.h:153
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#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 }
PWSTR DatabasePath
Definition: database.c:31
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4155
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define NULL
Definition: types.h:112
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
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
static const WCHAR SymbolicLink[]
Definition: interface.c:31

Referenced by MountMgrMountedDeviceArrival().

◆ DeleteNoDriveLetterEntry()

VOID DeleteNoDriveLetterEntry ( IN PMOUNTDEV_UNIQUE_ID  UniqueId)

Definition at line 2100 of file database.c.

2101 {
2103 
2106 
2108  DatabasePath,
2109  QueryTable,
2110  UniqueId,
2111  NULL);
2112 }
PWSTR DatabasePath
Definition: database.c:31
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4155
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
NTSTATUS NTAPI DeleteNoDriveLetterEntryRoutine(IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
Definition: database.c:2067
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define NULL
Definition: types.h:112
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by MountMgrCreatePointWorker(), and MountMgrDeletePoints().

◆ DeleteRegistryDriveLetter()

VOID DeleteRegistryDriveLetter ( IN PMOUNTDEV_UNIQUE_ID  UniqueId)

Definition at line 2048 of file database.c.

2049 {
2051 
2054 
2056  DatabasePath,
2057  QueryTable,
2058  UniqueId,
2059  NULL);
2060 }
PWSTR DatabasePath
Definition: database.c:31
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4155
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define NULL
Definition: types.h:112
NTSTATUS NTAPI DeleteDriveLetterRoutine(IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
Definition: database.c:2001
#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:290
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
Status
Definition: gdiplustypes.h:24
LONG GetRemoteDatabaseSize(IN HANDLE Database)
Definition: database.c:40
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Definition: mntmgr.h:85
NTSTATUS TruncateRemoteDatabase(IN HANDLE Database, IN LONG NewSize)
Definition: database.c:91
#define AllocatePool(Size)
Definition: mntmgr.h:153
PDATABASE_ENTRY GetRemoteDatabaseEntry(IN HANDLE Database, IN LONG StartingOffset)
Definition: database.c:125
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
base of all file and directory entries
Definition: entries.h:82
LONGLONG QuadPart
Definition: typedefs.h:114

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
#define FALSE
Definition: types.h:117
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY SymbolicLinksListHead
Definition: mntmgr.h:45
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
Definition: typedefs.h:119
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 636 of file mountmgr.c.

640 {
642  PLIST_ENTRY NextEntry;
645 
646  /* If a device name was given, use it */
647  if (DeviceNameGiven)
648  {
649  DeviceName.Length = SymbolicName->Length;
650  DeviceName.Buffer = SymbolicName->Buffer;
651  }
652  else
653  {
654  /* Otherwise, query it */
656  &DeviceName,
657  NULL, NULL,
658  NULL, NULL,
659  NULL, NULL);
660  if (!NT_SUCCESS(Status))
661  {
662  return Status;
663  }
664  }
665 
666  /* Look for device information matching devive */
667  for (NextEntry = DeviceExtension->DeviceListHead.Flink;
668  NextEntry != &(DeviceExtension->DeviceListHead);
669  NextEntry = NextEntry->Flink)
670  {
671  DeviceInfo = CONTAINING_RECORD(NextEntry,
673  DeviceListEntry);
674 
675  if (RtlEqualUnicodeString(&DeviceName, &(DeviceInfo->DeviceName), TRUE))
676  {
677  break;
678  }
679  }
680 
681  /* Release our buffer if required */
682  if (!DeviceNameGiven)
683  {
684  FreePool(DeviceName.Buffer);
685  }
686 
687  /* Return found information */
688  if (NextEntry == &(DeviceExtension->DeviceListHead))
689  {
691  }
692 
693  *DeviceInformation = DeviceInfo;
694  return STATUS_SUCCESS;
695 }
#define TRUE
Definition: types.h:120
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
LONG NTSTATUS
Definition: precomp.h:26
#define FreePool(P)
Definition: mntmgr.h:154
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3272
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _DeviceInfo DeviceInfo
Definition: typedefs.h:119
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define NULL
Definition: types.h:112
NTSTATUS QueryDeviceInformation(IN PUNICODE_STRING SymbolicName, OUT PUNICODE_STRING DeviceName OPTIONAL, OUT PMOUNTDEV_UNIQUE_ID *UniqueId OPTIONAL, OUT PBOOLEAN Removable OPTIONAL, OUT PBOOLEAN GptDriveLetter OPTIONAL, OUT PBOOLEAN HasGuid OPTIONAL, IN OUT LPGUID StableGuid OPTIONAL, OUT PBOOLEAN Valid OPTIONAL)
Definition: mountmgr.c:190
#define STATUS_SUCCESS
Definition: shellext.h:65
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)

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

◆ 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:290
struct _Entry Entry
Definition: kefuncs.h:627
LONG NTSTATUS
Definition: precomp.h:26
_In_ UCHAR EntrySize
Definition: iofuncs.h:642
#define FreePool(P)
Definition: mntmgr.h:154
long LONG
Definition: pedump.c:60
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Definition: mntmgr.h:85
NTSTATUS TruncateRemoteDatabase(IN HANDLE Database, IN LONG NewSize)
Definition: database.c:91
#define AllocatePool(Size)
Definition: mntmgr.h:153
T MAX(T a, T b)
Definition: polytest.cpp:85
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
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:725

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
#define FreePool(P)
Definition: mntmgr.h:154
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3272
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_Out_ PUNICODE_STRING DosName
Definition: rtlfuncs.h:1269

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
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_Out_ PUNICODE_STRING DosName
Definition: rtlfuncs.h:1269

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

◆ HasDriveLetter()

BOOLEAN HasDriveLetter ( IN PDEVICE_INFORMATION  DeviceInformation)

Definition at line 83 of file mountmgr.c.

84 {
85  PLIST_ENTRY NextEntry;
86  PSYMLINK_INFORMATION SymlinkInfo;
87 
88  /* Browse all the symlinks to check if there is at least a drive letter */
89  for (NextEntry = DeviceInformation->SymbolicLinksListHead.Flink;
90  NextEntry != &DeviceInformation->SymbolicLinksListHead;
91  NextEntry = NextEntry->Flink)
92  {
93  SymlinkInfo = CONTAINING_RECORD(NextEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
94 
95  if (IsDriveLetter(&SymlinkInfo->Name) && SymlinkInfo->Online)
96  {
97  return TRUE;
98  }
99  }
100 
101  return FALSE;
102 }
#define TRUE
Definition: types.h:120
BOOLEAN IsDriveLetter(PUNICODE_STRING SymbolicName)
Definition: symlink.c:922
#define FALSE
Definition: types.h:117
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: typedefs.h:119

Referenced by MountMgrCreatePointWorker(), and ProcessSuggestedDriveLetters().

◆ 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 }
PWSTR DatabasePath
Definition: database.c:31
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4155
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
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
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define NULL
Definition: types.h:112
#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
#define FALSE
Definition: types.h:117
__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 660 of file notify.c.

663 {
665  PVOID IrpBuffer = NULL;
669 
670  /* Get the associated device object */
673  &FileObject,
674  &DeviceObject);
675  if (!NT_SUCCESS(Status))
676  {
677  return;
678  }
679 
680  /* And then, get attached device */
682 
684 
685  /* Allocate a work item */
687  if (!WorkItem)
688  {
690  return;
691  }
692 
693  WorkItem->Event = NULL;
694  WorkItem->WorkItem = IoAllocateWorkItem(DeviceExtension->DeviceObject);
695  if (!WorkItem->WorkItem)
696  {
698  goto Cleanup;
699  }
700 
701  WorkItem->DeviceExtension = DeviceExtension;
702  WorkItem->StackSize = DeviceObject->StackSize;
703  /* Already provide the IRP */
704  WorkItem->Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
705 
707 
708  if (!WorkItem->Irp)
709  {
710  goto Cleanup;
711  }
712 
713  /* Ensure it has enough space */
714  IrpBuffer = AllocatePool(sizeof(MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT) + 1024);
715  if (!IrpBuffer)
716  {
717  goto Cleanup;
718  }
719 
720  WorkItem->DeviceName.Length = DeviceName->Length;
721  WorkItem->DeviceName.MaximumLength = DeviceName->Length + sizeof(WCHAR);
722  WorkItem->DeviceName.Buffer = AllocatePool(WorkItem->DeviceName.MaximumLength);
723  if (!WorkItem->DeviceName.Buffer)
724  {
725  goto Cleanup;
726  }
727 
728  RtlCopyMemory(WorkItem->DeviceName.Buffer, DeviceName->Buffer, DeviceName->Length);
729  WorkItem->DeviceName.Buffer[DeviceName->Length / sizeof(WCHAR)] = UNICODE_NULL;
730 
731  WorkItem->IrpBuffer = IrpBuffer;
732  WorkItem->IrpBufferLength = sizeof(MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT) + 1024;
733 
734  /* Add the worker in the list */
735  KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
736  InsertHeadList(&(DeviceExtension->UniqueIdWorkerItemListHead), &(WorkItem->UniqueIdWorkerItemListEntry));
737  KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
738 
739  /* And call the worker */
741 
742  return;
743 
744 Cleanup:
745  if (IrpBuffer)
746  {
747  FreePool(IrpBuffer);
748  }
749 
750  if (WorkItem->Irp)
751  {
752  IoFreeIrp(WorkItem->Irp);
753  }
754 
755  if (WorkItem->WorkItem)
756  {
757  IoFreeWorkItem(WorkItem->WorkItem);
758  }
759 
760  if (WorkItem)
761  {
763  }
764 }
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
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
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3272
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
struct _MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT
Status
Definition: gdiplustypes.h:24
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ObDereferenceObject
Definition: obfuncs.h:203
VOID IssueUniqueIdChangeNotifyWorker(IN PUNIQUE_ID_WORK_ITEM WorkItem, IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: notify.c:590
* PFILE_OBJECT
Definition: iotypes.h:1998
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
static const WCHAR Cleanup[]
Definition: register.c:80
#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 NULL
Definition: types.h:112
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
_Must_inspect_result_ _In_ PWDF_WORKITEM_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWORKITEM * WorkItem
Definition: wdfworkitem.h:110

Referenced by MountMgrMountedDeviceArrival().

◆ IssueUniqueIdChangeNotifyWorker()

VOID IssueUniqueIdChangeNotifyWorker ( IN PUNIQUE_ID_WORK_ITEM  WorkItem,
IN PMOUNTDEV_UNIQUE_ID  UniqueId 
)

Definition at line 590 of file notify.c.

592 {
593  PIRP Irp;
598 
599  /* Get the device object */
600  Status = IoGetDeviceObjectPointer(&(WorkItem->DeviceName),
602  &FileObject,
603  &DeviceObject);
604  if (!NT_SUCCESS(Status))
605  {
607  return;
608  }
609 
610  /* And then, the attached device */
612 
613  /* Initialize the IRP */
614  Irp = WorkItem->Irp;
615  IoInitializeIrp(Irp, IoSizeOfIrp(WorkItem->StackSize), (CCHAR)WorkItem->StackSize);
616 
617  if (InterlockedExchange((PLONG)&(WorkItem->Event), 0) != 0)
618  {
622  return;
623  }
624 
625  Irp->AssociatedIrp.SystemBuffer = WorkItem->IrpBuffer;
626  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
627  RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, UniqueId, UniqueId->UniqueIdLength + sizeof(USHORT));
628 
630 
631  Stack->Parameters.DeviceIoControl.InputBufferLength = UniqueId->UniqueIdLength + sizeof(USHORT);
632  Stack->Parameters.DeviceIoControl.OutputBufferLength = WorkItem->IrpBufferLength;
633  Stack->Parameters.DeviceIoControl.Type3InputBuffer = 0;
634  Stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY;
635  Stack->MajorFunction = IRP_MJ_DEVICE_CONTROL;
636 
637  Status = IoSetCompletionRoutineEx(WorkItem->DeviceExtension->DeviceObject,
638  Irp,
640  WorkItem,
641  TRUE, TRUE, TRUE);
642  if (!NT_SUCCESS(Status))
643  {
647  return;
648  }
649 
650  /* Call the driver */
654 }
#define IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY
Definition: imports.h:86
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define TRUE
Definition: types.h:120
NTSTATUS NTAPI UniqueIdChangeNotifyCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: notify.c:568
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 IoInitializeIrp(IN PIRP Irp, IN USHORT PacketSize, IN CCHAR StackSize)
Definition: irp.c:1854
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:636
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ PIRP Irp
Definition: csq.h:116
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
Status
Definition: gdiplustypes.h:24
VOID RemoveWorkItem(IN PUNIQUE_ID_WORK_ITEM WorkItem)
Definition: notify.c:480
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
char CCHAR
Definition: typedefs.h:51
#define ObDereferenceObject
Definition: obfuncs.h:203
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:1998
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define InterlockedExchange
Definition: armddk.h:54
unsigned short USHORT
Definition: pedump.c:61
#define IoSizeOfIrp(_StackSize)
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_Must_inspect_result_ _In_ PWDF_WORKITEM_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWORKITEM * WorkItem
Definition: wdfworkitem.h:110
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:65
#define FALSE
Definition: types.h:117
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: typedefs.h:119
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 1676 of file mountmgr.c.

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

Referenced by MountMgrChangeNotify(), and MountMgrCleanup().

◆ 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 */
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  {
199  PostOnlineNotification(DeviceExtension, &DeviceInformation->SymbolicName);
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);
222  MountMgrNotify(DeviceExtension);
223 
224  if (!DeviceInformation->ManuallyRegistered)
225  {
226  MountMgrNotifyNameChange(DeviceExtension, DeviceName, FALSE);
227  }
228 
229  return Status;
230 }
PWSTR DatabasePath
Definition: database.c:31
#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 TRUE
Definition: types.h:120
#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
VOID DeleteRegistryDriveLetter(IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: database.c:2048
#define InsertTailList(ListHead, Entry)
#define FreePool(P)
Definition: mntmgr.h:154
UNICODE_STRING SymbolicName
Definition: mntmgr.h:48
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3272
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
VOID DeleteNoDriveLetterEntry(IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: database.c:2100
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG, PCWSTR, PCWSTR, ULONG, PVOID, ULONG)
#define MOUNTMGR_IS_VOLUME_NAME(s)
Definition: mountmgr.h:61
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:190
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
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:311
Definition: typedefs.h:119
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
BOOLEAN ManuallyRegistered
Definition: mntmgr.h:53
#define AllocatePool(Size)
Definition: mntmgr.h:153
VOID ReconcileThisDatabaseWithMaster(IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation)
Definition: database.c:1613
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
#define NULL
Definition: types.h:112
BOOLEAN HasDriveLetter(IN PDEVICE_INFORMATION DeviceInformation)
Definition: mountmgr.c:83
UNICODE_STRING DeviceName
Definition: mntmgr.h:50
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
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:351
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING SymbolicLinkName
Definition: wdfdevice.h:3736

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

◆ MountMgrFreeDeadDeviceInfo()

VOID MountMgrFreeDeadDeviceInfo ( IN PDEVICE_INFORMATION  DeviceInformation)

Definition at line 701 of file mountmgr.c.

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

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

◆ MountMgrMountedDeviceArrival()

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

Definition at line 931 of file mountmgr.c.

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

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

◆ MountMgrMountedDeviceRemoval()

VOID MountMgrMountedDeviceRemoval ( IN PDEVICE_EXTENSION  Extension,
IN PUNICODE_STRING  DeviceName 
)

Definition at line 1446 of file mountmgr.c.

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

Referenced by MountMgrMountedDeviceNotification().

◆ MountMgrNotify()

VOID MountMgrNotify ( IN PDEVICE_EXTENSION  DeviceExtension)

Definition at line 311 of file notify.c.

312 {
313  PIRP Irp;
314  KIRQL OldIrql;
315  LIST_ENTRY CopyList;
316  PLIST_ENTRY NextEntry;
317 
318  /* Increase the epic number */
319  DeviceExtension->EpicNumber++;
320 
321  InitializeListHead(&CopyList);
322 
323  /* Copy all the pending IRPs for notification */
325  while (!IsListEmpty(&(DeviceExtension->IrpListHead)))
326  {
327  NextEntry = RemoveHeadList(&(DeviceExtension->IrpListHead));
328  Irp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
330  InsertTailList(&CopyList, &(Irp->Tail.Overlay.ListEntry));
331  }
333 
334  /* Then, notify them one by one */
335  while (!IsListEmpty(&CopyList))
336  {
337  NextEntry = RemoveHeadList(&CopyList);
338  Irp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
339 
340  *((PULONG)Irp->AssociatedIrp.SystemBuffer) = DeviceExtension->EpicNumber;
341  Irp->IoStatus.Information = sizeof(DeviceExtension->EpicNumber);
342 
344  }
345 }
VOID NTAPI IoAcquireCancelSpinLock(OUT PKIRQL Irql)
Definition: util.c:56
#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
_In_ PIRP Irp
Definition: csq.h:116
#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:119
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 NULL
Definition: types.h:112
#define IO_NO_INCREMENT
Definition: iotypes.h:598

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

◆ MountMgrNotifyNameChange()

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

Definition at line 351 of file notify.c.

354 {
355  PIRP Irp;
356  KEVENT Event;
358  PLIST_ENTRY NextEntry;
363  PDEVICE_RELATIONS DeviceRelations;
364  PDEVICE_INFORMATION DeviceInformation;
365  TARGET_DEVICE_CUSTOM_NOTIFICATION DeviceNotification;
366 
367  /* If we have to validate volume */
368  if (ValidateVolume)
369  {
370  /* Then, ensure we can find the device */
371  for (NextEntry = DeviceExtension->DeviceListHead.Flink;
372  NextEntry != &DeviceExtension->DeviceListHead;
373  NextEntry = NextEntry->Flink)
374  {
375  DeviceInformation = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
376  if (RtlCompareUnicodeString(DeviceName, &(DeviceInformation->DeviceName), TRUE) == 0)
377  {
378  break;
379  }
380  }
381 
382  /* No need to notify for a PnP device or if we didn't find the device */
383  if (NextEntry == &(DeviceExtension->DeviceListHead) ||
384  !DeviceInformation->ManuallyRegistered)
385  {
386  return;
387  }
388  }
389 
390  /* Then, get device object */
393  &FileObject,
394  &DeviceObject);
395  if (!NT_SUCCESS(Status))
396  {
397  return;
398  }
399 
401 
403 
404  /* Set up empty IRP (yes, yes!) */
406  DeviceObject,
407  NULL,
408  0,
409  NULL,
410  0,
411  FALSE,
412  &Event,
413  &IoStatusBlock);
414  if (!Irp)
415  {
418  return;
419  }
420 
422 
423  Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
424  Irp->IoStatus.Information = 0;
425 
426  /* Properly set it, we want to query device relations */
427  Stack->MajorFunction = IRP_MJ_PNP;
428  Stack->MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS;
429  Stack->Parameters.QueryDeviceRelations.Type = TargetDeviceRelation;
430  Stack->FileObject = FileObject;
431 
432  /* And call driver */
434  if (Status == STATUS_PENDING)
435  {
438  }
439 
442 
443  if (!NT_SUCCESS(Status))
444  {
445  return;
446  }
447 
448  /* Validate device return */
449  DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
450  if (DeviceRelations->Count < 1)
451  {
452  ExFreePool(DeviceRelations);
453  return;
454  }
455 
456  DeviceObject = DeviceRelations->Objects[0];
457  ExFreePool(DeviceRelations);
458 
459  /* Set up real notification */
460  DeviceNotification.Version = 1;
461  DeviceNotification.Size = sizeof(TARGET_DEVICE_CUSTOM_NOTIFICATION);
462  DeviceNotification.Event = GUID_IO_VOLUME_NAME_CHANGE;
463  DeviceNotification.FileObject = NULL;
464  DeviceNotification.NameBufferOffset = -1;
465 
466  /* And report */
468  &DeviceNotification,
469  NULL, NULL);
470 
472 
473  return;
474 }
return STATUS_NOT_SUPPORTED
struct _TARGET_DEVICE_CUSTOM_NOTIFICATION TARGET_DEVICE_CUSTOM_NOTIFICATION
#define TRUE
Definition: types.h:120
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2163
#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
if(dx==0 &&dy==0)
Definition: linetemp.h:174
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_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:636
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3272
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:467
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:547
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define ObDereferenceObject
Definition: obfuncs.h:203
* PFILE_OBJECT
Definition: iotypes.h:1998
#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:119
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
BOOLEAN ManuallyRegistered
Definition: mntmgr.h:53
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#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
struct _FILE_OBJECT * FileObject
Definition: iotypes.h:1012
NTSTATUS NTAPI IoReportTargetDeviceChangeAsynchronous(IN PDEVICE_OBJECT PhysicalDeviceObject, IN PVOID NotificationStructure, IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback OPTIONAL, IN PVOID Context OPTIONAL)
Definition: pnpreport.c:460
#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
Status
Definition: gdiplustypes.h:24
__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:135
#define NULL
Definition: types.h:112
#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()

BOOLEAN MountmgrReadNoAutoMount ( IN PUNICODE_STRING  RegistryPath)

Definition at line 898 of file mountmgr.c.

899 {
901  ULONG Result, Default = 0;
903 
905 
906  /* Simply read data from register */
908  QueryTable[0].Name = L"NoAutoMount";
912  QueryTable[0].DefaultLength = sizeof(ULONG);
913 
915  RegistryPath->Buffer,
916  QueryTable,
917  NULL,
918  NULL);
919  if (!NT_SUCCESS(Status))
920  {
921  return (Default != 0);
922  }
923 
924  return (Result != 0);
925 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4155
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const WCHAR L[]
Definition: oid.c:1250
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define REG_NONE
Definition: nt_native.h:1492
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144

Referenced by DriverEntry().

◆ 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 */
84  Status = WaitForRemoteDatabaseSemaphore(DeviceExtension);
85  KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
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  {
123  KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT,
124  1, FALSE);
125 
126  if (NT_SUCCESS(Status))
127  {
128  ReleaseRemoteDatabaseSemaphore(DeviceExtension);
129  }
130 
131  return;
132  }
133 
134  /* If lock failed, then, just update this database */
135  if (!NT_SUCCESS(Status))
136  {
137  ReconcileThisDatabaseWithMaster(DeviceExtension, DeviceInformation);
138  KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT,
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  {
147  KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT,
148  1, FALSE);
149  ReleaseRemoteDatabaseSemaphore(DeviceExtension);
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 
211  KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
212  ReleaseRemoteDatabaseSemaphore(DeviceExtension);
213 
214  return;
215 }
PWSTR DatabasePath
Definition: database.c:31
PMOUNTDEV_UNIQUE_ID UniqueId
Definition: mntmgr.h:82
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4155
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
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
VOID ReleaseRemoteDatabaseSemaphore(IN PDEVICE_EXTENSION DeviceExtension)
Definition: database.c:391
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
USHORT UniqueIdLength
Definition: imports.h:138
#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
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
VOID ChangeRemoteDatabaseUniqueId(IN PDEVICE_INFORMATION DeviceInformation, IN PMOUNTDEV_UNIQUE_ID OldUniqueId, IN PMOUNTDEV_UNIQUE_ID NewUniqueId)
Definition: database.c:1911
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
NTSTATUS WaitForRemoteDatabaseSemaphore(IN PDEVICE_EXTENSION DeviceExtension)
Definition: database.c:371
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Definition: typedefs.h:119
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define AllocatePool(Size)
Definition: mntmgr.h:153
VOID ReconcileThisDatabaseWithMaster(IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation)
Definition: database.c:1613
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
#define NULL
Definition: types.h:112
LIST_ENTRY ReplicatedUniqueIdsListHead
Definition: mntmgr.h:46
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
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 1837 of file database.c.

1839 {
1840  HANDLE Database;
1841  NTSTATUS Status;
1845  UNICODE_STRING DeviceRemoteDatabase;
1846 
1847  Database = 0;
1848 
1849  /* Get database name */
1850  DeviceRemoteDatabase.Length = 0;
1851  DeviceRemoteDatabase.MaximumLength = DeviceInformation->DeviceName.Length
1853  + sizeof(UNICODE_NULL);
1854  DeviceRemoteDatabase.Buffer = AllocatePool(DeviceRemoteDatabase.MaximumLength);
1855  if (!DeviceRemoteDatabase.Buffer)
1856  {
1857  return 0;
1858  }
1859 
1860  RtlAppendUnicodeStringToString(&DeviceRemoteDatabase, &DeviceInformation->DeviceName);
1861  RtlAppendUnicodeStringToString(&DeviceRemoteDatabase, &RemoteDatabase);
1862  DeviceRemoteDatabase.Buffer[DeviceRemoteDatabase.Length / sizeof(WCHAR)] = UNICODE_NULL;
1863 
1864  /* Open database */
1866  &DeviceRemoteDatabase,
1868  NULL,
1869  NULL);
1870 
1871  /* Disable hard errors */
1873 
1879  &IoStatusBlock,
1880  NULL,
1882  0,
1883  (!MigrateDatabase || DeviceInformation->Migrated == 0) ? FILE_OPEN_IF : FILE_OPEN,
1885  NULL,
1886  0,
1888  NULL,
1891  {
1892  DPRINT1("Attempt to exploit CVE-2015-1769. See CORE-10216\n");
1893  }
1894 
1895  /* If base it to be migrated and was opened successfully, go ahead */
1896  if (MigrateDatabase && NT_SUCCESS(Status))
1897  {
1898  CreateRemoteDatabase(DeviceInformation, &Database);
1899  }
1900 
1902  FreePool(DeviceRemoteDatabase.Buffer);
1903 
1904  return Database;
1905 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define FILE_WRITE_EA
Definition: nt_native.h:640
#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
#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:224
#define IO_STOP_ON_SYMLINK
Definition: iotypes.h:7353
UNICODE_STRING RemoteDatabase
Definition: database.c:34
#define FILE_SYNCHRONOUS_IO_ALERT
Definition: from_kernel.h:30
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
#define IO_NO_PARAMETER_CHECKING
Definition: iotypes.h:541
#define FILE_READ_DATA
Definition: nt_native.h:628
unsigned char BOOLEAN
#define FILE_WRITE_DATA
Definition: nt_native.h:631
Status
Definition: gdiplustypes.h:24
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
NTSTATUS CreateRemoteDatabase(IN PDEVICE_INFORMATION DeviceInformation, IN OUT PHANDLE Database)
Definition: database.c:1790
__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:137
BOOLEAN NTAPI IoSetThreadHardErrorMode(IN BOOLEAN HardErrorEnabled)
Definition: error.c:726
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define SYNCHRONIZE
Definition: nt_native.h:61
#define AllocatePool(Size)
Definition: mntmgr.h:153
#define FILE_OPEN
Definition: from_kernel.h:54
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#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
#define NULL
Definition: types.h:112
#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 */
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);
162  WorkItem->SymbolicName.Buffer = AllocatePool(WorkItem->SymbolicName.MaximumLength);
163  if (!WorkItem->SymbolicName.Buffer)
164  {
166  return;
167  }
168 
169  RtlCopyMemory(WorkItem->SymbolicName.Buffer, SymbolicName->Buffer, SymbolicName->Length);
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 }
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:723
_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
#define UNICODE_NULL
VOID NTAPI SendOnlineNotificationWorker(IN PVOID Parameter)
Definition: notify.c:96
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
__wchar_t WCHAR
Definition: xmlstorage.h:180
#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
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_Must_inspect_result_ _In_ PWDF_WORKITEM_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWORKITEM * WorkItem
Definition: wdfworkitem.h:110

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

198 {
199  PIRP Irp;
200  USHORT Size;
201  KEVENT Event;
202  BOOLEAN IsRemovable;
207  NTSTATUS Status, IntStatus;
211  STORAGE_DEVICE_NUMBER StorageDeviceNumber;
213 
214  /* Get device associated with the symbolic name */
217  &FileObject,
218  &DeviceObject);
219  if (!NT_SUCCESS(Status))
220  {
221  return Status;
222  }
223 
224  /* The associate FO can't have a file name */
225  if (FileObject->FileName.Length)
226  {
229  }
230 
231  /* Check if it's removable & return to the user (if asked to) */
232  IsRemovable = (FileObject->DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA);
233  if (Removable)
234  {
235  *Removable = IsRemovable;
236  }
237 
238  /* Get the attached device */
240 
241  /* If we've been asked for a GPT drive letter */
242  if (GptDriveLetter)
243  {
244  /* Consider it has one */
245  *GptDriveLetter = TRUE;
246 
247  if (!IsRemovable)
248  {
249  /* Query the GPT attributes */
252  DeviceObject,
253  NULL,
254  0,
255  &GptAttributes,
256  sizeof(GptAttributes),
257  FALSE,
258  &Event,
259  &IoStatusBlock);
260  if (!Irp)
261  {
265  }
266 
268  if (Status == STATUS_PENDING)
269  {
272  }
273 
274  /* In case of failure, don't fail, that's no vital */
275  if (!NT_SUCCESS(Status))
276  {
278  }
279  /* Check if it has a drive letter */
280  else if (GptAttributes.GptAttributes & GPT_BASIC_DATA_ATTRIBUTE_NO_DRIVE_LETTER)
281  {
282  *GptDriveLetter = FALSE;
283  }
284  }
285  }
286 
287  /* If caller wants to know if there's valid contents */
288  if (Valid)
289  {
290  /* Suppose it's not OK */
291  *Valid = FALSE;
292 
293  if (!IsRemovable)
294  {
295  /* Query partitions information */
298  DeviceObject,
299  NULL,
300  0,
301  &PartitionInfo,
302  sizeof(PartitionInfo),
303  FALSE,
304  &Event,
305  &IoStatusBlock);
306  if (!Irp)
307  {
311  }
312 
314  if (Status == STATUS_PENDING)
315  {
318  }
319 
320  /* Once again here, failure isn't major */
321  if (!NT_SUCCESS(Status))
322  {
324  }
325  /* Verify we know something in */
326  else if (PartitionInfo.PartitionStyle == PARTITION_STYLE_MBR &&
327  IsRecognizedPartition(PartitionInfo.Mbr.PartitionType))
328  {
329  *Valid = TRUE;
330  }
331 
332  /* It looks correct, ensure it is & query device number */
333  if (*Valid)
334  {
337  DeviceObject,
338  NULL,
339  0,
340  &StorageDeviceNumber,
341  sizeof(StorageDeviceNumber),
342  FALSE,
343  &Event,
344  &IoStatusBlock);
345  if (!Irp)
346  {
350  }
351 
353  if (Status == STATUS_PENDING)
354  {
357  }
358 
359  if (!NT_SUCCESS(Status))
360  {
362  }
363  else
364  {
365  *Valid = FALSE;
366  }
367  }
368  }
369  }
370 
371  /* If caller needs device name */
372  if (DeviceName)
373  {
374  /* Allocate a buffer just to request length */
375  Name = AllocatePool(sizeof(MOUNTDEV_NAME));
376  if (!Name)
377  {
381  }
382 
383  /* Query device name */
386  DeviceObject,
387  NULL,
388  0,
389  Name,
390  sizeof(MOUNTDEV_NAME),
391  FALSE,
392  &Event,
393  &IoStatusBlock);
394  if (!Irp)
395  {
396  FreePool(Name);
400  }
401 
403  Stack->FileObject = FileObject;
404 
406  if (Status == STATUS_PENDING)
407  {
410  }
411 
412  /* Now, we've got the correct length */
414  {
415  Size = Name->NameLength + sizeof(MOUNTDEV_NAME);
416 
417  FreePool(Name);
418 
419  /* Allocate proper size */
421  if (!Name)
422  {
426  }
427 
428  /* And query name (for real that time) */
431  DeviceObject,
432  NULL,
433  0,
434  Name,
435  Size,
436  FALSE,
437  &Event,
438  &IoStatusBlock);
439  if (!Irp)
440  {
441  FreePool(Name);
445  }
446 
448  Stack->FileObject = FileObject;
449 
451  if (Status == STATUS_PENDING)
452  {
455  }
456  }
457 
458  if (NT_SUCCESS(Status))
459  {
460  /* Copy back found name to the caller */
461  DeviceName->Length = Name->NameLength;
462  DeviceName->MaximumLength = Name->NameLength + sizeof(WCHAR);
463  DeviceName->Buffer = AllocatePool(DeviceName->MaximumLength);
464  if (!DeviceName->Buffer)
465  {
467  }
468  else
469  {
470  RtlCopyMemory(DeviceName->Buffer, Name->Name, Name->NameLength);
471  DeviceName->Buffer[Name->NameLength / sizeof(WCHAR)] = UNICODE_NULL;
472  }
473  }
474 
475  FreePool(Name);
476  }
477 
478  if (!NT_SUCCESS(Status))
479  {
482  return Status;
483  }
484 
485  /* If caller wants device unique ID */
486  if (UniqueId)
487  {
488  /* Prepare buffer to probe length */
490  if (!Id)
491  {
495  }
496 
497  /* Query unique ID length */
500  DeviceObject,
501  NULL,
502  0,
503  Id,
504  sizeof(MOUNTDEV_UNIQUE_ID),
505  FALSE,
506  &Event,
507  &IoStatusBlock);
508  if (!Irp)
509  {
510  FreePool(Id);
514  }
515 
517  Stack->FileObject = FileObject;
518 
520  if (Status == STATUS_PENDING)
521  {
524  }
525 
526  /* Retry with appropriate length */
528  {
529  Size = Id->UniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID);
530 
531  FreePool(Id);
532 
533  /* Allocate the correct buffer */
534  Id = AllocatePool(Size);
535  if (!Id)
536  {
540  }
541 
542  /* Query unique ID */
545  DeviceObject,
546  NULL,
547  0,
548  Id,
549  Size,
550  FALSE,
551  &Event,
552  &IoStatusBlock);
553  if (!Irp)
554  {
555  FreePool(Id);
559  }
560 
562  Stack->FileObject = FileObject;
563 
565  if (Status == STATUS_PENDING)
566  {
569  }
570  }
571 
572  /* Hands back unique ID */
573  if (NT_SUCCESS(Status))
574  {
575  *UniqueId = Id;
576  }
577  else
578  {
579  /* In case of failure, also free the rest */
580  FreePool(Id);
581  if (DeviceName->Length)
582  {
583  FreePool(DeviceName->Buffer);
584  }
585 
588 
589  return Status;
590  }
591  }
592 
593  /* If user wants to know about GUID */
594  if (HasGuid)
595  {
596  /* Query device stable GUID */
597