nickdu088 / SharpExt4

A .Net library to provide full access (read/write) to Linux ext2/ext3/ext4 filesystem
https://www.nickdu.com/?p=890
40 stars 8 forks source link

Exception when attempting to write text to file: "Could not read disk MBR." #1

Closed se1exin closed 3 years ago

se1exin commented 3 years ago

Hi there,

Firstly thanks for open sourcing this library! Awesome stuff.

Re the below, if you have a preferred issue format I'm happy to re-submit this with whatever details you need - I've tried to include everything you might need to know.

I'm hitting a "Could not read disk MBR." exception when attempting to write a file, interesting I can read the file I am writing to, just not write to it.

Here's a quick breakdown of what the code is doing:

  1. User selects USB disk from a dropdown (using ManagementObjectSearcher to find the disks and parse the disk indexes)
  2. Load the contents of /etc/wpa_supplicant/wpa_supplicant.conf and parse out ssid and psk strings, using:
            var disk = ExtDisk.Open(this.index); // Physical disk index found using ManagementObjectSearcher
            var fs = ExtFileSystem.Open(disk.Parititions[1]);
            var file = fs.OpenFile("/etc/wpa_supplicant/wpa_supplicant.conf", FileMode.Open, FileAccess.Read);
            var filelen = file.Length;
            var buf = new byte[filelen];
            file.Read(buf, 0, (int)filelen);
            file.Close();
            fs.Dispose();
            var content = Encoding.Default.GetString(buf);
            // Do stuff with the content to pull out ssid and psk

Note: This step is working.

  1. User then updates the ssid/psk in text fields in the form, hits a save button which calls:

            string template = $@"ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev";
            template += "\nupdate_config=1";
            template += "\ncountry=AU";
            template += "\nnetwork={";
            template += "\n  ssid=" + ssid;
            template += "\n  psk=" + password;
            template += "\n}";
    
            var disk = ExtDisk.Open(this.index); // Physical disk index found using ManagementObjectSearcher - same as in the read step
            var fs = ExtFileSystem.Open(disk.Parititions[1]);
            var file = fs.OpenFile("/etc/wpa_supplicant/wpa_supplicant.conf", FileMode.OpenOrCreate, FileAccess.ReadWrite);
            var buf = Encoding.UTF8.GetBytes(template);
            //Write to file
            file.Write(buf, 0, buf.Length);
            file.Close();
            fs.Dispose();

Step three throws the error when attempting to Open the disk.

nickdu088 commented 3 years ago

Thanks for letting me know. I will take a look today or tomorrow. From your description, it seems the disk MBR sector is not readable. Any way, I will debug and find out what exactly is happening.

BTW, your email is very clear to describe the issue. Thanks!

nickdu088 commented 3 years ago

Hi,

I just tested your code on my 8GB TF card with Raspberry Pi image, and everything is working ok in my side.

I can see "wpa_supplicant.conf" has been overwritten with your content. If possible, can you try again with newly flashed TF card?

    class Program
    {
        static void Main(string[] args)
        {
            ReadFile();
            WriteFile();
            ReadFile();
        }
        static void ReadFile()
        {
            var disk = ExtDisk.Open(3); // Physical disk index found using ManagementObjectSearcher
            var fs = ExtFileSystem.Open(disk.Parititions[1]);
            var file = fs.OpenFile("/etc/wpa_supplicant/wpa_supplicant.conf", FileMode.Open, FileAccess.Read);
            var filelen = file.Length;
            var buf = new byte[filelen];
            file.Read(buf, 0, (int)filelen);
            file.Close();
            fs.Dispose();
            var content = Encoding.Default.GetString(buf);
            // Do stuff with the content to pull out ssid and psk
        }
        static void WriteFile()
        {
            string template = $@"ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev";
            template += "\nupdate_config=1";
            template += "\ncountry=AU";
            template += "\nnetwork={";
            template += "\n  ssid=ssid";
            template += "\n  psk=password";
            template += "\n}";

            var disk = ExtDisk.Open(3); // Physical disk index found using ManagementObjectSearcher - same as in the read step
            var fs = ExtFileSystem.Open(disk.Parititions[1]);
            var file = fs.OpenFile("/etc/wpa_supplicant/wpa_supplicant.conf", FileMode.OpenOrCreate, FileAccess.ReadWrite);
            var buf = Encoding.UTF8.GetBytes(template);
            //Write to file
            file.Write(buf, 0, buf.Length);
            file.Close();
            fs.Dispose();
        }
    }
se1exin commented 3 years ago

Thanks @nickdu088 for the quick response. I should have thought to try a different SD card 🤦🏻

I'll try another card tomorrow when I'm back at work and let you know how it goes.

se1exin commented 3 years ago

@nickdu088 So I found the issue, and it wasn't related to the physical disk.

Some thing I failed to add in my original comment (I didn't consider this code path before sorry) is my program also attempts to load another file on the ext partition that may possibly not exist. I was simply wrapping OpenFile in a try catch, and if there was an exception I assume the file does not exist and show the user a message.

In my case the file does not exist, so OpenFile fails and my program catches the error gracefully. But if I comment out this code, my original issue when attempting to write the wpa_supplicant file to disk goes away.

Additionally, if I wrap OpenFile in a if (fs.FileExists(filename)) check, the issue also goes away.

So in summary, and at a guess, it looks if OpenFile fails it may not be releasing the underlying disk resource(s). That's just a guess - I'm sure you'd have a better idea than me.

nickdu088 commented 3 years ago

When OpenFile throws exception, the underlying handle may not be released properly and it may cause unexpected issue. You'd better check FileExists before opening a file.

BTW: can you star this project and let more people see and use this library? Thanks!

se1exin commented 3 years ago

Too easy, I'll be sure to check for files before trying to do things with them 🤓

Thanks for your help. I've given the project a star as well 😉