From 72a9a3af12dc1de9e9d8d0b1e833fa3b5bc639c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Poussineau?= Date: Sun, 1 Oct 2006 09:05:19 +0000 Subject: [PATCH] Rewrite SetupDiGetClassImageListExW and SetupDiGetClassImageIndex which were completly wrong Add stub for SetupDiDestroyClassImageList Now, you can see some icons in device manager svn path=/trunk/; revision=24338 --- reactos/dll/win32/setupapi/devclass.c | 135 ++++++++++++++---- reactos/dll/win32/setupapi/setupapi.rbuild | 1 + reactos/dll/win32/setupapi/setupapi_private.h | 15 +- reactos/dll/win32/setupapi/stubs.c | 12 -- 4 files changed, 114 insertions(+), 49 deletions(-) diff --git a/reactos/dll/win32/setupapi/devclass.c b/reactos/dll/win32/setupapi/devclass.c index f289e394323..e29bbc075d1 100644 --- a/reactos/dll/win32/setupapi/devclass.c +++ b/reactos/dll/win32/setupapi/devclass.c @@ -669,6 +669,38 @@ cleanup: return ret; } +/*********************************************************************** + * SetupDiDestroyClassImageList(SETUPAPI.@) + */ +BOOL WINAPI +SetupDiDestroyClassImageList( + IN PSP_CLASSIMAGELIST_DATA ClassImageListData) +{ + struct ClassImageList *list; + BOOL ret = FALSE; + + TRACE("%p\n", ClassImageListData); + + if (!ClassImageListData) + SetLastError(ERROR_INVALID_PARAMETER); + else if (ClassImageListData->cbSize != sizeof(SP_CLASSIMAGELIST_DATA)) + SetLastError(ERROR_INVALID_USER_BUFFER); + else if ((list = (struct ClassImageList *)ClassImageListData->Reserved) == NULL) + SetLastError(ERROR_INVALID_USER_BUFFER); + else if (list->magic != SETUP_CLASS_IMAGE_LIST_MAGIC) + SetLastError(ERROR_INVALID_USER_BUFFER); + else + { + //DestroyIcon() + //ImageList_Destroy(); + FIXME("Stub %p\n", ClassImageListData); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + } + + TRACE("Returning %d\n", ret); + return ret; +} + /*********************************************************************** * SetupDiGetClassDescriptionA (SETUPAPI.@) */ @@ -1302,28 +1334,21 @@ SetupDiGetClassImageIndex( SetLastError(ERROR_INVALID_PARAMETER); else { - HKEY hKey = INVALID_HANDLE_VALUE; - INT iconIndex; + DWORD i; - /* Read Icon registry entry into Buffer */ - hKey = SetupDiOpenClassRegKeyExW(ClassGuid, KEY_QUERY_VALUE, DIOCR_INTERFACE, list->MachineName, NULL); - if (hKey == INVALID_HANDLE_VALUE) - goto cleanup; - if (!SETUP_GetIconIndex(hKey, &iconIndex)) - goto cleanup; - - if (iconIndex >= 0) + for (i = 0; i < list->NumberOfGuids; i++) { - SetLastError(ERROR_INVALID_INDEX); - goto cleanup; + if (IsEqualIID(ClassGuid, &list->Guids[i])) + break; } - *ImageIndex = -iconIndex; - ret = TRUE; - -cleanup: - if (hKey != INVALID_HANDLE_VALUE) - RegCloseKey(hKey); + if (i == list->NumberOfGuids || list->IconIndexes[i] < 0) + SetLastError(ERROR_FILE_NOT_FOUND); + else + { + *ImageIndex = list->IconIndexes[i]; + ret = TRUE; + } } TRACE("Returning %d\n", ret); @@ -1388,11 +1413,24 @@ SetupDiGetClassImageListExW( else { struct ClassImageList *list = NULL; + DWORD RequiredSize; + HICON hIcon; DWORD size; + INT i; - size = FIELD_OFFSET(struct ClassImageList, szData); - if (MachineName) - size += (strlenW(MachineName) + 3) * sizeof(WCHAR); + /* Get list of all class GUIDs in given computer */ + ret = SetupDiBuildClassInfoListExW( + 0, + NULL, + 0, + &RequiredSize, + MachineName, + NULL); + if (!ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER) + goto cleanup; + + size = sizeof(struct ClassImageList) + + (sizeof(GUID) + sizeof(INT)) * RequiredSize; list = HeapAlloc(GetProcessHeap(), 0, size); if (!list) { @@ -1400,23 +1438,60 @@ SetupDiGetClassImageListExW( goto cleanup; } list->magic = SETUP_CLASS_IMAGE_LIST_MAGIC; - if (MachineName) + list->NumberOfGuids = RequiredSize; + list->Guids = (GUID*)(list + 1); + list->IconIndexes = (INT*)((ULONG_PTR)(list + 1) + sizeof(GUID) * RequiredSize); + + ret = SetupDiBuildClassInfoListExW( + 0, + list->Guids, + list->NumberOfGuids, + &RequiredSize, + MachineName, + NULL); + if (!ret) + goto cleanup; + else if (RequiredSize != list->NumberOfGuids) { - list->szData[0] = list->szData[1] = '\\'; - strcpyW(list->szData + 2, MachineName); - list->MachineName = list->szData; - } - else - { - list->MachineName = NULL; + /* Hm. Class list changed since last call. Ignore + * this case as it should be very rare */ + SetLastError(ERROR_GEN_FAILURE); + ret = FALSE; + goto cleanup; } + /* Prepare a HIMAGELIST */ + InitCommonControls(); + ClassImageListData->ImageList = ImageList_Create(16, 16, ILC_COLOR, 100, 10); + if (!ClassImageListData->ImageList) + goto cleanup; + ClassImageListData->Reserved = (ULONG_PTR)list; + + /* Now, we "simply" need to load icons associated with all class guids, + * and put their index in the image list in the IconIndexes array */ + for (i = 0; i < list->NumberOfGuids; i++) + { + ret = SetupDiLoadClassIcon( + &list->Guids[i], + &hIcon, + NULL); + if (ret) + list->IconIndexes[i] = ImageList_AddIcon(ClassImageListData->ImageList, hIcon); + else + list->IconIndexes[i] = -1; /* Special value to tell that icon is unavailable */ + } + ret = TRUE; cleanup: if (!ret) - MyFree(list); + { + if (ClassImageListData->Reserved) + SetupDiDestroyClassImageList(ClassImageListData); + else if (list) + MyFree(list); + } } TRACE("Returning %d\n", ret); diff --git a/reactos/dll/win32/setupapi/setupapi.rbuild b/reactos/dll/win32/setupapi/setupapi.rbuild index 0c81f9a3a4c..f0310051cb6 100644 --- a/reactos/dll/win32/setupapi/setupapi.rbuild +++ b/reactos/dll/win32/setupapi/setupapi.rbuild @@ -17,6 +17,7 @@ uuid wine ntdll + comctl32 kernel32 advapi32 user32 diff --git a/reactos/dll/win32/setupapi/setupapi_private.h b/reactos/dll/win32/setupapi/setupapi_private.h index 26290498bbb..2022aa376c9 100644 --- a/reactos/dll/win32/setupapi/setupapi_private.h +++ b/reactos/dll/win32/setupapi/setupapi_private.h @@ -201,13 +201,14 @@ struct ClassImageList { DWORD magic; /* SETUP_CLASS_IMAGE_LIST_MAGIC */ - /* Contains the name of the remote computer ('\\COMPUTERNAME' for example), - * or NULL if related to local machine. Points into szData field at the - * end of the structure */ - PCWSTR MachineName; - - /* Variable size array (contains data for MachineName) */ - WCHAR szData[ANYSIZE_ARRAY]; + /* Number of GUIDs contained in Guids and IconIndexes arrays */ + DWORD NumberOfGuids; + /* Array of GUIDs associated to icons of the image list. Its size + * is NumberOfGuids and is pointing after the end this structure */ + GUID* Guids; + /* Array of corresponding icons index in the image list. Its size + * is NumberOfGuids and is pointing after the end this structure */ + INT* IconIndexes; }; extern HINSTANCE hInstance; diff --git a/reactos/dll/win32/setupapi/stubs.c b/reactos/dll/win32/setupapi/stubs.c index fbc71540eae..d2617fdf747 100644 --- a/reactos/dll/win32/setupapi/stubs.c +++ b/reactos/dll/win32/setupapi/stubs.c @@ -155,18 +155,6 @@ BOOL WINAPI SetupOpenLog(BOOL Reserved) return TRUE; } - -/*********************************************************************** - * SetupDiDestroyClassImageList(SETUPAPI.@) - */ -BOOL WINAPI SetupDiDestroyClassImageList(PSP_CLASSIMAGELIST_DATA ClassImageListData) -{ - FIXME ("Stub %p\n", ClassImageListData); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return TRUE; -} - - /*********************************************************************** * SetupDiRegisterDeviceInfo(SETUPAPI.@) */