You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
958 lines
38 KiB
958 lines
38 KiB
//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//===========================================================================// |
|
|
|
#ifndef FILESYSTEM_H |
|
#define FILESYSTEM_H |
|
|
|
#ifdef _WIN32 |
|
#pragma once |
|
#endif |
|
|
|
#include <limits.h> |
|
|
|
#include "tier0/threadtools.h" |
|
#include "tier0/memalloc.h" |
|
#include "tier0/tslist.h" |
|
#include "tier1/interface.h" |
|
#include "tier1/utlsymbol.h" |
|
#include "tier1/utlstring.h" |
|
#include "tier1/functors.h" |
|
#include "tier1/checksum_crc.h" |
|
#include "tier1/utlqueue.h" |
|
#include "appframework/iappsystem.h" |
|
#include "tier2/tier2.h" |
|
#ifdef _PS3 |
|
#include <sysutil/sysutil_syscache.h> |
|
#include <sysutil/sysutil_gamecontent.h> |
|
struct HddCacheFileStatus; |
|
extern char gSrcGameDataPath[]; |
|
class CFileGroupSystem; |
|
#endif |
|
|
|
//----------------------------------------------------------------------------- |
|
// Forward declarations |
|
//----------------------------------------------------------------------------- |
|
|
|
class CUtlBuffer; |
|
class KeyValues; |
|
class IFileList; |
|
|
|
typedef void * FileHandle_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 |
|
|
|
//----------------------------------------------------------------------------- |
|
// 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 |
|
FILTER_CULLLOCALIZED = 3, // Ignore localized paths, assumes CULLNONPACK |
|
FILTER_CULLLOCALIZED_ANY = 4, // Ignore any localized paths |
|
}; |
|
|
|
// 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_DVDDEV = 0x04, // path is the dvddev cache |
|
}; |
|
typedef uint32 PathTypeQuery_t; |
|
|
|
#define IS_PACKFILE( n ) ( n & ( PATH_IS_PACKFILE | PATH_IS_MAPPACKFILE ) ) |
|
#define IS_DVDDEV( n ) ( n & PATH_IS_DVDDEV ) |
|
|
|
enum DVDMode_t |
|
{ |
|
DVDMODE_OFF = 0, // not using dvd |
|
DVDMODE_STRICT = 1, // dvd device only |
|
DVDMODE_DEV = 2, // dev mode, mutiple devices ok |
|
DVDMODE_DEV_VISTA = 3, // dev mode from a vista host, mutiple devices ok |
|
}; |
|
|
|
#ifdef _PS3 |
|
|
|
enum FsState_t |
|
{ |
|
FS_STATE_INIT = 0, |
|
FS_STATE_LEVEL_LOAD = 1, |
|
FS_STATE_LEVEL_RUN = 2, |
|
FS_STATE_LEVEL_RESTORE = 3, |
|
FS_STATE_LEVEL_LOAD_END = 4, |
|
FS_STATE_EXITING = 5 |
|
}; |
|
|
|
enum Ps3FileType_t |
|
{ |
|
PS3_FILETYPE_WAV, |
|
PS3_FILETYPE_ANI, |
|
PS3_FILETYPE_BSP, |
|
PS3_FILETYPE_VMT, |
|
PS3_FILETYPE_QPRE, |
|
PS3_FILETYPE_OTHER, |
|
PS3_FILETYPE_DIR, |
|
PS3_FILETYPE_UNKNOWN |
|
}; |
|
|
|
|
|
#endif |
|
|
|
// 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 = V_strlen( filename ); |
|
if ( len >= sizeof( m_szFilename ) ) |
|
{ |
|
V_strncpy( m_szFilename, &filename[ len - sizeof( m_szFilename ) + 1 ], sizeof( m_szFilename ) ); |
|
} |
|
else |
|
{ |
|
V_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 |
|
PATH_ADD_TO_TAIL_ATINDEX, // First 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_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 |
|
}; |
|
|
|
// 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); |
|
|
|
//----------------------------------------------------------------------------- |
|
// Used to add results from async directory scans |
|
//----------------------------------------------------------------------------- |
|
typedef void (*FSAsyncScanAddFunc_t)( void* pContext, char* pFoundPath, char* pFoundFile ); |
|
typedef void (*FSAsyncScanCompleteFunc_t)( void* pContext, 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 |
|
}; |
|
|
|
|
|
class CUnverifiedCRCFile |
|
{ |
|
public: |
|
char m_PathID[MAX_PATH]; |
|
char m_Filename[MAX_PATH]; |
|
CRC32_t m_CRC; |
|
}; |
|
|
|
|
|
// 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 |
|
|
|
|
|
|
|
// DLC license mask flags is 32 publisher defined bits |
|
// MSW 16 bits in 8.8: Type.SubVersion |
|
// LSW 16 bits: Flags |
|
|
|
// return id component |
|
#define DLC_LICENSE_ID( x ) ( ( ( (unsigned int)( x ) ) >> 24 ) & 0x000000FF ) |
|
// returns minor version component (not generally used, i.e. we dont rev dlc's yet) |
|
#define DLC_LICENSE_MINORVERSION( x ) ( ( ( (unsigned int)( x ) ) >> 16 ) & 0x000000FF ) |
|
// returns license flags |
|
#define DLC_LICENSE_FLAGS( x ) ( ( ( (unsigned int)( x ) ) & 0x0000FFFF ) ) |
|
|
|
#define DLCFLAGS_PRESENCE_ONLY 0x0001 // causes no search path loadout |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// 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; |
|
}; |
|
|
|
abstract_class IIoStats |
|
{ |
|
public: |
|
virtual void OnFileSeek( int nTimeInMs ) = 0; |
|
virtual void OnFileRead( int nTimeInMs, int nBytesRead ) = 0; |
|
virtual void OnFileOpen( const char * pFileName ) = 0; |
|
|
|
virtual int GetNumberOfFileSeeks() = 0; |
|
virtual int GetTimeInFileSeek() = 0; |
|
|
|
virtual int GetNumberOfFileReads() = 0; |
|
virtual int GetTimeInFileReads() = 0; |
|
virtual int GetFileReadTotalSize() = 0; |
|
|
|
virtual int GetNumberOfFileOpens() = 0; |
|
|
|
virtual void Reset() = 0; |
|
|
|
protected: |
|
virtual ~IIoStats() |
|
{ |
|
// Do nothing... |
|
} |
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Main file system interface |
|
//----------------------------------------------------------------------------- |
|
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 |
|
virtual const char *RelativePathToFullPath( const char *pFileName, const char *pPathID, char *pLocalPath, int localPathBufferSize, PathTypeFilter_t pathFilter = FILTER_NONE, PathTypeQuery_t *pPathType = NULL ) = 0; |
|
#if IsGameConsole() |
|
// Given a relative path, gets the PACK file that contained this file and its offset and size. Can be used to prefetch a file to a HDD for caching reason. |
|
virtual bool GetPackFileInfoFromRelativePath( const char *pFileName, const char *pPathID, char *pPackPath, int nPackPathBufferSize, int64 &nPosition, int64 &nLength ) = 0; |
|
#endif |
|
// Returns the search path, each path is separated by ;s. Returns the length of the string returned |
|
virtual int GetSearchPath( const char *pathID, bool bGetPackFiles, char *pPath, int nMaxLen ) = 0; |
|
|
|
// 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, const char *pFormat, ... ) FMTFUNCTION( 3, 4 ) = 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; |
|
|
|
// Searches for a file in all paths and results absolute path names for the file, works in pack files (zip and vpk) too |
|
// Lets you search for something like sound/sound.cache and get a list of every sound cache |
|
virtual void FindFileAbsoluteList( CUtlVector< CUtlString > &outAbsolutePathNames, const char *pWildCard, const char *pPathID ) = 0; |
|
|
|
//-------------------------------------------------------- |
|
// File name and directory operations |
|
//-------------------------------------------------------- |
|
|
|
// FIXME: This method is obsolete! Use RelativePathToFullPath instead! |
|
// converts a partial path into a full path |
|
virtual const char *GetLocalPath( const char *pFileName, char *pLocalPath, int localPathBufferSize ) = 0; |
|
|
|
// Returns true on success ( based on current list of search paths, otherwise false if |
|
// it can't be resolved ) |
|
virtual bool FullPathToRelativePath( const char *pFullpath, char *pRelative, int maxlen ) = 0; |
|
|
|
// 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; |
|
|
|
//------------------------------------ |
|
// 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)( 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; |
|
|
|
#if defined( _PS3 ) |
|
// EA cruft not used: virtual Ps3FileType_t GetPs3FileType(const char* path) = 0; |
|
virtual void LogFileAccess( const char *pFullFileName ) = 0; |
|
|
|
// Prefetches a full file in the HDD cache. |
|
virtual bool PrefetchFile( const char *pFileName, int nPriority, bool bPersist ) = 0; |
|
// Prefetches a file portion in the HDD cache. |
|
virtual bool PrefetchFile( const char *pFileName, int nPriority, bool bPersist, int64 nOffset, int64 nSize ) = 0; |
|
// Flushes the HDD cache. |
|
virtual void FlushCache() = 0; |
|
// Suspends all prefetches (like when the game is doing a file intensive operation not controlled by the HDD cache, like Bink movies). |
|
virtual void SuspendPrefetches( const char *pWhy ) = 0; |
|
// Resumes prefetches. This function has to to be called as many time as SuspendPrefetches() to effectively resumes prefetches. |
|
virtual void ResumePrefetches( const char * pWhy ) = 0; |
|
|
|
// Gets called when we are starting / ending a save (it allows the file system to reduce its HDD usage and use BluRay instead). |
|
virtual void OnSaveStateChanged( bool bSaving ) = 0; |
|
|
|
// Returns the prefetching state. If true, everything has been prefetched on the HDD. |
|
virtual bool IsPrefetchingDone() = 0; |
|
|
|
#endif //_PS3 |
|
//-------------------------------------------------------- |
|
// 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, |
|
TYPE_SOUNDOPERATORS, |
|
NUM_PRELOAD_TYPES |
|
}; |
|
|
|
// 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 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 FSAsyncStatus_t AsyncDirectoryScan( const char* pSearchSpec, bool recurseFolders, void* pContext, FSAsyncScanAddFunc_t pfnAdd, FSAsyncScanCompleteFunc_t pfnDone, FSAsyncControl_t *pControl = NULL ) = 0; |
|
|
|
virtual bool GetFileTypeForFullPath( char const *pFullPath, 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 |
|
virtual bool FullPathToRelativePathEx( const char *pFullpath, const char *pPathId, char *pRelative, int maxlen ) = 0; |
|
|
|
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 ) = 0; |
|
|
|
// This is called when the client connects to a server using a pure_server_whitelist.txt file. |
|
// |
|
// Files listed in pWantCRCList will have CRCs calculated for them IF they come off disk |
|
// (and those CRCs will come out of GetUnverifiedCRCFiles). |
|
// |
|
// Files listed in pAllowFromDiskList will be allowed to load from disk. All other files will |
|
// be forced to come from Steam. |
|
// |
|
// The filesystem hangs onto the whitelists you pass in here, and it will Release() them when it closes down |
|
// or when you call this function again. |
|
// |
|
// NOTE: The whitelists you pass in here will be accessed from multiple threads, so make sure the |
|
// IsFileInList function is thread safe. |
|
// |
|
// If pFilesToReload is non-null, the filesystem will hand back a list of files that should be reloaded because they |
|
// are now "dirty". For example, if you were on a non-pure server and you loaded a certain model, and then you connected |
|
// to a pure server that said that model had to come from Steam, then pFilesToReload would specify that model |
|
// and the engine should reload it so it can come from Steam. |
|
// |
|
// Be sure to call Release() on pFilesToReload. |
|
virtual void RegisterFileWhitelist( IFileList *pWantCRCList, IFileList *pAllowFromDiskList, 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 CheckCachedFileCRC( const char *pPathID, const char *pRelativeFilename, CRC32_t *pCRC ) = 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 GetUnverifiedCRCFiles( CUnverifiedCRCFile *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; |
|
|
|
virtual bool IsLaunchedFromXboxHDD() = 0; |
|
virtual bool IsInstalledToXboxHDDCache() = 0; |
|
virtual bool IsDVDHosted() = 0; |
|
virtual bool IsInstallAllowed() = 0; |
|
|
|
virtual int GetSearchPathID( char *pPath, int nMaxLen ) = 0; |
|
virtual bool FixupSearchPathsAfterInstall() = 0; |
|
|
|
virtual FSDirtyDiskReportFunc_t GetDirtyDiskReportFunc() = 0; |
|
|
|
virtual void AddVPKFile( char const *pszName, SearchPathAdd_t addType = PATH_ADD_TO_TAIL ) = 0; |
|
virtual void RemoveVPKFile( char const *pszName ) = 0; |
|
virtual void GetVPKFileNames( CUtlVector<CUtlString> &destVector ) = 0; |
|
virtual void RemoveAllMapSearchPaths() = 0; |
|
virtual void SyncDvdDevCache() = 0; |
|
|
|
virtual bool GetStringFromKVPool( CRC32_t poolKey, unsigned int key, char *pOutBuff, int buflen ) = 0; |
|
|
|
virtual bool DiscoverDLC( int iController ) = 0; |
|
virtual int IsAnyDLCPresent( bool *pbDLCSearchPathMounted = NULL ) = 0; |
|
virtual bool GetAnyDLCInfo( int iDLC, unsigned int *pLicenseMask, wchar_t *pTitleBuff, int nOutTitleSize ) = 0; |
|
virtual int IsAnyCorruptDLC() = 0; |
|
virtual bool GetAnyCorruptDLCInfo( int iCorruptDLC, wchar_t *pTitleBuff, int nOutTitleSize ) = 0; |
|
virtual bool AddDLCSearchPaths() = 0; |
|
virtual bool IsSpecificDLCPresent( unsigned int nDLCPackage ) = 0; |
|
|
|
// call this to look for CPU-hogs during loading processes. When you set this, a breakpoint |
|
// will be issued whenever the indicated # of seconds go by without an i/o request. Passing |
|
// 0.0 will turn off the functionality. |
|
virtual void SetIODelayAlarm( float flThreshhold ) = 0; |
|
|
|
virtual bool AddXLSPUpdateSearchPath( const void *pData, int nSize ) = 0; |
|
|
|
virtual IIoStats *GetIoStats() = 0; |
|
|
|
}; |
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
#if defined( _X360 ) && !defined( _CERT ) |
|
extern char g_szXboxProfileLastFileOpened[MAX_PATH]; |
|
#define SetLastProfileFileRead( s ) V_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 |
|
|
|
//----------------------------------------------------------------------------- |
|
// Globals Exposed |
|
//----------------------------------------------------------------------------- |
|
DECLARE_TIER2_INTERFACE( IFileSystem, g_pFullFileSystem ); |
|
|
|
|
|
|
|
|
|
#endif // FILESYSTEM_H
|
|
|