Changeset 2335
- Timestamp:
- 10/30/11 01:56:23 (19 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/eraser/Eraser.DefaultPlugins/ErasureTargets/FileSystemObjectErasureTarget.cs
r2274 r2335 255 255 info.IsReadOnly = false; 256 256 257 //Make sure the file does not have any attributes which may affect 258 //the erasure process 259 if ((info.Attributes & FileAttributes.Compressed) != 0 || 260 (info.Attributes & FileAttributes.Encrypted) != 0 || 261 (info.Attributes & FileAttributes.SparseFile) != 0) 262 { 263 //Log the error 264 Logger.Log(S._("The file {0} could not be erased because the file was " + 265 "either compressed, encrypted or a sparse file.", info.FullName), 266 LogLevel.Error); 267 return; 268 } 269 270 //Do not erase reparse points, as they will cause other references to the file 271 //to be to garbage. 272 if ((info.Attributes & FileAttributes.ReparsePoint) == 0) 273 fsManager.EraseFileSystemObject(info, method, 274 delegate(long lastWritten, long totalData, int currentPass) 275 { 276 if (Task.Canceled) 277 throw new OperationCanceledException(S._("The task was cancelled.")); 278 279 progress.Total = totalData; 280 progress.Completed += lastWritten; 281 OnProgressChanged(this, new ProgressChangedEventArgs(progress, 282 new TaskProgressChangedEventArgs(info.FullName, currentPass, method.Passes))); 283 }); 284 else 285 Logger.Log(S._("The file {0} is a hard link or a symbolic link thus the " + 286 "contents of the file was not erased.", LogLevel.Notice)); 287 288 //Remove the file. 289 FileInfo fileInfo = info.File; 290 if (fileInfo != null) 291 fsManager.DeleteFile(fileInfo); 257 //Define the callback function for progress reporting. 258 ErasureMethodProgressFunction callback = 259 delegate(long lastWritten, long totalData, int currentPass) 260 { 261 if (Task.Canceled) 262 throw new OperationCanceledException(S._("The task was cancelled.")); 263 264 progress.Total = totalData; 265 progress.Completed += lastWritten; 266 OnProgressChanged(this, new ProgressChangedEventArgs(progress, 267 new TaskProgressChangedEventArgs(info.FullName, currentPass, method.Passes))); 268 }; 269 270 TryEraseStream(fsManager, method, info, callback); 292 271 progress.MarkComplete(); 293 272 } … … 296 275 Logger.Log(S._("The file {0} could not be erased because the file's " + 297 276 "permissions prevent access to the file.", info.FullName), LogLevel.Error); 298 }299 catch (SharingViolationException)300 {301 if (!ManagerLibrary.Settings.ForceUnlockLockedFiles)302 throw;303 304 StringBuilder processStr = new StringBuilder();305 foreach (OpenHandle handle in OpenHandle.Close(info.FullName))306 {307 try308 {309 processStr.AppendFormat(310 System.Globalization.CultureInfo.InvariantCulture,311 "{0}, ", handle.Process.MainModule.FileName);312 }313 catch (System.ComponentModel.Win32Exception)314 {315 processStr.AppendFormat(316 System.Globalization.CultureInfo.InvariantCulture,317 "Process ID {0}, ", handle.Process.Id);318 }319 }320 321 if (processStr.Length != 0)322 Logger.Log(S._("Could not force closure of file \"{0}\" {1}",323 info.FileName, S._("(locked by {0})",324 processStr.ToString().Remove(processStr.Length - 2)).Trim()),325 LogLevel.Error);326 277 } 327 278 finally … … 332 283 } 333 284 } 285 286 /// <summary> 287 /// Attempts to erase a stream, trying to close all open handles if a process has 288 /// a lock on the file. 289 /// </summary> 290 /// <param name="fsManager">The file system provider used to erase the stream.</param> 291 /// <param name="method">The erasure method to use to erase the stream.</param> 292 /// <param name="info">The stream to erase.</param> 293 /// <param name="callback">The erasure progress callback.</param> 294 private void TryEraseStream(FileSystem fsManager, ErasureMethod method, StreamInfo info, 295 ErasureMethodProgressFunction callback) 296 { 297 for (int i = 0; ; ++i) 298 { 299 try 300 { 301 //Make sure the file does not have any attributes which may affect 302 //the erasure process 303 if ((info.Attributes & FileAttributes.Compressed) != 0 || 304 (info.Attributes & FileAttributes.Encrypted) != 0 || 305 (info.Attributes & FileAttributes.SparseFile) != 0) 306 { 307 //Log the error 308 Logger.Log(S._("The file {0} could not be erased because the file was " + 309 "either compressed, encrypted or a sparse file.", info.FullName), 310 LogLevel.Error); 311 return; 312 } 313 314 //Do not erase reparse points, as they will cause other references to the file 315 //to be to garbage. 316 if ((info.Attributes & FileAttributes.ReparsePoint) == 0) 317 fsManager.EraseFileSystemObject(info, method, callback); 318 else 319 Logger.Log(S._("The file {0} is a hard link or a symbolic link thus the " + 320 "contents of the file was not erased.", LogLevel.Notice)); 321 322 //Remove the file. 323 FileInfo fileInfo = info.File; 324 if (fileInfo != null) 325 fsManager.DeleteFile(fileInfo); 326 return; 327 } 328 catch (SharingViolationException) 329 { 330 if (!ManagerLibrary.Settings.ForceUnlockLockedFiles) 331 throw; 332 333 //Try closing all open handles. If it succeeds, we can run the erase again. 334 //To prevent Eraser from deadlocking, we will only attempt this once. Some 335 //programs may be aggressive and keep a handle open in a tight loop. 336 List<OpenHandle> remainingHandles = OpenHandle.Close(info.FullName); 337 if (i == 0 && remainingHandles.Count == 0) 338 continue; 339 340 //Either we could not close all instances, or we already tried twice. Report 341 //the error. 342 StringBuilder processStr = new StringBuilder(); 343 foreach (OpenHandle handle in remainingHandles) 344 { 345 try 346 { 347 processStr.AppendFormat( 348 System.Globalization.CultureInfo.InvariantCulture, 349 "{0}, ", handle.Process.MainModule.FileName); 350 } 351 catch (System.ComponentModel.Win32Exception) 352 { 353 processStr.AppendFormat( 354 System.Globalization.CultureInfo.InvariantCulture, 355 "Process ID {0}, ", handle.Process.Id); 356 } 357 } 358 359 if (processStr.Length != 0) 360 Logger.Log(S._("Could not force closure of file \"{0}\" {1}", 361 info.FileName, S._("(locked by {0})", 362 processStr.ToString().Remove(processStr.Length - 2)).Trim()), 363 LogLevel.Error); 364 } 365 } 366 } 334 367 } 335 368 }
Note: See TracChangeset
for help on using the changeset viewer.
