Files
tdkpin/original/reconstructed/tests/test_multimedia_paths.c
T
ddidderr 8b99e9607c feat(reconstruction): complete binary-backed C recovery
Replace the partial mechanics transcriptions with a separate, readable C11
reconstruction of the complete Win16 image while preserving the original raw
Ghidra export as immutable evidence. Cover all ordinary and overlapping entry
points, Borland runtime behavior, Win16 imports, segmented data, callbacks,
resources, indirect control flow, physics, rendering, persistence, and
startup/shutdown lifecycles.

Add deterministic extraction and audit tooling plus address-linked ledgers for
functions, imports, DGROUP ranges and objects, relocations, resources, and
callbacks. The final gate records zero raw, partial, restored, unknown,
blocked, or unclassified required units. Keep the semantic-fidelity boundary
explicit: the portable C is not claimed to reproduce a byte-identical Borland
NE build.

Add strict focused harnesses for every reconstructed C unit, exact resource
round-trip checks, and a 16-bit Borland Real48 reference probe. No Rust source
or Cargo metadata is changed in this phase.

Test Plan:
- `bash original/tools/test_reconstructed_c.sh` -- passed
- `bash original/tools/probe_real48_reference.sh` -- passed bit-for-bit
- `python3 original/tools/audit_reconstruction.py --require-complete` -- passed
- `git diff --cached --check` -- passed
- `git diff HEAD -- '*.rs' Cargo.toml Cargo.lock` -- empty
2026-08-23 16:41:17 +02:00

179 lines
6.0 KiB
C

#include "../tdkpin_multimedia.h"
#include <assert.h>
#include <stdint.h>
#include <string.h>
static Win16DosFileAttributesResult g_attribute_results[16];
static unsigned g_attribute_result_count;
static unsigned g_attribute_result_index;
static char g_attribute_names[16][80];
static unsigned g_oem_calls;
static Win16FarPtr g_environment;
static void write_far_string(Win16FarPtr destination, const char *source)
{
size_t length = strlen(source);
for (size_t index = 0; index <= length; index++) {
win16_write_u8(
win16_far_add_offset(destination, (uint16_t)index),
(uint8_t)source[index]);
}
}
static void read_far_string(
Win16FarPtr source, char *destination, size_t capacity)
{
size_t index = 0;
while (index + 1 < capacity) {
uint8_t byte = win16_read_u8(
win16_far_add_offset(source, (uint16_t)index));
destination[index++] = (char)byte;
if (byte == 0) {
return;
}
}
destination[capacity - 1] = 0;
}
INT16 AnsiToOem16(Win16FarPtr source, Win16FarPtr destination)
{
assert(source == destination);
g_oem_calls++;
return 1;
}
Win16DosFileAttributesResult win16_dos_get_file_attributes(
Win16FarPtr oem_name)
{
assert(g_attribute_result_index < g_attribute_result_count);
read_far_string(
oem_name,
g_attribute_names[g_attribute_result_index],
sizeof(g_attribute_names[g_attribute_result_index]));
return g_attribute_results[g_attribute_result_index++];
}
Win16FarPtr GetDOSEnvironment16(void)
{
return g_environment;
}
static void reset_attributes(void)
{
g_attribute_result_count = 0;
g_attribute_result_index = 0;
g_oem_calls = 0;
}
static void assert_far_string(Win16FarPtr string, const char *expected)
{
char actual[256];
read_far_string(string, actual, sizeof(actual));
assert(strcmp(actual, expected) == 0);
}
int main(void)
{
static uint8_t data[0x1000];
uint8_t stack_anchor = 0;
uintptr_t stack_base = (uintptr_t)&stack_anchor - 0x8000;
win16_reset_segment_bindings();
win16_bind_segment(0x7000, data, sizeof(data), true);
win16_bind_segment(0x7200, (void *)stack_base, 0x10000, true);
Win16FarPtr name = win16_make_far_pointer(0x7000, 0x0100);
Win16FarPtr search = win16_make_far_pointer(0x7000, 0x0200);
Win16FarPtr result = win16_make_far_pointer(0x7000, 0x0300);
char long_name[96];
memset(long_name, 'A', sizeof(long_name) - 1);
long_name[sizeof(long_name) - 1] = 0;
write_far_string(name, long_name);
reset_attributes();
g_attribute_result_count = 1;
g_attribute_results[0] =
(Win16DosFileAttributesResult){0x20, false};
Win16DosFileAttributesResult attributes =
borland_dos_get_file_attributes_ansi(name);
assert(!attributes.carry && attributes.attributes == 0x20);
assert(strlen(g_attribute_names[0]) == 79 && g_oem_calls == 1);
write_far_string(name, "FILE.DLL");
write_far_string(search, "C:\\ONE;D:;E:\\TWO");
reset_attributes();
g_attribute_result_count = 4;
g_attribute_results[0] =
(Win16DosFileAttributesResult){0, true};
g_attribute_results[1] =
(Win16DosFileAttributesResult){0x10, false}; /* directory */
g_attribute_results[2] =
(Win16DosFileAttributesResult){0, true};
g_attribute_results[3] =
(Win16DosFileAttributesResult){0x20, false};
assert(multimedia_search_file(search, name, result) == result);
assert(strcmp(g_attribute_names[0], "FILE.DLL") == 0);
assert(strcmp(g_attribute_names[1], "C:\\ONE\\FILE.DLL") == 0);
assert(strcmp(g_attribute_names[2], "D:FILE.DLL") == 0);
assert(strcmp(g_attribute_names[3], "E:\\TWO\\FILE.DLL") == 0);
assert_far_string(result, "E:\\TWO\\FILE.DLL");
write_far_string(search, "");
reset_attributes();
g_attribute_result_count = 1;
g_attribute_results[0] =
(Win16DosFileAttributesResult){0, true};
(void)multimedia_search_file(search, name, result);
assert_far_string(result, "");
write_far_string(search, ";X");
reset_attributes();
g_attribute_result_count = 2;
g_attribute_results[0] =
(Win16DosFileAttributesResult){0, true};
g_attribute_results[1] =
(Win16DosFileAttributesResult){0, false};
(void)multimedia_search_file(search, name, result);
assert(strcmp(g_attribute_names[1], "\\FILE.DLL") == 0);
Win16FarPtr input = win16_make_far_pointer(0x7000, 0x0400);
Win16FarPtr directory = win16_make_far_pointer(0x7000, 0x0500);
Win16FarPtr file = win16_make_far_pointer(0x7000, 0x0600);
Win16FarPtr extension = win16_make_far_pointer(0x7000, 0x0700);
write_far_string(input, "C:\\LONGDIR\\NAME.EXTMORE");
assert(multimedia_split_path(extension, file, directory, input) == 7);
assert_far_string(directory, "C:\\LONGDIR\\");
assert_far_string(file, "NAME");
assert_far_string(extension, ".EXT");
write_far_string(input, "DIR\\A?.*");
assert(multimedia_split_path(extension, file, directory, input) == 15);
assert_far_string(directory, "DIR\\");
assert_far_string(file, "A?");
assert_far_string(extension, ".*");
write_far_string(input, "GAME");
assert(multimedia_split_path(extension, file, directory, input) == 2);
assert_far_string(directory, "");
assert_far_string(file, "GAME");
assert_far_string(extension, "");
g_environment = win16_make_far_pointer(0x7000, 0x0800);
const char environment[] =
"FOO=one\0Path=two;three\0EMPTY=\0\0";
for (size_t index = 0; index < sizeof(environment); index++) {
win16_write_u8(
win16_far_add_offset(g_environment, (uint16_t)index),
(uint8_t)environment[index]);
}
write_far_string(name, "PATH");
Win16FarPtr value = multimedia_environment_value(name);
assert_far_string(value, "two;three");
write_far_string(name, "empty");
value = multimedia_environment_value(name);
assert(value != 0 && win16_read_u8(value) == 0);
write_far_string(name, "missing");
assert(multimedia_environment_value(name) == 0);
return 0;
}