Changeset 1223
- Timestamp:
- 9/29/2009 2:48:14 PM (4 years ago)
- File:
-
- 1 edited
-
trunk/eraser6/Eraser.Util/VolumeInfo.cs (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/eraser6/Eraser.Util/VolumeInfo.cs
r1207 r1223 393 393 } 394 394 395 /// <summary> 396 /// Opens a file with read, write, or read/write access. 397 /// </summary> 398 /// <param name="access">A System.IO.FileAccess constant specifying whether 399 /// to open the file with Read, Write, or ReadWrite file access.</param> 400 /// <returns>A System.IO.FileStream object opened in the specified mode 401 /// and access, unshared, and no special file options.</returns> 402 public FileStream Open(FileAccess access) 403 { 404 return Open(access, FileShare.None, FileOptions.None); 405 } 406 407 /// <summary> 408 /// Opens a file with read, write, or read/write access and the specified 409 /// sharing option. 410 /// </summary> 411 /// <param name="access">A System.IO.FileAccess constant specifying whether 412 /// to open the file with Read, Write, or ReadWrite file access.</param> 413 /// <param name="share">A System.IO.FileShare constant specifying the type 414 /// of access other FileStream objects have to this file.</param> 415 /// <returns>A System.IO.FileStream object opened with the specified mode, 416 /// access, sharing options, and no special file options.</returns> 417 public FileStream Open(FileAccess access, FileShare share) 418 { 419 return Open(access, share, FileOptions.None); 420 } 421 422 /// <summary> 423 /// Opens a file with read, write, or read/write access, the specified 424 /// sharing option, and other advanced options. 425 /// </summary> 426 /// <param name="mode">A System.IO.FileMode constant specifying the mode 427 /// (for example, Open or Append) in which to open the file.</param> 428 /// <param name="access">A System.IO.FileAccess constant specifying whether 429 /// to open the file with Read, Write, or ReadWrite file access.</param> 430 /// <param name="share">A System.IO.FileShare constant specifying the type 431 /// of access other FileStream objects have to this file.</param> 432 /// <param name="options">The System.IO.FileOptions constant specifying 433 /// the advanced file options to use when opening the file.</param> 434 /// <returns>A System.IO.FileStream object opened with the specified mode, 435 /// access, sharing options, and special file options.</returns> 436 public FileStream Open(FileAccess access, FileShare share, FileOptions options) 437 { 438 SafeFileHandle handle = OpenHandle(access, share, options); 439 440 //Check that the handle is valid 441 if (handle.IsInvalid) 442 throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()); 443 444 //Return the FileStream 445 return new FileStream(handle, access); 446 } 447 448 private SafeFileHandle OpenHandle(FileAccess access, FileShare share, FileOptions options) 449 { 450 //Access mode 451 uint iAccess = 0; 452 switch (access) 453 { 454 case FileAccess.Read: 455 iAccess = KernelApi.NativeMethods.GENERIC_READ; 456 break; 457 case FileAccess.ReadWrite: 458 iAccess = KernelApi.NativeMethods.GENERIC_READ | 459 KernelApi.NativeMethods.GENERIC_WRITE; 460 break; 461 case FileAccess.Write: 462 iAccess = KernelApi.NativeMethods.GENERIC_WRITE; 463 break; 464 } 465 466 //Sharing mode 467 if ((share & FileShare.Inheritable) != 0) 468 throw new NotSupportedException("Inheritable handles are not supported."); 469 470 //Advanced options 471 if ((options & FileOptions.Asynchronous) != 0) 472 throw new NotSupportedException("Asynchronous handles are not implemented."); 473 474 //Create the handle 475 string openPath = VolumeId; 476 if (openPath.Length > 0 && openPath[openPath.Length - 1] == '\\') 477 openPath = openPath.Remove(openPath.Length - 1); 478 SafeFileHandle result = KernelApi.NativeMethods.CreateFile(openPath, iAccess, 479 (uint)share, IntPtr.Zero, (uint)FileMode.Open, (uint)options, IntPtr.Zero); 480 if (result.IsInvalid) 481 throw KernelApi.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); 482 483 return result; 484 } 485 486 public VolumeLock LockVolume(FileStream stream) 487 { 488 return new VolumeLock(stream.SafeFileHandle); 489 } 490 395 491 private List<string> mountPoints = new List<string>(); 396 492 } 493 494 public class VolumeLock : IDisposable 495 { 496 internal VolumeLock(SafeFileHandle handle) 497 { 498 uint result = 0; 499 for (int i = 0; !KernelApi.NativeMethods.DeviceIoControl(handle, 500 KernelApi.NativeMethods.FSCTL_LOCK_VOLUME, IntPtr.Zero, 0, IntPtr.Zero, 501 0, out result, IntPtr.Zero); ++i) 502 { 503 if (i > 100) 504 throw new IOException("Could not lock volume."); 505 System.Threading.Thread.Sleep(100); 506 } 507 508 Handle = handle; 509 } 510 511 ~VolumeLock() 512 { 513 Dispose(false); 514 } 515 516 public void Dispose() 517 { 518 Dispose(true); 519 } 520 521 void Dispose(bool disposing) 522 { 523 if (disposing) 524 GC.SuppressFinalize(this); 525 526 uint result = 0; 527 if (!KernelApi.NativeMethods.DeviceIoControl(Handle, KernelApi.NativeMethods.FSCTL_UNLOCK_VOLUME, 528 IntPtr.Zero, 0, IntPtr.Zero, 0, out result, IntPtr.Zero)) 529 { 530 throw new IOException("Could not unlock volume."); 531 } 532 } 533 534 private SafeFileHandle Handle; 535 } 397 536 }
Note: See TracChangeset
for help on using the changeset viewer.
