Terminal services

Hi all,
Im working with Delphi 6 and Im trying to use APIs of terminal services supplied by WIN2k.
The problem is: Delphi doesn't support this dll  wtsapi32.dll.
So Im trying to load the DLL alone and I need to know some consts value.
WTS_CURRENT_SESSION and WTS_CURRENT_SERVER_HANDLE

If anyone knows thier values or other way to make Delphi do that I'll be grateful

Thanks
JohnyAAsked:
Who is Participating?
 
raidosConnect With a Mentor Commented:
Really strange...

i get the same result you do..

so i tweaked around a little, and finally found what might be a solution.. =)

Var
  InfoClass : Integer;
Begin
  InfoClass := Integer(WTSClientAddress);
  PWTSQuerySessionInfo(.., .., TWTSInfoClass(InfoClass), .., ..);
End;

Seems odd, but it works.. =)

why this is different than defining InfoClass : TWTSInfoClass; i don't know, i just know it is somehow..

Regards
//raidos
0
 
Russell LibbySoftware Engineer, Advisory Commented:

// Wtsapi32 defined constants
const
  WTS_CURRENT_SERVER_HANDLE  =  0;
  WTS_CURRENT_SESSION        = -1;

-------

Russell
0
 
olovyanCommented:
You might take a look at
http://codecentral.borland.com/codecentral/ccweb.exe/download?id=16010. This is Terminal Services API ported to Delphi.
Cheers,
Vladimir.
0
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
olovyanCommented:
I misspelled the URL. Should be:
http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=16010
Sorry for the inconvenience.
0
 
JohnyAAuthor Commented:
Thank you friends,

olovyan comment is very usefull but I have a small problem
before I give the points,
when I use Wtsapi32.pas I cant run my project on NT without terminal services. it says UTIDLL in not found!!

0
 
olovyanCommented:
Indeed, the wtsapi32.dll requires utildll.dll and winsta.dll. As far as I know this DLL is ditributed with Windows XP and 2000.
0
 
JohnyAAuthor Commented:
This a problem because the software must run on all platforms and must know how to handle terminal services!!
do anyone have idea?
0
 
raidosCommented:
if it must run on all platforms you will have to use dynamic linking, the wtsapi32.pas doesn't do that, it uses static linking, so you need to write your own wtsapi32 that handles the functions you need...

Currently doing a bit of that myself..=/

Regards
//raidos
0
 
JohnyAAuthor Commented:
I already did it, but didnt succeed to run any function.
My code is:

const
   FN_WTS_API                = 'wtsapi32.dll';

   WTS_CURRENT_SERVER_HANDLE = THandle(0);
   WTS_CURRENT_SESSION       = DWORD(-1);

var
   _WTSQuerySession : function(     hndlServe     : THandle;
                                    iSessionID    : Dword;
                                    WTSInfoClass  : WTS_INFO_CLASS;
                                var pBuffer       : PWTS_CLIENT_ADDRESS;
                                var iBytes        : Dword) : BOOL; stdcall;


wtsHandle := LoadLibrary( FN_WTS_API);

@_WTSQuerySession := GetProcAddress( wtsHandle, 'WTSQuerySessionInformationA');

0
 
JohnyAAuthor Commented:
correction:
   _WTSQuerySession : function(     hndlServe     : THandle;
                                    iSessionID    : Dword;
                                    WTSInfoClass  : WTS_INFO_CLASS;
                                var pBuffer       : Pointer;
                                var iBytes        : Dword) : BOOL; stdcall;

sorry, my mistake.
The interesting thing that when I use GetLastError to find the failure reason I dont get!
0
 
raidosCommented:
Const
  WTS_CURRENT_SERVER = THandle(0);
  WTS_CURRENT_SESSION = DWORD(-1);

  wtsapilib = 'wtsapi32.dll';

Type
  _WTS_INFO_CLASS = (
    WTSInitialProgram,
    WTSApplicationName,
    WTSWorkingDirectory,
    WTSOEMId,
    WTSSessionId,
    WTSUserName,
    WTSWinStationName,
    WTSDomainName,
    WTSConnectState,
    WTSClientBuildNumber,
    WTSClientName,
    WTSClientDirectory,
    WTSClientProductId,
    WTSClientHardwareId,
    WTSClientAddress,
    WTSClientDisplay,
    WTSClientProtocolType);
  {$EXTERNALSYM _WTS_INFO_CLASS}
  WTS_INFO_CLASS = _WTS_INFO_CLASS;
  TWtsInfoClass = WTS_INFO_CLASS;

  PWTS_CLIENT_ADDRESS = ^WTS_CLIENT_ADDRESS;
  {$EXTERNALSYM PWTS_CLIENT_ADDRESS}
  _WTS_CLIENT_ADDRESS = record
    AddressFamily: DWORD;           // AF_INET, AF_IPX, AF_NETBIOS, AF_UNSPEC
    Address: array [0..19] of Byte; // client network address
  end;
  {$EXTERNALSYM _WTS_CLIENT_ADDRESS}
  WTS_CLIENT_ADDRESS = _WTS_CLIENT_ADDRESS;
  {$EXTERNALSYM WTS_CLIENT_ADDRESS}
  TWtsClientAddress = WTS_CLIENT_ADDRESS;
  PWtsClientAddress = PWTS_CLIENT_ADDRESS;
  TWTSQuerySessionInformation = Function (hServer: THandle; SessionId: DWORD; WTSInfoClass: TWtsInfoClass; var ppBuffer: Pointer; var pBytesReturned: DWORD): BOOL; stdcall;
 

Function Init;
Var
  WTSLibHandle : THandle;
  PWTSQuerySessionInfo : TWTSQuerySessionInformation;
Begin
  WTSLibHandle := LoadLibrary(wtsapilib);
  If WTSLibHandle <> 0 Then Begin
    PWTSQuerySessionInfo := GetProcAddress(WTSLibHandle, 'WTSQuerySessionInformationA');
    If @PWTSQuerySessionInfo <> Nil Then Begin
      ShowMessage('It is set up now, just use');
    End;
  End;
End;


No @PWTSQuerySessionInfo := GetProcAddress(....);
just when checking that it has been assigned.. =)

Regards
//raidos
0
 
JohnyAAuthor Commented:
raidos,
this is not working! the init is working good in both cases mine and your, but when I use the function it fails.
Did you try to run it? if so, let me know the syntax.
Thanks
Johny
0
 
raidosCommented:
This is my function.. =)

Function GetClientIPTS: String;
Var
  RetBytes : Cardinal;
  ppBuffer : Pointer;
  BWFClientAddress: TWTSClientAddress;
  Buf : Array[0..19] Of Char;
begin
  If Not Assigned(PWTSQuerySessionInfo) Then Exit;
  Result := '';
  RetBytes := 0;
  FillChar(BWFClientAddress,SizeOf(TWTSClientAddress),#0);
  ppBuffer := Nil;
  PWTSQuerySessionInfo(WTS_CURRENT_SERVER, WTS_CURRENT_SESSION, WTSClientAddress, ppBuffer, RetBytes);
  Move(ppBuffer^,BWFClientAddress,RetBytes);
  Move(BWFClientAddress.Address,Buf,19);
  If Ord(Buf[2]) = 0 Then
    Result := ''
  Else
    Result := Format('%d.%d.%d.%d',[Ord(Buf[2]),Ord(Buf[3]),Ord(Buf[4]),Ord(Buf[5])]);
End;

If you use it with my previous comment, you will need to move the PWTSQuerySessionInfo into a global variable.

PS, this is horrible code, you really should fix it up before you use it..=)

Regards
//raidos
0
 
JohnyAAuthor Commented:
raidos,

I tried to pass to PWTSQuerySessionInfo function a variable of type TWtsInfoClass (lets say with value of WTSClientAddress) and it is not working, but if I use WTSClientAddress directly it works!!

by the way it works both case :)
1. @PWTSQuerySessionInfo := GetProcAddress(....);
2. PWTSQuerySessionInfo := GetProcAddress(....);

Johny
0
 
raidosCommented:
Wierd...i'll try it..
.

oh...i didn't realize that..
0
 
JohnyAAuthor Commented:
sorry but it doesnt work here !
its very weird, but anyway you deserve the points
Thnak you
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.