[Bug 6880] Stronghold 2/Legends do not start in win2k/xp mode

Wine Bugs wine-bugs at winehq.org
Fri May 4 08:01:17 CDT 2007


http://bugs.winehq.org/show_bug.cgi?id=6880





------- Additional Comments From focht at 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

-- 
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug, or are watching the assignee.



More information about the wine-bugs mailing list