Contains all the configuration information needed to run the service. It must be initialized before installation so that the kernel can configure the internal resources ready for use.
This structure:
All fields up to LocalAddress must be initialized. The LocalAddress field may be initialized later if required using SetRtServiceAttributes. To use any service-dependent fields, you must define those fields as part of the service_info field and initialize as required, and the value of the wExtraSize field must be initialized correctly.
The header file includes special cases of this structure for interrupt, polled, and port services.
typedef struct tagServiceDesc {
char cName[14];
WORD wServiceFlags;
WORD wPortCreationMask;
WORD wAddressSize;
WORD wControlMessageSize;
WORD wMaxTransactionBuffers;
WORD wMaxControlBuffers;
WORD wPortTableSize;
WORD wNullPortID;
WORD wFirstValidPortID;
WORD wLastValidPortID;
WORD wFirstAllocPortID;
WORD wLastAllocPortID;
LPPROC pInitialize; WORD _reserved_1;
LPPROC pGetAttributes; WORD _reserved_2;
LPPROC pSetAttributes; WORD _reserved_3;
LPPROC pCreatePort; WORD _reserved_4;
LPPROC pDeletePort; WORD _reserved_5;
LPPROC pVerifyAddress; WORD _reserved_6;
LPPROC pSendMessage; WORD _reserved_7;
LPPROC pGetFragment; WORD _reserved_8;
LPPROC pCancelTransaction; WORD _reserved_9;
LPPROC pUpdateReceiveInfo; WORD _reserved_10;
LPPROC pFinish; WORD _reserved_11;
LPPROC pService; WORD _reserved_12;
DWORD dwServiceThreadStackSize; WORD _reserved_13;
RTHANDLE hServiceObject;
GENADDR LocalAddress;
LPVOID _reserved_14[14];
WORD wExtraSize;
} SERVICEDESC, *LPSERVICEDESC;
cName
wServiceFlags
You can use these masks:
FL_SHORT_CIRCUIT_ONLYFL_GENERIC_TYPE |
The kernel does no extra actions to support the service being developed. The developer is responsible for creating the service thread and interface object. |
FL_INTERRUPT_TYPE |
The kernel creates an interrupt task using the extra fields in the INTERRUPTSERVICEDESC structure. These fields allow the kernel to create a default interrupt handler and thread. The thread calls the user's service handler when the interrupt handler signals the thread. |
FL_POLLED_TYPE |
The kernel creates a kernel alarm event and a default service thread. When the alarm event is signaled the service thread calls the user's service handler. The kernel uses the extra fields in the ALARMSERVICEDESC structure to create the alarm event and service thread. |
FL_PORT_TYPE |
The kernel creates a port object using the extra fields in the PORTSERVICEDESC structure. It also creates a service thread which calls ReceiveRtMessage on the port. Whenever a message arrives the service thread calls the user's service handler.
If the FL_LATE_INIT bit is set, the service will not call the Initialize handler until the first time CreateRtPort is called for this service. If the bit is clear then the Initialize handler is called during the call to InstallRtServiceDescriptor. If the FL_ALLOW_RSVP bit is set, the call SendRtMessageRSVP is allowed. If the bit is clear, any such call will fail with a status of E_NOT_CONFIGURED. The FL_ALLOW_FRAGMENTS bit controls access to ReceiveRtFragment. If the bit is clear, any such call for this service results in a failure status of E_NOT_CONFIGURED. If the FL_ADDRESSED bit is set, the service expects to process address fields. If it is clear, and attempt is made to the system call ConnectRtPort, it will fail; field checking on the address field in other calls is ignored. If the bit is set, and no address field is passed to any of the send message calls they will fail. The FL_ALLOW_SHORT_CIRCUIT and FL_SHORT_CIRCUIT_ONLY bits are reserved for future use, and will control system support for automatic short-circuit delivery of messages. |
wPortCreationMask
wAddressSize
wControlMessageSize
The kernel uses this value for validation purposes and for allocating the control message pool.
wMaxTransactionBuffers
wMaxControlBuffers
wPortTableSize
wNullPortID, wFirstValidPortID, wLastValidPortID, wFirstAllocPortID, wLastAllocPortID
If the port ID is in the range wFirstValidID ≤ port ID ≤ wLastValidID and the entry in the port table for that ID is empty, then the port is created with that ID. If the entry is not empty the creation fails with status E_PORT_ID_USED.
If the port ID matches the value in wNullPortID the kernel allocates the next free value in the range wFirstAllocPortID ≤ port ID ≤ wLastAllocPortID. If there is not a value available the creation fails with status E_LIMIT.
If the port ID is any other value, then the creation fails with status E_PARAM.
If it is desired to disable the auto-allocation of port IDs then make sure that the wNullPortID value falls within the valid port ID range.
If it is desired to only have the auto-allocation of port IDs then set the value of wFirstValidPortID to be greater than wLastValidPortID. In this case the user must always supply the value of wNullPortID when creating a port.
pInitialize, pGetAttributes, pSetAttributes, pCreatePort, pDeletePort, pVerifyAddress, pSendMessage, pGetFragment, pCancelTransaction, pUpdateReceiveInfo, pFinish, and pService
Service handlers that correspond to these fields include:
pInitialize |
Initialize |
pGetAttributes |
GetAttributes |
pSetAttributes |
SetAttributes |
pCreatePort |
CreatePort |
pDeletePort |
DeletePort |
pVerifyAddress |
VerifyAddress |
pSendMessage |
SendMessage |
pGetFragment |
GetFragment |
pCancelTransaction |
CancelTransaction |
pUpdateReceiveInfo |
UpdateReceiveInfo |
pFinish |
Finish |
pService |
Service |
dwServiceThreadStackSize
hServiceObject
LocalAddress
wExtraSize
SetRtServiceAttributes, SetAttributes, GetAttributes, InstallRtServiceDescriptor, CreatePort, CreateRtPort, DeletePort ReceiveRtMessage, Initialize, SendRtMessageRSVP, SendMessage, ReceiveRtFragment, GetFragment, VerifyAddress, CancelTransaction, UpdateReceiveInfo, Finish, Service