I want to be able to process a file forward or backward.
According to the SetFilePointer documentation, by putting a negative figure
in the LDistanceToMove field, the file pointer should be reset so that previous
records can be processed.
Doesn't work for me. Just keeps on processing forward.
are you using the FILE_CURRENT flag ?
personally, i prefer to always use FILE_BEGIN and make my own calculations - lol
that function is funky enough, by itself
If FILE_BEGIN is specified, DistanceToMove is interpreted as an unsigned location for the new file pointer.
(I guess you are using FILE_BEGIN)
not to mention - it is a 64-bit pointer if lpDistanceToMoveHigh is not NULL
so - you may have a 32-bit signed value that needs to be extended to a 64-bit signed value
Yeah, the docu is pretty ambiguous:
pDistanceToMoveHigh: Points to the high-order word of the 64-bit distance to move
That implies somehow that you must set pDistanceToMoveHigh to -1 if the low dword is negative. But they don't tell you so....
I hope this makes sense.
;==============================================================================
include \masm32\include\masm32rt.inc
;==============================================================================
.data
byteCount dd 0
buffer db 0
.code
;==============================================================================
start:
;==============================================================================
invoke CreateFile, chr$("test.bin"),
GENERIC_READ or GENERIC_WRITE,
NULL,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
mov esi, eax
printf("file handle: %d\n\n", esi)
xor ebx, ebx
.WHILE ebx < 100
mov buffer, bl
invoke WriteFile, esi,
ADDR buffer,
1,
ADDR byteCount,
NULL
inc ebx
.ENDW
;--------------------------------------------------------------
invoke SetFilePointer, esi,
0,
NULL,
FILE_BEGIN
printf("SetFilePointer return value: %d\n", eax)
invoke ReadFile, esi,
ADDR buffer,
1,
ADDR byteCount,
NULL
printf("ReadFile return value: %d\n", eax)
movzx eax, buffer
printf("BYTE at offset 0 from FILE_BEGIN: %d\n\n", eax)
invoke SetFilePointer, esi,
1,
NULL,
FILE_BEGIN
printf("SetFilePointer return value: %d\n", eax)
invoke ReadFile, esi,
ADDR buffer,
1,
ADDR byteCount,
NULL
printf("ReadFile return value: %d\n", eax)
movzx eax, buffer
printf("BYTE at offset 1 from FILE_BEGIN: %d\n\n", eax)
;--------------------------------------------------------------
printf("Note that read and write operations update the file pointer.\n\n")
invoke SetFilePointer, esi,
0,
NULL,
FILE_CURRENT
printf("SetFilePointer return value: %d\n", eax)
invoke ReadFile, esi,
ADDR buffer,
1,
ADDR byteCount,
NULL
printf("ReadFile return value: %d\n", eax)
movzx eax, buffer
printf("BYTE at offset 0 from FILE_CURRENT: %d\n\n", eax)
invoke SetFilePointer, esi,
0,
NULL,
FILE_CURRENT
printf("SetFilePointer return value: %d\n", eax)
invoke ReadFile, esi,
ADDR buffer,
1,
ADDR byteCount,
NULL
printf("ReadFile return value: %d\n", eax)
movzx eax, buffer
printf("BYTE at offset 0 from FILE_CURRENT: %d\n\n", eax)
invoke SetFilePointer, esi,
1,
NULL,
FILE_CURRENT
printf("SetFilePointer return value: %d\n", eax)
invoke ReadFile, esi,
ADDR buffer,
1,
ADDR byteCount,
NULL
printf("ReadFile return value: %d\n", eax)
movzx eax, buffer
printf("BYTE at offset 1 from FILE_CURRENT: %d\n\n", eax)
invoke SetFilePointer, esi,
-1,
NULL,
FILE_CURRENT
printf("SetFilePointer return value: %d\n", eax)
invoke ReadFile, esi,
ADDR buffer,
1,
ADDR byteCount,
NULL
printf("ReadFile return value: %d\n", eax)
movzx eax, buffer
printf("BYTE at offset -1 from FILE_CURRENT: %d\n\n", eax)
;--------------------------------------------------------------
printf("Note that offset 0 from FILE_END is past the end of the file.\n\n")
invoke SetFilePointer, esi,
0,
NULL,
FILE_END
printf("SetFilePointer return value: %d\n", eax)
invoke ReadFile, esi,
ADDR buffer,
1,
ADDR byteCount,
NULL
printf("ReadFile return value: %d\n", eax)
movzx eax, buffer
printf("BYTE at offset 0 from FILE_END: %d\n\n", eax)
invoke SetFilePointer, esi,
-1,
NULL,
FILE_END
printf("SetFilePointer return value: %d\n", eax)
invoke ReadFile, esi,
ADDR buffer,
4,
ADDR byteCount,
NULL
printf("ReadFile return value: %d\n", eax)
movzx eax, buffer
printf("BYTE at offset -1 from FILE_END: %d\n\n", eax)
invoke SetFilePointer, esi,
-2,
NULL,
FILE_END
printf("SetFilePointer return value: %d\n", eax)
invoke ReadFile, esi,
ADDR buffer,
4,
ADDR byteCount,
NULL
printf("ReadFile return value: %d\n", eax)
movzx eax, buffer
printf("BYTE at offset -2 from FILE_END: %d\n\n\n", eax)
invoke CloseHandle,esi
inkey
exit
;==============================================================================
end start
I apologize for the scanty info.
This is in answer to all but MichaelW - still studying that answer.
32-bit OS
Generic_Read
invoke SetFilePointer, hFile, -15, NULL, File_Current
The SetFilePointer instruction is a test version. Records in the file are 15 bytes long.
Somewhere in the Docs I got the impression that File_Current had to be specified.
Thanks for all the responses.
Quote from: shankle on April 23, 2012, 08:43:14 PM
invoke SetFilePointer, hFile, -15, NULL, File_Current
Possible problems:
1. sign extension needed:
invoke SetFilePointer, hFile, -15, -1, File_Current
2. read or write operation moves pointer ahead
3. File_Current != FILE_CURRENT
Best option imho is to use FILE_BEGIN with a dword index:
sub ebx, 15
invoke SetFilePointer, hFile, ebx, NULL, FILE_BEGIN
This is what MasmBasic Seek #n, index uses, and it works just fine.
Quote from: MichaelW on April 23, 2012, 07:21:01 PMI hope this makes sense............
Excellent! :U Thanks for posting this.