From a956e94f5c0b05dd94f4378248ac3f3d85385264 Mon Sep 17 00:00:00 2001 From: Robert Nelson Date: Thu, 27 Jul 2006 02:50:26 +0000 Subject: [PATCH] Add some missed files. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@3183 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/win32/stored/baculasd/bacula.bmp | Bin 0 -> 3126 bytes bacula/src/win32/stored/baculasd/bacula.ico | Bin 0 -> 766 bytes bacula/src/win32/stored/baculasd/bacula.rc | 1 + bacula/src/win32/stored/baculasd/error.ico | Bin 0 -> 766 bytes bacula/src/win32/stored/baculasd/idle.ico | Bin 0 -> 766 bytes bacula/src/win32/stored/baculasd/running.ico | Bin 0 -> 766 bytes bacula/src/win32/stored/baculasd/saving.ico | Bin 0 -> 766 bytes bacula/src/win32/stored/baculasd/warn.ico | Bin 0 -> 766 bytes bacula/src/win32/stored/baculasd/winabout.cpp | 80 ++ bacula/src/win32/stored/baculasd/winabout.h | 48 ++ bacula/src/win32/stored/baculasd/winbacula.h | 71 ++ .../src/win32/stored/baculasd/winevents.cpp | 87 ++ bacula/src/win32/stored/baculasd/winevents.h | 44 + bacula/src/win32/stored/baculasd/winmain.cpp | 331 ++++++++ bacula/src/win32/stored/baculasd/winres.h | 46 ++ bacula/src/win32/stored/baculasd/winres.rc | 181 +++++ .../src/win32/stored/baculasd/winservice.cpp | 753 ++++++++++++++++++ bacula/src/win32/stored/baculasd/winservice.h | 125 +++ bacula/src/win32/stored/baculasd/winstat.cpp | 97 +++ bacula/src/win32/stored/baculasd/winstat.h | 45 ++ bacula/src/win32/stored/baculasd/wintray.cpp | 357 +++++++++ bacula/src/win32/stored/baculasd/wintray.h | 93 +++ 22 files changed, 2359 insertions(+) create mode 100644 bacula/src/win32/stored/baculasd/bacula.bmp create mode 100644 bacula/src/win32/stored/baculasd/bacula.ico create mode 100644 bacula/src/win32/stored/baculasd/bacula.rc create mode 100644 bacula/src/win32/stored/baculasd/error.ico create mode 100644 bacula/src/win32/stored/baculasd/idle.ico create mode 100644 bacula/src/win32/stored/baculasd/running.ico create mode 100644 bacula/src/win32/stored/baculasd/saving.ico create mode 100644 bacula/src/win32/stored/baculasd/warn.ico create mode 100644 bacula/src/win32/stored/baculasd/winabout.cpp create mode 100644 bacula/src/win32/stored/baculasd/winabout.h create mode 100644 bacula/src/win32/stored/baculasd/winbacula.h create mode 100644 bacula/src/win32/stored/baculasd/winevents.cpp create mode 100644 bacula/src/win32/stored/baculasd/winevents.h create mode 100644 bacula/src/win32/stored/baculasd/winmain.cpp create mode 100644 bacula/src/win32/stored/baculasd/winres.h create mode 100644 bacula/src/win32/stored/baculasd/winres.rc create mode 100644 bacula/src/win32/stored/baculasd/winservice.cpp create mode 100644 bacula/src/win32/stored/baculasd/winservice.h create mode 100644 bacula/src/win32/stored/baculasd/winstat.cpp create mode 100644 bacula/src/win32/stored/baculasd/winstat.h create mode 100644 bacula/src/win32/stored/baculasd/wintray.cpp create mode 100644 bacula/src/win32/stored/baculasd/wintray.h diff --git a/bacula/src/win32/stored/baculasd/bacula.bmp b/bacula/src/win32/stored/baculasd/bacula.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a31eb1636902fbe82492cf1bcc9424b196296912 GIT binary patch literal 3126 zcmd6o!41MN3`NbI0XTAGf)2o)oiZAm!6(1^ib&KtPFvM#EjNvyznvnUujy*pCin;L z`+Q&Qh6pyl=L7xcSSw3+#U7a{C2WK5H7N1(-#tbpC*)g7x*!rg=@9{pUFI+a^jkg) zPL;HJ1tstbb|in{sG$Uc*|>%D1McMi+Ad6^&{{oz!WT*)SNfU0>RC?n7rfa;fX}|f zhdhxL@FRgIUysfJStVatHJ>Hea+epg44V9M!(hBCe^+?jI1Xq-`{Q>VrDrpxstQsN zul|%g8&n-7YQ9zi0jn?b^)?WA_yO5U@$dt(mEz%Z&xlvK=J^K5mW!e14=6nFeIt7e-mMG^>!P}Oo`Rqas4hADb?#lfFnd|d% literal 0 HcmV?d00001 diff --git a/bacula/src/win32/stored/baculasd/bacula.ico b/bacula/src/win32/stored/baculasd/bacula.ico new file mode 100644 index 0000000000000000000000000000000000000000..f6d50bf516caaa111e8598006ac9cac9ed166358 GIT binary patch literal 766 zcmbtSJx;?g7=0#0jMx!kPBRonq~rhy^#Cln0$1qjjca*l;0hgCP&-tj5>)1WcI<{! zl`8S#=g%+SuPg(KUtMbmJ}!V;+IzAlA4!Ev?x$g`g>w#|_1-g(w9#vx2PWQS9d{|GMa9(zmM9Oifg9J{yF$_zg`k0-syWK-!{PKm;c%Cp!Q4?eoMXst}RfUL&g>>lC`cR F_ZNY8Y|;P# literal 0 HcmV?d00001 diff --git a/bacula/src/win32/stored/baculasd/bacula.rc b/bacula/src/win32/stored/baculasd/bacula.rc new file mode 100644 index 0000000000..5849beb8e3 --- /dev/null +++ b/bacula/src/win32/stored/baculasd/bacula.rc @@ -0,0 +1 @@ +1 ICON "apcupsd.ico" diff --git a/bacula/src/win32/stored/baculasd/error.ico b/bacula/src/win32/stored/baculasd/error.ico new file mode 100644 index 0000000000000000000000000000000000000000..a8f85f120dbcc8483e9530af48554432945c2a91 GIT binary patch literal 766 zcmc&yu?~VT5Pd}wMy-RZwJeSret?0`a%lXrPEI8Lf}!Bzr^i}8{7j(2xG zt_gskN2wJU_YBxj+!GbCCJN-F^DxH1S_@DF+_XHymJp<9}LB@7nDn`rxlQm{6{?* z^`}?Y;|VMuK+ypUOTS!8`@DJDqP-kVdsdO`Ip6nPo$Hu%7DU0k(JY!*4BwcFFV=Zv AHvj+t literal 0 HcmV?d00001 diff --git a/bacula/src/win32/stored/baculasd/idle.ico b/bacula/src/win32/stored/baculasd/idle.ico new file mode 100644 index 0000000000000000000000000000000000000000..ce5315f2507bed96c9f4a12d542d7189ef1a2471 GIT binary patch literal 766 zcmc&yF%H5o47`*|9U%;?gmhs9^#dLHEQW}eWn!wt7Z@2kG9U#zX-TMBi3M@doqKlT zI#K{ZOQ{tY_YBxj+!GbCCJN-F^DxH1S_@Eg&dqQ9Nkt~$J0w<0PUr~96GW?nFRMyx zFTo#xwf5qDiKZ4_!u~RE8sX(jKRO>;$NqXJr4BMVAJ5#w*9Sv!>;>hL>uCjKBmYrP zTK(yh-iyZ*SU!NF0~VH^Tubx3dD^1A98G&xk?c9&@4GtJG3hLbf_bA})UO!+F%@4h CbY?XG literal 0 HcmV?d00001 diff --git a/bacula/src/win32/stored/baculasd/running.ico b/bacula/src/win32/stored/baculasd/running.ico new file mode 100644 index 0000000000000000000000000000000000000000..32dc42cd3c159fea18072b3b5baba6999d87c692 GIT binary patch literal 766 zcmc&yu?~VT5Pd}wMy-RZwJeSret?0`a%lXrPEI8Lf}!Bzr^i}8{7j(2xG zt_gskN2wJU_YBxj+!GbCCJN-F^DxH1S_@EwoA3KgMJC`oBvwjJ=m^OxM5}`@t4eDx z!5@IN_TqhsrWRg8f0;Lp@baY}oe!hqe7%!W2btWDckbcqgP}O~f^y0Av;wk`|EMRU z{`Bg4Jb~o{C^}$a>6dG1pEpliw3nl4&nl8V=li~^a~+e;f+(0bnnm-9;Tu!&1=o0F AHvj+t literal 0 HcmV?d00001 diff --git a/bacula/src/win32/stored/baculasd/saving.ico b/bacula/src/win32/stored/baculasd/saving.ico new file mode 100644 index 0000000000000000000000000000000000000000..f6d50bf516caaa111e8598006ac9cac9ed166358 GIT binary patch literal 766 zcmbtSJx;?g7=0#0jMx!kPBRonq~rhy^#Cln0$1qjjca*l;0hgCP&-tj5>)1WcI<{! zl`8S#=g%+SuPg(KUtMbmJ}!V;+IzAlA4!Ev?x$g`g>w#|_1-g(w9#vx2PWQS9d{|GMa9(zmM9Oifg9J{yF$_zg`k0-syWK-!{PKm;c%Cp!Q4?eoMXst}RfUL&g>>lC`cR F_ZNY8Y|;P# literal 0 HcmV?d00001 diff --git a/bacula/src/win32/stored/baculasd/warn.ico b/bacula/src/win32/stored/baculasd/warn.ico new file mode 100644 index 0000000000000000000000000000000000000000..26e1d398bb446fb55d02635a2afa4dc8489e0587 GIT binary patch literal 766 zcmc&yu?~VT5Pd}wMy-RZwJeSret?0`a%lXrPEI8Lf}!Bzr^i}8{7j(2xG zt_gskN2wJU_YBxj+!GbCCJN-F^DxH1S_@EwbMuWqsmKI;hr~+B2^}GMgJ^Z|WmReI zCHMod)?U0X(bU3A=r8l85njIZqw`^OoUeCM>L8Q*@yo9M@*nkN z)Sq5mk0-Ev07VBZEd6pV?epeoi}rFf?O8>#=X~FHb*^L5Sr7&DMzd&MF??exz5s&v BWi|i+ literal 0 HcmV?d00001 diff --git a/bacula/src/win32/stored/baculasd/winabout.cpp b/bacula/src/win32/stored/baculasd/winabout.cpp new file mode 100644 index 0000000000..5fbccae3a9 --- /dev/null +++ b/bacula/src/win32/stored/baculasd/winabout.cpp @@ -0,0 +1,80 @@ +/* + Copyright (C) 2000-2004 Kern Sibbald and John Walker + + 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. + + This file is patterned after the VNC Win32 code by ATT + + Kern E. Sibbald, 2000 +*/ + +#include "bacula.h" +#include "winbacula.h" +#include "winabout.h" +#include "winres.h" + +bacAbout::bacAbout() +{ + visible = false; +} + +bacAbout::~bacAbout() { }; + +void bacAbout::Show(BOOL show) +{ + if (show && !visible) { + DialogBoxParam(hAppInstance, MAKEINTRESOURCE(IDD_ABOUT), NULL, + (DLGPROC)DialogProc, (LONG)this); + } +} + + +BOOL CALLBACK +bacAbout::DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + /* Get the dialog class pointer from USERDATA */ + bacAbout *_this; + + switch (uMsg) { + case WM_INITDIALOG: + /* save the dialog class pointer */ + SetWindowLong(hwnd, GWL_USERDATA, lParam); + _this = (bacAbout *)lParam; + + /* Show the dialog */ + SetForegroundWindow(hwnd); + _this->visible = true; + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDCANCEL: + case IDOK: + EndDialog(hwnd, TRUE); + _this = (bacAbout *)GetWindowLong(hwnd, GWL_USERDATA); + _this->visible = false; + return TRUE; + } + break; + + case WM_DESTROY: + EndDialog(hwnd, FALSE); + _this = (bacAbout *)GetWindowLong(hwnd, GWL_USERDATA); + _this->visible = false; + return TRUE; + } + return 0; +} diff --git a/bacula/src/win32/stored/baculasd/winabout.h b/bacula/src/win32/stored/baculasd/winabout.h new file mode 100644 index 0000000000..46a6e94e3d --- /dev/null +++ b/bacula/src/win32/stored/baculasd/winabout.h @@ -0,0 +1,48 @@ +/* + Copyright (C) 2000-2004 Kern Sibbald and John Walker + + 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. + + This file was inspired by the VNC Win32 code by ATT + + Kern E. Sibbald, 2000 +*/ + + +/* Object implementing the About dialog for Bacula */ + +class bacAbout; + +#ifndef _WINABOUT_H_ +#define _WINABOUT_H_ 1 + +/* Define the bacAbout class */ +class bacAbout +{ +public: + bacAbout(); + ~bacAbout(); + + /* The dialog box window proc */ + static BOOL CALLBACK DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + + void Show(BOOL show); + + /* Object local storage */ + bool visible; +}; + +#endif diff --git a/bacula/src/win32/stored/baculasd/winbacula.h b/bacula/src/win32/stored/baculasd/winbacula.h new file mode 100644 index 0000000000..993b1ee8a6 --- /dev/null +++ b/bacula/src/win32/stored/baculasd/winbacula.h @@ -0,0 +1,71 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file was part of the VNC system. +// +// The VNC system 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. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. +// +// This file has been adapted to the Win32 version of Bacula +// by Kern E. Sibbald. Many thanks to ATT and James Weatherall, +// the original author, for providing an excellent template. +// +// Copyright (2000) Kern E. Sibbald +// + + +// Application specific messages + +// Message used for system tray notifications +#define WM_TRAYNOTIFY WM_USER+1 + +// Messages used for the server object to notify windows of things +#define WM_SRV_CLIENT_CONNECT WM_USER+2 +#define WM_SRV_CLIENT_AUTHENTICATED WM_USER+3 +#define WM_SRV_CLIENT_DISCONNECT WM_USER+4 + +// Export the application details +extern HINSTANCE hAppInstance; +extern const char *szAppName; +extern DWORD mainthreadId; + +// Main UPS server routine +extern int BaculaAppMain(); + +extern void LogErrorMsg(char *msg); + +// Standard command-line flag definitions +const char BaculaRunService[] = "/service"; +const char BaculaRunServiceHelper[] = "/servicehelper"; +const char BaculaRunAsUserApp[] = "/run"; + +const char BaculaInstallService[] = "/install"; +const char BaculaRemoveService[] = "/remove"; + +const char BaculaShowAbout[] = "/about"; +const char BaculaShowStatus[] = "/status"; +const char BaculaShowEvents[] = "/events"; +const char BaculaKillRunningCopy[] = "/kill"; + +const char BaculaShowHelp[] = "/help"; + +// Usage string +const char BaculaUsageText[] = "Bacula [/run] [/kill] [/install] [/remove] [/about] [/status] [/events]\n"; + +void LogErrorMsg(char *msg, char *fname, int lineno); +#define log_error_message(msg) LogErrorMsg((msg), __FILE__, __LINE__) diff --git a/bacula/src/win32/stored/baculasd/winevents.cpp b/bacula/src/win32/stored/baculasd/winevents.cpp new file mode 100644 index 0000000000..50edd0a5f5 --- /dev/null +++ b/bacula/src/win32/stored/baculasd/winevents.cpp @@ -0,0 +1,87 @@ +/* + Copyright (C) 2000-2003 Kern Sibbald and John Walker + + 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. + + This file is patterned after the VNC Win32 code by ATT + + Copyright (2000) Kern E. Sibbald +*/ + + +/* Code for the Events dialogue */ + +#include "bacula.h" +#include "winbacula.h" +#include "winevents.h" +#include "winres.h" + +extern "C" void FillEventsBox(HWND hwnd, int id_list); + +bacEvents::bacEvents() +{ + visible = FALSE; +} + +bacEvents::~bacEvents() +{ +} + +/* Show the dialogue box */ +void +bacEvents::Show(BOOL show) +{ + if (show && !visible) { + DialogBoxParam(hAppInstance, MAKEINTRESOURCE(IDD_EVENTS), NULL, + (DLGPROC)DialogProc, (LONG)this); + } +} + + +BOOL CALLBACK +bacEvents::DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + /* The dialog-box this pointer is in USERDATA */ + bacEvents *_this = (bacEvents *)GetWindowLong(hwnd, GWL_USERDATA); + + switch (uMsg) { + case WM_INITDIALOG: + /* Retrieve the Dialog box parameter */ + SetWindowLong(hwnd, GWL_USERDATA, lParam); + _this = (bacEvents *)lParam; + + /* Show the dialog */ + SetForegroundWindow(hwnd); + _this->visible = TRUE; + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDCANCEL: + case IDOK: + EndDialog(hwnd, TRUE); + _this->visible = FALSE; + return TRUE; + } + break; + + case WM_DESTROY: + EndDialog(hwnd, FALSE); + _this->visible = FALSE; + return TRUE; + } + return 0; +} diff --git a/bacula/src/win32/stored/baculasd/winevents.h b/bacula/src/win32/stored/baculasd/winevents.h new file mode 100644 index 0000000000..a28d66e124 --- /dev/null +++ b/bacula/src/win32/stored/baculasd/winevents.h @@ -0,0 +1,44 @@ +/* Object implementing the Events dialog for Bacula */ +/* + Copyright (C) 2000-2003 Kern Sibbald and John Walker + + 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. + + */ + + +class bacEvents; + +#ifndef _win_bacEVENTS +#define _win_bacEVENTS 1 + +/* Define the bacEvents class */ +class bacEvents +{ +public: + bacEvents(); + ~bacEvents(); + + /* The dialog box window proc */ + static BOOL CALLBACK DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + + void Show(BOOL show); + + /* Object local storage */ + BOOL visible; +}; + +#endif diff --git a/bacula/src/win32/stored/baculasd/winmain.cpp b/bacula/src/win32/stored/baculasd/winmain.cpp new file mode 100644 index 0000000000..e673db377b --- /dev/null +++ b/bacula/src/win32/stored/baculasd/winmain.cpp @@ -0,0 +1,331 @@ +/* + Copyright (C) 2000-2005 Kern Sibbald + + 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. + + This file is patterned after the VNC Win32 code by ATT + +*/ + +#include +#include +#include "bacula.h" +#include "winbacula.h" +#include "wintray.h" +#include "winservice.h" +#include +#include + +extern int BaculaMain(int argc, char *argv[]); +extern void terminate_stored(int sig); +extern DWORD g_error; +extern BOOL ReportStatus(DWORD state, DWORD exitcode, DWORD waithint); +extern void d_msg(const char *, int, int, const char *, ...); + +/* Globals */ +HINSTANCE hAppInstance; +const char *szAppName = "Bacula"; +DWORD mainthreadId; + +/* Imported variables */ +extern DWORD g_servicethread; + +#define MAX_COMMAND_ARGS 100 +static char *command_args[MAX_COMMAND_ARGS] = {"bacula-sd", NULL}; +static int num_command_args = 1; +static pid_t main_pid; +static pthread_t main_tid; + +/* + * WinMain parses the command line and either calls the main App + * routine or, under NT, the main service routine. + */ +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + PSTR CmdLine, int iCmdShow) +{ + char *szCmdLine = CmdLine; + char *wordPtr, *tempPtr; + int i, quote; + + /* Save the application instance and main thread id */ + hAppInstance = hInstance; + mainthreadId = GetCurrentThreadId(); + + main_pid = getpid(); + main_tid = pthread_self(); + + /* + * Funny things happen with the command line if the + * execution comes from c:/Program Files/bacula/bacula.exe + * We get a command line like: Files/bacula/bacula.exe" options + * I.e. someone stops scanning command line on a space, not + * realizing that the filename is quoted!!!!!!!!!! + * So if first character is not a double quote and + * the last character before first space is a double + * quote, we throw away the junk. + */ + + wordPtr = szCmdLine; + while (*wordPtr && *wordPtr != ' ') + wordPtr++; + if (wordPtr > szCmdLine) /* backup to char before space */ + wordPtr--; + /* if first character is not a quote and last is, junk it */ + if (*szCmdLine != '"' && *wordPtr == '"') { + szCmdLine = wordPtr + 1; + } +// MessageBox(NULL, szCmdLine, "Cmdline", MB_OK); + + /* Build Unix style argc *argv[] */ + + /* Don't NULL command_args[0] !!! */ + for (i=1;i +#include +#include "winres.h" +#include "../../../version.h" + +/* NB: Internationalization of this file will require some work... */ +#define N_(s) s + +///////////////////////////////////////////////////////////////////////////// +// +// Icons +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_BACULA ICON DISCARDABLE "bacula.ico" +IDI_IDLE ICON DISCARDABLE "idle.ico" +IDI_RUNNING ICON DISCARDABLE "running.ico" +IDI_JOB_ERROR ICON DISCARDABLE "error.ico" +IDI_JOB_WARNING ICON DISCARDABLE "warn.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_TRAYMENU MENU DISCARDABLE +BEGIN + POPUP "tray" + BEGIN + MENUITEM N_("&Status"), ID_STATUS + MENUITEM N_("&Events"), ID_EVENTS +#ifdef properties_implemented + MENUITEM N_("&Properties"), ID_PROPERTIES +#endif + MENUITEM SEPARATOR + MENUITEM N_("&About Bacula"), ID_ABOUT + MENUITEM SEPARATOR + MENUITEM N_("&Close Bacula"), ID_CLOSE + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,1,0,0 + PRODUCTVERSION 1,1,0,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0 // +#endif + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE 0 +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E0" // Lang=US English, CharSet=Windows Multiligual + BEGIN + VALUE "Comments", "by Kern Sibbald\0" + VALUE "CompanyName", " \0" + VALUE "FileDescription", "Bacula File daemon for Win32\0" + VALUE "FileVersion", VERSION "\0" + VALUE "InternalName", "Bacula\0" + VALUE "LegalCopyright", "Copyright Kern Sibbald, 1999-2006\0" + VALUE "LegalTrademarks", "Licensed under GNU GPL 2.0\0" + VALUE "OriginalFilename", "filed.exe\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "Bacula - Win32 Version\0" + VALUE "ProductVersion", VERSION + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 // US English, Multilingual + END +END + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_BACULABMP BITMAP DISCARDABLE "bacula.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + IDI_BACULA "Bacula" +END + +///////////////////////////////////////////////////////////////////////////// +// +// Properties Dialog +// +#ifdef properties_implemented + +IDD_PROPERTIES DIALOG DISCARDABLE 0, 0, 221, 204 +STYLE DS_MODALFRAME | DS_3DLOOK | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | + WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Bacula Properties" +FONT 8, "MS Sans Serif" +BEGIN + PUSHBUTTON N_("&Cancel"),IDCANCEL,165,25,51,15 + DEFPUSHBUTTON N_("&OK"),IDOK,165,5,51,15 + LTEXT "No Properites yet",IDC_NONYET_LABEL,19,30,56,15, + SS_CENTERIMAGE +END +#endif + +///////////////////////////////////////////////////////////////////////////// +// +// About Dialog +// + +IDD_ABOUT DIALOG DISCARDABLE 0, 0, 250, 145 +STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "About Bacula" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,190,120,50,15 +// CONTROL "\3", IDC_BACULABMP,"Static",SS_ICON | SS_CENTERIMAGE | +// SS_SUNKEN,7,5,73,65 +#ifndef HAVE_MINGW + CONTROL IDB_BACULABMP,IDB_BACULABMP,"Static",SS_BITMAP|SS_SUNKEN,7,5,32,32 +#endif + + LTEXT N_(" by Kern Sibbald"),IDC_NAME,134,38,78,10 + LTEXT N_("For more information, see:"),-1,115,60,100,10 + LTEXT " www.bacula.org",IDC_WWW,115,70,100,10 +// LTEXT " ",-1,69,81,100,10 +// LTEXT " ",-1,90,70,100,10 + LTEXT "Copyright (C) 1999-2006, Kern Sibbald",IDC_COPYRIGHT,7,120,175,10 + LTEXT N_("Licensed under GNU GPL 2.0."),IDC_TRADEMARK,7,130,175,10 + RTEXT N_("Build Date:"),-1,108,24,42,8 + RTEXT N_("Bacula Version:"),-1,100,9,50,8 + LTEXT VERSION,IDC_VERSION,159,10,65,8 + LTEXT BDATE,-1,159,24,65,10 + +END + +///////////////////////////////////////////////////////////////////////////// +// +// Status Dialog +// + +IDD_STATUS DIALOG DISCARDABLE 0, 0, 411, 244 +STYLE DS_MODALFRAME | DS_3DLOOK | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | + WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION N_("Bacula Status") +FONT 8, "Courier New" +BEGIN + DEFPUSHBUTTON "&OK",IDOK,355,5,51,15 + LISTBOX IDC_LIST, 2, 2, 350, 240, WS_VSCROLL | WS_HSCROLL | WS_BORDER +END + +///////////////////////////////////////////////////////////////////////////// +// +// Events Dialog +// + +IDD_EVENTS DIALOG DISCARDABLE 0, 0, 411, 204 +STYLE DS_MODALFRAME | DS_3DLOOK | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | + WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION N_("Bacula Events") +FONT 8, "Courier New" +BEGIN + DEFPUSHBUTTON "&OK",IDOK,355,5,51,15 + LISTBOX IDC_LIST, 2, 2, 350, 200, WS_VSCROLL | WS_HSCROLL | WS_BORDER +END diff --git a/bacula/src/win32/stored/baculasd/winservice.cpp b/bacula/src/win32/stored/baculasd/winservice.cpp new file mode 100644 index 0000000000..cde43b64e2 --- /dev/null +++ b/bacula/src/win32/stored/baculasd/winservice.cpp @@ -0,0 +1,753 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file was part of the VNC system. +// +// The VNC system 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. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. +// +// This file has been adapted to the Win32 version of Bacula +// by Kern E. Sibbald. Many thanks to ATT and James Weatherall, +// the original author, for providing an excellent template. +// +// Copyright (2000-2003) Kern E. Sibbald +// + + +// winService + +// Implementation of service-oriented functionality of Bacula +// I.e. command line options that contact a running version of +// Bacula and ask it to do something (show about, show status, +// show events, ...) + + +#include "bacula.h" +#include "winbacula.h" +#include "winservice.h" +#include "wintray.h" + +void set_service_description(SC_HANDLE hSCManager, SC_HANDLE hService, + LPSTR lpDesc); + +// OS-SPECIFIC ROUTINES + +// Create an instance of the bacService class to cause the static fields to be +// initialised properly + +bacService init; + +bacService::bacService() +{ + OSVERSIONINFO osversioninfo; + osversioninfo.dwOSVersionInfoSize = sizeof(osversioninfo); + + // Get the current OS version + if (!GetVersionEx(&osversioninfo)) { + g_platform_id = 0; + } else { + g_platform_id = osversioninfo.dwPlatformId; + } +} + + +// IsWin95 - returns a BOOL indicating whether the current OS is Win95 +BOOL +bacService::IsWin95() +{ + return (g_platform_id == VER_PLATFORM_WIN32_WINDOWS); +} + +// IsWinNT - returns a bool indicating whether the current OS is WinNT +BOOL +bacService::IsWinNT() +{ + return (g_platform_id == VER_PLATFORM_WIN32_NT); +} + +// Internal routine to find the Bacula menu class window and +// post a message to it! + +BOOL +PostToBacula(UINT message, WPARAM wParam, LPARAM lParam) +{ + // Locate the hidden Bacula menu window + HWND hservwnd = FindWindow(MENU_CLASS_NAME, NULL); + if (hservwnd == NULL) { + return FALSE; + } + + // Post the message to Bacula + PostMessage(hservwnd, message, wParam, lParam); + return TRUE; +} + + +// Static routine to show the Properties dialog for a currently-running +// copy of Bacula, (usually a servicified version.) + +BOOL +bacService::ShowProperties() +{ + return TRUE; +} + +// Static routine to show the Default Properties dialog for a currently-running +// copy of Bacula, (usually a servicified version.) + +BOOL +bacService::ShowDefaultProperties() +{ + return TRUE; +} + +// Static routine to show the About dialog for a currently-running +// copy of Bacula, (usually a servicified version.) + +BOOL +bacService::ShowAboutBox() +{ + // Post to the Bacula menu window + if (!PostToBacula(MENU_ABOUTBOX_SHOW, 0, 0)) { + MessageBox(NULL, _("No existing instance of Bacula could be contacted"), szAppName, MB_ICONEXCLAMATION | MB_OK); + return FALSE; + } + return TRUE; +} + +// Static routine to show the Status dialog for a currently-running +// copy of Bacula, (usually a servicified version.) + +BOOL +bacService::ShowStatus() +{ + // Post to the Bacula menu window + if (!PostToBacula(MENU_STATUS_SHOW, 0, 0)) { + MessageBox(NULL, _("No existing instance of Bacula could be contacted"), szAppName, MB_ICONEXCLAMATION | MB_OK); + return FALSE; + } + return TRUE; +} + +// SERVICE-MODE ROUTINES + +// Service-mode defines: + +// Executable name +#define BAC_APPNAME "baculasd" + +// Internal service name +#define BAC_SERVICENAME "Baculasd" + +// Displayed service name +#define BAC_SERVICEDISPLAYNAME "Bacula Storage Server" + +// List other required serves +#define BAC_DEPENDENCIES __TEXT("tcpip\0afd\0+File System\0") + + +// Internal service state +SERVICE_STATUS g_srvstatus; // current status of the service +SERVICE_STATUS_HANDLE g_hstatus; +DWORD g_error = 0; +DWORD g_servicethread = 0; +char* g_errortext[256]; + + +// Forward defines of internal service functions +void WINAPI ServiceMain(DWORD argc, char **argv); +DWORD WINAPI ServiceWorkThread(LPVOID lpwThreadParam); +void ServiceStop(); +void WINAPI ServiceCtrl(DWORD ctrlcode); +bool WINAPI CtrlHandler (DWORD ctrltype); +BOOL ReportStatus(DWORD state, DWORD exitcode, DWORD waithint); + +// ROUTINE TO QUERY WHETHER THIS PROCESS IS RUNNING AS A SERVICE OR NOT + +BOOL g_servicemode = FALSE; + +BOOL +bacService::RunningAsService() +{ + return g_servicemode; +} + +BOOL +bacService::KillRunningCopy() +{ + while (PostToBacula(WM_CLOSE, 0, 0)) + { } + return TRUE; +} + +// SERVICE MAIN ROUTINE +int +bacService::BaculaServiceMain() +{ + // Mark that we are a service + g_servicemode = TRUE; + + // How to run as a service depends upon the OS being used + switch (g_platform_id) { + + // Windows 95/98/Me + case VER_PLATFORM_WIN32_WINDOWS: + { + // Obtain a handle to the kernel library + HINSTANCE kerneldll = LoadLibrary("KERNEL32.DLL"); + if (kerneldll == NULL) { + MessageBox(NULL, _("KERNEL32.DLL not found: Bacula service not started"), + "Bacula Service", MB_OK); + break; + } + + // And find the RegisterServiceProcess function + DWORD (WINAPI *RegisterService)(DWORD, DWORD); + RegisterService = (DWORD (WINAPI *)(DWORD, DWORD)) + GetProcAddress(kerneldll, "RegisterServiceProcess"); + if (RegisterService == NULL) { + MessageBox(NULL, _("Registry service not found: Bacula service not started"), + "Bacula Service", MB_OK); + log_error_message(_("Registry service not found")); + break; + } + + // Register this process with the OS as a service! + RegisterService(0, 1); + + // Run the main program as a service + BaculaAppMain(); + + // Then remove the service from the system service table + RegisterService(0, 0); + + // Free the kernel library + FreeLibrary(kerneldll); + break; + } + + + // Windows NT, Win2K, WinXP + case VER_PLATFORM_WIN32_NT: + { + // Create a service entry table + SERVICE_TABLE_ENTRY dispatchTable[] = { + {BAC_SERVICENAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain}, + {NULL, NULL} + }; + + // Call the service control dispatcher with our entry table + if (!StartServiceCtrlDispatcher(dispatchTable)) { + log_error_message(_("StartServiceCtrlDispatcher failed.")); + } + break; + } /* end case */ + } /* end switch */ + return 0; +} + +// SERVICE MAIN ROUTINE - NT ONLY !!! +// NT/Win2K/WinXP ONLY !!! +void WINAPI ServiceMain(DWORD argc, char **argv) +{ + DWORD dwThreadID; + + // Register the service control handler + g_hstatus = RegisterServiceCtrlHandler(BAC_SERVICENAME, ServiceCtrl); + + if (g_hstatus == 0) { + log_error_message(_("RegisterServiceCtlHandler failed")); + MessageBox(NULL, _("Contact Register Service Handler failure"), + "Bacula service", MB_OK); + return; + } + + // Set up some standard service state values + g_srvstatus.dwServiceType = SERVICE_WIN32 | SERVICE_INTERACTIVE_PROCESS; + g_srvstatus.dwServiceSpecificExitCode = 0; + + // Give this status to the SCM + if (!ReportStatus( + SERVICE_START_PENDING, // Service state + NO_ERROR, // Exit code type + 45000)) { // Hint as to how long Bacula should have hung before you assume error + + ReportStatus(SERVICE_STOPPED, g_error, 0); + log_error_message(_("ReportStatus STOPPED failed 1")); + return; + } + + // Now start the service for real + (void)CreateThread(NULL, 0, ServiceWorkThread, NULL, 0, &dwThreadID); + return; +} + +// SERVICE START ROUTINE - thread that calls BaculaAppMain +// NT ONLY !!!! +DWORD WINAPI ServiceWorkThread(LPVOID lpwThreadParam) +{ + + // Save the current thread identifier + g_servicethread = GetCurrentThreadId(); + + // report the status to the service control manager. + // + if (!ReportStatus( + SERVICE_RUNNING, // service state + NO_ERROR, // exit code + 0)) { // wait hint + MessageBox(NULL, _("Report Service failure"), "Bacula Service", MB_OK); + log_error_message("ReportStatus RUNNING failed"); + return 0; + } + + /* Call Bacula main code */ + BaculaAppMain(); + + /* Mark that we're no longer running */ + g_servicethread = 0; + + /* Tell the service manager that we've stopped */ + ReportStatus(SERVICE_STOPPED, g_error, 0); + return 0; +} + + +// SERVICE STOP ROUTINE - post a quit message to the relevant thread +void ServiceStop() +{ + // Post a quit message to the main service thread + if (g_servicethread != 0) { + PostThreadMessage(g_servicethread, WM_QUIT, 0, 0); + } +} + +// SERVICE INSTALL ROUTINE +int +bacService::InstallService() +{ + const int pathlength = 2048; + char path[pathlength]; + char servicecmd[pathlength]; + int len; + + // Get the filename of this executable + if (GetModuleFileName(NULL, path, pathlength-(strlen(BaculaRunService)+2)) == 0) { + MessageBox(NULL, _("Unable to install Bacula service"), szAppName, MB_ICONEXCLAMATION | MB_OK); + return 0; + } + + // Append the service-start flag to the end of the path: + if ((int)strlen(path) + 20 + (int)strlen(BaculaRunService) < pathlength) { + sprintf(servicecmd, "\"%s\" %s -c \"%s", path, BaculaRunService, path); + len = strlen(servicecmd) - 1; + for ( ; len > 0; len--) { + if (servicecmd[len] == '\\') { + servicecmd[len+1] = 0; + break; + } + servicecmd[len] = 0; + } + strcat(servicecmd, "bacula-sd.conf\""); + + } else { + log_error_message(_("Service command length too long")); + MessageBox(NULL, _("Service command length too long. Service not registered."), + szAppName, MB_ICONEXCLAMATION | MB_OK); + return 0; + } + + // How to add the Bacula service depends upon the OS + switch (g_platform_id) { + + // Windows 95/98/Me + case VER_PLATFORM_WIN32_WINDOWS: + // Locate the RunService registry entry + HKEY runservices; + if (RegCreateKey(HKEY_LOCAL_MACHINE, + "Software\\Microsoft\\Windows\\CurrentVersion\\RunServices", + &runservices) != ERROR_SUCCESS) { + log_error_message(_("Cannot write System Registry")); + MessageBox(NULL, _("The System Registry could not be updated - the Bacula service was not installed"), szAppName, MB_ICONEXCLAMATION | MB_OK); + break; + } + + // Attempt to add a Bacula key + if (RegSetValueEx(runservices, szAppName, 0, REG_SZ, (unsigned char *)servicecmd, strlen(servicecmd)+1) != ERROR_SUCCESS) { + RegCloseKey(runservices); + log_error_message(_("Cannot add Bacula key to System Registry")); + MessageBox(NULL, _("The Bacula service could not be installed"), szAppName, MB_ICONEXCLAMATION | MB_OK); + break; + } + + RegCloseKey(runservices); + + // We have successfully installed the service! + MessageBox(NULL, + _("The Bacula File service was successfully installed.\n" + "The service may be started by double clicking on the\n" + "Bacula \"Start\" icon and will be automatically\n" + "be run the next time this machine is rebooted. "), + szAppName, + MB_ICONINFORMATION | MB_OK); + break; + + // Windows NT, Win2K, WinXP + case VER_PLATFORM_WIN32_NT: + SC_HANDLE hservice; + SC_HANDLE hsrvmanager; + + // Open the default, local Service Control Manager database + hsrvmanager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + if (hsrvmanager == NULL) { + log_error_message("OpenSCManager failed"); + MessageBox(NULL, + _("The Service Control Manager could not be contacted - the Bacula service was not installed"), + szAppName, MB_ICONEXCLAMATION | MB_OK); + break; + } + + // Create an entry for the Bacula service + hservice = CreateService( + hsrvmanager, // SCManager database + BAC_SERVICENAME, // name of service + BAC_SERVICEDISPLAYNAME, // name to display + SERVICE_ALL_ACCESS, // desired access + SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, + // service type + SERVICE_AUTO_START, // start type + SERVICE_ERROR_NORMAL, // error control type + servicecmd, // service's binary + NULL, // no load ordering group + NULL, // no tag identifier + BAC_DEPENDENCIES, // dependencies + NULL, // LocalSystem account + NULL); // no password + if (hservice == NULL) { + CloseServiceHandle(hsrvmanager); + log_error_message("CreateService failed"); + MessageBox(NULL, + _("The Bacula service could not be installed"), + szAppName, MB_ICONEXCLAMATION | MB_OK); + break; + } + + set_service_description(hsrvmanager,hservice, +_("Provides file backup and restore services. Bacula -- the network backup solution.")); + + CloseServiceHandle(hsrvmanager); + CloseServiceHandle(hservice); + + // Everything went fine + MessageBox(NULL, + _("The Bacula File service was successfully installed.\n" + "The service may be started from the Control Panel and will\n" + "automatically be run the next time this machine is rebooted."), + szAppName, + MB_ICONINFORMATION | MB_OK); + break; + default: + log_error_message("Unknown Windows System version"); + MessageBox(NULL, + _("Unknown Windows operating system.\n" + "Cannot install Bacula service.\n"), + szAppName, MB_ICONEXCLAMATION | MB_OK); + break; + }; + + return 0; +} + + +// SERVICE REMOVE ROUTINE +int +bacService::RemoveService() +{ + // How to remove the Bacula service depends upon the OS + switch (g_platform_id) { + + // Windows 95/98/Me + case VER_PLATFORM_WIN32_WINDOWS: + // Locate the RunService registry entry + HKEY runservices; + if (RegOpenKey(HKEY_LOCAL_MACHINE, + "Software\\Microsoft\\Windows\\CurrentVersion\\RunServices", + &runservices) != ERROR_SUCCESS) { + MessageBox(NULL, + _("Could not find registry entry.\nService probably not registerd - the Bacula service was not removed"), szAppName, MB_ICONEXCLAMATION | MB_OK); + } else { + // Attempt to delete the Bacula key + if (RegDeleteValue(runservices, szAppName) != ERROR_SUCCESS) { + RegCloseKey(runservices); + MessageBox(NULL, _("Could not delete Registry key.\nThe Bacula service could not be removed"), szAppName, MB_ICONEXCLAMATION | MB_OK); + } + + RegCloseKey(runservices); + break; + } + + // Try to kill any running copy of Bacula + if (!KillRunningCopy()) { + MessageBox(NULL, + _("Bacula could not be contacted, probably not running"), + szAppName, MB_ICONEXCLAMATION | MB_OK); + break; + } + + // We have successfully removed the service! + MessageBox(NULL, _("The Bacula service has been removed"), szAppName, MB_ICONINFORMATION | MB_OK); + break; + + // Windows NT, Win2K, WinXP + case VER_PLATFORM_WIN32_NT: + SC_HANDLE hservice; + SC_HANDLE hsrvmanager; + + // Open the SCM + hsrvmanager = OpenSCManager( + NULL, // machine (NULL == local) + NULL, // database (NULL == default) + SC_MANAGER_ALL_ACCESS // access required + ); + if (hsrvmanager) { + hservice = OpenService(hsrvmanager, BAC_SERVICENAME, SERVICE_ALL_ACCESS); + if (hservice != NULL) { + SERVICE_STATUS status; + + // Try to stop the Bacula service + if (ControlService(hservice, SERVICE_CONTROL_STOP, &status)) { + while(QueryServiceStatus(hservice, &status)) { + if (status.dwCurrentState == SERVICE_STOP_PENDING) { + Sleep(1000); + } else { + break; + } + } + + if (status.dwCurrentState != SERVICE_STOPPED) { + MessageBox(NULL, _("The Bacula service could not be stopped"), szAppName, MB_ICONEXCLAMATION | MB_OK); + } + } + + // Now remove the service from the SCM + if(DeleteService(hservice)) { + MessageBox(NULL, _("The Bacula service has been removed"), szAppName, MB_ICONINFORMATION | MB_OK); + } else { + MessageBox(NULL, _("The Bacula service could not be removed"), szAppName, MB_ICONEXCLAMATION | MB_OK); + } + + CloseServiceHandle(hservice); + } else { + MessageBox(NULL, _("The Bacula service could not be found"), szAppName, MB_ICONEXCLAMATION | MB_OK); + } + + CloseServiceHandle(hsrvmanager); + } else { + MessageBox(NULL, _("The SCM could not be contacted - the Bacula service was not removed"), szAppName, MB_ICONEXCLAMATION | MB_OK); + } + break; + } + return 0; +} + +// USEFUL SERVICE SUPPORT ROUTINES + +// Service control routine +void WINAPI ServiceCtrl(DWORD ctrlcode) +{ + // What control code have we been sent? + switch(ctrlcode) { + case SERVICE_CONTROL_STOP: + // STOP : The service must stop + g_srvstatus.dwCurrentState = SERVICE_STOP_PENDING; + ServiceStop(); + break; + + case SERVICE_CONTROL_INTERROGATE: + // QUERY : Service control manager just wants to know our state + break; + + default: + // Control code not recognised + break; + } + + // Tell the control manager what we're up to. + ReportStatus(g_srvstatus.dwCurrentState, NO_ERROR, 0); +} + +// Service manager status reporting +BOOL ReportStatus(DWORD state, + DWORD exitcode, + DWORD waithint) +{ + static DWORD checkpoint = 1; + BOOL result = TRUE; + + // If we're in the start state then we don't want the control manager + // sending us control messages because they'll confuse us. + if (state == SERVICE_START_PENDING) { + g_srvstatus.dwControlsAccepted = 0; + } else { + g_srvstatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; + } + + // Save the new status we've been given + g_srvstatus.dwCurrentState = state; + g_srvstatus.dwWin32ExitCode = exitcode; + g_srvstatus.dwWaitHint = waithint; + + // Update the checkpoint variable to let the SCM know that we + // haven't died if requests take a long time + if ((state == SERVICE_RUNNING) || (state == SERVICE_STOPPED)) { + g_srvstatus.dwCheckPoint = 0; + } else { + g_srvstatus.dwCheckPoint = checkpoint++; + } + + // Tell the SCM our new status + if (!(result = SetServiceStatus(g_hstatus, &g_srvstatus))) { + log_error_message(_("SetServiceStatus failed")); + } + + return result; +} + +// Error reporting +void LogErrorMsg(char *message, char *fname, int lineno) +{ + char msgbuff[256]; + HANDLE heventsrc; + char * strings[32]; + LPTSTR msg; + + // Get the error code + g_error = GetLastError(); + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER| + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + g_error, + 0, + (LPTSTR)&msg, + 0, + NULL); + + // Use event logging to log the error + heventsrc = RegisterEventSource(NULL, BAC_SERVICENAME); + + sprintf(msgbuff, _("\n\n%s error: %ld at %s:%d"), + BAC_SERVICENAME, g_error, fname, lineno); + strings[0] = msgbuff; + strings[1] = message; + strings[2] = msg; + + if (heventsrc != NULL) { + MessageBeep(MB_OK); + + ReportEvent( + heventsrc, // handle of event source + EVENTLOG_ERROR_TYPE, // event type + 0, // event category + 0, // event ID + NULL, // current user's SID + 3, // strings in 'strings' + 0, // no bytes of raw data + (const char **)strings, // array of error strings + NULL); // no raw data + + DeregisterEventSource(heventsrc); + } + LocalFree(msg); +} +typedef BOOL (WINAPI * WinAPI)(SC_HANDLE, DWORD, LPVOID); + +void set_service_description(SC_HANDLE hSCManager, SC_HANDLE hService, + LPSTR lpDesc) +{ + SC_LOCK sclLock; + LPQUERY_SERVICE_LOCK_STATUS lpqslsBuf; + SERVICE_DESCRIPTION sdBuf; + DWORD dwBytesNeeded; + WinAPI ChangeServiceDescription; + + HINSTANCE hLib = LoadLibrary("ADVAPI32.DLL"); + if (!hLib) { + return; + } + ChangeServiceDescription = (WinAPI)GetProcAddress(hLib, + "ChangeServiceConfig2A"); + FreeLibrary(hLib); + if (!ChangeServiceDescription) { + return; + } + + // Need to acquire database lock before reconfiguring. + sclLock = LockServiceDatabase(hSCManager); + + // If the database cannot be locked, report the details. + if (sclLock == NULL) { + // Exit if the database is not locked by another process. + if (GetLastError() != ERROR_SERVICE_DATABASE_LOCKED) { + log_error_message("LockServiceDatabase"); + return; + } + + // Allocate a buffer to get details about the lock. + lpqslsBuf = (LPQUERY_SERVICE_LOCK_STATUS)LocalAlloc( + LPTR, sizeof(QUERY_SERVICE_LOCK_STATUS)+256); + if (lpqslsBuf == NULL) { + log_error_message("LocalAlloc"); + return; + } + + // Get and print the lock status information. + if (!QueryServiceLockStatus( + hSCManager, + lpqslsBuf, + sizeof(QUERY_SERVICE_LOCK_STATUS)+256, + &dwBytesNeeded)) { + log_error_message("QueryServiceLockStatus"); + } + + if (lpqslsBuf->fIsLocked) { + printf(_("Locked by: %s, duration: %ld seconds\n"), + lpqslsBuf->lpLockOwner, + lpqslsBuf->dwLockDuration); + } else { + printf(_("No longer locked\n")); + } + + LocalFree(lpqslsBuf); + log_error_message(_("Could not lock database")); + return; + } + + // The database is locked, so it is safe to make changes. + + sdBuf.lpDescription = lpDesc; + + if (!ChangeServiceDescription( + hService, // handle to service + SERVICE_CONFIG_DESCRIPTION, // change: description + &sdBuf) ) { // value: new description + log_error_message("ChangeServiceConfig2"); + } + + // Release the database lock. + UnlockServiceDatabase(sclLock); +} diff --git a/bacula/src/win32/stored/baculasd/winservice.h b/bacula/src/win32/stored/baculasd/winservice.h new file mode 100644 index 0000000000..2195b58fca --- /dev/null +++ b/bacula/src/win32/stored/baculasd/winservice.h @@ -0,0 +1,125 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file was part of the ups system. +// +// The ups system 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. +// +// If the source code for the ups system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on ups@uk.research.att.com for information on obtaining it. +// +// This file has been adapted to the Win32 version of Bacula +// by Kern E. Sibbald. Many thanks to ATT and James Weatherall, +// the original author, for providing an excellent template. +// +// Copyright (2000) Kern E. Sibbald +// + + +// winservice.cpp + +// SERVICE-MODE CODE + +// This class provides access to service-oriented routines, under both +// Windows NT and Windows 95. Some routines only operate under one +// OS, others operate under any OS. + +class bacService; + +#if (!defined(_win_bacService)) +#define _win_bacService + +// The NT-specific code wrapper class +class bacService +{ +public: + bacService(); + + // SERVICE INSTALL & START FUNCTIONS + + // Routine called by WinMain to cause Bacula to be installed + // as a service. + static int BaculaServiceMain(); + + // Routine to install the Apcupsd service on the local machine + static int InstallService(); + + // Routine to remove the Apcupsd service from the local machine + static int RemoveService(); + + // SERVICE SUPPORT FUNCTIONS + + // Routine to establish and return the currently logged in user name + static BOOL CurrentUser(char *buffer, UINT size); + + // Routine to post a message to the currently running Apcupsd server + // to pass it a handle to the current user + static BOOL PostUserHelperMessage(); + // Routine to process a user helper message + static BOOL ProcessUserHelperMessage(WPARAM wParam, LPARAM lParam); + + // Routines to establish which OS we're running on + static BOOL IsWin95(); + static BOOL IsWinNT(); + + // Routine to establish whether the current instance is running + // as a service or not + static BOOL RunningAsService(); + + // Routine to kill any other running copy of Apcupsd + static BOOL KillRunningCopy(); + + // Routine to set the current thread into the given desktop + static BOOL SelectHDESK(HDESK newdesktop); + + // Routine to set the current thread into the named desktop, + // or the input desktop if no name is given + static BOOL SelectDesktop(char *name); + + // Routine to establish whether the current thread desktop is the + // current user input one + static BOOL InputDesktopSelected(); + + // Routine to fake a CtrlAltDel to winlogon when required. + // *** This is a nasty little hack... + static BOOL SimulateCtrlAltDel(); + + // Routine to make any currently running version of Apcupsd show its + // Properties dialog, to allow the user to make changes to their settings + static BOOL ShowProperties(); + + // Routine to make any currently running version of Apcupsd show the + // Properties dialog for the default settings, so the user can make changes + static BOOL ShowDefaultProperties(); + + // Routine to make the an already running copy of Apcupsd bring up its + // About box so you can check the version! + static BOOL ShowAboutBox(); + + // Routine to make the an already running copy of Apcupsd bring up its + // Status dialog + static BOOL ShowStatus(); + + // Routine to make the an already running copy of Apcupsd bring up its + // Events dialog + static BOOL ShowEvents(); + + // Routine to make an already running copy of Apcupsd form an outgoing + // connection to a new ups client + static BOOL PostAddNewClient(unsigned long ipaddress); +}; + +#endif diff --git a/bacula/src/win32/stored/baculasd/winstat.cpp b/bacula/src/win32/stored/baculasd/winstat.cpp new file mode 100644 index 0000000000..45e3c41ad1 --- /dev/null +++ b/bacula/src/win32/stored/baculasd/winstat.cpp @@ -0,0 +1,97 @@ +/* + * Bacula File daemon Status Dialog box + * + * Inspired from the VNC code by ATT. + * + * Copyright (2000) Kern E. Sibbald + * + */ +/* + Copyright (C) 2000-2003 Kern Sibbald and John Walker + + 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 "bacula.h" +#include "winbacula.h" +#include "winstat.h" +#include "winres.h" + +extern void FillStatusBox(HWND hwnd, int id_list); + +bacStatus::bacStatus() +{ + visible = FALSE; +} + +bacStatus::~bacStatus() +{ +} + + +/* Dialog box handling functions */ +void +bacStatus::Show(BOOL show) +{ + if (show && !visible) { + DialogBoxParam(hAppInstance, MAKEINTRESOURCE(IDD_STATUS), NULL, + (DLGPROC)DialogProc, (LONG)this); + } +} + +BOOL CALLBACK +bacStatus::DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + /* Get class pointer from user data */ + bacStatus *_this = (bacStatus *)GetWindowLong(hwnd, GWL_USERDATA); + + switch (uMsg) { + case WM_INITDIALOG: + /* Set class pointer in user data */ + SetWindowLong(hwnd, GWL_USERDATA, lParam); + _this = (bacStatus *)lParam; + + /* show the dialog */ + SetForegroundWindow(hwnd); + + /* Update every 5 seconds */ + SetTimer(hwnd, 1, 5000, NULL); + _this->visible = TRUE; + FillStatusBox(hwnd, IDC_LIST); + return TRUE; + + case WM_TIMER: + FillStatusBox(hwnd, IDC_LIST); + return TRUE; + + case WM_COMMAND: + switch (LOWORD(wParam)) { + case IDCANCEL: + case IDOK: + KillTimer(hwnd, 1); + EndDialog(hwnd, TRUE); + _this->visible = FALSE; + return TRUE; + } + break; + + case WM_DESTROY: + KillTimer(hwnd, 1); + EndDialog(hwnd, FALSE); + _this->visible = FALSE; + return TRUE; + } + return 0; +} diff --git a/bacula/src/win32/stored/baculasd/winstat.h b/bacula/src/win32/stored/baculasd/winstat.h new file mode 100644 index 0000000000..3486a00796 --- /dev/null +++ b/bacula/src/win32/stored/baculasd/winstat.h @@ -0,0 +1,45 @@ +/* + * Bacula Status Dialog header file + * + */ +/* + Copyright (C) 2000-2003 Kern Sibbald and John Walker + + 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. + + */ + + +class bacStatus; + +#ifndef _WINSTAT_H_ +#define _WINSTAT_H_ + +class bacStatus +{ +public: + bacStatus(); + ~bacStatus(); + + /* The Windows callback routine */ + static BOOL CALLBACK DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + + void Show(BOOL show); + + BOOL visible; +}; + +#endif diff --git a/bacula/src/win32/stored/baculasd/wintray.cpp b/bacula/src/win32/stored/baculasd/wintray.cpp new file mode 100644 index 0000000000..db2c593e52 --- /dev/null +++ b/bacula/src/win32/stored/baculasd/wintray.cpp @@ -0,0 +1,357 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file was part of the vnc system. +// +// The vnc system 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. +// +// If the source code for the vnc system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. +// +// This file has been adapted to the Win32 version of Bacula +// by Kern E. Sibbald. Many thanks to ATT and James Weatherall, +// the original author, for providing an excellent template. +// +// Copyright 2000-2004, Kern E. Sibbald +// + + + +// Tray + +// Implementation of a system tray icon & menu for Bacula + +#include "bacula.h" +#include "winbacula.h" +#include "winservice.h" +#include "winres.h" + +// Header + +#include "wintray.h" +#include "bacula.h" +#include "jcr.h" + +// Constants +#ifdef properties_implemented +const UINT MENU_PROPERTIES_SHOW = RegisterWindowMessage("Bacula.Properties.User.Show"); +const UINT MENU_DEFAULT_PROPERTIES_SHOW = RegisterWindowMessage("Bacula.Properties.Default.Show"); +#endif +const UINT MENU_ABOUTBOX_SHOW = RegisterWindowMessage("Bacula.AboutBox.Show"); +const UINT MENU_STATUS_SHOW = RegisterWindowMessage("Bacula.Status.Show"); +const UINT MENU_EVENTS_SHOW = RegisterWindowMessage("Bacula.Events.Show"); +const UINT MENU_SERVICEHELPER_MSG = RegisterWindowMessage("Bacula.ServiceHelper.Message"); +const UINT MENU_ADD_CLIENT_MSG = RegisterWindowMessage("Bacula.AddClient.Message"); +const char *MENU_CLASS_NAME = "BaculaSD Tray Icon"; + +extern void terminate_stored(int sig); +extern char *bac_status(char *buf, int buf_len); +extern int bacstat; + +// Implementation + +bacMenu::bacMenu() +{ + // Create a dummy window to handle tray icon messages + WNDCLASSEX wndclass; + + wndclass.cbSize = sizeof(wndclass); + wndclass.style = 0; + wndclass.lpfnWndProc = bacMenu::WndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = 0; + wndclass.hInstance = hAppInstance; + wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); + wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); + wndclass.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH); + wndclass.lpszMenuName = (const char *) NULL; + wndclass.lpszClassName = MENU_CLASS_NAME; + wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); + + RegisterClassEx(&wndclass); + + m_hwnd = CreateWindow(MENU_CLASS_NAME, + MENU_CLASS_NAME, + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + 200, 200, + NULL, + NULL, + hAppInstance, + NULL); + if (m_hwnd == NULL) { + PostQuitMessage(0); + return; + } + + // record which client created this window + SetWindowLong(m_hwnd, GWL_USERDATA, (LONG) this); + + // Timer to trigger icon updating + SetTimer(m_hwnd, 1, 5000, NULL); + + // Load the icons for the tray + m_idle_icon = LoadIcon(hAppInstance, MAKEINTRESOURCE(IDI_IDLE)); + m_running_icon = LoadIcon(hAppInstance, MAKEINTRESOURCE(IDI_RUNNING)); + m_error_icon = LoadIcon(hAppInstance, MAKEINTRESOURCE(IDI_JOB_ERROR)); + m_warn_icon = LoadIcon(hAppInstance, MAKEINTRESOURCE(IDI_JOB_WARNING)); + + // Load the popup menu + m_hmenu = LoadMenu(hAppInstance, MAKEINTRESOURCE(IDR_TRAYMENU)); + + // Install the tray icon! + AddTrayIcon(); +} + +bacMenu::~bacMenu() +{ + // Remove the tray icon + SendTrayMsg(NIM_DELETE, 0); + + // Destroy the loaded menu + if (m_hmenu != NULL) + DestroyMenu(m_hmenu); +} + +void +bacMenu::AddTrayIcon() +{ + SendTrayMsg(NIM_ADD, bacstat); +} + +void +bacMenu::DelTrayIcon() +{ + SendTrayMsg(NIM_DELETE, 0); +} + + +void +bacMenu::UpdateTrayIcon(int bacstat) +{ + (void *)bac_status(NULL, 0); + SendTrayMsg(NIM_MODIFY, bacstat); +} + +void +bacMenu::SendTrayMsg(DWORD msg, int bacstat) +{ + struct s_last_job *job; + + // Create the tray icon message + m_nid.hWnd = m_hwnd; + m_nid.cbSize = sizeof(m_nid); + m_nid.uID = IDI_BACULA; // never changes after construction + switch (bacstat) { + case 0: + m_nid.hIcon = m_idle_icon; + break; + case JS_Running: + m_nid.hIcon = m_running_icon; + break; + case JS_ErrorTerminated: + m_nid.hIcon = m_error_icon; + break; + default: + if (last_jobs->size() > 0) { + job = (struct s_last_job *)last_jobs->last(); + if (job->Errors) { + m_nid.hIcon = m_warn_icon; + } else { + m_nid.hIcon = m_idle_icon; + } + } else { + m_nid.hIcon = m_idle_icon; + } + break; + } + + m_nid.uFlags = NIF_ICON | NIF_MESSAGE; + m_nid.uCallbackMessage = WM_TRAYNOTIFY; + + + // Use resource string as tip if there is one + if (LoadString(hAppInstance, IDI_BACULA, m_nid.szTip, sizeof(m_nid.szTip))) { + m_nid.uFlags |= NIF_TIP; + } + + // Try to add the Bacula status to the tip string, if possible + if (m_nid.uFlags & NIF_TIP) { + bac_status(m_nid.szTip, sizeof(m_nid.szTip)); + } + + // Send the message + if (Shell_NotifyIcon(msg, &m_nid)) { + EnableMenuItem(m_hmenu, ID_CLOSE, MF_ENABLED); + } else { + if (!bacService::RunningAsService()) { + if (msg == NIM_ADD) { + // The tray icon couldn't be created, so use the Properties dialog + // as the main program window + // removed because it causes quit when not running as a + // service in use with BartPe. + // PostQuitMessage(0); + } + } + } +} + +// Process window messages +LRESULT CALLBACK bacMenu::WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) +{ + // This is a static method, so we don't know which instantiation we're + // dealing with. We use Allen Hadden's (ahadden@taratec.com) suggestion + // from a newsgroup to get the pseudo-this. + bacMenu *_this = (bacMenu *) GetWindowLong(hwnd, GWL_USERDATA); + + switch (iMsg) { + + // Every five seconds, a timer message causes the icon to update + case WM_TIMER: + // *** HACK for running servicified + if (bacService::RunningAsService()) { + // Attempt to add the icon if it's not already there + _this->AddTrayIcon(); + } + + // Update the icon + _this->UpdateTrayIcon(bacstat); + break; + + // STANDARD MESSAGE HANDLING + case WM_CREATE: + return 0; + + case WM_COMMAND: + // User has clicked an item on the tray menu + switch (LOWORD(wParam)) { + case ID_STATUS: + // Show the status dialog + _this->m_status.Show(TRUE); + _this->UpdateTrayIcon(bacstat); + break; + + case ID_EVENTS: + // Show the Events dialog + _this->m_events.Show(TRUE); + _this->UpdateTrayIcon(bacstat); + break; + + + case ID_KILLCLIENTS: + // Disconnect all currently connected clients + break; + + case ID_ABOUT: + // Show the About box + _this->m_about.Show(TRUE); + break; + + case ID_CLOSE: + // User selected Close from the tray menu + PostMessage(hwnd, WM_CLOSE, 0, 0); + break; + + } + return 0; + + case WM_TRAYNOTIFY: + // User has clicked on the tray icon or the menu + { + // Get the submenu to use as a pop-up menu + HMENU submenu = GetSubMenu(_this->m_hmenu, 0); + + // What event are we responding to, RMB click? + if (lParam==WM_RBUTTONUP) { + if (submenu == NULL) { + return 0; + } + + // Make the first menu item the default (bold font) + SetMenuDefaultItem(submenu, 0, TRUE); + + // Get the current cursor position, to display the menu at + POINT mouse; + GetCursorPos(&mouse); + + // There's a "bug" + // (Microsoft calls it a feature) in Windows 95 that requires calling + // SetForegroundWindow. To find out more, search for Q135788 in MSDN. + // + SetForegroundWindow(_this->m_nid.hWnd); + + // Display the menu at the desired position + TrackPopupMenu(submenu, + 0, mouse.x, mouse.y, 0, + _this->m_nid.hWnd, NULL); + + return 0; + } + + // Or was there a LMB double click? + if (lParam==WM_LBUTTONDBLCLK) { + // double click: execute first menu item + SendMessage(_this->m_nid.hWnd, + WM_COMMAND, + GetMenuItemID(submenu, 0), + 0); + } + + return 0; + } + + case WM_CLOSE: + terminate_stored(0); + break; + + case WM_DESTROY: + // The user wants Bacula to quit cleanly... + PostQuitMessage(0); + return 0; + + case WM_QUERYENDSESSION: + // Are we running as a system service? + // Or is the system shutting down (in which case we should check anyway!) + if ((!bacService::RunningAsService()) || (lParam == 0)) { + // No, so we are about to be killed + + // If there are remote connections then we should verify + // that the user is happy about killing them. + + // Finally, post a quit message, just in case + PostQuitMessage(0); + return TRUE; + } + return TRUE; + + + default: + if (iMsg == MENU_ABOUTBOX_SHOW) { + // External request to show our About dialog + PostMessage(hwnd, WM_COMMAND, MAKELONG(ID_ABOUT, 0), 0); + return 0; + } + if (iMsg == MENU_STATUS_SHOW) { + // External request to show our status + PostMessage(hwnd, WM_COMMAND, MAKELONG(ID_STATUS, 0), 0); + return 0; + } + } + + // Message not recognised + return DefWindowProc(hwnd, iMsg, wParam, lParam); +} diff --git a/bacula/src/win32/stored/baculasd/wintray.h b/bacula/src/win32/stored/baculasd/wintray.h new file mode 100644 index 0000000000..e2f7181c1d --- /dev/null +++ b/bacula/src/win32/stored/baculasd/wintray.h @@ -0,0 +1,93 @@ +// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. +// +// This file was part of the VNC system. +// +// The VNC system 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. +// +// If the source code for the VNC system is not available from the place +// whence you received this file, check http://www.uk.research.att.com/vnc or contact +// the authors on vnc@uk.research.att.com for information on obtaining it. +// +// This file has been adapted to the Win32 version of Bacula +// by Kern E. Sibbald. Many thanks to ATT and James Weatherall, +// the original author, for providing an excellent template. +// +// Copyright (2000) Kern E. Sibbald +// + + + +// winMenu + +// This class handles creation of a system-tray icon & menu + +class bacMenu; + +#if (!defined(_win_bacMENU)) +#define _win_bacMENU + +#include "winabout.h" +#include "winstat.h" +#include "winevents.h" + +// Constants +extern const UINT MENU_ABOUTBOX_SHOW; +extern const UINT MENU_STATUS_SHOW; +extern const UINT MENU_EVENTS_SHOW; +extern const UINT MENU_SERVICEHELPER_MSG; +extern const UINT MENU_ADD_CLIENT_MSG; +extern const char *MENU_CLASS_NAME; + +// The tray menu class itself +class bacMenu +{ +public: + bacMenu(); + ~bacMenu(); +protected: + // Tray icon handling + void AddTrayIcon(); + void DelTrayIcon(); + void UpdateTrayIcon(int battstat); + void SendTrayMsg(DWORD msg, int battstat); + + // Message handler for the tray window + static LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam); + + // Fields +protected: + + // About dialog for this server + bacAbout m_about; + + // Status dialog for this server + bacStatus m_status; + + bacEvents m_events; + + HWND m_hwnd; + HMENU m_hmenu; + NOTIFYICONDATA m_nid; + + // The icon handles + HICON m_idle_icon; + HICON m_running_icon; + HICON m_error_icon; + HICON m_warn_icon; +}; + + +#endif -- 2.39.5