public MoveToResourceViewModel(ICollection <string> patterns, ICollection <ResourceEntity> resourceEntities, string text, string extension, string className, string functionName) { Contract.Requires(patterns != null); Contract.Requires(resourceEntities != null); Contract.Requires(text != null); Contract.Requires(extension != null); _patterns = patterns; _resourceEntities = resourceEntities; _existingEntries = resourceEntities .SelectMany(entity => entity.Entries) .Where(entry => entry.Values[null] == text) .ToArray(); _reuseExisiting = _existingEntries.Any(); _selectedResourceEntry = _existingEntries.FirstOrDefault(); _value = text; _extension = extension; if (!_reuseExisiting) { _key = CreateKey(text, className, functionName); } Dispatcher.BeginInvoke(DispatcherPriority.Background, () => OnPropertyChanged(nameof(Key))); }
public TranslationItem([NotNull] ResourceTableEntry entry, [NotNull] string source, [NotNull] CultureKey targetCulture) { _entry = entry; Source = source; TargetCulture = targetCulture; _results.CollectionChanged += (_, __) => OnPropertyChanged(() => Translation); }
public void SelectEntry([NotNull] ResourceTableEntry entry) { SelectedTabIndex = 0; Dispatcher.BeginInvoke(DispatcherPriority.Background, () => { _resourceViewModel.SelectEntry(entry); }); }
public void SelectEntry([NotNull] ResourceTableEntry entry) { VSPackage.Instance.ShowToolWindow(); Dispatcher.BeginInvoke(DispatcherPriority.Background, () => { _shellViewModel.SelectEntry(entry); }); }
public void SelectEntry(ResourceTableEntry entry) { ThrowIfNotOnUIThread(); VsPackage.Instance.ShowToolWindow(); #pragma warning disable VSTHRD001 // Avoid legacy thread switching APIs // Must defer selection until tool window is fully shown! Dispatcher.BeginInvoke(DispatcherPriority.Background, () => _shellViewModel.SelectEntry(entry)); #pragma warning restore VSTHRD001 // Avoid legacy thread switching APIs }
public void Remove(ResourceTableEntry entry) { var task = _tasks.OfType <ResourceErrorTask>().FirstOrDefault(t => t.Entry == entry); if (task == null) { return; } _tasks.Remove(task); }
public void SelectEntry(ResourceTableEntry entry) { Microsoft.VisualStudio.Shell.ThreadHelper.ThrowIfNotOnUIThread(); VsPackage.Instance.ShowToolWindow(); Dispatcher.BeginInvoke(DispatcherPriority.Background, () => { _shellViewModel.SelectEntry(entry); }); }
public TranslationItem([NotNull] ResourceTableEntry entry, [NotNull] string source, [NotNull] CultureKey targetCulture) { Contract.Requires(entry != null); Contract.Requires(source != null); Contract.Requires(targetCulture != null); _entry = entry; _source = source; _targetCulture = targetCulture; _results.CollectionChanged += (_, __) => OnPropertyChanged(() => Translation); }
public TranslationItem([NotNull] ResourceTableEntry entry, [NotNull] string source, [NotNull] CultureKey targetCulture) { Contract.Requires(entry != null); Contract.Requires(source != null); Contract.Requires(targetCulture != null); _entry = entry; _source = source; _targetCulture = targetCulture; _results.CollectionChanged += (_, __) => OnPropertyChanged(() => Translation); _orderedResults = new ListCollectionView(_results); _orderedResults.SortDescriptions.Add(new SortDescription("Rating", ListSortDirection.Descending)); _orderedResults.SortDescriptions.Add(new SortDescription("Translator.DisplayName", ListSortDirection.Ascending)); }
public void SelectEntry([NotNull] ResourceTableEntry entry) { if (!ResourceManager.TableEntries.Contains(entry)) { return; } var entity = entry.Container; if (!SelectedEntities.Contains(entity)) { SelectedEntities.Add(entity); } SelectedTableEntries.Clear(); SelectedTableEntries.Add(entry); }
public void SelectEntry([NotNull] ResourceTableEntry entry) { if (!ResourceManager.TableEntries.Contains(entry)) { return; } var entity = entry.Container; ClearFiltersRequest?.Invoke(this, EventArgs.Empty); if (!SelectedEntities.Contains(entity)) { SelectedEntities.Add(entity); } SelectedTableEntries.Clear(); SelectedTableEntries.Add(entry); }
public ResourceErrorTask(ResourceTableEntry entry) { Entry = entry; }
public ResourceTableEntry MoveToResource(EnvDTE.Document document) { var extension = Path.GetExtension(document?.FullName); if (extension == null) { return(null); } var configurationItems = _compositionHost.GetExportedValue <DteConfiguration>().MoveToResources.Items; var configuration = configurationItems .FirstOrDefault(item => item.ParseExtensions().Contains(extension, StringComparer.OrdinalIgnoreCase)); if (configuration == null) { return(null); } Contract.Assume(document != null); var selection = GetSelection(document); if (selection == null) { return(null); } IParser parser = new GenericParser(); var text = !selection.IsEmpty ? selection.Text?.Trim('"') : parser.LocateString(selection, true); if (string.IsNullOrEmpty(text)) { return(null); } var patterns = configuration.ParsePatterns().ToArray(); var resourceViewModel = _compositionHost.GetExportedValue <ResourceViewModel>(); resourceViewModel.Reload(); var resourceManager = _compositionHost.GetExportedValue <ResourceManager>(); var entities = resourceManager.ResourceEntities .Where(entity => !entity.IsWinFormsDesignerResource) .ToArray(); var filter = Settings.Default?.ResourceFilter?.Trim(); if (!string.IsNullOrEmpty(filter)) { var regex = new Regex(filter, RegexOptions.IgnoreCase | RegexOptions.Singleline); entities = entities .Where(item => regex.Match(item.ToString()).Success) .ToArray(); } var favorites = new[] { GetPreferredResourceEntity(document, entities), _lastUsedEntity } .Where(item => item != null) .ToArray(); entities = favorites .Concat(entities.Except(favorites)) .ToArray(); var viewModel = new MoveToResourceViewModel(patterns, entities, text, extension, selection.ClassName, selection.FunctionName); var confirmed = ConfirmationDialog.Show(_compositionHost.Container, viewModel, Resources.MoveToResource).GetValueOrDefault(); if (confirmed && !string.IsNullOrEmpty(viewModel.Key)) { ResourceTableEntry entry = null; if (!viewModel.ReuseExisiting) { var entity = _lastUsedEntity = viewModel.SelectedResourceEntity; entry = entity?.Add(viewModel.Key); if (entry == null) { return(null); } entry.Values[null] = viewModel.Value; entry.Comment = viewModel.Comment; } selection.ReplaceWith(viewModel.Replacement); return(entry); } return(null); }
void Initialize() { Recognized = false; if (BaseStream == null) { return; } BaseExecutable = new MZ(BaseStream); if (!BaseExecutable.Recognized) { return; } if (BaseExecutable.Header.new_offset >= BaseStream.Length) { return; } BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin); byte[] buffer = new byte[Marshal.SizeOf(typeof(NEHeader))]; BaseStream.Read(buffer, 0, buffer.Length); IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length); Marshal.Copy(buffer, 0, hdrPtr, buffer.Length); Header = (NEHeader)Marshal.PtrToStructure(hdrPtr, typeof(NEHeader)); Marshal.FreeHGlobal(hdrPtr); if (Header.signature != SIGNATURE) { return; } Recognized = true; Type = "New Executable (NE)"; List <string> strings = new List <string>(); OperatingSystem reqOs = new OperatingSystem(); switch (Header.target_os) { case TargetOS.OS2: reqOs.Name = "OS/2"; if (Header.os_major > 0) { reqOs.MajorVersion = Header.os_major; reqOs.MinorVersion = Header.os_minor; } else { reqOs.MajorVersion = 1; reqOs.MinorVersion = 0; } if (Header.application_flags.HasFlag(ApplicationFlags.FullScreen) && !Header.application_flags.HasFlag(ApplicationFlags.GUICompatible) || !Header.application_flags.HasFlag(ApplicationFlags.FullScreen) && Header.application_flags.HasFlag(ApplicationFlags.GUICompatible)) { reqOs.Subsystem = "Console"; } else if (Header.application_flags.HasFlag(ApplicationFlags.FullScreen) && Header.application_flags.HasFlag(ApplicationFlags.GUICompatible)) { reqOs.Subsystem = "Presentation Manager"; } break; case TargetOS.Windows: case TargetOS.Win32: case TargetOS.Unknown: reqOs.Name = "Windows"; if (Header.os_major > 0) { reqOs.MajorVersion = Header.os_major; reqOs.MinorVersion = Header.os_minor; } else { switch (Header.target_os) { case TargetOS.Windows: reqOs.MajorVersion = 2; reqOs.MinorVersion = 0; break; case TargetOS.Unknown: reqOs.MajorVersion = 1; reqOs.MinorVersion = 0; break; } } break; case TargetOS.DOS: case TargetOS.Borland: reqOs.Name = "DOS"; reqOs.MajorVersion = Header.os_major; reqOs.MinorVersion = Header.os_minor; if (Header.target_os == TargetOS.Borland) { reqOs.Subsystem = "Borland Operating System Services"; } break; default: reqOs.Name = $"Unknown code {(byte)Header.target_os}"; reqOs.MajorVersion = Header.os_major; reqOs.MinorVersion = Header.os_minor; break; } RequiredOperatingSystem = reqOs; if (Header.segment_count > 0 && Header.segment_table_offset > 0 && Header.segment_table_offset + BaseExecutable.Header.new_offset < BaseStream.Length) { BaseStream.Position = Header.segment_table_offset + BaseExecutable.Header.new_offset; segments = new SegmentEntry[Header.segment_count]; for (int i = 0; i < segments.Length; i++) { buffer = new byte[Marshal.SizeOf(typeof(SegmentEntry))]; BaseStream.Read(buffer, 0, buffer.Length); segments[i] = BigEndianMarshal.ByteArrayToStructureLittleEndian <SegmentEntry>(buffer); } } // Some executable indicates 0 entries, some indicate a table start and no limit, will need to explore till next item ushort resourceUpperLimit = ushort.MaxValue; if (Header.entry_table_offset >= Header.resource_table_offset && Header.entry_table_offset <= resourceUpperLimit) { resourceUpperLimit = Header.entry_table_offset; } if (Header.segment_table_offset >= Header.resource_table_offset && Header.segment_table_offset <= resourceUpperLimit) { resourceUpperLimit = Header.segment_table_offset; } if (Header.module_reference_offset >= Header.resource_table_offset && Header.module_reference_offset <= resourceUpperLimit) { resourceUpperLimit = Header.module_reference_offset; } if (Header.nonresident_names_offset >= Header.resource_table_offset && Header.nonresident_names_offset <= resourceUpperLimit) { resourceUpperLimit = (ushort)Header.nonresident_names_offset; } if (Header.resident_names_offset >= Header.resource_table_offset && Header.resident_names_offset <= resourceUpperLimit) { resourceUpperLimit = Header.resident_names_offset; } if (Header.imported_names_offset >= Header.resource_table_offset && Header.imported_names_offset <= resourceUpperLimit) { resourceUpperLimit = Header.imported_names_offset; } if (Header.resource_table_offset < resourceUpperLimit && Header.resource_table_offset != 0) { if (Header.target_os == TargetOS.Windows || Header.target_os == TargetOS.Win32 || Header.target_os == TargetOS.Unknown) { Resources = GetResources(BaseStream, BaseExecutable.Header.new_offset, Header.resource_table_offset, resourceUpperLimit); for (int t = 0; t < Resources.types.Length; t++) { Resources.types[t].resources = Resources.types[t].resources.OrderBy(r => r.name).ToArray(); } Resources.types = Resources.types.OrderBy(t => t.name).ToArray(); Versions = GetVersions().ToArray(); strings.AddRange(from v in Versions from s in v.StringsByLanguage from k in s.Value select k.Value); foreach (ResourceType rtype in Resources.types) { if (rtype.name != "RT_STRING") { continue; } strings.AddRange(GetWindowsStrings(rtype)); } } else if (Header.target_os == TargetOS.OS2 && segments != null && Header.resource_entries > 0) { BaseStream.Position = BaseExecutable.Header.new_offset + Header.resource_table_offset; buffer = new byte[Header.resource_entries * 4]; BaseStream.Read(buffer, 0, buffer.Length); ResourceTableEntry[] entries = new ResourceTableEntry[Header.resource_entries]; for (int i = 0; i < entries.Length; i++) { entries[i].etype = BitConverter.ToUInt16(buffer, i * 4 + 0); entries[i].ename = BitConverter.ToUInt16(buffer, i * 4 + 2); } SegmentEntry[] resourceSegments = new SegmentEntry[Header.resource_entries]; Array.Copy(segments, Header.segment_count - Header.resource_entries, resourceSegments, 0, Header.resource_entries); SegmentEntry[] realSegments = new SegmentEntry[Header.segment_count - Header.resource_entries]; Array.Copy(segments, 0, realSegments, 0, realSegments.Length); segments = realSegments; SortedDictionary <ushort, List <Resource> > os2resources = new SortedDictionary <ushort, List <Resource> >(); for (int i = 0; i < entries.Length; i++) { os2resources.TryGetValue(entries[i].etype, out List <Resource> thisResourceType); if (thisResourceType == null) { thisResourceType = new List <Resource>(); } Resource thisResource = new Resource { id = entries[i].ename, name = $"{entries[i].ename}", flags = (ResourceFlags)resourceSegments[i].dwFlags, dataOffset = (uint)(resourceSegments[i].dwLogicalSectorOffset << Header.alignment_shift), length = resourceSegments[i].dwSegmentLength }; if (thisResource.length == 0) { thisResource.length = 65536; } if (thisResource.dataOffset == 0) { thisResource.dataOffset = 65536; } if ((resourceSegments[i].dwFlags & (ushort)SegmentFlags.Huge) == (ushort)SegmentFlags.Huge) { thisResource.length <<= Header.alignment_shift; } thisResource.data = new byte[thisResource.length]; BaseStream.Position = thisResource.dataOffset; BaseStream.Read(thisResource.data, 0, thisResource.data.Length); thisResourceType.Add(thisResource); os2resources.Remove(entries[i].etype); os2resources.Add(entries[i].etype, thisResourceType); } if (os2resources.Count > 0) { Resources = new ResourceTable(); int counter = 0; Resources.types = new ResourceType[os2resources.Count]; foreach (KeyValuePair <ushort, List <Resource> > kvp in os2resources) { Resources.types[counter].count = (ushort)kvp.Value.Count; Resources.types[counter].id = kvp.Key; Resources.types[counter].name = Os2.Resources.IdToName(kvp.Key); Resources.types[counter].resources = kvp.Value.OrderBy(r => r.id).ToArray(); counter++; } foreach (ResourceType rtype in Resources.types) { if (rtype.name != "RT_STRING") { continue; } strings.AddRange(GetOs2Strings(rtype)); } } } } resourceUpperLimit = ushort.MaxValue; if (Header.entry_table_offset >= Header.module_reference_offset && Header.entry_table_offset <= resourceUpperLimit) { resourceUpperLimit = Header.entry_table_offset; } if (Header.segment_table_offset >= Header.module_reference_offset && Header.segment_table_offset <= resourceUpperLimit) { resourceUpperLimit = Header.segment_table_offset; } if (Header.resource_table_offset >= Header.module_reference_offset && Header.resource_table_offset <= resourceUpperLimit) { resourceUpperLimit = Header.resource_table_offset; } if (Header.nonresident_names_offset >= Header.module_reference_offset && Header.nonresident_names_offset <= resourceUpperLimit) { resourceUpperLimit = (ushort)Header.nonresident_names_offset; } if (Header.imported_names_offset >= Header.module_reference_offset && Header.imported_names_offset <= resourceUpperLimit) { resourceUpperLimit = Header.imported_names_offset; } if (Header.module_reference_offset < resourceUpperLimit && Header.module_reference_offset != 0 && Header.reference_count > 0) { short[] referenceOffsets = new short[Header.reference_count]; buffer = new byte[2]; BaseStream.Position = Header.module_reference_offset + BaseExecutable.Header.new_offset; for (int i = 0; i < Header.reference_count; i++) { BaseStream.Read(buffer, 0, 2); referenceOffsets[i] = BitConverter.ToInt16(buffer, 0); } ImportedNames = new string[Header.reference_count]; for (int i = 0; i < Header.reference_count; i++) { BaseStream.Position = Header.imported_names_offset + BaseExecutable.Header.new_offset + referenceOffsets[i]; int len = BaseStream.ReadByte(); buffer = new byte[len]; BaseStream.Read(buffer, 0, len); ImportedNames[i] = Encoding.ASCII.GetString(buffer); } } resourceUpperLimit = ushort.MaxValue; if (Header.entry_table_offset >= Header.resident_names_offset && Header.entry_table_offset <= resourceUpperLimit) { resourceUpperLimit = Header.entry_table_offset; } if (Header.segment_table_offset >= Header.resident_names_offset && Header.segment_table_offset <= resourceUpperLimit) { resourceUpperLimit = Header.segment_table_offset; } if (Header.module_reference_offset >= Header.resident_names_offset && Header.module_reference_offset <= resourceUpperLimit) { resourceUpperLimit = Header.module_reference_offset; } if (Header.nonresident_names_offset >= Header.resident_names_offset && Header.nonresident_names_offset <= resourceUpperLimit) { resourceUpperLimit = (ushort)Header.nonresident_names_offset; } if (Header.imported_names_offset >= Header.resident_names_offset && Header.imported_names_offset <= resourceUpperLimit) { resourceUpperLimit = Header.imported_names_offset; } if (Header.resident_names_offset < resourceUpperLimit && Header.resident_names_offset != 0) { ResidentNames = GetResidentStrings(BaseStream, BaseExecutable.Header.new_offset, Header.resident_names_offset, resourceUpperLimit); if (ResidentNames.Length >= 1) { ModuleName = ResidentNames[0].name; if (ResidentNames.Length > 1) { ResidentName[] newResidentNames = new ResidentName[ResidentNames.Length - 1]; Array.Copy(ResidentNames, 1, newResidentNames, 0, ResidentNames.Length - 1); ResidentNames = newResidentNames; } else { ResidentNames = null; } } } if (Header.nonresident_table_size > 0) { NonResidentNames = GetResidentStrings(BaseStream, Header.nonresident_names_offset, 0, (ushort)(Header.nonresident_names_offset + Header.nonresident_table_size)); if (NonResidentNames.Length >= 1) { ModuleDescription = NonResidentNames[0].name; if (NonResidentNames.Length > 1) { ResidentName[] newNonResidentNames = new ResidentName[NonResidentNames.Length - 1]; Array.Copy(NonResidentNames, 1, newNonResidentNames, 0, NonResidentNames.Length - 1); NonResidentNames = newNonResidentNames; } else { NonResidentNames = null; } } } if (!string.IsNullOrEmpty(ModuleName)) { strings.Add(ModuleName); } if (!string.IsNullOrEmpty(ModuleDescription)) { strings.Add(ModuleDescription); } if (strings.Count > 0) { Strings = strings.Distinct().OrderBy(s => s); } if (segments == null) { return; } List <Segment> libsegs = new List <Segment>(); foreach (SegmentEntry seg in segments) { Segment libseg = new Segment { Flags = $"{(SegmentFlags)(seg.dwFlags & SEGMENT_FLAGS_MASK)}", Name = (SegmentType)(seg.dwFlags & SEGMENT_TYPE_MASK) == SegmentType.Code ? ".text" : ".data", Offset = seg.dwLogicalSectorOffset << Header.alignment_shift, Size = seg.dwSegmentLength }; if (Header.target_os == TargetOS.OS2 && (seg.dwFlags & (int)SegmentFlags.Huge) == (int)SegmentFlags.Huge) { libseg.Size <<= Header.alignment_shift; } libsegs.Add(libseg); } Segments = libsegs.OrderBy(s => s.Offset).ToArray(); }
private void Provider_Navigate(ResourceTableEntry entry) { ThrowIfNotOnUIThread(); _shellViewModel.SelectEntry(entry); }
public ResourceTableEntry MoveToResource(Document document) { var extension = Path.GetExtension(document?.FullName); if (extension == null) { return(null); } var configurationItems = _exportProvider.GetExportedValue <DteConfiguration>().MoveToResources.Items; var configuration = configurationItems .FirstOrDefault(item => item.ParseExtensions().Contains(extension, StringComparer.OrdinalIgnoreCase)); if (configuration == null) { return(null); } Contract.Assume(document != null); var selection = GetSelection(document); if (selection == null) { return(null); } IParser parser = new GenericParser(); var text = !selection.IsEmpty ? selection.Text?.Trim('"') : parser.LocateString(selection, true); if (string.IsNullOrEmpty(text)) { return(null); } var patterns = configuration.ParsePatterns().ToArray(); var resourceManager = _exportProvider.GetExportedValue <ResourceManager>(); resourceManager.Reload(ResourceLoadOptions.None); var entities = resourceManager.ResourceEntities .Where(entity => !entity.IsWinFormsDesignerResource) .ToArray(); var viewModel = new MoveToResourceViewModel(patterns, entities, text, extension, selection.ClassName, selection.FunctionName) { SelectedResourceEntity = GetPreferredResourceEntity(document, entities) ?? _lastUsedEntity }; var confirmed = ConfirmationDialog.Show(_exportProvider, viewModel, Resources.MoveToResource).GetValueOrDefault(); if (confirmed && !string.IsNullOrEmpty(viewModel.Key)) { ResourceTableEntry entry = null; if (!viewModel.ReuseExisiting) { var entity = _lastUsedEntity = viewModel.SelectedResourceEntity; entry = entity?.Add(viewModel.Key); if (entry == null) { return(null); } entry.Values[null] = viewModel.Value; entry.Comment = viewModel.Comment; } selection.ReplaceWith(viewModel.Replacement); return(entry); } ; return(null); }
public ResourceTableEntry MoveToResource([CanBeNull] EnvDTE.Document document) { var extension = Path.GetExtension(document?.FullName); if (extension == null) { return(null); } var fileName = Path.GetFileNameWithoutExtension(document.FullName); var configurationItems = _exportProvider.GetExportedValue <DteConfiguration>().MoveToResources.Items; var configuration = configurationItems .FirstOrDefault(item => item.ParseExtensions().Contains(extension, StringComparer.OrdinalIgnoreCase)); if (configuration == null) { return(null); } var selection = GetSelection(document); if (selection == null) { return(null); } IParser parser = new GenericParser(); var text = !selection.IsEmpty ? selection.Text?.Trim('"') : parser.LocateString(selection, true); if (string.IsNullOrEmpty(text)) { return(null); } var patterns = configuration.ParsePatterns().ToArray(); var resourceViewModel = _exportProvider.GetExportedValue <ResourceViewModel>(); resourceViewModel.Reload(); var resourceManager = _exportProvider.GetExportedValue <ResourceManager>(); var entities = resourceManager.ResourceEntities .Where(entity => !entity.IsWinFormsDesignerResource) .ToList(); var filter = EntityFilter.BuildFilter(Settings.Default.ResourceFilter); if (filter != null) { entities.RemoveAll(item => !filter(item.ToString())); } var projectResources = new HashSet <ResourceEntity>(GetResourceEntiesFromProject(document, entities)); // put resources from the same project on top entities.RemoveAll(entity => projectResources.Contains(entity)); entities.InsertRange(0, projectResources); // put the last used entry on top, if it's in the same project, or the last access was cross-project. if (_lastUsedEntity != null) { if (!_isLastUsedEntityInSameProject || IsInProject(_lastUsedEntity, document)) { entities.Remove(_lastUsedEntity); entities.Insert(0, _lastUsedEntity); } } var viewModel = new MoveToResourceViewModel(patterns, entities, text, extension, selection.ClassName, selection.FunctionName, fileName); var confirmed = ConfirmationDialog.Show(_exportProvider, viewModel, Resources.MoveToResource, null).GetValueOrDefault(); if (!confirmed || string.IsNullOrEmpty(viewModel.Key)) { return(null); } ResourceTableEntry entry = null; if (!viewModel.ReuseExisiting) { var entity = _lastUsedEntity = viewModel.SelectedResourceEntity; if (entity == null) { return(null); } _isLastUsedEntityInSameProject = IsInProject(entity, document); entry = entity.Add(viewModel.Key); if (entry == null) { return(null); } entry.Values[null] = viewModel.Value; entry.Comment = viewModel.Comment; } selection.ReplaceWith(viewModel.Replacement?.Value); return(entry); }
/// <summary> /// Reads in the NE resources from OS/2. /// </summary> public List <ProgramResource> LoadOs2Resources(NeImageLoader.NeSegment[] segments, ushort segmentCount, ushort alignmentShift) { List <ProgramResource> resources = new List <ProgramResource>(); var rsrcTable = new LeImageReader(RawImage, OffRsrcTable); var rdr = rsrcTable.Clone(); ResourceTableEntry[] entries = new ResourceTableEntry[ResourceTableEntries]; for (int i = 0; i < entries.Length; i++) { entries[i].etype = rdr.ReadUInt16(); entries[i].ename = rdr.ReadUInt16(); } NeImageLoader.NeSegment[] resourceSegments = new NeImageLoader.NeSegment[ResourceTableEntries]; Array.Copy(segments, segmentCount - ResourceTableEntries, resourceSegments, 0, ResourceTableEntries); NeImageLoader.NeSegment[] realSegments = new NeImageLoader.NeSegment[segmentCount - ResourceTableEntries]; Array.Copy(segments, 0, realSegments, 0, realSegments.Length); segments = realSegments; var os2Resources = new SortedDictionary <ushort, ProgramResourceGroup>(); for (int i = 0; i < entries.Length; i++) { os2Resources.TryGetValue(entries[i].etype, out ProgramResourceGroup resGrp); var rt = Os2ResourceType.FromInt(entries[i].etype); if (resGrp == null) { resGrp = new ProgramResourceGroup { Name = rt.Name } } ; uint length = resourceSegments[i].DataLength; var dataOffset = (uint)(resourceSegments[i].DataOffset << alignmentShift); if (length == 0) { length = 65536; } if (dataOffset == 0) { dataOffset = 65536; } if ((resourceSegments[i].Flags & (ushort)0x4000) != 0) { length <<= alignmentShift; } var rdrRsrc = new LeImageReader(RawImage, dataOffset); var rsrc = rdrRsrc.ReadBytes(length); var rsrcInstance = new ProgramResourceInstance { Name = $"{entries[i].ename}", Type = "Os2_" + resGrp.Name, Bytes = rsrc, FileExtension = rt.FileExtension }; resGrp.Resources.Add(rsrcInstance); os2Resources.Remove(entries[i].etype); os2Resources[entries[i].etype] = resGrp; } foreach (var kvp in os2Resources) { resources.Add(kvp.Value); } return(resources); } string ReadByteLengthString(EndianImageReader rdr, int offset) { var clone = rdr.Clone(); clone.Offset = clone.Offset + offset; var len = clone.ReadByte(); var abStr = clone.ReadBytes(len); return(Encoding.ASCII.GetString(abStr)); }