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

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // SYNC_FILES.CPP
  4. //
  5. // Sync Files Routines.
  6. //=====================================================================================//
  7. #include "vxconsole.h"
  8. char g_syncfiles_localPath[MAX_PATH];
  9. char g_syncfiles_targetPath[MAX_PATH];
  10. fileNode_t *g_syncfiles_targetFiles;
  11. int g_syncfiles_numTargetFiles;
  12. CProgress *g_syncFiles_progress;
  13. BOOL g_syncFiles_noWrite;
  14. BOOL g_syncFiles_force;
  15. BOOL g_syncFiles_verbose;
  16. struct dvdimage_t
  17. {
  18. char szString[MAX_PATH];
  19. CUtlString installPath;
  20. CUtlString versionDetailString;
  21. };
  22. CUtlVector< dvdimage_t> g_install_dvdImages;
  23. int g_install_Selection;
  24. bool g_install_bForceSync;
  25. bool g_install_bCleanTarget;
  26. //-----------------------------------------------------------------------------
  27. // SyncFilesDlg_Validate
  28. //
  29. //-----------------------------------------------------------------------------
  30. bool SyncFilesDlg_Validate()
  31. {
  32. if ( !g_connectedToXBox )
  33. {
  34. Sys_MessageBox( "Sync Error", "Cannot sync until connected to XBox." );
  35. return false;
  36. }
  37. return true;
  38. }
  39. //-----------------------------------------------------------------------------
  40. // SyncFilesDlg_Setup
  41. //
  42. //-----------------------------------------------------------------------------
  43. void SyncFilesDlg_Setup( HWND hWnd )
  44. {
  45. SetDlgItemText( hWnd, IDC_SYNCFILES_LOCALPATH, g_syncfiles_localPath );
  46. SetDlgItemText( hWnd, IDC_SYNCFILES_TARGETPATH, g_syncfiles_targetPath );
  47. CheckDlgButton( hWnd, IDC_SYNCFILES_FORCESYNC, g_syncFiles_force ? BST_CHECKED : BST_UNCHECKED );
  48. CheckDlgButton( hWnd, IDC_SYNCFILES_NOWRITE, g_syncFiles_noWrite ? BST_CHECKED : BST_UNCHECKED );
  49. CheckDlgButton( hWnd, IDC_SYNCFILES_VERBOSE, g_syncFiles_verbose ? BST_CHECKED : BST_UNCHECKED );
  50. }
  51. //-----------------------------------------------------------------------------
  52. // SyncFilesDlg_GetChanges
  53. //
  54. //-----------------------------------------------------------------------------
  55. bool SyncFilesDlg_GetChanges( HWND hwnd )
  56. {
  57. char localPath[MAX_PATH];
  58. char targetPath[MAX_PATH];
  59. localPath[0] = '\0';
  60. targetPath[0] = '\0';
  61. GetDlgItemText( hwnd, IDC_SYNCFILES_LOCALPATH, localPath, MAX_PATH );
  62. GetDlgItemText( hwnd, IDC_SYNCFILES_TARGETPATH, targetPath, MAX_PATH );
  63. strcpy( g_syncfiles_localPath, localPath );
  64. Sys_NormalizePath( g_syncfiles_localPath, true );
  65. strcpy( g_syncfiles_targetPath, targetPath );
  66. Sys_NormalizePath( g_syncfiles_targetPath, true );
  67. g_syncFiles_force = IsDlgButtonChecked( hwnd, IDC_SYNCFILES_FORCESYNC ) != 0;
  68. g_syncFiles_noWrite = IsDlgButtonChecked( hwnd, IDC_SYNCFILES_NOWRITE ) != 0;
  69. g_syncFiles_verbose = IsDlgButtonChecked( hwnd, IDC_SYNCFILES_VERBOSE ) != 0;
  70. // success
  71. return ( true );
  72. }
  73. //-----------------------------------------------------------------------------
  74. // SyncFilesDlg_Proc
  75. //
  76. //-----------------------------------------------------------------------------
  77. BOOL CALLBACK SyncFilesDlg_Proc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
  78. {
  79. switch ( message )
  80. {
  81. case WM_INITDIALOG:
  82. SyncFilesDlg_Setup( hwnd );
  83. return ( TRUE );
  84. case WM_COMMAND:
  85. switch ( LOWORD( wParam ) )
  86. {
  87. case IDC_OK:
  88. if ( !SyncFilesDlg_GetChanges( hwnd ) )
  89. break;
  90. EndDialog( hwnd, wParam );
  91. return ( TRUE );
  92. case IDCANCEL:
  93. case IDC_CANCEL:
  94. EndDialog( hwnd, wParam );
  95. return ( TRUE );
  96. }
  97. break;
  98. }
  99. return ( FALSE );
  100. }
  101. //-----------------------------------------------------------------------------
  102. // SyncFiles_FreeTargetList
  103. //
  104. //-----------------------------------------------------------------------------
  105. void SyncFiles_FreeTargetList()
  106. {
  107. g_syncfiles_numTargetFiles = 0;
  108. FreeTargetFileList( g_syncfiles_targetFiles );
  109. g_syncfiles_targetFiles = NULL;
  110. }
  111. //-----------------------------------------------------------------------------
  112. // SyncFiles_DoUpdates
  113. //
  114. //-----------------------------------------------------------------------------
  115. bool SyncFiles_DoUpdates()
  116. {
  117. WIN32_FILE_ATTRIBUTE_DATA localAttributes;
  118. fileNode_t *nodePtr;
  119. char sourceFilename[MAX_PATH];
  120. char statusBuff1[MAX_PATH];
  121. char statusBuff2[MAX_PATH];
  122. int targetPathLen;
  123. char *ptr;
  124. int progress;
  125. int fileSyncMode;
  126. int numSynced;
  127. int retVal;
  128. g_syncFiles_progress->SetStatus( "Syncing Target Files...", "", "" );
  129. g_syncFiles_progress->SetMeter( 0, g_syncfiles_numTargetFiles );
  130. fileSyncMode = FSYNC_ANDEXISTSONTARGET;
  131. if ( g_syncFiles_force )
  132. fileSyncMode |= FSYNC_ALWAYS;
  133. else
  134. fileSyncMode |= FSYNC_IFNEWER;
  135. targetPathLen = strlen( g_syncfiles_targetPath );
  136. numSynced = 0;
  137. progress = 0;
  138. nodePtr = g_syncfiles_targetFiles;
  139. while ( nodePtr )
  140. {
  141. ptr = nodePtr->filename+targetPathLen;
  142. if ( *ptr == '\\' )
  143. ptr++;
  144. // replace with source path head
  145. strcpy( sourceFilename, g_syncfiles_localPath );
  146. Sys_AddFileSeperator( sourceFilename, sizeof( sourceFilename ) );
  147. strcat( sourceFilename, ptr );
  148. float sourceFileSize = 0;
  149. if ( GetFileAttributesEx( sourceFilename, GetFileExInfoStandard, &localAttributes ) )
  150. {
  151. sourceFileSize = (float)localAttributes.nFileSizeLow / (1024.0f * 1024.0f);
  152. }
  153. _snprintf( statusBuff1, sizeof( statusBuff1 ), "Local File: %s (%.2f MB)", sourceFilename, sourceFileSize );
  154. statusBuff1[sizeof( statusBuff1 ) - 1] = '\0';
  155. _snprintf( statusBuff2, sizeof( statusBuff2 ), "Target File: %s", nodePtr->filename );
  156. statusBuff1[sizeof( statusBuff2 ) - 1] = '\0';
  157. g_syncFiles_progress->SetStatus( NULL, statusBuff1, statusBuff2 );
  158. retVal = FileSyncEx( sourceFilename, nodePtr->filename, fileSyncMode, g_syncFiles_verbose != FALSE, g_syncFiles_noWrite != FALSE);
  159. if ( retVal == 1 )
  160. {
  161. ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Sync: %s -> %s\n", sourceFilename, nodePtr->filename );
  162. numSynced++;
  163. }
  164. progress++;
  165. g_syncFiles_progress->SetMeter( progress, -1 );
  166. if ( g_syncFiles_progress->IsCancel() )
  167. {
  168. return false;
  169. }
  170. nodePtr = nodePtr->nextPtr;
  171. }
  172. ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Synced %d/%d Files.\n", numSynced, g_syncfiles_numTargetFiles );
  173. return true;
  174. }
  175. //-----------------------------------------------------------------------------
  176. // SyncFiles_GetTargetList
  177. //
  178. //-----------------------------------------------------------------------------
  179. bool SyncFiles_GetTargetList( char* pTargetPath )
  180. {
  181. g_syncFiles_progress->SetStatus( "Getting Target Files...", "", "" );
  182. g_syncFiles_progress->SetMeter( 0, 100 );
  183. if ( !GetTargetFileList_r( pTargetPath, true, FA_NORMAL|FA_READONLY, 0, &g_syncfiles_targetFiles ) )
  184. {
  185. ConsoleWindowPrintf( RGB( 255,0,0 ), "Bad Target Path '%s'\n", pTargetPath );
  186. return false;
  187. }
  188. fileNode_t* pFileNode;
  189. for ( pFileNode = g_syncfiles_targetFiles; pFileNode; pFileNode = pFileNode->nextPtr )
  190. {
  191. g_syncfiles_numTargetFiles++;
  192. }
  193. // success
  194. return true;
  195. }
  196. //-----------------------------------------------------------------------------
  197. // SyncFilesDlg_SaveConfig
  198. //
  199. //-----------------------------------------------------------------------------
  200. void SyncFilesDlg_SaveConfig()
  201. {
  202. Sys_SetRegistryString( "syncfiles_localPath", g_syncfiles_localPath );
  203. Sys_SetRegistryString( "syncfiles_targetPath", g_syncfiles_targetPath );
  204. Sys_SetRegistryInteger( "syncfiles_force", g_syncFiles_force );
  205. Sys_SetRegistryInteger( "syncfiles_noWrite", g_syncFiles_noWrite );
  206. Sys_SetRegistryInteger( "syncfiles_verbose", g_syncFiles_verbose );
  207. }
  208. //-----------------------------------------------------------------------------
  209. // SyncFilesDlg_Open
  210. //
  211. //-----------------------------------------------------------------------------
  212. void SyncFilesDlg_Open( void )
  213. {
  214. int result;
  215. bool bError;
  216. bool bValid;
  217. result = DialogBox( g_hInstance, MAKEINTRESOURCE( IDD_SYNCFILES ), g_hDlgMain, ( DLGPROC )SyncFilesDlg_Proc );
  218. if ( LOWORD( result ) != IDC_OK )
  219. return;
  220. SyncFilesDlg_SaveConfig();
  221. if ( !SyncFilesDlg_Validate() )
  222. return;
  223. g_syncFiles_progress = new CProgress;
  224. g_syncFiles_progress->Open( "Sync Files...", true, true );
  225. ConsoleWindowPrintf( XBX_CLR_DEFAULT, "\nSyncing Files From '%s' to '%s'\n", g_syncfiles_localPath, g_syncfiles_targetPath );
  226. bError = true;
  227. // get a file listing from target
  228. bValid = SyncFiles_GetTargetList( g_syncfiles_targetPath );
  229. if ( !bValid )
  230. goto cleanUp;
  231. // mark all files needing update
  232. bValid = SyncFiles_DoUpdates();
  233. if ( !bValid )
  234. goto cleanUp;
  235. bError = false;
  236. cleanUp:
  237. delete g_syncFiles_progress;
  238. g_syncFiles_progress = NULL;
  239. if ( bError )
  240. ConsoleWindowPrintf( XBX_CLR_RED, "Aborted.\n" );
  241. else
  242. ConsoleWindowPrintf( XBX_CLR_DEFAULT, "Finished.\n" );
  243. SyncFiles_FreeTargetList();
  244. }
  245. //-----------------------------------------------------------------------------
  246. // SyncFilesDlg_LoadConfig
  247. //
  248. //-----------------------------------------------------------------------------
  249. void SyncFilesDlg_LoadConfig()
  250. {
  251. // get our config
  252. Sys_GetRegistryString( "syncfiles_localPath", g_syncfiles_localPath, g_localPath, sizeof( g_syncfiles_localPath ) );
  253. Sys_GetRegistryString( "syncfiles_targetPath", g_syncfiles_targetPath, g_targetPath, sizeof( g_syncfiles_targetPath ) );
  254. Sys_GetRegistryInteger( "syncfiles_force", false, g_syncFiles_force );
  255. Sys_GetRegistryInteger( "syncfiles_noWrite", false, g_syncFiles_noWrite );
  256. Sys_GetRegistryInteger( "syncfiles_verbose", false, g_syncFiles_verbose );
  257. }
  258. //-----------------------------------------------------------------------------
  259. // SyncFilesDlg_Init
  260. //
  261. //-----------------------------------------------------------------------------
  262. bool SyncFilesDlg_Init()
  263. {
  264. SyncFilesDlg_LoadConfig();
  265. return true;
  266. }
  267. //-----------------------------------------------------------------------------
  268. // InstallDlg_InstallImage
  269. //
  270. //-----------------------------------------------------------------------------
  271. void InstallDlg_InstallImage( const char *pInstallPath, bool bForce, bool bCleanTarget )
  272. {
  273. int errCode;
  274. char *pToken;
  275. char arg1[MAXTOKEN];
  276. char arg2[MAXTOKEN];
  277. char sourceFilename[MAX_PATH];
  278. char sourcePath[MAX_PATH];
  279. char targetFilename[MAX_PATH];
  280. char filename[MAX_PATH];
  281. WIN32_FIND_DATA findData;
  282. HANDLE h;
  283. if ( !pInstallPath[0] )
  284. {
  285. return;
  286. }
  287. ConsoleWindowPrintf( XBX_CLR_DEFAULT, "\nSyncing From Install Depot: %s\n", pInstallPath );
  288. // get the install script
  289. char szScriptPath[MAX_PATH];
  290. V_ComposeFileName( pInstallPath, "../dvd_install.txt", szScriptPath, sizeof( szScriptPath ) );
  291. if ( !Sys_Exists( szScriptPath ) )
  292. {
  293. ConsoleWindowPrintf( XBX_CLR_RED, "Failed to open: %s\n", szScriptPath );
  294. return;
  295. }
  296. // sanity check
  297. // DVD image auto-build failure prevents the presence of the default.xex
  298. char szTempFilename[MAX_PATH];
  299. V_ComposeFileName( pInstallPath, "default.xex", szTempFilename, sizeof( szTempFilename ) );
  300. if ( !Sys_Exists( szTempFilename ) )
  301. {
  302. ConsoleWindowPrintf( XBX_CLR_RED, "Cancelled Installation! DVD Image Auto-Build Process Failed - Missing default.xex!\n" );
  303. return;
  304. }
  305. // get the version detail
  306. char szVersionPath[MAX_PATH];
  307. char *pVersionDetailString = NULL;
  308. V_ComposeFileName( pInstallPath, "version.txt", szVersionPath, sizeof( szVersionPath ) );
  309. if ( Sys_LoadFile( szVersionPath, (void**)&pVersionDetailString ) <= 0 )
  310. {
  311. ConsoleWindowPrintf( XBX_CLR_RED, "Cancelled Installation! DVD Image Auto-Build Process Failed! - Missing version.txt\n" );
  312. return;
  313. }
  314. Sys_LoadScriptFile( szScriptPath );
  315. CProgress* pProgress = new CProgress;
  316. pProgress->Open( "Installing DVD Image...", true, false );
  317. int numFailed = 0;
  318. int numSkipped = 0;
  319. int numUpdated = 0;
  320. int version = 0;
  321. bool bFailed = true;
  322. bool bSyntaxError = false;
  323. bool bCancelled = false;
  324. while ( 1 )
  325. {
  326. pToken = Sys_GetToken( true );
  327. if ( !pToken || !pToken[0] )
  328. break;
  329. if ( pProgress->IsCancel() )
  330. {
  331. bCancelled = true;
  332. break;
  333. }
  334. if ( !stricmp( pToken, "$version" ) )
  335. {
  336. // version <num> <targetroot>
  337. pToken = Sys_GetToken( false );
  338. if ( !pToken || !pToken[0] )
  339. {
  340. bSyntaxError = true;
  341. break;
  342. }
  343. version = atoi( pToken );
  344. if ( version < 0 )
  345. {
  346. version = 0;
  347. }
  348. pToken = Sys_GetToken( false );
  349. if ( !pToken || !pToken[0] )
  350. {
  351. bSyntaxError = true;
  352. break;
  353. }
  354. Sys_StripQuotesFromToken( pToken );
  355. V_FixSlashes( pToken );
  356. if ( pToken[0] == CORRECT_PATH_SEPARATOR )
  357. {
  358. // remove initial slash
  359. memcpy( pToken, pToken+1, strlen( pToken ) );
  360. }
  361. char szRootPath[MAX_PATH];
  362. V_ComposeFileName( g_targetPath, pToken, szRootPath, sizeof( szRootPath ) );
  363. if ( bCleanTarget )
  364. {
  365. // delete any exisiting files at target
  366. DM_FILE_ATTRIBUTES fileAttributes;
  367. HRESULT hr = DmGetFileAttributes( szRootPath, &fileAttributes );
  368. if ( hr == XBDM_NOERR )
  369. {
  370. // delete all files at valid target
  371. V_ComposeFileName( szRootPath, "*.*", szTempFilename, sizeof( szTempFilename ) );
  372. char *pArgs[3];
  373. pArgs[0] = "*del";
  374. pArgs[1] = szTempFilename;
  375. pArgs[2] = "/s";
  376. if ( !lc_del( 3, pArgs ) )
  377. {
  378. ConsoleWindowPrintf( XBX_CLR_RED, "Failed To Delete Files At '%s'.\n", szRootPath );
  379. break;
  380. }
  381. }
  382. }
  383. char szTargetVersionPath[MAX_PATH];
  384. V_ComposeFileName( szRootPath, "version.txt", szTargetVersionPath, sizeof( szTargetVersionPath ) );
  385. if ( !bForce )
  386. {
  387. int fileSize;
  388. char *pTargetVersionDetailString;
  389. if ( !LoadTargetFile( szTargetVersionPath, &fileSize, (void**)&pTargetVersionDetailString ) )
  390. {
  391. // expected version does not exist
  392. // force full install
  393. bForce = true;
  394. }
  395. else if ( strcmp( pVersionDetailString, pTargetVersionDetailString ) != 0 )
  396. {
  397. // different versions
  398. bForce = true;
  399. }
  400. Sys_Free( pTargetVersionDetailString );
  401. }
  402. if ( bForce && !FileSyncEx( szVersionPath, szTargetVersionPath, FSYNC_ALWAYS, true, false ) )
  403. {
  404. numFailed++;
  405. break;
  406. }
  407. }
  408. else if ( !stricmp( pToken, "$print" ) )
  409. {
  410. // print <string>
  411. pToken = Sys_GetToken( false );
  412. if ( !pToken || !pToken[0] )
  413. {
  414. bSyntaxError = true;
  415. break;
  416. }
  417. Sys_StripQuotesFromToken( pToken );
  418. ConsoleWindowPrintf( XBX_CLR_DEFAULT, "%s\n", pToken );
  419. }
  420. else if ( !stricmp( pToken, "$copy" ) )
  421. {
  422. // copy <source> <target>
  423. pToken = Sys_GetToken( false );
  424. if ( !pToken || !pToken[0] )
  425. {
  426. bSyntaxError = true;
  427. break;
  428. }
  429. Sys_StripQuotesFromToken( pToken );
  430. V_FixSlashes( pToken );
  431. if ( !V_strnicmp( pToken, "DVD\\", 4 ) )
  432. {
  433. // skip past DVD, used as a placeholder
  434. pToken += 4;
  435. }
  436. V_ComposeFileName( pInstallPath, pToken, arg1, sizeof( arg1 ) );
  437. pToken = Sys_GetToken( false );
  438. if ( !pToken || !pToken[0] )
  439. {
  440. bSyntaxError = true;
  441. break;
  442. }
  443. Sys_StripQuotesFromToken( pToken );
  444. V_FixSlashes( pToken );
  445. if ( pToken[0] == CORRECT_PATH_SEPARATOR )
  446. {
  447. // remove initial slash
  448. memcpy( pToken, pToken+1, strlen( pToken ) );
  449. }
  450. V_ComposeFileName( g_targetPath, pToken, arg2, sizeof( arg2 ) );
  451. Sys_StripFilename( arg1, sourcePath, sizeof( sourcePath ) );
  452. h = FindFirstFile( arg1, &findData );
  453. if ( h != INVALID_HANDLE_VALUE )
  454. {
  455. do
  456. {
  457. if ( pProgress->IsCancel() )
  458. {
  459. bCancelled = true;
  460. break;
  461. }
  462. if ( !stricmp( findData.cFileName, "." ) || !stricmp( findData.cFileName, ".." ) )
  463. {
  464. continue;
  465. }
  466. if ( findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
  467. {
  468. continue;
  469. }
  470. strcpy( sourceFilename, sourcePath );
  471. Sys_AddFileSeperator( sourceFilename, sizeof( sourceFilename ) );
  472. strcat( sourceFilename, findData.cFileName );
  473. Sys_NormalizePath( sourceFilename, false );
  474. Sys_StripPath( arg2, filename, sizeof( filename ) );
  475. if ( filename[0] )
  476. {
  477. // target filename is specified
  478. strcpy( targetFilename, arg2 );
  479. }
  480. else
  481. {
  482. // target filename is path
  483. strcpy( targetFilename, arg2 );
  484. Sys_AddFileSeperator( targetFilename, sizeof( targetFilename ) );
  485. strcat( targetFilename, findData.cFileName );
  486. Sys_NormalizePath( targetFilename, false );
  487. }
  488. ConsoleWindowPrintf( XBX_CLR_DEFAULT, "\nCopying: %s -> %s\n", sourceFilename, targetFilename );
  489. WIN32_FILE_ATTRIBUTE_DATA localAttributes;
  490. float sourceFileSize = 0;
  491. if ( GetFileAttributesEx( sourceFilename, GetFileExInfoStandard, &localAttributes ) )
  492. {
  493. sourceFileSize = (float)localAttributes.nFileSizeLow / (1024.0f * 1024.0f);
  494. }
  495. char statusBuff1[MAX_PATH];
  496. V_snprintf( statusBuff1, sizeof( statusBuff1 ), "Copying (%.2f MB) ... Please Wait", sourceFileSize );
  497. pProgress->SetStatus( statusBuff1, sourceFilename, targetFilename );
  498. int fileSyncMode = bForce ? FSYNC_ALWAYS : FSYNC_IFNEWER;
  499. errCode = FileSyncEx( sourceFilename, targetFilename, fileSyncMode, true, false );
  500. if ( errCode < 0 )
  501. {
  502. ConsoleWindowPrintf( XBX_CLR_RED, "Sync Failure!\n" );
  503. numFailed++;
  504. }
  505. else if ( errCode == 0 )
  506. {
  507. ConsoleWindowPrintf( XBX_CLR_BLUE, "Sync Skipped!\n" );
  508. numSkipped++;
  509. }
  510. else if ( errCode == 1 )
  511. {
  512. ConsoleWindowPrintf( XBX_CLR_GREEN, "Sync Completed!\n" );
  513. numUpdated++;
  514. }
  515. }
  516. while ( FindNextFile( h, &findData ) );
  517. FindClose( h );
  518. }
  519. }
  520. else if ( !stricmp( pToken, "$end" ) )
  521. {
  522. bFailed = false;
  523. break;
  524. }
  525. else
  526. {
  527. ConsoleWindowPrintf( XBX_CLR_RED, "Unknown token: '%s' in '%s'\n", pToken, szScriptPath );
  528. bSyntaxError = true;
  529. break;
  530. }
  531. }
  532. if ( bSyntaxError )
  533. {
  534. ConsoleWindowPrintf( XBX_CLR_RED, "Syntax Error in '%s'.\n", szScriptPath );
  535. }
  536. if ( bCancelled )
  537. {
  538. ConsoleWindowPrintf( XBX_CLR_RED, "Cancelled Installation!\n" );
  539. }
  540. else if ( bFailed )
  541. {
  542. ConsoleWindowPrintf( XBX_CLR_RED, "Failed Installation!\n" );
  543. }
  544. else
  545. {
  546. char *pCRLF = V_stristr( pVersionDetailString, "\r\n" );
  547. if ( pCRLF )
  548. {
  549. *pCRLF = '\0';
  550. }
  551. // spew stats
  552. ConsoleWindowPrintf( XBX_CLR_BLACK, "\n" );
  553. ConsoleWindowPrintf( XBX_CLR_BLACK, "Installation Completed.\n" );
  554. ConsoleWindowPrintf( XBX_CLR_BLACK, "-----------------------\n" );
  555. ConsoleWindowPrintf( XBX_CLR_BLACK, "Version: %s\n", pVersionDetailString ? pVersionDetailString : "???" );
  556. if ( numFailed )
  557. {
  558. ConsoleWindowPrintf( XBX_CLR_RED, "%d Failures.\n", numFailed );
  559. }
  560. ConsoleWindowPrintf( XBX_CLR_BLACK, "%d Files In Sync.\n", numSkipped );
  561. ConsoleWindowPrintf( XBX_CLR_BLACK, "%d Files Updated.\n", numUpdated );
  562. }
  563. delete pProgress;
  564. Sys_Free( pVersionDetailString );
  565. Sys_FreeScriptFile();
  566. }
  567. //-----------------------------------------------------------------------------
  568. // InstallDlg_GetChanges
  569. //
  570. //-----------------------------------------------------------------------------
  571. bool InstallDlg_GetChanges( HWND hWnd )
  572. {
  573. g_install_bForceSync = IsDlgButtonChecked( hWnd, IDC_INSTALL_FORCESYNC ) != 0;
  574. g_install_bCleanTarget = IsDlgButtonChecked( hWnd, IDC_INSTALL_CLEANTARGET ) != 0;
  575. g_install_Selection = -1;
  576. for ( int i = 0; i < g_install_dvdImages.Count(); i++ )
  577. {
  578. int state = ListView_GetItemState( GetDlgItem( hWnd, IDC_INSTALL_LIST ), i, LVIS_FOCUSED|LVIS_SELECTED );
  579. if ( state == ( LVIS_FOCUSED|LVIS_SELECTED ) )
  580. {
  581. g_install_Selection = i;
  582. break;
  583. }
  584. }
  585. return true;
  586. }
  587. //-----------------------------------------------------------------------------
  588. // SortDVDImages
  589. //
  590. //-----------------------------------------------------------------------------
  591. int SortDVDImages( const dvdimage_t *pA, const dvdimage_t *pB )
  592. {
  593. char szStringA[256];
  594. char szStringB[256];
  595. V_strncpy( szStringA, pA->szString, sizeof( szStringA ) );
  596. V_strncpy( szStringB, pB->szString, sizeof( szStringB ) );
  597. // sort staging first
  598. char *pCommentA = V_stristr( szStringA, " (" );
  599. char *pCommentB = V_stristr( szStringB, " (" );
  600. if ( pCommentA )
  601. {
  602. *pCommentA = '\0';
  603. }
  604. if ( pCommentB )
  605. {
  606. *pCommentB = '\0';
  607. }
  608. return stricmp( szStringB, szStringA );
  609. }
  610. //-----------------------------------------------------------------------------
  611. // InstallDlg_Populate
  612. //
  613. //-----------------------------------------------------------------------------
  614. void InstallDlg_Populate( HWND hWnd )
  615. {
  616. HWND hWndListView = GetDlgItem( hWnd, IDC_INSTALL_LIST );
  617. ListView_DeleteAllItems( hWndListView );
  618. g_install_dvdImages.Purge();
  619. // get list of DVD images
  620. char szPath[MAX_PATH];
  621. V_ComposeFileName( g_installPath, "DVD_*", szPath, sizeof( szPath ) );
  622. WIN32_FIND_DATA findData;
  623. HANDLE h = FindFirstFile( szPath, &findData );
  624. if ( h != INVALID_HANDLE_VALUE )
  625. {
  626. do
  627. {
  628. if ( !stricmp( findData.cFileName, "." ) || !stricmp( findData.cFileName, ".." ) )
  629. {
  630. continue;
  631. }
  632. if ( !( findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) )
  633. {
  634. // skip files
  635. continue;
  636. }
  637. char szInstallPath[MAX_PATH];
  638. V_strncpy( szInstallPath, g_installPath, sizeof( szInstallPath ) );
  639. V_AppendSlash( szInstallPath, sizeof( szInstallPath ) );
  640. V_strncat( szInstallPath, findData.cFileName, sizeof( szInstallPath ) );
  641. // qualify dvd dirs that are images
  642. char szBooterPath[MAX_PATH];
  643. V_ComposeFileName( szInstallPath, "default.xex", szBooterPath, sizeof( szBooterPath ) );
  644. if ( !Sys_Exists( szBooterPath ) )
  645. {
  646. continue;
  647. }
  648. char szVersionPath[MAX_PATH];
  649. V_ComposeFileName( szInstallPath, "version.txt", szVersionPath, sizeof( szVersionPath ) );
  650. char *pVersionDetailString = NULL;
  651. if ( Sys_LoadFile( szVersionPath, (void**)&pVersionDetailString ) == -1 )
  652. {
  653. continue;
  654. }
  655. char *pCRLF = V_stristr( pVersionDetailString, "\r\n" );
  656. if ( pCRLF )
  657. {
  658. *pCRLF = '\0';
  659. }
  660. dvdimage_t image;
  661. int year = 0;
  662. int month = 0;
  663. int day = 0;
  664. int hour = 0;
  665. int minute = 0;
  666. char timeOfDay[256];
  667. sscanf( findData.cFileName, "DVD_%d_%d_%d_%d_%d_%s", &year, &month, &day, &hour, &minute, timeOfDay );
  668. const char *pInfoString = timeOfDay;
  669. if ( !V_strnicmp( timeOfDay, "PM", 2 ) )
  670. {
  671. if ( hour != 12 )
  672. {
  673. // 24 hour time for correct sorting
  674. hour += 12;
  675. }
  676. pInfoString += 2;
  677. }
  678. else if ( !V_strnicmp( timeOfDay, "AM", 2 ) )
  679. {
  680. if ( hour == 12 )
  681. {
  682. // 24 hour time for correct sorting
  683. hour = 0;
  684. }
  685. pInfoString += 2;
  686. }
  687. char szCommentBuff[128];
  688. if ( pInfoString[0] == '_' )
  689. {
  690. // optional info after AM/PM
  691. pInfoString++;
  692. V_snprintf( szCommentBuff, sizeof( szCommentBuff ), " (%s)", pInfoString );
  693. }
  694. else
  695. {
  696. szCommentBuff[0] = '\0';
  697. }
  698. V_snprintf( image.szString, sizeof( image.szString ), "%2.2d/%2.2d/%4.4d %2.2d:%2.2d%s", month, day, year, hour, minute, szCommentBuff );
  699. image.installPath = szInstallPath;
  700. image.versionDetailString = pVersionDetailString;
  701. g_install_dvdImages.AddToTail( image );
  702. Sys_Free( pVersionDetailString );
  703. }
  704. while ( FindNextFile( h, &findData ) );
  705. FindClose( h );
  706. }
  707. // current image will be at head
  708. g_install_dvdImages.Sort( SortDVDImages );
  709. for ( int i = 0; i < g_install_dvdImages.Count(); i++ )
  710. {
  711. // setup and insert at end of list
  712. LVITEM lvi;
  713. memset( &lvi, 0, sizeof( lvi ) );
  714. lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_STATE;
  715. lvi.iItem = i;
  716. lvi.iSubItem = 0;
  717. lvi.state = 0;
  718. lvi.stateMask = 0;
  719. lvi.pszText = LPSTR_TEXTCALLBACK;
  720. lvi.lParam = (LPARAM)i;
  721. ListView_InsertItem( hWndListView, &lvi );
  722. }
  723. if ( g_install_dvdImages.Count() )
  724. {
  725. ListView_SetItemState( hWndListView, 0, LVIS_SELECTED|LVIS_FOCUSED, LVIS_SELECTED|LVIS_FOCUSED );
  726. }
  727. }
  728. //-----------------------------------------------------------------------------
  729. // InstallDlg_Setup
  730. //
  731. //-----------------------------------------------------------------------------
  732. void InstallDlg_Setup( HWND hWnd )
  733. {
  734. g_install_Selection = -1;
  735. g_install_bForceSync = false;
  736. g_install_bCleanTarget = false;
  737. HWND hWndListView = GetDlgItem( hWnd, IDC_INSTALL_LIST );
  738. // initialize columns
  739. LVCOLUMN lvc;
  740. memset( &lvc, 0, sizeof( lvc ) );
  741. lvc.mask = LVCF_FMT|LVCF_WIDTH|LVCF_TEXT|LVCF_SUBITEM;
  742. lvc.iSubItem = 0;
  743. lvc.fmt = LVCFMT_LEFT;
  744. lvc.cx = 200;
  745. lvc.pszText = ( LPSTR )"Date Built:";
  746. ListView_InsertColumn( hWndListView, 0, &lvc );
  747. lvc.iSubItem = 0;
  748. lvc.fmt = LVCFMT_LEFT;
  749. lvc.cx = 500;
  750. lvc.pszText = ( LPSTR )"Perforce Changelist:";
  751. ListView_InsertColumn( hWndListView, 1, &lvc );
  752. ListView_SetBkColor( hWndListView, g_backgroundColor );
  753. ListView_SetTextBkColor( hWndListView, g_backgroundColor );
  754. DWORD style = LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES;
  755. ListView_SetExtendedListViewStyleEx( hWndListView, style, style );
  756. InstallDlg_Populate( hWnd );
  757. }
  758. //-----------------------------------------------------------------------------
  759. // InstallDlg_Proc
  760. //
  761. //-----------------------------------------------------------------------------
  762. BOOL CALLBACK InstallDlg_Proc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
  763. {
  764. switch ( message )
  765. {
  766. case WM_INITDIALOG:
  767. InstallDlg_Setup( hWnd );
  768. return ( TRUE );
  769. case WM_NOTIFY:
  770. switch ( ( ( LPNMHDR )lParam )->code )
  771. {
  772. case LVN_GETDISPINFO:
  773. NMLVDISPINFO* plvdi;
  774. plvdi = (NMLVDISPINFO*)lParam;
  775. int item = (int)plvdi->item.lParam;
  776. switch ( plvdi->item.iSubItem )
  777. {
  778. case 0:
  779. plvdi->item.pszText = g_install_dvdImages[item].szString;
  780. return TRUE;
  781. case 1:
  782. plvdi->item.pszText = (LPSTR)g_install_dvdImages[item].versionDetailString.String();
  783. return TRUE;
  784. }
  785. }
  786. break;
  787. case WM_COMMAND:
  788. switch ( LOWORD( wParam ) )
  789. {
  790. case IDC_OK:
  791. InstallDlg_GetChanges( hWnd );
  792. EndDialog( hWnd, wParam );
  793. return ( TRUE );
  794. case IDC_INSTALL_REFRESH:
  795. InstallDlg_Populate( hWnd );
  796. return TRUE;
  797. case IDCANCEL:
  798. case IDC_CANCEL:
  799. EndDialog( hWnd, wParam );
  800. return ( TRUE );
  801. }
  802. break;
  803. }
  804. return ( FALSE );
  805. }
  806. //-----------------------------------------------------------------------------
  807. // InstallDlg_Open
  808. //
  809. //-----------------------------------------------------------------------------
  810. void InstallDlg_Open( void )
  811. {
  812. int result = DialogBox( g_hInstance, MAKEINTRESOURCE( IDD_INSTALL ), g_hDlgMain, ( DLGPROC )InstallDlg_Proc );
  813. if ( LOWORD( result ) == IDC_OK && g_install_Selection != -1 )
  814. {
  815. InstallDlg_InstallImage(
  816. g_install_dvdImages[g_install_Selection].installPath.String(),
  817. g_install_bForceSync,
  818. g_install_bCleanTarget );
  819. }
  820. g_install_dvdImages.Purge();
  821. }