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

📄 miniport.cxx

📁 WinCE5.0部分核心源码
💻 CXX
📖 第 1 页 / 共 5 页
字号:

        if (pAdapter) {
            gpPAN->AddRef ();
            gpPAN->Unlock ();
            MpMediaStatusIndicate (pAdapter);
            gpPAN->Lock ();
            gpPAN->DelRef ();
        }
    }

    if (pAdapter)
        pAdapter->DelRef ();
}

static BTHPAN_CONNECTION *GetAdapterConnection (BTHPAN_ADAPTER *pAdapter) {
    SVSUTIL_ASSERT (gpPAN->IsLocked ());

    int nAdapter = pAdapter - gpPAN->aAdapters;
    int i;
    for (i = 0 ; i < SVSUTIL_ARRLEN(gpPAN->aConn) ; ++i) {
        if ((gpPAN->aConn[i].state != DOWN) && (gpPAN->aConn[i].nAdapter == nAdapter)) {
            return &gpPAN->aConn[i];
        }
    }

    return NULL;
}

static DWORD WINAPI TimeoutConnection (void *pCallContext) { // Aborted call == immediate death...
    IFDBG(DebugOut (DEBUG_PAN_TRACE, L"TimeoutConnection 0x%08x\n", pCallContext));

    if (! gpPAN) {
        IFDBG(DebugOut (DEBUG_ERROR, L"[PAN] TimeoutConnection: context doesn't exist\n"));
        return ERROR_SUCCESS;
    }

    gpPAN->Lock ();
    if (gpPAN->state != UP) {
        IFDBG(DebugOut (DEBUG_ERROR, L"[PAN] TimeoutConnection: context not up\n"));
        gpPAN->Unlock ();
        return ERROR_SUCCESS;
    }

    BTHPAN_CONNECTION *pConn = ConnFromCtx (pCallContext);

    if (pConn) {
        IFDBG(DebugOut (DEBUG_PAN_TRACE, L"TimeoutConnection : aborting connection %04x%08x cid=0x%04x\n", pConn->ba.NAP, pConn->ba.SAP, pConn->cid));

        CloseConnection (pConn, NULL);
    } else {
        IFDBG(DebugOut (DEBUG_ERROR, L"[PAN] TimeoutConnection: connection not found!\n"));
    }

    gpPAN->Unlock ();

    IFDBG(DebugOut (DEBUG_PAN_TRACE, L"TimeoutConnection DONE\n"));

    return ERROR_SUCCESS;
}

static void ConnectionStarted (BTHPAN_CONNECTION *pConn) {
    SVSUTIL_ASSERT (gpPAN->IsLocked ());
    SVSUTIL_ASSERT (pConn->state == CONFIG_LINK);
    SVSUTIL_ASSERT (pConn->fConfigState == CONFIG_DONE);

    pConn->state = CONFIG_BNEP;
    pConn->fConfigState = 0;

    if (pConn->fPeerInitiated)  // Nothing to do, just wait for the other guy
        return;

    // We started connection, so we KNOW what adapter it is.
    SVSUTIL_ASSERT (pConn->nAdapter >= 0);

    unsigned char packet_body[256];

    SVSUTIL_ASSERT(gpPAN->cDataHeaders + gpPAN->cDataTrailers < 128);
    unsigned char *p = packet_body + gpPAN->cDataHeaders;

    *p++ = 0x01;            // Control
    *p++ = 0x01;            // Setup connection request
    unsigned int uiDestUUID, uiSrcUUID;

    if (IsBluetoothBasedGUID (&pConn->dest_service_id, &uiDestUUID) &&
        IsBluetoothBasedGUID (&gpPAN->aAdapters[pConn->nAdapter].service_id, &uiSrcUUID)) {
        if ((uiSrcUUID <= 0xffff) && (uiDestUUID <= 0xffff)) {
            *p++ = 2;
            *p++ = (unsigned char)(uiDestUUID >> 8);
            *p++ = (unsigned char)(uiDestUUID);
            *p++ = (unsigned char)(uiSrcUUID >> 8);
            *p++ = (unsigned char)(uiSrcUUID);
        } else {    // 32 bits
            *p++ = 4;
            *p++ = (unsigned char)(uiDestUUID >> 24);
            *p++ = (unsigned char)(uiDestUUID >> 16);
            *p++ = (unsigned char)(uiDestUUID >> 8);
            *p++ = (unsigned char)(uiDestUUID);
            *p++ = (unsigned char)(uiSrcUUID >> 24);
            *p++ = (unsigned char)(uiSrcUUID >> 16);
            *p++ = (unsigned char)(uiSrcUUID >> 8);
            *p++ = (unsigned char)(uiSrcUUID);
        }
    } else {    // Full UUIDs
        *p++ = sizeof(GUID);    // UUID size - full UUIDs

        SVSUTIL_ASSERT (sizeof(GUID) == sizeof(pConn->dest_service_id));
        SVSUTIL_ASSERT (sizeof(GUID) == sizeof(gpPAN->aAdapters[pConn->nAdapter].service_id));

        UUIDToWire (p, &pConn->dest_service_id);
        p += sizeof(GUID);
        UUIDToWire (p, &gpPAN->aAdapters[pConn->nAdapter].service_id);
        p += sizeof(GUID);
    }

    BD_BUFFER Buff;
    
    Buff.cSize = (p - packet_body) + gpPAN->cDataTrailers;
    Buff.cStart = gpPAN->cDataHeaders;
    Buff.cEnd = Buff.cSize - gpPAN->cDataTrailers;
    Buff.pFree = BufferFree;
    Buff.fMustCopy = TRUE;
    Buff.pBuffer   = packet_body;

    unsigned int uiConnRef = pConn->uiRef;

    pConn->scTimeout = btutil_ScheduleEvent (TimeoutConnection, ConnToCtx (pConn), gpPAN->aAdapters[pConn->nAdapter].uiCrtTimeout);

    if (! StartAuthenticatingThread (pConn)) {
        gpPAN->AddRef ();
        gpPAN->Unlock ();

        IFDBG(DumpBnepPacket (L"Sending connection request.", &Buff));

        int iRes = gpPAN->l2cap_if.l2ca_DataDown_In (gpPAN->hL2CAP, ConnToCtx (pConn), pConn->cid, &Buff);

        gpPAN->Lock ();
        gpPAN->DelRef ();

        if ((iRes != ERROR_SUCCESS) && (pConn->uiRef == uiConnRef))
            CloseConnection (pConn, NULL);
    } else {    // Delay request
        IFDBG(DebugOut (DEBUG_PAN_TRACE, L"ConnectionStarted : connection request delayed pending authentication\n"));

        BNEPPacket *pPendingPacket = new BNEPPacket(BufferCopy(&Buff));
        if (pPendingPacket)
            QueuePendingPacket(pConn, pPendingPacket);        
    }
}

static void AddConfigFlag (BTHPAN_CONNECTION *pConn, unsigned int uiFlag) {
    pConn->fConfigState |= uiFlag;

    if (pConn->fConfigState == CONFIG_DONE)
        ConnectionStarted (pConn);
}

static void MpCleanUpConnections (void) {
    IFDBG(DebugOut (DEBUG_PAN_TRACE, L"MpCleanUpConnections\n"));

    // Go through all adapters and set states of everything to disconnected

    gpPAN->Lock ();

    int i;
    for (i = 0 ; i < SVSUTIL_ARRLEN (gpPAN->aConn) ; ++i)
        SetConnectionToDown (&gpPAN->aConn[i]);

    gpPAN->Unlock ();

    IFDBG(DebugOut (DEBUG_PAN_TRACE, L"MpCleanUpConnections DONE\n"));
}

static int FilterByMCast (FILTER *pFilter, unsigned char *pAddr) {
    if (pFilter->cMCasts == 0)
        return FALSE;

    unsigned __int64 ui64Addr = net48tohost64(pAddr);
    for (int i = 0 ; i < (int)pFilter->cMCasts ; ++i) {
        pAddr = (unsigned char *)&pFilter->amc[i].from;
        unsigned __int64 ui64from = net48tohost64(pAddr);
        pAddr = (unsigned char *)&pFilter->amc[i].to;
        unsigned __int64 ui64to = net48tohost64(pAddr);

        if ((ui64Addr >= ui64from) && (ui64Addr <= ui64to))
            return FALSE;
    }

    return TRUE;
}

static int FilterByType (FILTER *pFilter, unsigned int uiNetType) {
    // Returns TRUE if packet is filtered out (NOT sent)

    if (pFilter->cNetTypes == 0)
        return FALSE;

    for (int i = 0 ; i < (int)pFilter->cNetTypes ; ++i) {
        if ((uiNetType >= pFilter->ant[i].from) && (uiNetType <= pFilter->ant[i].to))
            return FALSE;
    }

    return TRUE;
}

static void InvertAddress (unsigned char *pAddr1, unsigned char *pAddr2, unsigned char *pAddr3) {
    if (memcmp (pAddr1, pAddr3, 6) == 0)
        memcpy (pAddr1, pAddr2, 6);
    else if (memcmp (pAddr1, pAddr2, 6) == 0)
        memcpy (pAddr1, pAddr3, 6);
}

static int ComputeTotalExtensionLengthByType (unsigned char *pExt, int cTotal, BOOL fIgnoreKnown) { // return > 0 or -1
    // Total can be bigger than extensions.
    int fExt = TRUE;
    int iLen = 0;

    while (fExt) {
        if (cTotal < 2)
            return -1;

        unsigned char eType = *pExt & 0x7f;
        fExt = *pExt >> 7;
        unsigned char eLen = pExt[1];

        if (eLen < 1)
            return -1;

        cTotal -= eLen;
        pExt += eLen + 2;

        if (!fIgnoreKnown || (eType != 0))
            iLen += eLen + 2;
    }

    return (cTotal >= 0) ? iLen : -1;
}

static int ComputeTotalExtensionLength (unsigned char *pExt, int cTotal) { 
    return ComputeTotalExtensionLengthByType (pExt, cTotal, FALSE);
}

static void ProcessArpData (BTHPAN_ADAPTER *pAdapter, unsigned char *pPacket, int cPacket) {
    if ((cPacket != 28) && (cPacket != 46)) {
        IFDBG(DebugOut (DEBUG_WARN, L"[PAN] Warning - ARP packet with unexpected zie %d\n", cPacket));
        return;
    }

    if (pAdapter->fAddressSet) {
        // Substitute our internal addresses for Bluetooth and vice versa in ARP packets.
        InvertAddress (pPacket + 8, pAdapter->ethAddr, gpPAN->eth);
        InvertAddress (pPacket + 18, pAdapter->ethAddr, gpPAN->eth);        
    }
}

static int ProcessEthernet (
        BTHPAN_CONNECTION *pConnRecv, 
        unsigned char *pDestEther, 
        unsigned char *pSrcEther,
        unsigned int uiNetType, 
        unsigned char *p8021q, 
        unsigned char *pExt,
        int iExtSize,
        unsigned char *pData, 
        int cData) {
    IFDBG(DebugOut (DEBUG_PAN_TRACE, L"ProcessEthernet\n"));

    SVSUTIL_ASSERT (gpPAN->IsLocked ());
    unsigned int uiConnRef = pConnRecv->uiRef;

    if (pConnRecv->state == CONFIG_SECURITY) {
        IFDBG(DebugOut (DEBUG_WARN, L"ProcessEthernet : packet dropped because security setup is still in process\n"));
        return TRUE;
    }

    if ((pConnRecv->state != UP) || (pConnRecv->nAdapter == -1) || (gpPAN->aAdapters[pConnRecv->nAdapter].state != UP)) {
        IFDBG(DebugOut (DEBUG_WARN, L"ProcessEthernet : packet on a closed (or closing) connection or on inactive adapter\n"));
        return FALSE;
    }

    if (! pSrcEther)
        pSrcEther = pConnRecv->eth;

    if (! pDestEther)
        pDestEther = gpPAN->eth;

    BTHPAN_ADAPTER *pAdapter = &gpPAN->aAdapters[pConnRecv->nAdapter];
    pAdapter->AddRef ();
    int nAdapter = pAdapter - gpPAN->aAdapters;

    int fMCast       = ETH_IS_MULTICAST(pDestEther);
    int fBroad       = ETH_IS_BROADCAST(pDestEther);
    int fUnicast     = (! (fMCast || fBroad));
    int fUnicastToMe = fUnicast && (memcmp (gpPAN->eth, pDestEther, 6) == 0);

    int fConsumerFound = FALSE;

    if ((! fUnicastToMe) && (pAdapter->type != PANU)) {   // Do the forwarding...    
        for (int i = 0 ; (pAdapter->state == UP) && (i < SVSUTIL_ARRLEN (gpPAN->aConn)) ; ++i) {
            if ((pConnRecv != &gpPAN->aConn[i]) && (gpPAN->aConn[i].nAdapter == nAdapter) && (gpPAN->aConn[i].state == UP)) {
                BTHPAN_CONNECTION *pConnForward = &gpPAN->aConn[i];

                // Broadcast addresses are sent everywhere
                // Multicast addresses are sent everywhere except where not filtered
                // If this adapter is PANU, it sends everything over this one and only one connection
                int fSendSrc = TRUE;    // Source is always sent - this packet came from elsewhere
                int fSendDst = (memcmp (pConnForward->eth, pDestEther, 6) != 0);
                if ((! (fBroad || fMCast)) && fSendDst)
                    continue;

                if (! fSendDst)    // got it!
                    fConsumerFound = TRUE;

                BOOL fOmitPayload = FALSE;
                
                int iUnkExtSize = 0;
                if (pExt && (iExtSize > 0))
                    iUnkExtSize = ComputeTotalExtensionLengthByType(pExt, iExtSize, TRUE);

                if (iUnkExtSize < 0) {
                    // Something has gone wrong!  We should never get here since we should have
                    // already verified that the extension headers look good.
                    SVSUTIL_ASSERT(0);
                    return FALSE;
                }

                if (FilterByType (&pConnForward->filter, uiNetType)) {
                    IFDBG(DebugOut (DEBUG_PAN_TRACE, L"ProcessEthernet :: packet filtered by net type rule\n"));
                    if (iUnkExtSize == 0)
                        continue;
                    fOmitPayload = TRUE;
                    IFDBG(DebugOut (DEBUG_PAN_TRACE, L"ProcessEthernet :: forwarding *just* unknown extensions\n"));
                }

                if (fMCast && FilterByMCast (&pConnForward->filter, pDestEther)) {
                    IFDBG(DebugOut (DEBUG_PAN_TRACE, L"ProcessEthernet :: packet filtered by mcast rule\n"));
                    if (iUnkExtSize == 0)
                        continue;
                    fOmitPayload = TRUE;
                    IFDBG(DebugOut (DEBUG_PAN_TRACE, L"ProcessEthernet :: forwarding *just* unknown extensions\n"));
                }                               

                // Send the thing...
                BD_BUFFER *pBuff = BufferAlloc (gpPAN->cDataHeaders + gpPAN->cDataTrailers + (fSendSrc ? 6 : 0) + (fSendDst ? 6 : 0) + 3 + iUnkExtSize + (p8021q ? 4 : 0) + (fOmitPayload ? 0 : cData));
                if (pBuff) {
                    pBuff->cStart = gpPAN->cDataHeaders;
                    pBuff->cEnd   = pBuff->cSize - gpPAN->cDataTrailers;

                    // ** Add addresses **

                    unsigned char *p = pBuff->pBuffer + pBuff->cStart;
                    if (fSendSrc && fSendDst) {
                        *p++ = (iUnkExtSize ? 0x80 : 0x00);    // general ether
                        memcpy (p, pDestEther, 6);
                        p += 6;
                        memcpy (p, pSrcEther, 6);
                        p += 6;                        
                    } else if (fSendSrc) {
                        *p++ = (iUnkExtSize ? 0x83 : 0x03);    // source only
                        memcpy (p, pSrcEther, 6);
                        p += 6;
                    } else if (fSendDst) {
                        *p++ = (iUnkExtSize ? 0x84 : 0x04);    // dest only
                        memcpy (p, pDestEther, 6);
                        p += 6;
                    } else {
                        *p++ = (iUnkExtSize ? 0x82 : 0x02);    // compressed
                    }

                    // ** Add protocol type **

                    if (p8021q) { // always use 802.1q header if present
                        *p++ = 0x81;
                        *p++ = 0x00;
                    } else if (fOmitPayload) { // zero out protocol when filtered
                        *p++ = 0x00;
                        *p++ = 0x00;
                    } else {
                        *p++ = uiNetType >> 8;
                        *p++ = uiNetType & 0xff;
                    }

                    // ** Add unknown extensions **

                    while (iUnkExtSize > 0) {        
                        unsigned char eType = *pExt & 0x7f;
                        unsigned int eLen = pExt[1];

                        if (eType != 0) {
                            if ((iUnkExtSize - (2 + eLen)) > 0)
                                *pExt |= 0x80; // more extensions
                            else
                                *pExt &= 0x7f; // last extension
                            
                            // Add this unknown extension to the packet
                            memcpy (p, pExt, eLen + 2);
                            p += (2 + eLen);
                            
                            iUnkExtSize -= (2 + eLen);
                        }

⌨️ 快捷键说明

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