|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1992 Microsoft Corporation ! 4: ! 5: Module Name: ! 6: ! 7: Detect.c ! 8: ! 9: --*/ ! 10: ! 11: #include <ntddk.h> ! 12: #include <ntddnetd.h> ! 13: ! 14: #include <windef.h> ! 15: #include <winerror.h> ! 16: ! 17: #include <stdio.h> ! 18: #include <stdlib.h> ! 19: #include <string.h> ! 20: #include "detect.h" ! 21: ! 22: #if DBG ! 23: #define STATIC ! 24: #else ! 25: #define STATIC static ! 26: #endif ! 27: ! 28: // Prototype "borrowed" from WINUSER.H ! 29: extern int WINAPIV wsprintfW(LPWSTR, LPCWSTR, ...); ! 30: // Prototype "borrowed" from WINBASE.H ! 31: VOID WINAPI Sleep( DWORD dwMilliseconds ); ! 32: ! 33: ! 34: // ! 35: // This is the structure for all the cards which MS is shipping in this DLL. ! 36: // To add detection for a new adapter(s), simply add the proper routines to ! 37: // this structure. The rest is automatic. ! 38: // ! 39: ! 40: DETECT_ADAPTER DetectAdapters[] = { ! 41: ! 42: { ! 43: LanceIdentifyHandler, ! 44: LanceFirstNextHandler, ! 45: LanceOpenHandleHandler, ! 46: LanceCreateHandleHandler, ! 47: LanceCloseHandleHandler, ! 48: LanceQueryCfgHandler, ! 49: LanceVerifyCfgHandler, ! 50: LanceQueryMaskHandler, ! 51: LanceParamRangeHandler, ! 52: LanceQueryParameterNameHandler, ! 53: 0 ! 54: ! 55: }, ! 56: ! 57: { ! 58: EisaIdentifyHandler, ! 59: EisaFirstNextHandler, ! 60: EisaOpenHandleHandler, ! 61: EisaCreateHandleHandler, ! 62: EisaCloseHandleHandler, ! 63: EisaQueryCfgHandler, ! 64: EisaVerifyCfgHandler, ! 65: EisaQueryMaskHandler, ! 66: EisaParamRangeHandler, ! 67: EisaQueryParameterNameHandler, ! 68: 0 ! 69: ! 70: } ! 71: ! 72: }; ! 73: ! 74: ! 75: // ! 76: // Constant strings for parameters ! 77: // ! 78: ! 79: ! 80: WCHAR IrqString[] = L"IRQ"; ! 81: WCHAR IrqTypeString[] = L"IRQTYPE"; ! 82: WCHAR IoAddrString[] = L"IOADDR"; ! 83: WCHAR IoLengthString[] = L"IOADDRLENGTH"; ! 84: WCHAR MemAddrString[] = L"MEMADDR"; ! 85: WCHAR MemLengthString[] = L"MEMADDRLENGTH"; ! 86: WCHAR TransceiverString[] = L"TRANSCEIVER"; ! 87: WCHAR ZeroWaitStateString[] = L"ZEROWAITSTATE"; ! 88: WCHAR SlotNumberString[] = L"SLOTNUMBER"; ! 89: ! 90: ! 91: // ! 92: // Variables for keeping track of the resources that the DLL currently has ! 93: // claimed. ! 94: // ! 95: ! 96: PNETDTECT_RESOURCE ResourceList; ! 97: ULONG NumberOfResources = 0; ! 98: ULONG NumberOfAllocatedResourceSlots = 0; ! 99: ! 100: ! 101: BOOLEAN ! 102: PASCAL ! 103: NcDetectInitialInit( ! 104: IN PVOID DllHandle, ! 105: IN ULONG Reason, ! 106: IN PCONTEXT Context OPTIONAL ! 107: ) ! 108: ! 109: /*++ ! 110: ! 111: Routine Description: ! 112: ! 113: This routine calls CreateFile to open the device driver. ! 114: ! 115: Arguments: ! 116: ! 117: DllHandle - Not Used ! 118: ! 119: Reason - Attach or Detach ! 120: ! 121: Context - Not Used ! 122: ! 123: Return Value: ! 124: ! 125: STATUS_SUCCESS ! 126: ! 127: --*/ ! 128: ! 129: { ! 130: LONG SupportedDrivers; ! 131: LONG CurrentDriver; ! 132: LONG SupportedAdapters; ! 133: LONG TotalAdapters = 0; ! 134: LONG ReturnValue; ! 135: LONG Length = 0; ! 136: ! 137: if (Reason == 0) { ! 138: ! 139: // ! 140: // This is the close call ! 141: // ! 142: ! 143: // ! 144: // Free ResourceList ! 145: // ! 146: ! 147: if (NumberOfAllocatedResourceSlots > 0) { ! 148: ! 149: DetectFreeHeap(ResourceList); ! 150: ! 151: } ! 152: ! 153: // ! 154: // Free any temporary resources ! 155: // ! 156: ! 157: // BUGBUG: Where is this function? ! 158: // DetectFreeTemporaryResources(); ! 159: ! 160: return(TRUE); ! 161: ! 162: } ! 163: ! 164: SupportedDrivers = sizeof(DetectAdapters) / sizeof(DETECT_ADAPTER); ! 165: ! 166: CurrentDriver = 0; ! 167: ! 168: for (; CurrentDriver < SupportedDrivers ; CurrentDriver++) { ! 169: ! 170: // ! 171: // Count the total number of adapters supported by this DLL by ! 172: // iterating through each module, finding the number of adapters ! 173: // each module supports. ! 174: // ! 175: ! 176: SupportedAdapters = 0; ! 177: ! 178: for ( ; ; SupportedAdapters++) { ! 179: ! 180: ReturnValue = ! 181: (*(DetectAdapters[CurrentDriver].NcDetectIdentifyHandler))( ! 182: ((SupportedAdapters+10) * 100), ! 183: NULL, ! 184: Length ! 185: ); ! 186: ! 187: if (ReturnValue == ERROR_NO_MORE_ITEMS) { ! 188: ! 189: break; ! 190: ! 191: } ! 192: ! 193: } ! 194: ! 195: TotalAdapters += SupportedAdapters; ! 196: ! 197: DetectAdapters[CurrentDriver].SupportedAdapters = SupportedAdapters; ! 198: ! 199: } ! 200: ! 201: if (TotalAdapters > 0xFFFF) { ! 202: ! 203: // ! 204: // We do not support more than this many adapters in this DLL ! 205: // because of the way we build the Tokens and NetcardIds. ! 206: // ! 207: ! 208: return(FALSE); ! 209: ! 210: } ! 211: ! 212: return TRUE; ! 213: } ! 214: ! 215: LONG ! 216: NcDetectIdentify( ! 217: IN LONG Index, ! 218: OUT WCHAR *Buffer, ! 219: IN LONG BuffSize ! 220: ) ! 221: ! 222: /*++ ! 223: ! 224: Routine Description: ! 225: ! 226: This routine returns information about the netcards supported by ! 227: this DLL. ! 228: ! 229: Arguments: ! 230: ! 231: Index - The index of the netcard being address. The first ! 232: cards information is at index 1000, the second at 1100, etc. ! 233: ! 234: Buffer - Buffer to store the result into. ! 235: ! 236: BuffSize - Number of bytes in pwchBuffer ! 237: ! 238: Return Value: ! 239: ! 240: 0 if nothing went wrong, else the appropriate WINERROR.H value. ! 241: ! 242: --*/ ! 243: ! 244: { ! 245: LONG SupportedDrivers; ! 246: LONG CurrentDriver; ! 247: LONG ReturnValue; ! 248: LONG AdapterNumber = (Index / 100) - 10; ! 249: LONG CodeNumber = Index % 100; ! 250: ! 251: ! 252: // ! 253: // First we check the index for any of the 'special' values. ! 254: // ! 255: ! 256: if (Index == 0) { ! 257: ! 258: // ! 259: // Return manufacturers identfication ! 260: // ! 261: ! 262: if (BuffSize < 4) { ! 263: ! 264: return(ERROR_NOT_ENOUGH_MEMORY); ! 265: } ! 266: ! 267: // ! 268: // Copy in the identification number ! 269: // ! 270: ! 271: wsprintfW(Buffer,L"0x0"); ! 272: ! 273: return(0); ! 274: ! 275: } ! 276: ! 277: if (Index == 1) { ! 278: ! 279: // ! 280: // Return the date and version ! 281: // ! 282: ! 283: if (BuffSize < 12) { ! 284: ! 285: return(ERROR_NOT_ENOUGH_MEMORY); ! 286: } ! 287: ! 288: // ! 289: // Copy it in ! 290: // ! 291: ! 292: wsprintfW(Buffer,L"0x10920301"); ! 293: ! 294: return(0); ! 295: ! 296: } ! 297: ! 298: if (AdapterNumber < 0) { ! 299: ! 300: return(ERROR_INVALID_PARAMETER); ! 301: ! 302: } ! 303: ! 304: // ! 305: // Now we find the number of drivers this DLL is supporting. ! 306: // ! 307: SupportedDrivers = sizeof(DetectAdapters) / sizeof(DETECT_ADAPTER); ! 308: ! 309: ! 310: // ! 311: // Iterate through index until we find the the adapter indicated above. ! 312: // ! 313: ! 314: CurrentDriver = 0; ! 315: ! 316: for (; CurrentDriver < SupportedDrivers ; CurrentDriver++) { ! 317: ! 318: // ! 319: // See if the one we want is in here ! 320: // ! 321: ! 322: if (AdapterNumber < DetectAdapters[CurrentDriver].SupportedAdapters) { ! 323: ! 324: ReturnValue = ! 325: (*(DetectAdapters[CurrentDriver].NcDetectIdentifyHandler))( ! 326: ((AdapterNumber + 10) * 100) + CodeNumber, ! 327: Buffer, ! 328: BuffSize ! 329: ); ! 330: ! 331: return(ReturnValue); ! 332: ! 333: } else { ! 334: ! 335: // ! 336: // No, move on to next driver. ! 337: // ! 338: ! 339: AdapterNumber -= DetectAdapters[CurrentDriver].SupportedAdapters; ! 340: ! 341: } ! 342: ! 343: } ! 344: ! 345: return(ERROR_NO_MORE_ITEMS); ! 346: ! 347: } ! 348: ! 349: LONG ! 350: NcDetectFirstNext( ! 351: IN LONG NetcardId, ! 352: IN INTERFACE_TYPE InterfaceType, ! 353: IN ULONG BusNumber, ! 354: IN BOOL First, ! 355: OUT PVOID *Token, ! 356: OUT LONG *Confidence ! 357: ) ! 358: ! 359: /*++ ! 360: ! 361: Routine Description: ! 362: ! 363: This routine finds the instances of a physical adapter identified ! 364: by the NetcardId. ! 365: ! 366: Arguments: ! 367: ! 368: NetcardId - The index of the netcard being address. The first ! 369: cards information is id 1000, the second id 1100, etc. ! 370: ! 371: InterfaceType - Any bus type. ! 372: ! 373: BusNumber - The bus number of the bus to search. ! 374: ! 375: First - TRUE is we are to search for the first instance of an ! 376: adapter, FALSE if we are to continue search from a previous stopping ! 377: point. ! 378: ! 379: Token - A pointer to a handle to return to identify the found ! 380: instance ! 381: ! 382: Confidence - A pointer to a long for storing the confidence factor ! 383: that the card exists. ! 384: ! 385: Return Value: ! 386: ! 387: 0 if nothing went wrong, else the appropriate WINERROR.H value. ! 388: ! 389: --*/ ! 390: ! 391: { ! 392: LONG SupportedDrivers; ! 393: LONG CurrentDriver; ! 394: LONG ReturnValue; ! 395: LONG AdapterNumber = (NetcardId / 100) - 10; ! 396: ! 397: if (AdapterNumber < 0) { ! 398: ! 399: return(ERROR_INVALID_PARAMETER); ! 400: ! 401: } ! 402: ! 403: if ((NetcardId % 100) != 0) { ! 404: ! 405: return(ERROR_INVALID_PARAMETER); ! 406: ! 407: } ! 408: ! 409: // ! 410: // Now we find the number of drivers this DLL is supporting. ! 411: // ! 412: SupportedDrivers = sizeof(DetectAdapters) / sizeof(DETECT_ADAPTER); ! 413: ! 414: // ! 415: // Iterate through index until we find the the adapter indicated above. ! 416: // ! 417: ! 418: CurrentDriver = 0; ! 419: ! 420: for (; CurrentDriver < SupportedDrivers ; CurrentDriver++) { ! 421: ! 422: // ! 423: // See if the one we want is in here ! 424: // ! 425: ! 426: if (AdapterNumber < DetectAdapters[CurrentDriver].SupportedAdapters) { ! 427: ! 428: // ! 429: // Yes, so call to get the right one. ! 430: // ! 431: ! 432: ReturnValue = ! 433: (*(DetectAdapters[CurrentDriver].NcDetectFirstNextHandler))( ! 434: (AdapterNumber + 10) * 100, ! 435: InterfaceType, ! 436: BusNumber, ! 437: First, ! 438: Token, ! 439: Confidence ! 440: ); ! 441: ! 442: if (ReturnValue == 0) { ! 443: ! 444: // ! 445: // Store information ! 446: // ! 447: ! 448: *Token = (PVOID)(((ULONG)(*Token)) | (CurrentDriver << 16)); ! 449: ! 450: } else { ! 451: ! 452: *Token = 0; ! 453: ! 454: } ! 455: ! 456: return(ReturnValue); ! 457: ! 458: } else { ! 459: ! 460: // ! 461: // No, move on to next driver. ! 462: // ! 463: ! 464: AdapterNumber -= DetectAdapters[CurrentDriver].SupportedAdapters; ! 465: ! 466: } ! 467: ! 468: } ! 469: ! 470: return(ERROR_INVALID_PARAMETER); ! 471: } ! 472: ! 473: ! 474: ! 475: ! 476: LONG ! 477: NcDetectOpenHandle( ! 478: IN PVOID Token, ! 479: OUT PVOID *Handle ! 480: ) ! 481: ! 482: /*++ ! 483: ! 484: Routine Description: ! 485: ! 486: This routine takes a token returned by FirstNext and converts it ! 487: into a permanent handle. ! 488: ! 489: Arguments: ! 490: ! 491: Token - The token. ! 492: ! 493: Handle - A pointer to the handle, so we can store the resulting ! 494: handle. ! 495: ! 496: Return Value: ! 497: ! 498: 0 if nothing went wrong, else the appropriate WINERROR.H value. ! 499: ! 500: --*/ ! 501: ! 502: { ! 503: LONG ReturnValue; ! 504: LONG DriverToken = ((ULONG)Token & 0xFFFF); ! 505: LONG DriverNumber = ((ULONG)Token >> 16); ! 506: PADAPTER_HANDLE Adapter; ! 507: ! 508: ReturnValue = ! 509: (*(DetectAdapters[DriverNumber].NcDetectOpenHandleHandler))( ! 510: (PVOID)DriverToken, ! 511: Handle ! 512: ); ! 513: ! 514: if (ReturnValue == 0) { ! 515: ! 516: // ! 517: // Store information ! 518: // ! 519: ! 520: Adapter = DetectAllocateHeap( ! 521: sizeof(ADAPTER_HANDLE) ! 522: ); ! 523: ! 524: if (Adapter == NULL) { ! 525: ! 526: // ! 527: // Error ! 528: // ! 529: ! 530: (*(DetectAdapters[DriverNumber].NcDetectCloseHandleHandler))( ! 531: *Handle ! 532: ); ! 533: ! 534: return(ERROR_NOT_ENOUGH_MEMORY); ! 535: ! 536: } ! 537: ! 538: Adapter->Handle = *Handle; ! 539: Adapter->DriverNumber = DriverNumber; ! 540: ! 541: *Handle = Adapter; ! 542: ! 543: } else { ! 544: ! 545: *Handle = NULL; ! 546: ! 547: } ! 548: ! 549: return(ReturnValue); ! 550: ! 551: } ! 552: ! 553: ! 554: ! 555: ! 556: LONG ! 557: NcDetectCreateHandle( ! 558: IN LONG NetcardId, ! 559: IN INTERFACE_TYPE InterfaceType, ! 560: IN ULONG BusNumber, ! 561: OUT PVOID *Handle ! 562: ) ! 563: ! 564: /*++ ! 565: ! 566: Routine Description: ! 567: ! 568: This routine is used to force the creation of a handle for cases ! 569: where a card is not found via FirstNext, but the user says it does ! 570: exist. ! 571: ! 572: Arguments: ! 573: ! 574: NetcardId - The id of the card to create the handle for. ! 575: ! 576: InterfaceType - Any bus type. ! 577: ! 578: BusNumber - The bus number of the bus in the system. ! 579: ! 580: Handle - A pointer to the handle, for storing the resulting handle. ! 581: ! 582: Return Value: ! 583: ! 584: 0 if nothing went wrong, else the appropriate WINERROR.H value. ! 585: ! 586: --*/ ! 587: ! 588: { ! 589: LONG SupportedDrivers; ! 590: LONG CurrentDriver; ! 591: LONG ReturnValue; ! 592: LONG AdapterNumber = (NetcardId / 100) - 10; ! 593: PADAPTER_HANDLE Adapter; ! 594: ! 595: if (AdapterNumber < 0) { ! 596: ! 597: return(ERROR_INVALID_PARAMETER); ! 598: ! 599: } ! 600: ! 601: if ((NetcardId % 100) != 0) { ! 602: ! 603: return(ERROR_INVALID_PARAMETER); ! 604: ! 605: } ! 606: ! 607: // ! 608: // Now we find the number of drivers this DLL is supporting. ! 609: // ! 610: SupportedDrivers = sizeof(DetectAdapters) / sizeof(DETECT_ADAPTER); ! 611: ! 612: // ! 613: // Iterate through index until we find the the adapter indicated above. ! 614: // ! 615: ! 616: CurrentDriver = 0; ! 617: ! 618: for (; CurrentDriver < SupportedDrivers ; CurrentDriver++) { ! 619: ! 620: // ! 621: // See if the one we want is in here ! 622: // ! 623: ! 624: if (AdapterNumber < DetectAdapters[CurrentDriver].SupportedAdapters) { ! 625: ! 626: // ! 627: // Yes, so call to get the right one. ! 628: // ! 629: ! 630: ReturnValue = ! 631: (*(DetectAdapters[CurrentDriver].NcDetectCreateHandleHandler))( ! 632: (AdapterNumber + 10) * 100, ! 633: InterfaceType, ! 634: BusNumber, ! 635: Handle ! 636: ); ! 637: ! 638: if (ReturnValue == 0) { ! 639: ! 640: // ! 641: // Store information ! 642: // ! 643: ! 644: Adapter = DetectAllocateHeap( ! 645: sizeof(ADAPTER_HANDLE) ! 646: ); ! 647: ! 648: if (Adapter == NULL) { ! 649: ! 650: // ! 651: // Error ! 652: // ! 653: ! 654: (*(DetectAdapters[CurrentDriver].NcDetectCloseHandleHandler))( ! 655: *Handle ! 656: ); ! 657: ! 658: return(ERROR_NOT_ENOUGH_MEMORY); ! 659: ! 660: } ! 661: ! 662: Adapter->Handle = *Handle; ! 663: Adapter->DriverNumber = CurrentDriver; ! 664: ! 665: *Handle = Adapter; ! 666: ! 667: } else { ! 668: ! 669: *Handle = NULL; ! 670: ! 671: } ! 672: ! 673: return(ReturnValue); ! 674: ! 675: } else { ! 676: ! 677: // ! 678: // No, move on to next driver. ! 679: // ! 680: ! 681: AdapterNumber -= DetectAdapters[CurrentDriver].SupportedAdapters; ! 682: ! 683: } ! 684: ! 685: } ! 686: ! 687: return(ERROR_INVALID_PARAMETER); ! 688: } ! 689: ! 690: ! 691: ! 692: LONG ! 693: NcDetectCloseHandle( ! 694: IN PVOID Handle ! 695: ) ! 696: ! 697: /*++ ! 698: ! 699: Routine Description: ! 700: ! 701: This frees any resources associated with a handle. ! 702: ! 703: Arguments: ! 704: ! 705: pvHandle - The handle. ! 706: ! 707: Return Value: ! 708: ! 709: 0 if nothing went wrong, else the appropriate WINERROR.H value. ! 710: ! 711: --*/ ! 712: ! 713: { ! 714: PADAPTER_HANDLE Adapter = (PADAPTER_HANDLE)(Handle); ! 715: ! 716: (*(DetectAdapters[Adapter->DriverNumber].NcDetectCloseHandleHandler))( ! 717: Adapter->Handle ! 718: ); ! 719: ! 720: DetectFreeHeap( Adapter ); ! 721: ! 722: return(0); ! 723: } ! 724: ! 725: ! 726: ! 727: LONG ! 728: NcDetectQueryCfg( ! 729: IN PVOID Handle, ! 730: OUT WCHAR *Buffer, ! 731: IN LONG BuffSize ! 732: ) ! 733: ! 734: /*++ ! 735: ! 736: Routine Description: ! 737: ! 738: This routine calls the appropriate driver's query config handler to ! 739: get the parameters for the adapter associated with the handle. ! 740: ! 741: Arguments: ! 742: ! 743: Handle - The handle. ! 744: ! 745: Buffer - The resulting parameter list. ! 746: ! 747: BuffSize - Length of the given buffer in WCHARs. ! 748: ! 749: Return Value: ! 750: ! 751: 0 if nothing went wrong, else the appropriate WINERROR.H value. ! 752: ! 753: --*/ ! 754: ! 755: { ! 756: PADAPTER_HANDLE Adapter = (PADAPTER_HANDLE)(Handle); ! 757: LONG ReturnValue; ! 758: ! 759: ReturnValue = (*(DetectAdapters[Adapter->DriverNumber].NcDetectQueryCfgHandler))( ! 760: Adapter->Handle, ! 761: Buffer, ! 762: BuffSize ! 763: ); ! 764: ! 765: return(ReturnValue); ! 766: } ! 767: ! 768: ! 769: ! 770: LONG ! 771: NcDetectVerifyCfg( ! 772: IN PVOID Handle, ! 773: IN WCHAR *Buffer ! 774: ) ! 775: ! 776: /*++ ! 777: ! 778: Routine Description: ! 779: ! 780: This routine verifys that a given parameter list is complete and ! 781: correct for the adapter associated with the handle. ! 782: ! 783: Arguments: ! 784: ! 785: Handle - The handle. ! 786: ! 787: Buffer - The parameter list. ! 788: ! 789: Return Value: ! 790: ! 791: 0 if nothing went wrong, else the appropriate WINERROR.H value. ! 792: ! 793: --*/ ! 794: ! 795: { ! 796: PADAPTER_HANDLE Adapter = (PADAPTER_HANDLE)(Handle); ! 797: LONG ReturnValue; ! 798: ! 799: ReturnValue = (*(DetectAdapters[Adapter->DriverNumber].NcDetectVerifyCfgHandler))( ! 800: Adapter->Handle, ! 801: Buffer ! 802: ); ! 803: ! 804: return(ReturnValue); ! 805: } ! 806: ! 807: ! 808: ! 809: LONG ! 810: NcDetectQueryMask( ! 811: IN LONG NetcardId, ! 812: OUT WCHAR *Buffer, ! 813: IN LONG BuffSize ! 814: ) ! 815: ! 816: /*++ ! 817: ! 818: Routine Description: ! 819: ! 820: This routine returns the parameter list information for a specific ! 821: network card. ! 822: ! 823: Arguments: ! 824: ! 825: NetcardId - The id of the desired netcard. ! 826: ! 827: Buffer - The buffer for storing the parameter information. ! 828: ! 829: BuffSize - Length of Buffer in WCHARs. ! 830: ! 831: Return Value: ! 832: ! 833: 0 if nothing went wrong, else the appropriate WINERROR.H value. ! 834: ! 835: --*/ ! 836: ! 837: { ! 838: LONG SupportedDrivers; ! 839: LONG CurrentDriver; ! 840: LONG ReturnValue; ! 841: LONG AdapterNumber = (NetcardId / 100) - 10; ! 842: ! 843: if (AdapterNumber < 0) { ! 844: ! 845: return(ERROR_INVALID_PARAMETER); ! 846: ! 847: } ! 848: ! 849: if ((NetcardId % 100) != 0) { ! 850: ! 851: return(ERROR_INVALID_PARAMETER); ! 852: ! 853: } ! 854: ! 855: // ! 856: // Now we find the number of drivers this DLL is supporting. ! 857: // ! 858: SupportedDrivers = sizeof(DetectAdapters) / sizeof(DETECT_ADAPTER); ! 859: ! 860: // ! 861: // Iterate through index until we find the the adapter indicated above. ! 862: // ! 863: ! 864: CurrentDriver = 0; ! 865: ! 866: for (; CurrentDriver < SupportedDrivers ; CurrentDriver++) { ! 867: ! 868: // ! 869: // See if the one we want is in here ! 870: // ! 871: ! 872: if (AdapterNumber < DetectAdapters[CurrentDriver].SupportedAdapters) { ! 873: ! 874: // ! 875: // Yes, so call to get the right one. ! 876: // ! 877: ! 878: ReturnValue = ! 879: (*(DetectAdapters[CurrentDriver].NcDetectQueryMaskHandler))( ! 880: ((AdapterNumber + 10) * 100), ! 881: Buffer, ! 882: BuffSize ! 883: ); ! 884: ! 885: return(ReturnValue); ! 886: ! 887: } else { ! 888: ! 889: // ! 890: // No, move on to next driver. ! 891: // ! 892: ! 893: AdapterNumber -= DetectAdapters[CurrentDriver].SupportedAdapters; ! 894: ! 895: } ! 896: ! 897: } ! 898: ! 899: return(ERROR_INVALID_PARAMETER); ! 900: } ! 901: ! 902: LONG ! 903: NcDetectParamRange( ! 904: IN LONG NetcardId, ! 905: IN WCHAR *Param, ! 906: OUT LONG *Values, ! 907: OUT LONG *BuffSize ! 908: ) ! 909: ! 910: /*++ ! 911: ! 912: Routine Description: ! 913: ! 914: This routine returns a list of valid values for a given parameter name ! 915: for a given card. ! 916: ! 917: Arguments: ! 918: ! 919: NetcardId - The Id of the card desired. ! 920: ! 921: Param - A WCHAR string of the parameter name to query the values of. ! 922: ! 923: Values - A pointer to a list of LONGs into which we store valid values ! 924: for the parameter. ! 925: ! 926: BuffSize - At entry, the length of plValues in LONGs. At exit, the ! 927: number of LONGs stored in plValues. ! 928: ! 929: Return Value: ! 930: ! 931: 0 if nothing went wrong, else the appropriate WINERROR.H value. ! 932: ! 933: --*/ ! 934: ! 935: { ! 936: LONG SupportedDrivers; ! 937: LONG CurrentDriver; ! 938: LONG ReturnValue; ! 939: LONG AdapterNumber = (NetcardId / 100) - 10; ! 940: ! 941: if (AdapterNumber < 0) { ! 942: ! 943: return(ERROR_INVALID_PARAMETER); ! 944: ! 945: } ! 946: ! 947: if ((NetcardId % 100) != 0) { ! 948: ! 949: return(ERROR_INVALID_PARAMETER); ! 950: ! 951: } ! 952: ! 953: // ! 954: // Now we find the number of drivers this DLL is supporting. ! 955: // ! 956: SupportedDrivers = sizeof(DetectAdapters) / sizeof(DETECT_ADAPTER); ! 957: ! 958: // ! 959: // Iterate through index until we find the the adapter indicated above. ! 960: // ! 961: ! 962: CurrentDriver = 0; ! 963: ! 964: for (; CurrentDriver < SupportedDrivers ; CurrentDriver++) { ! 965: ! 966: // ! 967: // See if the one we want is in here ! 968: // ! 969: ! 970: if (AdapterNumber < DetectAdapters[CurrentDriver].SupportedAdapters) { ! 971: ! 972: // ! 973: // Yes, so call to get the right one. ! 974: // ! 975: ! 976: ReturnValue = ! 977: (*(DetectAdapters[CurrentDriver].NcDetectParamRangeHandler))( ! 978: ((AdapterNumber + 10) * 100), ! 979: Param, ! 980: Values, ! 981: BuffSize ! 982: ); ! 983: ! 984: return(ReturnValue); ! 985: ! 986: } else { ! 987: ! 988: // ! 989: // No, move on to next driver. ! 990: // ! 991: ! 992: AdapterNumber -= DetectAdapters[CurrentDriver].SupportedAdapters; ! 993: ! 994: } ! 995: ! 996: } ! 997: ! 998: return(ERROR_INVALID_PARAMETER); ! 999: } ! 1000: ! 1001: ! 1002: ! 1003: LONG ! 1004: NcDetectQueryParameterName( ! 1005: IN WCHAR *Param, ! 1006: OUT WCHAR *Buffer, ! 1007: IN LONG BufferSize ! 1008: ) ! 1009: ! 1010: /*++ ! 1011: ! 1012: Routine Description: ! 1013: ! 1014: Returns a localized, displayable name for a specific parameter. ! 1015: ! 1016: Arguments: ! 1017: ! 1018: Param - The parameter to be queried. ! 1019: ! 1020: Buffer - The buffer to store the result into. ! 1021: ! 1022: BufferSize - The length of Buffer in WCHARs. ! 1023: ! 1024: Return Value: ! 1025: ! 1026: 0 if nothing went wrong, else the appropriate WINERROR.H value. ! 1027: ! 1028: --*/ ! 1029: ! 1030: { ! 1031: LONG SupportedDrivers; ! 1032: LONG CurrentDriver; ! 1033: LONG ReturnValue; ! 1034: ! 1035: // ! 1036: // Now we find the number of drivers this DLL is supporting. ! 1037: // ! 1038: SupportedDrivers = sizeof(DetectAdapters) / sizeof(DETECT_ADAPTER); ! 1039: ! 1040: // ! 1041: // Iterate through index until we find the the adapter indicated above. ! 1042: // ! 1043: ! 1044: CurrentDriver = 0; ! 1045: ! 1046: for (; CurrentDriver < SupportedDrivers ; CurrentDriver++) { ! 1047: ! 1048: // ! 1049: // No way to tell where this came from -- guess until success. ! 1050: // ! 1051: ! 1052: ReturnValue = ! 1053: (*(DetectAdapters[CurrentDriver].NcDetectQueryParameterNameHandler))( ! 1054: Param, ! 1055: Buffer, ! 1056: BufferSize ! 1057: ); ! 1058: ! 1059: if (ReturnValue == 0) { ! 1060: ! 1061: return(0); ! 1062: ! 1063: } ! 1064: ! 1065: } ! 1066: ! 1067: return(ERROR_INVALID_PARAMETER); ! 1068: } ! 1069: ! 1070: ! 1071: LONG ! 1072: NcDetectResourceClaim( ! 1073: IN INTERFACE_TYPE InterfaceType, ! 1074: IN ULONG BusNumber, ! 1075: IN ULONG Type, ! 1076: IN ULONG Value, ! 1077: IN ULONG Length, ! 1078: IN ULONG Flags, ! 1079: IN BOOL Claim ! 1080: ) ! 1081: ! 1082: /*++ ! 1083: ! 1084: Routine Description: ! 1085: ! 1086: Attempts to claim a resources, failing if there is a conflict. ! 1087: ! 1088: Arguments: ! 1089: ! 1090: InterfaceType - Any type. ! 1091: ! 1092: BusNumber - The bus number of the bus to search. ! 1093: ! 1094: Type - The type of resource, Irq, Memory, Port, Dma ! 1095: ! 1096: Value - The starting value ! 1097: ! 1098: Length - The Length of the resource from starting value to end. ! 1099: ! 1100: Flags - If Type is IRQ, this defines if this is Latched or LevelSensitive. ! 1101: ! 1102: Claim - TRUE if we are to permanently claim the resource, else FALSE. ! 1103: ! 1104: Return Value: ! 1105: ! 1106: 0 if nothing went wrong, else the appropriate WINERROR.H value. ! 1107: ! 1108: --*/ ! 1109: ! 1110: { ! 1111: ULONG i; ! 1112: NTSTATUS NtStatus; ! 1113: ! 1114: // ! 1115: // Check the resources we've claimed for ourselves ! 1116: // ! 1117: ! 1118: for (i = 0; i < NumberOfResources; i++) { ! 1119: ! 1120: if ((ResourceList[i].InterfaceType == InterfaceType) && ! 1121: (ResourceList[i].BusNumber == BusNumber) && ! 1122: (ResourceList[i].Type == Type)) { ! 1123: ! 1124: if (Value < ResourceList[i].Value) { ! 1125: ! 1126: if ((Value + Length) > ResourceList[i].Value) { ! 1127: ! 1128: return(ERROR_SHARING_VIOLATION); ! 1129: ! 1130: } ! 1131: ! 1132: } else if (Value == ResourceList[i].Value) { ! 1133: ! 1134: return(ERROR_SHARING_VIOLATION); ! 1135: ! 1136: } else if (Value < (ResourceList[i].Value + ResourceList[i].Length)) { ! 1137: ! 1138: return(ERROR_SHARING_VIOLATION); ! 1139: ! 1140: } ! 1141: ! 1142: } ! 1143: ! 1144: } ! 1145: ! 1146: // ! 1147: // Make sure resource list has space for this one. ! 1148: // ! 1149: ! 1150: if (NumberOfResources == NumberOfAllocatedResourceSlots) { ! 1151: ! 1152: PVOID TmpList; ! 1153: ! 1154: // ! 1155: // Get more space ! 1156: // ! 1157: ! 1158: TmpList = DetectAllocateHeap((NumberOfAllocatedResourceSlots + 32) * ! 1159: sizeof(NETDTECT_RESOURCE) ! 1160: ); ! 1161: ! 1162: // ! 1163: // Copy data ! 1164: // ! 1165: ! 1166: memcpy(TmpList, ! 1167: ResourceList, ! 1168: (NumberOfAllocatedResourceSlots * sizeof(NETDTECT_RESOURCE)) ! 1169: ); ! 1170: ! 1171: // ! 1172: // Update counter ! 1173: // ! 1174: ! 1175: NumberOfAllocatedResourceSlots += 32; ! 1176: ! 1177: // ! 1178: // Free old space ! 1179: // ! 1180: ! 1181: DetectFreeHeap(ResourceList); ! 1182: ! 1183: ResourceList = (PNETDTECT_RESOURCE)TmpList; ! 1184: ! 1185: } ! 1186: ! 1187: // ! 1188: // Add it to the list ! 1189: // ! 1190: ! 1191: ResourceList[NumberOfResources].InterfaceType = InterfaceType; ! 1192: ResourceList[NumberOfResources].BusNumber = BusNumber; ! 1193: ResourceList[NumberOfResources].Type = Type; ! 1194: ResourceList[NumberOfResources].Value = Value; ! 1195: ResourceList[NumberOfResources].Length = Length; ! 1196: ResourceList[NumberOfResources].Flags = Flags; ! 1197: ! 1198: // ! 1199: // Try to claim the resource ! 1200: // ! 1201: ! 1202: NtStatus = DetectClaimResource( ! 1203: NumberOfResources + 1, ! 1204: (PVOID)ResourceList ! 1205: ); ! 1206: ! 1207: ! 1208: // ! 1209: // If failed, exit ! 1210: // ! 1211: ! 1212: if (NtStatus == STATUS_CONFLICTING_ADDRESSES) { ! 1213: ! 1214: // ! 1215: // Undo the claim ! 1216: // ! 1217: ! 1218: DetectClaimResource( ! 1219: NumberOfResources, ! 1220: (PVOID)ResourceList ! 1221: ); ! 1222: ! 1223: return(ERROR_SHARING_VIOLATION); ! 1224: ! 1225: } ! 1226: ! 1227: if (NtStatus) { ! 1228: ! 1229: return(ERROR_NOT_ENOUGH_MEMORY); ! 1230: ! 1231: } ! 1232: ! 1233: if (!Claim) { ! 1234: ! 1235: // ! 1236: // Undo the claim ! 1237: // ! 1238: ! 1239: DetectClaimResource( ! 1240: NumberOfResources, ! 1241: (PVOID)ResourceList ! 1242: ); ! 1243: ! 1244: } else { ! 1245: ! 1246: // ! 1247: // Adjust total count only if this is permanent ! 1248: // ! 1249: ! 1250: NumberOfResources++; ! 1251: ! 1252: } ! 1253: ! 1254: // ! 1255: // no error ! 1256: // ! 1257: ! 1258: return(0); ! 1259: } ! 1260: ! 1261: ! 1262: ! 1263: ! 1264: ! 1265: // ! 1266: // Support routines. ! 1267: // ! 1268: // These routines are common routines used within each detection module. ! 1269: // ! 1270: ! 1271: ! 1272: ! 1273: ! 1274: ! 1275: ! 1276: ULONG ! 1277: UnicodeStrLen( ! 1278: IN WCHAR *String ! 1279: ) ! 1280: ! 1281: /*++ ! 1282: ! 1283: Routine Description: ! 1284: ! 1285: This routine returns the number of Unicode characters in a NULL ! 1286: terminated Unicode string. ! 1287: ! 1288: Arguments: ! 1289: ! 1290: String - The string. ! 1291: ! 1292: Return Value: ! 1293: ! 1294: The length in number of unicode characters ! 1295: ! 1296: --*/ ! 1297: ! 1298: ! 1299: { ! 1300: ULONG Length; ! 1301: ! 1302: for (Length=0; ; Length++) { ! 1303: ! 1304: if (String[Length] == L'\0') { ! 1305: ! 1306: return Length; ! 1307: ! 1308: } ! 1309: ! 1310: } ! 1311: ! 1312: } ! 1313: ! 1314: WCHAR * ! 1315: FindParameterString( ! 1316: IN WCHAR *String1, ! 1317: IN WCHAR *String2 ! 1318: ) ! 1319: ! 1320: /*++ ! 1321: ! 1322: Routine Description: ! 1323: ! 1324: This routine returns a pointer to the first instance of String2 ! 1325: in String1. It assumes that String1 is a parameter list where ! 1326: each parameter name is terminated with a NULL and the entire ! 1327: string terminated by two consecutive NULLs. ! 1328: ! 1329: Arguments: ! 1330: ! 1331: String1 -- String to search. ! 1332: ! 1333: String2 -- Substring to search for. ! 1334: ! 1335: Return Value: ! 1336: ! 1337: Pointer to place in String1 of first character of String2 if it ! 1338: exists, else NULL. ! 1339: ! 1340: --*/ ! 1341: ! 1342: ! 1343: { ! 1344: ULONG Length1; ! 1345: ULONG Length2; ! 1346: WCHAR *Place = String1; ! 1347: ! 1348: Length2 = UnicodeStrLen(String2) + 1; ! 1349: ! 1350: Length1 = UnicodeStrLen(String1) + 1; ! 1351: ! 1352: // ! 1353: // While not the NULL only ! 1354: // ! 1355: ! 1356: while (Length1 != 1) { ! 1357: ! 1358: // ! 1359: // Are these the same? ! 1360: // ! 1361: ! 1362: if (memcmp(Place, String2, Length2 * sizeof(WCHAR)) == 0) { ! 1363: ! 1364: // ! 1365: // Yes. ! 1366: // ! 1367: ! 1368: return(Place); ! 1369: ! 1370: } ! 1371: ! 1372: Place = (WCHAR *)(Place + Length1); ! 1373: ! 1374: Length1 = UnicodeStrLen(Place) + 1; ! 1375: ! 1376: } ! 1377: ! 1378: return(NULL); ! 1379: ! 1380: } ! 1381: ! 1382: ! 1383: VOID ! 1384: ScanForNumber( ! 1385: IN WCHAR *Place, ! 1386: OUT ULONG *Value, ! 1387: OUT BOOLEAN *Found ! 1388: ) ! 1389: ! 1390: /*++ ! 1391: ! 1392: Routine Description: ! 1393: ! 1394: This routine does a sscanf(Place, "%d", Value) on a unicode string. ! 1395: ! 1396: Arguments: ! 1397: ! 1398: Place - String to read from ! 1399: ! 1400: Value - Pointer to place to store the result. ! 1401: ! 1402: Found - Pointer to tell if the routine failed to find an integer. ! 1403: ! 1404: Return Value: ! 1405: ! 1406: None. ! 1407: ! 1408: --*/ ! 1409: ! 1410: ! 1411: { ! 1412: ULONG Tmp; ! 1413: ! 1414: *Value = 0; ! 1415: *Found = FALSE; ! 1416: ! 1417: // ! 1418: // Skip leading blanks ! 1419: // ! 1420: ! 1421: while (*Place == L' ') { ! 1422: ! 1423: Place++; ! 1424: ! 1425: } ! 1426: ! 1427: ! 1428: // ! 1429: // Is this a hex number? ! 1430: // ! 1431: ! 1432: if ((Place[0] == L'0') && ! 1433: (Place[1] == L'x')) { ! 1434: ! 1435: // ! 1436: // Yes, parse it as a hex number ! 1437: // ! 1438: ! 1439: *Found = TRUE; ! 1440: ! 1441: // ! 1442: // Skip leading '0x' ! 1443: // ! 1444: ! 1445: Place += 2; ! 1446: ! 1447: // ! 1448: // Convert a hex number ! 1449: // ! 1450: ! 1451: while (TRUE) { ! 1452: ! 1453: if ((*Place >= L'0') && (*Place <= L'9')) { ! 1454: ! 1455: Tmp = ((ULONG)*Place) - ((ULONG)L'0'); ! 1456: ! 1457: } else { ! 1458: ! 1459: switch (*Place) { ! 1460: ! 1461: case L'a': ! 1462: case L'A': ! 1463: ! 1464: Tmp = 10; ! 1465: break; ! 1466: ! 1467: case L'b': ! 1468: case L'B': ! 1469: ! 1470: Tmp = 11; ! 1471: break; ! 1472: ! 1473: case L'c': ! 1474: case L'C': ! 1475: ! 1476: Tmp = 12; ! 1477: break; ! 1478: ! 1479: case L'd': ! 1480: case L'D': ! 1481: ! 1482: Tmp = 13; ! 1483: break; ! 1484: ! 1485: case L'e': ! 1486: case L'E': ! 1487: ! 1488: Tmp = 14; ! 1489: break; ! 1490: ! 1491: case L'f': ! 1492: case L'F': ! 1493: ! 1494: Tmp = 15; ! 1495: break; ! 1496: ! 1497: default: ! 1498: ! 1499: return; ! 1500: ! 1501: } ! 1502: ! 1503: } ! 1504: ! 1505: (*Value) *= 16; ! 1506: (*Value) += Tmp; ! 1507: ! 1508: Place++; ! 1509: ! 1510: } ! 1511: ! 1512: } else if ((*Place >= L'0') && (*Place <= L'9')) { ! 1513: ! 1514: // ! 1515: // Parse it as an int ! 1516: // ! 1517: ! 1518: *Found = TRUE; ! 1519: ! 1520: // ! 1521: // Convert a base 10 number ! 1522: // ! 1523: ! 1524: while (TRUE) { ! 1525: ! 1526: if ((*Place >= L'0') && (*Place <= L'9')) { ! 1527: ! 1528: Tmp = ((ULONG)*Place) - ((ULONG)L'0'); ! 1529: ! 1530: } else { ! 1531: ! 1532: return; ! 1533: ! 1534: } ! 1535: ! 1536: (*Value) *= 10; ! 1537: (*Value) += Tmp; ! 1538: ! 1539: Place++; ! 1540: ! 1541: } ! 1542: ! 1543: } ! 1544: ! 1545: } ! 1546: ! 1547: BOOLEAN ! 1548: CheckFor8390( ! 1549: IN INTERFACE_TYPE InterfaceType, ! 1550: IN ULONG BusNumber, ! 1551: IN ULONG IoBaseAddress ! 1552: ) ! 1553: ! 1554: /*++ ! 1555: ! 1556: Routine Description: ! 1557: ! 1558: This routine checks for the existence of an 8390 NIC. ! 1559: ! 1560: Arguments: ! 1561: ! 1562: InterfaceType - Any bus type. ! 1563: ! 1564: BusNumber - The bus number of the bus in the system. ! 1565: ! 1566: IoBaseAddress - The IoBaseAddress to check. ! 1567: ! 1568: Return Value: ! 1569: ! 1570: None. ! 1571: ! 1572: --*/ ! 1573: ! 1574: { ! 1575: UCHAR Value; ! 1576: UCHAR IMRValue; ! 1577: NTSTATUS NtStatus; ! 1578: UCHAR SavedOffset0; ! 1579: UCHAR SavedOffset3; ! 1580: UCHAR SavedOffsetF; ! 1581: BOOLEAN Status = TRUE; ! 1582: ! 1583: // ! 1584: // If the IoBaseAddress is the address of the DMA register on the NE2000 ! 1585: // adapter, then this routine will hang the card and the machine. To avoid ! 1586: // this, we first write to the Ne2000's reset port. ! 1587: // ! 1588: ! 1589: NtStatus = DetectReadPortUchar(InterfaceType, ! 1590: BusNumber, ! 1591: IoBaseAddress + 0xF, ! 1592: &SavedOffsetF ! 1593: ); ! 1594: ! 1595: if (NtStatus != STATUS_SUCCESS) { ! 1596: ! 1597: Status = FALSE; ! 1598: goto Fail; ! 1599: ! 1600: } ! 1601: ! 1602: NtStatus = DetectWritePortUchar(InterfaceType, ! 1603: BusNumber, ! 1604: IoBaseAddress + 0xF, ! 1605: 0xFF ! 1606: ); ! 1607: ! 1608: if (NtStatus != STATUS_SUCCESS) { ! 1609: ! 1610: Status = FALSE; ! 1611: goto Fail; ! 1612: ! 1613: } ! 1614: ! 1615: // ! 1616: // Write STOP bit ! 1617: // ! 1618: ! 1619: NtStatus = DetectReadPortUchar(InterfaceType, ! 1620: BusNumber, ! 1621: IoBaseAddress, ! 1622: &SavedOffset0 ! 1623: ); ! 1624: ! 1625: if (NtStatus != STATUS_SUCCESS) { ! 1626: ! 1627: Status = FALSE; ! 1628: goto Restore1; ! 1629: ! 1630: } ! 1631: ! 1632: NtStatus = DetectWritePortUchar(InterfaceType, ! 1633: BusNumber, ! 1634: IoBaseAddress, ! 1635: 0x21 ! 1636: ); ! 1637: ! 1638: if (NtStatus != STATUS_SUCCESS) { ! 1639: ! 1640: Status = FALSE; ! 1641: goto Restore1; ! 1642: ! 1643: } ! 1644: ! 1645: // ! 1646: // Read boundary ! 1647: // ! 1648: ! 1649: NtStatus = DetectReadPortUchar(InterfaceType, ! 1650: BusNumber, ! 1651: IoBaseAddress + 0x3, ! 1652: &Value ! 1653: ); ! 1654: ! 1655: if (NtStatus != STATUS_SUCCESS) { ! 1656: ! 1657: Status = FALSE; ! 1658: goto Restore2; ! 1659: ! 1660: } ! 1661: ! 1662: SavedOffset3 = Value; ! 1663: ! 1664: // ! 1665: // Write a different boundary ! 1666: // ! 1667: ! 1668: NtStatus = DetectWritePortUchar(InterfaceType, ! 1669: BusNumber, ! 1670: IoBaseAddress + 0x3, ! 1671: (UCHAR)(Value + 1) ! 1672: ); ! 1673: ! 1674: if (NtStatus != STATUS_SUCCESS) { ! 1675: ! 1676: Status = FALSE; ! 1677: goto Restore2; ! 1678: ! 1679: } ! 1680: ! 1681: // ! 1682: // Did it stick? ! 1683: // ! 1684: ! 1685: NtStatus = DetectReadPortUchar(InterfaceType, ! 1686: BusNumber, ! 1687: IoBaseAddress + 0x3, ! 1688: &IMRValue ! 1689: ); ! 1690: ! 1691: if (NtStatus != STATUS_SUCCESS) { ! 1692: ! 1693: Status = FALSE; ! 1694: goto Restore3; ! 1695: ! 1696: } ! 1697: ! 1698: if (IMRValue != (UCHAR)(Value + 1)) { ! 1699: ! 1700: Status = FALSE; ! 1701: goto Restore3; ! 1702: ! 1703: } ! 1704: ! 1705: // ! 1706: // Write IMR ! 1707: // ! 1708: ! 1709: NtStatus = DetectWritePortUchar(InterfaceType, ! 1710: BusNumber, ! 1711: IoBaseAddress + 0xF, ! 1712: 0x3F ! 1713: ); ! 1714: ! 1715: if (NtStatus != STATUS_SUCCESS) { ! 1716: ! 1717: Status = FALSE; ! 1718: goto Restore3; ! 1719: ! 1720: } ! 1721: ! 1722: ! 1723: // ! 1724: // switch to page 2 ! 1725: // ! 1726: ! 1727: NtStatus = DetectWritePortUchar(InterfaceType, ! 1728: BusNumber, ! 1729: IoBaseAddress, ! 1730: 0xA1 ! 1731: ); ! 1732: ! 1733: if (NtStatus != STATUS_SUCCESS) { ! 1734: ! 1735: // ! 1736: // Change to page 0 ! 1737: // ! 1738: ! 1739: DetectWritePortUchar(InterfaceType, ! 1740: BusNumber, ! 1741: IoBaseAddress, ! 1742: 0x21 ! 1743: ); ! 1744: ! 1745: Status = FALSE; ! 1746: goto Restore3; ! 1747: ! 1748: } ! 1749: ! 1750: // ! 1751: // Read the IMR ! 1752: // ! 1753: ! 1754: NtStatus = DetectReadPortUchar(InterfaceType, ! 1755: BusNumber, ! 1756: IoBaseAddress + 0xF, ! 1757: &IMRValue ! 1758: ); ! 1759: ! 1760: if (NtStatus != STATUS_SUCCESS) { ! 1761: ! 1762: // ! 1763: // Change to page 0 ! 1764: // ! 1765: ! 1766: DetectWritePortUchar(InterfaceType, ! 1767: BusNumber, ! 1768: IoBaseAddress, ! 1769: 0x21 ! 1770: ); ! 1771: ! 1772: Status = FALSE; ! 1773: goto Restore3; ! 1774: ! 1775: } ! 1776: ! 1777: // ! 1778: // Remove bits added by NIC ! 1779: // ! 1780: ! 1781: IMRValue &= 0x3F; ! 1782: ! 1783: // ! 1784: // switch to page 0 ! 1785: // ! 1786: ! 1787: NtStatus = DetectWritePortUchar(InterfaceType, ! 1788: BusNumber, ! 1789: IoBaseAddress, ! 1790: 0x21 ! 1791: ); ! 1792: ! 1793: if (NtStatus != STATUS_SUCCESS) { ! 1794: ! 1795: Status = FALSE; ! 1796: goto Restore3; ! 1797: ! 1798: } ! 1799: ! 1800: // ! 1801: // Write IMR ! 1802: // ! 1803: ! 1804: NtStatus = DetectWritePortUchar(InterfaceType, ! 1805: BusNumber, ! 1806: IoBaseAddress + 0xF, ! 1807: (UCHAR)(IMRValue) ! 1808: ); ! 1809: ! 1810: if (NtStatus != STATUS_SUCCESS) { ! 1811: ! 1812: Status = FALSE; ! 1813: goto Restore3; ! 1814: ! 1815: } ! 1816: ! 1817: // ! 1818: // switch to page 1 ! 1819: // ! 1820: ! 1821: NtStatus = DetectWritePortUchar(InterfaceType, ! 1822: BusNumber, ! 1823: IoBaseAddress, ! 1824: 0x61 ! 1825: ); ! 1826: ! 1827: if (NtStatus != STATUS_SUCCESS) { ! 1828: ! 1829: // ! 1830: // Change to page 0 ! 1831: // ! 1832: ! 1833: DetectWritePortUchar(InterfaceType, ! 1834: BusNumber, ! 1835: IoBaseAddress, ! 1836: 0x21 ! 1837: ); ! 1838: ! 1839: Status = FALSE; ! 1840: goto Restore3; ! 1841: ! 1842: } ! 1843: ! 1844: // ! 1845: // Write ~IMR ! 1846: // ! 1847: ! 1848: NtStatus = DetectWritePortUchar(InterfaceType, ! 1849: BusNumber, ! 1850: IoBaseAddress + 0xF, ! 1851: (UCHAR)(~IMRValue) ! 1852: ); ! 1853: ! 1854: if (NtStatus != STATUS_SUCCESS) { ! 1855: ! 1856: // ! 1857: // Change to page 0 ! 1858: // ! 1859: ! 1860: DetectWritePortUchar(InterfaceType, ! 1861: BusNumber, ! 1862: IoBaseAddress, ! 1863: 0x21 ! 1864: ); ! 1865: ! 1866: Status = FALSE; ! 1867: goto Restore3; ! 1868: ! 1869: } ! 1870: ! 1871: // ! 1872: // switch to page 2 ! 1873: // ! 1874: ! 1875: NtStatus = DetectWritePortUchar(InterfaceType, ! 1876: BusNumber, ! 1877: IoBaseAddress, ! 1878: 0xA1 ! 1879: ); ! 1880: ! 1881: if (NtStatus != STATUS_SUCCESS) { ! 1882: ! 1883: // ! 1884: // Change to page 0 ! 1885: // ! 1886: ! 1887: DetectWritePortUchar(InterfaceType, ! 1888: BusNumber, ! 1889: IoBaseAddress, ! 1890: 0x21 ! 1891: ); ! 1892: ! 1893: Status = FALSE; ! 1894: goto Restore3; ! 1895: ! 1896: } ! 1897: ! 1898: // ! 1899: // Read IMR ! 1900: // ! 1901: ! 1902: NtStatus = DetectReadPortUchar(InterfaceType, ! 1903: BusNumber, ! 1904: IoBaseAddress + 0xF, ! 1905: &Value ! 1906: ); ! 1907: ! 1908: if (NtStatus != STATUS_SUCCESS) { ! 1909: ! 1910: // ! 1911: // Change to page 0 ! 1912: // ! 1913: ! 1914: DetectWritePortUchar(InterfaceType, ! 1915: BusNumber, ! 1916: IoBaseAddress, ! 1917: 0x21 ! 1918: ); ! 1919: ! 1920: Status = FALSE; ! 1921: goto Restore3; ! 1922: ! 1923: } ! 1924: ! 1925: // ! 1926: // Are they the same? ! 1927: // ! 1928: ! 1929: if ((UCHAR)(Value & 0x3F) == (UCHAR)(IMRValue)) { ! 1930: ! 1931: Status = FALSE; ! 1932: ! 1933: } ! 1934: ! 1935: // ! 1936: // Change to page 0 ! 1937: // ! 1938: ! 1939: DetectWritePortUchar(InterfaceType, ! 1940: BusNumber, ! 1941: IoBaseAddress, ! 1942: 0x21 ! 1943: ); ! 1944: ! 1945: Restore3: ! 1946: ! 1947: DetectWritePortUchar(InterfaceType, ! 1948: BusNumber, ! 1949: IoBaseAddress + 0x3, ! 1950: SavedOffset3 ! 1951: ); ! 1952: ! 1953: Restore2: ! 1954: ! 1955: DetectWritePortUchar(InterfaceType, ! 1956: BusNumber, ! 1957: IoBaseAddress, ! 1958: SavedOffset0 ! 1959: ); ! 1960: ! 1961: Restore1: ! 1962: ! 1963: DetectWritePortUchar(InterfaceType, ! 1964: BusNumber, ! 1965: IoBaseAddress + 0xF, ! 1966: SavedOffsetF ! 1967: ); ! 1968: ! 1969: Fail: ! 1970: ! 1971: return(Status); ! 1972: ! 1973: } ! 1974: ! 1975: VOID ! 1976: Send8390Packet( ! 1977: IN INTERFACE_TYPE InterfaceType, ! 1978: IN ULONG BusNumber, ! 1979: IN ULONG IoBaseAddress, ! 1980: IN ULONG MemoryBaseAddress, ! 1981: IN COPY_ROUTINE CardCopyDownBuffer, ! 1982: IN UCHAR *NetworkAddress ! 1983: ) ! 1984: ! 1985: /*++ ! 1986: ! 1987: Routine Description: ! 1988: ! 1989: This routine creates an interrupt on an 8390 chip. The only way to ! 1990: do this is to actually transmit a packet. So, we put the card in ! 1991: loopback mode and let 'er rip. ! 1992: ! 1993: Arguments: ! 1994: ! 1995: InterfaceType - Any bus type. ! 1996: ! 1997: BusNumber - The bus number of the bus in the system. ! 1998: ! 1999: IoBaseAddress - The IoBaseAddress to check. ! 2000: ! 2001: MemoryBaseAddress - The MemoryBaseAddress (if applicable) to copy a p ! 2002: packet to for transmission. ! 2003: ! 2004: CardCopyDownBuffer - A routine for copying a packet onto a card. ! 2005: ! 2006: NetworkAddress - The network address of the machine. ! 2007: ! 2008: Return Value: ! 2009: ! 2010: None. ! 2011: ! 2012: --*/ ! 2013: ! 2014: { ! 2015: ! 2016: #define TEST_LEN 60 ! 2017: #define MAGIC_NUM 0x92 ! 2018: ! 2019: NTSTATUS NtStatus; ! 2020: ! 2021: UCHAR TestPacket[TEST_LEN] = {0}; // a dummy packet. ! 2022: ! 2023: memcpy(TestPacket, NetworkAddress, 6); ! 2024: memcpy(TestPacket+6, NetworkAddress, 6); ! 2025: TestPacket[12] = 0x00; ! 2026: TestPacket[13] = 0x00; ! 2027: TestPacket[TEST_LEN-1] = MAGIC_NUM; ! 2028: ! 2029: // ! 2030: // First construct TestPacket. ! 2031: // ! 2032: ! 2033: TestPacket[TEST_LEN-1] = MAGIC_NUM; ! 2034: ! 2035: // ! 2036: // Now copy down TestPacket and start the transmission. ! 2037: // ! 2038: ! 2039: (*CardCopyDownBuffer)(InterfaceType, ! 2040: BusNumber, ! 2041: IoBaseAddress, ! 2042: MemoryBaseAddress, ! 2043: TestPacket, ! 2044: TEST_LEN ! 2045: ); ! 2046: ! 2047: NtStatus = DetectWritePortUchar(InterfaceType, ! 2048: BusNumber, ! 2049: IoBaseAddress + 0x4, ! 2050: (UCHAR)(MemoryBaseAddress >> 8) ! 2051: ); ! 2052: ! 2053: ! 2054: if (NtStatus != STATUS_SUCCESS) { ! 2055: return; ! 2056: } ! 2057: ! 2058: ! 2059: NtStatus = DetectWritePortUchar(InterfaceType, ! 2060: BusNumber, ! 2061: IoBaseAddress + 0x6, ! 2062: 0x0 ! 2063: ); ! 2064: ! 2065: ! 2066: if (NtStatus != STATUS_SUCCESS) { ! 2067: return; ! 2068: } ! 2069: ! 2070: ! 2071: NtStatus = DetectWritePortUchar(InterfaceType, ! 2072: BusNumber, ! 2073: IoBaseAddress + 0x5, ! 2074: (UCHAR)(TEST_LEN) ! 2075: ); ! 2076: ! 2077: ! 2078: if (NtStatus != STATUS_SUCCESS) { ! 2079: return; ! 2080: } ! 2081: ! 2082: NtStatus = DetectWritePortUchar(InterfaceType, ! 2083: BusNumber, ! 2084: IoBaseAddress, ! 2085: 0x26 ! 2086: ); ! 2087: ! 2088: ! 2089: if (NtStatus != STATUS_SUCCESS) { ! 2090: return; ! 2091: } ! 2092: ! 2093: // ! 2094: // We pause here to allow the xmit to complete so that we can ACK ! 2095: // it below - leaving the card in a valid state. ! 2096: // ! 2097: ! 2098: { ! 2099: UCHAR i; ! 2100: UCHAR RegValue; ! 2101: ! 2102: for (i=0;i != 0xFF;i++) { ! 2103: ! 2104: // ! 2105: // check for send completion ! 2106: // ! 2107: ! 2108: NtStatus = DetectReadPortUchar(InterfaceType, ! 2109: BusNumber, ! 2110: IoBaseAddress + 0x7, ! 2111: &RegValue ! 2112: ); ! 2113: ! 2114: ! 2115: if (NtStatus != STATUS_SUCCESS) { ! 2116: return; ! 2117: } ! 2118: ! 2119: if (RegValue & 0xA) { ! 2120: break; ! 2121: } ! 2122: ! 2123: } ! 2124: ! 2125: } ! 2126: ! 2127: // ! 2128: // Turn off any interrupts ! 2129: // ! 2130: ! 2131: NtStatus = DetectWritePortUchar(InterfaceType, ! 2132: BusNumber, ! 2133: IoBaseAddress + 0xF, ! 2134: 0x00 ! 2135: ); ! 2136: ! 2137: ! 2138: if (NtStatus != STATUS_SUCCESS) { ! 2139: return; ! 2140: } ! 2141: ! 2142: // ! 2143: // Acknowledge any interrupts that are floating around. ! 2144: // ! 2145: ! 2146: NtStatus = DetectWritePortUchar(InterfaceType, ! 2147: BusNumber, ! 2148: IoBaseAddress + 0xE, ! 2149: 0xFF ! 2150: ); ! 2151: ! 2152: ! 2153: if (NtStatus != STATUS_SUCCESS) { ! 2154: return; ! 2155: } ! 2156: ! 2157: return; ! 2158: ! 2159: } ! 2160: ! 2161: PVOID ! 2162: DetectAllocateHeap( ! 2163: IN ULONG Size ! 2164: ) ! 2165: { ! 2166: PVOID pv = malloc( Size ) ; ! 2167: if ( Size ) ! 2168: memset( pv, 0, Size ) ; ! 2169: return pv ; ! 2170: } ! 2171: ! 2172: VOID ! 2173: DetectFreeHeap( ! 2174: IN PVOID BaseAddress ! 2175: ) ! 2176: { ! 2177: free( BaseAddress ) ; ! 2178: } ! 2179: ! 2180: ! 2181: ! 2182: // End of MSNCDET.C
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.