I have a .com application that is calling out to dos int21 4Bh to load and execute a program. MZ_Exec assumes this program is always going to be a dos executable and the application fails to run and complains that it is a pe executable. So I've started to try and add support for correctly handling pe executables. So far I have a patch like below but I'm thinking that a lot more needs to be done in order to fulfill the dos requirements of this function and kind of wanted some opinions on this. This compiles but I haven't tested it since the program is at work, just wanted to get some feedback.
Thanks, Chris
Index: dlls/winedos/module.c =================================================================== RCS file: /home/wine/wine/dlls/winedos/module.c,v retrieving revision 1.21 diff -u -r1.21 module.c --- dlls/winedos/module.c 30 Aug 2002 00:03:25 -0000 1.21 +++ dlls/winedos/module.c 22 Sep 2002 03:28:00 -0000 @@ -39,6 +39,7 @@ #endif #include "windef.h" #include "wine/winbase16.h" +#include "wine/winbase.h" #include "wingdi.h" #include "winuser.h" #include "winerror.h" @@ -342,16 +343,29 @@ */ BOOL WINAPI MZ_Exec( CONTEXT86 *context, LPCSTR filename, BYTE func, LPVOID paramblk ) { + enum binary_type binType; + STARTUPINFOA st; + PROCESS_INFORMATION pe; + BOOL status; + /* this may only be called from existing DOS processes * (i.e. one DOS app spawning another) */ - /* FIXME: do we want to check binary type first, to check - * whether it's a NE/PE executable? */ HANDLE hFile = CreateFileA( filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); BOOL ret = FALSE; + + binType = MODULE_GetBinaryType(hFile); + if (hFile == INVALID_HANDLE_VALUE) return FALSE; switch (func) { case 0: /* load and execute */ + if(binType == BINARY_PE_EXE) + { + ZeroMemory (&st, sizeof(STARTUPINFOA)); + st.cb = sizeof(STARTUPINFOA); + status = CreateProcessA (NULL, filename, NULL, NULL, FALSE, + 0, NULL, NULL, &st, &pe); + } case 1: /* load but don't execute */ { /* save current process's return SS:SP now */
"Chris Morgan" cmorgan@alum.wpi.edu wrote:
I have a .com application that is calling out to dos int21 4Bh to load and execute a program. MZ_Exec assumes this program is always going to be a dos executable and the application fails to run and complains that it is a pe executable. So I've started to try and add support for correctly handling pe executables.
If that is what Windows really does, then your approach is certainly right. Did you check how Windows does behave in that case?
So far I have a patch like below but I'm thinking that a lot more needs to be done in order to fulfill the dos requirements of this function and kind of wanted some opinions on this. This compiles but I haven't tested it since the program is at work, just wanted to get some feedback.
- binType = MODULE_GetBinaryType(hFile);
Why not call GetBinaryTypeA here? It will be much cleaner and will not break DLL separation.
Dmitry Timoshkov wrote:
"Chris Morgan" cmorgan@alum.wpi.edu wrote:
I have a .com application that is calling out to dos int21 4Bh to load and execute a program.
<snip>
If that is what Windows really does, then your approach is certainly right.
<more snippage>
Would it not be better (at least under Linux) to simply allow the normal OS load process to handle this? Since Linux can be configured to directly call Wine to run DOS/Windows binaries, the would allow them to run normally, plus if you wished to replace the DOS program with an equivelent native program it would still work.
"David D. Hagood" wowbagger@sktc.net writes:
Would it not be better (at least under Linux) to simply allow the normal OS load process to handle this? Since Linux can be configured to directly call Wine to run DOS/Windows binaries, the would allow them to run normally, plus if you wished to replace the DOS program with an equivelent native program it would still work.
No, using CreateProcess() is much better. It handles Unix binaries just as well, and does the right thing for Windows binaries (passing startup info etc.)