#include "stdafx.h" #include "main.h" #ifdef _DEBUG #define new DEBUG_NEW #endif #pragma warning(disable:4996) #define RUSROUTE_DRIVER //--------------------------------------------------------------------------- // class CMaaDrvApi //--------------------------------------------------------------------------- CMaaDrvApi::CMaaDrvApi ( const char * pszFileName ) { printf("Opening device %s...\n", pszFileName); #ifndef __unix__ OSVERSIONINFO Info; Info.dwOSVersionInfoSize = sizeof ( OSVERSIONINFO ); BOOL bV = GetVersionEx ( & Info ); m_IsWinNT = bV ? ( Info.dwPlatformId == VER_PLATFORM_WIN32_NT ? true : false ) : false; char txt [ 300 ]; if (strlen(pszFileName) + strlen("\\\\.\\Globals\\") >= sizeof(txt)) { m_IsLoadSuccessfully = FALSE; m_hVxD = INVALID_HANDLE_VALUE; } else { strcpy ( txt, "\\\\.\\" ); strcat ( txt, pszFileName ); m_IsLoadSuccessfully = FALSE; //m_hVxD = CreateFile ( txt, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_OVERLAPPED, 0 ); //m_hVxD = CreateFile ( txt, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_DELETE_ON_CLOSE, 0 ); m_hVxD = CreateFile ( txt, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_DELETE_ON_CLOSE, 0 ); if ( m_hVxD == INVALID_HANDLE_VALUE ) { m_hVxD = CreateFile ( txt, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0 ); } if ( m_hVxD == INVALID_HANDLE_VALUE ) { strcpy ( txt, "\\\\.\\Globals\\" ); strcat ( txt, pszFileName ); m_hVxD = CreateFile ( txt, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_DELETE_ON_CLOSE, 0 ); if ( m_hVxD == INVALID_HANDLE_VALUE ) { m_hVxD = CreateFile ( txt, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0 ); } } } if ( m_hVxD == INVALID_HANDLE_VALUE ) { DWORD err = GetLastError (); printf("Error = %d\n", err); m_ovlp.hEvent = 0; } else { m_ovlp.hEvent = 0; m_ovlp.hEvent = CreateEvent ( 0, TRUE, 0, NULL ); if ( m_ovlp.hEvent ) { m_IsLoadSuccessfully = TRUE; } } #else m_IsLoadSuccessfully = TRUE; #endif //!__unix__ } CMaaDrvApi::~CMaaDrvApi () { #ifndef __unix__ if ( m_hVxD != INVALID_HANDLE_VALUE ) { CloseHandle ( m_hVxD ); } if ( m_ovlp.hEvent ) { CloseHandle ( m_ovlp.hEvent ); } #endif //!__unix__ } //--------------------------------------------------------------------------- BOOL CMaaDrvApi::VxdIoControl ( DWORD dwService, const void * BuffIn, int SizeIn, void * BuffOut, int SizeOut, int * SizeRet ) { DWORD l_SizeRet = -1; m_SizeRet = l_SizeRet; if ( ! m_IsLoadSuccessfully ) { return 1; } BOOL Ret = FALSE; if ( m_hVxD != INVALID_HANDLE_VALUE ) { Ret = DeviceIoControl(m_hVxD, dwService, (void *)BuffIn, SizeIn, BuffOut, SizeOut, &l_SizeRet, NULL /*&m_ovlp*/); } m_SizeRet = l_SizeRet; if ( Ret && SizeRet ) { * SizeRet = l_SizeRet; } if ( ! Ret ) { //printf ( "Error code = %d\n", GetLastError() ); if ( GetLastError() == ERROR_IO_PENDING ) { //printf("VxD correctly returned operation incomplete.\n"); } else { //ERROR_OUT("VxD does not support the requested API!!!\n"); } } else { //ERROR_OUT("VxD processed the call synchronously!!!\n"); } // // DeviceIoControl call will have returned without completing // requested function. GetOverlappedResult at this point // should return ERROR_IO_INCOMPLETE if called w/ fWait=FALSE. // /* if ( ! GetOverlappedResult ( hVxD, &ovlp, &cbRet, FALSE ) ) { if ( GetLastError() == ERROR_IO_INCOMPLETE ) { printf("GetOverlappedResult returned expected value.\n"); } else { ERROR_OUT("GetOverlappedResult returned unexpected error.\n"); } } else { ERROR_OUT("GetOverlappedResult unexpectedly returned success.\n"); } */ /* nTicks = GetTickCount(); // // This call to GetOverlappedResult will suspend this thread // until the operation is completed by the VxD. I.e. until the // VxD calls DIOC_VWIN32CompletionRoutine. // GetOverlappedResult(hVxD, &ovlp, &cbRet, TRUE); nTicks = GetTickCount() - nTicks; // This will wrap after 47 days printf("DevIoctl Call elapsed time: %d ms\n", nTicks); printf("DevIoctl returned: %d bytes\n", cbRet); printf("DevIoctl output: %s\n", OutBuff); */ return Ret; } //--------------------------------------------------------------------------- BOOL CMaaDrvApi::IsLoadSuccessfully () { return m_IsLoadSuccessfully; } //--------------------------------------------------------------------------- /* typedef DWORD ( WINAPI *pfOpenVxDHandle )( HANDLE hSource ); //--------------------------------------------------------------------------- DWORD CMaaDrvApi::OpenVxDHandle ( HANDLE hWin32Source ) { DWORD vh = 0; if ( IsLoadSuccessfully () ) { HMODULE hm = GetModuleHandle ( "kernel32.dll" ); if ( hm ) { pfOpenVxDHandle pf = ( pfOpenVxDHandle ) GetProcAddress ( hm, "OpenVxDHandle" ); if ( pf ) { vh = pf ( hWin32Source ); } } } return vh; } */ //--------------------------------------------------------------------------- #ifdef RUSROUTE_DRIVER bool bRusRouteDriver = true; #else bool bRusRouteDriver = false; #endif OSVERSIONINFO verInfo; static char * DriverName = "Rusroutf"; CRusRouteApi::CRusRouteApi() : CMaaDrvApi(DriverName) { verInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx ( &verInfo ); } CRusRouteApi::~CRusRouteApi() { } const char * CRusRouteApi::GetDriverName() const { return bRusRouteDriver ? DriverName : "Unknown"; } BOOL CRusRouteApi::IsLoadSuccessfully() { if (bRusRouteDriver) { return CMaaDrvApi::IsLoadSuccessfully(); } return FALSE; } BOOL CRusRouteApi::GetVersion(int *VersionHigh, int *VersionLow, int *Build, char *Str, int *bIsDebug) { int vh, vl, b; char s[512]; BOOL d; if (!VersionHigh) { VersionHigh = &vh; } if (!VersionLow) { VersionLow = &vl; } if (!Build) { Build = &b; } if (!Str) { Str = s; } if (!bIsDebug) { bIsDebug = &d; } *VersionHigh = *VersionLow = *Build = 0; *Str = 0; *bIsDebug = FALSE; int Version = 0; if (bRusRouteDriver) { if (!IsLoadSuccessfully()) { //printf ( "Driver %s is not loaded.\n", DriverName ); return FALSE; } if (!VxdIoControl(RUSROUTE_GET_VERSION, NULL, 0, &Version, sizeof(Version), NULL)) { //printf ( "Error getting it's version number\n" ); return FALSE; } } //printf ( "Driver %s is loaded successfully.\n", DriverName ); const char * pDebugVersion = ""; if (Version < 0) { pDebugVersion = " (Debug)"; Version = Version & 0x7fffffff; *bIsDebug = TRUE; } int v = Version / 0x10000; *VersionHigh = v / 100; *VersionLow = v % 100; *Build = Version & 0xffff; sprintf(Str, "%d.%02d-%d%s", *VersionHigh, *VersionLow, *Build, pDebugVersion); return TRUE; } int CRusRouteApi::GetAdapters(DWORD * pAdapterNumbers, int MaxNumbers) { DWORD nn[512]; if (!pAdapterNumbers) { pAdapterNumbers = nn; MaxNumbers = sizeof(nn) / sizeof(nn[0]); } int Adapters = 0; if (bRusRouteDriver) { VxdIoControl ( RUSROUTE_GET_ADAPTER_LIST, NULL, 0, pAdapterNumbers, MaxNumbers * sizeof(int), &Adapters ); if (Adapters >= 0 && Adapters < (int)(MaxNumbers * sizeof(int))) { Adapters /= sizeof(int); } else { Adapters = -1; } } return Adapters; } #define DEVICE_NDISWANIP "\\DEVICE\\NDISWANIP" #define USER_NDISWANIP "WAN Network Interface (IP)" #define REGSTR_NETWORK_CONTROL_KEY TEXT("SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\") #define REGSTR_VAL_CONNECTION TEXT("\\Connection") #define REGSTR_NAME TEXT("Name") BOOL ConvertWindows2000AdapterName ( LPCSTR szAdapterName, LPSTR szUserFriendlyName, DWORD dwUserFriendlyNameLength ) { HKEY hKey; char szFriendlyNameKey[MAX_PATH*2]; DWORD dwType; if (_stricmp(szAdapterName, DEVICE_NDISWANIP) == 0) { strcpy (szUserFriendlyName, USER_NDISWANIP); return TRUE; } /* if (_stricmp(szAdapterName, DEVICE_NDISWANBH) == 0) { strcpy (szUserFriendlyName, USER_NDISWANBH); return TRUE; } if (_stricmp(szAdapterName, DEVICE_NDISWANIPV6) == 0) { strcpy (szUserFriendlyName, USER_NDISWANIPV6); return TRUE; } */ strcpy (szFriendlyNameKey, REGSTR_NETWORK_CONTROL_KEY); strcpy ((char*)szFriendlyNameKey + strlen(szFriendlyNameKey), &szAdapterName[strlen("\\Device\\")]); strcpy ((char*)szFriendlyNameKey + strlen(szFriendlyNameKey), REGSTR_VAL_CONNECTION); if (strlen(szAdapterName) < dwUserFriendlyNameLength) { strcpy(szUserFriendlyName, szAdapterName); } else if (dwUserFriendlyNameLength > 0) { szUserFriendlyName[0] = 0; } LONG lResult = RegOpenKeyEx ( HKEY_LOCAL_MACHINE, szFriendlyNameKey, 0, KEY_READ, &hKey ); if (lResult == ERROR_SUCCESS) { lResult = RegQueryValueEx(hKey, REGSTR_NAME, NULL, &dwType, (LPBYTE)szUserFriendlyName, &dwUserFriendlyNameLength); RegCloseKey(hKey); } else { return FALSE; } return TRUE; } BOOL CRusRouteApi::GetAdapterInfo(DWORD Number, CRusRoute_AdapterInfo *Info) { CRusRoute_AdapterInfo i; int Ret; if (!Info) { Info = &i; } if (bRusRouteDriver) { if (!VxdIoControl(RUSROUTE_GET_ADAPTER_INFO, &Number, sizeof(Number), Info, sizeof(*Info), &Ret)) { return FALSE; } if (Ret != sizeof(*Info) || (int)Info->m_Number < 0) { return FALSE; } char szName[MAX_PATH + sizeof(Info->m_Name) / 2 + 100]; szName[0] = 0; Info->m_Name[sizeof(Info->m_Name) - 2] = Info->m_Name[sizeof(Info->m_Name) - 1] = 0; WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)Info->m_Name, -1, szName, sizeof(szName), NULL, NULL); char szFriendlyName[MAX_PATH*4]; szFriendlyName[0] = 0; /* OSVERSIONINFO verInfo; memset(&verInfo, 0, sizeof(verInfo)); verInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&verInfo); //XP - 5.1 //2003 - 5.2 //Vista - 6.0 if (verInfo.dwPlatformId == VER_PLATFORM_WIN32_NT && (verInfo.dwMajorVersion >= 6 || (verInfo.dwMajorVersion == 5 && verInfo.dwMinorVersion >= 1))) */ if (verInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) { if (verInfo.dwMajorVersion >= 5) { // Windows 2000 or XP ConvertWindows2000AdapterName((const char*)szName, szFriendlyName, MAX_PATH*4); } /* else if (verInfo.dwMajorVersion == 4) { // Windows NT 4.0 ConvertWindowsNTAdapterName((const char*)szName, szFriendlyName, MAX_PATH*4); } */ } else { // Windows 9x/ME //ConvertWindows9xAdapterName((const char*)szName, szFriendlyName, MAX_PATH*4); } WCHAR OutName[MAX_PATH*8]; MultiByteToWideChar(CP_ACP, 0, szFriendlyName, (int)strlen(szFriendlyName) + 1, OutName, MAX_PATH * 4); int j; for (j = 0; OutName[j] && j < sizeof(Info->m_Name) / 2 - 1; j++) { *(short*)&Info->m_Name[2 * j] = OutName[j]; } Info->m_Name[2 * j] = 0; Info->m_Name[2 * j + 1] = 0; return TRUE; } return FALSE; } int CRusRouteApi::GetLineWanUpLinks(DWORD Number, RR_NDIS_WAN_LINE_UP_LINK * l, int n) // returns number of elements, <= n { int Ret; if (bRusRouteDriver) { if (!VxdIoControl(RUSROUTE_GET_WAN_UP_LINKS, &Number, sizeof(Number), l, n * sizeof(*l), &Ret)) { return 0; } //if (Ret != sizeof(*Info) || (int)Info->m_Number < 0) { return Ret / sizeof(*l); } } return 0; } BOOL CRusRouteApi::GetPacket(CRusRoute_Packet *p) { if (!p) { return FALSE; } if (bRusRouteDriver) { int SizeRet = 0; VxdIoControl(RUSROUTE_GET_PACKET, &p->m_AdapterNumber, sizeof(p->m_AdapterNumber), (CRusRoute_Packet0 *)p, sizeof(CRusRoute_Packet0), &SizeRet); if (SizeRet > sizeof(DWORD)) { if (SizeRet > sizeof(CRusRoute_Packet0)) { // CProtocolListColor c(CProtocolListColor::eRed); printf("GetPacket(): SizeRet == %d > %d\n", SizeRet, sizeof(CRusRoute_Packet0)); SizeRet = sizeof(CRusRoute_Packet0); } return TRUE; } return FALSE; } return FALSE; } BOOL CRusRouteApi::PutPacket(CRusRoute_Packet &p, int StatusEx) { if (StatusEx == 0) { static int aa = 0; aa++; aa++; } if (bRusRouteDriver) { int SizeRet = 0; int AdapterUsed = -4; DWORD aNum = p.m_AdapterNumber; DWORD Len = p.m_Length; if (Len > RUSROUTE_MAX_FRAME_SIZE) { // CProtocolListColor c(CProtocolListColor::eRed); printf("CRusRouteApi::PutPacket(): Error: Len = %d\n", Len); return FALSE; } VxdIoControl(RUSROUTE_PUT_PACKET, (CRusRoute_Packet0 *)&p, sizeof(CRusRoute_Packet0), &AdapterUsed, sizeof(AdapterUsed), &SizeRet); if (SizeRet >= sizeof(AdapterUsed) && AdapterUsed > 0) { return TRUE; } // CProtocolListColor c(CProtocolListColor::eRed); printf("CRusRouteApi::PutPacket(): returning FALSE, aNum = %p\n", aNum); return FALSE; } return FALSE; } BOOL CRusRouteApi::SetEventHandle(eEventType Type, HANDLE hEvent, int AdapterId) { if (bRusRouteDriver) { CRusRoute_SetEventHandle s; s.m_Type = Type; s.m_tmp = 0; s.m_Event = hEvent; s.m_AdapterNumber = AdapterId; int Ret = 0; VxdIoControl ( RUSROUTE_SET_EVENT_HANDLE, &s, sizeof(s), &Ret, sizeof(Ret), NULL); return Ret != 0; } return FALSE; } BOOL CRusRouteApi::Test1() { int Ret = 0; return VxdIoControl(RUSROUTE_TEST1, NULL, 0, NULL, 0, &Ret); } BOOL CRusRouteApi::Test2() { int Ret = 0; return VxdIoControl(RUSROUTE_TEST2, NULL, 0, NULL, 0, &Ret); } BOOL CRusRouteApi::TcpOptimize(int iAdd, CTcpOptimization *o) // -1 - remove(init) all, 1 - add, 0 - remove { if (bRusRouteDriver) { char Buf[sizeof(int) + sizeof(CTcpOptimization)]; memset(Buf, 0, sizeof(Buf)); *(int *)Buf = iAdd; if (o) { memcpy(Buf + sizeof(int), o, sizeof(*o)); } int Ret = 0; VxdIoControl(RUSROUTE_TCP_OPTIMIZE, Buf, sizeof(Buf), &Ret, sizeof(Ret), NULL); return Ret != 0; } return FALSE; } BOOL CRusRouteApi::LoginLogout(_IP Ip, int Id) // Id == -1 -- logout { if (bRusRouteDriver) { char Buf[sizeof(Ip) + sizeof(int)]; *(_IP *)Buf = Ip; *(int*)(Buf + sizeof(_IP)) = Id; int Ret = 0; VxdIoControl(RUSROUTE_LOGIN_LOGOUT, Buf, sizeof(Buf), &Ret, sizeof(Ret), NULL); return Ret != 0; } return FALSE; } /* BOOL CRusRouteApi::GetJournalRecs(sOptJournalRecs * r) { if (bRusRouteDriver && r) { int SizeRet = 0; VxdIoControl(RUSROUTE_GET_JOURNAL_RECS, NULL, 0, r, sizeof(*r), &SizeRet); return SizeRet == sizeof(*r); } return FALSE; } */ /* CMaaString CRusRouteApi::GetLog(bool bFirst) { CMaaString txt; if (bRusRouteDriver) { CMaaPtr Buf(128 * 1024 + 10); int t = bFirst ? 1 : 0; int SizeRet = 0; if (Buf.IsValid()) { VxdIoControl(RUSROUTE_GET_LOG, &t, (int)sizeof(t), Buf, (int)Buf.Size(), &SizeRet); if (SizeRet > 0 && Buf[SizeRet - 1] == 0) { SizeRet--; } } txt = CMaaString(Buf, SizeRet); } return txt; } */ int main() { CRusRouteApi api; DWORD t = GetTickCount(); if (!api.IsLoadSuccessfully()) { printf("Driver is not loaded.\n"); return 1; } { DWORD Adapters[100]; int n = api.GetAdapters(Adapters, 100); for (int i = 0; i < n; i++) { CRusRoute_AdapterInfo Info; memset(&Info, 0, sizeof(Info)); WCHAR *InName = (WCHAR *)Info.m_Name; //memcpy(InName, Info.m_Name, min(sizeof(Info.m_Name), sizeof(InName))); //InName[end] = 0; if (!api.GetAdapterInfo(Adapters[i], &Info)) { printf("Error getting adapter info for #%d\n", Adapters[i]); continue; } char Name[MAX_PATH]; Name[0] = 0; WideCharToMultiByte(CP_ACP, 0, InName, -1, Name, sizeof(Name), NULL, NULL); printf("%d. #%d %s\n", i + 1, Adapters[i], Name); } } HANDLE hEv = CreateEvent(NULL, TRUE, FALSE, NULL); api.SetEventHandle(CRusRouteApi::ePacketInterceptedEvent, hEv); SetEvent(hEv); printf("\n\n"); int n = 0, ns = 0, nr = 0; while(1) { DWORD dw = WaitForSingleObject(hEv, 2000); if (dw == WAIT_TIMEOUT) { printf("\r%d packets are handled: %d received, %d sent ...", n, nr, ns); continue; } ResetEvent(hEv); if (dw != WAIT_OBJECT_0) { // continue; } while(1) { CRusRoute_Packet p; p.m_AdapterNumber = -1; if (!api.GetPacket(&p)) { break; } if (p.m_Status & RUSROUTE_STATUS_PASS_TO_TCP) { nr++; } else { ns++; } api.PutPacket(p, 0); n++; if (n % 100 == 0 || GetTickCount() - t > 1000) { t = GetTickCount(); printf("\r%d packets are handled: %d received, %d sent ...", n, nr, ns); } } } api.SetEventHandle(CRusRouteApi::ePacketInterceptedEvent, NULL); CloseHandle(hEv); return 0; }