diff options
Diffstat (limited to 'external/vpc/public/filesystem.h')
| -rw-r--r-- | external/vpc/public/filesystem.h | 958 |
1 files changed, 958 insertions, 0 deletions
diff --git a/external/vpc/public/filesystem.h b/external/vpc/public/filesystem.h new file mode 100644 index 0000000..81d4d98 --- /dev/null +++ b/external/vpc/public/filesystem.h @@ -0,0 +1,958 @@ +//===== 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 |