Annotation of q_a/samples/ddk/detect/dtexampl.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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