From 8457fc0e22245f6340ac306009a2e10201c70451 Mon Sep 17 00:00:00 2001 From: cracyc Date: Mon, 18 Jun 2018 15:52:58 -0400 Subject: [PATCH] Implemented a whole bunch of 16-bit APIs. OS/2 1.0's cmd.exe sort of works! (Most of this work was cracyc's effort, but I started tweaking it before I thought to perform a commit. --ryan.) --- native/doscalls-lx.h | 211 +++++++++++++++++++++++ native/doscalls.c | 400 +++++++++++++++++++++++++++++++++++++++---- native/doscalls.h | 97 ++++++++++- native/kbdcalls-lx.h | 31 +++- native/kbdcalls.c | 34 ++++ native/kbdcalls.h | 11 +- native/msg-lx.h | 25 ++- native/msg.c | 43 ++++- native/msg.h | 3 +- native/nls-lx.h | 33 +++- native/nls.c | 31 +++- native/nls.h | 22 ++- native/os2types.h | 3 + native/sesmgr-lx.h | 23 ++- native/sesmgr.c | 8 +- native/sesmgr.h | 3 +- native/viocalls.c | 1 + 17 files changed, 926 insertions(+), 53 deletions(-) diff --git a/native/doscalls-lx.h b/native/doscalls-lx.h index fadcef2..824ea17 100644 --- a/native/doscalls-lx.h +++ b/native/doscalls-lx.h @@ -9,12 +9,41 @@ /* This is glue code for OS/2 binaries. Native binaries don't need this. */ #if LX_LEGACY +static APIRET16 bridge16to32_Dos16CWait(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, pid); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, ppid); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PRESULTCODES16, pres); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, option); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, action); + return Dos16CWait(action, option, pres, ppid, pid); +} + static VOID bridge16to32_Dos16Exit(uint8 *args) { LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, result); LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, action); Dos16Exit(action, result); } +static APIRET16 bridge16to32_Dos16GetInfoSeg(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PSEL, localseg); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PSEL, globalseg); + return Dos16GetInfoSeg(globalseg, localseg); +} + +static APIRET16 bridge16to32_Dos16HoldSignal(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, action); + return Dos16HoldSignal(action); +} + +static APIRET16 bridge16to32_Dos16SetSigHandler(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, signumber); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, action); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, prevaction); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PVOID, prevaddress); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PFN, routine); + return Dos16SetSigHandler(routine, prevaddress, prevaction, action, signumber); +} + static APIRET16 bridge16to32_Dos16AllocSeg(uint8 *args) { LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, flags); LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, psel); @@ -43,6 +72,101 @@ static APIRET16 bridge16to32_Dos16GetMachineMode(uint8 *args) { return Dos16GetMachineMode(pmode); } +static APIRET16 bridge16to32_Dos16ChDir(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(ULONG, res); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PSZ, pszDir); + return Dos16ChDir(pszDir, res); +} + +static APIRET16 bridge16to32_Dos16ChgFilePtr(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PULONG, newoffset); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, whence); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(LONG, distance); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, handle); + return Dos16ChgFilePtr(handle, distance, whence, newoffset); +} + +static APIRET16 bridge16to32_Dos16Close(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, hFile); + return Dos16Close(hFile); +} + +static APIRET16 bridge16to32_Dos16Delete(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(ULONG, res); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PSZ, pszFile); + return Dos16Delete(pszFile, res); +} + +static APIRET16 bridge16to32_Dos16DupHandle(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, pHfile); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, hFile); + return Dos16DupHandle(hFile, pHfile); +} + +static APIRET16 bridge16to32_Dos16FindClose(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, hDir); + return Dos16FindClose(hDir); +} + +static APIRET16 bridge16to32_Dos16FindFirst(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(ULONG, res); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, pcFileNames); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, cbBuf); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PVOID, pfindbuf); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, flAttribute); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PSHORT, phdir); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PSZ, pszFileSpec); + return Dos16FindFirst(pszFileSpec, phdir, flAttribute, pfindbuf, cbBuf, pcFileNames, res); +} + +static APIRET16 bridge16to32_Dos16FindNext(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, pcFilenames); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, cbfindbuf); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PVOID, pfindbuf); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, hDir); + return Dos16FindNext(hDir, pfindbuf, cbfindbuf, pcFilenames); +} + +static APIRET16 bridge16to32_Dos16Open(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PEAOP2, peaop2); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, fsOpenMode); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, fsOpenFlags); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, ulAttribute); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(ULONG, cbFile); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PULONG, pulAction); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, pHf); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PSZ, pszFileName); + return Dos16Open(pszFileName, pHf, pulAction, cbFile, ulAttribute, fsOpenFlags, fsOpenMode, peaop2); +} + +static APIRET16 bridge16to32_Dos16QCurDir(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, dirpathlen); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PBYTE, dirpath); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, drivenum); + return Dos16QCurDir(drivenum, dirpath, dirpathlen); +} + +static APIRET16 bridge16to32_Dos16QCurDisk(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PULONG, drivemap); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, drivenum); + return Dos16QCurDisk(drivenum, drivemap); +} + +static APIRET16 bridge16to32_Dos16QFileMode(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(ULONG, res); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, attr); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PCHAR, filepath); + return Dos16QFileMode(filepath, attr, res); +} + +static APIRET16 bridge16to32_Dos16QFsInfo(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, infobufsize); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PBYTE, infobuf); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, fslevel); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, drivenum); + return Dos16QFsInfo(drivenum, fslevel, infobuf, infobufsize); +} + static APIRET16 bridge16to32_Dos16QHandType(uint8 *args) { LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, pflags); LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, ptype); @@ -50,6 +174,13 @@ static APIRET16 bridge16to32_Dos16QHandType(uint8 *args) { return Dos16QHandType(handle, ptype, pflags); } +static APIRET16 bridge16to32_Dos16SetVec(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PVOID, prevaddress); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PFN, routine); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, vecnum); + return Dos16SetVec(vecnum, routine, prevaddress); +} + static APIRET16 bridge16to32_Dos16GetEnv(uint8 *args) { LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, pcmdoffset); LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, psel); @@ -73,6 +204,14 @@ static APIRET16 bridge16to32_Dos16GetCp(uint8 *args) { return Dos16GetCp(cb, arCP, pcCP); } +static APIRET16 bridge16to32_Dos16Read(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, pcbActual); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, cbRead); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PVOID, pBuffer); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, hFile); + return Dos16Read(hFile, pBuffer, cbRead, pcbActual); +} + static APIRET16 bridge16to32_Dos16Write(uint8 *args) { LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, actual); LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, buflen); @@ -103,23 +242,54 @@ static APIRET16 bridge16to32_DosSemSet(uint8 *args) { return DosSemSet(sem); } +static APIRET16 bridge16to32_Dos16ExecPgm(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PSZ, pName); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PRESULTCODES16, pRes); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PSZ, pEnv); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PSZ, pArg); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, execFlag); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(SHORT, cbObjname); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PCHAR, pObjname); + return Dos16ExecPgm(pObjname, cbObjname, execFlag, pArg, pEnv, pRes, pName); +} + LX_NATIVE_MODULE_16BIT_SUPPORT() + LX_NATIVE_MODULE_16BIT_API(Dos16CWait) LX_NATIVE_MODULE_16BIT_API(Dos16Exit) + LX_NATIVE_MODULE_16BIT_API(Dos16GetInfoSeg) + LX_NATIVE_MODULE_16BIT_API(Dos16HoldSignal) + LX_NATIVE_MODULE_16BIT_API(Dos16SetSigHandler) LX_NATIVE_MODULE_16BIT_API(Dos16AllocSeg) LX_NATIVE_MODULE_16BIT_API(Dos16ReallocSeg) LX_NATIVE_MODULE_16BIT_API(Dos16FreeSeg) LX_NATIVE_MODULE_16BIT_API(Dos16GetHugeShift) LX_NATIVE_MODULE_16BIT_API(Dos16GetMachineMode) + LX_NATIVE_MODULE_16BIT_API(Dos16ChDir) + LX_NATIVE_MODULE_16BIT_API(Dos16ChgFilePtr) + LX_NATIVE_MODULE_16BIT_API(Dos16Close) + LX_NATIVE_MODULE_16BIT_API(Dos16Delete) + LX_NATIVE_MODULE_16BIT_API(Dos16DupHandle) + LX_NATIVE_MODULE_16BIT_API(Dos16FindClose) + LX_NATIVE_MODULE_16BIT_API(Dos16FindFirst) + LX_NATIVE_MODULE_16BIT_API(Dos16FindNext) + LX_NATIVE_MODULE_16BIT_API(Dos16Open) + LX_NATIVE_MODULE_16BIT_API(Dos16QCurDir) + LX_NATIVE_MODULE_16BIT_API(Dos16QCurDisk) + LX_NATIVE_MODULE_16BIT_API(Dos16QFileMode) + LX_NATIVE_MODULE_16BIT_API(Dos16QFsInfo) LX_NATIVE_MODULE_16BIT_API(Dos16QHandType) + LX_NATIVE_MODULE_16BIT_API(Dos16SetVec) LX_NATIVE_MODULE_16BIT_API(Dos16GetEnv) LX_NATIVE_MODULE_16BIT_API(Dos16GetVersion) LX_NATIVE_MODULE_16BIT_API(Dos16GetPID) LX_NATIVE_MODULE_16BIT_API(Dos16GetCp) + LX_NATIVE_MODULE_16BIT_API(Dos16Read) LX_NATIVE_MODULE_16BIT_API(Dos16Write) LX_NATIVE_MODULE_16BIT_API(DosSemRequest) LX_NATIVE_MODULE_16BIT_API(DosSemClear) LX_NATIVE_MODULE_16BIT_API(DosSemWait) LX_NATIVE_MODULE_16BIT_API(DosSemSet) + LX_NATIVE_MODULE_16BIT_API(Dos16ExecPgm) LX_NATIVE_MODULE_16BIT_SUPPORT_END() LX_NATIVE_MODULE_DEINIT({ @@ -128,43 +298,83 @@ LX_NATIVE_MODULE_DEINIT({ static int init16_doscalls(void) { LX_NATIVE_MODULE_INIT_16BIT_SUPPORT() + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16CWait, 14) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16Exit, 4) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16GetInfoSeg, 8) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16HoldSignal, 2) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16SetSigHandler, 16) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16AllocSeg, 8) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16ReallocSeg, 4) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16FreeSeg, 2) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16GetHugeShift, 4) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16GetMachineMode, 4) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16ChDir, 8) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16ChgFilePtr, 12) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16Close, 2) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16Delete, 8) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16DupHandle, 6) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16FindClose, 2) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16FindFirst, 24) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16FindNext, 12) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16Open, 26) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16QCurDir, 10) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16QCurDisk, 8) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16QFileMode, 12) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16QFsInfo, 10) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16QHandType, 10) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16SetVec, 10) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16GetEnv, 8) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16GetVersion, 4) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16GetPID, 4) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16GetCp, 10) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16Read, 12) LX_NATIVE_INIT_16BIT_BRIDGE(Dos16Write, 12) LX_NATIVE_INIT_16BIT_BRIDGE(DosSemRequest, 8) LX_NATIVE_INIT_16BIT_BRIDGE(DosSemClear, 4) LX_NATIVE_INIT_16BIT_BRIDGE(DosSemWait, 8) LX_NATIVE_INIT_16BIT_BRIDGE(DosSemSet, 4) + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16ExecPgm, 24) LX_NATIVE_MODULE_INIT_16BIT_SUPPORT_END() return 1; } LX_NATIVE_MODULE_INIT({ if (!init16_doscalls()) return 0; }) + LX_NATIVE_EXPORT16(Dos16CWait, 2), LX_NATIVE_EXPORT16(Dos16Exit, 5), + LX_NATIVE_EXPORT16(Dos16GetInfoSeg, 8), + LX_NATIVE_EXPORT16(Dos16HoldSignal, 13), + LX_NATIVE_EXPORT16(Dos16SetSigHandler, 14), LX_NATIVE_EXPORT16(Dos16AllocSeg, 34), LX_NATIVE_EXPORT16(Dos16ReallocSeg, 38), LX_NATIVE_EXPORT16(Dos16FreeSeg, 39), LX_NATIVE_EXPORT16(Dos16GetHugeShift, 41), LX_NATIVE_EXPORT16(Dos16GetMachineMode, 49), + LX_NATIVE_EXPORT16(Dos16ChDir, 57), + LX_NATIVE_EXPORT16(Dos16ChgFilePtr, 58), + LX_NATIVE_EXPORT16(Dos16Close, 59), + LX_NATIVE_EXPORT16(Dos16Delete, 60), + LX_NATIVE_EXPORT16(Dos16DupHandle, 61), + LX_NATIVE_EXPORT16(Dos16FindClose, 63), + LX_NATIVE_EXPORT16(Dos16FindFirst, 64), + LX_NATIVE_EXPORT16(Dos16FindNext, 65), + LX_NATIVE_EXPORT16(Dos16Open, 70), + LX_NATIVE_EXPORT16(Dos16QCurDir, 71), + LX_NATIVE_EXPORT16(Dos16QCurDisk, 72), + LX_NATIVE_EXPORT16(Dos16QFileMode, 75), + LX_NATIVE_EXPORT16(Dos16QFsInfo, 76), LX_NATIVE_EXPORT16(Dos16QHandType, 77), + LX_NATIVE_EXPORT16(Dos16SetVec, 89), LX_NATIVE_EXPORT16(Dos16GetEnv, 91), LX_NATIVE_EXPORT16(Dos16GetVersion, 92), LX_NATIVE_EXPORT16(Dos16GetPID, 94), LX_NATIVE_EXPORT16(Dos16GetCp, 130), + LX_NATIVE_EXPORT16(Dos16Read, 137), LX_NATIVE_EXPORT16(Dos16Write, 138), LX_NATIVE_EXPORT16(DosSemRequest, 140), LX_NATIVE_EXPORT16(DosSemClear, 141), LX_NATIVE_EXPORT16(DosSemWait, 142), LX_NATIVE_EXPORT16(DosSemSet, 143), + LX_NATIVE_EXPORT16(Dos16ExecPgm, 144), LX_NATIVE_EXPORT(DosSetMaxFH, 209), LX_NATIVE_EXPORT(DosSetPathInfo, 219), LX_NATIVE_EXPORT(DosQueryPathInfo, 223), @@ -178,6 +388,7 @@ LX_NATIVE_MODULE_INIT({ if (!init16_doscalls()) return 0; }) LX_NATIVE_EXPORT(DosSetFilePtr, 256), LX_NATIVE_EXPORT(DosClose, 257), LX_NATIVE_EXPORT(DosDelete, 259), + LX_NATIVE_EXPORT(DosDupHandle, 260), LX_NATIVE_EXPORT(DosFindClose, 263), LX_NATIVE_EXPORT(DosFindFirst, 264), LX_NATIVE_EXPORT(DosFindNext, 265), diff --git a/native/doscalls.c b/native/doscalls.c index 84e7ee4..cb084bf 100644 --- a/native/doscalls.c +++ b/native/doscalls.c @@ -104,6 +104,12 @@ typedef struct static DirFinder GHDir1; +static GINFOSEG *ginfo; +static SEL ginfosel; +static LINFOSEG *linfo; +static SEL linfosel; + +static HDIR *hdir16 = 0; static int grabLock(pthread_mutex_t *lock) { @@ -940,10 +946,8 @@ APIRET DosReleaseMutexSem(HMTX hmtx) return ERROR_INVALID_HANDLE; } // DosReleaseMutexSem -APIRET DosSetFilePtr(HFILE hFile, LONG ib, ULONG method, PULONG ibActual) +static APIRET DosSetFilePtr_implementation(HFILE hFile, LONG ib, ULONG method, PULONG ibActual) { - TRACE_NATIVE("DosSetFilePtr(%u, %d, %u, %p)", (uint) hFile, (int) ib, (uint) method, ibActual); - int whence; switch (method) { case FILE_BEGIN: whence = SEEK_SET; break; @@ -967,12 +971,16 @@ APIRET DosSetFilePtr(HFILE hFile, LONG ib, ULONG method, PULONG ibActual) *ibActual = (ULONG) pos; return NO_ERROR; +} // DosSetFilePtr_implementation + +APIRET DosSetFilePtr(HFILE hFile, LONG ib, ULONG method, PULONG ibActual) +{ + TRACE_NATIVE("DosSetFilePtr(%u, %d, %u, %p)", (uint) hFile, (int) ib, (uint) method, ibActual); + return DosSetFilePtr_implementation(hFile, ib, method, ibActual); } // DosSetFilePtr -APIRET DosRead(HFILE hFile, PVOID pBuffer, ULONG cbRead, PULONG pcbActual) +static APIRET DosRead_implementation(HFILE hFile, PVOID pBuffer, ULONG cbRead, PULONG pcbActual) { - TRACE_NATIVE("DosRead(%u, %p, %u, %p)", (uint) hFile, pBuffer, (uint) cbRead, pcbActual); - const int fd = getHFileUnixDescriptor(hFile); if (fd == -1) return ERROR_INVALID_HANDLE; @@ -985,12 +993,16 @@ APIRET DosRead(HFILE hFile, PVOID pBuffer, ULONG cbRead, PULONG pcbActual) *pcbActual = (ULONG) br; return NO_ERROR; +} // DosRead_implementation + +APIRET DosRead(HFILE hFile, PVOID pBuffer, ULONG cbRead, PULONG pcbActual) +{ + TRACE_NATIVE("DosRead(%u, %p, %u, %p)", (uint) hFile, pBuffer, (uint) cbRead, pcbActual); + return DosRead_implementation(hFile, pBuffer, cbRead, pcbActual); } // DosRead -APIRET DosClose(HFILE hFile) +static APIRET DosClose_implementation(HFILE hFile) { - TRACE_NATIVE("DosClose(%u)", (uint) hFile); - const int fd = getHFileUnixDescriptor(hFile); if (fd == -1) return ERROR_INVALID_HANDLE; @@ -1008,8 +1020,15 @@ APIRET DosClose(HFILE hFile) ungrabLock(&GMutexDosCalls); return NO_ERROR; +} // DosClose_implementation + +APIRET DosClose(HFILE hFile) +{ + TRACE_NATIVE("DosClose(%u)", (uint) hFile); + return DosClose_implementation(hFile); } // DosClose + APIRET DosEnterMustComplete(PULONG pulNesting) { TRACE_NATIVE("DosEnterMustComplete(%p)", pulNesting); @@ -1503,10 +1522,8 @@ static void setProcessResultCode(PRESULTCODES pRes, const int status) } // else if } // setProcessResultCode -APIRET DosExecPgm(PCHAR pObjname, LONG cbObjname, ULONG execFlag, PSZ pArg, PSZ pEnv, PRESULTCODES pRes, PSZ pName) +static APIRET DosExecPgm_implementation(PCHAR pObjname, LONG cbObjname, ULONG execFlag, PSZ pArg, PSZ pEnv, PRESULTCODES pRes, PSZ pName) { - TRACE_NATIVE("DosExecPgm(%p, %u, %u, %p, %p, %p, '%s')", pObjname, (uint) cbObjname, (uint) execFlag, pArg, pEnv, pRes, pName); - APIRET retval = NO_ERROR; if (pObjname) // !!! FIXME: what does it want to put in here for failures? @@ -1609,6 +1626,12 @@ APIRET DosExecPgm(PCHAR pObjname, LONG cbObjname, ULONG execFlag, PSZ pArg, PSZ free(exe); return retval; +} // DosExecPgm_implementation + +APIRET DosExecPgm(PCHAR pObjname, LONG cbObjname, ULONG execFlag, PSZ pArg, PSZ pEnv, PRESULTCODES pRes, PSZ pName) +{ + TRACE_NATIVE("DosExecPgm('%s', %u, %u, '%s', '%s', %p, '%s')", pObjname, (uint) cbObjname, (uint) execFlag, pArg, pEnv, pRes, pName); + return DosExecPgm_implementation(pObjname, cbObjname, execFlag, pArg, pEnv, pRes, pName) } // DosExecPgm APIRET DosResetEventSem(HEV hev, PULONG pulPostCt) @@ -1908,11 +1931,11 @@ APIRET DosSubFreeMem(PVOID pbBase, PVOID pb, ULONG cb) return NO_ERROR; } // DosSubAllocMem -APIRET DosDelete(PSZ pszFile) +static APIRET DosDelete_implementation(PSZ pszFile) { - TRACE_NATIVE("DosDelete('%s')", pszFile); - APIRET err; + if (!pszFile) + return ERROR_INVALID_PARAMETER; char *unixpath = makeUnixPath(pszFile, &err); if (!unixpath) return err; @@ -1934,8 +1957,15 @@ APIRET DosDelete(PSZ pszFile) } // if return NO_ERROR; +} // DosDelete_implementation + +APIRET DosDelete(PSZ pszFile) +{ + TRACE_NATIVE("DosDelete('%s')", pszFile); + return DosDelete_implementation(pszFile); } // DosDelete + APIRET DosQueryCurrentDir(ULONG disknum, PBYTE pBuf, PULONG pcbBuf) { TRACE_NATIVE("DosQueryCurrentDir(%u, %p, %p)", (uint) disknum, pBuf, pcbBuf); @@ -2058,6 +2088,17 @@ APIRET DosOpenL(PSZ pszFileName, PHFILE pHf, PULONG pulAction, LONGLONG cbFile, return doDosOpen(pszFileName, pHf, pulAction, cbFile, ulAttribute, fsOpenFlags, fsOpenMode, peaop2); } // DosOpenL +static inline ULONG findNextSizeNeeded(const ULONG ulInfoLevel, const ULONG pcFileNames) +{ + switch (ulInfoLevel) { + case -1: return (sizeof (FILEFINDBUF) - CCHMAXPATHCOMP) * pcFileNames; + case FIL_STANDARD: return (sizeof (FILEFINDBUF3) - CCHMAXPATHCOMP) * pcFileNames; + case FIL_QUERYEASIZE: return (sizeof (FILEFINDBUF4) - CCHMAXPATHCOMP) * pcFileNames; + case FIL_QUERYEASFROMLIST: FIXME("write me"); return 0xFFFFFFFF; + default: assert(!"Shouldn't hit this."); return 0xFFFFFFFF; + } // switch + __builtin_unreachable(); +} // findNextSizeNeeded; static int wildcardMatch(const char *str, const char *pattern) { @@ -2094,7 +2135,7 @@ static int wildcardMatch(const char *str, const char *pattern) __builtin_unreachable(); } // wildcardMatch -static int findNextOne(DirFinder *dirf, PVOID *ppfindbuf, PULONG pcbBuf) +static int findNextOne(DirFinder *dirf, PVOID *ppfindbuf, PULONG pcbBuf, int *err) { const ULONG attr = dirf->attr; const ULONG musthave = (attr & 0xFF00) >> 8; @@ -2115,6 +2156,7 @@ static int findNextOne(DirFinder *dirf, PVOID *ppfindbuf, PULONG pcbBuf) const size_t namelen = strlen(name); if (namelen >= CCHMAXPATHCOMP) continue; + if (namelen + findNextSizeNeeded(dirf->level, 1) >= *pcbBuf) continue; // FIXME?? if (!wildcardMatch(name, pattern)) continue; @@ -2147,6 +2189,20 @@ static int findNextOne(DirFinder *dirf, PVOID *ppfindbuf, PULONG pcbBuf) // okay! Definitely take this one! switch (dirf->level) { + case -1: { + PFILEFINDBUF st = (PFILEFINDBUF) *ppfindbuf; + 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_STANDARD: { PFILEFINDBUF3 st = (PFILEFINDBUF3) *ppfindbuf; memset(st, '\0', sizeof (*st)); @@ -2203,8 +2259,10 @@ static APIRET findNext(DirFinder *dirf, PVOID pfindbuf, ULONG cbBuf, PULONG pcFi const ULONG maxents = *pcFileNames; ULONG i; + int err = NO_ERROR; + memset(pfindbuf, 0, cbBuf); for (i = 0; i < maxents; i++) { - if (!findNextOne(dirf, &pfindbuf, &cbBuf)) + if (!findNextOne(dirf, &pfindbuf, &cbBuf, &err)) break; } // for @@ -2213,22 +2271,12 @@ static APIRET findNext(DirFinder *dirf, PVOID pfindbuf, ULONG cbBuf, PULONG pcFi if ((i == 0) && (maxents > 0)) { closedir(dirf->dirp); dirf->dirp = NULL; + err = ERROR_NO_MORE_FILES; } // if - return NO_ERROR; + return err; } // 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); @@ -2237,7 +2285,7 @@ APIRET DosFindFirst(PSZ pszFileSpec, PHDIR phdir, ULONG flAttribute, PVOID pfind 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)) + else if ((ulInfoLevel != FIL_STANDARD) && (ulInfoLevel != FIL_QUERYEASIZE) && (ulInfoLevel != FIL_QUERYEASFROMLIST) && (ulInfoLevel != -1)) // -1 for 16 call return ERROR_INVALID_PARAMETER; else if (!pcFileNames) return ERROR_INVALID_PARAMETER; @@ -2250,7 +2298,7 @@ APIRET DosFindFirst(PSZ pszFileSpec, PHDIR phdir, ULONG flAttribute, PVOID pfind else if (cbBuf < findNextSizeNeeded(ulInfoLevel, *pcFileNames)) return ERROR_BUFFER_OVERFLOW; - if (ulInfoLevel != FIL_STANDARD) { + if ((ulInfoLevel != FIL_STANDARD) && (ulInfoLevel != -1)) { FIXME("implement extended attribute support"); return ERROR_INVALID_PARAMETER; } // if @@ -2328,6 +2376,8 @@ APIRET DosFindFirst(PSZ pszFileSpec, PHDIR phdir, ULONG flAttribute, PVOID pfind return err; } // if + if (err == ERROR_NO_MORE_FILES) + return ERROR_FILE_NOT_FOUND; *phdir = (HDIR) dirf; return NO_ERROR; } // DosFindFirst @@ -2907,6 +2957,45 @@ APIRET DosSetFileSize(HFILE h, ULONG len) return NO_ERROR; } // DosSetFileSize +static APIRET DosDupHandle_implementation(HFILE hFile, PHFILE pHfile) +{ + if (*pHfile == -1) { + HFileInfo *info = HFiles; + uint32 i; + + if (!grabLock(&GMutexDosCalls)) + return ERROR_SYS_INTERNAL; + + for (i = 0; i < MaxHFiles; i++, info++) { + if (info->fd == -1) { // available? + info->fd = -2; + break; + } // if + } // for + + ungrabLock(&GMutexDosCalls); + + if (i == MaxHFiles) { + return ERROR_TOO_MANY_OPEN_FILES; + } + memcpy(&HFiles[i], &HFiles[hFile], sizeof(HFileInfo)); + HFiles[i].fd = dup(HFiles[hFile].fd); + *pHfile = i; + } else { + if (HFiles[*pHfile].fd != -1) + return ERROR_INVALID_TARGET_HANDLE; + memcpy(&HFiles[*pHfile], &HFiles[hFile], sizeof(HFileInfo)); + HFiles[*pHfile].fd = dup(HFiles[hFile].fd); + } + return NO_ERROR; +} // DosDupHandle_implementation + +APIRET DosDupHandle(HFILE hFile, PHFILE pHfile) +{ + TRACE_NATIVE("DosDupHandle(%u, %p)", hFile, pHfile); + return DosDupHandle_implementation(hFile, pHfile); +} // DosDupHandle + APIRET16 Dos16GetVersion(PUSHORT pver) { TRACE_NATIVE("Dos16GetVersion(%p)", pver); @@ -3063,6 +3152,220 @@ APIRET16 Dos16Write(USHORT h, PVOID buf, USHORT buflen, PUSHORT actual) return (APIRET16) rc; } // Dos16Write +APIRET16 Dos16SetVec(USHORT vecnum, PFN routine, PVOID prevaddress) +{ + TRACE_NATIVE("Dos16SetVec(%u, %p, %p)", (uint) vecnum, routine, prevaddress); + FIXME("do something"); + if (prevaddress) *(PFN *)prevaddress = 0; + return NO_ERROR; +} + +APIRET16 Dos16SetSigHandler(PFN routine, PVOID prevaddress, PUSHORT prevaction, USHORT action, USHORT signumber) +{ + TRACE_NATIVE("Dos16SetSigHandler(%p, %p, %p, %u, %u)", routine, prevaddress, prevaction, action, signumber); + FIXME("do something"); + if (prevaddress) *(PFN *)prevaddress = 0; + if (prevaction) *prevaction = 0; + return NO_ERROR; +} + +APIRET16 OS2API16 Dos16GetInfoSeg(PSEL globalseg, PSEL localseg) +{ + TRACE_NATIVE("Dos16GetInfoSeg(%p, %p)", globalseg, localseg); + if (globalseg) *globalseg = ginfosel << 3 | 7; + if (localseg) *localseg = linfosel << 3 | 7; + return NO_ERROR; +} + +APIRET16 Dos16QCurDisk(PUSHORT drivenum, PULONG drivemap) +{ + TRACE_NATIVE("Dos16QCurDisk(%p, %p)", drivenum, drivemap); + if (drivenum) *drivenum = 3; // FIXME: C: only + if (drivemap) *drivemap = 1 << 2; + return NO_ERROR; +} + +APIRET16 Dos16QCurDir(USHORT drivenum, PBYTE dirpath, PUSHORT dirpathlen) +{ + TRACE_NATIVE("Dos16QCurDir(%d, %p, %p)", drivenum, dirpath, dirpathlen); + if (!dirpathlen || !dirpath) return ERROR_INVALID_PARAMETER; // ??? + int rlen, len = *dirpathlen; + char dirtmp[PATH_MAX]; + getcwd(dirtmp, PATH_MAX); + rlen = strlen(dirtmp); + if (dirpathlen) *dirpathlen = rlen + 1; + if (rlen >= len) { + *dirpathlen = rlen + 1; + return ERROR_BUFFER_OVERFLOW; + } + char *pch = strchr(dirtmp, '/'); + while (pch) { + *pch = '\\'; + pch = strchr(pch, '/'); + } + + strcpy((char *)dirpath, dirtmp + 1); + return NO_ERROR; +} + +APIRET16 Dos16HoldSignal(USHORT action) +{ + TRACE_NATIVE("Dos16HoldSignal(%d)", action); + FIXME("stub"); + return NO_ERROR; +} + +APIRET16 Dos16QFsInfo(USHORT drivenum, USHORT fslevel, PBYTE infobuf, USHORT infobufsize) +{ + TRACE_NATIVE("Dos16QFsInfo(%d, %d, %p, %d)", drivenum, fslevel, infobuf, infobufsize); + const char label[] = "linux"; + if (fslevel == 1) + FIXME("fslevel 1"); + else if (fslevel == 2) + { + infobuf[4] = sizeof(label); + strcpy((char *)&infobuf[5], label); + } + return NO_ERROR; +} + +APIRET16 Dos16QFileMode(PCHAR filepath, PUSHORT attr, ULONG res) +{ + TRACE_NATIVE("Dos16QFileMode('%s', %p, %d)", filepath, attr, res); + APIRET err; + char *path = makeUnixPath(filepath, &err); + if (!path) return err; + struct stat sbuf; + int ret = stat(path, &sbuf); + free(path); + if (ret) return ERROR_FILE_NOT_FOUND; + *attr = 0; + if (S_ISDIR(sbuf.st_mode)) + *attr |= (1 << 4); + return NO_ERROR; +} + +APIRET16 Dos16Open(PSZ pszFileName, PUSHORT pHf, PULONG pulAction, ULONG cbFile, USHORT ulAttribute, USHORT fsOpenFlags, USHORT fsOpenMode, PEAOP2 peaop2) +{ + TRACE_NATIVE("Dos16Open('%s', %p, %p, %u, %u, %u, %u, %p)", pszFileName, pHf, pulAction, (uint) cbFile, (uint) ulAttribute, (uint) fsOpenFlags, (uint) fsOpenMode, peaop2); + HFILE hf; + APIRET ret = doDosOpen(pszFileName, &hf, pulAction, (LONGLONG) cbFile, ulAttribute, fsOpenFlags, fsOpenMode, peaop2); + *pHf = hf; + return ret; +} // DosOpen + +APIRET16 Dos16FindFirst(PSZ pszFileSpec, PSHORT phdir, USHORT flAttribute, PVOID pfindbuf, USHORT cbBuf, PUSHORT pcFileNames, ULONG res) +{ + if (!hdir16) + hdir16 = calloc(10, sizeof(HDIR)); // 10 dir handles + ULONG hdir32 = *phdir; + ULONG cfn = *pcFileNames; + APIRET ret = DosFindFirst(pszFileSpec, &hdir32, flAttribute, pfindbuf, cbBuf, &cfn, -1); + if (ret && (ret != ERROR_EAS_DIDNT_FIT)) + return ret; + int i; + for (i = 0; i < 10; i++) + { + if(!hdir16[i]) + break; + } + if (i == 10) + return ERROR_NO_MORE_FILES; + hdir16[i] = hdir32; + *phdir = i; + *pcFileNames = cfn; + return ret; +} + +APIRET16 Dos16ChDir(PSZ pszDir, ULONG res) +{ + TRACE_NATIVE("Dos16ChDir('%s', %u)", pszDir, res); + APIRET err; + char *path = makeUnixPath(pszDir, &err); + if (!path) return err; + int ret = chdir(path); + free(path); + if (ret && (errno == ENOENT)) return ERROR_PATH_NOT_FOUND; + else if (ret) return ERROR_ACCESS_DENIED; + return NO_ERROR; +} + +APIRET16 Dos16Close(USHORT hFile) +{ + TRACE_NATIVE("Dos16Close(%u)", (uint) hFile); + return DosClose_implementation(hFile); +} // Dos16Close + +APIRET16 Dos16FindNext(USHORT hDir, PVOID pfindbuf, USHORT cbfindbuf, PUSHORT pcFilenames) +{ + APIRET ret; + ULONG pcfn = *pcFilenames; + ret = DosFindNext(hdir16[hDir], pfindbuf, cbfindbuf, &pcfn); + *pcFilenames = pcfn; + return ret; +} + +APIRET16 Dos16FindClose(USHORT hDir) +{ + if (hDir > 10) + return ERROR_INVALID_HANDLE; + HDIR hdir32 = hdir16[hDir]; + hdir16[hDir] = 0; + return DosFindClose(hdir32); +} + +APIRET16 Dos16Delete(PSZ pszFile, ULONG res) +{ + TRACE_NATIVE("Dos16Delete('%s', %u)", pszFile, (uint) res); + return DosDelete_implementation(pszFile); +} // Dos16Delete + +APIRET16 Dos16DupHandle(USHORT hFile, PUSHORT pHfile) +{ + TRACE_NATIVE("Dos16DupHandle(%u, %p)", (uint) hFile, pHfile); + HFILE phf = *(int16_t *)pHfile; + APIRET ret = DosDupHandle_implementation(hFile, &phf); + *pHfile = phf; + return ret; +} // Dos16DupHandle + +APIRET16 Dos16Read(USHORT hFile, PVOID pBuffer, USHORT cbRead, PUSHORT pcbActual) +{ + TRACE_NATIVE("Dos16Read(%u, %p, %u, %p)", (uint) hFile, pBuffer, (uint) cbRead, pcbActual); + ULONG actual; + APIRET ret = DosRead_implementation(hFile, pBuffer, cbRead, &actual); + *pcbActual = (USHORT) actual; + return ret; +} // Dos16Read + +APIRET16 Dos16ExecPgm(PCHAR pObjname, SHORT cbObjname, USHORT execFlag, PSZ pArg, PSZ pEnv, PRESULTCODES16 pRes, PSZ pName) +{ + TRACE_NATIVE("Dos16ExecPgm('%s', %d, %u, '%s', '%s', %p, '%s')", pObjname, (int) cbObjname, (uint) execFlag, pArg, pEnv, pRes, pName); + RESULTCODES res; + const APIRET ret = DosExecPgm_implementation(pObjname, cbObjname, execFlag, pArg, pEnv, &res, pName); + pRes->codeTerminate = (USHORT) res.codeTerminate; + pRes->codeResult = (USHORT) res.codeResult; + return ret; +} // Dos16ExecPgm + +APIRET16 Dos16CWait(USHORT action, USHORT option, PRESULTCODES16 pres, PUSHORT ppid, USHORT pid) +{ + TRACE_NATIVE("Dos16CWait(%u, %u, %p, %p, %u)", (uint) action, (uint) option, pres, ppid, (uint) pid); + RESULTCODES res; + PID cpid; + APIRET ret = DosWaitChild(action, option, &res, &cpid, pid); + pres->codeTerminate = res.codeTerminate; + pres->codeResult = res.codeResult; + *ppid = cpid; + return ret; +} // Dos16CWait + +APIRET16 Dos16ChgFilePtr(USHORT handle, LONG distance, USHORT whence, PULONG newoffset) +{ + TRACE_NATIVE("Dos16ChgFlePtr(%u, %u, %u, %p)", (uint) handle, (uint) distance, (uint) whence, newoffset); + return (APIRET16) DosSetFilePtr_implementation(handle, distance, whence, newoffset); +} // Dos16ChgFilePtr + LX_NATIVE_CONSTRUCTOR(doscalls) { @@ -3103,6 +3406,39 @@ LX_NATIVE_CONSTRUCTOR(doscalls) for (int i = 0; i <= 2; i++) { initHFileInfoFromUnixFd(i, &HFiles[i]); } // for + + GLoaderState.allocSegment(&ginfosel, 0); + GLoaderState.allocSegment(&linfosel, 0); + ginfo = (GINFOSEG *)GLoaderState.convert1616to32(ginfosel << 19); + linfo = (LINFOSEG *)GLoaderState.convert1616to32(linfosel << 19); + memset(ginfo, 0, sizeof(GINFOSEG)); + memset(linfo, 0, sizeof(LINFOSEG)); + ginfo->time = time(0); + struct tm *gtime = gmtime((time_t *)&ginfo->time); + ginfo->hour = gtime->tm_hour; + ginfo->minutes = gtime->tm_min; + ginfo->seconds = gtime->tm_sec; + ginfo->timezone = 0; + ginfo->cusecTimerInterval = 100; + ginfo->day = gtime->tm_mday; + ginfo->month = gtime->tm_mon; + ginfo->year = gtime->tm_year; + ginfo->weekday = gtime->tm_wday; + ginfo->uchMajorVersion = 20; + ginfo->uchMinorVersion = 40; + ginfo->sgCurrent = 1; + ginfo->sgMax = 99; + ginfo->cHugeShift = 0; + ginfo->fProtectModeOnly = 1; + ginfo->pidForeground = GLoaderState.pib.pib_ulpid; + ginfo->csecMaxWait = 1; + ginfo->cmsecMinSlice = 1; + ginfo->cmsecMaxSlice = 10; + ginfo->bootdrive = 3; + ginfo->csgWindowableVioMax = 99; + ginfo->csgPMMax = 99; + linfo->pidCurrent = GLoaderState.pib.pib_ulpid; + linfo->pidParent = GLoaderState.pib.pib_ulppid; } LX_NATIVE_DESTRUCTOR(doscalls) @@ -3125,6 +3461,8 @@ LX_NATIVE_DESTRUCTOR(doscalls) HFiles = NULL; MaxHFiles = 0; + GLoaderState.freeSelector(ginfosel); + GLoaderState.freeSelector(linfosel); pthread_mutex_destroy(&GMutexDosCalls); } diff --git a/native/doscalls.h b/native/doscalls.h index 53e497d..2edd533 100644 --- a/native/doscalls.h +++ b/native/doscalls.h @@ -256,6 +256,12 @@ typedef struct ULONG codeResult; } RESULTCODES, *PRESULTCODES; +typedef struct +{ + USHORT codeTerminate; + USHORT codeResult; +} RESULTCODES16, *PRESULTCODES16; + enum { EXEC_SYNC, @@ -317,6 +323,21 @@ enum MUST_HAVE_ARCHIVED = ( (FILE_ARCHIVED << 8) | FILE_ARCHIVED ) }; +typedef struct +{ + FDATE fdateCreation; + FTIME ftimeCreation; + FDATE fdateLastAccess; + FTIME ftimeLastAccess; + FDATE fdateLastWrite; + FTIME ftimeLastWrite; + ULONG cbFile; + ULONG cbFileAlloc; + USHORT attrFile; + UCHAR cchName; + CHAR achName[CCHMAXPATHCOMP]; +} FILEFINDBUF, *PFILEFINDBUF; + typedef struct { ULONG oNextEntryOffset; @@ -361,6 +382,59 @@ typedef struct UCHAR rgFSAData[1]; } FSQBUFFER2, *PFSQBUFFER2; +typedef struct +{ + ULONG time; + ULONG msecs; + UCHAR hour; + UCHAR minutes; + UCHAR seconds; + UCHAR hundredths; + USHORT timezone; + USHORT cusecTimerInterval; + UCHAR day; + UCHAR month; + USHORT year; + UCHAR weekday; + UCHAR uchMajorVersion; + UCHAR uchMinorVersion; + UCHAR chRevisionLetter; + UCHAR sgCurrent; + UCHAR sgMax; + UCHAR cHugeShift; + UCHAR fProtectModeOnly; + USHORT pidForeground; + UCHAR fDynamicSched; + UCHAR csecMaxWait; + USHORT cmsecMinSlice; + USHORT cmsecMaxSlice; + USHORT bootdrive; + UCHAR amecRAS[32]; + UCHAR csgWindowableVioMax; + UCHAR csgPMMax; +} GINFOSEG; + +typedef struct +{ + PID pidCurrent; + PID pidParent; + USHORT prtyCurrent; + TID tidCurrent; + USHORT sgCurrent; + UCHAR rfProcStatus; + UCHAR dummy1; + BOOL fForeground; + UCHAR typeProcess; + UCHAR dummy2; + SEL selEnvironment; + USHORT offCmdLine; + USHORT cbDataSegment; + USHORT cbStack; + USHORT cbHeap; + HMODULE hmod; + SEL selDS; +} LINFOSEG; + enum { DEVINFO_PRINTER, @@ -450,13 +524,32 @@ OS2EXPORT APIRET16 OS2API16 Dos16GetPID(PPIDINFO16 ppidinfo) OS2APIINFO(94); OS2EXPORT APIRET16 OS2API16 Dos16GetCp(USHORT cb, PUSHORT arCP, PUSHORT pcCP) OS2APIINFO(130); OS2EXPORT APIRET16 OS2API16 Dos16GetEnv(PUSHORT psel, PUSHORT pcmdoffset) OS2APIINFO(91); OS2EXPORT APIRET16 OS2API16 Dos16Write(USHORT h, PVOID buf, USHORT buflen, PUSHORT actual) OS2APIINFO(138); - - +OS2EXPORT APIRET16 OS2API16 Dos16SetVec(USHORT vecnum, PFN routine, PVOID prevaddress) OS2APIINFO(89); /* prevaddress is a PFN * */ +OS2EXPORT APIRET16 OS2API16 Dos16SetSigHandler(PFN routine, PVOID prevaddress, PUSHORT prevaction, USHORT action, USHORT signumber) OS2APIINFO(14); /* prevaddress is a PFNSIGHANDLER * routine is a PFNSIGHANDLER */ +OS2EXPORT APIRET16 OS2API16 Dos16GetInfoSeg(PSEL globalseg, PSEL localseg) OS2APIINFO(8); +OS2EXPORT APIRET16 OS2API16 Dos16QCurDisk(PUSHORT drivenum, PULONG drivemap) OS2APIINFO(72); +OS2EXPORT APIRET16 OS2API16 Dos16QCurDir(USHORT drivenum, PBYTE dirpath, PUSHORT dirpathlen) OS2APIINFO(71); +OS2EXPORT APIRET16 OS2API16 Dos16HoldSignal(USHORT action) OS2APIINFO(13); +OS2EXPORT APIRET16 OS2API16 Dos16QFsInfo(USHORT drivenum, USHORT fslevel, PBYTE infobuf, USHORT infobufsize) OS2APIINFO(76); +OS2EXPORT APIRET16 OS2API16 Dos16QFileMode(PCHAR filepath, PUSHORT attr, ULONG res) OS2APIINFO(75); +OS2EXPORT APIRET16 OS2API16 Dos16Open(PSZ pszFileName, PUSHORT pHf, PULONG pulAction, ULONG cbFile, USHORT ulAttribute, USHORT fsOpenFlags, USHORT fsOpenMode, PEAOP2 peaop2) OS2APIINFO(70); +OS2EXPORT APIRET16 OS2API16 Dos16FindFirst(PSZ pszFileSpec, PSHORT phdir, USHORT flAttribute, PVOID pfindbuf, USHORT cbBuf, PUSHORT pcFileNames, ULONG res) OS2APIINFO(64); +OS2EXPORT APIRET16 OS2API16 Dos16ChDir(PSZ pszDir, ULONG res) OS2APIINFO(57); +OS2EXPORT APIRET16 OS2API16 Dos16Close(USHORT hFile) OS2APIINFO(59); +OS2EXPORT APIRET16 OS2API16 Dos16FindNext(USHORT hDir, PVOID pfindbuf, USHORT cbfindbuf, PUSHORT pcFilenames) OS2APIINFO(65); +OS2EXPORT APIRET16 OS2API16 Dos16FindClose(USHORT hDir) OS2APIINFO(63); +OS2EXPORT APIRET16 OS2API16 Dos16Delete(PSZ pszFile, ULONG res) OS2APIINFO(60); +OS2EXPORT APIRET16 OS2API16 Dos16DupHandle(USHORT hFile, PUSHORT pHfile) OS2APIINFO(61); +OS2EXPORT APIRET16 OS2API16 Dos16Read(USHORT hFile, PVOID pBuffer, USHORT cbRead, PUSHORT pcbActual) OS2APIINFO(137); +OS2EXPORT APIRET16 OS2API16 Dos16ExecPgm(PCHAR pObjname, SHORT cbObjname, USHORT execFlag, PSZ pArg, PSZ pEnv, PRESULTCODES16 pRes, PSZ pName) OS2APIINFO(144); +OS2EXPORT APIRET16 OS2API16 Dos16CWait(USHORT action, USHORT option, PRESULTCODES16 pres, PUSHORT ppid, USHORT pid) OS2APIINFO(2); +OS2EXPORT APIRET16 OS2API16 Dos16ChgFilePtr(USHORT handle, LONG distance, USHORT whence, PULONG newoffset) OS2APIINFO(58); // !!! FIXME: these should probably get sorted alphabetically and/or grouped // !!! FIXME: into areas of functionality, but for now, I'm just listing them // !!! FIXME: in the order I implemented them to get things running. +OS2EXPORT APIRET OS2API DosDupHandle(HFILE hFile, PHFILE pHfile) OS2APIINFO(260); OS2EXPORT APIRET OS2API DosGetInfoBlocks(PTIB *pptib, PPIB *pppib) OS2APIINFO(312); OS2EXPORT APIRET OS2API DosQuerySysInfo(ULONG iStart, ULONG iLast, PVOID pBuf, ULONG cbBuf) OS2APIINFO(348); OS2EXPORT APIRET OS2API DosQueryModuleName(HMODULE hmod, ULONG cbName, PCHAR pch) OS2APIINFO(320); diff --git a/native/kbdcalls-lx.h b/native/kbdcalls-lx.h index aa88329..13c39bc 100644 --- a/native/kbdcalls-lx.h +++ b/native/kbdcalls-lx.h @@ -16,8 +16,31 @@ static APIRET16 bridge16to32_KbdCharIn(uint8 *args) { return KbdCharIn(pkbci, fWait, hkbd); } +static APIRET16 bridge16to32_KbdStringIn(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HKBD, hkbd); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, flag); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PSTRINGINBUF, pchin); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PCHAR, pch); + return KbdStringIn(pch, pchin, flag, hkbd); +} + +static APIRET16 bridge16to32_KbdGetStatus(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HKBD, hkbd); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PKBDKEYINFO, pkbci); + return KbdGetStatus(pkbci, hkbd); +} + +static APIRET16 bridge16to32_KbdSetStatus(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(HKBD, hkbd); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PKBDKEYINFO, pkbci); + return KbdSetStatus(pkbci, hkbd); +} + LX_NATIVE_MODULE_16BIT_SUPPORT() LX_NATIVE_MODULE_16BIT_API(KbdCharIn) + LX_NATIVE_MODULE_16BIT_API(KbdStringIn) + LX_NATIVE_MODULE_16BIT_API(KbdGetStatus) + LX_NATIVE_MODULE_16BIT_API(KbdSetStatus) LX_NATIVE_MODULE_16BIT_SUPPORT_END() LX_NATIVE_MODULE_DEINIT({ @@ -27,12 +50,18 @@ LX_NATIVE_MODULE_DEINIT({ static int init16_kbdcalls(void) { LX_NATIVE_MODULE_INIT_16BIT_SUPPORT() LX_NATIVE_INIT_16BIT_BRIDGE(KbdCharIn, 8) + LX_NATIVE_INIT_16BIT_BRIDGE(KbdStringIn, 12) + LX_NATIVE_INIT_16BIT_BRIDGE(KbdGetStatus, 6) + LX_NATIVE_INIT_16BIT_BRIDGE(KbdSetStatus, 6) LX_NATIVE_MODULE_INIT_16BIT_SUPPORT_END() return 1; } LX_NATIVE_MODULE_INIT({ if (!init16_kbdcalls()) return 0; }) - LX_NATIVE_EXPORT16(KbdCharIn, 4) + LX_NATIVE_EXPORT16_DIFFERENT_NAME(KbdCharIn, "KBDCHARIN", 4), + LX_NATIVE_EXPORT16_DIFFERENT_NAME(KbdStringIn, "KBDSTRINGIN", 9), + LX_NATIVE_EXPORT16_DIFFERENT_NAME(KbdGetStatus, "KBDGETSTATUS", 10), + LX_NATIVE_EXPORT16_DIFFERENT_NAME(KbdSetStatus, "KBDSETSTATUS", 11) LX_NATIVE_MODULE_INIT_END() #endif /* LX_LEGACY */ diff --git a/native/kbdcalls.c b/native/kbdcalls.c index 7e7e51f..5d98779 100644 --- a/native/kbdcalls.c +++ b/native/kbdcalls.c @@ -20,5 +20,39 @@ APIRET16 KbdCharIn(PKBDKEYINFO pkbci, USHORT fWait, HKBD hkbd) return NO_ERROR; } // kbdCharIn +APIRET16 KBDGETSTATUS(PKBDKEYINFO pkbci, HKBD hkbd) +{ + TRACE_NATIVE("KbdGetStatus(%p, %u)", pkbci, hkbd); + FIXME("stub"); + memset(pkbci, '\0', sizeof (*pkbci)); + return NO_ERROR; +} + +APIRET16 KBDSETSTATUS(PKBDKEYINFO pkbci, HKBD hkbd) +{ + TRACE_NATIVE("KbdSetStatus(%p, %u)", pkbci, hkbd); + FIXME("stub"); + return NO_ERROR; +} + +APIRET16 KBDSTRINGIN(PCHAR pch, PSTRINGINBUF pchin, USHORT flag, HKBD hkbd) +{ + TRACE_NATIVE("KbdStringIn(%p, %p, %u, %u)", pch, pchin, flag, hkbd); + if (!pch) return ERROR_INVALID_PARAMETER; + int count = 0; + char chr = getchar(); + while ((chr != '\r') && (chr != '\n') && (count < pchin->cb)) + { + pch[count++] = chr; + chr = getchar(); + } + if (count < (pchin->cb - 1)) + { + pch[count] = '\r'; + } + if (pchin) pchin->cchIn = count; + return NO_ERROR; +} + // end of kbdcalls.c ... diff --git a/native/kbdcalls.h b/native/kbdcalls.h index 3c9cc50..30b0a12 100644 --- a/native/kbdcalls.h +++ b/native/kbdcalls.h @@ -25,9 +25,18 @@ typedef struct USHORT fsState; ULONG time; } KBDKEYINFO, *PKBDKEYINFO; + +typedef struct +{ + USHORT cb; + USHORT cchIn; +} STRINGINBUF, *PSTRINGINBUF; #pragma pack(pop) -OS2EXPORT APIRET16 OS2API16 KbdCharIn(PKBDKEYINFO pkbci, USHORT fWait, HKBD hkbd) OS2APIINFO(4); +OS2EXPORT APIRET16 OS2API16 KbdCharIn(PKBDKEYINFO pkbci, USHORT fWait, HKBD hkbd) OS2APIINFO(ord=4,name=KBDCHARIN); +OS2EXPORT APIRET16 OS2API16 KbdStringIn(PCHAR pch, PSTRINGINBUF pchin, USHORT flag, HKBD hkbd) OS2APIINFO(ord=9,name=KBDSTRINGIN); +OS2EXPORT APIRET16 OS2API16 KbdGetStatus(PKBDKEYINFO pkbci, HKBD hkbd) OS2APIINFO(ord=10,name=KBDGETSTATUS); +OS2EXPORT APIRET16 OS2API16 KbdSetStatus(PKBDKEYINFO pkbci, HKBD hkbd) OS2APIINFO(ord=11,name=KBDSETSTATUS); #ifdef __cplusplus } diff --git a/native/msg-lx.h b/native/msg-lx.h index c91855c..dc56468 100644 --- a/native/msg-lx.h +++ b/native/msg-lx.h @@ -9,15 +9,28 @@ /* This is glue code for OS/2 binaries. Native binaries don't need this. */ #if LX_LEGACY -static APIRET16 bridge16to32_Dos16PutMessage(uint8 *args) { +static APIRET16 bridge16to32_DOSPUTMESSAGE(uint8 *args) { LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PCHAR, pBuf); LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, cbMsg); LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, hfile); - return Dos16PutMessage(hfile, cbMsg, pBuf); + return DOSPUTMESSAGE(hfile, cbMsg, pBuf); +} + +static APIRET16 bridge16to32_DOSTRUEGETMESSAGE(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PVOID, msgseg); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, pcbMsg); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PCHAR, pFilename); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, msgnum); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, cbBuf); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PCHAR, pData); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, cTable); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PVOID, pTable); + return DOSTRUEGETMESSAGE(pTable, cTable, pData, cbBuf, msgnum, pFilename, pcbMsg, msgseg); } LX_NATIVE_MODULE_16BIT_SUPPORT() - LX_NATIVE_MODULE_16BIT_API(Dos16PutMessage) + LX_NATIVE_MODULE_16BIT_API(DOSPUTMESSAGE) + LX_NATIVE_MODULE_16BIT_API(DOSTRUEGETMESSAGE) LX_NATIVE_MODULE_16BIT_SUPPORT_END() LX_NATIVE_MODULE_DEINIT({ @@ -26,13 +39,15 @@ LX_NATIVE_MODULE_DEINIT({ static int init16_msg(void) { LX_NATIVE_MODULE_INIT_16BIT_SUPPORT() - LX_NATIVE_INIT_16BIT_BRIDGE(Dos16PutMessage, 8) + LX_NATIVE_INIT_16BIT_BRIDGE(DOSPUTMESSAGE, 8) + LX_NATIVE_INIT_16BIT_BRIDGE(DOSTRUEGETMESSAGE, 26) LX_NATIVE_MODULE_INIT_16BIT_SUPPORT_END() return 1; } LX_NATIVE_MODULE_INIT({ if (!init16_msg()) return 0; }) - LX_NATIVE_EXPORT16(Dos16PutMessage, 1), + LX_NATIVE_EXPORT16(DOSPUTMESSAGE, 1), + LX_NATIVE_EXPORT16(DOSTRUEGETMESSAGE, 2), LX_NATIVE_EXPORT(DosPutMessage, 5) LX_NATIVE_MODULE_INIT_END() diff --git a/native/msg.c b/native/msg.c index f921f2f..5e33386 100644 --- a/native/msg.c +++ b/native/msg.c @@ -21,7 +21,7 @@ APIRET DosPutMessage(HFILE handle, ULONG msglen, PCHAR msg) return NO_ERROR; } // DosPutMessage -APIRET16 Dos16PutMessage(USHORT handle, USHORT msglen, PCHAR msg) +APIRET16 DOSPUTMESSAGE(USHORT handle, USHORT msglen, PCHAR msg) { TRACE_NATIVE("Dos16PutMessage(%u, %u, %p)", (uint) handle, (uint) msglen, msg); FIXME("really implement this"); @@ -29,5 +29,46 @@ APIRET16 Dos16PutMessage(USHORT handle, USHORT msglen, PCHAR msg) return NO_ERROR; } // Dos16PutMessage +APIRET16 DOSTRUEGETMESSAGE(PVOID pTable, USHORT cTable, PCHAR pData, USHORT cbBuf, USHORT msgnum, PCHAR pFilename, PUSHORT pcbMsg, PVOID msgseg) +{ + TRACE_NATIVE("Dos16TrueGetMessage(%p, %u, %p, %u, %u, %p, %p, %p)", pTable, cTable, pData, cbBuf, msgnum, pFilename, pcbMsg, msgseg); + void *msgdat = msgseg; + int offset = *(uint16_t *)(msgdat + 14); + offset = *(uint16_t *)(msgdat + offset + 4); + int count = *(uint16_t *)(msgdat + offset + 3); + uint16_t *msgarr = (uint16_t *)(msgdat + offset + 5); + int i, j = 0; + for (i = 0; i < count; i++) + { + if(*(uint16_t *)(msgdat + msgarr[i]) == msgnum) + break; + } + if (i == count) return ERROR_MR_MID_NOT_FOUND; + int msglen = *(PUSHORT)(msgdat + msgarr[i] + 2); + char *substr, *msg = (char *)(msgdat + msgarr[i] + 4); + int sub; + if (msg[0] == 'E') + { + j = 8; + if (cbBuf > 8) + sprintf(pData, "SYS%04d:", msgnum); + } + for (i = 1; (i < msglen) && (j < cbBuf); i++, j++) + { + if (msg[i] == '%') + { + sub = msg[++i] - '1'; + if ((sub < 0) || (sub >= cTable)) return ERROR_MR_INV_MSGF_FORMAT; + substr = GLoaderState.convert1616to32(((uint32_t *)pTable)[sub]); + strcpy(&pData[j], substr); + j += strlen(substr) - 1; + } + else + pData[j] = msg[i]; + } + *pcbMsg = j; + return NO_ERROR; +} + // end of msg.c ... diff --git a/native/msg.h b/native/msg.h index 49cb6bb..1d529a8 100644 --- a/native/msg.h +++ b/native/msg.h @@ -15,7 +15,8 @@ extern "C" { #endif -OS2EXPORT APIRET16 OS2API16 Dos16PutMessage(USHORT hfile, USHORT cbMsg, PCHAR pBuf) OS2APIINFO(1); +OS2EXPORT APIRET16 OS2API16 DOSPUTMESSAGE(USHORT hfile, USHORT cbMsg, PCHAR pBuf) OS2APIINFO(1); +OS2EXPORT APIRET16 OS2API16 DOSTRUEGETMESSAGE(PVOID pTable, USHORT cTable, PCHAR pData, USHORT cbBuf, USHORT msgnum, PCHAR pFilename, PUSHORT pcbMsg, PVOID msgseg) OS2APIINFO(2); OS2EXPORT APIRET OS2API DosPutMessage(HFILE hfile, ULONG cbMsg, PCHAR pBuf) OS2APIINFO(5); #ifdef __cplusplus diff --git a/native/nls-lx.h b/native/nls-lx.h index 78e5756..aa8acb2 100644 --- a/native/nls-lx.h +++ b/native/nls-lx.h @@ -9,15 +9,32 @@ /* This is glue code for OS/2 binaries. Native binaries don't need this. */ #if LX_LEGACY -static APIRET16 bridge16to32_Dos16GetDBCSEv(uint8 *args) { +static APIRET16 bridge16to32_DOSGETDBCSEV(uint8 *args) { LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PCHAR, buf); LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PCOUNTRYCODE16, pcc); LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, buflen); - return Dos16GetDBCSEv(buflen, pcc, buf); + return DOSGETDBCSEV(buflen, pcc, buf); +} + +static APIRET16 bridge16to32_DOSCASEMAP(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PCHAR, pch); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PCOUNTRYCODE16, pcc); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, len); + return DOSCASEMAP(len, pcc, pch); +} + +static APIRET16 bridge16to32_DOSGETCTRYINFO(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PUSHORT, dlen); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PCOUNTRYINFO16, pch); + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PCOUNTRYCODE16, pcc); + LX_NATIVE_MODULE_16BIT_BRIDGE_ARG(USHORT, len); + return DOSGETCTRYINFO(len, pcc, pch, dlen); } LX_NATIVE_MODULE_16BIT_SUPPORT() - LX_NATIVE_MODULE_16BIT_API(Dos16GetDBCSEv) + LX_NATIVE_MODULE_16BIT_API(DOSGETDBCSEV) + LX_NATIVE_MODULE_16BIT_API(DOSCASEMAP) + LX_NATIVE_MODULE_16BIT_API(DOSGETCTRYINFO) LX_NATIVE_MODULE_16BIT_SUPPORT_END() LX_NATIVE_MODULE_DEINIT({ @@ -26,16 +43,20 @@ LX_NATIVE_MODULE_DEINIT({ static int init16_nls(void) { LX_NATIVE_MODULE_INIT_16BIT_SUPPORT() - LX_NATIVE_INIT_16BIT_BRIDGE(Dos16GetDBCSEv, 10) + LX_NATIVE_INIT_16BIT_BRIDGE(DOSGETDBCSEV, 10) + LX_NATIVE_INIT_16BIT_BRIDGE(DOSCASEMAP, 10) + LX_NATIVE_INIT_16BIT_BRIDGE(DOSGETCTRYINFO, 14) LX_NATIVE_MODULE_INIT_16BIT_SUPPORT_END() return 1; } LX_NATIVE_MODULE_INIT({ if (!init16_nls()) return 0; }) - LX_NATIVE_EXPORT16(Dos16GetDBCSEv, 4), + LX_NATIVE_EXPORT16(DOSGETDBCSEV, 4), LX_NATIVE_EXPORT(DosQueryCtryInfo, 5), LX_NATIVE_EXPORT(DosQueryDBCSEnv, 6), - LX_NATIVE_EXPORT(DosMapCase, 7) + LX_NATIVE_EXPORT(DosMapCase, 7), + LX_NATIVE_EXPORT16(DOSCASEMAP, 391), + LX_NATIVE_EXPORT16(DOSGETCTRYINFO, 393) LX_NATIVE_MODULE_INIT_END() #endif /* LX_LEGACY */ diff --git a/native/nls.c b/native/nls.c index f217b8d..34eee8d 100644 --- a/native/nls.c +++ b/native/nls.c @@ -11,7 +11,7 @@ #include "nls-lx.h" -APIRET16 Dos16GetDBCSEv(USHORT buflen, PCOUNTRYCODE16 pcc, PCHAR buf) +APIRET16 DOSGETDBCSEV(USHORT buflen, PCOUNTRYCODE16 pcc, PCHAR buf) { // !!! FIXME: implement this for real. TRACE_NATIVE("Dos16GetDBCSEv(%u, %p, %p)", (uint) buflen, pcc, buf); @@ -21,6 +21,33 @@ APIRET16 Dos16GetDBCSEv(USHORT buflen, PCOUNTRYCODE16 pcc, PCHAR buf) return NO_ERROR; } // Dos16GetDBCSEv +APIRET16 DOSCASEMAP(USHORT len, PCOUNTRYCODE16 pcc, PCHAR pch) +{ + TRACE_NATIVE("Dos16CaseMap(%u, %p, %p)", (uint) len, pcc, pch); + if (!pcc) return ERROR_INVALID_PARAMETER; + COUNTRYCODE cc = {pcc->country, pcc->codepage}; + APIRET16 ret = DosMapCase(len, &cc, pch); + pcc->country = cc.country; + pcc->codepage = cc.codepage; + return ret; +} + +APIRET16 DOSGETCTRYINFO(USHORT len, PCOUNTRYCODE16 pcc, PCOUNTRYINFO16 pch, PUSHORT dlen) +{ + TRACE_NATIVE("Dos16GetCtryInfo(%u, %p, %p)",len, pcc, pch); + if (!pcc || !pch || (len < 6)) return ERROR_INVALID_PARAMETER; + COUNTRYINFO ci; + COUNTRYCODE cc = {pcc->country, pcc->codepage}; + APIRET16 ret = DosQueryCtryInfo(sizeof(ci), &cc, &ci, NULL); + if (ret) return ret; + pch->country = ci.country; + pch->codepage = ci.codepage; + pch->fsDateFmt = ci.fsDateFmt; + memcpy(&pch->szCurrency, &ci.szCurrency, len - 6); + if (dlen) *dlen = sizeof(PCOUNTRYCODE16); + return NO_ERROR; +} + APIRET DosQueryDBCSEnv(ULONG buflen, PCOUNTRYCODE pcc, PCHAR buf) { // !!! FIXME: implement this for real. @@ -83,6 +110,8 @@ APIRET DosQueryCtryInfo(ULONG cb, PCOUNTRYCODE pcc, PCOUNTRYINFO pci, PULONG pcb if (pcbActual) *pcbActual = 38; // OS/2 Warp 4.52 doesn't count the abReserved[5] at the end. + memcpy(pci, &ci, cb); + return NO_ERROR; } // DosQueryCtryInfo diff --git a/native/nls.h b/native/nls.h index 1fb9cfa..e2c78eb 100644 --- a/native/nls.h +++ b/native/nls.h @@ -50,7 +50,27 @@ typedef struct USHORT codepage; } COUNTRYCODE16, *PCOUNTRYCODE16; -OS2EXPORT APIRET16 OS2API16 Dos16GetDBCSEv(USHORT buflen, PCOUNTRYCODE16 pcc, PCHAR buf) OS2APIINFO(4); +typedef struct +{ + USHORT country; + USHORT codepage; + USHORT fsDateFmt; + CHAR szCurrency[5]; + CHAR szThousandsSeparator[2]; + CHAR szDecimal[2]; + CHAR szDateSeparator[2]; + CHAR szTimeSeparator[2]; + UCHAR fsCurrencyFmt; + UCHAR cDecimalPlace; + UCHAR fsTimeFmt; + USHORT abReserved1[2]; + CHAR szDataSeparator[2]; + USHORT abReserved2[5]; +} COUNTRYINFO16, *PCOUNTRYINFO16; + +OS2EXPORT APIRET16 OS2API16 DOSGETDBCSEV(USHORT buflen, PCOUNTRYCODE16 pcc, PCHAR buf) OS2APIINFO(4); +OS2EXPORT APIRET16 OS2API16 DOSCASEMAP(USHORT len, PCOUNTRYCODE16 pcc, PCHAR pch) OS2APIINFO(391); +OS2EXPORT APIRET16 OS2API16 DOSGETCTRYINFO(USHORT len, PCOUNTRYCODE16 pcc, PCOUNTRYINFO16 pch, PUSHORT dlen) OS2APIINFO(393); #ifdef __cplusplus } diff --git a/native/os2types.h b/native/os2types.h index 52d294c..e4b7054 100644 --- a/native/os2types.h +++ b/native/os2types.h @@ -88,6 +88,9 @@ typedef SHANDLE HKBD, *PHKBD; typedef PCHAR PSZ; typedef PCHAR PCH; +typedef USHORT SEL; +typedef PUSHORT PSEL; + typedef int (APIENTRY *PFN)(void); typedef ULONG ERRORID; diff --git a/native/sesmgr-lx.h b/native/sesmgr-lx.h index aaf38ec..699500a 100644 --- a/native/sesmgr-lx.h +++ b/native/sesmgr-lx.h @@ -9,7 +9,28 @@ /* This is glue code for OS/2 binaries. Native binaries don't need this. */ #if LX_LEGACY -LX_NATIVE_MODULE_INIT() +static APIRET16 bridge16to32_Dos16SMSetTitle(uint8 *args) { + LX_NATIVE_MODULE_16BIT_BRIDGE_PTRARG(PCHAR, title); + return Dos16SMSetTitle(title); +} + +LX_NATIVE_MODULE_16BIT_SUPPORT() + LX_NATIVE_MODULE_16BIT_API(Dos16SMSetTitle) +LX_NATIVE_MODULE_16BIT_SUPPORT_END() + +LX_NATIVE_MODULE_DEINIT({ + LX_NATIVE_MODULE_DEINIT_16BIT_SUPPORT(); +}) + +static int init16_sesmgr(void) { + LX_NATIVE_MODULE_INIT_16BIT_SUPPORT() + LX_NATIVE_INIT_16BIT_BRIDGE(Dos16SMSetTitle, 4) + LX_NATIVE_MODULE_INIT_16BIT_SUPPORT_END() + return 1; +} + +LX_NATIVE_MODULE_INIT({ if (!init16_sesmgr()) return 0; }) + LX_NATIVE_EXPORT16_DIFFERENT_NAME(Dos16SMSetTitle, "DOSSMSETTITLE", 5), LX_NATIVE_EXPORT(DosStartSession, 37) LX_NATIVE_MODULE_INIT_END() diff --git a/native/sesmgr.c b/native/sesmgr.c index ae1fdee..c3c80cf 100644 --- a/native/sesmgr.c +++ b/native/sesmgr.c @@ -6,7 +6,7 @@ * This file written by Ryan C. Gordon. */ -#include "os2native.h" +#include "os2native16.h" #include "sesmgr.h" #include "sesmgr-lx.h" @@ -18,5 +18,11 @@ printf("'%s', '%s', '%s'\n", psd->PgmTitle, psd->PgmName, psd->IconFile); return ERROR_NOT_ENOUGH_MEMORY; } // DosStartSession +OS2EXPORT APIRET16 OS2API16 Dos16SMSetTitle(PCHAR title) +{ + TRACE_NATIVE("Dos16SMSetTitle(%p)", title); + return NO_ERROR; +} + // end of sesmgr.c ... diff --git a/native/sesmgr.h b/native/sesmgr.h index e64f27f..f1a8fcc 100644 --- a/native/sesmgr.h +++ b/native/sesmgr.h @@ -40,7 +40,8 @@ typedef struct ULONG ObjectBuffLen; } STARTDATA, *PSTARTDATA; -OS2EXPORT APIRET OS2API DosStartSession(PSTARTDATA psd, PULONG pidSession, PPID ppid) OS2APIINFO(37); +OS2EXPORT APIRET OS2API DosStartSession(PSTARTDATA psd, PULONG pidSession, PPID ppid) OS2APIINFO(ord=37); +OS2EXPORT APIRET16 OS2API16 Dos16SMSetTitle(PCHAR title) OS2APIINFO(ord=5,name=DOSSMSETTITLE); #ifdef __cplusplus } diff --git a/native/viocalls.c b/native/viocalls.c index 7b6e7ca..f9a0c1a 100644 --- a/native/viocalls.c +++ b/native/viocalls.c @@ -268,6 +268,7 @@ APIRET16 VioGetBuf(PULONG pLVB, PUSHORT pcbLVB, HVIO hvio) APIRET16 VioGetCurType(PVIOCURSORINFO pvioCursorInfo, HVIO hvio) { TRACE_NATIVE("VioGetCurType(%p, %u)", pvioCursorInfo, (uint) hvio); + return NO_ERROR; if (hvio != 0) return ERROR_VIO_INVALID_HANDLE; // !!! FIXME: can be non-zero when VioCreatePS() is implemented.