Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi WinStationShadow API Function (https://www.delphipraxis.net/81827-winstationshadow-api-function.html)

Remko 4. Dez 2006 16:01


WinStationShadow API Function
 
Sorry for writing in English, I can read and write some German but its not sufficient to describe my question.
I'm looking for any info on how to use the WinStationShadow function from Winsta.dll to incorporate an option to shadow a users sessions from my app. Currently I use shadow.exe with commandline params but this isn't really nice.
Both tsadmin.exe and shadow.exe seem to use winsta.dll functions WinStationShadow and WinStationShadowStop which presumably use 2 structures _WinStationShadowTarget and/or _WinStationShadowTargetSetup.

Luckie 4. Dez 2006 17:55

Re: WinStationShadow API Function
 
Maybe this can help you: http://www.michael-puff.de/dirindex..../Importe/Nico/ -> winwlx.zip "Interface for the Microsoft WinLogon eXtention (WLX) API for Delphi"
If that doen't help try to contact Olli. He might be the only person who can help you.

Remko 4. Dez 2006 18:59

Re: WinStationShadow API Function
 
WinWlx doesn't contain the function or any pointers in the right direction. I agree with you that Olli could probably help, but I already asked him ;-) and he's very busy right now. He helped me before with other functions from Winsta.dll to get idle and login time from terminal server sessions.

Remko 11. Dez 2006 13:35

Re: WinStationShadow API Function
 
I did find out some more, just posting it here to share my information. Perhaps someone knows the next step?
Starting a Remote Control from TSAdmin.exe, accepting this from the client and exiting remote control executes these API functions:

Code:
API Name                    Return Value        Module Name
WinStationOpenServerW       808544 (0xC5660)    WINSTA.dll
Before Call Parameters
Pointer Paramter0: 2542716 (0x26CC7C)
Pointer Paramter1: (null)
Pointer Paramter2: 12367680 (0xBCB740)
Pointer Paramter3: 2 (0x2)
Pointer Paramter4: 7 (0x7)
Pointer Paramter5: 1 (0x1)
After Call Parameters
Pointer Paramter0: 2542716 (0x26CC7C)
Pointer Paramter1: (null)
Pointer Paramter2: 12367680 (0xBCB740)
Pointer Paramter3: 2 (0x2)
Pointer Paramter4: 7 (0x7)
Pointer Paramter5: 1 (0x1)
Return
808544 (0xC5660)

API Name                    Return Value        Module Name
WinStationShadow            1 (0x1)             WINSTA.dll
Before Call Parameters
Pointer Paramter0: (null)                 <-------------- unknown
Pointer Paramter1: 2542716 (0x26CC7C)     <-------------- not sure, handle to server or some unknow structure? == Param0 from WinStationOpenServerW
Pointer Paramter2: 3 (0x3)                <-------------- sessionid
Pointer Paramter3: 106 (0x6A)             <-------------- keycode for stopping the remote control (VK_MULTIPLY = 6A)
Pointer Paramter4: 2 (0x2)                <-------------- plus key (shift=1, ctrl=2, alt =4)
Pointer Paramter5: (null)                 <-------------- unknown
After Call Parameters
Pointer Paramter0: (null)
Pointer Paramter1: 2542716 (0x26CC7C)
Pointer Paramter2: 3 (0x3)
Pointer Paramter3: 106 (0x6A)
Pointer Paramter4: 2 (0x2)
Pointer Paramter5: (null)
Return
1 (0x1)                                   <--------------- Boolean or error/result code?


WinStationQueryInformationW 1 (0x1)             WINSTA.dll
Before Call Parameters
Pointer Paramter0: 808544 (0xC5660)
Pointer Paramter1: 3 (0x3)
Pointer Paramter2: 8 (0x8)
Pointer Paramter3: 451472 (0x6E390)
Pointer Paramter4: 1216 (0x4C0)
Pointer Paramter5: 452704 (0x6E860)
After Call Parameters
Pointer Paramter0: 808544 (0xC5660)
Pointer Paramter1: 3 (0x3)
Pointer Paramter2: 8 (0x8)
Pointer Paramter3: 451472 (0x6E390)
Pointer Paramter4: 1216 (0x4C0)
Pointer Paramter5: 452704 (0x6E860)
Return
1 (0x1)

API Name                    Return Value        Module Name
WinStationCloseServer       1 (0x1)             WINSTA.dll
Before Call Parameters
Pointer Paramter0: 808544 (0xC5660)
Pointer Paramter1: 454720 (0x6F040)
Pointer Paramter2: 1701515922 (0x656B1292)
Pointer Paramter3: 808544 (0xC5660)
Pointer Paramter4: (null)
Pointer Paramter5: 12367680 (0xBCB740)
After Call Parameters
Pointer Paramter0: 808544 (0xC5660)
Pointer Paramter1: 454720 (0x6F040)
Pointer Paramter2: 1701515922 (0x656B1292)
Pointer Paramter3: 808544 (0xC5660)
Pointer Paramter4: (null)
Pointer Paramter5: 12367680 (0xBCB740)
Return
1 (0x1)

Remko 12. Dez 2006 15:25

Re: WinStationShadow API Function
 
Just posting my progress:
const SERVERNAME_CURRENT: HWND = THandle(Nil);
const LOGONID_CURRENT: ULONG = ULong(-1);

function WinStationShadow(hServer: Handle; ActiveSessionID: ULong; SessionID: ULONG; KeyCode: ULong; KeyModifier: ULong): Boolean; stdcall; // ActiveSessionID can be LOGONID_CURRENT, hServer can be LOGONID_CURRENT

function WinStationConnectW(hServer: HANDLE; ConnectSessionID: ULong; ActiveSessionID: ULong; pPassword: PWideChar; Unknown: ULong): boolean; //Unknown seems to be always 0

Remote Control is working, stopping it isn't working yet. Current thoughts on how to proceed:
use OnStateChangeEvent, when fired check state of shadowed session (not WTSShadow), if so use WinStationShadowStop function (parameters unknown).

Remko 18. Dez 2006 09:10

Re: WinStationShadow API Function
 
Liste der Anhänge anzeigen (Anzahl: 1)
Again updating some progress:
Got starting a remote control and ending it with the supplied hotkey working. See attachment for code.
Currently included functions:
  • WinStationConnect (connect to a disconnect session)
  • WinStationQueryInformation (get login and idle time from a session)
  • WinStationShadow (shadow another session)

Olli 19. Dez 2006 01:36

Re: WinStationShadow API Function
 
Nah, Remko. I told you the second parameter in WinStationShadow() must be a string (LPCWSTR or PWideChar respectively). So NULL (nil) will just be an empty string then ... no idea what should be the contents, though. But it's definitely a string param. Also remember I told you that WinStationShadowStop() takes 3 parameters (check your chat logs). I haven't found out what the third parameter is, though. Use ULONG and 0 now. But if you declare it with two parameters only your stack will be unbalanced after every call!!!!

Code:
BOOLEAN __stdcall WinStationShadow(HANDLE hServer, LPCWSTR lpwszUnknownString, ULONG SessionID, ULONG KeyCode, ULONG KeyModifier);
BOOLEAN __stdcall WinStationShadowStop(HANDLE hServer, ULONG SessionID, int);
-1 for the session ID will cause the function to retrieve the default value of the current process' WindowStation from Teb.Peb.Win32WindowStation

Code:
mov    eax, large fs:18h ; TEB
mov    eax, [eax+30h] ; TEB.Peb
mov    eax, [eax+1D4h] ; PEB.Win32WindowStation
NULL for the hServer parameter causes the function to call the (non-exported) function WinStationOpenLocalServer() and retrieve the handle to the local server.

:mrgreen: :zwinker:

Remko 19. Dez 2006 07:40

Re: WinStationShadow API Function
 
Olli,

I made a type in the mail I sent you, what I meant to say is:
I misinterpreted WinStationShadowStop, I was thinkin way too complicated. We don't need to watch for session state change event and call WinStationShadowStop manually. When you press the hotkey it's done for you. So this function is only there if you want to stop remote control programmatically (why would one want to do that, the app that started is invisible?).
When I pass a PWideChar as second parameter for WinStationShadow nothing happens (no remote control), when I pass ULONG 0 it works.
If you look at the documentation from Citrix's Shadow API (actually windows terminal server API's are based on the winframe API's):

BOOL WINAPI WFShadowSessionW(
IN LPWSTR pServerName,
IN ULONG SessionID,
IN ULONG HotKey,
IN ULONG HKModifier,
);

There Servername is passed instead of a handle, so I tried passing ServerName as the second parameter. Nothing happens.

When I look at the Shadow.exe commandline utility, this is the syntax:
SHADOW {sessionname | sessionid} [/SERVER:servername] [/V]

sessionname Identifies the session with name sessionname.
sessionid Identifies the session with ID sessionid.
/SERVER:servername The server containing the session (default is current).
/V Display information about actions being performed.

So perhaps the string could be sessionname? That would make sense, either supply sessionname or sessionid. The other thing is that parameter 1 from WinStationOpenServerW seems to be equal to our parameter 2.

Remko 19. Dez 2006 09:27

Re: WinStationShadow API Function
 
Liste der Anhänge anzeigen (Anzahl: 1)
I did some tests with giving sessionname (eg RDP-Tcp#20) as 2nd parameter, doesn't seem to work. Then I tried with servername, if I specify either computername or IP then remote control works. My tests so far where all on a single server, so this parameter makes it possible to shadow a session on another server. This is probably needed because as Olli determined WinSta actually calls _RpcWinStationShadow. So servername is needed for the RPC part, hServer is probably needed to send the user a message ("domain\user wants to remote control, do you accept?").

So this is it:
function WinStationShadow(hServer: Handle; pServerName: PWideChar; SessionID: ULONG; HotKey: ULong; HKModifier: ULong): Boolean; stdcall;

Tested this with a remote server and it works! For local server you can supply Empty String or Nil that's why it working with ULONG 0.

So could param 3 for WinStationShadowStop also be Servername?
I will also have to test WinStationConnectW as the Unknown ULONG there could also be Servername.

Olli 19. Dez 2006 12:33

Re: WinStationShadow API Function
 
Zitat:

Zitat von Remko
When I pass a PWideChar as second parameter for WinStationShadow nothing happens (no remote control), when I pass ULONG 0 it works.

Pass nil or an empty string. Both are supposed to yield the default behavior you get with ULONG and 0.

Zitat:

Zitat von Remko
So could param 3 for WinStationShadowStop also be Servername?
I will also have to test WinStationConnectW as the Unknown ULONG there could also be Servername.

Yap, test it.

Since RpcWinStationShadow() gets called and it calls MSDN-Library durchsuchenNdrClientCall2(), a badly documented function from RPCRT4.dll, it will be a pain to analyze it in depth. But at least I can tell you the parameters which are passed during that call (the first two and the variable ones). But still it depends on the other side what it does with it, so finding that out is not worth much.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:17 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz