The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: shankle on April 23, 2012, 05:32:55 PM

Title: SetFilePointer
Post by: shankle on April 23, 2012, 05:32:55 PM
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.
Title: Re: SetFilePointer
Post by: dedndave on April 23, 2012, 05:47:50 PM
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
Title: Re: SetFilePointer
Post by: jj2007 on April 23, 2012, 05:53:44 PM
If FILE_BEGIN is specified, DistanceToMove is interpreted as an unsigned location for the new file pointer.

(I guess you are using FILE_BEGIN)
Title: Re: SetFilePointer
Post by: dedndave on April 23, 2012, 06:01:53 PM
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
Title: Re: SetFilePointer
Post by: jj2007 on April 23, 2012, 06:06:43 PM
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....
Title: Re: SetFilePointer
Post by: MichaelW on April 23, 2012, 07:21:01 PM
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

Title: Re: SetFilePointer
Post by: shankle on April 23, 2012, 08:43:14 PM
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.
Title: Re: SetFilePointer
Post by: jj2007 on April 23, 2012, 08:56:39 PM
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.
Title: Re: SetFilePointer
Post by: JD on April 23, 2012, 09:15:13 PM
Quote from: MichaelW on April 23, 2012, 07:21:01 PMI hope this makes sense............

Excellent!  :U  Thanks for posting this.