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