📄 disk.c
字号:
//
deviceExtension->StartingOffset.QuadPart = (LONGLONG)(0);
//
// TargetId/LUN describes a device location on the SCSI bus.
// This information comes from the inquiry buffer.
//
deviceExtension->PortNumber = (UCHAR)PortNumber;
deviceExtension->PathId = pathId;
deviceExtension->TargetId = targetId;
deviceExtension->Lun = lun;
//
// Set timeout value in seconds.
//
timeOut = ScsiClassQueryTimeOutRegistryValue(RegistryPath);
if (timeOut) {
deviceExtension->TimeOutValue = timeOut;
} else {
deviceExtension->TimeOutValue = SCSI_DISK_TIMEOUT;
}
//
// Back pointer to device object.
//
deviceExtension->DeviceObject = deviceObject;
//
// If this is a removable device, then make sure it is not a floppy.
// Perform a mode sense command to determine the media type. Note
// IsFloppyDevice also checks for write cache enabled.
//
if (IsFloppyDevice(deviceObject) && deviceObject->Characteristics & FILE_REMOVABLE_MEDIA &&
(((PINQUIRYDATA)LunInfo->InquiryData)->DeviceType == DIRECT_ACCESS_DEVICE)) {
status = STATUS_NO_SUCH_DEVICE;
goto CreateDiskDeviceObjectsExit;
}
DisableWriteCache(deviceObject,LunInfo);
writeCache = deviceExtension->DeviceFlags & DEV_WRITE_CACHE;
//
// NOTE: At this point one device object has been successfully created.
// from here on out return success.
//
//
// Do READ CAPACITY. This SCSI command
// returns the number of bytes on a device.
// Device extension is updated with device size.
//
status = ScsiClassReadDriveCapacity(deviceObject);
//
// If the read capcity failed then just return, unless this is a
// removable disk where a device object partition needs to be created.
//
if (!NT_SUCCESS(status) &&
!(deviceObject->Characteristics & FILE_REMOVABLE_MEDIA)) {
DebugPrint((1,
"CreateDiskDeviceObjects: Can't read capacity for device %s\n",
ntNameBuffer));
return(STATUS_SUCCESS);
} else {
//
// Make sure the volume verification bit is off so that
// IoReadPartitionTable will work.
//
deviceObject->Flags &= ~DO_VERIFY_VOLUME;
}
//
// Set up sector size fields.
//
// Stack variables will be used to update
// the partition device extensions.
//
// The device extension field SectorShift is
// used to calculate sectors in I/O transfers.
//
// The DiskGeometry structure is used to service
// IOCTls used by the format utility.
//
bytesPerSector = diskGeometry->BytesPerSector;
//
// Make sure sector size is not zero.
//
if (bytesPerSector == 0) {
//
// Default sector size for disk is 512.
//
bytesPerSector = diskGeometry->BytesPerSector = 512;
}
sectorShift = deviceExtension->SectorShift;
//
// Set pointer to disk data area that follows device extension.
//
diskData = (PDISK_DATA)(deviceExtension + 1);
//
// Determine is DM Driver is loaded on an IDE drive that is
// under control of Atapi - this could be either a crashdump or
// an Atapi device is sharing the controller with an IDE disk.
//
HalExamineMBR(deviceExtension->DeviceObject,
deviceExtension->DiskGeometry->BytesPerSector,
(ULONG)0x54,
(PVOID)&dmSkew);
if (dmSkew) {
//
// Update the device extension, so that the call to IoReadPartitionTable
// will get the correct information. Any I/O to this disk will have
// to be skewed by *dmSkew sectors aka DMByteSkew.
//
deviceExtension->DMSkew = *dmSkew;
deviceExtension->DMActive = TRUE;
deviceExtension->DMByteSkew = deviceExtension->DMSkew * bytesPerSector;
//
// Save away the infomation that we need, since this deviceExtension will soon be
// blown away.
//
dmActive = TRUE;
dmByteSkew = deviceExtension->DMByteSkew;
}
//
// Create objects for all the partitions on the device.
//
status = IoReadPartitionTable(deviceObject,
deviceExtension->DiskGeometry->BytesPerSector,
TRUE,
(PVOID)&partitionList);
//
// If the I/O read partition table failed and this is a removable device,
// then fix up the partition list to make it look like there is one
// zero length partition.
//
if ((!NT_SUCCESS(status) || partitionList->PartitionCount == 0) &&
deviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
if (!NT_SUCCESS(status)) {
//
// Remember this disk is not ready.
//
diskData->DriveNotReady = TRUE;
} else {
//
// Free the partition list allocated by IoReadPartitionTable.
//
ExFreePool(partitionList);
}
//
// Allocate and zero a partition list.
//
partitionList = ExAllocatePool(NonPagedPool, sizeof(*partitionList ));
if (partitionList != NULL) {
RtlZeroMemory( partitionList, sizeof( *partitionList ));
//
// Set the partition count to one and the status to success
// so one device object will be created. Set the partition type
// to a bogus value.
//
partitionList->PartitionCount = 1;
status = STATUS_SUCCESS;
}
}
if (NT_SUCCESS(status)) {
//
// Record disk signature.
//
diskData->Signature = partitionList->Signature;
//
// If disk signature is zero, then calculate the MBR checksum.
//
if (!diskData->Signature) {
if (!CalculateMbrCheckSum(deviceExtension,
&diskData->MbrCheckSum)) {
DebugPrint((1,
"SCSIDISK: Can't calculate MBR checksum for disk %x\n",
deviceExtension->DeviceNumber));
} else {
DebugPrint((2,
"SCSIDISK: MBR checksum for disk %x is %x\n",
deviceExtension->DeviceNumber,
diskData->MbrCheckSum));
}
}
//
// Check the registry and determine if the BIOS knew about this drive. If
// it did then update the geometry with the BIOS information.
//
UpdateGeometry(deviceExtension);
//
// Create device objects for the device partitions (if any).
// PartitionCount includes physical device partition 0,
// so only one partition means no objects to create.
//
DebugPrint((2,
"CreateDiskDeviceObjects: Number of partitions is %d\n",
partitionList->PartitionCount));
for (partitionNumber = 0; partitionNumber <
partitionList->PartitionCount; partitionNumber++) {
//
// Create partition object and set up partition parameters.
//
sprintf(ntNameBuffer,
"\\Device\\Harddisk%lu\\Partition%lu",
*DeviceCount,
partitionNumber + 1);
DebugPrint((2,
"CreateDiskDeviceObjects: Create device object %s\n",
ntNameBuffer));
status = ScsiClassCreateDeviceObject(DriverObject,
ntNameBuffer,
physicalDevice,
&deviceObject,
InitData);
if (!NT_SUCCESS(status)) {
DebugPrint((1, "CreateDiskDeviceObjects: Can't create device object for %s\n", ntNameBuffer));
break;
}
//
// Set up device object fields.
//
deviceObject->Flags |= DO_DIRECT_IO;
//
// Check if this is during initialization. If not indicate that
// system initialization already took place and this disk is ready
// to be accessed.
//
if (!RegistryPath) {
deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
}
deviceObject->StackSize = (CCHAR)PortDeviceObject->StackSize + 1;
//
// Set up device extension fields.
//
deviceExtension = deviceObject->DeviceExtension;
if (dmActive) {
//
// Restore any saved DM values.
//
deviceExtension->DMByteSkew = dmByteSkew;
deviceExtension->DMSkew = *dmSkew;
deviceExtension->DMActive = TRUE;
}
//
// Link new device extension to previous disk data
// to support dynamic partitioning.
//
diskData->NextPartition = deviceExtension;
//
// Get pointer to new disk data.
//
diskData = (PDISK_DATA)(deviceExtension + 1);
//
// Set next partition pointer to NULL in case this is the
// last partition.
//
diskData->NextPartition = NULL;
//
// Allocate spinlock for zoning for split-request completion.
//
KeInitializeSpinLock(&deviceExtension->SplitRequestSpinLock);
//
// Copy port device object pointer to device extension.
//
deviceExtension->PortDeviceObject = PortDeviceObject;
deviceExtension->PortNumber = (UCHAR)PortNumber;
//
// Set the alignment requirements for the device based on the
// host adapter requirements
//
if (PortDeviceObject->AlignmentRequirement > deviceObject->AlignmentRequirement) {
deviceObject->AlignmentRequirement = PortDeviceObject->AlignmentRequirement;
}
if (srbFlags & SRB_FLAGS_QUEUE_ACTION_ENABLE) {
numberListElements = 30;
} else {
numberListElements = 8;
}
//
// Build the lookaside list for srb's for this partition based on
// whether the adapter and disk can do tagged queueing.
//
ScsiClassInitializeSrbLookasideList(deviceExtension,
numberListElements);
deviceExtension->SrbFlags = srbFlags;
//
// Set the sense-data pointer in the device extension.
//
deviceExtension->SenseData = senseData;
deviceExtension->PortCapabilities = PortCapabilities;
deviceExtension->DiskGeometry = diskGeometry;
diskData->PartitionOrdinal = diskData->PartitionNumber = partitionNumber + 1;
diskData->PartitionType = partitionList->PartitionEntry[partitionNumber].PartitionType;
diskData->BootIndicator = partitionList->PartitionEntry[partitionNumber].BootIndicator;
DebugPrint((2, "CreateDiskDeviceObjects: Partition type is %x\n",
diskData->PartitionType));
deviceExtension->StartingOffset = partitionList->PartitionEntry[partitionNumber].StartingOffset;
deviceExtension->PartitionLength = partitionList->PartitionEntry[partitionNumber].PartitionLength;
diskData->HiddenSectors = partitionList->PartitionEntry[partitionNumber].HiddenSectors;
deviceExtension->PortNumber = (UCHAR)PortNumber;
deviceExtension->PathId = pathId;
deviceExtension->TargetId = targetId;
deviceExtension->Lun = lun;
//
// Check for removable media support.
//
if (((PINQUIRYDATA)LunInfo->InquiryData)->RemovableMedia) {
deviceObject->Characteristics |= FILE_REMOVABLE_MEDIA;
}
//
// Set timeout value in seconds.
//
deviceExtension->TimeOutValue = SCSI_DISK_TIMEOUT;
deviceExtension->DiskGeometry->BytesPerSector = bytesPerSector;
deviceExtension->SectorShift = sectorShift;
deviceExtension->DeviceObject = deviceObject;
deviceExtension->DeviceFlags |= physicalDeviceExtension->DeviceFlags;
} // end for (partitionNumber) ...
//
// Free the buffer allocated by reading the
// partition table.
//
ExFreePool(partitionList);
} else {
DebugPrint((1,
"CreateDiskDeviceObjects: IoReadPartitionTable failed\n"));
} // end if...else
return(STATUS_SUCCESS);
CreateDiskDeviceObjectsExit:
//
// Release the device since an error occurred.
//
ScsiClassClaimDevice(PortDeviceObject,
LunInfo,
TRUE,
NULL);
if (diskGeometry != NULL) {
ExFreePool(diskGeometry);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -