~ubuntu-branches/ubuntu/trusty/mariadb-5.5/trusty-proposed

« back to all changes in this revision

Viewing changes to packaging/WiX/ca/CustomAction.cpp

  • Committer: Package Import Robot
  • Author(s): Otto Kekäläinen
  • Date: 2013-12-22 10:27:05 UTC
  • Revision ID: package-import@ubuntu.com-20131222102705-mndw7s12mz0szrcn
Tags: upstream-5.5.32
Import upstream version 5.5.32

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
 
15
 
 
16
#ifndef UNICODE
 
17
#define UNICODE
 
18
#endif
 
19
 
 
20
#include <windows.h>
 
21
#include <winreg.h>
 
22
#include <msi.h>
 
23
#include <msiquery.h>
 
24
#include <wcautil.h>
 
25
#include <string.h>
 
26
#include <strsafe.h>
 
27
 
 
28
/*
 
29
 * Search the registry for a service whose ImagePath starts
 
30
 * with our install directory. Stop and remove it if requested.
 
31
 */
 
32
static TCHAR last_service_name[128];
 
33
int remove_service(TCHAR *installdir, int check_only) {
 
34
        HKEY hKey;
 
35
        int done = 0;
 
36
 
 
37
        if(wcslen(installdir) < 3) {
 
38
                WcaLog(LOGMSG_STANDARD, "INSTALLDIR is suspiciously short, better not do anything.");
 
39
                return 0;
 
40
        }
 
41
 
 
42
        if(check_only == 0) {
 
43
                WcaLog(LOGMSG_STANDARD, "Determining number of matching services...");
 
44
                int servicecount = remove_service(installdir, 1);
 
45
                if(servicecount <= 0) {
 
46
                        WcaLog(LOGMSG_STANDARD, "No services found, not removing anything.");
 
47
                        return 0;
 
48
                } else if(servicecount == 1) {
 
49
                        TCHAR buf[256];
 
50
                        swprintf_s(buf, sizeof(buf), TEXT("There is a service called '%ls' set up to run from this installation. Do you wish me to stop and remove that service?"), last_service_name);
 
51
                        int rc = MessageBox(NULL, buf, TEXT("Removing MySQL Server"), MB_ICONQUESTION|MB_YESNOCANCEL|MB_SYSTEMMODAL);
 
52
                        if(rc == IDCANCEL) return -1;
 
53
                        if(rc != IDYES) return 0;
 
54
                } else if(servicecount > 0) {
 
55
                        TCHAR buf[256];
 
56
                        swprintf_s(buf, sizeof(buf), TEXT("There appear to be %d services set up to run from this installation. Do you wish me to stop and remove those services?"), servicecount);
 
57
                        int rc = MessageBox(NULL, buf, TEXT("Removing MySQL Server"), MB_ICONQUESTION|MB_YESNOCANCEL|MB_SYSTEMMODAL);
 
58
                        if(rc == IDCANCEL) return -1;
 
59
                        if(rc != IDYES) return 0;
 
60
                }
 
61
        }
 
62
 
 
63
        if(check_only == -1) check_only = 0;
 
64
 
 
65
        WcaLog(LOGMSG_STANDARD, "Looking for service...");
 
66
        WcaLog(LOGMSG_STANDARD, "INSTALLDIR = %ls", installdir);
 
67
        if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\services"), 0, KEY_READ, &hKey)==ERROR_SUCCESS) {
 
68
                DWORD index = 0;
 
69
                TCHAR keyname[1024];
 
70
                DWORD keylen = sizeof(keyname);
 
71
                FILETIME t;
 
72
                /* Go through all services in the registry */
 
73
                while(RegEnumKeyExW(hKey, index, keyname, &keylen, NULL, NULL, NULL, &t) == ERROR_SUCCESS) {
 
74
                        HKEY hServiceKey = 0;
 
75
                        TCHAR path[1024];
 
76
                        DWORD pathlen = sizeof(path)-1;
 
77
                        if (RegOpenKeyExW(hKey, keyname, NULL, KEY_READ, &hServiceKey) == ERROR_SUCCESS) {
 
78
                                /* Look at the ImagePath value of each service */
 
79
                                if (RegQueryValueExW(hServiceKey, TEXT("ImagePath"), NULL, NULL, (LPBYTE)path, &pathlen) == ERROR_SUCCESS) {
 
80
                                        path[pathlen] = 0;
 
81
                                        TCHAR *p = path;
 
82
                                        if(p[0] == '"') p += 1;
 
83
                                        /* See if it is similar to our install directory */
 
84
                                        if(wcsncmp(p, installdir, wcslen(installdir)) == 0) {
 
85
                                                WcaLog(LOGMSG_STANDARD, "Found service '%ls' with ImagePath '%ls'.", keyname, path);
 
86
                                                swprintf_s(last_service_name, sizeof(last_service_name), TEXT("%ls"), keyname);
 
87
                                                /* If we are supposed to stop and remove the service... */
 
88
                                                if(!check_only) {
 
89
                                                        WcaLog(LOGMSG_STANDARD, "Trying to stop the service.");
 
90
                                                        SC_HANDLE hSCM = NULL; 
 
91
                                                        hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
 
92
                                                        if(hSCM != NULL) {
 
93
                                                                SC_HANDLE hService = NULL;
 
94
                                                                hService = OpenService(hSCM, keyname, SERVICE_STOP|SERVICE_QUERY_STATUS|DELETE);
 
95
                                                                if(hService != NULL) {
 
96
                                                                        WcaLog(LOGMSG_STANDARD, "Waiting for the service to stop...");
 
97
                                                                        SERVICE_STATUS status;
 
98
                                                                        /* Attempt to stop the service */
 
99
                                                                        if(ControlService(hService, SERVICE_CONTROL_STOP, &status)) {
 
100
                                                                                /* Now wait until it's stopped */
 
101
                                                                                while("it's one big, mean and cruel world out there") {
 
102
                                                                                        if(!QueryServiceStatus(hService, &status)) break;
 
103
                                                                                        if(status.dwCurrentState == SERVICE_STOPPED) break;
 
104
                                                                                        Sleep(1000);
 
105
                                                                                }
 
106
                                                                                WcaLog(LOGMSG_STANDARD, "Stopped the service.");
 
107
                                                                        }
 
108
                                                                        /* Mark the service for deletion */
 
109
                                                                        DeleteService(hService);
 
110
                                                                        CloseServiceHandle(hService);
 
111
                                                                }
 
112
                                                                CloseServiceHandle(hSCM);
 
113
                                                        }
 
114
                                                }
 
115
                                                done++;
 
116
                                        }
 
117
                                }
 
118
                                RegCloseKey(hServiceKey);
 
119
                        }
 
120
                        index++;
 
121
                        keylen = sizeof(keyname)-1;
 
122
                }
 
123
                RegCloseKey(hKey);
 
124
        } else {
 
125
                WcaLog(LOGMSG_STANDARD, "Can't seem to go through the list of installed services in the registry.");
 
126
        }
 
127
        return done;
 
128
}
 
129
 
 
130
UINT wrap(MSIHANDLE hInstall, char *name, int check_only) {
 
131
        HRESULT hr = S_OK;
 
132
        UINT er = ERROR_SUCCESS;
 
133
 
 
134
        hr = WcaInitialize(hInstall, name);
 
135
        ExitOnFailure(hr, "Failed to initialize");
 
136
 
 
137
        WcaLog(LOGMSG_STANDARD, "Initialized.");
 
138
 
 
139
    TCHAR INSTALLDIR[1024];
 
140
    DWORD INSTALLDIR_size = sizeof(INSTALLDIR);
 
141
        if(MsiGetPropertyW(hInstall, TEXT("CustomActionData"), INSTALLDIR, &INSTALLDIR_size) == ERROR_SUCCESS) {
 
142
                int rc = remove_service(INSTALLDIR, check_only);
 
143
                if(rc < 0) {
 
144
                        er = ERROR_CANCELLED;
 
145
                }
 
146
        } else {
 
147
                er = ERROR_CANT_ACCESS_FILE;
 
148
        }
 
149
 
 
150
LExit:
 
151
        return WcaFinalize(er);
 
152
}
 
153
 
 
154
UINT __stdcall RemoveServiceNoninteractive(MSIHANDLE hInstall)
 
155
{
 
156
        return wrap(hInstall, "RemoveServiceNoninteractive", -1);
 
157
}
 
158
 
 
159
UINT __stdcall RemoveService(MSIHANDLE hInstall)
 
160
{
 
161
        return wrap(hInstall, "RemoveService", 0);
 
162
}
 
163
 
 
164
UINT __stdcall TestService(MSIHANDLE hInstall)
 
165
{
 
166
        return wrap(hInstall, "TestService", 1);
 
167
}
 
168
 
 
169
/* DllMain - Initialize and cleanup WiX custom action utils */
 
170
extern "C" BOOL WINAPI DllMain(
 
171
        __in HINSTANCE hInst,
 
172
        __in ULONG ulReason,
 
173
        __in LPVOID
 
174
        )
 
175
{
 
176
        switch(ulReason)
 
177
        {
 
178
        case DLL_PROCESS_ATTACH:
 
179
                WcaGlobalInitialize(hInst);
 
180
                break;
 
181
 
 
182
        case DLL_PROCESS_DETACH:
 
183
                WcaGlobalFinalize();
 
184
                break;
 
185
        }
 
186
 
 
187
        return TRUE;
 
188
}