Opened 9 years ago

Closed 4 years ago

#67 closed enhancement (fixed)

Add mutexes for Win32 (client) to enable detection of running instance during install/uninstall

Reported by: Achim J Latz Owned by: chris
Priority: normal Milestone:
Component: bbackupd Version: trunk
Keywords: Cc:

Description

Creating mutexes for the Win32 client apps (bbackupctl.exe, bbackupd.exe, bbackupquery.exe) enable the detection of running instance during install/uninstall/upgrade. The fixes are trivial and platform-specific, sorry for that:

/usr/src/boxbackup-0.11rc7/bin/bbackupd/BackupDaemon.cpp

BackupDaemon::BackupDaemon()
{
        // Only ever one instance of a daemon
        SSLLib::Initialise();
        #ifdef WIN32
         CreateMutex(0,FALSE,"__boxbackup_mutex__");
        #endif
}

/usr/src/boxbackup-0.11rc7/bin/bbackupctl/bbackupctl.cpp

int main(int argc, const char *argv[])
{
        int returnCode = 0;

        #ifdef WIN32
         CreateMutex(0,FALSE,"__boxbackup_mutex__");
        #endif

/usr/src/boxbackup-0.11rc7/bin/bbackupquery/bbackupquery.cpp

int main(int argc, const char *argv[])
{
        int returnCode = 0;

        #ifdef WIN32
         CreateMutex(0,FALSE,"__boxbackup_mutex__");
        #endif

Change History (8)

comment:1 Changed 9 years ago by chris

There could be any number of independent Box Backup installations on a machine, and this fix would block that from working. This was a requested feature (see http://osdir.com/ml/sysutils.backup.boxbackup.general/2006-02/msg00151.html and FeatureRequests#RedundantServers).

What exactly is this for?

I think a better approach might be to use the existing command socket/named pipe, try to connect to the one specified in the configuration file, and if the connection is successful, ask it to terminate and wait for it to terminate. We could also ask for its PID when we connect and monitor that PID to determine when the service has shut down.

Another option is simply to ask the SCM to stop the named service before removing it.

comment:2 Changed 9 years ago by Achim J Latz

You can launch as many "independent Box Backup installations" as you like with this setup, with the same mutex.

I am not suggesting that we test for "Single Instance of Box Backup", merely use the system as it was designed (under Windows that means a mutext) to indicate that one or more copies of Box Backup are running.

This is used to enable the standard installers (Inno Setup, NSIS, WiX) to detect a running application and ask the user to close it if they want to re-install/uninstall/upgrade.

comment:3 Changed 9 years ago by chris

Owner: changed from ben to chris
Status: newassigned

OK, that seems reasonable, but I think I will wrap it in a platform-independent class so that at least we can implement this feature on other platforms reasonably easily in future.

comment:4 Changed 9 years ago by Achim J Latz

I think the problem of "locked" executables only exists on Windows: OSX and GNU/Linux don't have that limitation, for instance. So you might save yourself some work by having it platform specific for now.

In addition, Mutexes do not seem to be a big matter since nobody had requested this before.

comment:5 Changed 9 years ago by Achim J Latz

An improved version that allows for Box Backup/Boxi? detection (again, *not* limitation) across different users:

  /* Creates the two mutexes checked for by the installer/uninstaller to see if
  the program is still running.
  One of the mutexes is created in the global name space (which makes it
  possible to access the mutex across user sessions in Windows XP); the other
  is created in the session name space (because versions of Windows NT prior
  to 4.0 TSE don't have a global name space and don't support the 'Global\'
  prefix).
  */
void CreateMutexes(string)
{
 SECURITY_DESCRIPTOR SecurityDesc;
 SECURITY_ATTRIBUTES SecurityAttr;

 /* By default on Windows NT, created mutexes are accessible only by the user
    running the process. We need our mutexes to be accessible to all users, so
    that the mutex detection can work across user sessions in Windows XP. To
    do this we use a security descriptor with a null DACL.
 */

 InitializeSecurityDescriptor(&SecurityDesc, SECURITY_DESCRIPTOR_REVISION);
 SetSecurityDescriptorDacl(&SecurityDesc, TRUE, NULL, FALSE);
 SecurityAttr.nLength = sizeof(SecurityAttr);
 SecurityAttr.lpSecurityDescriptor = &SecurityDesc;
 SecurityAttr.bInheritHandle = FALSE;
 CreateMutex(&SecurityAttr, FALSE, TEXT(MutexName));
 CreateMutex(&SecurityAttr, FALSE, TEXT('Global\' + MutexName));
}

call this function like this:

int main(int argc, const char *argv[])
{
        int returnCode = 0;

        #ifdef WIN32
         CreateMutexes('__boxbackup_mutex__');
        #endif
}

comment:6 Changed 9 years ago by Achim J Latz

Small correction:

CreateMutex(&SecurityAttr, FALSE, TEXT('Global\' + MutexName));

should probably be (escaping the backslash from Global):

CreateMutex(&SecurityAttr, FALSE, TEXT('Global\\' + MutexName));

comment:7 Changed 8 years ago by Achim J Latz

Is the proposed solution acceptable?

Mutexes are used under Windows standard installers (Inno Setup, NSIS, WiX) to detect a running application and ask the user to close it if they want to re-install/uninstall/upgrade.

No other platform will require this, so a simple ifdef should be OK.

Thanks.

comment:8 Changed 4 years ago by chris

Resolution: fixed
Status: assignedclosed

Thanks Achim, added in r3516, sorry for the long delay.

Note: See TracTickets for help on using tickets.