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