News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Reading a file.

Started by agnokapathetic, April 12, 2006, 08:06:16 PM

Previous topic - Next topic

agnokapathetic

Hey all,
I'm just starting to take up assembly as a hobby after working with higher level languages such as Python and Java for years. As i devel into Assembly it seems quite elegant in its extreme, raw, simplicity.

Anyways, with my first project, I'm trying to read a file, and use the user32 MessageBox to display the information.

Im thinking my problem might be a type mistmatch (If you have them in Assembler, Like I said i'm and infant in this language).


.486
.model flat, stdcall
option casemap:none


include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
include \masm32\include\user32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib

.data
logfile db "test.log",0
.data?
hLog HANDLE ?                                  ; File handle
temp_buffer   db 32768 dup(?)

SizeReadWrite DWORD ?                   ; number of bytes actually read or write
.code
start:
invoke CreateFile,ADDR logfile, GENERIC_READ ,  FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,   NULL
mov hLog,eax

invoke ReadFile,hLog,temp_buffer, 16, ADDR SizeReadWrite,NULL ; Size hardcoded

invoke MessageBox,0,temp_buffer ,"Test",0

invoke CloseHandle,hLog

end start


Thanks in advance,
--Joel

Mark Jones

Hello Joel, welcome to the group. :toothy

Code looks pretty good, have you tried running it in a debugger such as OllyDbg yet? CreateFile and ReadFile are very particular about their flags and permissions. Stepping through each instruction (F8 in Olly) can "show" you what happens on nearly a line-by-line basis - very helpful for isolating issues.

There might be a few caveats with the program as it is written (I can't test it at the moment.) One is that the MessageBox API will only display a set quantity of text. If you try to display more than it can hold (about 1k probably), it will just exit with an (unhandled) error.

There are a few errors in the line

    invoke MessageBox,0,temp_buffer ,"Test",0


If you look up the MessageBox API at MSDN or in the Win32.HLP file, it shows the string parameters as "lpText" and "lpCaption." The lp basically stands for pointer, so that token should be a pointer and not a value, so try ADDR temp_buffer.

Quotations are not allowed in INVOKE statements. You can try replacing INVOKE with FN, which is a macro like invoke which allows quotations. That might do the trick. You'll need to include \masm32\macros\macros.asm

Finally you might want to consider allocating large buffers dynamically using routines like masm32's STRALLOC and STRFREE or Windows' GlobalAlloc and related. The .data? section is intended primarily for global uninitialized variables, not large buffers (it should work either way though.) Have fun!  :U
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

MichaelW

Also, you need to properly end the process, normally done with a call to ExitProcess.

If the Message Box caption "Error" is acceptable you can pass NULL in the lpCaption parameter.

eschew obfuscation

zcoder

Try to change these lines to this:

   invoke ReadFile,hLog,addr temp_buffer, 16, ADDR SizeReadWrite,NULL ; Size hardcoded
   
   invoke MessageBox,0,addr temp_buffer ,"Test",0   

I am not sure what macro you are using for the "Test" but if your not that is wrong too.

Zcoder....
Back in 1979, My computer ran so fine.
And there was no such thing,
As a Microsoft Crashed Machine.
http://zcoder.110mb.com
http://www.dietzel.com/partner/idevaffiliate.php?id=345_6  Free Domain Names

hutch--

#4
Joel,

Welcome on board. Here is a quick fix that works.


.486
.model flat, stdcall
option casemap:none


include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
include \masm32\include\user32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib

  .data
    logfile db "test.log",0
    msgbox_title db "Test",0

  .data?
    hLog HANDLE ?                                  ; File handle
    temp_buffer   db 32768 dup(?)
    fsiz dd ?
    SizeReadWrite DWORD ?                   ; number of bytes actually read or write

.code
start:

    invoke CreateFile,ADDR logfile,GENERIC_READ,
           FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL
    mov hLog,eax

    invoke GetFileSize,hLog,NULL
    mov fsiz, eax

    invoke ReadFile,hLog,ADDR temp_buffer,fsiz, ADDR SizeReadWrite,NULL

    invoke MessageBox,0,ADDR temp_buffer,ADDR msgbox_title,0

    invoke CloseHandle,hLog

    invoke ExitProcess,0

end start


See extra version below.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

The Svin

It also good to use GetFileAttributes before CreateFile, since there is possibilities that attributes you assumed for the file wouldn't match the factual ones.

agnokapathetic

Thanks to all of you.

I think I'm still treating the lanuage like i'de treat a higher level language, and i need to start thinking outside of my abstracted box  :lol

Thank you yet again, you all are part of a very welcoming community.

--Joel

PBrennick

Hutch,
The second example you post, the one that will open any size file will not assemble.  He will not be able to assemble it because temp_buffer is missing.

Paul
The GeneSys Project is available from:
The Repository or My crappy website

hutch--

Thanks Paul,

I appear to have resaved a version that was only partly modified. I get caught that way occasionally with multiple copies of the same source.

here is the fix.


    .486
    .model flat, stdcall
    option casemap:none


    include \masm32\include\windows.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\masm32.inc
    include \masm32\include\user32.inc

    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\masm32.lib

    .data
      logfile db "test.log",0
      msgbox_title db "Test",0

    .code

; --------------------------------------------------

start:
    call main
    invoke ExitProcess,0

; --------------------------------------------------

main proc

    LOCAL hLog  :DWORD      ; file handle
    LOCAL fsiz  :DWORD      ; file size
    LOCAL bwrt  :DWORD      ; bytes written
    LOCAL hMem  :DWORD      ; memory handle

    invoke CreateFile,ADDR logfile,GENERIC_READ,
           FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_ARCHIVE,NULL
    mov hLog, eax

    invoke GetFileSize,hLog,NULL            ; get the file size
    mov fsiz, eax
    sub fsiz, 1

    invoke GlobalAlloc,GMEM_FIXED,fsiz      ; allocate at least that much memory
    mov hMem, eax

    invoke ReadFile,hLog,hMem,fsiz,ADDR bwrt,NULL

    invoke MessageBox,0,hMem,ADDR msgbox_title,0

    invoke CloseHandle,hLog                 ; close the file handle

    invoke GlobalFree,hMem                  ; free the allocated memory

    ret

main endp

; --------------------------------------------------

end start
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

PBrennick

That definitely works, but have you tried it with a large file?   It is not very usuable without scrollbars!

Paul
The GeneSys Project is available from:
The Repository or My crappy website

hutch--

 :bg

You are right, a MessageBox is not suited for large text display but i did not want to change the original example too much or make it too complicated.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php