- Add preliminary wizard page title and subtitle string resources.
[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.16 2004/08/28 11:08:50 ekohl 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 0
280 /* FIXME: Currently unsupported */
281 if (!SetupDiInstallClass(NULL, LineBuffer, DI_QUIETINSTALL, NULL))
282 {
283 return FALSE;
284 }
285 #endif
286 }
287 while (SetupFindNextLine(&InfContext, &InfContext));
288
289 return TRUE;
290 }
291
292
293 DWORD STDCALL
294 InstallReactOS (HINSTANCE hInstance)
295 {
296 # if 0
297 OutputDebugStringA ("InstallReactOS() called\n");
298
299 if (!InitializeSetupActionLog (FALSE))
300 {
301 OutputDebugStringA ("InitializeSetupActionLog() failed\n");
302 }
303
304 LogItem (SYSSETUP_SEVERITY_INFORMATION,
305 L"ReactOS Setup starting");
306
307 LogItem (SYSSETUP_SEVERITY_FATAL_ERROR,
308 L"Buuuuuuaaaah!");
309
310 LogItem (SYSSETUP_SEVERITY_INFORMATION,
311 L"ReactOS Setup finished");
312
313 TerminateSetupActionLog ();
314 #endif
315 #if 0
316 UNICODE_STRING SidString;
317 #endif
318
319 if (!InitializeProfiles ())
320 {
321 DebugPrint ("InitializeProfiles() failed\n");
322 return 0;
323 }
324
325 /* Create the semi-random Domain-SID */
326 CreateRandomSid (&DomainSid);
327 if (DomainSid == NULL)
328 {
329 DebugPrint ("Domain-SID creation failed!\n");
330 return 0;
331 }
332
333 #if 0
334 RtlConvertSidToUnicodeString (&SidString, DomainSid, TRUE);
335 DebugPrint ("Domain-SID: %wZ\n", &SidString);
336 RtlFreeUnicodeString (&SidString);
337 #endif
338
339 /* Initialize the Security Account Manager (SAM) */
340 if (!SamInitializeSAM ())
341 {
342 DebugPrint ("SamInitializeSAM() failed!\n");
343 RtlFreeSid (DomainSid);
344 return 0;
345 }
346
347 /* Set the Domain SID (aka Computer SID) */
348 if (!SamSetDomainSid (DomainSid))
349 {
350 DebugPrint ("SamSetDomainSid() failed!\n");
351 RtlFreeSid (DomainSid);
352 return 0;
353 }
354
355 /* Append the Admin-RID */
356 AppendRidToSid(&AdminSid, DomainSid, DOMAIN_USER_RID_ADMIN);
357
358 #if 0
359 RtlConvertSidToUnicodeString (&SidString, DomainSid, TRUE);
360 DebugPrint ("Admin-SID: %wZ\n", &SidString);
361 RtlFreeUnicodeString (&SidString);
362 #endif
363
364 /* Create the Administrator account */
365 if (!SamCreateUser(L"Administrator", L"", AdminSid))
366 {
367 DebugPrint("SamCreateUser() failed!\n");
368 RtlFreeSid(AdminSid);
369 RtlFreeSid(DomainSid);
370 return 0;
371 }
372
373 /* Create the Administrator profile */
374 if (!CreateUserProfileW(AdminSid, L"Administrator"))
375 {
376 DebugPrint("CreateUserProfileW() failed!\n");
377 RtlFreeSid(AdminSid);
378 RtlFreeSid(DomainSid);
379 return 0;
380 }
381
382 RtlFreeSid(AdminSid);
383 RtlFreeSid(DomainSid);
384
385 CreateTempDir(L"TEMP");
386 CreateTempDir(L"TMP");
387
388 hSysSetupInf = SetupOpenInfFileW(L"syssetup.inf",
389 NULL,
390 INF_STYLE_WIN4,
391 NULL);
392 if (hSysSetupInf == INVALID_HANDLE_VALUE)
393 {
394 DebugPrint("SetupOpenInfFileW() failed to open 'syssetup.inf' (Error: %lu)\n", GetLastError());
395 return 0;
396 }
397
398 if (!ProcessSysSetupInf())
399 {
400 DebugPrint("ProcessSysSetupInf() failed!\n");
401 return 0;
402 }
403
404 InstallWizard();
405
406 SetupCloseInfFile(hSysSetupInf);
407
408 #ifdef VMWINST
409 RunVMWInstall();
410 #endif
411
412 DialogBox(hDllInstance,
413 MAKEINTRESOURCE(IDD_RESTART),
414 NULL,
415 RestartDlgProc);
416
417 return 0;
418 }
419
420
421 /*
422 * @unimplemented
423 */
424 DWORD STDCALL
425 SetupChangeFontSize(HANDLE hWnd,
426 LPCWSTR lpszFontSize)
427 {
428 return FALSE;
429 }