; ; mars-nwe-dosutils - NetWare/DOS utility tools. ; ; Copyright (C) 2026 Mario Fetka ; Copyright (C) 1993,1996 Martin Stover, Marburg, Germany ; ; This program is free software; you can redistribute it and/or ; modify it under the terms of the GNU General Public License ; as published by the Free Software Foundation; either version 2 ; of the License, or (at your option) any later version. ; ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU General Public License for more details. ; ; You should have received a copy of the GNU General Public License ; along with this program; if not, see . ; Purpose: Open Watcom WASM/MASM-syntax NetWare requester and Client32 transport glue. ; Depends on: ncp.h declarations, ncpcall.c transport helpers and ncpapi.c API wrappers. ; ; ncp.asm ; ; Low-level INT 21h Net_Call and Client32 requester entry points used by the ; DOS NCP transport helpers. This file is split from the former combined ; kern_wasm.asm so IPX glue can stay in ipx.asm. .286 .model large .code public _Net_Call public _ncp_raw_request public _ncp_openref_request public _ncp_mapvar_request _Net_Call proc far push bp mov bp, sp ; int Net_Call(UI func, void *req, void *repl) ; [bp+6] func ; [bp+8] req offset ; [bp+10] req segment ; [bp+12] repl offset ; [bp+14] repl segment mov ax, [bp+6] push ds push si push di pushf lds si, dword ptr [bp+8] les di, dword ptr [bp+12] int 21h popf pop di pop si pop ds pop bp mov ah, 0 ret _Net_Call endp ; int ncp_openref_request(UI refLo, UI refHi, void *outbuf) ; ; Opens a Client32 connection by connection reference using the same d32wrap ; convention as _CONNOpenByReference / w95ocref.o. ; ; Input: ; refLo/refHi = connection reference, e.g. C32PRIMREF returned 0028:0000. ; ; outbuf: ; +00 load AX from D8C1 ; +02 resolver off ; +04 resolver seg ; +06 trampoline off ; +08 trampoline seg ; +0A function off ; +0C function seg ; +0E return AX ; +10 return DX ; +12 handle low ; +14 handle high _ncp_openref_request proc far push bp mov bp, sp sub sp, 80 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 c32openref_fail ; resolve "CONNOpenByReference" push cs push offset c32openref_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 c32openref_have_func jmp c32openref_fail c32openref_have_func: ; local output handle dword at [bp-20] mov word ptr [bp-20], 0 mov word ptr [bp-18], 0 ; MapLockFlat(&handle, 4) -> flat [bp-24] 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-24], ax mov [bp-22], dx ; Call NIOS trampoline command 5 / CONNOpenByReference. ; This matches d32wrap _CONNOpenByReference after w95ocref: ; flat handle ptr, ; refHi/refLo, ; 0,0, ; FEFE FEFE FEFE FEFE, ; command 5, ; function ptr. push word ptr [bp-22] ; flat handle high push word ptr [bp-24] ; flat handle low push word ptr [bp+8] ; ref high push word ptr [bp+6] ; ref low push 0 push 0 push 0fefeH push 0fefeH push 0fefeH push 0fefeH push 0 push 5 push word ptr [bp-14] ; function seg push word ptr [bp-16] ; function off call dword ptr [bp-12] add sp, 1cH mov [bp-28], ax mov [bp-26], dx ; UnlockFlat(handle flat, 4) push 0 push 4 push word ptr [bp-22] push word ptr [bp-24] push 0 push 3 call dword ptr [bp-8] add sp, 0cH jmp short c32openref_store c32openref_fail: mov word ptr [bp-16], 0 mov word ptr [bp-14], 0 mov word ptr [bp-28], 0ffffH mov word ptr [bp-26], 0ffffH mov word ptr [bp-20], 0 mov word ptr [bp-18], 0 c32openref_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-28] mov es:[di+14], ax mov ax, [bp-26] mov es:[di+16], ax mov ax, [bp-20] mov es:[di+18], ax mov ax, [bp-18] mov es:[di+20], ax pop di pop si pop es pop ds mov sp, bp pop bp xor ah, ah ret c32openref_name db 'CONNOpenByReference',0 _ncp_openref_request endp ; int ncp_mapvar_request(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 _ncp_mapvar_request 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 _ncp_mapvar_request endp ; int ncp_raw_request(UI connLo, UI connHi, ; void *hdr, UI hdrLen, ; void *path, UI pathLen, ; void *rep0, UI rep0Len, ; void *rep1, UI rep1Len, ; void *outbuf) ; ; Sends a raw NCP request through the d32wrap-compatible 5-slot ; fragment tables: 5 * 8 = 0x28 bytes for request and reply. _ncp_raw_request proc far push bp mov bp, sp sub sp, 180 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-2], ax db 66h, 89h, 76h, 0FAh ; resolver at [bp-6] db 66h, 89h, 4Eh, 0F6h ; trampoline at [bp-10] or ax, ax jne raw_fail ; resolve COMPATNcpRequestReply push cs push offset raw_name push 0 push 0 call dword ptr [bp-6] add sp, 8 mov [bp-14], ax mov [bp-12], dx or ax, dx jne raw_have_func jmp raw_fail raw_have_func: ; actual reply len dword at [bp-36] mov word ptr [bp-36], 0 mov word ptr [bp-34], 0 ; map hdr -> [bp-20] push 0 push word ptr [bp+0eH] push word ptr [bp+0cH] push word ptr [bp+0aH] push 0 push 2 call dword ptr [bp-6] add sp, 0cH mov [bp-20], ax mov [bp-18], dx ; map path -> [bp-24] push 0 push word ptr [bp+14H] push word ptr [bp+12H] push word ptr [bp+10H] push 0 push 2 call dword ptr [bp-6] add sp, 0cH mov [bp-24], ax mov [bp-22], dx ; map rep0 -> [bp-28] push 0 push word ptr [bp+1aH] push word ptr [bp+18H] push word ptr [bp+16H] push 0 push 2 call dword ptr [bp-6] add sp, 0cH mov [bp-28], ax mov [bp-26], dx ; map rep1 -> [bp-32] push 0 push word ptr [bp+20H] push word ptr [bp+1eH] push word ptr [bp+1cH] push 0 push 2 call dword ptr [bp-6] add sp, 0cH mov [bp-32], ax mov [bp-30], dx ; zero req table [bp-160] len 40 and reply table [bp-120] len 40 push ss pop es cld xor ax, ax lea di, -160[bp] mov cx, 20 rep stosw lea di, -120[bp] mov cx, 20 rep stosw ; req entry0 = hdr mov ax, [bp-20] mov [bp-160], ax mov ax, [bp-18] mov [bp-158], ax mov ax, [bp+0eH] mov [bp-156], ax mov word ptr [bp-154], 0 ; req entry1 = path mov ax, [bp-24] mov [bp-152], ax mov ax, [bp-22] mov [bp-150], ax mov ax, [bp+14H] mov [bp-148], ax mov word ptr [bp-146], 0 ; reply entry0 = rep0 mov ax, [bp-28] mov [bp-120], ax mov ax, [bp-26] mov [bp-118], ax mov ax, [bp+1aH] mov [bp-116], ax mov word ptr [bp-114], 0 ; reply entry1 = rep1 mov ax, [bp-32] mov [bp-112], ax mov ax, [bp-30] mov [bp-110], ax mov ax, [bp+20H] mov [bp-108], ax mov word ptr [bp-106], 0 ; map req table 0x28 -> [bp-40] push 0 push 28H push ss lea ax, -160[bp] push ax push 0 push 2 call dword ptr [bp-6] add sp, 0cH mov [bp-40], ax mov [bp-38], dx ; map reply table 0x28 -> [bp-44] push 0 push 28H push ss lea ax, -120[bp] push ax push 0 push 2 call dword ptr [bp-6] add sp, 0cH mov [bp-44], ax mov [bp-42], dx ; map actual reply len -> [bp-48] push 0 push 4 push ss lea ax, -36[bp] push ax push 0 push 2 call dword ptr [bp-6] add sp, 0cH mov [bp-48], ax mov [bp-46], dx ; call COMPAT via NIOS command 8 push word ptr [bp-46] push word ptr [bp-48] push word ptr [bp-42] push word ptr [bp-44] push 0 push 2 push word ptr [bp-38] push word ptr [bp-40] push 0 push 2 push 0 push 57H push 0 push 0 push word ptr [bp+8] push word ptr [bp+6] push 0 push 8 push word ptr [bp-12] push word ptr [bp-14] call dword ptr [bp-10] add sp, 28H mov [bp-52], ax mov [bp-50], dx ; unlock important mappings only; ignore return push 0 push 4 push word ptr [bp-46] push word ptr [bp-48] push 0 push 3 call dword ptr [bp-6] add sp, 0cH push 0 push 28H push word ptr [bp-42] push word ptr [bp-44] push 0 push 3 call dword ptr [bp-6] add sp, 0cH push 0 push 28H push word ptr [bp-38] push word ptr [bp-40] push 0 push 3 call dword ptr [bp-6] add sp, 0cH jmp short raw_store raw_fail: mov word ptr [bp-14], 0 mov word ptr [bp-12], 0 mov word ptr [bp-52], 0ffffH mov word ptr [bp-50], 0ffffH mov word ptr [bp-36], 0 mov word ptr [bp-34], 0 raw_store: les di, dword ptr [bp+22H] mov ax, [bp-2] mov es:[di+0], ax mov ax, [bp-6] mov es:[di+2], ax mov ax, [bp-4] mov es:[di+4], ax mov ax, [bp-10] mov es:[di+6], ax mov ax, [bp-8] mov es:[di+8], ax mov ax, [bp-14] mov es:[di+10], ax mov ax, [bp-12] mov es:[di+12], ax mov ax, [bp-52] mov es:[di+14], ax mov ax, [bp-50] mov es:[di+16], ax mov ax, [bp-36] mov es:[di+18], ax mov ax, [bp-34] mov es:[di+20], ax pop di pop si pop es pop ds mov sp, bp pop bp xor ah, ah ret raw_name db 'COMPATNcpRequestReply',0 _ncp_raw_request endp end