home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / online / source / c / compilers / Tickle-4.0.sit.hqx / Tickle-4.0 / src / hfs_action.c < prev    next >
Text File  |  1993-11-18  |  17KB  |  636 lines

  1.  
  2. /*
  3. ** This source code was written by Tim Endres
  4. ** Email: time@ice.com.
  5. ** USMail: 8840 Main Street, Whitmore Lake, MI  48189
  6. **
  7. ** Some portions of this application utilize sources
  8. ** that are copyrighted by ICE Engineering, Inc., and
  9. ** ICE Engineering retains all rights to those sources.
  10. **
  11. ** Neither ICE Engineering, Inc., nor Tim Endres, 
  12. ** warrants this source code for any reason, and neither
  13. ** party assumes any responsbility for the use of these
  14. ** sources, libraries, or applications. The user of these
  15. ** sources and binaries assumes all responsbilities for
  16. ** any resulting consequences.
  17. */
  18.  
  19. #pragma segment HFSAction
  20.  
  21. #include "tickle.h"
  22. #include <DiskInit.h>
  23. #include <OSEvents.h>
  24.  
  25. extern int    errno;
  26.  
  27. #define HFS_SKIP_DIR                        (-64)
  28.  
  29. #define HFS_RECURSIVE                        0x0100
  30.  
  31. #define HFS_FILES                            0x0001
  32. #define HFS_FOLDERS                            0x0002
  33. #define HFS_FILES_AND_FOLDERS                ( HFS_FILES        | HFS_FOLDERS )
  34.  
  35. #define HFS_FILES_RECURSIVELY                ( HFS_FILES        | HFS_RECURSIVE)
  36. #define HFS_FOLDERS_RECURSIVELY                ( HFS_FOLDERS    | HFS_RECURSIVE)
  37. #define HFS_FILES_AND_FOLDERS_RECURSIVELY    ( HFS_FILES        | HFS_FOLDERS    | HFS_RECURSIVE)
  38.  
  39.  
  40. #define HFS_DO_FILES(FLAGS)            ( ( (FLAGS) & HFS_FILES )        != 0 )
  41. #define HFS_DO_FOLDERS(FLAGS)        ( ( (FLAGS) & HFS_FOLDERS )        != 0 )
  42. #define HFS_DO_RECURSIVELY(FLAGS)    ( ( (FLAGS) & HFS_RECURSIVE )    != 0 )
  43.  
  44. extern void SProgressCounting();
  45.  
  46. static int            count_progress_count = 0;
  47. static int            total_count = 0;
  48. static int            current_count = 0;
  49. static short        hfs_process_first_folder = 0;
  50.  
  51. extern long            progress_pos, progress_start;
  52.  
  53. void
  54. SProgressActionProc(message, start, end, pos)
  55. char    *message;
  56. int        start;
  57. int        end;
  58. int        pos;
  59. {
  60. #pragma unused (pos)
  61.  
  62.     sprintf(message, "Finished %d of %d files...",
  63.             (progress_pos - progress_start), (end - start));
  64.     }
  65.  
  66.  
  67. HFSSetFileInfo(cpb, parent, vRefNum, dirID, filename, action_data, action_ptr)
  68. CInfoPBPtr    cpb;
  69. CInfoPBPtr    parent;
  70. int            vRefNum;
  71. long        dirID;
  72. char        *filename;            /* C string */
  73. long        action_data;
  74. char        *action_ptr;
  75. {
  76. int                result;
  77. char            pname[32];
  78. HParamBlockRec    hpb;
  79.  
  80. #pragma unused (parent, action_ptr)
  81.  
  82.     strcpy(pname, filename); c2pstr(pname);
  83.     
  84.     hpb.fileParam.ioCompletion    = 0;
  85.     hpb.fileParam.ioFVersNum    = 0;
  86.     hpb.fileParam.ioFDirIndex    = 0;
  87.     hpb.fileParam.ioNamePtr        = pname;
  88.     hpb.fileParam.ioVRefNum        = vRefNum;
  89.     hpb.fileParam.ioDirID        = dirID;
  90.     hpb.fileParam.ioFlAttrib    = cpb->hFileInfo.ioFlAttrib;
  91.     hpb.fileParam.ioFlFndrInfo    = cpb->hFileInfo.ioFlFndrInfo;
  92.     hpb.fileParam.ioFlCrDat        = cpb->hFileInfo.ioFlCrDat;
  93.     hpb.fileParam.ioFlMdDat        = cpb->hFileInfo.ioFlMdDat;
  94.     
  95.     if (action_ptr == NULL)
  96.         hpb.fileParam.ioFlFndrInfo.fdType = (OSType)action_data;
  97.     else
  98.         hpb.fileParam.ioFlFndrInfo.fdCreator = (OSType)action_data;
  99.     
  100.     result = PBHSetFInfo(&hpb, FALSE);
  101.     
  102.     return result;
  103.     }
  104.  
  105. HFSSetFolderView(cpb, parent, vRefNum, dirID, filename, action_data, action_ptr)
  106. CInfoPBPtr    cpb;
  107. CInfoPBPtr    parent;
  108. int            vRefNum;
  109. long        dirID;
  110. char        *filename;            /* C string */
  111. long        action_data;
  112. char        *action_ptr;
  113. {
  114. int            result;
  115. int            saveindex;
  116. char        *savename;
  117. #pragma unused (parent, vRefNum, dirID, filename, action_ptr)
  118.  
  119.     savename = cpb->dirInfo.ioNamePtr;
  120.     saveindex = cpb->dirInfo.ioFDirIndex;
  121.     
  122.     cpb->dirInfo.ioDrUsrWds.frView = (short)(action_data & 0x0000FFFF);
  123.     cpb->dirInfo.ioNamePtr = NULL;
  124.     cpb->dirInfo.ioFDirIndex = -1;
  125.     
  126.     result = PBSetCatInfo(cpb, FALSE);
  127.     
  128.     cpb->dirInfo.ioNamePtr = savename;
  129.     cpb->dirInfo.ioFDirIndex = saveindex;
  130.     
  131.     return result;
  132.     }
  133.  
  134. HFSPrintInfo(cpb, parent, vRefNum, dirID, filename, action_data, action_ptr)
  135. CInfoPBPtr    cpb;
  136. CInfoPBPtr    parent;
  137. int            vRefNum;
  138. long        dirID;
  139. char        *filename;            /* C string */
  140. long        action_data;
  141. char        *action_ptr;
  142. {
  143. #pragma unused (parent, vRefNum, dirID, action_data, action_ptr)
  144.  
  145.     if ((cpb->hFileInfo.ioFlAttrib & ioDirMask) != 0) {
  146.         /* DIR */
  147.         Feedback("");
  148.         SetPort(theFeedbackWindow);
  149.         TextFace(bold);
  150.         Feedback("DIR  %s", filename);
  151.         SetPort(theFeedbackWindow);
  152.         TextFace(normal);
  153.         Feedback("     ID=%ld ParID=%ld vRef=%d flAttrib x%04X numFls %ld ",
  154.                     cpb->dirInfo.ioDrDirID, cpb->dirInfo.ioDrParID, cpb->dirInfo.ioVRefNum,
  155.                     cpb->dirInfo.ioFlAttrib, cpb->dirInfo.ioDrNmFls);
  156.         Feedback("     DInfo: RECT T%d L%d B%d R%d ",
  157.                     cpb->dirInfo.ioDrUsrWds.frRect.top, cpb->dirInfo.ioDrUsrWds.frRect.left,
  158.                     cpb->dirInfo.ioDrUsrWds.frRect.bottom, cpb->dirInfo.ioDrUsrWds.frRect.right);
  159.         Feedback("     DInfo: Flags x%04X View x%04X Loc H%d V%d ",
  160.                     cpb->dirInfo.ioDrUsrWds.frFlags, cpb->dirInfo.ioDrUsrWds.frView,
  161.                     cpb->dirInfo.ioDrUsrWds.frLocation.h, cpb->dirInfo.ioDrUsrWds.frLocation.v);
  162.         Feedback("     DXInfo: OpenChain %ld PutAway %ld  Comment %d Scroll H%d V%d ",
  163.                     cpb->dirInfo.ioDrFndrInfo.frOpenChain, cpb->dirInfo.ioDrFndrInfo.frPutAway,
  164.                     cpb->dirInfo.ioDrFndrInfo.frComment,
  165.                     cpb->dirInfo.ioDrFndrInfo.frScroll.h, cpb->dirInfo.ioDrFndrInfo.frScroll.v);
  166.         }
  167.     else {
  168.         /* FILE */
  169.         SetPort(theFeedbackWindow);
  170.         TextFace(bold);
  171.         Feedback("FILE %s", filename);
  172.         SetPort(theFeedbackWindow);
  173.         TextFace(normal);
  174.         Feedback("     DirID=%ld ParID=%ld vRef=%d flAttrib x%04X refNum %ld ",
  175.                     cpb->hFileInfo.ioDirID, cpb->hFileInfo.ioFlParID,
  176.                     cpb->hFileInfo.ioVRefNum, cpb->hFileInfo.ioFlAttrib, cpb->hFileInfo.ioFRefNum);
  177.         Feedback("     Type '%4.4s' Creator '%4.4s' IconID %ld Cmt %ld PutAway %ld ",
  178.                     &cpb->hFileInfo.ioFlFndrInfo.fdType, &cpb->hFileInfo.ioFlFndrInfo.fdCreator,
  179.                     cpb->hFileInfo.ioFlXFndrInfo.fdIconID, cpb->hFileInfo.ioFlXFndrInfo.fdComment,
  180.                     cpb->hFileInfo.ioFlXFndrInfo.fdPutAway);
  181.         Feedback("     fdFlags x%04X fdFldr %d Location H%d V%d ",
  182.                     cpb->hFileInfo.ioFlFndrInfo.fdFlags, cpb->hFileInfo.ioFlFndrInfo.fdFldr,
  183.                     cpb->hFileInfo.ioFlFndrInfo.fdLocation.h,
  184.                     cpb->hFileInfo.ioFlFndrInfo.fdLocation.v);
  185.         }
  186.     
  187.     return noErr;
  188.     }
  189.  
  190. show_file_info()
  191. {
  192.     ShowFeedback();
  193.     SetPort(theFeedbackWindow);
  194.     TextFace(underline);
  195.     Feedback("Show File Information");
  196.     SetPort(theFeedbackWindow);
  197.     TextFace(normal);
  198.     
  199.     hfs_process_first_folder = 0;
  200.     HFSApplyTo(HFSPrintInfo, 0, NULL, "Show Info", HFS_FILES_RECURSIVELY, 0);
  201.     }
  202.  
  203. show_folder_info()
  204. {
  205.     ShowFeedback();
  206.     SetPort(theFeedbackWindow);
  207.     TextFace(underline);
  208.     Feedback("Show Folder Information");
  209.     SetPort(theFeedbackWindow);
  210.     TextFace(normal);
  211.  
  212.     hfs_process_first_folder = 1;
  213.     HFSApplyTo(HFSPrintInfo, 0, NULL, "Show Info", HFS_FOLDERS_RECURSIVELY, 0);
  214.     }
  215.  
  216. show_file_and_folder_info()
  217. {
  218.     ShowFeedback();
  219.     SetPort(theFeedbackWindow);
  220.     TextFace(underline);
  221.     Feedback("Show File and Folder Information");
  222.     SetPort(theFeedbackWindow);
  223.     TextFace(normal);
  224.  
  225.     hfs_process_first_folder = 1;
  226.     HFSApplyTo(HFSPrintInfo, 0, NULL, "Show Info", HFS_FILES_AND_FOLDERS_RECURSIVELY, 0);
  227.     }
  228.  
  229. set_folder_views()
  230. {
  231. long    view;
  232.  
  233.     view = GetFolderView(0x0100);
  234.     if (view != 0) {
  235.         ShowFeedback();
  236.         SetPort(theFeedbackWindow);
  237.         TextFace(underline);
  238.         Feedback("Show File and Folder Information");
  239.         SetPort(theFeedbackWindow);
  240.         TextFace(normal);
  241.     
  242.         hfs_process_first_folder = 1;
  243.         HFSApplyTo(HFSSetFolderView, view, NULL, "Folder View", HFS_FOLDERS_RECURSIVELY, 1);
  244.         }
  245.     }
  246.  
  247. HFSApplyTo(action_proc, action_data, action_ptr, action_name, apply_to, verbose)
  248. PFI            action_proc;
  249. long        action_data;
  250. char        *action_ptr;
  251. char        *action_name;
  252. int            apply_to;
  253. int            verbose;
  254. {
  255. int            result;
  256. short        vRefNum;
  257. long        dirID;
  258. char        this_folder[32];
  259. char        from_path[256];
  260. CInfoPBRec    cpb;
  261. void        SProgressActionProc();
  262.  
  263.     yield_menus(YIELD_ON);
  264.     
  265.     if (! GetFolderPathName(action_name, from_path, &vRefNum, &dirID))
  266.         {
  267.         yield_menus(YIELD_OFF);
  268.         return;
  269.         }
  270.     
  271.     Feedback("Path '%s' vRef %d DirID %ld\n", from_path, vRefNum, dirID);
  272.     
  273.     cpb.hFileInfo.ioCompletion = 0;            /* Synchronous */
  274.     cpb.hFileInfo.ioNamePtr = this_folder; this_folder[0] = 0;
  275.     cpb.hFileInfo.ioVRefNum = vRefNum;        /* Returned here */
  276.     cpb.hFileInfo.ioFDirIndex = -1;            /* Get the directory in ioDirID */
  277.     cpb.hFileInfo.ioDirID = dirID;            /* same offset as ioFlNum */
  278.     result = PBGetCatInfo(&cpb, (Boolean)0);/* Synchronous */
  279.     
  280.     total_count = hfs_object_count(vRefNum, dirID, apply_to);
  281.  
  282.     if (total_count == CANCEL) {
  283.         Feedback("%s canceled by user.", action_name);
  284.         yield_menus(YIELD_OFF);
  285.         return;
  286.         }
  287.     if (total_count == FAILURE) {
  288.         Feedback("Error counting files to %s.", action_name);
  289.         yield_menus(YIELD_OFF);
  290.         return;
  291.         }
  292.     
  293.     current_count = 0;
  294.     Feedback("Total files to %s = %d.", action_name, total_count);
  295.     
  296.     c2pstr(action_name);
  297.     StartProgressWindow( action_name, 0, total_count, 0, SProgressActionProc);
  298.     p2cstr(action_name);
  299.  
  300.     result = do_hfs_action( vRefNum, dirID, apply_to,
  301.                             action_proc, action_name, action_data, action_ptr, verbose );
  302.     
  303.     StopProgressWindow();
  304.  
  305.     if (result == SUCCESS)
  306.         Feedback("%s of '%sƒ' completed.", action_name, from_path);
  307.     else if (result == CANCEL)
  308.         Feedback("%s of '%sƒ' canceled by user.", action_name, from_path);
  309.     else
  310.         message_alert("%s of '%sƒ' failed [%d].", action_name, from_path, result);
  311.     
  312.     yield_menus(YIELD_OFF);
  313.     
  314.     InitCursor();
  315.     }
  316.  
  317. hfs_set_file_info(creator)
  318. int                creator;
  319. {
  320. int                result;
  321. short            vRefNum;
  322. long            dirID;
  323. OSType            fdCreator;
  324. char            creator_str[32];
  325. char            this_folder[32];
  326. char            from_path[256];
  327. CInfoPBRec        cpb;
  328. void            SProgressActionProc();
  329.  
  330.     yield_menus(YIELD_ON);
  331.     
  332.     if (! GetFolderPathName("Set File Info...", from_path, &vRefNum, &dirID))
  333.         {
  334.         yield_menus(YIELD_OFF);
  335.         return;
  336.         }
  337.     
  338.     Feedback("Path '%s' vRef %d DirID %ld\n", from_path, vRefNum, dirID);
  339.     
  340.     cpb.hFileInfo.ioCompletion = 0;                /* Synchronous */
  341.     cpb.hFileInfo.ioNamePtr = this_folder; this_folder[0] = 0;
  342.     cpb.hFileInfo.ioVRefNum = vRefNum;        /* Returned here */
  343.     cpb.hFileInfo.ioFDirIndex = -1;                /* Get the directory in ioDirID */
  344.     cpb.hFileInfo.ioDirID = dirID;            /* same offset as ioFlNum */
  345.     result = PBGetCatInfo(&cpb, (Boolean)0);    /* Synchronous */
  346.     
  347.     strcpy(creator_str, ( creator ? "MPS " : "TEXT" ));
  348.     if (! GetInputLine( ( creator ? "New Creator:" : "New Type:" ), creator_str))
  349.         {
  350.         yield_menus(YIELD_OFF);
  351.         return;
  352.         }
  353.     
  354.     sprintf((char *)&fdCreator, "%4.4s", creator_str);
  355.     
  356.     total_count = hfs_object_count(vRefNum, dirID, HFS_FILES_RECURSIVELY);
  357.  
  358.     if (total_count == CANCEL) {
  359.         Feedback("Change canceled by user.");
  360.         yield_menus(YIELD_OFF);
  361.         return;
  362.         }
  363.     if (total_count == FAILURE) {
  364.         Feedback("Error counting the files to be changed.");
  365.         yield_menus(YIELD_OFF);
  366.         return;
  367.         }
  368.     
  369.     current_count = 0;
  370.     Feedback("Total files to change = %d.", total_count);
  371.     
  372.     StartProgressWindow( ( creator ? "\pChange Creator" : "\pChange Type" ),
  373.                             0, total_count, 0, SProgressActionProc);
  374.  
  375.     result = do_hfs_action( vRefNum, dirID, HFS_FILES_RECURSIVELY, HFSSetFileInfo,
  376.                             ( creator ? "Set Creator" : "Set Type" ),
  377.                             fdCreator, ( creator ? (char *)-1 : NULL ), 1 );
  378.     
  379.     StopProgressWindow();
  380.  
  381.     if (result == SUCCESS)
  382.         Feedback("%s change to '%sƒ' completed.",
  383.                     ( creator ? "Creator" : "Type" ), from_path);
  384.     else if (result == CANCEL)
  385.         Feedback("%s change to '%sƒ' canceled by user.",
  386.                     ( creator ? "Creator" : "Type" ), from_path);
  387.     else
  388.         message_alert("%s change to '%sƒ' failed [%d].",
  389.                         ( creator ? "Creator" : "Type" ), from_path, result);
  390.     
  391.     yield_menus(YIELD_OFF);
  392.     
  393.     InitCursor();
  394.     }
  395.  
  396. do_hfs_action(vRefNum, dirID, apply_to, action_proc, action_name, action_data, action_ptr, verbose)
  397. int            vRefNum;
  398. long        dirID;
  399. int            apply_to;
  400. PFI            action_proc;
  401. char        *action_name;
  402. long        action_data;
  403. char        *action_ptr;
  404. int            verbose;
  405. {
  406. short            index, myresult;
  407. CInfoPBRec        cpb, parent;
  408. char            myname[48],
  409.                 cname[48],
  410.                 thisfolder[48];
  411.  
  412.     DoYield();
  413.     
  414.     thisfolder[0] = 0;
  415.     parent.hFileInfo.ioCompletion = 0;                /* Synchronous */
  416.     parent.hFileInfo.ioNamePtr = thisfolder;        /* Space for *returned* name */
  417.     parent.hFileInfo.ioVRefNum = vRefNum;            /* Returned here */
  418.     parent.hFileInfo.ioFDirIndex = -1;                /* Get the directory in ioDirID */
  419.     parent.hFileInfo.ioDirID = dirID;                /* same offset as ioFlNum */
  420.     myresult = PBGetCatInfo(&parent, (Boolean)0);    /* Synchronous */
  421.     
  422.     if (myresult != noErr) {
  423.         Feedback("do_hfs_action: PBGetCatInfo(%d, %d) = %d\n", vRefNum, dirID, myresult);
  424.         return myresult;
  425.         }
  426.  
  427.     if (hfs_process_first_folder) {
  428.         if (HFS_DO_FOLDERS(apply_to)) {
  429.             sprintf(cname, "%.*s", thisfolder[0], &thisfolder[1]);
  430.             if (verbose)
  431.                 Feedback("%s '%s'...", action_name, cname);
  432.             
  433.             myresult = (*action_proc) (&parent, NULL, vRefNum, dirID,
  434.                                         cname, action_data, action_ptr);
  435.             
  436.             UpdateProgress(++current_count);
  437.             
  438.             if (myresult != noErr && myresult != HFS_SKIP_DIR) {
  439.                 Feedback("Error #%d %s folder '%s'.", myresult, action_name, cname);
  440.                 return myresult;
  441.                 }
  442.             }
  443.         }
  444.     hfs_process_first_folder = 0;
  445.     
  446.     cancel_current_op = 0;
  447.     for (index=1 ; ! cancel_current_op ; index++) {
  448.     
  449.         DoYield();
  450.         
  451.         if (pause_op)
  452.             while (pause_op)
  453.                 pausing();
  454.         
  455.         if (cancel_current_op)
  456.             break;
  457.         
  458.         /*
  459.         **
  460.         **     GET INFO OF NEXT OBJECT...
  461.         ** 
  462.         */
  463.         
  464.         cpb.hFileInfo.ioCompletion = 0;                    /* Synchronous */
  465.         cpb.hFileInfo.ioNamePtr = myname; myname[0] = 0;
  466.         cpb.hFileInfo.ioVRefNum = vRefNum;                /* Returned here */
  467.         cpb.hFileInfo.ioFDirIndex = index;                /* Get the ith file/directory */
  468.         cpb.hFileInfo.ioDirID = dirID;                    /* same offset as ioFlNum */
  469.         myresult = PBGetCatInfo(&cpb, (Boolean)false);    /* Synchronous */
  470.         if (cpb.hFileInfo.ioResult == fnfErr)
  471.             {
  472.             return SUCCESS;
  473.             }
  474.         
  475.         if (cpb.hFileInfo.ioResult != noErr)
  476.             {
  477.             Feedback("do_hfs_action: PBGetCatInfo(%d, %d, #%d) = %d\n",
  478.                         vRefNum, dirID, index, myresult);
  479.             return myresult;
  480.             }
  481.         
  482.         /*
  483.         **
  484.         **     PROCESS OBJECT
  485.         ** 
  486.         */
  487.  
  488.         if ((cpb.hFileInfo.ioFlAttrib & ioDirMask) != 0)
  489.             {
  490.             /* This is a DIRECTORY. */
  491.             sprintf(cname, "%.*s", myname[0], &myname[1]);
  492.             myresult = SUCCESS;
  493.             if (HFS_DO_FOLDERS(apply_to)) {
  494.                 if (verbose)
  495.                     Feedback("%s '%s'...", action_name, cname);
  496.                 
  497.                 myresult = (*action_proc) (&cpb, &parent, vRefNum, dirID,
  498.                                             cname, action_data, action_ptr);
  499.                 
  500.                 UpdateProgress(++current_count);
  501.                 
  502.                 if (myresult != noErr && myresult != HFS_SKIP_DIR) {
  503.                     Feedback("Error #%d %s folder '%s'.", myresult, action_name, cname);
  504.                     return myresult;
  505.                     }
  506.                 }
  507.             
  508.             if (HFS_DO_RECURSIVELY(apply_to) && myresult != HFS_SKIP_DIR) {
  509.                 myresult = do_hfs_action(vRefNum, cpb.hFileInfo.ioDirID, apply_to,
  510.                                             action_proc, action_name, action_data, action_ptr, verbose);
  511.                 switch (myresult) {
  512.                     case FAILURE:
  513.                     case CANCEL:
  514.                         Feedback("Error #%d from do_hfs_action(%d, %d).",
  515.                                     myresult, vRefNum, cpb.hFileInfo.ioDirID);
  516.                         return myresult;
  517.                         break;
  518.                     }
  519.                 }
  520.             }
  521.         else
  522.             {
  523.             /* This is a FILE. */
  524.             sprintf(cname, "%.*s", myname[0], &myname[1]);
  525.             if (HFS_DO_FILES(apply_to)) {
  526.                 if (verbose)
  527.                     Feedback("%s '%s'...", action_name, cname);
  528.                 
  529.                 myresult = (*action_proc) (&cpb, &parent, vRefNum, dirID,
  530.                                             cname, action_data, action_ptr);
  531.                 
  532.                 UpdateProgress(++current_count);
  533.     
  534.                 if (myresult != noErr) {
  535.                     Feedback("Error #%d %s file '%s'.", myresult, action_name, cname);
  536.                     return myresult;
  537.                     }
  538.                 }
  539.             } /* got a file... */
  540.  
  541.         } /* for objects in directory... */
  542.     
  543.     return SUCCESS;
  544.     }
  545.  
  546. #define my_disk_item    69
  547.  
  548. hfs_object_count(vRefNum, dirID, count_what)
  549. {
  550. long    mycount;
  551.  
  552.     count_progress_count = 0;
  553.     StartProgressWindow("\pCount Files", 0, -1, 0, SProgressCounting);
  554.     
  555.     mycount = do_hfs_object_count(vRefNum, dirID, count_what);
  556.     
  557.     StopProgressWindow();
  558.     
  559.     return mycount;
  560.     }
  561.  
  562. do_hfs_object_count(vRefNum, dirID, count_what)
  563. int            vRefNum;
  564. long        dirID;
  565. int            count_what;
  566. {
  567. short            index, myresult;
  568. int                count = 0;
  569. CInfoPBRec        cpb;
  570. char            myname[48];
  571. char            thisfolder[48];
  572. void            SProgressCounting();
  573.  
  574.     DoYield();
  575.     
  576.     cpb.hFileInfo.ioCompletion = 0;                /* Synchronous */
  577.     cpb.hFileInfo.ioNamePtr = thisfolder; thisfolder[0] = 0;
  578.     cpb.hFileInfo.ioVRefNum = vRefNum;            /* Returned here */
  579.     cpb.hFileInfo.ioFDirIndex = -1;                /* Get the directory in ioDirID */
  580.     cpb.hFileInfo.ioDirID = dirID;                /* same offset as ioFlNum */
  581.     myresult = PBGetCatInfo(&cpb, (Boolean)0);    /* Synchronous */
  582.     
  583.     if (hfs_process_first_folder)
  584.         count++;
  585.     
  586.     for (index=1 ; ! cancel_current_op ; index++) {
  587.     
  588.         DoYield();
  589.         
  590.         if (pause_op)
  591.             while (pause_op)
  592.                 pausing();
  593.         
  594.         if (cancel_current_op)
  595.             break;
  596.         
  597.         cpb.hFileInfo.ioCompletion = 0;                    /* Synchronous */
  598.         cpb.hFileInfo.ioNamePtr = myname; myname[0] = 0;
  599.         cpb.hFileInfo.ioVRefNum = vRefNum;                /* Returned here */
  600.         cpb.hFileInfo.ioFDirIndex = index;                /* Get the ith file/directory */
  601.         cpb.hFileInfo.ioDirID = dirID;                    /* same offset as ioFlNum */
  602.         myresult = PBGetCatInfo(&cpb, (Boolean)false);    /* Synchronous */
  603.         if (cpb.hFileInfo.ioResult == fnfErr)
  604.             {
  605.             return count;
  606.             }
  607.         if (cpb.hFileInfo.ioResult != noErr)
  608.             {
  609.             /* This is an ERROR. */
  610.             Feedback("Error #%d PBGetCatInfo(%d)!", cpb.hFileInfo.ioResult, index);
  611.             return FAILURE;
  612.             }
  613.         else if ((cpb.hFileInfo.ioFlAttrib & ioDirMask) > 0)
  614.             {
  615.             /* This is a DIRECTORY. */
  616.             UpdateProgress(++count_progress_count);
  617.             
  618.             if (HFS_DO_FOLDERS(count_what))
  619.                 count++;
  620.             
  621.             count += do_hfs_object_count(vRefNum, cpb.hFileInfo.ioDirID, count_what);
  622.             }
  623.         else
  624.             {
  625.             /* This is a FILE. */
  626.             if (HFS_DO_FILES(count_what))
  627.                 count++;
  628.             if ((++count_progress_count & 8) != 0)
  629.                 UpdateProgress(count_progress_count);
  630.             } /* got a file... */
  631.  
  632.         } /* for file in directory... */
  633.     
  634.     return count;
  635.     }
  636.