Category : OS/2 Files
Archive   : RUNDLL.ZIP
Filename : CALLDLL3.C

 
Output of file : CALLDLL3.C contained in archive : RUNDLL.ZIP
/*
calldll3.c -- run-time dynamic linking from the command-line
requires MSC 5.1 CRTEXE.OBJ, uses proc2.obj or procaddr.dll
doesn't include "os.h"

to use proc2.obj:
cl -AL -c -Gs2 -Ox -W2 calldll3.c proc2.c
link /nod/noi crtexe.obj calldll3 proc2,calldll3.exe,,crtlib.lib os2.lib;

to use procaddr.dll (IMPLIB procaddr.lib):
cl -AL -c -Gs2 -Ox -W2 calldll3.c
link /nod/noi crtexe.obj calldll3,calldll3,,procaddr.lib crtlib.lib os2.lib;

to run:
calldll3 [args...] [%mask]
examples:
calldll3 VIOCALLS VIOWRTTTY "hello world" 5 0
calldll3 doscalls DosMkDir \foobar 0L
calldll3 doscalls DosRmDir \foobar 0L
calldll3 DOSCALLS DosBeep 2000 300
calldll3 DOSCALLS 50 2000 300 ; DosBeep
calldll3 CRTLIB _printf "goodbye world: %lu" 666L " [%d]"
calldll3 CRTLIB ACOS -1.0 %.15f
calldll3 CRTLIB SQRT -1.0 %f
calldll3 CRTLIB _toupper 'b' %c
calldll3 PROCADDR LOADMODULE PROCADDR %X
*/

#include
#include
#include

#include "local.h"
#include "proc2.h"

typedef enum { typ_string, typ_byte, typ_word, typ_long, typ_float } TYPE;

TYPE NEAR type(char *arg);
TYPE NEAR retval_type(char *s);

VOID fail(char *msg) { puts(msg); exit(1); }

/*
push() : see Cortesi, Programmer's Essential OS/2 Handbook, pp.136-137
*/
VOID NEAR PASCAL push() { }
extern WORD pop(void);

#define PUSH_ARG(arg) \
{ \
switch (type(arg)) \
{ \
case typ_string: push(arg); c += 2; break; \
case typ_byte: push(arg[1]); c += 1; break; \
case typ_word: push(atoi(arg)); c += 1; break; \
case typ_long: push(atol(arg)); c += 2; break; \
case typ_float: push(atof(arg)); c += 4; break; \
} \
}

#define SYNTAX_MSG \
"syntax: calldll3 [args...] [%mask]"

main(int argc, char *argv[])
{
FN f;
TYPE retval_typ = typ_word;
char *mask = "%u";
WORD module;
BOOL is_cdecl;
int i, c;

if (argc < 3)
fail(SYNTAX_MSG);

/* handle optional printf mask */
if (strchr(argv[argc-1], '%'))
retval_typ = retval_type(mask = argv[--argc]);

if ((module = loadmodule(argv[1])) == 0)
fail("can't load module");

/* pass ASCIIZ string or ordinal number */
f = getprocaddr(module, isdigit(argv[2][0]) ? atol(argv[2]) : argv[2]);
if (! f)
fail("can't get function");

is_cdecl = ! (strcmp(strupr(argv[1]), "CRTLIB"));

/* push in reverse order for cdecl */
if (is_cdecl)
{
for (i=argc-1, c=0; i>=3; i--)
PUSH_ARG(argv[i]);
}
else
{
for (i=3; i PUSH_ARG(argv[i]);
}

/* args are on the stack : call (*f)() and print retval */
switch (retval_typ)
{
case typ_string: printf(mask, ((STRFN) f)()); break;
case typ_byte: printf(mask, ((BYTEFN) f)()); break;
case typ_word: printf(mask, f()); break;
case typ_long: printf(mask, ((LONGFN) f)()); break;
case typ_float: printf(mask, ((FLOATFN) f)()); break;
}

if (is_cdecl)
for (i=0; i pop();

freemodule(module);
return 0;
}

/*
type() uses some dumb rules to determine the type of an argument:
if first character of arg is a digit or '-'
and if arg contains '.' then it's a floating-point number
else if last character is an 'L' then it's a long
else it's a unsigned word
else if first character is an apostrophe
it's a single-byte character
otherwise
it's a string
*/
TYPE NEAR type(char *arg)
{
if (isdigit(arg[0]) || (arg[0] == '-' && isdigit(arg[1])))
{
char *p = arg;
while (*p)
if (*p++ == '.')
return typ_float;
return (*--p == 'L') ? typ_long : typ_word;
}
else
return (arg[0] == '\'') ? typ_byte : typ_string;
}

/*
retval_type() uses a printf() mask (e.g., %s or %lX) to determine
type of return value
*/
TYPE NEAR retval_type(char *s)
{
while (*s)
{
switch (*s)
{
case 's' : return typ_string; break;
case 'c' : return typ_byte; break;
case 'p' : case 'l' : case 'I' : case 'O' : case 'U' :
return typ_long; break;
case 'e' : case 'E' : case 'f' : case 'g' : case 'G' :
return typ_float; break;
}
s++;
}

/* still here */
return typ_word;
}


  3 Responses to “Category : OS/2 Files
Archive   : RUNDLL.ZIP
Filename : CALLDLL3.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/