]> cygwin.com Git - cygwin-apps/setup.git/blame - main.cc
2003-02-28 Max Bowsher <maxb@ukf.net>
[cygwin-apps/setup.git] / main.cc
CommitLineData
adaa168a 1 /*
23c9e63c
DD
2 * Copyright (c) 2000, Red Hat, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
11 *
12 * Written by DJ Delorie <dj@cygnus.com>
13 *
14 */
15
16/* OK, here's how this works. Each of the steps needed for install -
17 dialogs, downloads, installs - are in their own files and have some
18 "do_*" function (prototype in dialog.h) and a resource id (IDD_* or
19 IDD_S_* in resource.h) for that step. Each step is responsible for
20 selecting the next step! See the NEXT macro in dialog.h. Note
21 that the IDD_S_* ids are fake; those are for steps that don't
22 really have a controlling dialog (some have progress dialogs, but
23 those don't count, although they could). Replace the IDD_S_* with
24 IDD_* if you create a real dialog for those steps. */
25
b24c88b3
RC
26#if 0
27static const char *cvsid =
28 "\n%%% $Id$\n";
29#endif
8507f105 30
23c9e63c 31#include "win32.h"
ab57ceaa 32#include <commctrl.h>
23c9e63c
DD
33
34#include <stdio.h>
89b1a15b 35#include <stdlib.h>
23c9e63c
DD
36#include "resource.h"
37#include "dialog.h"
38#include "state.h"
39#include "msg.h"
23c9e63c
DD
40#include "find.h"
41#include "mount.h"
9f4a0c62 42#include "LogFile.h"
7cc06fd3 43#include "version.h"
89b1a15b
DD
44
45#include "port.h"
ab57ceaa
RC
46#include "proppage.h"
47#include "propsheet.h"
48
49// Page class headers
50#include "splash.h"
f9e903a3 51#include "AntiVirus.h"
ab57ceaa
RC
52#include "source.h"
53#include "root.h"
54#include "localdir.h"
55#include "net.h"
56#include "site.h"
57#include "choose.h"
58#include "threebar.h"
59#include "desktop.h"
23c9e63c 60
6908b7d7 61#include "getopt++/GetOption.h"
f2ff9838 62#include "getopt++/BoolOption.h"
1be8f8fd 63
23c9e63c
DD
64int next_dialog;
65
66HINSTANCE hinstance;
67
f2ff9838
RC
68static BoolOption UnattendedOption (false, 'q', "quiet-mode", "Unattended setup mode");
69
acbae401
CV
70/* Maximum size of a SID on NT/W2K. */
71#define MAX_SID_LEN 40
72
73/* Computes the size of an ACL in relation to the number of ACEs it
74 should contain. */
75#define TOKEN_ACL_SIZE(cnt) (sizeof(ACL) + \
76 (cnt) * (sizeof(ACCESS_ALLOWED_ACE) + MAX_SID_LEN))
77
78#define iswinnt (GetVersion() < 0x80000000)
79
80void
adaa168a 81set_default_sec ()
acbae401
CV
82{
83 /* To assure that the created files have a useful ACL, the
b24c88b3
RC
84 default DACL in the process token is set to full access to
85 everyone. This applies to files and subdirectories created
86 in directories which don't propagate permissions to child
adaa168a
MB
87 objects.
88 To assure that the files group is meaningful, a token primary
89 group of None is changed to Users or Administrators. */
acbae401
CV
90
91 /* Create a buffer which has enough room to contain the TOKEN_DEFAULT_DACL
92 structure plus an ACL with one ACE. */
93 char buf[sizeof (TOKEN_DEFAULT_DACL) + TOKEN_ACL_SIZE (1)];
94
95 /* First initialize the TOKEN_DEFAULT_DACL structure. */
96 PTOKEN_DEFAULT_DACL dacl = (PTOKEN_DEFAULT_DACL) buf;
97 dacl->DefaultDacl = (PACL) (buf + sizeof *dacl);
98
99 /* Initialize the ACL for containing one ACE. */
100 if (!InitializeAcl (dacl->DefaultDacl, TOKEN_ACL_SIZE (1), ACL_REVISION))
101 {
9f4a0c62
RC
102 log (LOG_TIMESTAMP) << "InitializeAcl() failed: " << GetLastError ()
103 << endLog;
acbae401
CV
104 return;
105 }
106
adaa168a
MB
107 PSID esid = NULL, asid = NULL, usid = NULL;
108 HANDLE token = NULL;
109 struct {
110 PSID psid;
111 char buf[MAX_SID_LEN];
112 } gsid;
113 char lsid[MAX_SID_LEN];
114 char compname[MAX_COMPUTERNAME_LENGTH + 1];
115 char domain[MAX_COMPUTERNAME_LENGTH + 1];
116 DWORD size;
117
b24c88b3 118 SID_IDENTIFIER_AUTHORITY sid_auth = { SECURITY_WORLD_SID_AUTHORITY };
adaa168a 119 if (!AllocateAndInitializeSid (&sid_auth, 1, 0, 0, 0, 0, 0, 0, 0, 0, &esid))
acbae401 120 {
9f4a0c62
RC
121 log (LOG_TIMESTAMP) << "AllocateAndInitializeSid() failed: " <<
122 GetLastError () << endLog;
adaa168a 123 goto out;
acbae401
CV
124 }
125
126 /* Create the ACE which grants full access to "Everyone" and store it
127 in dacl->DefaultDacl. */
b24c88b3 128 if (!AddAccessAllowedAce
adaa168a 129 (dacl->DefaultDacl, ACL_REVISION, GENERIC_ALL, esid))
acbae401 130 {
9f4a0c62
RC
131 log (LOG_TIMESTAMP) << "AddAccessAllowedAce() failed: %lu" <<
132 GetLastError () << endLog;
acbae401
CV
133 goto out;
134 }
135
136 /* Get the processes access token. */
acbae401 137 if (!OpenProcessToken (GetCurrentProcess (),
b24c88b3 138 TOKEN_READ | TOKEN_ADJUST_DEFAULT, &token))
acbae401 139 {
adaa168a
MB
140 log (LOG_TIMESTAMP) << "OpenProcessToken() failed: " <<
141 GetLastError () << endLog;
acbae401
CV
142 goto out;
143 }
144
145 /* Set the default DACL to the above computed ACL. */
146 if (!SetTokenInformation (token, TokenDefaultDacl, dacl, sizeof buf))
adaa168a
MB
147 log (LOG_TIMESTAMP) << "OpenProcessToken() failed: " <<
148 GetLastError () << endLog;
acbae401 149
acbae401 150
adaa168a
MB
151 /* Get the default group */
152 if (!GetTokenInformation (token, TokenPrimaryGroup, &gsid, sizeof gsid, &size))
153 {
154 log (LOG_TIMESTAMP) << "GetTokenInformation() failed: " <<
155 GetLastError () << endLog;
156 goto out;
157 }
158
159 /* Get the computer name */
160 if (!GetComputerName (compname, (size = sizeof compname, &size)))
161 {
162 log (LOG_TIMESTAMP) << "GetComputerName() failed: " <<
163 GetLastError () << endLog;
164 goto out;
165 }
166
167 /* Get the local domain SID */
168 SID_NAME_USE use;
169 DWORD sz;
170 if (!LookupAccountName (NULL, compname, lsid, (size = sizeof lsid, &size),
171 domain, (sz = sizeof domain, &sz), &use))
172 {
173 log (LOG_TIMESTAMP) << "LookupAccountName() failed: " <<
174 GetLastError () << endLog;
175 goto out;
176 }
177
178 /* Create the None SID from the domain SID.
179 On NT the last subauthority of a domain is -1 and it is replaced by the RID.
180 On other systems the RID is appended. */
181 sz = *GetSidSubAuthorityCount (lsid);
182 if (*GetSidSubAuthority (lsid, sz -1) != (DWORD) -1)
183 *GetSidSubAuthorityCount (lsid) = ++sz;
184 *GetSidSubAuthority (lsid, sz -1) = DOMAIN_GROUP_RID_USERS;
185
186 /* See if the group is None */
187 if (EqualSid (gsid.psid, lsid))
188 {
189 bool isadmins = false, isusers = false;
190 sid_auth = (SID_IDENTIFIER_AUTHORITY) { SECURITY_NT_AUTHORITY };
191 /* Get the SID for "Administrators" S-1-5-32-544 */
192 if (!AllocateAndInitializeSid (&sid_auth, 2, SECURITY_BUILTIN_DOMAIN_RID,
193 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &asid))
194 {
195 log (LOG_TIMESTAMP) << "AllocateAndInitializeSid() failed: " <<
196 GetLastError () << endLog;
197 goto out;
198 }
199 /* Get the SID for "Users" S-1-5-32-545 */
200 if (!AllocateAndInitializeSid (&sid_auth, 2, SECURITY_BUILTIN_DOMAIN_RID,
201 DOMAIN_ALIAS_RID_USERS, 0, 0, 0, 0, 0, 0, &usid))
202 {
203 log (LOG_TIMESTAMP) << "AllocateAndInitializeSid() failed: " <<
204 GetLastError () << endLog;
205 goto out;
206 }
207 /* Get the token groups */
208 if (!GetTokenInformation (token, TokenGroups, NULL, 0, &size)
209 && GetLastError () != ERROR_INSUFFICIENT_BUFFER)
210 {
211 log (LOG_TIMESTAMP) << "GetTokenInformation() failed: " <<
212 GetLastError () << endLog;
213 goto out;
214 }
215 else
216 {
217 char buf[size];
218 TOKEN_GROUPS *groups = (TOKEN_GROUPS *) buf;
219
220 if (!GetTokenInformation (token, TokenGroups, buf, size, &size))
221 {
222 log (LOG_TIMESTAMP) << "GetTokenInformation() failed: " <<
223 GetLastError () << endLog;
224 goto out;
225 }
226 else
227 /* See if admins or users is present */
228 for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
229 {
230 isadmins = isadmins || EqualSid(groups->Groups[pg].Sid, asid);
231 isusers = isusers || EqualSid(groups->Groups[pg].Sid, usid);
232 }
233 }
234 /* Set the default group to one of the above computed SID. */
235 PSID nsid = NULL;
236 if (isusers)
d5be1d23 237 {
adaa168a 238 nsid = usid;
d5be1d23
MB
239 log(LOG_TIMESTAMP) << "Changing gid to Users" << endLog;
240 }
adaa168a 241 else if (isadmins)
d5be1d23 242 {
adaa168a 243 nsid = asid;
d5be1d23
MB
244 log(LOG_TIMESTAMP) << "Changing gid to Administrators" << endLog;
245 }
adaa168a
MB
246 if (nsid && !SetTokenInformation (token, TokenPrimaryGroup, &nsid, sizeof nsid))
247 log (LOG_TIMESTAMP) << "SetTokenInformation() failed: " <<
248 GetLastError () << endLog;
249 }
250 out:
251 /* Close token handle. */
252 if (token)
253 CloseHandle (token);
254
255 /* Free memory occupied by the SIDs. */
256 if (esid)
257 FreeSid (esid);
258 if (asid)
259 FreeSid (asid);
260 if (usid)
261 FreeSid (usid);
acbae401
CV
262}
263
ab57ceaa
RC
264// Other threads talk to this page, so we need to have it externable.
265ThreeBarProgressPage Progress;
266
9f4a0c62
RC
267// This is a little ugly, but the decision about where to log occurs
268// after the source is set AND the root mount obtained
269// so we make the actual logger available to the appropriate routine(s).
a55c8f45 270LogFile *theLog;
9f4a0c62 271
45e01f23 272#ifndef __CYGWIN__
23c9e63c 273int WINAPI
1fd6d0a2 274WinMain (HINSTANCE h,
b24c88b3 275 HINSTANCE hPrevInstance, LPSTR command_line, int cmd_show)
23c9e63c 276{
8bb9dad9 277
23c9e63c 278 hinstance = h;
45e01f23
RC
279#else
280int
281main (int argc, char **argv)
282{
283 hinstance = GetModuleHandle (NULL);
284#endif
23c9e63c 285
9f4a0c62
RC
286 char *cwd=new char[_MAX_PATH];
287 GetCurrentDirectory (_MAX_PATH, cwd);
288 local_dir = String (cwd);
289 delete cwd;
290
15004270 291 LogSingleton::SetInstance (*(theLog = LogFile::createLogFile()));
a55c8f45
RC
292 theLog->setFile (LOG_BABBLE, local_dir + "/setup.log.full", false);
293 theLog->setFile (0, local_dir + "/setup.log", true);
9f4a0c62 294
8507f105 295 next_dialog = IDD_SPLASH;
23c9e63c 296
9f4a0c62 297 log (LOG_PLAIN) << "Starting cygwin install, version " << version << endLog;
89b1a15b 298
ab57ceaa 299 SplashPage Splash;
f9e903a3 300 AntiVirusPage AntiVirus;
ab57ceaa
RC
301 SourcePage Source;
302 RootPage Root;
303 LocalDirPage LocalDir;
304 NetPage Net;
305 SitePage Site;
306 ChooserPage Chooser;
307 DesktopSetupPage Desktop;
308 PropSheet MainWindow;
309
9f4a0c62 310 log (LOG_TIMESTAMP) << "Current Directory: " << local_dir << endLog;
89b1a15b 311
45e01f23
RC
312 // TODO: make an equivalent for __argv under cygwin.
313 char **_argv;
314#ifndef __CYGWIN__
ef465627 315 int argc;
45e01f23
RC
316// char **_argv;
317#ifndef __CYGWIN__
318 for (argc = 0, _argv = __argv; *_argv; _argv++)++argc;
319 _argv = __argv;
320#else
321// for (argc = 0, _argv = argv; *_argv; _argv++)++argc;
322 _argv = argv;
323#endif
324#else
325 _argv = argv;
326#endif
1be8f8fd 327
45e01f23 328 if (!GetOption::GetInstance().Process (argc,_argv))
a55c8f45 329 theLog->exit(1);
45e01f23 330// #endif
b24c88b3 331
f2ff9838
RC
332 unattended_mode = UnattendedOption;
333
adaa168a
MB
334 /* Set the default DACL and Group only on NT/W2K. 9x/ME has
335 no idea of access control lists and security at all. */
acbae401 336 if (iswinnt)
adaa168a 337 set_default_sec ();
acbae401 338
ab57ceaa
RC
339 // Initialize common controls
340 InitCommonControls ();
341
342 // Init window class lib
45e01f23 343 Window::SetAppInstance (hinstance);
ab57ceaa
RC
344
345 // Create pages
346 Splash.Create ();
f9e903a3 347 AntiVirus.Create ();
ab57ceaa
RC
348 Source.Create ();
349 Root.Create ();
350 LocalDir.Create ();
351 Net.Create ();
352 Site.Create ();
353 Chooser.Create ();
354 Progress.Create ();
355 Desktop.Create ();
356
357 // Add pages to sheet
358 MainWindow.AddPage (&Splash);
f9e903a3 359 MainWindow.AddPage (&AntiVirus);
ab57ceaa
RC
360 MainWindow.AddPage (&Source);
361 MainWindow.AddPage (&Root);
362 MainWindow.AddPage (&LocalDir);
363 MainWindow.AddPage (&Net);
364 MainWindow.AddPage (&Site);
365 MainWindow.AddPage (&Chooser);
366 MainWindow.AddPage (&Progress);
367 MainWindow.AddPage (&Desktop);
368
369 // Create the PropSheet main window
370 MainWindow.Create ();
23c9e63c 371
a55c8f45 372 theLog->exit (0);
b24c88b3
RC
373 /* Keep gcc happy :} */
374 return 0;
23c9e63c 375}
This page took 0.078194 seconds and 5 git commands to generate.