⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os2.c

📁 嵌入式环境下的GUI
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * OS/2 support routines for PhysicsFS. * * Please see the file LICENSE in the source's root directory. * *  This file written by Ryan C. Gordon. */#if HAVE_CONFIG_H#  include <config.h>#endif#if (defined OS2)#define INCL_DOSSEMAPHORES#define INCL_DOSDATETIME#define INCL_DOSFILEMGR#define INCL_DOSMODULEMGR#define INCL_DOSERRORS#define INCL_DOSPROCESS#define INCL_DOSDEVICES#define INCL_DOSDEVIOCTL#define INCL_DOSMISC#include <os2.h>#include <stdlib.h>#include <errno.h>#include <string.h>#include <time.h>#include <ctype.h>#define __PHYSICSFS_INTERNAL__#include "physfs_internal.h"const char *__PHYSFS_platformDirSeparator = "\\";static const char *get_os2_error_string(APIRET rc){    switch (rc)    {        case NO_ERROR: return(NULL);  /* not an error. */        case ERROR_INTERRUPT: return(NULL);  /* not an error. */        case ERROR_TIMEOUT: return(NULL);  /* not an error. */        case ERROR_NOT_ENOUGH_MEMORY: return(ERR_OUT_OF_MEMORY);        case ERROR_FILE_NOT_FOUND: return(ERR_NO_SUCH_FILE);        case ERROR_PATH_NOT_FOUND: return(ERR_NO_SUCH_PATH);        case ERROR_ACCESS_DENIED: return(ERR_ACCESS_DENIED);        case ERROR_NOT_DOS_DISK: return(ERR_NOT_A_DOS_DISK);        case ERROR_SHARING_VIOLATION: return(ERR_SHARING_VIOLATION);        case ERROR_CANNOT_MAKE: return(ERR_CANNOT_MAKE);        case ERROR_DEVICE_IN_USE: return(ERR_DEV_IN_USE);        case ERROR_OPEN_FAILED: return(ERR_OPEN_FAILED);        case ERROR_DISK_FULL: return(ERR_DISK_FULL);        case ERROR_PIPE_BUSY: return(ERR_PIPE_BUSY);        case ERROR_SHARING_BUFFER_EXCEEDED: return(ERR_SHARING_BUF_EXCEEDED);        case ERROR_FILENAME_EXCED_RANGE: return(ERR_BAD_FILENAME);        case ERROR_META_EXPANSION_TOO_LONG: return(ERR_BAD_FILENAME);        case ERROR_TOO_MANY_HANDLES: return(ERR_TOO_MANY_HANDLES);        case ERROR_TOO_MANY_OPEN_FILES: return(ERR_TOO_MANY_HANDLES);        case ERROR_NO_MORE_SEARCH_HANDLES: return(ERR_TOO_MANY_HANDLES);        case ERROR_SEEK_ON_DEVICE: return(ERR_SEEK_ERROR);        case ERROR_NEGATIVE_SEEK: return(ERR_SEEK_OUT_OF_RANGE);        case ERROR_DEL_CURRENT_DIRECTORY: return(ERR_DEL_CWD);        case ERROR_WRITE_PROTECT: return(ERR_WRITE_PROTECT_ERROR);        case ERROR_WRITE_FAULT: return(ERR_WRITE_FAULT);        case ERROR_LOCK_VIOLATION: return(ERR_LOCK_VIOLATION);        case ERROR_GEN_FAILURE: return(ERR_GENERAL_FAILURE);        case ERROR_UNCERTAIN_MEDIA: return(ERR_UNCERTAIN_MEDIA);        case ERROR_PROTECTION_VIOLATION: return(ERR_PROT_VIOLATION);        case ERROR_BROKEN_PIPE: return(ERR_BROKEN_PIPE);        case ERROR_INVALID_PARAMETER:        case ERROR_INVALID_NAME:        case ERROR_INVALID_DRIVE:        case ERROR_INVALID_HANDLE:        case ERROR_INVALID_FUNCTION:        case ERROR_INVALID_LEVEL:        case ERROR_INVALID_CATEGORY:        case ERROR_DUPLICATE_NAME:        case ERROR_BUFFER_OVERFLOW:        case ERROR_BAD_LENGTH:        case ERROR_BAD_DRIVER_LEVEL:        case ERROR_DIRECT_ACCESS_HANDLE:        case ERROR_NOT_OWNER:            return(ERR_PHYSFS_BAD_OS_CALL);        default: return(ERR_OS2_GENERIC);    } /* switch */    return(NULL);} /* get_os2_error_string */static APIRET os2err(APIRET retval){    char buf[128];    const char *err = get_os2_error_string(retval);    if (err == ERR_OS2_GENERIC)    {        snprintf(buf, ERR_OS2_GENERIC, (int) retval);        err = buf;    } /* if */    if (err != NULL)        __PHYSFS_setError(err);    return(err);} /* os2err *//* (be gentle, this function isn't very robust.) */static void cvt_path_to_correct_case(char *buf){    char *fname = buf + 3;            /* point to first element. */    char *ptr = strchr(fname, '\\');  /* find end of first element. */    buf[0] = toupper(buf[0]);  /* capitalize drive letter. */    /*     * Go through each path element, and enumerate its parent dir until     *  a case-insensitive match is found. If one is (and it SHOULD be)     *  then overwrite the original element with the correct case.     * If there's an error, or the path has vanished for some reason, it     *  won't hurt to have the original case, so we just keep going.     */    while (fname != NULL)    {        char spec[CCHMAXPATH];        FILEFINDBUF3 fb;        HDIR hdir = HDIR_CREATE;        ULONG count = 1;        APIRET rc;        *(fname - 1) = '\0';  /* isolate parent dir string. */        strcpy(spec, buf);      /* copy isolated parent dir... */        strcat(spec, "\\*.*");  /*  ...and add wildcard search spec. */        if (ptr != NULL)  /* isolate element to find (fname is the start). */            *ptr = '\0';        rc = DosFindFirst(spec, &hdir, FILE_DIRECTORY,                          &fb, sizeof (fb), &count, FIL_STANDARD);        if (rc == NO_ERROR)        {            while (count == 1)  /* while still entries to enumerate... */            {                if (__PHYSFS_platformStricmp(fb.achName, fname) == 0)                {                    strcpy(fname, fb.achName);                    break;  /* there it is. Overwrite and stop searching. */                } /* if */                DosFindNext(hdir, &fb, sizeof (fb), &count);            } /* while */            DosFindClose(hdir);        } /* if */        *(fname - 1) = '\\';   /* unisolate parent dir. */        fname = ptr;           /* point to next element. */        if (ptr != NULL)        {            *ptr = '\\';       /* unisolate element. */            ptr = strchr(++fname, '\\');  /* find next element. */        } /* if */    } /* while */} /* cvt_file_to_correct_case */static char *baseDir = NULL;int __PHYSFS_platformInit(void){    char buf[CCHMAXPATH];    APIRET rc;    PTIB ptib;    PPIB ppib;    PHYSFS_sint32 len;    assert(baseDir == NULL);    BAIL_IF_MACRO(os2err(DosGetInfoBlocks(&ptib, &ppib)) != NO_ERROR, NULL, 0);    rc = DosQueryModuleName(ppib->pib_hmte, sizeof (buf), (PCHAR) buf);    BAIL_IF_MACRO(os2err(rc) != NO_ERROR, NULL, 0);    /* chop off filename, leave path. */    for (len = strlen(buf) - 1; len >= 0; len--)    {        if (buf[len] == '\\')        {            buf[len] = '\0';            break;        } /* if */    } /* for */    assert(len > 0);  /* should have been a "x:\\" on the front on string. */    /* The string is capitalized! Figure out the REAL case... */    cvt_path_to_correct_case(buf);    baseDir = (char *) malloc(len + 1);    BAIL_IF_MACRO(baseDir == NULL, ERR_OUT_OF_MEMORY, 0);    strcpy(baseDir, buf);    return(1);  /* success. */} /* __PHYSFS_platformInit */int __PHYSFS_platformDeinit(void){    assert(baseDir != NULL);    free(baseDir);    baseDir = NULL;    return(1);  /* success. */} /* __PHYSFS_platformDeinit */static int disc_is_inserted(ULONG drive){    int rc;    char buf[20];    DosError(FERR_DISABLEHARDERR | FERR_DISABLEEXCEPTION);    rc = DosQueryFSInfo(drive + 1, FSIL_VOLSER, buf, sizeof (buf));    DosError(FERR_ENABLEHARDERR | FERR_ENABLEEXCEPTION);    return(rc == NO_ERROR);} /* is_cdrom_inserted *//* looks like "CD01" in ASCII (littleendian)...used for an ioctl. */#define CD01 0x31304443static int is_cdrom_drive(ULONG drive){    PHYSFS_uint32 param, data;    ULONG ul1, ul2;    APIRET rc;    HFILE hfile = NULLHANDLE;    char drivename[3] = { 'A' + drive, ':', '\0' };    rc = DosOpen(drivename, &hfile, &ul1, 0, 0,                 OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_FAIL_IF_NEW,                 OPEN_FLAGS_DASD | OPEN_FLAGS_FAIL_ON_ERROR |                 OPEN_FLAGS_NOINHERIT | OPEN_SHARE_DENYNONE, NULL);    BAIL_IF_MACRO(rc != NO_ERROR, NULL, 0);    data = 0;    param = PHYSFS_swapULE32(CD01);    ul1 = ul2 = sizeof (PHYSFS_uint32);    rc = DosDevIOCtl(hfile, IOCTL_CDROMDISK, CDROMDISK_GETDRIVER,                     &param, sizeof (param), &ul1, &data, sizeof (data), &ul2);    DosClose(hfile);    return((rc == NO_ERROR) && (PHYSFS_swapULE32(data) == CD01));} /* is_cdrom_drive */char **__PHYSFS_platformDetectAvailableCDs(void){    ULONG dummy;    ULONG drivemap;    ULONG i, bit;    APIRET rc;    char **retval;    PHYSFS_uint32 cd_count = 1;   /* we count the NULL entry. */    retval = (char **) malloc(sizeof (char *));    BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);    *retval = NULL;    rc = DosQueryCurrentDisk(&dummy, &drivemap);    BAIL_IF_MACRO(os2err(rc) != NO_ERROR, NULL, retval);    for (i = 0, bit = 1; i < 26; i++, bit <<= 1)    {        if (drivemap & bit)  /* this logical drive exists. */        {            if ((is_cdrom_drive(i)) && (disc_is_inserted(i)))            {                char **tmp = realloc(retval, sizeof (char *) * (cd_count + 1));                if (tmp)                {                    char *str = (char *) malloc(4);                    retval = tmp;                    retval[cd_count - 1] = str;                    if (str)                    {                        str[0] = ('A' + i);                        str[1] = ':';                        str[2] = '\\';                        str[3] = '\0';                        cd_count++;                    } /* if */                } /* if */            } /* if */        } /* if */    } /* for */    retval[cd_count - 1] = NULL;    return(retval);} /* __PHYSFS_platformDetectAvailableCDs */char *__PHYSFS_platformCalcBaseDir(const char *argv0){    char *retval = (char *) malloc(strlen(baseDir) + 1);    BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);    strcpy(retval, baseDir); /* calculated at init time. */    return(retval);} /* __PHYSFS_platformCalcBaseDir */char *__PHYSFS_platformGetUserName(void){    return(NULL);  /* (*shrug*) */} /* __PHYSFS_platformGetUserName */char *__PHYSFS_platformGetUserDir(void){    return(__PHYSFS_platformCalcBaseDir(NULL));} /* __PHYSFS_platformGetUserDir */int __PHYSFS_platformStricmp(const char *x, const char *y){    int ux, uy;    do    {        ux = toupper((int) *x);        uy = toupper((int) *y);        if (ux > uy)            return(1);        else if (ux < uy)            return(-1);        x++;        y++;    } while ((ux) && (uy));    return(0);} /* __PHYSFS_platformStricmp */int __PHYSFS_platformExists(const char *fname){    FILESTATUS3 fs;    APIRET rc = DosQueryPathInfo(fname, FIL_STANDARD, &fs, sizeof (fs));    return(os2err(rc) == NO_ERROR);} /* __PHYSFS_platformExists */int __PHYSFS_platformIsSymLink(const char *fname){    return(0);  /* no symlinks in OS/2. */} /* __PHYSFS_platformIsSymlink */int __PHYSFS_platformIsDirectory(const char *fname){    FILESTATUS3 fs;    APIRET rc = DosQueryPathInfo(fname, FIL_STANDARD, &fs, sizeof (fs));    BAIL_IF_MACRO(os2err(rc) != NO_ERROR, NULL, 0)    return((fs.attrFile & FILE_DIRECTORY) != 0);} /* __PHYSFS_platformIsDirectory */char *__PHYSFS_platformCvtToDependent(const char *prepend,                                      const char *dirName,                                      const char *append)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -