Module: wine Branch: master Commit: 8f985a338abcf9ed7dbf1c549f69a6a470c332c5 URL: http://source.winehq.org/git/wine.git/?a=commit;h=8f985a338abcf9ed7dbf1c549f...
Author: James Hawkins jhawkins@codeweavers.com Date: Wed Jul 16 10:51:54 2008 -0500
fusion: The VersionLength member is not constant, so dynamically load the metadata header.
---
dlls/fusion/assembly.c | 49 ++++++++++++++++++++++++++++++++++++++------- dlls/fusion/fusionpriv.h | 6 ++-- 2 files changed, 44 insertions(+), 11 deletions(-)
diff --git a/dlls/fusion/assembly.c b/dlls/fusion/assembly.c index 5bc8725..56ad060 100644 --- a/dlls/fusion/assembly.c +++ b/dlls/fusion/assembly.c @@ -271,22 +271,54 @@ static HRESULT parse_clr_tables(ASSEMBLY *assembly, ULONG offset) return S_OK; }
+static HRESULT parse_metadata_header(ASSEMBLY *assembly, DWORD *hdrsz) +{ + METADATAHDR *metadatahdr; + BYTE *ptr, *dest; + DWORD size, ofs; + ULONG rva; + + rva = assembly->corhdr->MetaData.VirtualAddress; + ptr = ImageRvaToVa(assembly->nthdr, assembly->data, rva, NULL); + if (!ptr) + return E_FAIL; + + metadatahdr = (METADATAHDR *)ptr; + + assembly->metadatahdr = HeapAlloc(GetProcessHeap(), 0, sizeof(METADATAHDR)); + if (!assembly->metadatahdr) + return E_OUTOFMEMORY; + + size = FIELD_OFFSET(METADATAHDR, Version); + memcpy(assembly->metadatahdr, metadatahdr, size); + + /* we don't care about the version string */ + + ofs = FIELD_OFFSET(METADATAHDR, Flags); + ptr += FIELD_OFFSET(METADATAHDR, Version) + metadatahdr->VersionLength + 1; + dest = (BYTE *)assembly->metadatahdr + ofs; + memcpy(dest, ptr, sizeof(METADATAHDR) - ofs); + + *hdrsz = sizeof(METADATAHDR) - sizeof(LPSTR) + metadatahdr->VersionLength + 1; + + return S_OK; +} + static HRESULT parse_clr_metadata(ASSEMBLY *assembly) { METADATASTREAMHDR *streamhdr; ULONG rva, i, ofs; LPSTR stream; HRESULT hr; + DWORD hdrsz; BYTE *ptr;
- rva = assembly->corhdr->MetaData.VirtualAddress; - assembly->metadatahdr = ImageRvaToVa(assembly->nthdr, assembly->data, - rva, NULL); - if (!assembly->metadatahdr) - return E_FAIL; + hr = parse_metadata_header(assembly, &hdrsz); + if (FAILED(hr)) + return hr;
- ptr = ImageRvaToVa(assembly->nthdr, assembly->data, - rva + sizeof(METADATAHDR), NULL); + rva = assembly->corhdr->MetaData.VirtualAddress; + ptr = ImageRvaToVa(assembly->nthdr, assembly->data, rva + hdrsz, NULL); if (!ptr) return E_FAIL;
@@ -393,7 +425,7 @@ HRESULT assembly_create(ASSEMBLY **out, LPCWSTR file) return S_OK;
failed: - assembly_release( assembly ); + assembly_release(assembly); return hr; }
@@ -402,6 +434,7 @@ HRESULT assembly_release(ASSEMBLY *assembly) if (!assembly) return S_OK;
+ HeapFree(GetProcessHeap(), 0, assembly->metadatahdr); HeapFree(GetProcessHeap(), 0, assembly->path); UnmapViewOfFile(assembly->data); CloseHandle(assembly->hmap); diff --git a/dlls/fusion/fusionpriv.h b/dlls/fusion/fusionpriv.h index 08a2d5c..a4e6193 100644 --- a/dlls/fusion/fusionpriv.h +++ b/dlls/fusion/fusionpriv.h @@ -27,6 +27,8 @@ #include "winbase.h" #include "winuser.h"
+#include <pshpack1.h> + typedef struct { ULONG Signature; @@ -34,13 +36,11 @@ typedef struct USHORT MinorVersion; ULONG Reserved; ULONG VersionLength; - BYTE Version[12]; + LPSTR Version; BYTE Flags; WORD Streams; } METADATAHDR;
-#include <pshpack1.h> - typedef struct { DWORD Offset;