首页 > 解决方案 > 使用 IOCTL_VIDEO_QUERY_AVAIL_MODES 获取视频适配器支持的模式列表

问题描述

我正在尝试从视频适配器驱动程序中查询支持的模式列表:

// IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES - Retrieve the count of modes on the display adapter
// Input-Buffer: none
// Output-Buffer: VIDEO_NUM_MODES

VIDEO_NUM_MODES videoNumModes{};

// Send the IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES control code directly to the device driver
ULONG bytesReturned{};
if (::DeviceIoControl(
        hDevice,                                // Handle to the display adapter device
        IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES,      // IOCTL code
        nullptr, 0,                             // No input param struct
        &videoNumModes, sizeof videoNumModes,   // Address/size of output param struct
        &bytesReturned,                         // Bytes returned in the output param struct
        nullptr))                               // Optional OVERLAPPED structure
{
    // Allocate a buffer to receive the array of supported modes
    const auto bufferSizeInBytes = videoNumModes.NumModes * videoNumModes.ModeInformationLength;
    pVideoModeInfo = new VIDEO_MODE_INFORMATION[videoNumModes.NumModes];

    // IOCTL_VIDEO_QUERY_AVAIL_MODES - Retrieve the array of supported modes
    // Input-Buffer: none
    // Output-Buffer: <allocated buffer>

    // Send the IOCTL_VIDEO_QUERY_AVAIL_MODES control code directly to the device driver
    if (::DeviceIoControl(
            hDevice,
            IOCTL_VIDEO_QUERY_AVAIL_MODES,
            nullptr, 0,
            pVideoModeInfo, bufferSizeInBytes,
            &bytesReturned,
            nullptr))

FALSE返回第一个DeviceIoControl调用,并将 LastError 设置为ERROR_INVALID_FUNCTION(0x1)。

我成功地使用相同的代码在我的驱动程序中调用自定义 IOCTL 内容,因此我确信实现本身是合理的。但是,当我打开设备的句柄时,我应该使用一个包含有关设备和我将要使用的接口的信息的字符串。我为我的自定义 IOCTL 接口定义了 GUID,并使用类似以下的内容来发送自定义 IOCTL 命令:

hDevice = ::CreateFileW(L"\\\\?\\ROOT#DISPLAY#0000#{5f2f2b485bbd-5201-f1f9-4520-30f4bf353599}", ...);

但是IOCTL_VIDEO_QUERY_NUM_AVAIL_MODESIOCTL_VIDEO_QUERY_AVAIL_MODES的文档没有提到它们属于哪个接口(GUID)。

我假设我必须使用GUID_DEVINTERFACE_DISPLAY_ADAPTER接口打开适配器设备,但是在第一次 DeviceIoControl 调用时我得到了不正确的功能。如果我用 . 打开适配器或其显示器之一,结果相同GUID_DEVINTERFACE_MONITOR

我在网上搜索了任何代码示例,但我发现的都是来自驱动程序方面的查询。

如果有帮助的话,我要针对的显示适配器驱动程序是 IddCx 驱动程序。有什么线索吗?

标签: winapiwdkioctlumdfiddcx

解决方案


推荐阅读