Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / reactos / dll / win32 / setupapi / devinst.c
diff --git a/reactos/dll/win32/setupapi/devinst.c b/reactos/dll/win32/setupapi/devinst.c
deleted file mode 100644 (file)
index b022fae..0000000
+++ /dev/null
@@ -1,5958 +0,0 @@
-/*
- * SetupAPI device installer
- *
- * Copyright 2000 Andreas Mohr for CodeWeavers
- *           2005-2006 HervĂ© Poussineau (hpoussin@reactos.org)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "setupapi_private.h"
-
-/* Unicode constants */
-static const WCHAR BackSlash[] = {'\\',0};
-static const WCHAR DateFormat[]  = {'%','u','-','%','u','-','%','u',0};
-static const WCHAR DotCoInstallers[]  = {'.','C','o','I','n','s','t','a','l','l','e','r','s',0};
-static const WCHAR DotHW[]  = {'.','H','W',0};
-static const WCHAR DotServices[]  = {'.','S','e','r','v','i','c','e','s',0};
-static const WCHAR InfDirectory[] = {'i','n','f','\\',0};
-static const WCHAR InstanceKeyFormat[] = {'%','0','4','l','u',0};
-static const WCHAR Version[]  = {'V','e','r','s','i','o','n',0};
-static const WCHAR VersionFormat[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
-
-static const WCHAR REGSTR_DRIVER_DATE[]  = {'D','r','i','v','e','r','D','a','t','e',0};
-static const WCHAR REGSTR_DRIVER_DATE_DATA[]  = {'D','r','i','v','e','r','D','a','t','e','D','a','t','a',0};
-static const WCHAR REGSTR_DRIVER_VERSION[]  = {'D','r','i','v','e','r','V','e','r','s','i','o','n',0};
-static const WCHAR REGSTR_SECURITY[]  = {'S','e','c','u','r','i','t','y',0};
-static const WCHAR REGSTR_UI_NUMBER_DESC_FORMAT[]  = {'U','I','N','u','m','b','e','r','D','e','s','c','F','o','r','m','a','t',0};
-
-typedef DWORD
-(CALLBACK* CLASS_INSTALL_PROC) (
-    IN DI_FUNCTION InstallFunction,
-    IN HDEVINFO DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL);
-typedef BOOL
-(WINAPI* DEFAULT_CLASS_INSTALL_PROC) (
-    IN HDEVINFO DeviceInfoSet,
-    IN OUT PSP_DEVINFO_DATA DeviceInfoData);
-typedef DWORD
-(CALLBACK* COINSTALLER_PROC) (
-    IN DI_FUNCTION InstallFunction,
-    IN HDEVINFO DeviceInfoSet,
-    IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
-    IN OUT PCOINSTALLER_CONTEXT_DATA Context);
-
-struct CoInstallerElement
-{
-    LIST_ENTRY ListEntry;
-
-    HMODULE Module;
-    COINSTALLER_PROC Function;
-    BOOL DoPostProcessing;
-    PVOID PrivateData;
-};
-
-struct GetSectionCallbackInfo
-{
-    PSP_ALTPLATFORM_INFO PlatformInfo;
-    BYTE ProductType;
-    WORD SuiteMask;
-    DWORD PrefixLength;
-    WCHAR BestSection[LINE_LEN + 1];
-    DWORD BestScore1, BestScore2, BestScore3, BestScore4, BestScore5;
-};
-
-
-
-static void SETUPDI_GuidToString(const GUID *guid, LPWSTR guidStr)
-{
-    static const WCHAR fmt[] = {'{','%','0','8','X','-','%','0','4','X','-',
-        '%','0','4','X','-','%','0','2','X','%','0','2','X','-','%','0','2',
-        'X','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','%',
-        '0','2','X','}',0};
-
-    sprintfW(guidStr, fmt, guid->Data1, guid->Data2, guid->Data3,
-        guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
-        guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
-}
-
-static DWORD
-GetErrorCodeFromCrCode(const IN CONFIGRET cr)
-{
-  switch (cr)
-  {
-    case CR_ACCESS_DENIED:        return ERROR_ACCESS_DENIED;
-    case CR_BUFFER_SMALL:         return ERROR_INSUFFICIENT_BUFFER;
-    case CR_CALL_NOT_IMPLEMENTED: return ERROR_CALL_NOT_IMPLEMENTED;
-    case CR_FAILURE:              return ERROR_GEN_FAILURE;
-    case CR_INVALID_DATA:         return ERROR_INVALID_USER_BUFFER;
-    case CR_INVALID_DEVICE_ID:    return ERROR_INVALID_PARAMETER;
-    case CR_INVALID_MACHINENAME:  return ERROR_INVALID_COMPUTERNAME;
-    case CR_INVALID_DEVNODE:      return ERROR_INVALID_PARAMETER;
-    case CR_INVALID_FLAG:         return ERROR_INVALID_FLAGS;
-    case CR_INVALID_POINTER:      return ERROR_INVALID_PARAMETER;
-    case CR_INVALID_PROPERTY:     return ERROR_INVALID_PARAMETER;
-    case CR_NO_SUCH_DEVNODE:      return ERROR_FILE_NOT_FOUND;
-    case CR_NO_SUCH_REGISTRY_KEY: return ERROR_FILE_NOT_FOUND;
-    case CR_NO_SUCH_VALUE:        return ERROR_FILE_NOT_FOUND;
-    case CR_OUT_OF_MEMORY:        return ERROR_NOT_ENOUGH_MEMORY;
-    case CR_REGISTRY_ERROR:       return ERROR_GEN_FAILURE;
-    case CR_ALREADY_SUCH_DEVINST: return ERROR_DEVINST_ALREADY_EXISTS;
-    case CR_SUCCESS:              return ERROR_SUCCESS;
-    default:                      return ERROR_GEN_FAILURE;
-  }
-
-  /* Does not happen */
-}
-
-/* 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;
-    LPCWSTR pExtensionArchitecture;
-    LPWSTR Fields[6];
-    DWORD i;
-    BOOL ret = FALSE;
-
-    //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};
-
-    TRACE("%s %p 0x%x 0x%x\n",
-        debugstr_w(SectionName), PlatformInfo, ProductType, SuiteMask);
-
-    *ScorePlatform = *ScoreMajorVersion = *ScoreMinorVersion = *ScoreProductType = *ScoreSuiteMask = 0;
-
-    Section = pSetupDuplicateString(SectionName);
-    if (!Section)
-    {
-        TRACE("pSetupDuplicateString() 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("Unknown 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: these fields may be NULL if the information is not provided
-     */
-    Fields[0] = 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) = UNICODE_NULL;
-        }
-    }
-    /* 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;
-
-    if (SectionName[info->PrefixLength] != '.')
-        return TRUE;
-
-    ret = CheckSectionValid(
-        &SectionName[info->PrefixLength],
-        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.@)
- */
-BOOL WINAPI
-SetupDiGetActualSectionToInstallExW(
-    IN HINF InfHandle,
-    IN PCWSTR InfSectionName,
-    IN PSP_ALTPLATFORM_INFO AlternatePlatformInfo OPTIONAL,
-    OUT PWSTR InfSectionWithExt OPTIONAL,
-    IN DWORD InfSectionWithExtSize,
-    OUT PDWORD RequiredSize OPTIONAL,
-    OUT PWSTR* Extension OPTIONAL,
-    IN PVOID Reserved)
-{
-    BOOL ret = FALSE;
-
-    TRACE("%p %s %p %p %lu %p %p %p\n", InfHandle, debugstr_w(InfSectionName),
-        AlternatePlatformInfo, InfSectionWithExt, InfSectionWithExtSize,
-        RequiredSize, Extension, Reserved);
-
-    if (!InfHandle || InfHandle == (HINF)INVALID_HANDLE_VALUE)
-        SetLastError(ERROR_INVALID_HANDLE);
-    else if (!InfSectionName)
-        SetLastError(ERROR_INVALID_PARAMETER);
-    else if (AlternatePlatformInfo && AlternatePlatformInfo->cbSize != sizeof(SP_ALTPLATFORM_INFO))
-        SetLastError(ERROR_INVALID_USER_BUFFER);
-    else if (Reserved != NULL)
-        SetLastError(ERROR_INVALID_PARAMETER);
-    else
-    {
-        static SP_ALTPLATFORM_INFO CurrentPlatform = { 0, };
-        static BYTE CurrentProductType = 0;
-        static WORD CurrentSuiteMask = 0;
-        PSP_ALTPLATFORM_INFO pPlatformInfo = &CurrentPlatform;
-        struct GetSectionCallbackInfo CallbackInfo;
-        DWORD dwFullLength;
-        BYTE ProductType;
-        WORD SuiteMask;
-
-        /* Fill platform info if needed */
-        if (AlternatePlatformInfo)
-        {
-            pPlatformInfo = AlternatePlatformInfo;
-            ProductType = 0;
-            SuiteMask = 0;
-        }
-        else
-        {
-            if (CurrentPlatform.cbSize != sizeof(SP_ALTPLATFORM_INFO))
-            {
-                /* That's the first time we go here. We need to fill in the structure */
-                SYSTEM_INFO SystemInfo;
-                GetSystemInfo(&SystemInfo);
-                CurrentPlatform.cbSize = sizeof(SP_ALTPLATFORM_INFO);
-                CurrentPlatform.Platform = OsVersionInfo.dwPlatformId;
-                CurrentPlatform.MajorVersion = OsVersionInfo.dwMajorVersion;
-                CurrentPlatform.MinorVersion = OsVersionInfo.dwMinorVersion;
-                CurrentPlatform.ProcessorArchitecture = SystemInfo.wProcessorArchitecture;
-                CurrentPlatform.Reserved = 0;
-                CurrentProductType = OsVersionInfo.wProductType;
-                CurrentSuiteMask = OsVersionInfo.wSuiteMask;
-            }
-            ProductType = CurrentProductType;
-            SuiteMask = CurrentSuiteMask;
-        }
-
-        CallbackInfo.PlatformInfo = pPlatformInfo;
-        CallbackInfo.ProductType = ProductType;
-        CallbackInfo.SuiteMask = SuiteMask;
-        CallbackInfo.PrefixLength = strlenW(InfSectionName);
-        CallbackInfo.BestScore1 = ULONG_MAX;
-        CallbackInfo.BestScore2 = ULONG_MAX;
-        CallbackInfo.BestScore3 = ULONG_MAX;
-        CallbackInfo.BestScore4 = ULONG_MAX;
-        CallbackInfo.BestScore5 = ULONG_MAX;
-        strcpyW(CallbackInfo.BestSection, InfSectionName);
-        TRACE("EnumerateSectionsStartingWith(InfSectionName = %S)\n", InfSectionName);
-        if (!EnumerateSectionsStartingWith(
-            InfHandle,
-            InfSectionName,
-            GetSectionCallback,
-            &CallbackInfo))
-        {
-            SetLastError(ERROR_GEN_FAILURE);
-            goto done;
-        }
-        TRACE("CallbackInfo.BestSection = %S\n", CallbackInfo.BestSection);
-
-        dwFullLength = lstrlenW(CallbackInfo.BestSection);
-        if (RequiredSize != NULL)
-            *RequiredSize = dwFullLength + 1;
-
-        if (InfSectionWithExtSize > 0)
-        {
-            if (InfSectionWithExtSize < dwFullLength + 1)
-            {
-                SetLastError(ERROR_INSUFFICIENT_BUFFER);
-                goto done;
-            }
-            strcpyW(InfSectionWithExt, CallbackInfo.BestSection);
-            if (Extension)
-            {
-                DWORD dwLength = lstrlenW(InfSectionName);
-                *Extension = (dwLength == dwFullLength) ? NULL : &InfSectionWithExt[dwLength];
-            }
-        }
-
-        ret = TRUE;
-    }
-
-done:
-    TRACE("Returning %d\n", ret);
-    return ret;
-}
-
-
-BOOL
-CreateDeviceInfo(
-    IN struct DeviceInfoSet *list,
-    IN LPCWSTR InstancePath,
-    IN LPCGUID pClassGuid,
-    OUT struct DeviceInfo **pDeviceInfo)
-{
-    DWORD size;
-    CONFIGRET cr;
-    struct DeviceInfo *deviceInfo;
-
-    *pDeviceInfo = NULL;
-
-    size = FIELD_OFFSET(struct DeviceInfo, Data) + (strlenW(InstancePath) + 1) * sizeof(WCHAR);
-    deviceInfo = HeapAlloc(GetProcessHeap(), 0, size);
-    if (!deviceInfo)
-    {
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return FALSE;
-    }
-    ZeroMemory(deviceInfo, size);
-
-    cr = CM_Locate_DevNode_ExW(&deviceInfo->dnDevInst, (DEVINSTID_W)InstancePath, CM_LOCATE_DEVNODE_PHANTOM, list->hMachine);
-    if (cr != CR_SUCCESS)
-    {
-        SetLastError(GetErrorCodeFromCrCode(cr));
-        return FALSE;
-    }
-
-    deviceInfo->set = list;
-    deviceInfo->InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
-    strcpyW(deviceInfo->Data, InstancePath);
-    deviceInfo->instanceId = deviceInfo->Data;
-    deviceInfo->UniqueId = strrchrW(deviceInfo->Data, '\\');
-    deviceInfo->DeviceDescription = NULL;
-    memcpy(&deviceInfo->ClassGuid, pClassGuid, sizeof(GUID));
-    deviceInfo->CreationFlags = 0;
-    InitializeListHead(&deviceInfo->DriverListHead);
-    InitializeListHead(&deviceInfo->InterfaceListHead);
-
-    *pDeviceInfo = deviceInfo;
-    return TRUE;
-}
-
-
-static BOOL
-DestroyClassInstallParams(struct ClassInstallParams* installParams)
-{
-    HeapFree(GetProcessHeap(), 0, installParams->PropChangeParams);
-    HeapFree(GetProcessHeap(), 0, installParams->AddPropertyPageData);
-    return TRUE;
-}
-
-static BOOL
-DestroyDeviceInfo(struct DeviceInfo *deviceInfo)
-{
-    PLIST_ENTRY ListEntry;
-    struct DriverInfoElement *driverInfo;
-    struct DeviceInterface *deviceInterface;
-
-    while (!IsListEmpty(&deviceInfo->DriverListHead))
-    {
-        ListEntry = RemoveHeadList(&deviceInfo->DriverListHead);
-        driverInfo = CONTAINING_RECORD(ListEntry, struct DriverInfoElement, ListEntry);
-        if (!DestroyDriverInfoElement(driverInfo))
-            return FALSE;
-    }
-    while (!IsListEmpty(&deviceInfo->InterfaceListHead))
-    {
-        ListEntry = RemoveHeadList(&deviceInfo->InterfaceListHead);
-        deviceInterface = CONTAINING_RECORD(ListEntry, struct DeviceInterface, ListEntry);
-        if (!DestroyDeviceInterface(deviceInterface))
-            return FALSE;
-    }
-    DestroyClassInstallParams(&deviceInfo->ClassInstallParams);
-    if (deviceInfo->hmodDevicePropPageProvider)
-        FreeLibrary(deviceInfo->hmodDevicePropPageProvider);
-    return HeapFree(GetProcessHeap(), 0, deviceInfo);
-}
-
-static BOOL
-DestroyDeviceInfoSet(struct DeviceInfoSet* list)
-{
-    PLIST_ENTRY ListEntry;
-    struct DeviceInfo *deviceInfo;
-
-    while (!IsListEmpty(&list->ListHead))
-    {
-        ListEntry = RemoveHeadList(&list->ListHead);
-        deviceInfo = CONTAINING_RECORD(ListEntry, struct DeviceInfo, ListEntry);
-        if (!DestroyDeviceInfo(deviceInfo))
-            return FALSE;
-    }
-    if (list->HKLM != HKEY_LOCAL_MACHINE)
-        RegCloseKey(list->HKLM);
-    CM_Disconnect_Machine(list->hMachine);
-    DestroyClassInstallParams(&list->ClassInstallParams);
-    if (list->hmodClassPropPageProvider)
-        FreeLibrary(list->hmodClassPropPageProvider);
-    return HeapFree(GetProcessHeap(), 0, list);
-}
-
-/***********************************************************************
- *              SetupDiBuildClassInfoList  (SETUPAPI.@)
- *
- * Returns a list of setup class GUIDs that identify the classes
- * that are installed on a local machine.
- *
- * PARAMS
- *   Flags [I] control exclusion of classes from the list.
- *   ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
- *   ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
- *   RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
- *
- * RETURNS
- *   Success: TRUE.
- *   Failure: FALSE.
- */
-BOOL WINAPI SetupDiBuildClassInfoList(
-        DWORD Flags,
-        LPGUID ClassGuidList,
-        DWORD ClassGuidListSize,
-        PDWORD RequiredSize)
-{
-    TRACE("\n");
-    return SetupDiBuildClassInfoListExW(Flags, ClassGuidList,
-                                        ClassGuidListSize, RequiredSize,
-                                        NULL, NULL);
-}
-
-/***********************************************************************
- *              SetupDiBuildClassInfoListExA  (SETUPAPI.@)
- *
- * Returns a list of setup class GUIDs that identify the classes
- * that are installed on a local or remote machine.
- *
- * PARAMS
- *   Flags [I] control exclusion of classes from the list.
- *   ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
- *   ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
- *   RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
- *   MachineName [I] name of a remote machine.
- *   Reserved [I] must be NULL.
- *
- * RETURNS
- *   Success: TRUE.
- *   Failure: FALSE.
- */
-BOOL WINAPI SetupDiBuildClassInfoListExA(
-        DWORD Flags,
-        LPGUID ClassGuidList,
-        DWORD ClassGuidListSize,
-        PDWORD RequiredSize,
-        LPCSTR MachineName,
-        PVOID Reserved)
-{
-    LPWSTR MachineNameW = NULL;
-    BOOL bResult;
-
-    TRACE("0x%lx %p %lu %p %s %p\n", Flags, ClassGuidList,
-        ClassGuidListSize, RequiredSize, debugstr_a(MachineName), Reserved);
-
-    if (MachineName)
-    {
-        MachineNameW = pSetupMultiByteToUnicode(MachineName, CP_ACP);
-        if (MachineNameW == NULL) return FALSE;
-    }
-
-    bResult = SetupDiBuildClassInfoListExW(Flags, ClassGuidList,
-                                           ClassGuidListSize, RequiredSize,
-                                           MachineNameW, Reserved);
-
-    MyFree(MachineNameW);
-
-    return bResult;
-}
-
-/***********************************************************************
- *              SetupDiBuildClassInfoListExW  (SETUPAPI.@)
- *
- * Returns a list of setup class GUIDs that identify the classes
- * that are installed on a local or remote machine.
- *
- * PARAMS
- *   Flags [I] control exclusion of classes from the list.
- *   ClassGuidList [O] pointer to a GUID-typed array that receives a list of setup class GUIDs.
- *   ClassGuidListSize [I] The number of GUIDs in the array (ClassGuidList).
- *   RequiredSize [O] pointer, which receives the number of GUIDs that are returned.
- *   MachineName [I] name of a remote machine.
- *   Reserved [I] must be NULL.
- *
- * RETURNS
- *   Success: TRUE.
- *   Failure: FALSE.
- */
-BOOL WINAPI SetupDiBuildClassInfoListExW(
-        DWORD Flags,
-        LPGUID ClassGuidList,
-        DWORD ClassGuidListSize,
-        PDWORD RequiredSize,
-        LPCWSTR MachineName,
-        PVOID Reserved)
-{
-    WCHAR szKeyName[40];
-    HKEY hClassesKey = INVALID_HANDLE_VALUE;
-    HKEY hClassKey;
-    DWORD dwLength;
-    DWORD dwIndex;
-    LONG lError;
-    DWORD dwGuidListIndex = 0;
-
-    TRACE("0x%lx %p %lu %p %s %p\n", Flags, ClassGuidList,
-        ClassGuidListSize, RequiredSize, debugstr_w(MachineName), Reserved);
-
-    if (!RequiredSize)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-    else if (!ClassGuidList && ClassGuidListSize > 0)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-
-    hClassesKey = SetupDiOpenClassRegKeyExW(NULL,
-                                            KEY_ENUMERATE_SUB_KEYS,
-                                            DIOCR_INSTALLER,
-                                            MachineName,
-                                            Reserved);
-    if (hClassesKey == INVALID_HANDLE_VALUE)
-    {
-        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;
-    }
-
-    RegCloseKey(hClassesKey);
-
-    if (RequiredSize != NULL)
-        *RequiredSize = dwGuidListIndex;
-
-    if (ClassGuidListSize < dwGuidListIndex)
-    {
-        SetLastError(ERROR_INSUFFICIENT_BUFFER);
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-/***********************************************************************
- *             SetupDiClassGuidsFromNameA  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiClassGuidsFromNameA(
-        LPCSTR ClassName,
-        LPGUID ClassGuidList,
-        DWORD ClassGuidListSize,
-        PDWORD RequiredSize)
-{
-    return SetupDiClassGuidsFromNameExA(ClassName, ClassGuidList,
-                                        ClassGuidListSize, RequiredSize,
-                                        NULL, NULL);
-}
-
-/***********************************************************************
- *             SetupDiClassGuidsFromNameW  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiClassGuidsFromNameW(
-        LPCWSTR ClassName,
-        LPGUID ClassGuidList,
-        DWORD ClassGuidListSize,
-        PDWORD RequiredSize)
-{
-    return SetupDiClassGuidsFromNameExW(ClassName, ClassGuidList,
-                                        ClassGuidListSize, RequiredSize,
-                                        NULL, NULL);
-}
-
-/***********************************************************************
- *             SetupDiClassGuidsFromNameExA  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiClassGuidsFromNameExA(
-        LPCSTR ClassName,
-        LPGUID ClassGuidList,
-        DWORD ClassGuidListSize,
-        PDWORD RequiredSize,
-        LPCSTR MachineName,
-        PVOID Reserved)
-{
-    LPWSTR ClassNameW = NULL;
-    LPWSTR MachineNameW = NULL;
-    BOOL bResult;
-
-    TRACE("%s %p %lu %p %s %p\n", debugstr_a(ClassName), ClassGuidList,
-        ClassGuidListSize, RequiredSize, debugstr_a(MachineName), Reserved);
-
-    if (!ClassName)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-
-    ClassNameW = pSetupMultiByteToUnicode(ClassName, CP_ACP);
-    if (ClassNameW == NULL)
-        return FALSE;
-
-    if (MachineName)
-    {
-        MachineNameW = pSetupMultiByteToUnicode(MachineName, CP_ACP);
-        if (MachineNameW == NULL)
-        {
-            MyFree(ClassNameW);
-            return FALSE;
-        }
-    }
-
-    bResult = SetupDiClassGuidsFromNameExW(ClassNameW, ClassGuidList,
-                                           ClassGuidListSize, RequiredSize,
-                                           MachineNameW, Reserved);
-
-    MyFree(MachineNameW);
-    MyFree(ClassNameW);
-
-    return bResult;
-}
-
-/***********************************************************************
- *             SetupDiClassGuidsFromNameExW  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiClassGuidsFromNameExW(
-        LPCWSTR ClassName,
-        LPGUID ClassGuidList,
-        DWORD ClassGuidListSize,
-        PDWORD RequiredSize,
-        LPCWSTR MachineName,
-        PVOID Reserved)
-{
-    WCHAR szKeyName[40];
-    WCHAR szClassName[MAX_CLASS_NAME_LEN];
-    HKEY hClassesKey;
-    HKEY hClassKey;
-    DWORD dwLength;
-    DWORD dwIndex;
-    LONG lError;
-    DWORD dwGuidListIndex = 0;
-
-    TRACE("%s %p %lu %p %s %p\n", debugstr_w(ClassName), ClassGuidList,
-        ClassGuidListSize, RequiredSize, debugstr_w(MachineName), Reserved);
-
-    if (!ClassName || !RequiredSize)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-    if (!ClassGuidList && ClassGuidListSize > 0)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-    *RequiredSize = 0;
-
-    hClassesKey = SetupDiOpenClassRegKeyExW(NULL,
-                                            KEY_ENUMERATE_SUB_KEYS,
-                                            DIOCR_INSTALLER,
-                                            MachineName,
-                                            Reserved);
-    if (hClassesKey == INVALID_HANDLE_VALUE)
-    {
-        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,
-                                  REGSTR_VAL_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;
-
-    if (ClassGuidListSize < dwGuidListIndex)
-    {
-        SetLastError(ERROR_INSUFFICIENT_BUFFER);
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-/***********************************************************************
- *              SetupDiClassNameFromGuidA  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiClassNameFromGuidA(
-        const GUID* ClassGuid,
-        PSTR ClassName,
-        DWORD ClassNameSize,
-        PDWORD RequiredSize)
-{
-    return SetupDiClassNameFromGuidExA(ClassGuid, ClassName,
-                                       ClassNameSize, RequiredSize,
-                                       NULL, NULL);
-}
-
-/***********************************************************************
- *              SetupDiClassNameFromGuidW  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiClassNameFromGuidW(
-        const GUID* ClassGuid,
-        PWSTR ClassName,
-        DWORD ClassNameSize,
-        PDWORD RequiredSize)
-{
-    return SetupDiClassNameFromGuidExW(ClassGuid, ClassName,
-                                       ClassNameSize, RequiredSize,
-                                       NULL, NULL);
-}
-
-/***********************************************************************
- *              SetupDiClassNameFromGuidExA  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiClassNameFromGuidExA(
-        const GUID* ClassGuid,
-        PSTR ClassName,
-        DWORD ClassNameSize,
-        PDWORD RequiredSize,
-        PCSTR MachineName,
-        PVOID Reserved)
-{
-    WCHAR ClassNameW[MAX_CLASS_NAME_LEN];
-    LPWSTR MachineNameW = NULL;
-    BOOL ret;
-
-    if (MachineName)
-        MachineNameW = pSetupMultiByteToUnicode(MachineName, CP_ACP);
-    ret = SetupDiClassNameFromGuidExW(ClassGuid, ClassNameW, MAX_CLASS_NAME_LEN,
-                                      RequiredSize, MachineNameW, Reserved);
-    if (ret)
-    {
-        int len = WideCharToMultiByte(CP_ACP, 0, ClassNameW, -1, ClassName,
-                                      ClassNameSize, NULL, NULL);
-        if (len == 0 || len > ClassNameSize)
-        {
-            SetLastError(ERROR_INSUFFICIENT_BUFFER);
-            ret = FALSE;
-        }
-    }
-    MyFree(MachineNameW);
-    return ret;
-}
-
-/***********************************************************************
- *             SetupDiClassNameFromGuidExW  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiClassNameFromGuidExW(
-        const GUID* ClassGuid,
-        PWSTR ClassName,
-        DWORD ClassNameSize,
-        PDWORD RequiredSize,
-        PCWSTR MachineName,
-        PVOID Reserved)
-{
-    HKEY hKey;
-    DWORD dwLength;
-    DWORD dwRegType;
-    LONG rc;
-    PWSTR Buffer;
-
-    TRACE("%s %p %lu %p %s %p\n", debugstr_guid(ClassGuid), ClassName,
-        ClassNameSize, RequiredSize, debugstr_w(MachineName), Reserved);
-
-    /* Make sure there's a GUID */
-    if (ClassGuid == NULL)
-    {
-        SetLastError(ERROR_INVALID_CLASS);  /* On Vista: ERROR_INVALID_USER_BUFFER */
-        return FALSE;
-    }
-
-    /* Make sure there's a real buffer when there's a size */
-    if ((ClassNameSize > 0) && (ClassName == NULL))
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);  /* On Vista: ERROR_INVALID_USER_BUFFER */
-        return FALSE;
-    }
-
-    /* Open the key for the GUID */
-    hKey = SetupDiOpenClassRegKeyExW(ClassGuid, KEY_QUERY_VALUE, DIOCR_INSTALLER, MachineName, Reserved);
-
-    if (hKey == INVALID_HANDLE_VALUE)
-        return FALSE;
-
-    /* Retrieve the class name data and close the key */
-    rc = QueryRegistryValue(hKey, REGSTR_VAL_CLASS, (LPBYTE *) &Buffer, &dwRegType, &dwLength);
-    RegCloseKey(hKey);
-
-    /* Make sure we got the data */
-    if (rc != ERROR_SUCCESS)
-    {
-        SetLastError(rc);
-        return FALSE;
-    }
-
-    /* Make sure the data is a string */
-    if (dwRegType != REG_SZ)
-    {
-        MyFree(Buffer);
-        SetLastError(ERROR_GEN_FAILURE);
-        return FALSE;
-    }
-
-    /* Determine the length of the class name */
-    dwLength /= sizeof(WCHAR);
-
-    if ((dwLength == 0) || (Buffer[dwLength - 1] != UNICODE_NULL))
-        /* Count the null-terminator */
-        dwLength++;
-
-    /* Inform the caller about the class name */
-    if ((ClassName != NULL) && (dwLength <= ClassNameSize))
-    {
-        memcpy(ClassName, Buffer, (dwLength - 1) * sizeof(WCHAR));
-        ClassName[dwLength - 1] = UNICODE_NULL;
-    }
-
-    /* Inform the caller about the required size */
-    if (RequiredSize != NULL)
-        *RequiredSize = dwLength;
-
-    /* Clean up the buffer */
-    MyFree(Buffer);
-
-    /* Make sure the buffer was large enough */
-    if ((ClassName == NULL) || (dwLength > ClassNameSize))
-    {
-        SetLastError(ERROR_INSUFFICIENT_BUFFER);
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-/***********************************************************************
- *             SetupDiCreateDeviceInfoList (SETUPAPI.@)
- */
-HDEVINFO WINAPI
-SetupDiCreateDeviceInfoList(const GUID *ClassGuid,
-        HWND hwndParent)
-{
-    return SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent, NULL, NULL);
-}
-
-/***********************************************************************
- *             SetupDiCreateDeviceInfoListExA (SETUPAPI.@)
- */
-HDEVINFO WINAPI
-SetupDiCreateDeviceInfoListExA(const GUID *ClassGuid,
-        HWND hwndParent,
-        PCSTR MachineName,
-        PVOID Reserved)
-{
-    LPWSTR MachineNameW = NULL;
-    HDEVINFO hDevInfo;
-
-    TRACE("%s %p %s %p\n", debugstr_guid(ClassGuid), hwndParent,
-      debugstr_a(MachineName), Reserved);
-
-    if (MachineName)
-    {
-        MachineNameW = pSetupMultiByteToUnicode(MachineName, CP_ACP);
-        if (MachineNameW == NULL)
-            return INVALID_HANDLE_VALUE;
-    }
-
-    hDevInfo = SetupDiCreateDeviceInfoListExW(ClassGuid, hwndParent,
-                                              MachineNameW, Reserved);
-
-    MyFree(MachineNameW);
-
-    return hDevInfo;
-}
-
-/***********************************************************************
- *             SetupDiCreateDeviceInfoListExW (SETUPAPI.@)
- *
- * Create an empty DeviceInfoSet list.
- *
- * PARAMS
- *   ClassGuid [I] if not NULL only devices with GUID ClassGuid are associated
- *                 with this list.
- *   hwndParent [I] hwnd needed for interface related actions.
- *   MachineName [I] name of machine to create emtpy DeviceInfoSet list, if NULL
- *                   local registry will be used.
- *   Reserved [I] must be NULL
- *
- * RETURNS
- *   Success: empty list.
- *   Failure: INVALID_HANDLE_VALUE.
- */
-HDEVINFO WINAPI
-SetupDiCreateDeviceInfoListExW(const GUID *ClassGuid,
-        HWND hwndParent,
-        PCWSTR MachineName,
-        PVOID Reserved)
-{
-    struct DeviceInfoSet *list = NULL;
-    DWORD size = FIELD_OFFSET(struct DeviceInfoSet, szData);
-    DWORD rc;
-    CONFIGRET cr;
-    HDEVINFO ret = INVALID_HANDLE_VALUE;
-
-    TRACE("%s %p %s %p\n", debugstr_guid(ClassGuid), hwndParent,
-      debugstr_w(MachineName), Reserved);
-
-    if (MachineName != NULL)
-    {
-        SIZE_T len = strlenW(MachineName);
-        if (len >= SP_MAX_MACHINENAME_LENGTH - 4)
-        {
-            SetLastError(ERROR_INVALID_MACHINENAME);
-            goto cleanup;
-        }
-        if(len > 0)
-            size += (len + 3) * sizeof(WCHAR);
-        else
-            MachineName = NULL;
-    }
-
-    if (Reserved != NULL)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return INVALID_HANDLE_VALUE;
-    }
-
-    list = MyMalloc(size);
-    if (!list)
-    {
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return INVALID_HANDLE_VALUE;
-    }
-    ZeroMemory(list, FIELD_OFFSET(struct DeviceInfoSet, szData));
-
-    list->magic = SETUP_DEVICE_INFO_SET_MAGIC;
-    memcpy(&list->ClassGuid,
-            ClassGuid ? ClassGuid : &GUID_NULL,
-            sizeof(list->ClassGuid));
-    list->InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
-    list->InstallParams.Flags |= DI_CLASSINSTALLPARAMS;
-    list->InstallParams.hwndParent = hwndParent;
-    if (MachineName)
-    {
-        rc = RegConnectRegistryW(MachineName, HKEY_LOCAL_MACHINE, &list->HKLM);
-        if (rc != ERROR_SUCCESS)
-        {
-            SetLastError(ERROR_INVALID_MACHINENAME);
-            goto cleanup;
-        }
-
-        list->szData[0] = list->szData[1] = '\\';
-        strcpyW(list->szData + 2, MachineName);
-        list->MachineName = list->szData;
-    }
-    else
-    {
-        list->HKLM = HKEY_LOCAL_MACHINE;
-        list->MachineName = NULL;
-    }
-    cr = CM_Connect_MachineW(list->MachineName, &list->hMachine);
-    if (cr != CR_SUCCESS)
-    {
-        SetLastError(GetErrorCodeFromCrCode(cr));
-        goto cleanup;
-    }
-    InitializeListHead(&list->DriverListHead);
-    InitializeListHead(&list->ListHead);
-
-    return (HDEVINFO)list;
-
-cleanup:
-    if (ret == INVALID_HANDLE_VALUE)
-    {
-        if (list)
-        {
-            if (list->HKLM != NULL && list->HKLM != HKEY_LOCAL_MACHINE)
-                RegCloseKey(list->HKLM);
-            MyFree(list);
-        }
-    }
-    return ret;
-}
-
-/***********************************************************************
- *              SetupDiCreateDevRegKeyA (SETUPAPI.@)
- */
-HKEY WINAPI SetupDiCreateDevRegKeyA(
-        HDEVINFO DeviceInfoSet,
-        PSP_DEVINFO_DATA DeviceInfoData,
-        DWORD Scope,
-        DWORD HwProfile,
-        DWORD KeyType,
-        HINF InfHandle,
-        PCSTR InfSectionName)
-{
-    PWSTR InfSectionNameW = NULL;
-    HKEY key;
-
-    TRACE("%p %p %d %d %d %p %s\n", DeviceInfoSet, DeviceInfoData, Scope,
-            HwProfile, KeyType, InfHandle, debugstr_a(InfSectionName));
-
-    if (InfHandle)
-    {
-        if (!InfSectionName)
-        {
-            SetLastError(ERROR_INVALID_PARAMETER);
-            return INVALID_HANDLE_VALUE;
-        }
-        else
-        {
-            InfSectionNameW = pSetupMultiByteToUnicode(InfSectionName, CP_ACP);
-            if (InfSectionNameW == NULL) return INVALID_HANDLE_VALUE;
-        }
-    }
-    key = SetupDiCreateDevRegKeyW(DeviceInfoSet, DeviceInfoData, Scope,
-            HwProfile, KeyType, InfHandle, InfSectionNameW);
-    MyFree(InfSectionNameW);
-    return key;
-}
-
-static HKEY
-OpenHardwareProfileKey(
-    IN HKEY HKLM,
-    IN DWORD HwProfile,
-    IN DWORD samDesired);
-
-/***********************************************************************
- *              SetupDiCreateDevRegKeyW (SETUPAPI.@)
- */
-HKEY WINAPI SetupDiCreateDevRegKeyW(
-        HDEVINFO DeviceInfoSet,
-        PSP_DEVINFO_DATA DeviceInfoData,
-        DWORD Scope,
-        DWORD HwProfile,
-        DWORD KeyType,
-        HINF InfHandle,
-        PCWSTR InfSectionName)
-{
-    struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
-    HKEY key = INVALID_HANDLE_VALUE;
-    LPWSTR lpGuidString = NULL;
-    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;
-    HKEY hClassKey = NULL;
-    HKEY hDeviceKey = INVALID_HANDLE_VALUE;
-    HKEY hKey = NULL;
-    HKEY RootKey;
-
-    TRACE("%p %p %lu %lu %lu %p %s\n", DeviceInfoSet, DeviceInfoData, Scope,
-            HwProfile, KeyType, InfHandle, debugstr_w(InfSectionName));
-
-    if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return INVALID_HANDLE_VALUE;
-    }
-    if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return INVALID_HANDLE_VALUE;
-    }
-    if (!DeviceInfoData || DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)
-            || !DeviceInfoData->Reserved)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return INVALID_HANDLE_VALUE;
-    }
-    if (Scope != DICS_FLAG_GLOBAL && Scope != DICS_FLAG_CONFIGSPECIFIC)
-    {
-        SetLastError(ERROR_INVALID_FLAGS);
-        return INVALID_HANDLE_VALUE;
-    }
-    if (KeyType != DIREG_DEV && KeyType != DIREG_DRV)
-    {
-        SetLastError(ERROR_INVALID_FLAGS);
-        return INVALID_HANDLE_VALUE;
-    }
-    if (InfHandle && !InfSectionName)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return INVALID_HANDLE_VALUE;
-    }
-    if (!InfHandle && InfSectionName)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return INVALID_HANDLE_VALUE;
-    }
-
-        if (Scope == DICS_FLAG_GLOBAL)
-            RootKey = set->HKLM;
-        else /* Scope == DICS_FLAG_CONFIGSPECIFIC */
-        {
-            hHWProfileKey = OpenHardwareProfileKey(set->HKLM, HwProfile, KEY_CREATE_SUB_KEY);
-            if (hHWProfileKey == INVALID_HANDLE_VALUE)
-                goto cleanup;
-            RootKey = hHWProfileKey;
-        }
-
-        if (KeyType == DIREG_DEV)
-        {
-            struct DeviceInfo *deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
-
-            rc = RegCreateKeyExW(
-                RootKey,
-                REGSTR_PATH_SYSTEMENUM,
-                0,
-                NULL,
-                REG_OPTION_NON_VOLATILE,
-                KEY_CREATE_SUB_KEY,
-                NULL,
-                &hEnumKey,
-                NULL);
-            if (rc != ERROR_SUCCESS)
-            {
-                SetLastError(rc);
-                goto cleanup;
-            }
-            rc = RegCreateKeyExW(
-                hEnumKey,
-                deviceInfo->instanceId,
-                0,
-                NULL,
-                REG_OPTION_NON_VOLATILE,
-#if _WIN32_WINNT >= 0x502
-                KEY_READ | KEY_WRITE,
-#else
-                KEY_ALL_ACCESS,
-#endif
-                NULL,
-                &hKey,
-                NULL);
-            if (rc != ERROR_SUCCESS)
-            {
-                SetLastError(rc);
-                goto cleanup;
-            }
-        }
-        else /* KeyType == DIREG_DRV */
-        {
-            /* 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;
-
-            rc = RegOpenKeyExW(RootKey, REGSTR_PATH_CLASS_NT, 0, KEY_CREATE_SUB_KEY, &hClassKey);
-            if (rc != ERROR_SUCCESS)
-            {
-                SetLastError(rc);
-                goto cleanup;
-            }
-
-            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
-            {
-                /* 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,
-                    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;
-                }
-            }
-        }
-
-        /* Do installation of the specified section */
-        if (InfHandle)
-        {
-            FIXME("Need to install section %s in file %p\n",
-                debugstr_w(InfSectionName), InfHandle);
-        }
-        key = hKey;
-
-cleanup:
-        if (lpGuidString)
-            RpcStringFreeW(&lpGuidString);
-        HeapFree(GetProcessHeap(), 0, DriverKey);
-        if (hHWProfileKey != INVALID_HANDLE_VALUE)
-            RegCloseKey(hHWProfileKey);
-        if (hEnumKey != NULL)
-            RegCloseKey(hEnumKey);
-        if (hClassKey != NULL)
-            RegCloseKey(hClassKey);
-        if (hDeviceKey != INVALID_HANDLE_VALUE)
-            RegCloseKey(hDeviceKey);
-        if (hKey != NULL && hKey != key)
-            RegCloseKey(hKey);
-
-    TRACE("Returning 0x%p\n", key);
-    return key;
-}
-
-/***********************************************************************
- *              SetupDiCreateDeviceInfoA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiCreateDeviceInfoA(
-        HDEVINFO DeviceInfoSet,
-        PCSTR DeviceName,
-        CONST GUID *ClassGuid,
-        PCSTR DeviceDescription,
-        HWND hwndParent,
-        DWORD CreationFlags,
-        PSP_DEVINFO_DATA DeviceInfoData)
-{
-    BOOL ret;
-    LPWSTR DeviceNameW = NULL;
-    LPWSTR DeviceDescriptionW = NULL;
-
-    TRACE("\n");
-
-    if (DeviceName)
-    {
-        DeviceNameW = pSetupMultiByteToUnicode(DeviceName, CP_ACP);
-        if (DeviceNameW == NULL) return FALSE;
-    }
-    if (DeviceDescription)
-    {
-        DeviceDescriptionW = pSetupMultiByteToUnicode(DeviceDescription, CP_ACP);
-        if (DeviceDescriptionW == NULL)
-        {
-            MyFree(DeviceNameW);
-            return FALSE;
-        }
-    }
-
-    ret = SetupDiCreateDeviceInfoW(DeviceInfoSet, DeviceNameW, ClassGuid, DeviceDescriptionW,
-            hwndParent, CreationFlags, DeviceInfoData);
-
-    MyFree(DeviceNameW);
-    MyFree(DeviceDescriptionW);
-
-    return ret;
-}
-
-/***********************************************************************
- *              SetupDiCreateDeviceInfoW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiCreateDeviceInfoW(
-        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;
-    CONFIGRET cr;
-    DEVINST RootDevInst;
-    DEVINST DevInst;
-    WCHAR GenInstanceId[MAX_DEVICE_ID_LEN];
-
-    TRACE("%p %s %s %s %p %x %p\n", DeviceInfoSet, debugstr_w(DeviceName),
-        debugstr_guid(ClassGuid), debugstr_w(DeviceDescription),
-        hwndParent, CreationFlags, DeviceInfoData);
-
-    if (!DeviceName)
-    {
-        SetLastError(ERROR_INVALID_DEVINST_NAME);
-        return FALSE;
-    }
-    if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (!ClassGuid)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-    if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (!IsEqualGUID(&set->ClassGuid, &GUID_NULL) &&
-        !IsEqualGUID(ClassGuid, &set->ClassGuid))
-    {
-        SetLastError(ERROR_CLASS_MISMATCH);
-        return FALSE;
-    }
-    if (CreationFlags & ~(DICD_GENERATE_ID | DICD_INHERIT_CLASSDRVS))
-    {
-        TRACE("Unknown flags: 0x%08lx\n", CreationFlags & ~(DICD_GENERATE_ID | DICD_INHERIT_CLASSDRVS));
-        SetLastError(ERROR_INVALID_FLAGS);
-        return FALSE;
-    }
-
-    /* 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,
-                               (CreationFlags & DICD_GENERATE_ID) ?
-                                     CM_CREATE_DEVINST_GENERATE_ID : 0,
-                               set->hMachine);
-    if (cr != CR_SUCCESS)
-    {
-        SetLastError(GetErrorCodeFromCrCode(cr));
-        return FALSE;
-    }
-
-    if (CreationFlags & DICD_GENERATE_ID)
-    {
-        /* Grab the actual instance ID that was created */
-        cr = CM_Get_Device_ID_Ex(DevInst,
-                                 GenInstanceId,
-                                 MAX_DEVICE_ID_LEN,
-                                 0,
-                                 set->hMachine);
-        if (cr != CR_SUCCESS)
-        {
-            SetLastError(GetErrorCodeFromCrCode(cr));
-            return FALSE;
-        }
-
-        DeviceName = GenInstanceId;
-        TRACE("Using generated instance ID: %s\n", debugstr_w(DeviceName));
-    }
-
-    if (CreateDeviceInfo(set, DeviceName, ClassGuid, &deviceInfo))
-    {
-        InsertTailList(&set->ListHead, &deviceInfo->ListEntry);
-
-        if (!DeviceInfoData)
-            ret = TRUE;
-        else
-        {
-            if (DeviceInfoData->cbSize != sizeof(SP_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;
-            }
-        }
-    }
-
-    if (ret == FALSE)
-    {
-        if (deviceInfo != NULL)
-        {
-            /* Remove deviceInfo from List */
-            RemoveEntryList(&deviceInfo->ListEntry);
-
-            /* Destroy deviceInfo */
-            DestroyDeviceInfo(deviceInfo);
-        }
-    }
-
-    TRACE("Returning %d\n", ret);
-    return ret;
-}
-
-/***********************************************************************
- *             SetupDiRegisterDeviceInfo (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiRegisterDeviceInfo(
-        HDEVINFO DeviceInfoSet,
-        PSP_DEVINFO_DATA DeviceInfoData,
-        DWORD Flags,
-        PSP_DETSIG_CMPPROC CompareProc,
-        PVOID CompareContext,
-        PSP_DEVINFO_DATA DupDeviceInfoData)
-{
-    struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
-    WCHAR DevInstId[MAX_DEVICE_ID_LEN];
-    DEVINST ParentDevInst;
-    CONFIGRET cr;
-    DWORD dwError = ERROR_SUCCESS;
-
-    TRACE("%p %p %08x %p %p %p\n", DeviceInfoSet, DeviceInfoData, Flags,
-            CompareProc, CompareContext, DupDeviceInfoData);
-
-    if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (!DeviceInfoData || DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)
-            || !DeviceInfoData->Reserved)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-
-    if (Flags & ~SPRDI_FIND_DUPS)
-    {
-        TRACE("Unknown flags: 0x%08lx\n", Flags & ~SPRDI_FIND_DUPS);
-        SetLastError(ERROR_INVALID_FLAGS);
-        return FALSE;
-    }
-
-    if (Flags & SPRDI_FIND_DUPS)
-    {
-        FIXME("Unimplemented codepath!\n");
-    }
-
-    CM_Get_Device_ID_Ex(DeviceInfoData->DevInst,
-                        DevInstId,
-                        MAX_DEVICE_ID_LEN,
-                        0,
-                        set->hMachine);
-
-    CM_Get_Parent_Ex(&ParentDevInst,
-                     DeviceInfoData->DevInst,
-                     0,
-                     set->hMachine);
-
-    cr = CM_Create_DevInst_Ex(&DeviceInfoData->DevInst,
-                              DevInstId,
-                              ParentDevInst,
-                              CM_CREATE_DEVINST_NORMAL | CM_CREATE_DEVINST_DO_NOT_INSTALL,
-                              set->hMachine);
-    if (cr != CR_SUCCESS &&
-        cr != CR_ALREADY_SUCH_DEVINST)
-    {
-        dwError = ERROR_NO_SUCH_DEVINST;
-    }
-
-    SetLastError(dwError);
-
-    return (dwError == ERROR_SUCCESS);
-}
-
-/***********************************************************************
- *             SetupDiEnumDeviceInfo (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiEnumDeviceInfo(
-        HDEVINFO  devinfo,
-        DWORD  index,
-        PSP_DEVINFO_DATA info)
-{
-    BOOL ret = FALSE;
-
-    TRACE("%p %d %p\n", devinfo, index, info);
-
-    if(info==NULL)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-    if (devinfo && devinfo != INVALID_HANDLE_VALUE)
-    {
-        struct DeviceInfoSet *list = (struct DeviceInfoSet *)devinfo;
-        if (list->magic == SETUP_DEVICE_INFO_SET_MAGIC)
-        {
-            if (info->cbSize != sizeof(SP_DEVINFO_DATA))
-                SetLastError(ERROR_INVALID_USER_BUFFER);
-            else
-            {
-                PLIST_ENTRY ItemList = list->ListHead.Flink;
-                while (ItemList != &list->ListHead && index-- > 0)
-                    ItemList = ItemList->Flink;
-                if (ItemList == &list->ListHead)
-                    SetLastError(ERROR_NO_MORE_ITEMS);
-                else
-                {
-                    struct DeviceInfo *DevInfo = CONTAINING_RECORD(ItemList, struct DeviceInfo, ListEntry);
-                    memcpy(&info->ClassGuid,
-                        &DevInfo->ClassGuid,
-                        sizeof(GUID));
-                    info->DevInst = DevInfo->dnDevInst;
-                    info->Reserved = (ULONG_PTR)DevInfo;
-                    ret = TRUE;
-                }
-            }
-        }
-        else
-            SetLastError(ERROR_INVALID_HANDLE);
-    }
-    else
-        SetLastError(ERROR_INVALID_HANDLE);
-    return ret;
-}
-
-/***********************************************************************
- *             SetupDiGetDeviceInstanceIdA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetDeviceInstanceIdA(
-        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);
-
-    if (!DeviceInstanceId && DeviceInstanceIdSize > 0)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-
-    ret = SetupDiGetDeviceInstanceIdW(DeviceInfoSet,
-                                DeviceInfoData,
-                                NULL,
-                                0,
-                                &size);
-    if (!ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
-        return FALSE;
-    instanceId = MyMalloc(size * sizeof(WCHAR));
-    if (instanceId)
-    {
-        ret = SetupDiGetDeviceInstanceIdW(DeviceInfoSet,
-                                          DeviceInfoData,
-                                          instanceId,
-                                          size,
-                                          &size);
-        if (ret)
-        {
-            int len = WideCharToMultiByte(CP_ACP, 0, instanceId, -1,
-                                          DeviceInstanceId,
-                                          DeviceInstanceIdSize, NULL, NULL);
-
-            if (!len)
-                ret = FALSE;
-            else
-            {
-                if (len > DeviceInstanceIdSize)
-                {
-                    SetLastError(ERROR_INSUFFICIENT_BUFFER);
-                    ret = FALSE;
-                }
-                if (RequiredSize)
-                    *RequiredSize = len;
-            }
-        }
-        MyFree(instanceId);
-    }
-    else
-    {
-        if (RequiredSize)
-            *RequiredSize = size;
-        SetLastError(ERROR_INSUFFICIENT_BUFFER);
-        ret = FALSE;
-    }
-    return ret;
-}
-
-/***********************************************************************
- *             SetupDiGetDeviceInstanceIdW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetDeviceInstanceIdW(
-        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);
-
-    if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (!DeviceInfoData || DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)
-            || !DeviceInfoData->Reserved)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-    devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
-    if (!DeviceInstanceId && DeviceInstanceIdSize > 0)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-    if (DeviceInstanceId && DeviceInstanceIdSize == 0)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-    TRACE("instance ID: %s\n", debugstr_w(devInfo->instanceId));
-    if (DeviceInstanceIdSize < lstrlenW(devInfo->instanceId) + 1)
-    {
-        SetLastError(ERROR_INSUFFICIENT_BUFFER);
-        if (RequiredSize)
-            *RequiredSize = lstrlenW(devInfo->instanceId) + 1;
-        return FALSE;
-    }
-    lstrcpyW(DeviceInstanceId, devInfo->instanceId);
-    if (RequiredSize)
-        *RequiredSize = lstrlenW(devInfo->instanceId) + 1;
-    return TRUE;
-}
-
-/***********************************************************************
- *             SetupDiGetActualSectionToInstallA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetActualSectionToInstallA(
-        HINF InfHandle,
-        PCSTR InfSectionName,
-        PSTR InfSectionWithExt,
-        DWORD InfSectionWithExtSize,
-        PDWORD RequiredSize,
-        PSTR *Extension)
-{
-    return SetupDiGetActualSectionToInstallExA(InfHandle, InfSectionName,
-        NULL, InfSectionWithExt, InfSectionWithExtSize, RequiredSize,
-        Extension, NULL);
-}
-
-/***********************************************************************
- *             SetupDiGetActualSectionToInstallW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetActualSectionToInstallW(
-        HINF InfHandle,
-        PCWSTR InfSectionName,
-        PWSTR InfSectionWithExt,
-        DWORD InfSectionWithExtSize,
-        PDWORD RequiredSize,
-        PWSTR *Extension)
-{
-    return SetupDiGetActualSectionToInstallExW(InfHandle, InfSectionName,
-        NULL, InfSectionWithExt, InfSectionWithExtSize, RequiredSize,
-        Extension, NULL);
-}
-
-/***********************************************************************
- *             SetupDiGetActualSectionToInstallExA  (SETUPAPI.@)
- */
-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)
-{
-    LPWSTR InfSectionNameW = NULL;
-    LPWSTR InfSectionWithExtW = NULL;
-    PWSTR ExtensionW;
-    BOOL bResult = FALSE;
-
-    TRACE("\n");
-
-    if (InfSectionName)
-    {
-        InfSectionNameW = pSetupMultiByteToUnicode(InfSectionName, CP_ACP);
-        if (InfSectionNameW == NULL)
-            goto cleanup;
-    }
-    if (InfSectionWithExt)
-    {
-        InfSectionWithExtW = MyMalloc(InfSectionWithExtSize * sizeof(WCHAR));
-        if (InfSectionWithExtW == NULL)
-            goto cleanup;
-    }
-
-    bResult = SetupDiGetActualSectionToInstallExW(
-        InfHandle, InfSectionNameW, AlternatePlatformInfo,
-        InfSectionWithExt ? InfSectionWithExtW : NULL,
-        InfSectionWithExtSize,
-        RequiredSize,
-        Extension ? &ExtensionW : NULL,
-        Reserved);
-
-    if (bResult && InfSectionWithExt)
-    {
-         bResult = WideCharToMultiByte(CP_ACP, 0, InfSectionWithExtW, -1, InfSectionWithExt,
-             InfSectionWithExtSize, NULL, NULL) != 0;
-    }
-    if (bResult && Extension)
-    {
-        if (ExtensionW == NULL)
-            *Extension = NULL;
-         else
-            *Extension = &InfSectionWithExt[ExtensionW - InfSectionWithExtW];
-    }
-
-cleanup:
-    MyFree(InfSectionNameW);
-    MyFree(InfSectionWithExtW);
-
-    return bResult;
-}
-
-/***********************************************************************
- *             SetupDiGetClassDescriptionA  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetClassDescriptionA(
-        const GUID* ClassGuid,
-        PSTR ClassDescription,
-        DWORD ClassDescriptionSize,
-        PDWORD RequiredSize)
-{
-    return SetupDiGetClassDescriptionExA(ClassGuid, ClassDescription,
-                                         ClassDescriptionSize,
-                                         RequiredSize, NULL, NULL);
-}
-
-/***********************************************************************
- *             SetupDiGetClassDescriptionW  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetClassDescriptionW(
-        const GUID* ClassGuid,
-        PWSTR ClassDescription,
-        DWORD ClassDescriptionSize,
-        PDWORD RequiredSize)
-{
-    return SetupDiGetClassDescriptionExW(ClassGuid, ClassDescription,
-                                         ClassDescriptionSize,
-                                         RequiredSize, NULL, NULL);
-}
-
-/***********************************************************************
- *             SetupDiGetClassDescriptionExA  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetClassDescriptionExA(
-        const GUID* ClassGuid,
-        PSTR ClassDescription,
-        DWORD ClassDescriptionSize,
-        PDWORD RequiredSize,
-        PCSTR MachineName,
-        PVOID Reserved)
-{
-    PWCHAR ClassDescriptionW = NULL;
-    LPWSTR MachineNameW = NULL;
-    BOOL ret = FALSE;
-
-    TRACE("%s %p %lu %p %s %p\n", debugstr_guid(ClassGuid), ClassDescription,
-        ClassDescriptionSize, RequiredSize, debugstr_a(MachineName), Reserved);
-
-    if (ClassDescriptionSize > 0)
-    {
-        ClassDescriptionW = MyMalloc(ClassDescriptionSize * sizeof(WCHAR));
-        if (!ClassDescriptionW)
-        {
-            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-            goto cleanup;
-        }
-    }
-
-    if (MachineName)
-    {
-        MachineNameW = pSetupMultiByteToUnicode(MachineName, CP_ACP);
-        if (!MachineNameW)
-        {
-            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-            goto cleanup;
-        }
-    }
-
-    ret = SetupDiGetClassDescriptionExW(ClassGuid, ClassDescriptionW,
-        ClassDescriptionSize * sizeof(WCHAR), RequiredSize, MachineNameW, Reserved);
-    if (ret)
-    {
-        DWORD len = (DWORD)WideCharToMultiByte(CP_ACP, 0, ClassDescriptionW, -1, ClassDescription,
-            ClassDescriptionSize, NULL, NULL);
-        if (len == 0 || len > ClassDescriptionSize)
-        {
-            SetLastError(ERROR_INSUFFICIENT_BUFFER);
-            ret = FALSE;
-        }
-    }
-
-cleanup:
-    MyFree(ClassDescriptionW);
-    MyFree(MachineNameW);
-    return ret;
-}
-
-/***********************************************************************
- *             SetupDiGetClassDescriptionExW  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetClassDescriptionExW(
-        const GUID* ClassGuid,
-        PWSTR ClassDescription,
-        DWORD ClassDescriptionSize,
-        PDWORD RequiredSize,
-        PCWSTR MachineName,
-        PVOID Reserved)
-{
-    HKEY hKey;
-    DWORD dwLength;
-    DWORD dwRegType;
-    LONG rc;
-    PWSTR Buffer;
-
-    TRACE("%s %p %lu %p %s %p\n", debugstr_guid(ClassGuid), ClassDescription,
-        ClassDescriptionSize, RequiredSize, debugstr_w(MachineName), Reserved);
-
-    /* Make sure there's a GUID */
-    if (!ClassGuid)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-
-    /* Make sure there's a real buffer when there's a size */
-    if (!ClassDescription && ClassDescriptionSize > 0)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-
-    /* Open the key for the GUID */
-    hKey = SetupDiOpenClassRegKeyExW(ClassGuid,
-                                     KEY_QUERY_VALUE,
-                                     DIOCR_INSTALLER,
-                                     MachineName,
-                                     Reserved);
-    if (hKey == INVALID_HANDLE_VALUE)
-        return FALSE;
-
-    /* Retrieve the class description data and close the key */
-    rc = QueryRegistryValue(hKey, NULL, (LPBYTE *) &Buffer, &dwRegType, &dwLength);
-    RegCloseKey(hKey);
-
-    /* Make sure we got the data */
-    if (rc != ERROR_SUCCESS)
-    {
-        SetLastError(rc);
-        return FALSE;
-    }
-
-    /* Make sure the data is a string */
-    if (dwRegType != REG_SZ)
-    {
-        MyFree(Buffer);
-        SetLastError(ERROR_GEN_FAILURE);
-        return FALSE;
-    }
-
-    /* Determine the length of the class description */
-    dwLength /= sizeof(WCHAR);
-
-    /* Count the null-terminator if none is present */
-    if ((dwLength == 0) || (Buffer[dwLength - 1] != UNICODE_NULL))
-        dwLength++;
-
-    /* Inform the caller about the class description */
-    if ((ClassDescription != NULL) && (dwLength <= ClassDescriptionSize))
-    {
-        memcpy(ClassDescription, Buffer, (dwLength - 1) * sizeof(WCHAR));
-        ClassDescription[dwLength - 1] = UNICODE_NULL;
-    }
-
-    /* Inform the caller about the required size */
-    if (RequiredSize != NULL)
-        *RequiredSize = dwLength;
-
-    /* Clean up the buffer */
-    MyFree(Buffer);
-
-    /* Make sure the buffer was large enough */
-    if ((ClassDescription == NULL) || (dwLength > ClassDescriptionSize))
-    {
-        SetLastError(ERROR_INSUFFICIENT_BUFFER);
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-/***********************************************************************
- *             SetupDiGetClassDevsA (SETUPAPI.@)
- */
-HDEVINFO WINAPI SetupDiGetClassDevsA(
-        CONST GUID *class,
-        LPCSTR enumstr,
-        HWND parent,
-        DWORD flags)
-{
-    return SetupDiGetClassDevsExA(class, enumstr, parent,
-                                  flags, NULL, NULL, NULL);
-}
-
-/***********************************************************************
- *               SetupDiGetClassDevsExA (SETUPAPI.@)
- */
-HDEVINFO WINAPI SetupDiGetClassDevsExA(
-        const GUID *class,
-        PCSTR enumstr,
-        HWND parent,
-        DWORD flags,
-        HDEVINFO deviceset,
-        PCSTR machine,
-        PVOID reserved)
-{
-    HDEVINFO ret;
-    LPWSTR enumstrW = NULL, machineW = NULL;
-
-    if (enumstr)
-    {
-        enumstrW = pSetupMultiByteToUnicode(enumstr, CP_ACP);
-        if (!enumstrW)
-        {
-            ret = INVALID_HANDLE_VALUE;
-            goto end;
-        }
-    }
-    if (machine)
-    {
-        machineW = pSetupMultiByteToUnicode(machine, CP_ACP);
-        if (!machineW)
-        {
-            MyFree(enumstrW);
-            ret = INVALID_HANDLE_VALUE;
-            goto end;
-        }
-    }
-    ret = SetupDiGetClassDevsExW(class, enumstrW, parent, flags, deviceset,
-            machineW, reserved);
-    MyFree(enumstrW);
-    MyFree(machineW);
-
-end:
-    return ret;
-}
-
-/***********************************************************************
- *             SetupDiGetClassDevsW (SETUPAPI.@)
- */
-HDEVINFO WINAPI SetupDiGetClassDevsW(
-        CONST GUID *class,
-        LPCWSTR enumstr,
-        HWND parent,
-        DWORD flags)
-{
-    return SetupDiGetClassDevsExW(class, enumstr, parent, flags, NULL, NULL,
-            NULL);
-}
-
-/***********************************************************************
- *              SetupDiGetClassDevsExW (SETUPAPI.@)
- */
-HDEVINFO WINAPI SetupDiGetClassDevsExW(
-        CONST GUID *class,
-        PCWSTR enumstr,
-        HWND parent,
-        DWORD flags,
-        HDEVINFO deviceset,
-        PCWSTR machine,
-        PVOID reserved)
-{
-    HDEVINFO hDeviceInfo = INVALID_HANDLE_VALUE;
-    struct DeviceInfoSet *list;
-    CONST GUID *pClassGuid;
-    LONG rc;
-    HDEVINFO set = INVALID_HANDLE_VALUE;
-
-    TRACE("%s %s %p 0x%08x %p %s %p\n", debugstr_guid(class),
-            debugstr_w(enumstr), parent, flags, deviceset, debugstr_w(machine),
-            reserved);
-
-    if (!(flags & DIGCF_ALLCLASSES) && !class)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return INVALID_HANDLE_VALUE;
-    }
-
-    /* Create the deviceset if not set */
-    if (deviceset)
-    {
-        list = (struct DeviceInfoSet *)deviceset;
-        if (list->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-        {
-            SetLastError(ERROR_INVALID_HANDLE);
-            goto cleanup;
-        }
-        hDeviceInfo = deviceset;
-    }
-    else
-    {
-         hDeviceInfo = SetupDiCreateDeviceInfoListExW(
-             flags & (DIGCF_DEVICEINTERFACE | DIGCF_ALLCLASSES) ? NULL : class,
-             NULL, machine, NULL);
-         if (hDeviceInfo == INVALID_HANDLE_VALUE)
-             goto cleanup;
-         list = (struct DeviceInfoSet *)hDeviceInfo;
-    }
-
-    if (flags & DIGCF_PROFILE)
-        FIXME(": flag DIGCF_PROFILE ignored\n");
-
-    if (flags & DIGCF_DEVICEINTERFACE)
-    {
-        if (!class)
-        {
-            SetLastError(ERROR_INVALID_PARAMETER);
-            goto cleanup;
-        }
-        rc = SETUP_CreateInterfaceList(list, machine, class, enumstr, flags & DIGCF_PRESENT);
-    }
-    else
-    {
-        /* Determine which class(es) should be included in the deviceset */
-        if (flags & DIGCF_ALLCLASSES)
-        {
-            /* The caller wants all classes. Check if
-             * the deviceset limits us to one class */
-            if (IsEqualIID(&list->ClassGuid, &GUID_NULL))
-                pClassGuid = NULL;
-            else
-                pClassGuid = &list->ClassGuid;
-        }
-        else if (class)
-        {
-            /* The caller wants one class. Check if it matches deviceset class */
-            if (IsEqualIID(&list->ClassGuid, class)
-             || IsEqualIID(&list->ClassGuid, &GUID_NULL))
-            {
-                pClassGuid = class;
-            }
-            else
-            {
-                SetLastError(ERROR_INVALID_PARAMETER);
-                goto cleanup;
-            }
-        }
-        else if (!IsEqualIID(&list->ClassGuid, &GUID_NULL))
-        {
-            /* No class specified. Try to use the one of the deviceset */
-            if (IsEqualIID(&list->ClassGuid, &GUID_NULL))
-                pClassGuid = &list->ClassGuid;
-            else
-            {
-                SetLastError(ERROR_INVALID_PARAMETER);
-                goto cleanup;
-            }
-        }
-        else
-        {
-            SetLastError(ERROR_INVALID_PARAMETER);
-            goto cleanup;
-        }
-        rc = SETUP_CreateDevicesList(list, machine, pClassGuid, enumstr);
-    }
-    if (rc != ERROR_SUCCESS)
-    {
-        SetLastError(rc);
-        goto cleanup;
-    }
-    set = hDeviceInfo;
-
-cleanup:
-    if (!deviceset && hDeviceInfo != INVALID_HANDLE_VALUE && hDeviceInfo != set)
-        SetupDiDestroyDeviceInfoList(hDeviceInfo);
-    return set;
-}
-
-/***********************************************************************
- *             SetupDiGetDeviceInfoListDetailA  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetDeviceInfoListDetailA(
-        HDEVINFO DeviceInfoSet,
-        PSP_DEVINFO_LIST_DETAIL_DATA_A DevInfoData )
-{
-    struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
-
-    TRACE("%p %p\n", DeviceInfoSet, DevInfoData);
-
-    if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (!DevInfoData ||
-            DevInfoData->cbSize != sizeof(SP_DEVINFO_LIST_DETAIL_DATA_A))
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-    memcpy(&DevInfoData->ClassGuid, &set->ClassGuid, sizeof(GUID));
-    DevInfoData->RemoteMachineHandle = set->hMachine;
-    if (set->MachineName)
-    {
-        FIXME("Stub\n");
-        SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-        return FALSE;
-    }
-    else
-        DevInfoData->RemoteMachineName[0] = 0;
-
-    return TRUE;
-}
-
-/***********************************************************************
- *             SetupDiGetDeviceInfoListDetailW  (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetDeviceInfoListDetailW(
-        HDEVINFO DeviceInfoSet,
-        PSP_DEVINFO_LIST_DETAIL_DATA_W DevInfoData )
-{
-    struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
-
-    TRACE("%p %p\n", DeviceInfoSet, DevInfoData);
-
-    if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (!DevInfoData ||
-            DevInfoData->cbSize != sizeof(SP_DEVINFO_LIST_DETAIL_DATA_W))
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-    memcpy(&DevInfoData->ClassGuid, &set->ClassGuid, sizeof(GUID));
-    DevInfoData->RemoteMachineHandle = set->hMachine;
-    if (set->MachineName)
-        strcpyW(DevInfoData->RemoteMachineName, set->MachineName + 2);
-    else
-        DevInfoData->RemoteMachineName[0] = 0;
-
-    return TRUE;
-}
-
-/***********************************************************************
- *             SetupDiCreateDeviceInterfaceA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiCreateDeviceInterfaceA(
-        HDEVINFO DeviceInfoSet,
-        PSP_DEVINFO_DATA DeviceInfoData,
-        const GUID *InterfaceClassGuid,
-        PCSTR ReferenceString,
-        DWORD CreationFlags,
-        PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
-{
-    BOOL ret;
-    LPWSTR ReferenceStringW = NULL;
-
-    TRACE("%p %p %s %s %08x %p\n", DeviceInfoSet, DeviceInfoData,
-            debugstr_guid(InterfaceClassGuid), debugstr_a(ReferenceString),
-            CreationFlags, DeviceInterfaceData);
-
-    if (ReferenceString)
-    {
-        ReferenceStringW = pSetupMultiByteToUnicode(ReferenceString, CP_ACP);
-        if (ReferenceStringW == NULL) return FALSE;
-    }
-
-    ret = SetupDiCreateDeviceInterfaceW(DeviceInfoSet, DeviceInfoData,
-            InterfaceClassGuid, ReferenceStringW, CreationFlags,
-            DeviceInterfaceData);
-
-    MyFree(ReferenceStringW);
-
-    return ret;
-}
-
-/***********************************************************************
- *             SetupDiCreateDeviceInterfaceW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiCreateDeviceInterfaceW(
-        HDEVINFO DeviceInfoSet,
-        PSP_DEVINFO_DATA DeviceInfoData,
-        const GUID *InterfaceClassGuid,
-        PCWSTR ReferenceString,
-        DWORD CreationFlags,
-        PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
-{
-    struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
-    TRACE("%p %p %s %s %08x %p\n", DeviceInfoSet, DeviceInfoData,
-            debugstr_guid(InterfaceClassGuid), debugstr_w(ReferenceString),
-            CreationFlags, DeviceInterfaceData);
-
-    if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (!DeviceInfoData || DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)
-            || !DeviceInfoData->Reserved)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-    if (!InterfaceClassGuid)
-    {
-        SetLastError(ERROR_INVALID_USER_BUFFER);
-        return FALSE;
-    }
-
-    FIXME("%p %p %s %s %08x %p\n", DeviceInfoSet, DeviceInfoData,
-            debugstr_guid(InterfaceClassGuid), debugstr_w(ReferenceString),
-            CreationFlags, DeviceInterfaceData);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
-}
-
-/***********************************************************************
- *             SetupDiCreateDeviceInterfaceRegKeyA (SETUPAPI.@)
- */
-HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyA(
-        HDEVINFO DeviceInfoSet,
-        PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
-        DWORD Reserved,
-        REGSAM samDesired,
-        HINF InfHandle,
-        PCSTR InfSectionName)
-{
-    HKEY key;
-    PWSTR InfSectionNameW = NULL;
-
-    TRACE("%p %p %d %08x %p %p\n", DeviceInfoSet, DeviceInterfaceData, Reserved,
-            samDesired, InfHandle, InfSectionName);
-    if (InfHandle)
-    {
-        if (!InfSectionName)
-        {
-            SetLastError(ERROR_INVALID_PARAMETER);
-            return INVALID_HANDLE_VALUE;
-        }
-        InfSectionNameW = pSetupMultiByteToUnicode(InfSectionName, CP_ACP);
-        if (!InfSectionNameW)
-            return INVALID_HANDLE_VALUE;
-    }
-    key = SetupDiCreateDeviceInterfaceRegKeyW(DeviceInfoSet,
-            DeviceInterfaceData, Reserved, samDesired, InfHandle,
-            InfSectionNameW);
-    MyFree(InfSectionNameW);
-    return key;
-}
-
-/***********************************************************************
- *             SetupDiCreateDeviceInterfaceRegKeyW (SETUPAPI.@)
- */
-HKEY WINAPI SetupDiCreateDeviceInterfaceRegKeyW(
-        HDEVINFO DeviceInfoSet,
-        PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
-        DWORD Reserved,
-        REGSAM samDesired,
-        HINF InfHandle,
-        PCWSTR InfSectionName)
-{
-    HKEY hKey, hDevKey;
-    LPWSTR SymbolicLink;
-    DWORD Length, Index;
-    LONG rc;
-    WCHAR bracedGuidString[39];
-    struct DeviceInterface *DevItf;
-    struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
-
-    TRACE("%p %p %d %08x %p %p\n", DeviceInfoSet, DeviceInterfaceData, Reserved,
-            samDesired, InfHandle, InfSectionName);
-
-    if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE ||
-            set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return INVALID_HANDLE_VALUE;
-    }
-    if (!DeviceInterfaceData ||
-            DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) ||
-            !DeviceInterfaceData->Reserved)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return INVALID_HANDLE_VALUE;
-    }
-    if (InfHandle && !InfSectionName)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return INVALID_HANDLE_VALUE;
-    }
-
-    hKey = SetupDiOpenClassRegKeyExW(&DeviceInterfaceData->InterfaceClassGuid, samDesired, DIOCR_INTERFACE, NULL, NULL);
-    if (hKey == INVALID_HANDLE_VALUE)
-    {
-        hKey = SetupDiOpenClassRegKeyExW(NULL, samDesired, DIOCR_INTERFACE, NULL, NULL);
-        if (hKey == INVALID_HANDLE_VALUE)
-        {
-            SetLastError(ERROR_INVALID_PARAMETER);
-            return INVALID_HANDLE_VALUE;
-        }
-        SETUPDI_GuidToString(&DeviceInterfaceData->InterfaceClassGuid, bracedGuidString);
-
-        if (RegCreateKeyExW(hKey, bracedGuidString, 0, NULL, 0, samDesired, NULL, &hDevKey, NULL) != ERROR_SUCCESS)
-        {
-            SetLastError(ERROR_INVALID_PARAMETER);
-            return INVALID_HANDLE_VALUE;
-        }
-        RegCloseKey(hKey);
-        hKey = hDevKey;
-    }
-
-    DevItf = (struct DeviceInterface *)DeviceInterfaceData->Reserved;
-
-    Length = (wcslen(DevItf->SymbolicLink)+1) * sizeof(WCHAR);
-    SymbolicLink = HeapAlloc(GetProcessHeap(), 0, Length);
-    if (!SymbolicLink)
-    {
-        RegCloseKey(hKey);
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return INVALID_HANDLE_VALUE;
-    }
-
-    wcscpy(SymbolicLink, DevItf->SymbolicLink);
-
-    Index = 0;
-    while(SymbolicLink[Index])
-    {
-        if (SymbolicLink[Index] == L'\\')
-        {
-            SymbolicLink[Index] = L'#';
-        }
-        Index++;
-    }
-
-    rc = RegCreateKeyExW(hKey, SymbolicLink, 0, NULL, 0, samDesired, NULL, &hDevKey, NULL);
-
-    RegCloseKey(hKey);
-    HeapFree(GetProcessHeap(), 0, SymbolicLink);
-
-    if (rc == ERROR_SUCCESS)
-    {
-        if (InfHandle && InfSectionName)
-        {
-            if (!SetupInstallFromInfSection(NULL /*FIXME */,
-                                            InfHandle,
-                                            InfSectionName,
-                                            SPINST_INIFILES | SPINST_REGISTRY | SPINST_INI2REG | SPINST_FILES | SPINST_BITREG | SPINST_REGSVR | SPINST_UNREGSVR | SPINST_PROFILEITEMS | SPINST_COPYINF,
-                                            hDevKey,
-                                            NULL,
-                                            0,
-                                            set->SelectedDevice->InstallParams.InstallMsgHandler,
-                                            set->SelectedDevice->InstallParams.InstallMsgHandlerContext,
-                                            INVALID_HANDLE_VALUE,
-                                            NULL))
-            {
-                RegCloseKey(hDevKey);
-                return INVALID_HANDLE_VALUE;
-            }
-        }
-    }
-
-    SetLastError(rc);
-    return hDevKey;
-}
-
-/***********************************************************************
- *             SetupDiDeleteDeviceInterfaceRegKey (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiDeleteDeviceInterfaceRegKey(
-        HDEVINFO DeviceInfoSet,
-        PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
-        DWORD Reserved)
-{
-    struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
-    BOOL ret = FALSE;
-
-    TRACE("%p %p %d\n", DeviceInfoSet, DeviceInterfaceData, Reserved);
-
-    if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE ||
-            set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (!DeviceInterfaceData ||
-            DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) ||
-            !DeviceInterfaceData->Reserved)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-
-    FIXME("%p %p %d\n", DeviceInfoSet, DeviceInterfaceData, Reserved);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return ret;
-}
-
-/***********************************************************************
- *             SetupDiEnumDeviceInterfaces (SETUPAPI.@)
- *
- * PARAMS
- *   DeviceInfoSet      [I]    Set of devices from which to enumerate
- *                             interfaces
- *   DeviceInfoData     [I]    (Optional) If specified, a specific device
- *                             instance from which to enumerate interfaces.
- *                             If it isn't specified, all interfaces for all
- *                             devices in the set are enumerated.
- *   InterfaceClassGuid [I]    The interface class to enumerate.
- *   MemberIndex        [I]    An index of the interface instance to enumerate.
- *                             A caller should start with MemberIndex set to 0,
- *                             and continue until the function fails with
- *                             ERROR_NO_MORE_ITEMS.
- *   DeviceInterfaceData [I/O] Returns an enumerated interface.  Its cbSize
- *                             member must be set to
- *                             sizeof(SP_DEVICE_INTERFACE_DATA).
- *
- * RETURNS
- *   Success: non-zero value.
- *   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)
-{
-    struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
-    BOOL ret = FALSE;
-
-    TRACE("%p, %p, %s, %d, %p\n", DeviceInfoSet, DeviceInfoData,
-     debugstr_guid(InterfaceClassGuid), MemberIndex, DeviceInterfaceData);
-
-    if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE ||
-            set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (DeviceInfoData && (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA) ||
-                !DeviceInfoData->Reserved))
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-    if (!DeviceInterfaceData ||
-            DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA))
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-    if (DeviceInfoData)
-    {
-        struct DeviceInfo *devInfo =
-            (struct DeviceInfo *)DeviceInfoData->Reserved;
-        BOOL found = FALSE;
-        PLIST_ENTRY InterfaceListEntry = devInfo->InterfaceListHead.Flink;
-        while (InterfaceListEntry != &devInfo->InterfaceListHead && !found)
-        {
-            struct DeviceInterface *DevItf = CONTAINING_RECORD(InterfaceListEntry, struct DeviceInterface, ListEntry);
-            if (!IsEqualIID(&DevItf->InterfaceClassGuid, InterfaceClassGuid))
-            {
-                InterfaceListEntry = InterfaceListEntry->Flink;
-                continue;
-            }
-            if (MemberIndex-- == 0)
-            {
-                /* return this item */
-                memcpy(&DeviceInterfaceData->InterfaceClassGuid,
-                    &DevItf->InterfaceClassGuid,
-                    sizeof(GUID));
-                DeviceInterfaceData->Flags = DevItf->Flags;
-                DeviceInterfaceData->Reserved = (ULONG_PTR)DevItf;
-                found = TRUE;
-                ret = TRUE;
-            }
-            InterfaceListEntry = InterfaceListEntry->Flink;
-        }
-        if (!found)
-            SetLastError(ERROR_NO_MORE_ITEMS);
-    }
-    else
-    {
-        BOOL found = FALSE;
-        PLIST_ENTRY ItemList = set->ListHead.Flink;
-        while (ItemList != &set->ListHead && !found)
-        {
-            PLIST_ENTRY InterfaceListEntry;
-            struct DeviceInfo *devInfo =
-                CONTAINING_RECORD(ItemList, struct DeviceInfo, ListEntry);
-            InterfaceListEntry = devInfo->InterfaceListHead.Flink;
-            while (InterfaceListEntry != &devInfo->InterfaceListHead && !found)
-            {
-                struct DeviceInterface *DevItf = CONTAINING_RECORD(InterfaceListEntry, struct DeviceInterface, ListEntry);
-                if (!IsEqualIID(&DevItf->InterfaceClassGuid, InterfaceClassGuid))
-                {
-                    InterfaceListEntry = InterfaceListEntry->Flink;
-                    continue;
-                }
-                if (MemberIndex-- == 0)
-                {
-                    /* return this item */
-                    memcpy(&DeviceInterfaceData->InterfaceClassGuid,
-                        &DevItf->InterfaceClassGuid,
-                        sizeof(GUID));
-                    DeviceInterfaceData->Flags = DevItf->Flags;
-                    DeviceInterfaceData->Reserved = (ULONG_PTR)DevItf;
-                    found = TRUE;
-                    ret = TRUE;
-                }
-                InterfaceListEntry = InterfaceListEntry->Flink;
-            }
-            ItemList = ItemList->Flink;
-
-        }
-        if (!found)
-            SetLastError(ERROR_NO_MORE_ITEMS);
-    }
-    return ret;
-}
-
-/***********************************************************************
- *             SetupDiDestroyDeviceInfoList (SETUPAPI.@)
-  *
- * Destroy a DeviceInfoList and free all used memory of the list.
- *
- * PARAMS
- *   devinfo [I] DeviceInfoList pointer to list to destroy
- *
- * RETURNS
- *   Success: non zero value.
- *   Failure: zero value.
- */
-BOOL WINAPI SetupDiDestroyDeviceInfoList(HDEVINFO devinfo)
-{
-    BOOL ret = FALSE;
-
-    TRACE("%p\n", devinfo);
-    if (devinfo && devinfo != INVALID_HANDLE_VALUE)
-    {
-        struct DeviceInfoSet *list = (struct DeviceInfoSet *)devinfo;
-
-        if (list->magic == SETUP_DEVICE_INFO_SET_MAGIC)
-        {
-            ret = DestroyDeviceInfoSet(list);
-        }
-    }
-
-    if (ret == FALSE)
-        SetLastError(ERROR_INVALID_HANDLE);
-
-    return ret;
-}
-
-/***********************************************************************
- *             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)
-{
-    struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
-    PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailDataW = NULL;
-    DWORD sizeW = 0, bytesNeeded;
-    BOOL ret = FALSE;
-
-    TRACE("(%p, %p, %p, %d, %p, %p)\n", DeviceInfoSet,
-     DeviceInterfaceData, DeviceInterfaceDetailData,
-     DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
-
-    if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE ||
-            set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (!DeviceInterfaceData ||
-            DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) ||
-            !DeviceInterfaceData->Reserved)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-    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);
-        return FALSE;
-    }
-
-
-    if (DeviceInterfaceDetailData != NULL)
-    {
-        sizeW = FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath)
-            + (DeviceInterfaceDetailDataSize - FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath)) * sizeof(WCHAR);
-        DeviceInterfaceDetailDataW = (PSP_DEVICE_INTERFACE_DETAIL_DATA_W)MyMalloc(sizeW);
-        if (!DeviceInterfaceDetailDataW)
-        {
-            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        }
-        DeviceInterfaceDetailDataW->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
-    }
-    if (!DeviceInterfaceDetailData || (DeviceInterfaceDetailData && DeviceInterfaceDetailDataW))
-    {
-        ret = SetupDiGetDeviceInterfaceDetailW(
-            DeviceInfoSet,
-            DeviceInterfaceData,
-            DeviceInterfaceDetailDataW,
-            sizeW,
-            &sizeW,
-            DeviceInfoData);
-        bytesNeeded = (sizeW - FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath)) / sizeof(WCHAR)
-            + FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath);
-        if (RequiredSize)
-            *RequiredSize = bytesNeeded;
-        if (ret && DeviceInterfaceDetailData && DeviceInterfaceDetailDataSize >= bytesNeeded)
-        {
-            if (!WideCharToMultiByte(
-                CP_ACP, 0,
-                DeviceInterfaceDetailDataW->DevicePath, -1,
-                DeviceInterfaceDetailData->DevicePath, DeviceInterfaceDetailDataSize - FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_A, DevicePath),
-                NULL, NULL))
-            {
-                ret = FALSE;
-            }
-        }
-    }
-    MyFree(DeviceInterfaceDetailDataW);
-
-    return ret;
-}
-
-/***********************************************************************
- *             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)
-{
-    struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
-    BOOL ret = FALSE;
-
-    TRACE("(%p, %p, %p, %d, %p, %p)\n", DeviceInfoSet,
-     DeviceInterfaceData, DeviceInterfaceDetailData,
-     DeviceInterfaceDetailDataSize, RequiredSize, DeviceInfoData);
-
-    if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE ||
-            set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (!DeviceInterfaceData ||
-            DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA) ||
-            !DeviceInterfaceData->Reserved)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-    if (DeviceInterfaceDetailData && DeviceInterfaceDetailData->cbSize != sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W))
-    {
-        SetLastError(ERROR_INVALID_USER_BUFFER);
-        return FALSE;
-    }
-    if (!DeviceInterfaceDetailData && DeviceInterfaceDetailDataSize)
-    {
-        SetLastError(ERROR_INVALID_USER_BUFFER);
-        return FALSE;
-    }
-    if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-    if ((DeviceInterfaceDetailData != NULL)
-        && (DeviceInterfaceDetailDataSize < (FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA_W, DevicePath)) + sizeof(WCHAR)))
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-    else
-    {
-        struct DeviceInterface *deviceInterface = (struct DeviceInterface *)DeviceInterfaceData->Reserved;
-        LPCWSTR devName = deviceInterface->SymbolicLink;
-        DWORD sizeRequired = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) +
-            (lstrlenW(devName) + 1) * sizeof(WCHAR);
-
-        if (sizeRequired > DeviceInterfaceDetailDataSize)
-        {
-            SetLastError(ERROR_INSUFFICIENT_BUFFER);
-            if (RequiredSize)
-                *RequiredSize = sizeRequired;
-        }
-        else
-        {
-            strcpyW(DeviceInterfaceDetailData->DevicePath, devName);
-            TRACE("DevicePath is %s\n", debugstr_w(DeviceInterfaceDetailData->DevicePath));
-            if (DeviceInfoData)
-            {
-                memcpy(&DeviceInfoData->ClassGuid,
-                    &deviceInterface->DeviceInfo->ClassGuid,
-                    sizeof(GUID));
-                DeviceInfoData->DevInst = deviceInterface->DeviceInfo->dnDevInst;
-                DeviceInfoData->Reserved = (ULONG_PTR)deviceInterface->DeviceInfo;
-            }
-            ret = TRUE;
-        }
-    }
-    return ret;
-}
-
-struct PropertyMapEntry
-{
-    DWORD   regType;
-    LPCSTR  nameA;
-    LPCWSTR nameW;
-};
-
-static struct PropertyMapEntry PropertyMap[] = {
-    { REG_SZ, "DeviceDesc", REGSTR_VAL_DEVDESC },
-    { REG_MULTI_SZ, "HardwareId", REGSTR_VAL_HARDWAREID },
-    { REG_MULTI_SZ, "CompatibleIDs", REGSTR_VAL_COMPATIBLEIDS },
-    { 0, NULL, NULL }, /* SPDRP_UNUSED0 */
-    { REG_SZ, "Service", REGSTR_VAL_SERVICE },
-    { 0, NULL, NULL }, /* SPDRP_UNUSED1 */
-    { 0, NULL, NULL }, /* SPDRP_UNUSED2 */
-    { REG_SZ, "Class", REGSTR_VAL_CLASS },
-    { REG_SZ, "ClassGUID", REGSTR_VAL_CLASSGUID },
-    { REG_SZ, "Driver", REGSTR_VAL_DRIVER },
-    { REG_DWORD, "ConfigFlags", REGSTR_VAL_CONFIGFLAGS },
-    { REG_SZ, "Mfg", REGSTR_VAL_MFG },
-    { REG_SZ, "FriendlyName", REGSTR_VAL_FRIENDLYNAME },
-    { REG_SZ, "LocationInformation", REGSTR_VAL_LOCATION_INFORMATION },
-    { 0, NULL, NULL }, /* SPDRP_PHYSICAL_DEVICE_OBJECT_NAME */
-    { REG_DWORD, "Capabilities", REGSTR_VAL_CAPABILITIES },
-    { REG_DWORD, "UINumber", REGSTR_VAL_UI_NUMBER },
-    { REG_MULTI_SZ, "UpperFilters", REGSTR_VAL_UPPERFILTERS },
-    { REG_MULTI_SZ, "LowerFilters", REGSTR_VAL_LOWERFILTERS },
-    { 0, NULL, NULL }, /* SPDRP_BUSTYPEGUID */
-    { 0, NULL, NULL }, /* SPDRP_LEGACYBUSTYPE */
-    { 0, NULL, NULL }, /* SPDRP_BUSNUMBER */
-    { 0, NULL, NULL }, /* SPDRP_ENUMERATOR_NAME */
-    { REG_BINARY, "Security", REGSTR_SECURITY },
-    { 0, NULL, NULL }, /* SPDRP_SECURITY_SDS */
-    { 0, NULL, NULL }, /* SPDRP_DEVTYPE */
-    { 0, NULL, NULL }, /* SPDRP_EXCLUSIVE */
-    { 0, NULL, NULL }, /* SPDRP_CHARACTERISTICS */
-    { 0, NULL, NULL }, /* SPDRP_ADDRESS */
-    { REG_SZ, "UINumberDescFormat", REGSTR_UI_NUMBER_DESC_FORMAT },
-    { 0, NULL, NULL }, /* SPDRP_DEVICE_POWER_DATA */
-    { 0, NULL, NULL }, /* SPDRP_REMOVAL_POLICY */
-    { 0, NULL, NULL }, /* SPDRP_REMOVAL_POLICY_HW_DEFAULT */
-    { 0, NULL, NULL }, /* SPDRP_REMOVAL_POLICY_OVERRIDE */
-    { 0, NULL, NULL }, /* SPDRP_INSTALL_STATE */
-};
-
-/***********************************************************************
- *             SetupDiGetDeviceRegistryPropertyA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetDeviceRegistryPropertyA(
-        HDEVINFO  DeviceInfoSet,
-        PSP_DEVINFO_DATA  DeviceInfoData,
-        DWORD   Property,
-        PDWORD  PropertyRegDataType,
-        PBYTE   PropertyBuffer,
-        DWORD   PropertyBufferSize,
-        PDWORD  RequiredSize)
-{
-    BOOL ret;
-    BOOL bIsStringProperty;
-    DWORD RegType;
-    DWORD RequiredSizeA, RequiredSizeW;
-    DWORD PropertyBufferSizeW = 0;
-    PBYTE PropertyBufferW = NULL;
-
-    TRACE("%p %p %d %p %p %d %p\n", DeviceInfoSet, DeviceInfoData,
-        Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize,
-        RequiredSize);
-
-    if (PropertyBufferSize != 0)
-    {
-        PropertyBufferSizeW = PropertyBufferSize * 2;
-        PropertyBufferW = HeapAlloc(GetProcessHeap(), 0, PropertyBufferSizeW);
-        if (!PropertyBufferW)
-        {
-            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-            return FALSE;
-        }
-    }
-
-    ret = SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet,
-                                            DeviceInfoData,
-                                            Property,
-                                            &RegType,
-                                            PropertyBufferW,
-                                            PropertyBufferSizeW,
-                                            &RequiredSizeW);
-
-    if (ret || GetLastError() == ERROR_INSUFFICIENT_BUFFER)
-    {
-        bIsStringProperty = (RegType == REG_SZ || RegType == REG_MULTI_SZ || RegType == REG_EXPAND_SZ);
-
-        if (bIsStringProperty)
-           RequiredSizeA = RequiredSizeW / sizeof(WCHAR);
-        else
-            RequiredSizeA = RequiredSizeW;
-        if (RequiredSize)
-            *RequiredSize = RequiredSizeA;
-        if (PropertyRegDataType)
-            *PropertyRegDataType = RegType;
-    }
-
-    if (!ret)
-    {
-        HeapFree(GetProcessHeap(), 0, PropertyBufferW);
-        return ret;
-    }
-
-    if (RequiredSizeA <= PropertyBufferSize)
-    {
-        if (bIsStringProperty && PropertyBufferSize > 0)
-        {
-            if (WideCharToMultiByte(CP_ACP, 0, (LPWSTR)PropertyBufferW, RequiredSizeW / sizeof(WCHAR), (LPSTR)PropertyBuffer, PropertyBufferSize, NULL, NULL) == 0)
-            {
-                /* Last error is already set by WideCharToMultiByte */
-                ret = FALSE;
-            }
-        }
-        else
-            memcpy(PropertyBuffer, PropertyBufferW, RequiredSizeA);
-    }
-    else
-    {
-        SetLastError(ERROR_INSUFFICIENT_BUFFER);
-        ret = FALSE;
-    }
-
-    HeapFree(GetProcessHeap(), 0, PropertyBufferW);
-    return ret;
-}
-
-/***********************************************************************
- *             SetupDiGetDeviceRegistryPropertyW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetDeviceRegistryPropertyW(
-        HDEVINFO  DeviceInfoSet,
-        PSP_DEVINFO_DATA  DeviceInfoData,
-        DWORD   Property,
-        PDWORD  PropertyRegDataType,
-        PBYTE   PropertyBuffer,
-        DWORD   PropertyBufferSize,
-        PDWORD  RequiredSize)
-{
-    BOOL ret = FALSE;
-    struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
-    struct DeviceInfo *devInfo;
-
-    TRACE("%p %p %d %p %p %d %p\n", DeviceInfoSet, DeviceInfoData,
-        Property, PropertyRegDataType, PropertyBuffer, PropertyBufferSize,
-        RequiredSize);
-
-    if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (!DeviceInfoData || DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)
-            || !DeviceInfoData->Reserved)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-    devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
-    if (Property < sizeof(PropertyMap) / sizeof(PropertyMap[0])
-        && PropertyMap[Property].nameW)
-    {
-        DWORD size = PropertyBufferSize;
-        HKEY hKey;
-        LONG l;
-        hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE);
-        if (hKey == INVALID_HANDLE_VALUE)
-            return FALSE;
-        l = RegQueryValueExW(hKey, PropertyMap[Property].nameW,
-                NULL, PropertyRegDataType, PropertyBuffer, &size);
-        RegCloseKey(hKey);
-
-        if (RequiredSize)
-            *RequiredSize = size;
-        switch(l) {
-            case ERROR_SUCCESS:
-                if (PropertyBuffer != NULL || size == 0)
-                    ret = TRUE;
-                else
-                    SetLastError(ERROR_INSUFFICIENT_BUFFER);
-                break;
-            case ERROR_MORE_DATA:
-                SetLastError(ERROR_INSUFFICIENT_BUFFER);
-                break;
-            default:
-                SetLastError(l);
-        }
-    }
-    else if (Property == SPDRP_PHYSICAL_DEVICE_OBJECT_NAME)
-    {
-        DWORD required = (strlenW(devInfo->Data) + 1) * sizeof(WCHAR);
-
-        if (PropertyRegDataType)
-            *PropertyRegDataType = REG_SZ;
-        if (RequiredSize)
-            *RequiredSize = required;
-        if (PropertyBufferSize >= required)
-        {
-            strcpyW((LPWSTR)PropertyBuffer, devInfo->Data);
-            ret = TRUE;
-        }
-        else
-            SetLastError(ERROR_INSUFFICIENT_BUFFER);
-    }
-    else
-    {
-        ERR("Property 0x%lx not implemented\n", Property);
-        SetLastError(ERROR_NOT_SUPPORTED);
-    }
-    return ret;
-}
-
-/***********************************************************************
- *             SetupDiSetDeviceRegistryPropertyA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiSetDeviceRegistryPropertyA(
-        HDEVINFO DeviceInfoSet,
-        PSP_DEVINFO_DATA DeviceInfoData,
-        DWORD Property,
-        const BYTE *PropertyBuffer,
-        DWORD PropertyBufferSize)
-{
-    BOOL ret = FALSE;
-    struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
-
-    TRACE("%p %p %d %p %d\n", DeviceInfoSet, DeviceInfoData, Property,
-        PropertyBuffer, PropertyBufferSize);
-
-    if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (!DeviceInfoData || DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)
-            || !DeviceInfoData->Reserved)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-
-    FIXME("%p %p 0x%lx %p 0x%lx\n", DeviceInfoSet, DeviceInfoData,
-        Property, PropertyBuffer, PropertyBufferSize);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return ret;
-}
-
-/***********************************************************************
- *             SetupDiSetDeviceRegistryPropertyW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiSetDeviceRegistryPropertyW(
-        HDEVINFO DeviceInfoSet,
-        PSP_DEVINFO_DATA DeviceInfoData,
-        DWORD Property,
-        const BYTE *PropertyBuffer,
-        DWORD PropertyBufferSize)
-{
-    BOOL ret = FALSE;
-    struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
-
-    TRACE("%p %p %d %p %d\n", DeviceInfoSet, DeviceInfoData, Property,
-        PropertyBuffer, PropertyBufferSize);
-
-    if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (!DeviceInfoData || DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)
-            || !DeviceInfoData->Reserved)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-    if (Property < sizeof(PropertyMap) / sizeof(PropertyMap[0])
-        && PropertyMap[Property].nameW)
-    {
-        HKEY hKey;
-        LONG l;
-        hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_SET_VALUE);
-        if (hKey == INVALID_HANDLE_VALUE)
-            return FALSE;
-        /* Write new data */
-        l = RegSetValueExW(
-            hKey, PropertyMap[Property].nameW, 0,
-                PropertyMap[Property].regType, PropertyBuffer,
-                PropertyBufferSize);
-        if (!l)
-            ret = TRUE;
-        else
-            SetLastError(l);
-        RegCloseKey(hKey);
-    }
-    else
-    {
-        ERR("Property 0x%lx not implemented\n", Property);
-        SetLastError(ERROR_NOT_SUPPORTED);
-    }
-
-    TRACE("Returning %d\n", ret);
-    return ret;
-}
-
-/***********************************************************************
- *             SetupDiInstallClassA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiInstallClassA(
-        HWND hwndParent,
-        PCSTR InfFileName,
-        DWORD Flags,
-        HSPFILEQ FileQueue)
-{
-    return SetupDiInstallClassExA(hwndParent, InfFileName, Flags, FileQueue, NULL, NULL, NULL);
-}
-
-/***********************************************************************
- *             SetupDiInstallClassExA (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiInstallClassExA(
-    IN HWND hwndParent OPTIONAL,
-    IN PCSTR InfFileName OPTIONAL,
-    IN DWORD Flags,
-    IN HSPFILEQ FileQueue OPTIONAL,
-    IN CONST GUID *InterfaceClassGuid OPTIONAL,
-    IN PVOID Reserved1,
-    IN PVOID Reserved2)
-{
-    PWSTR InfFileNameW = NULL;
-    BOOL Result;
-
-    if (!InfFileName)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-    else
-    {
-        InfFileNameW = pSetupMultiByteToUnicode(InfFileName, CP_ACP);
-        if (InfFileNameW == NULL)
-        {
-            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-            return FALSE;
-        }
-    }
-
-    Result = SetupDiInstallClassExW(hwndParent, InfFileNameW, Flags,
-        FileQueue, InterfaceClassGuid, Reserved1, Reserved2);
-
-    MyFree(InfFileNameW);
-
-    return Result;
-}
-
-HKEY SETUP_CreateClassKey(HINF hInf)
-{
-    WCHAR FullBuffer[MAX_PATH];
-    WCHAR Buffer[MAX_PATH];
-    DWORD RequiredSize;
-    HKEY hClassKey;
-    DWORD Disposition;
-
-    /* Obtain the Class GUID for this class */
-    if (!SetupGetLineTextW(NULL,
-                           hInf,
-                           Version,
-                           REGSTR_VAL_CLASSGUID,
-                           Buffer,
-                           sizeof(Buffer) / sizeof(WCHAR),
-                           &RequiredSize))
-    {
-        return INVALID_HANDLE_VALUE;
-    }
-
-    /* Build the corresponding registry key name */
-    lstrcpyW(FullBuffer, REGSTR_PATH_CLASS_NT);
-    lstrcatW(FullBuffer, BackSlash);
-    lstrcatW(FullBuffer, Buffer);
-
-    /* Obtain the Class name for this class */
-    if (!SetupGetLineTextW(NULL,
-                           hInf,
-                           Version,
-                           REGSTR_VAL_CLASS,
-                           Buffer,
-                           sizeof(Buffer) / sizeof(WCHAR),
-                           &RequiredSize))
-    {
-        return INVALID_HANDLE_VALUE;
-    }
-
-    /* Try to open or create the registry key */
-    TRACE("Opening class key %s\n", debugstr_w(FullBuffer));
-#if 0 // I keep this for reference...
-    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
-                      FullBuffer,
-                      0,
-                      KEY_SET_VALUE,
-                      &hClassKey))
-    {
-        /* Use RegCreateKeyExW */
-    }
-#endif
-    if (RegCreateKeyExW(HKEY_LOCAL_MACHINE,
-                        FullBuffer,
-                        0,
-                        NULL,
-                        REG_OPTION_NON_VOLATILE,
-                        KEY_SET_VALUE,
-                        NULL,
-                        &hClassKey,
-                        &Disposition))
-    {
-        ERR("RegCreateKeyExW(%s) failed\n", debugstr_w(FullBuffer));
-        return INVALID_HANDLE_VALUE;
-    }
-    if (Disposition == REG_CREATED_NEW_KEY)
-        TRACE("The class key %s was successfully created\n", debugstr_w(FullBuffer));
-    else
-        TRACE("The class key %s was successfully opened\n", debugstr_w(FullBuffer));
-
-    TRACE( "setting value %s to %s\n", debugstr_w(REGSTR_VAL_CLASS), debugstr_w(Buffer) );
-    if (RegSetValueExW(hClassKey,
-                       REGSTR_VAL_CLASS,
-                       0,
-                       REG_SZ,
-                       (LPBYTE)Buffer,
-                       RequiredSize * sizeof(WCHAR)))
-    {
-        RegCloseKey(hClassKey);
-        RegDeleteKeyW(HKEY_LOCAL_MACHINE,
-                      FullBuffer);
-        return INVALID_HANDLE_VALUE;
-    }
-
-    return hClassKey;
-}
-
-/***********************************************************************
- *             SetupDiInstallClassW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiInstallClassW(
-        HWND hwndParent,
-        PCWSTR InfFileName,
-        DWORD Flags,
-        HSPFILEQ FileQueue)
-{
-    return SetupDiInstallClassExW(hwndParent, InfFileName, Flags, FileQueue, NULL, NULL, NULL);
-}
-
-
-/***********************************************************************
- *             SetupDiOpenClassRegKey  (SETUPAPI.@)
- */
-HKEY WINAPI SetupDiOpenClassRegKey(
-        const GUID* ClassGuid,
-        REGSAM samDesired)
-{
-    return SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,
-                                     DIOCR_INSTALLER, NULL, NULL);
-}
-
-
-/***********************************************************************
- *             SetupDiOpenClassRegKeyExA  (SETUPAPI.@)
- */
-HKEY WINAPI SetupDiOpenClassRegKeyExA(
-        const GUID* ClassGuid,
-        REGSAM samDesired,
-        DWORD Flags,
-        PCSTR MachineName,
-        PVOID Reserved)
-{
-    PWSTR MachineNameW = NULL;
-    HKEY hKey;
-
-    TRACE("%s 0x%lx 0x%lx %s %p\n", debugstr_guid(ClassGuid), samDesired,
-        Flags, debugstr_a(MachineName), Reserved);
-
-    if (MachineName)
-    {
-        MachineNameW = pSetupMultiByteToUnicode(MachineName, CP_ACP);
-        if (MachineNameW == NULL)
-            return INVALID_HANDLE_VALUE;
-    }
-
-    hKey = SetupDiOpenClassRegKeyExW(ClassGuid, samDesired,
-                                     Flags, MachineNameW, Reserved);
-
-    MyFree(MachineNameW);
-
-    return hKey;
-}
-
-
-/***********************************************************************
- *             SetupDiOpenClassRegKeyExW  (SETUPAPI.@)
- */
-HKEY WINAPI SetupDiOpenClassRegKeyExW(
-        const GUID* ClassGuid,
-        REGSAM samDesired,
-        DWORD Flags,
-        PCWSTR MachineName,
-        PVOID Reserved)
-{
-    HKEY HKLM;
-    HKEY hClassesKey;
-    HKEY key;
-    LPCWSTR lpKeyName;
-    LONG l;
-
-    TRACE("%s 0x%lx 0x%lx %s %p\n", debugstr_guid(ClassGuid), samDesired,
-        Flags, debugstr_w(MachineName), Reserved);
-
-    if (MachineName != NULL)
-    {
-        l = RegConnectRegistryW(MachineName, HKEY_LOCAL_MACHINE, &HKLM);
-        if (l != ERROR_SUCCESS)
-        {
-            SetLastError(l);
-            return INVALID_HANDLE_VALUE;
-        }
-    }
-    else
-        HKLM = HKEY_LOCAL_MACHINE;
-
-    if (Flags == DIOCR_INSTALLER)
-    {
-        lpKeyName = REGSTR_PATH_CLASS_NT;
-    }
-    else if (Flags == DIOCR_INTERFACE)
-    {
-        lpKeyName = REGSTR_PATH_DEVICE_CLASSES;
-    }
-    else
-    {
-        ERR("Invalid Flags parameter!\n");
-        SetLastError(ERROR_INVALID_FLAGS);
-        if (MachineName != NULL) RegCloseKey(HKLM);
-        return INVALID_HANDLE_VALUE;
-    }
-
-    if (!ClassGuid)
-    {
-        if ((l = RegOpenKeyExW(HKLM,
-                               lpKeyName,
-                               0,
-                               samDesired,
-                               &hClassesKey)))
-        {
-            SetLastError(ERROR_INVALID_CLASS);
-            hClassesKey = INVALID_HANDLE_VALUE;
-        }
-        if (MachineName != NULL)
-            RegCloseKey(HKLM);
-        key = hClassesKey;
-    }
-    else
-    {
-        WCHAR bracedGuidString[39];
-
-        SETUPDI_GuidToString(ClassGuid, bracedGuidString);
-
-        if (!(l = RegOpenKeyExW(HKLM,
-                                lpKeyName,
-                                0,
-                                samDesired,
-                                &hClassesKey)))
-        {
-            if (MachineName != NULL)
-                RegCloseKey(HKLM);
-
-            if ((l = RegOpenKeyExW(hClassesKey,
-                                   bracedGuidString,
-                                   0,
-                                   samDesired,
-                                   &key)))
-            {
-                SetLastError(l);
-                key = INVALID_HANDLE_VALUE;
-            }
-            RegCloseKey(hClassesKey);
-        }
-        else
-        {
-            if (MachineName != NULL) RegCloseKey(HKLM);
-            SetLastError(l);
-            key = INVALID_HANDLE_VALUE;
-        }
-    }
-
-    return key;
-}
-
-/***********************************************************************
- *             SetupDiOpenDeviceInterfaceW (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiOpenDeviceInterfaceW(
-        HDEVINFO DeviceInfoSet,
-        PCWSTR DevicePath,
-        DWORD OpenFlags,
-        PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
-{
-    struct DeviceInfoSet * list;
-    PCWSTR pEnd;
-    DWORD dwLength, dwError, dwIndex, dwKeyName, dwSubIndex;
-    CLSID ClassId;
-    WCHAR Buffer[MAX_PATH + 1];
-    WCHAR SymBuffer[MAX_PATH + 1];
-    WCHAR InstancePath[MAX_PATH + 1];
-    HKEY hKey, hDevKey, hSymKey;
-    struct DeviceInfo * deviceInfo;
-    struct DeviceInterface *deviceInterface;
-    BOOL Ret;
-    PLIST_ENTRY ItemList;
-    PLIST_ENTRY InterfaceListEntry;
-
-    TRACE("%p %s %08x %p\n",
-        DeviceInfoSet, debugstr_w(DevicePath), OpenFlags, DeviceInterfaceData);
-
-
-    if (DeviceInterfaceData && DeviceInterfaceData->cbSize != sizeof(SP_DEVICE_INTERFACE_DATA))
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-
-    if (((struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-
-    list = (struct DeviceInfoSet * )DeviceInfoSet;
-
-    dwLength = wcslen(DevicePath);
-    if (dwLength < 39)
-    {
-        /* path must be at least a guid length + L'\0' */
-        SetLastError(ERROR_BAD_PATHNAME);
-        return FALSE;
-    }
-
-    if (DevicePath[0] != L'\\' ||
-        DevicePath[1] != L'\\' ||
-        (DevicePath[2] != L'?' && DevicePath[2] != L'.') ||
-        DevicePath[3] != L'\\')
-    {
-        /* invalid formatted path */
-        SetLastError(ERROR_BAD_PATHNAME);
-        return FALSE;
-    }
-
-    /* check for reference strings */
-    pEnd = wcschr(&DevicePath[4], L'\\');
-    if (!pEnd)
-    {
-        /* no reference string */
-        pEnd = DevicePath + dwLength;
-    }
-
-    /* copy guid */
-    wcscpy(Buffer, pEnd - 37);
-    Buffer[36] = L'\0';
-
-    dwError = UuidFromStringW(Buffer, &ClassId);
-    if (dwError != NOERROR)
-    {
-        /* invalid formatted path */
-        SetLastError(ERROR_BAD_PATHNAME);
-        return FALSE;
-    }
-
-    hKey = SetupDiOpenClassRegKeyExW(&ClassId, KEY_READ, DIOCR_INTERFACE, list->MachineName, NULL);
-
-    if (hKey == INVALID_HANDLE_VALUE)
-    {
-        /* invalid device class */
-        return FALSE;
-    }
-
-    ItemList = list->ListHead.Flink;
-    while (ItemList != &list->ListHead)
-    {
-        deviceInfo = CONTAINING_RECORD(ItemList, struct DeviceInfo, ListEntry);
-        InterfaceListEntry = deviceInfo->InterfaceListHead.Flink;
-        while (InterfaceListEntry != &deviceInfo->InterfaceListHead)
-        {
-            deviceInterface = CONTAINING_RECORD(InterfaceListEntry, struct DeviceInterface, ListEntry);
-            if (!IsEqualIID(&deviceInterface->InterfaceClassGuid, &ClassId))
-            {
-                InterfaceListEntry = InterfaceListEntry->Flink;
-                continue;
-            }
-
-            if (!wcsicmp(deviceInterface->SymbolicLink, DevicePath))
-            {
-                if (DeviceInterfaceData)
-                {
-                    DeviceInterfaceData->Reserved = (ULONG_PTR)deviceInterface;
-                    DeviceInterfaceData->Flags = deviceInterface->Flags;
-                    CopyMemory(&DeviceInterfaceData->InterfaceClassGuid, &ClassId, sizeof(GUID));
-                }
-
-                return TRUE;
-            }
-
-        }
-    }
-
-
-    dwIndex = 0;
-    do
-    {
-        Buffer[0] = 0;
-        dwKeyName = sizeof(Buffer) / sizeof(WCHAR);
-        dwError = RegEnumKeyExW(hKey, dwIndex, Buffer, &dwKeyName, NULL, NULL, NULL, NULL);
-
-        if (dwError != ERROR_SUCCESS)
-            break;
-
-        if (RegOpenKeyExW(hKey, Buffer, 0, KEY_READ, &hDevKey) != ERROR_SUCCESS)
-            break;
-
-        dwSubIndex = 0;
-        InstancePath[0] = 0;
-        dwKeyName = sizeof(InstancePath);
-
-        dwError = RegQueryValueExW(hDevKey, L"DeviceInstance", NULL, NULL, (LPBYTE)InstancePath, &dwKeyName);
-
-        while(TRUE)
-        {
-            Buffer[0] = 0;
-            dwKeyName = sizeof(Buffer) / sizeof(WCHAR);
-            dwError = RegEnumKeyExW(hDevKey, dwSubIndex, Buffer, &dwKeyName, NULL, NULL, NULL, NULL);
-
-            if (dwError != ERROR_SUCCESS)
-                break;
-
-            dwError = RegOpenKeyExW(hDevKey, Buffer, 0, KEY_READ, &hSymKey);
-            if (dwError != ERROR_SUCCESS)
-                break;
-
-            /* query for symbolic link */
-            dwKeyName = sizeof(SymBuffer);
-            SymBuffer[0] = L'\0';
-            dwError = RegQueryValueExW(hSymKey, L"SymbolicLink", NULL, NULL, (LPBYTE)SymBuffer, &dwKeyName);
-
-            if (dwError != ERROR_SUCCESS)
-            {
-                RegCloseKey(hSymKey);
-                break;
-            }
-
-            if (!wcsicmp(SymBuffer, DevicePath))
-            {
-                Ret = CreateDeviceInfo(list, InstancePath, &ClassId, &deviceInfo);
-                RegCloseKey(hSymKey);
-                RegCloseKey(hDevKey);
-                RegCloseKey(hKey);
-
-                if (Ret)
-                {
-                    deviceInterface = HeapAlloc(GetProcessHeap(), 0, sizeof(struct DeviceInterface) + (wcslen(SymBuffer) + 1) * sizeof(WCHAR));
-                    if (deviceInterface)
-                    {
-
-                        CopyMemory(&deviceInterface->InterfaceClassGuid, &ClassId, sizeof(GUID));
-                        deviceInterface->DeviceInfo = deviceInfo;
-                        deviceInterface->Flags = SPINT_ACTIVE; //FIXME
-
-                        wcscpy(deviceInterface->SymbolicLink, SymBuffer);
-
-                        InsertTailList(&deviceInfo->InterfaceListHead, &deviceInterface->ListEntry);
-                        InsertTailList(&list->ListHead, &deviceInfo->ListEntry);
-
-
-                        if (DeviceInterfaceData)
-                        {
-                            DeviceInterfaceData->Reserved = (ULONG_PTR)deviceInterface;
-                            DeviceInterfaceData->Flags = deviceInterface->Flags;
-                            CopyMemory(&DeviceInterfaceData->InterfaceClassGuid, &ClassId, sizeof(GUID));
-                        }
-                        else
-                        {
-                            Ret = FALSE;
-                            SetLastError(ERROR_INVALID_USER_BUFFER);
-                        }
-                    }
-                }
-                else
-                {
-                    HeapFree(GetProcessHeap(), 0, deviceInfo);
-                    Ret = FALSE;
-                }
-                return Ret;
-        }
-        RegCloseKey(hSymKey);
-        dwSubIndex++;
-    }
-
-    RegCloseKey(hDevKey);
-    dwIndex++;
-    } while(TRUE);
-
-    RegCloseKey(hKey);
-    return FALSE;
-}
-
-/***********************************************************************
- *             SetupDiOpenDeviceInterfaceA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiOpenDeviceInterfaceA(
-        HDEVINFO DeviceInfoSet,
-        PCSTR DevicePath,
-        DWORD OpenFlags,
-        PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData)
-{
-    LPWSTR DevicePathW = NULL;
-    BOOL bResult;
-
-    TRACE("%p %s %08lx %p\n", DeviceInfoSet, debugstr_a(DevicePath), OpenFlags, DeviceInterfaceData);
-
-    DevicePathW = pSetupMultiByteToUnicode(DevicePath, CP_ACP);
-    if (DevicePathW == NULL)
-        return FALSE;
-
-    bResult = SetupDiOpenDeviceInterfaceW(DeviceInfoSet,
-        DevicePathW, OpenFlags, DeviceInterfaceData);
-
-    MyFree(DevicePathW);
-
-    return bResult;
-}
-
-/***********************************************************************
- *             SetupDiSetClassInstallParamsA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiSetClassInstallParamsA(
-        HDEVINFO  DeviceInfoSet,
-        PSP_DEVINFO_DATA DeviceInfoData,
-        PSP_CLASSINSTALL_HEADER ClassInstallParams,
-        DWORD ClassInstallParamsSize)
-{
-    FIXME("%p %p %x %u\n",DeviceInfoSet, DeviceInfoData,
-          ClassInstallParams->InstallFunction, ClassInstallParamsSize);
-    return FALSE;
-}
-
-static BOOL WINAPI
-IntSetupDiRegisterDeviceInfo(
-        IN HDEVINFO DeviceInfoSet,
-        IN OUT PSP_DEVINFO_DATA DeviceInfoData)
-{
-    return SetupDiRegisterDeviceInfo(DeviceInfoSet, DeviceInfoData, 0, NULL, NULL, NULL);
-}
-
-/***********************************************************************
- *             SetupDiCallClassInstaller (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiCallClassInstaller(
-        DI_FUNCTION InstallFunction,
-        HDEVINFO DeviceInfoSet,
-        PSP_DEVINFO_DATA DeviceInfoData)
-{
-    BOOL ret = FALSE;
-
-    TRACE("%u %p %p\n", InstallFunction, DeviceInfoSet, DeviceInfoData);
-
-    if (!DeviceInfoSet)
-        SetLastError(ERROR_INVALID_PARAMETER);
-    else if (DeviceInfoSet == (HDEVINFO)INVALID_HANDLE_VALUE)
-        SetLastError(ERROR_INVALID_HANDLE);
-    else if (((struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-        SetLastError(ERROR_INVALID_HANDLE);
-    else if (((struct DeviceInfoSet *)DeviceInfoSet)->HKLM != HKEY_LOCAL_MACHINE)
-        SetLastError(ERROR_INVALID_HANDLE);
-    else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
-        SetLastError(ERROR_INVALID_USER_BUFFER);
-    else
-    {
-        SP_DEVINSTALL_PARAMS_W InstallParams;
-#define CLASS_COINSTALLER  0x1
-#define DEVICE_COINSTALLER 0x2
-#define CLASS_INSTALLER    0x4
-        UCHAR CanHandle = 0;
-        DEFAULT_CLASS_INSTALL_PROC DefaultHandler = NULL;
-
-        switch (InstallFunction)
-        {
-            case DIF_ADDPROPERTYPAGE_ADVANCED:
-                CanHandle = CLASS_COINSTALLER | DEVICE_COINSTALLER | CLASS_INSTALLER;
-                break;
-            case DIF_ADDREMOTEPROPERTYPAGE_ADVANCED:
-                CanHandle = CLASS_COINSTALLER | DEVICE_COINSTALLER | CLASS_INSTALLER;
-                break;
-            case DIF_ALLOW_INSTALL:
-                CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
-                break;
-            case DIF_DETECT:
-                CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
-                break;
-            case DIF_DESTROYPRIVATEDATA:
-                CanHandle = CLASS_INSTALLER;
-                break;
-            case DIF_INSTALLDEVICE:
-                CanHandle = CLASS_COINSTALLER | DEVICE_COINSTALLER | CLASS_INSTALLER;
-                DefaultHandler = SetupDiInstallDevice;
-                break;
-            case DIF_INSTALLDEVICEFILES:
-                CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
-                DefaultHandler = SetupDiInstallDriverFiles;
-                break;
-            case DIF_INSTALLINTERFACES:
-                CanHandle = CLASS_COINSTALLER | DEVICE_COINSTALLER | CLASS_INSTALLER;
-                DefaultHandler = SetupDiInstallDeviceInterfaces;
-                break;
-            case DIF_NEWDEVICEWIZARD_FINISHINSTALL:
-                CanHandle = CLASS_COINSTALLER | DEVICE_COINSTALLER | CLASS_INSTALLER;
-                break;
-            case DIF_NEWDEVICEWIZARD_POSTANALYZE:
-                CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
-                break;
-            case DIF_NEWDEVICEWIZARD_PREANALYZE:
-                CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
-                break;
-            case DIF_NEWDEVICEWIZARD_PRESELECT:
-                CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
-                break;
-            case DIF_NEWDEVICEWIZARD_SELECT:
-                CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
-                break;
-            case DIF_POWERMESSAGEWAKE:
-                CanHandle = CLASS_COINSTALLER | DEVICE_COINSTALLER | CLASS_INSTALLER;
-                break;
-            case DIF_PROPERTYCHANGE:
-                CanHandle = CLASS_COINSTALLER | DEVICE_COINSTALLER | CLASS_INSTALLER;
-                DefaultHandler = SetupDiChangeState;
-                break;
-            case DIF_REGISTER_COINSTALLERS:
-                CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
-                DefaultHandler = SetupDiRegisterCoDeviceInstallers;
-                break;
-            case DIF_REGISTERDEVICE:
-                CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
-                DefaultHandler = IntSetupDiRegisterDeviceInfo;
-                break;
-            case DIF_REMOVE:
-                CanHandle = CLASS_COINSTALLER | DEVICE_COINSTALLER | CLASS_INSTALLER;
-                DefaultHandler = SetupDiRemoveDevice;
-                break;
-            case DIF_SELECTBESTCOMPATDRV:
-                CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
-                DefaultHandler = SetupDiSelectBestCompatDrv;
-                break;
-            case DIF_SELECTDEVICE:
-                CanHandle = CLASS_COINSTALLER | CLASS_INSTALLER;
-                DefaultHandler = SetupDiSelectDevice;
-                break;
-            case DIF_TROUBLESHOOTER:
-                CanHandle = CLASS_COINSTALLER | DEVICE_COINSTALLER | CLASS_INSTALLER;
-                break;
-            case DIF_UNREMOVE:
-                CanHandle = CLASS_COINSTALLER | DEVICE_COINSTALLER | CLASS_INSTALLER;
-                DefaultHandler = SetupDiUnremoveDevice;
-                break;
-            default:
-                ERR("Install function %u not supported\n", InstallFunction);
-                SetLastError(ERROR_NOT_SUPPORTED);
-        }
-
-        InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
-        if (!SetupDiGetDeviceInstallParamsW(DeviceInfoSet, DeviceInfoData, &InstallParams))
-            /* Don't process this call, as a parameter is invalid */
-            CanHandle = 0;
-
-        if (CanHandle != 0)
-        {
-            LIST_ENTRY ClassCoInstallersListHead;
-            LIST_ENTRY DeviceCoInstallersListHead;
-            HMODULE ClassInstallerLibrary = NULL;
-            CLASS_INSTALL_PROC ClassInstaller = NULL;
-            COINSTALLER_CONTEXT_DATA Context;
-            PLIST_ENTRY ListEntry;
-            HKEY hKey;
-            DWORD dwRegType, dwLength;
-            DWORD rc = NO_ERROR;
-
-            InitializeListHead(&ClassCoInstallersListHead);
-            InitializeListHead(&DeviceCoInstallersListHead);
-
-            if (CanHandle & DEVICE_COINSTALLER)
-            {
-                hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_QUERY_VALUE);
-                if (hKey != INVALID_HANDLE_VALUE)
-                {
-                    rc = RegQueryValueExW(hKey, REGSTR_VAL_COINSTALLERS_32, NULL, &dwRegType, NULL, &dwLength);
-                    if (rc == ERROR_SUCCESS && dwRegType == REG_MULTI_SZ)
-                    {
-                        LPWSTR KeyBuffer = HeapAlloc(GetProcessHeap(), 0, dwLength);
-                        if (KeyBuffer != NULL)
-                        {
-                            rc = RegQueryValueExW(hKey, REGSTR_VAL_COINSTALLERS_32, NULL, NULL, (LPBYTE)KeyBuffer, &dwLength);
-                            if (rc == ERROR_SUCCESS)
-                            {
-                                LPWSTR ptr;
-                                for (ptr = KeyBuffer; *ptr; ptr += strlenW(ptr) + 1)
-                                {
-                                    /* Add coinstaller to DeviceCoInstallersListHead list */
-                                    struct CoInstallerElement *coinstaller;
-                                    TRACE("Got device coinstaller '%s'\n", debugstr_w(ptr));
-                                    coinstaller = HeapAlloc(GetProcessHeap(), 0, sizeof(struct CoInstallerElement));
-                                    if (!coinstaller)
-                                        continue;
-                                    ZeroMemory(coinstaller, sizeof(struct CoInstallerElement));
-                                    if (GetFunctionPointer(ptr, &coinstaller->Module, (PVOID*)&coinstaller->Function) == ERROR_SUCCESS)
-                                        InsertTailList(&DeviceCoInstallersListHead, &coinstaller->ListEntry);
-                                    else
-                                        HeapFree(GetProcessHeap(), 0, coinstaller);
-                                }
-                            }
-                            HeapFree(GetProcessHeap(), 0, KeyBuffer);
-                        }
-                    }
-                    RegCloseKey(hKey);
-                }
-            }
-            if (CanHandle & CLASS_COINSTALLER)
-            {
-                rc = RegOpenKeyExW(
-                    HKEY_LOCAL_MACHINE,
-                    REGSTR_PATH_CODEVICEINSTALLERS,
-                    0, /* Options */
-                    KEY_QUERY_VALUE,
-                    &hKey);
-                if (rc == ERROR_SUCCESS)
-                {
-                    LPWSTR lpGuidString;
-                    if (UuidToStringW((UUID*)&DeviceInfoData->ClassGuid, &lpGuidString) == RPC_S_OK)
-                    {
-                        rc = RegQueryValueExW(hKey, lpGuidString, NULL, &dwRegType, NULL, &dwLength);
-                        if (rc == ERROR_SUCCESS && dwRegType == REG_MULTI_SZ)
-                        {
-                            LPWSTR KeyBuffer = HeapAlloc(GetProcessHeap(), 0, dwLength);
-                            if (KeyBuffer != NULL)
-                            {
-                                rc = RegQueryValueExW(hKey, lpGuidString, NULL, NULL, (LPBYTE)KeyBuffer, &dwLength);
-                                if (rc == ERROR_SUCCESS)
-                                {
-                                    LPWSTR ptr;
-                                    for (ptr = KeyBuffer; *ptr; ptr += strlenW(ptr) + 1)
-                                    {
-                                        /* Add coinstaller to ClassCoInstallersListHead list */
-                                        struct CoInstallerElement *coinstaller;
-                                        TRACE("Got class coinstaller '%s'\n", debugstr_w(ptr));
-                                        coinstaller = HeapAlloc(GetProcessHeap(), 0, sizeof(struct CoInstallerElement));
-                                        if (!coinstaller)
-                                            continue;
-                                        ZeroMemory(coinstaller, sizeof(struct CoInstallerElement));
-                                        if (GetFunctionPointer(ptr, &coinstaller->Module, (PVOID*)&coinstaller->Function) == ERROR_SUCCESS)
-                                            InsertTailList(&ClassCoInstallersListHead, &coinstaller->ListEntry);
-                                        else
-                                            HeapFree(GetProcessHeap(), 0, coinstaller);
-                                    }
-                                }
-                                HeapFree(GetProcessHeap(), 0, KeyBuffer);
-                            }
-                        }
-                        RpcStringFreeW(&lpGuidString);
-                    }
-                    RegCloseKey(hKey);
-                }
-            }
-            if ((CanHandle & CLASS_INSTALLER) && !(InstallParams.FlagsEx & DI_FLAGSEX_CI_FAILED))
-            {
-                hKey = SetupDiOpenClassRegKey(&DeviceInfoData->ClassGuid, KEY_QUERY_VALUE);
-                if (hKey != INVALID_HANDLE_VALUE)
-                {
-                    rc = RegQueryValueExW(hKey, REGSTR_VAL_INSTALLER_32, NULL, &dwRegType, NULL, &dwLength);
-                    if (rc == ERROR_SUCCESS && dwRegType == REG_SZ)
-                    {
-                        LPWSTR KeyBuffer = HeapAlloc(GetProcessHeap(), 0, dwLength);
-                        if (KeyBuffer != NULL)
-                        {
-                            rc = RegQueryValueExW(hKey, REGSTR_VAL_INSTALLER_32, NULL, NULL, (LPBYTE)KeyBuffer, &dwLength);
-                            if (rc == ERROR_SUCCESS)
-                            {
-                                /* Get ClassInstaller function pointer */
-                                TRACE("Got class installer '%s'\n", debugstr_w(KeyBuffer));
-                                if (GetFunctionPointer(KeyBuffer, &ClassInstallerLibrary, (PVOID*)&ClassInstaller) != ERROR_SUCCESS)
-                                {
-                                    InstallParams.FlagsEx |= DI_FLAGSEX_CI_FAILED;
-                                    SetupDiSetDeviceInstallParamsW(DeviceInfoSet, DeviceInfoData, &InstallParams);
-                                }
-                            }
-                            HeapFree(GetProcessHeap(), 0, KeyBuffer);
-                        }
-                    }
-                    RegCloseKey(hKey);
-                }
-            }
-
-            /* Call Class co-installers */
-            Context.PostProcessing = FALSE;
-            rc = NO_ERROR;
-            ListEntry = ClassCoInstallersListHead.Flink;
-            while (rc == NO_ERROR && ListEntry != &ClassCoInstallersListHead)
-            {
-                struct CoInstallerElement *coinstaller;
-                coinstaller = CONTAINING_RECORD(ListEntry, struct CoInstallerElement, ListEntry);
-                rc = (*coinstaller->Function)(InstallFunction, DeviceInfoSet, DeviceInfoData, &Context);
-                coinstaller->PrivateData = Context.PrivateData;
-                if (rc == ERROR_DI_POSTPROCESSING_REQUIRED)
-                {
-                    coinstaller->DoPostProcessing = TRUE;
-                    rc = NO_ERROR;
-                }
-                ListEntry = ListEntry->Flink;
-            }
-
-            /* Call Device co-installers */
-            ListEntry = DeviceCoInstallersListHead.Flink;
-            while (rc == NO_ERROR && ListEntry != &DeviceCoInstallersListHead)
-            {
-                struct CoInstallerElement *coinstaller;
-                coinstaller = CONTAINING_RECORD(ListEntry, struct CoInstallerElement, ListEntry);
-                rc = (*coinstaller->Function)(InstallFunction, DeviceInfoSet, DeviceInfoData, &Context);
-                coinstaller->PrivateData = Context.PrivateData;
-                if (rc == ERROR_DI_POSTPROCESSING_REQUIRED)
-                {
-                    coinstaller->DoPostProcessing = TRUE;
-                    rc = NO_ERROR;
-                }
-                ListEntry = ListEntry->Flink;
-            }
-
-            /* Call Class installer */
-            if (ClassInstaller)
-            {
-                rc = (*ClassInstaller)(InstallFunction, DeviceInfoSet, DeviceInfoData);
-                FreeFunctionPointer(ClassInstallerLibrary, ClassInstaller);
-            }
-            else
-                rc = ERROR_DI_DO_DEFAULT;
-
-            /* Call default handler */
-            if (rc == ERROR_DI_DO_DEFAULT)
-            {
-                if (DefaultHandler && !(InstallParams.Flags & DI_NODI_DEFAULTACTION))
-                {
-                    if ((*DefaultHandler)(DeviceInfoSet, DeviceInfoData))
-                        rc = NO_ERROR;
-                    else
-                        rc = GetLastError();
-                }
-                else
-                    rc = NO_ERROR;
-            }
-
-            /* Call Class co-installers that required postprocessing */
-            Context.PostProcessing = TRUE;
-            ListEntry = ClassCoInstallersListHead.Flink;
-            while (ListEntry != &ClassCoInstallersListHead)
-            {
-                struct CoInstallerElement *coinstaller;
-                coinstaller = CONTAINING_RECORD(ListEntry, struct CoInstallerElement, ListEntry);
-                if (coinstaller->DoPostProcessing)
-                {
-                    Context.InstallResult = rc;
-                    Context.PrivateData = coinstaller->PrivateData;
-                    rc = (*coinstaller->Function)(InstallFunction, DeviceInfoSet, DeviceInfoData, &Context);
-                }
-                FreeFunctionPointer(coinstaller->Module, coinstaller->Function);
-                ListEntry = ListEntry->Flink;
-            }
-
-            /* Call Device co-installers that required postprocessing */
-            ListEntry = DeviceCoInstallersListHead.Flink;
-            while (ListEntry != &DeviceCoInstallersListHead)
-            {
-                struct CoInstallerElement *coinstaller;
-                coinstaller = CONTAINING_RECORD(ListEntry, struct CoInstallerElement, ListEntry);
-                if (coinstaller->DoPostProcessing)
-                {
-                    Context.InstallResult = rc;
-                    Context.PrivateData = coinstaller->PrivateData;
-                    rc = (*coinstaller->Function)(InstallFunction, DeviceInfoSet, DeviceInfoData, &Context);
-                }
-                FreeFunctionPointer(coinstaller->Module, coinstaller->Function);
-                ListEntry = ListEntry->Flink;
-            }
-
-            /* Free allocated memory */
-            while (!IsListEmpty(&ClassCoInstallersListHead))
-            {
-                ListEntry = RemoveHeadList(&ClassCoInstallersListHead);
-                HeapFree(GetProcessHeap(), 0, CONTAINING_RECORD(ListEntry, struct CoInstallerElement, ListEntry));
-            }
-            while (!IsListEmpty(&DeviceCoInstallersListHead))
-            {
-                ListEntry = RemoveHeadList(&DeviceCoInstallersListHead);
-                HeapFree(GetProcessHeap(), 0, CONTAINING_RECORD(ListEntry, struct CoInstallerElement, ListEntry));
-            }
-
-            ret = (rc == NO_ERROR);
-        }
-    }
-
-    TRACE("Returning %d\n", ret);
-    return ret;
-}
-
-/***********************************************************************
- *             SetupDiGetDeviceInstallParamsA (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiGetDeviceInstallParamsA(
-        HDEVINFO DeviceInfoSet,
-        PSP_DEVINFO_DATA DeviceInfoData,
-        PSP_DEVINSTALL_PARAMS_A DeviceInstallParams)
-{
-    SP_DEVINSTALL_PARAMS_W deviceInstallParamsW;
-    BOOL ret = FALSE;
-
-    TRACE("%p %p %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstallParams);
-
-    if (DeviceInstallParams == NULL)
-        SetLastError(ERROR_INVALID_PARAMETER);
-    else if (DeviceInstallParams->cbSize != sizeof(SP_DEVINSTALL_PARAMS_A))
-        SetLastError(ERROR_INVALID_USER_BUFFER);
-    else
-    {
-        deviceInstallParamsW.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
-        ret = SetupDiGetDeviceInstallParamsW(DeviceInfoSet, DeviceInfoData, &deviceInstallParamsW);
-
-        if (ret)
-        {
-            /* Do W->A conversion */
-            memcpy(
-                DeviceInstallParams,
-                &deviceInstallParamsW,
-                FIELD_OFFSET(SP_DEVINSTALL_PARAMS_W, DriverPath));
-            if (WideCharToMultiByte(CP_ACP, 0, deviceInstallParamsW.DriverPath, -1,
-                DeviceInstallParams->DriverPath, MAX_PATH, NULL, NULL) == 0)
-            {
-                DeviceInstallParams->DriverPath[0] = '\0';
-                ret = FALSE;
-            }
-        }
-    }
-
-    TRACE("Returning %d\n", ret);
-    return ret;
-}
-
-/***********************************************************************
- *             SetupDiGetDeviceInfoListClass  (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiGetDeviceInfoListClass(
-        IN HDEVINFO DeviceInfoSet,
-        OUT LPGUID ClassGuid)
-{
-    struct DeviceInfoSet *list;
-    BOOL ret = FALSE;
-
-    TRACE("%p %p\n", DeviceInfoSet, ClassGuid);
-
-    if (!DeviceInfoSet)
-        SetLastError(ERROR_INVALID_HANDLE);
-    else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-        SetLastError(ERROR_INVALID_HANDLE);
-    else if (IsEqualIID(&list->ClassGuid, &GUID_NULL))
-        SetLastError(ERROR_NO_ASSOCIATED_CLASS);
-    else
-    {
-        memcpy(&ClassGuid, &list->ClassGuid, sizeof(GUID));
-
-        ret = TRUE;
-    }
-
-    TRACE("Returning %d\n", ret);
-    return ret;
-}
-
-/***********************************************************************
- *             SetupDiGetDeviceInstallParamsW (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiGetDeviceInstallParamsW(
-        IN HDEVINFO DeviceInfoSet,
-        IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
-        OUT PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
-{
-    struct DeviceInfoSet *list;
-    BOOL ret = FALSE;
-
-    TRACE("%p %p %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstallParams);
-
-    if (!DeviceInfoSet)
-        SetLastError(ERROR_INVALID_HANDLE);
-    else if ((list = (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 (!DeviceInstallParams)
-        SetLastError(ERROR_INVALID_PARAMETER);
-    else if (DeviceInstallParams->cbSize != sizeof(SP_DEVINSTALL_PARAMS_W))
-        SetLastError(ERROR_INVALID_USER_BUFFER);
-    else
-    {
-        PSP_DEVINSTALL_PARAMS_W Source;
-
-        if (DeviceInfoData)
-            Source = &((struct DeviceInfo *)DeviceInfoData->Reserved)->InstallParams;
-        else
-            Source = &list->InstallParams;
-
-        ret = TRUE;
-
-        _SEH2_TRY
-        {
-            memcpy(DeviceInstallParams, Source, Source->cbSize);
-        }
-        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-            SetLastError(RtlNtStatusToDosError(_SEH2_GetExceptionCode()));
-            ret = FALSE;
-        }
-        _SEH2_END;
-    }
-
-    TRACE("Returning %d\n", ret);
-    return ret;
-}
-
-static BOOL
-CheckDeviceInstallParameters(
-        IN PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
-{
-    DWORD SupportedFlags =
-        DI_NOVCP |                            /* 0x00000008 */
-        DI_DIDCOMPAT |                        /* 0x00000010 */
-        DI_DIDCLASS |                         /* 0x00000020 */
-        DI_NEEDRESTART |                      /* 0x00000080 */
-        DI_NEEDREBOOT |                       /* 0x00000100 */
-        DI_RESOURCEPAGE_ADDED |               /* 0x00002000 */
-        DI_PROPERTIES_CHANGE |                /* 0x00004000 */
-        DI_ENUMSINGLEINF |                    /* 0x00010000 */
-        DI_DONOTCALLCONFIGMG |                /* 0x00020000 */
-        DI_CLASSINSTALLPARAMS |               /* 0x00100000 */
-        DI_NODI_DEFAULTACTION |               /* 0x00200000 */
-        DI_QUIETINSTALL |                     /* 0x00800000 */
-        DI_NOFILECOPY |                       /* 0x01000000 */
-        DI_DRIVERPAGE_ADDED;                  /* 0x04000000 */
-    DWORD SupportedFlagsEx =
-        DI_FLAGSEX_CI_FAILED |                /* 0x00000004 */
-        DI_FLAGSEX_DIDINFOLIST |              /* 0x00000010 */
-        DI_FLAGSEX_DIDCOMPATINFO |            /* 0x00000020 */
-        DI_FLAGSEX_ALLOWEXCLUDEDDRVS |        /* 0x00000800 */
-        DI_FLAGSEX_NO_DRVREG_MODIFY |         /* 0x00008000 */
-        DI_FLAGSEX_INSTALLEDDRIVER;           /* 0x04000000 */
-    BOOL ret = FALSE;
-
-    /* FIXME: add support for more flags */
-
-    /* FIXME: DI_CLASSINSTALLPARAMS flag is not correctly used.
-     * It should be checked before accessing to other values
-     * of the SP_DEVINSTALL_PARAMS structure */
-
-    if (DeviceInstallParams->Flags & ~SupportedFlags)
-    {
-        FIXME("Unknown Flags: 0x%08lx\n", DeviceInstallParams->Flags & ~SupportedFlags);
-        SetLastError(ERROR_INVALID_FLAGS);
-    }
-    else if (DeviceInstallParams->FlagsEx & ~SupportedFlagsEx)
-    {
-        FIXME("Unknown FlagsEx: 0x%08lx\n", DeviceInstallParams->FlagsEx & ~SupportedFlagsEx);
-        SetLastError(ERROR_INVALID_FLAGS);
-    }
-    else if ((DeviceInstallParams->Flags & DI_NOVCP)
-        && (DeviceInstallParams->FileQueue == NULL || DeviceInstallParams->FileQueue == (HSPFILEQ)INVALID_HANDLE_VALUE))
-        SetLastError(ERROR_INVALID_USER_BUFFER);
-    else
-    {
-        /* FIXME: check Reserved field */
-        ret = TRUE;
-    }
-
-    return ret;
-}
-
-/***********************************************************************
- *             SetupDiSetDeviceInstallParamsW (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiSetDeviceInstallParamsW(
-        IN HDEVINFO DeviceInfoSet,
-        IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
-        IN PSP_DEVINSTALL_PARAMS_W DeviceInstallParams)
-{
-    struct DeviceInfoSet *list;
-    BOOL ret = FALSE;
-
-    TRACE("%p %p %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstallParams);
-
-    if (!DeviceInfoSet)
-        SetLastError(ERROR_INVALID_HANDLE);
-    else if ((list = (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 (!DeviceInstallParams)
-        SetLastError(ERROR_INVALID_PARAMETER);
-    else if (DeviceInstallParams->cbSize != sizeof(SP_DEVINSTALL_PARAMS_W))
-        SetLastError(ERROR_INVALID_USER_BUFFER);
-    else if (CheckDeviceInstallParameters(DeviceInstallParams))
-    {
-        PSP_DEVINSTALL_PARAMS_W Destination;
-
-        if (DeviceInfoData)
-            Destination = &((struct DeviceInfo *)DeviceInfoData->Reserved)->InstallParams;
-        else
-            Destination = &list->InstallParams;
-        memcpy(Destination, DeviceInstallParams, DeviceInstallParams->cbSize);
-        ret = TRUE;
-    }
-
-    TRACE("Returning %d\n", ret);
-    return ret;
-}
-
-/***********************************************************************
- *             SetupDiSetDeviceInstallParamsW (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiSetDeviceInstallParamsA(
-        HDEVINFO DeviceInfoSet,
-        PSP_DEVINFO_DATA DeviceInfoData,
-        PSP_DEVINSTALL_PARAMS_A DeviceInstallParams)
-{
-    SP_DEVINSTALL_PARAMS_W deviceInstallParamsW;
-    int len = 0;
-    BOOL ret = FALSE;
-
-    TRACE("%p %p %p\n", DeviceInfoSet, DeviceInfoData, DeviceInstallParams);
-
-    if (DeviceInstallParams == NULL)
-        SetLastError(ERROR_INVALID_PARAMETER);
-    else if (DeviceInstallParams->cbSize < sizeof(SP_DEVINSTALL_PARAMS_A))
-        SetLastError(ERROR_INVALID_USER_BUFFER);
-    else
-    {
-        memcpy(&deviceInstallParamsW, DeviceInstallParams, FIELD_OFFSET(SP_DEVINSTALL_PARAMS_A, DriverPath));
-        deviceInstallParamsW.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
-        len = MultiByteToWideChar(CP_ACP, 0, DeviceInstallParams->DriverPath, -1, NULL, 0);
-        if (!len)
-        {
-            ERR("DrivePath is NULL\n");
-            ret = FALSE;
-        }
-        else
-        {
-            MultiByteToWideChar(CP_ACP, 0, DeviceInstallParams->DriverPath, -1, deviceInstallParamsW.DriverPath, len);
-            ret = SetupDiSetDeviceInstallParamsW(DeviceInfoSet, DeviceInfoData, &deviceInstallParamsW);
-        }
-    }
-
-    TRACE("Returning %d\n", ret);
-    return ret;
-}
-
-static HKEY
-OpenHardwareProfileKey(
-        IN HKEY HKLM,
-        IN DWORD HwProfile,
-        IN DWORD samDesired)
-{
-    HKEY hHWProfilesKey = NULL;
-    HKEY hHWProfileKey = NULL;
-    HKEY ret = INVALID_HANDLE_VALUE;
-    LONG rc;
-
-    rc = RegOpenKeyExW(HKLM,
-                       REGSTR_PATH_HWPROFILES,
-                       0,
-                       READ_CONTROL,
-                       &hHWProfilesKey);
-    if (rc != ERROR_SUCCESS)
-    {
-        SetLastError(rc);
-        goto cleanup;
-    }
-    if (HwProfile == 0)
-    {
-        rc = RegOpenKeyExW(hHWProfilesKey,
-                           REGSTR_KEY_CURRENT,
-                           0,
-                           KEY_CREATE_SUB_KEY,
-                           &hHWProfileKey);
-    }
-    else
-    {
-        WCHAR subKey[5];
-        snprintfW(subKey, 4, InstanceKeyFormat, HwProfile);
-        subKey[4] = '\0';
-        rc = RegOpenKeyExW(hHWProfilesKey,
-                           subKey,
-                           0,
-                           KEY_CREATE_SUB_KEY,
-                           &hHWProfileKey);
-    }
-    if (rc != ERROR_SUCCESS)
-    {
-        SetLastError(rc);
-        goto cleanup;
-    }
-    ret = hHWProfileKey;
-
-cleanup:
-    if (hHWProfilesKey != NULL)
-        RegCloseKey(hHWProfilesKey);
-    if (hHWProfileKey != NULL && hHWProfileKey != ret)
-        RegCloseKey(hHWProfileKey);
-    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)
-{
-    struct DeviceInfoSet *deviceInfoSet;
-    struct DeviceInfo *deviceInfo = (struct DeviceInfo *)DeviceInfoData;
-    BOOL ret = FALSE;
-
-    TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
-
-    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;
-}
-
-
-/***********************************************************************
- *             SetupDiOpenDeviceInfoA (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiOpenDeviceInfoA(
-        IN HDEVINFO DeviceInfoSet,
-        IN PCSTR DeviceInstanceId,
-        IN HWND hwndParent OPTIONAL,
-        IN DWORD OpenFlags,
-        OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
-{
-    LPWSTR DeviceInstanceIdW = NULL;
-    BOOL bResult;
-
-    TRACE("%p %s %p %lx %p\n", DeviceInfoSet, DeviceInstanceId, hwndParent, OpenFlags, DeviceInfoData);
-
-    DeviceInstanceIdW = pSetupMultiByteToUnicode(DeviceInstanceId, CP_ACP);
-    if (DeviceInstanceIdW == NULL)
-        return FALSE;
-
-    bResult = SetupDiOpenDeviceInfoW(DeviceInfoSet,
-        DeviceInstanceIdW, hwndParent, OpenFlags, DeviceInfoData);
-
-    MyFree(DeviceInstanceIdW);
-
-    return bResult;
-}
-
-
-/***********************************************************************
- *             SetupDiOpenDeviceInfoW (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiOpenDeviceInfoW(
-        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;
-    DWORD rc, dwSize;
-    BOOL ret = FALSE;
-
-    TRACE("%p %s %p %lx %p\n",
-        DeviceInfoSet, debugstr_w(DeviceInstanceId),
-        hwndParent, OpenFlags, DeviceInfoData);
-
-    if (OpenFlags & DIOD_CANCEL_REMOVE)
-        FIXME("DIOD_CANCEL_REMOVE flag not implemented\n");
-
-    if (!DeviceInfoSet)
-        SetLastError(ERROR_INVALID_HANDLE);
-    else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-        SetLastError(ERROR_INVALID_HANDLE);
-    else if (!DeviceInstanceId)
-        SetLastError(ERROR_INVALID_PARAMETER);
-    else if (OpenFlags & ~(DIOD_CANCEL_REMOVE | DIOD_INHERIT_CLASSDRVS))
-    {
-        TRACE("Unknown flags: 0x%08lx\n", OpenFlags & ~(DIOD_CANCEL_REMOVE | DIOD_INHERIT_CLASSDRVS));
-        SetLastError(ERROR_INVALID_FLAGS);
-    }
-    else if (DeviceInfoData && DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
-        SetLastError(ERROR_INVALID_USER_BUFFER);
-    else
-    {
-        struct DeviceInfo *deviceInfo = NULL;
-        /* Search if device already exists in DeviceInfoSet.
-         *    If yes, return the existing element
-         *    If no, create a new element using information in registry
-         */
-        PLIST_ENTRY ItemList = list->ListHead.Flink;
-        while (ItemList != &list->ListHead)
-        {
-            deviceInfo = CONTAINING_RECORD(ItemList, struct DeviceInfo, ListEntry);
-            if (!wcscmp(deviceInfo->instanceId, DeviceInstanceId))
-                break;
-            deviceInfo = NULL;
-            ItemList = ItemList->Flink;
-        }
-
-        if (deviceInfo)
-        {
-            /* good one found */
-            ret = TRUE;
-        }
-        else
-        {
-            GUID ClassGUID;
-            WCHAR szClassGuid[MAX_GUID_STRING_LEN];
-
-            /* Open supposed registry key */
-            rc = RegOpenKeyExW(
-                list->HKLM,
-                REGSTR_PATH_SYSTEMENUM,
-                0, /* Options */
-                READ_CONTROL,
-                &hEnumKey);
-            if (rc != ERROR_SUCCESS)
-            {
-                SetLastError(rc);
-                goto cleanup;
-            }
-            rc = RegOpenKeyExW(
-                hEnumKey,
-                DeviceInstanceId,
-                0, /* Options */
-                KEY_QUERY_VALUE,
-                &hKey);
-            RegCloseKey(hEnumKey);
-            if (rc != ERROR_SUCCESS)
-            {
-                if (rc == ERROR_FILE_NOT_FOUND)
-                    rc = ERROR_NO_SUCH_DEVINST;
-                SetLastError(rc);
-                goto cleanup;
-            }
-
-            ClassGUID = GUID_NULL;
-            dwSize = MAX_GUID_STRING_LEN * sizeof(WCHAR);
-
-            if (RegQueryValueExW(hKey,
-                                 REGSTR_VAL_CLASSGUID,
-                                 NULL,
-                                 NULL,
-                                 (LPBYTE)szClassGuid,
-                                 &dwSize) == ERROR_SUCCESS)
-            {
-                szClassGuid[MAX_GUID_STRING_LEN - 2] = UNICODE_NULL;
-
-                /* Convert a string to a ClassGuid */
-                UuidFromStringW(&szClassGuid[1], &ClassGUID);
-            }
-
-            if (!CreateDeviceInfo(list, DeviceInstanceId, &ClassGUID, &deviceInfo))
-                goto cleanup;
-
-            InsertTailList(&list->ListHead, &deviceInfo->ListEntry);
-
-            ret = TRUE;
-        }
-
-        if (ret && deviceInfo && DeviceInfoData)
-        {
-            memcpy(&DeviceInfoData->ClassGuid, &deviceInfo->ClassGuid, sizeof(GUID));
-            DeviceInfoData->DevInst = deviceInfo->dnDevInst;
-            DeviceInfoData->Reserved = (ULONG_PTR)deviceInfo;
-        }
-    }
-
-cleanup:
-    if (hKey != NULL)
-        RegCloseKey(hKey);
-    return ret;
-}
-
-
-/***********************************************************************
- *             SetupDiGetSelectedDevice (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiGetSelectedDevice(
-        IN HDEVINFO DeviceInfoSet,
-        OUT PSP_DEVINFO_DATA DeviceInfoData)
-{
-    struct DeviceInfoSet *list;
-    BOOL ret = FALSE;
-
-    TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
-
-    if (!DeviceInfoSet)
-        SetLastError(ERROR_INVALID_HANDLE);
-    else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-        SetLastError(ERROR_INVALID_HANDLE);
-    else if (list->SelectedDevice == NULL)
-        SetLastError(ERROR_NO_DEVICE_SELECTED);
-    else if (!DeviceInfoData)
-        SetLastError(ERROR_INVALID_PARAMETER);
-    else if (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
-        SetLastError(ERROR_INVALID_USER_BUFFER);
-    else
-    {
-        memcpy(&DeviceInfoData->ClassGuid,
-            &list->SelectedDevice->ClassGuid,
-            sizeof(GUID));
-        DeviceInfoData->DevInst = list->SelectedDevice->dnDevInst;
-        DeviceInfoData->Reserved = (ULONG_PTR)list->SelectedDevice;
-        ret = TRUE;
-    }
-
-    TRACE("Returning %d\n", ret);
-    return ret;
-}
-
-
-/***********************************************************************
- *             SetupDiSetSelectedDevice (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiSetSelectedDevice(
-        IN HDEVINFO DeviceInfoSet,
-        IN PSP_DEVINFO_DATA DeviceInfoData)
-{
-    struct DeviceInfoSet *list;
-    BOOL ret = FALSE;
-
-    TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
-
-    if (!DeviceInfoSet)
-        SetLastError(ERROR_INVALID_HANDLE);
-    else if ((list = (struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-        SetLastError(ERROR_INVALID_HANDLE);
-    else if (!DeviceInfoData)
-        SetLastError(ERROR_INVALID_PARAMETER);
-    else if (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
-        SetLastError(ERROR_INVALID_USER_BUFFER);
-    else if (DeviceInfoData->Reserved == 0)
-        SetLastError(ERROR_INVALID_USER_BUFFER);
-    else
-    {
-        list->SelectedDevice = (struct DeviceInfo *)DeviceInfoData->Reserved;
-        ret = TRUE;
-    }
-
-    TRACE("Returning %d\n", ret);
-    return ret;
-}
-
-
-/* Return the current hardware profile id, or -1 if error */
-static DWORD
-SETUPAPI_GetCurrentHwProfile(
-        IN HDEVINFO DeviceInfoSet)
-{
-    HKEY hKey = NULL;
-    DWORD dwRegType, dwLength;
-    DWORD hwProfile;
-    LONG rc;
-    DWORD ret = (DWORD)-1;
-
-    rc = RegOpenKeyExW(((struct DeviceInfoSet *)DeviceInfoSet)->HKLM,
-                       REGSTR_PATH_IDCONFIGDB,
-                       0, /* Options */
-                       KEY_QUERY_VALUE,
-                       &hKey);
-    if (rc != ERROR_SUCCESS)
-    {
-        SetLastError(rc);
-        goto cleanup;
-    }
-
-    dwLength = sizeof(DWORD);
-    rc = RegQueryValueExW(hKey,
-                          REGSTR_VAL_CURRENTCONFIG,
-                          NULL,
-                          &dwRegType,
-                          (LPBYTE)&hwProfile, &dwLength);
-    if (rc != ERROR_SUCCESS)
-    {
-        SetLastError(rc);
-        goto cleanup;
-    }
-    else if (dwRegType != REG_DWORD || dwLength != sizeof(DWORD))
-    {
-        SetLastError(ERROR_GEN_FAILURE);
-        goto cleanup;
-    }
-
-    ret = hwProfile;
-
-cleanup:
-    if (hKey != NULL)
-        RegCloseKey(hKey);
-
-    return ret;
-}
-
-static BOOL
-ResetDevice(
-        IN HDEVINFO DeviceInfoSet,
-        IN PSP_DEVINFO_DATA DeviceInfoData)
-{
-#ifndef __WINESRC__
-    struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
-    struct DeviceInfo *deviceInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
-    CONFIGRET cr;
-
-    cr = CM_Enable_DevNode_Ex(deviceInfo->dnDevInst, 0, set->hMachine);
-    if (cr != CR_SUCCESS)
-    {
-        SetLastError(GetErrorCodeFromCrCode(cr));
-        return FALSE;
-    }
-
-    return TRUE;
-#else
-    FIXME("Stub: ResetDevice(%p %p)\n", DeviceInfoSet, DeviceInfoData);
-    return TRUE;
-#endif
-}
-
-static BOOL StopDevice(
-        IN HDEVINFO DeviceInfoSet,
-        IN PSP_DEVINFO_DATA DeviceInfoData)
-{
-    FIXME("Stub: StopDevice(%p %p)\n", DeviceInfoSet, DeviceInfoData);
-    return TRUE;
-}
-
-/***********************************************************************
- *             SetupDiChangeState (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiChangeState(
-        IN HDEVINFO DeviceInfoSet,
-        IN OUT PSP_DEVINFO_DATA DeviceInfoData)
-{
-    PSP_PROPCHANGE_PARAMS PropChange;
-    HKEY hKey = INVALID_HANDLE_VALUE;
-    LPCWSTR RegistryValueName;
-    DWORD dwConfigFlags, dwLength, dwRegType;
-    LONG rc;
-    BOOL ret = FALSE;
-
-    TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
-
-    if (!DeviceInfoData)
-        PropChange = ((struct DeviceInfoSet *)DeviceInfoSet)->ClassInstallParams.PropChangeParams;
-    else
-        PropChange = ((struct DeviceInfo *)DeviceInfoData->Reserved)->ClassInstallParams.PropChangeParams;
-    if (!PropChange)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        goto cleanup;
-    }
-
-    if (PropChange->Scope == DICS_FLAG_GLOBAL)
-        RegistryValueName = REGSTR_VAL_CONFIGFLAGS;
-    else
-        RegistryValueName = REGSTR_VAL_CSCONFIGFLAGS;
-
-    switch (PropChange->StateChange)
-    {
-        case DICS_ENABLE:
-        case DICS_DISABLE:
-        {
-            /* Enable/disable device in registry */
-            hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, PropChange->Scope, PropChange->HwProfile, DIREG_DEV, KEY_QUERY_VALUE | KEY_SET_VALUE);
-            if (hKey == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND)
-                hKey = SetupDiCreateDevRegKeyW(DeviceInfoSet, DeviceInfoData, PropChange->Scope, PropChange->HwProfile, DIREG_DEV, NULL, NULL);
-            if (hKey == INVALID_HANDLE_VALUE)
-                break;
-            dwLength = sizeof(DWORD);
-            rc = RegQueryValueExW(
-                hKey,
-                RegistryValueName,
-                NULL,
-                &dwRegType,
-                (LPBYTE)&dwConfigFlags, &dwLength);
-            if (rc == ERROR_FILE_NOT_FOUND)
-                dwConfigFlags = 0;
-            else if (rc != ERROR_SUCCESS)
-            {
-                SetLastError(rc);
-                goto cleanup;
-            }
-            else if (dwRegType != REG_DWORD || dwLength != sizeof(DWORD))
-            {
-                SetLastError(ERROR_GEN_FAILURE);
-                goto cleanup;
-            }
-            if (PropChange->StateChange == DICS_ENABLE)
-                dwConfigFlags &= ~(PropChange->Scope == DICS_FLAG_GLOBAL ? CONFIGFLAG_DISABLED : CSCONFIGFLAG_DISABLED);
-            else
-                dwConfigFlags |= (PropChange->Scope == DICS_FLAG_GLOBAL ? CONFIGFLAG_DISABLED : CSCONFIGFLAG_DISABLED);
-            rc = RegSetValueExW(
-                hKey,
-                RegistryValueName,
-                0,
-                REG_DWORD,
-                (LPBYTE)&dwConfigFlags, sizeof(DWORD));
-            if (rc != ERROR_SUCCESS)
-            {
-                SetLastError(rc);
-                goto cleanup;
-            }
-
-            /* Enable/disable device if needed */
-            if (PropChange->Scope == DICS_FLAG_GLOBAL
-                || PropChange->HwProfile == 0
-                || PropChange->HwProfile == SETUPAPI_GetCurrentHwProfile(DeviceInfoSet))
-            {
-                if (PropChange->StateChange == DICS_ENABLE)
-                    ret = ResetDevice(DeviceInfoSet, DeviceInfoData);
-                else
-                    ret = StopDevice(DeviceInfoSet, DeviceInfoData);
-            }
-            else
-                ret = TRUE;
-            break;
-        }
-        case DICS_PROPCHANGE:
-        {
-            ret = ResetDevice(DeviceInfoSet, DeviceInfoData);
-            break;
-        }
-        default:
-        {
-            ERR("Unknown StateChange 0x%lx\n", PropChange->StateChange);
-            SetLastError(ERROR_NOT_SUPPORTED);
-        }
-    }
-
-cleanup:
-    if (hKey != INVALID_HANDLE_VALUE)
-        RegCloseKey(hKey);
-
-    TRACE("Returning %d\n", ret);
-    return ret;
-}
-
-/***********************************************************************
- *             SetupDiSelectDevice (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiSelectDevice(
-        IN HDEVINFO DeviceInfoSet,
-        IN OUT PSP_DEVINFO_DATA DeviceInfoData OPTIONAL)
-{
-    FIXME("%p %p\n", DeviceInfoSet, DeviceInfoData);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
-}
-
-
-/***********************************************************************
- *             SetupDiRegisterCoDeviceInstallers (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiRegisterCoDeviceInstallers(
-        IN HDEVINFO DeviceInfoSet,
-        IN PSP_DEVINFO_DATA DeviceInfoData)
-{
-    BOOL ret = FALSE; /* Return value */
-
-    TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
-
-    if (!DeviceInfoSet)
-        SetLastError(ERROR_INVALID_PARAMETER);
-    else if (DeviceInfoSet == (HDEVINFO)INVALID_HANDLE_VALUE)
-        SetLastError(ERROR_INVALID_HANDLE);
-    else if (((struct DeviceInfoSet *)DeviceInfoSet)->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-        SetLastError(ERROR_INVALID_HANDLE);
-    else if (!DeviceInfoData)
-        SetLastError(ERROR_INVALID_PARAMETER);
-    else if (DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA))
-        SetLastError(ERROR_INVALID_USER_BUFFER);
-    else
-    {
-        SP_DEVINSTALL_PARAMS_W InstallParams;
-        struct DriverInfoElement *SelectedDriver;
-        BOOL Result;
-        DWORD DoAction;
-        WCHAR SectionName[MAX_PATH];
-        DWORD SectionNameLength = 0;
-        HKEY hKey = INVALID_HANDLE_VALUE;
-        PVOID Context = NULL;
-
-        InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
-        Result = SetupDiGetDeviceInstallParamsW(DeviceInfoSet, DeviceInfoData, &InstallParams);
-        if (!Result)
-            goto cleanup;
-
-        SelectedDriver = (struct DriverInfoElement *)InstallParams.Reserved;
-        if (SelectedDriver == NULL)
-        {
-            SetLastError(ERROR_NO_DRIVER_SELECTED);
-            goto cleanup;
-        }
-
-        /* Get .CoInstallers section name */
-        Result = SetupDiGetActualSectionToInstallW(
-            SelectedDriver->InfFileDetails->hInf,
-            SelectedDriver->Details.SectionName,
-            SectionName, MAX_PATH, &SectionNameLength, NULL);
-        if (!Result || SectionNameLength > MAX_PATH - strlenW(DotCoInstallers) - 1)
-            goto cleanup;
-        lstrcatW(SectionName, DotCoInstallers);
-
-        /* Open/Create driver key information */
-#if _WIN32_WINNT >= 0x502
-        hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ | KEY_WRITE);
-#else
-        hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_ALL_ACCESS);
-#endif
-        if (hKey == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND)
-            hKey = SetupDiCreateDevRegKeyW(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, NULL, NULL);
-        if (hKey == INVALID_HANDLE_VALUE)
-            goto cleanup;
-
-        /* Install .CoInstallers section */
-        DoAction = SPINST_REGISTRY;
-        if (!(InstallParams.Flags & DI_NOFILECOPY))
-        {
-            DoAction |= SPINST_FILES;
-            Context = SetupInitDefaultQueueCallback(InstallParams.hwndParent);
-            if (!Context)
-                goto cleanup;
-        }
-        Result = SetupInstallFromInfSectionW(InstallParams.hwndParent,
-            SelectedDriver->InfFileDetails->hInf, SectionName,
-            DoAction, hKey, SelectedDriver->InfFileDetails->DirectoryName, SP_COPY_NEWER,
-            SetupDefaultQueueCallbackW, Context,
-            DeviceInfoSet, DeviceInfoData);
-        if (!Result)
-            goto cleanup;
-
-        ret = TRUE;
-
-cleanup:
-        if (Context)
-            SetupTermDefaultQueueCallback(Context);
-        if (hKey != INVALID_HANDLE_VALUE)
-            RegCloseKey(hKey);
-    }
-
-    TRACE("Returning %d\n", ret);
-    return ret;
-}
-
-static BOOL
-InfIsFromOEMLocation(
-        IN PCWSTR FullName,
-        OUT LPBOOL IsOEMLocation)
-{
-    PWCHAR last;
-
-    last = strrchrW(FullName, '\\');
-    if (!last)
-    {
-        /* No directory specified */
-        *IsOEMLocation = FALSE;
-    }
-    else
-    {
-        LPWSTR Windir;
-        UINT ret;
-
-        Windir = MyMalloc((MAX_PATH + 1 + strlenW(InfDirectory)) * sizeof(WCHAR));
-        if (!Windir)
-        {
-            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-            return FALSE;
-        }
-
-        ret = GetSystemWindowsDirectoryW(Windir, MAX_PATH);
-        if (ret == 0 || ret > MAX_PATH)
-        {
-            MyFree(Windir);
-            SetLastError(ERROR_GEN_FAILURE);
-            return FALSE;
-        }
-        if (*Windir && Windir[strlenW(Windir) - 1] != '\\')
-            strcatW(Windir, BackSlash);
-        strcatW(Windir, InfDirectory);
-
-        if (strncmpiW(FullName, Windir, last - FullName) == 0)
-        {
-            /* The path is %SYSTEMROOT%\Inf */
-            *IsOEMLocation = FALSE;
-        }
-        else
-        {
-            /* The file is in another place */
-            *IsOEMLocation = TRUE;
-        }
-        MyFree(Windir);
-    }
-    return TRUE;
-}
-
-/***********************************************************************
- *             SetupDiInstallDevice (SETUPAPI.@)
- */
-BOOL WINAPI
-SetupDiInstallDevice(
-        IN HDEVINFO DeviceInfoSet,
-        IN OUT PSP_DEVINFO_DATA DeviceInfoData)
-{
-    SP_DEVINSTALL_PARAMS_W InstallParams;
-    struct DriverInfoElement *SelectedDriver;
-    SYSTEMTIME DriverDate;
-    WCHAR SectionName[MAX_PATH];
-    WCHAR Buffer[32];
-    DWORD SectionNameLength = 0;
-    BOOL Result = FALSE;
-    ULONG DoAction;
-    DWORD RequiredSize;
-    LPWSTR pSectionName = NULL;
-    WCHAR ClassName[MAX_CLASS_NAME_LEN];
-    GUID ClassGuid;
-    LPWSTR lpGuidString = NULL, lpFullGuidString = NULL;
-    BOOL RebootRequired = FALSE;
-    HKEY hKey = INVALID_HANDLE_VALUE;
-    BOOL NeedtoCopyFile;
-    LARGE_INTEGER fullVersion;
-    LONG rc;
-    PVOID Context = NULL;
-    BOOL ret = FALSE; /* Return value */
-
-    TRACE("%p %p\n", DeviceInfoSet, DeviceInfoData);
-
-    if (!DeviceInfoSet)
-        SetLastError(ERROR_INVALID_PARAMETER);
-    else if (DeviceInfoSet == (HDEVINFO)INVALID_HANDLE_VALUE)
-        SetLastError(ERROR_INVALID_HANDLE);
-    else if (((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
-        Result = TRUE;
-
-    if (!Result)
-    {
-        /* One parameter is bad */
-        goto cleanup;
-    }
-
-    InstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
-    Result = SetupDiGetDeviceInstallParamsW(DeviceInfoSet, DeviceInfoData, &InstallParams);
-    if (!Result)
-        goto cleanup;
-
-    if (InstallParams.FlagsEx & DI_FLAGSEX_SETFAILEDINSTALL)
-    {
-        /* Set FAILEDINSTALL in ConfigFlags registry value */
-        DWORD ConfigFlags, regType;
-        Result = SetupDiGetDeviceRegistryPropertyW(
-            DeviceInfoSet,
-            DeviceInfoData,
-            SPDRP_CONFIGFLAGS,
-            &regType,
-            (PBYTE)&ConfigFlags,
-            sizeof(ConfigFlags),
-            NULL);
-        if (!Result || regType != REG_DWORD)
-        {
-            SetLastError(ERROR_GEN_FAILURE);
-            goto cleanup;
-        }
-        ConfigFlags |= DNF_DISABLED;
-        Result = SetupDiSetDeviceRegistryPropertyW(
-            DeviceInfoSet,
-            DeviceInfoData,
-            SPDRP_CONFIGFLAGS,
-            (PBYTE)&ConfigFlags,
-            sizeof(ConfigFlags));
-        if (!Result)
-        {
-            SetLastError(ERROR_GEN_FAILURE);
-            goto cleanup;
-        }
-
-        ret = TRUE;
-        goto cleanup;
-    }
-
-    SelectedDriver = (struct DriverInfoElement *)InstallParams.Reserved;
-    if (SelectedDriver == NULL)
-    {
-        SetLastError(ERROR_NO_DRIVER_SELECTED);
-        goto cleanup;
-    }
-
-    FileTimeToSystemTime(&SelectedDriver->Info.DriverDate, &DriverDate);
-
-    Result = SetupDiGetActualSectionToInstallW(
-        SelectedDriver->InfFileDetails->hInf,
-        SelectedDriver->Details.SectionName,
-        SectionName, MAX_PATH, &SectionNameLength, NULL);
-    if (!Result || SectionNameLength > MAX_PATH - strlenW(DotServices))
-        goto cleanup;
-    pSectionName = &SectionName[strlenW(SectionName)];
-
-    /* Get information from [Version] section */
-    if (!SetupDiGetINFClassW(SelectedDriver->Details.InfFileName, &ClassGuid, ClassName, MAX_CLASS_NAME_LEN, &RequiredSize))
-        goto cleanup;
-    /* Format ClassGuid to a string */
-    if (UuidToStringW((UUID*)&ClassGuid, &lpGuidString) != RPC_S_OK)
-        goto cleanup;
-    RequiredSize = lstrlenW(lpGuidString);
-    lpFullGuidString = HeapAlloc(GetProcessHeap(), 0, (RequiredSize + 3) * sizeof(WCHAR));
-    if (!lpFullGuidString)
-    {
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        goto cleanup;
-    }
-    lpFullGuidString[0] = '{';
-    memcpy(&lpFullGuidString[1], lpGuidString, RequiredSize * sizeof(WCHAR));
-    lpFullGuidString[RequiredSize + 1] = '}';
-    lpFullGuidString[RequiredSize + 2] = '\0';
-
-    /* Copy .inf file to Inf\ directory (if needed) */
-    Result = InfIsFromOEMLocation(SelectedDriver->Details.InfFileName, &NeedtoCopyFile);
-    if (!Result)
-        goto cleanup;
-    if (NeedtoCopyFile)
-    {
-        WCHAR NewFileName[MAX_PATH];
-        struct InfFileDetails *newInfFileDetails;
-        Result = SetupCopyOEMInfW(
-            SelectedDriver->Details.InfFileName,
-            NULL,
-            SPOST_NONE,
-            SP_COPY_NOOVERWRITE,
-            NewFileName, MAX_PATH,
-            NULL,
-            NULL);
-        if (!Result && GetLastError() != ERROR_FILE_EXISTS)
-            goto cleanup;
-        /* Create a new struct InfFileDetails, and set it to
-         * SelectedDriver->InfFileDetails, to release use of
-         * current InfFile */
-        newInfFileDetails = CreateInfFileDetails(NewFileName);
-        if (!newInfFileDetails)
-            goto cleanup;
-        DereferenceInfFile(SelectedDriver->InfFileDetails);
-        SelectedDriver->InfFileDetails = newInfFileDetails;
-        strcpyW(SelectedDriver->Details.InfFileName, NewFileName);
-    }
-
-    /* Open/Create driver key information */
-#if _WIN32_WINNT >= 0x502
-    hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ | KEY_WRITE);
-#else
-    hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_ALL_ACCESS);
-#endif
-    if (hKey == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND)
-        hKey = SetupDiCreateDevRegKeyW(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, NULL, NULL);
-    if (hKey == INVALID_HANDLE_VALUE)
-        goto cleanup;
-
-    /* Install main section */
-    DoAction = 0;
-    if (!(InstallParams.FlagsEx & DI_FLAGSEX_NO_DRVREG_MODIFY))
-        DoAction |= SPINST_REGISTRY;
-    if (!(InstallParams.Flags & DI_NOFILECOPY))
-    {
-        DoAction |= SPINST_FILES;
-        Context = SetupInitDefaultQueueCallback(InstallParams.hwndParent);
-        if (!Context)
-            goto cleanup;
-    }
-    *pSectionName = '\0';
-    Result = SetupInstallFromInfSectionW(InstallParams.hwndParent,
-        SelectedDriver->InfFileDetails->hInf, SectionName,
-        DoAction, hKey, SelectedDriver->InfFileDetails->DirectoryName, SP_COPY_NEWER,
-        SetupDefaultQueueCallbackW, Context,
-        DeviceInfoSet, DeviceInfoData);
-    if (!Result)
-        goto cleanup;
-    InstallParams.Flags |= DI_NOFILECOPY;
-    SetupDiSetDeviceInstallParamsW(DeviceInfoSet, DeviceInfoData, &InstallParams);
-
-    /* Write information to driver key */
-    *pSectionName = UNICODE_NULL;
-    memcpy(&fullVersion, &SelectedDriver->Info.DriverVersion, sizeof(LARGE_INTEGER));
-    TRACE("Write information to driver key\n");
-    TRACE("DriverDate      : '%u-%u-%u'\n", DriverDate.wMonth, DriverDate.wDay, DriverDate.wYear);
-    TRACE("DriverDesc      : '%s'\n", debugstr_w(SelectedDriver->Info.Description));
-    TRACE("DriverVersion   : '%ld.%ld.%lu.%ld'\n", fullVersion.HighPart >> 16, fullVersion.HighPart & 0xffff, fullVersion.LowPart >> 16, fullVersion.LowPart & 0xffff);
-    TRACE("InfPath         : '%s'\n", debugstr_w(SelectedDriver->InfFileDetails->FileName));
-    TRACE("InfSection      : '%s'\n", debugstr_w(SelectedDriver->Details.SectionName));
-    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));
-    sprintfW(Buffer, DateFormat, DriverDate.wMonth, DriverDate.wDay, DriverDate.wYear);
-    rc = RegSetValueExW(hKey, REGSTR_DRIVER_DATE, 0, REG_SZ, (const BYTE *)Buffer, (strlenW(Buffer) + 1) * sizeof(WCHAR));
-    if (rc == ERROR_SUCCESS)
-        rc = RegSetValueExW(hKey, REGSTR_DRIVER_DATE_DATA, 0, REG_BINARY, (const BYTE *)&SelectedDriver->Info.DriverDate, sizeof(FILETIME));
-    if (rc == ERROR_SUCCESS)
-        rc = RegSetValueExW(hKey, REGSTR_VAL_DRVDESC, 0, REG_SZ, (const BYTE *)SelectedDriver->Info.Description, (strlenW(SelectedDriver->Info.Description) + 1) * sizeof(WCHAR));
-    if (rc == ERROR_SUCCESS)
-    {
-        sprintfW(Buffer, VersionFormat, fullVersion.HighPart >> 16, fullVersion.HighPart & 0xffff, fullVersion.LowPart >> 16, fullVersion.LowPart & 0xffff);
-        rc = RegSetValueExW(hKey, REGSTR_DRIVER_VERSION, 0, REG_SZ, (const BYTE *)Buffer, (strlenW(Buffer) + 1) * sizeof(WCHAR));
-    }
-    if (rc == ERROR_SUCCESS)
-        rc = RegSetValueExW(hKey, REGSTR_VAL_INFPATH, 0, REG_SZ, (const BYTE *)SelectedDriver->InfFileDetails->FileName, (strlenW(SelectedDriver->InfFileDetails->FileName) + 1) * sizeof(WCHAR));
-    if (rc == ERROR_SUCCESS)
-        rc = RegSetValueExW(hKey, REGSTR_VAL_INFSECTION, 0, REG_SZ, (const BYTE *)SelectedDriver->Details.SectionName, (strlenW(SelectedDriver->Details.SectionName) + 1) * sizeof(WCHAR));
-    if (rc == ERROR_SUCCESS)
-        rc = RegSetValueExW(hKey, REGSTR_VAL_INFSECTIONEXT, 0, REG_SZ, (const BYTE *)&SectionName[strlenW(SelectedDriver->Details.SectionName)], (strlenW(SectionName) - strlenW(SelectedDriver->Details.SectionName) + 1) * sizeof(WCHAR));
-    if (rc == ERROR_SUCCESS)
-        rc = RegSetValueExW(hKey, REGSTR_VAL_MATCHINGDEVID, 0, REG_SZ, (const BYTE *)SelectedDriver->MatchingId, (strlenW(SelectedDriver->MatchingId) + 1) * sizeof(WCHAR));
-    if (rc == ERROR_SUCCESS)
-        rc = RegSetValueExW(hKey, REGSTR_VAL_PROVIDER_NAME, 0, REG_SZ, (const BYTE *)SelectedDriver->Info.ProviderName, (strlenW(SelectedDriver->Info.ProviderName) + 1) * sizeof(WCHAR));
-    if (rc != ERROR_SUCCESS)
-    {
-       SetLastError(rc);
-       goto cleanup;
-    }
-    RegCloseKey(hKey);
-    hKey = INVALID_HANDLE_VALUE;
-
-    /* FIXME: Process .LogConfigOverride section */
-
-    /* Install .Services section */
-    strcpyW(pSectionName, DotServices);
-    Result = SetupInstallServicesFromInfSectionExW(
-        SelectedDriver->InfFileDetails->hInf,
-        SectionName,
-        0,
-        DeviceInfoSet,
-        DeviceInfoData,
-        NULL,
-        NULL);
-    if (!Result)
-        goto cleanup;
-    if (GetLastError() == ERROR_SUCCESS_REBOOT_REQUIRED)
-        RebootRequired = TRUE;
-
-    /* Open device registry key */
-    hKey = SetupDiOpenDevRegKey(DeviceInfoSet, DeviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_SET_VALUE);
-    if (hKey == INVALID_HANDLE_VALUE)
-        goto cleanup;
-
-    /* Install .HW section */
-    DoAction = 0;
-    if (!(InstallParams.FlagsEx & DI_FLAGSEX_NO_DRVREG_MODIFY))
-        DoAction |= SPINST_REGISTRY;
-    strcpyW(pSectionName, DotHW);
-    Result = SetupInstallFromInfSectionW(InstallParams.hwndParent,
-        SelectedDriver->InfFileDetails->hInf, SectionName,
-        DoAction, hKey, NULL, 0,
-        NULL, NULL,
-        DeviceInfoSet, DeviceInfoData);
-    if (!Result)
-        goto cleanup;
-
-    /* Write information to enum key */
-    TRACE("Write information to enum key\n");
-    TRACE("Class           : '%s'\n", debugstr_w(ClassName));
-    TRACE("ClassGUID       : '%s'\n", debugstr_w(lpFullGuidString));
-    TRACE("DeviceDesc      : '%s'\n", debugstr_w(SelectedDriver->Info.Description));
-    TRACE("Mfg             : '%s'\n", debugstr_w(SelectedDriver->Info.MfgName));
-    rc = RegSetValueExW(hKey, REGSTR_VAL_CLASS, 0, REG_SZ, (const BYTE *)ClassName, (strlenW(ClassName) + 1) * sizeof(WCHAR));
-    if (rc == ERROR_SUCCESS)
-        rc = RegSetValueExW(hKey, REGSTR_VAL_CLASSGUID, 0, REG_SZ, (const BYTE *)lpFullGuidString, (strlenW(lpFullGuidString) + 1) * sizeof(WCHAR));
-    if (rc == ERROR_SUCCESS)
-        rc = RegSetValueExW(hKey, REGSTR_VAL_DEVDESC, 0, REG_SZ, (const BYTE *)SelectedDriver->Info.Description, (strlenW(SelectedDriver->Info.Description) + 1) * sizeof(WCHAR));
-    if (rc == ERROR_SUCCESS)
-        rc = RegSetValueExW(hKey, REGSTR_VAL_MFG, 0, REG_SZ, (const BYTE *)SelectedDriver->Info.MfgName, (strlenW(SelectedDriver->Info.MfgName) + 1) * sizeof(WCHAR));
-    if (rc != ERROR_SUCCESS)
-    {
-       SetLastError(rc);
-       goto cleanup;
-    }
-
-    /* Start the device */
-    if (!RebootRequired && !(InstallParams.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT | DI_DONOTCALLCONFIGMG)))
-        ret = ResetDevice(DeviceInfoSet, DeviceInfoData);
-    else
-        ret = TRUE;
-
-cleanup:
-    /* End of installation */
-    if (hKey != INVALID_HANDLE_VALUE)
-        RegCloseKey(hKey);
-    if (lpGuidString)
-        RpcStringFreeW(&lpGuidString);
-    HeapFree(GetProcessHeap(), 0, lpFullGuidString);
-    if (Context)
-        SetupTermDefaultQueueCallback(Context);
-    TRACE("Returning %d\n", ret);
-    return ret;
-}
-
-static HKEY SETUPDI_OpenDevKey(HKEY RootKey, struct DeviceInfo *devInfo, REGSAM samDesired)
-{
-    HKEY enumKey, key = INVALID_HANDLE_VALUE;
-    LONG l;
-
-    l = RegOpenKeyExW(RootKey, REGSTR_PATH_SYSTEMENUM, 0, READ_CONTROL, &enumKey);
-    if (!l)
-    {
-        l = RegOpenKeyExW(enumKey, devInfo->instanceId, 0, samDesired, &key);
-        RegCloseKey(enumKey);
-    }
-    if (l)
-        SetLastError(l);
-    return key;
-}
-
-static HKEY SETUPDI_OpenDrvKey(HKEY RootKey, struct DeviceInfo *devInfo, REGSAM samDesired)
-{
-    LPWSTR DriverKey = NULL;
-    DWORD dwLength = 0;
-    DWORD dwRegType;
-    DWORD rc;
-    HKEY hEnumKey = NULL;
-    HKEY hKey = NULL;
-    HKEY key = INVALID_HANDLE_VALUE;
-
-    hKey = SETUPDI_OpenDevKey(RootKey, devInfo, KEY_QUERY_VALUE);
-    if (hKey == INVALID_HANDLE_VALUE)
-        goto cleanup;
-    /* Read the 'Driver' key */
-    rc = RegQueryValueExW(hKey, REGSTR_VAL_DRIVER, NULL, &dwRegType, NULL, &dwLength);
-    if (rc != ERROR_SUCCESS)
-    {
-        SetLastError(rc);
-        goto cleanup;
-    }
-    else if (dwRegType != REG_SZ)
-    {
-        SetLastError(ERROR_GEN_FAILURE);
-        goto cleanup;
-    }
-    DriverKey = HeapAlloc(GetProcessHeap(), 0, dwLength);
-    if (!DriverKey)
-    {
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        goto cleanup;
-    }
-    rc = RegQueryValueExW(hKey, REGSTR_VAL_DRIVER, NULL, &dwRegType, (LPBYTE)DriverKey, &dwLength);
-    if (rc != ERROR_SUCCESS)
-    {
-        SetLastError(rc);
-        goto cleanup;
-    }
-    RegCloseKey(hKey);
-    hKey = NULL;
-    /* Need to open the driver key */
-    rc = RegOpenKeyExW(
-        RootKey,
-        REGSTR_PATH_CLASS_NT,
-        0, /* Options */
-        READ_CONTROL,
-        &hEnumKey);
-    if (rc != ERROR_SUCCESS)
-    {
-        SetLastError(rc);
-        goto cleanup;
-    }
-    rc = RegOpenKeyExW(
-        hEnumKey,
-        DriverKey,
-        0, /* Options */
-        samDesired,
-        &hKey);
-    if (rc != ERROR_SUCCESS)
-    {
-        SetLastError(rc);
-        goto cleanup;
-    }
-    key = hKey;
-
-cleanup:
-    if (hEnumKey != NULL)
-        RegCloseKey(hEnumKey);
-    if (hKey != NULL && hKey != key)
-        RegCloseKey(hKey);
-    if (DriverKey)
-        HeapFree(GetProcessHeap(), 0, DriverKey);
-    return key;
-}
-
-/***********************************************************************
- *             SetupDiOpenDevRegKey (SETUPAPI.@)
- */
-HKEY WINAPI SetupDiOpenDevRegKey(
-        HDEVINFO DeviceInfoSet,
-        PSP_DEVINFO_DATA DeviceInfoData,
-        DWORD Scope,
-        DWORD HwProfile,
-        DWORD KeyType,
-        REGSAM samDesired)
-{
-    struct DeviceInfoSet *set = DeviceInfoSet;
-    struct DeviceInfo *devInfo;
-    HKEY key = INVALID_HANDLE_VALUE;
-    HKEY RootKey;
-
-    TRACE("%p %p %d %d %d %x\n", DeviceInfoSet, DeviceInfoData,
-          Scope, HwProfile, KeyType, samDesired);
-
-    if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return INVALID_HANDLE_VALUE;
-    }
-    if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return INVALID_HANDLE_VALUE;
-    }
-    if (!DeviceInfoData || DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)
-            || !DeviceInfoData->Reserved)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return INVALID_HANDLE_VALUE;
-    }
-    if (Scope != DICS_FLAG_GLOBAL && Scope != DICS_FLAG_CONFIGSPECIFIC)
-    {
-        SetLastError(ERROR_INVALID_FLAGS);
-        return INVALID_HANDLE_VALUE;
-    }
-    if (KeyType != DIREG_DEV && KeyType != DIREG_DRV)
-    {
-        SetLastError(ERROR_INVALID_FLAGS);
-        return INVALID_HANDLE_VALUE;
-    }
-    devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
-    if (devInfo->set != set)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return INVALID_HANDLE_VALUE;
-    }
-    if (Scope != DICS_FLAG_GLOBAL)
-    {
-        RootKey = OpenHardwareProfileKey(set->HKLM, HwProfile, 0);
-        if (RootKey == INVALID_HANDLE_VALUE)
-            return INVALID_HANDLE_VALUE;
-    }
-    else
-        RootKey = set->HKLM;
-    switch (KeyType)
-    {
-        case DIREG_DEV:
-            key = SETUPDI_OpenDevKey(RootKey, devInfo, samDesired);
-            break;
-        case DIREG_DRV:
-            key = SETUPDI_OpenDrvKey(RootKey, devInfo, samDesired);
-            break;
-        default:
-            WARN("unknown KeyType %d\n", KeyType);
-    }
-    if (RootKey != set->HKLM)
-        RegCloseKey(RootKey);
-    return key;
-}
-
-static BOOL SETUPDI_DeleteDevKey(HKEY RootKey, struct DeviceInfo *devInfo)
-{
-    FIXME("\n");
-    return FALSE;
-}
-
-static BOOL SETUPDI_DeleteDrvKey(HKEY RootKey, struct DeviceInfo *devInfo)
-{
-    FIXME("\n");
-    return FALSE;
-}
-
-/***********************************************************************
- *             SetupDiDeleteDevRegKey (SETUPAPI.@)
- */
-BOOL WINAPI SetupDiDeleteDevRegKey(
-        HDEVINFO DeviceInfoSet,
-        PSP_DEVINFO_DATA DeviceInfoData,
-        DWORD Scope,
-        DWORD HwProfile,
-        DWORD KeyType)
-{
-    struct DeviceInfoSet *set = (struct DeviceInfoSet *)DeviceInfoSet;
-    struct DeviceInfo *devInfo;
-    BOOL ret = FALSE;
-    HKEY RootKey;
-
-    TRACE("%p %p %d %d %d\n", DeviceInfoSet, DeviceInfoData, Scope, HwProfile,
-            KeyType);
-
-    if (!DeviceInfoSet || DeviceInfoSet == INVALID_HANDLE_VALUE)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (set->magic != SETUP_DEVICE_INFO_SET_MAGIC)
-    {
-        SetLastError(ERROR_INVALID_HANDLE);
-        return FALSE;
-    }
-    if (!DeviceInfoData || DeviceInfoData->cbSize != sizeof(SP_DEVINFO_DATA)
-            || !DeviceInfoData->Reserved)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-    if (Scope != DICS_FLAG_GLOBAL && Scope != DICS_FLAG_CONFIGSPECIFIC)
-    {
-        SetLastError(ERROR_INVALID_FLAGS);
-        return FALSE;
-    }
-    if (KeyType != DIREG_DEV && KeyType != DIREG_DRV && KeyType != DIREG_BOTH)
-    {
-        SetLastError(ERROR_INVALID_FLAGS);
-        return FALSE;
-    }
-    devInfo = (struct DeviceInfo *)DeviceInfoData->Reserved;
-    if (devInfo->set != set)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return FALSE;
-    }
-    if (Scope != DICS_FLAG_GLOBAL)
-    {
-        RootKey = OpenHardwareProfileKey(set->HKLM, HwProfile, 0);
-        if (RootKey == INVALID_HANDLE_VALUE)
-            return FALSE;
-    }
-    else
-        RootKey = set->HKLM;
-    switch (KeyType)
-    {
-        case DIREG_DEV:
-            ret = SETUPDI_DeleteDevKey(RootKey, devInfo);
-            break;
-        case DIREG_DRV:
-            ret = SETUPDI_DeleteDrvKey(RootKey, devInfo);
-            break;
-        case DIREG_BOTH:
-            ret = SETUPDI_DeleteDevKey(RootKey, devInfo);
-            if (ret)
-                ret = SETUPDI_DeleteDrvKey(RootKey, devInfo);
-            break;
-        default:
-            WARN("unknown KeyType %d\n", KeyType);
-    }
-    if (RootKey != set->HKLM)
-        RegCloseKey(RootKey);
-    return ret;
-}