1*f6dc9357SAndroid Build Coastguard Worker // SysIconUtils.cpp
2*f6dc9357SAndroid Build Coastguard Worker
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker
5*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
6*f6dc9357SAndroid Build Coastguard Worker #include "../../../Common/StringConvert.h"
7*f6dc9357SAndroid Build Coastguard Worker #endif
8*f6dc9357SAndroid Build Coastguard Worker
9*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileDir.h"
10*f6dc9357SAndroid Build Coastguard Worker
11*f6dc9357SAndroid Build Coastguard Worker #include "SysIconUtils.h"
12*f6dc9357SAndroid Build Coastguard Worker
13*f6dc9357SAndroid Build Coastguard Worker #if defined(__MINGW32__) || defined(__MINGW64__)
14*f6dc9357SAndroid Build Coastguard Worker #include <shlobj.h>
15*f6dc9357SAndroid Build Coastguard Worker #else
16*f6dc9357SAndroid Build Coastguard Worker #include <ShlObj.h>
17*f6dc9357SAndroid Build Coastguard Worker #endif
18*f6dc9357SAndroid Build Coastguard Worker
19*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
20*f6dc9357SAndroid Build Coastguard Worker extern bool g_IsNT;
21*f6dc9357SAndroid Build Coastguard Worker #endif
22*f6dc9357SAndroid Build Coastguard Worker
23*f6dc9357SAndroid Build Coastguard Worker CExtToIconMap g_Ext_to_Icon_Map;
24*f6dc9357SAndroid Build Coastguard Worker
Shell_GetFileInfo_SysIconIndex_for_CSIDL(int csidl)25*f6dc9357SAndroid Build Coastguard Worker int Shell_GetFileInfo_SysIconIndex_for_CSIDL(int csidl)
26*f6dc9357SAndroid Build Coastguard Worker {
27*f6dc9357SAndroid Build Coastguard Worker LPITEMIDLIST pidl = NULL;
28*f6dc9357SAndroid Build Coastguard Worker SHGetSpecialFolderLocation(NULL, csidl, &pidl);
29*f6dc9357SAndroid Build Coastguard Worker if (pidl)
30*f6dc9357SAndroid Build Coastguard Worker {
31*f6dc9357SAndroid Build Coastguard Worker SHFILEINFO shFileInfo;
32*f6dc9357SAndroid Build Coastguard Worker shFileInfo.iIcon = -1;
33*f6dc9357SAndroid Build Coastguard Worker const DWORD_PTR res = SHGetFileInfo((LPCTSTR)(const void *)(pidl),
34*f6dc9357SAndroid Build Coastguard Worker FILE_ATTRIBUTE_DIRECTORY,
35*f6dc9357SAndroid Build Coastguard Worker &shFileInfo, sizeof(shFileInfo),
36*f6dc9357SAndroid Build Coastguard Worker SHGFI_PIDL | SHGFI_SYSICONINDEX);
37*f6dc9357SAndroid Build Coastguard Worker /*
38*f6dc9357SAndroid Build Coastguard Worker IMalloc *pMalloc;
39*f6dc9357SAndroid Build Coastguard Worker SHGetMalloc(&pMalloc);
40*f6dc9357SAndroid Build Coastguard Worker if (pMalloc)
41*f6dc9357SAndroid Build Coastguard Worker {
42*f6dc9357SAndroid Build Coastguard Worker pMalloc->Free(pidl);
43*f6dc9357SAndroid Build Coastguard Worker pMalloc->Release();
44*f6dc9357SAndroid Build Coastguard Worker }
45*f6dc9357SAndroid Build Coastguard Worker */
46*f6dc9357SAndroid Build Coastguard Worker // we use OLE2.dll function here
47*f6dc9357SAndroid Build Coastguard Worker CoTaskMemFree(pidl);
48*f6dc9357SAndroid Build Coastguard Worker if (res)
49*f6dc9357SAndroid Build Coastguard Worker return shFileInfo.iIcon;
50*f6dc9357SAndroid Build Coastguard Worker }
51*f6dc9357SAndroid Build Coastguard Worker return -1;
52*f6dc9357SAndroid Build Coastguard Worker }
53*f6dc9357SAndroid Build Coastguard Worker
54*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
55*f6dc9357SAndroid Build Coastguard Worker Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION
56*f6dc9357SAndroid Build Coastguard Worker typedef DWORD_PTR (WINAPI * Func_SHGetFileInfoW)(LPCWSTR pszPath, DWORD attrib, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags);
57*f6dc9357SAndroid Build Coastguard Worker
58*f6dc9357SAndroid Build Coastguard Worker static struct C_SHGetFileInfo_Init
59*f6dc9357SAndroid Build Coastguard Worker {
60*f6dc9357SAndroid Build Coastguard Worker Func_SHGetFileInfoW f_SHGetFileInfoW;
C_SHGetFileInfo_InitC_SHGetFileInfo_Init61*f6dc9357SAndroid Build Coastguard Worker C_SHGetFileInfo_Init()
62*f6dc9357SAndroid Build Coastguard Worker {
63*f6dc9357SAndroid Build Coastguard Worker f_SHGetFileInfoW = Z7_GET_PROC_ADDRESS(
64*f6dc9357SAndroid Build Coastguard Worker Func_SHGetFileInfoW, ::GetModuleHandleW(L"shell32.dll"),
65*f6dc9357SAndroid Build Coastguard Worker "SHGetFileInfoW");
66*f6dc9357SAndroid Build Coastguard Worker // f_SHGetFileInfoW = NULL; // for debug
67*f6dc9357SAndroid Build Coastguard Worker }
68*f6dc9357SAndroid Build Coastguard Worker } g_SHGetFileInfo_Init;
69*f6dc9357SAndroid Build Coastguard Worker #endif
70*f6dc9357SAndroid Build Coastguard Worker
71*f6dc9357SAndroid Build Coastguard Worker #ifdef _UNICODE
72*f6dc9357SAndroid Build Coastguard Worker #define My_SHGetFileInfoW SHGetFileInfoW
73*f6dc9357SAndroid Build Coastguard Worker #else
My_SHGetFileInfoW(LPCWSTR pszPath,DWORD attrib,SHFILEINFOW * psfi,UINT cbFileInfo,UINT uFlags)74*f6dc9357SAndroid Build Coastguard Worker static DWORD_PTR My_SHGetFileInfoW(LPCWSTR pszPath, DWORD attrib, SHFILEINFOW *psfi, UINT cbFileInfo, UINT uFlags)
75*f6dc9357SAndroid Build Coastguard Worker {
76*f6dc9357SAndroid Build Coastguard Worker if (!g_SHGetFileInfo_Init.f_SHGetFileInfoW)
77*f6dc9357SAndroid Build Coastguard Worker return 0;
78*f6dc9357SAndroid Build Coastguard Worker return g_SHGetFileInfo_Init.f_SHGetFileInfoW(pszPath, attrib, psfi, cbFileInfo, uFlags);
79*f6dc9357SAndroid Build Coastguard Worker }
80*f6dc9357SAndroid Build Coastguard Worker #endif
81*f6dc9357SAndroid Build Coastguard Worker
Shell_GetFileInfo_SysIconIndex_for_Path_attrib_iconIndexRef(CFSTR path,DWORD attrib,int & iconIndex)82*f6dc9357SAndroid Build Coastguard Worker DWORD_PTR Shell_GetFileInfo_SysIconIndex_for_Path_attrib_iconIndexRef(
83*f6dc9357SAndroid Build Coastguard Worker CFSTR path, DWORD attrib, int &iconIndex)
84*f6dc9357SAndroid Build Coastguard Worker {
85*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
86*f6dc9357SAndroid Build Coastguard Worker if (!g_IsNT || !g_SHGetFileInfo_Init.f_SHGetFileInfoW)
87*f6dc9357SAndroid Build Coastguard Worker {
88*f6dc9357SAndroid Build Coastguard Worker SHFILEINFO shFileInfo;
89*f6dc9357SAndroid Build Coastguard Worker // ZeroMemory(&shFileInfo, sizeof(shFileInfo));
90*f6dc9357SAndroid Build Coastguard Worker shFileInfo.iIcon = -1; // optional
91*f6dc9357SAndroid Build Coastguard Worker const DWORD_PTR res = ::SHGetFileInfo(fs2fas(path),
92*f6dc9357SAndroid Build Coastguard Worker attrib ? attrib : FILE_ATTRIBUTE_ARCHIVE,
93*f6dc9357SAndroid Build Coastguard Worker &shFileInfo, sizeof(shFileInfo),
94*f6dc9357SAndroid Build Coastguard Worker SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX);
95*f6dc9357SAndroid Build Coastguard Worker iconIndex = shFileInfo.iIcon;
96*f6dc9357SAndroid Build Coastguard Worker return res;
97*f6dc9357SAndroid Build Coastguard Worker }
98*f6dc9357SAndroid Build Coastguard Worker else
99*f6dc9357SAndroid Build Coastguard Worker #endif
100*f6dc9357SAndroid Build Coastguard Worker {
101*f6dc9357SAndroid Build Coastguard Worker SHFILEINFOW shFileInfo;
102*f6dc9357SAndroid Build Coastguard Worker // ZeroMemory(&shFileInfo, sizeof(shFileInfo));
103*f6dc9357SAndroid Build Coastguard Worker shFileInfo.iIcon = -1; // optional
104*f6dc9357SAndroid Build Coastguard Worker const DWORD_PTR res = ::My_SHGetFileInfoW(fs2us(path),
105*f6dc9357SAndroid Build Coastguard Worker attrib ? attrib : FILE_ATTRIBUTE_ARCHIVE,
106*f6dc9357SAndroid Build Coastguard Worker &shFileInfo, sizeof(shFileInfo),
107*f6dc9357SAndroid Build Coastguard Worker SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX);
108*f6dc9357SAndroid Build Coastguard Worker // (shFileInfo.iIcon == 0) returned for unknown extensions and files without extension
109*f6dc9357SAndroid Build Coastguard Worker iconIndex = shFileInfo.iIcon;
110*f6dc9357SAndroid Build Coastguard Worker // we use SHGFI_USEFILEATTRIBUTES, and
111*f6dc9357SAndroid Build Coastguard Worker // (res != 0) is expected for main cases, even if there are no such file.
112*f6dc9357SAndroid Build Coastguard Worker // (res == 0) for path with kSuperPrefix "\\?\"
113*f6dc9357SAndroid Build Coastguard Worker // Also SHGFI_USEFILEATTRIBUTES still returns icon inside exe.
114*f6dc9357SAndroid Build Coastguard Worker // So we can use SHGFI_USEFILEATTRIBUTES for any case.
115*f6dc9357SAndroid Build Coastguard Worker // UString temp = fs2us(path); // for debug
116*f6dc9357SAndroid Build Coastguard Worker // UString tempName = temp.Ptr(temp.ReverseFind_PathSepar() + 1); // for debug
117*f6dc9357SAndroid Build Coastguard Worker // iconIndex = -1; // for debug
118*f6dc9357SAndroid Build Coastguard Worker return res;
119*f6dc9357SAndroid Build Coastguard Worker }
120*f6dc9357SAndroid Build Coastguard Worker }
121*f6dc9357SAndroid Build Coastguard Worker
Shell_GetFileInfo_SysIconIndex_for_Path(CFSTR path,DWORD attrib)122*f6dc9357SAndroid Build Coastguard Worker int Shell_GetFileInfo_SysIconIndex_for_Path(CFSTR path, DWORD attrib)
123*f6dc9357SAndroid Build Coastguard Worker {
124*f6dc9357SAndroid Build Coastguard Worker int iconIndex = -1;
125*f6dc9357SAndroid Build Coastguard Worker if (!Shell_GetFileInfo_SysIconIndex_for_Path_attrib_iconIndexRef(
126*f6dc9357SAndroid Build Coastguard Worker path, attrib, iconIndex))
127*f6dc9357SAndroid Build Coastguard Worker iconIndex = -1;
128*f6dc9357SAndroid Build Coastguard Worker return iconIndex;
129*f6dc9357SAndroid Build Coastguard Worker }
130*f6dc9357SAndroid Build Coastguard Worker
131*f6dc9357SAndroid Build Coastguard Worker
Shell_GetFileInfo_SysIconIndex_for_Path_return_HRESULT(CFSTR path,DWORD attrib,Int32 * iconIndex)132*f6dc9357SAndroid Build Coastguard Worker HRESULT Shell_GetFileInfo_SysIconIndex_for_Path_return_HRESULT(
133*f6dc9357SAndroid Build Coastguard Worker CFSTR path, DWORD attrib, Int32 *iconIndex)
134*f6dc9357SAndroid Build Coastguard Worker {
135*f6dc9357SAndroid Build Coastguard Worker *iconIndex = -1;
136*f6dc9357SAndroid Build Coastguard Worker int iconIndexTemp;
137*f6dc9357SAndroid Build Coastguard Worker if (Shell_GetFileInfo_SysIconIndex_for_Path_attrib_iconIndexRef(
138*f6dc9357SAndroid Build Coastguard Worker path, attrib, iconIndexTemp))
139*f6dc9357SAndroid Build Coastguard Worker {
140*f6dc9357SAndroid Build Coastguard Worker *iconIndex = iconIndexTemp;
141*f6dc9357SAndroid Build Coastguard Worker return S_OK;
142*f6dc9357SAndroid Build Coastguard Worker }
143*f6dc9357SAndroid Build Coastguard Worker return GetLastError_noZero_HRESULT();
144*f6dc9357SAndroid Build Coastguard Worker }
145*f6dc9357SAndroid Build Coastguard Worker
146*f6dc9357SAndroid Build Coastguard Worker /*
147*f6dc9357SAndroid Build Coastguard Worker DWORD_PTR Shell_GetFileInfo_SysIconIndex_for_Path(const UString &fileName, DWORD attrib, int &iconIndex, UString *typeName)
148*f6dc9357SAndroid Build Coastguard Worker {
149*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
150*f6dc9357SAndroid Build Coastguard Worker if (!g_IsNT)
151*f6dc9357SAndroid Build Coastguard Worker {
152*f6dc9357SAndroid Build Coastguard Worker SHFILEINFO shFileInfo;
153*f6dc9357SAndroid Build Coastguard Worker shFileInfo.szTypeName[0] = 0;
154*f6dc9357SAndroid Build Coastguard Worker DWORD_PTR res = ::SHGetFileInfoA(GetSystemString(fileName), FILE_ATTRIBUTE_ARCHIVE | attrib, &shFileInfo,
155*f6dc9357SAndroid Build Coastguard Worker sizeof(shFileInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_TYPENAME);
156*f6dc9357SAndroid Build Coastguard Worker if (typeName)
157*f6dc9357SAndroid Build Coastguard Worker *typeName = GetUnicodeString(shFileInfo.szTypeName);
158*f6dc9357SAndroid Build Coastguard Worker iconIndex = shFileInfo.iIcon;
159*f6dc9357SAndroid Build Coastguard Worker return res;
160*f6dc9357SAndroid Build Coastguard Worker }
161*f6dc9357SAndroid Build Coastguard Worker else
162*f6dc9357SAndroid Build Coastguard Worker #endif
163*f6dc9357SAndroid Build Coastguard Worker {
164*f6dc9357SAndroid Build Coastguard Worker SHFILEINFOW shFileInfo;
165*f6dc9357SAndroid Build Coastguard Worker shFileInfo.szTypeName[0] = 0;
166*f6dc9357SAndroid Build Coastguard Worker DWORD_PTR res = ::My_SHGetFileInfoW(fileName, FILE_ATTRIBUTE_ARCHIVE | attrib, &shFileInfo,
167*f6dc9357SAndroid Build Coastguard Worker sizeof(shFileInfo), SHGFI_USEFILEATTRIBUTES | SHGFI_SYSICONINDEX | SHGFI_TYPENAME);
168*f6dc9357SAndroid Build Coastguard Worker if (typeName)
169*f6dc9357SAndroid Build Coastguard Worker *typeName = shFileInfo.szTypeName;
170*f6dc9357SAndroid Build Coastguard Worker iconIndex = shFileInfo.iIcon;
171*f6dc9357SAndroid Build Coastguard Worker return res;
172*f6dc9357SAndroid Build Coastguard Worker }
173*f6dc9357SAndroid Build Coastguard Worker }
174*f6dc9357SAndroid Build Coastguard Worker */
175*f6dc9357SAndroid Build Coastguard Worker
FindInSorted_Attrib(const CRecordVector<CAttribIconPair> & vect,DWORD attrib,unsigned & insertPos)176*f6dc9357SAndroid Build Coastguard Worker static int FindInSorted_Attrib(const CRecordVector<CAttribIconPair> &vect, DWORD attrib, unsigned &insertPos)
177*f6dc9357SAndroid Build Coastguard Worker {
178*f6dc9357SAndroid Build Coastguard Worker unsigned left = 0, right = vect.Size();
179*f6dc9357SAndroid Build Coastguard Worker while (left != right)
180*f6dc9357SAndroid Build Coastguard Worker {
181*f6dc9357SAndroid Build Coastguard Worker const unsigned mid = (left + right) / 2;
182*f6dc9357SAndroid Build Coastguard Worker const DWORD midAttrib = vect[mid].Attrib;
183*f6dc9357SAndroid Build Coastguard Worker if (attrib == midAttrib)
184*f6dc9357SAndroid Build Coastguard Worker return (int)mid;
185*f6dc9357SAndroid Build Coastguard Worker if (attrib < midAttrib)
186*f6dc9357SAndroid Build Coastguard Worker right = mid;
187*f6dc9357SAndroid Build Coastguard Worker else
188*f6dc9357SAndroid Build Coastguard Worker left = mid + 1;
189*f6dc9357SAndroid Build Coastguard Worker }
190*f6dc9357SAndroid Build Coastguard Worker insertPos = left;
191*f6dc9357SAndroid Build Coastguard Worker return -1;
192*f6dc9357SAndroid Build Coastguard Worker }
193*f6dc9357SAndroid Build Coastguard Worker
FindInSorted_Ext(const CObjectVector<CExtIconPair> & vect,const wchar_t * ext,unsigned & insertPos)194*f6dc9357SAndroid Build Coastguard Worker static int FindInSorted_Ext(const CObjectVector<CExtIconPair> &vect, const wchar_t *ext, unsigned &insertPos)
195*f6dc9357SAndroid Build Coastguard Worker {
196*f6dc9357SAndroid Build Coastguard Worker unsigned left = 0, right = vect.Size();
197*f6dc9357SAndroid Build Coastguard Worker while (left != right)
198*f6dc9357SAndroid Build Coastguard Worker {
199*f6dc9357SAndroid Build Coastguard Worker const unsigned mid = (left + right) / 2;
200*f6dc9357SAndroid Build Coastguard Worker const int compare = MyStringCompareNoCase(ext, vect[mid].Ext);
201*f6dc9357SAndroid Build Coastguard Worker if (compare == 0)
202*f6dc9357SAndroid Build Coastguard Worker return (int)mid;
203*f6dc9357SAndroid Build Coastguard Worker if (compare < 0)
204*f6dc9357SAndroid Build Coastguard Worker right = mid;
205*f6dc9357SAndroid Build Coastguard Worker else
206*f6dc9357SAndroid Build Coastguard Worker left = mid + 1;
207*f6dc9357SAndroid Build Coastguard Worker }
208*f6dc9357SAndroid Build Coastguard Worker insertPos = left;
209*f6dc9357SAndroid Build Coastguard Worker return -1;
210*f6dc9357SAndroid Build Coastguard Worker }
211*f6dc9357SAndroid Build Coastguard Worker
212*f6dc9357SAndroid Build Coastguard Worker
213*f6dc9357SAndroid Build Coastguard Worker // bool DoItemAlwaysStart(const UString &name);
214*f6dc9357SAndroid Build Coastguard Worker
GetIconIndex(DWORD attrib,const wchar_t * fileName)215*f6dc9357SAndroid Build Coastguard Worker int CExtToIconMap::GetIconIndex(DWORD attrib, const wchar_t *fileName /*, UString *typeName */)
216*f6dc9357SAndroid Build Coastguard Worker {
217*f6dc9357SAndroid Build Coastguard Worker int dotPos = -1;
218*f6dc9357SAndroid Build Coastguard Worker unsigned i;
219*f6dc9357SAndroid Build Coastguard Worker for (i = 0;; i++)
220*f6dc9357SAndroid Build Coastguard Worker {
221*f6dc9357SAndroid Build Coastguard Worker const wchar_t c = fileName[i];
222*f6dc9357SAndroid Build Coastguard Worker if (c == 0)
223*f6dc9357SAndroid Build Coastguard Worker break;
224*f6dc9357SAndroid Build Coastguard Worker if (c == '.')
225*f6dc9357SAndroid Build Coastguard Worker dotPos = (int)i;
226*f6dc9357SAndroid Build Coastguard Worker // we don't need IS_PATH_SEPAR check, because (fileName) doesn't include path prefix.
227*f6dc9357SAndroid Build Coastguard Worker // if (IS_PATH_SEPAR(c) || c == ':') dotPos = -1;
228*f6dc9357SAndroid Build Coastguard Worker }
229*f6dc9357SAndroid Build Coastguard Worker
230*f6dc9357SAndroid Build Coastguard Worker /*
231*f6dc9357SAndroid Build Coastguard Worker if (MyStringCompareNoCase(fileName, L"$Recycle.Bin") == 0)
232*f6dc9357SAndroid Build Coastguard Worker {
233*f6dc9357SAndroid Build Coastguard Worker char s[256];
234*f6dc9357SAndroid Build Coastguard Worker sprintf(s, "SPEC i = %3d, attr = %7x", _attribMap.Size(), attrib);
235*f6dc9357SAndroid Build Coastguard Worker OutputDebugStringA(s);
236*f6dc9357SAndroid Build Coastguard Worker OutputDebugStringW(fileName);
237*f6dc9357SAndroid Build Coastguard Worker }
238*f6dc9357SAndroid Build Coastguard Worker */
239*f6dc9357SAndroid Build Coastguard Worker
240*f6dc9357SAndroid Build Coastguard Worker if ((attrib & FILE_ATTRIBUTE_DIRECTORY) || dotPos < 0)
241*f6dc9357SAndroid Build Coastguard Worker for (unsigned k = 0;; k++)
242*f6dc9357SAndroid Build Coastguard Worker {
243*f6dc9357SAndroid Build Coastguard Worker if (k >= 2)
244*f6dc9357SAndroid Build Coastguard Worker return -1;
245*f6dc9357SAndroid Build Coastguard Worker unsigned insertPos = 0;
246*f6dc9357SAndroid Build Coastguard Worker const int index = FindInSorted_Attrib(_attribMap, attrib, insertPos);
247*f6dc9357SAndroid Build Coastguard Worker if (index >= 0)
248*f6dc9357SAndroid Build Coastguard Worker {
249*f6dc9357SAndroid Build Coastguard Worker // if (typeName) *typeName = _attribMap[index].TypeName;
250*f6dc9357SAndroid Build Coastguard Worker return _attribMap[(unsigned)index].IconIndex;
251*f6dc9357SAndroid Build Coastguard Worker }
252*f6dc9357SAndroid Build Coastguard Worker CAttribIconPair pair;
253*f6dc9357SAndroid Build Coastguard Worker pair.IconIndex = Shell_GetFileInfo_SysIconIndex_for_Path(
254*f6dc9357SAndroid Build Coastguard Worker #ifdef UNDER_CE
255*f6dc9357SAndroid Build Coastguard Worker FTEXT("\\")
256*f6dc9357SAndroid Build Coastguard Worker #endif
257*f6dc9357SAndroid Build Coastguard Worker FTEXT("__DIR__")
258*f6dc9357SAndroid Build Coastguard Worker , attrib
259*f6dc9357SAndroid Build Coastguard Worker // , pair.TypeName
260*f6dc9357SAndroid Build Coastguard Worker );
261*f6dc9357SAndroid Build Coastguard Worker if (_attribMap.Size() < (1u << 16) // we limit cache size
262*f6dc9357SAndroid Build Coastguard Worker || attrib < (1u << 15)) // we want to put all items with basic attribs to cache
263*f6dc9357SAndroid Build Coastguard Worker {
264*f6dc9357SAndroid Build Coastguard Worker /*
265*f6dc9357SAndroid Build Coastguard Worker char s[256];
266*f6dc9357SAndroid Build Coastguard Worker sprintf(s, "i = %3d, attr = %7x", _attribMap.Size(), attrib);
267*f6dc9357SAndroid Build Coastguard Worker OutputDebugStringA(s);
268*f6dc9357SAndroid Build Coastguard Worker */
269*f6dc9357SAndroid Build Coastguard Worker pair.Attrib = attrib;
270*f6dc9357SAndroid Build Coastguard Worker _attribMap.Insert(insertPos, pair);
271*f6dc9357SAndroid Build Coastguard Worker // if (typeName) *typeName = pair.TypeName;
272*f6dc9357SAndroid Build Coastguard Worker return pair.IconIndex;
273*f6dc9357SAndroid Build Coastguard Worker }
274*f6dc9357SAndroid Build Coastguard Worker if (pair.IconIndex >= 0)
275*f6dc9357SAndroid Build Coastguard Worker return pair.IconIndex;
276*f6dc9357SAndroid Build Coastguard Worker attrib = (attrib & FILE_ATTRIBUTE_DIRECTORY) ?
277*f6dc9357SAndroid Build Coastguard Worker FILE_ATTRIBUTE_DIRECTORY :
278*f6dc9357SAndroid Build Coastguard Worker FILE_ATTRIBUTE_ARCHIVE;
279*f6dc9357SAndroid Build Coastguard Worker }
280*f6dc9357SAndroid Build Coastguard Worker
281*f6dc9357SAndroid Build Coastguard Worker CObjectVector<CExtIconPair> &map =
282*f6dc9357SAndroid Build Coastguard Worker (attrib & FILE_ATTRIBUTE_COMPRESSED) ?
283*f6dc9357SAndroid Build Coastguard Worker _extMap_Compressed : _extMap_Normal;
284*f6dc9357SAndroid Build Coastguard Worker const wchar_t *ext = fileName + dotPos + 1;
285*f6dc9357SAndroid Build Coastguard Worker unsigned insertPos = 0;
286*f6dc9357SAndroid Build Coastguard Worker const int index = FindInSorted_Ext(map, ext, insertPos);
287*f6dc9357SAndroid Build Coastguard Worker if (index >= 0)
288*f6dc9357SAndroid Build Coastguard Worker {
289*f6dc9357SAndroid Build Coastguard Worker const CExtIconPair &pa = map[index];
290*f6dc9357SAndroid Build Coastguard Worker // if (typeName) *typeName = pa.TypeName;
291*f6dc9357SAndroid Build Coastguard Worker return pa.IconIndex;
292*f6dc9357SAndroid Build Coastguard Worker }
293*f6dc9357SAndroid Build Coastguard Worker
294*f6dc9357SAndroid Build Coastguard Worker for (i = 0;; i++)
295*f6dc9357SAndroid Build Coastguard Worker {
296*f6dc9357SAndroid Build Coastguard Worker const wchar_t c = ext[i];
297*f6dc9357SAndroid Build Coastguard Worker if (c == 0)
298*f6dc9357SAndroid Build Coastguard Worker break;
299*f6dc9357SAndroid Build Coastguard Worker if (c < L'0' || c > L'9')
300*f6dc9357SAndroid Build Coastguard Worker break;
301*f6dc9357SAndroid Build Coastguard Worker }
302*f6dc9357SAndroid Build Coastguard Worker if (i != 0 && ext[i] == 0)
303*f6dc9357SAndroid Build Coastguard Worker {
304*f6dc9357SAndroid Build Coastguard Worker // Shell_GetFileInfo_SysIconIndex_for_Path is too slow for big number of split extensions: .001, .002, .003
305*f6dc9357SAndroid Build Coastguard Worker if (!SplitIconIndex_Defined)
306*f6dc9357SAndroid Build Coastguard Worker {
307*f6dc9357SAndroid Build Coastguard Worker Shell_GetFileInfo_SysIconIndex_for_Path_attrib_iconIndexRef(
308*f6dc9357SAndroid Build Coastguard Worker #ifdef UNDER_CE
309*f6dc9357SAndroid Build Coastguard Worker FTEXT("\\")
310*f6dc9357SAndroid Build Coastguard Worker #endif
311*f6dc9357SAndroid Build Coastguard Worker FTEXT("__FILE__.001"), FILE_ATTRIBUTE_ARCHIVE, SplitIconIndex);
312*f6dc9357SAndroid Build Coastguard Worker SplitIconIndex_Defined = true;
313*f6dc9357SAndroid Build Coastguard Worker }
314*f6dc9357SAndroid Build Coastguard Worker return SplitIconIndex;
315*f6dc9357SAndroid Build Coastguard Worker }
316*f6dc9357SAndroid Build Coastguard Worker
317*f6dc9357SAndroid Build Coastguard Worker CExtIconPair pair;
318*f6dc9357SAndroid Build Coastguard Worker pair.Ext = ext;
319*f6dc9357SAndroid Build Coastguard Worker pair.IconIndex = Shell_GetFileInfo_SysIconIndex_for_Path(
320*f6dc9357SAndroid Build Coastguard Worker us2fs(fileName + dotPos),
321*f6dc9357SAndroid Build Coastguard Worker attrib & FILE_ATTRIBUTE_COMPRESSED ?
322*f6dc9357SAndroid Build Coastguard Worker FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_COMPRESSED:
323*f6dc9357SAndroid Build Coastguard Worker FILE_ATTRIBUTE_ARCHIVE);
324*f6dc9357SAndroid Build Coastguard Worker if (map.Size() < (1u << 16) // we limit cache size
325*f6dc9357SAndroid Build Coastguard Worker // || DoItemAlwaysStart(fileName + dotPos) // we want some popular extensions in cache
326*f6dc9357SAndroid Build Coastguard Worker )
327*f6dc9357SAndroid Build Coastguard Worker map.Insert(insertPos, pair);
328*f6dc9357SAndroid Build Coastguard Worker // if (typeName) *typeName = pair.TypeName;
329*f6dc9357SAndroid Build Coastguard Worker return pair.IconIndex;
330*f6dc9357SAndroid Build Coastguard Worker }
331*f6dc9357SAndroid Build Coastguard Worker
332*f6dc9357SAndroid Build Coastguard Worker
Shell_Get_SysImageList_smallIcons(bool smallIcons)333*f6dc9357SAndroid Build Coastguard Worker HIMAGELIST Shell_Get_SysImageList_smallIcons(bool smallIcons)
334*f6dc9357SAndroid Build Coastguard Worker {
335*f6dc9357SAndroid Build Coastguard Worker SHFILEINFO shFileInfo;
336*f6dc9357SAndroid Build Coastguard Worker // shFileInfo.hIcon = NULL; // optional
337*f6dc9357SAndroid Build Coastguard Worker const DWORD_PTR res = SHGetFileInfo(TEXT(""),
338*f6dc9357SAndroid Build Coastguard Worker /* FILE_ATTRIBUTE_ARCHIVE | */
339*f6dc9357SAndroid Build Coastguard Worker FILE_ATTRIBUTE_DIRECTORY,
340*f6dc9357SAndroid Build Coastguard Worker &shFileInfo, sizeof(shFileInfo),
341*f6dc9357SAndroid Build Coastguard Worker SHGFI_USEFILEATTRIBUTES |
342*f6dc9357SAndroid Build Coastguard Worker SHGFI_SYSICONINDEX |
343*f6dc9357SAndroid Build Coastguard Worker (smallIcons ? SHGFI_SMALLICON : SHGFI_LARGEICON));
344*f6dc9357SAndroid Build Coastguard Worker #if 0
345*f6dc9357SAndroid Build Coastguard Worker // (shFileInfo.hIcon == NULL), because we don't use SHGFI_ICON.
346*f6dc9357SAndroid Build Coastguard Worker // so DestroyIcon() is not required
347*f6dc9357SAndroid Build Coastguard Worker if (res && shFileInfo.hIcon) // unexpected
348*f6dc9357SAndroid Build Coastguard Worker DestroyIcon(shFileInfo.hIcon);
349*f6dc9357SAndroid Build Coastguard Worker #endif
350*f6dc9357SAndroid Build Coastguard Worker return (HIMAGELIST)res;
351*f6dc9357SAndroid Build Coastguard Worker }
352