From: Hervé Poussineau Date: Sun, 11 Dec 2005 08:11:21 +0000 (+0000) Subject: Implement SetupDiGetClassImageIndex, SetupDiGetClassImageList, SetupDiGetClassImageLi... X-Git-Tag: backups/expat-rbuild@40467~1027 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=f8818e5c0a1c05960ab933f6771319f85651b179 Implement SetupDiGetClassImageIndex, SetupDiGetClassImageList, SetupDiGetClassImageListExA/W, SetupDiLoadClassIcon svn path=/trunk/; revision=20054 --- diff --git a/reactos/lib/setupapi/devinst.c b/reactos/lib/setupapi/devinst.c index 7ce7a69e686..e0ca48f0c93 100644 --- a/reactos/lib/setupapi/devinst.c +++ b/reactos/lib/setupapi/devinst.c @@ -656,7 +656,7 @@ SetupDiCreateDeviceInfoListExW(const GUID *ClassGuid, TRACE("%s %p %s %p\n", debugstr_guid(ClassGuid), hwndParent, debugstr_w(MachineName), Reserved); - size = sizeof(struct DeviceInfoSet); + size = FIELD_OFFSET(struct DeviceInfoSet, szData); if (MachineName) size += (wcslen(MachineName) + 3) * sizeof(WCHAR); list = HeapAlloc(GetProcessHeap(), 0, size); @@ -1145,7 +1145,7 @@ CreateDeviceInfoElement( *pDeviceInfo = NULL; - size = sizeof(struct DeviceInfoElement) + (wcslen(InstancePath) + 1) * sizeof(WCHAR); + size = FIELD_OFFSET(struct DeviceInfoElement, Data) + (wcslen(InstancePath) + 1) * sizeof(WCHAR); deviceInfo = HeapAlloc(GetProcessHeap(), 0, size); if (!deviceInfo) { @@ -1841,6 +1841,303 @@ HDEVINFO WINAPI SetupDiGetClassDevsExW( } } +/*********************************************************************** + * SetupDiGetClassImageIndex (SETUPAPI.@) + */ + +static BOOL GetIconIndex( + IN HKEY hClassKey, + OUT PINT ImageIndex) +{ + LPWSTR Buffer = NULL; + DWORD dwRegType, dwLength; + LONG rc; + BOOL ret = FALSE; + + /* Read "Icon" registry key */ + rc = RegQueryValueExW(hClassKey, L"Icon", NULL, &dwRegType, NULL, &dwLength); + if (rc != ERROR_SUCCESS) + { + SetLastError(rc); + goto cleanup; + } else if (dwRegType != REG_SZ) + { + SetLastError(ERROR_INVALID_INDEX); + goto cleanup; + } + Buffer = MyMalloc(dwLength + sizeof(WCHAR)); + if (!Buffer) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto cleanup; + } + Buffer[dwLength / sizeof(WCHAR)] = 0; + rc = RegQueryValueExW(hClassKey, L"Icon", NULL, NULL, (LPBYTE)Buffer, &dwLength); + if (rc != ERROR_SUCCESS) + { + SetLastError(rc); + goto cleanup; + } + + /* Transform "Icon" value to a INT */ + *ImageIndex = atoiW(Buffer); + ret = TRUE; + +cleanup: + MyFree(Buffer); + return ret; +} + +BOOL WINAPI SetupDiGetClassImageIndex( + IN PSP_CLASSIMAGELIST_DATA ClassImageListData, + IN CONST GUID *ClassGuid, + OUT PINT ImageIndex) +{ + struct ClassImageList *list; + BOOL ret = FALSE; + + TRACE("%p %s %p\n", ClassImageListData, debugstr_guid(ClassGuid), ImageIndex); + + if (!ClassImageListData || !ClassGuid || !ImageIndex) + 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 if (!ImageIndex) + SetLastError(ERROR_INVALID_PARAMETER); + else + { + HKEY hKey = INVALID_HANDLE_VALUE; + INT iconIndex; + + /* 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 (!GetIconIndex(hKey, &iconIndex)) + goto cleanup; + + if (iconIndex >= 0) + { + SetLastError(ERROR_INVALID_INDEX); + goto cleanup; + } + + *ImageIndex = -iconIndex; + ret = TRUE; + +cleanup: + if (hKey != INVALID_HANDLE_VALUE) + RegCloseKey(hKey); + } + + TRACE("Returning %d\n", ret); + return ret; +} + +/*********************************************************************** + * SetupDiGetClassImageList(SETUPAPI.@) + */ +BOOL WINAPI SetupDiGetClassImageList( + OUT PSP_CLASSIMAGELIST_DATA ClassImageListData) +{ + return SetupDiGetClassImageListExW(ClassImageListData, NULL, NULL); +} + +/*********************************************************************** + * SetupDiGetClassImageListExA(SETUPAPI.@) + */ +BOOL WINAPI SetupDiGetClassImageListExA( + OUT PSP_CLASSIMAGELIST_DATA ClassImageListData, + IN PCSTR MachineName OPTIONAL, + IN PVOID Reserved) +{ + PWSTR MachineNameW = NULL; + BOOL ret; + + if (MachineName) + { + MachineNameW = MultiByteToUnicode(MachineName, CP_ACP); + if (MachineNameW == NULL) + return FALSE; + } + + ret = SetupDiGetClassImageListExW(ClassImageListData, MachineNameW, Reserved); + + if (MachineNameW) + MyFree(MachineNameW); + + return ret; +} + +/*********************************************************************** + * SetupDiGetClassImageListExW(SETUPAPI.@) + */ +BOOL WINAPI SetupDiGetClassImageListExW( + OUT PSP_CLASSIMAGELIST_DATA ClassImageListData, + IN PCWSTR MachineName OPTIONAL, + IN PVOID Reserved) +{ + BOOL ret = FALSE; + + TRACE("%p %p %p\n", ClassImageListData, debugstr_w(MachineName), Reserved); + + if (!ClassImageListData) + SetLastError(ERROR_INVALID_PARAMETER); + else if (ClassImageListData->cbSize != sizeof(SP_CLASSIMAGELIST_DATA)) + SetLastError(ERROR_INVALID_USER_BUFFER); + else if (Reserved) + SetLastError(ERROR_INVALID_PARAMETER); + else + { + struct ClassImageList *list = NULL; + DWORD size; + + size = FIELD_OFFSET(struct ClassImageList, szData); + if (MachineName) + size += (wcslen(MachineName) + 3) * sizeof(WCHAR); + list = HeapAlloc(GetProcessHeap(), 0, size); + if (!list) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto cleanup; + } + list->magic = SETUP_CLASS_IMAGE_LIST_MAGIC; + if (MachineName) + { + list->szData[0] = list->szData[1] = '\\'; + strcpyW(list->szData + 2, MachineName); + list->MachineName = list->szData; + } + else + { + list->MachineName = NULL; + } + + ClassImageListData->Reserved = (DWORD)list; /* FIXME: 64 bit portability issue */ + ret = TRUE; + +cleanup: + if (!ret) + MyFree(list); + } + + TRACE("Returning %d\n", ret); + return ret; +} + +/*********************************************************************** + * SetupDiLoadClassIcon(SETUPAPI.@) + */ +BOOL WINAPI SetupDiLoadClassIcon( + IN CONST GUID *ClassGuid, + OUT HICON *LargeIcon OPTIONAL, + OUT PINT MiniIconIndex OPTIONAL) +{ + BOOL ret = FALSE; + + if (!ClassGuid) + SetLastError(ERROR_INVALID_PARAMETER); + else + { + LPWSTR Buffer = NULL; + LPCWSTR DllName; + INT iconIndex; + HKEY hKey = INVALID_HANDLE_VALUE; + + hKey = SetupDiOpenClassRegKey(ClassGuid, KEY_QUERY_VALUE); + if (hKey == INVALID_HANDLE_VALUE) + goto cleanup; + + if (!GetIconIndex(hKey, &iconIndex)) + goto cleanup; + + if (iconIndex > 0) + { + /* Look up icon in dll specified by Installer32 or EnumPropPages32 key */ + PWCHAR Comma; + LONG rc; + DWORD dwRegType, dwLength; + rc = RegQueryValueExW(hKey, L"Installer32", NULL, &dwRegType, NULL, &dwLength); + if (rc == ERROR_SUCCESS && dwRegType == REG_SZ) + { + Buffer = MyMalloc(dwLength); + if (Buffer == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto cleanup; + } + rc = RegQueryValueExW(hKey, L"Installer32", NULL, NULL, (LPBYTE)Buffer, &dwLength); + if (rc != ERROR_SUCCESS) + { + SetLastError(rc); + goto cleanup; + } + } + else if + (ERROR_SUCCESS == (rc = RegQueryValueExW(hKey, L"EnumPropPages32", NULL, &dwRegType, NULL, &dwLength)) + && dwRegType == REG_SZ) + { + Buffer = MyMalloc(dwLength); + if (Buffer == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + goto cleanup; + } + rc = RegQueryValueExW(hKey, L"EnumPropPages32", NULL, NULL, (LPBYTE)Buffer, &dwLength); + if (rc != ERROR_SUCCESS) + { + SetLastError(rc); + goto cleanup; + } + } + 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'; + } + else + { + /* Look up icon in setupapi.dll */ + DllName = L"setupapi.dll"; + iconIndex = -iconIndex; + } + + TRACE("Icon index %d, dll name %s\n", iconIndex, debugstr_w(DllName)); + if (LargeIcon) + { + if (1 != ExtractIconEx(DllName, iconIndex, LargeIcon, NULL, 1)) + { + SetLastError(ERROR_INVALID_INDEX); + goto cleanup; + } + } + if (MiniIconIndex) + *MiniIconIndex = iconIndex; + ret = TRUE; + +cleanup: + if (hKey != INVALID_HANDLE_VALUE) + RegCloseKey(hKey); + MyFree(Buffer); + } + + TRACE("Returning %d\n", ret); + return ret; +} + /*********************************************************************** * SetupDiEnumDeviceInterfaces (SETUPAPI.@) */ @@ -2766,10 +3063,10 @@ HKEY WINAPI SetupDiOpenClassRegKey( * SetupDiOpenClassRegKeyExA (SETUPAPI.@) */ HKEY WINAPI SetupDiOpenClassRegKeyExA( - const GUID* ClassGuid, + const GUID* ClassGuid OPTIONAL, REGSAM samDesired, DWORD Flags, - PCSTR MachineName, + PCSTR MachineName OPTIONAL, PVOID Reserved) { PWSTR MachineNameW = NULL; @@ -2798,10 +3095,10 @@ HKEY WINAPI SetupDiOpenClassRegKeyExA( * SetupDiOpenClassRegKeyExW (SETUPAPI.@) */ HKEY WINAPI SetupDiOpenClassRegKeyExW( - const GUID* ClassGuid, + const GUID* ClassGuid OPTIONAL, REGSAM samDesired, DWORD Flags, - PCWSTR MachineName, + PCWSTR MachineName OPTIONAL, PVOID Reserved) { LPWSTR lpGuidString; @@ -4205,7 +4502,7 @@ BOOL WINAPI SetupDiCreateDeviceInfoW( if (CreationFlags & DICD_GENERATE_ID) { /* Generate a new unique ID for this device */ - SetLastError(ERROR_GEN_FAILURE); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); FIXME("not implemented\n"); } else @@ -4948,7 +5245,7 @@ SetupDiDeleteDeviceInfo( TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData); FIXME("not implemented\n"); - SetLastError(ERROR_GEN_FAILURE); + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return FALSE; } diff --git a/reactos/lib/setupapi/misc.c b/reactos/lib/setupapi/misc.c index ec3b1782ddc..2d303004774 100644 --- a/reactos/lib/setupapi/misc.c +++ b/reactos/lib/setupapi/misc.c @@ -278,7 +278,10 @@ LPWSTR WINAPI MultiByteToUnicode(LPCSTR lpMultiByteStr, UINT uCodePage) lpUnicodeStr = MyMalloc(nLength * sizeof(WCHAR)); if (lpUnicodeStr == NULL) + { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); return NULL; + } if (!MultiByteToWideChar(uCodePage, 0, lpMultiByteStr, nLength, lpUnicodeStr, nLength)) diff --git a/reactos/lib/setupapi/setupapi_private.h b/reactos/lib/setupapi/setupapi_private.h index 1dbaa8a4a78..f80f477f46f 100644 --- a/reactos/lib/setupapi/setupapi_private.h +++ b/reactos/lib/setupapi/setupapi_private.h @@ -41,6 +41,7 @@ #include "resource.h" #define SETUP_DEV_INFO_SET_MAGIC 0xd00ff057 +#define SETUP_CLASS_IMAGE_LIST_MAGIC 0xd00ff058 struct DeviceInterface /* Element of DeviceInfoElement.InterfaceListHead */ { @@ -153,6 +154,17 @@ struct DeviceInfoSet /* HDEVINFO */ WCHAR szData[0]; }; +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; + WCHAR szData[0]; +}; + extern HINSTANCE hInstance; #define RC_STRING_MAX_SIZE 256 diff --git a/reactos/lib/setupapi/stubs.c b/reactos/lib/setupapi/stubs.c index e222b5b72b5..3d9d366ca76 100644 --- a/reactos/lib/setupapi/stubs.c +++ b/reactos/lib/setupapi/stubs.c @@ -168,53 +168,6 @@ BOOL WINAPI SetupTerminateFileLog(HANDLE FileLogHandle) } -/*********************************************************************** - * SetupDiGetClassImageList(SETUPAPI.@) - */ -BOOL WINAPI SetupDiGetClassImageList(PSP_CLASSIMAGELIST_DATA ClassImageListData) -{ - FIXME ("Stub %p\n", ClassImageListData); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - - -/*********************************************************************** - * SetupDiGetClassImageListExA(SETUPAPI.@) - */ -BOOL WINAPI SetupDiGetClassImageListExA(PSP_CLASSIMAGELIST_DATA ClassImageListData, - PCSTR MachineName, PVOID Reserved) -{ - FIXME ("Stub %p %s %p\n", ClassImageListData, debugstr_a(MachineName), Reserved); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - - -/*********************************************************************** - * SetupDiGetClassImageListExW(SETUPAPI.@) - */ -BOOL WINAPI SetupDiGetClassImageListExW(PSP_CLASSIMAGELIST_DATA ClassImageListData, - PCWSTR MachineName, PVOID Reserved) -{ - FIXME ("Stub %p %s %p\n", ClassImageListData, debugstr_w(MachineName), Reserved); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - - -/*********************************************************************** - * SetupDiGetClassImageIndex(SETUPAPI.@) - */ -BOOL WINAPI SetupDiGetClassImageIndex(PSP_CLASSIMAGELIST_DATA ClassImageListData, - CONST GUID *ClassGuid, PINT ImageIndex) -{ - FIXME ("Stub %p %p %p\n", ClassImageListData, ClassGuid, ImageIndex); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -} - - /*********************************************************************** * SetupDiDestroyClassImageList(SETUPAPI.@) */ @@ -225,13 +178,3 @@ BOOL WINAPI SetupDiDestroyClassImageList(PSP_CLASSIMAGELIST_DATA ClassImageListD return TRUE; } - -/*********************************************************************** - * SetupDiLoadClassIcon(SETUPAPI.@) - */ -BOOL WINAPI SetupDiLoadClassIcon(CONST GUID *ClassGuid, HICON *LargeIcon, PINT MiniIconIndex) -{ - FIXME ("Stub %p %p %p\n", ClassGuid, LargeIcon, MiniIconIndex); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; -}