char *enumproc(char *dll, char *buf, unsigned *ord); enumproc() is a C function that, given the full pathname of an OS/2 dynamic-link library, will return the names of all the procedures exported by the DLL, in ASCIIZ (zero-delimited string) form. The Microsoft utility EXEHDR will of course list these procedures, but there are several problems with using EXEHDR: (1) it lists out a lot of other information as well; (2) using it under program control requires setting up a pipe; (3) using it under program control requires locating it on the disk; and (4) EXEHDR does not reside on every machine. enumproc() does not use EXEHDR. In fact, it turns out that it is very easy to retrieve the entry points within a DLL. Once one finds the offset of the entry table in the new executable header, the functions are stored in an array of structures like so: struct func_export { unsigned char length; char func_name[length]; /* warning! not C! */ unsigned short ord_num; } ; Since most DLLs export more than one function, the only tricky thing about using enumproc() is getting back more than one function name. Since C, unlike more advanced programming languages like Lisp and Icon, does not have multiple return values from a function, enumproc() resorts to the same gimick as the C standard library function strtok(): the first call to enumproc() passes in a string, and subequent calls to enumproc() pass in NULL. The file TEST.C gives this example: if (enumproc(filename, buf, &ord)) { /* first entry is just module name, ordinal number zero */ printf("Module: %s\n", buf); while (enumproc(0, buf, &ord)) printf("%s (#%u)\n", buf, ord); } As long as there are procedures to enumerate in the file, each call to enumproc() will cause the second and third parameters to be updated with the function name and its ordinal number, and the invocation will return a pointer to the function name. This means that enumproc() must maintain an open file handle between invocations. When enumproc() has enumerated all the procedures in the DLL, it will automatically close the file and return FALSE. If you wish to stop running enumproc() on a DLL before all the function names have been exhausted, just pass in (char *)-1. This will tell enumproc() to close the open file handle. The test module itself contains one interesting feature: if the test program ENUMPROC.EXE is run with a module name rather than with a full filename (e.g. C>enumproc viocalls rather than C>enumproc c:\dll\viocalls.dll) the test program will attempt to convert the module name into the full filename, using DOSGETMODHANDLE() and DOSGETMODNAME(). In the cases where the module has already been loaded into memory, this eliminates the necessity of checking LIBPATH. enumproc() was suggested by Noel J. Bergman. I hope you find it useful. Please direct any comments or criticisms to the author who remains, as ever, your humble servant, Andrew Schulman 32 Andrews St. #2 Cambridge MA 02139 (617) 876-2102 28 May 1988 ====================================================================== revised 10 June 1988: In the course of incorporating the enumproc feature into OS2XLISP, I found some bugs in enumproc.c related to opening and closing the file, and these have been fixed. I have been asked why enumproc() uses the infamous goto statement. There are three reasons: (1) to be perverse; (2) more seriously, because exception-handling often disrupts the flow of reading source code, and goto is a nice way to shunt exception-handling off to the side (not as nice a way as BASIC's ON ERROR) ["geez, first this guy uses goto, then he starts praising a feature in BASIC?!"]; and (3) it saved nine lines of code. Okay? There are two oddities to enumproc: (1) It only enumerates the functions in an OS/2 DLL; it does not, as previously advertised, enumerate the functions in a Windows DLL (at some point I will fix this); and (2) It enumerates a little too much from an OS/2 DLL: it seems to me that, for this facility to be useful, it should only list out those functions whose address you can actually get with DosGetProcAddr. In fact, enumproc will ALSO list out any functions exported from a non-DLL executable: that is any function designated as EXPORT in the DEF file, or marked with the C 5.1 _export keyword. Unfortunately or not, an address to such functions cannot be retrieved with DosGetProcAddr.