source: trunk/dll/wrappers.c@ 1639

Last change on this file since 1639 was 1639, checked in by Gregg Young, 14 years ago

Fix list file creation failure when file doesn't exist. Ticket 477

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