[SETUPAPI]
[reactos.git] / reactos / dll / win32 / setupapi / devclass.c
index 61a9be4..2bdd6e9 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "setupapi_private.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
+#include <wingdi.h>
 
 /* Unicode constants */
 static const WCHAR BackSlash[] = {'\\',0};
@@ -486,6 +486,7 @@ SetupDiGetClassImageListExW(
         HICON hIcon;
         DWORD size;
         INT i, bpp;
+        UINT idx;
 
         /* Get list of all class GUIDs in given computer */
         ret = SetupDiBuildClassInfoListExW(
@@ -589,6 +590,19 @@ SetupDiGetClassImageListExW(
                 list->IconIndexes[i] = -1; /* Special value to indicate that the icon is unavailable */
         }
 
+        /* Finally, add the overlay icons to the image list */
+        for (i = 0; i < 2; i++)
+        {
+            hIcon = LoadImage(hInstance, MAKEINTRESOURCE(500 + i), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
+            if (hIcon)
+            {
+                idx = ImageList_AddIcon(ClassImageListData->ImageList, hIcon);
+                if (idx != -1)
+                    ImageList_SetOverlayImage(ClassImageListData->ImageList, idx, i);
+                DestroyIcon(hIcon);
+            }
+        }
+
         ret = TRUE;
 
 cleanup:
@@ -646,108 +660,105 @@ SetupDiLoadClassIcon(
     OUT HICON *LargeIcon OPTIONAL,
     OUT PINT MiniIconIndex OPTIONAL)
 {
+    LPWSTR Buffer = NULL;
+    LPCWSTR DllName;
+    INT iconIndex = -18;
+    HKEY hKey = INVALID_HANDLE_VALUE;
+
     BOOL ret = FALSE;
 
-    if (!ClassGuid)
-        SetLastError(ERROR_INVALID_PARAMETER);
-    else
+    if (ClassGuid)
     {
-        LPWSTR Buffer = NULL;
-        LPCWSTR DllName;
-        INT iconIndex = 0;
-        HKEY hKey = INVALID_HANDLE_VALUE;
-
         hKey = SetupDiOpenClassRegKey(ClassGuid, KEY_QUERY_VALUE);
-        if (hKey == INVALID_HANDLE_VALUE)
-            goto cleanup;
-
-        if (!SETUP_GetIconIndex(hKey, &iconIndex))
-            goto cleanup;
+        if (hKey != INVALID_HANDLE_VALUE)
+            SETUP_GetIconIndex(hKey, &iconIndex);
+    }
 
-        if (iconIndex > 0)
+    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)
         {
-            /* 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)
             {
-                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;
+                SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+                goto cleanup;
             }
-            else if
-                (ERROR_SUCCESS == (rc = RegQueryValueExW(hKey, REGSTR_VAL_ENUMPROPPAGES_32, NULL, &dwRegType, NULL, &dwLength))
-                && dwRegType == REG_SZ)
+            rc = RegQueryValueExW(hKey, REGSTR_VAL_INSTALLER_32, NULL, NULL, (LPBYTE)Buffer, &dwLength);
+            if (rc != ERROR_SUCCESS)
             {
-                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;
+                SetLastError(rc);
+                goto cleanup;
             }
-            else
+            /* 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)
             {
-                /* Unable to find where to load the icon */
-                SetLastError(ERROR_FILE_NOT_FOUND);
+                SetLastError(ERROR_NOT_ENOUGH_MEMORY);
                 goto cleanup;
             }
-            Comma = strchrW(Buffer, ',');
-            if (!Comma)
+            rc = RegQueryValueExW(hKey, REGSTR_VAL_ENUMPROPPAGES_32, NULL, NULL, (LPBYTE)Buffer, &dwLength);
+            if (rc != ERROR_SUCCESS)
             {
-                SetLastError(ERROR_GEN_FAILURE);
+                SetLastError(rc);
                 goto cleanup;
             }
-            *Comma = '\0';
-            DllName = Buffer;
+            /* make sure the returned buffer is NULL-terminated */
+            Buffer[dwLength / sizeof(WCHAR)] = 0;
         }
         else
         {
-            /* Look up icon in setupapi.dll */
-            DllName = SetupapiDll;
-            iconIndex = -iconIndex;
+            /* 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)
+    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)
         {
-            *LargeIcon = LoadImage(hInstance, MAKEINTRESOURCE(iconIndex), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR);
-            if (!*LargeIcon)
-            {
-                SetLastError(ERROR_INVALID_INDEX);
-                goto cleanup;
-            }
+            SetLastError(ERROR_INVALID_INDEX);
+            goto cleanup;
         }
-        if (MiniIconIndex)
-            *MiniIconIndex = iconIndex;
-        ret = TRUE;
+    }
+    if (MiniIconIndex)
+        *MiniIconIndex = iconIndex;
+    ret = TRUE;
 
 cleanup:
-        if (hKey != INVALID_HANDLE_VALUE)
-            RegCloseKey(hKey);
+    if (hKey != INVALID_HANDLE_VALUE)
+        RegCloseKey(hKey);
+
+    if (Buffer != NULL)
         MyFree(Buffer);
-    }
 
     TRACE("Returning %d\n", ret);
     return ret;
@@ -1135,9 +1146,10 @@ SetupDiGetClassDevPropertySheetsA(
 
 struct ClassDevPropertySheetsData
 {
-    HPROPSHEETPAGE *PropertySheetPages;
-    DWORD MaximumNumberOfPages;
+    LPPROPSHEETHEADERW PropertySheetHeader;
+    DWORD PropertySheetHeaderPageListSize;
     DWORD NumberOfPages;
+    BOOL DontCancel;
 };
 
 static BOOL WINAPI
@@ -1149,14 +1161,16 @@ SETUP_GetClassDevPropertySheetsCallback(
 
     PropPageData = (struct ClassDevPropertySheetsData *)lParam;
 
-    if (PropPageData->NumberOfPages < PropPageData->MaximumNumberOfPages)
+    PropPageData->NumberOfPages++;
+
+    if (PropPageData->PropertySheetHeader->nPages < PropPageData->PropertySheetHeaderPageListSize)
     {
-        *PropPageData->PropertySheetPages = hPropSheetPage;
-        PropPageData->PropertySheetPages++;
+        PropPageData->PropertySheetHeader->phpage[PropPageData->PropertySheetHeader->nPages] = hPropSheetPage;
+        PropPageData->PropertySheetHeader->nPages++;
+        return TRUE;
     }
 
-    PropPageData->NumberOfPages++;
-    return TRUE;
+    return PropPageData->DontCancel;
 }
 
 /***********************************************************************
@@ -1192,8 +1206,6 @@ SetupDiGetClassDevPropertySheetsW(
         SetLastError(ERROR_INVALID_USER_BUFFER);
     else if (!DeviceInfoData && IsEqualIID(&list->ClassGuid, &GUID_NULL))
         SetLastError(ERROR_INVALID_PARAMETER);
-    else if (!PropertySheetHeader)
-        SetLastError(ERROR_INVALID_PARAMETER);
     else if (PropertySheetType != DIGCDP_FLAG_ADVANCED
           && PropertySheetType != DIGCDP_FLAG_BASIC
           && PropertySheetType != DIGCDP_FLAG_REMOTE_ADVANCED
@@ -1208,6 +1220,7 @@ SetupDiGetClassDevPropertySheetsW(
         PROPERTY_PAGE_PROVIDER pPropPageProvider = NULL;
         struct ClassDevPropertySheetsData PropPageData;
         DWORD dwLength, dwRegType;
+        DWORD InitialNumberOfPages;
         DWORD rc;
 
         if (DeviceInfoData)
@@ -1256,27 +1269,42 @@ SetupDiGetClassDevPropertySheetsW(
             goto cleanup;
         }
 
+        if (DeviceInfoData)
+        {
+            struct DeviceInfo *devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
+            devInfo->hmodDevicePropPageProvider = hModule;
+            devInfo->pDevicePropPageProvider = pPropPageProvider;
+        }
+        else
+        {
+            struct DeviceInfoSet *devInfoSet = (struct DeviceInfoSet *)DeviceInfoSet;
+            devInfoSet->hmodClassPropPageProvider = hModule;
+            devInfoSet->pClassPropPageProvider = pPropPageProvider;
+        }
+
+        InitialNumberOfPages = PropertySheetHeader->nPages;
+
         Request.cbSize = sizeof(SP_PROPSHEETPAGE_REQUEST);
         Request.PageRequested = SPPSR_ENUM_ADV_DEVICE_PROPERTIES;
         Request.DeviceInfoSet = DeviceInfoSet;
         Request.DeviceInfoData = DeviceInfoData;
-        PropPageData.PropertySheetPages = &PropertySheetHeader->phpage[PropertySheetHeader->nPages];
-        PropPageData.MaximumNumberOfPages = PropertySheetHeaderPageListSize - PropertySheetHeader->nPages;
+
+        PropPageData.PropertySheetHeader = PropertySheetHeader;
+        PropPageData.PropertySheetHeaderPageListSize = PropertySheetHeaderPageListSize;
         PropPageData.NumberOfPages = 0;
-        ret = pPropPageProvider(&Request, SETUP_GetClassDevPropertySheetsCallback, (LPARAM)&PropPageData);
-        if (!ret)
-            goto cleanup;
+        PropPageData.DontCancel = (RequiredSize != NULL) ? TRUE : FALSE;
+
+        pPropPageProvider(&Request, SETUP_GetClassDevPropertySheetsCallback, (LPARAM)&PropPageData);
 
         if (RequiredSize)
-            *RequiredSize = PropPageData.NumberOfPages + PropertySheetHeader->nPages;
-        if (PropPageData.NumberOfPages <= PropPageData.MaximumNumberOfPages)
+            *RequiredSize = PropPageData.NumberOfPages;
+
+        if (InitialNumberOfPages + PropPageData.NumberOfPages <= PropertySheetHeaderPageListSize)
         {
-            PropertySheetHeader->nPages += PropPageData.NumberOfPages;
             ret = TRUE;
         }
         else
         {
-            PropertySheetHeader->nPages += PropPageData.MaximumNumberOfPages;
             SetLastError(ERROR_INSUFFICIENT_BUFFER);
         }
 
@@ -1284,7 +1312,6 @@ cleanup:
         if (hKey != INVALID_HANDLE_VALUE)
             RegCloseKey(hKey);
         HeapFree(GetProcessHeap(), 0, PropPageProvider);
-        FreeFunctionPointer(hModule, pPropPageProvider);
     }
 
     TRACE("Returning %d\n", ret);