source: trunk/dll/wrappers.c@ 1877

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

Remove debug code

  • 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 1877 2015-10-11 21:43:27Z 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 //DbgMsg(pszSrcFile, uiLineNumber, "ppb %p", *ppb);
308 return rc;
309}
310
311APIRET xDosGetInfoBlocks(PTIB *pptib,
312 PPIB *pppib)
313{
314 APIRET apiret = DosGetInfoBlocks(pptib, pppib);
315
316 if (apiret) {
317 Dos_Error(MB_CANCEL, apiret, HWND_DESKTOP, pszSrcFile, __LINE__,
318 PCSZ_DOSGETINFOBLOCKS);
319 *pppib = 0;
320 *pptib = 0;
321 }
322 return apiret;
323}
324
325/**
326 * DosRequestMutexSem wrapper
327 */
328
329APIRET xDosRequestMutexSem(HMTX hmtx, ULONG ulTimeout)
330{
331 APIRET apiret = DosRequestMutexSem(hmtx, ulTimeout);
332
333 if (apiret && (ulTimeout == SEM_INDEFINITE_WAIT || apiret != ERROR_TIMEOUT)) {
334 Dos_Error(MB_CANCEL, apiret, HWND_DESKTOP, pszSrcFile, __LINE__,
335 PCSZ_DOSREQUESTMUTEXSEM);
336 }
337 return apiret;
338}
339
340/**
341 * DosReleaseMutexSem wrapper
342 */
343
344APIRET xDosReleaseMutexSem(HMTX hmtx)
345{
346 APIRET apiret = DosReleaseMutexSem(hmtx);
347
348 if (apiret) {
349 Dos_Error(MB_CANCEL, apiret, HWND_DESKTOP, pszSrcFile, __LINE__,
350 PCSZ_DOSRELEASEMUTEXSEM);
351 }
352 return apiret;
353}
354
355/**
356 * DosCreateEventSem wrapper
357 */
358
359APIRET xDosCreateEventSem (PSZ pszName,PHEV phev, ULONG flAttr, BOOL32 fState)
360{
361 APIRET apiret = DosCreateEventSem (pszName,phev, flAttr, fState);
362 if (apiret) {
363 Dos_Error(MB_CANCEL, apiret, HWND_DESKTOP, pszSrcFile, __LINE__,
364 PCSZ_DOSCREATEEVENTSEM);
365 }
366 return apiret;
367}
368
369/**
370 * DosWaitEventSem wrapper
371 */
372
373APIRET xDosWaitEventSem(HEV hev, ULONG ulTimeout)
374{
375 APIRET apiret = DosWaitEventSem(hev, ulTimeout);
376
377 if (apiret && (ulTimeout == SEM_INDEFINITE_WAIT || apiret != ERROR_TIMEOUT)) {
378 Dos_Error(MB_CANCEL, apiret, HWND_DESKTOP, pszSrcFile, __LINE__,
379 PCSZ_DOSWAITEVENTSEM);
380 }
381 return apiret;
382}
383
384/**
385 * DosPostEventSem wrapper
386 */
387
388APIRET xDosPostEventSem(HEV hev)
389{
390 APIRET apiret = DosPostEventSem(hev);
391
392 if (apiret && apiret != ERROR_ALREADY_POSTED) {
393 Dos_Error(MB_CANCEL, apiret, HWND_DESKTOP, pszSrcFile, __LINE__,
394 PCSZ_DOSPOSTEVENTSEM);
395 }
396 return apiret;
397}
398
399/**
400 * DosResetEventSem wrapper
401 */
402
403APIRET xDosResetEventSem(HEV hev, PULONG pulPostCt)
404{
405 APIRET apiret = DosResetEventSem(hev, pulPostCt);
406
407 if (apiret && apiret != ERROR_ALREADY_RESET) {
408 Dos_Error(MB_CANCEL, apiret, HWND_DESKTOP, pszSrcFile, __LINE__,
409 PCSZ_DOSRESETEVENTSEM);
410 }
411 return apiret;
412}
413
414/**
415 * DosFindFirst wrapper
416 */
417
418APIRET xDosFindFirst(PSZ pszFileSpec,
419 PHDIR phdir,
420 ULONG flAttribute,
421 PVOID pfindbuf,
422 ULONG cbBuf,
423 PULONG pcFileNames,
424 ULONG ulInfoLevel)
425{
426 APIRET rc;
427 if (fNoLargeFileSupport) {
428 switch (ulInfoLevel) {
429 case FIL_STANDARDL:
430 {
431 FILEFINDBUF3 ffb3;
432 ulInfoLevel = FIL_STANDARD;
433 *pcFileNames = 1; // fixme to support larger counts
434 rc = DosFindFirst(pszFileSpec, phdir, flAttribute, &ffb3, sizeof(ffb3),
435 pcFileNames, ulInfoLevel);
436 if (!rc) {
437 *(PFILEFINDBUF3)pfindbuf = ffb3; // Copy aligned data
438 ((PFILEFINDBUF3L)pfindbuf)->cbFile = ffb3.cbFile; // Copy unaligned data
439 ((PFILEFINDBUF3L)pfindbuf)->cbFileAlloc = ffb3.cbFileAlloc;
440 ((PFILEFINDBUF3L)pfindbuf)->attrFile = ffb3.attrFile;
441 ((PFILEFINDBUF3L)pfindbuf)->cchName = ffb3.cchName;
442 memcpy(((PFILEFINDBUF3L)pfindbuf)->achName, ffb3.achName, ffb3.cchName + 1);
443 }
444 }
445 break;
446 case FIL_QUERYEASIZEL:
447 {
448 FILEFINDBUF4 ffb4;
449 *pcFileNames = 1; // fixme to support larger counts
450 ulInfoLevel = FIL_QUERYEASIZE;
451 rc = DosFindFirst(pszFileSpec, phdir, flAttribute, &ffb4, sizeof(ffb4),
452 pcFileNames, ulInfoLevel);
453 if (!rc) {
454 *(PFILEFINDBUF4)pfindbuf = ffb4; // Copy aligned data
455 ((PFILEFINDBUF4L)pfindbuf)->cbFile = ffb4.cbFile; // Copy unaligned data
456 ((PFILEFINDBUF4L)pfindbuf)->cbFileAlloc = ffb4.cbFileAlloc;
457 ((PFILEFINDBUF4L)pfindbuf)->attrFile = ffb4.attrFile;
458 ((PFILEFINDBUF4L)pfindbuf)->cbList = ffb4.cbList;
459 ((PFILEFINDBUF4L)pfindbuf)->cchName = ffb4.cchName;
460 memcpy(((PFILEFINDBUF4L)pfindbuf)->achName, ffb4.achName, ffb4.cchName + 1);
461 }
462 }
463 break;
464 default:
465 Runtime_Error(pszSrcFile, __LINE__, "ulInfoLevel %u unexpected", ulInfoLevel);
466 rc = ERROR_INVALID_PARAMETER;
467 } // switch
468 }
469 else
470 rc = DosFindFirst(pszFileSpec, phdir, flAttribute, pfindbuf, cbBuf,
471 pcFileNames, ulInfoLevel);
472 return rc;
473}
474
475APIRET xDosFindNext(HDIR hDir,
476 PVOID pfindbuf,
477 ULONG cbfindbuf,
478 PULONG pcFileNames,
479 ULONG ulInfoLevel)
480{
481 APIRET rc;
482 if (fNoLargeFileSupport) {
483 switch (ulInfoLevel) {
484 case FIL_STANDARDL:
485 {
486 FILEFINDBUF3 ffb3;
487 *pcFileNames = 1; // fixme to support larger counts
488 rc = DosFindNext(hDir, &ffb3, sizeof(ffb3), pcFileNames);
489 if (!rc) {
490 *(PFILEFINDBUF3)pfindbuf = ffb3; // Copy aligned data
491 ((PFILEFINDBUF3L)pfindbuf)->cbFile = ffb3.cbFile; // Copy unaligned data
492 ((PFILEFINDBUF3L)pfindbuf)->cbFileAlloc = ffb3.cbFileAlloc;
493 ((PFILEFINDBUF3L)pfindbuf)->attrFile = ffb3.attrFile;
494 ((PFILEFINDBUF3L)pfindbuf)->cchName = ffb3.cchName;
495 memcpy(((PFILEFINDBUF3L)pfindbuf)->achName, ffb3.achName, ffb3.cchName + 1);
496 }
497 }
498 break;
499 case FIL_QUERYEASIZEL:
500 {
501 FILEFINDBUF4 ffb4;
502 *pcFileNames = 1; // fixme to support larger counts
503 rc = DosFindNext(hDir, &ffb4, sizeof(ffb4), pcFileNames);
504 if (!rc) {
505 *(PFILEFINDBUF4)pfindbuf = ffb4; // Copy aligned data
506 ((PFILEFINDBUF4L)pfindbuf)->cbFile = ffb4.cbFile; // Copy unaligned data
507 ((PFILEFINDBUF4L)pfindbuf)->cbFileAlloc = ffb4.cbFileAlloc;
508 ((PFILEFINDBUF4L)pfindbuf)->attrFile = ffb4.attrFile;
509 ((PFILEFINDBUF4L)pfindbuf)->cbList = ffb4.cbList;
510 ((PFILEFINDBUF4L)pfindbuf)->cchName = ffb4.cchName;
511 memcpy(((PFILEFINDBUF4L)pfindbuf)->achName, ffb4.achName, ffb4.cchName + 1);
512 }
513 }
514 break;
515 default:
516 Runtime_Error(pszSrcFile, __LINE__, "ulInfoLevel %u unexpected", ulInfoLevel);
517 rc = ERROR_INVALID_PARAMETER;
518 } // switch
519 }
520 else
521 rc = DosFindNext(hDir, pfindbuf, cbfindbuf, pcFileNames);
522
523 return rc;
524}
525
526/**
527 * DosQueryPathInfo wrapper
528 * Translate request for systems without large file support
529 */
530
531APIRET xDosQueryPathInfo (PSZ pszPathName, ULONG ulInfoLevel, PVOID pInfoBuf, ULONG cbInfoBuf)
532{
533 FILESTATUS3 fs3;
534 FILESTATUS4 fs4;
535 APIRET rc;
536
537 if (fNoLargeFileSupport) {
538 switch (ulInfoLevel) {
539 case FIL_STANDARDL:
540 rc = DosQueryPathInfo(pszPathName, ulInfoLevel, &fs3, sizeof(fs3));
541 if (!rc) {
542 *(PFILESTATUS3)pInfoBuf = fs3; // Copy aligned data
543 ((PFILESTATUS3L)pInfoBuf)->cbFile = fs3.cbFile; // Copy unaligned data
544 ((PFILESTATUS3L)pInfoBuf)->cbFileAlloc = fs3.cbFileAlloc;
545 ((PFILESTATUS3L)pInfoBuf)->attrFile = fs3.attrFile;
546 }
547 break;
548 case FIL_QUERYEASIZEL:
549 rc = DosQueryPathInfo(pszPathName, ulInfoLevel, &fs4, sizeof(fs4));
550 if (!rc) {
551 *(PFILESTATUS4)pInfoBuf = fs4; // Copy aligned data
552 ((PFILESTATUS4L)pInfoBuf)->cbFile = fs4.cbFile; // Copy unaligned data
553 ((PFILESTATUS4L)pInfoBuf)->cbFileAlloc = fs4.cbFileAlloc;
554 ((PFILESTATUS4L)pInfoBuf)->attrFile = fs4.attrFile;
555 ((PFILESTATUS4L)pInfoBuf)->cbList = fs4.cbList;
556 }
557 break;
558 default:
559 Runtime_Error(pszSrcFile, __LINE__, "ulInfoLevel %u unexpected", ulInfoLevel);
560 rc = ERROR_INVALID_PARAMETER;
561 } // switch
562 }
563 else
564 rc = DosQueryPathInfo (pszPathName, ulInfoLevel, pInfoBuf, cbInfoBuf);
565
566 return rc;
567}
568
569/**
570 * Wrap DosSetPathInfo to avoid spurious ERROR_INVALID_NAME returns and
571 * support systems without large file support
572 *
573 * Some kernels do not correctly handle FILESTATUS3 and PEAOP2 buffers
574 * that cross a 64K boundary.
575 * When this occurs, they return ERROR_INVALID_NAME.
576 *
577 * This code works around the problem because if the passed buffer crosses
578 * the boundary the alternate buffer will not because both are on the stack
579 * and we don't put enough additional data on the stack for this to occur.
580 *
581 * It is caller's responsitibility to report errors
582 * @param pInfoBuf pointer to FILESTATUS3(L) or EAOP2 buffer
583 * @param ulInfoLevel FIL_STANDARD(L) or FIL_QUERYEASIZE
584 * @returns Same as DosSetPathInfo
585 */
586
587APIRET xDosSetPathInfo(PSZ pszPathName,
588 ULONG ulInfoLevel,
589 PVOID pInfoBuf,
590 ULONG cbInfoBuf,
591 ULONG flOptions)
592{
593 FILESTATUS3 fs3;
594 FILESTATUS3 fs3_a;
595 FILESTATUS3L fs3l;
596 EAOP2 eaop2;
597 APIRET rc;
598 BOOL crosses = ((ULONG)pInfoBuf ^
599 ((ULONG)pInfoBuf + cbInfoBuf - 1)) & ~0xffff;
600 BOOL fResetVerify = FALSE;
601
602 if (fVerify && driveflags[toupper(*pszPathName) - 'A'] & DRIVE_WRITEVERIFYOFF) {
603 DosSetVerify(FALSE);
604 fResetVerify = TRUE;
605 }
606 switch (ulInfoLevel) {
607 case FIL_STANDARD:
608 if (crosses) {
609 fs3 = *(PFILESTATUS3)pInfoBuf; // Copy to buffer that does not cross 64K boundary
610 rc = DosSetPathInfo(pszPathName, ulInfoLevel, &fs3, cbInfoBuf, flOptions);
611 }
612 else
613 rc = DosSetPathInfo(pszPathName, ulInfoLevel, pInfoBuf, cbInfoBuf, flOptions);
614 break;
615
616 case FIL_STANDARDL:
617 if (fNoLargeFileSupport) {
618 ulInfoLevel = FIL_STANDARD;
619 fs3 = *(PFILESTATUS3)pInfoBuf; // Copy aligned data
620 // Check size too big to handle
621 if (((PFILESTATUS3L)pInfoBuf)->cbFile >= 1LL << 32 ||
622 ((PFILESTATUS3L)pInfoBuf)->cbFileAlloc >= 2LL << 32)
623 {
624 rc = ERROR_INVALID_PARAMETER;
625 }
626 else {
627 fs3.cbFile = ((PFILESTATUS3L)pInfoBuf)->cbFile; // Copy unaligned data
628 fs3.cbFileAlloc = ((PFILESTATUS3L)pInfoBuf)->cbFileAlloc;
629 fs3.attrFile = ((PFILESTATUS3L)pInfoBuf)->attrFile;
630 rc = DosSetPathInfo(pszPathName, ulInfoLevel, &fs3, sizeof(fs3), flOptions);
631 }
632 if (rc == ERROR_INVALID_NAME) {
633 // fixme to validate counts?
634 fs3_a = fs3; // Copy to buffer that does not cross
635 rc = DosSetPathInfo(pszPathName, ulInfoLevel, &fs3_a, sizeof(fs3_a), flOptions);
636 }
637 }
638 else {
639 rc = DosSetPathInfo(pszPathName, ulInfoLevel, pInfoBuf, cbInfoBuf, flOptions);
640 if (rc == ERROR_INVALID_NAME) {
641 fs3l = *(PFILESTATUS3L)pInfoBuf; // Copy to buffer that does not cross
642 rc = DosSetPathInfo(pszPathName, ulInfoLevel, &fs3l, sizeof(fs3l), flOptions);
643 }
644 }
645 break;
646 case FIL_QUERYEASIZE:
647 rc = DosSetPathInfo(pszPathName, ulInfoLevel, pInfoBuf, cbInfoBuf, flOptions);
648 if (rc == ERROR_INVALID_NAME) {
649 // fixme to validate counts?
650 eaop2 = *(PEAOP2)pInfoBuf; // Copy to buffer that does not cross
651 rc = DosSetPathInfo(pszPathName, ulInfoLevel, &eaop2, sizeof(eaop2), flOptions);
652 }
653 break;
654 default:
655 Runtime_Error(pszSrcFile, __LINE__, "ulInfoLevel %u unexpected", ulInfoLevel);
656 rc = ERROR_INVALID_PARAMETER;
657 } // switch
658 if (fResetVerify) {
659 DosSetVerify(fVerify);
660 fResetVerify = FALSE;
661 }
662 return rc;
663}
664
665PSZ xfgets(PSZ pszBuf, size_t cMaxBytes, FILE * fp, PCSZ pszSrcFile,
666 UINT uiLineNumber)
667{
668 PSZ psz = fgets(pszBuf, cMaxBytes, fp);
669
670 if (!psz) {
671 if (ferror(fp))
672 Runtime_Error(pszSrcFile, uiLineNumber, "fgets");
673 }
674 else {
675 size_t c = strlen(psz);
676
677 if (c + 1 > cMaxBytes)
678 Runtime_Error(pszSrcFile, uiLineNumber, "buffer overflow");
679 else if (!c || (psz[c - 1] != '\n' && psz[c - 1] != '\r'))
680 Runtime_Error(pszSrcFile, uiLineNumber, "missing EOL");
681 }
682 return psz;
683}
684
685PSZ xfgets_bstripcr(PSZ pszBuf, size_t cMaxBytes, FILE * fp, PCSZ pszSrcFile,
686 UINT uiLineNumber)
687{
688 PSZ psz = xfgets(pszBuf, cMaxBytes, fp, pszSrcFile, uiLineNumber);
689
690 if (psz)
691 bstripcr(psz);
692 return psz;
693}
694
695/**
696 * Wrapper for fopen it works around DosOpenL's failure to
697 * thunk properly so that fm2 can be loaded in high memory
698 * It also gives the option of reporting file open errors
699 * If fSilent is TRUE it fails silently; if FALSE it produces a
700 * runtime error dialog. Note pszMode must be passed on the stack
701 * to xfopen to avoid the thunking problem.
702 */
703
704FILE *xfopen(PCSZ pszFileName, PCSZ pszMode, PCSZ pszSrcFile,
705 UINT uiLineNumber, BOOL fSilent)
706{
707 CHAR FileName[CCHMAXPATH];
708 FILE *fp;
709
710 strcpy(FileName, pszFileName);
711 fp = fopen(FileName, pszMode);
712
713 if (!fp && !fSilent)
714 Runtime_Error(pszSrcFile, uiLineNumber, "fopen");
715 return fp;
716}
717
718/**
719 * Wrapper for _fsopen it works around DosOpenL's failure to
720 * thunk properly so that fm2 can be loaded in high memory
721 * It also gives the option of reporting file open errors
722 * If fSilent is TRUE it fails silently; if FALSE it produces a
723 * runtime error dialog. Note pszMode must be passed on the stack
724 * to xfopen to avoid the thunking problem
725 */
726
727FILE *xfsopen(PCSZ pszFileName, PCSZ pszMode, INT fSharemode, PCSZ pszSrcFile,
728 UINT uiLineNumber, BOOL fSilent)
729{
730 CHAR FileName[CCHMAXPATH];
731 FILE *fp;
732
733 strcpy(FileName, pszFileName);
734 fp = _fsopen(FileName, pszMode, fSharemode);
735 if (!fp && !strcmp(pszMode, "r+") && !fSilent)
736 fp = _fsopen(FileName, "w+", fSharemode);
737
738 if (!fp && !fSilent)
739 Runtime_Error(pszSrcFile, uiLineNumber, "_fsopen");
740 return fp;
741}
742
743//== xfree - safe free ==
744
745VOID xfree(PVOID pv, PCSZ pszSrcFile, UINT uiLineNumber)
746{
747 if (pv && pv != NullStr) {
748# ifdef FORTIFY
749 Fortify_free(pv, pszSrcFile, uiLineNumber);
750# else
751 free(pv);
752# endif
753
754 }
755}
756
757//== xmalloc() malloc with error checking ==
758
759PVOID xmalloc(size_t cBytes, PCSZ pszSrcFile, UINT uiLineNumber)
760{
761# ifdef FORTIFY
762 PVOID pv = Fortify_malloc(cBytes, pszSrcFile, uiLineNumber);
763# else
764 PVOID pv = malloc(cBytes);
765# endif
766
767 if (!pv)
768 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
769
770 return pv;
771}
772
773//== xmallocz() malloc and zero with error checking ==
774
775PVOID xmallocz(size_t cBytes, PCSZ pszSrcFile, UINT uiLineNumber)
776{
777 PVOID pv = xmalloc(cBytes, pszSrcFile, uiLineNumber);
778
779 if (pv)
780 memset(pv, 0, cBytes);
781
782 return pv;
783}
784
785//== xrealloc() realloc with error checking ==
786
787PVOID xrealloc(PVOID pvIn, size_t cBytes, PCSZ pszSrcFile, UINT uiLineNumber)
788{
789 if (pvIn != NullStr) {
790# ifdef FORTIFY
791 PVOID pv = Fortify_realloc(pvIn, cBytes, pszSrcFile, uiLineNumber);
792# else
793 PVOID pv = realloc(pvIn, cBytes);
794# endif
795
796 if (!pv && cBytes)
797 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
798
799 return pv;
800 }
801 else
802 return xmalloc(cBytes, pszSrcFile, uiLineNumber);
803}
804
805//== xstrdup() strdup with error checking ==
806
807PVOID xstrdup(PCSZ pszIn, PCSZ pszSrcFile, UINT uiLineNumber)
808{
809# ifdef FORTIFY
810 PSZ psz = Fortify_strdup(pszIn, pszSrcFile, uiLineNumber);
811# else
812 PSZ psz = strdup(pszIn);
813# endif
814
815 if (!psz)
816 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
817
818 return psz;
819}
820
821#if 0
822/*
823 * JBS: Wrappers for functions which...
824 * - are identified by klibc as "highmem-unsafe"
825 * - not yet used by FM/2
826 */
827
828// .H code for these functions
829// The following are ready to go.
830APIRET xDosCreatePipe(PHFILE phfReadHandle,
831 PHFILE phfWriteHandle,
832 ULONG ulPipeSize);
833
834APIRET xDosQueryFHState(HFILE hFile,
835 PULONG pulMode);
836
837#ifdef INCL_DOSNMPIPES
838APIRET xDosQueryNPHState(HPIPE hpipe,
839 PULONG pulState);
840#endif
841
842APIRET xDosSetDateTime(DATETIME *pdt);
843
844APIRET xDosSetFilePtr(HFILE hFile,
845 LONG lOffset,
846 ULONG ulOrigin,
847 PULONG pulPos);
848
849APIRET xDosSetFilePtrL(HFILE hFile,
850 LONGLONG llOffset,
851 ULONG ulOrigin,
852 PLONGLONG pllPos);
853
854#ifdef INCL_DOSPROCESS
855APIRET xDosWaitChild(ULONG ulAction,
856 ULONG ulWait,
857 PRESULTCODES pReturnCodes,
858 PPID ppidOut,
859 PID pidIn);
860#endif
861
862APIRET xDosWaitNPipe(PCSZ pszName,
863 ULONG ulTimeout);
864
865// The following functions still need work
866ULONG xWinUpper(HAB hab,
867 ULONG idcp,
868 ULONG idcc,
869 PSZ psz);
870
871APIRET xDosOpenL(PCSZ pszFileName,
872 PHFILE phFile,
873 PULONG pulAction,
874 LONGLONG llFileSize,
875 ULONG ulAttribute,
876 ULONG ulOpenFlags,
877 ULONG ulOpenMode,
878 PEAOP2 pEABuf);
879
880
881
882// .C code for the functions above
883APIRET xDosCreatePipe(PHFILE phfReadHandle,
884 PHFILE phfWriteHandle,
885 ULONG ulPipeSize)
886{
887 APIRET rc;
888 HFILE h1, h2;
889 PHFILE ph1 = NULL;
890 PHFILE ph2 = NULL;
891
892 if (phfReadHandle)
893 {
894 h1 = *phfReadHandle;
895 ph1 = &h1;
896 }
897 if (phfWriteHandle)
898 {
899 h2 = *phfWriteHandle;
900 ph2 = &h2;
901 }
902
903 rc = DosCreatePipe(ph1, ph2, ulPipeSize);
904
905 if (phfReadHandle)
906 *phfReadHandle = h1;
907 if (phfWriteHandle)
908 *phfWriteHandle = h2;
909 return rc;
910}
911
912// Code pEABuf
913APIRET xDosOpenL(PCSZ pszFileName,
914 PHFILE phFile,
915 PULONG pulAction,
916 LONGLONG llFileSize,
917 ULONG ulAttribute,
918 ULONG ulOpenFlags,
919 ULONG ulOpenMode,
920 PEAOP2 pEABuf)
921{
922 APIRET rc;
923 ULONG ul1;
924 PULONG pul1 = NULL;
925 HFILE hf1;
926 PHFILE phf1 = NULL;
927 char szFileNameLow[CCHMAXPATH];
928
929 strcpy(szFileNameLow, pszFileName);
930
931 if (phFile)
932 {
933 hf1 = *phFile;
934 phf1 = &hf1;
935 }
936 if (pulAction)
937 {
938 ul1 = *pulAction;
939 pul1 = &ul1;
940 }
941
942/** @todo pEABuf */
943
944 rc = DosOpenL(szFileNameLow, phf1, pul1, llFileSize, ulAttribute,
945 ulOpenFlags, ulOpenMode, pEABuf);
946
947 if (phFile)
948 *phFile = hf1;
949 if (pulAction)
950 *pulAction = ul1;
951
952 return rc;
953}
954
955APIRET xDosQueryNPHState(HPIPE hpipe,
956 PULONG pulState)
957{
958 APIRET rc;
959 ULONG ul1;
960 PULONG pul1 = NULL;
961
962 if (pulState)
963 {
964 ul1 = *pulState;
965 pul1 = &ul1;
966 }
967
968 rc = DosQueryNPHState(hpipe, pul1);
969
970 if (pulState)
971 *pulState = ul1;
972 return rc;
973}
974
975APIRET xDosQueryFHState(HFILE hFile,
976 PULONG pulMode)
977{
978 APIRET rc;
979 ULONG ul1;
980 PULONG pul1 = NULL;
981
982 if (pulMode)
983 {
984 ul1 = *pulMode;
985 pul1 = &ul1;
986 }
987
988 rc = DosQueryFHState(hFile, pul1);
989
990 if (pulMode)
991 *pulMode = ul1;
992
993 return rc;
994}
995
996APIRET xDosSetDateTime(DATETIME *pdt)
997{
998 APIRET rc;
999 DATETIME dt1;
1000 PDATETIME pdt1 = NULL;
1001
1002 if (pdt)
1003 {
1004 dt1 = *pdt;
1005 pdt1 = &dt1;
1006 }
1007
1008 rc = DosSetDateTime(pdt1);
1009
1010 return rc;
1011}
1012
1013APIRET xDosSetFilePtr(HFILE hFile,
1014 LONG lOffset,
1015 ULONG ulOrigin,
1016 PULONG pulPos)
1017{
1018 APIRET rc;
1019 ULONG ul1;
1020 PULONG pul1 = NULL;
1021
1022 if (pulPos)
1023 {
1024 ul1 = *pulPos;
1025 pul1 = &ul1;
1026 }
1027
1028 rc = DosSetFilePtr(hFile, lOffset, ulOrigin, pul1);
1029
1030 if (pulPos)
1031 *pulPos = ul1;
1032
1033 return rc;
1034}
1035
1036APIRET xDosSetFilePtrL(HFILE hFile,
1037 LONGLONG llOffset,
1038 ULONG ulOrigin,
1039 PLONGLONG pllPos)
1040{
1041 APIRET rc;
1042 LONGLONG ll1;
1043 PLONGLONG pll1 = NULL;
1044
1045 if (pllPos)
1046 {
1047 ll1 = *pllPos;
1048 pll1 = &ll1;
1049 }
1050
1051 rc = DosSetFilePtrL(hFile, llOffset, ulOrigin, pll1);
1052
1053 if (pllPos)
1054 *pllPos = ll1;
1055
1056 return rc;
1057}
1058
1059APIRET xDosWaitChild(ULONG ulAction,
1060 ULONG ulWait,
1061 PRESULTCODES pReturnCodes,
1062 PPID ppidOut,
1063 PID pidIn)
1064{
1065 APIRET rc;
1066 RESULTCODES res;
1067 PRESULTCODES pres = NULL;
1068 PID pid;
1069 PPID ppid = NULL;
1070
1071 if (pReturnCodes)
1072 {
1073 res = *pReturnCodes;
1074 pres = &res;
1075 }
1076 if (ppidOut)
1077 {
1078 pid = *ppidOut;
1079 ppid = &pid;
1080 }
1081
1082 rc = DosWaitChild(ulAction, ulWait, pres, ppid, pidIn);
1083
1084 if (pReturnCodes)
1085 *pReturnCodes = res;
1086 if (ppidOut)
1087 *ppidOut = pid;
1088
1089 return rc;
1090}
1091
1092APIRET xDosWaitNPipe(PCSZ pszName,
1093 ULONG ulTimeout)
1094{
1095 APIRET rc;
1096 char szNameLow[CCHMAXPATH];
1097
1098 strcpy(szNameLow, pszName);
1099 rc = DosWaitNPipe(szNameLow, ulTimeout);
1100 return rc;
1101}
1102
1103ULONG xWinUpper(HAB hab,
1104 ULONG idcp,
1105 ULONG idcc,
1106 PSZ psz)
1107{
1108 ULONG rc;
1109
1110 if (!HIGH_MEMORY_ADDRESS(psz))
1111 rc = WinUpper(hab, idcp, idcc, psz);
1112 else {
1113 size_t cch = strlen(psz);
1114 char *pszTmp = xmalloc(cch + 3, pszSrcFile, __LINE__);
1115 if (pszTmp)
1116 {
1117 memcpy(pszTmp, psz, cch + 1);
1118 pszTmp[cch + 1] = '\0';
1119 pszTmp[cch + 2] = '\0';
1120 rc = WinUpper(hab, idcp, idcc, pszTmp);
1121 if (rc > 0)
1122 memcpy(psz, pszTmp, rc <= cch ? rc + 1 : rc);
1123 xfree(pszTmp, pszSrcFile, __LINE__);
1124 }
1125 else
1126 {
1127 PSZ pszStart = psz;
1128 PSZ pszNext;
1129 while (*psz)
1130 {
1131 pszNext = (PSZ)WinNextChar(hab, idcp, idcc, psz);
1132 if (pszNext - psz == 1)
1133 *psz = WinUpperChar(hab, idcp, idcc, *psz);
1134 else if (pszNext - psz == 2)
1135 *(PUSHORT)psz = WinUpperChar(hab, idcp, idcc, *(PUSHORT)psz); /* a wild guess. */
1136 else
1137 break;
1138 psz = (char *)pszNext;
1139 }
1140 rc = psz - pszStart;
1141 }
1142 }
1143 return rc;
1144}
1145
1146#endif
1147
1148
1149#pragma alloc_text(WRAPPERS1,xfree,xfopen,xfsopen,xmalloc,xrealloc,xstrdup)
1150#pragma alloc_text(WRAPPERS2,xDosSetPathInfo,xDosFindFirst,xDosFindNext)
Note: See TracBrowser for help on using the repository browser.