mirror of
https://github.com/reactos/reactos.git
synced 2025-07-04 12:01:21 +00:00
Allow the user to specify a custom path for the driver when installing a new device
svn path=/trunk/; revision=22051
This commit is contained in:
parent
a10d9d8b2b
commit
57404cf7cf
3 changed files with 218 additions and 48 deletions
|
@ -350,7 +350,6 @@ SearchDriverRecursive(
|
||||||
BOOL retval = FALSE;
|
BOOL retval = FALSE;
|
||||||
HANDLE hFindFile = INVALID_HANDLE_VALUE;
|
HANDLE hFindFile = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
TRACE("SearchDriverRecursive(%s)\n", Path);
|
|
||||||
_tcscpy(DirPath, Path);
|
_tcscpy(DirPath, Path);
|
||||||
|
|
||||||
if (DirPath[_tcsclen(DirPath) - 1] != '\\')
|
if (DirPath[_tcsclen(DirPath) - 1] != '\\')
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include <windowsx.h>
|
||||||
#include <commctrl.h>
|
#include <commctrl.h>
|
||||||
#include <regstr.h>
|
#include <regstr.h>
|
||||||
#include <setupapi.h>
|
#include <setupapi.h>
|
||||||
|
|
|
@ -182,8 +182,83 @@ PrepareFoldersToScan(
|
||||||
IN PDEVINSTDATA DevInstData,
|
IN PDEVINSTDATA DevInstData,
|
||||||
IN HWND hwndDlg)
|
IN HWND hwndDlg)
|
||||||
{
|
{
|
||||||
FIXME("Include removable devices: %s\n", IsDlgButtonChecked(hwndDlg, IDC_CHECK_MEDIA) ? "yes" : "no");
|
TCHAR drive[] = {'?',':',0};
|
||||||
FIXME("Include custom path : %s\n", IsDlgButtonChecked(hwndDlg, IDC_CHECK_PATH) ? "yes" : "no");
|
DWORD dwDrives = 0;
|
||||||
|
DWORD i;
|
||||||
|
UINT nType;
|
||||||
|
DWORD CustomTextLength = 0;
|
||||||
|
DWORD LengthNeeded = 0;
|
||||||
|
LPTSTR Buffer;
|
||||||
|
|
||||||
|
TRACE("Include removable devices: %s\n", IsDlgButtonChecked(hwndDlg, IDC_CHECK_MEDIA) ? "yes" : "no");
|
||||||
|
TRACE("Include custom path : %s\n", IsDlgButtonChecked(hwndDlg, IDC_CHECK_PATH) ? "yes" : "no");
|
||||||
|
|
||||||
|
/* Calculate length needed to store the search paths */
|
||||||
|
if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_MEDIA))
|
||||||
|
{
|
||||||
|
dwDrives = GetLogicalDrives();
|
||||||
|
for (drive[0] = 'A', i = 1; drive[0] <= 'Z'; drive[0]++, i <<= 1)
|
||||||
|
{
|
||||||
|
if (dwDrives & i)
|
||||||
|
{
|
||||||
|
nType = GetDriveType(drive);
|
||||||
|
if (nType == DRIVE_REMOVABLE || nType == DRIVE_CDROM)
|
||||||
|
{
|
||||||
|
LengthNeeded += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_PATH))
|
||||||
|
{
|
||||||
|
CustomTextLength = 1 + SendDlgItemMessage(
|
||||||
|
hwndDlg,
|
||||||
|
IDC_COMBO_PATH,
|
||||||
|
WM_GETTEXTLENGTH,
|
||||||
|
(WPARAM)0,
|
||||||
|
(LPARAM)0);
|
||||||
|
LengthNeeded += CustomTextLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate space for search paths */
|
||||||
|
HeapFree(GetProcessHeap(), 0, DevInstData->CustomSearchPath);
|
||||||
|
DevInstData->CustomSearchPath = Buffer = HeapAlloc(
|
||||||
|
GetProcessHeap(),
|
||||||
|
0,
|
||||||
|
(LengthNeeded + 1) * sizeof(TCHAR));
|
||||||
|
if (!Buffer)
|
||||||
|
{
|
||||||
|
TRACE("HeapAlloc() failed\n");
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill search paths */
|
||||||
|
if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_MEDIA))
|
||||||
|
{
|
||||||
|
for (drive[0] = 'A', i = 1; drive[0] <= 'Z'; drive[0]++, i <<= 1)
|
||||||
|
{
|
||||||
|
if (dwDrives & i)
|
||||||
|
{
|
||||||
|
nType = GetDriveType(drive);
|
||||||
|
if (nType == DRIVE_REMOVABLE || nType == DRIVE_CDROM)
|
||||||
|
{
|
||||||
|
Buffer += 1 + _stprintf(Buffer, drive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (IsDlgButtonChecked(hwndDlg, IDC_CHECK_PATH))
|
||||||
|
{
|
||||||
|
Buffer += 1 + SendDlgItemMessage(
|
||||||
|
hwndDlg,
|
||||||
|
IDC_COMBO_PATH,
|
||||||
|
WM_GETTEXT,
|
||||||
|
(WPARAM)CustomTextLength,
|
||||||
|
(LPARAM)Buffer);
|
||||||
|
}
|
||||||
|
*Buffer = _T('\0');
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,64 +266,151 @@ static DWORD WINAPI
|
||||||
FindDriverProc(
|
FindDriverProc(
|
||||||
IN LPVOID lpParam)
|
IN LPVOID lpParam)
|
||||||
{
|
{
|
||||||
TCHAR drive[] = {'?',':',0};
|
|
||||||
size_t nType;
|
|
||||||
DWORD dwDrives;
|
|
||||||
PDEVINSTDATA DevInstData;
|
PDEVINSTDATA DevInstData;
|
||||||
DWORD config_flags;
|
DWORD config_flags;
|
||||||
UINT i = 1;
|
BOOL result = FALSE;
|
||||||
|
|
||||||
DevInstData = (PDEVINSTDATA)lpParam;
|
DevInstData = (PDEVINSTDATA)lpParam;
|
||||||
DPRINT1("FindDriverProc(%p)\n", DevInstData->CustomSearchPath);
|
|
||||||
if (DevInstData->CustomSearchPath)
|
|
||||||
{
|
|
||||||
LPCTSTR Path;
|
|
||||||
for (Path = DevInstData->CustomSearchPath; *Path != '\0'; Path += _tcslen(Path) + 1)
|
|
||||||
DPRINT1("Path %S\n", Path);
|
|
||||||
}
|
|
||||||
|
|
||||||
dwDrives = GetLogicalDrives();
|
/* Yes, we can safely ignore the problem (if any) */
|
||||||
for (drive[0] = 'A'; drive[0] <= 'Z'; drive[0]++)
|
SetupDiDestroyDriverInfoList(
|
||||||
{
|
|
||||||
if (dwDrives & i)
|
|
||||||
{
|
|
||||||
nType = GetDriveType(drive);
|
|
||||||
if (nType == DRIVE_REMOVABLE || nType == DRIVE_CDROM)
|
|
||||||
{
|
|
||||||
/* search for valid inf file */
|
|
||||||
if (SearchDriverRecursive(DevInstData, drive))
|
|
||||||
{
|
|
||||||
InstallCurrentDriver(DevInstData);
|
|
||||||
PostMessage(DevInstData->hDialog, WM_SEARCH_FINISHED, 1, 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i <<= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* update device configuration */
|
|
||||||
if (SetupDiGetDeviceRegistryProperty(
|
|
||||||
DevInstData->hDevInfo,
|
DevInstData->hDevInfo,
|
||||||
&DevInstData->devInfoData,
|
&DevInstData->devInfoData,
|
||||||
SPDRP_CONFIGFLAGS,
|
SPDIT_COMPATDRIVER);
|
||||||
NULL,
|
|
||||||
(BYTE *)&config_flags,
|
if (!DevInstData->CustomSearchPath)
|
||||||
sizeof(config_flags),
|
|
||||||
NULL))
|
|
||||||
{
|
{
|
||||||
config_flags |= CONFIGFLAG_FAILEDINSTALL;
|
/* Search in default location */
|
||||||
SetupDiSetDeviceRegistryProperty(
|
result = SearchDriver(DevInstData, NULL, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Search only in specified paths */
|
||||||
|
/* We need to check all specified directories to be
|
||||||
|
* sure to find the best driver for the device.
|
||||||
|
*/
|
||||||
|
LPCTSTR Path;
|
||||||
|
for (Path = DevInstData->CustomSearchPath; *Path != '\0'; Path += _tcslen(Path) + 1)
|
||||||
|
{
|
||||||
|
TRACE("Search driver in %S\n", Path);
|
||||||
|
if (_tcslen(Path) == 2 && Path[1] == ':')
|
||||||
|
{
|
||||||
|
if (SearchDriverRecursive(DevInstData, Path))
|
||||||
|
result = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (SearchDriver(DevInstData, Path, NULL))
|
||||||
|
result = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
PostMessage(DevInstData->hDialog, WM_SEARCH_FINISHED, 1, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Update device configuration */
|
||||||
|
if (SetupDiGetDeviceRegistryProperty(
|
||||||
DevInstData->hDevInfo,
|
DevInstData->hDevInfo,
|
||||||
&DevInstData->devInfoData,
|
&DevInstData->devInfoData,
|
||||||
SPDRP_CONFIGFLAGS,
|
SPDRP_CONFIGFLAGS,
|
||||||
(BYTE *)&config_flags, sizeof(config_flags));
|
NULL,
|
||||||
}
|
(BYTE *)&config_flags,
|
||||||
|
sizeof(config_flags),
|
||||||
|
NULL))
|
||||||
|
{
|
||||||
|
config_flags |= CONFIGFLAG_FAILEDINSTALL;
|
||||||
|
SetupDiSetDeviceRegistryProperty(
|
||||||
|
DevInstData->hDevInfo,
|
||||||
|
&DevInstData->devInfoData,
|
||||||
|
SPDRP_CONFIGFLAGS,
|
||||||
|
(BYTE *)&config_flags, sizeof(config_flags));
|
||||||
|
}
|
||||||
|
|
||||||
PostMessage(DevInstData->hDialog, WM_SEARCH_FINISHED, 0, 0);
|
PostMessage(DevInstData->hDialog, WM_SEARCH_FINISHED, 0, 0);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VOID
|
||||||
|
PopulateCustomPathCombo(
|
||||||
|
IN HWND hwndCombo)
|
||||||
|
{
|
||||||
|
HKEY hKey = NULL;
|
||||||
|
DWORD dwRegType;
|
||||||
|
DWORD dwPathLength;
|
||||||
|
LPTSTR Buffer = NULL;
|
||||||
|
LPCTSTR Path;
|
||||||
|
LONG rc;
|
||||||
|
|
||||||
|
ComboBox_ResetContent(hwndCombo);
|
||||||
|
|
||||||
|
/* RegGetValue would have been better... */
|
||||||
|
rc = RegOpenKeyEx(
|
||||||
|
HKEY_LOCAL_MACHINE,
|
||||||
|
REGSTR_PATH_SETUP REGSTR_KEY_SETUP,
|
||||||
|
0,
|
||||||
|
KEY_QUERY_VALUE,
|
||||||
|
&hKey);
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
TRACE("RegOpenKeyEx() failed with error 0x%lx\n", rc);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
rc = RegQueryValueEx(
|
||||||
|
hKey,
|
||||||
|
_T("Installation Sources"),
|
||||||
|
NULL,
|
||||||
|
&dwRegType,
|
||||||
|
NULL,
|
||||||
|
&dwPathLength);
|
||||||
|
if (rc != ERROR_SUCCESS || dwRegType != REG_MULTI_SZ)
|
||||||
|
{
|
||||||
|
TRACE("RegQueryValueEx() failed with error 0x%lx\n", rc);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
/* Allocate enough space to add 2 NULL chars at the end of the string */
|
||||||
|
Buffer = HeapAlloc(GetProcessHeap(), 0, dwPathLength + 2 * sizeof(TCHAR));
|
||||||
|
if (!Buffer)
|
||||||
|
{
|
||||||
|
TRACE("HeapAlloc() failed\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
rc = RegQueryValueEx(
|
||||||
|
hKey,
|
||||||
|
_T("Installation Sources"),
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
(LPBYTE)Buffer,
|
||||||
|
&dwPathLength);
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
TRACE("RegQueryValueEx() failed with error 0x%lx\n", rc);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
Buffer[dwPathLength] = Buffer[dwPathLength + 1] = '\0';
|
||||||
|
|
||||||
|
/* Populate combo box */
|
||||||
|
for (Path = Buffer; *Path; Path += _tcslen(Path))
|
||||||
|
ComboBox_AddString(hwndCombo, Path);
|
||||||
|
ComboBox_SetCurSel(hwndCombo, 0);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (hKey != NULL)
|
||||||
|
RegCloseKey(hKey);
|
||||||
|
HeapFree(GetProcessHeap(), 0, Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID
|
||||||
|
SaveCustomPath(
|
||||||
|
IN HWND hwndCombo)
|
||||||
|
{
|
||||||
|
FIXME("Stub.");
|
||||||
|
}
|
||||||
|
|
||||||
static INT_PTR CALLBACK
|
static INT_PTR CALLBACK
|
||||||
WelcomeDlgProc(
|
WelcomeDlgProc(
|
||||||
IN HWND hwndDlg,
|
IN HWND hwndDlg,
|
||||||
|
@ -382,6 +544,8 @@ CHSourceDlgProc(
|
||||||
dwStyle = GetWindowLong(hwndControl, GWL_STYLE);
|
dwStyle = GetWindowLong(hwndControl, GWL_STYLE);
|
||||||
SetWindowLong(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU);
|
SetWindowLong(hwndControl, GWL_STYLE, dwStyle & ~WS_SYSMENU);
|
||||||
|
|
||||||
|
PopulateCustomPathCombo(GetDlgItem(hwndDlg, IDC_COMBO_PATH));
|
||||||
|
|
||||||
SendDlgItemMessage(
|
SendDlgItemMessage(
|
||||||
hwndDlg,
|
hwndDlg,
|
||||||
IDC_RADIO_SEARCHHERE,
|
IDC_RADIO_SEARCHHERE,
|
||||||
|
@ -393,8 +557,7 @@ CHSourceDlgProc(
|
||||||
|
|
||||||
/* Disable manual driver choice for now */
|
/* Disable manual driver choice for now */
|
||||||
EnableWindow(GetDlgItem(hwndDlg, IDC_RADIO_CHOOSE), FALSE);
|
EnableWindow(GetDlgItem(hwndDlg, IDC_RADIO_CHOOSE), FALSE);
|
||||||
/* Disable custom path for now */
|
|
||||||
EnableWindow(GetDlgItem(hwndDlg, IDC_CHECK_PATH), FALSE);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,10 +600,13 @@ CHSourceDlgProc(
|
||||||
/* Handle a Next button click, if necessary */
|
/* Handle a Next button click, if necessary */
|
||||||
if (IsDlgButtonChecked(hwndDlg, IDC_RADIO_SEARCHHERE))
|
if (IsDlgButtonChecked(hwndDlg, IDC_RADIO_SEARCHHERE))
|
||||||
{
|
{
|
||||||
|
SaveCustomPath(GetDlgItem(hwndDlg, IDC_COMBO_PATH));
|
||||||
HeapFree(GetProcessHeap(), 0, DevInstData->CustomSearchPath);
|
HeapFree(GetProcessHeap(), 0, DevInstData->CustomSearchPath);
|
||||||
DevInstData->CustomSearchPath = NULL;
|
DevInstData->CustomSearchPath = NULL;
|
||||||
if (PrepareFoldersToScan(DevInstData, hwndDlg))
|
if (PrepareFoldersToScan(DevInstData, hwndDlg))
|
||||||
PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_SEARCHDRV);
|
PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_SEARCHDRV);
|
||||||
|
else
|
||||||
|
/* FIXME: unknown error */;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* FIXME */;
|
/* FIXME */;
|
||||||
|
@ -509,7 +675,11 @@ SearchDrvDlgProc(
|
||||||
if (wParam == 0)
|
if (wParam == 0)
|
||||||
PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_NODRIVER);
|
PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_NODRIVER);
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
/* FIXME: Shouldn't belong here... */
|
||||||
|
InstallCurrentDriver(DevInstData);
|
||||||
PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_FINISHPAGE);
|
PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_FINISHPAGE);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue