3 * Copyright (C) 2001, 2002 ReactOS Team
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.
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.
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.
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)
32 #define CMP_MAGIC 0x01234567
34 /* GLOBALS ******************************************************************/
36 /* FUNCTIONS ****************************************************************/
49 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, &dwType
, NULL
, &cbData
);
50 if (rc
!= ERROR_SUCCESS
)
53 return ERROR_FILE_NOT_FOUND
;
54 Value
= (WCHAR
*) HeapAlloc(GetProcessHeap(), 0, cbData
+ sizeof(WCHAR
));
56 return ERROR_NOT_ENOUGH_MEMORY
;
57 rc
= RegQueryValueExW(hKey
, pszKey
, NULL
, NULL
, (LPBYTE
)Value
, &cbData
);
58 if (rc
!= ERROR_SUCCESS
)
60 HeapFree(GetProcessHeap(), 0, Value
);
63 /* NULL-terminate the string */
64 Value
[cbData
/ sizeof(WCHAR
)] = '\0';
71 BOOL
IsConsoleShell(void)
73 HKEY ControlKey
= NULL
;
74 LPWSTR SystemStartOptions
= NULL
;
75 LPWSTR CurrentOption
, NextOption
; /* Pointers into SystemStartOptions */
81 REGSTR_PATH_CURRENT_CONTROL_SET
,
86 rc
= ReadRegSzKey(ControlKey
, L
"SystemStartOptions", &SystemStartOptions
);
87 if (rc
!= ERROR_SUCCESS
)
90 /* Check for CMDCONS in SystemStartOptions */
91 CurrentOption
= SystemStartOptions
;
94 NextOption
= wcschr(CurrentOption
, L
' ');
97 if (wcsicmp(CurrentOption
, L
"CMDCONS") == 0)
102 CurrentOption
= NextOption
? NextOption
+ 1 : NULL
;
106 if (ControlKey
!= NULL
)
107 RegCloseKey(ControlKey
);
108 HeapFree(GetProcessHeap(), 0, SystemStartOptions
);
113 BOOL
GetShell(WCHAR
*CommandLine
, HKEY hRootKey
)
117 WCHAR Shell
[MAX_PATH
];
119 BOOL ConsoleShell
= IsConsoleShell();
121 if(RegOpenKeyEx(hRootKey
,
122 REGSTR_PATH_WINLOGON
,
123 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
125 Size
= MAX_PATH
* sizeof(WCHAR
);
126 if(RegQueryValueEx(hKey
,
127 ConsoleShell
? L
"ConsoleShell" : L
"Shell",
131 &Size
) == ERROR_SUCCESS
)
133 if((Type
== REG_SZ
) || (Type
== REG_EXPAND_SZ
))
135 wcscpy(CommandLine
, Shell
);
146 StartAutoApplications(int clsid
)
148 WCHAR szPath
[MAX_PATH
] = {0};
151 WIN32_FIND_DATAW findData
;
152 SHELLEXECUTEINFOW ExecInfo
;
155 hResult
= SHGetFolderPathW(NULL
, clsid
, NULL
, SHGFP_TYPE_CURRENT
, szPath
);
156 len
= wcslen(szPath
);
157 if (!SUCCEEDED(hResult
) || len
== 0)
162 wcscat(szPath
, L
"\\*");
163 hFind
= FindFirstFileW(szPath
, &findData
);
164 if (hFind
== INVALID_HANDLE_VALUE
)
172 if (!(findData
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) && (findData
.nFileSizeHigh
|| findData
.nFileSizeLow
))
174 memset(&ExecInfo
, 0x0, sizeof(SHELLEXECUTEINFOW
));
175 ExecInfo
.cbSize
= sizeof(ExecInfo
);
176 ExecInfo
.lpVerb
= L
"open";
177 ExecInfo
.lpFile
= findData
.cFileName
;
178 ExecInfo
.lpDirectory
= szPath
;
179 ShellExecuteExW(&ExecInfo
);
181 }while(FindNextFileW(hFind
, &findData
));
187 TryToStartShell(LPCWSTR Shell
)
190 PROCESS_INFORMATION pi
;
191 WCHAR ExpandedShell
[MAX_PATH
];
193 ZeroMemory(&si
, sizeof(STARTUPINFO
));
194 si
.cb
= sizeof(STARTUPINFO
);
195 ZeroMemory(&pi
, sizeof(PROCESS_INFORMATION
));
197 ExpandEnvironmentStrings(Shell
, ExpandedShell
, MAX_PATH
);
199 if(!CreateProcess(NULL
,
204 NORMAL_PRIORITY_CLASS
,
211 StartAutoApplications(CSIDL_STARTUP
);
212 StartAutoApplications(CSIDL_COMMON_STARTUP
);
213 WaitForSingleObject(pi
.hProcess
, INFINITE
);
214 CloseHandle(pi
.hProcess
);
215 CloseHandle(pi
.hThread
);
220 void StartShell(void)
222 WCHAR Shell
[MAX_PATH
];
223 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
225 /* Try to run shell in user key */
226 if (GetShell(Shell
, HKEY_CURRENT_USER
) && TryToStartShell(Shell
))
229 /* Try to run shell in local machine key */
230 if (GetShell(Shell
, HKEY_LOCAL_MACHINE
) && TryToStartShell(Shell
))
233 /* Try default shell */
234 if (IsConsoleShell())
236 if(GetSystemDirectory(Shell
, MAX_PATH
- 8))
237 wcscat(Shell
, L
"\\cmd.exe");
239 wcscpy(Shell
, L
"cmd.exe");
243 if(GetWindowsDirectory(Shell
, MAX_PATH
- 13))
244 wcscat(Shell
, L
"\\explorer.exe");
246 wcscpy(Shell
, L
"explorer.exe");
248 if (!TryToStartShell(Shell
))
250 LoadString( GetModuleHandle(NULL
), STRING_USERINIT_FAIL
, szMsg
, sizeof(szMsg
) / sizeof(szMsg
[0]));
251 MessageBox(0, szMsg
, NULL
, 0);
256 void SetUserSettings(void)
260 WCHAR szWallpaper
[MAX_PATH
+ 1];
262 if(RegOpenKeyEx(HKEY_CURRENT_USER
,
264 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
266 Size
= sizeof(szWallpaper
);
267 if(RegQueryValueEx(hKey
,
272 &Size
) == ERROR_SUCCESS
275 /* Load and change the wallpaper */
276 SystemParametersInfo(SPI_SETDESKWALLPAPER
, 0, szWallpaper
, SPIF_SENDCHANGE
);
280 /* remove the wallpaper */
281 SystemParametersInfo(SPI_SETDESKWALLPAPER
, 0, NULL
, SPIF_SENDCHANGE
);
288 typedef DWORD (WINAPI
*PCMP_REPORT_LOGON
)(DWORD
, DWORD
);
294 PCMP_REPORT_LOGON CMP_Report_LogOn
;
296 hModule
= LoadLibrary(L
"setupapi.dll");
299 CMP_Report_LogOn
= (PCMP_REPORT_LOGON
)GetProcAddress(hModule
, "CMP_Report_LogOn");
300 if (CMP_Report_LogOn
)
301 CMP_Report_LogOn(CMP_MAGIC
, GetCurrentProcessId());
303 FreeLibrary(hModule
);
310 #pragma warning(disable : 4100)
311 #endif /* _MSC_VER */
314 WinMain(HINSTANCE hInst
,
315 HINSTANCE hPrevInstance
,