I need help in associating PHYSICAL_MONITOR which i get from GetPhysicalMonitorsFromHMONITOR with monitors DISPLAY_DEVICE.DeviceID (e.g. "\?\DISPLAY#GSM59AB#5&932a802&1&UID261#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}"), which is from EnumDisplayDevices used with flag EDD_GET_DEVICE_INTERFACE_NAME, or somehow get PHYSICAL_MONITOR from DISPLAY_DEVICE.DeviceID or vice versa.
I need both of them associated because:
HANDLE PHYSICAL_MONITOR.hPhysicalMonitor will be used for lowlevelmonitorconfigurationapi because i need to send commands to monitors.
DISPLAY_DEVICE.DeviceID is used to get EDID structure from registry (first 128 bytes are enough for me , need only manufacturer code and model) using SetupAPI
1 and 2 are done, the problem is associating id with physical monitor. Also it is possible to get all monitors EDIDs from registry using only SetupAPI, but in this case it is impossible to get physical monitors HANDLEs.
Same question on MSDN, not solved((
Also i noticed one thing: This code enumerates all monitors:
DWORD DispNum = 0;
DISPLAY_DEVICE DisplayDevice;
// Initialize DisplayDevice.
ZeroMemory(&DisplayDevice, sizeof(DisplayDevice));
DisplayDevice.cb = sizeof(DisplayDevice);
while ((EnumDisplayDevices(NULL, DispNum, &DisplayDevice, 0)))
{
std::wstring deviceName = DisplayDevice.DeviceName;
DISPLAY_DEVICE DisplayDeviceM;
ZeroMemory(&DisplayDeviceM, sizeof(DisplayDeviceM));
DisplayDeviceM.cb = sizeof(DisplayDeviceM);
int monitorIndex = 0;
while (EnumDisplayDevices(deviceName.c_str(), monitorIndex, &DisplayDeviceM, EDD_GET_DEVICE_INTERFACE_NAME))
{
std::wstring monitorID = DisplayDeviceM.DeviceID;
++monitorIndex;
}
DispNum++;
}
In the same order as this one:
BOOL CALLBACK EnumProc2(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
{
LPPHYSICAL_MONITOR pMons = NULL;
DWORD i, mcnt;
MONITORINFOEX mi;
ZeroMemory(&mi, sizeof(mi));
mi.cbSize = sizeof(mi);
GetMonitorInfo(hMonitor, &mi);
DISPLAY_DEVICE dd;
ZeroMemory(&dd, sizeof(dd));
dd.cb = sizeof(dd);
EnumDisplayDevices(mi.szDevice, 0, &dd, EDD_GET_DEVICE_INTERFACE_NAME);
monitorModelMnufac MdlManuf = findMonitorModelManufactFromEDID(dd.DeviceID);
if (!GetNumberOfPhysicalMonitorsFromHMONITOR(hMonitor, &mcnt)) return TRUE;
pMons = (LPPHYSICAL_MONITOR)malloc(mcnt * sizeof(PHYSICAL_MONITOR));
if (GetPhysicalMonitorsFromHMONITOR(hMonitor, mcnt, pMons))
for (i = 0; i < mcnt; i++)
{
AddToMonHandles(pMons[i].hPhysicalMonitor, MdlManuf);
}
free(pMons);
return TRUE;
}
And physical monitors HANDLEs are 0,1,2 and so on, so i can make HANDLEs from "monitorIndex" but i'm not sure if doing like that is secure.
I also looked in registry to find physical monitors HANDLEs, but nothing there.
Also found function which is helpful VideoPortDDCMonitorHelper but as i googled, it need to be used in driver/filter and can't be used from a simple executable.
Also tried to reverse windows dlls, all calls seems to be made from WIN32U.dll and Ghidra doesn't want to decompile it, or i'm just noob at that.
Please help me guys :)
EnumDisplayDevicesshows the adapters andEnumDisplayMonitorsshows the monitors. I have checked their parameters and found no key similarities between them, except for the display name, but this does not guarantee uniqueness. And I used them to enumerate the monitors separately, and the result shows that their order is the same. This can only be used as a reference. - Strive SunEnumDisplayDevicesandEnumDisplayMonitorsare two unrelated APIs. As I said in the first comment, one is the corresponding adapter and the other is the corresponding monitor. Simply, theDeviceIdis allocated by the graphics card, andPHYSICAL_MONITORis allocated by the monitor. Can you tell me what you want to do with SetupAPI and what kind of work you want to accomplish in the end? - Strive Sun