From: Sproul@sproul.sproul.com (Mark Sproul) Subject: Prefs file source code (C - long) Date: 2 Oct 92 09:05:30 GMT Several people asked for this source code. As explained in the comments, it came from Inside Mac Comm Toolbox and there is a lot of code dealing just with the Comm Tool box setup. It now handles the PREFERENCES folder in the system folder properly. I have done some additions to the code to make it more general and usable as far as dealing with preferences. Such as GET pref and SET pref. This code was all written and runs correctly with Think C 5.0. Its been several months since I wrote this and was looking at it. I may have forgotten to mention something, if you have any problems let me know and I will post updates. You need to define some things such as this: #define creatorType 'abcd' #define fileType 'PREF' #define prefsFileName "\pMyPreferences" /****************************************************************************** * adapted from * Inside the Macintosh Communications Toolbox * Page 333 * After initialization, the code shown first checks if a * preferences folder, which contains tool settings written in preference * files, already exists. If so, the application uses the settings in this file. * Otherwise, the code generates a new preferences file. ****************************************************************************** * Modifications ****************************************************************************** * Nov 27, 1991 Original version had a bug in it. * If the "Preferences" directory already existed, the preferences file * was placed in the system folder, not in the "Preferences" directory. * If the directory did NOT exist, everything worked fine. * I also changed it to check for the existance of the "Preferences" folder * first instead of trying to create one and letting an duplicate file error * indicate that it already existed. * by Mark Sproul * Internet: sproul@sproul.com * AppleLink: Sproul.M * Jan 16, 1992 Working on a general purpose prefs file manipulator * Jan 25, 1992 Prefs file resources working great ******************************************************************************/ #include #include /* ** Global Variables used by all of the prefs routines */ long prefDirID; /* Prefs Dir ID number */ long sysfDirID; /* System folder Dir ID number */ short prefVRefNum; /* Prefs Volume Ref number */ short prefFileOKFlag = 0; /* prefs file OK indicator */ /************************************************************* * This makes sure there is a prefs file in the PREFERENCES directory * if not, it creates it. * * getPrefsFile MUST be called before any atempt at getting the prefs values * *************************************************************/ void getPrefsFile(prefsFileName, creatorType, fileType) Str255 prefsFileName; OSType creatorType; OSType fileType; { OSErr osErr = noErr; SysEnvRec theWorld; CInfoPBPtr infoPB; WDPBPtr wdPB; HParmBlkPtr dirPB; short prefRefNum; Point where = { 75, 75 }; Str63 toolName; short procID; Handle h; Ptr p; ConnHandle prefConn; ConnHandle docConn; CMBufferSizes sizes = { 0, 0, 0, 0, 0, 0, 0, 0 }; infoPB = (CInfoPBPtr)NewPtrClear(sizeof(*infoPB)); wdPB = (WDPBPtr)NewPtrClear(sizeof(*wdPB)); dirPB = (HParmBlkPtr)NewPtrClear(sizeof(*dirPB)); /* find the system folder's volume reference number and directory ID */ osErr = SysEnvirons(curSysEnvVers, &theWorld); (*wdPB).ioVRefNum = theWorld.sysVRefNum; if (noErr == (osErr = PBGetWDInfo(wdPB, false))) { /********************************************************* * 11-27-91 Modified by Mark Sproul **********************************************************/ /* get the Volume Reference Number and save it */ prefVRefNum = (*wdPB).ioWDVRefNum; /* get the System directir ID and save it */ sysfDirID = (*wdPB).ioWDDirID; /* check for the preferences folder */ (*infoPB).hFileInfo.ioFDirIndex = 0; (*infoPB).hFileInfo.ioVRefNum = prefVRefNum; (*infoPB).hFileInfo.ioDirID = sysfDirID; (*infoPB).hFileInfo.ioNamePtr = "\pPreferences"; osErr = PBGetCatInfo(infoPB, false); /* save the "Preferecnces" dir number */ prefDirID = (*infoPB).hFileInfo.ioDirID; if (osErr == fnfErr) { /* Create "Preferences" folder */ (*dirPB).fileParam.ioVRefNum = prefVRefNum; (*dirPB).fileParam.ioDirID = sysfDirID; (*dirPB).fileParam.ioNamePtr = "\pPreferences"; osErr = PBDirCreate(dirPB, false); prefDirID = (*dirPB).fileParam.ioDirID; } /********************************************************* * end of modifications **********************************************************/ if (osErr == noErr) { /* does the preference file exist? */ (*infoPB).hFileInfo.ioFDirIndex = 0; (*infoPB).hFileInfo.ioVRefNum = prefVRefNum; (*infoPB).hFileInfo.ioDirID = prefDirID; (*infoPB).hFileInfo.ioNamePtr = prefsFileName; osErr = PBGetCatInfo(infoPB, false); if (osErr == noErr) { /* set flag saying the prefs file is OK */ prefFileOKFlag = 0xAA; } if (osErr == fnfErr) { /* no, so create a new preference file */ if (noErr == (osErr = HCreate(prefVRefNum, prefDirID, prefsFileName, creatorType, fileType))) { HCreateResFile(prefVRefNum, prefDirID, prefsFileName); if (noErr == (osErr = ResError())) { /* open the preference file */ prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsFileName, fsRdWrPerm); if (prefRefNum == -1) { osErr = ResError(); } else { /* create a default connection */ osErr = CRMGetIndToolName(classCM, 1,toolName); if (noErr == osErr) { prefConn = CMNew(CMGetProcID(toolName), cmData, sizes, 0, 0); /* leave the default setting as the preferance */ /************************************************************ * ORIGINALLY, the code let the user select setup at this point * I do not want it asking for serial port prefs on startup * if they are not set. * ---allow the user to select a prefered tool and configuration * ---osErr = CMChoose(&prefConn, where, nil); ************************************************************/ /* write the prefered tool name to the preference file */ HLock((Handle) prefConn); CMGetToolName((**prefConn).procID, toolName); HUnlock((Handle) prefConn); h = NewHandle(1 + toolName[0]); HLock(h); BlockMove(toolName, *h, GetHandleSize(h)); HUnlock(h); AddResource(h, 'pTXT', 0, ""); ReleaseResource(h); /* write the prefered configuration to the preference file */ p = CMGetConfig(prefConn); h = NewHandle(GetPtrSize(p)); HLock(h); BlockMove(p, *h, GetHandleSize(h)); HUnlock(h); AddResource(h, 'cTXT', 0, ""); ReleaseResource(h); DisposPtr(p); /* dispose of the connection */ CMDispose(prefConn); } /* close the file so that it can be used in a shared environment */ CloseResFile(prefRefNum); /* set flag saying the prefs file is OK */ prefFileOKFlag = 0xAA; } } } } } } } //***************************************************************** //* //* The following code was written by Mark Sproul //* This code allows easy access to prefs file //* //* //* //* //***************************************************************** /************************************** * get resource from Prefs file * ****************************************/ getPrefsResourceStr(prefsFileName, perfsResType, returnString) Str255 prefsFileName; OSType perfsResType; Str255 returnString; { short prefRefNum; Handle h; int i; Size hSize; h = nil; /* did the prefs file get opened or created OK */ if (prefFileOKFlag == 0xAA) { /* focus on the preference file */ prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsFileName, fsRdWrPerm); if (prefRefNum != -1) { h = Get1Resource(perfsResType, 0); hSize = GetHandleSize(h); /* get the size of the handle */ if (hSize > 255) hSize = 255; HLock(h); /* had to have this to make it compile under THINK C 5.0 */ for (i=0; i< hSize; i++) { returnString[i] = *(*h+i); } HUnlock(h); ReleaseResource(h); CloseResFile(prefRefNum); } } } /************************************** * set Comm Tool Box connection preference * ****************************************/ setCTBpref(prefsFileName) Str255 prefsFileName; { short prefRefNum; OSErr osErr, cmChooseReturnCode; int i; Str255 prefStr; short procID; Str63 toolName; Handle h; Ptr p; short iErr; Size hSize, newSize; ConnHandle docConn; CMBufferSizes sizes = { 0, 0, 0, 0, 0, 0, 0, 0 }; Point where = { 75, 75 }; if (isCTBavailable()) { /* did the prefs file get opened or created OK */ if (prefFileOKFlag == 0xAA) { getPrefsResourceStr(prefsFileName,'pTXT', prefStr); procID = CMGetProcID(prefStr); if (procID != -1) { /* create a new connection */ docConn = CMNew(procID, cmData, sizes, 0, 0); if (docConn != nil) { /* set the prefered configuration */ getPrefsResourceStr(prefsFileName,'cTXT', prefStr); osErr = CMSetConfig(docConn, (char *)prefStr); cmChooseReturnCode = CMChoose(&docConn, where, nil); } } else { /* the prefered tool could not be found so I */ osErr = CRMGetIndToolName(classCM, 1, toolName); docConn = CMNew(CMGetProcID(toolName), cmData, sizes, 0, 0); if (docConn != nil) { cmChooseReturnCode = CMChoose(&docConn, where, nil); } } if ((cmChooseReturnCode == chooseOKMinor) || (cmChooseReturnCode == chooseOKMajor)) { /* change the prefs file */ if (prefFileOKFlag == 0xAA) { /* open the preference file */ prefRefNum = HOpenResFile(prefVRefNum, prefDirID, prefsFileName, fsRdWrPerm); if (prefRefNum != -1) { /* write the prefered tool name to the preference file */ HLock((Handle) docConn); CMGetToolName((**docConn).procID, toolName); HUnlock((Handle) docConn); /* get the port TeXT resource */ h = Get1Resource('pTXT', 0); if (h == nil) { /* resource did not exist, add it to resource file */ h = NewHandle(1 + toolName[0]); HLock(h); BlockMove(toolName, *h, GetHandleSize(h)); HUnlock(h); AddResource(h, 'pTXT', 0, ""); } else { /* resoure DOES exist, change it */ hSize = GetHandleSize(h); /* get the size of the handle */ /* check for size of handle */ if (hSize != (1 + toolName[0])) { newSize = 1 + toolName[0]; SetHandleSize(h, newSize); } HLock(h); BlockMove(toolName, *h, GetHandleSize(h)); HUnlock(h); ChangedResource(h); } ReleaseResource(h); /* write the prefered configuration to the preference file */ p = CMGetConfig(docConn); /* get the configuration TeXT resource */ h = Get1Resource('cTXT', 0); if (h == nil) { /* resource did not exist, add it to resource file */ h = NewHandle(GetPtrSize(p)); HLock(h); BlockMove(p, *h, GetHandleSize(h)); HUnlock(h); AddResource(h, 'cTXT', 0, ""); iErr = ResError(); } else { /* resoure DOES exist, change it */ hSize = GetHandleSize(h); /* get the size of the handle */ /* check for size of handle */ if (hSize != GetPtrSize(p)) { newSize = GetPtrSize(p); SetHandleSize(h, newSize); } HLock(h); BlockMove(p, *h, GetHandleSize(h)); HUnlock(h); ChangedResource(h); } ReleaseResource(h); CloseResFile(prefRefNum); iErr = ResError(); DisposPtr(p); } } } if (docConn != nil) { /* dispose of the connection */ CMDispose(docConn); } } } } DoCommPortSetup(prefsFileName) Str255 prefsFileName; { setCTBpref(prefsFileName); } ------------------------------------- Mark Sproul - KB2ICI