Example #1
1
NTSTATUS PciDtfDeviceGetInfo(IN WDFDEVICE Device, IN WDFREQUEST Request)
{
	PCIDTF_DEV_INFO *ReqData;
	ULONG Value, Length;
	NTSTATUS Status = STATUS_SUCCESS;

	__try {
		Status = WdfRequestRetrieveOutputBuffer(Request,
							sizeof(PCIDTF_DEV_INFO),
							(PVOID *) & ReqData,
							NULL);
		if (!NT_SUCCESS(Status)) {
			TRACE_ERR("WdfRequestRetrieveOutputBuffer", Status);
			__leave;
		}
		Status = WdfDeviceQueryProperty(Device,
						DevicePropertyBusNumber,
						sizeof(Value), &Value, &Length);
		if (!NT_SUCCESS(Status)) {
			TRACE_ERR
			    ("WdfDeviceQueryProperty(DevicePropertyBusNumber)",
			     Status);
			__leave;
		}
		ReqData->bus = (UINT8) Value;
		Status = WdfDeviceQueryProperty(Device,
						DevicePropertyAddress,
						sizeof(Value), &Value, &Length);
		if (!NT_SUCCESS(Status)) {
			TRACE_ERR
			    ("WdfDeviceQueryProperty(DevicePropertyAddress)",
			     Status);
			__leave;
		}
		ReqData->devfn = (UINT8) Value;
		ReqData->reg_count = (int)
		    WdfCollectionGetCount(GetDeviceData(Device)->RegSpaces);
		TRACE_MSG(TRACE_LEVEL_VERBOSE, TRACE_FLAG_QUEUE,
			  "bus=0x%X, devfn=0x%X, reg_count=%d\n", ReqData->bus,
			  ReqData->devfn, ReqData->reg_count);
		WdfRequestSetInformation(Request, sizeof(PCIDTF_DEV_INFO));
	}
	__finally {
		WdfRequestComplete(Request, Status);
	}
	return Status;
}
static VOID
XenUsb_EvtIoDeviceControl(
  WDFQUEUE queue,
  WDFREQUEST request,
  size_t output_buffer_length,
  size_t input_buffer_length,
  ULONG io_control_code)
{
  NTSTATUS status;
  WDFDEVICE device = WdfIoQueueGetDevice(queue);
  PXENUSB_DEVICE_DATA xudd = GetXudd(device);

  UNREFERENCED_PARAMETER(queue);
  UNREFERENCED_PARAMETER(input_buffer_length);
  UNREFERENCED_PARAMETER(output_buffer_length);

  FUNCTION_ENTER();

  status = STATUS_BAD_INITIAL_PC;

  // these are in api\usbioctl.h
  switch(io_control_code)
  {
  case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION:
    FUNCTION_MSG("IOCTL_USB_GET_NODE_CONNECTION_INFORMATION\n");
    break;
  case IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION:
    FUNCTION_MSG("IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION\n");
    break;
  case IOCTL_USB_GET_NODE_CONNECTION_NAME:
    FUNCTION_MSG("IOCTL_USB_GET_NODE_CONNECTION_NAME\n");
    break;
  case IOCTL_USB_DIAG_IGNORE_HUBS_ON:
    FUNCTION_MSG("IOCTL_USB_DIAG_IGNORE_HUBS_ON\n");
    break;
  case IOCTL_USB_DIAG_IGNORE_HUBS_OFF:
    FUNCTION_MSG("IOCTL_USB_DIAG_IGNORE_HUBS_OFF\n");
    break;
  case IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME:
    FUNCTION_MSG("IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME\n");
    break;
  case IOCTL_USB_GET_HUB_CAPABILITIES:
    FUNCTION_MSG("IOCTL_USB_GET_HUB_CAPABILITIES\n");
    break;
  case IOCTL_USB_HUB_CYCLE_PORT:
    FUNCTION_MSG("IOCTL_USB_HUB_CYCLE_PORT\n");
    break;
  case IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES:
    FUNCTION_MSG("IOCTL_USB_GET_NODE_CONNECTION_ATTRIBUTES\n");
    break;
  case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX:
    FUNCTION_MSG("IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX\n");
    break;
  case IOCTL_USB_GET_ROOT_HUB_NAME:
  {
    PUSB_HCD_DRIVERKEY_NAME uhdn;
    size_t length;
    ULONG required_length = sizeof(USB_HCD_DRIVERKEY_NAME);
    
    FUNCTION_MSG("IOCTL_USB_GET_ROOT_HUB_NAME\n");
    FUNCTION_MSG(" output_buffer_length = %d\n", output_buffer_length);
      
    if (output_buffer_length < sizeof(USB_HCD_DRIVERKEY_NAME)) {
      status = STATUS_BUFFER_TOO_SMALL;
    } else {
      status = WdfRequestRetrieveOutputBuffer(request, output_buffer_length, (PVOID *)&uhdn, &length);
      if (NT_SUCCESS(status)) {
        WDFSTRING symbolic_link_wdfstring;
        UNICODE_STRING symbolic_link;
        
        uhdn->DriverKeyName[0] = 0;
        status = WdfStringCreate(NULL, WDF_NO_OBJECT_ATTRIBUTES, &symbolic_link_wdfstring);
        if (NT_SUCCESS(status)) {
          status = WdfDeviceRetrieveDeviceInterfaceString(xudd->root_hub_device, &GUID_DEVINTERFACE_USB_HUB, NULL, symbolic_link_wdfstring);
          if (NT_SUCCESS(status)) {
            WdfStringGetUnicodeString(symbolic_link_wdfstring, &symbolic_link);
            /* remove leading \??\ from name */
            symbolic_link.Buffer += 4;
            symbolic_link.Length -= 4 * sizeof(WCHAR);
            required_length = FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName) + symbolic_link.Length + sizeof(WCHAR);
            FUNCTION_MSG("output_buffer_length = %d\n", output_buffer_length);
            FUNCTION_MSG("required_length = %d\n", required_length);
            if (output_buffer_length >= required_length) {
              uhdn->ActualLength = required_length;
              memcpy(uhdn->DriverKeyName, symbolic_link.Buffer, symbolic_link.Length);
              uhdn->DriverKeyName[symbolic_link.Length / 2] = 0;
              WdfRequestSetInformation(request, required_length);
            } else {
              uhdn->ActualLength = required_length;
              uhdn->DriverKeyName[0] = 0;
              status = STATUS_SUCCESS;
              WdfRequestSetInformation(request, output_buffer_length);
            }
          } else {
            FUNCTION_MSG("WdfStringCreate = %08x\n", status);
          }
        } else {
          FUNCTION_MSG("WdfDeviceRetrieveDeviceInterfaceString = %08x\n", status);
          status = STATUS_INVALID_PARAMETER;
        }
      } else {
        FUNCTION_MSG("WdfRequestRetrieveOutputBuffer = %08x\n", status);
      }
      FUNCTION_MSG(" uhdn->ActualLength = %d\n", uhdn->ActualLength);
      FUNCTION_MSG(" uhdn->DriverKeyName = %S\n", uhdn->DriverKeyName);
    }
    break;
  }
  case IOCTL_GET_HCD_DRIVERKEY_NAME:
  {
    PUSB_HCD_DRIVERKEY_NAME uhdn;
    size_t length;
    ULONG required_length = sizeof(USB_HCD_DRIVERKEY_NAME);
    ULONG key_length;
    
    FUNCTION_MSG("IOCTL_GET_HCD_DRIVERKEY_NAME\n");
    FUNCTION_MSG(" output_buffer_length = %d\n", output_buffer_length);
      
    if (output_buffer_length < sizeof(USB_HCD_DRIVERKEY_NAME)) {
      FUNCTION_MSG("Buffer too small (%d < %d)\n", output_buffer_length, sizeof(USB_HCD_DRIVERKEY_NAME));
      status = STATUS_BUFFER_TOO_SMALL;
      break;
    }
    status = WdfRequestRetrieveOutputBuffer(request, output_buffer_length, (PVOID *)&uhdn, &length);
    if (!NT_SUCCESS(status)) {
      FUNCTION_MSG("WdfRequestRetrieveOutputBuffer = %08x\n", status);
      break;
    }
    status = WdfDeviceQueryProperty(device, DevicePropertyDriverKeyName, 0, NULL, &key_length);
    if (!NT_SUCCESS(status)) {
      FUNCTION_MSG("WdfDeviceQueryProperty = %08x\n", status);
      break;
    }    
    FUNCTION_MSG(" key_length = %d\n", key_length);
    required_length = FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName) + key_length + 2;
    uhdn->ActualLength = required_length;
    FUNCTION_MSG("output_buffer_length = %d\n", output_buffer_length);
    FUNCTION_MSG("required_length = %d\n", required_length);
    if (output_buffer_length >= required_length)
    {
      status = WdfDeviceQueryProperty(device, DevicePropertyDriverKeyName, 
        required_length - FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName), uhdn->DriverKeyName,
        &key_length);
      WdfRequestSetInformation(request, required_length);
    }
    else
    {
      uhdn->DriverKeyName[0] = 0;
      status = STATUS_SUCCESS;
      WdfRequestSetInformation(request, output_buffer_length);
    }
    FUNCTION_MSG(" uhdn->ActualLength = %d\n", uhdn->ActualLength);
    FUNCTION_MSG(" uhdn->DriverKeyName = %S\n", uhdn->DriverKeyName);
    break;
  }
#if 0
  case IOCTL_USB_RESET_HUB:
    FUNCTION_MSG("IOCTL_USB_RESET_HUB\n");
    break;
#endif
  default:
    FUNCTION_MSG("Unknown IOCTL %08x\n", io_control_code);
    break;
  }
  FUNCTION_MSG("Calling WdfRequestComplete with status = %08x\n", status);
  WdfRequestComplete(request, status);

  FUNCTION_EXIT();
}