diff --git a/kern.h b/kern.h index 1f9fc2b..5e6b4df 100644 --- a/kern.h +++ b/kern.h @@ -19,6 +19,7 @@ extern int KERN_CALL C32_LoadNios_Probe(UI axfunc, void *outbuf); extern int KERN_CALL C32_GetFunc_Probe(char *name, void *outbuf); extern int KERN_CALL C32_CallVersion_Nios_Probe(void *outbuf); extern int KERN_CALL C32_MapLock_Probe(void *ptr, UI len, void *outbuf); +extern int KERN_CALL C32_MapVar_Probe(UI specLen, UI flag, void *outbuf); extern int KERN_CALL C32_MapFull2_Probe(void *outbuf); extern int KERN_CALL C32_MapFull_Probe(void *outbuf); extern int KERN_CALL C32_ScanRefsIter_Probe(UI iterLo, UI iterHi, void *outbuf); diff --git a/kern_wasm.asm b/kern_wasm.asm index 733ef7f..3956239 100644 --- a/kern_wasm.asm +++ b/kern_wasm.asm @@ -31,6 +31,7 @@ public _C32_ScanRefs2_Probe public _C32_ScanRefsIter_Probe public _C32_MapFull_Probe public _C32_MapFull2_Probe +public _C32_MapVar_Probe public _Net_Call_VLM_Raw public _Net_Call_NWCVLMREQ @@ -2583,4 +2584,292 @@ _C32_MapFull2_Probe endp +; int C32_MapVar_Probe(UI specLen, UI flag, void *outbuf) +; +; Exact-ish raw version of w95mconn.o::__C32MapConn16To32 second step. +; +; It emulates: +; C32MAPCONNONE 40 -> server name MARS +; NWCSCANCONNINFO(scanIterator/result ptr, +; scanInfoLevel=0A, scanConnInfo=NWCString/SPECTDATA "MARS", +; scanFlags=1, connInfoVersion=0, +; returnInfoLevel=0, returnConnInfo=NULL, +; connReference local) +; +; But calls Client32 CONNScanInfo directly through ECX/NIOS command 0A. +; +; outbuf: +; +00 load AX +; +02 resolver off +; +04 resolver seg +; +06 trampoline off +; +08 trampoline seg +; +0A function off +; +0C function seg +; +0E ret AX +; +10 ret DX +; +12 resultRef low ; corresponds to caller output ptr in w95mconn +; +14 resultRef high +; +16 connRefLocal low ; corresponds to d32conni local -1c +; +18 connRefLocal high +_C32_MapVar_Probe proc far + push bp + mov bp, sp + sub sp, 140 + + push ds + push es + push si + push di + + ; clear ESI/ECX + db 66h, 33h, 0F6h + db 66h, 33h, 0C9h + + mov ax, 0D8C1h + int 2Fh + + mov [bp-4], ax ; load AX + ; resolver ESI -> [bp-8] + db 66h, 89h, 76h, 0F8h + ; trampoline ECX -> [bp-12] + db 66h, 89h, 4Eh, 0F4h + + or ax, ax + jne c32mapvar_fail + + ; resolve "CONNScanInfo" + push cs + push offset c32mapvar_name + push 0 + push 0 + call dword ptr [bp-8] + add sp, 8 + mov [bp-16], ax + mov [bp-14], dx + or ax, dx + jne c32mapvar_have_func + jmp c32mapvar_fail + +c32mapvar_have_func: + ; resultRef/output dword at [bp-20], init 0 + mov word ptr [bp-20], 0 + mov word ptr [bp-18], 0 + + ; connReference local dword at [bp-24], init 0 + mov word ptr [bp-24], 0 + mov word ptr [bp-22], 0 + + ; string buffer at [bp-80], copy "MARS", zero padded enough + lea di, -80[bp] + push ss + pop es + mov byte ptr es:[di+0], 'M' + mov byte ptr es:[di+1], 'A' + mov byte ptr es:[di+2], 'R' + mov byte ptr es:[di+3], 'S' + mov byte ptr es:[di+4], 0 + + ; Map string buffer len 31h -> [bp-28] + push 0 + push 31H + push ss + lea ax, -80[bp] + push ax + push 0 + push 2 + call dword ptr [bp-8] + add sp, 0cH + mov [bp-28], ax + mov [bp-26], dx + + ; Build SPECTDATA/NWCString transfer block at [bp-48], len 10h. + ; Mirrors d32conni initialization for server-name scan. + mov ax, [bp+6] + mov word ptr [bp-48], ax + mov word ptr [bp-46], 0 + mov ax, [bp-28] + mov word ptr [bp-44], ax + mov ax, [bp-26] + mov word ptr [bp-42], ax + mov word ptr [bp-40], 1 + mov word ptr [bp-38], 0 + mov word ptr [bp-36], 0 + mov word ptr [bp-34], 0 + + ; Map scanInfo spectdata block len 10h -> [bp-32] + push 0 + push 10H + push ss + lea ax, -48[bp] + push ax + push 0 + push 2 + call dword ptr [bp-8] + add sp, 0cH + mov [bp-32], ax + mov [bp-30], dx + + ; Map resultRef/output len4 -> [bp-56] (this is w95mconn caller ptr) + push 0 + push 4 + push ss + lea ax, -20[bp] + push ax + push 0 + push 2 + call dword ptr [bp-8] + add sp, 0cH + mov [bp-56], ax + mov [bp-54], dx + + ; Map connReference local len4 -> [bp-60] + push 0 + push 4 + push ss + lea ax, -24[bp] + push ax + push 0 + push 2 + call dword ptr [bp-8] + add sp, 0cH + mov [bp-60], ax + mov [bp-58], dx + + ; Raw CONNScanInfo via NIOS, following d32wrap _CONNScanInfo + ; argument order from d32conni L$115. + push word ptr [bp-58] ; connReference flat high + push word ptr [bp-60] ; connReference flat low + + push 0 ; returnConnInfo flat high = NULL + push 0 ; returnConnInfo flat low = NULL + + push 0 ; returnInfoLen high + push 0 ; returnInfoLen low + + push 0 ; returnInfoLevel high + push 4 ; returnInfoLevel low, as d32conni L$115 + + push 0 ; scan flag high + push word ptr [bp+8] ; scan flag low + + push word ptr [bp-30] ; scanInfo flat high + push word ptr [bp-32] ; scanInfo flat low + + push 0 ; scanInfoLevel high + push 0aH ; scanInfoLevel low = SERVER_NAME + + push word ptr [bp-54] ; scanIterator/result flat high + push word ptr [bp-56] ; scanIterator/result flat low + + push 0fefeH + push 0fefeH + push 0fefeH + push 0fefeH + + push 0 + push 0aH + push word ptr [bp-14] + push word ptr [bp-16] + call dword ptr [bp-12] + add sp, 30H + + mov [bp-64], ax + mov [bp-62], dx + + ; Unlock maps. + push 0 + push 4 + push word ptr [bp-58] + push word ptr [bp-60] + push 0 + push 3 + call dword ptr [bp-8] + add sp, 0cH + + push 0 + push 4 + push word ptr [bp-54] + push word ptr [bp-56] + push 0 + push 3 + call dword ptr [bp-8] + add sp, 0cH + + push 0 + push 10H + push word ptr [bp-30] + push word ptr [bp-32] + push 0 + push 3 + call dword ptr [bp-8] + add sp, 0cH + + push 0 + push 31H + push word ptr [bp-26] + push word ptr [bp-28] + push 0 + push 3 + call dword ptr [bp-8] + add sp, 0cH + + jmp short c32mapvar_store + +c32mapvar_fail: + mov word ptr [bp-16], 0 + mov word ptr [bp-14], 0 + mov word ptr [bp-64], 0ffffH + mov word ptr [bp-62], 0ffffH + mov word ptr [bp-20], 0 + mov word ptr [bp-18], 0 + mov word ptr [bp-24], 0 + mov word ptr [bp-22], 0 + +c32mapvar_store: + les di, dword ptr [bp+10] + + mov ax, [bp-4] + mov es:[di+0], ax + mov ax, [bp-8] + mov es:[di+2], ax + mov ax, [bp-6] + mov es:[di+4], ax + mov ax, [bp-12] + mov es:[di+6], ax + mov ax, [bp-10] + mov es:[di+8], ax + mov ax, [bp-16] + mov es:[di+10], ax + mov ax, [bp-14] + mov es:[di+12], ax + mov ax, [bp-64] + mov es:[di+14], ax + mov ax, [bp-62] + mov es:[di+16], ax + mov ax, [bp-20] + mov es:[di+18], ax + mov ax, [bp-18] + mov es:[di+20], ax + mov ax, [bp-24] + mov es:[di+22], ax + mov ax, [bp-22] + mov es:[di+24], ax + + pop di + pop si + pop es + pop ds + mov sp, bp + pop bp + xor ah, ah + ret + +c32mapvar_name db 'CONNScanInfo',0 + +_C32_MapVar_Probe endp + + + + end diff --git a/nwtests.c b/nwtests.c index 2463282..c59c4d7 100644 --- a/nwtests.c +++ b/nwtests.c @@ -1803,6 +1803,70 @@ static int tests_c32mapfull2(void) } +static int tests_c32mapvar_one(UI specLen, UI flag) +{ + uint8 out[32]; + uint16 ret_ax, ret_dx, result_lo, result_hi, cref_lo, cref_hi; + + memset(out, 0, sizeof(out)); + + fprintf(stdout, "\nTEST C32MAPVAR specLen=%u flag=%u\n", specLen, flag); + C32_MapVar_Probe(specLen, flag, out); + + ret_ax = tests_get_word_lh(out + 14); + ret_dx = tests_get_word_lh(out + 16); + result_lo = tests_get_word_lh(out + 18); + result_hi = tests_get_word_lh(out + 20); + cref_lo = tests_get_word_lh(out + 22); + cref_hi = tests_get_word_lh(out + 24); + + fprintf(stdout, "Return DX:AX=%04X:%04X resultRef=%04X:%04X connRefLocal=%04X:%04X\n", + ret_dx, ret_ax, result_hi, result_lo, cref_hi, cref_lo); + tests_dump_bytes("OUT:", out, 26); + + if (ret_ax == 0 && ret_dx == 0 && (cref_lo || cref_hi) && + !(cref_lo == 0xFFFE && cref_hi == 0xFFFF)) { + fprintf(stdout, "Try open with connRefLocal:\n"); + fprintf(stdout, " TESTS C32OPENREF %u %u\n", cref_lo, cref_hi); + } + + return(0); +} + +static int tests_c32mapvar(int argc, char *argv[]) +{ + UI specLen = 5; + UI flag = 0; + + if (argc > 2) + specLen = (UI)atoi(argv[2]); + if (argc > 3) + flag = (UI)atoi(argv[3]); + + return tests_c32mapvar_one(specLen, flag); +} + +static int tests_c32mapvarmatrix(void) +{ + fprintf(stdout, "TEST C32MAPVARMATRIX paged\n"); + fprintf(stdout, "Trying SPECTDATA length/flag variants for server MARS.\n"); + tests_wait_key(); + + tests_c32mapvar_one(5, 0); + tests_wait_key(); + + tests_c32mapvar_one(5, 1); + tests_wait_key(); + + tests_c32mapvar_one(0x31, 0); + tests_wait_key(); + + tests_c32mapvar_one(0x31, 1); + + return(0); +} + + int func_tests(int argc, char *argv[], int mode) { if (argc >= 2) { @@ -1851,6 +1915,12 @@ int func_tests(int argc, char *argv[], int mode) if (tests_same_arg(argv[1], "C32MAPFULL2")) return tests_c32mapfull2(); + if (tests_same_arg(argv[1], "C32MAPVAR")) + return tests_c32mapvar(argc, argv); + + if (tests_same_arg(argv[1], "C32MAPVARMATRIX")) + return tests_c32mapvarmatrix(); + if (tests_same_arg(argv[1], "NWREQ87C32MATRIX")) return tests_nwreq87c32matrix();