James Hawkins : fusion: The VersionLength member is not constant, so dynamically load the metadata header.
Alexandre Julliard
julliard at winehq.org
Wed Jul 16 13:33:04 CDT 2008
Module: wine
Branch: master
Commit: 8f985a338abcf9ed7dbf1c549f69a6a470c332c5
URL: http://source.winehq.org/git/wine.git/?a=commit;h=8f985a338abcf9ed7dbf1c549f69a6a470c332c5
Author: James Hawkins <jhawkins at 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;
More information about the wine-cvs
mailing list