Implement SetupDiGetClassImageIndex, SetupDiGetClassImageList,
SetupDiGetClassImageListExA/W, SetupDiLoadClassIcon
Modified: trunk/reactos/lib/setupapi/devinst.c
Modified: trunk/reactos/lib/setupapi/misc.c
Modified: trunk/reactos/lib/setupapi/setupapi_private.h
Modified: trunk/reactos/lib/setupapi/stubs.c
_____
Modified: trunk/reactos/lib/setupapi/devinst.c
--- trunk/reactos/lib/setupapi/devinst.c 2005-12-11 06:01:32 UTC
(rev 20053)
+++ trunk/reactos/lib/setupapi/devinst.c 2005-12-11 08:11:21 UTC
(rev 20054)
@@ -656,7 +656,7 @@
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 @@
*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)
{
@@ -1842,6 +1842,303 @@
}
/***********************************************************************
+ * 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.@)
*/
BOOL WINAPI SetupDiEnumDeviceInterfaces(
@@ -2766,10 +3063,10 @@
* 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 @@
* 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 @@
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 @@
TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
FIXME("not implemented\n");
- SetLastError(ERROR_GEN_FAILURE);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
_____
Modified: trunk/reactos/lib/setupapi/misc.c
--- trunk/reactos/lib/setupapi/misc.c 2005-12-11 06:01:32 UTC (rev
20053)
+++ trunk/reactos/lib/setupapi/misc.c 2005-12-11 08:11:21 UTC (rev
20054)
@@ -278,7 +278,10 @@
lpUnicodeStr = MyMalloc(nLength * sizeof(WCHAR));
if (lpUnicodeStr == NULL)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return NULL;
+ }
if (!MultiByteToWideChar(uCodePage, 0, lpMultiByteStr,
nLength, lpUnicodeStr, nLength))
_____
Modified: trunk/reactos/lib/setupapi/setupapi_private.h
--- trunk/reactos/lib/setupapi/setupapi_private.h 2005-12-11
06:01:32 UTC (rev 20053)
+++ trunk/reactos/lib/setupapi/setupapi_private.h 2005-12-11
08:11:21 UTC (rev 20054)
@@ -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 @@
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
_____
Modified: trunk/reactos/lib/setupapi/stubs.c
--- trunk/reactos/lib/setupapi/stubs.c 2005-12-11 06:01:32 UTC (rev
20053)
+++ trunk/reactos/lib/setupapi/stubs.c 2005-12-11 08:11:21 UTC (rev
20054)
@@ -169,53 +169,6 @@
/***********************************************************************
- * 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.@)
*/
BOOL WINAPI SetupDiDestroyClassImageList(PSP_CLASSIMAGELIST_DATA
ClassImageListData)
@@ -225,13 +178,3 @@
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;
-}