so I'm trying to learn assembly language using masm and doing some practice coding and im wondering what's wrong with my code
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
.DATA
FileNameFrom db "file1.txt",0
FileNameTo db "file2.txt", 0
.DATA?
hFile HANDLE ?
hFile2 HANDLE ?
BWritten db ?
hMemory HANDLE ?
pMemory DWORD ?
SizeReadWrite DWORD ?
newfiletext dd ?
.CONST
MEMSIZE equ 65535
.CODE
start:
;-------; CREATE/OPEN
push NULL
push FILE_ATTRIBUTE_NORMAL
push OPEN_EXISTING
push NULL
push 0
push GENERIC_READ
push offset FileNameFrom
call CreateFile
;-------;
;or ~ invoke CreateFile,addr FileName,GENERIC_READ,0, NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL
mov hFile, eax
invoke GlobalAlloc, GMEM_MOVEABLE OR GMEM_ZEROINIT, MEMSIZE
mov hMemory, eax
invoke GlobalLock, hMemory
mov pMemory, eax
;-------; READ
push NULL
push offset SizeReadWrite
push MEMSIZE-1
push pMemory
push hFile
call ReadFile
;-------;;;or ~ invoke ReadFile,hFile,pMemory, MEMSIZE-1,ADDR SizeReadWrite,NULL
push NULL
push hFile
call GetFileSize
mov newfiletext, eax
invoke CloseHandle, hFile
; WRITE
push NULL
push FILE_ATTRIBUTE_NORMAL
push CREATE_ALWAYS
push NULL
push 0
push GENERIC_ALL
push offset FileNameTo
call CreateFile
mov hFile, eax
push 0
push offset BWritten
push newfiletext
push offset pMemory
push hFile
call WriteFile
invoke GlobalUnlock, pMemory
invoke GlobalFree, hMemory
invoke CloseHandle, hFile
end start
What im trying to do is open an existing file (file1) then read the contents, create another file(file2) then copy the text from file1 to file2. I'm able to create file2.txt but when i open it, it's blank.
There's an error in your call to WriteFile
:
push offset pMemory <-- The offset operator shouldn't be used here
push hFile
call WriteFile
Also, don't use GENERIC_ALL
. Use the least amount of access rights you need, e.g. GENERIC_WRITE
or GENERIC_READ OR GENERIC_WRITE
. When using GENERIC_ALL
you may be asking for access that the current user doesn't have permission for.
Let's add some error checking to your code:
include \masm32\include\msvcrt.inc
includelib \masm32\lib\msvcrt.lib
...
szErrMsg db "GetLastError: %x",13,10,0
...
push GENERIC_ALL
push offset FileNameTo
call CreateFileA
mov hFile, eax
cmp eax,INVALID_HANDLE_VALUE
jne open_ok
invoke GetLastError
invoke crt_printf,addr szErrMsg,eax
open_ok:
Now running the program gives us the output GetLastError: 5
in the console. Googling for "getlasterror codes" yields this page, where we find that 5
means ERROR_ACCESS_DENIED
.