From 6beb0e5668ec8b9e45a3640b8bd1c66111722b1b Mon Sep 17 00:00:00 2001 From: Kamil Hornicek Date: Mon, 20 Oct 2014 13:08:42 +0000 Subject: [PATCH] [SETUPAPI] - actually use the icon source we get from registry instead of loading all icons from setupapi itself CORE-8614 svn path=/trunk/; revision=64845 --- reactos/dll/win32/setupapi/devclass.c | 230 +++++++++++++++----------- 1 file changed, 137 insertions(+), 93 deletions(-) diff --git a/reactos/dll/win32/setupapi/devclass.c b/reactos/dll/win32/setupapi/devclass.c index 60c92fe8fc1..cae8b660735 100644 --- a/reactos/dll/win32/setupapi/devclass.c +++ b/reactos/dll/win32/setupapi/devclass.c @@ -22,6 +22,7 @@ #include "setupapi_private.h" #include +#include /* Unicode constants */ static const WCHAR BackSlash[] = {'\\',0}; @@ -76,6 +77,7 @@ static const INSTALL_PARAMS_DATA InstallParamsData[] = { }; #undef ADD_PARAM_HANDLER +#define UNKNOWN_ICON_INDEX 18 /*********************************************************************** * SetupDiDestroyClassImageList(SETUPAPI.@) @@ -330,9 +332,6 @@ cleanup: return rc; } -/*********************************************************************** - * SetupDiGetClassImageIndex (SETUPAPI.@) - */ static BOOL SETUP_GetIconIndex( IN HKEY hClassKey, @@ -378,6 +377,9 @@ cleanup: return ret; } +/*********************************************************************** + * SetupDiGetClassImageIndex (SETUPAPI.@) + */ BOOL WINAPI SetupDiGetClassImageIndex( IN PSP_CLASSIMAGELIST_DATA ClassImageListData, @@ -458,6 +460,102 @@ SetupDiGetClassImageListExA( return ret; } +static BOOL WINAPI +SETUP_GetClassIconInfo(IN CONST GUID *ClassGuid, OUT PINT OutIndex, OUT LPWSTR *OutDllName) +{ + LPWSTR Buffer = NULL; + INT iconIndex = -UNKNOWN_ICON_INDEX; + HKEY hKey = INVALID_HANDLE_VALUE; + BOOL ret = FALSE; + + if (ClassGuid) + { + hKey = SetupDiOpenClassRegKey(ClassGuid, KEY_QUERY_VALUE); + if (hKey != INVALID_HANDLE_VALUE) + { + SETUP_GetIconIndex(hKey, &iconIndex); + } + } + + if (iconIndex > 0) + { + /* Look up icon in dll specified by Installer32 or EnumPropPages32 key */ + PWCHAR Comma; + LONG rc; + DWORD dwRegType, dwLength; + rc = RegQueryValueExW(hKey, REGSTR_VAL_INSTALLER_32, NULL, &dwRegType, NULL, &dwLength); + if (rc == ERROR_SUCCESS && dwRegType == REG_SZ) + { + Buffer = MyMalloc(dwLength + sizeof(WCHAR)); + if (Buffer == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto cleanup; + } + rc = RegQueryValueExW(hKey, REGSTR_VAL_INSTALLER_32, NULL, NULL, (LPBYTE)Buffer, &dwLength); + if (rc != ERROR_SUCCESS) + { + SetLastError(rc); + goto cleanup; + } + /* make sure the returned buffer is NULL-terminated */ + Buffer[dwLength / sizeof(WCHAR)] = 0; + } + else if + (ERROR_SUCCESS == (rc = RegQueryValueExW(hKey, REGSTR_VAL_ENUMPROPPAGES_32, NULL, &dwRegType, NULL, &dwLength)) + && dwRegType == REG_SZ) + { + Buffer = MyMalloc(dwLength + sizeof(WCHAR)); + if (Buffer == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto cleanup; + } + rc = RegQueryValueExW(hKey, REGSTR_VAL_ENUMPROPPAGES_32, NULL, NULL, (LPBYTE)Buffer, &dwLength); + if (rc != ERROR_SUCCESS) + { + SetLastError(rc); + goto cleanup; + } + /* make sure the returned buffer is NULL-terminated */ + Buffer[dwLength / sizeof(WCHAR)] = 0; + } + else + { + /* Unable to find where to load the icon */ + SetLastError(ERROR_FILE_NOT_FOUND); + goto cleanup; + } + Comma = strchrW(Buffer, ','); + if (!Comma) + { + SetLastError(ERROR_GEN_FAILURE); + goto cleanup; + } + *Comma = '\0'; + *OutDllName = Buffer; + } + else + { + /* Look up icon in setupapi.dll */ + iconIndex = -iconIndex; + *OutDllName = NULL; + } + + *OutIndex = iconIndex; + ret = TRUE; + + TRACE("Icon index %d, dll name %s\n", iconIndex, debugstr_w(*OutDllName ? *OutDllName : SetupapiDll)); + +cleanup: + + if (hKey != INVALID_HANDLE_VALUE) + RegCloseKey(hKey); + + return ret; +} + + /*********************************************************************** * SetupDiGetClassImageListExW(SETUPAPI.@) */ @@ -570,24 +668,32 @@ SetupDiGetClassImageListExW( for (i = 0; i < list->NumberOfGuids; i++) { INT miniIconIndex; + LPWSTR DllName = NULL; - ret = SetupDiLoadClassIcon( - &list->Guids[i], - NULL, - &miniIconIndex); - if (ret) + if (SETUP_GetClassIconInfo(&list->Guids[i], &miniIconIndex, &DllName)) { - hIcon = LoadImage(hInstance, MAKEINTRESOURCE(miniIconIndex), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); - if (hIcon) + if (DllName && ExtractIconExW(DllName, -miniIconIndex, NULL, &hIcon, 1) == 1) { list->IconIndexes[i] = ImageList_AddIcon(ClassImageListData->ImageList, hIcon); - DestroyIcon(hIcon); } + else if(!DllName) + { + hIcon = LoadImage(hInstance, MAKEINTRESOURCE(miniIconIndex), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); + list->IconIndexes[i] = ImageList_AddIcon(ClassImageListData->ImageList, hIcon); + } + + if(hIcon) + DestroyIcon(hIcon); else list->IconIndexes[i] = -1; + + if(DllName) + MyFree(DllName); } else + { list->IconIndexes[i] = -1; /* Special value to indicate that the icon is unavailable */ + } } /* Finally, add the overlay icons to the image list */ @@ -660,105 +766,43 @@ SetupDiLoadClassIcon( OUT HICON *LargeIcon OPTIONAL, OUT PINT MiniIconIndex OPTIONAL) { - LPWSTR Buffer = NULL; - LPCWSTR DllName; - INT iconIndex = -18; - HKEY hKey = INVALID_HANDLE_VALUE; - + INT iconIndex = 0; + LPWSTR DllName = NULL; BOOL ret = FALSE; + HICON hIcon = NULL; - if (ClassGuid) + if (LargeIcon) { - hKey = SetupDiOpenClassRegKey(ClassGuid, KEY_QUERY_VALUE); - if (hKey != INVALID_HANDLE_VALUE) - SETUP_GetIconIndex(hKey, &iconIndex); - } + if(!SETUP_GetClassIconInfo(ClassGuid, &iconIndex, &DllName)) + return FALSE; - if (iconIndex > 0) - { - /* Look up icon in dll specified by Installer32 or EnumPropPages32 key */ - PWCHAR Comma; - LONG rc; - DWORD dwRegType, dwLength; - rc = RegQueryValueExW(hKey, REGSTR_VAL_INSTALLER_32, NULL, &dwRegType, NULL, &dwLength); - if (rc == ERROR_SUCCESS && dwRegType == REG_SZ) - { - Buffer = MyMalloc(dwLength + sizeof(WCHAR)); - if (Buffer == NULL) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto cleanup; - } - rc = RegQueryValueExW(hKey, REGSTR_VAL_INSTALLER_32, NULL, NULL, (LPBYTE)Buffer, &dwLength); - if (rc != ERROR_SUCCESS) - { - SetLastError(rc); - goto cleanup; - } - /* make sure the returned buffer is NULL-terminated */ - Buffer[dwLength / sizeof(WCHAR)] = 0; - } - else if - (ERROR_SUCCESS == (rc = RegQueryValueExW(hKey, REGSTR_VAL_ENUMPROPPAGES_32, NULL, &dwRegType, NULL, &dwLength)) - && dwRegType == REG_SZ) + if (DllName && ExtractIconExW(DllName, -iconIndex, &hIcon, NULL, 1) == 1 && hIcon != NULL) { - Buffer = MyMalloc(dwLength + sizeof(WCHAR)); - if (Buffer == NULL) - { - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - goto cleanup; - } - rc = RegQueryValueExW(hKey, REGSTR_VAL_ENUMPROPPAGES_32, NULL, NULL, (LPBYTE)Buffer, &dwLength); - if (rc != ERROR_SUCCESS) - { - SetLastError(rc); - goto cleanup; - } - /* make sure the returned buffer is NULL-terminated */ - Buffer[dwLength / sizeof(WCHAR)] = 0; + ret = TRUE; } else { - /* Unable to find where to load the icon */ - SetLastError(ERROR_FILE_NOT_FOUND); - goto cleanup; - } - Comma = strchrW(Buffer, ','); - if (!Comma) - { - SetLastError(ERROR_GEN_FAILURE); - goto cleanup; - } - *Comma = '\0'; - DllName = Buffer; - } - else - { - /* Look up icon in setupapi.dll */ - DllName = SetupapiDll; - iconIndex = -iconIndex; - } + /* load the default unknown device icon if ExtractIcon failed */ + if(DllName) + iconIndex = UNKNOWN_ICON_INDEX; - TRACE("Icon index %d, dll name %s\n", iconIndex, debugstr_w(DllName)); - if (LargeIcon) - { - *LargeIcon = LoadImage(hInstance, MAKEINTRESOURCE(iconIndex), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR); - if (!*LargeIcon) - { - SetLastError(ERROR_INVALID_INDEX); - goto cleanup; + hIcon = LoadImage(hInstance, MAKEINTRESOURCE(iconIndex), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR); + + if(!LargeIcon) + goto cleanup; } } + if (MiniIconIndex) *MiniIconIndex = iconIndex; + ret = TRUE; + *LargeIcon = hIcon; cleanup: - if (hKey != INVALID_HANDLE_VALUE) - RegCloseKey(hKey); - if (Buffer != NULL) - MyFree(Buffer); + if(DllName) + MyFree(DllName); TRACE("Returning %d\n", ret); return ret; -- 2.17.1