Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read raw bytes from an SD card?

Tags:

.net

sd-card

On a Windows PC, is there a way to read the raw bytes from an SD card attached trough a USB card reader? The SD card gets written from an embedded system using no file system at all, so I can't use standard file access routines. This is similar to what the unix dd utility does, but I need to integrate this into a .NET application.

like image 284
geschema Avatar asked Apr 08 '10 08:04

geschema


Video Answer


1 Answers

I'm not really sure whether this is helpful or not, but assuming that even an unformatted disk gets a physical drive number in the Win32 Device Namespace (which I think it must), you might be able to extend the code shown here to identify the drive number and read raw bytes from anywhere on the device.

update: the original link is down. Code from the Internet Archive. See the Internet Archive copy of the original blog post (linked above) for context:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32.SafeHandles;
using System.Runtime.InteropServices;
using System.IO;

namespace RawDump
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public enum EMoveMethod : uint
        {
            Begin = 0,
            Current = 1,
            End = 2
        }

        [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern uint SetFilePointer(
            [In] SafeFileHandle hFile,
            [In] int lDistanceToMove,
            [Out] out int lpDistanceToMoveHigh,
            [In] EMoveMethod dwMoveMethod);

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

        [DllImport("kernel32", SetLastError = true)]
        internal extern static int ReadFile(SafeFileHandle handle, byte[] bytes,
           int numBytesToRead, out int numBytesRead, IntPtr overlapped_MustBeZero);

        private void buttonDump_Click(object sender, EventArgs e)
        {
            short FILE_ATTRIBUTE_NORMAL = 0x80;
            short INVALID_HANDLE_VALUE = -1;
            uint GENERIC_READ = 0x80000000;
            uint GENERIC_WRITE = 0x40000000;
            uint CREATE_NEW = 1;
            uint CREATE_ALWAYS = 2;
            uint OPEN_EXISTING = 3;

            SaveFileDialog mySFD = new SaveFileDialog();
            mySFD.FileName = "dump.bin";
            mySFD.InitialDirectory = Path.GetDirectoryName(Application.StartupPath);
            if(mySFD.ShowDialog() == DialogResult.OK)
            {
                SafeFileHandle handleValue = CreateFile(textBoxPath.Text, GENERIC_READ, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
                if (handleValue.IsInvalid)
                {
                    Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
                }

                int offset = int.Parse(textBoxOffset.Text, System.Globalization.NumberStyles.HexNumber);
                int size = int.Parse(textBoxSize.Text, System.Globalization.NumberStyles.HexNumber);
                byte[] buf = new byte[size];
                int read = 0;
                int moveToHigh;
                SetFilePointer(handleValue, offset, out moveToHigh, EMoveMethod.Begin);
                ReadFile(handleValue, buf, size, out read, IntPtr.Zero);
                FileStream myStream = File.OpenWrite(mySFD.FileName);
                myStream.Write(buf, 0, size);
                myStream.Flush();
                myStream.Close();
                handleValue.Close();
            }
        }
    }
}
like image 90
Ed Harper Avatar answered Oct 03 '22 19:10

Ed Harper