win-pvdrivers

view xenenum/xenenum.c @ 77:b9b4b731f890

Tidyups and work on getting xennet at least as functional as it was before I started messing with it :)
author James Harper <james.harper@bendigoit.com.au>
date Fri Dec 28 23:21:49 2007 +1100 (2007-12-28)
parents dfa772949c6e
children 17319a4920eb
line source
1 #include "xenenum.h"
2 #include <io/blkif.h>
3 #include <srb.h>
4 #include <scsi.h>
5 #include <ntddscsi.h>
6 #include <ntdddisk.h>
7 #include <stdlib.h>
8 #include <xen_public.h>
9 #include <io/xenbus.h>
10 #include <ntddft.h>
12 #define wmb() KeMemoryBarrier()
13 #define mb() KeMemoryBarrier()
15 DRIVER_INITIALIZE DriverEntry;
17 static NTSTATUS
18 XenEnum_AddDevice(WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit);
19 static NTSTATUS
20 XenEnum_PrepareHardware(WDFDEVICE hDevice, WDFCMRESLIST Resources, WDFCMRESLIST ResourcesTranslated);
21 static NTSTATUS
22 XenEnum_ReleaseHardware(WDFDEVICE Device, WDFCMRESLIST ResourcesTranslated);
23 static NTSTATUS
24 XenEnum_D0Entry(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState);
25 static NTSTATUS
26 XenEnum_D0EntryPostInterruptsEnabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState);
27 static NTSTATUS
28 XenEnum_D0Exit(WDFDEVICE Device, WDF_POWER_DEVICE_STATE TargetState);
29 static NTSTATUS
30 XenEnum_DeviceUsageNotification(WDFDEVICE Device, WDF_SPECIAL_FILE_TYPE NotificationType, BOOLEAN IsInNotificationPath);
32 static NTSTATUS
33 XenEnum_ChildListCreateDevice(WDFCHILDLIST ChildList, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, PWDFDEVICE_INIT ChildInit);
35 static VOID
36 XenEnum_WatchHandler(char *Path, PVOID Data);
38 #ifdef ALLOC_PRAGMA
39 #pragma alloc_text (INIT, DriverEntry)
40 #pragma alloc_text (PAGE, XenEnum_AddDevice)
41 #endif
43 LIST_ENTRY DeviceListHead;
44 //XEN_IFACE_EVTCHN EvtChnInterface;
45 //XEN_IFACE_XENBUS XenBusInterface;
46 XEN_IFACE XenInterface;
47 //XEN_IFACE_GNTTBL GntTblInterface;
49 static BOOLEAN AutoEnumerate;
51 NTSTATUS
52 DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
53 {
54 WDF_DRIVER_CONFIG config;
55 ULONG status;
56 UNICODE_STRING RegKeyName;
57 UNICODE_STRING RegValueName;
58 HANDLE RegHandle;
59 OBJECT_ATTRIBUTES RegObjectAttributes;
60 char Buf[200];
61 ULONG BufLen = 200;
62 PKEY_VALUE_PARTIAL_INFORMATION KeyPartialValue;
63 int State = 0;
64 int StartPos = 0;
65 WCHAR *SystemStartOptions;
66 size_t SystemStartOptionsLen;
67 size_t i;
69 KdPrint((__DRIVER_NAME " --> DriverEntry\n"));
71 WDF_DRIVER_CONFIG_INIT(&config, XenEnum_AddDevice);
72 status = WdfDriverCreate(
73 DriverObject,
74 RegistryPath,
75 WDF_NO_OBJECT_ATTRIBUTES,
76 &config,
77 WDF_NO_HANDLE);
78 if(!NT_SUCCESS(status))
79 {
80 KdPrint((__DRIVER_NAME " WdfDriverCreate failed with status 0x%08x\n", status));
81 }
83 RtlInitUnicodeString(&RegKeyName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control");
84 InitializeObjectAttributes(&RegObjectAttributes, &RegKeyName, OBJ_CASE_INSENSITIVE, NULL, NULL);
85 status = ZwOpenKey(&RegHandle, KEY_READ, &RegObjectAttributes);
86 if(!NT_SUCCESS(status))
87 {
88 KdPrint((__DRIVER_NAME " ZwOpenKey returned %08x\n", status));
89 }
91 RtlInitUnicodeString(&RegValueName, L"SystemStartOptions");
92 status = ZwQueryValueKey(RegHandle, &RegValueName, KeyValuePartialInformation, Buf, BufLen, &BufLen);
93 if(!NT_SUCCESS(status))
94 {
95 KdPrint((__DRIVER_NAME " ZwQueryKeyValue returned %08x\n", status));
96 }
97 //KdPrint((__DRIVER_NAME " BufLen = %d\n", BufLen));
98 KeyPartialValue = (PKEY_VALUE_PARTIAL_INFORMATION)Buf;
99 KdPrint((__DRIVER_NAME " Buf = %ws\n", KeyPartialValue->Data));
100 SystemStartOptions = (WCHAR *)KeyPartialValue->Data;
102 AutoEnumerate = FALSE;
104 RtlStringCbLengthW(SystemStartOptions, KeyPartialValue->DataLength, &SystemStartOptionsLen);
106 for (i = 0; i <= SystemStartOptionsLen/2; i++)
107 {
108 //KdPrint((__DRIVER_NAME " pos = %d, state = %d, char = '%wc' (%d)\n", i, State, SystemStartOptions[i], SystemStartOptions[i]));
110 switch (State)
111 {
112 case 0:
113 if (SystemStartOptions[i] == L'G')
114 {
115 StartPos = i;
116 State = 2;
117 } else if (SystemStartOptions[i] != L' ')
118 {
119 State = 1;
120 }
121 break;
122 case 1:
123 if (SystemStartOptions[i] == L' ')
124 State = 0;
125 break;
126 case 2:
127 if (SystemStartOptions[i] == L'P')
128 State = 3;
129 else
130 State = 0;
131 break;
132 case 3:
133 if (SystemStartOptions[i] == L'L')
134 State = 4;
135 else
136 State = 0;
137 break;
138 case 4:
139 if (SystemStartOptions[i] == L'P')
140 State = 5;
141 else
142 State = 0;
143 break;
144 case 5:
145 if (SystemStartOptions[i] == L'V')
146 State = 6;
147 else
148 State = 0;
149 break;
150 case 6:
151 if (SystemStartOptions[i] == L' ' || SystemStartOptions[i] == 0)
152 AutoEnumerate = TRUE;
153 State = 0;
154 break;
155 }
156 }
158 KdPrint((__DRIVER_NAME " AutoEnumerate = %d\n", AutoEnumerate));
160 KdPrint((__DRIVER_NAME " <-- DriverEntry\n"));
162 return status;
163 }
165 DEFINE_GUID( GUID_XENPCI_DEVCLASS, 0xC828ABE9, 0x14CA, 0x4445, 0xBA, 0xA6, 0x82, 0xC2, 0x37, 0x6C, 0x65, 0x18);
167 static WDFDEVICE GlobalDevice;
168 static PDEVICE_OBJECT Pdo;
170 static NTSTATUS
171 XenEnum_AddDevice(WDFDRIVER Driver, PWDFDEVICE_INIT DeviceInit)
172 {
173 WDF_CHILD_LIST_CONFIG ChildListConfig;
174 NTSTATUS status;
175 WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
176 PNP_BUS_INFORMATION BusInfo;
178 UNREFERENCED_PARAMETER(Driver);
180 KdPrint((__DRIVER_NAME " --> DeviceAdd\n"));
182 Pdo = WdfFdoInitWdmGetPhysicalDevice(DeviceInit);
184 WdfDeviceInitSetDeviceType(DeviceInit, FILE_DEVICE_BUS_EXTENDER);
185 WDF_CHILD_LIST_CONFIG_INIT(&ChildListConfig, sizeof(XENPCI_IDENTIFICATION_DESCRIPTION), XenEnum_ChildListCreateDevice);
186 WdfFdoInitSetDefaultChildListConfig(DeviceInit, &ChildListConfig, WDF_NO_OBJECT_ATTRIBUTES);
187 WdfDeviceInitSetExclusive(DeviceInit, FALSE);
189 WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
190 pnpPowerCallbacks.EvtDevicePrepareHardware = XenEnum_PrepareHardware;
191 pnpPowerCallbacks.EvtDeviceReleaseHardware = XenEnum_ReleaseHardware;
192 pnpPowerCallbacks.EvtDeviceD0Entry = XenEnum_D0Entry;
193 pnpPowerCallbacks.EvtDeviceD0EntryPostInterruptsEnabled = XenEnum_D0EntryPostInterruptsEnabled;
194 pnpPowerCallbacks.EvtDeviceD0Exit = XenEnum_D0Exit;
195 pnpPowerCallbacks.EvtDeviceUsageNotification = XenEnum_DeviceUsageNotification;
196 WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
198 /*create a device instance.*/
199 status = WdfDeviceCreate(&DeviceInit, WDF_NO_OBJECT_ATTRIBUTES, &GlobalDevice);
200 if(!NT_SUCCESS(status))
201 {
202 KdPrint((__DRIVER_NAME "WdfDeviceCreate failed with status 0x%08x\n", status));
203 return status;
204 }
206 BusInfo.BusTypeGuid = GUID_XENPCI_DEVCLASS;
207 BusInfo.LegacyBusType = Internal;
208 BusInfo.BusNumber = 0;
210 WdfDeviceSetBusInformationForChildren(GlobalDevice, &BusInfo);
212 /*
213 WdfDeviceSetSpecialFileSupport(GlobalDevice, WdfSpecialFilePaging, TRUE);
214 WdfDeviceSetSpecialFileSupport(GlobalDevice, WdfSpecialFileHibernation, TRUE);
215 WdfDeviceSetSpecialFileSupport(GlobalDevice, WdfSpecialFileDump, TRUE);
216 */
218 status = STATUS_SUCCESS;
220 KdPrint((__DRIVER_NAME " <-- DeviceAdd\n"));
221 return status;
222 }
224 static NTSTATUS
225 XenEnum_PrepareHardware(
226 IN WDFDEVICE Device,
227 IN WDFCMRESLIST ResourceList,
228 IN WDFCMRESLIST ResourceListTranslated)
229 {
230 NTSTATUS status = STATUS_SUCCESS;
232 UNREFERENCED_PARAMETER(ResourceList);
233 UNREFERENCED_PARAMETER(ResourceListTranslated);
235 KdPrint((__DRIVER_NAME " --> EvtDevicePrepareHardware\n"));
237 status = WdfFdoQueryForInterface(Device, &GUID_XEN_IFACE, (PINTERFACE)&XenInterface, sizeof(XEN_IFACE), 1, NULL);
238 if(!NT_SUCCESS(status))
239 {
240 KdPrint((__DRIVER_NAME " WdfFdoQueryForInterface (EvtChn) failed with status 0x%08x\n", status));
241 }
243 InitializeListHead(&DeviceListHead);
245 KdPrint((__DRIVER_NAME " <-- EvtDevicePrepareHardware\n"));
247 return status;
248 }
250 static NTSTATUS
251 XenEnum_ReleaseHardware(WDFDEVICE Device, WDFCMRESLIST ResourcesTranslated)
252 {
253 UNREFERENCED_PARAMETER(Device);
254 UNREFERENCED_PARAMETER(ResourcesTranslated);
256 // release interfaces here...
258 return STATUS_SUCCESS;
259 }
261 static NTSTATUS
262 XenEnum_D0Entry(
263 IN WDFDEVICE Device,
264 IN WDF_POWER_DEVICE_STATE PreviousState
265 )
266 {
267 NTSTATUS status = STATUS_SUCCESS;
269 UNREFERENCED_PARAMETER(Device);
270 UNREFERENCED_PARAMETER(PreviousState);
272 //KdPrint((__DRIVER_NAME " --> EvtDeviceD0Entry\n"));
274 //KdPrint((__DRIVER_NAME " <-- EvtDeviceD0Entry\n"));
276 return status;
277 }
279 static int EnumeratedDevices;
280 static KEVENT WaitDevicesEvent;
282 static NTSTATUS
283 XenEnum_D0EntryPostInterruptsEnabled(WDFDEVICE Device, WDF_POWER_DEVICE_STATE PreviousState)
284 {
285 NTSTATUS status = STATUS_SUCCESS;
286 PXENPCI_XEN_DEVICE_DATA PdoDeviceData;
287 char **Devices;
288 char *msg;
289 char buffer[128];
290 int i;
291 LARGE_INTEGER WaitTimeout;
293 UNREFERENCED_PARAMETER(Device);
294 UNREFERENCED_PARAMETER(PreviousState);
296 KdPrint((__DRIVER_NAME " --> EvtDeviceD0EntryPostInterruptsEnabled\n"));
298 PdoDeviceData = (PXENPCI_XEN_DEVICE_DATA)Pdo->DeviceExtension; //GetXenDeviceData(Device);
300 //KdPrint((__DRIVER_NAME " Path = %s\n", PdoDeviceData->Path));
301 PdoDeviceData->WatchHandler = XenEnum_WatchHandler;
302 PdoDeviceData->WatchContext = Device;
304 EnumeratedDevices = 0;
305 KeInitializeEvent(&WaitDevicesEvent, SynchronizationEvent, FALSE);
307 // TODO: Should probably do this in an EvtChildListScanForChildren
308 if (AutoEnumerate)
309 {
310 // TODO: Get the correct path from parent here...
311 msg = XenInterface.XenBus_List(XenInterface.InterfaceHeader.Context, XBT_NIL, PdoDeviceData->Path, &Devices);
312 if (!msg)
313 {
314 for (i = 0; Devices[i]; i++)
315 {
316 KdPrint((__DRIVER_NAME " found existing device %s\n", Devices[i]));
317 KdPrint((__DRIVER_NAME " faking watch event for %s/%s", PdoDeviceData->Path, Devices[i]));
318 RtlStringCbPrintfA(buffer, ARRAY_SIZE(buffer), "%s/%s", PdoDeviceData->Path, Devices[i]);
319 XenEnum_WatchHandler(buffer, Device);
320 //ExFreePoolWithTag(Devices[i], XENPCI_POOL_TAG);
321 }
322 /*
323 KdPrint((__DRIVER_NAME " Waiting for devices to be enumerated\n"));
324 while (EnumeratedDevices != i)
325 {
326 WaitTimeout.QuadPart = -600000000;
327 if (KeWaitForSingleObject(&WaitDevicesEvent, Executive, KernelMode, FALSE, &WaitTimeout) == STATUS_TIMEOUT)
328 {
329 KdPrint((__DRIVER_NAME " Wait timed out\n"));
330 break;
331 }
332 KdPrint((__DRIVER_NAME " %d out of %d devices enumerated\n", EnumeratedDevices, i));
333 }
334 */
335 }
336 }
338 KdPrint((__DRIVER_NAME " <-- EvtDeviceD0EntryPostInterruptsEnabled\n"));
340 return status;
341 }
343 static NTSTATUS
344 XenEnum_D0Exit(
345 IN WDFDEVICE Device,
346 IN WDF_POWER_DEVICE_STATE TargetState
347 )
348 {
349 NTSTATUS status = STATUS_SUCCESS;
350 //char *response;
352 UNREFERENCED_PARAMETER(Device);
353 UNREFERENCED_PARAMETER(TargetState);
355 //KdPrint((__DRIVER_NAME " --> EvtDeviceD0Exit\n"));
357 //response = XenBusInterface.RemWatch(XBT_NIL, XenBusInterface.InterfaceHeader.Context, XenEnum_WatchHandler, NULL);
359 //KdPrint((__DRIVER_NAME " <-- EvtDeviceD0Exit\n"));
361 return status;
362 }
364 static NTSTATUS
365 XenEnum_DeviceUsageNotification(WDFDEVICE Device, WDF_SPECIAL_FILE_TYPE NotificationType, BOOLEAN IsInNotificationPath)
366 {
367 KdPrint((__DRIVER_NAME " --> DeviceUsageNotification\n"));
369 switch (NotificationType)
370 {
371 case WdfSpecialFilePaging:
372 KdPrint((__DRIVER_NAME " NotificationType = WdfSpecialFilePaging, Using = %d\n", IsInNotificationPath));
373 break;
374 case WdfSpecialFileHibernation:
375 KdPrint((__DRIVER_NAME " NotificationType = WdfSpecialFileHibernation, Using = %d\n", IsInNotificationPath));
376 break;
377 case WdfSpecialFileDump:
378 KdPrint((__DRIVER_NAME " NotificationType = WdfSpecialFileDump, Using = %d\n", IsInNotificationPath));
379 break;
380 default:
381 KdPrint((__DRIVER_NAME " NotificationType = %d, Using = %d\n", NotificationType, IsInNotificationPath));
382 break;
383 }
384 KdPrint((__DRIVER_NAME " <-- DeviceUsageNotification\n"));
386 return TRUE;
387 }
389 static VOID
390 XenEnum_IoDefault(
391 IN WDFQUEUE Queue,
392 IN WDFREQUEST Request
393 )
394 {
395 UNREFERENCED_PARAMETER(Queue);
397 //KdPrint((__DRIVER_NAME " --> EvtDeviceIoDefault\n"));
399 WdfRequestComplete(Request, STATUS_NOT_IMPLEMENTED);
401 //KdPrint((__DRIVER_NAME " <-- EvtDeviceIoDefault\n"));
402 }
404 static VOID
405 XenEnum_WatchHandler(char *Path, PVOID Data)
406 {
407 NTSTATUS Status;
408 XENPCI_IDENTIFICATION_DESCRIPTION IdentificationDescription;
409 char **Bits;
410 int Count;
411 char TmpPath[128];
412 char *Value;
413 ANSI_STRING AnsiBuf;
414 WDFCHILDLIST ChildList;
415 WDFDEVICE Device = Data;
416 WDF_CHILD_LIST_ITERATOR ChildIterator;
417 WDFDEVICE ChildDevice;
418 PXENPCI_XEN_DEVICE_DATA ChildDeviceData;
420 UNREFERENCED_PARAMETER(Data);
422 KdPrint((__DRIVER_NAME " --> WatchHandler\n"));
424 KdPrint((__DRIVER_NAME " Path = %s\n", Path));
426 Bits = SplitString(Path, '/', 4, &Count);
427 if (Count == 3)
428 {
429 KdPrint((__DRIVER_NAME " Creating %s\n", Bits[2]));
430 ChildList = WdfFdoGetDefaultChildList(Device);
431 WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT(&IdentificationDescription.Header, sizeof(IdentificationDescription));
432 strncpy(IdentificationDescription.Path, Path, 128);
433 RtlInitAnsiString(&AnsiBuf, Bits[1]);
434 RtlAnsiStringToUnicodeString(&IdentificationDescription.DeviceType, &AnsiBuf, TRUE);
435 IdentificationDescription.DeviceIndex = atoi(Bits[2]);
436 if (IdentificationDescription.DeviceIndex > 0)
437 {
438 Status = WdfChildListAddOrUpdateChildDescriptionAsPresent(ChildList, &IdentificationDescription.Header, NULL);
439 }
440 }
441 else if (Count > 3)
442 {
443 WDF_CHILD_LIST_ITERATOR_INIT(&ChildIterator, WdfRetrievePresentChildren);
444 ChildList = WdfFdoGetDefaultChildList(Device);
445 WdfChildListBeginIteration(ChildList, &ChildIterator);
446 while (NT_SUCCESS(WdfChildListRetrieveNextDevice(ChildList, &ChildIterator, &ChildDevice, NULL)))
447 {
448 ChildDeviceData = GetXenDeviceData(ChildDevice);
449 if (!ChildDeviceData)
450 {
451 KdPrint((__FUNCTION__ " No child device data, should never happen\n"));
452 continue;
453 }
454 if (strncmp(ChildDeviceData->Path, Path, strlen(ChildDeviceData->Path)) == 0 && Path[strlen(ChildDeviceData->Path)] == '/')
455 {
456 KdPrint((__DRIVER_NAME " Child Path = %s (Match - WatchHandler = %08x)\n", ChildDeviceData->Path, ChildDeviceData->WatchHandler));
457 if (ChildDeviceData->WatchHandler != NULL)
458 ChildDeviceData->WatchHandler(Path, ChildDeviceData->WatchContext);
459 }
460 else
461 {
462 //KdPrint((__DRIVER_NAME " Child Path = %s (No Match)\n", ChildDeviceData->Path));
463 }
464 }
465 WdfChildListEndIteration(ChildList, &ChildIterator);
466 }
467 FreeSplitString(Bits, Count);
469 KdPrint((__DRIVER_NAME " <-- WatchHandler\n"));
471 return;
472 }
474 static NTSTATUS
475 XenEnum_ChildListCreateDevice(WDFCHILDLIST ChildList, PWDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER IdentificationDescription, PWDFDEVICE_INIT ChildInit)
476 {
477 NTSTATUS status;
478 WDFDEVICE ChildDevice;
479 PXENPCI_IDENTIFICATION_DESCRIPTION XenIdentificationDesc;
480 DECLARE_UNICODE_STRING_SIZE(buffer, 50);
481 WDF_OBJECT_ATTRIBUTES PdoAttributes;
482 DECLARE_CONST_UNICODE_STRING(DeviceLocation, L"Xen Bus");
483 PXENPCI_XEN_DEVICE_DATA ChildDeviceData = NULL;
484 WDF_QUERY_INTERFACE_CONFIG qiConfig;
485 // WDF_PDO_EVENT_CALLBACKS PdoCallbacks;
486 // UCHAR PnpMinors[2] = { IRP_MN_START_DEVICE, IRP_MN_STOP_DEVICE };
488 UNREFERENCED_PARAMETER(ChildList);
490 KdPrint((__DRIVER_NAME " --> ChildListCreateDevice\n"));
492 XenIdentificationDesc = CONTAINING_RECORD(IdentificationDescription, XENPCI_IDENTIFICATION_DESCRIPTION, Header);
494 // ChildDeviceData = XenEnumIdentificationDesc->DeviceData;
496 WdfDeviceInitSetDeviceType(ChildInit, FILE_DEVICE_UNKNOWN);
498 status = RtlUnicodeStringPrintf(&buffer, L"XEN\\%wsdev\0", XenIdentificationDesc->DeviceType.Buffer);
500 KdPrint((__DRIVER_NAME " %ws", buffer.Buffer));
502 status = WdfPdoInitAssignDeviceID(ChildInit, &buffer);
503 status = WdfPdoInitAddCompatibleID(ChildInit, &buffer);
504 status = WdfPdoInitAddHardwareID(ChildInit, &buffer);
506 status = RtlUnicodeStringPrintf(&buffer, L"%02d\0", XenIdentificationDesc->DeviceIndex);
507 status = WdfPdoInitAssignInstanceID(ChildInit, &buffer);
509 status = RtlUnicodeStringPrintf(&buffer, L"Xen %ws Device (%d)", XenIdentificationDesc->DeviceType.Buffer, XenIdentificationDesc->DeviceIndex);
510 status = WdfPdoInitAddDeviceText(ChildInit, &buffer, &DeviceLocation, 0x409);
511 WdfPdoInitSetDefaultLocale(ChildInit, 0x409);
513 WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&PdoAttributes, XENPCI_XEN_DEVICE_DATA);
515 status = WdfDeviceCreate(&ChildInit, &PdoAttributes, &ChildDevice);
516 if (!NT_SUCCESS(status))
517 {
518 KdPrint((__DRIVER_NAME " WdfDeviceCreate status = %08X\n", status));
519 }
521 WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFilePaging, TRUE);
522 WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileHibernation, TRUE);
523 WdfDeviceSetSpecialFileSupport(ChildDevice, WdfSpecialFileDump, TRUE);
525 ChildDeviceData = GetXenDeviceData(ChildDevice);
526 ChildDeviceData->Magic = XEN_DATA_MAGIC;
527 ChildDeviceData->AutoEnumerate = AutoEnumerate;
528 ChildDeviceData->WatchHandler = NULL;
529 strncpy(ChildDeviceData->Path, XenIdentificationDesc->Path, 128);
530 // memcpy(&ChildDeviceData->InterruptRaw, &InterruptRaw, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
531 // memcpy(&ChildDeviceData->InterruptTranslated, &InterruptTranslated, sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));
533 ChildDeviceData->XenInterface.InterfaceHeader.Size = sizeof(ChildDeviceData->XenInterface);
534 ChildDeviceData->XenInterface.InterfaceHeader.Version = 1;
535 ChildDeviceData->XenInterface.InterfaceHeader.Context = XenInterface.InterfaceHeader.Context;
536 ChildDeviceData->XenInterface.InterfaceHeader.InterfaceReference = WdfDeviceInterfaceReferenceNoOp;
537 ChildDeviceData->XenInterface.InterfaceHeader.InterfaceDereference = WdfDeviceInterfaceDereferenceNoOp;
539 ChildDeviceData->XenInterface.AllocMMIO = XenInterface.AllocMMIO;
540 ChildDeviceData->XenInterface.FreeMem = XenInterface.FreeMem;
542 ChildDeviceData->XenInterface.EvtChn_Bind = XenInterface.EvtChn_Bind;
543 ChildDeviceData->XenInterface.EvtChn_Unbind = XenInterface.EvtChn_Unbind;
544 ChildDeviceData->XenInterface.EvtChn_Mask = XenInterface.EvtChn_Mask;
545 ChildDeviceData->XenInterface.EvtChn_Unmask = XenInterface.EvtChn_Unmask;
546 ChildDeviceData->XenInterface.EvtChn_Notify = XenInterface.EvtChn_Notify;
547 ChildDeviceData->XenInterface.EvtChn_AllocUnbound = XenInterface.EvtChn_AllocUnbound;
548 ChildDeviceData->XenInterface.EvtChn_BindDpc = XenInterface.EvtChn_BindDpc;
550 ChildDeviceData->XenInterface.GntTbl_GrantAccess = XenInterface.GntTbl_GrantAccess;
551 ChildDeviceData->XenInterface.GntTbl_EndAccess = XenInterface.GntTbl_EndAccess;
553 ChildDeviceData->XenInterface.XenBus_Read = XenInterface.XenBus_Read;
554 ChildDeviceData->XenInterface.XenBus_Write = XenInterface.XenBus_Write;
555 ChildDeviceData->XenInterface.XenBus_Printf = XenInterface.XenBus_Printf;
556 ChildDeviceData->XenInterface.XenBus_StartTransaction = XenInterface.XenBus_StartTransaction;
557 ChildDeviceData->XenInterface.XenBus_EndTransaction = XenInterface.XenBus_EndTransaction;
558 ChildDeviceData->XenInterface.XenBus_List = XenInterface.XenBus_List;
559 ChildDeviceData->XenInterface.XenBus_AddWatch = XenInterface.XenBus_AddWatch;
560 ChildDeviceData->XenInterface.XenBus_RemWatch = XenInterface.XenBus_RemWatch;
562 WDF_QUERY_INTERFACE_CONFIG_INIT(&qiConfig, (PINTERFACE)&ChildDeviceData->XenInterface, &GUID_XEN_IFACE, NULL);
563 status = WdfDeviceAddQueryInterface(ChildDevice, &qiConfig);
564 if (!NT_SUCCESS(status)) {
565 return status;
566 }
573 KdPrint((__DRIVER_NAME " <-- ChildListCreateDevice (status = %08x)\n", status));
575 return status;
576 }