⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ndisdriver.c

📁 MICREL 网卡驱动 FOR CE 5.0
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// DWORD cRegPathSize - Number of bytes in lpRegPath.
//
// Returns lpRegPath if successful, NULL for failure.
//
#ifdef __cplusplus
extern "C"
#endif
LPWSTR Install_Driver (
    LPWSTR lpPnpId,
    LPWSTR lpRegPath,
    DWORD  cRegPathSize )
{
    DWORD  i;

#ifdef AUTO_DETECT
    LPWSTR lpDetectKeyName;
#endif

    DEBUGMSG( ZONE_INIT, ( TEXT( "KS884X: Install_Driver(%s, %s, %d)\r\n" ),
        lpPnpId, lpRegPath, cRegPathSize ));

#ifdef AUTO_DETECT
    if ( IsInstalled() ) {
        return NULL;
    }

    if ( ( lpDetectKeyName = FindDetectKey()) == NULL ) {
        return NULL;
    }

    if ( !AddKeyValues( lpDetectKeyName, DetectKeyValues ) ) {
        goto wid_fail_detect;
    }
#endif

    for ( i = 0; i < ( sizeof( KeyNames ) / sizeof( LPWSTR )); i++ ) {
        if ( !AddKeyValues( KeyNames[ i ], Values[ i ]) ) {
            goto wid_fail;
        }
    }

#ifdef AUTO_DETECT
    LocalFree( lpDetectKeyName );
#endif

    //
    // Return "Drivers\\PCMCIA\\NdisDriver"
    //
    wcscpy( lpRegPath, KeyNames[ 0 ]);
    return lpRegPath;

wid_fail:
    //
    // Clean up after ourself on failure.
    //
    for ( i = 0; i < ( sizeof( KeyNames ) / sizeof( LPWSTR )); i++ ) {
        RegDeleteKey( HKEY_LOCAL_MACHINE, KeyNames[ i ]);
    }

#ifdef AUTO_DETECT

wid_fail_detect:
    RegDeleteKey( HKEY_LOCAL_MACHINE, lpDetectKeyName );
    LocalFree( lpDetectKeyName );
#endif
    return NULL;
}  // Install_Driver


#ifdef AUTO_DETECT
//
// Windows CE Plug and play detection function for the
// NDIS network adapter
//
#ifdef __cplusplus
extern "C"
#endif
LPWSTR DetectNdisDevice (
    CARD_SOCKET_HANDLE hSock,
    UCHAR              DevType,
    LPWSTR             DevKey,
    DWORD              DevKeyLen )
{
    HANDLE hPcmciaDll;
    DWORD cerr;
    GETFIRSTTUPLE pfnGetFirstTuple;
    GETTUPLEDATA pfnGetTupleData;
    UCHAR buf[sizeof(CARD_DATA_PARMS) + 256];
    PCARD_DATA_PARMS pParms;
    PCARD_TUPLE_PARMS pTuple;
    PUCHAR pData;
    LPWSTR ret;

    if (DevType != PCCARD_TYPE_NETWORK) {
        DEBUGMSG(ZONE_INIT,
            (TEXT("DetectXircomCE2 - DevType == %d, expecting %d (PCCARD_TYPE_NETWORK\r\n"),
            DevType, PCCARD_TYPE_NETWORK));
        return NULL;
    }

    hPcmciaDll = LoadLibrary(TEXT("PCMCIA.DLL"));
    if (hPcmciaDll == NULL) {
        DEBUGMSG(ZONE_INIT,
            (TEXT("DetectXircomCE2 - LoadLibrary(PCMCIA.DLL) failed %d\r\n"),
            GetLastError()));
        return NULL;
    }

    pfnGetFirstTuple = (GETFIRSTTUPLE) GetProcAddress(hPcmciaDll, TEXT("CardGetFirstTuple"));
    pfnGetTupleData = (GETTUPLEDATA) GetProcAddress(hPcmciaDll, TEXT("CardGetTupleData"));
    if ((pfnGetFirstTuple == NULL) || (pfnGetTupleData == NULL)) {
        DEBUGMSG(ZONE_INIT,
            (TEXT("DetectXircomCE2 - GetProcAddress() failed %d\r\n")));
        FreeLibrary(hPcmciaDll);
        return NULL;
    }

    ret = NULL;
    pTuple = (PCARD_TUPLE_PARMS)buf;
    pTuple->hSocket = hSock;
    pTuple->uDesiredTuple = CISTPL_VERS_1;
    pTuple->fAttributes = 0;        // Don't want link info.
    cerr = pfnGetFirstTuple(pTuple);
    if (cerr == CERR_SUCCESS) {
        pParms = (PCARD_DATA_PARMS)buf;
        pParms->uBufLen = sizeof(buf) - sizeof(CARD_DATA_PARMS);
        pParms->uTupleOffset = 0;
        cerr = pfnGetTupleData(pParms);
        if (cerr == CERR_SUCCESS) {
            //
            // Check manufacturer string
            //
            pData = buf + sizeof(CARD_DATA_PARMS) + 2;
            if (strstr(pData, "Xircom")) {
                //
                // Check product string
                //
                pData += strlen(pData) + 1;
                if (strstr(pData, "CreditCard")) {
                    //
                    // Check product info string
                    //
                    pData += strlen(pData) + 1;
                    if (strstr(pData, "CE2")) {
                         wcscpy(DevKey, (TEXT("XircomCE2")));
                         Install_Driver(DevKey, (LPWSTR)buf,
                                        sizeof(buf)/sizeof(WCHAR));
                         ret = DevKey;
DEBUGMSG(ZONE_INIT,
    (TEXT("DetectXircomCE2 - Detected a Xircom CreditCard CE2 card.\r\n")));
                    }
                }
            }
        }
    }
    FreeLibrary(hPcmciaDll);
    return ret;
}  // DetectNdisDevice
#endif
#endif

/* ------------------------------------------------------------------------- */

#ifdef __cplusplus
#if defined NDIS51_MINIPORT
#   define DriverStruct3    DriverStruct.Ndis50Chars.Ndis40Chars.Ndis30Chars
#   define DriverStruct4    DriverStruct.Ndis50Chars.Ndis40Chars
#   define DriverStruct5    DriverStruct.Ndis50Chars
#elif defined NDIS50_MINIPORT
#   define DriverStruct3    DriverStruct.Ndis40Chars.Ndis30Chars
#   define DriverStruct4    DriverStruct.Ndis40Chars
#elif defined NDIS40_MINIPORT
#   define DriverStruct3    DriverStruct.Ndis30Chars
#   define DriverStruct4    DriverStruct
#else
#   define DriverStruct3    DriverStruct
#endif

#else
#define DriverStruct3   DriverStruct
#define DriverStruct4   DriverStruct
#define DriverStruct5   DriverStruct
#endif


/*
    This flag indicates whether or not we need to call
    NdisMRegisterAdapterShutdownHandler() and
    NdisMDeregisterAdapterShutdownHandler() to register/deregister the shutdown
    handler.  NDIS 5.1 registers the shutdown handler through the
    NDIS_MINIPORT_CHARACTERISTICS structure.  This will be set to FALSE if we
    successfully register as an NDIS 5.1 miniport.  For NDIS versions < 5.1 (or
    if we need to fall back to NDIS 5.0) this flag will remain TRUE and we will
    explicitly register the shutdown handler.
*/
BOOLEAN ExplicitRegisterShutdownHandler = TRUE;


extern int receive_overrun;


VOID PeriodTimerDpc (
    IN  PVOID       SystemSpecific1,
    IN  NDIS_HANDLE hAdapterContext,
    IN  PVOID       SystemSpecific2,
    IN  PVOID       SystemSpecific3 )
{
    // get the pointer to the adapter from the context handle
    PNDIS_ADAPTER pAdapter = ( PNDIS_ADAPTER ) hAdapterContext;
    PHARDWARE     pHardware = &pAdapter->m_Hardware;
    NDIS_STATUS   nsStatus;

    if ( !AcquireAdapter( pAdapter, FALSE ) )
    {
        return;
    }

/* PHY change interrupt is working for KS8841. */
#ifdef DEF_KS8842
    SwitchGetLinkStatus( &pAdapter->m_Hardware );
#endif
    if ( PortReadCounters( &pAdapter->m_Hardware, MAIN_PORT ) )
        goto monitor_release;

#ifdef DEF_KS8842
    if ( PortReadCounters( &pAdapter->m_Hardware, OTHER_PORT ) )
        goto monitor_release;
#endif
    if ( PortReadCounters( &pAdapter->m_Hardware, HOST_PORT ) )
        goto monitor_release;

    if ( pAdapter->m_nPME_wait )
    {
        if ( ++pAdapter->m_nPME_wait >= 2 ) {
            HardwareClearWolPMEStatus( pHardware );

#ifdef DBG
            DbgPrint( "clear PME."NEWLINE );
#endif
            pAdapter->m_nPME_wait = 0;

#ifdef DEBUG_OVERRUN
            DbgPrint( "%u + %u = %u"NEWLINE, pHardware->m_ulReceived,
                pHardware->m_ulDropped,
                pHardware->m_ulReceived + pHardware->m_ulDropped );
            pHardware->m_ulReceived = pHardware->m_ulDropped = 0;
#endif
        }
    }
    else if ( HardwareCheckWolPMEStatus( pHardware ) )
    {
        pAdapter->m_nPME_wait = 1;

#ifdef DBG
        DbgPrint( "PME asserted."NEWLINE );
#endif
    }

monitor_release:
    ReleaseAdapter( pAdapter );

#ifdef DEBUG_OVERRUN
    if ( receive_overrun )
    {
        if ( ++receive_overrun > 2 )
        {
            DbgPrint( "%u + %u = %u"NEWLINE, pHardware->m_ulReceived,
                pHardware->m_ulDropped,
                pHardware->m_ulReceived + pHardware->m_ulDropped );
            pHardware->m_ulReceived = pHardware->m_ulDropped = 0;
            receive_overrun = 0;
        }
    }
#endif
    if ( pAdapter->m_ulNdisMediaState !=
            pHardware->m_ulHardwareState )
    {
        nsStatus = ( NdisMediaStateConnected ==
            pHardware->m_ulHardwareState ) ?
            NDIS_STATUS_MEDIA_CONNECT : NDIS_STATUS_MEDIA_DISCONNECT;

        NdisMIndicateStatus( pAdapter->m_hAdapter, nsStatus, NULL, 0 );
        NdisMIndicateStatusComplete( pAdapter->m_hAdapter );
        pAdapter->m_ulNdisMediaState = pHardware->m_ulHardwareState;
    }
}  // PeriodTimerDpc

/* -------------------------------------------------------------------------- */

static struct hw_fn* ks8842_fn = NULL;

/*
    MiniportHalt

    Description:
        This routine halts the adapter when the driver is stopped.

    Parameters:
        NDIS_HANDLE hContext
            Handle to adapter context containing adapter information.

    Return (None):
*/

VOID MiniportHalt (
    IN  NDIS_HANDLE hContext )
{
    PNDIS_ADAPTER pAdapter = ( PNDIS_ADAPTER ) hContext;
    BOOLEAN       TimerCanceled;

#ifdef DEBUG_MINIPORT_HALT
    DbgPrint( "MiniportHalt"NEWLINE );
#endif

    // cancel the period timer
    NdisMCancelTimer( &pAdapter->m_PeriodTimer, &TimerCanceled );

    ShutdownAdapter( pAdapter );

    // Disconnect the interrupt line
    NdisMDeregisterInterrupt( &pAdapter->m_Interrupt );

    // Pause, waiting for any DPC stuff to clear.
    NdisMSleep( 250000 );

    DeRegisterAdapter( pAdapter );

    if ( ExplicitRegisterShutdownHandler )
    {
        NdisMDeregisterAdapterShutdownHandler( pAdapter->m_hAdapter );
    }

#if UNDER_CE
    NdisTerminateWrapper( pAdapter->m_hAdapter, NULL );
#endif
    NdisFreeSpinLock( &pAdapter->m_lockAdapter );
    NdisFreeSpinLock( &pAdapter->m_lockReceive );
    NdisFreeSpinLock( &pAdapter->m_lockHardware );
    FreeMemory( pAdapter );
    NdisFreeMemory( pAdapter, sizeof( NDIS_ADAPTER ), 0 );
}  // MiniportHalt


/*
    MiniportShutdown

    Description:
        This routine stops the adapter when the driver is stopped.

        Notes: MiniportShutdown SHOULD CALL NO NDISXXX FUNCTIONS.

    Parameters:
        NDIS_HANDLE hContext
            Handle to adapter context containing adapter information.

    Return (None):
*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -