source: trunk/dll/wrappers.c@ 1628

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

Hard coded the flags for the xDosAlloc* wrappers and added a description for each of them.

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