home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 15 / CDACTUAL15.iso / cdactual / OS2 / EDM2 / COMMON / SNIPPETS / NEWC2.ZIP / readme < prev    next >
Encoding:
Text File  |  1997-01-27  |  6.4 KB  |  170 lines

  1. Jan 22, 1997
  2.  
  3. What is NEWCALLS.DLL?
  4. =====================
  5. This is an example of how to redirect (or "hook") a function
  6. in a dll that you don't have the code for.  My example hooks
  7. DosOpen() for PMMERGE.DLL.  It works under Warp 3.0 or Warp
  8. 4.0.
  9.  
  10.  
  11. How it Works
  12. ============
  13. The exe header of PMMERGE.DLL is changed so that all
  14. references to DOSCALLS.DLL go to NEWCALLS.DLL instead (IBM's
  15. compiler supplies a utility called DLLRNAME to do this).
  16.  
  17. NEWCALLS.DLL contains a forwarder entry (to DOSCALLS.DLL)
  18. for every function exept Dos32Open().  The forwarder entries
  19. are created, by the linker (FWDSTAMP.EXE is NOT needed),
  20. because the *.def file both IMPORTS and EXPORTS all of the
  21. function names (except Dos32Open).
  22.  
  23. Since many of the ordinals are not referenced by name (and
  24. are not documented),  I forward them with a manufactured
  25. name. Example:
  26.  
  27.    _undoc4=DOSCALLS.4
  28.  
  29. Since the real doscalls.dll does not export a name for
  30. ordinal 4, it should not make any difference what it is
  31. called.  The important thing is that an oridinal of 4 does
  32. exist,  in case pmmerge.dll uses it (it will use it by
  33. ordinal number, not by name).  This may seem untrustworthy,
  34. but you have to keep in mind we are redirecting DOSCALLS
  35. only for one specific piece of code (pmmerge.dll);  and if
  36. we get it wrong it will fail to load.
  37.  
  38. Additionally,  newfwd.def IMPORTS the real Dos32Open,  for
  39. its own use, by ordinal (273), and calls it _Dos32Open().
  40. _Dos32Open() is a private name,  only seen by newcalls.dll.
  41.  
  42.         _DOS32OPEN =DOSCALLS.273
  43.  
  44.  
  45. Newcalls.c only has to contain code for one function,
  46. Dos32Open().  All other functions are automatically
  47. redirected,  at load time,  to the real doscalls.dll;  thus
  48. there is NO runtime performance impact,  only a slight
  49. (probably immeasurable) loadtime impact.
  50.  
  51.  
  52. Why NEWCALLS.DLL?
  53. =================
  54. Whenever anything changes on your WPS (which can happen
  55. simply by referencing an object),  changes are made to
  56. OS2.INI and/or OS2SYS.INI. Every so often (2 mins or so)
  57. these changes are written to disk.  Since OS/2 2.1,  *.ini
  58. files are kept completely in (swappable) memory,  and are
  59. rewritten, in their entirety,  whenever updates are required
  60. (this means the system will have to swap out memory equal to
  61. the size of your *.ini files,  swap in the memory where the
  62. *.ini file data is,  write them out, etc...this design
  63. sucks;  I liked the way os/2 1.1 through 2.0 did it better).
  64.  
  65. To further complicate things,  the *.ini file data is
  66. written out in chunks of 32k or less.  My os2*.ini files are
  67. 1.2mb;  that means about 40 DosWrite's.
  68.  
  69. The code for PrfOpenProfile() is in pmmerge.dll.
  70. PrfOpenProfile() calls DosOpen with the
  71. "OPEN_FLAGS_WRITE_THROUGH" bit on.  This causes each
  72. DosWrite() to the *.INI files to completely update all disk
  73. structures before it returns (this is VERY slow on HPFS).
  74.  
  75. It takes a good 15-20 seconds to write my *.ini files out
  76. (and this happens every few mins).  Not only do I have an
  77. annoyingly loud harddisk,  but the performance of my PC will
  78. sometimes crawl while the update is taking place (a priority
  79. boost is giving to threads blocked on disk i/o).
  80.  
  81. My replacement DosOpen() masks off the
  82. OPEN_FLAGS_WRITE_THROUGH bit,  so that all operations to the
  83. *.ini files are cached.  Now my *.ini file updates are next
  84. to instant (a second or so),  and a lot quieter;  file
  85. system structures are only updated once,  instead of after
  86. each DosWrite().
  87.  
  88. I'm sure someone at IBM thought they were being "safe" by
  89. using write-through mode.  I disagree.  The *.ini files are
  90. actually written as "os2.!!!" and "os2sys.!!!",  then
  91. renamed to os2*.ini after they are on the disk.  A power
  92. failure will only cause a problem if it occurs when the
  93. *.!!! files are renamed (regardless if you're using
  94. newcalls.dll or not).  A power failure while the ini file
  95. data is being written to disk will cause the system to use
  96. the older *.ini files already present.  It actually makes
  97. more sense to write the data out as fast as you can,  to get
  98. ahead of the power failure.
  99.  
  100.  
  101. How to use NEWCALLS.DLL
  102. =======================
  103.  
  104.  1) Compile/link newcalls.c using IBM's compiler (the IBM
  105.     linker is key; it creates the forwarder entries from the
  106.     *.def file).  Simply:
  107.  
  108.     icc /Gn /O /Fenewcalls.dll newcalls.c newfwd.def os2386.lib
  109.  
  110.     [see G.CMD]
  111.  
  112.  2) Backup your original \os2\dll\pmmerge.dll.   Run:
  113.  
  114.        \ibmcpp\bin\dllrname pmmerge.dll doscalls=NewCalls /q
  115.  
  116.     [see T.CMD]
  117.  
  118.     (You can't use the pmmerge.dll that is active;  copy it
  119.      somewhere else, modify the copy, boot to the command
  120.      line,  copy new dll to \os2\dll).
  121.  
  122.     This command will change all references to DOSCALLS to
  123.     NEWCALLS.DLL. This only affects pmmerge.dll.  It does
  124.     not directly affect any programs that use pmmerge.dll.
  125.     Furthermore,  only DosOpen (Dos32Open actually) has
  126.     replacement code -- all other entry points are forwarded
  127.     to the real doscalls.  There is ZERO runtime performance
  128.     impact on forwarded calls (there is a slight LOAD time
  129.     impact,  as the loader does its stuff).
  130.  
  131.  3) newcalls.dll,  and the modified pmmerge.dll must be on
  132.     your libpath (for example \os2\dll).
  133.  
  134.     Tip: - create a new dir called \newdll.
  135.          - Place newcalls.dll,  and the modified pmmerge.dll
  136.            there.
  137.          - Edit config.sys,  make sure the directory \newdll
  138.            comes before \os2\dll.
  139.          - Leave your original pmmerge.dll in \os2\dll (this
  140.            will allow Service Packs to correctly upadate
  141.            your system).
  142.          - Whenever you install a fixpak (service pack),
  143.            repeat steps 2 and 3.
  144.  
  145.   4) (optional).  You might have noticed that newcalls.c
  146.     prints a few messages to file handle 2 (stderr).  If you
  147.     want to see these, follow this procedure:
  148.  
  149.         a) Edit config.sys;  change "runworkplace" to
  150.            \os2\cmd.exe.
  151.         b) reboot (you will be in a PM session,  with an
  152.            open command prompt window).
  153.         c) enter "pmshell 2>stderr.out".  All pmshell
  154.            messages sent to stderr will go to this file, not
  155.            just messages from newcalls.dll.
  156.         d) To view the file while the shell is still
  157.            running, use "type stderr.out".
  158.  
  159.  
  160. Peter Fitzsimmons,
  161. President,
  162. A:WARE Inc (OS/2 Contracting)
  163.  
  164. Voice:  905 858 3222
  165.  
  166. Internet: pfitz@echo-on.net
  167. Internet: sol3@olc.gvc.com
  168.  
  169. Copyright (C) 1997, A:WARE Inc.
  170.