Baron-von-Riedesel / HX

Home of the HX DOS Extender and its included DPMI-host HDPMI.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Fix OS/2 (NE 16bit) argument passing

roytam1 opened this issue · comments

There is some effort that improves HX:

Fix OS/2 (NE 16bit) argument passing
Ringdingcoder/hx-for-opus@704231a

Another OS/2 argument passing fix (DosExecPgm)
Ringdingcoder/hx-for-opus@c1a72c5

How can I test the fix(es)?

Invoke one OS/2 16bit NE from another one and pass some command line args.

The second patch (to DOSXXX) is pretty obvious because it destroys the ax register which is later used by scasb.

The other one is in the DPMI loader's interrupt hook. Your version copies the command line to offset 80h in the PSP, but that’s not where the OS/2 startup code expects it. That’s why I copy it over into the environment segment. Without this, the invoked command would see the same command line as its caller.

From looking at this now, it looks like the loader patch copies only the first argument. I'm not sure right now, and I cannot investigate. The "fix" is certainly not entirely correct, but it made the use case work for which I needed it (running the Opus OS/2 compiler).

No, it copies the entire line. The additional cmp loop is for skipping over the first argument (the command name), and it scans the previous environment segment's contents, i.e. the one used to invoke the current program. The code should be mostly fine, unless the new line is too long for the segment, in which case it will likely crash.

The good way would be to allocate a new environment segment and accumulate everything there. I have seen an #ifdef to this effect, but have not investigated further.

I just went through this again step by step. I assume you know how to build what and which files to copy where. Starting with everything unmodified:

In Sample16/, run "sample6 a b c". You get:

E:\hx\Sample16>SAMPLE6.EXE a b c
launching sample5.exe
bytes read = 575
back in sample6.exe, returncode=0
launching sample2w.exe
hello world
arg: E:\HX\SAMPLE16\.\SAMPLE2W.EXE
arg: a
arg: b
arg: c
back in sample6.exe, returncode=0

The invoked program should not have received the a b c arguments.

Now change sample6.c like this and run again:

--- Sample16/_SAMPLE6.C	Wed Dec 13 10:00:38 2006
+++ Sample16/SAMPLE6.C	Sun Nov 11 17:28:51 2018
@@ -34,7 +34,7 @@
 #if 0
     spawnv(P_WAIT, ".\\SAMPLE2W.EXE", "");
 #else
-    if (DosExecPgm(0,0,0,0,0,&result,".\\SAMPLE2W.EXE") == 0)
+    if (DosExecPgm(0,0,0,"sample2w\0e f g\0",0,&result,".\\SAMPLE2W.EXE") == 0)
 #endif
         printf("back in sample6.exe, returncode=%X\n", result.codeResult);
     else

The output is exactly the same. sample2 still receives a b c instead of e f g.

Now apply the DPMILDR patch and run again:

E:\hx\Sample16>SAMPLE6.EXE a b c
launching sample5.exe
bytes read = 575
back in sample6.exe, returncode=0
launching sample2w.exe
hello world
arg: E:\HX\SAMPLE16\.\SAMPLE2W.EXE
back in sample6.exe, returncode=0

Different, but still wrong. With the final DOSEXEC patch:

E:\hx\Sample16>SAMPLE6.EXE a b c
launching sample5.exe
bytes read = 575
back in sample6.exe, returncode=0
launching sample2w.exe
hello world
arg: E:\HX\SAMPLE16\.\SAMPLE2W.EXE
arg: e
arg: f
arg: g
back in sample6.exe, returncode=0

Exactly as it should be.