ReactOS  0.4.15-dev-489-g75a0787
assembly.c
Go to the documentation of this file.
1 /*
2  * assembly parser
3  *
4  * Copyright 2008 James Hawkins
5  *
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.
10  *
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.
15  *
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
19  */
20 
21 #include "mscoree_private.h"
22 
23 #include <winver.h>
24 #include <dbghelp.h>
25 
26 typedef struct
27 {
32  ULONG VersionLength;
33  LPSTR Version;
34  BYTE Flags;
35  WORD Streams;
36 } METADATAHDR;
37 
38 typedef struct
39 {
40  DWORD Offset;
41  DWORD Size;
43 
44 typedef struct tagCLRTABLE
45 {
46  INT rows;
47  DWORD offset;
48 } CLRTABLE;
49 
50 struct tagASSEMBLY
51 {
53 
54  /* mapped files */
55  LPWSTR path;
56  HANDLE hfile;
57  HANDLE hmap;
58 
59  BYTE *data;
60 
63 
65 };
66 
67 static inline LPWSTR strdupW(LPCWSTR src)
68 {
69  LPWSTR dest;
70 
71  if (!src)
72  return NULL;
73 
74  dest = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(src) + 1) * sizeof(WCHAR));
75  if (dest)
76  lstrcpyW(dest, src);
77 
78  return dest;
79 }
80 
82 {
83  if (assembly->is_mapped_file)
84  return ImageRvaToVa(assembly->nthdr, assembly->data, rva, NULL);
85  else
86  return assembly->data + rva;
87 }
88 
90  IMAGE_DATA_DIRECTORY *datadir, void **data)
91 {
92  if (!datadir->VirtualAddress || !datadir->Size)
93  {
94  *data = NULL;
95  return 0;
96  }
97  else
98  {
100  return datadir->Size;
101  }
102 }
103 
105 {
106  METADATAHDR *metadatahdr;
107  BYTE *ptr, *dest;
108  DWORD size, ofs;
109  ULONG rva;
110 
111  rva = assembly->corhdr->MetaData.VirtualAddress;
113  if (!ptr)
114  return E_FAIL;
115 
116  metadatahdr = (METADATAHDR *)ptr;
117 
118  assembly->metadatahdr = HeapAlloc(GetProcessHeap(), 0, sizeof(METADATAHDR));
119  if (!assembly->metadatahdr)
120  return E_OUTOFMEMORY;
121 
123  memcpy(assembly->metadatahdr, metadatahdr, size);
124 
125  assembly->metadatahdr->Version = (LPSTR)&metadatahdr->Version;
126 
128  ptr += FIELD_OFFSET(METADATAHDR, Version) + metadatahdr->VersionLength + 1;
129  dest = (BYTE *)assembly->metadatahdr + ofs;
130  memcpy(dest, ptr, sizeof(METADATAHDR) - ofs);
131 
132  *hdrsz = sizeof(METADATAHDR) - sizeof(LPSTR) + metadatahdr->VersionLength + 1;
133 
134  return S_OK;
135 }
136 
138 {
139  HRESULT hr;
140  DWORD hdrsz;
141 
142  hr = parse_metadata_header(assembly, &hdrsz);
143  if (FAILED(hr))
144  return hr;
145 
146  return S_OK;
147 }
148 
150 {
151  IMAGE_DATA_DIRECTORY *datadirs;
152 
153  assembly->nthdr = ImageNtHeader(assembly->data);
154  if (!assembly->nthdr)
155  return E_FAIL;
156 
157  if (assembly->nthdr->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
158  {
159  IMAGE_OPTIONAL_HEADER64 *opthdr =
160  (IMAGE_OPTIONAL_HEADER64 *)&assembly->nthdr->OptionalHeader;
161  datadirs = opthdr->DataDirectory;
162  }
163  else
164  {
165  IMAGE_OPTIONAL_HEADER32 *opthdr =
166  (IMAGE_OPTIONAL_HEADER32 *)&assembly->nthdr->OptionalHeader;
167  datadirs = opthdr->DataDirectory;
168  }
169 
170  if (!datadirs)
171  return E_FAIL;
172 
174  return E_FAIL;
175 
176  return S_OK;
177 }
178 
180 {
181  HRESULT hr;
182 
184 
185  if (SUCCEEDED(hr))
187 
188  return hr;
189 }
190 
192 {
194  HRESULT hr;
195 
196  *out = NULL;
197 
199  if (!assembly)
200  return E_OUTOFMEMORY;
201 
202  assembly->is_mapped_file = 1;
203 
204  assembly->path = strdupW(file);
205  if (!assembly->path)
206  {
207  hr = E_OUTOFMEMORY;
208  goto failed;
209  }
210 
213  if (assembly->hfile == INVALID_HANDLE_VALUE)
214  {
216  goto failed;
217  }
218 
220  0, 0, NULL);
221  if (!assembly->hmap)
222  {
224  goto failed;
225  }
226 
227  assembly->data = MapViewOfFile(assembly->hmap, FILE_MAP_READ, 0, 0, 0);
228  if (!assembly->data)
229  {
231  goto failed;
232  }
233 
235  if (FAILED(hr)) goto failed;
236 
237  *out = assembly;
238  return S_OK;
239 
240 failed:
242  return hr;
243 }
244 
246 {
248  HRESULT hr;
249 
250  *out = NULL;
251 
253  if (!assembly)
254  return E_OUTOFMEMORY;
255 
256  assembly->is_mapped_file = 0;
257 
258  assembly->data = (BYTE*)hmodule;
259 
261  if (SUCCEEDED(hr))
262  *out = assembly;
263  else
265 
266  return hr;
267 }
268 
270 {
271  if (!assembly)
272  return S_OK;
273 
274  if (assembly->is_mapped_file)
275  {
276  UnmapViewOfFile(assembly->data);
277  CloseHandle(assembly->hmap);
278  CloseHandle(assembly->hfile);
279  }
280  HeapFree(GetProcessHeap(), 0, assembly->metadatahdr);
281  HeapFree(GetProcessHeap(), 0, assembly->path);
283 
284  return S_OK;
285 }
286 
288 {
289  *version = assembly->metadatahdr->Version;
290 
291  return S_OK;
292 }
293 
295 {
296  ULONG size;
297 
298  size = assembly_datadir_get_data(assembly, &assembly->corhdr->VTableFixups, (void**)fixups);
299  *count = size / sizeof(VTableFixup);
300 
301  return S_OK;
302 }
METADATAHDR * metadatahdr
Definition: assembly.c:65
#define CloseHandle
Definition: compat.h:407
IN PVOID IN PVOID IN USHORT Version
Definition: pci.h:361
ULONG MinorVersion
Definition: ros_glue.cpp:5
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntddk_ex.h:178
ULONG MajorVersion
Definition: ros_glue.cpp:4
INT rows
Definition: assembly.c:50
#define MapViewOfFile
Definition: compat.h:411
HRESULT hr
Definition: shlfolder.c:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
IMAGE_COR20_HEADER * corhdr
Definition: assembly.c:63
IMAGE_NT_HEADERS * nthdr
Definition: assembly.c:62
struct _VTableFixup VTableFixup
HRESULT assembly_get_runtime_version(ASSEMBLY *assembly, LPSTR *version)
Definition: assembly.c:865
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
Definition: ntimage.h:489
static HRESULT parse_metadata_header(ASSEMBLY *assembly, DWORD *hdrsz)
Definition: assembly.c:104
#define INVALID_HANDLE_VALUE
Definition: compat.h:400
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
BYTE * data
Definition: assembly.c:60
char * LPSTR
Definition: xmlstorage.h:182
#define lstrlenW
Definition: compat.h:416
#define E_FAIL
Definition: ddrawi.h:102
static struct _tagASSEMBLY assembly
int32_t INT
Definition: typedefs.h:57
#define FILE_SHARE_READ
Definition: compat.h:125
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
ULONG VersionLength
Definition: fusionpriv.h:48
static HMODULE hmodule
Definition: rasapi.c:29
static PVOID ptr
Definition: dispmode.c:27
smooth NULL
Definition: ftsmooth.c:416
static const WCHAR version[]
Definition: asmname.c:66
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
#define FILE_MAP_READ
Definition: compat.h:436
#define OPEN_EXISTING
Definition: compat.h:435
static HRESULT parse_headers(ASSEMBLY *assembly)
Definition: assembly.c:179
static void * assembly_rva_to_va(ASSEMBLY *assembly, ULONG rva)
Definition: assembly.c:81
GLsizeiptr size
Definition: glext.h:5919
#define GetProcessHeap()
Definition: compat.h:404
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
HRESULT assembly_get_vtable_fixups(ASSEMBLY *assembly, VTableFixup **fixups, DWORD *count)
Definition: assembly.c:294
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:78
#define CreateFileMappingW(a, b, c, d, e, f)
Definition: compat.h:410
unsigned short WORD
Definition: ntddk_ex.h:93
static FILE * out
Definition: regtests2xml.c:44
unsigned long DWORD
Definition: ntddk_ex.h:95
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC
Definition: ntimage.h:377
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
HANDLE hfile
Definition: assembly.c:58
static HRESULT parse_clr_metadata(ASSEMBLY *assembly)
Definition: assembly.c:137
HRESULT assembly_create(ASSEMBLY **out, LPCWSTR file)
Definition: assembly.c:641
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
HRESULT assembly_from_hmodule(ASSEMBLY **out, HMODULE hmodule)
Definition: assembly.c:245
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define GENERIC_READ
Definition: compat.h:124
GLenum src
Definition: glext.h:6340
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
unsigned char BYTE
Definition: xxhash.c:193
HRESULT assembly_release(ASSEMBLY *assembly)
Definition: assembly.c:694
#define S_OK
Definition: intsafe.h:59
struct tagCLRTABLE CLRTABLE
#define lstrcpyW
Definition: compat.h:415
unsigned short USHORT
Definition: pedump.c:61
static ULONG assembly_datadir_get_data(ASSEMBLY *assembly, IMAGE_DATA_DIRECTORY *datadir, void **data)
Definition: assembly.c:89
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
PVOID WINAPI ImageRvaToVa(_In_ PIMAGE_NT_HEADERS, _In_ PVOID, _In_ ULONG, _In_opt_ PIMAGE_SECTION_HEADER *)
HANDLE hmap
Definition: assembly.c:59
#define PAGE_READONLY
Definition: compat.h:127
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntimage.h:370
#define CreateFileW
Definition: compat.h:409
int is_mapped_file
Definition: assembly.c:52
DWORD offset
Definition: assembly.c:51
LPWSTR path
Definition: assembly.c:56
unsigned int ULONG
Definition: retypes.h:1
LPSTR Version
Definition: fusionpriv.h:49
PIMAGE_NT_HEADERS WINAPI ImageNtHeader(_In_ PVOID)
static char * dest
Definition: rtl.c:135
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define UnmapViewOfFile
Definition: compat.h:412
static const WCHAR Signature[]
Definition: parser.c:141
#define HeapFree(x, y, z)
Definition: compat.h:403
static LPWSTR strdupW(LPCWSTR src)
Definition: assembly.c:67
#define SUCCEEDED(hr)
Definition: intsafe.h:57
Definition: fci.c:126
static HRESULT parse_pe_header(ASSEMBLY *assembly)
Definition: assembly.c:149