]> cygwin.com Git - cygwin-apps/setup.git/blob - main.cc
2002-09-21 Robert Collins <rbtcollins@hotmail.com>
[cygwin-apps/setup.git] / main.cc
1 /*
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
26 #if 0
27 static const char *cvsid =
28 "\n%%% $Id$\n";
29 #endif
30
31 #include "win32.h"
32 #include <commctrl.h>
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include "resource.h"
37 #include "dialog.h"
38 #include "state.h"
39 #include "msg.h"
40 #include "find.h"
41 #include "mount.h"
42 #include "LogFile.h"
43 #include "version.h"
44
45 #include "port.h"
46 #include "proppage.h"
47 #include "propsheet.h"
48
49 // Page class headers
50 #include "splash.h"
51 #include "source.h"
52 #include "root.h"
53 #include "localdir.h"
54 #include "net.h"
55 #include "site.h"
56 #include "choose.h"
57 #include "threebar.h"
58 #include "desktop.h"
59
60 #include "getopt++/GetOption.h"
61 #include "getopt++/BoolOption.h"
62
63 int next_dialog;
64
65 HINSTANCE hinstance;
66
67 static BoolOption UnattendedOption (false, 'q', "quiet-mode", "Unattended setup mode");
68
69 /* Maximum size of a SID on NT/W2K. */
70 #define MAX_SID_LEN 40
71
72 /* Computes the size of an ACL in relation to the number of ACEs it
73 should contain. */
74 #define TOKEN_ACL_SIZE(cnt) (sizeof(ACL) + \
75 (cnt) * (sizeof(ACCESS_ALLOWED_ACE) + MAX_SID_LEN))
76
77 #define iswinnt (GetVersion() < 0x80000000)
78
79 void
80 set_default_dacl ()
81 {
82 /* To assure that the created files have a useful ACL, the
83 default DACL in the process token is set to full access to
84 everyone. This applies to files and subdirectories created
85 in directories which don't propagate permissions to child
86 objects. */
87
88 /* Create a buffer which has enough room to contain the TOKEN_DEFAULT_DACL
89 structure plus an ACL with one ACE. */
90 char buf[sizeof (TOKEN_DEFAULT_DACL) + TOKEN_ACL_SIZE (1)];
91
92 /* First initialize the TOKEN_DEFAULT_DACL structure. */
93 PTOKEN_DEFAULT_DACL dacl = (PTOKEN_DEFAULT_DACL) buf;
94 dacl->DefaultDacl = (PACL) (buf + sizeof *dacl);
95
96 /* Initialize the ACL for containing one ACE. */
97 if (!InitializeAcl (dacl->DefaultDacl, TOKEN_ACL_SIZE (1), ACL_REVISION))
98 {
99 log (LOG_TIMESTAMP) << "InitializeAcl() failed: " << GetLastError ()
100 << endLog;
101 return;
102 }
103
104 /* Get the SID for "Everyone". */
105 PSID sid;
106 SID_IDENTIFIER_AUTHORITY sid_auth = { SECURITY_WORLD_SID_AUTHORITY };
107 if (!AllocateAndInitializeSid (&sid_auth, 1, 0, 0, 0, 0, 0, 0, 0, 0, &sid))
108 {
109 log (LOG_TIMESTAMP) << "AllocateAndInitializeSid() failed: " <<
110 GetLastError () << endLog;
111 return;
112 }
113
114 /* Create the ACE which grants full access to "Everyone" and store it
115 in dacl->DefaultDacl. */
116 if (!AddAccessAllowedAce
117 (dacl->DefaultDacl, ACL_REVISION, GENERIC_ALL, sid))
118 {
119 log (LOG_TIMESTAMP) << "AddAccessAllowedAce() failed: %lu" <<
120 GetLastError () << endLog;
121 goto out;
122 }
123
124 /* Get the processes access token. */
125 HANDLE token;
126 if (!OpenProcessToken (GetCurrentProcess (),
127 TOKEN_READ | TOKEN_ADJUST_DEFAULT, &token))
128 {
129 log (LOG_TIMESTAMP) << "OpenProcessToken() failed: "
130 << GetLastError () << endLog;
131 goto out;
132 }
133
134 /* Set the default DACL to the above computed ACL. */
135 if (!SetTokenInformation (token, TokenDefaultDacl, dacl, sizeof buf))
136 log (LOG_TIMESTAMP) << "OpenProcessToken() failed: " << GetLastError ()
137 << endLog;
138
139 /* Close token handle. */
140 CloseHandle (token);
141
142 out:
143 /* Free memory occupied by the "Everyone" SID. */
144 FreeSid (sid);
145 }
146
147 // Other threads talk to this page, so we need to have it externable.
148 ThreeBarProgressPage Progress;
149
150 // This is a little ugly, but the decision about where to log occurs
151 // after the source is set AND the root mount obtained
152 // so we make the actual logger available to the appropriate routine(s).
153 LogFile theLog;
154
155 #ifndef __CYGWIN__
156 int WINAPI
157 WinMain (HINSTANCE h,
158 HINSTANCE hPrevInstance, LPSTR command_line, int cmd_show)
159 {
160
161 hinstance = h;
162 #else
163 int
164 main (int argc, char **argv)
165 {
166 hinstance = GetModuleHandle (NULL);
167 #endif
168
169 char *cwd=new char[_MAX_PATH];
170 GetCurrentDirectory (_MAX_PATH, cwd);
171 local_dir = String (cwd);
172 delete cwd;
173
174 LogSingleton::SetInstance (theLog);
175 theLog.setFile (LOG_BABBLE, local_dir + "/setup.log.full", false);
176 theLog.setFile (0, local_dir + "/setup.log", true);
177
178 next_dialog = IDD_SPLASH;
179
180 log (LOG_PLAIN) << "Starting cygwin install, version " << version << endLog;
181
182 SplashPage Splash;
183 SourcePage Source;
184 RootPage Root;
185 LocalDirPage LocalDir;
186 NetPage Net;
187 SitePage Site;
188 ChooserPage Chooser;
189 DesktopSetupPage Desktop;
190 PropSheet MainWindow;
191
192 log (LOG_TIMESTAMP) << "Current Directory: " << local_dir << endLog;
193
194 // TODO: make an equivalent for __argv under cygwin.
195 char **_argv;
196 #ifndef __CYGWIN__
197 int argc;
198 // char **_argv;
199 #ifndef __CYGWIN__
200 for (argc = 0, _argv = __argv; *_argv; _argv++)++argc;
201 _argv = __argv;
202 #else
203 // for (argc = 0, _argv = argv; *_argv; _argv++)++argc;
204 _argv = argv;
205 #endif
206 #else
207 _argv = argv;
208 #endif
209
210 if (!GetOption::GetInstance().Process (argc,_argv))
211 theLog.exit(1);
212 // #endif
213
214 unattended_mode = UnattendedOption;
215
216 /* Set the default DACL only on NT/W2K. 9x/ME has no idea of access
217 control lists and security at all. */
218 if (iswinnt)
219 set_default_dacl ();
220
221 // Initialize common controls
222 InitCommonControls ();
223
224 // Init window class lib
225 Window::SetAppInstance (hinstance);
226
227 // Create pages
228 Splash.Create ();
229 Source.Create ();
230 Root.Create ();
231 LocalDir.Create ();
232 Net.Create ();
233 Site.Create ();
234 Chooser.Create ();
235 Progress.Create ();
236 Desktop.Create ();
237
238 // Add pages to sheet
239 MainWindow.AddPage (&Splash);
240 MainWindow.AddPage (&Source);
241 MainWindow.AddPage (&Root);
242 MainWindow.AddPage (&LocalDir);
243 MainWindow.AddPage (&Net);
244 MainWindow.AddPage (&Site);
245 MainWindow.AddPage (&Chooser);
246 MainWindow.AddPage (&Progress);
247 MainWindow.AddPage (&Desktop);
248
249 // Create the PropSheet main window
250 MainWindow.Create ();
251
252 theLog.exit (0);
253 /* Keep gcc happy :} */
254 return 0;
255 }
This page took 0.048638 seconds and 6 git commands to generate.