/* * 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: Low-level NCP requester and Client32 transport helpers for the NetWare DOS tools. * Depends on: net.h, ncpapi.h, netcall.c requester glue, and ncp.asm/doc/kern.asm Net_Call/Client32 request entry points. * * The public ncpXX_YY_* protocol wrappers live in ncpapi.c. This file keeps * the lower-level requester/transport helpers used by those API wrappers. */ #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); }