Changeset 2191
- Timestamp:
- 6/18/2010 3:05:22 PM (3 years ago)
- File:
-
- 1 edited
-
trunk/eraser/Eraser.Util/PhysicalDriveInfo.cs (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/eraser/Eraser.Util/PhysicalDriveInfo.cs
r2188 r2191 66 66 { 67 67 using (SafeFileHandle handle = OpenWin32Device(GetDiskPath(i), 68 NativeMethods.FILE_READ_ATTRIBUTES ))68 NativeMethods.FILE_READ_ATTRIBUTES, FileShare.ReadWrite, FileOptions.None)) 69 69 { 70 70 if (handle.IsInvalid) … … 76 76 77 77 return result.AsReadOnly(); 78 }79 }80 81 /// <summary>82 /// Opens a device in the Win32 Namespace.83 /// </summary>84 /// <param name="deviceName">The name of the device to open.</param>85 /// <param name="access">The access needed for the handle.</param>86 /// <returns>A <see cref="SafeFileHandle"/> to the device.</returns>87 private static SafeFileHandle OpenWin32Device(string deviceName, uint access)88 {89 //Define the DOS device name for access90 string dosDeviceName = string.Format(CultureInfo.InvariantCulture,91 "eraser{0}_{1}", System.Diagnostics.Process.GetCurrentProcess().Id,92 System.AppDomain.GetCurrentThreadId());93 if (!NativeMethods.DefineDosDevice(94 NativeMethods.DosDeviceDefineFlags.RawTargetPath, dosDeviceName,95 deviceName))96 {97 throw Win32ErrorCode.GetExceptionForWin32Error(Marshal.GetLastWin32Error());98 }99 100 try101 {102 //Open the device handle.103 return NativeMethods.CreateFile(string.Format(CultureInfo.InvariantCulture,104 "\\\\.\\{0}", dosDeviceName), access,105 NativeMethods.FILE_SHARE_READ | NativeMethods.FILE_SHARE_WRITE, IntPtr.Zero,106 (int)FileMode.Open, (uint)FileAttributes.ReadOnly, IntPtr.Zero);107 }108 finally109 {110 //Then undefine the DOS device111 if (!NativeMethods.DefineDosDevice(112 NativeMethods.DosDeviceDefineFlags.ExactMatchOnRmove |113 NativeMethods.DosDeviceDefineFlags.RawTargetPath |114 NativeMethods.DosDeviceDefineFlags.RemoveDefinition,115 dosDeviceName, deviceName))116 {117 throw Win32ErrorCode.GetExceptionForWin32Error(Marshal.GetLastWin32Error());118 }119 78 } 120 79 } … … 134 93 string path = GetPartitionPath(i); 135 94 using (SafeFileHandle handle = OpenWin32Device(path, 136 NativeMethods.FILE_READ_ATTRIBUTES ))95 NativeMethods.FILE_READ_ATTRIBUTES, FileShare.ReadWrite, FileOptions.None)) 137 96 { 138 97 if (handle.IsInvalid) … … 171 130 { 172 131 using (SafeFileHandle handle = OpenWin32Device(GetDiskPath(), 173 NativeMethods.GENERIC_READ ))132 NativeMethods.GENERIC_READ, FileShare.ReadWrite, FileOptions.None)) 174 133 { 175 134 if (handle.IsInvalid) … … 189 148 } 190 149 150 /// <summary> 151 /// Opens a file with read, write, or read/write access. 152 /// </summary> 153 /// <param name="access">A System.IO.FileAccess constant specifying whether 154 /// to open the file with Read, Write, or ReadWrite file access.</param> 155 /// <returns>A System.IO.FileStream object opened in the specified mode 156 /// and access, unshared, and no special file options.</returns> 157 public FileStream Open(FileAccess access) 158 { 159 return Open(access, FileShare.None, FileOptions.None); 160 } 161 162 /// <summary> 163 /// Opens a file with read, write, or read/write access and the specified 164 /// sharing option. 165 /// </summary> 166 /// <param name="access">A System.IO.FileAccess constant specifying whether 167 /// to open the file with Read, Write, or ReadWrite file access.</param> 168 /// <param name="share">A System.IO.FileShare constant specifying the type 169 /// of access other FileStream objects have to this file.</param> 170 /// <returns>A System.IO.FileStream object opened with the specified mode, 171 /// access, sharing options, and no special file options.</returns> 172 public FileStream Open(FileAccess access, FileShare share) 173 { 174 return Open(access, share, FileOptions.None); 175 } 176 177 /// <summary> 178 /// Opens a file with read, write, or read/write access, the specified 179 /// sharing option, and other advanced options. 180 /// </summary> 181 /// <param name="mode">A System.IO.FileMode constant specifying the mode 182 /// (for example, Open or Append) in which to open the file.</param> 183 /// <param name="access">A System.IO.FileAccess constant specifying whether 184 /// to open the file with Read, Write, or ReadWrite file access.</param> 185 /// <param name="share">A System.IO.FileShare constant specifying the type 186 /// of access other FileStream objects have to this file.</param> 187 /// <param name="options">The System.IO.FileOptions constant specifying 188 /// the advanced file options to use when opening the file.</param> 189 /// <returns>A System.IO.FileStream object opened with the specified mode, 190 /// access, sharing options, and special file options.</returns> 191 public FileStream Open(FileAccess access, FileShare share, FileOptions options) 192 { 193 SafeFileHandle handle = OpenHandle(access, share, options); 194 195 //Check that the handle is valid 196 if (handle.IsInvalid) 197 { 198 int errorCode = Marshal.GetLastWin32Error(); 199 handle.Close(); 200 throw Win32ErrorCode.GetExceptionForWin32Error(errorCode); 201 } 202 203 //Return the stream 204 return new PhysicalDriveStream(this, handle, access); 205 } 206 207 private SafeFileHandle OpenHandle(FileAccess access, FileShare share, 208 FileOptions options) 209 { 210 //Access mode 211 uint iAccess = 0; 212 switch (access) 213 { 214 case FileAccess.Read: 215 iAccess = NativeMethods.GENERIC_READ; 216 break; 217 case FileAccess.ReadWrite: 218 iAccess = NativeMethods.GENERIC_READ | NativeMethods.GENERIC_WRITE; 219 break; 220 case FileAccess.Write: 221 iAccess = NativeMethods.GENERIC_WRITE; 222 break; 223 } 224 225 return OpenHandle(iAccess, share, options); 226 } 227 228 private SafeFileHandle OpenHandle(uint access, FileShare share, 229 FileOptions options) 230 { 231 //Sharing mode 232 if ((share & FileShare.Inheritable) != 0) 233 throw new NotSupportedException("Inheritable handles are not supported."); 234 235 //Advanced options 236 if ((options & FileOptions.Asynchronous) != 0) 237 throw new NotSupportedException("Asynchronous handles are not implemented."); 238 239 //Create the handle 240 SafeFileHandle result = OpenWin32Device(GetDiskPath(), access, share, options); 241 if (result.IsInvalid) 242 { 243 int errorCode = Marshal.GetLastWin32Error(); 244 result.Close(); 245 throw Win32ErrorCode.GetExceptionForWin32Error(errorCode); 246 } 247 248 return result; 249 } 250 251 /// <summary> 252 /// Opens a device in the Win32 Namespace. 253 /// </summary> 254 /// <param name="deviceName">The name of the device to open.</param> 255 /// <param name="access">The access needed for the handle.</param> 256 /// <returns>A <see cref="SafeFileHandle"/> to the device.</returns> 257 private static SafeFileHandle OpenWin32Device(string deviceName, uint access, 258 FileShare share, FileOptions options) 259 { 260 //Define the DOS device name for access 261 string dosDeviceName = string.Format(CultureInfo.InvariantCulture, 262 "eraser{0}_{1}", System.Diagnostics.Process.GetCurrentProcess().Id, 263 System.Threading.Thread.CurrentThread.ManagedThreadId); 264 if (!NativeMethods.DefineDosDevice( 265 NativeMethods.DosDeviceDefineFlags.RawTargetPath, dosDeviceName, 266 deviceName)) 267 { 268 throw Win32ErrorCode.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); 269 } 270 271 try 272 { 273 //Open the device handle. 274 return NativeMethods.CreateFile(string.Format(CultureInfo.InvariantCulture, 275 "\\\\.\\{0}", dosDeviceName), access, (uint)share, IntPtr.Zero, 276 (int)FileMode.Open, (uint)options, IntPtr.Zero); 277 } 278 finally 279 { 280 //Then undefine the DOS device 281 if (!NativeMethods.DefineDosDevice( 282 NativeMethods.DosDeviceDefineFlags.ExactMatchOnRmove | 283 NativeMethods.DosDeviceDefineFlags.RawTargetPath | 284 NativeMethods.DosDeviceDefineFlags.RemoveDefinition, 285 dosDeviceName, deviceName)) 286 { 287 throw Win32ErrorCode.GetExceptionForWin32Error(Marshal.GetLastWin32Error()); 288 } 289 } 290 } 291 191 292 public override bool Equals(object obj) 192 293 { … … 237 338 } 238 339 } 340 341 public class PhysicalDriveStream : FileStream 342 { 343 internal PhysicalDriveStream(PhysicalDriveInfo drive, SafeFileHandle handle, 344 FileAccess access) 345 : base(handle, access) 346 { 347 Drive = drive; 348 } 349 350 public override void SetLength(long value) 351 { 352 throw new InvalidOperationException(); 353 } 354 355 public override long Length 356 { 357 get 358 { 359 return Drive.Size; 360 } 361 } 362 363 /// <summary> 364 /// The <see cref="VolumeInfo"/> object this stream is encapsulating. 365 /// </summary> 366 private PhysicalDriveInfo Drive; 367 } 239 368 }
Note: See TracChangeset
for help on using the changeset viewer.
