mscorlib(4.0.0.0) API with additions
ResourceReader.cs
1 using System.Collections;
4 using System.IO;
5 using System.Reflection;
9 using System.Security;
10 using System.Text;
11 
12 namespace System.Resources
13 {
16  [ComVisible(true)]
18  {
19  internal sealed class TypeLimitingDeserializationBinder : SerializationBinder
20  {
21  private RuntimeType _typeToDeserialize;
22 
23  private ObjectReader _objectReader;
24 
25  internal ObjectReader ObjectReader
26  {
27  get
28  {
29  return _objectReader;
30  }
31  set
32  {
33  _objectReader = value;
34  }
35  }
36 
37  internal void ExpectingToDeserialize(RuntimeType type)
38  {
39  _typeToDeserialize = type;
40  }
41 
42  [SecuritySafeCritical]
43  public override Type BindToType(string assemblyName, string typeName)
44  {
45  AssemblyName asmName = new AssemblyName(assemblyName);
46  bool flag = false;
47  string[] typesSafeForDeserialization = TypesSafeForDeserialization;
48  foreach (string asmTypeName in typesSafeForDeserialization)
49  {
50  if (ResourceManager.CompareNames(asmTypeName, typeName, asmName))
51  {
52  flag = true;
53  break;
54  }
55  }
56  Type type = ObjectReader.FastBindToType(assemblyName, typeName);
57  if (type.IsEnum)
58  {
59  flag = true;
60  }
61  if (flag)
62  {
63  return null;
64  }
65  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResType&SerBlobMismatch", _typeToDeserialize.FullName, typeName));
66  }
67  }
68 
69  internal sealed class ResourceEnumerator : IDictionaryEnumerator, IEnumerator
70  {
71  private const int ENUM_DONE = int.MinValue;
72 
73  private const int ENUM_NOT_STARTED = -1;
74 
75  private ResourceReader _reader;
76 
77  private bool _currentIsValid;
78 
79  private int _currentName;
80 
81  private int _dataPosition;
82 
83  public object Key
84  {
85  [SecuritySafeCritical]
86  get
87  {
88  if (_currentName == int.MinValue)
89  {
90  throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumEnded"));
91  }
92  if (!_currentIsValid)
93  {
94  throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumNotStarted"));
95  }
96  if (_reader._resCache == null)
97  {
98  throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed"));
99  }
100  return _reader.AllocateStringForNameIndex(_currentName, out _dataPosition);
101  }
102  }
103 
104  public object Current => Entry;
105 
106  internal int DataPosition => _dataPosition;
107 
108  public DictionaryEntry Entry
109  {
110  [SecuritySafeCritical]
111  get
112  {
113  if (_currentName == int.MinValue)
114  {
115  throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumEnded"));
116  }
117  if (!_currentIsValid)
118  {
119  throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumNotStarted"));
120  }
121  if (_reader._resCache == null)
122  {
123  throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed"));
124  }
125  object obj = null;
126  string key;
127  lock (_reader)
128  {
129  lock (_reader._resCache)
130  {
131  key = _reader.AllocateStringForNameIndex(_currentName, out _dataPosition);
132  if (_reader._resCache.TryGetValue(key, out ResourceLocator value))
133  {
134  obj = value.Value;
135  }
136  if (obj == null)
137  {
138  obj = ((_dataPosition != -1) ? _reader.LoadObject(_dataPosition) : _reader.GetValueForNameIndex(_currentName));
139  }
140  }
141  }
142  return new DictionaryEntry(key, obj);
143  }
144  }
145 
146  public object Value
147  {
148  get
149  {
150  if (_currentName == int.MinValue)
151  {
152  throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumEnded"));
153  }
154  if (!_currentIsValid)
155  {
156  throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EnumNotStarted"));
157  }
158  if (_reader._resCache == null)
159  {
160  throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed"));
161  }
162  return _reader.GetValueForNameIndex(_currentName);
163  }
164  }
165 
166  internal ResourceEnumerator(ResourceReader reader)
167  {
168  _currentName = -1;
169  _reader = reader;
170  _dataPosition = -2;
171  }
172 
173  public bool MoveNext()
174  {
175  if (_currentName == _reader._numResources - 1 || _currentName == int.MinValue)
176  {
177  _currentIsValid = false;
178  _currentName = int.MinValue;
179  return false;
180  }
181  _currentIsValid = true;
182  _currentName++;
183  return true;
184  }
185 
186  public void Reset()
187  {
188  if (_reader._resCache == null)
189  {
190  throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed"));
191  }
192  _currentIsValid = false;
193  _currentName = -1;
194  }
195  }
196 
197  private const int DefaultFileStreamBufferSize = 4096;
198 
199  private BinaryReader _store;
200 
201  internal Dictionary<string, ResourceLocator> _resCache;
202 
203  private long _nameSectionOffset;
204 
205  private long _dataSectionOffset;
206 
207  private int[] _nameHashes;
208 
209  [SecurityCritical]
210  private unsafe int* _nameHashesPtr;
211 
212  private int[] _namePositions;
213 
214  [SecurityCritical]
215  private unsafe int* _namePositionsPtr;
216 
217  private RuntimeType[] _typeTable;
218 
219  private int[] _typeNamePositions;
220 
221  private BinaryFormatter _objFormatter;
222 
223  private int _numResources;
224 
225  private UnmanagedMemoryStream _ums;
226 
227  private int _version;
228 
229  private bool[] _safeToDeserialize;
230 
231  private TypeLimitingDeserializationBinder _typeLimitingBinder;
232 
233  private static readonly string[] TypesSafeForDeserialization = new string[21]
234  {
235  "System.String[], mscorlib, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
236  "System.DateTime[], mscorlib, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
237  "System.Drawing.Bitmap, System.Drawing, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
238  "System.Drawing.Imaging.Metafile, System.Drawing, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
239  "System.Drawing.Point, System.Drawing, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
240  "System.Drawing.PointF, System.Drawing, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
241  "System.Drawing.Size, System.Drawing, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
242  "System.Drawing.SizeF, System.Drawing, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
243  "System.Drawing.Font, System.Drawing, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
244  "System.Drawing.Icon, System.Drawing, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
245  "System.Drawing.Color, System.Drawing, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a",
246  "System.Windows.Forms.Cursor, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089",
247  "System.Windows.Forms.Padding, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089",
248  "System.Windows.Forms.LinkArea, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089",
249  "System.Windows.Forms.ImageListStreamer, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089",
250  "System.Windows.Forms.ListViewGroup, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089",
251  "System.Windows.Forms.ListViewItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089",
252  "System.Windows.Forms.ListViewItem+ListViewSubItem, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089",
253  "System.Windows.Forms.ListViewItem+ListViewSubItem+SubItemStyle, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089",
254  "System.Windows.Forms.OwnerDrawPropertyBag, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089",
255  "System.Windows.Forms.TreeNode, System.Windows.Forms, Culture=neutral, PublicKeyToken=b77a5c561934e089"
256  };
257 
264  [SecuritySafeCritical]
265  public ResourceReader(string fileName)
266  {
267  _resCache = new Dictionary<string, ResourceLocator>(FastResourceComparer.Default);
268  _store = new BinaryReader(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.RandomAccess, Path.GetFileName(fileName), bFromProxy: false), Encoding.UTF8);
269  try
270  {
271  ReadResources();
272  }
273  catch
274  {
275  _store.Close();
276  throw;
277  }
278  }
279 
285  [SecurityCritical]
286  public ResourceReader(Stream stream)
287  {
288  if (stream == null)
289  {
290  throw new ArgumentNullException("stream");
291  }
292  if (!stream.CanRead)
293  {
294  throw new ArgumentException(Environment.GetResourceString("Argument_StreamNotReadable"));
295  }
296  _resCache = new Dictionary<string, ResourceLocator>(FastResourceComparer.Default);
297  _store = new BinaryReader(stream, Encoding.UTF8);
298  _ums = (stream as UnmanagedMemoryStream);
299  ReadResources();
300  }
301 
302  [SecurityCritical]
304  {
305  _resCache = resCache;
306  _store = new BinaryReader(stream, Encoding.UTF8);
307  _ums = (stream as UnmanagedMemoryStream);
308  ReadResources();
309  }
310 
312  public void Close()
313  {
314  Dispose(disposing: true);
315  }
316 
318  public void Dispose()
319  {
320  Close();
321  }
322 
323  [SecuritySafeCritical]
324  private unsafe void Dispose(bool disposing)
325  {
326  if (_store != null)
327  {
328  _resCache = null;
329  if (disposing)
330  {
331  BinaryReader store = _store;
332  _store = null;
333  store?.Close();
334  }
335  _store = null;
336  _namePositions = null;
337  _nameHashes = null;
338  _ums = null;
339  _namePositionsPtr = null;
340  _nameHashesPtr = null;
341  }
342  }
343 
344  [SecurityCritical]
345  internal unsafe static int ReadUnalignedI4(int* p)
346  {
347  return *(byte*)p | (((byte*)p)[1] << 8) | (((byte*)p)[2] << 16) | (((byte*)p)[3] << 24);
348  }
349 
350  private void SkipInt32()
351  {
352  _store.BaseStream.Seek(4L, SeekOrigin.Current);
353  }
354 
355  private void SkipString()
356  {
357  int num = _store.Read7BitEncodedInt();
358  if (num < 0)
359  {
360  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_NegativeStringLength"));
361  }
362  _store.BaseStream.Seek(num, SeekOrigin.Current);
363  }
364 
365  [SecuritySafeCritical]
366  private unsafe int GetNameHash(int index)
367  {
368  if (_ums == null)
369  {
370  return _nameHashes[index];
371  }
372  return ReadUnalignedI4(_nameHashesPtr + index);
373  }
374 
375  [SecuritySafeCritical]
376  private unsafe int GetNamePosition(int index)
377  {
378  int num = (_ums != null) ? ReadUnalignedI4(_namePositionsPtr + index) : _namePositions[index];
379  if (num < 0 || num > _dataSectionOffset - _nameSectionOffset)
380  {
381  throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesNameInvalidOffset", num));
382  }
383  return num;
384  }
385 
390  {
391  return GetEnumerator();
392  }
393 
398  {
399  if (_resCache == null)
400  {
401  throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed"));
402  }
403  return new ResourceEnumerator(this);
404  }
405 
406  internal ResourceEnumerator GetEnumeratorInternal()
407  {
408  return new ResourceEnumerator(this);
409  }
410 
411  internal int FindPosForResource(string name)
412  {
413  int num = FastResourceComparer.HashFunction(name);
414  int num2 = 0;
415  int i = _numResources - 1;
416  int num3 = -1;
417  bool flag = false;
418  while (num2 <= i)
419  {
420  num3 = num2 + i >> 1;
421  int nameHash = GetNameHash(num3);
422  int num4 = (nameHash != num) ? ((nameHash >= num) ? 1 : (-1)) : 0;
423  if (num4 == 0)
424  {
425  flag = true;
426  break;
427  }
428  if (num4 < 0)
429  {
430  num2 = num3 + 1;
431  }
432  else
433  {
434  i = num3 - 1;
435  }
436  }
437  if (!flag)
438  {
439  return -1;
440  }
441  if (num2 != num3)
442  {
443  num2 = num3;
444  while (num2 > 0 && GetNameHash(num2 - 1) == num)
445  {
446  num2--;
447  }
448  }
449  if (i != num3)
450  {
451  for (i = num3; i < _numResources - 1 && GetNameHash(i + 1) == num; i++)
452  {
453  }
454  }
455  lock (this)
456  {
457  for (int j = num2; j <= i; j++)
458  {
459  _store.BaseStream.Seek(_nameSectionOffset + GetNamePosition(j), SeekOrigin.Begin);
460  if (CompareStringEqualsName(name))
461  {
462  int num5 = _store.ReadInt32();
463  if (num5 < 0 || num5 >= _store.BaseStream.Length - _dataSectionOffset)
464  {
465  throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesDataInvalidOffset", num5));
466  }
467  return num5;
468  }
469  }
470  }
471  return -1;
472  }
473 
474  [SecuritySafeCritical]
475  private unsafe bool CompareStringEqualsName(string name)
476  {
477  int num = _store.Read7BitEncodedInt();
478  if (num < 0)
479  {
480  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_NegativeStringLength"));
481  }
482  if (_ums != null)
483  {
484  byte* positionPointer = _ums.PositionPointer;
485  _ums.Seek(num, SeekOrigin.Current);
486  if (_ums.Position > _ums.Length)
487  {
488  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesNameTooLong"));
489  }
490  return FastResourceComparer.CompareOrdinal(positionPointer, num, name) == 0;
491  }
492  byte[] array = new byte[num];
493  int num3;
494  for (int num2 = num; num2 > 0; num2 -= num3)
495  {
496  num3 = _store.Read(array, num - num2, num2);
497  if (num3 == 0)
498  {
499  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceNameCorrupted"));
500  }
501  }
502  return FastResourceComparer.CompareOrdinal(array, num / 2, name) == 0;
503  }
504 
505  [SecurityCritical]
506  private unsafe string AllocateStringForNameIndex(int index, out int dataOffset)
507  {
508  long num = GetNamePosition(index);
509  int num2;
510  byte[] array;
511  lock (this)
512  {
513  _store.BaseStream.Seek(num + _nameSectionOffset, SeekOrigin.Begin);
514  num2 = _store.Read7BitEncodedInt();
515  if (num2 < 0)
516  {
517  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_NegativeStringLength"));
518  }
519  if (_ums != null)
520  {
521  if (_ums.Position > _ums.Length - num2)
522  {
523  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesIndexTooLong", index));
524  }
525  string text = null;
526  char* positionPointer = (char*)_ums.PositionPointer;
527  text = new string(positionPointer, 0, num2 / 2);
528  _ums.Position += num2;
529  dataOffset = _store.ReadInt32();
530  if (dataOffset < 0 || dataOffset >= _store.BaseStream.Length - _dataSectionOffset)
531  {
532  throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesDataInvalidOffset", dataOffset));
533  }
534  return text;
535  }
536  array = new byte[num2];
537  int num4;
538  for (int num3 = num2; num3 > 0; num3 -= num4)
539  {
540  num4 = _store.Read(array, num2 - num3, num3);
541  if (num4 == 0)
542  {
543  throw new EndOfStreamException(Environment.GetResourceString("BadImageFormat_ResourceNameCorrupted_NameIndex", index));
544  }
545  }
546  dataOffset = _store.ReadInt32();
547  if (dataOffset < 0 || dataOffset >= _store.BaseStream.Length - _dataSectionOffset)
548  {
549  throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesDataInvalidOffset", dataOffset));
550  }
551  }
552  return Encoding.Unicode.GetString(array, 0, num2);
553  }
554 
555  private object GetValueForNameIndex(int index)
556  {
557  long num = GetNamePosition(index);
558  lock (this)
559  {
560  _store.BaseStream.Seek(num + _nameSectionOffset, SeekOrigin.Begin);
561  SkipString();
562  int num2 = _store.ReadInt32();
563  if (num2 < 0 || num2 >= _store.BaseStream.Length - _dataSectionOffset)
564  {
565  throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesDataInvalidOffset", num2));
566  }
567  if (_version == 1)
568  {
569  return LoadObjectV1(num2);
570  }
571  ResourceTypeCode typeCode;
572  return LoadObjectV2(num2, out typeCode);
573  }
574  }
575 
576  internal string LoadString(int pos)
577  {
578  _store.BaseStream.Seek(_dataSectionOffset + pos, SeekOrigin.Begin);
579  string result = null;
580  int num = _store.Read7BitEncodedInt();
581  if (_version == 1)
582  {
583  if (num == -1)
584  {
585  return null;
586  }
587  if (FindType(num) != typeof(string))
588  {
589  throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResourceNotString_Type", FindType(num).FullName));
590  }
591  result = _store.ReadString();
592  }
593  else
594  {
595  ResourceTypeCode resourceTypeCode = (ResourceTypeCode)num;
596  if (resourceTypeCode != ResourceTypeCode.String && resourceTypeCode != 0)
597  {
598  string text = (resourceTypeCode >= ResourceTypeCode.StartOfUserTypes) ? FindType((int)(resourceTypeCode - 64)).FullName : resourceTypeCode.ToString();
599  throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ResourceNotString_Type", text));
600  }
601  if (resourceTypeCode == ResourceTypeCode.String)
602  {
603  result = _store.ReadString();
604  }
605  }
606  return result;
607  }
608 
609  internal object LoadObject(int pos)
610  {
611  if (_version == 1)
612  {
613  return LoadObjectV1(pos);
614  }
615  ResourceTypeCode typeCode;
616  return LoadObjectV2(pos, out typeCode);
617  }
618 
619  internal object LoadObject(int pos, out ResourceTypeCode typeCode)
620  {
621  if (_version == 1)
622  {
623  object obj = LoadObjectV1(pos);
624  typeCode = ((obj is string) ? ResourceTypeCode.String : ResourceTypeCode.StartOfUserTypes);
625  return obj;
626  }
627  return LoadObjectV2(pos, out typeCode);
628  }
629 
630  internal object LoadObjectV1(int pos)
631  {
632  try
633  {
634  return _LoadObjectV1(pos);
635  }
636  catch (EndOfStreamException inner)
637  {
638  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_TypeMismatch"), inner);
639  }
640  catch (ArgumentOutOfRangeException inner2)
641  {
642  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_TypeMismatch"), inner2);
643  }
644  }
645 
646  [SecuritySafeCritical]
647  private object _LoadObjectV1(int pos)
648  {
649  _store.BaseStream.Seek(_dataSectionOffset + pos, SeekOrigin.Begin);
650  int num = _store.Read7BitEncodedInt();
651  if (num == -1)
652  {
653  return null;
654  }
655  RuntimeType left = FindType(num);
656  if (left == typeof(string))
657  {
658  return _store.ReadString();
659  }
660  if (left == typeof(int))
661  {
662  return _store.ReadInt32();
663  }
664  if (left == typeof(byte))
665  {
666  return _store.ReadByte();
667  }
668  if (left == typeof(sbyte))
669  {
670  return _store.ReadSByte();
671  }
672  if (left == typeof(short))
673  {
674  return _store.ReadInt16();
675  }
676  if (left == typeof(long))
677  {
678  return _store.ReadInt64();
679  }
680  if (left == typeof(ushort))
681  {
682  return _store.ReadUInt16();
683  }
684  if (left == typeof(uint))
685  {
686  return _store.ReadUInt32();
687  }
688  if (left == typeof(ulong))
689  {
690  return _store.ReadUInt64();
691  }
692  if (left == typeof(float))
693  {
694  return _store.ReadSingle();
695  }
696  if (left == typeof(double))
697  {
698  return _store.ReadDouble();
699  }
700  if (left == typeof(DateTime))
701  {
702  return new DateTime(_store.ReadInt64());
703  }
704  if (left == typeof(TimeSpan))
705  {
706  return new TimeSpan(_store.ReadInt64());
707  }
708  if (left == typeof(decimal))
709  {
710  int[] array = new int[4];
711  for (int i = 0; i < array.Length; i++)
712  {
713  array[i] = _store.ReadInt32();
714  }
715  return new decimal(array);
716  }
717  return DeserializeObject(num);
718  }
719 
720  internal object LoadObjectV2(int pos, out ResourceTypeCode typeCode)
721  {
722  try
723  {
724  return _LoadObjectV2(pos, out typeCode);
725  }
726  catch (EndOfStreamException inner)
727  {
728  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_TypeMismatch"), inner);
729  }
730  catch (ArgumentOutOfRangeException inner2)
731  {
732  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_TypeMismatch"), inner2);
733  }
734  }
735 
736  [SecuritySafeCritical]
737  private unsafe object _LoadObjectV2(int pos, out ResourceTypeCode typeCode)
738  {
739  _store.BaseStream.Seek(_dataSectionOffset + pos, SeekOrigin.Begin);
740  typeCode = (ResourceTypeCode)_store.Read7BitEncodedInt();
741  switch (typeCode)
742  {
743  case ResourceTypeCode.Null:
744  return null;
745  case ResourceTypeCode.String:
746  return _store.ReadString();
747  case ResourceTypeCode.Boolean:
748  return _store.ReadBoolean();
749  case ResourceTypeCode.Char:
750  return (char)_store.ReadUInt16();
751  case ResourceTypeCode.Byte:
752  return _store.ReadByte();
753  case ResourceTypeCode.SByte:
754  return _store.ReadSByte();
755  case ResourceTypeCode.Int16:
756  return _store.ReadInt16();
757  case ResourceTypeCode.UInt16:
758  return _store.ReadUInt16();
759  case ResourceTypeCode.Int32:
760  return _store.ReadInt32();
761  case ResourceTypeCode.UInt32:
762  return _store.ReadUInt32();
763  case ResourceTypeCode.Int64:
764  return _store.ReadInt64();
765  case ResourceTypeCode.UInt64:
766  return _store.ReadUInt64();
767  case ResourceTypeCode.Single:
768  return _store.ReadSingle();
769  case ResourceTypeCode.Double:
770  return _store.ReadDouble();
771  case ResourceTypeCode.Decimal:
772  return _store.ReadDecimal();
773  case ResourceTypeCode.DateTime:
774  {
775  long dateData = _store.ReadInt64();
776  return DateTime.FromBinary(dateData);
777  }
778  case ResourceTypeCode.TimeSpan:
779  {
780  long ticks = _store.ReadInt64();
781  return new TimeSpan(ticks);
782  }
783  case ResourceTypeCode.ByteArray:
784  {
785  int num2 = _store.ReadInt32();
786  if (num2 < 0)
787  {
788  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceDataLengthInvalid", num2));
789  }
790  if (_ums == null)
791  {
792  if (num2 > _store.BaseStream.Length)
793  {
794  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceDataLengthInvalid", num2));
795  }
796  return _store.ReadBytes(num2);
797  }
798  if (num2 > _ums.Length - _ums.Position)
799  {
800  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceDataLengthInvalid", num2));
801  }
802  byte[] array2 = new byte[num2];
803  int num3 = _ums.Read(array2, 0, num2);
804  return array2;
805  }
806  case ResourceTypeCode.Stream:
807  {
808  int num = _store.ReadInt32();
809  if (num < 0)
810  {
811  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceDataLengthInvalid", num));
812  }
813  if (_ums == null)
814  {
815  byte[] array = _store.ReadBytes(num);
816  return new PinnedBufferMemoryStream(array);
817  }
818  if (num > _ums.Length - _ums.Position)
819  {
820  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourceDataLengthInvalid", num));
821  }
822  return new UnmanagedMemoryStream(_ums.PositionPointer, num, num, FileAccess.Read, skipSecurityCheck: true);
823  }
824  default:
825  {
826  if (typeCode < ResourceTypeCode.StartOfUserTypes)
827  {
828  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_TypeMismatch"));
829  }
830  int typeIndex = (int)(typeCode - 64);
831  return DeserializeObject(typeIndex);
832  }
833  }
834  }
835 
836  [SecurityCritical]
837  private object DeserializeObject(int typeIndex)
838  {
839  RuntimeType runtimeType = FindType(typeIndex);
840  if (_safeToDeserialize == null)
841  {
842  InitSafeToDeserializeArray();
843  }
844  object obj;
845  if (_safeToDeserialize[typeIndex])
846  {
847  _objFormatter.Binder = _typeLimitingBinder;
848  _typeLimitingBinder.ExpectingToDeserialize(runtimeType);
849  obj = _objFormatter.UnsafeDeserialize(_store.BaseStream, null);
850  }
851  else
852  {
853  _objFormatter.Binder = null;
854  obj = _objFormatter.Deserialize(_store.BaseStream);
855  }
856  if (obj.GetType() != runtimeType)
857  {
858  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResType&SerBlobMismatch", runtimeType.FullName, obj.GetType().FullName));
859  }
860  return obj;
861  }
862 
863  [SecurityCritical]
864  private void ReadResources()
865  {
866  BinaryFormatter binaryFormatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.File | StreamingContextStates.Persistence));
867  _typeLimitingBinder = new TypeLimitingDeserializationBinder();
868  binaryFormatter.Binder = _typeLimitingBinder;
869  _objFormatter = binaryFormatter;
870  try
871  {
872  _ReadResources();
873  }
874  catch (EndOfStreamException inner)
875  {
876  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"), inner);
877  }
878  catch (IndexOutOfRangeException inner2)
879  {
880  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"), inner2);
881  }
882  }
883 
884  [SecurityCritical]
885  private unsafe void _ReadResources()
886  {
887  int num = _store.ReadInt32();
888  if (num != ResourceManager.MagicNumber)
889  {
890  throw new ArgumentException(Environment.GetResourceString("Resources_StreamNotValid"));
891  }
892  int num2 = _store.ReadInt32();
893  int num3 = _store.ReadInt32();
894  if (num3 < 0 || num2 < 0)
895  {
896  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"));
897  }
898  if (num2 > 1)
899  {
900  _store.BaseStream.Seek(num3, SeekOrigin.Current);
901  }
902  else
903  {
904  string text = _store.ReadString();
905  AssemblyName asmName = new AssemblyName(ResourceManager.MscorlibName);
906  if (!ResourceManager.CompareNames(text, ResourceManager.ResReaderTypeName, asmName))
907  {
908  throw new NotSupportedException(Environment.GetResourceString("NotSupported_WrongResourceReader_Type", text));
909  }
910  SkipString();
911  }
912  int num4 = _store.ReadInt32();
913  if (num4 != 2 && num4 != 1)
914  {
915  throw new ArgumentException(Environment.GetResourceString("Arg_ResourceFileUnsupportedVersion", 2, num4));
916  }
917  _version = num4;
918  _numResources = _store.ReadInt32();
919  if (_numResources < 0)
920  {
921  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"));
922  }
923  int num5 = _store.ReadInt32();
924  if (num5 < 0)
925  {
926  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"));
927  }
928  _typeTable = new RuntimeType[num5];
929  _typeNamePositions = new int[num5];
930  for (int i = 0; i < num5; i++)
931  {
932  _typeNamePositions[i] = (int)_store.BaseStream.Position;
933  SkipString();
934  }
935  long position = _store.BaseStream.Position;
936  int num6 = (int)position & 7;
937  if (num6 != 0)
938  {
939  for (int j = 0; j < 8 - num6; j++)
940  {
941  _store.ReadByte();
942  }
943  }
944  if (_ums == null)
945  {
946  _nameHashes = new int[_numResources];
947  for (int k = 0; k < _numResources; k++)
948  {
949  _nameHashes[k] = _store.ReadInt32();
950  }
951  }
952  else
953  {
954  if ((_numResources & 3758096384u) != 0L)
955  {
956  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"));
957  }
958  int num7 = 4 * _numResources;
959  _nameHashesPtr = (int*)_ums.PositionPointer;
960  _ums.Seek(num7, SeekOrigin.Current);
961  byte* positionPointer = _ums.PositionPointer;
962  }
963  if (_ums == null)
964  {
965  _namePositions = new int[_numResources];
966  for (int l = 0; l < _numResources; l++)
967  {
968  int num8 = _store.ReadInt32();
969  if (num8 < 0)
970  {
971  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"));
972  }
973  _namePositions[l] = num8;
974  }
975  }
976  else
977  {
978  if ((_numResources & 3758096384u) != 0L)
979  {
980  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"));
981  }
982  int num9 = 4 * _numResources;
983  _namePositionsPtr = (int*)_ums.PositionPointer;
984  _ums.Seek(num9, SeekOrigin.Current);
985  byte* positionPointer2 = _ums.PositionPointer;
986  }
987  _dataSectionOffset = _store.ReadInt32();
988  if (_dataSectionOffset < 0)
989  {
990  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"));
991  }
992  _nameSectionOffset = _store.BaseStream.Position;
993  if (_dataSectionOffset < _nameSectionOffset)
994  {
995  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ResourcesHeaderCorrupted"));
996  }
997  }
998 
999  private RuntimeType FindType(int typeIndex)
1000  {
1001  if (typeIndex < 0 || typeIndex >= _typeTable.Length)
1002  {
1003  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_InvalidType"));
1004  }
1005  if (_typeTable[typeIndex] == null)
1006  {
1007  long position = _store.BaseStream.Position;
1008  try
1009  {
1010  _store.BaseStream.Position = _typeNamePositions[typeIndex];
1011  string typeName = _store.ReadString();
1012  _typeTable[typeIndex] = (RuntimeType)Type.GetType(typeName, throwOnError: true);
1013  }
1014  finally
1015  {
1016  _store.BaseStream.Position = position;
1017  }
1018  }
1019  return _typeTable[typeIndex];
1020  }
1021 
1022  [SecurityCritical]
1023  private void InitSafeToDeserializeArray()
1024  {
1025  _safeToDeserialize = new bool[_typeTable.Length];
1026  for (int i = 0; i < _typeTable.Length; i++)
1027  {
1028  long position = _store.BaseStream.Position;
1029  string text;
1030  try
1031  {
1032  _store.BaseStream.Position = _typeNamePositions[i];
1033  text = _store.ReadString();
1034  }
1035  finally
1036  {
1037  _store.BaseStream.Position = position;
1038  }
1039  RuntimeType runtimeType = (RuntimeType)Type.GetType(text, throwOnError: false);
1040  AssemblyName assemblyName;
1041  string typeName;
1042  if (runtimeType == null)
1043  {
1044  assemblyName = null;
1045  typeName = text;
1046  }
1047  else
1048  {
1049  if (runtimeType.BaseType == typeof(Enum))
1050  {
1051  _safeToDeserialize[i] = true;
1052  continue;
1053  }
1054  typeName = runtimeType.FullName;
1055  assemblyName = new AssemblyName();
1056  RuntimeAssembly runtimeAssembly = (RuntimeAssembly)runtimeType.Assembly;
1057  assemblyName.Init(runtimeAssembly.GetSimpleName(), runtimeAssembly.GetPublicKey(), null, null, runtimeAssembly.GetLocale(), AssemblyHashAlgorithm.None, AssemblyVersionCompatibility.SameMachine, null, AssemblyNameFlags.PublicKey, null);
1058  }
1059  string[] typesSafeForDeserialization = TypesSafeForDeserialization;
1060  foreach (string asmTypeName in typesSafeForDeserialization)
1061  {
1062  if (ResourceManager.CompareNames(asmTypeName, typeName, assemblyName))
1063  {
1064  _safeToDeserialize[i] = true;
1065  }
1066  }
1067  }
1068  }
1069 
1083  public void GetResourceData(string resourceName, out string resourceType, out byte[] resourceData)
1084  {
1085  if (resourceName == null)
1086  {
1087  throw new ArgumentNullException("resourceName");
1088  }
1089  if (_resCache == null)
1090  {
1091  throw new InvalidOperationException(Environment.GetResourceString("ResourceReaderIsClosed"));
1092  }
1093  int[] array = new int[_numResources];
1094  int num = FindPosForResource(resourceName);
1095  if (num == -1)
1096  {
1097  throw new ArgumentException(Environment.GetResourceString("Arg_ResourceNameNotExist", resourceName));
1098  }
1099  lock (this)
1100  {
1101  for (int i = 0; i < _numResources; i++)
1102  {
1103  _store.BaseStream.Position = _nameSectionOffset + GetNamePosition(i);
1104  int num2 = _store.Read7BitEncodedInt();
1105  if (num2 < 0)
1106  {
1107  throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesNameInvalidOffset", num2));
1108  }
1109  _store.BaseStream.Position += num2;
1110  int num3 = _store.ReadInt32();
1111  if (num3 < 0 || num3 >= _store.BaseStream.Length - _dataSectionOffset)
1112  {
1113  throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourcesDataInvalidOffset", num3));
1114  }
1115  array[i] = num3;
1116  }
1117  Array.Sort(array);
1118  int num4 = Array.BinarySearch(array, num);
1119  long num5 = (num4 < _numResources - 1) ? (array[num4 + 1] + _dataSectionOffset) : _store.BaseStream.Length;
1120  int num6 = (int)(num5 - (num + _dataSectionOffset));
1121  _store.BaseStream.Position = _dataSectionOffset + num;
1122  ResourceTypeCode resourceTypeCode = (ResourceTypeCode)_store.Read7BitEncodedInt();
1123  if (resourceTypeCode < ResourceTypeCode.Null || (int)resourceTypeCode >= 64 + _typeTable.Length)
1124  {
1125  throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_InvalidType"));
1126  }
1127  resourceType = TypeNameFromTypeCode(resourceTypeCode);
1128  num6 -= (int)(_store.BaseStream.Position - (_dataSectionOffset + num));
1129  byte[] array2 = _store.ReadBytes(num6);
1130  if (array2.Length != num6)
1131  {
1132  throw new FormatException(Environment.GetResourceString("BadImageFormat_ResourceNameCorrupted"));
1133  }
1134  resourceData = array2;
1135  }
1136  }
1137 
1138  private string TypeNameFromTypeCode(ResourceTypeCode typeCode)
1139  {
1140  if (typeCode < ResourceTypeCode.StartOfUserTypes)
1141  {
1142  return "ResourceTypeCode." + typeCode.ToString();
1143  }
1144  int num = (int)(typeCode - 64);
1145  long position = _store.BaseStream.Position;
1146  try
1147  {
1148  _store.BaseStream.Position = _typeNamePositions[num];
1149  return _store.ReadString();
1150  }
1151  finally
1152  {
1153  _store.BaseStream.Position = position;
1154  }
1155  }
1156  }
1157 }
Represents a character encoding.To browse the .NET Framework source code for this type,...
Definition: Encoding.cs:15
override string ToString()
Creates and returns a string representation of the current exception.
Definition: Exception.cs:474
object UnsafeDeserialize(Stream serializationStream, HeaderHandler handler)
Deserializes the specified stream into an object graph. The provided T:System.Runtime....
override long Length
Gets the length of the data in a stream.
virtual void Close()
Closes the current reader and the underlying stream.
The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method th...
unsafe string GetString(byte *bytes, int byteCount)
When overridden in a derived class, decodes a specified number of bytes starting at a specified addre...
Definition: Encoding.cs:1918
The exception that is thrown when reading is attempted past the end of a stream.
IDictionaryEnumerator GetEnumerator()
Returns an enumerator for this T:System.Resources.ResourceReader object.
FileOptions
Represents advanced options for creating a T:System.IO.FileStream object.
Definition: FileOptions.cs:9
override long Position
Gets or sets the current position in a stream.
virtual int ReadInt32()
Reads a 4-byte signed integer from the current stream and advances the current position of the stream...
ResourceReader(Stream stream)
Initializes a new instance of the T:System.Resources.ResourceReader class for the specified stream.
void Dispose()
Releases all resources used by the current instance of the T:System.Resources.ResourceReader class.
Allows users to control class loading and mandate what class to load.
virtual ulong ReadUInt64()
Reads an 8-byte unsigned integer from the current stream and advances the position of the stream by e...
FileMode
Specifies how the operating system should open a file.
Definition: FileMode.cs:8
static Encoding Unicode
Gets an encoding for the UTF-16 format using the little endian byte order.
Definition: Encoding.cs:975
Provides a mechanism for releasing unmanaged resources.To browse the .NET Framework source code for t...
Definition: IDisposable.cs:8
Definition: __Canon.cs:3
Specifies the current position within a stream.
void Close()
Releases all operating system resources associated with this T:System.Resources.ResourceReader object...
AssemblyNameFlags
Provides information about an T:System.Reflection.Assembly reference.
virtual decimal ReadDecimal()
Reads a decimal value from the current stream and advances the current position of the stream by sixt...
unsafe override int Read([In] [Out] byte[] buffer, int offset, int count)
Reads the specified number of bytes into the specified array.
static string GetFileName(string path)
Returns the file name and extension of the specified path string.
Definition: Path.cs:914
Describes the source and destination of a given serialized stream, and provides an additional caller-...
object Deserialize(Stream serializationStream)
Deserializes the specified stream into an object graph.
void GetResourceData(string resourceName, out string resourceType, out byte[] resourceData)
Retrieves the type name and data of a named resource from an open resource file or stream.
virtual byte ReadByte()
Reads the next byte from the current stream and advances the current position of the stream by one by...
virtual bool IsEnum
Gets a value indicating whether the current T:System.Type represents an enumeration.
Definition: Type.cs:484
Represents a resource manager that provides convenient access to culture-specific resources at run ti...
virtual ushort ReadUInt16()
Reads a 2-byte unsigned integer from the current stream using little-endian encoding and advances the...
A type representing a date and time value.
Serializes and deserializes an object, or an entire graph of connected objects, in binary format.
SeekOrigin
Specifies the position in a stream to use for seeking.
Definition: SeekOrigin.cs:9
Provides the base functionality for reading data from resource files.
virtual short ReadInt16()
Reads a 2-byte signed integer from the current stream and advances the current position of the stream...
abstract bool CanRead
When overridden in a derived class, gets a value indicating whether the current stream supports readi...
Definition: Stream.cs:577
virtual uint ReadUInt32()
Reads a 4-byte unsigned integer from the current stream and advances the position of the stream by fo...
Exposes an enumerator, which supports a simple iteration over a non-generic collection....
Definition: IEnumerable.cs:9
Provides information about, and means to manipulate, the current environment and platform....
Definition: Environment.cs:21
virtual sbyte ReadSByte()
Reads a signed byte from this stream and advances the current position of the stream by one byte.
static void Sort(Array array)
Sorts the elements in an entire one-dimensional T:System.Array using the T:System....
Definition: Array.cs:3259
unsafe byte * PositionPointer
Gets or sets a byte pointer to a stream based on the current position in the stream.
The exception that is thrown when the format of an argument is invalid, or when a composite format st...
SerializationBinder Binder
Gets or sets an object of type T:System.Runtime.Serialization.SerializationBinder that controls the b...
virtual byte [] ReadBytes(int count)
Reads the specified number of bytes from the current stream into a byte array and advances the curren...
virtual bool ReadBoolean()
Reads a Boolean value from the current stream and advances the current position of the stream by one ...
Provides a T:System.IO.Stream for a file, supporting both synchronous and asynchronous read and write...
Definition: FileStream.cs:15
Reads primitive data types as binary values in a specific encoding.
Definition: BinaryReader.cs:10
Provides methods for creating, manipulating, searching, and sorting arrays, thereby serving as the ba...
Definition: Array.cs:17
Represents type declarations: class types, interface types, array types, value types,...
Definition: Type.cs:18
virtual int Read()
Reads characters from the underlying stream and advances the current position of the stream in accord...
abstract long Seek(long offset, SeekOrigin origin)
When overridden in a derived class, sets the position within the current stream.
static int BinarySearch(Array array, object value)
Searches an entire one-dimensional sorted array for a specific element, using the T:System....
Definition: Array.cs:2060
IEnumerator GetEnumerator()
Returns an enumerator that iterates through a collection.
Enumerates the resources in a binary resources (.resources) file by reading sequential resource name/...
AssemblyVersionCompatibility
Defines the different types of assembly version compatibility. This feature is not available in versi...
Describes an assembly's unique identity in full.
Definition: AssemblyName.cs:19
override long Seek(long offset, SeekOrigin loc)
Sets the current position of the current stream to the given value.
virtual Stream BaseStream
Exposes access to the underlying stream of the T:System.IO.BinaryReader.
Definition: BinaryReader.cs:38
The exception that is thrown when one of the arguments provided to a method is not valid.
abstract long Length
When overridden in a derived class, gets the length in bytes of the stream.
Definition: Stream.cs:621
virtual unsafe float ReadSingle()
Reads a 4-byte floating point value from the current stream and advances the current position of the ...
FileAccess
Defines constants for read, write, or read/write access to a file.
Definition: FileAccess.cs:9
abstract long Position
When overridden in a derived class, gets or sets the position within the current stream.
Definition: Stream.cs:633
Enumerates the elements of a nongeneric dictionary.
virtual unsafe double ReadDouble()
Reads an 8-byte floating point value from the current stream and advances the current position of the...
static Encoding UTF8
Gets an encoding for the UTF-8 format.
Definition: Encoding.cs:1023
The exception that is thrown when a method call is invalid for the object's current state.
virtual string ReadString()
Reads a string from the current stream. The string is prefixed with the length, encoded as an integer...
Provides access to unmanaged blocks of memory from managed code.
StreamingContextStates
Defines a set of flags that specifies the source or destination context for the stream during seriali...
The exception that is thrown when the file image of a dynamic link library (DLL) or an executable pro...
ResourceReader(string fileName)
Initializes a new instance of the T:System.Resources.ResourceReader class for the specified named res...
virtual long ReadInt64()
Reads an 8-byte signed integer from the current stream and advances the current position of the strea...
Defines a dictionary key/value pair that can be set or retrieved.
bool TryGetValue(TKey key, out TValue value)
Gets the value associated with the specified key.
Definition: Dictionary.cs:1624
internal int Read7BitEncodedInt()
Reads in a 32-bit integer in compressed format.
Supports a simple iteration over a non-generic collection.
Definition: IEnumerator.cs:9
Performs operations on T:System.String instances that contain file or directory path information....
Definition: Path.cs:13
string FullName
Gets the full name of the assembly, also known as the display name.
AssemblyHashAlgorithm
Specifies all the hash algorithms used for hashing files and for generating the strong name.
FileShare
Contains constants for controlling the kind of access other T:System.IO.FileStream objects can have t...
Definition: FileShare.cs:9
Provides a generic view of a sequence of bytes. This is an abstract class.To browse the ....
Definition: Stream.cs:16