Author: hpoussin Date: Tue Oct 23 13:01:39 2007 New Revision: 29822
URL: http://svn.reactos.org/svn/reactos?rev=29822&view=rev Log: Implement SHCreateDefaultExtractIcon Export SHCreateDefaultContextMenu
Added: trunk/reactos/dll/win32/shell32/extracticon.c (with props) Modified: trunk/reactos/dll/win32/shell32/shell32.rbuild trunk/reactos/dll/win32/shell32/shell32.spec
Added: trunk/reactos/dll/win32/shell32/extracticon.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/extractic... ============================================================================== --- trunk/reactos/dll/win32/shell32/extracticon.c (added) +++ trunk/reactos/dll/win32/shell32/extracticon.c Tue Oct 23 13:01:39 2007 @@ -1,0 +1,512 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Registry namespace extension + * FILE: dll/win32/shell32/extracticon.c + * PURPOSE: Icon extraction + * + * PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org) + */ + +#define COBJMACROS +#define CONST_VTABLE +#include <shlobj.h> +#include <debug.h> + +struct IconLocation +{ + LPWSTR file; + UINT index; +}; + +struct IconExtraction +{ + ULONG ref; + IDefaultExtractIconInit defaultExtractIconInitImpl; + IExtractIconW extractIconWImpl; + IExtractIconA extractIconAImpl; + IPersistFile persistFileImpl; + + UINT flags; + struct IconLocation defaultIcon; + struct IconLocation normalIcon; + struct IconLocation openIcon; + struct IconLocation shortcutIcon; +}; + +static VOID +DuplicateString( + LPCWSTR Source, + LPWSTR *Destination) +{ + SIZE_T cb; + + if (*Destination) + CoTaskMemFree(*Destination); + + cb = (wcslen(Source) + 1) * sizeof(WCHAR); + *Destination = CoTaskMemAlloc(cb); + if (!*Destination) + return; + CopyMemory(*Destination, Source, cb); +} + +static HRESULT STDMETHODCALLTYPE +IconExtraction_DefaultExtractIconInit_QueryInterface( + IDefaultExtractIconInit *This, + REFIID riid, + void **ppvObject) +{ + struct IconExtraction *s = CONTAINING_RECORD(This, struct IconExtraction, defaultExtractIconInitImpl); + + if (!ppvObject) + return E_POINTER; + + if (IsEqualIID(riid, &IID_IUnknown)) + *ppvObject = &s->defaultExtractIconInitImpl; + else if (IsEqualIID(riid, &IID_IDefaultExtractIconInit)) + *ppvObject = &s->defaultExtractIconInitImpl; + else if (IsEqualIID(riid, &IID_IExtractIconW)) + *ppvObject = &s->extractIconWImpl; + else if (IsEqualIID(riid, &IID_IExtractIconA)) + *ppvObject = &s->extractIconAImpl; + else if (IsEqualIID(riid, &IID_IPersist)) + *ppvObject = &s->persistFileImpl; + else if (IsEqualIID(riid, &IID_IPersistFile)) + *ppvObject = &s->persistFileImpl; + else + { + *ppvObject = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef(This); + return S_OK; +} + +static ULONG STDMETHODCALLTYPE +IconExtraction_DefaultExtractIconInit_AddRef( + IDefaultExtractIconInit *This) +{ + struct IconExtraction *s = CONTAINING_RECORD(This, struct IconExtraction, defaultExtractIconInitImpl); + ULONG refCount = InterlockedIncrement((PLONG)&s->ref); + return refCount; +} + +static ULONG STDMETHODCALLTYPE +IconExtraction_DefaultExtractIconInit_Release( + IDefaultExtractIconInit *This) +{ + struct IconExtraction *s = CONTAINING_RECORD(This, struct IconExtraction, defaultExtractIconInitImpl); + ULONG refCount; + + if (!This) + return E_POINTER; + + refCount = InterlockedDecrement((PLONG)&s->ref); + if (refCount == 0) + { + if (s->defaultIcon.file) CoTaskMemFree(s->defaultIcon.file); + if (s->normalIcon.file) CoTaskMemFree(s->normalIcon.file); + if (s->openIcon.file) CoTaskMemFree(s->openIcon.file); + if (s->shortcutIcon.file) CoTaskMemFree(s->shortcutIcon.file); + CoTaskMemFree(s); + } + + return refCount; +} + +static HRESULT STDMETHODCALLTYPE +IconExtraction_DefaultExtractIconInit_SetDefaultIcon( + IDefaultExtractIconInit *This, + LPCWSTR pszFile, + int iIcon) +{ + struct IconExtraction *s = CONTAINING_RECORD(This, struct IconExtraction, defaultExtractIconInitImpl); + DuplicateString(pszFile, &s->defaultIcon.file); + if (!s->defaultIcon.file) + return E_OUTOFMEMORY; + s->defaultIcon.index = iIcon; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE +IconExtraction_DefaultExtractIconInit_SetFlags( + IDefaultExtractIconInit *This, + UINT uFlags) +{ + struct IconExtraction *s = CONTAINING_RECORD(This, struct IconExtraction, defaultExtractIconInitImpl); + s->flags = uFlags; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE +IconExtraction_DefaultExtractIconInit_SetKey( + IDefaultExtractIconInit *This, + HKEY hkey) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE +IconExtraction_DefaultExtractIconInit_SetNormalIcon( + IDefaultExtractIconInit *This, + LPCWSTR pszFile, + int iIcon) +{ + struct IconExtraction *s = CONTAINING_RECORD(This, struct IconExtraction, defaultExtractIconInitImpl); + DuplicateString(pszFile, &s->normalIcon.file); + if (!s->normalIcon.file) + return E_OUTOFMEMORY; + s->normalIcon.index = iIcon; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE +IconExtraction_DefaultExtractIconInit_SetOpenIcon( + IDefaultExtractIconInit *This, + LPCWSTR pszFile, + int iIcon) +{ + struct IconExtraction *s = CONTAINING_RECORD(This, struct IconExtraction, defaultExtractIconInitImpl); + DuplicateString(pszFile, &s->openIcon.file); + if (!s->openIcon.file) + return E_OUTOFMEMORY; + s->openIcon.index = iIcon; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE +IconExtraction_DefaultExtractIconInit_SetShortcutIcon( + IDefaultExtractIconInit *This, + LPCWSTR pszFile, + int iIcon) +{ + struct IconExtraction *s = CONTAINING_RECORD(This, struct IconExtraction, defaultExtractIconInitImpl); + DuplicateString(pszFile, &s->shortcutIcon.file); + if (!s->shortcutIcon.file) + return E_OUTOFMEMORY; + s->shortcutIcon.index = iIcon; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE +IconExtraction_ExtractIconW_QueryInterface( + IExtractIconW *This, + REFIID riid, + void **ppvObject) +{ + struct IconExtraction *s = CONTAINING_RECORD(This, struct IconExtraction, extractIconWImpl); + return IconExtraction_DefaultExtractIconInit_QueryInterface(&s->defaultExtractIconInitImpl, riid, ppvObject); +} + +static ULONG STDMETHODCALLTYPE +IconExtraction_ExtractIconW_AddRef( + IExtractIconW *This) +{ + struct IconExtraction *s = CONTAINING_RECORD(This, struct IconExtraction, extractIconWImpl); + return IconExtraction_DefaultExtractIconInit_AddRef(&s->defaultExtractIconInitImpl); +} + +static ULONG STDMETHODCALLTYPE +IconExtraction_ExtractIconW_Release( + IExtractIconW *This) +{ + struct IconExtraction *s = CONTAINING_RECORD(This, struct IconExtraction, extractIconWImpl); + return IconExtraction_DefaultExtractIconInit_Release(&s->defaultExtractIconInitImpl); +} + +static HRESULT STDMETHODCALLTYPE +IconExtraction_ExtractIconW_GetIconLocation( + IExtractIconW *This, + UINT uFlags, + LPWSTR szIconFile, + UINT cchMax, + int *piIndex, + UINT *pwFlags) +{ + struct IconExtraction *s = CONTAINING_RECORD(This, struct IconExtraction, extractIconWImpl); + const struct IconLocation *icon = NULL; + SIZE_T cb; + + if (uFlags & GIL_DEFAULTICON) + icon = s->defaultIcon.file ? &s->defaultIcon : &s->normalIcon; + else if (uFlags & GIL_FORSHORTCUT) + icon = s->shortcutIcon.file ? &s->shortcutIcon : &s->normalIcon; + else if (uFlags & GIL_OPENICON) + icon = s->openIcon.file ? &s->openIcon : &s->normalIcon; + else + icon = &s->normalIcon; + + if (!icon->file) + return E_FAIL; + + cb = wcslen(icon->file) + 1; + if (cchMax < (UINT)cb) + return E_FAIL; + CopyMemory(szIconFile, icon->file, cb * sizeof(WCHAR)); + *piIndex = icon->index; + *pwFlags = s->flags; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE +IconExtraction_ExtractIconW_Extract( + IExtractIconW *This, + LPCWSTR pszFile, + UINT nIconIndex, + HICON *phiconLarge, + HICON *phiconSmall, + UINT nIconSize) +{ + /* Nothing to do, ExtractIconW::GetIconLocation should be enough */ + return S_FALSE; +} + +static HRESULT STDMETHODCALLTYPE +IconExtraction_ExtractIconA_QueryInterface( + IExtractIconA *This, + REFIID riid, + void **ppvObject) +{ + struct IconExtraction *s = CONTAINING_RECORD(This, struct IconExtraction, extractIconAImpl); + return IconExtraction_DefaultExtractIconInit_QueryInterface(&s->defaultExtractIconInitImpl, riid, ppvObject); +} + +static ULONG STDMETHODCALLTYPE +IconExtraction_ExtractIconA_AddRef( + IExtractIconA *This) +{ + struct IconExtraction *s = CONTAINING_RECORD(This, struct IconExtraction, extractIconAImpl); + return IconExtraction_DefaultExtractIconInit_AddRef(&s->defaultExtractIconInitImpl); +} + +static ULONG STDMETHODCALLTYPE +IconExtraction_ExtractIconA_Release( + IExtractIconA *This) +{ + struct IconExtraction *s = CONTAINING_RECORD(This, struct IconExtraction, extractIconAImpl); + return IconExtraction_DefaultExtractIconInit_Release(&s->defaultExtractIconInitImpl); +} + +static HRESULT STDMETHODCALLTYPE +IconExtraction_ExtractIconA_GetIconLocation( + IExtractIconA *This, + UINT uFlags, + LPSTR szIconFile, + UINT cchMax, + int *piIndex, + UINT *pwFlags) +{ + struct IconExtraction *s = CONTAINING_RECORD(This, struct IconExtraction, extractIconAImpl); + LPWSTR szIconFileW = NULL; + HRESULT hr; + + if (cchMax > 0) + { + szIconFileW = CoTaskMemAlloc(cchMax * sizeof(WCHAR)); + if (!szIconFileW) + return E_OUTOFMEMORY; + } + + hr = IconExtraction_ExtractIconW_GetIconLocation( + &s->extractIconWImpl, uFlags, szIconFileW, cchMax, piIndex, pwFlags); + if (SUCCEEDED(hr) && cchMax > 0) + if (0 == WideCharToMultiByte(CP_ACP, 0, szIconFileW, cchMax, szIconFile, cchMax, NULL, NULL)) + hr = E_FAIL; + + if (szIconFileW) + CoTaskMemFree(szIconFileW); + return hr; +} + +static HRESULT STDMETHODCALLTYPE +IconExtraction_ExtractIconA_Extract( + IExtractIconA *This, + LPCSTR pszFile, + UINT nIconIndex, + HICON *phiconLarge, + HICON *phiconSmall, + UINT nIconSize) +{ + struct IconExtraction *s = CONTAINING_RECORD(This, struct IconExtraction, extractIconAImpl); + LPWSTR pszFileW = NULL; + int nLength; + HRESULT hr; + + if (pszFile) + { + nLength = MultiByteToWideChar(CP_ACP, 0, pszFile, -1, NULL, 0); + if (nLength == 0) + return E_FAIL; + pszFileW = CoTaskMemAlloc(nLength * sizeof(WCHAR)); + if (!pszFileW) + return E_OUTOFMEMORY; + if (!MultiByteToWideChar(CP_ACP, 0, pszFile, nLength, pszFileW, nLength)) + { + CoTaskMemFree(pszFileW); + return E_FAIL; + } + } + + hr = IconExtraction_ExtractIconW_Extract( + &s->extractIconWImpl, pszFileW, nIconIndex, phiconLarge, phiconSmall, nIconSize); + + if (pszFileW) + CoTaskMemFree(pszFileW); + return hr; +} + +static HRESULT STDMETHODCALLTYPE +IconExtraction_PersistFile_QueryInterface( + IPersistFile *This, + REFIID riid, + void **ppvObject) +{ + struct IconExtraction *s = CONTAINING_RECORD(This, struct IconExtraction, persistFileImpl); + return IconExtraction_DefaultExtractIconInit_QueryInterface(&s->defaultExtractIconInitImpl, riid, ppvObject); +} + +static ULONG STDMETHODCALLTYPE +IconExtraction_PersistFile_AddRef( + IPersistFile *This) +{ + struct IconExtraction *s = CONTAINING_RECORD(This, struct IconExtraction, persistFileImpl); + return IconExtraction_DefaultExtractIconInit_AddRef(&s->defaultExtractIconInitImpl); +} + +static ULONG STDMETHODCALLTYPE +IconExtraction_PersistFile_Release( + IPersistFile *This) +{ + struct IconExtraction *s = CONTAINING_RECORD(This, struct IconExtraction, persistFileImpl); + return IconExtraction_DefaultExtractIconInit_Release(&s->defaultExtractIconInitImpl); +} + +static HRESULT STDMETHODCALLTYPE +IconExtraction_PersistFile_GetClassID( + IPersistFile *This, + CLSID *pClassID) +{ + if (!pClassID) + return E_POINTER; + + *pClassID = GUID_NULL; + return S_OK; +} + +static HRESULT STDMETHODCALLTYPE +IconExtraction_PersistFile_IsDirty( + IPersistFile *This) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE +IconExtraction_PersistFile_Load( + IPersistFile *This, + LPCOLESTR pszFileName, + DWORD dwMode) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE +IconExtraction_PersistFile_Save( + IPersistFile *This, + LPCOLESTR pszFileName, + BOOL fRemember) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE +IconExtraction_PersistFile_SaveCompleted( + IPersistFile *This, + LPCOLESTR pszFileName) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +static HRESULT STDMETHODCALLTYPE +IconExtraction_PersistFile_GetCurFile( + IPersistFile *This, + LPOLESTR *ppszFileName) +{ + UNIMPLEMENTED; + return E_NOTIMPL; +} + +static const IDefaultExtractIconInitVtbl IconExtractionDefaultExtractIconInitVtbl = +{ + IconExtraction_DefaultExtractIconInit_QueryInterface, + IconExtraction_DefaultExtractIconInit_AddRef, + IconExtraction_DefaultExtractIconInit_Release, + IconExtraction_DefaultExtractIconInit_SetDefaultIcon, + IconExtraction_DefaultExtractIconInit_SetFlags, + IconExtraction_DefaultExtractIconInit_SetKey, + IconExtraction_DefaultExtractIconInit_SetNormalIcon, + IconExtraction_DefaultExtractIconInit_SetOpenIcon, + IconExtraction_DefaultExtractIconInit_SetShortcutIcon, +}; + +static const IExtractIconWVtbl IconExtractionExtractIconWVtbl = +{ + IconExtraction_ExtractIconW_QueryInterface, + IconExtraction_ExtractIconW_AddRef, + IconExtraction_ExtractIconW_Release, + IconExtraction_ExtractIconW_GetIconLocation, + IconExtraction_ExtractIconW_Extract, +}; + +static const IExtractIconAVtbl IconExtractionExtractIconAVtbl = +{ + IconExtraction_ExtractIconA_QueryInterface, + IconExtraction_ExtractIconA_AddRef, + IconExtraction_ExtractIconA_Release, + IconExtraction_ExtractIconA_GetIconLocation, + IconExtraction_ExtractIconA_Extract, +}; + +static const IPersistFileVtbl IconExtractionPersistFileVtbl = +{ + IconExtraction_PersistFile_QueryInterface, + IconExtraction_PersistFile_AddRef, + IconExtraction_PersistFile_Release, + IconExtraction_PersistFile_GetClassID, + IconExtraction_PersistFile_IsDirty, + IconExtraction_PersistFile_Load, + IconExtraction_PersistFile_Save, + IconExtraction_PersistFile_SaveCompleted, + IconExtraction_PersistFile_GetCurFile, +}; + +HRESULT WINAPI +SHCreateDefaultExtractIcon( + REFIID riid, + void **ppv) +{ + struct IconExtraction *s; + + if (!ppv) + return E_POINTER; + + *ppv = NULL; + + s = CoTaskMemAlloc(sizeof(struct IconExtraction)); + if (!s) + return E_OUTOFMEMORY; + memset(s, 0, sizeof(struct IconExtraction)); + s->defaultExtractIconInitImpl.lpVtbl = &IconExtractionDefaultExtractIconInitVtbl; + s->extractIconAImpl.lpVtbl = &IconExtractionExtractIconAVtbl; + s->extractIconWImpl.lpVtbl = &IconExtractionExtractIconWVtbl; + s->persistFileImpl.lpVtbl = &IconExtractionPersistFileVtbl; + s->ref = 1; + *ppv = &s->defaultExtractIconInitImpl; + + return S_OK; +}
Propchange: trunk/reactos/dll/win32/shell32/extracticon.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/reactos/dll/win32/shell32/shell32.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shell32.r... ============================================================================== --- trunk/reactos/dll/win32/shell32/shell32.rbuild (original) +++ trunk/reactos/dll/win32/shell32/shell32.rbuild Tue Oct 23 13:01:39 2007 @@ -4,7 +4,6 @@ <include base="shell32">.</include> <include base="recyclebin">.</include> <include base="ReactOS">include/reactos/wine</include> - <define name="__USE_W32API" /> <define name="_WIN32_IE">0x600</define> <define name="_WIN32_WINNT">0x600</define> <define name="WINVER">0x600</define> @@ -39,6 +38,7 @@ <file>dialogs.c</file> <file>dragdrophelper.c</file> <file>enumidlist.c</file> + <file>extracticon.c</file> <file>folders.c</file> <file>iconcache.c</file> <file>pidl.c</file>
Modified: trunk/reactos/dll/win32/shell32/shell32.spec URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/shell32/shell32.s... ============================================================================== --- trunk/reactos/dll/win32/shell32/shell32.spec (original) +++ trunk/reactos/dll/win32/shell32/shell32.spec Tue Oct 23 13:01:39 2007 @@ -320,6 +320,8 @@ @ stdcall SHBrowseForFolderW(ptr) @ stdcall SHChangeNotify (long long ptr ptr) @ stub SHChangeNotifySuspendResume +@ stdcall SHCreateDefaultContextMenu(ptr ptr ptr) +@ stdcall SHCreateDefaultExtractIcon(ptr ptr) @ stdcall SHCreateDirectoryExA(long str ptr) @ stdcall SHCreateDirectoryExW(long wstr ptr) @ stub SHCreateProcessAsUserW