- GetIfEntry, GetIfTable and GetNumberOfInterfaces answer from the host's interfaces. GetIfEntry names one by the index the record handed in carries, GetIfTable puts the rows behind a count, and a table that does not fit is refused with ERROR_INSUFFICIENT_BUFFER and the size it needs.
- The interface walk moved out of host_api.cpp into interfaces.cpp, so the records GetAdaptersAddresses reports and the rows these calls report come from one enumeration of the host rather than two.
- interfaces_test checks the record against the MIB_IFROW offsets Windows declares and the cutting of a long name. The new guest fixture interface_client.c reads the tables through the runtime, in 64-bit and 32-bit builds: it checks that the count, the rows and GetIfEntry agree, that a sorted table lists the rows by index, and that an unknown index and a short table fail as Windows fails them.
Assisted-by: Claude Code:deepseek-v4.1-flash-1017
AI-Scope: Read the MIB_IFROW and MIB_IFTABLE layouts, moved the interface enumeration into interfaces.cpp, wrote the three handlers and both tests, and checked them with ctest (native_interface_table_contract, native_interface_table_client, native_interface_table_client_x32).
A drive was \Device\HarddiskVolumeN with N counted over the drives present
for QueryDosDevice but from the letter (C first) for the process image and
mapped file names, so Z: had two device names, and NtQueryObject answered
an empty name for every file. NativePaths now gives each drive one volume
device (C is 1 and the drives after it follow in letter order, A and B
last) and turns a Win32 path into the NT name the object manager uses: a
drive path on its volume device, a UNC path on \Device\Mup. QueryDosDevice,
the image and mapped file names and NtQueryObject (ObjectNameInformation of
a file) use it; the drive list QueryDosDevice and GetLogicalDrives share
moved there as well. Zig reads a file name this way to find its own path.
Assisted-by: Claude Code:claude-opus-5-5
AI-Scope: the volume device naming and its callers
(cherry picked from commit 02cce32c5ee2b0c341e44ae6fa691f28aa51b62f)
c-ares sorts the addresses it resolves by the route to each (RFC 6724) and
asks GetBestRoute2 for the best source address. The answer is the host's own
routing choice: a datagram socket connected to the destination, which sends
nothing, is bound to the source address, and the adapter holding that address
is the interface. The route row names the interface and the destination as a
host route; an unreachable destination is ERROR_NETWORK_UNREACHABLE.
Assisted-by: Claude Code:claude-opus-5-5
AI-Scope: the handler
(cherry picked from commit a13a99c0ffd2ade13fc88ff0f635f16270ea7919)
aria2, through c-ares, takes its DNS servers from each adapter's
FirstDnsServerAddress list, which Raven left empty, so name resolution
failed with "Could not contact DNS servers". Every adapter but the loopback
one now lists the nameservers of the host's resolver configuration, as
IP_ADAPTER_DNS_SERVER_ADDRESS records, unless GAA_FLAG_SKIP_DNS_SERVER asks
for none.
Assisted-by: Claude Code:claude-opus-5-5
AI-Scope: the DNS server records
(cherry picked from commit d312173201493c6be172c9aaa3cb124d8b7b7b1c)
duf lists disks with FindFirstVolumeW and FindNextVolumeW, then asks
GetVolumePathNamesForVolumeNameW, GetVolumeInformationW and
GetDiskFreeSpaceExW about each volume by its \\?\Volume{GUID}\ name.
Each drive of the prefix is a volume whose GUID is made from its letter, so
the name is the same every time. The volume functions list them, name the
volume mounted at a drive's root (GetVolumeNameForVolumeMountPointW) and the
root a volume is mounted at, and every path function accepts a volume name
in place of the drive.
Assisted-by: Claude Code:claude-opus-5-5
AI-Scope: the volume functions and the volume name in path resolution
(cherry picked from commit cc93d36368f72f5b43c213643a54abe9aa2564e0)
OpenTofu asks it for the volume of a file it has open. The answer is the
volume every drive reports through GetVolumeInformationW, which now shares
its fields with the ANSI form and this one.
Assisted-by: Claude Code:claude-opus-5-5
AI-Scope: the handler and the shared fields
(cherry picked from commit 99bd8a6c6def628d3aec20b765dd2183597f683f)
* feat: give console programs the terminal as their console
A standard handle that is a terminal, and CONIN$, CONOUT$ and CON, now act as a console: modes map to terminal settings,
reads and writes convert between UTF-16 and the terminal's UTF-8, terminal input becomes key events, and Ctrl+C runs the
control handlers. Files and pipes still fail the console functions, as on Windows.
Assisted-by: Claude Code:claude-opus-5-5
AI-Scope: Wrote the console functions over the terminal, their pty test and the guest test program from the public console API documentation.
* test: let the console client run by hand, saying which step failed
Assisted-by: Claude Code:claude-opus-5-5
AI-Scope: Made the exact size and cursor checks optional and gave each step an instruction and a failure number.
* feat: follow the console cursor through the output instead of asking the terminal
Programs that redraw their command line read and move the cursor on every key; asking the terminal each time was slow, and
wrong on terminals that never answer. The terminal is now asked only when the position may be stale.
Assisted-by: Claude Code:claude-opus-5-5
AI-Scope: Wrote the cursor tracker, WriteConsoleOutputCharacter, ScrollConsoleScreenBuffer, the resize events and their tests.