News:

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

First post

Started by Derry, August 19, 2005, 08:06:05 PM

Previous topic - Next topic

Derry

Hi,

For some inexplicable reason, I've decided to learn Win32 assembly language - MASM. At the moment I'm working my way through Icezelion's tutorials and reading various posts to the forum.
Playing with file i/o I have 4 buttons on a dialog box, a checkbox, an edit box and a static.
Button 1 sets the check box
Button 2 clears the checkbox
Button 3 writes 'checked' or 'unchecked' to a file along with carriage returns/linefeeds

so the file may now contain for example:

Checked
Unchecked
Unchecked
Checked
etc

see code below:

.elseif eax==IDC_BTN1
invoke SendDlgItemMessage,hWin,IDC_CHK1,BM_SETCHECK,1,0

.elseif eax==IDC_BTN2
invoke SendDlgItemMessage,hWin,IDC_CHK1,BM_SETCHECK,0,0   
   
.elseif eax==IDC_BTN3         
         
invoke IsDlgButtonChecked,hWin,IDC_CHK1   
         
mov ChkState,eax
         
.if ChkState==BST_CHECKED
            
invoke   CreateFile,addr p2FileName,GENERIC_WRITE,NULL,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,NULL
            
mov   hFile, eax   
            
invoke SetFilePointer,hFile,0,0,FILE_END
            
invoke WriteFile,hFile,addr IsItChecked,LENGTHOF IsItChecked,addr pwritten,NULL
                        
invoke CloseHandle,hFile
         
         
.elseif ChkState==BST_UNCHECKED
                           
invoke   CreateFile,addr p2FileName,GENERIC_WRITE,NULL,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,NULL
            
mov   hFile, eax   
            
invoke SetFilePointer,hFile,0,0,FILE_END
            
invoke WriteFile,hFile,addr IsItNotChecked,LENGTHOF IsItNotChecked,addr pwritten,NULL
                        
invoke CloseHandle,hFile
               
.endif

Let's say I want to read the first line from the file into the edit box and/or static control

The third parameter of readfile is confusing me, how do I specify the number of bytes to read?

BOOL ReadFile(

    HANDLE hFile,   // handle of file to read
    LPVOID lpBuffer,   // address of buffer that receives data 
    DWORD nNumberOfBytesToRead,   // number of bytes to read
    LPDWORD lpNumberOfBytesRead,   // address of number of bytes read
    LPOVERLAPPED lpOverlapped    // address of structure for data
   );



I've tried this piece of code which I know is rubbish

.elseif eax==IDC_BTN4
      
invoke CreateFile,ADDR GetFile,GENERIC_READ,NULL,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL
mov hGetFile,eax
invoke SetFilePointer,hGetFile,0,0,FILE_BEGIN
invoke ReadFile,hGetFile,pMem,hMem,SizeRW,NULL
invoke SendDlgItemMessage,hWin,IDC_EDT1,ADDR pMem,0,0
         
invoke CloseHandle,hGetFile

How would I read say the read first line into the static control?

I took the code below from a post, it loops through a variable until NULL and writes the string out to a messagebox.

.data
SomeString db 'zebra stripes',0

.code
begin:

mov ecx, offset SomeString

@@:
inc ecx
mov dl, byte ptr [ecx]
test dl,dl
jnz @B

invoke MessageBox,0,ADDR SomeString,0,MB_OK

end begin


I assume this may be a possible solution but needing to specify the number of bytes to read from the file has me stumped. Apologies for being so long-winded

Any help gratefully received and thanks in advance

Derry

anon

What I usually do is use GetFileSize and use the results for nNumberOfBytesToRead (the third parameter)
that way you will be able to read the entire file. You can of course use a smaller number if you know how
many bytes you want to read.

Derry

Thanks Anon,

I have looked at filesize now and think i understand how I can read an entite file, but what do I do if I only want to read a line of text into a static control when I don't know the size of that line?
Sorry if I was not clear with the first post

Derry

jojo

For getting the first string only, you need something like this:

   invoke ReadFile, hFile, BufStart, dwFileSize, ADDR dwBytesRead, 0
   mov   bSuccess,eax
   invoke   CloseHandle, hFile
   mov   ecx,dwBytesRead
   mov   edi,BufStart

; edi will point to CRLF-terminated strings. We scan for the CRLF.
   dec   edi   ;edi=BufStart-1, for compensation of first inc after Get_CR

Get_Next:
   mov   edx,ecx   ;ACD free - edx is our counter
   mov   eax,2573   ;CrLF=13,10
Get_CR:
   inc   edi
   dec   ecx
   jle   CrFound
   cmp   word ptr[edi],ax
   jne   Get_CR
CrFound:
   sub   edx,ecx   ;len of string

... now here you need to copy the edx bytes into a buffer, then add a zero byte, and pass the address of the buffer to the edit control

Mark Jones

Jojo, should you preserve EDI?

Hi Derry, try searching above in the little search box. Just the other day someone else was asking the same thing and there were a couple more interesting methods posted. :)
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

jojo

Quote from: Mark Jones on August 20, 2005, 12:46:50 PM
Jojo, should you preserve EDI?

Yes indeed. In my actual code, I use

MyProc   proc...
   pushad         ;save all registers
   ...
   popad         ;restore all registers
   mov   eax,whatever
   ret
pushad+popad is lazy but pretty safe :toothy

Vortex

Hi Derry,

Welcome to the forum :U