wtsQuerySessionInfo & memory leak, any other options for app name?

Started by rgouette, April 09, 2015, 11:28:56 AM

Previous topic - Next topic

rgouette

Howdy, I'm wondering if anyone has discovered another means of getting the 'Application Name' from a T/S session , in light of
the below statement?


(s) Result[15] = Application Name. This is the published name of the application that this session is running.

Note: There is a memory leak in the underlying Win32 API function WTSQuerySessionInformation() that only occurs on WinXP & newer systems when the Application Name and Initial Program information items are retrieved. This extender function has been modified to not retrieve these values on WinXP & newer; the value "*UNSUPPORTED*" is returned in the appropriate array elements when this function is called on WinXP & newer systems.



Thanks much,
Rich


td

I am not sure how you might get that info.  I don't think there is anything in dotNet or WMI that will help.  I suppose you could try calling the TS API directly using DllCall. 
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

Ugly...
Code (winbatch) Select
; MemAddr - memory address
; nSize   - number of bytes allocated at MemAddr
#DefineFunction StrFromMemAddr(MemAddr, nSize)
   hBin = BinaryAlloc(nSize+1)
   DllCall("Kernel32.dll",long:"lstrcpynA",lpbinary:hBin, long:MemAddr, long:nSize)
   BinaryEODSet(hBin,nSize)
   strResult = BinaryPeekStr(hBin, 0, nSize)
   BinaryFree(hBin)
   return strResult ; ANSI string returned
#EndFunction

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Very quick and dirty example that likely doesn't server any useful purpose.
WTSApplicationName = 1
hServer = DllCall('Wtsapi32.dll', long:'WTSOpenServerA', lpstr:'.')
SessId = 1
hPtr = BinaryAlloc(4)
hBufSize = BinaryAlloc(4)
bResult = DllCall('Wtsapi32.dll', long:'WTSQuerySessionInformationA',long:hServer,long:SessId,long:WTSApplicationName,lpbinary:hPtr,lpbinary:hBufSize)
MemAddr =BinaryPeek4(hPtr,0)
strApp = StrFromMemAddr(MemAddr, BinaryPeek4(hBufSize,0))
DllCall('Wtsapi32.dll', long:'WTSFreeMemory',long:MemAddr)
BinaryFree(hBufSize)
BinaryFree(hPtr)

Message("Find Anything?", strApp)
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

ChuckC

And, of course, there's still the caveat that caused this thread to be started... even if DllCall() is used to call that API function directly, the memory leak is still going to occur in the process that is executing the WinBatch script.

td

Obviously, if the issue still exists in a newer version of Windows, it will still leak memory. But on modern systems it should not be a big issue, if the script is does not run for a protected period and/or make repeated calls.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

Also, Microsoft did issue a hotfix for the memory leak for Windows 2003/2008 and Vista.  Presumably, Windows 7, Window 2008 R2, and newer do not need a hotfix because the problem has been resolved. 
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

ChuckC

Ah, OK, so it might be worth putting the O.S. version check into the extender to determine if it is safe to make the API call, and if it is, then make the call and get the desired information instead of returning a value indicating the the API is unsupported.

td

It has been on the to-do list for some time but at low priority because no one has asked about it for about five years.  Since a user has asked about it again,  we will move it up a bit in priority.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade