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?