home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sys.mac.programmer
- Path: sparky!uunet!sun-barr!ames!data.nas.nasa.gov!taligent!keith@taligent.com
- From: keith@taligent.com (Keith Rollin)
- Subject: Re: Problem writing INIT/cdev
- Message-ID: <Bu0qMw.4Ev@taligent.com>
- Sender: usenet@taligent.com (More Bytes Than You Can Read)
- Organization: Taligent
- References: <1992Aug27.002347.14632@vax5.cit.cornell.edu> <Sep.3.01.53.43.1992.13837@math.rutgers.edu>
- Distribution: comp
- Date: Thu, 3 Sep 1992 20:08:55 GMT
- Lines: 156
-
- In article <Sep.3.01.53.43.1992.13837@math.rutgers.edu>,
- landwebe@math.rutgers.edu (Peter Landweber) writes:
- >
- >
- >
- > I am working on an INIT/cdev combination to be used under System
- > 7, and I've run into a problem.
- > At startup time, the INIT moves its resource map after the system
- > resource map in the linked list, and it patches CloseResFile() to
- > ignore the file. The result is that my file stays open, and its
- > resources are always available. This is similar to what Suitcase II
- > does with font suitcases. So far everything has gone extremely well
- > using this technique.
- > Now, I'm trying to add a "cdev". The problem is that when the
- > finder opens up my file as a Control Panel, it expects my file's
- > resource map to be the first in the linked list. Since the resource
- > map is actually at the end of the linked list, the finder crashes.
- >
- > So, my questions are:
- > 1) Is there a way for the Finder to open up a Control Panel if the
- > file is already open, and its resource map is not at the front of the
- > linked list?
- > 2) Is there a way to open a file twice, with two separate resource
- > maps? That way, I could still have one resource map linked after the
- > system resource map, and the other at the front of the linked list.
- > One of the maps could be read-only if necessary.
-
- I have an INIT/cdev that does the same thing. However, it takes a little
- different approach than yours, and it seems to work.
-
- First, I don't patch CloseResFile() to keep my file open. Instead, at INIT time,
- I install my code, remember the file I came from, and patch InitAllPacks(). I
- remember my file of origin with the following routine.
-
-
- static void RememberMe()
- {
- FCBPBRec pb;
- OSErr err;
-
- pb.ioCompletion = nil;
- pb.ioNamePtr = gOurName;
- pb.ioVRefNum = 0;
- pb.ioRefNum = CurResFile();
- pb.ioFCBIndx = 0;
-
- err = PBGetFCBInfoSync(&pb);
-
- gOurVRefNum = pb.ioFCBVRefNum;
- gOurDirID = pb.ioFCBParID;
- }
-
-
- I patch InitAllPacks() so that I can re-open my resource fork just before the
- first application is run:
-
-
- static pascal void MyInitAllPacks(void)
- {
- SetUpA4();
-
- oldInitAllPacks();
-
- if (gMyRefNum == 0)
- OpenAndAddMe();
-
- RestoreA4();
- }
-
-
- OpenAndAddMe() opens the resource fork and shuffles it behind the System file:
-
-
- typedef struct ResourceMap{
- long dataOffset;
- long mapOffset;
- long dataLength;
- long mapLength;
- struct ResourceMap **nextMap;
- short refNum;
- short attributes;
- short typesOffset;
- short namesOffset;
- } ResourceMap, *ResMapPtr, **ResMapHandle;
-
- static void OpenAndAddMe()
- {
- THz currentZone;
-
- short oldFile;
- short refNum;
- ResMapHandle current = nil;
- ResMapHandle previous = nil;
- ResMapHandle ourParent = nil;
- ResMapHandle us = nil;
- ResMapHandle system = nil;
-
- currentZone = GetZone();
- SetZone(SystemZone());
-
- oldFile = CurResFile();
- refNum = InlineHOpenResFile(gOurVRefNum, gOurDirID, gOurName, fsRdPerm);
- UseResFile(oldFile);
-
- if (refNum != -1) {
-
- current = (ResMapHandle) TopMapHndl;
-
- // First, find us (we should be on top)
-
- while ((current != nil) && ((**current).refNum != refNum)) {
- previous = current;
- current = (**current).nextMap;
- }
- if (current != nil) {
- ourParent = previous;
- us = current;
- }
-
- // Second, find the System
-
- system = (ResMapHandle) SysMapHndl;
-
- if ((us == nil) || (system == nil)) {
- CloseResFile(refNum);
- } else {
- if (ourParent != system) {
-
- //
- // Be sure to perform all these steps so that the
- // resource chain is never inconsistant or circular.
- // If that happens, debuggers like TMON will detonate.
- //
- if ((ResMapHandle) TopMapHndl == us)
- TopMapHndl = (void*) (**us).nextMap;
- if (ourParent)
- (**ourParent).nextMap = (**us).nextMap;
- (**us).nextMap = (**system).nextMap;
- (**system).nextMap = us;
- }
- gMyRefNum = refNum;
- }
- }
- SetZone(currentZone);
- }
-
- I've checked the resource chain with this setup, and my INIT/cdev file appears
- to get opened twice when the cdev is opened.
-
- Hope this helps,
-
- --
- Keith Rollin
- Phantom Programmer
- Taligent, Inc.
-
-