2 * git-wrapper - replace cmd\git.cmd with an executable
4 * Copyright (C) 2012 Pat Thoyts <patthoyts@users.sourceforge.net>
8 #define WIN32_LEAN_AND_MEAN
16 int __stdcall
wmain(void)
22 WCHAR exepath
[MAX_PATH
], exe
[MAX_PATH
];
23 LPWSTR cmd
= NULL
, path2
= NULL
, exep
= exe
;
27 /* get the installation location */
28 GetModuleFileName(NULL
, exepath
, MAX_PATH
);
29 PathRemoveFileSpec(exepath
);
30 PathRemoveFileSpec(exepath
);
32 /* set the default exe module */
34 PathAppend(exe
, L
"bin\\git.exe");
36 /* if not set, set TERM to msys */
37 if (GetEnvironmentVariable(L
"TERM", NULL
, 0) == 0) {
38 SetEnvironmentVariable(L
"TERM", L
"msys");
41 /* if not set, set PLINK_PROTOCOL to ssh */
42 if (GetEnvironmentVariable(L
"PLINK_PROTOCOL", NULL
, 0) == 0) {
43 SetEnvironmentVariable(L
"PLINK_PROTOCOL", L
"ssh");
46 /* set HOME to %HOMEDRIVE%%HOMEPATH% or %USERPROFILE%
47 * With roaming profiles: HOMEPATH is the roaming location and
48 * USERPROFILE is the local location
50 if (GetEnvironmentVariable(L
"HOME", NULL
, 0) == 0) {
52 len
= GetEnvironmentVariable(L
"HOMEPATH", NULL
, 0);
54 len
= GetEnvironmentVariable(L
"USERPROFILE", NULL
, 0);
56 e
= (LPWSTR
)malloc(len
* sizeof(WCHAR
));
57 GetEnvironmentVariable(L
"USERPROFILE", e
, len
);
58 SetEnvironmentVariable(L
"HOME", e
);
63 len
+= GetEnvironmentVariable(L
"HOMEDRIVE", NULL
, 0);
64 e
= (LPWSTR
)malloc(sizeof(WCHAR
) * (len
+ 2));
65 n
= GetEnvironmentVariable(L
"HOMEDRIVE", e
, len
);
66 GetEnvironmentVariable(L
"HOMEPATH", &e
[n
], len
-n
);
67 SetEnvironmentVariable(L
"HOME", e
);
73 len
= GetEnvironmentVariable(L
"PATH", NULL
, 0);
74 len
= sizeof(WCHAR
) * (len
+ 2 * MAX_PATH
);
75 path2
= (LPWSTR
)malloc(len
);
76 wcscpy(path2
, exepath
);
77 PathAppend(path2
, L
"bin;");
78 /* should do this only if it exists */
79 wcscat(path2
, exepath
);
80 PathAppend(path2
, L
"mingw\\bin;");
81 GetEnvironmentVariable(L
"PATH", &path2
[wcslen(path2
)],
82 (len
/sizeof(WCHAR
))-wcslen(path2
));
83 SetEnvironmentVariable(L
"PATH", path2
);
87 /* fix up the command line to call git.exe
88 * We have to be very careful about quoting here so we just
89 * trim off the first argument and replace it leaving the rest
93 int wargc
= 0, gui
= 0;
94 LPWSTR cmdline
= NULL
;
95 LPWSTR
*wargv
= NULL
, p
= NULL
;
96 cmdline
= GetCommandLine();
97 wargv
= CommandLineToArgvW(cmdline
, &wargc
);
98 cmd
= (LPWSTR
)malloc(sizeof(WCHAR
) * (wcslen(cmdline
) + MAX_PATH
));
99 if (wargc
> 1 && wcsicmp(L
"gui", wargv
[1]) == 0) {
101 if (wargc
> 2 && wcsicmp(L
"citool", wargv
[2]) == 0) {
103 wcscpy(cmd
, L
"git.exe");
105 WCHAR script
[MAX_PATH
];
107 wcscpy(script
, exepath
);
108 PathAppend(script
, L
"libexec\\git-core\\git-gui");
109 PathQuoteSpaces(script
);
110 wcscpy(cmd
, L
"wish.exe ");
113 exep
= NULL
; /* find the module from the commandline */
116 wcscpy(cmd
, L
"git.exe");
118 /* find the first space after the initial parameter then append all */
119 p
= wcschr(&cmdline
[wcslen(wargv
[0])], L
' ');
121 /* for git gui subcommands, remove the 'gui' word */
123 while (*p
== L
' ') ++p
;
132 /* set the console to ANSI/GUI codepage */
133 codepage
= GetConsoleCP();
134 SetConsoleCP(GetACP());
138 PROCESS_INFORMATION pi
;
139 ZeroMemory(&pi
, sizeof(PROCESS_INFORMATION
));
140 ZeroMemory(&si
, sizeof(STARTUPINFO
));
141 si
.cb
= sizeof(STARTUPINFO
);
142 CreateProcess(exep
,/* module: null means use command line */
143 cmd
, /* modified command line */
144 NULL
, /* process handle inheritance */
145 NULL
, /* thread handle inheritance */
146 TRUE
, /* handles inheritable? */
147 CREATE_UNICODE_ENVIRONMENT
,
148 NULL
, /* environment: use parent */
149 NULL
, /* starting directory: use parent */
152 WaitForSingleObject(pi
.hProcess
, INFINITE
);
157 /* reset the console codepage */
158 SetConsoleCP(codepage
);