Update PhysFS to 3.0.2.

This commit is contained in:
Alex Szpakowski
2019-04-07 16:41:55 -03:00
parent 69c47675b9
commit e7c36022a8
7 changed files with 296 additions and 141 deletions
+218 -117
View File
@@ -46,6 +46,8 @@ typedef struct __PHYSFS_DIRHANDLE__
void *opaque; /* Instance data unique to the archiver. */
char *dirName; /* Path to archive in platform-dependent notation. */
char *mountPoint; /* Mountpoint in virtual file tree. */
char *root; /* subdirectory of archiver to use as root of archive (NULL for actual root) */
size_t rootlen; /* subdirectory of archiver to use as root of archive (NULL for actual root) */
const PHYSFS_Archiver *funcs; /* Ptr to archiver info for this handle. */
struct __PHYSFS_DIRHANDLE__ *next; /* linked list stuff. */
} DirHandle;
@@ -86,6 +88,7 @@ static int allowSymLinks = 0;
static PHYSFS_Archiver **archivers = NULL;
static PHYSFS_ArchiveInfo **archiveInfo = NULL;
static volatile size_t numArchivers = 0;
static size_t longest_root = 0;
/* mutexes ... */
static void *errorLock = NULL; /* protects error message list. */
@@ -879,13 +882,20 @@ static DirHandle *openDirectory(PHYSFS_Io *io, const char *d, int forWriting)
if (io == NULL)
{
/* file doesn't exist, etc? Just fail out. */
PHYSFS_Stat statbuf;
BAIL_IF_ERRPASS(!__PHYSFS_platformStat(d, &statbuf, 1), NULL);
/* DIR gets first shot (unlike the rest, it doesn't deal with files). */
retval = tryOpenDir(io, &__PHYSFS_Archiver_DIR, d, forWriting, &claimed);
if (retval || claimed)
return retval;
if (statbuf.filetype == PHYSFS_FILETYPE_DIRECTORY)
{
retval = tryOpenDir(io, &__PHYSFS_Archiver_DIR, d, forWriting, &claimed);
if (retval || claimed)
return retval;
} /* if */
io = __PHYSFS_createNativeIo(d, forWriting ? 'w' : 'r');
BAIL_IF_ERRPASS(!io, 0);
BAIL_IF_ERRPASS(!io, NULL);
created_io = 1;
} /* if */
@@ -973,6 +983,18 @@ static int sanitizePlatformIndependentPath(const char *src, char *dst)
} /* sanitizePlatformIndependentPath */
static inline size_t dirHandleRootLen(const DirHandle *h)
{
return h ? h->rootlen : 0;
} /* dirHandleRootLen */
static inline int sanitizePlatformIndependentPathWithRoot(const DirHandle *h, const char *src, char *dst)
{
return sanitizePlatformIndependentPath(src, dst + dirHandleRootLen(h));
} /* sanitizePlatformIndependentPathWithRoot */
/*
* Figure out if (fname) is part of (h)'s mountpoint. (fname) must be an
* output from sanitizePlatformIndependentPath(), so that it is in a known
@@ -1371,6 +1393,7 @@ static int doDeinit(void)
archivers = NULL;
} /* if */
longest_root = 0;
allowSymLinks = 0;
initialized = 0;
@@ -1677,6 +1700,54 @@ int PHYSFS_setWriteDir(const char *newDir)
} /* PHYSFS_setWriteDir */
int PHYSFS_setRoot(const char *archive, const char *subdir)
{
DirHandle *i;
BAIL_IF(!archive, PHYSFS_ERR_INVALID_ARGUMENT, 0);
__PHYSFS_platformGrabMutex(stateLock);
for (i = searchPath; i != NULL; i = i->next)
{
if ((i->dirName != NULL) && (strcmp(archive, i->dirName) == 0))
{
if (!subdir || (strcmp(subdir, "/") == 0))
{
if (i->root)
allocator.Free(i->root);
i->root = NULL;
i->rootlen = 0;
} /* if */
else
{
const size_t len = strlen(subdir) + 1;
char *ptr = (char *) allocator.Malloc(len);
BAIL_IF_MUTEX(!ptr, PHYSFS_ERR_OUT_OF_MEMORY, stateLock, 0);
if (!sanitizePlatformIndependentPath(subdir, ptr))
{
allocator.Free(ptr);
BAIL_MUTEX_ERRPASS(stateLock, 0);
} /* if */
if (i->root)
allocator.Free(i->root);
i->root = ptr;
i->rootlen = len;
if (longest_root < len)
longest_root = len;
} /* else */
break;
} /* if */
} /* for */
__PHYSFS_platformReleaseMutex(stateLock);
return 1;
} /* PHYSFS_setRoot */
static int doMount(PHYSFS_Io *io, const char *fname,
const char *mountPoint, int appendToPath)
{
@@ -1994,6 +2065,9 @@ int PHYSFS_symbolicLinksPermitted(void)
* like ".." which should be done once instead of once per archive. This also
* gives us license to treat (fname) as scratch space in this function.
*
* (fname)'s buffer must have enough space available before it for this
* function to prepend any root directory for this DirHandle.
*
* Returns non-zero if string is safe, zero if there's a security issue.
* PHYSFS_getLastError() will specify what was wrong. (*fname) will be
* updated to point past any mount point elements so it is prepared to
@@ -2006,7 +2080,7 @@ static int verifyPath(DirHandle *h, char **_fname, int allowMissing)
char *start;
char *end;
if (*fname == '\0') /* quick rejection. */
if ((*fname == '\0') && (!h->root)) /* quick rejection. */
return 1;
/* !!! FIXME: This codeblock sucks. */
@@ -2029,6 +2103,17 @@ static int verifyPath(DirHandle *h, char **_fname, int allowMissing)
retval = 1; /* may be reset, below. */
} /* if */
/* prepend the root directory, if any. */
if (h->root)
{
const int isempty = (*fname == '\0');
fname -= h->rootlen - 1;
strcpy(fname, h->root);
if (!isempty)
fname[h->rootlen - 2] = '/';
*_fname = fname;
} /* if */
start = fname;
if (!allowSymLinks)
{
@@ -2074,20 +2159,19 @@ static int verifyPath(DirHandle *h, char **_fname, int allowMissing)
} /* verifyPath */
/* This must hold the stateLock before calling. */
static int doMkdir(const char *_dname, char *dname)
{
DirHandle *h;
DirHandle *h = writeDir;
char *start;
char *end;
int retval = 0;
int exists = 1; /* force existance check on first path element. */
BAIL_IF_ERRPASS(!sanitizePlatformIndependentPath(_dname, dname), 0);
assert(h != NULL);
__PHYSFS_platformGrabMutex(stateLock);
BAIL_IF_MUTEX(!writeDir, PHYSFS_ERR_NO_WRITE_DIR, stateLock, 0);
h = writeDir;
BAIL_IF_MUTEX_ERRPASS(!verifyPath(h, &dname, 1), stateLock, 0);
BAIL_IF_ERRPASS(!sanitizePlatformIndependentPathWithRoot(h, _dname, dname), 0);
BAIL_IF_ERRPASS(!verifyPath(h, &dname, 1), 0);
start = dname;
while (1)
@@ -2119,7 +2203,6 @@ static int doMkdir(const char *_dname, char *dname)
start = end + 1;
} /* while */
__PHYSFS_platformReleaseMutex(stateLock);
return retval;
} /* doMkdir */
@@ -2131,30 +2214,26 @@ int PHYSFS_mkdir(const char *_dname)
size_t len;
BAIL_IF(!_dname, PHYSFS_ERR_INVALID_ARGUMENT, 0);
len = strlen(_dname) + 1;
__PHYSFS_platformGrabMutex(stateLock);
BAIL_IF_MUTEX(!writeDir, PHYSFS_ERR_NO_WRITE_DIR, stateLock, 0);
len = strlen(_dname) + dirHandleRootLen(writeDir) + 1;
dname = (char *) __PHYSFS_smallAlloc(len);
BAIL_IF(!dname, PHYSFS_ERR_OUT_OF_MEMORY, 0);
BAIL_IF_MUTEX(!dname, PHYSFS_ERR_OUT_OF_MEMORY, stateLock, 0);
retval = doMkdir(_dname, dname);
__PHYSFS_platformReleaseMutex(stateLock);
__PHYSFS_smallFree(dname);
return retval;
} /* PHYSFS_mkdir */
/* This must hold the stateLock before calling. */
static int doDelete(const char *_fname, char *fname)
{
int retval;
DirHandle *h;
BAIL_IF_ERRPASS(!sanitizePlatformIndependentPath(_fname, fname), 0);
__PHYSFS_platformGrabMutex(stateLock);
BAIL_IF_MUTEX(!writeDir, PHYSFS_ERR_NO_WRITE_DIR, stateLock, 0);
h = writeDir;
BAIL_IF_MUTEX_ERRPASS(!verifyPath(h, &fname, 0), stateLock, 0);
retval = h->funcs->remove(h->opaque, fname);
__PHYSFS_platformReleaseMutex(stateLock);
return retval;
DirHandle *h = writeDir;
BAIL_IF_ERRPASS(!sanitizePlatformIndependentPathWithRoot(h, _fname, fname), 0);
BAIL_IF_ERRPASS(!verifyPath(h, &fname, 0), 0);
return h->funcs->remove(h->opaque, fname);
} /* doDelete */
@@ -2164,11 +2243,13 @@ int PHYSFS_delete(const char *_fname)
char *fname;
size_t len;
BAIL_IF(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, 0);
len = strlen(_fname) + 1;
__PHYSFS_platformGrabMutex(stateLock);
BAIL_IF_MUTEX(!writeDir, PHYSFS_ERR_NO_WRITE_DIR, stateLock, 0);
len = strlen(_fname) + dirHandleRootLen(writeDir) + 1;
fname = (char *) __PHYSFS_smallAlloc(len);
BAIL_IF(!fname, PHYSFS_ERR_OUT_OF_MEMORY, 0);
BAIL_IF_MUTEX(!fname, PHYSFS_ERR_OUT_OF_MEMORY, stateLock, 0);
retval = doDelete(_fname, fname);
__PHYSFS_platformReleaseMutex(stateLock);
__PHYSFS_smallFree(fname);
return retval;
} /* PHYSFS_delete */
@@ -2177,17 +2258,20 @@ int PHYSFS_delete(const char *_fname)
static DirHandle *getRealDirHandle(const char *_fname)
{
DirHandle *retval = NULL;
char *allocated_fname = NULL;
char *fname = NULL;
size_t len;
BAIL_IF(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, NULL);
len = strlen(_fname) + 1;
fname = __PHYSFS_smallAlloc(len);
BAIL_IF(!fname, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
__PHYSFS_platformGrabMutex(stateLock);
len = strlen(_fname) + longest_root + 1;
allocated_fname = __PHYSFS_smallAlloc(len);
BAIL_IF_MUTEX(!allocated_fname, PHYSFS_ERR_OUT_OF_MEMORY, stateLock, NULL);
fname = allocated_fname + longest_root;
if (sanitizePlatformIndependentPath(_fname, fname))
{
DirHandle *i;
__PHYSFS_platformGrabMutex(stateLock);
for (i = searchPath; i != NULL; i = i->next)
{
char *arcfname = fname;
@@ -2206,10 +2290,10 @@ static DirHandle *getRealDirHandle(const char *_fname)
} /* if */
} /* if */
} /* for */
__PHYSFS_platformReleaseMutex(stateLock);
} /* if */
__PHYSFS_smallFree(fname);
__PHYSFS_platformReleaseMutex(stateLock);
__PHYSFS_smallFree(allocated_fname);
return retval;
} /* getRealDirHandle */
@@ -2404,15 +2488,18 @@ int PHYSFS_enumerate(const char *_fn, PHYSFS_EnumerateCallback cb, void *data)
{
PHYSFS_EnumerateCallbackResult retval = PHYSFS_ENUM_OK;
size_t len;
char *allocated_fname;
char *fname;
BAIL_IF(!_fn, PHYSFS_ERR_INVALID_ARGUMENT, 0);
BAIL_IF(!cb, PHYSFS_ERR_INVALID_ARGUMENT, 0);
len = strlen(_fn) + 1;
fname = (char *) __PHYSFS_smallAlloc(len);
BAIL_IF(!fname, PHYSFS_ERR_OUT_OF_MEMORY, 0);
__PHYSFS_platformGrabMutex(stateLock);
len = strlen(_fn) + longest_root + 1;
allocated_fname = (char *) __PHYSFS_smallAlloc(len);
BAIL_IF_MUTEX(!allocated_fname, PHYSFS_ERR_OUT_OF_MEMORY, stateLock, 0);
fname = allocated_fname + longest_root;
if (!sanitizePlatformIndependentPath(_fn, fname))
retval = PHYSFS_ENUM_STOP;
else
@@ -2420,8 +2507,6 @@ int PHYSFS_enumerate(const char *_fn, PHYSFS_EnumerateCallback cb, void *data)
DirHandle *i;
SymlinkFilterData filterdata;
__PHYSFS_platformGrabMutex(stateLock);
if (!allowSymLinks)
{
memset(&filterdata, '\0', sizeof (filterdata));
@@ -2470,10 +2555,11 @@ int PHYSFS_enumerate(const char *_fn, PHYSFS_EnumerateCallback cb, void *data)
} /* else if */
} /* for */
__PHYSFS_platformReleaseMutex(stateLock);
} /* if */
__PHYSFS_smallFree(fname);
__PHYSFS_platformReleaseMutex(stateLock);
__PHYSFS_smallFree(allocated_fname);
return (retval == PHYSFS_ENUM_ERROR) ? 0 : 1;
} /* PHYSFS_enumerate */
@@ -2534,57 +2620,58 @@ int PHYSFS_isSymbolicLink(const char *fname)
} /* PHYSFS_isSymbolicLink */
static PHYSFS_File *doOpenWrite(const char *_fname, int appending)
static PHYSFS_File *doOpenWrite(const char *_fname, const int appending)
{
FileHandle *fh = NULL;
DirHandle *h;
size_t len;
char *fname;
BAIL_IF(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, 0);
len = strlen(_fname) + 1;
fname = (char *) __PHYSFS_smallAlloc(len);
BAIL_IF(!fname, PHYSFS_ERR_OUT_OF_MEMORY, 0);
if (sanitizePlatformIndependentPath(_fname, fname))
__PHYSFS_platformGrabMutex(stateLock);
h = writeDir;
BAIL_IF_MUTEX(!h, PHYSFS_ERR_NO_WRITE_DIR, stateLock, 0);
len = strlen(_fname) + dirHandleRootLen(h) + 1;
fname = (char *) __PHYSFS_smallAlloc(len);
BAIL_IF_MUTEX(!fname, PHYSFS_ERR_OUT_OF_MEMORY, stateLock, 0);
if (sanitizePlatformIndependentPathWithRoot(h, _fname, fname))
{
PHYSFS_Io *io = NULL;
DirHandle *h = NULL;
const PHYSFS_Archiver *f;
__PHYSFS_platformGrabMutex(stateLock);
GOTO_IF(!writeDir, PHYSFS_ERR_NO_WRITE_DIR, doOpenWriteEnd);
h = writeDir;
GOTO_IF_ERRPASS(!verifyPath(h, &fname, 0), doOpenWriteEnd);
f = h->funcs;
if (appending)
io = f->openAppend(h->opaque, fname);
else
io = f->openWrite(h->opaque, fname);
GOTO_IF_ERRPASS(!io, doOpenWriteEnd);
fh = (FileHandle *) allocator.Malloc(sizeof (FileHandle));
if (fh == NULL)
char *arcfname = fname;
if (verifyPath(h, &arcfname, 0))
{
io->destroy(io);
GOTO(PHYSFS_ERR_OUT_OF_MEMORY, doOpenWriteEnd);
const PHYSFS_Archiver *f = h->funcs;
if (appending)
io = f->openAppend(h->opaque, arcfname);
else
io = f->openWrite(h->opaque, arcfname);
if (io)
{
fh = (FileHandle *) allocator.Malloc(sizeof (FileHandle));
if (fh == NULL)
{
io->destroy(io);
PHYSFS_setErrorCode(PHYSFS_ERR_OUT_OF_MEMORY);
} /* if */
else
{
memset(fh, '\0', sizeof (FileHandle));
fh->io = io;
fh->dirHandle = h;
fh->next = openWriteList;
openWriteList = fh;
} /* else */
} /* if */
} /* if */
else
{
memset(fh, '\0', sizeof (FileHandle));
fh->io = io;
fh->dirHandle = h;
fh->next = openWriteList;
openWriteList = fh;
} /* else */
doOpenWriteEnd:
__PHYSFS_platformReleaseMutex(stateLock);
} /* if */
__PHYSFS_platformReleaseMutex(stateLock);
__PHYSFS_smallFree(fname);
return ((PHYSFS_File *) fh);
} /* doOpenWrite */
@@ -2605,22 +2692,25 @@ PHYSFS_File *PHYSFS_openAppend(const char *filename)
PHYSFS_File *PHYSFS_openRead(const char *_fname)
{
FileHandle *fh = NULL;
char *allocated_fname;
char *fname;
size_t len;
BAIL_IF(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, 0);
len = strlen(_fname) + 1;
fname = (char *) __PHYSFS_smallAlloc(len);
BAIL_IF(!fname, PHYSFS_ERR_OUT_OF_MEMORY, 0);
__PHYSFS_platformGrabMutex(stateLock);
BAIL_IF_MUTEX(!searchPath, PHYSFS_ERR_NOT_FOUND, stateLock, 0);
len = strlen(_fname) + longest_root + 1;
allocated_fname = (char *) __PHYSFS_smallAlloc(len);
BAIL_IF_MUTEX(!allocated_fname, PHYSFS_ERR_OUT_OF_MEMORY, stateLock, 0);
fname = allocated_fname + longest_root;
if (sanitizePlatformIndependentPath(_fname, fname))
{
DirHandle *i = NULL;
PHYSFS_Io *io = NULL;
__PHYSFS_platformGrabMutex(stateLock);
GOTO_IF(!searchPath, PHYSFS_ERR_NOT_FOUND, openReadEnd);
DirHandle *i;
for (i = searchPath; i != NULL; i = i->next)
{
@@ -2633,27 +2723,26 @@ PHYSFS_File *PHYSFS_openRead(const char *_fname)
} /* if */
} /* for */
GOTO_IF_ERRPASS(!io, openReadEnd);
fh = (FileHandle *) allocator.Malloc(sizeof (FileHandle));
if (fh == NULL)
if (io)
{
io->destroy(io);
GOTO(PHYSFS_ERR_OUT_OF_MEMORY, openReadEnd);
fh = (FileHandle *) allocator.Malloc(sizeof (FileHandle));
if (fh == NULL)
{
io->destroy(io);
PHYSFS_setErrorCode(PHYSFS_ERR_OUT_OF_MEMORY);
} /* if */
memset(fh, '\0', sizeof (FileHandle));
fh->io = io;
fh->forReading = 1;
fh->dirHandle = i;
fh->next = openReadList;
openReadList = fh;
} /* if */
memset(fh, '\0', sizeof (FileHandle));
fh->io = io;
fh->forReading = 1;
fh->dirHandle = i;
fh->next = openReadList;
openReadList = fh;
openReadEnd:
__PHYSFS_platformReleaseMutex(stateLock);
} /* if */
__PHYSFS_smallFree(fname);
__PHYSFS_platformReleaseMutex(stateLock);
__PHYSFS_smallFree(allocated_fname);
return ((PHYSFS_File *) fh);
} /* PHYSFS_openRead */
@@ -2662,7 +2751,6 @@ static int closeHandleInOpenList(FileHandle **list, FileHandle *handle)
{
FileHandle *prev = NULL;
FileHandle *i;
int rc = 1;
for (i = *list; i != NULL; i = i->next)
{
@@ -2670,9 +2758,19 @@ static int closeHandleInOpenList(FileHandle **list, FileHandle *handle)
{
PHYSFS_Io *io = handle->io;
PHYSFS_uint8 *tmp = handle->buffer;
rc = PHYSFS_flush((PHYSFS_File *) handle);
if (!rc)
return -1;
/* send our buffer to io... */
if (!handle->forReading)
{
if (!PHYSFS_flush((PHYSFS_File *) handle))
return -1;
/* ...then have io send it to the disk... */
else if (io->flush && !io->flush(io))
return -1;
} /* if */
/* ...then close the underlying file. */
io->destroy(io);
if (tmp != NULL) /* free any associated buffer. */
@@ -2970,21 +3068,19 @@ int PHYSFS_flush(PHYSFS_File *handle)
rc = io->write(io, fh->buffer + fh->bufpos, fh->buffill - fh->bufpos);
BAIL_IF_ERRPASS(rc <= 0, 0);
fh->bufpos = fh->buffill = 0;
return io->flush ? io->flush(io) : 1;
return 1;
} /* PHYSFS_flush */
int PHYSFS_stat(const char *_fname, PHYSFS_Stat *stat)
{
int retval = 0;
char *allocated_fname;
char *fname;
size_t len;
BAIL_IF(!_fname, PHYSFS_ERR_INVALID_ARGUMENT, 0);
BAIL_IF(!stat, PHYSFS_ERR_INVALID_ARGUMENT, 0);
len = strlen(_fname) + 1;
fname = (char *) __PHYSFS_smallAlloc(len);
BAIL_IF(!fname, PHYSFS_ERR_OUT_OF_MEMORY, 0);
/* set some sane defaults... */
stat->filesize = -1;
@@ -2994,6 +3090,12 @@ int PHYSFS_stat(const char *_fname, PHYSFS_Stat *stat)
stat->filetype = PHYSFS_FILETYPE_OTHER;
stat->readonly = 1;
__PHYSFS_platformGrabMutex(stateLock);
len = strlen(_fname) + longest_root + 1;
allocated_fname = (char *) __PHYSFS_smallAlloc(len);
BAIL_IF_MUTEX(!allocated_fname, PHYSFS_ERR_OUT_OF_MEMORY, stateLock, 0);
fname = allocated_fname + longest_root;
if (sanitizePlatformIndependentPath(_fname, fname))
{
if (*fname == '\0')
@@ -3006,7 +3108,6 @@ int PHYSFS_stat(const char *_fname, PHYSFS_Stat *stat)
{
DirHandle *i;
int exists = 0;
__PHYSFS_platformGrabMutex(stateLock);
for (i = searchPath; ((i != NULL) && (!exists)); i = i->next)
{
char *arcfname = fname;
@@ -3024,11 +3125,11 @@ int PHYSFS_stat(const char *_fname, PHYSFS_Stat *stat)
exists = 1;
} /* else if */
} /* for */
__PHYSFS_platformReleaseMutex(stateLock);
} /* else */
} /* if */
__PHYSFS_smallFree(fname);
__PHYSFS_platformReleaseMutex(stateLock);
__PHYSFS_smallFree(allocated_fname);
return retval;
} /* PHYSFS_stat */
+45 -5
View File
@@ -225,11 +225,11 @@ extern "C" {
#if defined(PHYSFS_DECL)
/* do nothing. */
#elif (defined _MSC_VER)
#elif defined(_MSC_VER)
#define PHYSFS_DECL __declspec(dllexport)
#elif (defined __SUNPRO_C)
#elif defined(__SUNPRO_C)
#define PHYSFS_DECL __global
#elif ((__GNUC__ >= 3) && (!__EMX__) && (!sun))
#elif ((__GNUC__ >= 3) && (!defined(__EMX__)) && (!defined(sun)))
#define PHYSFS_DECL __attribute__((visibility("default")))
#else
#define PHYSFS_DECL
@@ -433,8 +433,8 @@ typedef struct PHYSFS_Version
#ifndef DOXYGEN_SHOULD_IGNORE_THIS
#define PHYSFS_VER_MAJOR 3
#define PHYSFS_VER_MINOR 0
#define PHYSFS_VER_PATCH 1
#define PHYSFS_VER_MINOR 1
#define PHYSFS_VER_PATCH 0
#endif /* DOXYGEN_SHOULD_IGNORE_THIS */
@@ -3844,6 +3844,46 @@ PHYSFS_DECL int PHYSFS_deregisterArchiver(const char *ext);
/* Everything above this line is part of the PhysicsFS 2.1 API. */
/**
* \fn int PHYSFS_setRoot(const char *archive, const char *subdir)
* \brief Make a subdirectory of an archive its root directory.
*
* This lets you narrow down the accessible files in a specific archive. For
* example, if you have x.zip with a file in y/z.txt, mounted to /a, if you
* call PHYSFS_setRoot("x.zip", "/y"), then the call
* PHYSFS_openRead("/a/z.txt") will succeed.
*
* You can change an archive's root at any time, altering the interpolated
* file tree (depending on where paths shift, a different archive may be
* providing various files). If you set the root to NULL or "/", the
* archive will be treated as if no special root was set (as if the archive
* was just mounted normally).
*
* Changing the root only affects future operations on pathnames; a file
* that was opened from a path that changed due to a setRoot will not be
* affected.
*
* Setting a new root is not limited to archives in the search path; you may
* set one on the write dir, too, which might be useful if you have files
* open for write and thus can't change the write dir at the moment.
*
* It is not an error to set a subdirectory that does not exist to be the
* root of an archive; however, no files will be visible in this case. If
* the missing directories end up getting created (a mkdir to the physical
* filesystem, etc) then this will be reflected in the interpolated tree.
*
* \param archive dir/archive on which to change root.
* \param subdir new subdirectory to make the root of this archive.
* \return nonzero on success, zero on failure. Use
* PHYSFS_getLastErrorCode() to obtain the specific error.
*/
PHYSFS_DECL int PHYSFS_setRoot(const char *archive, const char *subdir);
/* Everything above this line is part of the PhysicsFS 3.1 API. */
#ifdef __cplusplus
}
#endif
@@ -203,6 +203,8 @@ static void SZIP_closeArchive(void *opaque)
SZIPinfo *info = (SZIPinfo *) opaque;
if (info)
{
if (info->io)
info->io->destroy(info->io);
SzArEx_Free(&info->db, &SZIP_SzAlloc);
__PHYSFS_DirTreeDeinit(&info->tree);
allocator.Free(info);
+19 -10
View File
@@ -162,35 +162,44 @@ void __PHYSFS_smallFree(void *ptr);
#define free(x) Do not use free() directly.
/* !!! FIXME: add alloca check here. */
/* by default, enable things, so builds can opt out of a few things they
want to avoid. But you can build with this #defined to 0 if you would
like to turn off everything except a handful of things you opt into. */
#ifndef PHYSFS_SUPPORTS_DEFAULT
#define PHYSFS_SUPPORTS_DEFAULT 1
#endif
#ifndef PHYSFS_SUPPORTS_ZIP
#define PHYSFS_SUPPORTS_ZIP 1
#define PHYSFS_SUPPORTS_ZIP PHYSFS_SUPPORTS_DEFAULT
#endif
#ifndef PHYSFS_SUPPORTS_7Z
#define PHYSFS_SUPPORTS_7Z 1
#define PHYSFS_SUPPORTS_7Z PHYSFS_SUPPORTS_DEFAULT
#endif
#ifndef PHYSFS_SUPPORTS_GRP
#define PHYSFS_SUPPORTS_GRP 1
#define PHYSFS_SUPPORTS_GRP PHYSFS_SUPPORTS_DEFAULT
#endif
#ifndef PHYSFS_SUPPORTS_HOG
#define PHYSFS_SUPPORTS_HOG 1
#define PHYSFS_SUPPORTS_HOG PHYSFS_SUPPORTS_DEFAULT
#endif
#ifndef PHYSFS_SUPPORTS_MVL
#define PHYSFS_SUPPORTS_MVL 1
#define PHYSFS_SUPPORTS_MVL PHYSFS_SUPPORTS_DEFAULT
#endif
#ifndef PHYSFS_SUPPORTS_WAD
#define PHYSFS_SUPPORTS_WAD 1
#define PHYSFS_SUPPORTS_WAD PHYSFS_SUPPORTS_DEFAULT
#endif
#ifndef PHYSFS_SUPPORTS_QPAK
#define PHYSFS_SUPPORTS_QPAK 1
#define PHYSFS_SUPPORTS_QPAK PHYSFS_SUPPORTS_DEFAULT
#endif
#ifndef PHYSFS_SUPPORTS_SLB
#define PHYSFS_SUPPORTS_SLB 1
#define PHYSFS_SUPPORTS_SLB PHYSFS_SUPPORTS_DEFAULT
#endif
#ifndef PHYSFS_SUPPORTS_ISO9660
#define PHYSFS_SUPPORTS_ISO9660 1
#define PHYSFS_SUPPORTS_ISO9660 PHYSFS_SUPPORTS_DEFAULT
#endif
#ifndef PHYSFS_SUPPORTS_VDF
#define PHYSFS_SUPPORTS_VDF 1
#define PHYSFS_SUPPORTS_VDF PHYSFS_SUPPORTS_DEFAULT
#endif
#if PHYSFS_SUPPORTS_7Z
+1
View File
@@ -699,3 +699,4 @@ static int mz_inflateEnd(mz_streamp pStream)
For more information, please refer to <https://unlicense.org/>
*/
+1 -1
View File
@@ -50,7 +50,7 @@ char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, TRUE);
BAIL_IF(!paths, PHYSFS_ERR_OS_ERROR, NULL);
NSString *path = (NSString *) paths[0];
NSString *path = (NSString *) [paths objectAtIndex:0];
BAIL_IF(!path, PHYSFS_ERR_OS_ERROR, NULL);
size_t len = [path lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
const size_t applen = strlen(app);
+10 -8
View File
@@ -572,18 +572,20 @@ char *__PHYSFS_platformCalcUserDir(void)
/*
* Should fail. Will write the size of the profile path in
* psize. Also note that the second parameter can't be
* NULL or the function fails.
*/
/*
* EDIT: (03.10.2018) after Windows 10 Update 1809 psize will be zero
* if something other than NULL is passed for the second argument.
* Passing NULL now makes GetUserProfileDirectoryW fail (rc == 0)
* and psize receives the correct user directory length.
* It seems to work fine on Windows 7 and Windows 10 Update 1803 too
* NULL or the function fails on Windows XP, but has to be NULL on
* Windows 10 or it will fail. :(
*/
rc = pGetDir(accessToken, NULL, &psize);
GOTO_IF(rc, PHYSFS_ERR_OS_ERROR, done); /* should have failed! */
if (psize == 0) /* probably on Windows XP, try a different way. */
{
WCHAR x = 0;
rc = pGetDir(accessToken, &x, &psize);
GOTO_IF(rc, PHYSFS_ERR_OS_ERROR, done); /* should have failed! */
GOTO_IF(!psize, PHYSFS_ERR_OS_ERROR, done); /* Uhoh... */
} /* if */
/* Allocate memory for the profile directory */
wstr = (LPWSTR) __PHYSFS_smallAlloc((psize + 1) * sizeof (WCHAR));
if (wstr != NULL)