252 views

This article is about how to retrieve the owner of a file. If you are experienced with some of the WinAPI security function this can be pretty easy. There are some problems that needs to be addressed though. The first one is the size of the security items like the SID name of the owner. Secondly, there is the possibility that a SID cannot be resolved to a human readable name at all. And thirdly, we need to check all the result values.

Read the rest of this entry »

542 views

Site Recommendation: Terminal Session and Desktops

Many Windows Programmers still have trouble when it comes to sessions, window stations and desktops. They frequently get mixed up and we can see a lot of question on the Internet about e.g. how to spawn processes in all logged-on user desktops (rather than sessions).  Hence, I have listed some articles that you can read to get a better understanding of such things like a Terminal Sessions.

Read the rest of this entry »

661 views

JWSCL and FreeAndNil Second Attempt

In my last article “Jwscl and FreeAndNil” there were some great comments on the source design. Oliver told me to use a guarded memory page so the memory is always invalid. With his information I wrote a source code that creates a pointer which always triggers an access violation.

Read the rest of this entry »

692 views

JWSCL and FreeAndNil

There is a lot of talking about the usage of FreeAndNil in destructors. I’ve never thought about it before so I used it quite often even in destructors. Although I don’t use it as a universal remedy function, it still seems to be a bad design: a thought shared by many leading Delphi experts.  Thus I refactored the destructors in JWSCL to accompany them.

Read the rest of this entry »

721 views

JWSCL Features Overview

I had some free time that I used to put together all the features JWSCL provides currently. There are some more features that are implemented by other tool classes or functions that I left out in favor of a good overview. A complete overview of all classes, methods and more gives you the documentation at http://jwscldoc.delphi-jedi.net.

So here are the feautures (You can look up the class names on the documentation page):

Read the rest of this entry »

972 views

Reminder to You

I had some trouble writing these lines because usually I do not want to publish criticism. But Oliver told me that it would be a good idea and I don’t want to disagree :) .

Read the rest of this entry »

392 views

ACTRL_ACCESS Diagram

I had some trouble with this rather complicated COM structure called ACTRL_ACCESS. So I post a diagram to show its design. Otherwise it would be a pity to leave it on my private hard drive.

Read the rest of this entry »

1,267 views

Programming Habits

I’m writing this article because I want to share programming habits with you. What habit did prove to be a good one for you? Share yours then, please. Read the rest of this entry »

405 views

I just commited (revision 843) a little bugfix that existed since revision 833. In TJwWTSSession.Create LocalFree was called (after StrConnect) without LocalAlloc. Since utildll.dll handles the memory allocation is it not needed at all.

[Update]
The fix is currently only available in the developer version repository (aka trunk) of Subversion.

674 views

I have just commited an updated version of my Terminal Server unit (revision 842) into SVN. I have done some tests on Windows 7 (a fix for Windows 7 was done in Jwa revision 830 btw) and all seems to work well.

Internally the Connect method of TJwTerminalServer verifies the connection to Terminal Server by reading some property. This is done because of a change in the API’s by Microsoft: opening a handle with WTSOpenServer to a nonexisting server actually returns a valid handle. I reported this as a bug to Microsoft some time ago and the “fixed it” by changing the documentation.

For those interested in the code: it is a class function called IsValidServerHandle which can be used to verify a handle returned by WTSOpenServer:

class function TJwTerminalServer.IsValidServerHandle(const hServer: THandle): Boolean;
var
  dwSize: DWORD;
  WinStaInfo: WINSTATIONINFORMATIONW;
begin
  { All Windows < Vista return 0 on Invalid handle }
  Result := hServer <> 0;

  { No need to continue if it's already invalid... }
  if not Result then
    Exit;

  { For Windows >= Vista we need to make a query to be sure
    A non valid connection will fail on WTSQuerySessionInformation and will
    return LastError RPC_S_SERVER_UNAVAILABLE }
  if (TJwWindowsVersion.IsWindowsVista(True)) or
    (TJwWindowsVersion.IsWindows2008(True)) then
  begin
    Result := WinStationQueryInformationW(hServer, 65536, WinStationInformation,
      @WinStaInfo, sizeof(WinStaInfo), dwSize) or (GetLastError() <> RPC_S_SERVER_UNAVAILABLE);
  end;
end;

A more visible change is the introduction of the Session function of TJwTerminalServer, with this function you can get all details for a specific session. It is meant for those cases where you need only one specific session and is of course far more efficient than enumerating all sessions, retrieving all sessions details and then finding the particular session in the SessionList.

The signature of the function is:

function TJwTerminalServer.Session(const SessionId: TJwSessionId = WTS_CURRENT_SESSION): TJwWTSSession;

Note that the parameter is default so you can call both:

Session := TS.Session;  // Retrieve the current Session

and

Session := TS.Session(1); // Retrieve the session with SessionId 1

It is important to understand the difference between Session and Sessions: where Session returns an instance of TJwWTSSession, SessionS returns a SessionList. This is especially important because Session works with a SessionId parameters and Sessions (being a TObjectList descendant) is accessed with by Index which is just the position in the ObjectList.

If a Session is not found an EJwsclWinCallFailedException will be raised so you’d better wrap the call into a try..except handler!

The last remark is that you, the caller, are responsible for freeing the object so a more complete sample would be like this:

var
  TS: TJwTerminalServer;
  Session: TJwWTSSession;
begin
  TS := TJwTerminalServer.Create;
  try
    try
      Session := TS.Session;
      try
        // Work with the session object
        ShowMessageFmt('Username=%s', [Session.Username]);
        Session.PostMessage('Hello from the Jedi guys!', 'Message', MB_OK);
      finally
        FreeAndNil(Session);
      end;
    except
      // Handle Exception here!
    end;
  finally
    FreeAndNil(TS);
  end;
end;

Paypal donation (EUR)

Amount:
Website(Optional):

Archives

 

March 2010
M T W T F S S
« Feb    
1234567
891011121314
15161718192021
22232425262728
293031