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 along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 /*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS Userinit Logon Application
22 * FILE: base/system/userinit/userinit.c
23 * PROGRAMMERS: Thomas Weidenmueller (w3seek@users.sourceforge.net)
24 * Herv� Poussineau (hpoussin@reactos.org)
25 */
26
27 #include "userinit.h"
28
29 #define CMP_MAGIC 0x01234567
30
31 /* GLOBALS ******************************************************************/
32
33 HINSTANCE hInstance;
34
35
36 /* FUNCTIONS ****************************************************************/
37
38 LONG
ReadRegSzKey(IN HKEY hKey,IN LPCWSTR pszKey,OUT LPWSTR * pValue)39 ReadRegSzKey(
40 IN HKEY hKey,
41 IN LPCWSTR pszKey,
42 OUT LPWSTR *pValue)
43 {
44 LONG rc;
45 DWORD dwType;
46 DWORD cbData = 0;
47 LPWSTR Value;
48
49 TRACE("(%p, %s, %p)\n", hKey, debugstr_w(pszKey), pValue);
50
51 rc = RegQueryValueExW(hKey, pszKey, NULL, &dwType, NULL, &cbData);
52 if (rc != ERROR_SUCCESS)
53 {
54 WARN("RegQueryValueEx(%s) failed with error %lu\n", debugstr_w(pszKey), rc);
55 return rc;
56 }
57 if (dwType != REG_SZ)
58 {
59 WARN("Wrong registry data type (%u vs %u)\n", dwType, REG_SZ);
60 return ERROR_FILE_NOT_FOUND;
61 }
62 Value = (WCHAR*) HeapAlloc(GetProcessHeap(), 0, cbData + sizeof(WCHAR));
63 if (!Value)
64 {
65 WARN("No memory\n");
66 return ERROR_NOT_ENOUGH_MEMORY;
67 }
68 rc = RegQueryValueExW(hKey, pszKey, NULL, NULL, (LPBYTE)Value, &cbData);
69 if (rc != ERROR_SUCCESS)
70 {
71 WARN("RegQueryValueEx(%s) failed with error %lu\n", debugstr_w(pszKey), rc);
72 HeapFree(GetProcessHeap(), 0, Value);
73 return rc;
74 }
75 /* NULL-terminate the string */
76 Value[cbData / sizeof(WCHAR)] = L'\0';
77
78 *pValue = Value;
79 return ERROR_SUCCESS;
80 }
81
82 static BOOL
IsConsoleShell(VOID)83 IsConsoleShell(VOID)
84 {
85 HKEY ControlKey = NULL;
86 LPWSTR SystemStartOptions = NULL;
87 LPWSTR CurrentOption, NextOption; /* Pointers into SystemStartOptions */
88 LONG rc;
89 BOOL ret = FALSE;
90
91 TRACE("()\n");
92
93 rc = RegOpenKeyEx(
94 HKEY_LOCAL_MACHINE,
95 REGSTR_PATH_CURRENT_CONTROL_SET,
96 0,
97 KEY_QUERY_VALUE,
98 &ControlKey);
99 if (rc != ERROR_SUCCESS)
100 {
101 WARN("RegOpenKeyEx() failed with error %lu\n", rc);
102 goto cleanup;
103 }
104
105 rc = ReadRegSzKey(ControlKey, L"SystemStartOptions", &SystemStartOptions);
106 if (rc != ERROR_SUCCESS)
107 {
108 WARN("ReadRegSzKey() failed with error %lu\n", rc);
109 goto cleanup;
110 }
111
112 /* Check for CONSOLE switch in SystemStartOptions */
113 CurrentOption = SystemStartOptions;
114 while (CurrentOption)
115 {
116 NextOption = wcschr(CurrentOption, L' ');
117 if (NextOption)
118 *NextOption = L'\0';
119 if (_wcsicmp(CurrentOption, L"CONSOLE") == 0)
120 {
121 TRACE("Found 'CONSOLE' boot option\n");
122 ret = TRUE;
123 goto cleanup;
124 }
125 CurrentOption = NextOption ? NextOption + 1 : NULL;
126 }
127
128 cleanup:
129 if (ControlKey != NULL)
130 RegCloseKey(ControlKey);
131 HeapFree(GetProcessHeap(), 0, SystemStartOptions);
132 TRACE("IsConsoleShell() returning %d\n", ret);
133 return ret;
134 }
135
136 static BOOL
GetShell(OUT WCHAR * CommandLine,IN HKEY hRootKey)137 GetShell(
138 OUT WCHAR *CommandLine, /* must be at least MAX_PATH long */
139 IN HKEY hRootKey)
140 {
141 HKEY hKey;
142 DWORD Type, Size;
143 WCHAR Shell[MAX_PATH];
144 BOOL ConsoleShell = IsConsoleShell();
145 LONG rc;
146
147 TRACE("(%p, %p)\n", CommandLine, hRootKey);
148
149 rc = RegOpenKeyExW(hRootKey, L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
150 0, KEY_QUERY_VALUE, &hKey);
151 if (rc != ERROR_SUCCESS)
152 {
153 WARN("RegOpenKeyEx() failed with error %lu\n", rc);
154 return FALSE;
155 }
156
157 Size = sizeof(Shell);
158 rc = RegQueryValueExW(hKey,
159 ConsoleShell ? L"ConsoleShell" : L"Shell",
160 NULL,
161 &Type,
162 (LPBYTE)Shell,
163 &Size);
164 RegCloseKey(hKey);
165
166 if (rc != ERROR_SUCCESS)
167 {
168 WARN("RegQueryValueEx() failed with error %lu\n", rc);
169 return FALSE;
170 }
171
172 if ((Type == REG_SZ) || (Type == REG_EXPAND_SZ))
173 {
174 TRACE("Found command line %s\n", debugstr_w(Shell));
175 wcscpy(CommandLine, Shell);
176 return TRUE;
177 }
178 else
179 {
180 WARN("Wrong type %lu (expected %u or %u)\n", Type, REG_SZ, REG_EXPAND_SZ);
181 return FALSE;
182 }
183 }
184
185 static BOOL
StartProcess(IN LPCWSTR CommandLine)186 StartProcess(
187 IN LPCWSTR CommandLine)
188 {
189 STARTUPINFO si;
190 PROCESS_INFORMATION pi;
191 WCHAR ExpandedCmdLine[MAX_PATH];
192
193 TRACE("(%s)\n", debugstr_w(CommandLine));
194
195 ExpandEnvironmentStringsW(CommandLine, ExpandedCmdLine, ARRAYSIZE(ExpandedCmdLine));
196
197 ZeroMemory(&si, sizeof(si));
198 si.cb = sizeof(si);
199 si.dwFlags = STARTF_USESHOWWINDOW;
200 si.wShowWindow = SW_SHOWNORMAL;
201 ZeroMemory(&pi, sizeof(pi));
202
203 if (!CreateProcessW(NULL,
204 ExpandedCmdLine,
205 NULL,
206 NULL,
207 FALSE,
208 NORMAL_PRIORITY_CLASS,
209 NULL,
210 NULL,
211 &si,
212 &pi))
213 {
214 WARN("CreateProcessW() failed with error %lu\n", GetLastError());
215 return FALSE;
216 }
217
218 CloseHandle(pi.hProcess);
219 CloseHandle(pi.hThread);
220 return TRUE;
221 }
222
223 static BOOL
StartShell(VOID)224 StartShell(VOID)
225 {
226 WCHAR Shell[MAX_PATH];
227 WCHAR szMsg[RC_STRING_MAX_SIZE];
228 DWORD Type, Size;
229 DWORD Value = 0;
230 LONG rc;
231 HKEY hKey;
232
233 TRACE("()\n");
234
235 /* Safe Mode shell run */
236 rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
237 L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Option",
238 0, KEY_QUERY_VALUE, &hKey);
239 if (rc == ERROR_SUCCESS)
240 {
241 Size = sizeof(Value);
242 rc = RegQueryValueExW(hKey, L"UseAlternateShell", NULL,
243 &Type, (LPBYTE)&Value, &Size);
244 RegCloseKey(hKey);
245
246 if (rc == ERROR_SUCCESS)
247 {
248 if (Type == REG_DWORD)
249 {
250 if (Value)
251 {
252 /* Safe Mode Alternate Shell required */
253 rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
254 L"SYSTEM\\CurrentControlSet\\Control\\SafeBoot",
255 0, KEY_READ, &hKey);
256 if (rc == ERROR_SUCCESS)
257 {
258 Size = sizeof(Shell);
259 rc = RegQueryValueExW(hKey, L"AlternateShell", NULL,
260 &Type, (LPBYTE)Shell, &Size);
261 RegCloseKey(hKey);
262
263 if (rc == ERROR_SUCCESS)
264 {
265 if ((Type == REG_SZ) || (Type == REG_EXPAND_SZ))
266 {
267 TRACE("Key located - %s\n", debugstr_w(Shell));
268
269 /* Try to run alternate shell */
270 if (StartProcess(Shell))
271 {
272 TRACE("Alternate shell started (Safe Mode)\n");
273 return TRUE;
274 }
275 }
276 else
277 {
278 WARN("Wrong type %lu (expected %u or %u)\n",
279 Type, REG_SZ, REG_EXPAND_SZ);
280 }
281 }
282 else
283 {
284 WARN("Alternate shell in Safe Mode required but not specified.\n");
285 }
286 }
287 }
288 }
289 else
290 {
291 WARN("Wrong type %lu (expected %u)\n", Type, REG_DWORD);
292 }
293 }
294 }
295
296 /* Try to run shell in user key */
297 if (GetShell(Shell, HKEY_CURRENT_USER) && StartProcess(Shell))
298 {
299 TRACE("Started shell from HKEY_CURRENT_USER\n");
300 return TRUE;
301 }
302
303 /* Try to run shell in local machine key */
304 if (GetShell(Shell, HKEY_LOCAL_MACHINE) && StartProcess(Shell))
305 {
306 TRACE("Started shell from HKEY_LOCAL_MACHINE\n");
307 return TRUE;
308 }
309
310 /* Try default shell */
311 if (IsConsoleShell())
312 {
313 *Shell = UNICODE_NULL;
314 if (GetSystemDirectoryW(Shell, ARRAYSIZE(Shell) - 8))
315 StringCchCatW(Shell, ARRAYSIZE(Shell), L"\\");
316 StringCchCatW(Shell, ARRAYSIZE(Shell), L"cmd.exe");
317 }
318 else
319 {
320 *Shell = UNICODE_NULL;
321 if (GetSystemWindowsDirectoryW(Shell, ARRAYSIZE(Shell) - 13))
322 StringCchCatW(Shell, ARRAYSIZE(Shell), L"\\");
323 StringCchCatW(Shell, ARRAYSIZE(Shell), L"explorer.exe");
324 }
325
326 if (!StartProcess(Shell))
327 {
328 WARN("Failed to start default shell '%s'\n", debugstr_w(Shell));
329 LoadStringW(GetModuleHandle(NULL), IDS_SHELL_FAIL, szMsg, ARRAYSIZE(szMsg));
330 MessageBoxW(NULL, szMsg, NULL, MB_OK);
331 return FALSE;
332 }
333 return TRUE;
334 }
335
336 const WCHAR g_RegColorNames[][32] = {
337 L"Scrollbar", /* 00 = COLOR_SCROLLBAR */
338 L"Background", /* 01 = COLOR_DESKTOP */
339 L"ActiveTitle", /* 02 = COLOR_ACTIVECAPTION */
340 L"InactiveTitle", /* 03 = COLOR_INACTIVECAPTION */
341 L"Menu", /* 04 = COLOR_MENU */
342 L"Window", /* 05 = COLOR_WINDOW */
343 L"WindowFrame", /* 06 = COLOR_WINDOWFRAME */
344 L"MenuText", /* 07 = COLOR_MENUTEXT */
345 L"WindowText", /* 08 = COLOR_WINDOWTEXT */
346 L"TitleText", /* 09 = COLOR_CAPTIONTEXT */
347 L"ActiveBorder", /* 10 = COLOR_ACTIVEBORDER */
348 L"InactiveBorder", /* 11 = COLOR_INACTIVEBORDER */
349 L"AppWorkSpace", /* 12 = COLOR_APPWORKSPACE */
350 L"Hilight", /* 13 = COLOR_HIGHLIGHT */
351 L"HilightText", /* 14 = COLOR_HIGHLIGHTTEXT */
352 L"ButtonFace", /* 15 = COLOR_BTNFACE */
353 L"ButtonShadow", /* 16 = COLOR_BTNSHADOW */
354 L"GrayText", /* 17 = COLOR_GRAYTEXT */
355 L"ButtonText", /* 18 = COLOR_BTNTEXT */
356 L"InactiveTitleText", /* 19 = COLOR_INACTIVECAPTIONTEXT */
357 L"ButtonHilight", /* 20 = COLOR_BTNHIGHLIGHT */
358 L"ButtonDkShadow", /* 21 = COLOR_3DDKSHADOW */
359 L"ButtonLight", /* 22 = COLOR_3DLIGHT */
360 L"InfoText", /* 23 = COLOR_INFOTEXT */
361 L"InfoWindow", /* 24 = COLOR_INFOBK */
362 L"ButtonAlternateFace", /* 25 = COLOR_ALTERNATEBTNFACE */
363 L"HotTrackingColor", /* 26 = COLOR_HOTLIGHT */
364 L"GradientActiveTitle", /* 27 = COLOR_GRADIENTACTIVECAPTION */
365 L"GradientInactiveTitle", /* 28 = COLOR_GRADIENTINACTIVECAPTION */
366 L"MenuHilight", /* 29 = COLOR_MENUHILIGHT */
367 L"MenuBar" /* 30 = COLOR_MENUBAR */
368 };
369
370 static COLORREF
StrToColorref(IN LPWSTR lpszCol)371 StrToColorref(
372 IN LPWSTR lpszCol)
373 {
374 BYTE rgb[3];
375
376 TRACE("(%s)\n", debugstr_w(lpszCol));
377
378 rgb[0] = (BYTE)wcstoul(lpszCol, &lpszCol, 10);
379 rgb[1] = (BYTE)wcstoul(lpszCol, &lpszCol, 10);
380 rgb[2] = (BYTE)wcstoul(lpszCol, &lpszCol, 10);
381 return RGB(rgb[0], rgb[1], rgb[2]);
382 }
383
384 static VOID
SetUserSysColors(VOID)385 SetUserSysColors(VOID)
386 {
387 HKEY hKey;
388 INT i;
389 WCHAR szColor[25];
390 DWORD Type, Size;
391 COLORREF crColor;
392 LONG rc;
393
394 TRACE("()\n");
395
396 rc = RegOpenKeyExW(HKEY_CURRENT_USER, REGSTR_PATH_COLORS,
397 0, KEY_QUERY_VALUE, &hKey);
398 if (rc != ERROR_SUCCESS)
399 {
400 WARN("RegOpenKeyEx() failed with error %lu\n", rc);
401 return;
402 }
403
404 for (i = 0; i < ARRAYSIZE(g_RegColorNames); i++)
405 {
406 Size = sizeof(szColor);
407 rc = RegQueryValueExW(hKey, g_RegColorNames[i], NULL, &Type,
408 (LPBYTE)szColor, &Size);
409 if (rc == ERROR_SUCCESS && Type == REG_SZ)
410 {
411 crColor = StrToColorref(szColor);
412 SetSysColors(1, &i, &crColor);
413 }
414 else
415 {
416 WARN("RegQueryValueEx(%s) failed with error %lu\n",
417 debugstr_w(g_RegColorNames[i]), rc);
418 }
419 }
420
421 RegCloseKey(hKey);
422 }
423
424 static VOID
SetUserWallpaper(VOID)425 SetUserWallpaper(VOID)
426 {
427 HKEY hKey;
428 DWORD Type, Size;
429 WCHAR szWallpaper[MAX_PATH + 1];
430 LONG rc;
431
432 TRACE("()\n");
433
434 rc = RegOpenKeyExW(HKEY_CURRENT_USER, REGSTR_PATH_DESKTOP,
435 0, KEY_QUERY_VALUE, &hKey);
436 if (rc != ERROR_SUCCESS)
437 {
438 WARN("RegOpenKeyEx() failed with error %lu\n", rc);
439 return;
440 }
441
442 Size = sizeof(szWallpaper);
443 rc = RegQueryValueExW(hKey,
444 L"Wallpaper",
445 NULL,
446 &Type,
447 (LPBYTE)szWallpaper,
448 &Size);
449 RegCloseKey(hKey);
450
451 if (rc == ERROR_SUCCESS && Type == REG_SZ)
452 {
453 ExpandEnvironmentStringsW(szWallpaper, szWallpaper, ARRAYSIZE(szWallpaper));
454 TRACE("Using wallpaper %s\n", debugstr_w(szWallpaper));
455
456 /* Load and change the wallpaper */
457 SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, szWallpaper, SPIF_SENDCHANGE);
458 }
459 else
460 {
461 /* Remove the wallpaper */
462 TRACE("No wallpaper set in registry (error %lu)\n", rc);
463 SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, NULL, SPIF_SENDCHANGE);
464 }
465 }
466
467 static VOID
SetUserSettings(VOID)468 SetUserSettings(VOID)
469 {
470 TRACE("()\n");
471
472 UpdatePerUserSystemParameters(1, TRUE);
473 SetUserSysColors();
474 SetUserWallpaper();
475 }
476
477 typedef DWORD (WINAPI *PCMP_REPORT_LOGON)(DWORD, DWORD);
478
479 static VOID
NotifyLogon(VOID)480 NotifyLogon(VOID)
481 {
482 HINSTANCE hModule;
483 PCMP_REPORT_LOGON CMP_Report_LogOn;
484
485 TRACE("()\n");
486
487 hModule = LoadLibraryW(L"setupapi.dll");
488 if (!hModule)
489 {
490 WARN("LoadLibrary() failed with error %lu\n", GetLastError());
491 return;
492 }
493
494 CMP_Report_LogOn = (PCMP_REPORT_LOGON)GetProcAddress(hModule, "CMP_Report_LogOn");
495 if (CMP_Report_LogOn)
496 CMP_Report_LogOn(CMP_MAGIC, GetCurrentProcessId());
497 else
498 WARN("GetProcAddress() failed\n");
499
500 FreeLibrary(hModule);
501 }
502
503 static BOOL
StartInstaller(IN LPCTSTR lpInstallerName)504 StartInstaller(IN LPCTSTR lpInstallerName)
505 {
506 SYSTEM_INFO SystemInfo;
507 SIZE_T cchInstallerNameLen;
508 PWSTR ptr;
509 DWORD dwAttribs;
510 WCHAR Installer[MAX_PATH];
511 WCHAR szMsg[RC_STRING_MAX_SIZE];
512
513 cchInstallerNameLen = wcslen(lpInstallerName);
514 if (ARRAYSIZE(Installer) < cchInstallerNameLen)
515 {
516 /* The buffer is not large enough to contain the installer file name */
517 return FALSE;
518 }
519
520 /*
521 * First, try to find the installer using the default drive, under
522 * the directory whose name corresponds to the currently-running
523 * CPU architecture.
524 */
525 GetSystemInfo(&SystemInfo);
526
527 *Installer = UNICODE_NULL;
528 /* Alternatively one can use SharedUserData->NtSystemRoot */
529 GetSystemWindowsDirectoryW(Installer, ARRAYSIZE(Installer) - cchInstallerNameLen - 1);
530 ptr = wcschr(Installer, L'\\');
531 if (ptr)
532 *++ptr = UNICODE_NULL;
533 else
534 *Installer = UNICODE_NULL;
535
536 /* Append the corresponding CPU architecture */
537 switch (SystemInfo.wProcessorArchitecture)
538 {
539 case PROCESSOR_ARCHITECTURE_INTEL:
540 StringCchCatW(Installer, ARRAYSIZE(Installer), L"I386");
541 break;
542
543 case PROCESSOR_ARCHITECTURE_MIPS:
544 StringCchCatW(Installer, ARRAYSIZE(Installer), L"MIPS");
545 break;
546
547 case PROCESSOR_ARCHITECTURE_ALPHA:
548 StringCchCatW(Installer, ARRAYSIZE(Installer), L"ALPHA");
549 break;
550
551 case PROCESSOR_ARCHITECTURE_PPC:
552 StringCchCatW(Installer, ARRAYSIZE(Installer), L"PPC");
553 break;
554
555 case PROCESSOR_ARCHITECTURE_SHX:
556 StringCchCatW(Installer, ARRAYSIZE(Installer), L"SHX");
557 break;
558
559 case PROCESSOR_ARCHITECTURE_ARM:
560 StringCchCatW(Installer, ARRAYSIZE(Installer), L"ARM");
561 break;
562
563 case PROCESSOR_ARCHITECTURE_IA64:
564 StringCchCatW(Installer, ARRAYSIZE(Installer), L"IA64");
565 break;
566
567 case PROCESSOR_ARCHITECTURE_ALPHA64:
568 StringCchCatW(Installer, ARRAYSIZE(Installer), L"ALPHA64");
569 break;
570
571 case PROCESSOR_ARCHITECTURE_AMD64:
572 StringCchCatW(Installer, ARRAYSIZE(Installer), L"AMD64");
573 break;
574
575 // case PROCESSOR_ARCHITECTURE_MSIL: /* .NET CPU-independent code */
576 case PROCESSOR_ARCHITECTURE_UNKNOWN:
577 default:
578 WARN("Unknown processor architecture %lu\n", SystemInfo.wProcessorArchitecture);
579 SystemInfo.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_UNKNOWN;
580 break;
581 }
582
583 if (SystemInfo.wProcessorArchitecture != PROCESSOR_ARCHITECTURE_UNKNOWN)
584 StringCchCatW(Installer, ARRAYSIZE(Installer), L"\\");
585 StringCchCatW(Installer, ARRAYSIZE(Installer), lpInstallerName);
586
587 dwAttribs = GetFileAttributesW(Installer);
588 if ((dwAttribs != INVALID_FILE_ATTRIBUTES) &&
589 !(dwAttribs & FILE_ATTRIBUTE_DIRECTORY))
590 {
591 /* We have found the installer */
592 if (StartProcess(Installer))
593 return TRUE;
594 }
595
596 ERR("Failed to start the installer '%s', trying alternative.\n", debugstr_w(Installer));
597
598 /*
599 * We failed. Try to find the installer from either the current
600 * ReactOS installation directory, or from our current directory.
601 */
602 *Installer = UNICODE_NULL;
603 /* Alternatively one can use SharedUserData->NtSystemRoot */
604 if (GetSystemWindowsDirectoryW(Installer, ARRAYSIZE(Installer) - cchInstallerNameLen - 1))
605 StringCchCatW(Installer, ARRAYSIZE(Installer), L"\\");
606 StringCchCatW(Installer, ARRAYSIZE(Installer), lpInstallerName);
607
608 dwAttribs = GetFileAttributesW(Installer);
609 if ((dwAttribs != INVALID_FILE_ATTRIBUTES) &&
610 !(dwAttribs & FILE_ATTRIBUTE_DIRECTORY))
611 {
612 /* We have found the installer */
613 if (StartProcess(Installer))
614 return TRUE;
615 }
616
617 /* We failed. Display an error message and quit. */
618 ERR("Failed to start the installer '%s'.\n", debugstr_w(Installer));
619 LoadStringW(GetModuleHandle(NULL), IDS_INSTALLER_FAIL, szMsg, ARRAYSIZE(szMsg));
620 MessageBoxW(NULL, szMsg, NULL, MB_OK);
621 return FALSE;
622 }
623
624 /* Used to get the shutdown privilege */
625 static BOOL
EnablePrivilege(LPCWSTR lpszPrivilegeName,BOOL bEnablePrivilege)626 EnablePrivilege(LPCWSTR lpszPrivilegeName, BOOL bEnablePrivilege)
627 {
628 BOOL Success;
629 HANDLE hToken;
630 TOKEN_PRIVILEGES tp;
631
632 Success = OpenProcessToken(GetCurrentProcess(),
633 TOKEN_ADJUST_PRIVILEGES,
634 &hToken);
635 if (!Success) return Success;
636
637 Success = LookupPrivilegeValueW(NULL,
638 lpszPrivilegeName,
639 &tp.Privileges[0].Luid);
640 if (!Success) goto Quit;
641
642 tp.PrivilegeCount = 1;
643 tp.Privileges[0].Attributes = (bEnablePrivilege ? SE_PRIVILEGE_ENABLED : 0);
644
645 Success = AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL);
646
647 Quit:
648 CloseHandle(hToken);
649 return Success;
650 }
651
652
653 int WINAPI
wWinMain(IN HINSTANCE hInst,IN HINSTANCE hPrevInstance,IN LPWSTR lpszCmdLine,IN int nCmdShow)654 wWinMain(IN HINSTANCE hInst,
655 IN HINSTANCE hPrevInstance,
656 IN LPWSTR lpszCmdLine,
657 IN int nCmdShow)
658 {
659 BOOL bIsLiveCD, Success = TRUE;
660 STATE State;
661
662 hInstance = hInst;
663
664 bIsLiveCD = IsLiveCD();
665
666 Restart:
667 SetUserSettings();
668
669 if (bIsLiveCD)
670 {
671 State.NextPage = LOCALEPAGE;
672 State.Run = SHELL;
673 }
674 else
675 {
676 State.NextPage = DONE;
677 State.Run = SHELL;
678 }
679
680 if (State.NextPage != DONE) // && bIsLiveCD
681 {
682 RunLiveCD(&State);
683 }
684
685 switch (State.Run)
686 {
687 case SHELL:
688 Success = StartShell();
689 if (Success)
690 NotifyLogon();
691 break;
692
693 case INSTALLER:
694 Success = StartInstaller(L"reactos.exe");
695 break;
696
697 case REBOOT:
698 {
699 EnablePrivilege(SE_SHUTDOWN_NAME, TRUE);
700 ExitWindowsEx(EWX_REBOOT, 0);
701 EnablePrivilege(SE_SHUTDOWN_NAME, FALSE);
702 Success = TRUE;
703 break;
704 }
705
706 default:
707 Success = FALSE;
708 break;
709 }
710
711 /*
712 * In LiveCD mode, go back to the main menu if we failed
713 * to either start the shell or the installer.
714 */
715 if (bIsLiveCD && !Success)
716 goto Restart;
717
718 return 0;
719 }
720
721 /* EOF */
722