I'm haveing a bit of trouble with the ReadFile and CreateFile functions. It looks ok to me but it crashes where you enter in the filename you want. Here is the code:
.586 ; create 32 bit code
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
include test.inc ;includes for just about anything(taken from masm32.inc?)
.data
msgA db "Enter in a file name. ",0 ;Input file name message
msgB db "Enter in some text. ",0 ;File content message
msgC db "Your new file is... ",0 ;File confirmation message (not really needed)
.data?
fname word 4 dup (?) ;File name buffer
string word 10 dup (?) ;File content buffer
buf word 10 dup (?) ;is this even needed?
.code
start:
invoke StdOut, addr msgA ;Output filename message
invoke StdIn, addr fname, sizeof fname ;Input filename
invoke StdOut, addr msgB ;Output file content message
invoke StdIn, addr string, sizeof string ;input file contents
invoke CreateFile,fname,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL ;create a file(this is where it chokes up
invoke WriteFile,fname,string,buf,NULL,NULL ;write file content buffer to the file
invoke Sleep,1000 ;gives a chance for the user to read input/output
invoke ExitProcess,NULL ;exit process(not sure if i need this[some programs crash without this])
end start
any help would be appreciated.
You must be careful with the parameters of CreateFile and WriteFile. Plus, CloseHandle is missing in your source code.
Here is a working sample :
.386
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
TEXT_LEN = 27
.data
text db 'This is a simple text file.'
filename db 'text.txt',0
.data?
hFile dd ?
_size dd ?
.code
start:
invoke CreateFile,ADDR filename,GENERIC_WRITE,\
0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,0
mov hFile,eax
invoke WriteFile,eax,ADDR text,TEXT_LEN,ADDR _size,0
invoke CloseHandle,hFile
invoke ExitProcess,0
END start
This example creates a file named text.txt
The content is the string labelled text specified in the data section.
Ok thanks it works, but how do you have the user input the filename and the contents?
QuoteStdIn
StdIn proc lpszBuffer:DWORD,bLen:DWORD
Description
StdIn receives text input from the console and places it in the buffer required as a parameter. The function terminates when Enter is pressed.
Parameters
1. lpszBuffer The buffer to receive the text input from the console.
2. bLen The length of the buffer.
Return Value
There is no return value.
Comments
The console determines the length of the maximum buffer size. 128 bytes should handle most console input needs. The position of the input on the console can be set with the locate function.
Quote.data?
fname word 4 dup (?) ;File name buffer
string word 10 dup (?) ;File content buffer
buf word 10 dup (?) ;is this even needed?
As a start, you are allocating only 8 bytes (4 words) as the buffer to store the input file name. Since you are later specifying that size when calling StdIn, that proc will only store the first 8 characters entered by the user.
Even if you would specify a large enough size for the entire file name when calling StdIn, you would then overwrite part of it when calling StdIn for the text which gets stored in the "string" buffer.
#1: Always allow enough memory for the expected input
Secondly, you reserve double bytes (i.e. words) for a text buffer only when you want the Unicode character set. Otherwise, you reserve bytes for the ANSI character set.