ReactOS 0.4.17-dev-357-ga8f14ff
utils.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Shell
3 * LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4 * PURPOSE: Implement shell light-weight utility functions
5 * COPYRIGHT: Copyright 2023-2024 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
6 */
7
8#define _ATL_NO_EXCEPTIONS
9
10/*
11 * HACK! These functions are conflicting with <shobjidl.h> inline functions...
12 */
13#define IShellFolder_GetDisplayNameOf _disabled_IShellFolder_GetDisplayNameOf_
14#define IShellFolder_ParseDisplayName _disabled_IShellFolder_ParseDisplayName_
15#define IShellFolder_CompareIDs _disabled_IShellFolder_CompareIDs_
16
17#include "precomp.h"
18#include <winver.h>
19#include <shellapi.h>
20#include <shlwapi.h>
21#include <shlobj_undoc.h>
22#include <shlguid_undoc.h>
23#include <userenv.h>
24#include <atlstr.h>
25#include "resource.h"
26
27#include <shlwapi_undoc.h>
29
30#include <strsafe.h>
31
32#ifndef FAILED_UNEXPECTEDLY
33#define FAILED_UNEXPECTEDLY FAILED /* FIXME: Make shellutils.h usable without ATL */
34#endif
35
37
39
40static inline WORD
42{
45}
46
47static BOOL
50 _In_ PCSTR lpString,
51 _In_ PCSTR lpSrc,
52 _Out_ PSTR pszDest,
54{
55 CHAR szBuff[MAX_PATH];
56 INT cchExpanded;
57
58 if (hUserToken)
59 {
60 if (ExpandEnvironmentStringsForUserA(hUserToken, lpSrc, szBuff, _countof(szBuff)))
61 cchExpanded = lstrlenA(szBuff) + 1;
62 else
63 cchExpanded = 0;
64 }
65 else
66 {
67 cchExpanded = ExpandEnvironmentStringsA(lpSrc, szBuff, _countof(szBuff));
68 }
69
70 if (!cchExpanded || cchExpanded > cchDest)
71 return FALSE;
72
73 INT cchEnvPath = cchExpanded - 1;
75 szBuff, cchEnvPath, lpString, cchEnvPath) != CSTR_EQUAL)
76 {
77 return FALSE;
78 }
79
80 INT cchSuffix = lstrlenA(lpString) - cchEnvPath;
81 if (lstrlenA(lpSrc) + cchSuffix >= cchDest)
82 return FALSE;
83
84 StringCchCopyA(pszDest, cchDest, lpSrc);
85 StringCchCatA(pszDest, cchDest, &lpString[cchEnvPath]);
86 return TRUE;
87}
88
89static BOOL
92 _In_ PCWSTR lpString,
93 _In_ PCWSTR lpSrc,
94 _Out_ PWSTR pszDest,
96{
97 WCHAR szBuff[MAX_PATH];
98 INT cchExpanded;
99
100 if (hUserToken)
101 {
102 if (ExpandEnvironmentStringsForUserW(hUserToken, lpSrc, szBuff, _countof(szBuff)))
103 cchExpanded = lstrlenW(szBuff) + 1;
104 else
105 cchExpanded = 0;
106 }
107 else
108 {
109 cchExpanded = ExpandEnvironmentStringsW(lpSrc, szBuff, _countof(szBuff));
110 }
111
112 if (!cchExpanded || cchExpanded > cchDest)
113 return FALSE;
114
115 INT cchEnvPath = cchExpanded - 1;
117 szBuff, cchEnvPath, lpString, cchEnvPath) != CSTR_EQUAL)
118 {
119 return FALSE;
120 }
121
122 INT cchSuffix = lstrlenW(lpString) - cchEnvPath;
123 if (lstrlenW(lpSrc) + cchSuffix >= cchDest)
124 return FALSE;
125
126 StringCchCopyW(pszDest, cchDest, lpSrc);
127 StringCchCatW(pszDest, cchDest, &lpString[cchEnvPath]);
128 return TRUE;
129}
130
131/*************************************************************************
132 * PathUnExpandEnvStringsForUserA [SHLWAPI.465]
133 *
134 * See PathUnExpandEnvStringsForUserW.
135 */
140 _In_ PCSTR pszPath,
141 _Out_writes_(cchBuff) PSTR pszBuff,
142 _In_ INT cchBuff)
143{
144 static const PCSTR c_varsA[] =
145 {
146 "%APPDATA%",
147 "%USERPROFILE%",
148 "%ALLUSERSPROFILE%",
149 "%ProgramFiles%",
150 "%SystemRoot%",
151 "%SystemDrive%",
152 };
153
154 if (!pszPath)
155 {
156 if (pszBuff && cchBuff)
157 *pszBuff = ANSI_NULL;
158
159 return FALSE;
160 }
161
162 if (!pszBuff)
163 return FALSE;
164
165 for (size_t iVar = 0; iVar < _countof(c_varsA); ++iVar)
166 {
167 if (UnExpandEnvironmentStringForUserA(hUserToken, pszPath, c_varsA[iVar],
168 pszBuff, cchBuff))
169 {
170 return TRUE;
171 }
172 }
173
174 return FALSE;
175}
176
177/*************************************************************************
178 * PathUnExpandEnvStringsForUserW [SHLWAPI.466]
179 *
180 * https://undoc.airesoft.co.uk/shlwapi.dll/PathUnExpandEnvStringsForUserW.php
181 */
186 _In_ PCWSTR pwszPath,
187 _Out_writes_(cchBuff) PWSTR pszBuff,
188 _In_ INT cchBuff)
189{
190 static const PCWSTR c_varsW[] =
191 {
192 L"%APPDATA%",
193 L"%USERPROFILE%",
194 L"%ALLUSERSPROFILE%",
195 L"%ProgramFiles%",
196 L"%SystemRoot%",
197 L"%SystemDrive%",
198 };
199
200 if (!pwszPath)
201 {
202 if (pszBuff && cchBuff)
203 *pszBuff = UNICODE_NULL;
204
205 return FALSE;
206 }
207
208 if (!pszBuff)
209 return FALSE;
210
211 for (size_t iVar = 0; iVar < _countof(c_varsW); ++iVar)
212 {
213 if (UnExpandEnvironmentStringForUserW(hUserToken, pwszPath, c_varsW[iVar],
214 pszBuff, cchBuff))
215 {
216 return TRUE;
217 }
218 }
219
220 return FALSE;
221}
222
223/*************************************************************************
224 * MapWin32ErrorToSTG [SHLWAPI.485]
225 *
226 * https://undoc.airesoft.co.uk/shlwapi.dll/MapWin32ErrorToSTG.php
227 */
230{
231 switch (hr)
232 {
234 return STG_E_ACCESSDENIED;
237 return STG_E_FILENOTFOUND;
241 default:
242 return hr;
243 }
244}
245
246static BOOL CharLowerNoDBCSAWorker(PSTR lpString, INT cchMax, BOOL bUppercase)
247{
248 CHAR szBuff[MAX_PATH];
249 INT cch;
250 if (!lpString)
251 return FALSE;
252 cch = cchMax ? cchMax : lstrlenA(lpString);
253 if (FAILED(StringCchCopyA(szBuff, _countof(szBuff), lpString)))
254 return FALSE;
256 szBuff, cch, lpString, cch);
257}
258
259static BOOL CharLowerNoDBCSWWorker(PWSTR lpString, INT cchMax, BOOL bUppercase)
260{
261 WCHAR szDest[MAX_PATH];
262 INT cch;
263 if (!lpString)
264 return FALSE;
265 cch = cchMax ? cchMax : lstrlenW(lpString);
266 if (FAILED(StringCchCopyW(szDest, _countof(szDest), lpString)))
267 return FALSE;
269 szDest, cch, lpString, cch);
270}
271
272/*************************************************************************
273 * CharLowerNoDBCSA [SHLWAPI.453]
274 */
276{
277 return CharLowerNoDBCSAWorker(lpString, 0, FALSE) ? lpString : NULL;
278}
279
280/*************************************************************************
281 * CharLowerNoDBCSW [SHLWAPI.454]
282 */
284{
285 return CharLowerNoDBCSWWorker(lpString, 0, FALSE) ? lpString : NULL;
286}
287
288/*************************************************************************
289 * CharUpperNoDBCSA [SHLWAPI.451]
290 */
292{
293 return CharLowerNoDBCSAWorker(lpString, 0, TRUE) ? lpString : NULL;
294}
295
296/*************************************************************************
297 * CharUpperNoDBCSW [SHLWAPI.452]
298 */
300{
301 return CharLowerNoDBCSWWorker(lpString, 0, TRUE) ? lpString : NULL;
302}
303
304static HRESULT
308 _In_ IContextMenu* pCM,
309 _In_ UINT fCMIC,
310 _In_ UINT fCMF,
311 _In_opt_ LPCSTR pszVerb,
312 _In_opt_ LPCWSTR pwszDir,
313 _In_ bool ForceQCM)
314{
315 CMINVOKECOMMANDINFOEX info = { sizeof(info), fCMIC, hWnd, pszVerb };
316 INT iDefItem = 0;
317 HMENU hMenu = NULL;
318 HCURSOR hOldCursor;
319 HRESULT hr = S_OK;
320 WCHAR wideverb[MAX_PATH];
321
322 if (!pCM)
323 return E_INVALIDARG;
324
325 hOldCursor = SetCursor(LoadCursorW(NULL, (LPCWSTR)IDC_WAIT));
326 info.nShow = SW_NORMAL;
327 if (pUnk)
329
330 if (IS_INTRESOURCE(pszVerb))
331 {
332 hMenu = CreatePopupMenu();
333 if (hMenu)
334 {
335 hr = pCM->QueryContextMenu(hMenu, 0, 1, MAXSHORT, fCMF | CMF_DEFAULTONLY);
336 iDefItem = GetMenuDefaultItem(hMenu, 0, 0);
337 if (iDefItem != -1)
338 info.lpVerb = MAKEINTRESOURCEA(iDefItem - 1);
339 }
340 info.lpVerbW = MAKEINTRESOURCEW(info.lpVerb);
341 }
342 else
343 {
345 {
346 info.fMask |= CMF_OPTIMIZEFORINVOKE;
347 }
348 if (pszVerb && SHAnsiToUnicode(pszVerb, wideverb, _countof(wideverb)))
349 {
350 info.fMask |= CMIC_MASK_UNICODE;
351 info.lpVerbW = wideverb;
352 }
353 if (ForceQCM)
354 {
355 hMenu = CreatePopupMenu();
356 hr = pCM->QueryContextMenu(hMenu, 0, 1, MAXSHORT, fCMF);
357 }
358 }
359
360 SetCursor(hOldCursor);
361
362 if (!FAILED_UNEXPECTEDLY(hr) && (iDefItem != -1 || info.lpVerb))
363 {
364 if (!hWnd)
365 info.fMask |= CMIC_MASK_FLAG_NO_UI;
366
368 if (pwszDir)
369 {
370 info.fMask |= CMIC_MASK_UNICODE;
371 info.lpDirectoryW = pwszDir;
372 if (SHUnicodeToAnsi(pwszDir, dir, _countof(dir)))
373 info.lpDirectory = dir;
374 }
375
376 hr = pCM->InvokeCommand((LPCMINVOKECOMMANDINFO)&info);
377 if (FAILED_UNEXPECTEDLY(hr)) { /* Diagnostic message */ }
378 }
379
380 if (pUnk)
382 if (hMenu)
383 DestroyMenu(hMenu);
384
385 return hr;
386}
387
388/*************************************************************************
389 * SHInvokeCommandOnContextMenuEx [SHLWAPI.639]
390 */
396 _In_ IContextMenu* pCM,
397 _In_ UINT fCMIC,
398 _In_ UINT fCMF,
399 _In_opt_ LPCSTR pszVerb,
400 _In_opt_ LPCWSTR pwszDir)
401{
402 return SHInvokeCommandOnContextMenuInternal(hWnd, pUnk, pCM, fCMIC, fCMF, pszVerb, pwszDir, true);
403}
404
405/*************************************************************************
406 * SHInvokeCommandOnContextMenu [SHLWAPI.540]
407 */
413 _In_ IContextMenu* pCM,
414 _In_ UINT fCMIC,
415 _In_opt_ LPCSTR pszVerb)
416{
417 return SHInvokeCommandOnContextMenuEx(hWnd, pUnk, pCM, fCMIC, CMF_EXTENDEDVERBS, pszVerb, NULL);
418}
419
420static inline BOOL
422{
423 for (const signed char *pch = (const signed char *)psz; *pch; ++pch)
424 {
425 if (*pch < 0)
426 return FALSE;
427 }
428 return TRUE;
429}
430
431/*************************************************************************
432 * SHInvokeCommandsOnContextMenu [SHLWAPI.541]
433 */
438 _In_opt_ IUnknown *punkSite,
439 _In_ IContextMenu *pCM,
440 _In_ DWORD fMask,
441 _In_reads_opt_(cVerbs) PCSTR *pVerbs,
442 _In_ UINT cVerbs)
443{
444 HRESULT hr;
445 CMINVOKECOMMANDINFOEX ici;
446 WCHAR szVerbW[MAX_PATH];
447 HMENU hMenu = NULL;
448 UINT iVerb, idDefault = (UINT)-1;
449 PCSTR pszVerbA = NULL;
450
451 if (!pCM)
452 return E_INVALIDARG;
453
454 hMenu = CreatePopupMenu();
455 if (!hMenu)
456 return E_OUTOFMEMORY;
457
458 if (punkSite)
459 IUnknown_SetSite(pCM, punkSite);
460
461 hr = pCM->QueryContextMenu(hMenu, 0, 1, MAXSHORT, (cVerbs ? 0 : CMF_DEFAULTONLY));
462 if (FAILED(hr))
463 goto Cleanup;
464
465 if (!cVerbs)
466 {
467 idDefault = GetMenuDefaultItem(hMenu, FALSE, 0);
468 if (idDefault != (UINT)-1)
469 pszVerbA = MAKEINTRESOURCEA(idDefault - 1);
470 }
471
472 ZeroMemory(&ici, sizeof(ici));
473 ici.cbSize = sizeof(ici);
474 ici.hwnd = hwnd;
475 ici.nShow = SW_SHOWNORMAL;
476
477 iVerb = 0;
478 do
479 {
480 if (cVerbs)
481 pszVerbA = pVerbs[iVerb];
482
483 if (!pszVerbA && idDefault == (UINT)-1)
484 {
485 hr = E_FAIL;
486 break;
487 }
488
489 ici.fMask = fMask;
490 ici.lpVerb = pszVerbA;
491 ici.lpVerbW = NULL;
492
493 if (idDefault == (UINT)-1 && !IS_INTRESOURCE(pszVerbA) && IsTextAsciiOnly(pszVerbA))
494 {
495 size_t ich;
496 for (ich = 0; pszVerbA[ich] && ich + 1 < _countof(szVerbW); ++ich)
497 {
498 szVerbW[ich] = (BYTE)pszVerbA[ich];
499 }
500 szVerbW[ich] = UNICODE_NULL;
501
502 ici.lpVerbW = szVerbW;
503 ici.fMask |= CMIC_MASK_UNICODE;
504 }
505
506 hr = pCM->InvokeCommand((LPCMINVOKECOMMANDINFO)&ici);
507
509 break;
510
511 ++iVerb;
512 } while (iVerb < cVerbs);
513
514Cleanup:
515 if (punkSite)
517 DestroyMenu(hMenu);
518 return hr;
519}
520
521/*************************************************************************
522 * SHInvokeCommandWithFlagsAndSite [SHLWAPI.571]
523 */
529 _In_ IShellFolder* pShellFolder,
530 _In_ LPCITEMIDLIST pidl,
531 _In_ UINT fCMIC,
532 _In_opt_ LPCSTR pszVerb)
533{
535 if (pShellFolder)
536 {
537 IContextMenu *pCM;
538 hr = pShellFolder->GetUIObjectOf(hWnd, 1, &pidl, IID_IContextMenu, NULL, (void**)&pCM);
539 if (SUCCEEDED(hr))
540 {
541 fCMIC |= CMIC_MASK_FLAG_LOG_USAGE;
542 hr = SHInvokeCommandOnContextMenuEx(hWnd, pUnk, pCM, fCMIC, 0, pszVerb, NULL);
543 pCM->Release();
544 }
545 }
546 return hr;
547}
548
549
550/*************************************************************************
551 * IContextMenu_Invoke [SHLWAPI.207]
552 *
553 * Used by Win:SHELL32!CISFBand::_TrySimpleInvoke.
554 */
558 _In_ IContextMenu *pContextMenu,
559 _In_ HWND hwnd,
560 _In_ LPCSTR lpVerb,
562{
563 TRACE("(%p, %p, %s, %u)\n", pContextMenu, hwnd, debugstr_a(lpVerb), uFlags);
565 uFlags, lpVerb, NULL, false);
566 return !FAILED_UNEXPECTEDLY(hr);
567}
568
569/*************************************************************************
570 * ShellExecuteCommand [INTERNAL]
571 */
572static HRESULT
574{
575 WCHAR szCmd[MAX_PATH * 2];
577 if (len <= 0) // Could not resolve the command, just use the input
578 {
579 HRESULT hr = StringCchCopyW(szCmd, _countof(szCmd), Command);
580 if (FAILED(hr))
581 return hr;
582 }
583 PWSTR pszArgs = PathGetArgsW(szCmd);
584 PathRemoveArgsW(szCmd);
585 PathUnquoteSpacesW(szCmd);
586
587 SHELLEXECUTEINFOW sei = { sizeof(sei), Flags, hWnd, NULL, szCmd, pszArgs };
588 sei.nShow = SW_SHOW;
591}
592
593/*************************************************************************
594 * RunRegCommand [SHLWAPI.469]
595 */
598{
599 WCHAR szCmd[MAX_PATH * 2];
600 DWORD cb = sizeof(szCmd);
602 if (error)
605}
606
607/*************************************************************************
608 * RunIndirectRegCommand [SHLWAPI.468]
609 */
612{
613 WCHAR szKey[MAX_PATH];
614 HRESULT hr;
615 if (pszSubKey)
616 hr = StringCchPrintfW(szKey, _countof(szKey), L"%s\\shell\\%s\\command", pszSubKey, pszVerb);
617 else
618 hr = StringCchPrintfW(szKey, _countof(szKey), L"shell\\%s\\command", pszVerb);
619 return SUCCEEDED(hr) ? RunRegCommand(hWnd, hKey, szKey) : hr;
620}
621
622/*************************************************************************
623 * SHRunIndirectRegClientCommand [SHLWAPI.467]
624 */
627{
628 WCHAR szKey[MAX_PATH], szClient[MAX_PATH];
629 HRESULT hr = StringCchPrintfW(szKey, _countof(szKey), L"Software\\Clients\\%s", pszClientType);
630 if (FAILED(hr))
631 return hr;
632
633 // Find the default client
634 DWORD error, cb;
635 cb = sizeof(szClient);
637 if (error)
638 {
639 cb = sizeof(szClient);
642 if (error)
644 }
645
646 hr = StringCchPrintfW(szKey, _countof(szKey), L"Software\\Clients\\%s\\%s", pszClientType, szClient);
647 if (SUCCEEDED(hr))
649 return hr;
650}
651
652/*************************************************************************
653 * PathFileExistsDefExtAndAttributesW [SHLWAPI.511]
654 *
655 * @param pszPath The path string.
656 * @param dwWhich The WHICH_... flags.
657 * @param pdwFileAttributes A pointer to the file attributes. Optional.
658 * @return TRUE if successful.
659 */
662 _Inout_ LPWSTR pszPath,
663 _In_ DWORD dwWhich,
664 _Out_opt_ LPDWORD pdwFileAttributes)
665{
666 TRACE("(%s, 0x%lX, %p)\n", debugstr_w(pszPath), dwWhich, pdwFileAttributes);
667
668 if (pdwFileAttributes)
669 *pdwFileAttributes = INVALID_FILE_ATTRIBUTES;
670
671 if (!pszPath)
672 return FALSE;
673
674 if (!dwWhich || (*PathFindExtensionW(pszPath) && (dwWhich & WHICH_OPTIONAL)))
675 return PathFileExistsAndAttributesW(pszPath, pdwFileAttributes);
676
677 if (!PathFileExistsDefExtW(pszPath, dwWhich))
678 {
679 if (pdwFileAttributes)
680 *pdwFileAttributes = INVALID_FILE_ATTRIBUTES;
681 return FALSE;
682 }
683
684 if (pdwFileAttributes)
685 *pdwFileAttributes = GetFileAttributesW(pszPath);
686
687 return TRUE;
688}
689
690static inline BOOL
692{
693 return (hr == E_FAIL || hr == E_INVALIDARG || hr == E_NOTIMPL);
694}
695
696// Used for IShellFolder_GetDisplayNameOf
698{
699 SHGDNF uRemove;
700 SHGDNF uAdd;
702};
703static const RETRY_DATA g_RetryData[] =
704{
705 { SHGDN_FOREDITING, SHGDN_NORMAL, SFGDNO_RETRYALWAYS },
706 { SHGDN_FORADDRESSBAR, SHGDN_NORMAL, SFGDNO_RETRYALWAYS },
707 { SHGDN_NORMAL, SHGDN_FORPARSING, SFGDNO_RETRYALWAYS },
708 { SHGDN_FORPARSING, SHGDN_NORMAL, SFGDNO_RETRYWITHFORPARSING },
709 { SHGDN_INFOLDER, SHGDN_NORMAL, SFGDNO_RETRYALWAYS },
710};
711
712/*************************************************************************
713 * IShellFolder_GetDisplayNameOf [SHLWAPI.316]
714 *
715 * @note Don't confuse with <shobjidl.h> inline function of the same name.
716 * If the original call fails with the given uFlags, this function will
717 * retry with other flags to attempt retrieving any meaningful description.
718 */
721 _In_ IShellFolder *psf,
722 _In_ LPCITEMIDLIST pidl,
723 _In_ SHGDNF uFlags,
725 _In_ DWORD dwRetryFlags) // dwRetryFlags is an additional parameter
726{
727 HRESULT hr;
728
729 TRACE("(%p)->(%p, 0x%lX, %p, 0x%lX)\n", psf, pidl, uFlags, lpName, dwRetryFlags);
730
731 hr = psf->GetDisplayNameOf(pidl, uFlags, lpName);
733 return hr;
734
735 dwRetryFlags |= SFGDNO_RETRYALWAYS;
736
737 if ((uFlags & SHGDN_FORPARSING) == 0)
738 dwRetryFlags |= SFGDNO_RETRYWITHFORPARSING;
739
740 // Retry with other flags to get successful results
741 for (SIZE_T iEntry = 0; iEntry < _countof(g_RetryData); ++iEntry)
742 {
743 const RETRY_DATA *pData = &g_RetryData[iEntry];
744 if (!(dwRetryFlags & pData->dwRetryFlags))
745 continue;
746
747 SHGDNF uNewFlags = ((uFlags & ~pData->uRemove) | pData->uAdd);
748 if (uNewFlags == uFlags)
749 continue;
750
751 hr = psf->GetDisplayNameOf(pidl, uNewFlags, lpName);
753 break;
754
755 uFlags = uNewFlags; // Update flags every time
756 }
757
758 return hr;
759}
760
761/*************************************************************************
762 * IShellFolder_ParseDisplayName [SHLWAPI.317]
763 *
764 * @note Don't confuse with <shobjidl.h> inline function of the same name.
765 * This function is safer than IShellFolder::ParseDisplayName.
766 */
769 _In_ IShellFolder *psf,
770 _In_opt_ HWND hwndOwner,
771 _In_opt_ LPBC pbcReserved,
772 _In_ LPOLESTR lpszDisplayName,
773 _Out_opt_ ULONG *pchEaten,
775 _Out_opt_ ULONG *pdwAttributes)
776{
777 ULONG dummy1, dummy2;
778
779 TRACE("(%p)->(%p, %p, %s, %p, %p, %p)\n", psf, hwndOwner, pbcReserved,
780 debugstr_w(lpszDisplayName), pchEaten, ppidl, pdwAttributes);
781
782 if (!pdwAttributes)
783 {
784 dummy1 = 0;
785 pdwAttributes = &dummy1;
786 }
787
788 if (!pchEaten)
789 {
790 dummy2 = 0;
791 pchEaten = &dummy2;
792 }
793
794 if (ppidl)
795 *ppidl = NULL;
796
797 return psf->ParseDisplayName(hwndOwner, pbcReserved, lpszDisplayName, pchEaten,
798 ppidl, pdwAttributes);
799}
800
801/*************************************************************************
802 * IShellFolder_CompareIDs [SHLWAPI.551]
803 *
804 * @note Don't confuse with <shobjidl.h> inline function of the same name.
805 * This function tries IShellFolder2 if possible.
806 */
809 _In_ IShellFolder *psf,
813{
814 TRACE("(%p, %p, %p, %p)\n", psf, lParam, pidl1, pidl2);
815
816 if (lParam & ~(SIZE_T)SHCIDS_COLUMNMASK)
817 {
818 /* Try as IShellFolder2 if possible */
819 HRESULT hr = psf->QueryInterface(IID_IShellFolder2, (void **)&psf);
820 if (FAILED(hr))
821 lParam &= SHCIDS_COLUMNMASK;
822 else
823 psf->Release();
824 }
825
826 return psf->CompareIDs(lParam, pidl1, pidl2);
827}
828
829/*************************************************************************
830 * SHDialogProc [INTERNAL]
831 *
832 * Used in SHDialogBox below
833 */
834
835typedef struct tagSHDIALOG
836{
840
841static INT_PTR CALLBACK
843{
846 HWND hwndItem;
847 LRESULT ret;
848
849 if (uMsg == WM_INITDIALOG)
850 {
853 lParam = (LPARAM)pData->pThis;
854 }
855 else
856 {
858 }
859
860 if (pData && pData->fn)
861 {
862 result = pData->fn(pData->pThis, hWnd, uMsg, wParam, lParam);
863 if (result)
864 return result;
865 }
866
867 switch (uMsg)
868 {
869 case WM_INITDIALOG:
870 return TRUE;
871
872 case WM_COMMAND:
873 if (LOWORD(wParam) == IDHELP)
874 return FALSE;
875
876 hwndItem = GetDlgItem(hWnd, LOWORD(wParam));
877 if (!hwndItem)
878 return FALSE;
879
880 ret = SendMessageA(hwndItem, WM_GETDLGCODE, 0, 0);
882 return FALSE;
883
885 return TRUE;
886
887 default:
888 return FALSE;
889 }
890}
891
892/*************************************************************************
893 * SHDialogBox [SHLWAPI.277]
894 */
898 _In_ PCSTR lpTemplateName,
901 _In_opt_ PVOID pThis)
902{
903 SHDIALOG data = { fn, pThis };
904 return DialogBoxParamA(hInstance, lpTemplateName, hWndParent, SHDialogProc, (LPARAM)&data);
905}
906
907/*************************************************************************
908 * NextPathA [SHLWAPI.449]
909 *
910 * See NextPathW.
911 */
914 _In_ PCSTR pszStart,
915 _Out_writes_(cchDest) PSTR pszDest,
917{
918 if (!pszStart)
919 return NULL;
920
921 PCSTR pchStart = pszStart;
922 while (*pchStart == ';')
923 ++pchStart;
924
925 if (!*pchStart)
926 return NULL;
927
928 PSTR pchEnd = StrChrA(pchStart, ';');
929 if (!pchEnd)
930 pchEnd = (PSTR)(pchStart + lstrlenA(pchStart));
931
932 const UINT cchSegment = (UINT)(pchEnd - pchStart);
933 const UINT cchToCopy = min(cchSegment + 1, cchDest);
934 lstrcpynA(pszDest, pchStart, cchToCopy);
935 pszDest[cchSegment] = ANSI_NULL;
936
937 PathRemoveBlanksA(pszDest);
938 if (!*pszDest)
939 return NULL;
940
941 return (*pchEnd == ';') ? (pchEnd + 1) : pchEnd;
942}
943
944/*************************************************************************
945 * NextPathW [SHLWAPI.450]
946 *
947 * Extracts the next path from a semicolon-separated path string (Unicode version)
948 *
949 * @param pszStart Parsing start position (semicolon-separated path string)
950 * @param pszDest Buffer to store the extracted path
951 * @param cchDest Buffer size (number of characters)
952 * @return Pointer to the beginning of the next path. NULL if there are no more paths.
953 */
956 _In_ PCWSTR pszStart,
957 _Out_writes_(cchDest) PWSTR pszDest,
959{
960 if (!pszStart)
961 return NULL;
962
963 PCWSTR pchStart = pszStart;
964 while (*pchStart == L';')
965 ++pchStart;
966
967 if (!*pchStart)
968 return NULL;
969
970 PWSTR pchEnd = StrChrW(pchStart, L';');
971 if (!pchEnd)
972 pchEnd = (PWSTR)(pchStart + lstrlenW(pchStart));
973
974 const UINT cchSegment = (UINT)(pchEnd - pchStart);
975 const UINT cchToCopy = min(cchSegment + 1, cchDest);
976 lstrcpynW(pszDest, pchStart, cchToCopy);
977 pszDest[cchSegment] = UNICODE_NULL;
978
979 PathRemoveBlanksW(pszDest);
980 if (!*pszDest)
981 return NULL;
982
983 return (*pchEnd == L';') ? (pchEnd + 1) : pchEnd;
984}
985
986static HRESULT
988 HKEY hkey,
991 PWSTR* ppszOut)
992{
993 *ppszOut = NULL;
994
997 if (error)
999
1000 PWSTR pszData = (PWSTR)LocalAlloc(LPTR, cbData);
1001 if (!pszData)
1003
1004 error = SHGetValueW(hkey, pszSubKey, pszValue, NULL, pszData, &cbData);
1005 if (error)
1006 {
1007 LocalFree(pszData);
1008 return HRESULT_FROM_WIN32(error);
1009 }
1010
1011 *ppszOut = pszData;
1012 return S_OK;
1013}
1014
1015/*************************************************************************
1016 * IUnknown_ShowBrowserBar [SHLWAPI.539]
1017 *
1018 * @see IWebBrowser2
1019 */
1023 _In_ REFGUID rguid,
1024 _In_ BOOL bShow)
1025{
1027 HRESULT hr = IUnknown_QueryServiceForWebBrowserApp(punk, IID_IWebBrowser2, (PVOID*)&pWB2);
1028 if (FAILED(hr))
1029 return hr;
1030
1031 WCHAR szGUID[40];
1032 StringFromGUID2(rguid, szGUID, _countof(szGUID));
1033
1034 CComVariant varClsid(szGUID), varShow((bool)!!bShow), varSize;
1035 return pWB2->ShowBrowserBar(&varClsid, &varShow, &varSize);
1036}
1037
1038/*************************************************************************
1039 * PrettifyFileDescriptionW [SHLWAPI.492]
1040 *
1041 * @see SHGetFileDescriptionW
1042 */
1045{
1046 if (!pszTarget || !*pszTarget)
1047 return;
1048
1049 PWSTR pszFreeList = NULL;
1050 PCWSTR pszList = pszCutList;
1051 PCWSTR pszAssoc = L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileAssociation";
1052 if (_AllocValueString(HKEY_LOCAL_MACHINE, pszAssoc, L"CutList", &pszFreeList) == S_OK)
1053 pszList = pszFreeList;
1054
1055 if (pszList && *pszList)
1056 {
1057 for (PCWSTR pszEntry = pszList; *pszEntry; pszEntry += lstrlenW(pszEntry) + 1)
1058 {
1059 PWSTR pszMatch = StrRStrIW(pszTarget, NULL, pszEntry);
1060 if (!pszMatch)
1061 continue;
1062
1063 if (pszMatch[lstrlenW(pszEntry)])
1064 continue;
1065
1066 *pszMatch = UNICODE_NULL;
1067 while (pszMatch > pszTarget && pszMatch[-1] == L' ')
1068 {
1069 --pszMatch;
1070 *pszMatch = UNICODE_NULL;
1071 }
1072
1073 break;
1074 }
1075 }
1076
1077 if (pszFreeList)
1078 LocalFree(pszFreeList);
1079}
1080
1081/*************************************************************************
1082 * SHGetFileDescriptionW [SHLWAPI.348]
1083 *
1084 * @see SHGetFileDescriptionA
1085 * @see PrettifyFileDescriptionW
1086 */
1088 _In_ PCWSTR pszPath,
1089 _In_opt_ PCWSTR pszVerKey,
1090 _In_opt_ PCWSTR pszDisplayName,
1091 _Out_opt_ PWSTR pszOut,
1092 _Inout_ PUINT pcchOut)
1093{
1094 DWORD pdwAttrs = 0;
1095 if (!PathFileExistsAndAttributesW(pszPath, &pdwAttrs))
1096 return FALSE;
1097
1100
1101 PVOID pvDescription = NULL;
1102 UINT cchDescription = 0;
1103 PVOID pvBlock = NULL;
1104
1105 BOOL bIsFile = !(pdwAttrs & FILE_ATTRIBUTE_DIRECTORY) &&
1106 !PathIsUNCServerW(pszPath) &&
1107 !PathIsUNCServerShareW(pszPath);
1108 if (bIsFile)
1109 {
1110 DWORD dwHandle = 0;
1111 DWORD cbBlock = GetFileVersionInfoSizeW(szPath, &dwHandle);
1112 if (cbBlock)
1113 {
1114 pvBlock = LocalAlloc(LPTR, cbBlock);
1115 if (pvBlock && GetFileVersionInfoW(szPath, dwHandle, cbBlock, pvBlock))
1116 {
1117 WCHAR szSubBlock[60];
1118 BOOL ret = FALSE;
1119 if (pszVerKey)
1120 {
1121 StringCchCopyW(szSubBlock, _countof(szSubBlock), pszVerKey);
1122 ret = VerQueryValueW(pvBlock, szSubBlock, &pvDescription, &cchDescription);
1123 }
1124
1125 if (!ret)
1126 {
1127 PVOID pTranslation = NULL;
1128 UINT cbTranslation = 0;
1129 if (VerQueryValueW(pvBlock, L"\\VarFileInfo\\Translation", &pTranslation,
1130 &cbTranslation) && cbTranslation)
1131 {
1132 UINT langId = ((PWORD)pTranslation)[0];
1133 UINT codePage = ((PWORD)pTranslation)[1];
1134 StringCchPrintfW(szSubBlock, _countof(szSubBlock),
1135 L"\\StringFileInfo\\%04X%04X\\FileDescription",
1136 langId, codePage);
1137 ret = VerQueryValueW(pvBlock, szSubBlock, &pvDescription, &cchDescription);
1138 }
1139 }
1140
1141 if (!ret)
1142 {
1143 // 0x0409: English (United States), 0x04B0: UTF-16 codepage
1144 StringCchCopyW(szSubBlock, _countof(szSubBlock),
1145 L"\\StringFileInfo\\040904B0\\FileDescription");
1146 ret = VerQueryValueW(pvBlock, szSubBlock, &pvDescription, &cchDescription);
1147 }
1148 if (!ret)
1149 {
1150 // 0x0409: English (United States), 0x04E4: Latin 1 codepage
1151 StringCchCopyW(szSubBlock, _countof(szSubBlock),
1152 L"\\StringFileInfo\\040904E4\\FileDescription");
1153 ret = VerQueryValueW(pvBlock, szSubBlock, &pvDescription, &cchDescription);
1154 }
1155 if (!ret)
1156 {
1157 // 0x0409: English (United States), 0x0000: Neutral
1158 StringCchCopyW(szSubBlock, _countof(szSubBlock),
1159 L"\\StringFileInfo\\04090000\\FileDescription");
1160 ret = VerQueryValueW(pvBlock, szSubBlock, &pvDescription, &cchDescription);
1161 }
1162 }
1163 }
1164 }
1165
1166 PWSTR pszDescription = (PWSTR)pvDescription;
1167 if (!pszDescription || !*pszDescription)
1168 {
1170 pszDescription = PathFindFileNameW(szPath);
1171 cchDescription = lstrlenW(pszDescription);
1172 }
1173
1174 PrettifyFileDescriptionW(pszDescription, pszDisplayName);
1175
1176 UINT cchResult = lstrlenW(pszDescription) + 1;
1177 if (pszOut)
1178 {
1179 UINT cchCopy = min(cchResult, *pcchOut);
1180 StringCchCopyW(pszOut, cchCopy, pszDescription);
1181 *pcchOut = cchCopy;
1182 }
1183 else
1184 {
1185 *pcchOut = cchResult;
1186 }
1187
1188 if (pvBlock)
1189 LocalFree(pvBlock);
1190
1191 return TRUE;
1192}
1193
1194/*************************************************************************
1195 * SHGetFileDescriptionA [SHLWAPI.349]
1196 *
1197 * @see SHGetFileDescriptionW
1198 */
1200 _In_ PCSTR pszPath,
1201 _In_opt_ PCSTR pszVerKey,
1202 _In_opt_ PCSTR pszDisplayName,
1203 _Out_opt_ PSTR pszOut,
1204 _Inout_ PUINT pcchOut)
1205{
1206 WCHAR szPathW[MAX_PATH], szVerKeyW[MAX_PATH], szDisplayNameW[MAX_PATH], szOutW[MAX_PATH];
1207 CHAR szOutA[MAX_PATH];
1208 BOOL ret;
1209 UINT cchOutW;
1210
1211 SHAnsiToUnicode(pszPath, szPathW, _countof(szPathW));
1212 szPathW[_countof(szPathW) - 1] = UNICODE_NULL;
1213
1214 if (pszVerKey)
1215 {
1216 SHAnsiToUnicode(pszVerKey, szVerKeyW, _countof(szVerKeyW));
1217 szVerKeyW[_countof(szVerKeyW) - 1] = UNICODE_NULL;
1218 }
1219
1220 if (pszDisplayName)
1221 {
1222 SHAnsiToUnicode(pszDisplayName, szDisplayNameW, _countof(szDisplayNameW));
1223 szDisplayNameW[_countof(szDisplayNameW) - 1] = UNICODE_NULL;
1224 }
1225
1226 cchOutW = (UINT)_countof(szOutW);
1227 ret = SHGetFileDescriptionW(szPathW, (pszVerKey ? szVerKeyW : NULL),
1228 (pszDisplayName ? szDisplayNameW : NULL), szOutW, &cchOutW);
1229 if (ret)
1230 {
1231 szOutW[_countof(szOutW) - 1] = UNICODE_NULL;
1232
1233 if (!pszOut)
1234 pszOut = szOutA;
1235
1236 SHUnicodeToAnsi(szOutW, pszOut, *pcchOut);
1237 if (*pcchOut > 0)
1238 pszOut[*pcchOut - 1] = ANSI_NULL;
1239 *pcchOut = lstrlenA(pszOut) + 1;
1240 }
1241
1242 return ret;
1243}
1244
1245/*************************************************************************
1246 * SHRestrictedMessageBox [SHLWAPI.384]
1247 *
1248 * @see https://www.geoffchappell.com/studies/windows/shell/shlwapi/api/util/restrictions/messagebox.htm
1249 * @see ShellMessageBoxW
1250 */
1252{
1254 MAKEINTRESOURCEW(IDS_RESTRICTIONS), MB_ICONERROR);
1255}
1256
1258{
1259 PPEB Peb = NtCurrentTeb()->Peb;
1260 return (Peb->OSMajorVersion << 8) | Peb->OSMinorVersion;
1261}
#define PathUnExpandEnvStringsForUserW
UINT cchMax
unsigned int dir
Definition: maze.c:112
HWND hWnd
Definition: settings.c:17
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
HANDLE hUserToken
Definition: install.c:39
#define EXTERN_C
Definition: basetyps.h:12
HINSTANCE hInstance
Definition: charmap.c:19
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define ERROR_MORE_DATA
Definition: dderror.h:13
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
HRESULT hr
Definition: delayimp.cpp:582
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define ERROR_SUCCESS
Definition: deptool.c:10
static LSTATUS(WINAPI *pRegDeleteTreeW)(HKEY
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UINT uFlags
Definition: api.c:59
INT WINAPI StringFromGUID2(REFGUID guid, LPOLESTR str, INT cmax)
Definition: combase.c:1525
LPWSTR WINAPI StrChrW(LPCWSTR lpszStr, WCHAR ch)
Definition: string.c:464
LPSTR WINAPI StrChrA(LPCSTR lpszStr, WORD ch)
Definition: string.c:266
LPWSTR WINAPI StrRStrIW(LPCWSTR lpszStr, LPCWSTR lpszEnd, LPCWSTR lpszSearch)
Definition: string.c:702
#define lstrcpynA
Definition: compat.h:751
#define MAX_PATH
Definition: compat.h:34
#define CALLBACK
Definition: compat.h:35
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
static const WCHAR version[]
Definition: asmname.c:66
PPEB Peb
Definition: dllmain.c:27
DWORD WINAPI ExpandEnvironmentStringsA(IN LPCSTR lpSrc, IN LPSTR lpDst, IN DWORD nSize)
Definition: environ.c:372
DWORD WINAPI ExpandEnvironmentStringsW(IN LPCWSTR lpSrc, IN LPWSTR lpDst, IN DWORD nSize)
Definition: environ.c:492
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:636
INT WINAPI LCMapStringA(LCID lcid, DWORD flags, LPCSTR src, INT srclen, LPSTR dst, INT dstlen)
Definition: locale.c:3834
INT WINAPI CompareStringA(LCID lcid, DWORD flags, LPCSTR str1, INT len1, LPCSTR str2, INT len2)
Definition: locale.c:4015
INT WINAPI CompareStringW(LCID lcid, DWORD flags, LPCWSTR str1, INT len1, LPCWSTR str2, INT len2)
Definition: locale.c:3946
INT WINAPI LCMapStringW(LCID lcid, DWORD flags, LPCWSTR src, INT srclen, LPWSTR dst, INT dstlen)
Definition: locale.c:3808
#define IS_INTRESOURCE(x)
Definition: loader.c:613
void WINAPI PathRemoveExtensionW(WCHAR *path)
Definition: path.c:1922
void WINAPI PathRemoveBlanksW(WCHAR *path)
Definition: path.c:1886
void WINAPI PathRemoveBlanksA(char *path)
Definition: path.c:1862
void WINAPI PathUnquoteSpacesW(WCHAR *path)
Definition: path.c:1982
BOOL WINAPI PathIsUNCServerShareW(const WCHAR *path)
Definition: path.c:1040
WCHAR *WINAPI PathFindFileNameW(const WCHAR *path)
Definition: path.c:1677
LPWSTR WINAPI PathFindExtensionW(const WCHAR *path)
Definition: path.c:1250
BOOL WINAPI PathIsUNCServerW(const WCHAR *path)
Definition: path.c:1852
WCHAR *WINAPI PathGetArgsW(const WCHAR *path)
Definition: path.c:1716
DWORD WINAPI GetVersion(void)
Definition: version.c:1458
BOOL WINAPI GetFileVersionInfoW(LPCWSTR filename, DWORD handle, DWORD datasize, LPVOID data)
Definition: version.c:967
BOOL WINAPI VerQueryValueW(LPCVOID pBlock, LPCWSTR lpSubBlock, LPVOID *lplpBuffer, PUINT puLen)
Definition: version.c:1171
DWORD WINAPI GetFileVersionInfoSizeW(LPCWSTR filename, LPDWORD handle)
Definition: version.c:738
static MonoProfilerRuntimeShutdownBeginCallback cb
Definition: metahost.c:118
DWORD WINAPI SHGetValueW(HKEY hkey, const WCHAR *subkey, const WCHAR *value, DWORD *type, void *data, DWORD *data_len)
Definition: main.c:2222
DWORD WINAPI SHAnsiToUnicode(const char *src, WCHAR *dest, int dest_len)
Definition: main.c:1801
DWORD WINAPI SHUnicodeToAnsi(const WCHAR *src, char *dest, int dest_len)
Definition: main.c:1756
HRESULT WINAPI IUnknown_SetSite(IUnknown *obj, IUnknown *site)
Definition: main.c:222
#define ShellMessageBoxW
Definition: precomp.h:63
HINSTANCE shlwapi_hInstance
Definition: shlwapi_main.c:33
HRESULT WINAPI IUnknown_QueryServiceForWebBrowserApp(IUnknown *lpUnknown, REFGUID riid, LPVOID *lppOut)
Definition: ordinal.c:4814
void WINAPI PathRemoveArgsW(LPWSTR lpszPath)
Definition: path.c:153
BOOL WINAPI PathFileExistsAndAttributesW(LPCWSTR lpszPath, DWORD *dwAttr)
Definition: path.c:747
BOOL WINAPI PathFileExistsDefExtW(LPWSTR lpszPath, DWORD dwWhich)
Definition: path.c:170
EXTERN_C HRESULT WINAPI RunRegCommand(_In_opt_ HWND hWnd, _In_ HKEY hKey, _In_opt_ PCWSTR pszSubKey)
Definition: utils.cpp:597
EXTERN_C HRESULT WINAPI SHInvokeCommandOnContextMenu(_In_opt_ HWND hWnd, _In_opt_ IUnknown *pUnk, _In_ IContextMenu *pCM, _In_ UINT fCMIC, _In_opt_ LPCSTR pszVerb)
Definition: utils.cpp:410
EXTERN_C LSTATUS WINAPI RegGetValueW(HKEY, LPCWSTR, LPCWSTR, DWORD, LPDWORD, PVOID, LPDWORD)
Definition: reg.c:1931
static BOOL IsTextAsciiOnly(PCSTR psz)
Definition: utils.cpp:421
EXTERN_C BOOL WINAPI PathUnExpandEnvStringsForUserA(_In_ HANDLE hUserToken, _In_ PCSTR pszPath, _Out_writes_(cchBuff) PSTR pszBuff, _In_ INT cchBuff)
Definition: utils.cpp:138
struct tagSHDIALOG * PSHDIALOG
EXTERN_C INT WINAPI SHRestrictedMessageBox(_In_ HWND hWnd)
Definition: utils.cpp:1251
EXTERN_C HRESULT WINAPI RunIndirectRegCommand(_In_opt_ HWND hWnd, _In_ HKEY hKey, _In_opt_ PCWSTR pszSubKey, _In_ PCWSTR pszVerb)
Definition: utils.cpp:611
static HRESULT ShellExecuteCommand(_In_opt_ HWND hWnd, _In_ PCWSTR Command, _In_opt_ UINT Flags)
Definition: utils.cpp:573
EXTERN_C HRESULT WINAPI SHInvokeCommandWithFlagsAndSite(_In_opt_ HWND hWnd, _In_opt_ IUnknown *pUnk, _In_ IShellFolder *pShellFolder, _In_ LPCITEMIDLIST pidl, _In_ UINT fCMIC, _In_opt_ LPCSTR pszVerb)
Definition: utils.cpp:526
EXTERN_C PSTR WINAPI NextPathA(_In_ PCSTR pszStart, _Out_writes_(cchDest) PSTR pszDest, _In_ UINT cchDest)
Definition: utils.cpp:913
EXTERN_C PWSTR WINAPI CharLowerNoDBCSW(_Inout_ PWSTR lpString)
Definition: utils.cpp:283
EXTERN_C ULONG WINAPI GetProcessOsVersion(void)
Definition: utils.cpp:1257
static BOOL UnExpandEnvironmentStringForUserA(_In_ HANDLE hUserToken, _In_ PCSTR lpString, _In_ PCSTR lpSrc, _Out_ PSTR pszDest, _In_ INT cchDest)
Definition: utils.cpp:48
EXTERN_C INT_PTR WINAPI SHDialogBox(_In_opt_ HINSTANCE hInstance, _In_ PCSTR lpTemplateName, _In_opt_ HWND hWndParent, _In_opt_ SHDIALOGPROC fn, _In_opt_ PVOID pThis)
Definition: utils.cpp:896
EXTERN_C PSTR WINAPI CharUpperNoDBCSA(_Inout_ PSTR lpString)
Definition: utils.cpp:291
VOID WINAPI PrettifyFileDescriptionW(_Inout_ PWSTR pszTarget, _In_opt_ PCWSTR pszCutList)
Definition: utils.cpp:1044
static BOOL UnExpandEnvironmentStringForUserW(_In_ HANDLE hUserToken, _In_ PCWSTR lpString, _In_ PCWSTR lpSrc, _Out_ PWSTR pszDest, _In_ INT cchDest)
Definition: utils.cpp:90
EXTERN_C HRESULT WINAPI SHInvokeCommandOnContextMenuEx(_In_opt_ HWND hWnd, _In_opt_ IUnknown *pUnk, _In_ IContextMenu *pCM, _In_ UINT fCMIC, _In_ UINT fCMF, _In_opt_ LPCSTR pszVerb, _In_opt_ LPCWSTR pwszDir)
Definition: utils.cpp:393
EXTERN_C HRESULT WINAPI MapWin32ErrorToSTG(_In_ HRESULT hr)
Definition: utils.cpp:229
EXTERN_C BOOL WINAPI IContextMenu_Invoke(_In_ IContextMenu *pContextMenu, _In_ HWND hwnd, _In_ LPCSTR lpVerb, _In_ UINT uFlags)
Definition: utils.cpp:557
BOOL WINAPI SHGetFileDescriptionA(_In_ PCSTR pszPath, _In_opt_ PCSTR pszVerKey, _In_opt_ PCSTR pszDisplayName, _Out_opt_ PSTR pszOut, _Inout_ PUINT pcchOut)
Definition: utils.cpp:1199
BOOL WINAPI SHGetFileDescriptionW(_In_ PCWSTR pszPath, _In_opt_ PCWSTR pszVerKey, _In_opt_ PCWSTR pszDisplayName, _Out_opt_ PWSTR pszOut, _Inout_ PUINT pcchOut)
Definition: utils.cpp:1087
EXTERN_C PSTR WINAPI CharLowerNoDBCSA(_Inout_ PSTR lpString)
Definition: utils.cpp:275
static const RETRY_DATA g_RetryData[]
Definition: utils.cpp:703
EXTERN_C HRESULT WINAPI SHInvokeCommandsOnContextMenu(_In_opt_ HWND hwnd, _In_opt_ IUnknown *punkSite, _In_ IContextMenu *pCM, _In_ DWORD fMask, _In_reads_opt_(cVerbs) PCSTR *pVerbs, _In_ UINT cVerbs)
Definition: utils.cpp:436
struct tagSHDIALOG SHDIALOG
static BOOL CharLowerNoDBCSWWorker(PWSTR lpString, INT cchMax, BOOL bUppercase)
Definition: utils.cpp:259
static HRESULT SHInvokeCommandOnContextMenuInternal(_In_opt_ HWND hWnd, _In_opt_ IUnknown *pUnk, _In_ IContextMenu *pCM, _In_ UINT fCMIC, _In_ UINT fCMF, _In_opt_ LPCSTR pszVerb, _In_opt_ LPCWSTR pwszDir, _In_ bool ForceQCM)
Definition: utils.cpp:305
#define FAILED_UNEXPECTEDLY
Definition: utils.cpp:33
static BOOL CharLowerNoDBCSAWorker(PSTR lpString, INT cchMax, BOOL bUppercase)
Definition: utils.cpp:246
EXTERN_C HRESULT WINAPI SHRunIndirectRegClientCommand(_In_opt_ HWND hWnd, _In_ PCWSTR pszClientType)
Definition: utils.cpp:626
EXTERN_C HRESULT WINAPI IUnknown_ShowBrowserBar(_In_ IUnknown *punk, _In_ REFGUID rguid, _In_ BOOL bShow)
Definition: utils.cpp:1021
#define IShellFolder_ParseDisplayName
Definition: utils.cpp:14
#define IShellFolder_CompareIDs
Definition: utils.cpp:15
static WORD GetVersionMajorMinor()
Definition: utils.cpp:41
EXTERN_C PWSTR WINAPI NextPathW(_In_ PCWSTR pszStart, _Out_writes_(cchDest) PWSTR pszDest, _In_ UINT cchDest)
Definition: utils.cpp:955
EXTERN_C PWSTR WINAPI CharUpperNoDBCSW(_Inout_ PWSTR lpString)
Definition: utils.cpp:299
static HRESULT _AllocValueString(HKEY hkey, PCWSTR pszSubKey, PCWSTR pszValue, PWSTR *ppszOut)
Definition: utils.cpp:987
BOOL WINAPI PathFileExistsDefExtAndAttributesW(_Inout_ LPWSTR pszPath, _In_ DWORD dwWhich, _Out_opt_ LPDWORD pdwFileAttributes)
Definition: utils.cpp:661
static INT_PTR CALLBACK SHDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: utils.cpp:842
#define IShellFolder_GetDisplayNameOf
Definition: utils.cpp:13
static BOOL SHLWAPI_IsBogusHRESULT(HRESULT hr)
Definition: utils.cpp:691
BOOL WINAPI ExpandEnvironmentStringsForUserW(IN HANDLE hToken, IN LPCWSTR lpSrc, OUT LPWSTR lpDest, IN DWORD dwSize)
Definition: environment.c:743
BOOL WINAPI ExpandEnvironmentStringsForUserA(IN HANDLE hToken, IN LPCSTR lpSrc, OUT LPSTR lpDest, IN DWORD dwSize)
Definition: environment.c:794
static const WCHAR Cleanup[]
Definition: register.c:80
static void *static void *static LPDIRECTPLAY IUnknown * pUnk
Definition: dplayx.c:30
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint64EXT * result
Definition: glext.h:11304
GLenum GLsizei len
Definition: glext.h:6722
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1390
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
ULONG Release()
nsrefcnt Release()
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define NtCurrentTeb
#define SFGDNO_RETRYWITHFORPARSING
#define SFGDNO_RETRYALWAYS
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define ZeroMemory
Definition: minwinbase.h:31
#define LPTR
Definition: minwinbase.h:93
LONG_PTR LPARAM
Definition: minwindef.h:175
LONG_PTR LRESULT
Definition: minwindef.h:176
UINT_PTR WPARAM
Definition: minwindef.h:174
#define error(str)
Definition: mkdosfs.c:1605
#define pch(ap)
Definition: match.c:418
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
LPCWSTR szPath
Definition: env.c:37
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
#define min(a, b)
Definition: monoChain.cc:55
unsigned int * PUINT
Definition: ndis.h:50
unsigned int UINT
Definition: ndis.h:50
#define _Out_opt_
Definition: no_sal2.h:214
#define _Inout_
Definition: no_sal2.h:162
#define _Out_writes_(s)
Definition: no_sal2.h:176
#define _Out_
Definition: no_sal2.h:160
#define _In_reads_opt_(s)
Definition: no_sal2.h:222
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define LOCALE_SYSTEM_DEFAULT
#define UNICODE_NULL
#define ANSI_NULL
interface IBindCtx * LPBC
Definition: objfwd.h:18
#define LOWORD(l)
Definition: pedump.c:82
WORD * PWORD
Definition: pedump.c:67
short WCHAR
Definition: pedump.c:58
char CHAR
Definition: pedump.c:57
_In_opt_ IUnknown * punk
Definition: shlwapi.h:158
_In_opt_ _In_opt_ _In_ _In_ DWORD cbData
Definition: shlwapi.h:761
_In_ INT cchDest
Definition: shlwapi.h:1151
_In_opt_ LPCSTR pszSubKey
Definition: shlwapi.h:783
_In_opt_ LPCSTR _In_opt_ LPCSTR pszValue
Definition: shlwapi.h:783
#define IDHELP
Definition: resource_2.h:8
#define _WIN32_WINNT_WIN7
Definition: sdkddkver.h:28
#define SEE_MASK_FLAG_LOG_USAGE
Definition: shellapi.h:55
_In_ UINT _In_ UINT cch
Definition: shellapi.h:432
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2723
#define PPCF_FORCEQUALIFY
Definition: shlobj.h:2429
LONG WINAPI PathProcessCommand(_In_ LPCWSTR, _Out_writes_(cchDest) LPWSTR, int cchDest, DWORD)
#define PPCF_ADDARGUMENTS
Definition: shlobj.h:2426
INT_PTR(CALLBACK * SHDIALOGPROC)(PVOID pThis, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
#define WHICH_OPTIONAL
const ITEMIDLIST_RELATIVE UNALIGNED * PCUIDLIST_RELATIVE
Definition: shtypes.idl:57
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
#define _countof(array)
Definition: sndvol32.h:70
#define TRACE(s)
Definition: solgame.cpp:4
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
STRSAFEAPI StringCchCatA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:320
STRSAFEAPI StringCchCatW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:325
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
STRSAFEAPI StringCchCopyA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:145
Definition: shell.h:41
SHGDNF uAdd
Definition: utils.cpp:700
SHGDNF uRemove
Definition: utils.cpp:699
DWORD dwRetryFlags
Definition: utils.cpp:701
Definition: scsiwmi.h:51
ULONG OSMinorVersion
Definition: ntddk_ex.h:301
ULONG OSMajorVersion
Definition: ntddk_ex.h:300
SHDIALOGPROC fn
Definition: utils.cpp:837
PVOID pThis
Definition: utils.cpp:838
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
uint16_t * PWSTR
Definition: typedefs.h:56
const char * LPCSTR
Definition: typedefs.h:52
int32_t INT_PTR
Definition: typedefs.h:64
char * PSTR
Definition: typedefs.h:51
const uint16_t * PCWSTR
Definition: typedefs.h:57
const uint16_t * LPCWSTR
Definition: typedefs.h:57
#define MAKEWORD(a, b)
Definition: typedefs.h:248
uint16_t * LPWSTR
Definition: typedefs.h:56
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t * LPDWORD
Definition: typedefs.h:59
int32_t INT
Definition: typedefs.h:58
const char * PCSTR
Definition: typedefs.h:52
uint32_t ULONG
Definition: typedefs.h:59
#define MAXSHORT
Definition: umtypes.h:114
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ LPCSTR lpName
Definition: winbase.h:2519
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
HICON HCURSOR
Definition: windef.h:99
#define WINAPI
Definition: msvc.h:6
#define ERROR_BUFFER_OVERFLOW
Definition: winerror.h:307
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:228
#define STG_E_FILEALREADYEXISTS
Definition: winerror.h:3674
#define STG_E_FILENOTFOUND
Definition: winerror.h:3660
#define ERROR_FILE_EXISTS
Definition: winerror.h:287
#define ERROR_CANCELLED
Definition: winerror.h:1055
#define STG_E_ACCESSDENIED
Definition: winerror.h:3663
#define NORM_IGNORECASE
Definition: winnls.h:191
#define LCMAP_UPPERCASE
Definition: winnls.h:202
#define CSTR_EQUAL
Definition: winnls.h:510
#define LCMAP_LOWERCASE
Definition: winnls.h:201
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define RRF_RT_REG_SZ
Definition: winreg.h:58
#define SW_SHOWNORMAL
Definition: winuser.h:781
#define SetWindowLongPtrA
Definition: winuser.h:5511
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:838
UINT WINAPI GetMenuDefaultItem(_In_ HMENU hMenu, _In_ UINT fByPos, _In_ UINT gmdiFlags)
#define DWLP_USER
Definition: winuser.h:883
#define WM_COMMAND
Definition: winuser.h:1768
#define DLGC_UNDEFPUSHBUTTON
Definition: winuser.h:2658
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
HCURSOR WINAPI SetCursor(_In_opt_ HCURSOR)
#define GetWindowLongPtrA
Definition: winuser.h:4982
#define WM_INITDIALOG
Definition: winuser.h:1767
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2474
#define DLGC_DEFPUSHBUTTON
Definition: winuser.h:2657
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
#define MB_ICONERROR
Definition: winuser.h:798
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define IDC_WAIT
Definition: winuser.h:697
#define SW_SHOW
Definition: winuser.h:786
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
#define SW_NORMAL
Definition: winuser.h:780
#define WM_GETDLGCODE
Definition: winuser.h:1717
INT_PTR WINAPI DialogBoxParamA(_In_opt_ HINSTANCE, _In_ LPCSTR, _In_opt_ HWND, _In_opt_ DLGPROC, _In_ LPARAM)
BOOL WINAPI EndDialog(_In_ HWND, _In_ INT_PTR)
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
unsigned char BYTE
Definition: xxhash.c:193