diff options
Diffstat (limited to 'src/libs/dutil/WixToolset.DUtil/shelutil.cpp')
-rw-r--r-- | src/libs/dutil/WixToolset.DUtil/shelutil.cpp | 210 |
1 files changed, 190 insertions, 20 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/shelutil.cpp b/src/libs/dutil/WixToolset.DUtil/shelutil.cpp index 2eb9a52a..72a0e5ce 100644 --- a/src/libs/dutil/WixToolset.DUtil/shelutil.cpp +++ b/src/libs/dutil/WixToolset.DUtil/shelutil.cpp | |||
@@ -9,6 +9,7 @@ | |||
9 | #define ShelExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_SHELUTIL, x, s, __VA_ARGS__) | 9 | #define ShelExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_SHELUTIL, x, s, __VA_ARGS__) |
10 | #define ShelExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_SHELUTIL, x, s, __VA_ARGS__) | 10 | #define ShelExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_SHELUTIL, x, s, __VA_ARGS__) |
11 | #define ShelExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_SHELUTIL, x, s, __VA_ARGS__) | 11 | #define ShelExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_SHELUTIL, x, s, __VA_ARGS__) |
12 | #define ShelExitWithRootFailure(x, e, s, ...) ExitWithRootFailureSource(DUTIL_SOURCE_SHELUTIL, x, e, s, __VA_ARGS__) | ||
12 | #define ShelExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_SHELUTIL, x, s, __VA_ARGS__) | 13 | #define ShelExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_SHELUTIL, x, s, __VA_ARGS__) |
13 | #define ShelExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_SHELUTIL, p, x, e, s, __VA_ARGS__) | 14 | #define ShelExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_SHELUTIL, p, x, e, s, __VA_ARGS__) |
14 | #define ShelExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_SHELUTIL, p, x, s, __VA_ARGS__) | 15 | #define ShelExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_SHELUTIL, p, x, s, __VA_ARGS__) |
@@ -19,6 +20,10 @@ | |||
19 | 20 | ||
20 | static PFN_SHELLEXECUTEEXW vpfnShellExecuteExW = ::ShellExecuteExW; | 21 | static PFN_SHELLEXECUTEEXW vpfnShellExecuteExW = ::ShellExecuteExW; |
21 | 22 | ||
23 | static HRESULT DAPI GetFolderFromCsidl( | ||
24 | __out_z LPWSTR* psczFolderPath, | ||
25 | __in int csidlFolder | ||
26 | ); | ||
22 | static HRESULT GetDesktopShellView( | 27 | static HRESULT GetDesktopShellView( |
23 | __in REFIID riid, | 28 | __in REFIID riid, |
24 | __out void **ppv | 29 | __out void **ppv |
@@ -57,7 +62,14 @@ extern "C" HRESULT DAPI ShelExec( | |||
57 | ) | 62 | ) |
58 | { | 63 | { |
59 | HRESULT hr = S_OK; | 64 | HRESULT hr = S_OK; |
60 | SHELLEXECUTEINFOW shExecInfo = {}; | 65 | SHELLEXECUTEINFOW shExecInfo = { }; |
66 | size_t cchWorkingDirectory = 0; | ||
67 | |||
68 | // CreateProcessW has undocumented MAX_PATH restriction for lpCurrentDirectory even when long path support is enabled. | ||
69 | if (wzWorkingDirectory && FAILED(::StringCchLengthW(wzWorkingDirectory, MAX_PATH - 1, &cchWorkingDirectory))) | ||
70 | { | ||
71 | wzWorkingDirectory = NULL; | ||
72 | } | ||
61 | 73 | ||
62 | shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); | 74 | shExecInfo.cbSize = sizeof(SHELLEXECUTEINFO); |
63 | shExecInfo.fMask = SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI | SEE_MASK_NOCLOSEPROCESS; | 75 | shExecInfo.fMask = SEE_MASK_FLAG_DDEWAIT | SEE_MASK_FLAG_NO_UI | SEE_MASK_NOCLOSEPROCESS; |
@@ -159,11 +171,7 @@ LExit: | |||
159 | } | 171 | } |
160 | 172 | ||
161 | 173 | ||
162 | /******************************************************************** | 174 | static HRESULT DAPI GetFolderFromCsidl( |
163 | ShelGetFolder() - gets a folder by CSIDL. | ||
164 | |||
165 | *******************************************************************/ | ||
166 | extern "C" HRESULT DAPI ShelGetFolder( | ||
167 | __out_z LPWSTR* psczFolderPath, | 175 | __out_z LPWSTR* psczFolderPath, |
168 | __in int csidlFolder | 176 | __in int csidlFolder |
169 | ) | 177 | ) |
@@ -185,19 +193,6 @@ LExit: | |||
185 | } | 193 | } |
186 | 194 | ||
187 | 195 | ||
188 | /******************************************************************** | ||
189 | ShelGetKnownFolder() - gets a folder by KNOWNFOLDERID. | ||
190 | |||
191 | Note: return E_NOTIMPL if called on pre-Vista operating systems. | ||
192 | *******************************************************************/ | ||
193 | #ifndef REFKNOWNFOLDERID | ||
194 | #define REFKNOWNFOLDERID REFGUID | ||
195 | #endif | ||
196 | |||
197 | #ifndef KF_FLAG_CREATE | ||
198 | #define KF_FLAG_CREATE 0x00008000 // Make sure that the folder already exists or create it and apply security specified in folder definition | ||
199 | #endif | ||
200 | |||
201 | EXTERN_C typedef HRESULT (STDAPICALLTYPE *PFN_SHGetKnownFolderPath)( | 196 | EXTERN_C typedef HRESULT (STDAPICALLTYPE *PFN_SHGetKnownFolderPath)( |
202 | REFKNOWNFOLDERID rfid, | 197 | REFKNOWNFOLDERID rfid, |
203 | DWORD dwFlags, | 198 | DWORD dwFlags, |
@@ -249,6 +244,181 @@ LExit: | |||
249 | return hr; | 244 | return hr; |
250 | } | 245 | } |
251 | 246 | ||
247 | extern "C" HRESULT DAPI ShelGetFolder( | ||
248 | __out_z LPWSTR* psczFolderPath, | ||
249 | __in int csidlFolder | ||
250 | ) | ||
251 | { | ||
252 | HRESULT hr = S_OK; | ||
253 | LPWSTR sczPath = NULL; | ||
254 | KNOWNFOLDERID rfid = { }; | ||
255 | |||
256 | csidlFolder &= ~CSIDL_FLAG_MASK; | ||
257 | |||
258 | switch (csidlFolder) | ||
259 | { | ||
260 | case CSIDL_ADMINTOOLS: | ||
261 | rfid = FOLDERID_AdminTools; | ||
262 | break; | ||
263 | case CSIDL_APPDATA: | ||
264 | rfid = FOLDERID_RoamingAppData; | ||
265 | break; | ||
266 | case CSIDL_CDBURN_AREA: | ||
267 | rfid = FOLDERID_CDBurning; | ||
268 | break; | ||
269 | case CSIDL_COMMON_ADMINTOOLS: | ||
270 | rfid = FOLDERID_CommonAdminTools; | ||
271 | break; | ||
272 | case CSIDL_COMMON_APPDATA: | ||
273 | rfid = FOLDERID_ProgramData; | ||
274 | break; | ||
275 | case CSIDL_COMMON_DESKTOPDIRECTORY: | ||
276 | rfid = FOLDERID_PublicDesktop; | ||
277 | break; | ||
278 | case CSIDL_COMMON_DOCUMENTS: | ||
279 | rfid = FOLDERID_PublicDocuments; | ||
280 | break; | ||
281 | case CSIDL_COMMON_MUSIC: | ||
282 | rfid = FOLDERID_PublicMusic; | ||
283 | break; | ||
284 | case CSIDL_COMMON_OEM_LINKS: | ||
285 | rfid = FOLDERID_CommonOEMLinks; | ||
286 | break; | ||
287 | case CSIDL_COMMON_PICTURES: | ||
288 | rfid = FOLDERID_PublicPictures; | ||
289 | break; | ||
290 | case CSIDL_COMMON_PROGRAMS: | ||
291 | rfid = FOLDERID_CommonPrograms; | ||
292 | break; | ||
293 | case CSIDL_COMMON_STARTMENU: | ||
294 | rfid = FOLDERID_CommonStartMenu; | ||
295 | break; | ||
296 | case CSIDL_COMMON_STARTUP: __fallthrough; | ||
297 | case CSIDL_COMMON_ALTSTARTUP: | ||
298 | rfid = FOLDERID_CommonStartup; | ||
299 | break; | ||
300 | case CSIDL_COMMON_TEMPLATES: | ||
301 | rfid = FOLDERID_CommonTemplates; | ||
302 | break; | ||
303 | case CSIDL_COMMON_VIDEO: | ||
304 | rfid = FOLDERID_PublicVideos; | ||
305 | break; | ||
306 | case CSIDL_COOKIES: | ||
307 | rfid = FOLDERID_Cookies; | ||
308 | break; | ||
309 | case CSIDL_DESKTOP: | ||
310 | case CSIDL_DESKTOPDIRECTORY: | ||
311 | rfid = FOLDERID_Desktop; | ||
312 | break; | ||
313 | case CSIDL_FAVORITES: __fallthrough; | ||
314 | case CSIDL_COMMON_FAVORITES: | ||
315 | rfid = FOLDERID_Favorites; | ||
316 | break; | ||
317 | case CSIDL_FONTS: | ||
318 | rfid = FOLDERID_Fonts; | ||
319 | break; | ||
320 | case CSIDL_HISTORY: | ||
321 | rfid = FOLDERID_History; | ||
322 | break; | ||
323 | case CSIDL_INTERNET_CACHE: | ||
324 | rfid = FOLDERID_InternetCache; | ||
325 | break; | ||
326 | case CSIDL_LOCAL_APPDATA: | ||
327 | rfid = FOLDERID_LocalAppData; | ||
328 | break; | ||
329 | case CSIDL_MYMUSIC: | ||
330 | rfid = FOLDERID_Music; | ||
331 | break; | ||
332 | case CSIDL_MYPICTURES: | ||
333 | rfid = FOLDERID_Pictures; | ||
334 | break; | ||
335 | case CSIDL_MYVIDEO: | ||
336 | rfid = FOLDERID_Videos; | ||
337 | break; | ||
338 | case CSIDL_NETHOOD: | ||
339 | rfid = FOLDERID_NetHood; | ||
340 | break; | ||
341 | case CSIDL_PERSONAL: | ||
342 | rfid = FOLDERID_Documents; | ||
343 | break; | ||
344 | case CSIDL_PRINTHOOD: | ||
345 | rfid = FOLDERID_PrintHood; | ||
346 | break; | ||
347 | case CSIDL_PROFILE: | ||
348 | rfid = FOLDERID_Profile; | ||
349 | break; | ||
350 | case CSIDL_PROGRAM_FILES: | ||
351 | rfid = FOLDERID_ProgramFiles; | ||
352 | break; | ||
353 | case CSIDL_PROGRAM_FILESX86: | ||
354 | rfid = FOLDERID_ProgramFilesX86; | ||
355 | break; | ||
356 | case CSIDL_PROGRAM_FILES_COMMON: | ||
357 | rfid = FOLDERID_ProgramFilesCommon; | ||
358 | break; | ||
359 | case CSIDL_PROGRAM_FILES_COMMONX86: | ||
360 | rfid = FOLDERID_ProgramFilesCommonX86; | ||
361 | break; | ||
362 | case CSIDL_PROGRAMS: | ||
363 | rfid = FOLDERID_Programs; | ||
364 | break; | ||
365 | case CSIDL_RECENT: | ||
366 | rfid = FOLDERID_Recent; | ||
367 | break; | ||
368 | case CSIDL_RESOURCES: | ||
369 | rfid = FOLDERID_ResourceDir; | ||
370 | break; | ||
371 | case CSIDL_RESOURCES_LOCALIZED: | ||
372 | rfid = FOLDERID_LocalizedResourcesDir; | ||
373 | break; | ||
374 | case CSIDL_SENDTO: | ||
375 | rfid = FOLDERID_SendTo; | ||
376 | break; | ||
377 | case CSIDL_STARTMENU: | ||
378 | rfid = FOLDERID_StartMenu; | ||
379 | break; | ||
380 | case CSIDL_STARTUP: | ||
381 | case CSIDL_ALTSTARTUP: | ||
382 | rfid = FOLDERID_Startup; | ||
383 | break; | ||
384 | case CSIDL_SYSTEM: | ||
385 | rfid = FOLDERID_System; | ||
386 | break; | ||
387 | case CSIDL_SYSTEMX86: | ||
388 | rfid = FOLDERID_SystemX86; | ||
389 | break; | ||
390 | case CSIDL_TEMPLATES: | ||
391 | rfid = FOLDERID_Templates; | ||
392 | break; | ||
393 | case CSIDL_WINDOWS: | ||
394 | rfid = FOLDERID_Windows; | ||
395 | break; | ||
396 | default: | ||
397 | ShelExitWithRootFailure(hr, E_INVALIDARG, "Unknown csidl: %d", csidlFolder); | ||
398 | } | ||
399 | |||
400 | hr = ShelGetKnownFolder(&sczPath, rfid); | ||
401 | if (E_NOTIMPL == hr) | ||
402 | { | ||
403 | hr = S_FALSE; | ||
404 | } | ||
405 | ShelExitOnFailure(hr, "Failed to get known folder."); | ||
406 | |||
407 | if (S_FALSE == hr) | ||
408 | { | ||
409 | hr = GetFolderFromCsidl(&sczPath, csidlFolder); | ||
410 | ShelExitOnFailure(hr, "Failed to get csidl folder."); | ||
411 | } | ||
412 | |||
413 | *psczFolderPath = sczPath; | ||
414 | sczPath = NULL; | ||
415 | |||
416 | LExit: | ||
417 | ReleaseStr(sczPath); | ||
418 | |||
419 | return hr; | ||
420 | } | ||
421 | |||
252 | 422 | ||
253 | // Internal functions. | 423 | // Internal functions. |
254 | 424 | ||
@@ -287,7 +457,7 @@ static HRESULT GetDesktopShellView( | |||
287 | else if (S_FALSE == hr) | 457 | else if (S_FALSE == hr) |
288 | { | 458 | { |
289 | //Windows XP | 459 | //Windows XP |
290 | hr = SHGetDesktopFolder(&psf); | 460 | hr = ::SHGetDesktopFolder(&psf); |
291 | ShelExitOnFailure(hr, "Failed to get desktop folder."); | 461 | ShelExitOnFailure(hr, "Failed to get desktop folder."); |
292 | 462 | ||
293 | hr = psf->CreateViewObject(NULL, IID_IShellView, ppv); | 463 | hr = psf->CreateViewObject(NULL, IID_IShellView, ppv); |