Send progress and action messages.

This commit is contained in:
Aric Stewart 2004-07-06 18:48:15 +00:00 committed by Alexandre Julliard
parent 5b936ca2fd
commit d2c395ad50
2 changed files with 290 additions and 85 deletions

View File

@ -167,6 +167,26 @@ static const WCHAR cszlsb[]={'[',0};
static const WCHAR cszrsb[]={']',0}; static const WCHAR cszrsb[]={']',0};
static const WCHAR cszbs[]={'\\',0}; static const WCHAR cszbs[]={'\\',0};
const static WCHAR szCreateFolders[] =
{'C','r','e','a','t','e','F','o','l','d','e','r','s',0};
const static WCHAR szCostFinalize[] =
{'C','o','s','t','F','i','n','a','l','i','z','e',0};
const static WCHAR szInstallFiles[] =
{'I','n','s','t','a','l','l','F','i','l','e','s',0};
const static WCHAR szDuplicateFiles[] =
{'D','u','p','l','i','c','a','t','e','F','i','l','e','s',0};
const static WCHAR szWriteRegistryValues[] =
{'W','r','i','t','e','R','e','g','i','s','t','r','y','V','a','l','u','e','s',0};
const static WCHAR szCostInitialize[] =
{'C','o','s','t','I','n','i','t','i','a','l','i','z','e',0};
const static WCHAR szFileCost[] = {'F','i','l','e','C','o','s','t',0};
const static WCHAR szInstallInitialize[] =
{'I','n','s','t','a','l','l','I','n','i','t','i','a','l','i','z','e',0};
const static WCHAR szInstallValidate[] =
{'I','n','s','t','a','l','l','V','a','l','i','d','a','t','e',0};
const static WCHAR szLaunchConditions[] =
{'L','a','u','n','c','h','C','o','n','d','i','t','i','o','n','s',0};
/******************************************************** /********************************************************
* helper functions to get around current HACKS and such * helper functions to get around current HACKS and such
@ -275,7 +295,7 @@ void ACTION_remove_tracked_tempfiles(MSIPACKAGE* package)
} }
} }
static void progress_message(MSIHANDLE hPackage, int a, int b, int c, int d ) static void ui_progress(MSIHANDLE hPackage, int a, int b, int c, int d )
{ {
MSIHANDLE row; MSIHANDLE row;
@ -288,6 +308,176 @@ static void progress_message(MSIHANDLE hPackage, int a, int b, int c, int d )
MsiCloseHandle(row); MsiCloseHandle(row);
} }
static void ui_actiondata(MSIHANDLE hPackage, LPCWSTR action, MSIHANDLE record)
{
static const WCHAR Query_t[] =
{'S','E','L','E','C','T',' ','*',' ','f','r','o','m',' ','A','c','t','i','o',
'n','T','e','x','t',' ','w','h','e','r','e',' ','A','c','t','i','o','n',' ','=',
' ','\'','%','s','\'',0};
WCHAR message[1024];
UINT rc;
MSIHANDLE view;
MSIHANDLE row = 0;
WCHAR *ActionFormat=NULL;
DWORD sz;
WCHAR Query[1024];
MSIHANDLE db;
LPWSTR ptr;
sprintfW(Query,Query_t,action);
db = MsiGetActiveDatabase(hPackage);
rc = MsiDatabaseOpenViewW(db, Query, &view);
MsiCloseHandle(db);
MsiViewExecute(view, 0);
rc = MsiViewFetch(view,&row);
if (rc != ERROR_SUCCESS)
{
MsiViewClose(view);
MsiCloseHandle(view);
return;
}
if (MsiRecordIsNull(row,3))
{
MsiCloseHandle(row);
MsiViewClose(view);
MsiCloseHandle(view);
return;
}
sz = 0;
MsiRecordGetStringW(row,3,NULL,&sz);
sz++;
ActionFormat = HeapAlloc(GetProcessHeap(),0,sz*sizeof(WCHAR));
MsiRecordGetStringW(row,3,ActionFormat,&sz);
MsiCloseHandle(row);
MsiViewClose(view);
MsiCloseHandle(view);
message[0]=0;
ptr = ActionFormat;
while (*ptr)
{
LPWSTR ptr2;
LPWSTR data=NULL;
WCHAR tmp[1023];
INT field;
ptr2 = strchrW(ptr,'[');
if (ptr2)
{
strncpyW(tmp,ptr,ptr2-ptr);
tmp[ptr2-ptr]=0;
strcatW(message,tmp);
ptr2++;
field = atoiW(ptr2);
sz = 0;
MsiRecordGetStringW(record,field,NULL,&sz);
sz++;
data = HeapAlloc(GetProcessHeap(),0,sz*sizeof(WCHAR));
MsiRecordGetStringW(record,field,data,&sz);
strcatW(message,data);
HeapFree(GetProcessHeap(),0,data);
ptr=strchrW(ptr2,']');
ptr++;
}
else
{
strcatW(message,ptr);
break;
}
}
row = MsiCreateRecord(1);
MsiRecordSetStringW(row,1,message);
MsiProcessMessage(hPackage, INSTALLMESSAGE_ACTIONDATA, row);
MsiCloseHandle(row);
HeapFree(GetProcessHeap(),0,ActionFormat);
}
static void ui_actionstart(MSIHANDLE hPackage, LPCWSTR action)
{
static const WCHAR template_s[]=
{'A','c','t','i','o','n',' ','%','s',':',' ','%','s','.',' ','%','s','.',0};
static const WCHAR format[] =
{'H','H','\'',':','\'','m','m','\'',':','\'','s','s',0};
static const WCHAR Query_t[] =
{'S','E','L','E','C','T',' ','*',' ','f','r','o','m',' ','A','c','t','i','o',
'n','T','e','x','t',' ','w','h','e','r','e',' ','A','c','t','i','o','n',' ','=',
' ','\'','%','s','\'',0};
WCHAR message[1024];
WCHAR timet[0x100];
UINT rc;
MSIHANDLE view;
MSIHANDLE row = 0;
WCHAR *ActionText=NULL;
DWORD sz;
WCHAR Query[1024];
MSIHANDLE db;
GetTimeFormatW(LOCALE_USER_DEFAULT, 0, NULL, format, timet, 0x100);
sprintfW(Query,Query_t,action);
db = MsiGetActiveDatabase(hPackage);
rc = MsiDatabaseOpenViewW(db, Query, &view);
MsiCloseHandle(db);
MsiViewExecute(view, 0);
rc = MsiViewFetch(view,&row);
if (rc != ERROR_SUCCESS)
{
MsiViewClose(view);
MsiCloseHandle(view);
return;
}
sz = 0;
MsiRecordGetStringW(row,2,NULL,&sz);
sz++;
ActionText = HeapAlloc(GetProcessHeap(),0,sz*sizeof(WCHAR));
MsiRecordGetStringW(row,2,ActionText,&sz);
MsiCloseHandle(row);
MsiViewClose(view);
MsiCloseHandle(view);
sprintfW(message,template_s,timet,action,ActionText);
row = MsiCreateRecord(1);
MsiRecordSetStringW(row,1,message);
MsiProcessMessage(hPackage, INSTALLMESSAGE_ACTIONSTART, row);
MsiCloseHandle(row);
HeapFree(GetProcessHeap(),0,ActionText);
}
static void ui_actioninfo(MSIHANDLE hPackage, LPCWSTR action, BOOL start,
UINT rc)
{
MSIHANDLE row;
static const WCHAR template_s[]=
{'A','c','t','i','o','n',' ','s','t','a','r','t',' ','%','s',':',' ','%','s',
'.',0};
static const WCHAR template_e[]=
{'A','c','t','i','o','n',' ','e','n','d','e','d',' ','%','s',':',' ','%','s',
'.',' ','R','e','t','u','r','n',' ','v','a','l','u','e',' ','%','i','.',0};
static const WCHAR format[] =
{'H','H','\'',':','\'','m','m','\'',':','\'','s','s',0};
WCHAR message[1024];
WCHAR timet[0x100];
GetTimeFormatW(LOCALE_USER_DEFAULT, 0, NULL, format, timet, 0x100);
if (start)
sprintfW(message,template_s,timet,action);
else
sprintfW(message,template_e,timet,action,rc);
row = MsiCreateRecord(1);
MsiRecordSetStringW(row,1,message);
MsiProcessMessage(hPackage, INSTALLMESSAGE_INFO, row);
MsiCloseHandle(row);
}
/**************************************************** /****************************************************
* TOP level entry points * TOP level entry points
*****************************************************/ *****************************************************/
@ -596,53 +786,36 @@ end:
*/ */
UINT ACTION_PerformAction(MSIHANDLE hPackage, const WCHAR *action) UINT ACTION_PerformAction(MSIHANDLE hPackage, const WCHAR *action)
{ {
const static WCHAR szCreateFolders[] = UINT rc = ERROR_SUCCESS;
{'C','r','e','a','t','e','F','o','l','d','e','r','s',0};
const static WCHAR szCostFinalize[] =
{'C','o','s','t','F','i','n','a','l','i','z','e',0};
const static WCHAR szInstallFiles[] =
{'I','n','s','t','a','l','l','F','i','l','e','s',0};
const static WCHAR szDuplicateFiles[] =
{'D','u','p','l','i','c','a','t','e','F','i','l','e','s',0};
const static WCHAR szWriteRegistryValues[] =
{'W','r','i','t','e','R','e','g','i','s','t','r','y','V','a','l','u','e','s',0};
const static WCHAR szCostInitialize[] =
{'C','o','s','t','I','n','i','t','i','a','l','i','z','e',0};
const static WCHAR szFileCost[] =
{'F','i','l','e','C','o','s','t',0};
const static WCHAR szInstallInitialize[] =
{'I','n','s','t','a','l','l','I','n','i','t','i','a','l','i','z','e',0};
const static WCHAR szInstallValidate[] =
{'I','n','s','t','a','l','l','V','a','l','i','d','a','t','e',0};
const static WCHAR szLaunchConditions[] =
{'L','a','u','n','c','h','C','o','n','d','i','t','i','o','n','s',0};
TRACE("Performing action (%s)\n",debugstr_w(action)); TRACE("Performing action (%s)\n",debugstr_w(action));
progress_message(hPackage,2,25,0,0); ui_actioninfo(hPackage, action, TRUE, 0);
ui_actionstart(hPackage, action);
ui_progress(hPackage,2,1,0,0);
/* pre install, setup and configureation block */ /* pre install, setup and configureation block */
if (strcmpW(action,szLaunchConditions)==0) if (strcmpW(action,szLaunchConditions)==0)
return ACTION_LaunchConditions(hPackage); rc = ACTION_LaunchConditions(hPackage);
if (strcmpW(action,szCostInitialize)==0) else if (strcmpW(action,szCostInitialize)==0)
return ACTION_CostInitialize(hPackage); rc = ACTION_CostInitialize(hPackage);
if (strcmpW(action,szFileCost)==0) else if (strcmpW(action,szFileCost)==0)
return ACTION_FileCost(hPackage); rc = ACTION_FileCost(hPackage);
if (strcmpW(action,szCostFinalize)==0) else if (strcmpW(action,szCostFinalize)==0)
return ACTION_CostFinalize(hPackage); rc = ACTION_CostFinalize(hPackage);
if (strcmpW(action,szInstallValidate)==0) else if (strcmpW(action,szInstallValidate)==0)
return ACTION_InstallValidate(hPackage); rc = ACTION_InstallValidate(hPackage);
/* install block */ /* install block */
if (strcmpW(action,szInstallInitialize)==0) else if (strcmpW(action,szInstallInitialize)==0)
return ACTION_InstallInitialize(hPackage); rc = ACTION_InstallInitialize(hPackage);
if (strcmpW(action,szCreateFolders)==0) else if (strcmpW(action,szCreateFolders)==0)
return ACTION_CreateFolders(hPackage); rc = ACTION_CreateFolders(hPackage);
if (strcmpW(action,szInstallFiles)==0) else if (strcmpW(action,szInstallFiles)==0)
return ACTION_InstallFiles(hPackage); rc = ACTION_InstallFiles(hPackage);
if (strcmpW(action,szDuplicateFiles)==0) else if (strcmpW(action,szDuplicateFiles)==0)
return ACTION_DuplicateFiles(hPackage); rc = ACTION_DuplicateFiles(hPackage);
if (strcmpW(action,szWriteRegistryValues)==0) else if (strcmpW(action,szWriteRegistryValues)==0)
return ACTION_WriteRegistryValues(hPackage); rc = ACTION_WriteRegistryValues(hPackage);
/* /*
Current called during itunes but unimplemented Current called during itunes but unimplemented
@ -704,16 +877,20 @@ UINT ACTION_PerformAction(MSIHANDLE hPackage, const WCHAR *action)
InstallFinalize InstallFinalize
. .
*/ */
if (ACTION_CustomAction(hPackage,action) != ERROR_SUCCESS) else if ((rc = ACTION_CustomAction(hPackage,action)) != ERROR_SUCCESS)
{
FIXME("UNHANDLED MSI ACTION %s\n",debugstr_w(action)); FIXME("UNHANDLED MSI ACTION %s\n",debugstr_w(action));
rc = ERROR_SUCCESS;
}
return ERROR_SUCCESS; ui_actioninfo(hPackage, action, FALSE, rc);
return rc;
} }
static UINT ACTION_CustomAction(MSIHANDLE hPackage,const WCHAR *action) static UINT ACTION_CustomAction(MSIHANDLE hPackage,const WCHAR *action)
{ {
UINT rc; UINT rc = ERROR_SUCCESS;
MSIHANDLE view; MSIHANDLE view;
MSIHANDLE row = 0; MSIHANDLE row = 0;
WCHAR ExecSeqQuery[1024] = WCHAR ExecSeqQuery[1024] =
@ -776,7 +953,7 @@ static UINT ACTION_CustomAction(MSIHANDLE hPackage,const WCHAR *action)
case 35: /* Directory set with formatted text. */ case 35: /* Directory set with formatted text. */
case 51: /* Property set with formatted text. */ case 51: /* Property set with formatted text. */
deformat_string(hPackage,target,&deformated); deformat_string(hPackage,target,&deformated);
MsiSetPropertyW(hPackage,source,deformated); rc = MsiSetPropertyW(hPackage,source,deformated);
HeapFree(GetProcessHeap(),0,deformated); HeapFree(GetProcessHeap(),0,deformated);
break; break;
default: default:
@ -1055,6 +1232,7 @@ static UINT ACTION_CreateFolders(MSIHANDLE hPackage)
WCHAR full_path[MAX_PATH]; WCHAR full_path[MAX_PATH];
DWORD sz; DWORD sz;
MSIHANDLE row = 0; MSIHANDLE row = 0;
MSIHANDLE uirow;
rc = MsiViewFetch(view,&row); rc = MsiViewFetch(view,&row);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
@ -1085,6 +1263,12 @@ static UINT ACTION_CreateFolders(MSIHANDLE hPackage)
TRACE("Folder is %s\n",debugstr_w(full_path)); TRACE("Folder is %s\n",debugstr_w(full_path));
/* UI stuff */
uirow = MsiCreateRecord(1);
MsiRecordSetStringW(uirow,1,full_path);
ui_actiondata(hPackage,szCreateFolders,uirow);
MsiCloseHandle(uirow);
if (folder->State == 0) if (folder->State == 0)
create_full_pathW(full_path); create_full_pathW(full_path);
@ -2129,12 +2313,17 @@ static UINT ACTION_InstallFiles(MSIHANDLE hPackage)
UINT rc = ERROR_SUCCESS; UINT rc = ERROR_SUCCESS;
INT index; INT index;
MSIPACKAGE *package; MSIPACKAGE *package;
MSIHANDLE uirow;
WCHAR uipath[MAX_PATH];
package = msihandle2msiinfo(hPackage, MSIHANDLETYPE_PACKAGE); package = msihandle2msiinfo(hPackage, MSIHANDLETYPE_PACKAGE);
if (!package) if (!package)
return ERROR_INVALID_HANDLE; return ERROR_INVALID_HANDLE;
/* increment progress bar each time action data is sent */
ui_progress(hPackage,1,1,1,0);
for (index = 0; index < package->loaded_files; index++) for (index = 0; index < package->loaded_files; index++)
{ {
WCHAR path_to_source[MAX_PATH]; WCHAR path_to_source[MAX_PATH];
@ -2178,8 +2367,19 @@ static UINT ACTION_InstallFiles(MSIHANDLE hPackage)
TRACE("file paths %s to %s\n",debugstr_w(file->SourcePath), TRACE("file paths %s to %s\n",debugstr_w(file->SourcePath),
debugstr_w(file->TargetPath)); debugstr_w(file->TargetPath));
progress_message(hPackage,2,1,0,0); /* the UI chunk */
uirow=MsiCreateRecord(9);
MsiRecordSetStringW(uirow,1,file->File);
strcpyW(uipath,file->TargetPath);
*(strrchrW(uipath,'\\')+1)=0;
MsiRecordSetStringW(uirow,9,uipath);
MsiRecordSetInteger(uirow,6,file->FileSize);
ui_actiondata(hPackage,szInstallFiles,uirow);
MsiCloseHandle(uirow);
rc = !MoveFileW(file->SourcePath,file->TargetPath); rc = !MoveFileW(file->SourcePath,file->TargetPath);
ui_progress(hPackage,2,0,0,0);
if (rc) if (rc)
ERR("Unable to move file\n"); ERR("Unable to move file\n");
else else
@ -2453,8 +2653,21 @@ static UINT ACTION_WriteRegistryValues(MSIHANDLE hPackage)
return rc; return rc;
} }
/* increment progress bar each time action data is sent */
ui_progress(hPackage,1,1,1,0);
while (1) while (1)
{ {
static const WCHAR szHCR[] =
{'H','K','E','Y','_','C','L','A','S','S','E','S','_','R','O','O','T','\\',0};
static const WCHAR szHCU[] =
{'H','K','E','Y','_','C','U','R','R','E','N','T','_','U','S','E','R','\\',0};
static const WCHAR szHLM[] =
{'H','K','E','Y','_','L','O','C','A','L','_','M','A','C','H','I','N','E',
'\\',0};
static const WCHAR szHU[] =
{'H','K','E','Y','_','U','S','E','R','S','\\',0};
WCHAR key[0x100]; WCHAR key[0x100];
WCHAR name[0x100]; WCHAR name[0x100];
LPWSTR value; LPWSTR value;
@ -2463,6 +2676,8 @@ static UINT ACTION_WriteRegistryValues(MSIHANDLE hPackage)
DWORD type,size; DWORD type,size;
WCHAR component[0x100]; WCHAR component[0x100];
INT component_index; INT component_index;
MSIHANDLE uirow;
WCHAR uikey[0x110];
INT root; INT root;
DWORD sz=0x100; DWORD sz=0x100;
@ -2504,14 +2719,17 @@ static UINT ACTION_WriteRegistryValues(MSIHANDLE hPackage)
else else
MsiRecordGetStringW(row,4,name,&sz); MsiRecordGetStringW(row,4,name,&sz);
/* get the root key */ /* get the root key */
switch (root) switch (root)
{ {
case 0: root_key = HKEY_CLASSES_ROOT; break; case 0: root_key = HKEY_CLASSES_ROOT;
case 1: root_key = HKEY_CURRENT_USER; break; strcpyW(uikey,szHCR); break;
case 2: root_key = HKEY_LOCAL_MACHINE; break; case 1: root_key = HKEY_CURRENT_USER;
case 3: root_key = HKEY_USERS; break; strcpyW(uikey,szHCU); break;
case 2: root_key = HKEY_LOCAL_MACHINE;
strcpyW(uikey,szHLM); break;
case 3: root_key = HKEY_USERS;
strcpyW(uikey,szHU); break;
default: default:
ERR("Unknown root %i\n",root); ERR("Unknown root %i\n",root);
root_key=NULL; root_key=NULL;
@ -2523,6 +2741,7 @@ static UINT ACTION_WriteRegistryValues(MSIHANDLE hPackage)
continue; continue;
} }
strcatW(uikey,key);
if (RegCreateKeyW( root_key, key, &hkey)) if (RegCreateKeyW( root_key, key, &hkey))
{ {
ERR("Could not create key %s\n",debugstr_w(key)); ERR("Could not create key %s\n",debugstr_w(key));
@ -2536,15 +2755,28 @@ static UINT ACTION_WriteRegistryValues(MSIHANDLE hPackage)
value = HeapAlloc(GetProcessHeap(),0,sz * sizeof(WCHAR)); value = HeapAlloc(GetProcessHeap(),0,sz * sizeof(WCHAR));
MsiRecordGetStringW(row,5,value,&sz); MsiRecordGetStringW(row,5,value,&sz);
value_data = parse_value(hPackage, value, &type, &size); value_data = parse_value(hPackage, value, &type, &size);
HeapFree(GetProcessHeap(),0,value);
if (value_data) if (value_data)
{ {
TRACE("Setting value %s\n",debugstr_w(name)); TRACE("Setting value %s\n",debugstr_w(name));
RegSetValueExW(hkey, name, 0, type, value_data, size); RegSetValueExW(hkey, name, 0, type, value_data, size);
uirow = MsiCreateRecord(3);
MsiRecordSetStringW(uirow,2,name);
MsiRecordSetStringW(uirow,1,uikey);
if (type == REG_SZ)
MsiRecordSetStringW(uirow,3,(LPWSTR)value_data);
else
MsiRecordSetStringW(uirow,3,value);
ui_actiondata(hPackage,szWriteRegistryValues,uirow);
ui_progress(hPackage,2,0,0,0);
MsiCloseHandle(uirow);
HeapFree(GetProcessHeap(),0,value_data); HeapFree(GetProcessHeap(),0,value_data);
} }
progress_message(hPackage,2,1,0,0); HeapFree(GetProcessHeap(),0,value);
MsiCloseHandle(row); MsiCloseHandle(row);
} }
@ -2705,45 +2937,15 @@ static UINT ACTION_InstallValidate(MSIHANDLE hPackage)
{ {
DWORD progress = 0; DWORD progress = 0;
static const CHAR q1[]="SELECT * FROM Registry"; static const CHAR q1[]="SELECT * FROM Registry";
static const CHAR q2[]=
"select Action from InstallExecuteSequence where Sequence > 0 order by Sequence";
UINT rc; UINT rc;
MSIHANDLE view; MSIHANDLE view;
MSIHANDLE row = 0; MSIHANDLE row = 0;
MSIHANDLE db; MSIHANDLE db;
BOOL flipit= FALSE;
MSIPACKAGE* package; MSIPACKAGE* package;
TRACE(" InstallValidate \n"); TRACE(" InstallValidate \n");
db = MsiGetActiveDatabase(hPackage); db = MsiGetActiveDatabase(hPackage);
rc = MsiDatabaseOpenViewA(db, q2, &view);
rc = MsiViewExecute(view, 0);
while (1)
{
rc = MsiViewFetch(view,&row);
if (rc != ERROR_SUCCESS)
{
rc = ERROR_SUCCESS;
break;
}
if (!flipit)
{
CHAR buf[0x100];
DWORD sz=0x100;
MsiRecordGetStringA(row,1,buf,&sz);
if (strcmp(buf,"InstallValidate")==0)
flipit=TRUE;
}
else
progress +=25;
MsiCloseHandle(row);
}
MsiViewClose(view);
MsiCloseHandle(view);
rc = MsiDatabaseOpenViewA(db, q1, &view); rc = MsiDatabaseOpenViewA(db, q1, &view);
rc = MsiViewExecute(view, 0); rc = MsiViewExecute(view, 0);
while (1) while (1)
@ -2763,7 +2965,7 @@ static UINT ACTION_InstallValidate(MSIHANDLE hPackage)
MsiCloseHandle(db); MsiCloseHandle(db);
package = msihandle2msiinfo(hPackage, MSIHANDLETYPE_PACKAGE); package = msihandle2msiinfo(hPackage, MSIHANDLETYPE_PACKAGE);
progress_message(hPackage,0,progress+package->loaded_files,0,0); ui_progress(hPackage,0,progress+package->loaded_files,0,0);
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }

View File

@ -419,10 +419,13 @@ INT WINAPI MsiProcessMessage( MSIHANDLE hInstall, INSTALLMESSAGE eMessageType,
if (msg_field > 1) if (msg_field > 1)
{ {
sprintf(number," %i: ",i); sprintf(number,"%i: ",i);
strcat(message,number); strcat(message,number);
} }
strcat(message,tmp); strcat(message,tmp);
if (msg_field > 1)
strcat(message," ");
HeapFree(GetProcessHeap(),0,tmp); HeapFree(GetProcessHeap(),0,tmp);
} }