http://bugs.winehq.org/show_bug.cgi?id=33092
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Keywords| |download Status|UNCONFIRMED |NEW URL| |http://assets.celemony.com/ | |demos/MelodyneDemo/3.2/Melo | |dyne.Demo.3.2.1.5.Setup.exe CC| |focht@gmx.net Component|-unknown |kernel32 Summary|Melodyne Studio demo |Melodyne Studio demo |crashes on startup |crashes on startup due to | |kernel32 forwarding some | |16-bit API to krnl386.exe16 Ever Confirmed|0 |1
--- Comment #5 from Anastasius Focht focht@gmx.net 2013-10-03 07:05:26 CDT --- Hello folks,
please don't attach application generated minidumps (.dmp), they are useless. Wine's own crash dialog -> "show details" -> "save as" -> attach the file.
Anyway ... the app uses Win9x era quick thunking for calling 16-bit API GetFreeSystemResources() to determine free system resources.
There are 3 problematic kernel32 forwards:
http://source.winehq.org/git/wine.git/blob/fa6b0580702b1cdcf97f64ac34b530956...
--- snip --- 45 35 stdcall -noname -i386 -private LoadLibrary16(str) krnl386.exe16.LoadLibrary16 46 36 stdcall -noname -i386 -private FreeLibrary16(long) krnl386.exe16.FreeLibrary16 47 37 stdcall -noname -i386 -private GetProcAddress16(long str) krnl386.exe16.GetProcAddress16 --- snip ---
I found an old C source file to illustrate what they do. It does not 100% match the actual app code but it gives you the idea.
Source: http://rtoss.googlecode.com/svn-history/TClock2ch/tc2ch/dll/sysres.c
--- snip --- void InitSysres(void) { if(bInitSysres) return;
bInitSysres = TRUE;
// if (VERSION != 9x) return; if(!(GetVersion() & 0x80000000)) return;
if(hmodKERNEL32 == NULL) hmodKERNEL32 = LoadLibrary("KERNEL32.dll"); if(hmodKERNEL32 == NULL) return;
LoadLibrary16 = (pfnLoadLibrary16)GetProcAddressByOrdinal(hmodKERNEL32, 35); FreeLibrary16 = (pfnFreeLibrary16)GetProcAddressByOrdinal(hmodKERNEL32, 36); GetProcAddress16 = (pfnGetProcAddress16)GetProcAddressByOrdinal(hmodKERNEL32, 37); QT_Thunk = (pfnQT_Thunk)GetProcAddress(hmodKERNEL32, "QT_Thunk"); if(LoadLibrary16 == NULL || FreeLibrary16 == NULL || GetProcAddress16 == NULL || QT_Thunk == NULL) { FreeLibrary(hmodKERNEL32); hmodKERNEL32 = NULL; return; }
hmodUSER16 = LoadLibrary16("USER.EXE"); if(hmodUSER16 < (HMODULE)32) { FreeLibrary(hmodKERNEL32); hmodKERNEL32 = NULL; hmodUSER16 = NULL; return; }
dwGetFreeSystemResources = GetProcAddress16(hmodUSER16, "GetFreeSystemResources"); if(dwGetFreeSystemResources == 0) { FreeLibrary(hmodKERNEL32); hmodKERNEL32 = NULL; FreeLibrary16(hmodUSER16); hmodUSER16 = NULL; } } --- snip ---
The import resolver:
--- snip --- /*------------------------------------------------ get a procedure address in DLL by ordinal --------------------------------------------------*/ FARPROC GetProcAddressByOrdinal(HMODULE hModule, int ord) { #ifdef _WIN64 UNREFERENCED_PARAMETER(hModule); UNREFERENCED_PARAMETER(ord); _ASSERTE(0); return 0;
#else IMAGE_NT_HEADERS *hdr; IMAGE_EXPORT_DIRECTORY *exp; DWORD *AddrFunc; WORD enewhdr, *pw; BYTE *moddb;
moddb = (BYTE *)hModule; pw = (WORD *) &moddb[0]; if (*pw != EMAGIC) return 0; pw = (WORD *) &moddb[ENEWHDR]; enewhdr = *pw; pw = (WORD *) &moddb[enewhdr]; if (*pw != PEMAGIC) return 0; hdr = (IMAGE_NT_HEADERS *) pw;
exp = (IMAGE_EXPORT_DIRECTORY *) (((DWORD_PTR) moddb) + ((DWORD_PTR) GET_DIR(IMAGE_DIRECTORY_ENTRY_EXPORT))); AddrFunc = (DWORD *) (moddb + (DWORD) exp->AddressOfFunctions);
ord--; if ((DWORD)ord < exp->NumberOfFunctions) return (FARPROC)( (ULONG_PTR)(moddb + AddrFunc[ord]) ); else return 0;
#endif _WIN64 } --- snip ---
$ du -sh Melodyne.Demo.3.2.1.5.Setup.exe 39M Melodyne.Demo.3.2.1.5.Setup.exe
$ sha1sum Melodyne.Demo.3.2.1.5.Setup.exe e8caa6acb5a02c99791f54558f4bd1daec143ca9 Melodyne.Demo.3.2.1.5.Setup.exe
$ wine --version wine-1.7.3-187-gec28040
Regards