ReactOS  0.4.11-dev-433-g473ca91
mntmgr.h File Reference
#include <ntifs.h>
#include <mountdev.h>
#include <ntddvol.h>
#include <ntdddisk.h>
#include <wdmguid.h>
#include <ndk/psfuncs.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 INIT_SECTION   /* Done via alloc_text for MSC */
 
#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_INFORMATION
PDEVICE_INFORMATION
 
typedef struct _SYMLINK_INFORMATION SYMLINK_INFORMATION
 
typedef struct
_SYMLINK_INFORMATION
PSYMLINK_INFORMATION
 
typedef struct
_SAVED_LINK_INFORMATION 
SAVED_LINK_INFORMATION
 
typedef struct
_SAVED_LINK_INFORMATION
PSAVED_LINK_INFORMATION
 
typedef struct _UNIQUE_ID_REPLICATE UNIQUE_ID_REPLICATE
 
typedef struct
_UNIQUE_ID_REPLICATE
PUNIQUE_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_ENTRY
PASSOCIATED_DEVICE_ENTRY
 
typedef struct
_DEVICE_INFORMATION_ENTRY 
DEVICE_INFORMATION_ENTRY
 
typedef struct
_DEVICE_INFORMATION_ENTRY
PDEVICE_INFORMATION_ENTRY
 
typedef struct
_ONLINE_NOTIFICATION_WORK_ITEM 
ONLINE_NOTIFICATION_WORK_ITEM
 
typedef struct
_ONLINE_NOTIFICATION_WORK_ITEM
PONLINE_NOTIFICATION_WORK_ITEM
 
typedef struct
_RECONCILE_WORK_ITEM_CONTEXT 
RECONCILE_WORK_ITEM_CONTEXT
 
typedef struct
_RECONCILE_WORK_ITEM_CONTEXT
PRECONCILE_WORK_ITEM_CONTEXT
 
typedef struct _RECONCILE_WORK_ITEM RECONCILE_WORK_ITEM
 
typedef struct
_RECONCILE_WORK_ITEM
PRECONCILE_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_ITEM
PUNIQUE_ID_WORK_ITEM
 

Functions

VOID NTAPI MountMgrCancel (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS MountMgrMountedDeviceArrival (IN PDEVICE_EXTENSION Extension, IN PUNICODE_STRING SymbolicName, IN BOOLEAN FromVolume)
 
VOID MountMgrMountedDeviceRemoval (IN PDEVICE_EXTENSION Extension, IN PUNICODE_STRING DeviceName)
 
NTSTATUS FindDeviceInfo (IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName, IN BOOLEAN DeviceNameGiven, OUT PDEVICE_INFORMATION *DeviceInformation)
 
VOID MountMgrFreeDeadDeviceInfo (IN PDEVICE_INFORMATION DeviceInformation)
 
NTSTATUS QueryDeviceInformation (IN PUNICODE_STRING SymbolicName, OUT PUNICODE_STRING DeviceName OPTIONAL, OUT PMOUNTDEV_UNIQUE_ID *UniqueId OPTIONAL, OUT PBOOLEAN Removable OPTIONAL, OUT PBOOLEAN GptDriveLetter OPTIONAL, OUT PBOOLEAN HasGuid OPTIONAL, IN OUT LPGUID StableGuid OPTIONAL, OUT PBOOLEAN Valid OPTIONAL)
 
BOOLEAN HasDriveLetter (IN PDEVICE_INFORMATION DeviceInformation)
 
INIT_SECTION 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

#define COLON_POSITION   0xD

Definition at line 165 of file mntmgr.h.

Referenced by MountMgrNextDriveLetterWorker(), and ProcessSuggestedDriveLetters().

#define DRIVE_LETTER_LENGTH   0x1C

Definition at line 166 of file mntmgr.h.

Referenced by MountMgrNextDriveLetterWorker(), and ProcessSuggestedDriveLetters().

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

Definition at line 159 of file mntmgr.h.

Referenced by ChangeRemoteDatabaseUniqueId(), CreateNewDriveLetterName(), CreateNoDriveLetterEntry(), CreateRemoteDatabase(), CreateRemoteDatabaseWorker(), DeleteRemoteDatabaseEntry(), DeleteSymbolicLinkNameFromMemory(), FindDeviceInfo(), GetRemoteDatabaseEntry(), GlobalCreateSymbolicLink(), GlobalDeleteSymbolicLink(), IssueUniqueIdChangeNotify(), MountMgrAssignDriveLetters(), MountMgrCreatePointWorker(), MountMgrDeletePoints(), MountMgrDeletePointsDbOnly(), MountMgrFreeDeadDeviceInfo(), MountMgrFreeMountedDeviceInfo(), MountMgrFreeSavedLink(), MountMgrMountedDeviceArrival(), MountMgrMountedDeviceRemoval(), MountMgrNextDriveLetterWorker(), MountMgrQueryDosVolumePath(), MountMgrQueryDosVolumePaths(), MountMgrQueryPoints(), MountMgrQueryVolumePaths(), MountMgrUniqueIdChangeRoutine(), MountMgrUnload(), MountMgrValidateBackPointer(), MountMgrVolumeMountPointChanged(), MountMgrVolumeMountPointCreated(), MountMgrVolumeMountPointDeleted(), OnlineMountedVolumes(), OpenRemoteDatabase(), PostOnlineNotification(), QueryDeviceInformation(), QueryPointsFromMemory(), QueryPointsFromSymbolicLinkName(), QuerySuggestedLinkName(), QuerySymbolicLinkNamesFromStorage(), QueryVolumeName(), ReconcileThisDatabaseWithMaster(), ReconcileThisDatabaseWithMasterWorker(), RedirectSavedLink(), RemoveWorkItem(), SendLinkCreated(), SendLinkDeleted(), SendOnlineNotificationWorker(), UniqueIdChangeNotifyWorker(), UpdateReplicatedUniqueIds(), WorkerThread(), and WriteUniqueIdToMaster().

#define INIT_SECTION   /* Done via alloc_text for MSC */

Definition at line 15 of file mntmgr.h.

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

Definition at line 162 of file mntmgr.h.

Typedef Documentation

Function Documentation

NTSTATUS AddRemoteDatabaseEntry ( IN HANDLE  Database,
IN PDATABASE_ENTRY  Entry 
)

Definition at line 64 of file database.c.

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

66 {
69 
70  /* Get size to append data */
72 
73  return ZwWriteFile(Database, NULL, NULL, NULL,
74  &IoStatusBlock, Entry,
75  Entry->EntrySize, &Size, NULL);
76 }
smooth NULL
Definition: ftsmooth.c:416
UINTN Size
Definition: acefiex.h:555
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
base of all file and directory entries
Definition: entries.h:82
LONGLONG QuadPart
Definition: typedefs.h:112
LONG GetRemoteDatabaseSize(IN HANDLE Database)
Definition: database.c:40
VOID ChangeRemoteDatabaseUniqueId ( IN PDEVICE_INFORMATION  DeviceInformation,
IN PMOUNTDEV_UNIQUE_ID  OldUniqueId,
IN PMOUNTDEV_UNIQUE_ID  NewUniqueId 
)

Definition at line 1890 of file database.c.

Referenced by MountMgrUniqueIdChangeRoutine().

1893 {
1894  LONG Offset = 0;
1895  HANDLE Database;
1896  PDATABASE_ENTRY Entry, NewEntry;
1898 
1899  /* Open the remote database */
1900  Database = OpenRemoteDatabase(DeviceInformation, FALSE);
1901  if (!Database)
1902  {
1903  return;
1904  }
1905 
1906  /* Get all the entries */
1907  do
1908  {
1909  Entry = GetRemoteDatabaseEntry(Database, Offset);
1910  if (!Entry)
1911  {
1912  break;
1913  }
1914 
1915  /* Not the correct entry, skip it */
1916  if (Entry->UniqueIdLength != OldUniqueId->UniqueIdLength)
1917  {
1918  Offset += Entry->EntrySize;
1919  FreePool(Entry);
1920  continue;
1921  }
1922 
1923  /* Not the correct entry, skip it */
1924  if (RtlCompareMemory(OldUniqueId->UniqueId,
1925  (PVOID)((ULONG_PTR)Entry + Entry->UniqueIdOffset),
1926  Entry->UniqueIdLength) != Entry->UniqueIdLength)
1927  {
1928  Offset += Entry->EntrySize;
1929  FreePool(Entry);
1930  continue;
1931  }
1932 
1933  /* Here, we have the correct entry */
1934  NewEntry = AllocatePool(Entry->EntrySize + NewUniqueId->UniqueIdLength - OldUniqueId->UniqueIdLength);
1935  if (!NewEntry)
1936  {
1937  Offset += Entry->EntrySize;
1938  FreePool(Entry);
1939  continue;
1940  }
1941 
1942  /* Recreate the entry from the previous one */
1943  NewEntry->EntrySize = Entry->EntrySize + NewUniqueId->UniqueIdLength - OldUniqueId->UniqueIdLength;
1944  NewEntry->EntryReferences = Entry->EntryReferences;
1945  NewEntry->SymbolicNameOffset = sizeof(DATABASE_ENTRY);
1946  NewEntry->SymbolicNameLength = Entry->SymbolicNameLength;
1947  NewEntry->UniqueIdOffset = Entry->SymbolicNameLength + sizeof(DATABASE_ENTRY);
1948  NewEntry->UniqueIdLength = NewUniqueId->UniqueIdLength;
1949  RtlCopyMemory((PVOID)((ULONG_PTR)NewEntry + NewEntry->SymbolicNameOffset),
1950  (PVOID)((ULONG_PTR)Entry + Entry->SymbolicNameOffset),
1951  NewEntry->SymbolicNameLength);
1952  RtlCopyMemory((PVOID)((ULONG_PTR)NewEntry + NewEntry->UniqueIdOffset),
1953  NewUniqueId->UniqueId, NewEntry->UniqueIdLength);
1954 
1955  /* Delete old entry */
1956  Status = DeleteRemoteDatabaseEntry(Database, Offset);
1957  if (!NT_SUCCESS(Status))
1958  {
1959  FreePool(Entry);
1960  FreePool(NewEntry);
1961  break;
1962  }
1963 
1964  /* And replace with new one */
1965  Status = AddRemoteDatabaseEntry(Database, NewEntry);
1966  FreePool(Entry);
1967  FreePool(NewEntry);
1968  } while (NT_SUCCESS(Status));
1969 
1970  CloseRemoteDatabase(Database);
1971 
1972  return;
1973 }
DWORD *typedef PVOID
Definition: winlogon.h:61
USHORT UniqueIdOffset
Definition: mntmgr.h:96
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
NTSTATUS DeleteRemoteDatabaseEntry(IN HANDLE Database, IN LONG StartingOffset)
Definition: database.c:233
struct _Entry Entry
Definition: kefuncs.h:640
ULONG EntryReferences
Definition: mntmgr.h:93
ULONG EntrySize
Definition: mntmgr.h:92
USHORT SymbolicNameLength
Definition: mntmgr.h:95
#define FreePool(P)
Definition: mntmgr.h:159
uint32_t ULONG_PTR
Definition: typedefs.h:63
HANDLE OpenRemoteDatabase(IN PDEVICE_INFORMATION DeviceInformation, IN BOOLEAN MigrateDatabase)
Definition: database.c:1817
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
USHORT UniqueIdLength
Definition: mntmgr.h:97
NTSTATUS CloseRemoteDatabase(IN HANDLE Database)
Definition: database.c:82
struct _DATABASE_ENTRY DATABASE_ENTRY
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
USHORT SymbolicNameOffset
Definition: mntmgr.h:94
Definition: mntmgr.h:90
#define AllocatePool(Size)
Definition: mntmgr.h:158
Status
Definition: gdiplustypes.h:24
DWORD *typedef HANDLE
Definition: winlogon.h:61
PDATABASE_ENTRY GetRemoteDatabaseEntry(IN HANDLE Database, IN LONG StartingOffset)
Definition: database.c:125
NTSTATUS AddRemoteDatabaseEntry(IN HANDLE Database, IN PDATABASE_ENTRY Entry)
Definition: database.c:64
return STATUS_SUCCESS
Definition: btrfs.c:2710
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
NTSTATUS CloseRemoteDatabase ( IN HANDLE  Database)

Definition at line 82 of file database.c.

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

83 {
84  return ZwClose(Database);
85 }
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSTATUS CreateNewVolumeName ( OUT PUNICODE_STRING  VolumeName,
IN PGUID VolumeGuid  OPTIONAL 
)

Definition at line 464 of file symlink.c.

Referenced by MountMgrMountedDeviceArrival(), and QuerySymbolicLinkNamesFromStorage().

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

Definition at line 269 of file uniqueid.c.

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

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 */
285  if (!NT_SUCCESS(RtlStringFromGUID(&Guid, &GuidString)))
286  {
287  return;
288  }
289 
290  /* No letter entries must start with #, so allocate a proper string */
291  String = AllocatePool(GuidString.Length + 2 * sizeof(WCHAR));
292  if (!String)
293  {
294  ExFreePoolWithTag(GuidString.Buffer, 0);
295  return;
296  }
297 
298  /* Write the complete string */
299  String[0] = L'#';
300  RtlCopyMemory(String + 1, GuidString.Buffer, GuidString.Length);
301  String[GuidString.Length / sizeof(WCHAR)] = UNICODE_NULL;
302 
303  /* Don't need that one anymore */
304  ExFreePoolWithTag(GuidString.Buffer, 0);
305 
306  /* Write the entry */
308  DatabasePath,
309  String,
310  REG_BINARY,
311  UniqueId->UniqueId,
312  UniqueId->UniqueIdLength);
313 
314  FreePool(String);
315 
316  return;
317 }
static PWSTR GuidString
Definition: apphelp.c:91
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define REG_BINARY
Definition: nt_native.h:1496
__wchar_t WCHAR
Definition: xmlstorage.h:180
uint16_t * PWCHAR
Definition: typedefs.h:54
#define WCHAR
Definition: msvc.h:43
#define FreePool(P)
Definition: mntmgr.h:159
CHAR16 * String
Definition: acefiex.h:201
#define UNICODE_NULL
static GUID * Guid
Definition: apphelp.c:93
NTKERNELAPI NTSTATUS ExUuidCreate(OUT UUID *Uuid)
Definition: uuid.c:303
_Inout_ PRX_CONNECTION_ID UniqueId
Definition: mrx.h:224
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG, PCWSTR, PCWSTR, ULONG, PVOID, ULONG)
static const WCHAR L[]
Definition: oid.c:1087
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define AllocatePool(Size)
Definition: mntmgr.h:158
PWSTR DatabasePath
Definition: database.c:31
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
VOID DeleteFromLocalDatabase ( IN PUNICODE_STRING  SymbolicLink,
IN PMOUNTDEV_UNIQUE_ID  UniqueId 
)

Definition at line 351 of file database.c.

Referenced by MountMgrMountedDeviceArrival().

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

Definition at line 2079 of file database.c.

Referenced by MountMgrCreatePointWorker(), and MountMgrDeletePoints().

2080 {
2082 
2083  RtlZeroMemory(QueryTable, sizeof(QueryTable));
2085 
2087  DatabasePath,
2088  QueryTable,
2089  UniqueId,
2090  NULL);
2091 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:3988
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
smooth NULL
Definition: ftsmooth.c:416
_Inout_ PRX_CONNECTION_ID UniqueId
Definition: mrx.h:224
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
PWSTR DatabasePath
Definition: database.c:31
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
NTSTATUS NTAPI DeleteNoDriveLetterEntryRoutine(IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
Definition: database.c:2046
VOID DeleteRegistryDriveLetter ( IN PMOUNTDEV_UNIQUE_ID  UniqueId)

Definition at line 2027 of file database.c.

Referenced by MountMgrCreatePointWorker().

2028 {
2030 
2031  RtlZeroMemory(QueryTable, sizeof(QueryTable));
2032  QueryTable[0].QueryRoutine = DeleteDriveLetterRoutine;
2033 
2035  DatabasePath,
2036  QueryTable,
2037  UniqueId,
2038  NULL);
2039 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:3988
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
smooth NULL
Definition: ftsmooth.c:416
_Inout_ PRX_CONNECTION_ID UniqueId
Definition: mrx.h:224
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
PWSTR DatabasePath
Definition: database.c:31
NTSTATUS NTAPI DeleteDriveLetterRoutine(IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
Definition: database.c:1980
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
NTSTATUS DeleteRemoteDatabaseEntry ( IN HANDLE  Database,
IN LONG  StartingOffset 
)

Definition at line 233 of file database.c.

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

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 */
300  Status = TruncateRemoteDatabase(Database, StartingOffset + EndSize);
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 }
DWORD *typedef PVOID
Definition: winlogon.h:61
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:282
NTSTATUS TruncateRemoteDatabase(IN HANDLE Database, IN LONG NewSize)
Definition: database.c:91
struct _Entry Entry
Definition: kefuncs.h:640
ULONG EntrySize
Definition: mntmgr.h:92
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define FreePool(P)
Definition: mntmgr.h:159
smooth NULL
Definition: ftsmooth.c:416
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
Definition: mntmgr.h:90
#define AllocatePool(Size)
Definition: mntmgr.h:158
Status
Definition: gdiplustypes.h:24
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
PDATABASE_ENTRY GetRemoteDatabaseEntry(IN HANDLE Database, IN LONG StartingOffset)
Definition: database.c:125
unsigned int ULONG
Definition: retypes.h:1
LONGLONG QuadPart
Definition: typedefs.h:112
LONG GetRemoteDatabaseSize(IN HANDLE Database)
Definition: database.c:40
VOID DeleteSymbolicLinkNameFromMemory ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PUNICODE_STRING  SymbolicLink,
IN BOOLEAN  MarkOffline 
)

Definition at line 866 of file symlink.c.

Referenced by MountMgrDeletePoints(), and MountMgrDeletePointsDbOnly().

869 {
870  PLIST_ENTRY DeviceEntry, SymbolEntry;
871  PDEVICE_INFORMATION DeviceInformation;
872  PSYMLINK_INFORMATION SymlinkInformation;
873 
874  /* First of all, ensure we have devices */
875  if (IsListEmpty(&(DeviceExtension->DeviceListHead)))
876  {
877  return;
878  }
879 
880  /* Then, look for the symbolic name */
881  for (DeviceEntry = DeviceExtension->DeviceListHead.Flink;
882  DeviceEntry != &(DeviceExtension->DeviceListHead);
883  DeviceEntry = DeviceEntry->Flink)
884  {
885  DeviceInformation = CONTAINING_RECORD(DeviceEntry, DEVICE_INFORMATION, DeviceListEntry);
886 
887  for (SymbolEntry = DeviceInformation->SymbolicLinksListHead.Flink;
888  SymbolEntry != &(DeviceInformation->SymbolicLinksListHead);
889  SymbolEntry = SymbolEntry->Flink)
890  {
891  SymlinkInformation = CONTAINING_RECORD(SymbolEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
892 
893  /* One we have found it */
894  if (RtlCompareUnicodeString(SymbolicLink, &(SymlinkInformation->Name), TRUE) == 0)
895  {
896  /* Check if caller just want it to be offline */
897  if (MarkOffline)
898  {
899  SymlinkInformation->Online = FALSE;
900  }
901  else
902  {
903  /* If not, delete it & notify */
904  SendLinkDeleted(&(DeviceInformation->SymbolicName), SymbolicLink);
905  RemoveEntryList(&(SymlinkInformation->SymbolicLinksListEntry));
906 
907  FreePool(SymlinkInformation->Name.Buffer);
908  FreePool(SymlinkInformation);
909  }
910 
911  /* No need to go farther */
912  return;
913  }
914  }
915  }
916 
917  return;
918 }
#define TRUE
Definition: types.h:120
#define FreePool(P)
Definition: mntmgr.h:159
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
UNICODE_STRING SymbolicName
Definition: mntmgr.h:53
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define FALSE
Definition: types.h:117
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
LIST_ENTRY SymbolicLinksListHead
Definition: mntmgr.h:50
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
Definition: typedefs.h:117
static const WCHAR SymbolicLink[]
Definition: interface.c:31
NTSTATUS FindDeviceInfo ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PUNICODE_STRING  SymbolicName,
IN BOOLEAN  DeviceNameGiven,
OUT PDEVICE_INFORMATION DeviceInformation 
)

Definition at line 650 of file mountmgr.c.

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

654 {
656  PLIST_ENTRY NextEntry;
659 
660  /* If a device name was given, use it */
661  if (DeviceNameGiven)
662  {
663  DeviceName.Length = SymbolicName->Length;
664  DeviceName.Buffer = SymbolicName->Buffer;
665  }
666  else
667  {
668  /* Otherwise, query it */
670  &DeviceName,
671  NULL, NULL,
672  NULL, NULL,
673  NULL, NULL);
674  if (!NT_SUCCESS(Status))
675  {
676  return Status;
677  }
678  }
679 
680  /* Look for device information matching devive */
681  for (NextEntry = DeviceExtension->DeviceListHead.Flink;
682  NextEntry != &(DeviceExtension->DeviceListHead);
683  NextEntry = NextEntry->Flink)
684  {
685  DeviceInfo = CONTAINING_RECORD(NextEntry,
687  DeviceListEntry);
688 
689  if (RtlEqualUnicodeString(&DeviceName, &(DeviceInfo->DeviceName), TRUE))
690  {
691  break;
692  }
693  }
694 
695  /* Release our buffer if required */
696  if (!DeviceNameGiven)
697  {
698  FreePool(DeviceName.Buffer);
699  }
700 
701  /* Return found information */
702  if (NextEntry == &(DeviceExtension->DeviceListHead))
703  {
705  }
706 
707  *DeviceInformation = DeviceInfo;
708  return STATUS_SUCCESS;
709 }
#define TRUE
Definition: types.h:120
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4658
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define FreePool(P)
Definition: mntmgr.h:159
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
struct _DeviceInfo DeviceInfo
Definition: typedefs.h:117
Status
Definition: gdiplustypes.h:24
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
UNICODE_STRING DeviceName
Definition: mntmgr.h:55
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:204
return STATUS_SUCCESS
Definition: btrfs.c:2710
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
PDATABASE_ENTRY GetRemoteDatabaseEntry ( IN HANDLE  Database,
IN LONG  StartingOffset 
)

Definition at line 125 of file database.c.

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

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 */
158  Entry = AllocatePool(EntrySize);
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) ||
176  (IoStatusBlock.Information != EntrySize) ||
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 }
USHORT UniqueIdOffset
Definition: mntmgr.h:96
_In_ PFCB _In_ LONGLONG StartingOffset
Definition: cdprocs.h:282
NTSTATUS TruncateRemoteDatabase(IN HANDLE Database, IN LONG NewSize)
Definition: database.c:91
struct _Entry Entry
Definition: kefuncs.h:640
USHORT SymbolicNameLength
Definition: mntmgr.h:95
_In_ UCHAR EntrySize
Definition: iofuncs.h:640
#define FreePool(P)
Definition: mntmgr.h:159
long LONG
Definition: pedump.c:60
smooth NULL
Definition: ftsmooth.c:416
USHORT UniqueIdLength
Definition: mntmgr.h:97
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
USHORT SymbolicNameOffset
Definition: mntmgr.h:94
Definition: mntmgr.h:90
#define AllocatePool(Size)
Definition: mntmgr.h:158
Status
Definition: gdiplustypes.h:24
T MAX(T a, T b)
Definition: polytest.cpp:85
_In_ PLARGE_INTEGER ByteOffset
Definition: mrx.h:173
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned int ULONG
Definition: retypes.h:1
LONGLONG QuadPart
Definition: typedefs.h:112
NTSTATUS GlobalCreateSymbolicLink ( IN PUNICODE_STRING  DosName,
IN PUNICODE_STRING  DeviceName 
)

Definition at line 111 of file symlink.c.

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

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

Definition at line 138 of file symlink.c.

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

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

Definition at line 87 of file mountmgr.c.

Referenced by MountMgrCreatePointWorker(), and ProcessSuggestedDriveLetters().

88 {
89  PLIST_ENTRY NextEntry;
90  PSYMLINK_INFORMATION SymlinkInfo;
91 
92  /* To have a drive letter, a device must have symbolic links */
93  if (IsListEmpty(&(DeviceInformation->SymbolicLinksListHead)))
94  {
95  return FALSE;
96  }
97 
98  /* Browse all the links untill a drive letter is found */
99  NextEntry = &(DeviceInformation->SymbolicLinksListHead);
100  do
101  {
102  SymlinkInfo = CONTAINING_RECORD(NextEntry, SYMLINK_INFORMATION, SymbolicLinksListEntry);
103 
104  if (SymlinkInfo->Online)
105  {
106  if (IsDriveLetter(&(SymlinkInfo->Name)))
107  {
108  return TRUE;
109  }
110  }
111 
112  NextEntry = NextEntry->Flink;
113  } while (NextEntry != &(DeviceInformation->SymbolicLinksListHead));
114 
115  return FALSE;
116 }
#define TRUE
Definition: types.h:120
BOOLEAN IsDriveLetter(PUNICODE_STRING SymbolicName)
Definition: symlink.c:924
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#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:119
Definition: typedefs.h:117
BOOLEAN HasNoDriveLetterEntry ( IN PMOUNTDEV_UNIQUE_ID  UniqueId)

Definition at line 354 of file uniqueid.c.

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

355 {
356  BOOLEAN EntryPresent = FALSE;
358 
359  RtlZeroMemory(QueryTable, sizeof(QueryTable));
361  QueryTable[0].EntryContext = &EntryPresent;
362 
364  DatabasePath,
365  QueryTable,
366  UniqueId,
367  NULL);
368 
369  return EntryPresent;
370 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:3988
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
smooth NULL
Definition: ftsmooth.c:416
unsigned char BOOLEAN
_Inout_ PRX_CONNECTION_ID UniqueId
Definition: mrx.h:224
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
PWSTR DatabasePath
Definition: database.c:31
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
BOOLEAN IsDriveLetter ( PUNICODE_STRING  SymbolicName)

Definition at line 924 of file symlink.c.

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

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

Definition at line 658 of file notify.c.

Referenced by MountMgrMountedDeviceArrival().

661 {
663  PVOID IrpBuffer = NULL;
666  PUNIQUE_ID_WORK_ITEM WorkItem = NULL;
667 
668  /* Get the associated device object */
671  &FileObject,
672  &DeviceObject);
673  if (!NT_SUCCESS(Status))
674  {
675  return;
676  }
677 
678  /* And then, get attached device */
679  DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject);
680 
681  ObDereferenceObject(FileObject);
682 
683  /* Allocate a work item */
684  WorkItem = AllocatePool(sizeof(UNIQUE_ID_WORK_ITEM));
685  if (!WorkItem)
686  {
687  ObDereferenceObject(DeviceObject);
688  return;
689  }
690 
691  WorkItem->Event = NULL;
692  WorkItem->WorkItem = IoAllocateWorkItem(DeviceExtension->DeviceObject);
693  if (!WorkItem->WorkItem)
694  {
695  ObDereferenceObject(DeviceObject);
696  goto Cleanup;
697  }
698 
699  WorkItem->DeviceExtension = DeviceExtension;
700  WorkItem->StackSize = DeviceObject->StackSize;
701  /* Already provide the IRP */
702  WorkItem->Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
703 
704  ObDereferenceObject(DeviceObject);
705 
706  if (!WorkItem->Irp)
707  {
708  goto Cleanup;
709  }
710 
711  /* Ensure it has enough space */
712  IrpBuffer = AllocatePool(sizeof(MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT) + 1024);
713  if (!IrpBuffer)
714  {
715  goto Cleanup;
716  }
717 
718  WorkItem->DeviceName.Length = DeviceName->Length;
719  WorkItem->DeviceName.MaximumLength = DeviceName->Length + sizeof(WCHAR);
720  WorkItem->DeviceName.Buffer = AllocatePool(WorkItem->DeviceName.MaximumLength);
721  if (!WorkItem->DeviceName.Buffer)
722  {
723  goto Cleanup;
724  }
725 
726  RtlCopyMemory(WorkItem->DeviceName.Buffer, DeviceName->Buffer, DeviceName->Length);
727  WorkItem->DeviceName.Buffer[DeviceName->Length / sizeof(WCHAR)] = UNICODE_NULL;
728 
729  WorkItem->IrpBuffer = IrpBuffer;
730  WorkItem->IrpBufferLength = sizeof(MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT) + 1024;
731 
732  /* Add the worker in the list */
734  InsertHeadList(&(DeviceExtension->UniqueIdWorkerItemListHead), &(WorkItem->UniqueIdWorkerItemListEntry));
736 
737  /* And call the worker */
739 
740  return;
741 
742 Cleanup:
743  if (IrpBuffer)
744  {
745  FreePool(IrpBuffer);
746  }
747 
748  if (WorkItem->Irp)
749  {
750  IoFreeIrp(WorkItem->Irp);
751  }
752 
753  if (WorkItem->WorkItem)
754  {
755  IoFreeWorkItem(WorkItem->WorkItem);
756  }
757 
758  if (WorkItem)
759  {
760  FreePool(WorkItem);
761  }
762 }
DWORD *typedef PVOID
Definition: winlogon.h:61
UNICODE_STRING DeviceName
Definition: mntmgr.h:152
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
USHORT MaximumLength
Definition: env_spec_w32.h:370
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1243
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define WCHAR
Definition: msvc.h:43
PDEVICE_EXTENSION DeviceExtension
Definition: mntmgr.h:148
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
#define FreePool(P)
Definition: mntmgr.h:159
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
PIO_WORKITEM WorkItem
Definition: mntmgr.h:147
VOID IssueUniqueIdChangeNotifyWorker(IN PUNIQUE_ID_WORK_ITEM WorkItem, IN PMOUNTDEV_UNIQUE_ID UniqueId)
Definition: notify.c:588
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
ULONG IrpBufferLength
Definition: mntmgr.h:153
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1214
struct _MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT
LONG NTSTATUS
Definition: precomp.h:26
_Inout_ PRX_CONNECTION_ID UniqueId
Definition: mrx.h:224
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
* PFILE_OBJECT
Definition: iotypes.h:1954
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
LIST_ENTRY UniqueIdWorkerItemListEntry
Definition: mntmgr.h:146
static const WCHAR Cleanup[]
Definition: register.c:80
#define AllocatePool(Size)
Definition: mntmgr.h:158
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define IO_NO_INCREMENT
Definition: iotypes.h:565
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
VOID IssueUniqueIdChangeNotifyWorker ( IN PUNIQUE_ID_WORK_ITEM  WorkItem,
IN PMOUNTDEV_UNIQUE_ID  UniqueId 
)

Definition at line 588 of file notify.c.

Referenced by IssueUniqueIdChangeNotify(), and UniqueIdChangeNotifyWorker().

590 {
591  PIRP Irp;
594  PIO_STACK_LOCATION Stack;
596 
597  /* Get the device object */
598  Status = IoGetDeviceObjectPointer(&(WorkItem->DeviceName),
600  &FileObject,
601  &DeviceObject);
602  if (!NT_SUCCESS(Status))
603  {
604  RemoveWorkItem(WorkItem);
605  return;
606  }
607 
608  /* And then, the attached device */
609  DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject);
610 
611  /* Initialize the IRP */
612  Irp = WorkItem->Irp;
613  IoInitializeIrp(Irp, IoSizeOfIrp(WorkItem->StackSize), (CCHAR)WorkItem->StackSize);
614 
615  if (InterlockedExchange((PLONG)&(WorkItem->Event), 0) != 0)
616  {
617  ObDereferenceObject(FileObject);
618  ObDereferenceObject(DeviceObject);
619  RemoveWorkItem(WorkItem);
620  return;
621  }
622 
623  Irp->AssociatedIrp.SystemBuffer = WorkItem->IrpBuffer;
624  Irp->Tail.Overlay.Thread = PsGetCurrentThread();
625  RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, UniqueId, UniqueId->UniqueIdLength + sizeof(USHORT));
626 
627  Stack = IoGetNextIrpStackLocation(Irp);
628 
629  Stack->Parameters.DeviceIoControl.InputBufferLength = UniqueId->UniqueIdLength + sizeof(USHORT);
630  Stack->Parameters.DeviceIoControl.OutputBufferLength = WorkItem->IrpBufferLength;
631  Stack->Parameters.DeviceIoControl.Type3InputBuffer = 0;
632  Stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY;
634 
635  Status = IoSetCompletionRoutineEx(WorkItem->DeviceExtension->DeviceObject,
636  Irp,
638  WorkItem,
639  TRUE, TRUE, TRUE);
640  if (!NT_SUCCESS(Status))
641  {
642  ObDereferenceObject(FileObject);
643  ObDereferenceObject(DeviceObject);
644  RemoveWorkItem(WorkItem);
645  return;
646  }
647 
648  /* Call the driver */
649  IoCallDriver(DeviceObject, Irp);
650  ObDereferenceObject(FileObject);
651  ObDereferenceObject(DeviceObject);
652 }
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY
Definition: imports.h:86
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
_In_ PIRP Irp
Definition: csq.h:116
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1243
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
VOID NTAPI IoInitializeIrp(IN PIRP Irp, IN USHORT PacketSize, IN CCHAR StackSize)
Definition: irp.c:1854
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1214
LONG NTSTATUS
Definition: precomp.h:26
_Inout_ PRX_CONNECTION_ID UniqueId
Definition: mrx.h:224
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
char CCHAR
Definition: typedefs.h:50
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:1954
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
#define InterlockedExchange
Definition: armddk.h:54
NTSTATUS NTAPI UniqueIdChangeNotifyCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: notify.c:566
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
unsigned short USHORT
Definition: pedump.c:61
#define IoSizeOfIrp(_StackSize)
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
VOID RemoveWorkItem(IN PUNIQUE_ID_WORK_ITEM WorkItem)
Definition: notify.c:478
PVOID PIRP
Definition: usb.h:38
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
signed int * PLONG
Definition: retypes.h:5
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
BOOLEAN IsUniqueIdPresent ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PDATABASE_ENTRY  DatabaseEntry 
)

Definition at line 221 of file uniqueid.c.

Referenced by ReconcileThisDatabaseWithMasterWorker().

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 }
DWORD *typedef PVOID
Definition: winlogon.h:61
#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:63
#define FALSE
Definition: types.h:117
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
Definition: typedefs.h:117
PMOUNTDEV_UNIQUE_ID UniqueId
Definition: mntmgr.h:54
UCHAR UniqueId[1]
Definition: imports.h:139
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
VOID NTAPI MountMgrCancel ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 1690 of file mountmgr.c.

Referenced by MountMgrChangeNotify(), and MountMgrCleanup().

1692 {
1694 
1695  RemoveEntryList(&(Irp->Tail.Overlay.ListEntry));
1696 
1697  IoReleaseCancelSpinLock(Irp->CancelIrql);
1698 
1699  Irp->IoStatus.Information = 0;
1700  Irp->IoStatus.Status = STATUS_CANCELLED;
1702 }
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define IoCompleteRequest
Definition: irp.c:1240
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define IO_NO_INCREMENT
Definition: iotypes.h:565
NTSTATUS MountMgrCreatePointWorker ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PUNICODE_STRING  SymbolicLinkName,
IN PUNICODE_STRING  DeviceName 
)

Definition at line 35 of file point.c.

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

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

Definition at line 715 of file mountmgr.c.

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

716 {
717  FreePool(DeviceInformation->SymbolicName.Buffer);
718  FreePool(DeviceInformation);
719 }
#define FreePool(P)
Definition: mntmgr.h:159
NTSTATUS MountMgrMountedDeviceArrival ( IN PDEVICE_EXTENSION  Extension,
IN PUNICODE_STRING  SymbolicName,
IN BOOLEAN  FromVolume 
)

Definition at line 945 of file mountmgr.c.

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

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

Definition at line 1460 of file mountmgr.c.

Referenced by MountMgrMountedDeviceNotification(), and MountMgrTargetDeviceNotification().

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

Definition at line 311 of file notify.c.

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

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 */
324  IoAcquireCancelSpinLock(&OldIrql);
325  while (!IsListEmpty(&(DeviceExtension->IrpListHead)))
326  {
327  NextEntry = RemoveHeadList(&(DeviceExtension->IrpListHead));
328  Irp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
329  InsertTailList(&CopyList, &(Irp->Tail.Overlay.ListEntry));
330  }
331  IoReleaseCancelSpinLock(OldIrql);
332 
333  /* Then, notify them one by one */
334  while (!IsListEmpty(&CopyList))
335  {
336  NextEntry = RemoveHeadList(&CopyList);
337  Irp = CONTAINING_RECORD(NextEntry, IRP, Tail.Overlay.ListEntry);
338 
339  *((PULONG)Irp->AssociatedIrp.SystemBuffer) = DeviceExtension->EpicNumber;
340  Irp->IoStatus.Information = sizeof(DeviceExtension->EpicNumber);
341 
343  }
344 }
_In_ PIRP Irp
Definition: csq.h:116
VOID NTAPI IoAcquireCancelSpinLock(OUT PKIRQL Irql)
Definition: util.c:56
IRP
Definition: iotypes.h:2462
#define InsertTailList(ListHead, Entry)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
UCHAR KIRQL
Definition: env_spec_w32.h:591
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#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:803
Definition: typedefs.h:117
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
PVOID PIRP
Definition: usb.h:38
#define IO_NO_INCREMENT
Definition: iotypes.h:565
VOID MountMgrNotifyNameChange ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PUNICODE_STRING  DeviceName,
IN BOOLEAN  ValidateVolume 
)

Definition at line 350 of file notify.c.

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

353 {
354  PIRP Irp;
355  KEVENT Event;
357  PLIST_ENTRY NextEntry;
359  PIO_STACK_LOCATION Stack;
362  PDEVICE_RELATIONS DeviceRelations;
363  PDEVICE_INFORMATION DeviceInformation;
364  TARGET_DEVICE_CUSTOM_NOTIFICATION DeviceNotification;
365 
366  /* If we have to validate volume */
367  if (ValidateVolume)
368  {
369  /* Then, ensure we can find the device */
370  NextEntry = DeviceExtension->DeviceListHead.Flink;
371  while (NextEntry != &(DeviceExtension->DeviceListHead))
372  {
373  DeviceInformation = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry);
374  if (RtlCompareUnicodeString(DeviceName, &(DeviceInformation->DeviceName), TRUE) == 0)
375  {
376  break;
377  }
378  }
379 
380  /* No need to notify for a PnP device or if we didn't find the device */
381  if (NextEntry == &(DeviceExtension->DeviceListHead) ||
382  !DeviceInformation->ManuallyRegistered)
383  {
384  return;
385  }
386  }
387 
388  /* Then, get device object */
391  &FileObject,
392  &DeviceObject);
393  if (!NT_SUCCESS(Status))
394  {
395  return;
396  }
397 
398  DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject);
399 
401 
402  /* Set up empty IRP (yes, yes!) */
404  DeviceObject,
405  NULL,
406  0,
407  NULL,
408  0,
409  FALSE,
410  &Event,
411  &IoStatusBlock);
412  if (!Irp)
413  {
414  ObDereferenceObject(DeviceObject);
415  ObDereferenceObject(FileObject);
416  return;
417  }
418 
419  Stack = IoGetNextIrpStackLocation(Irp);
420 
421  Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
422  Irp->IoStatus.Information = 0;
423 
424  /* Properly set it, we want to query device relations */
425  Stack->MajorFunction = IRP_MJ_PNP;
427  Stack->Parameters.QueryDeviceRelations.Type = TargetDeviceRelation;
428  Stack->FileObject = FileObject;
429 
430  /* And call driver */
431  Status = IoCallDriver(DeviceObject, Irp);
432  if (Status == STATUS_PENDING)
433  {
435  Status = IoStatusBlock.Status;
436  }
437 
438  ObDereferenceObject(DeviceObject);
439  ObDereferenceObject(FileObject);
440 
441  if (!NT_SUCCESS(Status))
442  {
443  return;
444  }
445 
446  /* Validate device return */
447  DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information;
448  if (DeviceRelations->Count < 1)
449  {
450  ExFreePool(DeviceRelations);
451  return;
452  }
453 
454  DeviceObject = DeviceRelations->Objects[0];
455  ExFreePool(DeviceRelations);
456 
457  /* Set up real notification */
458  DeviceNotification.Version = 1;
459  DeviceNotification.Size = sizeof(TARGET_DEVICE_CUSTOM_NOTIFICATION);
460  DeviceNotification.Event = GUID_IO_VOLUME_NAME_CHANGE;
461  DeviceNotification.FileObject = NULL;
462  DeviceNotification.NameBufferOffset = -1;
463 
464  /* And report */
466  &DeviceNotification,
467  NULL, NULL);
468 
469  ObDereferenceObject(DeviceObject);
470 
471  return;
472 }
#define TRUE
Definition: types.h:120
struct _TARGET_DEVICE_CUSTOM_NOTIFICATION TARGET_DEVICE_CUSTOM_NOTIFICATION
_In_ PIRP Irp
Definition: csq.h:116
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2054
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1243
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
WCHAR DeviceName[]
Definition: adapter.cpp:21
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
ACPI_EFI_EVENT Event
Definition: acefiex.h:633
#define FALSE
Definition: types.h:117
struct _DEVICE_RELATIONS * PDEVICE_RELATIONS
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1214
LONG NTSTATUS
Definition: precomp.h:26
if(!(yy_init))
Definition: macro.lex.yy.c:717
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
#define STATUS_PENDING
Definition: ntstatus.h:82
* PFILE_OBJECT
Definition: iotypes.h:1954
#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:117
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
BOOLEAN ManuallyRegistered
Definition: mntmgr.h:58
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
PFILE_OBJECT FileObject
Definition: iotypes.h:2812
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IRP_MN_QUERY_DEVICE_RELATIONS
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
UNICODE_STRING DeviceName
Definition: mntmgr.h:55
PVOID PIRP
Definition: usb.h:38
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
struct _FILE_OBJECT * FileObject
Definition: iotypes.h:974
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
NTSTATUS NTAPI IoReportTargetDeviceChangeAsynchronous(IN PDEVICE_OBJECT PhysicalDeviceObject, IN PVOID NotificationStructure, IN PDEVICE_CHANGE_COMPLETE_CALLBACK Callback OPTIONAL, IN PVOID Context OPTIONAL)
Definition: pnpreport.c:520
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
NTSTATUS MountMgrQuerySymbolicLink ( IN PUNICODE_STRING  SymbolicName,
IN OUT PUNICODE_STRING  LinkTarget 
)

Definition at line 961 of file symlink.c.

Referenced by MountMgrVolumeMountPointCreated(), and MountMgrVolumeMountPointDeleted().

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

Definition at line 912 of file mountmgr.c.

Referenced by DriverEntry().

913 {
915  ULONG Result, Default = 0;
917 
918  RtlZeroMemory(QueryTable, sizeof(QueryTable));
919 
920  /* Simply read data from register */
921  QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
922  QueryTable[0].Name = L"NoAutoMount";
923  QueryTable[0].EntryContext = &Result;
924  QueryTable[0].DefaultType = REG_NONE;
925  QueryTable[0].DefaultData = &Default;
926  QueryTable[0].DefaultLength = sizeof(ULONG);
927 
930  QueryTable,
931  NULL,
932  NULL);
933  if (!NT_SUCCESS(Status))
934  {
935  return (Default != 0);
936  }
937 
938  return (Result != 0);
939 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:3988
_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
smooth NULL
Definition: ftsmooth.c:416
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
static const WCHAR L[]
Definition: oid.c:1087
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
Status
Definition: gdiplustypes.h:24
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
#define REG_NONE
Definition: nt_native.h:1492
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
VOID MountMgrUniqueIdChangeRoutine ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PMOUNTDEV_UNIQUE_ID  OldUniqueId,
IN PMOUNTDEV_UNIQUE_ID  NewUniqueId 
)

Definition at line 71 of file uniqueid.c.

Referenced by UniqueIdChangeNotifyWorker().

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

Definition at line 1817 of file database.c.

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

1819 {
1820  HANDLE Database;
1821  NTSTATUS Status;
1825  UNICODE_STRING DeviceRemoteDatabase;
1826 
1827  Database = 0;
1828 
1829  /* Get database name */
1830  DeviceRemoteDatabase.Length = DeviceInformation->DeviceName.Length + RemoteDatabase.Length;
1831  DeviceRemoteDatabase.MaximumLength = DeviceRemoteDatabase.Length + sizeof(WCHAR);
1832  DeviceRemoteDatabase.Buffer = AllocatePool(DeviceRemoteDatabase.MaximumLength);
1833  if (!DeviceRemoteDatabase.Buffer)
1834  {
1835  return 0;
1836  }
1837 
1838  RtlCopyMemory(DeviceRemoteDatabase.Buffer, DeviceInformation->DeviceName.Buffer, DeviceInformation->DeviceName.Length);
1839  RtlCopyMemory(DeviceRemoteDatabase.Buffer + (DeviceInformation->DeviceName.Length / sizeof(WCHAR)),
1841  DeviceRemoteDatabase.Buffer[DeviceRemoteDatabase.Length / sizeof(WCHAR)] = UNICODE_NULL;
1842 
1843  /* Open database */
1844  InitializeObjectAttributes(&ObjectAttributes,
1845  &DeviceRemoteDatabase,
1847  NULL,
1848  NULL);
1849 
1850  /* Disable hard errors */
1851  PreviousMode = IoSetThreadHardErrorMode(FALSE);
1852 
1853  Status = IoCreateFile(&Database,
1857  &ObjectAttributes,
1858  &IoStatusBlock,
1859  NULL,
1861  0,
1862  (!MigrateDatabase || DeviceInformation->Migrated == 0) ? FILE_OPEN_IF : FILE_OPEN,
1864  NULL,
1865  0,
1867  NULL,
1869  if (Status == STATUS_STOPPED_ON_SYMLINK)
1870  {
1871  DPRINT1("Attempt to exploit CVE-2015-1769. See CORE-10216\n");
1872  }
1873 
1874  /* If base it to be migrated and was opened successfully, go ahead */
1875  if (MigrateDatabase && NT_SUCCESS(Status))
1876  {
1877  CreateRemoteDatabase(DeviceInformation, &Database);
1878  }
1879 
1880  IoSetThreadHardErrorMode(PreviousMode);
1881  FreePool(DeviceRemoteDatabase.Buffer);
1882 
1883  return Database;
1884 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define FILE_WRITE_EA
Definition: nt_native.h:640
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define FILE_OPEN_IF
Definition: from_kernel.h:56
USHORT MaximumLength
Definition: env_spec_w32.h:370
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
UNICODE_STRING RemoteDatabase
Definition: database.c:34
#define FILE_APPEND_DATA
Definition: nt_native.h:634
#define WCHAR
Definition: msvc.h:43
#define FreePool(P)
Definition: mntmgr.h:159
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
#define STATUS_STOPPED_ON_SYMLINK
Definition: ntstatus.h:212
#define IO_STOP_ON_SYMLINK
Definition: iotypes.h:6996
#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:508
#define FILE_READ_DATA
Definition: nt_native.h:628
smooth NULL
Definition: ftsmooth.c:416
#define FILE_WRITE_DATA
Definition: nt_native.h:631
unsigned char BOOLEAN
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define READ_CONTROL
Definition: nt_native.h:58
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
BOOLEAN NTAPI IoSetThreadHardErrorMode(IN BOOLEAN HardErrorEnabled)
Definition: error.c:707
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define SYNCHRONIZE
Definition: nt_native.h:61
#define AllocatePool(Size)
Definition: mntmgr.h:158
Status
Definition: gdiplustypes.h:24
#define FILE_OPEN
Definition: from_kernel.h:54
DWORD *typedef HANDLE
Definition: winlogon.h:61
#define FILE_READ_EA
Definition: nt_native.h:638
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
NTSTATUS CreateRemoteDatabase(IN PDEVICE_INFORMATION DeviceInformation, IN OUT PHANDLE Database)
Definition: database.c:1770
#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:3010
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
VOID PostOnlineNotification ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PUNICODE_STRING  SymbolicName 
)

Definition at line 145 of file notify.c.

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

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

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

212 {
213  PIRP Irp;
214  USHORT Size;
215  KEVENT Event;
217  BOOLEAN IsRemovable;
221  PIO_STACK_LOCATION Stack;
225  STORAGE_DEVICE_NUMBER StorageDeviceNumber;
227 
228  /* Get device associated with the symbolic name */
231  &FileObject,
232  &DeviceObject);
233  if (!NT_SUCCESS(Status))
234  {
235  return Status;
236  }
237 
238  /* The associate FO can't have a file name */
239  if (FileObject->FileName.Length)
240  {
241  ObDereferenceObject(FileObject);
243  }
244 
245  /* Check if it's removable & return to the user (if asked to) */
246  IsRemovable = (FileObject->DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA);
247  if (Removable)
248  {
249  *Removable = IsRemovable;
250  }
251 
252  /* Get the attached device */
253  DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject);
254 
255  /* If we've been asked for a GPT drive letter */
256  if (GptDriveLetter)
257  {
258  /* Consider it has one */
259  *GptDriveLetter = TRUE;
260 
261  if (!IsRemovable)
262  {
263  /* Query the GPT attributes */
266  DeviceObject,
267  NULL,
268  0,
269  &GptAttributes,
270  sizeof(GptAttributes),
271  FALSE,
272  &Event,
273  &IoStatusBlock);
274  if (!Irp)
275  {
276  ObDereferenceObject(DeviceObject);
277  ObDereferenceObject(FileObject);
279  }
280 
281  Status = IoCallDriver(DeviceObject, Irp);
282  if (Status == STATUS_PENDING)
283  {
285  Status = IoStatusBlock.Status;
286  }
287 
288  /* In case of failure, don't fail, that's no vital */
289  if (!NT_SUCCESS(Status))
290  {
291  Status = STATUS_SUCCESS;
292  }
293  /* Check if it has a drive letter */
294  else if (!(GptAttributes.GptAttributes &
295  GPT_BASIC_DATA_ATTRIBUTE_NO_DRIVE_LETTER))
296  {
297  *GptDriveLetter = FALSE;
298  }
299  }
300  }
301 
302  /* If caller wants to know if there's valid contents */
303  if (Valid)
304  {
305  /* Suppose it's not OK */
306  *Valid = FALSE;
307 
308  if (!IsRemovable)
309  {
310  /* Query partitions information */
313  DeviceObject,
314  NULL,
315  0,
316  &PartitionInfo,
317  sizeof(PartitionInfo),
318  FALSE,
319  &Event,
320  &IoStatusBlock);
321  if (!Irp)
322  {
323  ObDereferenceObject(DeviceObject);
324  ObDereferenceObject(FileObject);
326  }
327 
328  Status = IoCallDriver(DeviceObject, Irp);
329  if (Status == STATUS_PENDING)
330  {
332  Status = IoStatusBlock.Status;
333  }
334 
335  /* Once again here, failure isn't major */
336  if (!NT_SUCCESS(Status))
337  {
338  Status = STATUS_SUCCESS;
339  }
340  /* Verify we know something in */
341  else if (PartitionInfo.PartitionStyle == PARTITION_STYLE_MBR &&
342  IsRecognizedPartition(PartitionInfo.Mbr.PartitionType))
343  {
344  *Valid = TRUE;
345  }
346 
347  /* It looks correct, ensure it is & query device number */
348  if (*Valid)
349  {
352  DeviceObject,
353  NULL,
354  0,
355  &StorageDeviceNumber,
356  sizeof(StorageDeviceNumber),
357  FALSE,
358  &Event,
359  &IoStatusBlock);
360  if (!Irp)
361  {
362  ObDereferenceObject(DeviceObject);
363  ObDereferenceObject(FileObject);
365  }
366 
367  Status = IoCallDriver(DeviceObject, Irp);
368  if (Status == STATUS_PENDING)
369  {
371  Status = IoStatusBlock.Status;
372  }
373 
374  if (!NT_SUCCESS(Status))
375  {
376  Status = STATUS_SUCCESS;
377  }
378  else
379  {
380  *Valid = FALSE;
381  }
382  }
383  }
384  }
385 
386  /* If caller needs device name */
387  if (DeviceName)
388  {
389  /* Allocate a buffer just to request length */
390  Name = AllocatePool(sizeof(MOUNTDEV_NAME));
391  if (!Name)
392  {
393  ObDereferenceObject(DeviceObject);
394  ObDereferenceObject(FileObject);
396  }
397 
398  /* Query device name */
401  DeviceObject,
402  NULL,
403  0,
404  Name,
405  sizeof(MOUNTDEV_NAME),
406  FALSE,
407  &Event,
408  &IoStatusBlock);
409  if (!Irp)
410  {
411  FreePool(Name);
412  ObDereferenceObject(DeviceObject);
413  ObDereferenceObject(FileObject);
415  }
416 
417  Stack = IoGetNextIrpStackLocation(Irp);
418  Stack->FileObject = FileObject;
419 
420  Status = IoCallDriver(DeviceObject, Irp);
421  if (Status == STATUS_PENDING)
422  {
424  Status = IoStatusBlock.Status;
425  }
426 
427  /* Now, we've got the correct length */
428  if (Status == STATUS_BUFFER_OVERFLOW)
429  {
430  Size = Name->NameLength + sizeof(MOUNTDEV_NAME);
431 
432  FreePool(Name);
433 
434  /* Allocate proper size */
435  Name = AllocatePool(Size);
436  if (!Name)
437  {
438  ObDereferenceObject(DeviceObject);
439  ObDereferenceObject(FileObject);
441  }
442 
443  /* And query name (for real that time) */
446  DeviceObject,
447  NULL,
448  0,
449  Name,
450  Size,
451  FALSE,
452  &Event,
453  &IoStatusBlock);
454  if (!Irp)
455  {
456  FreePool(Name);
457  ObDereferenceObject(DeviceObject);
458  ObDereferenceObject(FileObject);
460  }
461 
462  Stack = IoGetNextIrpStackLocation(Irp);
463  Stack->FileObject = FileObject;
464 
465  Status = IoCallDriver(DeviceObject, Irp);
466  if (Status == STATUS_PENDING)
467  {
469  Status = IoStatusBlock.Status;
470  }
471  }
472 
473  /* Here we can't fail and assume default value */
474  if (!NT_SUCCESS(Status))
475  {
476  FreePool(Name);
477  ObDereferenceObject(DeviceObject);
478  ObDereferenceObject(FileObject);
479  return Status;
480  }
481 
482  /* Copy back found name to the caller */
483  DeviceName->Length = Name->NameLength;
484  DeviceName->MaximumLength = Name->NameLength + sizeof(WCHAR);
485  DeviceName->Buffer = AllocatePool(DeviceName->MaximumLength);
486  if (!DeviceName->Buffer)
487  {
488  FreePool(Name);
489  ObDereferenceObject(DeviceObject);
490  ObDereferenceObject(FileObject);
492  }
493 
494  RtlCopyMemory(DeviceName->Buffer, Name->Name, Name->NameLength);
495  DeviceName->Buffer[Name->NameLength / sizeof(WCHAR)] = UNICODE_NULL;
496  FreePool(Name);
497  }
498 
499  /* If caller wants device unique ID */
500  if (UniqueId)
501  {
502  /* Prepare buffer to probe length */
503  Id = AllocatePool(sizeof(MOUNTDEV_UNIQUE_ID));
504  if (!Id)
505  {
506  ObDereferenceObject(DeviceObject);
507  ObDereferenceObject(FileObject);
509  }
510 
511  /* Query unique ID length */
514  DeviceObject,
515  NULL,
516  0,
517  Id,
518  sizeof(MOUNTDEV_UNIQUE_ID),
519  FALSE,
520  &Event,
521  &IoStatusBlock);
522  if (!Irp)
523  {
524  FreePool(Id);
525  ObDereferenceObject(DeviceObject);
526  ObDereferenceObject(FileObject);
528  }
529 
530  Stack = IoGetNextIrpStackLocation(Irp);
531  Stack->FileObject = FileObject;
532 
533  Status = IoCallDriver(DeviceObject, Irp);
534  if (Status == STATUS_PENDING)
535  {
537  Status = IoStatusBlock.Status;
538  }
539 
540  /* Retry with appropriate length */
541  if (Status == STATUS_BUFFER_OVERFLOW)
542  {
543  Size = Id->UniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID);
544 
545  FreePool(Id);
546 
547  /* Allocate the correct buffer */
548  Id = AllocatePool(Size);
549  if (!Id)
550  {
551  ObDereferenceObject(DeviceObject);
552  ObDereferenceObject(FileObject);
554  }
555 
556  /* Query unique ID */
559  DeviceObject,
560  NULL,
561  0,
562  Id,
563  Size,
564  FALSE,
565  &Event,
566  &IoStatusBlock);
567  if (!Irp)
568  {
569  FreePool(Id);
570  ObDereferenceObject(DeviceObject);
571  ObDereferenceObject(FileObject);
573  }
574 
575  Stack = IoGetNextIrpStackLocation(Irp);
576  Stack->FileObject = FileObject;
577 
578  Status = IoCallDriver(DeviceObject, Irp);
579  if (Status == STATUS_PENDING)
580  {
582  Status = IoStatusBlock.Status;
583  }
584  }
585 
586  /* Hands back unique ID */
587  if (NT_SUCCESS(Status))
588  {
589  *UniqueId = Id;
590  }
591  else
592  {
593  /* In case of failure, also free the rest */
594  FreePool(Id);
595  if (DeviceName->Length)
596  {
597  FreePool(DeviceName->Buffer);
598  }
599 
600  ObDereferenceObject(DeviceObject);
601  ObDereferenceObject(FileObject);
602 
603  return Status;
604  }
605  }
606 
607  /* If user wants to know about GUID */
608  if (HasGuid)
609  {
610  /* Query device stable GUID */
613  DeviceObject,
614  NULL,
615  0,
616  StableGuid,
617  sizeof(GUID),
618  FALSE,
619  &Event,
620  &IoStatusBlock);
621  if (!Irp)
622  {
623  ObDereferenceObject(DeviceObject);
624  ObDereferenceObject(FileObject);
626  }
627 
628  Stack = IoGetNextIrpStackLocation(Irp);
629  Stack->FileObject = FileObject;
630 
631  Status = IoCallDriver(DeviceObject, Irp);
632  if (Status == STATUS_PENDING)
633  {
635  Status = IoStatusBlock.Status;
636  }
637 
638  *HasGuid = NT_SUCCESS(Status);
639  }