mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2025-01-21 18:35:32 +00:00
4325cdcc78
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
326 lines
8.6 KiB
C
326 lines
8.6 KiB
C
/*
|
|
File: CommResourceMgr.c
|
|
|
|
Contains: Communications Resource Manager
|
|
|
|
Written by: Byron Han
|
|
|
|
Copyright: © 1988-1990, 1992 by Apple Computer, Inc., all rights reserved.
|
|
|
|
Change History (most recent first):
|
|
|
|
<13> 4/28/92 DTY Remove hasAliasMgr conditional. Always use the Folder Manager.
|
|
<12> 2/7/92 BH changed define for MANAGERCODE to be TRUE or FALSE to allow
|
|
CommResourceMgrExtensions.c to properly conditionalize for
|
|
TheFuture and for CubeE and for building the glue file
|
|
<11> 7/2/91 BH added __CRMGetHeader
|
|
<10> 8/15/90 kaz Fixed C3.0 bug in _CRMResource calls that would do a SUBQ.L
|
|
instead of a CLR.L for a function result => garbage returned.
|
|
<9> 7/10/90 dba add __ to distinguish routines from glue
|
|
<8> 7/2/90 kaz Code shrink/cleanup.
|
|
<7> 4/9/90 BBH * Moving CRMFindCommunications here from
|
|
CommResourceMgrUtilities.a
|
|
¥ Use Folder Mgr if available (instead of manually creating
|
|
Communications Folder use the Extensions folder) this is
|
|
controlled by a conditional compile (if hasAliasMgr)
|
|
<6> 3/22/90 BBH moved getglobals macro to CommToolboxPriv.h
|
|
<5> 3/16/90 BBH fixed problem where deviceID's never got above 2 (after first
|
|
match of deviceType, we would immediately break)
|
|
<4> 3/16/90 BBH fixed GetDeviceID. when trying to match deviceID's was looking
|
|
at garbage.
|
|
<3> 3/16/90 BBH create a macro to get CommToolbox globals
|
|
<2> 3/15/90 BBH Fixed GetList to properly return pointer to commtoolbox globals
|
|
<1> 3/14/90 BBH first checked in
|
|
|
|
To Do:
|
|
*/
|
|
|
|
#include <SysEqu.h>
|
|
#include <Types.h>
|
|
#include <Memory.h>
|
|
#include <Resources.h>
|
|
#include <OSUtils.h>
|
|
#include <Errors.h>
|
|
|
|
#include <CommResources.h>
|
|
#include <CommToolboxPriv.h>
|
|
|
|
#include "CommResourceMgr.h"
|
|
|
|
// <12> changed to do TRUE and FALSE for the define
|
|
#define __MANAGERCODE__ TRUE
|
|
#include "CommResourceMgrExtensions.c"
|
|
|
|
#include <Folders.h>
|
|
|
|
// Should be moved to CommToolboxPriv.h
|
|
#define IsResError() ((*(short *) ResErr) != noErr)
|
|
|
|
// initializes the Communications Resource Manager
|
|
pascal CRMErr __InitCRM()
|
|
{
|
|
/* Shouldn't we return an error if CTB Globals didn't get allocated */
|
|
/*
|
|
|
|
if CRMGetGlobals & CRMGetGlobals->crmQueue != nil
|
|
|
|
*/
|
|
|
|
return(noErr);
|
|
}
|
|
|
|
// Folder stuff for 7.0
|
|
pascal OSErr __CRMFindCommunications(vRefNum, dirID)
|
|
short *vRefNum;
|
|
long *dirID;
|
|
{
|
|
return(FindFolder(kOnSystemDisk, kExtensionFolderType, kCreateFolder, vRefNum, dirID));
|
|
}
|
|
|
|
pascal OSErr __CRMCreateCommunications(vRefNum, dirID)
|
|
short *vRefNum;
|
|
long *dirID;
|
|
{
|
|
return(FindFolder(kOnSystemDisk, kExtensionFolderType, kCreateFolder, vRefNum, dirID));
|
|
}
|
|
|
|
//¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
|
|
// Routines for Device Management
|
|
//¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
|
|
|
|
// adds element to CRM queue
|
|
pascal void __CRMInstall(crmReqPtr)
|
|
QElemPtr crmReqPtr;
|
|
{
|
|
CRMRecPtr pMatch = (CRMRecPtr) crmReqPtr;
|
|
|
|
pMatch->qType = crmType;
|
|
pMatch->crmVersion = crmRecVersion;
|
|
pMatch->crmDeviceID = GetDeviceID(pMatch->crmDeviceType);
|
|
Enqueue(crmReqPtr, CRMGetHeader);
|
|
}
|
|
|
|
// this removes an entry from the CRM queue
|
|
pascal OSErr __CRMRemove(crmReqPtr)
|
|
QElemPtr crmReqPtr;
|
|
{
|
|
return( Dequeue(crmReqPtr, CRMGetHeader) );
|
|
}
|
|
|
|
pascal QHdrPtr __CRMGetHeader(void)
|
|
{
|
|
return CRMGetHeader;
|
|
}
|
|
|
|
// this searches for an entry with the same device type and with a
|
|
// device ID bigger than the one specified. since we keep the entry list
|
|
// sorted by device ID, we can do a simple search. maybe we should make this a
|
|
// binary search eventuallyÉ
|
|
pascal QElemPtr __CRMSearch(crmReqPtr)
|
|
QElemPtr crmReqPtr;
|
|
{
|
|
CRMRecPtr pMatch = (CRMRecPtr) crmReqPtr;
|
|
CRMRecPtr pWalker = (CRMRecPtr) CRMGetHeader->qHead;
|
|
|
|
for (; pWalker != nil; pWalker = (CRMRecPtr) pWalker->qLink)
|
|
if (pWalker->crmDeviceType == pMatch->crmDeviceType)
|
|
if (pWalker->crmDeviceID > pMatch->crmDeviceID)
|
|
return((QElemPtr) pWalker); // we're outta here
|
|
|
|
return(nil);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
// Utilities Routines
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// this returns the next free device ID for the given device type in the
|
|
// crm queue.
|
|
pascal long GetDeviceID(dType)
|
|
long dType;
|
|
{
|
|
CRMRecPtr pWalker = (CRMRecPtr)CRMGetHeader->qHead;
|
|
long rval = 0;
|
|
|
|
for (; pWalker != nil; pWalker = (CRMRecPtr) pWalker->qLink)
|
|
if (pWalker->crmDeviceType == dType) // <4>
|
|
if (pWalker->crmDeviceID > rval)
|
|
rval = pWalker->crmDeviceID; // remove break <5>
|
|
|
|
return(++rval);
|
|
}
|
|
|
|
//¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
|
|
// Routines for Resource Management
|
|
//¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
|
|
|
|
pascal long __CRMGetIndex(hResource)
|
|
Handle hResource;
|
|
{
|
|
CRMResourceCountPtr pMatch = FindResource(hResource);
|
|
long rval = 0;
|
|
|
|
if (pMatch != nil) {
|
|
if (pMatch->useCount <= 0)
|
|
RemoveEntry(pMatch); // cleanup pleaseÉ
|
|
else
|
|
rval = pMatch->useCount;
|
|
}
|
|
|
|
return(rval);
|
|
}
|
|
|
|
pascal Handle CRMGet10Resource(theType, theID, deep)
|
|
ResType theType;
|
|
short theID;
|
|
short deep;
|
|
{
|
|
Handle theHandle;
|
|
|
|
theHandle = (deep == 1 ? Get1Resource(theType, theID) : GetResource(theType, theID));
|
|
// Hopefully we can remove this workaround w/ C3.2
|
|
if (IsResError())
|
|
theHandle = nil;
|
|
HandleResource(theHandle);
|
|
return(theHandle);
|
|
}
|
|
|
|
pascal Handle CRMGet10IndResource(theType, index, deep)
|
|
ResType theType;
|
|
short index;
|
|
short deep;
|
|
{
|
|
Handle theHandle;
|
|
|
|
theHandle = (deep == 1 ? Get1IndResource(theType, index) : GetIndResource(theType, index));
|
|
if (IsResError())
|
|
theHandle = nil;
|
|
HandleResource(theHandle);
|
|
return(theHandle);
|
|
}
|
|
|
|
pascal Handle CRMGet10NamedResource(theType, name, deep)
|
|
ResType theType;
|
|
const Str255 name;
|
|
short deep;
|
|
{
|
|
Handle theHandle;
|
|
|
|
theHandle = (deep == 1 ? Get1NamedResource(theType, name) : GetNamedResource(theType, name));
|
|
if (IsResError())
|
|
theHandle = nil;
|
|
HandleResource(theHandle);
|
|
return(theHandle);
|
|
}
|
|
|
|
pascal void __CRMReleaseResource(Handle pResource)
|
|
{
|
|
CRMResourceCountPtr pMatch = FindResource(pResource);
|
|
|
|
if (pMatch != nil) // huh?
|
|
if (--(pMatch->useCount) <= 0) {
|
|
RemoveEntry(pMatch); // pull from list
|
|
pMatch = nil;
|
|
}
|
|
|
|
if (pMatch == nil)
|
|
ReleaseResource(pResource);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
// Utilities Routines
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// this finds the resource count entry for the given resource
|
|
CRMResourceCountPtr FindResource(hResource)
|
|
Handle hResource;
|
|
{
|
|
CRMResourceCountPtr pCRMResourceCount = GetList;
|
|
|
|
for (; pCRMResourceCount != nil; pCRMResourceCount = pCRMResourceCount->next)
|
|
if (pCRMResourceCount->theHandle == hResource)
|
|
return(pCRMResourceCount);
|
|
|
|
return(nil);
|
|
}
|
|
|
|
// this clears the resource counts for the file with the refnum specified
|
|
// used for cleanup purposesÉ
|
|
void ClearResource(refnum)
|
|
short refnum;
|
|
{
|
|
CRMResourceCountPtr curCRM = GetList,
|
|
tempCRM;
|
|
|
|
while (curCRM != nil) {
|
|
tempCRM = curCRM->next;
|
|
if (curCRM->refnum == refnum)
|
|
RemoveEntry(curCRM);
|
|
curCRM = tempCRM;
|
|
}
|
|
}
|
|
|
|
// this routine adds a resource to the resource count list
|
|
CRMResourceCountPtr RegisterDevice(hResource)
|
|
Handle hResource;
|
|
{
|
|
CRMResourceCountPtr pCRMResourceCount =
|
|
(CRMResourceCountPtr) NewPtrSys(sizeof(CRMResourceCount));
|
|
|
|
if (pCRMResourceCount != nil) {
|
|
pCRMResourceCount->next = GetList;
|
|
pCRMResourceCount->useCount = 0;
|
|
pCRMResourceCount->theHandle = hResource;
|
|
|
|
GetList = pCRMResourceCount; // put at start of list
|
|
// GetList is a macro
|
|
}
|
|
|
|
return(pCRMResourceCount);
|
|
}
|
|
|
|
|
|
// this routine removes an entry from the resource count list
|
|
void RemoveEntry(pMatch)
|
|
CRMResourceCountPtr pMatch;
|
|
{
|
|
CRMResourceCountPtr curCRM = GetList,
|
|
prevCRM = nil;
|
|
|
|
for (; curCRM != nil && pMatch != curCRM;
|
|
prevCRM = curCRM, curCRM = curCRM->next)
|
|
;
|
|
|
|
if (curCRM == nil)
|
|
return;
|
|
|
|
if (prevCRM == nil) // eliminating first element
|
|
GetList = curCRM->next; // GetList is a macro
|
|
else
|
|
prevCRM->next = curCRM->next;
|
|
|
|
DisposPtr((Ptr) curCRM);
|
|
}
|
|
|
|
// handle a resource by adding it to the resource count list if necessary
|
|
// and bumping the useCount if needed
|
|
|
|
void HandleResource(hResource)
|
|
Handle hResource;
|
|
{
|
|
CRMResourceCountPtr pMatch;
|
|
|
|
if (hResource == nil)
|
|
return;
|
|
|
|
pMatch = FindResource(hResource); // is it there?
|
|
if (pMatch == nil)
|
|
pMatch = RegisterDevice(hResource); // add to list
|
|
|
|
if (pMatch == nil)
|
|
return; // we are F*CKED!
|
|
|
|
pMatch->useCount++;
|
|
pMatch->refnum = HomeResFile(hResource); // for cleanup purposes
|
|
}
|