📄 action.c
字号:
'`','I','n','s','t','a','l','l','E','x','e','c','u','t','e',
'S','e','q','u','e','n','c','e','`',' ', 'W','H','E','R','E',' ',
'`','S','e','q','u','e','n','c','e','`',' ', '>',' ','%','i',' ',
'O','R','D','E','R',' ', 'B','Y',' ',
'`','S','e','q','u','e','n','c','e','`',0 };
MSIRECORD * row = 0;
static const WCHAR IVQuery[] =
{'S','E','L','E','C','T',' ','`','S','e','q','u','e','n','c','e','`',
' ', 'F','R','O','M',' ','`','I','n','s','t','a','l','l',
'E','x','e','c','u','t','e','S','e','q','u','e','n','c','e','`',' ',
'W','H','E','R','E',' ','`','A','c','t','i','o','n','`',' ','=',
' ','\'', 'I','n','s','t','a','l','l',
'V','a','l','i','d','a','t','e','\'', 0};
INT seq = 0;
iterate_action_param iap;
iap.package = package;
iap.UI = FALSE;
if (package->script->ExecuteSequenceRun)
{
TRACE("Execute Sequence already Run\n");
return ERROR_SUCCESS;
}
package->script->ExecuteSequenceRun = TRUE;
/* get the sequence number */
if (UIran)
{
row = MSI_QueryGetRecord(package->db, IVQuery);
if( !row )
return ERROR_FUNCTION_FAILED;
seq = MSI_RecordGetInteger(row,1);
msiobj_release(&row->hdr);
}
rc = MSI_OpenQuery(package->db, &view, ExecSeqQuery, seq);
if (rc == ERROR_SUCCESS)
{
TRACE("Running the actions\n");
rc = MSI_IterateRecords(view, NULL, ITERATE_Actions, &iap);
msiobj_release(&view->hdr);
}
return rc;
}
static UINT ACTION_ProcessUISequence(MSIPACKAGE *package)
{
MSIQUERY * view;
UINT rc;
static const WCHAR ExecSeqQuery [] =
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
'`','I','n','s','t','a','l','l',
'U','I','S','e','q','u','e','n','c','e','`',
' ','W','H','E','R','E',' ',
'`','S','e','q','u','e','n','c','e','`',' ',
'>',' ','0',' ','O','R','D','E','R',' ','B','Y',' ',
'`','S','e','q','u','e','n','c','e','`',0};
iterate_action_param iap;
iap.package = package;
iap.UI = TRUE;
rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
if (rc == ERROR_SUCCESS)
{
TRACE("Running the actions\n");
rc = MSI_IterateRecords(view, NULL, ITERATE_Actions, &iap);
msiobj_release(&view->hdr);
}
return rc;
}
/********************************************************
* ACTION helper functions and functions that perform the actions
*******************************************************/
static BOOL ACTION_HandleStandardAction(MSIPACKAGE *package, LPCWSTR action,
UINT* rc, BOOL force )
{
BOOL ret = FALSE;
BOOL run = force;
int i;
if (!run && !package->script->CurrentlyScripting)
run = TRUE;
if (!run)
{
if (strcmpW(action,szInstallFinalize) == 0 ||
strcmpW(action,szInstallExecute) == 0 ||
strcmpW(action,szInstallExecuteAgain) == 0)
run = TRUE;
}
i = 0;
while (StandardActions[i].action != NULL)
{
if (strcmpW(StandardActions[i].action, action)==0)
{
if (!run)
{
ui_actioninfo(package, action, TRUE, 0);
*rc = schedule_action(package,INSTALL_SCRIPT,action);
ui_actioninfo(package, action, FALSE, *rc);
}
else
{
ui_actionstart(package, action);
if (StandardActions[i].handler)
{
*rc = StandardActions[i].handler(package);
}
else
{
FIXME("unhandled standard action %s\n",debugstr_w(action));
*rc = ERROR_SUCCESS;
}
}
ret = TRUE;
break;
}
i++;
}
return ret;
}
static BOOL ACTION_HandleCustomAction( MSIPACKAGE* package, LPCWSTR action,
UINT* rc, BOOL force )
{
BOOL ret=FALSE;
UINT arc;
arc = ACTION_CustomAction(package,action, force);
if (arc != ERROR_CALL_NOT_IMPLEMENTED)
{
*rc = arc;
ret = TRUE;
}
return ret;
}
/*
* A lot of actions are really important even if they don't do anything
* explicit... Lots of properties are set at the beginning of the installation
* CostFinalize does a bunch of work to translate the directories and such
*
* But until I get write access to the database that is hard, so I am going to
* hack it to see if I can get something to run.
*/
UINT ACTION_PerformAction(MSIPACKAGE *package, const WCHAR *action, BOOL force)
{
UINT rc = ERROR_SUCCESS;
BOOL handled;
TRACE("Performing action (%s)\n",debugstr_w(action));
handled = ACTION_HandleStandardAction(package, action, &rc, force);
if (!handled)
handled = ACTION_HandleCustomAction(package, action, &rc, force);
if (!handled)
{
FIXME("unhandled msi action %s\n",debugstr_w(action));
rc = ERROR_FUNCTION_NOT_CALLED;
}
return rc;
}
UINT ACTION_PerformUIAction(MSIPACKAGE *package, const WCHAR *action)
{
UINT rc = ERROR_SUCCESS;
BOOL handled = FALSE;
TRACE("Performing action (%s)\n",debugstr_w(action));
handled = ACTION_HandleStandardAction(package, action, &rc,TRUE);
if (!handled)
handled = ACTION_HandleCustomAction(package, action, &rc, FALSE);
if( !handled && ACTION_DialogBox(package,action) == ERROR_SUCCESS )
handled = TRUE;
if (!handled)
{
FIXME("unhandled msi action %s\n",debugstr_w(action));
rc = ERROR_FUNCTION_NOT_CALLED;
}
return rc;
}
/*
* Actual Action Handlers
*/
static UINT ITERATE_CreateFolders(MSIRECORD *row, LPVOID param)
{
MSIPACKAGE *package = (MSIPACKAGE*)param;
LPCWSTR dir;
LPWSTR full_path;
MSIRECORD *uirow;
MSIFOLDER *folder;
dir = MSI_RecordGetString(row,1);
if (!dir)
{
ERR("Unable to get folder id\n");
return ERROR_SUCCESS;
}
full_path = resolve_folder(package,dir,FALSE,FALSE,&folder);
if (!full_path)
{
ERR("Unable to resolve folder id %s\n",debugstr_w(dir));
return ERROR_SUCCESS;
}
TRACE("Folder is %s\n",debugstr_w(full_path));
/* UI stuff */
uirow = MSI_CreateRecord(1);
MSI_RecordSetStringW(uirow,1,full_path);
ui_actiondata(package,szCreateFolders,uirow);
msiobj_release( &uirow->hdr );
if (folder->State == 0)
create_full_pathW(full_path);
folder->State = 3;
msi_free(full_path);
return ERROR_SUCCESS;
}
/* FIXME: probably should merge this with the above function */
static UINT msi_create_directory( MSIPACKAGE* package, LPCWSTR dir )
{
UINT rc = ERROR_SUCCESS;
MSIFOLDER *folder;
LPWSTR install_path;
install_path = resolve_folder(package, dir, FALSE, FALSE, &folder);
if (!install_path)
return ERROR_FUNCTION_FAILED;
/* create the path */
if (folder->State == 0)
{
create_full_pathW(install_path);
folder->State = 2;
}
msi_free(install_path);
return rc;
}
UINT msi_create_component_directories( MSIPACKAGE *package )
{
MSICOMPONENT *comp;
/* create all the folders required by the components are going to install */
LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
{
if (!ACTION_VerifyComponentForAction( comp, INSTALLSTATE_LOCAL))
continue;
msi_create_directory( package, comp->Directory );
}
return ERROR_SUCCESS;
}
/*
* Also we cannot enable/disable components either, so for now I am just going
* to do all the directories for all the components.
*/
static UINT ACTION_CreateFolders(MSIPACKAGE *package)
{
static const WCHAR ExecSeqQuery[] =
{'S','E','L','E','C','T',' ',
'`','D','i','r','e','c','t','o','r','y','_','`',
' ','F','R','O','M',' ',
'`','C','r','e','a','t','e','F','o','l','d','e','r','`',0 };
UINT rc;
MSIQUERY *view;
/* create all the empty folders specified in the CreateFolder table */
rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view );
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
rc = MSI_IterateRecords(view, NULL, ITERATE_CreateFolders, package);
msiobj_release(&view->hdr);
msi_create_component_directories( package );
return rc;
}
static UINT load_component( MSIRECORD *row, LPVOID param )
{
MSIPACKAGE *package = param;
MSICOMPONENT *comp;
comp = msi_alloc_zero( sizeof(MSICOMPONENT) );
if (!comp)
return ERROR_FUNCTION_FAILED;
list_add_tail( &package->components, &comp->entry );
/* fill in the data */
comp->Component = msi_dup_record_field( row, 1 );
TRACE("Loading Component %s\n", debugstr_w(comp->Component));
comp->ComponentId = msi_dup_record_field( row, 2 );
comp->Directory = msi_dup_record_field( row, 3 );
comp->Attributes = MSI_RecordGetInteger(row,4);
comp->Condition = msi_dup_record_field( row, 5 );
comp->KeyPath = msi_dup_record_field( row, 6 );
comp->Installed = INSTALLSTATE_UNKNOWN;
msi_component_set_state( comp, INSTALLSTATE_UNKNOWN );
return ERROR_SUCCESS;
}
static UINT load_all_components( MSIPACKAGE *package )
{
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','*',' ','F','R', 'O','M',' ',
'`','C','o','m','p','o','n','e','n','t','`',0 };
MSIQUERY *view;
UINT r;
if (!list_empty(&package->components))
return ERROR_SUCCESS;
r = MSI_DatabaseOpenViewW( package->db, query, &view );
if (r != ERROR_SUCCESS)
return r;
r = MSI_IterateRecords(view, NULL, load_component, package);
msiobj_release(&view->hdr);
return r;
}
typedef struct {
MSIPACKAGE *package;
MSIFEATURE *feature;
} _ilfs;
static UINT add_feature_component( MSIFEATURE *feature, MSICOMPONENT *comp )
{
ComponentList *cl;
cl = msi_alloc( sizeof (*cl) );
if ( !cl )
return ERROR_NOT_ENOUGH_MEMORY;
cl->component = comp;
list_add_tail( &feature->Components, &cl->entry );
return ERROR_SUCCESS;
}
static UINT add_feature_child( MSIFEATURE *parent, MSIFEATURE *child )
{
FeatureList *fl;
fl = msi_alloc( sizeof(*fl) );
if ( !fl )
return ERROR_NOT_ENOUGH_MEMORY;
fl->feature = child;
list_add_tail( &parent->Children, &fl->entry );
return ERROR_SUCCESS;
}
static UINT iterate_load_featurecomponents(MSIRECORD *row, LPVOID param)
{
_ilfs* ilfs= (_ilfs*)param;
LPCWSTR component;
MSICOMPONENT *comp;
component = MSI_RecordGetString(row,1);
/* check to see if the component is already loaded */
comp = get_loaded_component( ilfs->package, component );
if (!comp)
{
ERR("unknown component %s\n", debugstr_w(component));
return ERROR_FUNCTION_FAILED;
}
add_feature_component( ilfs->feature, comp );
comp->Enabled = TRUE;
return ERROR_SUCCESS;
}
static MSIFEATURE *find_feature_by_name( MSIPACKAGE *package, LPCWSTR name )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -