⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 disk.c

📁 WinAoE is an open source GPLv3 driver for using AoE (ATA over Ethernet) on Microsoft Windows
💻 C
📖 第 1 页 / 共 2 页
字号:
        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 + -