VirtualBox

Ignore:
Timestamp:
Jan 4, 2022 2:54:28 AM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
149134
Message:

Main/os2_util: Updates.

Location:
trunk/src/VBox/Main/src-helper-apps/os2
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-helper-apps/os2/Makefile.kmk

    r93116 r93120  
    2323# This is checked in as a binary, this is just the makefile for re-builting it.
    2424#
    25 override DEFS.os2 = RT_OS_OS2 # HACK ALERT!
    26 PROGRAMS += os2_util
    27 os2_util_TOOL         = OPENWATCOM-16
    28 os2_util_ASTOOL       = OPENWATCOM-16
    29 os2_util_LDTOOL       = OPENWATCOM-WL
    30 os2_util_BLD_TRG      = os2
    31 os2_util_BLD_TRG_ARCH = x86
    32 os2_util_INST         = $(INST_UNATTENDED_TEMPLATES)
    33 os2_util_MODE         = a+r,u+w
    34 os2_util_DEFS         = IN_RING3
    35 os2_util_CFLAGS       = -zl -s -ml
    36 os2_util_LDFLAGS      = \
     25ifdef VBOX_WITH_OPEN_WATCOM
     26 PROGRAMS += os2_util
     27endif
     28os2_util_TOOL           = OPENWATCOM-16
     29os2_util_ASTOOL         = OPENWATCOM-16
     30os2_util_LDTOOL         = OPENWATCOM-WL
     31os2_util_BLD_TRG        = os2
     32os2_util_BLD_TRG_ARCH   = x86
     33os2_util_INST           = $(INST_UNATTENDED_TEMPLATES)
     34os2_util_MODE           = a+r,u+w
     35os2_util_DEFS           = IN_RING3
     36os2_util_CFLAGS         = -zl -s -ml -os
     37os2_util_LDFLAGS        = \
    3738        SYSTEM os2 \
    3839        OPTION START=_Os2UtilMain \
     
    4142        OPTION MANYAUTODATA \
    4243        SEGMENT IOPL IOPL EXECUTEREAD
    43 os2_util_INCS         = $(PATH_TOOL_OPENWATCOM)/h/os21x
    44 os2_util_SOURCES      = os2_util.c os2_utilA.asm
     44if 0
     45os2_util_LDFLAGS       += Debug Watcom All
     46os2_util_CFLAGS        += -d2 -hw
     47endif
     48
     49os2_util_INCS           = $(PATH_TOOL_OPENWATCOM)/h/os21x
     50os2_util_SOURCES        = os2_util.c os2_utilA.asm
    4551
    4652include $(FILE_KBUILD_SUB_FOOTER)
  • trunk/src/VBox/Main/src-helper-apps/os2/os2_util.c

    r93116 r93120  
    2828#include <VBox/log.h>
    2929
     30#include "VBox/version.h"
     31
    3032
    3133/*********************************************************************************************************************************
     
    7981
    8082
     83/** strchr-like function. */
     84static char __far *MyStrChr(const char __far *psz, char chNeedle)
     85{
     86    char ch;
     87    while ((ch = *psz) != '\0')
     88    {
     89        if (ch == chNeedle)
     90            return (char __far *)psz;
     91        psz++;
     92    }
     93    return NULL;
     94}
     95
     96
    8197/** memcpy-like function.   */
    8298static void *MyMemCopy(void __far *pvDst, void const __far *pvSrc, USHORT cb)
     
    134150    MyOutNum(rc);
    135151    MyOutStr("\r\n");
    136     DosExit(EXIT_PROCESS, 0);
     152    DosExit(EXIT_PROCESS, 1);
     153}
     154
     155
     156static void MyApiError3AndQuit(PSZ pszOperation, PSZ psz2, PSZ psz3, USHORT rc)
     157{
     158    MyOutStr("Os2Util: error: ");
     159    MyOutStr(pszOperation);
     160    MyOutStr(psz2);
     161    MyOutStr(psz3);
     162    MyOutStr(" failed: ");
     163    MyOutNum(rc);
     164    MyOutStr("\r\n");
     165    DosExit(EXIT_PROCESS, 1);
     166}
     167
     168
     169static void MySyntaxErrorAndQuit(PSZ pszMsg)
     170{
     171    MyOutStr("Os2Util: syntax error: ");
     172    MyOutStr(pszMsg);
     173    MyOutStr("\r\n");
     174    DosExit(EXIT_PROCESS, 1);
    137175}
    138176
     
    160198         * Write out buffered data
    161199         */
     200        /** @todo this does not seem to work. */
    162201        pBuf = g_pBufferHead;
    163202        while (pBuf)
     
    234273
    235274
     275/**
     276 * Waits for the child progress to complete, returning it's status code.
     277 */
     278static void DoWait(PID pidChild, USHORT idSession, HQUEUE hQueue, PRESULTCODES pResultCodes)
     279{
     280    /*
     281     * Can we use DosCwait?
     282     */
     283    if (idSession == 0 && hQueue == NULL)
     284    {
     285        for (;;)
     286        {
     287            PID pidIgnored;
     288            USHORT rc = DosCwait(DCWA_PROCESS, DCWW_WAIT, pResultCodes, &pidIgnored, pidChild);
     289            if (rc == NO_ERROR)
     290                break;
     291            if (rc != ERROR_INTERRUPT)
     292            {
     293                MyOutStr("Os2Util: error: DosCwait(DCWA_PROCESS,DCWW_WAIT,,,");
     294                MyOutNum(pidChild);
     295                MyOutStr(") failed: ");
     296                MyOutNum(rc);
     297                MyOutStr("\r\n");
     298            }
     299        }
     300    }
     301    else
     302    {
     303        /*
     304         * No we have to use the queue interface to the session manager.
     305         */
     306        for (;;)
     307        {
     308            ULONG   ulAdderPidAndEvent = 0;
     309            PUSHORT pausData           = NULL;
     310            USHORT  cbData             = 0;
     311            BYTE    bPriority          = 0;
     312            HSEM    hSem               = NULL;
     313            USHORT rc = DosReadQueue(hQueue, &ulAdderPidAndEvent, &cbData, (PULONG)&pausData,
     314                                     0 /*uElementCode*/, 0 /* fNoWait */, &bPriority, &hSem);
     315            if (rc == NO_ERROR)
     316            {
     317                if (cbData >= sizeof(USHORT) * 2)
     318                {
     319                    USHORT idTermSession = pausData[0];
     320                    USHORT uExitCode     = pausData[1];
     321                    if (idTermSession == idSession)
     322                    {
     323                        pResultCodes->codeTerminate = 0;
     324                        pResultCodes->codeResult    = uExitCode;
     325                        break;
     326                    }
     327                    if (1)
     328                    {
     329                        MyOutStr("OutUtil: info: idTermSession=");
     330                        MyOutNum(idTermSession);
     331                        MyOutStr(" uExitCode=");
     332                        MyOutNum(uExitCode);
     333                        MyOutStr("\r\n");
     334                    }
     335                }
     336                else
     337                {
     338                    MyOutStr("OutUtil: warning: bogus queue element size: cbData=");
     339                    MyOutNum(cbData);
     340                    MyOutStr("\r\n");
     341                }
     342                DosFreeSeg((__segment)pausData);
     343            }
     344            else if (rc != ERROR_INTERRUPT)
     345            {
     346                DosCloseQueue(hQueue);
     347                MyApiErrorAndQuit("DosReadQueue", rc);
     348            }
     349        }
     350    }
     351}
     352
     353
     354/** Displays version string and quits.   */
     355static void ShowVersionAndQuit(void)
     356{
     357    CHAR szVer[] = "$Rev$\r\n";
     358    USHORT usIgnored;
     359    DosWrite(g_hStdOut, szVer, sizeof(szVer) - 1, &usIgnored);
     360    DosExit(EXIT_PROCESS, 0);
     361}
     362
     363
     364/** Displays usage info and quits.   */
    236365static void ShowUsageAndQuit(void)
    237366{
    238367    static char s_szHelp[] =
    239         "Os2Util.exe is tiny helper utility that implements TEE'ing to the VBox release log,\r\n"
    240         "files and shows the actual exit code of a program.  Standard error and output will\r\n"
    241         "be merged into one for simplicity reasons.\r\n"
     368        VBOX_PRODUCT " OS/2 Unattended Helper Version " VBOX_VERSION_STRING "\r\n"
     369        "(C) 2005-" VBOX_C_YEAR " " VBOX_VENDOR "\r\n"
    242370        "\r\n"
    243         "usage: Os2Util.exe [-a|--append] [-f<filename>|--tee-to-file <filename>] \\\r\n"
    244         "                   [-b|--tee-to-backdoor] -- <prog> [args]\r\n"
    245         "   or  Os2Util.exe <-w<msg>|--write-backdoor <msg>> \r\n";
     371        "Os2Util.exe is tiny helper utility that implements TEE'ing to the VBox release\r\n"
     372        "log, files and shows the actual exit code of a program.  Standard error and\r\n"
     373        "output will be merged into one for simplicity reasons.\r\n"
     374        "\r\n"
     375        "Usage: Os2Util.exe [-a|--append] [-f<filename>|--tee-to-file <filename>] \\\r\n"
     376        "                   [-b|--tee-to-backdoor] [-z<exit>|--as-zero <exit> [..]] \\\r\n"
     377        "                   -- <prog> [args]\r\n"
     378        "   or  Os2Util.exe <-w<msg>|--write-backdoor <msg>>\r\n"
     379        "\r\n"
     380        "Note! Does not supported any kind of quoting before the child arguments.\r\n"
     381        ;
    246382    USHORT usIgnored;
    247     DosWrite(g_hStdErr, s_szHelp, sizeof(s_szHelp) - 1, &usIgnored);
     383    DosWrite(g_hStdOut, s_szHelp, sizeof(s_szHelp) - 1, &usIgnored);
    248384    DosExit(EXIT_PROCESS, 0);
    249385}
     
    262398    if (*psz == '\0')
    263399    {
    264         USHORT usIgnored;
    265         DosWrite(g_hStdErr, RT_STR_TUPLE("Os2Util: syntax error: Option '"), &usIgnored);
    266         DosWrite(g_hStdErr, pszOption, MyStrLen(pszOption), &usIgnored);
    267         DosWrite(g_hStdErr, RT_STR_TUPLE("' takes a value\r\n"), &usIgnored);
     400        MyOutStr("Os2Util: syntax error: Option '");
     401        MyOutStr(pszOption);
     402        MyOutStr("' takes a value\r\n");
    268403        DosExit(EXIT_PROCESS, 2);
    269404    }
     
    275410    if (ch != '\0')
    276411        *psz++ = '\0';
     412    return psz;
     413}
     414
     415
     416/**
     417 * Gets the an numeric option value.
     418 */
     419static PSZ MyGetOptNum(PSZ psz, PSZ pszOption, PUSHORT puValue)
     420{
     421    PSZ    pszError = NULL;
     422    PSZ    pszValueStart = NULL;
     423    PSZ    pszValue;
     424    CHAR   ch;
     425    USHORT uValue;
     426    psz = MyGetOptValue(psz, pszOption, &pszValueStart);
     427
     428    pszValue = pszValueStart;
     429    uValue   = 0;
     430    if (pszValue[0] == '0' && ((ch = pszValue[1]) == 'x' || ch == 'X'))
     431    {
     432        pszValue += 2;
     433        while ((ch = *pszValue++) != '\0')
     434        {
     435            BYTE bDigit;
     436            if (ch <= '9' && ch >= '0')
     437                bDigit = ch - '0';
     438            else if (ch <= 'f' && ch >= 'a')
     439                bDigit = ch - 'a' + 10;
     440            else if (ch <= 'F' && ch >= 'A')
     441                bDigit = ch - 'A' + 10;
     442            else
     443            {
     444                pszError = "': invalid hex value\r\n";
     445                break;
     446            }
     447            if (uValue >> 12)
     448            {
     449                pszError = "': hex value out of range\r\n";
     450                break;
     451            }
     452            uValue <<= 4;
     453            uValue |= bDigit;
     454        }
     455    }
     456    else
     457    {
     458        while ((ch = *pszValue++) != '\0')
     459        {
     460            BYTE bDigit;
     461            if (ch <= '9' && ch >= '0')
     462                bDigit = ch - '0';
     463            else
     464            {
     465                pszError = "': invalid decimal value\r\n";
     466                break;
     467            }
     468            if (uValue * 10 / 10 != uValue)
     469            {
     470                pszError = "': decimal value out of range\r\n";
     471                break;
     472            }
     473            uValue *= 10;
     474            uValue += bDigit;
     475        }
     476    }
     477
     478    if (pszError)
     479    {
     480        MyOutStr("Os2Util: syntax error: Option '");
     481        MyOutStr(pszOption);
     482        MyOutStr("' with value '");
     483        MyOutStr(pszValueStart);
     484        MyOutStr(pszError);
     485        DosExit(EXIT_PROCESS, 2);
     486    }
     487
     488    *puValue = uValue;
    277489    return psz;
    278490}
     
    326538    RESULTCODES ResultCodes    = { 0xffff, 0xffff };
    327539    CHAR        szBuf[512];
     540    CHAR        szExeFull[CCHMAXPATH];
     541    PSZ         pszExe;
     542    USHORT      uExeType;
     543    USHORT      idSession      = 0;
     544    PID         pidChild       = 0;
     545    HQUEUE      hQueue         = ~(HQUEUE)0;
     546    CHAR        szQueueName[64];
     547    unsigned    cAsZero;
     548    USHORT      auAsZero[16];
    328549
    329550    /*
     
    359580                if (ch == 'a' && MyMatchLongOption(&psz, RT_STR_TUPLE("append")))
    360581                    fAppend = TRUE;
     582                else if (ch == 'a' && MyMatchLongOption(&psz, RT_STR_TUPLE("as-zero")))
     583                {
     584                    if (cAsZero > RT_ELEMENTS(auAsZero))
     585                        MySyntaxErrorAndQuit("Too many --as-zero/-z options");
     586                    psz = MyGetOptNum(psz + 1, "--as-zero", &auAsZero[cAsZero]);
     587                    cAsZero++;
     588                }
    361589                else if (ch == 'h' && MyMatchLongOption(&psz, RT_STR_TUPLE("help")))
    362590                    ShowUsageAndQuit();
     
    365593                else if (ch == 't' && MyMatchLongOption(&psz, RT_STR_TUPLE("tee-to-file")))
    366594                    psz = MyGetOptValue(psz, "--tee-to-file", &pszTeeToFile);
     595                else if (ch == 'v' && MyMatchLongOption(&psz, RT_STR_TUPLE("version")))
     596                    ShowVersionAndQuit();
    367597                else if (ch == 'w' && MyMatchLongOption(&psz, RT_STR_TUPLE("write-backdoor")))
    368598                {
     
    373603                else
    374604                {
    375                     DosWrite(g_hStdErr, RT_STR_TUPLE("Os2util: syntax error: "), &usIgnored);
    376                     DosWrite(g_hStdErr, pszOptStart, MyStrLen(pszOptStart), &usIgnored);
    377                     DosWrite(g_hStdErr, RT_STR_TUPLE("\r\n"), &usIgnored);
     605                    MyOutStr("Os2util: syntax error: ");
     606                    MyOutStr(pszOptStart);
     607                    MyOutStr("\r\n");
    378608                    DosExit(EXIT_PROCESS, 2);
    379609                }
     
    399629                        DosExit(EXIT_PROCESS, 0);
    400630                    }
     631                    else if (ch == 'z')
     632                    {
     633                        if (cAsZero > RT_ELEMENTS(auAsZero))
     634                            MySyntaxErrorAndQuit("Too many --as-zero/-z options");
     635                        psz = MyGetOptNum(psz + 1, "-z", &auAsZero[cAsZero]);
     636                        cAsZero++;
     637                    }
    401638                    else if (ch == '?' || ch == 'h' || ch == 'H')
    402639                        ShowUsageAndQuit();
     640                    else if (ch == 'V')
     641                        ShowVersionAndQuit();
    403642                    else
    404643                    {
    405                         DosWrite(g_hStdErr, RT_STR_TUPLE("Os2util: syntax error: "), &usIgnored);
     644                        MyOutStr("Os2util: syntax error: ");
    406645                        if (ch)
    407646                            DosWrite(g_hStdErr, &ch, 1, &usIgnored);
    408647                        else
    409                             DosWrite(g_hStdErr, RT_STR_TUPLE("lone dash"), &usIgnored);
    410                         DosWrite(g_hStdErr, RT_STR_TUPLE(" ("), &usIgnored);
    411                         DosWrite(g_hStdErr, pszOptStart, MyStrLen(pszOptStart), &usIgnored);
    412                         DosWrite(g_hStdErr, RT_STR_TUPLE(")\r\n"), &usIgnored);
     648                            MyOutStr("lone dash");
     649                        MyOutStr(" (");
     650                        MyOutStr(pszOptStart);
     651                        MyOutStr(")\r\n");
    413652                        DosExit(EXIT_PROCESS, 2);
    414653                    }
     
    425664    if (ch == '\0')
    426665    {
    427         DosWrite(g_hStdErr, RT_STR_TUPLE("Os2Util: syntax error: No program specified\r\n"), &usIgnored);
     666        MyOutStr("Os2Util: syntax error: No program specified\r\n");
    428667        DosExit(EXIT_PROCESS, 2);
    429668    }
     
    434673
    435674    /*
     675     * Find the executable and check its type.
     676     */
     677    if (   pszzNewCmdLine[1] == ':'
     678        || MyStrChr(pszzNewCmdLine, '\\')
     679        || MyStrChr(pszzNewCmdLine, '/'))
     680        pszExe = pszzNewCmdLine;
     681    else
     682    {
     683        rc = DosSearchPath(SEARCH_CUR_DIRECTORY | SEARCH_ENVIRONMENT | SEARCH_IGNORENETERRS, "PATH",
     684                           pszzNewCmdLine, szExeFull, sizeof(szExeFull));
     685        if (rc != NO_ERROR)
     686            MyApiError3AndQuit("DosSearchPath(7, \"PATH\", \"", pszzNewCmdLine, "\",,)", rc);
     687        pszExe = &szExeFull[0];
     688    }
     689
     690    /* Perhapse we should use WinQueryProgramType here instead? */
     691    rc = DosQAppType(pszExe, &uExeType);
     692    if (rc != NO_ERROR)
     693        MyApiErrorAndQuit("DosQAppType(pszExe, &uExeType)", rc);
     694#ifdef DEBUG
     695    MyOutStr("Os2Util: debug: uExeType="); MyOutNum(uExeType); MyOutStr("\r\n");
     696#endif
     697    /** @todo deal with launching winos2 programs too...   */
     698
     699    /*
    436700     * Prepare redirection.
    437701     */
     
    445709        rc = DosDupHandle(g_hStdErr, &hDup);
    446710        if (rc != NO_ERROR)
    447             MyApiErrorAndQuit("DosDupHandle(g_hStdErr, &hDup);", rc);
     711            MyApiErrorAndQuit("DosDupHandle(g_hStdErr, &hDup)", rc);
    448712        g_hStdErr = hDup;
    449713        DosSetFHandState(hDup, OPEN_FLAGS_NOINHERIT); /* not strictly necessary, so ignore errors */
     
    452716        rc = DosDupHandle(g_hStdOut, &hDup);
    453717        if (rc != NO_ERROR)
    454             MyApiErrorAndQuit("DosDupHandle(g_hStdOut, &hDup);", rc);
     718            MyApiErrorAndQuit("DosDupHandle(g_hStdOut, &hDup)", rc);
    455719        g_hStdOut = hDup;
    456720        DosSetFHandState(hDup, OPEN_FLAGS_NOINHERIT); /* not strictly necessary, so ignore errors */
     
    469733        rc = DosDupHandle(hPipeWrite, &hDup);
    470734        if (rc != NO_ERROR)
    471             MyApiErrorAndQuit("DosDupHandle(hPipeWrite, &hDup[=1]);", rc);
     735            MyApiErrorAndQuit("DosDupHandle(hPipeWrite, &hDup[=1])", rc);
    472736
    473737        hDup = 2;
    474738        rc = DosDupHandle(hPipeWrite, &hDup);
    475739        if (rc != NO_ERROR)
    476             MyApiErrorAndQuit("DosDupHandle(hPipeWrite, &hDup[=2]);", rc);
     740            MyApiErrorAndQuit("DosDupHandle(hPipeWrite, &hDup[=2])", rc);
    477741
    478742        /* We can close the write end of the pipe as we don't need the original handle any more. */
     
    484748     */
    485749    szBuf[0] = '\0';
    486     rc = DosExecPgm(szBuf, sizeof(szBuf), hPipeRead == -1 ? EXEC_SYNC : EXEC_ASYNCRESULT,
    487                     pszzNewCmdLine, pszzEnv, &ResultCodes, pszzNewCmdLine);
    488     if (rc != NO_ERROR)
    489     {
    490         MyOutStr("Os2Util: error: DosExecPgm failed for \"");
    491         MyOutStr(pszzNewCmdLine);
    492         MyOutStr("\": ");
    493         MyOutNum(rc);
    494         if (szBuf[0])
    495         {
    496             MyOutStr(" ErrObj=");
    497             szBuf[sizeof(szBuf) - 1] = '\0';
    498             MyOutStr(szBuf);
    499         }
    500         MyOutStr("\r\n");
    501         DosExit(EXIT_PROCESS, 1);
     750#define FAPPTYP_TYPE_MASK 7
     751    if ((uExeType & FAPPTYP_TYPE_MASK) == PT_WINDOWABLEVIO) /** @todo what if we're in fullscreen ourselves? */
     752    {
     753        /* For same type programs we can use DosExecPgm: */
     754        rc = DosExecPgm(szBuf, sizeof(szBuf), hPipeRead == -1 ? EXEC_SYNC : EXEC_ASYNCRESULT,
     755                        pszzNewCmdLine, pszzEnv, &ResultCodes, pszExe);
     756        if (rc != NO_ERROR)
     757        {
     758            MyOutStr("Os2Util: error: DosExecPgm failed for \"");
     759            MyOutStr(pszzNewCmdLine);
     760            MyOutStr("\": ");
     761            MyOutNum(rc);
     762            if (szBuf[0])
     763            {
     764                MyOutStr(" ErrObj=");
     765                szBuf[sizeof(szBuf) - 1] = '\0';
     766                MyOutStr(szBuf);
     767            }
     768            MyOutStr("\r\n");
     769            DosExit(EXIT_PROCESS, 1);
     770        }
     771        if (hPipeRead != -1)
     772            pidChild = ResultCodes.codeTerminate;
     773    }
     774    else
     775    {
     776        /* For different typed programs we have to use DosStartSession, which
     777           is a lot more tedious to use. */
     778        static const char   s_szQueueBase[] = "\\QUEUES\\OS2_UTIL-";
     779        union
     780        {
     781            STARTDATA       StartData;
     782            BYTE            abPadding[sizeof(STARTDATA) + 64];
     783            struct
     784            {
     785                STARTDATA   Core;
     786                ULONG       ulReserved;
     787                PSZ         pszBuf;
     788                USHORT      cbBuf;
     789            } s;
     790        } u;
     791        PIDINFO             PidInfo         = {0, 0, 0};
     792
     793        /* Create the wait queue first. */
     794        DosGetPID(&PidInfo);
     795        MyMemCopy(szQueueName, s_szQueueBase, sizeof(s_szQueueBase));
     796        MyNumToString(&szQueueName[sizeof(s_szQueueBase) - 1], PidInfo.pid);
     797
     798        rc = DosCreateQueue(&hQueue, 0 /*FIFO*/, szQueueName);
     799        if (rc != NO_ERROR)
     800            MyApiError3AndQuit("DosCreateQueue(&hQueue, 0, \"", szQueueName, "\")", rc);
     801
     802        u.StartData.Length        = sizeof(u.StartData);
     803        u.StartData.Related       = 1 /* SSF_RELATED_CHILD */;
     804        u.StartData.FgBg          = 0 /* SSF_FGBG_FORE */;
     805        u.StartData.TraceOpt      = 0 /* SSF_TRACEOPT_NONE */;
     806        u.StartData.PgmTitle      = NULL;
     807        u.StartData.PgmName       = pszExe;
     808        u.StartData.PgmInputs     = psz; /* just arguments, not exec apparently.*/
     809        u.StartData.TermQ         = szQueueName;
     810        u.StartData.Environment   = NULL; /* Inherit our env. Note! Using pszzEnv causes it to be freed
     811                                                                    and we'll crash reporting the error. */
     812        u.StartData.InheritOpt    = 1 /* SSF_INHERTOPT_PARENT */;
     813        u.StartData.SessionType   = uExeType & FAPPTYP_TYPE_MASK;
     814        if (uExeType & 0x20 /*FAPPTYP_DOS*/)
     815            u.StartData.SessionType = 4 /* SSF_TYPE_VDM */;
     816        u.StartData.IconFile      = NULL;
     817        u.StartData.PgmHandle     = 0;
     818        u.StartData.PgmControl    = 0 /* SSF_CONTROL_VISIBLE */;
     819        u.StartData.InitXPos      = 0;
     820        u.StartData.InitYPos      = 0;
     821        u.StartData.InitXSize     = 0;
     822        u.StartData.InitYSize     = 0;
     823        u.s.ulReserved            = 0;
     824        u.s.pszBuf                = NULL;
     825        u.s.cbBuf                 = 0;
     826
     827        rc = DosStartSession(&u.StartData, &idSession, &pidChild);
     828        if (rc != NO_ERROR)
     829        {
     830            DosCloseQueue(hQueue);
     831            MyApiError3AndQuit("DosStartSession for \"", pszExe, "\"", rc);
     832        }
    502833    }
    503834
     
    507838    if (hPipeRead != -1)
    508839    {
    509         /* Save the child pid. */
    510         PID const pidChild = ResultCodes.codeTerminate;
    511         PID       pidIgnored;
    512840
    513841        /* Close the write handles or we'll hang in the read loop. */
     
    517845        /* Disable hard error popups (file output to unformatted disks). */
    518846        DosError(2 /* only exceptions */);
    519 
    520847
    521848        /*
     
    538865                /* Backdoor: */
    539866                if (fTeeToBackdoor)
    540                     VBoxBackdoorPrint(psz, cbRead);
     867                    VBoxBackdoorPrint(szBuf, cbRead);
    541868
    542869                /* File: */
     
    560887
    561888        DosClose(hPipeRead);
    562         rc = DosCwait(DCWA_PROCESS, DCWW_WAIT, &ResultCodes, &pidIgnored, pidChild);
    563         if (rc != NO_ERROR)
    564         {
    565             MyOutStr("Os2Util: error: DosCwait(DCWA_PROCESS,DCWW_WAIT,,,");
    566             MyOutNum(pidChild);
    567             MyOutStr(") failed: ");
    568             MyOutNum(rc);
    569             MyOutStr("\r\n");
    570         }
    571     }
     889
     890        /*
     891         * Wait for the process to complete.
     892         */
     893        DoWait(pidChild, idSession, hQueue, &ResultCodes);
     894    }
     895    /*
     896     * Must wait for the session completion too.
     897     */
     898    else if (idSession != 0)
     899        DoWait(pidChild, idSession, hQueue, &ResultCodes);
    572900
    573901    /*
     
    585913    MyOutStr("\r\n");
    586914
     915    /* Treat it as zero? */
     916    if (ResultCodes.codeTerminate == 0)
     917    {
     918        unsigned i = cAsZero;
     919        while (i-- > 0)
     920            if (auAsZero[i] == ResultCodes.codeResult)
     921            {
     922                MyOutStr("Os2Util: info: treating status as zero\r\n");
     923                ResultCodes.codeResult = 0;
     924                break;
     925            }
     926    }
     927
     928    if (idSession != 0)
     929        DosCloseQueue(hQueue);
    587930    for (;;)
    588931        DosExit(EXIT_PROCESS, ResultCodes.codeTerminate == 0 ? ResultCodes.codeResult : 127);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette