_Must_inspect_result_ NTSTATUS FxIoTargetRemote::_Create( __in PFX_DRIVER_GLOBALS FxDriverGlobals, __in PWDF_OBJECT_ATTRIBUTES Attributes, __in CfxDeviceBase* Device, __out FxIoTargetRemote** Target ) { FxIoTargetRemote* pTarget; FxObject* pParent; WDFOBJECT hTarget; NTSTATUS status; *Target = NULL; if (Attributes == NULL || Attributes->ParentObject == NULL) { pParent = Device; } else { CfxDeviceBase* pSearchDevice; FxObjectHandleGetPtr(FxDriverGlobals, Attributes->ParentObject, FX_TYPE_OBJECT, (PVOID*) &pParent); pSearchDevice = FxDeviceBase::_SearchForDevice(pParent, NULL); if (pSearchDevice == NULL) { status = STATUS_INVALID_DEVICE_REQUEST; DoTraceLevelMessage( FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, "Attributes->ParentObject 0x%p must have WDFDEVICE as an " "eventual ancestor, %!STATUS!", Attributes->ParentObject, status); return status; } else if (pSearchDevice != Device) { status = STATUS_INVALID_DEVICE_REQUEST; DoTraceLevelMessage( FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, "Attributes->ParentObject 0x%p ancestor is WDFDEVICE %p, but " "not the same WDFDEVICE 0x%p passed to WdfIoTargetCreate, " "%!STATUS!", Attributes->ParentObject, pSearchDevice->GetHandle(), Device->GetHandle(), status); return status; } } pTarget = new (FxDriverGlobals, Attributes) FxIoTargetRemote(FxDriverGlobals); if (pTarget == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; DoTraceLevelMessage( FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, "Could not allocate memory for target, %!STATUS!", status); return status; } // // initialize the new target // status = pTarget->InitRemote(Device); if (!NT_SUCCESS(status)) { return status; } // // Commit and apply the attributes // status = pTarget->Commit(Attributes, &hTarget, pParent); if (NT_SUCCESS(status)) { *Target = pTarget; } else { // // This will properly clean up the target's state and free it // DoTraceLevelMessage( FxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIOTARGET, "Commit failed for target, %!STATUS!", status); pTarget->DeleteFromFailedCreate(); } return status; }
_Must_inspect_result_ NTSTATUS FxPkgIo::CreateQueue( __in PWDF_IO_QUEUE_CONFIG Config, __in PWDF_OBJECT_ATTRIBUTES QueueAttributes, __in_opt FxDriver* Caller, __deref_out FxIoQueue** ppQueue ) { PFX_DRIVER_GLOBALS pFxDriverGlobals; FxObject* pParent; FxIoQueue* pQueue; NTSTATUS status; FxDriver* pDriver; pParent = NULL; pQueue = NULL; pDriver = NULL; pFxDriverGlobals = GetDriverGlobals(); if (QueueAttributes != NULL && QueueAttributes->ParentObject != NULL) { CfxDeviceBase* pSearchDevice; FxObjectHandleGetPtr(pFxDriverGlobals, QueueAttributes->ParentObject, FX_TYPE_OBJECT, (PVOID*)&pParent); pSearchDevice = FxDeviceBase::_SearchForDevice(pParent, NULL); if (pSearchDevice == NULL) { status = STATUS_INVALID_DEVICE_REQUEST; DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIO, "QueueAttributes->ParentObject 0x%p must have WDFDEVICE as an " "eventual ancestor, %!STATUS!", QueueAttributes->ParentObject, status); return status; } else if (pSearchDevice != m_DeviceBase) { status = STATUS_INVALID_DEVICE_REQUEST; DoTraceLevelMessage( pFxDriverGlobals, TRACE_LEVEL_ERROR, TRACINGIO, "Attributes->ParentObject 0x%p ancestor is WDFDEVICE %p, but " "not the same WDFDEVICE 0x%p passed to WdfIoQueueCreate, " "%!STATUS!", QueueAttributes->ParentObject, pSearchDevice->GetHandle(), m_Device->GetHandle(), status); return status; } } else { // // By default, use the package as the parent // pParent = this; } // // v1.11 and up: get driver object if driver handle is specified. // Client driver can also specify a driver handle, the end result in this case is // a PkgIoContext that is NULL (see below), i.e., the same as if driver handle // was NULL. // if (Config->Size > sizeof(WDF_IO_QUEUE_CONFIG_V1_9) && Config->Driver != NULL) { FxObjectHandleGetPtr(GetDriverGlobals(), Config->Driver, FX_TYPE_DRIVER, (PVOID*)&pDriver); } status = FxIoQueue::_Create(pFxDriverGlobals, QueueAttributes, Config, Caller, this, m_PowerStateOn, &pQueue ); if (!NT_SUCCESS(status)) { ASSERT(pQueue == NULL); return status; } // // Class extension support: associate queue with a specific cx layer. // if (pDriver != NULL) { pQueue->SetCxDeviceInfo(m_Device->GetCxDeviceInfo(pDriver)); } status = pQueue->Commit(QueueAttributes, NULL, pParent); if (!NT_SUCCESS(status)) { pQueue->DeleteFromFailedCreate(); return status; } AddIoQueue(pQueue); *ppQueue = pQueue; return status; }