diff --git a/TODO.md b/TODO.md index 9ed046e..cc688b4 100644 --- a/TODO.md +++ b/TODO.md @@ -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 diff --git a/src/nwconn.c b/src/nwconn.c index 156ce0b..735f5cd 100644 --- a/src/nwconn.c +++ b/src/nwconn.c @@ -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