NTSTATUS FilterAddDevice( __in PDRIVER_OBJECT DriverObject, __in PDEVICE_OBJECT PhysicalDeviceObject ) /*++ Routine Description: The Plug & Play subsystem is handing us a brand new PDO, for which we (by means of INF registration) have been asked to provide a driver. We need to determine if we need to be in the driver stack for the device. Create a function device object to attach to the stack Initialize that device object Return status success. Remember: We can NOT actually send ANY non pnp IRPS to the given driver stack, UNTIL we have received an IRP_MN_START_DEVICE. Arguments: DeviceObject - pointer to a device object. PhysicalDeviceObject - pointer to a device object created by the underlying bus driver. Return Value: NT status code. --*/ { NTSTATUS status = STATUS_SUCCESS; PDEVICE_OBJECT deviceObject = NULL; PDEVICE_EXTENSION deviceExtension; ULONG deviceType = FILE_DEVICE_UNKNOWN; PAGED_CODE (); // // IoIsWdmVersionAvailable(1, 0x20) returns TRUE on os after Windows 2000. // if (RtlIsNtDdiVersionAvailable(NTDDI_WINXP)) { // // Win2K system bugchecks if the filter attached to a storage device // doesn't specify the same DeviceType as the device it's attaching // to. This bugcheck happens in the filesystem when you disable // the devicestack whose top level deviceobject doesn't have a VPB. // To workaround we will get the toplevel object's DeviceType and // specify that in IoCreateDevice. // deviceObject = IoGetAttachedDeviceReference(PhysicalDeviceObject); deviceType = deviceObject->DeviceType; ObDereferenceObject(deviceObject); } // // Create a filter device object. // status = IoCreateDevice (DriverObject, sizeof (DEVICE_EXTENSION), NULL, // No Name deviceType, FILE_DEVICE_SECURE_OPEN, FALSE, &deviceObject); if (!NT_SUCCESS (status)) { // // Returning failure here prevents the entire stack from functioning, // but most likely the rest of the stack will not be able to create // device objects either, so it is still OK. // return status; } DebugPrint (("AddDevice PDO (0x%p) FDO (0x%p)\n", PhysicalDeviceObject, deviceObject)); deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension; deviceExtension->Common.Type = DEVICE_TYPE_FIDO; deviceExtension->NextLowerDriver = IoAttachDeviceToDeviceStack ( deviceObject, PhysicalDeviceObject); // // Failure for attachment is an indication of a broken plug & play system. // if (NULL == deviceExtension->NextLowerDriver) { IoDeleteDevice(deviceObject); return STATUS_UNSUCCESSFUL; } deviceObject->Flags |= deviceExtension->NextLowerDriver->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE ); deviceObject->DeviceType = deviceExtension->NextLowerDriver->DeviceType; deviceObject->Characteristics = deviceExtension->NextLowerDriver->Characteristics; deviceExtension->Self = deviceObject; // // Let us use remove lock to keep count of IRPs so that we don't // deteach and delete our deviceobject until all pending I/Os in our // devstack are completed. Remlock is required to protect us from // various race conditions where our driver can get unloaded while we // are still running dispatch or completion code. // IoInitializeRemoveLock (&deviceExtension->RemoveLock , POOL_TAG, 1, // MaxLockedMinutes 100); // HighWatermark, this parameter is // used only on checked build. Specifies // the maximum number of outstanding // acquisitions allowed on the lock // // Set the initial state of the Filter DO // INITIALIZE_PNP_STATE(deviceExtension); DebugPrint(("AddDevice: %p to %p->%p \n", deviceObject, deviceExtension->NextLowerDriver, PhysicalDeviceObject)); deviceObject->Flags &= ~DO_DEVICE_INITIALIZING; return STATUS_SUCCESS; }
NTSTATUS NTAPI PopSetSystemPowerState(SYSTEM_POWER_STATE PowerState, POWER_ACTION PowerAction) { PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT Fdo; NTSTATUS Status; DEVICETREE_TRAVERSE_CONTEXT Context; POWER_STATE_TRAVERSE_CONTEXT PowerContext; Status = IopGetSystemPowerDeviceObject(&DeviceObject); if (!NT_SUCCESS(Status)) { DPRINT1("No system power driver available\n"); Fdo = NULL; } else { Fdo = IoGetAttachedDeviceReference(DeviceObject); if (Fdo == DeviceObject) { DPRINT("An FDO was not attached\n"); return STATUS_UNSUCCESSFUL; } } /* Set up context */ PowerContext.PowerAction = PowerAction; PowerContext.SystemPowerState = PowerState; PowerContext.PowerDevice = Fdo; /* Query for system power change */ IopInitDeviceTreeTraverseContext(&Context, IopRootDeviceNode, PopQuerySystemPowerStateTraverse, &PowerContext); Status = IopTraverseDeviceTree(&Context); if (!NT_SUCCESS(Status)) { DPRINT1("Query system power state failed; changing state anyway\n"); } /* Set system power change */ IopInitDeviceTreeTraverseContext(&Context, IopRootDeviceNode, PopSetSystemPowerStateTraverse, &PowerContext); IopTraverseDeviceTree(&Context); if (!PopAcpiPresent) return STATUS_NOT_IMPLEMENTED; if (Fdo != NULL) { if (PowerAction != PowerActionShutdownReset) PopSendSetSystemPowerState(Fdo, PowerState, PowerAction); ObDereferenceObject(Fdo); } return Status; }
/* * @implemented */ VOID IssueUniqueIdChangeNotify(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName, IN PMOUNTDEV_UNIQUE_ID UniqueId) { NTSTATUS Status; PVOID IrpBuffer = NULL; PFILE_OBJECT FileObject; PDEVICE_OBJECT DeviceObject; PUNIQUE_ID_WORK_ITEM WorkItem = NULL; /* Get the associated device object */ Status = IoGetDeviceObjectPointer(DeviceName, FILE_READ_ATTRIBUTES, &FileObject, &DeviceObject); if (!NT_SUCCESS(Status)) { return; } /* And then, get attached device */ DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject); ObDereferenceObject(FileObject); /* Allocate a work item */ WorkItem = AllocatePool(sizeof(UNIQUE_ID_WORK_ITEM)); if (!WorkItem) { ObDereferenceObject(DeviceObject); return; } WorkItem->Event = NULL; WorkItem->WorkItem = IoAllocateWorkItem(DeviceExtension->DeviceObject); if (!WorkItem->WorkItem) { ObDereferenceObject(DeviceObject); goto Cleanup; } WorkItem->DeviceExtension = DeviceExtension; WorkItem->StackSize = DeviceObject->StackSize; /* Already provide the IRP */ WorkItem->Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); ObDereferenceObject(DeviceObject); if (!WorkItem->Irp) { goto Cleanup; } /* Ensure it has enough space */ IrpBuffer = AllocatePool(sizeof(MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT) + 1024); if (!IrpBuffer) { goto Cleanup; } WorkItem->DeviceName.Length = DeviceName->Length; WorkItem->DeviceName.MaximumLength = DeviceName->Length + sizeof(WCHAR); WorkItem->DeviceName.Buffer = AllocatePool(WorkItem->DeviceName.MaximumLength); if (!WorkItem->DeviceName.Buffer) { goto Cleanup; } RtlCopyMemory(WorkItem->DeviceName.Buffer, DeviceName->Buffer, DeviceName->Length); WorkItem->DeviceName.Buffer[DeviceName->Length / sizeof(WCHAR)] = UNICODE_NULL; WorkItem->IrpBuffer = IrpBuffer; WorkItem->IrpBufferLength = sizeof(MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY_OUTPUT) + 1024; /* Add the worker in the list */ KeWaitForSingleObject(&(DeviceExtension->DeviceLock), Executive, KernelMode, FALSE, NULL); InsertHeadList(&(DeviceExtension->UniqueIdWorkerItemListHead), &(WorkItem->UniqueIdWorkerItemListEntry)); KeReleaseSemaphore(&(DeviceExtension->DeviceLock), IO_NO_INCREMENT, 1, FALSE); /* And call the worker */ IssueUniqueIdChangeNotifyWorker(WorkItem, UniqueId); return; Cleanup: if (IrpBuffer) { FreePool(IrpBuffer); } if (WorkItem->Irp) { IoFreeIrp(WorkItem->Irp); } if (WorkItem->WorkItem) { IoFreeWorkItem(WorkItem->WorkItem); } if (WorkItem) { FreePool(WorkItem); } }
NTSTATUS Bus_GetDeviceCapabilities( __in PDEVICE_OBJECT DeviceObject, __in PDEVICE_CAPABILITIES DeviceCapabilities ) /*++ Routine Description: This routine sends the get capabilities irp to the given stack Arguments: DeviceObject A device object in the stack whose capabilities we want DeviceCapabilites Where to store the answer Return Value: NTSTATUS --*/ { IO_STATUS_BLOCK ioStatus; KEVENT pnpEvent; NTSTATUS status; PDEVICE_OBJECT targetObject; PIO_STACK_LOCATION irpStack; PIRP pnpIrp; PAGED_CODE(); // // Initialize the capabilities that we will send down // RtlZeroMemory( DeviceCapabilities, sizeof(DEVICE_CAPABILITIES) ); DeviceCapabilities->Size = sizeof(DEVICE_CAPABILITIES); DeviceCapabilities->Version = 1; DeviceCapabilities->Address = -1; DeviceCapabilities->UINumber = -1; // // Initialize the event // KeInitializeEvent( &pnpEvent, NotificationEvent, FALSE ); targetObject = IoGetAttachedDeviceReference( DeviceObject ); // // Build an Irp // pnpIrp = IoBuildSynchronousFsdRequest( IRP_MJ_PNP, targetObject, NULL, 0, NULL, &pnpEvent, &ioStatus ); if (pnpIrp == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; goto GetDeviceCapabilitiesExit; } // // Pnp Irps all begin life as STATUS_NOT_SUPPORTED; // pnpIrp->IoStatus.Status = STATUS_NOT_SUPPORTED; // // Get the top of stack // irpStack = IoGetNextIrpStackLocation( pnpIrp ); // // Set the top of stack // RtlZeroMemory( irpStack, sizeof(IO_STACK_LOCATION ) ); irpStack->MajorFunction = IRP_MJ_PNP; irpStack->MinorFunction = IRP_MN_QUERY_CAPABILITIES; irpStack->Parameters.DeviceCapabilities.Capabilities = DeviceCapabilities; // // Call the driver // status = IoCallDriver( targetObject, pnpIrp ); if (status == STATUS_PENDING) { // // Block until the irp comes back. // Important thing to note here is when you allocate // the memory for an event in the stack you must do a // KernelMode wait instead of UserMode to prevent // the stack from getting paged out. // KeWaitForSingleObject( &pnpEvent, Executive, KernelMode, FALSE, NULL ); status = ioStatus.Status; } GetDeviceCapabilitiesExit: // // Done with reference // ObDereferenceObject( targetObject ); // // Done // return status; }
/* * @implemented */ VOID IssueUniqueIdChangeNotifyWorker(IN PUNIQUE_ID_WORK_ITEM WorkItem, IN PMOUNTDEV_UNIQUE_ID UniqueId) { PIRP Irp; NTSTATUS Status; PFILE_OBJECT FileObject; PIO_STACK_LOCATION Stack; PDEVICE_OBJECT DeviceObject; /* Get the device object */ Status = IoGetDeviceObjectPointer(&(WorkItem->DeviceName), FILE_READ_ATTRIBUTES, &FileObject, &DeviceObject); if (!NT_SUCCESS(Status)) { RemoveWorkItem(WorkItem); return; } /* And then, the attached device */ DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject); /* Initialize the IRP */ Irp = WorkItem->Irp; IoInitializeIrp(Irp, IoSizeOfIrp(WorkItem->StackSize), (CCHAR)WorkItem->StackSize); if (InterlockedExchange((PLONG)&(WorkItem->Event), 0) != 0) { ObDereferenceObject(FileObject); ObDereferenceObject(DeviceObject); RemoveWorkItem(WorkItem); return; } Irp->AssociatedIrp.SystemBuffer = WorkItem->IrpBuffer; Irp->Tail.Overlay.Thread = PsGetCurrentThread(); RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, UniqueId, UniqueId->UniqueIdLength + sizeof(USHORT)); Stack = IoGetNextIrpStackLocation(Irp); Stack->Parameters.DeviceIoControl.InputBufferLength = UniqueId->UniqueIdLength + sizeof(USHORT); Stack->Parameters.DeviceIoControl.OutputBufferLength = WorkItem->IrpBufferLength; Stack->Parameters.DeviceIoControl.Type3InputBuffer = 0; Stack->Parameters.DeviceIoControl.IoControlCode = IOCTL_MOUNTDEV_UNIQUE_ID_CHANGE_NOTIFY; Stack->MajorFunction = IRP_MJ_DEVICE_CONTROL; Status = IoSetCompletionRoutineEx(WorkItem->DeviceExtension->DeviceObject, Irp, UniqueIdChangeNotifyCompletion, WorkItem, TRUE, TRUE, TRUE); if (!NT_SUCCESS(Status)) { ObDereferenceObject(FileObject); ObDereferenceObject(DeviceObject); RemoveWorkItem(WorkItem); return; } /* Call the driver */ IoCallDriver(DeviceObject, Irp); ObDereferenceObject(FileObject); ObDereferenceObject(DeviceObject); }
/* * @implemented */ VOID MountMgrNotifyNameChange(IN PDEVICE_EXTENSION DeviceExtension, IN PUNICODE_STRING DeviceName, IN BOOLEAN ValidateVolume) { PIRP Irp; KEVENT Event; NTSTATUS Status; PLIST_ENTRY NextEntry; PFILE_OBJECT FileObject; PIO_STACK_LOCATION Stack; PDEVICE_OBJECT DeviceObject; IO_STATUS_BLOCK IoStatusBlock; PDEVICE_RELATIONS DeviceRelations; PDEVICE_INFORMATION DeviceInformation; TARGET_DEVICE_CUSTOM_NOTIFICATION DeviceNotification; /* If we have to validate volume */ if (ValidateVolume) { /* Then, ensure we can find the device */ NextEntry = DeviceExtension->DeviceListHead.Flink; while (NextEntry != &(DeviceExtension->DeviceListHead)) { DeviceInformation = CONTAINING_RECORD(NextEntry, DEVICE_INFORMATION, DeviceListEntry); if (RtlCompareUnicodeString(DeviceName, &(DeviceInformation->DeviceName), TRUE) == 0) { break; } } /* No need to notify for a PnP device or if we didn't find the device */ if (NextEntry == &(DeviceExtension->DeviceListHead) || !DeviceInformation->ManuallyRegistered) { return; } } /* Then, get device object */ Status = IoGetDeviceObjectPointer(DeviceName, FILE_READ_ATTRIBUTES, &FileObject, &DeviceObject); if (!NT_SUCCESS(Status)) { return; } DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject); KeInitializeEvent(&Event, NotificationEvent, FALSE); /* Set up empty IRP (yes, yes!) */ Irp = IoBuildDeviceIoControlRequest(0, DeviceObject, NULL, 0, NULL, 0, FALSE, &Event, &IoStatusBlock); if (!Irp) { ObDereferenceObject(DeviceObject); ObDereferenceObject(FileObject); return; } Stack = IoGetNextIrpStackLocation(Irp); Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; Irp->IoStatus.Information = 0; /* Properly set it, we want to query device relations */ Stack->MajorFunction = IRP_MJ_PNP; Stack->MinorFunction = IRP_MN_QUERY_DEVICE_RELATIONS; Stack->Parameters.QueryDeviceRelations.Type = TargetDeviceRelation; Stack->FileObject = FileObject; /* And call driver */ Status = IoCallDriver(DeviceObject, Irp); if (Status == STATUS_PENDING) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); Status = IoStatusBlock.Status; } ObDereferenceObject(DeviceObject); ObDereferenceObject(FileObject); if (!NT_SUCCESS(Status)) { return; } /* Validate device return */ DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information; if (DeviceRelations->Count < 1) { ExFreePool(DeviceRelations); return; } DeviceObject = DeviceRelations->Objects[0]; ExFreePool(DeviceRelations); /* Set up real notification */ DeviceNotification.Version = 1; DeviceNotification.Size = sizeof(TARGET_DEVICE_CUSTOM_NOTIFICATION); DeviceNotification.Event = GUID_IO_VOLUME_NAME_CHANGE; DeviceNotification.FileObject = NULL; DeviceNotification.NameBufferOffset = -1; /* And report */ IoReportTargetDeviceChangeAsynchronous(DeviceObject, &DeviceNotification, NULL, NULL); ObDereferenceObject(DeviceObject); return; }
static FORCEINLINE NTSTATUS __DriverQueryId( IN PDEVICE_OBJECT PhysicalDeviceObject, IN BUS_QUERY_ID_TYPE IdType, OUT PVOID *Information ) { PDEVICE_OBJECT DeviceObject; PIRP Irp; KEVENT Event; PIO_STACK_LOCATION StackLocation; NTSTATUS status; ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL); DeviceObject = IoGetAttachedDeviceReference(PhysicalDeviceObject); Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); status = STATUS_INSUFFICIENT_RESOURCES; if (Irp == NULL) goto fail1; StackLocation = IoGetNextIrpStackLocation(Irp); StackLocation->MajorFunction = IRP_MJ_PNP; StackLocation->MinorFunction = IRP_MN_QUERY_ID; StackLocation->Flags = 0; StackLocation->Parameters.QueryId.IdType = IdType; StackLocation->DeviceObject = DeviceObject; StackLocation->FileObject = NULL; KeInitializeEvent(&Event, NotificationEvent, FALSE); IoSetCompletionRoutine(Irp, DriverQueryIdCompletion, &Event, TRUE, TRUE, TRUE); // Default completion status Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; status = IoCallDriver(DeviceObject, Irp); if (status == STATUS_PENDING) { (VOID) KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); status = Irp->IoStatus.Status; } else { ASSERT3U(status, ==, Irp->IoStatus.Status); } if (!NT_SUCCESS(status)) goto fail2; *Information = (PVOID)Irp->IoStatus.Information; IoFreeIrp(Irp); ObDereferenceObject(DeviceObject); return STATUS_SUCCESS; fail2: Error("fail2\n"); IoFreeIrp(Irp); fail1: Error("fail1 (%08x)\n", status); ObDereferenceObject(DeviceObject); return status; }
NTSTATUS NTAPI PciQueryForPciBusInterface(IN PPCI_FDO_EXTENSION FdoExtension) { PDEVICE_OBJECT AttachedDevice; IO_STATUS_BLOCK IoStatusBlock; KEVENT Event; NTSTATUS Status; PIRP Irp; PIO_STACK_LOCATION IoStackLocation; PPCI_BUS_INTERFACE_STANDARD PciInterface; PAGED_CODE(); ASSERT(PCI_IS_ROOT_FDO(FdoExtension)); /* Allocate space for the inteface */ PciInterface = ExAllocatePoolWithTag(NonPagedPool, sizeof(PCI_BUS_INTERFACE_STANDARD), PCI_POOL_TAG); if (!PciInterface) return STATUS_INSUFFICIENT_RESOURCES; /* Get the device the PDO is attached to, should be the Root (ACPI) */ AttachedDevice = IoGetAttachedDeviceReference(FdoExtension->PhysicalDeviceObject); /* Build an IRP for this request */ KeInitializeEvent(&Event, SynchronizationEvent, FALSE); Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, AttachedDevice, NULL, 0, NULL, &Event, &IoStatusBlock); if (Irp) { /* Initialize the default PnP response */ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; Irp->IoStatus.Information = 0; /* Make it a Query Interface IRP */ IoStackLocation = IoGetNextIrpStackLocation(Irp); ASSERT(IoStackLocation->MajorFunction == IRP_MJ_PNP); IoStackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE; IoStackLocation->Parameters.QueryInterface.InterfaceType = &GUID_PCI_BUS_INTERFACE_STANDARD; IoStackLocation->Parameters.QueryInterface.Size = sizeof(GUID_PCI_BUS_INTERFACE_STANDARD); IoStackLocation->Parameters.QueryInterface.Version = PCI_BUS_INTERFACE_STANDARD_VERSION; IoStackLocation->Parameters.QueryInterface.Interface = (PINTERFACE)PciInterface; IoStackLocation->Parameters.QueryInterface.InterfaceSpecificData = NULL; /* Send it to the root PDO */ Status = IoCallDriver(AttachedDevice, Irp); if (Status == STATUS_PENDING) { /* Wait for completion */ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); Status = Irp->IoStatus.Status; } /* Check if an interface was returned */ if (!NT_SUCCESS(Status)) { /* No interface was returned by the root PDO */ FdoExtension->PciBusInterface = NULL; ExFreePoolWithTag(PciInterface, 0); } else { /* An interface was returned, save it */ FdoExtension->PciBusInterface = PciInterface; } /* Dereference the device object because we took a reference earlier */ ObfDereferenceObject(AttachedDevice); } else { /* Failure path, dereference the device object and set failure code */ if (AttachedDevice) ObfDereferenceObject(AttachedDevice); ExFreePoolWithTag(PciInterface, 0); Status = STATUS_INSUFFICIENT_RESOURCES; } /* Return status code to caller */ return Status; }
VOID FxPkgPnp::QueryForD3ColdInterface( VOID ) { MxDeviceObject deviceObject; PDEVICE_OBJECT topOfStack; PDEVICE_OBJECT pdo; FxAutoIrp irp; NTSTATUS status; // // This function can be invoked multiple times, particularly if filters // send IRP_MN_QUERY_CAPABILITIES. So bail out if the interface has already // been acquired. // if ((m_D3ColdInterface.InterfaceDereference != NULL) || (m_D3ColdInterface.GetIdleWakeInfo != NULL) || (m_D3ColdInterface.SetD3ColdSupport != NULL)) { return; } pdo = m_Device->GetPhysicalDevice(); if (pdo == NULL) { return; } // // Get the top of stack device object, even though normal filters and the // FDO may not have been added to the stack yet to ensure that this // query-interface is seen by bus filters. Specifically, in a PCI device // which is soldered to the motherboard, ACPI will be on the stack and it // needs to see this IRP. // topOfStack = IoGetAttachedDeviceReference(pdo); deviceObject.SetObject(topOfStack); if (deviceObject.GetObject() != NULL) { irp.SetIrp(FxIrp::AllocateIrp(deviceObject.GetStackSize())); if (irp.GetIrp() == NULL) { DoTraceLevelMessage( GetDriverGlobals(), TRACE_LEVEL_ERROR, TRACINGPNP, "Failed to allocate IRP to get D3COLD_SUPPORT_INTERFACE from !devobj %p", pdo); } else { // // Initialize the Irp // irp.SetStatus(STATUS_NOT_SUPPORTED); irp.ClearNextStack(); irp.SetMajorFunction(IRP_MJ_PNP); irp.SetMinorFunction(IRP_MN_QUERY_INTERFACE); irp.SetParameterQueryInterfaceType(&GUID_D3COLD_SUPPORT_INTERFACE); irp.SetParameterQueryInterfaceVersion(D3COLD_SUPPORT_INTERFACE_VERSION); irp.SetParameterQueryInterfaceSize(sizeof(m_D3ColdInterface)); irp.SetParameterQueryInterfaceInterfaceSpecificData(NULL); irp.SetParameterQueryInterfaceInterface((PINTERFACE)&m_D3ColdInterface); status = irp.SendIrpSynchronously(deviceObject.GetObject()); if (!NT_SUCCESS(status)) { DoTraceLevelMessage( GetDriverGlobals(), TRACE_LEVEL_VERBOSE, TRACINGPNP, "!devobj %p declined to supply D3COLD_SUPPORT_INTERFACE", pdo); RtlZeroMemory(&m_D3ColdInterface, sizeof(m_D3ColdInterface)); } } } ObDereferenceObject(topOfStack); }