tests
This commit is contained in:
68
kern.c
68
kern.c
@@ -123,6 +123,74 @@ int KERN_C_CALL Net_Call_CX(unsigned int ax, unsigned int bx,
|
||||
return Net_Call_C_Last.rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Experimental Client32/VLM-style AH=F2 raw request wrapper.
|
||||
*
|
||||
* This mirrors the official Novell FLAG.EXE wrapper shape seen in disassembly:
|
||||
* DX = connection / connection reference
|
||||
* ES:DI = reply buffer
|
||||
* CX = caller supplied size/count
|
||||
* DS:SI = request buffer
|
||||
* AH = F2h
|
||||
* AL = NCP function, e.g. 57h for NCP 87
|
||||
* int 21h
|
||||
*
|
||||
* Return convention mirrors Novell wrapper and old kern.asm Net_Call:
|
||||
* if AL != 0, AH is set to 89h in Net_Call_F2_C_Last.out_ax
|
||||
* return AL only
|
||||
*/
|
||||
int KERN_C_CALL Net_Call_F2_C(UI conn, UI function, UI cx, void *req, void *repl)
|
||||
{
|
||||
union REGS inregs;
|
||||
union REGS outregs;
|
||||
struct SREGS segregs;
|
||||
UI ret_ax;
|
||||
|
||||
memset(&inregs, 0, sizeof(inregs));
|
||||
memset(&outregs, 0, sizeof(outregs));
|
||||
memset(&segregs, 0, sizeof(segregs));
|
||||
memset(&Net_Call_C_Last, 0, sizeof(Net_Call_C_Last));
|
||||
|
||||
inregs.h.ah = 0xF2;
|
||||
inregs.h.al = (uint8)(function & 0xff);
|
||||
inregs.x.dx = conn;
|
||||
inregs.x.cx = cx;
|
||||
inregs.x.si = FP_OFF(req);
|
||||
inregs.x.di = FP_OFF(repl);
|
||||
segregs.ds = FP_SEG(req);
|
||||
segregs.es = FP_SEG(repl);
|
||||
|
||||
Net_Call_C_Last.in_ax = inregs.x.ax;
|
||||
Net_Call_C_Last.in_bx = inregs.x.bx;
|
||||
Net_Call_C_Last.in_cx = inregs.x.cx;
|
||||
Net_Call_C_Last.in_dx = inregs.x.dx;
|
||||
Net_Call_C_Last.in_si = inregs.x.si;
|
||||
Net_Call_C_Last.in_di = inregs.x.di;
|
||||
Net_Call_C_Last.in_ds = segregs.ds;
|
||||
Net_Call_C_Last.in_es = segregs.es;
|
||||
Net_Call_C_Last.req_ptr = req;
|
||||
Net_Call_C_Last.repl_ptr = repl;
|
||||
|
||||
int86x(0x21, &inregs, &outregs, &segregs);
|
||||
|
||||
ret_ax = outregs.x.ax;
|
||||
ret_ax &= 0x00ff;
|
||||
if (ret_ax)
|
||||
ret_ax |= 0x8900;
|
||||
|
||||
Net_Call_C_Last.out_ax = ret_ax;
|
||||
Net_Call_C_Last.out_bx = outregs.x.bx;
|
||||
Net_Call_C_Last.out_cx = outregs.x.cx;
|
||||
Net_Call_C_Last.out_dx = outregs.x.dx;
|
||||
Net_Call_C_Last.out_si = outregs.x.si;
|
||||
Net_Call_C_Last.out_di = outregs.x.di;
|
||||
Net_Call_C_Last.out_flags = outregs.x.cflag;
|
||||
Net_Call_C_Last.rc = ret_ax & 0x00ff;
|
||||
|
||||
return Net_Call_C_Last.rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Text dump for quick testing. Later we can expose this through DEBUG.EXE
|
||||
* as "debug netcall" or similar.
|
||||
|
||||
7
kern.h
7
kern.h
@@ -14,6 +14,13 @@ extern void esr_routine(ECB *ecb);
|
||||
extern void KERN_CALL xmemmove(void *ziel, void *quelle, UI anz);
|
||||
extern int KERN_CALL Net_Call(UI func, void *req, void *repl);
|
||||
extern int KERN_CALL Net_Call_C(UI func, void *req, void *repl);
|
||||
extern int KERN_CALL Net_Call_CX(UI func, UI bx, UI cx, UI dx,
|
||||
void *req, void *repl);
|
||||
extern int KERN_CALL Net_Call_F2_C(UI conn, UI function, UI cx,
|
||||
void *req, void *repl);
|
||||
extern void KERN_CALL Net_Call_C_Dump(void);
|
||||
extern UI KERN_CALL Net_Call_C_GetDebug(UI idx);
|
||||
extern int KERN_CALL Net_Call_C(UI func, void *req, void *repl);
|
||||
extern int KERN_CALL Net_Call_CX(UI func, UI bx, UI cx, UI dx,
|
||||
void *req, void *repl);
|
||||
extern void KERN_CALL Net_Call_C_Dump(void);
|
||||
|
||||
99
nwtests.c
99
nwtests.c
@@ -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|NCP87 [file]|NCP87F2 [file]]\n");
|
||||
fprintf(stdout, "Usage: TESTS [OLD|NETCALL|E300|NCPF2 [file] [REPLY]]\n");
|
||||
}
|
||||
|
||||
static int tests_netcall(void)
|
||||
@@ -188,24 +188,23 @@ static int tests_get_current_drive(void)
|
||||
return((int)regs.h.al);
|
||||
}
|
||||
|
||||
static int tests_current_dhandle(uint8 *dhandle)
|
||||
static int tests_current_conn_dhandle(uint8 *connid, uint8 *dhandle)
|
||||
{
|
||||
uint8 connid = 0;
|
||||
uint8 flags = 0;
|
||||
int drive;
|
||||
|
||||
drive = tests_get_current_drive();
|
||||
|
||||
if (get_drive_info((uint8)drive, &connid, dhandle, &flags)) {
|
||||
fprintf(stdout, "NCP87DBG get_drive_info failed drive=%c:\n", 'A' + drive);
|
||||
if (get_drive_info((uint8)drive, connid, dhandle, &flags)) {
|
||||
fprintf(stdout, "NCPF2DBG get_drive_info failed drive=%c:\n", 'A' + drive);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
fprintf(stdout, "NCP87DBG drive=%c: connid=%u dhandle=%u flags=%02X\n",
|
||||
'A' + drive, connid, *dhandle, flags);
|
||||
fprintf(stdout, "NCPF2DBG drive=%c: connid=%u dhandle=%u flags=%02X\n",
|
||||
'A' + drive, *connid, *dhandle, flags);
|
||||
|
||||
if (!connid || (flags & 0x80)) {
|
||||
fprintf(stdout, "NCP87DBG current drive is not a network drive\n");
|
||||
if (!*connid || (flags & 0x80)) {
|
||||
fprintf(stdout, "NCPF2DBG current drive is not a network drive\n");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
@@ -219,16 +218,9 @@ static int tests_add_handle_path(uint8 *p, uint8 dhandle, char *name)
|
||||
nlen = strlen(name);
|
||||
if (nlen > 255) nlen = 255;
|
||||
|
||||
/*
|
||||
* ncpfs ncp_add_handle_path2() form for dirstyle 0:
|
||||
* vol/handle byte
|
||||
* dirbase dword
|
||||
* dirstyle byte
|
||||
* NW path: component-count, len, bytes
|
||||
*/
|
||||
*p++ = dhandle;
|
||||
tests_put_dword_lh(p, 0L); p += 4;
|
||||
*p++ = 0; /* NCP_DIRSTYLE_HANDLE */
|
||||
*p++ = 0; /* dirstyle = short dir handle */
|
||||
*p++ = 1; /* one component */
|
||||
*p++ = (uint8)nlen;
|
||||
memcpy(p, name, nlen);
|
||||
@@ -237,85 +229,74 @@ static int tests_add_handle_path(uint8 *p, uint8 dhandle, char *name)
|
||||
return(1 + 4 + 1 + 1 + 1 + nlen);
|
||||
}
|
||||
|
||||
static int tests_ncp87_read_one(char *name, unsigned int ax)
|
||||
static int tests_ncpf2_read_one(char *name, UI cx_mode)
|
||||
{
|
||||
struct {
|
||||
uint16 len;
|
||||
uint8 data[320];
|
||||
} req;
|
||||
struct {
|
||||
uint16 len;
|
||||
uint8 data[256];
|
||||
} repl;
|
||||
|
||||
uint8 *p;
|
||||
uint8 connid = 0;
|
||||
uint8 dhandle = 0;
|
||||
UI cx;
|
||||
int hlen;
|
||||
int rc;
|
||||
uint32 attr;
|
||||
|
||||
if (tests_current_dhandle(&dhandle))
|
||||
if (tests_current_conn_dhandle(&connid, &dhandle))
|
||||
return(1);
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
memset(&repl, 0, sizeof(repl));
|
||||
|
||||
p = req.data;
|
||||
*p++ = 6; /* NCP87 subfunction 6: obtain file/subdir info */
|
||||
*p++ = 0; /* source namespace DOS */
|
||||
*p++ = 0; /* target namespace DOS */
|
||||
tests_put_word_lh(p, 0x0006); p += 2; /* SA_ALL: hidden+system */
|
||||
tests_put_dword_lh(p, 0x00000004UL); p += 4;/* RIM_ATTRIBUTES */
|
||||
*p++ = 6; /* NCP87 subfunction 6: obtain file/subdir info */
|
||||
*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 */
|
||||
hlen = tests_add_handle_path(p, dhandle, name);
|
||||
p += hlen;
|
||||
|
||||
req.len = (uint16)(p - req.data);
|
||||
repl.len = sizeof(repl.data);
|
||||
if (cx_mode == 0)
|
||||
cx = (UI)(p - req.data); /* most likely: request length */
|
||||
else
|
||||
cx = sizeof(repl.data); /* alternate: reply buffer size */
|
||||
|
||||
fprintf(stdout, "NCP87DBG TRY AX=%04X name=%s req.len=%u repl.len=%u\n",
|
||||
ax, name, req.len, repl.len);
|
||||
tests_dump_bytes("NCP87DBG req:", req.data, req.len > 48 ? 48 : req.len);
|
||||
fprintf(stdout, "NCPF2DBG name=%s func=57 conn=%u cx=%u mode=%u req.len=%u repl.max=%u\n",
|
||||
name, connid, cx, cx_mode, (UI)(p - req.data), (UI)sizeof(repl.data));
|
||||
tests_dump_bytes("NCPF2DBG req:", req.data, (p - req.data) > 64 ? 64 : (int)(p - req.data));
|
||||
|
||||
rc = Net_Call_C(ax, &req, &repl);
|
||||
rc = Net_Call_F2_C((UI)connid, 0x57, cx, req.data, repl.data);
|
||||
|
||||
fprintf(stdout, "NCP87DBG rc=%04X repl.len=%u\n", rc, repl.len);
|
||||
tests_dump_bytes("NCP87DBG repl:", repl.data, repl.len > 64 ? 64 : repl.len);
|
||||
fprintf(stdout, "NCPF2DBG rc=%04X\n", rc);
|
||||
tests_dump_bytes("NCPF2DBG repl:", repl.data, 64);
|
||||
Net_Call_C_Dump();
|
||||
|
||||
attr = tests_get_dword_lh(repl.data);
|
||||
fprintf(stdout, "NCP87DBG attr[0]=%08lX\n", attr);
|
||||
fprintf(stdout, "NCPF2DBG attr[0]=%08lX\n", attr);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int tests_ncp87(int argc, char *argv[])
|
||||
static int tests_ncpf2(int argc, char *argv[])
|
||||
{
|
||||
char *name = "LOGIN.EXE";
|
||||
UI mode = 0;
|
||||
|
||||
if (argc > 2)
|
||||
name = argv[2];
|
||||
if (argc > 3 && tests_same_arg(argv[3], "REPLY"))
|
||||
mode = 1;
|
||||
|
||||
fprintf(stdout, "TEST NCP87 obtain RIM_ATTRIBUTES for %s\n", name);
|
||||
fprintf(stdout, "This is read-only. It does not modify the file.\n\n");
|
||||
fprintf(stdout, "TEST NCPF2 AH=F2/AL=57 NCP87 obtain RIM_ATTRIBUTES\n");
|
||||
fprintf(stdout, "Default CX is request length. Add REPLY to use reply size.\n");
|
||||
fprintf(stdout, "This is read-only, but still experimental.\n\n");
|
||||
|
||||
/*
|
||||
* Try only the old-shell-style AX first. 0xF257 previously hung when used
|
||||
* inside FLAG, so do not try it here automatically.
|
||||
*/
|
||||
return tests_ncp87_read_one(name, 0xE200);
|
||||
}
|
||||
|
||||
static int tests_ncp87f2(int argc, char *argv[])
|
||||
{
|
||||
char *name = "LOGIN.EXE";
|
||||
|
||||
if (argc > 2)
|
||||
name = argv[2];
|
||||
|
||||
fprintf(stdout, "TEST NCP87 F257 obtain RIM_ATTRIBUTES for %s\n", name);
|
||||
fprintf(stdout, "WARNING: this variant may hang on some clients.\n\n");
|
||||
|
||||
return tests_ncp87_read_one(name, 0xF257);
|
||||
return tests_ncpf2_read_one(name, mode);
|
||||
}
|
||||
|
||||
|
||||
@@ -330,12 +311,6 @@ 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], "NCP87"))
|
||||
return tests_ncp87(argc, argv);
|
||||
|
||||
if (tests_same_arg(argv[1], "NCP87F2"))
|
||||
return tests_ncp87f2(argc, argv);
|
||||
|
||||
if (tests_same_arg(argv[1], "OLD"))
|
||||
return tests_old(argc - 1, argv + 1, mode);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user