docs: clarify nested ncp selector paths
This commit is contained in:
1
AI.md
1
AI.md
@@ -70,6 +70,7 @@ patch against the last confirmed applied patch, not against the rejected file.
|
||||
- When an SDK/WebSDK/PDF endpoint number is written in decimal notation, convert it carefully to the wire `case` value before adding inline documentation. Example: Directory Services `0x2222/22/12` in the PDF means SubFunctionCode decimal 12, i.e. wire `case 0x0c`; it is not the existing `case 0x12` / decimal 18 Allocate Permanent Directory Handle. Place disabled stubs directly at the correct numeric slot inside the dispatcher, never appended at the end of the function. For implemented endpoints, keep the detailed documentation inside the relevant `case` block, immediately after the `case` label/opening brace, matching the local style; do not leave a large endpoint block before the `case` label.
|
||||
- If a PDF/WebSDK page title and an internal table row disagree, prefer the endpoint title plus include/WebSDK cross-checks and record the mismatch instead of inventing a new wire case. Example: `0x2222/23 Verify Serialization` is titled SDK decimal `23/12` / wire `0x0c`, even though one PDF table row prints `SubFunctionCode (212)`; do not add a wire `0xd4` case without a packet trace or include-level confirmation.
|
||||
- In `TODO.md` and endpoint summaries, avoid ambiguous mixed notation for grouped subfunctions. Write SDK/PDF numbers as decimal and include the wire byte explicitly when it differs or could be confused, for example `SDK 22/18 / wire 0x12` or `SDK 22/12 / wire 0x0c`. Do not write `22/12` for a wire `case 0x12` unless the SDK number is actually decimal 12.
|
||||
- Do not assume every `0x2222` endpoint key is only `request_type/function/subfunction`. Some SDK/PDF/WebSDK families have deeper selectors inside the subfunction payload, such as NDS `0x2222/104/02` with a 32-bit NDS `Verb`, statistical `0x2222/123/34` with `InfoLevelNumber`, NCP extension `0x2222/36`/`37` with dynamic extension numbers, or reply layouts selected by an information type. When auditing such a family, document the selector path explicitly, for example `0x2222/104/02 verb=<n>` or `0x2222/123/34 level=<n>`, and distinguish true wire dispatch bytes from payload fields that merely select a structure or backend operation.
|
||||
- Keep `TODO.md` endpoint audit notes grouped by endpoint family and NetWare generation instead of as one long flat list.
|
||||
- Before starting the next detailed endpoint block, maintain a coverage index for SDK/WebSDK-listed `0x2222` groups that are not yet audited. Classify each group as present in code but not audited, missing a top-level handler, or likely later-generation/unclear. This index is only a planning aid: do not add active TODO work or source stubs until the specific block has been checked for handoffs and bucketed by oldest documented NetWare generation.
|
||||
- Before every new endpoint-family patch, first do a missing-endpoint pass for that family: enumerate the SDK/PDF/WebSDK/include endpoint list, compare it against actual `case` labels and forwarded destination handlers, then document implemented, disabled-stub, and absent slots separately. Do this retroactively for already documented families when touching them again.
|
||||
|
||||
48
REDESIGN.md
48
REDESIGN.md
@@ -87,8 +87,15 @@ typedef struct {
|
||||
|
||||
uint16_t request_type; /* 0x2222, 0x3333, 0x5555, ... */
|
||||
uint8_t function; /* top-level NCP function */
|
||||
int has_subfunction;
|
||||
uint8_t subfunction; /* grouped calls such as 23/x, 32/x, 87/x */
|
||||
|
||||
/*
|
||||
* Some NCP families are only one level deep, but others are nested.
|
||||
* The selector path records the bytes/words that identify the logical
|
||||
* operation after the top-level function, without pretending that every
|
||||
* family has exactly one byte-sized subfunction.
|
||||
*/
|
||||
int selector_count;
|
||||
uint32_t selector[4]; /* e.g. subfunction, level, verb, info type */
|
||||
|
||||
const uint8_t *request;
|
||||
int request_len;
|
||||
@@ -110,11 +117,23 @@ become the preferred handler interface.
|
||||
|
||||
The useful property is that endpoint documentation can point to a stable model:
|
||||
|
||||
- `function` and `subfunction` identify the endpoint;
|
||||
- `function` identifies the first NCP selector byte;
|
||||
- `selector[]` identifies any nested selector path after that byte;
|
||||
- `request` and `request_len` are the bytes after the already-decoded envelope;
|
||||
- `reply` and `reply_len` are the bytes before the common NCP response envelope;
|
||||
- `completion` is set once by the handler or by central error handling.
|
||||
|
||||
Do not assume that the logical endpoint key always stops at
|
||||
`request_type/function/subfunction`. The Novell documentation has several
|
||||
families where an endpoint has another selector inside the subfunction payload.
|
||||
Examples include NDS fragmented requests (`0x2222/104/02`) where the request
|
||||
contains a 32-bit NDS verb, statistical calls such as `0x2222/123/34` where an
|
||||
`InfoLevelNumber` selects the returned structure, NCP extension calls where the
|
||||
extension number is dynamic, and reply formats that vary by information type.
|
||||
The audit notation for such cases should make the nesting explicit, for example
|
||||
`0x2222/104/02 verb=...` or `0x2222/123/34 level=2`, instead of flattening it
|
||||
into an invented one-byte `zz` case.
|
||||
|
||||
## Replace magic return values with named results
|
||||
|
||||
The current `0`, `-1`, and `-2` convention should be made explicit before any
|
||||
@@ -156,8 +175,9 @@ Conceptual form:
|
||||
typedef struct {
|
||||
uint16_t request_type;
|
||||
uint8_t function;
|
||||
int has_subfunction;
|
||||
uint8_t subfunction;
|
||||
int selector_count;
|
||||
uint32_t selector[4];
|
||||
const char *selector_note;
|
||||
const char *name;
|
||||
const char *provider;
|
||||
uint32_t flags;
|
||||
@@ -167,9 +187,13 @@ typedef struct {
|
||||
Example entries:
|
||||
|
||||
```c
|
||||
{ 0x2222, 23, 1, 109, "Change Queue Job Entry old", "nwbind/queue", NCPDOC_FORWARDED },
|
||||
{ 0x2222, 32, 1, 0, "Open Semaphore old", "sema", NCPDOC_LOCAL },
|
||||
{ 0x2222, 33, 0, 0, "Negotiate Buffer Size", "nwconn", NCPDOC_LOCAL },
|
||||
{ 0x2222, 23, 1, { 109 }, "subfunction", "Change Queue Job Entry old", "nwbind/queue", NCPDOC_FORWARDED },
|
||||
{ 0x2222, 32, 1, { 0 }, "subfunction", "Open Semaphore old", "sema", NCPDOC_LOCAL },
|
||||
{ 0x2222, 33, 0, { 0 }, NULL, "Negotiate Buffer Size", "nwconn", NCPDOC_LOCAL },
|
||||
|
||||
/* Later NetWare 4.x examples that need more than one logical selector. */
|
||||
{ 0x2222, 104, 2, { 2, 0 }, "subfunction + NDS verb", "Send NDS Fragmented Request/Reply", "nwnds", NCPDOC_FUTURE },
|
||||
{ 0x2222, 123, 2, { 34, 2 }, "subfunction + info level", "Get Volume Information by Level", "servermgmt", NCPDOC_FUTURE },
|
||||
```
|
||||
|
||||
This table would help with the ongoing endpoint audit:
|
||||
@@ -184,6 +208,14 @@ This table would help with the ongoing endpoint audit:
|
||||
The first version should not drive runtime dispatch. It should only make review
|
||||
and missing-endpoint checks less error-prone.
|
||||
|
||||
The table should be able to represent a selector path rather than only a single
|
||||
subfunction. This matters for later NetWare 4.x families and for extension
|
||||
mechanisms. The first selector element is usually the documented subfunction
|
||||
byte, but later elements may be 16-bit or 32-bit fields from the request body,
|
||||
not dispatch bytes in the classic switch sense. Treat them as layout selectors,
|
||||
not as automatic nested `switch` cases unless the code actually dispatches on
|
||||
them.
|
||||
|
||||
## Handler structure
|
||||
|
||||
For newly touched endpoint families, prefer the following logical split even if
|
||||
|
||||
Reference in New Issue
Block a user