diff --git a/kern.h b/kern.h index f1096af..dc82803 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_MapFull_Probe(void *outbuf); extern int KERN_CALL C32_ScanRefsIter_Probe(UI iterLo, UI iterHi, void *outbuf); extern int KERN_CALL C32_ScanRefs2_Probe(void *outbuf); extern int KERN_CALL C32_ScanFirst_Probe(void *outbuf); diff --git a/kern_wasm.asm b/kern_wasm.asm index e323168..b39a9cf 100644 --- a/kern_wasm.asm +++ b/kern_wasm.asm @@ -29,6 +29,7 @@ public _C32_OpenRef_Probe public _C32_ScanFirst_Probe public _C32_ScanRefs2_Probe public _C32_ScanRefsIter_Probe +public _C32_MapFull_Probe public _Net_Call_VLM_Raw public _Net_Call_NWCVLMREQ @@ -2010,4 +2011,289 @@ _C32_ScanRefsIter_Probe endp +; int C32_MapFull_Probe(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_MapFull_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 c32mapfull_fail + + ; resolve "CONNScanInfo" + push cs + push offset c32mapfull_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 c32mapfull_have_func + jmp c32mapfull_fail + +c32mapfull_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 word ptr [bp-48], 31H + 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 ; connInfoVersion high + push 0 ; connInfoVersion 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 c32mapfull_store + +c32mapfull_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 + +c32mapfull_store: + les di, dword ptr [bp+6] + + 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 + +c32mapfull_name db 'CONNScanInfo',0 + +_C32_MapFull_Probe endp + + end diff --git a/nwtests.c b/nwtests.c index 4663d9c..7161d9a 100644 --- a/nwtests.c +++ b/nwtests.c @@ -1711,6 +1711,52 @@ static int tests_c32scaniter(int argc, char *argv[]) } +static int tests_c32mapfull(void) +{ + uint8 out[32]; + uint16 load_ax, res_off, res_seg, tramp_off, tramp_seg; + uint16 fn_off, fn_seg, ret_ax, ret_dx; + uint16 result_lo, result_hi, cref_lo, cref_hi; + + memset(out, 0, sizeof(out)); + + fprintf(stdout, "TEST C32MAPFULL\n"); + fprintf(stdout, "Exact-ish w95mconn __C32MapConn16To32 scan step for server MARS\n"); + + C32_MapFull_Probe(out); + + load_ax = tests_get_word_lh(out + 0); + res_off = tests_get_word_lh(out + 2); + res_seg = tests_get_word_lh(out + 4); + tramp_off = tests_get_word_lh(out + 6); + tramp_seg = tests_get_word_lh(out + 8); + fn_off = tests_get_word_lh(out + 10); + fn_seg = tests_get_word_lh(out + 12); + 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, "Load AX=%04X Resolver=%04X:%04X Tramp=%04X:%04X\n", + load_ax, res_seg, res_off, tramp_seg, tramp_off); + fprintf(stdout, "Function CONNScanInfo=%04X:%04X\n", fn_seg, fn_off); + fprintf(stdout, "Return DX:AX=%04X:%04X\n", ret_dx, ret_ax); + fprintf(stdout, "resultRef=%04X:%04X connRefLocal=%04X:%04X\n", + result_hi, result_lo, cref_hi, cref_lo); + tests_dump_bytes("OUT:", out, 26); + + if (ret_ax == 0 && ret_dx == 0 && (result_lo || result_hi)) { + fprintf(stdout, "\nTry next:\n"); + fprintf(stdout, " TESTS C32OPENREF %u %u\n", result_lo, result_hi); + fprintf(stdout, " TESTS NWREQ87C32RAW %u %u\n", result_lo, result_hi); + } + + return(0); +} + + int func_tests(int argc, char *argv[], int mode) { if (argc >= 2) { @@ -1753,6 +1799,9 @@ int func_tests(int argc, char *argv[], int mode) if (tests_same_arg(argv[1], "C32SCANITER")) return tests_c32scaniter(argc, argv); + if (tests_same_arg(argv[1], "C32MAPFULL")) + return tests_c32mapfull(); + if (tests_same_arg(argv[1], "NWREQ87C32MATRIX")) return tests_nwreq87c32matrix();