Amovible devices should be checked when doing automatic install

svn path=/trunk/; revision=22146
This commit is contained in:
Hervé Poussineau 2006-06-01 16:25:15 +00:00
parent 76aa2a4fa3
commit bf90c28bb1
3 changed files with 159 additions and 131 deletions

View file

@ -27,6 +27,12 @@ WINE_DEFAULT_DEBUG_CHANNEL(newdev);
/* Global variables */ /* Global variables */
HINSTANCE hDllInstance; HINSTANCE hDllInstance;
static BOOL
SearchDriver(
IN PDEVINSTDATA DevInstData,
IN LPCTSTR Directory OPTIONAL,
IN LPCTSTR InfFile OPTIONAL);
/* /*
* @implemented * @implemented
*/ */
@ -241,7 +247,7 @@ UpdateDriverForPlugAndPlayDevicesA(
} }
/* Directory and InfFile MUST NOT be specified simultaneously */ /* Directory and InfFile MUST NOT be specified simultaneously */
BOOL static BOOL
SearchDriver( SearchDriver(
IN PDEVINSTDATA DevInstData, IN PDEVINSTDATA DevInstData,
IN LPCTSTR Directory OPTIONAL, IN LPCTSTR Directory OPTIONAL,
@ -269,7 +275,10 @@ SearchDriver(
_tcsncpy(DevInstallParams.DriverPath, Directory, MAX_PATH); _tcsncpy(DevInstallParams.DriverPath, Directory, MAX_PATH);
} }
else else
{
DevInstallParams.Flags &= ~DI_ENUMSINGLEINF;
*DevInstallParams.DriverPath = _T('\0'); *DevInstallParams.DriverPath = _T('\0');
}
ret = SetupDiSetDeviceInstallParams( ret = SetupDiSetDeviceInstallParams(
DevInstData->hDevInfo, DevInstData->hDevInfo,
@ -334,7 +343,7 @@ GetFileExt(IN LPTSTR FileName)
return _T(""); return _T("");
} }
BOOL static BOOL
SearchDriverRecursive( SearchDriverRecursive(
IN PDEVINSTDATA DevInstData, IN PDEVINSTDATA DevInstData,
IN LPCTSTR Path) IN LPCTSTR Path)
@ -404,6 +413,118 @@ SearchDriverRecursive(
return retval; return retval;
} }
BOOL
ScanFoldersForDriver(
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.
*/
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;
}
}
}
return result;
}
BOOL
PrepareFoldersToScan(
IN PDEVINSTDATA DevInstData,
IN BOOL IncludeRemovableDevices,
IN BOOL IncludeCustomPath,
IN HWND hwndCombo OPTIONAL)
{
TCHAR drive[] = {'?',':',0};
DWORD dwDrives = 0;
DWORD i;
UINT nType;
DWORD CustomTextLength = 0;
DWORD LengthNeeded = 0;
LPTSTR Buffer;
TRACE("Include removable devices: %s\n", IncludeRemovableDevices ? "yes" : "no");
TRACE("Include custom path : %s\n", IncludeCustomPath ? "yes" : "no");
/* 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 = GetDriveType(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(TCHAR));
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 = GetDriveType(drive);
if (nType == DRIVE_REMOVABLE || nType == DRIVE_CDROM)
{
Buffer += 1 + _stprintf(Buffer, drive);
}
}
}
}
if (IncludeCustomPath)
{
Buffer += 1 + ComboBox_GetText(hwndCombo, Buffer, CustomTextLength);
}
*Buffer = _T('\0');
return TRUE;
}
BOOL BOOL
InstallCurrentDriver( InstallCurrentDriver(
IN PDEVINSTDATA DevInstData) IN PDEVINSTDATA DevInstData)
@ -623,8 +744,13 @@ DevInstallW(
TRACE("Installing %S (%S)\n", DevInstData->buffer, InstanceId); TRACE("Installing %S (%S)\n", DevInstData->buffer, InstanceId);
/* Search driver in default location */ /* Search driver in default location and removable devices */
if (SearchDriver(DevInstData, NULL, NULL)) if (!PrepareFoldersToScan(DevInstData, TRUE, FALSE, NULL))
{
TRACE("PrepareFoldersToScan() failed with error 0x%lx\n", GetLastError());
goto cleanup;
}
if (ScanFoldersForDriver(DevInstData))
{ {
/* Driver found ; install it */ /* Driver found ; install it */
retval = InstallCurrentDriver(DevInstData); retval = InstallCurrentDriver(DevInstData);

View file

@ -36,16 +36,17 @@ typedef struct _DEVINSTDATA
#define WM_INSTALL_FINISHED (WM_USER + 11) #define WM_INSTALL_FINISHED (WM_USER + 11)
/* newdev.c */ /* newdev.c */
BOOL
SearchDriver(
IN PDEVINSTDATA DevInstData,
IN LPCTSTR Directory OPTIONAL,
IN LPCTSTR InfFile OPTIONAL);
BOOL BOOL
SearchDriverRecursive( ScanFoldersForDriver(
IN PDEVINSTDATA DevInstData);
BOOL
PrepareFoldersToScan(
IN PDEVINSTDATA DevInstData, IN PDEVINSTDATA DevInstData,
IN LPCTSTR Path); IN BOOL IncludeRemovableDevices,
IN BOOL IncludeCustomPath,
IN HWND hwndCombo OPTIONAL);
BOOL BOOL
InstallCurrentDriver( InstallCurrentDriver(

View file

@ -176,91 +176,6 @@ StartDevice(
return Ret; return Ret;
} }
static BOOL
PrepareFoldersToScan(
IN PDEVINSTDATA DevInstData,
IN HWND hwndDlg)
{
TCHAR drive[] = {'?',':',0};
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;
}
static DWORD WINAPI static DWORD WINAPI
FindDriverProc( FindDriverProc(
IN LPVOID lpParam) IN LPVOID lpParam)
@ -271,39 +186,7 @@ FindDriverProc(
DevInstData = (PDEVINSTDATA)lpParam; DevInstData = (PDEVINSTDATA)lpParam;
/* Yes, we can safely ignore the problem (if any) */ result = ScanFoldersForDriver(DevInstData);
SetupDiDestroyDriverInfoList(
DevInstData->hDevInfo,
&DevInstData->devInfoData,
SPDIT_COMPATDRIVER);
if (!DevInstData->CustomSearchPath)
{
/* Search in default location */
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) if (result)
{ {
@ -600,7 +483,12 @@ WelcomeDlgProc(
case PSN_WIZNEXT: case PSN_WIZNEXT:
/* Handle a Next button click, if necessary */ /* Handle a Next button click, if necessary */
if (SendDlgItemMessage(hwndDlg, IDC_RADIO_AUTO, BM_GETCHECK, (WPARAM)0, (LPARAM)0) == BST_CHECKED) if (SendDlgItemMessage(hwndDlg, IDC_RADIO_AUTO, BM_GETCHECK, (WPARAM)0, (LPARAM)0) == BST_CHECKED)
PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_SEARCHDRV); {
if (PrepareFoldersToScan(DevInstData, TRUE, FALSE, NULL))
PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_SEARCHDRV);
else
PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSTALLFAILED);
}
return TRUE; return TRUE;
default: default:
@ -748,10 +636,18 @@ CHSourceDlgProc(
SaveCustomPath(GetDlgItem(hwndDlg, IDC_COMBO_PATH)); 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,
IsDlgButtonChecked(hwndDlg, IDC_CHECK_MEDIA),
IsDlgButtonChecked(hwndDlg, IDC_CHECK_PATH),
GetDlgItem(hwndDlg, IDC_COMBO_PATH)))
{
PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_SEARCHDRV); PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_SEARCHDRV);
}
else else
{
PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSTALLFAILED); PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSTALLFAILED);
}
} }
else else
/* FIXME */; /* FIXME */;
@ -832,6 +728,11 @@ SearchDrvDlgProc(
{ {
case PSN_SETACTIVE: case PSN_SETACTIVE:
PropSheet_SetWizButtons(GetParent(hwndDlg), !PSWIZB_NEXT | !PSWIZB_BACK); PropSheet_SetWizButtons(GetParent(hwndDlg), !PSWIZB_NEXT | !PSWIZB_BACK);
/* Yes, we can safely ignore the problem (if any) */
SetupDiDestroyDriverInfoList(
DevInstData->hDevInfo,
&DevInstData->devInfoData,
SPDIT_COMPATDRIVER);
hThread = CreateThread(NULL, 0, FindDriverProc, DevInstData, 0, &dwThreadId); hThread = CreateThread(NULL, 0, FindDriverProc, DevInstData, 0, &dwThreadId);
break; break;