disk.c
来自「一个类似windows」· C语言 代码 · 共 2,090 行 · 第 1/5 页
C
2,090 行
if (DeviceExtension->PartitionLength.QuadPart == 0)
return(STATUS_SUCCESS);
}
if (EndingOffset.QuadPart > DeviceExtension->PartitionLength.QuadPart)
{
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
return(STATUS_INVALID_PARAMETER);
}
return(STATUS_SUCCESS);
}
/**********************************************************************
* NAME INTERNAL
* DiskClassCreateDeviceObject
*
* DESCRIPTION
* Create the raw device and any partition devices on this drive
*
* RUN LEVEL
* PASSIVE_LEVEL
*
* ARGUMENTS
* DriverObject
* The system created driver object
* RegistryPath
* PortDeviceObject
* PortNumber
* DiskNumber
* Capabilities
* InquiryData
* InitialzationData
*
* RETURN VALUE
* STATUS_SUCCESS: Device objects for disk and partitions were created.
* Others: Failure.
*/
static NTSTATUS
DiskClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath,
IN PDEVICE_OBJECT PortDeviceObject,
IN ULONG PortNumber,
IN ULONG DiskNumber,
IN PIO_SCSI_CAPABILITIES Capabilities,
IN PSCSI_INQUIRY_DATA InquiryData,
IN PCLASS_INIT_DATA InitializationData)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING UnicodeDeviceDirName;
WCHAR NameBuffer[80];
CHAR NameBuffer2[80];
PDEVICE_OBJECT DiskDeviceObject;
PDEVICE_OBJECT PartitionDeviceObject;
PDEVICE_EXTENSION DiskDeviceExtension; /* defined in class2.h */
PDEVICE_EXTENSION PartitionDeviceExtension; /* defined in class2.h */
PDRIVE_LAYOUT_INFORMATION PartitionList = NULL;
HANDLE Handle;
PPARTITION_INFORMATION PartitionEntry;
PDISK_DATA DiskData;
ULONG PartitionNumber;
PVOID MbrBuffer;
NTSTATUS Status;
DPRINT("DiskClassCreateDeviceObject() called\n");
/* Create the harddisk device directory */
swprintf(NameBuffer,
L"\\Device\\Harddisk%lu",
DiskNumber);
RtlInitUnicodeString(&UnicodeDeviceDirName,
NameBuffer);
InitializeObjectAttributes(&ObjectAttributes,
&UnicodeDeviceDirName,
0,
NULL,
NULL);
Status = ZwCreateDirectoryObject(&Handle,
0,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
DPRINT("Could not create device dir object\n");
return(Status);
}
/* Claim the disk device */
Status = ScsiClassClaimDevice(PortDeviceObject,
InquiryData,
FALSE,
&PortDeviceObject);
if (!NT_SUCCESS(Status))
{
DPRINT("Could not claim disk device\n");
ZwMakeTemporaryObject(Handle);
ZwClose(Handle);
return(Status);
}
/* Create disk device (Partition 0) */
sprintf(NameBuffer2,
"\\Device\\Harddisk%lu\\Partition0",
DiskNumber);
Status = ScsiClassCreateDeviceObject(DriverObject,
NameBuffer2,
NULL,
&DiskDeviceObject,
InitializationData);
if (!NT_SUCCESS(Status))
{
DPRINT("ScsiClassCreateDeviceObject() failed (Status %x)\n", Status);
/* Release (unclaim) the disk */
ScsiClassClaimDevice(PortDeviceObject,
InquiryData,
TRUE,
NULL);
/* Delete the harddisk device directory */
ZwMakeTemporaryObject(Handle);
ZwClose(Handle);
return(Status);
}
DiskDeviceObject->Flags |= DO_DIRECT_IO;
if (((PINQUIRYDATA)InquiryData->InquiryData)->RemovableMedia)
{
DiskDeviceObject->Characteristics |= FILE_REMOVABLE_MEDIA;
}
DiskDeviceObject->StackSize = (CCHAR)PortDeviceObject->StackSize + 1;
if (PortDeviceObject->AlignmentRequirement > DiskDeviceObject->AlignmentRequirement)
{
DiskDeviceObject->AlignmentRequirement = PortDeviceObject->AlignmentRequirement;
}
DiskDeviceExtension = DiskDeviceObject->DeviceExtension;
DiskDeviceExtension->LockCount = 0;
DiskDeviceExtension->DeviceNumber = DiskNumber;
DiskDeviceExtension->DeviceObject = DiskDeviceObject;
DiskDeviceExtension->PortDeviceObject = PortDeviceObject;
DiskDeviceExtension->PhysicalDevice = DiskDeviceObject;
DiskDeviceExtension->PortCapabilities = Capabilities;
DiskDeviceExtension->StartingOffset.QuadPart = 0;
DiskDeviceExtension->PortNumber = (UCHAR)PortNumber;
DiskDeviceExtension->PathId = InquiryData->PathId;
DiskDeviceExtension->TargetId = InquiryData->TargetId;
DiskDeviceExtension->Lun = InquiryData->Lun;
DiskDeviceExtension->SrbFlags = 0;
/* Enable the command queueing, if it possible */
if (Capabilities->TaggedQueuing &&
((PINQUIRYDATA)InquiryData->InquiryData)->CommandQueue)
{
DiskDeviceExtension->SrbFlags |= SRB_FLAGS_QUEUE_ACTION_ENABLE;
}
/* Get timeout value */
DiskDeviceExtension->TimeOutValue =
ScsiClassQueryTimeOutRegistryValue(RegistryPath);
if (DiskDeviceExtension->TimeOutValue == 0)
DiskDeviceExtension->TimeOutValue = SCSI_DISK_TIMEOUT;
/* Initialize the lookaside list for SRBs */
ScsiClassInitializeSrbLookasideList(DiskDeviceExtension,
4);
/* zero-out disk data */
DiskData = (PDISK_DATA)(DiskDeviceExtension + 1);
RtlZeroMemory(DiskData,
sizeof(DISK_DATA));
/* Get disk geometry */
DiskDeviceExtension->DiskGeometry = ExAllocatePool(NonPagedPool,
sizeof(DISK_GEOMETRY));
if (DiskDeviceExtension->DiskGeometry == NULL)
{
DPRINT("Failed to allocate geometry buffer!\n");
ExDeleteNPagedLookasideList(&DiskDeviceExtension->SrbLookasideListHead);
IoDeleteDevice(DiskDeviceObject);
/* Release (unclaim) the disk */
ScsiClassClaimDevice(PortDeviceObject,
InquiryData,
TRUE,
NULL);
/* Delete the harddisk device directory */
ZwMakeTemporaryObject(Handle);
ZwClose(Handle);
return(STATUS_INSUFFICIENT_RESOURCES);
}
/* Allocate sense data buffer */
DiskDeviceExtension->SenseData = ExAllocatePool(NonPagedPoolCacheAligned,
SENSE_BUFFER_SIZE);
if (DiskDeviceExtension->SenseData == NULL)
{
DPRINT("Failed to allocate sense data buffer!\n");
ExFreePool (DiskDeviceExtension->DiskGeometry);
ExDeleteNPagedLookasideList(&DiskDeviceExtension->SrbLookasideListHead);
IoDeleteDevice(DiskDeviceObject);
/* Release (unclaim) the disk */
ScsiClassClaimDevice(PortDeviceObject,
InquiryData,
TRUE,
NULL);
/* Delete the harddisk device directory */
ZwMakeTemporaryObject(Handle);
ZwClose(Handle);
return(STATUS_INSUFFICIENT_RESOURCES);
}
/* Read the drive's capacity */
Status = ScsiClassReadDriveCapacity(DiskDeviceObject);
if (!NT_SUCCESS(Status) &&
(DiskDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) == 0)
{
DPRINT("Failed to retrieve drive capacity!\n");
return(STATUS_SUCCESS);
}
else
{
/* Clear the verify flag for removable media drives. */
DiskDeviceObject->Flags &= ~DO_VERIFY_VOLUME;
}
DPRINT("SectorSize: %lu\n", DiskDeviceExtension->DiskGeometry->BytesPerSector);
if ((DiskDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) &&
(DiskDeviceExtension->DiskGeometry->MediaType == RemovableMedia))
{
DiskClassCreateMediaChangeEvent(DiskDeviceExtension,DiskNumber);
if (DiskDeviceExtension->MediaChangeEvent != NULL)
{
DPRINT("Allocated media change event!\n");
}
}
/* Check disk for presence of a disk manager */
HalExamineMBR(DiskDeviceObject,
DiskDeviceExtension->DiskGeometry->BytesPerSector,
0x54,
&MbrBuffer);
if (MbrBuffer != NULL)
{
/* Start disk at sector 63 if the Ontrack Disk Manager was found */
DPRINT("Found 'Ontrack Disk Manager'!\n");
DiskDeviceExtension->DMSkew = 63;
DiskDeviceExtension->DMByteSkew =
63 * DiskDeviceExtension->DiskGeometry->BytesPerSector;
DiskDeviceExtension->DMActive = TRUE;
ExFreePool(MbrBuffer);
MbrBuffer = NULL;
}
if ((DiskDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) &&
(DiskDeviceExtension->DiskGeometry->MediaType == RemovableMedia))
{
/* Allocate a partition list for a single entry. */
PartitionList = ExAllocatePool(NonPagedPool,
sizeof(DRIVE_LAYOUT_INFORMATION));
if (PartitionList != NULL)
{
RtlZeroMemory(PartitionList,
sizeof(DRIVE_LAYOUT_INFORMATION));
PartitionList->PartitionCount = 1;
DiskData->DriveNotReady = TRUE;
Status = STATUS_SUCCESS;
}
}
else
{
/* Read partition table */
Status = IoReadPartitionTable(DiskDeviceObject,
DiskDeviceExtension->DiskGeometry->BytesPerSector,
TRUE,
&PartitionList);
DPRINT("IoReadPartitionTable(): Status: %lx\n", Status);
if ((!NT_SUCCESS(Status) || PartitionList->PartitionCount == 0) &&
DiskDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
{
if (!NT_SUCCESS(Status))
{
/* Drive is not ready. */
DPRINT("Drive not ready\n");
DiskData->DriveNotReady = TRUE;
}
else
{
ExFreePool(PartitionList);
}
/* Allocate a partition list for a single entry. */
PartitionList = ExAllocatePool(NonPagedPool,
sizeof(DRIVE_LAYOUT_INFORMATION));
if (PartitionList != NULL)
{
RtlZeroMemory(PartitionList,
sizeof(DRIVE_LAYOUT_INFORMATION));
PartitionList->PartitionCount = 1;
Status = STATUS_SUCCESS;
}
}
}
if (NT_SUCCESS(Status))
{
DPRINT("Read partition table!\n");
DPRINT(" Number of partitions: %u\n", PartitionList->PartitionCount);
/* Set disk signature */
DiskData->Signature = PartitionList->Signature;
/* Calculate MBR checksum if disk got no signature */
if (DiskData->Signature == 0)
{
if (!ScsiDiskCalcMbrCheckSum(DiskDeviceExtension,
&DiskData->MbrCheckSum))
{
DPRINT("MBR checksum calculation failed for disk %lu\n",
DiskDeviceExtension->DeviceNumber);
}
else
{
DPRINT("MBR checksum for disk %lu is %lx\n",
DiskDeviceExtension->DeviceNumber,
DiskData->MbrCheckSum);
}
}
else
{
DPRINT("Signature on disk %lu is %lx\n",
DiskDeviceExtension->DeviceNumber,
DiskData->Signature);
}
/* Update disk geometry if disk is visible to the BIOS */
ScsiDiskUpdateFixedDiskGeometry(DiskDeviceExtension);
for (PartitionNumber = 0; PartitionNumber < PartitionList->PartitionCount; PartitionNumber++)
{
PartitionEntry = &PartitionList->PartitionEntry[PartitionNumber];
DPRINT("Partition %02ld: nr: %d boot: %1x type: %x offset: %I64d size: %I64d\n",
PartitionNumber,
PartitionEntry->PartitionNumber,
PartitionEntry->BootIndicator,
PartitionEntry->PartitionType,
PartitionEntry->StartingOffset.QuadPart /
DiskDeviceExtension->DiskGeometry->BytesPerSector,
PartitionEntry->PartitionLength.QuadPart /
DiskDeviceExtension->DiskGeometry->BytesPerSector);
/* Create partition device object */
sprintf(NameBuffer2,
"\\Device\\Harddisk%lu\\Partition%lu",
DiskNumber,
PartitionNumber + 1);
Status = ScsiClassCreateDeviceObject(DriverObject,
NameBuffer2,
DiskDeviceObject,
&PartitionDeviceObject ,
InitializationData);
DPRINT("ScsiClassCreateDeviceObject(): Status %x\n", Status);
if (NT_SUCCESS(Status))
{
PartitionDeviceObject->Flags = DiskDeviceObject->Flags;
PartitionDeviceObject->Characteristics = DiskDeviceObject->Characteristics;
PartitionDeviceObject->StackSize = DiskDeviceObject->StackSize;
PartitionDeviceObject->AlignmentRequirement = DiskDeviceObject->AlignmentRequirement;
PartitionDeviceExtension = PartitionDeviceObject->DeviceExtension;
PartitionDeviceExtension->SenseData = DiskDeviceExtension->SenseData;
PartitionDeviceExtension->LockCount = 0;
PartitionDeviceExtension->DeviceNumber = DiskNumber;
PartitionDeviceExtension->DeviceObject = PartitionDeviceObject;
PartitionDeviceExtension->PortDeviceObject = PortDeviceObject;
PartitionDeviceExtension->DiskGeometry = DiskDeviceExtension->DiskGeometry;
PartitionDeviceExtension->PhysicalDevice = DiskDeviceExtension->PhysicalDevice;
PartitionDeviceExtension->PortCapabilities = Capabilities;
PartitionDeviceExtension->StartingOffset.QuadPart =
PartitionEntry->StartingOffset.QuadPart;
PartitionDeviceExtension->PartitionLength.QuadPart =
PartitionEntry->PartitionLength.QuadPart;
PartitionDeviceExtension->DMSkew = DiskDeviceExtension->DMSkew;
PartitionDeviceExtension->DMByteSkew = DiskDeviceExtension->DMByteSkew;
PartitionDeviceExtension->DMActive = DiskDeviceExtension->DMActive;
PartitionDeviceExtension->PortNumber = (UCHAR)PortNumber;
PartitionDeviceExtension->PathId = InquiryData->PathId;
PartitionDeviceExtension->TargetId = InquiryData->TargetId;
PartitionDeviceExtension->Lun = InquiryData->Lun;
PartitionDeviceExtension->SectorShift = DiskDeviceExtension->SectorShift;
PartitionDeviceExtension->TimeOutValue = SCSI_DISK_TIMEOUT;
/* Initialize lookaside list for SRBs */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?