From b0d1a0845c04c4cfca2a294f5a6e4461850b6846 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sun, 23 Mar 2003 11:38:00 +0000 Subject: [PATCH] Cygwin tweaks git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@390 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/autoconf/configure.in | 6 +- bacula/configure | 6 +- bacula/src/filed/win32/Makefile.in | 3 +- bacula/src/filed/win32/winbacula.h | 11 +- bacula/src/filed/win32/winmain.cpp | 97 +++--- bacula/src/filed/win32/winservice.cpp | 457 ++++++++++++++------------ bacula/src/findlib/attribs.c | 2 +- 7 files changed, 309 insertions(+), 273 deletions(-) diff --git a/bacula/autoconf/configure.in b/bacula/autoconf/configure.in index 5f18bdc977..da76b48b9f 100644 --- a/bacula/autoconf/configure.in +++ b/bacula/autoconf/configure.in @@ -1431,6 +1431,8 @@ if test "x$ac_cv_sys_largefile_CFLAGS" != "xno" ; then largefile_support="yes" fi +CCVERSION=`${CC} --version` +CXXVERSION=`${CXX} --version` echo " Configuration on `date`: @@ -1442,8 +1444,8 @@ Configuration on `date`: Install config files: ${sysconfdir} Scripts directory ${scriptdir} Working directory ${working_dir} - C Compiler: ${CC} - C++ Compiler: ${CXX} + C Compiler: ${CC} ${CCVERSION} + C++ Compiler: ${CXX} ${CXXVERSION} Compiler flags: ${CFLAGS} Linker flags: ${LDFLAGS} Libraries: ${LIBS} diff --git a/bacula/configure b/bacula/configure index 69ad6f6533..25729d4443 100755 --- a/bacula/configure +++ b/bacula/configure @@ -10116,6 +10116,8 @@ if test "x$ac_cv_sys_largefile_CFLAGS" != "xno" ; then largefile_support="yes" fi +CCVERSION=`${CC} --version` +CXXVERSION=`${CXX} --version` echo " Configuration on `date`: @@ -10127,8 +10129,8 @@ Configuration on `date`: Install config files: ${sysconfdir} Scripts directory ${scriptdir} Working directory ${working_dir} - C Compiler: ${CC} - C++ Compiler: ${CXX} + C Compiler: ${CC} ${CCVERSION} + C++ Compiler: ${CXX} ${CXXVERSION} Compiler flags: ${CFLAGS} Linker flags: ${LDFLAGS} Libraries: ${LIBS} diff --git a/bacula/src/filed/win32/Makefile.in b/bacula/src/filed/win32/Makefile.in index 163b2b0b99..57be855e06 100755 --- a/bacula/src/filed/win32/Makefile.in +++ b/bacula/src/filed/win32/Makefile.in @@ -3,6 +3,7 @@ # CFLAGS=@CFLAGS@ CC = @CC@ +CXX = @CXX@ RANLIB = @RANLIB@ SHELL = /bin/sh @@ -120,4 +121,4 @@ dummy: $(CC) -c $(CFLAGS) $< .cpp.o: - $(CC) -c $(CFLAGS) $< + $(CXX) -c $(CFLAGS) $< diff --git a/bacula/src/filed/win32/winbacula.h b/bacula/src/filed/win32/winbacula.h index f57cf1b034..df804f5aeb 100755 --- a/bacula/src/filed/win32/winbacula.h +++ b/bacula/src/filed/win32/winbacula.h @@ -55,6 +55,8 @@ 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"; @@ -63,11 +65,6 @@ const char BaculaRunAsUserApp[] = "/run"; const char BaculaInstallService[] = "/install"; const char BaculaRemoveService[] = "/remove"; -#ifdef properties_implemented -const char BaculaShowProperties[] = "/settings"; -const char BaculaShowDefaultProperties[] = "/defaultsettings"; -#endif - const char BaculaShowAbout[] = "/about"; const char BaculaShowStatus[] = "/status"; const char BaculaShowEvents[] = "/events"; @@ -76,8 +73,4 @@ const char BaculaKillRunningCopy[] = "/kill"; const char BaculaShowHelp[] = "/help"; // Usage string -#ifdef properties_implemented -const char BaculaUsageText[] = "Bacula [/run] [/kill] [/install] [/remove] [/settings] [/defaultsettings] [/about] [/status] [/evetns]\n"; -#else const char BaculaUsageText[] = "Bacula [/run] [/kill] [/install] [/remove] [/about] [/status] [/events]\n"; -#endif diff --git a/bacula/src/filed/win32/winmain.cpp b/bacula/src/filed/win32/winmain.cpp index 33d33747ed..4faaaea6d3 100755 --- a/bacula/src/filed/win32/winmain.cpp +++ b/bacula/src/filed/win32/winmain.cpp @@ -28,6 +28,7 @@ #include "wintray.h" #include "winservice.h" #include +#include extern int BaculaMain(int argc, char **argv); extern int terminate_filed(int sig); @@ -46,6 +47,7 @@ extern DWORD g_servicethread; static char *command_args[MAX_COMMAND_ARGS] = {"bacula-fd", 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 @@ -63,6 +65,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, mainthreadId = GetCurrentThreadId(); main_pid = getpid(); + main_tid = pthread_self(); /* * Funny things happen with the command line if the @@ -140,12 +143,14 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, BOOL argfound = FALSE; for (i = 0; i < (int)strlen(szCmdLine); i++) { - if (szCmdLine[i] <= ' ') - continue; + if (szCmdLine[i] <= ' ') { + continue; + } if (szCmdLine[i] == '-') { - while (szCmdLine[i] && szCmdLine[i] != ' ') + while (szCmdLine[i] && szCmdLine[i] != ' ') { i++; + } continue; } @@ -156,70 +161,70 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, // /servicehelper // Used on NT to connect to Bacula if (strncmp(&szCmdLine[i], BaculaRunServiceHelper, strlen(BaculaRunServiceHelper)) == 0) { - // NB : This flag MUST be parsed BEFORE "-service", otherwise it will match - // the wrong option! (This code should really be replaced with a simple - // parser machine and parse-table...) + // NB : This flag MUST be parsed BEFORE "-service", otherwise it will match + // the wrong option! (This code should really be replaced with a simple + // parser machine and parse-table...) - // Run the Bacula Service Helper app - bacService::PostUserHelperMessage(); - return 0; + // Run the Bacula Service Helper app + bacService::PostUserHelperMessage(); + return 0; } // /service if (strncmp(&szCmdLine[i], BaculaRunService, strlen(BaculaRunService)) == 0) { - // Run Bacula as a service - return bacService::BaculaServiceMain(); + // Run Bacula as a service + return bacService::BaculaServiceMain(); } // /run (this is the default if no command line arguments) if (strncmp(&szCmdLine[i], BaculaRunAsUserApp, strlen(BaculaRunAsUserApp)) == 0) { - // Bacula is being run as a user-level program - return BaculaAppMain(); + // Bacula is being run as a user-level program + return BaculaAppMain(); } // /install if (strncmp(&szCmdLine[i], BaculaInstallService, strlen(BaculaInstallService)) == 0) { - // Install Bacula as a service - bacService::InstallService(); - i+=strlen(BaculaInstallService); - continue; + // Install Bacula as a service + bacService::InstallService(); + i+=strlen(BaculaInstallService); + continue; } // /remove if (strncmp(&szCmdLine[i], BaculaRemoveService, strlen(BaculaRemoveService)) == 0) { - // Remove the Bacula service - bacService::RemoveService(); - i+=strlen(BaculaRemoveService); - continue; + // Remove the Bacula service + bacService::RemoveService(); + i+=strlen(BaculaRemoveService); + continue; } // /about if (strncmp(&szCmdLine[i], BaculaShowAbout, strlen(BaculaShowAbout)) == 0) { - // Show the About dialog of an existing instance of Bacula - bacService::ShowAboutBox(); - i+=strlen(BaculaShowAbout); - continue; + // Show the About dialog of an existing instance of Bacula + bacService::ShowAboutBox(); + i+=strlen(BaculaShowAbout); + continue; } // /status if (strncmp(&szCmdLine[i], BaculaShowStatus, strlen(BaculaShowStatus)) == 0) { - // Show the Status dialog of an existing instance of Bacula - bacService::ShowStatus(); - i+=strlen(BaculaShowStatus); - continue; + // Show the Status dialog of an existing instance of Bacula + bacService::ShowStatus(); + i+=strlen(BaculaShowStatus); + continue; } // /events if (strncmp(&szCmdLine[i], BaculaShowEvents, strlen(BaculaShowEvents)) == 0) { - // Show the Events dialog of an existing instance of Bacula - bacService::ShowEvents(); - i+=strlen(BaculaShowEvents); - continue; + // Show the Events dialog of an existing instance of Bacula + bacService::ShowEvents(); + i+=strlen(BaculaShowEvents); + continue; } // /kill if (strncmp(&szCmdLine[i], BaculaKillRunningCopy, strlen(BaculaKillRunningCopy)) == 0) { - // Kill any already running copy of Bacula - bacService::KillRunningCopy(); - i+=strlen(BaculaKillRunningCopy); - continue; + // Kill any already running copy of Bacula + bacService::KillRunningCopy(); + i+=strlen(BaculaKillRunningCopy); + continue; } // /help @@ -248,10 +253,14 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, * Called as a thread from BaculaAppMain() * Here we handle the Windows messages */ -DWORD WINAPI Main_Msg_Loop(LPVOID lpwThreadParam) +//DWORD WINAPI Main_Msg_Loop(LPVOID lpwThreadParam) +void *Main_Msg_Loop(LPVOID lpwThreadParam) { DWORD old_servicethread = g_servicethread; + + pthread_detach(pthread_self()); + /* Since we are the only thread with a message loop * mark ourselves as the service thread so that * we can receive all the window events. @@ -261,6 +270,7 @@ DWORD WINAPI Main_Msg_Loop(LPVOID lpwThreadParam) // Create tray icon & menu if we're running as an app bacMenu *menu = new bacMenu(); if (menu == NULL) { +// LogErrorMsg("Could not create sys tray menu"); PostQuitMessage(0); } @@ -272,8 +282,9 @@ DWORD WINAPI Main_Msg_Loop(LPVOID lpwThreadParam) DispatchMessage(&msg); } - if (menu != NULL) + if (menu != NULL) { delete menu; + } if (old_servicethread != 0) { /* started as NT service */ // Mark that we're no longer running @@ -282,6 +293,8 @@ DWORD WINAPI Main_Msg_Loop(LPVOID lpwThreadParam) // Tell the service manager that we've stopped. ReportStatus(SERVICE_STOPPED, g_error, 0); } + pthread_kill(main_tid, SIGTERM); /* ask main thread to terminate */ + sleep(1); kill(main_pid, SIGTERM); /* ask main thread to terminate */ _exit(0); } @@ -295,7 +308,8 @@ DWORD WINAPI Main_Msg_Loop(LPVOID lpwThreadParam) */ int BaculaAppMain() { - DWORD dwThreadID; +// DWORD dwThreadID; + pthread_t tid; // Set this process to be the last application to be shut down. SetProcessShutdownParameters(0x100, 0); @@ -308,7 +322,8 @@ int BaculaAppMain() } // Create a thread to handle the Windows messages - (void)CreateThread(NULL, 0, Main_Msg_Loop, NULL, 0, &dwThreadID); +// (void)CreateThread(NULL, 0, Main_Msg_Loop, NULL, 0, &dwThreadID); + pthread_create(&tid, NULL, Main_Msg_Loop, (void *)0); // Call the "real" Bacula BaculaMain(num_command_args, command_args); diff --git a/bacula/src/filed/win32/winservice.cpp b/bacula/src/filed/win32/winservice.cpp index 81b0b17f7b..d5ffc4c8f4 100755 --- a/bacula/src/filed/win32/winservice.cpp +++ b/bacula/src/filed/win32/winservice.cpp @@ -53,7 +53,7 @@ void SetServicePrivileges(); // Create an instance of the bacService class to cause the static fields to be // initialised properly -int NoGetFileAttributesEx = 0; /* set if function no avail -- Win95 */ +extern int NoGetFileAttributesEx; /* set if function no avail -- Win95 */ bacService init; @@ -299,15 +299,15 @@ bacService::ProcessUserHelperMessage(WPARAM wParam, LPARAM lParam) { // - Get the token for the given process HANDLE userToken = NULL; if (!OpenProcessToken(processHandle, TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE, &userToken)) { - CloseHandle(processHandle); - return FALSE; + CloseHandle(processHandle); + return FALSE; } CloseHandle(processHandle); // - Set this thread to impersonate them if (!ImpersonateLoggedOnUser(userToken)) { - CloseHandle(userToken); - return FALSE; + CloseHandle(userToken); + return FALSE; } CloseHandle(userToken); @@ -340,16 +340,19 @@ bacService::BaculaServiceMain() if (GetProcAddress(kerneldll, "GetFileAttributesEx") == NULL) { NoGetFileAttributesEx = 1; /*****FIXME***** remove after testing */ - MessageBox(NULL, "NoGetFileAttributesEx", "Bacula", MB_OK); - } + MessageBox(NULL, "winserv NoGetFileAttributesEx", "Bacula", MB_OK); + } else { + MessageBox(NULL, "winserv Got GetFileAttributesEx", "Bacula", MB_OK); + } // And find the RegisterServiceProcess function DWORD (*RegisterService)(DWORD, DWORD); RegisterService = (DWORD (*)(DWORD, DWORD)) GetProcAddress(kerneldll, "RegisterServiceProcess"); if (RegisterService == NULL) { - MessageBox(NULL, "Registry service not fond: Bacula service not started", + MessageBox(NULL, "Registry service not found: Bacula service not started", "Bacula Service", MB_OK); + LogErrorMsg("Registry service not found"); break; } @@ -397,6 +400,7 @@ void WINAPI ServiceMain(DWORD argc, char **argv) g_hstatus = RegisterServiceCtrlHandler(BAC_SERVICENAME, ServiceCtrl); if (g_hstatus == 0) { + LogErrorMsg("RegisterServiceCtlHandler failed"); MessageBox(NULL, "Contact Register Service Handler failure", "Bacula service", MB_OK); return; @@ -413,6 +417,7 @@ void WINAPI ServiceMain(DWORD argc, char **argv) 45000)) { // Hint as to how long Bacula should have hung before you assume error ReportStatus(SERVICE_STOPPED, g_error, 0); + LogErrorMsg("ReportStatus failed 1"); return; } @@ -436,6 +441,7 @@ DWORD WINAPI ServiceWorkThread(LPVOID lpwThreadParam) NO_ERROR, // exit code 0)) { // wait hint MessageBox(NULL, "Report Service failure", "Bacula Service", MB_OK); + LogErrorMsg("ReportStatus failed 2"); return 0; } @@ -554,6 +560,7 @@ bacService::InstallService() strcat(servicecmd, "\\bacula-fd.conf"); } else { + LogErrorMsg("Service commend length too long"); MessageBox(NULL, "Service command length too long. Service not registered.", szAppName, MB_ICONEXCLAMATION | MB_OK); return 0; @@ -569,6 +576,7 @@ bacService::InstallService() if (RegCreateKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\RunServices", &runservices) != ERROR_SUCCESS) { + LogErrorMsg("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; } @@ -576,6 +584,7 @@ bacService::InstallService() // Attempt to add a Bacula key if (RegSetValueEx(runservices, szAppName, 0, REG_SZ, (unsigned char *)servicecmd, strlen(servicecmd)+1) != ERROR_SUCCESS) { RegCloseKey(runservices); + LogErrorMsg("Cannot add Bacula key to System Registry"); MessageBox(NULL, "The Bacula service could not be installed", szAppName, MB_ICONEXCLAMATION | MB_OK); break; } @@ -624,6 +633,7 @@ bacService::InstallService() // Open the default, local Service Control Manager database hsrvmanager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); if (hsrvmanager == NULL) { + LogErrorMsg("OpenSCManager failed"); MessageBox(NULL, "The Service Control Manager could not be contacted - the Bacula service was not installed", szAppName, MB_ICONEXCLAMATION | MB_OK); @@ -648,6 +658,7 @@ bacService::InstallService() NULL); // no password if (hservice == NULL) { CloseServiceHandle(hsrvmanager); + LogErrorMsg("CreateService failed"); MessageBox(NULL, "The Bacula service could not be installed", szAppName, MB_ICONEXCLAMATION | MB_OK); @@ -673,16 +684,14 @@ bacService::InstallService() // Append the service-helper-start flag to the end of the path: if ((int)strlen(path) + 4 + (int)strlen(BaculaRunServiceHelper) < pathlength) { sprintf(servicehelpercmd, "\"%s\" %s", path, BaculaRunServiceHelper); - } else { - return 0; - } - // Add the Bacula Service Helper entry - if (RegSetValueEx(runapps, szAppName, 0, REG_SZ, - (unsigned char *)servicehelpercmd, strlen(servicehelpercmd)+1) != ERROR_SUCCESS) { - MessageBox(NULL, "WARNING:Unable to install the ServiceHelper hook\nGlobal user-specific registry settings will not be loaded", szAppName, MB_ICONEXCLAMATION | MB_OK); + // Add the Bacula Service Helper entry + if (RegSetValueEx(runapps, szAppName, 0, REG_SZ, + (unsigned char *)servicehelpercmd, strlen(servicehelpercmd)+1) != ERROR_SUCCESS) { + MessageBox(NULL, "WARNING:Unable to install the ServiceHelper hook\nGlobal user-specific registry settings will not be loaded", szAppName, MB_ICONEXCLAMATION | MB_OK); + } + RegCloseKey(runapps); } - RegCloseKey(runapps); } // Everything went fine @@ -694,6 +703,7 @@ bacService::InstallService() MB_ICONINFORMATION | MB_OK); break; default: + LogErrorMsg("Unknow Windows OP Sys"); MessageBox(NULL, "Unknown Windows operating system.\n" "Cannot install Bacula service.\n", @@ -704,6 +714,220 @@ bacService::InstallService() 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 + 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 + case VER_PLATFORM_WIN32_NT: + SC_HANDLE hservice; + SC_HANDLE hsrvmanager; + + // Attempt to remove the service-helper hook + HKEY runapps; + if (RegOpenKey(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", + &runapps) == ERROR_SUCCESS) { + // Attempt to delete the Bacula key + if (RegDeleteValue(runapps, szAppName) != ERROR_SUCCESS) { + MessageBox(NULL, "WARNING:The ServiceHelper hook entry could not be removed from the registry", szAppName, MB_ICONEXCLAMATION | MB_OK); + } + RegCloseKey(runapps); + } + + // 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))) { + LogErrorMsg("SetServiceStatus failed"); + } + + return result; +} + +// Error reporting +void LogErrorMsg(char *message) +{ + 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, "%s error: %ld", BAC_SERVICENAME, g_error); + 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); +} + +/* ================== Not yet implemented ===================== */ #ifdef implemented VOID ReconfigureSampleService(BOOL fDisable, LPSTR lpDesc) { @@ -807,204 +1031,3 @@ VOID ReconfigureSampleService(BOOL fDisable, LPSTR lpDesc) CloseServiceHandle(schService); } #endif - -// SERVICE REMOVE ROUTINE -int -bacService::RemoveService() -{ - // How to remove the Bacula service depends upon the OS - switch (g_platform_id) { - - // Windows 95/98 - 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 - case VER_PLATFORM_WIN32_NT: - SC_HANDLE hservice; - SC_HANDLE hsrvmanager; - - // Attempt to remove the service-helper hook - HKEY runapps; - if (RegOpenKey(HKEY_LOCAL_MACHINE, - "Software\\Microsoft\\Windows\\CurrentVersion\\Run", - &runapps) == ERROR_SUCCESS) - { - // Attempt to delete the Bacula key - if (RegDeleteValue(runapps, szAppName) != ERROR_SUCCESS) - { - MessageBox(NULL, "WARNING:The ServiceHelper hook entry could not be removed from the registry", szAppName, MB_ICONEXCLAMATION | MB_OK); - } - RegCloseKey(runapps); - } - - // 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))) - LogErrorMsg("SetServiceStatus failed"); - - return result; -} - -// Error reporting -void LogErrorMsg(char *message) -{ - char msgbuff[256]; - HANDLE heventsrc; - char * strings[2]; - - // Save the error code - g_error = GetLastError(); - - // Use event logging to log the error - heventsrc = RegisterEventSource(NULL, BAC_SERVICENAME); - - sprintf(msgbuff, "%s error: %ld", BAC_SERVICENAME, g_error); - strings[0] = msgbuff; - strings[1] = message; - - 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 - 2, // strings in 'strings' - 0, // no bytes of raw data - (const char **)strings, // array of error strings - NULL); // no raw data - - DeregisterEventSource(heventsrc); - } -} diff --git a/bacula/src/findlib/attribs.c b/bacula/src/findlib/attribs.c index 35e8c032f0..3d85767616 100755 --- a/bacula/src/findlib/attribs.c +++ b/bacula/src/findlib/attribs.c @@ -253,7 +253,7 @@ int encode_attribsEx(void *jcr, char *attribsEx, FF_PKT *ff_pkt) #ifdef HAVE_CYGWIN -extern int NoGetFileAttributesEx; +int NoGetFileAttributesEx = 0; int encode_attribsEx(void *jcr, char *attribsEx, FF_PKT *ff_pkt) { -- 2.39.5