This patch is an improved version of the previous patch for fixing DOS command line passing (that patch had an unbelievable number of bugs...). This patch uses correct command line maximum size (128 bytes can really hold only 126 bytes of command line because DOS command line is prefixed with length and suffixed with carriage return), truncates command line if it is too long, detects both first space in command line and command line length more robustly and finally it is much more readable :). Changelog: When DOS program executes another DOS program, command line is now passed correctly. If DOS command line is too long, command line is now truncated instead of letting it trash memory. Index: dlls/winedos/module.c =================================================================== RCS file: /home/wine/wine/dlls/winedos/module.c,v retrieving revision 1.14 diff -u -r1.14 module.c --- dlls/winedos/module.c 26 Apr 2002 19:05:17 -0000 1.14 +++ dlls/winedos/module.c 1 May 2002 09:25:45 -0000 @@ -112,22 +112,29 @@ /* FIXME: more PSP stuff */ } -static void MZ_FillPSP( LPVOID lpPSP, LPCSTR cmdline ) +static void MZ_FillPSP( LPVOID lpPSP, LPBYTE cmdline, int length ) { - PDB16*psp=lpPSP; - const char*cmd=cmdline?strchr(cmdline,' '):NULL; + PDB16 *psp = lpPSP; - /* copy parameters */ - if (cmd) { -#if 0 - /* command.com doesn't do this */ - while (*cmd == ' ') cmd++; -#endif - psp->cmdLine[0]=strlen(cmd); - strcpy(psp->cmdLine+1,cmd); - psp->cmdLine[psp->cmdLine[0]+1]='\r'; - } else psp->cmdLine[1]='\r'; - /* FIXME: more PSP stuff */ + while(length > 0 && *cmdline != ' ') { + length--; + cmdline++; + } + + /* command.com does not skip over multiple spaces */ + + if(length > 126) { + ERR("Command line truncated! (length %d > maximum length 126)\n", + length); + length = 126; + } + + psp->cmdLine[0] = length; + if(length > 0) + memmove(psp->cmdLine+1, cmdline, length); + psp->cmdLine[length+1] = '\r'; + + /* FIXME: more PSP stuff */ } /* default INT 08 handler: increases timer tick counter but not much more */ @@ -356,7 +363,11 @@ * let's work on the new values now */ LPBYTE psp_start = (LPBYTE)((DWORD)DOSVM_psp << 4); ExecBlock *blk = (ExecBlock *)paramblk; - MZ_FillPSP(psp_start, DOSMEM_MapRealToLinear(blk->cmdline)); + LPBYTE cmdline = DOSMEM_MapRealToLinear(blk->cmdline); + + /* First character contains the length of the command line. */ + MZ_FillPSP(psp_start, cmdline + 1, cmdline[0]); + /* the lame MS-DOS engineers decided that the return address should be in int22 */ DOSVM_SetRMHandler(0x22, (FARPROC16)MAKESEGPTR(context->SegCs, LOWORD(context->Eip))); if (func) { @@ -462,8 +473,9 @@ { TDB *pTask = TASK_GetCurrent(); BYTE *psp_start = PTR_REAL_TO_LIN( DOSVM_psp, 0 ); + LPSTR cmdline = GetCommandLineA(); - MZ_FillPSP(psp_start, GetCommandLineA()); + MZ_FillPSP(psp_start, cmdline, cmdline ? strlen(cmdline) : 0); pTask->flags |= TDBF_WINOLDAP; _LeaveWin16Lock(); -- Jukka Heinonen <http://www.iki.fi/jhei/>