From 2d82c9dd5e4872de12bc506a28e9cf3b49f0b136 Mon Sep 17 00:00:00 2001 From: Nicholas Hastings Date: Fri, 8 Nov 2013 10:15:40 -0500 Subject: [PATCH] Fix potential collision when creating directories. Remove staging files from unclean exit. --- DepotDownloader/ContentDownloader.cs | 41 ++++++++++++++++------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/DepotDownloader/ContentDownloader.cs b/DepotDownloader/ContentDownloader.cs index 2e777a57..b3273831 100644 --- a/DepotDownloader/ContentDownloader.cs +++ b/DepotDownloader/ContentDownloader.cs @@ -547,39 +547,44 @@ namespace DepotDownloader newProtoManifest = new ProtoManifest(depotManifest, depot.manifestId); - foreach (var file in depotManifest.Files) + // Pre-process + depotManifest.Files.ForEach(file => { + var fileFinalPath = Path.Combine(depot.installDir, file.FileName); + var fileStagingPath = Path.Combine(stagingDir, file.FileName); + + if (file.Flags.HasFlag(EDepotFileFlag.Directory)) + { + Directory.CreateDirectory(fileFinalPath); + Directory.CreateDirectory(fileStagingPath); + } + else + { + // Some manifests don't explicitly include all necessary directories + Directory.CreateDirectory(Path.GetDirectoryName(fileFinalPath)); + Directory.CreateDirectory(Path.GetDirectoryName(fileStagingPath)); + complete_download_size += file.TotalSize; } + }); var rand = new Random(); - depotManifest.Files.AsParallel().WithDegreeOfParallelism(4).ForAll(file => + depotManifest.Files.Where(f => !f.Flags.HasFlag(EDepotFileFlag.Directory)) + .AsParallel().WithDegreeOfParallelism(4) + .ForAll(file => { var clientIndex = rand.Next(0, cdnClients.Count); string download_path = Path.Combine(depot.installDir, file.FileName); string fileStagingPath = Path.Combine(stagingDir, file.FileName); - if (file.Flags.HasFlag(EDepotFileFlag.Directory)) + // This may still exist if the previous run exited before cleanup + if (File.Exists(fileStagingPath)) { - if (!Directory.Exists(download_path)) - Directory.CreateDirectory(download_path); - if (!Directory.Exists(fileStagingPath)) - Directory.CreateDirectory(fileStagingPath); - return; + File.Delete(fileStagingPath); } - // TODO: review this section compared to above - string dir_path = Path.GetDirectoryName(download_path); - string dir_staging_path = Path.GetDirectoryName(fileStagingPath); - - if (!Directory.Exists(dir_path)) - Directory.CreateDirectory(dir_path); - if (!Directory.Exists(Path.Combine(stagingDir, dir_path))) - Directory.CreateDirectory(dir_staging_path); - //// - FileStream fs = null; List neededChunks; FileInfo fi = new FileInfo(download_path);