win-pvdrivers

changeset 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 33392df89647
children fc7dfb98cc7a
files xenpci/xenpci.c xenpci/xenpci.h xenpci/xenpci.inx xenpci/xenpci_fdo.c xenpci/xenpci_pdo.c
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  }
     2.1 --- a/xenpci/xenpci.h	Sat Jan 09 15:09:11 2010 +1100
     2.2 +++ b/xenpci/xenpci.h	Sun Jan 10 10:07:32 2010 +1100
     2.3 @@ -69,7 +69,6 @@ DEFINE_GUID( GUID_XENPCI_DEVCLASS, 0xC82
     2.4  #define XEN_PV_PRODUCT_NUMBER   0x0002
     2.5  #define XEN_PV_PRODUCT_BUILD    0x00000001
     2.6  
     2.7 -extern ULONG qemu_filtered;
     2.8  extern ULONG qemu_protocol_version;
     2.9  
    2.10  typedef struct _ev_action_t {
    2.11 @@ -198,6 +197,7 @@ typedef struct {
    2.12  
    2.13    //WDFCOLLECTION veto_devices;
    2.14    LIST_ENTRY veto_list;
    2.15 +
    2.16  #if 0
    2.17    KSPIN_LOCK mmio_freelist_lock;
    2.18    PPFN_NUMBER mmio_freelist_base;
    2.19 @@ -316,7 +316,8 @@ EVT_WDF_CHILD_LIST_SCAN_FOR_CHILDREN Xen
    2.20  
    2.21  VOID
    2.22  XenPci_HideQemuDevices();
    2.23 -extern ULONG qemu_filtered_by_qemu;
    2.24 +extern WDFCOLLECTION qemu_hide_devices;
    2.25 +extern USHORT qemu_hide_flags_value;
    2.26  
    2.27  #if 0
    2.28  NTSTATUS
     3.1 --- a/xenpci/xenpci.inx	Sat Jan 09 15:09:11 2010 +1100
     3.2 +++ b/xenpci/xenpci.inx	Sun Jan 10 10:07:32 2010 +1100
     3.3 @@ -52,9 +52,9 @@ HKR,"Parameters", "veto_devices", 0x0001
     3.4  HKR,"Parameters", "veto_devices", 0x00010008, "vfb"
     3.5  HKR,"Parameters", "veto_devices", 0x00010008, "vkbd"
     3.6  HKR,"Parameters", "veto_devices", 0x00010008, "suspend"
     3.7 -; Add XenHide as a filter to IDE Controllers
     3.8 +; Add XenPci as a filter to IDE Controllers
     3.9  HKLM,SYSTEM\CurrentControlSet\Control\Class\{4D36E96A-E325-11CE-BFC1-08002BE10318},UpperFilters,0x00010008,XenPci
    3.10 -; Add XenHide as a filter to SCSI Controllers
    3.11 +; Add XenPci as a filter to SCSI Controllers
    3.12  HKLM,SYSTEM\CurrentControlSet\Control\Class\{4D36E97B-E325-11CE-BFC1-08002BE10318},UpperFilters,0x00010008,XenPci
    3.13  ; Add XenPci as a filter to Network Adapters
    3.14  HKLM,SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002bE10318},UpperFilters,0x00010008,XenPci
    3.15 @@ -66,8 +66,6 @@ HKLM,SYSTEM\CurrentControlSet\Control\Cl
    3.16  HKLM,SYSTEM\CurrentControlSet\Control\Class\{4D36E96A-E325-11CE-BFC1-08002BE10318},UpperFilters,0x00018002,XenHide
    3.17  HKLM,SYSTEM\CurrentControlSet\Control\Class\{4D36E97B-E325-11CE-BFC1-08002BE10318},UpperFilters,0x00018002,XenHide
    3.18  
    3.19 -
    3.20 -
    3.21  [DestinationDirs]
    3.22  XenPCI_Device_CoInstaller_CopyFiles = 11
    3.23  
     4.1 --- a/xenpci/xenpci_fdo.c	Sat Jan 09 15:09:11 2010 +1100
     4.2 +++ b/xenpci/xenpci_fdo.c	Sun Jan 10 10:07:32 2010 +1100
     4.3 @@ -363,10 +363,9 @@ XenPci_Suspend0(PVOID context)
     4.4    cancelled = hvm_shutdown(xpdd, SHUTDOWN_suspend);
     4.5    KdPrint((__DRIVER_NAME "     back from suspend, cancelled = %d\n", cancelled));
     4.6  
     4.7 -  if (qemu_filtered_by_qemu)
     4.8 +  if (qemu_hide_flags_value)
     4.9    {
    4.10      XenPci_HideQemuDevices();
    4.11 -    ASSERT(qemu_filtered_by_qemu);
    4.12    }
    4.13  
    4.14    XenPci_Resume(xpdd);
    4.15 @@ -668,10 +667,9 @@ XenPci_EvtDeviceD0Entry(WDFDEVICE device
    4.16      break;  
    4.17    }
    4.18  
    4.19 -  if (previous_state == WdfPowerDevicePrepareForHibernation && qemu_filtered_by_qemu)
    4.20 +  if (previous_state == WdfPowerDevicePrepareForHibernation && qemu_hide_flags_value)
    4.21    {
    4.22      XenPci_HideQemuDevices();
    4.23 -    ASSERT(qemu_filtered_by_qemu);
    4.24    }
    4.25    
    4.26    if (previous_state == WdfPowerDeviceD3Final)
     5.1 --- a/xenpci/xenpci_pdo.c	Sat Jan 09 15:09:11 2010 +1100
     5.2 +++ b/xenpci/xenpci_pdo.c	Sun Jan 10 10:07:32 2010 +1100
     5.3 @@ -604,8 +604,6 @@ XenPci_XenConfigDeviceSpecifyBuffers(WDF
     5.4    grant_ref_t gref;
     5.5    BOOLEAN done_xenbus_init = FALSE;
     5.6    PVOID value2;
     5.7 -  BOOLEAN active = TRUE;
     5.8 -  BOOLEAN dont_config = FALSE;
     5.9   
    5.10    FUNCTION_ENTER();
    5.11  
    5.12 @@ -647,9 +645,7 @@ XenPci_XenConfigDeviceSpecifyBuffers(WDF
    5.13    ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_VECTORS, NULL, &vectors, NULL);
    5.14    ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_STATE_PTR, NULL, &xppdd->device_state, NULL);
    5.15  
    5.16 -  if (!qemu_filtered)
    5.17 -    active = FALSE;
    5.18 -
    5.19 +#if 0
    5.20    while((type = GET_XEN_INIT_REQ(&in_ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value2)) != XEN_INIT_TYPE_END)
    5.21    {
    5.22      BOOLEAN condition;
    5.23 @@ -709,6 +705,7 @@ XenPci_XenConfigDeviceSpecifyBuffers(WDF
    5.24      FUNCTION_EXIT();
    5.25      return status;
    5.26    }
    5.27 +#endif
    5.28    
    5.29    // first pass, possibly before state == Connected
    5.30    in_ptr = src;
    5.31 @@ -859,10 +856,31 @@ XenPci_XenConfigDeviceSpecifyBuffers(WDF
    5.32        break;
    5.33      }
    5.34    }
    5.35 -  if (active)
    5.36 +  if (qemu_hide_flags_value)
    5.37    {
    5.38 -    ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_ACTIVE, NULL, NULL, NULL);
    5.39 +    ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_QEMU_HIDE_FLAGS, NULL, UlongToPtr(qemu_hide_flags_value), NULL);
    5.40    }
    5.41 +  else
    5.42 +  {
    5.43 +    DECLARE_UNICODE_STRING_SIZE(my_device_name, 128);
    5.44 +    
    5.45 +    RtlUnicodeStringPrintf(&my_device_name, L"#%S#", xppdd->device);
    5.46 +    
    5.47 +    for (i = 0; i < WdfCollectionGetCount(qemu_hide_devices); i++)
    5.48 +    {
    5.49 +      WDFSTRING wdf_string = WdfCollectionGetItem(qemu_hide_devices, i);
    5.50 +      UNICODE_STRING hide_device_name;
    5.51 +      
    5.52 +      WdfStringGetUnicodeString(wdf_string, &hide_device_name);
    5.53 +      
    5.54 +      if (RtlCompareUnicodeString(&hide_device_name, &my_device_name, TRUE) != 0)
    5.55 +      {
    5.56 +        ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_QEMU_HIDE_FILTER, NULL, NULL, NULL);
    5.57 +        break;
    5.58 +      }
    5.59 +    }
    5.60 +  }
    5.61 +  
    5.62    ADD_XEN_INIT_RSP(&out_ptr, XEN_INIT_TYPE_END, NULL, NULL, NULL);
    5.63  
    5.64    if (run_type)