0

我正在编写一个附加到网络摄像头的 WDF 过滤器驱动程序。我的代码在下面链接,虽然它可以工作(大部分情况下),但我遇到的一个问题是,当我解开网络摄像头时,驱动程序保持运行状态并且永远不会关闭。驱动程序注册表显示计数为 0 并且没有活动的枚举键,所以我知道它不再附加到任何东西,但我不确定它为什么不会卸载。有什么帮助吗?

NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
{
    WDF_DRIVER_CONFIG Config;
    WDF_DRIVER_CONFIG_INIT(&Config, WebcamFilterEvtDeviceAdd);
    NTSTATUS Status = WdfDriverCreate(pDriverObject, pRegistryPath, WDF_NO_OBJECT_ATTRIBUTES, &Config, WDF_NO_HANDLE);
    if (!NT_SUCCESS(Status)) {
        // TODO: Error handling
    }
    return Status;
}

NTSTATUS WebcamFilterEvtDeviceAdd(IN WDFDRIVER Driver, IN OUT PWDFDEVICE_INIT DeviceInit)
{
    UNREFERENCED_PARAMETER(Driver);

    WDF_OBJECT_ATTRIBUTES ObjectAttributes;
    WDF_OBJECT_ATTRIBUTES_INIT(&ObjectAttributes);
    WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(&ObjectAttributes, WebcamFilter_DEVICE_CONTEXT);

    WdfFdoInitSetFilter(DeviceInit);

    WDFDEVICE Device = NULL;
    NTSTATUS Status = WdfDeviceCreate(&DeviceInit, &ObjectAttributes, &Device);
    if (!NT_SUCCESS(Status)) {
        return Status;
    }

    PWebcamFilter_DEVICE_CONTEXT DeviceContext = GetContextFromWebcamFilterDevice(Device);
    DeviceContext->TargetToSendRequestsTo = WdfDeviceGetIoTarget(Device);

    WDF_IO_QUEUE_CONFIG IoCallbacks;
    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&IoCallbacks, WdfIoQueueDispatchParallel);
    IoCallbacks.PowerManaged = WdfFalse;
    IoCallbacks.EvtIoRead = WebcamFilterEvtIoRead;
    IoCallbacks.EvtIoWrite = WebcamFilterEvtIoWrite;
    IoCallbacks.EvtIoDeviceControl = WebcamFilterEvtIoDeviceControl;
    IoCallbacks.EvtIoDefault = WebcamFilterEvtIoDefault;
    Status = WdfIoQueueCreate(Device, &IoCallbacks, WDF_NO_OBJECT_ATTRIBUTES, WDF_NO_HANDLE);
    if (!NT_SUCCESS(Status)) {
        return Status;
    }

    if (InterlockedIncrement(&WebcamFilterFilterDeviceCount) == 1) {
        Status = CreateControlDevice(Driver);
        if (!NT_SUCCESS(Status)) {
            return Status;
        }
    }

    WDF_IO_QUEUE_CONFIG NotificationCallbacks;
    WDF_IO_QUEUE_CONFIG_INIT(&NotificationCallbacks, WdfIoQueueDispatchManual);
    NotificationCallbacks.PowerManaged = WdfFalse;
    Status = WdfIoQueueCreate(Device, &NotificationCallbacks, WDF_NO_OBJECT_ATTRIBUTES, &DeviceContext->NotificationQueue);
    if (!NT_SUCCESS(Status)) {
        return Status;
    }

    return STATUS_SUCCESS;
}

NTSTATUS CreateControlDevice(IN WDFDRIVER Driver)
{
    if (ControlDeviceExists) {
        return STATUS_SUCCESS;
    }

    PWDFDEVICE_INIT DeviceInit = WdfControlDeviceInitAllocate(Driver, &SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RWX_RES_RWX);
    if (!DeviceInit) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    WdfDeviceInitSetExclusive(DeviceInit, TRUE);

    DECLARE_CONST_UNICODE_STRING(NTDeviceName, L"\\Device\\WebcamFilter");
    NTSTATUS Status = WdfDeviceInitAssignName(DeviceInit, &NTDeviceName);
    if (!NT_SUCCESS(Status)) {
        return Status;
    }

    WDF_FILEOBJECT_CONFIG FileObjectConfig;
    WDF_FILEOBJECT_CONFIG_INIT(&FileObjectConfig, WebcamFilterControlCreate, WebcamFilterControlClose, WDF_NO_EVENT_CALLBACK);
    WdfDeviceInitSetFileObjectConfig(DeviceInit, &FileObjectConfig, NULL);

    Status = WdfDeviceCreate(&DeviceInit, WDF_NO_OBJECT_ATTRIBUTES, &WebcamFilterControlDevice);
    if (!NT_SUCCESS(Status)) {
        return Status;
    }

    DECLARE_CONST_UNICODE_STRING(DosDeviceName, L"\\DosDevices\\WebcamFilter");
    Status = WdfDeviceCreateSymbolicLink(WebcamFilterControlDevice, &DosDeviceName);
    if (!NT_SUCCESS(Status)) {
        return Status;
    }

    WDF_IO_QUEUE_CONFIG IoCallbacks;
    WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&IoCallbacks, WdfIoQueueDispatchSequential);
    IoCallbacks.EvtIoDeviceControl = WebcamFilterControlEvtIoDeviceControl;
    Status = WdfIoQueueCreate(WebcamFilterControlDevice, &IoCallbacks, WDF_NO_OBJECT_ATTRIBUTES, WDF_NO_HANDLE);
    if (!NT_SUCCESS(Status)) {
        return Status;
    }   

    WdfControlFinishInitializing(WebcamFilterControlDevice);
    return STATUS_SUCCESS;
}

VOID WebcamFilterEvtIoRead(IN WDFQUEUE Queue, IN WDFREQUEST Request, IN size_t Length)
{
    UNREFERENCED_PARAMETER(Queue);
    WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, Length);
    return;
}

VOID WebcamFilterEvtIoWrite(IN WDFQUEUE Queue, IN WDFREQUEST Request, IN size_t Length)
{
    UNREFERENCED_PARAMETER(Queue);
    WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, Length);
    return;
}

VOID WebcamFilterEvtIoDeviceControl(IN WDFQUEUE Queue, IN WDFREQUEST Request, IN size_t OutputBufferLength, IN size_t InputBufferLength, IN ULONG IoControlCode)
{
    UNREFERENCED_PARAMETER(OutputBufferLength);
    UNREFERENCED_PARAMETER(InputBufferLength);
    UNREFERENCED_PARAMETER(IoControlCode);
    WdfRequestComplete(Request, STATUS_SUCCESS);
    return;
}

VOID WebcamFilterControlCreate(IN WDFDEVICE Device, IN WDFREQUEST Request, IN WDFFILEOBJECT FileObject)
{
    UNREFERENCED_PARAMETER(Device);
    UNREFERENCED_PARAMETER(Request);
    UNREFERENCED_PARAMETER(FileObject);
    ControlDeviceExists = TRUE;
    WdfRequestComplete(Request, STATUS_SUCCESS);
    return;
}

VOID WebcamFilterControlClose(IN WDFFILEOBJECT FileObject)
{
    UNREFERENCED_PARAMETER(FileObject);
    ControlDeviceExists = FALSE;
    return;
}

VOID WebcamFilterControlEvtIoDeviceControl(IN WDFQUEUE Queue, IN WDFREQUEST Request, IN size_t OutputBufferLength, IN size_t InputBufferLength, IN ULONG IoControlCode)
{
    UNREFERENCED_PARAMETER(InputBufferLength);
    PWebcamFilter_DEVICE_CONTEXT DeviceContext = GetContextFromWebcamFilterDevice(WdfIoQueueGetDevice(Queue));
    switch (IoControlCode) {
        default:
            WdfRequestComplete(Request, STATUS_INVALID_DEVICE_REQUEST);
            break;
    }

    return;
}
4

0 回答 0