WinFrame API SDK Programmer's Guide

Transcription

WFAPI SDK Programmer's GuideIntroductionThe Citrix WFAPI functions enable application programs to perform tasks that are unique to XenAppand XenDesktop. Appropriate hotfixes and service packs may be needed for the functions defined hereto execute properly.In this document XenApp and XenDesktop will be referred to as Citrix VDA. XenApp (RDS VDA)runs on server OSs, Microsoft Windows 2008R2 (Win 7 server) and Windows 2012R2 (Win 8.1 server)and XenDesktop (WS VDA) runs on workstation OSs, Windows 7, Windows 8.1, Windows 10.This SDK allows software developers to programmatically access features specific to Citrix VDAs. Forexample: Enumerating servers, sessions, and processesManaging servers, sessions, and processesAccessing Citrix-specific user dataSending messages to a sessionUsing virtual channelsWaiting on system eventsThe WFAPI SDK comprises a set of function calls to the Wfapi.dll dynamic link library (DLL) for 32bit applications and Wfapi64.dll for 64-bit applications. These DLLs are available on servers runningXenApp and on Windows Workstation platforms running XenDesktop. Example programs are includedto assist developers.Using the WFAPI SDKThe WFAPI SDK is intended for use by OEMs and customers who need to write applications thatdirectly call WFAPI functions, using Microsoft Visual C , Version 12.0 (Visual Studio 2013).System RequirementsThe WFAPI SDK must be installed and built on a Windows 7, Windows 8.1, Windows 10, WindowsServers 2008R2 or 2012R2 computer with sufficient disk space. The SDK does not need more than afew megabytes of disk space; however, third-party development tools (for example, Microsoft VisualC ) may require a substantial amount of disk space. When considering system requirements for usingthis SDK, plan to have enough disk space for all of the necessary software components to install andfunction properly.The WFAPI SDK is supported on 32-bit and 64-bit operating systems. The descriptions in this guideare primarily based on 32-bit operating systems and differences for 64-bit operating systems are noted.Generally, wfapi64.lib and wfapi64.dll are needed if you intend to develop a genuine 64-bitapplication; in all other cases, the 32-bit version of the files can be used on both 32-bit and 64-bitsystems. If you do not intend to develop genuine 64-bit applications, you do not need to use thewfapi64.lib and wfapi64.dll files.The WFAPI SDK has been upgraded to work with Microsoft Visual C Version 12.0. This SDK wasbuilt and tested with earlier versions of MS Visual Studio compilers (i.e. Visual Studio 8) for backwardcompatibility. Install Visual C before installing the WFAPI SDK.1

Execution EnvironmentCitrix ProductMinimum Version RequirementICA ClientsVersion 11.2Citrix XenDesktopVersion 7.0Citrix XenAppVersion 6.5Required hotfixes, service packs, and clients are available from http://www.citrix.com/support.Directory LayoutThe following folders are created in the WFAPI SDK installation directory: DOCS – WFAPI SDK Guide and ReadmeEXAMPLES – C examplesINCLUDE – C header file Wfapi.hLIB – C library files Wfapi.lib (for 32-bit applications) and Wfapi64.lib (for 64-bit applications)To install the WFAPI SDKRun WFApiSDK.msi. Follow the installation dialogs. The default installation directory is%SystemDrive%\Program Files (x86)\Citrix\WFApiSDK.To uninstall the WFAPI SDKUse the Add or Remove Programs utility in the Windows Control Panel.Example ProgramsThe WFAPI SDK includes C example programs that demonstrate how to use the WFAPI functions.There are three C example programs: TESTALL and SMCCONSOLE. Both ANSI (Testall.exe) andUnicode (Testallw.exe and SmcConsole.exe) versions of the programs are supplied with each located inits own sub-directory. The makefile that is supplied with the example programs builds both the ANSIand Unicode versions of the executables. The Unicode version is made by defining the Unicodemacros. You may modify these makefiles for your system as needed.These example programs are written to run on 32-bit machines. To run these examples on a 64-bitmachine, modify the makefiles so they link to wfapi64.lib instead of wfapi.lib.The Testall and SMCConsole sample programs have been tested for use with Servers running RDSVDAs and Workstations running WS VDAs.2

C Example ProgramsThe following instructions apply to Microsoft Visual Studio 2013. Adapt the instructions as needed forother environments.To build the C example programs from a command prompt1. If the INCLUDE and LIB environment variables are not set (type set at a command prompt toview them), double-click the VS 2013 x86 (or x64) Native Tools Command Prompt. This startsa command prompt and runs the Vcvars32.bat script located in the Visual C BIN directory.2. Run NMAKE on the desired directory.Note: With the files as shipped, running NMAKE with no parameters will not rebuild the source files.To force rebuilding all files, run NMAKE CLEAN ALL.To build the C example programs from within Microsoft Visual Studio 20131. Create a new project.a. Open a New Project. Select New from the File menu and select Project. Alternatively,press Ctrl N or click New Project on the Start page.b. In the New Project window, select Visual C Projects in the left pane under ProjectTypes.c. Select Win32 Project under Templates in the right pane.d. Type a project name in the Name text box (for example, wfapi).e. Enter the location of the project in the Location box or browse to a location.f. Click OK. The Win32 Application Wizard - wfapi window appears.g. Select Application Settings to display the application settings window, and configure theproject.h. Select an option under Application type.i. Select Empty project under Additional options.j. Click Finish.2. Add the source file (Testall.c) to the project.a. Select Add Existing Item from the Project menu or press Ctrl Shift D.b. In the Add Existing Item - wfapi window, enter a file name in the File name box.Alternatively, you can use the tool bar to find a file that you want to add.c. Select the file. Click Open.3. Configure the build environment.a. Select Properties from the Project menu. The wfapi Property Pages window appears.b. Select All Configurations from the Configurations list. A tree of configuration settingsappears in the left pane.c. Expand the C/C node.d. Select the General node.e. Enter the path for the Wfapi.h file in the Additional Include Directories box in the rightpane.f. Expand the Linker node in the left pane.g. Select the General node.h. Select the Additional Library Directories box in the right pane. Enter the path for the3

Wfapi.lib file.i. Click OK.4. To build the Unicode version:a. Select Properties from the Project menu.b. Select All Configurations from the Configurations list.c. Expand the C/C node on the left.d. Select the General category.e. In the Preprocessor Definitions text box, type /DUNICODE and /D UNICODE.5. Build the executable. Select Build Project from the Build menu, where Project is the name ofyour project (for example, wfapi).4

TESTALLThis example program uses a text menu interface to call most of the WFAPI functions. To retrieveinformation, specify the user name, server, and domain. These values affect the results of theWFQueryUserConfig() and WFSetUserConfig() functions.Programming GuideWhen you write Windows applications using the Microsoft Windows SDK, call WFAPI functions onlywhen necessary. Your C applications can check for the presence of Wfapi.dll (for 32-bit applications) orWfapi64.dll (for 64-bit applications), enabling them to run on any Windows 7 or greater Workstation orServer environment. These options help make your applications as portable as possible.The server and workstation are used interchangeably in the below functions.Function SummaryC FunctionDescriptionWFCloseServer()Closes an open server handleWFDisconnectSession()Disconnects a specified sessionWFDisconnectSessionEx()Forces an immediate disconnect of aspecified sessionWFEnumerateProcessesA()Retrieves a list of processes on the rocessesExA()Retrieves a list of processes on a eSessionsA()Retrieves a list of sessions on a )Frees memory allocated by WFAPI functionsWFLogoffSession()Logs off a specified sessionWFOpenServerA()Opens a handle to a specified etrieves information about a specifiedsession on a serverWFQuerySessionInformationW()5

C FunctionDescriptionWFQueryUserConfigA()Retrieves configuration information about aspecified user on a serverWFQueryUserConfigW()WFSendMessageA()Sends a message box to a specified sessionWFSendMessageW()WFSetUserConfigA()Modifies configuration information for aspecified user on a serverWFSetUserConfigW()WFShutdownSystem()Shuts down (and optionally restarts) thecurrent serverWFTerminateProcess()Terminates a specified process on a serverWFVirtualChannelClose()Closes an open virtual channel handleWFVirtualChannelOpen()Opens a handle to a specific virtual channelWFVirtualChannelPurgeInput()Purges all queued input data sent from theclient to the server on a specified virtualchannelWFVirtualChannelPurgeOutput()Purges all queued output data sent from theserver to the client on a specified virtualchannelWFVirtualChannelQuery()Queries data related to a virtual channelWFVirtualChannelRead()Reads data from a virtual channelWFVirtualChannelReadEx()Reads data from a virtual channelWFVirtualChannelWrite()Writes data to a virtual channelWFWaitSystemEvent()Waits for an event (for example, ICA sessioncreate, delete, connect) before it returnsWFWaitSystemEvent()Verify the ability to wait on system ;6

Function CategoriesThe functions in the WFAPI SDK are grouped into several categories: internal, enumeration, serversystem, user, session, and virtual channel.Internal FunctionsThe WFAPI SDK internal functions are: WFOpenServerA() and WFOpenServerW() WFCloseServer() WFFreeMemory()These functions are internal to the WFAPI; they do not act upon the server or session. Most functionsrequire a handle to a server. A handle is obtained using the WFOpenServerA()/WFOpenServerW()function. The constant WF CURRENT SERVER HANDLE always refers to the current server andcan be used without explicitly issuing WFOpenServerA()/WFOpenServerW().Issue the WFCloseServer() function as part of your program’s clean-up when you are finished with thehandle. Do not close WF CURRENT SERVER HANDLE.If you call a C function that allocates and returns memory, de-allocate the memory using theWFFreeMemory() function when you are finished.Enumeration FunctionsThe WFAPI SDK enumeration functions are: WFEnumerateProcessesA() and WFEnumerateProcessesW() WFEnumerateProcessesExA() and WFEnumerateProcessesExW() WFEnumerateSessionsA() and WFEnumerateSessionsW()These functions are used to enumerate processes and sessions. The WFEnumerate Processes,WFEnumerateProcessesEx, and WFEnumerateSessions functions require a server handle.The WFEnumerateProcessEx functions return more detailed information than theWFEnumerateProcesses functions.Server System FunctionsThe WFAPI SDK server system functions are: WFShutdownSystem() WFWaitSystemEvent()These functions are used to manage a server system. The WFShutdownSystem() andWFWaitSystemEvent() functions require a server handle. WFShutdownSystem() shuts down andoptionally restarts the current server, and can be used to disable logons. WFWaitSystemEvent() waitsfor an event (ICA session create/delete/connect, user logon/logoff, and so on) before it returns.7

User FunctionsThe WFAPI SDK user functions are: WFQueryUserConfigA() and WFQueryUserConfigW() WFSetUserConfigA() and WFSetUserConfigW()These functions are used to retrieve or set user configuration information. Both functions require aserver name, a user name, and the class of information that will be operated on. A handle is notrequired. The constant WF CURRENT SERVER NAME refers to the current server.These functions are passed a server name instead of a handle because user account information oftenresides on a domain controller. Use the Windows function NetGetDCName() to retrieve the name of the primary domaincontroller for the WFSetUserConfig() function. Use the Windows function NetGetAnyDCName() to retrieve the name of any domain controllerfor the WFQueryUserConfig() function.You can use any domain controller to query domain information; however, you must use the primarydomain controller when changing domain information. This is in agreement with other Microsoft APIfunctions. The Visual Basic USER example program demonstrates the use of the NetGetAnyDCName()function.Session FunctionsThe WFAPI SDK session functions are: WFQuerySessionInformationA() and WFQuerySessionInformationW()WFSendMessageA() and WFSendMessageW()WFDisconnectSession() and eProcess()These functions are used to operate on active sessions. All functions require a server handle and asession ID.Virtual Channel FunctionsThe WFAPI SDK virtual channel functions are: lChannelPurgeOutput()WFVirtualChannelQuery()The ICA protocol provides multiplexed management of multiple virtual channels. A virtual channel is asession-oriented transmission connection that can be used by application layer code. Virtual channelsare used to add functional enhancements to the client, independent from the ICA protocol.8

The WFVirtualChannelOpen() function requires a server handle, a session ID, and a virtual channelname. It returns a virtual channel handle. The other functions require the resulting virtual channelhandle.Use the WFVirtualChannelClose() function to close the handle when it is no longer needed.Unicode and ANSI VersionsMost functions have both Unicode and ANSI versions. ANSI is an older, more common standard, but isdifficult to use simultaneously with multiple languages. Unicode is a 16-bit (wide) character set thatsupports up to 65,536 unique characters, allowing for the representation of multiple languagecharacters using a single character set.For each function that has both ANSI and Unicode declarations, both declarations are listed under themain heading. Each function is declared as either functionnameA( ) for the ANSI version orfunctionnameW( ) for the Unicode (wide) version.In C, the additional #define for functionname() allows you use a compiler directive to use all ANSI orall Unicode functions in the resulting executable. This makes it easy to produce both ANSI andUnicode versions of your programs because you need to change only the makefile.In Visual Basic, explicit function names must be used for those functions that have both ANSI andUnicode versions defined.C API Calling ConventionsC-language programs that use the WFAPI functions must include Wfapi.h, and link to Wfapi.lib for 32bit applications or Wfapi64.lib for 64-bit applications.The words IN and OUT that are listed in the function calling conventions are included only forclarification. They are defined as blank in the Windef.h file. If you do not have access to Windef.h, addthe following lines to the header file for your INOUTOUTWINAPI, as listed in the function calling conventions, is defined in the Windows.h file. If yourprogram uses dynamic linking with runtime binding, you must include Windows.h in the functionpointer definition. For more information, see the Testall.c example.If a function succeeds, the return value is TRUE. If a function fails, the return value is FALSE. Use theGetLastError() function to get the extended error status.9

Application Programming Guidelines Avoid using hard coded paths, such as C:\Temp. Use the Win32 API functions whenever possible. Many Windows API functions have Citrixenhancements to seamlessly support a multiuser environment. Do not assume that temporary files are persistent. Do not assume the existence of a default printer. Be sensitive to the bandwidth used by printing tasks. Do not use machine-specific attributes (such as machine names or IP addresses) for uniqueidentifiers. These items are common to all users on each machine. Write user-specific settings to HKEY CURRENT USER, not HKEY LOCAL MACHINE. Do not allow “File,” “Run” capabilities. Limit necessary animation to reduce bandwidth consumption. Use solid-color graphics for better ICA compression. Do not overwrite Windows Terminal Services-specific DLLs with Windows DLLs. Do not try to allocate all available memory. Do not use continuous polling loops in your code because they require excessive CPU cycles.Use event-driven techniques instead. Thoroughly test required peripheral devices over all connection types. Do not assume that your application will be run in a Windows Explorer shell. Memory leaks and their negative effects are greatly compounded in a multiuser environment. Avoid using bitmaps in graphics; use vector-based graphics instead. For best performance on anICA device, use the raster operator to “brush” graphics onto the screen. Some applications that use the TCP/IP protocol to communicate use the IP address as the hardcoded identifier of the client. Multiple instances of these applications will not run in a Citrixenvironment. For an application to properly communicate in a Citrix environment, the application must beable to negotiate a private socket, allowing the client and server to communicate using a uniqueIP/PORT/SOCKET address. The use of True Type fonts is preferred; these font types are stored on the client. If anapplication must use custom or Adobe fonts, configure them to be embedded Windows fonts forfaster display.10

Determining the Citrix VDA VersionTo determine the version of a Citrix VDA, issue the WFQuerySessionInformation() function withWFInfoClass set to WFVersion. Here is a C code segment extracted from the Testall.c exampleprogram.HANDLE hServer WF CURRENT SERVER HANDLE;DWORD SessionId WF CURRENT SESSION;LPTSTR pSessionInfo;DWORD ByteCount;LPOSVERSIONINFO pVerInfo;if ( !WFQuerySessionInformation( nt ) ) {tprintf( TEXT("”***WFQuerySessionInformation failed, error %u\n"),GetLastError() );return;}pVerInfo (LPOSVERSIONINFO) pSessionInfo;tprintf( TEXT("Version: major %u, minor %u, build %u, CSD: %s\n"),pVerInfo- dwMajorVersion, pVerInfo- dwMinorVersion,pVerInfo- dwBuildNumber, pVerInfo- szCSDVersion);ResultsIf this function is successful, it will return specific information about the version of the Citrix VDA thatis installed on your server. For example, if XenApp Server 6.0 is installed, this information will bedisplayed:Major 6, minor 0, build 2198Note: The results may vary, depending on the system configuration, and the hotfixes and service packsthat are installed on the system.11

Programming ReferenceUnless otherwise specified the following functions apply to Citrix VDAs. In the context of thisreference a ‘server’ can be any supported Windows OS that is running a Citrix VDA.WFCloseServerClose a server handle that was opened by WFOpenServer.C Calling ConventionVOID WINAPI WFCloseServer(IN HANDLE hServerHandle );hServerHandleA handle to a previously-opened server. Use the WFOpenServer() function to obtain a handle fora specific server.WFDisconnectSessionThis function disconnects a specified session.C Calling ConventionBOOL WINAPI WFDisconnectSession(IN HANDLE hServer,IN DWORD SessionId,IN BOOL bWait););hServerA handle to a server. Use the WFOpenServer() function to obtain a handle for a specific server orspecify WF CURRENT SERVER HANDLE to use the current server.SessionIdThe session ID of the target session. WF CURRENT SESSION identifies the current session.Use the WFEnumerateSessions() function to obtain session IDs.bWaitIf this value is TRUE, the function waits for the disconnect function to complete before it returns.Return ValuesIf the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. Usethe GetLastError() function to get the extended error status.12

WFDisconnectSessionExThis function forces an immediate disconnect of a specified session.C Calling ConventionBOOL WINAPI WFDisconnectSessionEx(IN HANDLE hServer,IN DWORD SessionId,IN ULONG Flags,IN PVOID pBuffer,IN ULONG BufferLength);hServerA handle to a server. Use the WFOpenServer() function to obtain a handle for a specific server orspecify WF CURRENT SERVER HANDLE to use the current server.SessionIdThe session ID of the target session. WF CURRENT SESSION identifies the current session.Use the WFEnumerateSessions() function to obtain session IDs.FlagsA combination of the following flags: WF DISCONNECT WAIT. If this flag is set, the function waits for the disconnect to finish; ifthis flag is not set, the function does not wait for the disconnect to finish. WF DISCONNECT NO NOTIFY CLIENT. If this flag is set, the function returns withoutnotifying the client; if this flag is not set, the function waits for the client’s response to ensurethat the client received the disconnect request.pBufferThis parameter is reserved for future use.BufferLengthThis parameter is reserved for future use.ReturnsIf the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. Usethe GetLastError() function to get the extended error status.RemarksThis function forces an immediate disconnect of the session. Use theWF DISCONNECT NO NOTIFY CLIENT flag with caution because it does not notify the client ofthe disconnect.13

WFEnumerateProcessesThis function retrieves a list of the active processes on a specified server.C Calling ConventionBOOL WINAPI WFEnumerateProcesses{W A}(IN HANDLE hServer,IN DWORD Reserved,IN DWORD Version,OUT PWF PROCESS INFO{W A} * ppProcessInfo,OUT DWORD * pCount);hServerA handle to a server. Use the WFOpenServer() function to obtain a handle for a specific server orspecify WF CURRENT SERVER HANDLE to use the current server.ReservedThis value must be zero (0).VersionThe version of the enumeration request, this value must be 1.ppProcessInfoA pointer to the address of a variable that will receive the enumeration results that are returned asan array of WF PROCESS INFO structures (defined in Wfapi.h). The buffer is allocated by thisfunction and is de-allocated using the WFFreeMemory() function.pCountA pointer to the variable that will receive the number of returned WF PROCESS INFOstructures.The name of the process pointed to by pProcessName contains an ANSI string ifWFEnumerateProcessesA() is used, and a Unicode string if WFEnumerateProcessesW() is used.ReturnsIf the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. Usethe GetLastError() function to get the extended error status.RemarksThis function only applies to RDS VDAs.14

WFEnumerateProcessesExThis function retrieves a list of the active processes on a specified server. Detailed process informationis also returned.C Calling ConventionBOOL WINAPI WFEnumerateProcessesEx{W A}(IN HANDLE hServer,IN DWORD Reserved,IN DWORD Version,OUT PWF PROCESS INFOEX{W A} * ppProcessInfo,OUT DWORD * pCount);hServerA handle to a server. Use the WFOpenServer() function to obtain a handle for a specific server orspecify WF CURRENT SERVER HANDLE to use the current server.ReservedThis value must be zero (0).VersionThe version of the enumeration request, this value must be 1.ppProcessInfoA pointer to the address of a variable that will receive the enumeration results that are returned asan array of WF PROCESS INFOEX structures (defined in Wfapi.h). The buffer is allocated bythis function and is de-allocated using the WFFreeMemory() function.pCountA pointer to the variable that will receive the number of returned WF PROCESS INFOEXstructures.ReturnsIf the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. Usethe GetLastError() function to get the extended error status.RemarksThis function only applies to RDS VDAs.15

WFEnumerateSessionsThis function retrieves a list of the sessions on a specified VDA.C Calling ConventionBOOL WINAPI WFEnumerateSessions{W A}(IN HANDLE hServer,IN DWORD Reserved,IN DWORD Version,OUT PWF SESSION INFO{W A} * ppSessionInfo,OUT DWORD * pCount);hServerA handle to a server. Use the WFOpenServer() function to obtain a handle for a particular server,or specify WF CURRENT SERVER HANDLE to use the current server.ReservedThis value must be zero (0).VersionThe version of the enumeration request, this value must be 1.ppSessionInfoA pointer to the address of a variable that will receive the enumeration results that are returned asan array of WF SESSION INFO structures (defined in Wfapi.h). The buffer is allocated by thisfunction and is de-allocated using the WFFreeMemory() function.pCountA pointer to the variable that will receive the number of returned WF SESSION INFOstructures.The session name pointed to by pWinStationName contains an ANSI string ifWFEnumerateSessionsA() is used, and a Unicode string if WFEnumerateSessionssW() is used.ReturnsIf the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. Usethe GetLastError() function to get the extended error status.RemarksThis function applies to RDS VDAs; on WS VDAs it will only show the console session.16

WFFreeMemoryThis function releases memory allocated by WFAPI functions.C Calling ConventionVOID WINAPI WFFreeMemory(IN PVOID pMemory);pMemoryA pointer to the memory to be freed.RemarksMany functions allocate a data area to return information. Use this function to release these data areas.WFLogoffSessionThis function logs off a specified session.C Calling ConventionBOOL WINAPI WFLogoffSession(IN HANDLE hServer,IN DWORD SessionId,IN BOOL bWait);hServerA handle to a server. Use the WFOpenServer() function to obtain a handle for a particular server,or specify WF CURRENT SERVER HANDLE to use the current server.SessionIdThe session ID of the target session. WF CURRENT SESSION specifies the current session.bWaitSpecify TRUE to instruct the server to wait for the operation to complete. Specify FALSE to logoff the session in the background. To verify that the session is logged off, use theWFQuerySessionInformation() function to query the session ID and check for a FALSE returnvalue.ReturnsIf the function succeeds, the return value is TRUE. If the function fails, the return value is FALSE. Usethe GetLastError() function to get the extended error status.17

WFOpenServerThis function opens a handle to a specified server.C Calling ConventionHANDLE WINAPI WFOpenServer{W A}(IN LPWSTR pServerName);pServerNameA pointer to the name of a server that is running a VDA.Supply an ANSI string to WFOpenServerA() and a Unicode string to WFOpenServerW().ReturnsIf the function succeeds, it returns a handle to the specified server. If the function fails, it returnsNULL. Call the GetLastError() function to get extended error status.RemarksWhen you are finished with the handle, use the WFCloseServer() function to close all server handlesopened using the WFOpenServer function, as part of you program's cleanup.You do not need to open a handle for operations performed on the server where the program is running.Use the constant WF CURRENT SERVER HANDLE instead.18

WFQuerySessionInformationThis function retrieves information about a specified session on a specified server.C Calling ConventionBOOL WINAPI WFQuerySessionInformation{W A}(IN HANDLE hServer,IN DWORD SessionIdIN WF INCO CLASS WFInfoClass,OUT LPWSTR * ppBuffer,OUT DWORD * pBytesReturned);hServerA handle to a server. Use the WFOpenServer() function to obtain a handle for a particular server,or specify WF CURRENT SERVER HANDLE to use the current server.SessionIdThe session ID of the target session. WF CURRENT SESSION specifies the current session.WFInfoClassType of information to be retrieved from the specified session.WFInfoClass valueData L-terminated stringWFWorkingDirectoryNULL-terminated stringWFOEMIdNULL-terminated stringWFSessionIdULONGWFUserNameNULL-terminated stringWFWinStationNameNULL-terminated stringWFDomainNameNULL-terminated WFClientNameNULL-terminated string3WFClientDirectoryNULL-terminated string3WFClientProductIdUSHORT3WFClientAddressWF CLIENT ADDRESS2, 3WFClientDisplayWF CLIENT DISPLAY2, 3WFClientCacheWF CLIENT CACHE2, 3WFClientDrivesWF CLIENT DRIVES2, 3WFICABufferLengthULONG3192

WFInfoClass valueData typeNoteWFApplicationNameNULL-terminated string3WFAppInfoWF APP INFO2, 3WFClientInfoWF CLIENT INFO2, 3WFUserInfoWF USER INFO2, 3WFSessionTimeWF SESSION TIME2 1 - This is a standard Windows structure defined in Winbase.h. For more information, see theWindows programming documentation. This option returns information only for the currentserver; the server handle parameter is ignored for this option. 2 - These structures are defined in Wfapi.h. 3 - These parameters can be used only if the function is called from an ICA session. If run fromthe server console or a Direct ICA station, the function returns FALSE. 4 - The strings are in ANSI format if WFEnumerateSessionInformationA() is used, and Unicodeformat if WFEnumerateSessionInformationW() is used. 5 - Use an INTEGER or LONG to retrieve a SHORT.ppBufferA pointer to the address of a variable that will receive the information about the specified session.The format and contents of the data depend on the specified information class being queried; seethe second column of the table above. The buffer is allocated by this function and is de-allocatedusing the WFFreeMemory(

The following instructions apply to Microsoft Visual Studio 2013. Adapt the instructions as needed for other environments. To build the C example programs from a command prompt . 1. If the INCLUDE and LIB environment variables are not set (type set at a command prompt to view them), double-click the VS