VOID GnttabTeardown( IN PXENBUS_GNTTAB_CONTEXT Context ) { Trace("====>\n"); Context->Fdo = NULL; HashTableDestroy(Context->MapTable); Context->MapTable = NULL; RtlZeroMemory(&Context->Lock, sizeof (KSPIN_LOCK)); RtlZeroMemory(&Context->List, sizeof (LIST_ENTRY)); RtlZeroMemory(&Context->DebugInterface, sizeof (XENBUS_DEBUG_INTERFACE)); RtlZeroMemory(&Context->SuspendInterface, sizeof (XENBUS_SUSPEND_INTERFACE)); RtlZeroMemory(&Context->CacheInterface, sizeof (XENBUS_CACHE_INTERFACE)); RtlZeroMemory(&Context->RangeSetInterface, sizeof (XENBUS_RANGE_SET_INTERFACE)); ASSERT(IsZeroMemory(Context, sizeof (XENBUS_GNTTAB_CONTEXT))); __GnttabFree(Context); Trace("<====\n"); }
static VOID GnttabDestroyCache( IN PINTERFACE Interface, IN PXENBUS_GNTTAB_CACHE Cache ) { PXENBUS_GNTTAB_CONTEXT Context = Interface->Context; KIRQL Irql; KeAcquireSpinLock(&Context->Lock, &Irql); RemoveEntryList(&Cache->ListEntry); KeReleaseSpinLock(&Context->Lock, Irql); RtlZeroMemory(&Cache->ListEntry, sizeof (LIST_ENTRY)); XENBUS_CACHE(Destroy, &Context->CacheInterface, Cache->Cache); Cache->Cache = NULL; Cache->Argument = NULL; Cache->ReleaseLock = NULL; Cache->AcquireLock = NULL; RtlZeroMemory(Cache->Name, sizeof (Cache->Name)); Cache->Context = NULL; ASSERT(IsZeroMemory(Cache, sizeof (XENBUS_GNTTAB_CACHE))); __GnttabFree(Cache); }
VOID DriverUnload( IN PDRIVER_OBJECT DriverObject ) { HANDLE UnplugKey; HANDLE ParametersKey; ASSERT3P(DriverObject, ==, __DriverGetDriverObject()); Trace("====>\n"); if (*InitSafeBootMode > 0) goto done; UnplugKey = __DriverGetUnplugKey(); RegistryCloseKey(UnplugKey); __DriverSetUnplugKey(NULL); ParametersKey = __DriverGetParametersKey(); if (ParametersKey != NULL) { RegistryCloseKey(ParametersKey); __DriverSetParametersKey(NULL); } RegistryTeardown(); done: __DriverSetDriverObject(NULL); ASSERT(IsZeroMemory(&Driver, sizeof (XENFILT_DRIVER))); Trace("<====\n"); }
VOID UnplugTeardown( IN OUT PXENFILT_UNPLUG_INTERFACE Interface ) { PXENFILT_UNPLUG_CONTEXT Context = Interface->Context; ULONG References; ASSERT3P(Context, ==, &UnplugContext); Trace("====>\n"); References = InterlockedDecrement(&Context->References); if (References > 0) goto done; Context->BlackListed = FALSE; Context->BootEmulated = FALSE; RtlZeroMemory(&Context->Lock, sizeof (HIGH_LOCK)); ASSERT(IsZeroMemory(Context, sizeof (XENFILT_UNPLUG_CONTEXT))); done: RtlZeroMemory(Interface, sizeof (XENFILT_UNPLUG_INTERFACE)); Trace("<====\n"); }
VOID DebugTeardown( IN OUT PXENBUS_DEBUG_INTERFACE Interface ) { PXENBUS_DEBUG_CONTEXT Context = Interface->Context; Trace("====>\n"); (VOID) KeDeregisterBugCheckCallback(&Context->BugCheckCallbackRecord); RtlZeroMemory(&Context->BugCheckCallbackRecord, sizeof (KBUGCHECK_CALLBACK_RECORD)); if (!IsListEmpty(&Context->List)) { PLIST_ENTRY ListEntry; for (ListEntry = Context->List.Flink; ListEntry != &Context->List; ListEntry = ListEntry->Flink) { PXENBUS_DEBUG_CALLBACK Callback; PCHAR Name; ULONG_PTR Offset; Callback = CONTAINING_RECORD(ListEntry, XENBUS_DEBUG_CALLBACK, ListEntry); ModuleLookup((ULONG_PTR)Callback->Caller, &Name, &Offset); if (Name != NULL) { Error("CALLBACK: %p PREFIX '%s' REGISTERED BY %s + %p\n", Callback->Function, Callback->Prefix, Name, (PVOID)Offset); } else { Error("CALLBACK: %p PREFIX '%s' REGISTERED BY %p\n", Callback->Function, Callback->Prefix, Callback->Caller); } } BUG("OUTSTANDING CALLBACKS"); } RtlZeroMemory(&Context->Lock, sizeof (KSPIN_LOCK)); RtlZeroMemory(&Context->List, sizeof (LIST_ENTRY)); ASSERT(IsZeroMemory(Context, sizeof (XENBUS_DEBUG_CONTEXT))); __DebugFree(Context); RtlZeroMemory(Interface, sizeof (XENBUS_DEBUG_INTERFACE)); Trace("<====\n"); }
VOID PdoDestroy( IN PXENFILT_PDO Pdo ) { PDEVICE_OBJECT LowerDeviceObject = Pdo->LowerDeviceObject; PXENFILT_DX Dx = Pdo->Dx; PDEVICE_OBJECT FilterDeviceObject = Dx->DeviceObject; ASSERT3U(__PdoGetDevicePnpState(Pdo), ==, Deleted); ASSERT(__PdoIsMissing(Pdo)); Pdo->Missing = FALSE; __PdoUnlink(Pdo); Info("%p (%s) (%s)\n", FilterDeviceObject, __PdoGetName(Pdo), Pdo->Reason); Pdo->Reason = NULL; Dx->Pdo = NULL; EmulatedRemoveObject(__PdoGetEmulatedInterface(Pdo), Pdo->EmulatedObject); Pdo->EmulatedObject = NULL; Pdo->EmulatedInterface = NULL; ThreadAlert(Pdo->DevicePowerThread); ThreadJoin(Pdo->DevicePowerThread); Pdo->DevicePowerThread = NULL; ThreadAlert(Pdo->SystemPowerThread); ThreadJoin(Pdo->SystemPowerThread); Pdo->SystemPowerThread = NULL; Pdo->PhysicalDeviceObject = NULL; Pdo->LowerDeviceObject = NULL; Pdo->Dx = NULL; IoDetachDevice(LowerDeviceObject); ASSERT(IsZeroMemory(Pdo, sizeof (XENFILT_PDO))); __PdoFree(Pdo); IoDeleteDevice(FilterDeviceObject); }
VOID DriverUnload( IN PDRIVER_OBJECT DriverObject ) { HANDLE ServiceKey; HANDLE AliasesKey; HANDLE AddressesKey; HANDLE ParametersKey; ASSERT3P(DriverObject, ==, __DriverGetDriverObject()); Trace("====>\n"); if (*InitSafeBootMode > 0) goto done; AliasesKey = __DriverGetAliasesKey(); __DriverSetAliasesKey(NULL); RegistryCloseKey(AliasesKey); AddressesKey = __DriverGetParametersKey(); __DriverSetAddressesKey(NULL); RegistryCloseKey(AddressesKey); ParametersKey = __DriverGetParametersKey(); if (ParametersKey != NULL) { __DriverSetParametersKey(NULL); RegistryCloseKey(ParametersKey); } ServiceKey = __DriverGetServiceKey(); __DriverSetServiceKey(NULL); RegistryCloseKey(ServiceKey); RegistryTeardown(); done: __DriverSetDriverObject(NULL); ASSERT(IsZeroMemory(&Driver, sizeof (XENVIF_DRIVER))); Trace("<====\n"); }
VOID NotifierTeardown( IN PXENVIF_NOTIFIER Notifier ) { KeFlushQueuedDpcs(); Notifier->Dpcs = 0; Notifier->Frontend = NULL; RtlZeroMemory(&Notifier->Dpc, sizeof (KDPC)); RtlZeroMemory(&Notifier->Lock, sizeof (KSPIN_LOCK)); ASSERT(IsZeroMemory(Notifier, sizeof (XENVIF_NOTIFIER))); __NotifierFree(Notifier); }
VOID PdoDestroy( IN PXENVBD_PDO Pdo ) { LARGE_INTEGER Timeout; Timeout.QuadPart = -1000000; while (InterlockedCompareExchange(&Pdo->ReferenceCount, 0, 0) > 0) { KeDelayExecutionThread(KernelMode, FALSE, &Timeout); } PdoD0ToD3(Pdo); FrontendDestroy(&Pdo->Frontend); ASSERT(IsZeroMemory(Pdo, sizeof(XENVBD_PDO))); __PdoFree(Pdo); }
VOID EmulatedTeardown( IN OUT PXENFILT_EMULATED_INTERFACE Interface ) { PXENFILT_EMULATED_CONTEXT Context = Interface->Context; Trace("====>\n"); if (Context->Table != NULL) { __EmulatedFree(Context->Table); Context->Table = NULL; } ASSERT(IsZeroMemory(Context, sizeof (XENFILT_EMULATED_CONTEXT))); __EmulatedFree(Context); RtlZeroMemory(Interface, sizeof (XENFILT_EMULATED_INTERFACE)); Trace("<====\n"); }
VOID SuspendTeardown( IN PXENBUS_SUSPEND_CONTEXT Context ) { Trace("====>\n"); Context->Fdo = NULL; RtlZeroMemory(&Context->DebugInterface, sizeof (XENBUS_DEBUG_INTERFACE)); RtlZeroMemory(&Context->Lock, sizeof (KSPIN_LOCK)); RtlZeroMemory(&Context->LateList, sizeof (LIST_ENTRY)); RtlZeroMemory(&Context->EarlyList, sizeof (LIST_ENTRY)); ASSERT(IsZeroMemory(Context, sizeof (XENBUS_SUSPEND_CONTEXT))); __SuspendFree(Context); Trace("<====\n"); }
static VOID GnttabDestroyCache( IN PXENBUS_GNTTAB_CONTEXT Context, IN PXENBUS_GNTTAB_CACHE Cache ) { CACHE(Destroy, Context->CacheInterface, Cache->Cache); Cache->Cache = NULL; Cache->Argument = NULL; Cache->ReleaseLock = NULL; Cache->AcquireLock = NULL; RtlZeroMemory(Cache->Name, sizeof (Cache->Name)); Cache->Context = NULL; ASSERT(IsZeroMemory(Cache, sizeof (XENBUS_GNTTAB_CACHE))); __GnttabFree(Cache); }
static FORCEINLINE NTSTATUS __CacheCreateObject( IN PXENBUS_CACHE Cache, OUT POBJECT_HEADER *Header ) { PVOID Object; NTSTATUS status; (*Header) = __CacheAllocate(sizeof (OBJECT_HEADER) + Cache->Size); status = STATUS_NO_MEMORY; if (*Header == NULL) goto fail1; (*Header)->Magic = OBJECT_HEADER_MAGIC; Object = (*Header) + 1; status = Cache->Ctor(Cache->Argument, Object); if (!NT_SUCCESS(status)) goto fail2; return STATUS_SUCCESS; fail2: Error("fail2\n"); (*Header)->Magic = 0; ASSERT(IsZeroMemory(*Header, sizeof (OBJECT_HEADER))); __CacheFree(*Header); fail1: Error("fail1 (%08x)\n", status); return status; }
NTSTATUS EmulatedInitialize( OUT PXENFILT_EMULATED_INTERFACE Interface ) { PXENFILT_EMULATED_CONTEXT Context; NTSTATUS status; Trace("====>\n"); Context = __EmulatedAllocate(sizeof (XENFILT_EMULATED_CONTEXT)); status = STATUS_NO_MEMORY; if (Context == NULL) goto fail1; status = __EmulatedGetDeviceTable(Context); if (!NT_SUCCESS(status)) goto fail2; Interface->Context = Context; Interface->Operations = &Operations; Trace("<====\n"); return STATUS_SUCCESS; fail2: Error("fail2\n"); ASSERT(IsZeroMemory(Context, sizeof (XENFILT_EMULATED_CONTEXT))); __EmulatedFree(Context); fail1: Error("fail1 (%08x)\n", status); return status; }
VOID DriverUnload( IN PDRIVER_OBJECT DriverObject ) { HANDLE ParametersKey; ASSERT3P(DriverObject, ==, __DriverGetDriverObject()); Trace("====>\n"); if (*InitSafeBootMode > 0) goto done; ParametersKey = __DriverGetParametersKey(); if (ParametersKey != NULL) { RegistryCloseKey(ParametersKey); __DriverSetParametersKey(NULL); } ProcessTeardown(); ModuleTeardown(); HypercallTeardown(&Driver.HypercallInterface); LogTeardown(); RegistryTeardown(); done: __DriverSetDriverObject(NULL); ASSERT(IsZeroMemory(&Driver, sizeof (XEN_DRIVER))); Trace("<====\n"); }
} DRIVER_UNLOAD DriverUnload; VOID DriverUnload( IN PDRIVER_OBJECT DriverObject ) { ASSERT3P(DriverObject, ==, __DriverGetDriverObject()); Trace("====>\n"); __DriverSetDriverObject(NULL); ASSERT(IsZeroMemory(&Driver, sizeof (XENHID_DRIVER))); Trace("<====\n"); } DRIVER_ADD_DEVICE AddDevice; NTSTATUS AddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT DeviceObject ) { NTSTATUS status; ASSERT3P(DriverObject, ==, __DriverGetDriverObject());
static NTSTATUS GnttabCreateCache( IN PINTERFACE Interface, IN const CHAR *Name, IN ULONG Reservation, IN VOID (*AcquireLock)(PVOID), IN VOID (*ReleaseLock)(PVOID), IN PVOID Argument, OUT PXENBUS_GNTTAB_CACHE *Cache ) { PXENBUS_GNTTAB_CONTEXT Context = Interface->Context; KIRQL Irql; NTSTATUS status; *Cache = __GnttabAllocate(sizeof (XENBUS_GNTTAB_CACHE)); status = STATUS_NO_MEMORY; if (*Cache == NULL) goto fail1; (*Cache)->Context = Context; status = RtlStringCbPrintfA((*Cache)->Name, sizeof ((*Cache)->Name), "%s_gnttab", Name); if (!NT_SUCCESS(status)) goto fail2; (*Cache)->AcquireLock = AcquireLock; (*Cache)->ReleaseLock = ReleaseLock; (*Cache)->Argument = Argument; status = XENBUS_CACHE(Create, &Context->CacheInterface, (*Cache)->Name, sizeof (XENBUS_GNTTAB_ENTRY), Reservation, GnttabEntryCtor, GnttabEntryDtor, GnttabAcquireLock, GnttabReleaseLock, *Cache, &(*Cache)->Cache); if (!NT_SUCCESS(status)) goto fail3; KeAcquireSpinLock(&Context->Lock, &Irql); InsertTailList(&Context->List, &(*Cache)->ListEntry); KeReleaseSpinLock(&Context->Lock, Irql); return STATUS_SUCCESS; fail3: Error("fail3\n"); (*Cache)->Argument = NULL; (*Cache)->ReleaseLock = NULL; (*Cache)->AcquireLock = NULL; RtlZeroMemory((*Cache)->Name, sizeof ((*Cache)->Name)); fail2: Error("fail2\n"); (*Cache)->Context = NULL; ASSERT(IsZeroMemory(*Cache, sizeof (XENBUS_GNTTAB_CACHE))); __GnttabFree(*Cache); fail1: Error("fail1 (%08x)\n", status); return status; }
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { HANDLE ServiceKey; HANDLE ParametersKey; ULONG Index; NTSTATUS status; ASSERT3P(__DriverGetDriverObject(), ==, NULL); ExInitializeDriverRuntime(DrvRtPoolNxOptIn); __EnableDbgPrint(); Trace("====>\n"); __DriverSetDriverObject(DriverObject); if (*InitSafeBootMode > 0) goto done; status = LogInitialize(); if (!NT_SUCCESS(status)) goto fail1; Info("%s (%s)\n", MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR, DAY_STR "/" MONTH_STR "/" YEAR_STR); SystemGetInformation(); status = HypercallInitialize(&Driver.HypercallInterface); if (!NT_SUCCESS(status)) goto fail2; status = ModuleInitialize(); if (!NT_SUCCESS(status)) goto fail3; status = ProcessInitialize(); if (!NT_SUCCESS(status)) goto fail4; status = RegistryInitialize(RegistryPath); if (!NT_SUCCESS(status)) goto fail5; status = RegistryOpenServiceKey(KEY_READ, &ServiceKey); if (!NT_SUCCESS(status)) goto fail6; status = RegistryOpenSubKey(ServiceKey, "Parameters", KEY_READ, &ParametersKey); if (NT_SUCCESS(status)) __DriverSetParametersKey(ParametersKey); RegistryCloseKey(ServiceKey); Driver.DriverObject->DriverUnload = DriverUnload; Driver.DriverObject->DriverExtension->AddDevice = AddDevice; for (Index = 0; Index <= IRP_MJ_MAXIMUM_FUNCTION; Index++) { #pragma prefast(suppress:28169) // No __drv_dispatchType annotation #pragma prefast(suppress:28168) // No matching __drv_dispatchType annotation for IRP_MJ_CREATE Driver.DriverObject->MajorFunction[Index] = Dispatch; } done: Trace("<====\n"); return STATUS_SUCCESS; fail6: Error("fail6\n"); RegistryTeardown(); fail5: Error("fail5\n"); ProcessTeardown(); fail4: Error("fail4\n"); ModuleTeardown(); fail3: Error("fail3\n"); HypercallTeardown(&Driver.HypercallInterface); fail2: Error("fail2\n"); LogTeardown(); fail1: Error("fail1 (%08x)\n", status); __DriverSetDriverObject(NULL); ASSERT(IsZeroMemory(&Driver, sizeof (XEN_DRIVER))); return status; }
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { HANDLE ServiceKey; HANDLE ParametersKey; HANDLE UnplugKey; ULONG Index; NTSTATUS status; ASSERT3P(__DriverGetDriverObject(), ==, NULL); ExInitializeDriverRuntime(DrvRtPoolNxOptIn); __DbgPrintEnable(); Trace("====>\n"); __DriverSetDriverObject(DriverObject); DriverObject->DriverUnload = DriverUnload; if (*InitSafeBootMode > 0) goto done; XenTouch(); Info("XENFILT %d.%d.%d (%d) (%02d.%02d.%04d)\n", MAJOR_VERSION, MINOR_VERSION, MICRO_VERSION, BUILD_NUMBER, DAY, MONTH, YEAR); status = RegistryInitialize(RegistryPath); if (!NT_SUCCESS(status)) goto fail1; status = RegistryOpenServiceKey(KEY_READ, &ServiceKey); if (!NT_SUCCESS(status)) goto fail2; status = RegistryOpenSubKey(ServiceKey, "Parameters", KEY_READ, &ParametersKey); if (NT_SUCCESS(status)) __DriverSetParametersKey(ParametersKey); status = RegistryOpenSubKey(ServiceKey, "Unplug", KEY_READ, &UnplugKey); if (!NT_SUCCESS(status)) goto fail3; __DriverSetUnplugKey(UnplugKey); RegistryCloseKey(ServiceKey); DriverObject->DriverExtension->AddDevice = AddDevice; for (Index = 0; Index <= IRP_MJ_MAXIMUM_FUNCTION; Index++) { #pragma prefast(suppress:28169) // No __drv_dispatchType annotation #pragma prefast(suppress:28168) // No matching __drv_dispatchType annotation for IRP_MJ_CREATE DriverObject->MajorFunction[Index] = Dispatch; } done: Trace("<====\n"); return STATUS_SUCCESS; fail3: Error("fail3\n"); if (ParametersKey != NULL) { RegistryCloseKey(ParametersKey); __DriverSetParametersKey(NULL); } fail2: Error("fail2\n"); RegistryTeardown(); fail1: Error("fail1 (%08x)\n", status); __DriverSetDriverObject(NULL); ASSERT(IsZeroMemory(&Driver, sizeof (XENFILT_DRIVER))); return status; }
static NTSTATUS GnttabCreateCache( IN PXENBUS_GNTTAB_CONTEXT Context, IN const CHAR *Name, IN ULONG Reservation, IN VOID (*AcquireLock)(PVOID), IN VOID (*ReleaseLock)(PVOID), IN PVOID Argument, OUT PXENBUS_GNTTAB_CACHE *Cache ) { NTSTATUS status; *Cache = __GnttabAllocate(sizeof (XENBUS_GNTTAB_CACHE)); status = STATUS_NO_MEMORY; if (*Cache == NULL) goto fail1; (*Cache)->Context = Context; status = RtlStringCbPrintfA((*Cache)->Name, sizeof ((*Cache)->Name), "%s_gnttab", Name); if (!NT_SUCCESS(status)) goto fail2; (*Cache)->AcquireLock = AcquireLock; (*Cache)->ReleaseLock = ReleaseLock; (*Cache)->Argument = Argument; status = CACHE(Create, Context->CacheInterface, (*Cache)->Name, sizeof (XENBUS_GNTTAB_DESCRIPTOR), Reservation, GnttabDescriptorCtor, GnttabDescriptorDtor, GnttabAcquireLock, GnttabReleaseLock, *Cache, &(*Cache)->Cache); if (!NT_SUCCESS(status)) goto fail3; return STATUS_SUCCESS; fail3: Error("fail3\n"); (*Cache)->Argument = NULL; (*Cache)->ReleaseLock = NULL; (*Cache)->AcquireLock = NULL; RtlZeroMemory((*Cache)->Name, sizeof ((*Cache)->Name)); fail2: Error("fail2\n"); (*Cache)->Context = NULL; ASSERT(IsZeroMemory(*Cache, sizeof (XENBUS_GNTTAB_CACHE))); __GnttabFree(*Cache); fail1: Error("fail1 (%08x)\n", status); return status; }
NTSTATUS PdoCreate( PXENFILT_FDO Fdo, PDEVICE_OBJECT PhysicalDeviceObject, XENFILT_EMULATED_OBJECT_TYPE Type ) { PDEVICE_OBJECT LowerDeviceObject; ULONG DeviceType; PDEVICE_OBJECT FilterDeviceObject; PXENFILT_DX Dx; PXENFILT_PDO Pdo; NTSTATUS status; LowerDeviceObject = IoGetAttachedDeviceReference(PhysicalDeviceObject); DeviceType = LowerDeviceObject->DeviceType; ObDereferenceObject(LowerDeviceObject); #pragma prefast(suppress:28197) // Possibly leaking memory 'PhysicalDeviceObject' status = IoCreateDevice(DriverGetDriverObject(), sizeof(XENFILT_DX), NULL, DeviceType, FILE_DEVICE_SECURE_OPEN, FALSE, &FilterDeviceObject); if (!NT_SUCCESS(status)) goto fail1; Dx = (PXENFILT_DX)FilterDeviceObject->DeviceExtension; RtlZeroMemory(Dx, sizeof (XENFILT_DX)); Dx->Type = PHYSICAL_DEVICE_OBJECT; Dx->DeviceObject = FilterDeviceObject; Dx->DevicePnpState = Present; Dx->SystemPowerState = PowerSystemShutdown; Dx->DevicePowerState = PowerDeviceD3; IoInitializeRemoveLock(&Dx->RemoveLock, PDO_TAG, 0, 0); Pdo = __PdoAllocate(sizeof (XENFILT_PDO)); status = STATUS_NO_MEMORY; if (Pdo == NULL) goto fail2; LowerDeviceObject = IoAttachDeviceToDeviceStack(FilterDeviceObject, PhysicalDeviceObject); status = STATUS_UNSUCCESSFUL; if (LowerDeviceObject == NULL) goto fail3; Pdo->Dx = Dx; Pdo->PhysicalDeviceObject = PhysicalDeviceObject; Pdo->LowerDeviceObject = LowerDeviceObject; status = ThreadCreate(PdoSystemPower, Pdo, &Pdo->SystemPowerThread); if (!NT_SUCCESS(status)) goto fail4; status = ThreadCreate(PdoDevicePower, Pdo, &Pdo->DevicePowerThread); if (!NT_SUCCESS(status)) goto fail5; Pdo->EmulatedInterface = FdoGetEmulatedInterface(Fdo); status = EmulatedAddObject(__PdoGetEmulatedInterface(Pdo), Type, FdoGetPrefix(Fdo), Pdo->LowerDeviceObject, &Pdo->EmulatedObject); if (!NT_SUCCESS(status)) goto fail6; __PdoSetName(Pdo); Info("%p (%s)\n", FilterDeviceObject, __PdoGetName(Pdo)); Dx->Pdo = Pdo; #pragma prefast(suppress:28182) // Dereferencing NULL pointer FilterDeviceObject->DeviceType = LowerDeviceObject->DeviceType; FilterDeviceObject->Characteristics = LowerDeviceObject->Characteristics; FilterDeviceObject->Flags |= LowerDeviceObject->Flags; FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; __PdoLink(Pdo, Fdo); return STATUS_SUCCESS; fail6: Error("fail6\n"); ThreadAlert(Pdo->DevicePowerThread); ThreadJoin(Pdo->DevicePowerThread); Pdo->DevicePowerThread = NULL; fail5: Error("fail5\n"); ThreadAlert(Pdo->SystemPowerThread); ThreadJoin(Pdo->SystemPowerThread); Pdo->SystemPowerThread = NULL; fail4: Error("fail4\n"); Pdo->PhysicalDeviceObject = NULL; Pdo->LowerDeviceObject = NULL; Pdo->Dx = NULL; IoDetachDevice(LowerDeviceObject); fail3: Error("fail3\n"); ASSERT(IsZeroMemory(Pdo, sizeof (XENFILT_PDO))); __PdoFree(Pdo); fail2: Error("fail2\n"); IoDeleteDevice(FilterDeviceObject); fail1: Error("fail1 (%08x)\n", status); return status; }