home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / Information / CSMP Digest / volume 1 / csmp-v1-206.txt < prev    next >
Encoding:
Text File  |  1994-12-08  |  33.1 KB  |  1,068 lines  |  [TEXT/R*ch]

  1. C.S.M.P. Digest             Tue, 03 Nov 92       Volume 1 : Issue 206
  2.  
  3. Today's Topics:
  4.  
  5.     Prefs file source code
  6.  
  7.  
  8.  
  9. The Comp.Sys.Mac.Programmer Digest is moderated by Michael A. Kelly.
  10.  
  11. The digest is a collection of article threads from the internet newsgroup
  12. comp.sys.mac.programmer.  It is designed for people who read c.s.m.p. semi-
  13. regularly and want an archive of the discussions.  If you don't know what a
  14. newsgroup is, you probably don't have access to it.  Ask your systems
  15. administrator(s) for details.  (This means you can't post questions to the
  16. digest.)
  17.  
  18. Each issue of the digest contains one or more sets of articles (called
  19. threads), with each set corresponding to a 'discussion' of a particular
  20. subject.  The articles are not edited; all articles included in this digest
  21. are in their original posted form (as received by our news server at
  22. cs.uoregon.edu).  Article threads are not added to the digest until the last
  23. article added to the thread is at least one month old (this is to ensure that
  24. the thread is dead before adding it to the digest).  Article threads that
  25. consist of only one message are generally not included in the digest.
  26.  
  27. The entire digest is available for anonymous ftp from ftp.cs.uoregon.edu
  28. [128.223.8.8] in the directory /pub/mac/csmp-digest.  Be sure to read the
  29. file /pub/mac/csmp-digest/README before downloading any files.  The most
  30. recent issues are available from sumex-aim.stanford.edu [36.44.0.6] in the
  31. directory /info-mac/digest/csmp.  If you don't have ftp capability, the sumex
  32. archive has a mail server; send a message with the text '$MACarch help' (no
  33. quotes) to LISTSERV@ricevm1.rice.edu for more information.
  34.  
  35. The digest is also available via email.  Just send a note saying that you
  36. want to be on the digest mailing list to mkelly@cs.uoregon.edu, and you will
  37. automatically receive each new issue as it is created.  Sorry, back issues
  38. are not available through the mailing list.
  39.  
  40. Send administrative mail to mkelly@cs.uoregon.edu.
  41.  
  42.  
  43. -------------------------------------------------------
  44.  
  45. From: Sproul@sproul.sproul.com (Mark Sproul)
  46. Subject: Prefs file source code
  47. Date: 29 Sep 92 08:05:41 GMT
  48. Organization: Sproul Consulting
  49.  
  50. Several people asked for this source code.  As explained in the comments,
  51. it came from Inside Mac Comm Toolbox and there is a lot of code dealing
  52. just with the Comm Tool box setup.  It now handles the PREFERENCES
  53. folder in the system folder properly.
  54.  
  55. I have done some additions to the code to make it more general and
  56. usable as far as dealing with preferences.  Such as GET pref and SET
  57. pref.  This code was all written and runs correctly with Think C 5.0.
  58.  
  59. Its been several months since I wrote this and was looking at it.
  60. I may have forgotten to mention something, if you have any problems
  61. let me know and I will post updates.
  62.  
  63. You need to define some things such as this:
  64.  
  65. #define    creatorType        'abcd'
  66. #define    fileType        'PREF'
  67. #define    prefsFileName    "\pMyPreferences"
  68.  
  69.  
  70.  
  71.  
  72.  
  73.  
  74. /******************************************************************************
  75. * adapted from
  76. *  Inside the Macintosh Communications Toolbox
  77. * Page  333
  78. * After initialization, the code shown first checks if a
  79. * preferences folder, which contains tool settings written in preference
  80. * files, already exists. If so, the application uses the settings in this file.
  81. * Otherwise, the code generates a new preferences file.
  82. ******************************************************************************
  83. * Modifications
  84. ******************************************************************************
  85. * Nov 27, 1991    Original version had a bug in it.
  86. *                If the "Preferences" directory already existed, the preferences file
  87. *                was placed in the system folder, not in the "Preferences" directory.
  88. *                If the directory did NOT exist, everything worked fine.
  89. *                I also changed it to check for the existance of the "Preferences" folder
  90. *                first instead of trying to create one and letting an duplicate file error
  91. *                indicate that it already existed.
  92. *                by Mark Sproul
  93. *                Internet: sproul@sproul.com
  94. *                AppleLink: Sproul.M
  95. * Jan 16, 1992    Working on a general purpose prefs file manipulator
  96. * Jan 25, 1992    Prefs file resources working great
  97. ******************************************************************************/
  98.  
  99. #include    <Connections.h>
  100. #include    <CommResources.h>
  101.  
  102. /*
  103. ** Global Variables used by all of the prefs routines
  104. */
  105. long            prefDirID;            /* Prefs Dir ID number */
  106. long            sysfDirID;            /* System folder Dir ID number */
  107. short            prefVRefNum;        /* Prefs Volume Ref number */
  108. short            prefFileOKFlag = 0;    /* prefs file OK indicator */
  109.  
  110. /*************************************************************
  111. * This makes sure there is a prefs file in the PREFERENCES directory
  112. * if not, it creates it.
  113. *
  114. * getPrefsFile MUST be called before any atempt at getting the prefs values
  115. *
  116. *************************************************************/
  117.  
  118. void getPrefsFile(prefsFileName, creatorType, fileType)
  119. Str255        prefsFileName;
  120. OSType        creatorType;
  121. OSType        fileType;
  122. {
  123. OSErr            osErr        = noErr;
  124. SysEnvRec        theWorld;
  125. CInfoPBPtr        infoPB;
  126. WDPBPtr            wdPB;
  127. HParmBlkPtr        dirPB;
  128.  
  129. short            prefRefNum;
  130. Point            where    = { 75, 75 };
  131. Str63            toolName;
  132. short            procID;
  133. Handle            h;
  134. Ptr                p;
  135.  
  136.  
  137. ConnHandle        prefConn;
  138.  
  139. ConnHandle        docConn;
  140. CMBufferSizes    sizes    = { 0, 0, 0, 0, 0, 0, 0, 0 };
  141.  
  142.  
  143.  
  144.     infoPB        = (CInfoPBPtr)NewPtrClear(sizeof(*infoPB));
  145.     wdPB        = (WDPBPtr)NewPtrClear(sizeof(*wdPB));
  146.     dirPB        = (HParmBlkPtr)NewPtrClear(sizeof(*dirPB));
  147.  
  148.  
  149.     /* find the system folder's volume reference number and directory ID */
  150.     osErr = SysEnvirons(curSysEnvVers, &theWorld);
  151.     (*wdPB).ioVRefNum = theWorld.sysVRefNum;
  152.  
  153.     if (noErr == (osErr = PBGetWDInfo(wdPB, false)))
  154.     {
  155.         /*********************************************************
  156.         * 11-27-91 Modified by Mark Sproul
  157.         **********************************************************/
  158.         /* get the Volume Reference Number and save it */
  159.         prefVRefNum    = (*wdPB).ioWDVRefNum;
  160.         /* get the System directir ID and save it */
  161.         sysfDirID    = (*wdPB).ioWDDirID;
  162.         
  163.         /* check for the preferences folder */
  164.         (*infoPB).hFileInfo.ioFDirIndex    = 0;
  165.         (*infoPB).hFileInfo.ioVRefNum    = prefVRefNum;
  166.         (*infoPB).hFileInfo.ioDirID        = sysfDirID;
  167.         (*infoPB).hFileInfo.ioNamePtr    = "\pPreferences";
  168.         osErr = PBGetCatInfo(infoPB, false);
  169.         /* save the "Preferecnces" dir number */ 
  170.         prefDirID    = (*infoPB).hFileInfo.ioDirID;
  171.         
  172.         if (osErr == fnfErr)
  173.         {
  174.             /* Create "Preferences" folder */
  175.             (*dirPB).fileParam.ioVRefNum    = prefVRefNum;
  176.             (*dirPB).fileParam.ioDirID        = sysfDirID;
  177.             (*dirPB).fileParam.ioNamePtr    = "\pPreferences";
  178.             osErr = PBDirCreate(dirPB, false);
  179.             prefDirID    = (*dirPB).fileParam.ioDirID;
  180.         }
  181.  
  182.         /*********************************************************
  183.         * end of modifications
  184.         **********************************************************/
  185.         if (osErr == noErr)
  186.         {
  187.             /* does the preference file exist? */
  188.             (*infoPB).hFileInfo.ioFDirIndex    = 0;
  189.             (*infoPB).hFileInfo.ioVRefNum    = prefVRefNum;
  190.             (*infoPB).hFileInfo.ioDirID        = prefDirID;
  191.             (*infoPB).hFileInfo.ioNamePtr    = prefsFileName;
  192.             osErr = PBGetCatInfo(infoPB, false);
  193.             if (osErr == noErr)
  194.             {
  195.                 /* set flag saying the prefs file is OK */
  196.                 prefFileOKFlag = 0xAA;
  197.             }
  198.             if (osErr == fnfErr)
  199.             {
  200.                 /* no, so create a new preference file */
  201.                 if (noErr == (osErr = HCreate(prefVRefNum, prefDirID, prefsFileName, creatorType, fileType)))
  202.                 {
  203.                     HCreateResFile(prefVRefNum, prefDirID, prefsFileName);
  204.                     if (noErr == (osErr = ResError()))
  205.                     {
  206.                         /* open the preference file */
  207.                         prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsFileName, fsRdWrPerm);
  208.                         if (prefRefNum == -1)
  209.                         {
  210.                             osErr = ResError();
  211.                         }
  212.                         else
  213.                         {
  214.                             /* create a default connection */
  215.                             osErr = CRMGetIndToolName(classCM, 1,toolName);
  216.                             if (noErr == osErr)
  217.                             {
  218.                                 prefConn = CMNew(CMGetProcID(toolName), cmData, sizes, 0, 0);
  219.                                 /* leave the default setting as the preferance */
  220.                                 
  221.                                 /************************************************************
  222.                                 * ORIGINALLY, the code let the user select setup at this point
  223.                                 * I do not want it asking for serial port prefs on startup
  224.                                 * if they are not set.
  225.                                 * ---allow the user to select a prefered tool and configuration
  226.                                 * ---osErr = CMChoose(&prefConn, where, nil);
  227.                                 ************************************************************/
  228.                             
  229.                                 /* write the prefered tool name to the preference file */
  230.                                 HLock((Handle) prefConn);
  231.                                 CMGetToolName((**prefConn).procID, toolName);
  232.                                 HUnlock((Handle) prefConn);
  233.                                 h = NewHandle(1 + toolName[0]);
  234.                                 HLock(h);
  235.                                 BlockMove(toolName, *h, GetHandleSize(h));
  236.                                 HUnlock(h);
  237.                                 AddResource(h, 'pTXT', 0, "");
  238.                                 ReleaseResource(h);
  239.                                 /* write the prefered configuration to the preference file */
  240.                                 p = CMGetConfig(prefConn);
  241.                                 h = NewHandle(GetPtrSize(p));
  242.                                 HLock(h);
  243.                                 BlockMove(p, *h, GetHandleSize(h));
  244.                                 HUnlock(h);
  245.                                 AddResource(h, 'cTXT', 0, "");
  246.                                 ReleaseResource(h);
  247.                                 DisposPtr(p);
  248.                                 
  249.                                 /* dispose of the connection */
  250.                                 CMDispose(prefConn);
  251.                             }
  252.                             /* close the file so that it can be used in a shared environment */
  253.                             CloseResFile(prefRefNum);
  254.                             /* set flag saying the prefs file is OK */
  255.                             prefFileOKFlag = 0xAA;
  256.                         }
  257.                     }
  258.                 }
  259.             }
  260.         }
  261.     }
  262. }
  263.  
  264. //*****************************************************************
  265. //*
  266. //* The following code was written by Mark Sproul
  267. //* This code allows easy access to prefs file
  268. //*
  269. //*
  270. //*
  271. //*
  272. //*****************************************************************
  273.  
  274. /**************************************
  275. * get resource from Prefs file
  276. *
  277. ****************************************/
  278. getPrefsResourceStr(prefsFileName, perfsResType, returnString)
  279. Str255        prefsFileName;
  280. OSType        perfsResType;
  281. Str255        returnString;
  282. {
  283. short            prefRefNum;
  284. Handle            h;
  285. int                i;
  286. Size            hSize;
  287.  
  288.     h = nil;
  289.     /* did the prefs file get opened or created OK */
  290.     if (prefFileOKFlag == 0xAA)
  291.     {
  292.         /* focus on the preference file */
  293.         prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsFileName, fsRdWrPerm);
  294.         if (prefRefNum != -1)
  295.         {
  296.             h = Get1Resource(perfsResType, 0);
  297.             hSize = GetHandleSize(h);            /* get the size of the handle */
  298.             if (hSize > 255) hSize = 255;
  299.             HLock(h);
  300.             /* had to have this to make it compile under THINK C 5.0 */
  301.             for (i=0; i< hSize; i++)
  302.             {
  303.                 returnString[i] = *(*h+i);
  304.             }
  305.             HUnlock(h);
  306.             ReleaseResource(h);
  307.             CloseResFile(prefRefNum);
  308.         }
  309.     }
  310. }
  311.  
  312.  
  313. /**************************************
  314. * set Comm Tool Box connection preference
  315. *
  316. ****************************************/
  317. setCTBpref(prefsFileName)
  318. Str255        prefsFileName;
  319. {
  320. short            prefRefNum;
  321. OSErr            osErr, cmChooseReturnCode;
  322. int                i;
  323. Str255            prefStr;
  324. short            procID;
  325. Str63            toolName;
  326. Handle            h;
  327. Ptr                p;
  328. short            iErr;
  329. Size            hSize, newSize;
  330.  
  331. ConnHandle        docConn;
  332. CMBufferSizes    sizes    = { 0, 0, 0, 0, 0, 0, 0, 0 };
  333. Point            where    = { 75, 75 };
  334.  
  335.     if (isCTBavailable())
  336.     {
  337.         /* did the prefs file get opened or created OK */
  338.         if (prefFileOKFlag == 0xAA)
  339.         {
  340.             getPrefsResourceStr(prefsFileName,'pTXT', prefStr);
  341.     
  342.             procID = CMGetProcID(prefStr);
  343.             if (procID != -1)
  344.             {
  345.                 /* create a new connection */
  346.                 docConn    = CMNew(procID, cmData, sizes, 0, 0);
  347.                 
  348.                 if (docConn != nil)
  349.                 {
  350.                     /* set the prefered configuration */
  351.         
  352.                     getPrefsResourceStr(prefsFileName,'cTXT', prefStr);
  353.                     osErr    = CMSetConfig(docConn, (char *)prefStr);
  354.     
  355.                     cmChooseReturnCode    = CMChoose(&docConn, where, nil);
  356.                 }
  357.             }
  358.             else
  359.             {
  360.                 /* the prefered tool could not be found so I */
  361.                 osErr    = CRMGetIndToolName(classCM, 1, toolName);
  362.                 docConn    = CMNew(CMGetProcID(toolName), cmData, sizes, 0, 0);
  363.                 if (docConn != nil)
  364.                 {
  365.                     cmChooseReturnCode    = CMChoose(&docConn, where, nil);
  366.                 }
  367.             }
  368.             
  369.             if ((cmChooseReturnCode == chooseOKMinor) || (cmChooseReturnCode == chooseOKMajor))
  370.             {
  371.                 /* change the prefs file */
  372.                 
  373.                 if (prefFileOKFlag == 0xAA)
  374.                 {
  375.                     /* open the preference file */
  376.                     prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsFileName, fsRdWrPerm);
  377.                     if (prefRefNum != -1)
  378.                     {
  379.                         /* write the prefered tool name to the preference file */
  380.                         HLock((Handle) docConn);
  381.                         CMGetToolName((**docConn).procID, toolName);
  382.                         HUnlock((Handle) docConn);
  383.                         
  384.                         /* get the port TeXT resource */
  385.                         h = Get1Resource('pTXT', 0);
  386.                         if (h == nil)
  387.                         {
  388.                             /* resource did not exist, add it to resource file */
  389.                             h = NewHandle(1 + toolName[0]);
  390.                             HLock(h);
  391.                             BlockMove(toolName, *h, GetHandleSize(h));
  392.                             HUnlock(h);
  393.                             AddResource(h, 'pTXT', 0, "");
  394.                         }
  395.                         else
  396.                         {
  397.                             /* resoure DOES exist, change it */
  398.                             hSize = GetHandleSize(h);            /* get the size of the handle */
  399.                             /* check for size of handle */
  400.                             if (hSize != (1 + toolName[0]))
  401.                             {
  402.                                 newSize = 1 + toolName[0];
  403.                                 SetHandleSize(h, newSize);
  404.                             }
  405.                             HLock(h);
  406.                             BlockMove(toolName, *h, GetHandleSize(h));
  407.                             HUnlock(h);
  408.                             ChangedResource(h);
  409.                         }
  410.                         ReleaseResource(h);
  411.                         
  412.                         /* write the prefered configuration to the preference file */
  413.                         p = CMGetConfig(docConn);
  414.     
  415.     
  416.                         /* get the configuration TeXT resource */
  417.                         h = Get1Resource('cTXT', 0);
  418.                         if (h == nil)
  419.                         {
  420.                             /* resource did not exist, add it to resource file */
  421.                             h = NewHandle(GetPtrSize(p));
  422.                             HLock(h);
  423.                             BlockMove(p, *h, GetHandleSize(h));
  424.                             HUnlock(h);
  425.                         
  426.                             AddResource(h, 'cTXT', 0, "");
  427.                             iErr = ResError();
  428.                         }
  429.                         else
  430.                         {
  431.                             /* resoure DOES exist, change it */
  432.                             hSize = GetHandleSize(h);            /* get the size of the handle */
  433.                             /* check for size of handle */
  434.                             if (hSize != GetPtrSize(p))
  435.                             {
  436.                                 newSize = GetPtrSize(p);
  437.                                 SetHandleSize(h, newSize);
  438.                             }
  439.                             HLock(h);
  440.                             BlockMove(p, *h, GetHandleSize(h));
  441.                             HUnlock(h);
  442.                             ChangedResource(h);
  443.                         }
  444.                         ReleaseResource(h);
  445.     
  446.                         CloseResFile(prefRefNum);
  447.                         iErr = ResError();
  448.                         DisposPtr(p);
  449.                     }
  450.                 }
  451.             }
  452.             
  453.             if (docConn != nil)
  454.             {
  455.                 /* dispose of the connection */
  456.                 CMDispose(docConn);
  457.             }
  458.     
  459.         }
  460.     }
  461. }
  462.  
  463.  
  464. DoCommPortSetup(prefsFileName)
  465. Str255    prefsFileName;
  466. {
  467.     setCTBpref(prefsFileName);
  468.  
  469. }
  470.  
  471. - -------------------------------------
  472. Mark Sproul - KB2ICI
  473.  
  474. +++++++++++++++++++++++++++
  475.  
  476. From: grobbins@Apple.COM (Grobbins)
  477. Date: 29 Sep 92 23:58:55 GMT
  478. Organization: Apple Computer Inc., Cupertino, CA
  479.  
  480. In article <D2150096.o1pwue@sproul.sproul.com> Sproul@sproul.sproul.com (Mark Sproul) writes:
  481. >Several people asked for this source code. ...It now handles the PREFERENCES
  482. >folder in the system folder properly.
  483.  
  484. No, it hardcodes the name "Preferences" and assumes that it is in the
  485. System folder.  Applications should instead use FindFolder under
  486. Systems 6 or 7 to locate the preferences folder.  FindFolder is
  487. documented starting on page 9-42 of Inside Mac VI.
  488.  
  489. Pasted below is the Q&A from issue 11 of develop magazine on
  490. preference files.
  491.  
  492. Grobbins         grobbins@apple.com
  493.  
  494. Usual disclaimers apply.
  495.  
  496. - -------------------------------------------------------
  497.  
  498. I want to place my user's preference file into the
  499. Preferences folder in the System folder under System 7, but I
  500. can't seem to get that folder's DirID and other information
  501. so my file will appear there! Additionally, how do I get to
  502. that folder if the user changes the names of the System
  503. Folder and Preferences folder? Also, once it's there, am I
  504. assuming correctly that the best way to find it again is to
  505. make an alias record to track the file ID?
  506. ___
  507.  
  508. System 7 introduced the routine FindFolder for locating the
  509. Preferences folder. Just make this call
  510.  
  511.    err := FindFolder(kOnSystemDisk, kPreferencesFolderType,
  512.             kCreateFolder, prefVRefNum, prefDirID);
  513.  
  514. and, if err is noErr, then prefVRefNum and prefDirID will
  515. contain the vRefNum and dirID of the Preferences folder. This
  516. can be used with HCreateResFile, HOpenResFile, PBHGetFInfo,
  517. or other File Manager calls to get to your preferences file.
  518. If a Preferences folder does not already exist, the
  519. kCreateFolder parameter instructs FindFolder to make one and
  520. return the vRefNum and dirID of the new folder as prefVRefNum
  521. and prefDirID.
  522.  
  523. FindFolder is documented in Chapter 9 of Inside Macintosh
  524. Volume VI, under "The System Folder and its Related
  525. Directories." While the FindFolder trap is only implemented
  526. under System 7 (check the gestalt selector
  527. gestaltFindFolderAttr, documented in Chapter 3 of Inside
  528. Macintosh VI, to see if FindFolder is available), if you're
  529. using MPW 3.2 (or the current Think compilers) glue is
  530. automatically included in your compiled code, making it safe
  531. to call FindFolder under System 6. The glue will check if
  532. FindFolder is available, and if it is not, will return the
  533. System folder's vRefNum and dirID as as prefVRefNum and
  534. prefDirID for the kPreferencesFolderType selector. Go ahead
  535. and use the System folder values as the location for the
  536. preferences file under System 6.
  537.  
  538. If you're not using a development system that provides the
  539. FindFolder glue, your code should check the FindFolder
  540. gestalt attribute to see if FindFolder is available. If
  541. FindFolder is available, call it. FindFolder is defined as
  542.  
  543.     FUNCTION FindFolder(vRefNum: INTEGER;folderType: OSType;
  544.                         createFolder: BOOLEAN;
  545.         VAR foundVRefNum: INTEGER;VAR foundDirID: LONGINT):OSErr;
  546.         INLINE $7000,$A823;
  547.  
  548. If FindFolder is not available, call SysEnvirons to find the
  549. System folder's WDRefNum, call PBGetWDInfo or GetWDInfo to
  550. convert the WDRefNum to a true vRefNum and dirID, and use
  551. those System folder numbers for the location of the
  552. preferences file. Example code for this is in the Q&A Stack,
  553. under Operating System:File System:Code for identifying
  554. vRefNum and dirID of Macintosh System Folder.
  555.  
  556. To locate the Preferences folder, use the above procedure
  557. rather than try to keep an alias of the Preferences folder or
  558. of the preferences file. However, if there are any other
  559. files in the System Folder upon which the application depends
  560. (such as dictionaries) those should be tracked with aliases,
  561. stored as 'alis' resources in the preferences file. See
  562. Chapter 27 of Inside Macintosh Volume VI for information on
  563. using aliases.
  564.  
  565. +++++++++++++++++++++++++++
  566.  
  567. From: peter@cujo.curtin.edu.au (Peter N Lewis)
  568. Organization: NCRPDA, Curtin University
  569. Date: Thu, 1 Oct 1992 02:27:00 GMT
  570.  
  571. In article <72915@apple.Apple.COM>, grobbins@Apple.COM (Grobbins) wrote:
  572. > In article <D2150096.o1pwue@sproul.sproul.com> Sproul@sproul.sproul.com (Mark Sproul) writes:
  573. > >Several people asked for this source code. ...It now handles the PREFERENCES
  574. > >folder in the system folder properly.
  575. > No, it hardcodes the name "Preferences" and assumes that it is in the
  576. > System folder.  Applications should instead use FindFolder under
  577. > Systems 6 or 7 to locate the preferences folder.  FindFolder is
  578. > documented starting on page 9-42 of Inside Mac VI.
  579.  
  580. Q&A:
  581. > gestaltFindFolderAttr, documented in Chapter 3 of Inside
  582. > Macintosh VI, to see if FindFolder is available), if you're
  583. > using MPW 3.2 (or the current Think compilers) glue is
  584. > automatically included in your compiled code, making it safe
  585. > to call FindFolder under System 6. The glue will check if
  586. > FindFolder is available, and if it is not, will return the
  587. > System folder's vRefNum and dirID as as prefVRefNum and
  588. > prefDirID for the kPreferencesFolderType selector. Go ahead
  589. > and use the System folder values as the location for the
  590. > preferences file under System 6.
  591.  
  592. While I agree you should use FindFolder (definitely don't hard code it!),
  593. and its really nice that you can just call it without worrying about
  594. whether its implemented or not, I disagree with using the System Folder on
  595. System 6 machines.  Many programs (mostly sharware programs I think :-)
  596. were using the Preferences folder before System 7 was even released.  Its
  597. sad that its always the english spelling, but we can't do much about that
  598. except put it in the resource fork so it can be internationalized, but the
  599. Preferences folder is at least a good approximation.
  600.  
  601. So I'd say (blatantly ignoring Apple's recomendation, and waiting for the
  602. Apple Thought Police to come break down my door :), check if you are
  603. running in System 6, and create and use the Preferences folder if you are
  604. (you can (of course) use FindFolder to find the System Folder so you know
  605. where to look for/put the Preferences folder...)
  606.  
  607. Have fun all, I'll go lock my door :-)
  608.    Peter.
  609.  
  610. _______________________________________________________________________
  611. Peter N Lewis, NCRPDA, Curtin University       peter@cujo.curtin.edu.au
  612. GPO Box U1987, Perth WA 6001, AUSTRALIA             FAX: +61 9 367 8141
  613.  
  614. +++++++++++++++++++++++++++
  615.  
  616. From: Sproul@sproul.sproul.com (Mark Sproul)
  617. Date: 2 Oct 92 09:05:30 GMT
  618. Organization: Sproul Consulting
  619.  
  620.  
  621. Several people asked for this source code.  As explained in the comments,
  622. it came from Inside Mac Comm Toolbox and there is a lot of code dealing
  623. just with the Comm Tool box setup.  It now handles the PREFERENCES
  624. folder in the system folder properly.
  625.  
  626. I have done some additions to the code to make it more general and
  627. usable as far as dealing with preferences.  Such as GET pref and SET
  628. pref.  This code was all written and runs correctly with Think C 5.0.
  629.  
  630. Its been several months since I wrote this and was looking at it.
  631. I may have forgotten to mention something, if you have any problems
  632. let me know and I will post updates.
  633.  
  634. You need to define some things such as this:
  635.  
  636. #define    creatorType        'abcd'
  637. #define    fileType        'PREF'
  638. #define    prefsFileName    "\pMyPreferences"
  639.  
  640.  
  641.  
  642.  
  643.  
  644.  
  645. /******************************************************************************
  646. * adapted from
  647. *  Inside the Macintosh Communications Toolbox
  648. * Page  333
  649. * After initialization, the code shown first checks if a
  650. * preferences folder, which contains tool settings written in preference
  651. * files, already exists. If so, the application uses the settings in this file.
  652. * Otherwise, the code generates a new preferences file.
  653. ******************************************************************************
  654. * Modifications
  655. ******************************************************************************
  656. * Nov 27, 1991    Original version had a bug in it.
  657. *                If the "Preferences" directory already existed, the preferences file
  658. *                was placed in the system folder, not in the "Preferences" directory.
  659. *                If the directory did NOT exist, everything worked fine.
  660. *                I also changed it to check for the existance of the "Preferences" folder
  661. *                first instead of trying to create one and letting an duplicate file error
  662. *                indicate that it already existed.
  663. *                by Mark Sproul
  664. *                Internet: sproul@sproul.com
  665. *                AppleLink: Sproul.M
  666. * Jan 16, 1992    Working on a general purpose prefs file manipulator
  667. * Jan 25, 1992    Prefs file resources working great
  668. ******************************************************************************/
  669.  
  670. #include    <Connections.h>
  671. #include    <CommResources.h>
  672.  
  673. /*
  674. ** Global Variables used by all of the prefs routines
  675. */
  676. long            prefDirID;            /* Prefs Dir ID number */
  677. long            sysfDirID;            /* System folder Dir ID number */
  678. short            prefVRefNum;        /* Prefs Volume Ref number */
  679. short            prefFileOKFlag = 0;    /* prefs file OK indicator */
  680.  
  681. /*************************************************************
  682. * This makes sure there is a prefs file in the PREFERENCES directory
  683. * if not, it creates it.
  684. *
  685. * getPrefsFile MUST be called before any atempt at getting the prefs values
  686. *
  687. *************************************************************/
  688.  
  689. void getPrefsFile(prefsFileName, creatorType, fileType)
  690. Str255        prefsFileName;
  691. OSType        creatorType;
  692. OSType        fileType;
  693. {
  694. OSErr            osErr        = noErr;
  695. SysEnvRec        theWorld;
  696. CInfoPBPtr        infoPB;
  697. WDPBPtr            wdPB;
  698. HParmBlkPtr        dirPB;
  699.  
  700. short            prefRefNum;
  701. Point            where    = { 75, 75 };
  702. Str63            toolName;
  703. short            procID;
  704. Handle            h;
  705. Ptr                p;
  706.  
  707.  
  708. ConnHandle        prefConn;
  709.  
  710. ConnHandle        docConn;
  711. CMBufferSizes    sizes    = { 0, 0, 0, 0, 0, 0, 0, 0 };
  712.  
  713.  
  714.  
  715.     infoPB        = (CInfoPBPtr)NewPtrClear(sizeof(*infoPB));
  716.     wdPB        = (WDPBPtr)NewPtrClear(sizeof(*wdPB));
  717.     dirPB        = (HParmBlkPtr)NewPtrClear(sizeof(*dirPB));
  718.  
  719.  
  720.     /* find the system folder's volume reference number and directory ID */
  721.     osErr = SysEnvirons(curSysEnvVers, &theWorld);
  722.     (*wdPB).ioVRefNum = theWorld.sysVRefNum;
  723.  
  724.     if (noErr == (osErr = PBGetWDInfo(wdPB, false)))
  725.     {
  726.         /*********************************************************
  727.         * 11-27-91 Modified by Mark Sproul
  728.         **********************************************************/
  729.         /* get the Volume Reference Number and save it */
  730.         prefVRefNum    = (*wdPB).ioWDVRefNum;
  731.         /* get the System directir ID and save it */
  732.         sysfDirID    = (*wdPB).ioWDDirID;
  733.         
  734.         /* check for the preferences folder */
  735.         (*infoPB).hFileInfo.ioFDirIndex    = 0;
  736.         (*infoPB).hFileInfo.ioVRefNum    = prefVRefNum;
  737.         (*infoPB).hFileInfo.ioDirID        = sysfDirID;
  738.         (*infoPB).hFileInfo.ioNamePtr    = "\pPreferences";
  739.         osErr = PBGetCatInfo(infoPB, false);
  740.         /* save the "Preferecnces" dir number */ 
  741.         prefDirID    = (*infoPB).hFileInfo.ioDirID;
  742.         
  743.         if (osErr == fnfErr)
  744.         {
  745.             /* Create "Preferences" folder */
  746.             (*dirPB).fileParam.ioVRefNum    = prefVRefNum;
  747.             (*dirPB).fileParam.ioDirID        = sysfDirID;
  748.             (*dirPB).fileParam.ioNamePtr    = "\pPreferences";
  749.             osErr = PBDirCreate(dirPB, false);
  750.             prefDirID    = (*dirPB).fileParam.ioDirID;
  751.         }
  752.  
  753.         /*********************************************************
  754.         * end of modifications
  755.         **********************************************************/
  756.         if (osErr == noErr)
  757.         {
  758.             /* does the preference file exist? */
  759.             (*infoPB).hFileInfo.ioFDirIndex    = 0;
  760.             (*infoPB).hFileInfo.ioVRefNum    = prefVRefNum;
  761.             (*infoPB).hFileInfo.ioDirID        = prefDirID;
  762.             (*infoPB).hFileInfo.ioNamePtr    = prefsFileName;
  763.             osErr = PBGetCatInfo(infoPB, false);
  764.             if (osErr == noErr)
  765.             {
  766.                 /* set flag saying the prefs file is OK */
  767.                 prefFileOKFlag = 0xAA;
  768.             }
  769.             if (osErr == fnfErr)
  770.             {
  771.                 /* no, so create a new preference file */
  772.                 if (noErr == (osErr = HCreate(prefVRefNum, prefDirID, prefsFileName, creatorType, fileType)))
  773.                 {
  774.                     HCreateResFile(prefVRefNum, prefDirID, prefsFileName);
  775.                     if (noErr == (osErr = ResError()))
  776.                     {
  777.                         /* open the preference file */
  778.                         prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsFileName, fsRdWrPerm);
  779.                         if (prefRefNum == -1)
  780.                         {
  781.                             osErr = ResError();
  782.                         }
  783.                         else
  784.                         {
  785.                             /* create a default connection */
  786.                             osErr = CRMGetIndToolName(classCM, 1,toolName);
  787.                             if (noErr == osErr)
  788.                             {
  789.                                 prefConn = CMNew(CMGetProcID(toolName), cmData, sizes, 0, 0);
  790.                                 /* leave the default setting as the preferance */
  791.                                 
  792.                                 /************************************************************
  793.                                 * ORIGINALLY, the code let the user select setup at this point
  794.                                 * I do not want it asking for serial port prefs on startup
  795.                                 * if they are not set.
  796.                                 * ---allow the user to select a prefered tool and configuration
  797.                                 * ---osErr = CMChoose(&prefConn, where, nil);
  798.                                 ************************************************************/
  799.                             
  800.                                 /* write the prefered tool name to the preference file */
  801.                                 HLock((Handle) prefConn);
  802.                                 CMGetToolName((**prefConn).procID, toolName);
  803.                                 HUnlock((Handle) prefConn);
  804.                                 h = NewHandle(1 + toolName[0]);
  805.                                 HLock(h);
  806.                                 BlockMove(toolName, *h, GetHandleSize(h));
  807.                                 HUnlock(h);
  808.                                 AddResource(h, 'pTXT', 0, "");
  809.                                 ReleaseResource(h);
  810.                                 /* write the prefered configuration to the preference file */
  811.                                 p = CMGetConfig(prefConn);
  812.                                 h = NewHandle(GetPtrSize(p));
  813.                                 HLock(h);
  814.                                 BlockMove(p, *h, GetHandleSize(h));
  815.                                 HUnlock(h);
  816.                                 AddResource(h, 'cTXT', 0, "");
  817.                                 ReleaseResource(h);
  818.                                 DisposPtr(p);
  819.                                 
  820.                                 /* dispose of the connection */
  821.                                 CMDispose(prefConn);
  822.                             }
  823.                             /* close the file so that it can be used in a shared environment */
  824.                             CloseResFile(prefRefNum);
  825.                             /* set flag saying the prefs file is OK */
  826.                             prefFileOKFlag = 0xAA;
  827.                         }
  828.                     }
  829.                 }
  830.             }
  831.         }
  832.     }
  833. }
  834.  
  835. //*****************************************************************
  836. //*
  837. //* The following code was written by Mark Sproul
  838. //* This code allows easy access to prefs file
  839. //*
  840. //*
  841. //*
  842. //*
  843. //*****************************************************************
  844.  
  845. /**************************************
  846. * get resource from Prefs file
  847. *
  848. ****************************************/
  849. getPrefsResourceStr(prefsFileName, perfsResType, returnString)
  850. Str255        prefsFileName;
  851. OSType        perfsResType;
  852. Str255        returnString;
  853. {
  854. short            prefRefNum;
  855. Handle            h;
  856. int                i;
  857. Size            hSize;
  858.  
  859.     h = nil;
  860.     /* did the prefs file get opened or created OK */
  861.     if (prefFileOKFlag == 0xAA)
  862.     {
  863.         /* focus on the preference file */
  864.         prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsFileName, fsRdWrPerm);
  865.         if (prefRefNum != -1)
  866.         {
  867.             h = Get1Resource(perfsResType, 0);
  868.             hSize = GetHandleSize(h);            /* get the size of the handle */
  869.             if (hSize > 255) hSize = 255;
  870.             HLock(h);
  871.             /* had to have this to make it compile under THINK C 5.0 */
  872.             for (i=0; i< hSize; i++)
  873.             {
  874.                 returnString[i] = *(*h+i);
  875.             }
  876.             HUnlock(h);
  877.             ReleaseResource(h);
  878.             CloseResFile(prefRefNum);
  879.         }
  880.     }
  881. }
  882.  
  883.  
  884. /**************************************
  885. * set Comm Tool Box connection preference
  886. *
  887. ****************************************/
  888. setCTBpref(prefsFileName)
  889. Str255        prefsFileName;
  890. {
  891. short            prefRefNum;
  892. OSErr            osErr, cmChooseReturnCode;
  893. int                i;
  894. Str255            prefStr;
  895. short            procID;
  896. Str63            toolName;
  897. Handle            h;
  898. Ptr                p;
  899. short            iErr;
  900. Size            hSize, newSize;
  901.  
  902. ConnHandle        docConn;
  903. CMBufferSizes    sizes    = { 0, 0, 0, 0, 0, 0, 0, 0 };
  904. Point            where    = { 75, 75 };
  905.  
  906.     if (isCTBavailable())
  907.     {
  908.         /* did the prefs file get opened or created OK */
  909.         if (prefFileOKFlag == 0xAA)
  910.         {
  911.             getPrefsResourceStr(prefsFileName,'pTXT', prefStr);
  912.     
  913.             procID = CMGetProcID(prefStr);
  914.             if (procID != -1)
  915.             {
  916.                 /* create a new connection */
  917.                 docConn    = CMNew(procID, cmData, sizes, 0, 0);
  918.                 
  919.                 if (docConn != nil)
  920.                 {
  921.                     /* set the prefered configuration */
  922.         
  923.                     getPrefsResourceStr(prefsFileName,'cTXT', prefStr);
  924.                     osErr    = CMSetConfig(docConn, (char *)prefStr);
  925.     
  926.                     cmChooseReturnCode    = CMChoose(&docConn, where, nil);
  927.                 }
  928.             }
  929.             else
  930.             {
  931.                 /* the prefered tool could not be found so I */
  932.                 osErr    = CRMGetIndToolName(classCM, 1, toolName);
  933.                 docConn    = CMNew(CMGetProcID(toolName), cmData, sizes, 0, 0);
  934.                 if (docConn != nil)
  935.                 {
  936.                     cmChooseReturnCode    = CMChoose(&docConn, where, nil);
  937.                 }
  938.             }
  939.             
  940.             if ((cmChooseReturnCode == chooseOKMinor) || (cmChooseReturnCode == chooseOKMajor))
  941.             {
  942.                 /* change the prefs file */
  943.                 
  944.                 if (prefFileOKFlag == 0xAA)
  945.                 {
  946.                     /* open the preference file */
  947.                     prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsFileName, fsRdWrPerm);
  948.                     if (prefRefNum != -1)
  949.                     {
  950.                         /* write the prefered tool name to the preference file */
  951.                         HLock((Handle) docConn);
  952.                         CMGetToolName((**docConn).procID, toolName);
  953.                         HUnlock((Handle) docConn);
  954.                         
  955.                         /* get the port TeXT resource */
  956.                         h = Get1Resource('pTXT', 0);
  957.                         if (h == nil)
  958.                         {
  959.                             /* resource did not exist, add it to resource file */
  960.                             h = NewHandle(1 + toolName[0]);
  961.                             HLock(h);
  962.                             BlockMove(toolName, *h, GetHandleSize(h));
  963.                             HUnlock(h);
  964.                             AddResource(h, 'pTXT', 0, "");
  965.                         }
  966.                         else
  967.                         {
  968.                             /* resoure DOES exist, change it */
  969.                             hSize = GetHandleSize(h);            /* get the size of the handle */
  970.                             /* check for size of handle */
  971.                             if (hSize != (1 + toolName[0]))
  972.                             {
  973.                                 newSize = 1 + toolName[0];
  974.                                 SetHandleSize(h, newSize);
  975.                             }
  976.                             HLock(h);
  977.                             BlockMove(toolName, *h, GetHandleSize(h));
  978.                             HUnlock(h);
  979.                             ChangedResource(h);
  980.                         }
  981.                         ReleaseResource(h);
  982.                         
  983.                         /* write the prefered configuration to the preference file */
  984.                         p = CMGetConfig(docConn);
  985.     
  986.     
  987.                         /* get the configuration TeXT resource */
  988.                         h = Get1Resource('cTXT', 0);
  989.                         if (h == nil)
  990.                         {
  991.                             /* resource did not exist, add it to resource file */
  992.                             h = NewHandle(GetPtrSize(p));
  993.                             HLock(h);
  994.                             BlockMove(p, *h, GetHandleSize(h));
  995.                             HUnlock(h);
  996.                         
  997.                             AddResource(h, 'cTXT', 0, "");
  998.                             iErr = ResError();
  999.                         }
  1000.                         else
  1001.                         {
  1002.                             /* resoure DOES exist, change it */
  1003.                             hSize = GetHandleSize(h);            /* get the size of the handle */
  1004.                             /* check for size of handle */
  1005.                             if (hSize != GetPtrSize(p))
  1006.                             {
  1007.                                 newSize = GetPtrSize(p);
  1008.                                 SetHandleSize(h, newSize);
  1009.                             }
  1010.                             HLock(h);
  1011.                             BlockMove(p, *h, GetHandleSize(h));
  1012.                             HUnlock(h);
  1013.                             ChangedResource(h);
  1014.                         }
  1015.                         ReleaseResource(h);
  1016.     
  1017.                         CloseResFile(prefRefNum);
  1018.                         iErr = ResError();
  1019.                         DisposPtr(p);
  1020.                     }
  1021.                 }
  1022.             }
  1023.             
  1024.             if (docConn != nil)
  1025.             {
  1026.                 /* dispose of the connection */
  1027.                 CMDispose(docConn);
  1028.             }
  1029.     
  1030.         }
  1031.     }
  1032. }
  1033.  
  1034.  
  1035. DoCommPortSetup(prefsFileName)
  1036. Str255    prefsFileName;
  1037. {
  1038.     setCTBpref(prefsFileName);
  1039.  
  1040. }
  1041.  
  1042.  
  1043. - -------------------------------------
  1044. Mark Sproul - KB2ICI
  1045.  
  1046. +++++++++++++++++++++++++++
  1047.  
  1048. From: winer@husc8.harvard.edu (Adam Winer)
  1049. Date: 2 Oct 92 20:12:00 GMT
  1050. Organization: Harvard University Science Center
  1051.  
  1052. If I remember correctly, there is MPW (and hence THINK C) glue that, if
  1053. FindFolder is called in a system without it, will just return the location
  1054. of the System Folder.  Sounds pretty good to me, if it works.
  1055.  
  1056. Adam
  1057. - -- 
  1058. Adam Winer        | The number you have reached is imaginary.
  1059. WINER@HARVARD.EDU    | Please rotate your phone 90 degrees and
  1060.                         | try again.
  1061.  
  1062. ---------------------------
  1063.  
  1064. End of C.S.M.P. Digest
  1065. **********************
  1066.