📄 netbiostransport.cpp
字号:
} 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 + -