Skip to content

Do not merge yet - My proof of concept for AOT compatible DiscUtils#54

Draft
devedse wants to merge 20 commits into
LTRData:LTRData.DiscUtils-initialfrom
devedse:LTRData.DiscUtils-initial
Draft

Do not merge yet - My proof of concept for AOT compatible DiscUtils#54
devedse wants to merge 20 commits into
LTRData:LTRData.DiscUtils-initialfrom
devedse:LTRData.DiscUtils-initial

Conversation

@devedse

@devedse devedse commented Dec 18, 2025

Copy link
Copy Markdown

Draft PR with some proof of concepts regarding AOT compatible disc utils

@devedse devedse marked this pull request as draft December 18, 2025 01:23

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be wrong in several ways. It needs to implement reading from other locations of the hive file outside of current bin object, so _buffer cannot be used to get all data. There are also a few errors in offset calculations, and I am also not sure whether the total length calculation is really reliable. I will try to find out how this can be resolved in some way.

devedse added 9 commits April 15, 2026 11:42
- Updated version to 0.17 in version.json
- Added new SourceGenerator project with FactoryGenerator
- Improved .gitignore to exclude additional build outputs
- Modified Directory.Build.props for versioning and compiler settings
- Registered new LogicalVolumeFactory and VirtualDiskTransport instances
- Enhanced logging in various classes for better traceability
- Created generate-packages.ps1 script for automated package generation
Modernize and refactor plugin/registration system for disk image and file system types:
- Bump version to 1.0.85
- Add AoT-friendly registration path for DiskImageBuilder
- Simplify and streamline FileSystemManager and VirtualDiskManager initialization
- Remove console logging and exception handling from factory discovery
- Make LogicalVolumeFactory internal
- Make VolumeManager registration internal and direct
- Add SetupCompleteAot for AoT environments
- General cleanup for improved startup and reliability
@devedse devedse force-pushed the LTRData.DiscUtils-initial branch from 277a7b4 to 5e3e244 Compare April 15, 2026 09:58
devedse and others added 11 commits April 15, 2026 11:59
…p to 1.0.104

During idle periods an iSCSI target can close the session due to the
DefaultTime2Retain/DefaultTime2Wait timeout expiring while no traffic
is flowing. This causes the next I/O to fail with a broken connection
rather than a clean retry.

Changes in Connection.cs:
- SemaphoreSlim (_streamSemaphore) serialises all PDU traffic so the
  keepalive timer and the main Send/SendAsync/Logout paths never
  interleave on the NetworkStream.
- Timer (_keepAliveTimer) fires every 10 s after login; skips ticks
  when a real command is in-flight.
- SendNopOut: ITT=0xFFFFFFFF / TTT=0xFFFFFFFF so no NOP-In response
  is expected (RFC 3720 §10.18).
- HandleNopIn: responds to target-initiated NOP-In (TTT!=0xFFFFFFFF)
  without advancing ExpectedStatusSequenceNumber (RFC 3720 §10.19).
- ReadPdu/ReadPduAsync: loop over consecutive NOP-In PDUs (max 16)
  before returning the next real response PDU.

Version bump: 1.0.103 -> 1.0.104
Resolved conflicts:
- Directory.Build.props: keep fork version 1.0.104 (fork maintains its own NuGet
  version sequence, above upstream's 1.0.83).
- Library/DiscUtils.Iscsi/Connection.cs: take upstream. Both sides implemented the
  same NOP-Out keepalive; upstream's is async (SendNopOutAsync) and its Send/SendAsync
  brace structure is self-consistent (the fork side would double-nest the for loop
  after auto-merge). Functionally equivalent keepalive; no fork logic lost.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…xed ri/li lists

SubKeyIndirectListCell backs both "ri" index-root lists (entries are subordinate
lists) and "li" leaf-index lists (entries are key nodes). The read paths
(Count, EnumerateKeyNames, EnumerateKeys, DoFindKey, KeyFinder) already tolerate a
single list whose entries are a mix of sublists and key nodes, by dispatching on the
actual cell type. But LinkSubKey/UnlinkSubKey still branched on ListType and hard-cast
every entry (GetCell<ListCell> for "ri", GetCell<KeyNodeCell> for "li").

On a real Windows SYSTEM hive whose "ri" list contains a direct key-node entry,
deleting a subkey (UnlinkSubKey) threw:
  System.InvalidCastException: Unable to cast object of type
  'DiscUtils.Registry.KeyNodeCell' to type 'DiscUtils.Registry.ListCell'.

Reading/enumerating the same key worked (those paths were already hardened); only
add/delete crashed.

Fix: LinkSubKey/UnlinkSubKey now dispatch on the actual cell type per entry
(GetCell<Cell> + "is ListCell"), exactly as the read paths do. Behaviour for
homogeneous "ri"/"li" lists is unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Includes the cherry-picked SubKeyIndirectListCell fix (InvalidCastException on
deleting/adding keys in mixed ri/li subkey lists). Triggers a fork build so
DevePXEBoot can consume the registry delete fix before it lands upstream (PR LTRData#69).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…stream)

Registry hive cells are 8-byte aligned. The check must reject sizes whose low 3
bits are set: (size & 0x7) != 0. Upstream LTRData.DiscUtils-initial had regressed
this to (size % 0x7) != 0 (mod 7), which rejects ~6 of every 7 valid sizes -
including the ~80-byte root key cell - so RegistryHive.Create() itself throws
"Invalid cell size" and every registry/BootConfig test fails (and the build hangs).
The fork's pre-merge code used (size % 8); this merge pulled in the regression.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ies (regressed in a551635)

GetFileLength must honor the NtfsOptions.FileLengthFromDirectoryEntries option: when
set (the default), a default-data-stream length request returns the directory entry's
cached RealSize. Commit a551635 ("Bugfixes for
FileExist and GetFileLength") removed that shortcut, so GetFileLength always looked up
the data attribute and the option became a no-op - breaking NtfsFileSystemTest.GetFileLength
(and the async variant), which expects a hardlink's stale directory-entry size (14325)
by default and the live data-attribute size (50) only when the option is disabled.
Restores the shortcut. The FileExists fix in that commit is correct and left intact.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
FindNextPresentSector/FindNextAbsentSector advance with
pos += (8 - sectorInBlock & 0x7) * Sizes.Sector. C# precedence makes this
(8 - sectorInBlock) & 0x7, not 8 - (sectorInBlock & 0x7): when sectorInBlock is
byte-aligned and the block-bitmap byte is empty, the original (8 - sectorInBlock % 8)
advanced by 8 sectors, but the rewrite yields 8 & 7 = 0, so pos never advances and the
extent enumeration (LayerExtents/Extents and the dynamic VHD/VMDK builders) loops
forever. Commit f7bf755 ("Minor code cleanups and optimizations") introduced this by
rewriting % 8 to & 0x7 without parentheses. Parenthesized so the mask applies to
sectorInBlock (the 7 - x & 0x7 mask forms are coincidentally equivalent but were
parenthesized too for clarity).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…b5b75d)

The synchronized wrapper kept its own Position auto-property and set
content.Position = Position before each operation but never wrote the advanced position
back afterward, so Position stayed frozen and reads/writes through the wrapper
re-processed the same offset (e.g. ExFat ReadLongSparseLimited read the wrong data).
Delegate Position to content.Position under the lock - correct for this single-shared-
cursor synchronized wrapper and fixes every read/write path (sync and async) at once.
Introduced by 4b5b75d ("Synchronized wrappers for disks and streams").

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants