diff --git a/native/doscalls.c b/native/doscalls.c index 5594ac8..4c60ed6 100644 --- a/native/doscalls.c +++ b/native/doscalls.c @@ -197,6 +197,7 @@ LX_NATIVE_MODULE_INIT({ if (!initDoscalls(lx_state)) return NULL; }) LX_NATIVE_EXPORT(DosQueryModuleHandle, 319), LX_NATIVE_EXPORT(DosQueryModuleName, 320), LX_NATIVE_EXPORT(DosQueryProcAddr, 321), + LX_NATIVE_EXPORT(DosQueryAppType, 323), LX_NATIVE_EXPORT(DosCreateEventSem, 324), LX_NATIVE_EXPORT(DosCloseEventSem, 326), LX_NATIVE_EXPORT(DosResetEventSem, 327), @@ -2612,5 +2613,83 @@ APIRET OS2API DosResetBuffer(HFILE hFile) return resetOneBuffer(fd); } // DosResetBuffer +APIRET DosQueryAppType(PSZ pszName, PULONG pFlags) +{ + TRACE_NATIVE("DosQueryAppType('%s', %p)", pszName, pFlags); + + if (!pFlags) + return ERROR_INVALID_PARAMETER; + + APIRET err = NO_ERROR; + char *path = makeUnixPath(pszName, &err); + if (!path) + return err; + + const int fd = open(path, O_RDONLY, 0); + free(path); + if (fd == -1) { + switch (errno) { // !!! FIXME: copy/paste, put this in a function. + case EACCES: return ERROR_ACCESS_DENIED; + case EISDIR: return ERROR_ACCESS_DENIED; + case EMFILE: return ERROR_TOO_MANY_OPEN_FILES; + case ENFILE: return ERROR_TOO_MANY_OPEN_FILES; + case ENAMETOOLONG: return ERROR_FILENAME_EXCED_RANGE; + case ENOSPC: return ERROR_DISK_FULL; + case ENOMEM: return ERROR_NOT_ENOUGH_MEMORY; + case ENOENT: return ERROR_FILE_NOT_FOUND; // !!! FIXME: could be PATH_NOT_FOUND too, depending on circumstances. + case ENOTDIR: return ERROR_PATH_NOT_FOUND; + case EPERM: return ERROR_ACCESS_DENIED; + case EROFS: return ERROR_ACCESS_DENIED; + case ETXTBSY: return ERROR_ACCESS_DENIED; + default: break; + } // switch + return ERROR_OPEN_FAILED; // !!! FIXME: debug logging about missing errno case. + } // if + + // !!! FIXME: I guess we should parse NE/LE files here too? + + uint32 lxoffset = 0; + LxHeader lx; + uint8 mz[2]; + if (read(fd, mz, 2) != 2) goto queryapptype_iofailed; + if ((mz[0] != 'M') || (mz[1] != 'Z')) goto queryapptype_iofailed; + if (lseek(fd, 0x3C, SEEK_SET) == -1) goto queryapptype_iofailed; + if (read(fd, &lxoffset, sizeof (lxoffset)) != sizeof (lxoffset)) goto queryapptype_iofailed; + if (lseek(fd, lxoffset, SEEK_SET) == -1) goto queryapptype_iofailed; + if (read(fd, &lx, sizeof (lx)) != sizeof (lx)) goto queryapptype_iofailed; + close(fd); + + if ((lx.magic_l != 'L') || (lx.magic_x != 'X')) return ERROR_INVALID_EXE_SIGNATURE; + if (lx.module_flags & 0x2000) return ERROR_EXE_MARKED_INVALID; // "not loadable" ... I guess this is it? + + const uint32 module_type = lx.module_flags & 0x00038000; + + ULONG flags = 0; + + // !!! FIXME: can you be both compat and incompat? + if (lx.module_flags & 0x100) flags |= FAPPTYP_NOTWINDOWCOMPAT; + if (lx.module_flags & 0x200) flags |= FAPPTYP_WINDOWCOMPAT; + if (lx.module_flags & 0x300) flags |= FAPPTYP_WINDOWAPI; + // !!! FIXME: FAPPTYP_BOUND = 0x0008 + if (module_type & 0x8000) flags |= FAPPTYP_DLL; + if (module_type & 0x20000) flags |= FAPPTYP_PHYSDRV; + if (module_type & 0x28000) flags |= FAPPTYP_VIRTDRV; + if (module_type & 0x18000) flags |= FAPPTYP_PROTDLL; + + // !!! FIXME: FAPPTYP_DOS = 0x0020 + // !!! FIXME: FAPPTYP_WINDOWSREAL = 0x0200 + // !!! FIXME: FAPPTYP_WINDOWSPROT = 0x0400 + // !!! FIXME: FAPPTYP_WINDOWSPROT31 =0x1000 + + flags |= FAPPTYP_32BIT; // !!! FIXME: currently always true. + + return NO_ERROR; + +queryapptype_iofailed: + close(fd); + return ERROR_INVALID_EXE_SIGNATURE; +} // DosQueryAppType + + // end of doscalls.c ... diff --git a/native/doscalls.h b/native/doscalls.h index 393b54d..9798db3 100644 --- a/native/doscalls.h +++ b/native/doscalls.h @@ -353,6 +353,24 @@ enum DEVINFO_ADAPTER }; +enum +{ + FAPPTYP_NOTSPEC = 0x0000, + FAPPTYP_NOTWINDOWCOMPAT = 0x0001, + FAPPTYP_WINDOWCOMPAT = 0x0002, + FAPPTYP_WINDOWAPI = 0x0003, + FAPPTYP_BOUND = 0x0008, + FAPPTYP_DLL = 0x0010, + FAPPTYP_DOS = 0x0020, + FAPPTYP_PHYSDRV = 0x0040, + FAPPTYP_VIRTDRV = 0x0080, + FAPPTYP_PROTDLL = 0x0100, + FAPPTYP_WINDOWSREAL = 0x0200, + FAPPTYP_WINDOWSPROT = 0x0400, + FAPPTYP_WINDOWSPROT31 =0x1000, + FAPPTYP_32BIT = 0x4000 +}; + // !!! FIXME: these should probably get sorted alphabetically and/or grouped // !!! FIXME: into areas of functionality, but for now, I'm just listing them @@ -413,6 +431,7 @@ APIRET OS2API DosQueryCurrentDisk(PULONG pdisknum, PULONG plogical); APIRET OS2API DosDevConfig(PVOID pdevinfo, ULONG item); APIRET OS2API DosLoadModule(PSZ pszName, ULONG cbName, PSZ pszModname, PHMODULE phmod); APIRET OS2API DosResetBuffer(HFILE hFile); +APIRET OS2API DosQueryAppType(PSZ pszName, PULONG pFlags); #ifdef __cplusplus }