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

📄 netbiostransport.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
         } else {
            ++itAdapt;
         }
    }
    if(fNeedPurge) {
        NetBIOSNotifyFunc(0xFF, 0, 0, 0);
    }

    Done:
        if(AdapterInfo != pAdapterInfo) {
            delete [] pAdapterInfo;
        }
}


//
// When an adapter shows up init it
static void
NetBIOSNotifyFunc(uchar lananum, DWORD dwNTE, int flags, int unused)
{
    CCritSection csLock(&csAdapterStackList);
    csLock.Lock();
    HRESULT hr;


    //
    // Loop through any adapter that has been deleted, and remove it now
    while(0 != NBAdapterDeleteStack.size()) {
        NetBIOSAdapter *pAdapter = NBAdapterDeleteStack.front();
        NBAdapterDeleteStack.pop_front();
        ASSERT(NULL != pAdapter);

        ce::list<char>::iterator itDiscover;
        ce::list<char>::iterator itDiscoverEnd;
        ce::list<NetBIOSAdapter *>::iterator itAdap;
        ce::list<NetBIOSAdapter *>::iterator itAdapEnd;
        char LANA = (char)0xFF;

        //
        // Seek our our adapter from the adapter stack and remove it from there (it may not be there)
        for(itAdap = NBAdapterStack.begin(), itAdapEnd = NBAdapterStack.end(); itAdap != itAdapEnd; ++itAdap) {
            if(pAdapter == *itAdap) {
                LANA = pAdapter->GetLANA();
                NetBIOSAdapter *pDel =  (*itAdap);
                NBAdapterStack.erase(itAdap++);
                ASSERT(NULL != pDel);
                break;
            }
        }


        TRACEMSG(ZONE_INIT, (L"SMBSRV:NetBIOSNotifyFunc: Lana %u being terminated",LANA));

        //
        // Stop the TCP listening thread
        hr = TerminateTCPListenThread(pAdapter->GetLANA());
        ASSERT(SUCCEEDED(hr));

        //
        // Destroy our adapter and its threads (which prob are dead by now anyway)
        if(pAdapter && FAILED(pAdapter->HaltAdapter())) {
            TRACEMSG(ZONE_INIT, (L"SMBSRV:NetBIOSNotifyFunc: Lana %u termination failure!",LANA));
            ASSERT(FALSE);
        }
        if(pAdapter) {
            delete pAdapter;
        }

    }

    //
    // Init a lan adapter
    if (flags & LANA_UP_FL) {
        if(g_fIsRunning) {

            #ifdef DEBUG
                ce::list<NetBIOSAdapter *>::iterator itAdapChk;
                ce::list<NetBIOSAdapter *>::iterator itAdapChkEnd;
                for(itAdapChk = NBAdapterStack.begin(), itAdapChkEnd = NBAdapterStack.end(); itAdapChk != itAdapChkEnd; ++itAdapChk) {
                    ASSERT(lananum != (*itAdapChk)->GetLANA());
                }
            #endif
            if(FAILED(InitLana(lananum, dwNTE))) {
                TRACEMSG(ZONE_ERROR, (L"SMBSRV:Error initing lana(%d)!",lananum));
            }
        } else {
            TRACEMSG(ZONE_NETBIOS, (L"SMBSRV: notification routine turned off... caching result"));
        }
    }
    TRACEMSG(ZONE_INIT, (L"SMBSRV:NetBIOSNotifyFunc"));
}




//
// Listen on name changes -- if/when one occurs restart the server
HRESULT StartListenOnNameChange()
{
    if(!NameChangeNotification::h) {
        StringConverter EventName;
        HANDLE   hNotifyInitialized = OpenEvent (EVENT_ALL_ACCESS, FALSE, NOTIFICATION_EVENTNAME_API_SET_READY);
        if (WAIT_OBJECT_0 != WaitForSingleObject (hNotifyInitialized, 20*1000)) {
            CloseHandle (hNotifyInitialized);
            TRACEMSG(ZONE_ERROR, (L"SMBSRV: notifications are not present"));
            return E_UNEXPECTED;
        }
        CloseHandle (hNotifyInitialized);

        EventName.append(NAMED_EVENT_PREFIX_TEXT);
        EventName.append("SMB_NameNotifyEvent");

        //
        // Create a listen event
        if(NULL == (NameChangeNotification::h = CreateEvent(NULL, FALSE, FALSE, L"SMB_NameNotifyEvent"))) {
            TRACEMSG(ZONE_ERROR, (L"SMBSRV: Cant create named notify event!"));
            return E_OUTOFMEMORY;
        }
        if(FALSE == CeRunAppAtEvent(EventName.GetUnsafeString(), NOTIFICATION_EVENT_MACHINE_NAME_CHANGE)) {
            RETAILMSG(1, (L"SMBSRV: ERROR Could not get notification for name notification!"));
            return E_UNEXPECTED;
        }

        //
        // Make a event listening thread
        if(NULL == (SMB_Globals::g_pWakeUpOnEvent = new WakeUpOnEvent())) {
            TRACEMSG(ZONE_ERROR, (TEXT("-SMB_Init - StartServer failed -- couldnt create wakeup on event thread")));
            return E_OUTOFMEMORY;
        }

        return SMB_Globals::g_pWakeUpOnEvent->AddEvent(NameChangeNotification::h,
                                               &g_HostNameWakeUpNode,
                                               &NameChangeNotification::usID);
    }
    else {
        return S_OK;
    }
}

//
// Listen on name changes -- if/when one occurs restart the server
HRESULT StopListeningOnNameChange()
{
    if(NameChangeNotification::h) {
        ASSERT(NULL != g_hHaltNetbiosTransport);
        ASSERT(NULL != NameChangeNotification::h);

        SMB_Globals::g_pWakeUpOnEvent->RemoveEvent(NameChangeNotification::usID);
        SetEvent(g_hHaltNetbiosTransport);
        CloseHandle(NameChangeNotification::h);
        NameChangeNotification::usID = 0xFFFF;
        NameChangeNotification::h = NULL;

        return S_OK;
    } else {
        return S_OK;
    }
}


//
// Register with netbios for adapters (it will fire with already known adapters
//   first)
HRESULT StartEnumeratingNetbios()
{
    ASSERT(0xFF == AddressChangeNotification::usID);
    ASSERT(INVALID_SOCKET == AddressChangeNotification::s);
    ASSERT(NULL == AddressChangeNotification::ov.hEvent);


    AddressChangeNotification::s = socket(AF_INET, SOCK_STREAM, 0);
    AddressChangeNotification::ov.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    //
    // Issue IOCTL to listen for adapter change information, then listen for it
    if(ERROR_SUCCESS != WSAIoctl(AddressChangeNotification::s, SIO_ADDRESS_LIST_CHANGE, NULL, 0, NULL, 0, NULL, &AddressChangeNotification::ov, NULL) &&
       ERROR_IO_PENDING != GetLastError()) {
        TRACEMSG(ZONE_ERROR, (L"SMBSRV:IP Adapter change error -- cant call ioctl with SIO_ADDRESS_LIST_CHANGE"));
        ASSERT(FALSE);
        return E_UNEXPECTED;
    }

    //
    // Call the fn() once to start -- and then put it into the event list
    SMBSRVR_IPAddressChanged();
    NetBIOSNotifyFunc(0, 0, LANA_UP_FL, 0);

    return SMB_Globals::g_pWakeUpOnEvent->AddEvent(AddressChangeNotification::ov.hEvent,
                                           &g_IPAddressChangedWakeUpNode,
                                           &AddressChangeNotification::usID);
}


//
// UnRegister with netbios for adapters
HRESULT StopEnumeratingNetbios()
{
    ASSERT(FALSE == g_fIsRunning);
    ASSERT(NULL != g_hHaltNetbiosTransport);

    SetEvent(g_hHaltNetbiosTransport);

    //
    // Close up any handles that are associated with the address change code
    {
        ASSERT(0xFF != AddressChangeNotification::usID);
        ASSERT(INVALID_SOCKET != AddressChangeNotification::s);
        ASSERT(NULL != AddressChangeNotification::ov.hEvent);

        SMB_Globals::g_pWakeUpOnEvent->RemoveEvent(AddressChangeNotification::usID);
        closesocket(AddressChangeNotification::s);
        CloseHandle(AddressChangeNotification::ov.hEvent);
        AddressChangeNotification::usID = 0xFF;
        AddressChangeNotification::s = INVALID_SOCKET;
        AddressChangeNotification::ov.hEvent = NULL;
    }

    return S_OK;
}


//this is a utility function that is used by NETBIOS to make CE behave a bit
//  more like NT
BYTE
NETBIOS_TRANSPORT::Netbios(ncb * pncb)
{
    BOOL fRet = FALSE;
    NCB newncb;
    for(;;)
    {
        //
        // Convert real NCB to WinCE NCB
        //
        switch (pncb->ncb_command) {
            case NCBCALL:       newncb.Command = NB_CALL;              break;
            case NCBLISTEN:     newncb.Command = NB_LISTEN;            break;
            case NCBHANGUP:     newncb.Command = NB_HANGUP;            break;
            case NCBSEND:       newncb.Command = NB_SEND;              break;
            case NCBRECV:       newncb.Command = NB_RECEIVE;           break;
            case NCBRECVANY:    newncb.Command = NB_RECEIVE_ANY;       break;
            case NCBDGSEND:     newncb.Command = NB_SEND_DG;           break;
            case NCBDGRECV:     newncb.Command = NB_RECEIVE_DG;        break;
            case NCBDGSENDBC:   newncb.Command = NB_SEND_BCAST_DG;     break;
            case NCBDGRECVBC:   newncb.Command = NB_RECEIVE_BCAST_DG;  break;
            case NCBADDNAME:    newncb.Command = NB_ADD_NAME;          break;
            case NCBADDMHNAME:  newncb.Command = NB_ADD_NAME;          break;
            case NCBDELNAME:    newncb.Command = NB_DELETE_NAME;       break;
            case NCBHANGUPANY:  newncb.Command = NB_HANGUP_ANY;        break;
            case NCBCANCEL:     newncb.Command = NB_CANCEL;            break;
            case NCBQUERYLANA:  newncb.Command = NB_QUERY_LANA;        break;
            default:
                TRACEMSG(ZONE_ERROR, (L"SMBSRV:Netbios - Illegal NCB command %B!!!\n", pncb->ncb_command));
                pncb->ncb_retcode = NRC_ILLCMD;
                return NRC_ILLCMD;
        }

        newncb.ReturnCode = 0;
        newncb.cTotal =     pncb->ncb_length;
        newncb.LSN =        pncb->ncb_lsn;
        newncb.LanaNum =    pncb->ncb_lana_num;
        memcpy(newncb.CallName, pncb->ncb_callname, sizeof(newncb.CallName));
        memcpy(newncb.Name, pncb->ncb_name, sizeof(newncb.Name));

        fRet = NETbiosThunk(0,newncb.Command,&newncb, pncb->ncb_length, pncb->ncb_buffer,0, NULL);
        if (FALSE == fRet)
        {
            switch (newncb.ReturnCode)
            {
                case NB_CANCELED:
                    pncb->ncb_retcode = NRC_CMDCAN;
                    break;
                case NB_NOMEM:
                    pncb->ncb_retcode = NRC_NORESOURCES;
                    break;
                case NB_BADNAME:
                    pncb->ncb_retcode = NRC_INUSE;
                    break;
                case NB_DUPNAME:
                    pncb->ncb_retcode = NRC_DUPNAME;
                    break;
                case NB_NAME_CFT:
                    pncb->ncb_retcode = NRC_NAMCONF;
                    break;
                case NB_NO_SSN:
                    pncb->ncb_retcode = NRC_SNUMOUT;
                    break;
                case NB_SSN_CLOSED:
                    pncb->ncb_retcode = NRC_SCLOSED;
                    break;
                case NB_SSN_ABORT:
                    pncb->ncb_retcode = NRC_SABORT;
                    break;
                case NB_IN_RECV:
                    pncb->ncb_retcode = NRC_TOOMANY;
                    break;
                case NB_MORE_DATA:
                    pncb->ncb_retcode = NRC_INCOMP;
                    break;
                case NB_IN_SELECT:
                    pncb->ncb_retcode = NRC_IFBUSY;
                    break;
                case NB_BAD_COMMAND:
                    pncb->ncb_retcode = NRC_ILLCMD;
                    break;
                case NB_BAD_LANA:
                    pncb->ncb_retcode = NRC_ADPTMALFN;
                    break;
                case NB_KEEP_ALIVE:
                    // If we given keepalive, just hide this from our caller and thunk again
                    TRACEMSG(ZONE_NETBIOS, (L"SMBSRV:Netbios - got keepalive, retrying packet: %d",newncb.ReturnCode));
                    continue;
                case NB_FAILURE:
                default:
                    pncb->ncb_retcode = NRC_IFAIL;
                    break;
            }
        #ifdef DEBUG
                if(10058 != newncb.ReturnCode ) {
                    TRACEMSG(ZONE_ERROR, (L"SMBSRV:Netbios - NCB Error %d\n",newncb.ReturnCode));
                }
        #endif
            pncb->ncb_length = (WORD) newncb.cTotal;
            pncb->ncb_lsn = newncb.LSN;
            pncb->ncb_lana_num = newncb.LanaNum;
            return pncb->ncb_retcode;
        }
        else
        {

            //
            // Convert back
            //
            pncb->ncb_retcode = 0;
            pncb->ncb_length = (WORD) newncb.cTotal;
            pncb->ncb_lsn = newncb.LSN;
            pncb->ncb_lana_num = newncb.LanaNum;
            memcpy(pncb->ncb_callname, newncb.CallName, sizeof(newncb.CallName));
            memcpy(pncb->ncb_name, newncb.Name, sizeof(newncb.Name));
            return 0;
        }
    }
    ASSERT(FALSE);//should never be here
    return 0;
}   // Netbios


BOOL AllowLana(LANA_INFO *pLanInfo)
{
    //
    // set AdapInfo to a reasonable number of adapters
    //   if we need more, we will request that later
    BOOL fAllowed = FALSE;
    IP_ADAPTER_INFO AdapInfo[1];
    PIP_ADAPTER_INFO pAdapInfo = &AdapInfo[0];
    PIP_ADAPTER_INFO pAdapTemp;
    ULONG ulAdapSize = sizeof(AdapInfo);

    CReg CRAdapterList;
    WCHAR wAdapterList[MAX_PATH];
    CHAR  AdapterList[MAX_PATH];

    //
    // Load the adapterlist from the registry
    if(FALSE == CRAdapterList.Open(HKEY_LOCAL_MACHINE, L"Services\\SMBServer")) {
        RETAILMSG(1, (L"No registy key under HKLM\\Services\\SMBServer\n"));
        goto Done;
    }
    if(FALSE == CRAdapterList.ValueSZ(L"AdapterList", wAdapterList, MAX_PATH / sizeof(WCHAR))) {
        RETAILMSG(1, (L"Name value under HKLM\\Services\\AdapterList is not there\n"));
        goto Done;
    }
    if(0 == wcscmp(L"*", wAdapterList)) {
        RETAILMSG(1, (L"All adapters are given access!\n"));
        fAllowed = TRUE;
        goto Done;
    }
    if(0x0100007f == pLanInfo->IPAddr && wcsstr(wAdapterList, L"localhost")) {
        RETAILMSG(1, (L"Allowing localhost!\n"));
        fAllowed = TRUE;
        goto Done;
    }
    if(0 == WideCharToMultiByte(CP_ACP, 0, wAdapterList, -1, AdapterList, MAX_PATH,NULL,NULL)) {
        TRACEMSG(ZONE_ERROR, (L"Conversion of AdapterList (%s) failed!!!", wAdapterList));
        ASSERT(FALSE);
        goto Done;
    }

    DWORD dwRetCode = GetAdaptersInformation(reinterpret_cast<CHAR**>(&pAdapInfo), ulAdapSize, &ulAdapSize);
    if(NO_ERROR != dwRetCode) {
        fAllowed = FALSE;
        goto Done;
    }

    //
    // Now loop through all of the adapters looking for IP addresses
    pAdapTemp = pAdapInfo;
    while(pAdapTemp) {
        //
        // Loop through all of the ipaddresses in the address list
        IP_ADDR_STRING *pAddr = &(pAdapTemp->IpAddressList);
        while(pAddr) {
            if((ULONG)pLanInfo->IPAddr == inet_addr(pAddr->IpAddress.String)) {
                char *pAdapAllowedTemp = AdapterList;

                //
                // Loop through all the allowed interfaces
                while(pAdapAllowedTemp && NULL != *pAdapAllowedTemp) {
                    char *pAdapEnd = strchr(pAdapAllowedTemp, ';');
                    ASSERT(FALSE == fAllowed); //if it were allowed we shouldnt be searching!

                    //
                    // Replace the ; with a null
                    if(pAdapEnd) {
                        ASSERT(';' == *pAdapEnd);
                        *pAdapEnd = NULL;
                    }

                    //
                    // See if the adapters are equal
                    if(0 == strcmp(pAdapTemp->AdapterName, pAdapAllowedTemp)) {
                        TRACEMSG(ZONE_NETBIOS, (L"NETBIOS: found ip addr for lana!"));
                        fAllowed = TRUE;
                    }

                    //
                    // Fix the search string back up
                    if(pAdapEnd)
                        *pAdapEnd = ';';

                    //
                    // Quit searching if its allowed otherwise, skip to the next
                    //   string
                    if(fAllowed)
                        goto Done;
                    else if (pAdapEnd) {
                        pAdapAllowedTemp = pAdapEnd+1;
                    } else {
                        pAdapAllowedTemp = NULL;
                    }

⌨️ 快捷键说明

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