Click here to Skip to main content
16,016,738 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello,

I have some weird problems with SetFilePointer.

Let's there is file with this data at the beginning of the file
{ 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A};

hSomeObject = CreateFileA(chSomeFile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
SetFilePointer(hSomeObject, 2, 0, FILE_BEGIN);
ReadFile(hSomeObject, chSomeBuffer, 0xA0, &dwBytesRead, 0);


So the values in chSomeBuffer should be like {0x3A, 0x4A, 0x5A ...}
But the pointer is set to 4 instead of 2. So it looks like {0x5A, 0x6A, 0x7A ...}

I checked the call in the debugger. And yes it's called with 2 as lDistanceToMove.

So my questions is: What the heck?

Not forget to mention the SetFilePointer(hSomeObject, 0, 0, FILE_BEGIN); gives me requested output (But that's also strange as there are still 2 bytes skipped at the beginning).
Posted

It works for me. Are you sure about your file?

HANDLE hSomeObject;
BYTE chSomeBuffer[500];
DWORD dwBytesRead;
hSomeObject = CreateFileA("C:\\Test.bin", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
SetFilePointer(hSomeObject, 2, 0, FILE_BEGIN);
ReadFile(hSomeObject, chSomeBuffer, 0xA0, &dwBytesRead, 0);



This site has a great free hex editor (XVI32):
http://www.chmaas.handshake.de/[^]
 
Share this answer
 
Comments
Espen Harlinn 6-Feb-11 16:43pm    
Good effort, my 5 - and another reason to suspect what we are not allowed to see :)
Im2N00By 6-Feb-11 18:07pm    
Yea I passed wrong file name by accident. They have almost identical data -> so that's why I was confused about the 2 bytes shift.
I made this error while I copied&pasted some parts of code and didn't noticed the variable name.
My guess is that you are comiling for UNICODE - this is easily checked, in the solution explorer right click on the project, select Properties and check General->Character Set.

This would explain why things seems to behave unexpectedly, well, it's a guess ...

Regards
Espen Harlinn
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 6-Feb-11 16:29pm    
Espen, to me, nothing indicates the use of stings or characters in the data in Question.
How can it be relevant?
--SA
Espen Harlinn 6-Feb-11 16:38pm    
The number of programs, including my own, that would fail if SetFilePointer didn't work as expected, is tremendous. So according to Sherlock Holmes: "When you have eliminated the impossible, whatever remains, however improbable, must be the truth". So basically I suspect the parts of his code we don’t see. Inadvertently compiling for unicode, while expecting ansi behavior is one possible explanation. He is using CreateFileA and not CreateFile, and that may be another hint. As I mentioned - it's a guess :)
Sergey Alexandrovich Kryukov 6-Feb-11 17:11pm    
I agree on everything, except I don't know where is Unicode is in your example. The API documentation explicitly say the shift is passed in bytes.

However, I can see your point. The way OP presents information about the file suggests it's some integers, but, strictly speaking it is not said explicitly and could be a set of characters, then the size would depend on Unicode compilation option, as you suggested.

--SA
Espen Harlinn 6-Feb-11 17:19pm    
As I wrote, it's a guess, mostly based on CreateFileA, and that VC++ 2010 now seems to create new projects with UNICODE on by default, that may take some people by surprise - TCHAR just became a wchar_t instead of char. As we don't see the rest of his code - it's obviously speculation on my part :)
Sergey Alexandrovich Kryukov 6-Feb-11 17:18pm    
Espen, I just calculated the items in my assumption and found the pointer that the data item is 4 bytes size, so if the shift is done by 2, it was actually done by 1 element instead of 2 elements and it give exactly the same pointer as OP describes. Multiplying offset in elements by sizeof(ElementType) will give exactly expected answer. Please check up -- my answer is correct.
--SA
It depends on the size of your data element. SetFilePointer does not know anything about if, so it point to 2 bytes, regardless. Probably, your element size is 4 bytes (8, whatever, you figure).

You should multiply offset by the result of sizeof.

—SA
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 6-Feb-11 17:20pm    
I checked up the calculation and obtained exactly the result you see and the result you expect through multiplication of the desired shift by sizeof of element type. Please check up -- will work as you expect.
--SA
Im2N00By 6-Feb-11 18:14pm    
#FIXED -> Problem solved by Answer 1
Why I should multiple anything? I just needed the pointer to skip first 2 bytes. So should I do it like sizeof(unsigned char)*2 -> equal to 2*1 = 2?
Sergey Alexandrovich Kryukov 6-Feb-11 19:29pm    
Thank you very much about reporting back the resolution of a pointer.
As to multiplication, I thought you wanted to shift by two elements, not by two bytes. You did not clearly indicate the size of the element, right? Besides, this is better practice. If you change you data element declaration, the code SetFilePointer with multiplication will remain valid, the code without it will be off. Don't you agree?
--SA
Im2N00By 7-Feb-11 10:30am    
I should describe my problems more carefully. But it's not easy when I can't "reveal" what I'm working on (Else I could copy&paste whole function).
Sergey Alexandrovich Kryukov 7-Feb-11 21:35pm    
My advice is: you develop some code specifically to post a question. It might even help you to isolate problem. The code should be as small as possible yet manifesting the problem. This is for everyone's benefit.
--SA
Have you checked the return value of SetFilePointer to see if it is INVALID_SET_FILE_POINTER and if so called GetLastError.

In addition the third parameter should be NULL, not 0.
 
Share this answer
 
Comments
Im2N00By 6-Feb-11 18:11pm    
1] I removed error checks from the sample to shorten the code.
2] Ever wonder what NULL stands for? Check WinDef.h -> #define NULL 0
Henry Minute 6-Feb-11 18:38pm    
1] OK
2] Never looked.
Im2N00By 7-Feb-11 10:37am    
One more thing, my previous comment was little bit "offensive". I didn't mean it. I just got little bit upset about answers to my second question on other programming portal. In one part of long description I said: "I made kernel driver for that" and one of the answer was: "You can't do the g] in user mode. You will have to code a kernel driver". There was more answers like that...

So I would like to apologize.
Henry Minute 7-Feb-11 16:39pm    
No need to apologize.

I was not offended, I'm too thick for that. :)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900