Esempio n. 1
0
/**
 * IRP_MJ_PNP:IRP_MN_QUERY_BUS_INFORMATION handler
 *
 * IRQL == PASSIVE_LEVEL, any thread
 * Do not send this IRP
 * Completed by PDO (here)
 *
 * @return
 *   Success:
 *     Irp->IoStatus.Status == STATUS_SUCCESS
 *     Irp->IoStatus.Information populated from paged memory
 *   Error:
 *     Irp->IoStatus.Status == STATUS_INSUFFICIENT_RESOURCES
 *     Irp->IoStatus.Information == 0
 *
 * TODO: Maybe it's best for a PDO to query its parent for this info,
 * instead of carrying it around
 */
static NTSTATUS STDCALL WvDummyPnpQueryBusInfo(
    IN DEVICE_OBJECT * dev_obj,
    IN IRP * irp
  ) {
    S_WVL_DUMMY_PDO * dummy;
    VOID * pnp_bus_info;
    NTSTATUS status;

    ASSERT(dev_obj);
    ASSERT(irp);
    dummy = dev_obj->DeviceExtension;
    ASSERT(dummy);

    /* Allocate for a copy of the bus info */
    pnp_bus_info = wv_palloc(sizeof dummy->PnpBusInfo);
    if (!pnp_bus_info) {
        DBG("wv_palloc failed\n");
        status = STATUS_INSUFFICIENT_RESOURCES;
        irp->IoStatus.Information = 0;
        goto pnp_bus_info;
      }

    /* Copy the bus info */
    RtlCopyMemory(pnp_bus_info, dummy->PnpBusInfo, sizeof dummy->PnpBusInfo);

    irp->IoStatus.Information = (ULONG_PTR) pnp_bus_info;
    status = STATUS_SUCCESS;

    /* irp->IoStatus.Information (pnp_bus_info) not freed */
    pnp_bus_info:

    irp->IoStatus.Status = status;
    WvlPassIrpUp(dev_obj, irp, IO_NO_INCREMENT);
    return status;
  }
Esempio n. 2
0
/**
 * Handle a PnP ID query with a WV_S_DUMMY_IDS object.
 *
 * @v Irp               The PnP ID query IRP to handle.
 * @v DummyIds          The object containing the IDs to respond with.
 * @ret NTSTATUS        The status of the operation.
 */
static NTSTATUS STDCALL WvDummyIds(
    IN PIRP Irp,
    IN WV_SP_DUMMY_IDS DummyIds
  ) {
    PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(Irp);
    BUS_QUERY_ID_TYPE query_type = io_stack_loc->Parameters.QueryId.IdType;
    const CHAR * start;
    const WCHAR * ids;
    UINT32 len;
    NTSTATUS status;

    start = (const CHAR *) DummyIds + DummyIds->Offset;
    ids = (const WCHAR *) start;
    switch (query_type) {
        case BusQueryDeviceID:
          ids += DummyIds->DevOffset;
          len = DummyIds->DevLen;
          break;

        case BusQueryInstanceID:
          ids += DummyIds->InstanceOffset;
          len = DummyIds->InstanceLen;
          break;

        case BusQueryHardwareIDs:
          ids += DummyIds->HardwareOffset;
          len = DummyIds->HardwareLen;
          break;

        case BusQueryCompatibleIDs:
          ids += DummyIds->CompatOffset;
          len = DummyIds->CompatLen;
          break;

        default:
          return WvlIrpComplete(Irp, 0, STATUS_NOT_SUPPORTED);
      }

    /* Allocate the return buffer. */
    Irp->IoStatus.Information = (ULONG_PTR) wv_palloc(len * sizeof *ids);
    if (Irp->IoStatus.Information == 0) {
        DBG("wv_palloc failed.\n");
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto alloc_info;
      }
    /* Copy the working buffer to the return buffer. */
    RtlCopyMemory(
        (PVOID) Irp->IoStatus.Information,
        ids,
        len * sizeof *ids
      );
    status = STATUS_SUCCESS;

    /* irp->IoStatus.Information not freed. */
    alloc_info:

    return WvlIrpComplete(Irp, Irp->IoStatus.Information, status);
  }
Esempio n. 3
0
NTSTATUS STDCALL WvDiskPnpQueryDevText(
    IN PDEVICE_OBJECT dev_obj,
    IN PIRP irp,
    IN WVL_SP_DISK_T disk
  ) {
    IN WV_SP_DEV_T dev = WvDevFromDevObj(dev_obj);
    WCHAR (*str)[512];
    PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(irp);
    NTSTATUS status;
    UINT32 str_len;

    /* Allocate a string buffer. */
    str = wv_mallocz(sizeof *str);
    if (str == NULL) {
        DBG("wv_malloc IRP_MN_QUERY_DEVICE_TEXT\n");
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto alloc_str;
      }
    /* Determine the query type. */
    switch (io_stack_loc->Parameters.QueryDeviceText.DeviceTextType) {
        case DeviceTextDescription:
          str_len = swprintf(*str, WVL_M_WLIT L" Disk") + 1;
          irp->IoStatus.Information =
            (ULONG_PTR) wv_palloc(str_len * sizeof *str);
          if (irp->IoStatus.Information == 0) {
              DBG("wv_palloc DeviceTextDescription\n");
              status = STATUS_INSUFFICIENT_RESOURCES;
              goto alloc_info;
            }
          RtlCopyMemory(
              (PWCHAR) irp->IoStatus.Information,
              str,
              str_len * sizeof *str
            );
          status = STATUS_SUCCESS;
          goto alloc_info;

        case DeviceTextLocationInformation:
          if (disk->disk_ops.PnpQueryId) {
              io_stack_loc->MinorFunction = IRP_MN_QUERY_ID;
              io_stack_loc->Parameters.QueryId.IdType = BusQueryInstanceID;
              return disk->disk_ops.PnpQueryId(dev_obj, irp, disk);
            }
          /* Else, fall through... */

        default:
          irp->IoStatus.Information = 0;
          status = STATUS_NOT_SUPPORTED;
      }
    /* irp->IoStatus.Information not freed. */
    alloc_info:

    wv_free(str);
    alloc_str:

    return WvlIrpComplete(irp, irp->IoStatus.Information, status);
  }
Esempio n. 4
0
/**
 * IRP_MJ_PNP:IRP_MN_QUERY_ID handler
 *
 * IRQL == PASSIVE_LEVEL, any thread
 * Ok to send this IRP
 * Completed by PDO (here)
 *
 * @param Parameters.QueryId.IdType (I/O stack location)
 *
 * @return
 *   Success:
 *     Irp->IoStatus.Status == STATUS_SUCCESS
 *     Irp->IoStatus.Information populated from paged memory
 *   Error:
 *     Irp->IoStatus.Information == 0
 *     Irp->IoStatus.Status == STATUS_INSUFFICIENT_RESOURCES
 *       or
 *     Irp->IoStatus.Status == STATUS_NOT_SUPPORTED
 */
static NTSTATUS STDCALL WvDummyPnpQueryId(
    IN DEVICE_OBJECT * dev_obj,
    IN IRP * irp
  ) {
    S_WVL_DUMMY_PDO * dummy;
    IO_STACK_LOCATION * io_stack_loc;
    const UCHAR * ptr;
    const WCHAR * ids;
    BUS_QUERY_ID_TYPE query_type;
    UINT32 len;
    VOID * response;
    NTSTATUS status;

    ASSERT(dev_obj);
    dummy = dev_obj->DeviceExtension;
    ASSERT(dummy);
    ASSERT(irp);

    io_stack_loc = IoGetCurrentIrpStackLocation(irp);
    ASSERT(io_stack_loc);

    ptr = (const VOID *) dummy->DummyIds;
    ptr += dummy->DummyIds->Offset;
    ids = (const VOID *) ptr;

    query_type = io_stack_loc->Parameters.QueryId.IdType;
    switch (query_type) {
        case BusQueryDeviceID:
        ids += dummy->DummyIds->DevOffset;
        len = dummy->DummyIds->DevLen;
        break;

        case BusQueryHardwareIDs:
        ids += dummy->DummyIds->HardwareOffset;
        len = dummy->DummyIds->HardwareLen;
        break;

        case BusQueryCompatibleIDs:
        ids += dummy->DummyIds->CompatOffset;
        len = dummy->DummyIds->CompatLen;
        break;

        case BusQueryInstanceID:
        ids += dummy->DummyIds->InstanceOffset;
        len = dummy->DummyIds->InstanceLen;
        break;

        default:
        status = STATUS_NOT_SUPPORTED;
        irp->IoStatus.Information = 0;
        goto err_query_type;
      }

    /* Allocate the respone */
    response = wv_palloc(len * sizeof *ids);
    if (!response) {
        DBG("Couldn't allocate response\n");
        status = STATUS_INSUFFICIENT_RESOURCES;
        irp->IoStatus.Information = 0;
        goto err_response;
      }

    /* Copy the IDs into the response */
    RtlCopyMemory(response, ids, len * sizeof *ids);

    irp->IoStatus.Information = (ULONG_PTR) response;
    status = STATUS_SUCCESS;

    /* irp->IoStatus.Information not freed */
    err_response:

    err_query_type:

    irp->IoStatus.Status = status;
    WvlPassIrpUp(dev_obj, irp, IO_NO_INCREMENT);
    return status;
  }
Esempio n. 5
0
static NTSTATUS STDCALL AoeBusPnpQueryDevText_(
    IN WVL_SP_BUS_T bus,
    IN PIRP irp
) {
    WCHAR (*str)[512];
    PIO_STACK_LOCATION io_stack_loc = IoGetCurrentIrpStackLocation(irp);
    NTSTATUS status;
    UINT32 str_len;

    /* Allocate a string buffer. */
    str = wv_mallocz(sizeof *str);
    if (str == NULL) {
        DBG("wv_malloc IRP_MN_QUERY_DEVICE_TEXT\n");
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto alloc_str;
    }
    /* Determine the query type. */
    switch (io_stack_loc->Parameters.QueryDeviceText.DeviceTextType) {
    case DeviceTextDescription:
        str_len = swprintf(*str, L"AoE Bus") + 1;
        irp->IoStatus.Information =
            (ULONG_PTR) wv_palloc(str_len * sizeof **str);
        if (irp->IoStatus.Information == 0) {
            DBG("wv_palloc DeviceTextDescription\n");
            status = STATUS_INSUFFICIENT_RESOURCES;
            goto alloc_info;
        }
        RtlCopyMemory(
            (PWCHAR) irp->IoStatus.Information,
            str,
            str_len * sizeof **str
        );
        status = STATUS_SUCCESS;
        goto alloc_info;

    case DeviceTextLocationInformation:
        str_len = AoeBusPnpId_(
                      NULL,
                      BusQueryInstanceID,
                      str
                  );
        irp->IoStatus.Information =
            (ULONG_PTR) wv_palloc(str_len * sizeof **str);
        if (irp->IoStatus.Information == 0) {
            DBG("wv_palloc DeviceTextLocationInformation\n");
            status = STATUS_INSUFFICIENT_RESOURCES;
            goto alloc_info;
        }
        RtlCopyMemory(
            (PWCHAR) irp->IoStatus.Information,
            str,
            str_len * sizeof **str
        );
        status = STATUS_SUCCESS;
        goto alloc_info;

    default:
        irp->IoStatus.Information = 0;
        status = STATUS_NOT_SUPPORTED;
    }
    /* irp->IoStatus.Information not freed. */
alloc_info:

    wv_free(str);
alloc_str:

    return WvlIrpComplete(irp, irp->IoStatus.Information, status);
}