Files
mars-dosutils/ncpcall.c
Mario Fetka 98ffa17006 ncpcalls: split IPX and requester assembly glue
Split the Open Watcom assembly glue into separate IPX and NCP requester
modules.

Keep the IPX socket and far-memory helper entry points in ipx.asm and move the
INT 21h Net_Call plus Client32 requester entry points into ncpcall.asm. Split
the former kern.h declarations accordingly into ipx.h and ncpcall.h, and update
net.h and the Open Watcom build to use the new headers and object files.

This matches the current source layout where ncpcall.c owns the low-level NCP
transport helpers and ncpapi.c owns the ncpXX_YY_* protocol API wrappers.

No behavior change.
2026-05-29 12:04:16 +02:00

271 lines
6.8 KiB
C

/*
* 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 <http://www.gnu.org/licenses/>.
*/
/*
* Purpose: Low-level NCP requester and Client32 transport helpers for the NetWare DOS tools.
* Depends on: net.h, ncpapi.h, netcall.c requester glue, and ncpcall.asm/doc/kern.asm Net_Call/Client32 request entry points.
*
* The public ncpXX_YY_* protocol wrappers live in ncpapi.c, which is planned
* to become ncpapi.c. This file keeps the lower-level requester/transport
* helpers that those API wrappers use.
*/
#include "net.h"
#include "ncpapi.h"
/* Client32 raw requester transport helpers used by the NCP API wrappers. */
/*
* ncp_build_handle_path
*
* Purpose:
* Builds the Client32-compatible NWHandlePathStruct used by NCP87 request
* wrappers when the caller already has one to three path components.
*
* Parameters:
* dhandle/dirbase/style describe the starting directory context. c1..c3
* are written as length-prefixed path components.
*
* Returns:
* Number of bytes used by the path structure.
*/
UI ncp_build_handle_path(uint8 *buf, uint8 dhandle,
uint16 dirbase, uint8 style,
int count,
const char *c1, const char *c2, const char *c3)
{
uint8 *p;
int l;
UI used;
/*
* DeveloperNet/ncpdos16 path structure used by NCP87/S6 through
* Client32 COMPATNcpRequestReply.
*
* This is the exact shape verified by TESTS NCP87C32AUTO:
* 00 02 00 00 00 00 01 09 4C 4F 47 49 4E 2E 45 58 45
*
* Meaning:
* word[1] = short dir handle
* word[3] = dir base
* byte[5] = dirstyle
* byte[6] = component count
* then len/name components
*
* The old/simple struct used by the INT 21h F257 fallback is not accepted
* by this Client32 path.
*/
memset(buf, 0, 0x140);
if (dhandle) {
tool_put_word_lh(buf + 1, (uint16)dhandle);
tool_put_word_lh(buf + 3, dirbase);
buf[5] = style;
} else {
buf[5] = 0xff;
}
p = buf + 6;
*p++ = (uint8)count;
if (count > 0 && c1) {
l = strlen(c1);
if (l > 255) l = 255;
*p++ = (uint8)l;
memcpy(p, c1, l);
p += l;
}
if (count > 1 && c2) {
l = strlen(c2);
if (l > 255) l = 255;
*p++ = (uint8)l;
memcpy(p, c2, l);
p += l;
}
if (count > 2 && c3) {
l = strlen(c3);
if (l > 255) l = 255;
*p++ = (uint8)l;
memcpy(p, c3, l);
p += l;
}
used = (UI)(p - buf);
tool_put_word_lh(buf + 0x13c, used);
return(used);
}
/*
* ncp_build_handle_path_from_dos_path
*
* Purpose:
* Converts a DOS-style path string into the Client32-compatible
* NWHandlePathStruct used by the NCP87 wrappers.
*
* Notes:
* Drive prefixes, leading slashes and simple current-directory components
* are skipped so tool callers can pass ordinary DOS paths.
*/
UI ncp_build_handle_path_from_dos_path(uint8 *buf, uint8 dhandle,
uint16 dirbase, uint8 style,
const char *dospath)
{
uint8 *p;
uint8 *countp;
int count = 0;
const char *s;
UI used;
memset(buf, 0, 0x140);
if (dhandle) {
tool_put_word_lh(buf + 1, (uint16)dhandle);
tool_put_word_lh(buf + 3, dirbase);
buf[5] = style;
} else {
buf[5] = 0xff;
}
p = buf + 6;
countp = p++;
s = dospath;
if (!s) s = "";
/*
* DOS tools mostly pass relative paths against the current directory
* handle. Accept simple DOS decoration here so RIGHTS can pass "." or
* ".\\UDIR\\FILE" without constructing path components in the caller.
*/
if (s[0] && s[1] == ':')
s += 2;
while (*s == '\\' || *s == '/')
s++;
while (*s && p < buf + 0x138 && count < 32) {
const char *start;
int len;
while (*s == '\\' || *s == '/')
s++;
if (*s == '.'
&& (s[1] == '\0' || s[1] == '\\' || s[1] == '/')) {
s++;
continue;
}
start = s;
while (*s && *s != '\\' && *s != '/')
s++;
len = (int)(s - start);
if (len <= 0)
continue;
if (len > 255)
len = 255;
if (p + 1 + len >= buf + 0x138)
break;
*p++ = (uint8)len;
memcpy(p, start, len);
p += len;
count++;
}
*countp = (uint8)count;
used = (UI)(p - buf);
tool_put_word_lh(buf + 0x13c, used);
return(used);
}
/*
* Current verified Client32 path for mars-nwe DOS utilities:
*
* ncp_mapvar_request(4,0) -> connRefLocal FFFF:FFFE
* ncp_openref_request(connRefLocal) -> Client32 handle, e.g. 0101:0001
*
* ncp_mapvar_request currently contains the confirmed Mars server-name scan
* shape. It is intentionally kept small and isolated here so FLAG and later
* tools do not carry the old exploratory tests.
*/
/*
* ncp_get_requester_handle
*
* Purpose:
* Resolves the active MARS/NetWare connection into the Client32 NCP handle
* used by the raw requester path.
*
* Requester path:
* ncp_mapvar_request followed by ncp_openref_request.
*
* Returns:
* 0 on success. Non-zero values indicate that the connection reference or
* Client32 NCP handle could not be obtained.
*/
int ncp_get_requester_handle(uint16 *handle_lo, uint16 *handle_hi)
{
uint8 mapout[32];
uint8 openout[32];
uint16 map_ret_ax, map_ret_dx;
uint16 cref_lo, cref_hi;
uint16 open_ret_ax, open_ret_dx;
if (!handle_lo || !handle_hi)
return(1);
*handle_lo = 0;
*handle_hi = 0;
memset(mapout, 0, sizeof(mapout));
ncp_mapvar_request(4, 0, mapout);
map_ret_ax = tool_get_word_lh(mapout + 14);
map_ret_dx = tool_get_word_lh(mapout + 16);
cref_lo = tool_get_word_lh(mapout + 22);
cref_hi = tool_get_word_lh(mapout + 24);
if (map_ret_ax != 0 || map_ret_dx != 0 || (cref_lo == 0 && cref_hi == 0))
return(2);
memset(openout, 0, sizeof(openout));
ncp_openref_request(cref_lo, cref_hi, openout);
open_ret_ax = tool_get_word_lh(openout + 14);
open_ret_dx = tool_get_word_lh(openout + 16);
*handle_lo = tool_get_word_lh(openout + 18);
*handle_hi = tool_get_word_lh(openout + 20);
if (open_ret_ax != 0 || open_ret_dx != 0 || (*handle_lo == 0 && *handle_hi == 0))
return(3);
return(0);
}