/*********************************************************************** $Id: strutil.c 907 2008-01-06 07:26:17Z stevenhl $ External strings file support Copyright (c) 1993-98 M. Kimes Copyright (c) 2006, 2008 Steven H. Levine 22 Jul 06 SHL Comments 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat 05 Jan 08 SHL Rename from string.c to avoid string.h conflict ***********************************************************************/ #include #include #include "strutil.h" #include "fm3str.h" #include "version.h" extern PSZ NullStr; // 05 Jan 08 SHL fixme to be in some .h static char **strs, *str; static ULONG numStr; //== LoadStrings() load strings from file == BOOL LoadStrings(char *filename) { BOOL ok = FALSE; ULONG size, len, totalsize; USHORT vermajor = 0, verminor = 0; register char *p; register ULONG x; FILE *fp; APIRET rc; /* Load strings from requested file or FM3RES.STR * with some quiet error-checking. * Return TRUE on success, FALSE on error. */ if (!filename) filename = "FM3RES.STR"; numStr = 0; if (str) DosFreeMem(str); strs = NULL; str = NULL; fp = _fsopen(filename, "rb", SH_DENYWR); if (fp) { if (fread(&numStr, sizeof(numStr), 1, fp) && numStr == IDS_NUMSTRS && fread(&len, sizeof(len), 1, fp) && fread(&vermajor, sizeof(vermajor), 1, fp) && fread(&verminor, sizeof(verminor), 1, fp) && (vermajor >= VERMAJORBREAK && (vermajor > VERMAJORBREAK || verminor >= VERMINORBREAK))) { fseek(fp, 0, SEEK_END); size = ftell(fp) - ((sizeof(ULONG) * 2) + (sizeof(USHORT) * 2)); if (size && size == len) { fseek(fp, (sizeof(ULONG) * 2) + (sizeof(USHORT) * 2), SEEK_SET); /* NOTE: Make one memory object for both str and strs * for efficiency. */ totalsize = size + sizeof(ULONG); totalsize += (totalsize % sizeof(ULONG)); len = totalsize; totalsize += (numStr * sizeof(char *)); totalsize += 4; rc = DosAllocMem((PPVOID) & str, totalsize, PAG_COMMIT | PAG_READ | PAG_WRITE); if (!rc && str) { strs = (char **)(str + len); if (fread(str, 1, size, fp) == size) { p = str; for (x = 0; x < numStr; x++) { if (p - str >= size) break; strs[x] = p; while (*p) p++; p++; } if (x == numStr) ok = TRUE; } if (ok) /* set pages to readonly */ DosSetMem(str, totalsize, PAG_COMMIT | PAG_READ); } } } fclose(fp); } if (!ok) { numStr = 0; if (str) DosFreeMem(str); str = NULL; strs = NULL; } return ok; } //== GetPString() return a readonly pointer to the requested string in memory == char *GetPString(ULONG id) { return id < numStr && str && strs && strs[id] ? strs[id] : NullStr; } //== StringsLoaded() return TRUE is strings loaded BOOL StringsLoaded(void) { return numStr && str && strs; } #pragma alloc_text(STRINGS,LoadStrings,GetPString)