News:

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

ReadFile & WriteFile

Started by DerCoder, December 07, 2011, 06:22:54 PM

Previous topic - Next topic

DerCoder

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

dedndave

it is pretty much the same code - just using a little different syntax
we do not have a "DO" in MASM, though   :P

fearless

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

ƒearless

jj2007

Pure Masm:

include \masm32\MasmBasic\MasmBasic.inc   ; download
   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?

DerCoder

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';
}

Vortex

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