📄 disk.c
字号:
//
// Set up an object directory to contain the objects for this
// device and all its partitions.
//
do {
WCHAR buffer[64];
UNICODE_STRING unicodeDirectoryName;
swprintf(buffer, L"\\Device\\Harddisk%d", *DeviceCount);
RtlInitUnicodeString(&unicodeDirectoryName, buffer);
InitializeObjectAttributes(&objectAttributes,
&unicodeDirectoryName,
OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
NULL,
NULL);
status = ZwCreateDirectoryObject(&handle,
DIRECTORY_ALL_ACCESS,
&objectAttributes);
(*DeviceCount)++;
} while((status == STATUS_OBJECT_NAME_COLLISION) ||
(status == STATUS_OBJECT_NAME_EXISTS));
if (!NT_SUCCESS(status)) {
DebugPrint((1, "DiskCreateFdo: Could not create directory - %lx\n",
status));
return(status);
}
//
// When this loop exits the count is inflated by one - fix that.
//
(*DeviceCount)--;
//
// Claim the device.
//
lowerDevice = IoGetAttachedDeviceReference(PhysicalDeviceObject);
status = ClassClaimDevice(lowerDevice, FALSE);
if (!NT_SUCCESS(status)) {
ZwMakeTemporaryObject(handle);
ZwClose(handle);
ObDereferenceObject(lowerDevice);
return status;
}
//
// Create a device object for this device. Each physical disk will
// have at least one device object. The required device object
// describes the entire device. Its directory path is
// \Device\HarddiskN\Partition0, where N = device number.
//
status = DiskGenerateDeviceName(TRUE,
*DeviceCount,
0,
NULL,
NULL,
&deviceName);
if(!NT_SUCCESS(status)) {
DebugPrint((1, "DiskCreateFdo - couldn't create name %lx\n",
status));
goto DiskCreateFdoExit;
}
status = ClassCreateDeviceObject(DriverObject,
deviceName,
PhysicalDeviceObject,
TRUE,
&deviceObject);
if (!NT_SUCCESS(status)) {
DebugPrint((1,
"DiskCreateFdo: Can not create device object %s\n",
ntNameBuffer));
goto DiskCreateFdoExit;
}
//
// Indicate that IRPs should include MDLs for data transfers.
//
SET_FLAG(deviceObject->Flags, DO_DIRECT_IO);
fdoExtension = deviceObject->DeviceExtension;
if(DasdAccessOnly) {
//
// Inidicate that only RAW should be allowed to mount on the root
// partition object. This ensures that a file system can't doubly
// mount on a super-floppy by mounting once on P0 and once on P1.
//
SET_FLAG(deviceObject->Vpb->Flags, VPB_RAW_MOUNT);
}
//
// Initialize lock count to zero. The lock count is used to
// disable the ejection mechanism on devices that support
// removable media. Only the lock count in the physical
// device extension is used.
//
fdoExtension->LockCount = 0;
//
// Save system disk number.
//
fdoExtension->DeviceNumber = *DeviceCount;
//
// Set the alignment requirements for the device based on the
// host adapter requirements
//
if (lowerDevice->AlignmentRequirement > deviceObject->AlignmentRequirement) {
deviceObject->AlignmentRequirement = lowerDevice->AlignmentRequirement;
}
//
// Finally, attach to the pdo
//
fdoExtension->LowerPdo = PhysicalDeviceObject;
fdoExtension->CommonExtension.LowerDeviceObject =
IoAttachDeviceToDeviceStack(
deviceObject,
PhysicalDeviceObject);
if(fdoExtension->CommonExtension.LowerDeviceObject == NULL) {
//
// Uh - oh, we couldn't attach
// cleanup and return
//
status = STATUS_UNSUCCESSFUL;
goto DiskCreateFdoExit;
}
{
PDISK_DATA diskData = fdoExtension->CommonExtension.DriverData;
//
// Initialize the partitioning lock as it may be used in the remove
// code.
//
KeInitializeEvent(&(diskData->PartitioningEvent),
SynchronizationEvent,
TRUE);
}
//
// Clear the init flag.
//
CLEAR_FLAG(deviceObject->Flags, DO_DEVICE_INITIALIZING);
//
// Store a handle to the device object directory for this disk
//
fdoExtension->DeviceDirectory = handle;
ObDereferenceObject(lowerDevice);
return STATUS_SUCCESS;
DiskCreateFdoExit:
//
// Release the device since an error occurred.
//
if (deviceObject != NULL) {
IoDeleteDevice(deviceObject);
}
//
// Delete directory and return.
//
if (!NT_SUCCESS(status)) {
ZwMakeTemporaryObject(handle);
ZwClose(handle);
}
ObDereferenceObject(lowerDevice);
return(status);
}
NTSTATUS
DiskReadWriteVerification(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
/*++
Routine Description:
I/O System entry for read and write requests to SCSI disks.
Arguments:
DeviceObject - Pointer to driver object created by system.
Irp - IRP involved.
Return Value:
NT Status
--*/
{
PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
ULONG transferByteCount = currentIrpStack->Parameters.Read.Length;
LARGE_INTEGER startingOffset;
PFUNCTIONAL_DEVICE_EXTENSION fdoExtension =
commonExtension->PartitionZeroExtension;
ULONG residualBytes;
NTSTATUS status;
//
// Verify parameters of this request.
// Check that ending sector is within partition and
// that number of bytes to transfer is a multiple of
// the sector size.
//
startingOffset.QuadPart =
(currentIrpStack->Parameters.Read.ByteOffset.QuadPart +
transferByteCount);
residualBytes = transferByteCount &
(fdoExtension->DiskGeometry.BytesPerSector - 1);
if ((startingOffset.QuadPart > commonExtension->PartitionLength.QuadPart) ||
(residualBytes != 0)) {
//
// This error may be caused by the fact that the drive is not ready.
//
status = ((PDISK_DATA) commonExtension->DriverData)->ReadyStatus;
if (!NT_SUCCESS(status)) {
//
// Flag this as a user errror so that a popup is generated.
//
DebugPrint((1, "DiskReadWriteVerification: ReadyStatus is %lx\n",
status));
IoSetHardErrorOrVerifyDevice(Irp, DeviceObject);
//
// status will keep the current error
//
ASSERT( status != STATUS_INSUFFICIENT_RESOURCES );
} else if((commonExtension->IsFdo == TRUE) && (residualBytes == 0)) {
//
// This failed because we think the physical disk is too small.
// Send it down to the drive and let the hardware decide for
// itself.
//
status = STATUS_SUCCESS;
} else {
//
// Note fastfat depends on this parameter to determine when to
// remount due to a sector size change.
//
status = STATUS_INVALID_PARAMETER;
}
} else {
//
// the drive is ready, so ok the read/write
//
status = STATUS_SUCCESS;
}
Irp->IoStatus.Status = status;
return status;
} // end DiskReadWrite()
NTSTATUS
DiskDetermineMediaTypes(
IN PDEVICE_OBJECT Fdo,
IN PIRP Irp,
IN UCHAR MediumType,
IN UCHAR DensityCode,
IN BOOLEAN MediaPresent,
IN BOOLEAN IsWritable
)
/*++
Routine Description:
Determines number of types based on the physical device, validates the user buffer
and builds the MEDIA_TYPE information.
Arguments:
DeviceObject - Pointer to functional device object created by system.
Irp - IOCTL_STORAGE_GET_MEDIA_TYPES_EX Irp.
MediumType - byte returned in mode data header.
DensityCode - byte returned in mode data block descriptor.
NumberOfTypes - pointer to be updated based on actual device.
Return Value:
Status is returned.
--*/
{
PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
PPHYSICAL_DEVICE_EXTENSION pdoExtension = Fdo->DeviceExtension;
PCOMMON_DEVICE_EXTENSION commonExtension = Fdo->DeviceExtension;
PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
PGET_MEDIA_TYPES mediaTypes = Irp->AssociatedIrp.SystemBuffer;
PDEVICE_MEDIA_INFO mediaInfo = &mediaTypes->MediaInfo[0];
BOOLEAN deviceMatched = FALSE;
PAGED_CODE();
//
// this should be checked prior to calling into this routine
// as we use the buffer as mediaTypes
//
ASSERT(irpStack->Parameters.DeviceIoControl.OutputBufferLength >=
sizeof(GET_MEDIA_TYPES));
//
// Determine if this device is removable or fixed.
//
if (!TEST_FLAG(Fdo->Characteristics, FILE_REMOVABLE_MEDIA)) {
//
// Fixed disk.
//
mediaTypes->DeviceType = FILE_DEVICE_DISK;
mediaTypes->MediaInfoCount = 1;
mediaInfo->DeviceSpecific.DiskInfo.Cylinders.QuadPart = fdoExtension->DiskGeometry.Cylinders.QuadPart;
mediaInfo->DeviceSpecific.DiskInfo.TracksPerCylinder = fdoExtension->DiskGeometry.TracksPerCylinder;
mediaInfo->DeviceSpecific.DiskInfo.SectorsPerTrack = fdoExtension->DiskGeometry.SectorsPerTrack;
mediaInfo->DeviceSpecific.DiskInfo.BytesPerSector = fdoExtension->DiskGeometry.BytesPerSector;
mediaInfo->DeviceSpecific.RemovableDiskInfo.NumberMediaSides = 1;
mediaInfo->DeviceSpecific.DiskInfo.MediaCharacteristics = (MEDIA_CURRENTLY_MOUNTED | MEDIA_READ_WRITE);
if (!IsWritable) {
SET_FLAG(mediaInfo->DeviceSpecific.DiskInfo.MediaCharacteristics,
MEDIA_WRITE_PROTECTED);
}
mediaInfo->DeviceSpecific.DiskInfo.MediaType = FixedMedia;
} else {
PUCHAR vendorId = (PUCHAR) fdoExtension->DeviceDescriptor + fdoExtension->DeviceDescriptor->VendorIdOffset;
PUCHAR productId = (PUCHAR) fdoExtension->DeviceDescriptor + fdoExtension->DeviceDescriptor->ProductIdOffset;
PUCHAR productRevision = (PUCHAR) fdoExtension->DeviceDescriptor + fdoExtension->DeviceDescriptor->ProductRevisionOffset;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -