### Author Topic: Trouble with file length under Win64  (Read 1255 times)

#### Gunther

• Member
• Posts: 3720
• Forgive your enemies, but never forget their names
##### Trouble with file length under Win64
« on: February 10, 2021, 10:11:00 PM »
Here is a small Win64 test program to determine the length of a file:
Code: [Select]
` include \masm32\include64\masm64rt.inc        option casemap: none        .data        align      1msg0               db "This small program is supposed to determine the length of a file:", 10                   db "-----------------------------------------------------------------", 10, 10, 0msg0A              db "File length = ", 0msg0B              db " Bytes", 10, 10, 0                   msg1               db "All tasks completed.", 10, 10, 0                   TheFile            db "TestFile.txt", 0  ; our test filestr_format         db "%s", 0            ; string formatuint64_format      db "%llu",0           ; 64 bit unsigned integer        align      8hTheFile           dq ?                  ; file handleTheFileLen         dq ?                  ; file length       .code; main             ; Purpose:    Assembly Language Framemain    proc        push       rbp                   ; preserve callee save CPU registers        push       rbx        push       rdi        push       rsi        push       r12        push       r13        push       r14        push       r15        ; open the file        invoke     vc_printf, addr str_format, addr msg0        invoke     CreateFileA, addr TheFile, GENERIC_READ, 0, 0, 0, FILE_ATTRIBUTE_NORMAL, OPEN_EXISTING        mov        hTheFile, rax         ; save file handle        ; get file size        invoke     GetFileSize, hTheFile, 0        mov        TheFileLen, rax       ; save file length        ; print file size        invoke     vc_printf, addr str_format, addr msg0A        invoke     vc_printf, addr uint64_format, addr TheFileLen        invoke     vc_printf, addr str_format, addr msg0B        ; close the file                 invoke     CloseHandle, hTheFile         invoke     vc_printf, addr str_format, addr msg1        waitkey        pop        r15                   ; restore CPU registers        pop        r14        pop        r13        pop        r12        pop        rsi        pop        rdi        pop        rbx        pop        rbp        invoke     ExitProcess, 0main    endp        end`It doesn't work as it should. Here's the output:
Quote

This small program is supposed to determine the length of a file:
-----------------------------------------------------------------

File length = 5368717616 Bytes

That's the point: the examined file is only 800 bytes in size. So the wrong file length is printed.

What's wrong with that? The archive contains the source, the executable program, the batch file and the test file. It is a small ASCII text file with 20 lines of text. Nothing exciting or disreputable.

Gunther
Get your facts first, and then you can distort them.

#### jj2007

• Member
• Posts: 11306
• Assembler is fun ;-)
##### Re: Trouble with file length under Win64
« Reply #1 on: February 10, 2021, 10:46:18 PM »

Code: [Select]
`include \Masm32\MasmBasic\Res\JBasic.inc ; ## builds in 32- or 64-bit mode with UAsm, ML, AsmC ##Init ; OPT_64 1 ; put 0 for 32 bit, 1 for 64 bit assembly  Cls  PrintLine Chr\$("This program was assembled with ", @AsmUsed\$(1), " in ", jbit\$, "-bit format.")  PrintLine "This small program is supposed to determine the length of a file:"  hTheFile equ <rbx>  mov hTheFile, rv(CreateFileA, Chr\$("GetFileSize.asc"), GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)  jinvoke     GetFileSize, hTheFile, 0  Print Str\$("The file size is %i bytes\n", rax)  jinvoke     CloseHandle, hTheFile  Inkey "all is fine"EndOfCode`
Output:
Code: [Select]
`This program was assembled with ml64 in 64-bit format.This small program is supposed to determine the length of a file:The file size is 4254 bytesall is fine`
Of course, if you are dealing with large files, you need a second argument to get the high dword.

#### mikeburr

• Member
• Posts: 132
##### Re: Trouble with file length under Win64
« Reply #2 on: February 10, 2021, 11:50:30 PM »
the resulting question   is prob ...
is this implying that 1 gig in 4 is allocated for potential file overhead [ sector / track overheads ]????
regards mikeb

#### TimoVJL

• Member
• Posts: 695
##### Re: Trouble with file length under Win64
« Reply #3 on: February 10, 2021, 11:55:08 PM »
Code: [Select]
`uint64_format      db "%llu",0           ; 64 bit unsigned integer` this might not be usable with msvcrt.dll,
have to use at least msvcr100.dll ?
May the source be with you

#### Vortex

• Member
• Posts: 2530
##### Re: Trouble with file length under Win64
« Reply #4 on: February 10, 2021, 11:58:39 PM »
Hi Gunther,

Can you try this one ?

Code: [Select]
`invoke     vc_printf, addr uint64_format, TheFileLen`

#### HSE

• Member
• Posts: 1612
• <AMD>< 7-32>
##### Re: Trouble with file length under Win64
« Reply #5 on: February 11, 2021, 12:17:12 AM »
Hi Gunther,

A good practice (at least when something went wrong ) is:
Code: [Select]
`invoke CreateFileA, addr TheFile, GENERIC_READ, 0, 0, 0, FILE_ATTRIBUTE_NORMAL, OPEN_EXISTING.if eax!=INVALID_HANDLE_VALUE                               mov hTheFile, rax         ; save file handle        ....else       ; there is an error.endif`
Regards, HSE

#### mikeburr

• Member
• Posts: 132
##### Re: Trouble with file length under Win64
« Reply #6 on: February 11, 2021, 12:38:20 AM »
HSE .. completely agree .... error checking essential ....
in this case
i doubt whether its failed .. its assumed  a max size/ default  32 bit file [ hence the 4gig comment and overheads comment ]
...  as create disposition 0 not defined in the SDK
with the open existing as security_batch etc etc
regards mikeb

#### jj2007

• Member
• Posts: 11306
• Assembler is fun ;-)
##### Re: Trouble with file length under Win64
« Reply #7 on: February 11, 2021, 12:48:08 AM »

Nope, Mike. As mentioned above, the order of arguments needs to be checked, that's all.

Btw GetFileSize is no good for certain hidden files (CreateFile fails), as I noted when testing for a large file:
Code: [Select]
`include \masm32\MasmBasic\MasmBasic.inc  Init  .if Exist("C:\hiberfil.sys") Inkey Str\$("File size is %3f GB", edx::GfSize(-1)/1073741824)  .else Inkey "no such file"  .endifEndOfCode`
File size is 4.39 GB (GfSize uses FindFirstFile instead of GetFileSize)

#### mikeburr

• Member
• Posts: 132
##### Re: Trouble with file length under Win64
« Reply #8 on: February 11, 2021, 12:59:12 AM »
jj
i think youve prob misunderstood what i wrote .. we can all see the params are incorrect ..
1) the question is whether create file succeeded with apparantly erroneous params [ hence the "not defined" comment ]
id like to see what happens with invalidity testing in to see if it did work by chance
2) the file size if created implied a fairly substantial file overhead hence the first comment i made
interested to hear about getfile though
regards mikeb

#### jj2007

• Member
• Posts: 11306
• Assembler is fun ;-)
##### Re: Trouble with file length under Win64
« Reply #9 on: February 11, 2021, 01:06:49 AM »
For large files that are indeed accessible, the correct use of CreateFile+GetFileSize is as follows:
Code: [Select]
`  mov hTheFile, rv(CreateFileA, Chr\$("GetFileSize.asc"), GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)  jinvoke GetFileSize, hTheFile, addr fsize ; point to a DWORD  mov edx, fsize  shl rdx, 32  add rax, rdx  Print Str\$("The file size is %i bytes\n", rax)`
As you rightly write, Mike, there is a certain overhead: CreateFile(); that's why GfSize() uses FindFirstFile under the hood, and can check the size of locked files, too.

How relevant that overhead is, that's another question
Code: [Select]
`25 ms for 1000x CreateFile, GetFileSize and CloseHandle25 ms for 1000x FindFirstFile and getting the size22 ms for 1000x CreateFile, GetFileSize and CloseHandle25 ms for 1000x FindFirstFile and getting the size20 ms for 1000x CreateFile, GetFileSize and CloseHandle24 ms for 1000x FindFirstFile and getting the size21 ms for 1000x CreateFile, GetFileSize and CloseHandle24 ms for 1000x FindFirstFile and getting the size21 ms for 1000x CreateFile, GetFileSize and CloseHandle25 ms for 1000x FindFirstFile and getting the size`

#### TouEnMasm

• Member
• Posts: 1615
##### Re: Trouble with file length under Win64
« Reply #10 on: February 11, 2021, 01:41:54 AM »

The createfile function don't give the size of the file.What you get is unitialised data.
use : FindFirstFile to get the size

Quote
.data
InfosFiles WIN32_FIND_DATA <>
NomAediter db "\chose\myfle.txt",0
.code
mov edx,ex
invoke FindClose,edx          ;close the search and now you have the size of the file in InfosFiles.nFileSizeLow

Fa is a musical note to play with CL

#### Gunther

• Member
• Posts: 3720
• Forgive your enemies, but never forget their names
##### Re: Trouble with file length under Win64
« Reply #11 on: February 11, 2021, 03:31:45 AM »
Timo,

Code: [Select]
`uint64_format      db "%llu",0           ; 64 bit unsigned integer` this might not be usable with msvcrt.dll,
have to use at least msvcr100.dll ?

you're right. It works fine with GCC's RTL, but not with msvcrt.dll. That's a real mess.

Erol,

Can you try this one ?

Code: [Select]
`invoke     vc_printf, addr uint64_format, TheFileLen`

that doesn't help.

HSE,

[/quote]
A good practice (at least when something went wrong ) is:
Code: [Select]
`invoke CreateFileA, addr TheFile, GENERIC_READ, 0, 0, 0, FILE_ATTRIBUTE_NORMAL, OPEN_EXISTING.if eax!=INVALID_HANDLE_VALUE                               mov hTheFile, rax         ; save file handle        ....else       ; there is an error.endif`
Regards, HSE

yes, of course. But it's only a small test program, to show the problem. Right now, it looks like it's a mix of several factors. I'll get back when I know more.

Gunther
Get your facts first, and then you can distort them.

#### Gunther

• Member
• Posts: 3720
• Forgive your enemies, but never forget their names
##### Re: Trouble with file length under Win64
« Reply #12 on: February 11, 2021, 04:37:40 AM »
As I already suspected, it was a concatenation of various error causes. Once the order of the parameters was not correct. On the other hand, there were problems printing unsigned long long with msvcrt.dll.

I was able to correct all this and now the file length is correctly determined and printed. Thanks for the help.

Gunther

« Last Edit: February 11, 2021, 06:37:58 AM by Gunther »
Get your facts first, and then you can distort them.

#### TimoVJL

• Member
• Posts: 695
##### Re: Trouble with file length under Win64
« Reply #13 on: February 11, 2021, 10:59:05 PM »
It works fine with GCC's RTL, but not with msvcrt.dll. That's a real mess.
M\$ just wanted to do things in their own way in Steve Pallmer era, C99 standard wasn't in their list.
May the source be with you

#### Gunther

• Member
• Posts: 3720
• Forgive your enemies, but never forget their names
##### Re: Trouble with file length under Win64
« Reply #14 on: February 12, 2021, 12:35:38 AM »
Timo,

M\$ just wanted to do things in their own way in Steve Pallmer era, C99 standard wasn't in their list.

that's right, but you can't just blame Ballmer, the gnat. Mr. Gates also has his share in this development.

Gunther
Get your facts first, and then you can distort them.