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
it is pretty much the same code - just using a little different syntax
we do not have a "DO" in MASM, though :P
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
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?
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';
}
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