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