mirror of
https://github.com/reactos/reactos.git
synced 2024-12-26 17:14:41 +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
|
||||
QueryDeviceInformation(
|
||||
IN PUNICODE_STRING SymbolicName,
|
||||
OUT PUNICODE_STRING DeviceName OPTIONAL,
|
||||
OUT PMOUNTDEV_UNIQUE_ID * UniqueId OPTIONAL,
|
||||
OUT PBOOLEAN Removable OPTIONAL,
|
||||
OUT PBOOLEAN GptDriveLetter OPTIONAL,
|
||||
OUT PBOOLEAN HasGuid OPTIONAL,
|
||||
IN OUT LPGUID StableGuid OPTIONAL,
|
||||
OUT PBOOLEAN Valid OPTIONAL
|
||||
);
|
||||
_In_ PUNICODE_STRING SymbolicName,
|
||||
_Out_opt_ PUNICODE_STRING DeviceName,
|
||||
_Out_opt_ PMOUNTDEV_UNIQUE_ID* UniqueId,
|
||||
_Out_opt_ PBOOLEAN Removable,
|
||||
_Out_opt_ PBOOLEAN GptDriveLetter,
|
||||
_Out_opt_ PBOOLEAN HasGuid,
|
||||
_Inout_opt_ LPGUID StableGuid,
|
||||
_Out_opt_ PBOOLEAN IsFT);
|
||||
|
||||
BOOLEAN
|
||||
HasDriveLetter(
|
||||
|
|
|
@ -271,14 +271,15 @@ CreateNewDriveLetterName(OUT PUNICODE_STRING DriveLetter,
|
|||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
||||
OUT PUNICODE_STRING DeviceName OPTIONAL,
|
||||
OUT PMOUNTDEV_UNIQUE_ID * UniqueId OPTIONAL,
|
||||
OUT PBOOLEAN Removable OPTIONAL,
|
||||
OUT PBOOLEAN GptDriveLetter OPTIONAL,
|
||||
OUT PBOOLEAN HasGuid OPTIONAL,
|
||||
IN OUT LPGUID StableGuid OPTIONAL,
|
||||
OUT PBOOLEAN Valid OPTIONAL)
|
||||
QueryDeviceInformation(
|
||||
_In_ PUNICODE_STRING SymbolicName,
|
||||
_Out_opt_ PUNICODE_STRING DeviceName,
|
||||
_Out_opt_ PMOUNTDEV_UNIQUE_ID* UniqueId,
|
||||
_Out_opt_ PBOOLEAN Removable,
|
||||
_Out_opt_ PBOOLEAN GptDriveLetter,
|
||||
_Out_opt_ PBOOLEAN HasGuid,
|
||||
_Inout_opt_ LPGUID StableGuid,
|
||||
_Out_opt_ PBOOLEAN IsFT)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
USHORT Size;
|
||||
|
@ -334,15 +335,7 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
|||
&GptAttributes,
|
||||
sizeof(GptAttributes),
|
||||
NULL);
|
||||
#if 0
|
||||
if (Status == STATUS_INSUFFICIENT_RESOURCES)
|
||||
{
|
||||
ObDereferenceObject(DeviceObject);
|
||||
ObDereferenceObject(FileObject);
|
||||
return Status;
|
||||
}
|
||||
#endif
|
||||
/* In case of failure, don't fail, that's no vital */
|
||||
/* Failure isn't major */
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
|
@ -355,15 +348,16 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
|||
}
|
||||
}
|
||||
|
||||
/* If caller wants to know if there's valid contents */
|
||||
if (Valid)
|
||||
/* If caller wants to know if this is a FT volume */
|
||||
if (IsFT)
|
||||
{
|
||||
/* Suppose it's not OK */
|
||||
*Valid = FALSE;
|
||||
/* Suppose it's not */
|
||||
*IsFT = FALSE;
|
||||
|
||||
/* FT volume can't be removable */
|
||||
if (!IsRemovable)
|
||||
{
|
||||
/* Query partitions information */
|
||||
/* Query partition information */
|
||||
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_DISK_GET_PARTITION_INFO_EX,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
|
@ -371,28 +365,22 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
|||
&PartitionInfo,
|
||||
sizeof(PartitionInfo),
|
||||
NULL);
|
||||
#if 0
|
||||
if (Status == STATUS_INSUFFICIENT_RESOURCES)
|
||||
{
|
||||
ObDereferenceObject(DeviceObject);
|
||||
ObDereferenceObject(FileObject);
|
||||
return Status;
|
||||
}
|
||||
#endif
|
||||
/* Once again here, failure isn't major */
|
||||
/* Failure isn't major */
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
/* Verify we know something in */
|
||||
else if (PartitionInfo.PartitionStyle == PARTITION_STYLE_MBR &&
|
||||
IsRecognizedPartition(PartitionInfo.Mbr.PartitionType))
|
||||
/* Check if this is a FT volume */
|
||||
else if ((PartitionInfo.PartitionStyle == PARTITION_STYLE_MBR) &&
|
||||
IsFTPartition(PartitionInfo.Mbr.PartitionType))
|
||||
{
|
||||
*Valid = TRUE;
|
||||
*IsFT = TRUE;
|
||||
}
|
||||
|
||||
/* It looks correct, ensure it is & query device number */
|
||||
if (*Valid)
|
||||
/* It looks like a FT volume. Verify it is really one by checking
|
||||
* 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,
|
||||
DeviceObject,
|
||||
|
@ -401,18 +389,10 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
|||
&StorageDeviceNumber,
|
||||
sizeof(StorageDeviceNumber),
|
||||
NULL);
|
||||
#if 0
|
||||
if (Status == STATUS_INSUFFICIENT_RESOURCES)
|
||||
{
|
||||
ObDereferenceObject(DeviceObject);
|
||||
ObDereferenceObject(FileObject);
|
||||
return Status;
|
||||
}
|
||||
#endif
|
||||
if (!NT_SUCCESS(Status))
|
||||
Status = STATUS_SUCCESS;
|
||||
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;
|
||||
WCHAR CSymLinkBuffer[RTL_NUMBER_OF(Cunc)], LinkTargetBuffer[MAX_PATH];
|
||||
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 */
|
||||
DeviceInformation = AllocatePool(sizeof(DEVICE_INFORMATION));
|
||||
|
@ -927,7 +908,7 @@ MountMgrMountedDeviceArrival(IN PDEVICE_EXTENSION DeviceExtension,
|
|||
&HasGptDriveLetter,
|
||||
&HasGuid,
|
||||
&StableGuid,
|
||||
&Valid);
|
||||
&IsFT);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL);
|
||||
|
@ -1151,7 +1132,7 @@ MountMgrMountedDeviceArrival(IN PDEVICE_EXTENSION DeviceExtension,
|
|||
Status = GlobalCreateSymbolicLink(&(SymLinks[i]), &TargetDeviceName);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
LinkError = TRUE;
|
||||
BOOLEAN LinkError = TRUE;
|
||||
|
||||
if ((SavedLinkInformation && !RedirectSavedLink(SavedLinkInformation, &(SymLinks[i]), &TargetDeviceName)) ||
|
||||
!SavedLinkInformation)
|
||||
|
@ -1315,30 +1296,23 @@ MountMgrMountedDeviceArrival(IN PDEVICE_EXTENSION DeviceExtension,
|
|||
RtlCopyMemory(NewUniqueId->UniqueId, UniqueId->UniqueId, UniqueId->UniqueIdLength);
|
||||
}
|
||||
|
||||
/* If the device is offline or valid, skip its notifications */
|
||||
if (IsOff || Valid)
|
||||
{
|
||||
/* Skip online notifications if the device is offline or a FT volume */
|
||||
if (IsOff || IsFT)
|
||||
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)
|
||||
{
|
||||
IsOff = !DeviceInformation->SkipNotifications;
|
||||
}
|
||||
SetOnline = !DeviceInformation->SkipNotifications;
|
||||
else
|
||||
{
|
||||
IsOff = FALSE;
|
||||
}
|
||||
SetOnline = FALSE;
|
||||
|
||||
/* Finally, release the exclusive lock */
|
||||
KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE);
|
||||
|
||||
/* If the device is not offline, notify its arrival */
|
||||
if (!IsOff)
|
||||
{
|
||||
/* Set the device online now if necessary */
|
||||
if (SetOnline)
|
||||
SendOnlineNotification(SymbolicName);
|
||||
}
|
||||
|
||||
/* If we had symlinks (from storage), free them */
|
||||
if (SymLinks)
|
||||
|
|
Loading…
Reference in a new issue