msi: Add handling for the StartServices action.
This commit is contained in:
parent
8ca3ca5a56
commit
58bb3571de
|
@ -4164,6 +4164,132 @@ static UINT ACTION_InstallServices( MSIPACKAGE *package )
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* converts arg1[~]arg2[~]arg3 to a list of ptrs to the strings */
|
||||||
|
static LPCWSTR *msi_service_args_to_vector(LPCWSTR name, LPWSTR args, DWORD *numargs)
|
||||||
|
{
|
||||||
|
LPCWSTR *vector;
|
||||||
|
LPWSTR p, q;
|
||||||
|
DWORD sep_len;
|
||||||
|
|
||||||
|
static const WCHAR separator[] = {'[','~',']',0};
|
||||||
|
|
||||||
|
*numargs = 0;
|
||||||
|
sep_len = sizeof(separator) / sizeof(WCHAR) - 1;
|
||||||
|
|
||||||
|
if (!args)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
vector = msi_alloc(sizeof(LPWSTR));
|
||||||
|
if (!vector)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
p = args;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
(*numargs)++;
|
||||||
|
vector[*numargs - 1] = p;
|
||||||
|
|
||||||
|
if ((q = strstrW(p, separator)))
|
||||||
|
{
|
||||||
|
*q = '\0';
|
||||||
|
|
||||||
|
vector = msi_realloc(vector, (*numargs + 1) * sizeof(LPWSTR));
|
||||||
|
if (!vector)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
p = q + sep_len;
|
||||||
|
}
|
||||||
|
} while (q);
|
||||||
|
|
||||||
|
return vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MSICOMPONENT *msi_find_component( MSIPACKAGE *package, LPCWSTR component )
|
||||||
|
{
|
||||||
|
MSICOMPONENT *comp;
|
||||||
|
|
||||||
|
LIST_FOR_EACH_ENTRY(comp, &package->components, MSICOMPONENT, entry)
|
||||||
|
{
|
||||||
|
if (!lstrcmpW(comp->Component, component))
|
||||||
|
return comp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT ITERATE_StartService(MSIRECORD *rec, LPVOID param)
|
||||||
|
{
|
||||||
|
MSIPACKAGE *package = (MSIPACKAGE *)param;
|
||||||
|
MSICOMPONENT *comp;
|
||||||
|
SC_HANDLE scm, service = NULL;
|
||||||
|
LPCWSTR name, *vector = NULL;
|
||||||
|
LPWSTR args;
|
||||||
|
DWORD event, numargs;
|
||||||
|
UINT r = ERROR_FUNCTION_FAILED;
|
||||||
|
|
||||||
|
comp = msi_find_component(package, MSI_RecordGetString(rec, 6));
|
||||||
|
if (!comp || comp->Action == INSTALLSTATE_UNKNOWN || comp->Action == INSTALLSTATE_ABSENT)
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
|
name = MSI_RecordGetString(rec, 2);
|
||||||
|
event = MSI_RecordGetInteger(rec, 3);
|
||||||
|
args = strdupW(MSI_RecordGetString(rec, 4));
|
||||||
|
|
||||||
|
if (!(event & msidbServiceControlEventStart))
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
|
scm = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT);
|
||||||
|
if (!scm)
|
||||||
|
{
|
||||||
|
ERR("Failed to open the service control manager\n");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
service = OpenServiceW(scm, name, SERVICE_START);
|
||||||
|
if (!service)
|
||||||
|
{
|
||||||
|
ERR("Failed to open service '%s'\n", debugstr_w(name));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
vector = msi_service_args_to_vector(name, args, &numargs);
|
||||||
|
|
||||||
|
if (!StartServiceW(service, numargs, vector))
|
||||||
|
{
|
||||||
|
ERR("Failed to start service '%s'\n", debugstr_w(name));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
done:
|
||||||
|
CloseServiceHandle(service);
|
||||||
|
CloseServiceHandle(scm);
|
||||||
|
|
||||||
|
msi_free(args);
|
||||||
|
msi_free(vector);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT ACTION_StartServices( MSIPACKAGE *package )
|
||||||
|
{
|
||||||
|
UINT rc;
|
||||||
|
MSIQUERY *view;
|
||||||
|
|
||||||
|
static const WCHAR query[] = {
|
||||||
|
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
|
||||||
|
'S','e','r','v','i','c','e','C','o','n','t','r','o','l',0 };
|
||||||
|
|
||||||
|
rc = MSI_DatabaseOpenViewW(package->db, query, &view);
|
||||||
|
if (rc != ERROR_SUCCESS)
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
|
rc = MSI_IterateRecords(view, NULL, ITERATE_StartService, package);
|
||||||
|
msiobj_release(&view->hdr);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static MSIFILE *msi_find_file( MSIPACKAGE *package, LPCWSTR filename )
|
static MSIFILE *msi_find_file( MSIPACKAGE *package, LPCWSTR filename )
|
||||||
{
|
{
|
||||||
MSIFILE *file;
|
MSIFILE *file;
|
||||||
|
@ -4336,13 +4462,6 @@ static UINT ACTION_SelfUnregModules( MSIPACKAGE *package )
|
||||||
return msi_unimplemented_action_stub( package, "SelfUnregModules", table );
|
return msi_unimplemented_action_stub( package, "SelfUnregModules", table );
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT ACTION_StartServices( MSIPACKAGE *package )
|
|
||||||
{
|
|
||||||
static const WCHAR table[] = {
|
|
||||||
'S','e','r','v','i','c','e','C','o','n','t','r','o','l',0 };
|
|
||||||
return msi_unimplemented_action_stub( package, "StartServices", table );
|
|
||||||
}
|
|
||||||
|
|
||||||
static UINT ACTION_StopServices( MSIPACKAGE *package )
|
static UINT ACTION_StopServices( MSIPACKAGE *package )
|
||||||
{
|
{
|
||||||
static const WCHAR table[] = {
|
static const WCHAR table[] = {
|
||||||
|
|
|
@ -184,6 +184,16 @@ enum msidbLocatorType
|
||||||
msidbLocatorType64bit = 0x010,
|
msidbLocatorType64bit = 0x010,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum msidbServiceControlEvent
|
||||||
|
{
|
||||||
|
msidbServiceControlEventStart = 0x00000001,
|
||||||
|
msidbServiceControlEventStop = 0x00000002,
|
||||||
|
msidbServiceControlEventDelete = 0x00000008,
|
||||||
|
msidbServiceControlEventUninstallStart = 0x00000010,
|
||||||
|
msidbServiceControlEventUninstallStop = 0x00000020,
|
||||||
|
msidbServiceControlEventUninstallDelete = 0x00000080,
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Windows SDK braindamage alert
|
* Windows SDK braindamage alert
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue