2 * Copyright (c) 2000, Red Hat, Inc.
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.
9 * A copy of the GNU General Public License can be found at
12 * Written by DJ Delorie <dj@cygnus.com>
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. */
27 static const char *cvsid
=
47 #include "propsheet.h"
51 #include "AntiVirus.h"
61 #include "getopt++/GetOption.h"
62 #include "getopt++/BoolOption.h"
68 static BoolOption
UnattendedOption (false, 'q', "quiet-mode", "Unattended setup mode");
70 /* Maximum size of a SID on NT/W2K. */
71 #define MAX_SID_LEN 40
73 /* Computes the size of an ACL in relation to the number of ACEs it
75 #define TOKEN_ACL_SIZE(cnt) (sizeof(ACL) + \
76 (cnt) * (sizeof(ACCESS_ALLOWED_ACE) + MAX_SID_LEN))
78 #define iswinnt (GetVersion() < 0x80000000)
83 /* To assure that the created files have a useful ACL, the
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
88 To assure that the files group is meaningful, a token primary
89 group of None is changed to Users or Administrators. */
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)];
95 /* First initialize the TOKEN_DEFAULT_DACL structure. */
96 PTOKEN_DEFAULT_DACL dacl
= (PTOKEN_DEFAULT_DACL
) buf
;
97 dacl
->DefaultDacl
= (PACL
) (buf
+ sizeof *dacl
);
99 /* Initialize the ACL for containing one ACE. */
100 if (!InitializeAcl (dacl
->DefaultDacl
, TOKEN_ACL_SIZE (1), ACL_REVISION
))
102 log (LOG_TIMESTAMP
) << "InitializeAcl() failed: " << GetLastError ()
107 PSID esid
= NULL
, asid
= NULL
, usid
= NULL
;
111 char buf
[MAX_SID_LEN
];
113 char lsid
[MAX_SID_LEN
];
114 char compname
[MAX_COMPUTERNAME_LENGTH
+ 1];
115 char domain
[MAX_COMPUTERNAME_LENGTH
+ 1];
118 SID_IDENTIFIER_AUTHORITY sid_auth
= { SECURITY_WORLD_SID_AUTHORITY
};
119 if (!AllocateAndInitializeSid (&sid_auth
, 1, 0, 0, 0, 0, 0, 0, 0, 0, &esid
))
121 log (LOG_TIMESTAMP
) << "AllocateAndInitializeSid() failed: " <<
122 GetLastError () << endLog
;
126 /* Create the ACE which grants full access to "Everyone" and store it
127 in dacl->DefaultDacl. */
128 if (!AddAccessAllowedAce
129 (dacl
->DefaultDacl
, ACL_REVISION
, GENERIC_ALL
, esid
))
131 log (LOG_TIMESTAMP
) << "AddAccessAllowedAce() failed: %lu" <<
132 GetLastError () << endLog
;
136 /* Get the processes access token. */
137 if (!OpenProcessToken (GetCurrentProcess (),
138 TOKEN_READ
| TOKEN_ADJUST_DEFAULT
, &token
))
140 log (LOG_TIMESTAMP
) << "OpenProcessToken() failed: " <<
141 GetLastError () << endLog
;
145 /* Set the default DACL to the above computed ACL. */
146 if (!SetTokenInformation (token
, TokenDefaultDacl
, dacl
, sizeof buf
))
147 log (LOG_TIMESTAMP
) << "OpenProcessToken() failed: " <<
148 GetLastError () << endLog
;
151 /* Get the default group */
152 if (!GetTokenInformation (token
, TokenPrimaryGroup
, &gsid
, sizeof gsid
, &size
))
154 log (LOG_TIMESTAMP
) << "GetTokenInformation() failed: " <<
155 GetLastError () << endLog
;
159 /* Get the computer name */
160 if (!GetComputerName (compname
, (size
= sizeof compname
, &size
)))
162 log (LOG_TIMESTAMP
) << "GetComputerName() failed: " <<
163 GetLastError () << endLog
;
167 /* Get the local domain SID */
170 if (!LookupAccountName (NULL
, compname
, lsid
, (size
= sizeof lsid
, &size
),
171 domain
, (sz
= sizeof domain
, &sz
), &use
))
173 log (LOG_TIMESTAMP
) << "LookupAccountName() failed: " <<
174 GetLastError () << endLog
;
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
;
186 /* See if the group is None */
187 if (EqualSid (gsid
.psid
, lsid
))
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
))
195 log (LOG_TIMESTAMP
) << "AllocateAndInitializeSid() failed: " <<
196 GetLastError () << endLog
;
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
))
203 log (LOG_TIMESTAMP
) << "AllocateAndInitializeSid() failed: " <<
204 GetLastError () << endLog
;
207 /* Get the token groups */
208 if (!GetTokenInformation (token
, TokenGroups
, NULL
, 0, &size
)
209 && GetLastError () != ERROR_INSUFFICIENT_BUFFER
)
211 log (LOG_TIMESTAMP
) << "GetTokenInformation() failed: " <<
212 GetLastError () << endLog
;
218 TOKEN_GROUPS
*groups
= (TOKEN_GROUPS
*) buf
;
220 if (!GetTokenInformation (token
, TokenGroups
, buf
, size
, &size
))
222 log (LOG_TIMESTAMP
) << "GetTokenInformation() failed: " <<
223 GetLastError () << endLog
;
227 /* See if admins or users is present */
228 for (DWORD pg
= 0; pg
< groups
->GroupCount
; ++pg
)
230 isadmins
= isadmins
|| EqualSid(groups
->Groups
[pg
].Sid
, asid
);
231 isusers
= isusers
|| EqualSid(groups
->Groups
[pg
].Sid
, usid
);
234 /* Set the default group to one of the above computed SID. */
239 log(LOG_TIMESTAMP
) << "Changing gid to Users" << endLog
;
244 log(LOG_TIMESTAMP
) << "Changing gid to Administrators" << endLog
;
246 if (nsid
&& !SetTokenInformation (token
, TokenPrimaryGroup
, &nsid
, sizeof nsid
))
247 log (LOG_TIMESTAMP
) << "SetTokenInformation() failed: " <<
248 GetLastError () << endLog
;
251 /* Close token handle. */
255 /* Free memory occupied by the SIDs. */
264 // Other threads talk to this page, so we need to have it externable.
265 ThreeBarProgressPage Progress
;
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).
274 WinMain (HINSTANCE h
,
275 HINSTANCE hPrevInstance
, LPSTR command_line
, int cmd_show
)
281 main (int argc
, char **argv
)
283 hinstance
= GetModuleHandle (NULL
);
286 char *cwd
=new char[_MAX_PATH
];
287 GetCurrentDirectory (_MAX_PATH
, cwd
);
288 local_dir
= String (cwd
);
291 LogSingleton::SetInstance (*(theLog
= LogFile::createLogFile()));
292 theLog
->setFile (LOG_BABBLE
, local_dir
+ "/setup.log.full", false);
293 theLog
->setFile (0, local_dir
+ "/setup.log", true);
295 next_dialog
= IDD_SPLASH
;
297 log (LOG_PLAIN
) << "Starting cygwin install, version " << version
<< endLog
;
300 AntiVirusPage AntiVirus
;
303 LocalDirPage LocalDir
;
307 DesktopSetupPage Desktop
;
308 PropSheet MainWindow
;
310 log (LOG_TIMESTAMP
) << "Current Directory: " << local_dir
<< endLog
;
312 // TODO: make an equivalent for __argv under cygwin.
318 for (argc
= 0, _argv
= __argv
; *_argv
; _argv
++)++argc
;
321 // for (argc = 0, _argv = argv; *_argv; _argv++)++argc;
328 if (!GetOption::GetInstance().Process (argc
,_argv
))
332 unattended_mode
= UnattendedOption
;
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. */
339 // Initialize common controls
340 InitCommonControls ();
342 // Init window class lib
343 Window::SetAppInstance (hinstance
);
357 // Add pages to sheet
358 MainWindow
.AddPage (&Splash
);
359 MainWindow
.AddPage (&AntiVirus
);
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
);
369 // Create the PropSheet main window
370 MainWindow
.Create ();
373 /* Keep gcc happy :} */