_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;
}
示例#2
0
文件: fxpkgio.cpp 项目: AntejaVM/WDF
_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;
}