Как записать в файл на сыром диске, используя CreateFile из kernel32.dll - PullRequest
0 голосов
/ 29 апреля 2020

Я пытаюсь записать напрямую на диск

Я могу читать, но не могу записать.

Есть ли какая-то конкретная c функция для записи в файл ?

Как включить запись?

pinvoke подпись:

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern SafeFileHandle CreateFile(
    string lpFileName,
    int dwDesiredAccess,
    int dwShareMode,
    IntPtr lpSecurityAttributes,
    uint dwCreationDisposition,
    uint dwFlagsAndAttributes,
    SafeFileHandle hTemplateFile);

Чтение работает нормально:

SafeFileHandle h = CreateFile(
    "\\.\PhysicalDrive1",
    unchecked((int)(0x80000000)),
    0,
    IntPtr.Zero,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    new SafeFileHandle(IntPtr.Zero, true));
FileStream stream = new FileStream(h, FileAccess.Read);
var @byte = stream.ReadByte();
stream.Close();
h.Close();

Но не запись :

SafeFileHandle h = CreateFile(
    "\\.\PhysicalDrive1", // Be careful to not damage your HDD
    unchecked((int)(0x40000000)),
    0,
    IntPtr.Zero,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    new SafeFileHandle(IntPtr.Zero, true));

FileStream stream = new FileStream(h, FileAccess.Write);

stream.WriteByte((byte)0xFF);
h.Close();

Я что-то не так делаю?


Код переписан с печатью кодов последней ошибки:

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

namespace RawHD
{
    static class Program
    {
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        internal static extern SafeFileHandle CreateFile(
            string lpFileName,
            int dwDesiredAccess,
            int dwShareMode,
            IntPtr lpSecurityAttributes,
            uint dwCreationDisposition,
            uint dwFlagsAndAttributes,
            SafeFileHandle hTemplateFile);

        internal const int SHARE_NONE = 0;
        internal const int GENERIC_READ = unchecked((int)0x80000000);
        internal const int GENERIC_WRITE = unchecked((int)0x40000000);
        internal const int OPEN_EXISTING = 3;
        internal const int FILE_ATTRIBUTE_NORMAL = 0x80;

        [STAThread]
        static void Main()
        {
            SafeFileHandle fileHandle = CreateFile(
                "\\\\.\\PhysicalDrive4",
                GENERIC_WRITE,
                SHARE_NONE,
                IntPtr.Zero, // optional parameter
                OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL,
                new SafeFileHandle(IntPtr.Zero, true));

            Console.WriteLine("After opening first file: " + Marshal.GetLastWin32Error());

            FileStream stream = new FileStream(fileHandle, FileAccess.Write);
            stream.WriteByte((byte)'C');
            Console.WriteLine("After writing: " + Marshal.GetLastWin32Error());
            Console.WriteLine("Char Written: C");

            fileHandle.Close();
            Console.WriteLine("After closing first file: " + Marshal.GetLastWin32Error());

            fileHandle = CreateFile(
                "\\\\.\\PhysicalDrive4",
                GENERIC_READ,
                SHARE_NONE,
                IntPtr.Zero, // optional parameter
                OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL,
                new SafeFileHandle(IntPtr.Zero, true));


            Console.WriteLine("After opening second file: " + Marshal.GetLastWin32Error());
            stream = new FileStream(fileHandle, FileAccess.Read);
            var @byte = stream.ReadByte();
            Console.WriteLine("After reading: " + Marshal.GetLastWin32Error());
            Console.WriteLine("Char Read: " + (char)@byte);
            stream.Close();
            fileHandle.Close();
            Console.WriteLine("After closing second file: " + Marshal.GetLastWin32Error());

            Console.ReadKey();
        }
    }
}

Это дает мне вывод:

После открытия первого файла: 0

После записи: 0

Char Написано: C

После закрытия первого файла: 0

После открытия второго файла: 0

После чтения: 0

Char Чтение: 3

После закрытия второго файла: 0


Также пробовал использовать функцию WriteFile из kernel32.dll:

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

namespace RawHD
{
    static class Program
    {
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        internal static extern SafeFileHandle CreateFile(
            string lpFileName,
            int dwDesiredAccess,
            int dwShareMode,
            IntPtr lpSecurityAttributes,
            uint dwCreationDisposition,
            uint dwFlagsAndAttributes,
            SafeFileHandle hTemplateFile);

        [DllImport("kernel32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool WriteFile(
            SafeFileHandle hFile,
            byte[] lpBuffer,
            uint nNumberOfBytesToWrite,
            out uint lpNumberOfBytesWritten,
            [In] ref NativeOverlapped lpOverlapped);

        internal const int SHARE_NONE = 0;
        internal const int GENERIC_READ = unchecked((int)0x80000000);
        internal const int GENERIC_WRITE = unchecked((int)0x40000000);
        internal const int OPEN_EXISTING = 3;
        internal const int FILE_ATTRIBUTE_NORMAL = 0x80;

        [STAThread]
        static void Main()
        {
            SafeFileHandle fileHandle = CreateFile(
                "\\\\.\\PhysicalDrive4",
                GENERIC_WRITE,
                SHARE_NONE,
                IntPtr.Zero, // optional parameter
                OPEN_EXISTING,
                FILE_ATTRIBUTE_NORMAL,
                new SafeFileHandle(IntPtr.Zero, true));

            Console.WriteLine("After opening first file: " + Marshal.GetLastWin32Error());

            NativeOverlapped over = new NativeOverlapped();
            over.OffsetLow = 0;
            over.OffsetHigh = 0;

            uint written;

            WriteFile(fileHandle, Encoding.ASCII.GetBytes("Test"), 4, out written, ref over);

            Console.WriteLine("After using WriteFile: " + Marshal.GetLastWin32Error());

            fileHandle.Close();
            Console.WriteLine("After closing first file: " + Marshal.GetLastWin32Error());

            Console.ReadKey();
        }
    }
}

Но это дает мне ошибку 87:

После открытия Первый файл: 0

После использования WriteFile: 0

После закрытия первого файла : 87

1 Ответ

0 голосов
/ 30 апреля 2020

В коде нет исключений, вам нужно использовать WriteAsyn c e ReadAsyn c, так как эти функции не поддерживают синхронные операции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...