Utils.cpp
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:13k
源码类别:

模拟服务器

开发平台:

C/C++

  1. #include "stdafx.h"
  2. #include "Utils.h"
  3. #include "Exception.h"
  4. #include "CriticalSection.h"
  5. #include "Macro.h"
  6. #include <memory>
  7. #include <iostream>
  8. #include <fstream>
  9. #include <conio.h>
  10. #ifdef _UNICODE
  11. typedef std::wfstream _tfstream;
  12. #else
  13. typedef std::fstream _tfstream;
  14. #endif
  15. #include "Lmcons.h"     // define UNLEN
  16. #define HOSTNAME_SIZE MAX_PATH
  17. /*
  18.  * Using directives
  19.  */
  20. using std::auto_ptr;
  21. using std::endl;
  22. /*
  23.  * namespace OnlineGameLib::Win32
  24.  */
  25. namespace OnlineGameLib {
  26. namespace Win32 {
  27. CCriticalSection s_criticalSection;
  28. static _tfstream s_debugOut;
  29. static std::string s_logFileName = "\common.log";
  30. void SetLogFileName( const _tstring &name )
  31. {
  32. USES_CONVERSION;
  33. if ( s_debugOut.is_open() )
  34. {
  35. s_debugOut.close();
  36. }
  37. s_logFileName = T2A( const_cast< PTSTR >( name.c_str() ) );
  38. }
  39. void Message( const char * const pInfo )
  40. {
  41. if ( pInfo )
  42. {
  43. ::MessageBeep( -1 );
  44. ::MessageBox( NULL, pInfo, "Info", MB_ICONINFORMATION );
  45. }
  46. }
  47. void Output( const _tstring &message )
  48. {
  49. return;
  50. #ifdef _DEBUG
  51. CCriticalSection::Owner lock( s_criticalSection );
  52. #ifdef _UNICODE
  53. std::wcout << ToString( GetCurrentThreadId() ) << _T(": ") << message << endl;
  54. #else
  55. std::cout << ToString( GetCurrentThreadId() ) << _T(": ") << message << endl;
  56. #endif
  57. const _tstring msg = ToString(GetCurrentThreadId()) + _T(": ") + message + _T("n");
  58. ::OutputDebugString( msg.c_str() );
  59. /* if (!s_debugOut.is_open())
  60. {
  61. s_debugOut.open(s_logFileName.c_str(), std::ios_base::out | std::ios_base::app);
  62. s_debugOut << _T("=======================================") << endl;
  63. }
  64. */
  65. s_debugOut <<  ToString( GetCurrentThreadId() ) << _T(": ") << message << endl;
  66. #else
  67.    // NULL
  68. #endif //_DEBUG
  69. }
  70. void Trace( const _tstring &progID, const _tstring &message )
  71. {
  72. #ifdef _DEBUG
  73. const _tstring msg = ToString(GetCurrentThreadId()) + _T(" [") + progID + _T("] ") + message + _T("n");
  74. cprintf( msg.c_str() );
  75. #endif
  76. }
  77. _tstring GetLastErrorMessage( DWORD last_error )
  78. {
  79. TCHAR errmsg[512];
  80. if ( !FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 
  81.   0,
  82.   last_error,
  83.   0,
  84.   errmsg, 
  85.   511,
  86.   NULL) )
  87. {
  88. /*
  89.  * if we fail, call ourself to find out why and return that error 
  90.  */
  91. return ( GetLastErrorMessage( GetLastError() ) );  
  92. }
  93.   
  94. return ( _tstring )errmsg;
  95. }
  96. _tstring HexToString( const BYTE *pBuffer, size_t iBytes )
  97. {
  98. _tstring result;
  99.      
  100. for ( size_t i = 0; i < iBytes; i++ )
  101. {
  102. BYTE c ;
  103. BYTE b = pBuffer[i] >> 4;
  104. if ( 9 >= b )
  105. {
  106. c = b + '0';
  107. }
  108. else
  109. {
  110. c = ( b - 10 ) + 'A';
  111. }
  112. result += (TCHAR)c;
  113. b = pBuffer[i] & 0x0f;
  114. if ( 9 >= b )
  115. {
  116. c = b + '0';
  117. }
  118. else
  119. {
  120. c = ( b - 10 ) + 'A';
  121. }
  122. result += ( TCHAR )c;
  123. }
  124.    return result;
  125. }
  126. void StringToHex( const _tstring &ts, BYTE *pBuffer, size_t nBytes )
  127. {
  128. USES_CONVERSION;
  129. const std::string s = T2A( const_cast< PTSTR >( ts.c_str() ) );
  130. for ( size_t i = 0; i < nBytes; i++ )
  131. {
  132. const size_t stringOffset = i * 2;
  133. BYTE val = 0;
  134. const BYTE b = s[stringOffset];
  135. if ( isdigit(b) )
  136. {
  137. val = ( BYTE )( (b - '0') * 16 );
  138. }
  139. else 
  140. {
  141. val = ( BYTE )( ( ( toupper(b) - 'A') + 10 ) * 16 ); 
  142. }
  143. const BYTE b1 = s[stringOffset + 1];
  144. if ( isdigit( b1 ) )
  145. {
  146. val += b1 - '0' ; 
  147. }
  148. else 
  149. {
  150. val += ( BYTE )( ( toupper(b1) - 'A' ) + 10 );
  151. }
  152. pBuffer[i] = val;
  153. }
  154. }
  155. DWORD HexStringToDWORD( LPCTSTR lpString )
  156. {
  157. int nLen = strlen( lpString );
  158. DWORD dwValue = 0;
  159. for( int i = 0; i < nLen; i++ )
  160. {
  161. dwValue = dwValue*16;
  162. char c = *( lpString+i );
  163. if ( c >= '0' && c <= '9' )
  164. {
  165. dwValue = dwValue + c - '0';
  166. }
  167. else if( c >= 'a' && c <= 'f' )
  168. {
  169. dwValue = dwValue + c - 'a' + 10;
  170. }
  171. else if( c >= 'A' && c <= 'F' )
  172. {
  173. dwValue = dwValue + c - 'A' + 10;
  174. }
  175. else
  176. {
  177. ASSERT( FALSE );
  178. }
  179. }
  180. return dwValue;
  181. }
  182. DWORD HashStr2ID( const char * const pStr )
  183. {
  184. if ( pStr )
  185. {
  186. DWORD dwID = 0;
  187. for ( int i = 0; pStr[i]; i++ )
  188. {
  189. dwID = ( dwID + ( i + 1 ) * pStr[i] ) % 0x8000000B * 0xFFFFFFEF;
  190. }
  191. return ( dwID ^ 0x12345678 );
  192. }
  193. return ( DWORD )( -1 );
  194. }
  195. unsigned long net_aton( const char *pAddr )
  196. {
  197. static char szAddr[16];
  198. static char seps[] = " .";
  199. char *token = NULL;
  200. unsigned long lnAddr = 0;
  201. unsigned long lnSeg = 0;
  202. int nPos = 0;
  203. if ( !pAddr )
  204. {
  205. return 0;
  206. }
  207. size_t len = strlen( pAddr );
  208. len = ( len > 15 ) ? 15 : len;
  209. memcpy( szAddr, pAddr, len );
  210. szAddr[len] = '';
  211. token = strtok( szAddr, seps );
  212. while( token != NULL && nPos < 4 )
  213. {
  214. /*
  215.  * While there are tokens in "string"
  216.  */
  217. lnSeg = atoi( token );
  218. lnAddr |= ( lnSeg & 0xFF ) << ( nPos * 8 );
  219. /*
  220.  * Get next token
  221.  */
  222. token = strtok( NULL, seps );
  223. nPos ++;
  224.    }
  225. return lnAddr;
  226. }
  227. const char *net_ntoa( unsigned long lnAddr )
  228. {
  229. static char szAddr[16];
  230. unsigned long lnSeg = lnAddr;
  231. sprintf( szAddr, 
  232. "%u.%u.%u.%u", 
  233. lnAddr & 0xFF,
  234. ( lnAddr >> 8 ) & 0xFF,
  235. ( lnAddr >> 16 ) & 0xFF,
  236. ( lnAddr >> 24 ) & 0xFF );
  237. szAddr[15] = '';
  238. return szAddr;
  239. }
  240. _tstring GetCurrentDirectory()
  241. {
  242. DWORD size = ::GetCurrentDirectory(0, 0);
  243. auto_ptr<TCHAR> spBuf( new TCHAR[size] );
  244. if ( 0 == ::GetCurrentDirectory( size, spBuf.get() ) )
  245. {
  246. throw CException( _T("GetCurrentDirectory()"), _T("Failed to get current directory") );
  247. }
  248. return _tstring( spBuf.get() );
  249. }
  250. _tstring GetAppFullPath( HINSTANCE hInst )
  251. {
  252. static bool gotName = false;
  253. static _tstring name;
  254. if (!gotName)
  255. {
  256. TCHAR moduleFileName[MAX_PATH + 1] ;
  257. DWORD moduleFileNameLen = MAX_PATH ;
  258. if ( ::GetModuleFileName( hInst, moduleFileName, moduleFileNameLen ) )
  259. {
  260. int nLen = strlen( moduleFileName );
  261. while ( nLen -- > 0 )
  262. {
  263. if ( '\' == moduleFileName[nLen] )
  264. {
  265. moduleFileName[nLen+1] = '';
  266. break;
  267. }
  268. }
  269. name = moduleFileName;
  270. }
  271. gotName = true;
  272. }
  273. return name;
  274. }
  275. _tstring GetDateStamp()
  276. {
  277. SYSTEMTIME systime;
  278. GetSystemTime( &systime );
  279. static TCHAR buffer[7];
  280. _stprintf(buffer, _T("%02d%02d%02d"),
  281. systime.wDay,
  282. systime.wMonth,
  283. ( 1900 + systime.wYear) % 100);
  284. return buffer;
  285. }
  286. _tstring GetTimeStamp()
  287. {
  288. SYSTEMTIME systime;
  289. GetLocalTime(&systime);
  290. static TCHAR buffer[9];
  291. _stprintf( buffer, _T("%02d:%02d:%02d"),
  292. systime.wHour,
  293. systime.wMinute,
  294. systime.wSecond );
  295. return buffer;
  296. }
  297. _tstring ToHex( BYTE c )
  298. {
  299. TCHAR hex[3];
  300. const int val = c;
  301. _stprintf( hex, _T("%02X"), val );
  302. return hex;
  303. }
  304. _tstring DumpData( const BYTE * const pData, size_t dataLength, size_t lineLength /* = 0 */ )
  305. {
  306. const size_t bytesPerLine = lineLength != 0 ? (lineLength - 1) / 3 : 0;
  307. _tstring result;
  308. _tstring hexDisplay;
  309. _tstring display;
  310. size_t i = 0;
  311. while ( i < dataLength )
  312. {
  313. const BYTE c = pData[i++];
  314. hexDisplay += ToHex( c ) + _T(" ");
  315. if ( isprint( c ) )
  316. {
  317. display += (TCHAR)c;
  318. }
  319. else
  320. {
  321. display += _T('.');
  322. }
  323. if ( ( bytesPerLine && ( i % bytesPerLine == 0 && i != 0 ) ) || i == dataLength )
  324. {
  325. if ( i == dataLength && ( bytesPerLine && ( i % bytesPerLine != 0 ) ) )
  326. {
  327. for ( size_t pad = i % bytesPerLine; pad < bytesPerLine; pad++ )
  328. {
  329. hexDisplay += _T("   ");
  330. }
  331. }
  332. result += hexDisplay + _T(" - ") + display + _T("n");
  333. hexDisplay = _T("");
  334. display = _T("");
  335. }
  336. }
  337. return result;
  338. }
  339. _tstring GetComputerName()
  340. {
  341. static bool gotName = false;
  342. static _tstring name = _T("UNAVAILABLE");
  343. if ( !gotName )
  344. {
  345. TCHAR computerName[MAX_COMPUTERNAME_LENGTH + 1] ;
  346. DWORD computerNameLen = MAX_COMPUTERNAME_LENGTH ;
  347. if ( ::GetComputerName( computerName, &computerNameLen ) )
  348. {
  349. name = computerName;
  350. }
  351. gotName = true;
  352. }
  353. return name;
  354. }
  355. _tstring GetModuleFileName( HINSTANCE hModule /* = 0 */ )
  356. {
  357. static bool gotName = false;
  358. static _tstring name = _T("UNAVAILABLE");
  359. if (!gotName)
  360. {
  361. TCHAR moduleFileName[MAX_PATH + 1] ;
  362. DWORD moduleFileNameLen = MAX_PATH ;
  363. if ( ::GetModuleFileName( hModule, moduleFileName, moduleFileNameLen ) )
  364. {
  365. name = moduleFileName;
  366. }
  367. gotName = true;
  368. }
  369. return name;
  370. }
  371. _tstring GetUserName()
  372. {
  373. static bool gotName = false;
  374. static _tstring name = _T("UNAVAILABLE");
  375. if ( !gotName )
  376. {
  377. TCHAR userName[UNLEN + 1] ;
  378. DWORD userNameLen = UNLEN;
  379. if ( ::GetUserName( userName, &userNameLen ) )
  380. {
  381. name = userName;
  382. }
  383. gotName = true;
  384. }
  385. return name;
  386. }
  387. _tstring StripLeading( const _tstring &source, const char toStrip )
  388. {
  389. const TCHAR *pSrc = source.c_str();
  390. while ( pSrc && *pSrc == toStrip )
  391. {
  392. ++pSrc;
  393. }
  394. return pSrc;
  395. }
  396. _tstring StripTrailing( const _tstring &source, const char toStrip )
  397. {
  398. size_t i = source.length();
  399. const _TCHAR *pSrc = source.c_str() + i;
  400. --pSrc;
  401. while ( i && *pSrc == toStrip )
  402. {
  403. --pSrc;
  404. --i;
  405. }
  406. return source.substr( 0, i );
  407. }
  408. #pragma comment(lib, "Version.lib")
  409. typedef struct LANGANDCODEPAGE
  410. {
  411. WORD wLanguage;
  412. WORD wCodePage;
  413. }LCP, NEAR *PLCP, FAR *LPLCP;
  414. _tstring GetFileVersion()
  415. {
  416. static bool gotName = false;
  417. static _tstring version;
  418. if ( gotName )
  419. {
  420. return version;
  421. }
  422. const _tstring moduleFileName = GetModuleFileName( NULL );
  423. LPTSTR pModuleFileName = const_cast< LPTSTR >( moduleFileName.c_str() );
  424. DWORD zero = 0;
  425. DWORD verSize = ::GetFileVersionInfoSize( pModuleFileName, &zero );
  426. if ( verSize != 0 )
  427. {
  428. auto_ptr< BYTE > spBlock( new BYTE[verSize] );
  429. LPLCP lpTranslate = NULL;
  430. UINT nTranslateSize = 0;
  431. /*
  432.  * How many language in this product?
  433.  */
  434. if ( ::GetFileVersionInfo( pModuleFileName, 0, verSize, spBlock.get() ) )
  435. {    
  436. if ( ::VerQueryValue( spBlock.get(), 
  437. const_cast< LPSTR >( _T("\VarFileInfo\Translation") ),
  438. ( void ** )( &lpTranslate ),
  439. &nTranslateSize ) )
  440. {
  441. if ( ( nTranslateSize / sizeof( LCP ) ) > 0 )
  442. {
  443. CHAR szSubBlock[64];
  444. /*
  445.  * get version information from first language.
  446.  */
  447. wsprintf( szSubBlock, 
  448. TEXT( "\StringFileInfo\%04x%04x\FileVersion" ),
  449. lpTranslate[0].wLanguage,
  450. lpTranslate[0].wCodePage);
  451. auto_ptr<BYTE> spBuffer( new BYTE[verSize] );
  452. if ( ::GetFileVersionInfo( pModuleFileName, 0, verSize, spBuffer.get() ) )
  453. {
  454. LPTSTR pVersion = 0;
  455. UINT verLen = 0;
  456. if ( ::VerQueryValue( spBuffer.get(), 
  457. szSubBlock,
  458. ( void ** )( &pVersion ),
  459. &verLen ) )
  460. {
  461. version = pVersion;
  462. gotName = true;
  463. }
  464. }
  465. }
  466. }
  467. }
  468. }
  469. return version;
  470. }
  471. /*
  472.  * Get local computer name.  Something like: "mycomputer.myserver.net"
  473.  */
  474. bool GetLocalName( LPTSTR strName, UINT nSize )
  475. {
  476. if ( strName && nSize > 0 )
  477. {
  478. char strHost[HOSTNAME_SIZE] = { 0 };
  479. /*
  480.  * get host name, if fail, SetLastError is set
  481.  */
  482. if ( SOCKET_ERROR != gethostname( strHost, sizeof( strHost ) ) )
  483. {
  484. struct hostent* hp;
  485. hp = gethostbyname( strHost );
  486. if ( hp )
  487. {
  488. strcpy( strHost, hp->h_name );
  489. }
  490. /*
  491.  * check if user provide enough buffer
  492.  */
  493. if ( strlen(strHost) > nSize )
  494. {
  495. ::SetLastError( ERROR_INSUFFICIENT_BUFFER );
  496. return false;
  497. }
  498. /*
  499.  * Unicode conversion
  500.  */
  501. #ifdef _UNICODE
  502. return ( 0 != MultiByteToWideChar( CP_ACP, 
  503. 0,
  504. strHost, 
  505. -1,
  506. strName, 
  507. nSize, 
  508. NULL, 
  509. NULL ) );
  510. #else
  511. _tcscpy( strName, strHost );
  512. return true;
  513. #endif
  514. }
  515. }
  516. else
  517. {
  518. ::SetLastError( ERROR_INVALID_PARAMETER );
  519. }
  520. return false;
  521. }
  522. /*
  523.  * Get TCP address of local computer in dot format ex: "127.0.0.0"
  524.  */
  525. bool GetLocalAddress( LPTSTR strAddress, UINT nSize, int nAdapter /* 0 */ )
  526. {
  527. /*
  528.  * Get computer local address
  529.  */
  530. if ( strAddress && nSize > 0 )
  531. {
  532. CHAR strHost[HOSTNAME_SIZE] = { 0 };
  533. /*
  534.  * get host name, if fail, SetLastError is called
  535.  */
  536. if ( SOCKET_ERROR != gethostname( strHost, sizeof( strHost ) ) )
  537. {
  538. struct hostent* hp;
  539. hp = gethostbyname( strHost );
  540. if ( hp && hp->h_addr_list[nAdapter] )
  541. {
  542. /*
  543.  * Address is four bytes (32-bit)
  544.  */
  545. if ( hp->h_length < 4 )
  546. {
  547. return false;
  548. }
  549. /*
  550.  * Convert address to . format
  551.  */
  552. strHost[0] = 0;
  553. /*
  554.  * Create Address string
  555.  */
  556. sprintf( strHost, "%u.%u.%u.%u",
  557. ( UINT )( ( ( PBYTE ) hp->h_addr_list[nAdapter])[0] ),
  558. ( UINT )( ( ( PBYTE ) hp->h_addr_list[nAdapter])[1] ),
  559. ( UINT )( ( ( PBYTE ) hp->h_addr_list[nAdapter])[2] ),
  560. ( UINT )( ( ( PBYTE ) hp->h_addr_list[nAdapter])[3] ) );
  561. /*
  562.  * check if user provide enough buffer
  563.  */
  564. if ( strlen( strHost ) > nSize )
  565. {
  566. ::SetLastError( ERROR_INSUFFICIENT_BUFFER );
  567. return false;
  568. }
  569. /*
  570.  * Unicode conversion
  571.  */
  572. #ifdef _UNICODE
  573. return ( 0 != MultiByteToWideChar( CP_ACP, 
  574. 0, 
  575. strHost, 
  576. -1, 
  577. strAddress,
  578. nSize, 
  579. NULL, 
  580. NULL ) );
  581. #else
  582. _tcscpy( strAddress, strHost );
  583. return true;
  584. #endif
  585. }
  586. }
  587. }
  588. else
  589. {
  590. ::SetLastError( ERROR_INVALID_PARAMETER );
  591. }
  592. return false;
  593. }
  594. } // End of namespace OnlineGameLib
  595. } // End of namespace Win32