Как я могу читать диск напрямую с .Net?

Можно ли читать диск напрямую с .Net? Под прямым я имею в виду через устройство в обход файловой системы. Я думаю, я бы пошел по этому пути, открыв устройство, например, "\ Device \ Ide \ IdeDeviceP2T0L0-1".

Если я не могу открыть устройство с помощью .NET API, было бы полезно знать, какой Win32 API использовать.

 Ali03 янв. 2012 г., 10:56
У меня похожий вопрос, не могли бы вы мне помочь?CreateFile: «Доступ запрещен» даже с правами администратора - Win7

Ответы на вопрос(4)

что если включен контроль учетных записей (по умолчанию в Windows Vista и выше), ваша программа должна работать с повышенными правами (с правами администратора). Если ваша программа используется только для нескольких пользователей, вы можете попросить пользователя щелкнуть правой кнопкой мыши исполняемые файлы и выбрать «Запуск от имени администратора». В противном случае вы можете скомпилировать файл манифеста в программу и в манифесте указать, что программу необходимо запускать с повышенными правами (для получения дополнительной информации выполните поиск по запросу «requiredExecutionLevel requireAdministrator»).

почему бы просто не написать dll на C и отказаться от .NET

Вы могли бы тогда p / вызвать вашу dll и иметь намного более легкое время всего этого

Решение Вопроса

CreateFile имеет поддержку прямого доступа к диску. Прочитайте заметки в разделе «Физические диски и тома». Вы должны быть в состоянии P / Invoke вызова.

Обратите внимание, что Vista и Server 2008 имеютстрого ограничен этот.

 Ali03 янв. 2012 г., 10:56
У меня похожий вопрос, не могли бы вы мне помочь?CreateFile: «Доступ запрещен» даже с правами администратора - Win7

Круто, спасибо Марк, я забыл, что CreateFile тоже открывает вещи. Я смотрел на API управления томами и не видел, как открыть вещи.

Вот небольшой класс, который оборачивает вещи. Также может быть возможно / правильно просто передать SafeFileHandle в FileStream.

using System;
using System.Runtime.InteropServices;
using System.IO;
using Microsoft.Win32.SafeHandles;

namespace ReadFromDevice
{
    public class DeviceStream : Stream, IDisposable
    {
        public const short FILE_ATTRIBUTE_NORMAL = 0x80;
        public const short INVALID_HANDLE_VALUE = -1;
        public const uint GENERIC_READ = 0x80000000;
        public const uint GENERIC_WRITE = 0x40000000;
        public const uint CREATE_NEW = 1;
        public const uint CREATE_ALWAYS = 2;
        public const uint OPEN_EXISTING = 3;

        // Use interop to call the CreateFile function.
        // For more information about CreateFile,
        // see the unmanaged MSDN reference library.
        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess,
          uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,
          uint dwFlagsAndAttributes, IntPtr hTemplateFile);

        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool ReadFile(
            IntPtr hFile,                        // handle to file
            byte[] lpBuffer,                // data buffer
            int nNumberOfBytesToRead,        // number of bytes to read
            ref int lpNumberOfBytesRead,    // number of bytes read
            IntPtr lpOverlapped
            //
            // ref OVERLAPPED lpOverlapped        // overlapped buffer
            );

        private SafeFileHandle handleValue = null;
        private FileStream _fs = null;

        public DeviceStream(string device)
        {
            Load(device);
        }

        private void Load(string Path)
        {
            if (string.IsNullOrEmpty(Path))
            {
                throw new ArgumentNullException("Path");
            }

            // Try to open the file.
            IntPtr ptr = CreateFile(Path, GENERIC_READ, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);

            handleValue = new SafeFileHandle(ptr, true);
            _fs = new FileStream(handleValue, FileAccess.Read);

            // If the handle is invalid,
            // get the last Win32 error 
            // and throw a Win32Exception.
            if (handleValue.IsInvalid)
            {
                Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
            }
        }

        public override bool CanRead
        {
            get { return true; }
        }

        public override bool CanSeek
        {
            get { return false; }
        }

        public override bool CanWrite
        {
            get { return false; }
        }

        public override void Flush()
        {
            return;
        }

        public override long Length
        {
            get { return -1; }
        }

        public override long Position
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }
        /// <summary>
        /// </summary>
        /// <param name="buffer">An array of bytes. When this method returns, the buffer contains the specified byte array with the values between offset and 
        /// (offset + count - 1) replaced by the bytes read from the current source. </param>
        /// <param name="offset">The zero-based byte offset in buffer at which to begin storing the data read from the current stream. </param>
        /// <param name="count">The maximum number of bytes to be read from the current stream.</param>
        /// <returns></returns>
        public override int Read(byte[] buffer, int offset, int count)
        {
            int BytesRead =0;
            var BufBytes = new byte[count];
            if (!ReadFile(handleValue.DangerousGetHandle(), BufBytes, count, ref BytesRead, IntPtr.Zero))
            {
                Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
            }
            for (int i = 0; i < BytesRead; i++)
            {
                buffer[offset + i] = BufBytes[i];
            }
            return BytesRead;
        }
        public override int ReadByte()
        {
            int BytesRead = 0;
            var lpBuffer = new byte[1];
            if (!ReadFile(
            handleValue.DangerousGetHandle(),                        // handle to file
            lpBuffer,                // data buffer
            1,        // number of bytes to read
            ref BytesRead,    // number of bytes read
            IntPtr.Zero
            ))
            { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); ;}
            return lpBuffer[0];
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            throw new NotImplementedException();
        }

        public override void SetLength(long value)
        {
            throw new NotImplementedException();
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            throw new NotImplementedException();
        }

        public override void Close()
        {
            handleValue.Close();
            handleValue.Dispose();
            handleValue = null;
            base.Close();
        }
        private bool disposed = false;

        new void Dispose()
        {
            Dispose(true);
            base.Dispose();
            GC.SuppressFinalize(this);
        }

        private new void Dispose(bool disposing)
        {
            // Check to see if Dispose has already been called.
            if (!this.disposed)
            {
                if (disposing)
                {
                    if (handleValue != null)
                    {
                        _fs.Dispose();
                        handleValue.Close();
                        handleValue.Dispose();
                        handleValue = null;
                    }
                }
                // Note disposing has been done.
                disposed = true;

            }
        }

    }
}

И пример использования класса

static void Main(string[] args)
        {
            var reader = new BinaryReader(new DeviceStream(@"\\.\PhysicalDrive3"));
            var writer = new BinaryWriter(new FileStream(@"g:\test.dat", FileMode.Create));
            var buffer = new byte[MB];
            int count;
            int loopcount=0;
            try{
                while((count=reader.Read(buffer,0,MB))>0)
                {
                    writer.Write(buffer,0,count);
                    System.Console.Write('.');
                    if(loopcount%100==0)
                    {
                        System.Console.WriteLine();
                        System.Console.WriteLine("100MB written");
                        writer.Flush();
                    }
                    loopcount++;
                }
            }
            catch(Exception e)
            {
                Console.WriteLine(e.Message);
            }
            reader.Close();
            writer.Flush();
            writer.Close();
        }

Применяются стандартные заявления об отказе от ответственности, этот код может быть опасным для вашего здоровья.

Ваш ответ на вопрос