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 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> 6 */ 7 8 #define _ATL_NO_EXCEPTIONS 9 #include "precomp.h" 10 #include <shellapi.h> 11 #include <shlwapi.h> 12 #include <shlwapi_undoc.h> 13 #include <shlobj_undoc.h> 14 #include <shlguid_undoc.h> 15 #include <atlstr.h> 16 #include <strsafe.h> 17 18 WINE_DEFAULT_DEBUG_CHANNEL(shell); 19 20 /************************************************************************* 21 * IContextMenu_Invoke [SHLWAPI.207] 22 * 23 * Used by Win:SHELL32!CISFBand::_TrySimpleInvoke. 24 */ 25 EXTERN_C 26 BOOL WINAPI 27 IContextMenu_Invoke( 28 _In_ IContextMenu *pContextMenu, 29 _In_ HWND hwnd, 30 _In_ LPCSTR lpVerb, 31 _In_ UINT uFlags) 32 { 33 CMINVOKECOMMANDINFO info; 34 BOOL ret = FALSE; 35 INT iDefItem = 0; 36 HMENU hMenu = NULL; 37 HCURSOR hOldCursor; 38 39 TRACE("(%p, %p, %s, %u)\n", pContextMenu, hwnd, debugstr_a(lpVerb), uFlags); 40 41 if (!pContextMenu) 42 return FALSE; 43 44 hOldCursor = SetCursor(LoadCursorW(NULL, (LPCWSTR)IDC_WAIT)); 45 46 ZeroMemory(&info, sizeof(info)); 47 info.cbSize = sizeof(info); 48 info.hwnd = hwnd; 49 info.nShow = SW_NORMAL; 50 info.lpVerb = lpVerb; 51 52 if (IS_INTRESOURCE(lpVerb)) 53 { 54 hMenu = CreatePopupMenu(); 55 if (hMenu) 56 { 57 pContextMenu->QueryContextMenu(hMenu, 0, 1, MAXSHORT, uFlags | CMF_DEFAULTONLY); 58 iDefItem = GetMenuDefaultItem(hMenu, 0, 0); 59 if (iDefItem != -1) 60 info.lpVerb = MAKEINTRESOURCEA(iDefItem - 1); 61 } 62 } 63 64 if (iDefItem != -1 || info.lpVerb) 65 { 66 if (!hwnd) 67 info.fMask |= CMIC_MASK_FLAG_NO_UI; 68 ret = SUCCEEDED(pContextMenu->InvokeCommand(&info)); 69 } 70 71 /* Invoking itself doesn't need the menu object, but getting the command info 72 needs the menu. */ 73 if (hMenu) 74 DestroyMenu(hMenu); 75 76 SetCursor(hOldCursor); 77 78 return ret; 79 } 80 81 /************************************************************************* 82 * PathFileExistsDefExtAndAttributesW [SHLWAPI.511] 83 * 84 * @param pszPath The path string. 85 * @param dwWhich The WHICH_... flags. 86 * @param pdwFileAttributes A pointer to the file attributes. Optional. 87 * @return TRUE if successful. 88 */ 89 BOOL WINAPI 90 PathFileExistsDefExtAndAttributesW( 91 _Inout_ LPWSTR pszPath, 92 _In_ DWORD dwWhich, 93 _Out_opt_ LPDWORD pdwFileAttributes) 94 { 95 TRACE("(%s, 0x%lX, %p)\n", debugstr_w(pszPath), dwWhich, pdwFileAttributes); 96 97 if (pdwFileAttributes) 98 *pdwFileAttributes = INVALID_FILE_ATTRIBUTES; 99 100 if (!pszPath) 101 return FALSE; 102 103 if (!dwWhich || (*PathFindExtensionW(pszPath) && (dwWhich & WHICH_OPTIONAL))) 104 return PathFileExistsAndAttributesW(pszPath, pdwFileAttributes); 105 106 if (!PathFileExistsDefExtW(pszPath, dwWhich)) 107 { 108 if (pdwFileAttributes) 109 *pdwFileAttributes = INVALID_FILE_ATTRIBUTES; 110 return FALSE; 111 } 112 113 if (pdwFileAttributes) 114 *pdwFileAttributes = GetFileAttributesW(pszPath); 115 116 return TRUE; 117 } 118