diff options
Diffstat (limited to 'src/libs')
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/apputil.cpp | 231 | ||||
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/inc/apputil.h | 41 | ||||
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/inc/pathutil.h | 10 | ||||
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/pathutil.cpp | 102 | ||||
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/precomp.h | 1 |
5 files changed, 268 insertions, 117 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/apputil.cpp b/src/libs/dutil/WixToolset.DUtil/apputil.cpp index 589a09dd..7e0bbc7b 100644 --- a/src/libs/dutil/WixToolset.DUtil/apputil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/apputil.cpp | |||
@@ -20,7 +20,18 @@ const DWORD PRIVATE_LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800; | |||
20 | typedef BOOL(WINAPI *LPFN_SETDEFAULTDLLDIRECTORIES)(DWORD); | 20 | typedef BOOL(WINAPI *LPFN_SETDEFAULTDLLDIRECTORIES)(DWORD); |
21 | typedef BOOL(WINAPI *LPFN_SETDLLDIRECTORYW)(LPCWSTR); | 21 | typedef BOOL(WINAPI *LPFN_SETDLLDIRECTORYW)(LPCWSTR); |
22 | 22 | ||
23 | extern "C" void DAPI AppFreeCommandLineArgs( | 23 | /******************************************************************** |
24 | EscapeCommandLineArgument - encodes wzArgument such that | ||
25 | ::CommandLineToArgv() will parse it back unaltered. If no escaping | ||
26 | was required, *psczEscaped is NULL. | ||
27 | |||
28 | ********************************************************************/ | ||
29 | static HRESULT EscapeCommandLineArgument( | ||
30 | __in_z LPCWSTR wzArgument, | ||
31 | __out_z LPWSTR* psczEscaped | ||
32 | ); | ||
33 | |||
34 | DAPI_(void) AppFreeCommandLineArgs( | ||
24 | __in LPWSTR* argv | 35 | __in LPWSTR* argv |
25 | ) | 36 | ) |
26 | { | 37 | { |
@@ -34,7 +45,7 @@ AppInitialize - initializes the standard safety precautions for an | |||
34 | installation application. | 45 | installation application. |
35 | 46 | ||
36 | ********************************************************************/ | 47 | ********************************************************************/ |
37 | extern "C" void DAPI AppInitialize( | 48 | DAPI_(void) AppInitialize( |
38 | __in_ecount(cSafelyLoadSystemDlls) LPCWSTR rgsczSafelyLoadSystemDlls[], | 49 | __in_ecount(cSafelyLoadSystemDlls) LPCWSTR rgsczSafelyLoadSystemDlls[], |
39 | __in DWORD cSafelyLoadSystemDlls | 50 | __in DWORD cSafelyLoadSystemDlls |
40 | ) | 51 | ) |
@@ -85,12 +96,12 @@ extern "C" void DAPI AppInitialize( | |||
85 | } | 96 | } |
86 | } | 97 | } |
87 | 98 | ||
88 | extern "C" void DAPI AppInitializeUnsafe() | 99 | DAPI_(void) AppInitializeUnsafe() |
89 | { | 100 | { |
90 | ::HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0); | 101 | ::HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0); |
91 | } | 102 | } |
92 | 103 | ||
93 | extern "C" DAPI_(HRESULT) AppParseCommandLine( | 104 | DAPI_(HRESULT) AppParseCommandLine( |
94 | __in LPCWSTR wzCommandLine, | 105 | __in LPCWSTR wzCommandLine, |
95 | __in int* pArgc, | 106 | __in int* pArgc, |
96 | __in LPWSTR** pArgv | 107 | __in LPWSTR** pArgv |
@@ -122,3 +133,215 @@ LExit: | |||
122 | 133 | ||
123 | return hr; | 134 | return hr; |
124 | } | 135 | } |
136 | |||
137 | DAPI_(HRESULT) AppAppendCommandLineArgument( | ||
138 | __deref_inout_z LPWSTR* psczCommandLine, | ||
139 | __in_z LPCWSTR wzArgument | ||
140 | ) | ||
141 | { | ||
142 | HRESULT hr = S_OK; | ||
143 | LPWSTR sczQuotedArg = NULL; | ||
144 | |||
145 | hr = EscapeCommandLineArgument(wzArgument, &sczQuotedArg); | ||
146 | AppExitOnFailure(hr, "Failed to escape command line argument."); | ||
147 | |||
148 | // If there is already data in the command line, | ||
149 | // append a space before appending the argument. | ||
150 | if (*psczCommandLine && **psczCommandLine) | ||
151 | { | ||
152 | hr = StrAllocConcatSecure(psczCommandLine, L" ", 0); | ||
153 | AppExitOnFailure(hr, "Failed to append space to command line with existing data."); | ||
154 | } | ||
155 | |||
156 | hr = StrAllocConcatSecure(psczCommandLine, sczQuotedArg ? sczQuotedArg : wzArgument, 0); | ||
157 | AppExitOnFailure(hr, "Failed to copy command line argument."); | ||
158 | |||
159 | LExit: | ||
160 | ReleaseStr(sczQuotedArg); | ||
161 | |||
162 | return hr; | ||
163 | } | ||
164 | |||
165 | DAPIV_(HRESULT) AppAppendCommandLineArgumentFormatted( | ||
166 | __deref_inout_z LPWSTR* psczCommandLine, | ||
167 | __in __format_string LPCWSTR wzFormat, | ||
168 | ... | ||
169 | ) | ||
170 | { | ||
171 | HRESULT hr = S_OK; | ||
172 | va_list args; | ||
173 | |||
174 | va_start(args, wzFormat); | ||
175 | hr = AppAppendCommandLineArgumentFormattedArgs(psczCommandLine, wzFormat, args); | ||
176 | va_end(args); | ||
177 | |||
178 | return hr; | ||
179 | } | ||
180 | |||
181 | DAPI_(HRESULT) AppAppendCommandLineArgumentFormattedArgs( | ||
182 | __deref_inout_z LPWSTR* psczCommandLine, | ||
183 | __in __format_string LPCWSTR wzFormat, | ||
184 | __in va_list args | ||
185 | ) | ||
186 | { | ||
187 | HRESULT hr = S_OK; | ||
188 | LPWSTR sczQuotedArg = NULL; | ||
189 | |||
190 | hr = AppEscapeCommandLineArgumentFormattedArgs(&sczQuotedArg, wzFormat, args); | ||
191 | AppExitOnFailure(hr, "Failed to escape command line argument."); | ||
192 | |||
193 | // If there is already data in the command line, | ||
194 | // append a space before appending the argument. | ||
195 | if (*psczCommandLine && **psczCommandLine) | ||
196 | { | ||
197 | hr = StrAllocConcatSecure(psczCommandLine, L" ", 0); | ||
198 | AppExitOnFailure(hr, "Failed to append space to command line with existing data."); | ||
199 | } | ||
200 | |||
201 | hr = StrAllocConcatSecure(psczCommandLine, sczQuotedArg, 0); | ||
202 | AppExitOnFailure(hr, "Failed to copy command line argument."); | ||
203 | |||
204 | LExit: | ||
205 | ReleaseStr(sczQuotedArg); | ||
206 | |||
207 | return hr; | ||
208 | } | ||
209 | |||
210 | DAPIV_(HRESULT) AppEscapeCommandLineArgumentFormatted( | ||
211 | __deref_inout_z LPWSTR* psczEscapedArgument, | ||
212 | __in __format_string LPCWSTR wzFormat, | ||
213 | ... | ||
214 | ) | ||
215 | { | ||
216 | HRESULT hr = S_OK; | ||
217 | va_list args; | ||
218 | |||
219 | va_start(args, wzFormat); | ||
220 | hr = AppEscapeCommandLineArgumentFormattedArgs(psczEscapedArgument, wzFormat, args); | ||
221 | va_end(args); | ||
222 | |||
223 | return hr; | ||
224 | } | ||
225 | |||
226 | DAPI_(HRESULT) AppEscapeCommandLineArgumentFormattedArgs( | ||
227 | __deref_inout_z LPWSTR* psczEscapedArgument, | ||
228 | __in __format_string LPCWSTR wzFormat, | ||
229 | __in va_list args | ||
230 | ) | ||
231 | { | ||
232 | HRESULT hr = S_OK; | ||
233 | LPWSTR sczFormattedArg = NULL; | ||
234 | LPWSTR sczQuotedArg = NULL; | ||
235 | |||
236 | hr = StrAllocFormattedArgsSecure(&sczFormattedArg, wzFormat, args); | ||
237 | AppExitOnFailure(hr, "Failed to format command line argument."); | ||
238 | |||
239 | hr = EscapeCommandLineArgument(sczFormattedArg, &sczQuotedArg); | ||
240 | AppExitOnFailure(hr, "Failed to escape command line argument."); | ||
241 | |||
242 | if (sczQuotedArg) | ||
243 | { | ||
244 | *psczEscapedArgument = sczQuotedArg; | ||
245 | sczQuotedArg = NULL; | ||
246 | } | ||
247 | else | ||
248 | { | ||
249 | *psczEscapedArgument = sczFormattedArg; | ||
250 | sczFormattedArg = NULL; | ||
251 | } | ||
252 | |||
253 | LExit: | ||
254 | ReleaseStr(sczFormattedArg); | ||
255 | ReleaseStr(sczQuotedArg); | ||
256 | |||
257 | return hr; | ||
258 | } | ||
259 | |||
260 | static HRESULT EscapeCommandLineArgument( | ||
261 | __in_z LPCWSTR wzArgument, | ||
262 | __out_z LPWSTR* psczEscaped | ||
263 | ) | ||
264 | { | ||
265 | HRESULT hr = S_OK; | ||
266 | BOOL fRequiresQuoting = FALSE; | ||
267 | SIZE_T cMaxEscapedSize = 0; | ||
268 | |||
269 | *psczEscaped = NULL; | ||
270 | |||
271 | // Loop through the argument determining if it needs to be quoted and what the maximum | ||
272 | // size would be if there are escape characters required. | ||
273 | for (LPCWSTR pwz = wzArgument; *pwz; ++pwz) | ||
274 | { | ||
275 | // Arguments with whitespace need quoting. | ||
276 | if (L' ' == *pwz || L'\t' == *pwz || L'\n' == *pwz || L'\v' == *pwz) | ||
277 | { | ||
278 | fRequiresQuoting = TRUE; | ||
279 | } | ||
280 | else if (L'"' == *pwz) // quotes need quoting and sometimes escaping. | ||
281 | { | ||
282 | fRequiresQuoting = TRUE; | ||
283 | ++cMaxEscapedSize; | ||
284 | } | ||
285 | else if (L'\\' == *pwz) // some backslashes need escaping, so we'll count them all to make sure there is room. | ||
286 | { | ||
287 | ++cMaxEscapedSize; | ||
288 | } | ||
289 | |||
290 | ++cMaxEscapedSize; | ||
291 | } | ||
292 | |||
293 | // If we found anything in the argument that requires our argument to be quoted | ||
294 | if (fRequiresQuoting) | ||
295 | { | ||
296 | hr = StrAlloc(psczEscaped, cMaxEscapedSize + 3); // plus three for the start and end quote plus null terminator. | ||
297 | AppExitOnFailure(hr, "Failed to allocate argument to be quoted."); | ||
298 | |||
299 | LPCWSTR pwz = wzArgument; | ||
300 | LPWSTR pwzQuoted = *psczEscaped; | ||
301 | |||
302 | *pwzQuoted = L'"'; | ||
303 | ++pwzQuoted; | ||
304 | while (*pwz) | ||
305 | { | ||
306 | DWORD dwBackslashes = 0; | ||
307 | while (L'\\' == *pwz) | ||
308 | { | ||
309 | ++dwBackslashes; | ||
310 | ++pwz; | ||
311 | } | ||
312 | |||
313 | // Escape all backslashes at the end of the string. | ||
314 | if (!*pwz) | ||
315 | { | ||
316 | dwBackslashes *= 2; | ||
317 | } | ||
318 | else if (L'"' == *pwz) // escape all backslashes before the quote and escape the quote itself. | ||
319 | { | ||
320 | dwBackslashes = dwBackslashes * 2 + 1; | ||
321 | } | ||
322 | // the backslashes don't have to be escaped. | ||
323 | |||
324 | // Add the appropriate number of backslashes | ||
325 | for (DWORD i = 0; i < dwBackslashes; ++i) | ||
326 | { | ||
327 | *pwzQuoted = L'\\'; | ||
328 | ++pwzQuoted; | ||
329 | } | ||
330 | |||
331 | // If there is a character, add it after all the escaped backslashes | ||
332 | if (*pwz) | ||
333 | { | ||
334 | *pwzQuoted = *pwz; | ||
335 | ++pwz; | ||
336 | ++pwzQuoted; | ||
337 | } | ||
338 | } | ||
339 | |||
340 | *pwzQuoted = L'"'; | ||
341 | ++pwzQuoted; | ||
342 | *pwzQuoted = L'\0'; // ensure the arg is null terminated. | ||
343 | } | ||
344 | |||
345 | LExit: | ||
346 | return hr; | ||
347 | } | ||
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/apputil.h b/src/libs/dutil/WixToolset.DUtil/inc/apputil.h index 1a1e14f7..11280102 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/apputil.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/apputil.h | |||
@@ -34,12 +34,51 @@ AppParseCommandLine - parses the command line using CommandLineToArgvW. | |||
34 | by calling AppFreeCommandLineArgs. | 34 | by calling AppFreeCommandLineArgs. |
35 | 35 | ||
36 | ********************************************************************/ | 36 | ********************************************************************/ |
37 | DAPI_(HRESULT) AppParseCommandLine( | 37 | HRESULT DAPI AppParseCommandLine( |
38 | __in LPCWSTR wzCommandLine, | 38 | __in LPCWSTR wzCommandLine, |
39 | __in int* argc, | 39 | __in int* argc, |
40 | __in LPWSTR** pArgv | 40 | __in LPWSTR** pArgv |
41 | ); | 41 | ); |
42 | 42 | ||
43 | /******************************************************************* | ||
44 | AppAppendCommandLineArgument - appends a command line argument on to a | ||
45 | string such that ::CommandLineToArgv() will shred them correctly | ||
46 | (i.e. quote arguments with spaces in them). | ||
47 | ********************************************************************/ | ||
48 | HRESULT DAPI AppAppendCommandLineArgument( | ||
49 | __deref_inout_z LPWSTR* psczCommandLine, | ||
50 | __in_z LPCWSTR wzArgument | ||
51 | ); | ||
52 | |||
53 | HRESULT DAPIV AppAppendCommandLineArgumentFormatted( | ||
54 | __deref_inout_z LPWSTR* psczCommandLine, | ||
55 | __in __format_string LPCWSTR wzFormat, | ||
56 | ... | ||
57 | ); | ||
58 | |||
59 | HRESULT DAPI AppAppendCommandLineArgumentFormattedArgs( | ||
60 | __deref_inout_z LPWSTR* psczCommandLine, | ||
61 | __in __format_string LPCWSTR wzFormat, | ||
62 | __in va_list args | ||
63 | ); | ||
64 | |||
65 | /******************************************************************** | ||
66 | AppEscapeCommandLineArgumentFormatted - formats a string and then | ||
67 | escapes it such that ::CommandLineToArgv() will parse it back unaltered. | ||
68 | |||
69 | ********************************************************************/ | ||
70 | HRESULT DAPIV AppEscapeCommandLineArgumentFormatted( | ||
71 | __deref_inout_z LPWSTR* psczEscapedArgument, | ||
72 | __in __format_string LPCWSTR wzFormat, | ||
73 | ... | ||
74 | ); | ||
75 | |||
76 | HRESULT DAPI AppEscapeCommandLineArgumentFormattedArgs( | ||
77 | __deref_inout_z LPWSTR* psczEscapedArgument, | ||
78 | __in __format_string LPCWSTR wzFormat, | ||
79 | __in va_list args | ||
80 | ); | ||
81 | |||
43 | #ifdef __cplusplus | 82 | #ifdef __cplusplus |
44 | } | 83 | } |
45 | #endif | 84 | #endif |
diff --git a/src/libs/dutil/WixToolset.DUtil/inc/pathutil.h b/src/libs/dutil/WixToolset.DUtil/inc/pathutil.h index 0ae9f437..00a468ce 100644 --- a/src/libs/dutil/WixToolset.DUtil/inc/pathutil.h +++ b/src/libs/dutil/WixToolset.DUtil/inc/pathutil.h | |||
@@ -14,16 +14,6 @@ typedef enum PATH_EXPAND | |||
14 | 14 | ||
15 | 15 | ||
16 | /******************************************************************* | 16 | /******************************************************************* |
17 | PathCommandLineAppend - appends a command line argument on to a | ||
18 | string such that ::CommandLineToArgv() will shred them correctly | ||
19 | (i.e. quote arguments with spaces in them). | ||
20 | ********************************************************************/ | ||
21 | DAPI_(HRESULT) PathCommandLineAppend( | ||
22 | __deref_inout_z LPWSTR* psczCommandLine, | ||
23 | __in_z LPCWSTR wzArgument | ||
24 | ); | ||
25 | |||
26 | /******************************************************************* | ||
27 | PathFile - returns a pointer to the file part of the path. | 17 | PathFile - returns a pointer to the file part of the path. |
28 | ********************************************************************/ | 18 | ********************************************************************/ |
29 | DAPI_(LPWSTR) PathFile( | 19 | DAPI_(LPWSTR) PathFile( |
diff --git a/src/libs/dutil/WixToolset.DUtil/pathutil.cpp b/src/libs/dutil/WixToolset.DUtil/pathutil.cpp index 5fad519b..7bac8ac3 100644 --- a/src/libs/dutil/WixToolset.DUtil/pathutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/pathutil.cpp | |||
@@ -21,108 +21,6 @@ | |||
21 | #define PATH_GOOD_ENOUGH 64 | 21 | #define PATH_GOOD_ENOUGH 64 |
22 | 22 | ||
23 | 23 | ||
24 | DAPI_(HRESULT) PathCommandLineAppend( | ||
25 | __deref_inout_z LPWSTR* psczCommandLine, | ||
26 | __in_z LPCWSTR wzArgument | ||
27 | ) | ||
28 | { | ||
29 | HRESULT hr = S_OK; | ||
30 | LPWSTR sczQuotedArg = NULL; | ||
31 | BOOL fRequiresQuoting = FALSE; | ||
32 | DWORD dwMaxEscapedSize = 0; | ||
33 | |||
34 | // Loop through the argument determining if it needs to be quoted and what the maximum | ||
35 | // size would be if there are escape characters required. | ||
36 | for (LPCWSTR pwz = wzArgument; *pwz; ++pwz) | ||
37 | { | ||
38 | // Arguments with whitespace need quoting. | ||
39 | if (L' ' == *pwz || L'\t' == *pwz || L'\n' == *pwz || L'\v' == *pwz) | ||
40 | { | ||
41 | fRequiresQuoting = TRUE; | ||
42 | } | ||
43 | else if (L'"' == *pwz) // quotes need quoting and sometimes escaping. | ||
44 | { | ||
45 | fRequiresQuoting = TRUE; | ||
46 | ++dwMaxEscapedSize; | ||
47 | } | ||
48 | else if (L'\\' == *pwz) // some backslashes need escaping, so we'll count them all to make sure there is room. | ||
49 | { | ||
50 | ++dwMaxEscapedSize; | ||
51 | } | ||
52 | |||
53 | ++dwMaxEscapedSize; | ||
54 | } | ||
55 | |||
56 | // If we found anything in the argument that requires our argument to be quoted | ||
57 | if (fRequiresQuoting) | ||
58 | { | ||
59 | hr = StrAlloc(&sczQuotedArg, dwMaxEscapedSize + 3); // plus three for the start and end quote plus null terminator. | ||
60 | PathExitOnFailure(hr, "Failed to allocate argument to be quoted."); | ||
61 | |||
62 | LPCWSTR pwz = wzArgument; | ||
63 | LPWSTR pwzQuoted = sczQuotedArg; | ||
64 | |||
65 | *pwzQuoted = L'"'; | ||
66 | ++pwzQuoted; | ||
67 | while (*pwz) | ||
68 | { | ||
69 | DWORD dwBackslashes = 0; | ||
70 | while (L'\\' == *pwz) | ||
71 | { | ||
72 | ++dwBackslashes; | ||
73 | ++pwz; | ||
74 | } | ||
75 | |||
76 | // Escape all backslashes at the end of the string. | ||
77 | if (!*pwz) | ||
78 | { | ||
79 | dwBackslashes *= 2; | ||
80 | } | ||
81 | else if (L'"' == *pwz) // escape all backslashes before the quote and escape the quote itself. | ||
82 | { | ||
83 | dwBackslashes = dwBackslashes * 2 + 1; | ||
84 | } | ||
85 | // the backslashes don't have to be escaped. | ||
86 | |||
87 | // Add the appropriate number of backslashes | ||
88 | for (DWORD i = 0; i < dwBackslashes; ++i) | ||
89 | { | ||
90 | *pwzQuoted = L'\\'; | ||
91 | ++pwzQuoted; | ||
92 | } | ||
93 | |||
94 | // If there is a character, add it after all the escaped backslashes | ||
95 | if (*pwz) | ||
96 | { | ||
97 | *pwzQuoted = *pwz; | ||
98 | ++pwz; | ||
99 | ++pwzQuoted; | ||
100 | } | ||
101 | } | ||
102 | |||
103 | *pwzQuoted = L'"'; | ||
104 | ++pwzQuoted; | ||
105 | *pwzQuoted = L'\0'; // ensure the arg is null terminated. | ||
106 | } | ||
107 | |||
108 | // If there is already data in the command line, append a space before appending the | ||
109 | // argument. | ||
110 | if (*psczCommandLine && **psczCommandLine) | ||
111 | { | ||
112 | hr = StrAllocConcat(psczCommandLine, L" ", 0); | ||
113 | PathExitOnFailure(hr, "Failed to append space to command line with existing data."); | ||
114 | } | ||
115 | |||
116 | hr = StrAllocConcat(psczCommandLine, sczQuotedArg ? sczQuotedArg : wzArgument, 0); | ||
117 | PathExitOnFailure(hr, "Failed to copy command line argument."); | ||
118 | |||
119 | LExit: | ||
120 | ReleaseStr(sczQuotedArg); | ||
121 | |||
122 | return hr; | ||
123 | } | ||
124 | |||
125 | |||
126 | DAPI_(LPWSTR) PathFile( | 24 | DAPI_(LPWSTR) PathFile( |
127 | __in_z LPCWSTR wzPath | 25 | __in_z LPCWSTR wzPath |
128 | ) | 26 | ) |
diff --git a/src/libs/dutil/WixToolset.DUtil/precomp.h b/src/libs/dutil/WixToolset.DUtil/precomp.h index f8f3b944..46d29f21 100644 --- a/src/libs/dutil/WixToolset.DUtil/precomp.h +++ b/src/libs/dutil/WixToolset.DUtil/precomp.h | |||
@@ -45,6 +45,7 @@ | |||
45 | #include "dutil.h" | 45 | #include "dutil.h" |
46 | #include "verutil.h" | 46 | #include "verutil.h" |
47 | #include "aclutil.h" | 47 | #include "aclutil.h" |
48 | #include "apputil.h" | ||
48 | #include "atomutil.h" | 49 | #include "atomutil.h" |
49 | #include "buffutil.h" | 50 | #include "buffutil.h" |
50 | #include "butil.h" | 51 | #include "butil.h" |