#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;
}
/*
*/
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;
}
/*
*/
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);
+
+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;
+}
+
+
+BOOL
+WINAPI
+InstallDevInstEx(
+ IN HWND hWndParent,
+ IN LPCWSTR InstanceId,
+ IN BOOL bUpdate,
+ OUT LPDWORD lpReboot,
+ IN DWORD Unknown)
{
- 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;
+ BOOL retval = FALSE;
+
+ TRACE("InstllDevInstEx(%p, %s, %d, %p, %lx)\n",
+ hWndParent, debugstr_w(InstanceId), bUpdate, lpReboot, Unknown);
+
+ 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 */
+ DevInstData->bUpdate = bUpdate;
+
+ /* 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;
+ }
+
+ /* 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;
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+InstallDevInst(
+ IN HWND hWndParent,
+ IN LPCWSTR InstanceId,
+ IN BOOL bUpdate,
+ OUT LPDWORD lpReboot)
+{
+ return InstallDevInstEx(hWndParent, InstanceId, bUpdate, lpReboot, 0);
}
+
/*
* @implemented
*/
BOOL WINAPI
ClientSideInstallW(
- IN HWND hWndOwner,
- IN DWORD dwUnknownFlags,
- IN LPWSTR lpNamedPipeName)
+ IN HWND hWndOwner,
+ IN HINSTANCE hInstance,
+ IN LPWSTR lpNamedPipeName,
+ IN INT Show)
{
BOOL ReturnValue = FALSE;
BOOL ShowWizard;
HANDLE hPipe = INVALID_HANDLE_VALUE;
PWSTR DeviceInstance = NULL;
PWSTR InstallEventName = NULL;
+ HANDLE hInstallEvent;
/* Open the pipe */
hPipe = CreateFileW(lpNamedPipeName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
}
ReturnValue = DevInstallW(NULL, NULL, DeviceInstance, ShowWizard ? SW_SHOWNOACTIVATE : SW_HIDE);
+ if(!ReturnValue)
+ {
+ ERR("DevInstallW failed with error %lu\n", GetLastError());
+ goto cleanup;
+ }
+
+ hInstallEvent = CreateEventW(NULL, TRUE, FALSE, InstallEventName);
+ if(!hInstallEvent)
+ {
+ TRACE("CreateEventW('%ls') failed with error %lu\n", InstallEventName, GetLastError());
+ goto cleanup;
+ }
+
+ SetEvent(hInstallEvent);
+ CloseHandle(hInstallEvent);
cleanup:
if(hPipe != INVALID_HANDLE_VALUE)
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;
}