This commit is contained in:
Mario Fetka
2026-05-23 15:09:50 +02:00
parent ed5da6c063
commit 99c3eed1bf
3 changed files with 177 additions and 1 deletions

131
nwtests.c
View File

@@ -21,7 +21,7 @@ static int tests_same_arg(char *a, char *b)
static void tests_usage(void)
{
fprintf(stdout, "Usage: TESTS [OLD|NETCALL|E300|NCPF2 [file] [REPLY]]\n");
fprintf(stdout, "Usage: TESTS [OLD|NETCALL|E300|NCPF2 [file]|NWREQ87 [file]]\n");
}
static int tests_netcall(void)
@@ -300,6 +300,132 @@ static int tests_ncpf2(int argc, char *argv[])
}
static void tests_build_nwreq87_path(uint8 *buf, uint8 dhandle,
char *name, UI *out_len)
{
uint8 *p;
int nlen;
memset(buf, 0, 300);
p = buf;
nlen = strlen(name);
if (nlen > 255) nlen = 255;
/*
* Same compact handle/path payload we used before:
* handle, dirbase, dirstyle, component-count, len, name
* The new part in this test is not the path itself; it is that we now
* reproduce NWCREQUEST's fragmented request and full reply size.
*/
*p++ = dhandle;
tests_put_dword_lh(p, 0L); p += 4;
*p++ = 0; /* dirstyle = short directory handle */
*p++ = 1; /* one path component */
*p++ = (uint8)nlen;
memcpy(p, name, nlen);
p += nlen;
*out_len = (UI)(p - buf);
}
static UI tests_build_nwreq87s6_flat(uint8 *req,
uint8 *path,
UI path_len)
{
uint8 *p;
memset(req, 0, 400);
p = req;
/*
* DeveloperNet ncpdos16 87s6.c builds two request fragments:
* frag 1 length 9:
* subfn=6, srcNS, dstNS, searchAttrs, returnInfoMask
* frag 2:
* packed handle/path structure
*
* NWCREQUEST for NETX/Shell concatenates those request fragments before
* calling NWCSHELLREQ.
*/
*p++ = 6; /* NCP87 subfunction 6 */
*p++ = 0; /* source namespace DOS */
*p++ = 0; /* target namespace DOS */
tests_put_word_lh(p, 0x0006); p += 2; /* SA_ALL */
tests_put_dword_lh(p, 0x00000004UL); p += 4;/* RIM_ATTRIBUTES */
memcpy(p, path, path_len);
p += path_len;
return (UI)(p - req);
}
static int tests_nwreq87(int argc, char *argv[])
{
char *name = "LOGIN.EXE";
uint8 connid = 0;
uint8 dhandle = 0;
uint8 path[300];
uint8 req[400];
uint8 repl[0x180];
uint8 dummy[8];
UI path_len;
UI req_len;
int rc;
uint32 a0;
uint32 a4;
uint32 a4d;
if (argc > 2)
name = argv[2];
if (tests_current_conn_dhandle(&connid, &dhandle))
return(1);
tests_build_nwreq87_path(path, dhandle, name, &path_len);
req_len = tests_build_nwreq87s6_flat(req, path, path_len);
memset(repl, 0, sizeof(repl));
memset(dummy, 0, sizeof(dummy));
fprintf(stdout, "TEST NWREQ87 shell-style NCP87/S6 for %s\n", name);
fprintf(stdout, "connid=%u dhandle=%u path.len=%u req.len=%u repl.len=%u\n",
connid, dhandle, path_len, req_len, (UI)0x014d);
tests_dump_bytes("NWREQ87 path:", path, path_len > 48 ? 48 : path_len);
tests_dump_bytes("NWREQ87 req :", req, req_len > 64 ? 64 : req_len);
/*
* Reproduce the NETX/Shell path in clndos16 dreq.c:
* first AH=F0/DX=conn via NWCSHELLREQ
* then AH=F2/AL=function with DS:SI=request, CX=requestLen,
* ES:DI=reply, DX=sum(replyFragLengths).
*
* For 87s6.c reply fragments are 0x4d + 0x100 = 0x014d.
*/
fprintf(stdout, "NWREQ87 init F000 DX=conn\n");
rc = Net_Call_F2X_C(0xF000, 0, 0, (UI)connid, dummy, repl);
fprintf(stdout, "NWREQ87 init rc=%04X\n", rc);
Net_Call_C_Dump();
fprintf(stdout, "NWREQ87 call F257 CX=req.len DX=014D\n");
rc = Net_Call_F2X_C(0xF257, 0, req_len, 0x014d, req, repl);
fprintf(stdout, "NWREQ87 rc=%04X\n", rc);
Net_Call_C_Dump();
tests_dump_bytes("NWREQ87 repl[0..63]:", repl, 64);
tests_dump_bytes("NWREQ87 repl[4d..8c]:", repl + 0x4d, 64);
a0 = tests_get_dword_lh(repl);
a4 = tests_get_dword_lh(repl + 4);
a4d = tests_get_dword_lh(repl + 0x4d);
fprintf(stdout, "NWREQ87 dword[0]=%08lX dword[4]=%08lX dword[4d]=%08lX\n",
a0, a4, a4d);
return(0);
}
int func_tests(int argc, char *argv[], int mode)
{
if (argc >= 2) {
@@ -309,6 +435,9 @@ int func_tests(int argc, char *argv[], int mode)
if (tests_same_arg(argv[1], "E300") || tests_same_arg(argv[1], "NETCALLE300"))
return tests_netcall_e300();
if (tests_same_arg(argv[1], "NWREQ87"))
return tests_nwreq87(argc, argv);
if (tests_same_arg(argv[1], "NCPF2"))
return tests_ncpf2(argc, argv);