source: trunk/dll/wrappers.c@ 1844

Last change on this file since 1844 was 1839, checked in by Steven Levine, 10 years ago

xDosGetInfoBlocks

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 16.4 KB
RevLine 
[395]1
2/***********************************************************************
3
4 $Id: wrappers.c 1839 2015-08-12 04:49:46Z stevenhl $
5
6 Wrappers with error checking
7
[1839]8 Copyright (c) 2006, 2015 Steven H.Levine
[395]9
10 22 Jul 06 SHL Baseline
[400]11 29 Jul 06 SHL Add xgets_stripped
[438]12 18 Aug 06 SHL Correct Runtime_Error line number report
[794]13 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
[826]14 01 Sep 07 GKY Add xDosSetPathInfo to fix case where FS3 buffer crosses 64k boundry
[850]15 06 Oct 07 SHL Add xDos...() wrappers to support systems wo/large file support (Gregg, Steven)
[1008]16 05 May 08 SHL Add FORTIFY support
[1358]17 25 Dec 08 GKY Add code to allow write verify to be turned off on a per drive basis
[1432]18 17 Jun 09 SHL Correct missing rc set
[1476]19 12 Jul 09 GKY Add xDosQueryAppType and xDosAlloc... to allow FM/2 to load in high memory
20 15 Nov 09 GKY Rework xDosQueryAppType to remove HIMEM ifdefs
[1627]21 26 Aug 11 GKY Add a low mem version of xDosAlloc* wrappers; move error checking into all the
[1839]22 xDosAlloc* wrappers.
[1639]23 09 Oct 11 GKY Modify xfsopen so it doesn't fail when called with r+ because the file doesn't exist.
[1839]24 We should be creating the file unless it is set to fail silently.
25 09 Aug 15 SHL Add xDosGetInfoBlocks
[395]26
27***********************************************************************/
28
[907]29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
[1354]32#include <ctype.h>
[907]33
[395]34#define INCL_WIN
[826]35#define INCL_DOS
36#define INCL_DOSERRORS
[841]37#define INCL_LONGLONG
[395]38#include <os2.h>
39
40#include "fm3dll.h"
[1215]41#include "init.h" // Data declaration(s)
[1182]42#include "wrappers.h"
[395]43#include "fm3str.h"
[907]44#include "errutil.h" // Dos_Error...
45#include "strutil.h" // GetPString
[1032]46#include "command.h"
47#include "tools.h"
48#include "avl.h"
[1182]49#include "strips.h" // bstrip
[395]50
[1005]51#include "fortify.h" // GetPString
[1354]52#include "info.h" // driveflags
53#include "notebook.h" // fVerify
[1439]54#include "pathutil.h" // MaxComLineStrg
[1005]55
[1215]56// Data definitions
[827]57static PSZ pszSrcFile = __FILE__;
58
[1215]59#pragma data_seg(GLOBAL1)
60BOOL fNoLargeFileSupport;
61
[1439]62APIRET xDosQueryAppType(PCSZ pszName, PULONG pFlags)
63{
64 APIRET rc;
[1476]65 CHAR szPgm[CCHMAXPATH];
[1439]66
[1476]67 strcpy(szPgm, pszName);
68 rc = DosQueryAppType(szPgm, pFlags);
[1439]69 return rc;
70}
71
[1628]72/**
73 * xDosAllocSharedMem uses OBJ_ANY on systems that support high memory use
74 * and falls back to low memory allocation where it is not supported.
75 * Flags are hard coded PAG_COMMIT | OBJ_GIVEABLE | PAG_READ | PAG_WRITE
76 * The wrapper provides error checking.
77 */
78
[1438]79APIRET xDosAllocSharedMem(PPVOID ppb,
[1839]80 PSZ pszName,
81 ULONG cb,
82 PCSZ pszSrcFile,
83 UINT uiLineNumber)
[1438]84{
85 APIRET rc; ;
86
[1628]87 rc = DosAllocSharedMem(ppb, pszName, cb,
[1839]88 PAG_COMMIT | OBJ_GIVEABLE | PAG_READ | PAG_WRITE | OBJ_ANY);
[1439]89 //DbgMsg(pszSrcFile, __LINE__, "ppb %p", *ppb);
[1438]90 if (rc)
[1628]91 rc = DosAllocSharedMem(ppb, pszName, cb, PAG_COMMIT | OBJ_GIVEABLE | PAG_READ | PAG_WRITE);
[1627]92 if (rc)
93 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
[1438]94 return rc;
95}
96
[1628]97/**
98 * xDosAllocMem uses OBJ_ANY on systems that support high memory use
99 * and falls back to low memory allocation where it is not supported.
100 * Flags are hard coded PAG_COMMIT | PAG_READ | PAG_WRITE.
101 * The wrapper provides error checking.
102 */
103
[1438]104APIRET xDosAllocMem(PPVOID ppb,
[1839]105 ULONG cb,
106 PCSZ pszSrcFile,
107 UINT uiLineNumber)
[1438]108{
109 APIRET rc;
110
[1628]111 rc = DosAllocMem(ppb, cb, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_ANY);
[1439]112 //DbgMsg(pszSrcFile, uiLineNumber, "ppb %p %x", *ppb, rc);
[1438]113 if (rc)
[1628]114 rc = DosAllocMem(ppb, cb, PAG_COMMIT | PAG_READ | PAG_WRITE);
[1627]115 if (rc)
116 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
[1439]117 //DbgMsg(pszSrcFile, uiLineNumber, "ppb %p", *ppb);
[1438]118 return rc;
119}
120
[1628]121/**
122 * xDosAllocMemLow doesn't use OBJ_ANY. It should be used when the buffer
123 * is going to be used by 16 functions that fail to thunk high memory addresses properly
124 * such as DosQueryAppType, DosOpenL, DosGetMessage and DosReadQueue (probably others)
125 * Flags are hard coded PAG_COMMIT | PAG_READ | PAG_WRITE.
126 * The wrapper provides error checking.
127 */
128
[1627]129APIRET xDosAllocMemLow(PPVOID ppb,
[1839]130 ULONG cb,
131 PCSZ pszSrcFile,
132 UINT uiLineNumber)
[1627]133{
134 APIRET rc;
135
[1628]136 rc = DosAllocMem(ppb, cb, PAG_COMMIT | PAG_READ | PAG_WRITE);
[1627]137 if (rc)
138 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
139 //DbgMsg(pszSrcFile, uiLineNumber, "ppb %p", *ppb);
140 return rc;
141}
142
[1839]143APIRET xDosGetInfoBlocks(PTIB *pptib,
144 PPIB *pppib)
145{
146 APIRET apiret = DosGetInfoBlocks(pptib, pppib);
147
148 if (apiret) {
149 Dos_Error(MB_CANCEL, apiret, HWND_DESKTOP, pszSrcFile, __LINE__,
150 PCSZ_DOSGETINFOBLOCKS);
151 *pppib = 0;
152 *pptib = 0;
153 }
154 return apiret;
155}
156
[850]157APIRET xDosFindFirst(PSZ pszFileSpec,
158 PHDIR phdir,
159 ULONG flAttribute,
160 PVOID pfindbuf,
161 ULONG cbBuf,
162 PULONG pcFileNames,
163 ULONG ulInfoLevel)
[838]164{
[850]165 APIRET rc;
166 if (fNoLargeFileSupport) {
167 switch (ulInfoLevel) {
168 case FIL_STANDARDL:
169 {
170 FILEFINDBUF3 ffb3;
171 ulInfoLevel = FIL_STANDARD;
172 *pcFileNames = 1; // fixme to support larger counts
173 rc = DosFindFirst(pszFileSpec, phdir, flAttribute, &ffb3, sizeof(ffb3),
174 pcFileNames, ulInfoLevel);
175 if (!rc) {
176 *(PFILEFINDBUF3)pfindbuf = ffb3; // Copy aligned data
177 ((PFILEFINDBUF3L)pfindbuf)->cbFile = ffb3.cbFile; // Copy unaligned data
178 ((PFILEFINDBUF3L)pfindbuf)->cbFileAlloc = ffb3.cbFileAlloc;
179 ((PFILEFINDBUF3L)pfindbuf)->attrFile = ffb3.attrFile;
180 ((PFILEFINDBUF3L)pfindbuf)->cchName = ffb3.cchName;
181 memcpy(((PFILEFINDBUF3L)pfindbuf)->achName, ffb3.achName, ffb3.cchName + 1);
182 }
183 }
[849]184 break;
[850]185 case FIL_QUERYEASIZEL:
186 {
187 FILEFINDBUF4 ffb4;
188 *pcFileNames = 1; // fixme to support larger counts
189 ulInfoLevel = FIL_QUERYEASIZE;
190 rc = DosFindFirst(pszFileSpec, phdir, flAttribute, &ffb4, sizeof(ffb4),
191 pcFileNames, ulInfoLevel);
192 if (!rc) {
193 *(PFILEFINDBUF4)pfindbuf = ffb4; // Copy aligned data
194 ((PFILEFINDBUF4L)pfindbuf)->cbFile = ffb4.cbFile; // Copy unaligned data
195 ((PFILEFINDBUF4L)pfindbuf)->cbFileAlloc = ffb4.cbFileAlloc;
196 ((PFILEFINDBUF4L)pfindbuf)->attrFile = ffb4.attrFile;
197 ((PFILEFINDBUF4L)pfindbuf)->cbList = ffb4.cbList;
198 ((PFILEFINDBUF4L)pfindbuf)->cchName = ffb4.cchName;
199 memcpy(((PFILEFINDBUF4L)pfindbuf)->achName, ffb4.achName, ffb4.cchName + 1);
200 }
201 }
[849]202 break;
203 default:
[850]204 Runtime_Error(pszSrcFile, __LINE__, "ulInfoLevel %u unexpected", ulInfoLevel);
205 rc = ERROR_INVALID_PARAMETER;
206 } // switch
207 }
208 else
[838]209 rc = DosFindFirst(pszFileSpec, phdir, flAttribute, pfindbuf, cbBuf,
[850]210 pcFileNames, ulInfoLevel);
211 return rc;
[838]212}
213
[850]214APIRET xDosFindNext(HDIR hDir,
215 PVOID pfindbuf,
216 ULONG cbfindbuf,
217 PULONG pcFileNames,
218 ULONG ulInfoLevel)
[838]219{
220 APIRET rc;
[849]221 if (fNoLargeFileSupport) {
[850]222 switch (ulInfoLevel) {
223 case FIL_STANDARDL:
224 {
225 FILEFINDBUF3 ffb3;
226 *pcFileNames = 1; // fixme to support larger counts
227 rc = DosFindNext(hDir, &ffb3, sizeof(ffb3), pcFileNames);
228 if (!rc) {
229 *(PFILEFINDBUF3)pfindbuf = ffb3; // Copy aligned data
230 ((PFILEFINDBUF3L)pfindbuf)->cbFile = ffb3.cbFile; // Copy unaligned data
231 ((PFILEFINDBUF3L)pfindbuf)->cbFileAlloc = ffb3.cbFileAlloc;
232 ((PFILEFINDBUF3L)pfindbuf)->attrFile = ffb3.attrFile;
233 ((PFILEFINDBUF3L)pfindbuf)->cchName = ffb3.cchName;
234 memcpy(((PFILEFINDBUF3L)pfindbuf)->achName, ffb3.achName, ffb3.cchName + 1);
235 }
236 }
237 break;
238 case FIL_QUERYEASIZEL:
239 {
240 FILEFINDBUF4 ffb4;
241 *pcFileNames = 1; // fixme to support larger counts
242 rc = DosFindNext(hDir, &ffb4, sizeof(ffb4), pcFileNames);
243 if (!rc) {
244 *(PFILEFINDBUF4)pfindbuf = ffb4; // Copy aligned data
245 ((PFILEFINDBUF4L)pfindbuf)->cbFile = ffb4.cbFile; // Copy unaligned data
246 ((PFILEFINDBUF4L)pfindbuf)->cbFileAlloc = ffb4.cbFileAlloc;
247 ((PFILEFINDBUF4L)pfindbuf)->attrFile = ffb4.attrFile;
248 ((PFILEFINDBUF4L)pfindbuf)->cbList = ffb4.cbList;
249 ((PFILEFINDBUF4L)pfindbuf)->cchName = ffb4.cchName;
250 memcpy(((PFILEFINDBUF4L)pfindbuf)->achName, ffb4.achName, ffb4.cchName + 1);
251 }
252 }
253 break;
254 default:
255 Runtime_Error(pszSrcFile, __LINE__, "ulInfoLevel %u unexpected", ulInfoLevel);
256 rc = ERROR_INVALID_PARAMETER;
257 } // switch
[849]258 }
259 else
[850]260 rc = DosFindNext(hDir, pfindbuf, cbfindbuf, pcFileNames);
[838]261
262 return rc;
263}
264
[827]265/**
[850]266 * DosQueryPathInfo wrapper
267 * Translate request for systems without large file support
268 */
269
270APIRET xDosQueryPathInfo (PSZ pszPathName, ULONG ulInfoLevel, PVOID pInfoBuf, ULONG cbInfoBuf)
271{
272 FILESTATUS3 fs3;
273 FILESTATUS4 fs4;
274 APIRET rc;
275
276 if (fNoLargeFileSupport) {
277 switch (ulInfoLevel) {
278 case FIL_STANDARDL:
279 rc = DosQueryPathInfo(pszPathName, ulInfoLevel, &fs3, sizeof(fs3));
280 if (!rc) {
281 *(PFILESTATUS3)pInfoBuf = fs3; // Copy aligned data
282 ((PFILESTATUS3L)pInfoBuf)->cbFile = fs3.cbFile; // Copy unaligned data
283 ((PFILESTATUS3L)pInfoBuf)->cbFileAlloc = fs3.cbFileAlloc;
284 ((PFILESTATUS3L)pInfoBuf)->attrFile = fs3.attrFile;
285 }
286 break;
287 case FIL_QUERYEASIZEL:
288 rc = DosQueryPathInfo(pszPathName, ulInfoLevel, &fs4, sizeof(fs4));
289 if (!rc) {
290 *(PFILESTATUS4)pInfoBuf = fs4; // Copy aligned data
291 ((PFILESTATUS4L)pInfoBuf)->cbFile = fs4.cbFile; // Copy unaligned data
292 ((PFILESTATUS4L)pInfoBuf)->cbFileAlloc = fs4.cbFileAlloc;
293 ((PFILESTATUS4L)pInfoBuf)->attrFile = fs4.attrFile;
294 ((PFILESTATUS4L)pInfoBuf)->cbList = fs4.cbList;
295 }
296 break;
297 default:
298 Runtime_Error(pszSrcFile, __LINE__, "ulInfoLevel %u unexpected", ulInfoLevel);
299 rc = ERROR_INVALID_PARAMETER;
300 } // switch
301 }
302 else
[1432]303 rc = DosQueryPathInfo (pszPathName, ulInfoLevel, pInfoBuf, cbInfoBuf);
[850]304
305 return rc;
306}
307
308/**
309 * Wrap DosSetPathInfo to avoid spurious ERROR_INVALID_NAME returns and
310 * support systems without large file support
311 *
[1627]312 * Some kernels do not correctly handle FILESTATUS3 and PEAOP2 buffers
[827]313 * that cross a 64K boundary.
314 * When this occurs, they return ERROR_INVALID_NAME.
315 * This code works around the problem because if the passed buffer crosses
316 * the boundary the alternate buffer will not because both are on the stack
317 * and we don't put enough additional data on the stack for this to occur.
318 * It is caller's responsitibility to report errors
[847]319 * @param pInfoBuf pointer to FILESTATUS3(L) or EAOP2 buffer
320 * @param ulInfoLevel FIL_STANDARD(L) or FIL_QUERYEASIZE
[827]321 * @returns Same as DosSetPathInfo
322 */
323
[841]324APIRET xDosSetPathInfo(PSZ pszPathName,
[850]325 ULONG ulInfoLevel,
[841]326 PVOID pInfoBuf,
327 ULONG cbInfoBuf,
[850]328 ULONG flOptions)
[826]329{
[850]330 FILESTATUS3 fs3;
331 FILESTATUS3 fs3_a;
332 FILESTATUS3L fs3l;
333 EAOP2 eaop2;
[849]334 APIRET rc;
[968]335 BOOL crosses = ((ULONG)pInfoBuf ^
[1839]336 ((ULONG)pInfoBuf + cbInfoBuf - 1)) & ~0xffff;
[1354]337 BOOL fResetVerify = FALSE;
[850]338
[1354]339 if (fVerify && driveflags[toupper(*pszPathName) - 'A'] & DRIVE_WRITEVERIFYOFF) {
340 DosSetVerify(FALSE);
341 fResetVerify = TRUE;
342 }
[850]343 switch (ulInfoLevel) {
344 case FIL_STANDARD:
[1839]345 if (crosses) {
[968]346 fs3 = *(PFILESTATUS3)pInfoBuf; // Copy to buffer that does not cross 64K boundary
[1839]347 rc = DosSetPathInfo(pszPathName, ulInfoLevel, &fs3, cbInfoBuf, flOptions);
348 }
349 else
350 rc = DosSetPathInfo(pszPathName, ulInfoLevel, pInfoBuf, cbInfoBuf, flOptions);
[850]351 break;
352
353 case FIL_STANDARDL:
354 if (fNoLargeFileSupport) {
355 ulInfoLevel = FIL_STANDARD;
356 fs3 = *(PFILESTATUS3)pInfoBuf; // Copy aligned data
357 // Check size too big to handle
358 if (((PFILESTATUS3L)pInfoBuf)->cbFile >= 1LL << 32 ||
359 ((PFILESTATUS3L)pInfoBuf)->cbFileAlloc >= 2LL << 32)
360 {
361 rc = ERROR_INVALID_PARAMETER;
362 }
363 else {
364 fs3.cbFile = ((PFILESTATUS3L)pInfoBuf)->cbFile; // Copy unaligned data
365 fs3.cbFileAlloc = ((PFILESTATUS3L)pInfoBuf)->cbFileAlloc;
366 fs3.attrFile = ((PFILESTATUS3L)pInfoBuf)->attrFile;
367 rc = DosSetPathInfo(pszPathName, ulInfoLevel, &fs3, sizeof(fs3), flOptions);
368 }
369 if (rc == ERROR_INVALID_NAME) {
370 // fixme to validate counts?
371 fs3_a = fs3; // Copy to buffer that does not cross
372 rc = DosSetPathInfo(pszPathName, ulInfoLevel, &fs3_a, sizeof(fs3_a), flOptions);
373 }
374 }
375 else {
376 rc = DosSetPathInfo(pszPathName, ulInfoLevel, pInfoBuf, cbInfoBuf, flOptions);
377 if (rc == ERROR_INVALID_NAME) {
378 fs3l = *(PFILESTATUS3L)pInfoBuf; // Copy to buffer that does not cross
379 rc = DosSetPathInfo(pszPathName, ulInfoLevel, &fs3l, sizeof(fs3l), flOptions);
380 }
381 }
382 break;
383 case FIL_QUERYEASIZE:
384 rc = DosSetPathInfo(pszPathName, ulInfoLevel, pInfoBuf, cbInfoBuf, flOptions);
385 if (rc == ERROR_INVALID_NAME) {
386 // fixme to validate counts?
387 eaop2 = *(PEAOP2)pInfoBuf; // Copy to buffer that does not cross
388 rc = DosSetPathInfo(pszPathName, ulInfoLevel, &eaop2, sizeof(eaop2), flOptions);
[1839]389 }
390 break;
[827]391 default:
392 Runtime_Error(pszSrcFile, __LINE__, "ulInfoLevel %u unexpected", ulInfoLevel);
393 rc = ERROR_INVALID_PARAMETER;
[850]394 } // switch
[1354]395 if (fResetVerify) {
396 DosSetVerify(fVerify);
397 fResetVerify = FALSE;
398 }
[826]399 return rc;
400}
401
[551]402PSZ xfgets(PSZ pszBuf, size_t cMaxBytes, FILE * fp, PCSZ pszSrcFile,
403 UINT uiLineNumber)
[400]404{
[551]405 PSZ psz = fgets(pszBuf, cMaxBytes, fp);
406
[400]407 if (!psz) {
408 if (ferror(fp))
409 Runtime_Error(pszSrcFile, uiLineNumber, "fgets");
410 }
411 else {
412 size_t c = strlen(psz);
[551]413
[400]414 if (c + 1 > cMaxBytes)
415 Runtime_Error(pszSrcFile, uiLineNumber, "buffer overflow");
[551]416 else if (!c || (psz[c - 1] != '\n' && psz[c - 1] != '\r'))
[400]417 Runtime_Error(pszSrcFile, uiLineNumber, "missing EOL");
418 }
419 return psz;
420}
421
[551]422PSZ xfgets_bstripcr(PSZ pszBuf, size_t cMaxBytes, FILE * fp, PCSZ pszSrcFile,
423 UINT uiLineNumber)
[400]424{
[551]425 PSZ psz = xfgets(pszBuf, cMaxBytes, fp, pszSrcFile, uiLineNumber);
426
[400]427 if (psz)
428 bstripcr(psz);
429 return psz;
430}
431
[1544]432/**
433 * Wrapper for fopen it works around DosOpenL's failure to
434 * thunk properly so that fm2 can be loaded in high memory
435 * It also gives the option of reporting file open errors
436 * If fSilent is TRUE it fails silently; if FALSE it produces a
437 * runtime error dialog. Note pszMode must be passed on the stack
438 * to xfopen to avoid the thunking problem.
439 */
440
[551]441FILE *xfopen(PCSZ pszFileName, PCSZ pszMode, PCSZ pszSrcFile,
[1544]442 UINT uiLineNumber, BOOL fSilent)
[395]443{
[1544]444 CHAR FileName[CCHMAXPATH];
445 FILE *fp;
[551]446
[1544]447 strcpy(FileName, pszFileName);
448 fp = fopen(FileName, pszMode);
449
450 if (!fp && !fSilent)
[395]451 Runtime_Error(pszSrcFile, uiLineNumber, "fopen");
452 return fp;
453}
454
[1544]455/**
456 * Wrapper for _fsopen it works around DosOpenL's failure to
457 * thunk properly so that fm2 can be loaded in high memory
458 * It also gives the option of reporting file open errors
459 * If fSilent is TRUE it fails silently; if FALSE it produces a
460 * runtime error dialog. Note pszMode must be passed on the stack
461 * to xfopen to avoid the thunking problem
462 */
463
[551]464FILE *xfsopen(PCSZ pszFileName, PCSZ pszMode, INT fSharemode, PCSZ pszSrcFile,
[1839]465 UINT uiLineNumber, BOOL fSilent)
[395]466{
[1544]467 CHAR FileName[CCHMAXPATH];
468 FILE *fp;
[551]469
[1544]470 strcpy(FileName, pszFileName);
471 fp = _fsopen(FileName, pszMode, fSharemode);
[1639]472 if (!fp && !strcmp(pszMode, "r+") && !fSilent)
473 fp = _fsopen(FileName, "w+", fSharemode);
[1544]474
475 if (!fp && !fSilent)
[395]476 Runtime_Error(pszSrcFile, uiLineNumber, "_fsopen");
477 return fp;
478}
479
480//== xfree - safe free ==
481
[1009]482VOID xfree(PVOID pv, PCSZ pszSrcFile, UINT uiLineNumber)
[395]483{
[1009]484 if (pv && pv != NullStr) {
[1063]485# ifdef FORTIFY
[1009]486 Fortify_free(pv, pszSrcFile, uiLineNumber);
[1063]487# else
[395]488 free(pv);
[1063]489# endif
[1009]490
491 }
[395]492}
493
494//== xmalloc() malloc with error checking ==
495
496PVOID xmalloc(size_t cBytes, PCSZ pszSrcFile, UINT uiLineNumber)
497{
[1006]498# ifdef FORTIFY
499 PVOID pv = Fortify_malloc(cBytes, pszSrcFile, uiLineNumber);
[1011]500# else
[395]501 PVOID pv = malloc(cBytes);
[1063]502# endif
[395]503
504 if (!pv)
[551]505 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
[395]506
507 return pv;
508}
509
510//== xmallocz() malloc and zero with error checking ==
511
512PVOID xmallocz(size_t cBytes, PCSZ pszSrcFile, UINT uiLineNumber)
513{
[1011]514 PVOID pv = xmalloc(cBytes, pszSrcFile, uiLineNumber);
[395]515
[1011]516 if (pv)
[395]517 memset(pv, 0, cBytes);
518
519 return pv;
520}
521
522//== xrealloc() realloc with error checking ==
523
524PVOID xrealloc(PVOID pvIn, size_t cBytes, PCSZ pszSrcFile, UINT uiLineNumber)
525{
[963]526 if (pvIn != NullStr) {
[1063]527# ifdef FORTIFY
528 PVOID pv = Fortify_realloc(pvIn, cBytes, pszSrcFile, uiLineNumber);
529# else
530 PVOID pv = realloc(pvIn, cBytes);
531# endif
[395]532
[963]533 if (!pv && cBytes)
534 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
[395]535
[963]536 return pv;
537 }
538 else
539 return xmalloc(cBytes, pszSrcFile, uiLineNumber);
[395]540}
541
542//== xstrdup() strdup with error checking ==
543
544PVOID xstrdup(PCSZ pszIn, PCSZ pszSrcFile, UINT uiLineNumber)
545{
[1009]546# ifdef FORTIFY
547 PSZ psz = Fortify_strdup(pszIn, pszSrcFile, uiLineNumber);
[1011]548# else
[395]549 PSZ psz = strdup(pszIn);
[1063]550# endif
[395]551
552 if (!psz)
[551]553 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
[395]554
555 return psz;
556}
[794]557
[1032]558
559#pragma alloc_text(WRAPPERS1,xfree,xfopen,xfsopen,xmalloc,xrealloc,xstrdup)
[1037]560#pragma alloc_text(WRAPPERS2,xDosSetPathInfo,xDosFindFirst,xDosFindNext)
Note: See TracBrowser for help on using the repository browser.