diff --git a/dll/win32/newdev/newdev.c b/dll/win32/newdev/newdev.c index 960f75212d3..8eade90eb32 100644 --- a/dll/win32/newdev/newdev.c +++ b/dll/win32/newdev/newdev.c @@ -359,7 +359,7 @@ SearchDriverRecursive( wcscat(DirPath, L"\\"); wcscpy(PathWithPattern, DirPath); - wcscat(PathWithPattern, L"\\*"); + wcscat(PathWithPattern, L"*"); for (hFindFile = FindFirstFileW(PathWithPattern, &wfd); ok && hFindFile != INVALID_HANDLE_VALUE; @@ -408,6 +408,14 @@ SearchDriverRecursive( return retval; } +BOOL +CheckBestDriver( + _In_ PDEVINSTDATA DevInstData, + _In_ PCWSTR pszDir) +{ + return SearchDriverRecursive(DevInstData, pszDir); +} + BOOL ScanFoldersForDriver( IN PDEVINSTDATA DevInstData) diff --git a/dll/win32/newdev/newdev_private.h b/dll/win32/newdev/newdev_private.h index baf570c331c..213f0c2865a 100644 --- a/dll/win32/newdev/newdev_private.h +++ b/dll/win32/newdev/newdev_private.h @@ -61,6 +61,11 @@ BOOL InstallCurrentDriver( IN PDEVINSTDATA DevInstData); +BOOL +CheckBestDriver( + _In_ PDEVINSTDATA DevInstData, + _In_ PCWSTR pszDir); + /* wizard.c */ BOOL DisplayWizard( diff --git a/dll/win32/newdev/wizard.c b/dll/win32/newdev/wizard.c index 7cdd4df3960..3dd231a4013 100644 --- a/dll/win32/newdev/wizard.c +++ b/dll/win32/newdev/wizard.c @@ -579,6 +579,38 @@ AutoDriver(HWND Dlg, BOOL Enabled) IncludePath(Dlg, Enabled & IsDlgButtonChecked(Dlg, IDC_CHECK_PATH)); } +static INT CALLBACK +BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData) +{ + BOOL bValid = FALSE; + + switch (uMsg) + { + case BFFM_INITIALIZED: + { + PCWSTR pszPath = ((PDEVINSTDATA)lpData)->CustomSearchPath; + + bValid = CheckBestDriver((PDEVINSTDATA)lpData, pszPath); + SendMessageW(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)pszPath); + SendMessageW(hwnd, BFFM_ENABLEOK, 0, bValid); + break; + } + + case BFFM_SELCHANGED: + { + WCHAR szDir[MAX_PATH]; + + if (SHGetPathFromIDListW((LPITEMIDLIST)lParam, szDir)) + { + bValid = CheckBestDriver((PDEVINSTDATA)lpData, szDir); + } + PostMessageW(hwnd, BFFM_ENABLEOK, 0, bValid); + break; + } + } + return 0; +} + static INT_PTR CALLBACK CHSourceDlgProc( IN HWND hwndDlg, @@ -651,15 +683,33 @@ CHSourceDlgProc( case IDC_BROWSE: { - BROWSEINFO bi = { 0 }; + BROWSEINFOW bi = { 0 }; LPITEMIDLIST pidl; WCHAR Title[MAX_PATH]; + WCHAR CustomSearchPath[MAX_PATH] = { 0 }; + INT len, idx = (INT)SendDlgItemMessageW(hwndDlg, IDC_COMBO_PATH, CB_GETCURSEL, 0, 0); LoadStringW(hDllInstance, IDS_BROWSE_FOR_FOLDER_TITLE, Title, _countof(Title)); + if (idx == CB_ERR) + len = GetWindowTextLengthW(GetDlgItem(hwndDlg, IDC_COMBO_PATH)); + else + len = (INT)SendDlgItemMessageW(hwndDlg, IDC_COMBO_PATH, CB_GETLBTEXTLEN, idx, 0); + + if (len < _countof(CustomSearchPath)) + { + if (idx == CB_ERR) + GetWindowTextW(GetDlgItem(hwndDlg, IDC_COMBO_PATH), CustomSearchPath, _countof(CustomSearchPath)); + else + SendDlgItemMessageW(hwndDlg, IDC_COMBO_PATH, CB_GETLBTEXT, idx, (LPARAM)CustomSearchPath); + } + DevInstData->CustomSearchPath = CustomSearchPath; + bi.hwndOwner = hwndDlg; bi.ulFlags = BIF_USENEWUI | BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT | BIF_NONEWFOLDERBUTTON; bi.lpszTitle = Title; - pidl = SHBrowseForFolder(&bi); + bi.lpfn = BrowseCallbackProc; + bi.lParam = (LPARAM)DevInstData; + pidl = SHBrowseForFolderW(&bi); if (pidl) { WCHAR Directory[MAX_PATH]; diff --git a/dll/win32/shell32/wine/brsfolder.c b/dll/win32/shell32/wine/brsfolder.c index 17a0236b944..d454ecf0f53 100644 --- a/dll/win32/shell32/wine/brsfolder.c +++ b/dll/win32/shell32/wine/brsfolder.c @@ -464,9 +464,17 @@ static void FillTreeView( browse_info *info, IShellFolder * lpsf, IShellFolder_Release(pSFChild); } } +#ifdef __REACTOS__ + if (ulAttrs != (ulAttrs & SFGAO_FOLDER)) + { + if (!InsertTreeViewItem(info, lpsf, pidlTemp, pidl, pEnumIL, hParent)) + goto done; + } +#else if (!InsertTreeViewItem(info, lpsf, pidlTemp, pidl, pEnumIL, hParent)) goto done; +#endif SHFree(pidlTemp); /* Finally, free the pidl that the shell gave us... */ pidlTemp=NULL; } diff --git a/dll/win32/syssetup/wizard.c b/dll/win32/syssetup/wizard.c index 75842349d3e..9afef48c4c5 100644 --- a/dll/win32/syssetup/wizard.c +++ b/dll/win32/syssetup/wizard.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -2880,6 +2881,123 @@ ProcessUnattendSection( } } +static BOOL +PathIsEqual( + IN LPCWSTR lpPath1, + IN LPCWSTR lpPath2) +{ + WCHAR szPath1[MAX_PATH]; + WCHAR szPath2[MAX_PATH]; + + /* If something goes wrong, better return TRUE, + * so the calling function returns early. + */ + if (!PathCanonicalizeW(szPath1, lpPath1)) + return TRUE; + + if (!PathAddBackslashW(szPath1)) + return TRUE; + + if (!PathCanonicalizeW(szPath2, lpPath2)) + return TRUE; + + if (!PathAddBackslashW(szPath2)) + return TRUE; + + return (_wcsicmp(szPath1, szPath2) == 0); +} + +static VOID +AddInstallationSource( + IN HKEY hKey, + IN LPWSTR lpPath) +{ + LONG res; + DWORD dwRegType; + DWORD dwPathLength = 0; + DWORD dwNewLength = 0; + LPWSTR Buffer = NULL; + LPWSTR Path; + + res = RegQueryValueExW( + hKey, + L"Installation Sources", + NULL, + &dwRegType, + NULL, + &dwPathLength); + + if (res != ERROR_SUCCESS || + dwRegType != REG_MULTI_SZ || + dwPathLength == 0 || + dwPathLength % sizeof(WCHAR) != 0) + { + dwPathLength = 0; + goto set; + } + + /* Reserve space for existing data + new string */ + dwNewLength = dwPathLength + (wcslen(lpPath) + 1) * sizeof(WCHAR); + Buffer = HeapAlloc(GetProcessHeap(), 0, dwNewLength); + if (!Buffer) + return; + + ZeroMemory(Buffer, dwNewLength); + + res = RegQueryValueExW( + hKey, + L"Installation Sources", + NULL, + NULL, + (LPBYTE)Buffer, + &dwPathLength); + + if (res != ERROR_SUCCESS) + { + HeapFree(GetProcessHeap(), 0, Buffer); + dwPathLength = 0; + goto set; + } + + /* Sanity check, these should already be zeros */ + Buffer[dwPathLength / sizeof(WCHAR) - 2] = UNICODE_NULL; + Buffer[dwPathLength / sizeof(WCHAR) - 1] = UNICODE_NULL; + + for (Path = Buffer; *Path; Path += wcslen(Path) + 1) + { + /* Check if path is already added */ + if (PathIsEqual(Path, lpPath)) + goto cleanup; + } + + Path = Buffer + dwPathLength / sizeof(WCHAR) - 1; + +set: + if (dwPathLength == 0) + { + dwNewLength = (wcslen(lpPath) + 1 + 1) * sizeof(WCHAR); + Buffer = HeapAlloc(GetProcessHeap(), 0, dwNewLength); + if (!Buffer) + return; + + Path = Buffer; + } + + StringCbCopyW(Path, dwNewLength - (Path - Buffer) * sizeof(WCHAR), lpPath); + Buffer[dwNewLength / sizeof(WCHAR) - 1] = UNICODE_NULL; + + RegSetValueExW( + hKey, + L"Installation Sources", + 0, + REG_MULTI_SZ, + (LPBYTE)Buffer, + dwNewLength); + +cleanup: + HeapFree(GetProcessHeap(), 0, Buffer); +} + VOID ProcessSetupInf( IN OUT PSETUPDATA pSetupData) @@ -2978,6 +3096,8 @@ ProcessSetupInf( NULL); if (res == ERROR_SUCCESS) { + AddInstallationSource(hKey, pSetupData->SourcePath); + res = RegSetValueExW(hKey, L"SourcePath", 0,