|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1992 Microsoft Corporation ! 4: ! 5: Module Name: ! 6: ! 7: Detect.c ! 8: ! 9: Abstract: ! 10: ! 11: This is the main file for the autodetection DLL for all the net cards ! 12: which MS is shipping with Windows NT. ! 13: ! 14: --*/ ! 15: ! 16: #include <ntddk.h> ! 17: #include <ntddnetd.h> ! 18: ! 19: #include <windef.h> ! 20: ! 21: // FUDGE the definition of LPSECURITY_ATTRIBUTES ! 22: typedef void * LPSECURITY_ATTRIBUTES ; ! 23: ! 24: // ! 25: // File System time stamps are represented with the following structure: ! 26: // ! 27: ! 28: typedef struct _FILETIME { ! 29: DWORD dwLowDateTime; ! 30: DWORD dwHighDateTime; ! 31: } FILETIME, *PFILETIME, *LPFILETIME; ! 32: ! 33: // Prototype "borrowed" from WINUSER.H ! 34: extern int WINAPIV wsprintfW(LPWSTR, LPCWSTR, ...); ! 35: // Prototype "borrowed" from WINBASE.H ! 36: VOID WINAPI Sleep( DWORD dwMilliseconds ); ! 37: ! 38: #include <winreg.h> ! 39: ! 40: #include <stdio.h> ! 41: #include <stdlib.h> ! 42: #include <string.h> ! 43: #include "detect.h" ! 44: ! 45: ! 46: #if DBG ! 47: #define STATIC ! 48: #else ! 49: #define STATIC static ! 50: #endif ! 51: ! 52: ! 53: #define MAX_BUS_INFO_SIZE 0x4000 // 16kb ! 54: ! 55: STATIC ! 56: BOOLEAN ! 57: GetBusTypeKey( ! 58: IN ULONG BusNumber, ! 59: const CHAR * BusTypeName, ! 60: INT InterfaceType, ! 61: OUT PVOID *InfoHandle ! 62: ) ! 63: ! 64: /*++ ! 65: ! 66: Routine Description: ! 67: ! 68: This routine finds the Microchannel bus with BusNumber in the ! 69: registry and returns a handle for the config information. ! 70: ! 71: Arguments: ! 72: ! 73: BusNumber - The bus number of the bus to search for. ! 74: BusTypeName - String name of bus type to search for ! 75: InterfaceType - Interface type numeric id. ! 76: InfoHandle - The resulting root in the registry. ! 77: ! 78: Return Value: ! 79: ! 80: TRUE if nothing went wrong, else FALSE. ! 81: ! 82: --*/ ! 83: { ! 84: static PSTR BusTypePathBase = "Hardware\\Description\\System\\"; ! 85: static PSTR ConfigData = "Configuration Data"; ! 86: CHAR BusTypePath [MAX_PATH] ; ! 87: PUCHAR BufferPointer = NULL ; ! 88: char SubkeyName [MAX_PATH] ; ! 89: PCM_FULL_RESOURCE_DESCRIPTOR FullResource; ! 90: HKEY BusTypeHandle = NULL, ! 91: BusHandle = NULL ; ! 92: FILETIME LastWrite ; ! 93: ULONG Index; ! 94: DWORD Type, ! 95: BufferSize, ! 96: NameSize ; ! 97: LONG err ; ! 98: BOOL Result = FALSE ; ! 99: ! 100: *InfoHandle = NULL; ! 101: ! 102: if (BusNumber > 98) ! 103: return FALSE; ! 104: ! 105: // ! 106: // Open the root. ! 107: // ! 108: strcpy( BusTypePath, BusTypePathBase ) ; ! 109: strcat( BusTypePath, BusTypeName ); ! 110: ! 111: if ( err = RegOpenKeyExA( HKEY_LOCAL_MACHINE, ! 112: BusTypePath, ! 113: 0, ! 114: KEY_READ, ! 115: & BusTypeHandle ) ) ! 116: { ! 117: return FALSE ; ! 118: } ! 119: ! 120: for ( Index = 0 ; ! Result ; Index++ ) ! 121: { ! 122: if ( BufferPointer ) ! 123: { ! 124: free( BufferPointer ) ; ! 125: BufferPointer = NULL ; ! 126: } ! 127: if ( BusHandle ) ! 128: { ! 129: RegCloseKey( BusHandle ) ; ! 130: BusHandle = NULL ; ! 131: } ! 132: ! 133: // ! 134: // Enumerate through keys, searching for the proper bus number ! 135: // ! 136: NameSize = sizeof SubkeyName ; ! 137: err = RegEnumKeyExA( BusTypeHandle, ! 138: Index, ! 139: SubkeyName, ! 140: & NameSize, ! 141: 0, ! 142: NULL, ! 143: 0, ! 144: & LastWrite ) ; ! 145: if ( err ) ! 146: { ! 147: break ; ! 148: } ! 149: ! 150: // ! 151: // Open the BusType root + Bus Number ! 152: // ! 153: ! 154: err = RegOpenKeyExA( BusTypeHandle, ! 155: SubkeyName, ! 156: 0, ! 157: KEY_READ, ! 158: & BusHandle ) ; ! 159: if ( err ) ! 160: { ! 161: continue ; ! 162: } ! 163: ! 164: BufferPointer = (PUCHAR) malloc( BufferSize = MAX_BUS_INFO_SIZE ) ; ! 165: if ( BufferPointer == NULL ) ! 166: { ! 167: break ; ! 168: } ! 169: ! 170: err = RegQueryValueExA( BusHandle, ! 171: ConfigData, ! 172: NULL, ! 173: & Type, ! 174: BufferPointer, ! 175: & BufferSize ) ; ! 176: if ( err ) ! 177: { ! 178: break ; ! 179: } ! 180: ! 181: // ! 182: // Search for our bus number and type ! 183: // ! 184: FullResource = (PCM_FULL_RESOURCE_DESCRIPTOR) BufferPointer; ! 185: ! 186: Result = FullResource->InterfaceType == InterfaceType ! 187: && FullResource->BusNumber == BusNumber ; ! 188: } ! 189: ! 190: if ( BusTypeHandle ) ! 191: RegCloseKey( BusTypeHandle ) ; ! 192: if ( BusHandle ) ! 193: RegCloseKey( BusHandle ) ; ! 194: ! 195: if ( Result ) ! 196: { ! 197: *InfoHandle = BufferPointer ; ! 198: } ! 199: else ! 200: if ( BufferPointer ) ! 201: { ! 202: free( BufferPointer ) ; ! 203: } ! 204: ! 205: return Result ; ! 206: ! 207: } ! 208: ! 209: ! 210: ! 211: BOOLEAN ! 212: GetMcaKey( ! 213: IN ULONG BusNumber, ! 214: OUT PVOID *InfoHandle ! 215: ) ! 216: ! 217: /*++ ! 218: ! 219: Routine Description: ! 220: ! 221: This routine finds the Microchannel bus with BusNumber in the ! 222: registry and returns a handle for the config information. ! 223: ! 224: Arguments: ! 225: ! 226: BusNumber - The bus number of the bus to search for. ! 227: ! 228: InfoHandle - The resulting root in the registry. ! 229: ! 230: Return Value: ! 231: ! 232: TRUE if nothing went wrong, else FALSE. ! 233: ! 234: --*/ ! 235: { ! 236: return GetBusTypeKey( BusNumber, ! 237: "MultifunctionAdapter", ! 238: MicroChannel, ! 239: InfoHandle ) ; ! 240: } ! 241: ! 242: ! 243: BOOLEAN ! 244: GetMcaPosId( ! 245: IN PVOID BusHandle, ! 246: IN ULONG SlotNumber, ! 247: OUT PULONG PosId ! 248: ) ! 249: ! 250: /*++ ! 251: ! 252: Routine Description: ! 253: ! 254: This routine returns the PosId of an adapter in SlotNumber of an MCA bus. ! 255: ! 256: Arguments: ! 257: ! 258: BusHandle - Handle returned by GetMcaKey(). ! 259: ! 260: SlotNumber - the desired slot number ! 261: ! 262: PosId - the PosId. ! 263: ! 264: Return Value: ! 265: ! 266: TRUE if nothing went wrong, else FALSE. ! 267: ! 268: --*/ ! 269: ! 270: { ! 271: PCM_FULL_RESOURCE_DESCRIPTOR FullResource; ! 272: PCM_PARTIAL_RESOURCE_LIST ResourceList; ! 273: ULONG i; ! 274: ULONG TotalSlots; ! 275: PCM_MCA_POS_DATA PosData; ! 276: ! 277: FullResource = (PCM_FULL_RESOURCE_DESCRIPTOR) BusHandle ; ! 278: ResourceList = &FullResource->PartialResourceList; ! 279: ! 280: // ! 281: // Find the device-specific information, which is where the POS data is. ! 282: // ! 283: for ( i = 0 ; i < ResourceList->Count; i++ ) ! 284: { ! 285: if (ResourceList->PartialDescriptors[i].Type == CmResourceTypeDeviceSpecific) ! 286: break; ! 287: } ! 288: ! 289: if (i == ResourceList->Count) { ! 290: ! 291: // ! 292: // Couldn't find device-specific information. ! 293: // ! 294: ! 295: return FALSE; ! 296: } ! 297: ! 298: TotalSlots = ResourceList->PartialDescriptors[i].u.DeviceSpecificData.DataSize; ! 299: ! 300: TotalSlots = TotalSlots / sizeof(CM_MCA_POS_DATA); ! 301: ! 302: if (SlotNumber <= TotalSlots) { ! 303: ! 304: PosData = (PCM_MCA_POS_DATA)(&ResourceList->PartialDescriptors[i+1]); ! 305: PosData += (SlotNumber - 1); ! 306: ! 307: *PosId = PosData->AdapterId; ! 308: return(TRUE); ! 309: ! 310: } ! 311: ! 312: return(FALSE); ! 313: ! 314: } ! 315: ! 316: ! 317: VOID ! 318: DeleteMcaKey( ! 319: IN PVOID BusHandle ! 320: ) ! 321: ! 322: /*++ ! 323: ! 324: Routine Description: ! 325: ! 326: This routine frees resources associated with an MCA handle. ! 327: ! 328: Arguments: ! 329: ! 330: BusHandle - Handle returned by GetMcaKey(). ! 331: ! 332: Return Value: ! 333: ! 334: None. ! 335: ! 336: --*/ ! 337: { ! 338: free( BusHandle ) ; ! 339: } ! 340: ! 341: ! 342: BOOLEAN ! 343: GetEisaKey( ! 344: IN ULONG BusNumber, ! 345: OUT PVOID *InfoHandle ! 346: ) ! 347: ! 348: /*++ ! 349: ! 350: Routine Description: ! 351: ! 352: This routine finds the Eisa bus with BusNumber in the ! 353: registry and returns a handle for the config information. ! 354: ! 355: Arguments: ! 356: ! 357: BusNumber - The bus number of the bus to search for. ! 358: ! 359: InfoHandle - The resulting root in the registry. ! 360: ! 361: Return Value: ! 362: ! 363: TRUE if nothing went wrong, else FALSE. ! 364: ! 365: --*/ ! 366: { ! 367: return GetBusTypeKey( BusNumber, ! 368: "EisaAdapter", ! 369: Eisa, ! 370: InfoHandle ) ; ! 371: } ! 372: ! 373: ! 374: BOOLEAN ! 375: GetEisaCompressedId( ! 376: IN PVOID BusHandle, ! 377: IN ULONG SlotNumber, ! 378: OUT PULONG CompressedId ! 379: ) ! 380: ! 381: /*++ ! 382: ! 383: Routine Description: ! 384: ! 385: This routine returns the PosId of an adapter in SlotNumber of an MCA bus. ! 386: ! 387: Arguments: ! 388: ! 389: BusHandle - Handle returned by GetEisaKey(). ! 390: ! 391: SlotNumber - the desired slot number ! 392: ! 393: CompressedId - EISA Id in the slot desired. ! 394: ! 395: Return Value: ! 396: ! 397: TRUE if nothing went wrong, else FALSE. ! 398: ! 399: --*/ ! 400: ! 401: { ! 402: PCM_FULL_RESOURCE_DESCRIPTOR FullResource; ! 403: PCM_PARTIAL_RESOURCE_LIST ResourceList; ! 404: PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor; ! 405: ULONG i; ! 406: ULONG TotalDataSize; ! 407: ULONG SlotDataSize; ! 408: PCM_EISA_SLOT_INFORMATION SlotInformation; ! 409: ! 410: FullResource = (PCM_FULL_RESOURCE_DESCRIPTOR) BusHandle; ! 411: ResourceList = &FullResource->PartialResourceList; ! 412: ! 413: // ! 414: // Find the device-specific information, which is where the POS data is. ! 415: // ! 416: for (i=0; i<ResourceList->Count; i++) { ! 417: if (ResourceList->PartialDescriptors[i].Type == CmResourceTypeDeviceSpecific) { ! 418: break; ! 419: } ! 420: } ! 421: ! 422: if (i == ResourceList->Count) { ! 423: ! 424: // ! 425: // Couldn't find device-specific information. ! 426: // ! 427: ! 428: return FALSE; ! 429: } ! 430: ! 431: ! 432: // ! 433: // Bingo! ! 434: // ! 435: ! 436: ResourceDescriptor = &(ResourceList->PartialDescriptors[i]); ! 437: ! 438: TotalDataSize = ResourceDescriptor->u.DeviceSpecificData.DataSize; ! 439: ! 440: SlotInformation = (PCM_EISA_SLOT_INFORMATION) ! 441: ((PUCHAR)ResourceDescriptor + ! 442: sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)); ! 443: ! 444: while (((LONG)TotalDataSize) > 0) { ! 445: ! 446: if (SlotInformation->ReturnCode == EISA_EMPTY_SLOT) { ! 447: ! 448: SlotDataSize = sizeof(CM_EISA_SLOT_INFORMATION); ! 449: ! 450: } else { ! 451: ! 452: SlotDataSize = sizeof(CM_EISA_SLOT_INFORMATION) + ! 453: SlotInformation->NumberFunctions * ! 454: sizeof(CM_EISA_FUNCTION_INFORMATION); ! 455: } ! 456: ! 457: if (SlotDataSize > TotalDataSize) { ! 458: ! 459: // ! 460: // Something is wrong again ! 461: // ! 462: ! 463: return FALSE; ! 464: ! 465: } ! 466: ! 467: if (SlotNumber != 0) { ! 468: ! 469: SlotNumber--; ! 470: ! 471: SlotInformation = (PCM_EISA_SLOT_INFORMATION) ! 472: ((PUCHAR)SlotInformation + SlotDataSize); ! 473: ! 474: TotalDataSize -= SlotDataSize; ! 475: ! 476: continue; ! 477: ! 478: } ! 479: ! 480: // ! 481: // This is our slot ! 482: // ! 483: ! 484: break; ! 485: ! 486: } ! 487: ! 488: if ((SlotNumber != 0) || (TotalDataSize == 0)) { ! 489: ! 490: // ! 491: // No such slot number ! 492: // ! 493: ! 494: return(FALSE); ! 495: ! 496: } ! 497: ! 498: // ! 499: // End loop ! 500: // ! 501: ! 502: *CompressedId = SlotInformation->CompressedId & 0x00FFFFFF; ! 503: ! 504: return(TRUE); ! 505: ! 506: } ! 507: ! 508: VOID ! 509: DeleteEisaKey( ! 510: IN PVOID BusHandle ! 511: ) ! 512: ! 513: /*++ ! 514: ! 515: Routine Description: ! 516: ! 517: This routine frees resources associated with an EISA handle. ! 518: ! 519: Arguments: ! 520: ! 521: BusHandle - Handle returned by GetEisaKey(). ! 522: ! 523: Return Value: ! 524: ! 525: None. ! 526: ! 527: --*/ ! 528: { ! 529: free( BusHandle ) ; ! 530: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.