https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3900cf88b3ad8fa1b53785bc2f69a5f07b9bdd22
commit 3900cf88b3ad8fa1b53785bc2f69a5f07b9bdd22 Author: Stanislav Motylkov <x86co...@gmail.com> AuthorDate: Mon May 23 19:04:47 2022 +0300 Commit: Stanislav Motylkov <x86co...@gmail.com> CommitDate: Mon May 23 19:04:47 2022 +0300 [DESK] Implement pCDevSettings_GetDeviceInstanceId properly - CM_Locate_DevNodeW expects a Device Instance ID as second argument, so it cannot be used for converting a Hardware ID. - Use SetupAPI functions here instead, as documented in: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-enumdisplaydevicesw - Now our desk.cpl passes correct identifier to CPL extensions, such as deskadp and deskmon, so clicking on "Properties" in the advanced display properties now works in Windows XP. - Also fix copypasta in DisplayAdvancedSettings that affected applet built with MSVC - deskadp extension was loaded twice. - Also fix magic flag value for EDD_GET_DEVICE_INTERFACE_NAME. --- dll/cpl/desk/advmon.c | 2 +- dll/cpl/desk/devsett.c | 81 ++++++++++++++++++++++++++++++------------------- dll/cpl/desk/settings.c | 2 +- 3 files changed, 51 insertions(+), 34 deletions(-) diff --git a/dll/cpl/desk/advmon.c b/dll/cpl/desk/advmon.c index 141f6ffe479..e933072316e 100644 --- a/dll/cpl/desk/advmon.c +++ b/dll/cpl/desk/advmon.c @@ -122,7 +122,7 @@ DisplayAdvancedSettings(HWND hWndParent, PDISPLAY_DEVICE_ENTRY DisplayDevice) SHAddFromPropSheetExtArray(hpsxaDev, PropSheetAddPage, (LPARAM)&psh); #ifdef _MSC_VER - hpsxaDisp = msvc_SHCreatePropSheetExtArrayEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_CONTROLSFOLDER TEXT("\\Device"), MAX_ADVANCED_PAGES - psh.nPages, pdo); + hpsxaDisp = msvc_SHCreatePropSheetExtArrayEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_CONTROLSFOLDER TEXT("\\Display"), MAX_ADVANCED_PAGES - psh.nPages, pdo); #else hpsxaDisp = SHCreatePropSheetExtArrayEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_CONTROLSFOLDER TEXT("\\Display"), MAX_ADVANCED_PAGES - psh.nPages, pdo); #endif diff --git a/dll/cpl/desk/devsett.c b/dll/cpl/desk/devsett.c index 73dbb78a62f..27e75d6d349 100644 --- a/dll/cpl/desk/devsett.c +++ b/dll/cpl/desk/devsett.c @@ -168,47 +168,64 @@ pCDevSettings_GetMonitorDevice(const WCHAR *pszDisplayDevice) return str; } +/** + * @brief + * Converts a Hardware ID (DeviceID from EnumDisplayDevices) + * to an unique Device Instance ID. + * + * @param[in] pszDevice + * A pointer to a null-terminated Unicode string + * containing a Hardware ID. + * e.g. "PCI\VEN_80EE&DEV_BEEF&SUBSYS_00000000&REV_00" + * + * @return + * A pointer to a null-terminated Unicode string + * containing an unique Device Instance ID + * or NULL in case of error. + * e.g. "PCI\VEN_80EE&DEV_BEEF&SUBSYS_00000000&REV_00\3&267A616A&0&10" + * + * @remarks + * The caller must free the returned string with LocalFree. + */ static PWSTR pCDevSettings_GetDeviceInstanceId(const WCHAR *pszDevice) { - DEVINST DevInst; - CONFIGRET cr; + HDEVINFO DevInfo; + SP_DEVINFO_DATA InfoData; ULONG BufLen; LPWSTR lpDevInstId = NULL; - DPRINT1("CDevSettings::GetDeviceInstanceId(%ws) UNIMPLEMENTED!\n", pszDevice); + DPRINT("CDevSettings::GetDeviceInstanceId(%ws)!\n", pszDevice); - cr = CM_Locate_DevNodeW(&DevInst, - (DEVINSTID_W)pszDevice, - CM_LOCATE_DEVNODE_NORMAL); - if (cr == CR_SUCCESS) - { - DPRINT1("Success1\n"); - cr = CM_Get_Device_ID_Size(&BufLen, - DevInst, - 0); - if (cr == CR_SUCCESS) - { - DPRINT1("Success2\n"); - lpDevInstId = LocalAlloc(LMEM_FIXED, - (BufLen + 1) * sizeof(WCHAR)); + DevInfo = SetupDiGetClassDevsW(NULL, pszDevice, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT); + if (DevInfo == INVALID_HANDLE_VALUE) + return NULL; - if (lpDevInstId != NULL) - { - DPRINT1("Success3\n"); - cr = CM_Get_Device_IDW(DevInst, - lpDevInstId, - BufLen, - 0); + ZeroMemory(&InfoData, sizeof(InfoData)); + InfoData.cbSize = sizeof(InfoData); - if (cr != CR_SUCCESS) - { - LocalFree((HLOCAL)lpDevInstId); - lpDevInstId = NULL; - } - DPRINT1("instance id: %ws\n", lpDevInstId); - } - } + /* Try to enumerate the first matching device */ + if (!SetupDiEnumDeviceInfo(DevInfo, 0, &InfoData)) + return NULL; + + if (SetupDiGetDeviceInstanceId(DevInfo, &InfoData, NULL, 0, &BufLen) || + GetLastError() != ERROR_INSUFFICIENT_BUFFER) + return NULL; + + lpDevInstId = LocalAlloc(LMEM_FIXED, + (BufLen + 1) * sizeof(WCHAR)); + + if (lpDevInstId == NULL) + return NULL; + + if (!SetupDiGetDeviceInstanceId(DevInfo, &InfoData, lpDevInstId, BufLen, NULL)) + { + LocalFree((HLOCAL)lpDevInstId); + lpDevInstId = NULL; + } + else + { + DPRINT("instance id: %ws\n", lpDevInstId); } return lpDevInstId; diff --git a/dll/cpl/desk/settings.c b/dll/cpl/desk/settings.c index 93d8b9a246f..d0b8d12a06b 100644 --- a/dll/cpl/desk/settings.c +++ b/dll/cpl/desk/settings.c @@ -330,7 +330,7 @@ SettingsOnInitDialog(IN HWND hwndDlg) /* Get video cards list */ pData->DisplayDeviceList = NULL; displayDevice.cb = sizeof(displayDevice); - while (EnumDisplayDevices(NULL, iDevNum, &displayDevice, 0x1)) + while (EnumDisplayDevices(NULL, iDevNum, &displayDevice, EDD_GET_DEVICE_INTERFACE_NAME)) { if ((displayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) != 0) {