ReactOS  0.4.13-dev-479-gec9c8fd
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 <stdarg.h>
22 #include <stdio.h>
23 
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27 #include "winver.h"
28 #include "wincrypt.h"
29 #include "dbghelp.h"
30 #include "ole2.h"
31 #include "fusion.h"
32 #include "corhdr.h"
33 
34 #include "fusionpriv.h"
35 #include "wine/debug.h"
36 #include "wine/unicode.h"
37 
38 #define TableFromToken(tk) (TypeFromToken(tk) >> 24)
39 #define TokenFromTable(idx) (idx << 24)
40 
41 #define MAX_CLR_TABLES 64
42 
43 #define MD_STRINGS_BIT 0x1
44 #define MD_GUIDS_BIT 0x2
45 #define MD_BLOBS_BIT 0x4
46 
47 typedef struct tagCLRTABLE
48 {
51 } CLRTABLE;
52 
54 {
56 
60 
63 
65 
70 
74 
77 };
78 
80 {
81  DWORD offset = rva, limit;
83  WORD i;
84 
85  img = IMAGE_FIRST_SECTION(nthdrs);
86 
87  if (rva < img->PointerToRawData)
88  return rva;
89 
90  for (i = 0; i < nthdrs->FileHeader.NumberOfSections; i++)
91  {
92  if (img[i].SizeOfRawData)
93  limit = img[i].SizeOfRawData;
94  else
95  limit = img[i].Misc.VirtualSize;
96 
97  if (rva >= img[i].VirtualAddress &&
98  rva < (img[i].VirtualAddress + limit))
99  {
100  if (img[i].PointerToRawData != 0)
101  {
102  offset -= img[i].VirtualAddress;
103  offset += img[i].PointerToRawData;
104  }
105 
106  return offset;
107  }
108  }
109 
110  return 0;
111 }
112 
113 static BYTE *GetData(BYTE *pData, ULONG *pLength)
114 {
115  if ((*pData & 0x80) == 0x00)
116  {
117  *pLength = (*pData & 0x7f);
118  return pData + 1;
119  }
120 
121  if ((*pData & 0xC0) == 0x80)
122  {
123  *pLength = ((*pData & 0x3f) << 8 | *(pData + 1));
124  return pData + 2;
125  }
126 
127  if ((*pData & 0xE0) == 0xC0)
128  {
129  *pLength = ((*pData & 0x1f) << 24 | *(pData + 1) << 16 |
130  *(pData + 2) << 8 | *(pData + 3));
131  return pData + 4;
132  }
133 
134  *pLength = (ULONG)-1;
135  return 0;
136 }
137 
139 {
140  return &assembly->data[offset];
141 }
142 
143 #define MAX_TABLES_WORD 0xFFFF
144 #define MAX_TABLES_1BIT_ENCODE 32767
145 #define MAX_TABLES_2BIT_ENCODE 16383
146 #define MAX_TABLES_3BIT_ENCODE 8191
147 #define MAX_TABLES_5BIT_ENCODE 2047
148 
150 {
151  DWORD size;
152  INT tables;
153 
154  switch (TokenFromTable(index))
155  {
156  case mdtModule:
157  {
158  size = sizeof(MODULETABLE) + (assembly->stringsz - sizeof(WORD)) +
159  2 * (assembly->guidsz - sizeof(WORD));
160  break;
161  }
162  case mdtTypeRef:
163  {
164  size = sizeof(TYPEREFTABLE) + 2 * (assembly->stringsz - sizeof(WORD));
165 
166  /* ResolutionScope:ResolutionScope */
167  tables = max(assembly->tables[TableFromToken(mdtModule)].rows,
168  assembly->tables[TableFromToken(mdtModuleRef)].rows);
170  tables = max(tables, assembly->tables[TableFromToken(mdtTypeRef)].rows);
171  size += (tables > MAX_TABLES_2BIT_ENCODE) ? sizeof(WORD) : 0;
172  break;
173  }
174  case mdtTypeDef:
175  {
176  size = sizeof(TYPEDEFTABLE) + 2 * (assembly->stringsz - sizeof(WORD));
177 
178  /* Extends:TypeDefOrRef */
179  tables = max(assembly->tables[TableFromToken(mdtTypeDef)].rows,
180  assembly->tables[TableFromToken(mdtTypeRef)].rows);
181  tables = max(tables, assembly->tables[TableFromToken(mdtTypeSpec)].rows);
182  size += (tables > MAX_TABLES_2BIT_ENCODE) ? sizeof(WORD) : 0;
183 
184  size += (assembly->tables[TableFromToken(mdtFieldDef)].rows >
185  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
186  size += (assembly->tables[TableFromToken(mdtMethodDef)].rows >
187  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
188  break;
189  }
190  case mdtFieldDef:
191  {
192  size = sizeof(FIELDTABLE) + (assembly->stringsz - sizeof(WORD)) +
193  (assembly->blobsz - sizeof(WORD));
194  break;
195  }
196  case mdtMethodDef:
197  {
198  size = sizeof(METHODDEFTABLE) + (assembly->stringsz - sizeof(WORD)) +
199  (assembly->blobsz - sizeof(WORD));
200 
201  size += (assembly->tables[TableFromToken(mdtParamDef)].rows >
202  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
203  break;
204  }
205  case mdtParamDef:
206  {
207  size = sizeof(PARAMTABLE) + (assembly->stringsz - sizeof(WORD));
208  break;
209  }
210  case mdtInterfaceImpl:
211  {
212  size = sizeof(INTERFACEIMPLTABLE);
213 
214  /* Interface:TypeDefOrRef */
215  tables = max(assembly->tables[TableFromToken(mdtTypeDef)].rows,
216  assembly->tables[TableFromToken(mdtTypeRef)].rows);
217  tables = max(tables, assembly->tables[TableFromToken(mdtTypeSpec)].rows);
218  size += (tables > MAX_TABLES_2BIT_ENCODE) ? sizeof(WORD) : 0;
219  break;
220  }
221  case mdtMemberRef:
222  {
223  size = sizeof(MEMBERREFTABLE) + (assembly->stringsz - sizeof(WORD)) +
224  (assembly->blobsz - sizeof(WORD));
225 
226  /* Class:MemberRefParent */
227  tables = max(assembly->tables[TableFromToken(mdtTypeRef)].rows,
228  assembly->tables[TableFromToken(mdtModuleRef)].rows);
230  tables = max(tables, assembly->tables[TableFromToken(mdtTypeSpec)].rows);
231  tables = max(tables, assembly->tables[TableFromToken(mdtTypeDef)].rows);
232  size += (tables > MAX_TABLES_3BIT_ENCODE) ? sizeof(WORD) : 0;
233  break;
234  }
235  case 0x0B000000: /* FIXME */
236  {
237  size = sizeof(CONSTANTTABLE) + (assembly->blobsz - sizeof(WORD));
238 
239  /* Parent:HasConstant */
240  tables = max(assembly->tables[TableFromToken(mdtParamDef)].rows,
241  assembly->tables[TableFromToken(mdtFieldDef)].rows);
242  tables = max(tables, assembly->tables[TableFromToken(mdtProperty)].rows);
243  size += (tables > MAX_TABLES_2BIT_ENCODE) ? sizeof(WORD) : 0;
244  break;
245  }
246  case mdtCustomAttribute:
247  {
248  size = sizeof(CUSTOMATTRIBUTETABLE) + (assembly->blobsz - sizeof(WORD));
249 
250  /* Parent:HasCustomAttribute */
251  tables = max(assembly->tables[TableFromToken(mdtMethodDef)].rows,
252  assembly->tables[TableFromToken(mdtFieldDef)].rows);
253  tables = max(tables, assembly->tables[TableFromToken(mdtTypeRef)].rows);
254  tables = max(tables, assembly->tables[TableFromToken(mdtTypeDef)].rows);
255  tables = max(tables, assembly->tables[TableFromToken(mdtParamDef)].rows);
259  tables = max(tables, assembly->tables[TableFromToken(mdtProperty)].rows);
260  tables = max(tables, assembly->tables[TableFromToken(mdtEvent)].rows);
263  tables = max(tables, assembly->tables[TableFromToken(mdtTypeSpec)].rows);
264  tables = max(tables, assembly->tables[TableFromToken(mdtAssembly)].rows);
265  tables = max(tables, assembly->tables[TableFromToken(mdtFile)].rows);
268  size += (tables > MAX_TABLES_5BIT_ENCODE) ? sizeof(WORD) : 0;
269 
270  /* Type:CustomAttributeType */
271  tables = max(assembly->tables[TableFromToken(mdtMethodDef)].rows,
272  assembly->tables[TableFromToken(mdtMemberRef)].rows);
273  size += (tables > MAX_TABLES_3BIT_ENCODE) ? sizeof(WORD) : 0;
274  break;
275  }
276  case 0x0D000000: /* FIXME */
277  {
278  size = sizeof(FIELDMARSHALTABLE) + (assembly->blobsz - sizeof(WORD));
279 
280  /* Parent:HasFieldMarshal */
281  tables = max(assembly->tables[TableFromToken(mdtFieldDef)].rows,
282  assembly->tables[TableFromToken(mdtParamDef)].rows);
283  size += (tables > MAX_TABLES_1BIT_ENCODE) ? sizeof(WORD) : 0;
284  break;
285  }
286  case mdtPermission:
287  {
288  size = sizeof(DECLSECURITYTABLE) + (assembly->blobsz - sizeof(WORD));
289 
290  /* Parent:HasDeclSecurity */
291  tables = max(assembly->tables[TableFromToken(mdtTypeDef)].rows,
292  assembly->tables[TableFromToken(mdtMethodDef)].rows);
293  tables = max(tables, assembly->tables[TableFromToken(mdtAssembly)].rows);
294  size += (tables > MAX_TABLES_2BIT_ENCODE) ? sizeof(WORD) : 0;
295  break;
296  }
297  case 0x0F000000: /* FIXME */
298  {
299  size = sizeof(CLASSLAYOUTTABLE);
300  size += (assembly->tables[TableFromToken(mdtTypeDef)].rows >
301  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
302  break;
303  }
304  case 0x10000000: /* FIXME */
305  {
306  size = sizeof(FIELDLAYOUTTABLE);
307  size += (assembly->tables[TableFromToken(mdtFieldDef)].rows >
308  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
309  break;
310  }
311  case mdtSignature:
312  {
313  size = sizeof(STANDALONESIGTABLE) + (assembly->blobsz - sizeof(WORD));
314  break;
315  }
316  case 0x12000000: /* FIXME */
317  {
318  size = sizeof(EVENTMAPTABLE);
319  size += (assembly->tables[TableFromToken(mdtTypeDef)].rows >
320  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
321  size += (assembly->tables[TableFromToken(mdtEvent)].rows >
322  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
323  break;
324  }
325  case mdtEvent:
326  {
327  size = sizeof(EVENTTABLE) + (assembly->stringsz - sizeof(WORD));
328 
329  /* EventType:TypeDefOrRef */
330  tables = max(assembly->tables[TableFromToken(mdtTypeDef)].rows,
331  assembly->tables[TableFromToken(mdtTypeRef)].rows);
332  tables = max(tables, assembly->tables[TableFromToken(mdtTypeSpec)].rows);
333  size += (tables > MAX_TABLES_2BIT_ENCODE) ? sizeof(WORD) : 0;
334  break;
335  }
336  case 0x15000000:/* FIXME */
337  {
338  size = sizeof(PROPERTYMAPTABLE);
339  size += (assembly->tables[TableFromToken(mdtTypeDef)].rows >
340  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
341  size += (assembly->tables[TableFromToken(mdtProperty)].rows >
342  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
343  break;
344  }
345  case mdtProperty:
346  {
347  size = sizeof(PROPERTYTABLE) + (assembly->stringsz - sizeof(WORD)) +
348  (assembly->blobsz - sizeof(WORD));
349  break;
350  }
351  case 0x18000000: /* FIXME */
352  {
353  size = sizeof(METHODSEMANTICSTABLE);
354 
355  /* Association:HasSemantics */
356  tables = max(assembly->tables[TableFromToken(mdtEvent)].rows,
357  assembly->tables[TableFromToken(mdtProperty)].rows);
358  size += (tables > MAX_TABLES_1BIT_ENCODE) ? sizeof(WORD) : 0;
359 
360  size += (assembly->tables[TableFromToken(mdtMethodDef)].rows >
361  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
362  break;
363  }
364  case 0x19000000: /* FIXME */
365  {
366  size = sizeof(METHODIMPLTABLE);
367 
368  /* MethodBody:MethodDefOrRef, MethodDeclaration:MethodDefOrRef */
369  tables = max(assembly->tables[TableFromToken(mdtMethodDef)].rows,
370  assembly->tables[TableFromToken(mdtMemberRef)].rows);
371  size += (tables > MAX_TABLES_1BIT_ENCODE) ? 2 * sizeof(WORD) : 0;
372 
373  size += (assembly->tables[TableFromToken(mdtTypeDef)].rows >
374  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
375  break;
376  }
377  case mdtModuleRef:
378  {
379  size = sizeof(MODULEREFTABLE) + (assembly->stringsz - sizeof(WORD));
380  break;
381  }
382  case mdtTypeSpec:
383  {
384  size = sizeof(TYPESPECTABLE) + (assembly->blobsz - sizeof(WORD));
385  break;
386  }
387  case 0x1C000000: /* FIXME */
388  {
389  size = sizeof(IMPLMAPTABLE) + (assembly->stringsz - sizeof(WORD));
390 
391  /* MemberForwarded:MemberForwarded */
392  tables = max(assembly->tables[TableFromToken(mdtFieldDef)].rows,
393  assembly->tables[TableFromToken(mdtMethodDef)].rows);
394  size += (tables > MAX_TABLES_1BIT_ENCODE) ? sizeof(WORD) : 0;
395 
396  size += (assembly->tables[TableFromToken(mdtModuleRef)].rows >
397  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
398  break;
399  }
400  case 0x1D000000: /* FIXME */
401  {
402  size = sizeof(FIELDRVATABLE);
403  size += (assembly->tables[TableFromToken(mdtFieldDef)].rows >
404  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
405  break;
406  }
407  case mdtAssembly:
408  {
409  size = sizeof(ASSEMBLYTABLE) + 2 * (assembly->stringsz - sizeof(WORD)) +
410  (assembly->blobsz - sizeof(WORD));
411  break;
412  }
413  case 0x20000001: /* FIXME */
414  {
415  size = sizeof(ASSEMBLYPROCESSORTABLE);
416  break;
417  }
418  case 0x22000000: /* FIXME */
419  {
420  size = sizeof(ASSEMBLYOSTABLE);
421  break;
422  }
423  case mdtAssemblyRef:
424  {
425  size = sizeof(ASSEMBLYREFTABLE) + 2 * (assembly->stringsz - sizeof(WORD)) +
426  2 * (assembly->blobsz - sizeof(WORD));
427  break;
428  }
429  case 0x24000000: /* FIXME */
430  {
432  size += (assembly->tables[TableFromToken(mdtAssemblyRef)].rows >
433  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
434  break;
435  }
436  case 0x25000000: /* FIXME */
437  {
438  size = sizeof(ASSEMBLYREFOSTABLE);
439  size += (assembly->tables[TableFromToken(mdtAssemblyRef)].rows >
440  MAX_TABLES_WORD) ? sizeof(WORD) : 0;
441  break;
442  }
443  case mdtFile:
444  {
445  size = sizeof(FILETABLE) + (assembly->stringsz - sizeof(WORD)) +
446  (assembly->blobsz - sizeof(WORD));
447  break;
448  }
449  case mdtExportedType:
450  {
451  size = sizeof(EXPORTEDTYPETABLE) + 2 * (assembly->stringsz - sizeof(WORD));
452 
453  /* Implementation:Implementation */
454  tables = max(assembly->tables[TableFromToken(mdtFile)].rows,
455  assembly->tables[TableFromToken(mdtMethodDef)].rows);
456  size += (tables > MAX_TABLES_2BIT_ENCODE) ? sizeof(WORD) : 0;
457  break;
458  }
459  case mdtManifestResource:
460  {
461  size = sizeof(MANIFESTRESTABLE) + (assembly->stringsz - sizeof(WORD));
462 
463  /* Implementation:Implementation */
464  tables = max(assembly->tables[TableFromToken(mdtFile)].rows,
465  assembly->tables[TableFromToken(mdtAssemblyRef)].rows);
466  size += (tables > MAX_TABLES_2BIT_ENCODE) ? sizeof(WORD) : 0;
467  break;
468  }
469  case 0x29000000: /* FIXME */
470  {
471  size = sizeof(NESTEDCLASSTABLE);
472  size += (assembly->tables[TableFromToken(mdtTypeDef)].rows >
473  MAX_TABLES_WORD) ? 2 * sizeof(WORD) : 0;
474  break;
475  }
476  default:
477  return 0;
478  }
479 
480  return size;
481 }
482 
484 {
485  DWORD i, count;
486  ULONG currofs;
487  ULONGLONG mask;
488 
489  currofs = offset;
490  assembly->tableshdr = assembly_data_offset(assembly, currofs);
491  if (!assembly->tableshdr)
492  return E_FAIL;
493 
494  assembly->stringsz = (assembly->tableshdr->HeapOffsetSizes & MD_STRINGS_BIT) ?
495  sizeof(DWORD) : sizeof(WORD);
496  assembly->guidsz = (assembly->tableshdr->HeapOffsetSizes & MD_GUIDS_BIT) ?
497  sizeof(DWORD) : sizeof(WORD);
498  assembly->blobsz = (assembly->tableshdr->HeapOffsetSizes & MD_BLOBS_BIT) ?
499  sizeof(DWORD) : sizeof(WORD);
500 
501  currofs += sizeof(METADATATABLESHDR);
502  assembly->numrows = assembly_data_offset(assembly, currofs);
503  if (!assembly->numrows)
504  return E_FAIL;
505 
506  memset(assembly->tables, -1, MAX_CLR_TABLES * sizeof(CLRTABLE));
507 
508  for (i = count = 0, mask = 1; i < MAX_CLR_TABLES; i++, mask <<= 1)
509  {
510  if (assembly->tableshdr->MaskValid.QuadPart & mask)
511  assembly->tables[i].rows = assembly->numrows[count++];
512  }
513  assembly->numtables = count;
514  currofs += assembly->numtables * sizeof(DWORD);
515 
516  for (i = 0, mask = 1; i < MAX_CLR_TABLES; i++, mask <<= 1)
517  {
518  if (assembly->tableshdr->MaskValid.QuadPart & mask)
519  {
520  assembly->tables[i].offset = currofs;
521  currofs += get_table_size(assembly, i) * assembly->tables[i].rows;
522  }
523  }
524 
525  return S_OK;
526 }
527 
529 {
530  METADATAHDR *metadatahdr;
531  BYTE *ptr, *dest;
532  DWORD size, ofs;
533  ULONG rva;
534 
535  rva = assembly->corhdr->MetaData.VirtualAddress;
536  ptr = ImageRvaToVa(assembly->nthdr, assembly->data, rva, NULL);
537  if (!ptr)
538  return E_FAIL;
539 
540  metadatahdr = (METADATAHDR *)ptr;
541 
542  if (!(assembly->metadatahdr = heap_alloc(sizeof(*assembly->metadatahdr)))) return E_OUTOFMEMORY;
543 
545  memcpy(assembly->metadatahdr, metadatahdr, size);
546 
547  assembly->metadatahdr->Version = (LPSTR)&metadatahdr->Version;
548 
550  ptr += FIELD_OFFSET(METADATAHDR, Version) + metadatahdr->VersionLength + 1;
551  dest = (BYTE *)assembly->metadatahdr + ofs;
552  memcpy(dest, ptr, sizeof(METADATAHDR) - ofs);
553 
554  *hdrsz = sizeof(METADATAHDR) - sizeof(LPSTR) + metadatahdr->VersionLength + 1;
555 
556  return S_OK;
557 }
558 
560 {
561  METADATASTREAMHDR *streamhdr;
562  ULONG rva, i, ofs;
563  LPSTR stream;
564  HRESULT hr;
565  DWORD hdrsz;
566  BYTE *ptr;
567 
568  hr = parse_metadata_header(assembly, &hdrsz);
569  if (FAILED(hr))
570  return hr;
571 
572  rva = assembly->corhdr->MetaData.VirtualAddress;
573  ptr = ImageRvaToVa(assembly->nthdr, assembly->data, rva + hdrsz, NULL);
574  if (!ptr)
575  return E_FAIL;
576 
577  for (i = 0; i < assembly->metadatahdr->Streams; i++)
578  {
579  streamhdr = (METADATASTREAMHDR *)ptr;
580  ofs = rva_to_offset(assembly->nthdr, rva + streamhdr->Offset);
581 
582  ptr += sizeof(METADATASTREAMHDR);
583  stream = (LPSTR)ptr;
584 
585  if (!lstrcmpA(stream, "#~"))
586  {
587  hr = parse_clr_tables(assembly, ofs);
588  if (FAILED(hr))
589  return hr;
590  }
591  else if (!lstrcmpA(stream, "#Strings") || !lstrcmpA(stream, "Strings"))
592  assembly->strings = assembly_data_offset(assembly, ofs);
593  else if (!lstrcmpA(stream, "#Blob") || !lstrcmpA(stream, "Blob"))
594  assembly->blobs = assembly_data_offset(assembly, ofs);
595 
596  ptr += ((lstrlenA(stream) + 1) + 3) & ~3; /* align on DWORD boundary */
597  }
598 
599  return S_OK;
600 }
601 
603 {
604  IMAGE_DATA_DIRECTORY *datadirs;
605 
606  assembly->nthdr = ImageNtHeader(assembly->data);
607  if (!assembly->nthdr)
608  return E_FAIL;
609 
610  if (assembly->nthdr->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
611  {
612  IMAGE_OPTIONAL_HEADER64 *opthdr =
613  (IMAGE_OPTIONAL_HEADER64 *)&assembly->nthdr->OptionalHeader;
614  datadirs = opthdr->DataDirectory;
615  }
616  else
617  {
618  IMAGE_OPTIONAL_HEADER32 *opthdr =
619  (IMAGE_OPTIONAL_HEADER32 *)&assembly->nthdr->OptionalHeader;
620  datadirs = opthdr->DataDirectory;
621  }
622 
623  if (!datadirs)
624  return E_FAIL;
625 
628  {
629  return E_FAIL;
630  }
631 
632  assembly->corhdr = ImageRvaToVa(assembly->nthdr, assembly->data,
634  if (!assembly->corhdr)
635  return E_FAIL;
636 
637  return S_OK;
638 }
639 
641 {
643  HRESULT hr;
644 
645  *out = NULL;
646 
647  if (!(assembly = heap_alloc_zero(sizeof(*assembly)))) return E_OUTOFMEMORY;
648 
649  assembly->path = strdupW(file);
650  if (!assembly->path)
651  {
652  hr = E_OUTOFMEMORY;
653  goto failed;
654  }
655 
658  if (assembly->hfile == INVALID_HANDLE_VALUE)
659  {
661  goto failed;
662  }
663 
665  0, 0, NULL);
666  if (!assembly->hmap)
667  {
669  goto failed;
670  }
671 
672  assembly->data = MapViewOfFile(assembly->hmap, FILE_MAP_READ, 0, 0, 0);
673  if (!assembly->data)
674  {
676  goto failed;
677  }
678 
680  if (FAILED(hr)) goto failed;
681 
683  if (FAILED(hr)) goto failed;
684 
685  *out = assembly;
686  return S_OK;
687 
688 failed:
690  return hr;
691 }
692 
694 {
695  if (!assembly)
696  return S_OK;
697 
698  heap_free(assembly->metadatahdr);
699  heap_free(assembly->path);
700  UnmapViewOfFile(assembly->data);
701  CloseHandle(assembly->hmap);
702  CloseHandle(assembly->hfile);
704 
705  return S_OK;
706 }
707 
709 {
710  int len;
711  LPWSTR cpy;
712  LPCSTR str = (LPCSTR)&assembly->strings[index];
713 
714  len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
715 
716  if ((cpy = heap_alloc(len * sizeof(WCHAR))))
717  MultiByteToWideChar(CP_ACP, 0, str, -1, cpy, len);
718 
719  return cpy;
720 }
721 
723 {
724  BYTE *ptr;
725  LONG offset;
726  DWORD stridx;
727 
728  offset = assembly->tables[TableFromToken(mdtAssembly)].offset;
729  if (offset == -1)
730  return E_FAIL;
731 
733  if (!ptr)
734  return E_FAIL;
735 
736  ptr += FIELD_OFFSET(ASSEMBLYTABLE, PublicKey) + assembly->blobsz;
737  if (assembly->stringsz == sizeof(DWORD))
738  stridx = *(DWORD *)ptr;
739  else
740  stridx = *(WORD *)ptr;
741 
742  *name = assembly_dup_str(assembly, stridx);
743  if (!*name)
744  return E_OUTOFMEMORY;
745 
746  return S_OK;
747 }
748 
750 {
751  WCHAR *cpy = heap_alloc((strlenW(assembly->path) + 1) * sizeof(WCHAR));
752  *path = cpy;
753  if (cpy)
754  strcpyW(cpy, assembly->path);
755  else
756  return E_OUTOFMEMORY;
757 
758  return S_OK;
759 }
760 
762 {
763  static const WCHAR format[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
764 
765  ASSEMBLYTABLE *asmtbl;
766  LONG offset;
767 
768  *version = NULL;
769 
770  offset = assembly->tables[TableFromToken(mdtAssembly)].offset;
771  if (offset == -1)
772  return E_FAIL;
773 
775  if (!asmtbl)
776  return E_FAIL;
777 
778  if (!(*version = heap_alloc(sizeof(format) + 4 * strlen("65535") * sizeof(WCHAR))))
779  return E_OUTOFMEMORY;
780 
781  sprintfW(*version, format, asmtbl->MajorVersion, asmtbl->MinorVersion,
782  asmtbl->BuildNumber, asmtbl->RevisionNumber);
783 
784  return S_OK;
785 }
786 
788 {
789  if ((assembly->corhdr->MajorRuntimeVersion == 2) && (assembly->corhdr->MinorRuntimeVersion == 0))
790  return peNone; /* .NET 1.x assembly */
791 
792  if (assembly->nthdr->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
793  return peAMD64; /* AMD64/IA64 assembly */
794 
795  if ((assembly->corhdr->Flags & COMIMAGE_FLAGS_ILONLY) && !(assembly->corhdr->Flags & COMIMAGE_FLAGS_32BITREQUIRED))
796  return peMSIL; /* MSIL assembly */
797 
798  return peI386; /* x86 assembly */
799 }
800 
802 {
803  return GetData(&assembly->blobs[index], size);
804 }
805 
807 {
808  ULONG i, size;
809  LONG offset;
810  BYTE *hashdata, *pubkey, *ptr;
811  HCRYPTPROV crypt;
813  BYTE tokbytes[BYTES_PER_TOKEN];
814  HRESULT hr = E_FAIL;
815  LPWSTR tok;
816  DWORD idx;
817 
818  *token = NULL;
819 
820  offset = assembly->tables[TableFromToken(mdtAssembly)].offset;
821  if (offset == -1)
822  return E_FAIL;
823 
825  if (!ptr)
826  return E_FAIL;
827 
828  ptr += FIELD_OFFSET(ASSEMBLYTABLE, PublicKey);
829  if (assembly->blobsz == sizeof(DWORD))
830  idx = *(DWORD *)ptr;
831  else
832  idx = *(WORD *)ptr;
833 
835 
838  return E_FAIL;
839 
840  if (!CryptCreateHash(crypt, CALG_SHA1, 0, 0, &hash))
841  return E_FAIL;
842 
843  if (!CryptHashData(hash, pubkey, size, 0))
844  return E_FAIL;
845 
846  size = 0;
848  return E_FAIL;
849 
850  if (!(hashdata = heap_alloc(size)))
851  {
852  hr = E_OUTOFMEMORY;
853  goto done;
854  }
855 
856  if (!CryptGetHashParam(hash, HP_HASHVAL, hashdata, &size, 0))
857  goto done;
858 
859  for (i = size - 1; i >= size - 8; i--)
860  tokbytes[size - i - 1] = hashdata[i];
861 
862  if (!(tok = heap_alloc((TOKEN_LENGTH + 1) * sizeof(WCHAR))))
863  {
864  hr = E_OUTOFMEMORY;
865  goto done;
866  }
867 
868  token_to_str(tokbytes, tok);
869 
870  *token = tok;
871  hr = S_OK;
872 
873 done:
874  heap_free(hashdata);
876  CryptReleaseContext(crypt, 0);
877 
878  return hr;
879 }
880 
882 {
883  *version = assembly->metadatahdr->Version;
884  return S_OK;
885 }
886 
888 {
889  LONG offset;
890  INT i, num_rows;
891  WCHAR **ret;
892  BYTE *ptr;
893  DWORD idx;
894 
895  *count = 0;
896 
897  offset = assembly->tables[TableFromToken(mdtFile)].offset;
898  if (offset == -1)
899  return S_OK;
900 
902  if (!ptr)
903  return S_OK;
904 
905  num_rows = assembly->tables[TableFromToken(mdtFile)].rows;
906  if (num_rows <= 0)
907  return S_OK;
908 
909  if (!(ret = heap_alloc(num_rows * sizeof(WCHAR *)))) return E_OUTOFMEMORY;
910 
911  for (i = 0; i < num_rows; i++)
912  {
913  ptr += sizeof(DWORD); /* skip Flags field */
914  if (assembly->stringsz == sizeof(DWORD))
915  idx = *(DWORD *)ptr;
916  else
917  idx = *(WORD *)ptr;
918 
920  if (!ret[i])
921  {
922  for (; i >= 0; i--) heap_free(ret[i]);
923  heap_free(ret);
924  return E_OUTOFMEMORY;
925  }
926  ptr += assembly->stringsz; /* skip Name field */
927  ptr += assembly->blobsz; /* skip Hash field */
928  }
929  *count = num_rows;
930  *files = ret;
931  return S_OK;
932 }
WORD RevisionNumber
Definition: fusionpriv.h:107
static DWORD rva_to_offset(IMAGE_NT_HEADERS *nthdrs, DWORD rva)
Definition: assembly.c:79
METADATAHDR * metadatahdr
Definition: assembly.c:64
static HRESULT parse_metadata_header(ASSEMBLY *assembly, DWORD *hdrsz)
Definition: assembly.c:528
HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPWSTR *token)
Definition: assembly.c:806
static void token_to_str(BYTE *bytes, LPWSTR str)
Definition: fusionpriv.h:467
#define max(a, b)
Definition: svc.c:63
static VOID * assembly_data_offset(ASSEMBLY *assembly, ULONG offset)
Definition: assembly.c:138
Definition: corhdr.h:41
HRESULT assembly_get_path(const ASSEMBLY *assembly, LPWSTR *path)
Definition: assembly.c:749
#define CloseHandle
Definition: compat.h:398
IN PVOID IN PVOID IN USHORT Version
Definition: pci.h:359
#define MD_STRINGS_BIT
Definition: assembly.c:43
struct tagEVENTTABLE EVENTTABLE
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntddk_ex.h:178
INT rows
Definition: assembly.c:49
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
#define MapViewOfFile
Definition: compat.h:402
HRESULT hr
Definition: shlfolder.c:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define MAX_CLR_TABLES
Definition: assembly.c:41
IMAGE_COR20_HEADER * corhdr
Definition: assembly.c:62
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
IMAGE_NT_HEADERS * nthdr
Definition: assembly.c:61
#define MAX_TABLES_WORD
Definition: assembly.c:143
static const WCHAR pubkey[]
Definition: asmname.c:66
#define CP_ACP
Definition: compat.h:99
HRESULT assembly_get_runtime_version(ASSEMBLY *assembly, LPSTR *version)
Definition: assembly.c:881
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR
Definition: ntimage.h:489
HRESULT assembly_get_name(ASSEMBLY *assembly, LPWSTR *name)
Definition: assembly.c:722
GLintptr offset
Definition: glext.h:5920
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
BYTE * data
Definition: assembly.c:59
PEKIND assembly_get_architecture(ASSEMBLY *assembly)
Definition: assembly.c:787
#define TableFromToken(tk)
Definition: assembly.c:38
char * LPSTR
Definition: xmlstorage.h:182
#define E_FAIL
Definition: ddrawi.h:102
static struct _tagASSEMBLY assembly
static DWORD
Definition: assembly.c:34
int32_t INT
Definition: typedefs.h:56
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
#define FILE_SHARE_READ
Definition: compat.h:125
GLint limit
Definition: glext.h:10326
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
BYTE * strings
Definition: assembly.c:75
GLenum GLint GLuint mask
Definition: glext.h:6028
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
BOOL WINAPI CryptGetHashParam(HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, DWORD *pdwDataLen, DWORD dwFlags)
Definition: crypt.c:1615
int hash
Definition: main.c:58
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
long LONG
Definition: pedump.c:60
static ULONG get_table_size(const ASSEMBLY *assembly, DWORD index)
Definition: assembly.c:149
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat token
Definition: glfuncs.h:210
ULONG VersionLength
Definition: fusionpriv.h:45
static PVOID ptr
Definition: dispmode.c:27
static BYTE * assembly_get_blob(ASSEMBLY *assembly, DWORD index, ULONG *size)
Definition: assembly.c:801
unsigned int idx
Definition: utils.c:41
WORD BuildNumber
Definition: fusionpriv.h:106
const WCHAR * str
DWORD blobsz
Definition: assembly.c:73
smooth NULL
Definition: ftsmooth.c:416
static const WCHAR version[]
Definition: asmname.c:64
#define MAX_TABLES_5BIT_ENCODE
Definition: assembly.c:147
BYTE * blobs
Definition: assembly.c:76
#define FILE_MAP_READ
Definition: compat.h:427
GLuint index
Definition: glext.h:6031
const char * LPCSTR
Definition: xmlstorage.h:183
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
#define OPEN_EXISTING
Definition: compat.h:426
DWORD guidsz
Definition: assembly.c:72
#define MAX_TABLES_3BIT_ENCODE
Definition: assembly.c:146
GLsizeiptr size
Definition: glext.h:5919
DWORD numtables
Definition: assembly.c:67
__wchar_t WCHAR
Definition: xmlstorage.h:180
GLint GLvoid * img
Definition: gl.h:1956
LONG HRESULT
Definition: typedefs.h:77
#define CreateFileMappingW(a, b, c, d, e, f)
Definition: compat.h:401
uint64_t ULONGLONG
Definition: typedefs.h:65
WORD MajorVersion
Definition: fusionpriv.h:104
int JSAMPARRAY int int num_rows
Definition: jpegint.h:412
unsigned short WORD
Definition: ntddk_ex.h:93
static FILE * out
Definition: regtests2xml.c:44
unsigned long DWORD
Definition: ntddk_ex.h:95
static HRESULT parse_clr_metadata(ASSEMBLY *assembly)
Definition: assembly.c:559
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC
Definition: ntimage.h:377
HANDLE hfile
Definition: assembly.c:57
BOOL WINAPI CryptDestroyHash(HCRYPTHASH hHash)
Definition: crypt.c:895
HRESULT assembly_create(ASSEMBLY **out, LPCWSTR file)
Definition: assembly.c:640
int ret
PEKIND
Definition: fusion.idl:35
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
Definition: parse.h:22
GLuint GLuint stream
Definition: glext.h:7522
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
unsigned char BYTE
Definition: mem.h:68
BOOL WINAPI CryptCreateHash(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, DWORD dwFlags, HCRYPTHASH *phHash)
Definition: crypt.c:745
#define GENERIC_READ
Definition: compat.h:124
#define MD_GUIDS_BIT
Definition: assembly.c:44
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3791
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
static HRESULT parse_clr_tables(ASSEMBLY *assembly, ULONG offset)
Definition: assembly.c:483
#define CRYPT_VERIFYCONTEXT
Definition: wincrypt.h:2069
HRESULT assembly_release(ASSEMBLY *assembly)
Definition: assembly.c:693
ULONG_PTR HCRYPTHASH
Definition: wincrypt.h:50
#define MD_BLOBS_BIT
Definition: assembly.c:45
HRESULT assembly_get_version(ASSEMBLY *assembly, LPWSTR *version)
Definition: assembly.c:761
#define S_OK
Definition: intsafe.h:59
WINE_UNICODE_INLINE WCHAR * strcpyW(WCHAR *dst, const WCHAR *src)
Definition: unicode.h:219
struct tagCLRTABLE CLRTABLE
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
ULONG_PTR HCRYPTPROV
Definition: wincrypt.h:46
#define TokenFromTable(idx)
Definition: assembly.c:39
WORD MinorVersion
Definition: fusionpriv.h:105
static BYTE * GetData(BYTE *pData, ULONG *pLength)
Definition: assembly.c:113
DWORD * numrows
Definition: assembly.c:68
CLRTABLE tables[MAX_CLR_TABLES]
Definition: assembly.c:69
Definition: services.c:325
#define sprintfW
Definition: unicode.h:58
BOOL WINAPI CryptHashData(HCRYPTHASH hHash, const BYTE *pbData, DWORD dwDataLen, DWORD dwFlags)
Definition: crypt.c:1776
#define CALG_SHA1
Definition: wincrypt.h:1807
#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:58
#define PAGE_READONLY
Definition: compat.h:127
BOOL WINAPI CryptAcquireContextA(HCRYPTPROV *phProv, LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType, DWORD dwFlags)
Definition: crypt.c:569
DWORD stringsz
Definition: assembly.c:71
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntimage.h:370
#define BYTES_PER_TOKEN
Definition: fusionpriv.h:463
static HRESULT parse_pe_header(ASSEMBLY *assembly)
Definition: assembly.c:602
#define MultiByteToWideChar
Definition: compat.h:100
#define CreateFileW
Definition: compat.h:400
DWORD offset
Definition: assembly.c:50
BOOL WINAPI CryptReleaseContext(HCRYPTPROV hProv, ULONG_PTR dwFlags)
Definition: crypt.c:651
Definition: name.c:36
#define TOKEN_LENGTH
Definition: fusionpriv.h:465
LPWSTR path
Definition: assembly.c:55
unsigned int ULONG
Definition: retypes.h:1
struct nls_table * tables
Definition: nls_base.c:22
METADATATABLESHDR * tableshdr
Definition: assembly.c:66
LPSTR Version
Definition: fusionpriv.h:46
PIMAGE_NT_HEADERS WINAPI ImageNtHeader(_In_ PVOID)
static char * dest
Definition: rtl.c:135
WCHAR * LPWSTR
Definition: xmlstorage.h:184
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1827
#define HP_HASHVAL
Definition: wincrypt.h:2183
#define UnmapViewOfFile
Definition: compat.h:403
Definition: _hash_fun.h:40
static LPWSTR assembly_dup_str(const ASSEMBLY *assembly, DWORD index)
Definition: assembly.c:708
#define memset(x, y, z)
Definition: compat.h:39
#define MAX_TABLES_2BIT_ENCODE
Definition: assembly.c:145
#define MAX_TABLES_1BIT_ENCODE
Definition: assembly.c:144
#define PROV_RSA_FULL
Definition: wincrypt.h:2039
static LPWSTR strdupW(LPCWSTR src)
Definition: assembly.c:67
HRESULT assembly_get_external_files(ASSEMBLY *assembly, LPWSTR **files, DWORD *count)
Definition: assembly.c:887
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
Definition: fci.c:126