KasperskyOS Community Edition 1.3

Using the base API (dcm_api.h)

Information about API functions is provided in the table below.

Dynamically creating an IPC channel on the server side

Dynamic creation of an IPC channel on the server side includes the following steps:

  1. Create a connect to DCM by calling the DcmInit() function.
  2. Publish the provided endpoints to DCM by using the DcmPublishEndpoint() function.

    In the serverHandle parameter of the DcmPublishEndpoint() function, specify the handle that identifies the server. The server-identifying handle can be the handle of this server process created by calling of the KosTaskGetSelf() and KosTaskGetHandle() functions from the task.h API in a sequence, or the handle created by calling the KnHandleCreateUserObject() function from the handle_api.h API. (When calling the KnHandleCreateUserObject() function, the rights parameter must specify the OCAP_HANDLE_TRANSFER and OCAP_HANDLE_GET_SID flags.) You can publish multiple endpoints by specifying the same or different handles that identify the server. (Clients can receive the descendants of these handles via the optional outServerHandle parameter of the DcmReadPubQueue() function.) After the endpoints are published, the handle identifying the server can be closed.

    A DcmPublishEndpoint() function call creates a DCM handle that enables receipt of client requests to create IPC channels to use a specific endpoint with a specific interface.

    To unpublish an endpoint, call the DcmCloseHandle() function to close the DCM handle that was created when the endpoint was published. If a server terminates, all of its published endpoints will also be unpublished.

  3. Receive a client request to create an IPC channel by calling the DcmListen() function.

    By calling the DcmListen() function with the same DCM handle in the pubHandle parameter, you can receive just those client requests that were sent to create IPC channels to use the endpoint with the interface that was defined when creating this DCM handle at step 2.

    You can use the optional outClientHandle and outClientName parameters of the DcmListen() function to get the handle identifying the client and the client name, respectively. (The handle identifying the client is the descendant of the handle specified in the clientHandle parameter of the DcmCreateConnection() function called on the client side.) This data can be used to make a decision on whether to accept or reject a client request. For example, the handle identifying the client may be used to get information about the client from other processes or to get the SID for this handle to compare it to other client-identifying handles available to the server. After making a decision, you can close the handle that identifies the client.

    A DcmListen() function call creates a DCM handle that enables acceptance or rejection of a client request to create an IPC channel.

  4. You can accept a client request to create an IPC channel by calling the DcmAccept() function.

    In the connectionId parameter of the DcmAccept() function, specify the DCM handle that was obtained at step 3.

    In the sessionHandle parameter of the DcmAccept() function, specify the callable handle to be passed to the client. To create a callable handle, call the KnHandleCreateUserObjectEx() function from the handle_api.h API. (When calling the KnHandleCreateUserObjectEx() function, the rights parameter must specify the OCAP_IPC_CALL and OCAP_HANDLE_TRANSFER flags, and the ipcChannel and riid parameters must specify the server IPC handle of the created IPC channel and the RIID, respectively. The server IPC handle is used to initialize IPC transport and manage IPC request processing on the server side. You can use the KnHandleCreateListener() function from the handle_api.h API to create a server handle. The endpoint ID (RIID) is a constant in the automatically generated transport code, for example: FsDriver_operationsComp_fileOperations_iid. After the client request is accepted, the callable handle can be closed.

    The transfer of a callable handle to a client can be associated with a resource transfer context object by specifying the handle of this object in the badgeHandle parameter of the DcmAccept() function. This will let you use the notice_api.h API to track the closing or revocation of descendants of the callable handle that form the handle inheritance subtree whose root node was generated when this callable handle was transferred to the client. (The transferred callable handle can be closed by the client, but this handle is also closed when the client terminates.) To create a resource transfer context object, call the KnHandleCreateBadge() function from the handle_api.h API.

    You can use the context parameter of the KnHandleCreateUserObjectEx() and KnHandleCreateBadge() functions to define the data to be associated with the callable handle and the transfer of the callable handle, respectively (similar to the user resource context and resource transfer context). The server will be able to receive the pointer to this data when dereferencing the callable handle. (Even though the callable handle is an IPC handle, the kernel puts it into the base_.self field of the constant part of an IPC request.)

    The same callable handle can be used to accept multiple requests from one or more clients.

    To reject a client request to create an IPC channel, call the DcmCloseHandle() function to close the DCM handle obtained at step 3. (In this case, a DcmConnect() function call on the client side terminates with an rcNotConnected error.) If a client request is accepted, the DCM handle obtained at step 3 must also be closed but only after calling the DcmAccept() function.

Dynamically creating an IPC channel on the client side

Dynamic creation of an IPC channel on the client side includes the following steps:

  1. Create a connect to DCM by calling the DcmInit() function.
  2. Create a DCM handle that enables receipt of a notification about publishing and unpublishing of endpoints with a specific interface.

    To complete this step, call the DcmSetSubscription() function.

    Use the optional parameters endpointName, serverName and serverHandle of the DcmSetSubscription() function to include notification filtering by qualified endpoint name, server name, and server-identifying handle, respectively. (The handle identifying the server is the descendant of the handle specified in the serverHandle parameter of the DcmPublishEndpoint() function called on the server side. One way for the client to get this handle is from another process.)

    The DcmSetSubscription() function call creates a DCM handle that enables receipt of notifications about the publishing and unpublishing of endpoints with a specific interface. It also generates a queue of notifications about the publication of endpoints that were published prior to the DcmSetSubscription() call and match the filter criteria. If you no longer need to receive notifications about publishing and unpublishing of endpoints with a specific interface, close this DCM handle by calling the DcmCloseHandle() function.

  3. You can extract a notification about endpoint publishing from the queue of these notifications by calling the DcmReadPubQueue() function.

    In the subscrHandle parameter of the DcmReadPubQueue() function, specify the DCM handle that was obtained at step 2.

    You can use the outServerHandle, outServerName and outEndpointName parameters of the DcmReadPubQueue() function to get the handle identifying the server, the server name, and the qualified name of the endpoint, respectively. (The handle identifying the server is the descendant of the handle specified in the serverHandle parameter of the DcmPublishEndpoint() function called on the server side.) This data can be used to decide whether to fulfill a request to create an IPC channel to the server. For example, the handle identifying the server may be used to get information about the server from other processes or to get the SID for this handle to compare it to other server-identifying handles available to the client.

    The value received via the outPubStatus parameter of the DcmReadPubQueue() function indicates that the endpoint was published or unpublished. A notification about endpoint unpublishing appears if the server unpublished this endpoint, or if the server terminated.

  4. Create a DCM handle that enables fulfillment of a request to create an IPC channel to the server.

    To complete this step, call the DcmCreateConnection() function.

    In the serverHandle parameter of the DcmCreateConnection() function, specify the handle that identifies the server. This handle can be obtained at step 3 via the outServerHandle parameter of the DcmReadPubQueue() function or by other means, such as from another process.

    In the clientHandle parameter of the DcmCreateConnection() function, specify the handle that identifies the client. This client-identifying handle can be the handle of the client process created by calling of the KosTaskGetSelf() and KosTaskGetHandle() functions from the task.h API in a sequence, or the handle created by calling the KnHandleCreateUserObject() function from the handle_api.h API. (When calling the KnHandleCreateUserObject() function, the rights parameter must specify the OCAP_HANDLE_TRANSFER and OCAP_HANDLE_GET_SID flags.) You can create multiple DCM handles that enable fulfillment of a request to create an IPC channel by specifying the same or different handles identifying the client in the clientHandle parameter of the DcmCreateConnection() function. (Servers can receive the descendants of these handles via the optional outClientHandle parameter of the DcmListen() function.) After creating a DCM handle that enables fulfillment of a request to create an IPC channel, the handle identifying the client can be closed.

    A DcmCreateConnection() function call creates a DCM handle that enables completion of a request to create an IPC channel to the server to use a specific endpoint with a specific interface.

  5. Complete a request to create an IPC channel to the server by calling the DcmConnect() function.

    In the connectionId parameter, specify the DCM handle obtained at step 4.

    After the DcmConnect() function is called, the client receives a callable handle via the outSessionHandle parameter. The client uses this handle to initialize IPC transport. In addition, the client specifies the INVALID_RIID value as the Runtime Implementation Identifier (RIID) in the proxy object initialization function.

    After receiving a callable handle, the DCM handle obtained at step 4 must be closed by calling the DcmCloseHandle() function.

Interrupting blocking function calls

To interrupt a blocking call of the DcmConnect(), DcmReadPubQueue() or DcmListen() function from another thread, call the DcmInterruptBlockingCall() function.

Using notifications

You can use the DcmSubscribeToEvents() and DcmUnsubscribeFromEvents() functions together with functions from the notice_api.h API to receive notifications about the occurrence of the following events: the server published or depublished an endpoint in DCM (the DCM_PUBLICATION_CHANGED flag), the server received a request from the client to create an IPC channel (the DCM_CLIENT_CONNECTED flag), a blocking call of the DcmConnect(), DcmReadPubQueue() or DcmListen() function was interrupted (the DCM_BLOCKING_CALL_INTERRUPTED flag), or the server received or rejected a client request to create an IPC channel (the DCM_CLIENT_RELEASED_BY_SERVER flag). (Flags of the event mask and the "resource–event mask" entry ID DCM_EVENT_ID are defined in the header file sysroot-*-kos/include/dcm/dcm_api.h from the KasperskyOS SDK.) The DcmSubscribeToEvents() and DcmUnsubscribeFromEvents() functions let you configure the notification receiver by adding or deleting, respectively, tracked objects identified by DCM handles.

Deleting dynamically created IPC channels

A dynamically created IPC channel will be deleted when closing the callable handle and server IPC handle of this IPC channel.

Deleting a DCM connection

If you no longer need to use DCM, you need to call the DcmFini() function to delete the connection to DCM and thereby free up the resources linked to this connection.

Information about API functions

dcm_api.h functions

Function

Information about the function

DcmInit()

Purpose

Creates a connection to DCM.

Parameters

N/A

Returned values

If successful, the function returns rcOk, otherwise it returns an error code.

If there is no IPC channel to DCM, the function returns rcNoCapability.

Additional information

Thread-safe function.

Non-blocking call.

DcmFini()

Purpose

Deletes a connection to DCM.

Parameters

N/A

Returned values

N/A

Additional information

Thread-safe function.

Non-blocking call.

DcmSubscribeToEvents()

Purpose

Configures the notification receiver to receive notifications about events related to the object identified by the defined DCM handle.

Parameters

  • [in] notice – identifier of the notification receiver.
  • [in] handle – DCM handle that was received by calling the DcmSetSubscription(), DcmCreateConnection() or DcmPublishEndpoint() function.

Returned values

If successful, the function returns rcOk, otherwise it returns an error code.

DcmUnsubscribeFromEvents()

Purpose

Configures the notification receiver to not receive notifications about events related to the object identified by the defined DCM handle.

Parameters

  • [in] notice – identifier of the notification receiver.
  • [in] handle – DCM handle that was received by calling the DcmSetSubscription(), DcmCreateConnection() or DcmPublishEndpoint() function.

Returned values

If successful, the function returns rcOk, otherwise it returns an error code.

DcmCloseHandle()

Purpose

Closes the DCM handle obtained by calling the DcmSetSubscription(), DcmCreateConnection(), DcmPublishEndpoint() or DcmListen() function from the main API, and DcmListenGroupPub() from the additional API for servers.

Parameters

  • [in] handle – DCM handle.

Returned values

If successful, the function returns rcOk, otherwise it returns an error code.

DcmInterruptBlockingCall()

Purpose

Interrupts a blocking call of the DcmConnect(), DcmReadPubQueue() or DcmListen() function.

Parameters

  • [in] handle – DCM handle specified when calling the DcmConnect(), DcmReadPubQueue() or DcmListen() function.

Returned values

If successful, the function returns rcOk, otherwise it returns an error code.

DcmSetSubscription()

Purpose

Creates a DCM handle that enables receipt of a notification about publishing and unpublishing of endpoints with a specific interface.

Parameters

  • [in] endpointType – pointer to the name of the interface of endpoints.
  • [in,optional] endpointName – pointer to the qualified name of the endpoint, or RTL_NULL to not use notification filtering based on the qualified name of the endpoint.
  • [in,optional] serverName – pointer to the server name, or RTL_NULL to not use notification filtering based on the server name.
  • [in,optional] serverHandle – handle identifying the server, or INVALID_HANDLE to not use notification filtering based on a specific server.
  • [out] outSubscrHandle – pointer to the DCM handle that enables receipt of notifications about the publishing and unpublishing of endpoints with a specific interface.

Returned values

If successful, the function returns rcOk, otherwise it returns an error code.

DcmReadPubQueue()

Purpose

Extracts a notification about the publishing and unpublishing of an endpoint from the notification queue.

Parameters

  • [in] subscrHandle – DCM handle created by calling the DcmSetSubscription() function.
  • [in] msec – time-out before notifications appearing in milliseconds, or INFINITE_TIMEOUT to set an unlimited time-out.
  • [out,optional] outServerHandle – pointer to the handle identifying the server, or RTL_NULL if this handle is not required.
  • [out,optional] outServerName – pointer to the buffer for the server name, or RTL_NULL if this name is not required.
  • [in] serverNameSize – size (bytes) for the server name, or 0 if this name is not required.
  • [out,optional] outEndpointName – pointer to the buffer for the qualified name of the endpoint, or RTL_NULL if this name is not required.
  • [in] endpointNameSize – size (bytes) of the buffer for the qualified name of the endpoint, or 0 if this name is not required.
  • [out] outPubStatus – pointer to the value indicating that the endpoint was published (DcmEndpointPublished) or unpublished (DcmEndpointUnpublished).

Returned values

If successful, the function returns rcOk, otherwise it returns an error code.

If a blocking call was interrupted by calling the DcmInterruptBlockingCall() function, rcAbort is returned.

Additional information

Non-blocking call if the msec parameter is set to 0.

DcmCreateConnection()

Purpose

Creates a DCM handle that enables fulfillment of a request to create an IPC channel to the server to use a specific endpoint with a specific interface.

Parameters

  • [in] endpointType – pointer to the name of the endpoint interface.
  • [in] endpointName – pointer to the qualified name of the endpoint.
  • [in] serverHandle – handle that identifies the server.
  • [in] clientHandle – handle that identifies the client.
  • [out] outConnectionId – pointer to the DCM handle that enables fulfillment of a request to create an IPC channel to the server to use a specific endpoint with a specific interface.

Returned values

If successful, the function returns rcOk, otherwise it returns an error code.

DcmConnect()

Purpose

Fulfills a request to create an IPC channel with a server.

Parameters

  • [in] connectionId – DCM handle created by calling the DcmCreateConnection() function.
  • [in] msec – timeout (in milliseconds) for fulfilling a request, or INFINITE_TIMEOUT to define an unlimited timeout.
  • [out] outSessionHandle – pointer to the callable handle.

Returned values

If successful, the function returns rcOk, otherwise it returns an error code.

If the msec parameter is set to 0 and the server did not handle the request to create an IPC channel, the function returns rcNotReady.

If a blocking call was interrupted by calling the DcmInterruptBlockingCall() function, rcAbort is returned.

Additional information

Non-blocking call if the msec parameter is set to 0.

DcmPublishEndpoint()

Purpose

Publishes the endpoint to DCM.

Parameters

  • [in] endpointType – pointer to the name of the endpoint interface.
  • [in] endpointName – pointer to the qualified name of the endpoint.
  • [in] serverHandle – handle that identifies the server.
  • [out] outPubHandle – pointer to the DCM handle that enables receipt of client requests to create IPC channels to use a specific endpoint with a specific interface.

Returned values

If successful, the function returns rcOk, otherwise it returns an error code.

DcmListen()

Purpose

Receives a client request to create an IPC channel

Parameters

  • [in] pubHandle – DCM handle created by calling the DcmPublishEndpoint() function.
  • [in] msec – timeout (in milliseconds) for the appearance of a client request, or INFINITE_TIMEOUT to define an unlimited timeout.
  • [out] outConnectionId – pointer to the DCM handle that enables you to accept or reject a client request to create an IPC channel.
  • [out,optional] outClientHandle – pointer to the handle identifying the client, or RTL_NULL if this handle is not required.
  • [out,optional] outClientName – pointer to the buffer for the client name, or RTL_NULL if this name is not required.
  • [in] clientNameSize – size (bytes) of the buffer for the client name, or 0 if this name is not required.

Returned values

If successful, the function returns rcOk, otherwise it returns an error code.

If a blocking call was interrupted by calling the DcmInterruptBlockingCall() function, rcAbort is returned.

Additional information

Non-blocking call if the msec parameter is set to 0.

DcmAccept()

Purpose

Accepts a client request to create an IPC channel.

Parameters

  • [in] connectionId – DCM handle obtained by calling the DcmListen() function.
  • [in] sessionHandle – callable handle for the client.
  • [in,optional] badgeHandle – handle of the resource transfer context object, or INVALID_HANDLE if you do not need to associate the transfer of a callable handle with this object.

Returned values

If successful, the function returns rcOk, otherwise it returns an error code.