- Implement SetupDiBuildClassInfoListExA,
  SetupDiClassGuidsFromNameExA, SetupDiCreateDeviceInfoListExA and
  SetupDiOpenClassRegKeyExA using MultiByteToUnicode.
- Retrieve OS version upon process attach.

diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c
index da423c9..8b78832 100644
--- a/dlls/setupapi/devinst.c
+++ b/dlls/setupapi/devinst.c
@@ -38,6 +38,8 @@
 #include "rpc.h"
 #include "rpcdce.h"
 
+#include "setupapi_private.h"
+
 
 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
 
@@ -90,8 +92,25 @@
         LPCSTR MachineName,
         PVOID Reserved)
 {
-    FIXME("\n");
-    return FALSE;
+    LPWSTR MachineNameW = NULL;
+    BOOL bResult;
+
+    TRACE("\n");
+
+    if (MachineName)
+    {
+        MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
+        if (MachineNameW == NULL) return FALSE;
+    }
+
+    bResult = SetupDiBuildClassInfoListExW(Flags, ClassGuidList,
+                                           ClassGuidListSize, RequiredSize,
+                                           MachineNameW, Reserved);
+
+    if (MachineNameW)
+        MyFree(MachineNameW);
+
+    return bResult;
 }
 
 /***********************************************************************
@@ -267,8 +286,36 @@
         LPCSTR MachineName,
         PVOID Reserved)
 {
-  FIXME("\n");
-  return FALSE;
+    LPWSTR ClassNameW = NULL;
+    LPWSTR MachineNameW = NULL;
+    BOOL bResult;
+
+    FIXME("\n");
+
+    ClassNameW = MultiByteToUnicode(ClassName, CP_ACP);
+    if (ClassNameW == NULL)
+        return FALSE;
+
+    if (MachineNameW)
+    {
+        MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
+        if (MachineNameW == NULL)
+        {
+            MyFree(ClassNameW);
+            return FALSE;
+        }
+    }
+
+    bResult = SetupDiClassGuidsFromNameExW(ClassNameW, ClassGuidList,
+                                           ClassGuidListSize, RequiredSize,
+                                           MachineNameW, Reserved);
+
+    if (MachineNameW)
+        MyFree(MachineNameW);
+
+    MyFree(ClassNameW);
+
+    return bResult;
 }
 
 /***********************************************************************
@@ -502,8 +549,25 @@
 			       PCSTR MachineName,
 			       PVOID Reserved)
 {
-  FIXME("\n");
-  return (HDEVINFO)INVALID_HANDLE_VALUE;
+    LPWSTR MachineNameW = NULL;
+    HDEVINFO hDevInfo;
+
+    TRACE("\n");
+
+    if (MachineName)
+    {
+        MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
+        if (MachineNameW == NULL)
+            return (HDEVINFO)INVALID_HANDLE_VALUE;
+    }
+
+    hDevInfo = SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent,
+                                              MachineNameW, Reserved);
+
+    if (MachineNameW)
+        MyFree(MachineNameW);
+
+    return hDevInfo;
 }
 
 /***********************************************************************
@@ -587,17 +651,10 @@
         PWSTR *Extension)
 {
     WCHAR szBuffer[MAX_PATH];
-    OSVERSIONINFOW OsVersionInfo;
     DWORD dwLength;
     DWORD dwFullLength;
     LONG lLineCount = -1;
 
-    OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
-    if (!GetVersionExW(&OsVersionInfo))
-    {
-	return FALSE;
-    }
-
     lstrcpyW(szBuffer, InfSectionName);
     dwLength = lstrlenW(szBuffer);
 
@@ -1048,8 +1105,25 @@
         PCSTR MachineName,
         PVOID Reserved)
 {
-    FIXME("\n");
-    return INVALID_HANDLE_VALUE;
+    PWSTR MachineNameW = NULL;
+    HKEY hKey;
+
+    TRACE("\n");
+
+    if (MachineName)
+    {
+        MachineNameW = MultiByteToUnicode(MachineName, CP_ACP);
+        if (MachineNameW == NULL)
+            return INVALID_HANDLE_VALUE;
+    }
+
+    hKey = SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,
+                                     Flags, MachineNameW, Reserved);
+
+    if (MachineNameW)
+        MyFree(MachineNameW);
+
+    return hKey;
 }
 
 
@@ -1125,7 +1199,7 @@
 }
 
 /***********************************************************************
- *		SetupDiOpenDeviceInterfaceA (SETUPAPI.@)
+ *		SetupDiOpenDeviceInterfaceW (SETUPAPI.@)
  */
 BOOL WINAPI SetupDiOpenDeviceInterfaceW(
        HDEVINFO DeviceInfoSet,
diff --git a/dlls/setupapi/setupapi_private.h b/dlls/setupapi/setupapi_private.h
index 7cd40e4..80d1f55 100644
--- a/dlls/setupapi/setupapi_private.h
+++ b/dlls/setupapi/setupapi_private.h
@@ -54,4 +54,6 @@
 #define _S_IWRITE 0x0080
 #define _S_IREAD  0x0100
 
+extern OSVERSIONINFOW OsVersionInfo;
+
 #endif /* __SETUPAPI_PRIVATE_H */
diff --git a/dlls/setupapi/setupcab.c b/dlls/setupapi/setupcab.c
index 6fc3001..b95f75d 100644
--- a/dlls/setupapi/setupcab.c
+++ b/dlls/setupapi/setupcab.c
@@ -44,6 +44,8 @@
 
 #include "wine/debug.h"
 
+OSVERSIONINFOW OsVersionInfo;
+
 static HINSTANCE CABINET_hInstance = 0;
 
 static HFDI (__cdecl *sc_FDICreate)(PFNALLOC, PFNFREE, PFNOPEN,
@@ -674,6 +676,9 @@
     switch (fdwReason) {
     case DLL_PROCESS_ATTACH:
         DisableThreadLibraryCalls(hinstDLL);
+        OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW);
+        if (!GetVersionExW(&OsVersionInfo))
+            return FALSE;
         break;
     case DLL_PROCESS_DETACH:
         UnloadCABINETDll();