docs: document semaphore endpoint layouts

This commit is contained in:
Mario Fetka
2026-06-02 05:25:25 +00:00
parent c77950f5d1
commit bfcb2e178f
2 changed files with 99 additions and 3 deletions

37
TODO.md
View File

@@ -179,9 +179,6 @@ Present in the code but not yet fully endpoint-audited:
- SDK `0x2222/26` through `0x2222/31` / wire `0x1a` through `0x1f` physical
record synchronization calls are implemented in `src/nwconn.c` but have not
yet received the detailed request-layout audit.
- SDK `0x2222/32` / wire `0x20` Semaphore is forwarded to `src/nwbind.c`; the
handoff is noted, but the semaphore subfunctions still need a per-subfunction
request/reply audit.
- SDK `0x2222/33` / wire `0x21` Negotiate Buffer Size and SDK `0x2222/34` /
wire `0x22` TTS calls are present in `src/nwconn.c`; their layouts still need
source comparisons.
@@ -491,6 +488,40 @@ Follow-up:
items. Continue with the next non-4.x/OES-only group after this block.
#### Semaphore group 0x2222/32
Current status:
- Direct `NCP 0x2222/32` / wire `0x20` is forwarded unchanged from
`src/nwconn.c` to `src/nwbind.c`, which passes `requestdata[0]` as the
semaphore subfunction and `requestdata[1..]` to `handle_func_0x20()` in
`src/sema.c`.
- The NetWare 2.x/3.x-compatible old semaphore subfunctions are now documented
at their real parser/reply site in `src/sema.c`:
- SDK `32/00` / wire subfunction `0x00` Open Semaphore (old)
- SDK `32/01` / wire subfunction `0x01` Examine Semaphore (old)
- SDK `32/02` / wire subfunction `0x02` Wait On Semaphore (old)
- SDK `32/03` / wire subfunction `0x03` Signal Semaphore (old)
- SDK `32/04` / wire subfunction `0x04` Close Semaphore (old)
- Request and response payloads were compared against the NDK/Core Protocols
PDF, the extracted WebSDK semaphore pages, and `nwsync.h`. The old `32/00`
through `32/04` operations line up with the currently implemented operation
set.
Known differences / follow-up:
- The PDF/WebSDK tables label `SemaphoreHandle` as long Lo-Hi. The current
`src/sema.c` implementation parses and emits semaphore handles with
`GET_BE32()` / `U32_TO_BE32()` while parsing `SemaphoreTimeOut` as Hi-Lo with
`GET_BE16()`. Keep this documented as a compatibility detail until packet
traces or client tests prove the expected wire order for MARS-NWE clients.
- `Wait On Semaphore` currently does not sleep until `SemaphoreTimeOut`; the
simple emulator returns timeout immediately when the semaphore value is not
available.
- Newer SDK `0x2222/111` semaphore calls are the modern paired variants and are
not routed through this compatibility handler.
#### File Server Environment group 0x2222/23
Current status:

View File

@@ -171,8 +171,36 @@ int handle_func_0x20(CONNECTION *c, uint8 *p, int ufunc, uint8 *responsedata)
{
int result = -0xfb; /* unknown request */
XDPRINTF((3, 0, "0x20 call ufunc=0x%x", ufunc));
/*
* Direct NCP 0x2222/32 Semaphore group. nwconn.c forwards this
* group unchanged: requestdata[0] is SubFunctionCode and p points
* at requestdata[1], the subfunction payload.
*
* The uploaded NDK/Core Protocols PDF and WebSDK list the old
* NetWare 2.x/3.x-compatible semaphore subfunctions as SDK
* 32/00 through 32/04. The newer SDK 111 semaphore variants have
* the same semantic operations but are not routed here.
*
* Note the current wire-order compatibility detail before changing
* this code: the PDF tables label SemaphoreHandle as long Lo-Hi,
* while this handler currently reads and writes handles with the
* big-endian helpers GET_BE32()/U32_TO_BE32(). TimeOut remains
* documented and parsed Hi-Lo with GET_BE16().
*/
switch (ufunc) {
case 0x0 : { /* open semaphore */
/*
* SDK 32/00 / wire subfunction 0x00 Open Semaphore
* (old).
* Request payload after SubFunctionCode:
* byte InitialSemaphoreValue
* byte SemaphoreNameLen
* byte SemaphoreName[SemaphoreNameLen]
* Reply data:
* dword SemaphoreHandle (currently emitted with
* U32_TO_BE32(), see group note above)
* byte SemaphoreOpenCount
*/
int value = *p;
int namlen = *(p+1);
uint8 *name = (p+2);
@@ -204,6 +232,16 @@ int handle_func_0x20(CONNECTION *c, uint8 *p, int ufunc, uint8 *responsedata)
break;
case 0x1 : { /* examine semaphore */
/*
* SDK 32/01 / wire subfunction 0x01 Examine Semaphore
* (old).
* Request payload after SubFunctionCode:
* dword SemaphoreHandle (currently parsed with
* GET_BE32(), see group note above)
* Reply data:
* byte SemaphoreValue
* byte SemaphoreOpenCount
*/
int handle = GET_BE32(p);
struct XDATA {
char value;
@@ -224,6 +262,17 @@ int handle_func_0x20(CONNECTION *c, uint8 *p, int ufunc, uint8 *responsedata)
case 0x2 : { /* wait on semaphore */
/*
* SDK 32/02 / wire subfunction 0x02 Wait On Semaphore
* (old).
* Request payload after SubFunctionCode:
* dword SemaphoreHandle (currently parsed with
* GET_BE32(), see group note above)
* word SemaphoreTimeOut (Hi-Lo)
* Reply: no data. Completion reports success, timeout,
* or lock error. The simple local emulator does not
* sleep; unavailable semaphores return timeout at once.
*/
int handle = GET_BE32(p);
int timeout = GET_BE16(p+4);
result=wait_sema(handle, timeout);
@@ -233,6 +282,14 @@ int handle_func_0x20(CONNECTION *c, uint8 *p, int ufunc, uint8 *responsedata)
break;
case 0x3 : { /* signal sema */
/*
* SDK 32/03 / wire subfunction 0x03 Signal Semaphore
* (old).
* Request payload after SubFunctionCode:
* dword SemaphoreHandle (currently parsed with
* GET_BE32(), see group note above)
* Reply: no data.
*/
int handle = GET_BE32(p);
result=signal_sema(handle);
XDPRINTF((2, 0, "signal_sem:%d, result=%d",
@@ -242,6 +299,14 @@ int handle_func_0x20(CONNECTION *c, uint8 *p, int ufunc, uint8 *responsedata)
case 0x4 : { /* close semaphore */
/*
* SDK 32/04 / wire subfunction 0x04 Close Semaphore
* (old).
* Request payload after SubFunctionCode:
* dword SemaphoreHandle (currently parsed with
* GET_BE32(), see group note above)
* Reply: no data.
*/
int handle = GET_BE32(p);
result=close_conn_sema(c, handle);
if (!result)