[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[paragui-cvs] CVS: paragui/src/physfs/platform macclassic.c,NONE,1.1 ske
From: |
Alexander Pipelka <address@hidden> |
Subject: |
[paragui-cvs] CVS: paragui/src/physfs/platform macclassic.c,NONE,1.1 skeleton.c,NONE,1.1 Makefile.am,1.1.1.1,1.2 unix.c,1.1.1.1,1.2 win32.c,1.1.1.1,1.2 |
Date: |
Sat, 27 Apr 2002 12:06:29 -0400 |
Update of /cvsroot/paragui/paragui/src/physfs/platform
In directory subversions:/tmp/cvs-serv12415/src/physfs/platform
Modified Files:
Makefile.am unix.c win32.c
Added Files:
macclassic.c skeleton.c
Log Message:
updated physfs to version 0.1.5
--- NEW FILE ---
/*
* MacOS Classic support routines for PhysicsFS.
*
* Please see the file LICENSE in the source's root directory.
*
* This file written by Ryan C. Gordon.
*/
#include <stdlib.h>
#include <string.h>
#include <alloca.h>
/*
* Most of the API calls in here are, according to ADC, available since
* MacOS 8.1. I don't think I used any MacOS 9 or CarbonLib-specific
* functions. There might be one or two 8.5 calls, and perhaps when the
* ADC docs say "Available in MacOS 8.1" they really mean "this works
* with System 6, but we don't want to hear about it at this point."
*
* IsAliasFile() showed up in MacOS 8.5. You can duplicate this code with
* PBGetCatInfoSync(), which is an older API, if you hope the bits in the
* catalog info never change (which they won't for, say, MacOS 8.1).
* See Apple Technote FL-30:
* http://developer.apple.com/technotes/fl/fl_30.html
*
* If you want to use weak pointers and Gestalt, and choose the correct
* code to use during __PHYSFS_platformInit(), I'll accept a patch, but
* chances are, it wasn't worth the time it took to write this, let alone
* implement that.
*/
/*
* Please note that I haven't tried this code with CarbonLib or under
* MacOS X at all. The code in unix.c is known to work with Darwin,
* and you may or may not be better off using that, especially since
* mutexes are no-ops in this file. Patches welcome.
*/
#ifdef __PHYSFS_CARBONIZED__ /* this is currently not defined anywhere. */
#include <Carbon.h>
#else
#include <OSUtils.h>
#include <Processes.h>
#include <Files.h>
#include <TextUtils.h>
#include <Resources.h>
#include <MacMemory.h>
#include <Events.h>
#include <DriverGestalt.h>
#include <Aliases.h>
#endif
#define __PHYSICSFS_INTERNAL__
#include "physfs_internal.h"
const char *__PHYSFS_platformDirSeparator = ":";
static struct ProcessInfoRec procInfo;
static FSSpec procfsspec;
int __PHYSFS_platformInit(void)
{
OSErr err;
ProcessSerialNumber psn;
BAIL_IF_MACRO(GetCurrentProcess(&psn) != noErr, ERR_OS_ERROR, 0);
memset(&procInfo, '\0', sizeof (ProcessInfoRec));
memset(&procfsspec, '\0', sizeof (FSSpec));
procInfo.processInfoLength = sizeof (ProcessInfoRec);
procInfo.processAppSpec = &procfsspec;
err = GetProcessInformation(&psn, &procInfo);
BAIL_IF_MACRO(err != noErr, ERR_OS_ERROR, 0);
return(1); /* we're golden. */
} /* __PHYSFS_platformInit */
int __PHYSFS_platformDeinit(void)
{
return(1); /* always succeed. */
} /* __PHYSFS_platformDeinit */
/*
* CD detection code is borrowed from Apple Technical Q&A DV18.
* http://developer.apple.com/qa/dv/dv18.html
*/
char **__PHYSFS_platformDetectAvailableCDs(void)
{
DriverGestaltParam pb;
DrvQEl *dqp;
OSErr status;
char **retval = (char **) malloc(sizeof (char *));
int cd_count = 1;
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
*retval = NULL;
pb.csCode = kDriverGestaltCode;
pb.driverGestaltSelector = kdgDeviceType;
dqp = (DrvQEl *) GetDrvQHdr()->qHead;
while (dqp != NULL)
{
pb.ioCRefNum = dqp->dQRefNum;
pb.ioVRefNum = dqp->dQDrive;
status = PBStatusSync((ParmBlkPtr) &pb);
if ((status == noErr) && (pb.driverGestaltResponse == kdgCDType))
{
Str63 volName;
HParamBlockRec hpbr;
memset(&hpbr, '\0', sizeof (HParamBlockRec));
hpbr.volumeParam.ioNamePtr = volName;
hpbr.volumeParam.ioVRefNum = dqp->dQDrive;
hpbr.volumeParam.ioVolIndex = 0;
if (PBHGetVInfoSync(&hpbr) == noErr)
{
char **tmp = realloc(retval, sizeof (char *) * cd_count + 1);
if (tmp)
{
char *str = (char *) malloc(volName[0] + 1);
retval = tmp;
if (str != NULL)
{
memcpy(str, &volName[1], volName[0]);
str[volName[0]] = '\0';
retval[cd_count-1] = str;
cd_count++;
} /* if */
} /* if */
} /* if */
} /* if */
dqp = (DrvQEl *) dqp->qLink;
} /* while */
retval[cd_count - 1] = NULL;
return(retval);
} /* __PHYSFS_platformDetectAvailableCDs */
static char *convFSSpecToPath(FSSpec *spec, int includeFile)
{
char *ptr;
char *retval = NULL;
UInt32 retLength = 0;
CInfoPBRec infoPB;
Str255 str255;
str255[0] = spec->name[0];
memcpy(&str255[1], &spec->name[1], str255[0]);
memset(&infoPB, '\0', sizeof (CInfoPBRec));
infoPB.dirInfo.ioNamePtr = str255; /* put name in here. */
infoPB.dirInfo.ioVRefNum = spec->vRefNum; /* ID of bin's volume. */
infoPB.dirInfo.ioDrParID = spec->parID; /* ID of bin's dir. */
infoPB.dirInfo.ioFDirIndex = (includeFile) ? 0 : -1;
/* walk the tree back to the root dir (volume), building path string... */
do
{
/* check parent dir of what we last looked at... */
infoPB.dirInfo.ioDrDirID = infoPB.dirInfo.ioDrParID;
if (PBGetCatInfoSync(&infoPB) != noErr)
{
if (retval != NULL)
free(retval);
BAIL_MACRO(ERR_OS_ERROR, NULL);
} /* if */
infoPB.dirInfo.ioFDirIndex = -1; /* look at parent dir next time. */
/* allocate more space for the retval... */
retLength += str255[0] + 1; /* + 1 for a ':' or null char... */
ptr = (char *) malloc(retLength);
if (ptr == NULL)
{
if (retval != NULL)
free(retval);
BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
} /* if */
/* prepend new dir to retval and cleanup... */
memcpy(ptr, &str255[1], str255[0]);
ptr[str255[0]] = '\0'; /* null terminate it. */
if (retval != NULL)
{
strcat(ptr, ":");
strcat(ptr, retval);
free(retval);
} /* if */
retval = ptr;
} while (infoPB.dirInfo.ioDrDirID != fsRtDirID);
return(retval);
} /* convFSSpecToPath */
char *__PHYSFS_platformCalcBaseDir(const char *argv0)
{
FSSpec spec;
/* Get the name of the binary's parent directory. */
FSMakeFSSpec(procfsspec.vRefNum, procfsspec.parID, procfsspec.name, &spec);
return(convFSSpecToPath(&spec, 0));
} /* __PHYSFS_platformCalcBaseDir */
char *__PHYSFS_platformGetUserName(void)
{
char *retval = NULL;
StringHandle strHandle;
short origResourceFile = CurResFile();
/* use the System resource file. */
UseResFile(0);
/* apparently, -16096 specifies the username. */
strHandle = GetString(-16096);
UseResFile(origResourceFile);
BAIL_IF_MACRO(strHandle == NULL, ERR_OS_ERROR, NULL);
HLock((Handle) strHandle);
retval = (char *) malloc((*strHandle)[0] + 1);
if (retval == NULL)
{
HUnlock((Handle) strHandle);
BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
} /* if */
memcpy(retval, &(*strHandle)[1], (*strHandle)[0]);
retval[(*strHandle)[0]] = '\0'; /* null-terminate it. */
HUnlock((Handle) strHandle);
return(retval);
} /* __PHYSFS_platformGetUserName */
char *__PHYSFS_platformGetUserDir(void)
{
#if 0
return(NULL); /* bah...use default behaviour, I guess. */
#else
/* (Hmm. Default behaviour is broken in the base library. :) ) */
return(__PHYSFS_platformCalcBaseDir(NULL));
#endif
} /* __PHYSFS_platformGetUserDir */
PHYSFS_uint64 __PHYSFS_platformGetThreadID(void)
{
return(1); /* single threaded. */
} /* __PHYSFS_platformGetThreadID */
int __PHYSFS_platformStricmp(const char *x, const char *y)
{
extern int _stricmp(const char *, const char *);
return(_stricmp(x, y)); /* (*shrug*) */
} /* __PHYSFS_platformStricmp */
static OSErr fnameToFSSpecNoAlias(const char *fname, FSSpec *spec)
{
OSErr err;
Str255 str255;
int needColon = (strchr(fname, ':') == NULL);
int len = strlen(fname) + ((needColon) ? 1 : 0);
if (len > 255)
return(bdNamErr);
/* !!! FIXME: What happens with relative pathnames? */
str255[0] = len;
memcpy(&str255[1], fname, len);
/* probably just a volume name, which seems to need a ':' at the end. */
if (needColon)
str255[len] = ':';
err = FSMakeFSSpec(0, 0, str255, spec);
return(err);
} /* fnameToFSSpecNoAlias */
/* !!! FIXME: This code is pretty heinous. */
static OSErr fnameToFSSpec(const char *fname, FSSpec *spec)
{
Boolean alias = 0;
Boolean folder = 0;
OSErr err = fnameToFSSpecNoAlias(fname, spec);
if (err == dirNFErr) /* might be an alias in the middle of the path. */
{
/*
* Has to be at least two ':' chars, or we wouldn't get a
* dir-not-found condition. (no ':' means it was just a volume,
* just one ':' means we would have gotten a fnfErr, if anything.
*/
char *ptr;
char *start;
char *path = alloca(strlen(fname) + 1);
strcpy(path, fname);
ptr = strchr(path, ':');
BAIL_IF_MACRO(!ptr, ERR_FILE_NOT_FOUND, err); /* just in case */
ptr = strchr(ptr + 1, ':');
BAIL_IF_MACRO(!ptr, ERR_FILE_NOT_FOUND, err); /* just in case */
*ptr = '\0';
err = fnameToFSSpecNoAlias(path, spec); /* get first dir. */
BAIL_IF_MACRO(err != noErr, ERR_OS_ERROR, err);
start = ptr;
ptr = strchr(start + 1, ':');
do
{
CInfoPBRec infoPB;
memset(&infoPB, '\0', sizeof (CInfoPBRec));
infoPB.dirInfo.ioNamePtr = spec->name;
infoPB.dirInfo.ioVRefNum = spec->vRefNum;
infoPB.dirInfo.ioDrDirID = spec->parID;
infoPB.dirInfo.ioFDirIndex = 0;
err = PBGetCatInfoSync(&infoPB);
if (err != noErr) /* not an alias, really a bogus path. */
return(fnameToFSSpecNoAlias(fname, spec)); /* reset */
if ((infoPB.dirInfo.ioFlAttrib & kioFlAttribDirMask) != 0)
spec->parID = infoPB.dirInfo.ioDrDirID;
if (ptr != NULL)
*ptr = '\0';
*start = strlen(start + 1); /* make it a pstring. */
err = FSMakeFSSpec(spec->vRefNum, spec->parID,
(const unsigned char *) start, spec);
if (err != noErr) /* not an alias, really a bogus path. */
return(fnameToFSSpecNoAlias(fname, spec)); /* reset */
err = ResolveAliasFileWithMountFlags(spec, 1, &folder, &alias, 0);
if (err != noErr) /* not an alias, really a bogus path. */
return(fnameToFSSpecNoAlias(fname, spec)); /* reset */
start = ptr;
if (ptr != NULL)
ptr = strchr(start + 1, ':');
} while (start != NULL);
} /* if */
else /* there's something there; make sure final file is not an alias. */
{
BAIL_IF_MACRO(err != noErr, ERR_OS_ERROR, err);
err = ResolveAliasFileWithMountFlags(spec, 1, &folder, &alias, 0);
BAIL_IF_MACRO(err != noErr, ERR_OS_ERROR, err);
} /* else */
return(noErr); /* w00t. */
} /* fnameToFSSpec */
int __PHYSFS_platformExists(const char *fname)
{
FSSpec spec;
return(fnameToFSSpec(fname, &spec) == noErr);
} /* __PHYSFS_platformExists */
int __PHYSFS_platformIsSymLink(const char *fname)
{
OSErr err;
FSSpec spec;
Boolean a = 0;
Boolean f = 0;
CInfoPBRec infoPB;
char *ptr;
char *dir = alloca(strlen(fname) + 1);
BAIL_IF_MACRO(dir == NULL, ERR_OUT_OF_MEMORY, 0);
strcpy(dir, fname);
ptr = strrchr(dir, ':');
if (ptr == NULL) /* just a volume name? Can't be a symlink. */
return(0);
/* resolve aliases up to the actual file... */
*ptr = '\0';
BAIL_IF_MACRO(fnameToFSSpec(dir, &spec) != noErr, ERR_OS_ERROR, 0);
*ptr = strlen(ptr + 1); /* ptr is now a pascal string. Yikes! */
memset(&infoPB, '\0', sizeof (CInfoPBRec));
infoPB.dirInfo.ioNamePtr = spec.name;
infoPB.dirInfo.ioVRefNum = spec.vRefNum;
infoPB.dirInfo.ioDrDirID = spec.parID;
infoPB.dirInfo.ioFDirIndex = 0;
BAIL_IF_MACRO(PBGetCatInfoSync(&infoPB) != noErr, ERR_OS_ERROR, 0);
err = FSMakeFSSpec(spec.vRefNum, infoPB.dirInfo.ioDrDirID,
(const unsigned char *) ptr, &spec);
BAIL_IF_MACRO(err != noErr, ERR_OS_ERROR, 0);
BAIL_IF_MACRO(IsAliasFile(&spec, &a, &f) != noErr, ERR_OS_ERROR, 0);
return(a);
} /* __PHYSFS_platformIsSymlink */
int __PHYSFS_platformIsDirectory(const char *fname)
{
FSSpec spec;
CInfoPBRec infoPB;
OSErr err;
BAIL_IF_MACRO(fnameToFSSpec(fname, &spec) != noErr, ERR_OS_ERROR, 0);
memset(&infoPB, '\0', sizeof (CInfoPBRec));
infoPB.dirInfo.ioNamePtr = spec.name; /* put name in here. */
infoPB.dirInfo.ioVRefNum = spec.vRefNum; /* ID of file's volume. */
infoPB.dirInfo.ioDrDirID = spec.parID; /* ID of bin's dir. */
infoPB.dirInfo.ioFDirIndex = 0; /* file (not parent) info. */
err = PBGetCatInfoSync(&infoPB);
BAIL_IF_MACRO(err != noErr, ERR_OS_ERROR, 0);
return((infoPB.dirInfo.ioFlAttrib & kioFlAttribDirMask) != 0);
} /* __PHYSFS_platformIsDirectory */
char *__PHYSFS_platformCvtToDependent(const char *prepend,
const char *dirName,
const char *append)
{
int len = ((prepend) ? strlen(prepend) : 0) +
((append) ? strlen(append) : 0) +
strlen(dirName) + 1;
const char *src;
char *dst;
char *retval = malloc(len);
BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
if (prepend != NULL)
{
strcpy(retval, prepend);
dst = retval + strlen(retval);
} /* if */
else
{
*retval = '\0';
dst = retval;
} /* else */
for (src = dirName; *src; src++, dst++)
*dst = ((*src == '/') ? ':' : *src);
*dst = '\0';
return(retval);
} /* __PHYSFS_platformCvtToDependent */
void __PHYSFS_platformTimeslice(void)
{
SystemTask();
} /* __PHYSFS_platformTimeslice */
LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
int omitSymLinks)
{
LinkedStringList *retval = NULL;
LinkedStringList *l = NULL;
LinkedStringList *prev = NULL;
UInt16 i;
UInt16 max;
FSSpec spec;
CInfoPBRec infoPB;
Str255 str255;
long dirID;
BAIL_IF_MACRO(fnameToFSSpec(dirname, &spec) != noErr, ERR_OS_ERROR, 0);
/* get the dir ID of what we want to enumerate... */
memset(&infoPB, '\0', sizeof (CInfoPBRec));
infoPB.dirInfo.ioNamePtr = spec.name; /* name of dir to enum. */
infoPB.dirInfo.ioVRefNum = spec.vRefNum; /* ID of file's volume. */
infoPB.dirInfo.ioDrDirID = spec.parID; /* ID of dir. */
infoPB.dirInfo.ioFDirIndex = 0; /* file (not parent) info. */
BAIL_IF_MACRO(PBGetCatInfoSync(&infoPB) != noErr, ERR_OS_ERROR, NULL);
if ((infoPB.dirInfo.ioFlAttrib & kioFlAttribDirMask) == 0)
BAIL_MACRO(ERR_NOT_A_DIR, NULL);
dirID = infoPB.dirInfo.ioDrDirID;
max = infoPB.dirInfo.ioDrNmFls;
for (i = 1; i <= max; i++)
{
FSSpec aliasspec;
Boolean alias = 0;
Boolean folder = 0;
memset(&infoPB, '\0', sizeof (CInfoPBRec));
str255[0] = 0;
infoPB.dirInfo.ioNamePtr = str255; /* store name in here. */
infoPB.dirInfo.ioVRefNum = spec.vRefNum; /* ID of dir's volume. */
infoPB.dirInfo.ioDrDirID = dirID; /* ID of dir. */
infoPB.dirInfo.ioFDirIndex = i; /* next file's info. */
if (PBGetCatInfoSync(&infoPB) != noErr)
continue; /* skip this file. Oh well. */
if (FSMakeFSSpec(spec.vRefNum, dirID, str255, &aliasspec) != noErr)
continue; /* skip it. */
if (IsAliasFile(&aliasspec, &alias, &folder) != noErr)
continue; /* skip it. */
if ((alias) && (omitSymLinks))
continue;
/* still here? Add it to the list. */
l = (LinkedStringList *) malloc(sizeof (LinkedStringList));
if (l == NULL)
break;
l->str = (char *) malloc(str255[0] + 1);
if (l->str == NULL)
{
free(l);
break;
} /* if */
memcpy(l->str, &str255[1], str255[0]);
l->str[str255[0]] = '\0';
if (retval == NULL)
retval = l;
else
prev->next = l;
prev = l;
l->next = NULL;
} /* for */
return(retval);
} /* __PHYSFS_platformEnumerateFiles */
char *__PHYSFS_platformCurrentDir(void)
{
/*
* I don't think MacOS has a concept of "current directory", beyond
* what is grafted on by a given standard C library implementation,
* so just return the base dir.
* We don't use this for anything crucial at the moment anyhow.
*/
return(__PHYSFS_platformCalcBaseDir(NULL));
} /* __PHYSFS_platformCurrentDir */
char *__PHYSFS_platformRealPath(const char *path)
{
/*
* fnameToFSSpec() will resolve any symlinks to get to the real
* file's FSSpec, which, when converted, will contain the real
* direct path to a given file. convFSSpecToPath() mallocs a
* return value buffer.
*/
FSSpec spec;
BAIL_IF_MACRO(fnameToFSSpec(path, &spec) != noErr, ERR_OS_ERROR, NULL);
return(convFSSpecToPath(&spec, 1));
} /* __PHYSFS_platformRealPath */
int __PHYSFS_platformMkDir(const char *path)
{
SInt32 val = 0;
FSSpec spec;
OSErr err = fnameToFSSpec(path, &spec);
BAIL_IF_MACRO(err == noErr, ERR_FILE_EXISTS, 0);
BAIL_IF_MACRO(err != fnfErr, ERR_OS_ERROR, 0);
err = DirCreate(spec.vRefNum, spec.parID, spec.name, &val);
BAIL_IF_MACRO(err != noErr, ERR_OS_ERROR, 0);
return(1);
} /* __PHYSFS_platformMkDir */
static SInt16 *macDoOpen(const char *fname, SInt8 perm, int createIfMissing)
{
int created = 0;
SInt16 *retval = NULL;
FSSpec spec;
OSErr err = fnameToFSSpec(fname, &spec);
BAIL_IF_MACRO((err != noErr) && (err != fnfErr), ERR_OS_ERROR, NULL);
if (err == fnfErr)
{
BAIL_IF_MACRO(!createIfMissing, ERR_FILE_NOT_FOUND, NULL);
err = HCreate(spec.vRefNum, spec.parID, spec.name,
procInfo.processSignature, 'BINA');
BAIL_IF_MACRO(err != noErr, ERR_OS_ERROR, NULL);
created = 1;
} /* if */
retval = (SInt16 *) malloc(sizeof (SInt16));
if (retval == NULL)
{
if (created)
HDelete(spec.vRefNum, spec.parID, spec.name);
BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
} /* if */
if (HOpenDF(spec.vRefNum, spec.parID, spec.name, perm, retval) != noErr)
{
free(retval);
if (created)
HDelete(spec.vRefNum, spec.parID, spec.name);
BAIL_MACRO(ERR_OS_ERROR, NULL);
} /* if */
return(retval);
} /* macDoOpen */
void *__PHYSFS_platformOpenRead(const char *filename)
{
SInt16 *retval = macDoOpen(filename, fsRdPerm, 0);
if (retval != NULL) /* got a file; seek to start. */
{
if (SetFPos(*retval, fsFromStart, 0) != noErr)
{
FSClose(*retval);
BAIL_MACRO(ERR_OS_ERROR, NULL);
} /* if */
} /* if */
return((void *) retval);
} /* __PHYSFS_platformOpenRead */
void *__PHYSFS_platformOpenWrite(const char *filename)
{
SInt16 *retval = macDoOpen(filename, fsRdWrPerm, 1);
if (retval != NULL) /* got a file; truncate it. */
{
if ((SetEOF(*retval, 0) != noErr) ||
(SetFPos(*retval, fsFromStart, 0) != noErr))
{
FSClose(*retval);
BAIL_MACRO(ERR_OS_ERROR, NULL);
} /* if */
} /* if */
return((void *) retval);
} /* __PHYSFS_platformOpenWrite */
void *__PHYSFS_platformOpenAppend(const char *filename)
{
SInt16 *retval = macDoOpen(filename, fsRdWrPerm, 1);
if (retval != NULL) /* got a file; seek to end. */
{
if (SetFPos(*retval, fsFromLEOF, 0) != noErr)
{
FSClose(*retval);
BAIL_MACRO(ERR_OS_ERROR, NULL);
} /* if */
} /* if */
return(retval);
} /* __PHYSFS_platformOpenAppend */
PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buffer,
PHYSFS_uint32 size, PHYSFS_uint32 count)
{
SInt16 ref = *((SInt16 *) opaque);
SInt32 br;
PHYSFS_uint32 i;
for (i = 0; i < count; i++)
{
br = size;
BAIL_IF_MACRO(FSRead(ref, &br, buffer) != noErr, ERR_OS_ERROR, i);
BAIL_IF_MACRO(br != size, ERR_OS_ERROR, i);
buffer = ((PHYSFS_uint8 *) buffer) + size;
} /* for */
return(count);
} /* __PHYSFS_platformRead */
PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
PHYSFS_uint32 size, PHYSFS_uint32 count)
{
SInt16 ref = *((SInt16 *) opaque);
SInt32 bw;
PHYSFS_uint32 i;
for (i = 0; i < count; i++)
{
bw = size;
BAIL_IF_MACRO(FSWrite(ref, &bw, buffer) != noErr, ERR_OS_ERROR, i);
BAIL_IF_MACRO(bw != size, ERR_OS_ERROR, i);
buffer = ((PHYSFS_uint8 *) buffer) + size;
} /* for */
return(count);
} /* __PHYSFS_platformWrite */
int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos)
{
SInt16 ref = *((SInt16 *) opaque);
OSErr err = SetFPos(ref, fsFromStart, (SInt32) pos);
BAIL_IF_MACRO(err != noErr, ERR_OS_ERROR, 0);
return(1);
} /* __PHYSFS_platformSeek */
PHYSFS_sint64 __PHYSFS_platformTell(void *opaque)
{
SInt16 ref = *((SInt16 *) opaque);
SInt32 curPos;
BAIL_IF_MACRO(GetFPos(ref, &curPos) != noErr, ERR_OS_ERROR, -1);
return((PHYSFS_sint64) curPos);
} /* __PHYSFS_platformTell */
PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque)
{
SInt16 ref = *((SInt16 *) opaque);
SInt32 eofPos;
BAIL_IF_MACRO(GetEOF(ref, &eofPos) != noErr, ERR_OS_ERROR, -1);
return((PHYSFS_sint64) eofPos);
} /* __PHYSFS_platformFileLength */
int __PHYSFS_platformEOF(void *opaque)
{
SInt16 ref = *((SInt16 *) opaque);
SInt32 eofPos, curPos;
BAIL_IF_MACRO(GetEOF(ref, &eofPos) != noErr, ERR_OS_ERROR, 1);
BAIL_IF_MACRO(GetFPos(ref, &curPos) != noErr, ERR_OS_ERROR, 1);
return(curPos >= eofPos);
} /* __PHYSFS_platformEOF */
int __PHYSFS_platformFlush(void *opaque)
{
SInt16 ref = *((SInt16 *) opaque);
ParamBlockRec pb;
memset(&pb, '\0', sizeof (ParamBlockRec));
pb.ioParam.ioRefNum = ref;
BAIL_IF_MACRO(PBFlushFileSync(&pb) != noErr, ERR_OS_ERROR, 0);
return(1);
} /* __PHYSFS_platformFlush */
int __PHYSFS_platformClose(void *opaque)
{
SInt16 ref = *((SInt16 *) opaque);
SInt16 vRefNum;
HParamBlockRec hpbr;
Str63 volName;
BAIL_IF_MACRO(GetVRefNum (ref, &vRefNum) != noErr, ERR_OS_ERROR, 0);
memset(&hpbr, '\0', sizeof (HParamBlockRec));
hpbr.volumeParam.ioNamePtr = volName;
hpbr.volumeParam.ioVRefNum = vRefNum;
hpbr.volumeParam.ioVolIndex = 0;
BAIL_IF_MACRO(PBHGetVInfoSync(&hpbr) != noErr, ERR_OS_ERROR, 0);
BAIL_IF_MACRO(FSClose(ref) != noErr, ERR_OS_ERROR, 0);
free(opaque);
FlushVol(volName, vRefNum);
return(1);
} /* __PHYSFS_platformClose */
int __PHYSFS_platformDelete(const char *path)
{
FSSpec spec;
OSErr err;
BAIL_IF_MACRO(fnameToFSSpec(path, &spec) != noErr, ERR_OS_ERROR, 0);
err = HDelete(spec.vRefNum, spec.parID, spec.name);
BAIL_IF_MACRO(err != noErr, ERR_OS_ERROR, 0);
return(1);
} /* __PHYSFS_platformDelete */
void *__PHYSFS_platformCreateMutex(void)
{
return((void *) 0x0001); /* no mutexes on MacOS Classic. */
} /* __PHYSFS_platformCreateMutex */
void __PHYSFS_platformDestroyMutex(void *mutex)
{
/* no mutexes on MacOS Classic. */
} /* __PHYSFS_platformDestroyMutex */
int __PHYSFS_platformGrabMutex(void *mutex)
{
return(1); /* no mutexes on MacOS Classic. */
} /* __PHYSFS_platformGrabMutex */
void __PHYSFS_platformReleaseMutex(void *mutex)
{
/* no mutexes on MacOS Classic. */
} /* __PHYSFS_platformReleaseMutex */
/* end of macclassic.c ... */
--- NEW FILE ---
/*
* Skeleton platform-dependent support routines for PhysicsFS.
*
* Please see the file LICENSE in the source's root directory.
*
* This file written by Ryan C. Gordon.
*/
#define __PHYSICSFS_INTERNAL__
#include "physfs_internal.h"
#error DO NOT COMPILE THIS. IT IS JUST A SKELETON EXAMPLE FILE.
const char *__PHYSFS_platformDirSeparator = ":";
int __PHYSFS_platformInit(void)
{
return(1); /* always succeed. */
} /* __PHYSFS_platformInit */
int __PHYSFS_platformDeinit(void)
{
return(1); /* always succeed. */
} /* __PHYSFS_platformDeinit */
char **__PHYSFS_platformDetectAvailableCDs(void)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL);
} /* __PHYSFS_platformDetectAvailableCDs */
char *__PHYSFS_platformCalcBaseDir(const char *argv0)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL);
} /* __PHYSFS_platformCalcBaseDir */
char *__PHYSFS_platformGetUserName(void)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL);
} /* __PHYSFS_platformGetUserName */
char *__PHYSFS_platformGetUserDir(void)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL);
} /* __PHYSFS_platformGetUserDir */
PHYSFS_uint64 __PHYSFS_platformGetThreadID(void)
{
return(1); /* single threaded. */
} /* __PHYSFS_platformGetThreadID */
int __PHYSFS_platformStricmp(const char *x, const char *y)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, 0);
} /* __PHYSFS_platformStricmp */
int __PHYSFS_platformExists(const char *fname)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, 0);
} /* __PHYSFS_platformExists */
int __PHYSFS_platformIsSymLink(const char *fname)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, 0);
} /* __PHYSFS_platformIsSymlink */
int __PHYSFS_platformIsDirectory(const char *fname)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, 0);
} /* __PHYSFS_platformIsDirectory */
char *__PHYSFS_platformCvtToDependent(const char *prepend,
const char *dirName,
const char *append)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL);
} /* __PHYSFS_platformCvtToDependent */
void __PHYSFS_platformTimeslice(void)
{
} /* __PHYSFS_platformTimeslice */
LinkedStringList *__PHYSFS_platformEnumerateFiles(const char *dirname,
int omitSymLinks)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL);
} /* __PHYSFS_platformEnumerateFiles */
char *__PHYSFS_platformCurrentDir(void)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL);
} /* __PHYSFS_platformCurrentDir */
char *__PHYSFS_platformRealPath(const char *path)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL);
} /* __PHYSFS_platformRealPath */
int __PHYSFS_platformMkDir(const char *path)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, 0);
} /* __PHYSFS_platformMkDir */
void *__PHYSFS_platformOpenRead(const char *filename)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL);
} /* __PHYSFS_platformOpenRead */
void *__PHYSFS_platformOpenWrite(const char *filename)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL);
} /* __PHYSFS_platformOpenWrite */
void *__PHYSFS_platformOpenAppend(const char *filename)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL);
} /* __PHYSFS_platformOpenAppend */
PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buffer,
PHYSFS_uint32 size, PHYSFS_uint32 count)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, -1);
} /* __PHYSFS_platformRead */
PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
PHYSFS_uint32 size, PHYSFS_uint32 count)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, -1);
} /* __PHYSFS_platformWrite */
int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, -1);
} /* __PHYSFS_platformSeek */
PHYSFS_sint64 __PHYSFS_platformTell(void *opaque)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, -1);
} /* __PHYSFS_platformTell */
PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, -1);
} /* __PHYSFS_platformFileLength */
int __PHYSFS_platformEOF(void *opaque)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, -1);
} /* __PHYSFS_platformEOF */
int __PHYSFS_platformFlush(void *opaque)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, 0);
} /* __PHYSFS_platformFlush */
int __PHYSFS_platformClose(void *opaque)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, 0);
} /* __PHYSFS_platformClose */
int __PHYSFS_platformDelete(const char *path)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, 0);
} /* __PHYSFS_platformDelete */
void *__PHYSFS_platformCreateMutex(void)
{
BAIL_MACRO(ERR_NOT_IMPLEMENTED, NULL);
} /* __PHYSFS_platformCreateMutex */
void __PHYSFS_platformDestroyMutex(void *mutex)
{
} /* __PHYSFS_platformDestroyMutex */
int __PHYSFS_platformGrabMutex(void *mutex)
{
/* not implemented, but can't call __PHYSFS_setError! */
return(0);
} /* __PHYSFS_platformGrabMutex */
void __PHYSFS_platformReleaseMutex(void *mutex)
{
/* not implemented, but can't call __PHYSFS_setError! */
} /* __PHYSFS_platformReleaseMutex */
/* end of skeleton.c ... */
Index: Makefile.am
===================================================================
RCS file: /cvsroot/paragui/paragui/src/physfs/platform/Makefile.am,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -r1.1.1.1 -r1.2
*** Makefile.am 15 Apr 2002 13:22:14 -0000 1.1.1.1
--- Makefile.am 27 Apr 2002 16:06:26 -0000 1.2
***************
*** 1,6 ****
--- 1,9 ----
EXTRA_DIST = \
beos.c \
+ darwin.c \
freebsd.c \
irix.c \
+ macclassic.c \
+ skeleton.c \
solaris.c \
unix.c \
Index: unix.c
===================================================================
RCS file: /cvsroot/paragui/paragui/src/physfs/platform/unix.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -r1.1.1.1 -r1.2
*** unix.c 15 Apr 2002 13:22:14 -0000 1.1.1.1
--- unix.c 27 Apr 2002 16:06:26 -0000 1.2
***************
*** 7,10 ****
--- 7,16 ----
*/
+ #if ((defined __APPLE__) && (defined __MACH__))
+ # if (!defined __DARWIN__)
+ # define __DARWIN__
+ # endif
+ #endif
+
#if (defined __STRICT_ANSI__)
#define __PHYSFS_DOING_STRICT_ANSI__
***************
*** 40,44 ****
--- 46,58 ----
#include <time.h>
#include <errno.h>
+
+ #if (!defined __DARWIN__)
#include <mntent.h>
+ #else
+ #include <sys/ucred.h>
+ #endif
+
+ #include <sys/mount.h>
+
#define __PHYSICSFS_INTERNAL__
***************
*** 48,51 ****
--- 62,129 ----
const char *__PHYSFS_platformDirSeparator = "/";
+
+ int __PHYSFS_platformInit(void)
+ {
+ return(1); /* always succeed. */
+ } /* __PHYSFS_platformInit */
+
+
+ int __PHYSFS_platformDeinit(void)
+ {
+ return(1); /* always succeed. */
+ } /* __PHYSFS_platformDeinit */
+
+
+
+ #if (defined __DARWIN__)
+
+ char **__PHYSFS_platformDetectAvailableCDs(void)
+ {
+ char **retval = (char **) malloc(sizeof (char *));
+ int cd_count = 1; /* We count the NULL entry. */
+ struct statfs* mntbufp = NULL;
+ int mounts;
+ int ii;
+
+ BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
+
+ mounts = getmntinfo( &mntbufp, MNT_WAIT );
+
+ for ( ii=0; ii < mounts; ++ii ) {
+ int add_it = 0;
+
+ if ( strcmp( mntbufp[ii].f_fstypename, "iso9660") == 0 )
+ add_it = 1;
+ else if ( strcmp( mntbufp[ii].f_fstypename, "cd9660") == 0 )
+ add_it = 1;
+ /* !!! other mount types? */
+
+ if (add_it)
+ {
+ char **tmp = realloc(retval, sizeof (char *) * cd_count + 1);
+ if (tmp)
+ {
+ retval = tmp;
+ retval[cd_count-1] = (char *)
+ malloc(strlen(mntbufp[ ii ].f_mntonname) + 1);
+ if (retval[cd_count-1])
+ {
+ strcpy(retval[cd_count-1], mntbufp[ ii ].f_mntonname);
+ cd_count++;
+ } /* if */
+ } /* if */
+ } /* if */
+ }
+
+ free( mntbufp );
+
+ retval[cd_count - 1] = NULL;
+ return(retval);
+ } /* __PHYSFS_platformDetectAvailableCDs */
+
+
+ #else /* non-Darwin implementation... */
+
+
char **__PHYSFS_platformDetectAvailableCDs(void)
{
***************
*** 55,58 ****
--- 133,138 ----
struct mntent *ent = NULL;
+ BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
+
*retval = NULL;
mounts = setmntent("/etc/mtab", "r");
***************
*** 86,90 ****
retval[cd_count - 1] = NULL;
return(retval);
! } /* __PHYSFS_detectAvailableCDs */
--- 166,172 ----
retval[cd_count - 1] = NULL;
return(retval);
! } /* __PHYSFS_platformDetectAvailableCDs */
!
! #endif
***************
*** 210,216 ****
! int __PHYSFS_platformGetThreadID(void)
{
! return((int) pthread_self());
} /* __PHYSFS_platformGetThreadID */
--- 292,298 ----
! PHYSFS_uint64 __PHYSFS_platformGetThreadID(void)
{
! return((PHYSFS_uint64) ((PHYSFS_uint32) pthread_self()));
} /* __PHYSFS_platformGetThreadID */
***************
*** 310,317 ****
void __PHYSFS_platformTimeslice(void)
{
! struct timespec napTime;
! napTime.tv_sec = 0;
! napTime.tv_nsec = 10 * 1000 * 1000; /* specified in nanoseconds. */
! nanosleep(&napTime, NULL); /* don't care if it fails. */
} /* __PHYSFS_platformTimeslice */
--- 392,396 ----
void __PHYSFS_platformTimeslice(void)
{
! usleep( 10 * 1000 ); /* don't care if it fails. */
} /* __PHYSFS_platformTimeslice */
***************
*** 412,424 ****
- int __PHYSFS_platformFileLength(FILE *handle)
- {
- struct stat statbuf;
- errno = 0;
- BAIL_IF_MACRO(fstat(fileno(handle), &statbuf) == -1, strerror(errno), -1);
- return(statbuf.st_size);
- } /* __PHYSFS_platformFileLength */
-
-
char *__PHYSFS_platformCurrentDir(void)
{
--- 491,494 ----
***************
*** 435,452 ****
if (retval != NULL)
free(retval);
! BAIL_IF_MACRO(1, ERR_OUT_OF_MEMORY, NULL);
} /* if */
!
retval = ptr;
ptr = getcwd(retval, allocSize);
} while (ptr == NULL && errno == ERANGE);
! if(ptr == NULL && errno) {
! /* getcwd() failed for some reason, for example current
! * directory not existing.
! */
! if (retval != NULL)
! free(retval);
! BAIL_IF_MACRO(1, ERR_NO_SUCH_FILE, NULL);
! }
return(retval);
} /* __PHYSFS_platformCurrentDir */
--- 505,526 ----
if (retval != NULL)
free(retval);
! BAIL_MACRO(ERR_OUT_OF_MEMORY, NULL);
} /* if */
!
retval = ptr;
ptr = getcwd(retval, allocSize);
} while (ptr == NULL && errno == ERANGE);
!
! if (ptr == NULL && errno)
! {
! /*
! * getcwd() failed for some reason, for example current
! * directory not existing.
! */
! if (retval != NULL)
! free(retval);
! BAIL_MACRO(ERR_NO_SUCH_FILE, NULL);
! } /* if */
!
return(retval);
} /* __PHYSFS_platformCurrentDir */
***************
*** 475,478 ****
--- 549,707 ----
return(1);
} /* __PHYSFS_platformMkDir */
+
+
+ static void *doOpen(const char *filename, const char *mode)
+ {
+ FILE *retval;
+ errno = 0;
+
+ retval = fopen(filename, mode);
+ if (retval == NULL)
+ __PHYSFS_setError(strerror(errno));
+
+ return((void *) retval);
+ } /* doOpen */
+
+
+ void *__PHYSFS_platformOpenRead(const char *filename)
+ {
+ return(doOpen(filename, "rb"));
+ } /* __PHYSFS_platformOpenRead */
+
+
+ void *__PHYSFS_platformOpenWrite(const char *filename)
+ {
+ return(doOpen(filename, "wb"));
+ } /* __PHYSFS_platformOpenWrite */
+
+
+ void *__PHYSFS_platformOpenAppend(const char *filename)
+ {
+ return(doOpen(filename, "wb+"));
+ } /* __PHYSFS_platformOpenAppend */
+
+
+ PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buffer,
+ PHYSFS_uint32 size, PHYSFS_uint32 count)
+ {
+ FILE *io = (FILE *) opaque;
+ int rc = fread(buffer, size, count, io);
+ if (rc < count)
+ {
+ int err = errno;
+ BAIL_IF_MACRO(ferror(io), strerror(err), rc);
+ BAIL_MACRO(ERR_PAST_EOF, rc);
+ } /* if */
+
+ return(rc);
+ } /* __PHYSFS_platformRead */
+
+
+ PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buffer,
+ PHYSFS_uint32 size, PHYSFS_uint32 count)
+ {
+ FILE *io = (FILE *) opaque;
+ int rc = fwrite((void *) buffer, size, count, io);
+ if (rc < count)
+ __PHYSFS_setError(strerror(errno));
+
+ return(rc);
+ } /* __PHYSFS_platformWrite */
+
+
+ int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos)
+ {
+ FILE *io = (FILE *) opaque;
+
+ /* !!! FIXME: Use llseek where available. */
+ errno = 0;
+ BAIL_IF_MACRO(fseek(io, pos, SEEK_SET) != 0, strerror(errno), 0);
+
+ return(1);
+ } /* __PHYSFS_platformSeek */
+
+
+ PHYSFS_sint64 __PHYSFS_platformTell(void *opaque)
+ {
+ FILE *io = (FILE *) opaque;
+ PHYSFS_sint64 retval = ftell(io);
+ BAIL_IF_MACRO(retval == -1, strerror(errno), -1);
+ return(retval);
+ } /* __PHYSFS_platformTell */
+
+
+ PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque)
+ {
+ FILE *io = (FILE *) opaque;
+ struct stat statbuf;
+ errno = 0;
+ BAIL_IF_MACRO(fstat(fileno(io), &statbuf) == -1, strerror(errno), -1);
+ return((PHYSFS_sint64) statbuf.st_size);
+ } /* __PHYSFS_platformFileLength */
+
+
+ int __PHYSFS_platformEOF(void *opaque)
+ {
+ return(feof((FILE *) opaque));
+ } /* __PHYSFS_platformEOF */
+
+
+ int __PHYSFS_platformFlush(void *opaque)
+ {
+ errno = 0;
+ BAIL_IF_MACRO(fflush((FILE *) opaque) == EOF, strerror(errno), 0);
+ return(1);
+ } /* __PHYSFS_platformFlush */
+
+
+ int __PHYSFS_platformClose(void *opaque)
+ {
+ errno = 0;
+ BAIL_IF_MACRO(fclose((FILE *) opaque) == EOF, strerror(errno), 0);
+ return(1);
+ } /* __PHYSFS_platformClose */
+
+
+ int __PHYSFS_platformDelete(const char *path)
+ {
+ errno = 0;
+ BAIL_IF_MACRO(remove(path) == -1, strerror(errno), 0);
+ return(1);
+ } /* __PHYSFS_platformDelete */
+
+
+ void *__PHYSFS_platformCreateMutex(void)
+ {
+ int rc;
+ pthread_mutex_t *m = (pthread_mutex_t *) malloc(sizeof (pthread_mutex_t));
+ BAIL_IF_MACRO(m == NULL, ERR_OUT_OF_MEMORY, NULL);
+ rc = pthread_mutex_init(m, NULL);
+ if (rc != 0)
+ {
+ free(m);
+ BAIL_MACRO(strerror(rc), NULL);
+ } /* if */
+
+ return((void *) m);
+ } /* __PHYSFS_platformCreateMutex */
+
+
+ void __PHYSFS_platformDestroyMutex(void *mutex)
+ {
+ pthread_mutex_destroy((pthread_mutex_t *) mutex);
+ free(mutex);
+ } /* __PHYSFS_platformDestroyMutex */
+
+
+ int __PHYSFS_platformGrabMutex(void *mutex)
+ {
+ return(pthread_mutex_lock((pthread_mutex_t *) mutex) == 0);
+ } /* __PHYSFS_platformGrabMutex */
+
+
+ void __PHYSFS_platformReleaseMutex(void *mutex)
+ {
+ pthread_mutex_unlock((pthread_mutex_t *) mutex);
+ } /* __PHYSFS_platformReleaseMutex */
/* end of unix.c ... */
Index: win32.c
===================================================================
RCS file: /cvsroot/paragui/paragui/src/physfs/platform/win32.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -r1.1.1.1 -r1.2
*** win32.c 15 Apr 2002 13:22:14 -0000 1.1.1.1
--- win32.c 27 Apr 2002 16:06:26 -0000 1.2
***************
*** 4,15 ****
* Please see the file LICENSE in the source's root directory.
*
! * This file written by Ryan C. Gordon.
*/
- #if (defined __STRICT_ANSI__)
- #define __PHYSFS_DOING_STRICT_ANSI__
- #endif
-
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
--- 4,12 ----
* Please see the file LICENSE in the source's root directory.
*
! * This file written by Ryan C. Gordon, and made sane by Gregory S. Read.
*/
#include <windows.h>
+ #include <userenv.h>
#include <stdio.h>
#include <stdlib.h>
***************
*** 19,25 ****
--- 16,32 ----
#include "physfs_internal.h"
+ #define LOWORDER_UINT64(pos) (PHYSFS_uint32)(pos & 0x00000000FFFFFFFF)
+ #define HIGHORDER_UINT64(pos) (PHYSFS_uint32)(pos & 0xFFFFFFFF00000000)
const char *__PHYSFS_platformDirSeparator = "\\";
+ static HANDLE ProcessHandle = NULL; /* Current process handle */
+ static HANDLE AccessTokenHandle = NULL; /* Security handle to process */
+ static DWORD ProcessID; /* ID assigned to current process */
+ static int runningNT; /* TRUE if NT derived OS */
+ static OSVERSIONINFO OSVersionInfo; /* Information about the OS */
+
+ /* NT specific information */
+ static char *ProfileDirectory = NULL; /* User profile folder */
static const char *win32strerror(void)
***************
*** 52,55 ****
--- 59,65 ----
if (GetDriveType(drive_str) == DRIVE_CDROM)
{
+
+ /* !!! FIXME: Make sure there's really a disc in the drive? */
+
char **tmp = realloc(retval, sizeof (char *) * cd_count + 1);
if (tmp)
***************
*** 71,85 ****
! char *__PHYSFS_platformCalcBaseDir(const char *argv0)
{
- DWORD buflen = 0;
- char *retval = NULL;
char *filepart = NULL;
!
! if (strchr(argv0, '\\') != NULL) /* default behaviour can handle this.
*/
! return(NULL);
!
! retval = (char *) malloc(sizeof (TCHAR) * (MAX_PATH + 1));
! buflen = GetModuleFileName(NULL, retval, MAX_PATH + 1);
retval[buflen] = '\0'; /* does API always null-terminate the string? */
--- 81,89 ----
! static char *getExePath(const char *argv0)
{
char *filepart = NULL;
! char *retval = (char *) malloc(sizeof (TCHAR) * (MAX_PATH + 1));
! DWORD buflen = GetModuleFileName(NULL, retval, MAX_PATH + 1);
retval[buflen] = '\0'; /* does API always null-terminate the string? */
***************
*** 106,109 ****
--- 110,122 ----
return(retval);
+ } /* getExePath */
+
+
+ char *__PHYSFS_platformCalcBaseDir(const char *argv0)
+ {
+ if (strchr(argv0, '\\') != NULL) /* default behaviour can handle this.
*/
+ return(NULL);
+
+ return(getExePath(argv0));
} /* __PHYSFS_platformCalcBaseDir */
***************
*** 129,180 ****
- static char *copyEnvironmentVariable(const char *varname)
- {
- const char *envr = getenv(varname);
- char *retval = NULL;
-
- if (envr != NULL)
- {
- retval = malloc(strlen(envr) + 1);
- if (retval != NULL)
- strcpy(retval, envr);
- } /* if */
-
- return(retval);
- } /* copyEnvironmentVariable */
-
-
char *__PHYSFS_platformGetUserDir(void)
{
! char *home = copyEnvironmentVariable("HOME");
! const char *homedrive = getenv("HOMEDRIVE");
! const char *homepath = getenv("HOMEPATH");
! if (home != NULL)
! return(home);
!
! if ((homedrive != NULL) && (homepath != NULL))
{
! char *retval = (char *) malloc(strlen(homedrive)+strlen(homepath)+2);
! if (retval != NULL)
! {
! strcpy(retval, homedrive);
! if ((homepath[0] != '\\') &&
! (homedrive[strlen(homedrive)-1] != '\\'))
! {
! strcat(retval, "\\");
! } /* if */
! strcat(retval, homepath);
! return(retval);
! } /* if */
! } /* if */
! return(NULL);
} /* __PHYSFS_platformGetUserDir */
! int __PHYSFS_platformGetThreadID(void)
{
! return((int) GetCurrentThreadId());
} /* __PHYSFS_platformGetThreadID */
--- 142,165 ----
char *__PHYSFS_platformGetUserDir(void)
{
! char *userdir = NULL;
! if (runningNT)
{
! userdir = ProfileDirectory;
! }
! else
! {
! /*!!!TODO - Need to return something for Win9x/ME */
! }
! return userdir;
} /* __PHYSFS_platformGetUserDir */
! PHYSFS_uint64 __PHYSFS_platformGetThreadID(void)
{
! return((PHYSFS_uint64)GetCurrentThreadId());
} /* __PHYSFS_platformGetThreadID */
***************
*** 183,186 ****
--- 168,174 ----
int __PHYSFS_platformStricmp(const char *x, const char *y)
{
+ #if (defined _MSC_VER)
+ return(stricmp(x, y));
+ #else
int ux, uy;
***************
*** 198,201 ****
--- 186,190 ----
return(0);
+ #endif
} /* __PHYSFS_platformStricmp */
***************
*** 267,271 ****
BAIL_IF_MACRO(dir == INVALID_HANDLE_VALUE, win32strerror(), NULL);
! for (; FindNextFile(dir, &ent) != 0; )
{
if (strcmp(ent.cFileName, ".") == 0)
--- 256,260 ----
BAIL_IF_MACRO(dir == INVALID_HANDLE_VALUE, win32strerror(), NULL);
! while (FindNextFile(dir, &ent) != 0)
{
if (strcmp(ent.cFileName, ".") == 0)
***************
*** 302,318 ****
- int __PHYSFS_platformFileLength(FILE *handle)
- {
- fpos_t curpos;
- int retval;
-
- fgetpos(handle, &curpos);
- fseek(handle, 0, SEEK_END);
- retval = ftell(handle);
- fsetpos(handle, &curpos);
- return(retval);
- } /* __PHYSFS_platformFileLength */
-
-
char *__PHYSFS_platformCurrentDir(void)
{
--- 291,294 ----
***************
*** 349,356 ****
*/
if ((path[0] == '\\') && (path[1] == '\\'))
- {
- BAIL_IF_MACRO(retval == NULL, ERR_OUT_OF_MEMORY, NULL);
strcpy(retval, path);
- } /* if */
else
--- 325,329 ----
***************
*** 462,465 ****
--- 435,878 ----
return(1);
} /* __PHYSFS_platformMkDir */
+
+ /*
+ * Initialize any NT specific stuff. This includes any OS based on NT.
+ *
+ * Return zero if there was a catastrophic failure and non-zero otherwise.
+ */
+ static int doNTInit(void)
+ {
+ DWORD pathsize = 0;
+ char TempProfileDirectory[1];
+
+ /* Create a process access token handle */
+ if(!OpenProcessToken(ProcessHandle, TOKEN_QUERY, &AccessTokenHandle))
+ {
+ /* Access token is required by other win32 functions */
+ return 0;
+ }
+
+ /* Should fail. Will write the size of the profile path in pathsize*/
+ /*!!! Second parameter can't be NULL or the function fails??? */
+ if(!GetUserProfileDirectory(AccessTokenHandle, TempProfileDirectory,
&pathsize))
+ {
+ /* Allocate memory for the profile directory */
+ ProfileDirectory = (char *)malloc(pathsize);
+ BAIL_IF_MACRO(ProfileDirectory == NULL, ERR_OUT_OF_MEMORY, 0);
+ /* Try to get the profile directory */
+ if(!GetUserProfileDirectory(AccessTokenHandle, ProfileDirectory,
&pathsize))
+ {
+ free(ProfileDirectory);
+ return 0;
+ }
+ }
+
+ /* Everything initialized okay */
+ return 1;
+ }
+
+ /*
+ * Get OS info and save it.
+ *
+ * Returns non-zero if successful, otherwise it returns zero on failure.
+ */
+ int getOSInfo(void)
+ {
+ /* Get OS info */
+ OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVersionInfo);
+ if(!GetVersionEx(&OSVersionInfo))
+ {
+ return 0;
+ }
+
+ /* Set to TRUE if we are runnign a WinNT based OS 4.0 or greater */
+ runningNT = (OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
+ (OSVersionInfo.dwMajorVersion > 3);
+
+ return 1;
+ }
+
+ int __PHYSFS_platformInit(void)
+ {
+ if(!getOSInfo())
+ {
+ return 0;
+ }
+
+ /* Get Windows ProcessID associated with the current process */
+ ProcessID = GetCurrentProcessId();
+ /* Create a process handle associated with the current process ID */
+ ProcessHandle = GetCurrentProcess();
+
+ if(ProcessHandle == NULL)
+ {
+ /* Process handle is required by other win32 functions */
+ return 0;
+ }
+
+ /* If running an NT system (NT/Win2k/XP, etc...) */
+ if(runningNT)
+ {
+ if(!doNTInit())
+ {
+ /* Error initializing NT stuff */
+ return 0;
+ }
+ }
+
+ /* It's all good */
+ return 1;
+ }
+
+ /*
+ * Uninitialize any NT specific stuff done in doNTInit().
+ *
+ * Return zero if there was a catastrophic failure and non-zero otherwise.
+ */
+ static int doNTDeinit(void)
+ {
+ if(CloseHandle(AccessTokenHandle) != S_OK)
+ {
+ return 0;
+ }
+
+ free(ProfileDirectory);
+
+ /* It's all good */
+ return 1;
+ }
+
+ int __PHYSFS_platformDeinit(void)
+ {
+ if(!doNTDeinit())
+ return 0;
+
+ if(CloseHandle(ProcessHandle) != S_OK)
+ return 0;
+
+ /* It's all good */
+ return 1;
+ }
+
+ void *__PHYSFS_platformOpenRead(const char *filename)
+ {
+ HANDLE FileHandle;
+
+ /* Open an existing file for read only. File can be opened by others
+ who request read access on the file only. */
+ FileHandle = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ /* If CreateFile() failed */
+ if(FileHandle == INVALID_HANDLE_VALUE)
+ return NULL;
+
+ return (void *)FileHandle;
+ }
+
+ void *__PHYSFS_platformOpenWrite(const char *filename)
+ {
+ HANDLE FileHandle;
+
+ /* Open an existing file for write only. File can be opened by others
+ who request read access to the file only */
+ FileHandle = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL,
+ CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ /* If CreateFile() failed */
+ if(FileHandle == INVALID_HANDLE_VALUE)
+ return NULL;
+
+ return (void *)FileHandle;
+ }
+
+ void *__PHYSFS_platformOpenAppend(const char *filename)
+ {
+ HANDLE FileHandle;
+
+ /* Open an existing file for appending only. File can be opened by others
+ who request read access to the file only. */
+ FileHandle = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL,
+ TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+ /* If CreateFile() failed */
+ if(FileHandle == INVALID_HANDLE_VALUE)
+ /* CreateFile might have failed because the file doesn't exist, so
+ we'll just create a new file for writing then */
+ return __PHYSFS_platformOpenWrite(filename);
+
+ return (void *)FileHandle;
+ }
+
+ PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buffer,
+ PHYSFS_uint32 size, PHYSFS_uint32 count)
+ {
+ HANDLE FileHandle;
+ DWORD CountOfBytesRead;
+ PHYSFS_sint64 retval;
+
+ /* Cast the generic handle to a Win32 handle */
+ FileHandle = (HANDLE)opaque;
+
+ /* Read data from the file */
+ /*!!! - uint32 might be a greater # than DWORD */
+ if(!ReadFile(FileHandle, buffer, count * size, &CountOfBytesRead, NULL))
+ {
+ /* Set the error to GetLastError */
+ __PHYSFS_setError(win32strerror());
+ /* We errored out */
+ retval = -1;
+ }
+ else
+ {
+ /* Return the number of "objects" read. */
+ /* !!! - What if not the right amount of bytes was read to make an
object? */
+ retval = CountOfBytesRead / size;
+ }
+
+ return retval;
+ }
+
+ PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, void *buffer,
+ PHYSFS_uint32 size, PHYSFS_uint32 count)
+ {
+ HANDLE FileHandle;
+ DWORD CountOfBytesWritten;
+ PHYSFS_sint64 retval;
+
+ /* Cast the generic handle to a Win32 handle */
+ FileHandle = (HANDLE)opaque;
+
+ /* Read data from the file */
+ /*!!! - uint32 might be a greater # than DWORD */
+ if(!WriteFile(FileHandle, buffer, count * size, &CountOfBytesWritten,
NULL))
+ {
+ /* Set the error to GetLastError */
+ __PHYSFS_setError(win32strerror());
+ /* We errored out */
+ retval = -1;
+ }
+ else
+ {
+ /* Return the number of "objects" read. */
+ /*!!! - What if not the right number of bytes was written? */
+ retval = CountOfBytesWritten / size;
+ }
+
+ return retval;
+ }
+
+ int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos)
+ {
+ HANDLE FileHandle;
+ int retval;
+ DWORD HighOrderPos;
+
+ /* Cast the generic handle to a Win32 handle */
+ FileHandle = (HANDLE)opaque;
+
+ /* Get the high order 32-bits of the position */
+ HighOrderPos = HIGHORDER_UINT64(pos);
+
+ /*!!! SetFilePointer needs a signed 64-bit value. */
+ /* Move pointer "pos" count from start of file */
+ if((SetFilePointer(FileHandle, LOWORDER_UINT64(pos), &HighOrderPos,
FILE_BEGIN)
+ == INVALID_SET_FILE_POINTER) && (GetLastError() != NO_ERROR))
+ {
+ /* An error occured. Set the error to GetLastError */
+ __PHYSFS_setError(win32strerror());
+
+ retval = 0;
+ }
+ else
+ {
+ /* No error occured */
+ retval = 1;
+ }
+
+ return retval;
+ }
+
+ PHYSFS_sint64 __PHYSFS_platformTell(void *opaque)
+ {
+ HANDLE FileHandle;
+ DWORD HighOrderPos = 0;
+ DWORD LowOrderPos;
+ PHYSFS_sint64 retval;
+
+ /* Cast the generic handle to a Win32 handle */
+ FileHandle = (HANDLE)opaque;
+
+ /* Get current position */
+ if(((LowOrderPos = SetFilePointer(FileHandle, 0, &HighOrderPos,
FILE_CURRENT))
+ == INVALID_SET_FILE_POINTER) && (GetLastError() != NO_ERROR))
+ {
+ /* Combine the high/low order to create the 64-bit position value */
+ retval = HighOrderPos;
+ retval = retval << 32;
+ retval |= LowOrderPos;
+ }
+ else
+ {
+ /* Set the error to GetLastError */
+ __PHYSFS_setError(win32strerror());
+ /* We errored out */
+ retval = 0;
+ }
+
+ /*!!! Can't find a file pointer routine?!?!?!!?!?*/
+ return retval;
+ }
+
+ PHYSFS_sint64 __PHYSFS_platformFileLength(void *handle)
+ {
+ HANDLE FileHandle;
+ DWORD FileSizeHigh;
+ DWORD FileSizeLow;
+ PHYSFS_sint64 retval;
+
+ /* Cast the generic handle to a Win32 handle */
+ FileHandle = (HANDLE)handle;
+
+ if(((FileSizeLow = GetFileSize(FileHandle, &FileSizeHigh))
+ == INVALID_SET_FILE_POINTER) && (GetLastError() != NO_ERROR))
+ {
+ /* Combine the high/low order to create the 64-bit position value */
+ retval = FileSizeHigh;
+ retval = retval << 32;
+ retval |= FileSizeLow;
+ }
+ else
+ {
+ /* Set the error to GetLastError */
+ __PHYSFS_setError(win32strerror());
+
+ retval = -1;
+ }
+
+ return retval;
+ }
+
+ int __PHYSFS_platformEOF(void *opaque)
+ {
+ HANDLE FileHandle;
+ PHYSFS_sint64 FilePosition;
+ int retval = 0;
+
+ /* Cast the generic handle to a Win32 handle */
+ FileHandle = (HANDLE)opaque;
+
+ /* Get the current position in the file */
+ if((FilePosition = __PHYSFS_platformTell(opaque)) != 0)
+ {
+ /* Non-zero if EOF is equal to the file length - 1 */
+ retval = FilePosition == __PHYSFS_platformFileLength(opaque) - 1;
+ }
+
+ return retval;
+ }
+
+ int __PHYSFS_platformFlush(void *opaque)
+ {
+ HANDLE FileHandle;
+ int retval;
+
+ /* Cast the generic handle to a Win32 handle */
+ FileHandle = (HANDLE)opaque;
+
+ /* Close the file */
+ if(!(retval = FlushFileBuffers(FileHandle)))
+ {
+ /* Set the error to GetLastError */
+ __PHYSFS_setError(win32strerror());
+ }
+
+ return retval;
+ }
+
+ int __PHYSFS_platformClose(void *opaque)
+ {
+ HANDLE FileHandle;
+ int retval;
+
+ /* Cast the generic handle to a Win32 handle */
+ FileHandle = (HANDLE)opaque;
+
+ /* Close the file */
+ if(!(retval = CloseHandle(FileHandle)))
+ {
+ /* Set the error to GetLastError */
+ __PHYSFS_setError(win32strerror());
+ }
+
+ return retval;
+ }
+
+ /*
+ * Remove a file or directory entry in the actual filesystem. (path) is
+ * specified in platform-dependent notation. Note that this deletes files
+ * _and_ directories, so you might need to do some determination.
+ * Non-empty directories should report an error and not delete themselves
+ * or their contents.
+ *
+ * Deleting a symlink should remove the link, not what it points to.
+ *
+ * On error, return zero and set the error message. Return non-zero on
success.
+ */
+ int __PHYSFS_platformDelete(const char *path)
+ {
+ int retval;
+
+ /* If filename is a folder */
+ if(GetFileAttributes(path) == FILE_ATTRIBUTE_DIRECTORY)
+ {
+ retval = RemoveDirectory(path);
+ }
+ else
+ {
+ retval = DeleteFile(path);
+ }
+
+ if(!retval)
+ {
+ /* Set the error to GetLastError */
+ __PHYSFS_setError(win32strerror());
+ }
+
+ return retval;
+ }
+
+ void *__PHYSFS_platformCreateMutex(void)
+ {
+ return (void *)CreateMutex(NULL, FALSE, NULL);
+ }
+
+ void __PHYSFS_platformDestroyMutex(void *mutex)
+ {
+ CloseHandle((HANDLE)mutex);
+ }
+
+ int __PHYSFS_platformGrabMutex(void *mutex)
+ {
+ int retval;
+
+ if(WaitForSingleObject((HANDLE)mutex, INFINITE) == WAIT_FAILED)
+ {
+ /* Our wait failed for some unknown reason */
+ retval = 1;
+ }
+ else
+ {
+ /* Good to go */
+ retval = 0;
+ }
+
+ return retval;
+ }
+
+ void __PHYSFS_platformReleaseMutex(void *mutex)
+ {
+ ReleaseMutex((HANDLE)mutex);
+ }
/* end of win32.c ... */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [paragui-cvs] CVS: paragui/src/physfs/platform macclassic.c,NONE,1.1 skeleton.c,NONE,1.1 Makefile.am,1.1.1.1,1.2 unix.c,1.1.1.1,1.2 win32.c,1.1.1.1,1.2,
Alexander Pipelka <address@hidden> <=
- Prev by Date:
[paragui-cvs] CVS: paragui/src/physfs/archivers Makefile.am,1.1.1.1,1.2 dir.c,1.1.1.1,1.2 grp.c,1.1.1.1,1.2 unzip.c,1.1.1.1,1.2 zip.c,1.1.1.1,1.2
- Next by Date:
[paragui-cvs] CVS: paragui/include pgpoint.h,NONE,1.1
- Previous by thread:
[paragui-cvs] CVS: paragui/src/physfs/archivers Makefile.am,1.1.1.1,1.2 dir.c,1.1.1.1,1.2 grp.c,1.1.1.1,1.2 unzip.c,1.1.1.1,1.2 zip.c,1.1.1.1,1.2
- Next by thread:
[paragui-cvs] CVS: paragui/include pgpoint.h,NONE,1.1
- Index(es):