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
7 * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
15 WINE_DEFAULT_DEBUG_CHANNEL(shell
);
26 IDefaultExtractIconInit defaultExtractIconInitImpl
;
27 IExtractIconW extractIconWImpl
;
28 IExtractIconA extractIconAImpl
;
29 IPersistFile persistFileImpl
;
32 struct IconLocation defaultIcon
;
33 struct IconLocation normalIcon
;
34 struct IconLocation openIcon
;
35 struct IconLocation shortcutIcon
;
46 CoTaskMemFree(*Destination
);
48 cb
= (wcslen(Source
) + 1) * sizeof(WCHAR
);
49 *Destination
= CoTaskMemAlloc(cb
);
52 CopyMemory(*Destination
, Source
, cb
);
55 static HRESULT STDMETHODCALLTYPE
56 IconExtraction_DefaultExtractIconInit_QueryInterface(
57 IDefaultExtractIconInit
*This
,
61 struct IconExtraction
*s
= CONTAINING_RECORD(This
, struct IconExtraction
, defaultExtractIconInitImpl
);
63 TRACE("(%p, %s, %p)\n", This
, debugstr_guid(riid
), ppvObject
);
68 if (IsEqualIID(riid
, &IID_IUnknown
))
69 *ppvObject
= &s
->defaultExtractIconInitImpl
;
70 else if (IsEqualIID(riid
, &IID_IDefaultExtractIconInit
))
71 *ppvObject
= &s
->defaultExtractIconInitImpl
;
72 else if (IsEqualIID(riid
, &IID_IExtractIconW
))
73 *ppvObject
= &s
->extractIconWImpl
;
74 else if (IsEqualIID(riid
, &IID_IExtractIconA
))
75 *ppvObject
= &s
->extractIconAImpl
;
76 else if (IsEqualIID(riid
, &IID_IPersist
))
77 *ppvObject
= &s
->persistFileImpl
;
78 else if (IsEqualIID(riid
, &IID_IPersistFile
))
79 *ppvObject
= &s
->persistFileImpl
;
86 IUnknown_AddRef(This
);
90 static ULONG STDMETHODCALLTYPE
91 IconExtraction_DefaultExtractIconInit_AddRef(
92 IDefaultExtractIconInit
*This
)
94 struct IconExtraction
*s
= CONTAINING_RECORD(This
, struct IconExtraction
, defaultExtractIconInitImpl
);
95 ULONG refCount
= InterlockedIncrement(&s
->ref
);
96 TRACE("(%p)\n", This
);
100 static ULONG STDMETHODCALLTYPE
101 IconExtraction_DefaultExtractIconInit_Release(
102 IDefaultExtractIconInit
*This
)
104 struct IconExtraction
*s
= CONTAINING_RECORD(This
, struct IconExtraction
, defaultExtractIconInitImpl
);
107 TRACE("(%p)\n", This
);
109 refCount
= InterlockedDecrement(&s
->ref
);
112 if (s
->defaultIcon
.file
) CoTaskMemFree(s
->defaultIcon
.file
);
113 if (s
->normalIcon
.file
) CoTaskMemFree(s
->normalIcon
.file
);
114 if (s
->openIcon
.file
) CoTaskMemFree(s
->openIcon
.file
);
115 if (s
->shortcutIcon
.file
) CoTaskMemFree(s
->shortcutIcon
.file
);
122 static HRESULT STDMETHODCALLTYPE
123 IconExtraction_DefaultExtractIconInit_SetDefaultIcon(
124 IDefaultExtractIconInit
*This
,
128 struct IconExtraction
*s
= CONTAINING_RECORD(This
, struct IconExtraction
, defaultExtractIconInitImpl
);
130 TRACE("(%p, %s, %d)\n", This
, debugstr_w(pszFile
), iIcon
);
132 DuplicateString(pszFile
, &s
->defaultIcon
.file
);
133 if (!s
->defaultIcon
.file
)
134 return E_OUTOFMEMORY
;
135 s
->defaultIcon
.index
= iIcon
;
139 static HRESULT STDMETHODCALLTYPE
140 IconExtraction_DefaultExtractIconInit_SetFlags(
141 IDefaultExtractIconInit
*This
,
144 struct IconExtraction
*s
= CONTAINING_RECORD(This
, struct IconExtraction
, defaultExtractIconInitImpl
);
146 TRACE("(%p, 0x%x)\n", This
, uFlags
);
152 static HRESULT STDMETHODCALLTYPE
153 IconExtraction_DefaultExtractIconInit_SetKey(
154 IDefaultExtractIconInit
*This
,
157 FIXME("(%p, %p)\n", This
, hkey
);
162 static HRESULT STDMETHODCALLTYPE
163 IconExtraction_DefaultExtractIconInit_SetNormalIcon(
164 IDefaultExtractIconInit
*This
,
168 struct IconExtraction
*s
= CONTAINING_RECORD(This
, struct IconExtraction
, defaultExtractIconInitImpl
);
170 TRACE("(%p, %s, %d)\n", This
, debugstr_w(pszFile
), iIcon
);
172 DuplicateString(pszFile
, &s
->normalIcon
.file
);
173 if (!s
->normalIcon
.file
)
174 return E_OUTOFMEMORY
;
175 s
->normalIcon
.index
= iIcon
;
179 static HRESULT STDMETHODCALLTYPE
180 IconExtraction_DefaultExtractIconInit_SetOpenIcon(
181 IDefaultExtractIconInit
*This
,
185 struct IconExtraction
*s
= CONTAINING_RECORD(This
, struct IconExtraction
, defaultExtractIconInitImpl
);
187 TRACE("(%p, %s, %d)\n", This
, debugstr_w(pszFile
), iIcon
);
189 DuplicateString(pszFile
, &s
->openIcon
.file
);
190 if (!s
->openIcon
.file
)
191 return E_OUTOFMEMORY
;
192 s
->openIcon
.index
= iIcon
;
196 static HRESULT STDMETHODCALLTYPE
197 IconExtraction_DefaultExtractIconInit_SetShortcutIcon(
198 IDefaultExtractIconInit
*This
,
202 struct IconExtraction
*s
= CONTAINING_RECORD(This
, struct IconExtraction
, defaultExtractIconInitImpl
);
204 TRACE("(%p, %s, %d)\n", This
, debugstr_w(pszFile
), iIcon
);
206 DuplicateString(pszFile
, &s
->shortcutIcon
.file
);
207 if (!s
->shortcutIcon
.file
)
208 return E_OUTOFMEMORY
;
209 s
->shortcutIcon
.index
= iIcon
;
213 static HRESULT STDMETHODCALLTYPE
214 IconExtraction_ExtractIconW_QueryInterface(
219 struct IconExtraction
*s
= CONTAINING_RECORD(This
, struct IconExtraction
, extractIconWImpl
);
220 return IconExtraction_DefaultExtractIconInit_QueryInterface(&s
->defaultExtractIconInitImpl
, riid
, ppvObject
);
223 static ULONG STDMETHODCALLTYPE
224 IconExtraction_ExtractIconW_AddRef(
227 struct IconExtraction
*s
= CONTAINING_RECORD(This
, struct IconExtraction
, extractIconWImpl
);
228 return IconExtraction_DefaultExtractIconInit_AddRef(&s
->defaultExtractIconInitImpl
);
231 static ULONG STDMETHODCALLTYPE
232 IconExtraction_ExtractIconW_Release(
235 struct IconExtraction
*s
= CONTAINING_RECORD(This
, struct IconExtraction
, extractIconWImpl
);
236 return IconExtraction_DefaultExtractIconInit_Release(&s
->defaultExtractIconInitImpl
);
239 static HRESULT STDMETHODCALLTYPE
240 IconExtraction_ExtractIconW_GetIconLocation(
248 struct IconExtraction
*s
= CONTAINING_RECORD(This
, struct IconExtraction
, extractIconWImpl
);
249 const struct IconLocation
*icon
= NULL
;
252 TRACE("(%p, 0x%x, %s, 0x%x, %p, %p)\n", This
, uFlags
, debugstr_w(szIconFile
), cchMax
, piIndex
, pwFlags
);
254 if (!piIndex
|| !pwFlags
)
257 if (uFlags
& GIL_DEFAULTICON
)
258 icon
= s
->defaultIcon
.file
? &s
->defaultIcon
: &s
->normalIcon
;
259 else if (uFlags
& GIL_FORSHORTCUT
)
260 icon
= s
->shortcutIcon
.file
? &s
->shortcutIcon
: &s
->normalIcon
;
261 else if (uFlags
& GIL_OPENICON
)
262 icon
= s
->openIcon
.file
? &s
->openIcon
: &s
->normalIcon
;
264 icon
= &s
->normalIcon
;
269 cb
= wcslen(icon
->file
) + 1;
270 if (cchMax
< (UINT
)cb
)
272 CopyMemory(szIconFile
, icon
->file
, cb
* sizeof(WCHAR
));
273 *piIndex
= icon
->index
;
278 static HRESULT STDMETHODCALLTYPE
279 IconExtraction_ExtractIconW_Extract(
287 TRACE("(%p, %s, %u, %p, %p, %u)\n", This
, debugstr_w(pszFile
),
288 nIconIndex
, phiconLarge
, phiconSmall
, nIconSize
);
290 /* Nothing to do, ExtractIconW::GetIconLocation should be enough */
294 static HRESULT STDMETHODCALLTYPE
295 IconExtraction_ExtractIconA_QueryInterface(
300 struct IconExtraction
*s
= CONTAINING_RECORD(This
, struct IconExtraction
, extractIconAImpl
);
301 return IconExtraction_DefaultExtractIconInit_QueryInterface(&s
->defaultExtractIconInitImpl
, riid
, ppvObject
);
304 static ULONG STDMETHODCALLTYPE
305 IconExtraction_ExtractIconA_AddRef(
308 struct IconExtraction
*s
= CONTAINING_RECORD(This
, struct IconExtraction
, extractIconAImpl
);
309 return IconExtraction_DefaultExtractIconInit_AddRef(&s
->defaultExtractIconInitImpl
);
312 static ULONG STDMETHODCALLTYPE
313 IconExtraction_ExtractIconA_Release(
316 struct IconExtraction
*s
= CONTAINING_RECORD(This
, struct IconExtraction
, extractIconAImpl
);
317 return IconExtraction_DefaultExtractIconInit_Release(&s
->defaultExtractIconInitImpl
);
320 static HRESULT STDMETHODCALLTYPE
321 IconExtraction_ExtractIconA_GetIconLocation(
329 struct IconExtraction
*s
= CONTAINING_RECORD(This
, struct IconExtraction
, extractIconAImpl
);
330 LPWSTR szIconFileW
= NULL
;
335 szIconFileW
= CoTaskMemAlloc(cchMax
* sizeof(WCHAR
));
337 return E_OUTOFMEMORY
;
340 hr
= IconExtraction_ExtractIconW_GetIconLocation(
341 &s
->extractIconWImpl
, uFlags
, szIconFileW
, cchMax
, piIndex
, pwFlags
);
342 if (SUCCEEDED(hr
) && cchMax
> 0)
343 if (0 == WideCharToMultiByte(CP_ACP
, 0, szIconFileW
, cchMax
, szIconFile
, cchMax
, NULL
, NULL
))
347 CoTaskMemFree(szIconFileW
);
351 static HRESULT STDMETHODCALLTYPE
352 IconExtraction_ExtractIconA_Extract(
360 struct IconExtraction
*s
= CONTAINING_RECORD(This
, struct IconExtraction
, extractIconAImpl
);
361 LPWSTR pszFileW
= NULL
;
367 nLength
= MultiByteToWideChar(CP_ACP
, 0, pszFile
, -1, NULL
, 0);
370 pszFileW
= CoTaskMemAlloc(nLength
* sizeof(WCHAR
));
372 return E_OUTOFMEMORY
;
373 if (!MultiByteToWideChar(CP_ACP
, 0, pszFile
, nLength
, pszFileW
, nLength
))
375 CoTaskMemFree(pszFileW
);
380 hr
= IconExtraction_ExtractIconW_Extract(
381 &s
->extractIconWImpl
, pszFileW
, nIconIndex
, phiconLarge
, phiconSmall
, nIconSize
);
384 CoTaskMemFree(pszFileW
);
388 static HRESULT STDMETHODCALLTYPE
389 IconExtraction_PersistFile_QueryInterface(
394 struct IconExtraction
*s
= CONTAINING_RECORD(This
, struct IconExtraction
, persistFileImpl
);
395 return IconExtraction_DefaultExtractIconInit_QueryInterface(&s
->defaultExtractIconInitImpl
, riid
, ppvObject
);
398 static ULONG STDMETHODCALLTYPE
399 IconExtraction_PersistFile_AddRef(
402 struct IconExtraction
*s
= CONTAINING_RECORD(This
, struct IconExtraction
, persistFileImpl
);
403 return IconExtraction_DefaultExtractIconInit_AddRef(&s
->defaultExtractIconInitImpl
);
406 static ULONG STDMETHODCALLTYPE
407 IconExtraction_PersistFile_Release(
410 struct IconExtraction
*s
= CONTAINING_RECORD(This
, struct IconExtraction
, persistFileImpl
);
411 return IconExtraction_DefaultExtractIconInit_Release(&s
->defaultExtractIconInitImpl
);
414 static HRESULT STDMETHODCALLTYPE
415 IconExtraction_PersistFile_GetClassID(
419 TRACE("(%p, %p)\n", This
, pClassID
);
424 *pClassID
= GUID_NULL
;
428 static HRESULT STDMETHODCALLTYPE
429 IconExtraction_PersistFile_IsDirty(
432 FIXME("(%p)\n", This
);
437 static HRESULT STDMETHODCALLTYPE
438 IconExtraction_PersistFile_Load(
440 LPCOLESTR pszFileName
,
443 FIXME("(%p, %s, %u)\n", This
, debugstr_w(pszFileName
), dwMode
);
448 static HRESULT STDMETHODCALLTYPE
449 IconExtraction_PersistFile_Save(
451 LPCOLESTR pszFileName
,
454 FIXME("(%p, %s, %d)\n", This
, debugstr_w(pszFileName
), fRemember
);
459 static HRESULT STDMETHODCALLTYPE
460 IconExtraction_PersistFile_SaveCompleted(
462 LPCOLESTR pszFileName
)
464 FIXME("(%p, %s)\n", This
, debugstr_w(pszFileName
));
469 static HRESULT STDMETHODCALLTYPE
470 IconExtraction_PersistFile_GetCurFile(
472 LPOLESTR
*ppszFileName
)
474 FIXME("(%p, %p)\n", This
, ppszFileName
);
479 static const IDefaultExtractIconInitVtbl IconExtractionDefaultExtractIconInitVtbl
=
481 IconExtraction_DefaultExtractIconInit_QueryInterface
,
482 IconExtraction_DefaultExtractIconInit_AddRef
,
483 IconExtraction_DefaultExtractIconInit_Release
,
484 IconExtraction_DefaultExtractIconInit_SetDefaultIcon
,
485 IconExtraction_DefaultExtractIconInit_SetFlags
,
486 IconExtraction_DefaultExtractIconInit_SetKey
,
487 IconExtraction_DefaultExtractIconInit_SetNormalIcon
,
488 IconExtraction_DefaultExtractIconInit_SetOpenIcon
,
489 IconExtraction_DefaultExtractIconInit_SetShortcutIcon
,
492 static const IExtractIconWVtbl IconExtractionExtractIconWVtbl
=
494 IconExtraction_ExtractIconW_QueryInterface
,
495 IconExtraction_ExtractIconW_AddRef
,
496 IconExtraction_ExtractIconW_Release
,
497 IconExtraction_ExtractIconW_GetIconLocation
,
498 IconExtraction_ExtractIconW_Extract
,
501 static const IExtractIconAVtbl IconExtractionExtractIconAVtbl
=
503 IconExtraction_ExtractIconA_QueryInterface
,
504 IconExtraction_ExtractIconA_AddRef
,
505 IconExtraction_ExtractIconA_Release
,
506 IconExtraction_ExtractIconA_GetIconLocation
,
507 IconExtraction_ExtractIconA_Extract
,
510 static const IPersistFileVtbl IconExtractionPersistFileVtbl
=
512 IconExtraction_PersistFile_QueryInterface
,
513 IconExtraction_PersistFile_AddRef
,
514 IconExtraction_PersistFile_Release
,
515 IconExtraction_PersistFile_GetClassID
,
516 IconExtraction_PersistFile_IsDirty
,
517 IconExtraction_PersistFile_Load
,
518 IconExtraction_PersistFile_Save
,
519 IconExtraction_PersistFile_SaveCompleted
,
520 IconExtraction_PersistFile_GetCurFile
,
524 SHCreateDefaultExtractIcon(
528 struct IconExtraction
*s
;
535 s
= CoTaskMemAlloc(sizeof(struct IconExtraction
));
537 return E_OUTOFMEMORY
;
538 memset(s
, 0, sizeof(struct IconExtraction
));
539 s
->defaultExtractIconInitImpl
.lpVtbl
= &IconExtractionDefaultExtractIconInitVtbl
;
540 s
->extractIconAImpl
.lpVtbl
= &IconExtractionExtractIconAVtbl
;
541 s
->extractIconWImpl
.lpVtbl
= &IconExtractionExtractIconWVtbl
;
542 s
->persistFileImpl
.lpVtbl
= &IconExtractionPersistFileVtbl
;
544 *ppv
= &s
->defaultExtractIconInitImpl
;