/// <summary> /// Checks to ensure that all the parts of the file path are legal, and then /// reassembles them into the physical path to the file on the local disk. /// </summary> /// <param name="type"></param> /// <param name="container"></param> /// <param name="file"></param> /// <returns></returns> public static string GetFilePath(string type, string container, string relativeDirectory, string file) { if (AutoUpdateManager.IsFilenameOrDirectorySafe(type) == false) { throw new Exception("Invalid type."); } if (AutoUpdateManager.IsFilenameOrDirectorySafe(container) == false) { throw new Exception("Invalid container."); } // The relative directory can contain \, but it shouldn't contain .. ever! if (relativeDirectory.StartsWith("\\") || relativeDirectory.StartsWith("//") || relativeDirectory.Contains("..")) { throw new Exception("Invalid relative directory."); } if (AutoUpdateManager.IsFilenameOrDirectorySafe(file) == false) { throw new Exception("Invalid filename."); } string containerPath = Path.Combine(type, container); string relativePath = containerPath; if (String.IsNullOrEmpty(relativeDirectory) == false) { relativePath = Path.Combine(containerPath, relativeDirectory); } string filePath = Path.Combine(relativePath, file); return(filePath); }
public static bool TryGetPublicationFiles(int publicationID, out Dictionary <string, UpdateItem> filesInPublication, out List <FileCollision> fileCollisions) { filesInPublication = new Dictionary <string, UpdateItem>(); fileCollisions = new List <FileCollision>(); foreach (FileInfo packageInfo in AutoUpdateManager.GetPackages()) { if (AutoUpdateManager.IsPackageExcludedFromPublication(publicationID, packageInfo.Name) == false) { foreach (UpdateItem fileInfo in AutoUpdateManager.GetFilesInUpdatePackage(packageInfo.Name)) { if (fileInfo.IsIncluded == false) { continue; } string relativeFilePath = Path.Combine(fileInfo.RelativeDirectory, fileInfo.Name); if (filesInPublication.ContainsKey(relativeFilePath) == true) { FileCollision fileCollision = new FileCollision(); fileCollision.CollidingFile = Path.Combine(packageInfo.Name, relativeFilePath); fileCollision.PreferredFile = Path.Combine(filesInPublication[relativeFilePath].PackageName, relativeFilePath); fileCollisions.Add(fileCollision); continue; } else { filesInPublication.Add(relativeFilePath, fileInfo); } } } } return(true); }
public static bool DeployPublication(int publicationID) { using (var db = new DataAccess.CSSDataContext()) { DataAccess.Lobby lobby = db.Lobbies.FirstOrDefault(p => p.Id == publicationID); if (lobby == null) { throw new Exception("Couldn't get lobby for publication id: " + publicationID); } if (Directory.Exists(lobby.BasePath) == false) { Directory.CreateDirectory(lobby.BasePath); } List <FileCollision> fileCollisions = new List <FileCollision>(); Dictionary <string, UpdateItem> filesInPublication = new Dictionary <string, UpdateItem>(); // Remove physical files from the directory. Not doing this with a recursive directory delete because // I don't want someone to put in a bad path into the content manager web UI, and then drill the // whole drive. foreach (DataAccess.AutoUpdateFile_Lobby file in db.AutoUpdateFile_Lobbies.Where(p => p.LobbyId == lobby.Id)) { string fileToDelete = Path.Combine(lobby.BasePath, file.AutoUpdateFile.Filename); if (File.Exists(fileToDelete) == true) { File.Delete(fileToDelete); } } // Clear all files for the lobby. db.AutoUpdateFile_Lobbies.DeleteAllOnSubmit(db.AutoUpdateFile_Lobbies.Where(p => p.LobbyId == lobby.Id)); db.SubmitChanges(); if (AutoUpdateManager.TryGetPublicationFiles(publicationID, out filesInPublication, out fileCollisions) == true) { foreach (UpdateItem fileInfo in filesInPublication.Values) { string checksum; using (SHA1 hasher = SHA1.Create()) { using (FileStream fs = new FileStream(fileInfo.FileInfo.FullName, FileMode.Open, FileAccess.Read)) checksum = Convert.ToBase64String(hasher.ComputeHash(fs)); } string fileVersion = String.Empty; FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(fileInfo.FileInfo.FullName); // Doing it this way, as sometimes there is product or vendor info at the // end of the file version spec. ProductVersion may not correctly reflect the actual // version of the file all the time. if (fileVersionInfo != null && fileVersionInfo.FileVersion != null) { fileVersion = String.Format("{0}.{1}.{2}.{3}", fileVersionInfo.FileMajorPart, fileVersionInfo.FileMinorPart, fileVersionInfo.FileBuildPart, fileVersionInfo.FilePrivatePart); } string relativeFilePath = Path.Combine(fileInfo.RelativeDirectory, fileInfo.Name); DataAccess.AutoUpdateFile autoUpdateFile = db.AutoUpdateFiles.FirstOrDefault(p => p.Filename == relativeFilePath); if (autoUpdateFile == null) { autoUpdateFile = new ACSSAuth.DataAccess.AutoUpdateFile() { Filename = relativeFilePath, IsProtected = fileInfo.IsProtected }; db.AutoUpdateFiles.InsertOnSubmit(autoUpdateFile); db.SubmitChanges(); } else { if (autoUpdateFile.IsProtected != fileInfo.IsProtected) { autoUpdateFile.IsProtected = fileInfo.IsProtected; db.SubmitChanges(); } } DataAccess.AutoUpdateFile_Lobby lobbyFile = db.AutoUpdateFile_Lobbies.FirstOrDefault(p => p.AutoUpdateFileId == autoUpdateFile.Id && p.LobbyId == lobby.Id); if (lobbyFile == null) { lobbyFile = new ACSSAuth.DataAccess.AutoUpdateFile_Lobby() { AutoUpdateFileId = autoUpdateFile.Id, CurrentVersion = fileVersion, DateCreated = fileInfo.FileInfo.CreationTime, DateModified = fileInfo.FileInfo.LastWriteTime, ValidChecksum = checksum, LobbyId = lobby.Id }; db.AutoUpdateFile_Lobbies.InsertOnSubmit(lobbyFile); db.SubmitChanges(); } string targetFilePath = Path.Combine(lobby.BasePath, relativeFilePath); string targetFileDirectory = Path.GetDirectoryName(targetFilePath); if (Directory.Exists(targetFileDirectory) == false) { Directory.CreateDirectory(targetFileDirectory); } File.Copy(fileInfo.FileInfo.FullName, targetFilePath, true); } } // Clean up any unused AutoUpdateFile records. //db.AutoUpdateFiles.DeleteAllOnSubmit(db.AutoUpdateFiles.Where(p => db.AutoUpdateFile_Lobbies.Select(r => r.AutoUpdateFileId).Contains(p.Id) == false)); //db.SubmitChanges(); } return(true); }