//========================================================================== // 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 //========================================================================== // FILE: Library.cpp // // AUTHOR: Andrey A. Moiseenko // // OVERVIEW Driver library of the base functions. // ~~~~~~~~ // DATE: 15.10.2003 //========================================================================== #include "perm.h" #include "temp.h" size_t gMemoryAllocated = 0; int gChkIrqlLevel = 0; CMaaGetCheckIrql::CMaaGetCheckIrql ( const char * szPoint ) { #ifdef _WINNT //CCliLock lk; //lk.Lock (); int l = gChkIrqlLevel++; //lk.UnLock (); m_szPoint = szPoint; m_Irql = KeGetCurrentIrql (); if ( m_szPoint ) { //PrintDbg ( "%s: Irql=%d, l=%d", m_szPoint, m_Irql, l ); } else { static int PointN = 0; m_PointN = ++PointN; //PrintDbg ( "Point %d: Irql=%d, l=%d", m_PointN, m_Irql, l ); } #endif } CMaaGetCheckIrql::~CMaaGetCheckIrql () { #ifdef _WINNT //CCliLock lk; //lk.Lock (); int l = --gChkIrqlLevel; //lk.UnLock (); KIRQL Irql = KeGetCurrentIrql (); if ( Irql == m_Irql ) { if ( m_szPoint ) { //PrintDbg ( "%s: Irql=%d (OK), l=%d", m_szPoint, Irql, l ); } else { //PrintDbg ( "Point %d: Irql=%d (OK), l=%d", m_PointN, Irql, l ); } } else { if ( m_szPoint ) { //PrintDbg ( "%s: Irql=%d (BAD !!!) must be %d; l=%d", m_szPoint, Irql, m_Irql, l ); } else { //PrintDbg ( "Point %d: Irql=%d (BAD !!!) must be %d; l=%d", m_PointN, Irql, m_Irql, l ); } //INT3; if (m_Irql < Irql) { KeLowerIrql(m_Irql); } } #endif } #ifndef __unix__ //--------------------------------------------------------------------------- int * p_minus_1 = (int *)(__int64)-1; int int_minus_1 = 0; int __cdecl _purecall ( void ) { // ?0000$ тому, кто знает, что должна вернуть эта функция !!! int_minus_1 = *p_minus_1; /* _asm { mov eax, -1 mov eax, [ eax ] } */ return 0; } //--------------------------------------------------------------------------- char * KillCrLf ( char * str ) { char * p = str; while ( *p ) p++; while ( p > str && ( p [ -1 ] == '\r' || p [ -1 ] == '\n' ) ) p--; *p = 0; return str; } //--------------------------------------------------------------------------- #ifndef Memset void Memset(void * destination, char c, int bytes ) { if ( ( unsigned ) bytes > 128U * 1024U ) { INT3; return; } memset(destination, c, bytes); /* _asm { push esi push edi mov edi, destination mov ecx, bytes mov al, c cld rep stosb pop edi pop esi } */ } #endif //--------------------------------------------------------------------------- #ifndef Memcpy void Memcpy ( void * destination, const void * source, int bytes ) { if ( ( unsigned ) bytes > 128U * 1024U ) { INT3; return; } //NdisMoveMemory(destination, source, bytes); memmove(destination, source, bytes); /* _asm { push esi push edi mov edi, destination mov esi, source mov ecx, bytes cld shr ecx, 2 rep movsd mov ecx, bytes and ecx, 3 rep movsb pop edi pop esi } */ } #endif //--------------------------------------------------------------------------- void MemcpyRevol ( void * destination, const void * source, int bytes ) { if ( ( unsigned ) bytes > 128U * 1024U ) { INT3; return; } memmove(destination, source, bytes); /* _asm { push esi push edi mov edi, destination mov esi, source mov ecx, bytes lea edi, [ edi + ecx - 4 ]; lea esi, [ esi + ecx - 4 ]; std shr ecx, 2 rep movsd mov ecx, bytes and ecx, 3 add edi, 3 add esi, 3 rep movsb cld pop edi pop esi } */ } //--------------------------------------------------------------------------- #ifndef Memmove void Memmove ( void * destination, const void * source, int bytes ) { memmove(destination, source, bytes); /* if ( ( _byte * ) source < ( _byte * ) destination && ( _byte * ) destination < bytes + ( _byte * ) source ) { MemcpyRevol ( destination, source, bytes ); } else { Memcpy ( destination, source, bytes ); } */ } #endif //--------------------------------------------------------------------------- #ifndef Memcmp int Memcmp ( const void * ptr1, const void * ptr2, int bytes ) { //return memcmp(ptr1, pt2, bytes); char * p1 = (char *)ptr1; char * p2 = (char *)ptr2; for (int i = 0; i < bytes; i++) { if (p1[i] != p2[i]) { return p1[i] - p2[i]; } } return 0; /* // returns sign as ptr1[] - ptr2[] int RetValue = 0; _asm { push esi push edi mov esi, ptr1 mov edi, ptr2 mov ecx, bytes cld shr ecx, 2 rep cmpsd jnz _NotZero mov ecx, bytes and ecx, 3 rep cmpsb jz _Zero jmp _NotEqByte _NotZero: mov ecx, 4 sub esi, ecx sub edi, ecx rep cmpsb _NotEqByte: rcr RetValue, 1 inc RetValue _Zero: pop edi pop esi } return RetValue; */ } #endif //--------------------------------------------------------------------------- #ifndef Memzero void Memzero ( void * destination, int bytes ) { memset(destination, 0, bytes); /* _asm { push edi mov edi, destination mov ecx, bytes cld shr ecx, 2 xor eax, eax rep stosd mov ecx, bytes and ecx, 3 rep stosb pop edi } */ } #endif //--------------------------------------------------------------------------- unsigned int Strlen ( const char * string ) { return (unsigned int)strlen(string); /* unsigned int RetValue; _asm { push edi mov edi, string mov ecx, 0xffffffff xor eax,eax cld repnz scasb not ecx dec ecx mov RetValue, ecx pop edi } return RetValue; */ } //--------------------------------------------------------------------------- int Strcmp ( const void * str1, const void * str2 ) { return strcmp((const char *)str1, (const char *)str2); /* int RetValue; _asm { push esi push edi mov esi, str1 mov edi, str2 xor eax, eax cld _Repeat: cmpsb jne _NotEq cmp al, [esi-1] jne _Repeat jmp Exit_Loop _NotEq: mov al, [esi-1] sub al, [edi-1] shl eax, 24 } Exit_Loop: _asm { mov RetValue, eax pop edi pop esi } return RetValue; */ } //--------------------------------------------------------------------------- int Stricmp ( const void * str1, const void * str2 ) { //return stricmp((const char *)str1, (const char *)str2); const char * p1 = ( const char * ) str1; const char * p2 = ( const char * ) str2; while (*p1 || *p2) { char c1 = *p1; char c2 = *p2; if (c1 >= 'a' && c1 <= 'z') { c1 -= 'a' - 'A'; } if (c2 >= 'a' && c2 <= 'z') { c2 -= 'a' - 'A'; } if (c1 != c2) { return *p1 - *p2; } p1++; p2++; } return *p1 - *p2; } //--------------------------------------------------------------------------- void Strcat ( char * str1, const char * str2, int MaxStr1Size ) { int len1, len2; len1 = Strlen ( str1 ); len2 = Strlen ( str2 ); if ( len1 + len2 + 1 > MaxStr1Size ) { if ( len1 > MaxStr1Size ) { return; } len2 = MaxStr1Size - 1 - len1; } Memcpy( str1 + len1, str2, len2 ); str1 [ len1 + len2 ] = 0; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void * NdisAlloc ( unsigned Size ) { void * Ptr = NULL; NDIS_PHYSICAL_ADDRESS HighAddress = NDIS_PHYSICAL_ADDRESS_CONST( -1, -1 ); if ( NdisAllocateMemory ( & Ptr, Size, 0, HighAddress ) == NDIS_STATUS_SUCCESS ) { gMemoryAllocated += Size; } if ( ! Ptr ) { INT3; #ifndef _WINNT OUT_DEBUG_STRING ( "MaaRF: Not enough free memory\r\n" ); #else DbgPrint ( "MaaRF: Not enough free memory\r\n" ); #endif } return Ptr; } //--------------------------------------------------------------------------- void NdisFree ( void * Ptr, unsigned Size ) { if ( Ptr ) { NdisFreeMemory ( Ptr, Size, 0 ); gMemoryAllocated -= Size; } } //--------------------------------------------------------------------------- #ifdef _WINNT void * malloc ( size_t Size ) { /* if (Size == 0x178) { __asm int 3; static int aa = 0; aa++; aa++; } */ /* if (Size == 0x41c) { __asm int 3; static int aa = 0; aa++; aa++; } if (Size == 0x7000) { __asm int 3; static int aa = 0; aa++; aa++; } */ void * p = ( void * ) ExAllocatePool ( NonPagedPool, Size ); if ( ! p ) { INT3; DbgPrint ( "MaaRF: Not enough free memory\r\n" ); } return p; } void * calloc ( size_t Size ) { void * addr = malloc ( Size ); if ( addr ) { NdisZeroMemory ( addr, ( int ) Size ); } return addr; } void free ( void * ptr ) { if ( ptr ) { ExFreePool ( ptr ); } } //void * __cdecl operator new ( size_t Size ) //{ // return calloc ( Size ); //} // //void __cdecl operator delete ( void * ptr ) //{ // free ( ptr ); //} #endif //--------------------------------------------------------------------------- void * __cdecl operator new(size_t col) { if ( col + sizeof(size_t) < col ) { INT3; return NULL; } if ( ! col ) { return NULL; } #ifdef _WIN9x char * x = ( char * ) NdisAlloc ( col + 4 ); #else char * x = ( char * ) malloc ( col + sizeof(size_t) ); #endif if ( x ) { *(size_t *)x = col + sizeof(size_t); #ifdef _WINNT gMemoryAllocated += col + sizeof(size_t); #endif x += sizeof(size_t); } return x; } //--------------------------------------------------------------------------- void __cdecl operator delete ( void * x ) { if ( x ) { char * p = ( char * ) x - sizeof(size_t); size_t xx = *(size_t *)p; if ( !xx ) { INT3; INT3; } else { *(size_t *)p = 0; #ifdef _WIN9x NdisFree ( p, xx ); #else free(p); gMemoryAllocated -= xx; #endif } } } _word /*__declspec(naked)*/ _stdcall htons(_word x) { return ((x >> 8) & 0xff) | ((x & 0xff) << 8); /* __asm { movzx eax, word ptr [ esp + 4 ] xchg al, ah ret 4 } */ } _dword /*__declspec(naked)*/ _stdcall htonl(_dword x) { return ((x >> 24) & 0xff) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | ((x & 0xff) << 24); /* __asm { mov eax, [ esp + 4 ] bswap eax ret 4 } */ } //--------------------------------------------------------------------------- char * CDrvSprintfAlloc(const char * format, ...) { va_list list; va_start(list, format); return CDrvSprintf_(format, list); } //--------------------------------------------------------------------------- void CDrvSprintf ( char * buff, const char * format, ... ) { va_list list; va_start ( list, format ); char * str = CDrvSprintf_ ( format, list ); if ( str ) { Memcpy ( buff, str, Strlen ( str ) + 1 ); } else { *buff = 0; } delete str; va_end ( list ); } //--------------------------------------------------------------------------- void MaaPrint ( const char * format, ... ) { va_list list; va_start ( list, format ); //pdo->m_PrintDbgLock.Lock (); #ifndef _WINNT static int SLock = 0; int LLock; __asm { pushfd cli inc SLock mov eax, SLock popfd mov LLock, eax } if ( LLock == 1 ) { #endif char * str = CDrvSprintf_ ( format, list ); if ( str ) { //#ifndef DRV_SUPRESS_DEBUG_OUT OUT_DEBUG_STRING ( str ); //#endif if (pdo) { pdo->Log(str); } } else { static int f = 0; if ( !f ) { f++; INT3; //#ifndef DRV_SUPRESS_DEBUG_OUT OUT_DEBUG_STRING ( "MaaRF: Not enough free memory\r\n" ); //#endif const char * str = "MaaRF: Not enough free memory\r\n"; if (pdo) { pdo->Log(str); } } } delete [] str; #ifndef _WINNT } __asm { dec SLock } #endif //pdo->m_PrintDbgLock.UnLock (); va_end ( list ); } //--------------------------------------------------------------------------- char * CDrvSprintf_ ( const char * __format, va_list list ) { #define MAX_SPRINTF_SIZE 2048 char * p, * buff; p = buff = new char [ MAX_SPRINTF_SIZE ]; int Flag_M = 0; if ( ! p ) { return p; } for ( const char * f = __format; * f; f++ ) { if ( *f != '%' ) { *p++ = *f; continue; } f++; switch ( *f ) { case 'd': { // decimal int x = va_arg ( list, int ); if ( x < 0 ) { *p++ = '-'; x = -x; } int y = 1; char c; while ( x / y > 9 ) { y *= 10; } while ( y > 0 ) { c = + ( char )( x / y ); *p++ = c + '0'; x -= ( int ) c * y; y /= 10; } break; } case 'x': { unsigned x = va_arg ( list, int ); for ( int shift=32; shift; shift -= 4 ) { char c = ( (x>>(shift-4)) & 0xf ); if ( c > 9 ) { c += 7; } *p++ = c + '0'; } break; } case 'p': { void * x = va_arg(list, void *); unsigned char * px = (unsigned char *)&x; for (int i=sizeof(x); --i >= 0; ) { unsigned char c = (px[i] >> 4) & 0x0f; if (c > 9) { c += 7; } *p++ = c + '0'; c = px[i] & 0x0f; if (c > 9) { c += 7; } *p++ = c + '0'; } break; } case 'b': // one hex byte { unsigned x = va_arg ( list, int ); for ( int shift=8; shift; shift -= 4 ) { char c = ( (x>>(shift-4)) & 0xf ); if ( c > 9 ) { c += 7; } *p++ = c + '0'; } break; } case 'w': { unsigned short x = va_arg ( list, unsigned short ); for ( int shift=16; shift; shift -= 4 ) { char c = ( (x>>(shift-4)) & 0xf ); if ( c > 9 ) { c += 7; } *p++ = c + '0'; } break; } case 'M': Flag_M++; case 'm': { _byte * ptr = va_arg ( list, _byte * ); int len = va_arg ( list, int ); int pos = 0; //BOOL fErrLen = FALSE; if ( len > ( MAX_SPRINTF_SIZE - 20 ) / 4 || len > 64 ) { Memcpy ( p, "%m-errlen! ", 11 ); p += 11; //fErrLen = TRUE; len = ( MAX_SPRINTF_SIZE - 20 ) / 4 < 64 ? ( MAX_SPRINTF_SIZE - 20 ) / 4 : 64; } for ( ; len-- > 0; ) { _byte c; //if ( len > ( MAX_SPRINTF_SIZE - 20 ) / 4 ) //{ // Memcpy ( p, "%m-err ", 7 ); // p += 7; // break; //} if ( pos >= 16 ) { pos = 0; *p++ = '\r'; *p++ = '\n'; } if ( ! pos && Flag_M ) { for ( int j = 0; j < 16; j++ ) { c = j <= len ? ptr [ j ] : ' '; c = ( c < ' ' || c > 240 ) ? '.' : c; *p++ = c; } *p++ = ' '; *p++ = ' '; } pos += Flag_M; c = ptr [ 0 ] >> 4; c = ( c > 9 ) ? c + 7 : c; *p++ = c + '0'; c = *ptr++ & 0x0f; c = ( c > 9 ) ? c + 7 : c; *p++ = c + '0'; if ( len ) { *p++ = ' '; } } Flag_M = 0; break; } case 's': { char * str = va_arg ( list, char * ); while ( * str ) { *p++ = *str++; } break; } case 'I': { //if ( f [ 1 ] == 'p' ) { // %I - ip address _IP ip = va_arg ( list, _IP ); for ( int i = 4; i--; ) { unsigned x = ( ( unsigned ) ip >> 24 ); ip <<= 8; int y = 1; char c; while ( x / y > 9 ) { y *= 10; } while ( y > 0 ) { c = + ( char )( x / y ); *p++ = c + '0'; x -= ( int ) c * y; y /= 10; } if ( i ) { *p++ = '.'; } } break; } } case ':': { //if ( f [ 1 ] == 'p' ) { // %: - mac address (6 bytes) _byte * a = va_arg ( list, _byte * ); for ( int i = 6; i--; ) { _byte x = *a++; for ( int tmp = 2; tmp--; ) { _byte c = x >> 4; x <<= 4; c = c < 10 ? c + '0' : c - 10 + 'A'; *p++ = c; } if ( i ) { *p++ = ':'; } } break; } } default: if ( *f ) { *p++ = *f; } } } *p++ = '\r'; *p++ = '\n'; *p++ = 0; p = new char [ Strlen ( buff ) + 1 ]; if ( p ) { Memcpy ( p, buff, Strlen ( buff ) + 1 ); delete [] buff; return p; } return buff; } //--------------------------------------------------------------------------- char * Ip2Text ( char * txt, _IP Ip ) { // but our SPrintf have %I option to print IPv4 Addresses int a = ( Ip >> 24 ) & 0xff; int b = ( Ip >> 16 ) & 0xff; int c = ( Ip >> 8 ) & 0xff; int d = Ip & 0xff; char p [ MAX_IP_TEXT + 2 ]; *p = 0; CDrvSprintf ( p, "%d.%d.%d.%d", a, b, c, d ); while ( *p && ( p [ Strlen ( p ) - 1 ] == '\r' || p [ Strlen ( p ) - 1 ] == '\n' ) ) { p [ Strlen ( p ) - 1 ] = 0; } Memcpy ( txt, p, Strlen ( p ) + 1 ); return txt; } //--------------------------------------------------------------------------- #endif //!__unix__ //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- int Impossible () { int * x = (int *)-1; return *x; } //---------------------------------------------------------------------------