home *** CD-ROM | disk | FTP | other *** search
/ Mega CD-ROM 1 / megacd_rom_1.zip / megacd_rom_1 / MAGAZINE / MSJOURNA / MSJV22.ZIP / FINDDEMO.ALL < prev   
Text File  |  1987-10-30  |  12KB  |  405 lines

  1. Microsoft Systems Journal
  2. Volume 2; Issue 2; May, 1987
  3.  
  4. Code Listings For:
  5.  
  6.     FINDDEMO
  7.     pp. 51-59
  8.  
  9. Author(s): Charles Petzold
  10. Title:     A Compleat Guide to Writing Your First OS/2 Program
  11.  
  12.  
  13.  
  14. ==============================================================================
  15. ==============================================================================
  16. Figure 2: FINDDEMO.C
  17.  
  18. ==============================================================================
  19.  
  20. /* finddemo.c -- program to demonstrate IPC and multitasking */
  21.  
  22. #include <doscall.h>
  23.  
  24. #define WORD  unsigned int
  25. #define DWORD unsigned long
  26.  
  27. #define NUMPROC     9                   /* number of process */
  28. #define CHILDPROG   "FINDER.EXE"
  29. #define QUEUENAME   "\\QUEUES\\FINDDEMO"
  30. #define THREADSTACK 1024
  31.  
  32. void far dispthread (void) ;
  33. void far waitthread (void) ;
  34.  
  35. WORD   queuehandle, count [NUMPROC] ;
  36. DWORD  runsem [NUMPROC], waitsem [NUMPROC] ;
  37. struct ResultCodes rc [NUMPROC] ;
  38. struct {
  39.      WORD count ;
  40.      struct {
  41.           WORD  reserved ;
  42.           DWORD far *sem ;
  43.           } index [NUMPROC] ;
  44.      } semtab ;
  45.           
  46. main ()
  47.      {
  48.      static char prompt[] = "Line number or Esc to end -->  \b" ;
  49.      struct KeyData keydata ;
  50.      WORD   index, len, i, dispID, waitID, sigaction ;
  51.      DWORD  sigaddr ;
  52.      char   dirmask [15], dispstack [THREADSTACK],
  53.             waitstack [THREADSTACK] ;
  54.  
  55.      /* 
  56.          Initialize: Set up "semtab" structure for DOSMUXSEMWAIT.
  57.          ----------  Disable Ctrl-Break and Ctrl-C exits.
  58.                      Create queue for IPC with FINDER.EXE.
  59.                      Create threads for messages from FINDER
  60.                          and waiting for FINDER terminations.
  61.                      Display text. 
  62.      */
  63.  
  64.      semtab.count = NUMPROC ;
  65.      for (index = 0 ; index < NUMPROC ; index++) {
  66.           DOSSEMSET ((DWORD) &waitsem[index]) ;          
  67.           semtab.index[index].sem = &waitsem[index] ;
  68.           }
  69.      DOSSETSIGHANDLER (0L, &sigaddr, &sigaction, 1, 1) ;
  70.      DOSSETSIGHANDLER (0L, &sigaddr, &sigaction, 1, 4) ;
  71.  
  72.      if (DOSCREATEQUEUE (&queuehandle, 0, QUEUENAME)) {
  73.           puts ("FINDDEMO: Cannot create new queue") ;
  74.           DOSEXIT (1, 1) ;
  75.           }
  76.      if (DOSCREATETHREAD (dispthread, &dispID, dispstack 
  77.                           + THREADSTACK) ||
  78.          DOSCREATETHREAD (waitthread, &waitID, waitstack 
  79.                           + THREADSTACK)) {
  80.           puts ("FINDDEMO: Cannot create threads") ;
  81.           DOSEXIT (1, 1) ;
  82.           }
  83.      displayheadings () ;
  84.  
  85.                /*
  86.                     Main Loop: Display prompt and read keyboard.
  87.                     ---------  Execute FINDER.EXE.
  88.                */
  89.      do   {
  90.           VIOSETCURPOS (18, 0, 0) ;
  91.           VIOWRTTTY (prompt, sizeof prompt - 1, 0) ;
  92.           KBDCHARIN (&keydata, 0, 0) ;
  93.  
  94.           index = keydata.char_code - '1' ;
  95.  
  96.           if (index <= NUMPROC && rc[index].TermCode_PID == 0) {
  97.                VIOWRTTTY (&keydata.char_code, 1, 0) ;
  98.                VIOWRTNCHAR (" ", 77, 7 + index, 3, 0) ;
  99.                do   {
  100.                     VIOSETCURPOS (7 + index, 3, 0) ;
  101.                     len = 13 ;
  102.                     KBDSTRINGIN (dirmask, &len, 0, 0) ;
  103.                     }
  104.                while (len == 0) ;
  105.  
  106.                dirmask [len] = '\0' ;
  107.                executeprogram (index, dirmask) ;
  108.                }
  109.           }
  110.      while (keydata.char_code != 27) ;
  111.  
  112.                /*
  113.                     Clean-up: Kill all existing FINDER.EXE processes.
  114.                     --------  Wait for processes to terminate.
  115.                               Close the queue and exit.
  116.                */
  117.  
  118.      for (index = 0 ; index < NUMPROC ; index++)
  119.           if (rc[index].TermCode_PID)
  120.                DOSKILLPROCESS (0, rc[index].TermCode_PID) ;
  121.  
  122.      for (index = 0 ; index < NUMPROC ; index++)
  123.           DOSSEMWAIT ((DWORD) &runsem [index], -1L) ;
  124.  
  125.      DOSCLOSEQUEUE (queuehandle) ;
  126.      DOSEXIT (1, 0) ;
  127.      }
  128.  
  129. displayheadings ()
  130.      {
  131.      static char heading  [] = "286DOS File Finder Demo Program",
  132.                  colheads [] = "Dir Mask     Status  Files",
  133.                  colunder [] = "--------     ------  -----" ;
  134.      char        buffer  [5] ;
  135.      WORD        row, col, i, len ;
  136.  
  137.      VIOGETCURPOS (&row, &col, 0) ;              /* get current attr */
  138.      VIOWRTTTY (" ", 1, 0) ;
  139.      len = 2 ;
  140.      VIOREADCELLSTR (buffer, &len, row, col, 0) ;
  141.      VIOSCROLLUP (0, 0, -1, -1, -1, buffer, 0) ;     /* clear screen */
  142.  
  143.      len = sizeof heading - 1 ;
  144.      col = (80 - len) / 2 ;
  145.      VIOWRTCHARSTR (heading, len, 1, col, 0) ;            /* heading */
  146.      VIOWRTNCHAR   ("\xC6",   1, 2, col - 1,   0) ;     /* underline */
  147.      VIOWRTNCHAR   ("\xCD", len, 2, col,       0) ;
  148.      VIOWRTNCHAR   ("\xB5",   1, 2, col + len, 0) ;
  149.      VIOWRTCHARSTR (colheads, sizeof colheads - 1, 5, 3, 0) ; 
  150.      VIOWRTCHARSTR (colunder, sizeof colunder - 1, 6, 3, 0) ;
  151.  
  152.      for (i = 0 ; i < NUMPROC ; i++) {                    /* numbers */
  153.           sprintf (buffer, "%d.", i + 1) ;
  154.           VIOWRTCHARSTR (buffer, 2, 7 + i, 0, 0) ;
  155.           }
  156.      }
  157.  
  158. executeprogram (index, dirmask)
  159.      WORD index ;
  160.      char *dirmask ;
  161.      {
  162.      char objbuf [32] ;
  163.      char args [128] ;
  164.  
  165.      strcat (strcpy (args, CHILDPROG), " ") ;      /* construct args */
  166.      strcat (strcat (args, dirmask), " ") ;
  167.      strcat (strcat (args, QUEUENAME), " ") ;
  168.      itoa (index, args + strlen (args), 10) ;
  169.  
  170.      count [index] = 0 ;                         /* initialize count */
  171.  
  172.      if (DOSEXECPGM (objbuf, 32, 2, args, 0, &rc[index], CHILDPROG))
  173.           {
  174.           puts ("FINDDEMO: Can't run FINDER.EXE") ;
  175.           DOSEXIT (1, 1) ;
  176.           }
  177.      VIOWRTCHARSTR ("Running", 7, index + 7, 16, 0) ;/* now executing */
  178.      DOSSEMSET   ((DWORD) &runsem [index]) ;
  179.      DOSSEMCLEAR ((DWORD) &waitsem[index]) ;
  180.      }
  181.  
  182. void far dispthread ()        /* thread to read messages from FINDER */
  183.      {                        /*   and display filenames.            */
  184.      DWORD request ;
  185.      WORD  len, index, i ;
  186.      char  far *farptr ;
  187.      char  priority, pathname [80], buffer [64] ;
  188.  
  189.      while (1) {
  190.           DOSREADQUEUE (queuehandle, &request, &len, 
  191.                          &(DWORD)farptr, 0, 0, &priority, 0L) ;
  192.           i = 0 ;
  193.           while (pathname [i++] = *farptr++) ;
  194.           index = (WORD) (request >> 16) ;
  195.           count [index] += len > 0 ;
  196.           sprintf (buffer, "%5d   %-48.48s", count [index], pathname) ;
  197.           VIOWRTCHARSTR (buffer, 56, 7 + index, 24, 0) ;
  198.           DOSFREESEG ((WORD) ((DWORD) farptr >> 16)) ;
  199.           }
  200.      }
  201.  
  202. void far waitthread ()     /* thread to wait for FINDER terminations */
  203.      {
  204.      WORD   index, PID ;
  205.      struct ResultCodes rescode ;
  206.      
  207.      while (1) {
  208.           DOSMUXSEMWAIT (&index, (WORD far *) &semtab, -1L) ;
  209.           DOSCWAIT (0, 0, &rescode, &PID, 0) ;
  210.  
  211.           for (index = 0 ; index < NUMPROC ; index++)  /* find index */
  212.                if (PID == rc[index].TermCode_PID) 
  213.                     break ;
  214.  
  215.           VIOWRTCHARSTR (rescode.TermCode_PID ? "Halted " : "Done   ",
  216.                               7, index + 7, 16, 0) ;
  217.           rc[index].TermCode_PID = 0 ;
  218.           DOSSEMCLEAR ((DWORD) &runsem [index]) ;
  219.           DOSSEMSET   ((DWORD) &waitsem[index]) ;
  220.           }
  221.      }
  222. ==============================================================================
  223.  
  224.  
  225.  
  226.  
  227.  
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236. ==============================================================================
  237. ==============================================================================
  238. Figure 3: FINDER.C
  239.  
  240. ==============================================================================
  241.  
  242. /* finder.c -- child process of finddemo */
  243.  
  244. #include <doscall.h>
  245.  
  246. unsigned index ;
  247. unsigned queuehandle ;
  248. unsigned parentPID ;
  249.  
  250. main (argc, argv)
  251.      int  argc ;
  252.      char *argv [] ;
  253.      {
  254.      if (argc < 4) {
  255.           puts ("Run FINDDEMO rather than FINDER") ;
  256.           DOSEXIT (1, 1) ;
  257.           }
  258.      if (DOSOPENQUEUE (&parentPID, &queuehandle, argv [2])) {
  259.           puts ("FINDER: Cannot open queue") ;
  260.           DOSEXIT (1, 1) ;
  261.           }
  262.      index = atoi (argv [3]) ;
  263.  
  264.      writequeue ("") ;
  265.      chdir ("\\") ;
  266.      find (argv [1]) ;
  267.      writequeue ("") ;
  268.  
  269.      DOSCLOSEQUEUE (queuehandle) ;
  270.      DOSEXIT (1, 0) ;
  271.      }
  272.  
  273. find (searchstr)
  274.      char     *searchstr ;
  275.      {
  276.      struct   FileFindBuf ffb ;
  277.      char     cwd [81], pathname [100] ;
  278.      unsigned handle = 0xFFFF, num = 1 ;
  279.  
  280.      if (cwd [strlen (getcwd (cwd, 80)) - 1] != '\\')
  281.           strcat (cwd, "\\") ;
  282.  
  283.      DOSFINDFIRST (searchstr, &handle, 7, &ffb, sizeof ffb, &num, 0L) ;
  284.      while (num) {
  285.           writequeue (strcat (strcpy (pathname, cwd), ffb.file_name)) ;
  286.           DOSFINDNEXT (handle, &ffb, sizeof ffb, &num) ;
  287.           }
  288.      DOSFINDCLOSE (handle) ;
  289.  
  290.      handle = 0xFFFF ;
  291.      num  = 1 ;
  292.      DOSFINDFIRST ("*.*", &handle, 0x17, &ffb, sizeof ffb, &num, 0L) ;
  293.      while (num) {
  294.           if (ffb.attributes & 0x10 && ffb.file_name [0] != '.') {
  295.                chdir (ffb.file_name) ;
  296.                find (searchstr) ;
  297.                chdir ("..") ;
  298.                }
  299.           DOSFINDNEXT (handle, &ffb, sizeof ffb, &num) ;
  300.           }
  301.      DOSFINDCLOSE (handle) ;
  302.      }
  303.  
  304. writequeue (str)
  305.      char *str ;
  306.      {
  307.      unsigned selector, parentselector ;
  308.      char far *farptr ;
  309.      int      len = strlen (str) ;
  310.  
  311.      DOSALLOCSEG (len + 1, &selector, 1) ;
  312.      farptr = (char far *) (((unsigned long) selector) << 16) ;
  313.  
  314.      while (*farptr++ = *str++) ;
  315.  
  316.      DOSGIVESEG (selector, parentPID, &parentselector) ;
  317.      DOSFREESEG (selector) ;
  318.      farptr = (char far *) (((unsigned long) parentselector) << 16) ;
  319.  
  320.      DOSWRITEQUEUE (queuehandle, index, len, farptr, 0) ;
  321.      }
  322. ==============================================================================
  323.  
  324.  
  325.  
  326.  
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335. ==============================================================================
  336. ==============================================================================
  337. Figure 4: FINDDEMO.DEF
  338.  
  339. ==============================================================================
  340.  
  341. NAME           FINDDEMO
  342. DESCRIPTION    'File Finder Demonstration Program'
  343. PROTMODE 
  344. DATA           MOVABLE 
  345. CODE           MOVABLE PURE
  346. HEAPSIZE       2048
  347. STACKSIZE      4096
  348. ==============================================================================
  349.  
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361. ==============================================================================
  362. ==============================================================================
  363. Figure 5: FINDER.DEF
  364.  
  365. ==============================================================================
  366.  
  367. NAME         FINDER
  368. DESCRIPTION     'File Finder Module for FINDDEMO'
  369. PROTMODE
  370. DATA         MOVABLE 
  371. CODE         MOVABLE PURE
  372. HEAPSIZE     2048
  373. STACKSIZE     8192
  374. ==============================================================================
  375.  
  376.  
  377.  
  378.  
  379.  
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386.  
  387. ==============================================================================
  388. ==============================================================================
  389. Figure 7: Make-file for FINDDEMO.EXE and FINDER.EXE
  390.  
  391. ==============================================================================
  392.  
  393. finddemo.obj  :  finddemo.
  394.     cl -c -G2 -Zp finddemo.c
  395.  
  396. finddemo.exe  :  finddemo.obj finddemo.def
  397.     link finddemo, /align:16, /map, doscalls slibc5, finddemo.def
  398.  
  399. finder.obj  :  findef.c
  400.     cl -c -G2 -Zp finder.c
  401.  
  402. finder.exe  :  finder.obj finder.def
  403.     link finder, /align:16, /map, doscalls slibc5, finder.def
  404. ==============================================================================
  405.