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