Sync with trunk rev.61910 to get latest improvements and bugfixes.
[reactos.git] / dll / win32 / newdev / newdev.c
index e371736..72f5bcc 100644 (file)
 
 #include "newdev_private.h"
 
-WINE_DEFAULT_DEBUG_CHANNEL(newdev);
+#include <stdio.h>
+#include <winnls.h>
 
 /* Global variables */
 HINSTANCE hDllInstance;
 
 static BOOL
 SearchDriver(
-       IN PDEVINSTDATA DevInstData,
-       IN LPCWSTR Directory OPTIONAL,
-       IN LPCWSTR InfFile OPTIONAL);
+    IN PDEVINSTDATA DevInstData,
+    IN LPCWSTR Directory OPTIONAL,
+    IN LPCWSTR InfFile OPTIONAL);
 
 /*
 * @implemented
 */
 BOOL WINAPI
 UpdateDriverForPlugAndPlayDevicesW(
-       IN HWND hwndParent,
-       IN LPCWSTR HardwareId,
-       IN LPCWSTR FullInfPath,
-       IN DWORD InstallFlags,
-       OUT PBOOL bRebootRequired OPTIONAL)
+    IN HWND hwndParent,
+    IN LPCWSTR HardwareId,
+    IN LPCWSTR FullInfPath,
+    IN DWORD InstallFlags,
+    OUT PBOOL bRebootRequired OPTIONAL)
 {
-       DEVINSTDATA DevInstData;
-       DWORD i;
-       LPWSTR Buffer = NULL;
-       DWORD BufferSize;
-       LPCWSTR CurrentHardwareId; /* Pointer into Buffer */
-       BOOL FoundHardwareId, FoundAtLeastOneDevice = FALSE;
-       BOOL ret = FALSE;
-
-       DevInstData.hDevInfo = INVALID_HANDLE_VALUE;
-
-       TRACE("UpdateDriverForPlugAndPlayDevicesW(%p %s %s 0x%x %p)\n",
-               hwndParent, debugstr_w(HardwareId), debugstr_w(FullInfPath), InstallFlags, bRebootRequired);
-
-       /* FIXME: InstallFlags bRebootRequired ignored! */
-
-       /* Check flags */
-       if (InstallFlags & ~(INSTALLFLAG_FORCE | INSTALLFLAG_READONLY | INSTALLFLAG_NONINTERACTIVE))
-       {
-               TRACE("Unknown flags: 0x%08lx\n", InstallFlags & ~(INSTALLFLAG_FORCE | INSTALLFLAG_READONLY | INSTALLFLAG_NONINTERACTIVE));
-               SetLastError(ERROR_INVALID_FLAGS);
-               goto cleanup;
-       }
-
-       /* Enumerate all devices of the system */
-       DevInstData.hDevInfo = SetupDiGetClassDevsW(NULL, NULL, hwndParent, DIGCF_ALLCLASSES | DIGCF_PRESENT);
-       if (DevInstData.hDevInfo == INVALID_HANDLE_VALUE)
-               goto cleanup;
-       DevInstData.devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
-       for (i = 0; ; i++)
-       {
-               if (!SetupDiEnumDeviceInfo(DevInstData.hDevInfo, i, &DevInstData.devInfoData))
-               {
-                       if (GetLastError() != ERROR_NO_MORE_ITEMS)
-                       {
-                               TRACE("SetupDiEnumDeviceInfo() failed with error 0x%x\n", GetLastError());
-                               goto cleanup;
-                       }
-                       /* This error was expected */
-                       break;
-               }
-
-               /* Get Hardware ID */
-               HeapFree(GetProcessHeap(), 0, Buffer);
-               Buffer = NULL;
-               BufferSize = 0;
-               while (!SetupDiGetDeviceRegistryPropertyW(
-                       DevInstData.hDevInfo,
-                       &DevInstData.devInfoData,
-                       SPDRP_HARDWAREID,
-                       NULL,
-                       (PBYTE)Buffer,
-                       BufferSize,
-                       &BufferSize))
-               {
-                       if (GetLastError() == ERROR_FILE_NOT_FOUND)
-                       {
-                               Buffer = NULL;
-                               break;
-                       }
-                       else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
-                       {
-                               TRACE("SetupDiGetDeviceRegistryPropertyW() failed with error 0x%x\n", GetLastError());
-                               goto cleanup;
-                       }
-                       /* This error was expected */
-                       HeapFree(GetProcessHeap(), 0, Buffer);
-                       Buffer = HeapAlloc(GetProcessHeap(), 0, BufferSize);
-                       if (!Buffer)
-                       {
-                               TRACE("HeapAlloc() failed\n", GetLastError());
-                               SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-                               goto cleanup;
-                       }
-               }
-               if (Buffer == NULL)
-                       continue;
-
-               /* Check if we match the given hardware ID */
-               FoundHardwareId = FALSE;
-               for (CurrentHardwareId = Buffer; *CurrentHardwareId != UNICODE_NULL; CurrentHardwareId += wcslen(CurrentHardwareId) + 1)
-               {
-                       if (wcscmp(CurrentHardwareId, HardwareId) == 0)
-                       {
-                               FoundHardwareId = TRUE;
-                               break;
-                       }
-               }
-               if (!FoundHardwareId)
-                       continue;
-
-               /* We need to try to update the driver of this device */
-
-               /* Get Instance ID */
-               HeapFree(GetProcessHeap(), 0, Buffer);
-               Buffer = NULL;
-               if (SetupDiGetDeviceInstanceIdW(DevInstData.hDevInfo, &DevInstData.devInfoData, NULL, 0, &BufferSize))
-               {
-                       /* Error, as the output buffer should be too small */
-                       SetLastError(ERROR_GEN_FAILURE);
-                       goto cleanup;
-               }
-               else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
-               {
-                       TRACE("SetupDiGetDeviceInstanceIdW() failed with error 0x%x\n", GetLastError());
-                       goto cleanup;
-               }
-               else if ((Buffer = HeapAlloc(GetProcessHeap(), 0, BufferSize * sizeof(WCHAR))) == NULL)
-               {
-                       TRACE("HeapAlloc() failed\n", GetLastError());
-                       SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-                       goto cleanup;
-               }
-               else if (!SetupDiGetDeviceInstanceIdW(DevInstData.hDevInfo, &DevInstData.devInfoData, Buffer, BufferSize, NULL))
-               {
-                       TRACE("SetupDiGetDeviceInstanceIdW() failed with error 0x%x\n", GetLastError());
-                       goto cleanup;
-               }
-               TRACE("Trying to update the driver of %s\n", debugstr_w(Buffer));
-
-               /* Search driver in the specified .inf file */
-               if (!SearchDriver(&DevInstData, NULL, FullInfPath))
-               {
-                       TRACE("SearchDriver() failed with error 0x%x\n", GetLastError());
-                       continue;
-               }
-
-               /* FIXME: HACK! We shouldn't check of ERROR_PRIVILEGE_NOT_HELD */
-               //if (!InstallCurrentDriver(&DevInstData))
-               if (!InstallCurrentDriver(&DevInstData) && GetLastError() != ERROR_PRIVILEGE_NOT_HELD)
-               {
-                       TRACE("InstallCurrentDriver() failed with error 0x%x\n", GetLastError());
-                       continue;
-               }
-
-               FoundAtLeastOneDevice = TRUE;
-       }
-
-       if (FoundAtLeastOneDevice)
-       {
-               SetLastError(NO_ERROR);
-               ret = TRUE;
-       }
-       else
-       {
-               TRACE("No device found with HardwareID %s\n", debugstr_w(HardwareId));
-               SetLastError(ERROR_NO_SUCH_DEVINST);
-       }
+    DEVINSTDATA DevInstData;
+    DWORD i;
+    LPWSTR Buffer = NULL;
+    DWORD BufferSize;
+    LPCWSTR CurrentHardwareId; /* Pointer into Buffer */
+    BOOL FoundHardwareId, FoundAtLeastOneDevice = FALSE;
+    BOOL ret = FALSE;
+
+    DevInstData.hDevInfo = INVALID_HANDLE_VALUE;
+
+    TRACE("UpdateDriverForPlugAndPlayDevicesW(%p %s %s 0x%x %p)\n",
+        hwndParent, debugstr_w(HardwareId), debugstr_w(FullInfPath), InstallFlags, bRebootRequired);
+
+    /* FIXME: InstallFlags bRebootRequired ignored! */
+
+    /* Check flags */
+    if (InstallFlags & ~(INSTALLFLAG_FORCE | INSTALLFLAG_READONLY | INSTALLFLAG_NONINTERACTIVE))
+    {
+        TRACE("Unknown flags: 0x%08lx\n", InstallFlags & ~(INSTALLFLAG_FORCE | INSTALLFLAG_READONLY | INSTALLFLAG_NONINTERACTIVE));
+        SetLastError(ERROR_INVALID_FLAGS);
+        goto cleanup;
+    }
+
+    /* Enumerate all devices of the system */
+    DevInstData.hDevInfo = SetupDiGetClassDevsW(NULL, NULL, hwndParent, DIGCF_ALLCLASSES | DIGCF_PRESENT);
+    if (DevInstData.hDevInfo == INVALID_HANDLE_VALUE)
+        goto cleanup;
+    DevInstData.devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
+    for (i = 0; ; i++)
+    {
+        if (!SetupDiEnumDeviceInfo(DevInstData.hDevInfo, i, &DevInstData.devInfoData))
+        {
+            if (GetLastError() != ERROR_NO_MORE_ITEMS)
+            {
+                TRACE("SetupDiEnumDeviceInfo() failed with error 0x%x\n", GetLastError());
+                goto cleanup;
+            }
+            /* This error was expected */
+            break;
+        }
+
+        /* Get Hardware ID */
+        HeapFree(GetProcessHeap(), 0, Buffer);
+        Buffer = NULL;
+        BufferSize = 0;
+        while (!SetupDiGetDeviceRegistryPropertyW(
+            DevInstData.hDevInfo,
+            &DevInstData.devInfoData,
+            SPDRP_HARDWAREID,
+            NULL,
+            (PBYTE)Buffer,
+            BufferSize,
+            &BufferSize))
+        {
+            if (GetLastError() == ERROR_FILE_NOT_FOUND)
+            {
+                Buffer = NULL;
+                break;
+            }
+            else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+            {
+                TRACE("SetupDiGetDeviceRegistryPropertyW() failed with error 0x%x\n", GetLastError());
+                goto cleanup;
+            }
+            /* This error was expected */
+            HeapFree(GetProcessHeap(), 0, Buffer);
+            Buffer = HeapAlloc(GetProcessHeap(), 0, BufferSize);
+            if (!Buffer)
+            {
+                TRACE("HeapAlloc() failed\n", GetLastError());
+                SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+                goto cleanup;
+            }
+        }
+        if (Buffer == NULL)
+            continue;
+
+        /* Check if we match the given hardware ID */
+        FoundHardwareId = FALSE;
+        for (CurrentHardwareId = Buffer; *CurrentHardwareId != UNICODE_NULL; CurrentHardwareId += wcslen(CurrentHardwareId) + 1)
+        {
+            if (wcscmp(CurrentHardwareId, HardwareId) == 0)
+            {
+                FoundHardwareId = TRUE;
+                break;
+            }
+        }
+        if (!FoundHardwareId)
+            continue;
+
+        /* We need to try to update the driver of this device */
+
+        /* Get Instance ID */
+        HeapFree(GetProcessHeap(), 0, Buffer);
+        Buffer = NULL;
+        if (SetupDiGetDeviceInstanceIdW(DevInstData.hDevInfo, &DevInstData.devInfoData, NULL, 0, &BufferSize))
+        {
+            /* Error, as the output buffer should be too small */
+            SetLastError(ERROR_GEN_FAILURE);
+            goto cleanup;
+        }
+        else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+        {
+            TRACE("SetupDiGetDeviceInstanceIdW() failed with error 0x%x\n", GetLastError());
+            goto cleanup;
+        }
+        else if ((Buffer = HeapAlloc(GetProcessHeap(), 0, BufferSize * sizeof(WCHAR))) == NULL)
+        {
+            TRACE("HeapAlloc() failed\n", GetLastError());
+            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+            goto cleanup;
+        }
+        else if (!SetupDiGetDeviceInstanceIdW(DevInstData.hDevInfo, &DevInstData.devInfoData, Buffer, BufferSize, NULL))
+        {
+            TRACE("SetupDiGetDeviceInstanceIdW() failed with error 0x%x\n", GetLastError());
+            goto cleanup;
+        }
+        TRACE("Trying to update the driver of %s\n", debugstr_w(Buffer));
+
+        /* Search driver in the specified .inf file */
+        if (!SearchDriver(&DevInstData, NULL, FullInfPath))
+        {
+            TRACE("SearchDriver() failed with error 0x%x\n", GetLastError());
+            continue;
+        }
+
+        /* FIXME: HACK! We shouldn't check of ERROR_PRIVILEGE_NOT_HELD */
+        //if (!InstallCurrentDriver(&DevInstData))
+        if (!InstallCurrentDriver(&DevInstData) && GetLastError() != ERROR_PRIVILEGE_NOT_HELD)
+        {
+            TRACE("InstallCurrentDriver() failed with error 0x%x\n", GetLastError());
+            continue;
+        }
+
+        FoundAtLeastOneDevice = TRUE;
+    }
+
+    if (FoundAtLeastOneDevice)
+    {
+        SetLastError(NO_ERROR);
+        ret = TRUE;
+    }
+    else
+    {
+        TRACE("No device found with HardwareID %s\n", debugstr_w(HardwareId));
+        SetLastError(ERROR_NO_SUCH_DEVINST);
+    }
 
 cleanup:
-       if (DevInstData.hDevInfo != INVALID_HANDLE_VALUE)
-               SetupDiDestroyDeviceInfoList(DevInstData.hDevInfo);
-       HeapFree(GetProcessHeap(), 0, Buffer);
-       return ret;
+    if (DevInstData.hDevInfo != INVALID_HANDLE_VALUE)
+        SetupDiDestroyDeviceInfoList(DevInstData.hDevInfo);
+    HeapFree(GetProcessHeap(), 0, Buffer);
+    return ret;
 }
 
 /*
@@ -204,429 +205,429 @@ cleanup:
 */
 BOOL WINAPI
 UpdateDriverForPlugAndPlayDevicesA(
-       IN HWND hwndParent,
-       IN LPCSTR HardwareId,
-       IN LPCSTR FullInfPath,
-       IN DWORD InstallFlags,
-       OUT PBOOL bRebootRequired OPTIONAL)
+    IN HWND hwndParent,
+    IN LPCSTR HardwareId,
+    IN LPCSTR FullInfPath,
+    IN DWORD InstallFlags,
+    OUT PBOOL bRebootRequired OPTIONAL)
 {
-       BOOL Result;
-       LPWSTR HardwareIdW = NULL;
-       LPWSTR FullInfPathW = NULL;
-
-       int len = MultiByteToWideChar(CP_ACP, 0, HardwareId, -1, NULL, 0);
-       HardwareIdW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
-       if (!HardwareIdW)
-       {
-               SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-               return FALSE;
-       }
-       MultiByteToWideChar(CP_ACP, 0, HardwareId, -1, HardwareIdW, len);
-
-       len = MultiByteToWideChar(CP_ACP, 0, FullInfPath, -1, NULL, 0);
-       FullInfPathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
-       if (!FullInfPathW)
-       {
-               HeapFree(GetProcessHeap(), 0, HardwareIdW);
-               SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-               return FALSE;
-       }
-       MultiByteToWideChar(CP_ACP, 0, FullInfPath, -1, FullInfPathW, len);
-
-       Result = UpdateDriverForPlugAndPlayDevicesW(
-               hwndParent,
-               HardwareIdW,
-               FullInfPathW,
-               InstallFlags,
-               bRebootRequired);
-
-       HeapFree(GetProcessHeap(), 0, HardwareIdW);
-       HeapFree(GetProcessHeap(), 0, FullInfPathW);
-
-       return Result;
+    BOOL Result;
+    LPWSTR HardwareIdW = NULL;
+    LPWSTR FullInfPathW = NULL;
+
+    int len = MultiByteToWideChar(CP_ACP, 0, HardwareId, -1, NULL, 0);
+    HardwareIdW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+    if (!HardwareIdW)
+    {
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        return FALSE;
+    }
+    MultiByteToWideChar(CP_ACP, 0, HardwareId, -1, HardwareIdW, len);
+
+    len = MultiByteToWideChar(CP_ACP, 0, FullInfPath, -1, NULL, 0);
+    FullInfPathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+    if (!FullInfPathW)
+    {
+        HeapFree(GetProcessHeap(), 0, HardwareIdW);
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        return FALSE;
+    }
+    MultiByteToWideChar(CP_ACP, 0, FullInfPath, -1, FullInfPathW, len);
+
+    Result = UpdateDriverForPlugAndPlayDevicesW(
+        hwndParent,
+        HardwareIdW,
+        FullInfPathW,
+        InstallFlags,
+        bRebootRequired);
+
+    HeapFree(GetProcessHeap(), 0, HardwareIdW);
+    HeapFree(GetProcessHeap(), 0, FullInfPathW);
+
+    return Result;
 }
 
 /* Directory and InfFile MUST NOT be specified simultaneously */
 static BOOL
 SearchDriver(
-       IN PDEVINSTDATA DevInstData,
-       IN LPCWSTR Directory OPTIONAL,
-       IN LPCWSTR InfFile OPTIONAL)
+    IN PDEVINSTDATA DevInstData,
+    IN LPCWSTR Directory OPTIONAL,
+    IN LPCWSTR InfFile OPTIONAL)
 {
-       SP_DEVINSTALL_PARAMS_W DevInstallParams = {0,};
-       BOOL ret;
-
-       DevInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
-       if (!SetupDiGetDeviceInstallParamsW(DevInstData->hDevInfo, &DevInstData->devInfoData, &DevInstallParams))
-       {
-               TRACE("SetupDiGetDeviceInstallParams() failed with error 0x%x\n", GetLastError());
-               return FALSE;
-       }
-       DevInstallParams.FlagsEx |= DI_FLAGSEX_ALLOWEXCLUDEDDRVS;
-
-       if (InfFile)
-       {
-               DevInstallParams.Flags |= DI_ENUMSINGLEINF;
-               wcsncpy(DevInstallParams.DriverPath, InfFile, MAX_PATH);
-       }
-       else if (Directory)
-       {
-               DevInstallParams.Flags &= ~DI_ENUMSINGLEINF;
-               wcsncpy(DevInstallParams.DriverPath, Directory, MAX_PATH);
-       }
-       else
-       {
-               DevInstallParams.Flags &= ~DI_ENUMSINGLEINF;
-               *DevInstallParams.DriverPath = '\0';
-       }
-
-       ret = SetupDiSetDeviceInstallParamsW(
-               DevInstData->hDevInfo,
-               &DevInstData->devInfoData,
-               &DevInstallParams);
-       if (!ret)
-       {
-               TRACE("SetupDiSetDeviceInstallParams() failed with error 0x%x\n", GetLastError());
-               return FALSE;
-       }
-
-       ret = SetupDiBuildDriverInfoList(
-               DevInstData->hDevInfo,
-               &DevInstData->devInfoData,
-               SPDIT_COMPATDRIVER);
-       if (!ret)
-       {
-               TRACE("SetupDiBuildDriverInfoList() failed with error 0x%x\n", GetLastError());
-               return FALSE;
-       }
-
-       DevInstData->drvInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
-       ret = SetupDiEnumDriverInfoW(
-               DevInstData->hDevInfo,
-               &DevInstData->devInfoData,
-               SPDIT_COMPATDRIVER,
-               0,
-               &DevInstData->drvInfoData);
-       if (!ret)
-       {
-               if (GetLastError() == ERROR_NO_MORE_ITEMS)
-                       return FALSE;
-               TRACE("SetupDiEnumDriverInfo() failed with error 0x%x\n", GetLastError());
-               return FALSE;
-       }
-
-       return TRUE;
+    SP_DEVINSTALL_PARAMS_W DevInstallParams = {0,};
+    BOOL ret;
+
+    DevInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS_W);
+    if (!SetupDiGetDeviceInstallParamsW(DevInstData->hDevInfo, &DevInstData->devInfoData, &DevInstallParams))
+    {
+        TRACE("SetupDiGetDeviceInstallParams() failed with error 0x%x\n", GetLastError());
+        return FALSE;
+    }
+    DevInstallParams.FlagsEx |= DI_FLAGSEX_ALLOWEXCLUDEDDRVS;
+
+    if (InfFile)
+    {
+        DevInstallParams.Flags |= DI_ENUMSINGLEINF;
+        wcsncpy(DevInstallParams.DriverPath, InfFile, MAX_PATH);
+    }
+    else if (Directory)
+    {
+        DevInstallParams.Flags &= ~DI_ENUMSINGLEINF;
+        wcsncpy(DevInstallParams.DriverPath, Directory, MAX_PATH);
+    }
+    else
+    {
+        DevInstallParams.Flags &= ~DI_ENUMSINGLEINF;
+        *DevInstallParams.DriverPath = '\0';
+    }
+
+    ret = SetupDiSetDeviceInstallParamsW(
+        DevInstData->hDevInfo,
+        &DevInstData->devInfoData,
+        &DevInstallParams);
+    if (!ret)
+    {
+        TRACE("SetupDiSetDeviceInstallParams() failed with error 0x%x\n", GetLastError());
+        return FALSE;
+    }
+
+    ret = SetupDiBuildDriverInfoList(
+        DevInstData->hDevInfo,
+        &DevInstData->devInfoData,
+        SPDIT_COMPATDRIVER);
+    if (!ret)
+    {
+        TRACE("SetupDiBuildDriverInfoList() failed with error 0x%x\n", GetLastError());
+        return FALSE;
+    }
+
+    DevInstData->drvInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
+    ret = SetupDiEnumDriverInfoW(
+        DevInstData->hDevInfo,
+        &DevInstData->devInfoData,
+        SPDIT_COMPATDRIVER,
+        0,
+        &DevInstData->drvInfoData);
+    if (!ret)
+    {
+        if (GetLastError() == ERROR_NO_MORE_ITEMS)
+            return FALSE;
+        TRACE("SetupDiEnumDriverInfo() failed with error 0x%x\n", GetLastError());
+        return FALSE;
+    }
+
+    return TRUE;
 }
 
 static BOOL
 IsDots(IN LPCWSTR str)
 {
-       if(wcscmp(str, L".") && wcscmp(str, L"..")) return FALSE;
-       return TRUE;
+    if(wcscmp(str, L".") && wcscmp(str, L"..")) return FALSE;
+    return TRUE;
 }
 
 static LPCWSTR
 GetFileExt(IN LPWSTR FileName)
 {
-       LPCWSTR Dot;
+    LPCWSTR Dot;
 
-       Dot = wcsrchr(FileName, '.');
-       if (!Dot)
-               return L"";
+    Dot = wcsrchr(FileName, '.');
+    if (!Dot)
+        return L"";
 
-       return Dot;
+    return Dot;
 }
 
 static BOOL
 SearchDriverRecursive(
-       IN PDEVINSTDATA DevInstData,
-       IN LPCWSTR Path)
+    IN PDEVINSTDATA DevInstData,
+    IN LPCWSTR Path)
 {
-       WIN32_FIND_DATAW wfd;
-       WCHAR DirPath[MAX_PATH];
-       WCHAR FileName[MAX_PATH];
-       WCHAR FullPath[MAX_PATH];
-       WCHAR LastDirPath[MAX_PATH] = L"";
-       WCHAR PathWithPattern[MAX_PATH];
-       BOOL ok = TRUE;
-       BOOL retval = FALSE;
-       HANDLE hFindFile = INVALID_HANDLE_VALUE;
-
-       wcscpy(DirPath, Path);
-
-       if (DirPath[wcslen(DirPath) - 1] != '\\')
-               wcscat(DirPath, L"\\");
-
-       wcscpy(PathWithPattern, DirPath);
-       wcscat(PathWithPattern, L"\\*");
-
-       for (hFindFile = FindFirstFileW(PathWithPattern, &wfd);
-               ok && hFindFile != INVALID_HANDLE_VALUE;
-               ok = FindNextFileW(hFindFile, &wfd))
-       {
-
-               wcscpy(FileName, wfd.cFileName);
-               if (IsDots(FileName))
-                       continue;
-
-               if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
-               {
-                       /* Recursive search */
-                       wcscpy(FullPath, DirPath);
-                       wcscat(FullPath, FileName);
-                       if (SearchDriverRecursive(DevInstData, FullPath))
-                       {
-                               retval = TRUE;
-                               /* We continue the search for a better driver */
-                       }
-               }
-               else
-               {
-                       LPCWSTR pszExtension = GetFileExt(FileName);
-
-                       if ((_wcsicmp(pszExtension, L".inf") == 0) && (wcscmp(LastDirPath, DirPath) != 0))
-                       {
-                               wcscpy(LastDirPath, DirPath);
-
-                               if (wcslen(DirPath) > MAX_PATH)
-                                       /* Path is too long to be searched */
-                                       continue;
-
-                               if (SearchDriver(DevInstData, DirPath, NULL))
-                               {
-                                       retval = TRUE;
-                                       /* We continue the search for a better driver */
-                               }
-
-                       }
-               }
-       }
-
-       if (hFindFile != INVALID_HANDLE_VALUE)
-               FindClose(hFindFile);
-       return retval;
+    WIN32_FIND_DATAW wfd;
+    WCHAR DirPath[MAX_PATH];
+    WCHAR FileName[MAX_PATH];
+    WCHAR FullPath[MAX_PATH];
+    WCHAR LastDirPath[MAX_PATH] = L"";
+    WCHAR PathWithPattern[MAX_PATH];
+    BOOL ok = TRUE;
+    BOOL retval = FALSE;
+    HANDLE hFindFile = INVALID_HANDLE_VALUE;
+
+    wcscpy(DirPath, Path);
+
+    if (DirPath[wcslen(DirPath) - 1] != '\\')
+        wcscat(DirPath, L"\\");
+
+    wcscpy(PathWithPattern, DirPath);
+    wcscat(PathWithPattern, L"\\*");
+
+    for (hFindFile = FindFirstFileW(PathWithPattern, &wfd);
+        ok && hFindFile != INVALID_HANDLE_VALUE;
+        ok = FindNextFileW(hFindFile, &wfd))
+    {
+
+        wcscpy(FileName, wfd.cFileName);
+        if (IsDots(FileName))
+            continue;
+
+        if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+        {
+            /* Recursive search */
+            wcscpy(FullPath, DirPath);
+            wcscat(FullPath, FileName);
+            if (SearchDriverRecursive(DevInstData, FullPath))
+            {
+                retval = TRUE;
+                /* We continue the search for a better driver */
+            }
+        }
+        else
+        {
+            LPCWSTR pszExtension = GetFileExt(FileName);
+
+            if ((_wcsicmp(pszExtension, L".inf") == 0) && (wcscmp(LastDirPath, DirPath) != 0))
+            {
+                wcscpy(LastDirPath, DirPath);
+
+                if (wcslen(DirPath) > MAX_PATH)
+                    /* Path is too long to be searched */
+                    continue;
+
+                if (SearchDriver(DevInstData, DirPath, NULL))
+                {
+                    retval = TRUE;
+                    /* We continue the search for a better driver */
+                }
+
+            }
+        }
+    }
+
+    if (hFindFile != INVALID_HANDLE_VALUE)
+        FindClose(hFindFile);
+    return retval;
 }
 
 BOOL
 ScanFoldersForDriver(
-       IN PDEVINSTDATA DevInstData)
+    IN PDEVINSTDATA DevInstData)
 {
-       BOOL result;
-
-       /* Search in default location */
-       result = SearchDriver(DevInstData, NULL, NULL);
-
-       if (DevInstData->CustomSearchPath)
-       {
-               /* Search only in specified paths */
-               /* We need to check all specified directories to be
-                * sure to find the best driver for the device.
-                */
-               LPCWSTR Path;
-               for (Path = DevInstData->CustomSearchPath; *Path != '\0'; Path += wcslen(Path) + 1)
-               {
-                       TRACE("Search driver in %s\n", debugstr_w(Path));
-                       if (wcslen(Path) == 2 && Path[1] == ':')
-                       {
-                               if (SearchDriverRecursive(DevInstData, Path))
-                                       result = TRUE;
-                       }
-                       else
-                       {
-                               if (SearchDriver(DevInstData, Path, NULL))
-                                       result = TRUE;
-                       }
-               }
-       }
-
-       return result;
+    BOOL result;
+
+    /* Search in default location */
+    result = SearchDriver(DevInstData, NULL, NULL);
+
+    if (DevInstData->CustomSearchPath)
+    {
+        /* Search only in specified paths */
+        /* We need to check all specified directories to be
+         * sure to find the best driver for the device.
+         */
+        LPCWSTR Path;
+        for (Path = DevInstData->CustomSearchPath; *Path != '\0'; Path += wcslen(Path) + 1)
+        {
+            TRACE("Search driver in %s\n", debugstr_w(Path));
+            if (wcslen(Path) == 2 && Path[1] == ':')
+            {
+                if (SearchDriverRecursive(DevInstData, Path))
+                    result = TRUE;
+            }
+            else
+            {
+                if (SearchDriver(DevInstData, Path, NULL))
+                    result = TRUE;
+            }
+        }
+    }
+
+    return result;
 }
 
 BOOL
 PrepareFoldersToScan(
-       IN PDEVINSTDATA DevInstData,
-       IN BOOL IncludeRemovableDevices,
-       IN BOOL IncludeCustomPath,
-       IN HWND hwndCombo OPTIONAL)
+    IN PDEVINSTDATA DevInstData,
+    IN BOOL IncludeRemovableDevices,
+    IN BOOL IncludeCustomPath,
+    IN HWND hwndCombo OPTIONAL)
 {
-       WCHAR drive[] = {'?',':',0};
-       DWORD dwDrives = 0;
-       DWORD i;
-       UINT nType;
-       DWORD CustomTextLength = 0;
-       DWORD LengthNeeded = 0;
-       LPWSTR Buffer;
-
-       /* Calculate length needed to store the search paths */
-       if (IncludeRemovableDevices)
-       {
-               dwDrives = GetLogicalDrives();
-               for (drive[0] = 'A', i = 1; drive[0] <= 'Z'; drive[0]++, i <<= 1)
-               {
-                       if (dwDrives & i)
-                       {
-                               nType = GetDriveTypeW(drive);
-                               if (nType == DRIVE_REMOVABLE || nType == DRIVE_CDROM)
-                               {
-                                       LengthNeeded += 3;
-                               }
-                       }
-               }
-       }
-       if (IncludeCustomPath)
-       {
-               CustomTextLength = 1 + ComboBox_GetTextLength(hwndCombo);
-               LengthNeeded += CustomTextLength;
-       }
-
-       /* Allocate space for search paths */
-       HeapFree(GetProcessHeap(), 0, DevInstData->CustomSearchPath);
-       DevInstData->CustomSearchPath = Buffer = HeapAlloc(
-               GetProcessHeap(),
-               0,
-               (LengthNeeded + 1) * sizeof(WCHAR));
-       if (!Buffer)
-       {
-               TRACE("HeapAlloc() failed\n");
-               SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-               return FALSE;
-       }
-
-       /* Fill search paths */
-       if (IncludeRemovableDevices)
-       {
-               for (drive[0] = 'A', i = 1; drive[0] <= 'Z'; drive[0]++, i <<= 1)
-               {
-                       if (dwDrives & i)
-                       {
-                               nType = GetDriveTypeW(drive);
-                               if (nType == DRIVE_REMOVABLE || nType == DRIVE_CDROM)
-                               {
-                                       Buffer += 1 + swprintf(Buffer, drive);
-                               }
-                       }
-               }
-       }
-       if (IncludeCustomPath)
-       {
-               Buffer += 1 + GetWindowTextW(hwndCombo, Buffer, CustomTextLength);
-       }
-       *Buffer = '\0';
-
-       return TRUE;
+    WCHAR drive[] = {'?',':',0};
+    DWORD dwDrives = 0;
+    DWORD i;
+    UINT nType;
+    DWORD CustomTextLength = 0;
+    DWORD LengthNeeded = 0;
+    LPWSTR Buffer;
+
+    /* Calculate length needed to store the search paths */
+    if (IncludeRemovableDevices)
+    {
+        dwDrives = GetLogicalDrives();
+        for (drive[0] = 'A', i = 1; drive[0] <= 'Z'; drive[0]++, i <<= 1)
+        {
+            if (dwDrives & i)
+            {
+                nType = GetDriveTypeW(drive);
+                if (nType == DRIVE_REMOVABLE || nType == DRIVE_CDROM)
+                {
+                    LengthNeeded += 3;
+                }
+            }
+        }
+    }
+    if (IncludeCustomPath)
+    {
+        CustomTextLength = 1 + ComboBox_GetTextLength(hwndCombo);
+        LengthNeeded += CustomTextLength;
+    }
+
+    /* Allocate space for search paths */
+    HeapFree(GetProcessHeap(), 0, DevInstData->CustomSearchPath);
+    DevInstData->CustomSearchPath = Buffer = HeapAlloc(
+        GetProcessHeap(),
+        0,
+        (LengthNeeded + 1) * sizeof(WCHAR));
+    if (!Buffer)
+    {
+        TRACE("HeapAlloc() failed\n");
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        return FALSE;
+    }
+
+    /* Fill search paths */
+    if (IncludeRemovableDevices)
+    {
+        for (drive[0] = 'A', i = 1; drive[0] <= 'Z'; drive[0]++, i <<= 1)
+        {
+            if (dwDrives & i)
+            {
+                nType = GetDriveTypeW(drive);
+                if (nType == DRIVE_REMOVABLE || nType == DRIVE_CDROM)
+                {
+                    Buffer += 1 + swprintf(Buffer, drive);
+                }
+            }
+        }
+    }
+    if (IncludeCustomPath)
+    {
+        Buffer += 1 + GetWindowTextW(hwndCombo, Buffer, CustomTextLength);
+    }
+    *Buffer = '\0';
+
+    return TRUE;
 }
 
 BOOL
 InstallCurrentDriver(
-       IN PDEVINSTDATA DevInstData)
+    IN PDEVINSTDATA DevInstData)
 {
-       BOOL ret;
-
-       TRACE("Installing driver %s: %s\n",
-               debugstr_w(DevInstData->drvInfoData.MfgName),
-               debugstr_w(DevInstData->drvInfoData.Description));
-
-       ret = SetupDiCallClassInstaller(
-               DIF_SELECTBESTCOMPATDRV,
-               DevInstData->hDevInfo,
-               &DevInstData->devInfoData);
-       if (!ret)
-       {
-               TRACE("SetupDiCallClassInstaller(DIF_SELECTBESTCOMPATDRV) failed with error 0x%x\n", GetLastError());
-               return FALSE;
-       }
-
-       ret = SetupDiCallClassInstaller(
-               DIF_ALLOW_INSTALL,
-               DevInstData->hDevInfo,
-               &DevInstData->devInfoData);
-       if (!ret)
-       {
-               TRACE("SetupDiCallClassInstaller(DIF_ALLOW_INSTALL) failed with error 0x%x\n", GetLastError());
-               return FALSE;
-       }
-
-       ret = SetupDiCallClassInstaller(
-               DIF_NEWDEVICEWIZARD_PREANALYZE,
-               DevInstData->hDevInfo,
-               &DevInstData->devInfoData);
-       if (!ret)
-       {
-               TRACE("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_PREANALYZE) failed with error 0x%x\n", GetLastError());
-               return FALSE;
-       }
-
-       ret = SetupDiCallClassInstaller(
-               DIF_NEWDEVICEWIZARD_POSTANALYZE,
-               DevInstData->hDevInfo,
-               &DevInstData->devInfoData);
-       if (!ret)
-       {
-               TRACE("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_POSTANALYZE) failed with error 0x%x\n", GetLastError());
-               return FALSE;
-       }
-
-       ret = SetupDiCallClassInstaller(
-               DIF_INSTALLDEVICEFILES,
-               DevInstData->hDevInfo,
-               &DevInstData->devInfoData);
-       if (!ret)
-       {
-               TRACE("SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES) failed with error 0x%x\n", GetLastError());
-               return FALSE;
-       }
-
-       ret = SetupDiCallClassInstaller(
-               DIF_REGISTER_COINSTALLERS,
-               DevInstData->hDevInfo,
-               &DevInstData->devInfoData);
-       if (!ret)
-       {
-               TRACE("SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS) failed with error 0x%x\n", GetLastError());
-               return FALSE;
-       }
-
-       ret = SetupDiCallClassInstaller(
-               DIF_INSTALLINTERFACES,
-               DevInstData->hDevInfo,
-               &DevInstData->devInfoData);
-       if (!ret)
-       {
-               TRACE("SetupDiCallClassInstaller(DIF_INSTALLINTERFACES) failed with error 0x%x\n", GetLastError());
-               return FALSE;
-       }
-
-       ret = SetupDiCallClassInstaller(
-               DIF_INSTALLDEVICE,
-               DevInstData->hDevInfo,
-               &DevInstData->devInfoData);
-       if (!ret)
-       {
-               TRACE("SetupDiCallClassInstaller(DIF_INSTALLDEVICE) failed with error 0x%x\n", GetLastError());
-               return FALSE;
-       }
-
-       ret = SetupDiCallClassInstaller(
-               DIF_NEWDEVICEWIZARD_FINISHINSTALL,
-               DevInstData->hDevInfo,
-               &DevInstData->devInfoData);
-       if (!ret)
-       {
-               TRACE("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_FINISHINSTALL) failed with error 0x%x\n", GetLastError());
-               return FALSE;
-       }
-
-       ret = SetupDiCallClassInstaller(
-               DIF_DESTROYPRIVATEDATA,
-               DevInstData->hDevInfo,
-               &DevInstData->devInfoData);
-       if (!ret)
-       {
-               TRACE("SetupDiCallClassInstaller(DIF_DESTROYPRIVATEDATA) failed with error 0x%x\n", GetLastError());
-               return FALSE;
-       }
-
-       return TRUE;
+    BOOL ret;
+
+    TRACE("Installing driver %s: %s\n",
+        debugstr_w(DevInstData->drvInfoData.MfgName),
+        debugstr_w(DevInstData->drvInfoData.Description));
+
+    ret = SetupDiCallClassInstaller(
+        DIF_SELECTBESTCOMPATDRV,
+        DevInstData->hDevInfo,
+        &DevInstData->devInfoData);
+    if (!ret)
+    {
+        TRACE("SetupDiCallClassInstaller(DIF_SELECTBESTCOMPATDRV) failed with error 0x%x\n", GetLastError());
+        return FALSE;
+    }
+
+    ret = SetupDiCallClassInstaller(
+        DIF_ALLOW_INSTALL,
+        DevInstData->hDevInfo,
+        &DevInstData->devInfoData);
+    if (!ret)
+    {
+        TRACE("SetupDiCallClassInstaller(DIF_ALLOW_INSTALL) failed with error 0x%x\n", GetLastError());
+        return FALSE;
+    }
+
+    ret = SetupDiCallClassInstaller(
+        DIF_NEWDEVICEWIZARD_PREANALYZE,
+        DevInstData->hDevInfo,
+        &DevInstData->devInfoData);
+    if (!ret)
+    {
+        TRACE("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_PREANALYZE) failed with error 0x%x\n", GetLastError());
+        return FALSE;
+    }
+
+    ret = SetupDiCallClassInstaller(
+        DIF_NEWDEVICEWIZARD_POSTANALYZE,
+        DevInstData->hDevInfo,
+        &DevInstData->devInfoData);
+    if (!ret)
+    {
+        TRACE("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_POSTANALYZE) failed with error 0x%x\n", GetLastError());
+        return FALSE;
+    }
+
+    ret = SetupDiCallClassInstaller(
+        DIF_INSTALLDEVICEFILES,
+        DevInstData->hDevInfo,
+        &DevInstData->devInfoData);
+    if (!ret)
+    {
+        TRACE("SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES) failed with error 0x%x\n", GetLastError());
+        return FALSE;
+    }
+
+    ret = SetupDiCallClassInstaller(
+        DIF_REGISTER_COINSTALLERS,
+        DevInstData->hDevInfo,
+        &DevInstData->devInfoData);
+    if (!ret)
+    {
+        TRACE("SetupDiCallClassInstaller(DIF_REGISTER_COINSTALLERS) failed with error 0x%x\n", GetLastError());
+        return FALSE;
+    }
+
+    ret = SetupDiCallClassInstaller(
+        DIF_INSTALLINTERFACES,
+        DevInstData->hDevInfo,
+        &DevInstData->devInfoData);
+    if (!ret)
+    {
+        TRACE("SetupDiCallClassInstaller(DIF_INSTALLINTERFACES) failed with error 0x%x\n", GetLastError());
+        return FALSE;
+    }
+
+    ret = SetupDiCallClassInstaller(
+        DIF_INSTALLDEVICE,
+        DevInstData->hDevInfo,
+        &DevInstData->devInfoData);
+    if (!ret)
+    {
+        TRACE("SetupDiCallClassInstaller(DIF_INSTALLDEVICE) failed with error 0x%x\n", GetLastError());
+        return FALSE;
+    }
+
+    ret = SetupDiCallClassInstaller(
+        DIF_NEWDEVICEWIZARD_FINISHINSTALL,
+        DevInstData->hDevInfo,
+        &DevInstData->devInfoData);
+    if (!ret)
+    {
+        TRACE("SetupDiCallClassInstaller(DIF_NEWDEVICEWIZARD_FINISHINSTALL) failed with error 0x%x\n", GetLastError());
+        return FALSE;
+    }
+
+    ret = SetupDiCallClassInstaller(
+        DIF_DESTROYPRIVATEDATA,
+        DevInstData->hDevInfo,
+        &DevInstData->devInfoData);
+    if (!ret)
+    {
+        TRACE("SetupDiCallClassInstaller(DIF_DESTROYPRIVATEDATA) failed with error 0x%x\n", GetLastError());
+        return FALSE;
+    }
+
+    return TRUE;
 }
 
 /*
@@ -634,173 +635,173 @@ InstallCurrentDriver(
 */
 BOOL WINAPI
 DevInstallW(
-       IN HWND hWndParent,
-       IN HINSTANCE hInstance,
-       IN LPCWSTR InstanceId,
-       IN INT Show)
+    IN HWND hWndParent,
+    IN HINSTANCE hInstance,
+    IN LPCWSTR InstanceId,
+    IN INT Show)
 {
-       PDEVINSTDATA DevInstData = NULL;
-       BOOL ret;
-       DWORD config_flags;
-       BOOL retval = FALSE;
-
-       TRACE("(%p, %p, %s, %d)\n", hWndParent, hInstance, debugstr_w(InstanceId), Show);
-
-       if (!IsUserAdmin())
-       {
-               /* XP kills the process... */
-               ExitProcess(ERROR_ACCESS_DENIED);
-       }
-
-       DevInstData = HeapAlloc(GetProcessHeap(), 0, sizeof(DEVINSTDATA));
-       if (!DevInstData)
-       {
-               TRACE("HeapAlloc() failed\n");
-               SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-               goto cleanup;
-       }
-
-       /* Clear devinst data */
-       ZeroMemory(DevInstData, sizeof(DEVINSTDATA));
-       DevInstData->devInfoData.cbSize = 0; /* Tell if the devInfoData is valid */
-
-       /* Fill devinst data */
-       DevInstData->hDevInfo = SetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, NULL);
-       if (DevInstData->hDevInfo == INVALID_HANDLE_VALUE)
-       {
-               TRACE("SetupDiCreateDeviceInfoListExW() failed with error 0x%x\n", GetLastError());
-               goto cleanup;
-       }
-
-       DevInstData->devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
-       ret = SetupDiOpenDeviceInfoW(
-               DevInstData->hDevInfo,
-               InstanceId,
-               NULL,
-               0, /* Open flags */
-               &DevInstData->devInfoData);
-       if (!ret)
-       {
-               TRACE("SetupDiOpenDeviceInfoW() failed with error 0x%x (InstanceId %s)\n",
-                       GetLastError(), debugstr_w(InstanceId));
-               DevInstData->devInfoData.cbSize = 0;
-               goto cleanup;
-       }
-
-       SetLastError(ERROR_GEN_FAILURE);
-       ret = SetupDiGetDeviceRegistryProperty(
-               DevInstData->hDevInfo,
-               &DevInstData->devInfoData,
-               SPDRP_DEVICEDESC,
-               &DevInstData->regDataType,
-               NULL, 0,
-               &DevInstData->requiredSize);
-
-       if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER && DevInstData->regDataType == REG_SZ)
-       {
-               DevInstData->buffer = HeapAlloc(GetProcessHeap(), 0, DevInstData->requiredSize);
-               if (!DevInstData->buffer)
-               {
-                       TRACE("HeapAlloc() failed\n");
-                       SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-               }
-               else
-               {
-                       ret = SetupDiGetDeviceRegistryPropertyW(
-                               DevInstData->hDevInfo,
-                               &DevInstData->devInfoData,
-                               SPDRP_DEVICEDESC,
-                               &DevInstData->regDataType,
-                               DevInstData->buffer, DevInstData->requiredSize,
-                               &DevInstData->requiredSize);
-               }
-       }
-       if (!ret)
-       {
-               TRACE("SetupDiGetDeviceRegistryProperty() failed with error 0x%x (InstanceId %s)\n",
-                       GetLastError(), debugstr_w(InstanceId));
-               goto cleanup;
-       }
-
-       if (SetupDiGetDeviceRegistryPropertyW(
-               DevInstData->hDevInfo,
-               &DevInstData->devInfoData,
-               SPDRP_CONFIGFLAGS,
-               NULL,
-               (BYTE *)&config_flags,
-               sizeof(config_flags),
-               NULL))
-       {
-               if (config_flags & CONFIGFLAG_FAILEDINSTALL)
-               {
-                       /* The device is disabled */
-                       TRACE("Device is disabled\n");
-                       retval = TRUE;
-                       goto cleanup;
-               }
-       }
-
-       TRACE("Installing %s (%s)\n", debugstr_w((PCWSTR)DevInstData->buffer), debugstr_w(InstanceId));
-
-       /* Search driver in default location and removable devices */
-       if (!PrepareFoldersToScan(DevInstData, FALSE, FALSE, NULL))
-       {
-               TRACE("PrepareFoldersToScan() failed with error 0x%lx\n", GetLastError());
-               goto cleanup;
-       }
-       if (ScanFoldersForDriver(DevInstData))
-       {
-               /* Driver found ; install it */
-               retval = InstallCurrentDriver(DevInstData);
-               TRACE("InstallCurrentDriver() returned %d\n", retval);
-               if (retval && Show != SW_HIDE)
-               {
-                       /* Should we display the 'Need to reboot' page? */
-                       SP_DEVINSTALL_PARAMS installParams;
-                       installParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
-                       if (SetupDiGetDeviceInstallParams(
-                               DevInstData->hDevInfo,
-                               &DevInstData->devInfoData,
-                               &installParams))
-                       {
-                               if (installParams.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT))
-                               {
-                                       TRACE("Displaying 'Reboot' wizard page\n");
-                                       retval = DisplayWizard(DevInstData, hWndParent, IDD_NEEDREBOOT);
-                               }
-                       }
-               }
-               goto cleanup;
-       }
-       else if (Show == SW_HIDE)
-       {
-               /* We can't show the wizard. Fail the install */
-               TRACE("No wizard\n");
-               goto cleanup;
-       }
-
-       /* Prepare the wizard, and display it */
-       TRACE("Need to show install wizard\n");
-       retval = DisplayWizard(DevInstData, hWndParent, IDD_WELCOMEPAGE);
+    PDEVINSTDATA DevInstData = NULL;
+    BOOL ret;
+    DWORD config_flags;
+    BOOL retval = FALSE;
+
+    TRACE("(%p, %p, %s, %d)\n", hWndParent, hInstance, debugstr_w(InstanceId), Show);
+
+    if (!IsUserAdmin())
+    {
+        /* XP kills the process... */
+        ExitProcess(ERROR_ACCESS_DENIED);
+    }
+
+    DevInstData = HeapAlloc(GetProcessHeap(), 0, sizeof(DEVINSTDATA));
+    if (!DevInstData)
+    {
+        TRACE("HeapAlloc() failed\n");
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        goto cleanup;
+    }
+
+    /* Clear devinst data */
+    ZeroMemory(DevInstData, sizeof(DEVINSTDATA));
+    DevInstData->devInfoData.cbSize = 0; /* Tell if the devInfoData is valid */
+
+    /* Fill devinst data */
+    DevInstData->hDevInfo = SetupDiCreateDeviceInfoListExW(NULL, NULL, NULL, NULL);
+    if (DevInstData->hDevInfo == INVALID_HANDLE_VALUE)
+    {
+        TRACE("SetupDiCreateDeviceInfoListExW() failed with error 0x%x\n", GetLastError());
+        goto cleanup;
+    }
+
+    DevInstData->devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
+    ret = SetupDiOpenDeviceInfoW(
+        DevInstData->hDevInfo,
+        InstanceId,
+        NULL,
+        0, /* Open flags */
+        &DevInstData->devInfoData);
+    if (!ret)
+    {
+        TRACE("SetupDiOpenDeviceInfoW() failed with error 0x%x (InstanceId %s)\n",
+            GetLastError(), debugstr_w(InstanceId));
+        DevInstData->devInfoData.cbSize = 0;
+        goto cleanup;
+    }
+
+    SetLastError(ERROR_GEN_FAILURE);
+    ret = SetupDiGetDeviceRegistryProperty(
+        DevInstData->hDevInfo,
+        &DevInstData->devInfoData,
+        SPDRP_DEVICEDESC,
+        &DevInstData->regDataType,
+        NULL, 0,
+        &DevInstData->requiredSize);
+
+    if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER && DevInstData->regDataType == REG_SZ)
+    {
+        DevInstData->buffer = HeapAlloc(GetProcessHeap(), 0, DevInstData->requiredSize);
+        if (!DevInstData->buffer)
+        {
+            TRACE("HeapAlloc() failed\n");
+            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        }
+        else
+        {
+            ret = SetupDiGetDeviceRegistryPropertyW(
+                DevInstData->hDevInfo,
+                &DevInstData->devInfoData,
+                SPDRP_DEVICEDESC,
+                &DevInstData->regDataType,
+                DevInstData->buffer, DevInstData->requiredSize,
+                &DevInstData->requiredSize);
+        }
+    }
+    if (!ret)
+    {
+        TRACE("SetupDiGetDeviceRegistryProperty() failed with error 0x%x (InstanceId %s)\n",
+            GetLastError(), debugstr_w(InstanceId));
+        goto cleanup;
+    }
+
+    if (SetupDiGetDeviceRegistryPropertyW(
+        DevInstData->hDevInfo,
+        &DevInstData->devInfoData,
+        SPDRP_CONFIGFLAGS,
+        NULL,
+        (BYTE *)&config_flags,
+        sizeof(config_flags),
+        NULL))
+    {
+        if (config_flags & CONFIGFLAG_FAILEDINSTALL)
+        {
+            /* The device is disabled */
+            TRACE("Device is disabled\n");
+            retval = TRUE;
+            goto cleanup;
+        }
+    }
+
+    TRACE("Installing %s (%s)\n", debugstr_w((PCWSTR)DevInstData->buffer), debugstr_w(InstanceId));
+
+    /* Search driver in default location and removable devices */
+    if (!PrepareFoldersToScan(DevInstData, FALSE, FALSE, NULL))
+    {
+        TRACE("PrepareFoldersToScan() failed with error 0x%lx\n", GetLastError());
+        goto cleanup;
+    }
+    if (ScanFoldersForDriver(DevInstData))
+    {
+        /* Driver found ; install it */
+        retval = InstallCurrentDriver(DevInstData);
+        TRACE("InstallCurrentDriver() returned %d\n", retval);
+        if (retval && Show != SW_HIDE)
+        {
+            /* Should we display the 'Need to reboot' page? */
+            SP_DEVINSTALL_PARAMS installParams;
+            installParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
+            if (SetupDiGetDeviceInstallParams(
+                DevInstData->hDevInfo,
+                &DevInstData->devInfoData,
+                &installParams))
+            {
+                if (installParams.Flags & (DI_NEEDRESTART | DI_NEEDREBOOT))
+                {
+                    TRACE("Displaying 'Reboot' wizard page\n");
+                    retval = DisplayWizard(DevInstData, hWndParent, IDD_NEEDREBOOT);
+                }
+            }
+        }
+        goto cleanup;
+    }
+    else if (Show == SW_HIDE)
+    {
+        /* We can't show the wizard. Fail the install */
+        TRACE("No wizard\n");
+        goto cleanup;
+    }
+
+    /* Prepare the wizard, and display it */
+    TRACE("Need to show install wizard\n");
+    retval = DisplayWizard(DevInstData, hWndParent, IDD_WELCOMEPAGE);
 
 cleanup:
-       if (DevInstData)
-       {
-               if (DevInstData->devInfoData.cbSize != 0)
-               {
-                       if (!SetupDiDestroyDriverInfoList(DevInstData->hDevInfo, &DevInstData->devInfoData, SPDIT_COMPATDRIVER))
-                               TRACE("SetupDiDestroyDriverInfoList() failed with error 0x%lx\n", GetLastError());
-               }
-               if (DevInstData->hDevInfo != INVALID_HANDLE_VALUE)
-               {
-                       if (!SetupDiDestroyDeviceInfoList(DevInstData->hDevInfo))
-                               TRACE("SetupDiDestroyDeviceInfoList() failed with error 0x%lx\n", GetLastError());
-               }
-               HeapFree(GetProcessHeap(), 0, DevInstData->buffer);
-               HeapFree(GetProcessHeap(), 0, DevInstData);
-       }
-
-       return retval;
+    if (DevInstData)
+    {
+        if (DevInstData->devInfoData.cbSize != 0)
+        {
+            if (!SetupDiDestroyDriverInfoList(DevInstData->hDevInfo, &DevInstData->devInfoData, SPDIT_COMPATDRIVER))
+                TRACE("SetupDiDestroyDriverInfoList() failed with error 0x%lx\n", GetLastError());
+        }
+        if (DevInstData->hDevInfo != INVALID_HANDLE_VALUE)
+        {
+            if (!SetupDiDestroyDeviceInfoList(DevInstData->hDevInfo))
+                TRACE("SetupDiDestroyDeviceInfoList() failed with error 0x%lx\n", GetLastError());
+        }
+        HeapFree(GetProcessHeap(), 0, DevInstData->buffer);
+        HeapFree(GetProcessHeap(), 0, DevInstData);
+    }
+
+    return retval;
 }
 
 /*
@@ -808,9 +809,9 @@ cleanup:
 */
 BOOL WINAPI
 ClientSideInstallW(
-       IN HWND hWndOwner,
-       IN DWORD dwUnknownFlags,
-       IN LPWSTR lpNamedPipeName)
+    IN HWND hWndOwner,
+    IN DWORD dwUnknownFlags,
+    IN LPWSTR lpNamedPipeName)
 {
     BOOL ReturnValue = FALSE;
     BOOL ShowWizard;
@@ -885,21 +886,21 @@ cleanup:
 
 BOOL WINAPI
 DllMain(
-       IN HINSTANCE hInstance,
-       IN DWORD dwReason,
-       IN LPVOID lpReserved)
+    IN HINSTANCE hInstance,
+    IN DWORD dwReason,
+    IN LPVOID lpReserved)
 {
-       if (dwReason == DLL_PROCESS_ATTACH)
-       {
-               INITCOMMONCONTROLSEX InitControls;
+    if (dwReason == DLL_PROCESS_ATTACH)
+    {
+        INITCOMMONCONTROLSEX InitControls;
 
-               DisableThreadLibraryCalls(hInstance);
+        DisableThreadLibraryCalls(hInstance);
 
-               InitControls.dwSize = sizeof(INITCOMMONCONTROLSEX);
-               InitControls.dwICC = ICC_PROGRESS_CLASS;
-               InitCommonControlsEx(&InitControls);
-               hDllInstance = hInstance;
-       }
+        InitControls.dwSize = sizeof(INITCOMMONCONTROLSEX);
+        InitControls.dwICC = ICC_PROGRESS_CLASS;
+        InitCommonControlsEx(&InitControls);
+        hDllInstance = hInstance;
+    }
 
-       return TRUE;
+    return TRUE;
 }