ReactOS 0.4.15-dev-8102-g108db8f
CExtractIcon.cpp
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Registry namespace extension
4 * FILE: dll/win32/shell32/extracticon.c
5 * PURPOSE: Icon extraction
6 *
7 * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
8 */
9
10#include "precomp.h"
11
13
15{
18};
19
21 public CComObjectRootEx<CComMultiThreadModelNoCS>,
23 public IExtractIconW,
24 public IExtractIconA,
25 public IPersistFile
26{
27private:
33public:
36
37 // IDefaultExtractIconInit
38 STDMETHOD(SetDefaultIcon)(LPCWSTR pszFile, int iIcon) override;
39 STDMETHOD(SetFlags)(UINT uFlags) override;
40 STDMETHOD(SetKey)(HKEY hkey) override;
41 STDMETHOD(SetNormalIcon)(LPCWSTR pszFile, int iIcon) override;
42 STDMETHOD(SetOpenIcon)(LPCWSTR pszFile, int iIcon) override;
43 STDMETHOD(SetShortcutIcon)(LPCWSTR pszFile, int iIcon) override;
44
45 // IExtractIconW
46 STDMETHOD(GetIconLocation)(UINT uFlags, LPWSTR szIconFile, UINT cchMax, int *piIndex, UINT *pwFlags) override;
47 STDMETHOD(Extract)(LPCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize) override;
48
49 // IExtractIconA
50 STDMETHOD(GetIconLocation)(UINT uFlags, LPSTR szIconFile, UINT cchMax, int *piIndex, UINT *pwFlags) override;
51 STDMETHOD(Extract)(LPCSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize) override;
52
53 // IPersist
54 STDMETHOD(GetClassID)(CLSID *pClassID) override;
55 STDMETHOD(IsDirty)() override;
56
57 // IPersistFile
58 STDMETHOD(Load)(LPCOLESTR pszFileName, DWORD dwMode) override;
59 STDMETHOD(Save)(LPCOLESTR pszFileName, BOOL fRemember) override;
60 STDMETHOD(SaveCompleted)(LPCOLESTR pszFileName) override;
61 STDMETHOD(GetCurFile)(LPOLESTR *ppszFileName) override;
62
64 COM_INTERFACE_ENTRY_IID(IID_IDefaultExtractIconInit, IDefaultExtractIconInit)
65 COM_INTERFACE_ENTRY_IID(IID_IExtractIconW, IExtractIconW)
66 COM_INTERFACE_ENTRY_IID(IID_IExtractIconA, IExtractIconA)
70};
71
75{
76 SIZE_T cb;
77
78 if (*Destination)
80
81 cb = (wcslen(Source) + 1) * sizeof(WCHAR);
83 if (!*Destination)
84 return;
86}
87
89{
90 flags = 0;
91 memset(&defaultIcon, 0, sizeof(defaultIcon));
92 memset(&normalIcon, 0, sizeof(normalIcon));
93 memset(&openIcon, 0, sizeof(openIcon));
94 memset(&shortcutIcon, 0, sizeof(shortcutIcon));
95}
96
98{
100 if (normalIcon.file) CoTaskMemFree(normalIcon.file);
101 if (openIcon.file) CoTaskMemFree(openIcon.file);
103}
104
106 LPCWSTR pszFile,
107 int iIcon)
108{
109 TRACE("(%p, %s, %d)\n", this, debugstr_w(pszFile), iIcon);
110
111 DuplicateString(pszFile, &defaultIcon.file);
112 if (!defaultIcon.file)
113 return E_OUTOFMEMORY;
114 defaultIcon.index = iIcon;
115 return S_OK;
116}
117
119 UINT uFlags)
120{
121 TRACE("(%p, 0x%x)\n", this, uFlags);
122
123 flags = uFlags;
124 return S_OK;
125}
126
128 HKEY hkey)
129{
130 FIXME("(%p, %p)\n", this, hkey);
132 return E_NOTIMPL;
133}
134
136 LPCWSTR pszFile,
137 int iIcon)
138{
139 TRACE("(%p, %s, %d)\n", this, debugstr_w(pszFile), iIcon);
140
141 DuplicateString(pszFile, &normalIcon.file);
142 if (!normalIcon.file)
143 return E_OUTOFMEMORY;
144 normalIcon.index = iIcon;
145 return S_OK;
146}
147
149 LPCWSTR pszFile,
150 int iIcon)
151{
152 TRACE("(%p, %s, %d)\n", this, debugstr_w(pszFile), iIcon);
153
154 DuplicateString(pszFile, &openIcon.file);
155 if (!openIcon.file)
156 return E_OUTOFMEMORY;
157 openIcon.index = iIcon;
158 return S_OK;
159}
160
162 LPCWSTR pszFile,
163 int iIcon)
164{
165 TRACE("(%p, %s, %d)\n", this, debugstr_w(pszFile), iIcon);
166
167 DuplicateString(pszFile, &shortcutIcon.file);
168 if (!shortcutIcon.file)
169 return E_OUTOFMEMORY;
170 shortcutIcon.index = iIcon;
171 return S_OK;
172}
173
175 UINT uFlags,
176 LPWSTR szIconFile,
177 UINT cchMax,
178 int *piIndex,
179 UINT *pwFlags)
180{
181 const struct IconLocation *icon = NULL;
182 SIZE_T cb;
183
184 TRACE("(%p, 0x%x, %s, 0x%x, %p, %p)\n", this, uFlags, debugstr_w(szIconFile), cchMax, piIndex, pwFlags);
185
186 if (!piIndex || !pwFlags)
187 return E_POINTER;
188
189 if (uFlags & GIL_DEFAULTICON)
190 icon = defaultIcon.file ? &defaultIcon : &normalIcon;
191 else if (uFlags & GIL_FORSHORTCUT)
192 icon = shortcutIcon.file ? &shortcutIcon : &normalIcon;
193 else if (uFlags & GIL_OPENICON)
194 icon = openIcon.file ? &openIcon : &normalIcon;
195 else
196 icon = &normalIcon;
197
198 if (!icon->file)
199 return E_FAIL;
200
201 cb = wcslen(icon->file) + 1;
202 if (cchMax < (UINT)cb)
203 return E_FAIL;
204 CopyMemory(szIconFile, icon->file, cb * sizeof(WCHAR));
205 *piIndex = icon->index;
206 *pwFlags = flags;
207 return S_OK;
208}
209
211 LPCWSTR pszFile,
212 UINT nIconIndex,
213 HICON *phiconLarge,
214 HICON *phiconSmall,
215 UINT nIconSize)
216{
217 TRACE("(%p, %s, %u, %p, %p, %u)\n", this, debugstr_w(pszFile), nIconIndex, phiconLarge, phiconSmall, nIconSize);
218
219 /* Nothing to do, ExtractIconW::GetIconLocation should be enough */
220 return S_FALSE;
221}
222
224 UINT uFlags,
225 LPSTR szIconFile,
226 UINT cchMax,
227 int *piIndex,
228 UINT *pwFlags)
229{
230 LPWSTR szIconFileW = NULL;
231 HRESULT hr;
232
233 if (cchMax > 0)
234 {
235 szIconFileW = (LPWSTR)CoTaskMemAlloc(cchMax * sizeof(WCHAR));
236 if (!szIconFileW)
237 return E_OUTOFMEMORY;
238 }
239
240 hr = GetIconLocation(uFlags, szIconFileW, cchMax, piIndex, pwFlags);
241 if (SUCCEEDED(hr) && cchMax > 0)
242 if (0 == WideCharToMultiByte(CP_ACP, 0, szIconFileW, cchMax, szIconFile, cchMax, NULL, NULL))
243 hr = E_FAIL;
244
245 if (szIconFileW)
246 CoTaskMemFree(szIconFileW);
247 return hr;
248}
249
251 LPCSTR pszFile,
252 UINT nIconIndex,
253 HICON *phiconLarge,
254 HICON *phiconSmall,
255 UINT nIconSize)
256{
257 LPWSTR pszFileW = NULL;
258 HRESULT hr;
259
260 if (pszFile)
261 {
262 int nLength;
263
264 nLength = MultiByteToWideChar(CP_ACP, 0, pszFile, -1, NULL, 0);
265 if (nLength == 0)
266 return E_FAIL;
267 pszFileW = (LPWSTR)CoTaskMemAlloc(nLength * sizeof(WCHAR));
268 if (!pszFileW)
269 return E_OUTOFMEMORY;
270 if (!MultiByteToWideChar(CP_ACP, 0, pszFile, nLength, pszFileW, nLength))
271 {
272 CoTaskMemFree(pszFileW);
273 return E_FAIL;
274 }
275 }
276
277 hr = Extract(pszFileW, nIconIndex, phiconLarge, phiconSmall, nIconSize);
278
279 if (pszFileW)
280 CoTaskMemFree(pszFileW);
281 return hr;
282}
283
285 CLSID *pClassID)
286{
287 TRACE("(%p, %p)\n", this, pClassID);
288
289 if (!pClassID)
290 return E_POINTER;
291
292 *pClassID = GUID_NULL;
293 return S_OK;
294}
295
297{
298 FIXME("(%p)\n", this);
300 return E_NOTIMPL;
301}
302
304 LPCOLESTR pszFileName,
305 DWORD dwMode)
306{
307 FIXME("(%p, %s, %u)\n", this, debugstr_w(pszFileName), dwMode);
309 return E_NOTIMPL;
310}
311
313 LPCOLESTR pszFileName,
314 BOOL fRemember)
315{
316 FIXME("(%p, %s, %d)\n", this, debugstr_w(pszFileName), fRemember);
318 return E_NOTIMPL;
319}
320
322 LPCOLESTR pszFileName)
323{
324 FIXME("(%p, %s)\n", this, debugstr_w(pszFileName));
326 return E_NOTIMPL;
327}
328
330 LPOLESTR *ppszFileName)
331{
332 FIXME("(%p, %p)\n", this, ppszFileName);
334 return E_NOTIMPL;
335}
336
338{
339 return ShellObjectCreator<CExtractIcon>(riid, ppv);
340}
341
342/*
343 * Partially implemented
344 * See apitests\shell32\SHCreateFileExtractIconW.cpp for details
345 * Currently (march 2018) our shell does not handle IExtractIconW with an invalid path,
346 * so this (wrong) implementation actually works better for us.
347 */
350WINAPI
352 _In_ LPCWSTR pszFile,
355 _Outptr_ void **ppv)
356{
357 SHFILEINFOW shfi;
359 HRESULT hr = E_FAIL;
360 if (firet)
361 {
365 return hr;
366
367 hr = iconInit->SetNormalIcon(shfi.szDisplayName, shfi.iIcon);
369 return hr;
370
371 return iconInit->QueryInterface(riid, ppv);
372 }
374 return hr;
375
376 return hr;
377}
EXTERN_C HRESULT WINAPI SHCreateFileExtractIconW(_In_ LPCWSTR pszFile, _In_ DWORD dwFileAttributes, _In_ REFIID riid, _Outptr_ void **ppv)
HRESULT WINAPI SHCreateDefaultExtractIcon(REFIID riid, void **ppv)
DWORD dwFileAttributes
UINT cchMax
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
#define EXTERN_C
Definition: basetyps.h:12
#define STDMETHOD(m)
Definition: basetyps.h:62
#define STDMETHODCALLTYPE
Definition: bdasup.h:9
#define FIXME(fmt,...)
Definition: debug.h:114
#define UNIMPLEMENTED
Definition: debug.h:118
STDMETHOD() SetNormalIcon(LPCWSTR pszFile, int iIcon) override
STDMETHOD() Load(LPCOLESTR pszFileName, DWORD dwMode) override
STDMETHOD() SetShortcutIcon(LPCWSTR pszFile, int iIcon) override
STDMETHOD() SetDefaultIcon(LPCWSTR pszFile, int iIcon) override
STDMETHOD() Save(LPCOLESTR pszFileName, BOOL fRemember) override
STDMETHOD() Extract(LPCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize) override
STDMETHOD() SetFlags(UINT uFlags) override
STDMETHOD() GetClassID(CLSID *pClassID) override
struct IconLocation normalIcon
STDMETHOD() SaveCompleted(LPCOLESTR pszFileName) override
struct IconLocation defaultIcon
STDMETHOD() IsDirty() override
struct IconLocation shortcutIcon
STDMETHOD() SetOpenIcon(LPCWSTR pszFile, int iIcon) override
struct IconLocation openIcon
STDMETHOD() SetKey(HKEY hkey) override
STDMETHOD() GetIconLocation(UINT uFlags, LPWSTR szIconFile, UINT cchMax, int *piIndex, UINT *pwFlags) override
STDMETHOD() GetCurFile(LPOLESTR *ppszFileName) override
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
UINT uFlags
Definition: api.c:59
#define CP_ACP
Definition: compat.h:109
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define FAILED_UNEXPECTEDLY(hr)
Definition: precomp.h:121
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLbitfield flags
Definition: glext.h:7161
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define debugstr_w
Definition: kernel32.h:32
#define GUID_NULL
Definition: ks.h:106
#define BEGIN_COM_MAP(x)
Definition: atlcom.h:581
#define COM_INTERFACE_ENTRY_IID(iid, x)
Definition: atlcom.h:601
#define END_COM_MAP()
Definition: atlcom.h:592
static HICON
Definition: imagelist.c:84
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
static LPOLESTR
Definition: stg_prop.c:27
#define _Outptr_
Definition: ms_sal.h:427
#define _In_
Definition: ms_sal.h:308
unsigned int UINT
Definition: ndis.h:50
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:3004
const GUID IID_IPersistFile
const GUID IID_IPersist
Definition: proxy.cpp:14
#define REFIID
Definition: guiddef.h:118
#define memset(x, y, z)
Definition: compat.h:39
DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path, DWORD dwFileAttributes, SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
Definition: shell32_main.c:415
#define SHGFI_ICONLOCATION
Definition: shellapi.h:169
#define SHGFI_USEFILEATTRIBUTES
Definition: shellapi.h:181
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
#define DuplicateString(x)
Definition: stringutils.h:45
WCHAR szDisplayName[MAX_PATH]
Definition: shellapi.h:375
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
WORD WORD PSZ PSZ pszFileName
Definition: vdmdbg.h:44
#define CopyMemory
Definition: winbase.h:1710
_In_ DWORD nLength
Definition: wincon.h:473
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define E_POINTER
Definition: winerror.h:2365
#define IID_PPV_ARG(Itype, ppType)
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185