home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / progc / cspool.arj / SPOOLER.C
C/C++ Source or Header  |  1992-05-15  |  6KB  |  271 lines

  1. /* Author Paul Mckenzie   -Public Domain-   */
  2.  
  3.  
  4. /* This module must be compiled with BYTE alignment ON */
  5.  
  6. /* Here are some C routines that accesses PRINT.COM.
  7.    PRINT.COM is accessed by issuing calls to interrupt 0x2F.
  8.    The print spooler must be installed by issuing a PRINT
  9.    command from the command line before these functions will
  10.    work properly.  Also, you must use DOS 3.0 or higher */
  11.  
  12. /* These functions are compatible with any DOS C compiler that
  13.    supports the int86...() family of functions and supports
  14.    byte alignment compilation.  This includes Turbo/Borland,
  15.    Microsoft, Zortech, Watcom, Lattice, JPI, and others not
  16.    mentioned. */
  17.  
  18.  
  19. #include <stdio.h>
  20. #include <dos.h>
  21. #include <stdlib.h>
  22. #define TRUE  1
  23. #define FALSE 0
  24. #define NEXTFILE 64
  25.  
  26. /* changes pointers to offset segment pair */
  27. #define GET_SEGMENT(x)  \
  28.                   ((unsigned) ((long)(char far *)(x) >> 16))
  29. #define GET_OFFSET(x)   \
  30.                    ((unsigned) ((long)(char far *)(x) & 0x0000FFFF))
  31. #define MAKE_FAR_POINTER(a,b)  ((char far *)(((unsigned long)(a) << 16)+(b)))
  32.  
  33. int spool_install(void);
  34. int spool_print(char *);
  35. int spool_status(char far **);
  36. int spool_status_end(void);
  37.  
  38. static int _spool_error;
  39.  
  40. typedef struct packet    /* packet needed for print spooler functions */
  41. {
  42.   char level;
  43.   char far *ptr;
  44. } packet;
  45.  
  46.  
  47.  
  48.  
  49. /* check if print spooler is installed.  The following return codes are as
  50.    follows:
  51.              if AL contains 0xFF, PRINT.COM is installed.
  52.               if AL contains 0, PRINT.COM is not installed, but can
  53.               be installed.
  54.               if AL contains 1, PRINT.COM is not installed and cannot be
  55.               installed. */
  56.  
  57. int spool_install()
  58. {
  59.   union REGS regs;
  60.   regs.x.ax = 0x0100;
  61.  
  62.   /* DOS must be at least 3.0 */
  63.   if (_osmajor < 3)
  64.   {
  65.     _spool_error = 1;
  66.     return FALSE;
  67.   }
  68.  
  69.   /* call multiplex function to test for installed print spooler */
  70.   int86(0x2F,®s,®s);
  71.   if (regs.x.ax & 0x00FF == 0x00FF)
  72.     return TRUE;
  73.  
  74.   /* return what AL has */
  75.   _spool_error = regs.h.al;
  76.   return FALSE;
  77. }
  78.  
  79.  
  80. /* spool_print() places a file in the print queue */
  81.  
  82.  
  83. int spool_print(char *filename)
  84. {
  85.  
  86.   union REGS regs;
  87.   struct SREGS sregs;
  88.  
  89.   /* define packet to submit */
  90.   packet p;
  91.  
  92.   /* set level to 0 */
  93.   p.level = 0;
  94.  
  95.   /* let packet ptr point to filename */
  96.   p.ptr = filename;
  97.  
  98.   /* set AX to 0x0101 - this is the 'submit file to print' command */
  99.   regs.x.ax = 0x0101;
  100.  
  101.   segread(&sregs);
  102.  
  103.   /* move packet pointer to DS:DX */
  104.   regs.x.dx = GET_OFFSET(&p);
  105.   sregs.ds = GET_SEGMENT(&p);
  106.  
  107.   /* place file in queue by calling multiplex function */
  108.   int86x(0x2F,®s,®s,&sregs);
  109.  
  110.   /* return error condition */
  111.   if (regs.x.cflag & 0x0001)
  112.   {
  113.     _spool_error = regs.x.ax;
  114.     return FALSE;
  115.   }
  116.  
  117.   /* OK */
  118.   return TRUE;
  119. }
  120.  
  121.  
  122. /* cancel a job from the print spooler - wildcards are allowed here */
  123.  
  124. int spool_cancel(char *dosname)
  125. {
  126.   struct SREGS sregs;
  127.   union REGS regs;
  128.   _spool_error = 0;
  129.  
  130.   /* move 'cancel job(s) command to AX' */
  131.   regs.x.ax = 0x0102;
  132.  
  133.   segread(&sregs);
  134.  
  135.   /* move dosname to DS:DX */
  136.   regs.x.dx = GET_OFFSET(dosname);
  137.   sregs.ds = GET_SEGMENT(dosname);
  138.  
  139.   /* call multiplex interrupt */
  140.   int86x(0x2F,®s,®s,&sregs);
  141.  
  142.   /* return if error */
  143.   if (regs.x.cflag & 0x0001)
  144.   {
  145.     _spool_error = regs.x.ax;
  146.     return FALSE;
  147.   }
  148.  
  149.   /* return OK */
  150.   return TRUE;
  151. }
  152.  
  153.  
  154. /* cancel all jobs */
  155. int spool_cancel_all()
  156. {
  157.   union REGS regs;
  158.   _spool_error = 0;
  159.  
  160.   /* move 'cancel all' constant to AX */
  161.   regs.x.ax = 0x0103;
  162.  
  163.   /* call multiplex interrupt */
  164.   int86(0x2F,®s,®s);
  165.  
  166.   /* return if error */
  167.   if (regs.x.cflag & 0x0001)
  168.   {
  169.     _spool_error = regs.x.ax;
  170.     return FALSE;
  171.   }
  172.  
  173.   /* return OK */
  174.   return TRUE;
  175. }
  176.  
  177.  
  178. /* reads status of print queue - returns file names in print queue.
  179.    Each file name is terminated by a 0 character.  Terminating file is
  180.    always NULL.  This function pauses the printer.  You must call
  181.    spool_status_end() to continue printing. */
  182.  
  183. int spool_status(char far **filenames)
  184. {
  185.   union REGS regs;
  186.   struct SREGS sregs;
  187.  
  188.   _spool_error = 0;
  189.  
  190.   segread(&sregs);
  191.  
  192.   /* move 'get file names' constant to AX */
  193.   regs.x.ax = 0x0104;
  194.  
  195.   int86x(0x2F,®s,®s,&sregs);
  196.   *filenames = MAKE_FAR_POINTER(sregs.ds,regs.x.si);
  197.  
  198.   /* return if error */
  199.   if (regs.x.cflag & 0x0001)
  200.   {
  201.     _spool_error = regs.x.ax;
  202.     return FALSE;
  203.   }
  204.  
  205.   /* return OK */
  206.   return TRUE;
  207. }
  208.  
  209.  
  210. /* continue printing after spoll_status() */
  211.  
  212. int spool_status_end()
  213. {
  214.   union REGS regs;
  215.   _spool_error = 0;
  216.   /* move 'get file names' constant to AX */
  217.   regs.x.ax = 0x0105;
  218.  
  219.   int86(0x2F,®s,®s);
  220.  
  221.   /* return if error */
  222.   if (regs.x.cflag & 0x0001)
  223.   {
  224.     _spool_error = regs.x.ax;
  225.     return FALSE;
  226.   }
  227.  
  228.   /* return OK */
  229.   return TRUE;
  230. }
  231.  
  232.  
  233.  
  234.  
  235. /* Example */
  236.  
  237.  
  238. main()
  239. {
  240.   char far *filename;
  241.   int status;
  242.   int i;
  243.   /* check if spooler installed */
  244.   if (!spool_install())
  245.   {
  246.     printf("PRINT.COM not installed.");
  247.     exit(0);
  248.   }
  249.  
  250.   /* spool print a file */
  251.   status = spool_print("spooler.c");
  252.  
  253.   /* get list of file names */
  254.   status = spool_status(&filename);
  255.  
  256.   /* loop to print all file names in queue */
  257.   /* all file names are 64 bytes apart.  Each name is NULL-terminated.
  258.      A null file name indicates the end of the list */
  259.   i = 1;
  260.   while (1)
  261.   {
  262.     if (!*filename)
  263.       break;
  264.     printf("File %d in print queue is %Fs\n",i,filename);
  265.     filename+=NEXTFILE;
  266.     i++;
  267.   }
  268.  
  269.   spool_status_end();
  270. }
  271.