Changeset 108
- Timestamp:
- Oct 13, 2001, 7:57:58 PM (24 years ago)
- Location:
- trunk
- Files:
-
- 22 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/helpers/apps.h
r101 r108 70 70 APIRET appFreeEnvironment(PDOSENVIRONMENT pEnv); 71 71 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 72 86 /* ****************************************************************** 73 87 * … … 76 90 ********************************************************************/ 77 91 78 #ifdef INCL_WINPROGRAMLIST79 // additional PROG_* flags for appQueryAppType80 #define PROG_XWP_DLL 998 // dynamic link library81 82 APIRET appQueryAppType(const char *pcszExecutable,83 PULONG pulDosAppType,84 PULONG pulWinAppType);85 86 ULONG appIsWindowsApp(ULONG ulProgCategory);87 92 88 93 PSZ appQueryDefaultWin31Environment(VOID); -
trunk/include/helpers/dosh.h
r94 r108 836 836 } LVMINFO, *PLVMINFO; 837 837 838 #define DOSH_PARTITIONS_LIMIT 10838 /* #define DOSH_PARTITIONS_LIMIT 10 839 839 840 840 #define PAR_UNUSED 0x00 // Unused … … 881 881 #define PAR_FREEBSD 0xA5 // FreeBSD 882 882 #define PAR_BBT 0xFF // BBT 883 */ 883 884 884 885 // one-byte alignment … … 966 967 typedef struct _PARTITIONINFO 967 968 { 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 976 978 PPARTITIONINFO pNext; // next info or NULL if last 977 979 } PARTITIONINFO; -
trunk/include/helpers/prfh.h
r71 r108 35 35 #define PRFH_HEADER_INCLUDED 36 36 37 /* common error codes used by the prfh* functions */ 37 /* ****************************************************************** 38 * 39 * Errors 40 * 41 ********************************************************************/ 38 42 39 43 #define PRFERR_DATASIZE 10001 // couldn't query data size for key … … 47 51 #define PRFERR_INVALID_KEY 10009 48 52 #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 ********************************************************************/ 49 174 50 175 APIRET prfhQueryKeysForApp(HINI hIni, … … 75 200 LONG prfhQueryColor(const char *pcszKeyName, const char *pcszDefault); 76 201 77 /*78 *@@ COUNTRYSETTINGS:79 * structure used for returning country settings80 * with prfhQueryCountrySettings.81 */82 83 typedef struct _COUNTRYSETTINGS84 {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.mm91 ulTimeFormat;92 // time format:93 // -- 0 12-hour clock94 // -- >0 24-hour clock95 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 107 202 APIRET prfhCopyKey(HINI hiniSource, 108 203 const char *pcszSourceApp, -
trunk/include/helpers/stringh.h
r104 r108 91 91 ULONG strhWords(PSZ psz); 92 92 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 128 93 #define STRH_BEGIN_CHARS "\x0d\x0a " 129 94 #define STRH_END_CHARS "\x0d\x0a /-" -
trunk/include/helpers/tmsgfile.h
r102 r108 20 20 #define TMSGFILE_HEADER_INCLUDED 21 21 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, 23 58 ULONG cTable, 24 59 PBYTE pbBuffer, … … 35 70 PCSZ pszFile, 36 71 PULONG pcbMsg); 72 */ 37 73 38 74 #endif // TMSGFILE_HEADER_INCLUDED -
trunk/include/helpers/tree.h
r106 r108 10 10 #endif 11 11 12 #ifndef SFLTREE_INCLUDED // Allow multiple inclusions13 #define SFLTREE_INCLUDED12 #ifndef XWPTREE_INCLUDED // Allow multiple inclusions 13 #define XWPTREE_INCLUDED 14 14 15 15 #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 101 101 #define WinQueryWindowPtr(a,b) winhQueryWindowPtr((a),(b)) 102 102 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)) 105 105 106 106 BOOL XWPENTRY winhSetDlgItemText(HWND hwnd, ULONG id, const char *pcsz); … … 758 758 PSZ XWPENTRY winhQueryWindowText(HWND hwnd); 759 759 760 BOOL XWPENTRY winhSetWindowText(HWND hwnd, 761 const char *pcszFormat, 762 ...); 763 760 764 /* 761 765 *@@ winhQueryDlgItemText: -
trunk/include/helpers/wphandle.h
r106 r108 51 51 #define ERROR_WPH_CORRUPT_HANDLES_DATA (ERROR_WPH_FIRST + 5) 52 52 #define ERROR_WPH_INVALID_PARENT_HANDLE (ERROR_WPH_FIRST + 6) 53 54 /* ******************************************************************55 *56 * Strings57 *58 ********************************************************************/59 60 // DECLARE_WPH_STRING is a handy macro which saves us from61 // keeping two string lists in both the .h and the .c file.62 // If this include file is included from the .c file, the63 // string is defined as a global variable. Otherwise64 // it is only declared as "extern" so other files can65 // see it.66 67 #ifdef INCLUDE_WPHANDLE_PRIVATE68 #define DECLARE_WPH_STRING(str, def) const char *str = def69 #else70 #define DECLARE_WPH_STRING(str, def) extern const char *str;71 #endif72 73 /*74 * OS2.INI applications75 *76 */77 78 // abstract objects per folder handle79 DECLARE_WPH_STRING(WPINIAPP_FDRCONTENT, "PM_Abstract:FldrContent");80 // all defined abstract objects on the system81 DECLARE_WPH_STRING(WPINIAPP_OBJECTS, "PM_Abstract:Objects");82 // their icons, if set individually83 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 positions89 DECLARE_WPH_STRING(WPINIAPP_FOLDERPOS, "PM_Workplace:FolderPos");90 91 // palette positions92 DECLARE_WPH_STRING(WPINIAPP_PALETTEPOS, "PM_Workplace:PalettePos");93 // ???94 DECLARE_WPH_STRING(WPINIAPP_STATUSPOS, "PM_Workplace:StatusPos");95 // startup folders96 DECLARE_WPH_STRING(WPINIAPP_STARTUP, "PM_Workplace:Startup");97 // all the defined templates on the system98 DECLARE_WPH_STRING(WPINIAPP_TEMPLATES, "PM_Workplace:Templates");99 100 // all work area folders101 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 applications114 *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.9133 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>");152 53 153 54 /* ****************************************************************** -
trunk/include/helpers/xstring.h
r91 r108 103 103 typedef XSTRRESERVE *PXSTRRESERVE; 104 104 105 void XWPENTRY xstrShrink(PXSTRING pxstr); 106 typedef void XWPENTRY XSTRSHRINK(PXSTRING pxstr); 107 typedef XSTRSHRINK *PXSTRSHRINK; 108 105 109 PXSTRING XWPENTRY xstrCreate(ULONG ulPreAllocate); 106 110 typedef PXSTRING XWPENTRY XSTRCREATE(ULONG ulPreAllocate); -
trunk/src/helpers/apps.c
r105 r108 476 476 /* ****************************************************************** 477 477 * 478 * Application start478 * Application information 479 479 * 480 480 ********************************************************************/ 481 482 /*483 *@@ CallBatchCorrectly:484 * fixes the specified PROGDETAILS for485 * command files in the executable part486 * by inserting /C XXX into the parameters487 * and setting the executable according488 * 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 XSTRING492 *@@changed V0.9.12 (2001-05-27) [umoeller]: moved from winh.c to apps.c493 */494 495 VOID CallBatchCorrectly(PPROGDETAILS pProgDetails,496 PXSTRING pstrParams, // in/out: modified parameters (reallocated)497 const char *pcszEnvVar, // in: env var spec'g command proc498 // (e.g. "OS2_SHELL"); can be NULL499 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.CMD503 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 later509 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 params521 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 PATH535 }536 481 537 482 /* … … 557 502 * -- PROG_VDD 558 503 * 559 * -- PROG_XWP_DLL: new apptype defined in winh.h for 560 * dynamic link libraries. 504 * -- PROG_DLL 561 505 * 562 506 * -- PROG_WINDOWEDVDM … … 590 534 else if ((_ulDosAppType & 0xF0) == FAPPTYP_DLL) // 0x10) 591 535 // DLL bit set 592 *pulWinAppType = PROG_ XWP_DLL;536 *pulWinAppType = PROG_DLL; 593 537 else if (_ulDosAppType & FAPPTYP_DOS) // 0x20) 594 538 // DOS bit set? … … 611 555 612 556 /* 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 565 PCSZ 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 /* 613 615 *@@ appIsWindowsApp: 614 616 * checks the specified program category … … 657 659 658 660 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 682 VOID 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 659 722 } 660 723 -
trunk/src/helpers/datetime.c
r90 r108 147 147 148 148 int dtCreateFileTimeStamp(PSZ pszTimeStamp, // out: time stamp 149 150 149 FDATE* pfdate, // in: date 150 FTIME* pftime) // in: time 151 151 { 152 152 return (sprintf(pszTimeStamp, … … 230 230 * returns TRUE if yr is a leap year. 231 231 * 232 * (c) Ray Gardner. 232 * (c) Ray Gardner. Public domain. 233 233 */ 234 234 … … 260 260 * you then get 63. 261 261 * 262 * (c) Ray Gardner. 262 * (c) Ray Gardner. Public domain. 263 263 */ 264 264 … … 272 272 * converts a year to the no. of days passed. 273 273 * 274 * (c) Ray Gardner. 274 * (c) Ray Gardner. Public domain. 275 275 */ 276 276 … … 288 288 * the given date. 289 289 * 290 * (c) Ray Gardner. 290 * (c) Ray Gardner. Public domain. 291 291 */ 292 292 … … 308 308 * 309 309 * 310 * (c) Ray Gardner. 310 * (c) Ray Gardner. Public domain. 311 311 */ 312 312 -
trunk/src/helpers/dialog.c
r106 r108 227 227 228 228 /* 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 234 VOID SetDlgFont(PCONTROLDEF pControlDef, 235 PDLGPRIVATE pDlgData) 236 { 237 LONG lPointSize = 0; 241 238 const char *pcszFontThis = pControlDef->pcszFont; 242 239 // can be NULL, … … 249 246 pDlgData->hps = WinGetPS(pDlgData->hwndDlg); 250 247 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 { 269 264 // create new font 270 265 pDlgData->lcidLast = gpihFindPresFont(NULLHANDLE, // no window yet … … 278 273 if (pDlgData->fmLast.fsDefn & FM_DEFN_OUTLINE) 279 274 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 298 VOID 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; 287 307 288 308 // ok, we FINALLY have a font now... … … 396 416 } 397 417 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 398 426 } 399 427 } … … 566 594 LHANDLE lHandleSet = NULLHANDLE; 567 595 ULONG flOld = 0; 596 597 LONG y, cy; // for combo box hacks 568 598 569 599 if (pColumnDef->fIsNestedTable) … … 588 618 pcszTitle = pControlDef->pcszText; 589 619 flStyle = pControlDef->flStyle; 620 621 y = pcp->y + pDlgData->ptlTotalOfs.y; 622 cy = pcp->cy; 590 623 } 591 624 } … … 598 631 pcszTitle = pControlDef->pcszText; 599 632 flStyle = pControlDef->flStyle; 633 634 y = pcp->y + pDlgData->ptlTotalOfs.y; 635 cy = pcp->cy; 600 636 601 637 // change the title if this is a static with SS_BITMAP; … … 613 649 pcszTitle = ""; 614 650 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; 615 661 } 616 662 } … … 640 686 flStyle, // hacked 641 687 pcp->x + pDlgData->ptlTotalOfs.x, 642 pcp->y + pDlgData->ptlTotalOfs.y,688 y, 643 689 pcp->cx, 644 pcp->cy,690 cy, 645 691 pDlgData->hwndDlg, // owner 646 692 HWND_BOTTOM, -
trunk/src/helpers/dosh.c
r105 r108 69 69 #pragma hdrstop 70 70 71 static const CHAR G_acDriveLetters[28] = " ABCDEFGHIJKLMNOPQRSTUVWXYZ";71 // static const CHAR G_acDriveLetters[28] = " ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 72 72 73 73 /* … … 703 703 PFSQBUFFER2 pfsqBuffer = (PFSQBUFFER2)fsqBuffer; 704 704 705 szName[0] = G_acDriveLetters[ulLogicalDrive];705 szName[0] = ulLogicalDrive + 'A' - 1; 706 706 szName[1] = ':'; 707 707 szName[2] = '\0'; … … 753 753 &ulBootDrive, 754 754 sizeof(ulBootDrive)); 755 return ( G_acDriveLetters[ulBootDrive]);755 return (ulBootDrive + 'A' - 1); 756 756 } 757 757 … … 1034 1034 *@@changed V0.9.1 (99-12-12) [umoeller]: added cbBuf to prototype 1035 1035 *@@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 1036 1037 */ 1037 1038 … … 1048 1049 1049 1050 // 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 device1057 pfsqBuffer, // buffer for returned data1058 &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) 1063 1064 { 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 } 1072 1076 } 1073 1077 } 1078 else 1079 arc = ERROR_INVALID_PARAMETER; // V0.9.16 (2001-10-02) [umoeller] 1074 1080 1075 1081 return (arc); … … 1883 1889 ULONG cbWritten; 1884 1890 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); 1888 1895 return (DosWrite(hfLog, (PVOID)szTemp, strlen(szTemp), &cbWritten)); 1889 1896 } … … 2000 2007 ULONG ulCurDisk = 0; 2001 2008 ULONG ulMap = 0; 2002 arc = DosQueryCurrentDisk(&ulCurDisk, &ulMap); 2003 if (arc == NO_ERROR) 2009 if (!(arc = DosQueryCurrentDisk(&ulCurDisk, &ulMap))) 2004 2010 { 2005 2011 ULONG cbBuf = CCHMAXPATH - 3; 2006 *pszBuf = G_acDriveLetters[ulCurDisk];2012 *pszBuf = ulCurDisk + 'A' - 1; 2007 2013 *(pszBuf + 1) = ':'; 2008 2014 *(pszBuf + 2) = '\\'; … … 2270 2276 2271 2277 // 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))) 2274 2279 { 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)))) 2280 2284 { 2281 2285 // 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))) 2284 2287 { 2285 2288 pPerfSys->fInitialized = TRUE; 2286 2289 // call CMD_KI_DISABLE later 2287 2290 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))) 2293 2295 { 2294 ULONG ul = 0; 2296 ULONG ul = 0, 2297 cProcs = pPerfSys->cProcessors, 2298 cbDouble = cProcs * sizeof(double), 2299 cbLong = cProcs * sizeof(LONG); 2295 2300 2296 2301 // 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 ) 2300 2315 arc = ERROR_NOT_ENOUGH_MEMORY; 2301 2316 else 2302 2317 { 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++) 2307 2319 { 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; 2342 2325 } 2343 2326 } … … 2347 2330 } // end if (arc == NO_ERROR) 2348 2331 2349 if (arc != NO_ERROR)2350 {2332 if (arc) 2333 // error: clean up 2351 2334 doshPerfClose(ppPerfSys); 2352 } 2335 2353 2336 } // end else if (!*ppPerfSys) 2354 2337 … … 2405 2388 else 2406 2389 { 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))) 2411 2393 { 2412 2394 // go thru all processors -
trunk/src/helpers/dosh2.c
r91 r108 2186 2186 2187 2187 /* 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 2203 APIRET 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 2249 APIRET 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 /* 2188 2309 * FindFile: 2189 2310 * helper for doshFindExecutable. 2190 2311 * 2191 2312 *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 2192 2314 */ 2193 2315 … … 2210 2332 if (!arc) 2211 2333 if (!(fs3.attrFile & FILE_DIRECTORY)) 2212 strhncpy0(pszExecutable,2213 pcszCommand,2214 cbExecutable);2334 arc = CopyToBuffer(pszExecutable, 2335 pcszCommand, 2336 cbExecutable); 2215 2337 else 2216 2338 // directory: … … 2218 2340 } 2219 2341 else 2342 { 2220 2343 // non-qualified: 2221 arc = DosSearchPath(SEARCH_IGNORENETERRS | SEARCH_ENVIRONMENT | SEARCH_CUR_DIRECTORY, 2344 /* arc = DosSearchPath(SEARCH_IGNORENETERRS 2345 | SEARCH_ENVIRONMENT 2346 | SEARCH_CUR_DIRECTORY, 2222 2347 "PATH", 2223 2348 (PSZ)pcszCommand, 2224 2349 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 } 2226 2360 2227 2361 return (arc); … … 2235 2369 * 1) If pcszCommand appears to be qualified (i.e. contains 2236 2370 * 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. 2241 2378 * 2242 2379 * papcszExtensions determines if additional searches are to be 2243 * performed if the file doesn't exist (case 1) or DosSearchPath2380 * performed if the file doesn't exist (case 1) or doshSearchPath 2244 2381 * returned ERROR_FILE_NOT_FOUND (case 2). 2245 2382 * This must point to an array of strings specifying the extra … … 2249 2386 * extra searches are performed. 2250 2387 * 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. 2254 2398 * 2255 2399 * Example: … … 2294 2438 { 2295 2439 const char *pcszExtThis = papcszExtensions[ul]; 2296 sprintf(psz2, "%s.%s", pcszCommand, pcszExtThis); 2440 sprintf(psz2, 2441 "%s.%s", 2442 pcszCommand, 2443 pcszExtThis); 2297 2444 arc = FindFile(psz2, 2298 2445 pszExecutable, … … 2328 2475 * on the system. 2329 2476 * 2330 * Based on code (C) Dmitry A. Steklenev.2331 *2332 2477 *@@added V0.9.0 [umoeller] 2333 2478 */ … … 2335 2480 UINT doshQueryDiskCount(VOID) 2336 2481 { 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); 2390 2485 } 2391 2486 … … 2393 2488 *@@ doshType2FSName: 2394 2489 * 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. 2521 2492 * 2522 2493 *@@added V0.9.0 [umoeller] 2494 *@@changed V0.9.16 (2001-10-08) [umoeller]: rewritten 2523 2495 */ 2524 2496 2525 2497 const char* doshType2FSName(unsigned char bFSType) // in: FS type 2526 2498 { 2527 PSZ zFSName = NULL;2528 2529 2499 switch (bFSType) 2530 2500 { 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"; 2664 2594 } 2665 return zFSName; 2595 2596 return NULL; 2666 2597 } 2667 2598 … … 2678 2609 * to point to the newly created PARTITIONINFO, so before 2679 2610 * calling this function for the first time, 2680 *2681 * Based on code (C) Dmitry A. Steklenev.2682 2611 * 2683 2612 *@@added V0.9.0 [umoeller] … … 2712 2641 ppiNew->cLetter = cLetter; 2713 2642 ppiNew->bFSType = bFsType; 2714 strcpy(ppiNew->szFSType, 2715 doshType2FSName(bFsType)); 2643 ppiNew->pcszFSType = doshType2FSName(bFsType); 2716 2644 ppiNew->fPrimary = fPrimary; 2717 2645 ppiNew->fBootable = fBootable; … … 2741 2669 } 2742 2670 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 2686 APIRET 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 2743 2722 // Sector and Cylinder values are actually 6 bits and 10 bits: 2744 2723 // … … 2756 2735 * get cylinder number. 2757 2736 * 2758 * Based on code (C)Dmitry A. Steklenev.2737 * Originally contributed by Dmitry A. Steklenev. 2759 2738 * 2760 2739 *@@added V0.9.0 [umoeller] … … 2771 2750 * get sector number. 2772 2751 * 2773 * Based on code (C)Dmitry A. Steklenev.2752 * Originally contributed by Dmitry A. Steklenev. 2774 2753 * 2775 2754 *@@added V0.9.0 [umoeller] … … 2796 2775 * -- ERROR_NOT_SUPPORTED (50): boot manager not installed. 2797 2776 * 2798 * Based on code (C)Dmitry A. Steklenev.2777 * Originally contributed by Dmitry A. Steklenev. 2799 2778 * 2800 2779 *@@added V0.9.0 [umoeller] … … 2858 2837 * -- ERROR_INVALID_PARAMETER: BMInfo is NULL. 2859 2838 * 2860 * Based on code (C)Dmitry A. Steklenev.2839 * Originally contributed by Dmitry A. Steklenev. 2861 2840 * 2862 2841 *@@added V0.9.0 [umoeller] … … 2907 2886 // skip unused partition, BootManager or Extended partition 2908 2887 if ( (MBoot.sPrtnInfo[i].bFileSysCode) // skip unused 2909 && (MBoot.sPrtnInfo[i].bFileSysCode != PAR_BOOTMANAGER) // skip boot manager2910 && (MBoot.sPrtnInfo[i].bFileSysCode != PAR_EXTENDED) // skip extended2888 && (MBoot.sPrtnInfo[i].bFileSysCode != 0x0A) // skip boot manager 2889 && (MBoot.sPrtnInfo[i].bFileSysCode != 0x05) // skip extended partition 2911 2890 ) 2912 2891 { … … 2945 2924 * This gets called from GetExtendedPartition. 2946 2925 * 2947 * Based on code (C)Dmitry A. Steklenev.2926 * Originally contributed by Dmitry A. Steklenev. 2948 2927 * 2949 2928 *@@added V0.9.0 [umoeller] … … 2973 2952 // skip unused partition or BootManager partition 2974 2953 if ( (MBoot.sPrtnInfo[i].bFileSysCode) 2975 && (MBoot.sPrtnInfo[i].bFileSysCode != PAR_BOOTMANAGER)2954 && (MBoot.sPrtnInfo[i].bFileSysCode != 0x0A) 2976 2955 ) 2977 2956 { … … 2980 2959 2981 2960 // special work around extended partition 2982 if (MBoot.sPrtnInfo[i].bFileSysCode == PAR_EXTENDED)2961 if (MBoot.sPrtnInfo[i].bFileSysCode == 0x05) 2983 2962 { 2984 2963 if ((arc = GetLogicalDrives(pppiFirst, … … 2995 2974 2996 2975 // 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) 2998 2977 ) 2999 2978 fAssignLetter = TRUE; … … 3034 3013 * This gets called from doshGetPartitionsList. 3035 3014 * 3036 * Based on code (C)Dmitry A. Steklenev.3015 * Originally contributed by Dmitry A. Steklenev. 3037 3016 * 3038 3017 *@@added V0.9.0 [umoeller] … … 3058 3037 i++) 3059 3038 { 3060 if (MBoot.sPrtnInfo[i].bFileSysCode == PAR_EXTENDED)3039 if (MBoot.sPrtnInfo[i].bFileSysCode == 0x05) 3061 3040 { 3062 3041 if ((arc = GetLogicalDrives(pppiFirst, … … 3075 3054 3076 3055 /* 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 3065 APIRET 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 /* 3077 3133 *@@ CleanPartitionInfos: 3078 3134 * … … 3137 3193 * -- 0: something else. 3138 3194 * 3139 * Based on code (C)Dmitry A. Steklenev.3195 * Originally contributed by Dmitry A. Steklenev. 3140 3196 * 3141 3197 *@@added V0.9.0 [umoeller] … … 3151 3207 PLVMINFO pLVMInfo = NULL; 3152 3208 3153 PARTITIONINFO *pPartitionInfos = NULL, // linked list of all partitions 3154 *ppiTemp = NULL; 3209 PARTITIONINFO *pPartitionInfos = NULL; // linked list of all partitions 3155 3210 USHORT cPartitions = 0; // bootable partition count 3156 3211 … … 3176 3231 } 3177 3232 3233 #ifndef __XWPLITE__ 3178 3234 if (arc) 3179 {3180 3235 // LVM not installed, or failed: 3181 3236 // 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 3239 3241 3240 3242 if (!arc) -
trunk/src/helpers/eah.c
r21 r108 857 857 USHORT usCodepage) // in: codepage to set in EAT_MVMT 858 858 { 859 PEABINDING peab ;859 PEABINDING peab = NULL; 860 860 if (pcszInput) 861 861 { 862 peab = (PEABINDING)malloc(sizeof(EABINDING)); 863 if (peab) 862 if ((peab = (PEABINDING)malloc(sizeof(EABINDING)))) 864 863 { 865 864 const char *p = pcszInput, -
trunk/src/helpers/helpers_pre.in
r91 r108 60 60 $(OUTPUTDIR)\except.obj \ 61 61 $(OUTPUTDIR)\level.obj \ 62 $(OUTPUTDIR)\nls.obj \ 62 63 $(OUTPUTDIR)\procstat.obj \ 63 64 $(OUTPUTDIR)\prfh.obj \ -
trunk/src/helpers/prfh.c
r71 r108 45 45 #include "setup.h" // code generation and debugging options 46 46 47 #define INCLUDE_PRFH_PRIVATE 47 48 #include "helpers\prfh.h" 48 49 … … 237 238 szTemp, sizeof(szTemp)-1); 238 239 return (szTemp[0]); 239 }240 241 /*242 *@@ prfhQueryCountrySettings:243 * this returns the most frequently used country settings244 * all at once into a COUNTRYSETTINGS structure (prfh.h).245 * This data corresponds to the user settings in the246 * 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 cDecimal260 */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 }274 240 } 275 241 -
trunk/src/helpers/stringh.c
r105 r108 651 651 } 652 652 return (ulWords); 653 }654 655 /*656 *@@ strhThousandsULong:657 * converts a ULONG into a decimal string, while658 * inserting thousands separators into it. Specify659 * the separator character in cThousands.660 *661 * Returns pszTarget so you can use it directly662 * with sprintf and the "%s" flag.663 *664 * For cThousands, you should use the data in665 * OS2.INI ("PM_National" application), which is666 * always set according to the "Country" object.667 * You can use prfhQueryCountrySettings to668 * retrieve this setting.669 *670 * Use strhThousandsDouble for "double" values.671 */672 673 PSZ strhThousandsULong(PSZ pszTarget, // out: decimal as string674 ULONG ul, // in: decimal to convert675 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, and732 * with a variable number of decimal places depending on the733 * 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 else746 if (dbl < 1000.0)747 sprintf(pszTarget, "%.1f%s", dbl, pszUnits);748 else749 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* or760 * 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 using764 + 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.mm771 *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 settings777 * at once using prfhQueryCountrySettings (prfh.c).778 *779 *@@changed V0.9.0 (99-11-07) [umoeller]: now calling strhDateTime780 */781 782 VOID strhFileDate(PSZ pszBuf, // out: string returned783 FDATE *pfDate, // in: date information784 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 time794 &dt,795 ulDateFormat,796 cDateSep,797 0, 0); // no time798 }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* or805 * 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 using809 + PrfQueryProfileInt(HINI_USER, "PM_National", "iTime", 0);810 * meaning:811 * -- 0 12-hour clock812 * -- >0 24-hour clock813 *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 settings819 * at once using prfhQueryCountrySettings (prfh.c).820 *821 *@@changed V0.8.5 (99-03-15) [umoeller]: fixed 12-hour crash822 *@@changed V0.9.0 (99-11-07) [umoeller]: now calling strhDateTime823 */824 825 VOID strhFileTime(PSZ pszBuf, // out: string returned826 FTIME *pfTime, // in: time information827 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 date836 pszBuf,837 &dt,838 0, 0, // no date839 ulTimeFormat,840 cTimeSep);841 }842 843 /*844 *@@ strhDateTime:845 * converts Control Program DATETIME info846 * into two strings. See strhFileDate and strhFileTime847 * 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 information855 ULONG ulDateFormat, // in: date format (0-3); see strhFileDate856 CHAR cDateSep, // in: date separator (e.g. '.')857 ULONG ulTimeFormat, // in: 24-hour time format (0 or 1); see strhFileTime858 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.mm892 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 data907 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 though914 // AM stands for "ante meridiam", but English is just915 // not logical), so that's handled below.916 917 PrfQueryProfileString(HINI_USER,918 "PM_National",919 "s2359", // key920 "PM", // default921 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 else932 {933 // <= 12h: AM934 PrfQueryProfileString(HINI_USER,935 "PM_National",936 "s1159", // key937 "AM", // default938 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 else949 // 24-hour clock950 sprintf(pszTime, "%02d%c%02d%c%02d",951 pDateTime->hours,952 cTimeSep,953 pDateTime->minutes,954 cTimeSep,955 pDateTime->seconds);956 }957 653 } 958 654 -
trunk/src/helpers/tmsgfile.c
r102 r108 2 2 /* 3 3 *@@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: 15 7 * 16 8 * 1) No external utility is necessary to change message … … 21 13 * only numerical IDs. 22 14 * 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. 24 40 * 25 41 * Usage: All OS/2 programs. … … 28 44 * -- tmf* text message file functions 29 45 * 30 * This code uses only C standard library functions31 * which are also part of the subsystem libraries.32 * It does _not_ use the fopen etc. functions, but33 * DosOpen etc. instead.34 * You can therefore use this code with your software35 * which uses the subsystem libraries only.36 *37 * This code was kindly provided by Christian Langanke.38 * Modifications April 1999 by Ulrich Mller. Any39 * substantial changes (other than comments and40 * formatting) are marked with (*UM).41 *42 46 * Note: Version numbering in this file relates to XWorkplace version 43 47 * numbering. … … 48 52 49 53 /* 50 * Copyright (C) 1999 Christian Langanke. 51 * Copyright (C) 1999-2000 Ulrich Mller. 54 * Copyright (C) 2001 Ulrich Mller. 52 55 * This file is part of the "XWorkplace helpers" source package. 53 56 * This is free software; you can redistribute it and/or modify … … 68 71 #define INCL_DOSFILEMGR 69 72 #define INCL_DOSMISC 70 #define INCL_DOSNLS71 73 #define INCL_DOSERRORS 72 74 #include <os2.h> … … 79 81 #include "setup.h" // code generation and debugging options 80 82 83 #include "helpers\dosh.h" 81 84 #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 82 90 #include "helpers\tmsgfile.h" 83 91 … … 93 101 ********************************************************************/ 94 102 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 109 typedef 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 118 static PCSZ G_pcszStartMarker = "\n<--", 119 G_pcszEndMarker = "-->:"; 114 120 115 121 /* ****************************************************************** 116 122 * 117 * Text Message File Code123 * Functions 118 124 * 119 125 ********************************************************************/ 120 126 121 127 /* 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 149 APIRET tmfOpenMessageFile(const char *pcszMessageFile, // in: fully q'fied .TMF file name 150 PTMFMSGFILE *ppMsgFile) // out: TMFMSGFILE struct 157 151 { 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))) 175 157 { 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))) 182 162 { 183 rc = ERROR_INVALID_PARAMETER;184 break;163 arc = ERROR_NOT_ENOUGH_MEMORY; 164 free(pszContent); 185 165 } 186 187 if (cbBuffer < 2)188 {189 rc = ERROR_BUFFER_OVERFLOW;190 break;191 }192 193 // search file194 if ((strchr(pszFile, ':')) ||195 (strchr(pszFile, '\\')) ||196 (strchr(pszFile, '/')))197 // drive and/or path given: no search in path198 strcpy(szMessageFile, pszFile);199 166 else 200 167 { 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;")) 241 189 { 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); 244 204 } 245 205 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; 298 310 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, 452 316 453 317 return (arc); … … 455 319 456 320 /* 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 329 APIRET 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 * 472 390 * -- 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 397 APIRET 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 487 402 { 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 516 408 { 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)) 526 414 { 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) 563 422 { 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++) 573 428 { 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 ; 799 438 } 800 439 } 801 440 } 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; 812 443 } 444 445 return (arc); 446 } 447 448 /* test case */ 449 450 #ifdef __TMFDEBUG__ 451 452 int main(int argc, char *argv[]) 453 { 454 APIRET arc; 455 PTMFMSGFILE pMsgFile; 456 457 if (argc < 3) 458 printf("tmsgfile <file> <msgid>\n"); 813 459 else 814 460 { 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); 818 482 } 819 820 // cleanup821 if (pbFileData)822 free(pbFileData);823 if (hfileMessageFile)824 DosClose(hfileMessageFile);825 826 return rc;827 483 } 828 484 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 195 195 196 196 /* 197 *@@ winhSetWindowText :197 *@@ winhSetWindowText2: 198 198 * 199 199 *@@added V0.9.13 (2001-06-21) [umoeller] 200 200 */ 201 201 202 BOOL winhSetWindowText (HWND hwnd, const char *pcsz)202 BOOL winhSetWindowText2(HWND hwnd, const char *pcsz) 203 203 { 204 204 // put the call in brackets so the macro won't apply here … … 3419 3419 3420 3420 /* 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 3431 BOOL 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 /* 3421 3447 *@@ winhReplaceWindowText: 3422 3448 * this is a combination of winhQueryWindowText -
trunk/src/helpers/wphandle.c
r106 r108 60 60 #include "helpers\standards.h" 61 61 #include "helpers\stringh.h" 62 #define INCLUDE_WPHANDLE_PRIVATE63 62 #include "helpers\wphandle.h" 64 63 #include "helpers\xstring.h" -
trunk/src/helpers/xstring.c
r91 r108 379 379 380 380 /* 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 391 void 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 /* 381 405 *@@ xstrCreate: 382 406 * allocates a new XSTRING from the heap
Note:
See TracChangeset
for help on using the changeset viewer.