Exemplo n.º 1
0
NTSTATUS                                              
MpHwHandlePnP(
              __in pHW_HBA_EXT              pHBAExt,  // Adapter device-object extension from port driver.
              __in PSCSI_PNP_REQUEST_BLOCK  pSrb
             )
{
    NTSTATUS status = STATUS_SUCCESS;

    KdPrint2(("PhDskMnt::MpHwHandlePnP:  pHBAExt = 0x%p, pSrb = 0x%p\n", pHBAExt, pSrb));

    switch(pSrb->PnPAction)
    {

      case StorRemoveDevice:
        status = ImScsiHandleRemoveDevice(pHBAExt, pSrb);

        break;

      case StorQueryCapabilities:
        status = ImScsiHandleQueryCapabilities(pHBAExt, pSrb);

        break;

      default:
        pSrb->SrbStatus = SRB_STATUS_SUCCESS;         // Do nothing.
    }

    if (STATUS_SUCCESS!=status) {
    }

    KdPrint2(("PhDskMnt::MpHwHandlePnP:  status = 0x%x\n", status));

    return status;
}                                                     // End MpHwHandlePnP().
Exemplo n.º 2
0
LONG
ImScsiCompletePendingSrbs(
                          __in pHW_HBA_EXT pHBAExt  // Adapter device-object extension from port driver.
)
{
  pMP_WorkRtnParms pWkRtnParms;
  LONG done = 0;

  KdPrint2(("PhDskMnt::ImScsiCompletePendingSrbs start. pHBAExt = 0x%p\n", pHBAExt));

  for (;;)
  {
    PLIST_ENTRY request =
      ExInterlockedRemoveHeadList(&pMPDrvInfoGlobal->ResponseList,
      &pMPDrvInfoGlobal->ResponseListLock);

    if (request == NULL)
    {
      LONG was_pending = _InterlockedExchangeAdd((volatile LONG*)&pHBAExt->WorkItems, -done);
      KdPrint2(("PhDskMnt::ImScsiCompletePendingSrbs finished.\n"));
      return was_pending - done;
    }

    ++done;

    pWkRtnParms = (pMP_WorkRtnParms)CONTAINING_RECORD(request, MP_WorkRtnParms, ResponseListEntry);

    KdPrint2(("PhDskMnt::ImScsiCompletePendingSrbs: Completing pWkRtnParms = 0x%p, pSrb = 0x%p\n", pWkRtnParms, pWkRtnParms->pSrb));

    ScsiPortNotification(RequestComplete, pWkRtnParms->pHBAExt, pWkRtnParms->pSrb);
    ScsiPortNotification(NextRequest, pWkRtnParms->pHBAExt);

    ExFreePoolWithTag(pWkRtnParms, MP_TAG_GENERAL);      // Free parm list.
  }
}
Exemplo n.º 3
0
NTSTATUS
ImScsiGetAdapterDeviceObject()
{
    NTSTATUS status = STATUS_OBJECT_NAME_NOT_FOUND;
    int i;
    UNICODE_STRING objname = { 0 };
    PFILE_OBJECT file_object = NULL;
    PDEVICE_OBJECT device_object = NULL;
    WCHAR objstr[] = L"\\Device\\Scsi\\PhDskMnt00";

    if (pMPDrvInfoGlobal->DeviceObject != NULL)
        return STATUS_SUCCESS;

    for (i = 0; i < 100; i++)
    {
        LARGE_INTEGER wait_time;

        if ((i & 7) == 7)
        {
            wait_time.QuadPart = -1;
            KeDelayExecutionThread(KernelMode, FALSE, &wait_time);
        }

        _snwprintf(objstr, sizeof(objstr)/sizeof(*objstr), L"\\Device\\Scsi\\PhDskMnt%i", i);

        RtlInitUnicodeString(&objname, objstr);

        KdPrint2(("PhDskMnt::ImScsiGetAdapterDeviceObject: Attempt to open %ws...\n", objstr));
    
        status = IoGetDeviceObjectPointer(&objname, GENERIC_ALL, &file_object, &device_object);

        if (!NT_SUCCESS(status))
        {
            KdPrint2(("PhDskMnt::ImScsiGetAdapterDeviceObject: Attempt to open %ws failed: status=0x%x\n", objstr, status));
            continue;
        }

        if (device_object->DriverObject != pMPDrvInfoGlobal->pDriverObj)
        {
            KdPrint2(("PhDskMnt::ImScsiGetAdapterDeviceObject: %ws was not our device.\n", objstr, status));
            continue;
        }

        pMPDrvInfoGlobal->DeviceObject = device_object;

        return STATUS_SUCCESS;
    }

    if (NT_SUCCESS(status))
        KdPrint(("PhDskMnt::ImScsiGetAdapterDeviceObject: Successfully opened %ws.\n", objstr));
    else
        DbgPrint(("PhDskMnt::ImScsiGetAdapterDeviceObject: Could not locate SCSI adapter device object by name.\n"));

    return status;
}
Exemplo n.º 4
0
/*
    Get next channel to be serviced
    (used in simplex mode only)
 */
PHW_CHANNEL
NTAPI
UniataGetNextChannel(
    IN PHW_CHANNEL chan
    )
{
    ULONG c=0, _c;
    PHW_DEVICE_EXTENSION deviceExtension;
    ULONG best_c;
    ULONG cost_c;

    deviceExtension = chan->DeviceExtension;

    if(!deviceExtension->simplexOnly) {
        return chan;
    }
    KdPrint2((PRINT_PREFIX "UniataGetNextChannel:\n"));
    best_c = -1;
    cost_c = 0;
    for(_c=0; _c<deviceExtension->NumberChannels; _c++) {
        c = (_c+deviceExtension->FirstChannelToCheck) % deviceExtension->NumberChannels;
        chan = &deviceExtension->chan[c];
        if(chan->queue_depth &&
           chan->queue_depth * (chan->ChannelSelectWaitCount+1) >
           cost_c) {
            best_c = c;
            cost_c = chan->queue_depth * (chan->ChannelSelectWaitCount+1);
        }
    }
    if(best_c == CHAN_NOT_SPECIFIED) {
        KdPrint2((PRINT_PREFIX "  empty queues\n"));
        return NULL;
    }
    deviceExtension->FirstChannelToCheck = c;
    for(_c=0; _c<deviceExtension->NumberChannels; _c++) {
        chan = &deviceExtension->chan[_c];
        if(_c == best_c) {
            chan->ChannelSelectWaitCount = 0;
            continue;
        }
        chan->ChannelSelectWaitCount++;
        if(!chan->queue_depth) {
            chan->ChannelSelectWaitCount = 0;
        } else {
            chan->ChannelSelectWaitCount++;
        }
    }
    KdPrint2((PRINT_PREFIX "  select chan %d\n", best_c));
    return &deviceExtension->chan[best_c];
} // end UniataGetNextChannel()
VOID
MpHwFreeAdapterResources(__in PVOID DeviceExtension)
{
    PLIST_ENTRY         pNextEntry;
    pHW_HBA_EXT         pLclHBAExt;
    KLOCK_QUEUE_HANDLE  LockHandle;
    KIRQL               lowest_assumed_irql = PASSIVE_LEVEL;
    pHW_HBA_EXT         pHBAExt = (pHW_HBA_EXT)DeviceExtension;

    KdPrint2(("PhDskMnt::MpHwFreeAdapterResources:  pHBAExt = 0x%p\n", pHBAExt));

    // Free memory allocated for disk
    ImScsiStopAdapter(pHBAExt, &lowest_assumed_irql);

    ImScsiAcquireLock(&pMPDrvInfoGlobal->DrvInfoLock, &LockHandle, lowest_assumed_irql);

    for (                                             // Go through linked list of HBA extensions.
        pNextEntry = pMPDrvInfoGlobal->ListMPHBAObj.Flink;
        pNextEntry != &pMPDrvInfoGlobal->ListMPHBAObj;
        pNextEntry = pNextEntry->Flink
        )
    {
        pLclHBAExt = CONTAINING_RECORD(pNextEntry, HW_HBA_EXT, List);

        if (pLclHBAExt == pHBAExt)
        {                    // Is this entry the same as pHBAExt?
            RemoveEntryList(pNextEntry);
            pMPDrvInfoGlobal->DrvInfoNbrMPHBAObj--;
            break;
        }
    }

    ImScsiReleaseLock(&LockHandle, &lowest_assumed_irql);

}                                                     // End MpHwFreeAdapterResources().
LONG
ImScsiCompletePendingSrbs(
__in pHW_HBA_EXT pHBAExt,  // Adapter device-object extension from port driver.
__inout __deref PKIRQL LowestAssumedIrql
)
{
    pMP_WorkRtnParms pWkRtnParms;
    LONG done = 0;

    KdPrint2(("PhDskMnt::ImScsiCompletePendingSrbs start. pHBAExt = 0x%p\n", pHBAExt));

    for (;;)
    {
        KLOCK_QUEUE_HANDLE lock_handle;
        PLIST_ENTRY request;

        ImScsiAcquireLock(&pMPDrvInfoGlobal->ResponseListLock,
            &lock_handle, *LowestAssumedIrql);

        request = RemoveHeadList(&pMPDrvInfoGlobal->ResponseList);
        if (request == &pMPDrvInfoGlobal->ResponseList)
        {
            request = NULL;
        }

        ImScsiReleaseLock(&lock_handle, LowestAssumedIrql);

        if (request == NULL)
        {
            LONG was_pending = _InterlockedExchangeAdd((volatile LONG*)&pHBAExt->WorkItems, -done);
            KdPrint2(("PhDskMnt::ImScsiCompletePendingSrbs finished.\n"));
            return was_pending - done;
        }

        ++done;

        pWkRtnParms = (pMP_WorkRtnParms)CONTAINING_RECORD(request, MP_WorkRtnParms, ResponseListEntry);

        KdPrint2(("PhDskMnt::ImScsiCompletePendingSrbs: Completing pWkRtnParms = 0x%p, pSrb = 0x%p\n", pWkRtnParms, pWkRtnParms->pSrb));

        ScsiPortNotification(RequestComplete, pWkRtnParms->pHBAExt, pWkRtnParms->pSrb);
        ScsiPortNotification(NextRequest, pWkRtnParms->pHBAExt);

        ExFreePoolWithTag(pWkRtnParms, MP_TAG_GENERAL);      // Free parm list.
    }
}
Exemplo n.º 7
0
BOOLEAN
MpHwInitialize(__in PVOID pHBAExt)
{
  UNREFERENCED_PARAMETER(pHBAExt);

  KdPrint2(("PhDskMnt::MpHwInitialize:  pHBAExt = 0x%p. IRQL=%i\n", pHBAExt, KeGetCurrentIrql()));

  return TRUE;
}                                                     // End MpHwInitialize().
Exemplo n.º 8
0
VOID
ImScsiStopAdapter(
                  __in pHW_HBA_EXT pHBAExt         // Adapter device-object extension from port driver.
                  )
{
    SRB_IMSCSI_REMOVE_DEVICE rem_data = { 0 };

    KdPrint2(("PhDskMnt::ImScsiStopAdapter:  pHBAExt = 0x%p\n", pHBAExt));

    // Remove all devices, using "wildcard" device number.
    rem_data.DeviceNumber.LongNumber = IMSCSI_ALL_DEVICES;

    ImScsiRemoveDevice(pHBAExt, &rem_data);

    KdPrint2(("PhDskMnt::ImScsiStopAdapter End.\n"));

    return;
}                                                     // End ImScsiStopAdapter().
Exemplo n.º 9
0
NTSTATUS
AWEAllocClose(IN PDEVICE_OBJECT DeviceObject,
	      IN PIRP Irp)
{
  PIO_STACK_LOCATION io_stack = IoGetCurrentIrpStackLocation(Irp);
  POBJECT_CONTEXT context = io_stack->FileObject->FsContext2;

  KdPrint(("AWEAlloc: Close.\n"));

  PAGED_CODE();

  if (context != NULL)
    {
      PBLOCK_DESCRIPTOR block = context->FirstBlock;

      KdPrint2(("AWEAlloc: Freeing context data. First block=%p\n", block));

      if (context->CurrentMdl != NULL)
	IoFreeMdl(context->CurrentMdl);

      while (block != NULL)
	{
	  PBLOCK_DESCRIPTOR next_block = block->NextBlock;

	  KdPrint2(("AWEAlloc: Freeing block=%p mdl=%p.\n",
		    block,
		    block->Mdl));

	  MmFreePagesFromMdl(block->Mdl);
	  ExFreePool(block->Mdl);
	  ExFreePoolWithTag(block, POOL_TAG);

	  block = next_block;
	}

      ExFreePoolWithTag(context, POOL_TAG);
    }

  Irp->IoStatus.Status = STATUS_SUCCESS;
  Irp->IoStatus.Information = 0;
  IoCompleteRequest(Irp, IO_NO_INCREMENT); 

  return STATUS_SUCCESS;
}
Exemplo n.º 10
0
VOID
ImScsiStopAdapter(
__in pHW_HBA_EXT pHBAExt,         // Adapter device-object extension from port driver.
__inout __deref PKIRQL LowestAssumedIrql
)
{
    DEVICE_NUMBER rem_data;

    KdPrint2(("PhDskMnt::ImScsiStopAdapter:  pHBAExt = 0x%p\n", pHBAExt));

    // Remove all devices, using "wildcard" device number.
    rem_data.LongNumber = IMSCSI_ALL_DEVICES;

    ImScsiRemoveDevice(pHBAExt, &rem_data, LowestAssumedIrql);

    KdPrint2(("PhDskMnt::ImScsiStopAdapter End.\n"));

    return;
}                                                     // End ImScsiStopAdapter().
Exemplo n.º 11
0
VOID
MpHwTimer(
  __in pHW_HBA_EXT pHBAExt
)
{
  ULONG wait = 40000;
  LONG pending;

  KdPrint2(("PhDskMnt::MpHwTimer start. pHBAExt = 0x%p\n", pHBAExt));

  pending = ImScsiCompletePendingSrbs(pHBAExt);

  if (pending > 0)
  {
    KdPrint2(("PhDskMnt::MpHwTimer finished, %i items pending, restarting in %u µs.\n", pending, wait));
    ScsiPortNotification(RequestTimerCall, pHBAExt, MpHwTimer, wait);
  }
  else
    KdPrint2(("PhDskMnt::MpHwTimer finished, nothing left to do.\n"));
}
Exemplo n.º 12
0
VOID
MpHwFreeAdapterResources(__in pHW_HBA_EXT pHBAExt)
{
    PLIST_ENTRY           pNextEntry; 
    pHW_HBA_EXT           pLclHBAExt;
#if defined(_AMD64_)
    KLOCK_QUEUE_HANDLE    LockHandle;
#else
    KIRQL                 SaveIrql;
#endif

    KdPrint2(("PhDskMnt::MpHwFreeAdapterResources:  pHBAExt = 0x%p\n", pHBAExt));

#if defined(_AMD64_)
    KeAcquireInStackQueuedSpinLock(&pMPDrvInfoGlobal->DrvInfoLock, &LockHandle);
#else
    KeAcquireSpinLock(&pMPDrvInfoGlobal->DrvInfoLock, &SaveIrql);
#endif

    for (                                             // Go through linked list of HBA extensions.
         pNextEntry =  pMPDrvInfoGlobal->ListMPHBAObj.Flink;
         pNextEntry != &pMPDrvInfoGlobal->ListMPHBAObj;
         pNextEntry =  pNextEntry->Flink
        ) {
        pLclHBAExt = CONTAINING_RECORD(pNextEntry, HW_HBA_EXT, List);

        if (pLclHBAExt==pHBAExt) {                    // Is this entry the same as pHBAExt?
            RemoveEntryList(pNextEntry);
            pMPDrvInfoGlobal->DrvInfoNbrMPHBAObj--;
            break;
        }
    }

#if defined(_AMD64_)
    KeReleaseInStackQueuedSpinLock(&LockHandle);
#else
    KeReleaseSpinLock(&pMPDrvInfoGlobal->DrvInfoLock, SaveIrql);
#endif

}                                                     // End MpHwFreeAdapterResources().
Exemplo n.º 13
0
SCSI_ADAPTER_CONTROL_STATUS
MpHwAdapterControl(
                   __in pHW_HBA_EXT               pHBAExt, // Adapter device-object extension from port driver.
                   __in SCSI_ADAPTER_CONTROL_TYPE ControlType,
                   __in PVOID                     pParameters
                  )
{
    PSCSI_SUPPORTED_CONTROL_TYPE_LIST pCtlTypList;
    ULONG                             i;

    KdPrint2(("PhDskMnt::MpHwAdapterControl:  pHBAExt = 0x%p, ControlType = 0x%p, pParameters=0x%p\n", pHBAExt, ControlType, pParameters));

    pHBAExt->AdapterState = ControlType;

    switch (ControlType) {
        case ScsiQuerySupportedControlTypes:
            KdPrint2(("PhDskMnt::MpHwAdapterControl: ScsiQuerySupportedControlTypes\n"));

            // Ggt pointer to control type list
            pCtlTypList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)pParameters;

            // Cycle through list to set TRUE for each type supported
            // making sure not to go past the MaxControlType
            for (i = 0; i < pCtlTypList->MaxControlType; i++)
                if ( i == ScsiQuerySupportedControlTypes ||
                     i == ScsiStopAdapter   || i == ScsiRestartAdapter ||
                     i == ScsiSetBootConfig || i == ScsiSetRunningConfig )
                {
                    pCtlTypList->SupportedTypeList[i] = TRUE;
                }
            break;

        case ScsiStopAdapter:
            KdPrint2(("PhDskMnt::MpHwAdapterControl: ScsiStopAdapter\n"));

            // Free memory allocated for disk
            ImScsiStopAdapter(pHBAExt);

            break;

        case ScsiRestartAdapter:
            KdPrint2(("PhDskMnt::MpHwAdapterControl: ScsiRestartAdapter\n"));

            /* To Do: Add some function. */

            break;

        case ScsiSetBootConfig:
            KdPrint2(("PhDskMnt::MpHwAdapterControl: ScsiSetBootConfig\n"));

            break;
            
        case ScsiSetRunningConfig:
            KdPrint2(("PhDskMnt::MpHwAdapterControl: ScsiSetRunningConfig\n"));

            break;

        default:
            KdPrint2(("PhDskMnt::MpHwAdapterControl: UNKNOWN: 0x%X\n", ControlType));

            break;
    } 

    KdPrint2(("PhDskMnt::MpHwAdapterControl End: status=0x%x\n", ScsiAdapterControlSuccess));

    return ScsiAdapterControlSuccess;
}                                                     // End MpHwAdapterControl().
Exemplo n.º 14
0
NTSTATUS
AWEAllocReadWrite(IN PDEVICE_OBJECT DeviceObject,
		  IN PIRP Irp)
{
  PIO_STACK_LOCATION io_stack = IoGetCurrentIrpStackLocation(Irp);
  POBJECT_CONTEXT context = io_stack->FileObject->FsContext2;
  ULONG length_done = 0;
  NTSTATUS status;
  PUCHAR system_buffer;

  KdPrint2(("AWEAlloc: Read/write request Offset=%#I64x Len=%#x.\n",
	    io_stack->Parameters.Read.ByteOffset,
	    io_stack->Parameters.Read.Length));

  if (context == NULL)
    {
      KdPrint2(("AWEAlloc: Read/write request on not initialized device.\n"));

      Irp->IoStatus.Status = STATUS_SUCCESS;
      Irp->IoStatus.Information = 0;

      IoCompleteRequest(Irp, IO_NO_INCREMENT);

      return STATUS_SUCCESS;
    }

  if (context->FirstBlock == NULL)
    {
      KdPrint2(("AWEAlloc: Read/write request on not initialized device.\n"));

      Irp->IoStatus.Status = STATUS_SUCCESS;
      Irp->IoStatus.Information = 0;

      IoCompleteRequest(Irp, IO_NO_INCREMENT);

      return STATUS_SUCCESS;
    }

  if (io_stack->Parameters.Read.ByteOffset.QuadPart > context->VirtualSize)
    {
      KdPrint2(("AWEAlloc: Read/write request starting past EOF.\n"));

      Irp->IoStatus.Status = STATUS_SUCCESS;
      Irp->IoStatus.Information = 0;

      IoCompleteRequest(Irp, IO_NO_INCREMENT);

      return STATUS_SUCCESS;
    }

  if ((io_stack->Parameters.Read.ByteOffset.QuadPart +
       io_stack->Parameters.Read.Length) > context->VirtualSize)
    {
      if (io_stack->MajorFunction == IRP_MJ_WRITE)
	{
	  IO_STATUS_BLOCK io_status;
	  LARGE_INTEGER new_size;

	  status = AWEAllocTryAcquireProtection(context, TRUE);
	  if (!NT_SUCCESS(status))
	    {
	      DbgPrint("AWEAlloc: Page table busy.\n");
	      Irp->IoStatus.Status = status;
	      Irp->IoStatus.Information = 0;
	      IoCompleteRequest(Irp, IO_NO_INCREMENT);
	      return status;
	    }

	  new_size.QuadPart =
	    io_stack->Parameters.Read.ByteOffset.QuadPart +
	    io_stack->Parameters.Read.Length;

	  new_size.QuadPart = max(new_size.QuadPart, context->VirtualSize);

	  status = AWEAllocSetSize(context,
				   &io_status,
				   &new_size);
	  if (!NT_SUCCESS(status))
	    {
	      DbgPrint("AWEAlloc: Error growing in-memory file.\n");
	      Irp->IoStatus.Status = status;
	      Irp->IoStatus.Information = 0;
	      IoCompleteRequest(Irp, IO_NO_INCREMENT);
	      return status;
	    }

	  AWEAllocReleaseProtection(context, TRUE);
	}
      else
	{
	  io_stack->Parameters.Read.Length = (ULONG)
	    (context->VirtualSize -
	     io_stack->Parameters.Read.ByteOffset.QuadPart);

	  KdPrint2(("AWEAlloc: Read request towards EOF. Len set to %x\n",
		    io_stack->Parameters.Read.Length));
	}
    }

  if (io_stack->Parameters.Read.Length == 0)
    {
      KdPrint2(("AWEAlloc: Zero bytes read/write request.\n"));

      Irp->IoStatus.Status = STATUS_SUCCESS;
      Irp->IoStatus.Information = 0;

      IoCompleteRequest(Irp, IO_NO_INCREMENT);

      return STATUS_SUCCESS;
    }

  system_buffer =
    MmGetSystemAddressForMdlSafe(Irp->MdlAddress, HighPagePriority);

  if (system_buffer == NULL)
    {
      DbgPrint("AWEAlloc: Failed mapping system buffer.\n");

      Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
      Irp->IoStatus.Information = 0;
      IoCompleteRequest(Irp, IO_NO_INCREMENT);
      return STATUS_INSUFFICIENT_RESOURCES;
    }

  KdPrint2(("AWEAlloc: System buffer: %p\n", system_buffer));

  status = AWEAllocTryAcquireProtection(context, FALSE);
  if (!NT_SUCCESS(status))
    {
      DbgPrint("AWEAlloc: Page table is busy.\n");

      Irp->IoStatus.Status = status;
      Irp->IoStatus.Information = 0;
      IoCompleteRequest(Irp, IO_NO_INCREMENT);
      return status;
    }      

  for (;;)
    {
      LONGLONG abs_offset_this_iter =
	io_stack->Parameters.Read.ByteOffset.QuadPart + length_done;
      ULONG page_offset_this_iter =
	AWEAllocGetPageOffsetFromAbsOffset(abs_offset_this_iter);
      ULONG bytes_this_iter = io_stack->Parameters.Read.Length - length_done;

      if (length_done >= io_stack->Parameters.Read.Length)
	{
	  KdPrint2(("AWEAlloc: Nothing left to do.\n"));

	  AWEAllocReleaseProtection(context, FALSE);

	  Irp->IoStatus.Status = STATUS_SUCCESS;
	  Irp->IoStatus.Information = length_done;

	  IoCompleteRequest(Irp, IO_NO_INCREMENT);

	  return STATUS_SUCCESS;
	}

      if ((page_offset_this_iter + bytes_this_iter) > ALLOC_PAGE_SIZE)
	bytes_this_iter = ALLOC_PAGE_SIZE - page_offset_this_iter;

      status = AWEAllocMapPage(context, abs_offset_this_iter);

      if (!NT_SUCCESS(status))
	{
	  DbgPrint("AWEAlloc: Failed mapping current image page.\n");

	  AWEAllocReleaseProtection(context, FALSE);

	  Irp->IoStatus.Status = status;
	  Irp->IoStatus.Information = 0;

	  IoCompleteRequest(Irp, IO_NO_INCREMENT);

	  return status;
	}

      KdPrint2(("AWEAlloc: Current image page mdl ptr=%p system ptr=%p.\n",
		context->CurrentMdl,
		context->CurrentPtr));

      switch (io_stack->MajorFunction)
	{
	case IRP_MJ_READ:
	  {
	    KdPrint2(("AWEAlloc: Copying memory image -> I/O buffer.\n"));

	    RtlCopyMemory(system_buffer + length_done,
			  context->CurrentPtr + page_offset_this_iter,
			  bytes_this_iter);

	    break;
	  }

	case IRP_MJ_WRITE:
	  {
	    KdPrint2(("AWEAlloc: Copying memory image <- I/O buffer.\n"));

	    RtlCopyMemory(context->CurrentPtr + page_offset_this_iter,
			  system_buffer + length_done,
			  bytes_this_iter);

	    break;
	  }
	}

      io_stack->FileObject->CurrentByteOffset.QuadPart += bytes_this_iter;

      KdPrint2(("AWEAlloc: Copy done.\n"));

      length_done += bytes_this_iter;

    }

}
Exemplo n.º 15
0
BOOLEAN
MpHwStartIo(
            __in       pHW_HBA_EXT          pHBAExt,  // Adapter device-object extension from port driver.
            __in __out PSCSI_REQUEST_BLOCK  pSrb
           )
{
    UCHAR                     Result = ResultDone;
#ifdef USE_SCSIPORT
    UCHAR                     PathId = pSrb->PathId;
    UCHAR                     TargetId = pSrb->TargetId;
    UCHAR                     Lun = pSrb->Lun;
#endif

    KdPrint2(("PhDskMnt::MpHwStartIo:  pHBAExt = 0x%p, pSrb = 0x%p, Path=%i, Target=%i, Lun=%i, IRQL=%i\n",
        pHBAExt,
        pSrb,
        (int) pSrb->PathId,
        (int) pSrb->TargetId,
        (int) pSrb->Lun,
        KeGetCurrentIrql()));

    pSrb->SrbStatus = SRB_STATUS_PENDING;
    pSrb->ScsiStatus = SCSISTAT_GOOD;

    ImScsiCompletePendingSrbs(pHBAExt);

    _InterlockedExchangeAdd((volatile LONG *)&pHBAExt->SRBsSeen, 1);   // Bump count of SRBs encountered.

    // Next, if true, will cause port driver to remove the associated LUNs if, for example, devmgmt.msc is asked "scan for hardware changes."
    //if (pHBAExt->bDontReport)
    //{                       // Act as though the HBA/path is gone?
    //    pSrb->SrbStatus = SRB_STATUS_INVALID_LUN;
    //    goto done;
    //}

    switch (pSrb->Function)
    {
    case SRB_FUNCTION_IO_CONTROL:
        ScsiIoControl(pHBAExt, pSrb, &Result);
        break;

    case SRB_FUNCTION_EXECUTE_SCSI:
        ScsiExecute(pHBAExt, pSrb, &Result);
        break;

    case SRB_FUNCTION_RESET_LOGICAL_UNIT:
        DbgPrint("PhDskMnt::MpHwStartIo: SRB_FUNCTION_RESET_LOGICAL_UNIT.\n");
        pSrb->SrbStatus = ScsiResetLun(pHBAExt, pSrb);
        break;

    case SRB_FUNCTION_RESET_DEVICE:
        DbgPrint("PhDskMnt::MpHwStartIo: SRB_FUNCTION_RESET_DEVICE.\n");
        pSrb->SrbStatus = ScsiResetDevice(pHBAExt, pSrb);
        break;
            
    case SRB_FUNCTION_RESET_BUS:
        DbgPrint("PhDskMnt::MpHwStartIo: SRB_FUNCTION_RESET_BUS.\n");
        pSrb->SrbStatus = MpHwResetBus(pHBAExt, pSrb->PathId);
        break;
            
    case SRB_FUNCTION_PNP:                        
        MpHwHandlePnP(pHBAExt, (PSCSI_PNP_REQUEST_BLOCK)pSrb);
        break;

    case SRB_FUNCTION_POWER:                      
        KdPrint(("PhDskMnt::MpHwStartIo: SRB_FUNCTION_POWER.\n"));
        // Do nothing.
        pSrb->SrbStatus = SRB_STATUS_SUCCESS;

        break;

    case SRB_FUNCTION_SHUTDOWN:                   
        KdPrint(("PhDskMnt::MpHwStartIo: SRB_FUNCTION_SHUTDOWN.\n"));
        // Do nothing.
        pSrb->SrbStatus = SRB_STATUS_SUCCESS;

        break;

    default:
        KdPrint(("PhDskMnt::MpHwStartIo: Unknown pSrb Function = 0x%x\n", pSrb->Function));
        
        ScsiSetCheckCondition(pSrb, SRB_STATUS_ERROR, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ADSENSE_ILLEGAL_COMMAND, 0);

        break;

    } // switch (pSrb->Function)

    if (Result == ResultDone)
    {                         // Complete now?
        // Note:  A miniport with real hardware would not always be calling RequestComplete from HwScsiStartIo.  Rather,
        //        the miniport would typically be doing real I/O and would call RequestComplete only at the end of that
        //        real I/O, in its HwScsiInterrupt or in a DPC routine.

#ifdef USE_SCSIPORT
        KdPrint2(("PhDskMnt::MpHwStartIo sending 'RequestComplete', 'NextRequest' and 'NextLuRequest' to ScsiPort.\n"));
        ScsiPortNotification(RequestComplete, pHBAExt, pSrb);
        ScsiPortNotification(NextRequest, pHBAExt);
        ScsiPortNotification(NextLuRequest, pHBAExt, 0, 0, 0);
#endif
#ifdef USE_STORPORT
        KdPrint2(("PhDskMnt::MpHwStartIo sending 'RequestComplete' to port StorPort.\n"));
        StorPortNotification(RequestComplete, pHBAExt, pSrb);
#endif
    }
    else
    {
#ifdef USE_SCSIPORT
        _InterlockedExchangeAdd((volatile LONG*)&pHBAExt->WorkItems, 1);

        KdPrint2(("PhDskMnt::MpHwStartIo sending 'RequestTimerCall' and 'NextLuRequest' to ScsiPort.\n"));
        ScsiPortNotification(RequestTimerCall, pHBAExt, MpHwTimer, (ULONG) 1);
        ScsiPortNotification(NextLuRequest, pHBAExt, PathId, TargetId, Lun);
        ScsiPortNotification(NextLuRequest, pHBAExt, 0, 0, 0);
#endif
    }

    KdPrint2(("PhDskMnt::MpHwStartIo End.\n"));

    return TRUE;
}                                                     // End MpHwStartIo().
Exemplo n.º 16
0
NTSTATUS
AWEAllocQueryInformation(IN PDEVICE_OBJECT DeviceObject,
			 IN PIRP Irp)
{
  PIO_STACK_LOCATION io_stack = IoGetCurrentIrpStackLocation(Irp);
  POBJECT_CONTEXT context = io_stack->FileObject->FsContext2;

  PAGED_CODE();

  KdPrint2(("AWEAlloc: QueryFileInformation: %u.\n",
	    io_stack->Parameters.QueryFile.FileInformationClass));

  RtlZeroMemory(Irp->AssociatedIrp.SystemBuffer,
		io_stack->Parameters.QueryFile.Length);

  switch (io_stack->Parameters.QueryFile.FileInformationClass)
    {
    case FileAlignmentInformation:
      {
	PFILE_ALIGNMENT_INFORMATION alignment_info =
	  (PFILE_ALIGNMENT_INFORMATION) Irp->AssociatedIrp.SystemBuffer;

	if (io_stack->Parameters.QueryFile.Length <
	    sizeof(FILE_ALIGNMENT_INFORMATION))
	  {
	    Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
	    Irp->IoStatus.Information = 0;
	    IoCompleteRequest(Irp, IO_NO_INCREMENT);
	    return STATUS_INVALID_PARAMETER;
	  }

	alignment_info->AlignmentRequirement = FILE_BYTE_ALIGNMENT;

	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = sizeof(FILE_ALIGNMENT_INFORMATION);
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
      }

    case FileAttributeTagInformation:
    case FileBasicInformation:
    case FileInternalInformation:
      Irp->IoStatus.Status = STATUS_SUCCESS;
      Irp->IoStatus.Information = io_stack->Parameters.QueryFile.Length;
      IoCompleteRequest(Irp, IO_NO_INCREMENT);
      return STATUS_SUCCESS;

    case FileNetworkOpenInformation:
      {
	PFILE_NETWORK_OPEN_INFORMATION network_open_info =
	  (PFILE_NETWORK_OPEN_INFORMATION) Irp->AssociatedIrp.SystemBuffer;

	if (io_stack->Parameters.QueryFile.Length <
	    sizeof(FILE_NETWORK_OPEN_INFORMATION))
	  {
	    Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
	    Irp->IoStatus.Information = 0;
	    IoCompleteRequest(Irp, IO_NO_INCREMENT);
	    return STATUS_SUCCESS;
	  }

	network_open_info->AllocationSize.QuadPart = context->TotalSize;
	network_open_info->EndOfFile.QuadPart = context->VirtualSize;

	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = sizeof(FILE_NETWORK_OPEN_INFORMATION);
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
      }

    case FileStandardInformation:
      {
	PFILE_STANDARD_INFORMATION standard_info =
	  (PFILE_STANDARD_INFORMATION) Irp->AssociatedIrp.SystemBuffer;

	if (io_stack->Parameters.QueryFile.Length <
	    sizeof(FILE_STANDARD_INFORMATION))
	  {
	    Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
	    Irp->IoStatus.Information = 0;
	    IoCompleteRequest(Irp, IO_NO_INCREMENT);
	    return STATUS_INVALID_PARAMETER;
	  }

	standard_info->AllocationSize.QuadPart = context->TotalSize;
	standard_info->EndOfFile.QuadPart = context->VirtualSize;
	standard_info->DeletePending = TRUE;

	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = sizeof(FILE_STANDARD_INFORMATION);
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
      }

    case FilePositionInformation:
      {
	PFILE_POSITION_INFORMATION position_info =
	  (PFILE_POSITION_INFORMATION) Irp->AssociatedIrp.SystemBuffer;

	if (io_stack->Parameters.QueryFile.Length <
	    sizeof(FILE_POSITION_INFORMATION))
	  {
	    Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
	    Irp->IoStatus.Information = 0;
	    IoCompleteRequest(Irp, IO_NO_INCREMENT);
	    return STATUS_INVALID_PARAMETER;
	  }

	position_info->CurrentByteOffset =
	  io_stack->FileObject->CurrentByteOffset;

	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = sizeof(FILE_POSITION_INFORMATION);
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
      }

    default:
      KdPrint(("AWEAlloc: Unsupported QueryFile.FileInformationClass: %u\n",
	       io_stack->Parameters.QueryFile.FileInformationClass));

      Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
      Irp->IoStatus.Information = 0;
      IoCompleteRequest(Irp, IO_NO_INCREMENT);
      return STATUS_INVALID_DEVICE_REQUEST;
    }
}
Exemplo n.º 17
0
NTSTATUS
AWEAllocLoadImageFile(IN POBJECT_CONTEXT Context,
		      IN OUT PIO_STATUS_BLOCK IoStatus,
		      IN PUNICODE_STRING FileName)
{
  OBJECT_ATTRIBUTES object_attributes;
  NTSTATUS status;
  HANDLE file_handle = NULL;
  FILE_STANDARD_INFORMATION file_standard;
  LARGE_INTEGER offset;

  PAGED_CODE();

  InitializeObjectAttributes(&object_attributes,
			     FileName,
			     OBJ_CASE_INSENSITIVE |
			     OBJ_FORCE_ACCESS_CHECK |
			     OBJ_OPENIF,
			     NULL,
			     NULL);

  status = ZwOpenFile(&file_handle,
		      SYNCHRONIZE | GENERIC_READ,
		      &object_attributes,
		      IoStatus,
		      FILE_SHARE_READ |
		      FILE_SHARE_DELETE,
		      FILE_NON_DIRECTORY_FILE |
		      FILE_SEQUENTIAL_ONLY |
		      FILE_NO_INTERMEDIATE_BUFFERING |
		      FILE_SYNCHRONOUS_IO_NONALERT);

  if (!NT_SUCCESS(status))
    {
      KdPrint(("AWEAlloc: ZwOpenFile failed: %#x\n", status));
      return status;
    }

  status = ZwQueryInformationFile(file_handle,
				  IoStatus,
				  &file_standard,
				  sizeof(FILE_STANDARD_INFORMATION),
				  FileStandardInformation);

  if (!NT_SUCCESS(status))
    {
      KdPrint(("AWEAlloc: ZwQueryInformationFile failed: %#x\n", status));
      ZwClose(file_handle);
      return status;
    }

  status = AWEAllocSetSize(Context, IoStatus, &file_standard.EndOfFile);

  if (!NT_SUCCESS(status))
    {
      KdPrint(("AWEAlloc: AWEAllocSetSize failed: %#x\n", status));
      ZwClose(file_handle);
      return status;
    }

  for (offset.QuadPart = 0;
       offset.QuadPart < file_standard.EndOfFile.QuadPart;
       offset.QuadPart += ALLOC_PAGE_SIZE)
    {
      status = AWEAllocMapPage(Context, offset.QuadPart);

      if (!NT_SUCCESS(status))
	{
	  KdPrint(("AWEAlloc: Failed mapping current image page.\n"));

	  IoStatus->Status = status;
	  IoStatus->Information = 0;

	  break;
	}

      KdPrint2(("AWEAlloc: Current image page mdl ptr=%p system ptr=%p.\n",
		Context->CurrentMdl,
		Context->CurrentPtr));

      status = ZwReadFile(file_handle,
			  NULL,
			  NULL,
			  NULL,
			  IoStatus,
			  Context->CurrentPtr,
			  ALLOC_PAGE_SIZE,
			  &offset,
			  NULL);

      if (!NT_SUCCESS(status))
	{
	  KdPrint(("AWEAlloc: ZwReadFile failed on image file.\n"));
	  break;
	}
    }

  ZwClose(file_handle);

  IoStatus->Information = 0;

  return status;
}
Exemplo n.º 18
0
VOID
ImScsiWorkerThread(__in PVOID Context)
{
    pHW_LU_EXTENSION            pLUExt = (pHW_LU_EXTENSION)Context;
    pMP_WorkRtnParms            pWkRtnParms = NULL;
    PLIST_ENTRY                 request_list = NULL;
    PKSPIN_LOCK                 request_list_lock = NULL;
    PKEVENT                     wait_objects[2] = { NULL };

    KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY);

    if (pLUExt != NULL)
    {
        KdPrint(("PhDskMnt::ImScsiWorkerThread: Device worker thread start. pLUExt = 0x%p\n",
            pLUExt));

        request_list = &pLUExt->RequestList;
        request_list_lock = &pLUExt->RequestListLock;
        wait_objects[0] = &pLUExt->RequestEvent;

        // If this is a VM backed disk that should be pre-loaded with an image file
        // we have to load the contents of that file now before entering the service
        // loop.
        if (pLUExt->VMDisk && (pLUExt->ImageFile != NULL))
            if (!ImScsiFillMemoryDisk(pLUExt))
                KeSetEvent(&pLUExt->StopThread, (KPRIORITY)0, FALSE);
    }
    else
    {
        KdPrint(("PhDskMnt::ImScsiWorkerThread: Global worker thread start. pLUExt=%p\n",
            pLUExt));

        request_list = &pMPDrvInfoGlobal->RequestList;
        request_list_lock = &pMPDrvInfoGlobal->RequestListLock;
        wait_objects[0] = &pMPDrvInfoGlobal->RequestEvent;
    }
    wait_objects[1] = &pMPDrvInfoGlobal->StopWorker;

    for (;;)
    {
        PLIST_ENTRY                 request;
        KLOCK_QUEUE_HANDLE          lock_handle;
        KIRQL                       lowest_assumed_irql = PASSIVE_LEVEL;

#ifdef USE_SCSIPORT

        NTSTATUS                    status = STATUS_SUCCESS;
        PIRP                        irp = NULL;

        ImScsiGetControllerObject();

        if (pMPDrvInfoGlobal->ControllerObject != NULL)
        {
            KdPrint2(("PhDskMnt::ImScsiWorkerThread: Pre-building IRP for next SMB_IMSCSI_CHECK.\n"));

            irp = ImScsiBuildCompletionIrp();
        }
#endif

        for (;;)
        {
            ImScsiAcquireLock(request_list_lock, &lock_handle, lowest_assumed_irql);

            request = RemoveHeadList(request_list);

            ImScsiReleaseLock(&lock_handle, &lowest_assumed_irql);

            if (request != request_list)
            {
                break;
            }

            if (KeReadStateEvent(&pMPDrvInfoGlobal->StopWorker) ||
                ((pLUExt != NULL) && (KeReadStateEvent(&pLUExt->StopThread))))
            {
                KdPrint(("PhDskMnt::ImScsiWorkerThread shutting down.\n"));

                if (pLUExt != NULL)
                {
                    KIRQL lowest_assumed_irql = PASSIVE_LEVEL;
                    ImScsiCleanupLU(pLUExt, &lowest_assumed_irql);
                }

#ifdef USE_SCSIPORT
                // One last SMB_IMSCSI_CHECK call to flush response queue and free allocated IRP
                if (irp != NULL)
                {
                    IoCallDriver(pMPDrvInfoGlobal->ControllerObject, irp);
                }
#endif

                PsTerminateSystemThread(STATUS_SUCCESS);
                return;
            }

            KdPrint2(("PhDskMnt::ImScsiWorkerThread idle, waiting for request.\n"));

            KeWaitForMultipleObjects(2, (PVOID*)wait_objects, WaitAny, Executive, KernelMode, FALSE, NULL, NULL);
        }

        pWkRtnParms = CONTAINING_RECORD(request, MP_WorkRtnParms, RequestListEntry);

        KdPrint2(("PhDskMnt::ImScsiWorkerThread got request. pWkRtnParms = 0x%p\n",
            pWkRtnParms));

        // Request to wait for LU worker thread to terminate
        if (pWkRtnParms->pSrb == NULL)
        {
            KdPrint(("PhDskMnt::ImScsiWorkerThread: Request to wait for LU worker thread to exit. pLUExt=%p\n",
                pWkRtnParms->pLUExt));

            if (pWkRtnParms->pLUExt->WorkerThread != NULL)
            {
                KeWaitForSingleObject(
                    pWkRtnParms->pLUExt->WorkerThread,
                    Executive,
                    KernelMode,
                    FALSE,
                    NULL);

                ObDereferenceObject(pWkRtnParms->pLUExt->WorkerThread);
                pWkRtnParms->pLUExt->WorkerThread = NULL;

                KdPrint(("PhDskMnt::ImScsiWorkerThread: Worker thread exit. Ready to free LUExt.\n"));
            }
            else
            {
                KdPrint(("PhDskMnt::ImScsiWorkerThread: Worker not started. Ready to free LUExt.\n"));
            }
            
            ExFreePoolWithTag(pWkRtnParms->pLUExt, MP_TAG_GENERAL);

            ExFreePoolWithTag(pWkRtnParms, MP_TAG_GENERAL);

            continue;
        }

        ImScsiDispatchWork(pWkRtnParms);

#ifdef USE_SCSIPORT

        KdPrint2(("PhDskMnt::ImScsiWorkerThread: Calling SMB_IMSCSI_CHECK for work: 0x%p.\n", pWkRtnParms));

        status = ImScsiCallForCompletion(irp, pWkRtnParms, &lowest_assumed_irql);

        if (!NT_SUCCESS(status))
            DbgPrint("PhDskMnt::ImScsiWorkerThread: IoCallDriver failed: 0x%X for work 0x%p\n", status, pWkRtnParms);
        else
            KdPrint2(("PhDskMnt::ImScsiWorkerThread: Finished SMB_IMSCSI_CHECK for work: 0x%p.\n", pWkRtnParms));

#endif

#ifdef USE_STORPORT

        KdPrint2(("PhDskMnt::ImScsiWorkerThread: Sending 'RequestComplete' to StorPort for work: 0x%p.\n", pWkRtnParms));

        StorPortNotification(RequestComplete, pWkRtnParms->pHBAExt, pWkRtnParms->pSrb);

        ExFreePoolWithTag(pWkRtnParms, MP_TAG_GENERAL);

        KdPrint2(("PhDskMnt::ImScsiWorkerThread: Finished work: 0x%p.\n", pWkRtnParms));

#endif

    }
}
Exemplo n.º 19
0
VOID
ImScsiDispatchWork(
__in pMP_WorkRtnParms        pWkRtnParms
)
{
    pHW_HBA_EXT               pHBAExt = pWkRtnParms->pHBAExt;
    pHW_LU_EXTENSION          pLUExt = pWkRtnParms->pLUExt;
    PSCSI_REQUEST_BLOCK       pSrb = pWkRtnParms->pSrb;
    PETHREAD                  pReqThread = pWkRtnParms->pReqThread;
    PCDB                      pCdb = (PCDB)pSrb->Cdb;

    KdPrint2(("PhDskMnt::ImScsiDispatchWork Action: 0x%X, pSrb: 0x%p, pSrb->DataBuffer: 0x%p pSrb->DataTransferLength: 0x%X\n",
        (int)pSrb->Cdb[0], pSrb, pSrb->DataBuffer, pSrb->DataTransferLength));

    switch (pSrb->Function)
    {
    case SRB_FUNCTION_IO_CONTROL:
    {
        PSRB_IO_CONTROL srb_io_control = (PSRB_IO_CONTROL)pSrb->DataBuffer;

        switch (srb_io_control->ControlCode)
        {
        case SMP_IMSCSI_CREATE_DEVICE:
        {                       // Create new?
            KIRQL lowest_assumed_irql = PASSIVE_LEVEL;

            KdPrint(("PhDskMnt::ImScsiDispatchWork: Request to create new device.\n"));

            ImScsiCreateLU(pHBAExt, pSrb, pReqThread, &lowest_assumed_irql);

            ObDereferenceObject(pReqThread);
        }
        break;

        default:
            break;
        }
    }
    break;

    case SRB_FUNCTION_EXECUTE_SCSI:
        switch (pSrb->Cdb[0])
        {
        case SCSIOP_READ:
        case SCSIOP_WRITE:
        case SCSIOP_READ16:
        case SCSIOP_WRITE16:
        {
            // Read/write?
            PVOID sysaddress;
            PVOID buffer;
            ULONG status;
            LARGE_INTEGER startingSector;
            LARGE_INTEGER startingOffset;
            KLOCK_QUEUE_HANDLE LockHandle;
            KIRQL lowest_assumed_irql = PASSIVE_LEVEL;

            if ((pCdb->AsByte[0] == SCSIOP_READ16) |
                (pCdb->AsByte[0] == SCSIOP_WRITE16))
            {
                REVERSE_BYTES_QUAD(&startingSector, pCdb->CDB16.LogicalBlock);
            }
            else
            {
                startingSector.QuadPart = 0;
                REVERSE_BYTES(&startingSector, &pCdb->CDB10.LogicalBlockByte0);
            }

            startingOffset.QuadPart = startingSector.QuadPart << pLUExt->BlockPower;

            KdPrint2(("PhDskMnt::ImScsiDispatchWork starting sector: 0x%I64X\n", startingSector));

            status = StoragePortGetSystemAddress(pHBAExt, pSrb, &sysaddress);

            if ((status != STORAGE_STATUS_SUCCESS) | (sysaddress == NULL))
            {
                DbgPrint("PhDskMnt::ImScsiDispatchWork: StorPortGetSystemAddress failed: status=0x%X address=0x%p translated=0x%p\n",
                    status,
                    pSrb->DataBuffer,
                    sysaddress);

                pSrb->SrbStatus = SRB_STATUS_ERROR;
                pSrb->ScsiStatus = SCSISTAT_GOOD;

                break;
            }

            buffer = ExAllocatePoolWithTag(NonPagedPool, pSrb->DataTransferLength, MP_TAG_GENERAL);

            if (buffer == NULL)
            {
                DbgPrint("PhDskMnt::ImScsiDispatchWork: Memory allocation failed.\n");

                pSrb->SrbStatus = SRB_STATUS_ERROR;
                pSrb->ScsiStatus = SCSISTAT_GOOD;

                break;
            }
            else
            {
                NTSTATUS status = STATUS_NOT_IMPLEMENTED;

                /// For write operations, prepare temporary buffer
                if ((pSrb->Cdb[0] == SCSIOP_WRITE) | (pSrb->Cdb[0] == SCSIOP_WRITE16))
                {
                    RtlMoveMemory(buffer, sysaddress, pSrb->DataTransferLength);
                }

                if ((pSrb->Cdb[0] == SCSIOP_READ) | (pSrb->Cdb[0] == SCSIOP_READ16))
                {
                    status = ImScsiReadDevice(pLUExt, buffer, &startingOffset, &pSrb->DataTransferLength);
                }
                else if ((pSrb->Cdb[0] == SCSIOP_WRITE) | (pSrb->Cdb[0] == SCSIOP_WRITE16))
                {
                    status = ImScsiWriteDevice(pLUExt, buffer, &startingOffset, &pSrb->DataTransferLength);
                }

                if (!NT_SUCCESS(status))
                {
                    ExFreePoolWithTag(buffer, MP_TAG_GENERAL);

                    DbgPrint("PhDskMnt::ImScsiDispatchWork: I/O error status=0x%X\n", status);
                    switch (status)
                    {
                    case STATUS_INVALID_BUFFER_SIZE:
                    {
                        DbgPrint("PhDskMnt::ImScsiDispatchWork: STATUS_INVALID_BUFFER_SIZE from image I/O. Reporting SCSI_SENSE_ILLEGAL_REQUEST/SCSI_ADSENSE_INVALID_CDB/0x00.\n");
                        ScsiSetCheckCondition(
                            pSrb,
                            SRB_STATUS_ERROR,
                            SCSI_SENSE_ILLEGAL_REQUEST,
                            SCSI_ADSENSE_INVALID_CDB,
                            0);
                        break;
                    }
                    case STATUS_DEVICE_BUSY:
                    {
                        DbgPrint("PhDskMnt::ImScsiDispatchWork: STATUS_DEVICE_BUSY from image I/O. Reporting SRB_STATUS_BUSY/SCSI_SENSE_NOT_READY/SCSI_ADSENSE_LUN_NOT_READY/SCSI_SENSEQ_BECOMING_READY.\n");
                        ScsiSetCheckCondition(
                            pSrb,
                            SRB_STATUS_BUSY,
                            SCSI_SENSE_NOT_READY,
                            SCSI_ADSENSE_LUN_NOT_READY,
                            SCSI_SENSEQ_BECOMING_READY
                            );
                        break;
                    }
                    default:
                    {
                        ScsiSetError(pSrb, SRB_STATUS_PARITY_ERROR);
                        break;
                    }
                    }

                    break;
                }

                /// Fake random disk signature in case mounted read-only, 0xAA55 at end of mbr and 0x00000000 in disk id field.
                /// Compatibility fix for mounting Windows Backup vhd files in read-only.
                if ((pLUExt->FakeDiskSignature != 0) &&
                    ((pSrb->Cdb[0] == SCSIOP_READ) |
                    (pSrb->Cdb[0] == SCSIOP_READ16)) &&
                    (startingSector.QuadPart == 0) &&
                    (pSrb->DataTransferLength >= 512) &&
                    (pLUExt->ReadOnly))
                {
                    PUCHAR mbr = (PUCHAR)buffer;

                    if ((*(PUSHORT)(mbr + 0x01FE) == 0xAA55) &
                        (*(PUSHORT)(mbr + 0x01BC) == 0x0000) &
                        ((*(mbr + 0x01BE) & 0x7F) == 0x00) &
                        ((*(mbr + 0x01CE) & 0x7F) == 0x00) &
                        ((*(mbr + 0x01DE) & 0x7F) == 0x00) &
                        ((*(mbr + 0x01EE) & 0x7F) == 0x00) &
                        ((*(PULONG)(mbr + 0x01B8) == 0x00000000UL)))
                    {
                        DbgPrint("PhDskMnt::ImScsiDispatchWork: Faking disk signature as %#X.\n", pLUExt->FakeDiskSignature);

                        *(PULONG)(mbr + 0x01B8) = pLUExt->FakeDiskSignature;
                    }
                }

                /// For write operations, temporary buffer holds read data.
                /// Copy that to system buffer.
                if ((pSrb->Cdb[0] == SCSIOP_READ) | (pSrb->Cdb[0] == SCSIOP_READ16))
                {
                    RtlMoveMemory(sysaddress, buffer, pSrb->DataTransferLength);
                }
            }

            ImScsiAcquireLock(&pLUExt->LastIoLock, &LockHandle, lowest_assumed_irql);

            if (pLUExt->LastIoBuffer != NULL)
                ExFreePoolWithTag(pLUExt->LastIoBuffer, MP_TAG_GENERAL);

            pLUExt->LastIoStartSector = startingSector.QuadPart;
            pLUExt->LastIoLength = pSrb->DataTransferLength;
            pLUExt->LastIoBuffer = buffer;

            ImScsiReleaseLock(&LockHandle, &lowest_assumed_irql);

            ScsiSetSuccess(pSrb, pSrb->DataTransferLength);
        }
        break;

        default:
        {
            DbgPrint("PhDskMnt::ImScsiDispatchWork unknown function: 0x%X\n", (int)pSrb->Cdb[0]);

            ScsiSetError(pSrb, SRB_STATUS_INTERNAL_ERROR);
        }
        }

    default:
        break;
    }

    KdPrint2(("PhDskMnt::ImScsiDispatchWork: End pSrb: 0x%p.\n", pSrb));

}                                                     // End ImScsiDispatchWork().
Exemplo n.º 20
0
NTSTATUS                                                                                                                                              
DriverEntry(
            __in PDRIVER_OBJECT  pDrvObj,
            __in PUNICODE_STRING pRegistryPath
           )
{
    NTSTATUS                       status = STATUS_SUCCESS;
#ifdef USE_STORPORT
    VIRTUAL_HW_INITIALIZATION_DATA hwInitData = { 0 };
#endif
#ifdef USE_SCSIPORT
    HW_INITIALIZATION_DATA         hwInitData = { 0 };
#endif
    pMPDriverInfo                  pMPDrvInfo;

    KdPrint2(("PhDskMnt::DriverEntry: Begin.\n"));
    
#ifdef MP_DrvInfo_Inline

    // Because there's no good way to clean up the allocation of the global driver information, 
    // the global information is kept in an inline structure.

    pMPDrvInfo = &lclDriverInfo;

#else

    //
    // Allocate basic miniport driver object (shared across instances of miniport). The pointer is kept in the driver binary's static storage.
    //
    // Because there's no good way to clean up the allocation of the global driver information, 
    // the global information will be leaked.  This is deemed acceptable since it's not expected
    // that DriverEntry will be invoked often in the life of a Windows boot.
    //

    pMPDrvInfo = ExAllocatePoolWithTag(NonPagedPool, sizeof(MPDriverInfo), MP_TAG_GENERAL);

    if (!pMPDrvInfo) {                                // No good?
        status = STATUS_INSUFFICIENT_RESOURCES;

        goto Done;
    }

#endif

    pMPDrvInfoGlobal = pMPDrvInfo;                    // Save pointer in binary's storage.

    RtlZeroMemory(pMPDrvInfo, sizeof(MPDriverInfo));  // Set pMPDrvInfo's storage to a known state.

    pMPDrvInfo->pDriverObj = pDrvObj;                 // Save pointer to driver object.

    KeInitializeSpinLock(&pMPDrvInfo->DrvInfoLock);   // Initialize spin lock.

    InitializeListHead(&pMPDrvInfo->ListMPHBAObj);    // Initialize list head.

    // Get registry parameters.

    MpQueryRegParameters(pRegistryPath, &pMPDrvInfo->MPRegInfo);

    // Set up information for ScsiPortInitialize().

#ifdef USE_STORPORT
    hwInitData.HwInitializationDataSize = sizeof(VIRTUAL_HW_INITIALIZATION_DATA);
#endif
#ifdef USE_SCSIPORT
#if NT4_COMPATIBLE
    hwInitData.HwInitializationDataSize = FIELD_OFFSET(HW_INITIALIZATION_DATA, HwAdapterControl);
#else
    hwInitData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
#endif
#endif

    hwInitData.HwInitialize             = MpHwInitialize;           // Required for all ports.
    hwInitData.HwStartIo                = MpHwStartIo;              // Required for all ports.
    hwInitData.HwFindAdapter            = MpHwFindAdapter;          // Required for all ports.
    hwInitData.HwResetBus               = MpHwResetBus;             // Required for all ports.
#ifndef NT4_COMPATIBLE
    hwInitData.HwAdapterControl         = MpHwAdapterControl;       // Required for all post NT4 ports.
#endif
#ifdef USE_STORPORT
    hwInitData.HwFreeAdapterResources   = MpHwFreeAdapterResources; // Required for virtual StorPort.
#endif

    hwInitData.AutoRequestSense         = TRUE;
    hwInitData.TaggedQueuing            = TRUE;
    hwInitData.MultipleRequestPerLu     = TRUE;

    hwInitData.MapBuffers               = STORAGE_MAP_BUFFERS_SETTING;

    hwInitData.DeviceExtensionSize      = sizeof(HW_HBA_EXT);
    hwInitData.SpecificLuExtensionSize  = sizeof(PVOID);
    hwInitData.SrbExtensionSize         = sizeof(HW_SRB_EXTENSION);

    hwInitData.AdapterInterfaceType     = STORAGE_INTERFACE_TYPE;

    status =  StoragePortInitialize(                     // Tell port driver we're here.
                                    pDrvObj,
                                    pRegistryPath,
                                    (PHW_INITIALIZATION_DATA)&hwInitData,
                                    NULL
                                    );

    DbgPrint("PhDskMnt::DriverEntry: StoragePortInitialize returned 0x%x\n", status);

    if (NT_SUCCESS(status))
    {
        // Register our own unload routine

        pMPDrvInfo->pChainUnload = pDrvObj->DriverUnload;
        pDrvObj->DriverUnload = ImScsiUnload;

    }
    else
    {
        ImScsiFreeGlobalResources();
    }

    KdPrint2(("PhDskMnt::DriverEntry: End. status=0x%x\n", status));
    
    return status;
}                                                     // End DriverEntry().
Exemplo n.º 21
0
ULONG
MpHwFindAdapter(
                __in       PVOID                           DeviceExtension,
                __in       PVOID                           pReservedArg1,
                __in       PVOID                           pReservedArg2,
#ifdef USE_STORPORT
                __in       PVOID                           pReservedArg3,
#endif
                __in       PCHAR                           ArgumentString,
                __in __out PPORT_CONFIGURATION_INFORMATION pConfigInfo,
                __out      PBOOLEAN                        pBAgain
)
{
    ULONG              i,
                       len,
                       status = SP_RETURN_FOUND;
    PCHAR              pChar;
    pHW_HBA_EXT        pHBAExt = (pHW_HBA_EXT)DeviceExtension;
    NTSTATUS           ntstatus;
    
#if defined(_AMD64_)

    KLOCK_QUEUE_HANDLE LockHandle;

#else

    KIRQL              SaveIrql;

#endif

    UNREFERENCED_PARAMETER(pReservedArg1);
    UNREFERENCED_PARAMETER(pReservedArg2);
#ifdef USE_STORPORT
    UNREFERENCED_PARAMETER(pReservedArg3);
#endif
    UNREFERENCED_PARAMETER(ArgumentString);

    KdPrint2(("PhDskMnt::MpHwFindAdapter:  Arg=%s%s%s, pHBAExt = 0x%p, pConfigInfo = 0x%p, IRQL=%i\n",
        ArgumentString != NULL ? "\"" : "(",
        ArgumentString != NULL ? ArgumentString : "null",
        ArgumentString != NULL ? "\"" : ")",
        pHBAExt,
        pConfigInfo,
        KeGetCurrentIrql()));

    if (pMPDrvInfoGlobal->GlobalsInitialized)
    {
        LARGE_INTEGER wait_time;

        DbgPrint("PhDskMnt::MpHwFindAdapter: Already initialized.\n");

        wait_time.QuadPart = -1000000;
        KeDelayExecutionThread(KernelMode, FALSE, &wait_time);
    }

    KeInitializeSpinLock(&pHBAExt->LUListLock);
    InitializeListHead(&pHBAExt->LUList);

    pHBAExt->HostTargetId = (UCHAR)pMPDrvInfoGlobal->MPRegInfo.InitiatorID;

#ifdef USE_STORPORT
    pConfigInfo->VirtualDevice                  = TRUE;                        // Inidicate no real hardware.
    pConfigInfo->SynchronizationModel           = StorSynchronizeFullDuplex;
#endif
    pConfigInfo->WmiDataProvider                = FALSE;                       // Indicate WMI provider.
    pConfigInfo->MaximumTransferLength          = SP_UNINITIALIZED_VALUE;      // Indicate unlimited.
    pConfigInfo->AlignmentMask                  = 0x3;                         // Indicate DWORD alignment.
    pConfigInfo->CachesData                     = FALSE;                       // Indicate miniport wants flush and shutdown notification.
    pConfigInfo->MaximumNumberOfTargets         = SCSI_MAXIMUM_TARGETS;        // Indicate maximum targets.
    pConfigInfo->NumberOfBuses                  =
        (UCHAR) pMPDrvInfoGlobal->MPRegInfo.NumberOfBuses;                     // Indicate number of busses.
    pConfigInfo->ScatterGather                  = TRUE;                        // Indicate scatter-gather (explicit setting needed for Win2003 at least).
    pConfigInfo->AutoRequestSense               = TRUE;
    pConfigInfo->TaggedQueuing                  = TRUE;
    pConfigInfo->MultipleRequestPerLu           = TRUE;

    // Save Vendor Id, Product Id, Revision in device extension.

    pChar = (PCHAR)pMPDrvInfoGlobal->MPRegInfo.VendorId.Buffer;
    len = min(8, (pMPDrvInfoGlobal->MPRegInfo.VendorId.Length/2));
    for ( i = 0; i < len; i++, pChar+=2)
      pHBAExt->VendorId[i] = *pChar;

    pChar = (PCHAR)pMPDrvInfoGlobal->MPRegInfo.ProductId.Buffer;
    len = min(16, (pMPDrvInfoGlobal->MPRegInfo.ProductId.Length/2));
    for ( i = 0; i < len; i++, pChar+=2)
      pHBAExt->ProductId[i] = *pChar;

    pChar = (PCHAR)pMPDrvInfoGlobal->MPRegInfo.ProductRevision.Buffer;
    len = min(4, (pMPDrvInfoGlobal->MPRegInfo.ProductRevision.Length/2));
    for ( i = 0; i < len; i++, pChar+=2)
      pHBAExt->ProductRevision[i] = *pChar;

    // Add HBA extension to master driver object's linked list.

#if defined(_AMD64_)

    KeAcquireInStackQueuedSpinLock(&pMPDrvInfoGlobal->DrvInfoLock, &LockHandle);

#else

    KeAcquireSpinLock(&pMPDrvInfoGlobal->DrvInfoLock, &SaveIrql);

#endif

    InsertTailList(&pMPDrvInfoGlobal->ListMPHBAObj, &pHBAExt->List);

    pMPDrvInfoGlobal->DrvInfoNbrMPHBAObj++;

#if defined(_AMD64_)

    KeReleaseInStackQueuedSpinLock(&LockHandle);

#else

    KeReleaseSpinLock(&pMPDrvInfoGlobal->DrvInfoLock, SaveIrql);

#endif

    if (!pMPDrvInfoGlobal->GlobalsInitialized)
    {
        HANDLE thread_handle;
        OBJECT_ATTRIBUTES object_attributes;

        KeInitializeSpinLock(&pMPDrvInfoGlobal->RequestListLock);
        InitializeListHead(&pMPDrvInfoGlobal->RequestList);
        KeInitializeEvent(&pMPDrvInfoGlobal->RequestEvent, SynchronizationEvent, FALSE);

#ifdef USE_SCSIPORT
        KeInitializeSpinLock(&pMPDrvInfoGlobal->ResponseListLock);
        KeInitializeEvent(&pMPDrvInfoGlobal->ResponseEvent, SynchronizationEvent, FALSE);
        InitializeListHead(&pMPDrvInfoGlobal->ResponseList);
#endif

        KeInitializeEvent(&pMPDrvInfoGlobal->StopWorker, NotificationEvent, FALSE);

        pMPDrvInfoGlobal->GlobalsInitialized = TRUE;

        InitializeObjectAttributes(&object_attributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);

        ntstatus = PsCreateSystemThread(
            &thread_handle,
            (ACCESS_MASK) 0L,
            &object_attributes,
            NULL,
            NULL,
            ImScsiWorkerThread,
            NULL);

        if (!NT_SUCCESS(ntstatus))
        {
            DbgPrint("PhDskMnt::ScsiGetLUExtension: Cannot create worker thread. (%#x)\n", ntstatus);

            status = SP_RETURN_ERROR;
        }
        else
        {
            ObReferenceObjectByHandle(
                thread_handle,
                FILE_READ_ATTRIBUTES | SYNCHRONIZE,
                *PsThreadType,
                KernelMode,
                (PVOID*)&pMPDrvInfoGlobal->WorkerThread,
                NULL
                );

            ZwClose(thread_handle);

            //for (i = 0; i < pHBAExt->NbrLUNsperHBA; i++)
            //    ImScsiCreateLU(pHBAExt, 0, (UCHAR)i, 0);
        }
    }

//Done:
    *pBAgain = FALSE;    
        
    KdPrint2(("PhDskMnt::MpHwFindAdapter: End, status = 0x%x\n", status));

    return status;
}                                                     // End MpHwFindAdapter().
Exemplo n.º 22
0
VOID
ScsiIoControl(
__in pHW_HBA_EXT          pHBAExt,    // Adapter device-object extension from port driver.
__in PSCSI_REQUEST_BLOCK  pSrb,
__in PUCHAR               pResult,
__inout __deref PKIRQL         LowestAssumedIrql
)
{
    PSRB_IO_CONTROL  srb_io_control = (PSRB_IO_CONTROL)pSrb->DataBuffer;

    *pResult = ResultDone;

    if (pSrb->DataTransferLength < sizeof(SRB_IO_CONTROL)
        || ((srb_io_control->HeaderLength != sizeof(SRB_IO_CONTROL)) |
        (srb_io_control->HeaderLength + srb_io_control->Length > pSrb->DataTransferLength)))
    {
        KdPrint2(("PhDskMnt::ScsiIoControl: Malformed MiniportIOCtl detected.\n",
            sizeof(srb_io_control->Signature),
            srb_io_control->Signature));

        ScsiSetError(pSrb, SRB_STATUS_INVALID_REQUEST);
        goto Done;
    }

    if (memcmp(srb_io_control->Signature, IMSCSI_FUNCTION_SIGNATURE,
        sizeof(IMSCSI_FUNCTION_SIGNATURE) - 1))
    {
        KdPrint2(("PhDskMnt::ScsiIoControl: MiniportIOCtl sig '%.*s' not supported\n",
            sizeof(srb_io_control->Signature),
            srb_io_control->Signature));

        ScsiSetError(pSrb, SRB_STATUS_INVALID_REQUEST);
        goto Done;
    }

    KdPrint2(("PhDskMnt::ScsiIoControl: Miniport IOCtl ControlCode = %#x\n",
        srb_io_control->ControlCode));

    switch (srb_io_control->ControlCode)
    {
    case SMP_IMSCSI_CHECK:
    {
        KdPrint2(("PhDskMnt::ScsiIoControl: Request to complete SRBs.\n"));
        srb_io_control->ReturnCode = STATUS_SUCCESS;
        ScsiSetSuccess(pSrb, 0);

        break;
    }

    case SMP_IMSCSI_CREATE_DEVICE:
    {
        PSRB_IMSCSI_CREATE_DATA srb_buffer = (PSRB_IMSCSI_CREATE_DATA)pSrb->DataBuffer;

        if ((srb_buffer->SrbIoControl.HeaderLength + srb_buffer->SrbIoControl.Length <
            FIELD_OFFSET(SRB_IMSCSI_CREATE_DATA, Fields.FileName))
            || (srb_buffer->Fields.FileNameLength +
            (ULONG)FIELD_OFFSET(SRB_IMSCSI_CREATE_DATA, Fields.FileName) >
            pSrb->DataTransferLength))
        {
            KdPrint(("PhDskMnt::ScsiIoControl: Bad SMP_IMSCSI_CREATE_DEVICE request.\n"));

            ScsiSetError(pSrb, SRB_STATUS_DATA_OVERRUN);
            goto Done;
        }

        ImScsiCreateDevice(pHBAExt, pSrb, pResult, LowestAssumedIrql);

        break;
    }

    case SMP_IMSCSI_REMOVE_DEVICE:
    {
        PSRB_IMSCSI_REMOVE_DEVICE srb_buffer = (PSRB_IMSCSI_REMOVE_DEVICE)pSrb->DataBuffer;

        KdPrint2(("PhDskMnt::ScsiIoControl: Request to remove device.\n"));

        if (!SRB_IO_CONTROL_SIZE_OK(srb_buffer))
        {
            KdPrint(("PhDskMnt::ScsiIoControl: Bad SMP_IMSCSI_REMOVE_DEVICE request.\n"));

            ScsiSetError(pSrb, SRB_STATUS_DATA_OVERRUN);
            goto Done;
        }

        srb_io_control->ReturnCode = ImScsiRemoveDevice(pHBAExt, &srb_buffer->DeviceNumber, LowestAssumedIrql);

        ScsiSetSuccess(pSrb, pSrb->DataTransferLength);

        break;
    }

    case SMP_IMSCSI_QUERY_VERSION:
    {
        PSRB_IMSCSI_QUERY_VERSION srb_buffer = (PSRB_IMSCSI_QUERY_VERSION)pSrb->DataBuffer;

        KdPrint2(("PhDskMnt::ScsiIoControl: Request for driver version.\n"));

        if (!SRB_IO_CONTROL_SIZE_OK(srb_buffer))
        {
            srb_io_control->ReturnCode = IMSCSI_DRIVER_VERSION;
            srb_io_control->Length = 0;

            ScsiSetSuccess(pSrb, pSrb->DataTransferLength);

            break;
        }

        srb_io_control->ReturnCode = IMSCSI_DRIVER_VERSION;
        srb_io_control->Length = sizeof(*srb_buffer) - sizeof(srb_buffer->SrbIoControl);
        srb_buffer->SubVersion = PHDSKMNT_VERSION_ULONG;

        ScsiSetSuccess(pSrb, pSrb->DataTransferLength);

        break;
    }

    case SMP_IMSCSI_QUERY_DEVICE:
    {
        PSRB_IMSCSI_CREATE_DATA srb_buffer = (PSRB_IMSCSI_CREATE_DATA)pSrb->DataBuffer;

        KdPrint2(("PhDskMnt::ScsiIoControl: Request SMP_IMSCSI_QUERY_DEVICE.\n"));

        if (!SRB_IO_CONTROL_SIZE_OK(srb_buffer))
        {
            KdPrint(("PhDskMnt::ScsiIoControl: Bad SMP_IMSCSI_QUERY_DEVICE request.\n"));

            pSrb->DataTransferLength = 0;
            ScsiSetError(pSrb, SRB_STATUS_DATA_OVERRUN);
            goto Done;
        }

        srb_io_control->ReturnCode = ImScsiQueryDevice(pHBAExt, srb_buffer, &pSrb->DataTransferLength, LowestAssumedIrql);

        ScsiSetSuccess(pSrb, pSrb->DataTransferLength);

        break;
    }

    case SMP_IMSCSI_QUERY_ADAPTER:
    {
        PSRB_IMSCSI_QUERY_ADAPTER srb_buffer = (PSRB_IMSCSI_QUERY_ADAPTER)pSrb->DataBuffer;

        KdPrint2(("PhDskMnt::ScsiIoControl: Request SMP_IMSCSI_QUERY_ADAPTER.\n"));

        if (!SRB_IO_CONTROL_SIZE_OK(srb_buffer))
        {
            KdPrint(("PhDskMnt::ScsiIoControl: Bad SMP_IMSCSI_QUERY_ADAPTER request.\n"));

            ScsiSetError(pSrb, SRB_STATUS_DATA_OVERRUN);
            goto Done;
        }

        srb_io_control->ReturnCode = ImScsiQueryAdapter(pHBAExt, srb_buffer, pSrb->DataTransferLength, LowestAssumedIrql);

        ScsiSetSuccess(pSrb, pSrb->DataTransferLength);

        break;
    }

    case SMP_IMSCSI_SET_DEVICE_FLAGS:
    {
        PSRB_IMSCSI_SET_DEVICE_FLAGS srb_buffer = (PSRB_IMSCSI_SET_DEVICE_FLAGS)pSrb->DataBuffer;

        KdPrint2(("PhDskMnt::ScsiIoControl: Request SMP_IMSCSI_SET_DEVICE_FLAGS.\n"));

        if (!SRB_IO_CONTROL_SIZE_OK(srb_buffer))
        {
            KdPrint(("PhDskMnt::ScsiIoControl: Bad SMP_IMSCSI_SET_DEVICE_FLAGS request.\n"));

            ScsiSetError(pSrb, SRB_STATUS_DATA_OVERRUN);
            goto Done;
        }

        srb_io_control->ReturnCode = ImScsiSetFlagsDevice(pHBAExt, srb_buffer, LowestAssumedIrql);

        ScsiSetSuccess(pSrb, pSrb->DataTransferLength);

        break;
    }

    case SMP_IMSCSI_EXTEND_DEVICE:
    {
        PSRB_IMSCSI_EXTEND_DEVICE srb_buffer = (PSRB_IMSCSI_EXTEND_DEVICE)pSrb->DataBuffer;

        KdPrint2(("PhDskMnt::ScsiIoControl: Request SMP_IMSCSI_EXTEND_DEVICE.\n"));

        if (!SRB_IO_CONTROL_SIZE_OK(srb_buffer))
        {
            KdPrint(("PhDskMnt::ScsiIoControl: Bad SMP_IMSCSI_EXTEND_DEVICE request.\n"));

            ScsiSetError(pSrb, SRB_STATUS_DATA_OVERRUN);
            goto Done;
        }

        ImScsiExtendDevice(pHBAExt, pSrb, pResult, LowestAssumedIrql, srb_buffer);

        break;
    }

    default:

        DbgPrint("PhDskMnt::ScsiExecute: Unknown IOControl code=0x%X\n", srb_io_control->ControlCode);

        ScsiSetError(pSrb, SRB_STATUS_INVALID_REQUEST);
        break;

    } // end switch

Done:
    KdPrint2(("PhDskMnt::ScsiIoControl: End: *Result=%i\n", (INT)*pResult));

    return;
}
Exemplo n.º 23
0
VOID
ImScsiCreateDevice(
__in pHW_HBA_EXT          pHBAExt,
__in PSCSI_REQUEST_BLOCK  pSrb,
__inout __deref PUCHAR         pResult,
__inout __deref PKIRQL         LowestAssumedIrql
)
{
    pHW_LU_EXTENSION        pLUExt = NULL;
    PSRB_IMSCSI_CREATE_DATA new_device = (PSRB_IMSCSI_CREATE_DATA)pSrb->DataBuffer;
    pMP_WorkRtnParms        pWkRtnParms;
    KLOCK_QUEUE_HANDLE      lock_handle;

    // If auto-selecting device number
    if (new_device->Fields.DeviceNumber.LongNumber == IMSCSI_AUTO_DEVICE_NUMBER)
    {
        KdPrint(("PhDskMnt::ImScsiCreateDevice: Auto-select device number.\n"));

        for (new_device->Fields.DeviceNumber.PathId = 0;
            new_device->Fields.DeviceNumber.PathId < pMPDrvInfoGlobal->MPRegInfo.NumberOfBuses;
            new_device->Fields.DeviceNumber.PathId++)
        {
            for (new_device->Fields.DeviceNumber.Lun = 0;
                new_device->Fields.DeviceNumber.Lun < MAX_LUNS;
                new_device->Fields.DeviceNumber.Lun++)
            {
                for (new_device->Fields.DeviceNumber.TargetId = 0;
                    new_device->Fields.DeviceNumber.TargetId < MAX_TARGETS;
                    new_device->Fields.DeviceNumber.TargetId++)
                {
#ifdef USE_SCSIPORT
                    // With SCSIPORT, reserve device 0:0:0 as control device
                    if (new_device->Fields.DeviceNumber.LongNumber == 0)
                        continue;
#endif

                    ScsiGetLUExtension(
                        pHBAExt,
                        &pLUExt,
                        new_device->Fields.DeviceNumber.PathId,
                        new_device->Fields.DeviceNumber.TargetId,
                        new_device->Fields.DeviceNumber.Lun,
                        LowestAssumedIrql
                        );

                    if (pLUExt == NULL)
                        break;
                }

                if (pLUExt == NULL)
                    break;
            }

            if (pLUExt == NULL)
                break;
        }

        if (pLUExt != NULL)
        {
            KdPrint(("PhDskMnt::ImScsiCreateDevice: No free device number found.\n"));
            new_device->SrbIoControl.ReturnCode = (ULONG)STATUS_NO_MORE_ENTRIES;
            ScsiSetSuccess(pSrb, pSrb->DataTransferLength);
            return;
        }

        KdPrint(("PhDskMnt::ImScsiCreateDevice: PathId=%i, TargetId=%i, Lun=%i.\n",
            (int)new_device->Fields.DeviceNumber.PathId,
            (int)new_device->Fields.DeviceNumber.TargetId,
            (int)new_device->Fields.DeviceNumber.Lun));
    }
    else
    {
        KdPrint(("PhDskMnt::ImScsiCreateDevice: PathId=%i, TargetId=%i, Lun=%i.\n",
            (int)new_device->Fields.DeviceNumber.PathId,
            (int)new_device->Fields.DeviceNumber.TargetId,
            (int)new_device->Fields.DeviceNumber.Lun));

#ifdef USE_SCSIPORT
        if (new_device->Fields.DeviceNumber.LongNumber == 0)
        {
            DbgPrint("PhDskMnt::ImScsiCreateDevice: Device number 0:0:0 is reserved.\n");
            new_device->SrbIoControl.ReturnCode = (ULONG)STATUS_OBJECT_NAME_COLLISION;
            ScsiSetSuccess(pSrb, pSrb->DataTransferLength);
            return;
        }
#endif

        ScsiGetLUExtension(
            pHBAExt,
            &pLUExt,
            new_device->Fields.DeviceNumber.PathId,
            new_device->Fields.DeviceNumber.TargetId,
            new_device->Fields.DeviceNumber.Lun,
            LowestAssumedIrql
            );

        if (pLUExt != NULL)
        {
            KdPrint(("PhDskMnt::ImScsiCreateDevice: Device already exists.\n"));
            new_device->SrbIoControl.ReturnCode = (ULONG)STATUS_OBJECT_NAME_COLLISION;
            ScsiSetSuccess(pSrb, pSrb->DataTransferLength);
            return;
        }
    }

    pWkRtnParms =                                     // Allocate parm area for work routine.
        (pMP_WorkRtnParms)ExAllocatePoolWithTag(NonPagedPool, sizeof(MP_WorkRtnParms), MP_TAG_GENERAL);

    if (pWkRtnParms == NULL)
    {
        DbgPrint("PhDskMnt::ImScsiCreateDevice Failed to allocate work parm structure\n");

        new_device->SrbIoControl.ReturnCode = (ULONG)STATUS_INSUFFICIENT_RESOURCES;
        ScsiSetSuccess(pSrb, pSrb->DataTransferLength);
        return;
    }

    RtlZeroMemory(pWkRtnParms, sizeof(MP_WorkRtnParms));

    pWkRtnParms->pHBAExt = pHBAExt;
    pWkRtnParms->pSrb = pSrb;
    pWkRtnParms->pReqThread = PsGetCurrentThread();

    ObReferenceObject(pWkRtnParms->pReqThread);

    // Queue work item, which will run in the System process.

    KdPrint2(("PhDskMnt::ImScsiCreateDevice: Queuing work=0x%p\n", pWkRtnParms));

    new_device->SrbIoControl.ReturnCode = (ULONG)STATUS_PENDING;

    ImScsiAcquireLock(&pMPDrvInfoGlobal->RequestListLock, &lock_handle, *LowestAssumedIrql);

    InsertTailList(&pMPDrvInfoGlobal->RequestList, &pWkRtnParms->RequestListEntry);

    ImScsiReleaseLock(&lock_handle, LowestAssumedIrql);

    KeSetEvent(&pMPDrvInfoGlobal->RequestEvent, (KPRIORITY)0, FALSE);

    *pResult = ResultQueued;                          // Indicate queuing.

    StoragePortNotification(BusChangeDetected, pHBAExt, new_device->Fields.DeviceNumber.PathId);

    KdPrint(("PhDskMnt::ImScsiCreateDevice: End: *Result=%i\n", *pResult));

    return;
}
Exemplo n.º 24
0
NTSTATUS
AWEAllocMapPage(IN POBJECT_CONTEXT Context,
		IN LONGLONG Offset)
{
  LONGLONG page_base = AWEAllocGetPageBaseFromAbsOffset(Offset);
  LONGLONG page_base_within_block;
  ULONG size_to_map = ALLOC_PAGE_SIZE;
  PBLOCK_DESCRIPTOR block;
  NTSTATUS status;

  KdPrint2(("AWEAlloc: MapPage request Offset=%#I64x BaseAddress=%#I64x.\n",
	    Offset,
	    page_base));

  if ((Context->CurrentPageBase == page_base) &
      (Context->CurrentMdl != NULL) &
      (Context->CurrentPtr != NULL))
    {
      KdPrint2(("AWEAlloc: MapPage: Page already mapped.\n"));
      return STATUS_SUCCESS;
    }

  // Find block that contains this page
  for (block = Context->FirstBlock;
       block != NULL;
       block = block->NextBlock)
    if (block->Offset <= page_base)
      break;

  if (block == NULL)
    {
      DbgPrint("AWEAlloc: MapPage: Cannot find blk for BaseAddress=%#I64x.\n",
	       page_base);

      return STATUS_DRIVER_INTERNAL_ERROR;
    }

  page_base_within_block = page_base - block->Offset;

  KdPrint2(("AWEAlloc: MapPage found blk Offset=%#I64x BaseAddress=%#I64x.\n",
	    block->Offset,
	    page_base_within_block));

  status = AWEAllocTryAcquireProtection(Context, TRUE);
  if (!NT_SUCCESS(status))
    {
      DbgPrint("AWEAlloc: Block table busy.\n");
      return status;
    }

  Context->CurrentPtr = NULL;
  Context->CurrentPageBase = (ULONG_PTR)-1;

  try
    {
      try
	{
	  if (Context->CurrentMdl != NULL)
	    IoFreeMdl(Context->CurrentMdl);

	  Context->CurrentMdl = NULL;

	  Context->CurrentMdl =
	    IoAllocateMdl(MmGetMdlVirtualAddress(block->Mdl),
			  size_to_map,
			  FALSE,
			  FALSE,
			  NULL);

	  if (Context->CurrentMdl == NULL)
	    {
	      DbgPrint("AWEAlloc: IoAllocateMdl() FAILED.\n");
	      return STATUS_INSUFFICIENT_RESOURCES;
	    }

	  if ((MmGetMdlByteCount(block->Mdl) - page_base_within_block) <
	      size_to_map)
	    {
	      KdPrint
		(("AWEAlloc: Incomplete page size! Shrinking page size.\n"));
	      size_to_map = 0;  // This will map remaining bytes
	    }

	  IoBuildPartialMdl(block->Mdl,
			    Context->CurrentMdl,
			    (PUCHAR) MmGetMdlVirtualAddress(block->Mdl) +
			    page_base_within_block,
			    size_to_map);

	  Context->CurrentPtr =
	    MmGetSystemAddressForMdlSafe(Context->CurrentMdl,
					 HighPagePriority);

	  if (Context->CurrentPtr == NULL)
	    {
	      DbgPrint("AWEAlloc: MmGetSystemAddressForMdlSafe() FAILED.\n");
	      
	      AWEAllocLogError(AWEAllocDriverObject,
			       0,
			       0,
			       NULL,
			       0,
			       1000,
			       STATUS_INSUFFICIENT_RESOURCES,
			       101,
			       STATUS_INSUFFICIENT_RESOURCES,
			       0,
			       0,
			       NULL,
			       L"MmGetSystemAddressForMdlSafe() failed during "
			       L"page mapping.");

	      IoFreeMdl(Context->CurrentMdl);
	      Context->CurrentMdl = NULL;
	      return STATUS_INSUFFICIENT_RESOURCES;
	    }

	  Context->CurrentPageBase = page_base;

	  KdPrint2(("AWEAlloc: MapPage success BaseAddress=%#I64x.\n",
		    page_base));
	}
      finally
	{
	  AWEAllocReleaseProtection(Context, TRUE);
	}
    }
  except (EXCEPTION_EXECUTE_HANDLER)
    {
      DbgPrint("AWEAlloc: Exception occured during page mapping.\n");

      AWEAllocLogError(AWEAllocDriverObject,
		       0,
		       0,
		       NULL,
		       0,
		       1000,
		       STATUS_INSUFFICIENT_RESOURCES,
		       101,
		       STATUS_INSUFFICIENT_RESOURCES,
		       0,
		       0,
		       NULL,
		       L"Exception occured during page mapping.");

      return STATUS_INSUFFICIENT_RESOURCES;
    }

  return STATUS_SUCCESS;
}
Exemplo n.º 25
0
VOID
ImScsiExtendDevice(
    __in pHW_HBA_EXT          pHBAExt,
    __in PSCSI_REQUEST_BLOCK  pSrb,
    __inout __deref PUCHAR         pResult,
    __inout __deref PKIRQL         LowestAssumedIrql,
    __inout __deref PSRB_IMSCSI_EXTEND_DEVICE       extend_device_data
    )
{
    UCHAR scsi_status;
    pHW_LU_EXTENSION device_extension;

    KdPrint(("ImScsi: Request to grow device %i:%i:%i by %I64i bytes.\n",
        (int)extend_device_data->DeviceNumber.PathId,
        (int)extend_device_data->DeviceNumber.TargetId,
        (int)extend_device_data->DeviceNumber.Lun,
        extend_device_data->ExtendSize.QuadPart));

    scsi_status = ScsiGetLUExtension(
        pHBAExt,
        &device_extension,
        extend_device_data->DeviceNumber.PathId,
        extend_device_data->DeviceNumber.TargetId,
        extend_device_data->DeviceNumber.Lun,
        LowestAssumedIrql
        );

    if ((scsi_status != SRB_STATUS_SUCCESS) | (device_extension == NULL))
    {
        extend_device_data->SrbIoControl.ReturnCode = (ULONG)STATUS_OBJECT_NAME_NOT_FOUND;
        ScsiSetSuccess(pSrb, pSrb->DataTransferLength);
        return;
    }

    if (device_extension->ReadOnly)
    {
        extend_device_data->SrbIoControl.ReturnCode = (ULONG)STATUS_MEDIA_WRITE_PROTECTED;
        ScsiSetSuccess(pSrb, pSrb->DataTransferLength);
        return;
    }

    pMP_WorkRtnParms pWkRtnParms =                                     // Allocate parm area for work routine.
        (pMP_WorkRtnParms)ExAllocatePoolWithTag(NonPagedPool, sizeof(MP_WorkRtnParms), MP_TAG_GENERAL);

    if (pWkRtnParms == NULL)
    {
        DbgPrint("ImScsi::ImScsiExtendDevice Failed to allocate work parm structure\n");

        ScsiSetCheckCondition(pSrb, SRB_STATUS_ERROR, SCSI_SENSE_HARDWARE_ERROR, SCSI_ADSENSE_NO_SENSE, 0);
        return;
    }

    RtlZeroMemory(pWkRtnParms, sizeof(MP_WorkRtnParms));

    pWkRtnParms->pHBAExt = pHBAExt;
    pWkRtnParms->pLUExt = device_extension;
    pWkRtnParms->pSrb = pSrb;

    KEVENT wait_event;
    BOOLEAN wait_result = KeGetCurrentIrql() < DISPATCH_LEVEL;

    if (wait_result)
    {
        KeInitializeEvent(&wait_event, EVENT_TYPE::NotificationEvent, FALSE);
        pWkRtnParms->CallerWaitEvent = &wait_event;
    }

    // Queue work item, which will run in the System process.
    KLOCK_QUEUE_HANDLE           lock_handle;

    KdPrint2(("PhDskMnt::ImScsiExtendDevice: Queuing work=0x%p\n", pWkRtnParms));

    ImScsiAcquireLock(&device_extension->RequestListLock, &lock_handle, *LowestAssumedIrql);

    InsertTailList(&device_extension->RequestList, &pWkRtnParms->RequestListEntry);

    ImScsiReleaseLock(&lock_handle, LowestAssumedIrql);

    KeSetEvent(&device_extension->RequestEvent, (KPRIORITY)0, FALSE);

    *pResult = ResultQueued;                          // Indicate queuing.

    if (wait_result)
    {
        KeWaitForSingleObject(&wait_event, KWAIT_REASON::Executive, MODE::KernelMode, FALSE, NULL);
    }

    StoragePortNotification(BusChangeDetected, pHBAExt, extend_device_data->DeviceNumber.PathId);

    return;
}
Exemplo n.º 26
0
NTSTATUS
ImScsiRemoveDevice(
__in            pHW_HBA_EXT     pHBAExt,
__in            PDEVICE_NUMBER  DeviceNumber,
__inout __deref PKIRQL          LowestAssumedIrql
)
{
    PLIST_ENTRY             list_ptr;
    NTSTATUS                status;
    ULONG                   count = 0;
    KLOCK_QUEUE_HANDLE      LockHandle;
    UCHAR                   pathId = DeviceNumber->PathId;

    KdPrint(("PhDskMnt::ImScsiRemoveDevice: PathId=%i, TargetId=%i, Lun=%i.\n",
        (int)DeviceNumber->PathId, (int)DeviceNumber->TargetId, (int)DeviceNumber->Lun));

    ImScsiAcquireLock(                   // Serialize the linked list of LUN extensions.              
        &pHBAExt->LUListLock, &LockHandle, *LowestAssumedIrql);

    for (list_ptr = pHBAExt->LUList.Flink;
        list_ptr != &pHBAExt->LUList;
        list_ptr = list_ptr->Flink
        )
    {
        pHW_LU_EXTENSION object;
        object = CONTAINING_RECORD(list_ptr, HW_LU_EXTENSION, List);

        if ((DeviceNumber->LongNumber ==
            IMSCSI_ALL_DEVICES) |
            (object->DeviceNumber.LongNumber ==
            DeviceNumber->LongNumber))
        {
            count++;
            KeSetEvent(&object->StopThread, (KPRIORITY)0, FALSE);
            KeSetEvent(&object->RequestEvent, (KPRIORITY)0, FALSE);
        }
    }

    ImScsiReleaseLock(&LockHandle, LowestAssumedIrql);

    if (count == 0)
    {
        KdPrint(("PhDskMnt::ImScsiRemoveDevice: Non-existing device.\n"));
        status = STATUS_OBJECT_NAME_NOT_FOUND;
        goto Done;
    }

    KdPrint(("PhDskMnt::ImScsiRemoveDevice: Found %i device(s).\n", count));

    status = STATUS_SUCCESS;

    if (pathId == 0xFF)
        pathId = 0x00;

    StoragePortNotification(BusChangeDetected, pHBAExt, pathId);

Done:
    KdPrint2(("PhDskMnt::ImScsiRemoveDevice: End: status=0x%X, *Result=%i\n", status));

    return status;
}
Exemplo n.º 27
0
BOOLEAN
MpHwStartIo(
__in                PVOID                DeviceExtension,  // Adapter device-object extension from port driver.
__inout __deref     PSCSI_REQUEST_BLOCK  pSrb
)
{
    KIRQL                   lowest_assumed_irql = PASSIVE_LEVEL;
    ResultType              Result = ResultDone;
    pHW_HBA_EXT             pHBAExt = (pHW_HBA_EXT)DeviceExtension;
#ifdef USE_SCSIPORT
    UCHAR                   PathId = pSrb->PathId;
    UCHAR                   TargetId = pSrb->TargetId;
    UCHAR                   Lun = pSrb->Lun;
#endif

    KdPrint2(("PhDskMnt::MpHwStartIo:  pHBAExt = 0x%p, pSrb = 0x%p, Path=%i, Target=%i, Lun=%i, IRQL=%i\n",
        pHBAExt,
        pSrb,
        (int)pSrb->PathId,
        (int)pSrb->TargetId,
        (int)pSrb->Lun,
        KeGetCurrentIrql()));

    pSrb->SrbStatus = SRB_STATUS_PENDING;
    pSrb->ScsiStatus = SCSISTAT_GOOD;

    ImScsiCompletePendingSrbs(pHBAExt, &lowest_assumed_irql);

    _InterlockedExchangeAdd((volatile LONG *)&pHBAExt->SRBsSeen, 1);   // Bump count of SRBs encountered.

    // Next, if true, will cause port driver to remove the associated LUNs if, for example, devmgmt.msc is asked "scan for hardware changes."
    //if (pHBAExt->bDontReport)
    //{                       // Act as though the HBA/path is gone?
    //    pSrb->SrbStatus = SRB_STATUS_NO_DEVICE;
    //    goto done;
    //}

    switch (pSrb->Function)
    {
    case SRB_FUNCTION_IO_CONTROL:
        ScsiIoControl(pHBAExt, pSrb, &Result, &lowest_assumed_irql);
        break;

    case SRB_FUNCTION_EXECUTE_SCSI:
        if (pSrb->Cdb[0] == SCSIOP_REPORT_LUNS)
        {
            ScsiOpReportLuns(pHBAExt, pSrb, &lowest_assumed_irql);
        }
        else
        {
            ScsiExecute(pHBAExt, pSrb, &Result, &lowest_assumed_irql);
        }
        break;

    case SRB_FUNCTION_RESET_LOGICAL_UNIT:
        DbgPrint("PhDskMnt::MpHwStartIo: SRB_FUNCTION_RESET_LOGICAL_UNIT.\n");
        pSrb->SrbStatus = ScsiResetLun(pHBAExt, pSrb);
        break;

    case SRB_FUNCTION_RESET_DEVICE:
        DbgPrint("PhDskMnt::MpHwStartIo: SRB_FUNCTION_RESET_DEVICE.\n");
        pSrb->SrbStatus = ScsiResetDevice(pHBAExt, pSrb);
        break;

    case SRB_FUNCTION_RESET_BUS:
        DbgPrint("PhDskMnt::MpHwStartIo: SRB_FUNCTION_RESET_BUS.\n");
        pSrb->SrbStatus = MpHwResetBus(pHBAExt, pSrb->PathId);
        break;

    case SRB_FUNCTION_PNP:
        ScsiPnP(pHBAExt, (PSCSI_PNP_REQUEST_BLOCK)pSrb, &lowest_assumed_irql);
        break;

    case SRB_FUNCTION_POWER:
        KdPrint(("PhDskMnt::MpHwStartIo: SRB_FUNCTION_POWER.\n"));
        // Do nothing.
        pSrb->SrbStatus = SRB_STATUS_SUCCESS;

        break;

    case SRB_FUNCTION_SHUTDOWN:
        KdPrint(("PhDskMnt::MpHwStartIo: SRB_FUNCTION_SHUTDOWN.\n"));
        // Do nothing.
        pSrb->SrbStatus = SRB_STATUS_SUCCESS;

        break;

    default:
        KdPrint(("PhDskMnt::MpHwStartIo: Unknown pSrb Function = 0x%X\n", pSrb->Function));

        //StorPortLogError(pHBAExt, pSrb, pSrb->PathId, pSrb->TargetId, pSrb->Lun, SP_PROTOCOL_ERROR, 0x0200 | pSrb->Cdb[0]);

        ScsiSetCheckCondition(pSrb, SRB_STATUS_ERROR, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ADSENSE_ILLEGAL_COMMAND, 0);

        break;

    } // switch (pSrb->Function)

    if (Result == ResultDone)
    {                         // Complete now?
#ifdef USE_SCSIPORT
        KdPrint2(("PhDskMnt::MpHwStartIo sending 'RequestComplete', 'NextRequest' and 'NextLuRequest' to ScsiPort.\n"));
        ScsiPortNotification(RequestComplete, pHBAExt, pSrb);
        ScsiPortNotification(NextRequest, pHBAExt);
        ScsiPortNotification(NextLuRequest, pHBAExt, 0, 0, 0);
#endif
#ifdef USE_STORPORT
        KdPrint2(("PhDskMnt::MpHwStartIo sending 'RequestComplete' to port StorPort.\n"));
        StorPortNotification(RequestComplete, pHBAExt, pSrb);
#endif
    }
    else
    {
#ifdef USE_SCSIPORT
        _InterlockedExchangeAdd((volatile LONG*)&pHBAExt->WorkItems, 1);

        KdPrint2(("PhDskMnt::MpHwStartIo sending 'RequestTimerCall' and 'NextLuRequest' to ScsiPort.\n"));
        ScsiPortNotification(RequestTimerCall, pHBAExt, MpHwTimer, (ULONG)1);
        ScsiPortNotification(NextLuRequest, pHBAExt, PathId, TargetId, Lun);
        ScsiPortNotification(NextLuRequest, pHBAExt, 0, 0, 0);
#endif
    }

    KdPrint2(("PhDskMnt::MpHwStartIo End.\n"));

    return TRUE;
}                                                     // End MpHwStartIo().
Exemplo n.º 28
0
NTSTATUS
AWEAllocSetInformation(IN PDEVICE_OBJECT DeviceObject,
		       IN PIRP Irp)
{
  PIO_STACK_LOCATION io_stack = IoGetCurrentIrpStackLocation(Irp);
  POBJECT_CONTEXT context = io_stack->FileObject->FsContext2;

  PAGED_CODE();

  KdPrint2(("AWEAlloc: SetFileInformation: %u.\n",
	    io_stack->Parameters.SetFile.FileInformationClass));

  switch (io_stack->Parameters.SetFile.FileInformationClass)
    {
    case FileAllocationInformation:
    case FileEndOfFileInformation:
      {
	NTSTATUS status;
	PFILE_END_OF_FILE_INFORMATION feof_info =
	  (PFILE_END_OF_FILE_INFORMATION) Irp->AssociatedIrp.SystemBuffer;

	if (io_stack->Parameters.SetFile.Length <
	    sizeof(FILE_END_OF_FILE_INFORMATION))
	  {
	    Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
	    Irp->IoStatus.Information = 0;
	    IoCompleteRequest(Irp, IO_NO_INCREMENT);
	    return STATUS_BUFFER_TOO_SMALL;
	  }

	status = AWEAllocTryAcquireProtection(context, TRUE);
	if (!NT_SUCCESS(status))
	  {
	    DbgPrint("AWEAlloc: Page table busy.\n");
	    Irp->IoStatus.Status = status;
	    Irp->IoStatus.Information = 0;
	    IoCompleteRequest(Irp, IO_NO_INCREMENT);
	    return status;
	  }

	status = AWEAllocSetSize(context,
				 &Irp->IoStatus,
				 &feof_info->EndOfFile);

	AWEAllocReleaseProtection(context, TRUE);

	IoCompleteRequest(Irp, IO_NO_INCREMENT);

	return status;
      }

    case FilePositionInformation:
      {
	PFILE_POSITION_INFORMATION position_info =
	  (PFILE_POSITION_INFORMATION) Irp->AssociatedIrp.SystemBuffer;

	if (io_stack->Parameters.SetFile.Length <
	    sizeof(FILE_POSITION_INFORMATION))
	  {
	    Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
	    Irp->IoStatus.Information = 0;
	    IoCompleteRequest(Irp, IO_NO_INCREMENT);
	    return STATUS_INVALID_PARAMETER;
	  }

	io_stack->FileObject->CurrentByteOffset =
	  position_info->CurrentByteOffset;

	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = 0;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
      }

    case FileBasicInformation:
    case FileDispositionInformation:
    case FileValidDataLengthInformation:
      Irp->IoStatus.Status = STATUS_SUCCESS;
      Irp->IoStatus.Information = 0;
      IoCompleteRequest(Irp, IO_NO_INCREMENT);
      return STATUS_SUCCESS;

    default:
      KdPrint(("AWEAlloc: Unsupported SetFile.FileInformationClass: %u\n",
	       io_stack->Parameters.SetFile.FileInformationClass));

      Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
      Irp->IoStatus.Information = 0;
      IoCompleteRequest(Irp, IO_NO_INCREMENT);
      return STATUS_INVALID_DEVICE_REQUEST;
    }
}