- Respect DeviceIsLocked flag and Alertable in IopMountVolume

- Don't mount if the VPB is alread ymoutned or being removed
- Bugcheck the system if we failed to mount the boot partition.

svn path=/trunk/; revision=22760
This commit is contained in:
Alex Ionescu 2006-07-02 05:30:45 +00:00
parent e3ec87ef6d
commit 2dfe23b2f6

View file

@ -330,8 +330,25 @@ IopMountVolume(IN PDEVICE_OBJECT DeviceObject,
LIST_ENTRY LocalList;
ASSERT_IRQL(PASSIVE_LEVEL);
/* Check if the device isn't already locked */
if (!DeviceIsLocked)
{
/* Lock it ourselves */
Status = KeWaitForSingleObject(&DeviceObject->DeviceLock,
Executive,
KeGetPreviousMode(),
Alertable,
NULL);
if ((Status == STATUS_ALERTED) || (Status == STATUS_USER_APC))
{
/* Don't mount if we were interrupted */
return Status;
}
}
/* Acquire the FS Lock*/
KeEnterCriticalRegion();
ExAcquireResourceSharedLite(&FileSystemListLock,TRUE);
ExAcquireResourceSharedLite(&FileSystemListLock, TRUE);
/* For a mount operation, this can only be a Disk, CD-ROM or tape */
if ((DeviceObject->DeviceType == FILE_DEVICE_DISK) ||
@ -351,57 +368,90 @@ IopMountVolume(IN PDEVICE_OBJECT DeviceObject,
FsList = &IopTapeFsListHead;
}
/* Now loop the fs list until one of the file systems accepts us */
ListEntry = FsList->Flink;
while (ListEntry != FsList)
/* Make sure we weren't already mounted */
if (!(DeviceObject->Vpb->Flags & (VPB_MOUNTED | VPB_REMOVE_PENDING)))
{
/* Get the Device Object for this FS */
FileSystemDeviceObject = CONTAINING_RECORD(ListEntry,
DEVICE_OBJECT,
Queue.ListEntry);
/* If we are not allowed to mount this volume as a raw filesystem volume
then don't try this */
if (!AllowRawMount && RawFsIsRawFileSystemDeviceObject(FileSystemDeviceObject))
/* Now loop the fs list until one of the file systems accepts us */
Status = STATUS_UNSUCCESSFUL;
ListEntry = FsList->Flink;
while (ListEntry != FsList)
{
Status = STATUS_UNRECOGNIZED_VOLUME;
/* Get the Device Object for this FS */
FileSystemDeviceObject = CONTAINING_RECORD(ListEntry,
DEVICE_OBJECT,
Queue.ListEntry);
/* If we are not allowed to mount this volume as a raw filesystem volume
then don't try this */
if (!AllowRawMount && RawFsIsRawFileSystemDeviceObject(FileSystemDeviceObject))
{
Status = STATUS_UNRECOGNIZED_VOLUME;
}
else
{
Status = IopMountFileSystem(FileSystemDeviceObject, DeviceObject);
}
switch (Status)
{
case STATUS_FS_DRIVER_REQUIRED:
DevObject = FileSystemDeviceObject;
ExReleaseResourceLite(&FileSystemListLock);
IopLoadFileSystem(DevObject);
ExAcquireResourceSharedLite(&FileSystemListLock,TRUE);
/* We need to setup a local list to pickup where we left */
LocalList.Flink = FsList->Flink;
ListEntry = &LocalList;
break;
case STATUS_SUCCESS:
DeviceObject->Vpb->Flags = DeviceObject->Vpb->Flags |
VPB_MOUNTED;
ExReleaseResourceLite(&FileSystemListLock);
KeLeaveCriticalRegion();
return(STATUS_SUCCESS);
case STATUS_UNRECOGNIZED_VOLUME:
default:
/* do nothing */
break;
}
ListEntry = ListEntry->Flink;
}
else
{
Status = IopMountFileSystem(FileSystemDeviceObject, DeviceObject);
}
switch (Status)
{
case STATUS_FS_DRIVER_REQUIRED:
DevObject = FileSystemDeviceObject;
ExReleaseResourceLite(&FileSystemListLock);
IopLoadFileSystem(DevObject);
ExAcquireResourceSharedLite(&FileSystemListLock,TRUE);
/* We need to setup a local list to pickup where we left */
LocalList.Flink = FsList->Flink;
ListEntry = &LocalList;
break;
case STATUS_SUCCESS:
DeviceObject->Vpb->Flags = DeviceObject->Vpb->Flags |
VPB_MOUNTED;
ExReleaseResourceLite(&FileSystemListLock);
KeLeaveCriticalRegion();
return(STATUS_SUCCESS);
case STATUS_UNRECOGNIZED_VOLUME:
default:
/* do nothing */
break;
}
ListEntry = ListEntry->Flink;
}
else if (DeviceObject->Vpb->Flags & VPB_REMOVE_PENDING)
{
/* Someone wants to remove us */
Status = STATUS_DEVICE_DOES_NOT_EXIST;
}
else
{
/* Someone already mounted us */
Status = STATUS_SUCCESS;
}
/* Release the FS lock */
ExReleaseResourceLite(&FileSystemListLock);
KeLeaveCriticalRegion();
return(STATUS_UNRECOGNIZED_VOLUME);
/* Release the device lock if we're holding it */
if (DeviceIsLocked) KeSetEvent(&DeviceObject->DeviceLock, 0, FALSE);
/* Check if we failed to mount the boot partition */
if ((!NT_SUCCESS(Status)) &&
(DeviceObject->Flags & DO_SYSTEM_BOOT_PARTITION))
{
/* Bugcheck the system */
KeBugCheckEx(INACCESSIBLE_BOOT_DEVICE,
(ULONG_PTR)DeviceObject,
Status,
0,
0);
}
/* Return the mount status */
return Status;
}
/* PUBLIC FUNCTIONS **********************************************************/