source: trunk/dll/wrappers.c@ 1880

Last change on this file since 1880 was 1880, checked in by Gregg Young, 10 years ago

Remove dead code and comments from remaining c files. #if 0 and #if NEVER were not addressed

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 27.4 KB
Line 
1
2/***********************************************************************
3
4 $Id: wrappers.c 1880 2015-10-12 18:26:16Z gyoung $
5
6 Wrappers with error checking
7
8 Copyright (c) 2006, 2015 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 06 Oct 07 SHL Add xDos...() wrappers to support systems wo/large file support (Gregg, Steven)
16 05 May 08 SHL Add FORTIFY support
17 25 Dec 08 GKY Add code to allow write verify to be turned off on a per drive basis
18 17 Jun 09 SHL Correct missing rc set
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
21 26 Aug 11 GKY Add a low mem version of xDosAlloc* wrappers; move error checking into all the
22 xDosAlloc* wrappers.
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.
25 12 Aug 15 JBS Ticket #522: Ensure no "highmem-unsafe" functions are called directly
26 1) New functions have been added
27 2) Code for unsafe-but-not-yet-used-by-FM/2 functions have been added in an
28 "#if 0" block for quick implementation should FM/2 start to use them.
29 Among these. xDosOpenL and xWinUpper still need work. The rest are ready for use.
30 20 Aug 15 SHL Add xDos...MutexSem and xDos..EventSem wrappers
31
32***********************************************************************/
33
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <ctype.h>
38
39#define INCL_WIN
40#define INCL_DOS
41#define INCL_DOSERRORS
42#define INCL_LONGLONG
43#include <os2.h>
44
45#include "fm3dll.h"
46#include "init.h" // Data declaration(s)
47#include "wrappers.h"
48#include "fm3str.h"
49#include "errutil.h" // Dos_Error...
50#include "strutil.h" // GetPString
51#include "command.h"
52#include "tools.h"
53#include "avl.h"
54#include "strips.h" // bstrip
55
56#include "fortify.h" // GetPString
57#include "info.h" // driveflags
58#include "notebook.h" // fVerify
59#include "pathutil.h" // MaxComLineStrg
60
61// Data definitions
62static PSZ pszSrcFile = __FILE__;
63
64#pragma data_seg(GLOBAL1)
65BOOL fNoLargeFileSupport;
66
67APIRET xDosDupHandle(HFILE hFile,
68 PHFILE phFile)
69{
70 APIRET rc;
71 HFILE hFileLow = *phFile;
72
73 rc = DosDupHandle(hFile, &hFileLow);
74 *phFile = hFileLow;
75 return rc;
76}
77
78APIRET xDosForceDelete(PSZ pszFileName)
79{
80 APIRET rc;
81 CHAR szFileNameLow[CCHMAXPATH];
82
83 strcpy(szFileNameLow, pszFileName);
84 rc = DosForceDelete(szFileNameLow);
85 return rc;
86}
87
88APIRET xDosQueryAppType(PCSZ pszName,
89 PULONG pFlags)
90{
91 APIRET rc;
92 ULONG ulFlagsLow;
93 CHAR szPgm[CCHMAXPATH];
94
95 strcpy(szPgm, pszName);
96 rc = DosQueryAppType(szPgm, &ulFlagsLow);
97 *pFlags = ulFlagsLow;
98 return rc;
99}
100
101APIRET xDosQueryHType(HFILE hFile,
102 PULONG pulType,
103 PULONG pulAttr)
104{
105 APIRET rc;
106 ULONG ulTypeLow, ulAttrLow;
107
108 rc = DosQueryHType(hFile, &ulTypeLow, &ulAttrLow);
109 *pulType = ulTypeLow;
110 *pulAttr = ulAttrLow;
111 return rc;
112}
113
114APIRET xDosStartSession(PSTARTDATA psd,
115 PULONG pulSessionID,
116 PPID ppid)
117{
118 APIRET rc;
119 ULONG ulSessionIDLow;
120 PID pidLow;
121 PSTARTDATA psdLow;
122 CHAR *pbSafe;
123 size_t cbSafe = sizeof(STARTDATA);
124 UINT ul0, ul1, ul2, ul3, ul4, ul5;
125
126 if (HIGH_MEMORY_ADDRESS(psd->PgmTitle))
127 {
128 ul0 = strlen((const char *)psd->PgmTitle) + 1;
129 cbSafe += ul0;
130 }
131 else
132 ul0 = 0;
133 if (HIGH_MEMORY_ADDRESS(psd->PgmName))
134 {
135 ul1 = strlen((const char *)psd->PgmName) + 1;
136 cbSafe += ul1;
137 }
138 else
139 ul1 = 0;
140 if (HIGH_MEMORY_ADDRESS(psd->TermQ))
141 {
142 ul2 = strlen((const char *)psd->TermQ) + 1;
143 cbSafe += ul2;
144 }
145 else
146 ul2 = 0;
147 if (HIGH_MEMORY_ADDRESS(psd->PgmInputs))
148 {
149 ul3 = strlen((const char *)psd->PgmInputs) + 1;
150 cbSafe += ul3;
151 }
152 else
153 ul3= 0;
154 if (HIGH_MEMORY_ADDRESS(psd->Environment))
155 {
156 const char *psz = (const char *)psd->Environment;
157 while (*psz)
158 psz = strchr(psz, '\0') + 1;
159 ul4 = (unsigned int *)psz - (unsigned int *)psd->Environment + 1;
160 cbSafe += ul4;
161 }
162 else
163 ul4 = 0;
164 if (HIGH_MEMORY_ADDRESS(psd->IconFile))
165 {
166 ul5 = strlen((const char *)psd->IconFile) + 1;
167 cbSafe += ul5;
168 }
169 else
170 ul5 = 0;
171 if (HIGH_MEMORY_ADDRESS(psd->ObjectBuffer) && psd->ObjectBuffLen)
172 cbSafe += psd->ObjectBuffLen;
173
174 rc = xDosAllocMemLow((void *)&psdLow,
175 cbSafe,
176 pszSrcFile,
177 __LINE__);
178 if (rc)
179 return ERROR_NOT_ENOUGH_MEMORY;
180
181 memcpy((PVOID)psdLow, (PVOID)psd, sizeof(STARTDATA));
182 pbSafe = (CHAR *)psdLow + sizeof(STARTDATA);
183 if (ul0)
184 {
185 memcpy(pbSafe, psd->PgmTitle, ul0);
186 psdLow->PgmTitle = pbSafe;
187 pbSafe += ul0;
188 }
189 if (ul1)
190 {
191 memcpy(pbSafe, psd->PgmName, ul1);
192 psdLow->PgmName = pbSafe;
193 pbSafe += ul1;
194 }
195 if (ul2)
196 {
197 memcpy(pbSafe, psd->TermQ, ul2);
198 psdLow->TermQ = (UCHAR *)pbSafe;
199 pbSafe += ul2;
200 }
201 if (ul3)
202 {
203 memcpy(pbSafe, psd->PgmInputs, ul3);
204 psdLow->PgmInputs = (UCHAR *)pbSafe;
205 pbSafe += ul3;
206 }
207 if (ul4)
208 {
209 memcpy(pbSafe, psd->Environment, ul4);
210 psdLow->Environment = (UCHAR *)pbSafe;
211 pbSafe += ul4;
212 }
213 if (ul5)
214 {
215 memcpy(pbSafe, psd->IconFile, ul5);
216 psdLow->IconFile = pbSafe;
217 pbSafe += ul5;
218 }
219 if (HIGH_MEMORY_ADDRESS(psd->ObjectBuffer) && psd->ObjectBuffLen)
220 psdLow->ObjectBuffer = pbSafe;
221
222 rc = DosStartSession(psdLow,
223 pulSessionID ? &ulSessionIDLow : NULL,
224 ppid ? &pidLow : NULL);
225
226 /* Set return values */
227 if (HIGH_MEMORY_ADDRESS(psd->ObjectBuffer) && psd->ObjectBuffLen)
228 memcpy(psd->ObjectBuffer, psdLow->ObjectBuffer, psd->ObjectBuffLen);
229 if (pulSessionID)
230 *pulSessionID = ulSessionIDLow;
231 if (ppid)
232 *ppid = pidLow;
233
234 /* cleanup and return. */
235 xfree(psdLow, pszSrcFile, __LINE__);
236 return rc;
237}
238
239
240//
241// "Other" wrapper functions
242//
243/**
244 * xDosAllocSharedMem uses OBJ_ANY on systems that support high memory use
245 * and falls back to low memory allocation where it is not supported.
246 * Flags are hard coded PAG_COMMIT | OBJ_GIVEABLE | PAG_READ | PAG_WRITE
247 * The wrapper provides error checking.
248 */
249
250APIRET xDosAllocSharedMem(PPVOID ppb,
251 PSZ pszName,
252 ULONG cb,
253 PCSZ pszSrcFile,
254 UINT uiLineNumber)
255{
256 APIRET rc;
257
258 rc = DosAllocSharedMem(ppb, pszName, cb,
259 PAG_COMMIT | OBJ_GIVEABLE | PAG_READ | PAG_WRITE | OBJ_ANY);
260 if (rc)
261 rc = DosAllocSharedMem(ppb, pszName, cb, PAG_COMMIT | OBJ_GIVEABLE | PAG_READ | PAG_WRITE);
262 if (rc)
263 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
264 return rc;
265}
266
267/**
268 * xDosAllocMem uses OBJ_ANY on systems that support high memory use
269 * and falls back to low memory allocation where it is not supported.
270 * Flags are hard coded PAG_COMMIT | PAG_READ | PAG_WRITE.
271 * The wrapper provides error checking.
272 */
273
274APIRET xDosAllocMem(PPVOID ppb,
275 ULONG cb,
276 PCSZ pszSrcFile,
277 UINT uiLineNumber)
278{
279 APIRET rc;
280
281 rc = DosAllocMem(ppb, cb, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_ANY);
282 if (rc)
283 rc = DosAllocMem(ppb, cb, PAG_COMMIT | PAG_READ | PAG_WRITE);
284 if (rc)
285 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
286 return rc;
287}
288
289/**
290 * xDosAllocMemLow doesn't use OBJ_ANY. It should be used when the buffer
291 * is going to be used by 16 functions that fail to thunk high memory addresses properly
292 * such as DosQueryAppType, DosOpenL, DosGetMessage and DosReadQueue (probably others)
293 * Flags are hard coded PAG_COMMIT | PAG_READ | PAG_WRITE.
294 * The wrapper provides error checking.
295 */
296
297APIRET xDosAllocMemLow(PPVOID ppb,
298 ULONG cb,
299 PCSZ pszSrcFile,
300 UINT uiLineNumber)
301{
302 APIRET rc;
303
304 rc = DosAllocMem(ppb, cb, PAG_COMMIT | PAG_READ | PAG_WRITE);
305 if (rc)
306 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
307 return rc;
308}
309
310APIRET xDosGetInfoBlocks(PTIB *pptib,
311 PPIB *pppib)
312{
313 APIRET apiret = DosGetInfoBlocks(pptib, pppib);
314
315 if (apiret) {
316 Dos_Error(MB_CANCEL, apiret, HWND_DESKTOP, pszSrcFile, __LINE__,
317 PCSZ_DOSGETINFOBLOCKS);
318 *pppib = 0;
319 *pptib = 0;
320 }
321 return apiret;
322}
323
324/**
325 * DosRequestMutexSem wrapper
326 */
327
328APIRET xDosRequestMutexSem(HMTX hmtx, ULONG ulTimeout)
329{
330 APIRET apiret = DosRequestMutexSem(hmtx, ulTimeout);
331
332 if (apiret && (ulTimeout == SEM_INDEFINITE_WAIT || apiret != ERROR_TIMEOUT)) {
333 Dos_Error(MB_CANCEL, apiret, HWND_DESKTOP, pszSrcFile, __LINE__,
334 PCSZ_DOSREQUESTMUTEXSEM);
335 }
336 return apiret;
337}
338
339/**
340 * DosReleaseMutexSem wrapper
341 */
342
343APIRET xDosReleaseMutexSem(HMTX hmtx)
344{
345 APIRET apiret = DosReleaseMutexSem(hmtx);
346
347 if (apiret) {
348 Dos_Error(MB_CANCEL, apiret, HWND_DESKTOP, pszSrcFile, __LINE__,
349 PCSZ_DOSRELEASEMUTEXSEM);
350 }
351 return apiret;
352}
353
354/**
355 * DosCreateEventSem wrapper
356 */
357
358APIRET xDosCreateEventSem (PSZ pszName,PHEV phev, ULONG flAttr, BOOL32 fState)
359{
360 APIRET apiret = DosCreateEventSem (pszName,phev, flAttr, fState);
361 if (apiret) {
362 Dos_Error(MB_CANCEL, apiret, HWND_DESKTOP, pszSrcFile, __LINE__,
363 PCSZ_DOSCREATEEVENTSEM);
364 }
365 return apiret;
366}
367
368/**
369 * DosWaitEventSem wrapper
370 */
371
372APIRET xDosWaitEventSem(HEV hev, ULONG ulTimeout)
373{
374 APIRET apiret = DosWaitEventSem(hev, ulTimeout);
375
376 if (apiret && (ulTimeout == SEM_INDEFINITE_WAIT || apiret != ERROR_TIMEOUT)) {
377 Dos_Error(MB_CANCEL, apiret, HWND_DESKTOP, pszSrcFile, __LINE__,
378 PCSZ_DOSWAITEVENTSEM);
379 }
380 return apiret;
381}
382
383/**
384 * DosPostEventSem wrapper
385 */
386
387APIRET xDosPostEventSem(HEV hev)
388{
389 APIRET apiret = DosPostEventSem(hev);
390
391 if (apiret && apiret != ERROR_ALREADY_POSTED) {
392 Dos_Error(MB_CANCEL, apiret, HWND_DESKTOP, pszSrcFile, __LINE__,
393 PCSZ_DOSPOSTEVENTSEM);
394 }
395 return apiret;
396}
397
398/**
399 * DosResetEventSem wrapper
400 */
401
402APIRET xDosResetEventSem(HEV hev, PULONG pulPostCt)
403{
404 APIRET apiret = DosResetEventSem(hev, pulPostCt);
405
406 if (apiret && apiret != ERROR_ALREADY_RESET) {
407 Dos_Error(MB_CANCEL, apiret, HWND_DESKTOP, pszSrcFile, __LINE__,
408 PCSZ_DOSRESETEVENTSEM);
409 }
410 return apiret;
411}
412
413/**
414 * DosFindFirst wrapper
415 */
416
417APIRET xDosFindFirst(PSZ pszFileSpec,
418 PHDIR phdir,
419 ULONG flAttribute,
420 PVOID pfindbuf,
421 ULONG cbBuf,
422 PULONG pcFileNames,
423 ULONG ulInfoLevel)
424{
425 APIRET rc;
426 if (fNoLargeFileSupport) {
427 switch (ulInfoLevel) {
428 case FIL_STANDARDL:
429 {
430 FILEFINDBUF3 ffb3;
431 ulInfoLevel = FIL_STANDARD;
432 *pcFileNames = 1; // fixme to support larger counts
433 rc = DosFindFirst(pszFileSpec, phdir, flAttribute, &ffb3, sizeof(ffb3),
434 pcFileNames, ulInfoLevel);
435 if (!rc) {
436 *(PFILEFINDBUF3)pfindbuf = ffb3; // Copy aligned data
437 ((PFILEFINDBUF3L)pfindbuf)->cbFile = ffb3.cbFile; // Copy unaligned data
438 ((PFILEFINDBUF3L)pfindbuf)->cbFileAlloc = ffb3.cbFileAlloc;
439 ((PFILEFINDBUF3L)pfindbuf)->attrFile = ffb3.attrFile;
440 ((PFILEFINDBUF3L)pfindbuf)->cchName = ffb3.cchName;
441 memcpy(((PFILEFINDBUF3L)pfindbuf)->achName, ffb3.achName, ffb3.cchName + 1);
442 }
443 }
444 break;
445 case FIL_QUERYEASIZEL:
446 {
447 FILEFINDBUF4 ffb4;
448 *pcFileNames = 1; // fixme to support larger counts
449 ulInfoLevel = FIL_QUERYEASIZE;
450 rc = DosFindFirst(pszFileSpec, phdir, flAttribute, &ffb4, sizeof(ffb4),
451 pcFileNames, ulInfoLevel);
452 if (!rc) {
453 *(PFILEFINDBUF4)pfindbuf = ffb4; // Copy aligned data
454 ((PFILEFINDBUF4L)pfindbuf)->cbFile = ffb4.cbFile; // Copy unaligned data
455 ((PFILEFINDBUF4L)pfindbuf)->cbFileAlloc = ffb4.cbFileAlloc;
456 ((PFILEFINDBUF4L)pfindbuf)->attrFile = ffb4.attrFile;
457 ((PFILEFINDBUF4L)pfindbuf)->cbList = ffb4.cbList;
458 ((PFILEFINDBUF4L)pfindbuf)->cchName = ffb4.cchName;
459 memcpy(((PFILEFINDBUF4L)pfindbuf)->achName, ffb4.achName, ffb4.cchName + 1);
460 }
461 }
462 break;
463 default:
464 Runtime_Error(pszSrcFile, __LINE__, "ulInfoLevel %u unexpected", ulInfoLevel);
465 rc = ERROR_INVALID_PARAMETER;
466 } // switch
467 }
468 else
469 rc = DosFindFirst(pszFileSpec, phdir, flAttribute, pfindbuf, cbBuf,
470 pcFileNames, ulInfoLevel);
471 return rc;
472}
473
474APIRET xDosFindNext(HDIR hDir,
475 PVOID pfindbuf,
476 ULONG cbfindbuf,
477 PULONG pcFileNames,
478 ULONG ulInfoLevel)
479{
480 APIRET rc;
481 if (fNoLargeFileSupport) {
482 switch (ulInfoLevel) {
483 case FIL_STANDARDL:
484 {
485 FILEFINDBUF3 ffb3;
486 *pcFileNames = 1; // fixme to support larger counts
487 rc = DosFindNext(hDir, &ffb3, sizeof(ffb3), pcFileNames);
488 if (!rc) {
489 *(PFILEFINDBUF3)pfindbuf = ffb3; // Copy aligned data
490 ((PFILEFINDBUF3L)pfindbuf)->cbFile = ffb3.cbFile; // Copy unaligned data
491 ((PFILEFINDBUF3L)pfindbuf)->cbFileAlloc = ffb3.cbFileAlloc;
492 ((PFILEFINDBUF3L)pfindbuf)->attrFile = ffb3.attrFile;
493 ((PFILEFINDBUF3L)pfindbuf)->cchName = ffb3.cchName;
494 memcpy(((PFILEFINDBUF3L)pfindbuf)->achName, ffb3.achName, ffb3.cchName + 1);
495 }
496 }
497 break;
498 case FIL_QUERYEASIZEL:
499 {
500 FILEFINDBUF4 ffb4;
501 *pcFileNames = 1; // fixme to support larger counts
502 rc = DosFindNext(hDir, &ffb4, sizeof(ffb4), pcFileNames);
503 if (!rc) {
504 *(PFILEFINDBUF4)pfindbuf = ffb4; // Copy aligned data
505 ((PFILEFINDBUF4L)pfindbuf)->cbFile = ffb4.cbFile; // Copy unaligned data
506 ((PFILEFINDBUF4L)pfindbuf)->cbFileAlloc = ffb4.cbFileAlloc;
507 ((PFILEFINDBUF4L)pfindbuf)->attrFile = ffb4.attrFile;
508 ((PFILEFINDBUF4L)pfindbuf)->cbList = ffb4.cbList;
509 ((PFILEFINDBUF4L)pfindbuf)->cchName = ffb4.cchName;
510 memcpy(((PFILEFINDBUF4L)pfindbuf)->achName, ffb4.achName, ffb4.cchName + 1);
511 }
512 }
513 break;
514 default:
515 Runtime_Error(pszSrcFile, __LINE__, "ulInfoLevel %u unexpected", ulInfoLevel);
516 rc = ERROR_INVALID_PARAMETER;
517 } // switch
518 }
519 else
520 rc = DosFindNext(hDir, pfindbuf, cbfindbuf, pcFileNames);
521
522 return rc;
523}
524
525/**
526 * DosQueryPathInfo wrapper
527 * Translate request for systems without large file support
528 */
529
530APIRET xDosQueryPathInfo (PSZ pszPathName, ULONG ulInfoLevel, PVOID pInfoBuf, ULONG cbInfoBuf)
531{
532 FILESTATUS3 fs3;
533 FILESTATUS4 fs4;
534 APIRET rc;
535
536 if (fNoLargeFileSupport) {
537 switch (ulInfoLevel) {
538 case FIL_STANDARDL:
539 rc = DosQueryPathInfo(pszPathName, ulInfoLevel, &fs3, sizeof(fs3));
540 if (!rc) {
541 *(PFILESTATUS3)pInfoBuf = fs3; // Copy aligned data
542 ((PFILESTATUS3L)pInfoBuf)->cbFile = fs3.cbFile; // Copy unaligned data
543 ((PFILESTATUS3L)pInfoBuf)->cbFileAlloc = fs3.cbFileAlloc;
544 ((PFILESTATUS3L)pInfoBuf)->attrFile = fs3.attrFile;
545 }
546 break;
547 case FIL_QUERYEASIZEL:
548 rc = DosQueryPathInfo(pszPathName, ulInfoLevel, &fs4, sizeof(fs4));
549 if (!rc) {
550 *(PFILESTATUS4)pInfoBuf = fs4; // Copy aligned data
551 ((PFILESTATUS4L)pInfoBuf)->cbFile = fs4.cbFile; // Copy unaligned data
552 ((PFILESTATUS4L)pInfoBuf)->cbFileAlloc = fs4.cbFileAlloc;
553 ((PFILESTATUS4L)pInfoBuf)->attrFile = fs4.attrFile;
554 ((PFILESTATUS4L)pInfoBuf)->cbList = fs4.cbList;
555 }
556 break;
557 default:
558 Runtime_Error(pszSrcFile, __LINE__, "ulInfoLevel %u unexpected", ulInfoLevel);
559 rc = ERROR_INVALID_PARAMETER;
560 } // switch
561 }
562 else
563 rc = DosQueryPathInfo (pszPathName, ulInfoLevel, pInfoBuf, cbInfoBuf);
564
565 return rc;
566}
567
568/**
569 * Wrap DosSetPathInfo to avoid spurious ERROR_INVALID_NAME returns and
570 * support systems without large file support
571 *
572 * Some kernels do not correctly handle FILESTATUS3 and PEAOP2 buffers
573 * that cross a 64K boundary.
574 * When this occurs, they return ERROR_INVALID_NAME.
575 *
576 * This code works around the problem because if the passed buffer crosses
577 * the boundary the alternate buffer will not because both are on the stack
578 * and we don't put enough additional data on the stack for this to occur.
579 *
580 * It is caller's responsitibility to report errors
581 * @param pInfoBuf pointer to FILESTATUS3(L) or EAOP2 buffer
582 * @param ulInfoLevel FIL_STANDARD(L) or FIL_QUERYEASIZE
583 * @returns Same as DosSetPathInfo
584 */
585
586APIRET xDosSetPathInfo(PSZ pszPathName,
587 ULONG ulInfoLevel,
588 PVOID pInfoBuf,
589 ULONG cbInfoBuf,
590 ULONG flOptions)
591{
592 FILESTATUS3 fs3;
593 FILESTATUS3 fs3_a;
594 FILESTATUS3L fs3l;
595 EAOP2 eaop2;
596 APIRET rc;
597 BOOL crosses = ((ULONG)pInfoBuf ^
598 ((ULONG)pInfoBuf + cbInfoBuf - 1)) & ~0xffff;
599 BOOL fResetVerify = FALSE;
600
601 if (fVerify && driveflags[toupper(*pszPathName) - 'A'] & DRIVE_WRITEVERIFYOFF) {
602 DosSetVerify(FALSE);
603 fResetVerify = TRUE;
604 }
605 switch (ulInfoLevel) {
606 case FIL_STANDARD:
607 if (crosses) {
608 fs3 = *(PFILESTATUS3)pInfoBuf; // Copy to buffer that does not cross 64K boundary
609 rc = DosSetPathInfo(pszPathName, ulInfoLevel, &fs3, cbInfoBuf, flOptions);
610 }
611 else
612 rc = DosSetPathInfo(pszPathName, ulInfoLevel, pInfoBuf, cbInfoBuf, flOptions);
613 break;
614
615 case FIL_STANDARDL:
616 if (fNoLargeFileSupport) {
617 ulInfoLevel = FIL_STANDARD;
618 fs3 = *(PFILESTATUS3)pInfoBuf; // Copy aligned data
619 // Check size too big to handle
620 if (((PFILESTATUS3L)pInfoBuf)->cbFile >= 1LL << 32 ||
621 ((PFILESTATUS3L)pInfoBuf)->cbFileAlloc >= 2LL << 32)
622 {
623 rc = ERROR_INVALID_PARAMETER;
624 }
625 else {
626 fs3.cbFile = ((PFILESTATUS3L)pInfoBuf)->cbFile; // Copy unaligned data
627 fs3.cbFileAlloc = ((PFILESTATUS3L)pInfoBuf)->cbFileAlloc;
628 fs3.attrFile = ((PFILESTATUS3L)pInfoBuf)->attrFile;
629 rc = DosSetPathInfo(pszPathName, ulInfoLevel, &fs3, sizeof(fs3), flOptions);
630 }
631 if (rc == ERROR_INVALID_NAME) {
632 // fixme to validate counts?
633 fs3_a = fs3; // Copy to buffer that does not cross
634 rc = DosSetPathInfo(pszPathName, ulInfoLevel, &fs3_a, sizeof(fs3_a), flOptions);
635 }
636 }
637 else {
638 rc = DosSetPathInfo(pszPathName, ulInfoLevel, pInfoBuf, cbInfoBuf, flOptions);
639 if (rc == ERROR_INVALID_NAME) {
640 fs3l = *(PFILESTATUS3L)pInfoBuf; // Copy to buffer that does not cross
641 rc = DosSetPathInfo(pszPathName, ulInfoLevel, &fs3l, sizeof(fs3l), flOptions);
642 }
643 }
644 break;
645 case FIL_QUERYEASIZE:
646 rc = DosSetPathInfo(pszPathName, ulInfoLevel, pInfoBuf, cbInfoBuf, flOptions);
647 if (rc == ERROR_INVALID_NAME) {
648 // fixme to validate counts?
649 eaop2 = *(PEAOP2)pInfoBuf; // Copy to buffer that does not cross
650 rc = DosSetPathInfo(pszPathName, ulInfoLevel, &eaop2, sizeof(eaop2), flOptions);
651 }
652 break;
653 default:
654 Runtime_Error(pszSrcFile, __LINE__, "ulInfoLevel %u unexpected", ulInfoLevel);
655 rc = ERROR_INVALID_PARAMETER;
656 } // switch
657 if (fResetVerify) {
658 DosSetVerify(fVerify);
659 fResetVerify = FALSE;
660 }
661 return rc;
662}
663
664PSZ xfgets(PSZ pszBuf, size_t cMaxBytes, FILE * fp, PCSZ pszSrcFile,
665 UINT uiLineNumber)
666{
667 PSZ psz = fgets(pszBuf, cMaxBytes, fp);
668
669 if (!psz) {
670 if (ferror(fp))
671 Runtime_Error(pszSrcFile, uiLineNumber, "fgets");
672 }
673 else {
674 size_t c = strlen(psz);
675
676 if (c + 1 > cMaxBytes)
677 Runtime_Error(pszSrcFile, uiLineNumber, "buffer overflow");
678 else if (!c || (psz[c - 1] != '\n' && psz[c - 1] != '\r'))
679 Runtime_Error(pszSrcFile, uiLineNumber, "missing EOL");
680 }
681 return psz;
682}
683
684PSZ xfgets_bstripcr(PSZ pszBuf, size_t cMaxBytes, FILE * fp, PCSZ pszSrcFile,
685 UINT uiLineNumber)
686{
687 PSZ psz = xfgets(pszBuf, cMaxBytes, fp, pszSrcFile, uiLineNumber);
688
689 if (psz)
690 bstripcr(psz);
691 return psz;
692}
693
694/**
695 * Wrapper for fopen it works around DosOpenL's failure to
696 * thunk properly so that fm2 can be loaded in high memory
697 * It also gives the option of reporting file open errors
698 * If fSilent is TRUE it fails silently; if FALSE it produces a
699 * runtime error dialog. Note pszMode must be passed on the stack
700 * to xfopen to avoid the thunking problem.
701 */
702
703FILE *xfopen(PCSZ pszFileName, PCSZ pszMode, PCSZ pszSrcFile,
704 UINT uiLineNumber, BOOL fSilent)
705{
706 CHAR FileName[CCHMAXPATH];
707 FILE *fp;
708
709 strcpy(FileName, pszFileName);
710 fp = fopen(FileName, pszMode);
711
712 if (!fp && !fSilent)
713 Runtime_Error(pszSrcFile, uiLineNumber, "fopen");
714 return fp;
715}
716
717/**
718 * Wrapper for _fsopen it works around DosOpenL's failure to
719 * thunk properly so that fm2 can be loaded in high memory
720 * It also gives the option of reporting file open errors
721 * If fSilent is TRUE it fails silently; if FALSE it produces a
722 * runtime error dialog. Note pszMode must be passed on the stack
723 * to xfopen to avoid the thunking problem
724 */
725
726FILE *xfsopen(PCSZ pszFileName, PCSZ pszMode, INT fSharemode, PCSZ pszSrcFile,
727 UINT uiLineNumber, BOOL fSilent)
728{
729 CHAR FileName[CCHMAXPATH];
730 FILE *fp;
731
732 strcpy(FileName, pszFileName);
733 fp = _fsopen(FileName, pszMode, fSharemode);
734 if (!fp && !strcmp(pszMode, "r+") && !fSilent)
735 fp = _fsopen(FileName, "w+", fSharemode);
736
737 if (!fp && !fSilent)
738 Runtime_Error(pszSrcFile, uiLineNumber, "_fsopen");
739 return fp;
740}
741
742//== xfree - safe free ==
743
744VOID xfree(PVOID pv, PCSZ pszSrcFile, UINT uiLineNumber)
745{
746 if (pv && pv != NullStr) {
747# ifdef FORTIFY
748 Fortify_free(pv, pszSrcFile, uiLineNumber);
749# else
750 free(pv);
751# endif
752
753 }
754}
755
756//== xmalloc() malloc with error checking ==
757
758PVOID xmalloc(size_t cBytes, PCSZ pszSrcFile, UINT uiLineNumber)
759{
760# ifdef FORTIFY
761 PVOID pv = Fortify_malloc(cBytes, pszSrcFile, uiLineNumber);
762# else
763 PVOID pv = malloc(cBytes);
764# endif
765
766 if (!pv)
767 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
768
769 return pv;
770}
771
772//== xmallocz() malloc and zero with error checking ==
773
774PVOID xmallocz(size_t cBytes, PCSZ pszSrcFile, UINT uiLineNumber)
775{
776 PVOID pv = xmalloc(cBytes, pszSrcFile, uiLineNumber);
777
778 if (pv)
779 memset(pv, 0, cBytes);
780
781 return pv;
782}
783
784//== xrealloc() realloc with error checking ==
785
786PVOID xrealloc(PVOID pvIn, size_t cBytes, PCSZ pszSrcFile, UINT uiLineNumber)
787{
788 if (pvIn != NullStr) {
789# ifdef FORTIFY
790 PVOID pv = Fortify_realloc(pvIn, cBytes, pszSrcFile, uiLineNumber);
791# else
792 PVOID pv = realloc(pvIn, cBytes);
793# endif
794
795 if (!pv && cBytes)
796 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
797
798 return pv;
799 }
800 else
801 return xmalloc(cBytes, pszSrcFile, uiLineNumber);
802}
803
804//== xstrdup() strdup with error checking ==
805
806PVOID xstrdup(PCSZ pszIn, PCSZ pszSrcFile, UINT uiLineNumber)
807{
808# ifdef FORTIFY
809 PSZ psz = Fortify_strdup(pszIn, pszSrcFile, uiLineNumber);
810# else
811 PSZ psz = strdup(pszIn);
812# endif
813
814 if (!psz)
815 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
816
817 return psz;
818}
819
820#if 0
821/*
822 * JBS: Wrappers for functions which...
823 * - are identified by klibc as "highmem-unsafe"
824 * - not yet used by FM/2
825 */
826
827// .H code for these functions
828// The following are ready to go.
829APIRET xDosCreatePipe(PHFILE phfReadHandle,
830 PHFILE phfWriteHandle,
831 ULONG ulPipeSize);
832
833APIRET xDosQueryFHState(HFILE hFile,
834 PULONG pulMode);
835
836#ifdef INCL_DOSNMPIPES
837APIRET xDosQueryNPHState(HPIPE hpipe,
838 PULONG pulState);
839#endif
840
841APIRET xDosSetDateTime(DATETIME *pdt);
842
843APIRET xDosSetFilePtr(HFILE hFile,
844 LONG lOffset,
845 ULONG ulOrigin,
846 PULONG pulPos);
847
848APIRET xDosSetFilePtrL(HFILE hFile,
849 LONGLONG llOffset,
850 ULONG ulOrigin,
851 PLONGLONG pllPos);
852
853#ifdef INCL_DOSPROCESS
854APIRET xDosWaitChild(ULONG ulAction,
855 ULONG ulWait,
856 PRESULTCODES pReturnCodes,
857 PPID ppidOut,
858 PID pidIn);
859#endif
860
861APIRET xDosWaitNPipe(PCSZ pszName,
862 ULONG ulTimeout);
863
864// The following functions still need work
865ULONG xWinUpper(HAB hab,
866 ULONG idcp,
867 ULONG idcc,
868 PSZ psz);
869
870APIRET xDosOpenL(PCSZ pszFileName,
871 PHFILE phFile,
872 PULONG pulAction,
873 LONGLONG llFileSize,
874 ULONG ulAttribute,
875 ULONG ulOpenFlags,
876 ULONG ulOpenMode,
877 PEAOP2 pEABuf);
878
879
880
881// .C code for the functions above
882APIRET xDosCreatePipe(PHFILE phfReadHandle,
883 PHFILE phfWriteHandle,
884 ULONG ulPipeSize)
885{
886 APIRET rc;
887 HFILE h1, h2;
888 PHFILE ph1 = NULL;
889 PHFILE ph2 = NULL;
890
891 if (phfReadHandle)
892 {
893 h1 = *phfReadHandle;
894 ph1 = &h1;
895 }
896 if (phfWriteHandle)
897 {
898 h2 = *phfWriteHandle;
899 ph2 = &h2;
900 }
901
902 rc = DosCreatePipe(ph1, ph2, ulPipeSize);
903
904 if (phfReadHandle)
905 *phfReadHandle = h1;
906 if (phfWriteHandle)
907 *phfWriteHandle = h2;
908 return rc;
909}
910
911// Code pEABuf
912APIRET xDosOpenL(PCSZ pszFileName,
913 PHFILE phFile,
914 PULONG pulAction,
915 LONGLONG llFileSize,
916 ULONG ulAttribute,
917 ULONG ulOpenFlags,
918 ULONG ulOpenMode,
919 PEAOP2 pEABuf)
920{
921 APIRET rc;
922 ULONG ul1;
923 PULONG pul1 = NULL;
924 HFILE hf1;
925 PHFILE phf1 = NULL;
926 char szFileNameLow[CCHMAXPATH];
927
928 strcpy(szFileNameLow, pszFileName);
929
930 if (phFile)
931 {
932 hf1 = *phFile;
933 phf1 = &hf1;
934 }
935 if (pulAction)
936 {
937 ul1 = *pulAction;
938 pul1 = &ul1;
939 }
940
941/** @todo pEABuf */
942
943 rc = DosOpenL(szFileNameLow, phf1, pul1, llFileSize, ulAttribute,
944 ulOpenFlags, ulOpenMode, pEABuf);
945
946 if (phFile)
947 *phFile = hf1;
948 if (pulAction)
949 *pulAction = ul1;
950
951 return rc;
952}
953
954APIRET xDosQueryNPHState(HPIPE hpipe,
955 PULONG pulState)
956{
957 APIRET rc;
958 ULONG ul1;
959 PULONG pul1 = NULL;
960
961 if (pulState)
962 {
963 ul1 = *pulState;
964 pul1 = &ul1;
965 }
966
967 rc = DosQueryNPHState(hpipe, pul1);
968
969 if (pulState)
970 *pulState = ul1;
971 return rc;
972}
973
974APIRET xDosQueryFHState(HFILE hFile,
975 PULONG pulMode)
976{
977 APIRET rc;
978 ULONG ul1;
979 PULONG pul1 = NULL;
980
981 if (pulMode)
982 {
983 ul1 = *pulMode;
984 pul1 = &ul1;
985 }
986
987 rc = DosQueryFHState(hFile, pul1);
988
989 if (pulMode)
990 *pulMode = ul1;
991
992 return rc;
993}
994
995APIRET xDosSetDateTime(DATETIME *pdt)
996{
997 APIRET rc;
998 DATETIME dt1;
999 PDATETIME pdt1 = NULL;
1000
1001 if (pdt)
1002 {
1003 dt1 = *pdt;
1004 pdt1 = &dt1;
1005 }
1006
1007 rc = DosSetDateTime(pdt1);
1008
1009 return rc;
1010}
1011
1012APIRET xDosSetFilePtr(HFILE hFile,
1013 LONG lOffset,
1014 ULONG ulOrigin,
1015 PULONG pulPos)
1016{
1017 APIRET rc;
1018 ULONG ul1;
1019 PULONG pul1 = NULL;
1020
1021 if (pulPos)
1022 {
1023 ul1 = *pulPos;
1024 pul1 = &ul1;
1025 }
1026
1027 rc = DosSetFilePtr(hFile, lOffset, ulOrigin, pul1);
1028
1029 if (pulPos)
1030 *pulPos = ul1;
1031
1032 return rc;
1033}
1034
1035APIRET xDosSetFilePtrL(HFILE hFile,
1036 LONGLONG llOffset,
1037 ULONG ulOrigin,
1038 PLONGLONG pllPos)
1039{
1040 APIRET rc;
1041 LONGLONG ll1;
1042 PLONGLONG pll1 = NULL;
1043
1044 if (pllPos)
1045 {
1046 ll1 = *pllPos;
1047 pll1 = &ll1;
1048 }
1049
1050 rc = DosSetFilePtrL(hFile, llOffset, ulOrigin, pll1);
1051
1052 if (pllPos)
1053 *pllPos = ll1;
1054
1055 return rc;
1056}
1057
1058APIRET xDosWaitChild(ULONG ulAction,
1059 ULONG ulWait,
1060 PRESULTCODES pReturnCodes,
1061 PPID ppidOut,
1062 PID pidIn)
1063{
1064 APIRET rc;
1065 RESULTCODES res;
1066 PRESULTCODES pres = NULL;
1067 PID pid;
1068 PPID ppid = NULL;
1069
1070 if (pReturnCodes)
1071 {
1072 res = *pReturnCodes;
1073 pres = &res;
1074 }
1075 if (ppidOut)
1076 {
1077 pid = *ppidOut;
1078 ppid = &pid;
1079 }
1080
1081 rc = DosWaitChild(ulAction, ulWait, pres, ppid, pidIn);
1082
1083 if (pReturnCodes)
1084 *pReturnCodes = res;
1085 if (ppidOut)
1086 *ppidOut = pid;
1087
1088 return rc;
1089}
1090
1091APIRET xDosWaitNPipe(PCSZ pszName,
1092 ULONG ulTimeout)
1093{
1094 APIRET rc;
1095 char szNameLow[CCHMAXPATH];
1096
1097 strcpy(szNameLow, pszName);
1098 rc = DosWaitNPipe(szNameLow, ulTimeout);
1099 return rc;
1100}
1101
1102ULONG xWinUpper(HAB hab,
1103 ULONG idcp,
1104 ULONG idcc,
1105 PSZ psz)
1106{
1107 ULONG rc;
1108
1109 if (!HIGH_MEMORY_ADDRESS(psz))
1110 rc = WinUpper(hab, idcp, idcc, psz);
1111 else {
1112 size_t cch = strlen(psz);
1113 char *pszTmp = xmalloc(cch + 3, pszSrcFile, __LINE__);
1114 if (pszTmp)
1115 {
1116 memcpy(pszTmp, psz, cch + 1);
1117 pszTmp[cch + 1] = '\0';
1118 pszTmp[cch + 2] = '\0';
1119 rc = WinUpper(hab, idcp, idcc, pszTmp);
1120 if (rc > 0)
1121 memcpy(psz, pszTmp, rc <= cch ? rc + 1 : rc);
1122 xfree(pszTmp, pszSrcFile, __LINE__);
1123 }
1124 else
1125 {
1126 PSZ pszStart = psz;
1127 PSZ pszNext;
1128 while (*psz)
1129 {
1130 pszNext = (PSZ)WinNextChar(hab, idcp, idcc, psz);
1131 if (pszNext - psz == 1)
1132 *psz = WinUpperChar(hab, idcp, idcc, *psz);
1133 else if (pszNext - psz == 2)
1134 *(PUSHORT)psz = WinUpperChar(hab, idcp, idcc, *(PUSHORT)psz); /* a wild guess. */
1135 else
1136 break;
1137 psz = (char *)pszNext;
1138 }
1139 rc = psz - pszStart;
1140 }
1141 }
1142 return rc;
1143}
1144
1145#endif
1146
1147
1148#pragma alloc_text(WRAPPERS1,xfree,xfopen,xfsopen,xmalloc,xrealloc,xstrdup)
1149#pragma alloc_text(WRAPPERS2,xDosSetPathInfo,xDosFindFirst,xDosFindNext)
Note: See TracBrowser for help on using the repository browser.