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