By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
454,780 Members | 1,520 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 454,780 IT Pros & Developers. It's quick & easy.

Access a physical disk

P: n/a
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();
}
}
}

May 12 '06 #1
Share this Question
Share on Google+
1 Reply


P: n/a
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


"d.******@gmail.com" wrote:
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();
}
}
}

May 13 '06 #2

This discussion thread is closed

Replies have been disabled for this discussion.