|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.