Hans Leidekker : msi: Implement the RemoveEnvironmentStrings standard action.
Alexandre Julliard
julliard at winehq.org
Wed Mar 3 11:15:47 CST 2010
Module: wine
Branch: master
Commit: f62211198a67e4efcf4b62e01b65025eda44b536
URL: http://source.winehq.org/git/wine.git/?a=commit;h=f62211198a67e4efcf4b62e01b65025eda44b536
Author: Hans Leidekker <hans at codeweavers.com>
Date: Wed Mar 3 14:38:06 2010 +0100
msi: Implement the RemoveEnvironmentStrings standard action.
---
dlls/msi/action.c | 195 +++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 159 insertions(+), 36 deletions(-)
diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index 4441030..08cf975 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -5810,7 +5810,7 @@ static UINT ACTION_RemoveODBC( MSIPACKAGE *package )
#define check_flag_combo(x, y) ((x) & ~(y)) == (y)
-static LONG env_set_flags( LPCWSTR *name, LPCWSTR *value, DWORD *flags )
+static UINT env_parse_flags( LPCWSTR *name, LPCWSTR *value, DWORD *flags )
{
LPCWSTR cptr = *name;
@@ -5891,18 +5891,8 @@ static LONG env_set_flags( LPCWSTR *name, LPCWSTR *value, DWORD *flags )
return ERROR_SUCCESS;
}
-static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param )
+static UINT open_env_key( DWORD flags, HKEY *key )
{
- MSIPACKAGE *package = param;
- LPCWSTR name, value, component;
- LPWSTR data = NULL, newval = NULL;
- LPWSTR deformatted = NULL, ptr;
- DWORD flags, type, size;
- LONG res;
- HKEY env = NULL, root;
- LPCWSTR environment;
- MSICOMPONENT *comp;
-
static const WCHAR user_env[] =
{'E','n','v','i','r','o','n','m','e','n','t',0};
static const WCHAR machine_env[] =
@@ -5911,6 +5901,42 @@ static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param )
'C','o','n','t','r','o','l','\\',
'S','e','s','s','i','o','n',' ','M','a','n','a','g','e','r','\\',
'E','n','v','i','r','o','n','m','e','n','t',0};
+ const WCHAR *env;
+ HKEY root;
+ LONG res;
+
+ if (flags & ENV_MOD_MACHINE)
+ {
+ env = machine_env;
+ root = HKEY_LOCAL_MACHINE;
+ }
+ else
+ {
+ env = user_env;
+ root = HKEY_CURRENT_USER;
+ }
+
+ res = RegOpenKeyExW( root, env, 0, KEY_ALL_ACCESS, key );
+ if (res != ERROR_SUCCESS)
+ {
+ WARN("Failed to open key %s (%d)\n", debugstr_w(env), res);
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ return ERROR_SUCCESS;
+}
+
+static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param )
+{
+ MSIPACKAGE *package = param;
+ LPCWSTR name, value, component;
+ LPWSTR data = NULL, newval = NULL, deformatted = NULL, ptr;
+ DWORD flags, type, size;
+ UINT res;
+ HKEY env;
+ MSICOMPONENT *comp;
+ MSIRECORD *uirow;
+ int action = 0;
component = MSI_RecordGetString(rec, 4);
comp = get_loaded_component(package, component);
@@ -5930,7 +5956,7 @@ static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param )
TRACE("name %s value %s\n", debugstr_w(name), debugstr_w(value));
- res = env_set_flags(&name, &value, &flags);
+ res = env_parse_flags(&name, &value, &flags);
if (res != ERROR_SUCCESS || !value)
goto done;
@@ -5942,24 +5968,12 @@ static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param )
value = deformatted;
- if (flags & ENV_MOD_MACHINE)
- {
- environment = machine_env;
- root = HKEY_LOCAL_MACHINE;
- }
- else
- {
- environment = user_env;
- root = HKEY_CURRENT_USER;
- }
-
- res = RegCreateKeyExW(root, environment, 0, NULL, 0,
- KEY_ALL_ACCESS, NULL, &env, NULL);
+ res = open_env_key( flags, &env );
if (res != ERROR_SUCCESS)
goto done;
- if (flags & ENV_ACT_REMOVE)
- FIXME("Not removing environment variable on uninstall!\n");
+ if (flags & ENV_MOD_MACHINE)
+ action |= 0x20000000;
size = 0;
type = REG_SZ;
@@ -5970,6 +5984,8 @@ static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param )
if ((res == ERROR_FILE_NOT_FOUND || !(flags & ENV_MOD_MASK)))
{
+ action = 0x2;
+
/* Nothing to do. */
if (!value)
{
@@ -5990,6 +6006,8 @@ static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param )
}
else
{
+ action = 0x1;
+
/* Contrary to MSDN, +-variable to [~];path works */
if (flags & ENV_ACT_SETABSENT && !(flags & ENV_MOD_MASK))
{
@@ -6010,7 +6028,10 @@ static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param )
if (flags & ENV_ACT_REMOVEMATCH && (!value || !lstrcmpW(data, value)))
{
- res = RegDeleteKeyW(env, name);
+ action = 0x4;
+ res = RegDeleteValueW(env, name);
+ if (res != ERROR_SUCCESS)
+ WARN("Failed to remove value %s (%d)\n", debugstr_w(name), res);
goto done;
}
@@ -6037,6 +6058,7 @@ static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param )
{
lstrcpyW(newval, value);
ptr = newval + lstrlenW(value);
+ action |= 0x80000000;
}
lstrcpyW(ptr, data);
@@ -6044,12 +6066,24 @@ static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param )
if (flags & ENV_MOD_APPEND)
{
lstrcatW(newval, value);
+ action |= 0x40000000;
}
}
TRACE("setting %s to %s\n", debugstr_w(name), debugstr_w(newval));
res = RegSetValueExW(env, name, 0, type, (LPVOID)newval, size);
+ if (res)
+ {
+ WARN("Failed to set %s to %s (%d)\n", debugstr_w(name), debugstr_w(newval), res);
+ }
done:
+ uirow = MSI_CreateRecord( 3 );
+ MSI_RecordSetStringW( uirow, 1, name );
+ MSI_RecordSetStringW( uirow, 2, newval );
+ MSI_RecordSetInteger( uirow, 3, action );
+ ui_actiondata( package, szWriteEnvironmentStrings, uirow );
+ msiobj_release( &uirow->hdr );
+
if (env) RegCloseKey(env);
msi_free(deformatted);
msi_free(data);
@@ -6074,6 +6108,102 @@ static UINT ACTION_WriteEnvironmentStrings( MSIPACKAGE *package )
return rc;
}
+static UINT ITERATE_RemoveEnvironmentString( MSIRECORD *rec, LPVOID param )
+{
+ MSIPACKAGE *package = param;
+ LPCWSTR name, value, component;
+ LPWSTR deformatted = NULL;
+ DWORD flags;
+ HKEY env;
+ MSICOMPONENT *comp;
+ MSIRECORD *uirow;
+ int action = 0;
+ LONG res;
+ UINT r;
+
+ component = MSI_RecordGetString( rec, 4 );
+ comp = get_loaded_component( package, component );
+ if (!comp)
+ return ERROR_SUCCESS;
+
+ if (comp->ActionRequest != INSTALLSTATE_ABSENT)
+ {
+ TRACE("Component not scheduled for removal: %s\n", debugstr_w(component));
+ comp->Action = comp->Installed;
+ return ERROR_SUCCESS;
+ }
+ comp->Action = INSTALLSTATE_ABSENT;
+
+ name = MSI_RecordGetString( rec, 2 );
+ value = MSI_RecordGetString( rec, 3 );
+
+ TRACE("name %s value %s\n", debugstr_w(name), debugstr_w(value));
+
+ r = env_parse_flags( &name, &value, &flags );
+ if (r != ERROR_SUCCESS)
+ return r;
+
+ if (!(flags & ENV_ACT_REMOVE))
+ {
+ TRACE("Environment variable %s not marked for removal\n", debugstr_w(name));
+ return ERROR_SUCCESS;
+ }
+
+ if (value && !deformat_string( package, value, &deformatted ))
+ return ERROR_OUTOFMEMORY;
+
+ value = deformatted;
+
+ r = open_env_key( flags, &env );
+ if (r != ERROR_SUCCESS)
+ {
+ r = ERROR_SUCCESS;
+ goto done;
+ }
+
+ if (flags & ENV_MOD_MACHINE)
+ action |= 0x20000000;
+
+ TRACE("Removing %s\n", debugstr_w(name));
+
+ res = RegDeleteValueW( env, name );
+ if (res != ERROR_SUCCESS)
+ {
+ WARN("Failed to delete value %s (%d)\n", debugstr_w(name), res);
+ r = ERROR_SUCCESS;
+ }
+
+done:
+ uirow = MSI_CreateRecord( 3 );
+ MSI_RecordSetStringW( uirow, 1, name );
+ MSI_RecordSetStringW( uirow, 2, value );
+ MSI_RecordSetInteger( uirow, 3, action );
+ ui_actiondata( package, szRemoveEnvironmentStrings, uirow );
+ msiobj_release( &uirow->hdr );
+
+ if (env) RegCloseKey( env );
+ msi_free( deformatted );
+ return r;
+}
+
+static UINT ACTION_RemoveEnvironmentStrings( MSIPACKAGE *package )
+{
+ UINT rc;
+ MSIQUERY *view;
+ static const WCHAR query[] =
+ {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
+ '`','E','n','v','i','r','o','n','m','e','n','t','`',0};
+
+ rc = MSI_DatabaseOpenViewW( package->db, query, &view );
+ if (rc != ERROR_SUCCESS)
+ return ERROR_SUCCESS;
+
+ rc = MSI_IterateRecords( view, NULL, ITERATE_RemoveEnvironmentString, package );
+ msiobj_release( &view->hdr );
+
+ return rc;
+}
+
#define is_dot_dir(x) ((x[0] == '.') && ((x[1] == 0) || ((x[1] == '.') && (x[2] == 0))))
typedef struct
@@ -6972,13 +7102,6 @@ static UINT ACTION_MigrateFeatureStates( MSIPACKAGE *package )
return msi_unimplemented_action_stub( package, "MigrateFeatureStates", table );
}
-static UINT ACTION_RemoveEnvironmentStrings( MSIPACKAGE *package )
-{
- static const WCHAR table[] = {
- 'E','n','v','i','r','o','n','m','e','n','t',0 };
- return msi_unimplemented_action_stub( package, "RemoveEnvironmentStrings", table );
-}
-
static UINT ACTION_MsiUnpublishAssemblies( MSIPACKAGE *package )
{
static const WCHAR table[] = {
More information about the wine-cvs
mailing list