From cbe3cb21f5bca61a03bbd4ae811ee906e09b3f4f Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sat, 13 Jun 2015 16:55:17 +0000 Subject: - miranda32.exe now does nothing bug extends PATH to %miranda_root%\libs and loads mir_app.dll; - everything that was in miranda32.exe (including resources) moved to mir_app.dll; - exports from mir_app.dll now available for using directly, without perversions; - src/stdplug.h deleted; git-svn-id: http://svn.miranda-ng.org/main/trunk@14143 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- src/modules/netlib/netliblog.cpp | 532 --------------------------------------- 1 file changed, 532 deletions(-) delete mode 100644 src/modules/netlib/netliblog.cpp (limited to 'src/modules/netlib/netliblog.cpp') diff --git a/src/modules/netlib/netliblog.cpp b/src/modules/netlib/netliblog.cpp deleted file mode 100644 index 2d3db45941..0000000000 --- a/src/modules/netlib/netliblog.cpp +++ /dev/null @@ -1,532 +0,0 @@ -/* - -Miranda NG: the free IM client for Microsoft* Windows* - -Copyright (ñ) 2012-15 Miranda NG project (http://miranda-ng.org), -Copyright (c) 2000-12 Miranda IM project, -all portions of this codebase are copyrighted to the people -listed in contributors.txt. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include "..\..\core\commonheaders.h" -#include "netlib.h" - -#define MS_NETLIB_LOGWIN "Netlib/Log/Win" - -extern HANDLE hConnectionHeaderMutex; - -#define TIMEFORMAT_NONE 0 -#define TIMEFORMAT_HHMMSS 1 -#define TIMEFORMAT_MILLISECONDS 2 -#define TIMEFORMAT_MICROSECONDS 3 -struct { - HWND hwndOpts; - int toOutputDebugString; - int toFile; - int toLog; - int timeFormat; - int showUser; - int dumpSent, dumpRecv, dumpProxy, dumpSsl; - int textDumps, autoDetectText; - CMString tszFile, tszUserFile; -} -static logOptions = { 0 }; - -struct LOGMSG -{ - const char* pszHead; - const char* pszMsg; -}; - -static __int64 mirandaStartTime, perfCounterFreq; -static int bIsActive = TRUE; -static HANDLE hLogEvent = NULL; -static HANDLE hLogger = NULL; - -static void InitLog() -{ - if (hLogger) { - mir_closeLog(hLogger); - hLogger = NULL; - } - - ptrT szBuf(db_get_tsa(NULL, "Netlib", "File")); - if (mir_tstrlen(szBuf)) { - logOptions.tszUserFile = szBuf; - - TCHAR path[MAX_PATH]; - PathToAbsoluteT(VARST(szBuf), path); - logOptions.tszFile = path; - } - else { - db_set_ts(NULL, "Netlib", "File", logOptions.tszUserFile = _T("%miranda_logpath%\\netlog.txt")); - logOptions.tszFile = Utils_ReplaceVarsT(logOptions.tszUserFile); - } - - if (logOptions.toFile) - hLogger = mir_createLog("Netlib", LPGENT("Standard netlib log"), logOptions.tszFile, 0); -} - -static const TCHAR* szTimeFormats[] = -{ - LPGENT("No times"), - LPGENT("Standard hh:mm:ss times"), - LPGENT("Times in milliseconds"), - LPGENT("Times in microseconds") -}; - -static INT_PTR CALLBACK LogOptionsDlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) -{ - TCHAR str[MAX_PATH]; - - switch (message) { - case WM_INITDIALOG: - logOptions.hwndOpts = hwndDlg; - TranslateDialogDefault(hwndDlg); - CheckDlgButton(hwndDlg, IDC_DUMPRECV, logOptions.dumpRecv ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_DUMPSENT, logOptions.dumpSent ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_DUMPPROXY, logOptions.dumpProxy ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_DUMPSSL, logOptions.dumpSsl ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_TEXTDUMPS, logOptions.textDumps ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_AUTODETECTTEXT, logOptions.autoDetectText ? BST_CHECKED : BST_UNCHECKED); - { - for (int i=0; i < SIZEOF(szTimeFormats); i++) - SendDlgItemMessage(hwndDlg, IDC_TIMEFORMAT, CB_ADDSTRING, 0, (LPARAM)TranslateTS(szTimeFormats[i])); - } - SendDlgItemMessage(hwndDlg, IDC_TIMEFORMAT, CB_SETCURSEL, logOptions.timeFormat, 0); - CheckDlgButton(hwndDlg, IDC_SHOWNAMES, logOptions.showUser ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_TOOUTPUTDEBUGSTRING, logOptions.toOutputDebugString ? BST_CHECKED : BST_UNCHECKED); - CheckDlgButton(hwndDlg, IDC_TOFILE, logOptions.toFile ? BST_CHECKED : BST_UNCHECKED); - SetDlgItemText(hwndDlg, IDC_FILENAME, logOptions.tszUserFile); - SetDlgItemText(hwndDlg, IDC_PATH, logOptions.tszFile); - CheckDlgButton(hwndDlg, IDC_SHOWTHISDLGATSTART, db_get_b(NULL, "Netlib", "ShowLogOptsAtStart", 0) ? BST_CHECKED : BST_UNCHECKED); - { - ptrA szRun(db_get_sa(NULL, "Netlib", "RunAtStart")); - if (szRun) - SetDlgItemTextA(hwndDlg, IDC_RUNATSTART, szRun); - - HWND hwndFilter = GetDlgItem(hwndDlg, IDC_FILTER); - SetWindowLongPtr(hwndFilter, GWL_STYLE, GetWindowLongPtr(hwndFilter, GWL_STYLE) | (TVS_NOHSCROLL | TVS_CHECKBOXES)); - - TVINSERTSTRUCT tvis = { 0 }; - tvis.hInsertAfter = TVI_SORT; - tvis.item.mask = TVIF_PARAM | TVIF_TEXT | TVIF_STATE; - tvis.item.stateMask = TVIS_STATEIMAGEMASK; - - for (int i = 0; i < netlibUser.getCount(); i++) { - tvis.item.pszText = netlibUser[i]->user.ptszDescriptiveName; - tvis.item.lParam = i; - tvis.item.state = INDEXTOSTATEIMAGEMASK((netlibUser[i]->toLog) ? 2 : 1); - TreeView_InsertItem(hwndFilter, &tvis); - } - tvis.item.lParam = -1; - tvis.item.pszText = TranslateT("(Miranda core logging)"); - tvis.item.state = INDEXTOSTATEIMAGEMASK((logOptions.toLog) ? 2 : 1); - TreeView_InsertItem(hwndFilter, &tvis); - } - return TRUE; - - case WM_COMMAND: - switch (LOWORD(wParam)) { - case IDC_FILENAME: - if (HIWORD(wParam) == EN_CHANGE) { - if ((HWND)lParam == GetFocus()) - CheckDlgButton(hwndDlg, IDC_TOFILE, BST_CHECKED); - - TCHAR path[MAX_PATH]; - GetWindowText((HWND)lParam, path, SIZEOF(path)); - - PathToAbsoluteT(VARST(path), path); - SetDlgItemText(hwndDlg, IDC_PATH, path); - } - break; - - case IDC_FILENAMEBROWSE: - case IDC_RUNATSTARTBROWSE: - GetWindowText(GetWindow((HWND)lParam, GW_HWNDPREV), str, SIZEOF(str)); - { - TCHAR filter[200]; - mir_sntprintf(filter, SIZEOF(filter), _T("%s (*)%c*%c"), TranslateT("All files"), 0, 0); - - OPENFILENAME ofn = { 0 }; - ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; - ofn.hwndOwner = hwndDlg; - ofn.Flags = OFN_HIDEREADONLY | OFN_DONTADDTORECENT; - if (LOWORD(wParam) == IDC_FILENAMEBROWSE) - ofn.lpstrTitle = TranslateT("Select where log file will be created"); - else { - ofn.Flags |= OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; - ofn.lpstrTitle = TranslateT("Select program to be run"); - } - ofn.lpstrFilter = filter; - ofn.lpstrFile = str; - ofn.nMaxFile = SIZEOF(str) - 2; - ofn.nMaxFileTitle = MAX_PATH; - if (LOWORD(wParam) == IDC_FILENAMEBROWSE) { - if (!GetSaveFileName(&ofn)) return 1; - } - else if (!GetOpenFileName(&ofn)) - return 1; - - if (LOWORD(wParam) == IDC_RUNATSTARTBROWSE && _tcschr(str, ' ') != NULL) { - memmove(str + 1, str, ((SIZEOF(str) - 2) * sizeof(TCHAR))); - str[0] = '"'; - mir_tstrcat(str, _T("\"")); - } - SetWindowText(GetWindow((HWND)lParam, GW_HWNDPREV), str); - } - break; - - case IDC_RUNNOW: - GetDlgItemText(hwndDlg, IDC_RUNATSTART, str, SIZEOF(str)); - if (str[0]) { - STARTUPINFO si = { sizeof(si) }; - PROCESS_INFORMATION pi; - CreateProcess(NULL, str, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); - } - break; - - case IDOK: - GetDlgItemText(hwndDlg, IDC_RUNATSTART, str, SIZEOF(str)); - db_set_ts(NULL, "Netlib", "RunAtStart", str); - db_set_b(NULL, "Netlib", "ShowLogOptsAtStart", (BYTE)IsDlgButtonChecked(hwndDlg, IDC_SHOWTHISDLGATSTART)); - - GetDlgItemText(hwndDlg, IDC_FILENAME, str, SIZEOF(str)); - logOptions.tszUserFile = rtrimt(str); - db_set_ts(NULL, "Netlib", "File", str); - - GetDlgItemText(hwndDlg, IDC_PATH, str, SIZEOF(str)); - logOptions.tszFile = rtrimt(str); - - db_set_b(NULL, "Netlib", "DumpRecv", logOptions.dumpRecv = IsDlgButtonChecked(hwndDlg, IDC_DUMPRECV)); - db_set_b(NULL, "Netlib", "DumpSent", logOptions.dumpSent = IsDlgButtonChecked(hwndDlg, IDC_DUMPSENT)); - db_set_b(NULL, "Netlib", "DumpProxy", logOptions.dumpProxy = IsDlgButtonChecked(hwndDlg, IDC_DUMPPROXY)); - db_set_b(NULL, "Netlib", "DumpSsl", logOptions.dumpSsl = IsDlgButtonChecked(hwndDlg, IDC_DUMPSSL)); - db_set_b(NULL, "Netlib", "TextDumps", logOptions.textDumps = IsDlgButtonChecked(hwndDlg, IDC_TEXTDUMPS)); - db_set_b(NULL, "Netlib", "AutoDetectText", logOptions.autoDetectText = IsDlgButtonChecked(hwndDlg, IDC_AUTODETECTTEXT)); - db_set_b(NULL, "Netlib", "TimeFormat", logOptions.timeFormat = SendDlgItemMessage(hwndDlg, IDC_TIMEFORMAT, CB_GETCURSEL, 0, 0)); - db_set_b(NULL, "Netlib", "ShowUser", logOptions.showUser = IsDlgButtonChecked(hwndDlg, IDC_SHOWNAMES)); - db_set_b(NULL, "Netlib", "ToOutputDebugString", logOptions.toOutputDebugString = IsDlgButtonChecked(hwndDlg, IDC_TOOUTPUTDEBUGSTRING)); - db_set_b(NULL, "Netlib", "ToFile", logOptions.toFile = IsDlgButtonChecked(hwndDlg, IDC_TOFILE)); - { - HWND hwndFilter = GetDlgItem(logOptions.hwndOpts, IDC_FILTER); - TVITEM tvi = { 0 }; - BOOL checked; - - tvi.mask = TVIF_HANDLE | TVIF_PARAM | TVIF_STATE | TVIF_TEXT; - tvi.hItem = TreeView_GetRoot(hwndFilter); - - while (tvi.hItem) { - TreeView_GetItem(hwndFilter, &tvi); - checked = ((tvi.state & TVIS_STATEIMAGEMASK) >> 12 == 2); - - if (tvi.lParam == -1) { - logOptions.toLog = checked; - db_set_dw(NULL, "Netlib", "NLlog", checked); - } - else if (tvi.lParam < netlibUser.getCount()) { - netlibUser[tvi.lParam]->toLog = checked; - db_set_dw(NULL, netlibUser[tvi.lParam]->user.szSettingsModule, "NLlog", checked); - } - - tvi.hItem = TreeView_GetNextSibling(hwndFilter, tvi.hItem); - } - } - InitLog(); - // fall through - case IDCANCEL: - DestroyWindow(hwndDlg); - } - break; - - case WM_CLOSE: - DestroyWindow(hwndDlg); - break; - - case WM_DESTROY: - ImageList_Destroy(TreeView_GetImageList(GetDlgItem(hwndDlg, IDC_FILTER), TVSIL_STATE)); - logOptions.hwndOpts = NULL; - break; - } - return FALSE; -} - -void NetlibLogShowOptions(void) -{ - if (logOptions.hwndOpts == NULL) - logOptions.hwndOpts = CreateDialog(hInst, MAKEINTRESOURCE(IDD_NETLIBLOGOPTS), NULL, LogOptionsDlgProc); - SetForegroundWindow(logOptions.hwndOpts); -} - -static INT_PTR ShowOptions(WPARAM, LPARAM) -{ - NetlibLogShowOptions(); - return 0; -} - -static INT_PTR NetlibLog(WPARAM wParam, LPARAM lParam) -{ - if (!bIsActive) - return 0; - - DWORD dwOriginalLastError = GetLastError(); - - NetlibUser *nlu = (NetlibUser*)wParam; - const char *pszMsg = (const char*)lParam; - if ((nlu != NULL && GetNetlibHandleType(nlu) != NLH_USER) || pszMsg == NULL) { - SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } - - /* if the Netlib user handle is NULL, just pretend its not */ - if (!(nlu != NULL ? nlu->toLog : logOptions.toLog)) - return 1; - - LARGE_INTEGER liTimeNow; - char szTime[32], szHead[128]; - switch (logOptions.timeFormat) { - case TIMEFORMAT_HHMMSS: - GetTimeFormatA(LOCALE_USER_DEFAULT, TIME_FORCE24HOURFORMAT | TIME_NOTIMEMARKER, NULL, NULL, szTime, SIZEOF(szTime)); - mir_strcat(szTime, " "); - break; - - case TIMEFORMAT_MILLISECONDS: - QueryPerformanceCounter(&liTimeNow); - liTimeNow.QuadPart -= mirandaStartTime; - mir_snprintf(szTime, SIZEOF(szTime), "%I64u.%03I64u ", liTimeNow.QuadPart / perfCounterFreq, - 1000 * (liTimeNow.QuadPart % perfCounterFreq) / perfCounterFreq); - break; - - case TIMEFORMAT_MICROSECONDS: - QueryPerformanceCounter(&liTimeNow); - liTimeNow.QuadPart -= mirandaStartTime; - mir_snprintf(szTime, SIZEOF(szTime), "%I64u.%06I64u ", liTimeNow.QuadPart / perfCounterFreq, - 1000000 * (liTimeNow.QuadPart % perfCounterFreq) / perfCounterFreq); - break; - - default: - szTime[0] = '\0'; - break; - } - - char *szUser = (logOptions.showUser) ? (nlu == NULL ? NULL : nlu->user.szSettingsModule) : NULL; - if (szUser) - mir_snprintf(szHead, SIZEOF(szHead), "[%s%04X] [%s] ", szTime, GetCurrentThreadId(), szUser); - else - mir_snprintf(szHead, SIZEOF(szHead), "[%s%04X] ", szTime, GetCurrentThreadId()); - - if (logOptions.toOutputDebugString) { - if (szHead[0]) - OutputDebugStringA(szHead); - OutputDebugStringA(pszMsg); - OutputDebugStringA("\n"); - } - - if (logOptions.toFile && !logOptions.tszFile.IsEmpty()) { - size_t len = mir_strlen(pszMsg); - mir_writeLogA(hLogger, "%s%s%s", szHead, pszMsg, pszMsg[len-1] == '\n' ? "" : "\r\n"); - } - - LOGMSG logMsg = { szHead, pszMsg }; - NotifyFastHook(hLogEvent, (WPARAM)nlu, (LPARAM)&logMsg); - - SetLastError(dwOriginalLastError); - return 1; -} - -static INT_PTR NetlibLogW(WPARAM wParam, LPARAM lParam) -{ - const wchar_t *pszMsg = (const wchar_t*)lParam; - char* szMsg = Utf8EncodeW(pszMsg); - INT_PTR res = NetlibLog(wParam, (LPARAM)szMsg); - mir_free(szMsg); - return res; -} - -void NetlibLogf(NetlibUser* nlu, const char *fmt, ...) -{ - if (nlu == NULL) { - if (!logOptions.toLog) - return; - } - else if (!nlu->toLog) - return; - - va_list va; - char szText[1024]; - - va_start(va, fmt); - mir_vsnprintf(szText, sizeof(szText), fmt, va); - va_end(va); - - NetlibLog((WPARAM)nlu, (LPARAM)szText); -} - -void NetlibDumpData(NetlibConnection *nlc, PBYTE buf, int len, int sent, int flags) -{ - char szTitleLine[128]; - char *szBuf; - bool useStack = false; - - // This section checks a number of conditions and aborts - // the dump if the data should not be written to the log - - // Check packet flags - if (flags & (MSG_PEEK | MSG_NODUMP)) - return; - - // Check user's log settings - if (!(logOptions.toOutputDebugString || GetSubscribersCount(hLogEvent) != 0 || (logOptions.toFile && !logOptions.tszFile.IsEmpty()))) - return; - if ((sent && !logOptions.dumpSent) || (!sent && !logOptions.dumpRecv)) - return; - if ((flags & MSG_DUMPPROXY) && !logOptions.dumpProxy) - return; - if ((flags & MSG_DUMPSSL) && !logOptions.dumpSsl) - return; - - WaitForSingleObject(hConnectionHeaderMutex, INFINITE); - NetlibUser *nlu = nlc ? nlc->nlu : NULL; - int titleLineLen = mir_snprintf(szTitleLine, SIZEOF(szTitleLine), "(%p:%u) Data %s%s\r\n", - nlc, nlc ? nlc->s : 0, sent ? "sent" : "received", flags & MSG_DUMPPROXY ? " (proxy)" : ""); - ReleaseMutex(hConnectionHeaderMutex); - - // check filter settings - if (nlu == NULL) { - if (!logOptions.toLog) - return; - } - else if (!nlu->toLog) - return; - - bool isText = true; - if (!logOptions.textDumps) - isText = false; - else if (!(flags & MSG_DUMPASTEXT)) { - if (logOptions.autoDetectText) { - for (int i = 0; i < len; i++) { - if ((buf[i] < ' ' && buf[i] != '\t' && buf[i] != '\r' && buf[i] != '\n') || buf[i] >= 0x80) { - isText = false; - break; - } - } - } - else isText = false; - } - - // Text data - if (isText) { - int sz = titleLineLen + len + 1; - useStack = sz <= 8192; - szBuf = (char*)(useStack ? alloca(sz) : mir_alloc(sz)); - memcpy(szBuf, szTitleLine, titleLineLen); - memcpy(szBuf + titleLineLen, (const char*)buf, len); - szBuf[titleLineLen + len] = '\0'; - } - // Binary data - else { - int line, col, colsInLine; - int sz = titleLineLen + ((len + 16) >> 4) * 78 + 1; - useStack = sz <= 8192; - - szBuf = (char*)(useStack ? alloca(sz) : mir_alloc(sz)); - memcpy(szBuf, szTitleLine, titleLineLen); - char *pszBuf = szBuf + titleLineLen; - for (line = 0;; line += 16) { - colsInLine = min(16, len - line); - - if (colsInLine == 16) { - PBYTE p = buf + line; - pszBuf += wsprintfA( - pszBuf, "%08X: %02X %02X %02X %02X-%02X %02X %02X %02X-%02X %02X %02X %02X-%02X %02X %02X %02X ", - line, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); //!!!!!!!!!! - } - else { - pszBuf += wsprintfA(pszBuf, "%08X: ", line); //!!!!!!!!!! - // Dump data as hex - for (col = 0; col < colsInLine; col++) - pszBuf += wsprintfA(pszBuf, "%02X%c", buf[line + col], ((col & 3) == 3 && col != 15) ? '-' : ' '); //!!!!!!!!!! - // Fill out last line with blanks - for (; col < 16; col++) { - mir_strcpy(pszBuf, " "); - pszBuf += 3; - } - *pszBuf++ = ' '; - } - - for (col = 0; col < colsInLine; col++) - *pszBuf++ = (buf[line + col] < ' ') ? '.' : (char)buf[line + col]; - - if (len - line <= 16) - break; - - *pszBuf++ = '\r'; // End each line with a break - *pszBuf++ = '\n'; // End each line with a break - } - *pszBuf = '\0'; - } - - NetlibLog((WPARAM)nlu, (LPARAM)szBuf); - if (!useStack) - mir_free(szBuf); -} - -void NetlibLogInit(void) -{ - LARGE_INTEGER li; - QueryPerformanceFrequency(&li); - perfCounterFreq = li.QuadPart; - QueryPerformanceCounter(&li); - mirandaStartTime = li.QuadPart; - - CreateServiceFunction(MS_NETLIB_LOGWIN, ShowOptions); - CreateServiceFunction(MS_NETLIB_LOG, NetlibLog); - CreateServiceFunction(MS_NETLIB_LOGW, NetlibLogW); - hLogEvent = CreateHookableEvent(ME_NETLIB_FASTDUMP); - - logOptions.dumpRecv = db_get_b(NULL, "Netlib", "DumpRecv", 1); - logOptions.dumpSent = db_get_b(NULL, "Netlib", "DumpSent", 1); - logOptions.dumpProxy = db_get_b(NULL, "Netlib", "DumpProxy", 1); - logOptions.dumpSsl = db_get_b(NULL, "Netlib", "DumpSsl", 0); - logOptions.textDumps = db_get_b(NULL, "Netlib", "TextDumps", 1); - logOptions.autoDetectText = db_get_b(NULL, "Netlib", "AutoDetectText", 1); - logOptions.timeFormat = db_get_b(NULL, "Netlib", "TimeFormat", TIMEFORMAT_HHMMSS); - logOptions.showUser = db_get_b(NULL, "Netlib", "ShowUser", 1); - logOptions.toOutputDebugString = db_get_b(NULL, "Netlib", "ToOutputDebugString", 0); - logOptions.toFile = db_get_b(NULL, "Netlib", "ToFile", 0); - logOptions.toLog = db_get_dw(NULL, "Netlib", "NLlog", 1); - - InitLog(); - - if (db_get_b(NULL, "Netlib", "ShowLogOptsAtStart", 0)) - NetlibLogShowOptions(); - - ptrT szBuf(db_get_tsa(NULL, "Netlib", "RunAtStart")); - if (szBuf) { - STARTUPINFO si = { sizeof(si) }; - PROCESS_INFORMATION pi; - CreateProcess(NULL, szBuf, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); - } -} - -void NetlibLogShutdown(void) -{ - bIsActive = FALSE; - DestroyHookableEvent(hLogEvent); hLogEvent = NULL; - if (IsWindow(logOptions.hwndOpts)) - DestroyWindow(logOptions.hwndOpts); -} -- cgit v1.2.3