docs: document ncp22 directory scan layouts

This commit is contained in:
Mario Fetka
2026-06-01 20:17:08 +00:00
parent 4db82757c1
commit 017ef23833
2 changed files with 171 additions and 18 deletions

39
TODO.md
View File

@@ -222,6 +222,28 @@ Current status:
for this older NetWare 2.x save/restore pair contain header/length wording
that does not line up cleanly with the common `0x2222/22` group header. This
is documented inline and no behavior was changed.
- `22/19` Set Directory Information, `22/1a` Get Path Name of a
Volume-Directory Number Pair, `22/1b` Scan Salvageable Files (old), `22/1c`
Recover Salvageable File (old), `22/1d` Purge Salvageable File (old),
`22/1e` Scan a Directory, `22/1f` Get Directory Entry, and `22/20` Scan
Volume's User Disk Restrictions now have inline request/reply layout
documentation.
- `22/19`, `22/1a`, `22/1b`, and `22/1d` match the documented request payload
offsets. `22/1a` uses the old 16-bit directory-entry-number form; the
WebSDK table does not spell out byte order for that word, while MARS-NWE
reads it as Hi-Lo.
- `22/1c` validates the documented old/new filename fields, but the current
backend call recovers by directory handle and sequence only and does not pass
the old/new names to the salvage backend.
- `22/1e` matches the documented offsets, but the SDK documents `Sequence` as
Lo-Hi while the current parser reads it with `GET_BE32()`.
- `22/1f` consumes the documented `DirectoryHandle`; legacy source comments
expected two extra unknown bytes after it, but the SDK request has no such
fields and the helper ignores them.
- `22/20` reads `VolumeNumber` and `Sequence` in the normal NCP 22 payload
positions. The WebSDK/PDF table for this call shows `VolumeNumber` one byte
later than the common group-header alignment; treat this as an offset
ambiguity until verified with a direct test caller.
Follow-up:
@@ -234,8 +256,21 @@ Follow-up:
before changing the conservative connection-local implementation; the SDK/PDF
tables for those two NetWare 2.x calls are less internally consistent than
the surrounding directory-handle calls.
- Continue the `0x2222/22` audit from `22/19` Set Directory Information onward,
keeping each patch to a small logical endpoint block.
- Verify `22/1a` directory-entry-number byte order against an old requester or
direct test caller before changing the current Hi-Lo interpretation.
- Decide whether `22/1c` should pass the documented old/new filename fields to
the salvage backend, or whether sequence-only recovery is sufficient for old
requester compatibility.
- Verify `22/1e` Sequence byte order; current code uses `GET_BE32()` although
the SDK/WebSDK documents Lo-Hi.
- Verify whether `22/1f` should continue accepting legacy callers that send the
two extra bytes described by the old source comment, even though the SDK
request only contains `DirectoryHandle`.
- Verify `22/20` VolumeNumber offset against a direct test caller; the WebSDK
table appears shifted by one byte compared with the normal NCP 22 group
header and the current parser.
- Continue the `0x2222/22` audit from `22/21` Add User Disk Space Restriction
onward, keeping each patch to a small logical endpoint block.
### Extended volume information field mapping

View File

@@ -3932,9 +3932,24 @@ static int handle_ncp_serv(void)
}
break;
case 0x19 : {
/* Set Directory Information
* Modifies basic directory information as creation date and
* directory rights mask. DOS namespace.
/*
* NCP 0x2222/22/25 Set Directory Information.
*
* SDK request payload:
* byte DirectoryHandle
* word CreationDate (Lo-Hi)
* word CreationTime (Lo-Hi)
* long OwnerID (Hi-Lo)
* byte MaximumAccessRightsMask
* byte DirectoryPathLen
* byte DirectoryPath[DirectoryPathLen]
*
* SDK reply: completion code only.
*
* Parser comparison: current INPUT layout matches the
* documented NetWare 2.x/3.x payload offsets. The parser
* passes the date/time byte pairs through to nw_set_dir_info()
* and reads OwnerID as documented Hi-Lo.
*/
struct INPUT {
uint8 header[7]; /* Requestheader */
@@ -3961,13 +3976,22 @@ static int handle_ncp_serv(void)
case 0x1a : { /* Get Pathname of A Volume Dir Pair */
/*
* Old NetWare 2.x compatibility call:
* byte volume
* word directory entry number (Hi-Lo)
* NCP 0x2222/22/26 Get Path Name of a
* Volume-Directory Number Pair.
*
* Reply:
* byte path length
* byte path[path length]
* SDK request payload:
* byte VolumeNumber
* word DirectoryEntryNumber
*
* SDK reply payload:
* byte DirectoryPathLen
* byte DirectoryPath[DirectoryPathLen]
*
* Parser comparison: current parser consumes the documented
* volume byte and 16-bit directory-entry number. The WebSDK
* table does not spell out byte order for that word; current
* code reads it as Hi-Lo and returns the documented length
* prefixed path string.
*
* This is the older string form of the NCP23/F3 mapping.
* NCP23/F3 is preferred for 32-bit directory numbers and
@@ -4026,6 +4050,22 @@ static int handle_ncp_serv(void)
break;
case 0x1b : { /* Scan Salvageable Files, old 22/27 */
/*
* NCP 0x2222/22/27 Scan Salvageable Files (old).
*
* SDK request payload:
* byte DirectoryHandle
* long Sequence (Lo-Hi)
*
* SDK reply payload: old DOS salvage directory entry,
* including next Sequence, attributes, short name, timestamps,
* deleted time/date, and deleted object ID.
*
* Parser comparison: current parser matches the documented
* request offsets and reads Sequence as Lo-Hi via GET_32().
* The compatibility bridge delegates reply construction to
* the shared salvage backend.
*/
int result;
if (requestlen < 8) result = -0xfb;
else result = nsp_salvage_scan_short_handle((int)p[1],
@@ -4037,6 +4077,26 @@ static int handle_ncp_serv(void)
break;
case 0x1c : { /* Recover Salvageable File, old 22/28 */
/*
* NCP 0x2222/22/28 Recover Salvageable File (old).
*
* SDK request payload:
* byte DirectoryHandle
* long Sequence (Hi-Lo)
* byte FileNameLen
* byte FileName[FileNameLen]
* byte NewFileNameLen
* byte NewFileName[NewFileNameLen]
*
* SDK reply: completion code only.
*
* Parser comparison: current parser validates the documented
* variable-length filename fields and reads Sequence as Hi-Lo.
* The backend call currently recovers by directory handle and
* sequence only; it does not pass the documented old/new name
* strings through. This is documented in TODO, not changed
* here.
*/
int result;
if (requestlen < 10) result = -0xfb;
else {
@@ -4058,6 +4118,18 @@ static int handle_ncp_serv(void)
break;
case 0x1d : { /* Purge Salvageable File, old 22/29 */
/*
* NCP 0x2222/22/29 Purge Salvageable File (old).
*
* SDK request payload:
* byte DirectoryHandle
* long Sequence (Hi-Lo)
*
* SDK reply: completion code only.
*
* Parser comparison: current parser matches the documented
* offsets and reads Sequence as Hi-Lo.
*/
int result;
if (requestlen < 8) result = -0xfb;
else result = nsp_salvage_purge_short_handle((int)p[1],
@@ -4068,6 +4140,25 @@ static int handle_ncp_serv(void)
break;
case 0x1e : { /* SCAN a Directory, e.g. used by ndir.exe */
/*
* NCP 0x2222/22/30 Scan a Directory.
*
* SDK request payload:
* byte DirectoryHandle
* byte SearchAttributes
* long Sequence (Lo-Hi)
* byte SearchPatternLen
* byte SearchPattern[SearchPatternLen]
*
* SDK reply payload: old DOS scan directory entry, beginning
* with next Sequence and followed by file/subdirectory
* metadata.
*
* Parser comparison: current INPUT layout matches the
* documented offsets, but it reads Sequence with GET_BE32()
* while the SDK documents Lo-Hi. This is recorded in TODO;
* no parser behavior is changed here.
*/
struct INPUT {
uint8 header[7]; /* Requestheader */
uint8 div[3]; /* 0x0, dlen, ufunc */
@@ -4091,6 +4182,23 @@ static int handle_ncp_serv(void)
break;
case 0x1f : { /* SCAN a root dir ???? */
/*
* NCP 0x2222/22/31 Get Directory Entry.
*
* SDK request payload:
* byte DirectoryHandle
*
* SDK reply payload: old DOS directory-entry information for
* the directory pointed to by the handle.
*
* Parser comparison: current parser consumes the documented
* handle byte. The legacy source comments treated the two
* bytes after the handle as unknown, but the SDK request has
* no such payload fields. The helper ignores those bytes and
* returns DOS directory info for the resolved handle. Keep
* this noted for old-requester verification before changing
* the accepted request length.
*/
struct INPUT {
uint8 header[7]; /* Requestheader */
uint8 div[3]; /* 0x0, dlen, ufunc */
@@ -4110,13 +4218,23 @@ static int handle_ncp_serv(void)
/*
* NCP 0x2222/22/32 Scan Volume's User Disk Restrictions.
*
* WebSDK / headers:
* Request: Volume Number, Sequence. Sequence starts at
* zero and is incremented by the number of entries returned
* by previous calls.
* Reply: Number Of Entries followed by up to twelve
* Object ID / Restriction pairs. Restrictions are reported
* in 4K blocks.
* SDK request payload:
* byte VolumeNumber
* long Sequence (Lo-Hi)
*
* SDK reply payload:
* byte NumberOfEntries
* repeated ObjectID / Restriction pairs, both 4K-block
* counters; the current bounded reply returns up to twelve
* entries per call.
*
* Parser comparison: current parser reads VolumeNumber from
* the first payload byte and Sequence as Lo-Hi via GET_32().
* The Micro Focus WebSDK table shows VolumeNumber one byte
* later than the normal NCP 22 group header would imply; the
* local parser follows the common group-header alignment.
* This offset ambiguity is recorded in TODO for direct-test
* verification.
*
* The Rust nwserver and lwared implementations both return
* an empty list after validating the volume. MARS-NWE keeps