News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Number and type of arguments required for call to C library

Started by jj2007, May 21, 2014, 10:21:19 PM

Previous topic - Next topic

jj2007

I have a C library that is badly documented. With PEview, I can see the exports, but not the number (and type) of arguments. So I googled a bit, and it seems consensus is "you'll have to disassemble it".

The odd thing is that my linker knows exactly the type and number of arguments - judging from the error messages.

Example:

UnzipFile LABEL NEAR
call UnzipFile
Gets assembled & linked, so the linker recognises the existence of UnzipFile

UnzipFile PROTO
call UnzipFile
Linker error unresolved external symbol '_UnzipFile@0'

UnzipFile PROTO :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
invoke UnzipFile, 1, 2, 3, 4, 5
Linker error unresolved external symbol '_UnzipFile@20'

So how does the linker recognise that definitions in the assembler source don't match those in the library? And can we get the info from the library?

qWord

MREAL macros - when you need floating point arithmetic while assembling!

jj2007

Quote from: qWord on May 21, 2014, 11:04:52 PM
C calling convention? "UnzipFile PROTO C ..."

That makes the _ and @nn disappear, but the linker still does not recognise it... I tried 4 and 6 args, too, no success.

The source is Pascal (from here), and calls it like this:
      rc := unzipfile ( thename, buf, r.headeroffset, 0,
      {$ifdef Windows}vk_escape{$else}27{$endif} ); {Escape interrupts}
      IF rc = unzip_ok THEN
        writeln ( 'Ok' )

Example:
FUNCTION UnzipFile conv arg_stdcall
         ( in_name : pchar;out_name : pchar;offset : longint;hFileAction : word;cm_index : integer ) : integer;
{$ENDIF}
{usage:
in_name:      name of zip file with full path
out_name:     desired name for out file
offset:       header position of desired file in zipfile
hFileAction:  handle to dialog box showing advance of decompression (optional)
cm_index:     notification code sent in a wm_command message to the dialog
               to update percent-bar
Return value: one of the above unzip_xxx codes

I can get this to assemble & link & run:
   CloseZipFile PROTO SYSCALL :DWORD
   invoke CloseZipFile, 1

... but only for Polink. MS Link complains with fatal error LNK1115: /MACHINE option required, in spite of the fact that I do supply /MACHINE:X86

If I change that to :X86J, MS Link suddenly acknowledges that a /MACHINE option was indeed specified, and throws

LINKV9 : warning LNK4012: invalid value 'X86J', must be 'ARM, EBC, IA64, MIPS, MIPS16, MIPSFPU, MIPSFPU16, SH4, THUMB, X64, or X86'; option ignored
LINKV9 : fatal error LNK1115: /MACHINE option required

Which looks really stupid (greetings to Richmond).

SYSCALL seems to work, though:include \masm32\include\masm32rt.inc
includelib unzipw.lib
.code
start:
mov ebx, esp
sub ebx, esp
CloseZipFile PROTO SYSCALL :DWORD
; int 3
push 0
invoke CloseZipFile, esp
pop ecx
print str$(eax), " retval", 13, 10
print str$(ebx), " stack difference"
exit
end start

nidud

deleted

qWord

Seems like that something is wrong with import library - I would simple build a new one using polib...
MREAL macros - when you need floating point arithmetic while assembling!

dedndave

have a look at msvcrt.inc....

    c_msvcrt typedef PROTO C :VARARG

    externdef _imp__printf:PTR c_msvcrt
    crt_printf equ <_imp__printf>

jj2007

Quote from: nidud on May 22, 2014, 12:03:42 AM
UnzipFile PROTO PASCAL :DWORD, :DWORD, :DWORD, :DWORD, :DWORD

No success...

Quote from: dedndave on May 22, 2014, 02:08:46 AM
have a look at msvcrt.inc....

That's all VARARG and C, while the unzip functions are apparently stdcall and not C.
I found two workarounds - SYSCALL with polink is the only solution that works:

includelib LiteUnZip.lib

UnzipOpenFileA PROTO SYSCALL :DWORD, :DWORD, :DWORD

.code
LiteUnzip proc filename
LOCAL hLite
  mov esi, esp
  if 1
   push 0      ; works fine
   push filename
   lea eax, hLite
   push eax
   call UnzipOpenFileA
  else
   invoke UnzipOpenFileA, addr hLite, filename, 0   ; works fine, too
   sub esp, 3*4      ; stack needs "negative balancing" here!
  endif
  sub esi, esp
  deb 4, "Result & stack difference", eax, hLite, esi
  ret
LiteUnzip endp


@qWord: Thanks, but this lib is indeed built with polib...

dedndave

i see a couple possibilities

1) have a look at Erol's Dll2Inc readme files and examples
    i tried that, and it creates an import library and an INC   :t

2) doubtful, but COM interface ?

Vortex

Hi Jochen,

Analyzing the import library :

\masm32\bin\dumpbin.exe /EXPORTS unzipw.lib

ChfUnzip_Init
CloseZipFile
FileUnzip
FileUnzipEx
GetFirstInZip
GetNextInZip
GetSupportedMethods
GetUnzipDllVersion
IsZip
SetNoRecurseDirs
SetUnzipQuestionProc
SetUnzipReportProc
UnzipFile
UnzipSize
ViewZip


No any decoration information. My solution is to use a custom invoke macro not checking the number of parameters :


include     \masm32\include\masm32rt.inc
include     invoke.inc

includelib  unzipw.lib

ChfUnzip_Init   PROTO SYSCALL
CloseZipFile    PROTO SYSCALL
FileUnzip       PROTO SYSCALL
FileUnzipEx     PROTO SYSCALL
GetFirstInZip   PROTO SYSCALL
GetNextInZip    PROTO SYSCALL
GetSupportedMethods  PROTO SYSCALL
GetUnzipDllVersion   PROTO SYSCALL
IsZip                PROTO SYSCALL
SetNoRecurseDirs     PROTO SYSCALL
SetUnzipQuestionProc PROTO SYSCALL
SetUnzipReportProc   PROTO SYSCALL
UnzipFile            PROTO SYSCALL
UnzipSize            PROTO SYSCALL
ViewZip              PROTO SYSCALL

.data

test1       db 'test',0

.data?

.code

start:

    invoke  ExitProcess,0

    _invoke  SetUnzipQuestionProc,1,2,3
    _invoke  SetUnzipReportProc,1,ADDR test1,ADDR test1,4
    _invoke  FileUnzip
    _invoke  IsZip,1

END start


As I don't know the prototypes of the zip functions, I wrote some dummy function calls above.

Gunther

Jochen, Erol,

Quote from: Vortex on May 22, 2014, 04:22:46 AM
As I don't know the prototypes of the zip functions, I wrote some dummy function calls above.

That's quite a fumbling. What about building it again?

Gunther
You have to know the facts before you can distort them.

Vortex

Hi Jochen,

Reading the document in :

http://sources.ru/pascal/archives/unziptmt.htm

Here is my attempt to create a .def and .lib file :

UnZipDll.def :

LIBRARY UnZipDll
EXPORTS
"_FileUnzip@20"
"_FileUnzipEx@12"
"_ViewZip@12"
"_SetUnZipReportProc@4"
"_SetUnZipQuestionProc@4"
"_UnzipSize@8"
"_ChfUnzip_Init@0"
"_SetNoRecurseDirs@4"
"_UnzipFile@20"
"_GetFirstInZip@8"
"_GetNextInZip@4"
"_IsZip@4"
"_CloseZipFile@4"
"_GetSupportedMethods@0"


\masm32\bin\polib /OUT:UnZipDll.lib /DEF:UnZipDll.def /MACHINE:x86

Could you try this one?

Vortex

Hi Jochen,

Checking this project :

http://www.codeproject.com/Articles/13370/LiteZip-and-LiteUnzip

Here is my include file :

; include file generated by lib2inc V2.2

UnzipClose PROTO :DWORD
UnzipFindItemA PROTO :DWORD,:DWORD,:DWORD
UnzipFindItem equ <UnzipFindItemA>

UnzipFindItemW PROTO :DWORD,:DWORD,:DWORD
UnzipFormatMessageA PROTO :DWORD,:DWORD,:DWORD
UnzipFormatMessage equ <UnzipFormatMessageA>

UnzipFormatMessageW PROTO :DWORD,:DWORD,:DWORD
UnzipGetItemA PROTO :DWORD,:DWORD
UnzipGetItem equ <UnzipGetItemA>

UnzipGetItemW PROTO :DWORD,:DWORD
UnzipItemToBuffer PROTO :DWORD,:DWORD,:DWORD,:DWORD
UnzipItemToFileA PROTO :DWORD,:DWORD,:DWORD
UnzipItemToFile equ <UnzipItemToFileA>

UnzipItemToFileW PROTO :DWORD,:DWORD,:DWORD
UnzipItemToHandle PROTO :DWORD,:DWORD,:DWORD
UnzipOpenBuffer PROTO :DWORD,:DWORD,:DWORD,:DWORD
UnzipOpenBufferRaw PROTO :DWORD,:DWORD,:DWORD,:DWORD
UnzipOpenFileA PROTO :DWORD,:DWORD,:DWORD
UnzipOpenFile equ <UnzipOpenFileA>

UnzipOpenFileRawA PROTO :DWORD,:DWORD,:DWORD
UnzipOpenFileRaw equ <UnzipOpenFileRawA>

UnzipOpenFileRawW PROTO :DWORD,:DWORD,:DWORD
UnzipOpenFileW PROTO :DWORD,:DWORD,:DWORD
UnzipOpenHandle PROTO :DWORD,:DWORD,:DWORD
UnzipOpenHandleRaw PROTO :DWORD,:DWORD,:DWORD
UnzipSetBaseDirA PROTO :DWORD,:DWORD
UnzipSetBaseDir equ <UnzipSetBaseDirA>

UnzipSetBaseDirW PROTO :DWORD,:DWORD

dedndave

i don't think that last one jives, Erol
different library, perhaps ?

the one Jochen is working with is (C) fPrint UK Ltd, 1998
is that info-zip, Jochen ????

Vortex

Hi Dave,

If I am not wrong, UnzipOpenFileA is a member of the LiteUnzip library.

jj2007

Thanks a lot, Erol and Dave :icon14:

It is actually Jeff Glatt's LiteZip library:
QuoteThis project is largely based upon work by Lucian Wischik, who in turn based his work on gzip 1.1.4, zlib, and info-zip which are by Jean-Loup Gailly and Mark Adler. Lucian's code has been reworked to be written in plain C, using only the Win32 API, and packaged into 2 DLLs. (Also some improvements to error-checking, some added functionality, and code-reduction/stream-lining was accomplished.)

With your help I found a way:

-   \masm32\bin\dll2inc liteunzip.dll
-   edit LiteUnZip.inc: delete all leading underscores (dll2inc has no options?)
-   \masm32\bin\polib /OUT:LiteUnzip.lib /DEF:LiteUnZip.def /MACHINE:x86 /NOUND

Works like a charm :t