win-pvdrivers

changeset 539:9ed05604c105

A better way to enforce the correct load order of the Wdf service
author James Harper <james.harper@bendigoit.com.au>
date Tue Mar 03 22:00:41 2009 +1100 (2009-03-03)
parents e75bb8d68370
children 0828c553c6c3
files xenpci/xenpci.c
line diff
     1.1 --- a/xenpci/xenpci.c	Tue Mar 03 09:51:24 2009 +1100
     1.2 +++ b/xenpci/xenpci.c	Tue Mar 03 22:00:41 2009 +1100
     1.3 @@ -79,7 +79,7 @@ XenPci_EvtDeviceAdd(WDFDRIVER driver, PW
     1.4    UNREFERENCED_PARAMETER(driver);
     1.5  
     1.6    FUNCTION_ENTER();
     1.7 -
     1.8 +  
     1.9    WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnp_power_callbacks);
    1.10    pnp_power_callbacks.EvtDeviceD0Entry = XenPci_EvtDeviceD0Entry;
    1.11    pnp_power_callbacks.EvtDeviceD0EntryPostInterruptsEnabled = XenPci_EvtDeviceD0EntryPostInterruptsEnabled;
    1.12 @@ -225,6 +225,112 @@ XenPci_HideQemuDevices()
    1.13    }
    1.14  }
    1.15  
    1.16 +/*
    1.17 +make sure the load order is System Reserved, Dummy Group, WdfLoadGroup, Boot Bus Extender
    1.18 +*/
    1.19 +
    1.20 +static VOID
    1.21 +XenPci_FixLoadOrder()
    1.22 +{
    1.23 +  NTSTATUS status;
    1.24 +  WDFCOLLECTION old_load_order, new_load_order;
    1.25 +  DECLARE_CONST_UNICODE_STRING(sgo_name, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder");
    1.26 +  DECLARE_CONST_UNICODE_STRING(list_name, L"List");
    1.27 +  WDFKEY sgo_key;
    1.28 +  ULONG i;
    1.29 +  LONG dummy_group_index = -1;
    1.30 +  LONG boot_bus_extender_index = -1;
    1.31 +  LONG wdf_load_group_index = -1;
    1.32 +  DECLARE_CONST_UNICODE_STRING(dummy_group_name, L"Dummy Group");
    1.33 +  DECLARE_CONST_UNICODE_STRING(wdf_load_group_name, L"WdfLoadGroup");
    1.34 +  DECLARE_CONST_UNICODE_STRING(boot_bus_extender_name, L"Boot Bus Extender");
    1.35 +
    1.36 +  FUNCTION_ENTER();
    1.37 +  
    1.38 +  status = WdfRegistryOpenKey(NULL, &sgo_name, KEY_QUERY_VALUE, WDF_NO_OBJECT_ATTRIBUTES, &sgo_key);
    1.39 +  if (!NT_SUCCESS(status))
    1.40 +  {
    1.41 +    KdPrint((__DRIVER_NAME "     Error opening ServiceGroupOrder key %08x\n", status));
    1.42 +    return;
    1.43 +  }
    1.44 +  WdfCollectionCreate(WDF_NO_OBJECT_ATTRIBUTES, &old_load_order);
    1.45 +  WdfCollectionCreate(WDF_NO_OBJECT_ATTRIBUTES, &new_load_order);  
    1.46 +  status = WdfRegistryQueryMultiString(sgo_key, &list_name, WDF_NO_OBJECT_ATTRIBUTES, old_load_order);
    1.47 +  if (!NT_SUCCESS(status))
    1.48 +  {
    1.49 +    KdPrint((__DRIVER_NAME "     Error reading ServiceGroupOrder\\List value %08x\n", status));
    1.50 +    WdfObjectDelete(new_load_order);
    1.51 +    WdfObjectDelete(old_load_order);
    1.52 +    return;
    1.53 +  }
    1.54 +  KdPrint((__DRIVER_NAME "     Current Order:\n"));        
    1.55 +  for (i = 0; i < WdfCollectionGetCount(old_load_order); i++)
    1.56 +  {
    1.57 +    WDFOBJECT ws = WdfCollectionGetItem(old_load_order, i);
    1.58 +    UNICODE_STRING val;
    1.59 +    WdfStringGetUnicodeString(ws, &val);
    1.60 +    if (!RtlCompareUnicodeString(&val, &dummy_group_name, TRUE))
    1.61 +      dummy_group_index = (ULONG)i;
    1.62 +    if (!RtlCompareUnicodeString(&val, &wdf_load_group_name, TRUE))
    1.63 +      wdf_load_group_index = (ULONG)i;         
    1.64 +    if (!RtlCompareUnicodeString(&val, &boot_bus_extender_name, TRUE))
    1.65 +      boot_bus_extender_index = (ULONG)i;         
    1.66 +    KdPrint((__DRIVER_NAME "       %wZ\n", &val));        
    1.67 +  }
    1.68 +  KdPrint((__DRIVER_NAME "     dummy_group_index = %d\n", dummy_group_index));
    1.69 +  KdPrint((__DRIVER_NAME "     wdf_load_group_index = %d\n", wdf_load_group_index));
    1.70 +  KdPrint((__DRIVER_NAME "     boot_bus_extender_index = %d\n", boot_bus_extender_index));
    1.71 +  if (boot_bus_extender_index == -1)
    1.72 +  {
    1.73 +    WdfObjectDelete(new_load_order);
    1.74 +    WdfObjectDelete(old_load_order);
    1.75 +    WdfRegistryClose(sgo_key);
    1.76 +    return; /* something is very wrong */
    1.77 +  }
    1.78 +  if (dummy_group_index == 1 && (wdf_load_group_index == -1 || (wdf_load_group_index > dummy_group_index && wdf_load_group_index < boot_bus_extender_index)))
    1.79 +  {
    1.80 +    return; /* our work here is done */
    1.81 +  }
    1.82 +  for (i = 0; i < WdfCollectionGetCount(old_load_order); i++)
    1.83 +  {
    1.84 +    WDFOBJECT ws;
    1.85 +    if (i == 1)
    1.86 +    {
    1.87 +      WDFSTRING tmp_wdf_string;
    1.88 +      WdfStringCreate(&dummy_group_name, WDF_NO_OBJECT_ATTRIBUTES, &tmp_wdf_string);
    1.89 +      WdfCollectionAdd(new_load_order, tmp_wdf_string);
    1.90 +      WdfObjectDelete(tmp_wdf_string);
    1.91 +    }
    1.92 +    if (i == 2 && wdf_load_group_index != -1)
    1.93 +    {
    1.94 +      WDFSTRING tmp_wdf_string;
    1.95 +      WdfStringCreate(&wdf_load_group_name, WDF_NO_OBJECT_ATTRIBUTES, &tmp_wdf_string);
    1.96 +      WdfCollectionAdd(new_load_order, tmp_wdf_string);
    1.97 +      WdfObjectDelete(tmp_wdf_string);
    1.98 +    }
    1.99 +    if (i == (ULONG)dummy_group_index || i == (ULONG)wdf_load_group_index)
   1.100 +      continue;
   1.101 +    ws = WdfCollectionGetItem(old_load_order, i);
   1.102 +    WdfCollectionAdd(new_load_order, ws);
   1.103 +  }
   1.104 +  WdfRegistryAssignMultiString(sgo_key, &list_name, new_load_order);
   1.105 +  KdPrint((__DRIVER_NAME "     New Order:\n"));        
   1.106 +  for (i = 0; i < WdfCollectionGetCount(new_load_order); i++)
   1.107 +  {
   1.108 +    WDFOBJECT ws = WdfCollectionGetItem(new_load_order, i);
   1.109 +    UNICODE_STRING val;
   1.110 +    WdfStringGetUnicodeString(ws, &val);
   1.111 +    KdPrint((__DRIVER_NAME "       %wZ\n", &val));        
   1.112 +  }
   1.113 +  WdfObjectDelete(new_load_order);
   1.114 +  WdfObjectDelete(old_load_order);
   1.115 +  WdfRegistryClose(sgo_key);
   1.116 +  
   1.117 +  FUNCTION_EXIT();
   1.118 +  
   1.119 +  return;
   1.120 +}
   1.121 +
   1.122  NTSTATUS
   1.123  DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
   1.124  {
   1.125 @@ -240,86 +346,17 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
   1.126    char Buf[300];// Sometimes bigger then 200 if system reboot from crash
   1.127    ULONG BufLen = 300;
   1.128    PKEY_VALUE_PARTIAL_INFORMATION KeyPartialValue;
   1.129 -  WDFCOLLECTION old_load_order, new_load_order;
   1.130 -  DECLARE_CONST_UNICODE_STRING(sgo_name, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\ServiceGroupOrder");
   1.131 -  DECLARE_CONST_UNICODE_STRING(list_name, L"List");
   1.132 -  WDFKEY sgo_key;
   1.133 +#if 0
   1.134 +  WDF_TIMER_CONFIG  timer_config;
   1.135 +  OBJECT_ATTRIBUTES timer_attributes;
   1.136 +#endif
   1.137  
   1.138    UNREFERENCED_PARAMETER(RegistryPath);
   1.139  
   1.140    FUNCTION_ENTER();
   1.141 +  
   1.142 +  XenPci_FixLoadOrder();
   1.143  
   1.144 -  WdfCollectionCreate(WDF_NO_OBJECT_ATTRIBUTES, &old_load_order);
   1.145 -  WdfCollectionCreate(WDF_NO_OBJECT_ATTRIBUTES, &new_load_order);
   1.146 -  status = WdfRegistryOpenKey(NULL, &sgo_name, KEY_QUERY_VALUE, WDF_NO_OBJECT_ATTRIBUTES, &sgo_key);
   1.147 -  if (NT_SUCCESS(status))
   1.148 -  {
   1.149 -    status = WdfRegistryQueryMultiString(sgo_key, &list_name, WDF_NO_OBJECT_ATTRIBUTES, old_load_order);
   1.150 -    if (!NT_SUCCESS(status))
   1.151 -    {
   1.152 -      KdPrint((__DRIVER_NAME "     Error reading ServiceGroupOrder\\List value %08x\n", status));
   1.153 -    }
   1.154 -    else
   1.155 -    {
   1.156 -      ULONG i;
   1.157 -      LONG boot_bus_extender_index = -1;
   1.158 -      LONG wdf_load_group_index = -1;
   1.159 -      DECLARE_CONST_UNICODE_STRING(wdf_load_group_name, L"WdfLoadGroup");
   1.160 -      DECLARE_CONST_UNICODE_STRING(boot_bus_extender_name, L"Boot Bus Extender");
   1.161 -      KdPrint((__DRIVER_NAME "     Current Order:\n"));        
   1.162 -      for (i = 0; i < WdfCollectionGetCount(old_load_order); i++)
   1.163 -      {
   1.164 -        WDFOBJECT ws = WdfCollectionGetItem(old_load_order, i);
   1.165 -        UNICODE_STRING val;
   1.166 -        WdfStringGetUnicodeString(ws, &val);
   1.167 -        if (!RtlCompareUnicodeString(&val, &wdf_load_group_name, TRUE))
   1.168 -          wdf_load_group_index = (ULONG)i;
   1.169 -        if (!RtlCompareUnicodeString(&val, &boot_bus_extender_name, TRUE))
   1.170 -          boot_bus_extender_index = (ULONG)i;         
   1.171 -        KdPrint((__DRIVER_NAME "       %wZ\n", &val));        
   1.172 -      }
   1.173 -      KdPrint((__DRIVER_NAME "     wdf_load_group_index = %d\n", wdf_load_group_index));
   1.174 -      KdPrint((__DRIVER_NAME "     boot_bus_extender_index = %d\n", boot_bus_extender_index));
   1.175 -      if (boot_bus_extender_index >= 0 && wdf_load_group_index >= 0
   1.176 -          && boot_bus_extender_index < wdf_load_group_index)
   1.177 -      {
   1.178 -        for (i = 0; i < WdfCollectionGetCount(old_load_order); i++)
   1.179 -        {
   1.180 -          UNICODE_STRING val;
   1.181 -          WDFOBJECT ws;
   1.182 -          if (i == (ULONG)wdf_load_group_index)
   1.183 -            continue;
   1.184 -          ws = WdfCollectionGetItem(old_load_order, i);
   1.185 -          WdfStringGetUnicodeString(ws, &val);
   1.186 -          if (i == (ULONG)boot_bus_extender_index)
   1.187 -          {
   1.188 -            WDFSTRING wdf_load_group_val;
   1.189 -            WdfStringCreate(&wdf_load_group_name, WDF_NO_OBJECT_ATTRIBUTES, &wdf_load_group_val);
   1.190 -            WdfCollectionAdd(new_load_order, wdf_load_group_val);
   1.191 -          }
   1.192 -          WdfCollectionAdd(new_load_order, ws);
   1.193 -        }
   1.194 -        KdPrint((__DRIVER_NAME "     New Order:\n"));        
   1.195 -        for (i = 0; i < WdfCollectionGetCount(new_load_order); i++)
   1.196 -        {
   1.197 -          WDFOBJECT ws = WdfCollectionGetItem(new_load_order, i);
   1.198 -          UNICODE_STRING val;
   1.199 -          WdfStringGetUnicodeString(ws, &val);
   1.200 -          KdPrint((__DRIVER_NAME "       %wZ\n", &val));        
   1.201 -        }
   1.202 -        WdfRegistryAssignMultiString(sgo_key, &list_name, new_load_order);
   1.203 -      }
   1.204 -    }
   1.205 -    WdfRegistryClose(sgo_key);
   1.206 -  }
   1.207 -  else
   1.208 -  {
   1.209 -    KdPrint((__DRIVER_NAME "     Error opening ServiceGroupOrder key %08x\n", status));
   1.210 -  }
   1.211 -  WdfObjectDelete(new_load_order);
   1.212 -  WdfObjectDelete(old_load_order);
   1.213 -
   1.214 -  //TestStuff();  
   1.215    RtlInitUnicodeString(&RegKeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control");
   1.216    InitializeObjectAttributes(&RegObjectAttributes, &RegKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL);
   1.217    status = ZwOpenKey(&RegHandle, KEY_READ, &RegObjectAttributes);
   1.218 @@ -380,13 +417,13 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
   1.219    if (qemu_filtered)
   1.220      KdPrint((__DRIVER_NAME "     PV Devices Active\n"));
   1.221    else
   1.222 -    KdPrint((__DRIVER_NAME "     PV Devices InActive\n"));
   1.223 +    KdPrint((__DRIVER_NAME "     PV Devices Inactive\n"));
   1.224    
   1.225    WDF_DRIVER_CONFIG_INIT(&config, XenPci_EvtDeviceAdd);
   1.226    status = WdfDriverCreate(DriverObject, RegistryPath, WDF_NO_OBJECT_ATTRIBUTES, &config, &driver);
   1.227  
   1.228    if (!NT_SUCCESS(status)) {
   1.229 -    KdPrint( ("WdfDriverCreate failed with status 0x%x\n", status));
   1.230 +    KdPrint((__DRIVER_NAME "     WdfDriverCreate failed with status 0x%x\n", status));
   1.231    }
   1.232  
   1.233    FUNCTION_EXIT();