Implemented more APIs. Watcom C's "wasm.exe" works now.
This commit is contained in:
1 parent
b2e32aeb37
commit
dc00a7e998
3 files changed
+452
-12
No files matched your search
+382
-12
@@ -87,6 +87,18 @@ typedef struct
|
||||
volatile int waiting;
|
||||
} EventSem;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DIR *dirp;
|
||||
ULONG attr;
|
||||
ULONG level;
|
||||
char pattern[CCHMAXPATHCOMP];
|
||||
} DirFinder;
|
||||
|
||||
static DirFinder GHDir1;
|
||||
|
||||
|
||||
LX_NATIVE_MODULE_DEINIT({
|
||||
ExitListItem *next = GExitList;
|
||||
GExitList = NULL;
|
||||
@@ -157,12 +169,17 @@ LX_NATIVE_MODULE_INIT({ if (!initDoscalls(lx_state)) return NULL; })
|
||||
LX_NATIVE_EXPORT(DosQueryHType, 224),
|
||||
LX_NATIVE_EXPORT(DosScanEnv, 227),
|
||||
LX_NATIVE_EXPORT(DosGetDateTime, 230),
|
||||
LX_NATIVE_EXPORT(DosDevConfig, 231),
|
||||
LX_NATIVE_EXPORT(DosExit, 234),
|
||||
LX_NATIVE_EXPORT(DosSetFilePtr, 256),
|
||||
LX_NATIVE_EXPORT(DosClose, 257),
|
||||
LX_NATIVE_EXPORT(DosDelete, 259),
|
||||
LX_NATIVE_EXPORT(DosFindClose, 263),
|
||||
LX_NATIVE_EXPORT(DosFindFirst, 264),
|
||||
LX_NATIVE_EXPORT(DosFindNext, 265),
|
||||
LX_NATIVE_EXPORT(DosOpen, 273),
|
||||
LX_NATIVE_EXPORT(DosQueryCurrentDir, 274),
|
||||
LX_NATIVE_EXPORT(DosQueryCurrentDisk, 275),
|
||||
LX_NATIVE_EXPORT(DosQueryFileInfo, 279),
|
||||
LX_NATIVE_EXPORT(DosWaitChild, 280),
|
||||
LX_NATIVE_EXPORT(DosRead, 281),
|
||||
@@ -1205,22 +1222,31 @@ static void unixTimeToOs2(const time_t unixtime, FDATE *os2date, FTIME *os2time)
|
||||
os2time->hours = (USHORT) lt.tm_hour;
|
||||
} // unixTimeToOs2
|
||||
|
||||
static inline void initFileCreationDateTime(FDATE *fdate, FTIME *ftime)
|
||||
{
|
||||
// we don't store creation date on Unix. OS/2 zeroes out fields that aren't
|
||||
// appropriate to FAT file systems, but I don't want to risk apps using
|
||||
// zeroes to decide a file in on a FAT disk and reducing features,
|
||||
// shrinking filenames to 8.3, etc.
|
||||
if (fdate) {
|
||||
fdate->day = 1;
|
||||
fdate->month = 1;
|
||||
fdate->year = 0; // years since 1980, apparently.
|
||||
} // if
|
||||
|
||||
if (ftime) {
|
||||
ftime->twosecs = 0;
|
||||
ftime->minutes = 0;
|
||||
ftime->hours = 0;
|
||||
} // if
|
||||
} // initFileCreationDateTime
|
||||
|
||||
static APIRET queryFileInfoStandardFromStat(const struct stat *statbuf, PVOID pInfoBuf, ULONG cbInfoBuf)
|
||||
{
|
||||
FILESTATUS3 *st = (FILESTATUS3 *) pInfoBuf;
|
||||
memset(st, '\0', sizeof (*st));
|
||||
|
||||
// we don't store creation date on Unix. OS/2 zeroes out fields that aren't
|
||||
// appropriate to FAT file systems, but I don't want to risk apps using
|
||||
// zeroes to decide a file in on a FAT disk and reducing features,
|
||||
// shrinking filenames to 8.3, etc.
|
||||
st->fdateCreation.day = 1;
|
||||
st->fdateCreation.month = 1;
|
||||
st->fdateCreation.year = 0; // years since 1980, apparently.
|
||||
st->ftimeCreation.twosecs = 0;
|
||||
st->ftimeCreation.minutes = 0;
|
||||
st->ftimeCreation.hours = 0;
|
||||
|
||||
initFileCreationDateTime(&st->fdateCreation, &st->ftimeCreation);
|
||||
unixTimeToOs2(statbuf->st_atime, &st->fdateLastAccess, &st->ftimeLastAccess);
|
||||
unixTimeToOs2(statbuf->st_mtime, &st->fdateLastWrite, &st->ftimeLastWrite);
|
||||
|
||||
@@ -1229,7 +1255,7 @@ static APIRET queryFileInfoStandardFromStat(const struct stat *statbuf, PVOID pI
|
||||
|
||||
if (S_ISDIR(statbuf->st_mode))
|
||||
st->attrFile |= FILE_DIRECTORY;
|
||||
if (statbuf->st_mode & ~S_IRUSR) // !!! FIXME: not accurate...?
|
||||
if ((statbuf->st_mode & S_IWUSR) == 0) // !!! FIXME: not accurate...?
|
||||
st->attrFile |= FILE_READONLY;
|
||||
|
||||
return NO_ERROR;
|
||||
@@ -2171,5 +2197,349 @@ APIRET DosOpenL(PSZ pszFileName, PHFILE pHf, PULONG pulAction, LONGLONG cbFile,
|
||||
return doDosOpen(pszFileName, pHf, pulAction, cbFile, ulAttribute, fsOpenFlags, fsOpenMode, peaop2);
|
||||
} // DosOpenL
|
||||
|
||||
|
||||
static int wildcardMatch(const char *str, const char *pattern)
|
||||
{
|
||||
// !!! FIXME: the way OS/2 matches files is sort of complex, and I'm not sure this is 100% right.
|
||||
int ext = 0;
|
||||
while (1) {
|
||||
const char pat = *(pattern++);
|
||||
if (pat == '\0') {
|
||||
return (*str == '\0') ? 1 : 0;
|
||||
} else if (pat == '?') {
|
||||
if (*str) // also matches end of string, but don't advance.
|
||||
str++;
|
||||
} else if ((pat == '.') && (!ext)) {
|
||||
ext = 1;
|
||||
if (*str == '.')
|
||||
str++;
|
||||
else if (*str != '\0')
|
||||
return 0;
|
||||
} else if (pat == '*') {
|
||||
const char next = *pattern;
|
||||
while (*str && (*str != next))
|
||||
str++;
|
||||
} else {
|
||||
const char ch = *str;
|
||||
const char a = ((ch >= 'A') && (ch <= 'Z')) ? (ch - ('A' - 'a')) : ch;
|
||||
const char b = ((pat >= 'A') && (pat <= 'Z')) ? (pat - ('A' - 'a')) : pat;
|
||||
if (a == b)
|
||||
str++;
|
||||
else
|
||||
return 0;
|
||||
} // else
|
||||
} // while
|
||||
|
||||
__builtin_unreachable();
|
||||
} // wildcardMatch
|
||||
|
||||
static int findNextOne(DirFinder *dirf, PVOID *ppfindbuf, PULONG pcbBuf)
|
||||
{
|
||||
const ULONG attr = dirf->attr;
|
||||
const ULONG musthave = (attr & 0xFF00) >> 8;
|
||||
const ULONG mayhave = (attr & 0x00FF);
|
||||
|
||||
// these attributes mean nothing on Unix, so if they are Must Haves, return nothing.
|
||||
if (musthave & (FILE_HIDDEN | FILE_SYSTEM | FILE_ARCHIVED))
|
||||
return 0;
|
||||
|
||||
struct dirent *dent;
|
||||
const int fd = dirfd(dirf->dirp);
|
||||
const char *pattern = dirf->pattern;
|
||||
|
||||
while ((dent = readdir(dirf->dirp)) != NULL) {
|
||||
const char *name = dent->d_name;
|
||||
// !!! FIXME: OS/2 doesn't enumerate ".." for the drive root!
|
||||
//if (strcmp(name, "..") == 0) { if drive_root continue; }
|
||||
|
||||
const size_t namelen = strlen(name);
|
||||
if (namelen >= CCHMAXPATHCOMP) continue;
|
||||
|
||||
if (!wildcardMatch(name, pattern)) continue;
|
||||
|
||||
// we stat(), not lstat(), because OS/2 doesn't understand symlinks,
|
||||
// so we pretend the real file/dir is there. This could cause
|
||||
// problems with broken links and infinite loops, though.
|
||||
// For lstat-like behaviour, if we change our minds, the last arg
|
||||
// of fstatat() needs the AT_SYMLINK_NOFOLLOW flag.
|
||||
struct stat statbuf;
|
||||
if (fstatat(fd, name, &statbuf, 0) == -1) continue;
|
||||
|
||||
const int isfile = S_ISREG(statbuf.st_mode);
|
||||
const int isdir = S_ISDIR(statbuf.st_mode);
|
||||
if (!isfile && !isdir) continue; // OS/2 didn't have fifos, devs, sockets, etc.
|
||||
assert(isfile != isdir);
|
||||
|
||||
if (isdir) {
|
||||
if ((mayhave & FILE_DIRECTORY) == 0) continue;
|
||||
} else {
|
||||
if (musthave & FILE_DIRECTORY) continue;
|
||||
} // else
|
||||
|
||||
const int readonly = ((statbuf.st_mode & S_IWUSR) == 0); // !!! FIXME: not accurate...?
|
||||
if (readonly) {
|
||||
if ((mayhave & FILE_READONLY) == 0) continue;
|
||||
} else {
|
||||
if (musthave & FILE_READONLY) continue;
|
||||
} // else
|
||||
|
||||
|
||||
// okay! Definitely take this one!
|
||||
switch (dirf->level) {
|
||||
case FIL_STANDARD: {
|
||||
PFILEFINDBUF3 st = (PFILEFINDBUF3) *ppfindbuf;
|
||||
memset(st, '\0', sizeof (*st));
|
||||
*ppfindbuf = st + 1;
|
||||
*pcbBuf -= sizeof (*st);
|
||||
st->oNextEntryOffset = sizeof (*st);
|
||||
initFileCreationDateTime(&st->fdateCreation, &st->ftimeCreation);
|
||||
unixTimeToOs2(statbuf.st_atime, &st->fdateLastAccess, &st->ftimeLastAccess);
|
||||
unixTimeToOs2(statbuf.st_mtime, &st->fdateLastWrite, &st->ftimeLastWrite);
|
||||
st->cbFile = (ULONG) statbuf.st_size; // !!! FIXME: > 2gig files?
|
||||
st->cbFileAlloc = (ULONG) (statbuf.st_blocks * 512);
|
||||
if (isdir) st->attrFile |= FILE_DIRECTORY;
|
||||
if (readonly) st->attrFile |= FILE_READONLY;
|
||||
st->cchName = (UCHAR) namelen;
|
||||
strcpy(st->achName, name);
|
||||
return 1;
|
||||
} // case
|
||||
|
||||
case FIL_QUERYEASIZE: {
|
||||
PFILEFINDBUF4 st = (PFILEFINDBUF4) *ppfindbuf;
|
||||
memset(st, '\0', sizeof (*st));
|
||||
*ppfindbuf = st + 1;
|
||||
*pcbBuf -= sizeof (*st);
|
||||
st->oNextEntryOffset = sizeof (*st);
|
||||
initFileCreationDateTime(&st->fdateCreation, &st->ftimeCreation);
|
||||
unixTimeToOs2(statbuf.st_atime, &st->fdateLastAccess, &st->ftimeLastAccess);
|
||||
unixTimeToOs2(statbuf.st_mtime, &st->fdateLastWrite, &st->ftimeLastWrite);
|
||||
st->cbFile = (ULONG) statbuf.st_size; // !!! FIXME: > 2gig files?
|
||||
st->cbFileAlloc = (ULONG) (statbuf.st_blocks * 512);
|
||||
if (isdir) st->attrFile |= FILE_DIRECTORY;
|
||||
if (readonly) st->attrFile |= FILE_READONLY;
|
||||
st->cbList = 0; FIXME("write me: EA support");
|
||||
st->cchName = (UCHAR) namelen;
|
||||
strcpy(st->achName, name);
|
||||
return 1;
|
||||
} // case
|
||||
|
||||
case FIL_QUERYEASFROMLIST:
|
||||
FIXME("write me");
|
||||
break;
|
||||
} // switch
|
||||
} // while
|
||||
|
||||
return 0; // found nothing else that matches our needs.
|
||||
} // findNextOne
|
||||
|
||||
|
||||
static APIRET findNext(DirFinder *dirf, PVOID pfindbuf, ULONG cbBuf, PULONG pcFileNames)
|
||||
{
|
||||
if (!dirf->dirp) {
|
||||
*pcFileNames = 0;
|
||||
return ERROR_NO_MORE_FILES;
|
||||
} // if
|
||||
|
||||
const ULONG maxents = *pcFileNames;
|
||||
ULONG i;
|
||||
for (i = 0; i < maxents; i++) {
|
||||
if (!findNextOne(dirf, &pfindbuf, &cbBuf))
|
||||
break;
|
||||
} // for
|
||||
|
||||
*pcFileNames = i;
|
||||
|
||||
if ((i == 0) && (maxents > 0)) {
|
||||
closedir(dirf->dirp);
|
||||
dirf->dirp = NULL;
|
||||
} // if
|
||||
|
||||
return NO_ERROR;
|
||||
} // findNext
|
||||
|
||||
static inline ULONG findNextSizeNeeded(const ULONG ulInfoLevel, const ULONG pcFileNames)
|
||||
{
|
||||
switch (ulInfoLevel) {
|
||||
case FIL_STANDARD: return sizeof (FILEFINDBUF3) * pcFileNames;
|
||||
case FIL_QUERYEASIZE: return sizeof (FILEFINDBUF4) * pcFileNames;
|
||||
case FIL_QUERYEASFROMLIST: FIXME("write me"); return 0xFFFFFFFF;
|
||||
default: assert(!"Shouldn't hit this."); return 0xFFFFFFFF;
|
||||
} // switch
|
||||
__builtin_unreachable();
|
||||
} // findNextSizeNeeded;
|
||||
|
||||
APIRET DosFindFirst(PSZ pszFileSpec, PHDIR phdir, ULONG flAttribute, PVOID pfindbuf, ULONG cbBuf, PULONG pcFileNames, ULONG ulInfoLevel)
|
||||
{
|
||||
TRACE_NATIVE("DosFindFirst('%s', %p, %u, %p, %u, %p, %u)", pszFileSpec, phdir, (uint) flAttribute, pfindbuf, (uint) cbBuf, pcFileNames, (uint) ulInfoLevel);
|
||||
|
||||
if (flAttribute & 0xffffc8c8) // reserved bits that must be zero.
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
else if (cbBuf > 0xFFFF) // !!! FIXME: Control Program API Reference says this fails if > 64k, although that was obviously a 16-bit limitation.
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
else if ((ulInfoLevel != FIL_STANDARD) && (ulInfoLevel != FIL_QUERYEASIZE) && (ulInfoLevel != FIL_QUERYEASFROMLIST))
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
else if (!pcFileNames)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
else if (!pfindbuf && (*pcFileNames != 0))
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
else if (!phdir)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
else if (!*phdir)
|
||||
return ERROR_INVALID_HANDLE;
|
||||
else if (cbBuf < findNextSizeNeeded(ulInfoLevel, *pcFileNames))
|
||||
return ERROR_BUFFER_OVERFLOW;
|
||||
|
||||
if (ulInfoLevel != FIL_STANDARD) {
|
||||
FIXME("implement extended attribute support");
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
} // if
|
||||
|
||||
if (flAttribute == FILE_NORMAL)
|
||||
flAttribute = FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_ARCHIVED; // most of the "may-have" bits.
|
||||
|
||||
APIRET err = NO_ERROR;
|
||||
char *path = makeUnixPath(pszFileSpec, &err);
|
||||
if (!path)
|
||||
return err;
|
||||
|
||||
char *pattern = strrchr(path, '/');
|
||||
if (pattern)
|
||||
*(pattern++) = '\0';
|
||||
else
|
||||
pattern = path;
|
||||
|
||||
if (strlen(pattern) >= CCHMAXPATHCOMP) {
|
||||
free(path);
|
||||
return ERROR_FILENAME_EXCED_RANGE;
|
||||
} // if
|
||||
|
||||
DirFinder *dirf = NULL;
|
||||
if (*phdir == HDIR_SYSTEM) {
|
||||
dirf = &GHDir1;
|
||||
} else if (*phdir == HDIR_CREATE) {
|
||||
dirf = (DirFinder *) malloc(sizeof (DirFinder));
|
||||
if (!dirf) {
|
||||
free(path);
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
} // if
|
||||
memset(dirf, '\0', sizeof (*dirf));
|
||||
} else {
|
||||
dirf = (DirFinder *) *phdir;
|
||||
} // else
|
||||
|
||||
DIR *dirp = opendir((path == pattern) ? "." : path);
|
||||
if (!dirp) {
|
||||
const int rc = errno;
|
||||
if (*phdir == HDIR_CREATE)
|
||||
free(dirf);
|
||||
free(path);
|
||||
switch (rc) {
|
||||
case EACCES: return ERROR_ACCESS_DENIED;
|
||||
case EMFILE: return ERROR_NO_MORE_SEARCH_HANDLES;
|
||||
case ENFILE: return ERROR_NO_MORE_SEARCH_HANDLES;
|
||||
case ENOMEM: return ERROR_NOT_ENOUGH_MEMORY;
|
||||
case ENOENT: return ERROR_PATH_NOT_FOUND; // !!! FIXME: should this be FILE_NOT_FOUND if the parent dir exists...?
|
||||
case ENAMETOOLONG: return ERROR_FILENAME_EXCED_RANGE;
|
||||
default: break;
|
||||
} // switch
|
||||
return ERROR_PATH_NOT_FOUND; // oh well.
|
||||
} // if
|
||||
|
||||
if (dirf->dirp)
|
||||
closedir(dirf->dirp);
|
||||
|
||||
dirf->dirp = dirp;
|
||||
dirf->attr = flAttribute;
|
||||
dirf->level = ulInfoLevel;
|
||||
strcpy(dirf->pattern, pattern);
|
||||
free(path);
|
||||
|
||||
err = findNext(dirf, pfindbuf, cbBuf, pcFileNames);
|
||||
|
||||
// From the Control Program API reference:
|
||||
// "Any nonzero return code, except ERROR_EAS_DIDNT_FIT, indicates that no handle has been allocated. This includes such nonerror
|
||||
// indicators as ERROR_NO_MORE_FILES."
|
||||
if ((err != NO_ERROR) && (err != ERROR_EAS_DIDNT_FIT)) {
|
||||
closedir(dirf->dirp);
|
||||
dirf->dirp = NULL;
|
||||
if (*phdir == HDIR_CREATE)
|
||||
free(dirf);
|
||||
return err;
|
||||
} // if
|
||||
|
||||
*phdir = (HDIR) dirf;
|
||||
return NO_ERROR;
|
||||
} // DosFindFirst
|
||||
|
||||
APIRET DosFindNext(HDIR hDir, PVOID pfindbuf, ULONG cbfindbuf, PULONG pcFilenames)
|
||||
{
|
||||
TRACE_NATIVE("DosFindNext(%u, %p, %u, %p)", (uint) hDir, pfindbuf, (uint) cbfindbuf, pcFilenames);
|
||||
|
||||
if ((hDir == 0) || (hDir == HDIR_SYSTEM) || (hDir == HDIR_CREATE))
|
||||
return ERROR_INVALID_HANDLE;
|
||||
else if (cbfindbuf > 0xFFFF) // !!! FIXME: Control Program API Reference says this fails if > 64k, although that was obviously a 16-bit limitation.
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
else if (!pcFilenames)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
else if (!pfindbuf && (*pcFilenames != 0))
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
else if (cbfindbuf < findNextSizeNeeded(((DirFinder *) hDir)->level, *pcFilenames))
|
||||
return ERROR_BUFFER_OVERFLOW;
|
||||
return findNext((DirFinder *) hDir, pfindbuf, cbfindbuf, pcFilenames);
|
||||
} // DosFindNext
|
||||
|
||||
APIRET DosFindClose(HDIR hDir)
|
||||
{
|
||||
TRACE_NATIVE("DosFindClose(%u)", (uint) hDir);
|
||||
|
||||
if ((hDir == 0) || (hDir == HDIR_SYSTEM) || (hDir == HDIR_CREATE))
|
||||
return ERROR_INVALID_HANDLE;
|
||||
|
||||
DirFinder *dirf = (DirFinder *) hDir;
|
||||
if (dirf->dirp)
|
||||
closedir(dirf->dirp);
|
||||
|
||||
if (dirf == &GHDir1)
|
||||
memset(dirf, '\0', sizeof (*dirf));
|
||||
else
|
||||
free(dirf);
|
||||
|
||||
return NO_ERROR;
|
||||
} // DosFindClose
|
||||
|
||||
APIRET DosQueryCurrentDisk(PULONG pdisknum, PULONG plogical)
|
||||
{
|
||||
TRACE_NATIVE("DosQueryCurrentDisk(%p, %p)", pdisknum, plogical);
|
||||
|
||||
// we only offer a "C:" drive at the moment.
|
||||
if (pdisknum)
|
||||
*pdisknum = 3; // C:
|
||||
if (plogical)
|
||||
*plogical = (1 << 2); // just C:
|
||||
return NO_ERROR;
|
||||
} // DosQueryCurrentDisk
|
||||
|
||||
APIRET DosDevConfig(PVOID pdevinfo, ULONG item)
|
||||
{
|
||||
TRACE_NATIVE("DosDevConfig(%p, %u)", pdevinfo, (uint) item);
|
||||
|
||||
if (pdevinfo == NULL)
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
BYTE *info = (BYTE *) pdevinfo;
|
||||
switch (item) {
|
||||
case DEVINFO_PRINTER: *info = 0; break; // we don't report any printers.
|
||||
case DEVINFO_RS232: *info = 0; break; // we don't report any serial ports.
|
||||
case DEVINFO_FLOPPY: *info = 0; break; // we don't report any floppies.
|
||||
case DEVINFO_COPROCESSOR: *info = 1; break; // We could check for this, but c'mon.
|
||||
case DEVINFO_SUBMODEL: *info = 1; break; // OS/2 Warp 4 under Vmware returns this, but I don't know what this means.
|
||||
case DEVINFO_MODEL: *info = 252; break; // OS/2 Warp 4 under Vmware returns this, but I don't know what this means.
|
||||
case DEVINFO_ADAPTER: *info = 1; break; // sure, you have a real display from the last 30+ years.
|
||||
default: return ERROR_INVALID_PARAMETER;
|
||||
} // switch
|
||||
|
||||
return NO_ERROR;
|
||||
} // DosDevConfig
|
||||
|
||||
// end of doscalls.c ...
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define CCHMAXPATH 260
|
||||
#define CCHMAXPATHCOMP 256
|
||||
|
||||
enum
|
||||
{
|
||||
EXIT_THREAD,
|
||||
@@ -181,6 +184,7 @@ enum
|
||||
FIL_QUERYFULLNAME = 5
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
typedef struct
|
||||
{
|
||||
USHORT day : 5;
|
||||
@@ -194,6 +198,7 @@ typedef struct
|
||||
USHORT minutes : 6;
|
||||
USHORT hours : 5;
|
||||
} FTIME, *PFTIME;
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -289,6 +294,65 @@ enum
|
||||
DSPI_WRTTHRU = 0x10,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
HDIR_CREATE = -1,
|
||||
HDIR_SYSTEM = 1
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
MUST_HAVE_READONLY = ( (FILE_READONLY << 8) | FILE_READONLY ),
|
||||
MUST_HAVE_HIDDEN = ( (FILE_HIDDEN << 8) | FILE_HIDDEN ),
|
||||
MUST_HAVE_SYSTEM = ( (FILE_SYSTEM << 8) | FILE_SYSTEM),
|
||||
MUST_HAVE_DIRECTORY = ( (FILE_DIRECTORY << 8) | FILE_DIRECTORY ),
|
||||
MUST_HAVE_ARCHIVED = ( (FILE_ARCHIVED << 8) | FILE_ARCHIVED )
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ULONG oNextEntryOffset;
|
||||
FDATE fdateCreation;
|
||||
FTIME ftimeCreation;
|
||||
FDATE fdateLastAccess;
|
||||
FTIME ftimeLastAccess;
|
||||
FDATE fdateLastWrite;
|
||||
FTIME ftimeLastWrite;
|
||||
ULONG cbFile;
|
||||
ULONG cbFileAlloc;
|
||||
ULONG attrFile;
|
||||
UCHAR cchName;
|
||||
CHAR achName[CCHMAXPATHCOMP];
|
||||
} FILEFINDBUF3, *PFILEFINDBUF3;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ULONG oNextEntryOffset;
|
||||
FDATE fdateCreation;
|
||||
FTIME ftimeCreation;
|
||||
FDATE fdateLastAccess;
|
||||
FTIME ftimeLastAccess;
|
||||
FDATE fdateLastWrite;
|
||||
FTIME ftimeLastWrite;
|
||||
ULONG cbFile;
|
||||
ULONG cbFileAlloc;
|
||||
ULONG attrFile;
|
||||
ULONG cbList;
|
||||
UCHAR cchName;
|
||||
CHAR achName[CCHMAXPATHCOMP];
|
||||
} FILEFINDBUF4, *PFILEFINDBUF4;
|
||||
|
||||
enum
|
||||
{
|
||||
DEVINFO_PRINTER,
|
||||
DEVINFO_RS232,
|
||||
DEVINFO_FLOPPY,
|
||||
DEVINFO_COPROCESSOR,
|
||||
DEVINFO_SUBMODEL,
|
||||
DEVINFO_MODEL,
|
||||
DEVINFO_ADAPTER
|
||||
};
|
||||
|
||||
|
||||
// !!! FIXME: these should probably get sorted alphabetically and/or grouped
|
||||
// !!! FIXME: into areas of functionality, but for now, I'm just listing them
|
||||
@@ -342,6 +406,11 @@ APIRET OS2API DosQueryModuleHandle(PSZ pszModname, PHMODULE phmod);
|
||||
APIRET OS2API DosQueryProcAddr(HMODULE hmod, ULONG ordinal, PSZ pszName, PFN* ppfn);
|
||||
APIRET OS2API DosQueryCp(ULONG cb, PULONG arCP, PULONG pcCP);
|
||||
APIRET OS2API DosOpenL(PSZ pszFileName, PHFILE pHf, PULONG pulAction, LONGLONG cbFile, ULONG ulAttribute, ULONG fsOpenFlags, ULONG fsOpenMode, PEAOP2 peaop2);
|
||||
APIRET OS2API DosFindFirst(PSZ pszFileSpec, PHDIR phdir, ULONG flAttribute, PVOID pfindbuf, ULONG cbBuf, PULONG pcFileNames, ULONG ulInfoLevel);
|
||||
APIRET OS2API DosFindNext(HDIR hDir, PVOID pfindbuf, ULONG cbfindbuf, PULONG pcFilenames);
|
||||
APIRET OS2API DosFindClose(HDIR hDir);
|
||||
APIRET OS2API DosQueryCurrentDisk(PULONG pdisknum, PULONG plogical);
|
||||
APIRET OS2API DosDevConfig(PVOID pdevinfo, ULONG item);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ typedef uint32_t LHANDLE, *PLHANDLE;
|
||||
typedef LHANDLE HANDLE, *PHANDLE;
|
||||
typedef HANDLE HMODULE, *PHMODULE;
|
||||
typedef HANDLE HFILE, *PHFILE;
|
||||
typedef HANDLE HDIR, *PHDIR;
|
||||
typedef HANDLE HEV, *PHEV;
|
||||
typedef HANDLE HMTX, *PHMTX;
|
||||
typedef HANDLE PID, *PPID;
|
||||
|
||||
Reference in new issue
Block a user