mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-19 20:24:49 +00:00
Merge pull request #713 from Ragora/feature-vfs-security
Feature: VFS Security
This commit is contained in:
commit
b753c9d91c
|
|
@ -1426,7 +1426,7 @@ void AssetImportConfig::loadSISFile(Torque::Path filePath)
|
|||
String settingsFile = settingsFilePath + "/" + fileExtension + ".sis";
|
||||
|
||||
FileObject* fileObj = new FileObject();
|
||||
if (Platform::isFile(settingsFile))
|
||||
if (Torque::FS::IsFile(settingsFile))
|
||||
{
|
||||
if (!fileObj->readMemory(settingsFile.c_str()))
|
||||
{
|
||||
|
|
@ -2170,7 +2170,7 @@ void AssetImporter::processShapeMaterialInfo(AssetImportObject* assetItem, S32 m
|
|||
|
||||
if (fullFilePath.isNotEmpty())
|
||||
{
|
||||
if (!Platform::isFile(fullFilePath.c_str()))
|
||||
if (!Torque::FS::IsFile(fullFilePath.c_str()))
|
||||
{
|
||||
//could be a stale path reference, such as if it was downloaded elsewhere. Trim to just the filename and see
|
||||
//if we can find it there
|
||||
|
|
@ -2182,7 +2182,7 @@ void AssetImporter::processShapeMaterialInfo(AssetImportObject* assetItem, S32 m
|
|||
if(filePath.getPath().isEmpty())
|
||||
fullFilePath = shapePathBase + "/" + fullFilePath;
|
||||
|
||||
if (Platform::isFile(fullFilePath.c_str()))
|
||||
if (Torque::FS::IsFile(fullFilePath.c_str()))
|
||||
{
|
||||
filePath = Torque::Path(fullFilePath);
|
||||
}
|
||||
|
|
@ -2316,7 +2316,7 @@ void AssetImporter::validateAsset(AssetImportObject* assetItem)
|
|||
}
|
||||
}
|
||||
|
||||
if (!assetItem->filePath.isEmpty() && !assetItem->generatedAsset && !Platform::isFile(assetItem->filePath.getFullPath().c_str()))
|
||||
if (!assetItem->filePath.isEmpty() && !assetItem->generatedAsset && !Torque::FS::IsFile(assetItem->filePath.getFullPath().c_str()))
|
||||
{
|
||||
assetItem->status = "Error";
|
||||
assetItem->statusType = "MissingFile";
|
||||
|
|
@ -2806,15 +2806,20 @@ Torque::Path AssetImporter::importImageAsset(AssetImportObject* assetItem)
|
|||
char qualifiedFromFile[2048];
|
||||
char qualifiedToFile[2048];
|
||||
|
||||
#ifndef TORQUE_SECURE_VFS
|
||||
Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile));
|
||||
Platform::makeFullPathName(assetPath.c_str(), qualifiedToFile, sizeof(qualifiedToFile));
|
||||
#else
|
||||
dStrcpy(qualifiedFromFile, originalPath.c_str(), sizeof(qualifiedFromFile));
|
||||
dStrcpy(qualifiedToFile, assetPath.c_str(), sizeof(qualifiedToFile));
|
||||
#endif
|
||||
|
||||
newAsset->setAssetName(assetName);
|
||||
newAsset->setImageFileName(imageFileName.c_str());
|
||||
|
||||
//If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original
|
||||
//file path for reimporting support later
|
||||
if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Platform::isFile(qualifiedFromFile))
|
||||
if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Torque::FS::IsFile(qualifiedFromFile))
|
||||
{
|
||||
newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile);
|
||||
}
|
||||
|
|
@ -2843,7 +2848,7 @@ Torque::Path AssetImporter::importImageAsset(AssetImportObject* assetItem)
|
|||
{
|
||||
bool isInPlace = !String::compare(qualifiedFromFile, qualifiedToFile);
|
||||
|
||||
if (!isInPlace && !dPathCopy(qualifiedFromFile, qualifiedToFile, !isReimport))
|
||||
if (!isInPlace && !Torque::FS::CopyFile(qualifiedFromFile, qualifiedToFile, !isReimport))
|
||||
{
|
||||
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to copy file %s", assetItem->filePath.getFullPath().c_str());
|
||||
activityLog.push_back(importLogBuffer);
|
||||
|
|
@ -2869,11 +2874,15 @@ Torque::Path AssetImporter::importMaterialAsset(AssetImportObject* assetItem)
|
|||
|
||||
char qualifiedFromFile[2048];
|
||||
|
||||
#ifndef TORQUE_SECURE_VFS
|
||||
Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile));
|
||||
#else
|
||||
dStrcpy(qualifiedFromFile, originalPath.c_str(), sizeof(qualifiedFromFile));
|
||||
#endif
|
||||
|
||||
newAsset->setAssetName(assetName);
|
||||
|
||||
if (!isReimport && Platform::isFile(qualifiedFromFile))
|
||||
if (!isReimport && Torque::FS::IsFile(qualifiedFromFile))
|
||||
{
|
||||
newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile);
|
||||
}
|
||||
|
|
@ -3035,11 +3044,17 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem)
|
|||
char qualifiedFromCSFile[2048];
|
||||
char qualifiedToCSFile[2048];
|
||||
|
||||
#ifndef TORQUE_SECURE_VFS
|
||||
Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile));
|
||||
Platform::makeFullPathName(assetPath.c_str(), qualifiedToFile, sizeof(qualifiedToFile));
|
||||
|
||||
Platform::makeFullPathName(originalConstructorPath.c_str(), qualifiedFromCSFile, sizeof(qualifiedFromCSFile));
|
||||
Platform::makeFullPathName(constructorPath.c_str(), qualifiedToCSFile, sizeof(qualifiedToCSFile));
|
||||
#else
|
||||
dStrcpy(qualifiedFromFile, originalPath.c_str(), sizeof(qualifiedFromFile));
|
||||
dStrcpy(qualifiedToFile, assetPath.c_str(), sizeof(qualifiedToFile));
|
||||
dStrcpy(qualifiedFromCSFile, originalConstructorPath.c_str(), sizeof(qualifiedFromCSFile));
|
||||
dStrcpy(qualifiedToCSFile, constructorPath.c_str(), sizeof(qualifiedToCSFile));
|
||||
#endif
|
||||
|
||||
newAsset->setAssetName(assetName);
|
||||
newAsset->setShapeFile(shapeFileName.c_str());
|
||||
|
|
@ -3057,7 +3072,7 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem)
|
|||
|
||||
//If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original
|
||||
//file path for reimporting support later
|
||||
if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Platform::isFile(qualifiedFromFile))
|
||||
if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Torque::FS::IsFile(qualifiedFromFile))
|
||||
{
|
||||
newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile);
|
||||
}
|
||||
|
|
@ -3121,7 +3136,7 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem)
|
|||
{
|
||||
bool isInPlace = !String::compare(qualifiedFromFile, qualifiedToFile);
|
||||
|
||||
if (!isInPlace && !dPathCopy(qualifiedFromFile, qualifiedToFile, !isReimport))
|
||||
if (!isInPlace && !Torque::FS::CopyFile(qualifiedFromFile, qualifiedToFile, !isReimport))
|
||||
{
|
||||
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to copy file %s", qualifiedFromFile);
|
||||
activityLog.push_back(importLogBuffer);
|
||||
|
|
@ -3130,9 +3145,9 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem)
|
|||
|
||||
if (!isInPlace)
|
||||
{
|
||||
if (Platform::isFile(qualifiedFromCSFile))
|
||||
if (Torque::FS::IsFile(qualifiedFromCSFile))
|
||||
{
|
||||
if (!dPathCopy(qualifiedFromCSFile, qualifiedToCSFile, !isReimport))
|
||||
if (!Torque::FS::CopyFile(qualifiedFromCSFile, qualifiedToCSFile, !isReimport))
|
||||
{
|
||||
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to copy file %s", qualifiedFromCSFile);
|
||||
activityLog.push_back(importLogBuffer);
|
||||
|
|
@ -3149,7 +3164,7 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem)
|
|||
else
|
||||
{
|
||||
//We're doing an in-place import, so double check we've already got a constructor file in the expected spot
|
||||
if (Platform::isFile(qualifiedFromCSFile))
|
||||
if (Torque::FS::IsFile(qualifiedFromCSFile))
|
||||
{
|
||||
//Yup, found it, we're good to go
|
||||
makeNewConstructor = false;
|
||||
|
|
@ -3162,7 +3177,7 @@ Torque::Path AssetImporter::importShapeAsset(AssetImportObject* assetItem)
|
|||
Torque::Path constrFilePath = qualifiedFromCSFile;
|
||||
constrFilePath.setExtension("cs");
|
||||
|
||||
if (Platform::isFile(constrFilePath.getFullPath().c_str()))
|
||||
if (Torque::FS::IsFile(constrFilePath.getFullPath().c_str()))
|
||||
{
|
||||
//Yup, found it, we're good to go
|
||||
makeNewConstructor = false;
|
||||
|
|
@ -3324,15 +3339,20 @@ Torque::Path AssetImporter::importSoundAsset(AssetImportObject* assetItem)
|
|||
char qualifiedFromFile[2048];
|
||||
char qualifiedToFile[2048];
|
||||
|
||||
#ifndef TORQUE_SECURE_VFS
|
||||
Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile));
|
||||
Platform::makeFullPathName(assetPath.c_str(), qualifiedToFile, sizeof(qualifiedToFile));
|
||||
#else
|
||||
dStrcpy(qualifiedFromFile, originalPath.c_str(), sizeof(qualifiedFromFile));
|
||||
dStrcpy(qualifiedToFile, assetPath.c_str(), sizeof(qualifiedToFile));
|
||||
#endif
|
||||
|
||||
newAsset->setAssetName(assetName);
|
||||
newAsset->setSoundFile(imageFileName.c_str());
|
||||
|
||||
//If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original
|
||||
//file path for reimporting support later
|
||||
if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Platform::isFile(qualifiedFromFile))
|
||||
if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Torque::FS::IsFile(qualifiedFromFile))
|
||||
{
|
||||
newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile);
|
||||
}
|
||||
|
|
@ -3351,7 +3371,7 @@ Torque::Path AssetImporter::importSoundAsset(AssetImportObject* assetItem)
|
|||
{
|
||||
bool isInPlace = !String::compare(qualifiedFromFile, qualifiedToFile);
|
||||
|
||||
if (!isInPlace && !dPathCopy(qualifiedFromFile, qualifiedToFile, !isReimport))
|
||||
if (!isInPlace && !Torque::FS::CopyFile(qualifiedFromFile, qualifiedToFile, !isReimport))
|
||||
{
|
||||
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to copy file %s", assetItem->filePath.getFullPath().c_str());
|
||||
activityLog.push_back(importLogBuffer);
|
||||
|
|
@ -3380,15 +3400,20 @@ Torque::Path AssetImporter::importShapeAnimationAsset(AssetImportObject* assetIt
|
|||
char qualifiedFromFile[2048];
|
||||
char qualifiedToFile[2048];
|
||||
|
||||
#ifndef TORQUE_SECURE_VFS
|
||||
Platform::makeFullPathName(originalPath.c_str(), qualifiedFromFile, sizeof(qualifiedFromFile));
|
||||
Platform::makeFullPathName(assetPath.c_str(), qualifiedToFile, sizeof(qualifiedToFile));
|
||||
#else
|
||||
dStrcpy(qualifiedFromFile, originalPath.c_str(), sizeof(qualifiedFromFile));
|
||||
dStrcpy(qualifiedToFile, assetPath.c_str(), sizeof(qualifiedToFile));
|
||||
#endif
|
||||
|
||||
newAsset->setAssetName(assetName);
|
||||
newAsset->setAnimationFile(imageFileName.c_str());
|
||||
|
||||
//If it's not a re-import, check that the file isn't being in-place imported. If it isn't, store off the original
|
||||
//file path for reimporting support later
|
||||
if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Platform::isFile(qualifiedFromFile))
|
||||
if (!isReimport && String::compare(qualifiedFromFile, qualifiedToFile) && Torque::FS::IsFile(qualifiedFromFile))
|
||||
{
|
||||
newAsset->setDataField(StringTable->insert("originalFilePath"), nullptr, qualifiedFromFile);
|
||||
}
|
||||
|
|
@ -3407,7 +3432,7 @@ Torque::Path AssetImporter::importShapeAnimationAsset(AssetImportObject* assetIt
|
|||
{
|
||||
bool isInPlace = !String::compare(qualifiedFromFile, qualifiedToFile);
|
||||
|
||||
if (!isInPlace && !dPathCopy(qualifiedFromFile, qualifiedToFile, !isReimport))
|
||||
if (!isInPlace && !Torque::FS::CopyFile(qualifiedFromFile, qualifiedToFile, !isReimport))
|
||||
{
|
||||
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Error! Unable to copy file %s", assetItem->filePath.getFullPath().c_str());
|
||||
activityLog.push_back(importLogBuffer);
|
||||
|
|
|
|||
|
|
@ -330,15 +330,15 @@ void ReflectionProbe::handleDeleteAction()
|
|||
if (mReflectionModeType != StaticCubemap)
|
||||
{
|
||||
String prefilPath = getPrefilterMapPath();
|
||||
if (Platform::isFile(prefilPath))
|
||||
if (Torque::FS::IsFile(prefilPath))
|
||||
{
|
||||
Platform::fileDelete(prefilPath);
|
||||
Torque::FS::Remove(prefilPath);
|
||||
}
|
||||
|
||||
String irrPath = getIrradianceMapPath();
|
||||
if (Platform::isFile(irrPath))
|
||||
if (Torque::FS::IsFile(irrPath))
|
||||
{
|
||||
Platform::fileDelete(irrPath);
|
||||
Torque::FS::Remove(irrPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2157,7 +2157,7 @@ DefineEngineFunction( gotoWebPage, void, ( const char* address ),,
|
|||
// the bogus url, and hope for the best.
|
||||
|
||||
String addr;
|
||||
if( Platform::isFile( address ) || Platform::isDirectory( address ) )
|
||||
if( Torque::FS::IsFile( address ) || Torque::FS::IsDirectory( address ) )
|
||||
{
|
||||
#ifdef TORQUE2D_TOOLS_FIXME
|
||||
addr = String::ToString( "file://%s", address );
|
||||
|
|
|
|||
|
|
@ -368,15 +368,11 @@ DefineEngineFunction(getFileCRC, S32, ( const char* fileName ),,
|
|||
|
||||
"@ingroup FileSystem")
|
||||
{
|
||||
String cleanfilename(Torque::Path::CleanSeparators(fileName));
|
||||
Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), cleanfilename.c_str());
|
||||
|
||||
Torque::Path givenPath(Torque::Path::CompressPath(sgScriptFilenameBuffer));
|
||||
Torque::FS::FileNodeRef fileRef = Torque::FS::GetFileNode( givenPath );
|
||||
Torque::FS::FileNodeRef fileRef = Torque::FS::GetFileNode( fileName );
|
||||
|
||||
if ( fileRef == NULL )
|
||||
{
|
||||
Con::errorf("getFileCRC() - could not access file: [%s]", givenPath.getFullPath().c_str() );
|
||||
Con::errorf("getFileCRC() - could not access file: [%s]", fileName );
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -391,10 +387,7 @@ DefineEngineFunction(isFile, bool, ( const char* fileName ),,
|
|||
|
||||
"@ingroup FileSystem")
|
||||
{
|
||||
String cleanfilename(Torque::Path::CleanSeparators(fileName));
|
||||
Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), cleanfilename.c_str());
|
||||
|
||||
Torque::Path givenPath(Torque::Path::CompressPath(sgScriptFilenameBuffer));
|
||||
Torque::Path givenPath(fileName);
|
||||
|
||||
if (givenPath.getFileName().isEmpty() && givenPath.getExtension().isNotEmpty())
|
||||
{
|
||||
|
|
@ -415,11 +408,7 @@ DefineEngineFunction(isScriptFile, bool, (const char* fileName), ,
|
|||
|
||||
"@ingroup FileSystem")
|
||||
{
|
||||
String cleanfilename(Torque::Path::CleanSeparators(fileName));
|
||||
Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), cleanfilename.c_str());
|
||||
|
||||
Torque::Path givenPath(Torque::Path::CompressPath(sgScriptFilenameBuffer));
|
||||
return Torque::FS::IsScriptFile(givenPath.getFullPath());
|
||||
return Torque::FS::IsScriptFile(fileName);
|
||||
}
|
||||
|
||||
DefineEngineFunction( IsDirectory, bool, ( const char* directory ),,
|
||||
|
|
@ -432,11 +421,7 @@ DefineEngineFunction( IsDirectory, bool, ( const char* directory ),,
|
|||
|
||||
"@ingroup FileSystem")
|
||||
{
|
||||
String dir(Torque::Path::CleanSeparators(directory));
|
||||
Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), dir.c_str());
|
||||
|
||||
Torque::Path givenPath(Torque::Path::CompressPath(sgScriptFilenameBuffer));
|
||||
return Torque::FS::IsDirectory( givenPath );
|
||||
return Torque::FS::IsDirectory( directory );
|
||||
}
|
||||
|
||||
DefineEngineFunction(isWriteableFileName, bool, ( const char* fileName ),,
|
||||
|
|
@ -447,14 +432,7 @@ DefineEngineFunction(isWriteableFileName, bool, ( const char* fileName ),,
|
|||
|
||||
"@ingroup FileSystem")
|
||||
{
|
||||
String filename(Torque::Path::CleanSeparators(fileName));
|
||||
Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), filename.c_str());
|
||||
|
||||
Torque::Path givenPath(Torque::Path::CompressPath(sgScriptFilenameBuffer));
|
||||
Torque::FS::FileSystemRef fs = Torque::FS::GetFileSystem(givenPath);
|
||||
Torque::Path path = fs->mapTo(givenPath);
|
||||
|
||||
return !Torque::FS::IsReadOnly(path);
|
||||
return !Torque::FS::IsReadOnly(fileName);
|
||||
}
|
||||
|
||||
DefineEngineFunction(startFileChangeNotifications, void, (),,
|
||||
|
|
@ -487,7 +465,12 @@ DefineEngineFunction(getDirectoryList, String, ( const char* path, S32 depth ),
|
|||
{
|
||||
// Grab the full path.
|
||||
char fullpath[1024];
|
||||
|
||||
#ifdef TORQUE_SECURE_VFS
|
||||
dStrcpy(fullpath, path, sizeof(fullpath));
|
||||
#else
|
||||
Platform::makeFullPathName(String::compare(path, "/") == 0 ? "" : path, fullpath, sizeof(fullpath));
|
||||
#endif
|
||||
|
||||
//dSprintf(fullpath, 511, "%s/%s", Platform::getWorkingDirectory(), path);
|
||||
|
||||
|
|
@ -501,7 +484,7 @@ DefineEngineFunction(getDirectoryList, String, ( const char* path, S32 depth ),
|
|||
|
||||
// Dump the directories.
|
||||
Vector<StringTableEntry> directories;
|
||||
Platform::dumpDirectories(fullpath, directories, depth, true);
|
||||
Torque::FS::DumpDirectories(fullpath, directories, depth, true);
|
||||
|
||||
if( directories.empty() )
|
||||
return "";
|
||||
|
|
@ -539,8 +522,12 @@ DefineEngineFunction(fileSize, S32, ( const char* fileName ),,
|
|||
|
||||
"@ingroup FileSystem")
|
||||
{
|
||||
Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), fileName);
|
||||
return Platform::getFileSize( sgScriptFilenameBuffer );
|
||||
StrongRefPtr<Torque::FS::FileNode> node = Torque::FS::GetFileNode(fileName);
|
||||
if (node.isValid())
|
||||
{
|
||||
return node->getSize();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
DefineEngineFunction( fileModifiedTime, String, ( const char* fileName ),,
|
||||
|
|
@ -550,20 +537,20 @@ DefineEngineFunction( fileModifiedTime, String, ( const char* fileName ),,
|
|||
"@return Formatted string (OS specific) containing modified time, \"9/3/2010 12:33:47 PM\" for example\n"
|
||||
"@ingroup FileSystem")
|
||||
{
|
||||
Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), fileName);
|
||||
Torque::FS::FileNodeRef node = Torque::FS::GetFileNode(fileName);
|
||||
|
||||
FileTime ft = {0};
|
||||
Platform::getFileTimes( sgScriptFilenameBuffer, NULL, &ft );
|
||||
if (node)
|
||||
{
|
||||
Platform::LocalTime lt = node->getModifiedTime().toLocalTime();
|
||||
|
||||
Platform::LocalTime lt = {0};
|
||||
Platform::fileToLocalTime( ft, < );
|
||||
|
||||
String fileStr = Platform::localTimeToString( lt );
|
||||
|
||||
char *buffer = Con::getReturnBuffer( fileStr.size() );
|
||||
dStrcpy( buffer, fileStr, fileStr.size() );
|
||||
|
||||
return buffer;
|
||||
String fileStr = Platform::localTimeToString(lt);
|
||||
|
||||
char *buffer = Con::getReturnBuffer(fileStr.size());
|
||||
dStrcpy(buffer, fileStr, fileStr.size());
|
||||
|
||||
return buffer;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
DefineEngineFunction( fileCreatedTime, String, ( const char* fileName ),,
|
||||
|
|
@ -573,20 +560,20 @@ DefineEngineFunction( fileCreatedTime, String, ( const char* fileName ),,
|
|||
"@return Formatted string (OS specific) containing created time, \"9/3/2010 12:33:47 PM\" for example\n"
|
||||
"@ingroup FileSystem")
|
||||
{
|
||||
Con::expandScriptFilename( sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), fileName );
|
||||
Torque::FS::FileNodeRef node = Torque::FS::GetFileNode(fileName);
|
||||
|
||||
FileTime ft = {0};
|
||||
Platform::getFileTimes( sgScriptFilenameBuffer, &ft, NULL );
|
||||
if (node)
|
||||
{
|
||||
Platform::LocalTime lt = node->getCreatedTime().toLocalTime();
|
||||
|
||||
Platform::LocalTime lt = {0};
|
||||
Platform::fileToLocalTime( ft, < );
|
||||
String fileStr = Platform::localTimeToString(lt);
|
||||
|
||||
String fileStr = Platform::localTimeToString( lt );
|
||||
char *buffer = Con::getReturnBuffer(fileStr.size());
|
||||
dStrcpy(buffer, fileStr, fileStr.size());
|
||||
|
||||
char *buffer = Con::getReturnBuffer( fileStr.size() );
|
||||
dStrcpy( buffer, fileStr, fileStr.size() );
|
||||
|
||||
return buffer;
|
||||
return buffer;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
DefineEngineFunction(compareFileTimes, S32, (const char* fileA, const char* fileB), ("", ""),
|
||||
|
|
@ -597,17 +584,33 @@ DefineEngineFunction(compareFileTimes, S32, (const char* fileA, const char* file
|
|||
"@return S32. If value is 1, then fileA is newer. If value is -1, then fileB is newer. If value is 0, they are equal.\n"
|
||||
"@ingroup FileSystem")
|
||||
{
|
||||
Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), fileA);
|
||||
Torque::FS::FileNodeRef nodeA = Torque::FS::GetFileNode(fileA);
|
||||
Torque::FS::FileNodeRef nodeB = Torque::FS::GetFileNode(fileB);
|
||||
|
||||
FileTime fileATime = { 0 };
|
||||
Platform::getFileTimes(sgScriptFilenameBuffer, NULL, &fileATime);
|
||||
// Can't do anything if either file doesn't exist
|
||||
if (!nodeA || !nodeB)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Con::expandScriptFilename(sgScriptFilenameBuffer, sizeof(sgScriptFilenameBuffer), fileB);
|
||||
Torque::FS::FileNode::Attributes fileAAttributes;
|
||||
Torque::FS::FileNode::Attributes fileBAttributes;
|
||||
|
||||
FileTime fileBTime = { 0 };
|
||||
Platform::getFileTimes(sgScriptFilenameBuffer, NULL, &fileBTime);
|
||||
// If retrieval of attributes fails, we can't compare
|
||||
if (!nodeA->getAttributes(&fileAAttributes) || !nodeB->getAttributes(&fileBAttributes))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return Platform::compareFileTimes(fileATime, fileBTime);
|
||||
if (fileAAttributes.mtime > fileBAttributes.mtime)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (fileAAttributes.mtime < fileBAttributes.mtime)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
DefineEngineFunction(fileDelete, bool, ( const char* path ),,
|
||||
|
|
@ -618,13 +621,7 @@ DefineEngineFunction(fileDelete, bool, ( const char* path ),,
|
|||
"@return True if file was successfully deleted\n"
|
||||
"@ingroup FileSystem")
|
||||
{
|
||||
static char fileName[1024];
|
||||
static char sandboxFileName[1024];
|
||||
|
||||
Con::expandScriptFilename( fileName, sizeof( fileName ), path );
|
||||
Platform::makeFullPathName(fileName, sandboxFileName, sizeof(sandboxFileName));
|
||||
|
||||
return dFileDelete(sandboxFileName);
|
||||
return Torque::FS::Remove(path);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -839,13 +836,7 @@ DefineEngineFunction( pathCopy, bool, ( const char* fromFile, const char* toFile
|
|||
"@note Only present in a Tools build of Torque.\n"
|
||||
"@ingroup FileSystem")
|
||||
{
|
||||
char qualifiedFromFile[ 2048 ];
|
||||
char qualifiedToFile[ 2048 ];
|
||||
|
||||
Platform::makeFullPathName( fromFile, qualifiedFromFile, sizeof( qualifiedFromFile ) );
|
||||
Platform::makeFullPathName( toFile, qualifiedToFile, sizeof( qualifiedToFile ) );
|
||||
|
||||
return dPathCopy( qualifiedFromFile, qualifiedToFile, noOverwrite );
|
||||
return Torque::FS::CopyFile(fromFile, toFile, noOverwrite);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -857,7 +848,11 @@ DefineEngineFunction( getCurrentDirectory, String, (),,
|
|||
"@see getWorkingDirectory()"
|
||||
"@ingroup FileSystem")
|
||||
{
|
||||
#ifdef TORQUE_SECURE_VFS
|
||||
return Torque::FS::GetCwd();
|
||||
#else
|
||||
return Platform::getCurrentDirectory();
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -870,8 +865,11 @@ DefineEngineFunction( setCurrentDirectory, bool, ( const char* path ),,
|
|||
"@note Only present in a Tools build of Torque.\n"
|
||||
"@ingroup FileSystem")
|
||||
{
|
||||
#ifdef TORQUE_SECURE_VFS
|
||||
return Torque::FS::SetCwd(path);
|
||||
#else
|
||||
return Platform::setCurrentDirectory( StringTable->insert( path ) );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -885,11 +883,7 @@ DefineEngineFunction( createPath, bool, ( const char* path ),,
|
|||
"@note Only present in a Tools build of Torque.\n"
|
||||
"@ingroup FileSystem" )
|
||||
{
|
||||
static char pathName[1024];
|
||||
|
||||
Con::expandScriptFilename( pathName, sizeof( pathName ), path );
|
||||
|
||||
return Platform::createPath( pathName );
|
||||
return Torque::FS::CreatePath(path);
|
||||
}
|
||||
|
||||
DefineEngineFunction(deleteDirectory, bool, (const char* path), ,
|
||||
|
|
|
|||
|
|
@ -46,7 +46,8 @@ namespace Torque
|
|||
mBuffer = dMalloc(mBufferSize);
|
||||
dMemset(mBuffer, 0, mBufferSize);
|
||||
mModified = Time::getCurrentTime();
|
||||
mLastAccess = mModified;
|
||||
mLastAccess = mModified;
|
||||
mCreated = mModified;
|
||||
mFileSystem = fs;
|
||||
}
|
||||
|
||||
|
|
@ -62,6 +63,7 @@ namespace Torque
|
|||
attr->size = mFileSize;
|
||||
attr->mtime = mModified;
|
||||
attr->atime = mLastAccess;
|
||||
attr->ctime = mCreated;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -81,6 +83,7 @@ namespace Torque
|
|||
U32 mBufferSize; // This is the size of the memory buffer >= mFileSize
|
||||
U32 mFileSize; // This is the size of the "file" <= mBufferSize
|
||||
Time mModified; // Last modified
|
||||
Time mCreated; // When Created
|
||||
Time mLastAccess; // Last access
|
||||
MemFileSystem* mFileSystem;
|
||||
};
|
||||
|
|
@ -508,4 +511,4 @@ namespace Torque
|
|||
}
|
||||
} // Namespace Mem
|
||||
|
||||
} // Namespace Torque
|
||||
} // Namespace Torque
|
||||
|
|
|
|||
|
|
@ -129,4 +129,4 @@ namespace Torque
|
|||
} // Namespace
|
||||
} // Namespace
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -195,4 +195,29 @@ void Time::get(S32 *pyear, S32 *pmonth, S32 *pday, S32 *phour, S32 *pminute, S32
|
|||
*pmicrosecond = time % OneSecond;
|
||||
}
|
||||
|
||||
Platform::LocalTime Time::toLocalTime()
|
||||
{
|
||||
Platform::LocalTime result;
|
||||
result.isdst = false;
|
||||
|
||||
S32 year;
|
||||
S32 month;
|
||||
S32 day;
|
||||
S32 hour;
|
||||
S32 minute;
|
||||
S32 second;
|
||||
S32 microsecond;
|
||||
|
||||
get(&year, &month, &day, &hour, &minute, &second, µsecond);
|
||||
result.year = year - 1900;
|
||||
result.month = month - 1;
|
||||
result.yearday = day;
|
||||
result.hour = hour;
|
||||
result.min = minute;
|
||||
result.sec = second;
|
||||
result.monthday = day % 32;
|
||||
result.weekday = day % 7;
|
||||
return result;
|
||||
}
|
||||
|
||||
} // Namespace
|
||||
|
|
|
|||
|
|
@ -26,7 +26,9 @@
|
|||
#ifndef _TORQUE_TYPES_H_
|
||||
#include "platform/types.h"
|
||||
#endif
|
||||
|
||||
#ifndef _PLATFORM_H_
|
||||
#include "platform/platform.h"
|
||||
#endif
|
||||
|
||||
#if defined(TORQUE_COMPILER_VISUALC)
|
||||
#define TORQUE_CONSTANT_S64(a) (a##I64)
|
||||
|
|
@ -105,6 +107,8 @@ public:
|
|||
S64 getMicroseconds() const;
|
||||
S64 getInternalRepresentation() const;
|
||||
|
||||
Platform::LocalTime toLocalTime();
|
||||
|
||||
private:
|
||||
class Tester
|
||||
{
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ public:
|
|||
// use the mod time for both mod and access time, since we only have mod time in the CD
|
||||
attr->mtime = ZipArchive::DOSTimeToTime(mZipEntry->mCD.mModTime, mZipEntry->mCD.mModDate);
|
||||
attr->atime = ZipArchive::DOSTimeToTime(mZipEntry->mCD.mModTime, mZipEntry->mCD.mModDate);
|
||||
attr->ctime = ZipArchive::DOSTimeToTime(mZipEntry->mCD.mModTime, mZipEntry->mCD.mModDate);
|
||||
attr->size = mZipEntry->mCD.mUncompressedSize;
|
||||
|
||||
return true;
|
||||
|
|
@ -197,6 +198,7 @@ public:
|
|||
// use the mod time for both mod and access time, since we only have mod time in the CD
|
||||
attr->mtime = ZipArchive::DOSTimeToTime(mZipEntry->mCD.mModTime, mZipEntry->mCD.mModDate);
|
||||
attr->atime = ZipArchive::DOSTimeToTime(mZipEntry->mCD.mModTime, mZipEntry->mCD.mModDate);
|
||||
attr->ctime = ZipArchive::DOSTimeToTime(mZipEntry->mCD.mModTime, mZipEntry->mCD.mModDate);
|
||||
attr->size = mZipEntry->mCD.mUncompressedSize;
|
||||
|
||||
return true;
|
||||
|
|
@ -291,6 +293,7 @@ public:
|
|||
ZipArchive::ZipEntry* zipEntry = mArchive->getRoot();
|
||||
attr->mtime = ZipArchive::DOSTimeToTime(zipEntry->mCD.mModTime, zipEntry->mCD.mModDate);
|
||||
attr->atime = ZipArchive::DOSTimeToTime(zipEntry->mCD.mModTime, zipEntry->mCD.mModDate);
|
||||
attr->ctime = ZipArchive::DOSTimeToTime(zipEntry->mCD.mModTime, zipEntry->mCD.mModDate);
|
||||
attr->size = zipEntry->mCD.mUncompressedSize;
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -75,4 +75,4 @@ private:
|
|||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -255,6 +255,64 @@ File::~File() {}
|
|||
Directory::Directory() {}
|
||||
Directory::~Directory() {}
|
||||
|
||||
bool Directory::dump(Vector<Path>& out)
|
||||
{
|
||||
const Path sourcePath = getName();
|
||||
|
||||
FileNode::Attributes currentAttributes;
|
||||
while (read(¤tAttributes))
|
||||
{
|
||||
Path currentPath = sourcePath;
|
||||
currentPath.appendPath(currentPath.getFileName());
|
||||
currentPath.setFileName(currentAttributes.name);
|
||||
|
||||
out.push_back(currentPath);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Directory::dumpFiles(Vector<Path>& out)
|
||||
{
|
||||
const Path sourcePath = getName();
|
||||
|
||||
FileNode::Attributes currentAttributes;
|
||||
while (read(¤tAttributes))
|
||||
{
|
||||
Path currentPath = sourcePath;
|
||||
currentPath.appendPath(currentPath.getFileName());
|
||||
currentPath.setFileName(currentAttributes.name);
|
||||
|
||||
if (IsFile(currentPath))
|
||||
{
|
||||
out.push_back(currentPath);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Directory::dumpDirectories(Vector<Path>& out)
|
||||
{
|
||||
const Path sourcePath = getName();
|
||||
|
||||
FileNode::Attributes currentAttributes;
|
||||
while (read(¤tAttributes))
|
||||
{
|
||||
Path currentPath = sourcePath;
|
||||
currentPath.appendPath(currentPath.getFileName());
|
||||
currentPath.setFileName(currentAttributes.name);
|
||||
|
||||
const bool result = IsDirectory(currentPath);
|
||||
if (result)
|
||||
{
|
||||
out.push_back(currentPath);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
FileNode::FileNode()
|
||||
: mChecksum(0)
|
||||
|
|
@ -273,6 +331,18 @@ Time FileNode::getModifiedTime()
|
|||
return attrs.mtime;
|
||||
}
|
||||
|
||||
Time FileNode::getCreatedTime()
|
||||
{
|
||||
Attributes attrs;
|
||||
|
||||
bool success = getAttributes(&attrs);
|
||||
|
||||
if (!success)
|
||||
return Time();
|
||||
|
||||
return attrs.ctime;
|
||||
}
|
||||
|
||||
U64 FileNode::getSize()
|
||||
{
|
||||
Attributes attrs;
|
||||
|
|
@ -500,6 +570,90 @@ Path MountSystem::_normalize(const Path& path)
|
|||
return po;
|
||||
}
|
||||
|
||||
bool MountSystem::copyFile(const Path& source, const Path& destination, bool noOverwrite)
|
||||
{
|
||||
// Exit out early if we're not overriding
|
||||
if (isFile(destination) && noOverwrite)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
FileRef sourceFile = openFile(source, FS::File::AccessMode::Read);
|
||||
const U64 sourceFileSize = sourceFile->getSize();
|
||||
|
||||
void* writeBuffer = dMalloc(sourceFileSize);
|
||||
sourceFile->read(writeBuffer, sourceFileSize);
|
||||
|
||||
FileRef destinationFile = openFile(destination, FS::File::AccessMode::Write);
|
||||
const bool success = destinationFile->write(writeBuffer, sourceFileSize) == sourceFileSize;
|
||||
|
||||
dFree(writeBuffer);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool MountSystem::_dumpDirectories(DirectoryRef directory, Vector<StringTableEntry>& directories, S32 depth, bool noBasePath, S32 currentDepth, const Path& basePath)
|
||||
{
|
||||
Vector<Torque::Path> directoryPaths;
|
||||
if (!directory->dumpDirectories(directoryPaths))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Queries against / will return a directory count of 1, but the code relies on actual directory entries (Eg. /data) so we handle that special case
|
||||
const U32 basePathDirectoryCount = String::compare(basePath.getFullPathWithoutRoot(), "/") == 0 ? basePath.getDirectoryCount() - 1 : basePath.getDirectoryCount();
|
||||
|
||||
for (U32 iteration = 0; iteration < directoryPaths.size(); ++iteration)
|
||||
{
|
||||
const Path& directoryPath = directoryPaths[iteration];
|
||||
|
||||
// Load the full path to the directory unless we're not supposed to include base paths
|
||||
String directoryPathString = directoryPath.getFullPath().c_str();
|
||||
if (noBasePath)
|
||||
{
|
||||
// Build a path representing the directory tree *after* the base path query but excluding the base
|
||||
// So if we queried for data/ and are currently processing data/ExampleModule/datablocks we want to output
|
||||
// ExampleModule/datablocks
|
||||
Path newDirectoryPath;
|
||||
for (U32 iteration = basePathDirectoryCount; iteration < directoryPath.getDirectoryCount(); ++iteration)
|
||||
{
|
||||
if (iteration > basePathDirectoryCount)
|
||||
{
|
||||
newDirectoryPath.setPath(newDirectoryPath.getPath() + "/");
|
||||
}
|
||||
newDirectoryPath.setPath(newDirectoryPath.getPath() + directoryPath.getDirectory(iteration));
|
||||
}
|
||||
|
||||
newDirectoryPath.setFileName(directoryPath.getFileName());
|
||||
newDirectoryPath.setExtension(directoryPath.getExtension());
|
||||
directoryPathString = newDirectoryPath.getFullPathWithoutRoot();
|
||||
}
|
||||
|
||||
// Output result and enumerate subdirectories if we're not too deep according to the depth parameter
|
||||
directories.push_back(StringTable->insert(directoryPathString, true));
|
||||
if (currentDepth <= depth)
|
||||
{
|
||||
const String subdirectoryPath = directoryPath.getFullPath() + "/";
|
||||
|
||||
DirectoryRef nextDirectory = OpenDirectory(subdirectoryPath);
|
||||
_dumpDirectories(nextDirectory, directories, depth, noBasePath, currentDepth + 1, basePath);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MountSystem::dumpDirectories(const Path& path, Vector<StringTableEntry>& directories, S32 depth, bool noBasePath)
|
||||
{
|
||||
if (!isDirectory(path))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
DirectoryRef sourceDirectory = openDirectory(path);
|
||||
return _dumpDirectories(sourceDirectory, directories, depth, noBasePath, 1, path);
|
||||
}
|
||||
|
||||
FileRef MountSystem::createFile(const Path& path)
|
||||
{
|
||||
Path np = _normalize(path);
|
||||
|
|
@ -792,22 +946,19 @@ bool MountSystem::isDirectory(const Path& path, FileSystemRef fsRef)
|
|||
{
|
||||
FileNode::Attributes attr;
|
||||
|
||||
bool result = false;
|
||||
if (fsRef.isNull())
|
||||
{
|
||||
if (getFileAttributes(path,&attr))
|
||||
return attr.flags & FileNode::Directory;
|
||||
return false;
|
||||
if (getFileAttributes(path, &attr))
|
||||
result = (attr.flags & FileNode::Directory) != 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
FileNodeRef fnRef = fsRef->resolve(path);
|
||||
if (fnRef.isNull())
|
||||
return false;
|
||||
|
||||
if (fnRef->getAttributes(&attr))
|
||||
return attr.flags & FileNode::Directory;
|
||||
return false;
|
||||
if (!fnRef.isNull() && fnRef->getAttributes(&attr))
|
||||
result = (attr.flags & FileNode::Directory) != 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool MountSystem::isReadOnly(const Path& path)
|
||||
|
|
@ -905,6 +1056,16 @@ FileRef CreateFile(const Path &path)
|
|||
return sgMountSystem.createFile(path);
|
||||
}
|
||||
|
||||
bool CopyFile(const Path& source, const Path& destination, bool noOverwrite)
|
||||
{
|
||||
return sgMountSystem.copyFile(source, destination, noOverwrite);
|
||||
}
|
||||
|
||||
bool DumpDirectories(const Path& path, Vector<StringTableEntry>& directories, S32 depth, bool noBasePath)
|
||||
{
|
||||
return sgMountSystem.dumpDirectories(path, directories, depth, noBasePath);
|
||||
}
|
||||
|
||||
DirectoryRef CreateDirectory(const Path &path)
|
||||
{
|
||||
return sgMountSystem.createDirectory(path);
|
||||
|
|
|
|||
|
|
@ -114,6 +114,7 @@ public:
|
|||
String name; ///< File/Directory name
|
||||
Time mtime; ///< Last modified time
|
||||
Time atime; ///< Last access time
|
||||
Time ctime; ///< Creation Time
|
||||
U64 size;
|
||||
};
|
||||
|
||||
|
|
@ -128,6 +129,7 @@ public:
|
|||
|
||||
// Convenience routines - may be overridden for optimal access
|
||||
virtual Time getModifiedTime(); ///< @note This will return Time() on failure
|
||||
virtual Time getCreatedTime(); ///< @note This will return Time() on failure
|
||||
virtual U64 getSize(); ///< @note This will return 0 on failure
|
||||
virtual U32 getChecksum(); ///< @note This will return 0 on failure
|
||||
|
||||
|
|
@ -201,7 +203,11 @@ public:
|
|||
// Functions
|
||||
virtual bool open() = 0;
|
||||
virtual bool close() = 0;
|
||||
virtual bool read(Attributes*) = 0;
|
||||
virtual bool read(Attributes*) = 0;
|
||||
|
||||
bool dump(Vector<Path>& out);
|
||||
bool dumpFiles(Vector<Path>& out);
|
||||
bool dumpDirectories(Vector<Path>& out);
|
||||
};
|
||||
|
||||
typedef WeakRefPtr<Directory> DirectoryPtr;
|
||||
|
|
@ -335,6 +341,9 @@ public:
|
|||
virtual ~MountSystem() {}
|
||||
|
||||
FileRef createFile(const Path& path);
|
||||
bool copyFile(const Path& source, const Path& destination, bool noOverwrite);
|
||||
bool dumpDirectories(const Path& path, Vector<StringTableEntry>& directories, S32 depth, bool noBasePath);
|
||||
|
||||
DirectoryRef createDirectory(const Path& path, FileSystemRef fs = NULL);
|
||||
virtual bool createPath(const Path& path);
|
||||
|
||||
|
|
@ -374,6 +383,8 @@ public:
|
|||
void startFileChangeNotifications();
|
||||
void stopFileChangeNotifications();
|
||||
|
||||
private:
|
||||
bool _dumpDirectories(DirectoryRef directory, Vector<StringTableEntry>& directories, S32 depth, bool noBasePath, S32 currentDepth, const Path& basePath);
|
||||
protected:
|
||||
virtual void _log(const String& msg);
|
||||
|
||||
|
|
@ -538,6 +549,12 @@ DirectoryRef OpenDirectory(const Path &file);
|
|||
///@ingroup VolumeSystem
|
||||
FileRef CreateFile(const Path &file);
|
||||
|
||||
/// Copy a file from one location to another.
|
||||
bool CopyFile(const Path& source, const Path& destination, bool noOverride);
|
||||
|
||||
/// Retrieve list of directories in the specified directory.
|
||||
bool DumpDirectories(const Path& path, Vector<StringTableEntry>& directories, S32 depth, bool noBasePath);
|
||||
|
||||
/// Create a directory.
|
||||
/// The directory object is returned in a closed state.
|
||||
///@ingroup VolumeSystem
|
||||
|
|
|
|||
|
|
@ -212,8 +212,13 @@ ImplementEnumType(_TamlFormatMode,
|
|||
AssertFatal(pSimObject != NULL, "Cannot write a NULL object.");
|
||||
AssertFatal(pFilename != NULL, "Cannot write to a NULL filename.");
|
||||
|
||||
// Expand the file-name into the file-path buffer.
|
||||
// Expand the file-name into the file-path buffer unless we're a secure VFS
|
||||
#ifndef TORQUE_SECURE_VFS
|
||||
Con::expandToolScriptFilename(mFilePathBuffer, sizeof(mFilePathBuffer), pFilename);
|
||||
#else
|
||||
dMemset(mFilePathBuffer, 0x00, sizeof(mFilePathBuffer));
|
||||
dMemcpy(mFilePathBuffer, pFilename, dStrlen(pFilename));
|
||||
#endif
|
||||
|
||||
FileStream stream;
|
||||
|
||||
|
|
|
|||
|
|
@ -328,8 +328,13 @@ char * Platform::makeFullPathName(const char *path, char *buffer, U32 size, cons
|
|||
// [rene, 05/05/2008] Based on overall file handling in Torque, it does not seem to make
|
||||
// that much sense to me to base things off the current working directory here.
|
||||
|
||||
#ifndef TORQUE_SCECURE_VFS
|
||||
if(cwd == NULL)
|
||||
cwd = Con::isCurrentScriptToolScript() ? Platform::getMainDotCsDir() : Platform::getCurrentDirectory();
|
||||
#else
|
||||
if (cwd == NULL)
|
||||
cwd = "game:/";
|
||||
#endif
|
||||
|
||||
dStrncpy(buffer, cwd, size);
|
||||
buffer[size-1] = 0;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "console/console.h"
|
||||
#include "platform/platform.h"
|
||||
|
||||
#if defined(TORQUE_OS_WIN)
|
||||
|
|
@ -48,7 +49,49 @@ bool MountDefaults()
|
|||
if ( !mounted )
|
||||
return false;
|
||||
|
||||
#ifdef TORQUE_SECURE_VFS
|
||||
mounted = Mount("/", createNativeFS(path));
|
||||
if (!mounted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef TORQUE_DISABLE_VIRTUAL_MOUNT_SYSTEM
|
||||
// Always mount the data & home dir so scripts work in either configuration. This is used for eg. preferences storage.
|
||||
Path dataDirectory = Platform::getUserDataDirectory();
|
||||
Path appDataDirectory = Path::Join(dataDirectory.getFullPath().c_str(), '/', TORQUE_APP_NAME);
|
||||
Path homeDirectory = Platform::getUserHomeDirectory();
|
||||
Path appHomeDirectory = Path::Join(homeDirectory.getFullPath().c_str(), '/', TORQUE_APP_NAME);
|
||||
|
||||
// Ensure the root of the data directory exists before trying to mount data VFS
|
||||
if (!Platform::FS::IsDirectory(appDataDirectory) && !Platform::FS::CreateDirectory(appDataDirectory))
|
||||
{
|
||||
// NOTE: We can't Con::errorf here because it doesn't actually output by this point in execution
|
||||
}
|
||||
|
||||
// Ensure the root of the home directory exists before trying to mount home VFS
|
||||
if (!Platform::FS::IsDirectory(appHomeDirectory) && !Platform::FS::CreateDirectory(appHomeDirectory))
|
||||
{
|
||||
// NOTE: We can't Con::errorf here because it doesn't actually output by this point in execution
|
||||
}
|
||||
|
||||
// data:/ points to a directory that is usually buried someplace harder to reach on OS
|
||||
mounted = Mount("data", Platform::FS::createNativeFS(appDataDirectory.getFullPath()));
|
||||
if (!mounted)
|
||||
{
|
||||
// NOTE: We can't Con::errorf here because it doesn't actually output by this point in execution
|
||||
return false;
|
||||
}
|
||||
|
||||
// home:/ refers to your Documents/<APPNAME> folder which is easier to reach than the data:/ mount
|
||||
mounted = Mount("home", Platform::FS::createNativeFS(appHomeDirectory.getFullPath()));
|
||||
if (!mounted)
|
||||
{
|
||||
// NOTE: We can't Con::errorf here because it doesn't actually output by this point in execution
|
||||
return false;
|
||||
}
|
||||
|
||||
// Note that the VirtualMountSystem must be enabled in volume.cpp for zip support to work.
|
||||
return MountZips("game");
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -135,6 +135,7 @@ static void copyStatAttributes(const struct stat& info, FileNode::Attributes* at
|
|||
attr->size = info.st_size;
|
||||
attr->mtime = UnixTimeToTime(info.st_mtime);
|
||||
attr->atime = UnixTimeToTime(info.st_atime);
|
||||
attr->ctime = UnixTimeToTime(info.st_ctime);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -595,6 +596,7 @@ String Platform::FS::getAssetDir()
|
|||
/// file systems.
|
||||
bool Platform::FS::InstallFileSystems()
|
||||
{
|
||||
#ifndef TORQUE_SECURE_VFS
|
||||
Platform::FS::Mount( "/", Platform::FS::createNativeFS( String() ) );
|
||||
|
||||
// Setup the current working dir.
|
||||
|
|
@ -611,6 +613,7 @@ bool Platform::FS::InstallFileSystems()
|
|||
// Mount the home directory
|
||||
if (char* home = getenv("HOME"))
|
||||
Platform::FS::Mount( "home", Platform::FS::createNativeFS(home) );
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,6 +143,10 @@ static void _CopyStatAttributes(const WIN32_FIND_DATAW& info, FileNode::Attribut
|
|||
attr->atime = Win32FileTimeToTime(
|
||||
info.ftLastAccessTime.dwLowDateTime,
|
||||
info.ftLastAccessTime.dwHighDateTime);
|
||||
|
||||
attr->ctime = Win32FileTimeToTime(
|
||||
info.ftCreationTime.dwLowDateTime,
|
||||
info.ftCreationTime.dwHighDateTime);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -758,6 +762,7 @@ String Platform::FS::getAssetDir()
|
|||
/// file systems.
|
||||
bool Platform::FS::InstallFileSystems()
|
||||
{
|
||||
#ifndef TORQUE_SECURE_VFS
|
||||
WCHAR buffer[1024];
|
||||
|
||||
// [8/24/2009 tomb] This stops Windows from complaining about drives that have no disks in
|
||||
|
|
@ -792,6 +797,7 @@ bool Platform::FS::InstallFileSystems()
|
|||
wd += '/';
|
||||
|
||||
Platform::FS::SetCwd(wd);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -284,10 +284,7 @@ bool SFXProfile::_preloadBuffer()
|
|||
|
||||
Resource<SFXResource>& SFXProfile::getResource()
|
||||
{
|
||||
char buf[1024];
|
||||
FileName fullFilename = String(Platform::makeFullPathName(mFilename, buf, sizeof(buf)));
|
||||
|
||||
if (!mResource && SFXResource::exists(fullFilename))
|
||||
if (!mResource && SFXResource::exists(mFilename))
|
||||
mResource = SFXResource::load(mFilename);
|
||||
else
|
||||
mResource = NULL;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
#include "windowManager/sdl/sdlWindowMgr.h"
|
||||
#include "platformSDL/sdlInputManager.h"
|
||||
#include "platform/platformVolume.h"
|
||||
#include "core/util/path.h"
|
||||
#include "gfx/gfxDevice.h"
|
||||
#include "core/util/journal/process.h"
|
||||
#include "core/strings/unicode.h"
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ function getUserPath()
|
|||
|
||||
function getPrefpath()
|
||||
{
|
||||
$prefPath = getUserPath() @ "/preferences";
|
||||
$prefPath = "home:/preferences";
|
||||
return $prefPath;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -169,6 +169,9 @@ if(NOT MSVC AND NOT APPLE) # handle single-configuration generator
|
|||
mark_as_advanced(TORQUE_ADDITIONAL_LINKER_FLAGS)
|
||||
endif()
|
||||
|
||||
option(TORQUE_SECURE_VFS "Secure VFS configuration. Arbitrary script access to file system will be heavily restricted." OFF)
|
||||
mark_as_advanced(TORQUE_SECURE_VFS)
|
||||
|
||||
option(TORQUE_MULTITHREAD "Multi Threading" ON)
|
||||
mark_as_advanced(TORQUE_MULTITHREAD)
|
||||
|
||||
|
|
@ -999,4 +1002,4 @@ if(TORQUE_SDL)
|
|||
else()
|
||||
set_target_properties(SDL2 PROPERTIES FOLDER ${TORQUE_LIBS_FOLDER_NAME})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -50,6 +50,9 @@
|
|||
/// Define me if you want path case insensitivity support in ZIP files.
|
||||
#cmakedefine TORQUE_ZIP_PATH_CASE_INSENSITIVE
|
||||
|
||||
/// Define me if you want to enable secure VFS support.
|
||||
#cmakedefine TORQUE_SECURE_VFS
|
||||
|
||||
/// Define me if you want to enable multithreading support.
|
||||
#cmakedefine TORQUE_MULTITHREAD
|
||||
|
||||
|
|
@ -225,4 +228,4 @@
|
|||
#endif
|
||||
|
||||
/// Password to use when opening encrypted zip files. Change this to whatever the password is for your zips.
|
||||
#define DEFAULT_ZIP_PASSWORD "@TORQUE_APP_PASSWORD@"
|
||||
#define DEFAULT_ZIP_PASSWORD "@TORQUE_APP_PASSWORD@"
|
||||
|
|
|
|||
Loading…
Reference in a new issue