Replace some strings by constants
[reactos.git] / reactos / lib / setupapi / devinst.c
index 6bbfaba..46eff4c 100644 (file)
@@ -29,31 +29,13 @@ static const WCHAR ClassGUID[]  = {'C','l','a','s','s','G','U','I','D',0};
 static const WCHAR Class[]  = {'C','l','a','s','s',0};
 static const WCHAR ClassInstall32[]  = {'C','l','a','s','s','I','n','s','t','a','l','l','3','2',0};
 static const WCHAR DeviceInstance[]  = {'D','e','v','i','c','e','I','n','s','t','a','n','c','e',0};
-static const WCHAR NoDisplayClass[]  = {'N','o','D','i','s','p','l','a','y','C','l','a','s','s',0};
-static const WCHAR NoInstallClass[]  = {'N','o','I','s','t','a','l','l','C','l','a','s','s',0};
-static const WCHAR NoUseClass[]  = {'N','o','U','s','e','C','l','a','s','s',0};
+static const WCHAR InterfaceInstall32[]  = {'I','n','t','e','r','f','a','c','e','I','n','s','t','a','l','l','3','2',0};
 static const WCHAR NtExtension[]  = {'.','N','T',0};
 static const WCHAR NtPlatformExtension[]  = {'.','N','T','x','8','6',0};
 static const WCHAR SymbolicLink[]  = {'S','y','m','b','o','l','i','c','L','i','n','k',0};
 static const WCHAR Version[]  = {'V','e','r','s','i','o','n',0};
 static const WCHAR WinExtension[]  = {'.','W','i','n',0};
 
-/* Registry key and value names */
-static const WCHAR ControlClass[] = {'S','y','s','t','e','m','\\',
-                                  'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
-                                  'C','o','n','t','r','o','l','\\',
-                                  'C','l','a','s','s',0};
-
-static const WCHAR DeviceClasses[] = {'S','y','s','t','e','m','\\',
-                                  'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
-                                  'C','o','n','t','r','o','l','\\',
-                                  'D','e','v','i','c','e','C','l','a','s','s','e','s',0};
-
-static const WCHAR EnumKeyName[] = {'S','y','s','t','e','m','\\',
-                                  'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
-                                  'E','n','u','m',0};
-
-
 /* FIXME: header mess */
 DEFINE_GUID(GUID_NULL,
   0x00000000L, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
@@ -77,6 +59,12 @@ typedef BOOL
     IN PSP_PROPSHEETPAGE_REQUEST PropPageRequest,
     IN LPFNADDPROPSHEETPAGE fAddFunc,
     IN LPARAM lParam);
+typedef BOOL
+(*UPDATE_CLASS_PARAM_HANDLER) (
+    IN HDEVINFO DeviceInfoSet,
+    IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
+    IN PSP_CLASSINSTALL_HEADER ClassInstallParams OPTIONAL,
+    IN DWORD ClassInstallParamsSize);
 
 struct CoInstallerElement
 {
@@ -88,6 +76,58 @@ struct CoInstallerElement
     PVOID PrivateData;
 };
 
+static BOOL
+PropertyChangeHandler(
+    IN HDEVINFO DeviceInfoSet,
+    IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
+    IN PSP_CLASSINSTALL_HEADER ClassInstallParams OPTIONAL,
+    IN DWORD ClassInstallParamsSize);
+
+static UPDATE_CLASS_PARAM_HANDLER UpdateClassInstallParamHandlers[] = {
+    NULL, /* DIF_SELECTDEVICE */
+    NULL, /* DIF_INSTALLDEVICE */
+    NULL, /* DIF_ASSIGNRESOURCES */
+    NULL, /* DIF_PROPERTIES */
+    NULL, /* DIF_REMOVE */
+    NULL, /* DIF_FIRSTTIMESETUP */
+    NULL, /* DIF_FOUNDDEVICE */
+    NULL, /* DIF_SELECTCLASSDRIVERS */
+    NULL, /* DIF_VALIDATECLASSDRIVERS */
+    NULL, /* DIF_INSTALLCLASSDRIVERS */
+    NULL, /* DIF_CALCDISKSPACE */
+    NULL, /* DIF_DESTROYPRIVATEDATA */
+    NULL, /* DIF_VALIDATEDRIVER */
+    NULL, /* DIF_MOVEDEVICE */
+    NULL, /* DIF_DETECT */
+    NULL, /* DIF_INSTALLWIZARD */
+    NULL, /* DIF_DESTROYWIZARDDATA */
+    PropertyChangeHandler, /* DIF_PROPERTYCHANGE */
+    NULL, /* DIF_ENABLECLASS */
+    NULL, /* DIF_DETECTVERIFY */
+    NULL, /* DIF_INSTALLDEVICEFILES */
+    NULL, /* DIF_UNREMOVE */
+    NULL, /* DIF_SELECTBESTCOMPATDRV */
+    NULL, /* DIF_ALLOW_INSTALL */
+    NULL, /* DIF_REGISTERDEVICE */
+    NULL, /* DIF_NEWDEVICEWIZARD_PRESELECT */
+    NULL, /* DIF_NEWDEVICEWIZARD_SELECT */
+    NULL, /* DIF_NEWDEVICEWIZARD_PREANALYZE */
+    NULL, /* DIF_NEWDEVICEWIZARD_POSTANALYZE */
+    NULL, /* DIF_NEWDEVICEWIZARD_FINISHINSTALL */
+    NULL, /* DIF_UNUSED1 */
+    NULL, /* DIF_INSTALLINTERFACES */
+    NULL, /* DIF_DETECTCANCEL */
+    NULL, /* DIF_REGISTER_COINSTALLERS */
+    NULL, /* DIF_ADDPROPERTYPAGE_ADVANCED */
+    NULL, /* DIF_ADDPROPERTYPAGE_BASIC */
+    NULL, /* DIF_RESERVED1 */
+    NULL, /* DIF_TROUBLESHOOTER */
+    NULL, /* DIF_POWERMESSAGEWAKE */
+    NULL, /* DIF_ADDREMOTEPROPERTYPAGE_ADVANCED */
+    NULL, /* DIF_UPDATEDRIVER_UI */
+    NULL  /* DIF_RESERVED2 */
+};
+
 /***********************************************************************
  *              SetupDiBuildClassInfoList  (SETUPAPI.@)
  */
@@ -197,7 +237,7 @@ BOOL WINAPI SetupDiBuildClassInfoListExW(
            }
 
            if (!RegQueryValueExW(hClassKey,
-                                 NoUseClass,
+                                 REGSTR_VAL_NOUSECLASS,
                                  NULL,
                                  NULL,
                                  NULL,
@@ -210,7 +250,7 @@ BOOL WINAPI SetupDiBuildClassInfoListExW(
 
            if ((Flags & DIBCI_NOINSTALLCLASS) &&
                (!RegQueryValueExW(hClassKey,
-                                  NoInstallClass,
+                                  REGSTR_VAL_NOINSTALLCLASS,
                                   NULL,
                                   NULL,
                                   NULL,
@@ -223,7 +263,7 @@ BOOL WINAPI SetupDiBuildClassInfoListExW(
 
            if ((Flags & DIBCI_NODISPLAYCLASS) &&
                (!RegQueryValueExW(hClassKey,
-                                  NoDisplayClass,
+                                  REGSTR_VAL_NODISPLAYCLASS,
                                   NULL,
                                   NULL,
                                   NULL,
@@ -1342,7 +1382,7 @@ static LONG SETUP_CreateDevList(
         HKLM = HKEY_LOCAL_MACHINE;
 
     rc = RegOpenKeyExW(HKLM,
-        EnumKeyName,
+        REGSTR_PATH_SYSTEMENUM,
         0,
         KEY_ENUMERATE_SUB_KEYS,
         &hEnumKey);
@@ -1580,7 +1620,7 @@ static LONG SETUP_CreateInterfaceList(
         /* Find class GUID associated to the device instance */
         rc = RegOpenKeyExW(
             HKEY_LOCAL_MACHINE,
-            EnumKeyName,
+            REGSTR_PATH_SYSTEMENUM,
             0, /* Options */
             KEY_ENUMERATE_SUB_KEYS,
             &hEnumKey);
@@ -1855,8 +1895,8 @@ static BOOL GetIconIndex(
     LONG rc;
     BOOL ret = FALSE;
 
-    /* Read "Icon" registry key */
-    rc = RegQueryValueExW(hClassKey, L"Icon", NULL, &dwRegType, NULL, &dwLength);
+    /* Read icon registry key */
+    rc = RegQueryValueExW(hClassKey, REGSTR_VAL_INSICON, NULL, &dwRegType, NULL, &dwLength);
     if (rc != ERROR_SUCCESS)
     {
         SetLastError(rc);
@@ -1872,7 +1912,7 @@ static BOOL GetIconIndex(
         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
         goto cleanup;
     }
-    rc = RegQueryValueExW(hClassKey, L"Icon", NULL, NULL, (LPBYTE)Buffer, &dwLength);
+    rc = RegQueryValueExW(hClassKey, REGSTR_VAL_INSICON, NULL, NULL, (LPBYTE)Buffer, &dwLength);
     if (rc != ERROR_SUCCESS)
     {
         SetLastError(rc);
@@ -1881,7 +1921,7 @@ static BOOL GetIconIndex(
     /* make sure the returned buffer is NULL-terminated */
     Buffer[dwLength / sizeof(WCHAR)] = 0;
 
-    /* Transform "Icon" value to a INT */
+    /* Transform icon value to a INT */
     *ImageIndex = atoiW(Buffer);
     ret = TRUE;
 
@@ -2063,7 +2103,7 @@ BOOL WINAPI SetupDiLoadClassIcon(
             PWCHAR Comma;
             LONG rc;
             DWORD dwRegType, dwLength;
-            rc = RegQueryValueExW(hKey, L"Installer32", NULL, &dwRegType, NULL, &dwLength);
+            rc = RegQueryValueExW(hKey, REGSTR_VAL_INSTALLER_32, NULL, &dwRegType, NULL, &dwLength);
             if (rc == ERROR_SUCCESS && dwRegType == REG_SZ)
             {
                 Buffer = MyMalloc(dwLength + sizeof(WCHAR));
@@ -2072,7 +2112,7 @@ BOOL WINAPI SetupDiLoadClassIcon(
                     SetLastError(ERROR_NOT_ENOUGH_MEMORY);
                     goto cleanup;
                 }
-                rc = RegQueryValueExW(hKey, L"Installer32", NULL, NULL, (LPBYTE)Buffer, &dwLength);
+                rc = RegQueryValueExW(hKey, REGSTR_VAL_INSTALLER_32, NULL, NULL, (LPBYTE)Buffer, &dwLength);
                 if (rc != ERROR_SUCCESS)
                 {
                     SetLastError(rc);
@@ -2082,7 +2122,7 @@ BOOL WINAPI SetupDiLoadClassIcon(
                 Buffer[dwLength / sizeof(WCHAR)] = 0;
             }
             else if
-                (ERROR_SUCCESS == (rc = RegQueryValueExW(hKey, L"EnumPropPages32", NULL, &dwRegType, NULL, &dwLength))
+                (ERROR_SUCCESS == (rc = RegQueryValueExW(hKey, REGSTR_VAL_ENUMPROPPAGES_32, NULL, &dwRegType, NULL, &dwLength))
                 && dwRegType == REG_SZ)
             {
                 Buffer = MyMalloc(dwLength + sizeof(WCHAR));
@@ -2091,7 +2131,7 @@ BOOL WINAPI SetupDiLoadClassIcon(
                     SetLastError(ERROR_NOT_ENOUGH_MEMORY);
                     goto cleanup;
                 }
-                rc = RegQueryValueExW(hKey, L"EnumPropPages32", NULL, NULL, (LPBYTE)Buffer, &dwLength);
+                rc = RegQueryValueExW(hKey, REGSTR_VAL_ENUMPROPPAGES_32, NULL, NULL, (LPBYTE)Buffer, &dwLength);
                 if (rc != ERROR_SUCCESS)
                 {
                     SetLastError(rc);
@@ -2240,6 +2280,12 @@ static BOOL DestroyDriverInfoElement(struct DriverInfoElement* driverInfo)
     return TRUE;
 }
 
+static BOOL DestroyClassInstallParams(struct ClassInstallParams* installParams)
+{
+    HeapFree(GetProcessHeap(), 0, installParams->PropChange);
+    return TRUE;
+}
+
 static BOOL DestroyDeviceInfoElement(struct DeviceInfoElement* deviceInfo)
 {
     PLIST_ENTRY ListEntry;
@@ -2257,6 +2303,7 @@ static BOOL DestroyDeviceInfoElement(struct DeviceInfoElement* deviceInfo)
         ListEntry = RemoveHeadList(&deviceInfo->InterfaceListHead);
         HeapFree(GetProcessHeap(), 0, ListEntry);
     }
+    DestroyClassInstallParams(&deviceInfo->ClassInstallParams);
     HeapFree(GetProcessHeap(), 0, deviceInfo);
     return TRUE;
 }
@@ -2276,6 +2323,7 @@ static BOOL DestroyDeviceInfoSet(struct DeviceInfoSet* list)
     if (list->HKLM != HKEY_LOCAL_MACHINE)
         RegCloseKey(list->HKLM);
     CM_Disconnect_Machine(list->hMachine);
+    DestroyClassInstallParams(&list->ClassInstallParams);
     HeapFree(GetProcessHeap(), 0, list);
     return TRUE;
 }
@@ -2579,39 +2627,39 @@ BOOL WINAPI SetupDiGetDeviceRegistryPropertyW(
                 switch (Property)
                 {
                     case SPDRP_CAPABILITIES:
-                        RegistryPropertyName = L"Capabilities"; break;
+                        RegistryPropertyName = REGSTR_VAL_CAPABILITIES; break;
                     case SPDRP_CLASS:
-                        RegistryPropertyName = L"Class"; break;
+                        RegistryPropertyName = REGSTR_VAL_CLASS; break;
                     case SPDRP_CLASSGUID:
-                        RegistryPropertyName = L"ClassGUID"; break;
+                        RegistryPropertyName = REGSTR_VAL_CLASSGUID; break;
                     case SPDRP_COMPATIBLEIDS:
-                        RegistryPropertyName = L"CompatibleIDs"; break;
+                        RegistryPropertyName = REGSTR_VAL_COMPATIBLEIDS; break;
                     case SPDRP_CONFIGFLAGS:
-                        RegistryPropertyName = L"ConfigFlags"; break;
+                        RegistryPropertyName = REGSTR_VAL_CONFIGFLAGS; break;
                     case SPDRP_DEVICEDESC:
-                        RegistryPropertyName = L"DeviceDesc"; break;
+                        RegistryPropertyName = REGSTR_VAL_DEVDESC; break;
                     case SPDRP_DRIVER:
-                        RegistryPropertyName = L"Driver"; break;
+                        RegistryPropertyName = REGSTR_VAL_DRIVER; break;
                     case SPDRP_FRIENDLYNAME:
-                        RegistryPropertyName = L"FriendlyName"; break;
+                        RegistryPropertyName = REGSTR_VAL_FRIENDLYNAME; break;
                     case SPDRP_HARDWAREID:
-                        RegistryPropertyName = L"HardwareID"; break;
+                        RegistryPropertyName = REGSTR_VAL_HARDWAREID; break;
                     case SPDRP_LOCATION_INFORMATION:
-                        RegistryPropertyName = L"LocationInformation"; break;
+                        RegistryPropertyName = REGSTR_VAL_LOCATION_INFORMATION; break;
                     case SPDRP_LOWERFILTERS:
-                        RegistryPropertyName = L"LowerFilters"; break;
+                        RegistryPropertyName = REGSTR_VAL_LOWERFILTERS; break;
                     case SPDRP_MFG:
-                        RegistryPropertyName = L"Mfg"; break;
+                        RegistryPropertyName = REGSTR_VAL_MFG; break;
                     case SPDRP_SECURITY:
                         RegistryPropertyName = L"Security"; break;
                     case SPDRP_SERVICE:
-                        RegistryPropertyName = L"Service"; break;
+                        RegistryPropertyName = REGSTR_VAL_SERVICE; break;
                     case SPDRP_UI_NUMBER:
-                        RegistryPropertyName = L"UINumber"; break;
+                        RegistryPropertyName = REGSTR_VAL_UI_NUMBER; break;
                     case SPDRP_UI_NUMBER_DESC_FORMAT:
                         RegistryPropertyName = L"UINumberDescFormat"; break;
                     case SPDRP_UPPERFILTERS:
-                        RegistryPropertyName = L"UpperFilters"; break;
+                        RegistryPropertyName = REGSTR_VAL_UPPERFILTERS; break;
                     default:
                         /* Should not happen */
                         RegistryPropertyName = NULL; break;
@@ -2620,7 +2668,7 @@ BOOL WINAPI SetupDiGetDeviceRegistryPropertyW(
                 /* Open registry key name */
                 rc = RegOpenKeyExW(
                     list->HKLM,
-                    EnumKeyName,
+                    REGSTR_PATH_SYSTEMENUM,
                     0, /* Options */
                     KEY_ENUMERATE_SUB_KEYS,
                     &hEnumKey);
@@ -2752,7 +2800,7 @@ BOOL WINAPI SetupDiSetDeviceRegistryPropertyW(
         SetLastError(ERROR_INVALID_HANDLE);
     else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEV_INFO_SET_MAGIC)
         SetLastError(ERROR_INVALID_HANDLE);
-    else if (DeviceInfoData)
+    else if (!DeviceInfoData)
         SetLastError(ERROR_INVALID_HANDLE);
     else if (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
         SetLastError(ERROR_INVALID_USER_BUFFER);
@@ -2779,27 +2827,27 @@ BOOL WINAPI SetupDiSetDeviceRegistryPropertyW(
                 switch (Property)
                 {
                     case SPDRP_COMPATIBLEIDS:
-                        RegistryPropertyName = L"CompatibleIDs";
+                        RegistryPropertyName = REGSTR_VAL_COMPATIBLEIDS;
                         RegistryDataType = REG_MULTI_SZ;
                         break;
                     case SPDRP_CONFIGFLAGS:
-                        RegistryPropertyName = L"ConfigFlags";
+                        RegistryPropertyName = REGSTR_VAL_CONFIGFLAGS;
                         RegistryDataType = REG_DWORD;
                         break;
                     case SPDRP_FRIENDLYNAME:
-                        RegistryPropertyName = L"FriendlyName";
+                        RegistryPropertyName = REGSTR_VAL_FRIENDLYNAME;
                         RegistryDataType = REG_SZ;
                         break;
                     case SPDRP_HARDWAREID:
-                        RegistryPropertyName = L"HardwareID";
+                        RegistryPropertyName = REGSTR_VAL_HARDWAREID;
                         RegistryDataType = REG_MULTI_SZ;
                         break;
                     case SPDRP_LOCATION_INFORMATION:
-                        RegistryPropertyName = L"LocationInformation";
+                        RegistryPropertyName = REGSTR_VAL_LOCATION_INFORMATION;
                         RegistryDataType = REG_SZ;
                         break;
                     case SPDRP_LOWERFILTERS:
-                        RegistryPropertyName = L"LowerFilters";
+                        RegistryPropertyName = REGSTR_VAL_LOWERFILTERS;
                         RegistryDataType = REG_MULTI_SZ;
                         break;
                     case SPDRP_SECURITY:
@@ -2807,7 +2855,7 @@ BOOL WINAPI SetupDiSetDeviceRegistryPropertyW(
                         RegistryDataType = REG_BINARY;
                         break;
                     case SPDRP_SERVICE:
-                        RegistryPropertyName = L"Service";
+                        RegistryPropertyName = REGSTR_VAL_SERVICE;
                         RegistryDataType = REG_SZ;
                         break;
                     case SPDRP_UI_NUMBER_DESC_FORMAT:
@@ -2815,7 +2863,7 @@ BOOL WINAPI SetupDiSetDeviceRegistryPropertyW(
                         RegistryDataType = REG_SZ;
                         break;
                     case SPDRP_UPPERFILTERS:
-                        RegistryPropertyName = L"UpperFilters";
+                        RegistryPropertyName = REGSTR_VAL_UPPERFILTERS;
                         RegistryDataType = REG_MULTI_SZ;
                         break;
                     default:
@@ -2909,7 +2957,7 @@ static HKEY CreateClassKey(HINF hInf)
         return INVALID_HANDLE_VALUE;
     }
 
-    lstrcpyW(FullBuffer, ControlClass);
+    lstrcpyW(FullBuffer, REGSTR_PATH_CLASS_NT);
     lstrcatW(FullBuffer, Buffer);
 
 
@@ -3042,7 +3090,7 @@ BOOL WINAPI SetupDiInstallClassW(
                                INVALID_HANDLE_VALUE,
                                NULL);
 
-    /* FIXME: More code! */
+    /* FIXME: Process InterfaceInstall32 section */
 
     if (bFileQueueCreated)
        SetupCloseFileQueue(FileQueue);
@@ -3122,11 +3170,11 @@ HKEY WINAPI SetupDiOpenClassRegKeyExW(
 
     if (Flags == DIOCR_INSTALLER)
     {
-        lpKeyName = ControlClass;
+        lpKeyName = REGSTR_PATH_CLASS_NT;
     }
     else if (Flags == DIOCR_INTERFACE)
     {
-        lpKeyName = DeviceClasses;
+        lpKeyName = REGSTR_PATH_DEVICE_CLASSES;
     }
     else
     {
@@ -3260,14 +3308,131 @@ BOOL WINAPI SetupDiSetClassInstallParamsA(
  *             SetupDiSetClassInstallParamsW (SETUPAPI.@)
  */
 BOOL WINAPI SetupDiSetClassInstallParamsW(
-       HDEVINFO  DeviceInfoSet,
-       PSP_DEVINFO_DATA DeviceInfoData,
-       PSP_CLASSINSTALL_HEADER ClassInstallParams,
-       DWORD ClassInstallParamsSize)
+       IN HDEVINFO DeviceInfoSet,
+       IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
+       IN PSP_CLASSINSTALL_HEADER ClassInstallParams OPTIONAL,
+       IN DWORD ClassInstallParamsSize)
 {
-    FIXME("%p %p %x %lu\n",DeviceInfoSet, DeviceInfoData,
-          ClassInstallParams->InstallFunction, ClassInstallParamsSize);
-    return FALSE;
+    struct DeviceInfoSet *list;
+    BOOL ret = FALSE;
+
+    TRACE("%p %p %p %lu\n", DeviceInfoSet, DeviceInfoData,
+        ClassInstallParams, ClassInstallParamsSize);
+
+    if (!DeviceInfoSet)
+        SetLastError(ERROR_INVALID_PARAMETER);
+    else if (DeviceInfoSet == (HDEVINFO)INVALID_HANDLE_VALUE)
+        SetLastError(ERROR_INVALID_HANDLE);
+    else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEV_INFO_SET_MAGIC)
+        SetLastError(ERROR_INVALID_HANDLE);
+    else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
+        SetLastError(ERROR_INVALID_USER_BUFFER);
+    else if (ClassInstallParams && ClassInstallParams->cbSize != sizeof(SP_CLASSINSTALL_HEADER))
+        SetLastError(ERROR_INVALID_USER_BUFFER);
+    else if (ClassInstallParams && ClassInstallParamsSize < sizeof(SP_CLASSINSTALL_HEADER))
+        SetLastError(ERROR_INVALID_PARAMETER);
+    else if (!ClassInstallParams && ClassInstallParamsSize != 0)
+        SetLastError(ERROR_INVALID_PARAMETER);
+    else
+    {
+        SP_DEVINSTALL_PARAMS_W InstallParams;
+        BOOL Result;
+
+        InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
+        Result = SetupDiGetDeviceInstallParamsW(DeviceInfoSet, DeviceInfoData, &InstallParams);
+        if (!Result)
+            goto done;
+
+        if (ClassInstallParams)
+        {
+            /* Check parameters in ClassInstallParams */
+            if (ClassInstallParams->InstallFunction < DIF_SELECTDEVICE
+                || ClassInstallParams->InstallFunction - DIF_SELECTDEVICE >= sizeof(UpdateClassInstallParamHandlers)/sizeof(UpdateClassInstallParamHandlers[0]))
+            {
+                SetLastError(ERROR_INVALID_USER_BUFFER);
+                goto done;
+            }
+            else if (UpdateClassInstallParamHandlers[ClassInstallParams->InstallFunction - DIF_SELECTDEVICE] == NULL)
+            {
+                FIXME("InstallFunction %u is valid, but has no associated update handler\n", ClassInstallParams->InstallFunction);
+                SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+                goto done;
+            }
+            ret = UpdateClassInstallParamHandlers[ClassInstallParams->InstallFunction - DIF_SELECTDEVICE](DeviceInfoSet, DeviceInfoData, ClassInstallParams, ClassInstallParamsSize);
+            if (!ret)
+                goto done;
+            InstallParams.Flags |= DI_CLASSINSTALLPARAMS;
+        }
+        else
+        {
+            InstallParams.Flags &= ~DI_CLASSINSTALLPARAMS;
+        }
+
+        ret = SetupDiSetDeviceInstallParamsW(DeviceInfoSet, DeviceInfoData, &InstallParams);
+    }
+
+done:
+    TRACE("Returning %d\n", ret);
+    return ret;
+}
+
+static BOOL PropertyChangeHandler(
+       IN HDEVINFO DeviceInfoSet,
+       IN PSP_DEVINFO_DATA DeviceInfoData,
+       IN PSP_CLASSINSTALL_HEADER ClassInstallParams OPTIONAL,
+       IN DWORD ClassInstallParamsSize)
+{
+    PSP_PROPCHANGE_PARAMS PropChangeParams = (PSP_PROPCHANGE_PARAMS)ClassInstallParams;
+    BOOL ret = FALSE;
+
+    if (!DeviceInfoData)
+        SetLastError(ERROR_INVALID_PARAMETER);
+    else if (ClassInstallParamsSize != sizeof(SP_PROPCHANGE_PARAMS))
+        SetLastError(ERROR_INVALID_PARAMETER);
+    else if (PropChangeParams && PropChangeParams->StateChange != DICS_ENABLE
+        && PropChangeParams->StateChange != DICS_DISABLE && PropChangeParams->StateChange != DICS_PROPCHANGE
+        && PropChangeParams->StateChange != DICS_START && PropChangeParams->StateChange != DICS_STOP)
+        SetLastError(ERROR_INVALID_FLAGS);
+    else if (PropChangeParams && PropChangeParams->Scope != DICS_FLAG_GLOBAL
+        && PropChangeParams->Scope != DICS_FLAG_CONFIGSPECIFIC)
+        SetLastError(ERROR_INVALID_FLAGS);
+    else if (PropChangeParams
+        && (PropChangeParams->StateChange == DICS_START || PropChangeParams->StateChange == DICS_STOP)
+        && PropChangeParams->Scope != DICS_FLAG_CONFIGSPECIFIC)
+        SetLastError(ERROR_INVALID_USER_BUFFER);
+    else
+    {
+        PSP_PROPCHANGE_PARAMS *CurrentPropChangeParams;
+        if (!DeviceInfoData)
+        {
+            struct DeviceInfoSet *list = (struct DeviceInfoSet *)DeviceInfoSet;
+            CurrentPropChangeParams = &list->ClassInstallParams.PropChange;
+        }
+        else
+        {
+            struct DeviceInfoElement *deviceInfo = (struct DeviceInfoElement *)DeviceInfoData->Reserved;
+            CurrentPropChangeParams = &deviceInfo->ClassInstallParams.PropChange;
+        }
+        if (*CurrentPropChangeParams)
+        {
+            MyFree(*CurrentPropChangeParams);
+            *CurrentPropChangeParams = NULL;
+        }
+        if (PropChangeParams)
+        {
+            *CurrentPropChangeParams = MyMalloc(sizeof(SP_PROPCHANGE_PARAMS));
+            if (!*CurrentPropChangeParams)
+            {
+                SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+                goto done;
+            }
+            memcpy(*CurrentPropChangeParams, PropChangeParams, sizeof(SP_PROPCHANGE_PARAMS));
+        }
+        ret = TRUE;
+    }
+
+done:
+    return ret;
 }
 
 static DWORD
@@ -3404,6 +3569,10 @@ BOOL WINAPI SetupDiCallClassInstaller(
             case DIF_NEWDEVICEWIZARD_PREANALYZE:
                 CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
                 break;
+            case DIF_PROPERTYCHANGE:
+                CanHandle = CLASS_COINSTALLER | DEVICE_COINSTALLER | CLASS_INSTALLER;
+                DefaultHandler = SetupDiChangeState;
+                break;
             case DIF_REGISTER_COINSTALLERS:
                 CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
                 DefaultHandler = SetupDiRegisterCoDeviceInstallers;
@@ -3442,13 +3611,13 @@ BOOL WINAPI SetupDiCallClassInstaller(
                 hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_QUERY_VALUE);
                 if (hKey != INVALID_HANDLE_VALUE)
                 {
-                    rc = RegQueryValueExW(hKey, L"CoInstallers32", NULL, &dwRegType, NULL, &dwLength);
+                    rc = RegQueryValueExW(hKey, REGSTR_VAL_COINSTALLERS_32, NULL, &dwRegType, NULL, &dwLength);
                     if (rc == ERROR_SUCCESS && dwRegType == REG_MULTI_SZ)
                     {
                         LPWSTR KeyBuffer = HeapAlloc(GetProcessHeap(), 0, dwLength);
                         if (KeyBuffer != NULL)
                         {
-                            rc = RegQueryValueExW(hKey, L"CoInstallers32", NULL, NULL, (LPBYTE)KeyBuffer, &dwLength);
+                            rc = RegQueryValueExW(hKey, REGSTR_VAL_COINSTALLERS_32, NULL, NULL, (LPBYTE)KeyBuffer, &dwLength);
                             if (rc == ERROR_SUCCESS)
                             {
                                 LPWSTR ptr;
@@ -3477,7 +3646,7 @@ BOOL WINAPI SetupDiCallClassInstaller(
             {
                 rc = RegOpenKeyEx(
                     HKEY_LOCAL_MACHINE,
-                    L"SYSTEM\\CurrentControlSet\\Control\\CoDeviceInstallers",
+                    REGSTR_PATH_CODEVICEINSTALLERS,
                     0, /* Options */
                     KEY_QUERY_VALUE,
                     &hKey);
@@ -3524,13 +3693,13 @@ BOOL WINAPI SetupDiCallClassInstaller(
                 hKey = SetupDiOpenClassRegKey(&DeviceInfoData->ClassGuid, KEY_QUERY_VALUE);
                 if (hKey != INVALID_HANDLE_VALUE)
                 {
-                    rc = RegQueryValueExW(hKey, L"Installer32", NULL, &dwRegType, NULL, &dwLength);
+                    rc = RegQueryValueExW(hKey, REGSTR_VAL_INSTALLER_32, NULL, &dwRegType, NULL, &dwLength);
                     if (rc == ERROR_SUCCESS && dwRegType == REG_SZ)
                     {
                         LPWSTR KeyBuffer = HeapAlloc(GetProcessHeap(), 0, dwLength);
                         if (KeyBuffer != NULL)
                         {
-                            rc = RegQueryValueExW(hKey, L"Installer32", NULL, NULL, (LPBYTE)KeyBuffer, &dwLength);
+                            rc = RegQueryValueExW(hKey, REGSTR_VAL_INSTALLER_32, NULL, NULL, (LPBYTE)KeyBuffer, &dwLength);
                             if (rc == ERROR_SUCCESS)
                             {
                                 /* Get ClassInstaller function pointer */
@@ -4029,7 +4198,7 @@ BOOL WINAPI SetupDiGetClassDevPropertySheetsW(
         if (hKey == INVALID_HANDLE_VALUE)
             goto cleanup;
 
-        rc = RegQueryValueExW(hKey, L"EnumPropPages32", NULL, &dwRegType, NULL, &dwLength);
+        rc = RegQueryValueExW(hKey, REGSTR_VAL_ENUMPROPPAGES_32, NULL, &dwRegType, NULL, &dwLength);
         if (rc == ERROR_FILE_NOT_FOUND)
         {
             /* No registry key. As it is optional, don't say it's a bad error */
@@ -4050,7 +4219,7 @@ BOOL WINAPI SetupDiGetClassDevPropertySheetsW(
             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
             goto cleanup;
         }
-        rc = RegQueryValueExW(hKey, L"EnumPropPages32", NULL, NULL, (LPBYTE)PropPageProvider, &dwLength);
+        rc = RegQueryValueExW(hKey, REGSTR_VAL_ENUMPROPPAGES_32, NULL, NULL, (LPBYTE)PropPageProvider, &dwLength);
         if (rc != ERROR_SUCCESS)
         {
             SetLastError(rc);
@@ -4176,25 +4345,101 @@ HKEY WINAPI SetupDiCreateDevRegKeyW(
         LPWSTR pDeviceInstance; /* Points into DriverKey, on the Index field */
         DWORD Index; /* Index used in the DriverKey name */
         DWORD rc;
+        HKEY hHWProfilesKey = INVALID_HANDLE_VALUE;
+        HKEY hHWProfileKey = INVALID_HANDLE_VALUE;
+        HKEY hEnumKey = INVALID_HANDLE_VALUE;
         HKEY hClassKey = INVALID_HANDLE_VALUE;
         HKEY hDeviceKey = INVALID_HANDLE_VALUE;
         HKEY hKey = INVALID_HANDLE_VALUE;
+        HKEY RootKey;
 
-        if (Scope == DICS_FLAG_CONFIGSPECIFIC)
+        if (Scope == DICS_FLAG_GLOBAL)
+            RootKey = list->HKLM;
+        else /* Scope == DICS_FLAG_CONFIGSPECIFIC */
         {
-            FIXME("DICS_FLAG_CONFIGSPECIFIC case unimplemented\n");
-            goto cleanup;
+            rc = RegOpenKeyExW(list->HKLM,
+                REGSTR_PATH_HWPROFILES,
+                0,
+                0,
+                &hHWProfilesKey);
+            if (rc != ERROR_SUCCESS)
+            {
+                SetLastError(rc);
+                goto cleanup;
+            }
+            if (HwProfile == 0)
+            {
+                rc = RegOpenKeyExW(
+                    hHWProfilesKey,
+                    REGSTR_KEY_CURRENT,
+                    0,
+                    KEY_CREATE_SUB_KEY,
+                    &hHWProfileKey);
+            }
+            else
+            {
+                WCHAR subKey[5];
+                snprintfW(subKey, 4, L"%04lu", HwProfile);
+                subKey[4] = '\0';
+                rc = RegOpenKeyExW(
+                    hHWProfilesKey,
+                    subKey,
+                    0,
+                    KEY_CREATE_SUB_KEY,
+                    &hHWProfileKey);
+            }
+            if (rc != ERROR_SUCCESS)
+            {
+                SetLastError(rc);
+                goto cleanup;
+            }
+            RootKey = hHWProfileKey;
         }
 
         if (KeyType == DIREG_DEV)
         {
-            FIXME("DIREG_DEV case unimplemented\n");
+            struct DeviceInfoElement *deviceInfo = (struct DeviceInfoElement *)DeviceInfoData->Reserved;
+
+            rc = RegCreateKeyExW(
+                RootKey,
+                REGSTR_PATH_SYSTEMENUM,
+                0,
+                NULL,
+                REG_OPTION_NON_VOLATILE,
+                KEY_CREATE_SUB_KEY,
+                NULL,
+                &hEnumKey,
+                NULL);
+            if (rc != ERROR_SUCCESS)
+            {
+                SetLastError(rc);
+                goto cleanup;
+            }
+            rc = RegCreateKeyExW(
+                hEnumKey,
+                deviceInfo->DeviceName,
+                0,
+                NULL,
+                REG_OPTION_NON_VOLATILE,
+#if _WIN32_WINNT >= 0x502
+                KEY_READ | KEY_WRITE,
+#else
+                KEY_ALL_ACCESS,
+#endif
+                NULL,
+                &hKey,
+                NULL);
+            if (rc != ERROR_SUCCESS)
+            {
+                SetLastError(rc);
+                goto cleanup;
+            }
         }
         else /* KeyType == DIREG_DRV */
         {
             if (UuidToStringW((UUID*)&DeviceInfoData->ClassGuid, &lpGuidString) != RPC_S_OK)
                 goto cleanup;
-            /* The driver key is in HKLM\System\CurrentControlSet\Control\Class\{GUID}\Index */
+            /* The driver key is in \System\CurrentControlSet\Control\Class\{GUID}\Index */
             DriverKey = HeapAlloc(GetProcessHeap(), 0, (wcslen(lpGuidString) + 7) * sizeof(WCHAR) + sizeof(UNICODE_STRING));
             if (!DriverKey)
             {
@@ -4205,8 +4450,8 @@ HKEY WINAPI SetupDiCreateDevRegKeyW(
             wcscat(DriverKey, lpGuidString);
             wcscat(DriverKey, L"}\\");
             pDeviceInstance = &DriverKey[wcslen(DriverKey)];
-            rc = RegOpenKeyExW(list->HKLM,
-                ControlClass,
+            rc = RegOpenKeyExW(RootKey,
+                REGSTR_PATH_CLASS_NT,
                 0,
                 KEY_CREATE_SUB_KEY,
                 &hClassKey);
@@ -4257,7 +4502,7 @@ HKEY WINAPI SetupDiCreateDevRegKeyW(
             hDeviceKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, Scope, HwProfile, DIREG_DEV, KEY_SET_VALUE);
             if (hDeviceKey == INVALID_HANDLE_VALUE)
                 goto cleanup;
-            rc = RegSetValueEx(hDeviceKey, L"Driver", 0, REG_SZ, (const BYTE *)DriverKey, (wcslen(DriverKey) + 1) * sizeof(WCHAR));
+            rc = RegSetValueEx(hDeviceKey, REGSTR_VAL_DRIVER, 0, REG_SZ, (const BYTE *)DriverKey, (wcslen(DriverKey) + 1) * sizeof(WCHAR));
             if (rc != ERROR_SUCCESS)
             {
                 SetLastError(rc);
@@ -4277,6 +4522,12 @@ cleanup:
         if (lpGuidString)
             RpcStringFreeW(&lpGuidString);
         HeapFree(GetProcessHeap(), 0, DriverKey);
+        if (hHWProfilesKey != INVALID_HANDLE_VALUE)
+            RegCloseKey(hHWProfilesKey);
+        if (hHWProfileKey != INVALID_HANDLE_VALUE)
+            RegCloseKey(hHWProfileKey);
+        if (hEnumKey != INVALID_HANDLE_VALUE)
+            RegCloseKey(hEnumKey);
         if (hClassKey != INVALID_HANDLE_VALUE)
             RegCloseKey(hClassKey);
         if (hDeviceKey != INVALID_HANDLE_VALUE)
@@ -4336,7 +4587,7 @@ HKEY WINAPI SetupDiOpenDevRegKey(
         {
             rc = RegOpenKeyExW(
                 list->HKLM,
-                EnumKeyName,
+                REGSTR_PATH_SYSTEMENUM,
                 0, /* Options */
                 KEY_ENUMERATE_SUB_KEYS,
                 &hRootKey);
@@ -4365,7 +4616,7 @@ HKEY WINAPI SetupDiOpenDevRegKey(
                 goto cleanup;
             }
             /* Read the 'Driver' key */
-            rc = RegQueryValueExW(hKey, L"Driver", NULL, &dwRegType, NULL, &dwLength);
+            rc = RegQueryValueExW(hKey, REGSTR_VAL_DRIVER, NULL, &dwRegType, NULL, &dwLength);
             if (rc != ERROR_SUCCESS)
             {
                 SetLastError(rc);
@@ -4382,7 +4633,7 @@ HKEY WINAPI SetupDiOpenDevRegKey(
                 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
                 goto cleanup;
             }
-            rc = RegQueryValueExW(hKey, L"Driver", NULL, &dwRegType, (LPBYTE)DriverKey, &dwLength);
+            rc = RegQueryValueExW(hKey, REGSTR_VAL_DRIVER, NULL, &dwRegType, (LPBYTE)DriverKey, &dwLength);
             if (rc != ERROR_SUCCESS)
             {
                 SetLastError(rc);
@@ -4393,7 +4644,7 @@ HKEY WINAPI SetupDiOpenDevRegKey(
             /* Need to open the driver key */
             rc = RegOpenKeyExW(
                 list->HKLM,
-                ControlClass,
+                REGSTR_PATH_CLASS_NT,
                 0, /* Options */
                 KEY_ENUMERATE_SUB_KEYS,
                 &hRootKey);
@@ -5464,7 +5715,7 @@ SetupDiOpenDeviceInfoW(
             /* Open supposed registry key */
             rc = RegOpenKeyExW(
                 list->HKLM,
-                EnumKeyName,
+                REGSTR_PATH_SYSTEMENUM,
                 0, /* Options */
                 KEY_ENUMERATE_SUB_KEYS,
                 &hEnumKey);
@@ -6160,6 +6411,170 @@ SetupDiGetDriverInfoDetailW(
     return ret;
 }
 
+/* Return the current hardware profile id, or -1 if error */
+static DWORD
+GetCurrentHwProfile(
+    IN HDEVINFO DeviceInfoSet)
+{
+    HKEY hKey = INVALID_HANDLE_VALUE;
+    DWORD dwRegType, dwLength;
+    DWORD hwProfile;
+    LONG rc;
+    DWORD ret = (DWORD)-1;
+
+    rc = RegOpenKeyExW(
+        ((struct DeviceInfoSet *)DeviceInfoSet)->HKLM,
+        REGSTR_PATH_IDCONFIGDB,
+        0, /* Options */
+        KEY_QUERY_VALUE,
+        &hKey);
+    if (rc != ERROR_SUCCESS)
+    {
+        SetLastError(rc);
+        goto cleanup;
+    }
+
+    dwLength = sizeof(DWORD);
+    rc = RegQueryValueExW(
+        hKey,
+        REGSTR_VAL_CURRENTCONFIG,
+        NULL,
+        &dwRegType,
+        (LPBYTE)&hwProfile, &dwLength);
+    if (rc != ERROR_SUCCESS)
+    {
+        SetLastError(rc);
+        goto cleanup;
+    }
+    else if (dwRegType != REG_DWORD || dwLength != sizeof(DWORD))
+    {
+        SetLastError(ERROR_GEN_FAILURE);
+        goto cleanup;
+    }
+
+    ret = hwProfile;
+
+cleanup:
+    if (hKey != INVALID_HANDLE_VALUE)
+        RegCloseKey(hKey);
+
+    return hwProfile;
+}
+
+/***********************************************************************
+ *             SetupDiChangeState (SETUPAPI.@)
+ */
+static BOOL StartDevice(VOID) { FIXME("Stub"); return TRUE; }
+static BOOL StopDevice(VOID) { FIXME("Stub"); return TRUE; }
+BOOL WINAPI
+SetupDiChangeState(
+    IN HDEVINFO DeviceInfoSet,
+    IN OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
+{
+    PSP_PROPCHANGE_PARAMS PropChange;
+    HKEY hKey = INVALID_HANDLE_VALUE;
+    LPCWSTR RegistryValueName;
+    DWORD dwConfigFlags, dwLength, dwRegType;
+    LONG rc;
+    BOOL ret = FALSE;
+
+    TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
+
+    if (!DeviceInfoData)
+        PropChange = ((struct DeviceInfoSet *)DeviceInfoSet)->ClassInstallParams.PropChange;
+    else
+        PropChange = ((struct DeviceInfoElement *)DeviceInfoData->Reserved)->ClassInstallParams.PropChange;
+    if (!PropChange)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        goto cleanup;
+    }
+
+    if (PropChange->Scope == DICS_FLAG_GLOBAL)
+        RegistryValueName = REGSTR_VAL_CONFIGFLAGS;
+    else
+        RegistryValueName = REGSTR_VAL_CSCONFIGFLAGS;
+
+    switch (PropChange->StateChange)
+    {
+        case DICS_ENABLE:
+        case DICS_DISABLE:
+        {
+            /* Enable/disable device in registry */
+            hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, PropChange->Scope, PropChange->HwProfile, DIREG_DEV, KEY_QUERY_VALUE | KEY_SET_VALUE);
+            if (hKey == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND)
+                hKey = SetupDiCreateDevRegKey(DeviceInfoSet, DeviceInfoData, PropChange->Scope, PropChange->HwProfile, DIREG_DEV, NULL, NULL);
+            if (hKey == INVALID_HANDLE_VALUE)
+                break;
+            dwLength = sizeof(DWORD);
+            rc = RegQueryValueExW(
+                hKey,
+                RegistryValueName,
+                NULL,
+                &dwRegType,
+                (LPBYTE)&dwConfigFlags, &dwLength);
+            if (rc == ERROR_FILE_NOT_FOUND)
+                dwConfigFlags = 0;
+            else if (rc != ERROR_SUCCESS)
+            {
+                SetLastError(rc);
+                goto cleanup;
+            }
+            else if (dwRegType != REG_DWORD || dwLength != sizeof(DWORD))
+            {
+                SetLastError(ERROR_GEN_FAILURE);
+                goto cleanup;
+            }
+            if (PropChange->StateChange == DICS_ENABLE)
+                dwConfigFlags &= ~(PropChange->Scope == DICS_FLAG_GLOBAL ? CONFIGFLAG_DISABLED : CSCONFIGFLAG_DISABLED);
+            else
+                dwConfigFlags |= (PropChange->Scope == DICS_FLAG_GLOBAL ? CONFIGFLAG_DISABLED : CSCONFIGFLAG_DISABLED);
+            rc = RegSetValueEx(
+                hKey,
+                RegistryValueName,
+                0,
+                REG_DWORD,
+                (LPBYTE)&dwConfigFlags, sizeof(DWORD));
+            if (rc != ERROR_SUCCESS)
+            {
+                SetLastError(rc);
+                goto cleanup;
+            }
+
+            /* Enable/disable device if needed */
+            if (PropChange->Scope == DICS_FLAG_GLOBAL
+                || PropChange->HwProfile == 0
+                || PropChange->HwProfile == GetCurrentHwProfile(DeviceInfoSet))
+            {
+                if (PropChange->StateChange == DICS_ENABLE)
+                    ret = StartDevice();
+                else
+                    ret = StopDevice();
+            }
+            else
+                ret = TRUE;
+            break;
+        }
+        case DICS_PROPCHANGE:
+        {
+            ret = StopDevice() && StartDevice();
+            break;
+        }
+        default:
+        {
+            FIXME("Unknown StateChange 0x%lx\n", PropChange->StateChange);
+            SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+        }
+    }
+
+cleanup:
+    if (hKey != INVALID_HANDLE_VALUE)
+        RegCloseKey(hKey);
+
+    TRACE("Returning %d\n", ret);
+    return ret;
+}
+
 /***********************************************************************
  *             SetupDiSelectBestCompatDrv (SETUPAPI.@)
  */
@@ -6611,7 +7026,7 @@ SetupDiInstallDevice(
             NULL, 0,
             &RequiredSize);
         if (!Result)
-            goto nextfile;
+            goto nextservice;
         if (RequiredSize > 0)
         {
             /* We got the needed size for the buffer */
@@ -6619,7 +7034,7 @@ SetupDiInstallDevice(
             if (!ServiceName)
             {
                 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-                goto nextfile;
+                goto nextservice;
             }
             Result = SetupGetStringFieldW(
                 &ContextService,
@@ -6627,7 +7042,7 @@ SetupDiInstallDevice(
                 ServiceName, RequiredSize,
                 &RequiredSize);
             if (!Result)
-                goto nextfile;
+                goto nextservice;
         }
         Result = SetupGetIntField(
             &ContextService,
@@ -6653,7 +7068,7 @@ SetupDiInstallDevice(
                 Result = TRUE;
             }
             else
-                goto nextfile;
+                goto nextservice;
         }
         if (RequiredSize > 0)
         {
@@ -6662,7 +7077,7 @@ SetupDiInstallDevice(
             if (!ServiceSection)
             {
                 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-                goto nextfile;
+                goto nextservice;
             }
             Result = SetupGetStringFieldW(
                 &ContextService,
@@ -6670,7 +7085,7 @@ SetupDiInstallDevice(
                 ServiceSection, RequiredSize,
                 &RequiredSize);
             if (!Result)
-                goto nextfile;
+                goto nextservice;
 
             SetLastError(ERROR_SUCCESS);
             Result = SetupInstallServicesFromInfSectionExW(
@@ -6684,7 +7099,7 @@ SetupDiInstallDevice(
             if (GetLastError() == ERROR_SUCCESS_REBOOT_REQUIRED)
                 RebootRequired = TRUE;
         }
-nextfile:
+nextservice:
         HeapFree(GetProcessHeap(), 0, ServiceName);
         HeapFree(GetProcessHeap(), 0, ServiceSection);
         if (!Result)
@@ -6734,15 +7149,15 @@ nextfile:
     TRACE("DeviceDesc      : '%S'\n", SelectedDriver->Info.Description);
     TRACE("Mfg             : '%S'\n", SelectedDriver->Info.MfgName);
     TRACE("Service         : '%S'\n", AssociatedService);
-    rc = RegSetValueEx(hKey, L"Class", 0, REG_SZ, (const BYTE *)ClassName, (wcslen(ClassName) + 1) * sizeof(WCHAR));
+    rc = RegSetValueEx(hKey, REGSTR_VAL_CLASS, 0, REG_SZ, (const BYTE *)ClassName, (wcslen(ClassName) + 1) * sizeof(WCHAR));
     if (rc == ERROR_SUCCESS)
-        rc = RegSetValueEx(hKey, L"ClassGUID", 0, REG_SZ, (const BYTE *)lpFullGuidString, (wcslen(lpFullGuidString) + 1) * sizeof(WCHAR));
+        rc = RegSetValueEx(hKey, REGSTR_VAL_CLASSGUID, 0, REG_SZ, (const BYTE *)lpFullGuidString, (wcslen(lpFullGuidString) + 1) * sizeof(WCHAR));
     if (rc == ERROR_SUCCESS)
-        rc = RegSetValueEx(hKey, L"DeviceDesc", 0, REG_SZ, (const BYTE *)SelectedDriver->Info.Description, (wcslen(SelectedDriver->Info.Description) + 1) * sizeof(WCHAR));
+        rc = RegSetValueEx(hKey, REGSTR_VAL_DEVDESC, 0, REG_SZ, (const BYTE *)SelectedDriver->Info.Description, (wcslen(SelectedDriver->Info.Description) + 1) * sizeof(WCHAR));
     if (rc == ERROR_SUCCESS)
-        rc = RegSetValueEx(hKey, L"Mfg", 0, REG_SZ, (const BYTE *)SelectedDriver->Info.MfgName, (wcslen(SelectedDriver->Info.MfgName) + 1) * sizeof(WCHAR));
+        rc = RegSetValueEx(hKey, REGSTR_VAL_MFG, 0, REG_SZ, (const BYTE *)SelectedDriver->Info.MfgName, (wcslen(SelectedDriver->Info.MfgName) + 1) * sizeof(WCHAR));
     if (rc == ERROR_SUCCESS && *AssociatedService)
-        rc = RegSetValueEx(hKey, L"Service", 0, REG_SZ, (const BYTE *)AssociatedService, (wcslen(AssociatedService) + 1) * sizeof(WCHAR));
+        rc = RegSetValueEx(hKey, REGSTR_VAL_SERVICE, 0, REG_SZ, (const BYTE *)AssociatedService, (wcslen(AssociatedService) + 1) * sizeof(WCHAR));
     if (rc != ERROR_SUCCESS)
     {
        SetLastError(rc);