Annotation of q_a/samples/ddk/detect/dtexampl.c, revision 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.