source: trunk/third/cns/src/driver/driverInstall.c @ 8789

Revision 8789, 21.1 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r8788, which included commits to RCS files with non-trunk default branches.
Line 
1/* driver.c */
2
3/*
4 *      The following code is to install and remove RAM drivers in the system
5 *      heap. Written by Pete Resnick with the help of Joe Holt, Phil Shapiro,
6 *      Tom Johnson, Michael A. Libes, Matthias Urlichs, John Norstad, and
7 *      Charles Martin.
8 *
9 *      Change Log
10 *      ----------
11 *      Date:           Change:                                                                         Who:
12 *      -----           -------                                                                         ----
13 *      22 Jan 91       Changed "if (UTableSize < UnitNtryCnt) {"       pr
14 *                              to "if (UTableSize > UnitNtryCnt) {" in
15 *                              DriverAvail.
16 *
17 *      28 Jan 91       Make sure resource map is updated to            pr
18 *                              change back the resource ID's in
19 *                              InstallRAMDriver by adding code to
20 *                              SetResFileAttrs and UpdateResFile.
21 */
22
23#include <Files.h>
24#include <Types.h>
25#include <Events.h>
26#include <Memory.h>
27#include <Resources.h>
28#include <Errors.h>
29#include <Devices.h>
30#include <SysEqu.h>
31
32#include <StdArg.h>
33#include "driverInstall.h"
34
35
36#define LOW_UNIT                48              /* First Unit Table Entry to use        */
37#define NEW_UNIT                64              /* Size of a "normal" Unit Table        */
38#define MAX_UNIT                128             /* Maximum size of a Unit Table         */
39#define UP_UNIT                 4               /* Size to bounce up Unit Table         */
40#define SCCLockOut              0x2600  /* Disable interrupts flag                      */
41#define OKICONID                128
42#define NOGOICONID              130
43
44#define debugPrint(a,b,c) /* nothing */
45#define debugPrintH(a,b) /* nothing */
46#define debugPrintS(a,b) /* nothing */
47#define debugPrintL(a,b) /* nothing */
48
49
50pascal void main()
51{
52        short           refNum;
53        EventRecord evtRec;
54        OSErr err;
55        // char theChar;
56        THz saveZone,sysHeap;
57        // Ptr aPtr;
58        unsigned short ref;
59        err = 0;
60       
61        saveZone = GetZone();
62        sysHeap = SystemZone();
63        SetZone(sysHeap);
64
65        if( GetNextEvent( 0, &evtRec ) );       /* get a null event to check the modifiers */
66       
67        if( ( ( evtRec.modifiers  ^ btnState) & ( optionKey ) ) == 0
68                &&  (err = InstallRAMDriver( "\p.kerberos", &refNum, open | thinkDATA | thinkMultSeg ))
69                 == noErr ) {
70                ShowINIT( OKICONID, -1 );                       /* display OK icon */
71        }
72        else {
73                DebugStr("\pFailed InstallRAMDriver");
74                ShowINIT( NOGOICONID, -1 );                     /* display disabled icon */
75//              debugPrintS("Kerberos Install Error: ",&err);
76
77        }
78       
79        SetZone(saveZone);
80//      ref = (unsigned short) GetDrvrRefNum("\p.kerberos");
81//      debugPrintS("Driver Refnum:",&ref);
82}
83
84#if 0
85debugPrint(char *str,char *s,long i)
86{
87        char *s2;
88        long k;
89        long len;
90        len = strlen(str);
91        if (len) {
92                s2=&(str[len-1]);
93                for (k=0;k<len;k++,i++) *--s = *s2--;
94        }
95       
96        *--s = (char) i;
97//      DebugStr(s);
98}
99 
100
101debugPrintS(char *str, void *vn)
102{
103        char buf[512];
104        char *s;
105        unsigned long n = 0;
106        long i = 0;
107        s = &buf[512];
108       
109        if (vn) {
110                n = *((unsigned short *) vn);
111                for (; n; n /= 10, i++) *--s = n % 10 + '0';
112        }
113
114        debugPrint(str,s,i);
115}
116
117debugPrintL(char *str, void *vn)
118{
119        char buf[512];
120        char *s;
121        unsigned long n = 0;
122        long i = 0;
123        s = &buf[512];
124       
125        if (vn) {
126                n = *((unsigned long *) vn);
127                for (; n; n /= 10, i++) *--s = n % 10 + '0';
128        }
129       
130        debugPrint(str,s,i);
131}
132
133
134debugPrintH(char *str, void *vn)
135{
136        char buf[512];
137        char *s;
138        unsigned long n = 0;
139        long i;
140        s = &buf[512];
141       
142                n = *((unsigned long *) vn);
143                if (n) for (i=0; n; n /= 10, i++) *--s = n % 10 + '0';
144                else { *--s = '0'; i++; }
145                debugPrint(str,s,i);
146               
147                s = &buf[512];
148                n = GetHandleSize(*((Handle *) vn));
149                if (n) for (i=0; n; n /= 10, i++) *--s = n % 10 + '0';
150                else { *--s = '0'; i++; }
151                debugPrint("   handle size:",s,i);
152
153                s = &buf[512];
154                n = **((unsigned long **) vn);
155                n = (long) StripAddress((void *) n);
156                if (n) for (i=0; n; n /= 10, i++) *--s = n % 10 + '0';
157                else { *--s = '0'; i++; }
158                debugPrint("   ptr:",s,i);
159}
160#endif
161
162testControl()
163{
164        short dummyCode = 1;
165        ParamBlockRec aPBR;
166        short ref;
167        OSErr err;
168       
169        ref = GetDrvrRefNum("\p.kerberos");
170        if (!ref) {
171                DebugStr("\pCouldn't find driver in table");
172                return;
173        }
174        aPBR.cntrlParam.ioCompletion = nil;
175        aPBR.cntrlParam.ioVRefNum = 0;
176        aPBR.cntrlParam.ioCRefNum = ref;
177        aPBR.cntrlParam.csCode = dummyCode;
178
179        err = PBControl( &aPBR, false );
180        debugPrintS("Controltest rc: ",&err);           
181}
182
183
184/*
185 *      InstallRAMDriver will install the named driver into the system heap
186 *      locked and return the driver reference number in refNum. Make sure
187 *      that the DRVR resources are numbered between 0 and 47 and that the
188 *      resources owned by the driver are also numbered appropriately. Using
189 *      resource ID's of 48 and higher may cause conflicts if you are using
190 *      the THINK C global data DATA resource or the THINK C multi-segment
191 *      DCOD resource, which get temporarily renumbered by this routine.
192 *      One major kludge: the ioMisc field of the ioParam block is not used
193 *      for non-file operations, so it is used to store a pointer to a block
194 *      containing the addresses of the DCOD resources (if they are being
195 *      used) so that they can be removed by RemoveRAMDriver. If Apple ever
196 *      uses that field, that mechanism will be gone. See driver.h for the
197 *      drvrInstFlags.
198 */
199 
200OSErr InstallRAMDriver(Str255 drvrName, short *refNum, Byte drvrInstFlags)
201{
202        OSErr errCode;
203        /* FIXED jcm - Think sign extends the right shift unless unsigned */
204        unsigned short rsrcID, dcodRsrcID;
205        short index, unitNum, dcodSegments, dcodIndex;
206        ResType rsrcType;
207        Str255 rsrcName;
208        Handle dataHandle, drvrHandle, *dcodHList = nil, tempHandle;
209        IOParam openBlock;
210        register DriverPtr drvrPtr;
211        register DCtlPtr ctlEntryPtr;
212/*
213        DBGlines, 3:
214        long debugData;         //debug
215        Handle saveData;        //debug
216        short tempAttr;         //debug
217*/
218
219        /* Get the unit number for the driver */
220        errCode = DriverAvail(&unitNum);
221        /*
222        DebugStr("\pInstallRAMDriver - errCode = DriverAvail(&unitNum)");
223        */
224        if(errCode != noErr)
225                return(errCode);
226
227        /* The driver must load into the system heap locked. */
228        SetResLoad(false);
229        drvrHandle = Get1NamedResource('DRVR', drvrName);
230        /*
231        DebugStr("\pdrvrHandle = Get1NamedResource('DRVR'...)");
232        */
233        SetResLoad(true);
234        if(drvrHandle == nil)
235                return(dInstErr);
236        SetResAttrs( drvrHandle, GetResAttrs( drvrHandle ) | resSysHeap | resLocked );
237        if(ResErr != noErr) {
238                errCode = ResErr;
239                ReleaseResource(drvrHandle);
240                return(errCode);
241        }
242       
243        /* Save the resource info for later use */
244        /* FIXED jcm - Think needs a str255 for the last argument, not a ptr to one */
245        GetResInfo(drvrHandle, (short*) &rsrcID, &rsrcType, rsrcName);
246        if(ResErr != noErr) {
247                errCode = ResErr;
248                ReleaseResource(drvrHandle);
249                return(errCode);
250        }
251       
252        /* Now load it and detach it */
253        LoadResource(drvrHandle);
254        if(ResErr != noErr) {
255                errCode = ResErr;
256                ReleaseResource(drvrHandle);
257                return(errCode);
258        }
259        DetachResource(drvrHandle);
260
261        if(drvrInstFlags & thinkDATA) {
262                /*
263                 *      Make sure the DATA resource will load into the system heap,
264                 *      locked, and is owned by our driver, where the ID is the
265                 *      unitNum in bits 5 through 10 (or 11 if needed), zeros in
266                 *      bits 11 (if there is room) 12 and 13 (which means DRVR), zeros
267                 *      in bits 0 through 4 (since there is only 1 DATA resource), and
268                 *      ones in bits 14 and 15. If any errors occur after the resource
269                 *      ID is changed, it must be changed back!
270                 */
271                SetResLoad(false);
272                dataHandle = Get1Resource('DATA', (rsrcID << 5) | 0xC000);
273                /*
274                DebugStr("\pdataHandle = Get1Resource('DATA'...");
275                */
276                SetResLoad(true);
277                if(dataHandle == nil) {
278                        errCode = ResErr;
279                        DisposHandle(drvrHandle);
280                        DebugStr("\pFailed loading DATA, about to return");
281                        return(errCode != noErr ? errCode : resNotFound);
282                }
283                SetResAttrs(dataHandle, GetResAttrs (dataHandle) | resSysHeap | resLocked );
284                if(ResErr != noErr) {
285                        DebugStr("\pError SetResAttrs on DATA");
286                        errCode = ResErr;
287                        DisposHandle(drvrHandle);
288                        return(errCode);
289                }
290                SetResInfo(dataHandle, (unitNum << 5) | 0xC000, 0);
291                if(ResErr != noErr) {
292                        DebugStr("\pError SetResInfo dataHandle");
293                        errCode = ResErr;
294                        DisposHandle(drvrHandle);
295                        return(errCode);
296                }
297        /*
298        DBGLines, 1:
299                saveData = dataHandle;  //debug
300        */
301       
302        }
303
304        if(drvrInstFlags & thinkMultSeg) {
305                /*
306                 *      Make sure the DCOD resources will load into the system heap,
307                 *      locked, and are owned by our driver, where the ID is the
308                 *      unitNum in bits 5 through 10 (or 11 if needed), zeros in
309                 *      bits 11 (if there is room) 12 and 13 (which means DRVR),
310                 *      the same ID in bits 0 through 4, and ones in bits 14 and 15.
311                 *      Keep a block containing the handles to those segments so that
312                 *      they can be thrown away later if needed. If any errors
313                 *      occur after the resource ID's are changed, they are changed
314                 *      back in ReleaseDrvrSegments.
315                 */
316                dcodSegments = 0;
317                errCode = noErr;
318                SetResLoad(false);
319               
320                /* Count how many segments there are */
321                for(index = 1;
322                    (index <= Count1Resources('DCOD')) && (errCode == noErr);
323                    ++index) {
324                        tempHandle = Get1IndResource('DCOD', index);
325                        /*
326                        DebugStr("\ptempHandle = Get1IndResource('DCOD'...");
327                        */
328                        if(tempHandle == nil)
329                                errCode = (ResErr != noErr ? ResErr : resNotFound);
330                        /* Think wants a str255 not a pointer to one for the last argument */
331                        GetResInfo(tempHandle, (short*) &dcodRsrcID, &rsrcType, rsrcName);
332                        ReleaseResource(tempHandle);
333                        if((dcodRsrcID & ~0xF01F) >> 5 == rsrcID) {
334                                ++dcodSegments;
335                                /*
336                                DebugStr("\pDCOD belongs to theis rsrcID");
337                                */
338                        }
339                }
340                SetResLoad(true);
341
342                if(errCode != noErr) {
343                        DebugStr("\pError locating DCOD");
344                        if(drvrInstFlags & thinkDATA) {
345                                SetResInfo(dataHandle, (rsrcID << 5) | 0xC000, 0);
346                                SetResFileAttrs(CurResFile(),
347                                                GetResFileAttrs(index) | mapChanged);
348                                UpdateResFile(CurResFile());
349                                ReleaseResource(dataHandle);
350                        }
351                        DisposHandle(drvrHandle);
352                        return(errCode);
353                }
354
355                /* Get a block of memory to hold the handles */
356                dcodHList = (Handle *)NewPtrSysClear(sizeof(Handle) * dcodSegments);
357                /*
358                DebugStr("\pdcodHList = (Handle*)NewPtrSysClear...");
359                */
360                if(dcodHList == nil) {
361                        if(drvrInstFlags & thinkDATA) {
362                                SetResInfo(dataHandle, (rsrcID << 5) | 0xC000, 0);
363                                SetResFileAttrs(CurResFile(),
364                                                GetResFileAttrs(index) | mapChanged);
365                                UpdateResFile(CurResFile());
366                                ReleaseResource(dataHandle);
367                        }
368                        DisposHandle(drvrHandle);
369                        return(memFullErr);
370                }
371
372                /* Get the resources and change the attributes and ID's */
373                dcodIndex = 0;
374                SetResLoad(false);
375                for(index = 1;
376                    (index <= Count1Resources('DCOD')) && (errCode == noErr);
377                    ++index) {
378                        tempHandle = Get1IndResource('DCOD', index);
379                        if(tempHandle == nil) {
380                                errCode = (ResErr != noErr ? ResErr : resNotFound);
381                        } else {
382                        /* Think wants a Str255 as the last argument not a pointer to one */
383                                GetResInfo(tempHandle, (short*) &dcodRsrcID, &rsrcType, rsrcName);
384
385                        /*
386                                debugPrintH("DCOD Handle: ",&tempHandle);
387                        */
388                               
389                                if((dcodRsrcID & ~0xF01F) >> 5 == rsrcID) {
390                                        dcodHList[dcodIndex] = tempHandle;
391                                        /*
392                                        DebugStr("\pdcodHList[dcodIndex]= tempHandle");
393                                        */
394                                        SetResAttrs( dcodHList[ dcodIndex ],
395                                                                 GetResAttrs( dcodHList[ dcodIndex ] ) | resSysHeap | resLocked );
396                                        if(ResErr != noErr) {
397                                                errCode = ResErr;
398                                                DebugStr("\pFailed SetResAttrs dcodH");
399                                        } else {
400                                                SetResInfo(dcodHList[dcodIndex],
401                                                                        (dcodRsrcID & 0xF01F) + (unitNum << 5),
402                                                                        0);
403                                                errCode = ResErr;
404                                        }
405
406                                /*
407                                        debugData = GetResAttrs(dcodHList[dcodIndex]);
408                                        debugPrintL("Set rez info: ",&debugData);
409                                        debugData = (long) tempHandle;
410                                */
411                                        ++dcodIndex;
412                                }
413                               
414/*
415                                debugPrintH("DCOD Handle after: ",&tempHandle);
416*/
417                        }
418                }
419                SetResLoad(true);
420               
421                if(errCode != noErr) {
422                        DebugStr("\pError changing DCOD resources");
423                        if(drvrInstFlags & thinkDATA) {
424                                SetResInfo(dataHandle, (rsrcID << 5) | 0xC000, 0);
425                                ReleaseResource(dataHandle);
426                        }
427                        ReleaseDrvrSegments(dcodHList, rsrcID, false);
428                        DisposHandle(drvrHandle);
429                        return(dInstErr);
430                }
431        }
432                   
433        /* Install with the refNum. The refNum is the -(unitNum + 1) */
434        errCode = DrvrInstall(drvrHandle, ~unitNum);
435        if(errCode != noErr) {
436                DebugStr("\pError returned from DrvrInstall. About to free DATA and DCOD");
437                if(drvrInstFlags & thinkDATA) {
438                        SetResInfo(dataHandle, (rsrcID << 5) | 0xC000, 0);
439                        SetResFileAttrs(CurResFile(),
440                                        GetResFileAttrs(index) | mapChanged);
441                        UpdateResFile(CurResFile());
442                        ReleaseResource(dataHandle);
443                }
444                if(drvrInstFlags & thinkMultSeg)
445                        ReleaseDrvrSegments(dcodHList, rsrcID, false);
446                DisposHandle(drvrHandle);
447                return(dInstErr);
448        }
449       
450        /* Move the important information to the driver entry */
451        ctlEntryPtr = *(UTableBase[unitNum]);
452        drvrPtr = *(DriverHandle)drvrHandle;
453        ctlEntryPtr->dCtlDriver = (Ptr)drvrHandle;
454        ctlEntryPtr->dCtlFlags = drvrPtr->drvrFlags;
455        ctlEntryPtr->dCtlDelay = drvrPtr->drvrDelay;
456        ctlEntryPtr->dCtlEMask = drvrPtr->drvrEMask;
457        ctlEntryPtr->dCtlMenu = drvrPtr->drvrMenu;
458        ctlEntryPtr->dCtlFlags |= dRAMBased;
459        /*
460        DebugStr("\pdctlEntry updated with driver header info");
461        */
462       
463        /* Hang onto the refNum just in case open changes it. */
464        index = CurResFile();
465       
466        /*
467         *      The open routine better load all the DATA and DCOD resources. If
468         *      the driver is going to want to be closed, it should store what
469         *      is passed to it in ioMisc and pass it back when close is called.
470         */
471
472/*
473        debugPrintS("Flags before open: ",&(ctlEntryPtr->dCtlFlags));
474        debugPrintH("Driver Handle: ",&drvrHandle);
475*/
476        if(drvrInstFlags & open) {
477                openBlock.ioCompletion = nil;
478                openBlock.ioNamePtr = drvrName;
479                openBlock.ioPermssn = fsCurPerm;
480                openBlock.ioMisc = (Ptr)dcodHList;
481                /*
482                DebugStr("\pCalling PBOpen");
483                */
484                errCode = PBOpen( (ParmBlkPtr) &openBlock, false);
485        }
486
487/*
488        debugPrintH("DCOD Handle after open: ",&debugData);
489        tempAttr = GetResAttrs((Handle) debugData);     // debug
490        debugPrintS("DCOD Attrs: ",&tempAttr);
491        debugPrintS("Flags after open: ",&(ctlEntryPtr->dCtlFlags));
492*/
493        testControl();  //debug
494       
495        /* Change CurResFile back to our original one. */
496        UseResFile(index);
497       
498        if(drvrInstFlags & thinkDATA) {
499                /*
500                 *      If the open was successful, the dataHandle will be detached.
501                 *      If the open failed, dataHandle may or may not be an attached
502                 *      resource, but probably isn't attached. Therefore, the resource
503                 *      must be retrieved to change the resource ID back, just in case
504                 *      the open routine changed the file's resource map. After that,
505                 *      release it. Errors here will be horrific because the file will
506                 *      basically be corrupted if the ID can't be changed back, so
507                 *      don't bother checking. At this point in the game, errors
508                 *      shouldn't occur anyway.
509                 */
510                SetResLoad(false);
511                dataHandle = Get1Resource('DATA', (unitNum << 5) | 0xC000);
512                SetResLoad(true);
513                if(dataHandle != nil) {
514                        /* DebugStr("\pAfter open DATA handle not nil"); */
515                        SetResInfo(dataHandle, (rsrcID << 5) | 0xC000, 0);
516                        SetResFileAttrs(CurResFile(),
517                                        GetResFileAttrs(index) | mapChanged);
518                        UpdateResFile(CurResFile());
519                        ReleaseResource(dataHandle);
520                }
521        }
522       
523        /* If an error occurred during the open */
524        if(errCode != noErr) {
525                DebugStr("\pError during open - removing RAM driver");
526                RemoveRAMDriver(~unitNum, false);
527                if(drvrInstFlags & thinkMultSeg)
528                        ReleaseDrvrSegments(dcodHList, rsrcID, false);
529        }
530        else {
531        if(drvrInstFlags & thinkMultSeg)
532                ReleaseDrvrSegments(dcodHList, rsrcID, true);
533        *refNum = ~unitNum;
534        }
535
536
537/*
538        DebugStr("\pEnd of rtn");
539        debugPrintH("DCOD Handle: ",&debugData);
540        debugPrintS("Driver Unit Number: ",&unitNum);
541        debugPrintH("Driver Handle: ",&drvrHandle);
542        debugPrintH("Data Handle: ",&saveData);
543        debugPrintH("Code (temp) Handle: ",&tempHandle);
544*/
545        /*
546        DebugStr("\pDone installing driver!");
547        */
548        return(errCode);
549}
550
551/*
552 *      Removes the driver installed in the system heap by InstallRAMDriver.
553 *      See the warning on InstallRAMDriver about the ioMisc field.
554 */
555
556OSErr RemoveRAMDriver(short refNum, Boolean dcodRemove)
557{
558        OSErr errCode = noErr, dcodHandles, index;
559        Handle dataHandle = nil, *dcodHList = nil, drvrHandle;
560        IOParam closeBlock;
561       
562        /* If the driver is open, close it */
563        if((**UTableBase[~refNum]).dCtlFlags & dOpened) {
564                closeBlock.ioCompletion = nil;
565                closeBlock.ioRefNum = refNum;
566                errCode = PBClose((ParmBlkPtr) &closeBlock, false);
567                if(errCode != noErr)
568                        return(errCode);
569                dcodHList = (Handle*) closeBlock.ioMisc;
570                dataHandle = (Handle)(**UTableBase[~refNum]).dCtlStorage;
571        }
572       
573        /*
574         *      Since the driver has been detached, it will have to be disposed of
575         *      later since DrvrRemove just does a ReleaseResource on the handle.
576         */
577        drvrHandle = (Handle)(**UTableBase[~refNum]).dCtlDriver;
578        errCode = DrvrRemove(refNum);
579        if(errCode != noErr)
580                return(errCode);
581        if(drvrHandle != nil) {
582                DisposHandle(drvrHandle);
583                if(dcodRemove && (dcodHList != nil)) {
584
585                        /*      The driver has passed back the handles to its segments so
586                         *      they can be disposed of.
587                         */
588                        dcodHandles = GetPtrSize((Ptr) &dcodHList) / sizeof(Handle);
589                        for(index = 0; index < dcodHandles; ++index)
590                                DisposHandle(dcodHList[index]);
591                        DisposPtr((Ptr) dcodHList);
592                }
593        }
594        return(noErr);
595}
596
597short GetDrvrRefNum(Str255 drvrName)
598{
599        short unitNum;
600        DCtlHandle curDCtlEntry;
601        DriverPtr curDrvrPtr;
602        long temp;              // debug
603        Handle thandle;
604       
605        /* Walk through the Unit Table */
606        for(unitNum = 0; unitNum < UnitNtryCnt; ++unitNum) {
607                curDCtlEntry = GetDCtlEntry(~unitNum);
608                if(curDCtlEntry != nil) {
609                /*
610                DebugStr("\pcurDCtlEntry");
611                */
612               
613                        /* If this is a RAM driver, it's a handle. ROM is a pointer */
614/*
615                        temp = (long) ((**curDCtlEntry).dCtlFlags);     //debug
616                        debugPrintL("Flags: ",&temp);
617                        temp = (long) ((**curDCtlEntry).dCtlDriver);    //debug
618*/
619                        if((**curDCtlEntry).dCtlFlags & dRAMBased) {
620                                curDrvrPtr = *(DriverHandle)(**curDCtlEntry).dCtlDriver;
621/*
622                                debugPrintH("Ram driver handle: ",&temp);
623*/
624                        }
625                        else {
626                                curDrvrPtr = (DriverPtr)(**curDCtlEntry).dCtlDriver;
627/*
628                                debugPrintL("Rom driver Ptr: ",&temp);
629*/
630                        }
631                       
632                        /* Does the driver name match? */
633                        if(curDrvrPtr != nil)
634                       
635                        /*
636                        DebugStr("\pcurDrvrPtr");
637                        */
638                       
639                                if(EqualString(drvrName, curDrvrPtr->drvrName,
640                                               false, false)) {
641/*
642                                        DebugStr(curDrvrPtr->drvrName);
643                                        debugPrintS("Driver Unit Number: ",&unitNum);
644                                        thandle = (**curDCtlEntry).dCtlStorage;
645                                        debugPrintH("Driver Storage handle: ",&thandle);
646*/
647                                        return(~unitNum);
648                                }
649                }
650        }
651        DebugStr("\pCouldn't find driver");
652        return(0);
653}
654
655OSErr GrowUTable(short newEntries)
656{
657        DCtlHandle *newUTableBase;
658        short savedStatus;
659       
660        /*
661        DebugStr("\pGrowUTable");
662        */
663       
664        /* Make room for the new Unit Table */
665        newUTableBase = (DCtlHandle *)NewPtrSysClear((UnitNtryCnt + newEntries)
666                                                                                                        * sizeof(DCtlHandle));
667        if(MemError() != noErr)
668                return(MemError());
669               
670        savedStatus = DisableInterrupts();
671        /*
672        FIXME jcm - Turning Think inline assembler into standalone .a procs for MPW
673        asm {
674                MOVE    SR,-(SP)                ; Save status register
675                MOVE    #SCCLockOut,SR  ; Disable interrupts
676        }
677        */
678       
679        /* Move the old Unit Table to the new Unit Table */
680        BlockMove((void *)UTableBase,(void *)newUTableBase, UnitNtryCnt * sizeof(DCtlHandle));
681        DisposPtr((Ptr) UTableBase);
682        UTableBase = newUTableBase;
683        UnitNtryCnt += newEntries;
684       
685        EnableInterrupts(savedStatus);
686        /*
687        FIXME jcm - Turning Think inline assembler into stadalone .a procs for MPW
688        asm {
689                MOVE    (SP)+,SR                ; Restore status register
690        }
691        */
692       
693        return(noErr);
694}
695
696OSErr DriverAvail(short *unitNum)
697{
698        short unitIndex;
699        Size UTableSize;
700        OSErr errCode = noErr;
701       
702        *unitNum = 0;
703       
704        /* Increase Unit Table size for Mac Plus */
705        if(UnitNtryCnt <= LOW_UNIT)
706                errCode = GrowUTable(NEW_UNIT - UnitNtryCnt);
707        if(errCode != noErr)
708                return(errCode);
709       
710        /* Look for an empty slot in what's already there */
711        for(unitIndex = LOW_UNIT;
712                        (unitIndex < UnitNtryCnt) && (*unitNum == 0);
713                        ++unitIndex)
714                       
715                if(UTableBase[unitIndex] == nil) {
716                        *unitNum = unitIndex;
717                        /*
718                        DebugStr("\p*unitNum = unitIndex, under UnitNtryCnt");
719                        */
720                }
721       
722        /* Unit Table full up to UnitNtryCnt, so increase it */
723        if(*unitNum == 0) {
724                UTableSize = GetPtrSize((Ptr)UTableBase) / sizeof(DCtlHandle);
725               
726                /* If there is space in the Unit Table, just up the count */
727                if(UTableSize > UnitNtryCnt) {
728                        *unitNum = UnitNtryCnt;
729                        /*
730                        DebugStr("\p*unitNum = UnitNtryCnt. UTableSize > UnitNtryCnt");
731                        */
732                        UnitNtryCnt += (UTableSize - UnitNtryCnt < UP_UNIT
733                                                                ? UTableSize - UnitNtryCnt
734                                                                : UP_UNIT);
735               
736               
737                /* If there isn't enough space, try to increase it */
738                } else {
739                        if(MAX_UNIT - UnitNtryCnt != 0) {
740                                unitIndex = UnitNtryCnt;
741                                errCode = GrowUTable(MAX_UNIT - UnitNtryCnt < UP_UNIT
742                                                                                ? MAX_UNIT - UnitNtryCnt
743                                                                                : UP_UNIT);
744                                if(errCode != noErr)
745                                        return(errCode);
746                                *unitNum = unitIndex;
747                                /*
748                                DebugStr("\p*unitNum = unitIndex. grow utable to max.");
749                                */
750                        }
751                }
752        }
753        if(*unitNum == 0)
754                return(unitTblFullErr);
755        else
756                return(noErr);
757}
758
759void ReleaseDrvrSegments(Handle *dcodHList, short rsrcID, Boolean detach)
760{
761        short index, dcodHandles, dcodRsrcID;
762        Handle tempHandle;      //debug
763        ResType rsrcType;
764        Str255 rsrcName;
765       
766        dcodHandles = GetPtrSize((Ptr) /*&*/dcodHList) / sizeof(Handle);
767        debugPrintS("ReleaseDrvrSegments: ",&dcodHandles);
768        if(rsrcID != 0) {
769                for(index = 0; index < dcodHandles; ++index)
770                        if(dcodHList[index]) {
771                                /* FIXED jcm - Think wants a Str255 not a pointer to one as the last arg */
772                                GetResInfo(dcodHList[index], &dcodRsrcID,
773                                           &rsrcType, rsrcName);
774                                SetResInfo(dcodHList[index],
775                                                        (dcodRsrcID & 0xF01F) + (rsrcID << 5),
776                                                        0);
777                        }
778                SetResFileAttrs(CurResFile(), GetResFileAttrs(index) | mapChanged);
779                UpdateResFile(CurResFile());
780        }
781        for(index = 0; index < dcodHandles; ++index)
782                if(dcodHList[index]) {
783                        if(detach) {
784                                tempHandle = dcodHList[index];  // debug
785                                DetachResource(dcodHList[index]);
786                        }
787                        else
788                                ReleaseResource(dcodHList[index]);
789                }
790        if(!detach)
791                DisposPtr((Ptr)dcodHList);
792}
Note: See TracBrowser for help on using the repository browser.