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

模拟服务器

开发平台:

C/C++

  1. // S3Relay.cpp : Defines the entry point for the application.
  2. //
  3. #include "stdafx.h"
  4. #include <objbase.h>
  5. #include <initguid.h>  // Include only once in your application
  6. #include "../../Multiserver/Heaven/Interface/IServer.h"
  7. #include "../../Multiserver/Rainbow/Interface/IClient.h"
  8. #include "S3Relay.h"
  9. #include "Global.h"
  10. #include "time.h"
  11. #include "LogFile.h"
  12. static CLockSRSW gs_lockRecv;
  13. static CLockSRSW gs_lockSend;
  14. static size_t gs_recvdatasize = 0;
  15. static size_t gs_senddatasize = 0;
  16. static BOOL gs_initialized = FALSE;
  17. static CLogFile gs_LogFile;
  18. /////////////////////////////////////////////////
  19. const char log_directory[] = "relay_log";
  20. const size_t log_threshold = 1024 * 1024;
  21. const UINT elapse_log = 3000;
  22. /////////////////////////////////////////////////
  23. void gTrackRecvData(const void* pData, size_t size)
  24. {
  25. AUTOLOCKWRITE(gs_lockRecv);
  26. gs_recvdatasize += size;
  27. }
  28. void gTrackSendData(const void* pData, size_t size)
  29. {
  30. AUTOLOCKWRITE(gs_lockSend);
  31. gs_senddatasize += size;
  32. }
  33. size_t gGetRecvDataSize()
  34. {
  35. AUTOLOCKREAD(gs_lockRecv);
  36. return gs_recvdatasize;
  37. }
  38. size_t gGetSendDataSize()
  39. {
  40. AUTOLOCKREAD(gs_lockSend);
  41. return gs_senddatasize;
  42. }
  43. #define MAX_LOADSTRING 100
  44. // Global Variables:
  45. HINSTANCE hInst; // current instance
  46. TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
  47. TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
  48. // Foward declarations of functions included in this code module:
  49. ATOM MyRegisterClass(HINSTANCE hInstance);
  50. BOOL InitInstance(HINSTANCE, int);
  51. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  52. LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
  53. LRESULT CALLBACK Login(HWND, UINT, WPARAM, LPARAM);
  54. std::_tstring g_rootloginname;
  55. std::_tstring g_rootloginpswd;
  56. BOOL g_interrupt = FALSE;
  57. HWND g_mainwnd = NULL;
  58. HWND g_listwnd = NULL;
  59. static inline sLogProgram(BOOL bEnter)
  60. {
  61. SYSTEMTIME systm;
  62. ::GetLocalTime(&systm);
  63. TCHAR buff[256];
  64. int len = 0;
  65. if (bEnter)
  66. len = _stprintf(buff, "rn*rn***** S3Relay Start (@ %04d/%02d/%02d %02d:%02d:%02d.%03d) >>>>>rn*rnrn",
  67. systm.wYear, systm.wMonth, systm.wDay, systm.wHour, systm.wMinute, systm.wSecond, systm.wMilliseconds);
  68. else
  69. len = _stprintf(buff, "rn*rn***** S3Relay Stop (@ %04d/%02d/%02d %02d:%02d:%02d.%03d) <<<<<rn*rnrn",
  70. systm.wYear, systm.wMonth, systm.wDay, systm.wHour, systm.wMinute, systm.wSecond, systm.wMilliseconds);
  71. gs_LogFile.TraceLog(buff, len * sizeof(TCHAR));
  72. }
  73. int APIENTRY WinMain(HINSTANCE hInstance,
  74.                      HINSTANCE hPrevInstance,
  75.                      LPSTR     lpCmdLine,
  76.                      int       nCmdShow)
  77. {
  78. try
  79. {
  80. //user input root login name & pswd
  81. ::DialogBox(hInstance, (LPCTSTR)IDD_DIALOG_ROOTLOGIN, NULL, (DLGPROC)Login);
  82. if (g_interrupt)
  83. return FALSE;
  84. std::_tstring strLogDir = gGetLocateDirectory() + log_directory;
  85. ::CreateDirectory(strLogDir.c_str(), NULL);
  86. if (!gs_LogFile.Initialize(strLogDir, log_threshold))
  87. {
  88. ::MessageBox(NULL, "Initializing LogFile fail", "error", MB_OK|MB_ICONERROR);
  89. return FALSE;
  90. }
  91. //the program enter
  92. sLogProgram(TRUE);
  93.   // TODO: Place code here.
  94. int retMain = 0;
  95. MSG msg;
  96. HACCEL hAccelTable;
  97. // Initialize global strings
  98. LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
  99. LoadString(hInstance, IDC_S3RELAY, szWindowClass, MAX_LOADSTRING);
  100. MyRegisterClass(hInstance);
  101. if (InitInstance (hInstance, nCmdShow))
  102. {
  103. // Perform application initialization:
  104. {
  105. hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_S3RELAY);
  106. // Main message loop:
  107. while (GetMessage(&msg, NULL, 0, 0)) 
  108. {
  109. if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
  110. {
  111. TranslateMessage(&msg);
  112. DispatchMessage(&msg);
  113. }
  114. }
  115. }
  116. retMain = msg.wParam;
  117. }
  118. //the program exit
  119. sLogProgram(FALSE);
  120. gs_LogFile.Uninitialize();
  121. return retMain;
  122. }
  123. catch (...)
  124. {
  125. ::MessageBox(NULL, "X state occur !", "error", MB_OK|MB_ICONERROR);
  126. return FALSE;
  127. }
  128. }
  129. class TwoFixBuffer
  130. {
  131. protected:
  132. #define MAX_BUFFER_LEN 1024 * 1024
  133. struct CSBuffer
  134. {
  135. BYTE buff[MAX_BUFFER_LEN + sizeof(DWORD)];
  136. DWORD nInfoStart;
  137. };
  138. CSBuffer m_RW_Buffer[2];
  139. int m_nRead;
  140. int m_nWrite;
  141. CRITICAL_SECTION m_switchsect;
  142. BOOL HasWriteInfo()
  143. {
  144. return m_RW_Buffer[m_nWrite].nInfoStart > 0;
  145. }
  146. BOOL HasReadInfo()
  147. {
  148. DWORD* pLen = (DWORD*)(m_RW_Buffer[m_nRead].buff + m_RW_Buffer[m_nRead].nInfoStart);
  149. return  *pLen != 0;
  150. }
  151. public:
  152. TwoFixBuffer()
  153. {
  154. ::InitializeCriticalSection(&m_switchsect);
  155. for (int n = 0; n < 2; n++)
  156. {
  157. memset(m_RW_Buffer[n].buff, 0, MAX_BUFFER_LEN + sizeof(DWORD));
  158. m_RW_Buffer[n].nInfoStart = 0;
  159. }
  160. m_nRead = 0;
  161. m_nWrite = 1;
  162. }
  163. ~TwoFixBuffer()
  164. {
  165. ::LeaveCriticalSection(&m_switchsect);
  166. ::DeleteCriticalSection(&m_switchsect);
  167. }
  168. //WriteInfo可以多个线程使用
  169. //其中nLen指内存长度
  170. BOOL WriteInfo(BYTE* szInfo, DWORD nLen)
  171. {
  172. if (nLen <= 0 || szInfo == NULL)
  173. return FALSE;
  174. ::EnterCriticalSection(&m_switchsect);
  175. BOOL bCanAdd = FALSE;
  176. DWORD nMemLen = nLen + sizeof(DWORD);
  177. DWORD nInfoStart = m_RW_Buffer[m_nWrite].nInfoStart;
  178. if (nInfoStart < MAX_BUFFER_LEN - nMemLen)
  179. {
  180. memcpy(m_RW_Buffer[m_nWrite].buff + nInfoStart, &nLen, sizeof(DWORD));
  181. memcpy(m_RW_Buffer[m_nWrite].buff + nInfoStart + sizeof(DWORD), szInfo, nLen);
  182. m_RW_Buffer[m_nWrite].nInfoStart += nMemLen;
  183. bCanAdd = TRUE;
  184. DWORD* pLen = (DWORD*)(m_RW_Buffer[m_nWrite].buff + nInfoStart + nMemLen);
  185. *pLen = 0;
  186. }
  187. ::LeaveCriticalSection(&m_switchsect);
  188. return bCanAdd;
  189. }
  190. //ReadInfo只能一个线程访问
  191. BYTE* ReadInfo()
  192. {
  193. BYTE* pInfo = NULL;
  194. if (HasReadInfo())
  195. {
  196. pInfo = m_RW_Buffer[m_nRead].buff + m_RW_Buffer[m_nRead].nInfoStart;
  197. DWORD nLen = *((DWORD*)pInfo);
  198. m_RW_Buffer[m_nRead].nInfoStart += nLen + sizeof(DWORD);
  199. }
  200. return pInfo;
  201. }
  202. void SwitchReadWrite()
  203. {
  204. if (!HasReadInfo() && HasWriteInfo())
  205. {
  206. ::EnterCriticalSection(&m_switchsect);
  207. //first clear read buffer
  208. m_RW_Buffer[m_nRead].nInfoStart = 0;
  209. DWORD* pLen = (DWORD*)m_RW_Buffer[m_nRead].buff;
  210. *pLen = 0;
  211. //switch read buffer and write buffer
  212. DWORD nTemp = m_nRead;
  213. m_nRead = m_nWrite;
  214. m_nWrite = nTemp;
  215. //read from head
  216. m_RW_Buffer[m_nRead].nInfoStart = 0;
  217. ::LeaveCriticalSection(&m_switchsect);
  218. }
  219. }
  220. };
  221. TwoFixBuffer g_TraceBuffer;
  222. long g_cnt = 0;
  223. int gTrace(LPCSTR fmt, ...)
  224. {
  225. if (g_listwnd == NULL)
  226. return -1;
  227. TCHAR tempbuff[256];
  228. g_cnt++;
  229. sprintf(tempbuff, "%d -- ", g_cnt);
  230. int n = strlen(tempbuff);
  231. va_list marker;
  232. va_start( marker, fmt );
  233. _vstprintf(tempbuff + n, fmt, marker);
  234. va_end( marker );
  235. n = strlen(tempbuff);
  236. g_TraceBuffer.WriteInfo((BYTE*)tempbuff, n + 1); //带0写入
  237. return 0;
  238. }
  239. //
  240. //  FUNCTION: MyRegisterClass()
  241. //
  242. //  PURPOSE: Registers the window class.
  243. //
  244. //  COMMENTS:
  245. //
  246. //    This function and its usage is only necessary if you want this code
  247. //    to be compatible with Win32 systems prior to the 'RegisterClassEx'
  248. //    function that was added to Windows 95. It is important to call this function
  249. //    so that the application will get 'well formed' small icons associated
  250. //    with it.
  251. //
  252. ATOM MyRegisterClass(HINSTANCE hInstance)
  253. {
  254. WNDCLASSEX wcex;
  255. wcex.cbSize = sizeof(WNDCLASSEX); 
  256. wcex.style = CS_HREDRAW | CS_VREDRAW;
  257. wcex.lpfnWndProc = (WNDPROC)WndProc;
  258. wcex.cbClsExtra = 0;
  259. wcex.cbWndExtra = 0;
  260. wcex.hInstance = hInstance;
  261. wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_S3RELAY);
  262. wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
  263. wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  264. wcex.lpszMenuName = (LPCSTR)IDC_S3RELAY;
  265. wcex.lpszClassName = szWindowClass;
  266. wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
  267. return RegisterClassEx(&wcex);
  268. }
  269. int gTimeStamp(char* sDest, char* pTail)
  270. {
  271. assert(sDest);
  272. time_t curtm = ::time(NULL);
  273. struct tm* ptm = localtime(&curtm);
  274. return sprintf(sDest, "[%04d/%02d/%02d %02d:%02d:%02d]%s",
  275. ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, pTail);
  276. }
  277. void gTraceLogFile(LPCTSTR pBuffer, long nLen)
  278. {
  279. if (!gs_LogFile.BeginBatch())
  280. return;
  281. char szTime[128];
  282. int nTime = gTimeStamp(szTime, " ");
  283. gs_LogFile.TraceLog(szTime, nTime);
  284. gs_LogFile.TraceLog(pBuffer, nLen);
  285. gs_LogFile.TraceLog(_T("rn"), 2 * sizeof(TCHAR));
  286. gs_LogFile.EndBatch();
  287. }
  288. void gClearTrace()
  289. {
  290. if (g_listwnd)
  291. ::SendMessage(g_listwnd, LB_RESETCONTENT, 0, 0);
  292. }
  293. void gShowTrace()
  294. {
  295. if (!g_listwnd)
  296. return;
  297. static BOOL bLastRead = FALSE;
  298. char* pBuff = NULL;
  299. DWORD* pMem = NULL;
  300. int nPercent = 0;
  301. int n1 = ::SendMessage(g_listwnd, LB_GETCOUNT, 0, 0);
  302. int cursel = ::SendMessage(g_listwnd, LB_GETCURSEL, 0, 0);
  303. BOOL isTrack = cursel < 0 || cursel + 1 >= n1;
  304. int n = n1;
  305. while (1)
  306. {
  307. pMem = (DWORD*)g_TraceBuffer.ReadInfo();
  308. if (pMem)
  309. {
  310. pBuff = (char*)(pMem + 1);
  311. if (n > 0 && n % 8100 == 0)
  312. {
  313. ::SendMessage(g_listwnd, LB_DELETESTRING, 0, NULL);
  314. }
  315. if (::SendMessage(g_listwnd, LB_ADDSTRING, 0, (LPARAM)pBuff) >= 0)
  316. n++;
  317. gTraceLogFile(pBuff, (*pMem) - 1); //去0写文件
  318. }
  319. else
  320. break;
  321. }
  322. if (isTrack && n > n1)
  323. {
  324. ::SendMessage(g_listwnd, LB_SETCURSEL, (WPARAM)n - 1, 0);
  325. }
  326. g_TraceBuffer.SwitchReadWrite();
  327. }
  328. int g_nShowTime = 0;
  329. //
  330. //   FUNCTION: InitInstance(HANDLE, int)
  331. //
  332. //   PURPOSE: Saves instance handle and creates main window
  333. //
  334. //   COMMENTS:
  335. //
  336. //        In this function, we save the instance handle in a global variable and
  337. //        create and display the main program window.
  338. //
  339. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  340. {
  341.    hInst = hInstance; // Store instance handle in our global variable
  342.    g_mainwnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
  343.       CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
  344.    if (!g_mainwnd)
  345.    {
  346.       return FALSE;
  347.    }
  348.    RECT rc = {0};
  349.    GetClientRect(g_mainwnd, &rc);
  350.    g_listwnd = ::CreateWindow("ListBox", "Out", WS_CHILD|WS_VISIBLE|WS_VSCROLL|WS_HSCROLL|LBS_NOINTEGRALHEIGHT, 0, 0, rc.right, rc.bottom, g_mainwnd, NULL, hInst, NULL);
  351.    if (!g_listwnd)
  352.    return FALSE;
  353.    ShowWindow(g_mainwnd, nCmdShow);
  354.    UpdateWindow(g_mainwnd);
  355. //gTraceLogFile(tempbuff, strlen(tempbuff));
  356. g_nShowTime = SetTimer(g_mainwnd, timer_log, elapse_log, NULL);
  357. //auto startup
  358. ::SendMessage(g_mainwnd, WM_COMMAND, MAKEWPARAM(IDM_STARTUP, 0), NULL);
  359. gShowTrace();
  360. gShowTrace();
  361.    return TRUE;
  362. }
  363. //
  364. //  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
  365. //
  366. //  PURPOSE:  Processes messages for the main window.
  367. //
  368. //  WM_COMMAND - process the application menu
  369. //  WM_PAINT - Paint the main window
  370. //  WM_DESTROY - post a quit message and return
  371. //
  372. //
  373. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  374. {
  375. int wmId, wmEvent;
  376. PAINTSTRUCT ps;
  377. HDC hdc;
  378. TCHAR szHello[MAX_LOADSTRING];
  379. LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
  380. switch (message) 
  381. {
  382. case WM_COMMAND:
  383. wmId    = LOWORD(wParam); 
  384. wmEvent = HIWORD(wParam); 
  385. // Parse the menu selections:
  386. switch (wmId)
  387. {
  388. case IDM_ABOUT:
  389.    DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
  390.    break;
  391. case IDM_EXIT:
  392.    SendMessage(hWnd, WM_CLOSE, 0, 0);
  393.    break;
  394. case IDM_CLEAR_TRACE:
  395. ::SendMessage(g_listwnd, LB_RESETCONTENT, 0, 0);
  396. break;
  397. case IDM_UPDATE_TRACE:
  398. gShowTrace();
  399. gShowTrace();
  400. break;
  401. case IDM_TRACE_HOSTSERVER: g_HostServer.TraceInfo(); break;
  402. case IDM_TRACE_CHATSERVER: g_ChatServer.TraceInfo(); break;
  403. case IDM_TRACE_TONGSERVER: g_TongServer.TraceInfo(); break;
  404. case IDM_TRACE_RELAYSERVER: g_RelayServer.TraceInfo(); break;
  405. case IDM_TRACE_ROOTCENTER: g_RootCenter.TraceInfo(); break;
  406. case IDM_TRACE_GATEWAYCENTER: g_GatewayCenter.TraceInfo(); break;
  407. case IDM_TRACE_DBROLECENTER: g_DBCenter.TraceInfo(); break;
  408. case IDM_TRACE_RELAYCENTER: g_RelayCenter.TraceInfo(); break;
  409. case IDM_TRACE_PLAYER_DETAIL: g_HostServer.TracePlayer(); break;
  410. case IDM_TRACE_PLAYER:
  411. rTRACE("message: online player total: %d", g_HostServer.GetPlayerCount());
  412. break;
  413. case IDM_TRACE_FRIENDPLAYER:
  414. rTRACE("message: friend player total: %d", g_FriendMgr.GetPlayerCount());
  415. break;
  416. case IDM_TRACE_FRIENDAFQS:
  417. rTRACE("message: friend AFQS: %d", g_FriendMgr.GetAFQSize());
  418. break;
  419. case IDM_TRACE_STATUS:
  420. rTRACE("message: [0] RootClient: %d, GatewayClient: %d, DBRoleClient: %d",
  421. g_RootCenter.GetClientCount(), g_GatewayCenter.GetClientCount(), g_DBCenter.GetClientCount());
  422. rTRACE("message: [1] RelayClient: %d, RelayConnect: %d",
  423. g_RelayCenter.GetClientCount(), g_RelayServer.GetConnectCount());
  424. rTRACE("message: [2] HostConnect: %d, ChatConnect: %d, TongConnect: %d",
  425. g_HostServer.GetConnectCount(), g_ChatServer.GetConnectCount(), g_TongServer.GetConnectCount());
  426. break;
  427. case IDM_TRACE_SOCKTHREAD:
  428. g_threadSock.TraceInfo();
  429. break;
  430. case IDM_TRACE_DATASIZE:
  431. dTRACE("message: recvsum: %ld B, sendsum: %ld B", gGetRecvDataSize(), gGetSendDataSize());
  432. break;
  433. case IDM_TRACE_MAC:
  434. {{
  435. std::_tstring descLocal;
  436. {{
  437. size_t lenLocal = 0;
  438. const UCHAR* macLocal = gGetHostMac(local_adapt, &lenLocal);
  439. for (int i = 0; i < lenLocal; i++)
  440. {
  441. char buff[3];
  442. _stprintf(buff, "%02X", macLocal[i]);
  443. if (i > 0)
  444. descLocal += '-';
  445. descLocal += buff;
  446. }
  447. }}
  448. std::_tstring descGlobal;
  449. {{
  450. size_t lenGlobal = 0;
  451. const UCHAR* macGlobal = gGetHostMac(global_adapt, &lenGlobal);
  452. for (int i = 0; i < lenGlobal; i++)
  453. {
  454. char buff[3];
  455. _stprintf(buff, "%02X", macGlobal[i]);
  456. if (i > 0)
  457. descGlobal += '-';
  458. descGlobal += buff;
  459. }
  460. }}
  461. rTRACE("message: localMAC: %s, globalMAC: %s", descLocal.c_str(), descGlobal.c_str());
  462. }}
  463. break;
  464. case IDM_TRACE_IP:
  465. rTRACE("message: localIP: 0x%08X (%s), globalIP: 0x%08X (%s)", gGetHostIP(local_adapt), std::_tstring(_ip2a(gGetHostIP(local_adapt))).c_str(), gGetHostIP(global_adapt), std::_tstring(_ip2a(gGetHostIP(global_adapt))).c_str());
  466. break;
  467. case IDM_STARTUP:
  468. if (gs_initialized)
  469. rTRACE("waring: already Initialized");
  470. else
  471. {
  472. rTRACE("Initializing ...");
  473. if (gInitialize())
  474. {
  475. gs_initialized = TRUE;
  476. rTRACE("Initialize OK");
  477. }
  478. else
  479. {
  480. gUninitialize();
  481. rTRACE("error: Initialize FAIL");
  482. }
  483. }
  484. break;
  485. case IDM_SHUTDOWN:
  486. if (!gs_initialized)
  487. {
  488. rTRACE("waring: already Uninitialized");
  489. gUninitialize();
  490. }
  491. else
  492. {
  493. rTRACE("Uninitializing ...");
  494. gUninitialize();
  495. gs_initialized = FALSE;
  496. rTRACE("Uninitialize OK");
  497. }
  498. break;
  499. default:
  500.    return DefWindowProc(hWnd, message, wParam, lParam);
  501. }
  502. break;
  503. case WM_PAINT:
  504. hdc = BeginPaint(hWnd, &ps);
  505. EndPaint(hWnd, &ps);
  506. break;
  507. case WM_DESTROY:
  508. //auto shutdown
  509. ::SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(IDM_SHUTDOWN, 0), NULL);
  510. if (g_nShowTime)
  511. KillTimer(hWnd, g_nShowTime);
  512. gShowTrace();
  513. gShowTrace();
  514. PostQuitMessage(0);
  515. break;
  516. case WM_CLOSE:
  517. if (::MessageBox(hWnd, "Are you sure ?", "warning", MB_YESNO) == IDYES)
  518. {
  519. DestroyWindow(hWnd);
  520. }
  521. break;
  522. case WM_SIZE:
  523. {
  524. RECT rc;
  525. GetClientRect(hWnd, &rc);
  526. MoveWindow(g_listwnd, 0, 0, rc.right, rc.bottom, TRUE);
  527. }
  528. break;
  529. case WM_TIMER:
  530. switch (wParam)
  531. {
  532. case timer_log: gShowTrace(); break;
  533. case timer_rootclient: gReOneClient(oneclient_root); break;
  534. case timer_gatewayclient: gReOneClient(oneclient_gateway); break;
  535. case timer_dbclient: gReOneClient(oneclient_db); break;
  536. case timer_friendudtdb: gFriendTimingUpdateDB(); break;
  537. default: break;
  538. }
  539. break;
  540. case UM_CONSIGNCLIENTSD:
  541. {{
  542. IClient* pClient = (IClient*)wParam;
  543. if (pClient)
  544. {
  545. //pClient->Shutdown();
  546. pClient->Cleanup();
  547. pClient->Release();
  548. }
  549. }}
  550. break;
  551. default:
  552. return DefWindowProc(hWnd, message, wParam, lParam);
  553.    }
  554.    return 0;
  555. }
  556. // Mesage handler for about box.
  557. LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  558. {
  559. switch (message)
  560. {
  561. case WM_INITDIALOG:
  562. return TRUE;
  563. case WM_COMMAND:
  564. if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
  565. {
  566. EndDialog(hDlg, LOWORD(wParam));
  567. return TRUE;
  568. }
  569. break;
  570. }
  571.     return FALSE;
  572. }
  573. // Mesage handler for login box.
  574. LRESULT CALLBACK Login(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  575. {
  576. switch (message)
  577. {
  578. case WM_INITDIALOG:
  579. return TRUE;
  580. case WM_COMMAND:
  581. {{
  582. TCHAR buffer[_MAX_PATH];
  583. switch (wParam)
  584. {
  585. case IDOK:
  586. ::GetDlgItemText(hDlg, IDC_EDIT_NAME, buffer, _MAX_PATH);
  587. g_rootloginname = buffer;
  588. ::GetDlgItemText(hDlg, IDC_EDIT_PSWD, buffer, _MAX_PATH);
  589. g_rootloginpswd = buffer;
  590. EndDialog(hDlg, LOWORD(wParam));
  591. return TRUE;
  592. case IDCANCEL:
  593. g_interrupt = TRUE;
  594. EndDialog(hDlg, LOWORD(wParam));
  595. return TRUE;
  596. }
  597. }}
  598. break;
  599. }
  600.     return FALSE;
  601. }
  602. HWND gGetMainWnd()
  603. {
  604. return g_mainwnd;
  605. }
  606. HWND gGetListBox()
  607. {
  608. return g_listwnd;
  609. }