summaryrefslogtreecommitdiff
path: root/utils/xbox/vxconsole/fileio.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/xbox/vxconsole/fileio.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'utils/xbox/vxconsole/fileio.cpp')
-rw-r--r--utils/xbox/vxconsole/fileio.cpp416
1 files changed, 416 insertions, 0 deletions
diff --git a/utils/xbox/vxconsole/fileio.cpp b/utils/xbox/vxconsole/fileio.cpp
new file mode 100644
index 0000000..9b9ca25
--- /dev/null
+++ b/utils/xbox/vxconsole/fileio.cpp
@@ -0,0 +1,416 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// FILEIO.CPP
+//
+// File I/O Service Routines
+//=====================================================================================//
+#include "vxconsole.h"
+
+//-----------------------------------------------------------------------------
+// SystemTimeToString
+//
+// mm/dd/yyyy hh:mm:ss am
+//-----------------------------------------------------------------------------
+char *SystemTimeToString( SYSTEMTIME *systemTime, char *buffer, int bufferSize )
+{
+ char timeString[256];
+ char dateString[256];
+ int length;
+
+ GetDateFormat( LOCALE_SYSTEM_DEFAULT, 0, systemTime, "MM'/'dd'/'yyyy", dateString, sizeof( dateString ) );
+ GetTimeFormat( LOCALE_SYSTEM_DEFAULT, 0, systemTime, "hh':'mm':'ss tt", timeString, sizeof( timeString ) );
+ length = _snprintf( buffer, bufferSize, "%s %s", dateString, timeString );
+ if ( length == -1 )
+ buffer[bufferSize-1] = '\0';
+
+ return buffer;
+}
+
+//-----------------------------------------------------------------------------
+// CompareFileTimes_NTFStoFATX
+//
+//-----------------------------------------------------------------------------
+int CompareFileTimes_NTFStoFATX( FILETIME* ntfsFileTime, char *ntfsTimeString, int ntfsStringSize, FILETIME* fatxFileTime, char *fatxTimeString, int fatxStringSize )
+{
+ SYSTEMTIME ntfsSystemTime;
+ SYSTEMTIME fatxSystemTime;
+ int diff;
+ int ntfsSeconds;
+ int fatxSeconds;
+
+ TIME_ZONE_INFORMATION tzInfo;
+ GetTimeZoneInformation( &tzInfo );
+
+ // cannot compare UTC file times directly
+ // disjoint filesystems - xbox has a +/- 2s error
+ // daylight savings time handling on each file system may cause problems
+ FileTimeToSystemTime( ntfsFileTime, &ntfsSystemTime );
+ FileTimeToSystemTime( fatxFileTime, &fatxSystemTime );
+
+ // operate on local times, assumes xbox and pc are both set for same time zone and daylight saving
+ SYSTEMTIME ntfsLocalTime;
+ SYSTEMTIME fatxLocalTime;
+ SystemTimeToTzSpecificLocalTime( &tzInfo, &ntfsSystemTime, &ntfsLocalTime );
+ SystemTimeToTzSpecificLocalTime( &tzInfo, &fatxSystemTime, &fatxLocalTime );
+
+ if ( ntfsTimeString )
+ {
+ SystemTimeToString( &ntfsLocalTime, ntfsTimeString, ntfsStringSize );
+ }
+
+ if ( fatxTimeString )
+ {
+ SystemTimeToString( &fatxLocalTime, fatxTimeString, fatxStringSize );
+ }
+
+ diff = ntfsLocalTime.wYear-fatxLocalTime.wYear;
+ if ( diff )
+ return diff;
+
+ diff = ntfsLocalTime.wMonth-fatxLocalTime.wMonth;
+ if ( diff )
+ return diff;
+
+ diff = ntfsLocalTime.wDay-fatxLocalTime.wDay;
+ if ( diff )
+ return diff;
+
+ diff = ntfsLocalTime.wHour-fatxLocalTime.wHour;
+ if ( diff )
+ return diff;
+
+ // allow for +/- 3s error
+ ntfsSeconds = ntfsLocalTime.wHour*60*60 + ntfsLocalTime.wMinute*60 + ntfsLocalTime.wSecond;
+ fatxSeconds = fatxLocalTime.wHour*60*60 + fatxLocalTime.wMinute*60 + fatxLocalTime.wSecond;
+
+ diff = ntfsSeconds-fatxSeconds;
+ if ( diff > 3 || diff < -3 )
+ return diff;
+
+ // times are considered equal
+ return 0;
+}
+
+//-----------------------------------------------------------------------------
+// FreeTargetFileList
+//
+//-----------------------------------------------------------------------------
+void FreeTargetFileList( fileNode_t* pFileList )
+{
+ fileNode_t *nodePtr;
+ fileNode_t *nextPtr;
+
+ if ( !pFileList )
+ return;
+
+ nodePtr = pFileList;
+ while ( nodePtr )
+ {
+ nextPtr = nodePtr->nextPtr;
+
+ Sys_Free( nodePtr->filename );
+ Sys_Free( nodePtr );
+
+ nodePtr = nextPtr;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// GetTargetFileList_r
+//
+//-----------------------------------------------------------------------------
+bool GetTargetFileList_r( char* targetPath, bool recurse, int attributes, int level, fileNode_t** pFileList )
+{
+ HRESULT hr;
+ PDM_WALK_DIR pWalkDir = NULL;
+ DM_FILE_ATTRIBUTES fileAttr;
+ bool valid;
+ char filename[MAX_PATH];
+ fileNode_t* nodePtr;
+ bool bGetNormal;
+ int fixedAttributes;
+
+ if ( !level )
+ *pFileList = NULL;
+
+ fixedAttributes = attributes;
+ if ( fixedAttributes & FILE_ATTRIBUTE_NORMAL )
+ {
+ fixedAttributes &= ~FILE_ATTRIBUTE_NORMAL;
+ bGetNormal = true;
+ }
+ else
+ bGetNormal = false;
+
+ while ( 1 )
+ {
+ hr = DmWalkDir( &pWalkDir, targetPath, &fileAttr );
+ if ( hr != XBDM_NOERR )
+ break;
+
+ strcpy( filename, targetPath );
+ Sys_AddFileSeperator( filename, sizeof( filename ) );
+ strcat( filename, fileAttr.Name );
+
+ // restrict to desired attributes
+ if ( ( bGetNormal && !fileAttr.Attributes ) || ( fileAttr.Attributes & fixedAttributes ) )
+ {
+ Sys_NormalizePath( filename, false );
+
+ // create a new file node
+ nodePtr = ( fileNode_t* )Sys_Alloc( sizeof( fileNode_t ) );
+
+ // link it in
+ nodePtr->filename = Sys_CopyString( filename );
+ nodePtr->changeTime = fileAttr.ChangeTime;
+ nodePtr->creationTime = fileAttr.CreationTime;
+ nodePtr->sizeHigh = fileAttr.SizeHigh;
+ nodePtr->sizeLow = fileAttr.SizeLow;
+ nodePtr->attributes = fileAttr.Attributes;
+ nodePtr->level = level;
+ nodePtr->nextPtr = *pFileList;
+ *pFileList = nodePtr;
+ }
+
+ if ( fileAttr.Attributes & FILE_ATTRIBUTE_DIRECTORY )
+ {
+ if ( recurse )
+ {
+ // descend into directory
+ valid = GetTargetFileList_r( filename, recurse, attributes, level+1, pFileList );
+ if ( !valid )
+ return false;
+ }
+ }
+ }
+ DmCloseDir( pWalkDir );
+
+ if ( hr != XBDM_ENDOFLIST )
+ {
+ // failure
+ return false;
+ }
+
+ // ok
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// FileSyncEx
+//
+// -1: failure, 0: nothing, 1: synced
+//-----------------------------------------------------------------------------
+int FileSyncEx( const char* localFilename, const char* targetFilename, int fileSyncMode, bool bVerbose, bool bNoWrite )
+{
+ bool copy;
+ bool pathExist;
+ WIN32_FILE_ATTRIBUTE_DATA localAttributes;
+ DM_FILE_ATTRIBUTES targetAttributes;
+ HRESULT hr;
+ int errCode;
+ int deltaTime;
+ char localTimeString[256];
+ char targetTimeString[256];
+
+ if ( ( fileSyncMode & FSYNC_TYPEMASK ) == FSYNC_OFF )
+ {
+ return 0;
+ }
+
+ if ( !GetFileAttributesEx( localFilename, GetFileExInfoStandard, &localAttributes ) )
+ {
+ // failed to get the local file's attributes
+ if ( bVerbose )
+ {
+ ConsoleWindowPrintf( XBX_CLR_RED, "Sync Failure: Local file %s not available\n", localFilename );
+ }
+ return -1;
+ }
+
+ if ( localAttributes.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
+ {
+ // ignore directory
+ return 0;
+ }
+
+ if ( fileSyncMode & FSYNC_ANDEXISTSONTARGET )
+ {
+ hr = DmGetFileAttributes( targetFilename, &targetAttributes );
+ if ( hr != XBDM_NOERR )
+ {
+ // target doesn't exist, no sync operation should commence
+ if ( bVerbose )
+ {
+ ConsoleWindowPrintf( XBX_CLR_DEFAULT, "No Update, Target file %s not available\n", targetFilename );
+ }
+ return 0;
+ }
+ }
+
+ // default success, no operation
+ errCode = 0;
+
+ // default, create path and copy
+ copy = true;
+ pathExist = false;
+
+ if ( ( fileSyncMode & FSYNC_TYPEMASK ) == FSYNC_IFNEWER )
+ {
+ hr = DmGetFileAttributes( targetFilename, &targetAttributes );
+ if ( hr == XBDM_NOERR )
+ {
+ // target path to file exists
+ pathExist = true;
+
+ // compare times
+ deltaTime = CompareFileTimes_NTFStoFATX( &localAttributes.ftLastWriteTime, localTimeString, sizeof( localTimeString), &targetAttributes.ChangeTime, targetTimeString, sizeof( targetTimeString ) );
+ if ( deltaTime < 0 )
+ {
+ // ntfs is older, fatx is newer, no update
+ if ( bVerbose )
+ {
+ ConsoleWindowPrintf( XBX_CLR_DEFAULT, "No Update, %s [%s] is newer than %s [%s]\n", targetFilename, targetTimeString, localFilename, localTimeString );
+ }
+ copy = false;
+ }
+ else if ( !deltaTime )
+ {
+ // equal times, compare sizes
+ if ( localAttributes.nFileSizeLow == targetAttributes.SizeLow &&
+ localAttributes.nFileSizeHigh == targetAttributes.SizeHigh )
+ {
+ // file appears synced
+ copy = false;
+ }
+ if ( bVerbose )
+ {
+ if ( copy )
+ {
+ ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Update, %s [%s] [%d] has different size than %s [%s] [%d]\n", targetFilename, targetTimeString, targetAttributes.SizeLow, localFilename, localTimeString, localAttributes.nFileSizeLow );
+ }
+ else
+ {
+ ConsoleWindowPrintf( XBX_CLR_DEFAULT, "No Update, %s [%s] [%d] has same time and file size as %s [%s] [%d]\n", targetFilename, targetTimeString, targetAttributes.SizeLow, localFilename, localTimeString, localAttributes.nFileSizeLow );
+ }
+ }
+ }
+ else
+ {
+ // ntfs is newer, fatx is older, update
+ if ( bVerbose )
+ {
+ ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Update, %s [%s] is older than %s [%s]\n", targetFilename, targetTimeString, localFilename, localTimeString );
+ }
+ }
+ }
+ }
+ else if ( ( fileSyncMode & FSYNC_TYPEMASK ) == FSYNC_ALWAYS )
+ {
+ if ( bVerbose )
+ {
+ ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Force Update, %s\n", targetFilename );
+ }
+ }
+
+ if ( copy && !bNoWrite )
+ {
+ if ( !pathExist )
+ {
+ CreateTargetPath( targetFilename );
+ }
+
+ hr = DmSendFile( localFilename, targetFilename );
+ if ( hr == XBDM_NOERR )
+ {
+ // force the target to match the local attributes
+ // to ensure sync
+ memset( &targetAttributes, 0, sizeof( targetAttributes ) );
+ targetAttributes.SizeHigh = localAttributes.nFileSizeHigh;
+ targetAttributes.SizeLow = localAttributes.nFileSizeLow;
+ targetAttributes.CreationTime = localAttributes.ftCreationTime;
+ targetAttributes.ChangeTime = localAttributes.ftLastWriteTime;
+ DmSetFileAttributes( targetFilename, &targetAttributes );
+
+ // success, file copied
+ errCode = 1;
+ }
+ else
+ {
+ // failure
+ if ( bVerbose )
+ {
+ ConsoleWindowPrintf( XBX_CLR_RED, "Sync Failed!\n" );
+ }
+ errCode = -1;
+ }
+
+ DebugCommand( "0x%8.8x = FileSyncEx( %s, %s )\n", hr, localFilename, targetFilename );
+ }
+
+ return errCode;
+}
+
+//-----------------------------------------------------------------------------
+// LoadTargetFile
+//
+//-----------------------------------------------------------------------------
+bool LoadTargetFile( const char *pTargetPath, int *pFileSize, void **pData )
+{
+ DM_FILE_ATTRIBUTES fileAttributes;
+ HRESULT hr;
+ DWORD bytesRead;
+ char *pBuffer;
+
+ *pFileSize = 0;
+ *pData = (void *)NULL;
+
+ hr = DmGetFileAttributes( pTargetPath, &fileAttributes );
+ if ( hr != XBDM_NOERR || !fileAttributes.SizeLow )
+ return false;
+
+ // allocate for size and terminating null
+ pBuffer = (char *)Sys_Alloc( fileAttributes.SizeLow+1 );
+
+ hr = DmReadFilePartial( pTargetPath, 0, (LPBYTE)pBuffer, fileAttributes.SizeLow, &bytesRead );
+ if ( hr != XBDM_NOERR || ( bytesRead != fileAttributes.SizeLow ) )
+ {
+ Sys_Free( pBuffer );
+ return false;
+ }
+
+ // add a terminating null
+ pBuffer[fileAttributes.SizeLow] = '\0';
+
+ *pFileSize = fileAttributes.SizeLow;
+ *pData = pBuffer;
+
+ // success
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// CreateTargetPath
+//
+//-----------------------------------------------------------------------------
+bool CreateTargetPath( const char *pTargetFilename )
+{
+ // create path chain
+ char *pPath;
+ char dirPath[MAX_PATH];
+
+ // prime and skip to first seperator
+ strcpy( dirPath, pTargetFilename );
+ pPath = strchr( dirPath, '\\' );
+ while ( pPath )
+ {
+ pPath = strchr( pPath+1, '\\' );
+ if ( pPath )
+ {
+ *pPath = '\0';
+ DmMkdir( dirPath );
+ *pPath = '\\';
+ }
+ }
+
+ return true;
+}