Install class installers.
[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.17 2004/10/19 14:33:07 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 (!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
316 if (!InitializeProfiles ())
317 {
318 DebugPrint ("InitializeProfiles() failed\n");
319 return 0;
320 }
321
322 /* Create the semi-random Domain-SID */
323 CreateRandomSid (&DomainSid);
324 if (DomainSid == NULL)
325 {
326 DebugPrint ("Domain-SID creation failed!\n");
327 return 0;
328 }
329
330 #if 0
331 RtlConvertSidToUnicodeString (&SidString, DomainSid, TRUE);
332 DebugPrint ("Domain-SID: %wZ\n", &SidString);
333 RtlFreeUnicodeString (&SidString);
334 #endif
335
336 /* Initialize the Security Account Manager (SAM) */
337 if (!SamInitializeSAM ())
338 {
339 DebugPrint ("SamInitializeSAM() failed!\n");
340 RtlFreeSid (DomainSid);
341 return 0;
342 }
343
344 /* Set the Domain SID (aka Computer SID) */
345 if (!SamSetDomainSid (DomainSid))
346 {
347 DebugPrint ("SamSetDomainSid() failed!\n");
348 RtlFreeSid (DomainSid);
349 return 0;
350 }
351
352 /* Append the Admin-RID */
353 AppendRidToSid(&AdminSid, DomainSid, DOMAIN_USER_RID_ADMIN);
354
355 #if 0
356 RtlConvertSidToUnicodeString (&SidString, DomainSid, TRUE);
357 DebugPrint ("Admin-SID: %wZ\n", &SidString);
358 RtlFreeUnicodeString (&SidString);
359 #endif
360
361 /* Create the Administrator account */
362 if (!SamCreateUser(L"Administrator", L"", AdminSid))
363 {
364 DebugPrint("SamCreateUser() failed!\n");
365 RtlFreeSid(AdminSid);
366 RtlFreeSid(DomainSid);
367 return 0;
368 }
369
370 /* Create the Administrator profile */
371 if (!CreateUserProfileW(AdminSid, L"Administrator"))
372 {
373 DebugPrint("CreateUserProfileW() failed!\n");
374 RtlFreeSid(AdminSid);
375 RtlFreeSid(DomainSid);
376 return 0;
377 }
378
379 RtlFreeSid(AdminSid);
380 RtlFreeSid(DomainSid);
381
382 CreateTempDir(L"TEMP");
383 CreateTempDir(L"TMP");
384
385 hSysSetupInf = SetupOpenInfFileW(L"syssetup.inf",
386 NULL,
387 INF_STYLE_WIN4,
388 NULL);
389 if (hSysSetupInf == INVALID_HANDLE_VALUE)
390 {
391 DebugPrint("SetupOpenInfFileW() failed to open 'syssetup.inf' (Error: %lu)\n", GetLastError());
392 return 0;
393 }
394
395 if (!ProcessSysSetupInf())
396 {
397 DebugPrint("ProcessSysSetupInf() failed!\n");
398 return 0;
399 }
400
401 InstallWizard();
402
403 SetupCloseInfFile(hSysSetupInf);
404
405 #ifdef VMWINST
406 RunVMWInstall();
407 #endif
408
409 DialogBox(hDllInstance,
410 MAKEINTRESOURCE(IDD_RESTART),
411 NULL,
412 RestartDlgProc);
413
414 return 0;
415 }
416
417
418 /*
419 * @unimplemented
420 */
421 DWORD STDCALL
422 SetupChangeFontSize(HANDLE hWnd,
423 LPCWSTR lpszFontSize)
424 {
425 return FALSE;
426 }