Programming reference

For function summaries , see:

  • Server-Side Functions Overview
  • Client-Side Functions Overview

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

Parameter Description
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

Parameter Description
pVD Pointer to a virtual driver control structure.
pVdLast Error 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

Parameter Description
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

Parameter Description
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 conditio n; 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;
    wdqi.WdInformationClass = WdOpenVirtualChannel; wdqi.pWdInformation = &OpenVirtualChannel;
    wdqi.WdInformationLength = sizeof(OPENVIRTUALCHANNEL); OpenVirtualChannel.pVCName = CTXPING_VIRTUAL_CHANNEL_NAME; rc = VdCallWd(pVd, WDxQUERYINFORMATION, &wdqi);
    /* 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-&gt;ChannelMask = (1L &lt;&lt; OpenVirtualChannel-&gt;);
    <!--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);
    rc = VdCallWd( pVd, WDxSETINFORMATION, &wdsi);
    /* do error processing here */
    <!--NeedCopy-->
    

    During the registration of the write hook, the WinStation driver passes entry points for the 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. Determine the version of the WinStation driver.

    New virtual drivers should determine whether the WinStation driver supports the new SendData API and “no polling” mode. Use the WdVirtualWriteHookEx information class to retrieve this information:

    // Do extra initialization to determine if
    // we are talking to an HPC client.
    wdsi.WdInformationClass = WdVirtualWriteHookEx;
    wdsi.pWdInformation = &vdwhex;
    wdsi.WdInformationLength = sizeof(VDWRITEHOOKEX);
    vdwhex.usVersion = HPC_VD_API_VERSION_LEGACY;
    
    //Set version
    
    // to 0; older clients will do nothing
    rc = VdCallWd(pVd, WDxQUERYINFORMATION, &wdsi, &uiSize);
    if (CLIENT_STATUS_SUCCESS != rc)
    {
    return(rc);
    }
    g_fIsHpc = (HPC_VD_API_VERSION_LEGACY != vdwhex.usVersion);
    
    // If version returned, this is HPC or later
    g_pSendData = vdwhex.pSendDataProc;  // save HPC SendData
    // API address
    <!--NeedCopy-->
    

    The usVersion that is returned may be one of the following values:

    typedef enum _HPC_VD_API_VERSION
    {
    HPC_VD_API_VERSION_LEGACY = 0,  // legacy VDs
    HPC_VD_API_VERSION_V1 =   1, // VcSDK API version 1
    } HPC VD API VERSION;
    <!--NeedCopy-->
    

    If the usVersion returned is HPC_VD_API_VERSION_LEGACY, the engine is an earlier engine. Any other value indicates the newer engine. The actual version returned indicates the version of the API supported. Currently the only other value that will be returned is HPC_VD_API_VERSION_V1. The g_fIsHpc flag should be set to indicate that the newer API is available.

    The WdVirtualWriteHookEx call also returns a pointer (g_pSendData). This is a pointer to the SendData function. Save this value for later use.

  5. Set the API options in the WinStation driver.

    If this virtual driver is loaded by the HPC WinStation driver, set the API options this driver will use:

    if(g_fIsHpc)
    {
    WDSET_HPC_PROPERITES hpcProperties;
    hpcProperties.usVersion = HPC_VD_API_VERSION_V1;
    hpcProperties.pWdData = g_pWd;
    hpcProperties.ulVdOptions = HPC_VD_OPTIONS_NO_POLLING;
    wdsi.WdInformationClass = WdHpcProperties;
    wdsi.pWdInformation = &hpcProperties;
    wdsi.WdInformationLength = sizeof(WDSET_HPC_PROPERITES);
    rc = VdCallWd(pVd, WDxSETINFORMATION, &wdsi, &uiSize);
    if(CLIENT_STATUS_SUCCESS != rc)
    {
    return(rc);
    }
    }
    <!--NeedCopy-->
    

    The usVersion field is set to inform the engine of the version of the VD API that this driver will use. This allows the engine to maintain the compatibility of the VD API for this driver at this level, even if the engine API changes in the future.

    The pWdData pointer must point to the same data that was pointed to by the pWdData field returned by the WdVirtualWriteHook VdCallWd call earlier in DriverOpen.

    The ulVdOptions field is a bitwise OR of any of the following bit definitions:

    typedef enum _HPC_VD_OPTIONS
    {
    HPC_VD_OPTIONS_NO_POLLING =0x0001,  // Flag indicating that
    //channels on this VD do not
    // require send data polling
    HPC_VD_OPTIONS_NO_COMPRESSION =0x0002  // Flag indicating
    // that channels on this VD
    // send data that does not
    // need reducer compression
    } HPC_VD_OPTIONS;
    <!--NeedCopy-->
    
  6. 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-->
    
  7. 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 check timers and other state information, send queued data to the server, and perform any other required processing. This function may be called on a regular basis by the main client poll loop.

Calling convention

INT DriverPoll(
PVD pVD,
PVOID pVdPoll,
PUINT16 puiSize);
<!--NeedCopy-->

Parameters

Parameter Description
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 function succeeds, it returns CLIENT_STATUS_SUCCESS.

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

If all virtual channels return CLIENT_STATUS_NO_DATA, the WinStation driver may slow down the polling process.

If the sending of data via either the QueueVirtualWrite or the SendData function is blocked (CLIENT_ERROR_NO_OUTBUF), DriverPoll should return CLIENT_STATUS_ERROR_RETRY so the WinStation driver does not slow polling. The virtual driver should then try again the next time it is polled.

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.

If polling has been disabled via the HPC_VD_OPTIONS_NO_POLLING option, DriverPoll will be called at least once, and then only when the virtual driver has asked to be polled, or when it has asked to be notified when a send operation can be retried. The return values have the same setting as in the polling case above. Return CLIENT_STATUS_SUCCESS if all data has been sent successfully. Return CLIENT_STATUS_NO_DATA if there is no data available to send. Return CLIENT_STATUS_ERROR_RETRY if the send operation was blocked and the virtual driver has more data to send.

Return values that begin with CLIENT_ERROR_* are fatal errors; the ICA session will be disconnected.

Remarks

A virtual driver is not allowed to block while waiting for a desired result (such as the availability of an output buffer).

The Ping example includes examples of processing types that can occur in Driver Poll.

DriverQueryInformation

Gets run-time information from the virtual driver.

Calling convention

INT DriverQueryInformation(
PVD pVD,
PVDQUERYINFORMATION pVdQueryInformation,
PUINT16 puiSize);
<!--NeedCopy-->

Parameters

Parameter Description
pVD Pointer to a virtual driver control structure.
pVdQuery Information 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

Parameter Description
pVD Pointer to a virtual driver control structure.
pVdSet Information 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.

SendData

Sends a virtual channel packet to the server, with a notification option.

Calling convention

INT WFCAPI SendData(DWORD pWd, USHORT usChannel,
 LPBYTE pData,USHORT usLen,
 LPVOID pUserData, UINT32 uiFlags);
<!--NeedCopy-->

Parameters

Parameters Description
pWd Pointer to a WinStation driver control structure.
us Channel The virtual channel number
pData Data passed as an argument to the callback
callback.usLen Lenght in bytes of the data in the data buffer
us User Data Length in b ytes of the data in the data buffer
uiFlags Flags to control the operation of the SendData function. This value consists of a number of flags bitwise OR’ed together. Each of the flags controls some aspect of the SendData interface.

Currently there is only one flag defined. See the SENDDATA_* enum:

  • SENDDATA_NOTIFY: If this flag is set,and when the SendData return code is CLIENT_ERROR_NO_OUTBUF indicating that the engine had no buffers to accommodate the outbound packet, the engine will notify the virtual driver later when it can retry the send operation. The notification occurs via the DriverPoll method.

Return value

The SendData function will return one of the following values:

  • CLIENT_STATUS_SUCCESS:
    • The data was copied into virtual write buffers.
    • The user’s buffer is free.
    • No callback will occur, even if the SENDDATA_NOTIFY flag is set.
    • The next SendData call can be issued immediately.
  • CLIENT_ERROR_NO_OUTBUF:
    • The virtual write could not be scheduled (out of VirtualWrite buffers). If a notification was requested, DriverPoll will be driven with the notification at some later time when the virtual driver should retry sending.
    • If no notification was requested, the virtual driver should return from DriverPoll and wait for the next poll before retrying the send. This assumes that the virtual driver had selected the polled mode of operation.
  • CLIENT_ERROR_BUFFER_STILL_BUSY: If the user has called SendData requesting a notification, and the return code was CLIENT_ERROR_NO_OUTBUF, the user must not issue another SendData call until the notification has occurred. If another call is issued before the notification occurs, the CLIENT_ERROR_BUFFER_STILL_BUSY return code will result.

  • CLIENT_ERROR_*: Any other error should cause the virtual driver and the session to close.

Note:

If the user has specified HPC_VD_OPTIONS_NO_POLLING in the HPC channel options, then the virtual driver must assume that its DriverPoll function will not be called again after receiving one of these errors.

Remarks

This function is used to send channel protocol to the server. The engine either accepts all the data, or refuses it all, in which case the channel will need to retry later (normally inside DriverPoll).

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

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

VOID wfcapi ICADataArrival(
 PVD pVD,
 USHORT uchan,
 LPBYTE pBuf,
 USHORT Length);
<!--NeedCopy-->

Parameters

Parameter Description
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

No value is returned from this function.

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 de livered. 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.

VdGetViewportInformation

Retrieve basic information about the local viewport window.

Calling convention

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

Parameters

Parameter Description
pVd A handle to the virtual channel driver.
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 viewport parameters change, such as the viewport mode, the viewport window handle, the session scaling parameters, or the session panning offsets. The caller can retrieve the updated viewport parameters by calling VdGetViewportInformation in the callback function. Typically called from DriverOpen.

Calling convention

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

Parameters

Parameter Description
pVd A handle to the virtual channel driver.
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,
 HND pVirtualWindow,
 PHND pLocalWindow);
<!--NeedCopy-->

Parameters

Parameter Description
pVd A handle to the virtual channel driver.
pVirtualWindow The window handle from the remote desktop session.
pLocalWindow 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.

Performs a combination of:

  • DPI scaling for remote desktops which don’t natively support DPI (mostly a legacy feature)
  • Scaling the rectangle according to the viewport session scale factors
  • Offsetting the rectangle according to the viewport session panning offsets

Typically, in that order. There are different types of rectangles which need to be scaled differently. Most of the time this function will be used to translate window rectangles in order to correctly size and position overlay windows on the local endpoint device. In such cases, the rectangle is assumed to be in screen coordinates. However, this function can also be used to translate client area rectangles or clipping rectangles. In such cases, the panning offsets will be ignored.

Calling convention

INT WFCAPI VdTranslateVirtualRect(
 PVD pVd,
 RECT pVirtualRect,
 LPRECT pLocalRect,
 UINT32 type);
<!--NeedCopy-->

Parameters

Parameter Description
pVd A handle to the virtual channel driver.
pVirtualRect 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.

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 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.

VdAcquireGraphicsListener

Obtain a graphics listener for a given virtual channel.

Calling convention

INT WFCAPI VdAcquireGraphicsListener(
 const char* vcName,
 PFN_GFXEVENTCALLBACK pfnCallback,
 PVOID pCallbackData,
 PGfxListener pListener);
<!--NeedCopy-->

Parameters

Parameter Description
vcName The name of the virtual channel which will receive the graphics data.
pfnCallback A callback function to be invoked whenever there is graphics data.
pCallbackData A user-provided context which will be passed to the callback when invoked.
pListener A pointer to receive the newly created listener.

Return values

CLIENT_STATUS_SUCCESS if successful.

VdReleaseGraphicsListener

Release a graphics listener and free any resources used by it.

Calling convention

INT WFCAPI VdReleaseGraphicsListener(
 GfxListener listener);
<!--NeedCopy-->

Parameters

Parameter Description
listener The listener to release.

Return values

CLIENT_STATUS_SUCCESS if successful.

VdAuthorizeGraphicsListener

Activates an existing graphics listener.

A graphics listener is bound to a virtual channel. This is accomplished by providing the name of the custom virtual channel as an argument when the listener is created. See VdAquireGraphicsListener. The graphics subsystem sends an event to the virtual channel for which the listener was registered. This event contains information needed to complete the initialization of the graphics listener.

This function should be called from DriverSetInformation.

Calling convention

INT WFCAPI VdAuthorizeGraphicsListener(
 GfxListener listener,
 GBufferConnectionEvt* pEvt);
<!--NeedCopy-->

Parameters

Parameter Description
listener The graphics listener to activate.
pEvt The event containing initialization information for the graphics listener.

Return values

CLIENT_STATUS_SUCCESS if successful.

VdLockFrameBuffer

Lock a frame buffer in order to access image data.

Calling convention

INT WFCAPI VdLockFrameBuffer(
 GfxListener listener,
 UINT32 bufferid,
 GfxImage* pImage);
<!--NeedCopy-->

Parameters

Parameter Description
listener A handle to the graphics listener from which this buffer originates.
bufferid An identifier for the buffer which contains the image data we want to access.
pImage A pointer to receive the image data.

Return values

CLIENT_STATUS_SUCCESS if successful.

VdUnlockFrameBuffer

Unlocks a buffer that was previously locked.

Calling convention

INT WFCAPI VdUnlockFrameBuffer(
 GfxListener listener,
 UINT32 bufferid);
<!--NeedCopy-->

Parameters

Parameter Description
listener A handle to the graphics listener.
bufferid An identifier for the buffer which contains the image data we no longer need to access.

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

Parameter Description
lpsz Section Name of section to query.
lpsz Entry 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

Parameter Description
lpsz Section Name of section to query.
lpsz Entry 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

Parameter Description
lpsz Section Name of section to query.
lpsz Entry Name of entry to query.
iDefault 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

Parameter Description
lpsz Section Name of section to query.
lpsz Entry Name of entry to query.
lpsz Default Default value to use.
lpsz Return Buffer Pointer to a buffer to hold results.
cb Size 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.

QueueVirtualWrite

A 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 NrOfSections,
USHORT Flag);
<!--NeedCopy-->

Parameters

Parameter Description
pWd Pointer to a WinStation driver control structure.
Channel The virtual channel number
pMemory Sections Pointer to an array of one or more elements of the structure MEMORY_SECTION (see below) containing the pure body of the protocol, i.e. excluding the virtual write header defining the channel and the length. This will get constructed by the QueueVirtualWrite function itself. Normally the protocol body will already be in a single contiguous block of memory. But if not, then multiple sections can be defined, and the destination function will copy all the different pieces into the appropriate internal WD queue.
Number Of Sections The number of memory sections, normally 1.
Flush Control Indicates whether a ‘flush to wire’ operation should be triggered after the data has been successfully queued. If this value is FLUSH_IMMEDIATELY, then if the line conditions permit, the WD will attempt to send this new virtual write immediately over the wire, after also flushing any earlier queued data for the same or higher priority. If the data is not time critical (within the span of about 50ms), it may be better not to force a flush at this point, so that the data (if small) may go over the wire together with other data, so making better use of the wire bandwidth. The value to use if an immediate flush is not required is !FLUSH_IMMEDIATELY.

Memory section

This structure has the definition:

typedef struct _MEMORY_SECTION
{
 UINT lenght; //Length of data
 LPBYTE pSection;  //Address of data
} MEMORY SECTION, far * LPMEMORY SECTION;
<!--NeedCopy-->

Return values

If the function succeeds, it returns CLIENT_STATUS_SUCCESS. If it cannot currently accept the data, it returns CLIENT_ERROR_NO_OUTBUF. If being called from DriverPoll, then the return value for the DriverPoll should normally be set to CLIENT_STATUS_ERROR_RETRY in this case. If the function fails, it returns an error code associated with the failure; use GetLastError to get the extended error information.

Remarks

This function is used to send channel protocol to the server. The engine either accepts all the data, or refuses it all, in which case the channel will need to retry later (normally inside DriverPoll).

The address for this function is obtained from the VDWRITEHOOK structure after hook Registration in pQueueVirtualWriteProc. The VDWRITEHOOK structure also provides pWd. Each successful call will ultimately result in a single block of protocol, with length = total length of all memory sections, being delivered to the server-side channel.

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);
<!--NeedCopy-->

Parameters

Parameter Description
pVd Pointer to a virtual driver control structure.
Proc Index Index of the WinStation driver routine to call. For virtual drivers, this can be either WDxQUERYINFORMATION or WDxSETINFORMATION.
pParam Pointer to a parameter structure.

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:.

  • 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).

WFVirtualChannelClose

Closes an open virtual channel handle.

Calling convention

BOOL WINAPI WFVirtualChannelClose(IN HANDLE hChannelHandle);
<!--NeedCopy-->

Parameter

Parameter Description
hChannel Handle Handle to a previously opened virtual channel. Use WFVirtualChannelOpen to obtain a handle for a specific channel.

Return values

If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE; call GetLastError to get extended error information.

Remarks

When this function is called, any data waiting to be sent to the client is discarded. Call this function when the server-side virtual channel application is finished.

The client- side virtual driver is not closed until the ICA session is closed. If the virtual driver sends data to the server after the server-side application closes, the data is queued on the server and eventually discarded.

To prevent the virtual driver from sending data after the server-side application closes, you might need to incorporate a packet type into your virtual channel protocol to notify the virtual driver that the server-side application is closing.

WFVirtualChannelOpen

Opens a handle to a specific virtual channel.

Calling convention

HANDLE WINAPI WFVirtualChannelOpen(IN HANDLE hServer,
 IN DWORD SessionId,
 IN LPSTR pVirtualName // ANSI name
 );
<!--NeedCopy-->

Parameters

Parameter Description
hServer Handle to a server running Citrix Virtual Apps. To specify the current server, use the constant WF_CURRENT_SERVER_HANDLE. Use WFOpenServer to obtain a handle for a specific server. For more information about the WFOpenServer function, see the WFAPI SDK documentation.
Session Id Server session ID. Use the constant WF_CURRENT_SESSION to specify the current session. To obtain the session ID of a specific session, use WFEnumerateSessions. For more information about session IDs and WFEnumerateSessions, see the WFAPI SDK documentation.
pVirtual Name Pointer to the virtual channel name. This is an ASCII string (even when Unicode is defined) of no more than seven characters.

Return values

If the function succeeds, it returns a handle to the specified virtual channel. If the function fails, it returns NULL; call GetLastError for extended error information.

Remarks

The WinStation driver opens the channel by name, assigns a channel number, and returns a handle. The server -side virtual channel application uses this handle to read and write data to the virtual channel.

WFVirtualChannelPurgeInput

Purges all queued input data sent from the client to the server on a specific virtual channel.

Calling convention

BOOL WINAPI WFVirtualChannelPurgeInput(IN HANDLE hChannelHandle);
<!--NeedCopy-->

Parameter

Parameter Description
hChannel Handle Handle to a previously opened virtual channel. To obtain a handle for a specific channel, use WFVirtualChannelOpen.

Return values

If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE; call GetLastError to get extended error information.

Remarks

Output buffers and queued data received from the client are discarded.

This function sends a message to the client WinStation driver, which then calls the client virtual driver’s

DriverSetInformation function with the VdFlush information class. For most virtual channels, this function is not necessary and you can use the Ping example function without modification.

WFVirtualChannelPurgeOutput

Purges all queued output data sent from the server to the client on a specific virtual channel.

Example of use: in an audio application in which the user starts playing a different audio file, use this function to discard the audio that was queued to be sent to the client from the first file played.

Calling convention

BOOL WINAPI WFVirtualChannelPurgeOutput(IN HANDLE hChannelHandle);
<!--NeedCopy-->

Parameter

Parameter Description
hChannel Handle Handle to a previously opened virtual channel. To obtain a handle for a specific channel, use WFVirtualChannelOpen.

Return values

If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. Call GetLastError to get extended error information.

Remarks

Output buffers and data queued to be sent to the client are discarded.

This function sends a message to the client WinStation driver, which then calls th e client virtual driver’s DriverSetInformation function with the VdFlush information class. For most virtual channels, this function is not necessary and you can use the Ping example function without modification.

WFVirtualChannelQuery

Returns data related to a virtual channel. This information is obtained when the ICA connection is initiated and the WinStation driver calls the DriverInfo function.

Calling convention

BOOL WINAPI WFVirtualChannelQuery(IN HANDLE hChannelHandle,
   IN WF_VIRTUAL_CLASS VirtualClass,
   OUT PVOID \*ppBuffer,
    OUT DWORD \*pBytesReturned
   );
<!--NeedCopy-->

Parameters

Parameter Description
hChannel Handle Handle to a previously opened virtual channel. To obtain a handle for a specific channel, use WFVirtualChannelOpen.
Virtual Class Type of information to request. Currently, the only defined value is WFVirtualClientData , which returns virtual channel client module data.
ppBuffer Pointer to the address of a variable to receive the data. The buffer is allocated within this fun ction and is deallocated by using WFFreeMemory.
pBytes Returned Pointer to a DWORD that is updated with the length of the data returned in the allocated buffer (upon successful return).

Return values

If the function succeeds, the return value is TRUE. If the function fails, the return value is F ALSE; Call GetLastError to get extended error information.

Remarks

ppBuffer begins with the structure VD_C2H, which begins with the structure MODULE_C2H. These two structures are defined in Ica-c2h.h (in src\inc). See the Ping example for more information.

WFVirtualChannelRead

Reads data from a virtual channel.

Calling convention

BOOL WINAPI WFVirtualChannelRead(IN HANDLE hChannelHandle,
  IN ULONG TimeOut,
 OUT PCHAR pBuffer,
  IN ULONG BufferSize,
  OUT PULONG pBytesRead
  );
<!--NeedCopy-->

Parameters

Parameter Description
hChannel Handle Handle to a previously opened virtual channel. To obtain a handle for a specific channel, use WFVirtualChannelOpen.
TimeOut Length of time to wait for data (in milliseconds). If this value is zero, the function returns immediately whether or not data is available. If this value is -1, the function continues waiting until there is data to read.
pBuffer Buffer to receive the data read from the virtual channel.
Buffer Size Size in bytes of the buffer needed.
pBytes Read Pointer to a variable that receives the number of bytes read.

Return values

If the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE; call GetLastError to get extended error information.

Remarks

The developer determines the BufferSize, 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 Citrix Virtual Apps, the maximum packet size is 5000 bytes (4996 bytes of data plus the 4-byte packet overhead generated by the ICA datastream manager).

If more data is received than the buffer can hold, the entire packet is discarded.

If no data is received, pBuffer and pBytesRead are unmodified. The function fails if the read times out.

The server-side virtual channel application is not notified when data is received. Instead, the data is queued until the application uses WFVirtualChannelRead to retrieve it.

WFVirtualChannelWrite

Writes data to a virtual channel.

Calling convention

BOOL WINAPI WFVirtualChannelWrite (IN HANDLE hChannelHandle,
 IN PCHAR pBuffer,
 IN ULONG Length,
  OUT PULONG pBytesWritten
  );
<!--NeedCopy-->

Parameters

Parameter Description
hChannel Handle Handle to a previously opened virtual channel. To obtain a handle for a specific channel, use WFVirtualChannelOpen.
pBuffer Buffer containing data to write to the virtual channel. This must be four bytes larger than the largest buffer written by the client.
Length Size in bytes of the buffer needed. This must be four bytes larger than the data written by the application.
pBytes Written Pointer to a ULONG variable that receives the number of bytes written.

Return values

If the data is sent, the return value is TRUE.

If the data is not sent, the return value is FALSE; call GetLastError to get extended error information.

Remarks

The developer determines the Length, 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, the maximum packet size is 5000 bytes (4996 bytes of data plus the 4-byte packet overhead generated by the ICA datastream manager).

The WinStation driver calls the client virtual driver’s ICADataArrival function.