ReactOS  0.4.14-dev-384-g5b37caa
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 
20 class CExtractIcon :
21  public CComObjectRootEx<CComMultiThreadModelNoCS>,
23  public IExtractIconW,
24  public IExtractIconA,
25  public IPersistFile
26 {
27 private:
33 public:
34  CExtractIcon();
35  ~CExtractIcon();
36 
37  // IDefaultExtractIconInit
38  virtual HRESULT STDMETHODCALLTYPE SetDefaultIcon(LPCWSTR pszFile, int iIcon);
40  virtual HRESULT STDMETHODCALLTYPE SetKey(HKEY hkey);
41  virtual HRESULT STDMETHODCALLTYPE SetNormalIcon(LPCWSTR pszFile, int iIcon);
42  virtual HRESULT STDMETHODCALLTYPE SetOpenIcon(LPCWSTR pszFile, int iIcon);
43  virtual HRESULT STDMETHODCALLTYPE SetShortcutIcon(LPCWSTR pszFile, int iIcon);
44 
45  // IExtractIconW
46  virtual HRESULT STDMETHODCALLTYPE GetIconLocation(UINT uFlags, LPWSTR szIconFile, UINT cchMax, int *piIndex, UINT *pwFlags);
47  virtual HRESULT STDMETHODCALLTYPE Extract(LPCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize);
48 
49  // IExtractIconA
50  virtual HRESULT STDMETHODCALLTYPE GetIconLocation(UINT uFlags, LPSTR szIconFile, UINT cchMax, int *piIndex, UINT *pwFlags);
51  virtual HRESULT STDMETHODCALLTYPE Extract(LPCSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize);
52 
53  // IPersist
54  virtual HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID);
56 
57  // IPersistFile
58  virtual HRESULT STDMETHODCALLTYPE Load(LPCOLESTR pszFileName, DWORD dwMode);
59  virtual HRESULT STDMETHODCALLTYPE Save(LPCOLESTR pszFileName, BOOL fRemember);
61  virtual HRESULT STDMETHODCALLTYPE GetCurFile(LPOLESTR *ppszFileName);
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 {
99  if (defaultIcon.file) CoTaskMemFree(defaultIcon.file);
100  if (normalIcon.file) CoTaskMemFree(normalIcon.file);
101  if (openIcon.file) CoTaskMemFree(openIcon.file);
102  if (shortcutIcon.file) CoTaskMemFree(shortcutIcon.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  */
349 WINAPI
352  REFIID riid,
353  void **ppv)
354 {
355  SHFILEINFOW shfi;
356  ULONG_PTR firet = SHGetFileInfoW(pszPath, dwFileAttributes, &shfi, sizeof(shfi), SHGFI_USEFILEATTRIBUTES | SHGFI_ICONLOCATION);
357  HRESULT hr = E_FAIL;
358  if (firet)
359  {
362  if (FAILED_UNEXPECTEDLY(hr))
363  return hr;
364 
365  hr = iconInit->SetNormalIcon(shfi.szDisplayName, shfi.iIcon);
366  if (FAILED_UNEXPECTEDLY(hr))
367  return hr;
368 
369  return iconInit->QueryInterface(riid, ppv);
370  }
371  if (FAILED_UNEXPECTEDLY(hr))
372  return hr;
373 
374  return hr;
375 }
376 
virtual HRESULT STDMETHODCALLTYPE GetCurFile(LPOLESTR *ppszFileName)
static HICON
Definition: imagelist.c:84
#define REFIID
Definition: guiddef.h:118
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:420
#define WideCharToMultiByte
Definition: compat.h:101
HRESULT hr
Definition: shlfolder.c:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
struct IconLocation defaultIcon
virtual HRESULT STDMETHODCALLTYPE SetDefaultIcon(LPCWSTR pszFile, int iIcon)
virtual HRESULT STDMETHODCALLTYPE Extract(LPCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize)
REFIID riid
Definition: precomp.h:44
#define CP_ACP
Definition: compat.h:99
virtual HRESULT STDMETHODCALLTYPE SaveCompleted(LPCOLESTR pszFileName)
const GUID IID_IPersist
Definition: proxy.cpp:14
_In_ DWORD nLength
Definition: wincon.h:461
REFIID LPVOID * ppv
Definition: atlbase.h:39
virtual HRESULT STDMETHODCALLTYPE IsDirty()
UINT uFlags
Definition: api.c:59
char * LPSTR
Definition: xmlstorage.h:182
static LPOLESTR
Definition: stg_prop.c:27
virtual HRESULT STDMETHODCALLTYPE Save(LPCOLESTR pszFileName, BOOL fRemember)
#define IID_PPV_ARG(Itype, ppType)
#define E_FAIL
Definition: ddrawi.h:102
uint32_t ULONG_PTR
Definition: typedefs.h:63
virtual HRESULT STDMETHODCALLTYPE SetShortcutIcon(LPCWSTR pszFile, int iIcon)
virtual HRESULT STDMETHODCALLTYPE Load(LPCOLESTR pszFileName, DWORD dwMode)
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
unsigned int BOOL
Definition: ntddk_ex.h:94
#define debugstr_w
Definition: kernel32.h:32
#define FIXME(fmt,...)
Definition: debug.h:110
WORD WORD PSZ PSZ pszFileName
Definition: vdmdbg.h:41
#define S_FALSE
Definition: winerror.h:2357
struct IconLocation shortcutIcon
smooth NULL
Definition: ftsmooth.c:416
const char * LPCSTR
Definition: xmlstorage.h:183
#define BEGIN_COM_MAP(x)
Definition: atlcom.h:541
#define TRACE(s)
Definition: solgame.cpp:4
__wchar_t WCHAR
Definition: xmlstorage.h:180
DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path, DWORD dwFileAttributes, SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
Definition: shell32_main.c:410
LONG HRESULT
Definition: typedefs.h:77
#define FAILED_UNEXPECTEDLY(hr)
Definition: shellutils.h:71
#define WINAPI
Definition: msvc.h:8
#define CopyMemory
Definition: winbase.h:1640
#define STDMETHODCALLTYPE
Definition: bdasup.h:9
unsigned long DWORD
Definition: ntddk_ex.h:95
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:2891
#define SHGFI_USEFILEATTRIBUTES
Definition: shellapi.h:179
GLbitfield flags
Definition: glext.h:7161
UINT cchMax
virtual HRESULT STDMETHODCALLTYPE SetNormalIcon(LPCWSTR pszFile, int iIcon)
WCHAR szDisplayName[MAX_PATH]
Definition: shellapi.h:373
#define GUID_NULL
Definition: ks.h:106
struct IconLocation normalIcon
HRESULT WINAPI SHCreateDefaultExtractIcon(REFIID riid, void **ppv)
VOID DuplicateString(LPCWSTR Source, LPWSTR *Destination)
WINE_DEFAULT_DEBUG_CHANNEL(shell)
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define SHGFI_ICONLOCATION
Definition: shellapi.h:167
#define S_OK
Definition: intsafe.h:59
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
#define COM_INTERFACE_ENTRY_IID(iid, x)
Definition: atlcom.h:561
virtual HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID)
#define E_NOTIMPL
Definition: ddrawi.h:99
virtual HRESULT STDMETHODCALLTYPE SetFlags(UINT uFlags)
virtual HRESULT STDMETHODCALLTYPE SetKey(HKEY hkey)
unsigned int UINT
Definition: ndis.h:50
#define MultiByteToWideChar
Definition: compat.h:100
static HMODULE MODULEINFO DWORD cb
Definition: module.c:32
struct IconLocation openIcon
const GUID IID_IPersistFile
DWORD dwFileAttributes
#define UNIMPLEMENTED
Definition: debug.h:114
virtual HRESULT STDMETHODCALLTYPE GetIconLocation(UINT uFlags, LPWSTR szIconFile, UINT cchMax, int *piIndex, UINT *pwFlags)
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167
#define END_COM_MAP()
Definition: atlcom.h:552
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define E_POINTER
Definition: winerror.h:2365
virtual HRESULT STDMETHODCALLTYPE SetOpenIcon(LPCWSTR pszFile, int iIcon)
#define EXTERN_C
Definition: basetyps.h:12
#define memset(x, y, z)
Definition: compat.h:39
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:404
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define SUCCEEDED(hr)
Definition: intsafe.h:57
EXTERN_C HRESULT WINAPI SHCreateFileExtractIconW(LPCWSTR pszPath, DWORD dwFileAttributes, REFIID riid, void **ppv)