Programming reference

For function summaries, see:

AppendVdHeader (Deprecated)

Note:

This function is deprecated. QueueVirtualWrite must be used in all new virtual drivers.

Places an ICA virtual channel prefix on the output buffer prior to assembling and sending the buffer.

Calling convention


INT WFCAPI AppendVdHeader (
    PWD pWd,
    USHORT Channel,
    USHORT ByteCount);

<!--NeedCopy-->

Parameters

pWD

Pointer to a WinStation driver control structure.

Channel

Virtual channel number.

ByteCount

Actual size in bytes of the virtual channel packet data to be sent. Do not include additional bytes reservered for the buffer overhead.

Return values

If the function succeeds, the return value is CLIENT_STATUS_SUCCESS.

If the function fails, the return value is the error code associated with the failure; use GetLastError to get the extended error information.

Remarks

Call this function to prefix the virtual channel packet with the appropriate header information. Normally the virtual driver sees only the private packet data. However, when a virtual driver sends a virtual channel packet to a server application, it must use this function to prefix the data with the ICA header.

Use OutBufReserve to reserve a buffer prior to making this call. The virtual driver must use this function immediately after a successful OutBufReserve and before any other data is placed in the packet. This action uses the additional four bytes requested in OutBufReserve, so do not include this overhead in ByteCount.

If an ICA header or virtual channel data is appended to the buffer, the buffer must be sent to the server before the control leaves the virtual driver.

A pointer to this function is obtained from the VDWRITEHOOK structure after hook registration in DriverOpen. The VDWRITEHOOK structure also provides pWd.

DriverClose

The WinStation driver calls this function prior to unloading the virtual driver, when the ICA connection is being terminated.

Calling convention


INT Driverclose(
    PVD pVD,
    PDLLCLOSE pVdClose,
    PUINT16 puiSize);

<!--NeedCopy-->

Parameters

pVD

Pointer to a virtual driver control structure.

pVdClose

Pointer to a standard driver close information structure.

puiSize

Pointer to the size of the driver close information structure. This is an input parameter.

Return values

If the function succeeds the return value is CLIENT_STATUS_SUCCESS.

If the function fails, the return value is the CLIENT_ERROR_* value corresponding to the error condition; see clterr.h (in src/inc/) for a list of error values beginning with CLIENT_ERROR.

Remarks

When DriverClose is called, all private driver data is freed. The virtual driver does not need to deallocate the virtual channel or write hooks.

The pVdClose structure currently contains one element – NotUsed. This structure can be ignored.

DriverGetLastError

This function is not used but is available for linking with the common front end, VDAPI.

Calling convention


INT DriverGetLastError(
    PVD pVD,
    PVDLASSTERROR pVdLastError);

<!--NeedCopy-->

Parameters

pVD

Pointer to a virtual driver control structure.

pVdLastError

Pointer to a structure that receives the last error information.

Return Value

The driver returns CLIENT_STATUS_SUCCESS.

Remarks

This function currently has no practical significance for virtual drivers; it is provided for compatibility with the loadable module interface.

DriverInfo

Gets information about the virtual driver, such as the version level of the driver.

Calling convention


INT DriverInfo(
    PVD pVD,
    PDLLINFO pVdInfo,
    PUINT16 puiSize);

<!--NeedCopy-->

Parameters

pVD

Pointer to a virtual driver control structure.

pVdInfo

Pointer to a standard driver information structure.

puiSize

Pointer to the size of the driver information structure. This is an output parameter.

Return value

If the function succeeds, it returns CLIENT_STATUS_SUCCESS.

If the function fails because the buffer pointed to by pVdInfo is too small, it returns CLIENT_ERROR_BUFFER_TOO_SMALL. Normally, when a CLIENT_ERROR_* result code is returned, the ICA session is disconnected. CLIENT_ERROR_BUFFER_TOO_SMALL is an exception and does not result in the ICA session being disconnected. Instead, the WinStation driver attempts to call DriverInfo again with the ByteCount of pVdInfo returned by the failed call.

Remarks

When the client starts, it calls this function to retrieve module-specific information for transmission to the host. This information is returned to the server side of the virtual channel by WFVirtualChannelQuery.

The virtual driver must support this call by returning a structure in the pVdInfo buffer. This structure can be a developer-defined virtual channel-specific structure, but it must begin with a VD_C2H structure, which in turn begins with a MODULE_C2H structure. All fields of the VD_C2H structure must be filled in except for the ChannelMask field. See ica-c2h.h (in src/inc/) for definitions of these structures.

The virtual driver must first check the size of the information buffer given against the size that the virtual driver requires (the VD_C2H structure). The size of the input buffer is given in pVdInfo->ByteCount.

If the buffer is too small to store the information that the driver needs to send, the correct size is filled into the ByteCount field and the driver returns CLIENT_ERROR_BUFFER_TOO_SMALL.

If the buffer is large enough, the driver must fill it with a module-defined structure. At a minimum, this structure must contain a VD_C2H structure. The VD_C2H structure must be the first data in the buffer; additional channel-specific data can follow. All relevant fields of this structure are filled in by this function. The flow control method is specified in the VDFLOW structure (an element of the VD_C2H structure). The Ping example contains a flow control selection.

The WinStation driver calls this function twice at initialization, after calling DriverOpen. The first call contains a NULL information buffer and a buffer size of zero. The driver is expected to fill in pVdInfo->ByteCount with the required buffer size and return CLIENT_ERROR_BUFFER_TOO_SMALL. The WinStation driver allocates a buffer of that size and retries the operation.

The data buffer pointed to by pVdinfo->pBuffer must not be changed by the virtual driver. The WinStation driver stores byte swap information in this buffer.

The parameter puiSize must be initialized to the size of the driver information structure.

DriverOpen

Initializes the virtual driver. The client engine calls this user-written function once when the client is loaded.

Calling convention


INT DriverOpen(
    PVD pVD, PVDOPEN pVdOpen)
    PUINT16 puiSize);

<!--NeedCopy-->

Parameters

pVD

Pointer to the virtual driver control structure. This pointer is passed on every call to the virtual driver.

pVdOpen

Pointer to the virtual driver Open structure.

puiSize

Pointer to the size of the virtual driver Open structure. This is an output parameter.

Return values

If the function succeeds, it returns CLIENT_STATUS_SUCCESS.

If the function fails, it returns the CLIENT_ERROR_* value corresponding to the error condition; see clterr.h (in src/inc/) for a list of error values beginning with CLIENT_ERROR

Remarks

The code fragments in this section are taken from the vdping example.

The DriverOpen function must:

1. Allocate a virtual channel.

Fill in a WDQUERYINFORMATION structure and call VdCallWd. The WinStation driver fills in the OpenVirtualChannel structure (including the channel number) and the data in pVd.


WDQUERYINFORMATION wdqi;
OPENVIRTUALCHANNEL OpenVirtualChannel;
UINT16 uiSize;
wdqi.WdInformationClass = WdOpenVirtualChannel;
wdqi.pWdInformation = &OpenVirtualChannel;
wdqi.WdInformationLength = sizeof(OPENVIRTUALCHANNEL);
OpenVirtualChannel.pVCName = CTXPING_VIRTUAL_CHANNEL_NAME;
uiSize = sizeof(WDQUERYINFORMATION);
rc = VdCallWd(pVd, WDxQUERYINFORMATION, &wdqi, &uiSize);
/* do error processing here */

<!--NeedCopy-->

After the call to VdCallWd, the channel number is assigned in the OpenVirtualChannel structure’s Channel element. Save the channel number and set the channel mask to indicate which channel this driver will handle.

For example:


g_usVirtualChannelNum = OpenVirtualChannel.Channel;
pVdOpen->ChannelMask = (1L << g_usVirtualChannelNum);

<!--NeedCopy-->

2. Optionally specify a pointer to a private data structure.

If you want the virtual driver to allocate memory for state data, it can have a pointer to this data returned on each call by placing the pointer in the virtual driver structure, as follows:


pVd->pPrivate = pMyStructure;

<!--NeedCopy-->

3. Exchange entry point data with the WinStation driver.

The virtual driver must register a write hook with the client WinStation driver. The write hook is the entry point of the virtual driver to be called when data is received for this virtual channel. The WinStation driver returns pointers to functions that the driver must use to fill in output buffers and sends data to the WinStation driver for transmission to the server.


WDSETINFORMATION wdsi; VDWRITEHOOK vdwh;
// Fill in a write hook structure
vdwh.Type = g_usVirtualChannelNum; vdwh.pVdData = pVd;
vdwh.pProc = (PVDWRITEPROCEDURE) ICADataArrival;
// Fill in a set information structure
wdsi.WdInformationClass = WdVirtualWriteHook;
wdsi.pWdInformation = &vdwh;
wdsi.WdInformationLength = sizeof(VDWRITEHOOK);
uiSize = sizeof(WDSETINFORMATION);
rc = VdCallWd( pVd, WDxSETINFORMATION, &wdsi, &uiSize);
/* do error processing here */

<!--NeedCopy-->

During the registration of the write hook, the WinStation driver passes entry points for the deprecated output buffer virtual driver helper functions to the virtual driver in the VDWRITEHOOK structure. The DriverOpen function saves these in global variables so helper functions in the virtual driver can use them. The WinStation driver also passes a pointer to the WinStation driver data area, which the DriverOpen function also saves (because it is the first argument to the virtual driver helper functions).


// Record pointers to functions used
// for sending data to the host.
pWd = vdwh.pWdData;
pOutBufReserve = vdwh.pOutBufReserveProc;
pOutBufAppend = vdwh.pOutBufAppenProc;
pOutBufWrite = vdwh.pOutBufWriteProc;
pAppendVdHeader = vdwh.pAppendVdHeaderProc;

<!--NeedCopy-->

4. Allocate all memory needed by the driver and do any initialization. You can obtain the maximum ICA buffer size from the MaximumWriteSize element in the VDWRITEHOOK structure that is returned.

Note:

vdwh.MaximumWriteSize is one byte greater than the actual maximum that you can use because it also includes the channel number.


g_usMaxDataSize = vdwh.MaxiumWriteSize - 1;
if(NULL == (pMyData = malloc( g_usMaxDataSize )))
{
    return(CLIENT_ERROR_NO_MEMORY);
}

<!--NeedCopy-->

5. Return the size of the VDOPEN structure in puiSize. This is used by the client engine to determine the version of the virtual channel driver.

DriverPoll

Allows the virtual driver to get periodic control to perform any action as required. With the Evt_* and Tmr_* APIs, a more event driven implementation is possible so you may find that the DriverPoll is empty.

Calling convention


INT DriverPoll(
PVD pVD,
PVOID pVdPoll,
PUINT16 puiSize);

<!--NeedCopy-->

Parameters

pVD

Pointer to a virtual driver control structure.

pVdPoll

Pointer to one of the driver poll information structures (DLLPOLL).

puiSize

Pointer to the size of the driver poll information structure. This is an output parameter.

Return values

If the functionsucceeds, it returns CLIENT_STATUS_SUCCESS. If the driver has no data on this polling pass, it returns CLIENT_STATUS_NO_DATA.

If the virtual driver cannot allocate an output buffer, it returns CLIENT_STATUS_ERROR_RETRY so the WinStation driver does not slow polling. The virtual driver then attempts to get an output buffer the next time it is polled.

Return values that begin with CLIENT_ERROR_ are fatal errors; the ICA session is disconnected.

Remarks

Because the client engine is single threaded, a virtual driver is not allowed to block while waiting for a desired result (such as the availability of an output buffer) because this prevents the rest of the client from processing.

The Ping example includes examples of processing that can occur in DriverPoll.

DriverQueryInformation

Gets run-time information from the virtual driver.

Calling convention


INT DriverQueryInformation(
PVD pVD,
PVDQUERYINFORMATION pVdQueryInformation,
PUINT16 puiSize);

<!--NeedCopy-->

Parameters

pVD

Pointer to a virtual driver control structure.

pVdQueryInformation

Pointer to a structure that specifies the information to query and the results buffer.

puiSize

Pointer to the size of the query information and resolves structure. This is an output parameter.

Return value

The function returns CLIENT_STATUS_SUCCESS.

Remarks

This function currently has no practical significance for virtual drivers; it is provided for compatibility with the loadable module interface. There are no general purpose query functions at this time other than LastError. The LastError query is accomplished through the DriverGetLastError function.

DriverSetInformation

Sets run-time information in the virtual driver.

Calling convention


INT DriverSetInformation(
PVD pVD,
PVDSETINFORMATION pVdSetInformation,
PUINT16 puiSize);

<!--NeedCopy-->

Parameters

pVD

Pointer to a virtual driver control structure.

pVdSetInformation

Pointer to a structure that specifies the information class, a pointer to any additional data, and the size in bytes of the additional data (if any).

puiSize

Pointer to the size of the information structure. This is an input parameter.

Return value

The function returns CLIENT_STATUS_SUCCESS.

Remarks

This function can receive two information classes:

  • VdDisableModule: When the connection is being closed.

  • VdFlush: When WFPurgeInput or WFPurgeOutput is called by the server-side virtual channel application. The VdSetInformation structure contains a pointer to a VDFLUSH structure that specifies which purge function was called.

Evt_create

Allocates an event structure containing a callback that can be associated with the input or the output events of a particular file descriptor.

Calling convention


VPSTATUS
Evt_create (
void \*hTC,
PFNDELIVER pDeliverFunc,
void \*pSubscriberId,
PEVT \*out);

<!--NeedCopy-->

Parameters

hTC

Pass NULL value as a dummy.

pDeliverFunc

The callback to call.

pSubscriberId

Data passed as an argument to the callback.

out

The event structure returned.

Return value

The event structure created is returned with the out pointer argument. If the function succeeds, the return value is EVT_SUCCESS.

If the function fails because of insufficient memory, the return value is EVT_OBJ_CREATE_FAILED.

Remarks

The first argument of the callback pSubscriberId is the same as the pSubscriberId used to create the event structure.

The second argument nEvt is a pointer to the event structure responsible for the callback.

Evt_destroy

Destroys previously created event structure by freeing its memory and nulling the given pointer.

Calling convention


VPSTATUS
Evt_destroy (
PEVT \*phEvt);

<!--NeedCopy-->

Parameters

phEvt

Pointer to the event object to destroy.

Return value

If the function succeeds, the return value is EVT_SUCCESS.

Remarks

The event object to destroy must be removed from the event loop using Evt_remove_triggers, before Evt_destroy is called.

Evt_remove_triggers

Removes the previously setup file descriptor selections from the given file descriptor.

Calling convention


VPSTATUS
Evt_remove_triggers (
Int fd);

<!--NeedCopy-->

Parameters

fd

The file descriptor to remove all selections from.

Return value

If the function succeeds, the return value is EVT_SUCCESS.

Remarks

If both the input and output conditions are selected, both the conditions are removed.

Evt_signal

Calls the callback stored within the given event structure.

Calling convention


VPSTATUS
Evt_signal (
PEVT hEvt);

<!--NeedCopy-->

Parameters

hEvt

The event structure containing the callback to call.

Return value

If the function succeeds, the return value is EVT_SUCCESS.

Remarks

Calls the callback function directly. No conditions must be met prior to this call.

Evt_trigger_for_input

Connects the callback of an event structure to trigger on the given file descriptor when it satisfies the input conditions.

Calling convention


VPSTATUS
Evt_trigger_for_input (
PEVT hEvt,
int fd);

<!--NeedCopy-->

Parameters

hEvt

The event structure to associate with the input conditions of the given file descriptor.

fd

The file descriptor.Workspace app

Return Value

If the function succeeds, the return value is EVT_SUCCESS.

If the function fails because of insufficient memory, the return value is EVT_OBJ_CREATE_FAILED.

Remarks

The Glib implementation of the event loop used by Citrix Workspace app for Linux watches for the input conditions G_IO_IN and G_IO_HUP.

Evt_trigger_for_output

Connects the callback of an event structure to trigger on the given file descriptor when it satisfies the output conditions.

Calling Convention


VPSTATUS
Evt_trigger_for_output (
PEVT hEvt,
int fd);

<!--NeedCopy-->

Parameters

hEvt

The event structure to associate with the ouput conditions of the given file descriptor.

fd

The file descriptor.Workspace app

Return value

If the function succeeds, the return value is EVT_SUCCESS.

If the function fails because of insufficient memory, the return value is EVT_OBJ_CREATE_FAILED.

Remarks

The Glib implementation of the event loop used by Citrix Workspace app for Linux watches for the ouput conditions G_IO_OUT.

ICADataArrival

The WinStation driver calls this function when data is received on a virtual channel being monitored by the driver. The address of this function is passed to the WinStation driver during DriverOpen.

Calling convention


INT wfcapi ICADataArrival(
PVD pVD,
USHORT uChan,
LPBYTE pBuf,
USHORT Length);

<!--NeedCopy-->

Parameters

pVD

Pointer to a virtual driver control structure.

uChan

Virtual channel number.

pBuf

Pointer to the data buffer containing the virtual channel data as sent by the server-side application.

Length

Length in bytes of the data in the buffer.

Return value

The driver returns CLIENT_STATUS_SUCCESS.

Remarks

This function name is a placeholder for a user-defined function; the actual function does not have to be called ICADataArrival, although it does have to match the function signature (parameters and return type). The address of this function is given to the WinStation driver during DriverOpen. Although ICA prefixes packet control data to the virtual channel data, this prefix is removed before this function is called.

After the virtual driver returns from this function, the WinStation driver considers the data delivered. The virtual driver must save whatever information it needs from this packet if later processing is required.

Do not allow this function to block. Use your own thread or the DriverPoll function (with polling enabled) for any required deferred processing.

The virtual driver can send data to the server on receipt of this data from within the ICADataArrival function, but be aware that the send operation may return an immediate error when buffers are not available to accommodate the send operation. The virtual driver may not block in this function waiting for the sending operation to complete.

If the virtual driver is handling multiple virtual channels, use the uChan parameter to determine the channel over which this data is to be sent. See DriverOpen for more information.

vdapi_is_feature_supported

Tells if a wanted feature is available in this end-point.

Calling convention

BOOL WFCAPI vdapi_is_feature_supported(
    const char* feature);
<!--NeedCopy-->

Parameters

Parameter Description
feature The feature name

Return values

TRUE if a wanted feature is available in this end-point.

VDAPI_FEATURE_VDVIEWPORT

The feature name of “VDVIEWPORT” API group. Pass this to vdapi_is_feature_supported() to query availability before making the actual call, like this:

    if (vdapi_is_feature_supported(VDAPI_FEATURE_VDVIEWPORT)) {
        BOOL ret = VdViewportIsSeamless(pVd);
        // ...
    }
<!--NeedCopy-->

IMPORTANT WARNING: DO NOT call any of the VDVIEWPORT APIs until you receive your first packet in ICADataArrival() You might get unexpected behavior if you call them in DriverOpen()/DriverSetXxx() stage.

VDVIEWPORTINFO

A viewport represents a local window in which a remote desktop session is displayed. This structure contains various information about a viewport, such as the viewport mode or type, the window handle, dimensions, etc.

There are two basic types of viewports: Windowed mode and seamless apps. In a windowed session, all application windows (and their contents) within the session are composited and rendered in a single window on the local endpoint device. Seamless applications get their own window/viewport on the local endpoint device.

/* dimensional properties */
typedef struct _VDVIEWPORTDIMS {
    UINT32 x;
    UINT32 y;
} VDVIEWPORTDIMS, *PVDVIEWPORTDIMS;

typedef struct _VDVIEWPORTINFO {
    // indicates the viewport type or mode (windowed or seamless app)
    // Note that in CWA-Windows, the display modes(scaling/panning) are also represented in this 'flag',
    // But in CWA-Linux, we don't support scaling/panning.
    UINT32 flags;

    // The X-window id of the viewport.
    // For windowed mode, it's always valid.
    // For seamless app, it's only valid if the "parent" window of "hwin" has been created.
    // (You can use MM_TWI_set_new_window_function() to register for window creation events and match with the "hwin" in the callback).
    UINT32 xwin;

    // The dimensions of the session displayed in the viewport.
    // For windowed mode, it's always valid.
    // For seamless app, it's only valid if a callback of VdRegisterViewportChangedCallback() has been triggered for the corresponding "hwin".
    VDVIEWPORTDIMS sessionSize;
} VDVIEWPORTINFO, *PVDVIEWPORTINFO;

#define VDVI_SEAMLESS 1
<!--NeedCopy-->

VdViewportIsSeamless

Tells if current viewport is running at seamless app mode.

Calling conventiona

BOOL WFCAPI VdViewportIsSeamless(
    PVD pVd);
<!--NeedCopy-->

Parameters

Parameter Description
pVd A handle to the virtual channel driver.

Return values

TRUE for seamless app mode. FALSE for windowed desktop mode.

VdGetViewportInformation

Retrieve basic information about the local viewport window.

Calling convention

INT WFCAPI VdGetViewportInformation(
    PVD pVd,
    UINT32 hwin,
    PVDVIEWPORTINFO pInfo);
<!--NeedCopy-->

Parameters

Parameter Description
pVd A handle to the virtual channel driver.
hwin The window handle from the remote desktop session(HWND). Pass 0 for desktop window under windowed mode(non-seamless mode).
pInfo A pointer to receive the viewport information.

Return values

CLIENT_STATUS_SUCCESS if successful.

VdGetViewportScaleFactors

Retrieve the session scale factors from the viewport information.

Calling convention

INT WFCAPI VdGetViewportScaleFactors(
    PVDVIEWPORTINFO pInfo,
    DOUBLE* pScaleX,
    DOUBLE* pScaleY);
<!--NeedCopy-->

Parameters

Parameter Description
pInfo A pointer to the viewport information.
pScaleX A pointer which receives the x scale factor.
pScaleY A pointer which receives the y scale factor.

Return values

CLIENT_STATUS_SUCCESS if successful.

VdRegisterViewportChangedCallback

Register for viewport change notifications.

The callback will be invoked whenever a seamless viewport window size change. The caller can retrieve the updated viewport parameters by calling VdGetViewportInformation in the callback function.

Calling convention

INT WFCAPI VdRegisterViewportChangedCallback(
    PVD pVd,
    UINT32 hwin,
    PFN_VIEWPORTCHANGED pfnCallback,
    PUINT32 puiHandle);
<!--NeedCopy-->

Parameters

Parameter Description
pVd A handle to the virtual channel driver.
hwin The window handle from the remote desktop session(HWND). Pass 0 for desktop window under windowed mode(non-seamless mode).
pfnCallback The callback to be invoked when the viewport changes.
puiHandle Receives an identifier that can be used to unregister the callback.

Return values

CLIENT_STATUS_SUCCESS if successful.

VdUnregisterViewportChangedCallback

Unregister for viewport change notifications.

This function unregisters a previously registered callback for viewport change notifications. Typically called from DriverClose.

Calling convention

INT WFCAPI VdUnregisterViewportChangedCallback(
    PVD pVd,
    UINT32 handle);
<!--NeedCopy-->

Parameters

Parameter Description
pVd A handle to the virtual channel driver.
handle The handle returned by VdRegisterViewportChangeNotifications.

Return values

CLIENT_STATUS_SUCCESS if successful.

VdTranslateAppWindow

Find the local window handle that maps to the given remote/virtual window handle.

Most of the time this function is used to set the correct parent window for overlays created on the local endpoint device. Virtual channels that create local overlays will typically send the window handle of the parent window on the remote desktop (within the remote session) to the endpoint device. This window handle then needs to be looked up in a mapping table on the local endpoint to find the corresponding local window handle.

Calling convention

INT WFCAPI VdTranslateAppWindow(
    PVD pVd,
    UINT32 hwin,
    PUINT32 pXwin);
<!--NeedCopy-->

Parameters

Parameter Description
pVd A handle to the virtual channel driver.
hwin The window handle from the remote desktop session(HWND). Pass 0 for desktop window under windowed mode(non-seamless mode).
pXwin Receives the window handle on the local endpoint device which corresponds to the given remote desktop window.

Return values

CLIENT_STATUS_SUCCESS if successful.

VdTranslateVirtualRect

Translate a rectangle from the VDA to local coordinates.

As of now, since CWA-Linux neither supports scaling nor panning, this API is only here to be consistent with the VCSDK-Windows APIs.

Calling convention

INT WFCAPI VdTranslateVirtualRect(
    PVD pVd,
    SIGNED_RECT virtualRect,
    PSIGNED_RECT pLocalRect,
    UINT32 type);
<!--NeedCopy-->

Parameters

Parameter Description
pVd A handle to the virtual channel driver.
virtualRect The input rectangle to translate.
pLocalRect Receives the translated rectangle.
type Indicates the type of rectangle being translated.

Return values

CLIENT_STATUS_SUCCESS if successful.

VDAPI_FEATURE_VDIO

The feature name of “VDIO” API group. Pass this to vdapi_is_feature_supported() to query availability before making the actual call, like this:

    if (vdapi_is_feature_supported(VDAPI_FEATURE_VDIO)) {
        INT ret = VdOpen(pVd, "VDPING", &channelNumber);
        // ...
    }
<!--NeedCopy-->

VdOpen

Retrieve channel number for virtual channel with the given name.

Calling convention

INT WFCAPI VdOpen(
    PVD pVd,
    PCHAR pName,
    PUSHORT pChannelNumber);
<!--NeedCopy-->

Parameters

Parameter Description
pVd A handle to the virtual channel driver.
pName The name of the virtual channel to open.
pChannelNumber A pointer to receive the allocated channel number.

Return values

CLIENT_STATUS_SUCCESS if successful.

VdRegisterIoCallback

Registers an IO callback which is used to receive data for the virtual channel driver.

Calling convention

INT WFCAPI VdRegisterIoCallback(
    PVD pVd,
    USHORT usChannelNumber,
    PVDWRITEPROCEDURE pProc,
    PVDIOCONTEXT pIoContext,
    PUSHORT pusMaxWriteSize);
<!--NeedCopy-->

Parameters

Parameter Description
pVd A handle to the virtual channel driver.
usChannelNumber The number which identifies the virtual channel from which to receive data.
pProc The callback function to be invoked when data is received from the virtual channel.
pIoContext (Out) A pointer to receive an I/O context through which data can be written to the virtual channel.
pusMaxWriteSize A pointer to receive the maximum packet size which can be written to the virtual channel.

Return values

CLIENT_STATUS_SUCCESS if successful.

VdUnregisterIoCallback

Unregisters an IO callback and releases the associated IO context.

Calling convention

INT WFCAPI VdUnregisterIoCallback(
    VDIOCONTEXT pIoContext);
<!--NeedCopy-->

Parameters

Parameter Description
pIoContext The I/O context to release.

Return values

CLIENT_STATUS_SUCCESS if successful.

VdWriteData

Write data to the virtual channel.

If the client supports sending data immediately, then the data is immediately sent. Otherwise, the data will be queued until VdServiceIo is called.

Calling convention

INT WFCAPI VdWriteData(
    VDIOCONTEXT pIoContext,
    MEMORY_SECTION* pBuffers,
    UINT32 count);
<!--NeedCopy-->

Parameters

Parameter Description
pIoContext The I/O context for the virtual channel to write data to.
pBuffers An array of buffers containing the data to write.
count The number of buffers to write.

Return values

CLIENT_STATUS_SUCCESS if successful.

VdServiceIo

Sends any pending outgoing data that has been queued for the virtual channel.

This method should be called by the virtual driver Poll method.

Calling convention

INT WFCAPI VdServiceIo(
    VDIOCONTEXT pIoContext);
<!--NeedCopy-->

Parameters

Parameter Description
pIoContext The I/O context for the virtual channel to send data for.

Return values

CLIENT_STATUS_SUCCESS if successful.

miGetPrivateProfileBool

Gets a Boolean value from a section of the Configuration Storage.

Calling convention


INT miGetPrivateProfileBool(
PCHAR lpszSection,
PCHAR lpszEntry,
BOOL bDefault);

<!--NeedCopy-->

Parameters

lpszSection

Name of section to query.

lpszEntry

Name of entry to query.

bDefault

Default value to use.

Return values

If the requested entry is found, the entry value is returned; otherwise, bDefault is returned.

Remarks

A Boolean value of TRUE can be represented by on, yes, or true in the configuration files. All other strings are interpreted as FALSE.

miGetPrivateProfileInt

Gets an integer from a section of the Configuration Storage.

Calling convention


INT miGetPrivateProfileInt(
PCHAR lpszSection,
PCHAR lpszEntry,
INT iDefault);

<!--NeedCopy-->

Parameters

lpszSection

Name of section to query.

lpszEntry

Name of entry to query.

iDefault

Default value to use.

Return values

If the requested entry is found, the entry value is returned; otherwise, iDefault is returned.

miGetPrivateProfileLong

Gets a long value from a section of the configuration files.

Calling convention


INT miGetPrivateProfileLong(
PCHAR lpszSection,
PCHAR lpszEntry,
LONG lDefault);

<!--NeedCopy-->

Parameters

lpszSection

Name of section to query.

lpszEntry

Name of entry to query.

lDefault

Default value to use.

Return Values

If the requested entry is found, the entry value is returned; otherwise, lDefault is returned.

miGetPrivateProfileString

Gets a string from a section of the configuration files.

Calling convention


INT miGetPrivateProfileString(
PCHAR lpszSection,
PCHAR lpszEntry,
PCHAR lpszDefault,
PCHAR lpszReturnBuffer, INT cbSize);

<!--NeedCopy-->

Parameters

lpszSection

Name of section to query.

lpszEntry

Name of entry to query.

lpszDefault

Default value to use.

lpszReturnBuffer

Pointer to a buffer to hold results.

cbSize

Size of lpszReturnBuffer in bytes.

Return values

This function returns the string length of the value returned in lpszReturnBuffer (not including the trailing NULL).

If the requested entry is found and the size of the entry string is less than or equal to cbSize, the entry value is copied to lpszReturnBuffer; otherwise, iDefault is copied to lpszReturnBuffer.

Remarks

lpszDefault must fit in lpszReturnBuffer. The caller is responsible for allocating and deallocating lpszReturnBuffer.

lpszReturnBuffer must be large enough to hold the maximum length entry string, plus a NULL termination character. If an entry string does not fit in lpszReturnBuffer, the lpszDefault value is used.

MM_clip

Sets the shape of the operating system window “xwin” from the list of sorted rectangles.

Calling convention


void
MM_clip (
UINT32 xwin,
int count,
struct tagTWI_RECT \*rects,
BOOLEAN extended)

<!--NeedCopy-->

Parameters

xwin

Operating system session sub-window.

count

Number of rectangles.

rects

Array of rectangles sorted by Y and X.

extended

TRUE for any extensions; otherwise, FALSE.

Return values

There are no return values.

Remarks

The structure has four long integers for left, top, right, and bottom. Rectangles are YXsorted.

The last argument must be FALSE to start a fresh clipping update, and TRUE to add any clipping updates to the current clipping list.

MM_destroy_window

Destroys a window created by MM_get_window().

Calling convention


void
MM_destroy_window (
UINT32 hwin,
UINT32 xwin,

<!--NeedCopy-->

Parameters

hwin

Host (seamless) window identifiers, ignored for non-seamless sessions.

xwin

x sub-window of the session window.

Return values

There are no return values.

Remarks

MM_destroy_window also removes any window deletion callbacks added with the low level MM_TWI_set_deletion_call.

MM_get_window

Creates an operating system window “xwinp” that is a sub-window of an existing session window with a server handle “hwin”.

Calling convention


BOOLEAN
MM_get_window (
UINT32 hwin,
UINT32 \*xwinp,

<!--NeedCopy-->

Parameters

hwin

Host (seamless) window identifiers, ignored for non-seamless sessions.

xwinp

Local operating system window identifier. Returns the sub-window identifier of the session window. In this case, the X Window System is the operating system windowing system.

Return values

If the parent (hwin) exists, the return value is TRUE. If the parent does not exist, the return value is FALSE.

If the return value is FALSE, the function, including window creation, still works. The root window, however, is used as a temporary parent.

A call to MM_get_window() or MM_set_geometry() can be used to reparent to any existing seamless window.

Remarks

When “0” is passed as the server handle in a non-seamless (single window) session, there can be an existing window, *xwinp that is reparented. The sub-window, however, is unmapped.

If the parent is seamless, *xwinp is protected by unmapping and reparenting it to the root before the parent is deleted.

MM_set_geometry

Sets the size and position for an existing sub-window, “xwin” of a session window with the server handle, “hwin”.

Calling convention


BOOLEAN
MM_set_geometry (
UINT32 hwin,
UINT32 xwin,
CTXMM_RECT \*rt);

<!--NeedCopy-->

Parameters

hwin

Host (seamless) window identifiers, ignored for non-seamless sessions.

xwin

Local operating system window identifier for the session sub-window. In this case, the X Window System is the operating system windowing system.

rt

CTXMM_RECT that describes the new window position and geometry.

Return values

If the parent (hwin) exists, the return value is TRUE. If the parent does not exist, the return value is FALSE.

If the return value is TRUE, the sub-window is mapped on return.

Remarks

The CTXMM_RECT window rectangle is within the session coordinates which are not window relative and consist of four unsigned 32-bit integers for left, top, right, and bottom.

MM_show_window

Makes a sub-window visible.

Calling convention


void
MM_show_window (
UINT32 xwin)

<!--NeedCopy-->

Parameters

xwin

Local operating system window identifier for the session sub-window. In this case, the X Window System is the operating system windowing system.

Return values

There are no return values.

Remarks

This function is called when the parent seamless window arrives after the geometry is set.

There must, however, be a successful call to MM_get_window() initially.

The function can be called with exactly the same window identifiers as the previous one. It cannot be used if MM_set_geometry() previously returned TRUE.

MM_TWI_clear_new_window_function

Clears the callback function set up using MM_TWI_set_new_window_function.

Calling convention


void
MM_TWI_clear_new_window_function (
void (\*) (UINT32))

<!--NeedCopy-->

Parameters

(*)(UINT32))

Callback function pointer to remove.

Return values

There are no return values.

Remarks

Clears the callback for seamless window creation.

MM_TWI_set_new_window_function

Sets a callback function for seamless window creation.

Calling convention


void
MM_TWI_set_new_window_function (
void (*) (UINT32));

<!--NeedCopy-->

Parameters

(*)(UINT32)

Callback function pointer to remove.

Return values

There are no return values.

Remarks

When MM_get_window() fails because the seamless window is not yet created, MM_TWI_set_new_window_function can be used to watch the creation. The handle must be established only when required and should be removed immediately. The callback argument is the server window handle of a newly created seamless window.

OutBufAppend (Deprecated)

Note:

This function is deprecated. QueueVirtualWrite must be used in all new virtual drivers.

Adds virtual channel packet data to the current output buffer.

Calling convention


INT WFCAPI OutBufAppend(
PWD pWd,
LPBYTE pData,
USHORT ByteCount);

<!--NeedCopy-->

Parameters

pWd

Pointer to a WinStation driver control structure.

pData

Pointer to the buffer containing the data to append.

ByteCount

Number of bytes to append to the buffer.

Return values

If the function succeeds, it returns CLIENT_STATUS_SUCCESS.

If the function fails, it returns error code associated with the failure; use GetLastError to get the extended error information.

Remarks

This function adds virtual channel packet data to the end of the current output buffer. A buffer of appropriate size must be reserved before calling this function.

The address for this function is obtained from the VDWRITEHOOK structure after hook registration. The VDWRITEHOOK structure also provides pWd.

This function can be called multiple times to build up the content of the buffer. It is not written until OutBufWrite is called. Attempts to write more data than was specified in OutBufReserve cause unpredictable results.

The packet header information must be filled in before this function is called.

If an ICA header or virtual channel data is appended to the buffer, the buffer must be sent to the server before the control leaves the virtual driver.

OutBufReserve (Deprecated)

Note:

This function is deprecated. QueueVirtualWrite must be used in all new virtual drivers.

Checks if a buffer of the requested size is available. This function does not allocate buffers because they are already allocated by the WinStation driver.

Calling convention


INT WFCAPI OutBufReserve(
PWD pWd,
USHORT ByteCount);

<!--NeedCopy-->

Parameters

pWd

Pointer to a WinStation driver control structure.

ByteCount

Size in bytes of the buffer needed. This must be four bytes larger than the data to be sent.

Return values

If a buffer of the specified size is available, the return value is CLIENT_STATUS_SUCCESS.

If a buffer of the specified size is not available, the return value is CLIENT_ERROR_NO_OUTBUF.

Remarks

After this function is called to reserve an output buffer, use the other OutBuf* helper functions to append data and then send the buffer to the server.

If a buffer of the specified size is not available, attempt the operation in a later DriverPoll call.

The developer determines the ByteCount, which can be any length up to the maximum size supported by the ICA connection. This size is independent of size restrictions on the lower-layer transport.

  • If the server is running XenApp or a version of Presentation Server 3.0 Feature Release 2 or later, the maximum packet size is 5000 bytes (4996 bytes of data plus the 4-byte packet overhead generated by the ICA datastream manager)

  • If the server is running a version of Presentation Server earlier than 3.0 Feature Release 2, the maximum packet size is 2048 bytes (2044 bytes of data plus the 4- byte packet overhead generated by the ICA datastream manager)

The address for this function is obtained from the VDWRITEHOOK structure after hook registration. The VDWRITEHOOK structure also provides the pWd address.

OutBufWrite (Deprecated)

Note:

This function is deprecated. QueueVirtualWrite must be used in all new virtual drivers.

Sends a virtual channel packet to XenApp or XenDesktop.

Calling convention


INT WFCAPI OutBufWrite(
PWD pWd);

<!--NeedCopy-->

Parameters

pWd

Pointer to a WinStation driver control structure.

Return values

If the function succeeds, it returns CLIENT_STATUS_SUCCESS.

If the function fails, it returns the error code associated with the failure; use GetLastError to get the extended error information.

Remarks

This function sends the current output buffer to the host. If a buffer was not reserved or no data was appended, this function does nothing.

If an ICA header or virtual channel data is appended to the buffer, the buffer must be sent to the server before DriverPoll returns.

The address for this function is obtained from the VDWRITEHOOK structure after hook registration. The VDWRITEHOOK structure also provides the pWd address.

QueueVirtualWrite

QueueVirtualWrite is an improved scatter gather interface. It queues a virtual write and stimulates packet output if required allowing data to be sent without having to wait for the poll.

Calling convention


int WFCAPI
QueueVirtualWrite (
PWD pWd,
SHORT Channel,
LPMEMORY_SECTION pMemorySections,
USHORT NrOfMemorySections,
USHORT Flag);

<!--NeedCopy-->

Parameters

pWd

Pointer to a WinStation driver control structure.

Channel

The virtual channel number

pMemorySections

Pointer to an array memory sections.

NrOfMemorySections

The number of memory sections.

Flag

This can be FLUSH_IMMEDIATELY if the data is required to be sent immediately or ! FLUSH_IMMEDIATELY for lower priority data.

Return values

If the function succeeds, that is queued successfully, the return value is CLIENT_STATUS_SUCCESS.

If the function fails because of unsuccessful queue, the return value is CLIENT_ERROR_NO_OUTBUF.

Remarks

The interface is simpler as it reduces the call sequence OutBufReserve, AppendVdHeader, OutBufAppend, and OutBufWrite down to a single QueveVirtualWrite call.

The data to be written across the chosen virtual channel is described by an array of MEMORY_SECTION structures, each of which contains a length and data pointer pair. This allows multiple non-contiguous data segments to be combined and written with a single QueueVirtualWrite.

Tmr_create

Creates a timer object and returns its handle.

Calling convention


VPSTATUS
Tmr_create (
HND hTC,
UINT32 uiPeriod,
PVOID pvSubscriber,
PFNDELIVER pfnDeliver.
PTMR * phTimer);

<!--NeedCopy-->

Parameters

hTC

The value is NULL.

uiPeriod

The timeout for the timer in milliseconds.

pvSubscriber

Data passed as an argument to the callback.

pfnDeliver

The callback to call.

phTimer

The returned timer structure.

Return values

If the function succeeds, the return value is TMR_SUCCESS.

If the function fails because of insufficient memory, the return value is TMR_OBJ_CREATE_FAILED.

Remarks

The default state of a newly created timer object is disabled. The “deliver” function is called when the timer fires.

Tmr_destroy

Destroys the timer object pointed to by the given handle and sets the handle to NULL.

Calling convention


VPSTATUS
Tmr_destroy (
PTMR \* phTimer);

<!--NeedCopy-->

Parameters

phTimer

The timer to destroy.

Return values

If the function succeeds, the return value is TMR_SUCCESS.

Remarks

Tmr_destroy is called for all timer objects when they are not required.

Tmr_setEnabled

Enables or disables a timer object.

Calling convention


VPSTATUS
Tmr_setEnabled (
PTMR \* hTimer);
BOOL fEnabled);

<!--NeedCopy-->

Parameters

hTimer

The timer to enable or disable.

fEnabled

Enables or disables the timer.

Return values

If the function succeeds, the return value is TMR_SUCCESS.

Remarks

Enabling a disabled timer restarts the timing period. Re-enabling an enabled timer, however, does not perform any action.

Tmr_setPeriod

Sets the timeout period for a timer.

Calling convention


VPSTATUS
Tmr_setPeriod (
PTMR \* hTimer);
UNIT32 uiPeriod);

<!--NeedCopy-->

Parameters

hTimer

The timer to change the timeout period for.

uiPeriod

The new timeout period in milliseconds.

Return values

If the function succeeds, the return value is TMR_SUCCESS.

Remarks

If the timer is already running, the timer is reset and fires after the new period. If the timer is disabled, the timeout period is updated but the timer remains disabled.

VdCallWd

Calls the client WinStation driver to query and set information about the virtual channel. This is the main method for the virtual driver to access the WinStation driver. For general-purpose virtual channel drivers, this sets the virtual write hook.

Calling convention


INT VdCallWd (
PVD pVd,
USHORT ProcIndex,
PVOID pParam,
PUINT16 puiSize);

<!--NeedCopy-->

Parameters

pVd

Pointer to a virtual driver control structure.

ProcIndex

Index of the WinStation driver routine to call. For virtual drivers, this can be either WDxQUERYINFORMATION or WDxSETINFORMATION.

pParam

Pointer to a parameter structure, used for both input and output.

puiSize

Size of parameter structure, used for both input and output.

Return values

If the function succeeds, it returns CLIENT_STATUS_SUCCESS.

If the function fails, it returns an error code associated with the failure; use DriverGetLastError to get the extended error information.

Remarks

This function is a general purpose mechanism to call routines in the WinStation driver. The only valid uses of this function for a virtual driver are:

  • To allocate the virtual channel using WDxQUERYINFORMATION

  • To exchange function pointers with the WinStation driver during DriverOpen using WDxSETINFORMATION

For more information, see DriverOpen or the Ping example.

On successful return, the VDWRITEHOOK structure contains pointers to the output buffer virtual driver helper functions, and a pointer to the WinStation driver control block (which is needed for buffer calls).