448
|
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 /* The purpose of this file is to ask the user where they want the
|
|
17 root of the installation to be, and to ask whether the user prefers
|
|
18 text or binary mounts. */
|
|
19
|
|
20 #include "win32.h"
|
|
21 #include <shlobj.h>
|
|
22 #include <stdio.h>
|
|
23 #include <stdlib.h>
|
|
24 #include <ctype.h>
|
|
25
|
|
26 #include "dialog.h"
|
|
27 #include "resource.h"
|
|
28 #include "state.h"
|
|
29 #include "msg.h"
|
|
30 #include "regedit.h"
|
|
31 #include "reginfo.h"
|
|
32 #include "concat.h"
|
|
33 #include "log.h"
|
|
34
|
|
35 static int rb[] = { IDC_INSTALL_CYGWIN, IDC_INSTALL_NATIVE, 0 };
|
|
36 static int su[] = { IDC_ROOT_SYSTEM, IDC_ROOT_USER, 0 };
|
|
37
|
|
38 static void
|
|
39 check_if_enable_next (HWND h)
|
|
40 {
|
|
41 EnableWindow (GetDlgItem (h, IDOK), install_type && root_dir && root_scope);
|
|
42 }
|
|
43
|
|
44 static void
|
|
45 load_dialog (HWND h)
|
|
46 {
|
|
47 rbset (h, rb, install_type);
|
|
48 rbset (h, su, root_scope);
|
|
49 eset (h, IDC_ROOT_DIR, root_dir);
|
|
50 check_if_enable_next (h);
|
|
51 }
|
|
52
|
|
53 static void
|
|
54 save_dialog (HWND h)
|
|
55 {
|
|
56 install_type = rbget (h, rb);
|
|
57 root_scope = rbget (h, su);
|
|
58 char* new_root_dir = eget (h, IDC_ROOT_DIR, root_dir);
|
|
59
|
|
60 if (!root_dir || strcmp (new_root_dir, root_dir) != 0)
|
|
61 root_dir_default = 0;
|
|
62
|
|
63 root_dir = new_root_dir;
|
|
64 }
|
|
65
|
|
66 /*
|
|
67 * is_admin () determines whether or not the current user is a member of the
|
|
68 * Administrators group. On Windows 9X, the current user is considered an
|
|
69 * Administrator by definition.
|
|
70 */
|
|
71
|
|
72 static int
|
|
73 is_admin ()
|
|
74 {
|
|
75 // Windows 9X users are considered Administrators by definition
|
|
76 OSVERSIONINFO verinfo;
|
|
77 verinfo.dwOSVersionInfoSize = sizeof (verinfo);
|
|
78 GetVersionEx (&verinfo);
|
|
79 if (verinfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
|
|
80 return 1;
|
|
81
|
|
82 // Get the process token for the current process
|
|
83 HANDLE token;
|
|
84 BOOL status = OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &token);
|
|
85 if (!status)
|
|
86 return 0;
|
|
87
|
|
88 // Get the group token information
|
|
89 UCHAR token_info[1024];
|
|
90 PTOKEN_GROUPS groups = (PTOKEN_GROUPS) token_info;
|
|
91 DWORD token_info_len = sizeof (token_info);
|
|
92 status = GetTokenInformation (token, TokenGroups, token_info, token_info_len, &token_info_len);
|
|
93 CloseHandle(token);
|
|
94 if (!status)
|
|
95 return 0;
|
|
96
|
|
97 // Create the Administrators group SID
|
|
98 PSID admin_sid;
|
|
99 SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_AUTHORITY;
|
|
100 status = AllocateAndInitializeSid (&authority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &admin_sid);
|
|
101 if (!status)
|
|
102 return 0;
|
|
103
|
|
104 // Check to see if the user is a member of the Administrators group
|
|
105 status = 0;
|
|
106 for (UINT i=0; i<groups->GroupCount; i++) {
|
|
107 if (EqualSid(groups->Groups[i].Sid, admin_sid)) {
|
|
108 status = 1;
|
|
109 break;
|
|
110 }
|
|
111 }
|
|
112
|
|
113 // Destroy the Administrators group SID
|
|
114 FreeSid (admin_sid);
|
|
115
|
|
116 // Return whether or not the user is a member of the Administrators group
|
|
117 return status;
|
|
118 }
|
|
119
|
|
120 static void
|
|
121 change_default_root (int id)
|
|
122 {
|
|
123 int issystem;
|
|
124 char* cygroot = find_cygwin_root (&issystem);
|
|
125 if (id == IDC_INSTALL_CYGWIN && cygroot)
|
|
126 {
|
|
127 root_dir = concat (cygroot, XEMACS_CYGWIN_DEFAULT_ROOT, 0);
|
|
128 install_type = IDC_INSTALL_CYGWIN;
|
|
129 }
|
|
130 else if (id == IDC_INSTALL_NATIVE)
|
|
131 {
|
|
132 char windir[_MAX_PATH];
|
|
133 GetWindowsDirectory (windir, sizeof (windir));
|
|
134 windir[2] = 0;
|
|
135 root_dir = concat (windir, XEMACS_DEFAULT_ROOT, 0);
|
|
136 install_type = IDC_INSTALL_NATIVE;
|
|
137 }
|
|
138 }
|
|
139
|
|
140 static int CALLBACK
|
|
141 browse_cb (HWND h, UINT m, LPARAM lp, LPARAM data)
|
|
142 {
|
|
143 switch (m)
|
|
144 {
|
|
145 case BFFM_INITIALIZED:
|
|
146 if (root_dir)
|
|
147 SendMessage (h, BFFM_SETSELECTION, TRUE, (LPARAM)root_dir);
|
|
148 break;
|
|
149 }
|
|
150 return 0;
|
|
151 }
|
|
152
|
|
153 static void
|
|
154 browse (HWND h)
|
|
155 {
|
|
156 BROWSEINFO bi;
|
|
157 CHAR name[MAX_PATH];
|
|
158 LPITEMIDLIST pidl;
|
|
159 memset (&bi, 0, sizeof (bi));
|
|
160 bi.hwndOwner = h;
|
|
161 bi.pszDisplayName = name;
|
|
162 bi.lpszTitle = "Select an installation root directory";
|
|
163 bi.ulFlags = BIF_RETURNONLYFSDIRS;
|
|
164 bi.lpfn = browse_cb;
|
|
165 pidl = SHBrowseForFolder (&bi);
|
|
166 if (pidl)
|
|
167 {
|
|
168 if (SHGetPathFromIDList (pidl, name))
|
|
169 eset (h, IDC_ROOT_DIR, name);
|
|
170 }
|
|
171 }
|
|
172
|
|
173 #define isslash(c) ((c) == '\\' || (c) == '/')
|
|
174
|
|
175 static int
|
|
176 directory_is_absolute ()
|
|
177 {
|
|
178 if (isalpha (root_dir[0])
|
|
179 && root_dir[1] == ':'
|
|
180 && (root_dir[2] == '\\' || root_dir[2] == '/'))
|
|
181 return 1;
|
|
182 return 0;
|
|
183 }
|
|
184
|
|
185 static int
|
|
186 directory_is_rootdir ()
|
|
187 {
|
|
188 char *c;
|
|
189 for (c = root_dir; *c; c++)
|
|
190 if (isslash (c[0]) && c[1] && !isslash (c[1]))
|
|
191 return 0;
|
|
192 return 1;
|
|
193 }
|
|
194
|
|
195 static int
|
|
196 cygwin_without_cygwin ()
|
|
197 {
|
|
198 int issystem;
|
|
199 if (install_type == IDC_INSTALL_CYGWIN
|
|
200 && !find_cygwin_root (&issystem))
|
|
201 return 1;
|
|
202 return 0;
|
|
203 }
|
|
204
|
|
205 static BOOL
|
|
206 dialog_cmd (HWND h, int id, HWND hwndctl, UINT code)
|
|
207 {
|
|
208 switch (id)
|
|
209 {
|
|
210
|
|
211 case IDC_ROOT_DIR:
|
|
212 case IDC_ROOT_SYSTEM:
|
|
213 case IDC_ROOT_USER:
|
|
214 save_dialog (h);
|
|
215 check_if_enable_next (h);
|
|
216 break;
|
|
217
|
|
218 case IDC_INSTALL_NATIVE:
|
|
219 case IDC_INSTALL_CYGWIN:
|
|
220 if (root_dir_default)
|
|
221 {
|
|
222 change_default_root (id);
|
|
223 eset (h, IDC_ROOT_DIR, root_dir);
|
|
224 }
|
|
225 save_dialog (h);
|
|
226 check_if_enable_next (h);
|
|
227 break;
|
|
228
|
|
229 case IDC_ROOT_BROWSE:
|
|
230 browse (h);
|
|
231 break;
|
|
232
|
|
233 case IDOK:
|
|
234 save_dialog (h);
|
|
235
|
|
236 if (! directory_is_absolute ())
|
|
237 {
|
|
238 note (IDS_ROOT_ABSOLUTE);
|
|
239 break;
|
|
240 }
|
|
241
|
|
242 if (directory_is_rootdir ())
|
|
243 if (IDNO == yesno (IDS_ROOT_SLASH))
|
|
244 break;
|
|
245
|
|
246 if (cygwin_without_cygwin ())
|
|
247 if (IDNO == yesno (IDS_ROOT_NOCYGWIN))
|
|
248 break;
|
|
249
|
452
|
250 create_xemacs_root (backslash (root_dir),
|
448
|
251 root_scope == IDC_ROOT_SYSTEM ? 1 : 0,
|
|
252 install_type == IDC_INSTALL_NATIVE ? 1 : 0);
|
|
253
|
|
254 switch (source)
|
|
255 {
|
|
256 case IDC_SOURCE_NETINST:
|
|
257 NEXT (IDD_NET);
|
|
258 break;
|
|
259 case IDC_SOURCE_CWD:
|
|
260 NEXT (IDD_S_FROM_CWD);
|
|
261 break;
|
|
262 default:
|
|
263 msg ("source is default? %d\n", source);
|
|
264 NEXT (0);
|
|
265 }
|
|
266 break;
|
|
267
|
|
268 case IDC_BACK:
|
|
269 save_dialog (h);
|
|
270 NEXT (IDD_LOCAL_DIR);
|
|
271 break;
|
|
272
|
|
273 case IDCANCEL:
|
|
274 NEXT (0);
|
|
275 break;
|
|
276 }
|
|
277 return FALSE;
|
|
278 }
|
|
279
|
|
280 static BOOL CALLBACK
|
|
281 dialog_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
|
|
282 {
|
|
283 switch (message)
|
|
284 {
|
|
285 case WM_INITDIALOG:
|
|
286 load_dialog (h);
|
|
287 return FALSE;
|
|
288 case WM_COMMAND:
|
|
289 return HANDLE_WM_COMMAND (h, wParam, lParam, dialog_cmd);
|
|
290 }
|
|
291 return FALSE;
|
|
292 }
|
|
293
|
657
|
294 static void
|
|
295 set_default_root ()
|
|
296 {
|
|
297 change_default_root (IDC_INSTALL_NATIVE);
|
|
298 root_scope = (is_admin()) ? IDC_ROOT_SYSTEM : IDC_ROOT_USER;
|
|
299 root_dir_default = 1;
|
|
300 }
|
|
301
|
448
|
302 void
|
|
303 do_root (HINSTANCE h)
|
|
304 {
|
|
305 int rv = 0;
|
657
|
306 // init will have read a previous root
|
|
307 if (!root_dir)
|
|
308 set_default_root ();
|
448
|
309
|
|
310 rv = DialogBox (h, MAKEINTRESOURCE (IDD_ROOT), 0, dialog_proc);
|
|
311 if (rv == -1)
|
|
312 fatal (IDS_DIALOG_FAILED);
|
|
313
|
|
314 log (0, "root: %s %s %s", root_dir,
|
|
315 (install_type == IDC_INSTALL_NATIVE) ? "native" : "cygwin",
|
|
316 (root_scope == IDC_ROOT_USER) ? "user" : "system");
|
|
317 }
|
|
318
|