//========================================================================== // PRODUCT: RusRoute - MaaSoftware routing firewall software driver // (C) Copyright Moiseenko A.A., MaaSoftware, 2003-2008. All Rights Reserved. // http://www.maasoftware.ru http://www.maasoftware.com // http://www.rusroute.ru http://www.rusroute.com // support@maasoftware.ru // You can use this driver sample for free for non commercial use //========================================================================== // FILE: Driver.cpp // // AUTHOR: Andrey A. Moiseenko // // OVERVIEW CMaaDriver class. // ~~~~~~~~ // DATE: 26.10.2003 //========================================================================== #include "perm.h" #include "temp.h" /* #ifdef _WIN64 void KfRaiseIrql(IN KIRQL NewIrql) { unsigned char OldIrql; KeRaiseIrql(NewIrql, (PKIRQL)&OldIrql); } #endif */ //--------------------------------------------------------------------------- struct MaaRF_SrvItem { int m_CtlCode; pfMaaRFService m_fPtr; }; //--------------------------------------------------------------------------- CMaaDriver::CMaaDriver () : m_fTimersAreStarted ( FALSE ), m_PrintDbgLock(false), m_hServices ( 50 ), #ifdef DRV_USE_DEBUG_STRING_BUFFERS m_FirstLog(true, 2 * 1024), m_LastLog(false, 2 * 1024) #else m_FirstLog(true, 1 * 1024), m_LastLog(false, 1 * 1024) #endif { int i; pEthFrame = new CDrvEthFrame; pFddiFrame = new CDrvFddiFrame; pTokenRingFrame = new CDrvTokenRingFrame; m_pMemBlock = new _byte [ CMaaMemBlockSize ]; if ( m_hServices.IsOK () ) { static MaaRF_SrvItem SrvList [] = { { RUSROUTE_GET_VERSION, &CMaaDriver::Srv_GetVersion }, { RUSROUTE_GET_ADAPTER_LIST, &CMaaDriver::Srv_GetAdapterList }, { RUSROUTE_GET_ADAPTER_INFO, &CMaaDriver::Srv_GetAdapterInfo }, { RUSROUTE_SET_EVENT_HANDLE, &CMaaDriver::Srv_SetEventHandle }, { RUSROUTE_GET_PACKET, &CMaaDriver::Srv_GetPacket }, { RUSROUTE_PUT_PACKET, &CMaaDriver::Srv_PutPacket }, { RUSROUTE_TCP_OPTIMIZE, &CMaaDriver::Srv_TcpOptimize }, { RUSROUTE_LOGIN_LOGOUT, &CMaaDriver::Srv_LoginLogout }, { RUSROUTE_GET_JOURNAL_RECS, &CMaaDriver::Srv_GetJournalRecs }, { RUSROUTE_GET_LOG, &CMaaDriver::Srv_GetLog }, { RUSROUTE_GET_TCP_OPT_STR, &CMaaDriver::Srv_GetTcpOptStr }, { RUSROUTE_GET_WAN_UP_LINKS, &CMaaDriver::Srv_GetWanUpLinks } //{ RUSROUTE_TEST1, &CMaaDriver::Srv_Test1 }, //{ RUSROUTE_TEST2, &CMaaDriver::Srv_Test2 } }; for ( i = sizeof ( SrvList ) / sizeof ( SrvList [ 0 ] ); i--; ) { m_hServices.Add ( SrvList [ i ].m_CtlCode, SrvList [ i ].m_fPtr ); } } } //--------------------------------------------------------------------------- void CMaaDriver::StartAllTimers () { if ( this && IsOK () && !m_fTimersAreStarted ) { m_fTimersAreStarted = TRUE; } } //--------------------------------------------------------------------------- CMaaDriver::~CMaaDriver () { delete [] m_pMemBlock; delete pTokenRingFrame; delete pFddiFrame; delete pEthFrame; } //--------------------------------------------------------------------------- BOOL CMaaDriver::IsOK () { return m_IsOK && pEthFrame && pFddiFrame && pTokenRingFrame && m_pMemBlock && m_hServices.IsOK (); } //--------------------------------------------------------------------------- BOOL CMaaDriver::LoadConfig () { BOOL Ret = FALSE; DWORD cbData = 100 * 1024; //INT3; #ifdef _WIN9x HKEY hk = NULL; _RegOpenKey ( HKEY_LOCAL_MACHINE, "Software\\Moisseyenko A.A.\\MaaRF", &hk ); if ( hk ) { _byte * Buffer = new _byte [ cbData ]; if ( Buffer ) { DWORD dwType = REG_BINARY; if ( ERROR_SUCCESS == _RegQueryValueEx ( hk, "Config", NULL, &dwType, ( LPBYTE ) Buffer, &cbData ) ) { m_pNew->SetConfig ( Buffer, ( int ) cbData ); if ( !m_pNew->m_fError ) { for ( CAdapterCfg * a = m_pNew->m_AdapterList.LookAtFront (); a; a = m_pNew->m_AdapterList.Next ( a ) ) { //a->m_Info.m_State |= 0x80000000; } if ( !ApplyNewConfig () ) { Ret = TRUE; } } } delete [] Buffer; } _RegCloseKey ( hk ); } #endif return Ret; } //---------------------------------------------------------------------------- void CMaaDriver::AddOptJournalDataLocked(int JournalId, int Id, _IP UserIp, int In, int Out, bool bNoSwap) { if (JournalId <= 0) { return; } sOptJournalKey k; k.JournalId = JournalId; k.Id = Id; k.UserIp = Id != -1 ? UserIp : 0; sOptJournalData d; d.In = d.Out = 0; //gLock.Lock(); m_hOptJournals.Find(k, &d); if (bNoSwap) { d.In += (unsigned int)In; d.Out += (unsigned int)Out; } else { d.In += (unsigned int)Out; d.Out += (unsigned int)In; } m_hOptJournals.AddOver(k, d); //gLock.UnLock(); } //--------------------------------------------------------------------------- int CMaaDriver::GetOptIdByIpActivity(_IP Ip) { int Id = -1; m_hOptIpIdHash.Find(Ip, &Id); return Id; } //--------------------------------------------------------------------------- void CMaaDriver::OnValidAdapterAppeared(CMaaService * pAdapter) { // //INT3; //for ( CAdapterCfg * a = m_pCurr->m_AdapterList.LookAtFront (); a; a = m_pCurr->m_AdapterList.Next ( a ) ) { // } // SetEvent (); m_AdapterListChangedEvent.SetUserEvent(); } //--------------------------------------------------------------------------- void CMaaDriver::OnSetConnectedEvent() { m_ConnectedEvent.SetUserEvent(); } //--------------------------------------------------------------------------- void CMaaDriver::OnAdapterClosed() { m_AdapterListChangedEvent.SetUserEvent(); } //--------------------------------------------------------------------------- void * gIO0 = "gIO0"; void * gIO = "gIO"; //--------------------------------------------------------------------------- int CMaaDriver::IOControl ( int Service, _byte * pBufferIn, int SizeIn, _byte * pBufferOut, int SizeOut, int * SizeOutRet ) { int Ret = ERROR_NOT_SUPPORTED; pfMaaRFService pService; if ( !m_hServices.Find ( Service, &pService ) ) { Lock (); //__asm int 1; gIO0 = gIO; //gIO = Ret = (*this.*pService)( Service, pBufferIn, SizeIn, pBufferOut, SizeOut, SizeOutRet ); gIO = "Ret"; UnLock (); } return Ret; } //--------------------------------------------------------------------------- int CMaaDriver::Srv_GetVersion ( int Service, _byte * pBufferIn, int SizeIn, _byte * pBufferOut, int SizeOut, int * SizeOutRet ) { gIO = "Srv_GetVersion"; if ( SizeOut >= sizeof ( int ) ) { #ifdef _DEBUG #define MAARF_MAKE_VERSION_NUMBER(high,low,build) ( ( high * 100 + low ) * 0x10000 + build + 0x80000000 ) #else #define MAARF_MAKE_VERSION_NUMBER(high,low,build) ( ( high * 100 + low ) * 0x10000 + build ) #endif * ( int * ) pBufferOut = ( int ) MAARF_MAKE_VERSION_NUMBER( 2, 0, 53 ); * SizeOutRet = sizeof ( int ); return 0; } return ERROR_INVALID_PARAMETER; } //--------------------------------------------------------------------------- int CMaaDriver::Srv_GetAdapterList ( int Service, _byte * pBufferIn, int SizeIn, _byte * pBufferOut, int SizeOut, int * SizeOutRet ) { gIO = "Srv_GetAdapterList"; int col = m_hAdapterName2AdapterNumber.EnumerateItems ( SizeOut / sizeof ( int ), NULL, ( int * ) pBufferOut ); if ( col >= 0 ) { *SizeOutRet = col * sizeof ( int ); return 0; } return ERROR_INVALID_PARAMETER; } //--------------------------------------------------------------------------- int CMaaDriver::Srv_GetWanUpLinks(int Service, _byte * pBufferIn, int SizeIn, _byte * pBufferOut, int SizeOut, int * SizeOutRet) { gIO = "Srv_GetWanUpLinks"; if ( SizeIn >= sizeof ( int ) && SizeOut >= sizeof ( RR_NDIS_WAN_LINE_UP_LINK ) ) { int Num = *(int *)pBufferIn; RR_NDIS_WAN_LINE_UP_LINK * l = (RR_NDIS_WAN_LINE_UP_LINK *)pBufferOut; int r = 0; //*SizeOutRet = r; CMaaAdapterInfo * a; if ( m_hAdapterNumber2AdapterInfo.Find ( Num, &a ) ) { // error //p.m_Number = (HANDLE)-1; } else { for (CMaaWanUps * u = a->m_WanUps.LookAtFront(); u && r + (int)sizeof(RR_NDIS_WAN_LINE_UP_LINK) <= SizeOut; u = a->m_WanUps.Next(u)) { memset(l, 0, sizeof(*l)); l->LinkSpeed = u->m_WanUp.LinkSpeed; l->MaximumTotalSize = u->m_WanUp.MaximumTotalSize; l->Quality = u->m_WanUp.Quality; l->SendWindow = u->m_WanUp.SendWindow; memcpy(l->RemoteAddress, u->m_WanUp.RemoteAddress, 6); memcpy(l->LocalAddress, u->m_WanUp.LocalAddress, 6); l->ProtocolType = u->m_WanUp.ProtocolType; l->m_BufferLength = u->m_BufferLength; memcpy(l->m_Buffer, u->m_Buffer, sizeof(u->m_Buffer)); r += sizeof(RR_NDIS_WAN_LINE_UP_LINK); l++; } } *SizeOutRet = r; return 0; } return ERROR_INVALID_PARAMETER; } //--------------------------------------------------------------------------- int CMaaDriver::Srv_GetAdapterInfo ( int Service, _byte * pBufferIn, int SizeIn, _byte * pBufferOut, int SizeOut, int * SizeOutRet ) { gIO = "Srv_GetAdapterInfo"; if ( SizeIn >= sizeof ( int ) && SizeOut >= sizeof ( CRusRoute_AdapterInfo ) ) { int Num = * ( int * ) pBufferIn; CRusRoute_AdapterInfo & p = * ( CRusRoute_AdapterInfo * ) pBufferOut; Memzero ( &p, sizeof ( p ) ); CMaaAdapterInfo * a; if ( m_hAdapterNumber2AdapterInfo.Find ( Num, &a ) ) { // error p.m_Number = (DWORD)-1; } else { p.m_Number = (DWORD)a->m_Number; p.m_SelectedMedium = a->m_SelectedMedium; p.m_State = a->m_State; p.m_Mac = a->m_Mac; p.m_PermanentMac = a->m_PermanentMac; p.m_DataGetMaxFrameSize = a->m_DataGetMaxFrameSize; p.m_IsWanLineUp = a->m_IsWanLineUp; p.m_IsMediaConnected = a->m_IsMediaConnected; p.m_LinkSpeed = a->m_LinkSpeed; p.m_WanUp.LinkSpeed = a->m_WanUp.LinkSpeed; p.m_WanUp.MaximumTotalSize = a->m_WanUp.MaximumTotalSize; p.m_WanUp.Quality = a->m_WanUp.Quality; p.m_WanUp.SendWindow = a->m_WanUp.SendWindow; memcpy(p.m_WanUp.RemoteAddress, a->m_WanUp.RemoteAddress, sizeof(p.m_WanUp.RemoteAddress)); memcpy(p.m_WanUp.LocalAddress, a->m_WanUp.LocalAddress, sizeof(p.m_WanUp.LocalAddress)); p.m_WanUp.ProtocolType = a->m_WanUp.ProtocolType; memcpy(p.m_WanDown.RemoteAddress, a->m_WanDown.RemoteAddress, sizeof(p.m_WanDown.RemoteAddress)); memcpy(p.m_WanDown.LocalAddress, a->m_WanDown.LocalAddress, sizeof(p.m_WanDown.LocalAddress)); //p.m_Ip1 = a->m_Ip1; //p.m_Ip2 = a->m_Ip2; //p.m_Mask = a->m_Mask; SimpleString * pName = &a->m_AdapterName; #ifdef _WINNT if ( 0 && a->m_UserFriendlyAdapterName.GetSize () ) { pName = &a->m_UserFriendlyAdapterName; } #endif int l = pName->GetSize () / sizeof ( MY_TCHAR ); l *= sizeof ( MY_TCHAR ); if ( l >= sizeof ( p.m_Name ) ) { l = sizeof ( p.m_Name ) / sizeof ( MY_TCHAR ) - 1; l *= sizeof ( MY_TCHAR ); } MY_TCHAR * pOutName = ( MY_TCHAR * ) p.m_Name; l /= sizeof(MY_TCHAR); for ( int i = 0; i <= l; i++ ) { *pOutName++ = ( * pName ) [ i ]; } *pOutName = 0; } *SizeOutRet = sizeof ( CRusRoute_AdapterInfo ); return 0; } return ERROR_INVALID_PARAMETER; } //--------------------------------------------------------------------------- int CMaaDriver::Srv_GetPacket ( int Service, _byte * pBufferIn, int SizeIn, _byte * pBufferOut, int SizeOut, int * SizeOutRet ) { gIO = "Srv_GetPacket"; PrintDbg("Srv_GetPacket()"); if ( SizeIn >= sizeof ( int ) && SizeOut >= sizeof ( CRusRoute_Packet0 ) ) { static char * pLastLogBuffer = NULL; static int LastLogBufferSize = 0; //__asm int 3; pLastLogBuffer = m_LastLog.GetBuffer(&LastLogBufferSize); CRusRoute_Packet0 & p = * ( CRusRoute_Packet0 * ) pBufferOut; //Memzero ( &p, sizeof ( p ) ); int Num = * (int *) pBufferIn; if (Num == -1) { UnLock(); CDrvPacket * m = GetInterceptedPacket(); if (m) { CMaaService * pServ = m->m_pService; Num = m->m_pService->m_Info.m_Number; PrintDbg("Got ad=%d m=%p", Num, m ); p.m_AdapterNumber = (DWORD)Num; p.m_Status = m->m_Status; p.m_Flags = NdisGetPacketFlags(m->m_pPacket); p.m_Length = m->m_Length; int x = m->m_Length <= RUSROUTE_MAX_FRAME_SIZE ? m->m_Length : RUSROUTE_MAX_FRAME_SIZE; memcpy(p.m_Buffer, m->m_pHeader, x); m->m_pService->ReturnInterceptedPacket(m); int * xx = (int *)p.m_Buffer; /* Lock(); xx[0] = (int)pServ; xx[1] = pServ->m_InterceptedPackets.GetCount(); xx[2] = pServ->m_FreeList.GetCount(); UnLock(); pServ->aLock(); xx[3] = pServ->m_RecvQueue.GetCount(); pServ->aUnLock(); xx[4] = xx[1] + xx[2] + xx[3]; x = x > 4 * sizeof(*xx) ? x : 4 * sizeof(*xx); */ *SizeOutRet = sizeof ( CRusRoute_Packet0 ) - RUSROUTE_MAX_FRAME_SIZE + x; } else { *SizeOutRet = 0; } Lock(); } else { CMaaAdapterInfo * a; if (!m_hAdapterNumber2AdapterInfo.Find(Num, &a)) { a->Touch(); UnLock(); CDrvPacket * m = a->m_pBind->GetInterceptedPacket(); if (m) { PrintDbg("Got ad=%d m=%p", Num, m); p.m_AdapterNumber = (DWORD)Num; p.m_Status = m->m_Status; p.m_Flags = NdisGetPacketFlags(m->m_pPacket); p.m_Length = m->m_Length; int x = m->m_Length <= RUSROUTE_MAX_FRAME_SIZE ? m->m_Length : RUSROUTE_MAX_FRAME_SIZE; memcpy(p.m_Buffer, m->m_pHeader, x); a->m_pBind->ReturnInterceptedPacket(m); *SizeOutRet = sizeof ( CRusRoute_Packet0 ) - RUSROUTE_MAX_FRAME_SIZE + x; } else { *SizeOutRet = 0; } Lock(); a->UnTouch(); } else { return ERROR_INVALID_PARAMETER; } } return 0; } return ERROR_INVALID_PARAMETER; } //--------------------------------------------------------------------------- int CMaaDriver::Srv_PutPacket ( int Service, _byte * pBufferIn, int SizeIn, _byte * pBufferOut, int SizeOut, int * SizeOutRet ) { gIO = "Srv_PutPacket"; PrintDbg("Srv_PutPacket()" ); if ( SizeIn >= sizeof ( CRusRoute_Packet0 ) - RUSROUTE_MAX_FRAME_SIZE && SizeOut >= sizeof ( int ) ) { CRusRoute_Packet0 & p = * ( CRusRoute_Packet0 * ) pBufferIn; //Memzero ( &p, sizeof ( p ) ); int Num = (int)p.m_AdapterNumber; CMaaAdapterInfo * a; if ( p.m_Length > RUSROUTE_MAX_FRAME_SIZE || (DWORD) SizeIn < sizeof ( CRusRoute_Packet0 ) - RUSROUTE_MAX_FRAME_SIZE + p.m_Length || m_hAdapterNumber2AdapterInfo.Find ( Num, &a ) ) { PrintDbg("Invalid ad=%d or pkt len", Num ); *(int *)pBufferOut = -1; } else { a->Touch(); UnLock(); if (p.m_Status & DRV_RECEIVE) { gIO = "Srv_PutPacket - Indicate Receive"; } else { gIO = "Srv_PutPacket - Send"; } // Send or indicate receive a->m_pBind->PutPacket(p); *(int *)pBufferOut = Num; Lock(); a->UnTouch(); } * SizeOutRet = sizeof ( int ); return 0; } return ERROR_INVALID_PARAMETER; } //--------------------------------------------------------------------------- int CMaaDriver::Srv_SetEventHandle ( int Service, _byte * pBufferIn, int SizeIn, _byte * pBufferOut, int SizeOut, int * SizeOutRet ) { gIO = "Srv_SetEventHandle"; // in: struct CRusRoute_SetEventHandle // out: int: 1 - success, 0 - failed if (SizeIn >= sizeof(CRusRoute_SetEventHandle) && SizeOut >= sizeof(int)) { CRusRoute_SetEventHandle &s = * (CRusRoute_SetEventHandle *)pBufferIn; int Ret = 0; if (s.m_Type == 0 || s.m_AdapterNumber == -1) { switch(s.m_Type) { case 0: SetupAdapterListChangedEvent(s.m_Event); Ret = 1; break; case 1: SetupPacketInterceptedEvent(s.m_Event); Ret = 1; break; case 2: SetupConnectedEvent(s.m_Event); Ret = 1; break; } } else { int Num = s.m_AdapterNumber; CMaaAdapterInfo * a; if (!m_hAdapterNumber2AdapterInfo.Find(Num, &a) && a->m_pBind) { switch(s.m_Type) { case 0: //SetupAdapterListChangedEvent(s.m_Event); //Ret = 1; break; case 1: a->m_pBind->SetupPacketInterceptedEvent(s.m_Event); Ret = 1; break; case 2: a->m_pBind->SetupConnectedEvent(s.m_Event); Ret = 1; break; } } } * ( int * ) pBufferOut = Ret; * SizeOutRet = sizeof(Ret); return 0; } return ERROR_INVALID_PARAMETER; } //--------------------------------------------------------------------------- void CMaaDriver::RemoveTcpOpt(CTcpOptimization * o) { //CTcpOptHashData dd; //CTcpHashData dd; //dd.p = this; CTcpOptimization &m_Opt = *o; //dd.b = 1; int Ret = m_hTcpSRedirs2.Remove(m_Opt.s.k1); //dd.b = 0; if (m_Opt.m_Flags & CTcpOptimization::eSRedir0) { Ret |= m_hTcpSRedirs2.Remove(m_Opt.s.k0); } else { Ret |= m_hTcpRRedirs2.Remove(m_Opt.s.k0); } //dd.b = 2; Ret |= m_hTcpSRedirs2.Remove(m_Opt.d.k0); //dd.b = 3; if (m_Opt.m_Flags & CTcpOptimization::eSRedir3) { Ret |= m_hTcpSRedirs2.Remove(m_Opt.d.k1); } else { Ret |= m_hTcpRRedirs2.Remove(m_Opt.d.k1); } //m_Opt.m_bOptimizationPerformed = false; m_TcpOptsList.Release(o); delete o; } //--------------------------------------------------------------------------- void CMaaDriver::AddTcpOpt(CTcpOptimization * o) { CTcpOptHashData dd; //CTcpHashData dd; dd.p = o; CTcpOptimization &m_Opt = *o; dd.b = 1; int Ret = m_hTcpSRedirs2.AddOver(m_Opt.s.k1, dd); dd.b = 0; if (m_Opt.m_Flags & CTcpOptimization::eSRedir0) { Ret |= m_hTcpSRedirs2.AddOver(m_Opt.s.k0, dd); } else { Ret |= m_hTcpRRedirs2.AddOver(m_Opt.s.k0, dd); } dd.b = 2; Ret |= m_hTcpSRedirs2.AddOver(m_Opt.d.k0, dd); dd.b = 3; if (m_Opt.m_Flags & CTcpOptimization::eSRedir3) { Ret |= m_hTcpSRedirs2.AddOver(m_Opt.d.k1, dd); } else { Ret |= m_hTcpRRedirs2.AddOver(m_Opt.d.k1, dd); } m_TcpOptsList.AddAtBack(o); //m_Opt.m_bOptimizationPerformed = true; } //--------------------------------------------------------------------------- int CMaaDriver::Srv_TcpOptimize(int Service, _byte * pBufferIn, int SizeIn, _byte * pBufferOut, int SizeOut, int * SizeOutRet) { gIO = "Srv_TcpOptimize"; if (SizeIn >= sizeof(int) + sizeof(CTcpOptimization) && SizeOut >= sizeof(int)) { int SubFn = *(int*)pBufferIn; if (SubFn == -1) { // Cleanup CTcpOptimization * o; while((o = m_TcpOptsList.LookAtFront())) { RemoveTcpOpt(o); } m_hOptIpIdHash.Cleanup(1024); m_hOptJournals.Cleanup(); int Ret = 0; *(int *)pBufferOut = Ret; *SizeOutRet = sizeof(Ret); return 0; } else if (SubFn == 0 || SubFn == +1) { int Ret = 0; CTcpOptimization * o = (CTcpOptimization *)(pBufferIn + sizeof(int)); CTcpOptHashData dd; if (!m_hTcpSRedirs2.Find(o->s.k1, &dd)) { RemoveTcpOpt(dd.p); } else if (SubFn == 0) { Ret = -1; } if (SubFn == +1) { dd.p = new CTcpOptimization; if (!dd.p) { Ret = -1; } else { memcpy(dd.p, o, sizeof(*o)); AddTcpOpt(dd.p); } } *(int *)pBufferOut = Ret; *SizeOutRet = sizeof(Ret); return 0; } } return ERROR_INVALID_PARAMETER; } //--------------------------------------------------------------------------- int CMaaDriver::Srv_LoginLogout(int Service, _byte * pBufferIn, int SizeIn, _byte * pBufferOut, int SizeOut, int * SizeOutRet) { gIO = "Srv_LoginLogout"; if (SizeIn >= sizeof(_IP) + sizeof(int) && SizeOut >= sizeof(int)) { _IP Ip = *(_IP *)pBufferIn; int Id = *(int*)(pBufferIn + sizeof(_IP)); if (Id == -1) { m_hOptIpIdHash.Remove(Ip); } else { m_hOptIpIdHash.AddOver(Ip, Id); } int Ret = 0; *(int *)pBufferOut = Ret; *SizeOutRet = sizeof(Ret); return 0; } return ERROR_INVALID_PARAMETER; } //--------------------------------------------------------------------------- struct sOptEnum { sOptJournalRec * p; int m, t; }; void GetOptJRProc(sOptJournalKey &k, sOptJournalData &d, CMaaUnivHash &ht, void * Param) { sOptEnum &e = *(sOptEnum *)Param; if (e.t >= e.m) { e.t++; return; } e.p->k = k; e.p->d = d; e.p++; e.t++; ht.Remove(k); } //---------------------------------------------------------------------------- int CMaaDriver::Srv_GetJournalRecs(int Service, _byte * pBufferIn, int SizeIn, _byte * pBufferOut, int SizeOut, int * SizeOutRet) { gIO = "Srv_GetJournalRecs"; if (/*SizeIn >= sizeof(int) &&*/ SizeOut >= sizeof(sOptJournalRecs)) { //int m = *(int *)pBufferIn; sOptJournalRecs &r = *(sOptJournalRecs *)pBufferOut; sOptEnum e; e.p = r.p; e.m = sizeof(r.p) / sizeof(r.p[0]); e.t = r.t = 0; m_hOptJournals.EnumerateByProc(&GetOptJRProc, &e); r.t = e.t <= e.m ? e.t : e.m; *SizeOutRet = sizeof(sOptJournalRecs); return 0; } return ERROR_INVALID_PARAMETER; } //--------------------------------------------------------------------------- int CMaaDriver::Srv_GetLog(int Service, _byte * pBufferIn, int SizeIn, _byte * pBufferOut, int SizeOut, int * SizeOutRet) { gIO = "Srv_GetLog"; if (SizeIn >= sizeof(int) && SizeOut >= 1) { int l = *(int *)pBufferIn; if (l == 1) { *SizeOutRet = m_FirstLog.Get((char *)pBufferOut, SizeOut); } else { *SizeOutRet = m_LastLog.Get((char *)pBufferOut, SizeOut); } return 0; } return ERROR_INVALID_PARAMETER; } //--------------------------------------------------------------------------- int CMaaDriver::Srv_GetTcpOptStr(int Service, _byte * pBufferIn, int SizeIn, _byte * pBufferOut, int SizeOut, int * SizeOutRet) { gIO = "Srv_GetTcpOptStr"; if (SizeIn >= sizeof(CTcpOptimization) && SizeOut >= sizeof(CTcpOptimization)) { CTcpOptimization * o = (CTcpOptimization *)(pBufferIn); CTcpOptHashData dd; if (!m_hTcpSRedirs2.Find(o->s.k1, &dd)) { CTcpOptimization * o = (CTcpOptimization *)(pBufferOut); memcpy(o, dd.p, sizeof(*o)); *SizeOutRet = sizeof(*o); } else { *SizeOutRet = 0; } return 0; } return ERROR_INVALID_PARAMETER; } //--------------------------------------------------------------------------- /* int CMaaDriver::Srv_GetJournalInfo ( int Service, _byte * pBufferIn, int SizeIn, _byte * pBufferOut, int SizeOut, int * SizeOutRet ) { if ( SizeIn >= sizeof ( int ) && SizeOut >= 4 * sizeof ( DWORD ) ) { * SizeOutRet = 0; return 0; } return ERROR_INVALID_PARAMETER; } */ //--------------------------------------------------------------------------- int CMaaDriver::Srv_Test1 ( int Service, _byte * pBufferIn, int SizeIn, _byte * pBufferOut, int SizeOut, int * SizeOutRet ) { /* //INT3; if ( SizeIn >= sizeof ( HANDLE ) ) { *SizeOutRet = 0; //SetupUserEvent(*(HANDLE *)pBufferIn, &gUserEvent); return 0; } return ERROR_INVALID_PARAMETER; */ *SizeOutRet = 0; /* m_Mutex.Lock(); m_Mutex.UnLock(); */ return 0; } //--------------------------------------------------------------------------- int CMaaDriver::Srv_Test2 ( int Service, _byte * pBufferIn, int SizeIn, _byte * pBufferOut, int SizeOut, int * SizeOutRet ) { //INT3; *SizeOutRet = 0; //SetUserEvent(gUserEvent); /* m_Mutex.Lock(); m_Mutex.Lock(); m_Mutex.UnLock(); m_Mutex.UnLock(); */ return 0; } //--------------------------------------------------------------------------- DWORD CMaaDriver::VIP_Set_Address ( WORD Something, DWORD Address, DWORD Mask ) { /* if ( m_er.m_Event && !m_er.m_fDisabled ) { m_er.m_fDisabled = 1; Maa_SetWin32EventEx ( &m_er ); } */ return 0; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void CMaaDriver::Log(const char * txt) { m_PrintDbgLock.Lock(); static char Num[6] = {'0', '0', '0', '0', ' ', 0}; for (int i = 3; i >= 0; i--) { if (Num[i] == '9') { Num[i] = '0'; } else { Num[i]++; break; } } m_FirstLog.Put(Num); m_FirstLog.Put(txt); m_LastLog.Put(Num); m_LastLog.Put(txt); m_PrintDbgLock.UnLock(); } //---------------------------------------------------------------------------- //--------------------------------------------------------------------------- CDrvPacket * CMaaDriver::GetInterceptedPacket() { Lock(); // context is locked CDrvPacket::CDrvPacketPtr * ptr = m_InterceptedPacketsList.GetFromFront(); if (ptr) { CDrvPacket *p = ptr->m_pDrvPacket; CMaaDList::Release(p); UnLock(); return p; } UnLock(); return NULL; } //--------------------------------------------------------------------------- void CMaaDriver::SetupAdapterListChangedEvent(HANDLE h) { m_AdapterListChangedEvent.SetupUserEvent(h); } //--------------------------------------------------------------------------- void CMaaDriver::SetupPacketInterceptedEvent(HANDLE h) { m_PacketInterceptedEvent.SetupUserEvent(h); } //--------------------------------------------------------------------------- void CMaaDriver::SetupConnectedEvent(HANDLE h) { m_ConnectedEvent.SetupUserEvent(h); } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- CMaaTimeService::CMaaTimeService () { #ifdef _WIN9x m_SystemTimeAddress = Get_System_Time_Address (); #endif } //--------------------------------------------------------------------------- _dword CMaaTimeService::GetTimeMs () { #ifdef _WIN9x return * m_SystemTimeAddress; #endif #ifdef _WINNT __int64 Time1, Divider, TimeMs; KeQuerySystemTime ( ( PLARGE_INTEGER ) &Time1 ); //TIME_FIELDS BaseTime = { 1980, 1, 1, 0, 0, 0, 0, 0 }; //RtlTimeFieldsToTime ( &BaseTime, &Time2 ); Divider = ( __int64 ) 10000L; TimeMs = Time1 / Divider; return ( _dword ) TimeMs; #endif } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- CDrvLock::CDrvLock(bool bLog) { m_bLog = bLog; #ifndef __unix__ _NdisAllocateSpinLock ( & m_Lock ); #ifdef _WINNT m_Irql = (KIRQL)-1; #endif #else m_IsLocked = false; #endif } //--------------------------------------------------------------------------- CDrvLock::~CDrvLock () { #ifndef __unix__ _NdisFreeSpinLock ( & m_Lock ); #else // do nothing... #endif } //--------------------------------------------------------------------------- void CDrvLock::Lock2(const char * f, int l) { if ( this ) { #ifndef DRV_SUPRESS_LOCK_OUT if (m_bLog) { PrintDbg("CDrvLock::Lock(), this = %p, locking...", this); } #endif #ifndef __unix__ #ifdef _WINNT KIRQL Irql = KeGetCurrentIrql (); #endif _NdisAcquireSpinLock ( & m_Lock ); #ifndef DRV_SUPRESS_LOCK_OUT if (m_bLog) { PrintDbg("CDrvLock::Lock(), this = %p, locked", this); } #endif #ifdef _WINNT if (m_Irql != (KIRQL)-1) { INT3; } m_Irql = Irql; #endif #else if ( ! m_IsLocked ) { LockInt ( & m_Flags ); m_IsLocked = true; } #endif } v.AfterLock(f, l); } //--------------------------------------------------------------------------- void CDrvLock::UnLock2(const char * f, int l) { if ( this ) { v.BeforeUnLock(f, l); #ifndef __unix__ #ifdef _WINNT KIRQL Old = m_Irql; if (Old == (KIRQL)-1) { INT3; } m_Irql = (KIRQL)-1; #endif #ifndef DRV_SUPRESS_LOCK_OUT if (m_bLog) { PrintDbg("CDrvLock::Lock(), this = %p, unlocking...", this); } #endif _NdisReleaseSpinLock ( & m_Lock ); #ifdef _WINNT #ifndef DRV_SUPRESS_LOCK_OUT if (m_bLog) { PrintDbg("CDrvLock::Lock(), this = %p, unlocked", this); } #endif KIRQL Irql = KeGetCurrentIrql (); /* if (Old != Irql) { if (Old < Irql) { KeLowerIrql(Old); } else { KfRaiseIrql(Old); } } */ #endif #else if ( m_IsLocked ) { m_IsLocked = false; UnLockInt ( & m_Flags ); } #endif } } //--------------------------------------------------------------------------- MyUserEvent::MyUserEvent() { #ifdef _WINNT for (int i = 0; i < 32; i++) { m_kEvent[i] = NULL; } #endif } //--------------------------------------------------------------------------- MyUserEvent::~MyUserEvent() { SetupUserEvent(NULL); } //--------------------------------------------------------------------------- void MyUserEvent::SetupUserEvent(HANDLE h) { #ifdef _WINNT KIRQL Orig = KeGetCurrentIrql(); if (Orig > PASSIVE_LEVEL) { KeLowerIrql(PASSIVE_LEVEL); } for (int i = 0; i < 32; i++) { void * p = NULL, * old; NTSTATUS Status = STATUS_INVALID_HANDLE; if (h) { Status = ObReferenceObjectByHandle(h, SYNCHRONIZE, *ExEventObjectType, UserMode, &p, NULL); } old = m_kEvent[i]; m_kEvent[i] = (KEVENT *) p; if (old) { ObDereferenceObject(old); } } if (Orig > PASSIVE_LEVEL) { KfRaiseIrql(Orig); } #endif } //--------------------------------------------------------------------------- LONG MyUserEvent::SetUserEvent() { #ifdef _WINNT ULONG Proc = KeGetCurrentProcessorNumber(); if (Proc < 32 && m_kEvent[Proc]) { return KeSetEvent(m_kEvent[Proc], 1, FALSE); } #endif return -1; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- /* MyMutex::MyMutex() { m_RecN = 0; for (int i = 0; i < 100; i++) { m_Levels[i] = -1; } KeInitializeMutex(&m_Mutex, 0); //Level } MyMutex::~MyMutex() { // //ObDereferenceObject(&m_Mutex); } void MyMutex::Lock() { KIRQL Orig = KeGetCurrentIrql(); if (Orig > PASSIVE_LEVEL) { KeLowerIrql(PASSIVE_LEVEL); } KeWaitForMutexObject(&m_Mutex, Executive, KernelMode, FALSE, NULL); int n = m_RecN++; if (n < 100) { m_Levels[n] = Orig; } //if (Orig > PASSIVE_LEVEL) //{ // KfRaiseIrql(Orig); //} } void MyMutex::UnLock() { KIRQL L; if (--m_RecN < 100) { L = m_Levels[m_RecN]; m_Levels[m_RecN] = -1; } else { L = -1; } KeReleaseMutex(&m_Mutex, FALSE); if (L != (KIRQL)-1) { KIRQL Orig = KeGetCurrentIrql(); if (Orig > L) { KeLowerIrql(L); } else if (Orig < L) { KfRaiseIrql(L); } } } */ //--------------------------------------------------------------------------- CTextLog::CTextLog(bool bFirst, int Size) { m_bFirst = bFirst; m_Buf = new char[m_Size = Size]; if (!m_Buf) { m_Size = 0; } m_Start = m_Len = 0; } CTextLog::~CTextLog() { delete [] m_Buf; } bool CTextLog::IsOK() { return m_Buf != 0; } void CTextLog::Put(const char * msg) { if (!m_Size) { return; } int Len = (int)strlen(msg); if (m_bFirst) { if (m_Size - m_Len < Len) { Len = m_Size - m_Len; } memcpy(m_Buf + /*m_Start +*/ m_Len, msg, Len); m_Len += Len; return; } if (Len > m_Size) { msg += Len - m_Size; Len = m_Size; } int be = m_Size - (m_Start + m_Len) % m_Size; if (be > Len) { memcpy(m_Buf + (m_Start + m_Len) % m_Size, msg, Len); } else { memcpy(m_Buf + (m_Start + m_Len) % m_Size, msg, be); memcpy(m_Buf, msg + be, Len - be); } m_Len += Len; if (m_Len > m_Size) { m_Start += m_Len - m_Size; m_Start %= m_Size; m_Len = m_Size; } } int CTextLog::Get(char * Buf, int MaxBufSize) { if (MaxBufSize < 1) { return 0; } int Len = m_Len < MaxBufSize - 1 ? m_Len : MaxBufSize - 1; int Start = m_bFirst ? m_Start : m_Start + m_Len - Len; if (Start + Len > m_Size) { int l = m_Size - Start; memcpy(Buf, m_Buf + Start, l); memcpy(Buf + l, m_Buf, Len - l); } else { memcpy(Buf, m_Buf + Start, Len); } Buf[Len] = 0; return Len + 1; } char * gxx; void Lock2(const char * f, int l) { gxx = "NdisAcquireSpinLock(&GlobalLock);"; #ifndef DRV_SUPRESS_LOCK_OUT PrintDbg("gLock()..."); #endif NdisAcquireSpinLock(&GlobalLock); if (pdo) { pdo->m_GLockV.AfterLock(f, l); } #ifndef DRV_SUPRESS_LOCK_OUT PrintDbg("gLock() - locked"); #endif } void UnLock2(const char * f, int l) { gxx = "NdisReleaseSpinLock(&GlobalLock);"; #ifndef DRV_SUPRESS_LOCK_OUT PrintDbg("gLock() - unlock..."); #endif if (pdo) { pdo->m_GLockV.BeforeUnLock(f, l); } NdisReleaseSpinLock(&GlobalLock); #ifndef DRV_SUPRESS_LOCK_OUT PrintDbg("gLock() - unlocked"); #endif } // hooks.cpp //--------------------------------------------------------------------------- // class CMaaAdapterInfo //--------------------------------------------------------------------------- CMaaAdapterInfo::CMaaAdapterInfo(PADAPT pAdapt) { char tmp[sizeof(m_WanUps)]; memcpy(&tmp, &m_WanUps, sizeof(m_WanUps)); Memzero ( this, sizeof ( *this ) ); // !!!!!!!! memcpy(&m_WanUps, &tmp, sizeof(m_WanUps)); //m_pProtocol = NULL; //m_pBind = NULL; m_pAdapt = pAdapt; m_State = eNotInit; m_bStatusClosing = false; m_PacketsProcessing = 0; m_GeneralStatus = NDIS_STATUS_SUCCESS; m_IsWanLineUp = m_IsMediaConnected = -1; //m_SendPacketsDropped = m_RecvPacketsDropped = 0; //m_WanUps.Init(); } CMaaAdapterInfo::~CMaaAdapterInfo () { //delete [] m_AdapterName.Buffer; { CMaaWanUps * p; while((p = m_WanUps.GetFromFront())) { delete p; } } } int CMaaAdapterInfo::OpenAdapterSucceded()//void * sb, int nsb, void * rb, int nrb) { /* m_Sb = NULL; { for (int i = nsb; --i >= 0; ) { void * p = 2048 * i + (char *)sb; *(void **)p = m_Sb; m_Sb = p; } } m_Rb = NULL; { for (int i = nrb; --i >= 0; ) { void * p = 2048 * i + (char *)rb; *(void **)p = m_Rb; m_Rb = p; } } */ // Context is locked //INT3; //!!! m_SelectedMedium = ....... // m_SelectedMedium = m_pInternalMediumArray [ * m_pInternalSelectedMediumIndex ]; // m_NdisBindingHandle = *m_pInternalNdisBindingHandle; if ( pdo->m_hAdapterName2AdapterNumber.Find ( m_AdapterName, &m_Number ) ) { m_Number = pdo->m_AdapterLastNumber; do { m_Number++; if (m_Number >= 0x1000) { m_Number = 1; } } while (!pdo->m_hAdapterNumber2AdapterInfo.Find(m_Number)); // Name can be added incorrectly while memory allocation error(s) pdo->m_hAdapterName2AdapterNumber.Add ( m_AdapterName, m_Number ); } // PrintDbg ( "m_NdisBindingHandle=%x", m_NdisBindingHandle ); // PNDIS_OPEN_BLOCK pBlock = ( PNDIS_OPEN_BLOCK ) m_NdisBindingHandle; // NdisMoveMemory ( & m_Block, pBlock, sizeof ( NDIS_OPEN_BLOCK ) ); /* #ifdef METHOD2 m_MyBindingHandle = &m_MyBlock; PrintDbg ( "METHOD2: m_MyBindingHandle = %x", m_MyBindingHandle ); NdisMoveMemory(&m_MyBlock, pBlock, sizeof(NDIS_OPEN_BLOCK)); m_MyBlock.NdisCommonOpenBlock.BindingHandle = m_MyBindingHandle; Memzero(m_ReservedData, sizeof ( m_ReservedData )); *m_pInternalNdisBindingHandle = m_MyBindingHandle; #endif */ //*m_pInternalNdisBindingHandle = ( NDIS_HANDLE ) & pBind -> m_Block; // m_BindingHandle = pBlock->NdisCommonOpenBlock.BindingHandle; // PrintDbg ( " m_BindingHandle=%x", m_BindingHandle ); // PrintDbg ( " MacHandle=%x", pBlock->NdisCommonOpenBlock.MacHandle ); //win98--> if ( !pdo->m_hBindingHandle2AdapterInfo.Add ( m_NdisBindingHandle, this ) ) //winxp | // \|/ /* if ( pdo->m_hBindingHandle2AdapterInfo.Add ( m_BindingHandle, this ) ) { return -1; } if ( pdo->m_hNdisBindingHandle2AdapterInfo.Add ( m_NdisBindingHandle, this ) ) { pdo->m_hBindingHandle2AdapterInfo.Remove ( m_BindingHandle ); return -1; } #ifdef METHOD2 if ( pdo->m_hMyBindingHandle2AdapterInfo.Add ( m_MyBindingHandle, this ) ) { pdo->m_hNdisBindingHandle2AdapterInfo.Remove ( m_NdisBindingHandle ); pdo->m_hBindingHandle2AdapterInfo.Remove ( m_BindingHandle ); return -1; } #endif m_pProtocol->m_AdapterList.AddAtBack ( this ); */ int tmp = pdo->m_hAdapterNumber2AdapterInfo.Add(m_Number, this); m_pBind = new CMaaAdapter(this); // user supplied class if (m_pBind && m_pBind->IsOK() && !tmp) { PrintDbg("Adapter [%s] medium=%d", m_AdapterName.const_char_ptr(), (int)m_SelectedMedium); /* #ifdef METHOD2 m_MyBlock.NdisCommonOpenBlock.RequestHandler = MSTCP_RequestHandler; m_MyBlock.NdisCommonOpenBlock.SendHandler = MSTCP_SendHandler; m_MyBlock.NdisCommonOpenBlock.SendPacketsHandler = MSTCP_SendPacketsHandler; m_MyBlock.NdisCommonOpenBlock.TransferDataHandler = MSTCP_TransferDataHandler; #else //RepatchNdis(1); pBlock->NdisCommonOpenBlock.RequestHandler = MSTCP_RequestHandler; pBlock->NdisCommonOpenBlock.SendHandler = MSTCP_SendHandler; pBlock->NdisCommonOpenBlock.SendPacketsHandler = MSTCP_SendPacketsHandler; pBlock->NdisCommonOpenBlock.TransferDataHandler = MSTCP_TransferDataHandler; #endif */ m_State = eRunning; return 0; } else { delete m_pBind; m_pBind = NULL; pdo->m_hAdapterNumber2AdapterInfo.Remove(m_Number); // m_pProtocol->m_AdapterList.Remove ( this ); // pdo->m_hBindingHandle2AdapterInfo.Remove ( m_BindingHandle ); // pdo->m_hNdisBindingHandle2AdapterInfo.Remove ( m_NdisBindingHandle ); // ret -1; } return -1; } void CMaaAdapterInfo::AdapterClosed () { // Context is locked delete m_pBind; m_pBind = NULL; pdo->m_hAdapterNumber2AdapterInfo.Remove(m_Number); // m_pProtocol->m_AdapterList.Remove ( this ); // pdo->m_hMyBindingHandle2AdapterInfo.Remove ( m_MyBindingHandle ); // pdo->m_hNdisBindingHandle2AdapterInfo.Remove ( m_NdisBindingHandle ); // pdo->m_hBindingHandle2AdapterInfo.Remove ( m_BindingHandle ); m_State = eClosed; } void CMaaAdapterInfo::Touch() { m_PacketsProcessing++; } void CMaaAdapterInfo::UnTouch() { m_PacketsProcessing--; } //--------------------------------------------------------------------------- CDrvLockVerifier::CDrvLockVerifier() { Proc = -1; File = "none"; Line = -1; } CDrvLockVerifier::~CDrvLockVerifier() { } void CDrvLockVerifier::AfterLock(const char * f, int l) { if (Proc != -1) { // __asm int 3; /* char * str = CDrvSprintfAlloc("Lock error: already locked by %s : %d, proc = %d", File, Line, Proc); if (str) { OUT_DEBUG_STRING(str); } __asm int 3; static int a = 0; a++; a++; delete [] str; */ } File = f; Line = l; Proc = KeGetCurrentProcessorNumber(); } void CDrvLockVerifier::BeforeUnLock(const char * f, int l) { int pr = KeGetCurrentProcessorNumber(); if (Proc == -1) { // __asm int 3; /* char * str = CDrvSprintfAlloc("Lock error: not locked while trying to unlock by %s : %d, proc = %d", f, l, pr); if (str) { OUT_DEBUG_STRING(str); } __asm int 3; static int a = 0; a++; a++; delete [] str; */ } else if (Proc != pr) { // __asm int 3; /* char * str = CDrvSprintfAlloc("Lock error: locked by other processor while trying to unlock by %s : %d, proc = %d, previous lock by %s : %d, proc = %d", f, l, pr, File, Line, Proc); if (str) { OUT_DEBUG_STRING(str); } __asm int 3; static int a = 0; a++; a++; delete [] str; */ return; } File = "unlocked"; Line = -1; Proc = -1; }