1
0
mirror of https://github.com/unrealircd/unrealircd.git synced 2026-07-10 20:03:14 +02:00
Files
unrealircd/src/windows/gui.c
T
Bram Matthys b74d15595b Change int rehash() to void request_rehash(), which is a better name
as it REQUESTS to rehash the server, but it may not be done immediately.
And making it void makes sure nobody relies on some sort of return
value which will differ between with vs without remote includes.

Also get rid of sig and loop.rehash_save_sig, as a NULL client
already indicates the same (or at least does so now).
2021-08-18 13:28:56 +02:00

1140 lines
32 KiB
C

/************************************************************************
* IRC - Internet Relay Chat, windows/gui.c
* Copyright (C) 2000-2004 David Flynn (DrBin) & Dominick Meglio (codemastr)
*
* 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#define WIN32_VERSION BASE_VERSION "-" PATCH1 PATCH2 PATCH3 PATCH4 PATCH5
#include "unrealircd.h"
#include <windowsx.h>
#include <commctrl.h>
#include <commdlg.h>
#include <richedit.h>
#include <Strsafe.h>
#include "resource.h"
#include "win.h"
#define TOOLBAR_START 82
#define TOOLBAR_STOP (TOOLBAR_START+20)
__inline void ShowDialog(HWND *handle, HINSTANCE inst, char *template, HWND parent,
DLGPROC proc)
{
if (!IsWindow(*handle))
{
*handle = CreateDialog(inst, template, parent, (DLGPROC)proc);
ShowWindow(*handle, SW_SHOW);
}
else
SetForegroundWindow(*handle);
}
/* Comments:
*
* DrBin did a great job with the original GUI, but he has been gone a long time.
* In his absense, it was decided it would be best to continue windows development.
* The new code is based on his so it will be pretty much similar in features, my
* main goal is to make it more stable. A lot of what I know about GUI coding
* I learned from DrBin so thanks to him for teaching me :) -- codemastr
*/
LRESULT CALLBACK MainDLG(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK LicenseDLG(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK InfoDLG(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK CreditsDLG(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK HelpDLG(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK StatusDLG(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK ConfigErrorDLG(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK FromVarDLG(HWND, UINT, WPARAM, LPARAM, unsigned char *, unsigned char **);
LRESULT CALLBACK FromFileReadDLG(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK FromFileDLG(HWND, UINT, WPARAM, LPARAM);
HBRUSH MainDlgBackground;
extern void SocketLoop(void *dummy);
HINSTANCE hInst;
NOTIFYICONDATA SysTray;
HTREEITEM AddItemToTree(HWND, LPSTR, int, short);
void win_map(Client *, HWND, short);
extern Link *Servers;
unsigned char *errors = NULL;
extern VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv);
void CleanUp(void)
{
Shell_NotifyIcon(NIM_DELETE ,&SysTray);
}
HWND hStatusWnd;
HWND hwIRCDWnd=NULL;
HWND hwTreeView;
HWND hWndMod;
UINT WM_TASKBARCREATED, WM_FINDMSGSTRING;
FARPROC lpfnOldWndProc;
HMENU hContext;
char OSName[OSVER_SIZE];
#ifdef USE_LIBCURL
extern char *find_loaded_remote_include(char *url);
#endif
void TaskBarCreated()
{
HICON hIcon = (HICON)LoadImage(hInst, MAKEINTRESOURCE(ICO_MAIN), IMAGE_ICON,16, 16, 0);
SysTray.cbSize = sizeof(NOTIFYICONDATA);
SysTray.hIcon = hIcon;
SysTray.hWnd = hwIRCDWnd;
SysTray.uCallbackMessage = WM_USER;
SysTray.uFlags = NIF_ICON|NIF_TIP|NIF_MESSAGE;
SysTray.uID = 0;
strcpy(SysTray.szTip, WIN32_VERSION);
Shell_NotifyIcon(NIM_ADD ,&SysTray);
}
LRESULT LinkSubClassFunc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
static HCURSOR hCursor;
if (!hCursor)
hCursor = LoadCursor(hInst, MAKEINTRESOURCE(CUR_HAND));
if (Message == WM_MOUSEMOVE || Message == WM_LBUTTONDOWN)
SetCursor(hCursor);
return CallWindowProc((WNDPROC)lpfnOldWndProc, hWnd, Message, wParam, lParam);
}
LRESULT RESubClassFunc(HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
POINT p;
RECT r;
DWORD start, end;
unsigned char string[500];
if (Message == WM_GETDLGCODE)
return DLGC_WANTALLKEYS;
if (Message == WM_CONTEXTMENU)
{
p.x = GET_X_LPARAM(lParam);
p.y = GET_Y_LPARAM(lParam);
if (GET_X_LPARAM(lParam) == -1 && GET_Y_LPARAM(lParam) == -1)
{
GetClientRect(hWnd, &r);
p.x = (int)((r.left + r.right)/2);
p.y = (int)((r.top + r.bottom)/2);
ClientToScreen(hWnd,&p);
}
if (!SendMessage(hWnd, EM_CANUNDO, 0, 0))
EnableMenuItem(hContext, IDM_UNDO, MF_BYCOMMAND|MF_GRAYED);
else
EnableMenuItem(hContext, IDM_UNDO, MF_BYCOMMAND|MF_ENABLED);
if (!SendMessage(hWnd, EM_CANPASTE, 0, 0))
EnableMenuItem(hContext, IDM_PASTE, MF_BYCOMMAND|MF_GRAYED);
else
EnableMenuItem(hContext, IDM_PASTE, MF_BYCOMMAND|MF_ENABLED);
if (GetWindowLong(hWnd, GWL_STYLE) & ES_READONLY)
{
EnableMenuItem(hContext, IDM_CUT, MF_BYCOMMAND|MF_GRAYED);
EnableMenuItem(hContext, IDM_DELETE, MF_BYCOMMAND|MF_GRAYED);
}
else
{
EnableMenuItem(hContext, IDM_CUT, MF_BYCOMMAND|MF_ENABLED);
EnableMenuItem(hContext, IDM_DELETE, MF_BYCOMMAND|MF_ENABLED);
}
SendMessage(hWnd, EM_GETSEL, (WPARAM)&start, (LPARAM)&end);
if (start == end)
EnableMenuItem(hContext, IDM_COPY, MF_BYCOMMAND|MF_GRAYED);
else
EnableMenuItem(hContext, IDM_COPY, MF_BYCOMMAND|MF_ENABLED);
TrackPopupMenu(hContext,TPM_LEFTALIGN|TPM_RIGHTBUTTON,p.x,p.y,0,GetParent(hWnd),NULL);
return 0;
}
return CallWindowProc((WNDPROC)lpfnOldWndProc, hWnd, Message, wParam, lParam);
}
int DoCloseUnreal(HWND hWnd)
{
unreal_log(ULOG_INFO, "main", "UNREALIRCD_STOP", NULL,
"Terminating server (process termination requested or GUI window closed)");
loop.terminating = 1;
unload_all_modules();
DestroyWindow(hWnd);
TerminateProcess(GetCurrentProcess(), 0);
exit(0); /* in case previous fails (possible?) */
}
int AskCloseUnreal(HWND hWnd)
{
if (MessageBox(hWnd, "Close UnrealIRCd?", "Are you sure?", MB_YESNO|MB_ICONQUESTION) == IDNO)
return 0;
DoCloseUnreal(hWnd);
exit(0);
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
unsigned char *s;
HWND hWnd;
WSADATA WSAData;
HICON hIcon;
SC_HANDLE hService, hSCManager;
SERVICE_TABLE_ENTRY DispatchTable[] =
{
{ "UnrealIRCd", ServiceMain },
{ 0, 0 }
};
DWORD need;
/* Go one level up, since we are currently in the bin\ subdir
* and we want to be in (f.e.) "C:\Program Files\UnrealIRCd 5"
*/
chdir("..");
GetOSName(OSName);
/* Check if we are running as a service... */
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if ((hService = OpenService(hSCManager, "UnrealIRCd", SC_MANAGER_CONNECT)))
{
int save_err = 0;
StartServiceCtrlDispatcher(DispatchTable);
if (GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
{
SERVICE_STATUS status;
/* Restart handling, it's ugly but it's as
* pretty as it is gonna get :)
*/
if (__argc == 2 && !strcmp(__argv[1], "restartsvc"))
{
QueryServiceStatus(hService, &status);
if (status.dwCurrentState != SERVICE_STOPPED)
{
ControlService(hService,
SERVICE_CONTROL_STOP, &status);
while (status.dwCurrentState == SERVICE_STOP_PENDING)
{
QueryServiceStatus(hService, &status);
if (status.dwCurrentState != SERVICE_STOPPED)
Sleep(1000);
}
}
}
if (!StartService(hService, 0, NULL))
save_err = GetLastError();
}
CloseServiceHandle(hService);
CloseServiceHandle(hSCManager);
if (save_err != ERROR_SERVICE_DISABLED)
exit(0);
} else {
CloseServiceHandle(hSCManager);
}
InitCommonControls();
WM_TASKBARCREATED = RegisterWindowMessage("TaskbarCreated");
WM_FINDMSGSTRING = RegisterWindowMessage(FINDMSGSTRING);
atexit(CleanUp);
if (!LoadLibrary("riched20.dll"))
LoadLibrary("riched32.dll");
InitDebug();
if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
{
MessageBox(NULL, "Unable to initialize WinSock", "UnrealIRCD Initalization Error", MB_OK);
return FALSE;
}
hInst = hInstance;
MainDlgBackground = CreateSolidBrush(RGB(75, 134, 238)); /* Background of main dialog */
hWnd = CreateDialog(hInstance, "UnrealIRCd", 0, (DLGPROC)MainDLG);
hwIRCDWnd = hWnd;
TaskBarCreated();
if (InitUnrealIRCd(__argc, __argv) != 1)
{
MessageBox(NULL, "UnrealIRCd has failed to initialize in InitUnrealIRCd()", "UnrealIRCD Initalization Error" ,MB_OK);
return FALSE;
}
ShowWindow(hWnd, SW_SHOW);
_beginthread(SocketLoop, 0, NULL);
while (GetMessage(&msg, NULL, 0, 0))
{
if (!IsWindow(hStatusWnd) || !IsDialogMessage(hStatusWnd, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return FALSE;
}
LRESULT CALLBACK MainDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
static HCURSOR hCursor;
static HMENU hRehash, hAbout, hConfig, hTray, hLogs;
unsigned char *argv[3];
Client *pClient;
unsigned char *msg;
POINT p;
if (message == WM_TASKBARCREATED)
{
TaskBarCreated();
return TRUE;
}
switch (message)
{
case WM_INITDIALOG:
{
ShowWindow(hDlg, SW_HIDE);
hCursor = LoadCursor(hInst, MAKEINTRESOURCE(CUR_HAND));
hContext = GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(MENU_CONTEXT)),0);
/* Rehash popup menu */
hRehash = GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(MENU_REHASH)),0);
/* About popup menu */
hAbout = GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(MENU_ABOUT)),0);
/* Systray popup menu set the items to point to the other menus*/
hTray = GetSubMenu(LoadMenu(hInst, MAKEINTRESOURCE(MENU_SYSTRAY)),0);
ModifyMenu(hTray, IDM_REHASH, MF_BYCOMMAND|MF_POPUP|MF_STRING, HandleToUlong(hRehash), "&Rehash");
ModifyMenu(hTray, IDM_ABOUT, MF_BYCOMMAND|MF_POPUP|MF_STRING, HandleToUlong(hAbout), "&About");
SetWindowText(hDlg, WIN32_VERSION);
SendMessage(hDlg, WM_SETICON, (WPARAM)ICON_SMALL,
(LPARAM)(HICON)LoadImage(hInst, MAKEINTRESOURCE(ICO_MAIN), IMAGE_ICON,16, 16, 0));
SendMessage(hDlg, WM_SETICON, (WPARAM)ICON_BIG,
(LPARAM)(HICON)LoadImage(hInst, MAKEINTRESOURCE(ICO_MAIN), IMAGE_ICON,32, 32, 0));
return TRUE;
}
case WM_CTLCOLORDLG:
return (LONG)HandleToLong(MainDlgBackground);
case WM_SIZE:
{
if (wParam & SIZE_MINIMIZED)
ShowWindow(hDlg,SW_HIDE);
return 0;
}
case WM_CLOSE:
return DoCloseUnreal(hDlg);
case WM_USER:
{
switch(LOWORD(lParam))
{
case WM_LBUTTONDBLCLK:
ShowWindow(hDlg, SW_SHOW);
ShowWindow(hDlg,SW_RESTORE);
SetForegroundWindow(hDlg);
case WM_RBUTTONDOWN:
SetForegroundWindow(hDlg);
break;
case WM_RBUTTONUP:
{
unsigned long i = 60000;
MENUITEMINFO mii;
GetCursorPos(&p);
DestroyMenu(hConfig);
hConfig = CreatePopupMenu();
DestroyMenu(hLogs);
hLogs = CreatePopupMenu();
AppendMenu(hConfig, MF_STRING, IDM_CONF, CPATH);
if (conf_log)
{
ConfigItem_log *logs;
AppendMenu(hConfig, MF_POPUP|MF_STRING, HandleToUlong(hLogs), "Logs");
for (logs = conf_log; logs; logs = logs->next)
{
AppendMenu(hLogs, MF_STRING, i++, logs->file);
}
}
AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
if (conf_include)
{
ConfigItem_include *inc;
for (inc = conf_include; inc; inc = inc->next)
{
if (inc->flag.type & INCLUDE_NOTLOADED)
continue;
#ifdef USE_LIBCURL
if (inc->flag.type & INCLUDE_REMOTE)
AppendMenu(hConfig, MF_STRING, i++, inc->url);
else
#endif
AppendMenu(hConfig, MF_STRING, i++, inc->file);
}
AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
}
if (conf_files)
{
AppendMenu(hConfig, MF_STRING, IDM_MOTD, conf_files->motd_file);
AppendMenu(hConfig, MF_STRING, IDM_SMOTD, conf_files->smotd_file);
AppendMenu(hConfig, MF_STRING, IDM_OPERMOTD, conf_files->opermotd_file);
AppendMenu(hConfig, MF_STRING, IDM_BOTMOTD, conf_files->botmotd_file);
AppendMenu(hConfig, MF_STRING, IDM_RULES, conf_files->rules_file);
}
if (conf_tld)
{
ConfigItem_tld *tlds;
AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
for (tlds = conf_tld; tlds; tlds = tlds->next)
{
if (!tlds->flag.motdptr)
AppendMenu(hConfig, MF_STRING, i++, tlds->motd_file);
if (!tlds->flag.ruleclient)
AppendMenu(hConfig, MF_STRING, i++, tlds->rules_file);
if (tlds->smotd_file)
AppendMenu(hConfig, MF_STRING, i++, tlds->smotd_file);
}
}
AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
AppendMenu(hConfig, MF_STRING, IDM_NEW, "New File");
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_SUBMENU;
mii.hSubMenu = hConfig;
SetMenuItemInfo(hTray, IDM_CONFIG, MF_BYCOMMAND, &mii);
TrackPopupMenu(hTray, TPM_LEFTALIGN|TPM_LEFTBUTTON,p.x,p.y,0,hDlg,NULL);
/* Kludge for a win bug */
SendMessage(hDlg, WM_NULL, 0, 0);
break;
}
}
return 0;
}
case WM_DESTROY:
return 0;
case WM_MOUSEMOVE:
{
POINT p;
p.x = LOWORD(lParam);
p.y = HIWORD(lParam);
if ((p.x >= 93) && (p.x <= 150) && (p.y >= TOOLBAR_START) && (p.y <= TOOLBAR_STOP))
SetCursor(hCursor);
else if ((p.x >= 160) && (p.x <= 208) && (p.y >= TOOLBAR_START) && (p.y <= TOOLBAR_STOP))
SetCursor(hCursor);
else if ((p.x >= 219) && (p.x <= 267) && (p.y >= TOOLBAR_START) && (p.y <= TOOLBAR_STOP))
SetCursor(hCursor);
else if ((p.x >= 279) && (p.x <= 325) && (p.y >= TOOLBAR_START) && (p.y <= TOOLBAR_STOP))
SetCursor(hCursor);
else if ((p.x >= 336) && (p.x <= 411) && (p.y >= TOOLBAR_START) && (p.y <= TOOLBAR_STOP))
SetCursor(hCursor);
return 0;
}
case WM_LBUTTONDOWN:
{
POINT p;
p.x = LOWORD(lParam);
p.y = HIWORD(lParam);
if ((p.x >= 93) && (p.x <= 150) && (p.y >= TOOLBAR_START) && (p.y <= TOOLBAR_STOP))
{
ClientToScreen(hDlg,&p);
TrackPopupMenu(hRehash,TPM_LEFTALIGN|TPM_LEFTBUTTON,p.x,p.y,0,hDlg,NULL);
return 0;
}
else if ((p.x >= 160) && (p.x <= 208) && (p.y >= TOOLBAR_START) && (p.y <= TOOLBAR_STOP))
{
ShowDialog(&hStatusWnd, hInst, "Status", hDlg, StatusDLG);
return 0;
}
else if ((p.x >= 219) && (p.x <= 267) && (p.y >= TOOLBAR_START) && (p.y <= TOOLBAR_STOP))
{
unsigned long i = 60000;
ClientToScreen(hDlg,&p);
DestroyMenu(hConfig);
hConfig = CreatePopupMenu();
DestroyMenu(hLogs);
hLogs = CreatePopupMenu();
AppendMenu(hConfig, MF_STRING, IDM_CONF, CPATH);
if (conf_log)
{
ConfigItem_log *logs;
AppendMenu(hConfig, MF_POPUP|MF_STRING, HandleToUlong(hLogs), "Logs");
for (logs = conf_log; logs; logs = logs->next)
{
AppendMenu(hLogs, MF_STRING, i++, logs->file);
}
}
AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
if (conf_include)
{
ConfigItem_include *inc;
for (inc = conf_include; inc; inc = inc->next)
{
#ifdef USE_LIBCURL
if (inc->flag.type & INCLUDE_REMOTE)
AppendMenu(hConfig, MF_STRING, i++, inc->url);
else
#endif
AppendMenu(hConfig, MF_STRING, i++, inc->file);
}
AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
}
if (conf_files)
{
AppendMenu(hConfig, MF_STRING, IDM_MOTD, conf_files->motd_file);
AppendMenu(hConfig, MF_STRING, IDM_SMOTD, conf_files->smotd_file);
AppendMenu(hConfig, MF_STRING, IDM_OPERMOTD, conf_files->opermotd_file);
AppendMenu(hConfig, MF_STRING, IDM_BOTMOTD, conf_files->botmotd_file);
AppendMenu(hConfig, MF_STRING, IDM_RULES, conf_files->rules_file);
}
if (conf_tld)
{
ConfigItem_tld *tlds;
AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
for (tlds = conf_tld; tlds; tlds = tlds->next)
{
if (!tlds->flag.motdptr)
AppendMenu(hConfig, MF_STRING, i++, tlds->motd_file);
if (!tlds->flag.ruleclient)
AppendMenu(hConfig, MF_STRING, i++, tlds->rules_file);
if (tlds->smotd_file)
AppendMenu(hConfig, MF_STRING, i++, tlds->smotd_file);
}
}
AppendMenu(hConfig, MF_SEPARATOR, 0, NULL);
AppendMenu(hConfig, MF_STRING, IDM_NEW, "New File");
TrackPopupMenu(hConfig,TPM_LEFTALIGN|TPM_LEFTBUTTON,p.x,p.y,0,hDlg,NULL);
return 0;
}
else if ((p.x >= 279) && (p.x <= 325) && (p.y >= TOOLBAR_START) && (p.y <= TOOLBAR_STOP))
{
ClientToScreen(hDlg,&p);
TrackPopupMenu(hAbout,TPM_LEFTALIGN|TPM_LEFTBUTTON,p.x,p.y,0,hDlg,NULL);
return 0;
}
else if ((p.x >= 336) && (p.x <= 411) && (p.y >= TOOLBAR_START) && (p.y <= TOOLBAR_STOP))
return AskCloseUnreal(hDlg);
}
case WM_SYSCOMMAND:
{
if (wParam == SC_CLOSE)
{
AskCloseUnreal(hDlg);
return 1;
}
break;
}
case WM_COMMAND:
{
if (LOWORD(wParam) >= 60000 && HIWORD(wParam) == 0 && !lParam)
{
unsigned char path[MAX_PATH];
if (GetMenuString(hLogs, LOWORD(wParam), path, MAX_PATH, MF_BYCOMMAND))
DialogBoxParam(hInst, "FromVar", hDlg, (DLGPROC)FromFileReadDLG, (LPARAM)path);
else
{
GetMenuString(hConfig,LOWORD(wParam), path, MAX_PATH, MF_BYCOMMAND);
#ifdef USE_LIBCURL
if (url_is_valid(path))
{
char *file = find_loaded_remote_include(path);
DialogBoxParam(hInst, "FromVar", hDlg, (DLGPROC)FromFileReadDLG, (LPARAM)file);
}
else
#endif
DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG, (LPARAM)path);
}
return FALSE;
}
if (!loop.booted)
{
MessageBox(NULL, "UnrealIRCd not booted due to configuration errors. "
"Check other window for error details. Then close that window, "
"fix the errors and start UnrealIRCd again.",
"UnrealIRCd not started",
MB_OK);
return FALSE;
}
switch(LOWORD(wParam))
{
case IDM_STATUS:
ShowDialog(&hStatusWnd, hInst, "Status", hDlg,StatusDLG);
break;
case IDM_SHUTDOWN:
return AskCloseUnreal(hDlg);
case IDM_RHALL:
MessageBox(NULL, "Rehashing all files", "Rehashing", MB_OK);
sendto_realops("Rehashing all files via the console");
request_rehash(NULL);
break;
case IDM_RHCONF:
MessageBox(NULL, "Rehashing the Config file", "Rehashing", MB_OK);
sendto_realops("Rehashing the Config file via the console");
request_rehash(NULL);
break;
case IDM_RHMOTD:
{
MessageBox(NULL, "Rehashing all MOTD and Rules files", "Rehashing", MB_OK);
rehash_motdrules();
sendto_realops("Rehashing all MOTD and Rules files via the console");
break;
}
case IDM_RHOMOTD:
MessageBox(NULL, "Rehashing the OperMOTD", "Rehashing", MB_OK);
read_motd(conf_files->opermotd_file, &opermotd);
sendto_realops("Rehashing the OperMOTD via the console");
break;
case IDM_RHBMOTD:
MessageBox(NULL, "Rehashing the BotMOTD", "Rehashing", MB_OK);
read_motd(conf_files->botmotd_file, &botmotd);
sendto_realops("Rehashing the BotMOTD via the console");
break;
case IDM_LICENSE:
DialogBox(hInst, "FromVar", hDlg, (DLGPROC)LicenseDLG);
break;
case IDM_INFO:
DialogBox(hInst, "FromVar", hDlg, (DLGPROC)InfoDLG);
break;
case IDM_CREDITS:
DialogBox(hInst, "FromVar", hDlg, (DLGPROC)CreditsDLG);
break;
case IDM_HELP:
DialogBox(hInst, "Help", hDlg, (DLGPROC)HelpDLG);
break;
case IDM_CONF:
DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG,
(LPARAM)CPATH);
break;
case IDM_MOTD:
DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG,
(LPARAM)conf_files->motd_file);
break;
case IDM_SMOTD:
DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG,
(LPARAM)conf_files->smotd_file);
break;
case IDM_OPERMOTD:
DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG,
(LPARAM)conf_files->opermotd_file);
break;
case IDM_BOTMOTD:
DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG,
(LPARAM)conf_files->botmotd_file);
break;
case IDM_RULES:
DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG,
(LPARAM)conf_files->rules_file);
break;
case IDM_NEW:
DialogBoxParam(hInst, "FromFile", hDlg, (DLGPROC)FromFileDLG, (LPARAM)NULL);
break;
}
}
}
return FALSE;
}
LRESULT CALLBACK LicenseDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
return FromVarDLG(hDlg, message, wParam, lParam, "UnrealIRCd License", gnulicense);
}
LRESULT CALLBACK InfoDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
return FromVarDLG(hDlg, message, wParam, lParam, "UnrealIRCd Team", unrealinfo);
}
LRESULT CALLBACK CreditsDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
return FromVarDLG(hDlg, message, wParam, lParam, "UnrealIRCd Credits", unrealcredits);
}
LRESULT CALLBACK FromVarDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam,
unsigned char *title, unsigned char **s)
{
HWND hWnd;
switch (message)
{
case WM_INITDIALOG:
{
#if 0
unsigned char String[16384];
int size;
unsigned char *RTFString;
StreamIO *stream = safe_alloc(sizeof(StreamIO));
EDITSTREAM edit;
SetWindowText(hDlg, title);
memset(String, 0, sizeof(String));
lpfnOldWndProc = (FARPROC)SetWindowLongPtr(GetDlgItem(hDlg, IDC_TEXT), GWLP_WNDPROC, (LONG_PTR)RESubClassFunc);
while (*s)
{
strcat(String, *s++);
if (*s)
strcat(String, "\r\n");
}
size = CountRTFSize(String)+1;
RTFString = safe_alloc(size);
IRCToRTF(String,RTFString);
RTFBuf = RTFString;
size--;
stream->size = &size;
stream->buffer = &RTFBuf;
edit.dwCookie = HandleToUlong(stream);
edit.pfnCallback = SplitIt;
SendMessage(GetDlgItem(hDlg, IDC_TEXT), EM_STREAMIN, (WPARAM)SF_RTF|SFF_PLAINRTF, (LPARAM)&edit);
safe_free(RTFString);
safe_free(stream);
return TRUE;
#else
return FALSE;
#endif
}
case WM_COMMAND:
{
hWnd = GetDlgItem(hDlg, IDC_TEXT);
if (LOWORD(wParam) == IDOK)
return EndDialog(hDlg, TRUE);
if (LOWORD(wParam) == IDM_COPY)
{
SendMessage(hWnd, WM_COPY, 0, 0);
return 0;
}
if (LOWORD(wParam) == IDM_SELECTALL)
{
SendMessage(hWnd, EM_SETSEL, 0, -1);
return 0;
}
if (LOWORD(wParam) == IDM_PASTE)
{
SendMessage(hWnd, WM_PASTE, 0, 0);
return 0;
}
if (LOWORD(wParam) == IDM_CUT)
{
SendMessage(hWnd, WM_CUT, 0, 0);
return 0;
}
if (LOWORD(wParam) == IDM_UNDO)
{
SendMessage(hWnd, EM_UNDO, 0, 0);
return 0;
}
if (LOWORD(wParam) == IDM_DELETE)
{
SendMessage(hWnd, WM_CLEAR, 0, 0);
return 0;
}
break;
}
case WM_CLOSE:
EndDialog(hDlg, TRUE);
break;
case WM_DESTROY:
break;
}
return (FALSE);
}
LRESULT CALLBACK FromFileReadDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
HWND hWnd;
switch (message)
{
case WM_INITDIALOG:
{
int fd,len;
unsigned char *buffer = '\0', *string = '\0';
EDITSTREAM edit;
StreamIO *stream = safe_alloc(sizeof(StreamIO));
unsigned char szText[256];
struct stat sb;
HWND hWnd = GetDlgItem(hDlg, IDC_TEXT), hTip;
StringCbPrintf(szText, sizeof(szText), "UnrealIRCd Viewer - %s", (unsigned char *)lParam);
SetWindowText(hDlg, szText);
lpfnOldWndProc = (FARPROC)SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)RESubClassFunc);
if ((fd = open((unsigned char *)lParam, _O_RDONLY|_O_BINARY)) != -1)
{
fstat(fd,&sb);
/* Only allocate the amount we need */
buffer = safe_alloc(sb.st_size+1);
buffer[0] = 0;
len = read(fd, buffer, sb.st_size);
buffer[len] = 0;
len = CountRTFSize(buffer)+1;
string = safe_alloc(len);
IRCToRTF(buffer,string);
RTFBuf = string;
len--;
stream->size = &len;
stream->buffer = &RTFBuf;
edit.dwCookie = (DWORD_PTR)stream;
edit.pfnCallback = SplitIt;
SendMessage(hWnd, EM_EXLIMITTEXT, 0, (LPARAM)0x7FFFFFFF);
SendMessage(hWnd, EM_STREAMIN, (WPARAM)SF_RTF|SFF_PLAINRTF, (LPARAM)&edit);
close(fd);
RTFBuf = NULL;
safe_free(buffer);
safe_free(string);
safe_free(stream);
}
return TRUE;
}
case WM_COMMAND:
{
hWnd = GetDlgItem(hDlg, IDC_TEXT);
if (LOWORD(wParam) == IDOK)
return EndDialog(hDlg, TRUE);
if (LOWORD(wParam) == IDM_COPY)
{
SendMessage(hWnd, WM_COPY, 0, 0);
return 0;
}
if (LOWORD(wParam) == IDM_SELECTALL)
{
SendMessage(hWnd, EM_SETSEL, 0, -1);
return 0;
}
if (LOWORD(wParam) == IDM_PASTE)
{
SendMessage(hWnd, WM_PASTE, 0, 0);
return 0;
}
if (LOWORD(wParam) == IDM_CUT)
{
SendMessage(hWnd, WM_CUT, 0, 0);
return 0;
}
if (LOWORD(wParam) == IDM_UNDO)
{
SendMessage(hWnd, EM_UNDO, 0, 0);
return 0;
}
if (LOWORD(wParam) == IDM_DELETE)
{
SendMessage(hWnd, WM_CLEAR, 0, 0);
return 0;
}
break;
}
case WM_CLOSE:
EndDialog(hDlg, TRUE);
break;
case WM_DESTROY:
break;
}
return FALSE;
}
LRESULT CALLBACK HelpDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
static HFONT hFont;
static HCURSOR hCursor;
switch (message)
{
case WM_INITDIALOG:
hCursor = LoadCursor(hInst, MAKEINTRESOURCE(CUR_HAND));
hFont = CreateFont(8,0,0,0,0,0,1,0,ANSI_CHARSET,0,0,PROOF_QUALITY,0,"MS Sans Serif");
SendMessage(GetDlgItem(hDlg, IDC_EMAIL), WM_SETFONT, (WPARAM)hFont,TRUE);
SendMessage(GetDlgItem(hDlg, IDC_URL), WM_SETFONT, (WPARAM)hFont,TRUE);
lpfnOldWndProc = (FARPROC)SetWindowLongPtr(GetDlgItem(hDlg, IDC_EMAIL), GWLP_WNDPROC, (LONG_PTR)LinkSubClassFunc);
SetWindowLongPtr(GetDlgItem(hDlg, IDC_URL), GWLP_WNDPROC, (LONG_PTR)LinkSubClassFunc);
return TRUE;
case WM_DRAWITEM:
{
LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
unsigned char text[500];
COLORREF oldtext;
RECT focus;
GetWindowText(lpdis->hwndItem, text, 500);
if (wParam == IDC_URL || IDC_EMAIL)
{
FillRect(lpdis->hDC, &lpdis->rcItem, GetSysColorBrush(COLOR_3DFACE));
oldtext = SetTextColor(lpdis->hDC, RGB(0,0,255));
DrawText(lpdis->hDC, text, strlen(text), &lpdis->rcItem, DT_CENTER|DT_VCENTER);
SetTextColor(lpdis->hDC, oldtext);
if (lpdis->itemState & ODS_FOCUS)
{
CopyRect(&focus, &lpdis->rcItem);
focus.left += 2;
focus.right -= 2;
focus.top += 1;
focus.bottom -= 1;
DrawFocusRect(lpdis->hDC, &focus);
}
return TRUE;
}
}
case WM_COMMAND:
if (LOWORD(wParam) == IDOK)
EndDialog(hDlg, TRUE);
if (HIWORD(wParam) == BN_DBLCLK)
{
if (LOWORD(wParam) == IDC_URL)
ShellExecute(NULL, "open", "https://www.unrealircd.org", NULL, NULL,
SW_MAXIMIZE);
else if (LOWORD(wParam) == IDC_EMAIL)
ShellExecute(NULL, "open", "mailto:unreal-users@lists.sourceforge.net", NULL, NULL,
SW_MAXIMIZE);
EndDialog(hDlg, TRUE);
return 0;
}
break;
case WM_CLOSE:
EndDialog(hDlg, TRUE);
break;
case WM_DESTROY:
DeleteObject(hFont);
break;
}
return FALSE;
}
LRESULT CALLBACK StatusDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
{
hwTreeView = GetDlgItem(hDlg, IDC_TREE);
win_map(&me, hwTreeView, 0);
SetDlgItemInt(hDlg, IDC_CLIENTS, irccounts.clients, FALSE);
SetDlgItemInt(hDlg, IDC_SERVERS, irccounts.servers, FALSE);
SetDlgItemInt(hDlg, IDC_INVISO, irccounts.invisible, FALSE);
SetDlgItemInt(hDlg, IDC_UNKNOWN, irccounts.unknown, FALSE);
SetDlgItemInt(hDlg, IDC_OPERS, irccounts.operators, FALSE);
SetDlgItemInt(hDlg, IDC_CHANNELS, irccounts.channels, FALSE);
if (irccounts.clients > irccounts.global_max)
irccounts.global_max = irccounts.clients;
if (irccounts.me_clients > irccounts.me_max)
irccounts.me_max = irccounts.me_clients;
SetDlgItemInt(hDlg, IDC_MAXCLIENTS, irccounts.global_max, FALSE);
SetDlgItemInt(hDlg, IDC_LCLIENTS, irccounts.me_clients, FALSE);
SetDlgItemInt(hDlg, IDC_LSERVERS, irccounts.me_servers, FALSE);
SetDlgItemInt(hDlg, IDC_LMAXCLIENTS, irccounts.me_max, FALSE);
SetTimer(hDlg, 1, 5000, NULL);
return TRUE;
}
case WM_CLOSE:
DestroyWindow(hDlg);
return TRUE;
case WM_TIMER:
TreeView_DeleteAllItems(hwTreeView);
win_map(&me, hwTreeView, 1);
SetDlgItemInt(hDlg, IDC_CLIENTS, irccounts.clients, FALSE);
SetDlgItemInt(hDlg, IDC_SERVERS, irccounts.servers, FALSE);
SetDlgItemInt(hDlg, IDC_INVISO, irccounts.invisible, FALSE);
SetDlgItemInt(hDlg, IDC_INVISO, irccounts.invisible, FALSE);
SetDlgItemInt(hDlg, IDC_UNKNOWN, irccounts.unknown, FALSE);
SetDlgItemInt(hDlg, IDC_OPERS, irccounts.operators, FALSE);
SetDlgItemInt(hDlg, IDC_CHANNELS, irccounts.channels, FALSE);
if (irccounts.clients > irccounts.global_max)
irccounts.global_max = irccounts.clients;
if (irccounts.me_clients > irccounts.me_max)
irccounts.me_max = irccounts.me_clients;
SetDlgItemInt(hDlg, IDC_MAXCLIENTS, irccounts.global_max, FALSE);
SetDlgItemInt(hDlg, IDC_LCLIENTS, irccounts.me_clients, FALSE);
SetDlgItemInt(hDlg, IDC_LSERVERS, irccounts.me_servers, FALSE);
SetDlgItemInt(hDlg, IDC_LMAXCLIENTS, irccounts.me_max, FALSE);
SetTimer(hDlg, 1, 5000, NULL);
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK)
{
DestroyWindow(hDlg);
return TRUE;
}
break;
}
return FALSE;
}
/* This was made by DrBin but I cleaned it up a bunch to make it work better */
HTREEITEM AddItemToTree(HWND hWnd, LPSTR lpszItem, int nLevel, short remap)
{
TVITEM tvi;
TVINSERTSTRUCT tvins;
static HTREEITEM hPrev = (HTREEITEM)TVI_FIRST;
static HTREEITEM hPrevLev[10] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
HTREEITEM hti;
if (remap)
{
hPrev = (HTREEITEM)TVI_FIRST;
memset(hPrevLev, 0, sizeof(HTREEITEM)*10);
}
tvi.mask = TVIF_TEXT|TVIF_PARAM;
tvi.pszText = lpszItem;
tvi.cchTextMax = lstrlen(lpszItem);
tvi.lParam = (LPARAM)nLevel;
tvins.item = tvi;
tvins.hInsertAfter = hPrev;
if (nLevel == 1)
tvins.hParent = TVI_ROOT;
else
tvins.hParent = hPrevLev[nLevel-1];
hPrev = (HTREEITEM)SendMessage(hWnd, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT) &tvins);
hPrevLev[nLevel] = hPrev;
TreeView_EnsureVisible(hWnd,hPrev);
if (nLevel > 1)
{
hti = TreeView_GetParent(hWnd, hPrev);
tvi.mask = TVIF_IMAGE|TVIF_SELECTEDIMAGE;
tvi.hItem = hti;
TreeView_SetItem(hWnd, &tvi);
}
return hPrev;
}
/*
* Now used to create list of servers for server list tree view -- David Flynn
* Recoded by codemastr to be faster.
* I removed the Potvin credit because it no longer uses any original code and I don't
* even think Potvin actually made the original code
*/
void win_map(Client *server, HWND hwTreeView, short remap)
{
/*
Client *acptr;
Link *lp;
AddItemToTree(hwTreeView,server->name,server->hopcount+1, remap);
for (lp = Servers; lp; lp = lp->next)
{
acptr = lp->value.client;
if (acptr->uplink != server)
continue;
win_map(acptr, hwTreeView, 0);
}
FIXME
*/
}
/* ugly stuff, but hey it works -- codemastr */
void win_log(FORMAT_STRING(const char *format), ...)
{
va_list ap;
unsigned char buf[2048];
FILE *fd;
va_start(ap, format);
ircvsnprintf(buf, sizeof(buf), format, ap);
stripcrlf(buf);
if (!IsService)
{
strcat(buf, "\r\n");
if (errors)
{
char *tbuf = safe_alloc(strlen(errors) + strlen(buf) + 1);
strcpy(tbuf, errors);
strcat(tbuf, buf);
safe_free(errors);
errors = tbuf;
}
else
{
safe_strdup(errors, buf);
}
}
else
{
FILE *fd = fopen("logs\\service.log", "a");
if (fd)
{
char timebuf[256];
snprintf(timebuf, sizeof(timebuf), "[%s]", myctime(time(NULL)));
fprintf(fd, "%s - %s\n", timebuf, buf);
fclose(fd);
}
#ifdef _DEBUG
else
{
OutputDebugString(buf);
}
#endif
}
va_end(ap);
}
void win_error()
{
if (errors && !IsService)
DialogBox(hInst, "ConfigError", hwIRCDWnd, (DLGPROC)ConfigErrorDLG);
if (need_34_upgrade)
{
need_34_upgrade = 0; /* anti-recursion. yes, is needed. */
if (MessageBox(NULL,
"Shall I try to upgrade your configuration files to UnrealIRCd 4 format?",
"3.2.x configuration detected",
MB_YESNO|MB_ICONQUESTION) == IDNO)
{
return;
}
else
{
update_conf();
MessageBox(NULL,
"Configuration file(s) upgraded! In next screen you can see what I did (just for reference). "
"After that, simply try to start UnrealIRCd again and see if it loads.",
"Configuration upgrade",
MB_OK);
DialogBox(hInst, "ConfigError", hwIRCDWnd, (DLGPROC)ConfigErrorDLG);
}
}
}
LRESULT CALLBACK ConfigErrorDLG(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
MessageBeep(MB_ICONEXCLAMATION);
SetDlgItemText(hDlg, IDC_CONFIGERROR, errors);
safe_free(errors);
errors = NULL;
return (TRUE);
case WM_COMMAND:
if (LOWORD(wParam) == IDOK)
EndDialog(hDlg, TRUE);
break;
case WM_CLOSE:
EndDialog(hDlg, TRUE);
break;
case WM_DESTROY:
break;
}
return (FALSE);
}