home *** CD-ROM | disk | FTP | other *** search
/ Current Shareware 1994 January / SHAR194.ISO / desqview / dvquit.zip / DVQUIT.CPP next >
C/C++ Source or Header  |  1993-08-16  |  11KB  |  381 lines

  1. /**************************************************************************/
  2. /*                                                                        */
  3. /* Program Name:                  DVQUIT                                  */
  4. /* System:                        General Purpose.                        */
  5. /* Date:                          08/02/93                                */
  6. /* Revision Date:                 -                                       */
  7. /* Created By:                    John Byrne                              */
  8. /* Program Language:              C++ Compiler                            */
  9. /* Modules Called:                -                                       */
  10. /* Calling Modules:               -                                       */
  11. /* Parameters:                    /F: copy from file                      */
  12. /*                                /T: copy to file                        */
  13. /*                                /Q: Quit Desqview option <QUIT> NOQUIT  */
  14. /*                                /A: File Action <FLUSH> CLOSE           */
  15. /*                                /W: File containing open windows names  */
  16. /*                                                                        */
  17. /* Files Used:                    -                                       */
  18. /* Description:                   Program to quit Desqview gracefully.    */
  19. /* The program flushes or optionally closes all files opened by DOS.      */
  20. /* This is done by using the /A: action parameter.  FLUSH will commit any */
  21. /* file output that is buffered to disk, updates the file's directory     */
  22. /* entry, and leaves the file opened.  The CLOSE option does the same     */
  23. /* except it closes the file.  The /Q: option permits quitting Desqview   */
  24. /* or performing any other options before exiting, leaving Desqview       */
  25. /* active.  QUIT is the default, NOQUIT does not quit Desqview.  NOQUIT   */
  26. /* is useful in tandem with the /A: option if a global update of all      */
  27. /* output files without quitting Desqview is desired.  You may have a     */
  28. /* checkpoint in a batch file where you want to insure that all buffers   */
  29. /* have been committed to disk.  To accomplish this use:                  */
  30. /*     DVQUIT /Q:NOQUIT /A:FLUSH                                          */
  31. /* The /F: and /T: options allow the user to copy a file to another prior */
  32. /* to exiting.  This allows a user selected batch file to execute within  */
  33. /* the batch file that started Desqview.                                  */
  34. /* The /W: option is used to specify the name of a file that contains the */
  35. /* name of open windows to check.  If any of these windows are open, the  */
  36. /* program displays an error message and exits without performing any     */
  37. /* functions.                                                             */
  38. /**************************************************************************/
  39. #include <stdlib.h>
  40. #include <dos.h>
  41. #include <IO.h>
  42. #include <fcntl.h>
  43. #include <sys/stat.h>
  44. #include <iostream.h>
  45. #include <iomanip.h>
  46. #include <string.h>
  47. #include <fstream.h>
  48. #include <ctype.h>
  49.  
  50. extern "C"
  51. {
  52. #include "dvapi.h"
  53. }
  54.  
  55. #define required (0x0200 + 26)
  56. #define MAX_WIN_OPEN 16
  57.  
  58. struct DCB_REC
  59.     {
  60.     unsigned int dcb_nusers;
  61.     unsigned int dcb_mode;
  62.     unsigned char dcb_datrb;
  63.     unsigned char dcb_dvatr;
  64.     unsigned char dcb_atrb2;
  65.     void far *dcb_pdrvr;
  66.     unsigned int dcb_frstc;
  67.     unsigned int dcb_modtm;
  68.     unsigned int dcb_moddt;
  69.     long dcb_totsiz;
  70.     long dcb_curpos;
  71.     unsigned int dcb_clsctr;
  72.     unsigned int dcb_curcls;
  73.     unsigned int dcb_dirsec;
  74.     unsigned char dcb_dirndx;
  75.     char dcb_fname[8];
  76.     char dcb_fext[3];
  77.     unsigned int dcb_fill1;
  78.     unsigned int dcb_fill2;
  79.     unsigned int dcb_fill3;
  80.     void near *dcb_owner;
  81.     unsigned int dcb_fill4;
  82.     unsigned int dcb_fill5;
  83.     unsigned int dcb_fill6;
  84.     unsigned int dcb_fill7;
  85. } far *dcb_ptr;
  86.  
  87. union REGS regs;
  88. struct SREGS sregs;
  89.  
  90. struct CVT_REC
  91.     {
  92.     void far *cvt_dpb;
  93.     void far *cvt_dcb_blk;
  94.     void far *cvt_clk;
  95.     void far *cvt_con;
  96.     unsigned int cvt_mbs;
  97.     void far *cvt_elr;
  98.     void far *cvt_ldt;
  99.     void far *cvt_fcb;
  100.     unsigned int cvt_fks;
  101.     unsigned char cvt_bld;
  102.     unsigned char cvt_lgd;
  103. } far *cvt_ptr;
  104.  
  105. struct DCBLNK_REC
  106.     {
  107.     void far *dcblnk_next_blk;
  108.     unsigned int dcblnk_blks;
  109. } far *dcblnk_ptr;
  110.  
  111. struct PSP_REC
  112.     {
  113.     unsigned int psp_num_handles;
  114.     char far *psp_handle_table;
  115. } far *handle_table;
  116.  
  117. unsigned long mywin;
  118. char check_for_open_windows(char, char *);
  119.  
  120. main(int argc, char *argv[])
  121. {
  122.     int j;
  123.     int TEMP_F;
  124.     int version;
  125.     unsigned int action_intr;
  126.     void far *f_p;
  127.     unsigned char save_handle;
  128.     char command_switch;
  129.     char in_file_name[50];
  130.     char out_file_name[50];
  131.     char check_file_name[50];
  132.     char in_char;
  133.     fstream *in_file, *out_file;
  134.     char ffile_parm, tfile_parm, quit_parm, chkwin_parm;
  135.  
  136.     version = api_init();
  137.     if(version < required)
  138.         {
  139.         cout <<"\nThis program requires DesqView version "
  140.         <<required/256 <<"."
  141.         <<setw(2) <<setfill('0') <<required%256
  142.         <<" or later.\n";
  143.         exit(1);
  144.     }
  145.  
  146.     api_level(required);
  147.     mywin = win_me();
  148.  
  149.     if((_osmajor > 5) || (_osmajor < 4))
  150.         {
  151.         cout <<"Requires MSDOS Version 4.00 or 5.00\n";
  152.         exit(1);
  153.     }
  154.  
  155.     if((argc == 2) && (strcmp(argv[1],"?") == 0))
  156.         {
  157.         cout <<"\n" <<argv[0] <<"\n"
  158.             << "     /F:file - File to copy from\n"
  159.             << "     /T:file - File to copy to\n"
  160.             << "     /A:<FLUSH>/CLOSE - Function to perform on open files\n"
  161.             << "     /Q:<QUIT>/NOQUIT - Quit/No quit DesqView\n"
  162.             << "     /W:file - File for open window names to check\n";
  163.         exit(0);
  164.     }
  165.  
  166.     action_intr = 0x6800; /* Flush files is default */
  167.     quit_parm = 1; /* Quit DesqView is default */
  168.     ffile_parm = NULL;
  169.     tfile_parm = NULL;
  170.     chkwin_parm = NULL;
  171.     for(j=1;j < argc;++j)
  172.         {
  173.         if(strlen(argv[j]) > 3)
  174.             {
  175.             ++argv[j]; /* hop over the parameter prefix slash  */
  176.             command_switch = toupper(argv[j][0]);
  177.             argv[j] += 2; /* hop over rest of parameter prefix */
  178.         }
  179.         else
  180.             {
  181.             continue;
  182.         }
  183.         switch(command_switch)
  184.             {
  185.         case 'F':   ffile_parm = 1;
  186.             strcpy(in_file_name,argv[j]);
  187.             break;
  188.         case 'T':   tfile_parm =1;
  189.             strcpy(out_file_name,argv[j]);
  190.             break;
  191.         case 'W':   chkwin_parm = 1;
  192.             strcpy(check_file_name,argv[j]);
  193.             break;
  194.         case 'A':   if(stricmp(argv[j],"FLUSH") == 0)
  195.                 {
  196.                 action_intr = 0x6800;
  197.                              /* Flush output buffers, don't close */
  198.             }
  199.             else if(stricmp(argv[j],"CLOSE") == 0)
  200.                 {
  201.                 action_intr = 0x3E00;
  202.                                  /* Close any file opened for output */
  203.             }
  204.             else
  205.                 {
  206.                 cout <<"\nInvalid Action Code - "
  207.                      << "Must be FLUSH or CLOSE\n";
  208.                 exit(1);
  209.             }
  210.             break;
  211.         case 'Q':   if(stricmp(argv[j],"QUIT") == 0)
  212.                 {
  213.                 quit_parm = 1;
  214.             }
  215.             else if(stricmp(argv[j],"NOQUIT") == 0)
  216.                 {
  217.                 quit_parm = 2;
  218.             }
  219.             else
  220.                 {
  221.                 cout <<"\nInvalid Quit Code - "
  222.                      <<"Must be QUIT or NOQUIT\n";
  223.                 exit(1);
  224.             }
  225.             break;
  226.         default:    argv[j] -= 3;  /* Add back parm prefix */
  227.             cout << "\nInvalid parameter - "
  228.                  << argv[j] << "\n";
  229.             exit(1);
  230.         }
  231.     }
  232.  
  233.     if((ffile_parm + tfile_parm) == 1)
  234.         {
  235.         if(ffile_parm == 1)
  236.             {
  237.             cout << "\nTo file parameter is missing\n";
  238.             exit(1);
  239.         }
  240.         if(tfile_parm == 1)
  241.             {
  242.             cout << "\nFrom file parameter is missing\n";
  243.             exit(1);
  244.         }
  245.     }
  246.  
  247.     if((ffile_parm + tfile_parm) == 2)
  248.         {
  249.         fstream in_file(in_file_name,
  250. ios::in);
  251.         if(in_file.bad())
  252.             {
  253.             cout << "\nUnable to open From File\n";
  254.             exit(1);
  255.         }
  256.         fstream out_file(out_file_name,ios::out);
  257.         if(out_file.bad())
  258.             {
  259.             cout << "\nUnable to open To File\n";
  260.             exit(1);
  261.         }
  262.         in_file.get(in_char);
  263.         while(!in_file.eof())
  264.             {
  265.             out_file.put(in_char);
  266.             in_file.get(in_char);
  267.         }
  268.         in_file.close();
  269.         out_file.close();
  270.     }
  271.  
  272.     if(chkwin_parm == 1)
  273.         {
  274.         if(check_for_open_windows(chkwin_parm, check_file_name) == 2)
  275.             {
  276.             exit(1);
  277.         }
  278.     }
  279.     api_beginc();
  280.     handle_table = (PSP_REC far *)MK_FP(_psp, 0x32);
  281.     regs.x.ax = 0x5200;
  282.     segread(&sregs);
  283.     intdosx(®s, ®s, &sregs);
  284.     cvt_ptr = (CVT_REC far *) MK_FP(sregs.es, regs.x.bx);
  285.     dcblnk_ptr = (DCBLNK_REC far *) cvt_ptr->cvt_dcb_blk;
  286.     do
  287.         {
  288.         f_p = (char far *)dcblnk_ptr + 6;
  289.         dcb_ptr = (DCB_REC far *) f_p;
  290.         for(j=0;j<dcblnk_ptr->dcblnk_blks;++j)
  291.             {
  292.             if((dcb_ptr->dcb_nusers > 0) &&
  293.                 (dcb_ptr->dcb_mode & (O_WRONLY | O_RDWR)))
  294.                 {
  295.                 TEMP_F = open("AUX", O_APPEND | O_BINARY,
  296.                     S_IREAD | S_IWRITE);
  297.                 save_handle = handle_table->psp_handle_table[TEMP_F];
  298.                 handle_table->psp_handle_table[TEMP_F] = j;
  299.                 regs.x.ax = action_intr;
  300.                 regs.x.bx = TEMP_F;
  301.                 intdos(®s, ®s);
  302.                 handle_table->psp_handle_table[TEMP_F] = save_handle;
  303.                 close(TEMP_F);
  304.             }
  305.             ++dcb_ptr;
  306.         }
  307.         dcblnk_ptr = (DCBLNK_REC far *)dcblnk_ptr->dcblnk_next_blk;
  308.     }
  309.     while((unsigned int) dcblnk_ptr != 0xFFFF); // only look at last word of
  310.     if(quit_parm == 1)
  311.         {
  312.         win_allow(mywin,ALW_CLOSE);
  313.         win_allow(mywin,ALW_QUIT);
  314.         api_pushkey('Y');
  315.         api_pushkey('Q');
  316.         api_pushkey(0xFC00);
  317.     }
  318.  
  319.     api_endc();
  320.     return(0);
  321. }
  322.  
  323. char check_for_open_windows(char chkwin_parm, char *check_file_name)
  324. {
  325.     int j;
  326.     int k;
  327.     int open_windows = 0;
  328.     int chk_rcds;
  329.     char *dont_close[MAX_WIN_OPEN];
  330.     fstream *check_file;
  331.     char chkwin_msg[] = "  Close the following window(s)\n"
  332.                         "  and try this command again!\n"
  333.                         "────────────────────────────────\n";
  334.     char msg_esc[] =  "\n    << Press Esc to Exit >>";
  335.     char *msg_string;
  336.  
  337.     check_file = new fstream(check_file_name,ios::in);
  338.     if(check_file->bad())
  339.         {
  340.         delete(check_file);
  341.         cout << "\nUnable to open Check Window File\n";
  342.         exit(1);
  343.     }
  344.     for(chk_rcds=0;chk_rcds<MAX_WIN_OPEN && !check_file->eof();
  345.         ++chk_rcds)
  346.         {
  347.         *check_file >> (dont_close[chk_rcds] = new char[40]);
  348.     }
  349.     check_file->close();
  350.     delete(check_file);
  351.     msg_string = (char *) malloc(strlen(chkwin_msg) + 1);
  352.     strcpy(msg_string, chkwin_msg);
  353.     for(j=0;j<chk_rcds;++j)
  354.         {
  355.         if(mal_find(dont_close[j], strlen(dont_close[j])))
  356.             {
  357.             chkwin_parm = 2;
  358.             ++open_windows;
  359.             msg_string = (char *) realloc(msg_string,
  360.                 strlen(msg_string) + strlen(dont_close[j]) + 5);
  361.             strcat(msg_string, "  ");
  362.             strcat(msg_string, strupr(dont_close[j]));
  363.             strcat(msg_string, "\n");
  364.         }
  365.     }
  366.     if(chkwin_parm == 2)
  367.         {
  368.         msg_string = (char *) realloc(msg_string,
  369.             strlen(msg_string) + strlen(msg_esc) + 1);
  370.         strcat(msg_string, msg_esc);
  371.         win_disperor(mywin, msg_string, strlen(msg_string),
  372.             open_windows + 5, 32, 1, 2);
  373.     }
  374.     free(msg_string);
  375.     for(j=0;j<chk_rcds;++j)
  376.         {
  377.         delete dont_close[j];
  378.     }
  379.     return(chkwin_parm);
  380. }
  381.