SetFilePointerEx not moving pointer
-
Hey there, I'm working on an NTFS Master File Table reader as part of a project for University. I've already got a Console API working in C++ which reads the current $MFT file/table, and i've begun work on porting the code over to C# (as per my requirements), however my version of SetFilePointerEx doesn't seem to move the file buffer pointer. My C++ code:
BOOL __stdcall SetFileBlockLocation(HANDLE address, LARGE_INTEGER position)
{
return SetFilePointerEx(address, position, NULL, FILE_BEGIN);
}My C# code:
public bool AssignPointerPosition(Int64 position, EFileMove movement)
{
if (this.IsBufferReady == false)
return false;if (Win32API.SetFilePointerEx(this.block, (long)position, IntPtr.Zero, movement) == false) { this.errorcode = Marshal.GetLastWin32Error(); this.errorpos = MFTHaltPosition.MoveFile; return false; } return true;
}
Where
EFileMove
is set toEFileMove.FileBegin
(aka. 0) When I run anotherReadFile
, it continues to read out the same block of data into the buffer (the first four bytes should beFILE
, but instead reads the beginning of theNTFS
block). Does anyone have an idea why it wouldn't move the pointer forward (position is a value far above 0), and is there a solution? Thank you, Chris -
Hey there, I'm working on an NTFS Master File Table reader as part of a project for University. I've already got a Console API working in C++ which reads the current $MFT file/table, and i've begun work on porting the code over to C# (as per my requirements), however my version of SetFilePointerEx doesn't seem to move the file buffer pointer. My C++ code:
BOOL __stdcall SetFileBlockLocation(HANDLE address, LARGE_INTEGER position)
{
return SetFilePointerEx(address, position, NULL, FILE_BEGIN);
}My C# code:
public bool AssignPointerPosition(Int64 position, EFileMove movement)
{
if (this.IsBufferReady == false)
return false;if (Win32API.SetFilePointerEx(this.block, (long)position, IntPtr.Zero, movement) == false) { this.errorcode = Marshal.GetLastWin32Error(); this.errorpos = MFTHaltPosition.MoveFile; return false; } return true;
}
Where
EFileMove
is set toEFileMove.FileBegin
(aka. 0) When I run anotherReadFile
, it continues to read out the same block of data into the buffer (the first four bytes should beFILE
, but instead reads the beginning of theNTFS
block). Does anyone have an idea why it wouldn't move the pointer forward (position is a value far above 0), and is there a solution? Thank you, Chris -
What does your import/p-invoke look like for SetFilePointerEx? What is this.block defined as?
My SetFilePointerEx import looks like this:
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool SetFilePointerEx(IntPtr fHandle, long lDistance, IntPtr lpNewPointer, EFileMove dwMove);And the
block
attribute is anIntPtr
:private IntPtr block;
Which stores the file pointer created by
CreateFile
, and is used to read the data. -
My SetFilePointerEx import looks like this:
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool SetFilePointerEx(IntPtr fHandle, long lDistance, IntPtr lpNewPointer, EFileMove dwMove);And the
block
attribute is anIntPtr
:private IntPtr block;
Which stores the file pointer created by
CreateFile
, and is used to read the data.Is SetFilePointerEx returning 0? If so, what is GetLastError reporting? I would recommend using SafeFileHandle instead of IntPtr for the file handle. I assume you are doing a verbatum translation of your C++ code to C#, so that you know the actual sequence of calls you are performing are valid.
-
Hey there, I'm working on an NTFS Master File Table reader as part of a project for University. I've already got a Console API working in C++ which reads the current $MFT file/table, and i've begun work on porting the code over to C# (as per my requirements), however my version of SetFilePointerEx doesn't seem to move the file buffer pointer. My C++ code:
BOOL __stdcall SetFileBlockLocation(HANDLE address, LARGE_INTEGER position)
{
return SetFilePointerEx(address, position, NULL, FILE_BEGIN);
}My C# code:
public bool AssignPointerPosition(Int64 position, EFileMove movement)
{
if (this.IsBufferReady == false)
return false;if (Win32API.SetFilePointerEx(this.block, (long)position, IntPtr.Zero, movement) == false) { this.errorcode = Marshal.GetLastWin32Error(); this.errorpos = MFTHaltPosition.MoveFile; return false; } return true;
}
Where
EFileMove
is set toEFileMove.FileBegin
(aka. 0) When I run anotherReadFile
, it continues to read out the same block of data into the buffer (the first four bytes should beFILE
, but instead reads the beginning of theNTFS
block). Does anyone have an idea why it wouldn't move the pointer forward (position is a value far above 0), and is there a solution? Thank you, ChrisNot that it should make any difference, so far as I can tell, but just in case it triggers something in your brain cell. Is the type of your
EFileMove
set touint
?enum EFileMove : uint
{
FileBegin = 0,
.................
.................
{The documentation I have read says the
dwMoveNethod
should be a uint.Henry Minute Do not read medical books! You could die of a misprint. - Mark Twain Girl: (staring) "Why do you need an icy cucumber?" “I want to report a fraud. The government is lying to us all.”
-
Is SetFilePointerEx returning 0? If so, what is GetLastError reporting? I would recommend using SafeFileHandle instead of IntPtr for the file handle. I assume you are doing a verbatum translation of your C++ code to C#, so that you know the actual sequence of calls you are performing are valid.
Yes, my
EFileMove
structure is inheritinguint
. When I get chance, i'll try converting the code to useSafeFileHandle
. When I runSetFilePointerEx
and sending 0 as the distance to move, and setting the file movement toEFileMove.FileEnd
, the resultinglong
value is always 0. It doesn't seem to adjust the pointer at all. I'm wondering if I should try passing aLARGE_INTEGER
structure through it instead? -
Yes, my
EFileMove
structure is inheritinguint
. When I get chance, i'll try converting the code to useSafeFileHandle
. When I runSetFilePointerEx
and sending 0 as the distance to move, and setting the file movement toEFileMove.FileEnd
, the resultinglong
value is always 0. It doesn't seem to adjust the pointer at all. I'm wondering if I should try passing aLARGE_INTEGER
structure through it instead? -
if SetFilePointerEx is returning false, then you should look at the error code.
if (!SetFilePointerEx(...)) { throw new Win32Exception(Marshal.GetLastWin32Error()); }
It's not returning false, but the
long
output for the 3rd argument (if I change the argument type toref long
) returns 0 (which documented by MSDN, would return the position of the pointer, thus the pointer hasn't changed). -
It's not returning false, but the
long
output for the 3rd argument (if I change the argument type toref long
) returns 0 (which documented by MSDN, would return the position of the pointer, thus the pointer hasn't changed).The third argument is actually 64 bit unsigned, so strictly speaking
long
is not the correct cast.Henry Minute Do not read medical books! You could die of a misprint. - Mark Twain Girl: (staring) "Why do you need an icy cucumber?" “I want to report a fraud. The government is lying to us all.”
-
The third argument is actually 64 bit unsigned, so strictly speaking
long
is not the correct cast.Henry Minute Do not read medical books! You could die of a misprint. - Mark Twain Girl: (staring) "Why do you need an icy cucumber?" “I want to report a fraud. The government is lying to us all.”
Edit Nevermind. Seems passing
Threading.NativeOverlapped
toReadFile
was causing issues with the buffer. And I also changed allIntPtr
toSafeFileHandle
, and it's working now. Thanks! Previous It makes no difference if I convert all theInt64
typeslong
, it still doesn't adjust the pointer and mySetFilePointerEx(this.block, 0, out pos, EFileMove.FileEnd);
still assigns 0 to the pos variable (and the buffer is not changed).modified on Saturday, January 1, 2011 7:41 AM
-
Not that it should make any difference, so far as I can tell, but just in case it triggers something in your brain cell. Is the type of your
EFileMove
set touint
?enum EFileMove : uint
{
FileBegin = 0,
.................
.................
{The documentation I have read says the
dwMoveNethod
should be a uint.Henry Minute Do not read medical books! You could die of a misprint. - Mark Twain Girl: (staring) "Why do you need an icy cucumber?" “I want to report a fraud. The government is lying to us all.”
the boundary between managed and unmanaged code does not care about the exact numeric type, all it needs is the right amount of bits. Signed and unsigned are irrelevant at run-time, as it used to be in purely native code. :)
Luc Pattyn [Forum Guidelines] [My Articles] [My CP bug tracking] Nil Volentibus Arduum
Season's Greetings to all CPians.
-
Hey there, I'm working on an NTFS Master File Table reader as part of a project for University. I've already got a Console API working in C++ which reads the current $MFT file/table, and i've begun work on porting the code over to C# (as per my requirements), however my version of SetFilePointerEx doesn't seem to move the file buffer pointer. My C++ code:
BOOL __stdcall SetFileBlockLocation(HANDLE address, LARGE_INTEGER position)
{
return SetFilePointerEx(address, position, NULL, FILE_BEGIN);
}My C# code:
public bool AssignPointerPosition(Int64 position, EFileMove movement)
{
if (this.IsBufferReady == false)
return false;if (Win32API.SetFilePointerEx(this.block, (long)position, IntPtr.Zero, movement) == false) { this.errorcode = Marshal.GetLastWin32Error(); this.errorpos = MFTHaltPosition.MoveFile; return false; } return true;
}
Where
EFileMove
is set toEFileMove.FileBegin
(aka. 0) When I run anotherReadFile
, it continues to read out the same block of data into the buffer (the first four bytes should beFILE
, but instead reads the beginning of theNTFS
block). Does anyone have an idea why it wouldn't move the pointer forward (position is a value far above 0), and is there a solution? Thank you, ChrisIf you use P/Invoke sufficiently correctly (it does not care about the exact integer types, all that matters is the size of the variables), the C# version should behave the same as the C++ version. And then the MSDN documentation says: "The file pointer returned by this function is not used for overlapped read and write operations. To specify the offset for overlapped operations, use the Offset and OffsetHigh members of the OVERLAPPED structure." Maybe that explains some. :)
Luc Pattyn [Forum Guidelines] [My Articles] [My CP bug tracking] Nil Volentibus Arduum
Season's Greetings to all CPians.
-
the boundary between managed and unmanaged code does not care about the exact numeric type, all it needs is the right amount of bits. Signed and unsigned are irrelevant at run-time, as it used to be in purely native code. :)
Luc Pattyn [Forum Guidelines] [My Articles] [My CP bug tracking] Nil Volentibus Arduum
Season's Greetings to all CPians.
On the way in, I agree. Although I understood that if the unmanaged part filled those bits with what it considered an unsigned value and then on return to the managed code those same bits were treated as or cast to a signed value, there is a possibility of unpredictable results.
Henry Minute Do not read medical books! You could die of a misprint. - Mark Twain Girl: (staring) "Why do you need an icy cucumber?" “I want to report a fraud. The government is lying to us all.”