Fix some whitespaces
[reactos.git] / reactos / dll / win32 / setupapi / devinst.c
index 3b83f6b..a0c94b5 100644 (file)
@@ -16,7 +16,7 @@
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
 #include "setupapi_private.h"
@@ -86,6 +86,15 @@ struct CoInstallerElement
     PVOID PrivateData;
 };
 
+struct GetSectionCallbackInfo
+{
+    PSP_ALTPLATFORM_INFO PlatformInfo;
+    BYTE ProductType;
+    WORD SuiteMask;
+    WCHAR BestSection[LINE_LEN + 1];
+    DWORD BestScore1, BestScore2, BestScore3, BestScore4, BestScore5;
+};
+
 static BOOL
 PropertyChangeHandler(
     IN HDEVINFO DeviceInfoSet,
@@ -144,7 +153,7 @@ static const UPDATE_CLASS_PARAM_HANDLER UpdateClassInstallParamHandlers[] = {
 BOOL WINAPI
 SetupDiBuildClassInfoList(
     IN DWORD Flags,
-    OUT LPGUID ClassGuidList  OPTIONAL,
+    OUT LPGUID ClassGuidList OPTIONAL,
     IN DWORD ClassGuidListSize,
     OUT PDWORD RequiredSize)
 {
@@ -160,10 +169,10 @@ SetupDiBuildClassInfoList(
 BOOL WINAPI
 SetupDiBuildClassInfoListExA(
     IN DWORD Flags,
-    OUT LPGUID ClassGuidList  OPTIONAL,
+    OUT LPGUID ClassGuidList OPTIONAL,
     IN DWORD ClassGuidListSize,
     OUT PDWORD RequiredSize,
-    IN PCSTR MachineName  OPTIONAL,
+    IN PCSTR MachineName OPTIONAL,
     IN PVOID Reserved)
 {
     LPWSTR MachineNameW = NULL;
@@ -193,10 +202,10 @@ SetupDiBuildClassInfoListExA(
 BOOL WINAPI
 SetupDiBuildClassInfoListExW(
     IN DWORD Flags,
-    OUT LPGUID ClassGuidList  OPTIONAL,
+    OUT LPGUID ClassGuidList OPTIONAL,
     IN DWORD ClassGuidListSize,
     OUT PDWORD RequiredSize,
-    IN PCWSTR MachineName  OPTIONAL,
+    IN PCWSTR MachineName OPTIONAL,
     IN PVOID Reserved)
 {
     WCHAR szKeyName[MAX_GUID_STRING_LEN + 1];
@@ -356,7 +365,7 @@ SetupDiClassGuidsFromNameExA(
     OUT LPGUID ClassGuidList,
     IN DWORD ClassGuidListSize,
     OUT PDWORD RequiredSize,
-    IN PCSTR MachineName  OPTIONAL,
+    IN PCSTR MachineName OPTIONAL,
     IN PVOID Reserved)
 {
     LPWSTR ClassNameW = NULL;
@@ -400,7 +409,7 @@ SetupDiClassGuidsFromNameExW(
     OUT LPGUID ClassGuidList,
     IN DWORD ClassGuidListSize,
     OUT PDWORD RequiredSize,
-    IN PCWSTR MachineName  OPTIONAL,
+    IN PCWSTR MachineName OPTIONAL,
     IN PVOID Reserved)
 {
     WCHAR szKeyName[MAX_GUID_STRING_LEN + 1];
@@ -512,7 +521,7 @@ SetupDiClassNameFromGuidA(
     IN CONST GUID* ClassGuid,
     OUT PSTR ClassName,
     IN DWORD ClassNameSize,
-    OUT PDWORD RequiredSize  OPTIONAL)
+    OUT PDWORD RequiredSize OPTIONAL)
 {
   return SetupDiClassNameFromGuidExA(ClassGuid, ClassName,
                                      ClassNameSize, RequiredSize,
@@ -527,7 +536,7 @@ SetupDiClassNameFromGuidW(
     IN CONST GUID* ClassGuid,
     OUT PWSTR ClassName,
     IN DWORD ClassNameSize,
-    OUT PDWORD RequiredSize  OPTIONAL)
+    OUT PDWORD RequiredSize OPTIONAL)
 {
   return SetupDiClassNameFromGuidExW(ClassGuid, ClassName,
                                      ClassNameSize, RequiredSize,
@@ -542,8 +551,8 @@ SetupDiClassNameFromGuidExA(
     IN CONST GUID* ClassGuid,
     OUT PSTR ClassName,
     IN DWORD ClassNameSize,
-    OUT PDWORD RequiredSize  OPTIONAL,
-    IN PCSTR MachineName  OPTIONAL,
+    OUT PDWORD RequiredSize OPTIONAL,
+    IN PCSTR MachineName OPTIONAL,
     IN PVOID Reserved)
 {
     WCHAR ClassNameW[MAX_CLASS_NAME_LEN];
@@ -574,8 +583,8 @@ SetupDiClassNameFromGuidExW(
     IN CONST GUID* ClassGuid,
     OUT PWSTR ClassName,
     IN DWORD ClassNameSize,
-    OUT PDWORD RequiredSize  OPTIONAL,
-    IN PCWSTR MachineName  OPTIONAL,
+    OUT PDWORD RequiredSize OPTIONAL,
+    IN PCWSTR MachineName OPTIONAL,
     IN PVOID Reserved)
 {
     HKEY hKey;
@@ -638,8 +647,8 @@ cleanup:
  */
 HDEVINFO WINAPI
 SetupDiCreateDeviceInfoList(
-    IN CONST GUID *ClassGuid  OPTIONAL,
-    IN HWND hwndParent  OPTIONAL)
+    IN CONST GUID *ClassGuid OPTIONAL,
+    IN HWND hwndParent OPTIONAL)
 {
   return SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent, NULL, NULL);
 }
@@ -649,9 +658,9 @@ SetupDiCreateDeviceInfoList(
  */
 HDEVINFO WINAPI
 SetupDiCreateDeviceInfoListExA(
-    IN CONST GUID *ClassGuid  OPTIONAL,
-    IN HWND hwndParent  OPTIONAL,
-    IN PCSTR MachineName  OPTIONAL,
+    IN CONST GUID *ClassGuid OPTIONAL,
+    IN HWND hwndParent OPTIONAL,
+    IN PCSTR MachineName OPTIONAL,
     IN PVOID Reserved)
 {
     LPWSTR MachineNameW = NULL;
@@ -709,9 +718,9 @@ GetErrorCodeFromCrCode(const IN CONFIGRET cr)
  */
 HDEVINFO WINAPI
 SetupDiCreateDeviceInfoListExW(
-    IN CONST GUID *ClassGuid  OPTIONAL,
-    IN HWND hwndParent  OPTIONAL,
-    IN PCWSTR MachineName  OPTIONAL,
+    IN CONST GUID *ClassGuid OPTIONAL,
+    IN HWND hwndParent OPTIONAL,
+    IN PCWSTR MachineName OPTIONAL,
     IN PVOID Reserved)
 {
   struct DeviceInfoSet *list;
@@ -859,10 +868,10 @@ BOOL WINAPI
 SetupDiGetActualSectionToInstallA(
     IN HINF InfHandle,
     IN PCSTR InfSectionName,
-    OUT PSTR InfSectionWithExt  OPTIONAL,
+    OUT PSTR InfSectionWithExt OPTIONAL,
     IN DWORD InfSectionWithExtSize,
-    OUT PDWORD RequiredSize  OPTIONAL,
-    OUT PSTR *Extension  OPTIONAL)
+    OUT PDWORD RequiredSize OPTIONAL,
+    OUT PSTR *Extension OPTIONAL)
 {
     return SetupDiGetActualSectionToInstallExA(InfHandle, InfSectionName,
         NULL, InfSectionWithExt, InfSectionWithExtSize, RequiredSize,
@@ -876,10 +885,10 @@ BOOL WINAPI
 SetupDiGetActualSectionToInstallW(
     IN HINF InfHandle,
     IN PCWSTR InfSectionName,
-    OUT PWSTR InfSectionWithExt  OPTIONAL,
+    OUT PWSTR InfSectionWithExt OPTIONAL,
     IN DWORD InfSectionWithExtSize,
-    OUT PDWORD RequiredSize  OPTIONAL,
-    OUT PWSTR *Extension  OPTIONAL)
+    OUT PDWORD RequiredSize OPTIONAL,
+    OUT PWSTR *Extension OPTIONAL)
 {
     return SetupDiGetActualSectionToInstallExW(InfHandle, InfSectionName,
         NULL, InfSectionWithExt, InfSectionWithExtSize, RequiredSize,
@@ -893,11 +902,11 @@ BOOL WINAPI
 SetupDiGetActualSectionToInstallExA(
     IN HINF InfHandle,
     IN PCSTR InfSectionName,
-    IN PSP_ALTPLATFORM_INFO AlternatePlatformInfo  OPTIONAL,
-    OUT PSTR InfSectionWithExt  OPTIONAL,
+    IN PSP_ALTPLATFORM_INFO AlternatePlatformInfo OPTIONAL,
+    OUT PSTR InfSectionWithExt OPTIONAL,
     IN DWORD InfSectionWithExtSize,
-    OUT PDWORD RequiredSize  OPTIONAL,
-    OUT PSTR* Extension  OPTIONAL,
+    OUT PDWORD RequiredSize OPTIONAL,
+    OUT PSTR* Extension OPTIONAL,
     IN PVOID Reserved)
 {
     LPWSTR InfSectionNameW = NULL;
@@ -948,6 +957,291 @@ cleanup:
     return bResult;
 }
 
+/* Lower scores are best ones */
+static BOOL
+CheckSectionValid(
+    IN LPCWSTR SectionName,
+    IN PSP_ALTPLATFORM_INFO PlatformInfo,
+    IN BYTE ProductType,
+    IN WORD SuiteMask,
+    OUT PDWORD ScorePlatform,
+    OUT PDWORD ScoreMajorVersion,
+    OUT PDWORD ScoreMinorVersion,
+    OUT PDWORD ScoreProductType,
+    OUT PDWORD ScoreSuiteMask)
+{
+    LPWSTR Section = NULL;
+    LPCWSTR pExtensionPlatform, pExtensionArchitecture;
+    LPWSTR Fields[6];
+    DWORD i;
+    BOOL ret = FALSE;
+
+    TRACE("%s %p 0x%x 0x%x\n",
+        debugstr_w(SectionName), PlatformInfo, ProductType, SuiteMask);
+
+    static const WCHAR ExtensionPlatformNone[]  = {'.',0};
+    static const WCHAR ExtensionPlatformNT[]  = {'.','N','T',0};
+    static const WCHAR ExtensionPlatformWindows[]  = {'.','W','i','n',0};
+
+    static const WCHAR ExtensionArchitectureNone[]  = {0};
+    static const WCHAR ExtensionArchitecturealpha[]  = {'a','l','p','h','a',0};
+    static const WCHAR ExtensionArchitectureamd64[]  = {'a','m','d','6','4',0};
+    static const WCHAR ExtensionArchitectureia64[]  = {'i','a','6','4',0};
+    static const WCHAR ExtensionArchitecturemips[]  = {'m','i','p','s',0};
+    static const WCHAR ExtensionArchitectureppc[]  = {'p','p','c',0};
+    static const WCHAR ExtensionArchitecturex86[]  = {'x','8','6',0};
+
+    *ScorePlatform = *ScoreMajorVersion = *ScoreMinorVersion = *ScoreProductType = *ScoreSuiteMask = 0;
+
+    Section = DuplicateString(SectionName);
+    if (!Section)
+    {
+        TRACE("DuplicateString() failed\n");
+        goto cleanup;
+    }
+
+    /* Set various extensions values */
+    switch (PlatformInfo->Platform)
+    {
+        case VER_PLATFORM_WIN32_WINDOWS:
+            pExtensionPlatform = ExtensionPlatformWindows;
+            break;
+        case VER_PLATFORM_WIN32_NT:
+            pExtensionPlatform = ExtensionPlatformNT;
+            break;
+        default:
+            ERR("Unkown platform 0x%lx\n", PlatformInfo->Platform);
+            pExtensionPlatform = ExtensionPlatformNone;
+            break;
+    }
+    switch (PlatformInfo->ProcessorArchitecture)
+    {
+        case PROCESSOR_ARCHITECTURE_ALPHA:
+            pExtensionArchitecture = ExtensionArchitecturealpha;
+            break;
+        case PROCESSOR_ARCHITECTURE_AMD64:
+            pExtensionArchitecture = ExtensionArchitectureamd64;
+            break;
+        case PROCESSOR_ARCHITECTURE_IA64:
+            pExtensionArchitecture = ExtensionArchitectureia64;
+            break;
+        case PROCESSOR_ARCHITECTURE_INTEL:
+            pExtensionArchitecture = ExtensionArchitecturex86;
+            break;
+        case PROCESSOR_ARCHITECTURE_MIPS:
+            pExtensionArchitecture = ExtensionArchitecturemips;
+            break;
+        case PROCESSOR_ARCHITECTURE_PPC:
+            pExtensionArchitecture = ExtensionArchitectureppc;
+            break;
+        default:
+            ERR("Unknown processor architecture 0x%x\n", PlatformInfo->ProcessorArchitecture);
+        case PROCESSOR_ARCHITECTURE_UNKNOWN:
+            pExtensionArchitecture = ExtensionArchitectureNone;
+            break;
+    }
+
+    /*
+     * Field[0] Platform
+     * Field[1] Architecture
+     * Field[2] Major version
+     * Field[3] Minor version
+     * Field[4] Product type
+     * Field[5] Suite mask
+     * Remark: lastests fields may be NULL if the information is not provided
+     */
+    Fields[0] = strchrW(Section, '.');
+    if (Fields[0] == NULL)
+    {
+        TRACE("No extension found\n");
+        *ScorePlatform = *ScoreMajorVersion = *ScoreMinorVersion = *ScoreProductType = *ScoreSuiteMask = ULONG_MAX;
+        ret = TRUE;
+        goto cleanup;
+    }
+    Fields[1] = Fields[0] + 1;
+    Fields[2] = Fields[3] = Fields[4] = Fields[5] = NULL;
+    for (i = 2; Fields[i - 1] != NULL && i < 6; i++)
+    {
+        Fields[i] = wcschr(Fields[i - 1], '.');
+        if (Fields[i])
+        {
+            Fields[i]++;
+            *(Fields[i] - 1) = L'\0';
+        }
+    }
+    /* Take care of first 2 fields */
+    if (strncmpiW(Fields[0], ExtensionPlatformWindows, strlenW(ExtensionPlatformWindows)) == 0)
+    {
+        if (PlatformInfo->Platform != VER_PLATFORM_WIN32_WINDOWS)
+        {
+            TRACE("Mismatch on platform field\n");
+            goto cleanup;
+        }
+        Fields[1] += wcslen(ExtensionPlatformWindows) - 1;
+    }
+    else if (strncmpiW(Fields[0], ExtensionPlatformNT, strlenW(ExtensionPlatformNT)) == 0)
+    {
+        if (PlatformInfo->Platform != VER_PLATFORM_WIN32_NT)
+        {
+            TRACE("Mismatch on platform field\n");
+            goto cleanup;
+        }
+        Fields[1] += wcslen(ExtensionPlatformNT) - 1;
+    }
+    else
+    {
+        /* No platform specified */
+        *ScorePlatform |= 0x02;
+    }
+    if (strcmpiW(Fields[1], ExtensionArchitectureNone) == 0)
+    {
+        /* No architecture specified */
+        *ScorePlatform |= 0x01;
+    }
+    else if (strcmpiW(Fields[1], pExtensionArchitecture) != 0)
+    {
+        TRACE("Mismatch on architecture field ('%s' and '%s')\n",
+            debugstr_w(Fields[1]), debugstr_w(pExtensionArchitecture));
+        goto cleanup;
+    }
+
+    /* Check if informations are matching */
+    if (Fields[2] && *Fields[2])
+    {
+        DWORD MajorVersion, MinorVersion = 0;
+        MajorVersion = strtoulW(Fields[2], NULL, 0);
+        if ((MajorVersion == 0 || MajorVersion == ULONG_MAX) &&
+            (errno == ERANGE || errno == EINVAL))
+        {
+            TRACE("Wrong MajorVersion ('%s')\n", debugstr_w(Fields[2]));
+            goto cleanup;
+        }
+        if (Fields[3] && *Fields[3])
+        {
+            MinorVersion = strtoulW(Fields[3], NULL, 0);
+            if ((MinorVersion == 0 || MinorVersion == ULONG_MAX) &&
+                (errno == ERANGE || errno == EINVAL))
+            {
+                TRACE("Wrong MinorVersion ('%s')\n", debugstr_w(Fields[3]));
+                goto cleanup;
+            }
+        }
+        if (PlatformInfo->MajorVersion < MajorVersion ||
+            (PlatformInfo->MajorVersion == MajorVersion && PlatformInfo->MinorVersion < MinorVersion))
+        {
+            TRACE("Mismatch on version field (%lu.%lu and %lu.%lu)\n",
+                MajorVersion, MinorVersion, PlatformInfo->MajorVersion, PlatformInfo->MinorVersion);
+            goto cleanup;
+        }
+        *ScoreMajorVersion = MajorVersion - PlatformInfo->MajorVersion;
+        if (MajorVersion == PlatformInfo->MajorVersion)
+            *ScoreMinorVersion = MinorVersion - PlatformInfo->MinorVersion;
+        else
+            *ScoreMinorVersion = MinorVersion;
+    }
+    else if (Fields[3] && *Fields[3])
+    {
+        TRACE("Minor version found without major version\n");
+        goto cleanup;
+    }
+    else
+    {
+        *ScoreMajorVersion = PlatformInfo->MajorVersion;
+        *ScoreMinorVersion = PlatformInfo->MinorVersion;
+    }
+
+    if (Fields[4] && *Fields[4])
+    {
+        DWORD CurrentProductType;
+        CurrentProductType = strtoulW(Fields[4], NULL, 0);
+        if ((CurrentProductType == 0 || CurrentProductType == ULONG_MAX) &&
+            (errno == ERANGE || errno == EINVAL))
+        {
+            TRACE("Wrong Product type ('%s')\n", debugstr_w(Fields[4]));
+            goto cleanup;
+        }
+        if (CurrentProductType != ProductType)
+        {
+            TRACE("Mismatch on product type (0x%08lx and 0x%08x)\n",
+                CurrentProductType, ProductType);
+            goto cleanup;
+        }
+    }
+    else
+        *ScoreProductType = 1;
+
+    if (Fields[5] && *Fields[5])
+    {
+        DWORD CurrentSuiteMask;
+        CurrentSuiteMask = strtoulW(Fields[5], NULL, 0);
+        if ((CurrentSuiteMask == 0 || CurrentSuiteMask == ULONG_MAX) &&
+            (errno == ERANGE || errno == EINVAL))
+        {
+            TRACE("Wrong Suite mask ('%s')\n", debugstr_w(Fields[5]));
+            goto cleanup;
+        }
+        if ((CurrentSuiteMask & ~SuiteMask) != 0)
+        {
+            TRACE("Mismatch on suite mask (0x%08lx and 0x%08x)\n",
+                CurrentSuiteMask, SuiteMask);
+            goto cleanup;
+        }
+        *ScoreSuiteMask = SuiteMask & ~CurrentSuiteMask;
+    }
+    else
+        *ScoreSuiteMask = SuiteMask;
+
+    ret = TRUE;
+
+cleanup:
+    MyFree(Section);
+    return ret;
+}
+
+static BOOL
+GetSectionCallback(
+    IN LPCWSTR SectionName,
+    IN PVOID Context)
+{
+    struct GetSectionCallbackInfo *info = Context;
+    DWORD Score1, Score2, Score3, Score4, Score5;
+    BOOL ret;
+
+    ret = CheckSectionValid(
+        SectionName,
+        info->PlatformInfo,
+        info->ProductType,
+        info->SuiteMask,
+        &Score1, &Score2, &Score3, &Score4, &Score5);
+    if (!ret)
+    {
+        TRACE("Section %s not compatible\n", debugstr_w(SectionName));
+        return TRUE;
+    }
+    if (Score1 > info->BestScore1) goto done;
+    if (Score1 < info->BestScore1) goto bettersection;
+    if (Score2 > info->BestScore2) goto done;
+    if (Score2 < info->BestScore2) goto bettersection;
+    if (Score3 > info->BestScore3) goto done;
+    if (Score3 < info->BestScore3) goto bettersection;
+    if (Score4 > info->BestScore4) goto done;
+    if (Score4 < info->BestScore4) goto bettersection;
+    if (Score5 > info->BestScore5) goto done;
+    if (Score5 < info->BestScore5) goto bettersection;
+    goto done;
+
+bettersection:
+    strcpyW(info->BestSection, SectionName);
+    info->BestScore1 = Score1;
+    info->BestScore2 = Score2;
+    info->BestScore3 = Score3;
+    info->BestScore4 = Score4;
+    info->BestScore5 = Score5;
+
+done:
+    return TRUE;
+}
+
 /***********************************************************************
  *             SetupDiGetActualSectionToInstallExW (SETUPAPI.@)
  */
@@ -955,11 +1249,11 @@ BOOL WINAPI
 SetupDiGetActualSectionToInstallExW(
     IN HINF InfHandle,
     IN PCWSTR InfSectionName,
-    IN PSP_ALTPLATFORM_INFO AlternatePlatformInfo  OPTIONAL,
-    OUT PWSTR InfSectionWithExt  OPTIONAL,
+    IN PSP_ALTPLATFORM_INFO AlternatePlatformInfo OPTIONAL,
+    OUT PWSTR InfSectionWithExt OPTIONAL,
     IN DWORD InfSectionWithExtSize,
-    OUT PDWORD RequiredSize  OPTIONAL,
-    OUT PWSTR* Extension  OPTIONAL,
+    OUT PDWORD RequiredSize OPTIONAL,
+    OUT PWSTR* Extension OPTIONAL,
     IN PVOID Reserved)
 {
     BOOL ret = FALSE;
@@ -979,162 +1273,84 @@ SetupDiGetActualSectionToInstallExW(
     else
     {
         static SP_ALTPLATFORM_INFO CurrentPlatform = { 0, };
+        static BYTE CurrentProductType = 0;
+        static WORD CurrentSuiteMask = 0;
         PSP_ALTPLATFORM_INFO pPlatformInfo = &CurrentPlatform;
-        LPCWSTR pExtensionPlatform, pExtensionArchitecture;
-        WCHAR SectionName[LINE_LEN + 1];
-        LONG lLineCount = -1;
+        struct GetSectionCallbackInfo CallbackInfo;
         DWORD dwFullLength;
+        BYTE ProductType;
+        WORD SuiteMask;
 
         /* Fill platform info if needed */
         if (AlternatePlatformInfo)
-            pPlatformInfo = AlternatePlatformInfo;
-        else if (CurrentPlatform.cbSize != sizeof(SP_ALTPLATFORM_INFO))
         {
-            /* That's the first time we go here. We need to fill in the structure */
-            OSVERSIONINFO VersionInfo;
-            SYSTEM_INFO SystemInfo;
-            VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-            ret = GetVersionEx(&VersionInfo);
-            if (!ret)
-                goto done;
-            GetSystemInfo(&SystemInfo);
-            CurrentPlatform.cbSize = sizeof(SP_ALTPLATFORM_INFO);
-            CurrentPlatform.Platform = VersionInfo.dwPlatformId;
-            CurrentPlatform.MajorVersion = VersionInfo.dwMajorVersion;
-            CurrentPlatform.MinorVersion = VersionInfo.dwMinorVersion;
-            CurrentPlatform.ProcessorArchitecture = SystemInfo.wProcessorArchitecture;
-            CurrentPlatform.Reserved = 0;
-        }
-
-static const WCHAR ExtensionPlatformNone[]  = {'.',0};
-static const WCHAR ExtensionPlatformNT[]  = {'.','N','T',0};
-static const WCHAR ExtensionPlatformWindows[]  = {'.','W','i','n',0};
-
-static const WCHAR ExtensionArchitectureNone[]  = {0};
-static const WCHAR ExtensionArchitecturealpha[]  = {'a','l','p','h','a',0};
-static const WCHAR ExtensionArchitectureamd64[]  = {'a','m','d','6','4',0};
-static const WCHAR ExtensionArchitectureia64[]  = {'i','a','6','4',0};
-static const WCHAR ExtensionArchitecturemips[]  = {'m','i','p','s',0};
-static const WCHAR ExtensionArchitectureppc[]  = {'p','p','c',0};
-static const WCHAR ExtensionArchitecturex86[]  = {'x','8','6',0};
-
-        /* Set various extensions values */
-        switch (pPlatformInfo->Platform)
-        {
-            case VER_PLATFORM_WIN32_WINDOWS:
-                pExtensionPlatform = ExtensionPlatformWindows;
-                break;
-            case VER_PLATFORM_WIN32_NT:
-                pExtensionPlatform = ExtensionPlatformNT;
-                break;
-            default:
-                ERR("Unkown platform 0x%lx\n", pPlatformInfo->Platform);
-                pExtensionPlatform = ExtensionPlatformNone;
-                break;
+            pPlatformInfo = AlternatePlatformInfo;
+            ProductType = 0;
+            SuiteMask = 0;
         }
-        switch (pPlatformInfo->ProcessorArchitecture)
+        else
         {
-            case PROCESSOR_ARCHITECTURE_ALPHA:
-                pExtensionArchitecture = ExtensionArchitecturealpha;
-                break;
-            case PROCESSOR_ARCHITECTURE_AMD64:
-                pExtensionArchitecture = ExtensionArchitectureamd64;
-                break;
-            case PROCESSOR_ARCHITECTURE_IA64:
-                pExtensionArchitecture = ExtensionArchitectureia64;
-                break;
-            case PROCESSOR_ARCHITECTURE_INTEL:
-                pExtensionArchitecture = ExtensionArchitecturex86;
-                break;
-            case PROCESSOR_ARCHITECTURE_MIPS:
-                pExtensionArchitecture = ExtensionArchitecturemips;
-                break;
-            case PROCESSOR_ARCHITECTURE_PPC:
-                pExtensionArchitecture = ExtensionArchitectureppc;
-                break;
-            default:
-                ERR("Unknown processor architecture 0x%x\n", pPlatformInfo->ProcessorArchitecture);
-            case PROCESSOR_ARCHITECTURE_UNKNOWN:
-                pExtensionArchitecture = ExtensionArchitectureNone;
-                break;
+            if (CurrentPlatform.cbSize != sizeof(SP_ALTPLATFORM_INFO))
+            {
+                /* That's the first time we go here. We need to fill in the structure */
+                OSVERSIONINFOEX VersionInfo;
+                SYSTEM_INFO SystemInfo;
+                VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+                ret = GetVersionEx((POSVERSIONINFO)&VersionInfo);
+                if (!ret)
+                    goto done;
+                GetSystemInfo(&SystemInfo);
+                CurrentPlatform.cbSize = sizeof(SP_ALTPLATFORM_INFO);
+                CurrentPlatform.Platform = VersionInfo.dwPlatformId;
+                CurrentPlatform.MajorVersion = VersionInfo.dwMajorVersion;
+                CurrentPlatform.MinorVersion = VersionInfo.dwMinorVersion;
+                CurrentPlatform.ProcessorArchitecture = SystemInfo.wProcessorArchitecture;
+                CurrentPlatform.Reserved = 0;
+                CurrentProductType = VersionInfo.wProductType;
+                CurrentSuiteMask = VersionInfo.wSuiteMask;
+            }
+            ProductType = CurrentProductType;
+            SuiteMask = CurrentSuiteMask;
+        }
+
+        CallbackInfo.PlatformInfo = pPlatformInfo;
+        CallbackInfo.ProductType = ProductType;
+        CallbackInfo.SuiteMask = SuiteMask;
+        CallbackInfo.BestScore1 = ULONG_MAX;
+        CallbackInfo.BestScore2 = ULONG_MAX;
+        CallbackInfo.BestScore3 = ULONG_MAX;
+        CallbackInfo.BestScore4 = ULONG_MAX;
+        CallbackInfo.BestScore5 = ULONG_MAX;
+        strcpyW(CallbackInfo.BestSection, InfSectionName);
+        if (!EnumerateSectionsStartingWith(
+            InfHandle,
+            InfSectionName,
+            GetSectionCallback,
+            &CallbackInfo))
+        {
+            SetLastError(ERROR_GEN_FAILURE);
+            goto done;
         }
 
-static const WCHAR FormatPlatformArchitectureMajorMinor[]  = {'%','s','%','s','%','s','.','%','l','u','.','%','l','u',0};
-static const WCHAR FormatPlatformMajorMinor[]  = {'%','s','%','s','.','%','l','u','.','%','l','u',0};
-static const WCHAR FormatPlatformArchitectureMajor[]  = {'%','s','%','s','%','s','.','%','l','u',0};
-static const WCHAR FormatPlatformMajor[]  = {'%','s','%','s','.','%','l','u',0};
-static const WCHAR FormatPlatformArchitecture[]  = {'%','s','%','s','%','s',0};
-static const WCHAR FormatPlatform[]  = {'%','s','%','s',0};
-static const WCHAR FormatNone[]  = {'%','s',0};
-
-        SectionName[LINE_LEN] = UNICODE_NULL;
-
-        /* Test with platform.architecture.major.minor extension */
-        snprintfW(SectionName, LINE_LEN, FormatPlatformArchitectureMajorMinor, InfSectionName,
-            pExtensionPlatform, pExtensionArchitecture, pPlatformInfo->MajorVersion, pPlatformInfo->MinorVersion);
-        lLineCount = SetupGetLineCountW(InfHandle, SectionName);
-        if (lLineCount != -1) goto sectionfound;
-
-        /* Test with platform.major.minor extension */
-        snprintfW(SectionName, LINE_LEN, FormatPlatformMajorMinor, InfSectionName,
-            pExtensionPlatform, pPlatformInfo->MajorVersion, pPlatformInfo->MinorVersion);
-        lLineCount = SetupGetLineCountW(InfHandle, SectionName);
-        if (lLineCount != -1) goto sectionfound;
-
-        /* Test with platform.architecture.major extension */
-        snprintfW(SectionName, LINE_LEN, FormatPlatformArchitectureMajor, InfSectionName,
-            pExtensionPlatform, pExtensionArchitecture, pPlatformInfo->MajorVersion);
-        lLineCount = SetupGetLineCountW(InfHandle, SectionName);
-        if (lLineCount != -1) goto sectionfound;
-
-        /* Test with platform.major extension */
-        snprintfW(SectionName, LINE_LEN, FormatPlatformMajor, InfSectionName,
-            pExtensionPlatform, pPlatformInfo->MajorVersion);
-        lLineCount = SetupGetLineCountW(InfHandle, SectionName);
-        if (lLineCount != -1) goto sectionfound;
-
-        /* Test with platform.architecture extension */
-        snprintfW(SectionName, LINE_LEN, FormatPlatformArchitecture, InfSectionName,
-            pExtensionPlatform, pExtensionArchitecture);
-        lLineCount = SetupGetLineCountW(InfHandle, SectionName);
-        if (lLineCount != -1) goto sectionfound;
-
-        /* Test with platform extension */
-        snprintfW(SectionName, LINE_LEN, FormatPlatform, InfSectionName,
-            pExtensionPlatform);
-        lLineCount = SetupGetLineCountW(InfHandle, SectionName);
-        if (lLineCount != -1) goto sectionfound;
-
-        /* Test without extension */
-        snprintfW(SectionName, LINE_LEN, FormatNone, InfSectionName);
-        lLineCount = SetupGetLineCountW(InfHandle, SectionName);
-        if (lLineCount != -1) goto sectionfound;
-
-        /* No appropriate section found */
-        SetLastError(ERROR_INVALID_PARAMETER);
-        goto done;
+        dwFullLength = lstrlenW(CallbackInfo.BestSection);
+        if (RequiredSize != NULL)
+            *RequiredSize = dwFullLength + 1;
 
-sectionfound:
-        dwFullLength = lstrlenW(SectionName);
-        if (InfSectionWithExt != NULL && InfSectionWithExtSize != 0)
+        if (InfSectionWithExtSize > 0)
         {
-            if (InfSectionWithExtSize < (dwFullLength + 1))
+            if (InfSectionWithExtSize < dwFullLength + 1)
             {
                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
                 goto done;
             }
-
-            lstrcpyW(InfSectionWithExt, SectionName);
-            if (Extension != NULL)
+            strcpyW(InfSectionWithExt, CallbackInfo.BestSection);
+            if (Extension)
             {
-                DWORD dwLength = lstrlenW(SectionName);
+                DWORD dwLength = lstrlenW(InfSectionName);
                 *Extension = (dwLength == dwFullLength) ? NULL : &InfSectionWithExt[dwLength];
             }
         }
 
-        if (RequiredSize != NULL)
-            *RequiredSize = dwFullLength + 1;
-
         ret = TRUE;
     }
 
@@ -1152,7 +1368,7 @@ SetupDiGetClassDescriptionA(
     IN CONST GUID *ClassGuid,
     OUT PSTR ClassDescription,
     IN DWORD ClassDescriptionSize,
-    OUT PDWORD RequiredSize  OPTIONAL)
+    OUT PDWORD RequiredSize OPTIONAL)
 {
   return SetupDiGetClassDescriptionExA(ClassGuid, ClassDescription,
                                        ClassDescriptionSize,
@@ -1167,7 +1383,7 @@ SetupDiGetClassDescriptionW(
     IN CONST GUID *ClassGuid,
     OUT PWSTR ClassDescription,
     IN DWORD ClassDescriptionSize,
-    OUT PDWORD RequiredSize  OPTIONAL)
+    OUT PDWORD RequiredSize OPTIONAL)
 {
   return SetupDiGetClassDescriptionExW(ClassGuid, ClassDescription,
                                        ClassDescriptionSize,
@@ -1182,8 +1398,8 @@ SetupDiGetClassDescriptionExA(
     IN CONST GUID *ClassGuid,
     OUT PSTR ClassDescription,
     IN DWORD ClassDescriptionSize,
-    OUT PDWORD RequiredSize  OPTIONAL,
-    IN PCSTR MachineName  OPTIONAL,
+    OUT PDWORD RequiredSize OPTIONAL,
+    IN PCSTR MachineName OPTIONAL,
     IN PVOID Reserved)
 {
     PWCHAR ClassDescriptionW;
@@ -1240,8 +1456,8 @@ SetupDiGetClassDescriptionExW(
     IN CONST GUID *ClassGuid,
     OUT PWSTR ClassDescription,
     IN DWORD ClassDescriptionSize,
-    OUT PDWORD RequiredSize  OPTIONAL,
-    IN PCWSTR MachineName  OPTIONAL,
+    OUT PDWORD RequiredSize OPTIONAL,
+    IN PCWSTR MachineName OPTIONAL,
     IN PVOID Reserved)
 {
     HKEY hKey = INVALID_HANDLE_VALUE;
@@ -1303,9 +1519,9 @@ cleanup:
  */
 HDEVINFO WINAPI
 SetupDiGetClassDevsA(
-    IN CONST GUID *ClassGuid  OPTIONAL,
-    IN PCSTR Enumerator  OPTIONAL,
-    IN HWND hwndParent  OPTIONAL,
+    IN CONST GUID *ClassGuid OPTIONAL,
+    IN PCSTR Enumerator OPTIONAL,
+    IN HWND hwndParent OPTIONAL,
     IN DWORD Flags)
 {
     return SetupDiGetClassDevsExA(ClassGuid, Enumerator, hwndParent,
@@ -1317,9 +1533,9 @@ SetupDiGetClassDevsA(
  */
 HDEVINFO WINAPI
 SetupDiGetClassDevsW(
-    IN CONST GUID *ClassGuid  OPTIONAL,
-    IN PCWSTR Enumerator  OPTIONAL,
-    IN HWND hwndParent  OPTIONAL,
+    IN CONST GUID *ClassGuid OPTIONAL,
+    IN PCWSTR Enumerator OPTIONAL,
+    IN HWND hwndParent OPTIONAL,
     IN DWORD Flags)
 {
     return SetupDiGetClassDevsExW(ClassGuid, Enumerator, hwndParent,
@@ -1331,12 +1547,12 @@ SetupDiGetClassDevsW(
  */
 HDEVINFO WINAPI
 SetupDiGetClassDevsExA(
-    IN CONST GUID *ClassGuid  OPTIONAL,
-    IN PCSTR Enumerator  OPTIONAL,
-    IN HWND hwndParent  OPTIONAL,
+    IN CONST GUID *ClassGuid OPTIONAL,
+    IN PCSTR Enumerator OPTIONAL,
+    IN HWND hwndParent OPTIONAL,
     IN DWORD Flags,
-    IN HDEVINFO DeviceInfoSet  OPTIONAL,
-    IN PCSTR MachineName  OPTIONAL,
+    IN HDEVINFO DeviceInfoSet OPTIONAL,
+    IN PCSTR MachineName OPTIONAL,
     IN PVOID Reserved)
 {
     HDEVINFO ret;
@@ -1883,12 +2099,12 @@ cleanup:
  */
 HDEVINFO WINAPI
 SetupDiGetClassDevsExW(
-    IN CONST GUID *ClassGuid  OPTIONAL,
-    IN PCWSTR Enumerator  OPTIONAL,
-    IN HWND hwndParent  OPTIONAL,
+    IN CONST GUID *ClassGuid OPTIONAL,
+    IN PCWSTR Enumerator OPTIONAL,
+    IN HWND hwndParent OPTIONAL,
     IN DWORD Flags,
-    IN HDEVINFO DeviceInfoSet  OPTIONAL,
-    IN PCWSTR MachineName  OPTIONAL,
+    IN HDEVINFO DeviceInfoSet OPTIONAL,
+    IN PCWSTR MachineName OPTIONAL,
     IN PVOID Reserved)
 {
     HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
@@ -2088,7 +2304,7 @@ SetupDiGetClassImageList(
 BOOL WINAPI
 SetupDiGetClassImageListExA(
     OUT PSP_CLASSIMAGELIST_DATA ClassImageListData,
-    IN PCSTR MachineName  OPTIONAL,
+    IN PCSTR MachineName OPTIONAL,
     IN PVOID Reserved)
 {
     PWSTR MachineNameW = NULL;
@@ -2115,7 +2331,7 @@ SetupDiGetClassImageListExA(
 BOOL WINAPI
 SetupDiGetClassImageListExW(
     OUT PSP_CLASSIMAGELIST_DATA ClassImageListData,
-    IN PCWSTR MachineName  OPTIONAL,
+    IN PCWSTR MachineName OPTIONAL,
     IN PVOID Reserved)
 {
     BOOL ret = FALSE;
@@ -2172,8 +2388,8 @@ cleanup:
 BOOL WINAPI
 SetupDiLoadClassIcon(
     IN CONST GUID *ClassGuid,
-    OUT HICON *LargeIcon  OPTIONAL,
-    OUT PINT MiniIconIndex  OPTIONAL)
+    OUT HICON *LargeIcon OPTIONAL,
+    OUT PINT MiniIconIndex OPTIONAL)
 {
     BOOL ret = FALSE;
 
@@ -2287,7 +2503,7 @@ cleanup:
 BOOL WINAPI
 SetupDiEnumDeviceInterfaces(
     IN HDEVINFO DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL,
+    IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
     IN CONST GUID *InterfaceClassGuid,
     IN DWORD MemberIndex,
     OUT PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
@@ -2464,10 +2680,10 @@ BOOL WINAPI
 SetupDiGetDeviceInterfaceDetailA(
     IN HDEVINFO DeviceInfoSet,
     IN PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
-    OUT PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData  OPTIONAL,
+    OUT PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData OPTIONAL,
     IN DWORD DeviceInterfaceDetailDataSize,
-    OUT PDWORD RequiredSize  OPTIONAL,
-    OUT PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL)
+    OUT PDWORD RequiredSize OPTIONAL,
+    OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
 {
     PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailDataW = NULL;
     DWORD sizeW = 0, sizeA;
@@ -2535,10 +2751,10 @@ BOOL WINAPI
 SetupDiGetDeviceInterfaceDetailW(
     IN HDEVINFO DeviceInfoSet,
     IN PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
-    OUT PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData  OPTIONAL,
+    OUT PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData OPTIONAL,
     IN DWORD DeviceInterfaceDetailDataSize,
-    OUT PDWORD RequiredSize  OPTIONAL,
-    OUT PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL)
+    OUT PDWORD RequiredSize OPTIONAL,
+    OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
 {
     BOOL ret = FALSE;
 
@@ -2603,10 +2819,10 @@ SetupDiGetDeviceRegistryPropertyA(
     IN HDEVINFO DeviceInfoSet,
     IN PSP_DEVINFO_DATA DeviceInfoData,
     IN DWORD Property,
-    OUT PDWORD PropertyRegDataType  OPTIONAL,
-    OUT PBYTE PropertyBuffer  OPTIONAL,
+    OUT PDWORD PropertyRegDataType OPTIONAL,
+    OUT PBYTE PropertyBuffer OPTIONAL,
     IN DWORD PropertyBufferSize,
-    OUT PDWORD  RequiredSize  OPTIONAL)
+    OUT PDWORD  RequiredSize OPTIONAL)
 {
     BOOL bResult;
     BOOL bIsStringProperty;
@@ -2690,10 +2906,10 @@ SetupDiGetDeviceRegistryPropertyW(
     IN HDEVINFO DeviceInfoSet,
     IN PSP_DEVINFO_DATA DeviceInfoData,
     IN DWORD Property,
-    OUT PDWORD PropertyRegDataType  OPTIONAL,
-    OUT PBYTE PropertyBuffer  OPTIONAL,
+    OUT PDWORD PropertyRegDataType OPTIONAL,
+    OUT PBYTE PropertyBuffer OPTIONAL,
     IN DWORD PropertyBufferSize,
-    OUT PDWORD  RequiredSize  OPTIONAL)
+    OUT PDWORD  RequiredSize OPTIONAL)
 {
     HKEY hEnumKey, hKey;
     DWORD rc;
@@ -2889,7 +3105,7 @@ SetupDiSetDeviceRegistryPropertyA(
     IN HDEVINFO DeviceInfoSet,
     IN OUT PSP_DEVINFO_DATA DeviceInfoData,
     IN DWORD Property,
-    IN CONST BYTE *PropertyBuffer  OPTIONAL,
+    IN CONST BYTE *PropertyBuffer OPTIONAL,
     IN DWORD PropertyBufferSize)
 {
     FIXME("%p %p 0x%lx %p 0x%lx\n", DeviceInfoSet, DeviceInfoData,
@@ -2906,7 +3122,7 @@ SetupDiSetDeviceRegistryPropertyW(
     IN HDEVINFO DeviceInfoSet,
     IN OUT PSP_DEVINFO_DATA DeviceInfoData,
     IN DWORD Property,
-    IN CONST BYTE *PropertyBuffer  OPTIONAL,
+    IN CONST BYTE *PropertyBuffer OPTIONAL,
     IN DWORD PropertyBufferSize)
 {
     struct DeviceInfoSet *list;
@@ -3038,10 +3254,10 @@ SetupDiSetDeviceRegistryPropertyW(
  */
 BOOL WINAPI
 SetupDiInstallClassA(
-    IN HWND hwndParent  OPTIONAL,
+    IN HWND hwndParent OPTIONAL,
     IN PCSTR InfFileName,
     IN DWORD Flags,
-    IN HSPFILEQ FileQueue  OPTIONAL)
+    IN HSPFILEQ FileQueue OPTIONAL)
 {
     return SetupDiInstallClassExA(hwndParent, InfFileName, Flags, FileQueue, NULL, NULL, NULL);
 }
@@ -3052,10 +3268,10 @@ SetupDiInstallClassA(
  */
 BOOL WINAPI
 SetupDiInstallClassW(
-    IN HWND hwndParent  OPTIONAL,
+    IN HWND hwndParent OPTIONAL,
     IN PCWSTR InfFileName,
     IN DWORD Flags,
-    IN HSPFILEQ FileQueue  OPTIONAL)
+    IN HSPFILEQ FileQueue OPTIONAL)
 {
     return SetupDiInstallClassExW(hwndParent, InfFileName, Flags, FileQueue, NULL, NULL, NULL);
 }
@@ -3066,11 +3282,11 @@ SetupDiInstallClassW(
  */
 BOOL WINAPI
 SetupDiInstallClassExA(
-    IN HWND hwndParent  OPTIONAL,
-    IN PCSTR InfFileName  OPTIONAL,
+    IN HWND hwndParent OPTIONAL,
+    IN PCSTR InfFileName OPTIONAL,
     IN DWORD Flags,
-    IN HSPFILEQ FileQueue  OPTIONAL,
-    IN CONST GUID *InterfaceClassGuid  OPTIONAL,
+    IN HSPFILEQ FileQueue OPTIONAL,
+    IN CONST GUID *InterfaceClassGuid OPTIONAL,
     IN PVOID Reserved1,
     IN PVOID Reserved2)
 {
@@ -3172,11 +3388,11 @@ cleanup:
  */
 BOOL WINAPI
 SetupDiInstallClassExW(
-    IN HWND hwndParent  OPTIONAL,
-    IN PCWSTR InfFileName  OPTIONAL,
+    IN HWND hwndParent OPTIONAL,
+    IN PCWSTR InfFileName OPTIONAL,
     IN DWORD Flags,
-    IN HSPFILEQ FileQueue  OPTIONAL,
-    IN CONST GUID *InterfaceClassGuid  OPTIONAL,
+    IN HSPFILEQ FileQueue OPTIONAL,
+    IN CONST GUID *InterfaceClassGuid OPTIONAL,
     IN PVOID Reserved1,
     IN PVOID Reserved2)
 {
@@ -3287,7 +3503,7 @@ SetupDiInstallClassExW(
                 SectionName,
                 SPINST_REGISTRY | SPINST_FILES | SPINST_BITREG | SPINST_INIFILES | SPINST_INI2REG,
                 hRootKey,
-                NULL, /* SourceRootPath */
+                NULL, /* FIXME: SourceRootPath */
                 !(Flags & DI_NOVCP) && (Flags & DI_FORCECOPY) ? SP_COPY_FORCE_IN_USE : 0, /* CopyFlags */
                 SetupDefaultQueueCallbackW,
                 callback_context,
@@ -3332,7 +3548,7 @@ cleanup:
  */
 HKEY WINAPI
 SetupDiOpenClassRegKey(
-    IN CONST GUID *ClassGuid  OPTIONAL,
+    IN CONST GUID *ClassGuid OPTIONAL,
     IN REGSAM samDesired)
 {
     return SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,
@@ -3345,10 +3561,10 @@ SetupDiOpenClassRegKey(
  */
 HKEY WINAPI
 SetupDiOpenClassRegKeyExA(
-    IN CONST GUID *ClassGuid  OPTIONAL,
+    IN CONST GUID *ClassGuid OPTIONAL,
     IN REGSAM samDesired,
     IN DWORD Flags,
-    IN PCSTR MachineName  OPTIONAL,
+    IN PCSTR MachineName OPTIONAL,
     IN PVOID Reserved)
 {
     PWSTR MachineNameW = NULL;
@@ -3378,10 +3594,10 @@ SetupDiOpenClassRegKeyExA(
  */
 HKEY WINAPI
 SetupDiOpenClassRegKeyExW(
-    IN CONST GUID* ClassGuid  OPTIONAL,
+    IN CONST GUID* ClassGuid OPTIONAL,
     IN REGSAM samDesired,
     IN DWORD Flags,
-    IN PCWSTR MachineName  OPTIONAL,
+    IN PCWSTR MachineName OPTIONAL,
     IN PVOID Reserved)
 {
     LPWSTR lpGuidString = NULL;
@@ -3489,7 +3705,7 @@ SetupDiOpenDeviceInterfaceW(
     IN HDEVINFO DeviceInfoSet,
     IN PCWSTR DevicePath,
     IN DWORD OpenFlags,
-    OUT PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData  OPTIONAL)
+    OUT PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData OPTIONAL)
 {
     FIXME("%p %s %08lx %p\n",
         DeviceInfoSet, debugstr_w(DevicePath), OpenFlags, DeviceInterfaceData);
@@ -3504,7 +3720,7 @@ SetupDiOpenDeviceInterfaceA(
     IN HDEVINFO DeviceInfoSet,
     IN PCSTR DevicePath,
     IN DWORD OpenFlags,
-    OUT PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData  OPTIONAL)
+    OUT PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData OPTIONAL)
 {
     LPWSTR DevicePathW = NULL;
     BOOL bResult;
@@ -3529,8 +3745,8 @@ SetupDiOpenDeviceInterfaceA(
 BOOL WINAPI
 SetupDiSetClassInstallParamsA(
     IN HDEVINFO  DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL,
-    IN PSP_CLASSINSTALL_HEADER ClassInstallParams  OPTIONAL,
+    IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
+    IN PSP_CLASSINSTALL_HEADER ClassInstallParams OPTIONAL,
     IN DWORD ClassInstallParamsSize)
 {
     FIXME("%p %p %x %lu\n",DeviceInfoSet, DeviceInfoData,
@@ -3544,8 +3760,8 @@ SetupDiSetClassInstallParamsA(
 BOOL WINAPI
 SetupDiSetClassInstallParamsW(
     IN HDEVINFO DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL,
-    IN PSP_CLASSINSTALL_HEADER ClassInstallParams  OPTIONAL,
+    IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
+    IN PSP_CLASSINSTALL_HEADER ClassInstallParams OPTIONAL,
     IN DWORD ClassInstallParamsSize)
 {
     struct DeviceInfoSet *list;
@@ -3760,7 +3976,7 @@ BOOL WINAPI
 SetupDiCallClassInstaller(
     IN DI_FUNCTION InstallFunction,
     IN HDEVINFO DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL)
+    IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
 {
     BOOL ret = FALSE;
 
@@ -4185,7 +4401,7 @@ SetupDiGetDeviceInfoListDetailW(
 BOOL WINAPI
 SetupDiGetDeviceInstallParamsA(
     IN HDEVINFO DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL,
+    IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
     OUT PSP_DEVINSTALL_PARAMS_A DeviceInstallParams)
 {
     SP_DEVINSTALL_PARAMS_W deviceInstallParamsW;
@@ -4228,7 +4444,7 @@ SetupDiGetDeviceInstallParamsA(
 BOOL WINAPI
 SetupDiGetDeviceInstallParamsW(
     IN HDEVINFO DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL,
+    IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
     OUT PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
 {
     struct DeviceInfoSet *list;
@@ -4322,7 +4538,7 @@ CheckDeviceInstallParameters(
 BOOL WINAPI
 SetupDiSetDeviceInstallParamsW(
     IN HDEVINFO DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL,
+    IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
     IN PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
 {
     struct DeviceInfoSet *list;
@@ -4363,9 +4579,9 @@ BOOL WINAPI
 SetupDiGetDeviceInstanceIdA(
     IN HDEVINFO DeviceInfoSet,
     IN PSP_DEVINFO_DATA DeviceInfoData,
-    OUT PSTR DeviceInstanceId  OPTIONAL,
+    OUT PSTR DeviceInstanceId OPTIONAL,
     IN DWORD DeviceInstanceIdSize,
-    OUT PDWORD RequiredSize  OPTIONAL)
+    OUT PDWORD RequiredSize OPTIONAL)
 {
     PWSTR DeviceInstanceIdW = NULL;
     BOOL ret = FALSE;
@@ -4410,9 +4626,9 @@ BOOL WINAPI
 SetupDiGetDeviceInstanceIdW(
     IN HDEVINFO DeviceInfoSet,
     IN PSP_DEVINFO_DATA DeviceInfoData,
-    OUT PWSTR DeviceInstanceId  OPTIONAL,
+    OUT PWSTR DeviceInstanceId OPTIONAL,
     IN DWORD DeviceInstanceIdSize,
-    OUT PDWORD RequiredSize  OPTIONAL)
+    OUT PDWORD RequiredSize OPTIONAL)
 {
     BOOL ret = FALSE;
 
@@ -4459,10 +4675,10 @@ SetupDiGetDeviceInstanceIdW(
 BOOL WINAPI
 SetupDiGetClassDevPropertySheetsA(
     IN HDEVINFO DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL,
+    IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
     IN LPPROPSHEETHEADERA PropertySheetHeader,
     IN DWORD PropertySheetHeaderPageListSize,
-    OUT PDWORD RequiredSize  OPTIONAL,
+    OUT PDWORD RequiredSize OPTIONAL,
     IN DWORD PropertySheetType)
 {
     PROPSHEETHEADERW psh;
@@ -4520,10 +4736,10 @@ GetClassDevPropertySheetsCallback(
 BOOL WINAPI
 SetupDiGetClassDevPropertySheetsW(
     IN HDEVINFO DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL,
+    IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
     IN OUT LPPROPSHEETHEADERW PropertySheetHeader,
     IN DWORD PropertySheetHeaderPageListSize,
-    OUT PDWORD RequiredSize  OPTIONAL,
+    OUT PDWORD RequiredSize OPTIONAL,
     IN DWORD PropertySheetType)
 {
     struct DeviceInfoSet *list;
@@ -4656,8 +4872,8 @@ SetupDiCreateDevRegKeyA(
     IN DWORD Scope,
     IN DWORD HwProfile,
     IN DWORD KeyType,
-    IN HINF InfHandle  OPTIONAL,
-    IN PCSTR InfSectionName  OPTIONAL)
+    IN HINF InfHandle OPTIONAL,
+    IN PCSTR InfSectionName OPTIONAL)
 {
     PCWSTR InfSectionNameW = NULL;
     HKEY ret = INVALID_HANDLE_VALUE;
@@ -4749,8 +4965,8 @@ SetupDiCreateDevRegKeyW(
     IN DWORD Scope,
     IN DWORD HwProfile,
     IN DWORD KeyType,
-    IN HINF InfHandle  OPTIONAL,
-    IN PCWSTR InfSectionName  OPTIONAL)
+    IN HINF InfHandle OPTIONAL,
+    IN PCWSTR InfSectionName OPTIONAL)
 {
     struct DeviceInfoSet *list;
     HKEY ret = INVALID_HANDLE_VALUE;
@@ -5094,10 +5310,10 @@ SetupDiCreateDeviceInfoA(
     IN HDEVINFO DeviceInfoSet,
     IN PCSTR DeviceName,
     IN CONST GUID *ClassGuid,
-    IN PCSTR DeviceDescription  OPTIONAL,
-    IN HWND hwndParent  OPTIONAL,
+    IN PCSTR DeviceDescription OPTIONAL,
+    IN HWND hwndParent OPTIONAL,
     IN DWORD CreationFlags,
-    OUT PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL)
+    OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
 {
     LPWSTR DeviceNameW = NULL;
     LPWSTR DeviceDescriptionW = NULL;
@@ -5139,10 +5355,10 @@ SetupDiCreateDeviceInfoW(
     IN HDEVINFO DeviceInfoSet,
     IN PCWSTR DeviceName,
     IN CONST GUID *ClassGuid,
-    IN PCWSTR DeviceDescription  OPTIONAL,
-    IN HWND hwndParent  OPTIONAL,
+    IN PCWSTR DeviceDescription OPTIONAL,
+    IN HWND hwndParent OPTIONAL,
     IN DWORD CreationFlags,
-    OUT PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL)
+    OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
 {
     struct DeviceInfoSet *list;
     BOOL ret = FALSE;
@@ -5639,13 +5855,54 @@ done:
     return Result;
 }
 
+static struct InfFileDetails *
+CreateInfFileDetails(
+    IN LPCWSTR InfFileName)
+{
+    struct InfFileDetails *details;
+    PWCHAR last;
+    DWORD Needed;
+
+    last = strrchrW(InfFileName, '\\');
+    Needed = FIELD_OFFSET(struct InfFileDetails, szData)
+        + strlenW(InfFileName) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
+    if (last != NULL)
+    Needed += (last - InfFileName) * sizeof(WCHAR) + sizeof(UNICODE_NULL);
+
+    details = HeapAlloc(GetProcessHeap(), 0, Needed);
+    if (!details)
+    {
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        return NULL;
+    }
+
+    memset(details, 0, Needed);
+    if (last)
+    {
+        details->DirectoryName = details->szData;
+        details->FullInfFileName = &details->szData[last - InfFileName + 1];
+        strncpyW(details->DirectoryName, InfFileName, last - InfFileName);
+    }
+    else
+        details->FullInfFileName = details->szData;
+    strcpyW(details->FullInfFileName, InfFileName);
+    ReferenceInfFile(details);
+    details->hInf = SetupOpenInfFileW(InfFileName, NULL, INF_STYLE_WIN4, NULL);
+    if (details->hInf == INVALID_HANDLE_VALUE)
+    {
+        HeapFree(GetProcessHeap(), 0, details);
+        return NULL;
+    }
+    return details;
+}
+
 /***********************************************************************
  *             SetupDiBuildDriverInfoList (SETUPAPI.@)
  */
 BOOL WINAPI
 SetupDiBuildDriverInfoList(
     IN HDEVINFO DeviceInfoSet,
-    IN OUT PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL,
+    IN OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
     IN DWORD DriverType)
 {
     struct DeviceInfoSet *list;
@@ -5803,23 +6060,9 @@ SetupDiBuildDriverInfoList(
                 strcpyW(pFullFilename, filename);
                 TRACE("Opening file %s\n", debugstr_w(FullInfFileName));
 
-                currentInfFileDetails = HeapAlloc(
-                    GetProcessHeap(),
-                    0,
-                    FIELD_OFFSET(struct InfFileDetails, FullInfFileName) + strlenW(FullInfFileName) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
+                currentInfFileDetails = CreateInfFileDetails(FullInfFileName);
                 if (!currentInfFileDetails)
                     continue;
-                memset(currentInfFileDetails, 0, sizeof(struct InfFileDetails));
-                strcpyW(currentInfFileDetails->FullInfFileName, FullInfFileName);
-
-                currentInfFileDetails->hInf = SetupOpenInfFileW(FullInfFileName, NULL, INF_STYLE_WIN4, NULL);
-                ReferenceInfFile(currentInfFileDetails);
-                if (currentInfFileDetails->hInf == INVALID_HANDLE_VALUE)
-                {
-                    HeapFree(GetProcessHeap(), 0, currentInfFileDetails);
-                    currentInfFileDetails = NULL;
-                    continue;
-                }
 
                 if (!GetVersionInformationFromInfFile(
                     currentInfFileDetails->hInf,
@@ -5828,8 +6071,7 @@ SetupDiBuildDriverInfoList(
                     &DriverDate,
                     &DriverVersion))
                 {
-                    SetupCloseInfFile(currentInfFileDetails->hInf);
-                    HeapFree(GetProcessHeap(), 0, currentInfFileDetails->hInf);
+                    DereferenceInfFile(currentInfFileDetails);
                     currentInfFileDetails = NULL;
                     continue;
                 }
@@ -5953,7 +6195,7 @@ SetupDiBuildDriverInfoList(
                                 DriverAlreadyAdded = FALSE;
                                 for (DriverRank = 0, currentId = (LPCWSTR)HardwareIDs; !DriverAlreadyAdded && *currentId; currentId += strlenW(currentId) + 1, DriverRank++)
                                 {
-                                    if (wcsicmp(DeviceId, currentId) == 0)
+                                    if (strcmpiW(DeviceId, currentId) == 0)
                                     {
                                         AddDriverToList(
                                             pDriverListHead,
@@ -5974,7 +6216,7 @@ SetupDiBuildDriverInfoList(
                                 {
                                     for (DriverRank = 0, currentId = (LPCWSTR)CompatibleIDs; !DriverAlreadyAdded && *currentId; currentId += strlenW(currentId) + 1, DriverRank++)
                                     {
-                                        if (wcsicmp(DeviceId, currentId) == 0)
+                                        if (strcmpiW(DeviceId, currentId) == 0)
                                         {
                                             AddDriverToList(
                                                 pDriverListHead,
@@ -6068,7 +6310,7 @@ SetupDiDeleteDeviceInfo(
 BOOL WINAPI
 SetupDiDestroyDriverInfoList(
     IN HDEVINFO DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL,
+    IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
     IN DWORD DriverType)
 {
     struct DeviceInfoSet *list;
@@ -6155,7 +6397,7 @@ SetupDiOpenDeviceInfoA(
     IN PCSTR DeviceInstanceId,
     IN HWND hwndParent OPTIONAL,
     IN DWORD OpenFlags,
-    OUT PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL)
+    OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
 {
     LPWSTR DeviceInstanceIdW = NULL;
     BOOL bResult;
@@ -6184,7 +6426,7 @@ SetupDiOpenDeviceInfoW(
     IN PCWSTR DeviceInstanceId,
     IN HWND hwndParent OPTIONAL,
     IN DWORD OpenFlags,
-    OUT PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL)
+    OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
 {
     struct DeviceInfoSet *list;
     HKEY hEnumKey, hKey = NULL;
@@ -6293,7 +6535,7 @@ cleanup:
 BOOL WINAPI
 SetupDiEnumDriverInfoA(
     IN HDEVINFO DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL,
+    IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
     IN DWORD DriverType,
     IN DWORD MemberIndex,
     OUT PSP_DRVINFO_DATA_A DriverInfoData)
@@ -6357,7 +6599,7 @@ SetupDiEnumDriverInfoA(
 BOOL WINAPI
 SetupDiEnumDriverInfoW(
     IN HDEVINFO DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL,
+    IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
     IN DWORD DriverType,
     IN DWORD MemberIndex,
     OUT PSP_DRVINFO_DATA_W DriverInfoData)
@@ -6461,7 +6703,7 @@ SetupDiGetSelectedDevice(
 BOOL WINAPI
 SetupDiGetSelectedDriverA(
     IN HDEVINFO DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL,
+    IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
     OUT PSP_DRVINFO_DATA_A DriverInfoData)
 {
     SP_DRVINFO_DATA_V2_W driverInfoData2W;
@@ -6521,7 +6763,7 @@ SetupDiGetSelectedDriverA(
 BOOL WINAPI
 SetupDiGetSelectedDriverW(
     IN HDEVINFO DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL,
+    IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
     OUT PSP_DRVINFO_DATA_W DriverInfoData)
 {
     BOOL ret = FALSE;
@@ -6605,8 +6847,8 @@ SetupDiSetSelectedDevice(
 BOOL WINAPI
 SetupDiSetSelectedDriverA(
     IN HDEVINFO DeviceInfoSet,
-    IN OUT PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL,
-    IN OUT PSP_DRVINFO_DATA_A DriverInfoData  OPTIONAL)
+    IN OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
+    IN OUT PSP_DRVINFO_DATA_A DriverInfoData OPTIONAL)
 {
     SP_DRVINFO_DATA_V1_W DriverInfoDataW;
     PSP_DRVINFO_DATA_W pDriverInfoDataW = NULL;
@@ -6668,8 +6910,8 @@ SetupDiSetSelectedDriverA(
 BOOL WINAPI
 SetupDiSetSelectedDriverW(
     IN HDEVINFO DeviceInfoSet,
-    IN OUT PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL,
-    IN OUT PSP_DRVINFO_DATA_W DriverInfoData  OPTIONAL)
+    IN OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
+    IN OUT PSP_DRVINFO_DATA_W DriverInfoData OPTIONAL)
 {
     BOOL ret = FALSE;
 
@@ -6755,11 +6997,11 @@ SetupDiSetSelectedDriverW(
 BOOL WINAPI
 SetupDiGetDriverInfoDetailA(
     IN HDEVINFO DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL,
+    IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
     IN PSP_DRVINFO_DATA_A DriverInfoData,
-    IN OUT PSP_DRVINFO_DETAIL_DATA_A DriverInfoDetailData  OPTIONAL,
+    IN OUT PSP_DRVINFO_DETAIL_DATA_A DriverInfoDetailData OPTIONAL,
     IN DWORD DriverInfoDetailDataSize,
-    OUT PDWORD RequiredSize  OPTIONAL)
+    OUT PDWORD RequiredSize OPTIONAL)
 {
     SP_DRVINFO_DATA_V2_W DriverInfoDataW;
     PSP_DRVINFO_DETAIL_DATA_W DriverInfoDetailDataW = NULL;
@@ -6956,11 +7198,11 @@ Cleanup:
 BOOL WINAPI
 SetupDiGetDriverInfoDetailW(
     IN HDEVINFO DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL,
+    IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
     IN PSP_DRVINFO_DATA_W DriverInfoData,
-    IN OUT PSP_DRVINFO_DETAIL_DATA_W DriverInfoDetailData  OPTIONAL,
+    IN OUT PSP_DRVINFO_DETAIL_DATA_W DriverInfoDetailData OPTIONAL,
     IN DWORD DriverInfoDetailDataSize,
-    OUT PDWORD RequiredSize  OPTIONAL)
+    OUT PDWORD RequiredSize OPTIONAL)
 {
     BOOL ret = FALSE;
 
@@ -7032,7 +7274,7 @@ SetupDiGetDriverInfoDetailW(
         DeviceID = HardwareIDs;
         while (DeviceID && *DeviceID && (size = wcslen(DeviceID)) + 1 < sizeLeft)
         {
-            TRACE("Adding %S to list\n", DeviceID);
+            TRACE("Adding %s to list\n", debugstr_w(DeviceID));
             wcscpy(pBuffer, DeviceID);
             DeviceID += size + 1;
             pBuffer += size + 1;
@@ -7049,7 +7291,7 @@ SetupDiGetDriverInfoDetailW(
         DeviceID = CompatibleIDs;
         while (DeviceID && *DeviceID && (size = wcslen(DeviceID)) + 1 < sizeLeft)
         {
-            TRACE("Adding %S to list\n", DeviceID);
+            TRACE("Adding %s to list\n", debugstr_w(DeviceID));
             wcscpy(pBuffer, DeviceID);
             DeviceID += size + 1;
             pBuffer += size + 1;
@@ -7280,7 +7522,7 @@ cleanup:
 BOOL WINAPI
 SetupDiSelectBestCompatDrv(
     IN HDEVINFO DeviceInfoSet,
-    IN OUT PSP_DEVINFO_DATA DeviceInfoData  OPTIONAL)
+    IN OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
 {
     SP_DRVINFO_DATA_W drvInfoData;
     BOOL ret;
@@ -7378,7 +7620,7 @@ SetupDiInstallDriverFiles(
         }
         ret = SetupInstallFromInfSectionW(InstallParams.hwndParent,
             SelectedDriver->InfFileDetails->hInf, SectionName,
-            SPINST_FILES, NULL, NULL, SP_COPY_NEWER,
+            SPINST_FILES, NULL, SelectedDriver->InfFileDetails->DirectoryName, SP_COPY_NEWER,
             InstallMsgHandler, InstallMsgHandlerContext,
             DeviceInfoSet, DeviceInfoData);
         if (!ret)
@@ -7388,7 +7630,7 @@ SetupDiInstallDriverFiles(
         lstrcatW(SectionName, DotCoInstallers);
         ret = SetupInstallFromInfSectionW(InstallParams.hwndParent,
             SelectedDriver->InfFileDetails->hInf, SectionName,
-            SPINST_FILES, NULL, NULL, SP_COPY_NEWER,
+            SPINST_FILES, NULL, SelectedDriver->InfFileDetails->DirectoryName, SP_COPY_NEWER,
             InstallMsgHandler, InstallMsgHandlerContext,
             DeviceInfoSet, DeviceInfoData);
         if (!ret)
@@ -7485,7 +7727,7 @@ SetupDiRegisterCoDeviceInstallers(
         }
         Result = SetupInstallFromInfSectionW(InstallParams.hwndParent,
             SelectedDriver->InfFileDetails->hInf, SectionName,
-            DoAction, hKey, NULL, SP_COPY_NEWER,
+            DoAction, hKey, SelectedDriver->InfFileDetails->DirectoryName, SP_COPY_NEWER,
             SetupDefaultQueueCallback, Context,
             DeviceInfoSet, DeviceInfoData);
         if (!Result)
@@ -7792,7 +8034,7 @@ SetupDiInstallDevice(
     pSectionName = &SectionName[strlenW(SectionName)];
 
     /* Get information from [Version] section */
-    if (!SetupDiGetINFClassW(SelectedDriver->Details.InfFileName, &ClassGuid, ClassName, MAX_CLASS_NAME_LEN, &RequiredSize))
+    if (!SetupDiGetINFClassW(SelectedDriver->InfFileDetails->FullInfFileName, &ClassGuid, ClassName, MAX_CLASS_NAME_LEN, &RequiredSize))
         goto cleanup;
     /* Format ClassGuid to a string */
     if (UuidToStringW((UUID*)&ClassGuid, &lpGuidString) != RPC_S_OK)
@@ -7834,7 +8076,7 @@ SetupDiInstallDevice(
     *pSectionName = '\0';
     Result = SetupInstallFromInfSectionW(InstallParams.hwndParent,
         SelectedDriver->InfFileDetails->hInf, SectionName,
-        DoAction, hKey, NULL, SP_COPY_NEWER,
+        DoAction, hKey, SelectedDriver->InfFileDetails->DirectoryName, SP_COPY_NEWER,
         SetupDefaultQueueCallback, Context,
         DeviceInfoSet, DeviceInfoData);
     if (!Result)
@@ -7854,7 +8096,7 @@ SetupDiInstallDevice(
     TRACE("InfSectionExt   : '%s'\n", debugstr_w(&SectionName[strlenW(SelectedDriver->Details.SectionName)]));
     TRACE("MatchingDeviceId: '%s'\n", debugstr_w(SelectedDriver->MatchingId));
     TRACE("ProviderName    : '%s'\n", debugstr_w(SelectedDriver->Info.ProviderName));
-    swprintf(Buffer, L"%u-%u-%u", DriverDate.wMonth, DriverDate.wDay, DriverDate.wYear);
+    sprintfW(Buffer, L"%u-%u-%u", DriverDate.wMonth, DriverDate.wDay, DriverDate.wYear);
     rc = RegSetValueEx(hKey, REGSTR_DRIVER_DATE, 0, REG_SZ, (const BYTE *)Buffer, (strlenW(Buffer) + 1) * sizeof(WCHAR));
     if (rc == ERROR_SUCCESS)
         rc = RegSetValueEx(hKey, REGSTR_DRIVER_DATE_DATA, 0, REG_BINARY, (const BYTE *)&SelectedDriver->Info.DriverDate, sizeof(FILETIME));
@@ -7862,7 +8104,7 @@ SetupDiInstallDevice(
         rc = RegSetValueEx(hKey, REGSTR_VAL_DRVDESC, 0, REG_SZ, (const BYTE *)SelectedDriver->Info.Description, (strlenW(SelectedDriver->Info.Description) + 1) * sizeof(WCHAR));
     if (rc == ERROR_SUCCESS)
     {
-        swprintf(Buffer, L"%u.%u.%u.%u", fullVersion.HighPart >> 16, fullVersion.HighPart & 0xffff, fullVersion.LowPart >> 16, fullVersion.LowPart & 0xffff);
+        sprintfW(Buffer, L"%u.%u.%u.%u", fullVersion.HighPart >> 16, fullVersion.HighPart & 0xffff, fullVersion.LowPart >> 16, fullVersion.LowPart & 0xffff);
         rc = RegSetValueEx(hKey, REGSTR_DRIVER_VERSION, 0, REG_SZ, (const BYTE *)Buffer, (strlenW(Buffer) + 1) * sizeof(WCHAR));
     }
     if (rc == ERROR_SUCCESS)