Solved

Terminal services

Posted on 2002-04-24
16
1,220 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
 

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
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 

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

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

758 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

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now