About Terminal Server, Citrix, Delphi and other stuff
24 Feb
Just read a tweet from @andyjmorgan about Interactive Service Detection. This made me remember that it’s possible to switch to the Session 0 with an undocumented api in winsta.dll.
For this API to work you must have the Interactive Services Detection (UI0Detect) service running.
21 Oct
Yesterday I needed to set a few registry keys remotely from a 32 bit windows machine to a 64 bit machine.
I used reg.exe to set the key but even though it returned success the key wasn’t altered.
As I suspected the key was written to the Wow6432Node. In the help I couldn’t find any switch to force reg.exe to use the 64-bit view.
On a 64 bit machine this is not a problem since both 32- and 64 bit versions of reg.exe exists. The 32 bit version of reg.exe defaults to the 32 bit view and the 64 bit version defaults to the 64 bit view.
But luckily reg.exe has a switch (that is not listed in the help) to force the View:
16 Aug
Today I was reusing some old (pre vista) code the retrieves the Logon SID that I wrote a few years ago. The Logon SID is a special SID that identifies a logon session that has the form S-1-5-5-X-Y.
You can view your Logon SID with Process Explorer, right click a GUI process, select Properties and goto the Security Tab:
11 Aug
The GetTokenInformation function can be used with the TokenLinkedToken Information Class on Windows Vista and higher to the linked (Elevated) token.
This is useful when User Account Control is enabled and you want to launch an elevated process e.g. from a service.
This example code fails however when User Account Control is disabled:
|
1 2 3 4 5 6 7 8 9 |
if (bElevate)
{
ZeroMemory(&tlt, sizeof(tlt));
bResult = GetTokenInformation(hToken, TokenLinkedToken, &tlt, sizeof(tlt), &RetLength);
if (!bResult)
{
// Handle error here
}
} |
GetLastError() returns 1312 which is defined in winerror.h as ERROR_NO_SUCH_LOGON_SESSION with description “A specified logon session does not exist. It may already have been terminated.”
So you should check if User Account Control is enabled in such cases (or make this error non critical).
11 Aug
Snippet below can be used to programmatically determine if User Account Control is enabled:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
uses JwaWinbase, JwaWinNt; function IsUACEnabled: Boolean; var hToken: THandle; tet: TOKEN_ELEVATION_TYPE; dwSize: DWORD; begin Win32Check(OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, hToken)); // TokenElevationType class only available on Vista+ Win32Check(GetTokenInformation(hToken, TokenElevationType, @tet, SizeOf(tet), dwSize)); Result := tet <> TokenElevationTypeDefault; end; |
19 Jan
I just recorded a SasLibEx Screencast, it shows some of the very powerfull features of SasLibEx.
The following features are shown:
3 Jan
Have you developed an application that accesses files and may stop because a file cannot be accessed but you need to?
Since Windows Vista it is possible to find out the name of the application which holds open a file.
And we have created a solution for you that doesn’t require a driver, nor does it need Administrator rights! Just plain user source code for you to use instantly.
We have developed a solution in Delphi that can show your user which application stalls your application. Look at these screenshots:
In fact, these dialogs are only for demonstration purposes. But you can get them in addition as a Delphi project!
The code itself is fairly easy to use. We have developed an extension to the official IFileIsInUse Interface from Microsoft.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
type
IFileIsInUse = interface(IUnknown)
['{64a1cbf0-3a1a-4461-9158-376969693950}']
function GetAppName(out ppszName: LPWSTR) : HRESULT; stdcall;
function GetUsage(out pfut : FILE_USAGE_TYPE) : HRESULT; stdcall;
function GetCapabilities(out pdwCapFlags : DWORD) : HRESULT; stdcall;
function GetSwitchToHWND(out phwnd : HWND) : HRESULT; stdcall;
function CloseFile() : HRESULT; stdcall;
end;
IFileIsInUse2 = interface(IFileIsInUse)
['{C69C0E72-DCE2-474D-AC16-E31B77B526B3}']
function GetProcessID(out pdwProcessID : DWORD) : HRESULT; stdcall;
end; |
All you have to do it to call this function provides by us:
|
1 |
function GetFileInUseInfo(const FileName : WideString) : IFileIsInUse2; |
The name of the app is returned by the method GetAppName. And if the other application supports IFileIsInUse (call method GetCapabilities) interface you even can close the file or switch to the window.
You’ll see how it works in the demonstration project (images above) accompanied by the function GetFileInUseInfo.
Currently, we only offer a Delphi solution. C++ may available in future or when there’s enough demand for it.
Please use the Contact Form to get more information about how to obtain the solution and conditions.
19 Dec
I was cleaning up some old data on my Hard Drive when I found a program I wrote about a year ago.
At that time I was doing a project where I was deploying a Windows 2008 based Citrix Environment.
I wanted to get rid of the new Personal Folders or User’s files icon on the Desktop and replace it with the familiar My Documents icon.

These settings are stored in the Registry under HKEY_CLASSES_ROOT\CLSID\{folder’s GUID}\ShellFolder.
12 Sep
I have written a small commandline tool that shows the Active Directory Property Sheet for a given account.
The Property sheet is what you get when you doubleclick an object in Active Directory & Computers. Basically this tool is meant to make it easy to quickly view or change properties without needing to start a GUI tool and looking up the account in the AD Tree.
(more…)
15 Jun
If you look into the registry in the key HKLM\System\CurrentControlSet\ProductOptions you will find several licensing related Values.
The ProductType and ProductSuite keys contain the OS Suite and Edition, but the ProductPolicy key is much more interesting. So let’s have a closer look at it, open RegEdit and DoubleClick the key, you will something like the screenshot below, a Binary Value:
As you can see the license names are there as a Unicode string and later on I will show you how we can read the values. But because I didn’t want to extract all the names manually I decided to see if I could reverse the used structure because it didn’t look very complicated. Using a Hex Editor I could determine the important part of the structure.
Active Directory Altiris Automation Manager bug Citrix Dell Delphi Exchange Exchange2003 Exchange2010 Hack Hewlett-Packard HP iOS Jailbreak Java LinkedIn Linux Lync McAfee MSI MySQL Navigation Objects Office Outlook Passat Password PowerPoint PowerShell RES RNS315 RNS510 SasLibEx Terminal Server ThinApp TSAdminEx VBS VCDS Vista VMWare Volkswagen Windows PE Wordpress XenApp
WP Cumulus Flash tag cloud by Roy Tanck requires Flash Player 9 or better.