J
Jerry
I am trying to read a physical sector off of the disk (the boot sector
for drive C
from C#. I have no problems doing it from a C/C++
application using the Win32 API CreateFile and ReadFile. However, when
I attempt to use PInvoke to do the very same thing in C# the data read
in is somehow being altered from what is on disk. Several of the bytes
are being changed from their original value to 0x3f!?!?!
Anyone have any ideas as to what I am doing wrong? I have tried to use
others suggestions and create a FileStream from the file handle, but
all I get at runtime is a "The Parameter is incorrect" exception
thrown!?! So, I am trying to stick with ReadFile since it actually
will perform the read for now.
Below is the portion of the code which performs the calls to
CreateFile/ReadFile.
[StructLayout(LayoutKind.Sequential)]
public struct OVERLAPPED
{
public uint Internal;
public uint InternalHigh;
public uint Offset;
public uint OffsetHigh;
public int hEvent;
}
[DllImport("kernel32", SetLastError=true)]
static extern int CreateFile(
string filename,
uint desiredAccess,
uint shareMode,
IntPtr attributes,
uint creationDisposition,
uint flagsAndAttributes,
IntPtr templateFile);
[DllImport("kernel32", SetLastError=true)]
public static extern Boolean CloseHandle ( int handle );
[DllImport("kernel32.dll",SetLastError=true)]
public static extern Boolean ReadFile(
IntPtr hFile,
Byte[] buffer,
UInt32 BytesToRead,
ref UInt32 BytedRead,
OVERLAPPED OverLapped);
static int EIGHT_K = 8192;
static int FIVE_TWELVE_BYTES = 512;
static uint GENERIC_READ = 0x80000000;
static uint OPEN_EXISTING = 3;
static uint FILE_SHARE_READ = 0x00000001;
static uint FILE_SHARE_WRITE = 0x00000002;
public bool Create()
{
int fileHandle = 0;
bool returnVal = true;
try
{
// Open the device specified (Using the boot partition)
string deviceName = @"\\.\C:";
fileHandle = CreateFile ( deviceName, GENERIC_READ, FILE_SHARE_READ |
FILE_SHARE_WRITE, (IntPtr)0, OPEN_EXISTING, 0, (IntPtr)0);
if ( fileHandle != -1 )
{
Byte [] sector = new Byte[EIGHT_K];
UInt32 bytesRead = (uint) EIGHT_K;
OVERLAPPED ol = new OVERLAPPED();
bool worked = ReadFile ( (IntPtr) fileHandle, sector, (uint)
EIGHT_K, ref bytesRead, ol);
if ( worked == false || bytesRead != EIGHT_K )
{
returnVal = false;
}
..
..
for drive C

application using the Win32 API CreateFile and ReadFile. However, when
I attempt to use PInvoke to do the very same thing in C# the data read
in is somehow being altered from what is on disk. Several of the bytes
are being changed from their original value to 0x3f!?!?!
Anyone have any ideas as to what I am doing wrong? I have tried to use
others suggestions and create a FileStream from the file handle, but
all I get at runtime is a "The Parameter is incorrect" exception
thrown!?! So, I am trying to stick with ReadFile since it actually
will perform the read for now.
Below is the portion of the code which performs the calls to
CreateFile/ReadFile.
[StructLayout(LayoutKind.Sequential)]
public struct OVERLAPPED
{
public uint Internal;
public uint InternalHigh;
public uint Offset;
public uint OffsetHigh;
public int hEvent;
}
[DllImport("kernel32", SetLastError=true)]
static extern int CreateFile(
string filename,
uint desiredAccess,
uint shareMode,
IntPtr attributes,
uint creationDisposition,
uint flagsAndAttributes,
IntPtr templateFile);
[DllImport("kernel32", SetLastError=true)]
public static extern Boolean CloseHandle ( int handle );
[DllImport("kernel32.dll",SetLastError=true)]
public static extern Boolean ReadFile(
IntPtr hFile,
Byte[] buffer,
UInt32 BytesToRead,
ref UInt32 BytedRead,
OVERLAPPED OverLapped);
static int EIGHT_K = 8192;
static int FIVE_TWELVE_BYTES = 512;
static uint GENERIC_READ = 0x80000000;
static uint OPEN_EXISTING = 3;
static uint FILE_SHARE_READ = 0x00000001;
static uint FILE_SHARE_WRITE = 0x00000002;
public bool Create()
{
int fileHandle = 0;
bool returnVal = true;
try
{
// Open the device specified (Using the boot partition)
string deviceName = @"\\.\C:";
fileHandle = CreateFile ( deviceName, GENERIC_READ, FILE_SHARE_READ |
FILE_SHARE_WRITE, (IntPtr)0, OPEN_EXISTING, 0, (IntPtr)0);
if ( fileHandle != -1 )
{
Byte [] sector = new Byte[EIGHT_K];
UInt32 bytesRead = (uint) EIGHT_K;
OVERLAPPED ol = new OVERLAPPED();
bool worked = ReadFile ( (IntPtr) fileHandle, sector, (uint)
EIGHT_K, ref bytesRead, ol);
if ( worked == false || bytesRead != EIGHT_K )
{
returnVal = false;
}
..
..