Commit 93f29250 authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

fusion: Add locking around operations on the assembly cache.

parent 6032b474
...@@ -41,6 +41,9 @@ ...@@ -41,6 +41,9 @@
WINE_DEFAULT_DEBUG_CHANNEL(fusion); WINE_DEFAULT_DEBUG_CHANNEL(fusion);
static const WCHAR cache_mutex_nameW[] =
{'_','_','W','I','N','E','_','F','U','S','I','O','N','_','C','A','C','H','E','_','M','U','T','E','X','_','_',0};
static BOOL create_full_path(LPCWSTR path) static BOOL create_full_path(LPCWSTR path)
{ {
LPWSTR new_path; LPWSTR new_path;
...@@ -126,6 +129,7 @@ typedef struct { ...@@ -126,6 +129,7 @@ typedef struct {
IAssemblyCache IAssemblyCache_iface; IAssemblyCache IAssemblyCache_iface;
LONG ref; LONG ref;
HANDLE lock;
} IAssemblyCacheImpl; } IAssemblyCacheImpl;
static inline IAssemblyCacheImpl *impl_from_IAssemblyCache(IAssemblyCache *iface) static inline IAssemblyCacheImpl *impl_from_IAssemblyCache(IAssemblyCache *iface)
...@@ -166,17 +170,29 @@ static ULONG WINAPI IAssemblyCacheImpl_AddRef(IAssemblyCache *iface) ...@@ -166,17 +170,29 @@ static ULONG WINAPI IAssemblyCacheImpl_AddRef(IAssemblyCache *iface)
static ULONG WINAPI IAssemblyCacheImpl_Release(IAssemblyCache *iface) static ULONG WINAPI IAssemblyCacheImpl_Release(IAssemblyCache *iface)
{ {
IAssemblyCacheImpl *This = impl_from_IAssemblyCache(iface); IAssemblyCacheImpl *cache = impl_from_IAssemblyCache(iface);
ULONG refCount = InterlockedDecrement(&This->ref); ULONG refCount = InterlockedDecrement( &cache->ref );
TRACE("(%p)->(ref before = %u)\n", This, refCount + 1); TRACE("(%p)->(ref before = %u)\n", cache, refCount + 1);
if (!refCount) if (!refCount)
HeapFree(GetProcessHeap(), 0, This); {
CloseHandle( cache->lock );
HeapFree( GetProcessHeap(), 0, cache );
}
return refCount; return refCount;
} }
static void cache_lock( IAssemblyCacheImpl *cache )
{
WaitForSingleObject( cache->lock, INFINITE );
}
static void cache_unlock( IAssemblyCacheImpl *cache )
{
ReleaseMutex( cache->lock );
}
static HRESULT WINAPI IAssemblyCacheImpl_UninstallAssembly(IAssemblyCache *iface, static HRESULT WINAPI IAssemblyCacheImpl_UninstallAssembly(IAssemblyCache *iface,
DWORD dwFlags, DWORD dwFlags,
LPCWSTR pszAssemblyName, LPCWSTR pszAssemblyName,
...@@ -184,6 +200,7 @@ static HRESULT WINAPI IAssemblyCacheImpl_UninstallAssembly(IAssemblyCache *iface ...@@ -184,6 +200,7 @@ static HRESULT WINAPI IAssemblyCacheImpl_UninstallAssembly(IAssemblyCache *iface
ULONG *pulDisposition) ULONG *pulDisposition)
{ {
HRESULT hr; HRESULT hr;
IAssemblyCacheImpl *cache = impl_from_IAssemblyCache(iface);
IAssemblyName *asmname, *next = NULL; IAssemblyName *asmname, *next = NULL;
IAssemblyEnum *asmenum = NULL; IAssemblyEnum *asmenum = NULL;
WCHAR *p, *path = NULL; WCHAR *p, *path = NULL;
...@@ -202,6 +219,8 @@ static HRESULT WINAPI IAssemblyCacheImpl_UninstallAssembly(IAssemblyCache *iface ...@@ -202,6 +219,8 @@ static HRESULT WINAPI IAssemblyCacheImpl_UninstallAssembly(IAssemblyCache *iface
if (FAILED( hr )) if (FAILED( hr ))
return hr; return hr;
cache_lock( cache );
hr = CreateAssemblyEnum( &asmenum, NULL, asmname, ASM_CACHE_GAC, NULL ); hr = CreateAssemblyEnum( &asmenum, NULL, asmname, ASM_CACHE_GAC, NULL );
if (FAILED( hr )) if (FAILED( hr ))
goto done; goto done;
...@@ -253,6 +272,7 @@ done: ...@@ -253,6 +272,7 @@ done:
if (next) IAssemblyName_Release( next ); if (next) IAssemblyName_Release( next );
if (asmenum) IAssemblyEnum_Release( asmenum ); if (asmenum) IAssemblyEnum_Release( asmenum );
HeapFree( GetProcessHeap(), 0, path ); HeapFree( GetProcessHeap(), 0, path );
cache_unlock( cache );
return hr; return hr;
} }
...@@ -261,6 +281,7 @@ static HRESULT WINAPI IAssemblyCacheImpl_QueryAssemblyInfo(IAssemblyCache *iface ...@@ -261,6 +281,7 @@ static HRESULT WINAPI IAssemblyCacheImpl_QueryAssemblyInfo(IAssemblyCache *iface
LPCWSTR pszAssemblyName, LPCWSTR pszAssemblyName,
ASSEMBLY_INFO *pAsmInfo) ASSEMBLY_INFO *pAsmInfo)
{ {
IAssemblyCacheImpl *cache = impl_from_IAssemblyCache(iface);
IAssemblyName *asmname, *next = NULL; IAssemblyName *asmname, *next = NULL;
IAssemblyEnum *asmenum = NULL; IAssemblyEnum *asmenum = NULL;
HRESULT hr; HRESULT hr;
...@@ -281,6 +302,8 @@ static HRESULT WINAPI IAssemblyCacheImpl_QueryAssemblyInfo(IAssemblyCache *iface ...@@ -281,6 +302,8 @@ static HRESULT WINAPI IAssemblyCacheImpl_QueryAssemblyInfo(IAssemblyCache *iface
if (FAILED(hr)) if (FAILED(hr))
return hr; return hr;
cache_lock( cache );
hr = CreateAssemblyEnum(&asmenum, NULL, asmname, ASM_CACHE_GAC, NULL); hr = CreateAssemblyEnum(&asmenum, NULL, asmname, ASM_CACHE_GAC, NULL);
if (FAILED(hr)) if (FAILED(hr))
goto done; goto done;
...@@ -303,7 +326,7 @@ done: ...@@ -303,7 +326,7 @@ done:
IAssemblyName_Release(asmname); IAssemblyName_Release(asmname);
if (next) IAssemblyName_Release(next); if (next) IAssemblyName_Release(next);
if (asmenum) IAssemblyEnum_Release(asmenum); if (asmenum) IAssemblyEnum_Release(asmenum);
cache_unlock( cache );
return hr; return hr;
} }
...@@ -331,9 +354,10 @@ static HRESULT WINAPI IAssemblyCacheImpl_InstallAssembly(IAssemblyCache *iface, ...@@ -331,9 +354,10 @@ static HRESULT WINAPI IAssemblyCacheImpl_InstallAssembly(IAssemblyCache *iface,
LPCWSTR pszManifestFilePath, LPCWSTR pszManifestFilePath,
LPCFUSION_INSTALL_REFERENCE pRefData) LPCFUSION_INSTALL_REFERENCE pRefData)
{ {
static const WCHAR format[] = static const WCHAR format[] = {'%','s','\\','%','s','\\','%','s','_','_','%','s','\\',0};
{'%','s','\\','%','s','\\','%','s','_','_','%','s','\\',0}; static const WCHAR ext_exe[] = {'.','e','x','e',0};
static const WCHAR ext_dll[] = {'.','d','l','l',0};
IAssemblyCacheImpl *cache = impl_from_IAssemblyCache(iface);
ASSEMBLY *assembly; ASSEMBLY *assembly;
LPWSTR filename; LPWSTR filename;
LPWSTR name = NULL; LPWSTR name = NULL;
...@@ -345,9 +369,6 @@ static HRESULT WINAPI IAssemblyCacheImpl_InstallAssembly(IAssemblyCache *iface, ...@@ -345,9 +369,6 @@ static HRESULT WINAPI IAssemblyCacheImpl_InstallAssembly(IAssemblyCache *iface,
LPWSTR ext; LPWSTR ext;
HRESULT hr; HRESULT hr;
static const WCHAR ext_exe[] = {'.','e','x','e',0};
static const WCHAR ext_dll[] = {'.','d','l','l',0};
TRACE("(%p, %d, %s, %p)\n", iface, dwFlags, TRACE("(%p, %d, %s, %p)\n", iface, dwFlags,
debugstr_w(pszManifestFilePath), pRefData); debugstr_w(pszManifestFilePath), pRefData);
...@@ -382,6 +403,8 @@ static HRESULT WINAPI IAssemblyCacheImpl_InstallAssembly(IAssemblyCache *iface, ...@@ -382,6 +403,8 @@ static HRESULT WINAPI IAssemblyCacheImpl_InstallAssembly(IAssemblyCache *iface,
if (FAILED(hr)) if (FAILED(hr))
goto done; goto done;
cache_lock( cache );
get_assembly_directory(asmdir, MAX_PATH, assembly_get_architecture(assembly)); get_assembly_directory(asmdir, MAX_PATH, assembly_get_architecture(assembly));
sprintfW(path, format, asmdir, name, version, token); sprintfW(path, format, asmdir, name, version, token);
...@@ -404,6 +427,7 @@ done: ...@@ -404,6 +427,7 @@ done:
HeapFree(GetProcessHeap(), 0, version); HeapFree(GetProcessHeap(), 0, version);
HeapFree(GetProcessHeap(), 0, asmpath); HeapFree(GetProcessHeap(), 0, asmpath);
assembly_release(assembly); assembly_release(assembly);
cache_unlock( cache );
return hr; return hr;
} }
...@@ -438,9 +462,13 @@ HRESULT WINAPI CreateAssemblyCache(IAssemblyCache **ppAsmCache, DWORD dwReserved ...@@ -438,9 +462,13 @@ HRESULT WINAPI CreateAssemblyCache(IAssemblyCache **ppAsmCache, DWORD dwReserved
cache->IAssemblyCache_iface.lpVtbl = &AssemblyCacheVtbl; cache->IAssemblyCache_iface.lpVtbl = &AssemblyCacheVtbl;
cache->ref = 1; cache->ref = 1;
cache->lock = CreateMutexW( NULL, FALSE, cache_mutex_nameW );
if (!cache->lock)
{
HeapFree( GetProcessHeap(), 0, cache );
return HRESULT_FROM_WIN32( GetLastError() );
}
*ppAsmCache = &cache->IAssemblyCache_iface; *ppAsmCache = &cache->IAssemblyCache_iface;
return S_OK; 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