嗯嗯。。。。校验光盘

NTSTATUS
UnitReadyCompletionRoutine( PDEVICE_OBJECT   DeviceObject, PIRP   Irp,PVOID   Context)
{
 PDEVICE_EXTENSION           deviceExtension;
 
#ifdef TIMERTEST
 //完成自己发的 SCSIOP_TEST_UNIT_READY
 PSCSI_REQUEST_BLOCK Srb = (PSCSI_REQUEST_BLOCK)Context;
 DeviceObject = (PDEVICE_OBJECT)Irp->UserBuffer;
 deviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
 //判断返回的数值
 if(SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_SUCCESS && NT_SUCCESS(Irp->IoStatus.Status ))
 {
  if( deviceExtension->CDState == CDEmpty)
  {
   InterlockedExchange((LONG *)&deviceExtension->CDState,CDCheck); //设置状态为光盘需要检测
   //设置一个事件表示这个设备插入了要校验信息
   KeSetEvent(&(deviceExtension->queue.DelayThreadQueueNotEmptyEvent),IO_NO_INCREMENT,FALSE); 
  }
 }
 else
 {
  if( deviceExtension->CDState != CDEmpty)
  {
   InterlockedExchange((LONG *)&deviceExtension->CDState,CDEmpty); //设置状态为光盘拔出了
   if(g_pRemoveEvent)
    KeSetEvent((PKEVENT)g_pRemoveEvent,IO_NO_INCREMENT,FALSE); //通知光盘弹出了
  }
 }
 if(Srb->SenseInfoBuffer)
  ExFreePool(Srb->SenseInfoBuffer);
 ExFreePool(Srb);
 IoFreeIrp(Irp);
 return STATUS_MORE_PROCESSING_REQUIRED;
#endif
}
//校验设备状态
NTSTATUS TestUnitReady( PDEVICE_EXTENSION deviceExtension)
{
 NTSTATUS status;
 /*status = SendSrbCdbToNextDeviceObject(deviceExtension->NextLowerDriver, SCSIOP_TEST_UNIT_READY, 6,
 NULL, 0, NULL, NULL);
 if(!NT_SUCCESS(status))
 {
 DeviceFlushQueue(deviceExtension->NextLowerDriver);
 }*/
 PSCSI_REQUEST_BLOCK Srb;
 PIRP irp;
 PIO_STACK_LOCATION irpStack;
 PUCHAR senseInfoBuffer;
 PDEVICE_OBJECT DeviceObject = deviceExtension->NextLowerDriver;
 Srb = ExAllocatePool(NonPagedPool, sizeof(SCSI_REQUEST_BLOCK));
 if(Srb == NULL) 
 {
  return STATUS_INSUFFICIENT_RESOURCES; 
 }
 senseInfoBuffer = ExAllocatePool(NonPagedPool, SENSE_BUFFER_SIZE);
 if(senseInfoBuffer == NULL) 
 {
  ExFreePool(Srb);
  return STATUS_INSUFFICIENT_RESOURCES;
 }
 RtlZeroMemory(Srb, sizeof(SCSI_REQUEST_BLOCK));
 RtlZeroMemory(senseInfoBuffer, SENSE_BUFFER_SIZE);
 //设置长度和执行命令
 Srb->Length = sizeof(SCSI_REQUEST_BLOCK);
 Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
 Srb->PathId = 0;
 Srb->TargetId = 0;
 Srb->Lun = 0;
 Srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
 Srb->SenseInfoBuffer = senseInfoBuffer;
 Srb->DataBuffer = NULL;
 Srb->DataTransferLength = 0;
 Srb->ScsiStatus = Srb->SrbStatus = 0;
 Srb->NextSrb = 0;
 Srb->TimeOutValue = 20; //超时时间
 Srb->CdbLength = 6;
 SET_FLAG(Srb->SrbFlags, SRB_FLAGS_NO_DATA_TRANSFER);
 SET_FLAG(Srb->SrbFlags, SRB_FLAGS_DISABLE_SYNCH_TRANSFER);
 SET_FLAG(Srb->SrbFlags, SRB_FLAGS_NO_QUEUE_FREEZE);
 /*Srb->QueueAction = SRB_SIMPLE_TAG_REQUEST;
 Srb->QueueTag = 0xff;*/
 Srb->QueueAction = 0;
 Srb->QueueTag = 0;
 //分配一个IRP把这个SRB发下去 
 irp = IoAllocateIrp(DeviceObject->StackSize+1, FALSE);
 if(irp == NULL) 
 {
  if(Srb)
   ExFreePool(Srb);
  if(senseInfoBuffer)
   ExFreePool(senseInfoBuffer);
  return STATUS_INSUFFICIENT_RESOURCES;
 }
 irpStack = IoGetNextIrpStackLocation(irp);
 irpStack->MajorFunction = IRP_MJ_SCSI;
 irpStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_SCSI_EXECUTE_IN;
 irpStack->Parameters.Scsi.Srb = Srb;
 irp->AssociatedIrp.SystemBuffer = NULL;
 irp->MdlAddress = NULL;
 Srb->OriginalRequest = irp;
 irp->UserBuffer = deviceExtension-> Self;
 IoSetCompletionRoutine(irp, UnitReadyCompletionRoutine, Srb, TRUE, TRUE, TRUE);
 status = IoCallDriver(DeviceObject, irp);
 return status;
}

你可能感兴趣的:(嗯嗯。。。。校验光盘)