blob: f1d3dc6eb5991c02a4e2d62d3c5512541f060243 [file] [log] [blame]
Bram Moolenaaredf3f972016-08-29 22:49:24 +02001/* vi:set ts=8 sts=4 sw=4 noet:
Bram Moolenaar071d4272004-06-13 20:20:40 +00002 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 *
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
8 */
9/*
Bram Moolenaar30e8e732019-09-27 13:08:36 +020010 * dosinst.h: Common code for dosinst.c and uninstall.c
Bram Moolenaar071d4272004-06-13 20:20:40 +000011 */
Bram Moolenaar362e1a32006-03-06 23:29:24 +000012
Bram Moolenaar071d4272004-06-13 20:20:40 +000013#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <sys/stat.h>
17#include <fcntl.h>
18
19#ifndef UNIX_LINT
Bram Moolenaar2f189752020-02-12 21:15:43 +010020# include <io.h>
Bram Moolenaar071d4272004-06-13 20:20:40 +000021# include <ctype.h>
22
Bram Moolenaar6199d432017-10-14 19:05:44 +020023# include <direct.h>
Bram Moolenaar071d4272004-06-13 20:20:40 +000024
Bram Moolenaar6199d432017-10-14 19:05:44 +020025# include <windows.h>
26# include <shlobj.h>
Bram Moolenaar071d4272004-06-13 20:20:40 +000027#endif
28
29#ifdef UNIX_LINT
Bram Moolenaar9bf703d2019-11-30 19:44:38 +010030// Running lint on Unix: Some things are missing.
Bram Moolenaar071d4272004-06-13 20:20:40 +000031char *searchpath(char *name);
32#endif
33
Bram Moolenaar48e330a2016-02-23 14:53:34 +010034#if defined(UNIX_LINT)
Bram Moolenaar071d4272004-06-13 20:20:40 +000035# include <unistd.h>
36# include <errno.h>
37#endif
38
39#include "version.h"
40
Bram Moolenaar48e330a2016-02-23 14:53:34 +010041#if defined(UNIX_LINT)
Bram Moolenaar071d4272004-06-13 20:20:40 +000042# define vim_mkdir(x, y) mkdir((char *)(x), y)
43#else
Bram Moolenaareae1b912019-05-09 15:12:55 +020044# define vim_mkdir(x, y) _mkdir((char *)(x))
Bram Moolenaar071d4272004-06-13 20:20:40 +000045#endif
Bram Moolenaarab8205e2010-07-07 15:14:03 +020046
Bram Moolenaar48e330a2016-02-23 14:53:34 +010047#define sleep(n) Sleep((n) * 1000)
Bram Moolenaarab8205e2010-07-07 15:14:03 +020048
Bram Moolenaar9bf703d2019-11-30 19:44:38 +010049// ----------------------------------------
Bram Moolenaar071d4272004-06-13 20:20:40 +000050
51
Bram Moolenaar9bf703d2019-11-30 19:44:38 +010052#define BUFSIZE (MAX_PATH*2) // long enough to hold a file name path
Bram Moolenaar071d4272004-06-13 20:20:40 +000053#define NUL 0
54
55#define FAIL 0
56#define OK 1
57
58#ifndef FALSE
59# define FALSE 0
60#endif
61#ifndef TRUE
62# define TRUE 1
63#endif
64
Bram Moolenaar760d14a2010-07-31 22:03:44 +020065/*
66 * Modern way of creating registry entries, also works on 64 bit windows when
67 * compiled as a 32 bit program.
68 */
69# ifndef KEY_WOW64_64KEY
70# define KEY_WOW64_64KEY 0x0100
71# endif
Bram Moolenaar6199d432017-10-14 19:05:44 +020072# ifndef KEY_WOW64_32KEY
73# define KEY_WOW64_32KEY 0x0200
74# endif
Bram Moolenaar760d14a2010-07-31 22:03:44 +020075
Bram Moolenaar35d7a2f2022-06-09 20:53:54 +010076#ifdef __MINGW32__
77# define UNUSED __attribute__((unused))
78#else
79# define UNUSED
80#endif
81
Bram Moolenaar071d4272004-06-13 20:20:40 +000082#define VIM_STARTMENU "Programs\\Vim " VIM_VERSION_SHORT
83
Bram Moolenaar9bf703d2019-11-30 19:44:38 +010084int interactive; // non-zero when running interactively
Bram Moolenaar071d4272004-06-13 20:20:40 +000085
86/*
87 * Call malloc() and exit when out of memory.
88 */
89 static void *
90alloc(int len)
91{
Bram Moolenaare4963c52019-02-22 19:41:08 +010092 void *p;
Bram Moolenaar071d4272004-06-13 20:20:40 +000093
Bram Moolenaare4963c52019-02-22 19:41:08 +010094 p = malloc(len);
95 if (p == NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +000096 {
97 printf("ERROR: out of memory\n");
98 exit(1);
99 }
Bram Moolenaare4963c52019-02-22 19:41:08 +0100100 return p;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000101}
102
103/*
104 * The toupper() in Bcc 5.5 doesn't work, use our own implementation.
105 */
106 static int
107mytoupper(int c)
108{
109 if (c >= 'a' && c <= 'z')
110 return c - 'a' + 'A';
111 return c;
112}
113
114 static void
115myexit(int n)
116{
117 if (!interactive)
118 {
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100119 // Present a prompt, otherwise error messages can't be read.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000120 printf("Press Enter to continue\n");
121 rewind(stdin);
122 (void)getchar();
123 }
124 exit(n);
125}
126
Bram Moolenaar071d4272004-06-13 20:20:40 +0000127
Bram Moolenaar6199d432017-10-14 19:05:44 +0200128typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS)(HANDLE, PBOOL);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000129/*
Bram Moolenaar6199d432017-10-14 19:05:44 +0200130 * Check if this is a 64-bit OS.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000131 */
Bram Moolenaar6199d432017-10-14 19:05:44 +0200132 static BOOL
133is_64bit_os(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000134{
Bram Moolenaar6199d432017-10-14 19:05:44 +0200135#ifdef _WIN64
136 return TRUE;
137#else
138 BOOL bIsWow64 = FALSE;
139 LPFN_ISWOW64PROCESS pIsWow64Process;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000140
Bram Moolenaar6199d432017-10-14 19:05:44 +0200141 pIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(
142 GetModuleHandle("kernel32"), "IsWow64Process");
143 if (pIsWow64Process != NULL)
144 pIsWow64Process(GetCurrentProcess(), &bIsWow64);
145 return bIsWow64;
146#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000147}
148
Bram Moolenaar071d4272004-06-13 20:20:40 +0000149 static char *
150searchpath(char *name)
151{
152 static char widename[2 * BUFSIZE];
153 static char location[2 * BUFSIZE + 2];
154
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100155 // There appears to be a bug in FindExecutableA() on Windows NT.
156 // Use FindExecutableW() instead...
Bram Moolenaar6199d432017-10-14 19:05:44 +0200157 MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)name, -1,
158 (LPWSTR)widename, BUFSIZE);
159 if (FindExecutableW((LPCWSTR)widename, (LPCWSTR)"",
160 (LPWSTR)location) > (HINSTANCE)32)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000161 {
Bram Moolenaar6199d432017-10-14 19:05:44 +0200162 WideCharToMultiByte(CP_ACP, 0, (LPWSTR)location, -1,
163 (LPSTR)widename, 2 * BUFSIZE, NULL, NULL);
164 return widename;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000165 }
166 return NULL;
167}
Bram Moolenaar071d4272004-06-13 20:20:40 +0000168
169/*
170 * Call searchpath() and save the result in allocated memory, or return NULL.
171 */
172 static char *
173searchpath_save(char *name)
174{
175 char *p;
176 char *s;
177
178 p = searchpath(name);
179 if (p == NULL)
180 return NULL;
181 s = alloc(strlen(p) + 1);
182 strcpy(s, p);
183 return s;
184}
185
Bram Moolenaar4c3f5362006-04-11 21:38:50 +0000186
187#ifndef CSIDL_COMMON_PROGRAMS
188# define CSIDL_COMMON_PROGRAMS 0x0017
189#endif
190#ifndef CSIDL_COMMON_DESKTOPDIRECTORY
191# define CSIDL_COMMON_DESKTOPDIRECTORY 0x0019
192#endif
193
Bram Moolenaar071d4272004-06-13 20:20:40 +0000194/*
195 * Get the path to a requested Windows shell folder.
196 *
197 * Return FAIL on error, OK on success
198 */
199 int
200get_shell_folder_path(
201 char *shell_folder_path,
202 const char *shell_folder_name)
203{
204 /*
205 * The following code was successfully built with make_mvc.mak.
206 * The resulting executable worked on Windows 95, Millennium Edition, and
207 * 2000 Professional. But it was changed after testing...
208 */
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100209 LPITEMIDLIST pidl = 0; // Pointer to an Item ID list allocated below
210 LPMALLOC pMalloc; // Pointer to an IMalloc interface
Bram Moolenaar071d4272004-06-13 20:20:40 +0000211 int csidl;
212 int alt_csidl = -1;
213 static int desktop_csidl = -1;
214 static int programs_csidl = -1;
215 int *pcsidl;
216 int r;
217
218 if (strcmp(shell_folder_name, "desktop") == 0)
219 {
220 pcsidl = &desktop_csidl;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000221 csidl = CSIDL_COMMON_DESKTOPDIRECTORY;
222 alt_csidl = CSIDL_DESKTOP;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000223 }
224 else if (strncmp(shell_folder_name, "Programs", 8) == 0)
225 {
226 pcsidl = &programs_csidl;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000227 csidl = CSIDL_COMMON_PROGRAMS;
228 alt_csidl = CSIDL_PROGRAMS;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000229 }
230 else
231 {
232 printf("\nERROR (internal) unrecognised shell_folder_name: \"%s\"\n\n",
233 shell_folder_name);
234 return FAIL;
235 }
236
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100237 // Did this stuff before, use the same ID again.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000238 if (*pcsidl >= 0)
239 {
240 csidl = *pcsidl;
241 alt_csidl = -1;
242 }
243
244retry:
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100245 // Initialize pointer to IMalloc interface
Bram Moolenaar071d4272004-06-13 20:20:40 +0000246 if (NOERROR != SHGetMalloc(&pMalloc))
247 {
248 printf("\nERROR getting interface for shell_folder_name: \"%s\"\n\n",
249 shell_folder_name);
250 return FAIL;
251 }
252
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100253 // Get an ITEMIDLIST corresponding to the folder code
Bram Moolenaar071d4272004-06-13 20:20:40 +0000254 if (NOERROR != SHGetSpecialFolderLocation(0, csidl, &pidl))
255 {
256 if (alt_csidl < 0 || NOERROR != SHGetSpecialFolderLocation(0,
257 alt_csidl, &pidl))
258 {
259 printf("\nERROR getting ITEMIDLIST for shell_folder_name: \"%s\"\n\n",
260 shell_folder_name);
261 return FAIL;
262 }
263 csidl = alt_csidl;
264 alt_csidl = -1;
265 }
266
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100267 // Translate that ITEMIDLIST to a string
Bram Moolenaar071d4272004-06-13 20:20:40 +0000268 r = SHGetPathFromIDList(pidl, shell_folder_path);
269
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100270 // Free the data associated with pidl
Bram Moolenaar071d4272004-06-13 20:20:40 +0000271 pMalloc->lpVtbl->Free(pMalloc, pidl);
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100272 // Release the IMalloc interface
Bram Moolenaar071d4272004-06-13 20:20:40 +0000273 pMalloc->lpVtbl->Release(pMalloc);
274
275 if (!r)
276 {
277 if (alt_csidl >= 0)
278 {
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100279 // We probably get here for Windows 95: the "all users"
280 // desktop/start menu entry doesn't exist.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000281 csidl = alt_csidl;
282 alt_csidl = -1;
283 goto retry;
284 }
285 printf("\nERROR translating ITEMIDLIST for shell_folder_name: \"%s\"\n\n",
286 shell_folder_name);
287 return FAIL;
288 }
289
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100290 // If there is an alternative: verify we can write in this directory.
291 // This should cause a retry when the "all users" directory exists but we
292 // are a normal user and can't write there.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000293 if (alt_csidl >= 0)
294 {
295 char tbuf[BUFSIZE];
296 FILE *fd;
297
298 strcpy(tbuf, shell_folder_path);
299 strcat(tbuf, "\\vim write test");
300 fd = fopen(tbuf, "w");
301 if (fd == NULL)
302 {
303 csidl = alt_csidl;
304 alt_csidl = -1;
305 goto retry;
306 }
307 fclose(fd);
308 unlink(tbuf);
309 }
310
311 /*
312 * Keep the found csidl for next time, so that we don't have to do the
313 * write test every time.
314 */
315 if (*pcsidl < 0)
316 *pcsidl = csidl;
317
318 if (strncmp(shell_folder_name, "Programs\\", 9) == 0)
319 strcat(shell_folder_path, shell_folder_name + 8);
320
321 return OK;
322}
Bram Moolenaar071d4272004-06-13 20:20:40 +0000323
324/*
325 * List of targets. The first one (index zero) is used for the default path
326 * for the batch files.
327 */
Bram Moolenaar97b2ad32006-03-18 21:40:56 +0000328#define TARGET_COUNT 9
Bram Moolenaar071d4272004-06-13 20:20:40 +0000329
330struct
331{
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100332 char *name; // Vim exe name (without .exe)
333 char *batname; // batch file name
334 char *lnkname; // shortcut file name
335 char *exename; // exe file name
336 char *exenamearg; // exe file name when using exearg
337 char *exearg; // argument for vim.exe or gvim.exe
338 char *oldbat; // path to existing xxx.bat or NULL
339 char *oldexe; // path to existing xxx.exe or NULL
340 char batpath[BUFSIZE]; // path of batch file to create; not
341 // created when it's empty
Bram Moolenaar071d4272004-06-13 20:20:40 +0000342} targets[TARGET_COUNT] =
343{
Yegappan Lakshmanana34b4462022-06-11 10:43:26 +0100344 {"all", "batch files", NULL, NULL, NULL, NULL, NULL, NULL, ""},
Bram Moolenaar071d4272004-06-13 20:20:40 +0000345 {"vim", "vim.bat", "Vim.lnk",
Yegappan Lakshmanana34b4462022-06-11 10:43:26 +0100346 "vim.exe", "vim.exe", "", NULL, NULL, ""},
Bram Moolenaar071d4272004-06-13 20:20:40 +0000347 {"gvim", "gvim.bat", "gVim.lnk",
Yegappan Lakshmanana34b4462022-06-11 10:43:26 +0100348 "gvim.exe", "gvim.exe", "", NULL, NULL, ""},
Bram Moolenaar071d4272004-06-13 20:20:40 +0000349 {"evim", "evim.bat", "gVim Easy.lnk",
Yegappan Lakshmanana34b4462022-06-11 10:43:26 +0100350 "evim.exe", "gvim.exe", "-y", NULL, NULL, ""},
Bram Moolenaar071d4272004-06-13 20:20:40 +0000351 {"view", "view.bat", "Vim Read-only.lnk",
Yegappan Lakshmanana34b4462022-06-11 10:43:26 +0100352 "view.exe", "vim.exe", "-R", NULL, NULL, ""},
Bram Moolenaar071d4272004-06-13 20:20:40 +0000353 {"gview", "gview.bat", "gVim Read-only.lnk",
Yegappan Lakshmanana34b4462022-06-11 10:43:26 +0100354 "gview.exe", "gvim.exe", "-R", NULL, NULL, ""},
Bram Moolenaar071d4272004-06-13 20:20:40 +0000355 {"vimdiff", "vimdiff.bat", "Vim Diff.lnk",
Yegappan Lakshmanana34b4462022-06-11 10:43:26 +0100356 "vimdiff.exe","vim.exe", "-d", NULL, NULL, ""},
Bram Moolenaar071d4272004-06-13 20:20:40 +0000357 {"gvimdiff","gvimdiff.bat", "gVim Diff.lnk",
Yegappan Lakshmanana34b4462022-06-11 10:43:26 +0100358 "gvimdiff.exe","gvim.exe", "-d", NULL, NULL, ""},
Bram Moolenaar97b2ad32006-03-18 21:40:56 +0000359 {"vimtutor","vimtutor.bat", "Vim tutor.lnk",
Yegappan Lakshmanana34b4462022-06-11 10:43:26 +0100360 "vimtutor.bat", "vimtutor.bat", "", NULL, NULL, ""},
Bram Moolenaar071d4272004-06-13 20:20:40 +0000361};
362
Bram Moolenaar1fa8d2c2020-02-17 22:53:14 +0100363/* Uninstall key for vim.bat, etc. */
364#define VIMBAT_UNINSTKEY "rem # uninstall key: " VIM_VERSION_NODOT " #"
365
Bram Moolenaar071d4272004-06-13 20:20:40 +0000366#define ICON_COUNT 3
367char *(icon_names[ICON_COUNT]) =
368 {"gVim " VIM_VERSION_SHORT,
369 "gVim Easy " VIM_VERSION_SHORT,
370 "gVim Read only " VIM_VERSION_SHORT};
371char *(icon_link_names[ICON_COUNT]) =
372 {"gVim " VIM_VERSION_SHORT ".lnk",
373 "gVim Easy " VIM_VERSION_SHORT ".lnk",
374 "gVim Read only " VIM_VERSION_SHORT ".lnk"};
375
Bram Moolenaar6199d432017-10-14 19:05:44 +0200376/* This is only used for dosinst.c. */
377#if defined(DOSINST)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000378/*
379 * Run an external command and wait for it to finish.
380 */
381 static void
382run_command(char *cmd)
383{
384 char *cmd_path;
Bram Moolenaarbbd854d2019-02-18 22:19:33 +0100385 char cmd_buf[BUFSIZE * 2 + 35];
Bram Moolenaar071d4272004-06-13 20:20:40 +0000386 char *p;
387
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100388 // On WinNT, 'start' is a shell built-in for cmd.exe rather than an
389 // executable (start.exe) like in Win9x.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000390 cmd_path = searchpath_save("cmd.exe");
391 if (cmd_path != NULL)
392 {
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100393 // There is a cmd.exe, so this might be Windows NT. If it is,
394 // we need to call cmd.exe explicitly. If it is a later OS,
395 // calling cmd.exe won't hurt if it is present.
396 // Also, "start" on NT expects a window title argument.
397 // Replace the slashes with backslashes.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000398 while ((p = strchr(cmd_path, '/')) != NULL)
399 *p = '\\';
Bram Moolenaar442b4222010-05-24 21:34:22 +0200400 sprintf(cmd_buf, "%s /c start \"vimcmd\" /wait %s", cmd_path, cmd);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000401 free(cmd_path);
402 }
403 else
404 {
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100405 // No cmd.exe, just make the call and let the system handle it.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000406 sprintf(cmd_buf, "start /w %s", cmd);
407 }
408 system(cmd_buf);
409}
410#endif
411
412/*
413 * Append a backslash to "name" if there isn't one yet.
414 */
Bram Moolenaar6aa2cd42016-02-16 15:06:59 +0100415 void
Bram Moolenaar071d4272004-06-13 20:20:40 +0000416add_pathsep(char *name)
417{
418 int len = strlen(name);
419
420 if (len > 0 && name[len - 1] != '\\' && name[len - 1] != '/')
421 strcat(name, "\\");
422}
423
424/*
425 * The normal chdir() does not change the default drive. This one does.
426 */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000427 int
428change_drive(int drive)
429{
Bram Moolenaar071d4272004-06-13 20:20:40 +0000430 char temp[3] = "-:";
431 temp[0] = (char)(drive + 'A' - 1);
432 return !SetCurrentDirectory(temp);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000433}
434
435/*
436 * Change directory to "path".
437 * Return 0 for success, -1 for failure.
438 */
439 int
440mch_chdir(char *path)
441{
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100442 if (path[0] == NUL) // just checking...
Bram Moolenaar071d4272004-06-13 20:20:40 +0000443 return 0;
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100444 if (path[1] == ':') // has a drive name
Bram Moolenaar071d4272004-06-13 20:20:40 +0000445 {
446 if (change_drive(mytoupper(path[0]) - 'A' + 1))
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100447 return -1; // invalid drive name
Bram Moolenaar071d4272004-06-13 20:20:40 +0000448 path += 2;
449 }
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100450 if (*path == NUL) // drive name only
Bram Moolenaar071d4272004-06-13 20:20:40 +0000451 return 0;
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100452 return chdir(path); // let the normal chdir() do the rest
Bram Moolenaar071d4272004-06-13 20:20:40 +0000453}
454
455/*
456 * Expand the executable name into a full path name.
457 */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000458 static char *
Bram Moolenaar35d7a2f2022-06-09 20:53:54 +0100459my_fullpath(char *buf, char *fname UNUSED, int len)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000460{
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100461 // Only GetModuleFileName() will get the long file name path.
462 // GetFullPathName() may still use the short (FAT) name.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000463 DWORD len_read = GetModuleFileName(NULL, buf, (size_t)len);
464
465 return (len_read > 0 && len_read < (DWORD)len) ? buf : NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000466}
Bram Moolenaar071d4272004-06-13 20:20:40 +0000467
468/*
469 * Remove the tail from a file or directory name.
470 * Puts a NUL on the last '/' or '\'.
471 */
472 static void
473remove_tail(char *path)
474{
475 int i;
476
477 for (i = strlen(path) - 1; i > 0; --i)
478 if (path[i] == '/' || path[i] == '\\')
479 {
480 path[i] = NUL;
481 break;
482 }
483}
484
485
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100486char installdir[MAX_PATH-9]; // top of the installation dir, where the
487 // install.exe is located, E.g.:
488 // "c:\vim\vim60"
489int runtimeidx; // index in installdir[] where "vim60" starts
490char *sysdrive; // system drive or "c:\"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000491
492/*
493 * Setup for using this program.
494 * Sets "installdir[]".
495 */
496 static void
497do_inits(char **argv)
498{
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100499 // Find out the full path of our executable.
Bram Moolenaare4963c52019-02-22 19:41:08 +0100500 if (my_fullpath(installdir, argv[0], sizeof(installdir)) == NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000501 {
502 printf("ERROR: Cannot get name of executable\n");
503 myexit(1);
504 }
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100505 // remove the tail, the executable name "install.exe"
Bram Moolenaar071d4272004-06-13 20:20:40 +0000506 remove_tail(installdir);
507
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100508 // change to the installdir
Bram Moolenaar071d4272004-06-13 20:20:40 +0000509 mch_chdir(installdir);
510
Bram Moolenaar9bf703d2019-11-30 19:44:38 +0100511 // Find the system drive. Only used for searching the Vim executable, not
512 // very important.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000513 sysdrive = getenv("SYSTEMDRIVE");
514 if (sysdrive == NULL || *sysdrive == NUL)
515 sysdrive = "C:\\";
516}