From 171941ad185893f848bf915e869d5d3622695489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Mon, 16 Oct 2023 20:52:31 +0200 Subject: [PATCH] [DESK] Add the current screensaver in the list if it isn't already present (#5766) - Introduce AddScreenSaver[Item] helpers for adding screensavers in the list (either given by file path or by item structure). - Rename "AddScreenSavers" to "EnumScreenSavers", and "ScreenSaverItem" type to "SCREEN_SAVER_ITEM". - Ensure the stored "SCRNSAVE.EXE" value is NULL-terminated. - Add the current screensaver, specified by the "SCRNSAVE.EXE" registry value, in the list if it isn't already present; otherwise select it in the list. - Make the filename comparison case-insensitive. --- dll/cpl/desk/screensaver.c | 351 ++++++++++++++++++------------------- 1 file changed, 172 insertions(+), 179 deletions(-) diff --git a/dll/cpl/desk/screensaver.c b/dll/cpl/desk/screensaver.c index 549422e5492..b99b35b5827 100644 --- a/dll/cpl/desk/screensaver.c +++ b/dll/cpl/desk/screensaver.c @@ -16,15 +16,15 @@ static const TCHAR szPreviewWndClass[] = TEXT("SSDemoParent"); typedef struct { - BOOL bIsScreenSaver; /* Is this background a wallpaper */ + BOOL bIsScreenSaver; /* Is this a valid screensaver */ TCHAR szFilename[MAX_PATH]; TCHAR szDisplayName[256]; -} ScreenSaverItem; +} SCREEN_SAVER_ITEM; typedef struct _DATA { - ScreenSaverItem ScreenSaverItems[MAX_SCREENSAVERS]; + SCREEN_SAVER_ITEM ScreenSaverItems[MAX_SCREENSAVERS]; PROCESS_INFORMATION PrevWindowPi; int Selection; WNDPROC OldPreviewProc; @@ -411,136 +411,149 @@ CheckRegScreenSaverIsSecure(HWND hwndDlg) } -static VOID -SearchScreenSavers(HWND hwndScreenSavers, - LPCTSTR pszSearchPath, - PDATA pData) +static BOOL +AddScreenSaverItem( + _In_ HWND hwndScreenSavers, + _In_ PDATA pData, + _In_ SCREEN_SAVER_ITEM* ScreenSaverItem) { - WIN32_FIND_DATA fd; - TCHAR szSearchPath[MAX_PATH]; - HANDLE hFind; - ScreenSaverItem *ScreenSaverItem; - HANDLE hModule; - UINT i, ScreenSaverCount; + UINT i; + + if (pData->ScreenSaverCount >= MAX_SCREENSAVERS) + return FALSE; + + i = SendMessage(hwndScreenSavers, + CB_ADDSTRING, + 0, + (LPARAM)ScreenSaverItem->szDisplayName); + if ((i == CB_ERR) || (i == CB_ERRSPACE)) + return FALSE; + + SendMessage(hwndScreenSavers, + CB_SETITEMDATA, + i, + (LPARAM)pData->ScreenSaverCount); + + pData->ScreenSaverCount++; + return TRUE; +} + +static BOOL +AddScreenSaver( + _In_ HWND hwndScreenSavers, + _In_ PDATA pData, + _In_ LPCTSTR pszFilePath, + _In_ LPCTSTR pszFileName) +{ + SCREEN_SAVER_ITEM* ScreenSaverItem; + HANDLE hModule; HRESULT hr; - ScreenSaverCount = pData->ScreenSaverCount; + if (pData->ScreenSaverCount >= MAX_SCREENSAVERS) + return FALSE; - hr = StringCbCopy(szSearchPath, sizeof(szSearchPath), pszSearchPath); + ScreenSaverItem = pData->ScreenSaverItems + pData->ScreenSaverCount; + + ScreenSaverItem->bIsScreenSaver = TRUE; + + hModule = LoadLibraryEx(pszFilePath, + NULL, + DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE); + if (hModule) + { + if (LoadString(hModule, + 1, + ScreenSaverItem->szDisplayName, + _countof(ScreenSaverItem->szDisplayName)) == 0) + { + /* If the string does not exist, copy the file name */ + hr = StringCbCopy(ScreenSaverItem->szDisplayName, + sizeof(ScreenSaverItem->szDisplayName), + pszFileName); + if (FAILED(hr)) + { + FreeLibrary(hModule); + return FALSE; + } + /* Remove the .scr extension */ + ScreenSaverItem->szDisplayName[_tcslen(pszFileName)-4] = _T('\0'); + } + FreeLibrary(hModule); + } + else + { + hr = StringCbCopy(ScreenSaverItem->szDisplayName, + sizeof(ScreenSaverItem->szDisplayName), + _T("Unknown")); + if (FAILED(hr)) + return FALSE; + } + + hr = StringCbCopy(ScreenSaverItem->szFilename, + sizeof(ScreenSaverItem->szFilename), + pszFilePath); if (FAILED(hr)) - return; - hr = StringCbCat(szSearchPath, sizeof(szSearchPath), TEXT("\\*.scr")); + return FALSE; + + return AddScreenSaverItem(hwndScreenSavers, pData, ScreenSaverItem); +} + +static VOID +SearchScreenSavers( + _In_ HWND hwndScreenSavers, + _In_ PDATA pData, + _In_ LPCTSTR pszSearchPath) +{ + HRESULT hr; + WIN32_FIND_DATA fd; + HANDLE hFind; + TCHAR szFilePath[MAX_PATH]; + + hr = StringCbPrintf(szFilePath, sizeof(szFilePath), + TEXT("%s\\*.scr"), pszSearchPath); if (FAILED(hr)) return; - hFind = FindFirstFile(szSearchPath, &fd); - + hFind = FindFirstFile(szFilePath, &fd); if (hFind == INVALID_HANDLE_VALUE) return; - while (ScreenSaverCount < MAX_SCREENSAVERS) + do { /* Don't add any hidden screensavers */ - if ((fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) == 0) - { - TCHAR filename[MAX_PATH]; + if (fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) + continue; - hr = StringCbCopy(filename, sizeof(filename), pszSearchPath); - if (FAILED(hr)) - { - FindClose(hFind); - return; - } - hr = StringCbCat(filename, sizeof(filename), _T("\\")); - if (FAILED(hr)) - { - FindClose(hFind); - return; - } - hr = StringCbCat(filename, sizeof(filename), fd.cFileName); - if (FAILED(hr)) - { - FindClose(hFind); - return; - } - - ScreenSaverItem = pData->ScreenSaverItems + ScreenSaverCount; - - ScreenSaverItem->bIsScreenSaver = TRUE; - - hModule = LoadLibraryEx(filename, - NULL, - DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE); - if (hModule) - { - if (0 == LoadString(hModule, - 1, - ScreenSaverItem->szDisplayName, - sizeof(ScreenSaverItem->szDisplayName) / sizeof(TCHAR))) - { - // If the string does not exists, copy the name of the file - hr = StringCbCopy(ScreenSaverItem->szDisplayName, sizeof(ScreenSaverItem->szDisplayName), fd.cFileName); - if (FAILED(hr)) - { - FreeLibrary(hModule); - FindClose(hFind); - return; - } - ScreenSaverItem->szDisplayName[_tcslen(fd.cFileName)-4] = '\0'; - } - FreeLibrary(hModule); - } - else - { - hr = StringCbCopy(ScreenSaverItem->szDisplayName, sizeof(ScreenSaverItem->szDisplayName), _T("Unknown")); - if (FAILED(hr)) - { - FindClose(hFind); - return; - } - } - - hr = StringCbCopy(ScreenSaverItem->szFilename, sizeof(ScreenSaverItem->szFilename), filename); - if (FAILED(hr)) - { - FindClose(hFind); - return; - } - - i = SendMessage(hwndScreenSavers, - CB_ADDSTRING, - 0, - (LPARAM)ScreenSaverItem->szDisplayName); - - SendMessage(hwndScreenSavers, - CB_SETITEMDATA, - i, - (LPARAM)ScreenSaverCount); - - ScreenSaverCount++; - } - - if (!FindNextFile(hFind, &fd)) + if (pData->ScreenSaverCount >= MAX_SCREENSAVERS) break; - } + + hr = StringCbPrintf(szFilePath, sizeof(szFilePath), + TEXT("%s\\%s"), pszSearchPath, fd.cFileName); + if (FAILED(hr)) + break; + + if (!AddScreenSaver(hwndScreenSavers, pData, szFilePath, fd.cFileName)) + break; + + } while (FindNextFile(hFind, &fd)); FindClose(hFind); - - pData->ScreenSaverCount = ScreenSaverCount; } - static VOID -AddScreenSavers(HWND hwndDlg, PDATA pData) +EnumScreenSavers( + _In_ HWND hwndScreenSavers, + _In_ PDATA pData) { - HWND hwndScreenSavers = GetDlgItem(hwndDlg, IDC_SCREENS_LIST); + SCREEN_SAVER_ITEM* ScreenSaverItem; + PTCHAR pBackSlash; TCHAR szSearchPath[MAX_PATH]; TCHAR szLocalPath[MAX_PATH]; - INT i; - ScreenSaverItem *ScreenSaverItem = NULL; - LPTSTR lpBackSlash; - /* Add the "None" item */ + /* Initialize the number of list items */ + pData->ScreenSaverCount = 0; + + /* Add the "(None)" item */ ScreenSaverItem = pData->ScreenSaverItems; ScreenSaverItem->bIsScreenSaver = FALSE; @@ -548,39 +561,28 @@ AddScreenSavers(HWND hwndDlg, PDATA pData) LoadString(hApplet, IDS_NONE, ScreenSaverItem->szDisplayName, - sizeof(ScreenSaverItem->szDisplayName) / sizeof(TCHAR)); + _countof(ScreenSaverItem->szDisplayName)); - i = SendMessage(hwndScreenSavers, - CB_ADDSTRING, - 0, - (LPARAM)ScreenSaverItem->szDisplayName); + AddScreenSaverItem(hwndScreenSavers, pData, ScreenSaverItem); - SendMessage(hwndScreenSavers, - CB_SETITEMDATA, - i, - (LPARAM)0); - - // Initialize number of items into the list - pData->ScreenSaverCount = 1; - - // Add all the screensavers where the applet is stored. - GetModuleFileName(hApplet, szLocalPath, MAX_PATH); - lpBackSlash = _tcsrchr(szLocalPath, _T('\\')); - if (lpBackSlash != NULL) + /* Add all the screensavers where the applet is stored */ + GetModuleFileName(hApplet, szLocalPath, _countof(szLocalPath)); + pBackSlash = _tcsrchr(szLocalPath, _T('\\')); + if (pBackSlash != NULL) { - *lpBackSlash = '\0'; - SearchScreenSavers(hwndScreenSavers, szLocalPath, pData); + *pBackSlash = _T('\0'); + SearchScreenSavers(hwndScreenSavers, pData, szLocalPath); } - // Add all the screensavers in the C:\ReactOS\System32 directory. - GetSystemDirectory(szSearchPath, MAX_PATH); - if (lpBackSlash != NULL && _tcsicmp(szSearchPath, szLocalPath) != 0) - SearchScreenSavers(hwndScreenSavers, szSearchPath, pData); + /* Add all the screensavers in the C:\ReactOS\System32 directory */ + GetSystemDirectory(szSearchPath, _countof(szSearchPath)); + if (pBackSlash != NULL && _tcsicmp(szSearchPath, szLocalPath) != 0) + SearchScreenSavers(hwndScreenSavers, pData, szSearchPath); - // Add all the screensavers in the C:\ReactOS directory. - GetWindowsDirectory(szSearchPath, MAX_PATH); - if (lpBackSlash != NULL && _tcsicmp(szSearchPath, szLocalPath) != 0) - SearchScreenSavers(hwndScreenSavers, szSearchPath, pData); + /* Add all the screensavers in the C:\ReactOS directory */ + GetWindowsDirectory(szSearchPath, _countof(szSearchPath)); + if (pBackSlash != NULL && _tcsicmp(szSearchPath, szLocalPath) != 0) + SearchScreenSavers(hwndScreenSavers, pData, szSearchPath); } @@ -606,7 +608,7 @@ SetScreenSaver(HWND hwndDlg, PDATA pData) /* Set the screensaver */ if (pData->ScreenSaverItems[pData->Selection].bIsScreenSaver) { - SIZE_T Length = _tcslen(pData->ScreenSaverItems[pData->Selection].szFilename) * sizeof(TCHAR); + SIZE_T Length = (_tcslen(pData->ScreenSaverItems[pData->Selection].szFilename) + 1) * sizeof(TCHAR); RegSetValueEx(regKey, _T("SCRNSAVE.EXE"), 0, @@ -658,9 +660,9 @@ SetScreenSaver(HWND hwndDlg, PDATA pData) static BOOL OnInitDialog(HWND hwndDlg, PDATA pData) { - LPTSTR lpCurSs; HWND hwndSSCombo = GetDlgItem(hwndDlg, IDC_SCREENS_LIST); - INT Num; + LPTSTR pSsValue; + INT iCurSs; WNDCLASS wc = {0}; pData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DATA)); @@ -712,76 +714,67 @@ OnInitDialog(HWND hwndDlg, PDATA pData) IDC_SCREENS_TIME, UDM_SETRANGE, 0, - MAKELONG - ((short) 240, (short) 1)); + MAKELONG(240, 1)); - AddScreenSavers(hwndDlg, - pData); + EnumScreenSavers(hwndSSCombo, pData); CheckRegScreenSaverIsSecure(hwndDlg); /* Set the current screensaver in the combo box */ - lpCurSs = GetCurrentScreenSaverValue(_T("SCRNSAVE.EXE")); - if (lpCurSs) + iCurSs = 0; // Default to "(None)" + pSsValue = GetCurrentScreenSaverValue(_T("SCRNSAVE.EXE")); + if (pSsValue) { BOOL bFound = FALSE; INT i; - for (i = 0; i < MAX_SCREENSAVERS; i++) + /* Find whether the current screensaver is in the list */ + for (i = 0; i < pData->ScreenSaverCount; i++) { - if (!_tcscmp(lpCurSs, pData->ScreenSaverItems[i].szFilename)) + if (!_tcsicmp(pSsValue, pData->ScreenSaverItems[i].szFilename)) { bFound = TRUE; break; } } + if (!bFound) + { + /* The current screensaver is not in the list: add it */ + // i = pData->ScreenSaverCount; + bFound = AddScreenSaver(hwndSSCombo, pData, pSsValue, _T("SCRNSAVE.EXE")); + if (bFound) + i = pData->ScreenSaverCount - 1; + } + + HeapFree(GetProcessHeap(), 0, pSsValue); + if (bFound) { - Num = SendMessage(hwndSSCombo, - CB_FINDSTRINGEXACT, - -1, - (LPARAM)pData->ScreenSaverItems[i].szDisplayName); - if (Num != CB_ERR) - SendMessage(hwndSSCombo, - CB_SETCURSEL, - Num, - 0); + /* The current screensaver should be in the list: select it */ + iCurSs = SendMessage(hwndSSCombo, + CB_FINDSTRINGEXACT, + -1, + (LPARAM)pData->ScreenSaverItems[i].szDisplayName); + if (iCurSs == CB_ERR) + iCurSs = 0; // Default to "(None)" } - else - { - SendMessage(hwndSSCombo, - CB_SETCURSEL, - 0, - 0); - } - - HeapFree(GetProcessHeap(), 0, lpCurSs); - } - else - { - /* Set screensaver to (none) */ - SendMessage(hwndSSCombo, - CB_SETCURSEL, - 0, - 0); } + SendMessage(hwndSSCombo, CB_SETCURSEL, iCurSs, 0); /* Set the current timeout */ - lpCurSs = GetCurrentScreenSaverValue(_T("ScreenSaveTimeOut")); - if (lpCurSs) + pSsValue = GetCurrentScreenSaverValue(_T("ScreenSaveTimeOut")); + if (pSsValue) { - UINT Time = _ttoi(lpCurSs); + UINT Time = _ttoi(pSsValue) / 60; - Time /= 60; + HeapFree(GetProcessHeap(), 0, pSsValue); SendDlgItemMessage(hwndDlg, IDC_SCREENS_TIME, UDM_SETPOS32, 0, Time); - - HeapFree(GetProcessHeap(), 0, lpCurSs); } SelectionChanged(hwndDlg, pData);