низкоуровневый ввод / вывод в стиле C ++ для чтения FAT32 - PullRequest
2 голосов
/ 16 июля 2009

Я работаю над чтением записи FAT32 на жестком диске и до сих пор успешно читал записи, используя API CreateFile, ReadFile и SetFilePointer. Вот мой код (написанный на C #).

--- DLL ИМПОРТ -----

[DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr CreateFile(string lpFileName, Int32 dwDesiredAccess,
            Int32 dwShareMode, Int32 lpSecurityAttributes, Int32 dwCreationDisposition,
            Int32 dwFlagsAndAttributes, IntPtr hTemplateFile);

        [DllImport("kernel32.dll")]
        static extern bool ReadFile(IntPtr hFile, byte[] lpBuffer,
           uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, uint lpOverlapped);

        [DllImport("kernel32.dll")]
        extern static int SetFilePointer(IntPtr hFile, int lDistanceToMove, int lpDistanceToMoveHigh, uint dwMoveMethod);

        [DllImport("kernel32.dll")]
        extern static Boolean CloseHandle(IntPtr hObject);

------ КОД ---- будет работать в любом приложении .NET ---------

        int ret, nread;
        IntPtr handle;
        int s = 512;
        byte[] readbuffer = new byte[512];

    IntPtr ptr = CreateFile(@"\\.\F:", -1073741824, 3, 0, 3, 128, IntPtr.Zero);
 if (ptr != System.IntPtr.Zero)
            {
                int i = 100;
                int ret = SetFilePointer(ptr, 0, 0, 0);
                ret = SetFilePointer(ptr, 4194304, 0, 1);
                while (true)
                {
                    byte[] inp = new byte[512];
                    uint read = 0;
                    if (ret != -1)
                    {
                        ReadFile(ptr, inp, 512, out read, 0);
                        for (int k = 0; k < 16; k++)
                        {
                            string s = ASCIIEncoding.ASCII.GetString(inp, k*32, 11);
                            if (inp[k*32] == 0xE5)
                            {
                                MessageBox.Show(s);
                            }
                        }
                        //ret = SetFilePointer(ptr, 512, 0, 1);
                    }

                }
            }

Приведенный выше код читает диск F:\, и для ознакомительных целей я сделал его для чтения первого кластера каталогов файлов и выполнения запросов к каждой записи файла и отображения имени файла, если оно было удалено.

Однако я хочу сделать это в полномасштабном приложении, для которого мне придется часто использовать байтовый массив и сопоставлять его с указанными структурами данных в соответствии со Спецификацией FAT32.

Как эффективно использовать байтовый массив, в который я читаю данные? Я попробовал один и тот же код, используя filestream и binaryreader, и он работает, однако теперь предположим, что у меня есть структура C что-то вроде

struct bios_data
{
byte id[3];
char name[11];
byte sectorpercluster[2];
...
}

Я хочу иметь подобную структуру данных в C #, и когда я читаю данные в байтовый массив, я хочу отобразить их в структуре. Я перепробовал много вариантов, но не получил полного решения. Я пытался создать класс и сделать сериализацию, но это тоже не сработало. У меня есть еще около 3 структур, подобных этим, которые я буду использовать при чтении данных из записи FAT. Как мне лучше всего достичь желаемых результатов?

Ответы [ 2 ]

1 голос
/ 16 июля 2009

Если вы хотите читать двоичные данные непосредственно в структуры, C-style, эта статья может вас заинтересовать. Он написал неуправляемую оболочку для функций C stdio и взаимодействует с ней. Я попробовал это - это работает довольно хорошо. Приятно читать непосредственно в структуру в C #, и это быстро. Вы можете просто сделать:

unsafe 
{ 
 fmp3.Read<MyStruct>(&myStructVar); 
}
0 голосов
/ 16 июля 2009

Я дал ответ о том, как преобразовать байтовые массивы и структуры в этот вопрос .

...