win-pvdrivers

diff xenpci/xenpci.c @ 747:f43c89df09b2

Big changes to the way the device hiding works. Should fix the way Vista and above need a reboot into safe mode after install.
author James Harper <james.harper@bendigoit.com.au>
date Sun Jan 10 10:07:32 2010 +1100 (2010-01-10)
parents 7f984f45dfe4
children 65a687a0933e
line diff
     1.1 --- a/xenpci/xenpci.c	Sat Jan 09 15:09:11 2010 +1100
     1.2 +++ b/xenpci/xenpci.c	Sun Jan 10 10:07:32 2010 +1100
     1.3 @@ -228,7 +228,7 @@ XenPci_EvtDeviceAdd_XenPci(WDFDRIVER dri
     1.4  }
     1.5  
     1.6  NTSTATUS
     1.7 -XenHide_EvtDevicePrepareHardware (WDFDEVICE device, WDFCMRESLIST resources_raw, WDFCMRESLIST resources_translated)
     1.8 +XenHide_EvtDevicePrepareHardware(WDFDEVICE device, WDFCMRESLIST resources_raw, WDFCMRESLIST resources_translated)
     1.9  {
    1.10    UNREFERENCED_PARAMETER(device);
    1.11    UNREFERENCED_PARAMETER(resources_raw);
    1.12 @@ -290,8 +290,8 @@ XenPci_IdSuffixMatches(PWDFDEVICE_INIT d
    1.13    return FALSE;
    1.14  }
    1.15  
    1.16 -ULONG qemu_filtered;
    1.17 -ULONG qemu_filtered_by_qemu;
    1.18 +WDFCOLLECTION qemu_hide_devices;
    1.19 +USHORT qemu_hide_flags_value;
    1.20  
    1.21  static NTSTATUS
    1.22  XenPci_EvtDeviceAdd_XenHide(WDFDRIVER driver, PWDFDEVICE_INIT device_init)
    1.23 @@ -303,30 +303,12 @@ XenPci_EvtDeviceAdd_XenHide(WDFDRIVER dr
    1.24    WDF_OBJECT_ATTRIBUTES device_attributes;
    1.25    BOOLEAN hide_required = FALSE;
    1.26    WDFDEVICE device;
    1.27 -  WDFKEY param_key;
    1.28 -  DECLARE_CONST_UNICODE_STRING(hide_devices_name, L"hide_devices");
    1.29 -  WDFCOLLECTION hide_devices;
    1.30    ULONG i;
    1.31 -  
    1.32 +
    1.33    UNREFERENCED_PARAMETER(driver);
    1.34  
    1.35    FUNCTION_ENTER();
    1.36  
    1.37 -  WdfCollectionCreate(WDF_NO_OBJECT_ATTRIBUTES, &hide_devices);
    1.38 -  status = WdfDriverOpenParametersRegistryKey(driver, KEY_QUERY_VALUE, WDF_NO_OBJECT_ATTRIBUTES, &param_key);
    1.39 -  if (NT_SUCCESS(status))
    1.40 -  {
    1.41 -    status = WdfRegistryQueryMultiString(param_key, &hide_devices_name, WDF_NO_OBJECT_ATTRIBUTES, hide_devices);
    1.42 -    if (!NT_SUCCESS(status))
    1.43 -    {
    1.44 -      KdPrint(("Error reading parameters/hide_devices value %08x\n", status));
    1.45 -    }
    1.46 -    WdfRegistryClose(param_key);
    1.47 -  }
    1.48 -  else
    1.49 -  {
    1.50 -    KdPrint(("Error opening parameters key %08x\n", status));
    1.51 -  }
    1.52    status = WdfFdoInitAllocAndQueryProperty(device_init, DevicePropertyDeviceDescription, NonPagedPool, WDF_NO_OBJECT_ATTRIBUTES, &memory);
    1.53    if (NT_SUCCESS(status))
    1.54    {
    1.55 @@ -337,9 +319,9 @@ XenPci_EvtDeviceAdd_XenHide(WDFDRIVER dr
    1.56      device_description = L"<unknown device>";
    1.57    }
    1.58  
    1.59 -  for (i = 0; i < WdfCollectionGetCount(hide_devices); i++)
    1.60 +  for (i = 0; i < WdfCollectionGetCount(qemu_hide_devices); i++)
    1.61    {
    1.62 -    WDFSTRING wdf_string = WdfCollectionGetItem(hide_devices, i);
    1.63 +    WDFSTRING wdf_string = WdfCollectionGetItem(qemu_hide_devices, i);
    1.64      UNICODE_STRING unicode_string;
    1.65      WdfStringGetUnicodeString(wdf_string, &unicode_string);
    1.66      if (XenPci_IdSuffixMatches(device_init, unicode_string.Buffer))
    1.67 @@ -348,21 +330,6 @@ XenPci_EvtDeviceAdd_XenHide(WDFDRIVER dr
    1.68        break;
    1.69      }
    1.70    }
    1.71 -#if 0
    1.72 -  /* hide only specific devices */
    1.73 -  if (XenPci_IdSuffixMatches(device_init, L"VEN_8086&DEV_7010")) // Qemu IDE
    1.74 -  {
    1.75 -    hide_required = TRUE;
    1.76 -  }
    1.77 -  else if (XenPci_IdSuffixMatches(device_init, L"VEN_1000&DEV_0012"))// Qemu SCSI
    1.78 -  {
    1.79 -    hide_required = TRUE;
    1.80 -  }
    1.81 -  else if (XenPci_IdSuffixMatches(device_init, L"VEN_10EC&DEV_8139")) // Qemu Network
    1.82 -  {
    1.83 -    hide_required = TRUE;
    1.84 -  }
    1.85 -#endif
    1.86    if (!hide_required)
    1.87    {
    1.88      WdfObjectDelete(memory);
    1.89 @@ -404,7 +371,7 @@ XenPci_EvtDeviceAdd(WDFDRIVER driver, PW
    1.90      KdPrint((__DRIVER_NAME "     Xen PCI device found - must be fdo\n"));
    1.91      return XenPci_EvtDeviceAdd_XenPci(driver, device_init);
    1.92    }
    1.93 -  else if (qemu_filtered && !qemu_filtered_by_qemu)
    1.94 +  else if (WdfCollectionGetCount(qemu_hide_devices) > 0)
    1.95    {
    1.96      KdPrint((__DRIVER_NAME "     Xen PCI device not found - must be filter\n"));
    1.97      return XenPci_EvtDeviceAdd_XenHide(driver, device_init);  
    1.98 @@ -420,7 +387,13 @@ extern PULONG InitSafeBootMode;
    1.99  VOID
   1.100  XenPci_HideQemuDevices()
   1.101  {
   1.102 -  qemu_filtered_by_qemu = FALSE;
   1.103 +  WRITE_PORT_USHORT(XEN_IOPORT_DEVICE_MASK, (USHORT)qemu_hide_flags_value); //QEMU_UNPLUG_ALL_IDE_DISKS|QEMU_UNPLUG_ALL_NICS);
   1.104 +  KdPrint((__DRIVER_NAME "     Disabled qemu devices\n"));\
   1.105 +}
   1.106 +
   1.107 +static BOOLEAN
   1.108 +XenPci_CheckHideQemuDevices()
   1.109 +{
   1.110    if (READ_PORT_USHORT(XEN_IOPORT_MAGIC) == 0x49d2)
   1.111    {
   1.112      qemu_protocol_version = READ_PORT_UCHAR(XEN_IOPORT_VERSION);
   1.113 @@ -437,15 +410,13 @@ XenPci_HideQemuDevices()
   1.114        }
   1.115        /* fall through */
   1.116      case 0:
   1.117 -      qemu_filtered_by_qemu = TRUE;
   1.118 -      WRITE_PORT_USHORT(XEN_IOPORT_DEVICE_MASK, QEMU_UNPLUG_ALL_IDE_DISKS|QEMU_UNPLUG_ALL_NICS);
   1.119 -      KdPrint((__DRIVER_NAME "     Disabled qemu devices\n"));
   1.120 -      break;
   1.121 +      return TRUE;
   1.122      default:
   1.123        KdPrint((__DRIVER_NAME "     Unknown qemu version %d\n", qemu_protocol_version));
   1.124        break;
   1.125      }
   1.126    }
   1.127 +  return FALSE;
   1.128  }
   1.129  
   1.130  /*
   1.131 @@ -653,6 +624,19 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
   1.132      }
   1.133    }
   1.134    
   1.135 +  WDF_DRIVER_CONFIG_INIT(&config, XenPci_EvtDeviceAdd);
   1.136 +  status = WdfDriverCreate(DriverObject, RegistryPath, WDF_NO_OBJECT_ATTRIBUTES, &config, &driver);
   1.137 +
   1.138 +  WdfCollectionCreate(WDF_NO_OBJECT_ATTRIBUTES, &qemu_hide_devices);
   1.139 +
   1.140 +  if (!NT_SUCCESS(status)) {
   1.141 +    KdPrint((__DRIVER_NAME "     WdfDriverCreate failed with status 0x%x\n", status));
   1.142 +    FUNCTION_EXIT();
   1.143 +    return status;
   1.144 +  }
   1.145 +
   1.146 +  qemu_hide_flags_value = 0;
   1.147 +
   1.148    if (wcsstr(SystemStartOptions, L"NOGPLPV"))
   1.149      KdPrint((__DRIVER_NAME "     NOGPLPV found\n"));
   1.150    conf_info = IoGetConfigurationInformation();
   1.151 @@ -660,24 +644,65 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
   1.152        && !wcsstr(SystemStartOptions, L"NOGPLPV")
   1.153        && !*InitSafeBootMode)
   1.154    {
   1.155 -    qemu_filtered = TRUE;
   1.156 -    /* see if the qemu method of disabling the PCI devices exists */
   1.157 -    XenPci_HideQemuDevices();
   1.158 -  }
   1.159 -  
   1.160 -  if (qemu_filtered)
   1.161 -    KdPrint((__DRIVER_NAME "     PV Devices Active\n"));
   1.162 -  else
   1.163 -    KdPrint((__DRIVER_NAME "     PV Devices Inactive\n"));
   1.164 -  
   1.165 -  WDF_DRIVER_CONFIG_INIT(&config, XenPci_EvtDeviceAdd);
   1.166 -  status = WdfDriverCreate(DriverObject, RegistryPath, WDF_NO_OBJECT_ATTRIBUTES, &config, &driver);
   1.167 -
   1.168 -  if (!NT_SUCCESS(status)) {
   1.169 -    KdPrint((__DRIVER_NAME "     WdfDriverCreate failed with status 0x%x\n", status));
   1.170 +    if (wcsstr(SystemStartOptions, L"GPLPVUSEFILTERHIDE") == 0 && XenPci_CheckHideQemuDevices())
   1.171 +    {
   1.172 +      DECLARE_CONST_UNICODE_STRING(qemu_hide_flags_name, L"qemu_hide_flags");
   1.173 +      WDFCOLLECTION qemu_hide_flags;
   1.174 +      WDFKEY param_key;
   1.175 +      ULONG i;
   1.176 +      
   1.177 +      WdfCollectionCreate(WDF_NO_OBJECT_ATTRIBUTES, &qemu_hide_flags);
   1.178 +      status = WdfDriverOpenParametersRegistryKey(driver, KEY_QUERY_VALUE, WDF_NO_OBJECT_ATTRIBUTES, &param_key);
   1.179 +      if (NT_SUCCESS(status))
   1.180 +      {
   1.181 +        status = WdfRegistryQueryMultiString(param_key, &qemu_hide_flags_name, WDF_NO_OBJECT_ATTRIBUTES, qemu_hide_flags);
   1.182 +        if (!NT_SUCCESS(status))
   1.183 +        {
   1.184 +          KdPrint(("Error reading parameters/qemu_hide_flags value %08x\n", status));
   1.185 +        }
   1.186 +        else
   1.187 +        {
   1.188 +          for (i = 0; i < WdfCollectionGetCount(qemu_hide_flags); i++)
   1.189 +          {
   1.190 +            ULONG value;
   1.191 +            WDFSTRING wdf_string = WdfCollectionGetItem(qemu_hide_flags, i);
   1.192 +            UNICODE_STRING unicode_string;
   1.193 +            WdfStringGetUnicodeString(wdf_string, &unicode_string);
   1.194 +            KdPrint(("\n", status));
   1.195 +            status = RtlUnicodeStringToInteger(&unicode_string, 0, &value);
   1.196 +            qemu_hide_flags_value |= value;
   1.197 +          }
   1.198 +        }
   1.199 +        WdfRegistryClose(param_key);
   1.200 +      }
   1.201 +      else
   1.202 +      {
   1.203 +        KdPrint(("Error opening parameters key %08x\n", status));
   1.204 +      }
   1.205 +      XenPci_HideQemuDevices();
   1.206 +    }
   1.207 +    else
   1.208 +    {
   1.209 +      DECLARE_CONST_UNICODE_STRING(hide_devices_name, L"hide_devices");
   1.210 +      WDFKEY param_key;
   1.211 +      status = WdfDriverOpenParametersRegistryKey(driver, KEY_QUERY_VALUE, WDF_NO_OBJECT_ATTRIBUTES, &param_key);
   1.212 +      if (NT_SUCCESS(status))
   1.213 +      {
   1.214 +        status = WdfRegistryQueryMultiString(param_key, &hide_devices_name, WDF_NO_OBJECT_ATTRIBUTES, qemu_hide_devices);
   1.215 +        if (!NT_SUCCESS(status))
   1.216 +        {
   1.217 +          KdPrint(("Error reading parameters/hide_devices value %08x\n", status));
   1.218 +        }
   1.219 +        WdfRegistryClose(param_key);
   1.220 +      }
   1.221 +      else
   1.222 +      {
   1.223 +        KdPrint(("Error opening parameters key %08x\n", status));
   1.224 +      }
   1.225 +    }
   1.226    }
   1.227  
   1.228    FUNCTION_EXIT();
   1.229  
   1.230 -  return status;
   1.231 +  return STATUS_SUCCESS;
   1.232  }