The MASM Forum Archive 2004 to 2012

General Forums => The Workshop => Topic started by: DerCoder on December 07, 2011, 06:22:54 PM

Title: ReadFile & WriteFile
Post by: DerCoder on December 07, 2011, 06:22:54 PM
Hey guyz,

I'd like to write the content of one file into another one. In C++ it would look like this:
do
{
ReadFile(hReadFrom, (void*) szReadBuffer, sizeof(szReadBuffer), &dwBytesRead, NULL);
WriteFile(hWriteTo, (void*) szReadBuffer, dwBytesRead, &dwBytesWritten, NULL);
dwTotallyWritten += dwBytesRead;
} while (dwBytesRead != 0);


That snippet of code writes part by part into the new file.

Now, I want to do this in Assembler (MASM32), but I really don't have any idea, how to do this.
When I initialize a "variable" in .DATA-segment
szBuffer DB 65536 dup (0)
the file gets +64k filesize >_<

It would be very nice, if someone could help me out. I'm out of ideas :(

Big thanks, DerCoder
Title: Re: ReadFile & WriteFile
Post by: dedndave on December 07, 2011, 06:41:21 PM
it is pretty much the same code - just using a little different syntax
we do not have a "DO" in MASM, though   :P
Title: Re: ReadFile & WriteFile
Post by: fearless on December 07, 2011, 06:46:12 PM
you could create a variable in .DATA? which isnt allocated as space in the obj/lib (or dll/exe), the space for that var is then created at run time. You can then use RtlZeroMemory to fill it with 0s to make sure its all empty and ready for use.



.DATA
BytesRead dd 0
BytesWritten dd 0

.DATA?
szReadBuffer db 65535 dup (?)
hReadFrom dd ?
hWriteTo dd ?


.CODE
;
;some code later
;

; open files for reading from and writing to - do some error checking of course ;)
Invoke CreateFile ......
.IF eax != INVALID_HANDLE_VALUE
   mov hReadFrom, eax
.ELSE
   ; some error occurred, so handle it, display message to user or whatever
   ret
.ENDIF

Invoke CreateFile .....
.IF eax != INVALID_HANDLE_VALUE
   mov hWriteTo, eax
.ELSE
   ; some error occurred, so handle it, display message to user or whatever
   ret
.ENDIF


; clear buffer, if in a loop, perhaps add this after the write operation and any other processing, if a one time thing, then just clear it before use.
Invoke RtlZeroMemory, Addr szReadBuffer, SIZEOF szReadBuffer

; Start the read/write operation in some sort of loop - perhaps a .WHILE .ENDW loop or whatever suits
Invoke ReadFile, hReadFrom, Addr szReadBuffer, SIZEOF szReadBuffer, Addr BytesRead, NULL
Invoke WriteFile, hWriteTo, Addr szReadBufer, BytesRead, Addr BytesWritten, NULL

Title: Re: ReadFile & WriteFile
Post by: jj2007 on December 07, 2011, 06:58:05 PM
Pure Masm:

include \masm32\MasmBasic\MasmBasic.inc   ; download (http://www.masm32.com/board/index.php?topic=12460)
   Init
   FileWrite "OutFile.txt", Cat$("Start_"+FileRead$("WriteFile.asm")+"_end")
   Inkey Str$("%i bytes written", LastFileSize+10)
   Exit
end start

Why are you so worried about file size?
Title: Re: ReadFile & WriteFile
Post by: DerCoder on December 07, 2011, 07:53:10 PM
Big thanks fearless :) This made my evening lol :D

Well... It's out of topic and I hope no one minds, but can u tell me, how to run through the buffer and do sth like this:
for (int a = 0; a < dwBytesRead; a++)
{
    szBuffer[a] = szBuffer[a] ^ 'x';
}
Title: Re: ReadFile & WriteFile
Post by: Vortex on December 07, 2011, 08:06:39 PM
Hi DerCoder,

Here is a quick example for you. You can consider allocating dynamic memory.


include copyfile.inc

.data

msg1 db 'copyfile srcfile.ext destfile.ext',13,10,0

.code

main PROC C uses esi edi ebx argc:DWORD,argv:DWORD

LOCAL pMem:DWORD
LOCAL NumOfBytesRead:DWORD
LOCAL NumOfBytesWritten:DWORD
LOCAL hRead:DWORD
LOCAL hWrite:DWORD

    cmp     argc,1+2
    je      @f
    invoke  StdOut,ADDR msg1
    ret
@@:
    invoke  VirtualAlloc,0,64*1024,\
            MEM_COMMIT,PAGE_EXECUTE_READWRITE

    mov     pMem,eax

    mov     esi,argv
    lea     edi,NumOfBytesRead
    xor     ebx,ebx

    invoke  CreateFile,DWORD PTR [esi+4],GENERIC_READ,0,0,\
            OPEN_EXISTING,0,0
    mov     hRead,eax   

    invoke  CreateFile,DWORD PTR [esi+8],GENERIC_WRITE,0,0,\
            CREATE_ALWAYS,0,0
    mov     hWrite,eax

@@:
    invoke  ReadFile,hRead,pMem,64*1024,edi,0
    mov     esi,DWORD PTR [edi]
    invoke  WriteFile,hWrite,pMem,esi,ADDR NumOfBytesWritten,0
    add     ebx,esi
    test    esi,esi
    jnz     @b

    invoke  VirtualFree,pMem,0,MEM_RELEASE
    ret

main ENDP

END