Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Why SetFilePointerEx can't accept a negative number as the distance offset?

265 views
Skip to first unread message

xmllmx

unread,
Sep 7, 2007, 3:48:54 PM9/7/07
to
Hi all,

I encounter a strange problem. I successfully opened one partition for
reading its sectors, however, I couldn't successfully pass a negative
value as the offset from FILE_END. Note that the value is sector-
aligned.

=============== Code ===============

HANDLE hDrive = CreateFile(L"\\\\.\\C:", GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL&~FILE_FLAG_NO_BUFFERING, 0);
LARGE_INTEGER i64;
i64.QuadPart = -512;
SetFilePointerEx(hDrive, i64, 0, FILE_END); // Fail! Why?
CloseHandle(hDrive);

=============== Code ===============

If I open an ordinary file such as L"C:\\sample.txt", then everything
is OK. What is the difference between a partition and a file?

Thanks in advance!

xmllmx

unread,
Sep 7, 2007, 3:58:31 PM9/7/07
to
Even if I change the value -512 to 0, the call to SetFilePointerEx
still fails.

How weird it is!

xmllmx

unread,
Sep 7, 2007, 4:05:14 PM9/7/07
to
PS.

The error code returned by SetFilePointerEx is 0x87
(ERROR_INVALID_PARAMETER).


AliR (VC++ MVP)

unread,
Sep 7, 2007, 4:14:56 PM9/7/07
to
Have you tried passing a file * as the third parameter instead of null to
see what happens?

AliR.


"xmllmx" <xml...@gmail.com> wrote in message
news:1189195514....@w3g2000hsg.googlegroups.com...

xmllmx

unread,
Sep 7, 2007, 4:34:49 PM9/7/07
to
> > (ERROR_INVALID_PARAMETER).- Hide quoted text -
>
> - Show quoted text -

Yes, I've tried. But the result is the same.

MSDN says, If this parameter is NULL, the new file pointer is not
returned.

Joseph M. Newcomer

unread,
Sep 7, 2007, 11:48:25 PM9/7/07
to
I have no idea what asking SetFilePointerEx to do to seek to a drive even means, since
this can only apply to a file.

Also, what does

FILE_ATTRIBUTE_NORMAL & ~FILE_FLAG_NO_BUFFERING

mean? It means

0x00000080 & ~0x20000000
or
0x00000080 & 0xDFFFFFFF

0000 0000 0000 0000 0000 0000 1000 0000
1101 1111 1111 1111 1111 1111 1111 1111
===================================
0000 0000 0000 0000 0000 0000 1000 0000
0x00000080
FILE_ATTRIBUTE_NORMAL

in other words, ~FILE_FLAG_NO_BUFFERING has ABSOLUTELY NO MEANING IN THIS CONTEXT!

Did you perhaps mean

FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING?

I cannot fathom what SetFilePointerEx could mean when a drive is opened. I note that you
do not actually test the CreateFile to see if it works. You do not call ::GetLastError()
to get the error code. You do not check the result of ::SetFilePointerEx (whose third
parameter should be written as NULL, not 0), and you do not call ::GetLastError() to
answer your own question!

When coded properly, you will find the error code is 87, invalid parameter value. And
your question is misleading, because it cannot accept 0, either. And it does not accept
+512. In fact, it does not appear to accept ANY offset! Perhaps it is because
SetFilePointerEx has no meaning?

Also GetFileInformationByHandle() also fails, with error code 87. GetFileSizeEx() fails
with error code 87.

Also, when using binary operators like |, please put whatspace around them so the code is
readable.

What is it you are trying to accomplish?
joe

Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm

xmllmx

unread,
Sep 8, 2007, 12:27:28 AM9/8/07
to
Thank you, Joseph.

My purpose is simple: I want to read the last sector of the drive.

All of the first three posts are mine. Maybe you just saw my first
post.

My second post:
==================


"Even if I change the value -512 to 0, the call to SetFilePointerEx
still fails.

How weird it is!"
==================


My third post:
==============
"PS.

The error code returned by SetFilePointerEx is 0x87
(ERROR_INVALID_PARAMETER)."

==================

CreateFile is successful. And I can sucessfully call SetFilePointerEx
with positive value such as 512, 1024, etc. As long as the offset is
positive and sector-aligned, the call will always succeed!

For example, the following code is OK.

========== Code =============


HANDLE hDrive = CreateFile(L"\\\\.\\C:", GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING,

NULL, NULL);
LARGE_INTEGER i64;
i64.QuadPart = 512; // must be a whole number multiple of the volume's
sector size
SetFilePointerEx(hDrive, i64, 0, FILE_BEGIN); // OK!
CloseHandle(hDrive);
========== Code =============

Moreover, in some case, I can use a negative value successfully. See
below:

i64.QuadPart = 512; // must be a whole number multiple of the volume's
sector size
SetFilePointerEx(hDrive, i64, 0, FILE_BEGIN); // OK!

/*
Now the current file pointer points to 512, so I can move the file
pointer backward.
*/
i64.QuadPart = -512;
SetFilePointerEx(hDrive, i64, 0, FILE_CURRENT); // OK!

>From the experiments above, we can see that SetFilePointerEx() has its
meaning. I think a drive can be treated as an ordinary file.
GetFileType() will return FILE_TYPE_DISK, which means the drive is
seeking device rather than nonseeking device, so we can call
SetFilePointerEx on the drive.

After I rephrase my problem, my original problem is still unsolved:

i64.QuadPart = -512;
SetFilePointerEx(hDrive, i64, 0, FILE_END); // This time the call will
still return 0x87

I'm still awaiting help for this. Thanks.

Joseph M. Newcomer

unread,
Sep 8, 2007, 1:41:35 AM9/8/07
to
You can't. For all practical purposes, the *concept* does not even exist. Since it makes
no sense to allow this (you don't even know what the last sector is, and given dynamic
remapping, RAID drives, virtual drives, etc.) there is no way to even *identify* what the
last sector is! You can only do this if you have privileged access to the physical drive,
and you don't have that.

I have no idea why this could possibly make sense, even if it were possible, but no sane
operating system would ever permit this sort of thing to be done. It would be a truly
massive security hole. So it isn't going to happen.
joe

Norman Diamond

unread,
Sep 9, 2007, 8:37:27 PM9/9/07
to
The original poster has permission to open the entire partition and
read/write the entire partition, so an attempt to read the last sector of
the partition is not a security hole.

Even though we don't know in the physical hardware which sector is "last" in
some sense in the physical drive (or in which physical drive in RAID as you
point out) there is some sector that has the highest block number, starting
from 0 for the first block in the partition.

I don't know why Windows doesn't deliver, but the original poster's wishes
look sensible to me.


"Joseph M. Newcomer" <newc...@flounder.com> wrote in message
news:tad4e35ub4jp9foqg...@4ax.com...

Alexander Grigoriev

unread,
Sep 9, 2007, 9:56:18 PM9/9/07
to
It could be that files opened to the whole partition don't have "size"
concept. Thus, end of file is not known for them.
I wonder whether GetFileSize(Ex) will succeed for such a handle and return
non-zero result.

"Norman Diamond" <ndia...@community.nospam> wrote in message
news:OvgmML08...@TK2MSFTNGP04.phx.gbl...

0 new messages