Trying to use IOCTL_VIDEO_QUERY_AVAIL_MODES on my IddCx video adapter driver

I’m trying to query a list of supported modes from my 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 elsewhere to call custom IOCTL stuff in this driver, so I’m confident that the implementation itself is sound. However, when I open a handle to the device, I query Windows for paths to devices that implement my custom interface (whose GUID I defined in my driver). Only one device path comes back, and it looks something like this:

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

(that’s my custom interface GUID tacked on to the end).

So, I expected that issuing a standard video adapter IOCTL command might require opening the device with that, well-known interface. 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 it must be 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 to compare against, but all I find are from the driver side, responding to the query.

From what I’ve read, display drivers are required to support both request, so I must be doing something wrong. Any clues?

Just to be clear, the IOCTL requests (both standard and my custom driver IOCTLs) are being made from client code.

The WDK docs have two entries underneath “Display”: “Windows Display Driver Model (WDDM) Design Guide” and “Windows 2000 Display Driver Model (XDDM) Design Guide”. IOCTL_VIDEO_XXX are documented underneath XDDM chapter “Processing Video Requests”. XDDM is obsolete since Windows Vista.

Marcel Ruedinger
datronicsoft

Wow. Somehow I missed your reply, Marcel. Thanks for the info.

I couldn’t find a solution to this at the time, so I hard-coded the list as a temporary work-around (since we control both the driver and client software). It’s been so long that I don’t recall where I got the info on IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES and IOCTL_VIDEO_QUERY_AVAIL_MODES. Those two are the only control codes that I’m using (everything else was being done via fairly standard Win32 APIs.

I was planning on investigating using IDXGIOutput::GetDisplayModeList or IDXGIOutput1::GetDisplayModeList1 as an alternative, but it seems that they would ultimately end up querying the driver somehow.

Do you have any idea/suggestion as to what might have replaced IOCTL_VIDEO_XXX as the recommended/x method for getting an adapter’s supported resolutions? (I can’t use EnumDisplaySettingsEx, because that requires an actual GDI device)

Cheers,

–Scott

On an unrelated side note, almost 30 years ago I worked with a Scott Smith on the Twin Turbo-128 graphics cards for IMS. Admittedly, yours is a common name, but the graphics card business is not very large. Did you once work for IMS?

The whole IOCTL_VIDEO_xxx set was the fundamental basis for XPDM. That’s how a display driver communicated with its miniport. The miniport was opened exclusively by win32k.sys, so an outside app should never have been able to make these requests at all. That whole mechanism is completely gone in WDDM. There is no miniport. Use the abstractions (like IDXGIOutput); that’s the right way.

Thanks you Tim, that clarifies things tremendously.

Did you once work for IMS?

Not me. If you liked him, it’s possible that he was a distant cousin. On the other hand, if he was a pain in the neck to work with, I’m leaning toward “no relation”. :slight_smile:

The most memorable thing about IMS (later iXMicro) was that they hired Christopher Knight, who played Peter Brady in the Brady Bunch, as VP of Marketing. I met him at their COMDEX booth one year. Interesting what useless information our brains hold on to.

We might not (yet?) be able to solve the mystery of our brains :slight_smile:
However, we can answer the initial question above:
The connecting and configuring display (CCD) APIs

Marcel Ruedinger
datronicsoft