Counter Strike : Global Offensive Source Code
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.

1396 lines
45 KiB

  1. //===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //===========================================================================//
  7. #ifndef BASEFILESYSTEM_H
  8. #define BASEFILESYSTEM_H
  9. #include "tier0/platform.h"
  10. #ifdef _PS3
  11. #include <sdk_version.h>
  12. #if CELL_SDK_VERSION >= 0x085007
  13. #define getenv(x) NULL //TEMP REMOVE THIS - RP
  14. #endif
  15. #endif
  16. #ifdef _WIN32
  17. #pragma once
  18. #endif
  19. #if defined( _WIN32 )
  20. #if !defined( _X360 ) && !defined( _PS3 ) && !defined(LINUX)
  21. #include <io.h>
  22. #include <direct.h>
  23. #define WIN32_LEAN_AND_MEAN
  24. #include <windows.h>
  25. #define SUPPORT_VPK
  26. #endif
  27. #undef GetCurrentDirectory
  28. #undef GetJob
  29. #undef AddJob
  30. #elif defined( POSIX ) && !defined( _PS3 )
  31. #include <unistd.h> // unlink
  32. #include "linux_support.h"
  33. #define INVALID_HANDLE_VALUE (void *)-1
  34. // undo the prepended "_" 's
  35. #define _chmod chmod
  36. #define _stat stat
  37. #define _alloca alloca
  38. #define _S_IFDIR S_IFDIR
  39. #define SUPPORT_VPK
  40. #elif defined(_PS3)
  41. #include <unistd.h> // unlink
  42. #define INVALID_HANDLE_VALUE ( void * )-1
  43. // undo the prepended "_" 's
  44. #define _chmod chmod
  45. #define _stat stat
  46. #define _alloca alloca
  47. #define _S_IFDIR S_IFDIR
  48. #endif
  49. #include "tier0/threadtools.h"
  50. #include <stdio.h>
  51. #include <sys/types.h>
  52. #include <sys/stat.h>
  53. #ifndef _PS3
  54. #include <malloc.h>
  55. #endif // _PS3
  56. #include <string.h>
  57. #include "tier1/utldict.h"
  58. #ifdef SUPPORT_VPK
  59. #include "vpklib/packedstore.h"
  60. #endif
  61. #include <time.h>
  62. #include "refcount.h"
  63. #include "filesystem.h"
  64. #include "tier1/utlvector.h"
  65. #include "tier1/UtlStringMap.h"
  66. #include <stdarg.h>
  67. #include "tier1/utlrbtree.h"
  68. #include "tier1/utlsymbol.h"
  69. #include "tier1/utllinkedlist.h"
  70. #include "tier1/utlstring.h"
  71. #include "tier1/utlsortvector.h"
  72. #include "bspfile.h"
  73. #include "tier1/utldict.h"
  74. #include "tier1/tier1.h"
  75. #include "byteswap.h"
  76. #include "threadsaferefcountedobject.h"
  77. #include "filetracker.h"
  78. #ifdef _PS3
  79. #include "ps3/ps3_platform.h"
  80. #include "ps3/ps3_core.h"
  81. #else
  82. #include "xbox/xboxstubs.h"
  83. #endif // _PS3
  84. #include "tier0/memdbgon.h"
  85. #ifdef _WIN32
  86. #define CORRECT_PATH_SEPARATOR '\\'
  87. #define INCORRECT_PATH_SEPARATOR '/'
  88. #elif defined(POSIX)
  89. #define CORRECT_PATH_SEPARATOR '/'
  90. #define INCORRECT_PATH_SEPARATOR '\\'
  91. #endif
  92. #ifdef _WIN32
  93. #define PATHSEPARATOR(c) ((c) == '\\' || (c) == '/')
  94. #elif defined(POSIX)
  95. #define PATHSEPARATOR(c) ((c) == '/')
  96. #endif //_WIN32
  97. #define MAX_FILEPATH 512
  98. #if !defined( _X360 )
  99. #define SUPPORT_IODELAY_MONITORING
  100. #endif
  101. #ifdef _PS3
  102. #define FILE_ATTRIBUTE_DIRECTORY S_IFDIR
  103. typedef struct
  104. {
  105. // public data
  106. int dwFileAttributes;
  107. char cFileName[PATH_MAX]; // the file name returned from the call
  108. int numMatches;
  109. struct dirent **namelist;
  110. } FIND_DATA;
  111. #define WIN32_FIND_DATA FIND_DATA
  112. #endif // _PS3
  113. extern CUtlSymbolTableMT g_PathIDTable;
  114. struct DLCCorrupt_t
  115. {
  116. XCONTENT_DATA m_ContentData;
  117. };
  118. struct DLCContent_t
  119. {
  120. XCONTENT_DATA m_ContentData;
  121. DWORD m_LicenseMask;
  122. int m_nController;
  123. char m_szVolume[8];
  124. bool m_bMounted;
  125. bool m_bCorrupt;
  126. };
  127. class CDLCLess
  128. {
  129. public:
  130. bool Less( const DLCContent_t& lhs, const DLCContent_t& rhs, void *pContext )
  131. {
  132. return ( ( lhs.m_LicenseMask & 0xFFFF0000 ) < ( rhs.m_LicenseMask & 0xFFFF0000 ) );
  133. }
  134. };
  135. enum FileMode_t
  136. {
  137. FM_BINARY,
  138. FM_TEXT
  139. };
  140. enum FileType_t
  141. {
  142. FT_NORMAL,
  143. FT_PACK_BINARY,
  144. FT_PACK_TEXT,
  145. #if defined(_PS3)
  146. FT_RUNTIME_PS3,
  147. #endif
  148. };
  149. #if defined(_PS3)
  150. void FixUpPathCaseForPS3( const char* pFilePath );
  151. #endif
  152. class IThreadPool;
  153. class CAsyncJobFuliller;
  154. class CBlockingFileItemList;
  155. class KeyValues;
  156. class CCompiledKeyValuesReader;
  157. class CBaseFileSystem;
  158. class CPackFileHandle;
  159. class CPackFile;
  160. class IFileList;
  161. class CFileOpenInfo;
  162. class CFileHandleTimer;
  163. class CWhitelistSpecs
  164. {
  165. public:
  166. IFileList *m_pWantCRCList;
  167. IFileList *m_pAllowFromDiskList;
  168. };
  169. typedef CThreadSafeRefCountedObject<CWhitelistSpecs*> CWhitelistHolder;
  170. //-----------------------------------------------------------------------------
  171. class CIODelayAlarmThread;
  172. class CFileHandle
  173. {
  174. public:
  175. CFileHandle( CBaseFileSystem* fs );
  176. virtual ~CFileHandle();
  177. void Init( CBaseFileSystem* fs );
  178. int GetSectorSize();
  179. bool IsOK();
  180. void Flush();
  181. void SetBufferSize( int nBytes );
  182. int Read( void* pBuffer, int nLength );
  183. int Read( void* pBuffer, int nDestSize, int nLength );
  184. int Write( const void* pBuffer, int nLength );
  185. int Seek( int64 nOffset, int nWhence );
  186. int Tell();
  187. int Size();
  188. int64 AbsoluteBaseOffset();
  189. bool EndOfFile();
  190. char *m_pszTrueFileName;
  191. char const *Name() const { return m_pszTrueFileName ? m_pszTrueFileName : ""; }
  192. void SetName( char const *pName )
  193. {
  194. Assert( pName );
  195. Assert( !m_pszTrueFileName );
  196. int len = Q_strlen( pName );
  197. m_pszTrueFileName = new char[len + 1];
  198. memcpy( m_pszTrueFileName, pName, len + 1 );
  199. }
  200. CPackFileHandle *m_pPackFileHandle;
  201. #ifdef SUPPORT_VPK
  202. CPackedStoreFileHandle m_VPKHandle;
  203. #endif
  204. int64 m_nLength;
  205. FileType_t m_type;
  206. FILE *m_pFile;
  207. protected:
  208. CBaseFileSystem *m_fs;
  209. #ifdef _PS3
  210. // FOURCCs generate a warning on PS3
  211. enum
  212. {
  213. MAGIC = 0xABCDABCD,
  214. FREE_MAGIC = 0xDEADBEEF
  215. };
  216. #else // !_PS3
  217. enum
  218. {
  219. MAGIC = 'CFHa',
  220. FREE_MAGIC = 'FreM'
  221. };
  222. #endif // _PS3
  223. unsigned int m_nMagic;
  224. bool IsValid();
  225. };
  226. // A pack file handle - essentially represents a file inside the pack file.
  227. // Note, there is no provision for compression here at the current time.
  228. class CPackFileHandle
  229. {
  230. public:
  231. inline CPackFileHandle( CPackFile* pOwner, int64 nBase, unsigned int nLength, unsigned int nIndex = -1, unsigned int nFilePointer = 0 );
  232. inline ~CPackFileHandle();
  233. int Read( void* pBuffer, int nDestSize, int nBytes );
  234. int Seek( int nOffset, int nWhence );
  235. int Tell() { return m_nFilePointer; }
  236. int Size() { return m_nLength; }
  237. inline void SetBufferSize( int nBytes );
  238. inline int GetSectorSize();
  239. inline int64 AbsoluteBaseOffset();
  240. protected:
  241. int64 m_nBase; // Base offset of the file inside the pack file.
  242. unsigned int m_nFilePointer; // Current seek pointer (0 based from the beginning of the file).
  243. CPackFile* m_pOwner; // Pack file that owns this handle
  244. unsigned int m_nLength; // Length of this file.
  245. unsigned int m_nIndex; // Index into the pack's directory table
  246. };
  247. //-----------------------------------------------------------------------------
  248. class CPackFile : public CRefCounted<CRefCountServiceMT>
  249. {
  250. public:
  251. inline CPackFile();
  252. inline virtual ~CPackFile();
  253. // The means by which you open files:
  254. virtual CFileHandle *OpenFile( const char *pFileName, const char *pOptions = "rb" );
  255. // The two functions a pack file must provide
  256. virtual bool Prepare( int64 fileLen = -1, int64 nFileOfs = 0 ) = 0;
  257. virtual bool FindFile( const char *pFilename, int &nIndex, int64 &nPosition, int &nLength ) = 0;
  258. // This is the core IO routine for reading anything from a pack file, everything should go through here at some point
  259. virtual int ReadFromPack( int nIndex, void* buffer, int nDestBytes, int nBytes, int64 nOffset );
  260. // Returns the filename for a given file in the pack. Returns true if a filename is found, otherwise buffer is filled with "unknown"
  261. virtual bool IndexToFilename( int nIndex, char* buffer, int nBufferSize ) = 0;
  262. inline int GetSectorSize();
  263. virtual void SetupPreloadData() {}
  264. virtual void DiscardPreloadData() {}
  265. virtual int64 GetPackFileBaseOffset() = 0;
  266. virtual CRC32_t GetKVPoolKey() { return 0; }
  267. virtual bool GetStringFromKVPool( unsigned int key, char *pOutBuff, int buflen ) { return false; }
  268. // Note: threading model for pack files assumes that data
  269. // is segmented into pack files that aggregate files
  270. // meant to be read in one thread. Performance characteristics
  271. // tuned for that case
  272. CThreadFastMutex m_mutex;
  273. // Path management:
  274. void SetPath( const CUtlSymbol &path ) { m_Path = path; }
  275. const CUtlSymbol& GetPath() const { Assert( m_Path != UTL_INVAL_SYMBOL ); return m_Path; }
  276. CUtlSymbol m_Path;
  277. // possibly embedded pack
  278. int64 m_nBaseOffset;
  279. CUtlString m_ZipName;
  280. bool m_bIsMapPath;
  281. long m_lPackFileTime;
  282. int m_refCount;
  283. int m_nOpenFiles;
  284. FILE *m_hPackFileHandleFS;
  285. #ifdef SUPPORT_VPK
  286. CPackedStoreFileHandle m_hPackFileHandleVPK;
  287. #endif
  288. bool m_bIsExcluded;
  289. int m_PackFileID;
  290. protected:
  291. int64 m_FileLength;
  292. CBaseFileSystem *m_fs;
  293. friend class CPackFileHandle;
  294. };
  295. class CZipPackFile : public CPackFile
  296. {
  297. public:
  298. CZipPackFile( CBaseFileSystem* fs, void *pSection = NULL );
  299. ~CZipPackFile();
  300. // Loads the pack file
  301. virtual bool Prepare( int64 fileLen = -1, int64 nFileOfs = 0 );
  302. virtual bool FindFile( const char *pFilename, int &nIndex, int64 &nOffset, int &nLength );
  303. virtual int ReadFromPack( int nIndex, void* buffer, int nDestBytes, int nBytes, int64 nOffset );
  304. int64 GetPackFileBaseOffset() { return m_nBaseOffset; }
  305. bool IndexToFilename( int nIndex, char *pBuffer, int nBufferSize );
  306. virtual CRC32_t GetKVPoolKey();
  307. virtual bool GetStringFromKVPool( unsigned int key, char *pOutBuff, int buflen );
  308. protected:
  309. #pragma pack(1)
  310. typedef struct
  311. {
  312. char name[ 112 ];
  313. int64 filepos;
  314. int64 filelen;
  315. } packfile64_t;
  316. typedef struct
  317. {
  318. char id[ 4 ];
  319. int64 dirofs;
  320. int64 dirlen;
  321. } packheader64_t;
  322. typedef struct
  323. {
  324. char id[ 8 ];
  325. int64 packheaderpos;
  326. int64 originalfilesize;
  327. } packappenededheader_t;
  328. #pragma pack()
  329. // A Pack file directory entry:
  330. class CPackFileEntry
  331. {
  332. public:
  333. unsigned int m_nPosition;
  334. unsigned int m_nLength;
  335. unsigned int m_HashName;
  336. unsigned short m_nPreloadIdx;
  337. unsigned short pad;
  338. FileNameHandle_t m_hDebugFilename;
  339. };
  340. class CPackFileLessFunc
  341. {
  342. public:
  343. bool Less( CPackFileEntry const& src1, CPackFileEntry const& src2, void *pCtx );
  344. };
  345. // Find a file inside a pack file:
  346. const CPackFileEntry* FindFile( const char* pFileName );
  347. // Entries to the individual files stored inside the pack file.
  348. CUtlSortVector< CPackFileEntry, CPackFileLessFunc > m_PackFiles;
  349. bool GetOffsetAndLength( const char *FileName, int &nBaseIndex, int64 &nFileOffset, int &nLength );
  350. // Preload Support
  351. void SetupPreloadData();
  352. void DiscardPreloadData();
  353. ZIP_PreloadDirectoryEntry* GetPreloadEntry( int nEntryIndex );
  354. int64 m_nPreloadSectionOffset;
  355. unsigned int m_nPreloadSectionSize;
  356. ZIP_PreloadHeader *m_pPreloadHeader;
  357. unsigned short* m_pPreloadRemapTable;
  358. ZIP_PreloadDirectoryEntry *m_pPreloadDirectory;
  359. void* m_pPreloadData;
  360. CByteswap m_swap;
  361. CRC32_t m_KVPoolKey;
  362. CUtlFilenameSymbolTable m_KVStringPool;
  363. void *m_pSection;
  364. };
  365. class CFileLoadInfo
  366. {
  367. public:
  368. bool m_bSteamCacheOnly; // If Steam and this is true, then the file is only looked for in the Steam caches.
  369. bool m_bLoadedFromSteamCache; // If Steam, this tells whether the file was loaded off disk or the Steam cache.
  370. #ifdef _PS3
  371. Ps3FileType_t m_ps3Filetype;
  372. #endif
  373. };
  374. //-----------------------------------------------------------------------------
  375. #ifdef AsyncRead
  376. #undef AsyncRead
  377. #undef AsyncReadMutiple
  378. #endif
  379. //-----------------------------------------------------------------------------
  380. abstract_class CBaseFileSystem : public CTier2AppSystem< IFileSystem >
  381. {
  382. friend class CPackFileHandle;
  383. friend class CPackFile;
  384. friend class CXZipPackFile;
  385. friend class CFileHandle;
  386. friend class CFileTracker;
  387. friend class CFileTracker2;
  388. friend class CFileOpenInfo;
  389. typedef CTier2AppSystem< IFileSystem > BaseClass;
  390. public:
  391. CBaseFileSystem();
  392. ~CBaseFileSystem();
  393. // Methods of IAppSystem
  394. virtual void *QueryInterface( const char *pInterfaceName );
  395. virtual InitReturnVal_t Init();
  396. virtual void Shutdown();
  397. void InitAsync();
  398. void ShutdownAsync();
  399. void ParsePathID( const char* &pFilename, const char* &pPathID, char tempPathID[MAX_PATH] );
  400. // file handling
  401. virtual FileHandle_t Open( const char *pFileName, const char *pOptions, const char *pathID );
  402. virtual FileHandle_t OpenEx( const char *pFileName, const char *pOptions, unsigned flags = 0, const char *pathID = 0, char **ppszResolvedFilename = NULL );
  403. virtual void Close( FileHandle_t );
  404. virtual void Seek( FileHandle_t file, int pos, FileSystemSeek_t method );
  405. virtual unsigned int Tell( FileHandle_t file );
  406. virtual unsigned int Size( FileHandle_t file );
  407. virtual unsigned int Size( const char *pFileName, const char *pPathID );
  408. virtual void SetBufferSize( FileHandle_t file, unsigned nBytes );
  409. virtual bool IsOk( FileHandle_t file );
  410. virtual void Flush( FileHandle_t file );
  411. virtual bool Precache( const char *pFileName, const char *pPathID );
  412. virtual bool EndOfFile( FileHandle_t file );
  413. virtual int Read( void *pOutput, int size, FileHandle_t file );
  414. virtual int ReadEx( void* pOutput, int sizeDest, int size, FileHandle_t file );
  415. virtual int Write( void const* pInput, int size, FileHandle_t file );
  416. virtual char *ReadLine( char *pOutput, int maxChars, FileHandle_t file );
  417. virtual int FPrintf( FileHandle_t file, PRINTF_FORMAT_STRING const char *pFormat, ... ) FMTFUNCTION( 3, 4 );
  418. // Reads/writes files to utlbuffers
  419. virtual bool ReadFile( const char *pFileName, const char *pPath, CUtlBuffer &buf, int nMaxBytes, int nStartingByte, FSAllocFunc_t pfnAlloc = NULL );
  420. virtual bool WriteFile( const char *pFileName, const char *pPath, CUtlBuffer &buf );
  421. virtual bool UnzipFile( const char *pFileName, const char *pPath, const char *pDestination );
  422. virtual int ReadFileEx( const char *pFileName, const char *pPath, void **ppBuf, bool bNullTerminate, bool bOptimalAlloc, int nMaxBytes = 0, int nStartingByte = 0, FSAllocFunc_t pfnAlloc = NULL );
  423. virtual bool ReadToBuffer( FileHandle_t hFile, CUtlBuffer &buf, int nMaxBytes = 0, FSAllocFunc_t pfnAlloc = NULL );
  424. // Optimal buffer
  425. bool GetOptimalIOConstraints( FileHandle_t hFile, unsigned *pOffsetAlign, unsigned *pSizeAlign, unsigned *pBufferAlign );
  426. void *AllocOptimalReadBuffer( FileHandle_t hFile, unsigned nSize, unsigned nOffset ) { return malloc( nSize ); }
  427. void FreeOptimalReadBuffer( void *p ) { free( p ); }
  428. // Gets the current working directory
  429. virtual bool GetCurrentDirectory( char* pDirectory, int maxlen );
  430. // this isn't implementable on STEAM as is.
  431. virtual void CreateDirHierarchy( const char *path, const char *pathID );
  432. // returns true if the file is a directory
  433. virtual bool IsDirectory( const char *pFileName, const char *pathID );
  434. // path info
  435. virtual const char *GetLocalPath( const char *pFileName, char *pLocalPath, int localPathBufferSize );
  436. virtual bool FullPathToRelativePath( const char *pFullpath, char *pRelative, int maxlen );
  437. // removes a file from disk
  438. virtual void RemoveFile( char const* pRelativePath, const char *pathID );
  439. // Remove all search paths (including write path?)
  440. virtual void RemoveAllSearchPaths( void );
  441. // Purpose: Removes all search paths for a given pathID, such as all "GAME" paths.
  442. virtual void RemoveSearchPaths( const char *pathID );
  443. // STUFF FROM IFileSystem
  444. // Add paths in priority order (mod dir, game dir, ....)
  445. // Can also add pak files (errr, NOT YET!)
  446. virtual void AddSearchPath( const char *pPath, const char *pathID, SearchPathAdd_t addType );
  447. virtual bool RemoveSearchPath( const char *pPath, const char *pathID );
  448. virtual void PrintSearchPaths( void );
  449. virtual void MarkPathIDByRequestOnly( const char *pPathID, bool bRequestOnly );
  450. virtual bool IsFileInReadOnlySearchPath(const char *pPath, const char *pathID = 0);
  451. virtual bool FileExists( const char *pFileName, const char *pPathID = NULL );
  452. virtual long GetFileTime( const char *pFileName, const char *pPathID = NULL );
  453. virtual bool IsFileWritable( char const *pFileName, const char *pPathID = NULL );
  454. virtual bool SetFileWritable( char const *pFileName, bool writable, const char *pPathID = 0 );
  455. virtual void FileTimeToString( char *pString, int maxChars, long fileTime );
  456. virtual const char *FindFirst( const char *pWildCard, FileFindHandle_t *pHandle );
  457. virtual const char *FindFirstEx( const char *pWildCard, const char *pPathID, FileFindHandle_t *pHandle );
  458. virtual const char *FindNext( FileFindHandle_t handle );
  459. virtual bool FindIsDirectory( FileFindHandle_t handle );
  460. virtual void FindClose( FileFindHandle_t handle );
  461. virtual void FindFileAbsoluteList( CUtlVector< CUtlString > &outAbsolutePathNames, const char *pWildCard, const char *pPathID );
  462. virtual void PrintOpenedFiles( void );
  463. virtual void SetWarningFunc( void (*pfnWarning)( const char *fmt, ... ) );
  464. virtual void SetWarningLevel( FileWarningLevel_t level );
  465. virtual void AddLoggingFunc( FileSystemLoggingFunc_t logFunc );
  466. virtual void RemoveLoggingFunc( FileSystemLoggingFunc_t logFunc );
  467. virtual bool RenameFile( char const *pOldPath, char const *pNewPath, const char *pathID );
  468. virtual void GetLocalCopy( const char *pFileName );
  469. virtual FileNameHandle_t FindOrAddFileName( char const *pFileName );
  470. virtual FileNameHandle_t FindFileName( char const *pFileName );
  471. virtual bool String( const FileNameHandle_t& handle, char *buf, int buflen );
  472. virtual int GetPathIndex( const FileNameHandle_t &handle );
  473. long GetPathTime( const char *pFileName, const char *pPathID );
  474. bool ShouldGameReloadFile( const char *pFilename );
  475. virtual void EnableWhitelistFileTracking( bool bEnable, bool bCacheAllVPKHashes, bool bRecalculateAndCheckHashes );
  476. virtual void RegisterFileWhitelist( IFileList *pWantCRCList, IFileList *pAllowFromDiskList, IFileList **pFilesToReload );
  477. virtual void MarkAllCRCsUnverified();
  478. virtual void CacheFileCRCs( const char *pPathname, ECacheCRCType eType, IFileList *pFilter );
  479. void CacheFileCRCs_R( const char *pPathname, ECacheCRCType eType, IFileList *pFilter, CUtlDict<int,int> &searchPathNames );
  480. virtual EFileCRCStatus CheckCachedFileHash( const char *pPathID, const char *pRelativeFilename, int nFileFraction, FileHash_t *pFileHash );
  481. virtual int GetUnverifiedFileHashes( CUnverifiedFileHash *pFiles, int nMaxFiles );
  482. virtual int GetWhitelistSpewFlags();
  483. virtual void SetWhitelistSpewFlags( int flags );
  484. virtual void InstallDirtyDiskReportFunc( FSDirtyDiskReportFunc_t func );
  485. virtual void CacheAllVPKFileHashes( bool bCacheAllVPKHashes, bool bRecalculateAndCheckHashes );
  486. virtual bool CheckVPKFileHash( int PackFileID, int nPackFileNumber, int nFileFraction, MD5Value_t &md5Value );
  487. // Returns the file system statistics retreived by the implementation. Returns NULL if not supported.
  488. virtual const FileSystemStatistics *GetFilesystemStatistics();
  489. // GetVPKFileStatisticsKV
  490. virtual void GetVPKFileStatisticsKV( KeyValues *pKV );
  491. // Load dlls
  492. virtual CSysModule *LoadModule( const char *pFileName, const char *pPathID, bool bValidatedDllOnly );
  493. virtual void UnloadModule( CSysModule *pModule );
  494. //--------------------------------------------------------
  495. // asynchronous file loading
  496. //--------------------------------------------------------
  497. virtual FSAsyncStatus_t AsyncReadMultiple( const FileAsyncRequest_t *pRequests, int nRequests, FSAsyncControl_t *pControls );
  498. virtual FSAsyncStatus_t AsyncReadMultipleCreditAlloc( const FileAsyncRequest_t *pRequests, int nRequests, const char *pszFile, int line, FSAsyncControl_t *phControls = NULL );
  499. virtual FSAsyncStatus_t AsyncDirectoryScan( const char* pSearchSpec, bool recurseFolders, void* pContext, FSAsyncScanAddFunc_t pfnAdd, FSAsyncScanCompleteFunc_t pfnDone, FSAsyncControl_t *pControl = NULL );
  500. virtual FSAsyncStatus_t AsyncFinish( FSAsyncControl_t hControl, bool wait );
  501. virtual FSAsyncStatus_t AsyncGetResult( FSAsyncControl_t hControl, void **ppData, int *pSize );
  502. virtual FSAsyncStatus_t AsyncAbort( FSAsyncControl_t hControl );
  503. virtual FSAsyncStatus_t AsyncStatus( FSAsyncControl_t hControl );
  504. virtual FSAsyncStatus_t AsyncSetPriority(FSAsyncControl_t hControl, int newPriority);
  505. virtual FSAsyncStatus_t AsyncFlush();
  506. virtual FSAsyncStatus_t AsyncAppend(const char *pFileName, const void *pSrc, int nSrcBytes, bool bFreeMemory, FSAsyncControl_t *pControl) { return AsyncWrite( pFileName, pSrc, nSrcBytes, bFreeMemory, true, pControl); }
  507. virtual FSAsyncStatus_t AsyncWrite(const char *pFileName, const void *pSrc, int nSrcBytes, bool bFreeMemory, bool bAppend, FSAsyncControl_t *pControl);
  508. virtual FSAsyncStatus_t AsyncWriteFile(const char *pFileName, const CUtlBuffer *pSrc, int nSrcBytes, bool bFreeMemory, bool bAppend, FSAsyncControl_t *pControl);
  509. virtual FSAsyncStatus_t AsyncAppendFile(const char *pDestFileName, const char *pSrcFileName, FSAsyncControl_t *pControl);
  510. virtual void AsyncFinishAll( int iToPriority = INT_MIN );
  511. virtual void AsyncFinishAllWrites();
  512. virtual bool AsyncSuspend();
  513. virtual bool AsyncResume();
  514. virtual void AsyncAddRef( FSAsyncControl_t hControl );
  515. virtual void AsyncRelease( FSAsyncControl_t hControl );
  516. virtual FSAsyncStatus_t AsyncBeginRead( const char *pszFile, FSAsyncFile_t *phFile );
  517. virtual FSAsyncStatus_t AsyncEndRead( FSAsyncFile_t hFile );
  518. //--------------------------------------------------------
  519. // pack files
  520. //--------------------------------------------------------
  521. bool AddPackFile( const char *pFileName, const char *pathID );
  522. bool AddPackFileFromPath( const char *pPath, const char *pakfile, bool bCheckForAppendedPack, const char *pathID );
  523. // converts a partial path into a full path
  524. // can be filtered to restrict path types and can provide info about resolved path
  525. virtual const char *RelativePathToFullPath( const char *pFileName, const char *pPathID, char *pFullPath, int fullPathBufferSize, PathTypeFilter_t pathFilter = FILTER_NONE, PathTypeQuery_t *pPathType = NULL );
  526. #if IsGameConsole()
  527. virtual bool GetPackFileInfoFromRelativePath( const char *pFileName, const char *pPathID, char *pPackPath, int nPackPathBufferSize, int64 &nPosition, int64 &nLength );
  528. #endif
  529. // Returns the search path, each path is separated by ;s. Returns the length of the string returned
  530. virtual int GetSearchPath( const char *pathID, bool bGetPackFiles, char *pPath, int nMaxLen );
  531. virtual int GetSearchPathID( char *pPath, int nMaxLen );
  532. #if defined( TRACK_BLOCKING_IO )
  533. virtual void EnableBlockingFileAccessTracking( bool state );
  534. virtual bool IsBlockingFileAccessEnabled() const;
  535. virtual IBlockingFileItemList *RetrieveBlockingFileAccessInfo();
  536. virtual void RecordBlockingFileAccess( bool synchronous, const FileBlockingItem& item );
  537. virtual bool SetAllowSynchronousLogging( bool state );
  538. #endif
  539. virtual bool GetFileTypeForFullPath( char const *pFullPath, wchar_t *buf, size_t bufSizeInBytes );
  540. virtual void BeginMapAccess();
  541. virtual void EndMapAccess();
  542. virtual bool FullPathToRelativePathEx( const char *pFullpath, const char *pPathId, char *pRelative, int maxlen );
  543. FSAsyncStatus_t SyncRead( const FileAsyncRequest_t &request );
  544. FSAsyncStatus_t SyncWrite(const char *pszFilename, const void *pSrc, int nSrcBytes, bool bFreeMemory, bool bAppend );
  545. FSAsyncStatus_t SyncAppendFile(const char *pAppendToFileName, const char *pAppendFromFileName );
  546. FSAsyncStatus_t SyncGetFileSize( const FileAsyncRequest_t &request );
  547. void DoAsyncCallback( const FileAsyncRequest_t &request, void *pData, int nBytesRead, FSAsyncStatus_t result );
  548. void SetupPreloadData();
  549. void DiscardPreloadData();
  550. // 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.
  551. // Otherwise, it'll just fall through to the regular KeyValues loading routines
  552. virtual KeyValues *LoadKeyValues( KeyValuesPreloadType_t type, char const *filename, char const *pPathID = 0 );
  553. virtual bool LoadKeyValues( KeyValues& head, KeyValuesPreloadType_t type, char const *filename, char const *pPathID = 0 );
  554. virtual DVDMode_t GetDVDMode() { return m_DVDMode; }
  555. virtual bool IsLaunchedFromXboxHDD() { return m_bLaunchedFromXboxHDD; }
  556. virtual bool IsInstalledToXboxHDDCache() { return m_bFoundXboxImageInCache; }
  557. virtual bool IsDVDHosted() { return m_bDVDHosted; }
  558. virtual bool IsInstallAllowed() { return m_bAllowXboxInstall; }
  559. virtual bool FixupSearchPathsAfterInstall();
  560. virtual FSDirtyDiskReportFunc_t GetDirtyDiskReportFunc() { return m_DirtyDiskReportFunc; }
  561. virtual void AddVPKFile( char const *pszName, SearchPathAdd_t addType = PATH_ADD_TO_TAIL );
  562. virtual void RemoveVPKFile( char const *pszName );
  563. virtual void GetVPKFileNames( CUtlVector<CUtlString> &destVector );
  564. virtual void RemoveAllMapSearchPaths( void );
  565. void BuildExcludeList();
  566. virtual void SyncDvdDevCache();
  567. bool FixupFATXFilename( const char *pFilename, char *pOutFilename, int nOutSize );
  568. virtual bool GetStringFromKVPool( CRC32_t poolKey, unsigned int key, char *pOutBuff, int buflen );
  569. virtual bool DiscoverDLC( int iController );
  570. virtual int IsAnyDLCPresent( bool *pbDLCSearchPathMounted = NULL );
  571. virtual bool GetAnyDLCInfo( int iDLC, unsigned int *pLicenseMask, wchar_t *pTitleBuff, int nOutTitleSize );
  572. virtual int IsAnyCorruptDLC();
  573. virtual bool GetAnyCorruptDLCInfo( int iCorruptDLC, wchar_t *pTitleBuff, int nOutTitleSize );
  574. virtual bool AddDLCSearchPaths();
  575. virtual bool IsSpecificDLCPresent( unsigned int nDLCPackage );
  576. void PrintDLCInfo();
  577. virtual void SetIODelayAlarm( float flTime );
  578. virtual bool AddXLSPUpdateSearchPath( const void *pData, int nSize );
  579. virtual IIoStats *GetIoStats();
  580. public:
  581. //------------------------------------
  582. // Synchronous path for file operations
  583. //------------------------------------
  584. class CPathIDInfo
  585. {
  586. public:
  587. const CUtlSymbol& GetPathID() const;
  588. const char* GetPathIDString() const;
  589. void SetPathID( CUtlSymbol id );
  590. public:
  591. // See MarkPathIDByRequestOnly.
  592. bool m_bByRequestOnly;
  593. private:
  594. CUtlSymbol m_PathID;
  595. const char *m_pDebugPathID;
  596. };
  597. ////////////////////////////////////////////////
  598. // IMPLEMENTATION DETAILS FOR CBaseFileSystem //
  599. ////////////////////////////////////////////////
  600. class CSearchPath
  601. {
  602. public:
  603. CSearchPath( void );
  604. ~CSearchPath( void );
  605. const char* GetPathString() const;
  606. // Path ID ("game", "mod", "gamebin") accessors.
  607. const CUtlSymbol& GetPathID() const;
  608. const char* GetPathIDString() const;
  609. // Search path (c:\hl2\hl2) accessors.
  610. void SetPath( CUtlSymbol id );
  611. const CUtlSymbol& GetPath() const;
  612. void SetPackFile(CPackFile *pPackFile) { m_pPackFile = pPackFile; }
  613. CPackFile *GetPackFile() const { return m_pPackFile; }
  614. int m_storeId;
  615. // Used to track if its search
  616. CPathIDInfo *m_pPathIDInfo;
  617. bool m_bIsDvdDevPath;
  618. private:
  619. CUtlSymbol m_Path;
  620. const char *m_pDebugPath;
  621. CPackFile *m_pPackFile;
  622. public:
  623. bool m_bIsLocalizedPath;
  624. };
  625. static void MarkLocalizedPath( CSearchPath *sp );
  626. class CSearchPathsVisits
  627. {
  628. public:
  629. void Reset()
  630. {
  631. m_Visits.RemoveAll();
  632. }
  633. bool MarkVisit( const CSearchPath &searchPath )
  634. {
  635. if ( m_Visits.Find( searchPath.m_storeId ) == m_Visits.InvalidIndex() )
  636. {
  637. MEM_ALLOC_CREDIT();
  638. m_Visits.AddToTail( searchPath.m_storeId );
  639. return false;
  640. }
  641. return true;
  642. }
  643. private:
  644. CUtlVector<int> m_Visits; // This is a copy of IDs for the search paths we've visited, so
  645. };
  646. class CSearchPathsIterator
  647. {
  648. public:
  649. CSearchPathsIterator( CBaseFileSystem *pFileSystem, const char **ppszFilename, const char *pszPathID, PathTypeFilter_t pathTypeFilter = FILTER_NONE )
  650. : m_iCurrent( -1 ),
  651. m_PathTypeFilter( pathTypeFilter ),
  652. m_bExcluded( false )
  653. {
  654. char tempPathID[MAX_PATH];
  655. if ( *ppszFilename && (*ppszFilename)[0] == '/' && (*ppszFilename)[1] == '/' ) // ONLY '//' (and not '\\') for our special format
  656. {
  657. // Allow for UNC-type syntax to specify the path ID.
  658. pFileSystem->ParsePathID( *ppszFilename, pszPathID, tempPathID );
  659. }
  660. if ( pszPathID )
  661. {
  662. m_pathID = g_PathIDTable.AddString( pszPathID );
  663. }
  664. else
  665. {
  666. m_pathID = UTL_INVAL_SYMBOL;
  667. }
  668. if ( *ppszFilename && !Q_IsAbsolutePath( *ppszFilename ) )
  669. {
  670. // Copy paths to minimize mutex lock time
  671. pFileSystem->m_SearchPathsMutex.Lock();
  672. CopySearchPaths( pFileSystem->m_SearchPaths );
  673. pFileSystem->m_SearchPathsMutex.Unlock();
  674. V_strncpy( m_Filename, *ppszFilename, sizeof( m_Filename ) );
  675. V_FixSlashes( m_Filename );
  676. }
  677. else
  678. {
  679. // If it's an absolute path, it isn't worth using the paths at all. Simplify
  680. // client logic by pretending there's a search path of 1
  681. m_EmptyPathIDInfo.m_bByRequestOnly = false;
  682. m_EmptySearchPath.m_pPathIDInfo = &m_EmptyPathIDInfo;
  683. m_EmptySearchPath.SetPath( m_pathID );
  684. m_EmptySearchPath.m_storeId = -1;
  685. m_Filename[0] = '\0';
  686. }
  687. }
  688. CSearchPathsIterator( CBaseFileSystem *pFileSystem, const char *pszPathID, PathTypeFilter_t pathTypeFilter = FILTER_NONE )
  689. : m_iCurrent( -1 ),
  690. m_PathTypeFilter( pathTypeFilter ),
  691. m_bExcluded( false )
  692. {
  693. if ( pszPathID )
  694. {
  695. m_pathID = g_PathIDTable.AddString( pszPathID );
  696. }
  697. else
  698. {
  699. m_pathID = UTL_INVAL_SYMBOL;
  700. }
  701. // Copy paths to minimize mutex lock time
  702. pFileSystem->m_SearchPathsMutex.Lock();
  703. CopySearchPaths( pFileSystem->m_SearchPaths );
  704. pFileSystem->m_SearchPathsMutex.Unlock();
  705. m_Filename[0] = '\0';
  706. }
  707. CSearchPath *GetFirst();
  708. CSearchPath *GetNext();
  709. private:
  710. CSearchPathsIterator( const CSearchPathsIterator & );
  711. void operator=(const CSearchPathsIterator &);
  712. void CopySearchPaths( const CUtlVector<CSearchPath> &searchPaths )
  713. {
  714. m_SearchPaths = searchPaths;
  715. for ( int i = 0; i < m_SearchPaths.Count(); i++ )
  716. {
  717. if ( m_SearchPaths[i].GetPackFile() )
  718. {
  719. m_SearchPaths[i].GetPackFile()->AddRef();
  720. }
  721. }
  722. }
  723. int m_iCurrent;
  724. CUtlSymbol m_pathID;
  725. CUtlVector<CSearchPath> m_SearchPaths;
  726. CSearchPathsVisits m_visits;
  727. CSearchPath m_EmptySearchPath;
  728. CPathIDInfo m_EmptyPathIDInfo;
  729. PathTypeFilter_t m_PathTypeFilter;
  730. char m_Filename[MAX_PATH]; // set for relative names only
  731. bool m_bExcluded;
  732. };
  733. friend class CSearchPathsIterator;
  734. struct FindData_t
  735. {
  736. WIN32_FIND_DATA findData;
  737. int currentSearchPathID;
  738. CUtlVector<char> wildCardString;
  739. HANDLE findHandle;
  740. CSearchPathsVisits m_VisitedSearchPaths; // This is a copy of IDs for the search paths we've visited, so avoids searching duplicate paths.
  741. int m_CurrentStoreID; // CSearchPath::m_storeId of the current search path.
  742. CUtlSymbol m_FilterPathID; // What path ID are we looking at? Ignore all others. (Only set by FindFirstEx).
  743. CUtlDict<int,int> m_VisitedFiles; // We go through the search paths in priority order, and we use this to make sure
  744. // that we don't return the same file more than once.
  745. #ifdef SUPPORT_VPK
  746. CUtlStringList m_fileMatchesFromVPK;
  747. CUtlStringList m_dirMatchesFromVPK;
  748. #endif
  749. };
  750. friend class CSearchPath;
  751. CWhitelistHolder m_FileWhitelist;
  752. int m_WhitelistSpewFlags; // Combination of WHITELIST_SPEW_ flags.
  753. // logging functions
  754. CUtlVector< FileSystemLoggingFunc_t > m_LogFuncs;
  755. CThreadMutex m_SearchPathsMutex;
  756. CUtlVector< CSearchPath > m_SearchPaths;
  757. CUtlVector<CPathIDInfo*> m_PathIDInfos;
  758. CUtlLinkedList<FindData_t> m_FindData;
  759. CUtlVector<CFileHandleTimer*> m_FileHandleTimers; // Used to debug approximate times for each file read
  760. CThreadFastMutex m_FileHandleTimersMutex;
  761. int m_iMapLoad;
  762. // Global list of pack file handles
  763. CUtlVector<CPackFile *> m_ZipFiles;
  764. FILE *m_pLogFile;
  765. bool m_bOutputDebugString;
  766. IThreadPool * m_pThreadPool;
  767. // Statistics:
  768. FileSystemStatistics m_Stats;
  769. #ifdef SUPPORT_IODELAY_MONITORING
  770. float m_flDelayLimit;
  771. float m_flLastIOTime;
  772. FORCEINLINE void NoteIO( void )
  773. {
  774. if ( m_pDelayThread )
  775. {
  776. m_flLastIOTime = Plat_FloatTime();
  777. }
  778. }
  779. CIODelayAlarmThread *m_pDelayThread;
  780. #else
  781. FORCEINLINE void NoteIO( void )
  782. {
  783. }
  784. #endif
  785. #if defined( TRACK_BLOCKING_IO )
  786. CBlockingFileItemList *m_pBlockingItems;
  787. bool m_bBlockingFileAccessReportingEnabled;
  788. bool m_bAllowSynchronousLogging;
  789. friend class CBlockingFileItemList;
  790. friend class CAutoBlockReporter;
  791. #endif
  792. CFileTracker2 m_FileTracker2;
  793. protected:
  794. //----------------------------------------------------------------------------
  795. // Purpose: Functions implementing basic file system behavior.
  796. //----------------------------------------------------------------------------
  797. virtual FILE *FS_fopen( const char *filename, const char *options, unsigned flags, int64 *size, CFileLoadInfo *pInfo ) = 0;
  798. virtual void FS_setbufsize( FILE *fp, unsigned nBytes ) = 0;
  799. virtual void FS_fclose( FILE *fp ) = 0;
  800. virtual void FS_fseek( FILE *fp, int64 pos, int seekType ) = 0;
  801. virtual long FS_ftell( FILE *fp ) = 0;
  802. virtual int FS_feof( FILE *fp ) = 0;
  803. size_t FS_fread( void *dest, size_t size, FILE *fp ) { return FS_fread( dest, (size_t)-1, size, fp ); }
  804. virtual size_t FS_fread( void *dest, size_t destSize, size_t size, FILE *fp ) = 0;
  805. virtual size_t FS_fwrite( const void *src, size_t size, FILE *fp ) = 0;
  806. virtual bool FS_setmode( FILE *fp, FileMode_t mode ) { return false; }
  807. virtual size_t FS_vfprintf( FILE *fp, const char *fmt, va_list list ) = 0;
  808. virtual int FS_ferror( FILE *fp ) = 0;
  809. virtual int FS_fflush( FILE *fp ) = 0;
  810. virtual char *FS_fgets( char *dest, int destSize, FILE *fp ) = 0;
  811. virtual int FS_stat( const char *path, struct _stat *buf ) = 0;
  812. virtual int FS_chmod( const char *path, int pmode ) = 0;
  813. virtual HANDLE FS_FindFirstFile( const char *findname, WIN32_FIND_DATA *dat) = 0;
  814. virtual bool FS_FindNextFile(HANDLE handle, WIN32_FIND_DATA *dat) = 0;
  815. virtual bool FS_FindClose(HANDLE handle) = 0;
  816. virtual int FS_GetSectorSize( FILE * ) { return 1; }
  817. #if defined( TRACK_BLOCKING_IO )
  818. void BlockingFileAccess_EnterCriticalSection();
  819. void BlockingFileAccess_LeaveCriticalSection();
  820. CThreadMutex m_BlockingFileMutex;
  821. #endif
  822. void GetFileNameForHandle( FileHandle_t handle, char *buf, size_t buflen );
  823. protected:
  824. //-----------------------------------------------------------------------------
  825. // Purpose: For tracking unclosed files
  826. // NOTE: The symbol table could take up memory that we don't want to eat here.
  827. // In that case, we shouldn't store them in a table, or we should store them as locally allocates stings
  828. // so we can control the size
  829. //-----------------------------------------------------------------------------
  830. class COpenedFile
  831. {
  832. public:
  833. COpenedFile( void );
  834. ~COpenedFile( void );
  835. COpenedFile( const COpenedFile& src );
  836. bool operator==( const COpenedFile& src ) const;
  837. void SetName( char const *name );
  838. char const *GetName( void );
  839. FILE *m_pFile;
  840. char *m_pName;
  841. };
  842. //CUtlRBTree< COpenedFile, int > m_OpenedFiles;
  843. CThreadMutex m_OpenedFilesMutex;
  844. CUtlVector <COpenedFile> m_OpenedFiles;
  845. CUtlStringMap< bool > m_NonexistingFilesExtensions;
  846. #ifdef NONEXISTING_FILES_CACHE_SUPPORT
  847. CUtlStringMap< double > m_NonexistingFilesCache;
  848. #endif
  849. static bool OpenedFileLessFunc( COpenedFile const& src1, COpenedFile const& src2 );
  850. FileWarningLevel_t m_fwLevel;
  851. void (*m_pfnWarning)( const char *fmt, ... );
  852. FILE *Trace_FOpen( const char *filename, const char *options, unsigned flags, int64 *size, CFileLoadInfo *pInfo=NULL );
  853. void Trace_FClose( FILE *fp );
  854. void Trace_FRead( int size, FILE* file );
  855. void Trace_FWrite( int size, FILE* file );
  856. void Trace_DumpUnclosedFiles( void );
  857. public:
  858. void LogAccessToFile( char const *accesstype, char const *fullpath, char const *options );
  859. void FileSystemWarning( FileWarningLevel_t level, const char *fmt, ... );
  860. protected:
  861. // Note: if pFoundStoreID is passed in, then it will set that to the CSearchPath::m_storeId value of the search path it found the file in.
  862. const char* FindFirstHelper( const char *pWildCard, const char *pPathID, FileFindHandle_t *pHandle, int *pFoundStoreID );
  863. bool FindNextFileHelper( FindData_t *pFindData, int *pFoundStoreID );
  864. void FindFileAbsoluteListHelper( CUtlVector< CUtlString > &outAbsolutePathNames, FindData_t &findData, const char *pAbsoluteFindName );
  865. void AddMapPackFile( const char *pPath, const char *pPathID, SearchPathAdd_t addType );
  866. void AddPackFiles( const char *pPath, const CUtlSymbol &pathID, SearchPathAdd_t addType, int iForceInsertIndex = 0 );
  867. bool PreparePackFile( CPackFile &packfile, int offsetofpackinmetafile, int64 filelen );
  868. // Goes through all the search paths (or just the one specified) and calls FindFile on them. Returns the first successful result, if any.
  869. FileHandle_t FindFileInSearchPaths( const char *pFileName, const char *pOptions, const char *pathID, unsigned flags, char **ppszResolvedFilename = NULL, bool bTrackCRCs=false );
  870. bool HandleOpenFromZipFile( CFileOpenInfo &openInfo );
  871. void HandleOpenFromPackFile( CPackFile *pPackFile, CFileOpenInfo &openInfo );
  872. void HandleOpenRegularFile( CFileOpenInfo &openInfo, bool bIsAbsolutePath );
  873. FileHandle_t FindFile( const CSearchPath *path, const char *pFileName, const char *pOptions, unsigned flags, char **ppszResolvedFilename = NULL, bool bTrackCRCs=false );
  874. int FastFindFile( const CSearchPath *path, const char *pFileName );
  875. long FastFileTime( const CSearchPath *path, const char *pFileName );
  876. const char *GetWritePath( const char *pFilename, const char *pathID );
  877. // Computes a full write path
  878. void ComputeFullWritePath( char* pDest, int maxlen, const char *pWritePathID, char const *pRelativePath );
  879. void AddSearchPathInternal( const char *pPath, const char *pathID, SearchPathAdd_t addType, bool bAddPackFiles, int iForceInsertIndex = 0 );
  880. // Opens a file for read or write
  881. FileHandle_t OpenForRead( const char *pFileName, const char *pOptions, unsigned flags, const char *pathID, char **ppszResolvedFilename = NULL );
  882. FileHandle_t OpenForWrite( const char *pFileName, const char *pOptions, const char *pathID );
  883. CSearchPath *FindWritePath( const char *pFilename, const char *pathID );
  884. // Helper function for fs_log file logging
  885. void LogFileAccess( const char *pFullFileName );
  886. #if IsPlatformPS3()
  887. virtual bool PrefetchFile( const char *pFileName, int nPriority, bool bPersist );
  888. virtual bool PrefetchFile( const char *pFileName, int nPriority, bool bPersist, int64 nOffset, int64 nSize );
  889. virtual void FlushCache();
  890. virtual void SuspendPrefetches( const char *pWhy );
  891. virtual void ResumePrefetches( const char *pWhy );
  892. virtual void OnSaveStateChanged( bool bSaving );
  893. virtual bool IsPrefetchingDone();
  894. #endif
  895. bool LookupKeyValuesRootKeyName( char const *filename, char const *pPathID, char *rootName, size_t bufsize );
  896. // If bByRequestOnly is -1, then it will default to false if it doesn't already exist, and it
  897. // won't change it if it does already exist. Otherwise, it will be set to the value of bByRequestOnly.
  898. CPathIDInfo* FindOrAddPathIDInfo( const CUtlSymbol &id, int bByRequestOnly );
  899. static bool FilterByPathID( const CSearchPath *pSearchPath, const CUtlSymbol &pathID );
  900. // Global/shared filename/path table
  901. CUtlFilenameSymbolTable m_FileNames;
  902. // This manages most of the info we use for pure servers (whether files came from Steam caches or off-disk, their CRCs, which ones are unverified, etc).
  903. CFileTracker m_FileTracker;
  904. int m_WhitelistFileTrackingEnabled; // -1 if unset, 0 if disabled (single player), 1 if enabled (multiplayer).
  905. FSDirtyDiskReportFunc_t m_DirtyDiskReportFunc;
  906. static CUtlSymbol m_GamePathID;
  907. static CUtlSymbol m_BSPPathID;
  908. static DVDMode_t m_DVDMode;
  909. static bool m_bFoundXboxImageInCache;
  910. static bool m_bLaunchedFromXboxHDD;
  911. static bool m_bDVDHosted;
  912. static bool m_bAllowXboxInstall;
  913. static bool m_bSearchPathsPatchedAfterInstall;
  914. // Pack exclude paths are strictly for 360 to allow holes in search paths and pack files
  915. // which fall through to support new or dynamic data on the host pc.
  916. struct ExcludeFilePath_t
  917. {
  918. FileNameHandle_t m_hName;
  919. FileNameHandle_t m_hFixedName;
  920. };
  921. static CUtlVector< FileNameHandle_t > m_ExcludeFilePaths;
  922. #ifdef SUPPORT_VPK
  923. CUtlVector< CPackedStore *> m_VPKFiles;
  924. CUtlDict<int,int> m_VPKDirectories;
  925. CPackedStoreFileHandle FindFileInVPKs( const char *pFileName );
  926. #endif
  927. static CUtlSortVector< DLCContent_t, CDLCLess > m_DLCContents;
  928. static CUtlVector< DLCCorrupt_t > m_CorruptDLC;
  929. };
  930. inline const CUtlSymbol& CBaseFileSystem::CPathIDInfo::GetPathID() const
  931. {
  932. return m_PathID;
  933. }
  934. inline const char* CBaseFileSystem::CPathIDInfo::GetPathIDString() const
  935. {
  936. return g_PathIDTable.String( m_PathID );
  937. }
  938. inline const char* CBaseFileSystem::CSearchPath::GetPathString() const
  939. {
  940. return g_PathIDTable.String( m_Path );
  941. }
  942. inline void CBaseFileSystem::CPathIDInfo::SetPathID( CUtlSymbol sym )
  943. {
  944. m_PathID = sym;
  945. m_pDebugPathID = GetPathIDString();
  946. }
  947. inline const CUtlSymbol& CBaseFileSystem::CSearchPath::GetPathID() const
  948. {
  949. return m_pPathIDInfo->GetPathID();
  950. }
  951. inline const char* CBaseFileSystem::CSearchPath::GetPathIDString() const
  952. {
  953. return m_pPathIDInfo->GetPathIDString();
  954. }
  955. inline void CBaseFileSystem::CSearchPath::SetPath( CUtlSymbol id )
  956. {
  957. m_Path = id;
  958. m_pDebugPath = g_PathIDTable.String( m_Path );
  959. MarkLocalizedPath( this );
  960. }
  961. inline const CUtlSymbol& CBaseFileSystem::CSearchPath::GetPath() const
  962. {
  963. return m_Path;
  964. }
  965. inline bool CBaseFileSystem::FilterByPathID( const CSearchPath *pSearchPath, const CUtlSymbol &pathID )
  966. {
  967. if ( (UtlSymId_t)pathID == UTL_INVAL_SYMBOL )
  968. {
  969. // They didn't specify a specific search path, so if this search path's path ID is by
  970. // request only, then ignore it.
  971. return pSearchPath->m_pPathIDInfo->m_bByRequestOnly;
  972. }
  973. else
  974. {
  975. // Bit of a hack, but specifying "BSP" as the search path will search in "GAME" for only the map/.bsp pack file path
  976. if ( pathID == m_BSPPathID )
  977. {
  978. if ( pSearchPath->GetPathID() != m_GamePathID )
  979. return true;
  980. if ( !pSearchPath->GetPackFile() )
  981. return true;
  982. if ( !pSearchPath->GetPackFile()->m_bIsMapPath )
  983. return true;
  984. return false;
  985. }
  986. else
  987. {
  988. return (pSearchPath->GetPathID() != pathID);
  989. }
  990. }
  991. }
  992. // Pack file handle implementation:
  993. inline CPackFileHandle::CPackFileHandle( CPackFile* pOwner, int64 nBase, unsigned int nLength, unsigned int nIndex, unsigned int nFilePointer )
  994. {
  995. m_pOwner = pOwner;
  996. m_nBase = nBase;
  997. m_nLength = nLength;
  998. m_nIndex = nIndex;
  999. m_nFilePointer = nFilePointer;
  1000. pOwner->AddRef();
  1001. }
  1002. inline CPackFileHandle::~CPackFileHandle()
  1003. {
  1004. m_pOwner->m_mutex.Lock();
  1005. --m_pOwner->m_nOpenFiles;
  1006. if ( m_pOwner->m_nOpenFiles == 0 && m_pOwner->m_bIsMapPath )
  1007. {
  1008. if ( m_pOwner->m_hPackFileHandleFS )
  1009. {
  1010. m_pOwner->m_fs->Trace_FClose( m_pOwner->m_hPackFileHandleFS );
  1011. m_pOwner->m_hPackFileHandleFS = NULL;
  1012. }
  1013. }
  1014. m_pOwner->Release();
  1015. m_pOwner->m_mutex.Unlock();
  1016. }
  1017. inline void CPackFileHandle::SetBufferSize( int nBytes )
  1018. {
  1019. if ( m_pOwner->m_hPackFileHandleFS )
  1020. {
  1021. m_pOwner->m_fs->FS_setbufsize( m_pOwner->m_hPackFileHandleFS, nBytes );
  1022. }
  1023. }
  1024. inline int CPackFileHandle::GetSectorSize()
  1025. {
  1026. return m_pOwner->GetSectorSize();
  1027. }
  1028. inline int64 CPackFileHandle::AbsoluteBaseOffset()
  1029. {
  1030. return m_pOwner->GetPackFileBaseOffset() + m_nBase;
  1031. }
  1032. // Pack file implementation:
  1033. inline CPackFile::CPackFile()
  1034. {
  1035. m_FileLength = 0;
  1036. m_hPackFileHandleFS = NULL;
  1037. m_fs = NULL;
  1038. m_nBaseOffset = 0;
  1039. m_bIsMapPath = false;
  1040. m_lPackFileTime = 0L;
  1041. m_refCount = 0;
  1042. m_nOpenFiles = 0;
  1043. m_PackFileID = 0;
  1044. }
  1045. inline CPackFile::~CPackFile()
  1046. {
  1047. if ( m_nOpenFiles )
  1048. {
  1049. Error( "Closing pack file with %d open files!\n", m_nOpenFiles );
  1050. }
  1051. if ( m_hPackFileHandleFS )
  1052. {
  1053. m_fs->FS_fclose( m_hPackFileHandleFS );
  1054. m_hPackFileHandleFS = NULL;
  1055. }
  1056. m_fs->m_ZipFiles.FindAndRemove( this );
  1057. }
  1058. inline int CPackFile::GetSectorSize()
  1059. {
  1060. if ( m_hPackFileHandleFS )
  1061. {
  1062. return m_fs->FS_GetSectorSize( m_hPackFileHandleFS );
  1063. }
  1064. #ifdef SUPPORT_VPK
  1065. else if ( m_hPackFileHandleVPK )
  1066. {
  1067. return 2048;
  1068. }
  1069. #endif
  1070. else
  1071. {
  1072. return -1;
  1073. }
  1074. }
  1075. #if defined( TRACK_BLOCKING_IO )
  1076. class CAutoBlockReporter
  1077. {
  1078. public:
  1079. CAutoBlockReporter( CBaseFileSystem *fs, bool synchronous, char const *filename, int eBlockType, int nTypeOfAccess ) :
  1080. m_pFS( fs ),
  1081. m_Item( eBlockType, filename, 0.0f, nTypeOfAccess ),
  1082. m_bSynchronous( synchronous )
  1083. {
  1084. Assert( m_pFS );
  1085. m_Timer.Start();
  1086. }
  1087. CAutoBlockReporter( CBaseFileSystem *fs, bool synchronous, FileHandle_t handle, int eBlockType, int nTypeOfAccess ) :
  1088. m_pFS( fs ),
  1089. m_Item( eBlockType, NULL, 0.0f, nTypeOfAccess ),
  1090. m_bSynchronous( synchronous )
  1091. {
  1092. Assert( m_pFS );
  1093. char name[ 512 ];
  1094. m_pFS->GetFileNameForHandle( handle, name, sizeof( name ) );
  1095. m_Item.SetFileName( name );
  1096. m_Timer.Start();
  1097. }
  1098. ~CAutoBlockReporter()
  1099. {
  1100. m_Timer.End();
  1101. m_Item.m_flElapsed = m_Timer.GetDuration().GetSeconds();
  1102. m_pFS->RecordBlockingFileAccess( m_bSynchronous, m_Item );
  1103. }
  1104. private:
  1105. CBaseFileSystem *m_pFS;
  1106. CFastTimer m_Timer;
  1107. FileBlockingItem m_Item;
  1108. bool m_bSynchronous;
  1109. };
  1110. #define AUTOBLOCKREPORTER_FN( name, fs, sync, filename, blockType, accessType ) CAutoBlockReporter block##name( fs, sync, filename, blockType, accessType );
  1111. #define AUTOBLOCKREPORTER_FH( name, fs, sync, handle, blockType, accessType ) CAutoBlockReporter block##name( fs, sync, handle, blockType, accessType );
  1112. #else
  1113. #define AUTOBLOCKREPORTER_FN( name, fs, sync, filename, blockType, accessType ) // Nothing
  1114. #define AUTOBLOCKREPORTER_FH( name, fs, sync, handle , blockType, accessType ) // Nothing
  1115. #endif
  1116. // singleton accessor
  1117. CBaseFileSystem *BaseFileSystem();
  1118. #include "tier0/memdbgoff.h"
  1119. #endif // BASEFILESYSTEM_H