Hello,
I'm building a simple DLL to check the size of a file, but i'm getting some errors, see my code:
.386
option casemap :none ; case sensitive
include \masm32\include\masm32rt.inc
.data
FileName db "\masm32\include\windows.inc", 0
QPrompt db "Enter The File: ", 24h
SizeMess db "File Size = ", 24h
CrLf db 0Dh, 0Ah, 24h
Buffer db 127, 0, 128 dup(0)
.code
LibMain proc instance:dword,reason:dword,unused:dword
mov eax,1
call FileOperation
inkey
exit
ret
LibMain endp
FileInput proc
;set the DS register
mov ax, @data ;data segment
mov ds, ax
;display the prompt message
mov dx, offset QPrompt
mov ah, 9
int 21h
;read buffered input
mov dx, offset Buffer
mov ah, 0Ah
int 21h
;display a carriage return/line feed
mov dx, offset CrLf
mov ah, 9
int 21h
;terminate the input string
mov bh, 0
mov bl, Buffer + 1
mov byte ptr Buffer[bx + 2], 24h
;display their input
mov dx, offset Buffer + 2
mov ah, 9
int 21h
ret
FileInput endp
FileOperation proc
local bytecount :DWORD
.if rv(exist, addr FileName) != 0
mov bytecount, rv(filesize, addr Buffer)
print str$(bytecount), " Bytes", 10
.else
call FileNotFound
.endif
ret
FileOperation endp
FileNotFound proc
print "Sorry, file cannot be found.", 10
ret
FileNotFound endp
End LibMain
And here is the compiler log:
D:\Masm32\Bin\ML /c /coff /Cp /nologo /I"D:\Masm32\Include" "D:\File Size\filesize.asm"
Assembling: D:\File Size\filesize.asm
D:\File Size\filesize.asm(26) : error A2022: instruction operands must be the same size
D:\File Size\filesize.asm(31) : error A2022: instruction operands must be the same size
D:\File Size\filesize.asm(36) : error A2022: instruction operands must be the same size
D:\File Size\filesize.asm(46) : error A2022: instruction operands must be the same size
D:\File Size\filesize.asm(22) : error A2004: symbol type conflict
D:\Masm32\Bin\Link @"D:\File Size\link.war"
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
/SUBSYSTEM:WINDOWS /RELEASE /VERSION:4.0 "/LIBPATH:D:\Masm32\Lib" /DLL "D:\File Size\filesize.obj" "/OUT:D:\File Size\filesize.dll"
LINK : fatal error LNK1181: cannot open input file "D:\File Size\filesize.obj"
Make finished. 6 error(s) occured.
Best Regards,
Nathan Paulino Campos
Hi Nathan,
You cannot use interrupts in the Win32 environment.
In another thread I have explained you that it is not a very good idea to use LibMain (DLL entry point) in order to perform any operations other than initializations needed for the DLL itself. But apparently you choose to ignore that advice.
In addition to that now you are trying to mix old and obsolete DOS 16 bits code with a Windows 32bit DLL. Not a very "bright" idea either.
Since you insist in not learning...
I do "suggest" that you make up your mind and choose between:
1) go for old DOS like 16bits code
2) learn how to use the new 32bits Windows API.
Then, how i can do this using 32 Bits?
Hi Nathan,
To get the size of a file, you have to use the following APIs :
- CreateFile to open the file
- GetFileSize
- Finally, CloseHandle to close the handle returned by CreateFile.
Ok, but the thing is how i can do a input character using Windows API?
Regards.
An easy method is to use the StdIn function from masm32.lib
From the Masm32 Library Reference :
QuoteStdIn 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.
Thanks Vortex, but you can post a link or something like a example of use?
Thanks.
Someone can help me?
Hi nathanpc,
Show some efforts to write a simple example with StdIn and we will help you. It's impossible to learn a programming language without practicing writing code on your computer.
The function takes two parameters. The first, a pointer to a buffer and the second the size of this buffer. Your code should be like the following :
BUFFER_SIZE equ 100
.
.
invoke StdIn,ADDR buffer,BUFFER_SIZE
.
.
Hello Vortex,
I don't know if i'm putting all in the correct place, but i'm getting some errors when i try to compile it, see my code now:
.386
option casemap :none ; case sensitive
include \masm32\include\masm32rt.inc
.data
FileName db "\masm32\include\windows.inc", 0
SizeMess db "File Size = ", 0
Msg db "File> ", 0
.code
LibMain proc instance:dword,reason:dword,unused:dword
local InputBuffer[128]:byte
invoke StdOut, eax
mov eax, 1
call FileOperation
inkey
exit
ret
LibMain endp
FileInput proc
BUFFER_SIZE equ 100
invoke StdIn,ADDR buffer,BUFFER_SIZE
ret
FileInput endp
FileOperation proc
local bytecount :DWORD
.if rv(exist, addr FileName) != 0
print Msg
mov BUFFER_SIZE, rv(filesize, addr BUFFER_SIZE)
print str$(BUFFER_SIZE), " Bytes", 10
.else
call FileNotFound
.endif
ret
FileOperation endp
FileNotFound proc
print "Sorry, file cannot be found.", 10
ret
FileNotFound endp
End LibMain
And the compiler log:
D:\Masm32\Bin\ML /c /coff /Cp /nologo /I"D:\Masm32\Include" "D:\File Size\filesize.asm"
Assembling: D:\File Size\filesize.asm
D:\File Size\filesize.asm(23) : error A2006: undefined symbol : buffer
D:\File Size\filesize.asm(23) : error A2114: INVOKE argument type mismatch : argument : 1
D:\File Size\filesize.asm(31) : error A2033: invalid INVOKE argument : 1
rv(5): Macro Called From
D:\File Size\filesize.asm(31): Main Line Code
D:\File Size\filesize.asm(31) : error A2114: INVOKE argument type mismatch : argument : 1
rv(5): Macro Called From
D:\File Size\filesize.asm(31): Main Line Code
D:\File Size\filesize.asm(31) : error A2001: immediate operand not allowed
D:\Masm32\Bin\Link @"D:\File Size\link.war"
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
/SUBSYSTEM:WINDOWS /RELEASE /VERSION:4.0 "/LIBPATH:D:\Masm32\Lib" /DLL "D:\File Size\filesize.obj" "/OUT:D:\File Size\filesize.dll"
LINK : fatal error LNK1181: cannot open input file "D:\File Size\filesize.obj"
Make finished. 8 error(s) occured.
This method of learning is very nice, because i really learn. Thanks Vortex
Best Regards,
Nathan Paulino Campos
Hi Nathan,
For the moment, try to work on simple projects. After making some practices, you can create a DLL to get the size of a file.
Please run the example under a debugger like Ollydbg to understand some concepts and please refer to the MSDN or Win32 Programmer's Reference ( API reference ) to study the APIs.
Here is an example :
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\masm32.lib
BUFFER_SIZE equ 100
.data
szWelcome db 'Please type the file name :',13,10,0
format1 db 13,10,'The size of the file = %u bytes',0
.data?
hFile dd ?
buffer db BUFFER_SIZE dup(?)
buffer2 db BUFFER_SIZE dup(?)
.code
start:
invoke StdOut,ADDR szWelcome
invoke StdIn,ADDR buffer,BUFFER_SIZE
; A string returned by StdIn is terminated by the CR+LF,0 byte sequence : 13,10,0
; Replace the CR byte - ASCII 13 with 0
mov BYTE PTR [buffer+eax-2],0
invoke CreateFile,ADDR buffer,GENERIC_READ,0,0,\
OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0
; If CreateFile fails terminate silently the application
cmp eax,INVALID_HANDLE_VALUE
je finish
mov hFile,eax
invoke GetFileSize,eax,0
invoke wsprintf,ADDR buffer2,ADDR format1,eax
invoke StdOut,ADDR buffer2
invoke CloseHandle,hFile
finish:
invoke ExitProcess,0
END start
Now, you should try to improve the code above. For example you can make a better application by adding more error checking. Later, another attempt should be to create your own StdIn function.
Thanks very much Vortex!
Now i'm studing your code and reading things in MSDN and about the APIs.