[SETUPAPI]
[reactos.git] / reactos / dll / win32 / setupapi / devinst.c
index c87811f..c090132 100644 (file)
@@ -134,12 +134,13 @@ CheckSectionValid(
     OUT PDWORD ScoreSuiteMask)
 {
     LPWSTR Section = NULL;
-    LPCWSTR pExtensionPlatform, pExtensionArchitecture;
+    //LPCWSTR pExtensionPlatform;
+    LPCWSTR pExtensionArchitecture;
     LPWSTR Fields[6];
     DWORD i;
     BOOL ret = FALSE;
 
-    static const WCHAR ExtensionPlatformNone[]  = {'.',0};
+    //static const WCHAR ExtensionPlatformNone[]  = {'.',0};
     static const WCHAR ExtensionPlatformNT[]  = {'.','N','T',0};
     static const WCHAR ExtensionPlatformWindows[]  = {'.','W','i','n',0};
 
@@ -167,14 +168,14 @@ CheckSectionValid(
     switch (PlatformInfo->Platform)
     {
         case VER_PLATFORM_WIN32_WINDOWS:
-            pExtensionPlatform = ExtensionPlatformWindows;
+            //pExtensionPlatform = ExtensionPlatformWindows;
             break;
         case VER_PLATFORM_WIN32_NT:
-            pExtensionPlatform = ExtensionPlatformNT;
+            //pExtensionPlatform = ExtensionPlatformNT;
             break;
         default:
             ERR("Unknown platform 0x%lx\n", PlatformInfo->Platform);
-            pExtensionPlatform = ExtensionPlatformNone;
+            //pExtensionPlatform = ExtensionPlatformNone;
             break;
     }
     switch (PlatformInfo->ProcessorArchitecture)
@@ -755,104 +756,104 @@ BOOL WINAPI SetupDiBuildClassInfoListExW(
                                             Reserved);
     if (hClassesKey == INVALID_HANDLE_VALUE)
     {
-       return FALSE;
+        return FALSE;
     }
 
     for (dwIndex = 0; ; dwIndex++)
     {
-       dwLength = 40;
-       lError = RegEnumKeyExW(hClassesKey,
-                              dwIndex,
-                              szKeyName,
-                              &dwLength,
-                              NULL,
-                              NULL,
-                              NULL,
-                              NULL);
-       TRACE("RegEnumKeyExW() returns %d\n", lError);
-       if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)
-       {
-           TRACE("Key name: %s\n", debugstr_w(szKeyName));
-
-           if (RegOpenKeyExW(hClassesKey,
-                             szKeyName,
-                             0,
-                             KEY_QUERY_VALUE,
-                             &hClassKey))
-           {
-               RegCloseKey(hClassesKey);
-               return FALSE;
-           }
-
-           if (!RegQueryValueExW(hClassKey,
-                                 REGSTR_VAL_NOUSECLASS,
-                                 NULL,
-                                 NULL,
-                                 NULL,
-                                 NULL))
-           {
-               TRACE("'NoUseClass' value found!\n");
-               RegCloseKey(hClassKey);
-               continue;
-           }
-
-           if ((Flags & DIBCI_NOINSTALLCLASS) &&
-               (!RegQueryValueExW(hClassKey,
-                                  REGSTR_VAL_NOINSTALLCLASS,
-                                  NULL,
-                                  NULL,
-                                  NULL,
-                                  NULL)))
-           {
-               TRACE("'NoInstallClass' value found!\n");
-               RegCloseKey(hClassKey);
-               continue;
-           }
-
-           if ((Flags & DIBCI_NODISPLAYCLASS) &&
-               (!RegQueryValueExW(hClassKey,
-                                  REGSTR_VAL_NODISPLAYCLASS,
-                                  NULL,
-                                  NULL,
-                                  NULL,
-                                  NULL)))
-           {
-               TRACE("'NoDisplayClass' value found!\n");
-               RegCloseKey(hClassKey);
-               continue;
-           }
-
-           RegCloseKey(hClassKey);
-
-           TRACE("Guid: %s\n", debugstr_w(szKeyName));
-           if (dwGuidListIndex < ClassGuidListSize)
-           {
-               if (szKeyName[0] == '{' && szKeyName[37] == '}')
-               {
-                   szKeyName[37] = 0;
-               }
-               TRACE("Guid: %p\n", &szKeyName[1]);
-
-               UuidFromStringW(&szKeyName[1],
-                               &ClassGuidList[dwGuidListIndex]);
-           }
-
-           dwGuidListIndex++;
-       }
-
-       if (lError != ERROR_SUCCESS)
-           break;
+        dwLength = 40;
+        lError = RegEnumKeyExW(hClassesKey,
+                               dwIndex,
+                               szKeyName,
+                               &dwLength,
+                               NULL,
+                               NULL,
+                               NULL,
+                               NULL);
+        TRACE("RegEnumKeyExW() returns %d\n", lError);
+        if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)
+        {
+            TRACE("Key name: %s\n", debugstr_w(szKeyName));
+
+            if (RegOpenKeyExW(hClassesKey,
+                              szKeyName,
+                              0,
+                              KEY_QUERY_VALUE,
+                              &hClassKey))
+            {
+                RegCloseKey(hClassesKey);
+                return FALSE;
+            }
+
+            if (!RegQueryValueExW(hClassKey,
+                                  REGSTR_VAL_NOUSECLASS,
+                                  NULL,
+                                  NULL,
+                                  NULL,
+                                  NULL))
+            {
+                TRACE("'NoUseClass' value found!\n");
+                RegCloseKey(hClassKey);
+                continue;
+            }
+
+            if ((Flags & DIBCI_NOINSTALLCLASS) &&
+                (!RegQueryValueExW(hClassKey,
+                                   REGSTR_VAL_NOINSTALLCLASS,
+                                   NULL,
+                                   NULL,
+                                   NULL,
+                                   NULL)))
+            {
+                TRACE("'NoInstallClass' value found!\n");
+                RegCloseKey(hClassKey);
+                continue;
+            }
+
+            if ((Flags & DIBCI_NODISPLAYCLASS) &&
+                (!RegQueryValueExW(hClassKey,
+                                   REGSTR_VAL_NODISPLAYCLASS,
+                                   NULL,
+                                   NULL,
+                                   NULL,
+                                   NULL)))
+            {
+                TRACE("'NoDisplayClass' value found!\n");
+                RegCloseKey(hClassKey);
+                continue;
+            }
+
+            RegCloseKey(hClassKey);
+
+            TRACE("Guid: %s\n", debugstr_w(szKeyName));
+            if (dwGuidListIndex < ClassGuidListSize)
+            {
+                if (szKeyName[0] == '{' && szKeyName[37] == '}')
+                {
+                    szKeyName[37] = 0;
+                }
+                TRACE("Guid: %p\n", &szKeyName[1]);
+
+                UuidFromStringW(&szKeyName[1],
+                                &ClassGuidList[dwGuidListIndex]);
+            }
+
+            dwGuidListIndex++;
+        }
+
+        if (lError != ERROR_SUCCESS)
+            break;
     }
 
     RegCloseKey(hClassesKey);
 
     if (RequiredSize != NULL)
-       *RequiredSize = dwGuidListIndex;
+        *RequiredSize = dwGuidListIndex;
 
     if (ClassGuidListSize < dwGuidListIndex)
     {
-       SetLastError(ERROR_INSUFFICIENT_BUFFER);
-       return FALSE;
+        SetLastError(ERROR_INSUFFICIENT_BUFFER);
+        return FALSE;
     }
 
     return TRUE;
@@ -867,9 +868,9 @@ BOOL WINAPI SetupDiClassGuidsFromNameA(
         DWORD ClassGuidListSize,
         PDWORD RequiredSize)
 {
-  return SetupDiClassGuidsFromNameExA(ClassName, ClassGuidList,
-                                      ClassGuidListSize, RequiredSize,
-                                      NULL, NULL);
+    return SetupDiClassGuidsFromNameExA(ClassName, ClassGuidList,
+                                        ClassGuidListSize, RequiredSize,
+                                        NULL, NULL);
 }
 
 /***********************************************************************
@@ -881,9 +882,9 @@ BOOL WINAPI SetupDiClassGuidsFromNameW(
         DWORD ClassGuidListSize,
         PDWORD RequiredSize)
 {
-  return SetupDiClassGuidsFromNameExW(ClassName, ClassGuidList,
-                                      ClassGuidListSize, RequiredSize,
-                                      NULL, NULL);
+    return SetupDiClassGuidsFromNameExW(ClassName, ClassGuidList,
+                                        ClassGuidListSize, RequiredSize,
+                                        NULL, NULL);
 }
 
 /***********************************************************************
@@ -958,7 +959,7 @@ BOOL WINAPI SetupDiClassGuidsFromNameExW(
         ClassGuidListSize, RequiredSize, debugstr_w(MachineName), Reserved);
 
     if (!ClassName || !RequiredSize)
-     {
+    {
         SetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
     }
@@ -967,7 +968,7 @@ BOOL WINAPI SetupDiClassGuidsFromNameExW(
         SetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
     }
-       *RequiredSize = 0;
+    *RequiredSize = 0;
 
     hClassesKey = SetupDiOpenClassRegKeyExW(NULL,
                                             KEY_ENUMERATE_SUB_KEYS,
@@ -976,82 +977,82 @@ BOOL WINAPI SetupDiClassGuidsFromNameExW(
                                             Reserved);
     if (hClassesKey == INVALID_HANDLE_VALUE)
     {
-       return FALSE;
+        return FALSE;
     }
 
     for (dwIndex = 0; ; dwIndex++)
     {
-       dwLength = 40;
-       lError = RegEnumKeyExW(hClassesKey,
-                              dwIndex,
-                              szKeyName,
-                              &dwLength,
-                              NULL,
-                              NULL,
-                              NULL,
-                              NULL);
-       TRACE("RegEnumKeyExW() returns %d\n", lError);
-       if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)
-       {
-           TRACE("Key name: %p\n", szKeyName);
-
-           if (RegOpenKeyExW(hClassesKey,
-                             szKeyName,
-                             0,
-                             KEY_QUERY_VALUE,
-                             &hClassKey))
-           {
-               RegCloseKey(hClassesKey);
-               return FALSE;
-           }
-
-           dwLength = MAX_CLASS_NAME_LEN * sizeof(WCHAR);
-           if (!RegQueryValueExW(hClassKey,
-                                 Class,
-                                 NULL,
-                                 NULL,
-                                 (LPBYTE)szClassName,
-                                 &dwLength))
-           {
-               TRACE("Class name: %p\n", szClassName);
-
-               if (strcmpiW(szClassName, ClassName) == 0)
-               {
-                   TRACE("Found matching class name\n");
-
-                   TRACE("Guid: %p\n", szKeyName);
-                   if (dwGuidListIndex < ClassGuidListSize)
-                   {
-                       if (szKeyName[0] == '{' && szKeyName[37] == '}')
-                       {
-                           szKeyName[37] = 0;
-                       }
-                       TRACE("Guid: %p\n", &szKeyName[1]);
-
-                       UuidFromStringW(&szKeyName[1],
-                                       &ClassGuidList[dwGuidListIndex]);
-                   }
-
-                   dwGuidListIndex++;
-               }
-           }
-
-           RegCloseKey(hClassKey);
-       }
-
-       if (lError != ERROR_SUCCESS)
-           break;
+        dwLength = 40;
+        lError = RegEnumKeyExW(hClassesKey,
+                               dwIndex,
+                               szKeyName,
+                               &dwLength,
+                               NULL,
+                               NULL,
+                               NULL,
+                               NULL);
+        TRACE("RegEnumKeyExW() returns %d\n", lError);
+        if (lError == ERROR_SUCCESS || lError == ERROR_MORE_DATA)
+        {
+            TRACE("Key name: %p\n", szKeyName);
+
+            if (RegOpenKeyExW(hClassesKey,
+                              szKeyName,
+                              0,
+                              KEY_QUERY_VALUE,
+                              &hClassKey))
+            {
+                RegCloseKey(hClassesKey);
+                return FALSE;
+            }
+
+            dwLength = MAX_CLASS_NAME_LEN * sizeof(WCHAR);
+            if (!RegQueryValueExW(hClassKey,
+                                  Class,
+                                  NULL,
+                                  NULL,
+                                  (LPBYTE)szClassName,
+                                  &dwLength))
+            {
+                TRACE("Class name: %p\n", szClassName);
+
+                if (strcmpiW(szClassName, ClassName) == 0)
+                {
+                    TRACE("Found matching class name\n");
+
+                    TRACE("Guid: %p\n", szKeyName);
+                    if (dwGuidListIndex < ClassGuidListSize)
+                    {
+                        if (szKeyName[0] == '{' && szKeyName[37] == '}')
+                        {
+                            szKeyName[37] = 0;
+                        }
+                        TRACE("Guid: %p\n", &szKeyName[1]);
+
+                        UuidFromStringW(&szKeyName[1],
+                                        &ClassGuidList[dwGuidListIndex]);
+                    }
+
+                    dwGuidListIndex++;
+                }
+            }
+
+            RegCloseKey(hClassKey);
+        }
+
+        if (lError != ERROR_SUCCESS)
+            break;
     }
 
     RegCloseKey(hClassesKey);
 
     if (RequiredSize != NULL)
-       *RequiredSize = dwGuidListIndex;
+        *RequiredSize = dwGuidListIndex;
 
     if (ClassGuidListSize < dwGuidListIndex)
     {
-       SetLastError(ERROR_INSUFFICIENT_BUFFER);
-       return FALSE;
+        SetLastError(ERROR_INSUFFICIENT_BUFFER);
+        return FALSE;
     }
 
     return TRUE;
@@ -1066,9 +1067,9 @@ BOOL WINAPI SetupDiClassNameFromGuidA(
         DWORD ClassNameSize,
         PDWORD RequiredSize)
 {
-  return SetupDiClassNameFromGuidExA(ClassGuid, ClassName,
-                                     ClassNameSize, RequiredSize,
-                                     NULL, NULL);
+    return SetupDiClassNameFromGuidExA(ClassGuid, ClassName,
+                                       ClassNameSize, RequiredSize,
+                                       NULL, NULL);
 }
 
 /***********************************************************************
@@ -1080,9 +1081,9 @@ BOOL WINAPI SetupDiClassNameFromGuidW(
         DWORD ClassNameSize,
         PDWORD RequiredSize)
 {
-  return SetupDiClassNameFromGuidExW(ClassGuid, ClassName,
-                                     ClassNameSize, RequiredSize,
-                                     NULL, NULL);
+    return SetupDiClassNameFromGuidExW(ClassGuid, ClassName,
+                                       ClassNameSize, RequiredSize,
+                                       NULL, NULL);
 }
 
 /***********************************************************************
@@ -1103,11 +1104,11 @@ BOOL WINAPI SetupDiClassNameFromGuidExA(
     if (MachineName)
         MachineNameW = pSetupMultiByteToUnicode(MachineName, CP_ACP);
     ret = SetupDiClassNameFromGuidExW(ClassGuid, ClassNameW, MAX_CLASS_NAME_LEN,
-     RequiredSize, MachineNameW, Reserved);
+                                      RequiredSize, MachineNameW, Reserved);
     if (ret)
     {
         int len = WideCharToMultiByte(CP_ACP, 0, ClassNameW, -1, ClassName,
-         ClassNameSize, NULL, NULL);
+                                      ClassNameSize, NULL, NULL);
         if (len == 0 || len > ClassNameSize)
         {
             SetLastError(ERROR_INSUFFICIENT_BUFFER);
@@ -1213,9 +1214,9 @@ BOOL WINAPI SetupDiClassNameFromGuidExW(
  */
 HDEVINFO WINAPI
 SetupDiCreateDeviceInfoList(const GUID *ClassGuid,
-                           HWND hwndParent)
+        HWND hwndParent)
 {
-  return SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent, NULL, NULL);
+    return SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent, NULL, NULL);
 }
 
 /***********************************************************************
@@ -1223,9 +1224,9 @@ SetupDiCreateDeviceInfoList(const GUID *ClassGuid,
  */
 HDEVINFO WINAPI
 SetupDiCreateDeviceInfoListExA(const GUID *ClassGuid,
-                              HWND hwndParent,
-                              PCSTR MachineName,
-                              PVOID Reserved)
+        HWND hwndParent,
+        PCSTR MachineName,
+        PVOID Reserved)
 {
     LPWSTR MachineNameW = NULL;
     HDEVINFO hDevInfo;
@@ -1267,9 +1268,9 @@ SetupDiCreateDeviceInfoListExA(const GUID *ClassGuid,
  */
 HDEVINFO WINAPI
 SetupDiCreateDeviceInfoListExW(const GUID *ClassGuid,
-                              HWND hwndParent,
-                              PCWSTR MachineName,
-                              PVOID Reserved)
+        HWND hwndParent,
+        PCWSTR MachineName,
+        PVOID Reserved)
 {
     struct DeviceInfoSet *list = NULL;
     DWORD size = FIELD_OFFSET(struct DeviceInfoSet, szData);
@@ -1288,7 +1289,10 @@ SetupDiCreateDeviceInfoListExW(const GUID *ClassGuid,
             SetLastError(ERROR_INVALID_MACHINENAME);
             goto cleanup;
         }
-        size += (len + 3) * sizeof(WCHAR);
+        if(len > 0)
+            size += (len + 3) * sizeof(WCHAR);
+        else
+            MachineName = NULL;
     }
 
     if (Reserved != NULL)
@@ -1415,6 +1419,8 @@ HKEY WINAPI SetupDiCreateDevRegKeyW(
     LPWSTR DriverKey = NULL; /* {GUID}\Index */
     LPWSTR pDeviceInstance; /* Points into DriverKey, on the Index field */
     DWORD Index; /* Index used in the DriverKey name */
+    DWORD dwSize;
+    DWORD Disposition;
     DWORD rc;
     HKEY hHWProfileKey = INVALID_HANDLE_VALUE;
     HKEY hEnumKey = NULL;
@@ -1514,37 +1520,104 @@ HKEY WINAPI SetupDiCreateDevRegKeyW(
         }
         else /* KeyType == DIREG_DRV */
         {
-            if (UuidToStringW((UUID*)&DeviceInfoData->ClassGuid, &lpGuidString) != RPC_S_OK)
-                goto cleanup;
-            /* The driver key is in \System\CurrentControlSet\Control\Class\{GUID}\Index */
-            DriverKey = HeapAlloc(GetProcessHeap(), 0, (strlenW(lpGuidString) + 7) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
-            if (!DriverKey)
-            {
-                SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+            /* Open device key, to read Driver value */
+            hDeviceKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, Scope, HwProfile, DIREG_DEV, KEY_QUERY_VALUE | KEY_SET_VALUE);
+            if (hDeviceKey == INVALID_HANDLE_VALUE)
                 goto cleanup;
-            }
-            DriverKey[0] = '{';
-            strcpyW(&DriverKey[1], lpGuidString);
-            pDeviceInstance = &DriverKey[strlenW(DriverKey)];
-            *pDeviceInstance++ = '}';
-            *pDeviceInstance++ = '\\';
-            rc = RegOpenKeyExW(RootKey,
-                REGSTR_PATH_CLASS_NT,
-                0,
-                KEY_CREATE_SUB_KEY,
-                &hClassKey);
+
+            rc = RegOpenKeyExW(RootKey, REGSTR_PATH_CLASS_NT, 0, KEY_CREATE_SUB_KEY, &hClassKey);
             if (rc != ERROR_SUCCESS)
             {
                 SetLastError(rc);
                 goto cleanup;
             }
 
-            /* Try all values for Index between 0 and 9999 */
-            Index = 0;
-            while (Index <= 9999)
+            rc = RegQueryValueExW(hDeviceKey, REGSTR_VAL_DRIVER, NULL, NULL, NULL, &dwSize);
+            if (rc != ERROR_SUCCESS)
+            {
+                /* Create a new driver key */
+
+                if (UuidToStringW((UUID*)&DeviceInfoData->ClassGuid, &lpGuidString) != RPC_S_OK)
+                    goto cleanup;
+
+                /* The driver key is in \System\CurrentControlSet\Control\Class\{GUID}\Index */
+                DriverKey = HeapAlloc(GetProcessHeap(), 0, (strlenW(lpGuidString) + 7) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
+                if (!DriverKey)
+                {
+                    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+                    goto cleanup;
+                }
+
+                DriverKey[0] = '{';
+                strcpyW(&DriverKey[1], lpGuidString);
+                pDeviceInstance = &DriverKey[strlenW(DriverKey)];
+                *pDeviceInstance++ = '}';
+                *pDeviceInstance++ = '\\';
+
+                /* Try all values for Index between 0 and 9999 */
+                Index = 0;
+                while (Index <= 9999)
+                {
+                    sprintfW(pDeviceInstance, InstanceKeyFormat, Index);
+                    rc = RegCreateKeyExW(hClassKey,
+                        DriverKey,
+                        0,
+                        NULL,
+                        REG_OPTION_NON_VOLATILE,
+#if _WIN32_WINNT >= 0x502
+                        KEY_READ | KEY_WRITE,
+#else
+                        KEY_ALL_ACCESS,
+#endif
+                        NULL,
+                        &hKey,
+                        &Disposition);
+                    if (rc != ERROR_SUCCESS)
+                    {
+                        SetLastError(rc);
+                        goto cleanup;
+                    }
+                    if (Disposition == REG_CREATED_NEW_KEY)
+                        break;
+                    RegCloseKey(hKey);
+                    hKey = NULL;
+                    Index++;
+                }
+
+                if (Index > 9999)
+                {
+                    /* Unable to create more than 9999 devices within the same class */
+                    SetLastError(ERROR_GEN_FAILURE);
+                    goto cleanup;
+                }
+
+                /* Write the new Driver value */
+                rc = RegSetValueExW(hDeviceKey, REGSTR_VAL_DRIVER, 0, REG_SZ, (const BYTE *)DriverKey, (strlenW(DriverKey) + 1) * sizeof(WCHAR));
+                if (rc != ERROR_SUCCESS)
+                {
+                    SetLastError(rc);
+                    goto cleanup;
+                }
+
+            }
+            else
             {
-                DWORD Disposition;
-                sprintfW(pDeviceInstance, InstanceKeyFormat, Index);
+                /* Open the existing driver key */
+
+                DriverKey = HeapAlloc(GetProcessHeap(), 0, dwSize);
+                if (!DriverKey)
+                {
+                    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+                    goto cleanup;
+                }
+
+                rc = RegQueryValueExW(hDeviceKey, REGSTR_VAL_DRIVER, NULL, NULL, (LPBYTE)DriverKey, &dwSize);
+                if (rc != ERROR_SUCCESS)
+                {
+                    SetLastError(rc);
+                    goto cleanup;
+                }
+
                 rc = RegCreateKeyExW(hClassKey,
                     DriverKey,
                     0,
@@ -1563,28 +1636,6 @@ HKEY WINAPI SetupDiCreateDevRegKeyW(
                     SetLastError(rc);
                     goto cleanup;
                 }
-                if (Disposition == REG_CREATED_NEW_KEY)
-                    break;
-                RegCloseKey(hKey);
-                hKey = NULL;
-                Index++;
-            }
-            if (Index > 9999)
-            {
-                /* Unable to create more than 9999 devices within the same class */
-                SetLastError(ERROR_GEN_FAILURE);
-                goto cleanup;
-            }
-
-            /* Open device key, to write Driver value */
-            hDeviceKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, Scope, HwProfile, DIREG_DEV, KEY_SET_VALUE);
-            if (hDeviceKey == INVALID_HANDLE_VALUE)
-                goto cleanup;
-            rc = RegSetValueExW(hDeviceKey, REGSTR_VAL_DRIVER, 0, REG_SZ, (const BYTE *)DriverKey, (strlenW(DriverKey) + 1) * sizeof(WCHAR));
-            if (rc != ERROR_SUCCESS)
-            {
-                SetLastError(rc);
-                goto cleanup;
             }
         }
 
@@ -1619,13 +1670,13 @@ cleanup:
  *              SetupDiCreateDeviceInfoA (SETUPAPI.@)
  */
 BOOL WINAPI SetupDiCreateDeviceInfoA(
-       HDEVINFO DeviceInfoSet,
-       PCSTR DeviceName,
-       CONST GUID *ClassGuid,
-       PCSTR DeviceDescription,
-       HWND hwndParent,
-       DWORD CreationFlags,
-       PSP_DEVINFO_DATA DeviceInfoData)
+        HDEVINFO DeviceInfoSet,
+        PCSTR DeviceName,
+        CONST GUID *ClassGuid,
+        PCSTR DeviceDescription,
+        HWND hwndParent,
+        DWORD CreationFlags,
+        PSP_DEVINFO_DATA DeviceInfoData)
 {
     BOOL ret;
     LPWSTR DeviceNameW = NULL;
@@ -1661,17 +1712,20 @@ BOOL WINAPI SetupDiCreateDeviceInfoA(
  *              SetupDiCreateDeviceInfoW (SETUPAPI.@)
  */
 BOOL WINAPI SetupDiCreateDeviceInfoW(
-       HDEVINFO DeviceInfoSet,
-       PCWSTR DeviceName,
-       CONST GUID *ClassGuid,
-       PCWSTR DeviceDescription,
-       HWND hwndParent,
-       DWORD CreationFlags,
-       PSP_DEVINFO_DATA DeviceInfoData)
+        HDEVINFO DeviceInfoSet,
+        PCWSTR DeviceName,
+        CONST GUID *ClassGuid,
+        PCWSTR DeviceDescription,
+        HWND hwndParent,
+        DWORD CreationFlags,
+        PSP_DEVINFO_DATA DeviceInfoData)
 {
     struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
+    struct DeviceInfo *deviceInfo = NULL;
     BOOL ret = FALSE;
-    SP_DEVINFO_DATA DevInfo;
+    CONFIGRET cr;
+    DEVINST RootDevInst;
+    DEVINST DevInst;
 
     TRACE("%p %s %s %s %p %x %p\n", DeviceInfoSet, debugstr_w(DeviceName),
         debugstr_guid(ClassGuid), debugstr_w(DeviceDescription),
@@ -1710,59 +1764,62 @@ BOOL WINAPI SetupDiCreateDeviceInfoW(
         return FALSE;
     }
 
-        if (CreationFlags & DICD_GENERATE_ID)
-        {
-            /* Generate a new unique ID for this device */
-            SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-            FIXME("not implemented\n");
-        }
+    /* Get the root device instance */
+    cr = CM_Locate_DevInst_ExW(&RootDevInst,
+                               NULL,
+                               CM_LOCATE_DEVINST_NORMAL,
+                               set->hMachine);
+    if (cr != CR_SUCCESS)
+    {
+        SetLastError(ERROR_INVALID_DATA);
+        return FALSE;
+    }
+
+    /* Create the new device instance */
+    cr = CM_Create_DevInst_ExW(&DevInst,
+                               (DEVINSTID)DeviceName,
+                               RootDevInst,
+                               0,
+                               set->hMachine);
+    if (cr != CR_SUCCESS)
+    {
+        SetLastError(ERROR_INVALID_DATA);
+        return FALSE;
+    }
+
+    if (CreateDeviceInfo(set, DeviceName, ClassGuid, &deviceInfo))
+    {
+        InsertTailList(&set->ListHead, &deviceInfo->ListEntry);
+
+        if (!DeviceInfoData)
+            ret = TRUE;
         else
         {
-            /* Device name is fully qualified. Try to open it */
-            BOOL rc;
-
-            DevInfo.cbSize = sizeof(SP_DEVINFO_DATA);
-            rc = SetupDiOpenDeviceInfoW(
-                DeviceInfoSet,
-                DeviceName,
-                NULL, /* hwndParent */
-                CreationFlags & DICD_INHERIT_CLASSDRVS ? DIOD_INHERIT_CLASSDRVS : 0,
-                &DevInfo);
-
-            if (rc)
+            if (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
             {
-                /* SetupDiOpenDeviceInfoW has already added
-                 * the device info to the device info set
-                 */
-                SetLastError(ERROR_DEVINST_ALREADY_EXISTS);
+                SetLastError(ERROR_INVALID_USER_BUFFER);
             }
-            else if (GetLastError() == ERROR_NO_SUCH_DEVINST)
+            else
             {
-                struct DeviceInfo *deviceInfo;
+                memcpy(&DeviceInfoData->ClassGuid, ClassGuid, sizeof(GUID));
+                DeviceInfoData->DevInst = deviceInfo->dnDevInst;
+                DeviceInfoData->Reserved = (ULONG_PTR)deviceInfo;
+                ret = TRUE;
+            }
+        }
+    }
 
-                if (CreateDeviceInfo(set, DeviceName, ClassGuid, &deviceInfo))
-                {
-                    InsertTailList(&set->ListHead, &deviceInfo->ListEntry);
+    if (ret == FALSE)
+    {
+        if (deviceInfo != NULL)
+        {
+            /* Remove deviceInfo from List */
+            RemoveEntryList(&deviceInfo->ListEntry);
 
-                    if (!DeviceInfoData)
-                        ret = TRUE;
-                    else
-                    {
-                        if (DeviceInfoData->cbSize != sizeof(PSP_DEVINFO_DATA))
-                        {
-                            SetLastError(ERROR_INVALID_USER_BUFFER);
-                        }
-                        else
-                        {
-                            memcpy(&DeviceInfoData->ClassGuid, ClassGuid, sizeof(GUID));
-                            DeviceInfoData->DevInst = deviceInfo->dnDevInst;
-                            DeviceInfoData->Reserved = (ULONG_PTR)deviceInfo;
-                            ret = TRUE;
-                        }
-                    }
-                }
-            }
+            /* Destroy deviceInfo */
+            DestroyDeviceInfo(deviceInfo);
         }
+    }
 
     TRACE("Returning %d\n", ret);
     return ret;
@@ -1861,18 +1918,18 @@ BOOL WINAPI SetupDiEnumDeviceInfo(
  *             SetupDiGetDeviceInstanceIdA (SETUPAPI.@)
  */
 BOOL WINAPI SetupDiGetDeviceInstanceIdA(
-       HDEVINFO DeviceInfoSet,
-       PSP_DEVINFO_DATA DeviceInfoData,
-       PSTR DeviceInstanceId,
-       DWORD DeviceInstanceIdSize,
-       PDWORD RequiredSize)
+        HDEVINFO DeviceInfoSet,
+        PSP_DEVINFO_DATA DeviceInfoData,
+        PSTR DeviceInstanceId,
+        DWORD DeviceInstanceIdSize,
+        PDWORD RequiredSize)
 {
     BOOL ret = FALSE;
     DWORD size;
     PWSTR instanceId;
 
     TRACE("%p %p %p %d %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstanceId,
-           DeviceInstanceIdSize, RequiredSize);
+            DeviceInstanceIdSize, RequiredSize);
 
     if (!DeviceInstanceId && DeviceInstanceIdSize > 0)
     {
@@ -1930,17 +1987,17 @@ BOOL WINAPI SetupDiGetDeviceInstanceIdA(
  *             SetupDiGetDeviceInstanceIdW (SETUPAPI.@)
  */
 BOOL WINAPI SetupDiGetDeviceInstanceIdW(
-       HDEVINFO DeviceInfoSet,
-       PSP_DEVINFO_DATA DeviceInfoData,
-       PWSTR DeviceInstanceId,
-       DWORD DeviceInstanceIdSize,
-       PDWORD RequiredSize)
+        HDEVINFO DeviceInfoSet,
+        PSP_DEVINFO_DATA DeviceInfoData,
+        PWSTR DeviceInstanceId,
+        DWORD DeviceInstanceIdSize,
+        PDWORD RequiredSize)
 {
     struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
     struct DeviceInfo *devInfo;
 
     TRACE("%p %p %p %d %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstanceId,
-           DeviceInstanceIdSize, RequiredSize);
+            DeviceInstanceIdSize, RequiredSize);
 
     if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
     {
@@ -2020,14 +2077,14 @@ BOOL WINAPI SetupDiGetActualSectionToInstallW(
  */
 BOOL WINAPI
 SetupDiGetActualSectionToInstallExA(
-    IN HINF InfHandle,
-    IN PCSTR InfSectionName,
-    IN PSP_ALTPLATFORM_INFO AlternatePlatformInfo OPTIONAL,
-    OUT PSTR InfSectionWithExt OPTIONAL,
-    IN DWORD InfSectionWithExtSize,
-    OUT PDWORD RequiredSize OPTIONAL,
-    OUT PSTR* Extension OPTIONAL,
-    IN PVOID Reserved)
+        IN HINF InfHandle,
+        IN PCSTR InfSectionName,
+        IN PSP_ALTPLATFORM_INFO AlternatePlatformInfo OPTIONAL,
+        OUT PSTR InfSectionWithExt OPTIONAL,
+        IN DWORD InfSectionWithExtSize,
+        OUT PDWORD RequiredSize OPTIONAL,
+        OUT PSTR* Extension OPTIONAL,
+        IN PVOID Reserved)
 {
     LPWSTR InfSectionNameW = NULL;
     LPWSTR InfSectionWithExtW = NULL;
@@ -2086,9 +2143,9 @@ BOOL WINAPI SetupDiGetClassDescriptionA(
         DWORD ClassDescriptionSize,
         PDWORD RequiredSize)
 {
-  return SetupDiGetClassDescriptionExA(ClassGuid, ClassDescription,
-                                       ClassDescriptionSize,
-                                       RequiredSize, NULL, NULL);
+    return SetupDiGetClassDescriptionExA(ClassGuid, ClassDescription,
+                                         ClassDescriptionSize,
+                                         RequiredSize, NULL, NULL);
 }
 
 /***********************************************************************
@@ -2100,9 +2157,9 @@ BOOL WINAPI SetupDiGetClassDescriptionW(
         DWORD ClassDescriptionSize,
         PDWORD RequiredSize)
 {
-  return SetupDiGetClassDescriptionExW(ClassGuid, ClassDescription,
-                                       ClassDescriptionSize,
-                                       RequiredSize, NULL, NULL);
+    return SetupDiGetClassDescriptionExW(ClassGuid, ClassDescription,
+                                         ClassDescriptionSize,
+                                         RequiredSize, NULL, NULL);
 }
 
 /***********************************************************************
@@ -2259,10 +2316,10 @@ BOOL WINAPI SetupDiGetClassDescriptionExW(
  *             SetupDiGetClassDevsA (SETUPAPI.@)
  */
 HDEVINFO WINAPI SetupDiGetClassDevsA(
-       CONST GUID *class,
-       LPCSTR enumstr,
-       HWND parent,
-       DWORD flags)
+        CONST GUID *class,
+        LPCSTR enumstr,
+        HWND parent,
+        DWORD flags)
 {
     return SetupDiGetClassDevsExA(class, enumstr, parent,
                                   flags, NULL, NULL, NULL);
@@ -2315,10 +2372,10 @@ end:
  *             SetupDiGetClassDevsW (SETUPAPI.@)
  */
 HDEVINFO WINAPI SetupDiGetClassDevsW(
-       CONST GUID *class,
-       LPCWSTR enumstr,
-       HWND parent,
-       DWORD flags)
+        CONST GUID *class,
+        LPCWSTR enumstr,
+        HWND parent,
+        DWORD flags)
 {
     return SetupDiGetClassDevsExW(class, enumstr, parent, flags, NULL, NULL,
             NULL);
@@ -2803,11 +2860,11 @@ BOOL WINAPI SetupDiDeleteDeviceInterfaceRegKey(
  *   Failure: FALSE.  Call GetLastError() for more info.
  */
 BOOL WINAPI SetupDiEnumDeviceInterfaces(
-       HDEVINFO DeviceInfoSet,
-       PSP_DEVINFO_DATA DeviceInfoData,
-       CONST GUID * InterfaceClassGuid,
-       DWORD MemberIndex,
-       PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
+        HDEVINFO DeviceInfoSet,
+        PSP_DEVINFO_DATA DeviceInfoData,
+        CONST GUID * InterfaceClassGuid,
+        DWORD MemberIndex,
+        PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
 {
     struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
     BOOL ret = FALSE;
@@ -2940,12 +2997,12 @@ BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)
  *             SetupDiGetDeviceInterfaceDetailA (SETUPAPI.@)
  */
 BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(
-      HDEVINFO DeviceInfoSet,
-      PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
-      PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData,
-      DWORD DeviceInterfaceDetailDataSize,
-      PDWORD RequiredSize,
-      PSP_DEVINFO_DATA DeviceInfoData)
+        HDEVINFO DeviceInfoSet,
+        PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
+        PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData,
+        DWORD DeviceInterfaceDetailDataSize,
+        PDWORD RequiredSize,
+        PSP_DEVINFO_DATA DeviceInfoData)
 {
     struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
     PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailDataW = NULL;
@@ -2969,13 +3026,19 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(
         SetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
     }
-    if (DeviceInterfaceDetailData && (DeviceInterfaceDetailData->cbSize <
-            FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath) + 1 ||
-            DeviceInterfaceDetailData->cbSize > sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A)))
+    if (DeviceInterfaceDetailData && (DeviceInterfaceDetailData->cbSize != sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A)))
+    {
+        SetLastError(ERROR_INVALID_USER_BUFFER);
+        return FALSE;
+    }
+
+    if((DeviceInterfaceDetailDataSize != 0) &&
+        (DeviceInterfaceDetailDataSize < (FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath) + sizeof(CHAR))))
     {
         SetLastError(ERROR_INVALID_USER_BUFFER);
         return FALSE;
     }
+
     if (!DeviceInterfaceDetailData && DeviceInterfaceDetailDataSize)
     {
         SetLastError(ERROR_INVALID_USER_BUFFER);
@@ -2992,10 +3055,10 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(
         {
             SetLastError(ERROR_NOT_ENOUGH_MEMORY);
         }
+        DeviceInterfaceDetailDataW->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
     }
     if (!DeviceInterfaceDetailData || (DeviceInterfaceDetailData && DeviceInterfaceDetailDataW))
     {
-        DeviceInterfaceDetailDataW->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
         ret = SetupDiGetDeviceInterfaceDetailW(
             DeviceInfoSet,
             DeviceInterfaceData,
@@ -3007,7 +3070,7 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(
             + FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath);
         if (RequiredSize)
             *RequiredSize = bytesNeeded;
-        if (ret && DeviceInterfaceDetailData && DeviceInterfaceDetailDataSize <= bytesNeeded)
+        if (ret && DeviceInterfaceDetailData && DeviceInterfaceDetailDataSize >= bytesNeeded)
         {
             if (!WideCharToMultiByte(
                 CP_ACP, 0,
@@ -3028,12 +3091,12 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailA(
  *             SetupDiGetDeviceInterfaceDetailW (SETUPAPI.@)
  */
 BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(
-      HDEVINFO DeviceInfoSet,
-      PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
-      PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData,
-      DWORD DeviceInterfaceDetailDataSize,
-      PDWORD RequiredSize,
-      PSP_DEVINFO_DATA DeviceInfoData)
+        HDEVINFO DeviceInfoSet,
+        PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
+        PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData,
+        DWORD DeviceInterfaceDetailDataSize,
+        PDWORD RequiredSize,
+        PSP_DEVINFO_DATA DeviceInfoData)
 {
     struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
     BOOL ret = FALSE;
@@ -3070,7 +3133,8 @@ BOOL WINAPI SetupDiGetDeviceInterfaceDetailW(
         SetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
     }
-    if (DeviceInterfaceDetailData != NULL && DeviceInterfaceDetailDataSize < FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath) + sizeof(WCHAR))
+    if ((DeviceInterfaceDetailData != NULL)
+        && (DeviceInterfaceDetailDataSize < (FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath)) + sizeof(WCHAR)))
     {
         SetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
@@ -3185,14 +3249,13 @@ BOOL WINAPI SetupDiGetDeviceRegistryPropertyA(
         }
     }
 
-    ret = SetupDiGetDeviceRegistryPropertyW(
-        DeviceInfoSet,
-        DeviceInfoData,
-        Property,
-        &RegType,
-        PropertyBufferW,
-        PropertyBufferSizeW,
-        &RequiredSizeW);
+    ret = SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet,
+                                            DeviceInfoData,
+                                            Property,
+                                            &RegType,
+                                            PropertyBufferW,
+                                            PropertyBufferSizeW,
+                                            &RequiredSizeW);
 
     if (ret || GetLastError() == ERROR_INSUFFICIENT_BUFFER)
     {
@@ -3331,11 +3394,11 @@ BOOL WINAPI SetupDiGetDeviceRegistryPropertyW(
  *             SetupDiSetDeviceRegistryPropertyA (SETUPAPI.@)
  */
 BOOL WINAPI SetupDiSetDeviceRegistryPropertyA(
-       HDEVINFO DeviceInfoSet,
-       PSP_DEVINFO_DATA DeviceInfoData,
-       DWORD Property,
-       const BYTE *PropertyBuffer,
-       DWORD PropertyBufferSize)
+        HDEVINFO DeviceInfoSet,
+        PSP_DEVINFO_DATA DeviceInfoData,
+        DWORD Property,
+        const BYTE *PropertyBuffer,
+        DWORD PropertyBufferSize)
 {
     BOOL ret = FALSE;
     struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
@@ -3370,11 +3433,11 @@ BOOL WINAPI SetupDiSetDeviceRegistryPropertyA(
  *             SetupDiSetDeviceRegistryPropertyW (SETUPAPI.@)
  */
 BOOL WINAPI SetupDiSetDeviceRegistryPropertyW(
-       HDEVINFO DeviceInfoSet,
-       PSP_DEVINFO_DATA DeviceInfoData,
-       DWORD Property,
-       const BYTE *PropertyBuffer,
-       DWORD PropertyBufferSize)
+        HDEVINFO DeviceInfoSet,
+        PSP_DEVINFO_DATA DeviceInfoData,
+        DWORD Property,
+        const BYTE *PropertyBuffer,
+        DWORD PropertyBufferSize)
 {
     BOOL ret = FALSE;
     struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
@@ -3401,8 +3464,8 @@ BOOL WINAPI SetupDiSetDeviceRegistryPropertyW(
     if (Property < sizeof(PropertyMap) / sizeof(PropertyMap[0])
         && PropertyMap[Property].nameW)
     {
-       HKEY hKey;
-       LONG l;
+        HKEY hKey;
+        LONG l;
         hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_SET_VALUE);
         if (hKey == INVALID_HANDLE_VALUE)
             return FALSE;
@@ -3487,14 +3550,14 @@ HKEY SETUP_CreateClassKey(HINF hInf)
     HKEY hClassKey;
 
     if (!SetupGetLineTextW(NULL,
-                          hInf,
-                          Version,
-                          ClassGUID,
-                          Buffer,
-                          MAX_PATH,
-                          &RequiredSize))
+                           hInf,
+                           Version,
+                           ClassGUID,
+                           Buffer,
+                           MAX_PATH,
+                           &RequiredSize))
     {
-       return INVALID_HANDLE_VALUE;
+        return INVALID_HANDLE_VALUE;
     }
 
     lstrcpyW(FullBuffer, REGSTR_PATH_CLASS_NT);
@@ -3502,48 +3565,47 @@ HKEY SETUP_CreateClassKey(HINF hInf)
     lstrcatW(FullBuffer, Buffer);
 
     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
-                     FullBuffer,
-                     0,
-                     KEY_SET_VALUE,
-                     &hClassKey))
-    {
-       if (!SetupGetLineTextW(NULL,
-                              hInf,
-                              Version,
-                              Class,
-                              Buffer,
-                              MAX_PATH,
-                              &RequiredSize))
-       {
-           return INVALID_HANDLE_VALUE;
-       }
-
-       if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,
-                           FullBuffer,
-                           0,
-                           NULL,
-                           REG_OPTION_NON_VOLATILE,
-                           KEY_SET_VALUE,
-                           NULL,
-                           &hClassKey,
-                           NULL))
-       {
-           return INVALID_HANDLE_VALUE;
-       }
+                      FullBuffer,
+                      0,
+                      KEY_SET_VALUE,
+                      &hClassKey))
+    {
+        if (!SetupGetLineTextW(NULL,
+                               hInf,
+                               Version,
+                               Class,
+                               Buffer,
+                               MAX_PATH,
+                               &RequiredSize))
+        {
+            return INVALID_HANDLE_VALUE;
+        }
 
+        if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,
+                            FullBuffer,
+                            0,
+                            NULL,
+                            REG_OPTION_NON_VOLATILE,
+                            KEY_SET_VALUE,
+                            NULL,
+                            &hClassKey,
+                            NULL))
+        {
+            return INVALID_HANDLE_VALUE;
+        }
     }
 
     if (RegSetValueExW(hClassKey,
-                      Class,
-                      0,
-                      REG_SZ,
-                      (LPBYTE)Buffer,
-                      RequiredSize * sizeof(WCHAR)))
-    {
-       RegCloseKey(hClassKey);
-       RegDeleteKeyW(HKEY_LOCAL_MACHINE,
-                     FullBuffer);
-       return INVALID_HANDLE_VALUE;
+                       Class,
+                       0,
+                       REG_SZ,
+                       (LPBYTE)Buffer,
+                       RequiredSize * sizeof(WCHAR)))
+    {
+        RegCloseKey(hClassKey);
+        RegDeleteKeyW(HKEY_LOCAL_MACHINE,
+                      FullBuffer);
+        return INVALID_HANDLE_VALUE;
     }
 
     return hClassKey;
@@ -3656,10 +3718,10 @@ HKEY WINAPI SetupDiOpenClassRegKeyExW(
     if (!ClassGuid)
     {
         if ((l = RegOpenKeyExW(HKLM,
-                          lpKeyName,
-                          0,
-                          samDesired,
-                          &hClassesKey)))
+                               lpKeyName,
+                               0,
+                               samDesired,
+                               &hClassesKey)))
         {
             SetLastError(ERROR_INVALID_CLASS);
             hClassesKey = INVALID_HANDLE_VALUE;
@@ -3675,19 +3737,19 @@ HKEY WINAPI SetupDiOpenClassRegKeyExW(
         SETUPDI_GuidToString(ClassGuid, bracedGuidString);
 
         if (!(l = RegOpenKeyExW(HKLM,
-                          lpKeyName,
-                          0,
-                          samDesired,
-                          &hClassesKey)))
+                                lpKeyName,
+                                0,
+                                samDesired,
+                                &hClassesKey)))
         {
-                if (MachineName != NULL)
-                    RegCloseKey(HKLM);
-                
+            if (MachineName != NULL)
+                RegCloseKey(HKLM);
+
             if ((l = RegOpenKeyExW(hClassesKey,
-                              bracedGuidString,
-                              0,
-                              samDesired,
-                              &key)))
+                                   bracedGuidString,
+                                   0,
+                                   samDesired,
+                                   &key)))
             {
                 SetLastError(l);
                 key = INVALID_HANDLE_VALUE;
@@ -3709,10 +3771,10 @@ HKEY WINAPI SetupDiOpenClassRegKeyExW(
  *             SetupDiOpenDeviceInterfaceW (SETUPAPI.@)
  */
 BOOL WINAPI SetupDiOpenDeviceInterfaceW(
-       HDEVINFO DeviceInfoSet,
-       PCWSTR DevicePath,
-       DWORD OpenFlags,
-       PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
+        HDEVINFO DeviceInfoSet,
+        PCWSTR DevicePath,
+        DWORD OpenFlags,
+        PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
 {
     struct DeviceInfoSet * list;
     PCWSTR pEnd;
@@ -3914,7 +3976,7 @@ BOOL WINAPI SetupDiOpenDeviceInterfaceW(
 
     RegCloseKey(hDevKey);
     dwIndex++;
-    }while(TRUE);
+    } while(TRUE);
 
     RegCloseKey(hKey);
     return FALSE;
@@ -3924,10 +3986,10 @@ BOOL WINAPI SetupDiOpenDeviceInterfaceW(
  *             SetupDiOpenDeviceInterfaceA (SETUPAPI.@)
  */
 BOOL WINAPI SetupDiOpenDeviceInterfaceA(
-       HDEVINFO DeviceInfoSet,
-       PCSTR DevicePath,
-       DWORD OpenFlags,
-       PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
+        HDEVINFO DeviceInfoSet,
+        PCSTR DevicePath,
+        DWORD OpenFlags,
+        PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
 {
     LPWSTR DevicePathW = NULL;
     BOOL bResult;
@@ -3950,10 +4012,10 @@ BOOL WINAPI SetupDiOpenDeviceInterfaceA(
  *             SetupDiSetClassInstallParamsA (SETUPAPI.@)
  */
 BOOL WINAPI SetupDiSetClassInstallParamsA(
-       HDEVINFO  DeviceInfoSet,
-       PSP_DEVINFO_DATA DeviceInfoData,
-       PSP_CLASSINSTALL_HEADER ClassInstallParams,
-       DWORD ClassInstallParamsSize)
+        HDEVINFO  DeviceInfoSet,
+        PSP_DEVINFO_DATA DeviceInfoData,
+        PSP_CLASSINSTALL_HEADER ClassInstallParams,
+        DWORD ClassInstallParamsSize)
 {
     FIXME("%p %p %x %u\n",DeviceInfoSet, DeviceInfoData,
           ClassInstallParams->InstallFunction, ClassInstallParamsSize);
@@ -3962,8 +4024,8 @@ BOOL WINAPI SetupDiSetClassInstallParamsA(
 
 static BOOL WINAPI
 IntSetupDiRegisterDeviceInfo(
-    IN HDEVINFO DeviceInfoSet,
-    IN OUT PSP_DEVINFO_DATA DeviceInfoData)
+        IN HDEVINFO DeviceInfoSet,
+        IN OUT PSP_DEVINFO_DATA DeviceInfoData)
 {
     return SetupDiRegisterDeviceInfo(DeviceInfoSet, DeviceInfoData, 0, NULL, NULL, NULL);
 }
@@ -3972,9 +4034,9 @@ IntSetupDiRegisterDeviceInfo(
  *             SetupDiCallClassInstaller (SETUPAPI.@)
  */
 BOOL WINAPI SetupDiCallClassInstaller(
-       DI_FUNCTION InstallFunction,
-       HDEVINFO DeviceInfoSet,
-       PSP_DEVINFO_DATA DeviceInfoData)
+        DI_FUNCTION InstallFunction,
+        HDEVINFO DeviceInfoSet,
+        PSP_DEVINFO_DATA DeviceInfoData)
 {
     BOOL ret = FALSE;
 
@@ -4327,9 +4389,9 @@ BOOL WINAPI SetupDiCallClassInstaller(
  *             SetupDiGetDeviceInstallParamsA (SETUPAPI.@)
  */
 BOOL WINAPI SetupDiGetDeviceInstallParamsA(
-       HDEVINFO DeviceInfoSet,
-       PSP_DEVINFO_DATA DeviceInfoData,
-       PSP_DEVINSTALL_PARAMS_A DeviceInstallParams)
+        HDEVINFO DeviceInfoSet,
+        PSP_DEVINFO_DATA DeviceInfoData,
+        PSP_DEVINSTALL_PARAMS_A DeviceInstallParams)
 {
     SP_DEVINSTALL_PARAMS_W deviceInstallParamsW;
     BOOL ret = FALSE;
@@ -4370,8 +4432,8 @@ BOOL WINAPI SetupDiGetDeviceInstallParamsA(
  */
 BOOL WINAPI
 SetupDiGetDeviceInfoListClass(
-    IN HDEVINFO DeviceInfoSet,
-    OUT LPGUID ClassGuid)
+        IN HDEVINFO DeviceInfoSet,
+        OUT LPGUID ClassGuid)
 {
     struct DeviceInfoSet *list;
     BOOL ret = FALSE;
@@ -4400,9 +4462,9 @@ SetupDiGetDeviceInfoListClass(
  */
 BOOL WINAPI
 SetupDiGetDeviceInstallParamsW(
-    IN HDEVINFO DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
-    OUT PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
+        IN HDEVINFO DeviceInfoSet,
+        IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
+        OUT PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
 {
     struct DeviceInfoSet *list;
     BOOL ret = FALSE;
@@ -4448,7 +4510,7 @@ SetupDiGetDeviceInstallParamsW(
 
 static BOOL
 CheckDeviceInstallParameters(
-    IN PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
+        IN PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
 {
     DWORD SupportedFlags =
         DI_NOVCP |                            /* 0x00000008 */
@@ -4507,9 +4569,9 @@ CheckDeviceInstallParameters(
  */
 BOOL WINAPI
 SetupDiSetDeviceInstallParamsW(
-    IN HDEVINFO DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
-    IN PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
+        IN HDEVINFO DeviceInfoSet,
+        IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
+        IN PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
 {
     struct DeviceInfoSet *list;
     BOOL ret = FALSE;
@@ -4542,10 +4604,14 @@ SetupDiSetDeviceInstallParamsW(
     return ret;
 }
 
-BOOL WINAPI SetupDiSetDeviceInstallParamsA(
-       HDEVINFO DeviceInfoSet,
-       PSP_DEVINFO_DATA DeviceInfoData,
-       PSP_DEVINSTALL_PARAMS_A DeviceInstallParams)
+/***********************************************************************
+ *             SetupDiSetDeviceInstallParamsW (SETUPAPI.@)
+ */
+BOOL WINAPI
+SetupDiSetDeviceInstallParamsA(
+        HDEVINFO DeviceInfoSet,
+        PSP_DEVINFO_DATA DeviceInfoData,
+        PSP_DEVINSTALL_PARAMS_A DeviceInstallParams)
 {
     SP_DEVINSTALL_PARAMS_W deviceInstallParamsW;
     int len = 0;
@@ -4580,9 +4646,9 @@ BOOL WINAPI SetupDiSetDeviceInstallParamsA(
 
 static HKEY
 OpenHardwareProfileKey(
-    IN HKEY HKLM,
-    IN DWORD HwProfile,
-    IN DWORD samDesired)
+        IN HKEY HKLM,
+        IN DWORD HwProfile,
+        IN DWORD samDesired)
 {
     HKEY hHWProfilesKey = NULL;
     HKEY hHWProfileKey = NULL;
@@ -4590,10 +4656,10 @@ OpenHardwareProfileKey(
     LONG rc;
 
     rc = RegOpenKeyExW(HKLM,
-        REGSTR_PATH_HWPROFILES,
-        0,
-        0,
-        &hHWProfilesKey);
+                       REGSTR_PATH_HWPROFILES,
+                       0,
+                       0,
+                       &hHWProfilesKey);
     if (rc != ERROR_SUCCESS)
     {
         SetLastError(rc);
@@ -4601,24 +4667,22 @@ OpenHardwareProfileKey(
     }
     if (HwProfile == 0)
     {
-        rc = RegOpenKeyExW(
-            hHWProfilesKey,
-            REGSTR_KEY_CURRENT,
-            0,
-            KEY_CREATE_SUB_KEY,
-            &hHWProfileKey);
+        rc = RegOpenKeyExW(hHWProfilesKey,
+                           REGSTR_KEY_CURRENT,
+                           0,
+                           KEY_CREATE_SUB_KEY,
+                           &hHWProfileKey);
     }
     else
     {
         WCHAR subKey[5];
         snprintfW(subKey, 4, InstanceKeyFormat, HwProfile);
         subKey[4] = '\0';
-        rc = RegOpenKeyExW(
-            hHWProfilesKey,
-            subKey,
-            0,
-            KEY_CREATE_SUB_KEY,
-            &hHWProfileKey);
+        rc = RegOpenKeyExW(hHWProfilesKey,
+                           subKey,
+                           0,
+                           KEY_CREATE_SUB_KEY,
+                           &hHWProfileKey);
     }
     if (rc != ERROR_SUCCESS)
     {
@@ -4635,19 +4699,55 @@ cleanup:
     return ret;
 }
 
+static BOOL
+IsDeviceInfoInDeviceInfoSet(
+        struct DeviceInfoSet *deviceInfoSet,
+        struct DeviceInfo *deviceInfo)
+{
+    PLIST_ENTRY ListEntry;
+
+    ListEntry = deviceInfoSet->ListHead.Flink;
+    while (ListEntry != &deviceInfoSet->ListHead)
+    {
+        if (deviceInfo == CONTAINING_RECORD(ListEntry, struct DeviceInfo, ListEntry))
+            return TRUE;
+
+        ListEntry = ListEntry->Flink;
+    }
+
+    return FALSE;
+}
+
 /***********************************************************************
  *             SetupDiDeleteDeviceInfo (SETUPAPI.@)
  */
 BOOL WINAPI
 SetupDiDeleteDeviceInfo(
-    IN HDEVINFO DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData)
+        IN HDEVINFO DeviceInfoSet,
+        IN PSP_DEVINFO_DATA DeviceInfoData)
 {
+    struct DeviceInfoSet *deviceInfoSet;
+    struct DeviceInfo *deviceInfo = (struct DeviceInfo *)DeviceInfoData;
+    BOOL ret = FALSE;
+
     TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
 
-    FIXME("not implemented\n");
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    if (!DeviceInfoSet)
+        SetLastError(ERROR_INVALID_HANDLE);
+    else if ((deviceInfoSet = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC)
+        SetLastError(ERROR_INVALID_HANDLE);
+    else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
+        SetLastError(ERROR_INVALID_USER_BUFFER);
+    else if (!IsDeviceInfoInDeviceInfoSet(deviceInfoSet, deviceInfo))
+        SetLastError(ERROR_INVALID_PARAMETER);
+    else
+    {
+        RemoveEntryList(&deviceInfo->ListEntry);
+        DestroyDeviceInfo(deviceInfo);
+        ret = TRUE;
+    }
+
+    return ret;
 }
 
 
@@ -4656,11 +4756,11 @@ SetupDiDeleteDeviceInfo(
  */
 BOOL WINAPI
 SetupDiOpenDeviceInfoA(
-    IN HDEVINFO DeviceInfoSet,
-    IN PCSTR DeviceInstanceId,
-    IN HWND hwndParent OPTIONAL,
-    IN DWORD OpenFlags,
-    OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
+        IN HDEVINFO DeviceInfoSet,
+        IN PCSTR DeviceInstanceId,
+        IN HWND hwndParent OPTIONAL,
+        IN DWORD OpenFlags,
+        OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
 {
     LPWSTR DeviceInstanceIdW = NULL;
     BOOL bResult;
@@ -4685,11 +4785,11 @@ SetupDiOpenDeviceInfoA(
  */
 BOOL WINAPI
 SetupDiOpenDeviceInfoW(
-    IN HDEVINFO DeviceInfoSet,
-    IN PCWSTR DeviceInstanceId,
-    IN HWND hwndParent OPTIONAL,
-    IN DWORD OpenFlags,
-    OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
+        IN HDEVINFO DeviceInfoSet,
+        IN PCWSTR DeviceInstanceId,
+        IN HWND hwndParent OPTIONAL,
+        IN DWORD OpenFlags,
+        OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
 {
     struct DeviceInfoSet *list;
     HKEY hEnumKey, hKey = NULL;
@@ -4814,8 +4914,8 @@ cleanup:
  */
 BOOL WINAPI
 SetupDiGetSelectedDevice(
-    IN HDEVINFO DeviceInfoSet,
-    OUT PSP_DEVINFO_DATA DeviceInfoData)
+        IN HDEVINFO DeviceInfoSet,
+        OUT PSP_DEVINFO_DATA DeviceInfoData)
 {
     struct DeviceInfoSet *list;
     BOOL ret = FALSE;
@@ -4852,8 +4952,8 @@ SetupDiGetSelectedDevice(
  */
 BOOL WINAPI
 SetupDiSetSelectedDevice(
-    IN HDEVINFO DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData)
+        IN HDEVINFO DeviceInfoSet,
+        IN PSP_DEVINFO_DATA DeviceInfoData)
 {
     struct DeviceInfoSet *list;
     BOOL ret = FALSE;
@@ -4884,7 +4984,7 @@ SetupDiSetSelectedDevice(
 /* Return the current hardware profile id, or -1 if error */
 static DWORD
 SETUPAPI_GetCurrentHwProfile(
-    IN HDEVINFO DeviceInfoSet)
+        IN HDEVINFO DeviceInfoSet)
 {
     HKEY hKey = NULL;
     DWORD dwRegType, dwLength;
@@ -4892,12 +4992,11 @@ SETUPAPI_GetCurrentHwProfile(
     LONG rc;
     DWORD ret = (DWORD)-1;
 
-    rc = RegOpenKeyExW(
-        ((struct DeviceInfoSet *)DeviceInfoSet)->HKLM,
-        REGSTR_PATH_IDCONFIGDB,
-        0, /* Options */
-        KEY_QUERY_VALUE,
-        &hKey);
+    rc = RegOpenKeyExW(((struct DeviceInfoSet *)DeviceInfoSet)->HKLM,
+                       REGSTR_PATH_IDCONFIGDB,
+                       0, /* Options */
+                       KEY_QUERY_VALUE,
+                       &hKey);
     if (rc != ERROR_SUCCESS)
     {
         SetLastError(rc);
@@ -4905,12 +5004,11 @@ SETUPAPI_GetCurrentHwProfile(
     }
 
     dwLength = sizeof(DWORD);
-    rc = RegQueryValueExW(
-        hKey,
-        REGSTR_VAL_CURRENTCONFIG,
-        NULL,
-        &dwRegType,
-        (LPBYTE)&hwProfile, &dwLength);
+    rc = RegQueryValueExW(hKey,
+                          REGSTR_VAL_CURRENTCONFIG,
+                          NULL,
+                          &dwRegType,
+                          (LPBYTE)&hwProfile, &dwLength);
     if (rc != ERROR_SUCCESS)
     {
         SetLastError(rc);
@@ -4933,8 +5031,8 @@ cleanup:
 
 static BOOL
 ResetDevice(
-    IN HDEVINFO DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData)
+        IN HDEVINFO DeviceInfoSet,
+        IN PSP_DEVINFO_DATA DeviceInfoData)
 {
 #ifndef __WINESRC__
     struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
@@ -4956,8 +5054,8 @@ ResetDevice(
 }
 
 static BOOL StopDevice(
-    IN HDEVINFO DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData)
+        IN HDEVINFO DeviceInfoSet,
+        IN PSP_DEVINFO_DATA DeviceInfoData)
 {
     FIXME("Stub: StopDevice(%p %p)\n", DeviceInfoSet, DeviceInfoData);
     return TRUE;
@@ -4968,8 +5066,8 @@ static BOOL StopDevice(
  */
 BOOL WINAPI
 SetupDiChangeState(
-    IN HDEVINFO DeviceInfoSet,
-    IN OUT PSP_DEVINFO_DATA DeviceInfoData)
+        IN HDEVINFO DeviceInfoSet,
+        IN OUT PSP_DEVINFO_DATA DeviceInfoData)
 {
     PSP_PROPCHANGE_PARAMS PropChange;
     HKEY hKey = INVALID_HANDLE_VALUE;
@@ -5080,12 +5178,12 @@ cleanup:
  */
 BOOL WINAPI
 SetupDiSelectDevice(
-    IN HDEVINFO DeviceInfoSet,
-    IN OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
+        IN HDEVINFO DeviceInfoSet,
+        IN OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
 {
-       FIXME("%p %p\n", DeviceInfoSet, DeviceInfoData);
-       SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-       return FALSE;
+    FIXME("%p %p\n", DeviceInfoSet, DeviceInfoData);
+    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+    return FALSE;
 }
 
 
@@ -5094,8 +5192,8 @@ SetupDiSelectDevice(
  */
 BOOL WINAPI
 SetupDiRegisterCoDeviceInstallers(
-    IN HDEVINFO DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData)
+        IN HDEVINFO DeviceInfoSet,
+        IN PSP_DEVINFO_DATA DeviceInfoData)
 {
     BOOL ret = FALSE; /* Return value */
 
@@ -5186,8 +5284,8 @@ cleanup:
 
 static BOOL
 InfIsFromOEMLocation(
-    IN PCWSTR FullName,
-    OUT LPBOOL IsOEMLocation)
+        IN PCWSTR FullName,
+        OUT LPBOOL IsOEMLocation)
 {
     PWCHAR last;
 
@@ -5240,8 +5338,8 @@ InfIsFromOEMLocation(
  */
 BOOL WINAPI
 SetupDiInstallDevice(
-    IN HDEVINFO DeviceInfoSet,
-    IN OUT PSP_DEVINFO_DATA DeviceInfoData)
+        IN HDEVINFO DeviceInfoSet,
+        IN OUT PSP_DEVINFO_DATA DeviceInfoData)
 {
     SP_DEVINSTALL_PARAMS_W InstallParams;
     struct DriverInfoElement *SelectedDriver;
@@ -5373,7 +5471,7 @@ SetupDiInstallDevice(
             NewFileName, MAX_PATH,
             NULL,
             NULL);
-        if (!Result)
+        if (!Result && GetLastError() != ERROR_FILE_EXISTS)
             goto cleanup;
         /* Create a new struct InfFileDetails, and set it to
          * SelectedDriver->InfFileDetails, to release use of
@@ -5625,12 +5723,12 @@ cleanup:
  *             SetupDiOpenDevRegKey (SETUPAPI.@)
  */
 HKEY WINAPI SetupDiOpenDevRegKey(
-       HDEVINFO DeviceInfoSet,
-       PSP_DEVINFO_DATA DeviceInfoData,
-       DWORD Scope,
-       DWORD HwProfile,
-       DWORD KeyType,
-       REGSAM samDesired)
+        HDEVINFO DeviceInfoSet,
+        PSP_DEVINFO_DATA DeviceInfoData,
+        DWORD Scope,
+        DWORD HwProfile,
+        DWORD KeyType,
+        REGSAM samDesired)
 {
     struct DeviceInfoSet *set = DeviceInfoSet;
     struct DeviceInfo *devInfo;
@@ -5712,11 +5810,11 @@ static BOOL SETUPDI_DeleteDrvKey(HKEY RootKey, struct DeviceInfo *devInfo)
  *             SetupDiDeleteDevRegKey (SETUPAPI.@)
  */
 BOOL WINAPI SetupDiDeleteDevRegKey(
-       HDEVINFO DeviceInfoSet,
-       PSP_DEVINFO_DATA DeviceInfoData,
-       DWORD Scope,
-       DWORD HwProfile,
-       DWORD KeyType)
+        HDEVINFO DeviceInfoSet,
+        PSP_DEVINFO_DATA DeviceInfoData,
+        DWORD Scope,
+        DWORD HwProfile,
+        DWORD KeyType)
 {
     struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
     struct DeviceInfo *devInfo;