https://git.reactos.org/?p=reactos.git;a=commitdiff;h=45c8e4dcd022fdec232a9…
commit 45c8e4dcd022fdec232a9644d717bf466ac05f5c
Author: Jose Carlos Jesus <zecarlos1957(a)hotmail.com>
AuthorDate: Sun Nov 27 15:00:46 2022 +0000
Commit: GitHub <noreply(a)github.com>
CommitDate: Sun Nov 27 18:00:46 2022 +0300
[NEWDEV][SHELL32][SYSSETUP] Improve browse driver folder dialog (#4293)
[NEWDEV] Enable OK button in "Browse For Folder" only when driver is found
Implement BrowseCallbackProc() function which sends BFFM_ENABLEOK message
to the browse dialog whether the driver is found in the selected folder.
Pass the search path to the browse dialog depending on the current index
of the drop down combobox. If the index is not set, just get window text.
Then, automatically expand the tree view to the specified path by sending
BFFM_SETSELECTION message.
Also fix a bug in SearchDriverRecursive() where a duplicate backslash
was added to the PathWithPattern string variable.
[SHELL32] Do not add Recycle Bin to the tree view items in FillTreeView()
[SYSSETUP] Add source path to the "Installation Sources" multi-string key
Each time the ProcessSetupInf() is being called, add the source path
to the "Installation Sources" registry key, if it's not added there
yet.
The driver search path combobox will be then populated using its value.
---
dll/win32/newdev/newdev.c | 10 +++-
dll/win32/newdev/newdev_private.h | 5 ++
dll/win32/newdev/wizard.c | 54 ++++++++++++++++-
dll/win32/shell32/wine/brsfolder.c | 8 +++
dll/win32/syssetup/wizard.c | 120 +++++++++++++++++++++++++++++++++++++
5 files changed, 194 insertions(+), 3 deletions(-)
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 <windowsx.h>
#include <wincon.h>
#include <shlobj.h>
+#include <shlwapi.h>
#include <tzlib.h>
#include <strsafe.h>
@@ -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,