fusion: Also copy external files in IAssemblyCache::InstallAssembly.
This commit is contained in:
parent
9b34a3a75c
commit
45473a65a0
|
@ -370,6 +370,32 @@ static HRESULT WINAPI IAssemblyCacheImpl_CreateAssemblyScavenger(IAssemblyCache
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT copy_file( const WCHAR *src_dir, DWORD src_len, const WCHAR *dst_dir, DWORD dst_len,
|
||||||
|
const WCHAR *filename )
|
||||||
|
{
|
||||||
|
WCHAR *src_file, *dst_file;
|
||||||
|
DWORD len = strlenW( filename );
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
|
if (!(src_file = HeapAlloc( GetProcessHeap(), 0, (src_len + len + 1) * sizeof(WCHAR) )))
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
memcpy( src_file, src_dir, src_len * sizeof(WCHAR) );
|
||||||
|
strcpyW( src_file + src_len, filename );
|
||||||
|
|
||||||
|
if (!(dst_file = HeapAlloc( GetProcessHeap(), 0, (dst_len + len + 1) * sizeof(WCHAR) )))
|
||||||
|
{
|
||||||
|
HeapFree( GetProcessHeap(), 0, src_file );
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
memcpy( dst_file, dst_dir, dst_len * sizeof(WCHAR) );
|
||||||
|
strcpyW( dst_file + dst_len, filename );
|
||||||
|
|
||||||
|
if (!CopyFileW( src_file, dst_file, FALSE )) hr = HRESULT_FROM_WIN32( GetLastError() );
|
||||||
|
HeapFree( GetProcessHeap(), 0, src_file );
|
||||||
|
HeapFree( GetProcessHeap(), 0, dst_file );
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI IAssemblyCacheImpl_InstallAssembly(IAssemblyCache *iface,
|
static HRESULT WINAPI IAssemblyCacheImpl_InstallAssembly(IAssemblyCache *iface,
|
||||||
DWORD dwFlags,
|
DWORD dwFlags,
|
||||||
LPCWSTR pszManifestFilePath,
|
LPCWSTR pszManifestFilePath,
|
||||||
|
@ -383,11 +409,12 @@ static HRESULT WINAPI IAssemblyCacheImpl_InstallAssembly(IAssemblyCache *iface,
|
||||||
static const WCHAR ext_dll[] = {'.','d','l','l',0};
|
static const WCHAR ext_dll[] = {'.','d','l','l',0};
|
||||||
IAssemblyCacheImpl *cache = impl_from_IAssemblyCache(iface);
|
IAssemblyCacheImpl *cache = impl_from_IAssemblyCache(iface);
|
||||||
ASSEMBLY *assembly;
|
ASSEMBLY *assembly;
|
||||||
WCHAR *filename, *ext;
|
const WCHAR *extension, *filename, *src_dir;
|
||||||
WCHAR *name = NULL, *token = NULL, *version = NULL, *asmpath = NULL;
|
WCHAR *name = NULL, *token = NULL, *version = NULL, *asmpath = NULL;
|
||||||
WCHAR path[MAX_PATH], asmdir[MAX_PATH];
|
WCHAR asmdir[MAX_PATH], *p, **external_files = NULL, *dst_dir = NULL;
|
||||||
PEKIND architecture;
|
PEKIND architecture;
|
||||||
char *clr_version;
|
char *clr_version;
|
||||||
|
DWORD i, count = 0, src_len, dst_len = sizeof(format_v40)/sizeof(format_v40[0]);
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE("(%p, %d, %s, %p)\n", iface, dwFlags,
|
TRACE("(%p, %d, %s, %p)\n", iface, dwFlags,
|
||||||
|
@ -396,10 +423,10 @@ static HRESULT WINAPI IAssemblyCacheImpl_InstallAssembly(IAssemblyCache *iface,
|
||||||
if (!pszManifestFilePath || !*pszManifestFilePath)
|
if (!pszManifestFilePath || !*pszManifestFilePath)
|
||||||
return E_INVALIDARG;
|
return E_INVALIDARG;
|
||||||
|
|
||||||
if (!(ext = strrchrW(pszManifestFilePath, '.')))
|
if (!(extension = strrchrW(pszManifestFilePath, '.')))
|
||||||
return HRESULT_FROM_WIN32(ERROR_INVALID_NAME);
|
return HRESULT_FROM_WIN32(ERROR_INVALID_NAME);
|
||||||
|
|
||||||
if (lstrcmpiW(ext, ext_exe) && lstrcmpiW(ext, ext_dll))
|
if (lstrcmpiW(extension, ext_exe) && lstrcmpiW(extension, ext_dll))
|
||||||
return HRESULT_FROM_WIN32(ERROR_INVALID_NAME);
|
return HRESULT_FROM_WIN32(ERROR_INVALID_NAME);
|
||||||
|
|
||||||
if (GetFileAttributesW(pszManifestFilePath) == INVALID_FILE_ATTRIBUTES)
|
if (GetFileAttributesW(pszManifestFilePath) == INVALID_FILE_ATTRIBUTES)
|
||||||
|
@ -428,33 +455,63 @@ static HRESULT WINAPI IAssemblyCacheImpl_InstallAssembly(IAssemblyCache *iface,
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
hr = assembly_get_external_files(assembly, &external_files, &count);
|
||||||
|
if (FAILED(hr))
|
||||||
|
goto done;
|
||||||
|
|
||||||
cache_lock( cache );
|
cache_lock( cache );
|
||||||
|
|
||||||
architecture = assembly_get_architecture(assembly);
|
architecture = assembly_get_architecture(assembly);
|
||||||
get_assembly_directory(asmdir, MAX_PATH, clr_version, architecture);
|
get_assembly_directory(asmdir, MAX_PATH, clr_version, architecture);
|
||||||
|
|
||||||
|
dst_len += strlenW(asmdir) + strlenW(name) + strlenW(version) + strlenW(token);
|
||||||
|
if (!(dst_dir = HeapAlloc(GetProcessHeap(), 0, dst_len * sizeof(WCHAR))))
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
if (!strcmp(clr_version, "v4.0.30319"))
|
if (!strcmp(clr_version, "v4.0.30319"))
|
||||||
sprintfW(path, format_v40, asmdir, name, version, token);
|
dst_len = sprintfW(dst_dir, format_v40, asmdir, name, version, token);
|
||||||
else
|
else
|
||||||
sprintfW(path, format, asmdir, name, version, token);
|
dst_len = sprintfW(dst_dir, format, asmdir, name, version, token);
|
||||||
|
|
||||||
create_full_path(path);
|
create_full_path(dst_dir);
|
||||||
|
|
||||||
hr = assembly_get_path(assembly, &asmpath);
|
hr = assembly_get_path(assembly, &asmpath);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
filename = PathFindFileNameW(asmpath);
|
if ((p = strrchrW(asmpath, '\\')))
|
||||||
|
{
|
||||||
|
filename = p + 1;
|
||||||
|
src_dir = asmpath;
|
||||||
|
src_len = filename - asmpath;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
filename = asmpath;
|
||||||
|
src_dir = NULL;
|
||||||
|
src_len = 0;
|
||||||
|
}
|
||||||
|
hr = copy_file(src_dir, src_len, dst_dir, dst_len, filename);
|
||||||
|
if (FAILED(hr))
|
||||||
|
goto done;
|
||||||
|
|
||||||
strcatW(path, filename);
|
for (i = 0; i < count; i++)
|
||||||
if (!CopyFileW(asmpath, path, FALSE))
|
{
|
||||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
hr = copy_file(src_dir, src_len, dst_dir, dst_len, external_files[i]);
|
||||||
|
if (FAILED(hr))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
HeapFree(GetProcessHeap(), 0, name);
|
HeapFree(GetProcessHeap(), 0, name);
|
||||||
HeapFree(GetProcessHeap(), 0, token);
|
HeapFree(GetProcessHeap(), 0, token);
|
||||||
HeapFree(GetProcessHeap(), 0, version);
|
HeapFree(GetProcessHeap(), 0, version);
|
||||||
HeapFree(GetProcessHeap(), 0, asmpath);
|
HeapFree(GetProcessHeap(), 0, asmpath);
|
||||||
|
HeapFree(GetProcessHeap(), 0, dst_dir);
|
||||||
|
for (i = 0; i < count; i++) HeapFree(GetProcessHeap(), 0, external_files[i]);
|
||||||
|
HeapFree(GetProcessHeap(), 0, external_files);
|
||||||
assembly_release(assembly);
|
assembly_release(assembly);
|
||||||
cache_unlock( cache );
|
cache_unlock( cache );
|
||||||
return hr;
|
return hr;
|
||||||
|
|
|
@ -761,9 +761,9 @@ HRESULT assembly_get_name(ASSEMBLY *assembly, LPWSTR *name)
|
||||||
|
|
||||||
ptr += FIELD_OFFSET(ASSEMBLYTABLE, PublicKey) + assembly->blobsz;
|
ptr += FIELD_OFFSET(ASSEMBLYTABLE, PublicKey) + assembly->blobsz;
|
||||||
if (assembly->stringsz == sizeof(DWORD))
|
if (assembly->stringsz == sizeof(DWORD))
|
||||||
stridx = *((DWORD *)ptr);
|
stridx = *(DWORD *)ptr;
|
||||||
else
|
else
|
||||||
stridx = *((WORD *)ptr);
|
stridx = *(WORD *)ptr;
|
||||||
|
|
||||||
*name = assembly_dup_str(assembly, stridx);
|
*name = assembly_dup_str(assembly, stridx);
|
||||||
if (!*name)
|
if (!*name)
|
||||||
|
@ -912,3 +912,52 @@ HRESULT assembly_get_runtime_version(ASSEMBLY *assembly, LPSTR *version)
|
||||||
*version = assembly->metadatahdr->Version;
|
*version = assembly->metadatahdr->Version;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT assembly_get_external_files(ASSEMBLY *assembly, LPWSTR **files, DWORD *count)
|
||||||
|
{
|
||||||
|
LONG offset;
|
||||||
|
INT i, num_rows;
|
||||||
|
WCHAR **ret;
|
||||||
|
BYTE *ptr;
|
||||||
|
DWORD idx;
|
||||||
|
|
||||||
|
*count = 0;
|
||||||
|
|
||||||
|
offset = assembly->tables[TableFromToken(mdtFile)].offset;
|
||||||
|
if (offset == -1)
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
ptr = assembly_data_offset(assembly, offset);
|
||||||
|
if (!ptr)
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
num_rows = assembly->tables[TableFromToken(mdtFile)].rows;
|
||||||
|
if (num_rows <= 0)
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
ret = HeapAlloc(GetProcessHeap(), 0, num_rows * sizeof(WCHAR *));
|
||||||
|
if (!ret)
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
for (i = 0; i < num_rows; i++)
|
||||||
|
{
|
||||||
|
ptr += sizeof(DWORD); /* skip Flags field */
|
||||||
|
if (assembly->stringsz == sizeof(DWORD))
|
||||||
|
idx = *(DWORD *)ptr;
|
||||||
|
else
|
||||||
|
idx = *(WORD *)ptr;
|
||||||
|
|
||||||
|
ret[i] = assembly_dup_str(assembly, idx);
|
||||||
|
if (!ret[i])
|
||||||
|
{
|
||||||
|
for (; i >= 0; i--) HeapFree(GetProcessHeap(), 0, ret[i]);
|
||||||
|
HeapFree(GetProcessHeap(), 0, ret);
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
ptr += assembly->stringsz; /* skip Name field */
|
||||||
|
ptr += assembly->blobsz; /* skip Hash field */
|
||||||
|
}
|
||||||
|
*count = num_rows;
|
||||||
|
*files = ret;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
|
@ -436,6 +436,7 @@ HRESULT assembly_get_version(ASSEMBLY *assembly, LPWSTR *version) DECLSPEC_HIDDE
|
||||||
PEKIND assembly_get_architecture(ASSEMBLY *assembly) DECLSPEC_HIDDEN;
|
PEKIND assembly_get_architecture(ASSEMBLY *assembly) DECLSPEC_HIDDEN;
|
||||||
HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPWSTR *token) DECLSPEC_HIDDEN;
|
HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPWSTR *token) DECLSPEC_HIDDEN;
|
||||||
HRESULT assembly_get_runtime_version(ASSEMBLY *assembly, LPSTR *version) DECLSPEC_HIDDEN;
|
HRESULT assembly_get_runtime_version(ASSEMBLY *assembly, LPSTR *version) DECLSPEC_HIDDEN;
|
||||||
|
HRESULT assembly_get_external_files(ASSEMBLY *assembly, LPWSTR **files, DWORD *count) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
extern HRESULT IAssemblyName_SetPath(IAssemblyName *iface, LPCWSTR path) DECLSPEC_HIDDEN;
|
extern HRESULT IAssemblyName_SetPath(IAssemblyName *iface, LPCWSTR path) DECLSPEC_HIDDEN;
|
||||||
extern HRESULT IAssemblyName_GetPath(IAssemblyName *iface, LPWSTR buf, ULONG *len) DECLSPEC_HIDDEN;
|
extern HRESULT IAssemblyName_GetPath(IAssemblyName *iface, LPWSTR buf, ULONG *len) DECLSPEC_HIDDEN;
|
||||||
|
|
Loading…
Reference in New Issue