mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
332 lines
10 KiB
332 lines
10 KiB
#include "shellprv.h"
|
|
#pragma hdrstop
|
|
|
|
//========================================================================
|
|
// CDefExtIcon Class definition
|
|
//========================================================================
|
|
typedef struct _CDefExtIcon // dxi
|
|
{
|
|
IExtractIcon xicon;
|
|
#ifdef UNICODE
|
|
IExtractIconA xiconA;
|
|
#endif
|
|
UINT cRef;
|
|
int iIcon;
|
|
int iIconOpen;
|
|
UINT uFlags; // GIL_SIMULATEDOC/PERINSTANCE/PERCLASS
|
|
TCHAR achModule[1];
|
|
} CDefExtIcon, FAR* LPDEFEXTICON;
|
|
|
|
//========================================================================
|
|
// CDefExtIcon Member function prototypes
|
|
//========================================================================
|
|
STDMETHODIMP CDefExtIcon_QueryInterface(LPEXTRACTICON pxicon, REFIID riid, LPVOID FAR* ppvObj);
|
|
STDMETHODIMP_(ULONG) CDefExtIcon_AddRef(LPEXTRACTICON pxicon);
|
|
STDMETHODIMP_(ULONG) CDefExtIcon_Release(LPEXTRACTICON pxicon);
|
|
STDMETHODIMP CDefExtIcon_GetIconLocation(LPEXTRACTICON pxicon,
|
|
UINT uFlags,
|
|
LPTSTR szIconFile,
|
|
UINT cchMax,
|
|
int * piIndex,
|
|
UINT * pwFlags);
|
|
|
|
STDMETHODIMP CDefExtIcon_ExtractIcon(LPEXTRACTICON pxicon,
|
|
LPCTSTR pszFile,
|
|
UINT nIconIndex,
|
|
HICON *phiconLarge,
|
|
HICON *phiconSmall,
|
|
UINT nIconSize);
|
|
|
|
#ifdef UNICODE
|
|
//========================================================================
|
|
// CDefExtIcon Member function prototypes
|
|
//========================================================================
|
|
STDMETHODIMP CDefExtIconA_QueryInterface(LPEXTRACTICONA pxiconA, REFIID riid, LPVOID FAR* ppvObj);
|
|
STDMETHODIMP_(ULONG) CDefExtIconA_AddRef(LPEXTRACTICONA pxiconA);
|
|
STDMETHODIMP_(ULONG) CDefExtIconA_Release(LPEXTRACTICONA pxiconA);
|
|
STDMETHODIMP CDefExtIconA_GetIconLocation(LPEXTRACTICONA pxiconA,
|
|
UINT uFlags,
|
|
LPSTR szIconFile,
|
|
UINT cchMax,
|
|
int * piIndex,
|
|
UINT * pwFlags);
|
|
|
|
STDMETHODIMP CDefExtIconA_ExtractIcon(LPEXTRACTICONA pxiconA,
|
|
LPCSTR pszFile,
|
|
UINT nIconIndex,
|
|
HICON *phiconLarge,
|
|
HICON *phiconSmall,
|
|
UINT nIconSize);
|
|
#endif
|
|
|
|
|
|
//========================================================================
|
|
// CDefExtIcon Vtable
|
|
//========================================================================
|
|
#pragma warning(error: 4090 4028 4047)
|
|
#pragma data_seg(".text", "CODE")
|
|
|
|
IExtractIconVtbl c_CDefExtIconVtbl = {
|
|
CDefExtIcon_QueryInterface,
|
|
CDefExtIcon_AddRef,
|
|
CDefExtIcon_Release,
|
|
CDefExtIcon_GetIconLocation,
|
|
CDefExtIcon_ExtractIcon,
|
|
};
|
|
|
|
#ifdef UNICODE
|
|
IExtractIconAVtbl c_CDefExtIconAVtbl = {
|
|
CDefExtIconA_QueryInterface,
|
|
CDefExtIconA_AddRef,
|
|
CDefExtIconA_Release,
|
|
CDefExtIconA_GetIconLocation,
|
|
CDefExtIconA_ExtractIcon,
|
|
};
|
|
#endif
|
|
|
|
#pragma data_seg()
|
|
#pragma warning(default: 4090 4028 4047)
|
|
|
|
//========================================================================
|
|
// CDefExtIcon constructor
|
|
//========================================================================
|
|
|
|
STDAPI SHCreateDefExtIcon(LPCTSTR pszModule, int iIcon, int iIconOpen, UINT uFlags, LPEXTRACTICON * pxiconOut)
|
|
{
|
|
return SHCreateDefExtIconKey(NULL, pszModule, iIcon, iIconOpen, uFlags, pxiconOut);
|
|
}
|
|
|
|
//========================================================================
|
|
// CDefExtIcon constructor
|
|
//========================================================================
|
|
|
|
STDAPI SHCreateDefExtIconKey(HKEY hkey, LPCTSTR pszModule, int iIcon, int iIconOpen,
|
|
UINT uFlags, LPEXTRACTICON * pxiconOut)
|
|
{
|
|
HRESULT hresSuccess = NOERROR;
|
|
HRESULT hres = ResultFromScode(E_OUTOFMEMORY); // assume error;
|
|
LPDEFEXTICON pdxi;
|
|
TCHAR szModule[MAX_PATH];
|
|
DWORD cb = SIZEOF(szModule);
|
|
|
|
if (hkey)
|
|
{
|
|
if (RegQueryValue(hkey, c_szDefaultIcon, szModule, &cb) == ERROR_SUCCESS && szModule[0])
|
|
{
|
|
iIcon = PathParseIconLocation(szModule);
|
|
iIconOpen = iIcon;
|
|
pszModule = szModule;
|
|
}
|
|
else
|
|
hresSuccess = S_FALSE;
|
|
}
|
|
|
|
if (pszModule == NULL)
|
|
{
|
|
// REVIEW: We should be able to make it faster!
|
|
GetModuleFileName(HINST_THISDLL, szModule, ARRAYSIZE(szModule));
|
|
pszModule = szModule;
|
|
}
|
|
|
|
pdxi = (void*)LocalAlloc(LPTR, SIZEOF(CDefExtIcon) + (lstrlen(pszModule) * SIZEOF(TCHAR)));
|
|
if (pdxi)
|
|
{
|
|
pdxi->xicon.lpVtbl = &c_CDefExtIconVtbl;
|
|
#ifdef UNICODE
|
|
pdxi->xiconA.lpVtbl = &c_CDefExtIconAVtbl;
|
|
#endif
|
|
pdxi->cRef = 1;
|
|
pdxi->iIcon = iIcon;
|
|
pdxi->iIconOpen = iIconOpen;
|
|
pdxi->uFlags = uFlags;
|
|
lstrcpy(pdxi->achModule, pszModule);
|
|
*pxiconOut = &pdxi->xicon;
|
|
hres = hresSuccess;
|
|
}
|
|
return hres;
|
|
}
|
|
|
|
//========================================================================
|
|
// CDefExtIcon members
|
|
//========================================================================
|
|
STDMETHODIMP CDefExtIcon_QueryInterface(LPEXTRACTICON pxicon, REFIID riid,
|
|
LPVOID FAR* ppvObj)
|
|
{
|
|
LPDEFEXTICON this = IToClass(CDefExtIcon, xicon, pxicon);
|
|
if (IsEqualIID(riid, &IID_IExtractIcon) || IsEqualIID(riid, &IID_IUnknown))
|
|
{
|
|
*ppvObj = pxicon;
|
|
this->cRef++;
|
|
return NOERROR;
|
|
}
|
|
#ifdef UNICODE
|
|
else if (IsEqualIID(riid, &IID_IExtractIconA))
|
|
{
|
|
*ppvObj = &this->xiconA;
|
|
this->cRef++;
|
|
return NOERROR;
|
|
}
|
|
#endif
|
|
|
|
*ppvObj = NULL;
|
|
return(ResultFromScode(E_NOINTERFACE));
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CDefExtIcon_AddRef(LPEXTRACTICON pxicon)
|
|
{
|
|
LPDEFEXTICON this = IToClass(CDefExtIcon, xicon, pxicon);
|
|
this->cRef++;
|
|
return this->cRef;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CDefExtIcon_Release(LPEXTRACTICON pxicon)
|
|
{
|
|
LPDEFEXTICON this = IToClass(CDefExtIcon, xicon, pxicon);
|
|
this->cRef--;
|
|
if (this->cRef > 0)
|
|
{
|
|
return this->cRef;
|
|
}
|
|
|
|
LocalFree((HLOCAL)this);
|
|
return 0;
|
|
}
|
|
|
|
STDMETHODIMP CDefExtIcon_GetIconLocation(LPEXTRACTICON pxicon,
|
|
UINT uFlags,
|
|
LPTSTR szIconFile,
|
|
UINT cchMax,
|
|
int * piIndex,
|
|
UINT * pwFlags)
|
|
{
|
|
LPDEFEXTICON this = IToClass(CDefExtIcon, xicon, pxicon);
|
|
HRESULT hres = ResultFromScode(S_FALSE);
|
|
int iIcon;
|
|
|
|
iIcon = (uFlags & GIL_OPENICON) ? this->iIconOpen : this->iIcon;
|
|
if (iIcon != (UINT)-1)
|
|
{
|
|
lstrcpyn(szIconFile, this->achModule, cchMax);
|
|
*piIndex = iIcon;
|
|
*pwFlags = this->uFlags;
|
|
hres = NOERROR;
|
|
}
|
|
|
|
return hres;
|
|
}
|
|
|
|
STDMETHODIMP CDefExtIcon_ExtractIcon(LPEXTRACTICON pxicon,
|
|
LPCTSTR pszFile,
|
|
UINT nIconIndex,
|
|
HICON *phiconLarge,
|
|
HICON *phiconSmall,
|
|
UINT nIconSize)
|
|
{
|
|
LPDEFEXTICON this = IToClass(CDefExtIcon, xicon, pxicon);
|
|
|
|
if (this->uFlags & GIL_NOTFILENAME)
|
|
{
|
|
//
|
|
// "*" as the file name means iIndex is already a system
|
|
// icon index, we are done.
|
|
//
|
|
// defview never calls us in this case, but external people will.
|
|
//
|
|
if (pszFile[0] == TEXT('*') && pszFile[1] == 0)
|
|
{
|
|
DebugMsg(DM_TRACE, TEXT("DefExtIcon::ExtractIcon handling '*' for backup"));
|
|
|
|
if (himlIcons == NULL)
|
|
{
|
|
FileIconInit( FALSE );
|
|
}
|
|
|
|
if (phiconLarge)
|
|
*phiconLarge = ImageList_GetIcon(himlIcons, nIconIndex, 0);
|
|
|
|
if (phiconSmall)
|
|
*phiconSmall = ImageList_GetIcon(himlIconsSmall, nIconIndex, 0);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
// this is the case where nIconIndex is a unique id for the
|
|
// file. always get the first icon.
|
|
|
|
nIconIndex = 0;
|
|
}
|
|
|
|
return SHDefExtractIcon(pszFile, nIconIndex, this->uFlags,
|
|
phiconLarge, phiconSmall, nIconSize);
|
|
}
|
|
|
|
#ifdef UNICODE
|
|
//========================================================================
|
|
// CDefExtIconA members
|
|
//========================================================================
|
|
STDMETHODIMP CDefExtIconA_QueryInterface(LPEXTRACTICONA pxiconA, REFIID riid,
|
|
LPVOID FAR* ppvObj)
|
|
{
|
|
LPDEFEXTICON this = IToClass(CDefExtIcon, xiconA, pxiconA);
|
|
return CDefExtIcon_QueryInterface(&this->xicon,riid,ppvObj);
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CDefExtIconA_AddRef(LPEXTRACTICONA pxiconA)
|
|
{
|
|
LPDEFEXTICON this = IToClass(CDefExtIcon, xiconA, pxiconA);
|
|
return CDefExtIcon_AddRef(&this->xicon);
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CDefExtIconA_Release(LPEXTRACTICONA pxiconA)
|
|
{
|
|
LPDEFEXTICON this = IToClass(CDefExtIcon, xiconA, pxiconA);
|
|
return CDefExtIcon_Release(&this->xicon);
|
|
}
|
|
|
|
STDMETHODIMP CDefExtIconA_GetIconLocation(LPEXTRACTICONA pxiconA,
|
|
UINT uFlags,
|
|
LPSTR pszIconFile,
|
|
UINT cchMax,
|
|
int * piIndex,
|
|
UINT * pwFlags)
|
|
{
|
|
WCHAR szIconFile[MAX_PATH];
|
|
LPDEFEXTICON this = IToClass(CDefExtIcon, xiconA, pxiconA);
|
|
HRESULT hres;
|
|
|
|
hres = CDefExtIcon_GetIconLocation(&this->xicon, uFlags,
|
|
szIconFile, ARRAYSIZE(szIconFile),
|
|
piIndex, pwFlags);
|
|
//
|
|
// We don't want to copy the icon file name on the S_FALSE case
|
|
//
|
|
if (SUCCEEDED(hres) && hres != S_FALSE)
|
|
{
|
|
WideCharToMultiByte(CP_ACP, 0,
|
|
szIconFile, -1,
|
|
pszIconFile, cchMax,
|
|
NULL, NULL);
|
|
}
|
|
return hres;
|
|
}
|
|
|
|
STDMETHODIMP CDefExtIconA_ExtractIcon(LPEXTRACTICONA pxiconA,
|
|
LPCSTR pszFile,
|
|
UINT nIconIndex,
|
|
HICON *phiconLarge,
|
|
HICON *phiconSmall,
|
|
UINT nIconSize)
|
|
{
|
|
WCHAR szFile[MAX_PATH];
|
|
LPDEFEXTICON this = IToClass(CDefExtIcon, xiconA, pxiconA);
|
|
|
|
Assert(pszFile != NULL);
|
|
|
|
MultiByteToWideChar(CP_ACP, 0,
|
|
pszFile, -1,
|
|
szFile, ARRAYSIZE(szFile));
|
|
return CDefExtIcon_ExtractIcon(&this->xicon,
|
|
szFile,nIconIndex,
|
|
phiconLarge,phiconSmall,nIconSize);
|
|
}
|
|
#endif
|