📄 disk.c
字号:
IoDeleteDevice(DeviceExtension->Self);
Status = STATUS_NO_SUCH_DEVICE;
} else {
Status = STATUS_SUCCESS;
}
break;
case IRP_MN_CANCEL_REMOVE_DEVICE:
DeviceExtension->State = DeviceExtension->OldState;
Status = STATUS_SUCCESS;
break;
case IRP_MN_SURPRISE_REMOVAL:
DeviceExtension->OldState = DeviceExtension->State;
DeviceExtension->State = SurpriseRemovePending;
Status = STATUS_SUCCESS;
break;
default:
Status = Irp->IoStatus.Status;
}
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
NTSTATUS STDCALL DiskDispatchSCSI(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION Stack, IN PDEVICEEXTENSION DeviceExtension) {
NTSTATUS Status;
PSCSI_REQUEST_BLOCK Srb;
PCDB Cdb;
LONGLONG StartSector;
ULONG SectorCount, Temp;
LONGLONG LargeTemp;
PMODE_PARAMETER_HEADER ModeParameterHeader;
Srb = Stack->Parameters.Scsi.Srb;
Cdb = (PCDB)Srb->Cdb;
Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
Srb->ScsiStatus = SCSISTAT_GOOD;
Irp->IoStatus.Information = 0;
Status = STATUS_SUCCESS;
if (Srb->Lun == 0) {
switch (Srb->Function) {
case SRB_FUNCTION_EXECUTE_SCSI:
switch (Cdb->AsByte[0]) {
case SCSIOP_TEST_UNIT_READY:
Srb->SrbStatus = SRB_STATUS_SUCCESS;
break;
case SCSIOP_READ:
case SCSIOP_READ16:
case SCSIOP_WRITE:
case SCSIOP_WRITE16:
if (Cdb->AsByte[0] == SCSIOP_READ16 || Cdb->AsByte[0] == SCSIOP_WRITE16) {
REVERSE_BYTES_QUAD(&StartSector, &(((PCDB16)Cdb)->LogicalBlock[0]));
REVERSE_BYTES(&SectorCount, &(((PCDB16)Cdb)->TransferLength[0]));
} else {
StartSector = (Cdb->CDB10.LogicalBlockByte0 << 24) + (Cdb->CDB10.LogicalBlockByte1 << 16) + (Cdb->CDB10.LogicalBlockByte2 << 8) + Cdb->CDB10.LogicalBlockByte3;
SectorCount = (Cdb->CDB10.TransferBlocksMsb << 8) + Cdb->CDB10.TransferBlocksLsb;
}
if (StartSector >= DeviceExtension->Disk.LBADiskSize) {
DbgPrint("!! Fixed SectorCount (StartSector off disk) !!\n");
SectorCount = 0;
}
if ((StartSector + SectorCount > DeviceExtension->Disk.LBADiskSize) && SectorCount != 0) {
DbgPrint("!! Fixed SectorCount (StartSector + SectorCount off disk) !!\n");
SectorCount = (ULONG)(DeviceExtension->Disk.LBADiskSize - StartSector);
}
if (SectorCount * SECTORSIZE > Srb->DataTransferLength) {
DbgPrint("!! Fixed SectorCount (DataTransferLength too small) !!\n");
SectorCount = Srb->DataTransferLength / SECTORSIZE;
}
if (Srb->DataTransferLength % SECTORSIZE != 0) DbgPrint("!! DataTransferLength not aligned !!\n");
if (Srb->DataTransferLength > SectorCount * SECTORSIZE) DbgPrint("!! DataTransferLength too big !!\n");
Srb->DataTransferLength = SectorCount * SECTORSIZE;
Srb->SrbStatus = SRB_STATUS_SUCCESS;
if (SectorCount == 0) {
Irp->IoStatus.Information = 0;
break;
}
if ((((PUCHAR)Srb->DataBuffer - (PUCHAR)MmGetMdlVirtualAddress(Irp->MdlAddress)) + (PUCHAR)MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority)) == NULL) {
Status = STATUS_INSUFFICIENT_RESOURCES;
Irp->IoStatus.Information = 0;
break;
}
if (Cdb->AsByte[0] == SCSIOP_READ || Cdb->AsByte[0] == SCSIOP_READ16) {
return AoERequest(DeviceExtension, Read, StartSector, SectorCount, ((PUCHAR)Srb->DataBuffer - (PUCHAR)MmGetMdlVirtualAddress(Irp->MdlAddress)) + (PUCHAR)MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority), Irp);
} else {
return AoERequest(DeviceExtension, Write, StartSector, SectorCount, ((PUCHAR)Srb->DataBuffer - (PUCHAR)MmGetMdlVirtualAddress(Irp->MdlAddress)) + (PUCHAR)MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority), Irp);
}
break;
case SCSIOP_VERIFY:
case SCSIOP_VERIFY16:
if (Cdb->AsByte[0] == SCSIOP_VERIFY16) {
REVERSE_BYTES_QUAD(&StartSector, &(((PCDB16)Cdb)->LogicalBlock[0]));
REVERSE_BYTES(&SectorCount, &(((PCDB16)Cdb)->TransferLength[0]));
} else {
StartSector = (Cdb->CDB10.LogicalBlockByte0 << 24) + (Cdb->CDB10.LogicalBlockByte1 << 16) + (Cdb->CDB10.LogicalBlockByte2 << 8) + Cdb->CDB10.LogicalBlockByte3;
SectorCount = (Cdb->CDB10.TransferBlocksMsb << 8) + Cdb->CDB10.TransferBlocksLsb;
}
// Srb->DataTransferLength = SectorCount * SECTORSIZE;
Srb->SrbStatus = SRB_STATUS_SUCCESS;
break;
case SCSIOP_READ_CAPACITY:
Temp = SECTORSIZE;
REVERSE_BYTES(&(((PREAD_CAPACITY_DATA)Srb->DataBuffer)->BytesPerBlock), &Temp);
if ((DeviceExtension->Disk.LBADiskSize - 1) > 0xffffffff) {
((PREAD_CAPACITY_DATA)Srb->DataBuffer)->LogicalBlockAddress = -1;
} else {
Temp = (ULONG)(DeviceExtension->Disk.LBADiskSize - 1);
REVERSE_BYTES(&(((PREAD_CAPACITY_DATA)Srb->DataBuffer)->LogicalBlockAddress), &Temp);
}
Irp->IoStatus.Information = sizeof(READ_CAPACITY_DATA);
Srb->SrbStatus = SRB_STATUS_SUCCESS;
Status = STATUS_SUCCESS;
break;
case SCSIOP_READ_CAPACITY16:
Temp = SECTORSIZE;
REVERSE_BYTES(&(((PREAD_CAPACITY_DATA_EX)Srb->DataBuffer)->BytesPerBlock), &Temp);
LargeTemp = DeviceExtension->Disk.LBADiskSize - 1;
REVERSE_BYTES_QUAD(&(((PREAD_CAPACITY_DATA_EX)Srb->DataBuffer)->LogicalBlockAddress.QuadPart), &LargeTemp);
Irp->IoStatus.Information = sizeof(READ_CAPACITY_DATA_EX);
Srb->SrbStatus = SRB_STATUS_SUCCESS;
Status = STATUS_SUCCESS;
break;
case SCSIOP_MODE_SENSE:
if (Srb->DataTransferLength < sizeof(MODE_PARAMETER_HEADER)) {
Srb->SrbStatus = SRB_STATUS_DATA_OVERRUN;
break;
}
ModeParameterHeader = (PMODE_PARAMETER_HEADER)Srb->DataBuffer;
RtlZeroMemory(ModeParameterHeader, Srb->DataTransferLength);
ModeParameterHeader->ModeDataLength = sizeof(MODE_PARAMETER_HEADER);
ModeParameterHeader->MediumType = FixedMedia;
ModeParameterHeader->BlockDescriptorLength = 0;
Srb->DataTransferLength = sizeof(MODE_PARAMETER_HEADER);
Irp->IoStatus.Information = sizeof(MODE_PARAMETER_HEADER);
Srb->SrbStatus = SRB_STATUS_SUCCESS;
break;
case SCSIOP_MEDIUM_REMOVAL:
Irp->IoStatus.Information = 0;
Srb->SrbStatus = SRB_STATUS_SUCCESS;
Status = STATUS_SUCCESS;
break;
default:
DbgPrint("!!Invalid SCSIOP (%02x)!!\n", Cdb->AsByte[0]);
Srb->SrbStatus = SRB_STATUS_ERROR;
Status = STATUS_NOT_IMPLEMENTED;
}
break;
case SRB_FUNCTION_IO_CONTROL:
Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
break;
case SRB_FUNCTION_CLAIM_DEVICE:
Srb->DataBuffer = DeviceObject;
break;
case SRB_FUNCTION_RELEASE_DEVICE:
ObDereferenceObject(DeviceObject);
break;
case SRB_FUNCTION_SHUTDOWN:
case SRB_FUNCTION_FLUSH:
Srb->SrbStatus = SRB_STATUS_SUCCESS;
break;
default:
DbgPrint("!!Invalid SRB FUNCTION (%08x)!!\n", Srb->Function);
Status = STATUS_NOT_IMPLEMENTED;
}
} else {
DbgPrint("!!Invalid Lun!!\n");
}
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
NTSTATUS STDCALL DiskDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION Stack, IN PDEVICEEXTENSION DeviceExtension) {
NTSTATUS Status;
ULONG CopySize;
PSTORAGE_PROPERTY_QUERY StoragePropertyQuery;
STORAGE_ADAPTER_DESCRIPTOR StorageAdapterDescriptor;
STORAGE_DEVICE_DESCRIPTOR StorageDeviceDescriptor;
DISK_GEOMETRY DiskGeometry;
SCSI_ADDRESS ScsiAdress;
switch (Stack->Parameters.DeviceIoControl.IoControlCode) {
case IOCTL_STORAGE_QUERY_PROPERTY:
StoragePropertyQuery = Irp->AssociatedIrp.SystemBuffer;
Status = STATUS_INVALID_PARAMETER;
if (StoragePropertyQuery->PropertyId == StorageAdapterProperty && StoragePropertyQuery->QueryType == PropertyStandardQuery) {
CopySize = (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_ADAPTER_DESCRIPTOR)?Stack->Parameters.DeviceIoControl.OutputBufferLength:sizeof(STORAGE_ADAPTER_DESCRIPTOR));
StorageAdapterDescriptor.Version = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
StorageAdapterDescriptor.Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
StorageAdapterDescriptor.MaximumTransferLength = SECTORSIZE * DeviceExtension->Disk.MaxSectorsPerPacket;
// StorageAdapterDescriptor.MaximumTransferLength = SECTORSIZE * POOLSIZE;
StorageAdapterDescriptor.MaximumPhysicalPages = (ULONG)-1;
StorageAdapterDescriptor.AlignmentMask = 0;
StorageAdapterDescriptor.AdapterUsesPio = TRUE;
StorageAdapterDescriptor.AdapterScansDown = FALSE;
StorageAdapterDescriptor.CommandQueueing = FALSE;
StorageAdapterDescriptor.AcceleratedTransfer = FALSE;
StorageAdapterDescriptor.BusType = BusTypeScsi;
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &StorageAdapterDescriptor, CopySize);
Irp->IoStatus.Information = (ULONG_PTR)CopySize;
Status = STATUS_SUCCESS;
}
if (StoragePropertyQuery->PropertyId == StorageDeviceProperty && StoragePropertyQuery->QueryType == PropertyStandardQuery) {
CopySize = (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(STORAGE_DEVICE_DESCRIPTOR)?Stack->Parameters.DeviceIoControl.OutputBufferLength:sizeof(STORAGE_DEVICE_DESCRIPTOR));
StorageDeviceDescriptor.Version = sizeof(STORAGE_DEVICE_DESCRIPTOR);
StorageDeviceDescriptor.Size = sizeof(STORAGE_DEVICE_DESCRIPTOR);
StorageDeviceDescriptor.DeviceType = DIRECT_ACCESS_DEVICE;
StorageDeviceDescriptor.DeviceTypeModifier = 0;
StorageDeviceDescriptor.RemovableMedia = FALSE;
StorageDeviceDescriptor.CommandQueueing = FALSE;
StorageDeviceDescriptor.VendorIdOffset = 0;
StorageDeviceDescriptor.ProductIdOffset = 0;
StorageDeviceDescriptor.ProductRevisionOffset = 0;
StorageDeviceDescriptor.SerialNumberOffset = 0;
StorageDeviceDescriptor.BusType = BusTypeScsi;
StorageDeviceDescriptor.RawPropertiesLength = 0;
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &StorageDeviceDescriptor, CopySize);
Irp->IoStatus.Information = (ULONG_PTR)CopySize;
Status = STATUS_SUCCESS;
}
if (Status == STATUS_INVALID_PARAMETER) {
DbgPrint("!!Invalid IOCTL_STORAGE_QUERY_PROPERTY (PropertyId: %08x / QueryType: %08x)!!\n", StoragePropertyQuery->PropertyId, StoragePropertyQuery->QueryType);
}
break;
case IOCTL_DISK_GET_DRIVE_GEOMETRY:
CopySize = (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(DISK_GEOMETRY)?Stack->Parameters.DeviceIoControl.OutputBufferLength:sizeof(DISK_GEOMETRY));
DiskGeometry.MediaType = FixedMedia;
DiskGeometry.Cylinders.QuadPart = DeviceExtension->Disk.Cylinders;
DiskGeometry.TracksPerCylinder = DeviceExtension->Disk.Heads;
DiskGeometry.SectorsPerTrack = DeviceExtension->Disk.Sectors;
DiskGeometry.BytesPerSector = SECTORSIZE;
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &DiskGeometry, CopySize);
Irp->IoStatus.Information = (ULONG_PTR)CopySize;
Status = STATUS_SUCCESS;
break;
case IOCTL_SCSI_GET_ADDRESS:
CopySize = (Stack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(SCSI_ADDRESS)?Stack->Parameters.DeviceIoControl.OutputBufferLength:sizeof(SCSI_ADDRESS));
ScsiAdress.Length = sizeof(SCSI_ADDRESS);
ScsiAdress.PortNumber = 0;
ScsiAdress.PathId = 0;
ScsiAdress.TargetId = (UCHAR)DeviceExtension->Disk.DiskNumber;
ScsiAdress.Lun = 0;
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, &ScsiAdress, CopySize);
Irp->IoStatus.Information = (ULONG_PTR)CopySize;
Status = STATUS_SUCCESS;
break;
default:
Irp->IoStatus.Information = 0;
Status = STATUS_INVALID_PARAMETER;
}
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
NTSTATUS STDCALL DiskDispatchSystemControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION Stack, IN PDEVICEEXTENSION DeviceExtension) {
NTSTATUS Status;
Status = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
// FIXME put in SCSI
NTSTATUS STDCALL BusGetDeviceCapabilities(IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_CAPABILITIES DeviceCapabilities) {
IO_STATUS_BLOCK ioStatus;
KEVENT pnpEvent;
NTSTATUS status;
PDEVICE_OBJECT targetObject;
PIO_STACK_LOCATION irpStack;
PIRP pnpIrp;
RtlZeroMemory(DeviceCapabilities, sizeof(DEVICE_CAPABILITIES));
DeviceCapabilities->Size = sizeof(DEVICE_CAPABILITIES);
DeviceCapabilities->Version = 1;
DeviceCapabilities->Address = -1;
DeviceCapabilities->UINumber = -1;
KeInitializeEvent(&pnpEvent, NotificationEvent, FALSE);
targetObject = IoGetAttachedDeviceReference(DeviceObject);
pnpIrp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, targetObject, NULL, 0, NULL, &pnpEvent, &ioStatus);
if (pnpIrp == NULL) {
status = STATUS_INSUFFICIENT_RESOURCES;
} else {
pnpIrp->IoStatus.Status = STATUS_NOT_SUPPORTED;
irpStack = IoGetNextIrpStackLocation(pnpIrp);
RtlZeroMemory(irpStack, sizeof(IO_STACK_LOCATION));
irpStack->MajorFunction = IRP_MJ_PNP;
irpStack->MinorFunction = IRP_MN_QUERY_CAPABILITIES;
irpStack->Parameters.DeviceCapabilities.Capabilities = DeviceCapabilities;
status = IoCallDriver(targetObject, pnpIrp);
if (status == STATUS_PENDING) {
KeWaitForSingleObject(&pnpEvent, Executive, KernelMode, FALSE, NULL);
status = ioStatus.Status;
}
}
ObDereferenceObject(targetObject);
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -