- Play default logon sound when logging on
[reactos.git] / reactos / base / system / userinit / userinit.c
1 /*
2 * ReactOS applications
3 * Copyright (C) 2001, 2002 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS Userinit Logon Application
22 * FILE: subsys/system/userinit/userinit.c
23 * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net)
24 * Hervé Poussineau (hpoussin@reactos.org)
25 */
26 #include <windows.h>
27 #include <cfgmgr32.h>
28 #include <regstr.h>
29 #include <shlobj.h>
30 #include <shlwapi.h>
31 #include "resource.h"
32 #include <wine/debug.h>
33 #include <win32k/ntusrtyp.h>
34
35 WINE_DEFAULT_DEBUG_CHANNEL(userinit);
36
37 #define CMP_MAGIC 0x01234567
38
39 /* GLOBALS ******************************************************************/
40
41 /* FUNCTIONS ****************************************************************/
42
43 static LONG
44 ReadRegSzKey(
45 IN HKEY hKey,
46 IN LPCWSTR pszKey,
47 OUT LPWSTR* pValue)
48 {
49 LONG rc;
50 DWORD dwType;
51 DWORD cbData = 0;
52 LPWSTR Value;
53
54 TRACE("(%p, %s, %p)\n", hKey, debugstr_w(pszKey), pValue);
55
56 rc = RegQueryValueExW(hKey, pszKey, NULL, &dwType, NULL, &cbData);
57 if (rc != ERROR_SUCCESS)
58 {
59 WARN("RegQueryValueEx(%s) failed with error %lu\n", debugstr_w(pszKey), rc);
60 return rc;
61 }
62 if (dwType != REG_SZ)
63 {
64 WARN("Wrong registry data type (%u vs %u)\n", dwType, REG_SZ);
65 return ERROR_FILE_NOT_FOUND;
66 }
67 Value = (WCHAR*) HeapAlloc(GetProcessHeap(), 0, cbData + sizeof(WCHAR));
68 if (!Value)
69 {
70 WARN("No memory\n");
71 return ERROR_NOT_ENOUGH_MEMORY;
72 }
73 rc = RegQueryValueExW(hKey, pszKey, NULL, NULL, (LPBYTE)Value, &cbData);
74 if (rc != ERROR_SUCCESS)
75 {
76 WARN("RegQueryValueEx(%s) failed with error %lu\n", debugstr_w(pszKey), rc);
77 HeapFree(GetProcessHeap(), 0, Value);
78 return rc;
79 }
80 /* NULL-terminate the string */
81 Value[cbData / sizeof(WCHAR)] = '\0';
82
83 *pValue = Value;
84 return ERROR_SUCCESS;
85 }
86
87 static
88 BOOL IsConsoleShell(VOID)
89 {
90 HKEY ControlKey = NULL;
91 LPWSTR SystemStartOptions = NULL;
92 LPWSTR CurrentOption, NextOption; /* Pointers into SystemStartOptions */
93 LONG rc;
94 BOOL ret = FALSE;
95
96 TRACE("()\n");
97
98 rc = RegOpenKeyEx(
99 HKEY_LOCAL_MACHINE,
100 REGSTR_PATH_CURRENT_CONTROL_SET,
101 0,
102 KEY_QUERY_VALUE,
103 &ControlKey);
104 if (rc != ERROR_SUCCESS)
105 {
106 WARN("RegOpenKeyEx() failed with error %lu\n", rc);
107 goto cleanup;
108 }
109
110 rc = ReadRegSzKey(ControlKey, L"SystemStartOptions", &SystemStartOptions);
111 if (rc != ERROR_SUCCESS)
112 {
113 WARN("ReadRegSzKey() failed with error %lu\n", rc);
114 goto cleanup;
115 }
116
117 /* Check for CONSOLE in SystemStartOptions */
118 CurrentOption = SystemStartOptions;
119 while (CurrentOption)
120 {
121 NextOption = wcschr(CurrentOption, L' ');
122 if (NextOption)
123 *NextOption = L'\0';
124 if (_wcsicmp(CurrentOption, L"CONSOLE") == 0)
125 {
126 TRACE("Found 'CONSOLE' boot option\n");
127 ret = TRUE;
128 goto cleanup;
129 }
130 CurrentOption = NextOption ? NextOption + 1 : NULL;
131 }
132
133 cleanup:
134 if (ControlKey != NULL)
135 RegCloseKey(ControlKey);
136 HeapFree(GetProcessHeap(), 0, SystemStartOptions);
137 TRACE("IsConsoleShell() returning %d\n", ret);
138 return ret;
139 }
140
141 static
142 BOOL GetShell(
143 OUT WCHAR *CommandLine, /* must be at least MAX_PATH long */
144 IN HKEY hRootKey)
145 {
146 HKEY hKey;
147 DWORD Type, Size;
148 WCHAR Shell[MAX_PATH];
149 BOOL Ret = FALSE;
150 BOOL ConsoleShell = IsConsoleShell();
151 LONG rc;
152
153 TRACE("(%p, %p)\n", CommandLine, hRootKey);
154
155 rc = RegOpenKeyExW(hRootKey, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
156 0, KEY_QUERY_VALUE, &hKey);
157 if (rc == ERROR_SUCCESS)
158 {
159 Size = MAX_PATH * sizeof(WCHAR);
160 rc = RegQueryValueExW(hKey,
161 ConsoleShell ? L"ConsoleShell" : L"Shell",
162 NULL,
163 &Type,
164 (LPBYTE)Shell,
165 &Size);
166 if (rc == ERROR_SUCCESS)
167 {
168 if ((Type == REG_SZ) || (Type == REG_EXPAND_SZ))
169 {
170 TRACE("Found command line %s\n", debugstr_w(Shell));
171 wcscpy(CommandLine, Shell);
172 Ret = TRUE;
173 }
174 else
175 WARN("Wrong type %lu (expected %u or %u)\n", Type, REG_SZ, REG_EXPAND_SZ);
176 }
177 else
178 WARN("RegQueryValueEx() failed with error %lu\n", rc);
179 RegCloseKey(hKey);
180 }
181 else
182 WARN("RegOpenKeyEx() failed with error %lu\n", rc);
183
184 return Ret;
185 }
186
187 static VOID
188 StartAutoApplications(
189 IN INT clsid)
190 {
191 WCHAR szPath[MAX_PATH] = {0};
192 HRESULT hResult;
193 HANDLE hFind;
194 WIN32_FIND_DATAW findData;
195 SHELLEXECUTEINFOW ExecInfo;
196 size_t len;
197
198 TRACE("(%d)\n", clsid);
199
200 hResult = SHGetFolderPathW(NULL, clsid, NULL, SHGFP_TYPE_CURRENT, szPath);
201 len = wcslen(szPath);
202 if (!SUCCEEDED(hResult) || len == 0)
203 {
204 WARN("SHGetFolderPath() failed with error %lu\n", GetLastError());
205 return;
206 }
207
208 wcscat(szPath, L"\\*");
209 hFind = FindFirstFileW(szPath, &findData);
210 if (hFind == INVALID_HANDLE_VALUE)
211 {
212 WARN("FindFirstFile(%s) failed with error %lu\n", debugstr_w(szPath), GetLastError());
213 return;
214 }
215 szPath[len] = L'\0';
216
217 do
218 {
219 if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (findData.nFileSizeHigh || findData.nFileSizeLow))
220 {
221 memset(&ExecInfo, 0x0, sizeof(SHELLEXECUTEINFOW));
222 ExecInfo.cbSize = sizeof(ExecInfo);
223 ExecInfo.lpVerb = L"open";
224 ExecInfo.lpFile = findData.cFileName;
225 ExecInfo.lpDirectory = szPath;
226 TRACE("Executing %s in directory %s\n",
227 debugstr_w(findData.cFileName), debugstr_w(szPath));
228 ShellExecuteExW(&ExecInfo);
229 }
230 } while (FindNextFileW(hFind, &findData));
231 FindClose(hFind);
232 }
233
234 static BOOL
235 TryToStartShell(
236 IN LPCWSTR Shell)
237 {
238 STARTUPINFO si;
239 PROCESS_INFORMATION pi;
240 WCHAR ExpandedShell[MAX_PATH];
241
242 TRACE("(%s)\n", debugstr_w(Shell));
243
244 ZeroMemory(&si, sizeof(STARTUPINFO));
245 si.cb = sizeof(STARTUPINFO);
246 ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
247
248 ExpandEnvironmentStrings(Shell, ExpandedShell, MAX_PATH);
249
250 if (!CreateProcess(NULL,
251 ExpandedShell,
252 NULL,
253 NULL,
254 FALSE,
255 NORMAL_PRIORITY_CLASS,
256 NULL,
257 NULL,
258 &si,
259 &pi))
260 {
261 WARN("CreateProcess() failed with error %lu\n", GetLastError());
262 return FALSE;
263 }
264
265 StartAutoApplications(CSIDL_STARTUP);
266 StartAutoApplications(CSIDL_COMMON_STARTUP);
267 CloseHandle(pi.hProcess);
268 CloseHandle(pi.hThread);
269 return TRUE;
270 }
271
272 static
273 VOID StartShell(VOID)
274 {
275 WCHAR Shell[MAX_PATH];
276 TCHAR szMsg[RC_STRING_MAX_SIZE];
277
278 TRACE("()\n");
279
280 /* Try to run shell in user key */
281 if (GetShell(Shell, HKEY_CURRENT_USER) && TryToStartShell(Shell))
282 {
283 TRACE("Started shell from HKEY_CURRENT_USER\n");
284 return;
285 }
286
287 /* Try to run shell in local machine key */
288 if (GetShell(Shell, HKEY_LOCAL_MACHINE) && TryToStartShell(Shell))
289 {
290 TRACE("Started shell from HKEY_LOCAL_MACHINE\n");
291 return;
292 }
293
294 /* Try default shell */
295 if (IsConsoleShell())
296 {
297 if (GetSystemDirectory(Shell, MAX_PATH - 8))
298 wcscat(Shell, L"\\cmd.exe");
299 else
300 wcscpy(Shell, L"cmd.exe");
301 }
302 else
303 {
304 if (GetWindowsDirectory(Shell, MAX_PATH - 13))
305 wcscat(Shell, L"\\explorer.exe");
306 else
307 wcscpy(Shell, L"explorer.exe");
308 }
309 if (!TryToStartShell(Shell))
310 {
311 WARN("Failed to start default shell %s\n", debugstr_w(Shell));
312 LoadString( GetModuleHandle(NULL), STRING_USERINIT_FAIL, szMsg, sizeof(szMsg) / sizeof(szMsg[0]));
313 MessageBox(0, szMsg, NULL, 0);
314 }
315 }
316
317 const WCHAR g_RegColorNames[][32] = {
318 L"Scrollbar", /* 00 = COLOR_SCROLLBAR */
319 L"Background", /* 01 = COLOR_DESKTOP */
320 L"ActiveTitle", /* 02 = COLOR_ACTIVECAPTION */
321 L"InactiveTitle", /* 03 = COLOR_INACTIVECAPTION */
322 L"Menu", /* 04 = COLOR_MENU */
323 L"Window", /* 05 = COLOR_WINDOW */
324 L"WindowFrame", /* 06 = COLOR_WINDOWFRAME */
325 L"MenuText", /* 07 = COLOR_MENUTEXT */
326 L"WindowText", /* 08 = COLOR_WINDOWTEXT */
327 L"TitleText", /* 09 = COLOR_CAPTIONTEXT */
328 L"ActiveBorder", /* 10 = COLOR_ACTIVEBORDER */
329 L"InactiveBorder", /* 11 = COLOR_INACTIVEBORDER */
330 L"AppWorkSpace", /* 12 = COLOR_APPWORKSPACE */
331 L"Hilight", /* 13 = COLOR_HIGHLIGHT */
332 L"HilightText", /* 14 = COLOR_HIGHLIGHTTEXT */
333 L"ButtonFace", /* 15 = COLOR_BTNFACE */
334 L"ButtonShadow", /* 16 = COLOR_BTNSHADOW */
335 L"GrayText", /* 17 = COLOR_GRAYTEXT */
336 L"ButtonText", /* 18 = COLOR_BTNTEXT */
337 L"InactiveTitleText", /* 19 = COLOR_INACTIVECAPTIONTEXT */
338 L"ButtonHilight", /* 20 = COLOR_BTNHIGHLIGHT */
339 L"ButtonDkShadow", /* 21 = COLOR_3DDKSHADOW */
340 L"ButtonLight", /* 22 = COLOR_3DLIGHT */
341 L"InfoText", /* 23 = COLOR_INFOTEXT */
342 L"InfoWindow", /* 24 = COLOR_INFOBK */
343 L"ButtonAlternateFace", /* 25 = COLOR_ALTERNATEBTNFACE */
344 L"HotTrackingColor", /* 26 = COLOR_HOTLIGHT */
345 L"GradientActiveTitle", /* 27 = COLOR_GRADIENTACTIVECAPTION */
346 L"GradientInactiveTitle", /* 28 = COLOR_GRADIENTINACTIVECAPTION */
347 L"MenuHilight", /* 29 = COLOR_MENUHILIGHT */
348 L"MenuBar" /* 30 = COLOR_MENUBAR */
349 };
350 #define NUM_SYSCOLORS (sizeof(g_RegColorNames) / sizeof(g_RegColorNames[0]))
351
352 static
353 COLORREF StrToColorref(
354 IN LPWSTR lpszCol)
355 {
356 BYTE rgb[3];
357
358 TRACE("(%s)\n", debugstr_w(lpszCol));
359
360 rgb[0] = StrToIntW(lpszCol);
361 lpszCol = StrChrW(lpszCol, L' ') + 1;
362 rgb[1] = StrToIntW(lpszCol);
363 lpszCol = StrChrW(lpszCol, L' ') + 1;
364 rgb[2] = StrToIntW(lpszCol);
365 return RGB(rgb[0], rgb[1], rgb[2]);
366 }
367
368 static
369 VOID SetUserSysColors(VOID)
370 {
371 HKEY hKey;
372 INT i;
373 WCHAR szColor[20];
374 DWORD Type, Size;
375 COLORREF crColor;
376 LONG rc;
377
378 TRACE("()\n");
379
380 rc = RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_COLORS,
381 0, KEY_QUERY_VALUE, &hKey);
382 if (rc != ERROR_SUCCESS)
383 {
384 WARN("RegOpenKeyEx() failed with error %lu\n", rc);
385 return;
386 }
387 for(i = 0; i < NUM_SYSCOLORS; i++)
388 {
389 Size = sizeof(szColor);
390 rc = RegQueryValueEx(hKey, g_RegColorNames[i], NULL, &Type,
391 (LPBYTE)szColor, &Size);
392 if (rc == ERROR_SUCCESS && Type == REG_SZ)
393 {
394 crColor = StrToColorref(szColor);
395 SetSysColors(1, &i, &crColor);
396 }
397 else
398 WARN("RegQueryValueEx(%s) failed with error %lu\n",
399 debugstr_w(g_RegColorNames[i]), rc);
400 }
401 RegCloseKey(hKey);
402 }
403
404 static
405 VOID LoadUserFontSetting(
406 IN LPWSTR lpValueName,
407 OUT PLOGFONTW pFont)
408 {
409 HKEY hKey;
410 LOGFONTW lfTemp;
411 DWORD Type, Size;
412 LONG rc;
413
414 TRACE("(%s, %p)\n", debugstr_w(lpValueName), pFont);
415
416 Size = sizeof(LOGFONTW);
417 rc = RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_METRICS,
418 0, KEY_QUERY_VALUE, &hKey);
419 if (rc != ERROR_SUCCESS)
420 {
421 WARN("RegOpenKeyEx() failed with error %lu\n", rc);
422 return;
423 }
424 rc = RegQueryValueEx(hKey, lpValueName, NULL, &Type, (LPBYTE)&lfTemp, &Size);
425 if (rc != ERROR_SUCCESS || Type != REG_BINARY)
426 {
427 WARN("RegQueryValueEx() failed with error %lu\n", rc);
428 return;
429 }
430 RegCloseKey(hKey);
431 /* FIXME: Check if lfTemp is a valid font */
432 *pFont = lfTemp;
433 }
434
435 static
436 VOID LoadUserMetricSetting(
437 IN LPWSTR lpValueName,
438 OUT INT *pValue)
439 {
440 HKEY hKey;
441 DWORD Type, Size;
442 WCHAR strValue[8];
443 LONG rc;
444
445 TRACE("(%s, %p)\n", debugstr_w(lpValueName), pValue);
446
447 Size = sizeof(strValue);
448 rc = RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_METRICS,
449 0, KEY_QUERY_VALUE, &hKey);
450 if (rc != ERROR_SUCCESS)
451 {
452 WARN("RegOpenKeyEx() failed with error %lu\n", rc);
453 return;
454 }
455 rc = RegQueryValueEx(hKey, lpValueName, NULL, &Type, (LPBYTE)&strValue, &Size);
456 if (rc != ERROR_SUCCESS || Type != REG_SZ)
457 {
458 WARN("RegQueryValueEx() failed with error %lu\n", rc);
459 return;
460 }
461 RegCloseKey(hKey);
462 *pValue = StrToInt(strValue);
463 }
464
465 static
466 VOID SetUserMetrics(VOID)
467 {
468 NONCLIENTMETRICSW ncmetrics;
469 MINIMIZEDMETRICS mmmetrics;
470
471 TRACE("()\n");
472
473 ncmetrics.cbSize = sizeof(NONCLIENTMETRICSW);
474 mmmetrics.cbSize = sizeof(MINIMIZEDMETRICS);
475 SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSW), &ncmetrics, 0);
476 SystemParametersInfoW(SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &mmmetrics, 0);
477
478 LoadUserFontSetting(L"CaptionFont", &ncmetrics.lfCaptionFont);
479 LoadUserFontSetting(L"SmCaptionFont", &ncmetrics.lfSmCaptionFont);
480 LoadUserFontSetting(L"MenuFont", &ncmetrics.lfMenuFont);
481 LoadUserFontSetting(L"StatusFont", &ncmetrics.lfStatusFont);
482 LoadUserFontSetting(L"MessageFont", &ncmetrics.lfMessageFont);
483 /* FIXME: load icon font ? */
484
485 LoadUserMetricSetting(L"BorderWidth", &ncmetrics.iBorderWidth);
486 LoadUserMetricSetting(L"ScrollWidth", &ncmetrics.iScrollWidth);
487 LoadUserMetricSetting(L"ScrollHeight", &ncmetrics.iScrollHeight);
488 LoadUserMetricSetting(L"CaptionWidth", &ncmetrics.iCaptionWidth);
489 LoadUserMetricSetting(L"CaptionHeight", &ncmetrics.iCaptionHeight);
490 LoadUserMetricSetting(L"SmCaptionWidth", &ncmetrics.iSmCaptionWidth);
491 LoadUserMetricSetting(L"SmCaptionHeight", &ncmetrics.iSmCaptionHeight);
492 LoadUserMetricSetting(L"Menuwidth", &ncmetrics.iMenuWidth);
493 LoadUserMetricSetting(L"MenuHeight", &ncmetrics.iMenuHeight);
494
495 SystemParametersInfoW(SPI_SETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSW), &ncmetrics, 0);
496 }
497
498 static
499 VOID SetUserWallpaper(VOID)
500 {
501 HKEY hKey;
502 DWORD Type, Size;
503 WCHAR szWallpaper[MAX_PATH + 1];
504 LONG rc;
505
506 TRACE("()\n");
507
508 rc = RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_DESKTOP,
509 0, KEY_QUERY_VALUE, &hKey);
510 if (rc == ERROR_SUCCESS)
511 {
512 Size = sizeof(szWallpaper);
513 rc = RegQueryValueEx(hKey,
514 L"Wallpaper",
515 NULL,
516 &Type,
517 (LPBYTE)szWallpaper,
518 &Size);
519 if (rc == ERROR_SUCCESS && Type == REG_SZ)
520 {
521 ExpandEnvironmentStrings(szWallpaper, szWallpaper, MAX_PATH);
522 TRACE("Using wallpaper %s\n", debugstr_w(szWallpaper));
523
524 /* Load and change the wallpaper */
525 SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, szWallpaper, SPIF_SENDCHANGE);
526 }
527 else
528 {
529 /* remove the wallpaper */
530 TRACE("No wallpaper set in registry (error %lu)\n", rc);
531 SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, NULL, SPIF_SENDCHANGE);
532 }
533 RegCloseKey(hKey);
534 }
535 else
536 WARN("RegOpenKeyEx() failed with error %lu\n", rc);
537 }
538
539 static VOID SetUserPreference(UINT uiAction,BOOL bValue,UINT fWinIni)
540 {
541 DWORD dwvalue = bValue;
542 SystemParametersInfo(uiAction, 0, (PVOID)&dwvalue, fWinIni);
543 }
544
545 static VOID SetUserPreferences(VOID)
546 {
547 HKEY hKey;
548 DWORD Type, Size;
549 LONG rc;
550 USERPREFERENCESMASK Preferences;
551
552 TRACE("()\n");
553
554 rc = RegOpenKeyEx(HKEY_CURRENT_USER, REGSTR_PATH_DESKTOP,
555 0, KEY_QUERY_VALUE, &hKey);
556 if (rc == ERROR_SUCCESS)
557 {
558 Size = sizeof(USERPREFERENCESMASK);
559 ERR("USERPREFERENCESMASK size: %d\n",Size);
560
561 rc = RegQueryValueEx(hKey,
562 L"UserPreferencesMask",
563 NULL,
564 &Type,
565 (LPBYTE)&Preferences,
566 &Size);
567 if (rc == ERROR_SUCCESS && Type == REG_BINARY)
568 {
569 SetUserPreference(SPI_SETUIEFFECTS, Preferences.bUiEffects, SPIF_SENDCHANGE);
570 SetUserPreference(SPI_SETACTIVEWINDOWTRACKING, Preferences.bActiveWindowTracking, SPIF_SENDCHANGE);
571 SetUserPreference(SPI_SETMENUANIMATION, Preferences.bMenuAnimation, SPIF_SENDCHANGE);
572 SetUserPreference(SPI_SETCOMBOBOXANIMATION, Preferences.bComboBoxAnimation, SPIF_SENDCHANGE);
573 SetUserPreference(SPI_SETLISTBOXSMOOTHSCROLLING, Preferences.bListBoxSmoothScrolling, SPIF_SENDCHANGE);
574 SetUserPreference(SPI_SETGRADIENTCAPTIONS, Preferences.bGradientCaptions, SPIF_SENDCHANGE);
575 SetUserPreference(SPI_SETKEYBOARDCUES, Preferences.bKeyboardCues, SPIF_SENDCHANGE);
576 SetUserPreference(SPI_SETACTIVEWNDTRKZORDER, Preferences.bActiveWndTrkZorder, SPIF_SENDCHANGE);
577 SetUserPreference(SPI_SETHOTTRACKING, Preferences.bHotTracking, SPIF_SENDCHANGE);
578 SetUserPreference(SPI_SETMENUFADE, Preferences.bMenuFade, SPIF_SENDCHANGE);
579 SetUserPreference(SPI_SETSELECTIONFADE, Preferences.bSelectionFade, SPIF_SENDCHANGE);
580 SetUserPreference(SPI_SETTOOLTIPANIMATION, Preferences.bTooltipAnimation, SPIF_SENDCHANGE);
581 SetUserPreference(SPI_SETTOOLTIPFADE, Preferences.bTooltipFade, SPIF_SENDCHANGE);
582 SetUserPreference(SPI_SETCURSORSHADOW, Preferences.bCursorShadow, SPIF_SENDCHANGE);
583 }
584 else
585 {
586 ERR("No User Preferences set in registry or incorrect type (error %lu)\n", rc);
587 }
588 RegCloseKey(hKey);
589 }
590 else
591 WARN("RegOpenKeyEx() failed with error %lu\n", rc);
592 }
593
594 static VOID
595 PlayLogonSound()
596 {
597 HKEY hKey;
598 WCHAR szBuffer[MAX_PATH] = {0};
599 WCHAR szDest[MAX_PATH];
600 DWORD dwSize = sizeof(szBuffer);
601 HMODULE hLibrary;
602 typedef BOOL WINAPI (*PLAYSOUNDW)(LPCWSTR,HMODULE,DWORD);
603 PLAYSOUNDW Play;
604
605 if (RegOpenKeyExW(HKEY_CURRENT_USER, L"AppEvents\\Schemes\\Apps\\.Default\\WindowsLogon\\.Current", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
606 {
607 return;
608 }
609
610 if (RegQueryValueExW(hKey, NULL, NULL, NULL, (LPBYTE)szBuffer, &dwSize) != ERROR_SUCCESS)
611 {
612 RegCloseKey(hKey);
613 return;
614 }
615
616
617 RegCloseKey(hKey);
618
619 if (!szBuffer[0])
620 return;
621
622
623 szBuffer[MAX_PATH-1] = L'\0';
624 if (ExpandEnvironmentStringsW(szBuffer, szDest, MAX_PATH))
625 {
626 hLibrary = LoadLibraryW(L"winmm.dll");
627 if (hLibrary)
628 {
629 Play = (PLAYSOUNDW)GetProcAddress(hLibrary, "PlaySoundW");
630 if (Play)
631 {
632 Play(szDest, NULL, SND_FILENAME);
633 }
634 FreeLibrary(hLibrary);
635 }
636 }
637 }
638
639 static
640 VOID SetUserSettings(VOID)
641 {
642 TRACE("()\n");
643
644 SetUserSysColors();
645 SetUserMetrics();
646 SetUserWallpaper();
647 SetUserPreferences();
648 }
649
650 typedef DWORD (WINAPI *PCMP_REPORT_LOGON)(DWORD, DWORD);
651
652 static VOID
653 NotifyLogon(VOID)
654 {
655 HINSTANCE hModule;
656 PCMP_REPORT_LOGON CMP_Report_LogOn;
657
658 TRACE("()\n");
659
660 hModule = LoadLibrary(L"setupapi.dll");
661 if (hModule)
662 {
663 CMP_Report_LogOn = (PCMP_REPORT_LOGON)GetProcAddress(hModule, "CMP_Report_LogOn");
664 if (CMP_Report_LogOn)
665 CMP_Report_LogOn(CMP_MAGIC, GetCurrentProcessId());
666 else
667 WARN("GetProcAddress() failed\n");
668
669 FreeLibrary(hModule);
670 }
671 else
672 WARN("LoadLibrary() failed with error %lu\n", GetLastError());
673 }
674
675 #ifdef _MSC_VER
676 #pragma warning(disable : 4100)
677 #endif /* _MSC_VER */
678
679 int WINAPI
680 wWinMain(IN HINSTANCE hInst,
681 IN HINSTANCE hPrevInstance,
682 IN LPWSTR lpszCmdLine,
683 IN int nCmdShow)
684 {
685 SetUserSettings();
686 StartShell();
687 NotifyLogon();
688 PlayLogonSound();
689 return 0;
690 }
691
692 /* EOF */