docs: document ncp22 quota and trustee layouts

This commit is contained in:
Mario Fetka
2026-06-01 20:32:01 +00:00
parent 017ef23833
commit cb4d9c8a9e
3 changed files with 187 additions and 35 deletions

View File

@@ -756,10 +756,24 @@ static void handle_fxx(int gelen, int func)
} else if (0x16 == func) {
switch (ufunc) {
/* QUOTA support from: Matt Paley */
case 0x21 : /* Change volume restrictions */
case 0x22 : /* Remove volume restrictions */
case 0x29 : { /* Read volume restrictions */
/* Returns 3 integers, uid, gid, 0=OK/1=Permission denied */
case 0x21 : /* Add User Disk Space Restriction, 0x2222/22/33 */
case 0x22 : /* Remove User Disk Space Restrictions, 0x2222/22/34 */
case 0x29 : { /* Get Object Disk Usage And Restrictions, 0x2222/22/41 */
/*
* Forwarded from src/nwconn.c NCP 0x2222/22. The shared quota
* prehandler sees only the subfunction payload as rdata:
*
* rdata[0] VolumeNumber
* rdata[1..4] ObjectID (Hi-Lo)
* rdata[5..8] DiskSpaceLimit (Lo-Hi, only for 22/33)
*
* Parser comparison: ObjectID is read from the documented position
* for all three subfunctions. DiskSpaceLimit for 22/33 is not
* consumed by this prehandler; handle_after_bind() receives only the
* uid/gid/permission tuple produced below.
*
* Returns 3 integers, uid, gid, 0=OK/1=Permission denied.
*/
uint32 id = GET_BE32(rdata+1);
internal_act=1;
if (get_guid((int*) responsedata, (int*)(responsedata+sizeof(int)),

View File

@@ -4229,12 +4229,12 @@ static int handle_ncp_serv(void)
* 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 first payload byte and Sequence with GET_BE32(), while
* the SDK/PDF documents Sequence as Lo-Hi. 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. Both items are
* 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
@@ -4252,22 +4252,70 @@ static int handle_ncp_serv(void)
}
break;
case 0x21 : { /* change Vol restrictions for Obj */
case 0x21 : { /* Add User Disk Space Restriction */
/*
* NCP 0x2222/22/33 Add User Disk Space Restriction.
*
* SDK request payload after the group header:
* byte VolumeNumber
* long ObjectID (Hi-Lo)
* long DiskSpaceLimit (Lo-Hi, 4K blocks)
*
* SDK completion: 0x00 success, 0x8c no set privileges,
* 0x96 server out of memory, 0x98 disk map error.
*
* Parser comparison: this dispatcher only recognizes the
* subfunction and forwards prehandling to nwbind. The
* forwarded parser in src/nwbind.c maps ObjectID from the
* documented payload position, but the current quota
* prehandle does not consume DiskSpaceLimit. That is
* recorded in TODO for a behavior audit; this comment does
* not change wire behavior.
*/
XDPRINTF((5, 0, "Change vol restrictions"));
}
return(-2); /* nwbind must do prehandling */
case 0x22 : { /* remove Vol restrictions for Obj */
case 0x22 : { /* Remove User Disk Space Restrictions */
/*
* NCP 0x2222/22/34 Remove User Disk Space Restrictions.
*
* SDK request payload after the group header:
* byte VolumeNumber
* long ObjectID (Hi-Lo)
*
* SDK completion: 0x00 success, 0x8c no set privileges,
* 0xfe user not found.
*
* Parser comparison: this dispatcher forwards the call to
* nwbind, whose quota prehandler reads ObjectID from the
* documented payload position.
*/
XDPRINTF((5, 0, "Remove vol restrictions"));
}
return(-2); /* nwbind must do prehandling */
case 0x25 : { /* Set Entry, Set Directory File Information
* sets or changes the file or directory information to the
* values entered in 'Change Bits'.
* NO REPLY
* used by ncopy.exe, flag.exe
*/
case 0x25 : { /* Set Directory Entry Information */
/*
* NCP 0x2222/22/37 Set Directory Entry Information.
*
* SDK request payload after the group header:
* byte DirHandle
* byte SearchAttributes
* long Sequence (Lo-Hi)
* long ChangeBits (Lo-Hi)
* ... DOS file/directory or Macintosh namespace entry
*
* SDK completion: 0x00 success, 0x01 invalid parameter,
* 0x8c no set privileges, 0xbf invalid name space.
*
* Parser comparison: current struct layout matches the
* documented field order and fixed 148-byte payload, but it
* reads Sequence with GET_BE32() while the SDK documents
* Sequence as Lo-Hi. ChangeBits is handled later by
* nw_set_a_directory_entry() as Lo-Hi. This endpoint is
* used by ncopy.exe and flag.exe.
*/
struct INPUT {
uint8 header[7]; /* Requestheader */
uint8 div[3]; /* 0x0, dlen, ufunc */
@@ -4295,7 +4343,27 @@ static int handle_ncp_serv(void)
}
break;
case 0x26 : { /* Scan file or Dir for ext trustees */
case 0x26 : { /* Scan File or Directory for Extended Trustees */
/*
* NCP 0x2222/22/38 Scan File or Directory for Extended
* Trustees.
*
* SDK request payload after the group header:
* byte DirHandle
* byte Sequence
* byte PathLen
* byte Path[PathLen]
*
* SDK reply payload:
* byte NumberOfEntries
* long ObjectID[20] (Hi-Lo)
* word TrusteeRights[20]
*
* Parser comparison: current parser and reply layout match
* the documented payload offsets. Rights are converted
* from mars_nwe trustee bits back to the NCP 22 mask before
* serialization.
*/
int sequence = (int)*(p+2); /* trustee sequence */
struct XDATA {
uint8 entries;
@@ -4331,7 +4399,23 @@ static int handle_ncp_serv(void)
}
break;
case 0x27 : { /* Add Ext Trustees to DIR or File */
case 0x27 : { /* Add Extended Trustee to Directory or File */
/*
* NCP 0x2222/22/39 Add Extended Trustee to Directory or
* File.
*
* SDK request payload after the group header:
* byte DirHandle
* long ObjectID (Hi-Lo)
* word TrusteeRights (Lo-Hi)
* byte PathLen
* byte Path[PathLen]
*
* Parser comparison: current parser matches the documented
* payload layout and converts the NCP 22 rights mask to the
* internal trustee-rights representation before calling the
* existing trustee backend.
*/
struct INPUT {
uint8 header[7]; /* Requestheader */
uint8 div[3]; /* 0x0, dlen, ufunc */
@@ -4370,7 +4454,28 @@ static int handle_ncp_serv(void)
}
break;
case 0x28 : { /* Scan File Physical ??? */
case 0x28 : { /* Scan Directory Disk Space */
/*
* NCP 0x2222/22/40 Scan Directory Disk Space.
*
* SDK request payload after the group header:
* byte DirectoryHandle
* byte SearchAttributes
* long Sequence (Lo-Hi)
* byte SearchPatternLen
* byte SearchPattern[SearchPatternLen]
*
* SDK reply is the extended disk-space scan entry, including
* Sequence, data/resource fork size, deleted-file fields,
* inherited rights, and namespace fork-size data.
*
* Parser comparison: current payload offsets match, but the
* Sequence is read with GET_BE32() while the SDK documents
* Lo-Hi. The current implementation delegates to
* nw_scan_a_directory(), returning the normal directory-scan
* structure rather than the full documented disk-space scan
* reply. Both differences are recorded in TODO.
*/
struct INPUT {
uint8 header[7]; /* Requestheader */
uint8 div[3]; /* 0x0, dlen, ufunc */
@@ -4410,6 +4515,9 @@ static int handle_ncp_serv(void)
* handle_after_bind() calls nw_get_vol_restrictions(). Without
* quota support, keep the SDK-compatible fallback local so builds
* on hosts without quota support do not need the quota backend.
*
* Parser comparison: request payload is VolumeNumber followed by
* ObjectID (Hi-Lo), matching the documented layout.
*/
case 0x29 : { /* Get Object Disk Usage And Restrictions */
#if QUOTA_SUPPORT