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
RevLine 
[395]1
2/***********************************************************************
3
4 $Id: wrappers.c 1880 2015-10-12 18:26:16Z gyoung $
5
6 Wrappers with error checking
7
[1860]8 Copyright (c) 2006, 2015 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
[1839]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.
[1839]24 We should be creating the file unless it is set to fail silently.
[1847]25 12 Aug 15 JBS Ticket #522: Ensure no "highmem-unsafe" functions are called directly
[1845]26 1) New functions have been added
[1848]27 2) Code for unsafe-but-not-yet-used-by-FM/2 functions have been added in an
[1845]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.
[1860]30 20 Aug 15 SHL Add xDos...MutexSem and xDos..EventSem wrappers
[395]31
32***********************************************************************/
33
[907]34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
[1354]37#include <ctype.h>
[907]38
[395]39#define INCL_WIN
[826]40#define INCL_DOS
41#define INCL_DOSERRORS
[841]42#define INCL_LONGLONG
[395]43#include <os2.h>
44
45#include "fm3dll.h"
[1215]46#include "init.h" // Data declaration(s)
[1182]47#include "wrappers.h"
[395]48#include "fm3str.h"
[907]49#include "errutil.h" // Dos_Error...
50#include "strutil.h" // GetPString
[1032]51#include "command.h"
52#include "tools.h"
53#include "avl.h"
[1182]54#include "strips.h" // bstrip
[395]55
[1005]56#include "fortify.h" // GetPString
[1354]57#include "info.h" // driveflags
58#include "notebook.h" // fVerify
[1439]59#include "pathutil.h" // MaxComLineStrg
[1005]60
[1215]61// Data definitions
[827]62static PSZ pszSrcFile = __FILE__;
63
[1215]64#pragma data_seg(GLOBAL1)
65BOOL fNoLargeFileSupport;
66
[1845]67APIRET xDosDupHandle(HFILE hFile,
68 PHFILE phFile)
[1439]69{
[1845]70 APIRET rc;
[1860]71 HFILE hFileLow = *phFile;
[1845]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{
[1439]91 APIRET rc;
[1845]92 ULONG ulFlagsLow;
[1476]93 CHAR szPgm[CCHMAXPATH];
[1439]94
[1476]95 strcpy(szPgm, pszName);
[1845]96 rc = DosQueryAppType(szPgm, &ulFlagsLow);
97 *pFlags = ulFlagsLow;
[1439]98 return rc;
99}
100
[1845]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//
[1628]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
[1438]250APIRET xDosAllocSharedMem(PPVOID ppb,
[1839]251 PSZ pszName,
252 ULONG cb,
253 PCSZ pszSrcFile,
254 UINT uiLineNumber)
[1438]255{
[1845]256 APIRET rc;
[1438]257
[1628]258 rc = DosAllocSharedMem(ppb, pszName, cb,
[1839]259 PAG_COMMIT | OBJ_GIVEABLE | PAG_READ | PAG_WRITE | OBJ_ANY);
[1438]260 if (rc)
[1628]261 rc = DosAllocSharedMem(ppb, pszName, cb, PAG_COMMIT | OBJ_GIVEABLE | PAG_READ | PAG_WRITE);
[1627]262 if (rc)
263 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
[1438]264 return rc;
265}
266
[1628]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
[1438]274APIRET xDosAllocMem(PPVOID ppb,
[1839]275 ULONG cb,
276 PCSZ pszSrcFile,
277 UINT uiLineNumber)
[1438]278{
279 APIRET rc;
280
[1628]281 rc = DosAllocMem(ppb, cb, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_ANY);
[1438]282 if (rc)
[1628]283 rc = DosAllocMem(ppb, cb, PAG_COMMIT | PAG_READ | PAG_WRITE);
[1627]284 if (rc)
285 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
[1438]286 return rc;
287}
288
[1628]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
[1627]297APIRET xDosAllocMemLow(PPVOID ppb,
[1839]298 ULONG cb,
299 PCSZ pszSrcFile,
300 UINT uiLineNumber)
[1627]301{
302 APIRET rc;
303
[1628]304 rc = DosAllocMem(ppb, cb, PAG_COMMIT | PAG_READ | PAG_WRITE);
[1627]305 if (rc)
306 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
307 return rc;
308}
309
[1839]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
[1860]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
[850]417APIRET xDosFindFirst(PSZ pszFileSpec,
418 PHDIR phdir,
419 ULONG flAttribute,
420 PVOID pfindbuf,
421 ULONG cbBuf,
422 PULONG pcFileNames,
423 ULONG ulInfoLevel)
[838]424{
[850]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 }
[849]444 break;
[850]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 }
[849]462 break;
463 default:
[850]464 Runtime_Error(pszSrcFile, __LINE__, "ulInfoLevel %u unexpected", ulInfoLevel);
465 rc = ERROR_INVALID_PARAMETER;
466 } // switch
467 }
468 else
[838]469 rc = DosFindFirst(pszFileSpec, phdir, flAttribute, pfindbuf, cbBuf,
[850]470 pcFileNames, ulInfoLevel);
471 return rc;
[838]472}
473
[850]474APIRET xDosFindNext(HDIR hDir,
475 PVOID pfindbuf,
476 ULONG cbfindbuf,
477 PULONG pcFileNames,
478 ULONG ulInfoLevel)
[838]479{
480 APIRET rc;
[849]481 if (fNoLargeFileSupport) {
[850]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
[849]518 }
519 else
[850]520 rc = DosFindNext(hDir, pfindbuf, cbfindbuf, pcFileNames);
[838]521
522 return rc;
523}
524
[827]525/**
[850]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
[1432]563 rc = DosQueryPathInfo (pszPathName, ulInfoLevel, pInfoBuf, cbInfoBuf);
[850]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 *
[1627]572 * Some kernels do not correctly handle FILESTATUS3 and PEAOP2 buffers
[827]573 * that cross a 64K boundary.
574 * When this occurs, they return ERROR_INVALID_NAME.
[1845]575 *
[827]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.
[1845]579 *
[827]580 * It is caller's responsitibility to report errors
[847]581 * @param pInfoBuf pointer to FILESTATUS3(L) or EAOP2 buffer
582 * @param ulInfoLevel FIL_STANDARD(L) or FIL_QUERYEASIZE
[827]583 * @returns Same as DosSetPathInfo
584 */
585
[841]586APIRET xDosSetPathInfo(PSZ pszPathName,
[850]587 ULONG ulInfoLevel,
[841]588 PVOID pInfoBuf,
589 ULONG cbInfoBuf,
[850]590 ULONG flOptions)
[826]591{
[1845]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;
[850]600
[1845]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;
[850]614
[1845]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;
[850]624 }
625 else {
[1845]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);
[850]630 }
631 if (rc == ERROR_INVALID_NAME) {
632 // fixme to validate counts?
[1845]633 fs3_a = fs3; // Copy to buffer that does not cross
634 rc = DosSetPathInfo(pszPathName, ulInfoLevel, &fs3_a, sizeof(fs3_a), flOptions);
[1839]635 }
[1845]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;
[826]662}
663
[551]664PSZ xfgets(PSZ pszBuf, size_t cMaxBytes, FILE * fp, PCSZ pszSrcFile,
665 UINT uiLineNumber)
[400]666{
[551]667 PSZ psz = fgets(pszBuf, cMaxBytes, fp);
668
[400]669 if (!psz) {
670 if (ferror(fp))
671 Runtime_Error(pszSrcFile, uiLineNumber, "fgets");
672 }
673 else {
674 size_t c = strlen(psz);
[551]675
[400]676 if (c + 1 > cMaxBytes)
677 Runtime_Error(pszSrcFile, uiLineNumber, "buffer overflow");
[551]678 else if (!c || (psz[c - 1] != '\n' && psz[c - 1] != '\r'))
[400]679 Runtime_Error(pszSrcFile, uiLineNumber, "missing EOL");
680 }
681 return psz;
682}
683
[551]684PSZ xfgets_bstripcr(PSZ pszBuf, size_t cMaxBytes, FILE * fp, PCSZ pszSrcFile,
685 UINT uiLineNumber)
[400]686{
[551]687 PSZ psz = xfgets(pszBuf, cMaxBytes, fp, pszSrcFile, uiLineNumber);
688
[400]689 if (psz)
690 bstripcr(psz);
691 return psz;
692}
693
[1544]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
[551]703FILE *xfopen(PCSZ pszFileName, PCSZ pszMode, PCSZ pszSrcFile,
[1544]704 UINT uiLineNumber, BOOL fSilent)
[395]705{
[1544]706 CHAR FileName[CCHMAXPATH];
707 FILE *fp;
[551]708
[1544]709 strcpy(FileName, pszFileName);
710 fp = fopen(FileName, pszMode);
711
712 if (!fp && !fSilent)
[395]713 Runtime_Error(pszSrcFile, uiLineNumber, "fopen");
714 return fp;
715}
716
[1544]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
[551]726FILE *xfsopen(PCSZ pszFileName, PCSZ pszMode, INT fSharemode, PCSZ pszSrcFile,
[1839]727 UINT uiLineNumber, BOOL fSilent)
[395]728{
[1544]729 CHAR FileName[CCHMAXPATH];
730 FILE *fp;
[551]731
[1544]732 strcpy(FileName, pszFileName);
733 fp = _fsopen(FileName, pszMode, fSharemode);
[1639]734 if (!fp && !strcmp(pszMode, "r+") && !fSilent)
735 fp = _fsopen(FileName, "w+", fSharemode);
[1544]736
737 if (!fp && !fSilent)
[395]738 Runtime_Error(pszSrcFile, uiLineNumber, "_fsopen");
739 return fp;
740}
741
742//== xfree - safe free ==
743
[1009]744VOID xfree(PVOID pv, PCSZ pszSrcFile, UINT uiLineNumber)
[395]745{
[1009]746 if (pv && pv != NullStr) {
[1063]747# ifdef FORTIFY
[1009]748 Fortify_free(pv, pszSrcFile, uiLineNumber);
[1063]749# else
[395]750 free(pv);
[1063]751# endif
[1009]752
753 }
[395]754}
755
756//== xmalloc() malloc with error checking ==
757
758PVOID xmalloc(size_t cBytes, PCSZ pszSrcFile, UINT uiLineNumber)
759{
[1006]760# ifdef FORTIFY
761 PVOID pv = Fortify_malloc(cBytes, pszSrcFile, uiLineNumber);
[1011]762# else
[395]763 PVOID pv = malloc(cBytes);
[1063]764# endif
[395]765
766 if (!pv)
[551]767 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
[395]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{
[1011]776 PVOID pv = xmalloc(cBytes, pszSrcFile, uiLineNumber);
[395]777
[1011]778 if (pv)
[395]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{
[963]788 if (pvIn != NullStr) {
[1063]789# ifdef FORTIFY
790 PVOID pv = Fortify_realloc(pvIn, cBytes, pszSrcFile, uiLineNumber);
791# else
792 PVOID pv = realloc(pvIn, cBytes);
793# endif
[395]794
[963]795 if (!pv && cBytes)
796 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
[395]797
[963]798 return pv;
799 }
800 else
801 return xmalloc(cBytes, pszSrcFile, uiLineNumber);
[395]802}
803
804//== xstrdup() strdup with error checking ==
805
806PVOID xstrdup(PCSZ pszIn, PCSZ pszSrcFile, UINT uiLineNumber)
807{
[1009]808# ifdef FORTIFY
809 PSZ psz = Fortify_strdup(pszIn, pszSrcFile, uiLineNumber);
[1011]810# else
[395]811 PSZ psz = strdup(pszIn);
[1063]812# endif
[395]813
814 if (!psz)
[551]815 Runtime_Error(pszSrcFile, uiLineNumber, GetPString(IDS_OUTOFMEMORY));
[395]816
817 return psz;
818}
[794]819
[1845]820#if 0
821/*
822 * JBS: Wrappers for functions which...
[1860]823 * - are identified by klibc as "highmem-unsafe"
824 * - not yet used by FM/2
[1845]825 */
[1032]826
[1845]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
[1032]1148#pragma alloc_text(WRAPPERS1,xfree,xfopen,xfsopen,xmalloc,xrealloc,xstrdup)
[1037]1149#pragma alloc_text(WRAPPERS2,xDosSetPathInfo,xDosFindFirst,xDosFindNext)
Note: See TracBrowser for help on using the repository browser.