Changeset 108


Ignore:
Timestamp:
Oct 13, 2001, 7:57:58 PM (24 years ago)
Author:
umoeller
Message:

Lots of updates from the last week for conditional compiles and other stuff.

Location:
trunk
Files:
22 edited

Legend:

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

    r101 r108  
    7070    APIRET appFreeEnvironment(PDOSENVIRONMENT pEnv);
    7171
     72    #ifdef INCL_WINPROGRAMLIST
     73        // additional PROG_* flags for appQueryAppType
     74        // #define PROG_XWP_DLL            998      // dynamic link library
     75                    // removed, PROG_DLL exists already
     76                    // V0.9.16 (2001-10-06)
     77
     78        APIRET appQueryAppType(const char *pcszExecutable,
     79                                PULONG pulDosAppType,
     80                                PULONG pulWinAppType);
     81
     82        PCSZ appDescribeAppType(PROGCATEGORY progc);
     83
     84        ULONG appIsWindowsApp(ULONG ulProgCategory);
     85
    7286    /* ******************************************************************
    7387     *
     
    7690     ********************************************************************/
    7791
    78     #ifdef INCL_WINPROGRAMLIST
    79         // additional PROG_* flags for appQueryAppType
    80         #define PROG_XWP_DLL            998      // dynamic link library
    81 
    82         APIRET appQueryAppType(const char *pcszExecutable,
    83                                 PULONG pulDosAppType,
    84                                 PULONG pulWinAppType);
    85 
    86         ULONG appIsWindowsApp(ULONG ulProgCategory);
    8792
    8893        PSZ appQueryDefaultWin31Environment(VOID);
  • trunk/include/helpers/dosh.h

    r94 r108  
    836836    } LVMINFO, *PLVMINFO;
    837837
    838     #define DOSH_PARTITIONS_LIMIT   10
     838    /* #define DOSH_PARTITIONS_LIMIT   10
    839839
    840840    #define PAR_UNUSED      0x00    // Unused
     
    881881    #define PAR_FREEBSD     0xA5    // FreeBSD
    882882    #define PAR_BBT         0xFF    // BBT
     883    */
    883884
    884885    // one-byte alignment
     
    966967    typedef struct _PARTITIONINFO
    967968    {
    968         BYTE  bDisk;                 // drive number
    969         CHAR  cLetter;               // probable drive letter or ' ' if none
    970         BYTE  bFSType;               // file system type
    971         CHAR  szFSType[10];          // file system name (created by us)
    972         BOOL  fPrimary;              // primary partition?
    973         BOOL  fBootable;             // bootable by Boot Manager?
    974         CHAR  szBootName[9];         // Boot Manager name, if (fBootable)
    975         ULONG ulSize;                // size MBytes
     969        BYTE    bDisk;                 // drive number
     970        CHAR    cLetter;               // probable drive letter or ' ' if none
     971        BYTE    bFSType;               // file system type
     972        PCSZ    pcszFSType;            // file system name (as returned by
     973                                       // doshType2FSName, can be NULL!)
     974        BOOL    fPrimary;              // primary partition?
     975        BOOL    fBootable;             // bootable by Boot Manager?
     976        CHAR    szBootName[9];         // Boot Manager name, if (fBootable)
     977        ULONG   ulSize;                // size MBytes
    976978        PPARTITIONINFO pNext;        // next info or NULL if last
    977979    } PARTITIONINFO;
  • trunk/include/helpers/prfh.h

    r71 r108  
    3535    #define PRFH_HEADER_INCLUDED
    3636
    37     /* common error codes used by the prfh* functions */
     37    /* ******************************************************************
     38     *
     39     *   Errors
     40     *
     41     ********************************************************************/
    3842
    3943    #define PRFERR_DATASIZE     10001   // couldn't query data size for key
     
    4751    #define PRFERR_INVALID_KEY  10009
    4852    #define PRFERR_KEY_EXISTS   10010
     53
     54    /* ******************************************************************
     55     *
     56     *   Strings
     57     *
     58     ********************************************************************/
     59
     60    // DECLARE_PRFH_STRING is a handy macro which saves us from
     61    // keeping two string lists in both the .h and the .c file.
     62    // If this include file is included from the .c file, the
     63    // string is defined as a global variable. Otherwise
     64    // it is only declared as "extern" so other files can
     65    // see it.
     66
     67    #ifdef INCLUDE_PRFH_PRIVATE
     68        #define DECLARE_PRFH_STRING(str, def) const char *str = def
     69    #else
     70        #define DECLARE_PRFH_STRING(str, def) extern const char *str;
     71    #endif
     72
     73    /*
     74     * OS2.INI applications
     75     *
     76     */
     77
     78    // NLS settings section
     79    DECLARE_PRFH_STRING(PMINIAPP_NATIONAL, "PM_National");
     80
     81    // system font settings section
     82    DECLARE_PRFH_STRING(PMINIAPP_SYSTEMFONTS, "PM_SystemFonts");
     83    DECLARE_PRFH_STRING(PMINIKEY_DEFAULTFONT, "DefaultFont");
     84    DECLARE_PRFH_STRING(PMINIKEY_ICONTEXTFONT, "IconText");
     85    DECLARE_PRFH_STRING(PMINIKEY_MENUSFONT, "Menus");
     86
     87    // installed fonts secsion
     88    DECLARE_PRFH_STRING(PMINIAPP_FONTS, "PM_Fonts");
     89
     90    // general WPS settings
     91    DECLARE_PRFH_STRING(WPINIAPP_WORKPLACE, "PM_Workplace");
     92    DECLARE_PRFH_STRING(WPINIKEY_MENUBAR, "FolderMenuBar");
     93
     94    // abstract objects per folder handle
     95    DECLARE_PRFH_STRING(WPINIAPP_FDRCONTENT, "PM_Abstract:FldrContent");
     96    // all defined abstract objects on the system
     97    DECLARE_PRFH_STRING(WPINIAPP_OBJECTS, "PM_Abstract:Objects");
     98    // their icons, if set individually
     99    DECLARE_PRFH_STRING(WPINIAPP_ICONS, "PM_Abstract:Icons");
     100
     101    // object ID's (<WP_DESKTOP> etc.)
     102    DECLARE_PRFH_STRING(WPINIAPP_LOCATION, "PM_Workplace:Location");
     103
     104    // folder positions
     105    DECLARE_PRFH_STRING(WPINIAPP_FOLDERPOS, "PM_Workplace:FolderPos");
     106
     107    // palette positions
     108    DECLARE_PRFH_STRING(WPINIAPP_PALETTEPOS, "PM_Workplace:PalettePos");
     109    // ???
     110    DECLARE_PRFH_STRING(WPINIAPP_STATUSPOS, "PM_Workplace:StatusPos");
     111    // startup folders
     112    DECLARE_PRFH_STRING(WPINIAPP_STARTUP, "PM_Workplace:Startup");
     113    // all the defined templates on the system
     114    DECLARE_PRFH_STRING(WPINIAPP_TEMPLATES, "PM_Workplace:Templates");
     115
     116    // all work area folders
     117    DECLARE_PRFH_STRING(WPINIAPP_WORKAREARUNNING, "FolderWorkareaRunningObjects");
     118    // spooler windows ?!?
     119    DECLARE_PRFH_STRING(WPINIAPP_JOBCNRPOS, "PM_PrintObject:JobCnrPos");
     120
     121    // associations by type ("Plain Text")
     122    DECLARE_PRFH_STRING(WPINIAPP_ASSOCTYPE, "PMWP_ASSOC_TYPE");
     123    // associations by filter ("*.txt")
     124    DECLARE_PRFH_STRING(WPINIAPP_ASSOCFILTER, "PMWP_ASSOC_FILTER");
     125    // checksums ?!?
     126    DECLARE_PRFH_STRING(WPINIAPP_ASSOC_CHECKSUM, "PMWP_ASSOC_CHECKSUM");
     127
     128    /*
     129     * OS2SYS.INI applications
     130     *
     131     */
     132
     133    DECLARE_PRFH_STRING(WPINIAPP_ACTIVEHANDLES, "PM_Workplace:ActiveHandles");
     134    DECLARE_PRFH_STRING(WPINIAPP_HANDLES, "PM_Workplace:Handles");
     135    DECLARE_PRFH_STRING(WPINIAPP_HANDLESAPP, "HandlesAppName");
     136
     137    /*
     138     * some default WPS INI keys:
     139     *
     140     */
     141
     142    DECLARE_PRFH_STRING(WPOBJID_DESKTOP, "<WP_DESKTOP>");
     143
     144    DECLARE_PRFH_STRING(WPOBJID_KEYB, "<WP_KEYB>");
     145    DECLARE_PRFH_STRING(WPOBJID_MOUSE, "<WP_MOUSE>");
     146    DECLARE_PRFH_STRING(WPOBJID_CNTRY, "<WP_CNTRY>");
     147    DECLARE_PRFH_STRING(WPOBJID_SOUND, "<WP_SOUND>");
     148    DECLARE_PRFH_STRING(WPOBJID_SYSTEM, "<WP_SYSTEM>"); // V0.9.9
     149    DECLARE_PRFH_STRING(WPOBJID_POWER, "<WP_POWER>");
     150    DECLARE_PRFH_STRING(WPOBJID_WINCFG, "<WP_WINCFG>");
     151
     152    DECLARE_PRFH_STRING(WPOBJID_HIRESCLRPAL, "<WP_HIRESCLRPAL>");
     153    DECLARE_PRFH_STRING(WPOBJID_LORESCLRPAL, "<WP_LORESCLRPAL>");
     154    DECLARE_PRFH_STRING(WPOBJID_FNTPAL, "<WP_FNTPAL>");
     155    DECLARE_PRFH_STRING(WPOBJID_SCHPAL96, "<WP_SCHPAL96>");
     156
     157    DECLARE_PRFH_STRING(WPOBJID_LAUNCHPAD, "<WP_LAUNCHPAD>");
     158    DECLARE_PRFH_STRING(WPOBJID_WARPCENTER, "<WP_WARPCENTER>");
     159
     160    DECLARE_PRFH_STRING(WPOBJID_SPOOL, "<WP_SPOOL>");
     161    DECLARE_PRFH_STRING(WPOBJID_VIEWER, "<WP_VIEWER>");
     162    DECLARE_PRFH_STRING(WPOBJID_SHRED, "<WP_SHRED>");
     163    DECLARE_PRFH_STRING(WPOBJID_CLOCK, "<WP_CLOCK>");
     164
     165    DECLARE_PRFH_STRING(WPOBJID_START, "<WP_START>");
     166    DECLARE_PRFH_STRING(WPOBJID_TEMPS, "<WP_TEMPS>");
     167    DECLARE_PRFH_STRING(WPOBJID_DRIVES, "<WP_DRIVES>");
     168
     169    /* ******************************************************************
     170     *
     171     *   Functions
     172     *
     173     ********************************************************************/
    49174
    50175    APIRET prfhQueryKeysForApp(HINI hIni,
     
    75200    LONG prfhQueryColor(const char *pcszKeyName, const char *pcszDefault);
    76201
    77     /*
    78      *@@ COUNTRYSETTINGS:
    79      *      structure used for returning country settings
    80      *      with prfhQueryCountrySettings.
    81      */
    82 
    83     typedef struct _COUNTRYSETTINGS
    84     {
    85         ULONG   ulDateFormat,
    86                         // date format:
    87                         // --  0   mm.dd.yyyy  (English)
    88                         // --  1   dd.mm.yyyy  (e.g. German)
    89                         // --  2   yyyy.mm.dd  (Japanese)
    90                         // --  3   yyyy.dd.mm
    91                 ulTimeFormat;
    92                         // time format:
    93                         // --  0   12-hour clock
    94                         // --  >0  24-hour clock
    95         CHAR    cDateSep,
    96                         // date separator (e.g. '/')
    97                 cTimeSep,
    98                         // time separator (e.g. ':')
    99                 cDecimal,
    100                         // decimal separator (e.g. '.')
    101                 cThousands;
    102                         // thousands separator (e.g. ',')
    103     } COUNTRYSETTINGS, *PCOUNTRYSETTINGS;
    104 
    105     VOID prfhQueryCountrySettings(PCOUNTRYSETTINGS pcs);
    106 
    107202    APIRET prfhCopyKey(HINI hiniSource,
    108203                       const char *pcszSourceApp,
  • trunk/include/helpers/stringh.h

    r104 r108  
    9191    ULONG strhWords(PSZ psz);
    9292
    93     PSZ APIENTRY strhThousandsULong(PSZ pszTarget, ULONG ul, CHAR cThousands);
    94     typedef PSZ APIENTRY STRHTHOUSANDSULONG(PSZ pszTarget, ULONG ul, CHAR cThousands);
    95     typedef STRHTHOUSANDSULONG *PSTRHTHOUSANDSULONG;
    96 
    97     PSZ strhThousandsDouble(PSZ pszTarget, double dbl, CHAR cThousands);
    98 
    99     PSZ strhVariableDouble(PSZ pszTarget, double dbl, PSZ pszUnits,
    100                            CHAR cThousands);
    101 
    102     VOID strhFileDate(PSZ pszBuf,
    103                       FDATE *pfDate,
    104                       ULONG ulDateFormat,
    105                       CHAR cDateSep);
    106 
    107     VOID strhFileTime(PSZ pszBuf,
    108                       FTIME *pfTime,
    109                       ULONG ulTimeFormat,
    110                       CHAR cTimeSep);
    111 
    112     VOID APIENTRY strhDateTime(PSZ pszDate,
    113                                PSZ pszTime,
    114                                DATETIME *pDateTime,
    115                                ULONG ulDateFormat,
    116                                CHAR cDateSep,
    117                                ULONG ulTimeFormat,
    118                                CHAR cTimeSep);
    119     typedef VOID APIENTRY STRHDATETIME(PSZ pszDate,
    120                                PSZ pszTime,
    121                                DATETIME *pDateTime,
    122                                ULONG ulDateFormat,
    123                                CHAR cDateSep,
    124                                ULONG ulTimeFormat,
    125                                CHAR cTimeSep);
    126     typedef STRHDATETIME *PSTRHDATETIME;
    127 
    12893    #define STRH_BEGIN_CHARS    "\x0d\x0a "
    12994    #define STRH_END_CHARS      "\x0d\x0a /-"
  • trunk/include/helpers/tmsgfile.h

    r102 r108  
    2020    #define TMSGFILE_HEADER_INCLUDED
    2121
    22     APIRET tmfGetMessage(PCHAR *pTable,
     22    #ifndef XSTRING_HEADER_INCLUDED
     23        #error tmsgfile.h requires xstring.h to be included first.
     24    #endif
     25
     26    #ifndef XWPTREE_INCLUDED
     27        #error tmsgfile.h requires tree.h to be included first.
     28    #endif
     29
     30    /*
     31     *@@ TMFMSGFILE:
     32     *
     33     *@@added V0.9.16 (2001-10-08) [umoeller]
     34     */
     35
     36    typedef struct _TMFMSGFILE
     37    {
     38        PSZ     pszFilename;            // copy of .TMF file name
     39
     40        XSTRING strContent;             // file's full contents (converted to C LF format)
     41
     42        TREE    *IDsTreeRoot;           // root of tree with MSGENTRY's (a TREE* really)
     43        ULONG   cIDs;                   // count of entries in the tree
     44    } TMFMSGFILE, *PTMFMSGFILE;
     45
     46    APIRET tmfOpenMessageFile(const char *pcszMessageFile,
     47                              PTMFMSGFILE *ppMsgFile);
     48
     49    APIRET tmfCloseMessageFile(PTMFMSGFILE *ppMsgFile);
     50
     51    APIRET tmfGetMessage(PTMFMSGFILE pMsgFile,
     52                         PCSZ pcszMessageName,
     53                         PXSTRING pstr,
     54                         PSZ *pTable,
     55                         ULONG cTableEntries);
     56
     57    /* APIRET tmfGetMessage(PCHAR *pTable,
    2358                         ULONG cTable,
    2459                         PBYTE pbBuffer,
     
    3570                            PCSZ pszFile,
    3671                            PULONG pcbMsg);
     72       */
    3773
    3874#endif // TMSGFILE_HEADER_INCLUDED
  • trunk/include/helpers/tree.h

    r106 r108  
    1010#endif
    1111
    12 #ifndef SFLTREE_INCLUDED               //  Allow multiple inclusions
    13     #define SFLTREE_INCLUDED
     12#ifndef XWPTREE_INCLUDED               //  Allow multiple inclusions
     13    #define XWPTREE_INCLUDED
    1414
    1515    #if (!defined OS2_INCLUDED) && (!defined _OS2_H) && (!defined __SIMPLES_DEFINED)   // changed V0.9.0 (99-10-22) [umoeller]
  • trunk/include/helpers/winh.h

    r106 r108  
    101101        #define WinQueryWindowPtr(a,b) winhQueryWindowPtr((a),(b))
    102102
    103         BOOL XWPENTRY winhSetWindowText(HWND hwnd, const char *pcsz);
    104         #define WinSetWindowText(a,b) winhSetWindowText((a),(b))
     103        BOOL XWPENTRY winhSetWindowText2(HWND hwnd, const char *pcsz);
     104        #define WinSetWindowText(a,b) winhSetWindowText2((a),(b))
    105105
    106106        BOOL XWPENTRY winhSetDlgItemText(HWND hwnd, ULONG id, const char *pcsz);
     
    758758    PSZ XWPENTRY winhQueryWindowText(HWND hwnd);
    759759
     760    BOOL XWPENTRY winhSetWindowText(HWND hwnd,
     761                                    const char *pcszFormat,
     762                                    ...);
     763
    760764    /*
    761765     *@@ winhQueryDlgItemText:
  • trunk/include/helpers/wphandle.h

    r106 r108  
    5151    #define ERROR_WPH_CORRUPT_HANDLES_DATA          (ERROR_WPH_FIRST +   5)
    5252    #define ERROR_WPH_INVALID_PARENT_HANDLE         (ERROR_WPH_FIRST +   6)
    53 
    54     /* ******************************************************************
    55      *
    56      *   Strings
    57      *
    58      ********************************************************************/
    59 
    60     // DECLARE_WPH_STRING is a handy macro which saves us from
    61     // keeping two string lists in both the .h and the .c file.
    62     // If this include file is included from the .c file, the
    63     // string is defined as a global variable. Otherwise
    64     // it is only declared as "extern" so other files can
    65     // see it.
    66 
    67     #ifdef INCLUDE_WPHANDLE_PRIVATE
    68         #define DECLARE_WPH_STRING(str, def) const char *str = def
    69     #else
    70         #define DECLARE_WPH_STRING(str, def) extern const char *str;
    71     #endif
    72 
    73     /*
    74      * OS2.INI applications
    75      *
    76      */
    77 
    78     // abstract objects per folder handle
    79     DECLARE_WPH_STRING(WPINIAPP_FDRCONTENT, "PM_Abstract:FldrContent");
    80     // all defined abstract objects on the system
    81     DECLARE_WPH_STRING(WPINIAPP_OBJECTS, "PM_Abstract:Objects");
    82     // their icons, if set individually
    83     DECLARE_WPH_STRING(WPINIAPP_ICONS, "PM_Abstract:Icons");
    84 
    85     // object ID's (<WP_DESKTOP> etc.)
    86     DECLARE_WPH_STRING(WPINIAPP_LOCATION, "PM_Workplace:Location");
    87 
    88     // folder positions
    89     DECLARE_WPH_STRING(WPINIAPP_FOLDERPOS, "PM_Workplace:FolderPos");
    90 
    91     // palette positions
    92     DECLARE_WPH_STRING(WPINIAPP_PALETTEPOS, "PM_Workplace:PalettePos");
    93     // ???
    94     DECLARE_WPH_STRING(WPINIAPP_STATUSPOS, "PM_Workplace:StatusPos");
    95     // startup folders
    96     DECLARE_WPH_STRING(WPINIAPP_STARTUP, "PM_Workplace:Startup");
    97     // all the defined templates on the system
    98     DECLARE_WPH_STRING(WPINIAPP_TEMPLATES, "PM_Workplace:Templates");
    99 
    100     // all work area folders
    101     DECLARE_WPH_STRING(WPINIAPP_WORKAREARUNNING, "FolderWorkareaRunningObjects");
    102     // spooler windows ?!?
    103     DECLARE_WPH_STRING(WPINIAPP_JOBCNRPOS, "PM_PrintObject:JobCnrPos");
    104 
    105     // associations by type ("Plain Text")
    106     DECLARE_WPH_STRING(WPINIAPP_ASSOCTYPE, "PMWP_ASSOC_TYPE");
    107     // associations by filter ("*.txt")
    108     DECLARE_WPH_STRING(WPINIAPP_ASSOCFILTER, "PMWP_ASSOC_FILTER");
    109     // checksums ?!?
    110     DECLARE_WPH_STRING(WPINIAPP_ASSOC_CHECKSUM, "PMWP_ASSOC_CHECKSUM");
    111 
    112     /*
    113      * OS2SYS.INI applications
    114      *
    115      */
    116 
    117     DECLARE_WPH_STRING(WPINIAPP_ACTIVEHANDLES, "PM_Workplace:ActiveHandles");
    118     DECLARE_WPH_STRING(WPINIAPP_HANDLES, "PM_Workplace:Handles");
    119     DECLARE_WPH_STRING(WPINIAPP_HANDLESAPP, "HandlesAppName");
    120 
    121     /*
    122      * some default WPS INI keys:
    123      *
    124      */
    125 
    126     DECLARE_WPH_STRING(WPOBJID_DESKTOP, "<WP_DESKTOP>");
    127 
    128     DECLARE_WPH_STRING(WPOBJID_KEYB, "<WP_KEYB>");
    129     DECLARE_WPH_STRING(WPOBJID_MOUSE, "<WP_MOUSE>");
    130     DECLARE_WPH_STRING(WPOBJID_CNTRY, "<WP_CNTRY>");
    131     DECLARE_WPH_STRING(WPOBJID_SOUND, "<WP_SOUND>");
    132     DECLARE_WPH_STRING(WPOBJID_SYSTEM, "<WP_SYSTEM>"); // V0.9.9
    133     DECLARE_WPH_STRING(WPOBJID_POWER, "<WP_POWER>");
    134     DECLARE_WPH_STRING(WPOBJID_WINCFG, "<WP_WINCFG>");
    135 
    136     DECLARE_WPH_STRING(WPOBJID_HIRESCLRPAL, "<WP_HIRESCLRPAL>");
    137     DECLARE_WPH_STRING(WPOBJID_LORESCLRPAL, "<WP_LORESCLRPAL>");
    138     DECLARE_WPH_STRING(WPOBJID_FNTPAL, "<WP_FNTPAL>");
    139     DECLARE_WPH_STRING(WPOBJID_SCHPAL96, "<WP_SCHPAL96>");
    140 
    141     DECLARE_WPH_STRING(WPOBJID_LAUNCHPAD, "<WP_LAUNCHPAD>");
    142     DECLARE_WPH_STRING(WPOBJID_WARPCENTER, "<WP_WARPCENTER>");
    143 
    144     DECLARE_WPH_STRING(WPOBJID_SPOOL, "<WP_SPOOL>");
    145     DECLARE_WPH_STRING(WPOBJID_VIEWER, "<WP_VIEWER>");
    146     DECLARE_WPH_STRING(WPOBJID_SHRED, "<WP_SHRED>");
    147     DECLARE_WPH_STRING(WPOBJID_CLOCK, "<WP_CLOCK>");
    148 
    149     DECLARE_WPH_STRING(WPOBJID_START, "<WP_START>");
    150     DECLARE_WPH_STRING(WPOBJID_TEMPS, "<WP_TEMPS>");
    151     DECLARE_WPH_STRING(WPOBJID_DRIVES, "<WP_DRIVES>");
    15253
    15354    /* ******************************************************************
  • trunk/include/helpers/xstring.h

    r91 r108  
    103103    typedef XSTRRESERVE *PXSTRRESERVE;
    104104
     105    void XWPENTRY xstrShrink(PXSTRING pxstr);
     106    typedef void XWPENTRY XSTRSHRINK(PXSTRING pxstr);
     107    typedef XSTRSHRINK *PXSTRSHRINK;
     108
    105109    PXSTRING XWPENTRY xstrCreate(ULONG ulPreAllocate);
    106110    typedef PXSTRING XWPENTRY XSTRCREATE(ULONG ulPreAllocate);
  • trunk/src/helpers/apps.c

    r105 r108  
    476476/* ******************************************************************
    477477 *
    478  *   Application start
     478 *   Application information
    479479 *
    480480 ********************************************************************/
    481 
    482 /*
    483  *@@ CallBatchCorrectly:
    484  *      fixes the specified PROGDETAILS for
    485  *      command files in the executable part
    486  *      by inserting /C XXX into the parameters
    487  *      and setting the executable according
    488  *      to an environment variable.
    489  *
    490  *@@added V0.9.6 (2000-10-16) [umoeller]
    491  *@@changed V0.9.7 (2001-01-15) [umoeller]: now using XSTRING
    492  *@@changed V0.9.12 (2001-05-27) [umoeller]: moved from winh.c to apps.c
    493  */
    494 
    495 VOID CallBatchCorrectly(PPROGDETAILS pProgDetails,
    496                         PXSTRING pstrParams,        // in/out: modified parameters (reallocated)
    497                         const char *pcszEnvVar,     // in: env var spec'g command proc
    498                                                     // (e.g. "OS2_SHELL"); can be NULL
    499                         const char *pcszDefProc)    // in: def't command proc (e.g. "CMD.EXE")
    500 {
    501     // XXX.CMD file as executable:
    502     // fix args to /C XXX.CMD
    503 
    504     PSZ     pszOldParams = NULL;
    505     ULONG   ulOldParamsLength = pstrParams->ulLength;
    506     if (ulOldParamsLength)
    507         // we have parameters already:
    508         // make a backup... we'll append that later
    509         pszOldParams = strdup(pstrParams->psz);
    510 
    511     // set new params to "/C filename.cmd"
    512     xstrcpy(pstrParams, "/C ", 0);
    513     xstrcat(pstrParams,
    514             pProgDetails->pszExecutable,
    515             0);
    516 
    517     if (pszOldParams)
    518     {
    519         // .cmd had params:
    520         // append space and old params
    521         xstrcatc(pstrParams, ' ');
    522         xstrcat(pstrParams,
    523                 pszOldParams,
    524                 ulOldParamsLength);
    525         free(pszOldParams);
    526     }
    527 
    528     // set executable to $(OS2_SHELL)
    529     pProgDetails->pszExecutable = NULL;
    530     if (pcszEnvVar)
    531         pProgDetails->pszExecutable = getenv(pcszEnvVar);
    532     if (!pProgDetails->pszExecutable)
    533         pProgDetails->pszExecutable = (PSZ)pcszDefProc;
    534                 // should be on PATH
    535 }
    536481
    537482/*
     
    557502 *      --  PROG_VDD
    558503 *
    559  *      --  PROG_XWP_DLL: new apptype defined in winh.h for
    560  *          dynamic link libraries.
     504 *      --  PROG_DLL
    561505 *
    562506 *      --  PROG_WINDOWEDVDM
     
    590534        else if ((_ulDosAppType & 0xF0) == FAPPTYP_DLL) // 0x10)
    591535            // DLL bit set
    592             *pulWinAppType = PROG_XWP_DLL;
     536            *pulWinAppType = PROG_DLL;
    593537        else if (_ulDosAppType & FAPPTYP_DOS)           // 0x20)
    594538            // DOS bit set?
     
    611555
    612556/*
     557 *@@ appDescribeAppType:
     558 *      returns a "PROG_*" string for the given
     559 *      program type. Useful for WPProgram setup
     560 *      strings and such.
     561 *
     562 *@@added V0.9.16 (2001-10-06)
     563 */
     564
     565PCSZ appDescribeAppType(PROGCATEGORY progc)        // in: from PROGDETAILS.progc
     566{
     567    switch (progc)
     568    {
     569        case PROG_DEFAULT: return "PROG_DEFAULT";
     570        case PROG_FULLSCREEN: return "PROG_FULLSCREEN";
     571        case PROG_WINDOWABLEVIO: return "PROG_WINDOWABLEVIO";
     572        case PROG_PM: return "PROG_PM";
     573        case PROG_GROUP: return "PROG_GROUP";
     574        case PROG_VDM: return "PROG_VDM";
     575            // same as case PROG_REAL: return "PROG_REAL";
     576        case PROG_WINDOWEDVDM: return "PROG_WINDOWEDVDM";
     577        case PROG_DLL: return "PROG_DLL";
     578        case PROG_PDD: return "PROG_PDD";
     579        case PROG_VDD: return "PROG_VDD";
     580        case PROG_WINDOW_REAL: return "PROG_WINDOW_REAL";
     581        case PROG_30_STD: return "PROG_30_STD";
     582            // same as case PROG_WINDOW_PROT: return "PROG_WINDOW_PROT";
     583        case PROG_WINDOW_AUTO: return "PROG_WINDOW_AUTO";
     584        case PROG_30_STDSEAMLESSVDM: return "PROG_30_STDSEAMLESSVDM";
     585            // same as case PROG_SEAMLESSVDM: return "PROG_SEAMLESSVDM";
     586        case PROG_30_STDSEAMLESSCOMMON: return "PROG_30_STDSEAMLESSCOMMON";
     587            // same as case PROG_SEAMLESSCOMMON: return "PROG_SEAMLESSCOMMON";
     588        case PROG_31_STDSEAMLESSVDM: return "PROG_31_STDSEAMLESSVDM";
     589        case PROG_31_STDSEAMLESSCOMMON: return "PROG_31_STDSEAMLESSCOMMON";
     590        case PROG_31_ENHSEAMLESSVDM: return "PROG_31_ENHSEAMLESSVDM";
     591        case PROG_31_ENHSEAMLESSCOMMON: return "PROG_31_ENHSEAMLESSCOMMON";
     592        case PROG_31_ENH: return "PROG_31_ENH";
     593        case PROG_31_STD: return "PROG_31_STD";
     594
     595// Warp 4 toolkit defines, whatever these were designed for...
     596#ifndef PROG_DOS_GAME
     597    #define PROG_DOS_GAME            (PROGCATEGORY)21
     598#endif
     599#ifndef PROG_WIN_GAME
     600    #define PROG_WIN_GAME            (PROGCATEGORY)22
     601#endif
     602#ifndef PROG_DOS_MODE
     603    #define PROG_DOS_MODE            (PROGCATEGORY)23
     604#endif
     605
     606        case PROG_DOS_GAME: return "PROG_DOS_GAME";
     607        case PROG_WIN_GAME: return "PROG_WIN_GAME";
     608        case PROG_DOS_MODE: return "PROG_DOS_MODE";
     609    }
     610
     611    return NULL;
     612}
     613
     614/*
    613615 *@@ appIsWindowsApp:
    614616 *      checks the specified program category
     
    657659
    658660    return (0);
     661}
     662
     663/* ******************************************************************
     664 *
     665 *   Application start
     666 *
     667 ********************************************************************/
     668
     669/*
     670 *@@ CallBatchCorrectly:
     671 *      fixes the specified PROGDETAILS for
     672 *      command files in the executable part
     673 *      by inserting /C XXX into the parameters
     674 *      and setting the executable according
     675 *      to an environment variable.
     676 *
     677 *@@added V0.9.6 (2000-10-16) [umoeller]
     678 *@@changed V0.9.7 (2001-01-15) [umoeller]: now using XSTRING
     679 *@@changed V0.9.12 (2001-05-27) [umoeller]: moved from winh.c to apps.c
     680 */
     681
     682VOID CallBatchCorrectly(PPROGDETAILS pProgDetails,
     683                        PXSTRING pstrParams,        // in/out: modified parameters (reallocated)
     684                        const char *pcszEnvVar,     // in: env var spec'g command proc
     685                                                    // (e.g. "OS2_SHELL"); can be NULL
     686                        const char *pcszDefProc)    // in: def't command proc (e.g. "CMD.EXE")
     687{
     688    // XXX.CMD file as executable:
     689    // fix args to /C XXX.CMD
     690
     691    PSZ     pszOldParams = NULL;
     692    ULONG   ulOldParamsLength = pstrParams->ulLength;
     693    if (ulOldParamsLength)
     694        // we have parameters already:
     695        // make a backup... we'll append that later
     696        pszOldParams = strdup(pstrParams->psz);
     697
     698    // set new params to "/C filename.cmd"
     699    xstrcpy(pstrParams, "/C ", 0);
     700    xstrcat(pstrParams,
     701            pProgDetails->pszExecutable,
     702            0);
     703
     704    if (pszOldParams)
     705    {
     706        // .cmd had params:
     707        // append space and old params
     708        xstrcatc(pstrParams, ' ');
     709        xstrcat(pstrParams,
     710                pszOldParams,
     711                ulOldParamsLength);
     712        free(pszOldParams);
     713    }
     714
     715    // set executable to $(OS2_SHELL)
     716    pProgDetails->pszExecutable = NULL;
     717    if (pcszEnvVar)
     718        pProgDetails->pszExecutable = getenv(pcszEnvVar);
     719    if (!pProgDetails->pszExecutable)
     720        pProgDetails->pszExecutable = (PSZ)pcszDefProc;
     721                // should be on PATH
    659722}
    660723
  • trunk/src/helpers/datetime.c

    r90 r108  
    147147
    148148int dtCreateFileTimeStamp(PSZ pszTimeStamp,      // out: time stamp
    149                             FDATE* pfdate,         // in: date
    150                             FTIME* pftime)         // in: time
     149                          FDATE* pfdate,         // in: date
     150                          FTIME* pftime)         // in: time
    151151{
    152152    return (sprintf(pszTimeStamp,
     
    230230 *      returns TRUE if yr is a leap year.
    231231 *
    232  *      (c) Ray Gardner.
     232 *      (c) Ray Gardner. Public domain.
    233233 */
    234234
     
    260260 *      you then get 63.
    261261 *
    262  *      (c) Ray Gardner.
     262 *      (c) Ray Gardner. Public domain.
    263263 */
    264264
     
    272272 *      converts a year to the no. of days passed.
    273273 *
    274  *      (c) Ray Gardner.
     274 *      (c) Ray Gardner. Public domain.
    275275 */
    276276
     
    288288 *      the given date.
    289289 *
    290  *      (c) Ray Gardner.
     290 *      (c) Ray Gardner. Public domain.
    291291 */
    292292
     
    308308 *
    309309 *
    310  *      (c) Ray Gardner.
     310 *      (c) Ray Gardner. Public domain.
    311311 */
    312312
  • trunk/src/helpers/dialog.c

    r106 r108  
    227227
    228228/*
    229  *@@ CalcAutoSizeText:
    230  *
    231  *@@changed V0.9.12 (2001-05-31) [umoeller]: fixed various things with statics
    232  *@@changed V0.9.12 (2001-05-31) [umoeller]: fixed broken fonts
    233  *@@changed V0.9.14 (2001-08-01) [umoeller]: now caching fonts, which is significantly faster
    234  */
    235 
    236 VOID CalcAutoSizeText(PCONTROLDEF pControlDef,
    237                       BOOL fMultiLine,          // in: if TRUE, multiple lines
    238                       PSIZEL pszlAuto,          // out: computed size
    239                       PDLGPRIVATE pDlgData)
    240 {
     229 *@@ SetDlgFont:
     230 *
     231 *@@added V0.9.16 (2001-10-11) [umoeller]
     232 */
     233
     234VOID SetDlgFont(PCONTROLDEF pControlDef,
     235                PDLGPRIVATE pDlgData)
     236{
     237    LONG lPointSize = 0;
    241238    const char *pcszFontThis = pControlDef->pcszFont;
    242239                    // can be NULL,
     
    249246        pDlgData->hps = WinGetPS(pDlgData->hwndDlg);
    250247
    251     if (pcszFontThis)
    252     {
    253         LONG lPointSize = 0;
    254 
    255         // check if we can reuse font data from last time
    256         // V0.9.14 (2001-08-01) [umoeller]
    257         if (strhcmp(pcszFontThis,
    258                     pDlgData->pcszFontLast))
    259         {
    260             // different font than last time:
    261 
    262             // delete old font?
    263             if (pDlgData->lcidLast)
    264             {
    265                 GpiSetCharSet(pDlgData->hps, LCID_DEFAULT);
    266                 GpiDeleteSetId(pDlgData->hps, pDlgData->lcidLast);
    267             }
    268 
     248    // check if we can reuse font data from last time
     249    // V0.9.14 (2001-08-01) [umoeller]
     250    if (strhcmp(pcszFontThis,               // can be NULL!
     251                pDlgData->pcszFontLast))
     252    {
     253        // different font than last time:
     254
     255        // delete old font?
     256        if (pDlgData->lcidLast)
     257        {
     258            GpiSetCharSet(pDlgData->hps, LCID_DEFAULT);     // LCID_DEFAULT == 0
     259            GpiDeleteSetId(pDlgData->hps, pDlgData->lcidLast);
     260        }
     261
     262        if (pcszFontThis)
     263        {
    269264            // create new font
    270265            pDlgData->lcidLast = gpihFindPresFont(NULLHANDLE,        // no window yet
     
    278273            if (pDlgData->fmLast.fsDefn & FM_DEFN_OUTLINE)
    279274                gpihSetPointSize(pDlgData->hps, lPointSize);
    280 
    281             pDlgData->pcszFontLast = pcszFontThis;
    282         }
    283 
    284         pszlAuto->cy =   pDlgData->fmLast.lMaxBaselineExt
    285                        + pDlgData->fmLast.lExternalLeading;
    286     }
     275        }
     276        else
     277        {
     278            // use default font:
     279            // @@todo handle presparams, maybe inherited?
     280            GpiSetCharSet(pDlgData->hps, LCID_DEFAULT);
     281            GpiQueryFontMetrics(pDlgData->hps,
     282                                sizeof(pDlgData->fmLast),
     283                                &pDlgData->fmLast);
     284        }
     285
     286        pDlgData->pcszFontLast = pcszFontThis;      // can be NULL
     287    }
     288}
     289
     290/*
     291 *@@ CalcAutoSizeText:
     292 *
     293 *@@changed V0.9.12 (2001-05-31) [umoeller]: fixed various things with statics
     294 *@@changed V0.9.12 (2001-05-31) [umoeller]: fixed broken fonts
     295 *@@changed V0.9.14 (2001-08-01) [umoeller]: now caching fonts, which is significantly faster
     296 */
     297
     298VOID CalcAutoSizeText(PCONTROLDEF pControlDef,
     299                      BOOL fMultiLine,          // in: if TRUE, multiple lines
     300                      PSIZEL pszlAuto,          // out: computed size
     301                      PDLGPRIVATE pDlgData)
     302{
     303    SetDlgFont(pControlDef, pDlgData);
     304
     305    pszlAuto->cy =   pDlgData->fmLast.lMaxBaselineExt
     306                   + pDlgData->fmLast.lExternalLeading;
    287307
    288308    // ok, we FINALLY have a font now...
     
    396416            }
    397417        break;
     418
     419        default:
     420            // any other control (just to be safe):
     421            SetDlgFont(pControlDef, pDlgData);
     422            pszlAuto->cx = 50;
     423            pszlAuto->cy =   pDlgData->fmLast.lMaxBaselineExt
     424                           + pDlgData->fmLast.lExternalLeading
     425                           + 5;         // some space
    398426    }
    399427}
     
    566594    LHANDLE     lHandleSet = NULLHANDLE;
    567595    ULONG       flOld = 0;
     596
     597    LONG        y, cy;              // for combo box hacks
    568598
    569599    if (pColumnDef->fIsNestedTable)
     
    588618                pcszTitle = pControlDef->pcszText;
    589619                flStyle = pControlDef->flStyle;
     620
     621                y = pcp->y + pDlgData->ptlTotalOfs.y;
     622                cy = pcp->cy;
    590623            }
    591624        }
     
    598631        pcszTitle = pControlDef->pcszText;
    599632        flStyle = pControlDef->flStyle;
     633
     634        y = pcp->y + pDlgData->ptlTotalOfs.y;
     635        cy = pcp->cy;
    600636
    601637        // change the title if this is a static with SS_BITMAP;
     
    613649            pcszTitle = "";
    614650            lHandleSet = (LHANDLE)pControlDef->pcszText;
     651        }
     652        // hack the stupid drop-down combobox which doesn't
     653        // expand otherwise (the size of the drop-down is
     654        // the full size of the control... duh)
     655        else if (    ((ULONG)pControlDef->pcszClass == 0xffff0002L)
     656                  && (flStyle & (CBS_DROPDOWN | CBS_DROPDOWNLIST))
     657                )
     658        {
     659            y -= 100;
     660            cy += 100;
    615661        }
    616662    }
     
    640686                              flStyle,      // hacked
    641687                              pcp->x + pDlgData->ptlTotalOfs.x,
    642                               pcp->y + pDlgData->ptlTotalOfs.y,
     688                              y,
    643689                              pcp->cx,
    644                               pcp->cy,
     690                              cy,
    645691                              pDlgData->hwndDlg,   // owner
    646692                              HWND_BOTTOM,
  • trunk/src/helpers/dosh.c

    r105 r108  
    6969#pragma hdrstop
    7070
    71 static const CHAR  G_acDriveLetters[28] = " ABCDEFGHIJKLMNOPQRSTUVWXYZ";
     71// static const CHAR  G_acDriveLetters[28] = " ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    7272
    7373/*
     
    703703            PFSQBUFFER2 pfsqBuffer = (PFSQBUFFER2)fsqBuffer;
    704704
    705             szName[0] = G_acDriveLetters[ulLogicalDrive];
     705            szName[0] = ulLogicalDrive + 'A' - 1;
    706706            szName[1] = ':';
    707707            szName[2] = '\0';
     
    753753                    &ulBootDrive,
    754754                    sizeof(ulBootDrive));
    755     return (G_acDriveLetters[ulBootDrive]);
     755    return (ulBootDrive + 'A' - 1);
    756756}
    757757
     
    10341034 *@@changed V0.9.1 (99-12-12) [umoeller]: added cbBuf to prototype
    10351035 *@@changed V0.9.14 (2001-08-01) [umoeller]: fixed, this never respected cbBuf
     1036 *@@changed V0.9.16 (2001-10-02) [umoeller]: added check for valid logical disk no
    10361037 */
    10371038
     
    10481049
    10491050    // compose "D:"-type string from logical drive letter
    1050     szName[0] = G_acDriveLetters[ulLogicalDrive];
    1051     szName[1] = ':';
    1052     szName[2] = '\0';
    1053 
    1054     arc = DosQueryFSAttach(szName,          // logical drive of attached FS ("D:"-style)
    1055                            0,               // ulOrdinal, ignored for FSAIL_QUERYNAME
    1056                            FSAIL_QUERYNAME, // return name for a drive or device
    1057                            pfsqBuffer,      // buffer for returned data
    1058                            &cbBuffer);      // sizeof(*pfsqBuffer)
    1059 
    1060     if (arc == NO_ERROR)
    1061     {
    1062         if (pszBuf)
     1051    if (ulLogicalDrive > 0 && ulLogicalDrive < 27)
     1052    {
     1053        szName[0] = ulLogicalDrive + 'A' - 1;
     1054        szName[1] = ':';
     1055        szName[2] = '\0';
     1056
     1057        arc = DosQueryFSAttach(szName,          // logical drive of attached FS ("D:"-style)
     1058                               0,               // ulOrdinal, ignored for FSAIL_QUERYNAME
     1059                               FSAIL_QUERYNAME, // return name for a drive or device
     1060                               pfsqBuffer,      // buffer for returned data
     1061                               &cbBuffer);      // sizeof(*pfsqBuffer)
     1062
     1063        if (arc == NO_ERROR)
    10631064        {
    1064             // The data for the last three fields in the FSQBUFFER2
    1065             // structure are stored at the offset of fsqBuffer.szName.
    1066             // Each data field following fsqBuffer.szName begins
    1067             // immediately after the previous item.
    1068             strncpy(pszBuf,
    1069                     (CHAR*)(&pfsqBuffer->szName) + pfsqBuffer->cbName + 1,
    1070                     cbBuf);         // V0.9.14 (2001-08-01) [umoeller]
    1071             *(pszBuf + cbBuf) = '\0';
     1065            if (pszBuf)
     1066            {
     1067                // The data for the last three fields in the FSQBUFFER2
     1068                // structure are stored at the offset of fsqBuffer.szName.
     1069                // Each data field following fsqBuffer.szName begins
     1070                // immediately after the previous item.
     1071                strncpy(pszBuf,
     1072                        (CHAR*)(&pfsqBuffer->szName) + pfsqBuffer->cbName + 1,
     1073                        cbBuf);         // V0.9.14 (2001-08-01) [umoeller]
     1074                *(pszBuf + cbBuf) = '\0';
     1075            }
    10721076        }
    10731077    }
     1078    else
     1079        arc = ERROR_INVALID_PARAMETER; // V0.9.16 (2001-10-02) [umoeller]
    10741080
    10751081    return (arc);
     
    18831889        ULONG   cbWritten;
    18841890        DosGetDateTime(&dt);
    1885         sprintf(szTemp, "Time: %02d:%02d:%02d %s",
    1886             dt.hours, dt.minutes, dt.seconds,
    1887             pcsz);
     1891        sprintf(szTemp,
     1892                "Time: %02d:%02d:%02d %s",
     1893                dt.hours, dt.minutes, dt.seconds,
     1894                pcsz);
    18881895        return (DosWrite(hfLog, (PVOID)szTemp, strlen(szTemp), &cbWritten));
    18891896    }
     
    20002007    ULONG   ulCurDisk = 0;
    20012008    ULONG   ulMap = 0;
    2002     arc = DosQueryCurrentDisk(&ulCurDisk, &ulMap);
    2003     if (arc == NO_ERROR)
     2009    if (!(arc = DosQueryCurrentDisk(&ulCurDisk, &ulMap)))
    20042010    {
    20052011        ULONG   cbBuf = CCHMAXPATH - 3;
    2006         *pszBuf = G_acDriveLetters[ulCurDisk];
     2012        *pszBuf = ulCurDisk + 'A' - 1;
    20072013        *(pszBuf + 1) = ':';
    20082014        *(pszBuf + 2) = '\\';
     
    22702276
    22712277        // resolve DosPerfSysCall API entry
    2272         arc = DosLoadModule(NULL, 0, "DOSCALLS", &pPerfSys->hmod);
    2273         if (arc == NO_ERROR)
     2278        if (!(arc = DosLoadModule(NULL, 0, "DOSCALLS", &pPerfSys->hmod)))
    22742279        {
    2275             arc = DosQueryProcAddr(pPerfSys->hmod,
    2276                                    976,
    2277                                    "DosPerfSysCall",
    2278                                    (PFN*)(&pPerfSys->pDosPerfSysCall));
    2279             if (arc == NO_ERROR)
     2280            if (!(arc = DosQueryProcAddr(pPerfSys->hmod,
     2281                                         976,
     2282                                         "DosPerfSysCall",
     2283                                         (PFN*)(&pPerfSys->pDosPerfSysCall))))
    22802284            {
    22812285                // OK, we got the API: initialize!
    2282                 arc = pPerfSys->pDosPerfSysCall(CMD_KI_ENABLE, 0, 0, 0);
    2283                 if (arc == NO_ERROR)
     2286                if (!(arc = pPerfSys->pDosPerfSysCall(CMD_KI_ENABLE, 0, 0, 0)))
    22842287                {
    22852288                    pPerfSys->fInitialized = TRUE;
    22862289                            // call CMD_KI_DISABLE later
    22872290
    2288                     arc = pPerfSys->pDosPerfSysCall(CMD_PERF_INFO,
    2289                                                     0,
    2290                                                     (ULONG)(&pPerfSys->cProcessors),
    2291                                                     0);
    2292                     if (arc == NO_ERROR)
     2291                    if (!(arc = pPerfSys->pDosPerfSysCall(CMD_PERF_INFO,
     2292                                                          0,
     2293                                                          (ULONG)(&pPerfSys->cProcessors),
     2294                                                          0)))
    22932295                    {
    2294                         ULONG   ul = 0;
     2296                        ULONG   ul = 0,
     2297                                cProcs = pPerfSys->cProcessors,
     2298                                cbDouble = cProcs * sizeof(double),
     2299                                cbLong = cProcs * sizeof(LONG);
    22952300
    22962301                        // allocate arrays
    2297                         pPerfSys->paCPUUtils = (PCPUUTIL)calloc(pPerfSys->cProcessors,
    2298                                                                 sizeof(CPUUTIL));
    2299                         if (!pPerfSys->paCPUUtils)
     2302                        if (    (!(pPerfSys->paCPUUtils = (PCPUUTIL)calloc(cProcs,
     2303                                                                sizeof(CPUUTIL))))
     2304                             || (!(pPerfSys->padBusyPrev
     2305                                    = (double*)malloc(cbDouble)))
     2306                             || (!(pPerfSys->padTimePrev
     2307                                    = (double*)malloc(cbDouble)))
     2308                             || (!(pPerfSys->padIntrPrev
     2309                                    = (double*)malloc(cbDouble)))
     2310                             || (!(pPerfSys->palLoads
     2311                                    = (PLONG)malloc(cbLong)))
     2312                             || (!(pPerfSys->palIntrs
     2313                                    = (PLONG)malloc(cbLong)))
     2314                           )
    23002315                            arc = ERROR_NOT_ENOUGH_MEMORY;
    23012316                        else
    23022317                        {
    2303                             pPerfSys->padBusyPrev = (double*)malloc(pPerfSys->cProcessors * sizeof(double));
    2304                             if (!pPerfSys->padBusyPrev)
    2305                                 arc = ERROR_NOT_ENOUGH_MEMORY;
    2306                             else
     2318                            for (ul = 0; ul < cProcs; ul++)
    23072319                            {
    2308                                 pPerfSys->padTimePrev
    2309                                     = (double*)malloc(pPerfSys->cProcessors * sizeof(double));
    2310                                 if (!pPerfSys->padTimePrev)
    2311                                     arc = ERROR_NOT_ENOUGH_MEMORY;
    2312                                 else
    2313                                 {
    2314                                     pPerfSys->padIntrPrev
    2315                                         = (double*)malloc(pPerfSys->cProcessors * sizeof(double));
    2316                                     if (!pPerfSys->padIntrPrev)
    2317                                         arc = ERROR_NOT_ENOUGH_MEMORY;
    2318                                     else
    2319                                     {
    2320                                         pPerfSys->palLoads = (PLONG)malloc(pPerfSys->cProcessors * sizeof(LONG));
    2321                                         if (!pPerfSys->palLoads)
    2322                                             arc = ERROR_NOT_ENOUGH_MEMORY;
    2323                                         else
    2324                                         {
    2325                                             pPerfSys->palIntrs = (PLONG)malloc(pPerfSys->cProcessors * sizeof(LONG));
    2326                                             if (!pPerfSys->palIntrs)
    2327                                                 arc = ERROR_NOT_ENOUGH_MEMORY;
    2328                                             else
    2329                                             {
    2330                                                 for (ul = 0; ul < pPerfSys->cProcessors; ul++)
    2331                                                 {
    2332                                                     pPerfSys->padBusyPrev[ul] = 0.0;
    2333                                                     pPerfSys->padTimePrev[ul] = 0.0;
    2334                                                     pPerfSys->padIntrPrev[ul] = 0.0;
    2335                                                     pPerfSys->palLoads[ul] = 0;
    2336                                                     pPerfSys->palIntrs[ul] = 0;
    2337                                                 }
    2338                                             }
    2339                                         }
    2340                                     }
    2341                                 }
     2320                                pPerfSys->padBusyPrev[ul] = 0.0;
     2321                                pPerfSys->padTimePrev[ul] = 0.0;
     2322                                pPerfSys->padIntrPrev[ul] = 0.0;
     2323                                pPerfSys->palLoads[ul] = 0;
     2324                                pPerfSys->palIntrs[ul] = 0;
    23422325                            }
    23432326                        }
     
    23472330        } // end if (arc == NO_ERROR)
    23482331
    2349         if (arc != NO_ERROR)
    2350         {
     2332        if (arc)
     2333            // error: clean up
    23512334            doshPerfClose(ppPerfSys);
    2352         }
     2335
    23532336    } // end else if (!*ppPerfSys)
    23542337
     
    24052388    else
    24062389    {
    2407         arc = pPerfSys->pDosPerfSysCall(CMD_KI_RDCNT,
    2408                                         (ULONG)pPerfSys->paCPUUtils,
    2409                                         0, 0);
    2410         if (arc == NO_ERROR)
     2390        if (!(arc = pPerfSys->pDosPerfSysCall(CMD_KI_RDCNT,
     2391                                              (ULONG)pPerfSys->paCPUUtils,
     2392                                              0, 0)))
    24112393        {
    24122394            // go thru all processors
  • trunk/src/helpers/dosh2.c

    r91 r108  
    21862186
    21872187/*
     2188 *@@ CopyToBuffer:
     2189 *      little helper for copying a string to
     2190 *      a target buffer with length checking.
     2191 *
     2192 *      Returns:
     2193 *
     2194 *      --  NO_ERROR
     2195 *
     2196 *      --  ERROR_BUFFER_OVERFLOW if pszTarget does
     2197 *          not have enough room to hold pcszSource
     2198 *          (including the null terminator).
     2199 *
     2200 *@@added V0.9.16 (2001-10-08) [umoeller]
     2201 */
     2202
     2203APIRET CopyToBuffer(PSZ pszTarget,      // out: target buffer
     2204                    PCSZ pcszSource,    // in: source string
     2205                    ULONG cbTarget)     // in: size of target buffer
     2206{
     2207    ULONG ulLength = strlen(pcszSource);
     2208    if (ulLength < cbTarget)
     2209    {
     2210        memcpy(pszTarget,
     2211               pcszSource,
     2212               ulLength + 1);
     2213        return (NO_ERROR);
     2214    }
     2215
     2216    return(ERROR_BUFFER_OVERFLOW);
     2217}
     2218
     2219/*
     2220 *@@ doshSearchPath:
     2221 *      replacement for DosSearchPath.
     2222 *
     2223 *      This looks along all directories which are
     2224 *      specified in the value of the given environment
     2225 *      variable if pcszFile is found.
     2226 *
     2227 *      As opposed to the stupid DosSearchPath, this
     2228 *      ignores subdirectories in the path particles.
     2229 *      For example, DosSearchPath would usually not
     2230 *      find an INSTALL file because \OS2 contains
     2231 *      an INSTALL directory, or NETSCAPE because
     2232 *      \OS2\INSTALL contains a NETSCAPE directory.
     2233 *
     2234 *      Returns:
     2235 *
     2236 *      --  NO_ERROR: pszExecutable has received the
     2237 *          full path of pcszFile.
     2238 *
     2239 *      --  ERROR_FILE_NOT_FOUND: pcszFile was not found
     2240 *          in the specified path (or is a directory).
     2241 *
     2242 *      --  ERROR_BUFFER_OVERFLOW: pcszFile was found, but
     2243 *          the pszExecutable buffer is too small to hold
     2244 *          the full path.
     2245 *
     2246 *@@added V0.9.16 (2001-10-08) [umoeller]
     2247 */
     2248
     2249APIRET doshSearchPath(const char *pcszPath,     // in: path variable name (e.g. "PATH")
     2250                      const char *pcszFile,     // in: file to look for (e.g. "LVM.EXE")
     2251                      PSZ pszExecutable,        // out: full path (e.g. "F:\os2\lvm.exe")
     2252                      ULONG cbExecutable)       // in: sizeof (*pszExecutable)
     2253{
     2254    APIRET arc = NO_ERROR;
     2255
     2256    // get the PATH value
     2257    PSZ pszPath;
     2258    if (!(arc = DosScanEnv((PSZ)pcszPath,
     2259                           &pszPath)))
     2260    {
     2261        // run thru the path components
     2262        PSZ pszPathCopy;
     2263        if (pszPathCopy = strdup(pszPath))
     2264        {
     2265            PSZ pszToken = strtok(pszPathCopy, ";");
     2266            while (pszToken)        // V0.9.12 (2001-05-03) [umoeller]
     2267            {
     2268                CHAR szFileMask[2*CCHMAXPATH];
     2269                FILESTATUS3 fs3;
     2270
     2271                sprintf(szFileMask,
     2272                        "%s\\%s",
     2273                        pszToken,           // path particle
     2274                        pcszFile);          // e.g. "netscape"
     2275
     2276                if (    (!(arc = DosQueryPathInfo(szFileMask,
     2277                                                  FIL_STANDARD,
     2278                                                  &fs3,
     2279                                                  sizeof(fs3))))
     2280                     // make sure it's not a directory
     2281                     // and that it's not hidden
     2282                     && (!(fs3.attrFile & (FILE_DIRECTORY | FILE_HIDDEN)))
     2283                   )
     2284                {
     2285                    // copy
     2286                    arc = CopyToBuffer(pszExecutable,
     2287                                       szFileMask,
     2288                                       cbExecutable);
     2289                    // and stop
     2290                    break;
     2291                }
     2292                else
     2293                    arc = ERROR_FILE_NOT_FOUND;
     2294                    // and search on
     2295
     2296                pszToken = strtok(NULL, ";");
     2297            };
     2298
     2299            free(pszPathCopy);
     2300        }
     2301        else
     2302            arc = ERROR_NOT_ENOUGH_MEMORY;
     2303    }
     2304
     2305    return (arc);
     2306}
     2307
     2308/*
    21882309 * FindFile:
    21892310 *      helper for doshFindExecutable.
    21902311 *
    21912312 *added V0.9.11 (2001-04-25) [umoeller]
     2313 *@@changed V0.9.16 (2001-10-08) [umoeller]: rewrote second half for DosSearchPath replacement, which returns directories too
    21922314 */
    21932315
     
    22102332        if (!arc)
    22112333            if (!(fs3.attrFile & FILE_DIRECTORY))
    2212                 strhncpy0(pszExecutable,
    2213                           pcszCommand,
    2214                           cbExecutable);
     2334                arc = CopyToBuffer(pszExecutable,
     2335                                   pcszCommand,
     2336                                   cbExecutable);
    22152337            else
    22162338                // directory:
     
    22182340    }
    22192341    else
     2342    {
    22202343        // non-qualified:
    2221         arc = DosSearchPath(SEARCH_IGNORENETERRS | SEARCH_ENVIRONMENT | SEARCH_CUR_DIRECTORY,
     2344        /* arc = DosSearchPath(SEARCH_IGNORENETERRS
     2345                                | SEARCH_ENVIRONMENT
     2346                                | SEARCH_CUR_DIRECTORY,
    22222347                            "PATH",
    22232348                            (PSZ)pcszCommand,
    22242349                            pszExecutable,
    2225                             cbExecutable);
     2350                            cbExecutable); */
     2351            // The above is not useable. It returns directories
     2352            // on the path... for example, it returns \OS2\INSTALL\NETSCAPE
     2353            // if netscape is looked for. So we search manually... sigh.
     2354            // V0.9.16 (2001-10-08) [umoeller]
     2355        arc = doshSearchPath("PATH",
     2356                             pcszCommand,
     2357                             pszExecutable,
     2358                             cbExecutable);
     2359    }
    22262360
    22272361    return (arc);
     
    22352369 *      1)  If pcszCommand appears to be qualified (i.e. contains
    22362370 *          a backslash), this checks for whether the file exists.
    2237  *
    2238  *      2)  If pcszCommand contains no backslash, this calls
    2239  *          DosSearchPath in order to find the full path of the
    2240  *          executable.
     2371 *          If it is a directory, ERROR_INVALID_EXE_SIGNATURE is
     2372 *          returned.
     2373 *
     2374 *      2)  If pcszCommand contains no backslash, this searches
     2375 *          all directories on the PATH in order to find the full
     2376 *          path of the executable. Starting with V0.9.16, we
     2377 *          use doshSearchPath for that.
    22412378 *
    22422379 *      papcszExtensions determines if additional searches are to be
    2243  *      performed if the file doesn't exist (case 1) or DosSearchPath
     2380 *      performed if the file doesn't exist (case 1) or doshSearchPath
    22442381 *      returned ERROR_FILE_NOT_FOUND (case 2).
    22452382 *      This must point to an array of strings specifying the extra
     
    22492386 *      extra searches are performed.
    22502387 *
    2251  *      If this returns NO_ERROR, pszExecutable receives
    2252  *      the full path of the executable found by DosSearchPath.
    2253  *      Otherwise ERROR_FILE_NOT_FOUND is returned.
     2388 *      Returns:
     2389 *
     2390 *      --  NO_ERROR: pszExecutable has received the full path of
     2391 *          the executable found by DosSearchPath.
     2392 *
     2393 *      --  ERROR_FILE_NOT_FOUND
     2394 *
     2395 *      --  ERROR_BUFFER_OVERFLOW: pcszCommand was found, but
     2396 *          the pszExecutable buffer is too small to hold
     2397 *          the full path.
    22542398 *
    22552399 *      Example:
     
    22942438            {
    22952439                const char *pcszExtThis = papcszExtensions[ul];
    2296                 sprintf(psz2, "%s.%s", pcszCommand, pcszExtThis);
     2440                sprintf(psz2,
     2441                        "%s.%s",
     2442                        pcszCommand,
     2443                        pcszExtThis);
    22972444                arc = FindFile(psz2,
    22982445                               pszExecutable,
     
    23282475 *      on the system.
    23292476 *
    2330  *      Based on code (C) Dmitry A. Steklenev.
    2331  *
    23322477 *@@added V0.9.0 [umoeller]
    23332478 */
     
    23352480UINT doshQueryDiskCount(VOID)
    23362481{
    2337     USHORT count = 0;
    2338 
    2339     DosPhysicalDisk(INFO_COUNT_PARTITIONABLE_DISKS, &count, 2, 0, 0);
    2340     return (count);
    2341 }
    2342 
    2343 /*
    2344  *@@ doshReadSector:
    2345  *      reads a physical disk sector.
    2346  *
    2347  *      If NO_ERROR is returned, the sector contents
    2348  *      have been stored in *buff.
    2349  *
    2350  *      Based on code (C) Dmitry A. Steklenev.
    2351  *
    2352  *@@added V0.9.0 [umoeller]
    2353  *@@changed V0.9.9 (2001-04-04) [umoeller]: added more error checking
    2354  */
    2355 
    2356 APIRET doshReadSector(USHORT disk,      // in: physical disk no. (1, 2, 3, ...)
    2357                       void *buff,
    2358                       USHORT head,
    2359                       USHORT cylinder,
    2360                       USHORT sector)
    2361 {
    2362     APIRET  arc;
    2363     HFILE   dh = 0;
    2364     char    dn[256];
    2365 
    2366     sprintf(dn, "%u:", disk);
    2367     if (!(arc = DosPhysicalDisk(INFO_GETIOCTLHANDLE, &dh, 2, dn, 3)))
    2368     {
    2369         TRACKLAYOUT DiskIOParm;
    2370         ULONG IOCtlDataLength = sizeof(DiskIOParm);
    2371         ULONG IOCtlParmLength = 512;
    2372 
    2373         DiskIOParm.bCommand = 0;
    2374         DiskIOParm.usHead = head;
    2375         DiskIOParm.usCylinder = cylinder;
    2376         DiskIOParm.usFirstSector = 0;
    2377         DiskIOParm.cSectors = 1;
    2378         DiskIOParm.TrackTable[0].usSectorNumber = sector;
    2379         DiskIOParm.TrackTable[0].usSectorSize = 512;
    2380 
    2381         arc = DosDevIOCtl(dh,
    2382                           IOCTL_PHYSICALDISK, PDSK_READPHYSTRACK,
    2383                           &DiskIOParm, IOCtlParmLength, &IOCtlParmLength,
    2384                           buff       , IOCtlDataLength, &IOCtlDataLength);
    2385 
    2386         DosPhysicalDisk(INFO_FREEIOCTLHANDLE, 0, 0, &dh, 2);
    2387     }
    2388 
    2389     return (arc);
     2482    USHORT usCount = 0;
     2483    DosPhysicalDisk(INFO_COUNT_PARTITIONABLE_DISKS, &usCount, 2, 0, 0);
     2484    return (usCount);
    23902485}
    23912486
     
    23932488 *@@ doshType2FSName:
    23942489 *      this returns a static, zero-terminated string
    2395  *      for the given FS type. This is always 7 bytes
    2396  *      in length.
    2397  *
    2398  *      Values for operating system indicator:
    2399  *      --  00h  empty
    2400  *      --  01h  DOS 12-bit FAT
    2401  *      --  02h  XENIX root file system
    2402  *      --  03h  XENIX /usr file system (obsolete)
    2403  *      --  04h  DOS 16-bit FAT (up to 32M)
    2404  *      --  05h  DOS 3.3+ extended partition
    2405  *      --  06h  DOS 3.31+ Large File System (16-bit FAT, over 32M)
    2406  *      --  07h  QNX
    2407  *      --  07h  OS/2 HPFS
    2408  *      --  07h  Windows NT NTFS
    2409  *      --  07h  Advanced Unix
    2410  *      --  08h  OS/2 (v1.0-1.3 only)
    2411  *      --  08h  AIX bootable partition, SplitDrive
    2412  *      --  08h  Commodore DOS
    2413  *      --  08h  DELL partition spanning multiple drives
    2414  *      --  09h  AIX data partition
    2415  *      --  09h  Coherent filesystem
    2416  *      --  0Ah  OS/2 Boot Manager
    2417  *      --  0Ah  OPUS
    2418  *      --  0Ah  Coherent swap partition
    2419  *      --  0Bh  Windows95 with 32-bit FAT
    2420  *      --  0Ch  Windows95 with 32-bit FAT (using LBA-mode INT 13 extensions)
    2421  *      --  0Eh  logical-block-addressable VFAT (same as 06h but using LBA-mode INT 13)
    2422  *      --  0Fh  logical-block-addressable VFAT (same as 05h but using LBA-mode INT 13)
    2423  *      --  10h  OPUS
    2424  *      --  11h  OS/2 Boot Manager hidden 12-bit FAT partition
    2425  *      --  12h  Compaq Diagnostics partition
    2426  *      --  14h  (resulted from using Novell DOS 7.0 FDISK to delete Linux Native part)
    2427  *      --  14h  OS/2 Boot Manager hidden sub-32M 16-bit FAT partition
    2428  *      --  16h  OS/2 Boot Manager hidden over-32M 16-bit FAT partition
    2429  *      --  17h  OS/2 Boot Manager hidden HPFS partition
    2430  *      --  18h  AST special Windows swap file ("Zero-Volt Suspend" partition)
    2431  *      --  21h  officially listed as reserved
    2432  *      --  23h  officially listed as reserved
    2433  *      --  24h  NEC MS-DOS 3.x
    2434  *      --  26h  officially listed as reserved
    2435  *      --  31h  officially listed as reserved
    2436  *      --  33h  officially listed as reserved
    2437  *      --  34h  officially listed as reserved
    2438  *      --  36h  officially listed as reserved
    2439  *      --  38h  Theos
    2440  *      --  3Ch  PowerQuest PartitionMagic recovery partition
    2441  *      --  40h  VENIX 80286
    2442  *      --  41h  Personal RISC Boot
    2443  *      --  42h  SFS (Secure File System) by Peter Gutmann
    2444  *      --  50h  OnTrack Disk Manager, read-only partition
    2445  *      --  51h  OnTrack Disk Manager, read/write partition
    2446  *      --  51h  NOVEL
    2447  *      --  52h  CP/M
    2448  *      --  52h  Microport System V/386
    2449  *      --  53h  OnTrack Disk Manager, write-only partition???
    2450  *      --  54h  OnTrack Disk Manager (DDO)
    2451  *      --  56h  GoldenBow VFeature
    2452  *      --  61h  SpeedStor
    2453  *      --  63h  Unix SysV/386, 386/ix
    2454  *      --  63h  Mach, MtXinu BSD 4.3 on Mach
    2455  *      --  63h  GNU HURD
    2456  *      --  64h  Novell NetWare 286
    2457  *      --  65h  Novell NetWare (3.11)
    2458  *      --  67h  Novell
    2459  *      --  68h  Novell
    2460  *      --  69h  Novell
    2461  *      --  70h  DiskSecure Multi-Boot
    2462  *      --  71h  officially listed as reserved
    2463  *      --  73h  officially listed as reserved
    2464  *      --  74h  officially listed as reserved
    2465  *      --  75h  PC/IX
    2466  *      --  76h  officially listed as reserved
    2467  *      --  80h  Minix v1.1 - 1.4a
    2468  *      --  81h  Minix v1.4b+
    2469  *      --  81h  Linux
    2470  *      --  81h  Mitac Advanced Disk Manager
    2471  *      --  82h  Linux Swap partition
    2472  *      --  82h  Prime
    2473  *      --  83h  Linux native file system (ext2fs/xiafs)
    2474  *      --  84h  OS/2-renumbered type 04h partition (related to hiding DOS C: drive)
    2475  *      --  86h  FAT16 volume/stripe set (Windows NT)
    2476  *      --  87h  HPFS Fault-Tolerant mirrored partition
    2477  *      --  87h  NTFS volume/stripe set
    2478  *      --  93h  Amoeba file system
    2479  *      --  94h  Amoeba bad block table
    2480  *      --  A0h  Phoenix NoteBIOS Power Management "Save-to-Disk" partition
    2481  *      --  A1h  officially listed as reserved
    2482  *      --  A3h  officially listed as reserved
    2483  *      --  A4h  officially listed as reserved
    2484  *      --  A5h  FreeBSD, BSD/386
    2485  *      --  A6h  officially listed as reserved
    2486  *      --  B1h  officially listed as reserved
    2487  *      --  B3h  officially listed as reserved
    2488  *      --  B4h  officially listed as reserved
    2489  *      --  B6h  officially listed as reserved
    2490  *      --  B7h  BSDI file system (secondarily swap)
    2491  *      --  B8h  BSDI swap partition (secondarily file system)
    2492  *      --  C1h  DR DOS 6.0 LOGIN.EXE-secured 12-bit FAT partition
    2493  *      --  C4h  DR DOS 6.0 LOGIN.EXE-secured 16-bit FAT partition
    2494  *      --  C6h  DR DOS 6.0 LOGIN.EXE-secured Huge partition
    2495  *      --  C6h  corrupted FAT16 volume/stripe set (Windows NT)
    2496  *      --  C7h  Syrinx Boot
    2497  *      --  C7h  corrupted NTFS volume/stripe set
    2498  *      --  D8h  CP/M-86
    2499  *      --  DBh  CP/M, Concurrent CP/M, Concurrent DOS
    2500  *      --  DBh  CTOS (Convergent Technologies OS)
    2501  *      --  E1h  SpeedStor 12-bit FAT extended partition
    2502  *      --  E3h  DOS read-only
    2503  *      --  E3h  Storage Dimensions
    2504  *      --  E4h  SpeedStor 16-bit FAT extended partition
    2505  *      --  E5h  officially listed as reserved
    2506  *      --  E6h  officially listed as reserved
    2507  *      --  F1h  Storage Dimensions
    2508  *      --  F2h  DOS 3.3+ secondary partition
    2509  *      --  F3h  officially listed as reserved
    2510  *      --  F4h  SpeedStor
    2511  *      --  F4h  Storage Dimensions
    2512  *      --  F6h  officially listed as reserved
    2513  *      --  FEh  LANstep
    2514  *      --  FEh  IBM PS/2 IML
    2515  *      --  FFh  Xenix bad block table
    2516  *
    2517  *      Note: for partition type 07h, one should inspect the partition boot record
    2518  *            for the actual file system type
    2519  *
    2520  *      Based on code (C) Dmitry A. Steklenev.
     2490 *      for the given FS type, or NULL if the type
     2491 *      is unknown.
    25212492 *
    25222493 *@@added V0.9.0 [umoeller]
     2494 *@@changed V0.9.16 (2001-10-08) [umoeller]: rewritten
    25232495 */
    25242496
    25252497const char* doshType2FSName(unsigned char bFSType)  // in: FS type
    25262498{
    2527     PSZ zFSName = NULL;
    2528 
    25292499    switch (bFSType)
    25302500    {
    2531         case PAR_UNUSED:
    2532             zFSName = "UNUSED ";
    2533             break;
    2534         case PAR_FAT12SMALL:
    2535             zFSName = "FAT-12 ";
    2536             break;
    2537         case PAR_XENIXROOT:
    2538             zFSName = "XENIX  ";
    2539             break;
    2540         case PAR_XENIXUSER:
    2541             zFSName = "XENIX  ";
    2542             break;
    2543         case PAR_FAT16SMALL:
    2544             zFSName = "FAT-16 ";
    2545             break;
    2546         case PAR_EXTENDED:
    2547             zFSName = "EXTEND ";
    2548             break;
    2549         case PAR_FAT16BIG:
    2550             zFSName = "BIGDOS ";
    2551             break;
    2552         case PAR_HPFS:
    2553             zFSName = "HPFS   ";
    2554             break;
    2555         case PAR_AIXBOOT:
    2556             zFSName = "AIX    ";
    2557             break;
    2558         case PAR_AIXDATA:
    2559             zFSName = "AIX    ";
    2560             break;
    2561         case PAR_BOOTMANAGER:
    2562             zFSName = "BOOTMNG";
    2563             break;
    2564         case PAR_WINDOWS95:
    2565             zFSName = "WIN95  ";
    2566             break;
    2567         case PAR_WINDOWS95LB:
    2568             zFSName = "WIN95  ";
    2569             break;
    2570         case PAR_VFAT16BIG:
    2571             zFSName = "VFAT   ";
    2572             break;
    2573         case PAR_VFAT16EXT:
    2574             zFSName = "VFAT   ";
    2575             break;
    2576         case PAR_OPUS:
    2577             zFSName = "OPUS   ";
    2578             break;
    2579         case PAR_HID12SMALL:
    2580             zFSName = "FAT-12*";
    2581             break;
    2582         case PAR_COMPAQDIAG:
    2583             zFSName = "COMPAQ ";
    2584             break;
    2585         case PAR_HID16SMALL:
    2586             zFSName = "FAT-16*";
    2587             break;
    2588         case PAR_HID16BIG:
    2589             zFSName = "BIGDOS*";
    2590             break;
    2591         case PAR_HIDHPFS:
    2592             zFSName = "HPFS*  ";
    2593             break;
    2594         case PAR_WINDOWSSWP:
    2595             zFSName = "WINSWAP";
    2596             break;
    2597         case PAR_NECDOS:
    2598             zFSName = "NECDOS ";
    2599             break;
    2600         case PAR_THEOS:
    2601             zFSName = "THEOS  ";
    2602             break;
    2603         case PAR_VENIX:
    2604             zFSName = "VENIX  ";
    2605             break;
    2606         case PAR_RISCBOOT:
    2607             zFSName = "RISC   ";
    2608             break;
    2609         case PAR_SFS:
    2610             zFSName = "SFS    ";
    2611             break;
    2612         case PAR_ONTRACK:
    2613             zFSName = "ONTRACK";
    2614             break;
    2615         case PAR_ONTRACKEXT:
    2616             zFSName = "ONTRACK";
    2617             break;
    2618         case PAR_CPM:
    2619             zFSName = "CP/M   ";
    2620             break;
    2621         case PAR_UNIXSYSV:
    2622             zFSName = "UNIX   ";
    2623             break;
    2624         case PAR_NOVELL_64:
    2625             zFSName = "NOVELL ";
    2626             break;
    2627         case PAR_NOVELL_65:
    2628             zFSName = "NOVELL ";
    2629             break;
    2630         case PAR_NOVELL_67:
    2631             zFSName = "NOVELL ";
    2632             break;
    2633         case PAR_NOVELL_68:
    2634             zFSName = "NOVELL ";
    2635             break;
    2636         case PAR_NOVELL_69:
    2637             zFSName = "NOVELL ";
    2638             break;
    2639         case PAR_PCIX:
    2640             zFSName = "PCIX   ";
    2641             break;
    2642         case PAR_MINIX:
    2643             zFSName = "MINIX  ";
    2644             break;
    2645         case PAR_LINUX:
    2646             zFSName = "LINUX  ";
    2647             break;
    2648         case PAR_LINUXSWAP:
    2649             zFSName = "LNXSWP ";
    2650             break;
    2651         case PAR_LINUXFILE:
    2652             zFSName = "LINUX  ";
    2653             break;
    2654         case PAR_FREEBSD:
    2655             zFSName = "FREEBSD";
    2656             break;
    2657         case PAR_BBT:
    2658             zFSName = "BBT    ";
    2659             break;
    2660 
    2661         default:
    2662             zFSName = "       ";
    2663             break;
     2501        case 0x00: return "empty";
     2502        case 0x01: return "DOS 12-bit FAT < 10 Mb";
     2503        case 0x02: return "XENIX root file system";
     2504        case 0x03: return "XENIX /usr file system (obsolete)";
     2505        case 0x04: return "DOS 16-bit FAT < 32 Mb";
     2506        case 0x05: return "DOS 3.3+ extended partition";
     2507        case 0x06: return "DOS 3.31+ 16-bit FAT > 32 Mb";
     2508        case 0x07: return "HPFS/NTFS/QNX/Advanced Unix";
     2509        case 0x08: return "OS/2 1.0-1.3/AIX/Commodore/DELL";
     2510        case 0x09: return "AIX data/Coherent";
     2511        case 0x0A: return "OS/2 Boot Manager/OPUS/Coherent Swap";
     2512        case 0x0B: return "Windows95 with 32-bit FAT";
     2513        case 0x0C: return "Windows95 with 32-bit FAT (LBA)";
     2514        case 0x0E: return "Windows 95 VFAT (06h plus LBA)";
     2515        case 0x0F: return "Windows 95 VFAT (05h plus LBA)";
     2516        case 0x10: return "OPUS";
     2517        case 0x11: return "OS/2 Boot Manager hidden 12-bit FAT";
     2518        case 0x12: return "Compaq Diagnostics";
     2519        case 0x14: return "OS/2 Boot Manager hidden sub-32M 16-bit FAT";
     2520        case 0x16: return "OS/2 Boot Manager hidden over-32M 16-bit FAT";
     2521        case 0x17: return "OS/2 Boot Manager hidden HPFS";
     2522        case 0x18: return "AST special Windows swap file (\"Zero-Volt Suspend\")";
     2523        // case 0x21: reserved
     2524        // case 0x23: reserved
     2525        case 0x24: return "NEC MS-DOS 3.x";
     2526        // case 0x26: reserved
     2527        // case 0x31: reserved
     2528        // case 0x33: reserved
     2529        // case 0x34: reserved
     2530        // case 0x36: reserved
     2531        case 0x38: return "Theos";
     2532        case 0x3C: return "PowerQuest PartitionMagic recovery partition";
     2533        case 0x40: return "VENIX 80286";
     2534        case 0x41: return "Personal RISC Boot";
     2535        case 0x42: return "SFS (Secure File System) by Peter Gutmann";
     2536        case 0x50: return "OnTrack Disk Manager, read-only";
     2537        case 0x51: return "OnTrack Disk Manager, read/write";
     2538        case 0x52: return "CP/M or Microport System V/386";
     2539        case 0x53: return "OnTrack Disk Manager, write-only???";
     2540        case 0x54: return "OnTrack Disk Manager (DDO)";
     2541        case 0x56: return "GoldenBow VFeature";
     2542        case 0x61: return "SpeedStor";
     2543        case 0x63: return "Unix SysV/386, 386/ix or Mach, MtXinu BSD 4.3 on Mach or GNU HURD";
     2544        case 0x64: return "Novell NetWare 286";
     2545        case 0x65: return "Novell NetWare (3.11)";
     2546        case 0x67:
     2547        case 0x68:
     2548        case 0x69: return "Novell";
     2549        case 0x70: return "DiskSecure Multi-Boot";
     2550        // case 0x71: reserved
     2551        // case 0x73: reserved
     2552        // case 0x74: reserved
     2553        case 0x75: return "PC/IX";
     2554        // case 0x76: reserved
     2555        case 0x80: return "Minix v1.1 - 1.4a";
     2556        case 0x81: return "Minix v1.4b+ or Linux or Mitac Advanced Disk Manager";
     2557        case 0x82: return "Linux Swap or Prime";
     2558        case 0x83: return "Linux native file system (ext2fs/xiafs)";
     2559        case 0x84: return "OS/2-renumbered type 04h (hidden DOS C: drive)";
     2560        case 0x86: return "FAT16 volume/stripe set (Windows NT)";
     2561        case 0x87: return "HPFS Fault-Tolerant mirrored partition or NTFS volume/stripe set";
     2562        case 0x93: return "Amoeba file system";
     2563        case 0x94: return "Amoeba bad block table";
     2564        case 0xA0: return "Phoenix NoteBIOS Power Management \"Save-to-Disk\" partition";
     2565        // case 0xA1: reserved
     2566        // case 0xA3: reserved
     2567        // case 0xA4: reserved
     2568        case 0xA5: return "FreeBSD, BSD/386";
     2569        // case 0xA6: reserved
     2570        // case 0xB1: reserved
     2571        // case 0xB3: reserved
     2572        // case 0xB4: reserved
     2573        // case 0xB6: reserved
     2574        case 0xB7: return "BSDI file system (secondarily swap)";
     2575        case 0xB8: return "BSDI swap (secondarily file system)";
     2576        case 0xC1: return "DR DOS 6.0 LOGIN.EXE-secured 12-bit FAT";
     2577        case 0xC4: return "DR DOS 6.0 LOGIN.EXE-secured 16-bit FAT";
     2578        case 0xC6: return "DR DOS 6.0 LOGIN.EXE-secured Huge partition or NT corrupted FAT16 volume/stripe set";
     2579        case 0xC7: return "Syrinx Boot or corrupted NTFS volume/stripe set";
     2580        case 0xD8: return "CP/M-86";
     2581        case 0xDB: return "CP/M, Concurrent CP/M, Concurrent DOS, Convergent Technologies OS";
     2582        case 0xE1: return "SpeedStor 12-bit FAT extended partition";
     2583        case 0xE3: return "DOS read-only or Storage Dimensions";
     2584        case 0xE4: return "SpeedStor 16-bit FAT extended partition";
     2585        // case 0xE5: reserved
     2586        // case 0xE6: reserved
     2587        case 0xF1: return "Storage Dimensions";
     2588        case 0xF2: return "DOS 3.3+ secondary partition";
     2589        // case 0xF3: reserved
     2590        case 0xF4: return "SpeedStor or Storage Dimensions";
     2591        // case 0xF6: reserved
     2592        case 0xFE: return "LANstep or IBM PS/2 IML";
     2593        case 0xFF: return "Xenix bad block table";
    26642594    }
    2665     return zFSName;
     2595
     2596    return NULL;
    26662597}
    26672598
     
    26782609 *      to point to the newly created PARTITIONINFO, so before
    26792610 *      calling this function for the first time,
    2680  *
    2681  *      Based on code (C) Dmitry A. Steklenev.
    26822611 *
    26832612 *@@added V0.9.0 [umoeller]
     
    27122641        ppiNew->cLetter = cLetter;
    27132642        ppiNew->bFSType = bFsType;
    2714         strcpy(ppiNew->szFSType,
    2715                doshType2FSName(bFsType));
     2643        ppiNew->pcszFSType = doshType2FSName(bFsType);
    27162644        ppiNew->fPrimary = fPrimary;
    27172645        ppiNew->fBootable = fBootable;
     
    27412669}
    27422670
     2671#ifndef __XWPLITE__
     2672
     2673/*
     2674 *@@ doshReadSector:
     2675 *      reads a physical disk sector.
     2676 *
     2677 *      If NO_ERROR is returned, the sector contents
     2678 *      have been stored in *buff.
     2679 *
     2680 *      Originally contributed by Dmitry A. Steklenev.
     2681 *
     2682 *@@added V0.9.0 [umoeller]
     2683 *@@changed V0.9.9 (2001-04-04) [umoeller]: added more error checking
     2684 */
     2685
     2686APIRET doshReadSector(USHORT disk,      // in: physical disk no. (1, 2, 3, ...)
     2687                      void *buff,
     2688                      USHORT head,
     2689                      USHORT cylinder,
     2690                      USHORT sector)
     2691{
     2692    APIRET  arc;
     2693    HFILE   dh = 0;
     2694    char    dn[256];
     2695
     2696    sprintf(dn, "%u:", disk);
     2697    if (!(arc = DosPhysicalDisk(INFO_GETIOCTLHANDLE, &dh, 2, dn, 3)))
     2698    {
     2699        TRACKLAYOUT DiskIOParm;
     2700        ULONG IOCtlDataLength = sizeof(DiskIOParm);
     2701        ULONG IOCtlParmLength = 512;
     2702
     2703        DiskIOParm.bCommand = 0;
     2704        DiskIOParm.usHead = head;
     2705        DiskIOParm.usCylinder = cylinder;
     2706        DiskIOParm.usFirstSector = 0;
     2707        DiskIOParm.cSectors = 1;
     2708        DiskIOParm.TrackTable[0].usSectorNumber = sector;
     2709        DiskIOParm.TrackTable[0].usSectorSize = 512;
     2710
     2711        arc = DosDevIOCtl(dh,
     2712                          IOCTL_PHYSICALDISK, PDSK_READPHYSTRACK,
     2713                          &DiskIOParm, IOCtlParmLength, &IOCtlParmLength,
     2714                          buff       , IOCtlDataLength, &IOCtlDataLength);
     2715
     2716        DosPhysicalDisk(INFO_FREEIOCTLHANDLE, 0, 0, &dh, 2);
     2717    }
     2718
     2719    return (arc);
     2720}
     2721
    27432722// Sector and Cylinder values are actually 6 bits and 10 bits:
    27442723//
     
    27562735 *      get cylinder number.
    27572736 *
    2758  *      Based on code (C) Dmitry A. Steklenev.
     2737 *      Originally contributed by Dmitry A. Steklenev.
    27592738 *
    27602739 *@@added V0.9.0 [umoeller]
     
    27712750 *      get sector number.
    27722751 *
    2773  *      Based on code (C) Dmitry A. Steklenev.
     2752 *      Originally contributed by Dmitry A. Steklenev.
    27742753 *
    27752754 *@@added V0.9.0 [umoeller]
     
    27962775 *      -- ERROR_NOT_SUPPORTED (50): boot manager not installed.
    27972776 *
    2798  *      Based on code (C) Dmitry A. Steklenev.
     2777 *      Originally contributed by Dmitry A. Steklenev.
    27992778 *
    28002779 *@@added V0.9.0 [umoeller]
     
    28582837 *      -- ERROR_INVALID_PARAMETER: BMInfo is NULL.
    28592838 *
    2860  *      Based on code (C) Dmitry A. Steklenev.
     2839 *      Originally contributed by Dmitry A. Steklenev.
    28612840 *
    28622841 *@@added V0.9.0 [umoeller]
     
    29072886                    // skip unused partition, BootManager or Extended partition
    29082887                    if (    (MBoot.sPrtnInfo[i].bFileSysCode)  // skip unused
    2909                         &&  (MBoot.sPrtnInfo[i].bFileSysCode != PAR_BOOTMANAGER) // skip boot manager
    2910                         &&  (MBoot.sPrtnInfo[i].bFileSysCode != PAR_EXTENDED) // skip extended
     2888                        &&  (MBoot.sPrtnInfo[i].bFileSysCode != 0x0A) // skip boot manager
     2889                        &&  (MBoot.sPrtnInfo[i].bFileSysCode != 0x05) // skip extended partition
    29112890                       )
    29122891                    {
     
    29452924 *      This gets called from GetExtendedPartition.
    29462925 *
    2947  *      Based on code (C) Dmitry A. Steklenev.
     2926 *      Originally contributed by Dmitry A. Steklenev.
    29482927 *
    29492928 *@@added V0.9.0 [umoeller]
     
    29732952        // skip unused partition or BootManager partition
    29742953        if (    (MBoot.sPrtnInfo[i].bFileSysCode)
    2975              && (MBoot.sPrtnInfo[i].bFileSysCode != PAR_BOOTMANAGER)
     2954             && (MBoot.sPrtnInfo[i].bFileSysCode != 0x0A)
    29762955           )
    29772956        {
     
    29802959
    29812960            // special work around extended partition
    2982             if (MBoot.sPrtnInfo[i].bFileSysCode == PAR_EXTENDED)
     2961            if (MBoot.sPrtnInfo[i].bFileSysCode == 0x05)
    29832962            {
    29842963                if ((arc = GetLogicalDrives(pppiFirst,
     
    29952974
    29962975            // raise driver letter if OS/2 would recognize this drive
    2997             if (    (MBoot.sPrtnInfo[i].bFileSysCode < PAR_PCIX)
     2976            if (    (MBoot.sPrtnInfo[i].bFileSysCode < 0x75)
    29982977               )
    29992978                fAssignLetter = TRUE;
     
    30343013 *      This gets called from doshGetPartitionsList.
    30353014 *
    3036  *      Based on code (C) Dmitry A. Steklenev.
     3015 *      Originally contributed by Dmitry A. Steklenev.
    30373016 *
    30383017 *@@added V0.9.0 [umoeller]
     
    30583037         i++)
    30593038    {
    3060         if (MBoot.sPrtnInfo[i].bFileSysCode == PAR_EXTENDED)
     3039        if (MBoot.sPrtnInfo[i].bFileSysCode == 0x05)
    30613040        {
    30623041            if ((arc = GetLogicalDrives(pppiFirst,
     
    30753054
    30763055/*
     3056 *@@ ReadFDiskPartitions:
     3057 *      helper for doshGetPartitionsList for non-LVM
     3058 *      systems.
     3059 *
     3060 *      Originally contributed by Dmitry A. Steklenev.
     3061 *
     3062 *@@added V0.9.16 (2001-10-08) [umoeller]
     3063 */
     3064
     3065APIRET ReadFDiskPartitions(PARTITIONINFO **ppPartitionInfos,
     3066                           USHORT *pcPartitions,
     3067                           PUSHORT pusContext)              // out: error context
     3068{
     3069    APIRET          arc = NO_ERROR;
     3070
     3071    PAR_INFO        BmInfo;     // BootManager partition
     3072    USHORT          usBmDisk;     // BootManager disk
     3073    USHORT          cDisks = doshQueryDiskCount();    // physical disks count
     3074    USHORT          i;
     3075
     3076    CHAR            cLetter = 'C';  // first drive letter
     3077
     3078    PARTITIONINFO   *ppiTemp = NULL;
     3079
     3080    if (cDisks > 8)              // Not above 8 disks
     3081        cDisks = 8;
     3082
     3083    // get boot manager disk and info
     3084    if ((arc = doshGetBootManager(&usBmDisk,
     3085                                  NULL,
     3086                                  &BmInfo)) != NO_ERROR)
     3087    {
     3088        *pusContext = 1;
     3089    }
     3090    else
     3091    {
     3092        // on each disk, read primary partitions
     3093        for (i = 1; i <= cDisks; i++)
     3094        {
     3095            if ((arc = GetPrimaryPartitions(ppPartitionInfos,
     3096                                            &ppiTemp,
     3097                                            pcPartitions,
     3098                                            &cLetter,
     3099                                            usBmDisk,
     3100                                            usBmDisk ? &BmInfo : 0,
     3101                                            i)))
     3102            {
     3103                *pusContext = 2;
     3104            }
     3105        }
     3106
     3107        if (!arc && usBmDisk)
     3108        {
     3109            // boot manager found:
     3110            // on each disk, read extended partition
     3111            // with logical drives
     3112            for (i = 1; i <= cDisks; i++)
     3113            {
     3114                if ((arc = GetExtendedPartition(ppPartitionInfos,
     3115                                                &ppiTemp,
     3116                                                pcPartitions,
     3117                                                &cLetter,
     3118                                                &BmInfo,
     3119                                                i)))
     3120                {
     3121                    *pusContext = 3;
     3122                }
     3123            }
     3124        }
     3125    } // end else if ((arc = doshGetBootManager(&usBmDisk,
     3126
     3127    return (arc);
     3128}
     3129
     3130#endif
     3131
     3132/*
    30773133 *@@ CleanPartitionInfos:
    30783134 *
     
    31373193 *      --  0: something else.
    31383194 *
    3139  *      Based on code (C) Dmitry A. Steklenev.
     3195 *      Originally contributed by Dmitry A. Steklenev.
    31403196 *
    31413197 *@@added V0.9.0 [umoeller]
     
    31513207    PLVMINFO        pLVMInfo = NULL;
    31523208
    3153     PARTITIONINFO   *pPartitionInfos = NULL, // linked list of all partitions
    3154                     *ppiTemp = NULL;
     3209    PARTITIONINFO   *pPartitionInfos = NULL; // linked list of all partitions
    31553210    USHORT          cPartitions = 0;        // bootable partition count
    31563211
     
    31763231    }
    31773232
     3233#ifndef __XWPLITE__
    31783234    if (arc)
    3179     {
    31803235        // LVM not installed, or failed:
    31813236        // parse partitions manually
    3182         PAR_INFO        BmInfo;     // BootManager partition
    3183         USHORT          usBmDisk;     // BootManager disk
    3184         USHORT          cDisks = doshQueryDiskCount();    // physical disks count
    3185         USHORT          i;
    3186 
    3187         CHAR            cLetter = 'C';  // first drive letter
    3188 
    3189         // start over
    3190         arc = NO_ERROR;
    3191 
    3192         if (cDisks > 8)              // Not above 8 disks
    3193             cDisks = 8;
    3194 
    3195         // get boot manager disk and info
    3196         if ((arc = doshGetBootManager(&usBmDisk,
    3197                                       NULL,
    3198                                       &BmInfo)) != NO_ERROR)
    3199         {
    3200             *pusContext = 1;
    3201         }
    3202         else
    3203         {
    3204             // on each disk, read primary partitions
    3205             for (i = 1; i <= cDisks; i++)
    3206             {
    3207                 if ((arc = GetPrimaryPartitions(&pPartitionInfos,
    3208                                                 &ppiTemp,
    3209                                                 &cPartitions,
    3210                                                 &cLetter,
    3211                                                 usBmDisk,
    3212                                                 usBmDisk ? &BmInfo : 0,
    3213                                                 i)))
    3214                 {
    3215                     *pusContext = 2;
    3216                 }
    3217             }
    3218 
    3219             if (!arc && usBmDisk)
    3220             {
    3221                 // boot manager found:
    3222                 // on each disk, read extended partition
    3223                 // with logical drives
    3224                 for (i = 1; i <= cDisks; i++)
    3225                 {
    3226                     if ((arc = GetExtendedPartition(&pPartitionInfos,
    3227                                                     &ppiTemp,
    3228                                                     &cPartitions,
    3229                                                     &cLetter,
    3230                                                     &BmInfo,
    3231                                                     i)))
    3232                     {
    3233                         *pusContext = 3;
    3234                     }
    3235                 }
    3236             }
    3237         } // end else if ((arc = doshGetBootManager(&usBmDisk,
    3238     } // end else if (!doshQueryLVMInfo(&pLVMInfo))
     3237        arc = ReadFDiskPartitions(&pPartitionInfos,
     3238                                  &cPartitions,
     3239                                  pusContext);
     3240#endif
    32393241
    32403242    if (!arc)
  • trunk/src/helpers/eah.c

    r21 r108  
    857857                                    USHORT usCodepage)  // in: codepage to set in EAT_MVMT
    858858{
    859     PEABINDING peab;
     859    PEABINDING peab = NULL;
    860860    if (pcszInput)
    861861    {
    862         peab = (PEABINDING)malloc(sizeof(EABINDING));
    863         if (peab)
     862        if ((peab = (PEABINDING)malloc(sizeof(EABINDING))))
    864863        {
    865864            const char *p = pcszInput,
  • trunk/src/helpers/helpers_pre.in

    r91 r108  
    6060$(OUTPUTDIR)\except.obj \
    6161$(OUTPUTDIR)\level.obj \
     62$(OUTPUTDIR)\nls.obj \
    6263$(OUTPUTDIR)\procstat.obj \
    6364$(OUTPUTDIR)\prfh.obj \
  • trunk/src/helpers/prfh.c

    r71 r108  
    4545#include "setup.h"                      // code generation and debugging options
    4646
     47#define INCLUDE_PRFH_PRIVATE
    4748#include "helpers\prfh.h"
    4849
     
    237238                          szTemp, sizeof(szTemp)-1);
    238239    return (szTemp[0]);
    239 }
    240 
    241 /*
    242  *@@ prfhQueryCountrySettings:
    243  *      this returns the most frequently used country settings
    244  *      all at once into a COUNTRYSETTINGS structure (prfh.h).
    245  *      This data corresponds to the user settings in the
    246  *      WPS "Country" object (which writes the data in "PM_National"
    247  *      in OS2.INI).
    248  *
    249  *      In case a key cannot be found, the following (English)
    250  *      default values are set:
    251  *      --  ulDateFormat = 0 (English date format, mm.dd.yyyy);
    252  *      --  ulTimeFormat = 0 (12-hour clock);
    253  *      --  cDateSep = '/' (date separator);
    254  *      --  cTimeSep = ':' (time separator);
    255  *      --  cDecimal = '.' (decimal separator).
    256  *      --  cThousands = ',' (thousands separator).
    257  *
    258  *@@added V0.9.0 [umoeller]
    259  *@@changed V0.9.7 (2000-12-02) [umoeller]: added cDecimal
    260  */
    261 
    262 VOID prfhQueryCountrySettings(PCOUNTRYSETTINGS pcs)
    263 {
    264     if (pcs)
    265     {
    266         const char *pcszApp = "PM_National";
    267         pcs->ulDateFormat = PrfQueryProfileInt(HINI_USER, (PSZ)pcszApp, "iDate", 0);
    268         pcs->ulTimeFormat = PrfQueryProfileInt(HINI_USER, (PSZ)pcszApp, "iTime", 0);
    269         pcs->cDateSep = prfhQueryProfileChar(HINI_USER, (PSZ)pcszApp, "sDate", '/');
    270         pcs->cTimeSep = prfhQueryProfileChar(HINI_USER, (PSZ)pcszApp, "sTime", ':');
    271         pcs->cDecimal = prfhQueryProfileChar(HINI_USER, (PSZ)pcszApp, "sDecimal", '.');
    272         pcs->cThousands = prfhQueryProfileChar(HINI_USER, (PSZ)pcszApp, "sThousand", ',');
    273     }
    274240}
    275241
  • trunk/src/helpers/stringh.c

    r105 r108  
    651651    }
    652652    return (ulWords);
    653 }
    654 
    655 /*
    656  *@@ strhThousandsULong:
    657  *      converts a ULONG into a decimal string, while
    658  *      inserting thousands separators into it. Specify
    659  *      the separator character in cThousands.
    660  *
    661  *      Returns pszTarget so you can use it directly
    662  *      with sprintf and the "%s" flag.
    663  *
    664  *      For cThousands, you should use the data in
    665  *      OS2.INI ("PM_National" application), which is
    666  *      always set according to the "Country" object.
    667  *      You can use prfhQueryCountrySettings to
    668  *      retrieve this setting.
    669  *
    670  *      Use strhThousandsDouble for "double" values.
    671  */
    672 
    673 PSZ strhThousandsULong(PSZ pszTarget,       // out: decimal as string
    674                        ULONG ul,            // in: decimal to convert
    675                        CHAR cThousands)     // in: separator char (e.g. '.')
    676 {
    677     USHORT ust, uss, usc;
    678     CHAR   szTemp[40];
    679     sprintf(szTemp, "%lu", ul);
    680 
    681     ust = 0;
    682     usc = strlen(szTemp);
    683     for (uss = 0; uss < usc; uss++)
    684     {
    685         if (uss)
    686             if (((usc - uss) % 3) == 0)
    687             {
    688                 pszTarget[ust] = cThousands;
    689                 ust++;
    690             }
    691         pszTarget[ust] = szTemp[uss];
    692         ust++;
    693     }
    694     pszTarget[ust] = '\0';
    695 
    696     return (pszTarget);
    697 }
    698 
    699 /*
    700  *@@ strhThousandsDouble:
    701  *      like strhThousandsULong, but for a "double"
    702  *      value. Note that after-comma values are truncated.
    703  */
    704 
    705 PSZ strhThousandsDouble(PSZ pszTarget, double dbl, CHAR cThousands)
    706 {
    707     USHORT ust, uss, usc;
    708     CHAR   szTemp[40];
    709     sprintf(szTemp, "%.0f", floor(dbl));
    710 
    711     ust = 0;
    712     usc = strlen(szTemp);
    713     for (uss = 0; uss < usc; uss++)
    714     {
    715         if (uss)
    716             if (((usc - uss) % 3) == 0)
    717             {
    718                 pszTarget[ust] = cThousands;
    719                 ust++;
    720             }
    721         pszTarget[ust] = szTemp[uss];
    722         ust++;
    723     }
    724     pszTarget[ust] = '\0';
    725 
    726     return (pszTarget);
    727 }
    728 
    729 /*
    730  *@@ strhVariableDouble:
    731  *      like strhThousandsULong, but for a "double" value, and
    732  *      with a variable number of decimal places depending on the
    733  *      size of the quantity.
    734  *
    735  *@@added V0.9.6 (2000-11-12) [pr]
    736  */
    737 
    738 PSZ strhVariableDouble(PSZ pszTarget,
    739                        double dbl,
    740                        PSZ pszUnits,
    741                        CHAR cThousands)
    742 {
    743     if (dbl < 100.0)
    744         sprintf(pszTarget, "%.2f%s", dbl, pszUnits);
    745     else
    746         if (dbl < 1000.0)
    747             sprintf(pszTarget, "%.1f%s", dbl, pszUnits);
    748         else
    749             strcat(strhThousandsDouble(pszTarget, dbl, cThousands),
    750                    pszUnits);
    751 
    752     return(pszTarget);
    753 }
    754 
    755 /*
    756  *@@ strhFileDate:
    757  *      converts file date data to a string (to pszBuf).
    758  *      You can pass any FDATE structure to this function,
    759  *      which are returned in those FILEFINDBUF* or
    760  *      FILESTATUS* structs by the Dos* functions.
    761  *
    762  *      ulDateFormat is the PM setting for the date format,
    763  *      as set in the "Country" object, and can be queried using
    764  +              PrfQueryProfileInt(HINI_USER, "PM_National", "iDate", 0);
    765  *
    766  *      meaning:
    767  *      --  0   mm.dd.yyyy  (English)
    768  *      --  1   dd.mm.yyyy  (e.g. German)
    769  *      --  2   yyyy.mm.dd  (Japanese, ISO)
    770  *      --  3   yyyy.dd.mm
    771  *
    772  *      cDateSep is used as a date separator (e.g. '.').
    773  *      This can be queried using:
    774  +          prfhQueryProfileChar(HINI_USER, "PM_National", "sDate", '/');
    775  *
    776  *      Alternatively, you can query all the country settings
    777  *      at once using prfhQueryCountrySettings (prfh.c).
    778  *
    779  *@@changed V0.9.0 (99-11-07) [umoeller]: now calling strhDateTime
    780  */
    781 
    782 VOID strhFileDate(PSZ pszBuf,           // out: string returned
    783                   FDATE *pfDate,        // in: date information
    784                   ULONG ulDateFormat,   // in: date format (0-3)
    785                   CHAR cDateSep)        // in: date separator (e.g. '.')
    786 {
    787     DATETIME dt;
    788     dt.day = pfDate->day;
    789     dt.month = pfDate->month;
    790     dt.year = pfDate->year + 1980;
    791 
    792     strhDateTime(pszBuf,
    793                  NULL,          // no time
    794                  &dt,
    795                  ulDateFormat,
    796                  cDateSep,
    797                  0, 0);         // no time
    798 }
    799 
    800 /*
    801  *@@ strhFileTime:
    802  *      converts file time data to a string (to pszBuf).
    803  *      You can pass any FTIME structure to this function,
    804  *      which are returned in those FILEFINDBUF* or
    805  *      FILESTATUS* structs by the Dos* functions.
    806  *
    807  *      ulTimeFormat is the PM setting for the time format,
    808  *      as set in the "Country" object, and can be queried using
    809  +              PrfQueryProfileInt(HINI_USER, "PM_National", "iTime", 0);
    810  *      meaning:
    811  *      --  0   12-hour clock
    812  *      --  >0  24-hour clock
    813  *
    814  *      cDateSep is used as a time separator (e.g. ':').
    815  *      This can be queried using:
    816  +              prfhQueryProfileChar(HINI_USER, "PM_National", "sTime", ':');
    817  *
    818  *      Alternatively, you can query all the country settings
    819  *      at once using prfhQueryCountrySettings (prfh.c).
    820  *
    821  *@@changed V0.8.5 (99-03-15) [umoeller]: fixed 12-hour crash
    822  *@@changed V0.9.0 (99-11-07) [umoeller]: now calling strhDateTime
    823  */
    824 
    825 VOID strhFileTime(PSZ pszBuf,           // out: string returned
    826                   FTIME *pfTime,        // in: time information
    827                   ULONG ulTimeFormat,   // in: 24-hour time format (0 or 1)
    828                   CHAR cTimeSep)        // in: time separator (e.g. ':')
    829 {
    830     DATETIME dt;
    831     dt.hours = pfTime->hours;
    832     dt.minutes = pfTime->minutes;
    833     dt.seconds = pfTime->twosecs * 2;
    834 
    835     strhDateTime(NULL,          // no date
    836                  pszBuf,
    837                  &dt,
    838                  0, 0,          // no date
    839                  ulTimeFormat,
    840                  cTimeSep);
    841 }
    842 
    843 /*
    844  *@@ strhDateTime:
    845  *      converts Control Program DATETIME info
    846  *      into two strings. See strhFileDate and strhFileTime
    847  *      for more detailed parameter descriptions.
    848  *
    849  *@@added V0.9.0 (99-11-07) [umoeller]
    850  */
    851 
    852 VOID strhDateTime(PSZ pszDate,          // out: date string returned (can be NULL)
    853                   PSZ pszTime,          // out: time string returned (can be NULL)
    854                   DATETIME *pDateTime,  // in: date/time information
    855                   ULONG ulDateFormat,   // in: date format (0-3); see strhFileDate
    856                   CHAR cDateSep,        // in: date separator (e.g. '.')
    857                   ULONG ulTimeFormat,   // in: 24-hour time format (0 or 1); see strhFileTime
    858                   CHAR cTimeSep)        // in: time separator (e.g. ':')
    859 {
    860     if (pszDate)
    861     {
    862         switch (ulDateFormat)
    863         {
    864             case 0:  // mm.dd.yyyy  (English)
    865                 sprintf(pszDate, "%02d%c%02d%c%04d",
    866                     pDateTime->month,
    867                         cDateSep,
    868                     pDateTime->day,
    869                         cDateSep,
    870                     pDateTime->year);
    871             break;
    872 
    873             case 1:  // dd.mm.yyyy  (e.g. German)
    874                 sprintf(pszDate, "%02d%c%02d%c%04d",
    875                     pDateTime->day,
    876                         cDateSep,
    877                     pDateTime->month,
    878                         cDateSep,
    879                     pDateTime->year);
    880             break;
    881 
    882             case 2: // yyyy.mm.dd  (Japanese)
    883                 sprintf(pszDate, "%04d%c%02d%c%02d",
    884                     pDateTime->year,
    885                         cDateSep,
    886                     pDateTime->month,
    887                         cDateSep,
    888                     pDateTime->day);
    889             break;
    890 
    891             default: // yyyy.dd.mm
    892                 sprintf(pszDate, "%04d%c%02d%c%02d",
    893                     pDateTime->year,
    894                         cDateSep,
    895                     pDateTime->day,
    896                         cDateSep,
    897                     pDateTime->month);
    898             break;
    899         }
    900     }
    901 
    902     if (pszTime)
    903     {
    904         if (ulTimeFormat == 0)
    905         {
    906             // for 12-hour clock, we need additional INI data
    907             CHAR szAMPM[10] = "err";
    908 
    909             if (pDateTime->hours > 12)
    910             {
    911                 // > 12h: PM.
    912 
    913                 // Note: 12:xx noon is 12 AM, not PM (even though
    914                 // AM stands for "ante meridiam", but English is just
    915                 // not logical), so that's handled below.
    916 
    917                 PrfQueryProfileString(HINI_USER,
    918                     "PM_National",
    919                     "s2359",        // key
    920                     "PM",           // default
    921                     szAMPM, sizeof(szAMPM)-1);
    922                 sprintf(pszTime, "%02d%c%02d%c%02d %s",
    923                     // leave 12 == 12 (not 0)
    924                     pDateTime->hours % 12,
    925                         cTimeSep,
    926                     pDateTime->minutes,
    927                         cTimeSep,
    928                     pDateTime->seconds,
    929                     szAMPM);
    930             }
    931             else
    932             {
    933                 // <= 12h: AM
    934                 PrfQueryProfileString(HINI_USER,
    935                                       "PM_National",
    936                                       "s1159",        // key
    937                                       "AM",           // default
    938                                       szAMPM, sizeof(szAMPM)-1);
    939                 sprintf(pszTime, "%02d%c%02d%c%02d %s",
    940                     pDateTime->hours,
    941                         cTimeSep,
    942                     pDateTime->minutes,
    943                         cTimeSep,
    944                     pDateTime->seconds,
    945                     szAMPM);
    946             }
    947         }
    948         else
    949             // 24-hour clock
    950             sprintf(pszTime, "%02d%c%02d%c%02d",
    951                 pDateTime->hours,
    952                     cTimeSep,
    953                 pDateTime->minutes,
    954                     cTimeSep,
    955                 pDateTime->seconds);
    956     }
    957653}
    958654
  • trunk/src/helpers/tmsgfile.c

    r102 r108  
    22/*
    33 *@@sourcefile tmsgfile.c:
    4  *      contains a "text message file" helper function,
    5  *      which works similar to DosGetMessage. See
    6  *      tmfGetMessage for details.
    7  *
    8  *      tmfGetMessage operates on plain-text ".TMF" files.
    9  *      The file is "compiled" into the file's extended
    10  *      attributes for faster access after the first access.
    11  *      When the file's contents change, the EAs are recompiled
    12  *      automatically.
    13  *
    14  *      This has the following advantages over DosGetMessage:
     4 *      replacement code for DosGetMessage for decent NLS support.
     5 *
     6 *      This code has the following advantages over DosGetMessage:
    157 *
    168 *      1)  No external utility is necessary to change message
     
    2113 *          only numerical IDs.
    2214 *
    23  *      This file is entirely new with V0.9.0.
     15 *      The .TMF file must have the following format:
     16 *
     17 *      1)  Any message must start on the beginning of a line
     18 *          and look like this:
     19 *
     20 +              <--MSGID-->: message text
     21 *
     22 *          "MSGID" can be any string and will serve as the
     23 *          message identifier for tmfGetMessage.
     24 *          Leading spaces after "-->:" will be ignored.
     25 *
     26 *      2)  The message text may span across several lines.
     27 *          If so, the line breaks are returned as plain
     28 *          newline (\n) characters by tmfGetMessage.
     29 *
     30 *      3)  Comments in the file are supported if they start
     31 *          with a semicolon (";") at the beginning of a line.
     32 *          Any following text is ignored until the next
     33 *          message ID.
     34 *
     35 *      This file was originally added V0.9.0. The original
     36 *      code was contributed by Christian Langanke, but this
     37 *      has been completely rewritten with V0.9.16 to use my
     38 *      fast string functions now. Also, tmfGetMessage requires
     39 *      tmfOpenMessageFile to be called beforehand.
    2440 *
    2541 *      Usage: All OS/2 programs.
     
    2844 *      --  tmf*   text message file functions
    2945 *
    30  *      This code uses only C standard library functions
    31  *      which are also part of the subsystem libraries.
    32  *      It does _not_ use the fopen etc. functions, but
    33  *      DosOpen etc. instead.
    34  *      You can therefore use this code with your software
    35  *      which uses the subsystem libraries only.
    36  *
    37  *      This code was kindly provided by Christian Langanke.
    38  *      Modifications April 1999 by Ulrich M”ller. Any
    39  *      substantial changes (other than comments and
    40  *      formatting) are marked with (*UM).
    41  *
    4246 *      Note: Version numbering in this file relates to XWorkplace version
    4347 *            numbering.
     
    4852
    4953/*
    50  *      Copyright (C) 1999 Christian Langanke.
    51  *      Copyright (C) 1999-2000 Ulrich M”ller.
     54 *      Copyright (C) 2001 Ulrich M”ller.
    5255 *      This file is part of the "XWorkplace helpers" source package.
    5356 *      This is free software; you can redistribute it and/or modify
     
    6871#define INCL_DOSFILEMGR
    6972#define INCL_DOSMISC
    70 #define INCL_DOSNLS
    7173#define INCL_DOSERRORS
    7274#include <os2.h>
     
    7981#include "setup.h"                      // code generation and debugging options
    8082
     83#include "helpers\dosh.h"
    8184#include "helpers\eah.h"
     85#include "helpers\standards.h"
     86#include "helpers\stringh.h"
     87#include "helpers\tree.h"
     88#include "helpers\xstring.h"
     89
    8290#include "helpers\tmsgfile.h"
    8391
     
    93101 ********************************************************************/
    94102
    95 // extended attribute used for timestamp; written to .TMF file
    96 #define EA_TIMESTAMP "TMF.FILEINFO"
    97 // extended attribute used for compiled text file; written to .TMF file
    98 #define EA_MSGTABLE  "TMF.MSGTABLE"
    99 
    100 #define NEWLINE "\n"
    101 
    102 // start-of-msgid marker
    103 #define MSG_NAME_START   "\r\n<--"
    104 // end-of-msgid marker
    105 #define MSG_NAME_END     "-->:"       // fixed: the space had to be removed, because
    106                                       // if a newline was the first character after ":",
    107                                       // we got complete garbage (crashes) (99-10-23) [umoeller]
    108 // comment marker
    109 #define MSG_COMMENT_LINE "\r\n;"
    110 
    111 // internal prototypes
    112 APIRET          CompileMsgTable(PSZ pszMessageFile, PBYTE * ppbTableData);
    113 APIRET          GetTimeStamp(PFILESTATUS3 pfs3, PSZ pszBuffer, ULONG ulBufferlen);
     103/*
     104 *@@ MSGENTRY:
     105 *
     106 *@@added V0.9.16 (2001-10-08) [umoeller]
     107 */
     108
     109typedef struct _MSGENTRY
     110{
     111    TREE    Tree;               // ulKey points to strID.psz
     112    XSTRING strID;              // message ID
     113    ULONG   ulOfsText;          // offset of start of text (in C-format buffer)
     114    ULONG   cbText;             // length of text in msg file
     115} MSGENTRY, *PMSGENTRY;
     116
     117// globals
     118static PCSZ     G_pcszStartMarker = "\n<--",
     119                G_pcszEndMarker = "-->:";
    114120
    115121/* ******************************************************************
    116122 *
    117  *   Text Message File Code
     123 *   Functions
    118124 *
    119125 ********************************************************************/
    120126
    121127/*
    122  *@@ tmfGetMessage:
    123  *      just like DosGetMessage, except that this does not
    124  *      take a simple message number for the message in the
    125  *      given message file, but a PSZ message identifier
    126  *      (pszMessageName).
    127  *
    128  *      This function automatically compiles the given .TMF
    129  *      file into the file's extended attributes, if we find
    130  *      that this is necessary, by calling CompileMsgTable.
    131  *
    132  *      Note that for compatibily, this function performs the
    133  *      same brain-dead string processing as DosGetMessage, that
    134  *      is, the return string is _not_ null-terminated, and
    135  *      trailing newline characters are _not_ cut off.
    136  *
    137  *      If you don't like this, call tmfGetMessageExt, which
    138  *      calls this function in turn.
    139  *
    140  *      <B>Returns:</B>
    141  *      --  ERROR_INVALID_PARAMETER
    142  *      --  ERROR_BUFFER_OVERFLOW
    143  *      --  ERROR_MR_MID_NOT_FOUND
    144  *      --  ERROR_MR_INV_MSGF_FORMAT
    145  *      --  ERROR_BUFFER_OVERFLOW
    146  *
    147  *      plus the error codes of DosOpen, DosRead, DosClose.
    148  */
    149 
    150 APIRET tmfGetMessage(PCHAR* pTable,    // in: pointer table for string insertion
    151                      ULONG cTable,     // in: number of pointers in *pTable
    152                      PBYTE pbBuffer,   // out: returned string
    153                      ULONG cbBuffer,   // out: sizeof(*pbBuffer)
    154                      PCSZ pszMessageName,  // in: message identifier
    155                      PCSZ pszFile,      // in: message file (.TMF extension proposed)
    156                      PULONG pcbMsg)    // out: bytes written to *pbBuffer
     128 *@@ tmfOpenMessageFile:
     129 *      opens a .TMF message file for future use
     130 *      with tmfGetMessage.
     131 *
     132 *      Use tmfCloseMessageFile to close the file
     133 *      again and free all resources. This thing
     134 *      can allocate quite a bit of memory.
     135 *
     136 *      Returns:
     137 *
     138 *      --  NO_ERROR: *ppMsgFile has received the
     139 *          new TMFMSGFILE structure.
     140 *
     141 *      --  ERROR_NOT_ENOUGH_MEMORY
     142 *
     143 *      plus any of the errors of doshLoadTextFile,
     144 *      such as ERROR_FILE_NOT_FOUND.
     145 *
     146 *@@added V0.9.16 (2001-10-08) [umoeller]
     147 */
     148
     149APIRET tmfOpenMessageFile(const char *pcszMessageFile, // in: fully q'fied .TMF file name
     150                          PTMFMSGFILE *ppMsgFile)     // out: TMFMSGFILE struct
    157151{
    158     // fixed UM 99-10-22: now initializing all vars to 0,
    159     // because ulBytesRead might be returned from this func
    160     APIRET          rc = NO_ERROR;
    161     CHAR            szMessageFile[_MAX_PATH];
    162     PBYTE           pbTableData = NULL;
    163     PSZ             pszEntry = 0;
    164     PSZ             pszEndOfEntry = 0;
    165     ULONG           ulMessagePos = 0;
    166     ULONG           ulMessageLen = 0;
    167 
    168     HFILE           hfile = NULLHANDLE;
    169     ULONG           ulFilePtr = 0;
    170     ULONG           ulAction = 0;
    171     ULONG           ulBytesToRead = 0;
    172     ULONG           ulBytesRead = 0;
    173 
    174     do
     152    APIRET arc;
     153    PSZ pszContent = NULL;
     154
     155    if (!(arc = doshLoadTextFile(pcszMessageFile,
     156                                 &pszContent)))
    175157    {
    176         // check parms
    177         if ((!pbBuffer) ||
    178             (!cbBuffer) ||
    179             (!pszMessageName) ||
    180             (!*pszMessageName) ||
    181             (!*pszFile))
     158        // file loaded:
     159        // create a TMFMSGFILE entry
     160        PTMFMSGFILE pFile;
     161        if (!(pFile = NEW(TMFMSGFILE)))
    182162        {
    183             rc = ERROR_INVALID_PARAMETER;
    184             break;
     163            arc = ERROR_NOT_ENOUGH_MEMORY;
     164            free(pszContent);
    185165        }
    186 
    187         if (cbBuffer < 2)
    188         {
    189             rc = ERROR_BUFFER_OVERFLOW;
    190             break;
    191         }
    192 
    193         // search file
    194         if ((strchr(pszFile, ':')) ||
    195             (strchr(pszFile, '\\')) ||
    196             (strchr(pszFile, '/')))
    197             // drive and/or path given: no search in path
    198             strcpy(szMessageFile, pszFile);
    199166        else
    200167        {
    201             // only filename, search in current dir and DPATH
    202             rc = DosSearchPath(SEARCH_IGNORENETERRS
    203                                | SEARCH_ENVIRONMENT
    204                                | SEARCH_CUR_DIRECTORY,
    205                                "DPATH",
    206                                (PSZ)pszFile,
    207                                szMessageFile,
    208                                sizeof(szMessageFile));
    209             if (rc != NO_ERROR)
    210                 break;
    211         }
    212 
    213         // _Pmpf(("tmfGetMessage: Found %s", szMessageFile));
    214 
    215         // compile table if neccessary
    216         rc = CompileMsgTable(szMessageFile, &pbTableData);
    217         if (rc != NO_ERROR)
    218             break;
    219 
    220         // _Pmpf(("tmfGetMessage: Now searching compiled file"));
    221 
    222         // search the name
    223         pszEntry = strstr(pbTableData, pszMessageName);
    224         if (!pszEntry)
    225         {
    226             rc = ERROR_MR_MID_NOT_FOUND;
    227             break;
    228         }
    229         else
    230             pszEntry += strlen(pszMessageName) + 1;
    231 
    232         // isolate entry
    233         pszEndOfEntry = strchr(pszEntry, '\n');
    234         if (pszEndOfEntry)
    235             *pszEndOfEntry = 0;
    236 
    237         // get numbers
    238         ulMessagePos = atol(pszEntry);
    239         if (ulMessagePos == 0)
    240             if (!pszEntry)
     168            // TMFMSGFILE created:
     169
     170            PCSZ    pStartOfFile,
     171                    pStartOfMarker;
     172
     173            ULONG   ulStartMarkerLength = strlen(G_pcszStartMarker),
     174                    ulEndMarkerLength = strlen(G_pcszEndMarker);
     175
     176            // initialize TMFMSGFILE struct
     177            ZERO(pFile);
     178            pFile->pszFilename = strdup(pcszMessageFile);
     179            treeInit(&pFile->IDsTreeRoot);
     180
     181            xstrInitSet(&pFile->strContent, pszContent);
     182
     183            // convert to plain C format
     184            xstrConvertLineFormat(&pFile->strContent,
     185                                  CRLF2LF);
     186
     187            // kick out all the comments
     188            while (pStartOfMarker = strstr(pFile->strContent.psz, "\n;"))
    241189            {
    242                 rc = ERROR_MR_INV_MSGF_FORMAT;
    243                 break;
     190                // copy the next line over this
     191                PCSZ pEOL = strhFindEOL(pStartOfMarker + 2, NULL);
     192                /* printf("pStartOfMarker = %lX, pEOL = %lX\n",
     193                        pStartOfMarker,
     194                        pEOL); */
     195                xstrrpl(&pFile->strContent,
     196                        // ofs of first char to replace: "\n;"
     197                        pStartOfMarker - pFile->strContent.psz,
     198                        // no. of chars to replace:
     199                        pEOL - pStartOfMarker,
     200                        // string to replace chars with:
     201                        NULL,
     202                        // length of replacement string:
     203                        0);
    244204            }
    245205
    246         pszEntry = strchr(pszEntry, ' ');
    247         if (!pszEntry)
    248         {
    249             rc = ERROR_MR_INV_MSGF_FORMAT;
    250             break;
    251         }
    252         ulMessageLen = atol(pszEntry);
    253 
    254         // determine maximum read len
    255         ulBytesToRead = _min(ulMessageLen, cbBuffer);
    256 
    257         // open file and read message
    258         rc = DosOpen((PSZ)pszFile,
    259                      &hfile,
    260                      &ulAction,
    261                      0, 0,
    262                      OPEN_ACTION_FAIL_IF_NEW
    263                      | OPEN_ACTION_OPEN_IF_EXISTS,
    264                      OPEN_FLAGS_FAIL_ON_ERROR
    265                      | OPEN_SHARE_DENYWRITE
    266                      | OPEN_ACCESS_READONLY,
    267                      NULL);
    268         if (rc != NO_ERROR)
    269             break;
    270 
    271         rc = DosSetFilePtr(hfile, ulMessagePos, FILE_BEGIN, &ulFilePtr);
    272         if ((rc != NO_ERROR) || (ulFilePtr != ulMessagePos))
    273             break;
    274 
    275         rc = DosRead(hfile,
    276                      pbBuffer,
    277                      ulBytesToRead,
    278                      &ulBytesRead);
    279         if (rc != NO_ERROR)
    280             break;
    281 
    282         // report "buffer too small" here
    283         if (ulBytesToRead < ulMessageLen)
    284             rc = ERROR_BUFFER_OVERFLOW;
    285 
    286     }
    287     while (FALSE);
    288 
    289     // replace string placeholders ("%1" etc.) (*UM)
    290     if (rc == NO_ERROR)     // added (99-10-24) [umoeller]
    291         if (cTable)
    292         {
    293             // create a temporary buffer for replacements
    294             PSZ             pszTemp = (PSZ)malloc(cbBuffer);
    295 
    296             if (!pszTemp)
    297                 rc = ERROR_NOT_ENOUGH_MEMORY;
     206            // free excessive memory
     207            xstrShrink(&pFile->strContent);
     208
     209            pStartOfFile = pFile->strContent.psz;
     210
     211            // go build a tree of all message IDs...
     212
     213            // find first start message marker
     214            pStartOfMarker = strstr(pStartOfFile,
     215                                    G_pcszStartMarker);     // start-of-line marker
     216            while (    (pStartOfMarker)
     217                    && (!arc)
     218                  )
     219            {
     220                // start marker found:
     221                PCSZ pStartOfMsgID = pStartOfMarker + ulStartMarkerLength;
     222                // search next start marker
     223                PCSZ pStartOfNextMarker = strstr(pStartOfMsgID + 1,
     224                                                 G_pcszStartMarker);
     225                // and the end-marker
     226                PCSZ pEndOfMarker = strstr(pStartOfMsgID + 1,
     227                                           G_pcszEndMarker);
     228
     229                PMSGENTRY pNew;
     230
     231                // sanity checks...
     232
     233                if (    (pStartOfNextMarker)
     234                     && (pStartOfNextMarker < pEndOfMarker)
     235                   )
     236                {
     237                    // next start marker before end marker:
     238                    // that doesn't look correct, skip this entry
     239                    pStartOfMarker = pStartOfNextMarker;
     240                    continue;
     241                }
     242
     243                if (!pEndOfMarker)
     244                    // no end marker found:
     245                    // that's invalid too, and there can't be any
     246                    // message left in the file then...
     247                    break;
     248
     249                // alright, this ID looks correct now
     250                if (!(pNew = NEW(MSGENTRY)))
     251                    arc = ERROR_NOT_ENOUGH_MEMORY;
     252                else
     253                {
     254                    // length of the ID
     255                    ULONG ulIDLength = pEndOfMarker - pStartOfMsgID;
     256                    PCSZ pStartOfText = pEndOfMarker + ulEndMarkerLength;
     257
     258                    ZERO(pNew);
     259
     260                    // copy the string ID (between start and end markers)
     261                    xstrInit(&pNew->strID, 0);
     262                    xstrcpy(&pNew->strID,
     263                            pStartOfMsgID,
     264                            ulIDLength);
     265                    // make ulKey point to the string ID for tree sorting
     266                    pNew->Tree.ulKey = (ULONG)pNew->strID.psz;
     267
     268                    // skip leading spaces
     269                    while (*pStartOfText == ' ')
     270                        pStartOfText++;
     271
     272                    // store start of text
     273                    pNew->ulOfsText = pStartOfText - pStartOfFile;
     274
     275                    // check if there's a comment before the
     276                    // next item
     277                    /* if (pNextComment = strstr(pStartOfText, "\n;"))
     278                    {
     279                        if (    (!pStartOfNextMarker)
     280                             || (pNextComment < pStartOfNextMarker)
     281                           )
     282                            pEndOfText = pNextComment;
     283                    } */
     284
     285                    if (pStartOfNextMarker)
     286                        // other markers left:
     287                        pNew->cbText =    // offset of next marker
     288                                         (pStartOfNextMarker - pStartOfFile)
     289                                       - pNew->ulOfsText;
     290                    else
     291                        // this was the last message:
     292                        pNew->cbText = strlen(pStartOfText);
     293
     294                    // store this thing
     295                    if (!treeInsert(&pFile->IDsTreeRoot,
     296                                    (TREE*)pNew,
     297                                    treeCompareStrings))
     298                        // successfully inserted:
     299                        (pFile->cIDs)++;
     300                }
     301
     302                // go on with next start marker (can be NULL)
     303                pStartOfMarker = pStartOfNextMarker;
     304            } // end while (    (pStartOfMarker) ...
     305
     306            // done with IDs, or error occured:
     307            if (!arc)
     308                // output
     309                *ppMsgFile = pFile;
    298310            else
    299             {
    300                 // two pointers for copying
    301                 PSZ             pSource = pbBuffer,
    302                                 pTarget = pszTemp;
    303 
    304                 CHAR            szMsgNum[5] = "0";
    305                 ULONG           ulTableIndex = 0;
    306 
    307                 ULONG           ulCount = 0, ulTargetWritten = 0;
    308 
    309                 // 1) copy the stuff we've read to the
    310                 // new temporary buffer
    311                 for (ulCount = 0;
    312                      ulCount < ulBytesRead;
    313                      ulCount++)
    314                     *pTarget++ = *pSource++;
    315 
    316                 // 2) now go thru the source string
    317                 // (which we've read above) and
    318                 // look for "%" characters; we do
    319                 // this while copying the stuff
    320                 // back to pbBuffer
    321 
    322                 pSource = pszTemp;
    323                 pTarget = pbBuffer;
    324 
    325                 for (ulCount = 0;
    326                      ulCount < ulBytesRead;
    327                      ulCount++)
    328                 {
    329                     if (*pSource == '%')
    330                     {
    331                         // copy the index (should be > 0)
    332                         szMsgNum[0] = *(pSource + 1);
    333                         // szMsgNum[1] is still 0
    334 
    335                         // Pmpf(("      Found %s", szMsgNum));
    336 
    337                         ulTableIndex = atoi(szMsgNum);
    338                         // _Pmpf(("        --> %d", ulTableIndex));
    339                         if ((ulTableIndex != 0)
    340                             && (ulTableIndex <= cTable)
    341                             )
    342                         {
    343                             // valid index:
    344                             // insert stuff from table
    345                             PSZ            *ppTableThis = (PSZ*)(pTable + (ulTableIndex - 1));
    346 
    347                             // (pTable) if 1, (pTable+1) if 2, ...
    348                             PSZ             pTableSource = *ppTableThis;
    349 
    350                             // copy string from table
    351                             // and increase the target pointer
    352                             while ((*pTarget++ = *pTableSource++))
    353                                 ulTargetWritten++;
    354 
    355                             // increase source pointer to point
    356                             // behind the "%x"
    357                             pSource += 2;
    358                             // decrease target again, because
    359                             // we've copied a null-byte
    360                             pTarget--;
    361 
    362                             ulCount++;
    363                             // next for
    364                             continue;
    365                         }
    366                         // else invalid index: just copy
    367                     }
    368 
    369                     // regular character: copy
    370                     *pTarget++ = *pSource++;
    371                     ulTargetWritten++;
    372                 }                   // end for (ulCount = 0) ...
    373 
    374                 ulBytesRead = ulTargetWritten;
    375 
    376                 free(pszTemp);      // V0.9.9 (2001-03-13) [umoeller]
    377             } // if pszTemp
    378         }                           // end if (cTable)
    379 
    380     // report bytes written (*UM)
    381     if (pcbMsg)
    382         *pcbMsg = ulBytesRead;
    383 
    384     // cleanup
    385     if (hfile)
    386         DosClose(hfile);
    387     if (pbTableData)
    388         free(pbTableData);
    389 
    390     return (rc);
    391 }
    392 
    393 /*
    394  *@@ tmfGetMessageExt:
    395  *      just like tmfGetMessage, but this func is smart
    396  *      enough to return a zero-terminated string and
    397  *      strip trailing newlines.
    398  *
    399  *      See tmfGetMessage for details.
    400  */
    401 
    402 APIRET tmfGetMessageExt(PCHAR* pTable,    // in: pointer table for string insertion
    403                         ULONG cTable,     // in: number of pointers in *pTable
    404                         PBYTE pbBuffer,   // out: returned string
    405                         ULONG cbBuffer,   // out: sizeof(*pbBuffer)
    406                         PCSZ pszMessageName,  // in: message identifier
    407                         PCSZ pszFile,      // in: message file (.TMF extension proposed)
    408                         PULONG pcbMsg)    // out: bytes written to *pbBuffer
    409 {
    410     APIRET  arc = NO_ERROR;
    411     ULONG   cbReturned = 0;
    412     arc = tmfGetMessage(pTable, cTable, pbBuffer, cbBuffer, pszMessageName, pszFile,
    413                         &cbReturned);
    414 
    415     if (arc == NO_ERROR)
    416     {
    417         PSZ p = pbBuffer;
    418 
    419         // terminate string
    420         if (cbReturned < cbBuffer)
    421             *(pbBuffer+cbReturned) = 0;
    422         else
    423             *(pbBuffer+cbBuffer-1) = 0;
    424 
    425         // remove leading spaces (99-10-24) [umoeller]
    426         while (*p == ' ')
    427             p++;
    428         if (p != pbBuffer)
    429         {
    430             // we have leading spaces:
    431             strcpy(pbBuffer, p);
    432             // decrease byte count
    433             cbReturned -= (p - pbBuffer);
    434         }
    435 
    436         // remove trailing newlines
    437         while (TRUE)
    438         {
    439             p = pbBuffer + strlen(pbBuffer) - 1;
    440             if (    (*p == '\n')
    441                  || (*p == '\r')
    442                )
    443             {
    444                 *p = '\0';
    445             } else
    446                 break; // while (TRUE)
    447         }
    448     }
    449 
    450     if (pcbMsg)
    451         *pcbMsg = cbReturned;
     311                // error:
     312                tmfCloseMessageFile(&pFile);
     313
     314        } // end else if (!(pFile = NEW(TMFMSGFILE)))
     315    } // end if (!(arc = doshLoadTextFile(pcszMessageFile,
    452316
    453317    return (arc);
     
    455319
    456320/*
    457  *@@ CompileMsgTable:
    458  *      this gets called from tmfGetMessage.
    459  *      Here we check for whether the given
    460  *      message file has been compiled to the
    461  *      EAs yet or if the compilation is
    462  *      outdated.
    463  *
    464  *      If we need recompilation, we do this here.
    465  *      Memory for the compiled message table is
    466  *      allocated here using malloc(), and the
    467  *      buffer is stored in ppbTableData. You
    468  *      must free() this buffer after using this
    469  *      function.
    470  *
    471  *      <B>Returns:</B>
     321 *@@ tmfCloseMessageFile:
     322 *      closes a message file opened by
     323 *      tmfOpenMessageFile, frees all resources,
     324 *      and sets *ppMsgFile to NULL for safety.
     325 *
     326 *@@added V0.9.16 (2001-10-08) [umoeller]
     327 */
     328
     329APIRET tmfCloseMessageFile(PTMFMSGFILE *ppMsgFile)
     330{
     331    if (ppMsgFile && *ppMsgFile)
     332    {
     333        PTMFMSGFILE pFile = *ppMsgFile;
     334        ULONG   cItems;
     335        TREE**  papNodes;
     336
     337        if (pFile->pszFilename)
     338            free(pFile->pszFilename);
     339        xstrClear(&pFile->strContent);
     340
     341        if (cItems = pFile->cIDs)
     342        {
     343            if (papNodes = treeBuildArray(pFile->IDsTreeRoot,
     344                                          &cItems))
     345            {
     346                ULONG ul;
     347                for (ul = 0; ul < cItems; ul++)
     348                {
     349                    PMSGENTRY pNodeThis = (PMSGENTRY)(papNodes[ul]);
     350
     351                    xstrClear(&pNodeThis->strID);
     352
     353                    free(pNodeThis);
     354                }
     355
     356                free(papNodes);
     357            }
     358        }
     359
     360        free(pFile);
     361        *ppMsgFile = NULL;
     362
     363        return (NO_ERROR);
     364    }
     365
     366    return (ERROR_INVALID_PARAMETER);
     367}
     368
     369/*
     370 *@@ tmfGetMessage:
     371 *      replacement for DosGetMessage.
     372 *
     373 *      After you have opened a .TMF file with tmfOpenMessageFile,
     374 *      you can pass it to this function to retrieve a message
     375 *      with the given string (!) ID. See tmsgfile.c for details.
     376 *
     377 *      Note that this will invoke xstrcpy on the given XSTRING
     378 *      buffer. In other words, the string must be initialized
     379 *      (see xstrInit), but will be replaced.
     380 *
     381 *      This does perform the same simple string replacements
     382 *      as DosGetMessage, that is, the string "%1" will be
     383 *      replaced with pTable[0], "%2" will be replaced with
     384 *      pTable[1], and so on.
     385 *
     386 *      Returns:
     387 *
     388 *      --  NO_ERROR;
     389 *
    472390 *      --  ERROR_INVALID_PARAMETER
    473  *      --  ERROR_BUFFER_OVERFLOW
    474  *      --  ERROR_NOT_ENOUGH_MEMORY
    475  *      --  ERROR_READ_FAULT
    476  *      --  ERROR_INVALID_DATA
    477  *
    478  *@@changed V0.9.1 (99-12-12) [umoeller]: fixed heap overwrites which caused irregular crashes
    479  *@@changed V0.9.1 (99-12-12) [umoeller]: fixed realloc failure
    480  *@@changed V0.9.1 (99-12-12) [umoeller]: file last-write date is now reset when EAs are written
    481  *@@changed V0.9.1 (2000-02-01) [umoeller]: now skipping leading spaces in msg
    482  *@@todo handle 64KB EA limit
    483  */
    484 
    485 APIRET CompileMsgTable(PSZ pszMessageFile,     // in: file to compile
    486                        PBYTE *ppbTableDataReturn)  // out: compiled message table
     391 *
     392 *      --  ERROR_MR_MID_NOT_FOUND
     393 *
     394 *@@added V0.9.16 (2001-10-08) [umoeller]
     395 */
     396
     397APIRET tmfGetMessage(PTMFMSGFILE pMsgFile,      // in: msg file opened by tmfOpenMessageFile
     398                     PCSZ pcszMessageName,      // in: msg name to look for (case-sensitive!)
     399                     PXSTRING pstr,             // out: message string, if found (XSTRING must be initialized)
     400                     PSZ *pTable,               // in: replacement table or NULL
     401                     ULONG cTableEntries)       // in: count of items in pTable or null
    487402{
    488     APIRET          rc = NO_ERROR;
    489     // CHAR            szMessageFile[_MAX_PATH];
    490 
    491     FILESTATUS3     fs3MessageFile;
    492 
    493     // fixed UM 99-10-22: initializing all vars to 0
    494     ULONG           ulStampLength = 0;
    495     PBYTE           pbFileData = NULL;
    496     ULONG           ulFileDataLength = 0;
    497 
    498     CHAR            szFileStampOld[18] = "";     // yyyymmddhhmmssms.
    499 
    500     CHAR            szFileStampCurrent[18] = "";
    501 
    502     PBYTE           pbTableData = NULL;
    503     ULONG           cbTableDataAllocated = 0;
    504     ULONG           cbTableDataUsed = 0;
    505 
    506     HFILE           hfileMessageFile = NULLHANDLE;
    507     ULONG           ulAction = 0;
    508     ULONG           ulBytesRead = 0;
    509 
    510     COUNTRYCODE     cc = {0, 0};
    511 
    512     ULONG           cbOpenTag = strlen(MSG_NAME_START);
    513     ULONG           cbClosingTag = strlen(MSG_NAME_END);
    514 
    515     do
     403    APIRET arc = NO_ERROR;
     404
     405    if (!pMsgFile)
     406        arc = ERROR_INVALID_PARAMETER;
     407    else
    516408    {
    517         PSZ             pCurrentNameStart = 0;
    518         PSZ             pCurrentNameEnd = 0;
    519         ULONG           ulCurrentMessagePos = 0;
    520         ULONG           ulCurrentMessageLen = 0;
    521         // BOOL            fError = FALSE;
    522 
    523         // check parms
    524         if ((!pszMessageFile) ||
    525             (!ppbTableDataReturn))
     409        // go find the message in the tree
     410        PMSGENTRY pEntry;
     411        if (pEntry = (PMSGENTRY)treeFind(pMsgFile->IDsTreeRoot,
     412                                         (ULONG)pcszMessageName,
     413                                         treeCompareStrings))
    526414        {
    527             rc = ERROR_INVALID_PARAMETER;
    528             break;
    529         }
    530 
    531         // get length and timestamp of file
    532         rc = DosQueryPathInfo(pszMessageFile,
    533                               FIL_STANDARD,
    534                               &fs3MessageFile,
    535                               sizeof(fs3MessageFile));
    536         if (rc != NO_ERROR)
    537             break;
    538         ulFileDataLength = fs3MessageFile.cbFile;
    539 
    540         // determine current timestamp
    541         GetTimeStamp(&fs3MessageFile, szFileStampCurrent, sizeof(szFileStampCurrent));
    542 
    543         // _Pmpf(("    Timestamp for %s: '%s'", pszMessageFile, szFileStampCurrent));
    544 
    545         // determine saved timestamp
    546         ulStampLength = sizeof(szFileStampOld);
    547         rc = eahReadStringEA(pszMessageFile,
    548                           EA_TIMESTAMP,
    549                           szFileStampOld,
    550                           &ulStampLength);
    551 
    552         // _Pmpf(("    Saved timestamp for %s: '%s'", pszMessageFile, szFileStampOld));
    553 
    554         // compare timestamps
    555         if ((rc == NO_ERROR)
    556             && (ulStampLength == (strlen(szFileStampCurrent) + 1))
    557             && (!strcmp(szFileStampCurrent, szFileStampOld))
    558             )
    559         {
    560 
    561             // read table out of EAs
    562             do
     415            // copy the raw string to the output buffer
     416            xstrcpy(pstr,
     417                    pMsgFile->strContent.psz + pEntry->ulOfsText,
     418                    pEntry->cbText);
     419
     420            // now replace strings from the table
     421            if (cTableEntries && pTable)
    563422            {
    564                 // get ea length of table
    565                 rc = eahReadStringEA(pszMessageFile,
    566                                   EA_MSGTABLE,
    567                                   NULL, &cbTableDataAllocated);
    568                 if (rc != ERROR_BUFFER_OVERFLOW)
    569                     break;
    570 
    571                 // get memory
    572                 if ((pbTableData = (PBYTE)malloc(cbTableDataAllocated)) == NULL)
     423                CHAR szFind[34] = "%0";
     424                ULONG ul;
     425                for (ul = 0;
     426                     ul < cTableEntries;
     427                     ul++)
    573428                {
    574                     rc = ERROR_NOT_ENOUGH_MEMORY;
    575                     break;
    576                 }
    577 
    578                 // read table
    579                 rc = eahReadStringEA(pszMessageFile,
    580                                   EA_MSGTABLE,
    581                                   pbTableData, &cbTableDataAllocated);
    582 
    583             }
    584             while (FALSE);
    585 
    586             // if no error occurred, we are finished
    587             if (rc == NO_ERROR)
    588             {
    589                 // _Pmpf(("      --> using precompiled table"));
    590                 break;
    591             }
    592         } // end if
    593 
    594         // _Pmpf(("      --> recompiling table"));
    595 
    596         // recompilation needed:
    597         // get memory for file data
    598         if ((pbFileData = (PBYTE)malloc(ulFileDataLength + 1)) == NULL)
    599         {
    600             rc = ERROR_NOT_ENOUGH_MEMORY;
    601             break;
    602         }
    603         *(pbFileData + ulFileDataLength) = 0;
    604 
    605         // get memory for table data
    606         cbTableDataAllocated = ulFileDataLength / 2;
    607         if ((pbTableData = (PBYTE)malloc(cbTableDataAllocated)) == NULL)
    608         {
    609             rc = ERROR_NOT_ENOUGH_MEMORY;
    610             break;
    611         }
    612 
    613         *pbTableData = 0;
    614                 // fixed V0.9.1 (99-12-12);
    615                 // this was
    616                 //      *(pbTableData + cbTableDataAllocated) = 0;
    617                 // since we're using "strcat" below to write into
    618                 // the table data, this wasn't such a good idea
    619 
    620         // open file and read it
    621         rc = DosOpen(pszMessageFile,
    622                      &hfileMessageFile,
    623                      &ulAction,
    624                      0, 0,
    625                      OPEN_ACTION_FAIL_IF_NEW
    626                      | OPEN_ACTION_OPEN_IF_EXISTS,
    627                      OPEN_FLAGS_FAIL_ON_ERROR
    628                      | OPEN_SHARE_DENYWRITE
    629                      | OPEN_ACCESS_READWRITE,   // needed for EA attachement
    630                       NULL);
    631         if (rc != NO_ERROR)
    632             break;
    633 
    634         rc = DosRead(hfileMessageFile,
    635                      pbFileData,
    636                      ulFileDataLength,
    637                      &ulBytesRead);
    638         if (rc != NO_ERROR)
    639             break;
    640         if (ulBytesRead != ulFileDataLength)
    641         {
    642             rc = ERROR_READ_FAULT;
    643             break;
    644         }
    645 
    646         // search first message name
    647         // this will automatically skip comments
    648         // at the beginning
    649         pCurrentNameStart = strstr(pbFileData, MSG_NAME_START);
    650 
    651         if (!pCurrentNameStart)
    652         {
    653             rc = ERROR_INVALID_DATA;
    654             break;
    655         }
    656         else
    657             pCurrentNameStart += cbOpenTag;
    658                 // this points to message ID string after "<--" now
    659 
    660         // is first name complete ?
    661         pCurrentNameEnd = strstr(pCurrentNameStart, MSG_NAME_END);
    662         if (!pCurrentNameEnd)
    663         {
    664             rc = ERROR_INVALID_DATA;
    665             break;
    666         }
    667 
    668         // scan through all names
    669         while (     (pCurrentNameStart)
    670                  && (*pCurrentNameStart)
    671               )
    672         {
    673             PSZ     pNextNameStart = 0,
    674                     pNextCommentStart = 0,
    675                     pEndOfMsg = 0;
    676             CHAR    szEntry[500] = "";
    677 
    678             // search end of name, if not exist, skip end of file
    679             pCurrentNameEnd = strstr(pCurrentNameStart, MSG_NAME_END);
    680                 // this points to the closing "-->" now
    681             if (!pCurrentNameEnd)
    682                 break;
    683 
    684             // search next name (ID), if none, use end of string
    685             pNextNameStart = strstr(pCurrentNameEnd, MSG_NAME_START);
    686                     // points to next "<--" now
    687             if (!pNextNameStart)
    688                 // not found:
    689                 // use terminating null byte
    690                 pNextNameStart = pCurrentNameStart + strlen(pCurrentNameStart);
    691             else
    692                 // found:
    693                 // point to next message ID string
    694                 pNextNameStart += cbOpenTag;
    695 
    696             pEndOfMsg = pNextNameStart - cbOpenTag;
    697 
    698             // search next comment (99-11-28) [umoeller]
    699             pNextCommentStart = strstr(pCurrentNameEnd, MSG_COMMENT_LINE);
    700             if (pNextCommentStart)
    701                 // another comment found:
    702                 if (pNextCommentStart < pNextNameStart)
    703                     // if it's even before the next key, use that
    704                     // for the end of the current string; otherwise
    705                     // the comment would appear in the message too
    706                     pEndOfMsg = pNextCommentStart;
    707 
    708             // now we have:
    709             // -- pCurrentNameStart: points to message ID after "<--"
    710             // -- pCurrentNameEnd: points to "-->"
    711             // -- pNextNameStart: points to _next_ message ID after "<--"
    712             // -- pNextCommentStart: points to _next_ comment
    713             // -- pEndOfMsg: either pNextNameStart-cbOpenTag
    714             //               or pNextCommentStart,
    715             //               whichever comes first
    716 
    717             // calculate table entry data
    718             *pCurrentNameEnd = 0;
    719             ulCurrentMessagePos = (pCurrentNameEnd - pbFileData) + cbClosingTag;
    720             // this points to the first character after the <-- --> tag now;
    721             // if this points to a space character, take next char
    722             // (V0.9.1 (2000-02-13) [umoeller])
    723             while (     (*(pbFileData + ulCurrentMessagePos))
    724                      && (*(pbFileData + ulCurrentMessagePos) == ' ')
    725                   )
    726                 ulCurrentMessagePos++;
    727 
    728             ulCurrentMessageLen = (pEndOfMsg - pbFileData) - ulCurrentMessagePos;
    729                     // pszNextNameStart - pbFileData - ulCurrentMessagePos - 1;
    730 
    731             // determine entry
    732             sprintf(szEntry, "%s %lu %lu" NEWLINE,
    733                     pCurrentNameStart,
    734                     ulCurrentMessagePos,
    735                     ulCurrentMessageLen);
    736 
    737             /* _Pmpf(("Found %s at %d, length %d",
    738                     pCurrentNameStart,
    739                     ulCurrentMessagePos,
    740                     ulCurrentMessageLen)); */
    741 
    742             // need more space ?
    743             if ((cbTableDataUsed + strlen(szEntry) + 1) > cbTableDataAllocated)
    744             {
    745                 PBYTE           pbTmp;
    746                 // _Pmpf(("  Re-allocating!!"));
    747 
    748                 cbTableDataAllocated += ulFileDataLength / 2;
    749                 pbTmp = (PBYTE)realloc(pbTableData, cbTableDataAllocated);
    750                 if (!pbTmp)
    751                 {
    752                     rc = ERROR_NOT_ENOUGH_MEMORY;
    753                     break;
    754                 }
    755                 else
    756                     pbTableData = pbTmp;
    757             }
    758 
    759             // add entry
    760             strcat(pbTableData, szEntry);
    761             cbTableDataUsed += strlen(szEntry);
    762                     // added V0.9.1 (99-12-12);
    763                     // this was 0 all the time and never raised
    764 
    765             // adress next entry
    766             pCurrentNameStart = pNextNameStart;
    767 
    768         }  // while (pszCurrentNameStart)
    769 
    770         // write new timestamp and table
    771         // @@todo handle 64 kb limit here !!!
    772         if (rc == NO_ERROR)
    773         {
    774             FILESTATUS3 fs3Tmp;
    775 
    776             rc = eahWriteStringEA(hfileMessageFile, EA_TIMESTAMP, szFileStampCurrent);
    777             rc = eahWriteStringEA(hfileMessageFile, EA_MSGTABLE, pbTableData);
    778 
    779             if (rc == NO_ERROR)
    780             {
    781                 // fixed V0.9.1 (99-12-12): we need to reset the file date to
    782                 // the old date,
    783                 // because writing EAs updates the "last write date" also;
    784                 // without this, we'd recompile every single time
    785                 rc = DosQueryFileInfo(hfileMessageFile,
    786                                       FIL_STANDARD,
    787                                       &fs3Tmp,
    788                                       sizeof(fs3Tmp));
    789                 if (rc == NO_ERROR)
    790                 {
    791                     // restore original "last write" date
    792                     // _Pmpf(("Resetting file date"));
    793                     fs3Tmp.fdateLastWrite = fs3MessageFile.fdateLastWrite;
    794                     fs3Tmp.ftimeLastWrite = fs3MessageFile.ftimeLastWrite;
    795                     DosSetFileInfo(hfileMessageFile,
    796                                    FIL_STANDARD,
    797                                    &fs3Tmp,
    798                                    sizeof(fs3Tmp));
     429                    ULONG ulOfs = 0;
     430                    PSZ pszReplThis = pTable[ul];
     431
     432                    _ultoa(ul + 1, szFind + 1, 10);
     433                    while (xstrFindReplaceC(pstr,
     434                                            &ulOfs,
     435                                            szFind,
     436                                            pszReplThis))
     437                        ;
    799438                }
    800439            }
    801440        }
    802     } while (FALSE);
    803 
    804 
    805     if (rc == NO_ERROR)
    806     {
    807         // hand over result
    808         *ppbTableDataReturn = pbTableData;
    809 
    810         // make text uppercase
    811         rc = DosMapCase(cbTableDataAllocated, &cc, pbTableData);
     441        else
     442            arc = ERROR_MR_MID_NOT_FOUND;
    812443    }
     444
     445    return (arc);
     446}
     447
     448/* test case */
     449
     450#ifdef __TMFDEBUG__
     451
     452int main(int argc, char *argv[])
     453{
     454    APIRET arc;
     455    PTMFMSGFILE pMsgFile;
     456
     457    if (argc < 3)
     458        printf("tmsgfile <file> <msgid>\n");
    813459    else
    814460    {
    815         // error occured:
    816         if (pbTableData)
    817             free(pbTableData);
     461        if (!(arc = tmfOpenMessageFile(argv[1], &pMsgFile)))
     462        {
     463            XSTRING str;
     464            xstrInit(&str, 0);
     465            if (!(arc = tmfGetMessage(pMsgFile,
     466                                      argv[2],
     467                                      &str,
     468                                      NULL,
     469                                      0)))
     470            {
     471                printf("String:\n%s", str.psz);
     472            }
     473            else
     474                printf("tmfGetMessage returned %d\n", arc);
     475
     476            xstrClear(&str);
     477
     478            tmfCloseMessageFile(&pMsgFile);
     479        }
     480        else
     481            printf("tmfOpenMessageFile returned %d\n", arc);
    818482    }
    819 
    820     // cleanup
    821     if (pbFileData)
    822         free(pbFileData);
    823     if (hfileMessageFile)
    824         DosClose(hfileMessageFile);
    825 
    826     return rc;
    827483}
    828484
    829 /*
    830  * GetTimeStamp:
    831  *      this returns the "last write date" timestamp
    832  *      of the file specified in pfs3.
    833  *
    834  *      <B>Usage:</B> called from CompileMsgTable
    835  *      to check whether the compilation is
    836  *      outdated.
    837  *
    838  *      Returns:
    839  *      --  NO_ERROR
    840  *      --  ERROR_INVALID_PARAMETER
    841  *      --  ERROR_BUFFER_OVERFLOW: pszBuffer too small for timestamp
    842  */
    843 
    844 APIRET GetTimeStamp(PFILESTATUS3 pfs3,     // in: file to check
    845                     PSZ pszBuffer,    // out: timestamp
    846                     ULONG ulBufferlen)    // in: sizeof(*pszBuffer)
    847 {
    848 
    849     APIRET          rc = NO_ERROR;
    850     CHAR            szTimeStamp[15];
    851     static PSZ      pszFormatTimestamp = "%4u%02u%02u%02u%02u%02u%";
    852 
    853     do
    854     {
    855         // check parms
    856         if ((!pfs3) ||
    857             (!pszBuffer))
    858         {
    859             rc = ERROR_INVALID_PARAMETER;
    860             break;
    861         }
    862 
    863         // create stamp
    864         sprintf(szTimeStamp,
    865                 pszFormatTimestamp,
    866                 pfs3->fdateLastWrite.year + 1980,
    867                 pfs3->fdateLastWrite.month,
    868                 pfs3->fdateLastWrite.day,
    869                 pfs3->ftimeLastWrite.hours,
    870                 pfs3->ftimeLastWrite.minutes,
    871                 pfs3->ftimeLastWrite.twosecs * 2);
    872 
    873         // check bufferlen
    874         if (strlen(szTimeStamp) + 1 > ulBufferlen)
    875         {
    876             rc = ERROR_BUFFER_OVERFLOW;
    877             break;
    878         }
    879 
    880         // hand over result
    881         strcpy(pszBuffer, szTimeStamp);
    882     }
    883     while (FALSE);
    884 
    885     return rc;
    886 }
    887 
     485#endif
  • trunk/src/helpers/winh.c

    r106 r108  
    195195
    196196    /*
    197      *@@ winhSetWindowText:
     197     *@@ winhSetWindowText2:
    198198     *
    199199     *@@added V0.9.13 (2001-06-21) [umoeller]
    200200     */
    201201
    202     BOOL winhSetWindowText(HWND hwnd, const char *pcsz)
     202    BOOL winhSetWindowText2(HWND hwnd, const char *pcsz)
    203203    {
    204204        // put the call in brackets so the macro won't apply here
     
    34193419
    34203420/*
     3421 *@@ winhSetWindowText:
     3422 *      like WinSetWindowText, but this one accepts
     3423 *      printf-like arguments.
     3424 *
     3425 *      Note that the total string is limited to
     3426 *      1000 characters.
     3427 *
     3428 *@@added V0.9.16 (2001-10-08) [umoeller]
     3429 */
     3430
     3431BOOL winhSetWindowText(HWND hwnd,
     3432                       const char *pcszFormat,
     3433                       ...)
     3434{
     3435    CHAR szBuf[1000];
     3436    va_list     args;
     3437    int         i;
     3438    va_start(args, pcszFormat);
     3439    i = vsprintf(szBuf, pcszFormat, args);
     3440    va_end(args);
     3441
     3442    return (WinSetWindowText(hwnd,
     3443                             szBuf));
     3444}
     3445
     3446/*
    34213447 *@@ winhReplaceWindowText:
    34223448 *      this is a combination of winhQueryWindowText
  • trunk/src/helpers/wphandle.c

    r106 r108  
    6060#include "helpers\standards.h"
    6161#include "helpers\stringh.h"
    62 #define INCLUDE_WPHANDLE_PRIVATE
    6362#include "helpers\wphandle.h"
    6463#include "helpers\xstring.h"
  • trunk/src/helpers/xstring.c

    r91 r108  
    379379
    380380/*
     381 *@@ xstrShrink:
     382 *      reallocates the string buffer so that it
     383 *      is exactly the length of the string with
     384 *      its null byte, if the string has excessive
     385 *      memory allocated. Useful if you are sure
     386 *      that the string won't grow again.
     387 *
     388 *@@added V0.9.16 (2001-10-08) [umoeller]
     389 */
     390
     391void XWPENTRY xstrShrink(PXSTRING pxstr)
     392{
     393    if (    (pxstr)
     394         && (pxstr->psz)
     395         && (pxstr->cbAllocated > pxstr->ulLength + 1)
     396       )
     397    {
     398        pxstr->psz = realloc(pxstr->psz,
     399                             pxstr->ulLength + 1);
     400        pxstr->cbAllocated = pxstr->ulLength + 1;
     401    }
     402}
     403
     404/*
    381405 *@@ xstrCreate:
    382406 *      allocates a new XSTRING from the heap
Note: See TracChangeset for help on using the changeset viewer.