4 * Copyright 2008 James Hawkins
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #include "wine/list.h"
33 #include "mscoree_private.h"
35 #include "wine/debug.h"
36 #include "wine/unicode.h"
56 typedef struct tagCLRTABLE
70 IMAGE_NT_HEADERS
*nthdr
;
71 IMAGE_COR20_HEADER
*corhdr
;
73 METADATAHDR
*metadatahdr
;
76 static inline LPWSTR
strdupW(LPCWSTR src
)
83 dest
= HeapAlloc(GetProcessHeap(), 0, (lstrlenW(src
) + 1) * sizeof(WCHAR
));
90 static HRESULT
parse_metadata_header(ASSEMBLY
*assembly
, DWORD
*hdrsz
)
92 METADATAHDR
*metadatahdr
;
97 rva
= assembly
->corhdr
->MetaData
.VirtualAddress
;
98 ptr
= ImageRvaToVa(assembly
->nthdr
, assembly
->data
, rva
, NULL
);
102 metadatahdr
= (METADATAHDR
*)ptr
;
104 assembly
->metadatahdr
= HeapAlloc(GetProcessHeap(), 0, sizeof(METADATAHDR
));
105 if (!assembly
->metadatahdr
)
106 return E_OUTOFMEMORY
;
108 size
= FIELD_OFFSET(METADATAHDR
, Version
);
109 memcpy(assembly
->metadatahdr
, metadatahdr
, size
);
111 assembly
->metadatahdr
->Version
= (LPSTR
)&metadatahdr
->Version
;
113 ofs
= FIELD_OFFSET(METADATAHDR
, Flags
);
114 ptr
+= FIELD_OFFSET(METADATAHDR
, Version
) + metadatahdr
->VersionLength
+ 1;
115 dest
= (BYTE
*)assembly
->metadatahdr
+ ofs
;
116 memcpy(dest
, ptr
, sizeof(METADATAHDR
) - ofs
);
118 *hdrsz
= sizeof(METADATAHDR
) - sizeof(LPSTR
) + metadatahdr
->VersionLength
+ 1;
123 static HRESULT
parse_clr_metadata(ASSEMBLY
*assembly
)
128 hr
= parse_metadata_header(assembly
, &hdrsz
);
135 static HRESULT
parse_pe_header(ASSEMBLY
*assembly
)
137 IMAGE_DATA_DIRECTORY
*datadirs
;
139 assembly
->nthdr
= ImageNtHeader(assembly
->data
);
140 if (!assembly
->nthdr
)
143 if (assembly
->nthdr
->OptionalHeader
.Magic
== IMAGE_NT_OPTIONAL_HDR64_MAGIC
)
145 IMAGE_OPTIONAL_HEADER64
*opthdr
=
146 (IMAGE_OPTIONAL_HEADER64
*)&assembly
->nthdr
->OptionalHeader
;
147 datadirs
= opthdr
->DataDirectory
;
151 IMAGE_OPTIONAL_HEADER32
*opthdr
=
152 (IMAGE_OPTIONAL_HEADER32
*)&assembly
->nthdr
->OptionalHeader
;
153 datadirs
= opthdr
->DataDirectory
;
159 if (!datadirs
[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
].VirtualAddress
||
160 !datadirs
[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
].Size
)
165 assembly
->corhdr
= ImageRvaToVa(assembly
->nthdr
, assembly
->data
,
166 datadirs
[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
].VirtualAddress
, NULL
);
167 if (!assembly
->corhdr
)
173 HRESULT
assembly_create(ASSEMBLY
**out
, LPCWSTR file
)
180 assembly
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(ASSEMBLY
));
182 return E_OUTOFMEMORY
;
184 assembly
->path
= strdupW(file
);
191 assembly
->hfile
= CreateFileW(file
, GENERIC_READ
, FILE_SHARE_READ
,
192 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
193 if (assembly
->hfile
== INVALID_HANDLE_VALUE
)
195 hr
= HRESULT_FROM_WIN32(GetLastError());
199 assembly
->hmap
= CreateFileMappingW(assembly
->hfile
, NULL
, PAGE_READONLY
,
203 hr
= HRESULT_FROM_WIN32(GetLastError());
207 assembly
->data
= MapViewOfFile(assembly
->hmap
, FILE_MAP_READ
, 0, 0, 0);
210 hr
= HRESULT_FROM_WIN32(GetLastError());
214 hr
= parse_pe_header(assembly
);
215 if (FAILED(hr
)) goto failed
;
217 hr
= parse_clr_metadata(assembly
);
218 if (FAILED(hr
)) goto failed
;
224 assembly_release(assembly
);
228 HRESULT
assembly_release(ASSEMBLY
*assembly
)
233 HeapFree(GetProcessHeap(), 0, assembly
->metadatahdr
);
234 HeapFree(GetProcessHeap(), 0, assembly
->path
);
235 UnmapViewOfFile(assembly
->data
);
236 CloseHandle(assembly
->hmap
);
237 CloseHandle(assembly
->hfile
);
238 HeapFree(GetProcessHeap(), 0, assembly
);
243 HRESULT
assembly_get_runtime_version(ASSEMBLY
*assembly
, LPSTR
*version
)
245 *version
= assembly
->metadatahdr
->Version
;