Remko Weijnen's Blog (Remko's Blog)

About Virtualization, VDI, SBC, Application Compatibility and anything else I feel like

Archive for the ‘Delphi’ Category

How Outlook and Exchange handle Timezones

Again an old war story, this time about timezone handling in Outlook/Exchange.

I am not sure which year it was but I had just started to work for a new company and inherited an Exchange 5.5 Server.

The mail had been migrated from an earlier version and calendar data was migrated from Schedule+.

On the first change to Daylight Savings (DTS) all recurring appointments where shown one hour later (or earlier can’t remember) in Outlook. A manual change was not an option: there were over 2000 mailboxes each with a lot of appointments.

We first tried a workaround by disabling DTS on the the workstations and then manually change the time when changing from and to DTS. 

But this influenced the timestamps on externals mails and of course appointments with external parties.

After a lot of (and I really mean a lot) of researching I found that Outlook stores all times in an appointment as relative (UTC) time.

Upon display it uses an undocumented TimeZone descriptor field to convert to Local Time.



If you want to check if you are running on a Server Core edition of Windows you can use the GetProductInfo API.

GetProductInfo takes 4 input parameters that can be obtained using GetVersionEx and the OSVERSIONINFOEX structure:

No we call GetProductInfo:




In the previous parts (part 1 part 2) i’ve described the theoretical part and implementation problems. So, now we can write the code:

1) In case we login the user, we just call LsaLogonUser to get the token:

In part 1 I’ve described the theoretical parts needed for a custom autologon application implementation.

But there are some practical problems which I will describe here.

1) I use the LsaLogonUser function to log in the user. However, if I do not pass not null for the LocalGroups parameter, msgina.dll fails to process the logon.

Why? Because it looks for the SE_GROUP_LOGON_ID SID and treat it as logon SID. So we have to add the logon SID manually:

Windows XP introduced the ability to use Fast User Switching (FUS from here on), which is implemented using Terminal Services.

But in some cases (i.e. when FUS is not enabled, or when you connect to the console in Windows 2003 server), the Winlogon process in an RDP session needs to transfer credentials to Session 0.

Although not documented in MSDN, the process of transferring credentials is described by Keith Brown in the June 2005 issue of MSDN magazine: Customizing GINA, Part 2.

WlxQueryConsoleSwitchCredentials and WlxGetConsoleSwitchCredentials are used in the transfer with the semi-documented WLX_SAS_TYPE_AUTHENTICATED SAS code constant.

Internally, winlogon.exe uses a Named Pipe, \\.\Pipe\TerminalServer\AutoReconnect, to implement both of these functions.

The pipe format is described in this structure:

If you want to obtain a user’s token in a Terminal Server or Citrix session (eg to launch a process in a session) you can call the WTSQueryUserToken function.

On the x64 versions of Windows XP and Server 2003 this function fails however and returns ERROR_INSUFFICIENT_BUFFER (“The data area passed to a system call is too small.”) when called from a 32 bit process.

Internally WTSQueryUserToken calls the undocumented function WinstationQueryInformationW with the WinStationUserToken class (14) and passing a WINSTATIONUSERTOKEN struct, filled with caller ProcessId and ThreadId.

But on x64 Windows the size of this structure is 24 bytes, while on 32 bit Windows the size of the structure is 12 bytes!


Determine the System Page Size

Just a quick note: if you want to determine the page size of the OS (Windows) you can use the GetSystemInfo function.


Note that MSDN recommends to use the GetNativeSystemInfo function when running in a 32 bit app on an x64 OS (and you can use the IsWow64Process function to determine that).

One example where you need to know the PageSize is when you want to create a Paging File using the NtCreatePagingFile function because this function requires that the MinimumSize and MaximumSize parameters are a multiple of the PageSize.

Some interesting links on the subject:

As you may know, you can enumerate processes of a specific Terminal Server or Citrix session using the NtQuerySystemInformation function.

On x86 system the code below works fine:

While this works fine on Windows XP and 2003 x86, it fails to work correctly on the x64 versions of Windows XP and 2003 (or maybe even higher).

The problem is that RetLength is always SizeOf(SYSTEM_SESSION_PROCESS_INFORMATION) and thus we are in an endless loop!


Convert Drive Bitmask to Drive Letter

I was writing a test program that will perform some actions when a USB Memory Stick is inserted.

When this happens Windows send a Broadcast a WM_DEVICECHANGE message.

The wParam member of this Message contains a (pointer to) a DEV_BROADCAST_HDR structure.

if the dbch_devicetype member of this structure is of type DBT_DEVTYP_VOLUME then we can cast the structure to DEV_BROADCAST_VOLUME.

And finally the dbcv_unitmask member of that structure returns a Bitmask containing the Drive Letter.

A fast and convenient method to convert this Bitmask to a Drive Letter (the first found) is the function below:

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.

All you have to do it to call this function provides by us:

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.