Getting to run some delphi program with wine under linux

Maybe you have an Windows program, but you don’t want to start your Windows virtual machine (or boot into Windows) everytime to use it. There is wine which provides a compatibility layer for Windows programs so that they can run on Linux and other operating systems.

However, not all programs run out of the box with wine. There is an application database that gives you some hints or overview, what you can expect when you try to run this application with wine. But there will be no entry of course, if your program is not very common.

So here’s a step by step guide, to get a program running with one specific problem: It crashes and it can be solved by adding a native DLL. It turns out, that the crash error is a common error for programs written in Delphi. Seems like Delphi uses special functions of the Windows GUI libraries that Wine didn’t implement yet.

  1. Install wine. Don’t use your distribution’s package - it’s likely to be older. Download Wine from their homepage and follow the instructions to install.

  2. Try to run the program. In my case, the executable is called “Time.exe”: wine Time.exe

  3. The program crashes, you’ll notice it.

Crash Dialog

Additionally some error messages appear in the console:

err:ole:CoGetClassObject class {00000514-0000-0010-8000-00aa006d2ea4} not registered
err:ole:create_server class {00000514-0000-0010-8000-00aa006d2ea4} not registered
err:ole:CoGetClassObject no class object {00000514-0000-0010-8000-00aa006d2ea4} could be created for context 0x5
wine: Unhandled exception 0x0eedfade in thread 9 at address 0x7bcd6000:0x7b43b6bc (thread 0009), starting debugger...
err:seh:setup_exception_record stack overflow 1088 bytes in thread 0009 eip 7bc45856 esp 00230ef0 stack 0x230000-0x231000-0x330000

It appears that 0x0eedfade is an exception code, if Delphi calls some Windows API and the API returns with an failure. See Debug Channels documentation for “Structured Exception Handling”:

These are invoked either when an application performs an illegal operation (i.e. crashes), or if a program throws its own exceptions. Wine converts UNIX signals into SEH exceptions and outputs them using this channel. This can be useful because applications will often trap their own crash, in order to perform an emergency save for instance. The most common exception to watch for is STATUS_ACCESS_VIOLATION or 0xC0000005 which is the closest equivalent in Win32 to a segfault. You may also see codes which don’t appear in the headers; these are typically language-specific exceptions used by whichever compiler was used to produce the EXE. E.g. 0xEEDFADE is the code for a Delphi internal exception, and 0xE06D7363 is a Microsoft Visual C++ exception, which has a magic value ({{{info[0]}}}) of 0x19930520, which is easy to remember because it looks like a date (and probably is). If you see any of these exceptions, it probably means a Win32 API call returned a non-zero error code somewhere.

So, 0x0eedfade means, an internal Delphi exception occurred.

The lines above display some GUID that is not registered: 00000514-0000-0010-8000-00aa006d2ea4. A search for this leads to some COM+ APIs and finall to this forum entry. This suggests to install the DLL for “mdac28”, which is part of Microsoft Data Access Components.

The simplest way to install this DLL is using winetricks:

wget https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks
sh winetricks mdac28

After that, the application runs:

Time 2.0

But, how can you now, whether it’s really a Delphi application? Look at the output of strings Time.exe |egrep "TObject|Delphi|Borland"|sort|uniq:

Delphi%.8X
Delphi Component
Delphi Picture
Software\Borland\Delphi\Locales
SOFTWARE\Borland\Delphi\RTL
Software\Borland\Locales
TObject
TObject
TObjectField
TObjectList
Andreas Dangel | subscribe via RSS | adangel | © Copyright 2018. adangel.org (26 May 2018)