Solved

Terminal services

Posted on 2002-04-24
16
1,233 Views
Last Modified: 2010-05-18
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
0
Comment
Question by:JohnyA
  • 7
  • 5
  • 3
  • +1
16 Comments
 
LVL 26

Expert Comment

by:Russell Libby
ID: 6966253

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

-------

Russell
0
 

Expert Comment

by:olovyan
ID: 6967137
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
 

Expert Comment

by:olovyan
ID: 6967144
I misspelled the URL. Should be:
http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=16010
Sorry for the inconvenience.
0
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

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

 

Author Comment

by:JohnyA
ID: 6967856
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
 

Expert Comment

by:olovyan
ID: 6967868
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
 

Author Comment

by:JohnyA
ID: 6967989
This a problem because the software must run on all platforms and must know how to handle terminal services!!
do anyone have idea?
0
 
LVL 3

Expert Comment

by:raidos
ID: 6968306
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
 

Author Comment

by:JohnyA
ID: 6968322
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
 

Author Comment

by:JohnyA
ID: 6968325
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
 
LVL 3

Expert Comment

by:raidos
ID: 6968367
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
 

Author Comment

by:JohnyA
ID: 6968418
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
 
LVL 3

Expert Comment

by:raidos
ID: 6968533
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
 

Author Comment

by:JohnyA
ID: 6968641
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
 
LVL 3

Expert Comment

by:raidos
ID: 6968660
Wierd...i'll try it..
.

oh...i didn't realize that..
0
 
LVL 3

Accepted Solution

by:
raidos earned 50 total points
ID: 6968747
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
 

Author Comment

by:JohnyA
ID: 6968798
sorry but it doesnt work here !
its very weird, but anyway you deserve the points
Thnak you
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

821 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question