mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[MOUNTMGR] Fix initial sending of device online notification (#7030)
1. MountMgrMountedDeviceArrival(): Fix the conditions under which the device's online notifications are skipped (SkipNotifications == TRUE) and fix the code comments. Now, things make much more sense: online notifications are skipped when the device is already offline or is a legacy (NT <= 4) fault-tolerant volume (see point 2 below), or is NOT mounted (doesn't have a drive letter). Previously, we were sending an online notification if the device was NOT mounted (why?!...) or if it was deemed as "valid" (wrongly determined, see point 2 below). 2. QueryDeviceInformation(): * The usage of the "Valid" parameter didn't make much sense. Indeed, when a partition/volume device is reported to the Mount Manager, it's already valid. (Also, setting "Valid" to TRUE only in the case of an MBR partition while ignoring GPT ones, and resetting it to FALSE if IOCTL_STORAGE_GET_DEVICE_NUMBER returned success, pointed to something incorrect was going on.) Instead, what we are checking here is whether the device is a legacy fault-tolerant volume: such volume can only reside on an MBR disk, have the expected partition type, and does not really reside on a specific storage device (hence the check for IOCTL_STORAGE_GET_DEVICE_NUMBER returning failure). * Take also the opportunity to SAL2-ify the function.
This commit is contained in:
parent
5f26356079
commit
7e89227a00
2 changed files with 46 additions and 73 deletions
|
@ -225,15 +225,14 @@ MountMgrFreeDeadDeviceInfo(
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
QueryDeviceInformation(
|
QueryDeviceInformation(
|
||||||
IN PUNICODE_STRING SymbolicName,
|
_In_ PUNICODE_STRING SymbolicName,
|
||||||
OUT PUNICODE_STRING DeviceName OPTIONAL,
|
_Out_opt_ PUNICODE_STRING DeviceName,
|
||||||
OUT PMOUNTDEV_UNIQUE_ID * UniqueId OPTIONAL,
|
_Out_opt_ PMOUNTDEV_UNIQUE_ID* UniqueId,
|
||||||
OUT PBOOLEAN Removable OPTIONAL,
|
_Out_opt_ PBOOLEAN Removable,
|
||||||
OUT PBOOLEAN GptDriveLetter OPTIONAL,
|
_Out_opt_ PBOOLEAN GptDriveLetter,
|
||||||
OUT PBOOLEAN HasGuid OPTIONAL,
|
_Out_opt_ PBOOLEAN HasGuid,
|
||||||
IN OUT LPGUID StableGuid OPTIONAL,
|
_Inout_opt_ LPGUID StableGuid,
|
||||||
OUT PBOOLEAN Valid OPTIONAL
|
_Out_opt_ PBOOLEAN IsFT);
|
||||||
);
|
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
HasDriveLetter(
|
HasDriveLetter(
|
||||||
|
|
|
@ -271,14 +271,15 @@ CreateNewDriveLetterName(OUT PUNICODE_STRING DriveLetter,
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
QueryDeviceInformation(
|
||||||
OUT PUNICODE_STRING DeviceName OPTIONAL,
|
_In_ PUNICODE_STRING SymbolicName,
|
||||||
OUT PMOUNTDEV_UNIQUE_ID * UniqueId OPTIONAL,
|
_Out_opt_ PUNICODE_STRING DeviceName,
|
||||||
OUT PBOOLEAN Removable OPTIONAL,
|
_Out_opt_ PMOUNTDEV_UNIQUE_ID* UniqueId,
|
||||||
OUT PBOOLEAN GptDriveLetter OPTIONAL,
|
_Out_opt_ PBOOLEAN Removable,
|
||||||
OUT PBOOLEAN HasGuid OPTIONAL,
|
_Out_opt_ PBOOLEAN GptDriveLetter,
|
||||||
IN OUT LPGUID StableGuid OPTIONAL,
|
_Out_opt_ PBOOLEAN HasGuid,
|
||||||
OUT PBOOLEAN Valid OPTIONAL)
|
_Inout_opt_ LPGUID StableGuid,
|
||||||
|
_Out_opt_ PBOOLEAN IsFT)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
USHORT Size;
|
USHORT Size;
|
||||||
|
@ -334,15 +335,7 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
||||||
&GptAttributes,
|
&GptAttributes,
|
||||||
sizeof(GptAttributes),
|
sizeof(GptAttributes),
|
||||||
NULL);
|
NULL);
|
||||||
#if 0
|
/* Failure isn't major */
|
||||||
if (Status == STATUS_INSUFFICIENT_RESOURCES)
|
|
||||||
{
|
|
||||||
ObDereferenceObject(DeviceObject);
|
|
||||||
ObDereferenceObject(FileObject);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* In case of failure, don't fail, that's no vital */
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
|
@ -355,15 +348,16 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If caller wants to know if there's valid contents */
|
/* If caller wants to know if this is a FT volume */
|
||||||
if (Valid)
|
if (IsFT)
|
||||||
{
|
{
|
||||||
/* Suppose it's not OK */
|
/* Suppose it's not */
|
||||||
*Valid = FALSE;
|
*IsFT = FALSE;
|
||||||
|
|
||||||
|
/* FT volume can't be removable */
|
||||||
if (!IsRemovable)
|
if (!IsRemovable)
|
||||||
{
|
{
|
||||||
/* Query partitions information */
|
/* Query partition information */
|
||||||
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_DISK_GET_PARTITION_INFO_EX,
|
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_DISK_GET_PARTITION_INFO_EX,
|
||||||
DeviceObject,
|
DeviceObject,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -371,28 +365,22 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
||||||
&PartitionInfo,
|
&PartitionInfo,
|
||||||
sizeof(PartitionInfo),
|
sizeof(PartitionInfo),
|
||||||
NULL);
|
NULL);
|
||||||
#if 0
|
/* Failure isn't major */
|
||||||
if (Status == STATUS_INSUFFICIENT_RESOURCES)
|
|
||||||
{
|
|
||||||
ObDereferenceObject(DeviceObject);
|
|
||||||
ObDereferenceObject(FileObject);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* Once again here, failure isn't major */
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
/* Verify we know something in */
|
/* Check if this is a FT volume */
|
||||||
else if (PartitionInfo.PartitionStyle == PARTITION_STYLE_MBR &&
|
else if ((PartitionInfo.PartitionStyle == PARTITION_STYLE_MBR) &&
|
||||||
IsRecognizedPartition(PartitionInfo.Mbr.PartitionType))
|
IsFTPartition(PartitionInfo.Mbr.PartitionType))
|
||||||
{
|
{
|
||||||
*Valid = TRUE;
|
*IsFT = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* It looks correct, ensure it is & query device number */
|
/* It looks like a FT volume. Verify it is really one by checking
|
||||||
if (*Valid)
|
* that it does NOT lie on a specific storage device (i.e. it is
|
||||||
|
* not a basic volume). */
|
||||||
|
if (*IsFT)
|
||||||
{
|
{
|
||||||
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_STORAGE_GET_DEVICE_NUMBER,
|
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_STORAGE_GET_DEVICE_NUMBER,
|
||||||
DeviceObject,
|
DeviceObject,
|
||||||
|
@ -401,18 +389,10 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
||||||
&StorageDeviceNumber,
|
&StorageDeviceNumber,
|
||||||
sizeof(StorageDeviceNumber),
|
sizeof(StorageDeviceNumber),
|
||||||
NULL);
|
NULL);
|
||||||
#if 0
|
|
||||||
if (Status == STATUS_INSUFFICIENT_RESOURCES)
|
|
||||||
{
|
|
||||||
ObDereferenceObject(DeviceObject);
|
|
||||||
ObDereferenceObject(FileObject);
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
else
|
else
|
||||||
*Valid = FALSE;
|
*IsFT = FALSE; // Succeeded, so this cannot be a FT volume.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -890,7 +870,8 @@ MountMgrMountedDeviceArrival(IN PDEVICE_EXTENSION DeviceExtension,
|
||||||
PDEVICE_INFORMATION DeviceInformation, CurrentDevice;
|
PDEVICE_INFORMATION DeviceInformation, CurrentDevice;
|
||||||
WCHAR CSymLinkBuffer[RTL_NUMBER_OF(Cunc)], LinkTargetBuffer[MAX_PATH];
|
WCHAR CSymLinkBuffer[RTL_NUMBER_OF(Cunc)], LinkTargetBuffer[MAX_PATH];
|
||||||
UNICODE_STRING TargetDeviceName, SuggestedLinkName, DeviceName, VolumeName, DriveLetter, LinkTarget, CSymLink;
|
UNICODE_STRING TargetDeviceName, SuggestedLinkName, DeviceName, VolumeName, DriveLetter, LinkTarget, CSymLink;
|
||||||
BOOLEAN HasGuid, HasGptDriveLetter, Valid, UseOnlyIfThereAreNoOtherLinks, IsDrvLetter, IsOff, IsVolumeName, LinkError;
|
BOOLEAN HasGuid, HasGptDriveLetter, IsFT, UseOnlyIfThereAreNoOtherLinks;
|
||||||
|
BOOLEAN IsDrvLetter, IsOff, IsVolumeName, SetOnline;
|
||||||
|
|
||||||
/* New device = new structure to represent it */
|
/* New device = new structure to represent it */
|
||||||
DeviceInformation = AllocatePool(sizeof(DEVICE_INFORMATION));
|
DeviceInformation = AllocatePool(sizeof(DEVICE_INFORMATION));
|
||||||
|
@ -927,7 +908,7 @@ MountMgrMountedDeviceArrival(IN PDEVICE_EXTENSION DeviceExtension,
|
||||||
&HasGptDriveLetter,
|
&HasGptDriveLetter,
|
||||||
&HasGuid,
|
&HasGuid,
|
||||||
&StableGuid,
|
&StableGuid,
|
||||||
&Valid);
|
&IsFT);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
|
KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
|
||||||
|
@ -1151,7 +1132,7 @@ MountMgrMountedDeviceArrival(IN PDEVICE_EXTENSION DeviceExtension,
|
||||||
Status = GlobalCreateSymbolicLink(&(SymLinks[i]), &TargetDeviceName);
|
Status = GlobalCreateSymbolicLink(&(SymLinks[i]), &TargetDeviceName);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
LinkError = TRUE;
|
BOOLEAN LinkError = TRUE;
|
||||||
|
|
||||||
if ((SavedLinkInformation && !RedirectSavedLink(SavedLinkInformation, &(SymLinks[i]), &TargetDeviceName)) ||
|
if ((SavedLinkInformation && !RedirectSavedLink(SavedLinkInformation, &(SymLinks[i]), &TargetDeviceName)) ||
|
||||||
!SavedLinkInformation)
|
!SavedLinkInformation)
|
||||||
|
@ -1315,30 +1296,23 @@ MountMgrMountedDeviceArrival(IN PDEVICE_EXTENSION DeviceExtension,
|
||||||
RtlCopyMemory(NewUniqueId->UniqueId, UniqueId->UniqueId, UniqueId->UniqueIdLength);
|
RtlCopyMemory(NewUniqueId->UniqueId, UniqueId->UniqueId, UniqueId->UniqueIdLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the device is offline or valid, skip its notifications */
|
/* Skip online notifications if the device is offline or a FT volume */
|
||||||
if (IsOff || Valid)
|
if (IsOff || IsFT)
|
||||||
{
|
|
||||||
DeviceInformation->SkipNotifications = TRUE;
|
DeviceInformation->SkipNotifications = TRUE;
|
||||||
}
|
|
||||||
|
|
||||||
/* If automount is enabled or the device already mounted, set it offline */
|
/* If automount is enabled or the device was already mounted, send now
|
||||||
|
* the online notification if needed; otherwise, defer its posting */
|
||||||
if (!DeviceExtension->NoAutoMount || IsDrvLetter)
|
if (!DeviceExtension->NoAutoMount || IsDrvLetter)
|
||||||
{
|
SetOnline = !DeviceInformation->SkipNotifications;
|
||||||
IsOff = !DeviceInformation->SkipNotifications;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
SetOnline = FALSE;
|
||||||
IsOff = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Finally, release the exclusive lock */
|
/* Finally, release the exclusive lock */
|
||||||
KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
|
KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
|
||||||
|
|
||||||
/* If the device is not offline, notify its arrival */
|
/* Set the device online now if necessary */
|
||||||
if (!IsOff)
|
if (SetOnline)
|
||||||
{
|
|
||||||
SendOnlineNotification(SymbolicName);
|
SendOnlineNotification(SymbolicName);
|
||||||
}
|
|
||||||
|
|
||||||
/* If we had symlinks (from storage), free them */
|
/* If we had symlinks (from storage), free them */
|
||||||
if (SymLinks)
|
if (SymLinks)
|
||||||
|
|
Loading…
Reference in a new issue