Files
mars-dosutils/c32ncp.c
2026-05-23 22:16:36 +02:00

169 lines
4.5 KiB
C

#include "net.h"
#include "c32ncp.h"
/* c32ncp.c - Client32 NCP helpers for mars-dosutils */
static void c32_put_word_lh(uint8 *p, uint16 v)
{
p[0] = (uint8)(v & 0xff);
p[1] = (uint8)((v >> 8) & 0xff);
}
static void c32_put_dword_lh(uint8 *p, uint32 v)
{
p[0] = (uint8)(v & 0xff);
p[1] = (uint8)((v >> 8) & 0xff);
p[2] = (uint8)((v >> 16) & 0xff);
p[3] = (uint8)((v >> 24) & 0xff);
}
static uint16 c32_get_word_lh(uint8 *p)
{
return((uint16)(p[0] | ((uint16)p[1] << 8)));
}
static uint32 c32_get_dword_lh(uint8 *p)
{
return((uint32)p[0] |
((uint32)p[1] << 8) |
((uint32)p[2] << 16) |
((uint32)p[3] << 24));
}
static int c32_build_handle_path(uint8 *p, uint8 dhandle, const char *name)
{
int nlen;
nlen = strlen(name);
if (nlen > 255)
nlen = 255;
*p++ = dhandle;
c32_put_dword_lh(p, 0L); p += 4;
*p++ = 0; /* dirstyle = short dir handle */
*p++ = 1; /* one path component */
*p++ = (uint8)nlen;
memcpy(p, name, nlen);
return(1 + 4 + 1 + 1 + 1 + nlen);
}
/*
* Current verified Client32 path for mars-nwe DOS utilities:
*
* C32_MapVar_Probe(4,0) -> connRefLocal FFFF:FFFE
* C32_OpenRef_Probe(connRefLocal) -> Client32 handle, e.g. 0101:0001
*
* C32_MapVar_Probe 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.
*/
int c32_get_ncp_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));
C32_MapVar_Probe(4, 0, mapout);
map_ret_ax = c32_get_word_lh(mapout + 14);
map_ret_dx = c32_get_word_lh(mapout + 16);
cref_lo = c32_get_word_lh(mapout + 22);
cref_hi = c32_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));
C32_OpenRef_Probe(cref_lo, cref_hi, openout);
open_ret_ax = c32_get_word_lh(openout + 14);
open_ret_dx = c32_get_word_lh(openout + 16);
*handle_lo = c32_get_word_lh(openout + 18);
*handle_hi = c32_get_word_lh(openout + 20);
if (open_ret_ax != 0 || open_ret_dx != 0 || (*handle_lo == 0 && *handle_hi == 0))
return(3);
return(0);
}
int c32_ncp87_obtain_rim_attributes(const char *name,
uint16 dir_handle,
uint32 *attr_out,
uint16 *actual_out,
uint16 *handle_lo_out,
uint16 *handle_hi_out)
{
uint16 handle_lo, handle_hi;
uint8 hdr[16];
uint8 path[0x140];
uint8 rep0[0x60];
uint8 rep1[0x110];
uint8 rawout[32];
uint16 raw_ret_ax, raw_ret_dx;
uint16 actual_lo;
int path_len;
int rc;
if (!name || !attr_out)
return(1);
*attr_out = 0;
if (actual_out) *actual_out = 0;
if (handle_lo_out) *handle_lo_out = 0;
if (handle_hi_out) *handle_hi_out = 0;
rc = c32_get_ncp_handle(&handle_lo, &handle_hi);
if (rc)
return(10 + rc);
memset(hdr, 0, sizeof(hdr));
hdr[0] = 6; /* NCP87 subfunction 6 */
hdr[1] = 0; /* source namespace DOS */
hdr[2] = 0; /* target namespace DOS */
c32_put_word_lh(hdr + 3, 0x0006); /* SA_ALL */
c32_put_dword_lh(hdr + 5, 0x00000004UL); /* RIM_ATTRIBUTES */
path_len = c32_build_handle_path(path, (uint8)dir_handle, name);
memset(rep0, 0, sizeof(rep0));
memset(rep1, 0, sizeof(rep1));
memset(rawout, 0, sizeof(rawout));
C32_NCP87_Raw5_Probe(handle_lo, handle_hi,
hdr, 9,
path, (UI)path_len,
rep0, 0x4d,
rep1, 0x100,
rawout);
raw_ret_ax = c32_get_word_lh(rawout + 14);
raw_ret_dx = c32_get_word_lh(rawout + 16);
actual_lo = c32_get_word_lh(rawout + 18);
if (raw_ret_ax != 0 || raw_ret_dx != 0)
return(20);
/*
* Verified reply layout for RIM_ATTRIBUTES:
* REP0+4 little-endian dword = DOS attributes
* Example LOGIN.EXE: 20h archive.
*/
*attr_out = c32_get_dword_lh(rep0 + 4);
if (actual_out) *actual_out = actual_lo;
if (handle_lo_out) *handle_lo_out = handle_lo;
if (handle_hi_out) *handle_hi_out = handle_hi;
return(0);
}