[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.
This commit is contained in:
Hermès Bélusca-Maïto 2023-10-16 20:52:31 +02:00
parent b3a25bcf8b
commit 171941ad18
No known key found for this signature in database
GPG Key ID: 3B2539C65E7B93D0

View File

@ -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);