Changeset 31


Ignore:
Timestamp:
Mar 30, 2016, 12:31:15 PM (9 years ago)
Author:
Alex Taylor
Message:

Fixes to return string handling plus workaround for unexpected DosQuerySysState return data (from SHL).

Location:
rxutilex/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • rxutilex/trunk/rxutilex.c

    r30 r31  
    104104#define FL_TIME_LOCALE          2
    105105
     106static const char *PSZ_ZERO = "0";
     107static const char *PSZ_ONE = "1";
    106108
    107109// List of functions to be registered by Sys2LoadFuncs or dropped by Sys2DropFuncs
     
    135137};
    136138
    137 
    138139// FUNCTION DECLARATIONS
    139140
     
    174175RexxFunctionHandler Sys2SyncBuffer;
    175176
    176 
    177177// Private internal functions
    178 ULONG GetProcess( PSZ pszProgram, PSZ pszFullName, PULONG pulPID, PULONG pulPPID, PULONG pulType, PUSHORT pusPriority, PULONG pulCPU );
    179 BOOL  SaveResultString( PRXSTRING prsResult, PCH pchBytes, ULONG ulBytes );
    180 BOOL  WriteStemElement( PSZ pszStem, ULONG ulIndex, PSZ pszValue );
    181 void  WriteErrorCode( ULONG ulError, PSZ pszContext );
    182 
     178ULONG GetProcess( PCSZ pszProgram, PSZ pszFullName, PULONG pulPID, PULONG pulPPID, PULONG pulType, PUSHORT pusPriority, PULONG pulCPU );        // 2016-02-20 SHL
     179BOOL  SaveResultString( PRXSTRING prsResult, PCSZ pchBytes, ULONG ulBytes );    // 2016-02-20 SHL
     180BOOL  WriteStemElement( PCSZ pszStem, ULONG ulIndex, PCSZ pszValue );   // 2016-02-20 SHL
     181void  WriteErrorCode( ULONG ulError, PCSZ pszContext ); // 2016-02-20 SHL
    183182
    184183// MACROS
    185184#define TIME_SECONDS( timeval )     ( timeval / 32 )
    186185#define TIME_HUNDREDTHS( timeval )  (( timeval % 32 ) * 100 / 32 )
    187 
    188186
    189187/* ------------------------------------------------------------------------- *
     
    209207        RexxRegisterFunctionDll( RxFunctionTbl[i], SZ_LIBRARY_NAME, RxFunctionTbl[i] );
    210208
    211     MAKERXSTRING( *prsResult, "", 0 );
     209    SaveResultString( prsResult, NULL, 0 );     // 2016-02-20 SHL
    212210    return ( 0 );
    213211}
     
    235233        RexxDeregisterFunction( RxFunctionTbl[i] );
    236234
    237     MAKERXSTRING( *prsResult, "", 0 );
     235    SaveResultString( prsResult, NULL, 0 );     // 2016-02-20 SHL
    238236    return ( 0 );
    239237}
     
    258256    sprintf( szVersion, "%s", SZ_VERSION );
    259257
    260     MAKERXSTRING( *prsResult, szVersion, strlen(szVersion) );
     258    SaveResultString( prsResult, szVersion, strlen(szVersion) );        // 2016-02-20 SHL
    261259    return ( 0 );
    262260}
     
    317315    DosGetInfoBlocks( &ptib, &ppib );
    318316    ulPType = ppib->pib_ultype;
    319     ppib->pib_ultype = 3;
     317    ppib->pib_ultype = 3;               // Morph to PM
    320318    hab = WinInitialize( 0 );
    321319    if ( !hab ) {
     
    328326     * (in the calling process), which is also OK.
    329327     */
    330     hmq = WinCreateMsgQueue( hab, 0);
     328    hmq = WinCreateMsgQueue( hab, 0 );
     329
     330    // 2016-02-20 SHL Sync return values with docs
    331331
    332332    // Place the string on the clipboard as CF_TEXT
     
    337337
    338338        ulBytes = argv[0].strlength + 1;
    339         ulRC = DosAllocSharedMem( (PVOID) &pszShareMem, NULL, ulBytes,
     339        ulRC = DosAllocSharedMem( (PVOID) &pszShareMem,
     340                                  NULL,
     341                                  ulBytes,
    340342                                  PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_GIVEABLE );
    341343        if ( ulRC == 0 ) {
    342344            memset( pszShareMem, 0, ulBytes );
    343345            strncpy( pszShareMem, argv[0].strptr, ulBytes - 1 );
    344             if ( ! WinSetClipbrdData( hab, (ULONG) pszShareMem, CF_TEXT, CFI_POINTER ))
    345                 WriteErrorCode( ERRORIDERROR(WinGetLastError(hab)), "WinSetClipbrdData");
     346            if ( ! WinSetClipbrdData( hab, (ULONG) pszShareMem, CF_TEXT, CFI_POINTER ) ) {
     347                WriteErrorCode( ERRORIDERROR(WinGetLastError(hab)), "WinSetClipbrdData" );
     348                SaveResultString( prsResult, PSZ_ZERO, 1 );     // 2016-02-20 SHL
     349            }
    346350            else
    347                 MAKERXSTRING( *prsResult, "", 0 );
     351                SaveResultString( prsResult, PSZ_ONE, 1 );      // Success - 2016-02-20 SHL
    348352        } else {
    349353            WriteErrorCode( ulRC, "DosAllocSharedMem");
    350             MAKERXSTRING( *prsResult, "", 0 );
     354            SaveResultString( prsResult, PSZ_ZERO, 1 ); // 2016-02-20 SHL
    351355        }
    352356
    353357        WinCloseClipbrd( hab );
    354358    } else {
    355         WriteErrorCode( ulRC, "WinOpenClipbrd");
    356         MAKERXSTRING( *prsResult, "", 0 );
     359        // 2016-02-20 SHL Report PM error code
     360        WriteErrorCode( ERRORIDERROR(WinGetLastError(hab)), "WinOpenClipbrd" );
     361        SaveResultString( prsResult, PSZ_ZERO, 1 );     // 2016-02-20 SHL
    357362    }
    358363
    359364    if ( hmq != NULLHANDLE ) WinDestroyMsgQueue( hmq );
    360365    if ( fHabTerm ) WinTerminate( hab );
    361     ppib->pib_ultype = ulPType;
     366    ppib->pib_ultype = ulPType;                 // Restore
    362367
    363368    return ( 0 );
     
    373378 *   None.                                                                   *
    374379 *                                                                           *
    375  * REXX RETURN VALUE: The retrieved clipboard string                         *
     380 * REXX RETURN VALUE: The retrieved clipboard string  or "" if fails.        *
    376381 * ------------------------------------------------------------------------- */
    377382ULONG APIENTRY Sys2GetClipboardText( PSZ pszName, ULONG argc, RXSTRING argv[], PSZ pszQueue, PRXSTRING prsResult )
     
    415420
    416421        // Read plain text from the clipboard, if available
    417         if (( pszClipText = (PSZ) WinQueryClipbrdData( hab, CF_TEXT )) != NULL ) {
    418 
    419             ulBytes = strlen( pszClipText ) + 1;
    420             if (( pszLocalText = (PSZ) malloc( ulBytes )) != NULL ) {
     422        if (( pszClipText = (PSZ) WinQueryClipbrdData( hab, CF_TEXT ) ) != NULL ) {
     423
     424            ulBytes = strlen(pszClipText) + 1;
     425            if ( ( pszLocalText = (PSZ) malloc( ulBytes ) ) != NULL ) {
    421426                memset( pszLocalText, 0, ulBytes );
    422427                strncpy( pszLocalText, pszClipText, ulBytes - 1 );
    423                 if ( ! SaveResultString( prsResult, pszLocalText, ulBytes - 1 )) {
    424                     MAKERXSTRING( *prsResult, "", 0 );
    425                 }
     428                SaveResultString( prsResult, pszLocalText, ulBytes - 1 );       // 2016-02-20 SHL
    426429                free( pszLocalText );
    427430            } else {
    428431                WriteErrorCode( ERROR_NOT_ENOUGH_MEMORY, "malloc");
    429                 MAKERXSTRING( *prsResult, "", 0 );
     432                SaveResultString( prsResult, NULL, 0 ); // 2016-02-20 SHL
    430433            }
    431434
    432435        } else {
    433436            // Either no text exists, or clipboard is not readable
    434             MAKERXSTRING( *prsResult, "", 0 );
     437            SaveResultString( prsResult, NULL, 0 );     // 2016-02-20 SHL
    435438        }
    436439
    437440        WinCloseClipbrd( hab );
    438441    } else {
    439         WriteErrorCode( ulRC, "WinOpenClipbrd");
    440         MAKERXSTRING( *prsResult, "", 0 );
     442        // 2016-02-20 SHL Report PM error code
     443        WriteErrorCode( ERRORIDERROR(WinGetLastError(hab)), "WinOpenClipbrd" );
     444        SaveResultString( prsResult, NULL, 0 ); // 2016-02-20 SHL
    441445    }
    442446
     
    489493
    490494    // Parse the ID type flag
    491     if ( argc >= 2 && RXVALIDSTRING(argv[1]) ) {
     495    if ( argc >= 2 && RXVALIDSTRING( argv[1] ) ) {
    492496        strupr( argv[1].strptr );
    493         if (strcspn(argv[1].strptr, "HNP") > 0 ) return ( 40 );
     497        if ( strcspn(argv[1].strptr, "HNP") > 0 ) return ( 40 );
    494498        switch ( argv[1].strptr[0] ) {
    495499
     
    505509                      if ( pszProcName == NULL ) {
    506510                          WriteErrorCode( ERROR_NOT_ENOUGH_MEMORY, "calloc");
    507                           MAKERXSTRING( *prsResult, "0", 1 );
     511                          SaveResultString( prsResult, NULL, 0 );       // 2016-02-20 SHL
    508512                          return ( 0 );
    509513                      }
     
    515519        if ( pszProcName == NULL ) {
    516520            WriteErrorCode( ERROR_NOT_ENOUGH_MEMORY, "calloc");
    517             MAKERXSTRING( *prsResult, "0", 1 );
     521            SaveResultString( prsResult, NULL, 0 );     // 2016-02-20 SHL
    518522            return ( 0 );
    519523        }
     
    524528    rc = GetProcess( pszProcName, szFullName, &ulPID, &ulPPID, &ulType, &usPrty, &ulTime );
    525529    if (( rc != NO_ERROR ) || ( ulPID == 0 )) {
    526         MAKERXSTRING( *prsResult, "", 0 );
     530        SaveResultString( prsResult, NULL, 0 ); // 2016-02-20 SHL
    527531        return ( 0 );
    528532    }
     
    532536             TIME_SECONDS( ulTime ) % 60, TIME_HUNDREDTHS( ulTime ), szFullName );
    533537
    534     MAKERXSTRING( *prsResult, szReturn, strlen(szReturn) );
     538    SaveResultString( prsResult, szReturn, strlen(szReturn) );  // 2016-02-20 SHL
    535539
    536540    return ( 0 );
     
    588592                      if ( pszProcName == NULL ) {
    589593                          WriteErrorCode( ERROR_NOT_ENOUGH_MEMORY, "calloc");
    590                           MAKERXSTRING( *prsResult, "0", 1 );
     594                          SaveResultString( prsResult, PSZ_ZERO, 1 );   // 2016-02-20 SHL
    591595                          return ( 0 );
    592596                      }
     
    598602        if ( pszProcName == NULL ) {
    599603            WriteErrorCode( ERROR_NOT_ENOUGH_MEMORY, "calloc");
    600             MAKERXSTRING( *prsResult, "0", 1 );
     604            SaveResultString( prsResult, PSZ_ZERO, 1 ); // 2016-02-20 SHL
    601605            return ( 0 );
    602606        }
     
    604608    }
    605609
    606     if ( pszProcName != NULL ) {
     610    if ( pszProcName ) {
    607611        // Get the process PID
    608612        rc = GetProcess( pszProcName, szFullName, &ulPID, &ulPPID, &ulType, &usPrty, &ulTime );
    609613        if (( rc != NO_ERROR ) || ( ulPID == 0 )) {
    610             MAKERXSTRING( *prsResult, "0", 1 );
     614            free( pszProcName );
     615            SaveResultString( prsResult, PSZ_ZERO, 1 ); // 2016-02-20 SHL
    611616            return ( 0 );
    612617        }
     
    617622    if ( rc != NO_ERROR ) {
    618623        WriteErrorCode( rc, "DosKillProcess");
    619         MAKERXSTRING( *prsResult, "0", 1 );
    620         return ( 0 );
    621     }
    622 
    623     MAKERXSTRING( *prsResult, "1", 1 );
     624        SaveResultString( prsResult, PSZ_ZERO, 1 );     // 2016-02-20 SHL
     625    }
     626    else
     627        SaveResultString( prsResult, PSZ_ONE, 1 );      // 2016-02-20 SHL
     628
     629    // 2016-02-20 SHL Avoid leak
     630    if ( pszProcName )
     631      free( pszProcName );
     632
    624633    return ( 0 );
    625634}
     
    683692    pBuf = (QSPTRREC *) malloc( UL_SSBUFSIZE );
    684693#else
    685     pBuf = (QSPTRREC *) malloc( UL_SSBUFSIZE ); // 2015-04-23 SHL
     694    pBuf = (QSPTRREC *) malloc( UL_SSBUFSIZE ); // 2015-04-23 SHL
    686695#endif
    687696
    688697    if ( pBuf == NULL ) {
    689698        WriteErrorCode( ERROR_NOT_ENOUGH_MEMORY, "malloc");
    690         MAKERXSTRING( *prsResult, "", 0 );
     699        SaveResultString( prsResult, NULL, 0 ); // 2016-02-20 SHL
    691700        return ( 0 );
    692701    }
     
    697706    if ( rc != NO_ERROR ) {
    698707        WriteErrorCode( rc, "DosQProcStatus");
    699         MAKERXSTRING( *prsResult, "", 0 );
     708        SaveResultString( prsResult, NULL, 0 ); // 2016-02-20 SHL
    700709        return ( 0 );
    701710    }
     
    705714    if ( rc != NO_ERROR ) {
    706715        WriteErrorCode( rc, "DosQuerySysState");
    707         MAKERXSTRING( *prsResult, "", 0 );
     716        SaveResultString( prsResult, NULL, 0 ); // 2016-02-20 SHL
    708717        return ( 0 );
    709718    }
     
    712721    // Now get the list of processes
    713722    ulCount = 0;
    714 #   if 1 // 2015-06-12 SHL FIXME to know if can occur
    715     if ( pBuf->pProcRec == NULL ) {
    716         WriteErrorCode( rc, "pBuf->pProcRec NULL");
    717         MAKERXSTRING( *prsResult, "", 0 );
     723#   if 1 // 2016-02-25 SHL FIXME debug bad pointer
     724    // 2016-02-26 SHL FIXME to be gone when sure this can not occur
     725    if ( (ULONG)pBuf->pProcRec < 0x10000 ) {
     726        sprintf( szName, "rxutilex#%u pBuf->pProcRec 0x%x < 0x10000",
     727                 __LINE__, (ULONG)pBuf->pProcRec );
     728        WriteErrorCode( ERROR_INVALID_ADDRESS, szName );
     729        SaveResultString( prsResult, NULL, 0 );
     730        free( pBuf );
    718731        return ( 0 );
    719732    }
    720733#   endif
    721734
    722     // 2015-06-12 SHL pThrdRec can be 0 - probably when process starting or dieing
    723735    for (pPrec = pBuf->pProcRec;
    724736         ;
    725          pPrec = pPrec->pThrdRec ?
    726                    (QSPREC *)(pPrec->pThrdRec + pPrec->cTCB) :
    727                    pPrec + 1
     737         pPrec = (QSPREC *)(pPrec->pThrdRec + pPrec->cTCB)
    728738        )
    729739
    730740    {
    731 #       if 1
    732         // 2015-06-19 SHL FIXME to be gone if proven that never can occur
    733         if ((ULONG)pPrec < 0x10000) {
    734             fprintf(stderr, "* rxutilex#%u ulCount %u pPrec %p\n", __LINE__, ulCount, pPrec);
    735             break;                      // Avoid death
     741#       if 0 // 2015-06-19 SHL FIXME debug bad pointer
     742        // 2016-02-26 SHL FIMXE to be gone when sure no longer needed
     743        if ( (ULONG)pPrec < 0x10000 ) {
     744            sprintf( szName, "rxutilex#%u pPrec 0x%x < 0x10000",
     745                     __LINE__, (ULONG)pPrec );
     746            WriteErrorCode( ERROR_INVALID_ADDRESS, szName );
     747            SaveResultString( prsResult, NULL, 0 );
     748            free( pBuf );
     749            return ( 0 );
    736750        }
    737751#       endif
    738752
    739         // 2015-06-19 SHL FIXME debug was trapping here if pThrdRec NULL
    740         if (pPrec->RecType != QS_PROCESS)
    741             break;
    742 
    743 #       if 1
    744         /* Avoid death if no threads
    745            This is undocumented but probably occurs if called while process
    746            is starting or terminating
    747            2015-07-31 SHL
    748         */
    749         if (!pPrec->cTCB)
    750           fprintf(stderr, "* rxutilex#%u ulCount %u pBuf %p pPrec %p pPrec->pThrdRec %p pPrec->cTCB %u\n", __LINE__, ulCount, pBuf, pPrec, pPrec->pThrdRec, pPrec->cTCB);
    751         // 2015-07-31 SHL FIXME debug
    752         if ((ULONG)(pPrec->pThrdRec) < 0x10000) {
    753           fprintf(stderr, "* rxutilex#%u ulCount %u pBuf %p pPrec %p pPrec->pThrdRec %p pPrec->cTCB %u\n", __LINE__, ulCount, pBuf, pPrec, pPrec->pThrdRec, pPrec->cTCB);
    754           break;                        // Avoid death
     753        // Check for documented end marker - RecType not QS_PROCESS
     754        if ( pPrec->RecType != QS_PROCESS ) {
     755#           if 0 // 2016-02-26 SHL FIXME debug
     756            fprintf( stderr,
     757                     "* rxutilex#%u RecType != QS_PROCESS "
     758                     "ulCount %u pBuf %p pPrec %p ->RecType %x ->pThrdRec %p ->pid %u ->ppid %u ->type %u ->stat %u ->hmte %x ->cTCB %u\n",
     759                     __LINE__, ulCount, pBuf, pPrec, pPrec->RecType, pPrec->pThrdRec,
     760                     pPrec->pid, pPrec->ppid,
     761                     pPrec->type, pPrec->stat, pPrec->hMte, pPrec->cTCB );
     762#           endif
     763            break;                      // Must be end of list
     764        }
     765
     766        // Check for alternate end marker - pThredRec NULL
     767        // This appears to be an undocumented end marker
     768        // Might be a defect - testing says only RecType is non-zero
     769        // 2015-06-12 SHL pThrdRec can be 0 - probably when process starting or dieing
     770        if ( (PVOID)pPrec->pThrdRec == NULL ) {
     771#           if 0 // 2016-02-26 SHL FIXME debug
     772            fprintf( stderr,
     773                     "* rxutilex#%u pThrdRec NULL "
     774                     "ulCount %u pBuf %p pPrec %p ->pThrdRec %p ->pid %u ->ppid %u ->type %u ->stat %u ->hmte %x ->cTCB %u\n",
     775                     __LINE__, ulCount, pBuf, pPrec, pPrec->pThrdRec, pPrec->pid, pPrec->ppid,
     776                     pPrec->type, pPrec->stat, pPrec->hMte, pPrec->cTCB );
     777#           endif
     778            break;                      // Must be end of list
     779        }
     780
     781#       if 1 // 2015-07-31 SHL FIXME debug bad pointer
     782        // 2016-02-26 SHL FIXME to be gone when sure can not occur
     783        if ( (ULONG)(pPrec->pThrdRec) < 0x10000 ) {
     784            sprintf( szName,
     785                     "rxutilex#%u pPrec < 0x10000 "
     786                     "ulCount %u pBuf %p pPrec %p ->pThrdRec %p ->pid %u ->ppid %u ->type %u ->stat %u ->hmte %x ->cTCB %u\n",
     787                     __LINE__, ulCount, pBuf, pPrec, pPrec->pThrdRec, pPrec->pid, pPrec->ppid,
     788                     pPrec->type, pPrec->stat, pPrec->hMte, pPrec->cTCB );
     789            WriteErrorCode( ERROR_INVALID_ADDRESS, szName );
     790            SaveResultString( prsResult, NULL, 0 );
     791            free( pBuf );
     792            return ( 0 );
     793        }
     794#       endif
     795#       if 1 // 2016-02-26 SHL FIXME debug bad count
     796        // 2016-02-26 SHL FIXME to be gone when sure can not occur
     797        // This is probably occurs only when pThrdRec NULL too which is already checked
     798        if ( !pPrec->cTCB ) {
     799            sprintf( szName, "rxutilex#%u cTCB 0 ulCount %u pBuf %p pPrec %p ->pid %u ->type %u ->stat %u\n",
     800                     __LINE__, ulCount, pBuf, pPrec, pPrec->pid, pPrec->type, pPrec->stat );
     801            WriteErrorCode( ERROR_INVALID_DATA, szName );
     802            SaveResultString( prsResult, NULL, 0 );
     803            free( pBuf );
     804            return ( 0 );
    755805        }
    756806#       endif
     
    784834        WriteStemElement( szStem, ulCount, szPInfo );
    785835
    786 #       if 1    // 2015-07-31 SHL FIXME debug
    787         // 2015-07-31 SHL FIXME debug
    788         if (!pPrec->cTCB) {
    789           fprintf(stderr, "* rxutilex: szPInfo %s\n", szPInfo);
    790           fprintf(stderr, "* rxutilex: ulCount %u pBuf %p pPrec %p pPrec->pThrdRec %p pPrec->cTCB %u\n", ulCount, pBuf, pPrec, pPrec->pThrdRec, pPrec->cTCB);
    791           fprintf(stderr, "* rxutilex: next RecType %x\n", (pPrec + 1)->RecType);
    792     }
    793         // 2015-07-31 SHL FIXME debug
    794         if ((ULONG)pPrec->pThrdRec < 0x10000 || !pPrec->cTCB) {
    795           fprintf(stderr, "* rxutilex: szPInfo %s\n", szPInfo);
    796           fprintf(stderr, "* rxutilex: ulCount %u pBuf %p pPrec %p pPrec->pThrdRec %p pPrec->cTCB %u\n", ulCount, pBuf, pPrec, pPrec->pThrdRec, pPrec->cTCB);
    797           fprintf(stderr, "* rxutilex: next RecType %x\n", (pPrec + 1)->RecType);
    798           break;                // Avoid death
     836#       if 0 // 2015-07-31 SHL FIXME debug bad count
     837        // 2016-02-26 SHL FIXME to be gone when sure no longer needed
     838        if ( !pPrec->cTCB ) {
     839            sprintf( szName, "rxutilex#%u: cTCB 0 "
     840                     "ulCount %u pBuf %p pPrec %p ->pThrdRec %p ->pid %u\n",
     841                     __LINE__, ulCount, pBuf, pPrec, pPrec->pThrdRec, pPrec->pid );
     842            WriteErrorCode( ERROR_INVALID_DATA, szName );
     843            SaveResultString( prsResult, NULL, 0 );
     844            free( pBuf );
     845            return ( 0 );
     846        }
     847#       endif
     848#       if 0    // 2015-07-31 SHL FIXME debug bad pointer
     849        // 2016-02-26 SHL FIXME to be gone when sure no longer needed
     850        if ( (ULONG)pPrec->pThrdRec < 0x10000 ) {
     851            sprintf( szName,
     852                     "rxutilex#%u: pBuf->pThrdRec < 0x10000 "
     853                     "ulCount %u pBuf %p pPrec %p ->pThrdRec %p ->pid %u ->cTCB %u\n",
     854                     __LINE__, ulCount, pBuf, pPrec, pPrec->pThrdRec, pPrec->pid, pPrec->cTCB );
     855            WriteErrorCode( rc, szName );
     856            SaveResultString( prsResult, NULL, 0 );
     857            free( pBuf );
     858            return ( 0 );
    799859        }
    800860#       endif
    801861    } // for
    802862
    803     // Create the "0" stem element with the number of processes found
     863    // Create the stem.0 element with the number of processes found
    804864    sprintf( szNumber, "%d", ulCount );
    805865    WriteStemElement( szStem, 0, szNumber );
    806866
    807867    // And also return the number of processes as the REXX return string
    808     MAKERXSTRING( *prsResult, szNumber, strlen(szNumber) );
     868    SaveResultString( prsResult, szNumber, strlen(szNumber) );  // 2016-02-20 SHL
    809869
    810870    free( pBuf );
     
    842902    if ( rc != NO_ERROR ) {
    843903        WriteErrorCode( rc, "DosQuerySysInfo");
    844         MAKERXSTRING( *prsResult, "0", 1 );
     904        SaveResultString( prsResult, PSZ_ZERO, 1 );     // 2016-02-20 SHL
    845905        return ( 0 );
    846906    }
     
    851911
    852912    // Return the memory size as the REXX return string
    853     MAKERXSTRING( *prsResult, szMemSize, strlen(szMemSize) );
     913    SaveResultString( prsResult, szMemSize, strlen(szMemSize) );        // 2016-02-20 SHL
    854914
    855915    return ( 0 );
     
    886946    if ( rc != NO_ERROR ) {
    887947        WriteErrorCode( rc, "DosQuerySysInfo");
    888         MAKERXSTRING( *prsResult, "0", 1 );
     948        SaveResultString( prsResult, PSZ_ZERO, 1 );     // 2016-02-20 SHL
    889949        return ( 0 );
    890950    }
     
    892952
    893953    // Return the PID as the REXX return string
    894     MAKERXSTRING( *prsResult, szPID, strlen(szPID) );
     954    SaveResultString( prsResult, szPID, strlen(szPID) );          // 2016-02-20 SHL
    895955
    896956    return ( 0 );
     
    926986    if ( pszOldModule == NULL ) {
    927987        WriteErrorCode( ERROR_NOT_ENOUGH_MEMORY, "calloc");
    928         MAKERXSTRING( *prsResult, "0", 1 );
     988        SaveResultString( prsResult, PSZ_ZERO, 1 );     // 2016-02-20 SHL
    929989        return ( 0 );
    930990    }
     
    937997            if ( pszNewModule == NULL ) {
    938998                WriteErrorCode( ERROR_NOT_ENOUGH_MEMORY, "calloc");
    939                 MAKERXSTRING( *prsResult, "0", 1 );
     999                SaveResultString( prsResult, PSZ_ZERO, 1 );     // 2016-02-20 SHL
    9401000                return ( 0 );
    9411001            }
     
    9501010            if ( pszBackup == NULL ) {
    9511011                WriteErrorCode( ERROR_NOT_ENOUGH_MEMORY, "calloc");
    952                 MAKERXSTRING( *prsResult, "0", 1 );
     1012                SaveResultString( prsResult, PSZ_ZERO, 1 );     // 2016-02-20 SHL
    9531013                return ( 0 );
    9541014            }
     
    9611021    if ( rc != NO_ERROR ) {
    9621022        WriteErrorCode( rc, "DosReplaceModule");
    963         MAKERXSTRING( *prsResult, "0", 1 );
     1023        SaveResultString( prsResult, PSZ_ZERO, 1 );     // 2016-02-20 SHL
    9641024        return ( 0 );
    9651025    }
    9661026
    9671027    // Return 1 on success
    968     MAKERXSTRING( *prsResult, "1", 1 );
     1028    SaveResultString( prsResult, PSZ_ONE, 1 );  // 2016-02-20 SHL
    9691029
    9701030    return ( 0 );
     
    9851045 *      values.  Ignored for integer values.                    (DEFAULT: 2) *
    9861046 *                                                                           *
    987  * REXX RETURN VALUE: The formatted number, or '' on error.                  *
     1047 * REXX RETURN VALUE: The formatted number, or "" on error.                  *
    9881048 * ------------------------------------------------------------------------- */
    9891049ULONG APIENTRY Sys2FormatNumber( PSZ pszName, ULONG argc, RXSTRING argv[], PSZ pszQueue, PRXSTRING prsResult )
     
    10151075         */
    10161076        PSZ pszLang, p;
    1017         if (( DosScanEnv("LANG", &pszLang ) == NO_ERROR ) &&
    1018             pszLang && ( strlen( pszLang ) >= 2 ))
     1077        if ( DosScanEnv( "LANG", &pszLang ) == NO_ERROR &&
     1078             pszLang &&
     1079             strlen(pszLang) >= 2 )
    10191080        {
    10201081            p = strdup( pszLang );
     
    10911152    if ( rc != ULS_SUCCESS ) {
    10921153        WriteErrorCode( rc, "UniCreateLocaleObject");
    1093         MAKERXSTRING( *prsResult, "", 0 );
     1154        SaveResultString( prsResult, NULL, 0 ); // 2016-02-20 SHL
    10941155        return ( 0 );
    10951156    }
     
    10971158    if ( rc != ULS_SUCCESS ) {
    10981159        WriteErrorCode( rc, "UniQueryLocaleInfo");
    1099         MAKERXSTRING( *prsResult, "", 0 );
     1160        SaveResultString( prsResult, NULL, 0 ); // 2016-02-20 SHL
    11001161        return ( 0 );
    11011162     }
     
    11211182
    11221183    // Return the formatted number
    1123     MAKERXSTRING( *prsResult, achNumber, strlen( achNumber ));
     1184    SaveResultString( prsResult, achNumber, strlen(achNumber) );        // 2016-02-20 SHL
    11241185
    11251186    return ( 0 );
     
    11471208 *        L = convert to local time using the current TZ (DEFAULT)           *
    11481209 *                                                                           *
    1149  * REXX RETURN VALUE: The formatted time string, or '' on error.             *
     1210 * REXX RETURN VALUE: The formatted time string, or "" on error.             *
    11501211 * ------------------------------------------------------------------------- */
    11511212ULONG APIENTRY Sys2FormatTime( PSZ pszName, ULONG argc, RXSTRING argv[], PSZ pszQueue, PRXSTRING prsResult )
     
    12031264     */
    12041265    DosScanEnv("TZ", &pszTZ );
    1205     pszSetTZ = (PSZ) malloc( strlen( pszTZ ) + 5 );
     1266    pszSetTZ = (PSZ) malloc( strlen(pszTZ) + 5 );
    12061267    if ( pszSetTZ ) {
    12071268        sprintf( pszSetTZ, "TZ=%s", pszTZ );
     
    12171278        if ( ttSeconds == -1 ) {
    12181279            WriteErrorCode( ttSeconds, "time");
    1219             MAKERXSTRING( *prsResult, "", 0 );
     1280            SaveResultString( prsResult, NULL, 0 );     // 2016-02-20 SHL
    12201281            if ( pszSetTZ ) free( pszSetTZ );
    12211282            return 0;
     
    12271288        if ( !timeptr ) {
    12281289            WriteErrorCode( 1, "gmtime");
    1229             MAKERXSTRING( *prsResult, "0", 1 );
     1290            SaveResultString( prsResult, NULL, 0 );     // 2016-02-20 SHL       // 2016-02-20 SHL
    12301291            if ( pszSetTZ ) free( pszSetTZ );
    12311292            return 0;
     
    12361297        if ( !timeptr ) {
    12371298            WriteErrorCode( 1, "localtime");
    1238             MAKERXSTRING( *prsResult, "0", 1 );
     1299            SaveResultString( prsResult, NULL, 0 );     // 2016-02-20 SHL
    12391300            if ( pszSetTZ ) free( pszSetTZ );
    12401301            return 0;
     
    12611322    if ( stRC == NO_ERROR ) {
    12621323        WriteErrorCode( stRC, "strftime");
    1263         MAKERXSTRING( *prsResult, "", 0 );
     1324        SaveResultString( prsResult, NULL, 0 ); // 2016-02-20 SHL
    12641325        if ( pszSetTZ ) free( pszSetTZ );
    12651326        return ( 0 );
     
    12671328
    12681329    // Return the formatted time string
    1269     MAKERXSTRING( *prsResult, szTime, strlen(szTime) );
     1330    SaveResultString( prsResult, szTime, strlen(szTime) );      // 2016-02-20 SHL
    12701331
    12711332    if ( pszSetTZ ) free( pszSetTZ );
     
    13761437     */
    13771438    DosScanEnv("TZ", &pszTZ );
    1378     pszSetTZ = (PSZ) malloc( strlen( pszTZ ) + 5 );
     1439    pszSetTZ = (PSZ) malloc( strlen(pszTZ) + 5 );
    13791440    sprintf( pszSetTZ, "TZ=%s", pszTZ );
    13801441    putenv( pszSetTZ );
     
    13901451        if ( timeval == -1 ) {
    13911452            WriteErrorCode( timeval, "time");
    1392             MAKERXSTRING( *prsResult, "0", 1 );
     1453            SaveResultString( prsResult, PSZ_ZERO, 1 ); // 2016-02-20 SHL
    13931454            free( pszSetTZ );
    13941455            return 0;
     
    14071468        if ( timeval == -1 ) {
    14081469            WriteErrorCode( timeval, "mktime");
    1409             MAKERXSTRING( *prsResult, "0", 1 );
     1470            SaveResultString( prsResult, PSZ_ZERO, 1 ); // 2016-02-20 SHL
    14101471            free( pszSetTZ );
    14111472            return 0;
     
    14191480    sprintf( szEpochTime, "%d", timeval );
    14201481#endif
    1421     MAKERXSTRING( *prsResult, szEpochTime, strlen(szEpochTime) );
     1482    SaveResultString( prsResult, szEpochTime, strlen(szEpochTime) );    // 2016-02-20 SHL
    14221483
    14231484    free( pszSetTZ );
     
    14401501 *                                                                           *
    14411502 * REXX RETURN VALUE:                                                        *
    1442  *   The fully-qualified path of the DLL, if found (or '' if not found).     *
     1503 *   The fully-qualified path of the DLL, if found (or "" if not found).     *
    14431504 * ------------------------------------------------------------------------- */
    14441505ULONG APIENTRY Sys2LocateDLL( PSZ pszName, ULONG argc, RXSTRING argv[], PSZ pszQueue, PRXSTRING prsResult )
     
    14721533        if ( bLoadedOnly ) {
    14731534            // Just return
    1474             MAKERXSTRING( *prsResult, "", 0 );
     1535            SaveResultString( prsResult, NULL, 0 );     // 2016-02-20 SHL
    14751536            return 0;
    14761537        }
     
    14791540        if ( rc ) {
    14801541            WriteErrorCode( rc, "DosLoadModule");
    1481             MAKERXSTRING( *prsResult, "", 0 );
     1542            SaveResultString( prsResult, NULL, 0 );     // 2016-02-20 SHL
    14821543            return 0;
    14831544        }
     
    14891550    if ( rc ) {
    14901551        WriteErrorCode( rc, "DosQueryModuleName");
    1491         MAKERXSTRING( *prsResult, "", 0 );
     1552        SaveResultString( prsResult, NULL, 0 ); // 2016-02-20 SHL
    14921553        if ( bUnload ) DosFreeModule( hmod );
    14931554        return 0;
     
    14981559
    14991560    // Return the full path name
    1500     if ( ! SaveResultString( prsResult, achModuleName, strlen( achModuleName ))) {
    1501         MAKERXSTRING( *prsResult, "", 0 );
    1502     }
     1561    SaveResultString( prsResult, achModuleName, strlen(achModuleName) );        // 2016-02-20 SHL
    15031562
    15041563    return 0;
     
    15341593 *                                                                           *
    15351594 * REXX RETURN VALUE:                                                        *
    1536  *   A four-byte pipe handle.                                                *
     1595 *   A four-byte pipe handle or 0 if create fails                            *
    15371596 * ------------------------------------------------------------------------- */
    15381597ULONG APIENTRY Sys2CreateNamedPipe( PSZ pszName, ULONG argc, RXSTRING argv[], PSZ pszQueue, PRXSTRING prsResult )
     
    16231682    if ( pszNPName == NULL ) {
    16241683        WriteErrorCode( ERROR_NOT_ENOUGH_MEMORY, "calloc");
    1625         MAKERXSTRING( *prsResult, "0", 1 );
     1684        SaveResultString( prsResult, PSZ_ZERO, 1 );     // 2016-02-20 SHL
    16261685        return ( 0 );
    16271686    }
     
    16321691    if (rc) {
    16331692        WriteErrorCode( rc, "DosCreateNPipe");
    1634         MAKERXSTRING( *prsResult, "", 0 );
     1693        SaveResultString( prsResult, PSZ_ZERO, 1 );     // 2016-02-20 SHL
    16351694        return 0;
    16361695    }
     
    16381697    // Return the handle as the REXX result string
    16391698    sprintf( achHandle, "%8X", hp );
    1640     MAKERXSTRING( *prsResult, achHandle, strlen( achHandle ));
     1699    SaveResultString( prsResult, achHandle, strlen(achHandle) ); // 2016-02-20 SHL
    16411700
    16421701    free( pszNPName );
     
    16811740    {
    16821741        WriteErrorCode( rc, "DosConnectNPipe");
    1683         MAKERXSTRING( *prsResult, "0", 1 );
     1742        SaveResultString( prsResult, PSZ_ZERO, 1 );     // 2016-02-20 SHL
    16841743        return ( 0 );
    16851744    }
    16861745
    16871746    // Return 1 on success
    1688     MAKERXSTRING( *prsResult, "1", 1 );
     1747    SaveResultString( prsResult, PSZ_ONE, 1 );  // 2016-02-20 SHL
    16891748    return ( 0 );
    16901749}
     
    17181777    if ( rc != NO_ERROR ) {
    17191778        WriteErrorCode( rc, "DosDisConnectNPipe");
    1720         MAKERXSTRING( *prsResult, "0", 1 );
     1779        SaveResultString( prsResult, PSZ_ZERO, 1 );     // 2016-02-20 SHL
    17211780        return ( 0 );
    17221781    }
    17231782
    17241783    // Return 1 on success
    1725     MAKERXSTRING( *prsResult, "1", 1 );
     1784    SaveResultString( prsResult, PSZ_ONE, 1 );  // 2016-02-20 SHL
    17261785    return ( 0 );
    17271786}
     
    17391798 *   String of the format "bytes status", where bytes is the number of bytes *
    17401799 *   currently waiting in the pipe, and status is one of: DISCONNECTED,      *
    1741  *   LISTENING, CONNECTED, or CLOSING.                                       *
     1800 *   LISTENING, CONNECTED, or CLOSING or "" if API error                     *
    17421801 * ------------------------------------------------------------------------- */
    17431802ULONG APIENTRY Sys2CheckNamedPipe( PSZ pszName, ULONG argc, RXSTRING argv[], PSZ pszQueue, PRXSTRING prsResult )
     
    17591818    if ( rc != NO_ERROR ) {
    17601819        WriteErrorCode( rc, "DosPeekNPipe");
    1761         MAKERXSTRING( *prsResult, "", 0 );
     1820        SaveResultString( prsResult, NULL, 0 ); // 2016-02-20 SHL
    17621821        return ( 0 );
    17631822    }
     
    17711830    }
    17721831
    1773     if ( ! SaveResultString( prsResult, szStatus, strlen( szStatus ))) {
    1774         MAKERXSTRING( *prsResult, "", 0 );
    1775     }
     1832    SaveResultString( prsResult, szStatus, strlen(szStatus) );  // 2016-02-20 SHL
     1833
    17761834    return ( 0 );
    17771835}
     
    19532011    if ( pszFile == NULL ) {
    19542012        WriteErrorCode( ERROR_NOT_ENOUGH_MEMORY, "calloc");
    1955         MAKERXSTRING( *prsResult, "0", 1 );
     2013        SaveResultString( prsResult, NULL, 0 ); // 2016-02-20 SHL
    19562014        return ( 0 );
    19572015    }
     
    19622020    if (rc) {
    19632021        WriteErrorCode( rc, "DosOpenL");
    1964         MAKERXSTRING( *prsResult, "", 0 );
     2022        SaveResultString( prsResult, NULL, 0 ); // 2016-02-20 SHL
    19652023        free( pszFile );
    19662024        return ( 0 );
     
    19692027    // Return the handle as the REXX result string
    19702028    sprintf( achHandle, "%8X", hf );
    1971     MAKERXSTRING( *prsResult, achHandle, strlen( achHandle ));
     2029    SaveResultString( prsResult, achHandle, strlen(achHandle) );        // 2016-02-20 SHL
    19722030
    19732031    free( pszFile );
     
    20042062    if ( rc != NO_ERROR ) {
    20052063        WriteErrorCode( rc, "DosClose");
    2006         MAKERXSTRING( *prsResult, "0", 1 );
     2064        SaveResultString( prsResult, PSZ_ZERO, 1 );     // 2016-02-20 SHL
    20072065    }
    20082066    else {
    2009         MAKERXSTRING( *prsResult, "1", 1 );
     2067        SaveResultString( prsResult, PSZ_ONE, 1 );      // 2016-02-20 SHL
    20102068    }
    20112069
     
    20292087 *                                                                           *
    20302088 * REXX RETURN VALUE:                                                        *
    2031  *   The new file position, in bytes.                                        *
     2089 *   The new file position, in bytes or "" if error                          *
    20322090 * ------------------------------------------------------------------------- */
    20332091ULONG APIENTRY Sys2Seek( PSZ pszName, ULONG argc, RXSTRING argv[], PSZ pszQueue, PRXSTRING prsResult )
     
    20672125    if ( rc != NO_ERROR ) {
    20682126        WriteErrorCode( rc, "DosSetFilePtrL");
    2069         MAKERXSTRING( *prsResult, "", 0 );
     2127        SaveResultString( prsResult, NULL, 0 ); // 2016-02-20 SHL
    20702128        return ( 0 );
    20712129    }
     
    20732131    // Return the new position as the REXX result string
    20742132    sprintf( achActual, "%lld", llActual );
    2075     MAKERXSTRING( *prsResult, achActual, strlen( achActual ));
     2133    SaveResultString( prsResult, achActual, strlen(achActual) );        // 2016-02-20 SHL
    20762134
    20772135    return ( 0 );
     
    21172175    if ( rc || !cbActual ) {
    21182176        WriteErrorCode( rc, "DosRead");
    2119         MAKERXSTRING( *prsResult, "", 0 );
     2177        SaveResultString( prsResult, NULL, 0 ); // 2016-02-20 SHL
    21202178        goto cleanup;
    21212179    }
    2122     if ( ! SaveResultString( prsResult, pszData, cbActual )) {
    2123         MAKERXSTRING( *prsResult, "", 0 );
    2124     }
     2180    SaveResultString( prsResult, pszData, cbActual );   // 2016-02-20 SHL
    21252181
    21262182cleanup:
     
    21642220    if ( rc != NO_ERROR ) {
    21652221        WriteErrorCode( rc, "DosWrite");
    2166         MAKERXSTRING( *prsResult, "0", 1 );
     2222        SaveResultString( prsResult, PSZ_ZERO, 1 );     // 2016-02-20 SHL
    21672223        return ( 0 );
    21682224    }
    21692225
    21702226    sprintf( szActual, "%d", cbActual );
    2171     MAKERXSTRING( *prsResult, szActual, strlen( szActual ));
     2227    SaveResultString( prsResult, szActual, strlen(szActual) );  // 2016-02-20 SHL
    21722228    return ( 0 );
    21732229}
     
    22032259    if ( rc != NO_ERROR ) {
    22042260        WriteErrorCode( rc, "DosResetBuffer");
    2205         MAKERXSTRING( *prsResult, "0", 1 );
     2261        SaveResultString( prsResult, PSZ_ZERO, 1 );     // 2016-02-20 SHL
    22062262    }
    22072263    else {
    2208         MAKERXSTRING( *prsResult, "1", 1 );
     2264        SaveResultString( prsResult, PSZ_ONE, 1 );      // 2016-02-20 SHL
    22092265    }
    22102266
     
    22392295 *   0 on success, or a non-zero API return code in the case of an error.    *
    22402296 * ------------------------------------------------------------------------- */
    2241 ULONG GetProcess( PSZ pszProgram,
     2297// 2016-02-20 SHL Rework to avoid traps
     2298ULONG GetProcess( PCSZ pszProgram,
    22422299                  PSZ pszFullName,
    22432300                  PULONG pulPID,
     
    22502307    QSPTRREC *pBuf;                     // Data returned by DosQProcStatus()
    22512308#else
    2252     QSPTRREC *pBuf;                     // Data returned by DosQuerySysState()  // 2015-04-23 SHL
     2309    QSPTRREC *pBuf;                     // Data returned by DosQuerySysState()  // 2015-04-23 SHL
    22532310#endif
    22542311    QSPREC *pPrec;                      // Pointer to process information block
     
    22652322    APIRET rc;                          // Return code
    22662323
    2267 
    22682324    // Use current process when PID is 0 and program name is not specified
    22692325    if (( pszProgram == NULL ) && ( *pulPID == 0 )) {
     
    22792335    pBuf = (QSPTRREC *) malloc( UL_SSBUFSIZE );
    22802336#else
    2281     pBuf = (QSPTRREC *) malloc( UL_SSBUFSIZE ); // 2015-04-23 SHL
     2337    pBuf = (QSPTRREC *) malloc( UL_SSBUFSIZE ); // 2015-04-23 SHL
    22822338#endif
    22832339
     
    23002356    if ( rc != NO_ERROR ) {
    23012357        WriteErrorCode( rc, "DosQuerySysState");
     2358        free( pBuf );
    23022359        return ( rc );
    23032360    }
    2304     pPrec = (QSPREC *)(((QSPTRREC*)pBuf) -> pProcRec);  // 2015-04-23 SHL
     2361    pPrec = (QSPREC *)(((QSPTRREC*)pBuf) -> pProcRec);  // 2015-04-23 SHL
    23052362#endif
    23062363
     
    23122369    else if ( *pulPID == 0 ) return 0;
    23132370
     2371#   if 1 // 2016-02-25 SHL FIXME debug bad pointer
     2372    // 2016-02-26 SHL FIXME to be gone when sure can not occur
     2373    if ( (ULONG)pPrec < 0x10000 ) {
     2374        sprintf( szName, "rxutilex#%u pPrec 0x%x < 0x10000", __LINE__, (ULONG)pPrec );
     2375        WriteErrorCode( ERROR_INVALID_ADDRESS, szName);
     2376        free( pBuf );
     2377        return ( 0 );
     2378    }
     2379#   endif
     2380
    23142381    // Now look for the specified process
    2315     while (( pPrec->RecType == 1 ) && ( !fMatch )) {
     2382    // List ends with RecType not QS_PROCESS or pThrdRec NULL
     2383    while ( pPrec->RecType == QS_PROCESS && pPrec->pThrdRec != NULL && !fMatch ) {
    23162384
    23172385        if ( pszProgram == NULL ) {
     2386            // Match by pid
    23182387            if ( pPrec->pid == *pulPID ) {
    23192388                fMatch = TRUE;
     
    23512420            // Create a copy without the extension
    23522421            strcpy( szNoExt, pszCurrent );
    2353             if (( c = strrchr( szNoExt, '.')) != NULL ) memset( c, 0, strlen(c) );
    2354             if (( pszCurrent != NULL ) &&
    2355                 (( stricmp(pszCurrent, pszProgram) == 0 ) || ( stricmp(szNoExt, pszProgram) == 0 )))
     2422            if ( ( c = strrchr( szNoExt, '.') ) != NULL )
     2423                memset( c, 0, strlen(c) );
     2424            if ( pszCurrent != NULL &&
     2425                 ( stricmp(pszCurrent, pszProgram) == 0 || stricmp(szNoExt, pszProgram) == 0 ) )
    23562426            {
    23572427                fMatch = TRUE;
     
    23772447            }
    23782448        }
    2379         pPrec = (QSPREC *) ( (PBYTE) (pPrec->pThrdRec) + ( pPrec->cTCB * sizeof(QSTREC) ) );
    2380     }
     2449        pPrec = (QSPREC *)(pPrec->pThrdRec + pPrec->cTCB);
     2450
     2451#       if 1 // 2016-02-25 SHL FIXME debug pointer - can this occur?
     2452        // 2016-02-26 SHL FIXME to be gone when sure can not occur
     2453        if ( (ULONG)pPrec < 0x10000 ) {
     2454            sprintf( szName, "rxutilex#%u pPrec 0x%x < 0x10000", __LINE__, (ULONG)pPrec );
     2455            WriteErrorCode( ERROR_INVALID_ADDRESS, szName);
     2456            free( pBuf );
     2457            return ( 0 );
     2458        }
     2459#       endif
     2460
     2461    } // while
    23812462    if ( !fMatch ) *pulPID = 0;
    23822463
     
    23902471 *                                                                           *
    23912472 * Writes new string contents to the specified RXSTRING, allocating any      *
    2392  * additional memory that may be required.  If the string to be written has  *
    2393  * zero length, nothing is done.                                             *
    2394  *                                                                           *
    2395  * This function should be used in place of MAKERXSTRING if there is a       *
    2396  * possibility that the string contents could be longer than 256 characters. *
     2473 * additional memory that may be required.                                   *
    23972474 *                                                                           *
    23982475 * ARGUMENTS:                                                                *
    23992476 *   PRXSTRING prsResult: Pointer to an existing RXSTRING for writing.       *
    2400  *   PCH       pchBytes : The string contents to write to prsResult.         *
    2401  *   ULONG     ulBytes  : The number of bytes in pchBytes to write.          *
     2477 *   PCH       pchBytes : The string contents to write to prsResult or NULL  *
     2478 *   ULONG     ulBytes  : The number of bytes in pchBytes to write 0..N.     *
    24022479 *                                                                           *
    24032480 * RETURNS: BOOL                                                             *
    24042481 *   TRUE if prsResult was successfully updated.  FALSE otherwise.           *
    24052482 * ------------------------------------------------------------------------- */
    2406 BOOL SaveResultString( PRXSTRING prsResult, PCH pchBytes, ULONG ulBytes )
     2483BOOL SaveResultString( PRXSTRING prsResult, PCSZ pchBytes, ULONG ulBytes )
    24072484{
    24082485    ULONG ulRC;
    24092486    PCH   pchNew;
    24102487
    2411     if ( ulBytes == 0 ) return ( FALSE );
     2488    // 2016-02-20 SHL Rework for easier usage
     2489    if (!pchBytes)
     2490      ulBytes = 0;                              // Sync for caller
    24122491    if ( ulBytes > 256 ) {
    24132492        // REXX provides 256 bytes by default; allocate more if necessary
     
    24152494        if ( ulRC != 0 ) {
    24162495            WriteErrorCode( ulRC, "DosAllocMem");
     2496            prsResult->strlength = 0;           // 2016-02-20 SHL Force result to empty string
    24172497            return ( FALSE );
    24182498        }
     
    24212501        prsResult->strptr = pchNew;
    24222502    }
    2423     memcpy( prsResult->strptr, pchBytes, ulBytes );
     2503    if (ulBytes)
     2504      memcpy( prsResult->strptr, pchBytes, ulBytes );
    24242505    prsResult->strlength = ulBytes;
    24252506
     
    24422523 *   TRUE on success, FALSE on failure.                                      *
    24432524 * ------------------------------------------------------------------------- */
    2444 BOOL WriteStemElement( PSZ pszStem, ULONG ulIndex, PSZ pszValue )
     2525// 2016-02-20 SHL
     2526BOOL WriteStemElement( PCSZ pszStem, ULONG ulIndex, PCSZ pszValue )
    24452527{
    24462528    SHVBLOCK shvVar;                   // REXX shared variable pool block
     
    24562538        // 2015-06-03 SHL Was using DosAllocMem and leaking memory
    24572539        // REXX API does not free this kind of buffer
    2458         ulBytes = strlen( pszValue );
     2540        ulBytes = strlen(pszValue);
    24592541    }
    24602542    MAKERXSTRING( shvVar.shvname, szCompoundName, strlen(szCompoundName) );
    2461     shvVar.shvvalue.strptr    = pszValue;
     2543    shvVar.shvvalue.strptr    = (PCH)pszValue;
    24622544    shvVar.shvvalue.strlength = ulBytes;
    24632545    shvVar.shvnamelen  = RXSTRLEN( shvVar.shvname );
     
    24892571 * RETURNS: N/A                                                              *
    24902572 * ------------------------------------------------------------------------- */
    2491 void WriteErrorCode( ULONG ulError, PSZ pszContext )
     2573void WriteErrorCode( ULONG ulError, PCSZ pszContext )
    24922574{
    24932575    SHVBLOCK shvVar;                   // REXX shared variable pool block
     
    25002582        sprintf( szErrorText, "%u: %s", ulError, pszContext );
    25012583    MAKERXSTRING( shvVar.shvname,  SZ_ERROR_NAME, strlen(SZ_ERROR_NAME) );
    2502     MAKERXSTRING( shvVar.shvvalue, szErrorText,   strlen(szErrorText) );
     2584    MAKERXSTRING( shvVar.shvvalue, szErrorText, strlen(szErrorText) );
    25032585    shvVar.shvnamelen  = RXSTRLEN( shvVar.shvname );
    25042586    shvVar.shvvaluelen = RXSTRLEN( shvVar.shvvalue );
    25052587    shvVar.shvcode     = RXSHV_SYSET;
    25062588    shvVar.shvnext     = NULL;
     2589    shvVar.shvret      = 0;             // 2016-02-26 SHL
    25072590    ulRc = RexxVariablePool( &shvVar );
    2508     if ( ulRc > 1 )
    2509         printf("Unable to set %s: rc = %d, ulRc = %x\n", shvVar.shvname.strptr, shvVar.shvret, ulRc ); /* 2015-04-23 SHL */
    2510 }
    2511 
    2512 
     2591    // 2016-02-26 SHL Correct if
     2592    if ( ulRc & ~RXSHV_NEWV )
     2593        printf("* Unable to set %s: shvret = 0x%x, apiret = 0x%x\n", shvVar.shvname.strptr, (UCHAR)shvVar.shvret, ulRc ); // 2016-02-26 SHL Correct formatting
     2594}
     2595
  • rxutilex/trunk/rxutilex.def

    r30 r31  
    11LIBRARY     RXUTILEX INITINSTANCE TERMINSTANCE
    22DATA        MULTIPLE NONSHARED
    3 DESCRIPTION '@#Alex Taylor:0.1.3#@##1## 27 Jan 2016 00:26:24     REINFORCE::::::@@Extended REXX Utility Functions'
     3DESCRIPTION '@#Alex Taylor:0.1.3#@##1## 30 Mar 2016 18:58:46     REINFORCE::::::@@Extended REXX Utility Functions'
    44
    55EXPORTS     Sys2LoadFuncs
Note: See TracChangeset for help on using the changeset viewer.