Using IOCTL_VIDEO_QUERY_AVAIL_MODES to get a list of modes supported by a video adapter

166 Views Asked by At

I'm trying to query a list of supported modes from a video adapter driver:

// 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))

I get FALSE back on the first DeviceIoControl call with LastError set to ERROR_INVALID_FUNCTION (0x1).

I use this same code successfully to call custom IOCTL stuff in my drivers, so I'm confident that the implementation itself is sound. However, when I open a handle to the device, I'm supposed to use a string containing information about both the device and the interface I'm going to use. I defined the GUID for my custom IOCTL interface, and I use something like the following to send custom IOCTL commands:

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

But the documentation for IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES and IOCTL_VIDEO_QUERY_AVAIL_MODES doesn't mention which interface (GUID) they're a part of.

I assumed that I had to open the adapter device with the GUID_DEVINTERFACE_DISPLAY_ADAPTER interface, but I'm getting Incorrect Function on the first DeviceIoControl call. Same result if I open the adapter or one of its monitors with GUID_DEVINTERFACE_MONITOR.

I've searched online for any code examples, but all I find are from the driver side, responding to the query.

The display adapter driver that I'm issuing this against is an IddCx driver, if that helps. Any clues?

0

There are 0 best solutions below