1139 lines
46 KiB
C++
1139 lines
46 KiB
C++
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
// $NoKeywords: $
|
|
//===========================================================================//
|
|
|
|
#ifndef FILESYSTEM_H
|
|
#define FILESYSTEM_H
|
|
#pragma once
|
|
|
|
#include <limits.h>
|
|
|
|
#include "appframework/IAppSystem.h"
|
|
#include "tier0/memalloc.h"
|
|
#include "tier0/threadtools.h"
|
|
#include "tier1/checksum_crc.h"
|
|
#include "tier1/checksum_md5.h"
|
|
#include "tier1/interface.h"
|
|
#include "tier1/refcount.h"
|
|
#include "tier1/utlstring.h"
|
|
#include "tier1/utlsymbol.h"
|
|
|
|
#ifdef _WIN32
|
|
#pragma once
|
|
#endif
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Forward declarations
|
|
//-----------------------------------------------------------------------------
|
|
|
|
class CUtlBuffer;
|
|
class KeyValues;
|
|
class IFileList;
|
|
class IThreadPool;
|
|
class CMemoryFileBacking;
|
|
|
|
typedef void *FileHandle_t;
|
|
typedef void *FileCacheHandle_t;
|
|
typedef int FileFindHandle_t;
|
|
typedef void (*FileSystemLoggingFunc_t)(const char *fileName,
|
|
const char *accessType);
|
|
typedef int WaitForResourcesHandle_t;
|
|
|
|
#ifdef _X360
|
|
typedef void *HANDLE;
|
|
#endif
|
|
|
|
#define USE_CRC_FILE_TRACKING 0
|
|
|
|
// Turn on some extra pure server debug spew in certain builds.
|
|
// WARNING: This spew can be used by hackers to locate places to hack
|
|
// the code to bypas sv_pure! Be careful!
|
|
#if defined(_DEBUG) || defined(STAGING_ONLY)
|
|
#define PURE_SERVER_DEBUG_SPEW
|
|
#endif
|
|
|
|
/// How strict will the pure server be for a particular set of files
|
|
enum EPureServerFileClass {
|
|
ePureServerFileClass_Unknown = -1, // dummy debugging value
|
|
ePureServerFileClass_Any = 0,
|
|
ePureServerFileClass_AnyTrusted,
|
|
ePureServerFileClass_CheckHash,
|
|
};
|
|
|
|
class IPureServerWhitelist {
|
|
public:
|
|
// Reference counting
|
|
virtual void AddRef() = 0;
|
|
virtual void Release() = 0;
|
|
|
|
// What should we do with a particular file?
|
|
virtual EPureServerFileClass GetFileClass(const char *pszFilename) = 0;
|
|
|
|
// Access list of trusted keys which we will allow to set trusted content
|
|
virtual int GetTrustedKeyCount() const = 0;
|
|
virtual const byte *GetTrustedKey(int iKeyIndex, int *nKeySize) const = 0;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Enums used by the interface
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#define FILESYSTEM_MAX_SEARCH_PATHS 128
|
|
|
|
enum FileSystemSeek_t {
|
|
FILESYSTEM_SEEK_HEAD = SEEK_SET,
|
|
FILESYSTEM_SEEK_CURRENT = SEEK_CUR,
|
|
FILESYSTEM_SEEK_TAIL = SEEK_END,
|
|
};
|
|
|
|
enum { FILESYSTEM_INVALID_FIND_HANDLE = -1 };
|
|
|
|
enum FileWarningLevel_t {
|
|
// A problem!
|
|
FILESYSTEM_WARNING = -1,
|
|
|
|
// Don't print anything
|
|
FILESYSTEM_WARNING_QUIET = 0,
|
|
|
|
// On shutdown, report names of files left unclosed
|
|
FILESYSTEM_WARNING_REPORTUNCLOSED,
|
|
|
|
// Report number of times a file was opened, closed
|
|
FILESYSTEM_WARNING_REPORTUSAGE,
|
|
|
|
// Report all open/close events to console ( !slow! )
|
|
FILESYSTEM_WARNING_REPORTALLACCESSES,
|
|
|
|
// Report all open/close/read events to the console ( !slower! )
|
|
FILESYSTEM_WARNING_REPORTALLACCESSES_READ,
|
|
|
|
// Report all open/close/read/write events to the console ( !slower! )
|
|
FILESYSTEM_WARNING_REPORTALLACCESSES_READWRITE,
|
|
|
|
// Report all open/close/read/write events and all async I/O file events to
|
|
// the console ( !slower(est)! )
|
|
FILESYSTEM_WARNING_REPORTALLACCESSES_ASYNC,
|
|
|
|
};
|
|
|
|
// search path filtering
|
|
enum PathTypeFilter_t {
|
|
FILTER_NONE = 0, // no filtering, all search path types match
|
|
FILTER_CULLPACK = 1, // pack based search paths are culled (maps and zips)
|
|
FILTER_CULLNONPACK = 2, // non-pack based search paths are culled
|
|
};
|
|
|
|
// search path querying (bit flags)
|
|
enum {
|
|
PATH_IS_NORMAL = 0x00, // normal path, not pack based
|
|
PATH_IS_PACKFILE = 0x01, // path is a pack file
|
|
PATH_IS_MAPPACKFILE = 0x02, // path is a map pack file
|
|
PATH_IS_REMOTE = 0x04, // path is the remote filesystem
|
|
};
|
|
typedef uint32 PathTypeQuery_t;
|
|
|
|
#define IS_PACKFILE(n) (n & (PATH_IS_PACKFILE | PATH_IS_MAPPACKFILE))
|
|
#define IS_REMOTE(n) (n & PATH_IS_REMOTE)
|
|
|
|
enum DVDMode_t {
|
|
DVDMODE_OFF = 0, // not using dvd
|
|
DVDMODE_STRICT = 1, // dvd device only
|
|
DVDMODE_DEV = 2, // dev mode, mutiple devices ok
|
|
};
|
|
|
|
// In non-retail builds, enable the file blocking access tracking stuff...
|
|
#if defined(TRACK_BLOCKING_IO)
|
|
enum FileBlockingWarning_t {
|
|
// Report how long synchronous i/o took to complete
|
|
FILESYSTEM_BLOCKING_SYNCHRONOUS = 0,
|
|
// Report how long async i/o took to complete if AsyncFileFinished caused it
|
|
// to load via "blocking" i/o
|
|
FILESYSTEM_BLOCKING_ASYNCHRONOUS_BLOCK,
|
|
// Report how long async i/o took to complete
|
|
FILESYSTEM_BLOCKING_ASYNCHRONOUS,
|
|
// Report how long the async "callback" took
|
|
FILESYSTEM_BLOCKING_CALLBACKTIMING,
|
|
|
|
FILESYSTEM_BLOCKING_NUMBINS,
|
|
};
|
|
|
|
#pragma pack(1)
|
|
class FileBlockingItem {
|
|
public:
|
|
enum {
|
|
FB_ACCESS_OPEN = 1,
|
|
FB_ACCESS_CLOSE = 2,
|
|
FB_ACCESS_READ = 3,
|
|
FB_ACCESS_WRITE = 4,
|
|
FB_ACCESS_APPEND = 5,
|
|
FB_ACCESS_SIZE = 6
|
|
};
|
|
|
|
FileBlockingItem()
|
|
: m_ItemType((FileBlockingWarning_t)0),
|
|
m_flElapsed(0.0f),
|
|
m_nAccessType(0) {
|
|
SetFileName(NULL);
|
|
}
|
|
|
|
FileBlockingItem(int type, char const *filename, float elapsed,
|
|
int accessType)
|
|
: m_ItemType((FileBlockingWarning_t)type),
|
|
m_flElapsed(elapsed),
|
|
m_nAccessType(accessType) {
|
|
SetFileName(filename);
|
|
}
|
|
|
|
void SetFileName(char const *filename) {
|
|
if (!filename) {
|
|
m_szFilename[0] = 0;
|
|
return;
|
|
}
|
|
|
|
int len = Q_strlen(filename);
|
|
if (len >= sizeof(m_szFilename)) {
|
|
Q_strncpy(m_szFilename, &filename[len - sizeof(m_szFilename) + 1],
|
|
sizeof(m_szFilename));
|
|
} else {
|
|
Q_strncpy(m_szFilename, filename, sizeof(m_szFilename));
|
|
}
|
|
}
|
|
|
|
char const *GetFileName() const { return m_szFilename; }
|
|
|
|
FileBlockingWarning_t m_ItemType;
|
|
float m_flElapsed;
|
|
byte m_nAccessType;
|
|
|
|
private:
|
|
char m_szFilename[32];
|
|
};
|
|
#pragma pack()
|
|
|
|
class IBlockingFileItemList {
|
|
public:
|
|
// You can't call any of the below calls without locking first
|
|
virtual void LockMutex() = 0;
|
|
virtual void UnlockMutex() = 0;
|
|
|
|
virtual int First() const = 0;
|
|
virtual int Next(int i) const = 0;
|
|
virtual int InvalidIndex() const = 0;
|
|
|
|
virtual const FileBlockingItem &Get(int index) const = 0;
|
|
|
|
virtual void Reset() = 0;
|
|
};
|
|
|
|
#endif // TRACK_BLOCKING_IO
|
|
|
|
enum FilesystemMountRetval_t {
|
|
FILESYSTEM_MOUNT_OK = 0,
|
|
FILESYSTEM_MOUNT_FAILED,
|
|
};
|
|
|
|
enum SearchPathAdd_t {
|
|
PATH_ADD_TO_HEAD, // First path searched
|
|
PATH_ADD_TO_TAIL, // Last path searched
|
|
};
|
|
|
|
enum FilesystemOpenExFlags_t {
|
|
FSOPEN_UNBUFFERED = (1 << 0),
|
|
FSOPEN_FORCE_TRACK_CRC =
|
|
(1 << 1), // This makes it calculate a CRC for the file (if the file
|
|
// came from disk) regardless of the IFileList passed to
|
|
// RegisterFileWhitelist.
|
|
FSOPEN_NEVERINPACK = (1 << 2), // 360 only, hint to FS that file is not
|
|
// allowed to be in pack file
|
|
};
|
|
|
|
#define FILESYSTEM_INVALID_HANDLE (FileHandle_t)0
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Structures used by the interface
|
|
//-----------------------------------------------------------------------------
|
|
|
|
struct FileSystemStatistics {
|
|
CInterlockedUInt nReads, nWrites, nBytesRead, nBytesWritten, nSeeks;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// File system allocation functions. Client must free on failure
|
|
//-----------------------------------------------------------------------------
|
|
typedef void *(*FSAllocFunc_t)(const char *pszFilename, unsigned nBytes);
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Used to display dirty disk error functions
|
|
//-----------------------------------------------------------------------------
|
|
typedef void (*FSDirtyDiskReportFunc_t)();
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Asynchronous support types
|
|
//-----------------------------------------------------------------------------
|
|
DECLARE_POINTER_HANDLE(FSAsyncControl_t);
|
|
DECLARE_POINTER_HANDLE(FSAsyncFile_t);
|
|
const FSAsyncFile_t FS_INVALID_ASYNC_FILE = (FSAsyncFile_t)(0x0000ffff);
|
|
|
|
//---------------------------------------------------------
|
|
// Async file status
|
|
//---------------------------------------------------------
|
|
enum FSAsyncStatus_t {
|
|
FSASYNC_ERR_NOT_MINE =
|
|
-8, // Filename not part of the specified file system, try a different
|
|
// one. (Used internally to find the right filesystem)
|
|
FSASYNC_ERR_RETRY_LATER =
|
|
-7, // Failure for a reason that might be temporary. You might retry,
|
|
// but not immediately. (E.g. Network problems)
|
|
FSASYNC_ERR_ALIGNMENT = -6, // read parameters invalid for unbuffered IO
|
|
FSASYNC_ERR_FAILURE = -5, // hard subsystem failure
|
|
FSASYNC_ERR_READING = -4, // read error on file
|
|
FSASYNC_ERR_NOMEMORY = -3, // out of memory for file read
|
|
FSASYNC_ERR_UNKNOWNID = -2, // caller's provided id is not recognized
|
|
FSASYNC_ERR_FILEOPEN =
|
|
-1, // filename could not be opened (bad path, not exist, etc)
|
|
FSASYNC_OK = 0, // operation is successful
|
|
FSASYNC_STATUS_PENDING, // file is properly queued, waiting for service
|
|
FSASYNC_STATUS_INPROGRESS, // file is being accessed
|
|
FSASYNC_STATUS_ABORTED, // file was aborted by caller
|
|
FSASYNC_STATUS_UNSERVICED, // file is not yet queued
|
|
};
|
|
|
|
//---------------------------------------------------------
|
|
// Async request flags
|
|
//---------------------------------------------------------
|
|
enum FSAsyncFlags_t {
|
|
FSASYNC_FLAGS_ALLOCNOFREE =
|
|
(1 << 0), // do the allocation for dataPtr, but don't free
|
|
FSASYNC_FLAGS_FREEDATAPTR =
|
|
(1 << 1), // free the memory for the dataPtr post callback
|
|
FSASYNC_FLAGS_SYNC =
|
|
(1 << 2), // Actually perform the operation synchronously. Used to
|
|
// simplify client code paths
|
|
FSASYNC_FLAGS_NULLTERMINATE =
|
|
(1
|
|
<< 3), // allocate an extra byte and null terminate the buffer read in
|
|
};
|
|
|
|
//---------------------------------------------------------
|
|
// Return value for CheckFileCRC.
|
|
//---------------------------------------------------------
|
|
enum EFileCRCStatus {
|
|
k_eFileCRCStatus_CantOpenFile, // We don't have this file.
|
|
k_eFileCRCStatus_GotCRC,
|
|
k_eFileCRCStatus_FileInVPK
|
|
};
|
|
|
|
// Used in CacheFileCRCs.
|
|
enum ECacheCRCType {
|
|
k_eCacheCRCType_SingleFile,
|
|
k_eCacheCRCType_Directory,
|
|
k_eCacheCRCType_Directory_Recursive
|
|
};
|
|
|
|
//---------------------------------------------------------
|
|
// Optional completion callback for each async file serviced (or failed)
|
|
// call is not reentrant, async i/o guaranteed suspended until return
|
|
// Note: If you change the signature of the callback, you will have to account
|
|
// for it in FileSystemV12 (toml [4/18/2005] )
|
|
//---------------------------------------------------------
|
|
struct FileAsyncRequest_t;
|
|
typedef void (*FSAsyncCallbackFunc_t)(const FileAsyncRequest_t &request,
|
|
int nBytesRead, FSAsyncStatus_t err);
|
|
|
|
//---------------------------------------------------------
|
|
// Description of an async request
|
|
//---------------------------------------------------------
|
|
struct FileAsyncRequest_t {
|
|
FileAsyncRequest_t() {
|
|
memset(this, 0, sizeof(*this));
|
|
hSpecificAsyncFile = FS_INVALID_ASYNC_FILE;
|
|
}
|
|
const char *pszFilename; // file system name
|
|
void *pData; // optional, system will alloc/free if NULL
|
|
int nOffset; // optional initial seek_set, 0=beginning
|
|
int nBytes; // optional read clamp, -1=exist test, 0=full read
|
|
FSAsyncCallbackFunc_t pfnCallback; // optional completion callback
|
|
void *pContext; // caller's unique file identifier
|
|
int priority; // inter list priority, 0=lowest
|
|
unsigned flags; // behavior modifier
|
|
const char
|
|
*pszPathID; // path ID (NOTE: this field is here to remain binary
|
|
// compatible with release HL2 filesystem interface)
|
|
FSAsyncFile_t
|
|
hSpecificAsyncFile; // Optional hint obtained using AsyncBeginRead()
|
|
FSAllocFunc_t pfnAlloc; // custom allocator. can be null. not compatible
|
|
// with FSASYNC_FLAGS_FREEDATAPTR
|
|
};
|
|
|
|
struct FileHash_t {
|
|
enum EFileHashType_t {
|
|
k_EFileHashTypeUnknown = 0,
|
|
k_EFileHashTypeEntireFile = 1,
|
|
k_EFileHashTypeIncompleteFile = 2,
|
|
};
|
|
FileHash_t() {
|
|
m_eFileHashType = FileHash_t::k_EFileHashTypeUnknown;
|
|
m_cbFileLen = 0;
|
|
m_PackFileID = 0;
|
|
m_nPackFileNumber = 0;
|
|
}
|
|
int m_eFileHashType;
|
|
CRC32_t m_crcIOSequence;
|
|
MD5Value_t m_md5contents;
|
|
int m_cbFileLen;
|
|
int m_PackFileID;
|
|
int m_nPackFileNumber;
|
|
|
|
bool operator==(const FileHash_t &src) const {
|
|
return m_crcIOSequence == src.m_crcIOSequence &&
|
|
m_md5contents == src.m_md5contents &&
|
|
m_eFileHashType == src.m_eFileHashType;
|
|
}
|
|
bool operator!=(const FileHash_t &src) const {
|
|
return m_crcIOSequence != src.m_crcIOSequence ||
|
|
m_md5contents != src.m_md5contents ||
|
|
m_eFileHashType != src.m_eFileHashType;
|
|
}
|
|
};
|
|
|
|
class CUnverifiedFileHash {
|
|
public:
|
|
char m_PathID[MAX_PATH];
|
|
char m_Filename[MAX_PATH];
|
|
int m_nFileFraction;
|
|
FileHash_t m_FileHash;
|
|
};
|
|
|
|
class CUnverifiedCRCFile {
|
|
public:
|
|
char m_PathID[MAX_PATH];
|
|
char m_Filename[MAX_PATH];
|
|
CRC32_t m_CRC;
|
|
};
|
|
|
|
class CUnverifiedMD5File {
|
|
public:
|
|
char m_PathID[MAX_PATH];
|
|
char m_Filename[MAX_PATH];
|
|
unsigned char bits[MD5_DIGEST_LENGTH];
|
|
};
|
|
|
|
// Spew flags for SetWhitelistSpewFlags (set with the fs_whitelist_spew_flags
|
|
// cvar). Update the comment for the fs_whitelist_spew_flags cvar if you change
|
|
// these.
|
|
#define WHITELIST_SPEW_WHILE_LOADING \
|
|
0x0001 // list files as they are added to the CRC tracker
|
|
#define WHITELIST_SPEW_RELOAD_FILES \
|
|
0x0002 // show files the filesystem is telling the engine to reload
|
|
#define WHITELIST_SPEW_DONT_RELOAD_FILES \
|
|
0x0004 // show files the filesystem is NOT telling the engine to reload
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Interface to fetch a file asynchronously from any source. This is used
|
|
// as a hook
|
|
//-----------------------------------------------------------------------------
|
|
|
|
abstract_class IAsyncFileFetch {
|
|
public:
|
|
typedef void *Handle;
|
|
|
|
/// Initiate a request. Returns error status, or on success
|
|
/// returns an opaque handle used to terminate the job
|
|
///
|
|
/// Should return FSASYNC_ERR_NOT_MINE if the filename isn't
|
|
/// handled by this interface
|
|
///
|
|
/// The callback is required, and is the only mechanism to communicate
|
|
/// status. (No polling.) The request is automatically destroyed anytime
|
|
/// after the callback is executed.
|
|
virtual FSAsyncStatus_t Start(const FileAsyncRequest_t &request,
|
|
Handle *pOutHandle,
|
|
IThreadPool *pThreadPool) = 0;
|
|
|
|
/// Attempt to complete any active work, returning status. The callback
|
|
/// WILL be executed (this is necessary in case we allocated the buffer).
|
|
/// Afterwards, the request is automatically destroyed.
|
|
virtual FSAsyncStatus_t FinishSynchronous(Handle hControl) = 0;
|
|
|
|
/// Terminate any active work and destroy all resources and bookkeeping
|
|
/// info. The callback will NOT be executed.
|
|
virtual FSAsyncStatus_t Abort(Handle hControl) = 0;
|
|
};
|
|
|
|
// This interface is for VPK files to communicate with FileTracker
|
|
abstract_class IThreadedFileMD5Processor {
|
|
public:
|
|
virtual int SubmitThreadedMD5Request(uint8 * pubBuffer, int cubBuffer,
|
|
int PackFileID, int nPackFileNumber,
|
|
int nPackFileFraction) = 0;
|
|
virtual bool BlockUntilMD5RequestComplete(int iRequest,
|
|
MD5Value_t *pMd5ValueOut) = 0;
|
|
virtual bool IsMD5RequestComplete(int iRequest,
|
|
MD5Value_t *pMd5ValueOut) = 0;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Base file system interface
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// This is the minimal interface that can be implemented to provide access to
|
|
// a named set of files.
|
|
#define BASEFILESYSTEM_INTERFACE_VERSION "VBaseFileSystem011"
|
|
|
|
abstract_class IBaseFileSystem {
|
|
public:
|
|
virtual int Read(void *pOutput, int size, FileHandle_t file) = 0;
|
|
virtual int Write(void const *pInput, int size, FileHandle_t file) = 0;
|
|
|
|
// if pathID is NULL, all paths will be searched for the file
|
|
virtual FileHandle_t Open(const char *pFileName, const char *pOptions,
|
|
const char *pathID = 0) = 0;
|
|
virtual void Close(FileHandle_t file) = 0;
|
|
|
|
virtual void Seek(FileHandle_t file, int pos,
|
|
FileSystemSeek_t seekType) = 0;
|
|
virtual unsigned int Tell(FileHandle_t file) = 0;
|
|
virtual unsigned int Size(FileHandle_t file) = 0;
|
|
virtual unsigned int Size(const char *pFileName,
|
|
const char *pPathID = 0) = 0;
|
|
|
|
virtual void Flush(FileHandle_t file) = 0;
|
|
virtual bool Precache(const char *pFileName, const char *pPathID = 0) = 0;
|
|
|
|
virtual bool FileExists(const char *pFileName, const char *pPathID = 0) = 0;
|
|
virtual bool IsFileWritable(char const *pFileName,
|
|
const char *pPathID = 0) = 0;
|
|
virtual bool SetFileWritable(char const *pFileName, bool writable,
|
|
const char *pPathID = 0) = 0;
|
|
|
|
virtual long GetFileTime(const char *pFileName,
|
|
const char *pPathID = 0) = 0;
|
|
|
|
//--------------------------------------------------------
|
|
// Reads/writes files to utlbuffers. Use this for optimal read performance
|
|
// when doing open/read/close
|
|
//--------------------------------------------------------
|
|
virtual bool ReadFile(const char *pFileName, const char *pPath,
|
|
CUtlBuffer &buf, int nMaxBytes = 0,
|
|
int nStartingByte = 0,
|
|
FSAllocFunc_t pfnAlloc = NULL) = 0;
|
|
virtual bool WriteFile(const char *pFileName, const char *pPath,
|
|
CUtlBuffer &buf) = 0;
|
|
virtual bool UnzipFile(const char *pFileName, const char *pPath,
|
|
const char *pDestination) = 0;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Main file system interface
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#define FILESYSTEM_INTERFACE_VERSION "VFileSystem022"
|
|
|
|
abstract_class IFileSystem : public IAppSystem, public IBaseFileSystem {
|
|
public:
|
|
//--------------------------------------------------------
|
|
// Steam operations
|
|
//--------------------------------------------------------
|
|
|
|
virtual bool IsSteam() const = 0;
|
|
|
|
// Supplying an extra app id will mount this app in addition
|
|
// to the one specified in the environment variable "steamappid"
|
|
//
|
|
// If nExtraAppId is < -1, then it will mount that app ID only.
|
|
// (Was needed by the dedicated server b/c the "SteamAppId" env var only
|
|
// gets passed to steam.dll at load time, so the dedicated couldn't pass it
|
|
// in that way).
|
|
virtual FilesystemMountRetval_t MountSteamContent(int nExtraAppId = -1) = 0;
|
|
|
|
//--------------------------------------------------------
|
|
// Search path manipulation
|
|
//--------------------------------------------------------
|
|
|
|
// Add paths in priority order (mod dir, game dir, ....)
|
|
// If one or more .pak files are in the specified directory, then they are
|
|
// added after the file system path
|
|
// If the path is the relative path to a .bsp file, then any previous .bsp
|
|
// file
|
|
// override is cleared and the current .bsp is searched for an embedded PAK
|
|
// file and this file becomes the highest priority search path ( i.e., it's
|
|
// looked at first
|
|
// even before the mod's file system path ).
|
|
virtual void AddSearchPath(const char *pPath, const char *pathID,
|
|
SearchPathAdd_t addType = PATH_ADD_TO_TAIL) = 0;
|
|
virtual bool RemoveSearchPath(const char *pPath,
|
|
const char *pathID = 0) = 0;
|
|
|
|
// Remove all search paths (including write path?)
|
|
virtual void RemoveAllSearchPaths(void) = 0;
|
|
|
|
// Remove search paths associated with a given pathID
|
|
virtual void RemoveSearchPaths(const char *szPathID) = 0;
|
|
|
|
// This is for optimization. If you mark a path ID as "by request only",
|
|
// then files inside it will only be accessed if the path ID is specifically
|
|
// requested. Otherwise, it will be ignored. If there are currently no
|
|
// search paths with the specified path ID, then it will still remember it
|
|
// in case you add search paths with this path ID.
|
|
virtual void MarkPathIDByRequestOnly(const char *pPathID,
|
|
bool bRequestOnly) = 0;
|
|
|
|
// converts a partial path into a full path
|
|
// Prefer using the RelativePathToFullPath_safe template wrapper to calling
|
|
// this directly
|
|
virtual const char *RelativePathToFullPath(
|
|
const char *pFileName, const char *pPathID,
|
|
OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars,
|
|
PathTypeFilter_t pathFilter = FILTER_NONE,
|
|
PathTypeQuery_t *pPathType = NULL) = 0;
|
|
template <size_t maxLenInChars>
|
|
const char *RelativePathToFullPath_safe(
|
|
const char *pFileName, const char *pPathID,
|
|
OUT_Z_ARRAY char(&pDest)[maxLenInChars],
|
|
PathTypeFilter_t pathFilter = FILTER_NONE,
|
|
PathTypeQuery_t * pPathType = NULL) {
|
|
return RelativePathToFullPath(pFileName, pPathID, pDest,
|
|
(int)maxLenInChars, pathFilter,
|
|
pPathType);
|
|
}
|
|
|
|
// Returns the search path, each path is separated by ;s. Returns the length
|
|
// of the string returned Prefer using the GetSearchPath_safe template
|
|
// wrapper to calling this directly
|
|
virtual int GetSearchPath(const char *pathID, bool bGetPackFiles,
|
|
OUT_Z_CAP(maxLenInChars) char *pDest,
|
|
int maxLenInChars) = 0;
|
|
template <size_t maxLenInChars>
|
|
int GetSearchPath_safe(const char *pathID, bool bGetPackFiles,
|
|
OUT_Z_ARRAY char(&pDest)[maxLenInChars]) {
|
|
return GetSearchPath(pathID, bGetPackFiles, pDest, (int)maxLenInChars);
|
|
}
|
|
|
|
// interface for custom pack files > 4Gb
|
|
virtual bool AddPackFile(const char *fullpath, const char *pathID) = 0;
|
|
|
|
//--------------------------------------------------------
|
|
// File manipulation operations
|
|
//--------------------------------------------------------
|
|
|
|
// Deletes a file (on the WritePath)
|
|
virtual void RemoveFile(char const *pRelativePath,
|
|
const char *pathID = 0) = 0;
|
|
|
|
// Renames a file (on the WritePath)
|
|
virtual bool RenameFile(char const *pOldPath, char const *pNewPath,
|
|
const char *pathID = 0) = 0;
|
|
|
|
// create a local directory structure
|
|
virtual void CreateDirHierarchy(const char *path,
|
|
const char *pathID = 0) = 0;
|
|
|
|
// File I/O and info
|
|
virtual bool IsDirectory(const char *pFileName, const char *pathID = 0) = 0;
|
|
|
|
virtual void FileTimeToString(char *pStrip, int maxCharsIncludingTerminator,
|
|
long fileTime) = 0;
|
|
|
|
//--------------------------------------------------------
|
|
// Open file operations
|
|
//--------------------------------------------------------
|
|
|
|
virtual void SetBufferSize(FileHandle_t file, unsigned nBytes) = 0;
|
|
|
|
virtual bool IsOk(FileHandle_t file) = 0;
|
|
|
|
virtual bool EndOfFile(FileHandle_t file) = 0;
|
|
|
|
virtual char *ReadLine(char *pOutput, int maxChars, FileHandle_t file) = 0;
|
|
virtual int FPrintf(FileHandle_t file,
|
|
PRINTF_FORMAT_STRING const char *pFormat, ...) = 0;
|
|
|
|
//--------------------------------------------------------
|
|
// Dynamic library operations
|
|
//--------------------------------------------------------
|
|
|
|
// load/unload modules
|
|
virtual CSysModule *LoadModule(const char *pFileName,
|
|
const char *pPathID = 0,
|
|
bool bValidatedDllOnly = true) = 0;
|
|
virtual void UnloadModule(CSysModule * pModule) = 0;
|
|
|
|
//--------------------------------------------------------
|
|
// File searching operations
|
|
//--------------------------------------------------------
|
|
|
|
// FindFirst/FindNext. Also see FindFirstEx.
|
|
virtual const char *FindFirst(const char *pWildCard,
|
|
FileFindHandle_t *pHandle) = 0;
|
|
virtual const char *FindNext(FileFindHandle_t handle) = 0;
|
|
virtual bool FindIsDirectory(FileFindHandle_t handle) = 0;
|
|
virtual void FindClose(FileFindHandle_t handle) = 0;
|
|
|
|
// Same as FindFirst, but you can filter by path ID, which can make it
|
|
// faster.
|
|
virtual const char *FindFirstEx(const char *pWildCard, const char *pPathID,
|
|
FileFindHandle_t *pHandle) = 0;
|
|
|
|
//--------------------------------------------------------
|
|
// File name and directory operations
|
|
//--------------------------------------------------------
|
|
|
|
// FIXME: This method is obsolete! Use RelativePathToFullPath instead!
|
|
// converts a partial path into a full path
|
|
// Prefer using the GetLocalPath_safe template wrapper to calling this
|
|
// directly
|
|
virtual const char *GetLocalPath(const char *pFileName,
|
|
OUT_Z_CAP(maxLenInChars) char *pDest,
|
|
int maxLenInChars) = 0;
|
|
template <size_t maxLenInChars>
|
|
const char *GetLocalPath_safe(const char *pFileName,
|
|
OUT_Z_ARRAY char(&pDest)[maxLenInChars]) {
|
|
return GetLocalPath(pFileName, pDest, (int)maxLenInChars);
|
|
}
|
|
|
|
// Returns true on success ( based on current list of search paths,
|
|
// otherwise false if
|
|
// it can't be resolved )
|
|
// Prefer using the FullPathToRelativePath_safe template wrapper to calling
|
|
// this directly
|
|
virtual bool FullPathToRelativePath(const char *pFullpath,
|
|
OUT_Z_CAP(maxLenInChars) char *pDest,
|
|
int maxLenInChars) = 0;
|
|
template <size_t maxLenInChars>
|
|
bool FullPathToRelativePath_safe(const char *pFullpath,
|
|
OUT_Z_ARRAY char(&pDest)[maxLenInChars]) {
|
|
return FullPathToRelativePath(pFullpath, pDest, (int)maxLenInChars);
|
|
}
|
|
|
|
// Gets the current working directory
|
|
virtual bool GetCurrentDirectory(char *pDirectory, int maxlen) = 0;
|
|
|
|
//--------------------------------------------------------
|
|
// Filename dictionary operations
|
|
//--------------------------------------------------------
|
|
|
|
virtual FileNameHandle_t FindOrAddFileName(char const *pFileName) = 0;
|
|
virtual bool String(const FileNameHandle_t &handle, char *buf,
|
|
int buflen) = 0;
|
|
|
|
//--------------------------------------------------------
|
|
// Asynchronous file operations
|
|
//--------------------------------------------------------
|
|
|
|
//------------------------------------
|
|
// Global operations
|
|
//------------------------------------
|
|
FSAsyncStatus_t AsyncRead(const FileAsyncRequest_t &request,
|
|
FSAsyncControl_t *phControl = NULL) {
|
|
return AsyncReadMultiple(&request, 1, phControl);
|
|
}
|
|
virtual FSAsyncStatus_t AsyncReadMultiple(
|
|
const FileAsyncRequest_t *pRequests, int nRequests,
|
|
FSAsyncControl_t *phControls = NULL) = 0;
|
|
virtual FSAsyncStatus_t AsyncAppend(const char *pFileName, const void *pSrc,
|
|
int nSrcBytes, bool bFreeMemory,
|
|
FSAsyncControl_t *pControl = NULL) = 0;
|
|
virtual FSAsyncStatus_t AsyncAppendFile(
|
|
const char *pAppendToFileName, const char *pAppendFromFileName,
|
|
FSAsyncControl_t *pControl = NULL) = 0;
|
|
virtual void AsyncFinishAll(int iToPriority = 0) = 0;
|
|
virtual void AsyncFinishAllWrites() = 0;
|
|
virtual FSAsyncStatus_t AsyncFlush() = 0;
|
|
virtual bool AsyncSuspend() = 0;
|
|
virtual bool AsyncResume() = 0;
|
|
|
|
/// Add async fetcher interface. This gives apps a hook to intercept async
|
|
/// requests and pull the data from a source of their choosing. The
|
|
/// immediate use case is to load assets from the CDN via HTTP.
|
|
virtual void AsyncAddFetcher(IAsyncFileFetch * pFetcher) = 0;
|
|
virtual void AsyncRemoveFetcher(IAsyncFileFetch * pFetcher) = 0;
|
|
|
|
//------------------------------------
|
|
// Functions to hold a file open if planning on doing mutiple reads. Use is
|
|
// optional, and is taken only as a hint
|
|
//------------------------------------
|
|
virtual FSAsyncStatus_t AsyncBeginRead(const char *pszFile,
|
|
FSAsyncFile_t *phFile) = 0;
|
|
virtual FSAsyncStatus_t AsyncEndRead(FSAsyncFile_t hFile) = 0;
|
|
|
|
//------------------------------------
|
|
// Request management
|
|
//------------------------------------
|
|
virtual FSAsyncStatus_t AsyncFinish(FSAsyncControl_t hControl,
|
|
bool wait = true) = 0;
|
|
virtual FSAsyncStatus_t AsyncGetResult(FSAsyncControl_t hControl,
|
|
void **ppData, int *pSize) = 0;
|
|
virtual FSAsyncStatus_t AsyncAbort(FSAsyncControl_t hControl) = 0;
|
|
virtual FSAsyncStatus_t AsyncStatus(FSAsyncControl_t hControl) = 0;
|
|
// set a new priority for a file already in the queue
|
|
virtual FSAsyncStatus_t AsyncSetPriority(FSAsyncControl_t hControl,
|
|
int newPriority) = 0;
|
|
virtual void AsyncAddRef(FSAsyncControl_t hControl) = 0;
|
|
virtual void AsyncRelease(FSAsyncControl_t hControl) = 0;
|
|
|
|
//--------------------------------------------------------
|
|
// Remote resource management
|
|
//--------------------------------------------------------
|
|
|
|
// starts waiting for resources to be available
|
|
// returns FILESYSTEM_INVALID_HANDLE if there is nothing to wait on
|
|
virtual WaitForResourcesHandle_t WaitForResources(
|
|
const char *resourcelist) = 0;
|
|
// get progress on waiting for resources; progress is a float [0, 1],
|
|
// complete is true on the waiting being done returns false if no progress
|
|
// is available any calls after complete is true or on an invalid handle
|
|
// will return false, 0.0f, true
|
|
virtual bool GetWaitForResourcesProgress(WaitForResourcesHandle_t handle,
|
|
float *progress /* out */,
|
|
bool *complete /* out */) = 0;
|
|
// cancels a progress call
|
|
virtual void CancelWaitForResources(WaitForResourcesHandle_t handle) = 0;
|
|
|
|
// hints that a set of files will be loaded in near future
|
|
// HintResourceNeed() is not to be confused with resource precaching.
|
|
virtual int HintResourceNeed(const char *hintlist,
|
|
int forgetEverything) = 0;
|
|
// returns true if a file is on disk
|
|
virtual bool IsFileImmediatelyAvailable(const char *pFileName) = 0;
|
|
|
|
// copies file out of pak/bsp/steam cache onto disk (to be accessible by
|
|
// third-party code)
|
|
virtual void GetLocalCopy(const char *pFileName) = 0;
|
|
|
|
//--------------------------------------------------------
|
|
// Debugging operations
|
|
//--------------------------------------------------------
|
|
|
|
// Dump to printf/OutputDebugString the list of files that have not been
|
|
// closed
|
|
virtual void PrintOpenedFiles(void) = 0;
|
|
virtual void PrintSearchPaths(void) = 0;
|
|
|
|
// output
|
|
virtual void SetWarningFunc(
|
|
void (*pfnWarning)(PRINTF_FORMAT_STRING const char *fmt, ...)) = 0;
|
|
virtual void SetWarningLevel(FileWarningLevel_t level) = 0;
|
|
virtual void AddLoggingFunc(
|
|
void (*pfnLogFunc)(const char *fileName, const char *accessType)) = 0;
|
|
virtual void RemoveLoggingFunc(FileSystemLoggingFunc_t logFunc) = 0;
|
|
|
|
// Returns the file system statistics retreived by the implementation.
|
|
// Returns NULL if not supported.
|
|
virtual const FileSystemStatistics *GetFilesystemStatistics() = 0;
|
|
|
|
//--------------------------------------------------------
|
|
// Start of new functions after Lost Coast release (7/05)
|
|
//--------------------------------------------------------
|
|
|
|
virtual FileHandle_t OpenEx(const char *pFileName, const char *pOptions,
|
|
unsigned flags = 0, const char *pathID = 0,
|
|
char **ppszResolvedFilename = NULL) = 0;
|
|
|
|
// Extended version of read provides more context to allow for more optimal
|
|
// reading
|
|
virtual int ReadEx(void *pOutput, int sizeDest, int size,
|
|
FileHandle_t file) = 0;
|
|
virtual int ReadFileEx(const char *pFileName, const char *pPath,
|
|
void **ppBuf, bool bNullTerminate = false,
|
|
bool bOptimalAlloc = false, int nMaxBytes = 0,
|
|
int nStartingByte = 0,
|
|
FSAllocFunc_t pfnAlloc = NULL) = 0;
|
|
|
|
virtual FileNameHandle_t FindFileName(char const *pFileName) = 0;
|
|
|
|
#if defined(TRACK_BLOCKING_IO)
|
|
virtual void EnableBlockingFileAccessTracking(bool state) = 0;
|
|
virtual bool IsBlockingFileAccessEnabled() const = 0;
|
|
|
|
virtual IBlockingFileItemList *RetrieveBlockingFileAccessInfo() = 0;
|
|
#endif
|
|
|
|
virtual void SetupPreloadData() = 0;
|
|
virtual void DiscardPreloadData() = 0;
|
|
|
|
// Fixme, we could do these via a string embedded into the compiled data,
|
|
// etc...
|
|
enum KeyValuesPreloadType_t {
|
|
TYPE_VMT,
|
|
TYPE_SOUNDEMITTER,
|
|
TYPE_SOUNDSCAPE,
|
|
NUM_PRELOAD_TYPES
|
|
};
|
|
|
|
virtual void LoadCompiledKeyValues(KeyValuesPreloadType_t type,
|
|
char const *archiveFile) = 0;
|
|
|
|
// If the "PreloadedData" hasn't been purged, then this'll try and instance
|
|
// the KeyValues using the fast path of compiled keyvalues loaded during
|
|
// startup. Otherwise, it'll just fall through to the regular KeyValues
|
|
// loading routines
|
|
virtual KeyValues *LoadKeyValues(KeyValuesPreloadType_t type,
|
|
char const *filename,
|
|
char const *pPathID = 0) = 0;
|
|
virtual bool LoadKeyValues(KeyValues & head, KeyValuesPreloadType_t type,
|
|
char const *filename,
|
|
char const *pPathID = 0) = 0;
|
|
virtual bool ExtractRootKeyName(KeyValuesPreloadType_t type, char *outbuf,
|
|
size_t bufsize, char const *filename,
|
|
char const *pPathID = 0) = 0;
|
|
|
|
virtual FSAsyncStatus_t AsyncWrite(const char *pFileName, const void *pSrc,
|
|
int nSrcBytes, bool bFreeMemory,
|
|
bool bAppend = false,
|
|
FSAsyncControl_t *pControl = NULL) = 0;
|
|
virtual FSAsyncStatus_t AsyncWriteFile(
|
|
const char *pFileName, const CUtlBuffer *pSrc, int nSrcBytes,
|
|
bool bFreeMemory, bool bAppend = false,
|
|
FSAsyncControl_t *pControl = NULL) = 0;
|
|
// Async read functions with memory blame
|
|
FSAsyncStatus_t AsyncReadCreditAlloc(const FileAsyncRequest_t &request,
|
|
const char *pszFile, int line,
|
|
FSAsyncControl_t *phControl = NULL) {
|
|
return AsyncReadMultipleCreditAlloc(&request, 1, pszFile, line,
|
|
phControl);
|
|
}
|
|
virtual FSAsyncStatus_t AsyncReadMultipleCreditAlloc(
|
|
const FileAsyncRequest_t *pRequests, int nRequests, const char *pszFile,
|
|
int line, FSAsyncControl_t *phControls = NULL) = 0;
|
|
|
|
virtual bool GetFileTypeForFullPath(
|
|
char const *pFullPath, OUT_Z_BYTECAP(bufSizeInBytes) wchar_t *buf,
|
|
size_t bufSizeInBytes) = 0;
|
|
|
|
//--------------------------------------------------------
|
|
//--------------------------------------------------------
|
|
virtual bool ReadToBuffer(FileHandle_t hFile, CUtlBuffer & buf,
|
|
int nMaxBytes = 0,
|
|
FSAllocFunc_t pfnAlloc = NULL) = 0;
|
|
|
|
//--------------------------------------------------------
|
|
// Optimal IO operations
|
|
//--------------------------------------------------------
|
|
virtual bool GetOptimalIOConstraints(
|
|
FileHandle_t hFile, unsigned *pOffsetAlign, unsigned *pSizeAlign,
|
|
unsigned *pBufferAlign) = 0;
|
|
inline unsigned GetOptimalReadSize(FileHandle_t hFile,
|
|
unsigned nLogicalSize);
|
|
virtual void *AllocOptimalReadBuffer(FileHandle_t hFile, unsigned nSize = 0,
|
|
unsigned nOffset = 0) = 0;
|
|
virtual void FreeOptimalReadBuffer(void *) = 0;
|
|
|
|
//--------------------------------------------------------
|
|
//
|
|
//--------------------------------------------------------
|
|
virtual void BeginMapAccess() = 0;
|
|
virtual void EndMapAccess() = 0;
|
|
|
|
// Returns true on success, otherwise false if it can't be resolved
|
|
// Prefer using the FullPathToRelativePathEx_safe template wrapper to
|
|
// calling this directly
|
|
virtual bool FullPathToRelativePathEx(
|
|
const char *pFullpath, const char *pPathId,
|
|
OUT_Z_CAP(maxLenInChars) char *pDest, int maxLenInChars) = 0;
|
|
template <size_t maxLenInChars>
|
|
bool FullPathToRelativePathEx_safe(
|
|
const char *pFullpath, OUT_Z_ARRAY char(&pDest)[maxLenInChars]) {
|
|
return FullPathToRelativePathEx(pFullpath, pDest, (int)maxLenInChars);
|
|
}
|
|
|
|
virtual int GetPathIndex(const FileNameHandle_t &handle) = 0;
|
|
virtual long GetPathTime(const char *pPath, const char *pPathID) = 0;
|
|
|
|
virtual DVDMode_t GetDVDMode() = 0;
|
|
|
|
//--------------------------------------------------------
|
|
// Whitelisting for pure servers.
|
|
//--------------------------------------------------------
|
|
|
|
// This should be called ONCE at startup. Multiplayer games (gameinfo.txt
|
|
// does not contain singleplayer_only) want to enable this so sv_pure works.
|
|
virtual void EnableWhitelistFileTracking(
|
|
bool bEnable, bool bCacheAllVPKHashes,
|
|
bool bRecalculateAndCheckHashes) = 0;
|
|
|
|
// This is called when the client connects to a server using a
|
|
// pure_server_whitelist.txt file.
|
|
virtual void RegisterFileWhitelist(IPureServerWhitelist * pWhiteList,
|
|
IFileList * *pFilesToReload) = 0;
|
|
|
|
// Called when the client logs onto a server. Any files that came off disk
|
|
// should be marked as unverified because this server may have a different
|
|
// set of files it wants to guarantee.
|
|
virtual void MarkAllCRCsUnverified() = 0;
|
|
|
|
// As the server loads whitelists when it transitions maps, it calls this to
|
|
// calculate CRCs for any files marked with check_crc. Then it calls
|
|
// CheckCachedFileCRC later when it gets client requests to verify CRCs.
|
|
virtual void CacheFileCRCs(const char *pPathname, ECacheCRCType eType,
|
|
IFileList *pFilter) = 0;
|
|
virtual EFileCRCStatus CheckCachedFileHash(
|
|
const char *pPathID, const char *pRelativeFilename, int nFileFraction,
|
|
FileHash_t *pFileHash) = 0;
|
|
|
|
// Fills in the list of files that have been loaded off disk and have not
|
|
// been verified. Returns the number of files filled in (between 0 and
|
|
// nMaxFiles).
|
|
//
|
|
// This also removes any files it's returning from the unverified CRC list,
|
|
// so they won't be returned from here again. The client sends batches of
|
|
// these to the server to verify.
|
|
virtual int GetUnverifiedFileHashes(CUnverifiedFileHash * pFiles,
|
|
int nMaxFiles) = 0;
|
|
|
|
// Control debug message output.
|
|
// Pass a combination of WHITELIST_SPEW_ flags.
|
|
virtual int GetWhitelistSpewFlags() = 0;
|
|
virtual void SetWhitelistSpewFlags(int flags) = 0;
|
|
|
|
// Installs a callback used to display a dirty disk dialog
|
|
virtual void InstallDirtyDiskReportFunc(FSDirtyDiskReportFunc_t func) = 0;
|
|
|
|
//--------------------------------------------------------
|
|
// Low-level file caching. Cached files are loaded into memory and used
|
|
// to satisfy read requests (sync and async) until the cache is destroyed.
|
|
// NOTE: this could defeat file whitelisting, if a file were loaded in
|
|
// a non-whitelisted environment and then reused. Clients should not cache
|
|
// files across moves between pure/non-pure environments.
|
|
//--------------------------------------------------------
|
|
virtual FileCacheHandle_t CreateFileCache() = 0;
|
|
virtual void AddFilesToFileCache(FileCacheHandle_t cacheId,
|
|
const char **ppFileNames, int nFileNames,
|
|
const char *pPathID) = 0;
|
|
virtual bool IsFileCacheFileLoaded(FileCacheHandle_t cacheId,
|
|
const char *pFileName) = 0;
|
|
virtual bool IsFileCacheLoaded(FileCacheHandle_t cacheId) = 0;
|
|
virtual void DestroyFileCache(FileCacheHandle_t cacheId) = 0;
|
|
|
|
// XXX For now, we assume that all path IDs are "GAME", never cache files
|
|
// outside of the game search path, and preferentially return those files
|
|
// whenever anyone searches for a match even if an on-disk file in another
|
|
// folder would have been found first in a traditional search. extending
|
|
// the memory cache to cover non-game files isn't necessary right now, but
|
|
// should just be a matter of defining a more complex key type. (henryg)
|
|
|
|
// Register a CMemoryFileBacking; must balance with UnregisterMemoryFile.
|
|
// Returns false and outputs an ref-bumped pointer to the existing entry
|
|
// if the same file has already been registered by someone else; this must
|
|
// be Unregistered to maintain the balance.
|
|
virtual bool RegisterMemoryFile(
|
|
CMemoryFileBacking * pFile,
|
|
CMemoryFileBacking * *ppExistingFileWithRef) = 0;
|
|
|
|
// Unregister a CMemoryFileBacking; must balance with RegisterMemoryFile.
|
|
virtual void UnregisterMemoryFile(CMemoryFileBacking * pFile) = 0;
|
|
|
|
virtual void CacheAllVPKFileHashes(bool bCacheAllVPKHashes,
|
|
bool bRecalculateAndCheckHashes) = 0;
|
|
virtual bool CheckVPKFileHash(int PackFileID, int nPackFileNumber,
|
|
int nFileFraction, MD5Value_t &md5Value) = 0;
|
|
|
|
// Called when we unload a file, to remove that file's info for pure server
|
|
// purposes.
|
|
virtual void NotifyFileUnloaded(const char *pszFilename,
|
|
const char *pPathId) = 0;
|
|
|
|
// Returns true on successfully retrieve case-sensitive full path, otherwise
|
|
// false Prefer using the GetCaseCorrectFullPath template wrapper to calling
|
|
// this directly
|
|
virtual bool GetCaseCorrectFullPath_Ptr(
|
|
const char *pFullPath, OUT_Z_CAP(maxLenInChars) char *pDest,
|
|
int maxLenInChars) = 0;
|
|
template <size_t maxLenInChars>
|
|
bool GetCaseCorrectFullPath(const char *pFullPath,
|
|
OUT_Z_ARRAY char(&pDest)[maxLenInChars]) {
|
|
return GetCaseCorrectFullPath_Ptr(pFullPath, pDest, (int)maxLenInChars);
|
|
}
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Memory file backing, which you can use to fake out the filesystem, caching
|
|
// data in memory and have it associated with a file
|
|
//-----------------------------------------------------------------------------
|
|
class CMemoryFileBacking : public CRefCounted<CRefCountServiceMT> {
|
|
public:
|
|
CMemoryFileBacking(IFileSystem *pFS)
|
|
: m_pFS(pFS),
|
|
m_nRegistered(0),
|
|
m_pFileName(NULL),
|
|
m_pData(NULL),
|
|
m_nLength(0) {}
|
|
~CMemoryFileBacking() {
|
|
free((char *)m_pFileName);
|
|
if (m_pData) m_pFS->FreeOptimalReadBuffer((char *)m_pData);
|
|
}
|
|
|
|
IFileSystem *m_pFS;
|
|
int m_nRegistered;
|
|
const char *m_pFileName;
|
|
const char *m_pData;
|
|
int m_nLength;
|
|
|
|
private:
|
|
CMemoryFileBacking(const CMemoryFileBacking &); // not defined
|
|
CMemoryFileBacking &operator=(const CMemoryFileBacking &); // not defined
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#if defined(_X360) && !defined(_RETAIL)
|
|
extern char g_szXboxProfileLastFileOpened[MAX_PATH];
|
|
#define SetLastProfileFileRead(s) \
|
|
Q_strncpy(g_szXboxProfileLastFileOpened, \
|
|
sizeof(g_szXboxProfileLastFileOpened), pFileName)
|
|
#define GetLastProfileFileRead() (&g_szXboxProfileLastFileOpened[0])
|
|
#else
|
|
#define SetLastProfileFileRead(s) ((void)0)
|
|
#define GetLastProfileFileRead() NULL
|
|
#endif
|
|
|
|
#if defined(_X360) && defined(_BASETSD_H_)
|
|
class CXboxDiskCacheSetter {
|
|
public:
|
|
CXboxDiskCacheSetter(SIZE_T newSize) {
|
|
m_oldSize = XGetFileCacheSize();
|
|
XSetFileCacheSize(newSize);
|
|
}
|
|
|
|
~CXboxDiskCacheSetter() { XSetFileCacheSize(m_oldSize); }
|
|
|
|
private:
|
|
SIZE_T m_oldSize;
|
|
};
|
|
#define DISK_INTENSIVE() CXboxDiskCacheSetter cacheSetter(1024 * 1024)
|
|
#else
|
|
#define DISK_INTENSIVE() ((void)0)
|
|
#endif
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
inline unsigned IFileSystem::GetOptimalReadSize(FileHandle_t hFile,
|
|
unsigned nLogicalSize) {
|
|
unsigned align;
|
|
if (GetOptimalIOConstraints(hFile, &align, NULL, NULL))
|
|
return AlignValue(nLogicalSize, align);
|
|
else
|
|
return nLogicalSize;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// We include this here so it'll catch compile errors in VMPI early.
|
|
#include "filesystem_passthru.h"
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Async memory tracking
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#if (defined(_DEBUG) || defined(USE_MEM_DEBUG))
|
|
#define AsyncRead(a, b) AsyncReadCreditAlloc(a, __FILE__, __LINE__, b)
|
|
#define AsyncReadMutiple(a, b, c) \
|
|
AsyncReadMultipleCreditAlloc(a, b, __FILE__, __LINE__, c)
|
|
#endif
|
|
|
|
extern IFileSystem *g_pFullFileSystem;
|
|
|
|
#endif // FILESYSTEM_H
|