summaryrefslogtreecommitdiff
path: root/src/libs/dutil/WixToolset.DUtil/shelutil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/dutil/WixToolset.DUtil/shelutil.cpp')
-rw-r--r--src/libs/dutil/WixToolset.DUtil/shelutil.cpp210
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
20static PFN_SHELLEXECUTEEXW vpfnShellExecuteExW = ::ShellExecuteExW; 21static PFN_SHELLEXECUTEEXW vpfnShellExecuteExW = ::ShellExecuteExW;
21 22
23static HRESULT DAPI GetFolderFromCsidl(
24 __out_z LPWSTR* psczFolderPath,
25 __in int csidlFolder
26 );
22static HRESULT GetDesktopShellView( 27static 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/******************************************************************** 174static HRESULT DAPI GetFolderFromCsidl(
163 ShelGetFolder() - gets a folder by CSIDL.
164
165*******************************************************************/
166extern "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
201EXTERN_C typedef HRESULT (STDAPICALLTYPE *PFN_SHGetKnownFolderPath)( 196EXTERN_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
247extern "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
416LExit:
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);