diff --git a/reactos/dll/win32/newdev/newdev.c b/reactos/dll/win32/newdev/newdev.c index dd039603212..82f453d0d8a 100644 --- a/reactos/dll/win32/newdev/newdev.c +++ b/reactos/dll/win32/newdev/newdev.c @@ -27,6 +27,12 @@ WINE_DEFAULT_DEBUG_CHANNEL(newdev); /* Global variables */ HINSTANCE hDllInstance; +static BOOL +SearchDriver( + IN PDEVINSTDATA DevInstData, + IN LPCTSTR Directory OPTIONAL, + IN LPCTSTR InfFile OPTIONAL); + /* * @implemented */ @@ -241,7 +247,7 @@ UpdateDriverForPlugAndPlayDevicesA( } /* Directory and InfFile MUST NOT be specified simultaneously */ -BOOL +static BOOL SearchDriver( IN PDEVINSTDATA DevInstData, IN LPCTSTR Directory OPTIONAL, @@ -269,7 +275,10 @@ SearchDriver( _tcsncpy(DevInstallParams.DriverPath, Directory, MAX_PATH); } else + { + DevInstallParams.Flags &= ~DI_ENUMSINGLEINF; *DevInstallParams.DriverPath = _T('\0'); + } ret = SetupDiSetDeviceInstallParams( DevInstData->hDevInfo, @@ -334,7 +343,7 @@ GetFileExt(IN LPTSTR FileName) return _T(""); } -BOOL +static BOOL SearchDriverRecursive( IN PDEVINSTDATA DevInstData, IN LPCTSTR Path) @@ -404,6 +413,118 @@ SearchDriverRecursive( 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 InstallCurrentDriver( IN PDEVINSTDATA DevInstData) @@ -623,8 +744,13 @@ DevInstallW( TRACE("Installing %S (%S)\n", DevInstData->buffer, InstanceId); - /* Search driver in default location */ - if (SearchDriver(DevInstData, NULL, NULL)) + /* Search driver in default location and removable devices */ + if (!PrepareFoldersToScan(DevInstData, TRUE, FALSE, NULL)) + { + TRACE("PrepareFoldersToScan() failed with error 0x%lx\n", GetLastError()); + goto cleanup; + } + if (ScanFoldersForDriver(DevInstData)) { /* Driver found ; install it */ retval = InstallCurrentDriver(DevInstData); diff --git a/reactos/dll/win32/newdev/newdev_private.h b/reactos/dll/win32/newdev/newdev_private.h index 95fee8e3ead..7ec6c44d8f1 100644 --- a/reactos/dll/win32/newdev/newdev_private.h +++ b/reactos/dll/win32/newdev/newdev_private.h @@ -36,16 +36,17 @@ typedef struct _DEVINSTDATA #define WM_INSTALL_FINISHED (WM_USER + 11) /* newdev.c */ -BOOL -SearchDriver( - IN PDEVINSTDATA DevInstData, - IN LPCTSTR Directory OPTIONAL, - IN LPCTSTR InfFile OPTIONAL); BOOL -SearchDriverRecursive( +ScanFoldersForDriver( + IN PDEVINSTDATA DevInstData); + +BOOL +PrepareFoldersToScan( IN PDEVINSTDATA DevInstData, - IN LPCTSTR Path); + IN BOOL IncludeRemovableDevices, + IN BOOL IncludeCustomPath, + IN HWND hwndCombo OPTIONAL); BOOL InstallCurrentDriver( diff --git a/reactos/dll/win32/newdev/wizard.c b/reactos/dll/win32/newdev/wizard.c index 2c12ea753d0..de920382eef 100644 --- a/reactos/dll/win32/newdev/wizard.c +++ b/reactos/dll/win32/newdev/wizard.c @@ -176,91 +176,6 @@ StartDevice( 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 FindDriverProc( IN LPVOID lpParam) @@ -271,39 +186,7 @@ FindDriverProc( DevInstData = (PDEVINSTDATA)lpParam; - /* Yes, we can safely ignore the problem (if any) */ - 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; - } - } - } + result = ScanFoldersForDriver(DevInstData); if (result) { @@ -600,7 +483,12 @@ WelcomeDlgProc( case PSN_WIZNEXT: /* Handle a Next button click, if necessary */ 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; default: @@ -748,10 +636,18 @@ CHSourceDlgProc( SaveCustomPath(GetDlgItem(hwndDlg, IDC_COMBO_PATH)); HeapFree(GetProcessHeap(), 0, DevInstData->CustomSearchPath); 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); + } else + { PropSheet_SetCurSelByID(GetParent(hwndDlg), IDD_INSTALLFAILED); + } } else /* FIXME */; @@ -832,6 +728,11 @@ SearchDrvDlgProc( { case PSN_SETACTIVE: 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); break;