http://bugs.winehq.org/show_bug.cgi?id=6880
------- Additional Comments From focht@gmx.net 2007-04-05 08:01 ------- Hello,
the main executable is wrapped by SecuRom 7.x software protection. The cause for games to fail with FT_* on NT based systems is quite simple: it's an additional braindamaged OS version check. Seems they dont trust standard ways reading CurrentVersion registry subkeys and GetVersion(Ex)() at all.
FT_Thunk() belongs to flat thunking API which is *only* supported and exported by Win9X kernel32 binaries. NT thunks (16 <-> 32 bit code) work quite different, it's called "generic thunking" there.
To work around this problem, wine's loader needs to be changed the way it returns API exports (e.g. GetProcAddress). There are some ways to do it:
1.) Add some additional .spec prototype hint (containing version hint) and compile a static list from .spec files (into some struct/array whatever) into wine code. This info gets checked against the export requested in kernel32 (GetProcAddress) or ntdll (LdrGetProcedureAddress). Return export address if allowed or not at runtime.
2.) Use dynamic list from some file. Read a list of OS dependant exports from config file when the loader initializes at runtime. This list contains exports which should never be returned to GetProcAddress() calls on specific winecfg OS version.
That way, such braindamaged code will work too. This applies to almost all SecuRom versions (and maybe other applications which employ similar code).
--- snip --- I've seen quite some applications that fail in the end like this one: 0009:Call kernel32.GetModuleHandleA(011bf1d4 "mscoree.dll") ret=00c5936f 0009:Ret kernel32.GetModuleHandleA() retval=00000000 ret=00c5936f Then ExitProcess. --- snip ---
This has nothing to do with this bug. The application uses dynamic msvc 7.1 runtime, which implicitly pulls mscoree.dll in.
Normally mscrt __crtExitProcess() calls just ExitProcess() but on newer versions a call to __crtCorExitProcess() is made to ensure proper shutdown of managed parts (even if you don't use managed = .NET code).
CorExitProcess() basically does this:
--- snip --- hModule = GetModuleHandle("mscoree.dll"); if (hModule != NULL) { pfn = (PFN_EXIT_PROCESS) GetProcAddress( hModule, "CorExitProcess"); if (pfn != NULL) pfn(status); } --- snip ---
If mscoree module or the export is not found it causes no harm. It works as designed.
The reason for this additional (implicit) shutdown code is you have no control whether a part of operation system or application dll (3rd party/injected) might pull in managed stuff thats why this code exists.
Regards