1 /* 2 * PROJECT: ReactOS CabView Shell Extension 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: Utility header file 5 * COPYRIGHT: Copyright 2024 Whindmar Saksit <whindsaks@proton.me> 6 */ 7 8 #pragma once 9 10 template<class H> static int ErrorBox(H hWnd, int Error) 11 { 12 SHELL_ErrorBox(hWnd, Error); 13 return Error; 14 } 15 16 template<class T> static inline bool IsPathSep(T c) 17 { 18 return c == '\\' || c == '/'; 19 } 20 21 inline bool IsEqual(const SHCOLUMNID &scid, REFGUID guid, UINT pid) 22 { 23 return scid.pid == pid && IsEqualGUID(scid.fmtid, guid); 24 } 25 26 inline HRESULT InitVariantFromBuffer(const void *buffer, UINT cb, VARIANT *pv) 27 { 28 SAFEARRAY *pa = SafeArrayCreateVector(VT_UI1, 0, cb); 29 if (pa) 30 { 31 CopyMemory(pa->pvData, buffer, cb); 32 V_VT(pv) = VT_UI1 | VT_ARRAY; 33 V_UNION(pv, parray) = pa; 34 return S_OK; 35 } 36 V_VT(pv) = VT_EMPTY; 37 return E_OUTOFMEMORY; 38 } 39 40 inline void FreeStrRet(STRRET &str) 41 { 42 if (str.uType == STRRET_WSTR) 43 { 44 SHFree(str.pOleStr); 45 str.uType = STRRET_CSTR; 46 } 47 } 48 49 inline HRESULT StrTo(LPCWSTR str, UINT len, STRRET &sr) 50 { 51 LPWSTR data = (LPWSTR)SHAlloc(++len * sizeof(WCHAR)); 52 if (!data) 53 return E_OUTOFMEMORY; 54 lstrcpynW(data, str, len); 55 sr.uType = STRRET_WSTR; 56 sr.pOleStr = data; 57 return S_OK; 58 } 59 60 inline HRESULT StrTo(LPCWSTR str, STRRET &sr) 61 { 62 return StrTo(str, lstrlenW(str), sr); 63 } 64 65 inline HRESULT StrTo(LPCWSTR str, UINT len, VARIANT &v) 66 { 67 BSTR data = SysAllocStringLen(str, len); 68 if (!data) 69 return E_OUTOFMEMORY; 70 V_VT(&v) = VT_BSTR; 71 V_BSTR(&v) = data; 72 return S_OK; 73 } 74 75 inline HRESULT StrTo(LPCWSTR str, VARIANT &v) 76 { 77 return StrTo(str, lstrlenW(str), v); 78 } 79 80 inline HRESULT StrRetToVariantBSTR(STRRET *psr, VARIANT &v) 81 { 82 HRESULT hr = StrRetToBSTR(psr, NULL, &V_BSTR(&v)); 83 if (SUCCEEDED(hr)) 84 V_VT(&v) = VT_BSTR; 85 return hr; 86 } 87 88 inline HRESULT GetDetailsOf(IShellFolder2 &Folder, PCUITEMID_CHILD pidl, UINT Column, PWSTR &String) 89 { 90 SHELLDETAILS details; 91 HRESULT hr = Folder.GetDetailsOf(pidl, Column, &details); 92 if (SUCCEEDED(hr)) 93 hr = StrRetToStrW(&details.str, pidl, &String); 94 return hr; 95 } 96 97 inline HRESULT InsertMenuItem(QCMINFO &qcmi, UINT &Pos, UINT &TrackId, UINT Id, UINT ResId, int State = 0) 98 { 99 UINT flags = 0; 100 WCHAR string[MAX_PATH]; 101 string[0] = UNICODE_NULL; 102 if ((Id += qcmi.idCmdFirst) > qcmi.idCmdLast) 103 return E_FAIL; 104 else if (ResId == (UINT)-1) 105 flags |= MF_SEPARATOR; 106 else if (!LoadStringW(_AtlBaseModule.GetResourceInstance(), ResId, string, _countof(string))) 107 return E_FAIL; 108 109 MENUITEMINFOW mii; 110 mii.cbSize = FIELD_OFFSET(MENUITEMINFOW, hbmpItem); // USER32 version agnostic 111 mii.fMask = MIIM_FTYPE | MIIM_ID | MIIM_STRING | MIIM_STATE; 112 mii.fType = flags; 113 mii.wID = Id; 114 mii.dwTypeData = string; 115 mii.cch = 0; 116 mii.fState = State; 117 if (!InsertMenuItemW(qcmi.hmenu, Pos, TRUE, &mii)) 118 return E_FAIL; 119 Pos++; 120 TrackId = max(TrackId, Id); 121 return S_OK; 122 } 123 124 inline SFGAOF MapFSToSFAttributes(UINT att) 125 { 126 return ((att & FILE_ATTRIBUTE_READONLY) ? SFGAO_READONLY : 0) | 127 ((att & FILE_ATTRIBUTE_HIDDEN) ? SFGAO_HIDDEN : 0) | 128 ((att & FILE_ATTRIBUTE_SYSTEM) ? SFGAO_SYSTEM : 0); 129 } 130 131 inline bool IncludeInEnumIDList(SHCONTF contf, SFGAOF att) 132 { 133 const SHCONTF both = SHCONTF_FOLDERS | SHCONTF_NONFOLDERS; 134 const SFGAOF superbits = SFGAO_HIDDEN | SFGAO_READONLY | SFGAO_SYSTEM; 135 const bool isfile = (att & (SFGAO_STREAM | SFGAO_FOLDER)) != SFGAO_FOLDER; 136 if ((contf & both) != both && !(contf & SHCONTF_STORAGE)) 137 { 138 if (isfile && (contf & SHCONTF_FOLDERS)) 139 return false; 140 if ((att & SFGAO_FOLDER) && (contf & SHCONTF_NONFOLDERS)) 141 return false; 142 } 143 if ((att & SFGAO_HIDDEN) && !(contf & (SHCONTF_INCLUDEHIDDEN | SHCONTF_STORAGE))) 144 return false; 145 if ((att & superbits) > SFGAO_HIDDEN && !(contf & (SHCONTF_INCLUDESUPERHIDDEN | SHCONTF_STORAGE))) 146 return false; 147 return true; 148 } 149 150 inline int MapPIDLToSystemImageListIndex(IShellFolder *pSF, PCUITEMID_CHILD pidl, UINT GilFlags = 0) 151 { 152 int normal, open; 153 BOOL qopen = GilFlags & GIL_OPENICON; 154 normal = SHMapPIDLToSystemImageListIndex(pSF, pidl, qopen ? &open : NULL); 155 return qopen && open != -1 ? open : normal; 156 } 157