WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

Terminal Server

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

UDF to get Citrix session information

Keywords: 	 UDF to get Citrix session information 

Here is a UDF that decodes all the Citrix Metaframe WFQuerySessionInfo goodies:
; WinBatch2K UDF to use Citrix Metaframe WFQuerySessionInformation.
; Tested with Metaframe XP SP2 on Win2K SP2 and NT4 TSE SP6.
; 1. session_ID of -1 returns info of current session.
; 2. query_str of -1 returns ALL info for session.
; 3. string nulls returned as "NULL", numeric nulls returned as zero.
; See Citrix Metrframe SDK for information on structures returned!

#DefineFunction evsWFQuerySession(session_ID, query_str)
	;query with value or bitwise OR of values:
	;
	; Value    Function              i  Returns
	;--------- --------------------- -- --------
	;        1 WFVersion					0  struct
	;        2 WFInitialProgram		1  string
	;        4 WFWorkingDirectory		2  string
	;        8 WFOEMId					3  string
	;       16 WFSessionId				4  long
	;       32 WFUserName				5  string
	;       64 WFWinstationName		6  string
	;      128 WFDomainName				7  string
	;      256 WFConnectState			8  long
	;      512 WFClientBuildNumber	9  long
	;     1024 WFClientName				10 string
	;     2048 WFClientDirectory		11 string
	;     4096 WFClientProductID		12 short
	;     8192 WFClientHardwareId		13 long?
	;    16384 WFClientAddress			14 struct
	;    32768 WFClientDisplay			15 struct
	;    65536 WFClientCache			16 struct
	;========= FUNCTIONS ABOVE ARE SIMILAR FROM TERMINAL SERVER TO CITRIX
	;========= FUNCTIONS BELOW ARE UNIQUE TO METAFRAME
	;   131072 WFClientDrives			17 struct
	;   262144 WFICABufferLength		18 long
	;   524288 WFLicenseEnabler		19 null?
	;  1048576 RESERVED2					20 null?
	;  2097152 WFApplicationName		21 string
	;  4194304 WFVersionEx				22 null?
	;  8388608 WFClientInfo				23 struct
	; 16777216 WFUserInfo				24 struct
	; 33554432 WFAppInfo					25 struct
	; 67108864 WFClientLatency			26 struct
	;134217728 WFSessionTime			27 struct

	query = (%query_str%)
	dll_name = "WFAPI.DLL"
	ep_name = "WFQuerySessionInformationA"
	WFServer = 0 ; Use current server
	dll_handle = DllLoad(dll_name)
	str_return = ""

	for xx = 0 to 27
		if query & (2 ** xx)
			;Get value
			if str_return != "" then str_return = StrCat(str_return, "|")
			WFInfoClass = xx
			if WFInfoClass == 12
				type = 3 ;SHORT
			else
				if (WFInfoClass == 4) || (WFInfoClass == 8) || (WFInfoClass == 9) || (WFInfoClass == 12) || (WFInfoClass == 13) || (WFInfoClass == 18)
					type = 2 ;LONG
				else
					if (WFInfoClass == 0) || (WFInfoClass == 14) || (WFInfoClass == 15) || (WFInfoClass == 16) || (WFInfoClass == 17) || (WFInfoClass == 23) || (WFInfoClass == 24) || (WFInfoClass == 25) || (WFInfoClass == 26) || (WFInfoClass == 27)
						type = 0 ;STRUCTURE
					else
						type = 1 ;STRING
					endif
				endif
			endif
			ppBuffer = BinaryAlloc(4)             ;Allocate buffer for return pointer
			BinaryEODSet(ppBuffer, 4)             ;tell WinBatch all data is valid
			pBytesReturned = BinaryAlloc(4)       ;Allocate buffer for return count
			BinaryEODSet(pBytesReturned, 4)       ;Tell Winbatch all data is valid
			flag = DllCall(dll_handle, long:ep_name, LONG:WFServer, long:Session_ID, LONG:WFInfoClass, lpbinary:ppBuffer,lpbinary:pBytesReturned)
			if flag
				BytesReturned = BinaryPeek4(pBytesReturned, 0)
				Pointer2Buffer = BinaryPeek4(ppBuffer, 0)
				select type
					case 3
						this_value = IntControl(32, Pointer2Buffer, "WORD", 0, 0)
						break
					case 2
						this_value = IntControl(32, Pointer2Buffer, "LONG", 0, 0)
						break
					case 1
						this_value = evsMemToStr(Pointer2Buffer, BytesReturned)
						break
					case 0
						if WFInfoClass == 0
							for yy = 0 to 4
								this_value%yy% = IntControl(32, (Pointer2Buffer + 4 * yy), "LONG", 0, 0)
							next
							this_value5 = evsMemToStr((Pointer2Buffer + 20), (this_value0 - 20))
							this_value = StrCat(this_value1, ",", this_value2, ",", this_value3, ",", this_value4, ",", this_value5)
						endif
						if WFInfoClass == 14
							this_value1 = IntControl(32, Pointer2Buffer, "LONG", 0, 0)
							this_value2 = ""
							for yy = 2 to 5
								if this_value2 != "" then this_value2 = StrCat(this_value2, ".")
								temp_value = IntControl(32, (Pointer2Buffer + 4 + yy), "BYTE", 0, 0)
								if temp_value < 0 then temp_value = (256 + temp_value)
								this_value2 = StrCat(this_value2, temp_value)
							next
							this_value = StrCat(this_value1, ",", this_value2)
						endif
						if (WFInfoClass == 15) || (WFInfoClass == 26)
							for yy = 0 to 2
								this_value%yy% = IntControl(32, (Pointer2Buffer + 4 * yy), "LONG", 0, 0)
							next
							this_value = StrCat(this_value0, ",", this_value1, ",", this_value2)
						endif
						if WFInfoClass == 16
							this_value = ""
							for yy = 0 to 56 by 8
								if this_value != "" then this_value = StrCat(this_value, ",")
								temp_value = IntControl(32, (Pointer2Buffer + yy), "LONG", 0, 0)
								this_value = StrCat(this_value, temp_value)
							next
						endif
						if WFInfoClass == 17
							this_value1 = IntControl(32, Pointer2Buffer, "LONG", 0, 0)
							this_value2 = IntControl(32, (Pointer2Buffer + 4), "LONG", 0, 0)
							this_value3 = ""
							for yy = 0 to this_value2 - 1
								temp_value = IntControl(32, (Pointer2Buffer + 8 + ( yy * 8) ), "LONG", 0, 0)
								temp_value = Num2Char(temp_value)
								this_value3 = StrCat(this_value3, temp_value)
							next
							this_value = StrCat(this_value1, ",", this_value2, ",", this_value3)
						endif
						if WFInfoClass == 23
							for yy = 0 to 5
								this_value%yy% = IntControl(32, (Pointer2Buffer + 4 * yy), "LONG", 0, 0)
							next
							this_value0 = evsMemToStr(this_value0, 128)
							this_value1 = evsMemToStr(this_value1, 128)
							this_value6 = ""
							for yy = 2 to 5
								if this_value6 != "" then this_value6 = StrCat(this_value6, ".")
								temp_value = IntControl(32, (Pointer2Buffer + 24 + yy), "BYTE", 0, 0)
								if temp_value < 0 then temp_value = (256 + temp_value)
								this_value6 = StrCat(this_value6, temp_value)
							next
							this_value = StrCat(this_value0, ",", this_value1, ",", this_value2, ",", this_value3, ",", this_value4, ",", this_value5, ",", this_value6)
						endif
						if (WFInfoClass == 24) || (WFInfoClass == 25)
							for yy = 0 to 2
								this_value%yy% = IntControl(32, (Pointer2Buffer + 4 * yy), "LONG", 0, 0)
								this_value%yy% = evsMemToStr(this_value%yy%, 128)
							next
							this_value = StrCat(this_value0, ",", this_value1, ",", this_value2)
						endif
						if WFInfoClass == 27
							this_value = ""
							for yy = 0 to 32 by 8
								if this_value != "" then this_value = StrCat(this_value, ",")
								temp_value = WinFiletimeToSystemTime(Pointer2Buffer + yy)
								this_value = StrCat(this_value,temp_value)
							next
						endif
						break
				end select
				str_return = StrCat(str_return, this_value)
				DllCall(dll_handle, void:"WFFreeMemory", LONG:Pointer2Buffer)
			endif
			BinaryFree(pBytesReturned)
			BinaryFree(ppBuffer)
		endif
	next
	DllFree(dll_handle)
	return str_return
#EndFunction

#DefineFunction evsMemToStr(p2Buffer, max_bytes)
	; Returns string data from null-terminated memory string at pointer
	mystring = ""
	str_end = p2Buffer + max_bytes
	while p2Buffer < str_end
		byte_val = IntControl(32, p2Buffer, "BYTE", 0, 0)
		if byte_val == 0 then break
		char = Num2Char(byte_val)
		mystring = strcat(mystring, char)
		p2Buffer = p2Buffer + 1
	endwhile
	if mystring == "" then mystring = "NULL"
	return mystring
#EndFunction

#DefineFunction WinFiletimeToSystemTime(p2Buffer)
	; Converts 8-byte windows time value at pointer to WinBatch-friendly human readable string
	FT = BinaryAlloc(8)
	FTL = BinaryAlloc(8)
	ST = BinaryAlloc(16)
	lobyte = IntControl(32, (p2Buffer + 0), "LONG", 0, 0)
	hibyte = IntControl(32, (p2Buffer + 4), "LONG", 0, 0)
	BinaryPoke4(FT,0,lobyte)
	BinaryPoke4(FT,4,hibyte)
	Kernel32 = strcat(dirwindows(1),"KERNEL32.DLL")
	X = DllCall(Kernel32,long:"FileTimeToLocalFileTime",lpbinary:FT,lpbinary:FTL)
	X = DllCall(Kernel32,long:"FileTimeToSystemTime",lpbinary:FTL,lpbinary:ST)
	Year = StrFixLeft(BinaryPeek2(ST,0),"0",4)
	Month = StrFixLeft(BinaryPeek2(ST,2),"0",2)
	Day = StrFixLeft(BinaryPeek2(ST,6),"0",2)
	Hour = StrFixLeft(BinaryPeek2(ST,8),"0",2)
	Minute = StrFixLeft(BinaryPeek2(ST,10),"0",2)
	Seconds = StrFixLeft(BinaryPeek2(ST,12),"0",2)
	BinaryFree(FT)
	BinaryFree(FTL)
	BinaryFree(ST)
	tcode = StrCat(Year,":",Month,":",Day,":",Hour,":",Minute,":",Seconds)
	return tcode
#EndFunction

Query = AskLine("Test", "Bitwise OR'd Functions", "32 | 64")
stuff = evsWFQuerySession(-1, Query)
Message("TEST",stuff)


Article ID:   W15431
File Created: 2003:05:13:11:27:42
Last Updated: 2003:05:13:11:27:42