Author: khornicek Date: Mon Oct 20 13:08:42 2014 New Revision: 64845
URL: http://svn.reactos.org/svn/reactos?rev=64845&view=rev Log: [SETUPAPI] - actually use the icon source we get from registry instead of loading all icons from setupapi itself CORE-8614
Modified: trunk/reactos/dll/win32/setupapi/devclass.c
Modified: trunk/reactos/dll/win32/setupapi/devclass.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/setupapi/devclass... ============================================================================== --- trunk/reactos/dll/win32/setupapi/devclass.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/setupapi/devclass.c [iso-8859-1] Mon Oct 20 13:08:42 2014 @@ -22,6 +22,7 @@ #include "setupapi_private.h"
#include <wingdi.h> +#include <shellapi.h>
/* Unicode constants */ static const WCHAR BackSlash[] = {'\',0}; @@ -76,6 +77,7 @@ }; #undef ADD_PARAM_HANDLER
+#define UNKNOWN_ICON_INDEX 18
/*********************************************************************** * SetupDiDestroyClassImageList(SETUPAPI.@) @@ -330,9 +332,6 @@ return rc; }
-/*********************************************************************** - * SetupDiGetClassImageIndex (SETUPAPI.@) - */ static BOOL SETUP_GetIconIndex( IN HKEY hClassKey, @@ -378,6 +377,9 @@ return ret; }
+/*********************************************************************** + * SetupDiGetClassImageIndex (SETUPAPI.@) + */ BOOL WINAPI SetupDiGetClassImageIndex( IN PSP_CLASSIMAGELIST_DATA ClassImageListData, @@ -457,6 +459,102 @@
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 @@ for (i = 0; i < list->NumberOfGuids; i++) { INT miniIconIndex; - - ret = SetupDiLoadClassIcon( - &list->Guids[i], - NULL, - &miniIconIndex); - if (ret) - { - hIcon = LoadImage(hInstance, MAKEINTRESOURCE(miniIconIndex), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR); - if (hIcon) + LPWSTR DllName = NULL; + + if (SETUP_GetClassIconInfo(&list->Guids[i], &miniIconIndex, &DllName)) + { + if (DllName && ExtractIconExW(DllName, -miniIconIndex, NULL, &hIcon, 1) == 1) { list->IconIndexes[i] = ImageList_AddIcon(ClassImageListData->ImageList, 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 @@ 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; - - 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; + HICON hIcon = NULL; + + if (LargeIcon) + { + if(!SETUP_GetClassIconInfo(ClassGuid, &iconIndex, &DllName)) + return FALSE; + + if (DllName && ExtractIconExW(DllName, -iconIndex, &hIcon, NULL, 1) == 1 && hIcon != NULL) + { + 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; - } - - 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; - } - } + /* load the default unknown device icon if ExtractIcon failed */ + if(DllName) + iconIndex = UNKNOWN_ICON_INDEX; + + 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;