Commit 013652fe authored by Dmitry Timoshkov's avatar Dmitry Timoshkov Committed by Alexandre Julliard

shell32: Make SHGetDesktopFolder use a cached instance of IShellFolder.

parent 9a67bded
...@@ -117,30 +117,12 @@ static HRESULT WINAPI ISF_Desktop_fnQueryInterface( ...@@ -117,30 +117,12 @@ static HRESULT WINAPI ISF_Desktop_fnQueryInterface(
static ULONG WINAPI ISF_Desktop_fnAddRef (IShellFolder2 * iface) static ULONG WINAPI ISF_Desktop_fnAddRef (IShellFolder2 * iface)
{ {
IGenericSFImpl *This = (IGenericSFImpl *)iface; return 2; /* non-heap based object */
ULONG refCount = InterlockedIncrement(&This->ref);
TRACE ("(%p)->(count=%u)\n", This, refCount - 1);
return refCount;
} }
static ULONG WINAPI ISF_Desktop_fnRelease (IShellFolder2 * iface) static ULONG WINAPI ISF_Desktop_fnRelease (IShellFolder2 * iface)
{ {
IGenericSFImpl *This = (IGenericSFImpl *)iface; return 1; /* non-heap based object */
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;
} }
/************************************************************************** /**************************************************************************
...@@ -865,9 +847,8 @@ static const IShellFolder2Vtbl vt_MCFldr_ShellFolder2 = ...@@ -865,9 +847,8 @@ static const IShellFolder2Vtbl vt_MCFldr_ShellFolder2 =
HRESULT WINAPI ISF_Desktop_Constructor ( HRESULT WINAPI ISF_Desktop_Constructor (
IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv) IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
{ {
IGenericSFImpl *sf; static IGenericSFImpl *cached_sf;
WCHAR szMyPath[MAX_PATH]; WCHAR szMyPath[MAX_PATH];
HRESULT r;
TRACE ("unkOut=%p %s\n", pUnkOuter, shdebugstr_guid (riid)); TRACE ("unkOut=%p %s\n", pUnkOuter, shdebugstr_guid (riid));
...@@ -876,26 +857,31 @@ HRESULT WINAPI ISF_Desktop_Constructor ( ...@@ -876,26 +857,31 @@ HRESULT WINAPI ISF_Desktop_Constructor (
if (pUnkOuter) if (pUnkOuter)
return CLASS_E_NOAGGREGATION; return CLASS_E_NOAGGREGATION;
if (!SHGetSpecialFolderPathW( 0, szMyPath, CSIDL_DESKTOPDIRECTORY, TRUE )) if (!cached_sf)
return E_UNEXPECTED; {
IGenericSFImpl *sf;
sf = LocalAlloc( LMEM_ZEROINIT, sizeof (IGenericSFImpl) ); if (!SHGetSpecialFolderPathW( 0, szMyPath, CSIDL_DESKTOPDIRECTORY, TRUE ))
if (!sf) return E_UNEXPECTED;
return E_OUTOFMEMORY;
sf->ref = 0; sf = LocalAlloc( LMEM_ZEROINIT, sizeof (IGenericSFImpl) );
sf->lpVtbl = &vt_MCFldr_ShellFolder2; if (!sf)
sf->pidlRoot = _ILCreateDesktop(); /* my qualified pidl */ return E_OUTOFMEMORY;
sf->sPathTarget = SHAlloc( (lstrlenW(szMyPath) + 1)*sizeof(WCHAR) );
lstrcpyW( sf->sPathTarget, szMyPath );
r = IUnknown_QueryInterface( _IUnknown_(sf), riid, ppv ); sf->ref = 1;
if (!SUCCEEDED (r)) sf->lpVtbl = &vt_MCFldr_ShellFolder2;
{ sf->pidlRoot = _ILCreateDesktop(); /* my qualified pidl */
IUnknown_Release( _IUnknown_(sf) ); sf->sPathTarget = SHAlloc( (lstrlenW(szMyPath) + 1)*sizeof(WCHAR) );
return r; lstrcpyW( sf->sPathTarget, szMyPath );
if (InterlockedCompareExchangePointer((void *)&cached_sf, sf, NULL) != NULL)
{
/* some other thread already been here */
SHFree( sf->pidlRoot );
SHFree( sf->sPathTarget );
LocalFree( sf );
}
} }
TRACE ("--(%p)\n", sf); return IUnknown_QueryInterface( _IUnknown_(cached_sf), riid, ppv );
return S_OK;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment