source: trunk/dll/wrappers.c@ 838

Last change on this file since 838 was 838, checked in by Gregg Young, 18 years ago

Remainder of changes for xDosFindFirst/Next wrapper performance test

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.3 KB
Line 
1
2/***********************************************************************
3
4 $Id: wrappers.c 838 2007-09-21 19:19:18Z gyoung $
5
6 Wrappers with error checking
7
8 Copyright (c) 2006 Steven H.Levine
9
10 22 Jul 06 SHL Baseline
11 29 Jul 06 SHL Add xgets_stripped
12 18 Aug 06 SHL Correct Runtime_Error line number report
13 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
14 01 Sep 07 GKY Add xDosSetPathInfo to fix case where FS3 buffer crosses 64k boundry
15
16***********************************************************************/
17
18#define INCL_WIN
19#define INCL_DOS
20#define INCL_DOSERRORS
21#include <os2.h>
22
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26
27#include "fm3dll.h"
28#include "fm3str.h"
29
30static PSZ pszSrcFile = __FILE__;
31
32APIRET APIENTRY xDosFindFirst(PSZ pszFileSpec,
33 PHDIR phdir,
34 ULONG flAttribute,
35 PVOID pfindbuf,
36 ULONG cbBuf,
37 PULONG pcFileNames,
38 ULONG ulInfoLevel)
39{
40 APIRET rc;
41
42 rc = DosFindFirst(pszFileSpec, phdir, flAttribute, pfindbuf, cbBuf,
43 pcFileNames, ulInfoLevel);
44 return rc;
45}
46
47APIRET APIENTRY xDosFindNext(HDIR hDir,
48 PVOID pfindbuf,
49 ULONG cbfindbuf,
50 PULONG pcFilenames)
51{
52 APIRET rc;
53
54 rc = DosFindNext(hDir, pfindbuf, cbfindbuf, pcFilenames);
55 return rc;
56}
57
58/**
59 * Wrap DosSetPathInfo to avoid spurious ERROR_INVALID_NAME returns
60 * Some kernels to do not correctly handle FILESTATUS3 and PEAOP2 buffers
61 * that cross a 64K boundary.
62 * When this occurs, they return ERROR_INVALID_NAME.
63 * This code works around the problem because if the passed buffer crosses
64 * the boundary the alternate buffer will not because both are on the stack
65 * and we don't put enough additional data on the stack for this to occur.
66 * It is caller's responsitibility to report errors
67 * @param pInfoBuf pointer to FILESTATUS3 or EAOP2 buffer
68 * @param ulInfoLevel FIL_STANDARD or FIL_QUERYEASIZE
69 * @returns Same as DosSetPathInfo
70 */
71
72APIRET APIENTRY xDosSetPathInfo(PSZ pszPathName,
73 ULONG ulInfoLevel,
74 PVOID pInfoBuf,
75 ULONG cbInfoBuf,
76 ULONG flOptions)
77{
78 APIRET rc = DosSetPathInfo(pszPathName, ulInfoLevel, pInfoBuf, cbInfoBuf, flOptions);
79 FILESTATUS3 alt_fs3;
80 EAOP2 alt_eaop2;
81 if (rc == ERROR_INVALID_NAME) {
82 switch (ulInfoLevel) {
83 case FIL_STANDARD:
84 alt_fs3 = *(PFILESTATUS3)pInfoBuf; // Copy
85 rc = DosSetPathInfo(pszPathName, ulInfoLevel, &alt_fs3, sizeof(alt_fs3), flOptions);
86 break;
87 case FIL_QUERYEASIZE:
88 alt_eaop2 = *(PEAOP2)pInfoBuf; // Copy
89 rc = DosSetPathInfo(pszPathName, ulInfoLevel, &alt_eaop2, sizeof(alt_eaop2), flOptions);
90 break;
91 default:
92 Runtime_Error(pszSrcFile, __LINE__, "ulInfoLevel %u unexpected", ulInfoLevel);
93 rc = ERROR_INVALID_PARAMETER;
94 } // switch
95 }
96 return rc;
97}
98
99PSZ xfgets(PSZ pszBuf, size_t cMaxBytes, FILE * fp, PCSZ pszSrcFile,
100 UINT uiLineNumber)
101{
102 PSZ psz = fgets(pszBuf, cMaxBytes, fp);
103
104 if (!psz) {
105 if (ferror(fp))
106 Runtime_Error(pszSrcFile, uiLineNumber, "fgets");
107 }
108 else {
109 size_t c = strlen(psz);
110
111 if (c + 1 > cMaxBytes)
112 Runtime_Error(pszSrcFile, uiLineNumber, "buffer overflow");
113 else if (!c || (psz[c - 1] != '\n' && psz[c - 1] != '\r'))
114 Runtime_Error(pszSrcFile, uiLineNumber, "missing EOL");
115 }
116 return psz;
117}
118
119PSZ xfgets_bstripcr(PSZ pszBuf, size_t cMaxBytes, FILE * fp, PCSZ pszSrcFile,
120 UINT uiLineNumber)
121{
122 PSZ psz = xfgets(pszBuf, cMaxBytes, fp, pszSrcFile, uiLineNumber);
123
124 if (psz)
125 bstripcr(psz);
126 return psz;
127}
128
129FILE *xfopen(PCSZ pszFileName, PCSZ pszMode, PCSZ pszSrcFile,
130 UINT uiLineNumber)
131{
132 FILE *fp = fopen(pszFileName, pszMode);
133
134 if (!fp)
135 Runtime_Error(pszSrcFile, uiLineNumber, "fopen");
136 return fp;
137}
138
139FILE *xfsopen(PCSZ pszFileName, PCSZ pszMode, INT fSharemode, PCSZ pszSrcFile,
140 UINT uiLineNumber)
141{
142 FILE *fp = _fsopen((PSZ) pszFileName, (PSZ) pszMode, fSharemode);
143
144 if (!fp)
145 Runtime_Error(pszSrcFile, uiLineNumber, "_fsopen");
146 return fp;
147}
148
149//== xfree - safe free ==
150
151VOID xfree(PVOID pv)
152{
153 if (pv)
154 free(pv);
155}
156
157//== xmalloc() malloc with error checking ==
158
159PVOID xmalloc(size_t cBytes, PCSZ pszSrcFile, UINT uiLineNumber)
160{
161 PVOID pv = malloc(cBytes);
162
163 if (!pv)
164 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
165
166 return pv;
167}
168
169//== xmallocz() malloc and zero with error checking ==
170
171PVOID xmallocz(size_t cBytes, PCSZ pszSrcFile, UINT uiLineNumber)
172{
173 PVOID pv = malloc(cBytes);
174
175 if (!pv)
176 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
177 else
178 memset(pv, 0, cBytes);
179
180 return pv;
181}
182
183//== xrealloc() realloc with error checking ==
184
185PVOID xrealloc(PVOID pvIn, size_t cBytes, PCSZ pszSrcFile, UINT uiLineNumber)
186{
187 PVOID pv = realloc(pvIn, cBytes);
188
189 if (!pv && cBytes)
190 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
191
192 return pv;
193
194}
195
196//== xstrdup() strdup with error checking ==
197
198PVOID xstrdup(PCSZ pszIn, PCSZ pszSrcFile, UINT uiLineNumber)
199{
200 PSZ psz = strdup(pszIn);
201
202 if (!psz)
203 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
204
205 return psz;
206}
207
208#pragma alloc_text(WRAPPERS1,xfree,xfopen,xfsopen,xmalloc,xrealloc, xstrdup)
209
Note: See TracBrowser for help on using the repository browser.