ReactOS  0.4.14-dev-358-gbef841c
database.c File Reference
#include "mntmgr.h"
#include <debug.h>
Include dependency graph for database.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

LONG GetRemoteDatabaseSize (IN HANDLE Database)
 
NTSTATUS AddRemoteDatabaseEntry (IN HANDLE Database, IN PDATABASE_ENTRY Entry)
 
NTSTATUS CloseRemoteDatabase (IN HANDLE Database)
 
NTSTATUS TruncateRemoteDatabase (IN HANDLE Database, IN LONG NewSize)
 
PDATABASE_ENTRY GetRemoteDatabaseEntry (IN HANDLE Database, IN LONG StartingOffset)
 
NTSTATUS WriteRemoteDatabaseEntry (IN HANDLE Database, IN LONG Offset, IN PDATABASE_ENTRY Entry)
 
NTSTATUS DeleteRemoteDatabaseEntry (IN HANDLE Database, IN LONG StartingOffset)
 
NTSTATUS NTAPI DeleteFromLocalDatabaseRoutine (IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
 
VOID DeleteFromLocalDatabase (IN PUNICODE_STRING SymbolicLink, IN PMOUNTDEV_UNIQUE_ID UniqueId)
 
NTSTATUS WaitForRemoteDatabaseSemaphore (IN PDEVICE_EXTENSION DeviceExtension)
 
VOID ReleaseRemoteDatabaseSemaphore (IN PDEVICE_EXTENSION DeviceExtension)
 
NTSTATUS NTAPI QueryUniqueIdQueryRoutine (IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
 
NTSTATUS QueryUniqueIdFromMaster (IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName, OUT PMOUNTDEV_UNIQUE_ID *UniqueId)
 
NTSTATUS WriteUniqueIdToMaster (IN PDEVICE_EXTENSION DeviceExtension, IN PDATABASE_ENTRY DatabaseEntry)
 
VOID NTAPI ReconcileThisDatabaseWithMasterWorker (IN PVOID Parameter)
 
VOID NTAPI WorkerThread (IN PDEVICE_OBJECT DeviceObject, IN PVOID Context)
 
NTSTATUS QueueWorkItem (IN PDEVICE_EXTENSION DeviceExtension, IN PRECONCILE_WORK_ITEM WorkItem, IN PVOID Context)
 
NTSTATUS QueryVolumeName (IN HANDLE RootDirectory, IN PFILE_REPARSE_POINT_INFORMATION ReparsePointInformation, IN PUNICODE_STRING FileName OPTIONAL, OUT PUNICODE_STRING SymbolicName, OUT PUNICODE_STRING VolumeName)
 
VOID OnlineMountedVolumes (IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation)
 
VOID ReconcileThisDatabaseWithMaster (IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation)
 
VOID ReconcileAllDatabasesWithMaster (IN PDEVICE_EXTENSION DeviceExtension)
 
VOID NTAPI CreateRemoteDatabaseWorker (IN PDEVICE_OBJECT DeviceObject, IN PVOID Context)
 
NTSTATUS CreateRemoteDatabase (IN PDEVICE_INFORMATION DeviceInformation, IN OUT PHANDLE Database)
 
HANDLE OpenRemoteDatabase (IN PDEVICE_INFORMATION DeviceInformation, IN BOOLEAN MigrateDatabase)
 
VOID ChangeRemoteDatabaseUniqueId (IN PDEVICE_INFORMATION DeviceInformation, IN PMOUNTDEV_UNIQUE_ID OldUniqueId, IN PMOUNTDEV_UNIQUE_ID NewUniqueId)
 
NTSTATUS NTAPI DeleteDriveLetterRoutine (IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
 
VOID DeleteRegistryDriveLetter (IN PMOUNTDEV_UNIQUE_ID UniqueId)
 
NTSTATUS NTAPI DeleteNoDriveLetterEntryRoutine (IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
 
VOID DeleteNoDriveLetterEntry (IN PMOUNTDEV_UNIQUE_ID UniqueId)
 

Variables

PWSTR DatabasePath = L"\\Registry\\Machine\\System\\MountedDevices"
 
PWSTR OfflinePath = L"\\Registry\\Machine\\System\\MountedDevices\\Offline"
 
UNICODE_STRING RemoteDatabase = RTL_CONSTANT_STRING(L"\\System Volume Information\\MountPointManagerRemoteDatabase")
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 28 of file database.c.

Function Documentation

◆ AddRemoteDatabaseEntry()

NTSTATUS AddRemoteDatabaseEntry ( IN HANDLE  Database,
IN PDATABASE_ENTRY  Entry 
)

Definition at line 64 of file database.c.

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

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

◆ ChangeRemoteDatabaseUniqueId()

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

Definition at line 1909 of file database.c.

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

Referenced by MountMgrUniqueIdChangeRoutine().

◆ CloseRemoteDatabase()

NTSTATUS CloseRemoteDatabase ( IN HANDLE  Database)

Definition at line 82 of file database.c.

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

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

◆ CreateRemoteDatabase()

NTSTATUS CreateRemoteDatabase ( IN PDEVICE_INFORMATION  DeviceInformation,
IN OUT PHANDLE  Database 
)

Definition at line 1789 of file database.c.

1791 {
1792  KEVENT Event;
1793  NTSTATUS Status;
1794  PMIGRATE_WORK_ITEM WorkItem;
1795 
1797 
1798  /* Allocate a work item dedicated to migration */
1799  WorkItem = AllocatePool(sizeof(MIGRATE_WORK_ITEM));
1800  if (!WorkItem)
1801  {
1802  *Database = 0;
1804  }
1805 
1806  RtlZeroMemory(WorkItem, sizeof(MIGRATE_WORK_ITEM));
1807  WorkItem->Event = &Event;
1808  WorkItem->DeviceInformation = DeviceInformation;
1809  WorkItem->WorkItem = IoAllocateWorkItem(DeviceInformation->DeviceExtension->DeviceObject);
1810  if (!WorkItem->WorkItem)
1811  {
1812  FreePool(WorkItem);
1813  *Database = 0;
1815  }
1816 
1817  /* And queue it */
1818  IoQueueWorkItem(WorkItem->WorkItem,
1821  WorkItem);
1822 
1824  Status = WorkItem->Status;
1825 
1826  *Database = (NT_SUCCESS(Status) ? WorkItem->Database : 0);
1827 
1828  FreePool(WorkItem);
1829  return Status;
1830 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONG NTSTATUS
Definition: precomp.h:26
PKEVENT Event
Definition: mntmgr.h:134
VOID NTAPI CreateRemoteDatabaseWorker(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context)
Definition: database.c:1685
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
#define FreePool(P)
Definition: mntmgr.h:154
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
HANDLE Database
Definition: mntmgr.h:136
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PDEVICE_INFORMATION DeviceInformation
Definition: mntmgr.h:133
PIO_WORKITEM WorkItem
Definition: mntmgr.h:132
NTSTATUS Status
Definition: mntmgr.h:135
#define AllocatePool(Size)
Definition: mntmgr.h:153
Status
Definition: gdiplustypes.h:24
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261

Referenced by OpenRemoteDatabase().

◆ CreateRemoteDatabaseWorker()

VOID NTAPI CreateRemoteDatabaseWorker ( IN PDEVICE_OBJECT  DeviceObject,
IN PVOID  Context 
)

Definition at line 1685 of file database.c.

1687 {
1688  NTSTATUS Status;
1689  HANDLE Database = 0;
1690  UNICODE_STRING DatabaseName;
1691  PMIGRATE_WORK_ITEM WorkItem;
1694  PDEVICE_INFORMATION DeviceInformation;
1695 
1697 
1698  /* Extract context */
1699  WorkItem = Context;
1700  DeviceInformation = WorkItem->DeviceInformation;
1701 
1702  /* Reconstruct appropriate string */
1703  DatabaseName.Length = DeviceInformation->DeviceName.Length + RemoteDatabase.Length;
1704  DatabaseName.MaximumLength = DatabaseName.Length + sizeof(WCHAR);
1705  DatabaseName.Buffer = AllocatePool(DatabaseName.MaximumLength);
1706  if (DatabaseName.Buffer == NULL)
1707  {
1709  goto Cleanup;
1710  }
1711 
1712  /* Create the required folder (in which the database will be stored
1713  * \System Volume Information at root of the volume
1714  */
1715  Status = RtlCreateSystemVolumeInformationFolder(&(DeviceInformation->DeviceName));
1716  if (!NT_SUCCESS(Status))
1717  {
1718  goto Cleanup;
1719  }
1720 
1721  /* Finish initiating strings */
1722  RtlCopyMemory(DatabaseName.Buffer, DeviceInformation->DeviceName.Buffer, DeviceInformation->DeviceName.Length);
1723  RtlCopyMemory(DatabaseName.Buffer + (DeviceInformation->DeviceName.Length / sizeof(WCHAR)),
1725  DatabaseName.Buffer[DatabaseName.Length / sizeof(WCHAR)] = UNICODE_NULL;
1726 
1727  /* Create database */
1729  &DatabaseName,
1731  NULL,
1732  NULL);
1733 
1739  &IoStatusBlock,
1740  NULL,
1742  0,
1743  FILE_CREATE,
1745  NULL,
1746  0,
1748  NULL,
1750  if (!NT_SUCCESS(Status))
1751  {
1753  {
1754  DPRINT1("Attempt to exploit CVE-2015-1769. See CORE-10216\n");
1755  }
1756 
1757  Database = 0;
1758  goto Cleanup;
1759  }
1760 
1761 Cleanup:
1762  if (DatabaseName.Buffer)
1763  {
1764  FreePool(DatabaseName.Buffer);
1765  }
1766 
1767  if (NT_SUCCESS(Status))
1768  {
1769  DeviceInformation->Migrated = 1;
1770  }
1771  else if (Database != 0)
1772  {
1773  ZwClose(Database);
1774  }
1775 
1776  IoFreeWorkItem(WorkItem->WorkItem);
1777 
1778  WorkItem->WorkItem = NULL;
1779  WorkItem->Status = Status;
1780  WorkItem->Database = Database;
1781 
1782  KeSetEvent(WorkItem->Event, 0, FALSE);
1783 }
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 STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
PKEVENT Event
Definition: mntmgr.h:134
#define FILE_CREATE
Definition: from_kernel.h:55
UNICODE_STRING RemoteDatabase
Definition: database.c:34
#define FILE_APPEND_DATA
Definition: nt_native.h:634
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
#define FreePool(P)
Definition: mntmgr.h:154
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
#define STATUS_STOPPED_ON_SYMLINK
Definition: ntstatus.h:212
#define IO_STOP_ON_SYMLINK
Definition: iotypes.h:6997
HANDLE Database
Definition: mntmgr.h:136
#define FILE_SYNCHRONOUS_IO_ALERT
Definition: from_kernel.h:30
#define UNICODE_NULL
#define IO_NO_PARAMETER_CHECKING
Definition: iotypes.h:509
#define FILE_READ_DATA
Definition: nt_native.h:628
smooth NULL
Definition: ftsmooth.c:416
#define FILE_WRITE_DATA
Definition: nt_native.h:631
NTSTATUS NTAPI RtlCreateSystemVolumeInformationFolder(IN PUNICODE_STRING VolumeRootPath)
Definition: sysvol.c:545
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PDEVICE_INFORMATION DeviceInformation
Definition: mntmgr.h:133
PIO_WORKITEM WorkItem
Definition: mntmgr.h:132
NTSTATUS Status
Definition: mntmgr.h:135
#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
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
static const WCHAR Cleanup[]
Definition: register.c:80
#define SYNCHRONIZE
Definition: nt_native.h:61
#define AllocatePool(Size)
Definition: mntmgr.h:153
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define FILE_READ_EA
Definition: nt_native.h:638
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define DPRINT1
Definition: precomp.h:8
UNICODE_STRING DeviceName
Definition: mntmgr.h:50
NTSTATUS NTAPI IoCreateFile(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG Disposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength, IN CREATE_FILE_TYPE CreateFileType, IN PVOID ExtraCreateParameters OPTIONAL, IN ULONG Options)
Definition: file.c:3009
struct tagContext Context
Definition: acpixf.h:1030
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231

Referenced by CreateRemoteDatabase().

◆ DeleteDriveLetterRoutine()

NTSTATUS NTAPI DeleteDriveLetterRoutine ( IN PWSTR  ValueName,
IN ULONG  ValueType,
IN PVOID  ValueData,
IN ULONG  ValueLength,
IN PVOID  Context,
IN PVOID  EntryContext 
)

Definition at line 1999 of file database.c.

2005 {
2006  PMOUNTDEV_UNIQUE_ID UniqueId;
2007  UNICODE_STRING RegistryEntry;
2008 
2010 
2011  if (ValueType != REG_BINARY)
2012  {
2013  return STATUS_SUCCESS;
2014  }
2015 
2016  UniqueId = Context;
2017 
2018  /* First ensure we have the correct data */
2019  if (UniqueId->UniqueIdLength != ValueLength)
2020  {
2021  return STATUS_SUCCESS;
2022  }
2023 
2025  {
2026  return STATUS_SUCCESS;
2027  }
2028 
2029  RtlInitUnicodeString(&RegistryEntry, ValueName);
2030 
2031  /* Then, it's a drive letter, erase it */
2032  if (IsDriveLetter(&RegistryEntry))
2033  {
2035  DatabasePath,
2036  ValueName);
2037  }
2038 
2039  return STATUS_SUCCESS;
2040 }
NTSYSAPI NTSTATUS WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR)
#define REG_BINARY
Definition: nt_native.h:1496
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
_In_ PCWSTR _In_z_ PCWSTR _In_ ULONG ValueType
Definition: rtlfuncs.h:4016
USHORT UniqueIdLength
Definition: imports.h:138
BOOLEAN IsDriveLetter(PUNICODE_STRING SymbolicName)
Definition: symlink.c:922
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4004
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:311
_In_ GUID _In_ PVOID _In_ ULONG ValueLength
Definition: hubbusif.h:311
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
PWSTR DatabasePath
Definition: database.c:31
struct tagContext Context
Definition: acpixf.h:1030
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
return STATUS_SUCCESS
Definition: btrfs.c:2938
UCHAR UniqueId[1]
Definition: imports.h:139
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465

Referenced by DeleteRegistryDriveLetter().

◆ DeleteFromLocalDatabase()

VOID DeleteFromLocalDatabase ( IN PUNICODE_STRING  SymbolicLink,
IN PMOUNTDEV_UNIQUE_ID  UniqueId 
)

Definition at line 351 of file database.c.

353 {
355 
358  QueryTable[0].Name = SymbolicLink->Buffer;
359 
361  DatabasePath,
362  QueryTable,
363  UniqueId,
364  NULL);
365 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4004
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
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

Referenced by MountMgrMountedDeviceArrival().

◆ DeleteFromLocalDatabaseRoutine()

NTSTATUS NTAPI DeleteFromLocalDatabaseRoutine ( IN PWSTR  ValueName,
IN ULONG  ValueType,
IN PVOID  ValueData,
IN ULONG  ValueLength,
IN PVOID  Context,
IN PVOID  EntryContext 
)

Definition at line 322 of file database.c.

328 {
329  PMOUNTDEV_UNIQUE_ID UniqueId = Context;
330 
333 
334  /* Ensure it matches, and delete */
335  if ((UniqueId->UniqueIdLength == ValueLength) &&
337  ValueLength))
338  {
340  DatabasePath,
341  ValueName);
342  }
343 
344  return STATUS_SUCCESS;
345 }
NTSYSAPI NTSTATUS WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
_In_ PCWSTR _In_z_ PCWSTR _In_ ULONG ValueType
Definition: rtlfuncs.h:4016
USHORT UniqueIdLength
Definition: imports.h:138
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4004
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:311
_In_ GUID _In_ PVOID _In_ ULONG ValueLength
Definition: hubbusif.h:311
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
PWSTR DatabasePath
Definition: database.c:31
struct tagContext Context
Definition: acpixf.h:1030
return STATUS_SUCCESS
Definition: btrfs.c:2938
UCHAR UniqueId[1]
Definition: imports.h:139
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465

Referenced by DeleteFromLocalDatabase().

◆ DeleteNoDriveLetterEntry()

VOID DeleteNoDriveLetterEntry ( IN PMOUNTDEV_UNIQUE_ID  UniqueId)

Definition at line 2098 of file database.c.

2099 {
2101 
2104 
2106  DatabasePath,
2107  QueryTable,
2108  UniqueId,
2109  NULL);
2110 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4004
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
smooth NULL
Definition: ftsmooth.c:416
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:2065

Referenced by MountMgrCreatePointWorker(), and MountMgrDeletePoints().

◆ DeleteNoDriveLetterEntryRoutine()

NTSTATUS NTAPI DeleteNoDriveLetterEntryRoutine ( IN PWSTR  ValueName,
IN ULONG  ValueType,
IN PVOID  ValueData,
IN ULONG  ValueLength,
IN PVOID  Context,
IN PVOID  EntryContext 
)

Definition at line 2065 of file database.c.

2071 {
2072  PMOUNTDEV_UNIQUE_ID UniqueId = Context;
2073 
2075 
2076  /* Ensure we have correct input */
2077  if (ValueName[0] != L'#' || ValueType != REG_BINARY ||
2078  UniqueId->UniqueIdLength != ValueLength)
2079  {
2080  return STATUS_SUCCESS;
2081  }
2082 
2083  /* And then, if unique ID matching, delete entry */
2085  {
2087  DatabasePath,
2088  ValueName);
2089  }
2090 
2091  return STATUS_SUCCESS;
2092 }
NTSYSAPI NTSTATUS WINAPI RtlDeleteRegistryValue(ULONG, PCWSTR, PCWSTR)
#define REG_BINARY
Definition: nt_native.h:1496
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
_In_ PCWSTR _In_z_ PCWSTR _In_ ULONG ValueType
Definition: rtlfuncs.h:4016
USHORT UniqueIdLength
Definition: imports.h:138
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4004
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:311
static const WCHAR L[]
Definition: oid.c:1250
_In_ GUID _In_ PVOID _In_ ULONG ValueLength
Definition: hubbusif.h:311
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
PWSTR DatabasePath
Definition: database.c:31
struct tagContext Context
Definition: acpixf.h:1030
return STATUS_SUCCESS
Definition: btrfs.c:2938
UCHAR UniqueId[1]
Definition: imports.h:139
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465

Referenced by DeleteNoDriveLetterEntry().

◆ DeleteRegistryDriveLetter()

VOID DeleteRegistryDriveLetter ( IN PMOUNTDEV_UNIQUE_ID  UniqueId)

Definition at line 2046 of file database.c.

2047 {
2049 
2052 
2054  DatabasePath,
2055  QueryTable,
2056  UniqueId,
2057  NULL);
2058 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4004
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
smooth NULL
Definition: ftsmooth.c:416
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:1999
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261

Referenced by MountMgrCreatePointWorker().

◆ DeleteRemoteDatabaseEntry()

NTSTATUS DeleteRemoteDatabaseEntry ( IN HANDLE  Database,
IN LONG  StartingOffset 
)

Definition at line 233 of file database.c.

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

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

◆ GetRemoteDatabaseEntry()

PDATABASE_ENTRY GetRemoteDatabaseEntry ( IN HANDLE  Database,
IN LONG  StartingOffset 
)

Definition at line 125 of file database.c.

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

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

◆ GetRemoteDatabaseSize()

LONG GetRemoteDatabaseSize ( IN HANDLE  Database)

Definition at line 40 of file database.c.

41 {
44  FILE_STANDARD_INFORMATION StandardInfo;
45 
46  /* Just query the size */
47  Status = ZwQueryInformationFile(Database,
49  &StandardInfo,
52  if (NT_SUCCESS(Status))
53  {
54  return StandardInfo.EndOfFile.LowPart;
55  }
56 
57  return 0;
58 }
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ULONG LowPart
Definition: typedefs.h:104
Status
Definition: gdiplustypes.h:24
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define FileStandardInformation
Definition: propsheet.cpp:61

Referenced by AddRemoteDatabaseEntry(), and DeleteRemoteDatabaseEntry().

◆ OnlineMountedVolumes()

VOID OnlineMountedVolumes ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PDEVICE_INFORMATION  DeviceInformation 
)

Definition at line 1460 of file database.c.

1462 {
1463  HANDLE Handle;
1464  NTSTATUS Status;
1468  PDEVICE_INFORMATION VolumeDeviceInformation;
1469  WCHAR FileNameBuffer[0x8], SymbolicNameBuffer[0x64];
1471  FILE_REPARSE_POINT_INFORMATION ReparsePointInformation, SavedReparsePointInformation;
1472 
1473  /* Removable devices don't have remote database on them */
1474  if (DeviceInformation->Removable)
1475  {
1476  return;
1477  }
1478 
1479  /* Prepare a string with reparse point index */
1480  ReparseFile.Length = DeviceInformation->DeviceName.Length + ReparseIndex.Length;
1481  ReparseFile.MaximumLength = ReparseFile.Length + sizeof(UNICODE_NULL);
1482  ReparseFile.Buffer = AllocatePool(ReparseFile.MaximumLength);
1483  if (!ReparseFile.Buffer)
1484  {
1485  return;
1486  }
1487 
1488  RtlCopyMemory(ReparseFile.Buffer, DeviceInformation->DeviceName.Buffer,
1489  DeviceInformation->DeviceName.Length);
1490  RtlCopyMemory((PVOID)((ULONG_PTR)ReparseFile.Buffer + DeviceInformation->DeviceName.Length),
1491  ReparseFile.Buffer, ReparseFile.Length);
1492  ReparseFile.Buffer[ReparseFile.Length / sizeof(WCHAR)] = UNICODE_NULL;
1493 
1495  &ReparseFile,
1497  NULL,
1498  NULL);
1499 
1500  /* Open reparse point */
1504  &IoStatusBlock,
1507  FreePool(ReparseFile.Buffer);
1508  if (!NT_SUCCESS(Status))
1509  {
1510  DeviceInformation->NoDatabase = FALSE;
1511  return;
1512  }
1513 
1514  /* Query reparse point information
1515  * We only pay attention to mout point
1516  */
1518  FileName.Buffer = FileNameBuffer;
1519  FileName.Length = sizeof(FileNameBuffer);
1520  FileName.MaximumLength = sizeof(FileNameBuffer);
1522  Status = ZwQueryDirectoryFile(Handle,
1523  NULL,
1524  NULL,
1525  NULL,
1526  &IoStatusBlock,
1527  &ReparsePointInformation,
1530  TRUE,
1531  &FileName,
1532  FALSE);
1533  if (!NT_SUCCESS(Status))
1534  {
1535  ZwClose(Handle);
1536  return;
1537  }
1538 
1539  RestartScan = TRUE;
1540 
1541  /* Query mount points */
1542  while (TRUE)
1543  {
1544  SymbolicName.Length = 0;
1545  SymbolicName.MaximumLength = sizeof(SymbolicNameBuffer);
1546  SymbolicName.Buffer = SymbolicNameBuffer;
1547  RtlCopyMemory(&SavedReparsePointInformation, &ReparsePointInformation, sizeof(FILE_REPARSE_POINT_INFORMATION));
1548 
1549  Status = ZwQueryDirectoryFile(Handle,
1550  NULL,
1551  NULL,
1552  NULL,
1553  &IoStatusBlock,
1554  &ReparsePointInformation,
1557  TRUE,
1558  (RestartScan) ? &FileName : NULL,
1559  RestartScan);
1560  if (!RestartScan)
1561  {
1562  if (ReparsePointInformation.FileReference == SavedReparsePointInformation.FileReference &&
1563  ReparsePointInformation.Tag == SavedReparsePointInformation.Tag)
1564  {
1565  break;
1566  }
1567  }
1568  else
1569  {
1570  RestartScan = FALSE;
1571  }
1572 
1573  if (!NT_SUCCESS(Status) || ReparsePointInformation.Tag != IO_REPARSE_TAG_MOUNT_POINT)
1574  {
1575  break;
1576  }
1577 
1578  /* Get the volume name associated to the mount point */
1580  &ReparsePointInformation,
1581  NULL, &SymbolicName,
1582  &VolumeName);
1583  if (!NT_SUCCESS(Status))
1584  {
1585  continue;
1586  }
1587 
1589 
1590  /* Get its information */
1591  Status = FindDeviceInfo(DeviceExtension, &SymbolicName,
1592  FALSE, &VolumeDeviceInformation);
1593  if (!NT_SUCCESS(Status))
1594  {
1595  DeviceInformation->NoDatabase = TRUE;
1596  continue;
1597  }
1598 
1599  /* If notification are enabled, mark it online */
1600  if (!DeviceInformation->SkipNotifications)
1601  {
1602  PostOnlineNotification(DeviceExtension, &VolumeDeviceInformation->SymbolicName);
1603  }
1604  }
1605 
1606  ZwClose(Handle);
1607 }
#define FILE_GENERIC_READ
Definition: nt_native.h:653
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)
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ BOOLEAN _In_ ULONG _In_opt_ PULONG _In_ BOOLEAN RestartScan
Definition: fltkernel.h:2298
USHORT MaximumLength
Definition: env_spec_w32.h:370
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FreePool(P)
Definition: mntmgr.h:154
UNICODE_STRING SymbolicName
Definition: mntmgr.h:48
#define FILE_SHARE_READ
Definition: compat.h:125
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define IO_REPARSE_TAG_MOUNT_POINT
Definition: iotypes.h:6875
#define FILE_SYNCHRONOUS_IO_ALERT
Definition: from_kernel.h:30
#define UNICODE_NULL
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS FindDeviceInfo(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName, IN BOOLEAN DeviceNameGiven, OUT PDEVICE_INFORMATION *DeviceInformation)
Definition: mountmgr.c:641
UNICODE_STRING ReparseIndex
Definition: symlink.c:40
_In_ HANDLE Handle
Definition: extypes.h:390
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI NTSTATUS NTAPI ZwOpenFile(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _Out_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG ShareAccess, _In_ ULONG OpenOptions)
#define AllocatePool(Size)
Definition: mntmgr.h:153
Status
Definition: gdiplustypes.h:24
VOID PostOnlineNotification(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName)
Definition: notify.c:145
struct _FileName FileName
Definition: fatprocs.h:884
NTSTATUS QueryVolumeName(IN HANDLE RootDirectory, IN PFILE_REPARSE_POINT_INFORMATION ReparsePointInformation, IN PUNICODE_STRING FileName OPTIONAL, OUT PUNICODE_STRING SymbolicName, OUT PUNICODE_STRING VolumeName)
Definition: database.c:1292
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned int * PULONG
Definition: retypes.h:1
_Must_inspect_result_ _Inout_opt_ PUNICODE_STRING VolumeName
Definition: fltkernel.h:1117
WCHAR FileNameBuffer[_MAX_PATH]
Definition: framewnd.c:239
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define FILE_OPEN_REPARSE_POINT
Definition: from_kernel.h:46

Referenced by ReconcileThisDatabaseWithMaster().

◆ OpenRemoteDatabase()

HANDLE OpenRemoteDatabase ( IN PDEVICE_INFORMATION  DeviceInformation,
IN BOOLEAN  MigrateDatabase 
)

Definition at line 1836 of file database.c.

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

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

◆ QueryUniqueIdFromMaster()

NTSTATUS QueryUniqueIdFromMaster ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PUNICODE_STRING  SymbolicName,
OUT PMOUNTDEV_UNIQUE_ID UniqueId 
)

Definition at line 440 of file database.c.

443 {
445  PDEVICE_INFORMATION DeviceInformation;
447 
448  /* Query the unique ID */
452 
453  *UniqueId = NULL;
455  DatabasePath,
456  QueryTable,
457  UniqueId,
458  NULL);
459  /* Unique ID found, no need to go farther */
460  if (*UniqueId)
461  {
462  return STATUS_SUCCESS;
463  }
464 
465  /* Otherwise, find associate device information */
466  Status = FindDeviceInfo(DeviceExtension, SymbolicName, FALSE, &DeviceInformation);
467  if (!NT_SUCCESS(Status))
468  {
469  return Status;
470  }
471 
472  *UniqueId = AllocatePool(DeviceInformation->UniqueId->UniqueIdLength + sizeof(MOUNTDEV_UNIQUE_ID));
473  if (!*UniqueId)
474  {
476  }
477 
478  /* Return this unique ID (better than nothing) */
479  (*UniqueId)->UniqueIdLength = DeviceInformation->UniqueId->UniqueIdLength;
480  RtlCopyMemory(&((*UniqueId)->UniqueId), &(DeviceInformation->UniqueId->UniqueId), (*UniqueId)->UniqueIdLength);
481 
482  return STATUS_SUCCESS;
483 }
_In_ PCWSTR _Inout_ _At_ QueryTable _Pre_unknown_ PRTL_QUERY_REGISTRY_TABLE QueryTable
Definition: rtlfuncs.h:4004
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS NTAPI QueryUniqueIdQueryRoutine(IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
Definition: database.c:401
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
LONG NTSTATUS
Definition: precomp.h:26
USHORT UniqueIdLength
Definition: imports.h:138
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine
Definition: nt_native.h:109
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS FindDeviceInfo(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName, IN BOOLEAN DeviceNameGiven, OUT PDEVICE_INFORMATION *DeviceInformation)
Definition: mountmgr.c:641
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define AllocatePool(Size)
Definition: mntmgr.h:153
PWSTR DatabasePath
Definition: database.c:31
Status
Definition: gdiplustypes.h:24
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
return STATUS_SUCCESS
Definition: btrfs.c:2938
PMOUNTDEV_UNIQUE_ID UniqueId
Definition: mntmgr.h:49
UCHAR UniqueId[1]
Definition: imports.h:139

Referenced by ReconcileThisDatabaseWithMasterWorker().

◆ QueryUniqueIdQueryRoutine()

NTSTATUS NTAPI QueryUniqueIdQueryRoutine ( IN PWSTR  ValueName,
IN ULONG  ValueType,
IN PVOID  ValueData,
IN ULONG  ValueLength,
IN PVOID  Context,
IN PVOID  EntryContext 
)

Definition at line 401 of file database.c.

407 {
408  PMOUNTDEV_UNIQUE_ID IntUniqueId;
409  PMOUNTDEV_UNIQUE_ID * UniqueId;
410 
414 
415  /* Sanity check */
416  if (ValueLength >= 0x10000)
417  {
418  return STATUS_SUCCESS;
419  }
420 
421  /* Allocate the Unique ID */
422  IntUniqueId = AllocatePool(sizeof(UniqueId) + ValueLength);
423  if (IntUniqueId)
424  {
425  /* Copy data & return */
426  IntUniqueId->UniqueIdLength = (USHORT)ValueLength;
427  RtlCopyMemory(&(IntUniqueId->UniqueId), ValueData, ValueLength);
428 
429  UniqueId = Context;
430  *UniqueId = IntUniqueId;
431  }
432 
433  return STATUS_SUCCESS;
434 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
_In_ PCWSTR _In_z_ PCWSTR _In_ ULONG ValueType
Definition: rtlfuncs.h:4016
USHORT UniqueIdLength
Definition: imports.h:138
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4004
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:311
_In_ GUID _In_ PVOID _In_ ULONG ValueLength
Definition: hubbusif.h:311
#define AllocatePool(Size)
Definition: mntmgr.h:153
unsigned short USHORT
Definition: pedump.c:61
struct tagContext Context
Definition: acpixf.h:1030
return STATUS_SUCCESS
Definition: btrfs.c:2938
UCHAR UniqueId[1]
Definition: imports.h:139

Referenced by QueryUniqueIdFromMaster().

◆ QueryVolumeName()

NTSTATUS QueryVolumeName ( IN HANDLE  RootDirectory,
IN PFILE_REPARSE_POINT_INFORMATION  ReparsePointInformation,
IN PUNICODE_STRING FileName  OPTIONAL,
OUT PUNICODE_STRING  SymbolicName,
OUT PUNICODE_STRING  VolumeName 
)

Definition at line 1292 of file database.c.

1297 {
1298  HANDLE Handle;
1299  NTSTATUS Status;
1300  ULONG NeededLength;
1303  PFILE_NAME_INFORMATION FileNameInfo;
1304  PREPARSE_DATA_BUFFER ReparseDataBuffer;
1305 
1306  UNREFERENCED_PARAMETER(ReparsePointInformation);
1307 
1308  if (!FileName)
1309  {
1311  NULL,
1313  RootDirectory,
1314  NULL);
1315  }
1316  else
1317  {
1319  FileName,
1321  NULL,
1322  NULL);
1323  }
1324 
1325  /* Open volume */
1329  &IoStatusBlock,
1333  if (!NT_SUCCESS(Status))
1334  {
1335  return Status;
1336  }
1337 
1338  /* Get the reparse point data */
1339  ReparseDataBuffer = AllocatePool(MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
1340  if (!ReparseDataBuffer)
1341  {
1342  ZwClose(Handle);
1344  }
1345 
1347  0,
1348  NULL,
1349  NULL,
1350  &IoStatusBlock,
1352  NULL,
1353  0,
1354  ReparseDataBuffer,
1356  if (!NT_SUCCESS(Status))
1357  {
1358  FreePool(ReparseDataBuffer);
1359  ZwClose(Handle);
1360  return Status;
1361  }
1362 
1363  /* Check that name can fit in buffer */
1364  if (ReparseDataBuffer->MountPointReparseBuffer.SubstituteNameLength + sizeof(UNICODE_NULL) > SymbolicName->MaximumLength)
1365  {
1366  FreePool(ReparseDataBuffer);
1367  ZwClose(Handle);
1368  return STATUS_BUFFER_TOO_SMALL;
1369  }
1370 
1371  /* Copy symbolic name */
1372  SymbolicName->Length = ReparseDataBuffer->MountPointReparseBuffer.SubstituteNameLength;
1374  (PWSTR)((ULONG_PTR)ReparseDataBuffer->MountPointReparseBuffer.PathBuffer +
1375  ReparseDataBuffer->MountPointReparseBuffer.SubstituteNameOffset),
1376  ReparseDataBuffer->MountPointReparseBuffer.SubstituteNameLength);
1377 
1378  FreePool(ReparseDataBuffer);
1379 
1380  /* Name has to \ terminated */
1381  if (SymbolicName->Buffer[SymbolicName->Length / sizeof(WCHAR) - 1] != L'\\')
1382  {
1383  ZwClose(Handle);
1384  return STATUS_INVALID_PARAMETER;
1385  }
1386 
1387  /* So that we can delete it, and match mountmgr requirements */
1388  SymbolicName->Length -= sizeof(WCHAR);
1390 
1391  /* Also ensure it's really a volume name... */
1393  {
1394  ZwClose(Handle);
1395  return STATUS_INVALID_PARAMETER;
1396  }
1397 
1398  /* Now prepare to really get the name */
1399  FileNameInfo = AllocatePool(sizeof(FILE_NAME_INFORMATION) + 2 * sizeof(WCHAR));
1400  if (!FileNameInfo)
1401  {
1402  ZwClose(Handle);
1404  }
1405 
1406  Status = ZwQueryInformationFile(Handle,
1407  &IoStatusBlock,
1408  FileNameInfo,
1409  sizeof(FILE_NAME_INFORMATION) + 2 * sizeof(WCHAR),
1412  {
1413  /* As expected... Reallocate with proper size */
1414  NeededLength = FileNameInfo->FileNameLength;
1415  FreePool(FileNameInfo);
1416 
1417  FileNameInfo = AllocatePool(sizeof(FILE_NAME_INFORMATION) + NeededLength);
1418  if (!FileNameInfo)
1419  {
1420  ZwClose(Handle);
1422  }
1423 
1424  /* And query name */
1425  Status = ZwQueryInformationFile(Handle,
1426  &IoStatusBlock,
1427  FileNameInfo,
1428  sizeof(FILE_NAME_INFORMATION) + NeededLength,
1430  }
1431 
1432  ZwClose(Handle);
1433 
1434  if (!NT_SUCCESS(Status))
1435  {
1436  return Status;
1437  }
1438 
1439  /* Return the volume name */
1440  VolumeName->Length = (USHORT)FileNameInfo->FileNameLength;
1441  VolumeName->MaximumLength = (USHORT)FileNameInfo->FileNameLength + sizeof(WCHAR);
1443  if (!VolumeName->Buffer)
1444  {
1446  }
1447 
1448  RtlCopyMemory(VolumeName->Buffer, FileNameInfo->FileName, FileNameInfo->FileNameLength);
1449  VolumeName->Buffer[FileNameInfo->FileNameLength / sizeof(WCHAR)] = UNICODE_NULL;
1450 
1451  FreePool(FileNameInfo);
1452 
1453  return STATUS_SUCCESS;
1454 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
WCHAR RootDirectory[MAX_PATH]
Definition: format.c:74
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:54
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FSCTL_GET_REPARSE_POINT
Definition: winioctl.h:97
#define FreePool(P)
Definition: mntmgr.h:154
#define FILE_SHARE_READ
Definition: compat.h:125
#define FILE_OPEN_BY_FILE_ID
Definition: from_kernel.h:41
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define UNICODE_NULL
#define MOUNTMGR_IS_VOLUME_NAME(s)
Definition: mountmgr.h:61
NTSYSAPI NTSTATUS NTAPI ZwFsControlFile(IN HANDLE DeviceHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG IoControlCode, IN PVOID InputBuffer, IN ULONG InputBufferSize, OUT PVOID OutputBuffer, IN ULONG OutputBufferSize)
smooth NULL
Definition: ftsmooth.c:416
_In_ HANDLE Handle
Definition: extypes.h:390
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _REPARSE_DATA_BUFFER::@308::@311 MountPointReparseBuffer
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
NTSYSAPI NTSTATUS NTAPI ZwOpenFile(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _Out_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG ShareAccess, _In_ ULONG OpenOptions)
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
static const WCHAR L[]
Definition: oid.c:1250
#define SYNCHRONIZE
Definition: nt_native.h:61
#define AllocatePool(Size)
Definition: mntmgr.h:153
Status
Definition: gdiplustypes.h:24
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
unsigned short USHORT
Definition: pedump.c:61
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
_Must_inspect_result_ _Inout_opt_ PUNICODE_STRING VolumeName
Definition: fltkernel.h:1117
unsigned int ULONG
Definition: retypes.h:1
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE
Definition: iotypes.h:6857
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define FILE_OPEN_REPARSE_POINT
Definition: from_kernel.h:46

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

◆ QueueWorkItem()

NTSTATUS QueueWorkItem ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PRECONCILE_WORK_ITEM  WorkItem,
IN PVOID  Context 
)

Definition at line 1261 of file database.c.

1264 {
1265  KIRQL OldIrql;
1266 
1267  WorkItem->Context = Context;
1268 
1269  /* When called, lock is already acquired */
1270 
1271  /* If noone (-1 as references), start to work */
1272  if (InterlockedIncrement(&(DeviceExtension->WorkerReferences)) == 0)
1273  {
1274  IoQueueWorkItem(WorkItem->WorkItem, WorkerThread, DelayedWorkQueue, DeviceExtension);
1275  }
1276 
1277  /* Otherwise queue worker for delayed execution */
1278  KeAcquireSpinLock(&(DeviceExtension->WorkerLock), &OldIrql);
1279  InsertTailList(&(DeviceExtension->WorkerQueueListHead),
1280  &(WorkItem->WorkerQueueListEntry));
1281  KeReleaseSpinLock(&(DeviceExtension->WorkerLock), OldIrql);
1282 
1283  KeReleaseSemaphore(&(DeviceExtension->WorkerSemaphore), IO_NO_INCREMENT, 1, FALSE);
1284 
1285  return STATUS_SUCCESS;
1286 }
#define InsertTailList(ListHead, Entry)
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID NTAPI WorkerThread(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context)
Definition: database.c:1148
#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
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
#define InterlockedIncrement
Definition: armddk.h:53
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
struct tagContext Context
Definition: acpixf.h:1030
#define IO_NO_INCREMENT
Definition: iotypes.h:566
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by ReconcileThisDatabaseWithMaster().

◆ ReconcileAllDatabasesWithMaster()

VOID ReconcileAllDatabasesWithMaster ( IN PDEVICE_EXTENSION  DeviceExtension)

Definition at line 1659 of file database.c.

1660 {
1661  PLIST_ENTRY NextEntry;
1662  PDEVICE_INFORMATION DeviceInformation;
1663 
1664  /* Browse all the devices */
1665  for (NextEntry = DeviceExtension->DeviceListHead.Flink;
1666  NextEntry != &(DeviceExtension->DeviceListHead);
1667  NextEntry = NextEntry->Flink)
1668  {
1669  DeviceInformation = CONTAINING_RECORD(NextEntry,
1671  DeviceListEntry);
1672  /* If it's not removable, then, it might have a database to sync */
1673  if (!DeviceInformation->Removable)
1674  {
1675  ReconcileThisDatabaseWithMaster(DeviceExtension, DeviceInformation);
1676  }
1677  }
1678 }
VOID ReconcileThisDatabaseWithMaster(IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation)
Definition: database.c:1613
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 Removable
Definition: mntmgr.h:54

Referenced by MountMgrDeviceControl().

◆ ReconcileThisDatabaseWithMaster()

VOID ReconcileThisDatabaseWithMaster ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PDEVICE_INFORMATION  DeviceInformation 
)

Definition at line 1613 of file database.c.

1615 {
1616  PRECONCILE_WORK_ITEM WorkItem;
1617 
1618  /* Removable devices don't have remote database */
1619  if (DeviceInformation->Removable)
1620  {
1621  return;
1622  }
1623 
1624  /* Allocate a work item */
1625  WorkItem = AllocatePool(sizeof(RECONCILE_WORK_ITEM));
1626  if (!WorkItem)
1627  {
1628  return;
1629  }
1630 
1631  WorkItem->WorkItem = IoAllocateWorkItem(DeviceExtension->DeviceObject);
1632  if (!WorkItem->WorkItem)
1633  {
1634  FreePool(WorkItem);
1635  return;
1636  }
1637 
1638  /* And queue it */
1640  WorkItem->DeviceExtension = DeviceExtension;
1641  WorkItem->DeviceInformation = DeviceInformation;
1642  QueueWorkItem(DeviceExtension, WorkItem, &(WorkItem->DeviceExtension));
1643 
1644  /* If there's no automount, and automatic letters
1645  * all volumes to find those online and notify there presence
1646  */
1647  if (DeviceExtension->WorkerThreadStatus == 0 &&
1648  DeviceExtension->AutomaticDriveLetter == 1 &&
1649  DeviceExtension->NoAutoMount == FALSE)
1650  {
1651  OnlineMountedVolumes(DeviceExtension, DeviceInformation);
1652  }
1653 }
VOID NTAPI ReconcileThisDatabaseWithMasterWorker(IN PVOID Parameter)
Definition: database.c:560
NTSTATUS QueueWorkItem(IN PDEVICE_EXTENSION DeviceExtension, IN PRECONCILE_WORK_ITEM WorkItem, IN PVOID Context)
Definition: database.c:1261
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
#define FreePool(P)
Definition: mntmgr.h:154
VOID OnlineMountedVolumes(IN PDEVICE_EXTENSION DeviceExtension, IN PDEVICE_INFORMATION DeviceInformation)
Definition: database.c:1460
#define AllocatePool(Size)
Definition: mntmgr.h:153
PIO_WORKITEM WorkItem
Definition: mntmgr.h:124
PWORKER_THREAD_ROUTINE WorkerRoutine
Definition: mntmgr.h:125

Referenced by MountMgrCreatePointWorker(), MountMgrMountedDeviceArrival(), MountMgrTargetDeviceNotification(), MountMgrUniqueIdChangeRoutine(), MountMgrVolumeMountPointChanged(), and ReconcileAllDatabasesWithMaster().

◆ ReconcileThisDatabaseWithMasterWorker()

VOID NTAPI ReconcileThisDatabaseWithMasterWorker ( IN PVOID  Parameter)

Definition at line 560 of file database.c.

561 {
562  ULONG Offset;
566  PMOUNTDEV_UNIQUE_ID UniqueId;
567  PDATABASE_ENTRY DatabaseEntry;
568  HANDLE DatabaseHandle, Handle;
571  PDEVICE_INFORMATION ListDeviceInfo;
572  PLIST_ENTRY Entry, EntryInfo, NextEntry;
573  PASSOCIATED_DEVICE_ENTRY AssociatedDevice;
574  BOOLEAN HardwareErrors, Restart, FailedFinding;
575  WCHAR FileNameBuffer[0x8], SymbolicNameBuffer[100];
577  FILE_REPARSE_POINT_INFORMATION ReparsePointInformation, SavedReparsePointInformation;
578  PDEVICE_EXTENSION DeviceExtension = ((PRECONCILE_WORK_ITEM_CONTEXT)Parameter)->DeviceExtension;
579  PDEVICE_INFORMATION DeviceInformation = ((PRECONCILE_WORK_ITEM_CONTEXT)Parameter)->DeviceInformation;
580 
581  /* We're unloading, do nothing */
582  if (Unloading)
583  {
584  return;
585  }
586 
587  /* Lock remote DB */
588  if (!NT_SUCCESS(WaitForRemoteDatabaseSemaphore(DeviceExtension)))
589  {
590  return;
591  }
592 
593  /* Recheck for unloading */
594  if (Unloading)
595  {
596  goto ReleaseRDS;
597  }
598 
599  /* Find the DB to reconcile */
600  KeWaitForSingleObject(&DeviceExtension->DeviceLock, Executive, KernelMode, FALSE, NULL);
601  for (Entry = DeviceExtension->DeviceListHead.Flink;
602  Entry != &DeviceExtension->DeviceListHead;
603  Entry = Entry->Flink)
604  {
605  ListDeviceInfo = CONTAINING_RECORD(Entry, DEVICE_INFORMATION, DeviceListEntry);
606  if (ListDeviceInfo == DeviceInformation)
607  {
608  break;
609  }
610  }
611 
612  /* If not found, or if removable, bail out */
613  if (Entry == &DeviceExtension->DeviceListHead || DeviceInformation->Removable)
614  {
615  KeReleaseSemaphore(&DeviceExtension->DeviceLock, IO_NO_INCREMENT, 1, FALSE);
616  goto ReleaseRDS;
617  }
618 
619  /* Get our device object */
621  if (!NT_SUCCESS(Status))
622  {
623  KeReleaseSemaphore(&DeviceExtension->DeviceLock, IO_NO_INCREMENT, 1, FALSE);
624  goto ReleaseRDS;
625  }
626 
627  /* Mark mounted only if not unloading */
629  {
630  InterlockedExchangeAdd(&ListDeviceInfo->MountState, 1);
631  }
632 
634 
635  /* Force default: no DB, and need for reconcile */
636  DeviceInformation->NeedsReconcile = TRUE;
637  DeviceInformation->NoDatabase = TRUE;
638  FailedFinding = FALSE;
639 
640  /* Remove any associated device that refers to the DB to reconcile */
641  for (Entry = DeviceExtension->DeviceListHead.Flink;
642  Entry != &DeviceExtension->DeviceListHead;
643  Entry = Entry->Flink)
644  {
645  ListDeviceInfo = CONTAINING_RECORD(Entry, DEVICE_INFORMATION, DeviceListEntry);
646 
647  EntryInfo = ListDeviceInfo->AssociatedDevicesHead.Flink;
648  while (EntryInfo != &ListDeviceInfo->AssociatedDevicesHead)
649  {
650  AssociatedDevice = CONTAINING_RECORD(EntryInfo, ASSOCIATED_DEVICE_ENTRY, AssociatedDevicesEntry);
651  NextEntry = EntryInfo->Flink;
652 
653  if (AssociatedDevice->DeviceInformation == DeviceInformation)
654  {
655  RemoveEntryList(&AssociatedDevice->AssociatedDevicesEntry);
656  FreePool(AssociatedDevice->String.Buffer);
657  FreePool(AssociatedDevice);
658  }
659 
660  EntryInfo = NextEntry;
661  }
662  }
663 
664  /* Open the remote database */
665  DatabaseHandle = OpenRemoteDatabase(DeviceInformation, FALSE);
666 
667  /* Prepare a string with reparse point index */
668  ReparseFile.Length = DeviceInformation->DeviceName.Length + ReparseIndex.Length;
669  ReparseFile.MaximumLength = ReparseFile.Length + sizeof(UNICODE_NULL);
670  ReparseFile.Buffer = AllocatePool(ReparseFile.MaximumLength);
671  if (ReparseFile.Buffer == NULL)
672  {
673  if (DatabaseHandle != 0)
674  {
675  CloseRemoteDatabase(DatabaseHandle);
676  }
677  KeReleaseSemaphore(&DeviceExtension->DeviceLock, IO_NO_INCREMENT, 1, FALSE);
678  goto ReleaseRDS;
679  }
680 
681  RtlCopyMemory(ReparseFile.Buffer, DeviceInformation->DeviceName.Buffer,
682  DeviceInformation->DeviceName.Length);
683  RtlCopyMemory((PVOID)((ULONG_PTR)ReparseFile.Buffer + DeviceInformation->DeviceName.Length),
685  ReparseFile.Buffer[ReparseFile.Length / sizeof(WCHAR)] = UNICODE_NULL;
686 
688  &ReparseFile,
690  NULL,
691  NULL);
692 
693  /* Open reparse point directory */
694  HardwareErrors = IoSetThreadHardErrorMode(FALSE);
698  &IoStatusBlock,
701  IoSetThreadHardErrorMode(HardwareErrors);
702 
703  FreePool(ReparseFile.Buffer);
704 
705  if (!NT_SUCCESS(Status))
706  {
707  if (DatabaseHandle != 0)
708  {
709  TruncateRemoteDatabase(DatabaseHandle, 0);
710  CloseRemoteDatabase(DatabaseHandle);
711  }
712  KeReleaseSemaphore(&DeviceExtension->DeviceLock, IO_NO_INCREMENT, 1, FALSE);
713  goto ReleaseRDS;
714  }
715 
716  /* Query reparse point information
717  * We only pay attention to mout point
718  */
720  FileName.Buffer = FileNameBuffer;
721  FileName.Length = sizeof(FileNameBuffer);
722  FileName.MaximumLength = sizeof(FileNameBuffer);
724  Status = ZwQueryDirectoryFile(Handle,
725  NULL,
726  NULL,
727  NULL,
728  &IoStatusBlock,
729  &ReparsePointInformation,
732  TRUE,
733  &FileName,
734  FALSE);
735  if (!NT_SUCCESS(Status))
736  {
737  ZwClose(Handle);
738  if (DatabaseHandle != 0)
739  {
740  TruncateRemoteDatabase(DatabaseHandle, 0);
741  CloseRemoteDatabase(DatabaseHandle);
742  }
743  KeReleaseSemaphore(&DeviceExtension->DeviceLock, IO_NO_INCREMENT, 1, FALSE);
744  goto ReleaseRDS;
745  }
746 
747  /* If we failed to open the remote DB previously,
748  * retry this time allowing migration (and thus, creation if required)
749  */
750  if (DatabaseHandle == 0)
751  {
752  DatabaseHandle = OpenRemoteDatabase(DeviceInformation, TRUE);
753  if (DatabaseHandle == 0)
754  {
755  KeReleaseSemaphore(&DeviceExtension->DeviceLock, IO_NO_INCREMENT, 1, FALSE);
756  goto ReleaseRDS;
757  }
758  }
759 
760  KeReleaseSemaphore(&DeviceExtension->DeviceLock, IO_NO_INCREMENT, 1, FALSE);
761 
762  /* Reset all the references to our DB entries */
763  Offset = 0;
764  for (;;)
765  {
766  DatabaseEntry = GetRemoteDatabaseEntry(DatabaseHandle, Offset);
767  if (DatabaseEntry == NULL)
768  {
769  break;
770  }
771 
772  DatabaseEntry->EntryReferences = 0;
773  Status = WriteRemoteDatabaseEntry(DatabaseHandle, Offset, DatabaseEntry);
774  if (!NT_SUCCESS(Status))
775  {
776  FreePool(DatabaseEntry);
777  goto CloseReparse;
778  }
779 
780  Offset += DatabaseEntry->EntrySize;
781  FreePool(DatabaseEntry);
782  }
783 
784  /* Init string for QueryVolumeName call */
785  SymbolicName.MaximumLength = sizeof(SymbolicNameBuffer);
786  SymbolicName.Length = 0;
787  SymbolicName.Buffer = SymbolicNameBuffer;
788  Restart = TRUE;
789 
790  /* Start looping on reparse points */
791  for (;;)
792  {
793  RtlCopyMemory(&SavedReparsePointInformation, &ReparsePointInformation, sizeof(FILE_REPARSE_POINT_INFORMATION));
794  Status = ZwQueryDirectoryFile(Handle,
795  NULL,
796  NULL,
797  NULL,
798  &IoStatusBlock,
799  &ReparsePointInformation,
802  TRUE,
803  Restart ? &FileName : NULL,
804  Restart);
805  /* Restart only once */
806  if (Restart)
807  {
808  Restart = FALSE;
809  }
810  else
811  {
812  /* If we get the same one, we're done, bail out */
813  if (ReparsePointInformation.FileReference == SavedReparsePointInformation.FileReference &&
814  ReparsePointInformation.Tag == SavedReparsePointInformation.Tag)
815  {
816  break;
817  }
818  }
819 
820  /* If querying failed, or if onloading, or if not returning mount points, bail out */
821  if (!NT_SUCCESS(Status) || Unloading || ReparsePointInformation.Tag != IO_REPARSE_TAG_MOUNT_POINT)
822  {
823  break;
824  }
825 
826  /* Get the volume name associated to the mount point */
827  Status = QueryVolumeName(Handle, &ReparsePointInformation, 0, &SymbolicName, &VolumeName);
828  if (!NT_SUCCESS(Status))
829  {
830  continue;
831  }
832 
833  /* Browse the DB to find the name */
834  Offset = 0;
835  for (;;)
836  {
837  UNICODE_STRING DbName;
838 
839  DatabaseEntry = GetRemoteDatabaseEntry(DatabaseHandle, Offset);
840  if (DatabaseEntry == NULL)
841  {
842  break;
843  }
844 
845  DbName.MaximumLength = DatabaseEntry->SymbolicNameLength;
846  DbName.Length = DbName.MaximumLength;
847  DbName.Buffer = (PWSTR)((ULONG_PTR)DatabaseEntry + DatabaseEntry->SymbolicNameOffset);
848  /* Found, we're done! */
849  if (RtlEqualUnicodeString(&DbName, &SymbolicName, TRUE))
850  {
851  break;
852  }
853 
854  Offset += DatabaseEntry->EntrySize;
855  FreePool(DatabaseEntry);
856  }
857 
858  /* If we found the mount point.... */
859  if (DatabaseEntry != NULL)
860  {
861  /* If it was referenced, reference it once more and update to remote */
862  if (DatabaseEntry->EntryReferences)
863  {
864  ++DatabaseEntry->EntryReferences;
865  Status = WriteRemoteDatabaseEntry(DatabaseHandle, Offset, DatabaseEntry);
866  if (!NT_SUCCESS(Status))
867  {
868  goto FreeDBEntry;
869  }
870 
871  FreePool(DatabaseEntry);
872  }
873  else
874  {
875  /* Query the Unique ID associated to that mount point in case it changed */
876  KeWaitForSingleObject(&DeviceExtension->DeviceLock, Executive, KernelMode, FALSE, NULL);
877  Status = QueryUniqueIdFromMaster(DeviceExtension, &SymbolicName, &UniqueId);
878  if (!NT_SUCCESS(Status))
879  {
880  /* If we failed doing so, reuse the old Unique ID and push it to master */
881  Status = WriteUniqueIdToMaster(DeviceExtension, DatabaseEntry);
882  if (!NT_SUCCESS(Status))
883  {
884  goto ReleaseDeviceLock;
885  }
886 
887  /* And then, reference & write the entry */
888  ++DatabaseEntry->EntryReferences;
889  Status = WriteRemoteDatabaseEntry(DatabaseHandle, Offset, DatabaseEntry);
890  if (!NT_SUCCESS(Status))
891  {
892  goto ReleaseDeviceLock;
893  }
894 
895  KeReleaseSemaphore(&DeviceExtension->DeviceLock, IO_NO_INCREMENT, 1, FALSE);
896  FreePool(DatabaseEntry);
897  }
898  /* If the Unique ID didn't change */
899  else if (UniqueId->UniqueIdLength == DatabaseEntry->UniqueIdLength &&
900  RtlCompareMemory(UniqueId->UniqueId,
901  (PVOID)((ULONG_PTR)DatabaseEntry + DatabaseEntry->UniqueIdOffset),
902  UniqueId->UniqueIdLength) == UniqueId->UniqueIdLength)
903  {
904  /* Reference the entry, and update to remote */
905  ++DatabaseEntry->EntryReferences;
906  Status = WriteRemoteDatabaseEntry(DatabaseHandle, Offset, DatabaseEntry);
907  if (!NT_SUCCESS(Status))
908  {
909  goto FreeUniqueId;
910  }
911 
912  FreePool(UniqueId);
913  KeReleaseSemaphore(&DeviceExtension->DeviceLock, IO_NO_INCREMENT, 1, FALSE);
914  FreePool(DatabaseEntry);
915  }
916  /* Would, by chance, the Unique ID be present elsewhere? */
917  else if (IsUniqueIdPresent(DeviceExtension, DatabaseEntry))
918  {
919  /* Push the ID to master */
920  Status = WriteUniqueIdToMaster(DeviceExtension, DatabaseEntry);
921  if (!NT_SUCCESS(Status))
922  {
923  goto FreeUniqueId;
924  }
925 
926  /* And then, reference & write the entry */
927  ++DatabaseEntry->EntryReferences;
928  Status = WriteRemoteDatabaseEntry(DatabaseHandle, Offset, DatabaseEntry);
929  if (!NT_SUCCESS(Status))
930  {
931  goto FreeUniqueId;
932  }
933 
934  FreePool(UniqueId);
935  KeReleaseSemaphore(&DeviceExtension->DeviceLock, IO_NO_INCREMENT, 1, FALSE);
936  FreePool(DatabaseEntry);
937  }
938  else
939  {
940  /* OK, at that point, we're facing a totally unknown unique ID
941  * So, get rid of the old entry, and recreate a new one with
942  * the know unique ID
943  */
944  Status = DeleteRemoteDatabaseEntry(DatabaseHandle, Offset);
945  if (!NT_SUCCESS(Status))
946  {
947  goto FreeUniqueId;
948  }
949 
950  FreePool(DatabaseEntry);
951  /* Allocate a new entry big enough */
952  DatabaseEntry = AllocatePool(UniqueId->UniqueIdLength + SymbolicName.Length + sizeof(DATABASE_ENTRY));
953  if (DatabaseEntry == NULL)
954  {
955  goto FreeUniqueId;
956  }
957 
958  /* Configure it */
959  DatabaseEntry->EntrySize = UniqueId->UniqueIdLength + SymbolicName.Length + sizeof(DATABASE_ENTRY);
960  DatabaseEntry->EntryReferences = 1;
961  DatabaseEntry->SymbolicNameOffset = sizeof(DATABASE_ENTRY);
962  DatabaseEntry->SymbolicNameLength = SymbolicName.Length;
963  DatabaseEntry->UniqueIdOffset = SymbolicName.Length + sizeof(DATABASE_ENTRY);
964  DatabaseEntry->UniqueIdLength = UniqueId->UniqueIdLength;
965  RtlCopyMemory((PVOID)((ULONG_PTR)DatabaseEntry + DatabaseEntry->SymbolicNameOffset), SymbolicName.Buffer, DatabaseEntry->SymbolicNameLength);
966  RtlCopyMemory((PVOID)((ULONG_PTR)DatabaseEntry + DatabaseEntry->UniqueIdOffset), UniqueId->UniqueId, UniqueId->UniqueIdLength);
967 
968  /* And write it remotely */
969  Status = AddRemoteDatabaseEntry(DatabaseHandle, DatabaseEntry);
970  if (!NT_SUCCESS(Status))
971  {
972  FreePool(DatabaseEntry);
973  goto FreeUniqueId;
974  }
975 
976  FreePool(UniqueId);
977  FreePool(DatabaseEntry);
978  KeReleaseSemaphore(&DeviceExtension->DeviceLock, IO_NO_INCREMENT, 1, FALSE);
979  }
980  }
981  }
982  else
983  {
984  /* We failed finding it remotely
985  * So, let's allocate a new remote DB entry
986  */
987  KeWaitForSingleObject(&DeviceExtension->DeviceLock, Executive, KernelMode, FALSE, NULL);
988  /* To be able to do so, we need the device Unique ID, ask master */
989  Status = QueryUniqueIdFromMaster(DeviceExtension, &SymbolicName, &UniqueId);
990  KeReleaseSemaphore(&DeviceExtension->DeviceLock, IO_NO_INCREMENT, 1, FALSE);
991  if (NT_SUCCESS(Status))
992  {
993  /* Allocate a new entry big enough */
994  DatabaseEntry = AllocatePool(UniqueId->UniqueIdLength + SymbolicName.Length + sizeof(DATABASE_ENTRY));
995  if (DatabaseEntry != NULL)
996  {
997  /* Configure it */
998  DatabaseEntry->EntrySize = UniqueId->UniqueIdLength + SymbolicName.Length + sizeof(DATABASE_ENTRY);
999  DatabaseEntry->EntryReferences = 1;
1000  DatabaseEntry->SymbolicNameOffset = sizeof(DATABASE_ENTRY);
1001  DatabaseEntry->SymbolicNameLength = SymbolicName.Length;
1002  DatabaseEntry->UniqueIdOffset = SymbolicName.Length + sizeof(DATABASE_ENTRY);
1003  DatabaseEntry->UniqueIdLength = UniqueId->UniqueIdLength;
1004  RtlCopyMemory((PVOID)((ULONG_PTR)DatabaseEntry + DatabaseEntry->SymbolicNameOffset), SymbolicName.Buffer, DatabaseEntry->SymbolicNameLength);
1005  RtlCopyMemory((PVOID)((ULONG_PTR)DatabaseEntry + DatabaseEntry->UniqueIdOffset), UniqueId->UniqueId, UniqueId->UniqueIdLength);
1006 
1007  /* And write it remotely */
1008  Status = AddRemoteDatabaseEntry(DatabaseHandle, DatabaseEntry);
1009  FreePool(DatabaseEntry);
1010  FreePool(UniqueId);
1011 
1012  if (!NT_SUCCESS(Status))
1013  {
1014  goto FreeVolume;
1015  }
1016  }
1017  else
1018  {
1019  FreePool(UniqueId);
1020  }
1021  }
1022  }
1023 
1024  /* Find info about the device associated associated with the mount point */
1025  KeWaitForSingleObject(&DeviceExtension->DeviceLock, Executive, KernelMode, FALSE, NULL);
1026  Status = FindDeviceInfo(DeviceExtension, &SymbolicName, FALSE, &ListDeviceInfo);
1027  if (!NT_SUCCESS(Status))
1028  {
1029  FailedFinding = TRUE;
1031  }
1032  else
1033  {
1034  /* Associate the device with the currrent DB */
1035  AssociatedDevice = AllocatePool(sizeof(ASSOCIATED_DEVICE_ENTRY));
1036  if (AssociatedDevice == NULL)
1037  {
1039  }
1040  else
1041  {
1042  AssociatedDevice->DeviceInformation = DeviceInformation;
1043  AssociatedDevice->String.Length = VolumeName.Length;
1044  AssociatedDevice->String.MaximumLength = VolumeName.MaximumLength;
1045  AssociatedDevice->String.Buffer = VolumeName.Buffer;
1046  InsertTailList(&ListDeviceInfo->AssociatedDevicesHead, &AssociatedDevice->AssociatedDevicesEntry);
1047  }
1048 
1049  /* If we don't have to skip notifications, notify */
1050  if (!ListDeviceInfo->SkipNotifications)
1051  {
1052  PostOnlineNotification(DeviceExtension, &ListDeviceInfo->SymbolicName);
1053  }
1054  }
1055 
1056  KeReleaseSemaphore(&DeviceExtension->DeviceLock, IO_NO_INCREMENT, 1, FALSE);
1057  }
1058 
1059  /* We don't need mount points any longer */
1060  ZwClose(Handle);
1061 
1062  /* Look for the DB again */
1063  KeWaitForSingleObject(&DeviceExtension->DeviceLock, Executive, KernelMode, FALSE, NULL);
1064  for (Entry = DeviceExtension->DeviceListHead.Flink;
1065  Entry != &DeviceExtension->DeviceListHead;
1066  Entry = Entry->Flink)
1067  {
1068  ListDeviceInfo = CONTAINING_RECORD(Entry, DEVICE_INFORMATION, DeviceListEntry);
1069  if (ListDeviceInfo == DeviceInformation)
1070  {
1071  break;
1072  }
1073  }
1074 
1075  if (Entry == &DeviceExtension->DeviceListHead)
1076  {
1077  ListDeviceInfo = NULL;
1078  }
1079 
1080  /* Start the pruning loop */
1081  Offset = 0;
1082  for (;;)
1083  {
1084  /* Get the entry */
1085  DatabaseEntry = GetRemoteDatabaseEntry(DatabaseHandle, Offset);
1086  if (DatabaseEntry == NULL)
1087  {
1088  break;
1089  }
1090 
1091  /* It's not referenced anylonger? Prune it */
1092  if (DatabaseEntry->EntryReferences == 0)
1093  {
1094  Status = DeleteRemoteDatabaseEntry(DatabaseHandle, Offset);
1095  if (!NT_SUCCESS(Status))
1096  {
1097  FreePool(DatabaseEntry);
1098  KeReleaseSemaphore(&DeviceExtension->DeviceLock, IO_NO_INCREMENT, 1, FALSE);
1099  goto CloseRDB;
1100  }
1101  }
1102  /* Update the Unique IDs to reflect the changes we might have done previously */
1103  else
1104  {
1105  if (ListDeviceInfo != NULL)
1106  {
1107  UpdateReplicatedUniqueIds(ListDeviceInfo, DatabaseEntry);
1108  }
1109 
1110  Offset += DatabaseEntry->EntrySize;
1111  }
1112 
1113  FreePool(DatabaseEntry);
1114  }
1115 
1116  /* We do have a DB now :-) */
1117  if (ListDeviceInfo != NULL && !FailedFinding)
1118  {
1119  DeviceInformation->NoDatabase = FALSE;
1120  }
1121 
1122  KeReleaseSemaphore(&DeviceExtension->DeviceLock, IO_NO_INCREMENT, 1, FALSE);
1123 
1124  goto CloseRDB;
1125 
1126 FreeUniqueId:
1127  FreePool(UniqueId);
1128 ReleaseDeviceLock:
1129  KeReleaseSemaphore(&DeviceExtension->DeviceLock, IO_NO_INCREMENT, 1, FALSE);
1130 FreeDBEntry:
1131  FreePool(DatabaseEntry);
1132 FreeVolume:
1134 CloseReparse:
1135  ZwClose(Handle);
1136 CloseRDB:
1137  CloseRemoteDatabase(DatabaseHandle);
1138 ReleaseRDS:
1139  ReleaseRemoteDatabaseSemaphore(DeviceExtension);
1140  return;
1141 }
#define FILE_GENERIC_READ
Definition: nt_native.h:653
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
USHORT UniqueIdOffset
Definition: mntmgr.h:91
#define TRUE
Definition: types.h:120
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
NTSTATUS TruncateRemoteDatabase(IN HANDLE Database, IN LONG NewSize)
Definition: database.c:91
struct _Entry Entry
Definition: kefuncs.h:640
ULONG EntryReferences
Definition: mntmgr.h:88
USHORT MaximumLength
Definition: env_spec_w32.h:370
ULONG EntrySize
Definition: mntmgr.h:87
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:54
PDEVICE_INFORMATION DeviceInformation
Definition: mntmgr.h:98
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
LONG NTSTATUS
Definition: precomp.h:26
USHORT UniqueIdLength
Definition: imports.h:138
BOOLEAN IsUniqueIdPresent(IN PDEVICE_EXTENSION DeviceExtension, IN PDATABASE_ENTRY DatabaseEntry)
Definition: uniqueid.c:221
#define DO_UNLOAD_PENDING
Definition: env_spec_w32.h:392
NTSTATUS NTAPI IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName, IN ACCESS_MASK DesiredAccess, OUT PFILE_OBJECT *FileObject, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1435
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
NTSTATUS WriteUniqueIdToMaster(IN PDEVICE_EXTENSION DeviceExtension, IN PDATABASE_ENTRY DatabaseEntry)
Definition: database.c:489
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
_In_ PVOID Parameter
Definition: ldrtypes.h:241
#define InsertTailList(ListHead, Entry)
USHORT SymbolicNameLength
Definition: mntmgr.h:90
#define FreePool(P)
Definition: mntmgr.h:154
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
UNICODE_STRING SymbolicName
Definition: mntmgr.h:48
LIST_ENTRY AssociatedDevicesEntry
Definition: mntmgr.h:97
#define FILE_SHARE_READ
Definition: compat.h:125
uint32_t ULONG_PTR
Definition: typedefs.h:63
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define IO_REPARSE_TAG_MOUNT_POINT
Definition: iotypes.h:6875
#define FILE_SYNCHRONOUS_IO_ALERT
Definition: from_kernel.h:30
HANDLE OpenRemoteDatabase(IN PDEVICE_INFORMATION DeviceInformation, IN BOOLEAN MigrateDatabase)
Definition: database.c:1836
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define UNICODE_NULL
BOOLEAN NeedsReconcile
Definition: mntmgr.h:56
BOOLEAN NoDatabase
Definition: mntmgr.h:57
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
USHORT UniqueIdLength
Definition: mntmgr.h:92
NTSTATUS FindDeviceInfo(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName, IN BOOLEAN DeviceNameGiven, OUT PDEVICE_INFORMATION *DeviceInformation)
Definition: mountmgr.c:641
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
UNICODE_STRING ReparseIndex
Definition: symlink.c:40
#define InterlockedExchangeAdd
Definition: interlocked.h:181
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 CloseRemoteDatabase(IN HANDLE Database)
Definition: database.c:82
struct _DATABASE_ENTRY DATABASE_ENTRY
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
_In_ HANDLE Handle
Definition: extypes.h:390
BOOLEAN SkipNotifications
Definition: mntmgr.h:58
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _RECONCILE_WORK_ITEM_CONTEXT * PRECONCILE_WORK_ITEM_CONTEXT
Definition: mntmgr.h:95
USHORT SymbolicNameOffset
Definition: mntmgr.h:89
* PFILE_OBJECT
Definition: iotypes.h:1955
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
Definition: mntmgr.h:85
NTSYSAPI NTSTATUS NTAPI ZwOpenFile(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _Out_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG ShareAccess, _In_ ULONG OpenOptions)
BOOLEAN NTAPI IoSetThreadHardErrorMode(IN BOOLEAN HardErrorEnabled)
Definition: error.c:707
Definition: typedefs.h:117
UNICODE_STRING String
Definition: mntmgr.h:99
#define AllocatePool(Size)
Definition: mntmgr.h:153
Status
Definition: gdiplustypes.h:24
VOID PostOnlineNotification(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName)
Definition: notify.c:145
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
struct _FileName FileName
Definition: fatprocs.h:884
NTSTATUS WriteRemoteDatabaseEntry(IN HANDLE Database, IN LONG Offset, IN PDATABASE_ENTRY Entry)
Definition: database.c:200
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
BOOLEAN Removable
Definition: mntmgr.h:54
NTSTATUS QueryVolumeName(IN HANDLE RootDirectory, IN PFILE_REPARSE_POINT_INFORMATION ReparsePointInformation, IN PUNICODE_STRING FileName OPTIONAL, OUT PUNICODE_STRING SymbolicName, OUT PUNICODE_STRING VolumeName)
Definition: database.c:1292
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
unsigned int * PULONG
Definition: retypes.h:1
VOID UpdateReplicatedUniqueIds(IN PDEVICE_INFORMATION DeviceInformation, IN PDATABASE_ENTRY DatabaseEntry)
Definition: uniqueid.c:376
UNICODE_STRING DeviceName
Definition: mntmgr.h:50
NTSTATUS WaitForRemoteDatabaseSemaphore(IN PDEVICE_EXTENSION DeviceExtension)
Definition: database.c:371
_Must_inspect_result_ _Inout_opt_ PUNICODE_STRING VolumeName
Definition: fltkernel.h:1117
WCHAR FileNameBuffer[_MAX_PATH]
Definition: framewnd.c:239
PDATABASE_ENTRY GetRemoteDatabaseEntry(IN HANDLE Database, IN LONG StartingOffset)
Definition: database.c:125
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
LIST_ENTRY AssociatedDevicesHead
Definition: mntmgr.h:47
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSTATUS QueryUniqueIdFromMaster(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicName, OUT PMOUNTDEV_UNIQUE_ID *UniqueId)
Definition: database.c:440
NTSTATUS AddRemoteDatabaseEntry(IN HANDLE Database, IN PDATABASE_ENTRY Entry)
Definition: database.c:64
VOID ReleaseRemoteDatabaseSemaphore(IN PDEVICE_EXTENSION DeviceExtension)
Definition: database.c:391
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
UCHAR UniqueId[1]
Definition: imports.h:139
base of all file and directory entries
Definition: entries.h:82
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465

Referenced by MountMgrQueryDosVolumePaths(), and ReconcileThisDatabaseWithMaster().

◆ ReleaseRemoteDatabaseSemaphore()

VOID ReleaseRemoteDatabaseSemaphore ( IN PDEVICE_EXTENSION  DeviceExtension)

Definition at line 391 of file database.c.

392 {
393  KeReleaseSemaphore(&(DeviceExtension->RemoteDatabaseLock), IO_NO_INCREMENT, 1, FALSE);
394 }
LONG NTAPI KeReleaseSemaphore(IN PKSEMAPHORE Semaphore, IN KPRIORITY Increment, IN LONG Adjustment, IN BOOLEAN Wait)
Definition: semphobj.c:54
#define IO_NO_INCREMENT
Definition: iotypes.h:566

Referenced by MountMgrDeviceControl(), MountMgrUniqueIdChangeRoutine(), and ReconcileThisDatabaseWithMasterWorker().

◆ TruncateRemoteDatabase()

NTSTATUS TruncateRemoteDatabase ( IN HANDLE  Database,
IN LONG  NewSize 
)

Definition at line 91 of file database.c.

93 {
97  FILE_ALLOCATION_INFORMATION Allocation;
98 
99  EndOfFile.EndOfFile.QuadPart = NewSize;
100  Allocation.AllocationSize.QuadPart = NewSize;
101 
102  /* First set EOF */
103  Status = ZwSetInformationFile(Database,
104  &IoStatusBlock,
105  &EndOfFile,
108  if (NT_SUCCESS(Status))
109  {
110  /* And then, properly set allocation information */
111  Status = ZwSetInformationFile(Database,
112  &IoStatusBlock,
113  &Allocation,
116  }
117 
118  return Status;
119 }
LONG NTSTATUS
Definition: precomp.h:26
LARGE_INTEGER AllocationSize
Definition: winternl.h:688
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
Status
Definition: gdiplustypes.h:24
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
LONGLONG QuadPart
Definition: typedefs.h:112

Referenced by DeleteRemoteDatabaseEntry(), GetRemoteDatabaseEntry(), and ReconcileThisDatabaseWithMasterWorker().

◆ WaitForRemoteDatabaseSemaphore()

NTSTATUS WaitForRemoteDatabaseSemaphore ( IN PDEVICE_EXTENSION  DeviceExtension)

Definition at line 371 of file database.c.

372 {
375 
376  /* Wait for 7 minutes */
377  Timeout.QuadPart = 0xFA0A1F00;
378  Status = KeWaitForSingleObject(&(DeviceExtension->RemoteDatabaseLock), Executive, KernelMode, FALSE, &Timeout);
379  if (Status != STATUS_TIMEOUT)
380  {
381  return Status;
382  }
383 
384  return STATUS_IO_TIMEOUT;
385 }
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
Status
Definition: gdiplustypes.h:24
static ULONG Timeout
Definition: ping.c:61
#define STATUS_IO_TIMEOUT
Definition: udferr_usr.h:163

Referenced by MountMgrDeviceControl(), MountMgrUniqueIdChangeRoutine(), and ReconcileThisDatabaseWithMasterWorker().

◆ WorkerThread()

VOID NTAPI WorkerThread ( IN PDEVICE_OBJECT  DeviceObject,
IN PVOID  Context 
)

Definition at line 1148 of file database.c.

1150 {
1151  ULONG i;
1152  KEVENT Event;
1153  KIRQL OldIrql;
1154  NTSTATUS Status;
1155  HANDLE SafeEvent;
1158  PRECONCILE_WORK_ITEM WorkItem;
1159  PDEVICE_EXTENSION DeviceExtension;
1161 
1163 
1165  &SafeVolumes,
1167  NULL,
1168  NULL);
1170  Timeout.QuadPart = -10000000LL; /* Wait for 1 second */
1171 
1172  /* Wait as long as possible for clearance from autochk
1173  * We will write remote databases only if it is safe
1174  * to access volumes.
1175  * First, given we start before SMSS, wait for the
1176  * event creation.
1177  */
1178  i = 0;
1179  do
1180  {
1181  /* If we started to shutdown, stop waiting forever and jump to last attempt */
1182  if (Unloading)
1183  {
1184  i = 999;
1185  }
1186  else
1187  {
1188  /* Attempt to open the event */
1190  if (NT_SUCCESS(Status))
1191  {
1192  break;
1193  }
1194 
1195  /* Wait a bit to give SMSS a chance to create the event */
1197  }
1198 
1199  ++i;
1200  }
1201  while (i < 1000);
1202 
1203  /* We managed to open the event, wait until autochk signals it */
1204  if (i < 1000)
1205  {
1206  do
1207  {
1208  Status = ZwWaitForSingleObject(SafeEvent, FALSE, &Timeout);
1209  }
1210  while (Status == STATUS_TIMEOUT && !Unloading);
1211 
1212  ZwClose(SafeEvent);
1213  }
1214 
1215  DeviceExtension = Context;
1216 
1217  InterlockedExchange(&(DeviceExtension->WorkerThreadStatus), 1);
1218 
1219  /* Acquire workers lock */
1220  KeWaitForSingleObject(&(DeviceExtension->WorkerSemaphore), Executive, KernelMode, FALSE, NULL);
1221 
1222  KeAcquireSpinLock(&(DeviceExtension->WorkerLock), &OldIrql);
1223 
1224  /* Ensure there are workers */
1225  while (!IsListEmpty(&(DeviceExtension->WorkerQueueListHead)))
1226  {
1227  /* Unqueue a worker */
1228  Entry = RemoveHeadList(&(DeviceExtension->WorkerQueueListHead));
1229  WorkItem = CONTAINING_RECORD(Entry,
1231  WorkerQueueListEntry);
1232 
1233  KeReleaseSpinLock(&(DeviceExtension->WorkerLock), OldIrql);
1234 
1235  /* Call it */
1236  WorkItem->WorkerRoutine(WorkItem->Context);
1237 
1238  IoFreeWorkItem(WorkItem->WorkItem);
1239  FreePool(WorkItem);
1240 
1241  if (InterlockedDecrement(&(DeviceExtension->WorkerReferences)) < 0)
1242  {
1243  return;
1244  }
1245 
1246  KeWaitForSingleObject(&(DeviceExtension->WorkerSemaphore), Executive, KernelMode, FALSE, NULL);
1247  KeAcquireSpinLock(&(DeviceExtension->WorkerLock), &OldIrql);
1248  }
1249  KeReleaseSpinLock(&(DeviceExtension->WorkerLock), OldIrql);
1250 
1251  InterlockedDecrement(&(DeviceExtension->WorkerReferences));
1252 
1253  /* Reset event */
1255 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define LL
Definition: tui.h:85
struct _Entry Entry
Definition: kefuncs.h:640
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
NTSYSCALLAPI NTSTATUS NTAPI ZwOpenEvent(_Out_ PHANDLE EventHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes)
UNICODE_STRING SafeVolumes
Definition: symlink.c:38
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
#define FreePool(P)
Definition: mntmgr.h:154
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
UCHAR KIRQL
Definition: env_spec_w32.h:591
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:435
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
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define InterlockedDecrement
Definition: armddk.h:52
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
Definition: typedefs.h:117
#define InterlockedExchange
Definition: armddk.h:54
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
static ULONG Timeout
Definition: ping.c:61
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
PIO_WORKITEM WorkItem
Definition: mntmgr.h:124
struct tagContext Context
Definition: acpixf.h:1030
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
PWORKER_THREAD_ROUTINE WorkerRoutine
Definition: mntmgr.h:125
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
base of all file and directory entries
Definition: entries.h:82
KEVENT UnloadEvent
Definition: mountmgr.c:41

Referenced by QueueWorkItem().

◆ WriteRemoteDatabaseEntry()

NTSTATUS WriteRemoteDatabaseEntry ( IN HANDLE  Database,
IN LONG  Offset,
IN PDATABASE_ENTRY  Entry 
)

Definition at line 200 of file database.c.

203 {
207 
208  ByteOffset.QuadPart = Offset;
209  Status = ZwWriteFile(Database,
210  NULL,
211  NULL,
212  NULL,
213  &IoStatusBlock,
214  Entry,
215  Entry->EntrySize,
216  &ByteOffset,
217  NULL);
218  if (NT_SUCCESS(Status))
219  {
220  if (IoStatusBlock.Information < Entry->EntrySize)
221  {
223  }
224  }
225 
226  return Status;
227 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONG NTSTATUS
Definition: precomp.h:26
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:24
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
base of all file and directory entries
Definition: entries.h:82
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:716

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

◆ WriteUniqueIdToMaster()

NTSTATUS WriteUniqueIdToMaster ( IN PDEVICE_EXTENSION  DeviceExtension,
IN PDATABASE_ENTRY  DatabaseEntry 
)

Definition at line 489 of file database.c.

491 {
494  PLIST_ENTRY NextEntry;
495  UNICODE_STRING SymbolicString;
496  PDEVICE_INFORMATION DeviceInformation;
497 
498  /* Create symbolic name from database entry */
499  SymbolicName = AllocatePool(DatabaseEntry->SymbolicNameLength + sizeof(WCHAR));
500  if (!SymbolicName)
501  {
503  }
504 
506  (PVOID)((ULONG_PTR)DatabaseEntry + DatabaseEntry->SymbolicNameOffset),
507  DatabaseEntry->SymbolicNameLength);
508  SymbolicName[DatabaseEntry->SymbolicNameLength / sizeof(WCHAR)] = UNICODE_NULL;
509 
510  /* Associate the unique ID with the name from remote database */
512  DatabasePath,
513  SymbolicName,
514  REG_BINARY,
515  (PVOID)((ULONG_PTR)DatabaseEntry + DatabaseEntry->UniqueIdOffset),
516  DatabaseEntry->UniqueIdLength);
518 
519  /* Reget symbolic name */
520  SymbolicString.Length = DatabaseEntry->SymbolicNameLength;
521  SymbolicString.MaximumLength = DatabaseEntry->SymbolicNameLength;
522  SymbolicString.Buffer = (PVOID)((ULONG_PTR)DatabaseEntry + DatabaseEntry->SymbolicNameOffset);
523 
524  /* Find the device using this unique ID */
525  for (NextEntry = DeviceExtension->DeviceListHead.Flink;
526  NextEntry != &(DeviceExtension->DeviceListHead);
527  NextEntry = NextEntry->Flink)
528  {
529  DeviceInformation = CONTAINING_RECORD(NextEntry,
531  DeviceListEntry);
532 
533  if (DeviceInformation->UniqueId->UniqueIdLength != DatabaseEntry->UniqueIdLength)
534  {
535  continue;
536  }
537 
538  if (RtlCompareMemory((PVOID)((ULONG_PTR)DatabaseEntry + DatabaseEntry->UniqueIdOffset),
539  DeviceInformation->UniqueId->UniqueId,
540  DatabaseEntry->UniqueIdLength) == DatabaseEntry->UniqueIdLength)
541  {
542  break;
543  }
544  }
545 
546  /* If found, create a mount point */
547  if (NextEntry != &(DeviceExtension->DeviceListHead))
548  {
549  MountMgrCreatePointWorker(DeviceExtension, &SymbolicString, &(DeviceInformation->DeviceName));
550  }
551 
552  return Status;
553 }
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
_In_ PNDIS_STRING _In_ PNDIS_STRING SymbolicName
Definition: ndis.h:4676
LONG NTSTATUS
Definition: precomp.h:26
USHORT UniqueIdLength
Definition: imports.h:138
uint16_t * PWCHAR
Definition: typedefs.h:54
NTSTATUS MountMgrCreatePointWorker(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING SymbolicLinkName, IN PUNICODE_STRING DeviceName)
Definition: point.c:35
#define FreePool(P)
Definition: mntmgr.h:154
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define UNICODE_NULL
void * PVOID
Definition: retypes.h:9
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
__wchar_t WCHAR
Definition: xmlstorage.h:180
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG, PCWSTR, PCWSTR, ULONG, PVOID, ULONG)
Definition: typedefs.h:117
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define AllocatePool(Size)
Definition: mntmgr.h:153
PWSTR DatabasePath
Definition: database.c:31
Status
Definition: gdiplustypes.h:24
UNICODE_STRING DeviceName
Definition: mntmgr.h:50
PMOUNTDEV_UNIQUE_ID UniqueId
Definition: mntmgr.h:49
UCHAR UniqueId[1]
Definition: imports.h:139
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465

Referenced by ReconcileThisDatabaseWithMasterWorker().

Variable Documentation

◆ DatabasePath

◆ OfflinePath

PWSTR OfflinePath = L"\\Registry\\Machine\\System\\MountedDevices\\Offline"

Definition at line 32 of file database.c.

Referenced by IsOffline().

◆ RemoteDatabase

UNICODE_STRING RemoteDatabase = RTL_CONSTANT_STRING(L"\\System Volume Information\\MountPointManagerRemoteDatabase")