Annotation of driverkit/libDriver/User/IOConfigTable.m, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
                      7:  * Reserved.  This file contains Original Code and/or Modifications of
                      8:  * Original Code as defined in and that are subject to the Apple Public
                      9:  * Source License Version 1.1 (the "License").  You may not use this file
                     10:  * except in compliance with the License.  Please obtain a copy of the
                     11:  * License at http://www.apple.com/publicsource and read it before using
                     12:  * this file.
                     13:  * 
                     14:  * The Original Code and all software distributed under the License are
                     15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
                     19:  * License for the specific language governing rights and limitations
                     20:  * under the License.
                     21:  * 
                     22:  * @APPLE_LICENSE_HEADER_END@
                     23:  */
                     24: /*     Copyright (c) 1993 NeXT Computer, Inc.  All rights reserved. 
                     25:  *
                     26:  * User level implementation of IOConfigTable.
                     27:  *
                     28:  * HISTORY
                     29:  * 27-Jan-93    Doug Mitchell at NeXT
                     30:  *      Created.
                     31:  */
                     32: 
                     33: #import <driverkit/IOConfigTable.h>
                     34: #import <driverkit/IODevice.h>
                     35: #import <driverkit/configTablePrivate.h>
                     36: #import <driverkit/generalFuncs.h>
                     37: #import <driverkit/driverServer.h>
                     38: #import <driverkit/driverTypesPrivate.h>
                     39: #import <streams/streams.h>
                     40: #import <objc/NXStringTable.h>
                     41: #import <libc.h>
                     42: 
                     43: static void parseDriverList(const char *driverList, List *list);
                     44: 
                     45: @interface IOConfigTable(Private)
                     46: + openForFile : (const char *)filename;
                     47: @end
                     48: 
                     49: /*
                     50:  * The _private ivar points to one of these.
                     51:  */
                     52: typedef struct {
                     53:        NXStringTable   *stringTable;
                     54:        const char      *bundleName;            // associated directory 
                     55: } _configPriv;
                     56: 
                     57: @implementation IOConfigTable
                     58: 
                     59: - free
                     60: {
                     61:        _configPriv *configPriv = _private;
                     62:        
                     63:        if(configPriv) {
                     64:                if(configPriv->stringTable) {
                     65:                        [configPriv->stringTable free];
                     66:                }
                     67:                if(configPriv->bundleName) {
                     68:                        IOFree((void *)configPriv->bundleName, 
                     69:                                strlen(configPriv->bundleName) + 1);
                     70:                }
                     71:                IOFree(configPriv, sizeof(_configPriv));
                     72:        }
                     73:        return [super free];
                     74: }
                     75: 
                     76: /*
                     77:  * Obtain the system-wide configuration table.
                     78:  */
                     79: #define SYSTEM_CONFIG_FROM_RPC 1
                     80: 
                     81: + newFromSystemConfig
                     82: {
                     83: #if    SYSTEM_CONFIG_FROM_RPC
                     84:        
                     85:        IOReturn        rtn;
                     86:        IOConfigData    configData;
                     87:        unsigned        size = IO_CONFIG_TABLE_SIZE;
                     88:        NXStream        *stream;
                     89:        NXStringTable   *stringTable;
                     90:        int             len;
                     91:        IOConfigTable   *newObj = [self alloc];
                     92:        port_t          deviceMaster = device_master_self();
                     93:        _configPriv     *configPriv;
                     94:        
                     95:        /*
                     96:         * Get system config data from the kernel.
                     97:         */
                     98:        rtn = _IOGetSystemConfig(deviceMaster,
                     99:                IO_CONFIG_TABLE_SIZE, 
                    100:                configData,
                    101:                &size);
                    102:        if(rtn) {
                    103:                IOLog("IOConfigTable: _IOGetSystemConfig: %s\n",
                    104:                        [IODevice stringFromReturn:rtn]);
                    105:                return nil;
                    106:        }
                    107: 
                    108:        /*
                    109:         * Create a stream, write raw table to it.
                    110:         */
                    111:        stream = NXOpenMemory(NULL, 0, NX_READWRITE);
                    112:        len = strlen(configData);
                    113:        NXWrite(stream, configData, len);
                    114:        NXSeek(stream, 0, NX_FROMSTART);
                    115:        
                    116:        /*
                    117:         * Create string table, write stream to it.
                    118:         */
                    119:        stringTable = [[NXStringTable alloc] init];
                    120:        if([stringTable readFromStream:stream] == nil) {
                    121:                IOLog("IOConfigTable: readFromStream returned nil\n");
                    122:                [stringTable free];
                    123:                return nil;
                    124:        }
                    125:        configPriv = newObj->_private = IOMalloc(sizeof(_configPriv));
                    126:        configPriv->stringTable = stringTable;
                    127:        configPriv->bundleName = NULL;
                    128:        return newObj;
                    129: 
                    130: #else  SYSTEM_CONFIG_FROM_RPC
                    131:        return [self openForFile:IO_SYSTEM_CONFIG_FILE];
                    132: #endif SYSTEM_CONFIG_FROM_RPC
                    133: }
                    134: 
                    135: /*
                    136:  * Obtain the configuration table for a specified device and unit number. 
                    137:  * ("Unit number" is terminology from IODevice.h. We've been calling it 
                    138:  * "instance number" in the context of system config and startup.)
                    139:  */
                    140: + newForDriver                         : (const char *)driverName
                    141:                                   unit : (int)unit
                    142: {
                    143:        char            filename[200];
                    144:        IOConfigTable   *newObj;
                    145:        _configPriv     *configPriv;
                    146:        int             length;
                    147:        char            *bundleName;
                    148:        
                    149:        sprintf(filename, "%s%s%s/Instance%d%s", 
                    150:                IO_CONFIG_DIR, driverName, IO_BUNDLE_EXTENSION,
                    151:                unit, IO_TABLE_EXTENSION);
                    152:        newObj = (IOConfigTable *)[self openForFile:filename];
                    153:        if(newObj == nil) {
                    154:                return nil;
                    155:        }
                    156:        configPriv = newObj->_private;
                    157:        sprintf(filename, "%s%s%s", 
                    158:                IO_CONFIG_DIR, driverName, IO_BUNDLE_EXTENSION);
                    159:        length = strlen(filename) + 1;
                    160:        bundleName = IOMalloc(length);
                    161:        strcpy(bundleName, filename);
                    162:        configPriv->bundleName = bundleName;
                    163:        return newObj;
                    164: }
                    165: 
                    166: + newDefaultTableForDriver             : (const char *)driverName
                    167: {
                    168:        char            filename[200];
                    169:        IOConfigTable   *newObj;
                    170:        _configPriv     *configPriv;
                    171:        int             length;
                    172:        char            *bundleName;
                    173:        
                    174:        sprintf(filename, "%s%s%s/%s", 
                    175:                IO_CONFIG_DIR, driverName, IO_BUNDLE_EXTENSION,
                    176:                IO_DEFAULT_TABLE_FILENAME);
                    177:        newObj = (IOConfigTable *)[self openForFile:filename];
                    178:        if(newObj == nil) {
                    179:                return nil;
                    180:        }
                    181:        configPriv = newObj->_private;
                    182:        sprintf(filename, "%s%s%s", 
                    183:                IO_CONFIG_DIR, driverName, IO_BUNDLE_EXTENSION);
                    184:        length = strlen(filename) + 1;
                    185:        bundleName = IOMalloc(length);
                    186:        strcpy(bundleName, filename);
                    187:        configPriv->bundleName = bundleName;
                    188:        return newObj;
                    189: }
                    190:        
                    191:        
                    192: /*
                    193:  * Obtain a list of instances of IOConfigTable, one per {boot, active} 
                    194:  * device on the system.
                    195:  */
                    196: + (List *) tablesForInstalledDrivers
                    197: {
                    198:        List            *list;
                    199:        IOConfigTable   *systemConfig;
                    200:        const char      *drivers;
                    201:        
                    202:        list = [[List alloc] init];
                    203:        systemConfig = [self newFromSystemConfig];
                    204:        if(systemConfig == nil) {
                    205:                IOLog("tablesForInstalledDrivers: no system config file"
                    206:                        " found\n");
                    207:                return nil;
                    208:        }
                    209:        drivers = [systemConfig valueForStringKey:"Boot Drivers"];
                    210:        parseDriverList(drivers, list);
                    211:        drivers = [systemConfig valueForStringKey:"Active Drivers"];
                    212:        parseDriverList(drivers, list);
                    213:        if([list count] == 0) {
                    214:                IOLog("installedDrivers: no drivers found\n");
                    215:        }
                    216:        return list;
                    217: }
                    218: 
                    219: /*
                    220:  * Obtain a list of instances of IOConfigTable, one per driver
                    221:  * loaded by the booter.
                    222:  */
                    223: + (List *) tablesForBootDrivers
                    224: {
                    225:     List               *list;
                    226:     IOReturn           rtn;
                    227:     int                        i;
                    228:     IOConfigData       configData;
                    229:     unsigned           size;
                    230:     port_t             deviceMaster = device_master_self();
                    231:     NXStream           *stream;
                    232:     NXStringTable      *stringTable;
                    233:     int                len;
                    234:     IOConfigTable      *newTable;
                    235:     _configPriv                *configPriv;
                    236:     
                    237:     list = [[List alloc] init];
                    238:     for (i=1; ; i++) {
                    239:        /*
                    240:         * Get system config data from the kernel.
                    241:         */
                    242:        size = IO_CONFIG_TABLE_SIZE;
                    243:        rtn = _IOGetDriverConfig(deviceMaster,
                    244:                i,
                    245:                IO_CONFIG_TABLE_SIZE, 
                    246:                configData,
                    247:                &size);
                    248:        if(rtn != IO_R_SUCCESS) {
                    249:            if (rtn != IO_R_NO_DEVICE) {
                    250:                IOLog("IOConfigTable: _IOGetDriverConfig: %s\n",
                    251:                        [IODevice stringFromReturn:rtn]);
                    252:                [list free];
                    253:                return nil;
                    254:            }
                    255:            break;
                    256:        }
                    257: 
                    258:        /*
                    259:         * Create a stream, write raw table to it.
                    260:         */
                    261:        stream = NXOpenMemory(NULL, 0, NX_READWRITE);
                    262:        len = strlen(configData);
                    263:        NXWrite(stream, configData, len);
                    264:        NXSeek(stream, 0, NX_FROMSTART);
                    265:     
                    266:        /*
                    267:         * Create string table, write stream to it.
                    268:         */
                    269:        stringTable = [[NXStringTable alloc] init];
                    270:        if([stringTable readFromStream:stream] == nil) {
                    271:                IOLog("IOConfigTable: readFromStream returned nil\n");
                    272:                [stringTable free];
                    273:                return nil;
                    274:        }
                    275:        newTable = [self alloc];
                    276:        configPriv = newTable->_private = IOMalloc(sizeof(_configPriv));
                    277:        configPriv->stringTable = stringTable;
                    278:        configPriv->bundleName = NULL;
                    279:        [list addObject:newTable];
                    280:     }
                    281:     return list;
                    282: }
                    283: 
                    284: /*
                    285:  * Obtain an NXBundle for a driver associated with current IOConfigTable
                    286:  * instance.
                    287:  */
                    288: - (NXBundle *)driverBundle; 
                    289: 
                    290: {
                    291:        NXBundle        *bundle;
                    292:        _configPriv     *configPriv = _private;
                    293:                        
                    294:        if(configPriv->bundleName == NULL) {
                    295:                /*
                    296:                 * Must be system config; no can do.
                    297:                 */
                    298:                return nil;
                    299:        }
                    300:        bundle = [NXBundle alloc];
                    301:        return [bundle initForDirectory:configPriv->bundleName];
                    302: }
                    303: 
                    304: 
                    305: /*
                    306:  * Obtain value for specified string key, string and unsigned int versions.
                    307:  *
                    308:  * String version. Returns NULL if key not found.
                    309:  */
                    310: - (const char *)valueForStringKey:(const char *)key
                    311: {
                    312:        _configPriv *configPriv = _private;
                    313:        NXStringTable *stringTable = configPriv->stringTable;
                    314:        
                    315:        return [stringTable valueForStringKey:key];
                    316: }
                    317: 
                    318: @end
                    319: 
                    320: @implementation IOConfigTable(Private)
                    321: 
                    322: + openForFile : (const char *)filename
                    323: {
                    324:        IOConfigTable *newObj = [self alloc];
                    325:        NXStringTable *stringTable = [[NXStringTable alloc] init];
                    326:        _configPriv *configPriv;
                    327:        
                    328:        newObj->_private = nil;
                    329:        if([stringTable readFromFile:filename] == nil) {
                    330:                [newObj free];
                    331:                [stringTable free];
                    332:                return nil;
                    333:        }
                    334:        configPriv = newObj->_private = IOMalloc(sizeof(_configPriv));
                    335:        configPriv->stringTable = stringTable;
                    336:        configPriv->bundleName = NULL;
                    337:        return newObj;
                    338: }
                    339: 
                    340: 
                    341: @end
                    342: 
                    343: /*
                    344:  * parse driverList string; get an IOConfigTable for each unit 
                    345:  * of each device in the string; add each IOConfigTable to list.
                    346:  */
                    347: static void
                    348: parseDriverList(const char *driverList,
                    349:                List *list)
                    350: {
                    351:        IOConfigTable   *driverConfig;
                    352:        char            driverName[100];
                    353:        const char      *stringP;               // --> activeDrivers
                    354:        char            *nameP;                 // --> driverName
                    355:        int             unit;
                    356:        BOOL            gotName;
                    357: 
                    358:        if(driverList == NULL) {
                    359:                return;
                    360:        }
                    361:        nameP = driverName;     
                    362:        gotName = NO;
                    363:        stringP = driverList;
                    364:        while(1) {
                    365:            if((*stringP == ' ') || (*stringP == '\0')) {
                    366:                if(!gotName) {
                    367:                    /*
                    368:                     * Skip spaces (we haven't gotten a name yet).
                    369:                     */
                    370:                    if(*stringP == '\0') {
                    371:                        break;                  // trailing spaces
                    372:                    } 
                    373:                    goto nextChar;
                    374:                }
                    375:                *nameP = '\0';                  // null-terminate driverName
                    376:                    
                    377:                /*
                    378:                 * Reset...
                    379:                 */
                    380:                nameP = driverName;
                    381:                gotName = NO;
                    382:                
                    383:                /*
                    384:                 * Get an IOCongTable for each possible
                    385:                 * instance of the driver.
                    386:                 */
                    387:                for(unit=0; ; unit++) {
                    388:                    driverConfig = [IOConfigTable newForDriver:driverName
                    389:                                            unit:unit];
                    390:                    if(driverConfig) {
                    391:                        [list addObject:driverConfig];
                    392:                    }
                    393:                    else {
                    394:                        /*
                    395:                         * No more instances.
                    396:                         */
                    397:                        if(*stringP) {
                    398:                            goto nextChar;
                    399:                        }
                    400:                        else {
                    401:                            goto out;
                    402:                        }
                    403:                    }
                    404:                }   /* for unit */                                                      
                    405:            }       /* space */
                    406:            else {
                    407:                gotName = YES;
                    408:                *nameP++ = *stringP;
                    409:            }
                    410: nextChar:
                    411:            stringP++;
                    412:        }
                    413: out:
                    414:        return;
                    415: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.