#include "wintray.h"
#include "winservice.h"
#include <signal.h>
+#include <pthread.h>
extern int BaculaMain(int argc, char **argv);
extern int terminate_filed(int sig);
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
mainthreadId = GetCurrentThreadId();
main_pid = getpid();
+ main_tid = pthread_self();
/*
* Funny things happen with the command line if the
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;
}
// /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
* 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.
// 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);
}
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
// 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);
}
*/
int BaculaAppMain()
{
- DWORD dwThreadID;
+// DWORD dwThreadID;
+ pthread_t tid;
// Set this process to be the last application to be shut down.
SetProcessShutdownParameters(0x100, 0);
}
// 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);
// 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;
// - 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);
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;
}
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;
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;
}
NO_ERROR, // exit code
0)) { // wait hint
MessageBox(NULL, "Report Service failure", "Bacula Service", MB_OK);
+ LogErrorMsg("ReportStatus failed 2");
return 0;
}
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;
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;
}
// 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;
}
// 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);
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);
// 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
MB_ICONINFORMATION | MB_OK);
break;
default:
+ LogErrorMsg("Unknow Windows OP Sys");
MessageBox(NULL,
"Unknown Windows operating system.\n"
"Cannot install Bacula service.\n",
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)
{
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);
- }
-}