views:

889

answers:

2

i am workign on reading the FAT32 entry of the harddisk and so far have been successful in reading the entries by makign use of the following APIs

CreateFile, ReadFile, SetFilePointer. Here is my code in C# written so far.

---The DLL IMPORTS-----

[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);

------CODE----Will Work in any .NET Application---------

        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);
                    }

                }
            }

The code above reads the F:\ drive and for trial purposes i have made it to read the first File Directory Cluster and query through each file entry and display the file name if it has been deleted.

However i want to make it to a fully blown application, for which i will have to frequently use the byte array and map it to the specified data structures according to the FAT32 Specification.

What i want to know is how can i efficiently use the byte array into which i am reading the data, i have tried the same code using filestream and binaryreader and it works, however now suppose i have a C Structure something like

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

i want to have a similar data structure in C# and when i read data to a byte array i want to map it to the structure, i tried many options but didn't get a complete solution. I tried making a class and do serialization too but that also didn't work. I have around 3 more structures like theese which i will be using as i read the data from the FAT entry. How can i best achieve the desired results, any help?

Thanks }

A: 

I gave an answer on how to convert between byte arrays and structs in this question.

OregonGhost
+1  A: 

If you want to read binary data directly into structs, C-style, this article may interest you. He wrote an unmanaged wrapper around the C stdio functions and interoperates with it. I have tried it - it does work quite well. It is nice to read directly into a struct in C#, and it is fast. You can just do:

unsafe 
{ 
 fmp3.Read<MyStruct>(&myStructVar); 
}
R Ubben