From c6d34d7b05aec8dae05c2db7093af43cd085a3c5 Mon Sep 17 00:00:00 2001 From: Owen Rudge Date: Mon, 19 Jul 2010 19:33:19 +0100 Subject: [PATCH] fusion: Install assemblies into correct directory for architecture. --- dlls/fusion/asmcache.c | 27 ++++++++++++++++++++++----- dlls/fusion/assembly.c | 14 ++++++++++++++ dlls/fusion/fusionpriv.h | 1 + 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/dlls/fusion/asmcache.c b/dlls/fusion/asmcache.c index f35de7f142a..7334e5d793e 100644 --- a/dlls/fusion/asmcache.c +++ b/dlls/fusion/asmcache.c @@ -91,15 +91,32 @@ static BOOL create_full_path(LPCWSTR path) return ret; } -static BOOL get_assembly_directory(LPWSTR dir, DWORD size) +static BOOL get_assembly_directory(LPWSTR dir, DWORD size, BYTE architecture) { - static const WCHAR gac[] = - {'\\','a','s','s','e','m','b','l','y','\\','G','A','C','_','M','S','I','L',0}; + static const WCHAR gac[] = {'\\','a','s','s','e','m','b','l','y','\\','G','A','C',0}; - FIXME("Ignoring assembly architecture\n"); + static const WCHAR msil[] = {'_','M','S','I','L',0}; + static const WCHAR x86[] = {'_','3','2',0}; + static const WCHAR amd64[] = {'_','6','4',0}; GetWindowsDirectoryW(dir, size); strcatW(dir, gac); + + switch (architecture) + { + case peMSIL: + strcatW(dir, msil); + break; + + case peI386: + strcatW(dir, x86); + break; + + case peAMD64: + strcatW(dir, amd64); + break; + } + return TRUE; } @@ -291,7 +308,7 @@ static HRESULT WINAPI IAssemblyCacheImpl_InstallAssembly(IAssemblyCache *iface, if (FAILED(hr)) goto done; - get_assembly_directory(asmdir, MAX_PATH); + get_assembly_directory(asmdir, MAX_PATH, assembly_get_architecture(assembly)); sprintfW(path, format, asmdir, name, version, token); diff --git a/dlls/fusion/assembly.c b/dlls/fusion/assembly.c index bc187ac91cd..328b2792c9c 100644 --- a/dlls/fusion/assembly.c +++ b/dlls/fusion/assembly.c @@ -811,6 +811,20 @@ HRESULT assembly_get_version(ASSEMBLY *assembly, LPWSTR *version) return S_OK; } +BYTE assembly_get_architecture(ASSEMBLY *assembly) +{ + if ((assembly->corhdr->MajorRuntimeVersion == 2) && (assembly->corhdr->MinorRuntimeVersion == 0)) + return 0; /* .NET 1.x assembly */ + + if (assembly->nthdr->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) + return peAMD64; /* AMD64/IA64 assembly */ + + if ((assembly->corhdr->Flags & COMIMAGE_FLAGS_ILONLY) && !(assembly->corhdr->Flags & COMIMAGE_FLAGS_32BITREQUIRED)) + return peMSIL; /* MSIL assembly */ + + return peI386; /* x86 assembly */ +} + static BYTE *assembly_get_blob(ASSEMBLY *assembly, WORD index, ULONG *size) { return GetData(&assembly->blobs[index], size); diff --git a/dlls/fusion/fusionpriv.h b/dlls/fusion/fusionpriv.h index 4b9bd576d5b..6f4b28dc793 100644 --- a/dlls/fusion/fusionpriv.h +++ b/dlls/fusion/fusionpriv.h @@ -433,6 +433,7 @@ HRESULT assembly_release(ASSEMBLY *assembly); HRESULT assembly_get_name(ASSEMBLY *assembly, LPWSTR *name); HRESULT assembly_get_path(ASSEMBLY *assembly, LPWSTR *path); HRESULT assembly_get_version(ASSEMBLY *assembly, LPWSTR *version); +BYTE assembly_get_architecture(ASSEMBLY *assembly); HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPWSTR *token); static inline LPWSTR strdupW(LPCWSTR src)