mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-22 03:51:32 +00:00
Try to get windows to delete temporary files early, so they don't linger over crashes or whatever. win9x still sucks.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5898 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
be0c0b1821
commit
7c162c1b5b
3 changed files with 92 additions and 10 deletions
|
@ -2,7 +2,7 @@
|
|||
#include "fs.h"
|
||||
#include "errno.h"
|
||||
|
||||
#if !defined(NACL) && !defined(FTE_TARGET_WEB)
|
||||
#if !defined(NACL) && !defined(FTE_TARGET_WEB) && !defined(_WIN32)
|
||||
|
||||
#ifdef WEBSVONLY
|
||||
#define Z_Free free
|
||||
|
@ -120,7 +120,8 @@ vfsfile_t *FSSTDIO_OpenTemp(void)
|
|||
vfsstdiofile_t *file;
|
||||
|
||||
#ifdef _WIN32
|
||||
/*warning: annother app might manage to open the file before we can. if the file is not opened exclusively then we can end up with issues
|
||||
/*microsoft's tmpfile will nearly always fail, as it insists on writing to the root directory and that requires running everything with full admin rights.
|
||||
warning: there's a race condition between tempnam and fopen. if the file is not opened exclusively then we can end up with issues
|
||||
on windows, fopen is typically exclusive anyway, but not on unix. but on unix, tmpfile is actually usable, so special-case the windows code
|
||||
we also have a special close function to ensure the file is deleted too
|
||||
*/
|
||||
|
|
|
@ -201,6 +201,7 @@ void MyRegDeleteKeyValue(void *base, const char *keyname, const char *valuename)
|
|||
|
||||
#define VFSW32_Open VFSOS_Open
|
||||
#define VFSW32_OpenPath VFSOS_OpenPath
|
||||
#define VFSW32_OpenTemp FS_OpenTemp
|
||||
|
||||
typedef struct {
|
||||
searchpathfuncs_t pub;
|
||||
|
@ -314,6 +315,75 @@ static qboolean QDECL VFSW32_Close(vfsfile_t *file)
|
|||
Z_Free(file);
|
||||
return true;
|
||||
}
|
||||
static qboolean QDECL VFSW32_CloseTemp(vfsfile_t *file)
|
||||
{
|
||||
vfsw32file_t *intfile = (vfsw32file_t*)file;
|
||||
if (intfile->mmap)
|
||||
{
|
||||
UnmapViewOfFile(intfile->mmap);
|
||||
CloseHandle(intfile->mmh);
|
||||
}
|
||||
CloseHandle(intfile->hand);
|
||||
DeleteFileA((char*)(intfile+1));
|
||||
Z_Free(file);
|
||||
return true;
|
||||
}
|
||||
|
||||
vfsfile_t *QDECL VFSW32_OpenTemp(void)
|
||||
{
|
||||
static int seq=-1;
|
||||
HANDLE h = INVALID_HANDLE_VALUE;
|
||||
vfsw32file_t *file;
|
||||
if (WinNT)
|
||||
{ //gotta use wide stuff.
|
||||
//on the plus side, FILE_SHARE_DELETE works.
|
||||
wchar_t osname[MAX_PATH];
|
||||
wchar_t tmppath[MAX_PATH];
|
||||
if (GetTempPathW(countof(tmppath), tmppath))
|
||||
if ((seq=GetTempFileNameW(tmppath, L"fte", ++seq, osname)))
|
||||
h = CreateFileW(osname, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE, NULL);
|
||||
if (!h)
|
||||
return VFSPIPE_Open(1, true);
|
||||
DeleteFileW(osname);
|
||||
|
||||
file = Z_Malloc(sizeof(vfsw32file_t));
|
||||
#ifdef _DEBUG
|
||||
narrowen(file->funcs.dbgname, sizeof(file->funcs.dbgname), osname);
|
||||
#endif
|
||||
file->funcs.Close = VFSW32_Close; //we already deleted it. woo.
|
||||
}
|
||||
else
|
||||
{ //can't use wide stuff.
|
||||
//FLIE_SHARE_DELETE doesn't work. we have to faff around ourselves.
|
||||
char osname[MAX_PATH];
|
||||
char tmppath[MAX_PATH];
|
||||
if (GetTempPathA(countof(tmppath), tmppath))
|
||||
if ((seq=GetTempFileNameA(tmppath, "fte", ++seq, osname)))
|
||||
h = CreateFileA(osname, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL);
|
||||
if (!h)
|
||||
return VFSPIPE_Open(1, true);
|
||||
|
||||
file = Z_Malloc(sizeof(vfsw32file_t) + strlen(osname)+1);
|
||||
strcpy((char*)(file+1), osname);
|
||||
#ifdef _DEBUG
|
||||
narrowen(file->funcs.dbgname, sizeof(file->funcs.dbgname), osname);
|
||||
#endif
|
||||
file->funcs.Close = VFSW32_CloseTemp; //gotta delete it after close. hopefully we won't crash too often...
|
||||
}
|
||||
file->funcs.ReadBytes = VFSW32_ReadBytes;
|
||||
file->funcs.WriteBytes = VFSW32_WriteBytes;
|
||||
file->funcs.Seek = VFSW32_Seek;
|
||||
file->funcs.Tell = VFSW32_Tell;
|
||||
file->funcs.GetLen = VFSW32_GetSize;
|
||||
file->funcs.Flush = VFSW32_Flush;
|
||||
file->hand = h;
|
||||
file->mmh = INVALID_HANDLE_VALUE;
|
||||
file->mmap = NULL;
|
||||
file->offset = 0;
|
||||
file->length = 0;
|
||||
|
||||
return &file->funcs;
|
||||
}
|
||||
|
||||
//WARNING: handle can be null
|
||||
static vfsfile_t *QDECL VFSW32_OpenInternal(vfsw32path_t *handle, const char *quakename, const char *osname, const char *mode)
|
||||
|
|
|
@ -2994,13 +2994,19 @@ typedef struct
|
|||
struct xz_dec *s;
|
||||
} vf_xz_dec_t;
|
||||
|
||||
static qboolean QDECL FS_XZ_Dec_Close(vfsfile_t *f)
|
||||
static vfsfile_t *FS_XZ_Finish(vfsfile_t *f)
|
||||
{
|
||||
vf_xz_dec_t *n = (vf_xz_dec_t*)f;
|
||||
VFS_CLOSE(n->outfile);
|
||||
vfsfile_t *r = n->outfile;
|
||||
if (n->s)
|
||||
xz_dec_end(n->s);
|
||||
Z_Free(n);
|
||||
return r;
|
||||
}
|
||||
static qboolean QDECL FS_XZ_Dec_Close(vfsfile_t *f)
|
||||
{
|
||||
vfsfile_t *orig = FS_XZ_Finish(f);
|
||||
VFS_CLOSE(orig);
|
||||
return true;
|
||||
}
|
||||
static int QDECL FS_XZ_Dec_Write(vfsfile_t *f, const void *buffer, int len)
|
||||
|
@ -3126,21 +3132,26 @@ vfsfile_t *FS_XZ_DecompressReadFilter(vfsfile_t *srcfile)
|
|||
|
||||
if (blocksize == HEADER_MAGIC_SIZE && !memcmp(block, HEADER_MAGIC, HEADER_MAGIC_SIZE))
|
||||
{ //okay, looks like an xz.
|
||||
vfsfile_t *pipe = VFSPIPE_Open(2, false);
|
||||
vfsfile_t *xzpipe = FS_XZ_DecompressWriteFilter(pipe);
|
||||
vfsfile_t *xzpipe = FS_OpenTemp();
|
||||
if (!xzpipe)
|
||||
xzpipe = VFSPIPE_Open(1, true);
|
||||
xzpipe = FS_XZ_DecompressWriteFilter(xzpipe);
|
||||
for (;blocksize;)
|
||||
{
|
||||
if (blocksize < 0 || blocksize != VFS_WRITE(xzpipe, block, blocksize))
|
||||
{
|
||||
VFS_CLOSE(pipe);
|
||||
pipe = NULL;
|
||||
VFS_CLOSE(xzpipe);
|
||||
xzpipe = NULL;
|
||||
break;
|
||||
}
|
||||
blocksize = VFS_READ(srcfile, block, sizeof(block));
|
||||
}
|
||||
VFS_CLOSE(srcfile);
|
||||
VFS_CLOSE(xzpipe);
|
||||
return pipe;
|
||||
|
||||
if (xzpipe)
|
||||
xzpipe = FS_XZ_Finish(xzpipe);
|
||||
VFS_SEEK(xzpipe, 0);
|
||||
return xzpipe;
|
||||
}
|
||||
VFS_SEEK(srcfile, 0);
|
||||
return srcfile;
|
||||
|
|
Loading…
Reference in a new issue