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 »
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.
08 Jan
Posted by: Remko in: JEDI Windows Security Code Lib
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;
16 Dec
Posted by: Christian Wimmer in: Common
… to be called before CoRegisterClassObject, which can be called indirectly by Application.Initialize.
You can see this comment at the beginning of a newly created service application. Unfortunately, today it is only half of the truth.
16 Nov
Posted by: Christian Wimmer in: JEDI Windows Security Code Lib
I have updated JWSCL Version 0.9.2a to support Windows 7. Version 0.9.3 supports Windows 7 from the beginning but since many people use 0.9.2a, I have decided to merge Windows 7 support.
If you look at the MSDN documentation of CreateProcess you might notice the following remark for the lpCommandLine parameter:
The Unicode version of this function, CreateProcessW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation.
This means that when you move over to Unicode (Delphi 2009/2010) existing code might produce an Access Violation.
This code for example will produce an Access Violation:
To prevent these kinds of Access Violation we could change the declaration of the lpCommandLine parameter as var. This prevents passing nil though (which is allowed).
So if we want to allow passing nil but not a constant we should declare 2 overloaded functions:
and
I choose PByte in the second declaration because it allows for nil but disallows PChar(’notepad.exe’) which will also AV.
So what do you think? Should we change this in Jwa?
Have you every wondered why 16bit applications cannot run on 64bit? Read the rest of this entry »
There is a design pattern called Singleton that usually applies only to classes. But imho it can also be applied to applications to prevent the user from starting several instances of the application. I came along this article on DelphiAboutCom which shows how to create a single instance application. Unfortunately it doesn’t work.
Windows 7 is released but its version is called 6.1 instead of 7. Well, the reason behind this is experience.
23 Sep
Posted by: Christian Wimmer in: Common, JWA Downloads, JWSCL Downloads
JEDI Windows API (JWAL) and JEDI Windows Security Library (JWSCL) are now available in version 2.3 and 0.9.3. They support Delphi 2010.
You can download them or use the new Subversion branches.
| M | T | W | T | F | S | S |
|---|---|---|---|---|---|---|
| « Jan | ||||||
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |