From: Sproul@sproul.sproul.com (Mark Sproul)
Newsgroups: comp.sys.mac.programmer
Subject: code for Finding Prefs File (long)
Date: 5 Jan 93 18:15:16 GMT
Reply-To: Sproul@sproul.sproul.com (Mark Sproul)
Organization: Sproul Consulting
X-Mailer: uAccess - Macintosh Release: 1.6v1

Below is code for finding and working with prefs file in system 7
prefernce folder and working with said file

There are people looking for this code again, I posted it before.
Since I posted it last, I have made some additions to it.  This code
is originally from Inside Mac Comm ToolBox.

============================================================================
FILE: doPrefs.proto.h
============================================================================

void		getPrefsFile(Str255, OSType, OSType);
Boolean		getPrefsResourceStr(Str255, OSType, Str255);
Boolean		getPrefsResourceData(Str255, OSType, char *, long);
void		setPrefsResourceStr(Str255, OSType, Ptr, long);
void		setCTBpref(Str255);
void		DoCommPortSetup(Str255);

============================================================================
FILE: doPrefs.c
============================================================================


/******************************************************************************
* 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
*				AppleLink: Sproul.M
* Jan 16, 1992	Working on a general purpose prefs file manipulator
* Jan 25, 1992	Prefs file resources working great
******************************************************************************/

#include	<Connections.h>
#include	<CommResources.h>
#include	"doPrefs.proto.h"
/*
** 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 directory 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;
						}
					}
				}
			}
		}
	}
}



//**************************************
//* get resource String from Prefs file
//*
//***************************************
Boolean	getPrefsResourceStr(prefsFileName, perfsResType, returnString)
Str255		prefsFileName;
OSType		perfsResType;
Str255		returnString;
{
short			prefRefNum;
Handle			h;
int				i;
Size			hSize;
Boolean			returnFlag;

	h = nil;
	returnFlag	= false;
	/* 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);
			if (h != nil)
			{
				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);
				returnFlag	= true;			//* prefs string is OK
			}
			CloseResFile(prefRefNum);
		}
	}
	else
	{
		//* generate prefs file alert message
	}
	return(returnFlag);
}

//**************************************
//* get resource String from Prefs file
//*
//***************************************
Boolean	getPrefsResourceData(	Str255		prefsFileName,
								OSType		perfsResType,
								char		*returnString,
								long		maxLen)
{
short			prefRefNum;
Handle			h;
int				i;
Size			hSize;
Boolean			returnFlag;

	h = nil;
	returnFlag	= false;
	/* 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);
			if (h != nil)
			{
				hSize = GetHandleSize(h);			/* get the size of the handle */
				if (hSize > maxLen) hSize = maxLen;
				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);
				returnFlag	= true;			//* prefs string is OK
			}
			CloseResFile(prefRefNum);
		}
	}
	else
	{
		//* generate prefs file alert message
	}
	return(returnFlag);
}

//**************************************
//* save resource to Prefs file
//*
//***************************************
void	setPrefsResourceStr(Str255 prefsFileName, OSType perfsResType,char *buffer, long bufLen)
{
short			prefRefNum;
Handle			h;
int				i;
Size			hSize, newSize;

	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)
		{
			//* get the specified resource */
			h = Get1Resource(perfsResType, 0);
			if (h == nil)
			{
				/* resource did not exist, add it to resource file */
				h = NewHandle(1 + bufLen);
				HLock(h);
				BlockMove(buffer, *h, GetHandleSize(h));
				HUnlock(h);
				AddResource(h, perfsResType, 0, "\p");
			}
			else
			{
				/* resoure DOES exist, change it */
				hSize = GetHandleSize(h);			/* get the size of the handle */
				/* check for size of handle */
				if (hSize != (1 + bufLen))
				{
					newSize = 1 + bufLen;
					SetHandleSize(h, newSize);
				}
				HLock(h);
				BlockMove(buffer, *h, GetHandleSize(h));
				HUnlock(h);
				ChangedResource(h);
			}
			ReleaseResource(h);
			CloseResFile(prefRefNum);
		}
	}
	else
	{
		PutAlertMessage("\pProgram cant find prefs file");
	}
}


/**************************************
* set Comm Tool Box connection preference
*
****************************************/
void	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	= { 40, 40 };

	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);
			}
	
		}
	}
	else
	{
		SysBeep(1);
		SysBeep(1);
	}
}


void	DoCommPortSetup(prefsFileName)
Str255	prefsFileName;
{
	setCTBpref(prefsFileName);

}

-----------------------------------------------------
Mark Sproul - KB2ICI - New Jersey
sproul@sproul.com
Newsgroups: comp.sys.mac.programmer