home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / comp / os / msdos / programm / 12493 < prev    next >
Encoding:
Text File  |  1993-01-28  |  7.8 KB  |  245 lines

  1. Newsgroups: comp.os.msdos.programmer
  2. Path: sparky!uunet!ftpbox!news.acns.nwu.edu!zaphod.mps.ohio-state.edu!darwin.sura.net!bogus.sura.net!opusc!usceast!douglas
  3. From: douglas@cs.scarolina.edu (G. David Douglas Jr.)
  4. Subject: Re: Help - DOS commands from program...
  5. Message-ID: <douglas.728109342@willow.cs.scarolina.edu>
  6. Sender: usenet@usceast.cs.scarolina.edu (USENET News System)
  7. Organization: USC  Department of Computer Science
  8. References: <1k4gi7INNou2@charnel.ecst.csuchico.edu> <douglas.728101903@ebony.cs.scarolina.edu>
  9. Date: 27 Jan 93 04:35:42 GMT
  10. Lines: 233
  11.  
  12.  
  13. P.S.  This isn't the code I mentioned, but I tried it, and exec'ing 
  14.       COMMAND.COM to change to another directory, then opening a file
  15.       and writing to it DOES cause the file to be created in the 
  16.       changed-to directory, so see what you think.  (This is under
  17.       MS-DOS 4.01). 
  18.       
  19.       (I _HOPE_ this isn't an inappropriate posting for this group!
  20.        If so, my apologies!)
  21.  
  22.  
  23. David Douglas
  24. douglas@usceast.cs.scarolina.edu
  25.  
  26.  
  27. { File:  QWERTY.PAS (for lack of a better filename :-) }
  28. program tryit;
  29.  
  30. {$I EXEC.PAS}
  31.  
  32. VAR F : TEXT;
  33.  
  34. BEGIN
  35.  
  36.   EXEC('C:\COMMAND.COM', '/C CD C:\');
  37.   EXEC('C:\COMMAND.COM', '/C MD QWERTY.DIR');
  38.   EXEC('C:\COMMAND.COM', '/C CD \QWERTY.DIR');
  39.   ASSIGN(F,'QWERTY.OUT');
  40.   REWRITE(F);
  41.   WRITELN(F, 'This the output of QWERTY');
  42.   CLOSE(F);
  43.  
  44. END.
  45.  
  46. { File:  EXEC.PAS }
  47.  
  48.  
  49. {----------------------------------------------------------------------------}
  50. {                                                                            }
  51. {     Exec                                                                   }
  52. {                                                                            }
  53. {   This subroutine, given a partial (or full) path-name to a file to be     }
  54. { executed (but NOT a .BAT file), and a commandline containing the           }
  55. { parameters to be passed to that program, tries to execute the given        }
  56. { file with the given parameters.  If an error occurs, an appropriate error  }
  57. { message is printed.                                                        }
  58. {                                                                            }
  59. {   To execute a particular batch file, specify COMMAND.COM as the program   }
  60. { to be executed, and '/C batch-file-name' as the commandline.  DON'T TRY    }
  61. { TO EXECUTE A BATCH FILE DIRECTLY -- THE COMPUTER WILL LOCK UP, AND YOU     }
  62. { WILL HAVE TO RESET THE COMPUTER!!!                                         }
  63. {                                                                            }
  64. { ***NOTE*** : Compile to an executable file with a 'O C I 0' option and     }
  65. { a reasonable 'O C A' value of, for instance, 0800(from the Turbo Pascal    }
  66. { main menu).  Otherwise, there may not be enough memory available to load   }
  67. { and execute the requested program.                                         }
  68. {                                                                            }
  69. {                                                                            }
  70. {----------------------------------------------------------------------------}
  71.  
  72. TYPE _EXECSTRING255_ = STRING[255];
  73.  
  74. PROCEDURE EXEC(FILENAME, COMMANDLINE : _EXECSTRING255_);
  75.  
  76.   CONST EOS  = #0;  { End-Of-String }
  77.         BEEP = #7;
  78.  
  79.         ERROR_MSG : _EXECSTRING255_ =
  80.                     'Error in execution of child process -- try again.';
  81.  
  82.         ERROR_MESSAGES : ARRAY[1..18] OF _EXECSTRING255_ =
  83.         ( 'Invalid function number.',
  84.           'File not found.',
  85.           'Path not found.',
  86.           'Too many open files (no handles available).',
  87.           'Access denied.',
  88.           'Invalid handle.',
  89.           'Memory control blocks destroyed.',
  90.           'Insufficient memory.',
  91.           'Invalid memory block address.',
  92.           'Invalid environment.',
  93.           'Invalid format.',
  94.           'Invalid access code.',
  95.           'Invalid data.',
  96.           '',            { not used }
  97.           'Invalid drive specified.',
  98.           'Attempted to remove the current directory.',
  99.           'Not same device.',
  100.           'No more files.'
  101.         );
  102.  
  103.   TYPE ARRTYPE = ARRAY[1..256] OF CHAR;
  104.  
  105.        PARAMBLOCKTYPE  = RECORD
  106.                            ENV,
  107.                            CMDLINEOFS,
  108.                            CMDLINESEG,
  109.                            FCB1OFS,
  110.                            FCB1SEG,
  111.                            FCB2OFS,
  112.                            FCB2SEG    : INTEGER;
  113.                          END;
  114.  
  115.        REGISTERS = RECORD
  116.          CASE BOOLEAN OF
  117.            TRUE  : ( AL, AH, BL, BH, CL, CH, DL, DH : BYTE );
  118.            FALSE : ( AX,     BX,     CX,     DX,
  119.                      BP, SI, DI, DS, ES, FLAGS : INTEGER );
  120.          END;
  121.  
  122.   VAR
  123.       XERROR_MSG  : _EXECSTRING255_;
  124.       ENVIRONMENT : INTEGER ABSOLUTE CSEG:$2C;
  125.       ASCIIZSTR   : ARRTYPE;
  126.       I,J         : INTEGER;
  127.  
  128.       FCB1,
  129.       FCB2        : ARRAY[1..16] OF BYTE;
  130.       ERRORCODE   : INTEGER;
  131.  
  132.       PARAMBLOCK  : PARAMBLOCKTYPE;
  133.       R           : REGISTERS;
  134.  
  135.  
  136.   BEGIN  { PROCEDURE EXEC }
  137.  
  138. { Initialize the FULL error message }
  139.  
  140.     XERROR_MSG := BEEP + BEEP + BEEP + ERROR_MSG;
  141.  
  142. { "Initialize" the two FCBs }
  143.  
  144.     FOR I := 1 TO 16 DO
  145.       BEGIN
  146.         FCB1[I] := 0;
  147.         FCB2[I] := 0;
  148.       END;
  149.  
  150.     FOR I := 2 TO 12 DO
  151.       BEGIN
  152.         FCB1[I] := 32;
  153.         FCB2[I] := 32;
  154.       END;
  155.  
  156. { Load the ENV, CMDLINESEG, etc., fields of the PARAMBLOCK record with }
  157. { the appropriate values.                                              }
  158.  
  159.     WITH PARAMBLOCK DO
  160.       BEGIN
  161.         ENV        := ENVIRONMENT;
  162.         CMDLINESEG := SEG(COMMANDLINE);
  163.         CMDLINEOFS := OFS(COMMANDLINE);
  164.         FCB1SEG    := SEG(FCB1);
  165.         FCB1OFS    := OFS(FCB1);
  166.         FCB2SEG    := SEG(FCB2);
  167.         FCB2OFS    := OFS(FCB2);
  168.       END;
  169.  
  170. { Get the given filename-string into ASCIIZ format }
  171.  
  172.     J := 0;
  173.     FOR I := 1 TO LENGTH(FILENAME) DO
  174.       BEGIN
  175.         J := J + 1;
  176.         ASCIIZSTR[J] := FILENAME[I];
  177.       END;
  178.     J := J + 1;
  179.     ASCIIZSTR[J] := EOS;
  180.  
  181. { Initialize the proper register-fields in register-record R. }
  182.  
  183.     WITH R DO
  184.       BEGIN
  185.         DS := SEG(ASCIIZSTR);
  186.         DX := OFS(ASCIIZSTR);
  187.         ES := SEG(PARAMBLOCK);
  188.         BX := OFS(PARAMBLOCK);
  189.         AH := $4B;              { Execute-child-process service }
  190.         AL := 0;                { Load and execute method       }
  191.       END;
  192.  
  193. { Invoke the proper service }
  194.  
  195.     MSDOS(R);
  196.  
  197. { Check the result -- if the Carry bit of FLAGS is set, then an error }
  198. { occurred -- print the appropriate error message.  Error code is     }
  199. { found in AX register field.                                         }
  200.  
  201.     IF (R.FLAGS AND 1) = 1
  202.       THEN BEGIN
  203.              WRITELN(XERROR_MSG);
  204.              WRITELN(ERROR_MESSAGES[R.AX]);
  205.            END;
  206.  
  207.   END;  { PROCEDURE EXEC }
  208.  
  209.  
  210. {----------------------------------------------------------------------------}
  211. {                                                                            }
  212. {     ReturnCode                                                             }
  213. {                                                                            }
  214. {   This subroutine attempts to retrieve the return-code returned by the     }
  215. { last program that executed.                                                }
  216. {                                                                            }
  217. {----------------------------------------------------------------------------}
  218.  
  219. FUNCTION RETURNCODE : INTEGER;
  220.  
  221.   TYPE
  222.  
  223.        REGISTERS = RECORD
  224.          CASE BOOLEAN OF
  225.            TRUE  : ( AL, AH, BL, BH, CL, CH, DL, DH : BYTE );
  226.            FALSE : ( AX,     BX,     CX,     DX,
  227.                      BP, SI, DI, DS, ES, FLAGS : INTEGER );
  228.          END;
  229.  
  230.   VAR
  231.       R : REGISTERS;
  232.  
  233.   BEGIN
  234.  
  235.   { Initialize the proper register-fields in R }
  236.  
  237.       R.AH := $4D;            { Fetch-exit-code service }
  238.  
  239.       MSDOS(R);
  240.  
  241.       RETURNCODE := R.AL;         { Return the right return-code }
  242.  
  243.   END; { FUNCTION RETURNCODE }
  244.  
  245.