Team Fortress 2 Source Code as on 22/4/2020
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.
 
 
 
 
 
 

942 lines
26 KiB

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// SYNC_FILES.CPP
//
// Sync Files Routines.
//=====================================================================================//
#include "vxconsole.h"
char g_syncfiles_localPath[MAX_PATH];
char g_syncfiles_targetPath[MAX_PATH];
fileNode_t *g_syncfiles_targetFiles;
int g_syncfiles_numTargetFiles;
CProgress *g_syncFiles_progress;
BOOL g_syncFiles_noWrite;
BOOL g_syncFiles_force;
BOOL g_syncFiles_verbose;
struct dvdimage_t
{
char szString[MAX_PATH];
CUtlString installPath;
CUtlString versionDetailString;
};
CUtlVector< dvdimage_t> g_install_dvdImages;
int g_install_Selection;
bool g_install_bForceSync;
bool g_install_bCleanTarget;
//-----------------------------------------------------------------------------
// SyncFilesDlg_Validate
//
//-----------------------------------------------------------------------------
bool SyncFilesDlg_Validate()
{
if ( !g_connectedToXBox )
{
Sys_MessageBox( "Sync Error", "Cannot sync until connected to XBox." );
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// SyncFilesDlg_Setup
//
//-----------------------------------------------------------------------------
void SyncFilesDlg_Setup( HWND hWnd )
{
SetDlgItemText( hWnd, IDC_SYNCFILES_LOCALPATH, g_syncfiles_localPath );
SetDlgItemText( hWnd, IDC_SYNCFILES_TARGETPATH, g_syncfiles_targetPath );
CheckDlgButton( hWnd, IDC_SYNCFILES_FORCESYNC, g_syncFiles_force ? BST_CHECKED : BST_UNCHECKED );
CheckDlgButton( hWnd, IDC_SYNCFILES_NOWRITE, g_syncFiles_noWrite ? BST_CHECKED : BST_UNCHECKED );
CheckDlgButton( hWnd, IDC_SYNCFILES_VERBOSE, g_syncFiles_verbose ? BST_CHECKED : BST_UNCHECKED );
}
//-----------------------------------------------------------------------------
// SyncFilesDlg_GetChanges
//
//-----------------------------------------------------------------------------
bool SyncFilesDlg_GetChanges( HWND hwnd )
{
char localPath[MAX_PATH];
char targetPath[MAX_PATH];
localPath[0] = '\0';
targetPath[0] = '\0';
GetDlgItemText( hwnd, IDC_SYNCFILES_LOCALPATH, localPath, MAX_PATH );
GetDlgItemText( hwnd, IDC_SYNCFILES_TARGETPATH, targetPath, MAX_PATH );
strcpy( g_syncfiles_localPath, localPath );
Sys_NormalizePath( g_syncfiles_localPath, true );
strcpy( g_syncfiles_targetPath, targetPath );
Sys_NormalizePath( g_syncfiles_targetPath, true );
g_syncFiles_force = IsDlgButtonChecked( hwnd, IDC_SYNCFILES_FORCESYNC ) != 0;
g_syncFiles_noWrite = IsDlgButtonChecked( hwnd, IDC_SYNCFILES_NOWRITE ) != 0;
g_syncFiles_verbose = IsDlgButtonChecked( hwnd, IDC_SYNCFILES_VERBOSE ) != 0;
// success
return ( true );
}
//-----------------------------------------------------------------------------
// SyncFilesDlg_Proc
//
//-----------------------------------------------------------------------------
BOOL CALLBACK SyncFilesDlg_Proc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
{
switch ( message )
{
case WM_INITDIALOG:
SyncFilesDlg_Setup( hwnd );
return ( TRUE );
case WM_COMMAND:
switch ( LOWORD( wParam ) )
{
case IDC_OK:
if ( !SyncFilesDlg_GetChanges( hwnd ) )
break;
EndDialog( hwnd, wParam );
return ( TRUE );
case IDCANCEL:
case IDC_CANCEL:
EndDialog( hwnd, wParam );
return ( TRUE );
}
break;
}
return ( FALSE );
}
//-----------------------------------------------------------------------------
// SyncFiles_FreeTargetList
//
//-----------------------------------------------------------------------------
void SyncFiles_FreeTargetList()
{
g_syncfiles_numTargetFiles = 0;
FreeTargetFileList( g_syncfiles_targetFiles );
g_syncfiles_targetFiles = NULL;
}
//-----------------------------------------------------------------------------
// SyncFiles_DoUpdates
//
//-----------------------------------------------------------------------------
bool SyncFiles_DoUpdates()
{
WIN32_FILE_ATTRIBUTE_DATA localAttributes;
fileNode_t *nodePtr;
char sourceFilename[MAX_PATH];
char statusBuff1[MAX_PATH];
char statusBuff2[MAX_PATH];
int targetPathLen;
char *ptr;
int progress;
int fileSyncMode;
int numSynced;
int retVal;
g_syncFiles_progress->SetStatus( "Syncing Target Files...", "", "" );
g_syncFiles_progress->SetMeter( 0, g_syncfiles_numTargetFiles );
fileSyncMode = FSYNC_ANDEXISTSONTARGET;
if ( g_syncFiles_force )
fileSyncMode |= FSYNC_ALWAYS;
else
fileSyncMode |= FSYNC_IFNEWER;
targetPathLen = strlen( g_syncfiles_targetPath );
numSynced = 0;
progress = 0;
nodePtr = g_syncfiles_targetFiles;
while ( nodePtr )
{
ptr = nodePtr->filename+targetPathLen;
if ( *ptr == '\\' )
ptr++;
// replace with source path head
strcpy( sourceFilename, g_syncfiles_localPath );
Sys_AddFileSeperator( sourceFilename, sizeof( sourceFilename ) );
strcat( sourceFilename, ptr );
float sourceFileSize = 0;
if ( GetFileAttributesEx( sourceFilename, GetFileExInfoStandard, &localAttributes ) )
{
sourceFileSize = (float)localAttributes.nFileSizeLow / (1024.0f * 1024.0f);
}
_snprintf( statusBuff1, sizeof( statusBuff1 ), "Local File: %s (%.2f MB)", sourceFilename, sourceFileSize );
statusBuff1[sizeof( statusBuff1 ) - 1] = '\0';
_snprintf( statusBuff2, sizeof( statusBuff2 ), "Target File: %s", nodePtr->filename );
statusBuff1[sizeof( statusBuff2 ) - 1] = '\0';
g_syncFiles_progress->SetStatus( NULL, statusBuff1, statusBuff2 );
retVal = FileSyncEx( sourceFilename, nodePtr->filename, fileSyncMode, g_syncFiles_verbose != FALSE, g_syncFiles_noWrite != FALSE);
if ( retVal == 1 )
{
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Sync: %s -> %s\n", sourceFilename, nodePtr->filename );
numSynced++;
}
progress++;
g_syncFiles_progress->SetMeter( progress, -1 );
if ( g_syncFiles_progress->IsCancel() )
{
return false;
}
nodePtr = nodePtr->nextPtr;
}
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Synced %d/%d Files.\n", numSynced, g_syncfiles_numTargetFiles );
return true;
}
//-----------------------------------------------------------------------------
// SyncFiles_GetTargetList
//
//-----------------------------------------------------------------------------
bool SyncFiles_GetTargetList( char* pTargetPath )
{
g_syncFiles_progress->SetStatus( "Getting Target Files...", "", "" );
g_syncFiles_progress->SetMeter( 0, 100 );
if ( !GetTargetFileList_r( pTargetPath, true, FA_NORMAL|FA_READONLY, 0, &g_syncfiles_targetFiles ) )
{
ConsoleWindowPrintf( RGB( 255,0,0 ), "Bad Target Path '%s'\n", pTargetPath );
return false;
}
fileNode_t* pFileNode;
for ( pFileNode = g_syncfiles_targetFiles; pFileNode; pFileNode = pFileNode->nextPtr )
{
g_syncfiles_numTargetFiles++;
}
// success
return true;
}
//-----------------------------------------------------------------------------
// SyncFilesDlg_SaveConfig
//
//-----------------------------------------------------------------------------
void SyncFilesDlg_SaveConfig()
{
Sys_SetRegistryString( "syncfiles_localPath", g_syncfiles_localPath );
Sys_SetRegistryString( "syncfiles_targetPath", g_syncfiles_targetPath );
Sys_SetRegistryInteger( "syncfiles_force", g_syncFiles_force );
Sys_SetRegistryInteger( "syncfiles_noWrite", g_syncFiles_noWrite );
Sys_SetRegistryInteger( "syncfiles_verbose", g_syncFiles_verbose );
}
//-----------------------------------------------------------------------------
// SyncFilesDlg_Open
//
//-----------------------------------------------------------------------------
void SyncFilesDlg_Open( void )
{
int result;
bool bError;
bool bValid;
result = DialogBox( g_hInstance, MAKEINTRESOURCE( IDD_SYNCFILES ), g_hDlgMain, ( DLGPROC )SyncFilesDlg_Proc );
if ( LOWORD( result ) != IDC_OK )
return;
SyncFilesDlg_SaveConfig();
if ( !SyncFilesDlg_Validate() )
return;
g_syncFiles_progress = new CProgress;
g_syncFiles_progress->Open( "Sync Files...", true, true );
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "\nSyncing Files From '%s' to '%s'\n", g_syncfiles_localPath, g_syncfiles_targetPath );
bError = true;
// get a file listing from target
bValid = SyncFiles_GetTargetList( g_syncfiles_targetPath );
if ( !bValid )
goto cleanUp;
// mark all files needing update
bValid = SyncFiles_DoUpdates();
if ( !bValid )
goto cleanUp;
bError = false;
cleanUp:
delete g_syncFiles_progress;
g_syncFiles_progress = NULL;
if ( bError )
ConsoleWindowPrintf( XBX_CLR_RED, "Aborted.\n" );
else
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Finished.\n" );
SyncFiles_FreeTargetList();
}
//-----------------------------------------------------------------------------
// SyncFilesDlg_LoadConfig
//
//-----------------------------------------------------------------------------
void SyncFilesDlg_LoadConfig()
{
// get our config
Sys_GetRegistryString( "syncfiles_localPath", g_syncfiles_localPath, g_localPath, sizeof( g_syncfiles_localPath ) );
Sys_GetRegistryString( "syncfiles_targetPath", g_syncfiles_targetPath, g_targetPath, sizeof( g_syncfiles_targetPath ) );
Sys_GetRegistryInteger( "syncfiles_force", false, g_syncFiles_force );
Sys_GetRegistryInteger( "syncfiles_noWrite", false, g_syncFiles_noWrite );
Sys_GetRegistryInteger( "syncfiles_verbose", false, g_syncFiles_verbose );
}
//-----------------------------------------------------------------------------
// SyncFilesDlg_Init
//
//-----------------------------------------------------------------------------
bool SyncFilesDlg_Init()
{
SyncFilesDlg_LoadConfig();
return true;
}
//-----------------------------------------------------------------------------
// InstallDlg_InstallImage
//
//-----------------------------------------------------------------------------
void InstallDlg_InstallImage( const char *pInstallPath, bool bForce, bool bCleanTarget )
{
int errCode;
char *pToken;
char arg1[MAXTOKEN];
char arg2[MAXTOKEN];
char sourceFilename[MAX_PATH];
char sourcePath[MAX_PATH];
char targetFilename[MAX_PATH];
char filename[MAX_PATH];
WIN32_FIND_DATA findData;
HANDLE h;
if ( !pInstallPath[0] )
{
return;
}
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "\nSyncing From Install Depot: %s\n", pInstallPath );
// get the install script
char szScriptPath[MAX_PATH];
V_ComposeFileName( pInstallPath, "../dvd_install.txt", szScriptPath, sizeof( szScriptPath ) );
if ( !Sys_Exists( szScriptPath ) )
{
ConsoleWindowPrintf( XBX_CLR_RED, "Failed to open: %s\n", szScriptPath );
return;
}
// sanity check
// DVD image auto-build failure prevents the presence of the default.xex
char szTempFilename[MAX_PATH];
V_ComposeFileName( pInstallPath, "default.xex", szTempFilename, sizeof( szTempFilename ) );
if ( !Sys_Exists( szTempFilename ) )
{
ConsoleWindowPrintf( XBX_CLR_RED, "Cancelled Installation! DVD Image Auto-Build Process Failed - Missing default.xex!\n" );
return;
}
// get the version detail
char szVersionPath[MAX_PATH];
char *pVersionDetailString = NULL;
V_ComposeFileName( pInstallPath, "version.txt", szVersionPath, sizeof( szVersionPath ) );
if ( Sys_LoadFile( szVersionPath, (void**)&pVersionDetailString ) <= 0 )
{
ConsoleWindowPrintf( XBX_CLR_RED, "Cancelled Installation! DVD Image Auto-Build Process Failed! - Missing version.txt\n" );
return;
}
Sys_LoadScriptFile( szScriptPath );
CProgress* pProgress = new CProgress;
pProgress->Open( "Installing DVD Image...", true, false );
int numFailed = 0;
int numSkipped = 0;
int numUpdated = 0;
int version = 0;
bool bFailed = true;
bool bSyntaxError = false;
bool bCancelled = false;
while ( 1 )
{
pToken = Sys_GetToken( true );
if ( !pToken || !pToken[0] )
break;
if ( pProgress->IsCancel() )
{
bCancelled = true;
break;
}
if ( !stricmp( pToken, "$version" ) )
{
// version <num> <targetroot>
pToken = Sys_GetToken( false );
if ( !pToken || !pToken[0] )
{
bSyntaxError = true;
break;
}
version = atoi( pToken );
if ( version < 0 )
{
version = 0;
}
pToken = Sys_GetToken( false );
if ( !pToken || !pToken[0] )
{
bSyntaxError = true;
break;
}
Sys_StripQuotesFromToken( pToken );
V_FixSlashes( pToken );
if ( pToken[0] == CORRECT_PATH_SEPARATOR )
{
// remove initial slash
memcpy( pToken, pToken+1, strlen( pToken ) );
}
char szRootPath[MAX_PATH];
V_ComposeFileName( g_targetPath, pToken, szRootPath, sizeof( szRootPath ) );
if ( bCleanTarget )
{
// delete any exisiting files at target
DM_FILE_ATTRIBUTES fileAttributes;
HRESULT hr = DmGetFileAttributes( szRootPath, &fileAttributes );
if ( hr == XBDM_NOERR )
{
// delete all files at valid target
V_ComposeFileName( szRootPath, "*.*", szTempFilename, sizeof( szTempFilename ) );
char *pArgs[3];
pArgs[0] = "*del";
pArgs[1] = szTempFilename;
pArgs[2] = "/s";
if ( !lc_del( 3, pArgs ) )
{
ConsoleWindowPrintf( XBX_CLR_RED, "Failed To Delete Files At '%s'.\n", szRootPath );
break;
}
}
}
char szTargetVersionPath[MAX_PATH];
V_ComposeFileName( szRootPath, "version.txt", szTargetVersionPath, sizeof( szTargetVersionPath ) );
if ( !bForce )
{
int fileSize;
char *pTargetVersionDetailString;
if ( !LoadTargetFile( szTargetVersionPath, &fileSize, (void**)&pTargetVersionDetailString ) )
{
// expected version does not exist
// force full install
bForce = true;
}
else if ( strcmp( pVersionDetailString, pTargetVersionDetailString ) != 0 )
{
// different versions
bForce = true;
}
Sys_Free( pTargetVersionDetailString );
}
if ( bForce && !FileSyncEx( szVersionPath, szTargetVersionPath, FSYNC_ALWAYS, true, false ) )
{
numFailed++;
break;
}
}
else if ( !stricmp( pToken, "$print" ) )
{
// print <string>
pToken = Sys_GetToken( false );
if ( !pToken || !pToken[0] )
{
bSyntaxError = true;
break;
}
Sys_StripQuotesFromToken( pToken );
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "%s\n", pToken );
}
else if ( !stricmp( pToken, "$copy" ) )
{
// copy <source> <target>
pToken = Sys_GetToken( false );
if ( !pToken || !pToken[0] )
{
bSyntaxError = true;
break;
}
Sys_StripQuotesFromToken( pToken );
V_FixSlashes( pToken );
if ( !V_strnicmp( pToken, "DVD\\", 4 ) )
{
// skip past DVD, used as a placeholder
pToken += 4;
}
V_ComposeFileName( pInstallPath, pToken, arg1, sizeof( arg1 ) );
pToken = Sys_GetToken( false );
if ( !pToken || !pToken[0] )
{
bSyntaxError = true;
break;
}
Sys_StripQuotesFromToken( pToken );
V_FixSlashes( pToken );
if ( pToken[0] == CORRECT_PATH_SEPARATOR )
{
// remove initial slash
memcpy( pToken, pToken+1, strlen( pToken ) );
}
V_ComposeFileName( g_targetPath, pToken, arg2, sizeof( arg2 ) );
Sys_StripFilename( arg1, sourcePath, sizeof( sourcePath ) );
h = FindFirstFile( arg1, &findData );
if ( h != INVALID_HANDLE_VALUE )
{
do
{
if ( pProgress->IsCancel() )
{
bCancelled = true;
break;
}
if ( !stricmp( findData.cFileName, "." ) || !stricmp( findData.cFileName, ".." ) )
{
continue;
}
if ( findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
{
continue;
}
strcpy( sourceFilename, sourcePath );
Sys_AddFileSeperator( sourceFilename, sizeof( sourceFilename ) );
strcat( sourceFilename, findData.cFileName );
Sys_NormalizePath( sourceFilename, false );
Sys_StripPath( arg2, filename, sizeof( filename ) );
if ( filename[0] )
{
// target filename is specified
strcpy( targetFilename, arg2 );
}
else
{
// target filename is path
strcpy( targetFilename, arg2 );
Sys_AddFileSeperator( targetFilename, sizeof( targetFilename ) );
strcat( targetFilename, findData.cFileName );
Sys_NormalizePath( targetFilename, false );
}
ConsoleWindowPrintf( XBX_CLR_DEFAULT, "\nCopying: %s -> %s\n", sourceFilename, targetFilename );
WIN32_FILE_ATTRIBUTE_DATA localAttributes;
float sourceFileSize = 0;
if ( GetFileAttributesEx( sourceFilename, GetFileExInfoStandard, &localAttributes ) )
{
sourceFileSize = (float)localAttributes.nFileSizeLow / (1024.0f * 1024.0f);
}
char statusBuff1[MAX_PATH];
V_snprintf( statusBuff1, sizeof( statusBuff1 ), "Copying (%.2f MB) ... Please Wait", sourceFileSize );
pProgress->SetStatus( statusBuff1, sourceFilename, targetFilename );
int fileSyncMode = bForce ? FSYNC_ALWAYS : FSYNC_IFNEWER;
errCode = FileSyncEx( sourceFilename, targetFilename, fileSyncMode, true, false );
if ( errCode < 0 )
{
ConsoleWindowPrintf( XBX_CLR_RED, "Sync Failure!\n" );
numFailed++;
}
else if ( errCode == 0 )
{
ConsoleWindowPrintf( XBX_CLR_BLUE, "Sync Skipped!\n" );
numSkipped++;
}
else if ( errCode == 1 )
{
ConsoleWindowPrintf( XBX_CLR_GREEN, "Sync Completed!\n" );
numUpdated++;
}
}
while ( FindNextFile( h, &findData ) );
FindClose( h );
}
}
else if ( !stricmp( pToken, "$end" ) )
{
bFailed = false;
break;
}
else
{
ConsoleWindowPrintf( XBX_CLR_RED, "Unknown token: '%s' in '%s'\n", pToken, szScriptPath );
bSyntaxError = true;
break;
}
}
if ( bSyntaxError )
{
ConsoleWindowPrintf( XBX_CLR_RED, "Syntax Error in '%s'.\n", szScriptPath );
}
if ( bCancelled )
{
ConsoleWindowPrintf( XBX_CLR_RED, "Cancelled Installation!\n" );
}
else if ( bFailed )
{
ConsoleWindowPrintf( XBX_CLR_RED, "Failed Installation!\n" );
}
else
{
char *pCRLF = V_stristr( pVersionDetailString, "\r\n" );
if ( pCRLF )
{
*pCRLF = '\0';
}
// spew stats
ConsoleWindowPrintf( XBX_CLR_BLACK, "\n" );
ConsoleWindowPrintf( XBX_CLR_BLACK, "Installation Completed.\n" );
ConsoleWindowPrintf( XBX_CLR_BLACK, "-----------------------\n" );
ConsoleWindowPrintf( XBX_CLR_BLACK, "Version: %s\n", pVersionDetailString ? pVersionDetailString : "???" );
if ( numFailed )
{
ConsoleWindowPrintf( XBX_CLR_RED, "%d Failures.\n", numFailed );
}
ConsoleWindowPrintf( XBX_CLR_BLACK, "%d Files In Sync.\n", numSkipped );
ConsoleWindowPrintf( XBX_CLR_BLACK, "%d Files Updated.\n", numUpdated );
}
delete pProgress;
Sys_Free( pVersionDetailString );
Sys_FreeScriptFile();
}
//-----------------------------------------------------------------------------
// InstallDlg_GetChanges
//
//-----------------------------------------------------------------------------
bool InstallDlg_GetChanges( HWND hWnd )
{
g_install_bForceSync = IsDlgButtonChecked( hWnd, IDC_INSTALL_FORCESYNC ) != 0;
g_install_bCleanTarget = IsDlgButtonChecked( hWnd, IDC_INSTALL_CLEANTARGET ) != 0;
g_install_Selection = -1;
for ( int i = 0; i < g_install_dvdImages.Count(); i++ )
{
int state = ListView_GetItemState( GetDlgItem( hWnd, IDC_INSTALL_LIST ), i, LVIS_FOCUSED|LVIS_SELECTED );
if ( state == ( LVIS_FOCUSED|LVIS_SELECTED ) )
{
g_install_Selection = i;
break;
}
}
return true;
}
//-----------------------------------------------------------------------------
// SortDVDImages
//
//-----------------------------------------------------------------------------
int SortDVDImages( const dvdimage_t *pA, const dvdimage_t *pB )
{
char szStringA[256];
char szStringB[256];
V_strncpy( szStringA, pA->szString, sizeof( szStringA ) );
V_strncpy( szStringB, pB->szString, sizeof( szStringB ) );
// sort staging first
char *pCommentA = V_stristr( szStringA, " (" );
char *pCommentB = V_stristr( szStringB, " (" );
if ( pCommentA )
{
*pCommentA = '\0';
}
if ( pCommentB )
{
*pCommentB = '\0';
}
return stricmp( szStringB, szStringA );
}
//-----------------------------------------------------------------------------
// InstallDlg_Populate
//
//-----------------------------------------------------------------------------
void InstallDlg_Populate( HWND hWnd )
{
HWND hWndListView = GetDlgItem( hWnd, IDC_INSTALL_LIST );
ListView_DeleteAllItems( hWndListView );
g_install_dvdImages.Purge();
// get list of DVD images
char szPath[MAX_PATH];
V_ComposeFileName( g_installPath, "DVD_*", szPath, sizeof( szPath ) );
WIN32_FIND_DATA findData;
HANDLE h = FindFirstFile( szPath, &findData );
if ( h != INVALID_HANDLE_VALUE )
{
do
{
if ( !stricmp( findData.cFileName, "." ) || !stricmp( findData.cFileName, ".." ) )
{
continue;
}
if ( !( findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) )
{
// skip files
continue;
}
char szInstallPath[MAX_PATH];
V_strncpy( szInstallPath, g_installPath, sizeof( szInstallPath ) );
V_AppendSlash( szInstallPath, sizeof( szInstallPath ) );
V_strncat( szInstallPath, findData.cFileName, sizeof( szInstallPath ) );
// qualify dvd dirs that are images
char szBooterPath[MAX_PATH];
V_ComposeFileName( szInstallPath, "default.xex", szBooterPath, sizeof( szBooterPath ) );
if ( !Sys_Exists( szBooterPath ) )
{
continue;
}
char szVersionPath[MAX_PATH];
V_ComposeFileName( szInstallPath, "version.txt", szVersionPath, sizeof( szVersionPath ) );
char *pVersionDetailString = NULL;
if ( Sys_LoadFile( szVersionPath, (void**)&pVersionDetailString ) == -1 )
{
continue;
}
char *pCRLF = V_stristr( pVersionDetailString, "\r\n" );
if ( pCRLF )
{
*pCRLF = '\0';
}
dvdimage_t image;
int year = 0;
int month = 0;
int day = 0;
int hour = 0;
int minute = 0;
char timeOfDay[256];
sscanf( findData.cFileName, "DVD_%d_%d_%d_%d_%d_%s", &year, &month, &day, &hour, &minute, timeOfDay );
const char *pInfoString = timeOfDay;
if ( !V_strnicmp( timeOfDay, "PM", 2 ) )
{
if ( hour != 12 )
{
// 24 hour time for correct sorting
hour += 12;
}
pInfoString += 2;
}
else if ( !V_strnicmp( timeOfDay, "AM", 2 ) )
{
if ( hour == 12 )
{
// 24 hour time for correct sorting
hour = 0;
}
pInfoString += 2;
}
char szCommentBuff[128];
if ( pInfoString[0] == '_' )
{
// optional info after AM/PM
pInfoString++;
V_snprintf( szCommentBuff, sizeof( szCommentBuff ), " (%s)", pInfoString );
}
else
{
szCommentBuff[0] = '\0';
}
V_snprintf( image.szString, sizeof( image.szString ), "%2.2d/%2.2d/%4.4d %2.2d:%2.2d%s", month, day, year, hour, minute, szCommentBuff );
image.installPath = szInstallPath;
image.versionDetailString = pVersionDetailString;
g_install_dvdImages.AddToTail( image );
Sys_Free( pVersionDetailString );
}
while ( FindNextFile( h, &findData ) );
FindClose( h );
}
// current image will be at head
g_install_dvdImages.Sort( SortDVDImages );
for ( int i = 0; i < g_install_dvdImages.Count(); i++ )
{
// setup and insert at end of list
LVITEM lvi;
memset( &lvi, 0, sizeof( lvi ) );
lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE;
lvi.iItem = i;
lvi.iSubItem = 0;
lvi.state = 0;
lvi.stateMask = 0;
lvi.pszText = LPSTR_TEXTCALLBACK;
lvi.lParam = (LPARAM)i;
ListView_InsertItem( hWndListView, &lvi );
}
if ( g_install_dvdImages.Count() )
{
ListView_SetItemState( hWndListView, 0, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED );
}
}
//-----------------------------------------------------------------------------
// InstallDlg_Setup
//
//-----------------------------------------------------------------------------
void InstallDlg_Setup( HWND hWnd )
{
g_install_Selection = -1;
g_install_bForceSync = false;
g_install_bCleanTarget = false;
HWND hWndListView = GetDlgItem( hWnd, IDC_INSTALL_LIST );
// initialize columns
LVCOLUMN lvc;
memset( &lvc, 0, sizeof( lvc ) );
lvc.mask = LVCF_FMT|LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM;
lvc.iSubItem = 0;
lvc.fmt = LVCFMT_LEFT;
lvc.cx = 200;
lvc.pszText = ( LPSTR )"Date Built:";
ListView_InsertColumn( hWndListView, 0, &lvc );
lvc.iSubItem = 0;
lvc.fmt = LVCFMT_LEFT;
lvc.cx = 500;
lvc.pszText = ( LPSTR )"Perforce Changelist:";
ListView_InsertColumn( hWndListView, 1, &lvc );
ListView_SetBkColor( hWndListView, g_backgroundColor );
ListView_SetTextBkColor( hWndListView, g_backgroundColor );
DWORD style = LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES;
ListView_SetExtendedListViewStyleEx( hWndListView, style, style );
InstallDlg_Populate( hWnd );
}
//-----------------------------------------------------------------------------
// InstallDlg_Proc
//
//-----------------------------------------------------------------------------
BOOL CALLBACK InstallDlg_Proc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
switch ( message )
{
case WM_INITDIALOG:
InstallDlg_Setup( hWnd );
return ( TRUE );
case WM_NOTIFY:
switch ( ( ( LPNMHDR )lParam )->code )
{
case LVN_GETDISPINFO:
NMLVDISPINFO* plvdi;
plvdi = (NMLVDISPINFO*)lParam;
int item = (int)plvdi->item.lParam;
switch ( plvdi->item.iSubItem )
{
case 0:
plvdi->item.pszText = g_install_dvdImages[item].szString;
return TRUE;
case 1:
plvdi->item.pszText = (LPSTR)g_install_dvdImages[item].versionDetailString.String();
return TRUE;
}
}
break;
case WM_COMMAND:
switch ( LOWORD( wParam ) )
{
case IDC_OK:
InstallDlg_GetChanges( hWnd );
EndDialog( hWnd, wParam );
return ( TRUE );
case IDC_INSTALL_REFRESH:
InstallDlg_Populate( hWnd );
return TRUE;
case IDCANCEL:
case IDC_CANCEL:
EndDialog( hWnd, wParam );
return ( TRUE );
}
break;
}
return ( FALSE );
}
//-----------------------------------------------------------------------------
// InstallDlg_Open
//
//-----------------------------------------------------------------------------
void InstallDlg_Open( void )
{
int result = DialogBox( g_hInstance, MAKEINTRESOURCE( IDD_INSTALL ), g_hDlgMain, ( DLGPROC )InstallDlg_Proc );
if ( LOWORD( result ) == IDC_OK && g_install_Selection != -1 )
{
InstallDlg_InstallImage(
g_install_dvdImages[g_install_Selection].installPath.String(),
g_install_bForceSync,
g_install_bCleanTarget );
}
g_install_dvdImages.Purge();
}