Error When Using Input Character In a DLL

Started by nathanpc, October 03, 2009, 05:41:41 PM

Previous topic - Next topic

nathanpc

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

Vortex

Hi Nathan,

You cannot use interrupts in the Win32 environment.

BogdanOntanu

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.

Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

nathanpc


Vortex

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.

nathanpc

Ok, but the thing is how i can do a input character using Windows API?

Regards.

Vortex

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.

nathanpc

Thanks Vortex, but you can post a link or something like a example of use?

Thanks.


Vortex

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
.
.

nathanpc

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

Vortex

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.

nathanpc

#12
Thanks very much Vortex!
Now i'm studing your code and reading things in MSDN and about the APIs.