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).
In this article
- AppendVdHeader (Deprecated)
- DriverClose
- DriverGetLastError
- DriverInfo
- DriverOpen
- DriverPoll
- DriverQueryInformation
- DriverSetInformation
- Evt_create
- Evt_destroy
- Evt_remove_triggers
- Evt_signal
- Evt_trigger_for_input
- Evt_trigger_for_output
- ICADataArrival
- vdapi_is_feature_supported
- VDAPI_FEATURE_VDVIEWPORT
- VDVIEWPORTINFO
- VdViewportIsSeamless
- VdGetViewportInformation
- VdGetViewportScaleFactors
- VdRegisterViewportChangedCallback
- VdUnregisterViewportChangedCallback
- VdTranslateAppWindow
- VdTranslateVirtualRect
- VDAPI_FEATURE_VDIO
- VdOpen
- VdRegisterIoCallback
- VdUnregisterIoCallback
- VdWriteData
- VdServiceIo
- miGetPrivateProfileBool
- miGetPrivateProfileInt
- miGetPrivateProfileLong
- miGetPrivateProfileString
- MM_clip
- MM_destroy_window
- MM_get_window
- MM_set_geometry
- MM_show_window
- MM_TWI_clear_new_window_function
- MM_TWI_set_new_window_function
- OutBufAppend (Deprecated)
- OutBufReserve (Deprecated)
- OutBufWrite (Deprecated)
- QueueVirtualWrite
- Tmr_create
- Tmr_destroy
- Tmr_setEnabled
- Tmr_setPeriod
- VdCallWd