home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / comp / sys / mac / programm / 14959 < prev    next >
Encoding:
Text File  |  1992-09-03  |  4.4 KB  |  169 lines

  1. Newsgroups: comp.sys.mac.programmer
  2. Path: sparky!uunet!sun-barr!ames!data.nas.nasa.gov!taligent!keith@taligent.com
  3. From: keith@taligent.com (Keith Rollin)
  4. Subject: Re: Problem writing INIT/cdev
  5. Message-ID: <Bu0qMw.4Ev@taligent.com>
  6. Sender: usenet@taligent.com (More Bytes Than You Can Read)
  7. Organization: Taligent
  8. References: <1992Aug27.002347.14632@vax5.cit.cornell.edu> <Sep.3.01.53.43.1992.13837@math.rutgers.edu>
  9. Distribution: comp
  10. Date: Thu, 3 Sep 1992 20:08:55 GMT
  11. Lines: 156
  12.  
  13. In article <Sep.3.01.53.43.1992.13837@math.rutgers.edu>,
  14. landwebe@math.rutgers.edu (Peter Landweber) writes:
  15. >      I am working on an INIT/cdev combination to be used under System
  16. > 7, and I've run into a problem.
  17. >      At startup time, the INIT moves its resource map after the system
  18. > resource map in the linked list, and it patches CloseResFile() to
  19. > ignore the file.  The result is that my file stays open, and its
  20. > resources are always available.  This is similar to what Suitcase II
  21. > does with font suitcases.  So far everything has gone extremely well 
  22. > using this technique.
  23. >      Now, I'm trying to add a "cdev".  The problem is that when the
  24. > finder opens up my file as a Control Panel, it expects my file's
  25. > resource map to be the first in the linked list.  Since the resource
  26. > map is actually at the end of the linked list, the finder crashes.
  27. > So, my questions are:
  28. > 1)  Is there a way for the Finder to open up a Control Panel if the
  29. > file is already open, and its resource map is not at the front of the
  30. > linked list?
  31. > 2)  Is there a way to open a file twice, with two separate resource
  32. > maps?  That way, I could still have one resource map linked after the
  33. > system resource map, and the other at the front of the linked list.
  34. > One of the maps could be read-only if necessary.
  35.  
  36. I have an INIT/cdev that does the same thing. However, it takes a little
  37. different approach than yours, and it seems to work.
  38.  
  39. First, I don't patch CloseResFile() to keep my file open. Instead, at INIT time,
  40. I install my code, remember the file I came from, and patch InitAllPacks(). I
  41. remember my file of origin with the following routine.
  42.  
  43.  
  44. static void    RememberMe()
  45. {
  46.     FCBPBRec    pb;
  47.     OSErr        err;
  48.  
  49.     pb.ioCompletion = nil;
  50.     pb.ioNamePtr = gOurName;
  51.     pb.ioVRefNum = 0;
  52.     pb.ioRefNum = CurResFile();
  53.     pb.ioFCBIndx = 0;
  54.     
  55.     err = PBGetFCBInfoSync(&pb);
  56.     
  57.     gOurVRefNum = pb.ioFCBVRefNum;
  58.     gOurDirID = pb.ioFCBParID;
  59. }
  60.  
  61.  
  62. I patch InitAllPacks() so that I can re-open my resource fork just before the
  63. first application is run:
  64.  
  65.  
  66. static pascal void    MyInitAllPacks(void)
  67. {
  68.     SetUpA4();
  69.     
  70.     oldInitAllPacks();
  71.     
  72.     if (gMyRefNum == 0)
  73.         OpenAndAddMe();
  74.         
  75.     RestoreA4();
  76. }
  77.  
  78.  
  79. OpenAndAddMe() opens the resource fork and shuffles it behind the System file:
  80.  
  81.  
  82. typedef struct ResourceMap{
  83.     long        dataOffset;
  84.     long        mapOffset;
  85.     long        dataLength;
  86.     long        mapLength;
  87.     struct ResourceMap    **nextMap;
  88.     short        refNum;
  89.     short        attributes;
  90.     short        typesOffset;
  91.     short        namesOffset;
  92. } ResourceMap, *ResMapPtr, **ResMapHandle;
  93.  
  94. static void    OpenAndAddMe()
  95. {
  96.     THz                currentZone;
  97.  
  98.     short            oldFile;
  99.     short            refNum;
  100.     ResMapHandle    current = nil;
  101.     ResMapHandle    previous = nil;
  102.     ResMapHandle    ourParent = nil;
  103.     ResMapHandle    us = nil;
  104.     ResMapHandle    system = nil;
  105.     
  106.     currentZone = GetZone();
  107.     SetZone(SystemZone());
  108.  
  109.     oldFile = CurResFile();
  110.     refNum = InlineHOpenResFile(gOurVRefNum, gOurDirID, gOurName, fsRdPerm);
  111.     UseResFile(oldFile);
  112.     
  113.     if (refNum != -1) {
  114.  
  115.         current = (ResMapHandle) TopMapHndl;
  116.         
  117.         // First, find us (we should be on top)
  118.  
  119.         while ((current != nil) && ((**current).refNum != refNum)) {
  120.             previous = current;
  121.             current = (**current).nextMap;
  122.         }
  123.         if (current != nil) {
  124.             ourParent = previous;
  125.             us = current;
  126.         }
  127.         
  128.         // Second, find the System
  129.         
  130.         system = (ResMapHandle) SysMapHndl;
  131.         
  132.         if ((us == nil) || (system == nil)) {
  133.             CloseResFile(refNum);
  134.         } else {
  135.             if (ourParent != system) {
  136.             
  137.             //
  138.             // Be sure to perform all these steps so that the
  139.             // resource chain is never inconsistant or circular.
  140.             // If that happens, debuggers like TMON will detonate.
  141.             //
  142.                 if ((ResMapHandle) TopMapHndl == us)
  143.                     TopMapHndl = (void*) (**us).nextMap;
  144.                 if (ourParent)
  145.                     (**ourParent).nextMap = (**us).nextMap;
  146.                 (**us).nextMap = (**system).nextMap;
  147.                 (**system).nextMap = us;
  148.             }
  149.             gMyRefNum = refNum;
  150.         }
  151.     }
  152.     SetZone(currentZone);
  153. }
  154.  
  155. I've checked the resource chain with this setup, and my INIT/cdev file appears
  156. to get opened twice when the cdev is opened.
  157.  
  158. Hope this helps,
  159.  
  160. --
  161. Keith Rollin
  162. Phantom Programmer
  163. Taligent, Inc.
  164.  
  165.