]> cygwin.com Git - cygwin-apps/setup.git/blame - main.cc
Support xz and lzma decompression via liblzma
[cygwin-apps/setup.git] / main.cc
CommitLineData
2b734ec7 1/*
23c9e63c 2 * Copyright (c) 2000, Red Hat, Inc.
e46e15bf 3 * Copyright (c) 2003, Robert Collins <rbtcollins@hotmail.com>
23c9e63c
DD
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 * A copy of the GNU General Public License can be found at
11 * http://www.gnu.org/
12 *
13 * Written by DJ Delorie <dj@cygnus.com>
e46e15bf
RC
14 * Robert Collins <rbtcollins@hotmail.com>
15 *
23c9e63c
DD
16 *
17 */
18
19/* OK, here's how this works. Each of the steps needed for install -
20 dialogs, downloads, installs - are in their own files and have some
21 "do_*" function (prototype in dialog.h) and a resource id (IDD_* or
22 IDD_S_* in resource.h) for that step. Each step is responsible for
23 selecting the next step! See the NEXT macro in dialog.h. Note
24 that the IDD_S_* ids are fake; those are for steps that don't
25 really have a controlling dialog (some have progress dialogs, but
26 those don't count, although they could). Replace the IDD_S_* with
27 IDD_* if you create a real dialog for those steps. */
28
b24c88b3
RC
29#if 0
30static const char *cvsid =
31 "\n%%% $Id$\n";
32#endif
8507f105 33
c8356810
CF
34#undef _WIN32_WINNT
35#define _WIN32_WINNT 0x0501
e36b0f1e 36#define CINTERFACE
23c9e63c 37#include "win32.h"
ab57ceaa 38#include <commctrl.h>
e36b0f1e 39#include "shlobj.h"
23c9e63c
DD
40
41#include <stdio.h>
89b1a15b 42#include <stdlib.h>
23c9e63c
DD
43#include "resource.h"
44#include "dialog.h"
45#include "state.h"
46#include "msg.h"
23c9e63c
DD
47#include "find.h"
48#include "mount.h"
9f4a0c62 49#include "LogFile.h"
2b734ec7 50#include "setup_version.h"
89b1a15b 51
ab57ceaa
RC
52#include "proppage.h"
53#include "propsheet.h"
54
55// Page class headers
56#include "splash.h"
f9e903a3 57#include "AntiVirus.h"
ab57ceaa
RC
58#include "source.h"
59#include "root.h"
60#include "localdir.h"
61#include "net.h"
62#include "site.h"
63#include "choose.h"
82306ac2 64#include "prereq.h"
ab57ceaa
RC
65#include "threebar.h"
66#include "desktop.h"
23c9e63c 67
6908b7d7 68#include "getopt++/GetOption.h"
f2ff9838 69#include "getopt++/BoolOption.h"
1be8f8fd 70
072fb49a
MB
71#include "Exception.h"
72#include <stdexcept>
73
f26f525f
CF
74#include "UserSettings.h"
75#include "SourceSetting.h"
76#include "ConnectionSetting.h"
77#include "KeysSetting.h"
78
c8356810
CF
79#include <wincon.h>
80#include <fstream>
81
072fb49a 82using namespace std;
0df9be37 83
23c9e63c 84HINSTANCE hinstance;
4ea94dbb 85bool is_legacy;
23c9e63c 86
f2ff9838 87static BoolOption UnattendedOption (false, 'q', "quiet-mode", "Unattended setup mode");
7a4e611a 88static BoolOption PackageManagerOption (false, 'M', "package-manager", "Semi-attended chooser-only mode");
c9feb168 89static BoolOption HelpOption (false, 'h', "help", "print help");
89216328
CF
90static BOOL WINAPI (*dyn_AttachConsole) (DWORD);
91static BOOL WINAPI (*dyn_GetLongPathName) (LPCTSTR, LPTSTR, DWORD);
92
93
94static void inline
95set_dynaddr ()
96{
97 HMODULE hm = LoadLibrary ("kernel32.dll");
98 if (!hm)
99 return;
100
101 dyn_AttachConsole = (BOOL WINAPI (*)(DWORD)) GetProcAddress (hm, "AttachConsole");
102 dyn_GetLongPathName = (BOOL WINAPI (*)(LPCTSTR, LPTSTR, DWORD)) GetProcAddress (hm, "GetLongPathNameA");
103}
f2ff9838 104
c8356810
CF
105static void inline
106set_cout ()
107{
0188fce5
CF
108 HANDLE my_stdout = GetStdHandle (STD_OUTPUT_HANDLE);
109 if (my_stdout != INVALID_HANDLE_VALUE && GetFileType (my_stdout) != FILE_TYPE_UNKNOWN)
0cbac692 110 return;
0188fce5 111
0188fce5 112 if (dyn_AttachConsole && dyn_AttachConsole ((DWORD) -1))
e0fd9bd3 113 {
0188fce5
CF
114 ofstream *conout = new ofstream ("conout$");
115 cout.rdbuf (conout->rdbuf ());
116 cout.flush ();
e0fd9bd3 117 }
c8356810
CF
118}
119
ab57ceaa
RC
120// Other threads talk to this page, so we need to have it externable.
121ThreeBarProgressPage Progress;
122
9f4a0c62
RC
123// This is a little ugly, but the decision about where to log occurs
124// after the source is set AND the root mount obtained
125// so we make the actual logger available to the appropriate routine(s).
a55c8f45 126LogFile *theLog;
9f4a0c62 127
f26f525f
CF
128static inline void
129main_display ()
130{
131 /* nondisplay classes */
132 LocalDirSetting localDir;
133 SourceSetting SourceSettings;
134 ConnectionSetting ConnectionSettings;
135 SiteSetting ChosenSites;
136 ExtraKeysSetting ExtraKeys;
137
138 SplashPage Splash;
139 AntiVirusPage AntiVirus;
140 SourcePage Source;
141 RootPage Root;
142 LocalDirPage LocalDir;
143 NetPage Net;
144 SitePage Site;
145 ChooserPage Chooser;
146 PrereqPage Prereq;
147 DesktopSetupPage Desktop;
148 PropSheet MainWindow;
149
150 log (LOG_TIMESTAMP) << "Current Directory: " << local_dir << endLog;
151
152 if (HelpOption)
153 {
154 GetOption::GetInstance ().ParameterUsage (log (LOG_PLAIN)
155 << "\nCommand Line Options:\n");
156 theLog->exit (0);
157 }
158
159 /* Set the default DACL and Group only on NT/W2K. 9x/ME has
160 no idea of access control lists and security at all. */
161 if (IsWindowsNT ())
162 nt_sec.setDefaultSecurity ();
163
164 // Initialize common controls
e36b0f1e
CV
165 INITCOMMONCONTROLSEX icce = { sizeof (INITCOMMONCONTROLSEX),
166 ICC_WIN95_CLASSES };
167 InitCommonControlsEx (&icce);
168
169 // Initialize COM and ShellLink instance here. For some reason
170 // Windows 7 fails to create the ShellLink instance if this is
171 // done later, in the thread which actually creates the shortcuts.
172 extern IShellLink *sl;
9e11837b 173 CoInitializeEx (NULL, COINIT_APARTMENTTHREADED);
e36b0f1e
CV
174 HRESULT res = CoCreateInstance (&CLSID_ShellLink, NULL,
175 CLSCTX_INPROC_SERVER, &IID_IShellLink,
176 (LPVOID *) & sl);
177 if (res)
178 {
179 char buf[256];
180 sprintf (buf, "CoCreateInstance failed with error %p.\n"
181 "Setup will not be able to create Cygwin Icons\n"
182 "in the Start Menu or on the Desktop.", (void *) res);
3e805913 183 MessageBox (NULL, buf, "Cygwin Setup", MB_OK);
e36b0f1e 184 }
f26f525f
CF
185
186 // Init window class lib
187 Window::SetAppInstance (hinstance);
188
189 // Create pages
190 Splash.Create ();
191 AntiVirus.Create ();
192 Source.Create ();
193 Root.Create ();
194 LocalDir.Create ();
195 Net.Create ();
196 Site.Create ();
197 Chooser.Create ();
198 Prereq.Create ();
199 Progress.Create ();
200 Desktop.Create ();
201
202 // Add pages to sheet
203 MainWindow.AddPage (&Splash);
204 MainWindow.AddPage (&AntiVirus);
205 MainWindow.AddPage (&Source);
206 MainWindow.AddPage (&Root);
207 MainWindow.AddPage (&LocalDir);
208 MainWindow.AddPage (&Net);
209 MainWindow.AddPage (&Site);
210 MainWindow.AddPage (&Chooser);
211 MainWindow.AddPage (&Prereq);
212 MainWindow.AddPage (&Progress);
213 MainWindow.AddPage (&Desktop);
214
215 // Create the PropSheet main window
216 MainWindow.Create ();
e36b0f1e
CV
217
218 // Uninitalize COM
219 if (sl)
220 sl->lpVtbl->Release (sl);
221 CoUninitialize ();
f26f525f
CF
222}
223
4ea94dbb
CF
224static void
225set_legacy (const char *command)
226{
89216328
CF
227 char buf[MAX_PATH + 1];
228 if (strchr (command, '~') == NULL || !dyn_GetLongPathName
229 || !dyn_GetLongPathName (command, buf, MAX_PATH))
230 {
231 strncpy (buf, command, MAX_PATH);
232 buf[MAX_PATH] = '\0';
233 }
4ea94dbb
CF
234 strlwr (buf);
235 is_legacy = strstr (buf, "setup-legacy");
236}
237
45e01f23 238#ifndef __CYGWIN__
23c9e63c 239int WINAPI
1fd6d0a2 240WinMain (HINSTANCE h,
b24c88b3 241 HINSTANCE hPrevInstance, LPSTR command_line, int cmd_show)
23c9e63c 242{
8bb9dad9 243
23c9e63c 244 hinstance = h;
45e01f23
RC
245#else
246int
247main (int argc, char **argv)
248{
249 hinstance = GetModuleHandle (NULL);
250#endif
23c9e63c 251
89216328 252 set_dynaddr ();
3e805913
CV
253 // Make sure the C runtime functions use the same codepage as the GUI
254 char locale[12];
255 snprintf(locale, sizeof locale, ".%u", GetACP());
256 setlocale(LC_ALL, locale);
257
4ea94dbb
CF
258 set_legacy (_argv[0]);
259
260 if (is_legacy && IsWindowsNT ())
261 {
262 if (MessageBox (NULL,
263 "You are attempting to install a legacy version of Cygwin\n"
264 "on a modern version of Windows. Press \"OK\" if this is\n"
265 "really want you want to do. Otherwise press \"Cancel\".\n"
266 "See http://cygwin.com/ for more information.",
267 "Attempt to install legacy version of Cygwin",
268 MB_OKCANCEL | MB_ICONSTOP | MB_SETFOREGROUND | MB_TOPMOST)
269 == IDCANCEL)
270 return 1;
271 }
272 else if (!is_legacy && !IsWindowsNT ())
a5405502
CV
273 {
274 MessageBox (NULL,
275 "Cygwin 1.7 and later does not run on Windows 95,\n"
276 "Windows 98, or Windows Me. If you want to install Cygwin\n"
277 "on one of these systems, please install an older version.\n"
278 "See http://cygwin.com/ for more information.",
4ea94dbb 279 "Unsupported version of Windows detected",
a5405502
CV
280 MB_OK | MB_ICONSTOP | MB_SETFOREGROUND | MB_TOPMOST);
281 return 1;
282 }
283
072fb49a 284 try {
5072c0bb 285 char cwd[MAX_PATH];
4875ac88 286 GetCurrentDirectory (MAX_PATH, cwd);
08678720 287 local_dir = std::string (cwd);
072fb49a 288
c66b9174
MB
289 // TODO: make an equivalent for __argv under cygwin.
290 char **_argv;
291#ifndef __CYGWIN__
292 int argc;
5072c0bb
BD
293 for (argc = 0, _argv = __argv; *_argv; _argv++)
294 ++argc;
c66b9174
MB
295 _argv = __argv;
296#else
297 _argv = argv;
298#endif
299
5072c0bb
BD
300 if (!GetOption::GetInstance ().Process (argc,_argv, NULL))
301 exit (1);
c66b9174 302
7a4e611a
DK
303 unattended_mode = PackageManagerOption ? chooseronly
304 : (UnattendedOption ? unattended : attended);
305
c8356810
CF
306 if (unattended_mode || HelpOption)
307 set_cout ();
308
5072c0bb 309 LogSingleton::SetInstance (*(theLog = LogFile::createLogFile ()));
4d10ec8c
CV
310 const char *sep = isdirsep (local_dir[local_dir.size () - 1]) ? "" : "\\";
311 theLog->setFile (LOG_BABBLE, local_dir + sep + "setup.log.full", false);
312 theLog->setFile (0, local_dir + sep + "setup.log", true);
072fb49a 313
5072c0bb
BD
314 log (LOG_PLAIN) << "Starting cygwin install, version "
315 << setup_version << endLog;
072fb49a 316
f26f525f 317 UserSettings Settings (local_dir);
072fb49a 318
f26f525f 319 main_display ();
072fb49a 320
f26f525f 321 Settings.save (); // Clean exit.. save user options.
b24c88b3 322
0407753c
DK
323 if (rebootneeded)
324 {
325 theLog->exit (IDS_REBOOT_REQUIRED);
326 }
327 else
328 {
329 theLog->exit (0);
330 }
c9feb168 331 }
072fb49a 332 TOPLEVEL_CATCH("main");
c9feb168 333
072fb49a 334 // Never reached
b24c88b3 335 return 0;
23c9e63c 336}
This page took 0.094275 seconds and 5 git commands to generate.