473,503 Members | 1,673 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Problems using PInvoke to read a PhysicalDrive

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;
}
..
..
Nov 16 '05 #1
4 7690
Jerry wrote:
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;
}
.
.
.
}


Could you post a working example which would produce that problem with 0x3F?
Nov 16 '05 #2
Here you go. If after running this code you open c:\sector.dat and
look at byte number 24 is is set to 0x3f, and it should be 0x20. This
is only one example of many characters changed from their original
value to 0x3f. I hope this helps. Thank you for your time.

using System;
using System.Runtime.InteropServices;
using System.IO;

namespace CSharpSectorTest
{
/// <summary>
/// Summary description for Class1.
/// </summary>
class Class1
{
public class BootSector
{
[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 = 1;
static uint FILE_SHARE_WRITE =2;

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
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();

// Can't get a FileStream ctor to work so I am using Win32 API
ReadFile
bool worked = ReadFile ( (IntPtr) fileHandle, sector, (uint)
EIGHT_K, ref bytesRead, ol);
if ( worked == true && bytesRead == EIGHT_K )
{
//Write to the specified file
Char [] outdata = new Char[sector.Length];
sector.CopyTo( outdata, 0);

StreamWriter sw = new StreamWriter ( @"c:\sector.dat", false,
System.Text.Encoding.Default );
sw.Write ( outdata, 0, EIGHT_K );
sw.Close ();
return;
}
}
}
catch ( Exception ex )
{
return;
}
finally
{
CloseHandle(fileHandle);
}
return;
}
}
}
}

Nov 16 '05 #3
[DllImport("kernel32.dll",SetLastError=true)]
public static extern Boolean ReadFile(
IntPtr hFile,
Byte[] buffer,
UInt32 BytesToRead,
ref UInt32 BytedRead,
OVERLAPPED OverLapped);

The last parameter (overlapped) should be a ref parameter.

I recommend you try to find correct declarations at
http://www.pinvoke.net

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Nov 16 '05 #4
Using the declarations from www.pinvoke.net did not solve the problem.

Nov 16 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

21
42983
by: Gavin | last post by:
Hi, I'm a newbie to programming of any kind. I have posted this to other groups in a hope to get a response from anyone. Can any one tell me how to make my VB program read the Bios serial number...
2
3326
by: Craig | last post by:
I've seen many examples of how to call SHGetFileInfo in shell32.dll to get a files associated icon, but I can't find anywhere how to get the file information (size, last date modified, etc, etc)...
0
2473
by: Claire | last post by:
Hi Ive been using Mattias Sjögren's example at http://www.msjogren.net/dotnet/eng/samples/dotnet_dynpinvoke.asp to load an unmanaged 3rd party dll dynamically when my object is created. Calling...
3
2950
by: Baron | last post by:
an asp.net page on Machine A is trying to access files on several machines of different domains.. any 'good' method to do it without mapping drive in prior..... i've read something called...
1
3023
by: gregarican | last post by:
A couple of days ago I was debating about whether to use C++/CLI or C# 2005's PInvoke in order to tie in my VS 2005 app with a legacy csta32.dll file. So far I have tried to call one method out of...
11
2958
by: titan nyquist | last post by:
I want to read/write user settings. I thought about using .ini or .xml files. Are there classes in c# to handle this? The stuff I find on the 'net seems old. Titan
14
3767
by: Mohamed Mansour | last post by:
Hey there, this will be somewhat a long post, but any response is appreciated! I have done many PInvoke in the past from C++ to C#, but I did PInvoke within C# not C++/CLI. Can someone explain...
0
1062
by: Aldev | last post by:
Hi There, I am quite new to PInvoke and calling COM functions from C#. I have managed so far to call some unmanaged functions ib my C++ dll from my C# code but at the moment I am having trouble...
3
3203
by: not_a_commie | last post by:
The CLR won't garbage collect until it needs to. You should see the memory usage climb for some time before stabilizing. Can you change your declaration to use the 'out' keyword rather than a 'ref'...
0
7198
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7072
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7319
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
6979
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
1
4998
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
3160
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3149
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
730
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
373
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.