Changeset 127


Ignore:
Timestamp:
Jan 5, 2002, 8:11:10 PM (24 years ago)
Author:
umoeller
Message:

Tons of updates for turbo folders and replacement icons.

Location:
trunk
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/helpers/apps.h

    r123 r127  
    103103                                    const PROGDETAILS *pcProgDetails,
    104104                                    ULONG ulFlags,
    105                                     HAPP *phapp);
     105                                    HAPP *phapp,
     106                                    ULONG cbFailingName,
     107                                    PSZ pszFailingName);
    106108
    107109        BOOL XWPENTRY appWaitForApp(HWND hwndNotify,
  • trunk/include/helpers/comctl.h

    r115 r127  
    411411                // caused by a mouse click.
    412412    } EMPHASISNOTIFY, *PEMPHASISNOTIFY;
     413
     414    /* ******************************************************************
     415     *
     416     *   Super Combo Box
     417     *
     418     ********************************************************************/
     419
     420    BOOL ctlComboFromEntryField(HWND hwnd,
     421                                ULONG flStyle);
    413422
    414423    /* ******************************************************************
  • trunk/include/helpers/dosh.h

    r125 r127  
    345345                           ULONG ulAttr);
    346346
    347     APIRET doshOpenExisting(PCSZ pcszFilename,
     347    /* APIRET doshOpenExisting(PCSZ pcszFilename,
    348348                            ULONG ulOpenFlags,
    349349                            HFILE *phf);
    350 
    351     APIRET doshWriteAt(HFILE hf,
    352                        LONG lOffset,
    353                        ULONG ulMethod,
    354                        ULONG cb,
    355                        PBYTE pbData);
    356 
    357     APIRET doshReadAt(HFILE hf,
    358                       LONG lOffset,
    359                       ULONG ulMethod,
    360                       PULONG pcb,
    361                       PBYTE pbData);
     350       */
    362351
    363352    /*
     
    377366
    378367    #define XOPEN_READ_EXISTING           0x0001
    379     #define XOPEN_READWRITE_APPEND        0x0002
    380     #define XOPEN_READWRITE_NEW           0x0003
     368    #define XOPEN_READWRITE_EXISTING      0x0002
     369    #define XOPEN_READWRITE_APPEND        0x0003
     370    #define XOPEN_READWRITE_NEW           0x0004
    381371    #define XOPEN_ACCESS_MASK             0xffff
    382372
     
    388378                    PXFILE *ppFile);
    389379
     380    APIRET doshReadAt(PXFILE pFile,
     381                      ULONG ulOffset,
     382                      PULONG pcb,
     383                      PBYTE pbData);
     384
    390385    APIRET doshWrite(PXFILE pFile,
    391                      PCSZ pcsz,
    392                      ULONG cb);
     386                     ULONG cb,
     387                     PCSZ pbData);
     388
     389    APIRET doshWriteAt(PXFILE pFile,
     390                       ULONG ulOffset,
     391                       ULONG cb,
     392                       PCSZ pbData);
    393393
    394394    APIRET doshWriteLogEntry(PXFILE pFile,
     
    858858    #define EXEFORMAT_LX            4
    859859    #define EXEFORMAT_TEXT_BATCH    5
    860     #define EXEFORMAT_TEXT_REXX     6
     860    #define EXEFORMAT_TEXT_CMD      6       // REXX or plain OS/2 batch
     861    #define EXEFORMAT_COM           7       // added V0.9.16 (2002-01-04) [umoeller]
    861862
    862863    // target OS (in NE and LX)
     
    869870    #define EXEOS_WIN32             6
    870871
     872#ifndef __STRIP_DOWN_EXECUTABLE__
     873// for mini stubs in warpin, which has its own
     874// implementation of this
     875
    871876    /*
    872877     *@@ EXECUTABLE:
     
    877882    typedef struct _EXECUTABLE
    878883    {
    879         HFILE               hfExe;
     884        // executable opened by doshOpen
     885        PXFILE              pFile;
    880886
    881887        /* All the following fields are set by
     
    891897
    892898        // New Executable (NE) header, if ulExeFormat == EXEFORMAT_NE
    893 #ifndef __STRIP_DOWN_EXECUTABLE__       // for mini stubs in warpin, to reduce code size
    894899        PNEHEADER           pNEHeader;
    895900        ULONG               cbNEHeader;
    896 #endif
    897901
    898902        // Linear Executable (LX) header, if ulExeFormat == EXEFORMAT_LX
     
    901905
    902906        // Portable Executable (PE) header, if ulExeFormat == EXEFORMAT_PE
    903 #ifndef __STRIP_DOWN_EXECUTABLE__       // for mini stubs in warpin, to reduce code size
    904907        PPEHEADER           pPEHeader;
    905908        ULONG               cbPEHeader;
    906 #endif
     909
    907910        // module analysis (always set):
    908911        ULONG               ulExeFormat;
     
    913916                // EXEFORMAT_LX            4
    914917                // EXEFORMAT_TEXT_BATCH    5
    915                 // EXEFORMAT_TEXT_REXX     6
     918                // EXEFORMAT_TEXT_CMD      6
     919                // EXEFORMAT_COM           7
    916920
    917921        BOOL                fLibrary,           // TRUE if this is a DLL
     
    942946                // module info substring (if IBM BLDLEVEL format)
    943947
    944 #ifndef __STRIP_DOWN_EXECUTABLE__       // for mini stubs in warpin, to reduce code size
    945948        // if pszInfo is extended DESCRIPTION field, the following
    946949        // are set as well:
     
    964967        POS2NERESTBLENTRY       paOS2NEResTblEntry;
    965968        POS2NESEGMENT           paOS2NESegments;
    966 
    967 #endif
    968969    } EXECUTABLE, *PEXECUTABLE;
    969970
     
    10611062                              PCSZ *papcszExtensions,
    10621063                              ULONG cExtensions);
     1064#endif
    10631065
    10641066    /********************************************************************
     
    12641266    VOID doshFreeLVMInfo(PLVMINFO pInfo);
    12651267
     1268    /* ******************************************************************
     1269     *
     1270     *   Wildcard matching
     1271     *
     1272     ********************************************************************/
     1273
     1274    BOOL doshMatch(const char *pcszMask,
     1275                   const char *pcszName);
     1276
    12661277#endif
    12671278
  • trunk/include/helpers/gpih.h

    r125 r127  
    270270    HBITMAP XWPENTRY gpihCreateBitmap2(HPS hpsMem, ULONG  cx, ULONG cy, ULONG cPlanes, ULONG cBitCount);
    271271
    272     HBITMAP XWPENTRY gpihCreateBmpFromPS(HAB hab, HPS hpsScreen, PRECTL prcl);
    273     typedef HBITMAP XWPENTRY GPIHCREATEBMPFROMPS(HAB hab, HPS hpsScreen, PRECTL prcl);
    274     typedef GPIHCREATEBMPFROMPS *PGPIHCREATEBMPFROMPS;
    275 
    276272    HBITMAP XWPENTRY gpihCreateHalftonedBitmap(HAB hab, HBITMAP hbmSource, LONG lColorGray);
    277273    typedef HBITMAP XWPENTRY GPIHCREATEHALFTONEDBITMAP(HAB hab, HBITMAP hbmSource, LONG lColorGray);
     
    344340    typedef GPIHDESTROYXBITMAP *PGPIHDESTROYXBITMAP;
    345341
     342    PXBITMAP gpihCreateBmpFromPS(HAB hab,
     343                                 HPS hpsScreen,
     344                                 PRECTL prcl);
     345
    346346#endif
    347347
  • trunk/include/helpers/stringh.h

    r123 r127  
    166166    /* ******************************************************************
    167167     *
    168      *   Wildcard matching
    169      *
    170      ********************************************************************/
    171 
    172     #define FNM_MATCH           0
    173     #define FNM_NOMATCH         1
    174     #define FNM_ERR             2
    175 
    176     #define FNM_NOESCAPE        16
    177     #define FNM_PATHNAME        32
    178     #define FNM_PERIOD          64
    179 
    180     #define FNM_STYLE_MASK      15
    181 
    182     #define FNM_POSIX           0
    183     #define FNM_OS2             1
    184     #define FNM_DOS             2
    185 
    186     #define FNM_IGNORECASE      128
    187     #define FNM_PATHPREFIX      256
    188 
    189     BOOL XWPENTRY strhMatchOS2(const char *pcszMask, const char *pcszName);
    190 
    191     BOOL XWPENTRY strhMatchExt(const char *pcszMask,
    192                                const char *pcszName,
    193                                unsigned flags);
    194 
    195     /* ******************************************************************
    196      *
    197168     *   Fast string searches
    198169     *
  • trunk/include/helpers/undoc.h

    r41 r127  
    113113    #define ID_WPMI_REFRESH                0x1F7
    114114
    115     /*
    116      * Return codes for wpConfirmObjectTitle:
    117      *      only def'd in the Warp 4 Toolkit
    118      *      (and partly in wpsystem.h).
    119      */
    120 
    121     #ifndef NAMECLASH_CANCEL
    122         #define NAMECLASH_CANCEL    0
    123     #endif
    124     #ifndef NAMECLASH_NONE
    125         #define NAMECLASH_NONE      1
    126     #endif
    127     #ifndef NAMECLASH_RENAME
    128         #define NAMECLASH_RENAME    2
    129     #endif
    130     #ifndef NAMECLASH_REPLACE
    131         #define NAMECLASH_REPLACE   8
    132     #endif
    133115#endif
    134116
  • trunk/include/helpers/winh.h

    r113 r127  
    534534
    535535    #define winhQueryLboxSelectedItem(hwndListBox, sItemStart) \
    536             (SHORT)(WinSendMsg(hwndListBox,                    \
     536            SHORT1FROMMR(WinSendMsg(hwndListBox,                    \
    537537                            LM_QUERYSELECTION,                 \
    538538                            (MPARAM)(sItemStart),              \
  • trunk/include/helpers/wphandle.h

    r113 r127  
    5656    #define ERROR_WPH_NO_MATCHING_DRIVE_BLOCK       (ERROR_WPH_FIRST +  11)
    5757    #define ERROR_WPH_NO_MATCHING_ROOT_DIR          (ERROR_WPH_FIRST +  12)
     58    #define ERROR_WPH_NOT_FILESYSTEM_HANDLE         (ERROR_WPH_FIRST +  13)
    5859
    5960    /* ******************************************************************
  • trunk/src/helpers/apps.c

    r123 r127  
    3333
    3434#define INCL_DOSPROCESS
     35#define INCL_DOSMODULEMGR
    3536#define INCL_DOSSESMGR
    3637#define INCL_DOSERRORS
    3738
    3839#define INCL_WINPROGRAMLIST     // needed for PROGDETAILS, wppgm.h
     40#define INCL_WINERRORS
     41#define INCL_SHLERRORS
    3942#include <os2.h>
    4043
     
    107110
    108111APIRET appParseEnvironment(const char *pcszEnv,
    109                            PDOSENVIRONMENT pEnv)
     112                           PDOSENVIRONMENT pEnv)        // out: new environment
    110113{
    111114    APIRET arc = NO_ERROR;
     
    123126        }
    124127
    125         pEnv->cVars = cVars;
     128        pEnv->cVars = 0;
    126129        pEnv->papszVars = 0;
    127130
    128131        if (cVars)
    129132        {
    130             PSZ *papsz = (PSZ*)malloc(sizeof(PSZ) * cVars);
    131             if (!papsz)
     133            ULONG cbArray = sizeof(PSZ) * cVars;
     134            PSZ *papsz;
     135            if (!(papsz = (PSZ*)malloc(cbArray)))
    132136                arc = ERROR_NOT_ENOUGH_MEMORY;
    133137            else
    134138            {
    135139                PSZ *ppszTarget = papsz;
    136                 memset(papsz, 0, sizeof(PSZ) * cVars);
     140                memset(papsz, 0, cbArray);
    137141                pszVarThis = (PSZ)pcszEnv;
    138142                while (*pszVarThis)
    139143                {
    140                     *ppszTarget = strdup(pszVarThis);
     144                    ULONG ulThisLen;
     145                    if (!(*ppszTarget = strhdup(pszVarThis, &ulThisLen)))
     146                    {
     147                        arc = ERROR_NOT_ENOUGH_MEMORY;
     148                        break;
     149                    }
     150                    (pEnv->cVars)++;
    141151                    ppszTarget++;
    142                     pszVarThis += strlen(pszVarThis) + 1;
     152                    pszVarThis += ulThisLen + 1;
    143153                }
    144154
     
    156166 *      process environment, which is retrieved from
    157167 *      the info blocks.
     168 *
     169 *      Returns:
     170 *
     171 *      --  NO_ERROR:
     172 *
     173 *      --  ERROR_INVALID_PARAMETER
     174 *
     175 *      --  ERROR_BAD_ENVIRONMENT: no environment found in
     176 *          info blocks.
    158177 *
    159178 *@@added V0.9.4 (2000-07-19) [umoeller]
     
    173192        if (arc == NO_ERROR)
    174193        {
    175             PSZ pszEnv = ppib->pib_pchenv;
    176             if (pszEnv)
     194            PSZ pszEnv;
     195            if (pszEnv = ppib->pib_pchenv)
    177196                arc = appParseEnvironment(pszEnv, pEnv);
    178197            else
     
    200219 *@@changed V0.9.12 (2001-05-21) [umoeller]: fixed memory leak
    201220 *@@changed V0.9.12 (2001-05-27) [umoeller]: moved from dosh2.c to apps.c
     221 *@@changed V0.9.16 (2002-01-01) [umoeller]: removed extra heap allocation
    202222 */
    203223
     
    205225                           PSZ pszVarName)
    206226{
    207     PSZ *ppszRet = 0;
    208     if (pEnv)
    209     {
    210         if ((pEnv->papszVars) && (pszVarName))
    211         {
    212             PSZ     *ppszThis = pEnv->papszVars;
    213             // PSZ     pszThis;
    214             ULONG   ul = 0;
    215             ULONG   ulVarNameLen = 0;
    216 
    217             PSZ     pszSearch = NULL; // receives "VARNAME="
    218             PSZ     pFirstEqual = strchr(pszVarName, '=');
    219             if (pFirstEqual)
    220                 pszSearch = strhSubstr(pszVarName, pFirstEqual + 1);
    221             else
    222             {
    223                 ulVarNameLen = strlen(pszVarName);
    224                 pszSearch = (PSZ)malloc(ulVarNameLen + 2);
    225                 memcpy(pszSearch, pszVarName, ulVarNameLen);
    226                 *(pszSearch + ulVarNameLen) = '=';
    227                 *(pszSearch + ulVarNameLen + 1) = 0;
    228             }
    229 
    230             ulVarNameLen = strlen(pszSearch);
    231 
    232             for (ul = 0;
    233                  ul < pEnv->cVars;
    234                  ul++)
    235             {
    236                 if (strnicmp(*ppszThis, pszSearch, ulVarNameLen) == 0)
     227    PSZ     *ppszRet = 0;
     228
     229    if (    (pEnv)
     230         && (pEnv->papszVars)
     231         && (pszVarName)
     232       )
     233    {
     234        ULONG   ul = 0;
     235        ULONG   ulVarNameLen = 0;
     236
     237        PSZ     pFirstEqual;
     238        // rewrote all the following for speed V0.9.16 (2002-01-01) [umoeller]
     239        if (pFirstEqual = strchr(pszVarName, '='))
     240            // VAR=VALUE
     241            //    ^ pFirstEqual
     242            ulVarNameLen = pFirstEqual - pszVarName;
     243        else
     244            ulVarNameLen = strlen(pszVarName);
     245
     246        for (ul = 0;
     247             ul < pEnv->cVars;
     248             ul++)
     249        {
     250            PSZ pszThis = pEnv->papszVars[ul];
     251            if (pFirstEqual = strchr(pszThis, '='))
     252            {
     253                ULONG ulLenThis = pFirstEqual - pszThis;
     254                if (    (ulLenThis == ulVarNameLen)
     255                     && (!memicmp(pszThis,
     256                                  pszVarName,
     257                                  ulVarNameLen))
     258                   )
    237259                {
    238                     ppszRet = ppszThis;
     260                    ppszRet = &pEnv->papszVars[ul];
    239261                    break;
    240262                }
    241 
    242                 // next environment string
    243                 ppszThis++;
    244             }
    245 
    246             free(pszSearch);        // was missing V0.9.12 (2001-05-21) [umoeller]
     263            }
    247264        }
    248265    }
     
    296313        else
    297314        {
    298             PSZ *ppszEnvLine = appFindEnvironmentVar(pEnv, pszNewEnv);
    299             if (ppszEnvLine)
    300             {
     315            PSZ *ppszEnvLine;
     316            if (ppszEnvLine = appFindEnvironmentVar(pEnv, pszNewEnv))
    301317                // was set already: replace
    302                 free(*ppszEnvLine);
    303                 *ppszEnvLine = strdup(pszNewEnv);
    304                 if (!(*ppszEnvLine))
    305                     arc = ERROR_NOT_ENOUGH_MEMORY;
    306             }
     318                arc = strhStore(ppszEnvLine,
     319                                pszNewEnv,
     320                                NULL);
    307321            else
    308322            {
     
    312326                // allocate new array, with one new entry
    313327                // fixed V0.9.12 (2001-05-26) [umoeller], this crashed
    314                 PSZ *papszNew = (PSZ*)malloc(sizeof(PSZ) * (pEnv->cVars + 1));
    315 
    316                 if (!papszNew)
     328                PSZ *papszNew;
     329
     330                if (!(papszNew = (PSZ*)malloc(sizeof(PSZ) * (pEnv->cVars + 1))))
    317331                    arc = ERROR_NOT_ENOUGH_MEMORY;
    318332                else
     
    339353                    }
    340354
    341                     if (pEnv->papszVars)
    342                         free(pEnv->papszVars);      // was missing V0.9.12 (2001-05-21) [umoeller]
    343 
     355                    free(pEnv->papszVars);      // was missing V0.9.12 (2001-05-21) [umoeller]
    344356                    pEnv->papszVars = papszNew;
    345357                    pEnv->cVars++;
     
    374386{
    375387    APIRET  arc = NO_ERROR;
    376     if (!pEnv)
     388    if (    (!pEnv)
     389         || (!pEnv->papszVars)
     390       )
    377391        arc = ERROR_INVALID_PARAMETER;
    378392    else
    379393    {
    380         if (!pEnv->papszVars)
    381             arc = ERROR_INVALID_PARAMETER;
     394        // count memory needed for all strings
     395        ULONG   cbNeeded = 0,
     396                ul = 0;
     397        PSZ     *ppszThis = pEnv->papszVars;
     398
     399        for (ul = 0;
     400             ul < pEnv->cVars;
     401             ul++)
     402        {
     403            cbNeeded += strlen(*ppszThis) + 1; // length of string plus null terminator
     404
     405            // next environment string
     406            ppszThis++;
     407        }
     408
     409        cbNeeded++;     // for another null terminator
     410
     411        if (!(*ppszEnv = (PSZ)malloc(cbNeeded)))
     412            arc = ERROR_NOT_ENOUGH_MEMORY;
    382413        else
    383414        {
    384             // count memory needed for all strings
    385             ULONG   cbNeeded = 0,
    386                     ul = 0;
    387             PSZ     *ppszThis = pEnv->papszVars;
    388 
     415            PSZ     pTarget = *ppszEnv;
     416            if (pulSize)
     417                *pulSize = cbNeeded;
     418            ppszThis = pEnv->papszVars;
     419
     420            // now copy each string
    389421            for (ul = 0;
    390422                 ul < pEnv->cVars;
    391423                 ul++)
    392424            {
    393                 cbNeeded += strlen(*ppszThis) + 1; // length of string plus null terminator
     425                PSZ pSource = *ppszThis;
     426
     427                while ((*pTarget++ = *pSource++))
     428                    ;
     429
     430                // *pTarget++ = 0;     // append null terminator per string
    394431
    395432                // next environment string
     
    397434            }
    398435
    399             cbNeeded++;     // for another null terminator
    400 
    401             *ppszEnv = (PSZ)malloc(cbNeeded);
    402             if (!(*ppszEnv))
    403                 arc = ERROR_NOT_ENOUGH_MEMORY;
    404             else
    405             {
    406                 PSZ     pTarget = *ppszEnv;
    407                 if (pulSize)
    408                     *pulSize = cbNeeded;
    409                 ppszThis = pEnv->papszVars;
    410 
    411                 // now copy each string
    412                 for (ul = 0;
    413                      ul < pEnv->cVars;
    414                      ul++)
    415                 {
    416                     PSZ pSource = *ppszThis;
    417 
    418                     while ((*pTarget++ = *pSource++))
    419                         ;
    420 
    421                     // *pTarget++ = 0;     // append null terminator per string
    422 
    423                     // next environment string
    424                     ppszThis++;
    425                 }
    426 
    427                 *pTarget++ = 0;     // append second null terminator
    428             }
     436            *pTarget++ = 0;     // append second null terminator
    429437        }
    430438    }
     
    444452{
    445453    APIRET  arc = NO_ERROR;
    446     if (!pEnv)
     454    if (    (!pEnv)
     455         || (!pEnv->papszVars)
     456       )
    447457        arc = ERROR_INVALID_PARAMETER;
    448458    else
    449459    {
    450         if (!pEnv->papszVars)
    451             arc = ERROR_INVALID_PARAMETER;
    452         else
    453         {
    454             PSZ     *ppszThis = pEnv->papszVars;
    455             PSZ     pszThis;
    456             ULONG   ul = 0;
    457 
    458             for (ul = 0;
    459                  ul < pEnv->cVars;
    460                  ul++)
    461             {
    462                 pszThis = *ppszThis;
    463                 free(pszThis);
    464                 // *ppszThis = NULL;
    465                 // next environment string
    466                 ppszThis++;
    467             }
    468 
    469             free(pEnv->papszVars);
    470             pEnv->cVars = 0;
    471         }
     460        PSZ     *ppszThis = pEnv->papszVars;
     461        PSZ     pszThis;
     462        ULONG   ul = 0;
     463
     464        for (ul = 0;
     465             ul < pEnv->cVars;
     466             ul++)
     467        {
     468            pszThis = *ppszThis;
     469            free(pszThis);
     470            // *ppszThis = NULL;
     471            // next environment string
     472            ppszThis++;
     473        }
     474
     475        free(pEnv->papszVars);
     476        pEnv->cVars = 0;
    472477    }
    473478
     
    920925 *@@changed V0.9.16 (2001-10-19) [umoeller]: added thread-1 check
    921926 *@@changed V0.9.16 (2001-12-06) [umoeller]: now using doshSearchPath for finding pszExecutable if not qualified
     927 *@@changed V0.9.16 (2002-01-04) [umoeller]: removed error report if startup directory was drive letter only
     928 *@@changed V0.9.16 (2002-01-04) [umoeller]: added more detailed error reports and *FailingName params
    922929 */
    923930
     
    925932                   const PROGDETAILS *pcProgDetails, // in: program spec (req.)
    926933                   ULONG ulFlags,          // in: APP_RUN_* flags
    927                    HAPP *phapp)            // out: application handle if NO_ERROR is returned
     934                   HAPP *phapp,            // out: application handle if NO_ERROR is returned
     935                   ULONG cbFailingName,
     936                   PSZ pszFailingName)
    928937{
    929938    APIRET          arc = NO_ERROR;
    930939    PROGDETAILS     ProgDetails;
     940
     941    if (pszFailingName)
     942        *pszFailingName = '\0';
    931943
    932944    if (!pcProgDetails || !phapp)
     
    10811093                    if (ProgDetails.pszStartupDir)
    10821094                    {
    1083                         if (!(arc = doshQueryPathAttr(ProgDetails.pszStartupDir,
    1084                                                       &ulAttr)))
    1085                             if (!(ulAttr & FILE_DIRECTORY))
    1086                                 arc = ERROR_PATH_NOT_FOUND;
     1095                        // it is valid to specify a startup dir of "C:"
     1096                        if (    (strlen(ProgDetails.pszStartupDir) > 2)
     1097                             && (!(arc = doshQueryPathAttr(ProgDetails.pszStartupDir,
     1098                                                           &ulAttr)))
     1099                             && (!(ulAttr & FILE_DIRECTORY))
     1100                           )
     1101                            arc = ERROR_PATH_NOT_FOUND;
    10871102                    }
    10881103                }
     
    12221237                                  MB_YESNO | MB_MOVEABLE)
    12231238                          == MBID_YES) */
     1239
     1240                if (pszFailingName)
     1241                    strhncpy0(pszFailingName, ProgDetails.pszExecutable, cbFailingName);
     1242
    12241243                if (!(*phapp = WinStartApp(hwndNotify,
    12251244                                                    // receives WM_APPTERMINATENOTIFY
     
    12351254                                                // app will be terminated automatically
    12361255                                                // when the WPS terminates!
    1237                     arc = ERROR_BAD_FORMAT;
    1238                             // @@todo we can probably do better
    1239                             // V0.9.16 (2001-10-19) [umoeller]
    1240 
    1241                 // _Pmpf((__FUNCTION__ ": got happ 0x%lX", happ));
     1256                {
     1257                    // cannot start app: unfortunately WinStartApp doesn't
     1258                    // return meaningful codes like DosStartSession, so
     1259                    // try to see what happened
     1260                    switch (ERRORIDERROR(WinGetLastError(0)))
     1261                    {
     1262                        case PMERR_DOS_ERROR: //  (0x1200)
     1263                        {
     1264                            // this is probably the case where the module
     1265                            // couldn't be loaded, so try DosStartSession
     1266                            // to get a meaningful return code... note that
     1267                            // this cannot handle hwndNotify then
     1268                            RESULTCODES result;
     1269                            arc = DosExecPgm(pszFailingName,
     1270                                             cbFailingName,
     1271                                             EXEC_ASYNC,
     1272                                             NULL, // ProgDetails.pszParameters,
     1273                                             NULL, // ProgDetails.pszEnvironment,
     1274                                             &result,
     1275                                             ProgDetails.pszExecutable);
     1276
     1277                            /* ULONG sid, pid;
     1278                            STARTDATA   SData;
     1279                            SData.Length  = sizeof(STARTDATA);
     1280                            SData.Related = SSF_RELATED_CHILD; //INDEPENDENT;
     1281                            SData.FgBg    = SSF_FGBG_FORE;
     1282                            SData.TraceOpt = SSF_TRACEOPT_NONE;
     1283
     1284                            SData.PgmTitle = ProgDetails.pszTitle;
     1285                            SData.PgmName = ProgDetails.pszExecutable;
     1286                            SData.PgmInputs = ProgDetails.pszParameters;
     1287
     1288                            SData.TermQ = NULL;
     1289                            SData.Environment = ProgDetails.pszEnvironment;
     1290                            SData.InheritOpt = SSF_INHERTOPT_PARENT;    // ignored
     1291                            SData.SessionType = SSF_TYPE_DEFAULT;
     1292                            SData.IconFile = 0;
     1293                            SData.PgmHandle = 0;
     1294
     1295                            SData.PgmControl = SSF_CONTROL_VISIBLE;
     1296
     1297                            SData.InitXPos  = 30;
     1298                            SData.InitYPos  = 40;
     1299                            SData.InitXSize = 200;
     1300                            SData.InitYSize = 140;
     1301                            SData.Reserved = 0;
     1302                            SData.ObjectBuffer  = pszFailingName;
     1303                            SData.ObjectBuffLen = cbFailingName;
     1304
     1305                            arc = DosStartSession(&SData, &sid, &pid);
     1306                            */
     1307                        }
     1308                        break;
     1309
     1310                        case PMERR_INVALID_APPL: //  (0x1530)
     1311                                // Attempted to start an application whose type is not
     1312                                // recognized by OS/2.
     1313                            arc = ERROR_INVALID_EXE_SIGNATURE;
     1314                        break;
     1315
     1316                        case PMERR_INVALID_PARAMETERS: //  (0x1208)
     1317                                // An application parameter value is invalid for
     1318                                // its converted PM type. For  example: a 4-byte
     1319                                // value outside the range -32 768 to +32 767 cannot be
     1320                                // converted to a SHORT, and a negative number cannot
     1321                                // be converted to a ULONG or USHORT.
     1322                            arc = ERROR_INVALID_DATA;
     1323                        break;
     1324
     1325                        case PMERR_STARTED_IN_BACKGROUND: //  (0x1532)
     1326                                // The application started a new session in the
     1327                                // background.
     1328                            arc = ERROR_SMG_START_IN_BACKGROUND;
     1329                        break;
     1330
     1331                        case PMERR_INVALID_WINDOW: // (0x1206)
     1332                                // The window specified with a Window List call
     1333                                // is not a valid frame window.
     1334
     1335                        default:
     1336                            arc = ERROR_BAD_FORMAT;
     1337                        break;
     1338                    }
     1339                }
    12421340            }
    12431341        }
     
    13441442                          &pd,
    13451443                          0,
    1346                           &happ))
     1444                          &happ,
     1445                          0,
     1446                          NULL))
    13471447       )
    13481448    {
  • trunk/src/helpers/dosh.c

    r126 r127  
    16401640 */
    16411641
     1642/*
    16421643APIRET doshOpenExisting(PCSZ pcszFilename,   // in: file name
    16431644                        ULONG ulOpenFlags,          // in: open flags
     
    16541655                    NULL));     // EAs
    16551656}
    1656 
    1657 /*
    1658  *@@ doshWriteAt:
    1659  *      writes cb bytes (pointed to by pbData) to the
    1660  *      position specified by ulMethod and lOffset into
    1661  *      the file specified by hf.
    1662  *
    1663  *      If ulMethod is FILE_BEGIN, lOffset specifies the
    1664  *      offset from the beginning of the file. With
    1665  *      FILE_CURRENT, lOffset is considered from the
    1666  *      current file pointer, and with FILE_END, it is
    1667  *      considered from the end of the file.
    1668  *
    1669  *@@added V0.9.13 (2001-06-14) [umoeller]
    1670  */
    1671 
    1672 APIRET doshWriteAt(HFILE hf,        // in: OS/2 file handle
    1673                    LONG lOffset,    // in: offset to write at (depends on ulMethod)
    1674                    ULONG ulMethod,  // in: one of FILE_BEGIN, FILE_CURRENT, FILE_END
    1675                    ULONG cb,        // in: bytes to write
    1676                    PBYTE pbData)    // in: ptr to bytes to write (must be cb bytes)
    1677 {
    1678     APIRET arc;
    1679     ULONG ulDummy;
    1680     if (!(arc = DosSetFilePtr(hf,
    1681                               lOffset,
    1682                               ulMethod,
    1683                               &ulDummy)))
    1684         arc = DosWrite(hf,
    1685                        pbData,
    1686                        cb,
    1687                        &ulDummy);
    1688 
    1689     return (arc);
    1690 }
    1691 
    1692 /*
    1693  *@@ doshReadAt:
    1694  *      reads cb bytes from the position specified by
    1695  *      ulMethod and lOffset into the buffer pointed to
    1696  *      by pbData, which should be cb bytes in size.
    1697  *
    1698  *      Use lOffset and ulMethod as with doshWriteAt.
    1699  *
    1700  *@@added V0.9.13 (2001-06-14) [umoeller]
    1701  */
    1702 
    1703 APIRET doshReadAt(HFILE hf,        // in: OS/2 file handle
    1704                   LONG lOffset,    // in: offset to write at (depends on ulMethod)
    1705                   ULONG ulMethod,  // in: one of FILE_BEGIN, FILE_CURRENT, FILE_END
    1706                   PULONG pcb,      // in: bytes to read, out: bytes read
    1707                   PBYTE pbData)    // out: read buffer (must be cb bytes)
    1708 {
    1709     APIRET arc;
    1710     ULONG cb = *pcb;
    1711     ULONG ulDummy;
    1712 
    1713     *pcb = 0;
    1714 
    1715     if (!(arc = DosSetFilePtr(hf,
    1716                               lOffset,
    1717                               ulMethod,
    1718                               &ulDummy)))
    1719     {
    1720         if (!(arc = DosRead(hf,
    1721                             pbData,
    1722                             cb,
    1723                             &ulDummy)))
    1724             *pcb = ulDummy;     // bytes read
    1725     }
    1726 
    1727     return (arc);
    1728 }
     1657*/
    17291658
    17301659/*
     
    17411670 +      +-------------------------+------+------------+-----------+
    17421671 +      |  XOPEN_READ_EXISTING    | read | opens      | fails     |
     1672 +      |                         |      | fptr = 0   |           |
     1673 +      +-------------------------+------+------------+-----------+
     1674 +      |  XOPEN_READWRITE_EXISTING r/w  | opens      | fails     |
    17431675 +      |                         |      | fptr = 0   |           |
    17441676 +      +-------------------------+------+------------+-----------+
     
    18021734            fsOpenMode |=   OPEN_SHARE_DENYWRITE
    18031735                          | OPEN_ACCESS_READONLY;
    1804             // _Pmpf((__FUNCTION__ ": opening XOPEN_READ_EXISTING"));
    18051736
    18061737            // run this first, because if the file doesn't
     
    18081739            // which isn't that meaningful
    18091740            // V0.9.16 (2001-12-08) [umoeller]
     1741            arc = doshQueryPathSize(pcszFilename,
     1742                                    pcbFile);
     1743        break;
     1744
     1745        case XOPEN_READWRITE_EXISTING:
     1746            fsOpenFlags =   OPEN_ACTION_FAIL_IF_NEW
     1747                          | OPEN_ACTION_OPEN_IF_EXISTS;
     1748            fsOpenMode |=   OPEN_SHARE_DENYWRITE
     1749                          | OPEN_ACCESS_READWRITE;
     1750
    18101751            arc = doshQueryPathSize(pcszFilename,
    18111752                                    pcbFile);
     
    19281869
    19291870/*
     1871 *@@ doshReadAt:
     1872 *      reads cb bytes from the position specified by
     1873 *      lOffset into the buffer pointed to by pbData,
     1874 *      which should be cb bytes in size.
     1875 *
     1876 *      Note that lOffset is always considered to
     1877 *      be from the beginning of the file (FILE_BEGIN
     1878 *      method).
     1879 *
     1880 *@@added V0.9.13 (2001-06-14) [umoeller]
     1881 *@@changed V0.9.16 (2001-12-18) [umoeller]: now with XFILE, and always using FILE_BEGIN
     1882 */
     1883
     1884APIRET doshReadAt(PXFILE pFile,
     1885                  ULONG ulOffset,    // in: offset to read from (from beginning of file)
     1886                  PULONG pcb,      // in: bytes to read, out: bytes read
     1887                  PBYTE pbData)    // out: read buffer (must be cb bytes)
     1888{
     1889    APIRET arc;
     1890    ULONG cb = *pcb;
     1891    ULONG ulDummy;
     1892
     1893    if (!(arc = doshLockFile(pFile)))   // this checks for pFile
     1894    {
     1895        *pcb = 0;
     1896
     1897        if (!(arc = DosSetFilePtr(pFile->hf,
     1898                                  (LONG)ulOffset,
     1899                                  FILE_BEGIN,
     1900                                  &ulDummy)))
     1901        {
     1902            if (!(arc = DosRead(pFile->hf,
     1903                                pbData,
     1904                                cb,
     1905                                &ulDummy)))
     1906                *pcb = ulDummy;     // bytes read
     1907        }
     1908
     1909        doshUnlockFile(pFile);
     1910    }
     1911
     1912    return (arc);
     1913}
     1914
     1915/*
    19301916 *@@ doshWrite:
    19311917 *      writes the specified data to the file.
     
    19371923 *      writing.
    19381924 *
     1925 *      Note that this expects that the file
     1926 *      pointer is at the end of the file, or
     1927 *      you will get garbage.
     1928 *
    19391929 *@@added V0.9.16 (2001-10-19) [umoeller]
    19401930 *@@changed V0.9.16 (2001-12-02) [umoeller]: added XOPEN_BINARY \r\n support
     
    19431933
    19441934APIRET doshWrite(PXFILE pFile,
    1945                  PCSZ pcsz,
    1946                  ULONG cb)
     1935                 ULONG cb,
     1936                 PCSZ pbData)
    19471937{
    19481938    APIRET arc = NO_ERROR;
    1949     if ((!pFile) || (!pcsz))
     1939    if ((!pFile) || (!pbData))
    19501940        arc = ERROR_INVALID_PARAMETER;
    19511941    else
    19521942    {
    19531943        if (!cb)
    1954             cb = strlen(pcsz);
     1944            cb = strlen(pbData);
    19551945
    19561946        if (!cb)
     
    19671957                // count all \n first
    19681958                ULONG cNewLines = 0;
    1969                 PCSZ pSource = pcsz;
     1959                PCSZ pSource = pbData;
    19701960                ULONG ul;
    19711961                for (ul = 0;
     
    19871977                    {
    19881978                        PSZ pTarget = pszNew;
    1989                         pSource = pcsz;
     1979                        pSource = pbData;
    19901980                        for (ul = 0;
    19911981                             ul < cb;
     
    20102000                                         (pszNew)
    20112001                                                ? pszNew
    2012                                                 : (PSZ)pcsz,
     2002                                                : (PSZ)pbData,
    20132003                                         cb,
    20142004                                         &cbWritten)))
     
    20212011                free(pszNew);
    20222012        }
     2013    }
     2014
     2015    return (arc);
     2016}
     2017
     2018/*
     2019 *@@ doshWriteAt:
     2020 *      writes cb bytes (pointed to by pbData) to the
     2021 *      specified file at the position lOffset (from
     2022 *      the beginning of the file).
     2023 *
     2024 *@@added V0.9.13 (2001-06-14) [umoeller]
     2025 */
     2026
     2027APIRET doshWriteAt(PXFILE pFile,
     2028                   ULONG ulOffset,    // in: offset to write at
     2029                   ULONG cb,        // in: bytes to write
     2030                   PCSZ pbData)     // in: ptr to bytes to write (must be cb bytes)
     2031{
     2032    APIRET arc;
     2033    if (!(arc = doshLockFile(pFile)))   // this checks for pFile
     2034    {
     2035        ULONG cbWritten;
     2036        if (!(arc = DosSetFilePtr(pFile->hf,
     2037                                  (LONG)ulOffset,
     2038                                  FILE_BEGIN,
     2039                                  &cbWritten)))
     2040        {
     2041            if (!(arc = DosWrite(pFile->hf,
     2042                                 (PSZ)pbData,
     2043                                 cb,
     2044                                 &cbWritten)))
     2045            {
     2046                if (ulOffset + cbWritten > pFile->cbCurrent)
     2047                    pFile->cbCurrent = ulOffset + cbWritten;
     2048            }
     2049        }
     2050
     2051        doshUnlockFile(pFile);
    20232052    }
    20242053
     
    20592088        {
    20602089            if (!(arc = doshWrite(pFile,
    2061                                   szTemp,
    2062                                   ulLength)))
     2090                                  ulLength,
     2091                                  szTemp)))
    20632092            {
    20642093                va_list arg_ptr;
     
    20732102
    20742103                arc = doshWrite(pFile,
    2075                                 (PCSZ)szTemp,
    2076                                 ulLength);
     2104                                ulLength,
     2105                                szTemp);
    20772106            }
    20782107        }
  • trunk/src/helpers/dosh2.c

    r126 r127  
    6565#include "helpers\dosh.h"
    6666#include "helpers\ensure.h"
     67#include "helpers\nls.h"
    6768#include "helpers\standards.h"
    6869#include "helpers\stringh.h"
     
    441442 *@@changed V0.9.16 (2001-12-08) [umoeller]: fLibrary was never set, works for LX and NE now
    442443 *@@changed V0.9.16 (2001-12-08) [umoeller]: some speed optimizations, changed some return codes
     444 *@@changed V0.9.16 (2002-01-04) [umoeller]: added fixes for COM, BAT, CMD extensions
    443445 */
    444446
     
    446448                    PEXECUTABLE* ppExec)
    447449{
    448     APIRET  arc = NO_ERROR;
    449 
    450     ULONG   ulAction = 0;
    451     HFILE   hFile;
     450    APIRET      arc = NO_ERROR;
     451
    452452    PEXECUTABLE pExec = NULL;
     453
     454    PXFILE      pFile = NULL;
     455    ULONG       cbFile = 0;
     456    PCSZ        pExt;
     457    BOOL        fOpenFile = FALSE;
    453458
    454459    if (!ppExec)
     
    460465    memset(pExec, 0, sizeof(EXECUTABLE));
    461466
    462     if (!(arc = DosOpen((PSZ)pcszExecutable,
    463                         &hFile,
    464                         &ulAction,                      // out: action taken
    465                         0,                              // in: new file (ignored for read-mode)
    466                         0,                              // in: new file attribs (ignored)
    467                         // open-flags
    468                         OPEN_ACTION_FAIL_IF_NEW
    469                            | OPEN_ACTION_OPEN_IF_EXISTS,
    470                         // open-mode
    471                         OPEN_FLAGS_FAIL_ON_ERROR        // report errors to caller
    472                            | OPEN_FLAGS_SEQUENTIAL
    473                            | OPEN_FLAGS_NOINHERIT
    474                            // | OPEN_SHARE_DENYNONE
    475                            | OPEN_SHARE_DENYWRITE       // changed V0.9.16 (2001-12-08) [umoeller]
    476                            | OPEN_ACCESS_READONLY,      // read-only mode
    477                         NULL)))                         // no EAs
     467    // check some of the default extensions
     468    // V0.9.16 (2002-01-04) [umoeller]
     469    if (pExt = doshGetExtension(pcszExecutable))
     470    {
     471        if (!stricmp(pExt, "COM"))
     472        {
     473            // I am not willing to find out more about the
     474            // .COM executable format, so for this one case,
     475            // let OS/2 determine what we have here
     476            ULONG ulDosAppType = 0;
     477            if (!(arc = DosQueryAppType((PSZ)pcszExecutable, &ulDosAppType)))
     478            {
     479                if (ulDosAppType & FAPPTYP_DOS)           // 0x20
     480                    pExec->ulOS = EXEOS_DOS3;
     481                else
     482                    pExec->ulOS = EXEOS_OS2;
     483
     484                pExec->ulExeFormat = EXEFORMAT_COM;
     485            }
     486        }
     487        else if (!stricmp(pExt, "BAT"))
     488        {
     489            pExec->ulOS = EXEOS_DOS3;
     490            pExec->ulExeFormat = EXEFORMAT_TEXT_BATCH;
     491        }
     492        else if (!stricmp(pExt, "CMD"))
     493        {
     494            pExec->ulOS = EXEOS_OS2;
     495            pExec->ulExeFormat = EXEFORMAT_TEXT_CMD;
     496        }
     497        else
     498            fOpenFile = TRUE;
     499    }
     500
     501    if (    (fOpenFile)
     502         && (!(arc = doshOpen((PSZ)pcszExecutable,
     503                              XOPEN_READ_EXISTING,
     504                              &cbFile,
     505                              &pFile)))
     506       )
    478507    {
    479508        // file opened successfully:
     509        pExec->pFile = pFile;
    480510
    481511        // read old DOS EXE header
     
    485515        {
    486516            pExec->cbDosExeHeader = sizeof(DOSEXEHEADER);
    487             if (!(arc = doshReadAt(hFile,
     517            if (!(arc = doshReadAt(pFile,
    488518                                   0,
    489                                    FILE_BEGIN,
    490519                                   &pExec->cbDosExeHeader,      // in/out
    491520                                   (PBYTE)pExec->pDosExeHeader)))
     
    554583                    if (!(pbHeader = (PBYTE)malloc(cbRead)))
    555584                        arc = ERROR_NOT_ENOUGH_MEMORY;
    556                     else if (!(arc = doshReadAt(hFile,
     585                    else if (!(arc = doshReadAt(pFile,
    557586                                                ulNewHeaderOfs,
    558                                                 FILE_BEGIN,
    559587                                                &cbRead,
    560588                                                pbHeader)))
     
    626654                                // plus an extended header, so check what
    627655                                // we've got
    628                                 ULONG cbPE =   24
    629                                              + ((PPEHEADER)pbHeader)->usHeaderSize;
     656                                ULONG cbPE =   sizeof(PEHEADER); // 24
     657                                   //           + ((PPEHEADER)pbHeader)->usHeaderSize;
    630658                                pExec->pPEHeader = (PPEHEADER)realloc(pbHeader,
    631659                                                                      cbPE);
     
    635663                                pExec->f32Bits = TRUE;
    636664
     665                                /*
    637666                                // we have the first 24 bytes already, so
    638                                 // go for the next chunk
    639                                 if (cbRead = pExec->pPEHeader->usHeaderSize)
     667                                // go for the next chunk, if this is more
     668                                // than we have in PEHEADER
     669                                if (    (cbRead < cbPE)
     670                                     && (cbRead = pExec->pPEHeader->usHeaderSize)
     671                                   )
    640672                                {
     673                                    _Pmpf(("  usHdrSize %d, sizeof(PEHEADER) %d, cbRead %d, cbPE %d --> reading extended header",
     674                                           pExec->pPEHeader->usHeaderSize,
     675                                           sizeof(PEHEADER),
     676                                           cbRead,
     677                                           cbPE));
    641678                                    if (!(arc = doshReadAt(hFile,
    642679                                                           ulNewHeaderOfs + 24,
     
    647684                                    }
    648685                                    else
     686                                    {
    649687                                        arc = ERROR_BAD_EXE_FORMAT;
     688                                        FREE(pExec->pPEHeader);
     689                                    }
    650690                                }
     691                                else
     692                                    _Pmpf(("  already got extended header"));
     693                                */
    651694                            }
    652695                        }
    653696                        else
     697                        {
    654698                            // strange type:
    655699                            arc = ERROR_INVALID_EXE_SIGNATURE;
    656 
    657                         if (pbCheckOS)
     700                            FREE(pbHeader);
     701                        }
     702
     703                        if ((!arc) && (pbCheckOS))
    658704                        {
    659705                            // BYTE to check for operating system
     
    681727                            }
    682728                        }
    683                     }
    684                 }
    685             } // end if (!(arc = DosSetFilePtr(hFile,
    686         } // end if pExec->pDosExeHeader = (PDOSEXEHEADER)malloc(sizeof(DOSEXEHEADER));
    687 
    688         // store exec's HFILE
    689         pExec->hfExe = hFile;
     729                    } // end if (!(arc = doshReadAt(hFile,
     730                } // end if (fLoadNewHeader)
     731            } // end if (!(arc = doshReadAt(hFile,
     732        } // end else if (!(pExec->pDosExeHeader = (PDOSEXEHEADER)malloc(sizeof(DOSEXEHEADER))))
     733
    690734    } // end if (!(arc = DosOpen((PSZ)pcszExecutable,
    691735
     
    941985    else
    942986    {
     987        PXFILE      pFile = pExec->pFile;
     988
    943989        ULONG       ulNRNTOfs = 0;
    944990
     
    9781024            // move EXE file pointer to offset of non-resident name table
    9791025            // (from LX header)
    980             if (!(arc = DosSetFilePtr(pExec->hfExe,     // file is still open
     1026            if (!(arc = DosSetFilePtr(pFile->hf,     // file is still open
    9811027                                      ulNRNTOfs,      // ofs determined above
    9821028                                      FILE_BEGIN,
     
    9901036                else
    9911037                {
    992                     if (!(arc = DosRead(pExec->hfExe,
     1038                    if (!(arc = DosRead(pFile->hf,
    9931039                                        pszNameTable,
    9941040                                        2000,
     
    10691115        PFSYSMODULE paModules = NULL;
    10701116        int i;
     1117        HFILE hfExe = pExec->pFile->hf;
    10711118
    10721119        ULONG ulNewHeaderOfs = 0;       // V0.9.12 (2001-05-03) [umoeller]
     
    10921139                memset(paModules, 0, cb);   // V0.9.9 (2001-04-03) [umoeller]
    10931140
    1094                 ENSURE_SAFE(DosSetFilePtr(pExec->hfExe,
     1141                ENSURE_SAFE(DosSetFilePtr(hfExe,
    10951142                                          pExec->pLXHeader->ulImportModTblOfs
    10961143                                            + ulNewHeaderOfs, // V0.9.12 (2001-05-03) [umoeller]
     
    11031150
    11041151                    // reading the length of the module name
    1105                     ENSURE_SAFE(DosRead(pExec->hfExe, &bLen, 1, &ulDummy));
     1152                    ENSURE_SAFE(DosRead(hfExe, &bLen, 1, &ulDummy));
    11061153
    11071154                    // reading the module name
    1108                     ENSURE_SAFE(DosRead(pExec->hfExe,
     1155                    ENSURE_SAFE(DosRead(hfExe,
    11091156                                        paModules[i].achModuleName,
    11101157                                        bLen,
     
    11431190                    // then we read the name in the import table
    11441191
    1145                     ENSURE_SAFE(DosSetFilePtr(pExec->hfExe,
     1192                    ENSURE_SAFE(DosSetFilePtr(hfExe,
    11461193                                              pExec->pNEHeader->usModRefTblOfs
    11471194                                                + ulNewHeaderOfs // V0.9.12 (2001-05-03) [umoeller]
     
    11501197                                              &ulDummy));
    11511198
    1152                     ENSURE_SAFE(DosRead(pExec->hfExe, &usOfs, 2, &ulDummy));
    1153 
    1154                     ENSURE_SAFE(DosSetFilePtr(pExec->hfExe,
     1199                    ENSURE_SAFE(DosRead(hfExe, &usOfs, 2, &ulDummy));
     1200
     1201                    ENSURE_SAFE(DosSetFilePtr(hfExe,
    11551202                                              pExec->pNEHeader->usImportTblOfs
    11561203                                                + ulNewHeaderOfs // V0.9.12 (2001-05-03) [umoeller]
     
    11591206                                              &ulDummy));
    11601207
    1161                     ENSURE_SAFE(DosRead(pExec->hfExe, &bLen, 1, &ulDummy));
    1162 
    1163                     ENSURE_SAFE(DosRead(pExec->hfExe,
     1208                    ENSURE_SAFE(DosRead(hfExe, &bLen, 1, &ulDummy));
     1209
     1210                    ENSURE_SAFE(DosRead(hfExe,
    11641211                                        paModules[i].achModuleName,
    11651212                                        bLen,
     
    12241271
    12251272    ULONG ulNewHeaderOfs = 0; // V0.9.12 (2001-05-03) [umoeller]
     1273    HFILE hfExe = pExec->pFile->hf;
    12261274
    12271275    if (pExec->pDosExeHeader)
     
    12291277        ulNewHeaderOfs = pExec->pDosExeHeader->ulNewHeaderOfs;
    12301278
    1231     ENSURE(DosSetFilePtr(pExec->hfExe,
     1279    ENSURE(DosSetFilePtr(hfExe,
    12321280                         pExec->pLXHeader->ulEntryTblOfs
    12331281                           + ulNewHeaderOfs, // V0.9.12 (2001-05-03) [umoeller]
     
    12411289               bFlag;
    12421290
    1243         ENSURE(DosRead(pExec->hfExe, &bCnt, 1, &ulDummy));
     1291        ENSURE(DosRead(hfExe, &bCnt, 1, &ulDummy));
    12441292
    12451293        if (bCnt == 0)
     
    12471295            break;
    12481296
    1249         ENSURE(DosRead(pExec->hfExe, &bType, 1, &ulDummy));
     1297        ENSURE(DosRead(hfExe, &bType, 1, &ulDummy));
    12501298
    12511299        switch (bType & 0x7F)
     
    12691317
    12701318            case 1:
    1271                 ENSURE(DosSetFilePtr(pExec->hfExe,
     1319                ENSURE(DosSetFilePtr(hfExe,
    12721320                                     sizeof(USHORT),
    12731321                                     FILE_CURRENT,
     
    12761324                for (i = 0; i < bCnt; i ++)
    12771325                {
    1278                     ENSURE(DosRead(pExec->hfExe, &bFlag, 1, &ulDummy));
     1326                    ENSURE(DosRead(hfExe, &bFlag, 1, &ulDummy));
    12791327
    12801328                    if (bFlag & 0x01)
     
    12911339                    usOrdinal++;
    12921340
    1293                     ENSURE(DosSetFilePtr(pExec->hfExe,
     1341                    ENSURE(DosSetFilePtr(hfExe,
    12941342                                         sizeof(USHORT),
    12951343                                         FILE_CURRENT,
     
    13081356
    13091357            case 2:
    1310                 ENSURE(DosSetFilePtr(pExec->hfExe,
     1358                ENSURE(DosSetFilePtr(hfExe,
    13111359                                     sizeof(USHORT),
    13121360                                     FILE_CURRENT,
     
    13151363                for (i = 0; i < bCnt; i ++)
    13161364                {
    1317                     ENSURE(DosRead(pExec->hfExe, &bFlag, 1, &ulDummy));
     1365                    ENSURE(DosRead(hfExe, &bFlag, 1, &ulDummy));
    13181366
    13191367                    if (bFlag & 0x01)
     
    13301378                    usOrdinal++;
    13311379
    1332                     ENSURE(DosSetFilePtr(pExec->hfExe,
     1380                    ENSURE(DosSetFilePtr(hfExe,
    13331381                                         sizeof(USHORT) + sizeof(USHORT),
    13341382                                         FILE_CURRENT,
     
    13471395
    13481396            case 3:
    1349                 ENSURE(DosSetFilePtr(pExec->hfExe,
     1397                ENSURE(DosSetFilePtr(hfExe,
    13501398                                     sizeof(USHORT),
    13511399                                     FILE_CURRENT,
     
    13541402                for (i = 0; i < bCnt; i ++)
    13551403                {
    1356                     ENSURE(DosRead(pExec->hfExe, &bFlag, 1, &ulDummy));
     1404                    ENSURE(DosRead(hfExe, &bFlag, 1, &ulDummy));
    13571405
    13581406                    if (bFlag & 0x01)
     
    13691417                    usOrdinal++;
    13701418
    1371                     ENSURE(DosSetFilePtr(pExec->hfExe,
     1419                    ENSURE(DosSetFilePtr(hfExe,
    13721420                                         sizeof(ULONG),
    13731421                                         FILE_CURRENT,
     
    13851433
    13861434            case 4:
    1387                 ENSURE(DosSetFilePtr(pExec->hfExe,
     1435                ENSURE(DosSetFilePtr(hfExe,
    13881436                                     sizeof(USHORT),
    13891437                                     FILE_CURRENT,
     
    13921440                for (i = 0; i < bCnt; i ++)
    13931441                {
    1394                     ENSURE(DosSetFilePtr(pExec->hfExe,
     1442                    ENSURE(DosSetFilePtr(hfExe,
    13951443                                         sizeof(BYTE) + sizeof(USHORT) + sizeof(ULONG),
    13961444                                         FILE_CURRENT,
     
    14641512
    14651513    ULONG ulNewHeaderOfs = 0;
     1514    HFILE hfExe = pExec->pFile->hf;
    14661515
    14671516    if (pExec->pDosExeHeader)
     
    14691518        ulNewHeaderOfs = pExec->pDosExeHeader->ulNewHeaderOfs;
    14701519
    1471     ENSURE(DosSetFilePtr(pExec->hfExe,
     1520    ENSURE(DosSetFilePtr(hfExe,
    14721521                         pExec->pNEHeader->usEntryTblOfs
    14731522                           + ulNewHeaderOfs, // V0.9.12 (2001-05-03) [umoeller]
     
    14811530             bFlag;
    14821531
    1483         ENSURE(DosRead(pExec->hfExe, &bCnt, 1, &ulDummy));
     1532        ENSURE(DosRead(hfExe, &bCnt, 1, &ulDummy));
    14841533
    14851534        if (bCnt == 0)
     
    14871536            break;
    14881537
    1489         ENSURE(DosRead(pExec->hfExe, &bType, 1, &ulDummy));
     1538        ENSURE(DosRead(hfExe, &bType, 1, &ulDummy));
    14901539
    14911540        if (bType)
     
    14931542            for (i = 0; i < bCnt; i++)
    14941543            {
    1495                 ENSURE(DosRead(pExec->hfExe,
     1544                ENSURE(DosRead(hfExe,
    14961545                               &bFlag,
    14971546                               1,
     
    15141563                {
    15151564                    // moveable segment
    1516                     ENSURE(DosSetFilePtr(pExec->hfExe,
     1565                    ENSURE(DosSetFilePtr(hfExe,
    15171566                                         5,
    15181567                                         FILE_CURRENT,
     
    15221571                {
    15231572                    // fixed segment or constant (0xFE)
    1524                     ENSURE(DosSetFilePtr(pExec->hfExe,
     1573                    ENSURE(DosSetFilePtr(hfExe,
    15251574                                         2,
    15261575                                         FILE_CURRENT,
     
    15851634    USHORT        usOrdinal;
    15861635    PFSYSFUNCTION pFunction;
     1636    HFILE hfExe = pExec->pFile->hf;
    15871637
    15881638    while (TRUE)
     
    15921642        // int    i;
    15931643
    1594         ENSURE(DosRead(pExec->hfExe, &bLen, 1, &ulDummy));
     1644        ENSURE(DosRead(hfExe, &bLen, 1, &ulDummy));
    15951645
    15961646        if (bLen == 0)
     
    15981648            break;
    15991649
    1600         ENSURE(DosRead(pExec->hfExe, &achName, bLen, &ulDummy));
     1650        ENSURE(DosRead(hfExe, &achName, bLen, &ulDummy));
    16011651        achName[bLen] = 0;
    16021652
    1603         ENSURE(DosRead(pExec->hfExe, &usOrdinal, sizeof(USHORT), &ulDummy));
     1653        ENSURE(DosRead(hfExe, &usOrdinal, sizeof(USHORT), &ulDummy));
    16041654
    16051655        if ((pFunction = (PFSYSFUNCTION)bsearch(&usOrdinal,
     
    16681718        ULONG ulDummy;
    16691719
     1720        HFILE hfExe = pExec->pFile->hf;
    16701721        ULONG ulNewHeaderOfs = 0; // V0.9.12 (2001-05-03) [umoeller]
    16711722
     
    17021753                // we now scan the resident name table entries
    17031754
    1704                 ENSURE_SAFE(DosSetFilePtr(pExec->hfExe,
     1755                ENSURE_SAFE(DosSetFilePtr(hfExe,
    17051756                                          pExec->pLXHeader->ulResdNameTblOfs
    17061757                                            + ulNewHeaderOfs, // V0.9.12 (2001-05-03) [umoeller]
     
    17131764                // whose offset is _from the begining of the file_
    17141765
    1715                 ENSURE_SAFE(DosSetFilePtr(pExec->hfExe,
     1766                ENSURE_SAFE(DosSetFilePtr(hfExe,
    17161767                                          pExec->pLXHeader->ulNonResdNameTblOfs,
    17171768                                          FILE_BEGIN,
     
    17501801                // we now scan the resident name table entries
    17511802
    1752                 ENSURE_SAFE(DosSetFilePtr(pExec->hfExe,
     1803                ENSURE_SAFE(DosSetFilePtr(hfExe,
    17531804                                          pExec->pNEHeader->usResdNameTblOfs
    17541805                                            + ulNewHeaderOfs, // V0.9.12 (2001-05-03) [umoeller]
     
    17611812                // whose offset is _from the begining of the file_
    17621813
    1763                 ENSURE_SAFE(DosSetFilePtr(pExec->hfExe,
     1814                ENSURE_SAFE(DosSetFilePtr(hfExe,
    17641815                                          pExec->pNEHeader->ulNonResdTblOfs,
    17651816                                          FILE_BEGIN,
     
    18421893        PFSYSRESOURCE   paResources = NULL;
    18431894
     1895        HFILE hfExe = pExec->pFile->hf;
    18441896        ULONG           ulNewHeaderOfs = 0; // V0.9.12 (2001-05-03) [umoeller]
    18451897
     
    18861938                memset(paResources, 0, cb); // V0.9.9 (2001-04-03) [umoeller]
    18871939
    1888                 ENSURE_SAFE(DosSetFilePtr(pExec->hfExe,
     1940                ENSURE_SAFE(DosSetFilePtr(hfExe,
    18891941                                          pLXHeader->ulResTblOfs
    18901942                                            + ulNewHeaderOfs, // V0.9.12 (2001-05-03) [umoeller]
     
    18941946                for (i = 0; i < cResources; i++)
    18951947                {
    1896                     ENSURE_SAFE(DosRead(pExec->hfExe, &rs, 14, &ulDummy));
     1948                    ENSURE_SAFE(DosRead(hfExe, &rs, 14, &ulDummy));
    18971949
    18981950                    paResources[i].ulID = rs.name;
     
    19121964                                          * (paResources[i].ulFlag - 1));
    19131965
    1914                     ENSURE_SAFE(DosSetFilePtr(pExec->hfExe,
     1966                    ENSURE_SAFE(DosSetFilePtr(hfExe,
    19151967                                              ulOfsThis,
    19161968                                              FILE_BEGIN,
    19171969                                              &ulDummy));
    19181970
    1919                     ENSURE_SAFE(DosRead(pExec->hfExe, &ot, sizeof(ot), &ulDummy));
     1971                    ENSURE_SAFE(DosRead(hfExe, &ot, sizeof(ot), &ulDummy));
    19201972
    19211973                    paResources[i].ulFlag  = ((ot.o32_flags & OBJWRITE)
     
    19682020                    // we first read the resources IDs and types
    19692021
    1970                     ENSURE_SAFE(DosSetFilePtr(pExec->hfExe,
     2022                    ENSURE_SAFE(DosSetFilePtr(hfExe,
    19712023                                              pNEHeader->usResTblOfs
    19722024                                                + ulNewHeaderOfs, // V0.9.12 (2001-05-03) [umoeller]
     
    19762028                    for (i = 0; i < cResources; i++)
    19772029                    {
    1978                         ENSURE_SAFE(DosRead(pExec->hfExe, &rti, sizeof(rti), &ulDummy));
     2030                        ENSURE_SAFE(DosRead(hfExe, &rti, sizeof(rti), &ulDummy));
    19792031
    19802032                        paResources[i].ulID = rti.name;
     
    19862038                    for (i = 0; i < cResources; i++)
    19872039                    {
    1988                         ENSURE_SAFE(DosSetFilePtr(pExec->hfExe,
     2040                        ENSURE_SAFE(DosSetFilePtr(hfExe,
    19892041                                                  ulNewHeaderOfs // V0.9.12 (2001-05-03) [umoeller]
    19902042                                                    + pNEHeader->usSegTblOfs
     
    19962048                                                    &ulDummy));
    19972049
    1998                         ENSURE_SAFE(DosRead(pExec->hfExe, &ns, sizeof(ns), &ulDummy));
     2050                        ENSURE_SAFE(DosRead(hfExe, &ns, sizeof(ns), &ulDummy));
    19992051
    20002052                        paResources[i].ulSize = ns.ns_cbseg;
     
    20132065                ULONG  ulDummy;
    20142066
    2015                 ENSURE(DosSetFilePtr(pExec->hfExe,
     2067                ENSURE(DosSetFilePtr(hfExe,
    20162068                                     pNEHeader->usResTblOfs
    20172069                                       + ulNewHeaderOfs, // V0.9.12 (2001-05-03) [umoeller]
     
    20192071                                     &ulDummy));
    20202072
    2021                 ENSURE(DosRead(pExec->hfExe,
     2073                ENSURE(DosRead(hfExe,
    20222074                               &usAlignShift,
    20232075                               sizeof(usAlignShift),
     
    20292081                    USHORT usCount;
    20302082
    2031                     ENSURE(DosRead(pExec->hfExe,
     2083                    ENSURE(DosRead(hfExe,
    20322084                                   &usTypeID,
    20332085                                   sizeof(usTypeID),
     
    20372089                        break;
    20382090
    2039                     ENSURE(DosRead(pExec->hfExe,
     2091                    ENSURE(DosRead(hfExe,
    20402092                                   &usCount,
    20412093                                   sizeof(usCount),
    20422094                                   &ulDummy));
    20432095
    2044                     ENSURE(DosSetFilePtr(pExec->hfExe,
     2096                    ENSURE(DosSetFilePtr(hfExe,
    20452097                                         sizeof(ULONG),
    20462098                                         FILE_CURRENT,
     
    20502102
    20512103                    // first pass, skip NAMEINFO table
    2052                     ENSURE(DosSetFilePtr(pExec->hfExe,
     2104                    ENSURE(DosSetFilePtr(hfExe,
    20532105                                         usCount*6*sizeof(USHORT),
    20542106                                         FILE_CURRENT,
     
    20672119                    memset(paResources, 0, cb);
    20682120
    2069                     ENSURE_SAFE(DosSetFilePtr(pExec->hfExe,
     2121                    ENSURE_SAFE(DosSetFilePtr(hfExe,
    20702122                                              pNEHeader->usResTblOfs
    20712123                                                + ulNewHeaderOfs,
     
    20732125                                              &ulDummy));
    20742126
    2075                     ENSURE_SAFE(DosRead(pExec->hfExe,
     2127                    ENSURE_SAFE(DosRead(hfExe,
    20762128                                        &usAlignShift,
    20772129                                        sizeof(usAlignShift),
     
    20842136                        int i;
    20852137
    2086                         ENSURE_SAFE(DosRead(pExec->hfExe,
     2138                        ENSURE_SAFE(DosRead(hfExe,
    20872139                                            &usTypeID,
    20882140                                            sizeof(usTypeID),
     
    20922144                            break;
    20932145
    2094                         ENSURE_SAFE(DosRead(pExec->hfExe,
     2146                        ENSURE_SAFE(DosRead(hfExe,
    20952147                                            &usCount,
    20962148                                            sizeof(usCount),
    20972149                                            &ulDummy));
    20982150
    2099                         ENSURE_SAFE(DosSetFilePtr(pExec->hfExe,
     2151                        ENSURE_SAFE(DosSetFilePtr(hfExe,
    21002152                                                  sizeof(ULONG),
    21012153                                                  FILE_CURRENT,
     
    21092161                                   usID;
    21102162
    2111                             ENSURE_SAFE(DosSetFilePtr(pExec->hfExe,
     2163                            ENSURE_SAFE(DosSetFilePtr(hfExe,
    21122164                                                      sizeof(USHORT),
    21132165                                                      FILE_CURRENT,
    21142166                                                      &ulDummy));
    21152167
    2116                             ENSURE_SAFE(DosRead(pExec->hfExe,
     2168                            ENSURE_SAFE(DosRead(hfExe,
    21172169                                                &usLength,
    21182170                                                sizeof(USHORT),
    21192171                                                &ulDummy));
    2120                             ENSURE_SAFE(DosRead(pExec->hfExe,
     2172                            ENSURE_SAFE(DosRead(hfExe,
    21212173                                                &usFlags,
    21222174                                                sizeof(USHORT),
    21232175                                                &ulDummy));
    2124                             ENSURE_SAFE(DosRead(pExec->hfExe,
     2176                            ENSURE_SAFE(DosRead(hfExe,
    21252177                                                &usID,
    21262178                                                sizeof(USHORT),
    21272179                                                &ulDummy));
    21282180
    2129                             ENSURE_SAFE(DosSetFilePtr(pExec->hfExe,
     2181                            ENSURE_SAFE(DosSetFilePtr(hfExe,
    21302182                                                      2*sizeof(USHORT),
    21312183                                                      FILE_CURRENT,
     
    22342286    else
    22352287    {
     2288        PXFILE pFile = pExec->pFile;
    22362289        ULONG ulNewHeaderOfs = 0;
    22372290        ULONG cb;
     
    22462299                                        (PBYTE*)&pExec->pRsTbl,
    22472300                                        &cb)))
    2248              && (!(arc = doshReadAt(pExec->hfExe,
     2301             && (!(arc = doshReadAt(pFile,
    22492302                                    pLXHeader->ulResTblOfs
    22502303                                      + ulNewHeaderOfs,
    2251                                     FILE_BEGIN,
    22522304                                    &cb,
    22532305                                    (PBYTE)pExec->pRsTbl)))
     
    22592311                                            (PBYTE*)&pExec->pObjTbl,
    22602312                                            &cb)))
    2261                  && (!(arc = doshReadAt(pExec->hfExe,
     2313                 && (!(arc = doshReadAt(pFile,
    22622314                                        pLXHeader->ulObjTblOfs
    22632315                                          + ulNewHeaderOfs,
    2264                                         FILE_BEGIN,
    22652316                                        &cb,
    22662317                                        (PBYTE)pExec->pObjTbl)))
     
    22722323                                                (PBYTE*)&pExec->pObjPageTbl,
    22732324                                                &cb)))
    2274                      && (!(arc = doshReadAt(pExec->hfExe,
     2325                     && (!(arc = doshReadAt(pFile,
    22752326                                            pLXHeader->ulObjPageTblOfs
    22762327                                              + ulNewHeaderOfs,
    2277                                             FILE_BEGIN,
    22782328                                            &cb,
    22792329                                            (PBYTE)pExec->pObjPageTbl)))
     
    23412391    else
    23422392    {
     2393        PXFILE pFile = pExec->pFile;
    23432394        ULONG ulNewHeaderOfs = 0;
    23442395        ULONG cb;
     
    23532404                                        (PBYTE*)&pExec->paOS2NEResTblEntry,
    23542405                                        &cb)))
    2355              && (!(arc = doshReadAt(pExec->hfExe,
     2406             && (!(arc = doshReadAt(pFile,
    23562407                                    pNEHeader->usResTblOfs
    23572408                                      + ulNewHeaderOfs,
    2358                                     FILE_BEGIN,
    23592409                                    &cb,
    23602410                                    (PBYTE)pExec->paOS2NEResTblEntry)))
     
    23662416                                            (PBYTE*)&pExec->paOS2NESegments,
    23672417                                            &cb)))
    2368                  && (!(arc = doshReadAt(pExec->hfExe,
     2418                 && (!(arc = doshReadAt(pFile,
    23692419                                        pNEHeader->usResTblOfs
    23702420                                          + ulNewHeaderOfs
    23712421                                          - cb, // pNEHeader->usResSegmCount * sizeof(struct new_seg)
    2372                                         FILE_BEGIN,
    23732422                                        &cb,
    23742423                                        (PBYTE)pExec->paOS2NESegments)))
     
    24612510        }
    24622511
    2463         if (pExec->hfExe)
    2464             arc = DosClose(pExec->hfExe);
     2512        doshClose(&pExec->pFile);
    24652513
    24662514        free(pExec);
     
    41134161    }
    41144162}
     4163
     4164/*
     4165 *@@category: Helpers\Control program helpers\Wildcard matching
     4166 *      See doshMatch.
     4167 */
     4168
     4169/* ******************************************************************
     4170 *
     4171 *   Wildcard matching
     4172 *
     4173 ********************************************************************/
     4174
     4175/*
     4176 * PerformMatch:
     4177 *      compares a single path component. The input strings must
     4178 *      not have slashes or backslashes in them.
     4179 *
     4180 *      fHasDot must be true if pName contains at least one dot.
     4181 *
     4182 *      Note that this function is recursive.
     4183 */
     4184
     4185BOOL PerformMatch(PCSZ pMask,
     4186                  PCSZ pName,
     4187                  int fHasDot)
     4188{
     4189    while (TRUE)
     4190    {
     4191        // go thru the pMask char by char
     4192        switch (*pMask)
     4193        {
     4194            case 0:
     4195                // if we've reached the end of the mask,
     4196                // we better have the end of the name too
     4197                if (*pName == 0)
     4198                    return TRUE;
     4199                return FALSE;
     4200
     4201            case '?':
     4202                // a question mark matches one single character;
     4203                // it does _not_ match a dot;
     4204                // at the end of the component, it also matches
     4205                // no characters
     4206                if (    (*pName != '.')
     4207                     && (*pName != 0)
     4208                   )
     4209                    ++pName;
     4210                ++pMask;
     4211            break;
     4212
     4213            case '*':
     4214                // asterisk matches zero or more characters
     4215
     4216                // skip extra asterisks
     4217                do
     4218                {
     4219                    ++pMask;
     4220                } while (*pMask == '*');
     4221
     4222                // pMask points to after '*';
     4223                // pName is unchanged... so for each pName
     4224                // that follows, check if it matches
     4225                while (TRUE)
     4226                {
     4227                    if (PerformMatch(pMask, pName, fHasDot))
     4228                        // the remainder matched:
     4229                        // then everything matches
     4230                        return TRUE;
     4231
     4232                    if (*pName == 0)
     4233                        return FALSE;
     4234
     4235                    // didn't match: try next pName
     4236                    ++pName;
     4237                }
     4238
     4239            case '.':
     4240                // a dot matches a dot only, even if the name doesn't
     4241                // have one at the end
     4242                ++pMask;
     4243                if (*pName == '.')
     4244                    ++pName;
     4245                else if (    (fHasDot)
     4246                          || (*pName != 0)
     4247                        )
     4248                    return FALSE;
     4249            break;
     4250
     4251            default:
     4252                if (*pMask++ != *pName++)
     4253                    return FALSE;
     4254            break;
     4255        }
     4256    }
     4257}
     4258
     4259/*
     4260 *@@ doshMatch:
     4261 *      this matches '*' and '?' wildcards, similar to what
     4262 *      DosEditName does. It returns TRUE if the given name
     4263 *      matches the given mask.
     4264 *
     4265 *      However, this does not require a file to be present, but
     4266 *      works on strings only.
     4267 *
     4268 *      This accepts both short and fully qualified masks and
     4269 *      names, but the following rules apply:
     4270 *
     4271 *      --  Either both the mask and the name must be fully
     4272 *          qualified, or both must not. Otherwise the match fails.
     4273 *
     4274 *      --  If fully qualified, only the last component may contain
     4275 *          wildcards.
     4276 *
     4277 *      --  This compares without respect to case always.
     4278 *
     4279 *      --  As opposed to the WPS, this handles multiple dots in
     4280 *          filenames correctly. For example, the WPS will not
     4281 *          match "*.ZIP" against "whatever-0.9.3.zip", but this
     4282 *          one will.
     4283 *
     4284 *      This replaces strhMatchOS2 which has been removed with
     4285 *      V0.9.16 and is a lot faster than the old code, which has
     4286 *      been completely rewritten.
     4287 *
     4288 *@@added V0.9.16 (2002-01-01) [umoeller]
     4289 */
     4290
     4291BOOL doshMatch(const char *pcszMask,     // in: mask (e.g. "*.txt")
     4292               const char *pcszName)     // in: string to check (e.g. "test.txt")
     4293{
     4294    BOOL    brc = FALSE;
     4295
     4296    int     iMaskDrive = -1,
     4297            iNameDrive = -1;
     4298
     4299    ULONG   cbMask = strlen(pcszMask),
     4300            cbName = strlen(pcszName);
     4301    PSZ     pszMask = (PSZ)_alloca(cbMask + 1),
     4302            pszName = (PSZ)_alloca(cbName + 1);
     4303
     4304    PCSZ    pLastMaskComponent,
     4305            pLastNameComponent;
     4306
     4307    ULONG   cbMaskPath = 0,
     4308            cbNamePath = 0;
     4309
     4310    CHAR    c;
     4311
     4312    memcpy(pszMask, pcszMask, cbMask + 1);
     4313    nlsUpper(pszMask, cbMask);
     4314    memcpy(pszName, pcszName, cbName + 1);
     4315    nlsUpper(pszName, cbName);
     4316
     4317    if (pLastMaskComponent = strrchr(pszMask, '\\'))
     4318    {
     4319        // length of path component
     4320        cbMaskPath = pLastMaskComponent - pszMask;
     4321        pLastMaskComponent++;
     4322    }
     4323    else
     4324        pLastMaskComponent = pszMask;
     4325
     4326    if (pLastNameComponent = strrchr(pszName, '\\'))
     4327    {
     4328        // length of path component
     4329        cbNamePath = pLastNameComponent - pszName;
     4330        pLastNameComponent++;
     4331    }
     4332    else
     4333        pLastNameComponent = pszName;
     4334
     4335    // compare paths; if the lengths are different
     4336    // or memcmp fails, we can't match
     4337    if (    (cbMaskPath == cbNamePath)      // can both be null
     4338         && (    (cbMaskPath == 0)
     4339              || (!memcmp(pszMask, pszName, cbMaskPath))
     4340            )
     4341       )
     4342    {
     4343        // alright, paths match:
     4344        brc = PerformMatch(pLastMaskComponent,
     4345                           pLastNameComponent,
     4346                           // has dot?
     4347                           (strchr(pLastNameComponent, '.') != NULL));
     4348
     4349    }
     4350
     4351    return brc;
     4352}
     4353
     4354
  • trunk/src/helpers/gpih.c

    r126 r127  
    15551555
    15561556/*
    1557  *@@ gpihCreateBmpFromPS:
    1558  *      this creates a new bitmap and copies a screen rectangle
    1559  *      into it. Consider this a "screen capture" function.
    1560  *
    1561  *      The new bitmap (which is returned) is compatible with the
    1562  *      device associated with hpsScreen. This function calls
    1563  *      gpihCreateMemPS and gpihCreateBitmap to have it created.
    1564  *      The memory PS is only temporary and freed again.
    1565  *
    1566  *      This returns the handle of the new bitmap,
    1567  *      which can then be used for WinDrawBitmap and such, or
    1568  *      NULLHANDLE upon errors.
    1569  *
    1570  *@@changed V0.9.12 (2001-05-20) [umoeller]: fixed excessive mem PS size
    1571  */
    1572 
    1573 HBITMAP gpihCreateBmpFromPS(HAB hab,        // in: anchor block
    1574                             HPS hpsScreen,  // in: screen PS to copy from
    1575                             PRECTL prcl)    // in: rectangle to copy
    1576 {
    1577 
    1578     /* To copy an image from a display screen to a bit map:
    1579       1. Associate the memory device context with a presentation space.
    1580       2. Create a bit map.
    1581       3. Select the bit map into the memory device context by calling GpiSetBitmap.
    1582       4. Determine the location (in device coordinates) of the image.
    1583       5. Call GpiBitBlt and copy the image to the bit map. */
    1584 
    1585     HDC hdcMem;
    1586     HPS hpsMem;
    1587     HBITMAP hbm = NULLHANDLE;
    1588     POINTL aptl[3];
    1589 
    1590     SIZEL szlPage = {prcl->xRight - prcl->xLeft,
    1591                      prcl->yTop - prcl->yBottom};       // fixed V0.9.12 (2001-05-20) [umoeller]
    1592     if (gpihCreateMemPS(hab,
    1593                         &szlPage,
    1594                         &hdcMem,
    1595                         &hpsMem))
    1596     {
    1597         if ((hbm = gpihCreateBitmap(hpsMem,
    1598                                     szlPage.cx,
    1599                                     szlPage.cy)))
    1600         {
    1601             // Associate the bit map and the memory presentation space.
    1602             if (GpiSetBitmap(hpsMem, hbm)
    1603                     != HBM_ERROR)
    1604             {
    1605                 // Copy the screen to the bit map.
    1606                 aptl[0].x = 0;              // lower-left corner of destination rectangle
    1607                 aptl[0].y = 0;
    1608                 aptl[1].x = prcl->xRight;   // upper-right corner for both
    1609                 aptl[1].y = prcl->yTop;
    1610                 aptl[2].x = prcl->xLeft;    // lower-left corner of source rectangle
    1611                 aptl[2].y = prcl->yBottom;
    1612 
    1613                 if (GpiBitBlt(hpsMem,
    1614                               hpsScreen,
    1615                               sizeof(aptl) / sizeof(POINTL), // Number of points in aptl
    1616                               aptl,
    1617                               ROP_SRCCOPY,
    1618                               BBO_IGNORE)
    1619                         == GPI_ERROR)
    1620                 {
    1621                     // error during bitblt:
    1622                     GpiDeleteBitmap(hbm);
    1623                     hbm = NULLHANDLE; // for return code
    1624                 }
    1625             }
    1626             else
    1627             {
    1628                 // error selecting bitmap for hpsMem:
    1629                 GpiDeleteBitmap(hbm);
    1630                 hbm = NULLHANDLE; // for return code
    1631             }
    1632         }
    1633 
    1634         GpiDestroyPS(hpsMem);
    1635         DevCloseDC(hdcMem);
    1636     } // end if (hdcMem = DevOpenDC())
    1637 
    1638     return (hbm);
    1639 }
    1640 
    1641 /*
    16421557 *@@ gpihCreateHalftonedBitmap:
    16431558 *      this creates a half-toned copy of the
     
    22462161}
    22472162
    2248 
     2163/*
     2164 *@@ gpihCreateBmpFromPS:
     2165 *      this creates a new bitmap and copies a screen rectangle
     2166 *      into it. Consider this a "screen capture" function.
     2167 *
     2168 *      The new bitmap (which is returned) is compatible with the
     2169 *      device associated with hpsScreen. This function calls
     2170 *      gpihCreateMemPS and gpihCreateBitmap to have it created.
     2171 *      The memory PS is only temporary and freed again.
     2172 *
     2173 *      This returns the handle of the new bitmap,
     2174 *      which can then be used for WinDrawBitmap and such, or
     2175 *      NULLHANDLE upon errors.
     2176 *
     2177 *@@changed V0.9.12 (2001-05-20) [umoeller]: fixed excessive mem PS size
     2178 *@@changed V0.9.16 (2001-01-04) [umoeller]: now creating XBITMAP
     2179 */
     2180
     2181PXBITMAP gpihCreateBmpFromPS(HAB hab,        // in: anchor block
     2182                             HPS hpsScreen,  // in: screen PS to copy from
     2183                             PRECTL prcl)    // in: rectangle to copy
     2184{
     2185
     2186    /* To copy an image from a display screen to a bit map:
     2187      1. Associate the memory device context with a presentation space.
     2188      2. Create a bit map.
     2189      3. Select the bit map into the memory device context by calling GpiSetBitmap.
     2190      4. Determine the location (in device coordinates) of the image.
     2191      5. Call GpiBitBlt and copy the image to the bit map. */
     2192
     2193    PXBITMAP pBmp;
     2194
     2195    if (pBmp = gpihCreateXBitmap(hab,
     2196                                 prcl->xRight - prcl->xLeft,
     2197                                 prcl->yTop - prcl->yBottom))
     2198    {
     2199        POINTL aptl[3];
     2200        // Copy the screen to the bit map.
     2201        aptl[0].x = 0;              // lower-left corner of destination rectangle
     2202        aptl[0].y = 0;
     2203        aptl[1].x = prcl->xRight;   // upper-right corner for both
     2204        aptl[1].y = prcl->yTop;
     2205        aptl[2].x = prcl->xLeft;    // lower-left corner of source rectangle
     2206        aptl[2].y = prcl->yBottom;
     2207
     2208        if (GpiBitBlt(pBmp->hpsMem,
     2209                      hpsScreen,
     2210                      sizeof(aptl) / sizeof(POINTL), // Number of points in aptl
     2211                      aptl,
     2212                      ROP_SRCCOPY,
     2213                      BBO_IGNORE)
     2214                == GPI_ERROR)
     2215        {
     2216            // error during bitblt:
     2217            gpihDestroyXBitmap(&pBmp);
     2218        }
     2219    }
     2220
     2221    return (pBmp);
     2222}
     2223
  • trunk/src/helpers/helpers_pre.in

    r113 r127  
    8080$(OUTPUTDIR)\cctl_chart.obj \
    8181$(OUTPUTDIR)\cctl_checkcnr.obj \
     82$(OUTPUTDIR)\cctl_combo.obj \
    8283$(OUTPUTDIR)\cctl_progbar.obj \
    8384$(OUTPUTDIR)\cctl_splitwin.obj \
  • trunk/src/helpers/stringh.c

    r123 r127  
    152152            *ppszTarget = NULL;
    153153    }
     154    else
     155        return (ERROR_INVALID_PARAMETER);
    154156
    155157    if (pulLength)
     
    16591661/* ******************************************************************
    16601662 *
    1661  *   Wildcard matching
    1662  *
    1663  ********************************************************************/
    1664 
    1665 /*
    1666  *  The following code has been taken from "fnmatch.zip".
    1667  *
    1668  *      (c) 1994-1996 by Eberhard Mattes.
    1669  */
    1670 
    1671 /* In OS/2 and DOS styles, both / and \ separate components of a path.
    1672  * This macro returns true iff C is a separator. */
    1673 
    1674 #define IS_OS2_COMP_SEP(C)  ((C) == '/' || (C) == '\\')
    1675 
    1676 
    1677 /* This macro returns true if C is at the end of a component of a
    1678  * path. */
    1679 
    1680 #define IS_OS2_COMP_END(C)  ((C) == 0 || IS_OS2_COMP_SEP (C))
    1681 
    1682 /*
    1683  * skip_comp_os2:
    1684  *      Return a pointer to the next component of the path SRC, for OS/2
    1685  *      and DOS styles.  When the end of the string is reached, a pointer
    1686  *      to the terminating null character is returned.
    1687  *
    1688  *      (c) 1994-1996 by Eberhard Mattes.
    1689  */
    1690 
    1691 static const unsigned char* skip_comp_os2(const unsigned char *src)
    1692 {
    1693     /* Skip characters until hitting a separator or the end of the
    1694      * string. */
    1695 
    1696     while (!IS_OS2_COMP_END(*src))
    1697         ++src;
    1698 
    1699     /* Skip the separator if we hit a separator. */
    1700 
    1701     if (*src != 0)
    1702         ++src;
    1703     return src;
    1704 }
    1705 
    1706 /*
    1707  * has_colon:
    1708  *      returns true iff the path P contains a colon.
    1709  *
    1710  *      (c) 1994-1996 by Eberhard Mattes.
    1711  */
    1712 
    1713 static int has_colon(const unsigned char *p)
    1714 {
    1715     while (*p != 0)
    1716         if (*p == ':')
    1717             return 1;
    1718         else
    1719             ++p;
    1720     return 0;
    1721 }
    1722 
    1723 /*
    1724  * match_comp_os2:
    1725  *      compares a single component (directory name or file name)
    1726  *      of the paths, for OS/2 and DOS styles. MASK and NAME point
    1727  *      into a component of the wildcard and the name to be checked,
    1728  *      respectively. Comparing stops at the next separator.
    1729  *      The FLAGS argument is the same as that of fnmatch().
    1730  *
    1731  *      HAS_DOT is true if a dot is in the current component of NAME.
    1732  *      The number of dots is not restricted, even in DOS style.
    1733  *
    1734  *      Returns FNM_MATCH iff MASK and NAME match.
    1735  *
    1736  *      Note that this function is recursive.
    1737  *
    1738  *      (c) 1994-1996 by Eberhard Mattes.
    1739  */
    1740 
    1741 static int match_comp_os2(const unsigned char *mask,
    1742                           const unsigned char *name,
    1743                           unsigned flags,
    1744                           int has_dot)
    1745 {
    1746     int             rc;
    1747 
    1748     for (;;)
    1749         switch (*mask)
    1750         {
    1751             case 0:
    1752 
    1753                 /* There must be no extra characters at the end of NAME when
    1754                  * reaching the end of MASK unless _FNM_PATHPREFIX is set:
    1755                  * in that case, NAME may point to a separator. */
    1756 
    1757                 if (*name == 0)
    1758                     return FNM_MATCH;
    1759                 if ((flags & FNM_PATHPREFIX) && IS_OS2_COMP_SEP(*name))
    1760                     return FNM_MATCH;
    1761                 return FNM_NOMATCH;
    1762 
    1763             case '/':
    1764             case '\\':
    1765 
    1766                 /* Separators match separators. */
    1767 
    1768                 if (IS_OS2_COMP_SEP(*name))
    1769                     return FNM_MATCH;
    1770 
    1771                 /* If _FNM_PATHPREFIX is set, a trailing separator in MASK
    1772                  * is ignored at the end of NAME. */
    1773 
    1774                 if ((flags & FNM_PATHPREFIX) && mask[1] == 0 && *name == 0)
    1775                     return FNM_MATCH;
    1776 
    1777                 /* Stop comparing at the separator. */
    1778 
    1779                 return FNM_NOMATCH;
    1780 
    1781             case '?':
    1782 
    1783                 /* A question mark matches one character.  It does not match
    1784                  * a dot.  At the end of the component (and before a dot),
    1785                  * it also matches zero characters. */
    1786 
    1787                 if (*name != '.' && !IS_OS2_COMP_END(*name))
    1788                     ++name;
    1789                 ++mask;
    1790                 break;
    1791 
    1792             case '*':
    1793 
    1794                 /* An asterisk matches zero or more characters.  In DOS
    1795                  * mode, dots are not matched. */
    1796 
    1797                 do
    1798                 {
    1799                     ++mask;
    1800                 }
    1801                 while (*mask == '*');
    1802                 for (;;)
    1803                 {
    1804                     rc = match_comp_os2(mask, name, flags, has_dot);
    1805                     if (rc != FNM_NOMATCH)
    1806                         return rc;
    1807                     if (IS_OS2_COMP_END(*name))
    1808                         return FNM_NOMATCH;
    1809                     if (*name == '.' && (flags & FNM_STYLE_MASK) == FNM_DOS)
    1810                         return FNM_NOMATCH;
    1811                     ++name;
    1812                 }
    1813 
    1814             case '.':
    1815 
    1816                 /* A dot matches a dot.  It also matches the implicit dot at
    1817                  * the end of a dot-less NAME. */
    1818 
    1819                 ++mask;
    1820                 if (*name == '.')
    1821                     ++name;
    1822                 else if (has_dot || !IS_OS2_COMP_END(*name))
    1823                     return FNM_NOMATCH;
    1824                 break;
    1825 
    1826             default:
    1827 
    1828                 /* All other characters match themselves. */
    1829 
    1830                 if (flags & FNM_IGNORECASE)
    1831                 {
    1832                     if (tolower(*mask) != tolower(*name))
    1833                         return FNM_NOMATCH;
    1834                 }
    1835                 else
    1836                 {
    1837                     if (*mask != *name)
    1838                         return FNM_NOMATCH;
    1839                 }
    1840                 ++mask;
    1841                 ++name;
    1842                 break;
    1843         }
    1844 }
    1845 
    1846 /*
    1847  * match_comp:
    1848  *      compares a single component (directory name or file
    1849  *      name) of the paths, for all styles which need
    1850  *      component-by-component matching. MASK and NAME point
    1851  *      to the start of a component of the wildcard and the
    1852  *      name to be checked, respectively.  Comparing stops at
    1853  *      the next separator. The FLAGS argument is the same as
    1854  *      that of fnmatch().
    1855  *
    1856  *      Return FNM_MATCH iff MASK and NAME match.
    1857  *
    1858  *      (c) 1994-1996 by Eberhard Mattes.
    1859  */
    1860 
    1861 static int match_comp(const unsigned char *mask,
    1862                       const unsigned char *name,
    1863                       unsigned flags)
    1864 {
    1865     const unsigned char *s;
    1866 
    1867     switch (flags & FNM_STYLE_MASK)
    1868     {
    1869         case FNM_OS2:
    1870         case FNM_DOS:
    1871 
    1872             /* For OS/2 and DOS styles, we add an implicit dot at the end of
    1873              * the component if the component doesn't include a dot. */
    1874 
    1875             s = name;
    1876             while (!IS_OS2_COMP_END(*s) && *s != '.')
    1877                 ++s;
    1878             return match_comp_os2(mask, name, flags, *s == '.');
    1879 
    1880         default:
    1881             return FNM_ERR;
    1882     }
    1883 }
    1884 
    1885 /* In Unix styles, / separates components of a path.  This macro
    1886  * returns true iff C is a separator. */
    1887 
    1888 #define IS_UNIX_COMP_SEP(C)  ((C) == '/')
    1889 
    1890 
    1891 /* This macro returns true if C is at the end of a component of a
    1892  * path. */
    1893 
    1894 #define IS_UNIX_COMP_END(C)  ((C) == 0 || IS_UNIX_COMP_SEP (C))
    1895 
    1896 /*
    1897  * match_unix:
    1898  *      matches complete paths for Unix styles.
    1899  *
    1900  *      The FLAGS argument is the same as that of fnmatch().
    1901  *      COMP points to the start of the current component in
    1902  *      NAME.  Return FNM_MATCH iff MASK and NAME match.  The
    1903  *      backslash character is used for escaping ? and * unless
    1904  *      FNM_NOESCAPE is set.
    1905  *
    1906  *      (c) 1994-1996 by Eberhard Mattes.
    1907  */
    1908 
    1909 static int match_unix(const unsigned char *mask,
    1910                       const unsigned char *name,
    1911                       unsigned flags,
    1912                       const unsigned char *comp)
    1913 {
    1914     unsigned char   c1, c2;
    1915     char            invert, matched;
    1916     const unsigned char *start;
    1917     int             rc;
    1918 
    1919     for (;;)
    1920         switch (*mask)
    1921         {
    1922             case 0:
    1923 
    1924                 /* There must be no extra characters at the end of NAME when
    1925                  * reaching the end of MASK unless _FNM_PATHPREFIX is set:
    1926                  * in that case, NAME may point to a separator. */
    1927 
    1928                 if (*name == 0)
    1929                     return FNM_MATCH;
    1930                 if ((flags & FNM_PATHPREFIX) && IS_UNIX_COMP_SEP(*name))
    1931                     return FNM_MATCH;
    1932                 return FNM_NOMATCH;
    1933 
    1934             case '?':
    1935 
    1936                 /* A question mark matches one character.  It does not match
    1937                  * the component separator if FNM_PATHNAME is set.  It does
    1938                  * not match a dot at the start of a component if FNM_PERIOD
    1939                  * is set. */
    1940 
    1941                 if (*name == 0)
    1942                     return FNM_NOMATCH;
    1943                 if ((flags & FNM_PATHNAME) && IS_UNIX_COMP_SEP(*name))
    1944                     return FNM_NOMATCH;
    1945                 if (*name == '.' && (flags & FNM_PERIOD) && name == comp)
    1946                     return FNM_NOMATCH;
    1947                 ++mask;
    1948                 ++name;
    1949                 break;
    1950 
    1951             case '*':
    1952 
    1953                 /* An asterisk matches zero or more characters.  It does not
    1954                  * match the component separator if FNM_PATHNAME is set.  It
    1955                  * does not match a dot at the start of a component if
    1956                  * FNM_PERIOD is set. */
    1957 
    1958                 if (*name == '.' && (flags & FNM_PERIOD) && name == comp)
    1959                     return FNM_NOMATCH;
    1960                 do
    1961                 {
    1962                     ++mask;
    1963                 }
    1964                 while (*mask == '*');
    1965                 for (;;)
    1966                 {
    1967                     rc = match_unix(mask, name, flags, comp);
    1968                     if (rc != FNM_NOMATCH)
    1969                         return rc;
    1970                     if (*name == 0)
    1971                         return FNM_NOMATCH;
    1972                     if ((flags & FNM_PATHNAME) && IS_UNIX_COMP_SEP(*name))
    1973                         return FNM_NOMATCH;
    1974                     ++name;
    1975                 }
    1976 
    1977             case '/':
    1978 
    1979                 /* Separators match only separators.  If _FNM_PATHPREFIX is
    1980                  * set, a trailing separator in MASK is ignored at the end
    1981                  * of NAME. */
    1982 
    1983                 if (!(IS_UNIX_COMP_SEP(*name)
    1984                       || ((flags & FNM_PATHPREFIX) && *name == 0
    1985                       && (mask[1] == 0
    1986                           || (!(flags & FNM_NOESCAPE) && mask[1] == '\\'
    1987                   && mask[2] == 0)))))
    1988                     return FNM_NOMATCH;
    1989 
    1990                 ++mask;
    1991                 if (*name != 0)
    1992                     ++name;
    1993 
    1994                 /* This is the beginning of a new component if FNM_PATHNAME
    1995                  * is set. */
    1996 
    1997                 if (flags & FNM_PATHNAME)
    1998                     comp = name;
    1999                 break;
    2000 
    2001             case '[':
    2002 
    2003                 /* A set of characters.  Always case-sensitive. */
    2004 
    2005                 if (*name == 0)
    2006                     return FNM_NOMATCH;
    2007                 if ((flags & FNM_PATHNAME) && IS_UNIX_COMP_SEP(*name))
    2008                     return FNM_NOMATCH;
    2009                 if (*name == '.' && (flags & FNM_PERIOD) && name == comp)
    2010                     return FNM_NOMATCH;
    2011 
    2012                 invert = 0;
    2013                 matched = 0;
    2014                 ++mask;
    2015 
    2016                 /* If the first character is a ! or ^, the set matches all
    2017                  * characters not listed in the set. */
    2018 
    2019                 if (*mask == '!' || *mask == '^')
    2020                 {
    2021                     ++mask;
    2022                     invert = 1;
    2023                 }
    2024 
    2025                 /* Loop over all the characters of the set.  The loop ends
    2026                  * if the end of the string is reached or if a ] is
    2027                  * encountered unless it directly follows the initial [ or
    2028                  * [-. */
    2029 
    2030                 start = mask;
    2031                 while (!(*mask == 0 || (*mask == ']' && mask != start)))
    2032                 {
    2033                     /* Get the next character which is optionally preceded
    2034                      * by a backslash. */
    2035 
    2036                     c1 = *mask++;
    2037                     if (!(flags & FNM_NOESCAPE) && c1 == '\\')
    2038                     {
    2039                         if (*mask == 0)
    2040                             break;
    2041                         c1 = *mask++;
    2042                     }
    2043 
    2044                     /* Ranges of characters are written as a-z.  Don't
    2045                      * forget to check for the end of the string and to
    2046                      * handle the backslash.  If the character after - is a
    2047                      * ], it isn't a range. */
    2048 
    2049                     if (*mask == '-' && mask[1] != ']')
    2050                     {
    2051                         ++mask; /* Skip the - character */
    2052                         if (!(flags & FNM_NOESCAPE) && *mask == '\\')
    2053                             ++mask;
    2054                         if (*mask == 0)
    2055                             break;
    2056                         c2 = *mask++;
    2057                     }
    2058                     else
    2059                         c2 = c1;
    2060 
    2061                     /* Now check whether this character or range matches NAME. */
    2062 
    2063                     if (c1 <= *name && *name <= c2)
    2064                         matched = 1;
    2065                 }
    2066 
    2067                 /* If the end of the string is reached before a ] is found,
    2068                  * back up to the [ and compare it to NAME. */
    2069 
    2070                 if (*mask == 0)
    2071                 {
    2072                     if (*name != '[')
    2073                         return FNM_NOMATCH;
    2074                     ++name;
    2075                     mask = start;
    2076                     if (invert)
    2077                         --mask;
    2078                 }
    2079                 else
    2080                 {
    2081                     if (invert)
    2082                         matched = !matched;
    2083                     if (!matched)
    2084                         return FNM_NOMATCH;
    2085                     ++mask;     /* Skip the ] character */
    2086                     if (*name != 0)
    2087                         ++name;
    2088                 }
    2089                 break;
    2090 
    2091             case '\\':
    2092                 ++mask;
    2093                 if (flags & FNM_NOESCAPE)
    2094                 {
    2095                     if (*name != '\\')
    2096                         return FNM_NOMATCH;
    2097                     ++name;
    2098                 }
    2099                 else if (*mask == '*' || *mask == '?')
    2100                 {
    2101                     if (*mask != *name)
    2102                         return FNM_NOMATCH;
    2103                     ++mask;
    2104                     ++name;
    2105                 }
    2106                 break;
    2107 
    2108             default:
    2109 
    2110                 /* All other characters match themselves. */
    2111 
    2112                 if (flags & FNM_IGNORECASE)
    2113                 {
    2114                     if (tolower(*mask) != tolower(*name))
    2115                         return FNM_NOMATCH;
    2116                 }
    2117                 else
    2118                 {
    2119                     if (*mask != *name)
    2120                         return FNM_NOMATCH;
    2121                 }
    2122                 ++mask;
    2123                 ++name;
    2124                 break;
    2125         }
    2126 }
    2127 
    2128 /*
    2129  * _fnmatch_unsigned:
    2130  *      Check whether the path name NAME matches the wildcard MASK.
    2131  *
    2132  *      Return:
    2133  *      --   0 (FNM_MATCH) if it matches,
    2134  *      --   _FNM_NOMATCH if it doesn't,
    2135  *      --   FNM_ERR on error.
    2136  *
    2137  *      The operation of this function is controlled by FLAGS.
    2138  *      This is an internal function, with unsigned arguments.
    2139  *
    2140  *      (c) 1994-1996 by Eberhard Mattes.
    2141  */
    2142 
    2143 static int _fnmatch_unsigned(const unsigned char *mask,
    2144                              const unsigned char *name,
    2145                              unsigned flags)
    2146 {
    2147     int     m_drive,
    2148             n_drive,
    2149             rc;
    2150 
    2151     /* Match and skip the drive name if present. */
    2152 
    2153     m_drive = ((isalpha(mask[0]) && mask[1] == ':') ? mask[0] : -1);
    2154     n_drive = ((isalpha(name[0]) && name[1] == ':') ? name[0] : -1);
    2155 
    2156     if (m_drive != n_drive)
    2157     {
    2158         if (m_drive == -1 || n_drive == -1)
    2159             return FNM_NOMATCH;
    2160         if (!(flags & FNM_IGNORECASE))
    2161             return FNM_NOMATCH;
    2162         if (tolower(m_drive) != tolower(n_drive))
    2163             return FNM_NOMATCH;
    2164     }
    2165 
    2166     if (m_drive != -1)
    2167         mask += 2;
    2168     if (n_drive != -1)
    2169         name += 2;
    2170 
    2171     /* Colons are not allowed in path names, except for the drive name,
    2172      * which was skipped above. */
    2173 
    2174     if (has_colon(mask) || has_colon(name))
    2175         return FNM_ERR;
    2176 
    2177     /* The name "\\server\path" should not be matched by mask
    2178      * "\*\server\path".  Ditto for /. */
    2179 
    2180     switch (flags & FNM_STYLE_MASK)
    2181     {
    2182         case FNM_OS2:
    2183         case FNM_DOS:
    2184 
    2185             if (IS_OS2_COMP_SEP(name[0]) && IS_OS2_COMP_SEP(name[1]))
    2186             {
    2187                 if (!(IS_OS2_COMP_SEP(mask[0]) && IS_OS2_COMP_SEP(mask[1])))
    2188                     return FNM_NOMATCH;
    2189                 name += 2;
    2190                 mask += 2;
    2191             }
    2192             break;
    2193 
    2194         case FNM_POSIX:
    2195 
    2196             if (name[0] == '/' && name[1] == '/')
    2197             {
    2198                 int             i;
    2199 
    2200                 name += 2;
    2201                 for (i = 0; i < 2; ++i)
    2202                     if (mask[0] == '/')
    2203                         ++mask;
    2204                     else if (mask[0] == '\\' && mask[1] == '/')
    2205                         mask += 2;
    2206                     else
    2207                         return FNM_NOMATCH;
    2208             }
    2209 
    2210             /* In Unix styles, treating ? and * w.r.t. components is simple.
    2211              * No need to do matching component by component. */
    2212 
    2213             return match_unix(mask, name, flags, name);
    2214     }
    2215 
    2216     /* Now compare all the components of the path name, one by one.
    2217      * Note that the path separator must not be enclosed in brackets. */
    2218 
    2219     while (*mask != 0 || *name != 0)
    2220     {
    2221 
    2222         /* If _FNM_PATHPREFIX is set, the names match if the end of MASK
    2223          * is reached even if there are components left in NAME. */
    2224 
    2225         if (*mask == 0 && (flags & FNM_PATHPREFIX))
    2226             return FNM_MATCH;
    2227 
    2228         /* Compare a single component of the path name. */
    2229 
    2230         rc = match_comp(mask, name, flags);
    2231         if (rc != FNM_MATCH)
    2232             return rc;
    2233 
    2234         /* Skip to the next component or to the end of the path name. */
    2235 
    2236         mask = skip_comp_os2(mask);
    2237         name = skip_comp_os2(name);
    2238     }
    2239 
    2240     /* If we reached the ends of both strings, the names match. */
    2241 
    2242     if (*mask == 0 && *name == 0)
    2243         return FNM_MATCH;
    2244 
    2245     /* The names do not match. */
    2246 
    2247     return FNM_NOMATCH;
    2248 }
    2249 
    2250 /*
    2251  *@@ strhMatchOS2:
    2252  *      this matches wildcards, similar to what DosEditName does.
    2253  *      However, this does not require a file to be present, but
    2254  *      works on strings only.
    2255  */
    2256 
    2257 BOOL strhMatchOS2(const char *pcszMask,     // in: mask (e.g. "*.txt")
    2258                   const char *pcszName)     // in: string to check (e.g. "test.txt")
    2259 {
    2260     return ((BOOL)(_fnmatch_unsigned((const unsigned char *)pcszMask,
    2261                                      (const unsigned char *)pcszName,
    2262                                      FNM_OS2 | FNM_IGNORECASE)
    2263                    == FNM_MATCH)
    2264            );
    2265 }
    2266 
    2267 /*
    2268  *@@ strhMatchExt:
    2269  *      like strhMatchOS2, but this takes all the flags
    2270  *      for input.
    2271  *
    2272  *@@added V0.9.15 (2001-09-14) [umoeller]
    2273  */
    2274 
    2275 BOOL strhMatchExt(const char *pcszMask,     // in: mask (e.g. "*.txt")
    2276                   const char *pcszName,     // in: string to check (e.g. "test.txt")
    2277                   unsigned flags)           // in: FNM_* flags
    2278 {
    2279     return ((BOOL)(_fnmatch_unsigned((const unsigned char *)pcszMask,
    2280                                      (const unsigned char *)pcszName,
    2281                                      flags)
    2282                    == FNM_MATCH)
    2283            );
    2284 }
    2285 
    2286 /* ******************************************************************
    2287  *
    22881663 *   Fast string searches
    22891664 *
  • trunk/src/helpers/timer.c

    r123 r127  
    1212 *      to those XTimers which have elapsed.
    1313 *
    14  *      So to use XTimers, do the following:
    15  *
    16  *      1.  Create a timer set with tmrCreateSet. Specify
    17  *          an owner window and the timer ID of the master
    18  *          PM timer.
    19  *
    20  *      2.  You can then start and stop XTimers for windows
    21  *          on the same thread by calling tmrStartXTimer and
    22  *          tmrStopXTimer, respectively.
    23  *
    24  *      3.  In the window proc of the owner window, respond
    25  *          to WM_TIMER for the master PM timer by calling
    26  *          tmrTimerTick. This will call the window procs
    27  *          of those windows with WM_TIMER messages directly
    28  *          whose XTimers have elapsed.
    29  *
    3014 *      The main advantage of the XTimers is that these
    3115 *      are not a limited resource (as opposed to PM timers).
     
    3418 *      be queried with WinQuerySysValue(SV_CTIMERS).
    3519 *
     20 *      XTimers are used excessively by the default widgets
     21 *      of XWorkplace's XCenter.
     22 *
    3623 *      There are a few limitations with the XTimers though:
    37  *
    38  *      --  If you start a timer with a timeout < 100 ms,
    39  *          the first WM_TIMER might not appear before
    40  *          100 ms have elapsed. This may or be not the
    41  *          case, depending on whether other timers are
    42  *          running.
    4324 *
    4425 *      --  tmrTimerTick (which you must call when the
     
    6243 *          side, always call tmrStopAllTimers when WM_DESTROY
    6344 *          comes into a window which has used timers.
     45 *
     46 *      So to use XTimers, do the following:
     47 *
     48 *      1.  Create a timer set with tmrCreateSet. Specify
     49 *          an owner window and the timer ID of the master
     50 *          PM timer.
     51 *
     52 *      2.  You can then start and stop XTimers for windows
     53 *          on the same thread by calling tmrStartXTimer and
     54 *          tmrStopXTimer, respectively.
     55 *
     56 *      3.  In the window proc of the owner window, respond
     57 *          to WM_TIMER for the master PM timer by calling
     58 *          tmrTimerTick. This will call the window procs
     59 *          of those windows with WM_TIMER messages directly
     60 *          whose XTimers have elapsed.
    6461 *
    6562 *      Function prefixes:
     
    195192                  USHORT usTimerID)         // in: timer ID
    196193{
    197     if (pSet && pSet->pvllXTimers)
    198     {
    199         PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers;
     194    PLINKLIST pllXTimers;
     195    if (    (pSet)
     196         && (pllXTimers = (PLINKLIST)pSet->pvllXTimers)
     197       )
     198    {
    200199        PLISTNODE pNode = lstQueryFirstNode(pllXTimers);
    201200        while (pNode)
     
    227226                 PXTIMER pTimer)        // in: timer to remove.
    228227{
    229     if (pSet && pSet->pvllXTimers)
    230     {
    231         PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers;
     228    PLINKLIST pllXTimers;
     229    if (    (pSet)
     230         && (pllXTimers = (PLINKLIST)pSet->pvllXTimers)
     231       )
     232    {
    232233        lstRemoveItem(pllXTimers,
    233234                      pTimer);       // auto-free!
     
    409410        if (pSet)
    410411        {
    411             PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers;
    412             if (pllXTimers)
     412            PLINKLIST pllXTimers;
     413            if (pllXTimers = (PLINKLIST)pSet->pvllXTimers)
    413414            {
    414415                PLISTNODE pTimerNode = lstQueryFirstNode(pllXTimers);
     
    424425                pSet->pvllXTimers = NULL;
    425426            }
     427
     428            if (pSet->idPMTimerRunning)
     429            {
     430                WinStopTimer(pSet->hab,
     431                             pSet->hwndOwner,
     432                             pSet->idPMTimer);
     433                pSet->idPMTimerRunning = 0;
     434            }
     435
     436            free(pSet);
    426437        }
    427 
    428         if (pSet->idPMTimerRunning)
    429         {
    430             WinStopTimer(pSet->hab,
    431                          pSet->hwndOwner,
    432                          pSet->idPMTimer);
    433             pSet->idPMTimerRunning = 0;
    434         }
    435 
    436         free(pSet);
    437438
    438439        UnlockTimers();
     
    456457 *@@changed V0.9.14 (2001-08-01) [umoeller]: fixed mem overwrite which might have caused crashes if this got called during tmrTimerTick
    457458 *@@changed V0.9.14 (2001-08-03) [umoeller]: fixed "half frequency" regression caused by frequency optimizations
     459 *@@changed V0.9.16 (2001-12-18) [umoeller]: now using WinDispatchMsg to avoid crashes during win destruction
    458460 */
    459461
     
    462464    if (LockTimers())
    463465    {
    464         if (pSet)
    465         {
    466             PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers;
    467             if (pllXTimers)
     466        PLINKLIST pllXTimers;
     467        if (    (pSet)
     468             && (pllXTimers = (PLINKLIST)pSet->pvllXTimers)
     469           )
     470        {
     471            // go thru all XTimers and see which one
     472            // has elapsed; for all of these, post WM_TIMER
     473            // to the target window proc
     474            PLISTNODE pTimerNode = lstQueryFirstNode(pllXTimers);
     475
     476            if (!pTimerNode)
    468477            {
    469                 // go thru all XTimers and see which one
    470                 // has elapsed; for all of these, post WM_TIMER
    471                 // to the target window proc
    472                 PLISTNODE pTimerNode = lstQueryFirstNode(pllXTimers);
    473 
    474                 if (!pTimerNode)
     478                // no timers left:
     479                if (pSet->idPMTimerRunning)
    475480                {
    476                     // no timers left:
    477                     if (pSet->idPMTimerRunning)
     481                    // but PM timer running:
     482                    // stop it
     483                    WinStopTimer(pSet->hab,
     484                                 pSet->hwndOwner,
     485                                 pSet->idPMTimer);
     486                    pSet->idPMTimerRunning = 0;
     487                }
     488
     489                pSet->ulPMTimeout = 0;
     490            }
     491            else
     492            {
     493                // we have timers:
     494                BOOL    fFoundInvalid = FALSE;
     495
     496                // get current time
     497                ULONG   ulTimeNow = 0;
     498                DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT,
     499                                &ulTimeNow, sizeof(ulTimeNow));
     500
     501                #ifdef DEBUG_XTIMERS
     502                    _Pmpf((__FUNCTION__ ": ulTimeNow = %d", ulTimeNow));
     503                #endif
     504
     505                while (pTimerNode)
     506                {
     507                    // get next node first because the
     508                    // list can get modified while processing
     509                    // V0.9.12 (2001-05-24) [umoeller]
     510                    PLISTNODE pNext = pTimerNode->pNext;
     511
     512                    PXTIMER pTimer = (PXTIMER)pTimerNode->pItemData;
     513
     514                    #ifdef DEBUG_XTIMERS
     515                        _Pmpf(("   timer %d: ulNextFire = %d",
     516                                lstIndexFromItem(pllXTimers, pTimer),
     517                                pTimer->ulNextFire));
     518                    #endif
     519
     520                    if (    (pTimer)
     521                         // && (pTimer->ulNextFire < ulTimeNow)
     522                            // V0.9.14 (2001-08-01) [umoeller]
     523                            // use <= because otherwise we'll get
     524                            // only half the frequency...
     525                            // we get here frequently where the
     526                            // two values are EXACTLY equal due
     527                            // to the above optimization (DosQuerySysInfo
     528                            // called once only for the entire loop)
     529                         && (pTimer->ulNextFire <= ulTimeNow)
     530                       )
    478531                    {
    479                         // but PM timer running:
    480                         // stop it
    481                         WinStopTimer(pSet->hab,
    482                                      pSet->hwndOwner,
    483                                      pSet->idPMTimer);
    484                         pSet->idPMTimerRunning = 0;
    485                     }
    486 
    487                     pSet->ulPMTimeout = 0;
    488                 }
    489                 else
    490                 {
    491                     // we have timers:
    492                     BOOL    fFoundInvalid = FALSE;
    493 
    494                     // get current time
    495                     ULONG   ulTimeNow = 0;
    496                     DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT,
    497                                     &ulTimeNow, sizeof(ulTimeNow));
    498 
    499                     #ifdef DEBUG_XTIMERS
    500                         _Pmpf((__FUNCTION__ ": ulTimeNow = %d", ulTimeNow));
    501                     #endif
    502 
    503                     while (pTimerNode)
    504                     {
    505                         // get next node first because the
    506                         // list can get modified while processing
    507                         // V0.9.12 (2001-05-24) [umoeller]
    508                         PLISTNODE pNext = pTimerNode->pNext;
    509 
    510                         PXTIMER pTimer = (PXTIMER)pTimerNode->pItemData;
     532                        // this timer has elapsed:
     533                        // fire!
    511534
    512535                        #ifdef DEBUG_XTIMERS
    513                             _Pmpf(("   timer %d: ulNextFire = %d",
    514                                     lstIndexFromItem(pllXTimers, pTimer),
    515                                     pTimer->ulNextFire));
     536                            _Pmpf(("   --> fire!"));
    516537                        #endif
    517538
    518                         if (    (pTimer)
    519                              // && (pTimer->ulNextFire < ulTimeNow)
    520                                 // V0.9.14 (2001-08-01) [umoeller]
    521                                 // use <= because otherwise we'll get
    522                                 // only half the frequency...
    523                                 // we get here frequently where the
    524                                 // two values are EXACTLY equal due
    525                                 // to the above optimization (DosQuerySysInfo
    526                                 // called once only for the entire loop)
    527                              && (pTimer->ulNextFire <= ulTimeNow)
    528                            )
     539                        if (WinIsWindow(pSet->hab,
     540                                        pTimer->hwndTarget))
    529541                        {
    530                             // this timer has elapsed:
    531                             // fire!
    532 
    533                             #ifdef DEBUG_XTIMERS
    534                                 _Pmpf(("   --> fire!"));
    535                             #endif
    536 
    537                             if (WinIsWindow(pSet->hab,
    538                                             pTimer->hwndTarget))
    539                             {
    540                                 // window still valid:
    541                                 // get the window's window proc
    542                                 QMSG qmsg;
    543                                 /* PFNWP pfnwp = (PFNWP)WinQueryWindowPtr(pTimer->hwndTarget,
    544                                                                        QWP_PFNWP); */
    545 
    546                                 // moved this up V0.9.14 (2001-08-01) [umoeller]
    547                                 pTimer->ulNextFire = ulTimeNow + pTimer->ulTimeout;
    548 
    549                                 // call the window proc DIRECTLY
    550                                 qmsg.hwnd = pTimer->hwndTarget;
    551                                 qmsg.msg = WM_TIMER;
    552                                 qmsg.mp1 = (MPARAM)pTimer->usTimerID;
    553                                 qmsg.mp2 = (MPARAM)0;
    554                                 qmsg.time = 0;
    555                                 qmsg.ptl.x = 0;
    556                                 qmsg.ptl.y = 0;
    557                                 qmsg.reserved = 0;
    558                                 WinDispatchMsg(pSet->hab,
    559                                                &qmsg);
    560                                 /* pfnwp(pTimer->hwndTarget,
    561                                       WM_TIMER,
    562                                       (MPARAM)pTimer->usTimerID,
    563                                       0); */
    564                                     // V0.9.12 (2001-05-24) [umoeller]
    565                                     // if the winproc chooses to start or
    566                                     // stop a timer, pNext still points
    567                                     // to a valid node...
    568                                     // -- if a timer is removed, that's OK
    569                                     // -- if a timer is added, it is added to
    570                                     //    the list, so we'll see it in this loop
    571 
    572                                 // V0.9.14 (2001-08-01) [umoeller]
    573 
    574                                 // DO NOT REFERENCE pTimer AFTER THIS CODE;
    575                                 // tmrTimerTick might have removed the timer,
    576                                 // and since the list is auto-free, pTimer
    577                                 // might have been freed!!
    578                             }
    579                             else
    580                             {
    581                                 // window has been destroyed:
    582                                 lstRemoveNode(pllXTimers,
    583                                               pTimerNode);
    584                                     // pNext is still valid
    585 
    586                                 fFoundInvalid = TRUE;
    587                             }
    588 
    589                         } // end if (pTimer->ulNextFire < ulTimeNow)
    590 
    591                         // next timer
    592                         pTimerNode = pNext; // V0.9.12 (2001-05-24) [umoeller]
    593                     } // end while (pTimerNode)
    594 
    595                     // destroy invalid timers, if any
    596                     if (fFoundInvalid)
    597                         AdjustPMTimer(pSet);
    598 
    599                 } // end else if (!pTimerNode)
    600             } // end if (pllXTimers)
    601         } // end if (pSet)
     542                            // window still valid:
     543                            // get the window's window proc
     544                            QMSG qmsg;
     545                            /* PFNWP pfnwp = (PFNWP)WinQueryWindowPtr(pTimer->hwndTarget,
     546                                                                   QWP_PFNWP); */
     547
     548                            // moved this up V0.9.14 (2001-08-01) [umoeller]
     549                            pTimer->ulNextFire = ulTimeNow + pTimer->ulTimeout;
     550
     551                            // call the window proc DIRECTLY
     552                            // V0.9.16 (2001-12-18) [umoeller]:
     553                            // now using WinDispatchMsg to avoid crashes
     554                            // while hwndTarget is being destroyed
     555                            qmsg.hwnd = pTimer->hwndTarget;
     556                            qmsg.msg = WM_TIMER;
     557                            qmsg.mp1 = (MPARAM)pTimer->usTimerID;
     558                            qmsg.mp2 = (MPARAM)0;
     559                            qmsg.time = 0;
     560                            qmsg.ptl.x = 0;
     561                            qmsg.ptl.y = 0;
     562                            qmsg.reserved = 0;
     563                            WinDispatchMsg(pSet->hab,
     564                                           &qmsg);
     565
     566                            /* pfnwp(pTimer->hwndTarget,
     567                                  WM_TIMER,
     568                                  (MPARAM)pTimer->usTimerID,
     569                                  0); */
     570                                // V0.9.12 (2001-05-24) [umoeller]
     571                                // if the winproc chooses to start or
     572                                // stop a timer, pNext still points
     573                                // to a valid node...
     574                                // -- if a timer is removed, that's OK
     575                                // -- if a timer is added, it is added to
     576                                //    the list, so we'll see it in this loop
     577
     578                            // V0.9.14 (2001-08-01) [umoeller]
     579
     580                            // DO NOT REFERENCE pTimer AFTER THIS CODE;
     581                            // the winproc might have removed the timer,
     582                            // and since the list is auto-free, pTimer
     583                            // might have been freed!!
     584                        }
     585                        else
     586                        {
     587                            // window has been destroyed:
     588                            lstRemoveNode(pllXTimers,
     589                                          pTimerNode);
     590                                // pNext is still valid
     591
     592                            fFoundInvalid = TRUE;
     593                        }
     594
     595                    } // end if (pTimer->ulNextFire < ulTimeNow)
     596
     597                    // next timer
     598                    pTimerNode = pNext; // V0.9.12 (2001-05-24) [umoeller]
     599                } // end while (pTimerNode)
     600
     601                // destroy invalid timers, if any
     602                if (fFoundInvalid)
     603                    AdjustPMTimer(pSet);
     604
     605            } // end else if (!pTimerNode)
     606        } // end if (pllXTimers)
    602607
    603608        UnlockTimers();
     
    614619 *      XTimers is not limited.
    615620 *
    616  *      Returns a new timer or resets an existing
    617  *      timer (if usTimerID is already used with
    618  *      hwnd). Use tmrStopXTimer to stop the timer.
     621 *      Returns the ID of a new timer or resets an
     622 *      existing timer (if usTimerID is already used
     623 *      with hwnd). Use tmrStopXTimer to stop the timer.
     624 *
     625 *      Returns 0 if an error occured. It is thus
     626 *      invalid to specify a timer ID of 0.
    619627 *
    620628 *      The timer is _not_ stopped automatically
     
    644652USHORT XWPENTRY tmrStartXTimer(PXTIMERSET pSet, // in: timer set (from tmrCreateSet)
    645653                               HWND hwnd,       // in: target window for XTimer
    646                                USHORT usTimerID, // in: timer ID for XTimer's WM_TIMER
     654                               USHORT usTimerID, // in: timer ID for XTimer's WM_TIMER (must be > 0)
    647655                               ULONG ulTimeout) // in: XTimer's timeout
    648656{
     
    653661    if (LockTimers())
    654662    {
    655         if (pSet)
    656         {
    657             PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers;
    658 
    659             if ((pllXTimers) && (hwnd) && (ulTimeout))
     663        PLINKLIST pllXTimers;
     664        if (    (pSet)
     665             && (pllXTimers = (PLINKLIST)pSet->pvllXTimers)
     666             && (hwnd)
     667             && (ulTimeout)
     668             && (usTimerID)     // V0.9.16 (2001-12-18) [umoeller]
     669           )
     670        {
     671            PXTIMER pTimer;
     672            ULONG ulTimeNow;
     673
     674            // fix the timeout... we allow only multiples of
     675            // 25, and it must be at least 25 (otherwise our
     676            // internal master timer calculations will fail)
     677            // V0.9.14 (2001-07-07) [umoeller]
     678            if (ulTimeout < 25)
     679                ulTimeout = 25;
     680            else
     681                ulTimeout = (ulTimeout + 10) / 25 * 25;
     682
     683            DosQuerySysInfo(QSV_MS_COUNT,
     684                            QSV_MS_COUNT,
     685                            &ulTimeNow,
     686                            sizeof(ulTimeNow));
     687
     688            // check if this timer exists already
     689            if (pTimer = FindTimer(pSet,
     690                                   hwnd,
     691                                   usTimerID))
    660692            {
    661                 PXTIMER pTimer;
    662 
    663                 // fix the timeout... we allow only multiples of
    664                 // 25, and it must be at least 25 (otherwise our
    665                 // internal master timer calculations will fail)
    666                 // V0.9.14 (2001-07-07) [umoeller]
    667                 if (ulTimeout < 25)
    668                     ulTimeout = 25;
    669                 else
    670                     ulTimeout = (ulTimeout + 10) / 25 * 25;
    671 
    672                 // check if this timer exists already
    673                 if (pTimer = FindTimer(pSet,
    674                                        hwnd,
    675                                        usTimerID))
     693                // exists already: reset only
     694                pTimer->ulNextFire = ulTimeNow + ulTimeout;
     695                usrc = usTimerID;
     696            }
     697            else
     698            {
     699                // new timer needed:
     700                if (pTimer = NEW(XTIMER))
    676701                {
    677                     // exists already: reset only
    678                     ULONG ulTimeNow;
    679                     DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT,
    680                                     &ulTimeNow, sizeof(ulTimeNow));
     702                    pTimer->usTimerID = usTimerID;
     703                    pTimer->hwndTarget = hwnd;
     704                    pTimer->ulTimeout = ulTimeout;
    681705                    pTimer->ulNextFire = ulTimeNow + ulTimeout;
     706
     707                    lstAppendItem(pllXTimers,
     708                                  pTimer);
    682709                    usrc = usTimerID;
    683710                }
    684                 else
    685                 {
    686                     // new timer needed:
    687                     if (pTimer = NEW(XTIMER))
    688                     {
    689                         ULONG ulTimeNow;
    690                         DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT,
    691                                         &ulTimeNow, sizeof(ulTimeNow));
    692                         pTimer->usTimerID = usTimerID;
    693                         pTimer->hwndTarget = hwnd;
    694                         pTimer->ulTimeout = ulTimeout;
    695                         pTimer->ulNextFire = ulTimeNow + ulTimeout;
    696 
    697                         lstAppendItem(pllXTimers,
    698                                       pTimer);
    699                         usrc = usTimerID;
    700                     }
    701                 }
    702 
    703                 if (usrc)
    704                     // timer created or reset:
    705                     AdjustPMTimer(pSet);
    706 
    707             } // if ((hwnd) && (ulTimeout))
    708         }
     711            }
     712
     713            if (usrc)
     714                // timer created or reset:
     715                AdjustPMTimer(pSet);
     716
     717        } // if ((hwnd) && (ulTimeout))
    709718
    710719        UnlockTimers();
     
    733742    if (LockTimers())
    734743    {
    735         if (pSet && pSet->pvllXTimers)
    736         {
    737             // PLINKLIST pllXTimers = (PLINKLIST)pSet->pvllXTimers;
    738 
    739             PXTIMER pTimer = FindTimer(pSet,
    740                                        hwnd,
    741                                        usTimerID);
    742             if (pTimer)
    743             {
    744                 RemoveTimer(pSet, pTimer);
    745                 // recalculate
    746                 AdjustPMTimer(pSet);
    747                 brc = TRUE;
    748             }
     744        PXTIMER pTimer;
     745        if (pTimer = FindTimer(pSet,
     746                               hwnd,
     747                               usTimerID))
     748                // FindTimer checks the params
     749        {
     750            RemoveTimer(pSet, pTimer);
     751            // recalculate
     752            AdjustPMTimer(pSet);
     753            brc = TRUE;
    749754        }
    750755
  • trunk/src/helpers/wphandle.c

    r116 r127  
    949949 *      filename for hObject.
    950950 *      This is a one-shot function, using wphQueryActiveHandles,
    951  *      wphReadAllBlocks, and wphFindPartName.
     951 *      wphLoadHandles, and wphComposePath.
     952 *      As a result, this function is _very_ expensive.
    952953 *
    953954 *      Returns:
     
    956957 *
    957958 *      --  ERROR_INVALID_HANDLE: hObject is invalid.
     959 *
     960 *      --  ERROR_WPH_NOT_FILESYSTEM_HANDLE: hObject's hiword is wrong.
    958961 *
    959962 *@@changed V0.9.16 (2001-10-02) [umoeller]: rewritten
     
    983986            else
    984987            {
     988                USHORT usHiwordFileSystem = ((PHANDLESBUF)hHandles)->usHiwordFileSystem;
     989
    985990                // is this really a file-system object?
    986                 if (HIUSHORT(hObject) == ((PHANDLESBUF)hHandles)->usHiwordFileSystem)
     991                if (HIUSHORT(hObject) == usHiwordFileSystem)
    987992                {
    988993                    // use loword only
     
    9981003                    // _Pmpf((__FUNCTION__ ": wphFindPartName returned %d", arc));
    9991004                }
     1005                else
     1006                    arc = ERROR_WPH_NOT_FILESYSTEM_HANDLE;
    10001007
    10011008                wphFreeHandles(&hHandles);
  • trunk/src/helpers/xml.c

    r121 r127  
    11351135                    {
    11361136                        // the element is allowed at all: now check for the
    1137                         // lists case...
     1137                        // lists case... @@todo
    11381138                        switch (ulDeclType)
    11391139                        {
Note: See TracChangeset for help on using the changeset viewer.