home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / ENUMP2.ZIP / ENUMPROC.TXT < prev    next >
Text File  |  1988-06-11  |  5KB  |  104 lines

  1.  
  2.     char *enumproc(char *dll, char *buf, unsigned *ord);
  3.  
  4.  
  5.     enumproc() is a C function that, given the full pathname of an
  6. OS/2 dynamic-link library, will return the names of all the
  7. procedures exported by the DLL, in ASCIIZ (zero-delimited string)
  8. form.
  9.  
  10.     The Microsoft utility EXEHDR will of course list these procedures,
  11. but there are several problems with using EXEHDR: (1) it lists out a
  12. lot of other information as well; (2) using it under program control
  13. requires setting up a pipe; (3) using it under program control
  14. requires locating it on the disk; and (4) EXEHDR does not reside on
  15. every machine.
  16.  
  17.     enumproc() does not use EXEHDR.  In fact, it turns out that it is
  18. very easy to retrieve the entry points within a DLL.  Once one finds
  19. the offset of the entry table in the new executable header, the functions
  20. are stored in an array of structures like so:
  21.  
  22.         struct func_export {
  23.             unsigned char length;
  24.             char func_name[length];     /* warning! not C! */
  25.             unsigned short ord_num;
  26.             } ;
  27.  
  28.     Since most DLLs export more than one function, the only tricky thing
  29. about using enumproc() is getting back more than one function name.  
  30. Since C, unlike more advanced programming languages like Lisp and Icon,
  31. does not have multiple return values from a function, enumproc() resorts
  32. to the same gimick as the C standard library function strtok():  the
  33. first call to enumproc() passes in a string, and subequent calls to
  34. enumproc() pass in NULL.  The file TEST.C gives this example:
  35.  
  36.         if (enumproc(filename, buf, &ord))
  37.         {
  38.             /* first entry is just module name, ordinal number zero */
  39.             printf("Module: %s\n", buf);
  40.             while (enumproc(0, buf, &ord))
  41.                 printf("%s (#%u)\n", buf, ord);
  42.         }
  43.  
  44.     As long as there are procedures to enumerate in the file, each call
  45. to enumproc() will cause the second and third parameters to be updated
  46. with the function name and its ordinal number, and the invocation will
  47. return a pointer to the function name.
  48.  
  49.     This means that enumproc() must maintain an open file handle
  50. between invocations.  When enumproc() has enumerated all the procedures
  51. in the DLL, it will automatically close the file and return FALSE.
  52.  
  53.     If you wish to stop running enumproc() on a DLL before all the function
  54. names have been exhausted, just pass in (char *)-1.  This will tell
  55. enumproc() to close the open file handle.
  56.  
  57.     The test module itself contains one interesting feature:  if the test
  58. program ENUMPROC.EXE is run with a module name rather than with a full
  59. filename (e.g. C>enumproc viocalls rather than C>enumproc c:\dll\viocalls.dll)
  60. the test program will attempt to convert the module name into the full
  61. filename, using DOSGETMODHANDLE() and DOSGETMODNAME().  In the cases where
  62. the module has already been loaded into memory, this eliminates the 
  63. necessity of checking LIBPATH.
  64.  
  65.     enumproc() was suggested by Noel J. Bergman.  I hope you find it 
  66. useful.  Please direct any comments or criticisms to the author who
  67. remains, as ever, your humble servant,
  68.                         
  69.                                     Andrew Schulman
  70.                                     32 Andrews St. #2
  71.                                     Cambridge MA 02139
  72.                                     (617) 876-2102
  73.  
  74.                                     28 May 1988
  75.  
  76. ======================================================================
  77. revised 10 June 1988:
  78.  
  79.     In the course of incorporating the enumproc feature into
  80. OS2XLISP, I found some bugs in enumproc.c related to opening and
  81. closing the file, and these have been fixed.  
  82.  
  83.     I have been asked why enumproc() uses the infamous goto
  84. statement.  There are three reasons: (1) to be perverse; (2) more
  85. seriously, because exception-handling often disrupts the flow of
  86. reading source code, and goto is a nice way to shunt exception-handling
  87. off to the side (not as nice a way as BASIC's ON ERROR) ["geez, first
  88. this guy uses goto, then he starts praising a feature in BASIC?!"];
  89. and (3) it saved nine lines of code.  Okay?
  90.  
  91.     There are two oddities to enumproc:
  92.  
  93.     (1) It only enumerates the functions in an OS/2 DLL; it does not,
  94. as previously advertised, enumerate the functions in a Windows DLL
  95. (at some point I will fix this); and
  96.  
  97.      (2) It enumerates a little too much from an OS/2 DLL: it seems to
  98. me that, for this facility to be useful, it should only list out those
  99. functions whose address you can actually get with DosGetProcAddr.  In
  100. fact, enumproc will ALSO list out any functions exported from a non-DLL
  101. executable:  that is any function designated as EXPORT in the DEF file,
  102. or marked with the C 5.1 _export keyword.  Unfortunately or not, an address
  103. to such functions cannot be retrieved with DosGetProcAddr.
  104.