PageRenderTime 109ms CodeModel.GetById 18ms RepoModel.GetById 3ms app.codeStats 3ms

/src/sys/dotnet/perwapi/PERWAPI.cs

https://bitbucket.org/bedlaczech/fan-1.0
C# | 13234 lines | 8246 code | 1818 blank | 3170 comment | 1527 complexity | 6cf790997bbe38881aabbe059f2403ff MD5 | raw file
Possible License(s): CC-BY-SA-3.0

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * PERWAPI - An API for Reading and Writing PE Files
  3. *
  4. * Copyright (c) Diane Corney, Queensland University of Technology, 2004.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the PERWAPI Copyright as included with this
  8. * distribution in the file PERWAPIcopyright.rtf.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY as is explained in the copyright notice.
  12. *
  13. * The author may be contacted at d.corney@qut.edu.au
  14. *
  15. * Version Date: 26/01/07
  16. *
  17. * Contributions Made By:
  18. *
  19. * Douglas Stockwell - Developed support for PDB files.
  20. * Andrew Bacon - Integrated PDB file support and developed automatic
  21. * stack depth calculations.
  22. *
  23. * Placed in Subversion repository by John Gough on 2-Mar-2007
  24. *
  25. */
  26. using System;
  27. using System.IO;
  28. using System.Collections;
  29. using SCG = System.Collections.Generic;
  30. using System.Text;
  31. using System.Security.Permissions;
  32. using System.Diagnostics;
  33. using System.Diagnostics.SymbolStore;
  34. using System.Runtime.InteropServices;
  35. using QUT;
  36. namespace PERWAPI {
  37. /// <summary>
  38. /// Diagnostic
  39. /// </summary>
  40. public class Diag {
  41. /// <summary>
  42. /// Flag for diagnostic output.
  43. /// </summary>
  44. public static bool DiagOn = false;
  45. }
  46. /// <summary>
  47. /// Facilities for outputting hexadecimal strings
  48. /// </summary>
  49. public class Hex {
  50. readonly static char[] hexDigit = {'0','1','2','3','4','5','6','7',
  51. '8','9','A','B','C','D','E','F'};
  52. readonly static uint[] iByteMask = {0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000};
  53. readonly static ulong[] lByteMask = {0x00000000000000FF, 0x000000000000FF00,
  54. 0x0000000000FF0000, 0x00000000FF000000,
  55. 0x000000FF00000000, 0x0000FF0000000000,
  56. 0x00FF000000000000, 0xFF00000000000000 };
  57. readonly static uint nibble0Mask = 0x0000000F;
  58. readonly static uint nibble1Mask = 0x000000F0;
  59. /// <summary>
  60. /// Derives a hexademical string for a byte value
  61. /// </summary>
  62. /// <param name="b">the byte value</param>
  63. /// <returns>hex string for the byte value</returns>
  64. public static String Byte(int b) {
  65. char[] str = new char[2];
  66. uint num = (uint)b;
  67. uint b1 = num & nibble0Mask;
  68. uint b2 = (num & nibble1Mask) >> 4;
  69. str[0] = hexDigit[b2];
  70. str[1] = hexDigit[b1];
  71. return new String(str);
  72. }
  73. /// <summary>
  74. /// Derives a hexademical string for a short value
  75. /// </summary>
  76. /// <param name="b">the short value</param>
  77. /// <returns>hex string for the short value</returns>
  78. public static String Short(int b) {
  79. char[] str = new char[4];
  80. uint num1 = (uint)b & iByteMask[0];
  81. uint num2 = ((uint)b & iByteMask[1]) >> 8;
  82. uint b1 = num1 & nibble0Mask;
  83. uint b2 = (num1 & nibble1Mask) >> 4;
  84. uint b3 = num2 & nibble0Mask;
  85. uint b4 = (num2 & nibble1Mask) >> 4;
  86. str[0] = hexDigit[b4];
  87. str[1] = hexDigit[b3];
  88. str[2] = hexDigit[b2];
  89. str[3] = hexDigit[b1];
  90. return new String(str);
  91. }
  92. /// <summary>
  93. /// Derives a hexademical string for an int value
  94. /// </summary>
  95. /// <param name="val">the int value</param>
  96. /// <returns>hex string for the int value</returns>
  97. public static String Int(int val) {
  98. char[] str = new char[8];
  99. uint num = (uint)val;
  100. int strIx = 7;
  101. for (int i=0; i < iByteMask.Length; i++) {
  102. uint b = num & iByteMask[i];
  103. b >>= (i*8);
  104. uint b1 = b & nibble0Mask;
  105. uint b2 = (b & nibble1Mask) >> 4;
  106. str[strIx--] = hexDigit[b1];
  107. str[strIx--] = hexDigit[b2];
  108. }
  109. return new String(str);
  110. }
  111. /// <summary>
  112. /// Derives a hexademical string for an unsigned int value
  113. /// </summary>
  114. /// <param name="num">the unsigned int value</param>
  115. /// <returns>hex string for the unsigned int value</returns>
  116. public static String Int(uint num) {
  117. char[] str = new char[8];
  118. int strIx = 7;
  119. for (int i=0; i < iByteMask.Length; i++) {
  120. uint b = num & iByteMask[i];
  121. b >>= (i*8);
  122. uint b1 = b & nibble0Mask;
  123. uint b2 = (b & nibble1Mask) >> 4;
  124. str[strIx--] = hexDigit[b1];
  125. str[strIx--] = hexDigit[b2];
  126. }
  127. return new String(str);
  128. }
  129. /// <summary>
  130. /// Derives a hexademical string for a long value
  131. /// </summary>
  132. /// <param name="lnum">the long value</param>
  133. /// <returns>hex string for the long value</returns>
  134. public static String Long(long lnum) {
  135. ulong num = (ulong)lnum;
  136. return Long(num);
  137. }
  138. /// <summary>
  139. /// Derives a hexademical string for an unsigned long value
  140. /// </summary>
  141. /// <param name="num">the unsigned long value</param>
  142. /// <returns>hex string for the unsigned long value</returns>
  143. public static String Long(ulong num) {
  144. char[] str = new char[16];
  145. int strIx = 15;
  146. for (int i=0; i < lByteMask.Length; i++) {
  147. ulong b = num & lByteMask[i];
  148. b >>= (i*8);
  149. ulong b1 = b & nibble0Mask;
  150. ulong b2 = (b & nibble1Mask) >> 4;
  151. str[strIx--] = hexDigit[b1];
  152. str[strIx--] = hexDigit[b2];
  153. }
  154. return new String(str);
  155. }
  156. }
  157. /// <summary>
  158. /// Exception for features yet to be implemented
  159. /// </summary>
  160. public class NotYetImplementedException : System.Exception {
  161. /// <summary>
  162. /// constructor
  163. /// </summary>
  164. /// <param name="msg"></param>
  165. public NotYetImplementedException(string msg) : base(msg + " Not Yet Implemented") { }
  166. }
  167. /// <summary>
  168. /// Error in a type signature
  169. /// </summary>
  170. public class TypeSignatureException : System.Exception {
  171. /// <summary>
  172. /// constructor
  173. /// </summary>
  174. /// <param name="msg"></param>
  175. public TypeSignatureException(string msg) : base(msg) { }
  176. }
  177. /// <summary>
  178. /// Error with a CIL instruction
  179. /// </summary>
  180. public class InstructionException : System.Exception {
  181. IType iType;
  182. uint op;
  183. internal InstructionException(IType iType, uint op) {
  184. this.iType = iType;
  185. this.op = op;
  186. }
  187. internal string AddMethodName(string name) {
  188. string istr = " ";
  189. switch (iType) {
  190. case (IType.fieldOp) : istr += (FieldOp)op; break;
  191. case (IType.methOp) : istr += (MethodOp)op; break;
  192. case (IType.specialOp) : istr += (SpecialOp)op; break;
  193. case (IType.typeOp) : istr += (TypeOp)op; break;
  194. default : break;
  195. }
  196. return "NullPointer in instruction" + istr + " for method " + name;
  197. }
  198. }
  199. /// <summary>
  200. /// Error with descriptor types
  201. /// </summary>
  202. public class DescriptorException : System.Exception {
  203. /// <summary>
  204. /// exception
  205. /// </summary>
  206. /// <param name="msg"></param>
  207. public DescriptorException(string msg):
  208. base("Descriptor for " + msg + " already exists") { }
  209. /// <summary>
  210. /// exception
  211. /// </summary>
  212. public DescriptorException() :
  213. base("Descriptor is a Def when a Ref is required") { }
  214. }
  215. /// <summary>
  216. /// Error for invalid PE file
  217. /// </summary>
  218. public class PEFileException : System.Exception {
  219. /// <summary>
  220. /// PEFile exception constructor
  221. /// </summary>
  222. /// <param name="msg"></param>
  223. public PEFileException(string msg) : base("Error in PE File: " + msg) { }
  224. }
  225. /// <summary>
  226. /// When the maximum stack depth could not be found dynamically.
  227. /// </summary>
  228. public class CouldNotFindMaxStackDepth : System.Exception {
  229. /// <summary>
  230. /// Constructor
  231. /// </summary>
  232. public CouldNotFindMaxStackDepth() : base("Not able to find the maximum stack depth.") { }
  233. }
  234. /// <summary>
  235. /// When the stack depth is not valid for the current position.
  236. /// </summary>
  237. public class InvalidStackDepth : System.Exception {
  238. /// <summary>
  239. /// Constructor
  240. /// </summary>
  241. public InvalidStackDepth(string msg) : base("Invalid stack depth reached: " + msg) { }
  242. }
  243. /**************************************************************************/
  244. // Various Enumerations for PEFiles
  245. /// <summary>
  246. /// flags for the assembly (.corflags)
  247. /// </summary>
  248. public enum CorFlags {
  249. /// <summary>
  250. /// IL only
  251. /// </summary>
  252. CF_IL_ONLY = 1,
  253. /// <summary>
  254. /// 32 bits
  255. /// </summary>
  256. CF_32_BITREQUIRED = 2,
  257. /// <summary>
  258. /// strong name signed
  259. /// </summary>
  260. CF_STRONGNAMESIGNED = 8,
  261. /// <summary>
  262. /// track debug data
  263. /// </summary>
  264. CF_TRACKDEBUGDATA = 0x10000
  265. }
  266. /// <summary>
  267. /// subsystem for the assembly (.subsystem)
  268. /// </summary>
  269. public enum SubSystem {
  270. /// <summary>
  271. /// native subsystem
  272. /// </summary>
  273. Native = 1,
  274. /// <summary>
  275. /// gui app
  276. /// </summary>
  277. Windows_GUI = 2,
  278. /// <summary>
  279. /// console app
  280. /// </summary>
  281. Windows_CUI = 3,
  282. /// <summary>
  283. /// os2 console
  284. /// </summary>
  285. OS2_CUI = 5,
  286. /// <summary>
  287. /// posix console
  288. /// </summary>
  289. POSIX_CUI = 7,
  290. /// <summary>
  291. /// native windows
  292. /// </summary>
  293. Native_Windows = 8,
  294. /// <summary>
  295. /// CE gui
  296. /// </summary>
  297. Windows_CE_GUI = 9
  298. }
  299. /// <summary>
  300. /// Hash algorithms for the assembly
  301. /// </summary>
  302. public enum HashAlgorithmType {
  303. /// <summary>
  304. /// No hash algorithm
  305. /// </summary>
  306. None,
  307. /// <summary>
  308. /// SHA1
  309. /// </summary>
  310. SHA1 = 0x8004
  311. }
  312. /// <summary>
  313. /// Attributes for this assembly
  314. /// </summary>
  315. public enum AssemAttr {
  316. /// <summary>
  317. /// Public key assembly attribute
  318. /// </summary>
  319. PublicKey = 0x01,
  320. /// <summary>
  321. /// retargetable assembly
  322. /// </summary>
  323. Retargetable = 0x100,
  324. /// <summary>
  325. /// JIT tracking
  326. /// </summary>
  327. EnableJITCompileTracking = 0x8000,
  328. /// <summary>
  329. /// Disable JIT compile optimizer
  330. /// </summary>
  331. DisableJITCompileOptimizer = 0x4000}
  332. /// <summary>
  333. /// Method call conventions
  334. /// </summary>
  335. [FlagsAttribute]
  336. public enum CallConv {
  337. /// <summary>
  338. /// default cc
  339. /// </summary>
  340. Default,
  341. /// <summary>
  342. /// cdecl
  343. /// </summary>
  344. Cdecl,
  345. /// <summary>
  346. /// stdcall
  347. /// </summary>
  348. Stdcall,
  349. /// <summary>
  350. /// this call
  351. /// </summary>
  352. Thiscall,
  353. /// <summary>
  354. /// fast call
  355. /// </summary>
  356. Fastcall,
  357. /// <summary>
  358. /// var arg
  359. /// </summary>
  360. Vararg,
  361. /// <summary>
  362. /// generic
  363. /// </summary>
  364. Generic = 0x10,
  365. /// <summary>
  366. /// instance
  367. /// </summary>
  368. Instance = 0x20,
  369. /// <summary>
  370. /// explicit instance
  371. /// </summary>
  372. InstanceExplicit = 0x60 }
  373. /// <summary>
  374. /// Method Types for Events and Properties
  375. /// </summary>
  376. public enum MethodType {
  377. /// <summary>
  378. /// setter
  379. /// </summary>
  380. Setter = 0x01,
  381. /// <summary>
  382. /// getter
  383. /// </summary>
  384. Getter,
  385. /// <summary>
  386. /// other
  387. /// </summary>
  388. Other = 0x04,
  389. /// <summary>
  390. /// add on
  391. /// </summary>
  392. AddOn = 0x08,
  393. /// <summary>
  394. /// remove on
  395. /// </summary>
  396. RemoveOn = 0x10,
  397. /// <summary>
  398. /// Fire
  399. /// </summary>
  400. Fire = 0x20 }
  401. /// <summary>
  402. /// Type custom modifier
  403. /// </summary>
  404. public enum CustomModifier {
  405. /// <summary>
  406. /// mod req
  407. /// </summary>
  408. modreq = 0x1F,
  409. /// <summary>
  410. /// mod opt
  411. /// </summary>
  412. modopt };
  413. /// <summary>
  414. /// Attibutes for a class
  415. /// </summary>
  416. [FlagsAttribute]
  417. public enum TypeAttr {
  418. Private, Public, NestedPublic, NestedPrivate,
  419. NestedFamily, NestedAssembly, NestedFamAndAssem, NestedFamOrAssem,
  420. SequentialLayout, ExplicitLayout = 0x10, Interface = 0x20,
  421. Abstract = 0x80, PublicAbstract = 0x81, Sealed = 0x100,
  422. PublicSealed = 0x101, SpecialName = 0x400, RTSpecialName = 0x800,
  423. Import = 0x1000, Serializable = 0x2000, UnicodeClass = 0x10000,
  424. AutoClass = 0x20000, BeforeFieldInit = 0x100000 }
  425. /// <summary>
  426. /// Attributes for a field
  427. /// </summary>
  428. [FlagsAttribute]
  429. public enum FieldAttr {
  430. Default, Private, FamAndAssem, Assembly,
  431. Family, FamOrAssem, Public, Static = 0x10, PublicStatic = 0x16,
  432. Initonly = 0x20, Literal = 0x40, Notserialized = 0x80,
  433. SpecialName = 0x200, RTSpecialName = 0x400 }
  434. /// <summary>
  435. /// Attributes for a method
  436. /// </summary>
  437. [FlagsAttribute]
  438. public enum MethAttr {
  439. Default, Private, FamAndAssem, Assembly,
  440. Family, FamOrAssem, Public, Static = 0x0010, PublicStatic = 0x16,
  441. Final = 0x0020, PublicStaticFinal = 0x36, Virtual = 0x0040,
  442. PrivateVirtual, PublicVirtual = 0x0046, HideBySig = 0x0080,
  443. NewSlot = 0x0100, Abstract = 0x0400, SpecialName = 0x0800,
  444. RTSpecialName = 0x1000, SpecialRTSpecialName = 0x1800,
  445. RequireSecObject = 0x8000}
  446. /// <summary>
  447. /// Attributes for .pinvokeimpl method declarations
  448. /// </summary>
  449. [FlagsAttribute]
  450. public enum PInvokeAttr {
  451. ansi = 2, unicode = 4, autochar = 6,
  452. lasterr = 0x040, winapi = 0x100, cdecl = 0x200, stdcall = 0x300,
  453. thiscall = 0x400, fastcall = 0x500 }
  454. /// <summary>
  455. /// Implementation attributes for a method
  456. /// </summary>
  457. [FlagsAttribute]
  458. public enum ImplAttr {
  459. IL, Native, OPTIL, Runtime, Unmanaged,
  460. ForwardRef = 0x10, PreserveSig = 0x0080, InternalCall = 0x1000,
  461. Synchronised = 0x0020, Synchronized = 0x0020, NoInLining = 0x0008}
  462. /// <summary>
  463. /// Modes for a parameter
  464. /// </summary>
  465. [FlagsAttribute]
  466. public enum ParamAttr { Default, In, Out, Opt = 4 }
  467. /// <summary>
  468. /// Flags for a generic parameter
  469. /// </summary>
  470. [Flags]
  471. public enum GenericParamAttr {
  472. NonVariant,
  473. Covariant,
  474. Contravariant,
  475. ReferenceType = 0x4,
  476. RequireDefaultCtor = 0x10 }
  477. /// <summary>
  478. /// Which version of PE file to build
  479. /// </summary>
  480. public enum NetVersion {
  481. Everett, /* version 1.1.4322 */
  482. Whidbey40, /* version 2.0.40607 beta 1*/
  483. Whidbey41, /* version 2.0.41202 */
  484. Whidbey50, /* version 2.0.50215 beta2*/
  485. Version2 /* version 2.0.50727.0 */
  486. }
  487. /// <summary>
  488. /// CIL instructions
  489. /// </summary>
  490. public enum Op {
  491. nop, breakOp, ldarg_0, ldarg_1, ldarg_2, ldarg_3, ldloc_0, ldloc_1, ldloc_2,
  492. ldloc_3, stloc_0, stloc_1, stloc_2, stloc_3,
  493. ldnull = 0x14, ldc_i4_m1, ldc_i4_0, ldc_i4_1, ldc_i4_2, ldc_i4_3,
  494. ldc_i4_4, ldc_i4_5, ldc_i4_6, ldc_i4_7, ldc_i4_8, dup = 0x25, pop,
  495. ret = 0x2A, ldind_i1 = 0x46, ldind_u1, ldind_i2, ldind_u2, ldind_i4,
  496. ldind_u4, ldind_i8, ldind_i, ldind_r4, ldind_r8, ldind_ref, stind_ref,
  497. stind_i1, stind_i2, stind_i4, stind_i8, stind_r4, stind_r8, add, sub, mul,
  498. div, div_un, rem, rem_un, and, or, xor, shl, shr, shr_un, neg, not,
  499. conv_i1, conv_i2, conv_i4, conv_i8, conv_r4, conv_r8, conv_u4, conv_u8,
  500. conv_r_un = 0x76, throwOp = 0x7A, conv_ovf_i1_un = 0x82, conv_ovf_i2_un,
  501. conv_ovf_i4_un, conv_ovf_i8_un, conf_ovf_u1_un, conv_ovf_u2_un,
  502. conv_ovf_u4_un, conv_ovf_u8_un, conv_ovf_i_un, conv_ovf_u_un,
  503. ldlen = 0x8E, ldelem_i1 = 0x90, ldelem_u1, ldelem_i2, ldelem_u2,
  504. ldelem_i4, ldelem_u4, ldelem_i8, ldelem_i, ldelem_r4, ldelem_r8,
  505. ldelem_ref, stelem_i, stelem_i1, stelem_i2, stelem_i4, stelem_i8,
  506. stelem_r4, stelem_r8, stelem_ref, conv_ovf_i1 = 0xb3, conv_ovf_u1,
  507. conv_ovf_i2, conv_ovf_u2, conv_ovf_i4, conv_ovf_u4, conv_ovf_i8,
  508. conv_ovf_u8, ckfinite = 0xC3, conv_u2 = 0xD1, conv_u1, conv_i,
  509. conv_ovf_i, conv_ovf_u, add_ovf, add_ovf_un, mul_ovf, mul_ovf_un,
  510. sub_ovf, sub_ovf_un, endfinally, stind_i = 0xDF, conv_u,
  511. arglist = 0xFE00, ceq, cgt, cgt_un, clt, clt_un, localloc = 0xFE0F,
  512. endfilter = 0xFE11, volatile_ = 0xFE13, tail_, cpblk = 0xFE17, initblk,
  513. rethrow = 0xFE1A, refanytype = 0xFE1D, readOnly}
  514. /// <summary>
  515. /// CIL instructions requiring an integer parameter
  516. /// </summary>
  517. public enum IntOp {
  518. ldarg_s = 0x0E, ldarga_s, starg_s, ldloc_s, ldloca_s,
  519. stloc_s, ldc_i4_s = 0x1F, ldc_i4, ldarg = 0xFE09,
  520. ldarga, starg, ldloc, ldloca, stloc, unaligned = 0xFE12 }
  521. /// <summary>
  522. /// CIL instructions requiring a field parameter
  523. /// </summary>
  524. public enum FieldOp {
  525. ldfld = 0x7B, ldflda, stfld, ldsfld, ldsflda,
  526. stsfld, ldtoken = 0xD0 }
  527. /// <summary>
  528. /// CIL instructions requiring a method parameter
  529. /// </summary>
  530. public enum MethodOp {
  531. jmp = 0x27, call, callvirt = 0x6F, newobj = 0x73,
  532. ldtoken = 0xD0, ldftn = 0xFE06, ldvirtfn }
  533. /// <summary>
  534. /// CIL instructions requiring a type parameter
  535. /// </summary>
  536. public enum TypeOp {
  537. cpobj = 0x70, ldobj, castclass = 0x74, isinst,
  538. unbox = 0x79, stobj = 0x81, box = 0x8C, newarr,
  539. ldelema = 0x8F, ldelem_any = 0xA3, stelem_any, unbox_any,
  540. refanyval = 0xC2, mkrefany = 0xC6,
  541. ldtoken = 0xD0, initobj = 0xFE15, constrained, sizeOf = 0xFE1C }
  542. /// <summary>
  543. /// CIL branch instructions
  544. /// </summary>
  545. public enum BranchOp {
  546. br_s = 0x2B, brfalse_s, brtrue_s, beq_s, bge_s, bgt_s, ble_s,
  547. blt_s, bne_un_s, bge_un_s, bgt_un_s, ble_un_s, blt_un_s,
  548. br, brfalse, brtrue, beq, bge, bgt, ble, blt, bne_un, bge_un, bgt_un, ble_un, blt_un,
  549. leave = 0xDD, leave_s }
  550. public enum SpecialOp {
  551. ldc_i8 = 0x21, ldc_r4, ldc_r8, calli = 0x29,
  552. Switch = 0x45, ldstr = 0x72 }
  553. /// <summary>
  554. /// Index for all the tables in the meta data
  555. /// </summary>
  556. public enum MDTable {
  557. Module, TypeRef, TypeDef, Field = 0x04, Method = 0x06,
  558. Param = 0x08, InterfaceImpl, MemberRef, Constant, CustomAttribute,
  559. FieldMarshal, DeclSecurity, ClassLayout, FieldLayout, StandAloneSig,
  560. EventMap, Event = 0x14, PropertyMap, Property = 0x17, MethodSemantics,
  561. MethodImpl, ModuleRef, TypeSpec, ImplMap, FieldRVA, Assembly = 0x20,
  562. AssemblyProcessor, AssemblyOS, AssemblyRef, AssemblyRefProcessor,
  563. AssemblyRefOS, File, ExportedType, ManifestResource, NestedClass,
  564. GenericParam, MethodSpec, GenericParamConstraint, MaxMDTable }
  565. public enum NativeTypeIx {
  566. Void = 0x01, Boolean, I1, U1, I2, U2, I4, U4,
  567. I8, U8, R4, R8, SysChar, Variant, Currency, Ptr, Decimal, Date, BStr,
  568. LPStr, LPWStr, LPTStr, FixedSysString, ObjectRef, IUnknown, IDispatch,
  569. Struct, Intf, SafeArray, FixedArray, Int, UInt, NestedStruct, ByValStr,
  570. AnsiBStr, TBStr, VariantBool, Func, AsAny = 0x28, Array = 0x2A, LPStruct,
  571. CustomMarshaller, Error }
  572. public enum SafeArrayType {
  573. int16 = 2, int32, float32, float64,
  574. currency, date, bstr, dispatch, error, boolean, variant, unknown,
  575. Decimal, int8 = 16, uint8, uint16, uint32, Int = 22, UInt,
  576. record = 0x24,
  577. MAX = 0x50
  578. }
  579. internal enum CIx {
  580. TypeDefOrRef, HasConstant, HasCustomAttr, HasFieldMarshal,
  581. HasDeclSecurity, MemberRefParent, HasSemantics, MethodDefOrRef,
  582. MemberForwarded, Implementation, CustomAttributeType, ResolutionScope,
  583. TypeOrMethodDef, MaxCIx }
  584. internal enum MapType { eventMap, propertyMap, nestedClass }
  585. public enum ElementType : byte {
  586. End, Void, Boolean, Char, I1, U1, I2, U2, I4, U4,
  587. I8, U8, R4, R8, String, Ptr, ByRef, ValueType, Class, Var, Array, GenericInst,
  588. TypedByRef, I = 0x18, U, FnPtr = 0x1B, Object, SZArray, MVar, CmodReqd,
  589. CmodOpt, Internal, Modifier = 0x40, Sentinel, Pinned = 0x45, ClassType = 0x50 }
  590. public enum SecurityAction {
  591. Request = 0x01, Demand, Assert, Deny, PermitOnly,
  592. LinkDemand, InheritanceDemand, RequestMinimum, RequestOptional, RequestRefuse,
  593. PreJITGrant, PreJITDeny, NonCASDemand, NonCASLinkDemand, NonCASInheritanceDemand }
  594. internal enum IType {
  595. op, methOp, fieldOp, typeOp, specialOp, int8Op, uint8Op, uint16Op,
  596. int32Op, branchOp }
  597. /**************************************************************************/
  598. /// <summary>
  599. /// Abstract class to represent a row of the Meta Data Tables
  600. /// </summary>
  601. public abstract class TableRow {
  602. internal PEReader buffer;
  603. private uint row = 0;
  604. /// <summary>
  605. /// The index of the Meta Data Table containing this element
  606. /// </summary>
  607. protected MDTable tabIx;
  608. /*-------------------- Constructors ---------------------------------*/
  609. internal TableRow() { }
  610. internal TableRow(PEReader buff, uint ix, MDTable tableIx) {
  611. buffer = buff;
  612. row = ix;
  613. tabIx = tableIx;
  614. }
  615. /// <summary>
  616. /// The row number of this element in the Meta Data Table
  617. /// </summary>
  618. public uint Row {
  619. get { return row; }
  620. set { row = value; }
  621. }
  622. }
  623. /****************************************************/
  624. /// <summary>
  625. /// Base class for all Meta Data table elements
  626. /// </summary>
  627. public abstract class MetaDataElement : TableRow, IComparable {
  628. /// <summary>
  629. /// The list of custom attributes associated with this meta data element
  630. /// </summary>
  631. protected ArrayList customAttributes;
  632. protected bool done = false;
  633. protected bool sortTable = false;
  634. internal bool unresolved = false;
  635. /*-------------------- Constructors ---------------------------------*/
  636. internal MetaDataElement() { }
  637. /// <summary>
  638. /// Get any custom attributes associated with this meta data element
  639. /// </summary>
  640. /// <returns>Array of custom attribute descriptors</returns>
  641. public CustomAttribute[] GetCustomAttributes() {
  642. if (customAttributes == null) return new CustomAttribute[0];
  643. return (CustomAttribute[])customAttributes.ToArray(typeof(CustomAttribute));
  644. }
  645. /// <summary>
  646. /// Associate some custom attribute(s) with this meta data element
  647. /// </summary>
  648. /// <param name="cas">list of custom attributes</param>
  649. public void SetCustomAttributes(CustomAttribute[] cas) {
  650. if (cas == null)
  651. customAttributes = null;
  652. else
  653. customAttributes = new ArrayList(cas);
  654. }
  655. internal virtual bool isDef() { return false; }
  656. internal virtual void Resolve(PEReader buff) { }
  657. internal virtual void ResolveDetails(PEReader buff) { }
  658. internal virtual uint GetCodedIx(CIx code) { return 0; }
  659. internal bool NeedToSort() { return sortTable; }
  660. internal virtual uint SortKey() {
  661. throw new PEFileException("Trying to sort table of " + this);
  662. //return 0;
  663. }
  664. /// <summary>
  665. /// Add a custom attribute to this item
  666. /// </summary>
  667. /// <param name="ctorMeth">the constructor method for this attribute</param>
  668. /// <param name="val">the byte value of the parameters</param>
  669. public void AddCustomAttribute(Method ctorMeth, byte[] val) {
  670. if (customAttributes == null) {
  671. customAttributes = new ArrayList();
  672. }
  673. customAttributes.Add(new CustomAttribute(this,ctorMeth,val));
  674. }
  675. /// <summary>
  676. /// Add a custom attribute to this item
  677. /// </summary>
  678. /// <param name="ctorMeth">the constructor method for this attribute</param>
  679. /// <param name="cVals">the constant values of the parameters</param>
  680. public void AddCustomAttribute(Method ctorMeth, Constant[] cVals) {
  681. if (customAttributes == null) {
  682. customAttributes = new ArrayList();
  683. }
  684. customAttributes.Add(new CustomAttribute(this,ctorMeth,cVals));
  685. }
  686. /// <summary>
  687. /// Associate a custom attribute with this meta data element
  688. /// </summary>
  689. public void AddCustomAttribute(CustomAttribute ca) {
  690. if (customAttributes == null) {
  691. customAttributes = new ArrayList();
  692. }
  693. customAttributes.Add(ca);
  694. }
  695. internal uint Token() {
  696. if (Row == 0) throw new Exception("Meta data token is zero!!");
  697. return (((uint)tabIx << 24) | Row);
  698. }
  699. internal void BuildMDTables(MetaDataOut md) {
  700. if (done) return;
  701. done = true;
  702. if (Diag.DiagOn) Console.WriteLine("In BuildMDTables");
  703. BuildTables(md);
  704. if (customAttributes != null) {
  705. for (int i=0; i < customAttributes.Count; i++) {
  706. CustomAttribute ca = (CustomAttribute)customAttributes[i];
  707. ca.BuildTables(md);
  708. }
  709. }
  710. }
  711. internal virtual void BuildTables(MetaDataOut md) { }
  712. internal virtual void BuildSignatures(MetaDataOut md) {
  713. done = false;
  714. }
  715. internal virtual void BuildCILInfo(CILWriter output) { }
  716. internal virtual void AddToTable(MetaDataOut md) {
  717. md.AddToTable(tabIx,this);
  718. }
  719. internal virtual void Write(PEWriter output) { }
  720. internal virtual void Write(CILWriter output) {
  721. throw new Exception("CIL backend not yet fully implemented - " + GetType().ToString());
  722. }
  723. internal virtual string NameString() { return "NoName"; }
  724. internal void DescriptorError(MetaDataElement elem) {
  725. throw new DescriptorException(elem.NameString());
  726. }
  727. #region IComparable Members
  728. public int CompareTo(object obj) {
  729. uint otherKey = ((MetaDataElement)obj).SortKey();
  730. uint thisKey = SortKey();
  731. if (thisKey == otherKey) {
  732. if (this is GenericParam) {
  733. if (((GenericParam)this).Index < ((GenericParam)obj).Index)
  734. return -1;
  735. else
  736. return 1;
  737. }
  738. return 0;
  739. }
  740. if (thisKey < otherKey) return -1;
  741. return 1;
  742. }
  743. #endregion
  744. }
  745. /**************************************************************************/
  746. /// <summary>
  747. /// Layout information for a class (.class [sequential | explicit])
  748. /// </summary>
  749. internal class ClassLayout : MetaDataElement {
  750. ClassDef parent;
  751. ushort packSize = 0;
  752. uint classSize = 0;
  753. uint parentIx = 0;
  754. /*-------------------- Constructors ---------------------------------*/
  755. internal ClassLayout(int pack, int cSize, ClassDef par) {
  756. packSize = (ushort)pack;
  757. classSize = (uint)cSize;
  758. parent = par;
  759. tabIx = MDTable.ClassLayout;
  760. }
  761. internal ClassLayout(ushort pack, uint cSize, ClassDef par) {
  762. packSize = pack;
  763. classSize = cSize;
  764. parent = par;
  765. tabIx = MDTable.ClassLayout;
  766. }
  767. internal ClassLayout(PEReader buff) {
  768. packSize = buff.ReadUInt16();
  769. classSize = buff.ReadUInt32();
  770. parentIx = buff.GetIndex(MDTable.TypeDef);
  771. tabIx = MDTable.ClassLayout;
  772. }
  773. internal static ClassLayout FindLayout(PEReader buff, ClassDef paren, uint classIx) {
  774. buff.SetElementPosition(MDTable.ClassLayout,0);
  775. for (int i=0; i < buff.GetTableSize(MDTable.ClassLayout); i++) {
  776. ushort packSize = buff.ReadUInt16();
  777. uint classSize = buff.ReadUInt32();
  778. if (buff.GetIndex(MDTable.TypeDef) == classIx)
  779. return new ClassLayout(packSize,classSize,paren);
  780. }
  781. return null;
  782. }
  783. internal static void Read(PEReader buff, TableRow[] layouts) {
  784. for (int i=0; i < layouts.Length; i++ ) {
  785. layouts[i] = new ClassLayout(buff);
  786. }
  787. }
  788. internal override void Resolve(PEReader buff) {
  789. parent = (ClassDef)buff.GetElement(MDTable.TypeDef,parentIx);
  790. if (parent != null) parent.Layout = this;
  791. }
  792. /*------------------------- public set and get methods --------------------------*/
  793. public void SetPack(int pack) { packSize = (ushort)pack; }
  794. public int GetPack() { return (int)packSize; }
  795. public void SetSize(int size) { classSize = (uint)size; }
  796. public int GetSize() { return (int)classSize; }
  797. /*----------------------------- internal functions ------------------------------*/
  798. internal sealed override void BuildTables(MetaDataOut md) {
  799. md.AddToTable(tabIx,this);
  800. }
  801. internal static uint Size(MetaData md) {
  802. return 6 + md.TableIndexSize(MDTable.TypeDef);
  803. }
  804. internal sealed override void Write(PEWriter output) {
  805. output.Write(packSize);
  806. output.Write(classSize);
  807. output.WriteIndex(MDTable.TypeDef,parent.Row);
  808. }
  809. }
  810. /**************************************************************************/
  811. /// <summary>
  812. /// Summary description for ConstantElem.
  813. /// </summary>
  814. internal class ConstantElem : MetaDataElement {
  815. MetaDataElement parent;
  816. Constant cValue;
  817. uint valIx = 0, parentIx = 0;
  818. /*-------------------- Constructors ---------------------------------*/
  819. internal ConstantElem(MetaDataElement parent, Constant val) {
  820. this.parent = parent;
  821. cValue = val;
  822. sortTable = true;
  823. tabIx = MDTable.Constant;
  824. }
  825. internal ConstantElem(PEReader buff) {
  826. byte constType = buff.ReadByte();
  827. byte pad = buff.ReadByte();
  828. parentIx = buff.GetCodedIndex(CIx.HasConstant);
  829. //valIx = buff.GetBlobIx();
  830. cValue = buff.GetBlobConst(constType);
  831. sortTable = true;
  832. tabIx = MDTable.Constant;
  833. }
  834. internal override void Resolve(PEReader buff) {
  835. parent = buff.GetCodedElement(CIx.HasConstant,parentIx);
  836. if (parent != null) {
  837. if (parent is Param) ((Param)parent).AddDefaultValue(cValue);
  838. else if (parent is FieldDef) ((FieldDef)parent).AddValue(cValue);
  839. else ((Property)parent).AddInitValue(cValue);
  840. }
  841. }
  842. internal static void Read(PEReader buff, TableRow[] consts) {
  843. for (int i=0; i < consts.Length; i++)
  844. consts[i] = new ConstantElem(buff);
  845. }
  846. /*----------------------------- internal functions ------------------------------*/
  847. internal override uint SortKey() {
  848. return (parent.Row << MetaData.CIxShiftMap[(uint)CIx.HasConstant])
  849. | parent.GetCodedIx(CIx.HasConstant);
  850. }
  851. internal sealed override void BuildTables(MetaDataOut md) {
  852. md.AddToTable(MDTable.Constant,this);
  853. valIx = cValue.GetBlobIndex(md);
  854. }
  855. internal static uint Size(MetaData md) {
  856. return 2 + md.CodedIndexSize(CIx.HasConstant) + md.BlobIndexSize();
  857. }
  858. internal sealed override void Write(PEWriter output) {
  859. output.Write(cValue.GetTypeIndex());
  860. output.Write((byte)0);
  861. output.WriteCodedIndex(CIx.HasConstant,parent);
  862. output.BlobIndex(valIx);
  863. }
  864. }
  865. /**************************************************************************/
  866. /// <summary>
  867. /// Descriptor for a Custom Attribute (.custom)
  868. /// </summary>
  869. public class CustomAttribute : MetaDataElement {
  870. internal static readonly ushort prolog = 0x0001;
  871. private static readonly int initSize = 5;
  872. MetaDataElement parent;
  873. Method type;
  874. uint valIx, parentIx, typeIx;
  875. Constant[] argVals, vals;
  876. public byte[] byteVal;
  877. ushort numNamed = 0;
  878. string[] names;
  879. bool[] isField;
  880. bool changed = false;
  881. /*-------------------- Constructors ---------------------------------*/
  882. internal CustomAttribute(MetaDataElement paren, Method constrType,
  883. Constant[] val) {
  884. parent = paren;
  885. type = constrType;
  886. argVals = val;
  887. changed = true;
  888. sortTable = true;
  889. tabIx = MDTable.CustomAttribute;
  890. }
  891. internal CustomAttribute(MetaDataElement paren, Method constrType,
  892. byte[] val) {
  893. parent = paren;
  894. type = constrType;
  895. tabIx = MDTable.CustomAttribute;
  896. byteVal = val;
  897. sortTable = true;
  898. changed = true;
  899. }
  900. internal CustomAttribute(PEReader buff) {
  901. parentIx = buff.GetCodedIndex(CIx.HasCustomAttr);
  902. typeIx = buff.GetCodedIndex(CIx.CustomAttributeType);
  903. valIx = buff.GetBlobIx();
  904. sortTable = true;
  905. tabIx = MDTable.CustomAttribute;
  906. }
  907. internal static void Read(PEReader buff, TableRow[] attrs) {
  908. for (int i=0; i < attrs.Length; i++) {
  909. attrs[i] = new CustomAttribute(buff);
  910. }
  911. }
  912. internal override void Resolve(PEReader buff) {
  913. parent = buff.GetCodedElement(CIx.HasCustomAttr,parentIx);
  914. if (parent == null) return;
  915. parent.AddCustomAttribute(this);
  916. type = (Method)buff.GetCodedElement(CIx.CustomAttributeType,typeIx);
  917. byteVal = buff.GetBlob(valIx);
  918. }
  919. /*------------------------- public set and get methods --------------------------*/
  920. public void AddFieldOrProp(string name, Constant val, bool isFld) {
  921. if ((byteVal != null) && !changed) DecodeCustomAttributeBlob();
  922. if (numNamed == 0) {
  923. names = new string[initSize];
  924. vals = new Constant[initSize];
  925. isField = new bool[initSize];
  926. } else if (numNamed >= names.Length) {
  927. string[] tmpNames = names;
  928. Constant[] tmpVals = vals;
  929. bool[] tmpField = isField;
  930. names = new String[names.Length + initSize];
  931. vals = new Constant[vals.Length + initSize];
  932. isField = new bool[isField.Length + initSize];
  933. for (int i = 0; i < numNamed; i++) {
  934. names[i] = tmpNames[i];
  935. vals[i] = tmpVals[i];
  936. isField[i] = tmpField[i];
  937. }
  938. }
  939. names[numNamed] = name;
  940. vals[numNamed] = val;
  941. isField[numNamed++] = isFld;
  942. changed = true;
  943. }
  944. public Constant[] Args {
  945. get {
  946. if (!changed && (byteVal != null)) {
  947. try {
  948. DecodeCustomAttributeBlob();
  949. } catch {
  950. }
  951. }
  952. return argVals;
  953. }
  954. set {
  955. argVals = value;
  956. changed = true;
  957. }
  958. }
  959. public string[] GetNames() {
  960. return names;
  961. }
  962. public bool[] GetIsField() {
  963. return isField;
  964. }
  965. public Constant[] GetNamedArgs() {
  966. return vals;
  967. }
  968. /*----------------------------- internal functions ------------------------------*/
  969. internal void DecodeCustomAttributeBlob() {
  970. MemoryStream caBlob = new MemoryStream(byteVal);
  971. BinaryReader blob = new BinaryReader(caBlob,System.Text.Encoding.UTF8);
  972. if (blob.ReadUInt16() != CustomAttribute.prolog) throw new PEFileException("Invalid Custom Attribute Blob");
  973. Type[] parTypes = type.GetParTypes();
  974. argVals = new Constant[parTypes.Length];
  975. for (int i=0; i < parTypes.Length; i++) {
  976. Type argType = parTypes[i];
  977. bool arrayConst = argType is Array;
  978. if (arrayConst) argType = ((ZeroBasedArray)(parTypes[i])).ElemType();
  979. bool boxed = argType is SystemClass;
  980. int eType = argType.GetTypeIndex();
  981. if (arrayConst) {
  982. Constant[] elems = new Constant[blob.ReadUInt32()];
  983. for (int j=0; j < elems.Length; j++) {
  984. if (boxed) {
  985. eType = blob.ReadByte();
  986. elems[j] = new BoxedSimpleConst((SimpleConstant)PEReader.ReadConst(eType,blob));
  987. } else {
  988. elems[j] = PEReader.ReadConst(eType,blob);
  989. }
  990. }
  991. argVals[i] = new ArrayConst(elems);
  992. } else if (boxed) {
  993. argVals[i] = new BoxedSimpleConst((SimpleConstant)PEReader.ReadConst(blob.ReadByte(),blob));
  994. } else {
  995. argVals[i] = PEReader.ReadConst(eType,blob);
  996. }
  997. }
  998. uint numNamed = 0;
  999. if (blob.BaseStream.Position != byteVal.Length)
  1000. numNamed = blob.ReadUInt16();
  1001. if (numNamed > 0) {
  1002. names = new string[numNamed];
  1003. vals = new Constant[numNamed];
  1004. isField = new bool[numNamed];
  1005. for (int i=0; i < numNamed; i++) {
  1006. isField[i] = blob.ReadByte() == 0x53;
  1007. int eType = blob.ReadByte();
  1008. names[i] = blob.ReadString();
  1009. vals[i] = PEReader.ReadConst(eType,blob);
  1010. }
  1011. }
  1012. }
  1013. internal void AddFieldOrProps(string[] names, Constant[] vals, bool[] isField) {
  1014. this.names = names;
  1015. this.vals = vals;
  1016. this.isField = isField;
  1017. numNamed = (ushort)names.Length;
  1018. }
  1019. internal void SetBytes(byte[] bytes) {
  1020. this.byteVal = bytes;
  1021. }
  1022. internal Method GetCAType() {
  1023. return type;
  1024. }
  1025. internal override uint SortKey() {
  1026. return (parent.Row << MetaData.CIxShiftMap[(uint)CIx.HasCustomAttr])
  1027. | parent.GetCodedIx(CIx.HasCustomAttr);
  1028. }
  1029. internal sealed override void BuildTables(MetaDataOut md) {
  1030. md.AddToTable(tabIx,this);
  1031. type.BuildMDTables(md);
  1032. // more adding to tables if data is not bytes
  1033. if (changed || (byteVal == null)) {
  1034. MemoryStream str = new MemoryStream();
  1035. BinaryWriter bw = new BinaryWriter(str);
  1036. bw.Write((ushort)1);
  1037. if (argVals != null) {
  1038. for (int i=0; i < argVals.Length; i++) {
  1039. argVals[i].Write(bw);
  1040. }
  1041. }
  1042. bw.Write(numNamed);
  1043. for (int i=0; i < numNamed; i++) {
  1044. if (isField[i]) bw.Write(Field.FieldTag);
  1045. else bw.Write(Property.PropertyTag);
  1046. bw.Write(vals[i].GetTypeIndex());
  1047. bw.Write(names[i]); // check this is the right format!!!
  1048. vals[i].Write(bw);
  1049. }
  1050. byteVal = str.ToArray();
  1051. }
  1052. valIx = md.AddToBlobHeap(byteVal);
  1053. }
  1054. internal static uint Size(MetaData md) {
  1055. return md.CodedIndexSize(CIx.HasCustomAttr) + md.CodedIndexSize(CIx.CustomAttributeType) + md.BlobIndexSize();
  1056. }
  1057. internal sealed override void Write(PEWriter output) {
  1058. output.WriteCodedIndex(CIx.HasCustomAttr,parent);
  1059. output.WriteCodedIndex(CIx.CustomAttributeType,type);
  1060. output.BlobIndex(valIx);
  1061. }
  1062. }
  1063. /**************************************************************************/
  1064. /// <summary>
  1065. /// Descriptor for security permissions for a class or a method NOT YET IMPLEMENTED
  1066. /// </summary>
  1067. public class DeclSecurity : MetaDataElement {
  1068. SecurityAction action;
  1069. MetaDataElement parent;
  1070. uint parentIx = 0, permissionIx;
  1071. byte[] permissionSet;
  1072. /*-------------------- Constructors ---------------------------------*/
  1073. internal DeclSecurity(MetaDataElement paren, SecurityAction act, byte[] perSet) {
  1074. parent = paren;
  1075. action = act;
  1076. permissionSet = perSet;
  1077. sortTable = true;
  1078. tabIx = MDTable.DeclSecurity;
  1079. }
  1080. internal DeclSecurity(PEReader buff) {
  1081. action = (SecurityAction)buff.ReadUInt16();
  1082. parentIx = buff.GetCodedIndex(CIx.HasDeclSecurity);
  1083. permissionSet = buff.GetBlob();
  1084. sortTable = true;
  1085. tabIx = MDTable.DeclSecurity;
  1086. }
  1087. internal static void Read(PEReader buff, TableRow[] secs) {
  1088. for (int i=0; i < secs.Length; i++)
  1089. secs[i] = new DeclSecurity(buff);
  1090. }
  1091. internal static DeclSecurity FindSecurity(PEReader buff, MetaDataElement paren, uint codedParIx) {
  1092. buff.SetElementPosition(MDTable.DeclSecurity,0);
  1093. for (int i=0; i < buff.GetTableSize(MDTable.DeclSecurity); i++) {
  1094. uint act = buff.ReadUInt16();
  1095. if (buff.GetCodedIndex(CIx.HasDeclSecurity) == codedParIx)
  1096. return new DeclSecurity(paren,(SecurityAction)act,buff.GetBlob());
  1097. uint junk = buff.GetBlobIx();
  1098. }
  1099. return null;
  1100. }
  1101. internal override void Resolve(PEReader buff) {
  1102. parent = buff.GetCodedElement(CIx.HasDeclSecurity,parentIx);
  1103. if (parent != null) {
  1104. if (parent is ClassDef) ((ClassDef)parent).AddSecurity(this);
  1105. if (parent is Assembly) ((Assembly)parent).AddSecurity(this);
  1106. if (parent is MethodDef) ((MethodDef)parent).AddSecurity(this);
  1107. }
  1108. }
  1109. internal override uint SortKey() {
  1110. return (parent.Row << MetaData.CIxShiftMap[(uint)CIx.HasDeclSecurity])
  1111. | parent.GetCodedIx(CIx.HasDeclSecurity);
  1112. }
  1113. internal sealed override void BuildTables(MetaDataOut md) {
  1114. md.AddToTable(MDTable.DeclSecurity, this);
  1115. permissionIx = md.AddToBlobHeap(permissionSet);
  1116. }
  1117. internal static uint Size(MetaData md) {
  1118. return 2 + md.CodedIndexSize(CIx.HasDeclSecurity) + md.BlobIndexSize();
  1119. }
  1120. internal sealed override void Write(PEWriter output) {
  1121. output.Write((UInt16)action); // or should this be 2 bytes??
  1122. output.WriteCodedIndex(CIx.HasDeclSecurity,parent);
  1123. output.BlobIndex(permissionIx);
  1124. }
  1125. }
  1126. /**************************************************************************/
  1127. /// <summary>
  1128. /// Descriptor for a class defined in another module of THIS assembly
  1129. /// and exported (.class extern)
  1130. /// </summary>
  1131. internal class ExternClass : MetaDataElement {
  1132. MetaDataElement implementation;
  1133. uint flags, typeDefId = 0;
  1134. uint implIx = 0, nameIx = 0, nameSpaceIx = 0;
  1135. string nameSpace, name;
  1136. /*-------------------- Constructors ---------------------------------*/
  1137. internal ExternClass(TypeAttr attr, string ns, string name, MetaDataElement paren) {
  1138. flags = (uint)attr;
  1139. nameSpace = ns;
  1140. this.name = name;
  1141. implementation = paren;
  1142. tabIx = MDTable.ExportedType;
  1143. }
  1144. public ExternClass(PEReader buff) {
  1145. flags = buff.ReadUInt32();
  1146. typeDefId = buff.ReadUInt32();
  1147. name = buff.GetString();
  1148. nameSpace = buff.GetString();
  1149. implIx = buff.GetCodedIndex(CIx.Implementation);
  1150. tabIx = MDTable.ExportedType;
  1151. }
  1152. internal static void Read(PEReader buff, TableRow[] eClasses) {
  1153. for (int i=0; i < eClasses.Length; i++)
  1154. eClasses[i] = new ExternClass(buff);
  1155. }
  1156. internal static void GetClassRefs(PEReader buff, TableRow[] eClasses) {
  1157. for (uint i=0; i < eClasses.Length; i++) {
  1158. uint junk = buff.ReadUInt32();
  1159. junk = buff.ReadUInt32();
  1160. string name = buff.GetString();
  1161. string nameSpace = buff.GetString();
  1162. uint implIx = buff.GetCodedIndex(CIx.Implementation);
  1163. eClasses[i] = new ClassRef(implIx,nameSpace,name);
  1164. eClasses[i].Row = i+1;
  1165. }
  1166. }
  1167. internal override void Resolve(PEReader buff) {
  1168. implementation = buff.GetCodedElement(CIx.Implementation,implIx);
  1169. while (implementation is ExternClass)
  1170. implementation = ((ExternClass)implementation).implementation;
  1171. ((ModuleFile)implementation).fileModule.AddExternClass(this);
  1172. }
  1173. internal string NameSpace() { return nameSpace; }
  1174. internal string Name() { return name; }
  1175. internal sealed override void BuildTables(MetaDataOut md) {
  1176. md.AddToTable(MDTable.ExportedType,this);
  1177. nameSpaceIx = md.AddToStringsHeap(nameSpace);
  1178. nameIx = md.AddToStringsHeap(name);
  1179. if (implementation is ModuleRef) {
  1180. ModuleFile mFile = ((ModuleRef)implementation).modFile;
  1181. mFile.BuildMDTables(md);
  1182. implementation = mFile;
  1183. }
  1184. }
  1185. internal static uint Size(MetaData md) {
  1186. return 8 + 2* md.StringsIndexSize() + md.CodedIndexSize(CIx.Implementation);
  1187. }
  1188. internal sealed override void Write(PEWriter output) {
  1189. output.Write(flags);
  1190. output.Write(0);
  1191. output.StringsIndex(nameIx);
  1192. output.StringsIndex(nameSpaceIx);
  1193. output.WriteCodedIndex(CIx.Implementation,implementation);
  1194. }
  1195. internal sealed override uint GetCodedIx(CIx code) {
  1196. switch (code) {
  1197. case (CIx.HasCustomAttr) : return 17;
  1198. case (CIx.Implementation) : return 2;
  1199. }
  1200. return 0;
  1201. }
  1202. }
  1203. /**************************************************************************/
  1204. /// <summary>
  1205. /// Base class for Event and Property descriptors
  1206. /// </summary>
  1207. public abstract class Feature : MetaDataElement {
  1208. private static readonly int INITSIZE = 5;
  1209. private static readonly ushort specialName = 0x200;
  1210. private static readonly ushort rtsSpecialName = 0x400;
  1211. private static readonly ushort noSpecialName = 0xFDFF;
  1212. private static readonly ushort noRTSSpecialName = 0xFBFF;
  1213. protected ClassDef parent;
  1214. protected ushort flags = 0;
  1215. protected string name;
  1216. protected int tide = 0;
  1217. protected uint nameIx;
  1218. protected MethodSemantics[] methods = new MethodSemantics[INITSIZE];
  1219. /*-------------------- Constructors ---------------------------------*/
  1220. internal Feature(string name, ClassDef par) {
  1221. parent = par;
  1222. this.name = name;
  1223. }
  1224. internal Feature() { }
  1225. internal static string[] GetFeatureNames(PEReader buff, MDTable tabIx, MDTable mapTabIx,
  1226. ClassDef theClass, uint classIx) {
  1227. buff.SetElementPosition(mapTabIx,0);
  1228. uint start = 0, end = 0, i = 0;
  1229. for (; (i < buff.GetTableSize(tabIx)) && (start == 0); i++) {
  1230. if (buff.GetIndex(MDTable.TypeDef) == classIx) {
  1231. start = buff.GetIndex(tabIx);
  1232. }
  1233. }
  1234. if (start == 0) return null;
  1235. if (i < buff.GetTableSize(mapTabIx)) {
  1236. uint junk = buff.GetIndex(MDTable.TypeDef);
  1237. end = buff.GetIndex(tabIx);
  1238. } else
  1239. end = buff.GetTableSize(tabIx);
  1240. if (tabIx == MDTable.Event)
  1241. theClass.eventIx = start;
  1242. e

Large files files are truncated, but you can click here to view the full file