198 lines
4.6 KiB
C
198 lines
4.6 KiB
C
/*++
|
|
|
|
Copyright (c) 2000-2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
mountvol.c
|
|
|
|
Abstract:
|
|
|
|
This module implements routines related to the mounting of a RAW volume.
|
|
|
|
--*/
|
|
|
|
#include "rawx.h"
|
|
|
|
VOID
|
|
RawxDeleteVolumeDevice(
|
|
IN PDEVICE_OBJECT VolumeDeviceObject
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine deletes an instance of a volume device object.
|
|
|
|
Arguments:
|
|
|
|
VolumeDeviceObject - Specifies the volume device object to delete.
|
|
|
|
Return Value:
|
|
|
|
Status of operation.
|
|
|
|
--*/
|
|
{
|
|
PRAW_VOLUME_EXTENSION VolumeExtension;
|
|
|
|
VolumeExtension = (PRAW_VOLUME_EXTENSION)VolumeDeviceObject->DeviceExtension;
|
|
|
|
//
|
|
// There shouldn't be any open files for this volume.
|
|
//
|
|
|
|
ASSERT(VolumeExtension->ShareAccess.OpenCount == 0);
|
|
|
|
//
|
|
// Release the reference on the target device object.
|
|
//
|
|
|
|
if (VolumeExtension->TargetDeviceObject != NULL) {
|
|
ObDereferenceObject(VolumeExtension->TargetDeviceObject);
|
|
}
|
|
|
|
//
|
|
// Delete the device object.
|
|
//
|
|
|
|
IoDeleteDevice(VolumeDeviceObject);
|
|
}
|
|
|
|
NTSTATUS
|
|
RawxMountVolume(
|
|
IN PDEVICE_OBJECT TargetDeviceObject
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called by the I/O manager to attempt to mount this file
|
|
system.
|
|
|
|
Arguments:
|
|
|
|
TargetDeviceObject - Specifies the device object to attempt to mount.
|
|
|
|
Return Value:
|
|
|
|
Status of operation.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS status;
|
|
ULONG IoControlCode;
|
|
DISK_GEOMETRY DiskGeometry;
|
|
PDEVICE_OBJECT VolumeDeviceObject;
|
|
PRAW_VOLUME_EXTENSION VolumeExtension;
|
|
|
|
VolumeDeviceObject = NULL;
|
|
|
|
RawxAcquireGlobalMutexExclusive();
|
|
|
|
//
|
|
// Get the drive geometry from the device. We don't care about the result,
|
|
// but this gives the device an opportunity to reset any state, such as the
|
|
// number of accessible bytes.
|
|
//
|
|
|
|
IoControlCode = (TargetDeviceObject->DeviceType == FILE_DEVICE_CD_ROM) ?
|
|
IOCTL_CDROM_GET_DRIVE_GEOMETRY : IOCTL_DISK_GET_DRIVE_GEOMETRY;
|
|
|
|
IoSynchronousDeviceIoControlRequest(IoControlCode, TargetDeviceObject, NULL,
|
|
0, &DiskGeometry, sizeof(DISK_GEOMETRY), NULL, FALSE);
|
|
|
|
//
|
|
// Create the volume's device object.
|
|
//
|
|
|
|
status = IoCreateDevice(&RawxDriverObject, sizeof(RAW_VOLUME_EXTENSION),
|
|
NULL, FILE_DEVICE_DISK_FILE_SYSTEM, FALSE, &VolumeDeviceObject);
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
goto CleanupAndExit;
|
|
}
|
|
|
|
//
|
|
// Increase the volume's IRP stack size for requests that we pass down to
|
|
// the target device object.
|
|
//
|
|
|
|
VolumeDeviceObject->StackSize = (UCHAR)(VolumeDeviceObject->StackSize +
|
|
TargetDeviceObject->StackSize);
|
|
|
|
//
|
|
// Ensure that the alignment for this device matches the requirements of the
|
|
// target device.
|
|
//
|
|
|
|
if (VolumeDeviceObject->AlignmentRequirement < TargetDeviceObject->AlignmentRequirement) {
|
|
VolumeDeviceObject->AlignmentRequirement = TargetDeviceObject->AlignmentRequirement;
|
|
}
|
|
|
|
//
|
|
// If the target device object supports direct I/O, then indicate that we
|
|
// can as well.
|
|
//
|
|
|
|
if (RawxIsFlagSet(TargetDeviceObject->Flags, DO_DIRECT_IO)) {
|
|
VolumeDeviceObject->Flags |= DO_DIRECT_IO;
|
|
}
|
|
|
|
//
|
|
// If the target device object supports scatter gather I/O, then indicate
|
|
// that we can as well.
|
|
//
|
|
|
|
if (RawxIsFlagSet(TargetDeviceObject->Flags, DO_SCATTER_GATHER_IO)) {
|
|
VolumeDeviceObject->Flags |= DO_SCATTER_GATHER_IO;
|
|
}
|
|
|
|
//
|
|
// Set the size of a sector for this device.
|
|
//
|
|
|
|
VolumeDeviceObject->SectorSize = TargetDeviceObject->SectorSize;
|
|
|
|
//
|
|
// Increment the reference count on the target device object since we'll be
|
|
// holding a pointer to it.
|
|
//
|
|
|
|
ObReferenceObject(TargetDeviceObject);
|
|
|
|
//
|
|
// Initialize the volume's device extension data.
|
|
//
|
|
|
|
VolumeExtension = (PRAW_VOLUME_EXTENSION)VolumeDeviceObject->DeviceExtension;
|
|
|
|
VolumeExtension->TargetDeviceObject = TargetDeviceObject;
|
|
|
|
//
|
|
// Initialize the volume's instance lock.
|
|
//
|
|
|
|
ExInitializeReadWriteLock(&VolumeExtension->VolumeMutex);
|
|
|
|
//
|
|
// The device has finished initializing and is ready to accept requests.
|
|
//
|
|
|
|
VolumeDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
|
|
|
|
//
|
|
// Connect the volume device object to the target device object and return
|
|
// success.
|
|
//
|
|
|
|
TargetDeviceObject->MountedOrSelfDevice = VolumeDeviceObject;
|
|
|
|
status = STATUS_SUCCESS;
|
|
|
|
CleanupAndExit:
|
|
RawxReleaseGlobalMutex();
|
|
|
|
return status;
|
|
}
|