Enable automatic adjustment of daylight savings changes.
[reactos.git] / reactos / lib / syssetup / install.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2003 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 /* $Id: install.c,v 1.18 2004/11/09 15:02:35 ion Exp $
20 *
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS system libraries
23 * PURPOSE: System setup
24 * FILE: lib/syssetup/install.c
25 * PROGRAMER: Eric Kohl
26 */
27
28 /* INCLUDES *****************************************************************/
29
30 #include <ntos.h>
31 #include <windows.h>
32 #include <commctrl.h>
33 #include <stdio.h>
34 #include <tchar.h>
35 #include <stdlib.h>
36
37 #include <samlib.h>
38 #include <syssetup.h>
39 #include <userenv.h>
40 #include <setupapi.h>
41
42 #include "globals.h"
43 #include "resource.h"
44
45 #define VMWINST
46
47 VOID WINAPI CreateCmdLink(VOID);
48
49
50 /* GLOBALS ******************************************************************/
51
52 PSID DomainSid = NULL;
53 PSID AdminSid = NULL;
54
55 HINF hSysSetupInf = INVALID_HANDLE_VALUE;
56
57 /* FUNCTIONS ****************************************************************/
58
59 void
60 DebugPrint(char* fmt,...)
61 {
62 char buffer[512];
63 va_list ap;
64
65 va_start(ap, fmt);
66 vsprintf(buffer, fmt, ap);
67 va_end(ap);
68
69 strcat(buffer, "\nRebooting now!");
70 MessageBoxA(NULL,
71 buffer,
72 "ReactOS Setup",
73 MB_OK);
74 }
75
76
77 #ifdef VMWINST
78 static BOOL
79 RunVMWInstall(VOID)
80 {
81 PROCESS_INFORMATION ProcInfo;
82 STARTUPINFO si;
83
84 ZeroMemory(&si, sizeof(STARTUPINFO));
85 si.cb = sizeof(STARTUPINFO);
86
87 if(CreateProcessA(NULL, "vmwinst.exe", NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS,
88 NULL, NULL, &si, &ProcInfo))
89 {
90 WaitForSingleObject(ProcInfo.hProcess, INFINITE);
91 CloseHandle(ProcInfo.hThread);
92 CloseHandle(ProcInfo.hProcess);
93 return TRUE;
94 }
95 return FALSE;
96 }
97 #endif
98
99
100 static VOID
101 CreateRandomSid (PSID *Sid)
102 {
103 SID_IDENTIFIER_AUTHORITY SystemAuthority = {SECURITY_NT_AUTHORITY};
104 LARGE_INTEGER SystemTime;
105 PULONG Seed;
106
107 NtQuerySystemTime (&SystemTime);
108 Seed = &SystemTime.u.LowPart;
109
110 RtlAllocateAndInitializeSid (&SystemAuthority,
111 4,
112 SECURITY_NT_NON_UNIQUE_RID,
113 RtlUniform (Seed),
114 RtlUniform (Seed),
115 RtlUniform (Seed),
116 SECURITY_NULL_RID,
117 SECURITY_NULL_RID,
118 SECURITY_NULL_RID,
119 SECURITY_NULL_RID,
120 Sid);
121 }
122
123
124 static VOID
125 AppendRidToSid (PSID *Dst,
126 PSID Src,
127 ULONG NewRid)
128 {
129 ULONG Rid[8] = {0, 0, 0, 0, 0, 0, 0, 0};
130 UCHAR RidCount;
131 ULONG i;
132
133 RidCount = *RtlSubAuthorityCountSid (Src);
134
135 for (i = 0; i < RidCount; i++)
136 Rid[i] = *RtlSubAuthoritySid (Src, i);
137
138 if (RidCount < 8)
139 {
140 Rid[RidCount] = NewRid;
141 RidCount++;
142 }
143
144 RtlAllocateAndInitializeSid (RtlIdentifierAuthoritySid (Src),
145 RidCount,
146 Rid[0],
147 Rid[1],
148 Rid[2],
149 Rid[3],
150 Rid[4],
151 Rid[5],
152 Rid[6],
153 Rid[7],
154 Dst);
155 }
156
157 INT_PTR CALLBACK
158 RestartDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
159 {
160 switch(msg)
161 {
162 case WM_INITDIALOG:
163 SendDlgItemMessage(hWnd, IDC_RESTART_PROGRESS, PBM_SETRANGE, 0,
164 MAKELPARAM(0, 300));
165 SetTimer(hWnd, 0, 50, NULL);
166 return TRUE;
167
168 case WM_TIMER:
169 {
170 INT Position;
171 HWND hWndProgress;
172
173 hWndProgress = GetDlgItem(hWnd, IDC_RESTART_PROGRESS);
174 Position = SendMessage(hWndProgress, PBM_GETPOS, 0, 0);
175 if (Position == 300)
176 EndDialog(hWnd, 0);
177 else
178 SendMessage(hWndProgress, PBM_SETPOS, Position + 1, 0);
179 }
180 return TRUE;
181
182 case WM_COMMAND:
183 switch (wParam)
184 {
185 case IDOK:
186 case IDCANCEL:
187 EndDialog(hWnd, 0);
188 return TRUE;
189 }
190 break;
191 }
192
193 return FALSE;
194 }
195
196 static VOID
197 CreateTempDir(LPCWSTR VarName)
198 {
199 WCHAR szTempDir[MAX_PATH];
200 WCHAR szBuffer[MAX_PATH];
201 DWORD dwLength;
202 HKEY hKey;
203
204 if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
205 L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment",
206 0,
207 KEY_ALL_ACCESS,
208 &hKey))
209 {
210 DebugPrint("Error: %lu\n", GetLastError());
211 return;
212 }
213
214 /* Get temp dir */
215 dwLength = MAX_PATH * sizeof(WCHAR);
216 if (RegQueryValueExW (hKey,
217 VarName,
218 NULL,
219 NULL,
220 (LPBYTE)szBuffer,
221 &dwLength))
222 {
223 DebugPrint("Error: %lu\n", GetLastError());
224 RegCloseKey (hKey);
225 return;
226 }
227
228 /* Expand it */
229 if (!ExpandEnvironmentStringsW (szBuffer,
230 szTempDir,
231 MAX_PATH))
232 {
233 DebugPrint("Error: %lu\n", GetLastError());
234 RegCloseKey (hKey);
235 return;
236 }
237
238 /* Create profiles directory */
239 if (!CreateDirectoryW (szTempDir, NULL))
240 {
241 if (GetLastError () != ERROR_ALREADY_EXISTS)
242 {
243 DebugPrint("Error: %lu\n", GetLastError());
244 RegCloseKey (hKey);
245 return;
246 }
247 }
248
249 RegCloseKey (hKey);
250 }
251
252
253 BOOL
254 ProcessSysSetupInf(VOID)
255 {
256 INFCONTEXT InfContext;
257 TCHAR LineBuffer[256];
258 DWORD LineLength;
259
260 if (!SetupFindFirstLine(hSysSetupInf,
261 _T("DeviceInfsToInstall"),
262 NULL,
263 &InfContext))
264 {
265 return FALSE;
266 }
267
268 do
269 {
270 if (!SetupGetStringField(&InfContext,
271 0,
272 LineBuffer,
273 256,
274 &LineLength))
275 {
276 return FALSE;
277 }
278
279 if (!SetupDiInstallClass(NULL, LineBuffer, DI_QUIETINSTALL, NULL))
280 {
281 return FALSE;
282 }
283 }
284 while (SetupFindNextLine(&InfContext, &InfContext));
285
286 return TRUE;
287 }
288
289
290 DWORD STDCALL
291 InstallReactOS (HINSTANCE hInstance)
292 {
293 # if 0
294 OutputDebugStringA ("InstallReactOS() called\n");
295
296 if (!InitializeSetupActionLog (FALSE))
297 {
298 OutputDebugStringA ("InitializeSetupActionLog() failed\n");
299 }
300
301 LogItem (SYSSETUP_SEVERITY_INFORMATION,
302 L"ReactOS Setup starting");
303
304 LogItem (SYSSETUP_SEVERITY_FATAL_ERROR,
305 L"Buuuuuuaaaah!");
306
307 LogItem (SYSSETUP_SEVERITY_INFORMATION,
308 L"ReactOS Setup finished");
309
310 TerminateSetupActionLog ();
311 #endif
312 #if 0
313 UNICODE_STRING SidString;
314 #endif
315 ULONG LastError;
316
317 if (!InitializeProfiles ())
318 {
319 DebugPrint ("InitializeProfiles() failed\n");
320 return 0;
321 }
322
323 /* Create the semi-random Domain-SID */
324 CreateRandomSid (&DomainSid);
325 if (DomainSid == NULL)
326 {
327 DebugPrint ("Domain-SID creation failed!\n");
328 return 0;
329 }
330
331 #if 0
332 RtlConvertSidToUnicodeString (&SidString, DomainSid, TRUE);
333 DebugPrint ("Domain-SID: %wZ\n", &SidString);
334 RtlFreeUnicodeString (&SidString);
335 #endif
336
337 /* Initialize the Security Account Manager (SAM) */
338 if (!SamInitializeSAM ())
339 {
340 DebugPrint ("SamInitializeSAM() failed!\n");
341 RtlFreeSid (DomainSid);
342 return 0;
343 }
344
345 /* Set the Domain SID (aka Computer SID) */
346 if (!SamSetDomainSid (DomainSid))
347 {
348 DebugPrint ("SamSetDomainSid() failed!\n");
349 RtlFreeSid (DomainSid);
350 return 0;
351 }
352
353 /* Append the Admin-RID */
354 AppendRidToSid(&AdminSid, DomainSid, DOMAIN_USER_RID_ADMIN);
355
356 #if 0
357 RtlConvertSidToUnicodeString (&SidString, DomainSid, TRUE);
358 DebugPrint ("Admin-SID: %wZ\n", &SidString);
359 RtlFreeUnicodeString (&SidString);
360 #endif
361
362 /* Create the Administrator account */
363 if (!SamCreateUser(L"Administrator", L"", AdminSid))
364 {
365 /* Check what the error was.
366 * If the Admin Account already exists, then it means Setup
367 * wasn't allowed to finish properly. Instead of rebooting
368 * and not completing it, let it restart instead
369 */
370 LastError = GetLastError();
371 if (LastError != ERROR_USER_EXISTS) {
372 DebugPrint("SamCreateUser() failed!\n");
373 RtlFreeSid(AdminSid);
374 RtlFreeSid(DomainSid);
375 return 0;
376 }
377 }
378
379 /* Create the Administrator profile */
380 if (!CreateUserProfileW(AdminSid, L"Administrator"))
381 {
382 DebugPrint("CreateUserProfileW() failed!\n");
383 RtlFreeSid(AdminSid);
384 RtlFreeSid(DomainSid);
385 return 0;
386 }
387
388 RtlFreeSid(AdminSid);
389 RtlFreeSid(DomainSid);
390
391 CreateTempDir(L"TEMP");
392 CreateTempDir(L"TMP");
393
394 hSysSetupInf = SetupOpenInfFileW(L"syssetup.inf",
395 NULL,
396 INF_STYLE_WIN4,
397 NULL);
398 if (hSysSetupInf == INVALID_HANDLE_VALUE)
399 {
400 DebugPrint("SetupOpenInfFileW() failed to open 'syssetup.inf' (Error: %lu)\n", GetLastError());
401 return 0;
402 }
403
404 if (!ProcessSysSetupInf())
405 {
406 DebugPrint("ProcessSysSetupInf() failed!\n");
407 return 0;
408 }
409
410 InstallWizard();
411
412 SetupCloseInfFile(hSysSetupInf);
413
414 #ifdef VMWINST
415 RunVMWInstall();
416 #endif
417
418 DialogBox(hDllInstance,
419 MAKEINTRESOURCE(IDD_RESTART),
420 NULL,
421 RestartDlgProc);
422
423 return 0;
424 }
425
426
427 /*
428 * @unimplemented
429 */
430 DWORD STDCALL
431 SetupChangeFontSize(HANDLE hWnd,
432 LPCWSTR lpszFontSize)
433 {
434 return FALSE;
435 }