News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Reading in file to struct

Started by jasonabullard, November 21, 2012, 04:40:31 PM

Previous topic - Next topic

jasonabullard


First just wanted to say hi and glad to finally be able to start learning asm.  Tried a few years ago and did not have the time to commit that it takes to learn.  My background is mainly C# and some c++ but I have always wanted to at least learn the basics of asm.  Even in C# I always found myself having to use API's because of the limitations within the .NET framework.  With that said here is my first question...how does one convert the buffer received from ReadFile into a struct?  I have tried using assume and although this works good it seems to either be aligned improperly or I'm doing something wrong.

Here is the code snippet of creating and reading:


mov hFile, FUNC(CreateFile, addr FilePath, GENERIC_READ or GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0)
.if hFile == INVALID_HANDLE_VALUE
invoke GetLastError
invoke MessageBox, NULL, eax, addr AppName, MB_OK
.endif

mov pBuffer, FUNC(GlobalAlloc, GMEM_FIXED or GMEM_ZEROINIT, 1000h)

invoke ReadFile, hFile, pBuffer, 1000h, addr nBytesRead, NULL
.if eax != TRUE
invoke GetLastError
invoke MessageBox, NULL, eax, addr AppName, MB_OK
.endif

mov edi, pBuffer
assume edi:ptr REGF

.if [edi].signature == REGF_SIGNATURE
invoke MessageBox, hwnd, addr [edi].signature, offset AppName, MB_OK
.endif


When I compare the two signatures they match and the message box presents me with the signature but adds a few characters to the end.  Here is my struct declaration:


; -------------------------
; Registry File Structure
; -------------------------
REGF struct [4]
signature dd ? ; offset = 0x00
sequence1 dd ? ; offset = 0x04
sequence2 dd ? ; offset = 0x08
REGF ends


If I attempt to show a messagebox with sequence1 or sequence2 the result is a * and block; however, it should be a number.  I'm pretty sure it is just me missing some type of alignment or possibly using the wrong types.

jj2007

I am a lazy Basic coder, so my version looks like this:

include \masm32\MasmBasic\MasmBasic.inc   ; download
.data?
rc   RECT <>

   Init
   Open "I", #1, "MyRect.dat"
   Recall #1, rc
   Close
   deb 1, "Result", rc.left, rc.top, rc.right, rc.bottom
   Exit
end start

But jokes apart: Your code looks ok. You are reading in dwords - have you thought of letting your MessageBox show strings?
  mov eax, [edi].signature
  invoke MessageBox, hwnd, str$(eax), offset AppName, MB_OK 

dedndave

Quote from: jj2007 on November 21, 2012, 05:44:42 PM
Your code looks ok. You are reading in dwords - have you thought of letting your MessageBox show strings?
  mov eax, [edi].signature
  invoke MessageBox, hwnd, str$(eax), offset AppName, MB_OK

that also applies to the value returned from GetLastError
they are binary values that need to be converted to ascii strings to be displayed
you can convert them to signed/unsigned decimal or hexidecimal strings (or whatever base you like)

MichaelW

Or you can get the system-defined error string for the error and display it.

;==============================================================================
; Build as a console app.
;==============================================================================
    include \masm32\include\masm32rt.inc
;==============================================================================
    .data
        lpBuffer dd 0
    .code
;==============================================================================
start:
;==============================================================================

    invoke SetLastError, ERROR_FILE_NOT_FOUND
    invoke GetLastError

    invoke FormatMessage, FORMAT_MESSAGE_ALLOCATE_BUFFER or \
                          FORMAT_MESSAGE_FROM_SYSTEM,
                          0,
                          eax,
                          0,
                          ADDR lpBuffer,
                          0,
                          0

    printf("%d\t%d\n\n", eax, ERROR_FILE_NOT_FOUND)

    printf("%s\n\n", lpBuffer )

    invoke LocalFree, lpBuffer

    printf("%s\n\n",LastError$())

    inkey
    exit

;==============================================================================
end start


Note in the code above that LastError$() is a MASM32 macro that automates the process, uses a fixed buffer, and preserves the registers and the flags.

    ; ----------------------------------------------------------------------
    ; A macro that encapsulates GetLastError() and FormatMessage() to return
    ; the system based error string for debugging API functions that return
    ; error information with the GetLastError() API call.
    ; ----------------------------------------------------------------------
      LastError$ MACRO
        IFNDEF @@_e_r_r_o_r_@@
          .data?
            @@_e_r_r_o_r_@@ db 1024 dup (?)
          .code
        ENDIF
        pushad
        pushfd
        invoke GetLastError
        mov edi,eax
        invoke FormatMessage,FORMAT_MESSAGE_FROM_SYSTEM,
                             NULL,edi,0,ADDR @@_e_r_r_o_r_@@,1024,NULL
        popfd
        popad
        EXITM <OFFSET @@_e_r_r_o_r_@@>
      ENDM

Well Microsoft, here's another nice mess you've gotten us into.

jasonabullard

Thanks guys!!  The str$ macro definitely worked.  I need to go through the macro file/documentation to see what features are available and see how each one works.

dedndave


Gunther

Hi Jason,

welcome to the forum.  :t

Gunther
You have to know the facts before you can distort them.

jasonabullard

Quote from: dedndave on November 25, 2012, 01:00:20 PM
masm32\help\hlhelp.chm

:t

Thanks!  Found all the help files the other day.  Haven't had a chance to go through them yet though.