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 manage all the desktop setup, such
|
|
17 as start menu, batch files, desktop icons, and shortcuts. Note
|
|
18 that unlike other do_* functions, this one is called directly from
|
|
19 install.cc */
|
|
20
|
|
21
|
|
22 #include "win32.h"
|
|
23 #include <shlobj.h>
|
|
24
|
|
25 #include <io.h>
|
|
26 #include <stdio.h>
|
|
27 #include <stdlib.h>
|
|
28 #ifndef WIN32_NATIVE
|
|
29 #include <unistd.h>
|
|
30 #endif
|
|
31
|
|
32 #include "resource.h"
|
|
33 #include "ini.h"
|
|
34 #include "msg.h"
|
|
35 #include "state.h"
|
|
36 #include "concat.h"
|
|
37 #include "mkdir.h"
|
|
38 #include "dialog.h"
|
|
39 #include "version.h"
|
|
40 #include "reginfo.h"
|
|
41 #include "regedit.h"
|
|
42 #include "port.h"
|
|
43
|
|
44 extern "C" {
|
|
45 void make_link_2 (char *exepath, char *args, char *icon, char *lname);
|
|
46 };
|
|
47
|
|
48 static OSVERSIONINFO verinfo;
|
|
49
|
|
50 /* Lines starting with '@' are conditionals - include 'N' for NT,
|
|
51 '5' for Win95, '8' for Win98, '*' for all, like this:
|
|
52 echo foo
|
|
53 @N8
|
|
54 echo NT or 98
|
|
55 @*
|
|
56 */
|
|
57
|
|
58 #define COMMAND9XARGS "/E:4096 /c"
|
|
59 #define COMMAND9XEXE "\\command.com"
|
|
60
|
|
61 static char *iconname;
|
|
62 static char *batname;
|
|
63
|
|
64 static void
|
|
65 make_link (char *linkpath, char *title, char *target)
|
|
66 {
|
|
67 char argbuf[_MAX_PATH];
|
|
68 char *fname = concat (linkpath, "/", title, ".lnk", 0);
|
|
69
|
|
70 if (_access (fname, 0) == 0)
|
|
71 return; /* already exists */
|
|
72
|
|
73 msg ("make_link %s, %s, %s\n", fname, title, target);
|
|
74
|
|
75 mkdir_p (0, fname);
|
|
76
|
|
77 char *exepath, *args;
|
|
78
|
|
79 /* If we are running Win9x, build a command line. */
|
|
80 if (verinfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
|
|
81 {
|
|
82 exepath = target;
|
|
83 args = "";
|
|
84 }
|
|
85 else
|
|
86 {
|
|
87 char windir[MAX_PATH];
|
|
88
|
|
89 GetWindowsDirectory (windir, sizeof (windir));
|
|
90 exepath = concat (windir, COMMAND9XEXE, 0);
|
|
91 sprintf (argbuf, "%s %s", COMMAND9XARGS, target);
|
|
92 args = argbuf;
|
|
93 }
|
|
94
|
|
95 msg ("make_link_2 (%s, %s, %s, %s)", exepath, args, iconname, fname);
|
|
96 make_link_2 (exepath, args, iconname, fname);
|
|
97 }
|
|
98
|
|
99 static char*
|
|
100 find_xemacs_exe_path ()
|
|
101 {
|
|
102 if (xemacs_package->type == TY_CYGWIN)
|
|
103 return backslash (concat (root_dir, "/bin/", XEMACS_CYGWIN_ARCH_NAME, 0));
|
|
104 else
|
|
105 return backslash (concat (root_dir, "\\XEmacs-",
|
|
106 xemacs_package->info[xemacs_package->trust].version,
|
|
107 "\\", XEMACS_NATIVE_ARCH_NAME, 0));
|
|
108 }
|
|
109
|
|
110 static char*
|
|
111 find_xemacs_exe_name ()
|
|
112 {
|
462
|
113 /* Hack to support older versions. */
|
|
114 if (strncmp (xemacs_package->info[xemacs_package->trust].version,
|
|
115 "21.1", 4) == 0)
|
|
116 return strdup ("runemacs.exe");
|
|
117 else if (xemacs_package->type == TY_CYGWIN)
|
448
|
118 return backslash (concat ("xemacs-",
|
|
119 xemacs_package->info[xemacs_package->trust].version,
|
|
120 ".exe", 0));
|
|
121 else
|
|
122 return strdup ("xemacs.exe");
|
|
123 }
|
|
124
|
|
125 static void
|
|
126 start_menu (char *title, char *target)
|
|
127 {
|
|
128 char path[_MAX_PATH];
|
|
129 LPITEMIDLIST id;
|
|
130 int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0;
|
|
131 SHGetSpecialFolderLocation (NULL, issystem ? CSIDL_COMMON_PROGRAMS : CSIDL_PROGRAMS, &id);
|
|
132 SHGetPathFromIDList (id, path);
|
|
133 // following lines added because it appears Win95 does not use common programs
|
|
134 // unless it comes into play when multiple users for Win95 is enabled
|
|
135 msg("Program directory for program link: %s",path);
|
|
136 if ( strlen(path) == 0) {
|
|
137 SHGetSpecialFolderLocation (NULL, CSIDL_PROGRAMS, &id);
|
|
138 SHGetPathFromIDList (id, path);
|
|
139 msg("Program directory for program link changed to: %s",path);
|
|
140 }
|
|
141 // end of Win95 addition
|
|
142 strcat (path, "/");
|
|
143 strcat (path, XEMACS_INFO_XEMACS_ORG_REGISTRY_NAME);
|
|
144 make_link (path, title, target);
|
|
145 }
|
|
146
|
|
147 static void
|
|
148 desktop_icon (char *title, char *target)
|
|
149 {
|
|
150 char path[_MAX_PATH];
|
|
151 LPITEMIDLIST id;
|
|
152 int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0;
|
|
153 //SHGetSpecialFolderLocation (NULL, issystem ? CSIDL_DESKTOP : CSIDL_COMMON_DESKTOPDIRECTORY, &id);
|
|
154 SHGetSpecialFolderLocation (NULL, issystem ? CSIDL_COMMON_DESKTOPDIRECTORY : CSIDL_DESKTOPDIRECTORY, &id);
|
|
155 SHGetPathFromIDList (id, path);
|
|
156 // following lines added because it appears Win95 does not use common programs
|
|
157 // unless it comes into play when multiple users for Win95 is enabled
|
|
158 msg("Desktop directory for desktop link: %s",path);
|
|
159 if ( strlen(path) == 0) {
|
|
160 SHGetSpecialFolderLocation (NULL, CSIDL_DESKTOPDIRECTORY, &id);
|
|
161 SHGetPathFromIDList (id, path);
|
|
162 msg("Desktop directory for deskop link changed to: %s",path);
|
|
163 }
|
|
164 // end of Win95 addition
|
|
165 make_link (path, title, target);
|
|
166 }
|
|
167
|
|
168 static int
|
|
169 uexists (char *path)
|
|
170 {
|
|
171 char *f = concat (root_dir, path, 0);
|
|
172 int a = _access (f, 0);
|
|
173 free (f);
|
|
174 if (a == 0)
|
|
175 return 1;
|
|
176 return 0;
|
|
177 }
|
|
178
|
|
179 static void
|
|
180 make_passwd_group ()
|
|
181 {
|
|
182 if (verinfo.dwPlatformId != VER_PLATFORM_WIN32_NT)
|
|
183 {
|
|
184 int i;
|
|
185
|
|
186 LOOP_PACKAGES
|
|
187 {
|
|
188 if (!strcmp (package[i].name, "cygwin"))
|
|
189 {
|
|
190 /* mkpasswd and mkgroup are not working on 9x/ME up to 1.1.5-4 */
|
|
191 char *border_version = canonicalize_version ("1.1.5-4");
|
|
192 char *inst_version = canonicalize_version (pi.version);
|
|
193
|
|
194 if (strcmp (inst_version, border_version) <= 0)
|
|
195 return;
|
|
196
|
|
197 break;
|
|
198 }
|
|
199 }
|
|
200 }
|
|
201
|
|
202 if (uexists ("/etc/passwd") && uexists ("/etc/group"))
|
|
203 return;
|
|
204
|
|
205 char *fname = concat (root_dir, "/etc/postinstall/passwd-grp.bat", 0);
|
|
206 mkdir_p (0, fname);
|
|
207
|
|
208 FILE *p = fopen (fname, "wb");
|
|
209 if (!p)
|
|
210 return;
|
|
211
|
|
212 if (!uexists ("/etc/passwd"))
|
|
213 fprintf (p, "bin\\mkpasswd -l > etc\\passwd\n");
|
|
214 if (!uexists ("/etc/group"))
|
|
215 fprintf (p, "bin\\mkgroup -l > etc\\group\n");
|
|
216
|
|
217 fclose (p);
|
|
218 }
|
|
219
|
|
220 static void
|
|
221 save_icon ()
|
|
222 {
|
|
223 iconname = backslash (concat (root_dir, XEMACS_RESOURCE_DIR,
|
|
224 "xemacs.ico", 0));
|
|
225
|
|
226 HRSRC rsrc = FindResource (NULL, "XEMACS.ICON", "FILE");
|
|
227 if (rsrc == NULL)
|
|
228 {
|
|
229 fatal ("FindResource failed");
|
|
230 }
|
|
231 HGLOBAL res = LoadResource (NULL, rsrc);
|
|
232 char *data = (char *) LockResource (res);
|
|
233 int len = SizeofResource (NULL, rsrc);
|
|
234
|
|
235 FILE *f = fopen (iconname, "wb");
|
|
236 if (f)
|
|
237 {
|
|
238 fwrite (data, 1, len, f);
|
|
239 fclose (f);
|
|
240 }
|
|
241 }
|
|
242
|
|
243 static void
|
|
244 do_desktop_setup()
|
|
245 {
|
|
246 save_icon ();
|
|
247
|
|
248 if (root_menu && batname) {
|
|
249 start_menu ("XEmacs", batname);
|
|
250 }
|
|
251
|
|
252 if (root_desktop && batname) {
|
|
253 desktop_icon ("XEmacs", batname);
|
|
254 }
|
|
255
|
|
256 // set regkeys for the application
|
|
257 if (xemacs_package != 0)
|
|
258 {
|
|
259 int issystem = (root_scope == IDC_ROOT_SYSTEM ? 1 : 0);
|
|
260 if (xemacs_package->type == TY_NATIVE)
|
|
261 {
|
|
262 #define FROB(exe) set_app_path ((exe), \
|
|
263 find_xemacs_exe_path (), \
|
|
264 issystem)
|
|
265 FROB (find_xemacs_exe_name ());
|
|
266 FROB ("runemacs.exe");
|
|
267 FROB ("xemacs.exe");
|
|
268 #undef FROB
|
|
269 }
|
|
270 else if (xemacs_package->type == TY_CYGWIN)
|
|
271 {
|
|
272 int junk;
|
|
273 char* root = find_cygwin_root (&junk);
|
|
274 #define FROB(exe) set_app_path ((exe), \
|
|
275 concat (find_xemacs_exe_path (), ";", \
|
|
276 root, "\\bin;", \
|
|
277 root, "\\usr\\bin", 0), \
|
|
278 issystem)
|
|
279 FROB (find_xemacs_exe_name ());
|
|
280 FROB ("runemacs.exe");
|
|
281 FROB ("xemacs.exe");
|
|
282 #undef FROB
|
|
283 }
|
|
284 }
|
|
285 }
|
|
286
|
|
287 static int da[] = { IDC_ROOT_DESKTOP, 0 };
|
|
288 static int ma[] = { IDC_ROOT_MENU, 0 };
|
|
289
|
|
290 static void
|
|
291 check_if_enable_next (HWND h)
|
|
292 {
|
|
293 EnableWindow (GetDlgItem (h, IDOK), 1);
|
|
294 }
|
|
295
|
|
296 static void
|
|
297 load_dialog (HWND h)
|
|
298 {
|
|
299 rbset (h, da, root_desktop);
|
|
300 rbset (h, ma, root_menu);
|
|
301 check_if_enable_next (h);
|
|
302 }
|
|
303
|
|
304 static int check_desktop (char *title, char *target)
|
|
305 {
|
|
306 char path[_MAX_PATH];
|
|
307 LPITEMIDLIST id;
|
|
308 int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0;
|
|
309 SHGetSpecialFolderLocation (NULL, issystem ? CSIDL_COMMON_DESKTOPDIRECTORY : CSIDL_DESKTOPDIRECTORY, &id);
|
|
310 SHGetPathFromIDList (id, path);
|
|
311 // following lines added because it appears Win95 does not use common programs
|
|
312 // unless it comes into play when multiple users for Win95 is enabled
|
|
313 msg ("Desktop directory for desktop link: %s",path);
|
|
314 if (strlen (path) == 0) {
|
|
315 SHGetSpecialFolderLocation (NULL, CSIDL_DESKTOPDIRECTORY, &id);
|
|
316 SHGetPathFromIDList (id, path);
|
|
317 msg ("Desktop directory for deskop link changed to: %s",path);
|
|
318 }
|
|
319 // end of Win95 addition
|
|
320 char *fname = concat (path, "/", title, ".lnk", 0);
|
|
321
|
|
322 if (_access (fname, 0) == 0)
|
|
323 return 0; /* already exists */
|
|
324
|
|
325 fname = concat (path, "/", title, ".pif", 0); /* check for a pif as well */
|
|
326
|
|
327 if (_access (fname, 0) == 0)
|
|
328 return 0; /* already exists */
|
|
329
|
|
330 return IDC_ROOT_DESKTOP;
|
|
331 }
|
|
332
|
|
333 static int check_startmenu (char *title, char *target)
|
|
334 {
|
|
335 char path[_MAX_PATH];
|
|
336 LPITEMIDLIST id;
|
|
337 int issystem = (root_scope == IDC_ROOT_SYSTEM) ? 1 : 0;
|
|
338 SHGetSpecialFolderLocation (NULL, issystem ? CSIDL_COMMON_PROGRAMS : CSIDL_PROGRAMS, &id);
|
|
339 SHGetPathFromIDList (id, path);
|
|
340 // following lines added because it appears Win95 does not use common programs
|
|
341 // unless it comes into play when multiple users for Win95 is enabled
|
|
342 msg ("Program directory for program link: %s",path);
|
|
343 if (strlen (path) == 0) {
|
|
344 SHGetSpecialFolderLocation (NULL, CSIDL_PROGRAMS, &id);
|
|
345 SHGetPathFromIDList (id, path);
|
|
346 msg ("Program directory for program link changed to: %s",path);
|
|
347 }
|
|
348 // end of Win95 addition
|
|
349 strcat (path, "/");
|
|
350 strcat (path, XEMACS_INFO_XEMACS_ORG_REGISTRY_NAME);
|
|
351 char *fname = concat (path, "/", title, ".lnk", 0);
|
|
352
|
|
353 if (_access (fname, 0) == 0)
|
|
354 return 0; /* already exists */
|
|
355
|
|
356 fname = concat (path, "/", title, ".pif", 0); /* check for a pif as well */
|
|
357
|
|
358 if (_access (fname, 0) == 0)
|
|
359 return 0; /* already exists */
|
|
360
|
|
361 return IDC_ROOT_MENU;
|
|
362 }
|
|
363
|
|
364 static void
|
|
365 save_dialog (HWND h)
|
|
366 {
|
|
367 root_desktop= rbget (h, da);
|
|
368 root_menu = rbget (h, ma);
|
|
369 }
|
|
370
|
|
371 static BOOL
|
|
372 dialog_cmd (HWND h, int id, HWND hwndctl, UINT code)
|
|
373 {
|
|
374 switch (id)
|
|
375 {
|
|
376
|
|
377 case IDC_ROOT_DESKTOP:
|
|
378 case IDC_ROOT_MENU:
|
|
379 save_dialog (h);
|
|
380 check_if_enable_next (h);
|
|
381 break;
|
|
382
|
|
383 case IDOK:
|
|
384 save_dialog (h);
|
|
385 do_desktop_setup();
|
|
386 NEXT (IDD_S_POSTINSTALL);
|
|
387 break;
|
|
388
|
|
389 case IDC_BACK:
|
|
390 save_dialog (h);
|
|
391 NEXT (IDD_CHOOSE);
|
|
392 break;
|
|
393
|
|
394 case IDCANCEL:
|
|
395 NEXT (0);
|
|
396 break;
|
|
397 }
|
|
398 return FALSE;
|
|
399 }
|
|
400
|
|
401 static BOOL CALLBACK
|
|
402 dialog_proc (HWND h, UINT message, WPARAM wParam, LPARAM lParam)
|
|
403 {
|
|
404 switch (message)
|
|
405 {
|
|
406 case WM_INITDIALOG:
|
|
407 load_dialog (h);
|
|
408 return FALSE;
|
|
409 case WM_COMMAND:
|
|
410 return HANDLE_WM_COMMAND (h, wParam, lParam, dialog_cmd);
|
|
411 }
|
|
412 return FALSE;
|
|
413 }
|
|
414
|
|
415 void
|
|
416 do_desktop (HINSTANCE h)
|
|
417 {
|
|
418 CoInitialize (NULL);
|
|
419
|
|
420 verinfo.dwOSVersionInfoSize = sizeof (verinfo);
|
|
421 GetVersionEx (&verinfo);
|
|
422 batname = 0;
|
|
423
|
|
424 if (xemacs_package != 0 && xemacs_package->type != TY_GENERIC)
|
|
425 {
|
|
426 batname = concat (find_xemacs_exe_path (), "\\",
|
452
|
427 find_xemacs_exe_name (),
|
|
428 0);
|
448
|
429 root_desktop = check_desktop ("XEmacs", batname);
|
|
430 root_menu = check_startmenu ("XEmacs", batname);
|
|
431 }
|
|
432 else
|
|
433 {
|
|
434 root_desktop = 0;
|
|
435 root_menu = 0;
|
|
436 }
|
|
437
|
|
438 int rv = 0;
|
|
439
|
|
440 rv = DialogBox (h, MAKEINTRESOURCE (IDD_DESKTOP), 0, dialog_proc);
|
|
441 if (rv == -1)
|
|
442 fatal (IDS_DIALOG_FAILED);
|
|
443 }
|