shell32: Make SHGetDesktopFolder use a cached instance of IShellFolder.
This commit is contained in:
parent
9a67bded8c
commit
013652feee
|
@ -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 =
|
||||||
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,6 +857,10 @@ HRESULT WINAPI ISF_Desktop_Constructor (
|
||||||
if (pUnkOuter)
|
if (pUnkOuter)
|
||||||
return CLASS_E_NOAGGREGATION;
|
return CLASS_E_NOAGGREGATION;
|
||||||
|
|
||||||
|
if (!cached_sf)
|
||||||
|
{
|
||||||
|
IGenericSFImpl *sf;
|
||||||
|
|
||||||
if (!SHGetSpecialFolderPathW( 0, szMyPath, CSIDL_DESKTOPDIRECTORY, TRUE ))
|
if (!SHGetSpecialFolderPathW( 0, szMyPath, CSIDL_DESKTOPDIRECTORY, TRUE ))
|
||||||
return E_UNEXPECTED;
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
|
@ -883,19 +868,20 @@ HRESULT WINAPI ISF_Desktop_Constructor (
|
||||||
if (!sf)
|
if (!sf)
|
||||||
return E_OUTOFMEMORY;
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
sf->ref = 0;
|
sf->ref = 1;
|
||||||
sf->lpVtbl = &vt_MCFldr_ShellFolder2;
|
sf->lpVtbl = &vt_MCFldr_ShellFolder2;
|
||||||
sf->pidlRoot = _ILCreateDesktop(); /* my qualified pidl */
|
sf->pidlRoot = _ILCreateDesktop(); /* my qualified pidl */
|
||||||
sf->sPathTarget = SHAlloc( (lstrlenW(szMyPath) + 1)*sizeof(WCHAR) );
|
sf->sPathTarget = SHAlloc( (lstrlenW(szMyPath) + 1)*sizeof(WCHAR) );
|
||||||
lstrcpyW( sf->sPathTarget, szMyPath );
|
lstrcpyW( sf->sPathTarget, szMyPath );
|
||||||
|
|
||||||
r = IUnknown_QueryInterface( _IUnknown_(sf), riid, ppv );
|
if (InterlockedCompareExchangePointer((void *)&cached_sf, sf, NULL) != NULL)
|
||||||
if (!SUCCEEDED (r))
|
|
||||||
{
|
{
|
||||||
IUnknown_Release( _IUnknown_(sf) );
|
/* some other thread already been here */
|
||||||
return r;
|
SHFree( sf->pidlRoot );
|
||||||
|
SHFree( sf->sPathTarget );
|
||||||
|
LocalFree( sf );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE ("--(%p)\n", sf);
|
return IUnknown_QueryInterface( _IUnknown_(cached_sf), riid, ppv );
|
||||||
return S_OK;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue