shell32: Make SHGetDesktopFolder use a cached instance of IShellFolder.

This commit is contained in:
Dmitry Timoshkov 2007-06-21 23:50:55 +09:00 committed by Alexandre Julliard
parent 9a67bded8c
commit 013652feee
1 changed files with 27 additions and 41 deletions

View File

@ -117,30 +117,12 @@ static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
static ULONG WINAPI ISF_Desktop_fnAddRef (IShellFolder2 * iface)
{
IGenericSFImpl *This = (IGenericSFImpl *)iface;
ULONG refCount = InterlockedIncrement(&This->ref);
TRACE ("(%p)->(count=%u)\n", This, refCount - 1);
return refCount;
return 2; /* non-heap based object */
}
static ULONG WINAPI ISF_Desktop_fnRelease (IShellFolder2 * iface)
{
IGenericSFImpl *This = (IGenericSFImpl *)iface;
ULONG refCount = InterlockedDecrement(&This->ref);
TRACE ("(%p)->(count=%u)\n", This, refCount + 1);
if (!refCount)
{
TRACE ("-- destroying IShellFolder(%p)\n", This);
SHFree (This->pidlRoot);
SHFree (This->sPathTarget);
LocalFree ((HLOCAL) This);
return 0;
}
return refCount;
return 1; /* non-heap based object */
}
/**************************************************************************
@ -865,9 +847,8 @@ static const IShellFolder2Vtbl vt_MCFldr_ShellFolder2 =
HRESULT WINAPI ISF_Desktop_Constructor (
IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
{
IGenericSFImpl *sf;
static IGenericSFImpl *cached_sf;
WCHAR szMyPath[MAX_PATH];
HRESULT r;
TRACE ("unkOut=%p %s\n", pUnkOuter, shdebugstr_guid (riid));
@ -876,6 +857,10 @@ HRESULT WINAPI ISF_Desktop_Constructor (
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;
if (!cached_sf)
{
IGenericSFImpl *sf;
if (!SHGetSpecialFolderPathW( 0, szMyPath, CSIDL_DESKTOPDIRECTORY, TRUE ))
return E_UNEXPECTED;
@ -883,19 +868,20 @@ HRESULT WINAPI ISF_Desktop_Constructor (
if (!sf)
return E_OUTOFMEMORY;
sf->ref = 0;
sf->ref = 1;
sf->lpVtbl = &vt_MCFldr_ShellFolder2;
sf->pidlRoot = _ILCreateDesktop(); /* my qualified pidl */
sf->sPathTarget = SHAlloc( (lstrlenW(szMyPath) + 1)*sizeof(WCHAR) );
lstrcpyW( sf->sPathTarget, szMyPath );
r = IUnknown_QueryInterface( _IUnknown_(sf), riid, ppv );
if (!SUCCEEDED (r))
if (InterlockedCompareExchangePointer((void *)&cached_sf, sf, NULL) != NULL)
{
IUnknown_Release( _IUnknown_(sf) );
return r;
/* some other thread already been here */
SHFree( sf->pidlRoot );
SHFree( sf->sPathTarget );
LocalFree( sf );
}
}
TRACE ("--(%p)\n", sf);
return S_OK;
return IUnknown_QueryInterface( _IUnknown_(cached_sf), riid, ppv );
}