home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / elvos221.zip / lib / doexec.txt < prev    next >
Text File  |  1998-12-10  |  26KB  |  580 lines

  1. The MS-DOS version of elvis uses Thomas Wagner's do_exec() function to swap
  2. itself out while running external programs.  His original distribution is
  3. available at...
  4.  
  5.     ftp://ftp.demon.co.uk/pub/mirrors/simtelnet/msdos/pgmutil/exec33b.zip
  6.  
  7. In elvis, the following files are derived from his work:
  8.  
  9.     osmsdos/doexec.h    This is a copy of his "exec.h" file.
  10.  
  11.     osmsdos/doexec.lib    This is a library containing the spawncl.obj and
  12.             checkpcl.obj files from his distribution, plus an
  13.             exec.obj file compiled from his exec.c source file.
  14.  
  15. The following is the "readme.doc" file from his original distribution.
  16. -------------------------------------------------------------------------------
  17.  
  18.                   An EXEC function with memory swap
  19.                    Version 3.3b, released 93-11-29
  20.  
  21.                       Public Domain Software by
  22.                             Thomas Wagner
  23.                        Ferrari electronic GmbH
  24.                   (NOTE: Address change, see below)
  25.  
  26.  
  27. This archive contains the sources for an 'EXEC' function that allows
  28. calling external programs, while optionally swapping out the memory
  29. image to EMS, XMS, or file. When swapping out, only a few K of main
  30. memory remain resident. The code and data stub is about 1k, the actual
  31. memory usage depends on memory fragmentation, and especially on the
  32. size of the environment variables. The resident memory usage
  33. typically ranges from 2K to 7K.
  34.  
  35. The Routines are compatible with 
  36.    Turbo C (Versions 1.x, 2.x, and C++ 1.0)
  37.    Borland C++ (Version 2.0 and above),
  38.    Microsoft C (Versions 5.1 and above), 
  39.    Watcom C (Version 8.0), 
  40.    Turbo Pascal (Versions 4.x to 6.x).
  41.  
  42. EMS (LIM 3.0 or above) or XMS is used automatically if there is
  43. enough space left, otherwise a temporary file is created. If the
  44. "TEMP=" or "TMP=" environment variable is present, the temporary file
  45. is created in the directory specified by this variable, otherwise it
  46. is created in the current directory.
  47.  
  48. For detailed usage and parameter information, see the file "exec.h" (C) 
  49. or "exec.pas" (Pascal).
  50.  
  51. The general format is
  52.  
  53.    retcode = do_exec (filename to execute,
  54.                       program parameter and redirection string,
  55.                       spawn options,
  56.                       memory needed (0xffff to always swap, 0 to never swap),
  57.                       environment pointer/flag)
  58.  
  59. for example:
  60.  
  61.    rc = do_exec ("cl", "-c -Od exec.c >&errout", USE_ALL, 0xffff, NULL);
  62.  
  63. or, for Pascal:
  64.  
  65.    rc := do_exec ('tpc', '/$D+ exec >&errout', USE_ALL, $ffff, false);
  66.  
  67. Redirection for standard input, standard output, and standard error
  68. is optionally handled by parsing the command parameter string for the
  69. standard redirection combinations:
  70.  
  71.    stdin:   <file
  72.    stdout:  >file    or >>file   to append
  73.    stderr:  >&file   or >&>file  to append
  74.  
  75. Redirection is supported by default, to disable it you must change
  76. the define in both spawn.asm and exec.c/exec.pas.
  77.  
  78. If the command to be executed is a BAT file, the command processor
  79. will be invoked automatically. The command processor will also be
  80. invoked if the command is empty. The COMSPEC environment variable is
  81. used to locate the command processor, any parameters present on the
  82. COMSPEC line are inserted into the parameter string.
  83.  
  84. An example:
  85.  
  86.    Given   COMSPEC=C:\DOS\COMMAND.COM /E:960
  87.            PATH=C:\DOS;C:\CMD
  88.            File B.BAT resides in C:\CMD
  89.            do_exec is called with ('b', 'one two >out', ...)
  90.  
  91.    Then the command executed is
  92.            C:\DOS\COMMAND.COM
  93.    with the parameter string
  94.            /E:720 /C C:\CMD\B.BAT one two
  95.    and standard output redirected to file 'out'.
  96.  
  97.  
  98.  
  99.                         CONTENTS
  100.                         ========
  101.  
  102. This archive contains the following files:
  103.  
  104.     README.DOC      This file
  105.     LIESMICH.DOC    German version of this file
  106.  
  107.     GETLANG.EXE     A helper program to extract a single-language
  108.                     version from the dual-language source. All C and
  109.                     Assembler sources (Pascal sources only partially)
  110.                     are commented in both English and German,
  111.                     which makes the code hard to read. For easier
  112.                     reading, you can use GETLANG to eliminate one
  113.                     of the languages.
  114.  
  115.          Usage:   GETLANG language compiler <infile >outfile
  116.             Where    language is 'E' for English or 'D' for German
  117.                      compiler is 'C' for C files, 'A' for Assembler,
  118.                      or 'P' for Pascal.
  119.  
  120.          Samples: GETLANG e a <spawn.asm >spawne.asm
  121.                   GETLANG e c <extest.c >exteste.c
  122.  
  123.     DEUTSCH.BAT     Batch-File to execute GETLANG for all source
  124.                     files, German version
  125.     ENGLISH.BAT     Batch-File to execute GETLANG for all source
  126.                     files, English version
  127.  
  128.     SPAWN.ASM       The main swap/exec function
  129.  
  130.         This file is common to the C and Pascal versions.
  131.         It must be assembled with Turbo-Assembler for use with
  132.         Pascal. The C version can be assembled with TASM (specify 
  133.         /JMASM51 on the command line) or MASM 5.1.
  134.  
  135.         To assemble:
  136.             tasm /DPASCAL spawn,spawnp;     For Turbo Pascal, near calls
  137.             tasm /DPASCAL /DFARCALL spawn,spawnp;  
  138.                                             For Turbo Pascal, far calls
  139.             ?asm spawn;                     For C (default small model)
  140.             ?asm /DMODL=xxx spawn;          For C (model 'xxx')
  141.          Example:
  142.             masm /DMODL=large spawn;            Large model C
  143.             tasm /DMODL=medium /JMASM51 spawn;  Medium model C
  144.  
  145.     SPAWNP.OBJ      SPAWN assembled for use with Pascal, near calls
  146.     SPAWNCS.OBJ     SPAWN assembled for use with C (small model)
  147.     SPAWNCL.OBJ     SPAWN assembled for use with C (large model)
  148.         
  149.         The C files have been assembled with the /MX switch
  150.         for case-sensitive external linking.
  151.  
  152.         Note for Turbo Pascal: You can use the near call version of
  153.         SPAWN even when compiling with "force far calls" by enclosing
  154.         the external definitions of do_spawn and prep_swap in file
  155.         exec.pas with {$F-} and {$F+}.
  156.         To avoid confusion when generating multiple language
  157.         versions, the Pascal OBJ-File was named "spawnp.obj".
  158.  
  159.     CHECKPAT.ASM   Utility function to check and resolve a path 
  160.  
  161.         This file is common to the C and Pascal versions.
  162.         It must be assembled with Turbo-Assembler for use with
  163.         Pascal. The C version can be assembled with TASM (specify 
  164.         /JMASM51 on the command line) or MASM 5.1.
  165.  
  166.         To assemble:
  167.             tasm /DPASCAL checkpat,checkpap;  For Turbo Pascal, near calls
  168.             tasm /DPASCAL /DFARCALL checkpat,checkpap;  
  169.                                               For Turbo Pascal, far calls
  170.             ?asm checkpat;                    For C (default small model)
  171.             ?asm /DMODL=xxx checkpat;         For C (model 'xxx')
  172.          Example:
  173.             masm /DMODL=large checkpat;            Large model C
  174.             tasm /DMODL=medium /JMASM51 checkpat;  Medium model C
  175.  
  176.     CHECKPAP.OBJ    CHECKPAT assembled for use with Pascal, far calls
  177.     CHECKPCS.OBJ    CHECKPAT assembled for use with C (small model)
  178.     CHECKPCL.OBJ    CHECKPAT assembled for use with C (large model)
  179.     CHECKPAT.PAS    Wrapper unit for checkpat (Pascal only)   
  180.  
  181.         The C files have been assembled with the /MX switch
  182.         for case-sensitive external linking.
  183.         The Pascal version must be assembled with the FARCALL switch
  184.         when used with the CHECKPAT.PAS unit. At least Turbo Pascal
  185.         version 5.5 seems to automatically generate a far call if an
  186.         external routine is defined in the interface part of the unit.
  187.  
  188.     EXEC.PAS        Interface routines and documentation for Turbo Pascal
  189.     EXEC.C          Interface routines for C
  190.     EXEC.H          Interface definitions and documentation for C
  191.     COMPAT.H        MS-C/TC Compatibility definitions for C
  192.  
  193.         These files prepare the parameters for the main spawn
  194.         function, and handle the file search and environment 
  195.         processing.
  196.  
  197.     EXTEST.C        C Test program for EXEC
  198.     EXTEST.PAS      Turbo Pascal Test program for EXEC
  199.  
  200.         The EXTEST program tests the functionality of the do_exec
  201.         function. It expects you to input a DOS-command and its
  202.         parameters, separated by a comma. Entering an empty line
  203.         will spawn a copy of COMMAND.COM without parameters.
  204.  
  205.    MAKEPAS          Make-file for Turbo Pascal (Borland Make) 
  206.    MAKETC           Make-file for Borland C++ (Borland Make) 
  207.    MAKEMS           Make-file for Microsoft C (MS NMAKE) 
  208.  
  209.  
  210. The Turbo Pascal version of EXEC.PAS includes replacement functions
  211. for the environment access functions 'envcount', 'envstr', and
  212. 'getenv', plus an additional function, 'putenv'. This function allows
  213. you to add strings to the environment for the spawned process. The
  214. definition is
  215.  
  216.         procedure putenv (envstr: string);
  217.  
  218. with 'envstr' containing a string of the form 'ENVVAR=value'. The '='
  219. is required. To delete an environment string, use 'ENVVAR='. Please
  220. use the environment functions from the EXEC unit only, do not mix them
  221. with calls to the DOS unit functions.
  222.  
  223.  
  224.                         SUPPORT
  225.                         =======
  226.  
  227. This software is in the Public Domain. This means that there is no
  228. restriction whatsoever on private or commercial use. No registration
  229. fees have to be paid, and no licenses are necessary for use. It also
  230. means that the author can not be held liable for any damages caused
  231. by the use of this software. You have the source, please check it out
  232. before use.
  233.  
  234. I will try my best to eliminate any bugs reported to me, and to 
  235. incorporate suggested enhancements and changes. However, my spare 
  236. time is limited, so I can not guarantee continued or individual 
  237. support. Please address all reports or questions to my business 
  238. address: 
  239.  
  240.         Ferrari electronic GmbH
  241.         attn: Thomas Wagner
  242.         Ruhlsdorfer Strasse 138
  243.         D-14513 Teltow
  244.         Germany
  245.  
  246.         Phone: (+49 3328) 474 626
  247.         Fax:   (+49 3328) 438 04-0
  248.         BBS:   (+49 3328) 438 04-8
  249.  
  250.         Internet:    twagner@bix.com
  251.         BIX:         twagner
  252.         Compuserve:  100023,2042
  253.  
  254. But, please, if at all possible, do it in writing. Please do not 
  255. phone unless it is absolutely vital (or you have a business 
  256. proposal). I like to hear about any applications for EXEC, and 
  257. if you are visiting Berlin, I also invite you to drop by for a 
  258. talk. But I am usually not that happy when I am interrupted in my 
  259. paid work by a phone call requesting support for a free product. 
  260.  
  261. I will try to answer all letters and Faxes I receive. However, I am
  262. usually not the fastest in this respect, so please be patient. If you
  263. don't hear for me for a while, send me a short reminder. The
  264. preferred, and the fastest, method to reach me is through our BBS,
  265. and through BIX, where I daily check my mailbox. Send mail to
  266. 'twagner' from BIX, or to 'twagner@bix.com" through the Internet. The
  267. second best way is CompuServe e-mail, which I usually check several
  268. times, but at least once, a week.
  269.  
  270. BIX (tm) is an electronic conferencing system. BIX can be (and is)
  271. accessed from all parts of the world. Although accessing BIX from
  272. outside the US isn't exactly cheap (don't ask me what I have to pay
  273. each month), the wealth of information available there, and the fast
  274. and extensive help the other members can give you on all kinds of 
  275. hard- and software problems, makes it worth every Mark, Peseta, 
  276. Franc, or Ruble you have to spend. New versions and updates of EXEC
  277. will first appear on BIX. 
  278.  
  279. To get more info on joining BIX, call the BIX Customer Service at 
  280. 800-695-4775 (U.S.), or 617-354-4137 (elsewhere) from 12:00 to 23:00
  281. EDT (-4 GMT). BIX access currently is $39 for three months (flat
  282. fee), plus the applicable telecomm charges (Tymnet in the U.S. and
  283. Canada, your local PTT's Packet Net charges from outside the U.S.).
  284. International users living near a BT Tymnet node can access BIX
  285. through international Tymnet at special low rates. Call the BIX
  286. helpline for Tymnet access points and charges. Other international
  287. users will need an account (NUI) with their local packet net. Please
  288. enquire at your post/telecomm office for details.
  289.  
  290. Our BBS is available 24 hours, 7 days a week, and supports up to
  291. 14.400 bps, with V.42bis and MNP5 error correction and compression.
  292.  
  293.  
  294.                         RESTRICTIONS
  295.                         ============
  296.  
  297. The "no return" mode of EXEC is included for completeness only. It
  298. has some disadvantages over the standard compiler functions for
  299. executing without return. In particular, files are not closed, and
  300. interrupt vectors used by the Run-Time-Library are not restored to
  301. the DOS defaults. If possible, use the standard RTL functions for
  302. this mode.
  303.  
  304. The assembler module "spawn" must not be the first module linked.
  305. Either put it into a library, or specify spawn.obj as one of the last
  306. objects in the link command or the Turbo project file. The spawn
  307. module will overwrite about 1k at the start of the program image.
  308. Although the contents of this area will be saved, they may not
  309. contain parts of the spawn module itself, since this could destroy
  310. the code being executed. The do_exec function will check for this
  311. condition, and return an error code if the program code could be in
  312. danger.
  313.  
  314. The calling program may not have interrupt handlers installed when
  315. calling the do_exec function. This includes handlers for Control C
  316. and critical errors. If you want to handle interrupts while the
  317. program is swapped, you will have to modify the spawn module such
  318. that the interrupt handlers are included in the resident part.
  319.  
  320. All open files will stay open during the EXEC call. This reduces the
  321. number of handles available to the child process. The "C_FILE_INFO"
  322. environment variable created by some C compilers on the standard C
  323. spawn call is not supported. If the NO_INHERIT flag is set in
  324. spawn.asm (default), all open files except for the first five
  325. standard handles will be "hidden" from the child, and thus will not
  326. be inherited. This increases the possible number of open files for
  327. the child, although the system-wide open file limit (the config.sys
  328. FILES= value) still must be high enough to support all open files.
  329.  
  330. Internal commands are not automatically processed. You can execute 
  331. those by loading the command interpreter (by passing an empty string 
  332. as the command name). For example:
  333.  
  334. (C)     retcode = do_exec ("dir", "*.*", USE_ALL, 0xffff, environ);
  335.         if (retcode == RC_NOFILE)
  336.            retcode = do_exec ("", "/c dir *.*", USE_ALL, 0xffff, environ);
  337.  
  338. (P)     retcode := do_exec ('dir', '*.*', USE_ALL, $ffff, true);
  339.         if (retcode = RC_NOFILE)
  340.            retcode := do_exec ('', '/c dir *.*', USE_ALL, $ffff, true);
  341.  
  342.  
  343.  
  344.                         CAUTIONS
  345.                         ========
  346.  
  347. The functions should be compatible with DOS versions down to DOS
  348. 2.21, but they have been tested under DOS 3.3, DOS 4.0, DOS 5.0, 
  349. DOS 6.0, and DR-DOS 5.0 only.
  350.  
  351. Compiler compatibility has been tested for Borland C++ 2.0/3.1,
  352. Microsoft C 6.0a, Visual C++ 1.0, and Turbo Pascal 5.5 only. I do not
  353. have access to other compilers. Turbo Pascal 6.0 was reported to work
  354. fine with EXEC. The DOS-extender mode of Turbo Pascal 7.0 (and any
  355. other DOS extender) will not work with EXEC.
  356.  
  357. Spawning a command that exits and stays resident (TSR), like PRINT or
  358. Sidekick, will fragment memory and prevent a return to the calling
  359. program. This should, however, not crash the system. Allocated EMS
  360. or XMS pages are released, a swap file is deleted.
  361.  
  362. If the program memory image is not contiguous, the swapping code has
  363. to use undocumented DOS-internals. In particular, the swapper has to
  364. modify DOS memory control blocks directly. In theory, this could lead
  365. to incompatibilities with later versions of DOS, or with DOS
  366. substitutes or emulators. In practice, no problems have been reported
  367. with any DOS version, including DOS 6.0 and the DR-DOS versions.
  368.  
  369. If the NO_INHERIT flag is set to TRUE in spawn.asm, some undocumented
  370. fields in the PSP are used and modified. This should work with all
  371. DOS versions and clones, but you can set NO_INHERIT to FALSE if you
  372. are afraid of potential problems (but not if you use handle-table
  373. expansion).
  374.  
  375.  
  376.                         Revision History
  377.                         ================
  378.  
  379. Changes for Version 3.3a to 3.3b:
  380.  
  381. Under certain circumstances (the first MCB of a program was the PSP,
  382. not the environment, and unallocated blocks followed), the restored
  383. memory image was incorrect. This bug was reported and fixed by
  384. Giorgio Angelotti.
  385.  
  386. Changes for version 3.3 to 3.3a:
  387.  
  388. Besides the address change, the only significant modification is a
  389. better handling of redirection. Like with DOS, redirection parameters
  390. may now be interspersed with other command line arguments.
  391.  
  392. The Pascal version was buggy in the handling of multiple redirection
  393. and COMSPEC parameters. This was fixed.
  394.  
  395.  
  396. Changes for version 3.2a to 3.3:
  397.  
  398. A new option for Turbo Pascal recognizes the free heap space and
  399. suppresses swapping for this area. For many applications this will
  400. speed up the swapping process, and reduce swap space requirements.
  401. Since this is version dependent (Turbo Pascal version 6 uses a
  402. different heap management scheme than its predecessors), the
  403. preassembled version has this feature disabled. Please set PAS_FREE
  404. in SPAWN.ASM to TRUE, and set TPAS_6 to TRUE or FALSE depending on
  405. your version of Turbo Pascal to use it.
  406.  
  407. The Pascal "putenv" function was buggy. When putting a variable
  408. already in the environment, it produced a duplicate entry instead of
  409. replacing it. Bug reported and fixed by A. Bailey.
  410.  
  411. When determining program name and path, a program with a base name
  412. (without extension) equal to the name of a directory was not found
  413. under certain circumstances. The checkpath function was modified to
  414. correctly handle this case. Bug reported by H. Lembke.
  415.  
  416. An extended handle table would cause the swap-back to fail on a
  417. file-swap if NO_INHERIT was true. This was due to the restoration of
  418. the handle table pointers before allocating and restoring the MCB the
  419. handle table was in. The handle table pointer is now restored after
  420. swapping everything back. Bug reported by H. Lembke.
  421.  
  422. EXEC would fail completely with an extended handle table if
  423. NO_INHERIT was false. The MCB containing the handle table now is not
  424. swapped, which will likely fragment memory, so setting NO_INHERIT to
  425. false when extending the handle table is not recommended. 
  426.  
  427. The C do_exec function now correctly handles NULL pointers to the
  428. command line and parameter strings.
  429.  
  430.  
  431. Changes for version 3.2 to 3.2a:
  432.  
  433. A bug in checkpat.asm that caused incomplete path specs was fixed.
  434.  
  435. A bug in spawn.asm that caused redirected files to stay open even
  436. after program termination was fixed.
  437.  
  438. Changes for version 3.1 to 3.2:
  439.  
  440. The call of a user-defineable function (through a function pointer or
  441. a procedure variable) from do_exec immediately before executing the
  442. external command was added. This function can output messages and
  443. perform additional checks. The previously internal structure
  444. containing the swap parameters was made global for access by this
  445. function. For details see exec.h/exec.pas, and the example in
  446. extest.c/extest.pas.
  447.  
  448. A bug in checkpat.asm that led to erroneous operation of the 'exists'
  449. function when used with Turbo Pascal was fixed.
  450.  
  451. The Pascal version of extest was (finally) brought up to date, and
  452. now corresponds closely to the C version. A sample for the use of the
  453. user-defined call-back function was added in both versions.
  454.  
  455. The definition of the internal routines in exec.c was changed to
  456. "static", initialisation of some variables in do_exec was corrected.
  457.  
  458.  
  459. Changes for version 3.0a to 3.1:
  460.  
  461. The capability to process BAT files and to handle redirection was
  462. added.  The program search order now exactly matches the DOS order
  463. with the exception of internal commands (there is no safe way to
  464. determine whether a command is internal or external). Redirection is
  465. optional.  The interface to do_exec did not change (redirection is
  466. handled by parsing the parameter string), but do_spawn takes three
  467. new parameters if redirection is enabled.
  468.  
  469. A routine was added (checkpat.asm) that checks and resolves a path
  470. name in addition to splitting it. This routine does some thorough
  471. checks on the supplied path and filename, and will handle critical
  472. errors (invalid drive, drive not ready) without user intervention.
  473. This routine is used to process the program file name, the command
  474. processor filename, and the temporary path. This routine is not
  475. dependent on the other EXEC/SPAWN routines, and thus might be
  476. useful for other applications.
  477.  
  478. Several new error codes allow better analysis of error conditions.
  479.  
  480. The temporary file path will now always be a complete path, so that a
  481. change of the default drive and directory while spawned can no longer
  482. cause the swap file to get lost.
  483.  
  484. Any parameters on the COMSPEC= environment string will be inserted
  485. into the command parameters when calling the command processor. This
  486. allows specification of environment size and other parameters when
  487. spawning.
  488.  
  489. The check for file existance was moved to checkpat.asm, and changed
  490. from a 'find first' operation to 'get file attributes'. This seems to
  491. be marginally faster, and avoids compiler dependencies.
  492.  
  493. The GETLANG program was corrected to use stderr to output the usage
  494. information.
  495.  
  496.  
  497. Changes for version 3.0 to 3.0a:
  498.  
  499. A minor bug in EXEC.C was fixed: a '<' was missing in a German
  500. comment, so that GETLANG E would gobble up a large part of the file.
  501.  
  502. A problem (feature? bug?) with the Turbo C/Borland C "stat" function
  503. always returning directories with a "read-only" attribute prevented
  504. the "TEMP" directory from being used. The Write permission for the
  505. directory is no longer checked.
  506.  
  507. The preallocation of the swap file introduced in Version 3.0 to make
  508. sure that the disk can hold the swap file causes a severe slowdown
  509. when the swap drive is a Novell Network drive. Two new "method" flags
  510. were introduced to circumvent this problem:
  511.  
  512.       NO_PREALLOC - never preallocate
  513.       CHECK_NET   - check for network drive, don't preallocate if net
  514.  
  515. If the file is not preallocated, the disk is not checked for
  516. sufficient space at all. Using the "get disk free space" call usually
  517. takes even longer than preallocation. This is not a big problem
  518. though, swapping simply will fail with error code 0x502 when the disk
  519. is full on swapping out.
  520.  
  521. Thanks to Tim Frost ('<' bug) and Tron Hvaring (stat and Novell
  522. problems) for their reports.
  523.  
  524.  
  525. Changes for version 3.0:
  526.  
  527. This is a major rewrite of the code in spawn.asm. The interface for
  528. do_exec and do_spawn has changed, the exec and extest files have been
  529. modified accordingly.
  530.  
  531. The main enhancement is support for XMS.
  532.  
  533. The code in spawn.c was modularized a tad, and a lot of comments were
  534. added. This should help in better understanding the code. Old bugs
  535. (versions 2.4 and 2.5 were buggy in handling non-swapping spawns)
  536. were eliminated.
  537.  
  538. The allocation of swap space has been separated from the actual
  539. swapping. Although not used in the current do_exec routine, this
  540. could be used to issue an informative message about where the
  541. swapping will go to, and to try other paths for the temporary file if
  542. allocation fails. You might elect to add support for this in the
  543. do_exec routine, just be careful not to modify the memory layout
  544. between the calls to prep_swap and do_swap.
  545.  
  546. The MCB blocks are no longer modified in preparation of the swap.
  547. Instead of using an internal chain with undocumented fields in the
  548. MCB, the MCB chain is now parsed multiple times. Since the chain
  549. normally consists of just a few elements, this will not severely
  550. impact execution performance. MCBs are now swapped out and restored
  551. in their original form, including the "unused" fields that are not
  552. really unused in DOS 4.0 and later versions.
  553.  
  554. Saving fragmented memory will now use less EMS space, since the
  555. blocks are packed tight. Previous versions started a new page for
  556. every MCB.
  557.  
  558. Memory blocks located "below" the PSP (including the environment
  559. block, unless it is needed for an environment copy) will now be
  560. swapped, too. This may increase available memory if DOS memory is
  561. fragmented.
  562.  
  563.  
  564. Things not done in this release:
  565.  
  566. The MCB chain still is modified directly. Although some users have
  567. suggested trying to call DOS to allocate the blocks, this has proven
  568. impractical in some tests. If memory is fragmented, getting DOS to
  569. allocate a block at an exact location is rather tedious. I will keep
  570. the suggestion in mind, but the current method works reliably with
  571. all known (and unknown) versions of DOS and its clones.
  572.  
  573. Another good suggestion not implemented in this version is the save
  574. and restore of the interrupt vector table to remove TSRs installed
  575. while the program was swapped out. It would be rather complex to find
  576. and release all memory blocks belonging to the TSR, and without
  577. releasing the TSRs memory, the program can not be swapped back in
  578. anyway, so restoring the interrupt table wouldn't help.
  579.  
  580.