Access a physical disk

D

d.albano

Hi to all,
this is my first post in this group.

I need to directly access to a disk but i'm getting some problem to let
to filestream to work.

I use createfile to acquire PhysicalDrive0 handle and after i pass the
pointer to filestream constructor to manage it using .NET related
methods

The problem is that when FileStream initialize it read the lenght of
the content of the related handle and, naturally, it throw an exception

here there is the stack trace:
at System.IO.__Error.WinIOError(Int32 errorCode, String str)
at System.IO.FileStream.get_Length()
at System.IO.FileStream..ctor(IntPtr handle, FileAccess access, Boolean
ownsH
andle, Int32 bufferSize, Boolean isAsync)
at DiskReader.Class1.Main(String[] args) in c:\documents and
settings\daniele
_dll\documenti\visual studio projects\ntfsreader\class1.cs:line 128

There is a way to use .net related methods or i must use Win32 Apis?

Thanks,
Best Regards,
Daniele

---
PS: here there is my code

namespace DiskReader
{
/// <summary>
/// Descrizione di riepilogo per Class1.
/// </summary>
class Class1
{
[DllImport("kernel32.dll", SetLastError=true)]
static extern IntPtr CreateFile(
string lpFileName,
EFileAccess dwDesiredAccess,
EFileShare dwShareMode,
IntPtr lpSecurityAttributes,
ECreationDisposition dwCreationDisposition,
EFileAttributes dwFlagsAndAttributes,
IntPtr hTemplateFile);

[DllImport("kernel32.dll", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CloseHandle(IntPtr hObject);

[Flags]
public enum EFileAccess : uint
{
GenericRead = 0x80000000,
GenericWrite = 0x40000000,
GenericExecute = 0x20000000,
GenericAll = 0x10000000,
}

[Flags]
public enum EFileShare : uint
{
None = 0x00000000,
Read = 0x00000001,
Write = 0x00000002,
Delete = 0x00000004,
}

public enum ECreationDisposition : uint
{
New = 1,
CreateAlways = 2,
OpenExisting = 3,
OpenAlways = 4,
TruncateExisting = 5,
}

[Flags]
public enum EFileAttributes : uint
{
Readonly = 0x00000001,
Hidden = 0x00000002,
System = 0x00000004,
Directory = 0x00000010,
Archive = 0x00000020,
Device = 0x00000040,
Normal = 0x00000080,
Temporary = 0x00000100,
SparseFile = 0x00000200,
ReparsePoint = 0x00000400,
Compressed = 0x00000800,
Offline= 0x00001000,
NotContentIndexed = 0x00002000,
Encrypted = 0x00004000,
Write_Through = 0x80000000,
Overlapped = 0x40000000,
NoBuffering = 0x20000000,
RandomAccess = 0x10000000,
SequentialScan = 0x08000000,
DeleteOnClose = 0x04000000,
BackupSemantics = 0x02000000,
PosixSemantics = 0x01000000,
OpenReparsePoint = 0x00200000,
OpenNoRecall = 0x00100000,
FirstPipeInstance = 0x00080000
}

/// <summary>
/// Il punto di ingresso principale dell'applicazione.
/// </summary>
[STAThread]
static void Main(string[] args)
{

// Apre il disco
IntPtr diskHandle = CreateFile(
@"\\.\PhysicalDrive0",
EFileAccess.GenericRead | EFileAccess.GenericWrite,
EFileShare.Read | EFileShare.Write,
IntPtr.Zero,
ECreationDisposition.OpenExisting,
EFileAttributes.Device | EFileAttributes.NoBuffering |
EFileAttributes.Write_Through,
IntPtr.Zero);

if (diskHandle.ToInt32() == -1)
{
Console.WriteLine("Errore: " +
Marshal.GetLastWin32Error().ToString());
Console.ReadLine();

return;
}

// Inizializza lo stream
FileStream fileStream = null;
try
{
fileStream = new FileStream(diskHandle, FileAccess.Read, true,
8096, false);
}
catch(IOException e)
{
Console.WriteLine(e.Message);
Console.WriteLine();
Console.WriteLine(e.StackTrace);
Console.WriteLine();
Console.WriteLine(e.Source.ToString());

Console.ReadLine();
return;
}

// Si posizione alla prima partizione
fileStream.Seek(446, SeekOrigin.Begin);

// Legge le varie entries della tabella
for (int i = 0; i < 4; i++)
{
Console.WriteLine("Partition {0}:", i);

byte[] buffer = new byte[16];
fileStream.Read(buffer, 0, buffer.Length);

// Verifica se la partizione è avviabile
if (buffer[0] == 0)
{
Console.WriteLine("\tAvviabile: SI");
}
else
{
Console.WriteLine("\tAvviabile: NO");
}

Console.WriteLine("");
}

// Chiude lo stream
fileStream.Close();
CloseHandle(diskHandle);

Console.ReadLine();
}
}
}
 
G

Guest

As it happens.. I'm also writing C# code to access a physical drive.

I think the problem is that FileStream's constructor expects a handle to a
file.

*** You don't have a handle to a file ***

You have a handle to a device...

This means you can make use of DeviceIoControl to access the *device* driver
directly.

You can also use the ReadFile and WriteFile API to read and write sectors to
the drive.

Important - You must make all calls to ReadFile and WriteFile using buffers
that are integer multiples of the device's *sector size*

You can ascertain sector size via calls to DeviceIoControl. Typically it
will be 512, 1024, 2048, or 4096 bytes..

You also need administrative priviledge to access the drive.

Let me know how you get on, maybe we can share tips.

Cheers

Steve

-----------------------------------

s--ddooot---simpson---aaa_tttt---gestech---dddooottt---com--au






Hi to all,
this is my first post in this group.

I need to directly access to a disk but i'm getting some problem to let
to filestream to work.

I use createfile to acquire PhysicalDrive0 handle and after i pass the
pointer to filestream constructor to manage it using .NET related
methods

The problem is that when FileStream initialize it read the lenght of
the content of the related handle and, naturally, it throw an exception

here there is the stack trace:
at System.IO.__Error.WinIOError(Int32 errorCode, String str)
at System.IO.FileStream.get_Length()
at System.IO.FileStream..ctor(IntPtr handle, FileAccess access, Boolean
ownsH
andle, Int32 bufferSize, Boolean isAsync)
at DiskReader.Class1.Main(String[] args) in c:\documents and
settings\daniele
_dll\documenti\visual studio projects\ntfsreader\class1.cs:line 128

There is a way to use .net related methods or i must use Win32 Apis?

Thanks,
Best Regards,
Daniele

---
PS: here there is my code

namespace DiskReader
{
/// <summary>
/// Descrizione di riepilogo per Class1.
/// </summary>
class Class1
{
[DllImport("kernel32.dll", SetLastError=true)]
static extern IntPtr CreateFile(
string lpFileName,
EFileAccess dwDesiredAccess,
EFileShare dwShareMode,
IntPtr lpSecurityAttributes,
ECreationDisposition dwCreationDisposition,
EFileAttributes dwFlagsAndAttributes,
IntPtr hTemplateFile);

[DllImport("kernel32.dll", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CloseHandle(IntPtr hObject);

[Flags]
public enum EFileAccess : uint
{
GenericRead = 0x80000000,
GenericWrite = 0x40000000,
GenericExecute = 0x20000000,
GenericAll = 0x10000000,
}

[Flags]
public enum EFileShare : uint
{
None = 0x00000000,
Read = 0x00000001,
Write = 0x00000002,
Delete = 0x00000004,
}

public enum ECreationDisposition : uint
{
New = 1,
CreateAlways = 2,
OpenExisting = 3,
OpenAlways = 4,
TruncateExisting = 5,
}

[Flags]
public enum EFileAttributes : uint
{
Readonly = 0x00000001,
Hidden = 0x00000002,
System = 0x00000004,
Directory = 0x00000010,
Archive = 0x00000020,
Device = 0x00000040,
Normal = 0x00000080,
Temporary = 0x00000100,
SparseFile = 0x00000200,
ReparsePoint = 0x00000400,
Compressed = 0x00000800,
Offline= 0x00001000,
NotContentIndexed = 0x00002000,
Encrypted = 0x00004000,
Write_Through = 0x80000000,
Overlapped = 0x40000000,
NoBuffering = 0x20000000,
RandomAccess = 0x10000000,
SequentialScan = 0x08000000,
DeleteOnClose = 0x04000000,
BackupSemantics = 0x02000000,
PosixSemantics = 0x01000000,
OpenReparsePoint = 0x00200000,
OpenNoRecall = 0x00100000,
FirstPipeInstance = 0x00080000
}

/// <summary>
/// Il punto di ingresso principale dell'applicazione.
/// </summary>
[STAThread]
static void Main(string[] args)
{

// Apre il disco
IntPtr diskHandle = CreateFile(
@"\\.\PhysicalDrive0",
EFileAccess.GenericRead | EFileAccess.GenericWrite,
EFileShare.Read | EFileShare.Write,
IntPtr.Zero,
ECreationDisposition.OpenExisting,
EFileAttributes.Device | EFileAttributes.NoBuffering |
EFileAttributes.Write_Through,
IntPtr.Zero);

if (diskHandle.ToInt32() == -1)
{
Console.WriteLine("Errore: " +
Marshal.GetLastWin32Error().ToString());
Console.ReadLine();

return;
}

// Inizializza lo stream
FileStream fileStream = null;
try
{
fileStream = new FileStream(diskHandle, FileAccess.Read, true,
8096, false);
}
catch(IOException e)
{
Console.WriteLine(e.Message);
Console.WriteLine();
Console.WriteLine(e.StackTrace);
Console.WriteLine();
Console.WriteLine(e.Source.ToString());

Console.ReadLine();
return;
}

// Si posizione alla prima partizione
fileStream.Seek(446, SeekOrigin.Begin);

// Legge le varie entries della tabella
for (int i = 0; i < 4; i++)
{
Console.WriteLine("Partition {0}:", i);

byte[] buffer = new byte[16];
fileStream.Read(buffer, 0, buffer.Length);

// Verifica se la partizione è avviabile
if (buffer[0] == 0)
{
Console.WriteLine("\tAvviabile: SI");
}
else
{
Console.WriteLine("\tAvviabile: NO");
}

Console.WriteLine("");
}

// Chiude lo stream
fileStream.Close();
CloseHandle(diskHandle);

Console.ReadLine();
}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top