Activate features and components based on their various conditions.
This commit is contained in:
parent
ec688fb4e0
commit
7d3e5973fe
|
@ -76,6 +76,7 @@ typedef struct tagMSICOMPONENT
|
|||
WCHAR KeyPath[96];
|
||||
|
||||
INSTALLSTATE State;
|
||||
BOOL FeatureState;
|
||||
BOOL Enabled;
|
||||
INT Cost;
|
||||
}MSICOMPONENT;
|
||||
|
@ -136,6 +137,8 @@ static UINT ACTION_InstallFiles(MSIHANDLE hPackage);
|
|||
static UINT ACTION_DuplicateFiles(MSIHANDLE hPackage);
|
||||
static UINT ACTION_WriteRegistryValues(MSIHANDLE hPackage);
|
||||
static UINT ACTION_CustomAction(MSIHANDLE hPackage,const WCHAR *action);
|
||||
static UINT ACTION_InstallInitialize(MSIHANDLE hPackage);
|
||||
static UINT ACTION_InstallValidate(MSIHANDLE hPackage);
|
||||
|
||||
static UINT HANDLE_CustomType1(MSIHANDLE hPackage, const LPWSTR source,
|
||||
const LPWSTR target, const INT type);
|
||||
|
@ -205,6 +208,22 @@ inline static int get_loaded_component(MSIPACKAGE* package, LPCWSTR Component )
|
|||
return rc;
|
||||
}
|
||||
|
||||
inline static int get_loaded_feature(MSIPACKAGE* package, LPCWSTR Feature )
|
||||
{
|
||||
INT rc = -1;
|
||||
INT i;
|
||||
|
||||
for (i = 0; i < package->loaded_features; i++)
|
||||
{
|
||||
if (strcmpW(Feature,package->features[i].Feature)==0)
|
||||
{
|
||||
rc = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static UINT track_tempfile(MSIHANDLE hPackage, LPCWSTR name, LPCWSTR path)
|
||||
{
|
||||
MSIPACKAGE *package;
|
||||
|
@ -254,6 +273,19 @@ void ACTION_remove_tracked_tempfiles(MSIPACKAGE* package)
|
|||
}
|
||||
}
|
||||
|
||||
static void progress_message(MSIHANDLE hPackage, int a, int b, int c, int d )
|
||||
{
|
||||
MSIHANDLE row;
|
||||
|
||||
row = MsiCreateRecord(4);
|
||||
MsiRecordSetInteger(row,1,a);
|
||||
MsiRecordSetInteger(row,2,b);
|
||||
MsiRecordSetInteger(row,3,c);
|
||||
MsiRecordSetInteger(row,4,d);
|
||||
MsiProcessMessage(hPackage, INSTALLMESSAGE_PROGRESS, row);
|
||||
MsiCloseHandle(row);
|
||||
}
|
||||
|
||||
/****************************************************
|
||||
* TOP level entry points
|
||||
*****************************************************/
|
||||
|
@ -576,15 +608,27 @@ UINT ACTION_PerformAction(MSIHANDLE hPackage, const WCHAR *action)
|
|||
{'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};
|
||||
|
||||
TRACE("Performing action (%s)\n",debugstr_w(action));
|
||||
progress_message(hPackage,2,25,0,0);
|
||||
|
||||
/* pre install, setup and configureation block */
|
||||
if (strcmpW(action,szCostInitialize)==0)
|
||||
return ACTION_CostInitialize(hPackage);
|
||||
if (strcmpW(action,szFileCost)==0)
|
||||
return ACTION_FileCost(hPackage);
|
||||
if (strcmpW(action,szCostFinalize)==0)
|
||||
return ACTION_CostFinalize(hPackage);
|
||||
if (strcmpW(action,szInstallValidate)==0)
|
||||
return ACTION_InstallValidate(hPackage);
|
||||
|
||||
/* install block */
|
||||
if (strcmpW(action,szInstallInitialize)==0)
|
||||
return ACTION_InstallInitialize(hPackage);
|
||||
if (strcmpW(action,szCreateFolders)==0)
|
||||
return ACTION_CreateFolders(hPackage);
|
||||
if (strcmpW(action,szInstallFiles)==0)
|
||||
|
@ -593,6 +637,7 @@ UINT ACTION_PerformAction(MSIHANDLE hPackage, const WCHAR *action)
|
|||
return ACTION_DuplicateFiles(hPackage);
|
||||
if (strcmpW(action,szWriteRegistryValues)==0)
|
||||
return ACTION_WriteRegistryValues(hPackage);
|
||||
|
||||
/*
|
||||
Current called during itunes but unimplemented
|
||||
|
||||
|
@ -602,14 +647,11 @@ UINT ACTION_PerformAction(MSIHANDLE hPackage, const WCHAR *action)
|
|||
CostInitialize
|
||||
MigrateFeatureStates
|
||||
ResolveSource (sets SourceDir)
|
||||
FileCost
|
||||
ValidateProductID (sets ProductID)
|
||||
IsolateComponents (Empty)
|
||||
SetODBCFolders
|
||||
MigrateFeatureStates
|
||||
InstallValidate
|
||||
RemoveExistingProducts
|
||||
InstallInitialize
|
||||
AllocateRegistrySpace
|
||||
ProcessComponents
|
||||
UnpublishComponents
|
||||
|
@ -1092,6 +1134,7 @@ static int load_component(MSIPACKAGE* package, MSIHANDLE row)
|
|||
|
||||
package->components[index].State = INSTALLSTATE_UNKNOWN;
|
||||
package->components[index].Enabled = TRUE;
|
||||
package->components[index].FeatureState= FALSE;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
@ -1518,19 +1561,6 @@ static UINT resolve_folder(MSIHANDLE hPackage, LPCWSTR name, LPWSTR path,
|
|||
|
||||
TRACE("Working to resolve %s\n",debugstr_w(name));
|
||||
|
||||
for (i = 0; i < package->loaded_folders; i++)
|
||||
{
|
||||
if (strcmpW(package->folders[i].Directory,name)==0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= package->loaded_folders)
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
|
||||
|
||||
if (folder)
|
||||
*folder = &(package->folders[i]);
|
||||
|
||||
if (!path)
|
||||
return rc;
|
||||
|
||||
|
@ -1548,6 +1578,8 @@ static UINT resolve_folder(MSIHANDLE hPackage, LPCWSTR name, LPWSTR path,
|
|||
if (set_prop)
|
||||
MsiSetPropertyW(hPackage,cszTargetDir,path);
|
||||
}
|
||||
if (folder)
|
||||
*folder = &(package->folders[0]);
|
||||
return rc;
|
||||
}
|
||||
else
|
||||
|
@ -1568,10 +1600,24 @@ static UINT resolve_folder(MSIHANDLE hPackage, LPCWSTR name, LPWSTR path,
|
|||
}
|
||||
}
|
||||
}
|
||||
if (folder)
|
||||
*folder = &(package->folders[0]);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < package->loaded_folders; i++)
|
||||
{
|
||||
if (strcmpW(package->folders[i].Directory,name)==0)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= package->loaded_folders)
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
|
||||
if (folder)
|
||||
*folder = &(package->folders[i]);
|
||||
|
||||
if (!source && package->folders[i].ResolvedTarget[0])
|
||||
{
|
||||
strcpyW(path,package->folders[i].ResolvedTarget);
|
||||
|
@ -1624,11 +1670,11 @@ static UINT resolve_folder(MSIHANDLE hPackage, LPCWSTR name, LPWSTR path,
|
|||
* The costing needs to be implemented at some point but for now I am going
|
||||
* to focus on the directory building
|
||||
*
|
||||
*
|
||||
*/
|
||||
static UINT ACTION_CostFinalize(MSIHANDLE hPackage)
|
||||
{
|
||||
static const CHAR *ExecSeqQuery = "select * from Directory";
|
||||
static const CHAR *ConditionQuery = "select * from Condition";
|
||||
UINT rc;
|
||||
MSIHANDLE view;
|
||||
MSIPACKAGE *package;
|
||||
|
@ -1637,6 +1683,7 @@ static UINT ACTION_CostFinalize(MSIHANDLE hPackage)
|
|||
TRACE("Building Directory properties\n");
|
||||
|
||||
package = msihandle2msiinfo(hPackage, MSIHANDLETYPE_PACKAGE);
|
||||
|
||||
rc = MsiDatabaseOpenViewA(package->db, ExecSeqQuery, &view);
|
||||
|
||||
if (rc != ERROR_SUCCESS)
|
||||
|
@ -1742,8 +1789,77 @@ static UINT ACTION_CostFinalize(MSIHANDLE hPackage)
|
|||
}
|
||||
}
|
||||
|
||||
MsiSetPropertyA(hPackage,"CostingComplete","1");
|
||||
TRACE("Evaluating Condition Table\n");
|
||||
|
||||
rc = MsiDatabaseOpenViewA(package->db, ConditionQuery, &view);
|
||||
|
||||
if (rc != ERROR_SUCCESS)
|
||||
return rc;
|
||||
|
||||
rc = MsiViewExecute(view, 0);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
MsiViewClose(view);
|
||||
MsiCloseHandle(view);
|
||||
return rc;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
WCHAR Feature[0x100];
|
||||
WCHAR Condition[0x100];
|
||||
MSIHANDLE row = 0;
|
||||
DWORD sz;
|
||||
int feature_index;
|
||||
|
||||
rc = MsiViewFetch(view,&row);
|
||||
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
rc = ERROR_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
sz = 0x100;
|
||||
MsiRecordGetStringW(row,1,Feature,&sz);
|
||||
sz = 0x100;
|
||||
MsiRecordGetStringW(row,3,Condition,&sz);
|
||||
|
||||
feature_index = get_loaded_feature(package,Feature);
|
||||
if (feature_index < 0)
|
||||
ERR("FAILED to find loaded feature %s\n",debugstr_w(Feature));
|
||||
else
|
||||
{
|
||||
if (MsiEvaluateConditionW(hPackage,Condition) == MSICONDITION_TRUE)
|
||||
{
|
||||
int level = MsiRecordGetInteger(row,2);
|
||||
TRACE("Reseting feature %s to level %i\n",debugstr_w(Feature),
|
||||
level);
|
||||
package->features[feature_index].Level = level;
|
||||
}
|
||||
}
|
||||
|
||||
MsiCloseHandle(row);
|
||||
}
|
||||
MsiViewClose(view);
|
||||
MsiCloseHandle(view);
|
||||
|
||||
TRACE("Enabling or Disabling Components\n");
|
||||
for (i = 0; i < package->loaded_components; i++)
|
||||
{
|
||||
if (package->components[i].Condition[0])
|
||||
{
|
||||
if (MsiEvaluateConditionW(hPackage,
|
||||
package->components[i].Condition) == MSICONDITION_FALSE)
|
||||
{
|
||||
TRACE("Disabling component %s\n",
|
||||
debugstr_w(package->components[i].Component));
|
||||
package->components[i].Enabled = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MsiSetPropertyA(hPackage,"CostingComplete","1");
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2003,14 +2119,6 @@ static UINT ACTION_InstallFiles(MSIHANDLE hPackage)
|
|||
INT index;
|
||||
MSIPACKAGE *package;
|
||||
|
||||
/* REALLY what we want to do is go through all the enabled
|
||||
* features and check all the components of that feature and
|
||||
* make sure that component is not already install and blah
|
||||
* blah blah... I will do it that way some day.. really
|
||||
* but for sheer gratification I am going to just brute force
|
||||
* install all the files
|
||||
*/
|
||||
|
||||
package = msihandle2msiinfo(hPackage, MSIHANDLETYPE_PACKAGE);
|
||||
|
||||
if (!package)
|
||||
|
@ -2023,6 +2131,17 @@ static UINT ACTION_InstallFiles(MSIHANDLE hPackage)
|
|||
|
||||
file = &package->files[index];
|
||||
|
||||
if (file->Temporary)
|
||||
continue;
|
||||
|
||||
if (!package->components[file->ComponentIndex].Enabled ||
|
||||
!package->components[file->ComponentIndex].FeatureState)
|
||||
{
|
||||
TRACE("File %s is not scheduled for install\n",
|
||||
debugstr_w(file->File));
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((file->State == 1) || (file->State == 2))
|
||||
{
|
||||
TRACE("Installing %s\n",debugstr_w(file->File));
|
||||
|
@ -2048,6 +2167,7 @@ static UINT ACTION_InstallFiles(MSIHANDLE hPackage)
|
|||
TRACE("file paths %s to %s\n",debugstr_w(file->SourcePath),
|
||||
debugstr_w(file->TargetPath));
|
||||
|
||||
progress_message(hPackage,2,1,0,0);
|
||||
rc = !MoveFileW(file->SourcePath,file->TargetPath);
|
||||
if (rc)
|
||||
ERR("Unable to move file\n");
|
||||
|
@ -2066,7 +2186,6 @@ inline static UINT get_file_target(MSIHANDLE hPackage, LPCWSTR file_key,
|
|||
INT index;
|
||||
|
||||
package = msihandle2msiinfo(hPackage, MSIHANDLETYPE_PACKAGE);
|
||||
|
||||
if (!package)
|
||||
return ERROR_INVALID_HANDLE;
|
||||
|
||||
|
@ -2074,8 +2193,13 @@ inline static UINT get_file_target(MSIHANDLE hPackage, LPCWSTR file_key,
|
|||
{
|
||||
if (strcmpW(file_key,package->files[index].File)==0)
|
||||
{
|
||||
strcmpW(file_source,package->files[index].TargetPath);
|
||||
return ERROR_SUCCESS;
|
||||
if (package->files[index].State >= 3)
|
||||
{
|
||||
strcmpW(file_source,package->files[index].TargetPath);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
else
|
||||
return ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2088,16 +2212,13 @@ static UINT ACTION_DuplicateFiles(MSIHANDLE hPackage)
|
|||
MSIHANDLE view;
|
||||
MSIHANDLE row = 0;
|
||||
static const CHAR *ExecSeqQuery = "select * from DuplicateFile";
|
||||
MSIHANDLE db;
|
||||
MSIPACKAGE* package;
|
||||
|
||||
package = msihandle2msiinfo(hPackage, MSIHANDLETYPE_PACKAGE);
|
||||
if (!package)
|
||||
return ERROR_INVALID_HANDLE;
|
||||
|
||||
/*
|
||||
* Yes we should only do this for components that are installed
|
||||
* but again I need to do that went I track components.
|
||||
*/
|
||||
db = MsiGetActiveDatabase(hPackage);
|
||||
rc = MsiDatabaseOpenViewA(db, ExecSeqQuery, &view);
|
||||
MsiCloseHandle(db);
|
||||
rc = MsiDatabaseOpenViewA(package->db, ExecSeqQuery, &view);
|
||||
|
||||
if (rc != ERROR_SUCCESS)
|
||||
return rc;
|
||||
|
@ -2116,6 +2237,8 @@ static UINT ACTION_DuplicateFiles(MSIHANDLE hPackage)
|
|||
WCHAR file_source[MAX_PATH];
|
||||
WCHAR dest_name[0x100];
|
||||
WCHAR dest_path[MAX_PATH];
|
||||
WCHAR component[0x100];
|
||||
INT component_index;
|
||||
|
||||
DWORD sz=0x100;
|
||||
|
||||
|
@ -2126,6 +2249,24 @@ static UINT ACTION_DuplicateFiles(MSIHANDLE hPackage)
|
|||
break;
|
||||
}
|
||||
|
||||
sz=0x100;
|
||||
rc = MsiRecordGetStringW(row,2,component,&sz);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
ERR("Unable to get component\n");
|
||||
MsiCloseHandle(row);
|
||||
break;
|
||||
}
|
||||
|
||||
component_index = get_loaded_component(package,component);
|
||||
if (!package->components[component_index].Enabled ||
|
||||
!package->components[component_index].FeatureState)
|
||||
{
|
||||
TRACE("Skipping copy due to disabled component\n");
|
||||
MsiCloseHandle(row);
|
||||
continue;
|
||||
}
|
||||
|
||||
sz=0x100;
|
||||
rc = MsiRecordGetStringW(row,3,file_key,&sz);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
|
@ -2283,14 +2424,13 @@ static UINT ACTION_WriteRegistryValues(MSIHANDLE hPackage)
|
|||
MSIHANDLE view;
|
||||
MSIHANDLE row = 0;
|
||||
static const CHAR *ExecSeqQuery = "select * from Registry";
|
||||
MSIHANDLE db;
|
||||
MSIPACKAGE *package;
|
||||
|
||||
/* Again here we want to key off of the components being installed...
|
||||
* oh well
|
||||
*/
|
||||
db = MsiGetActiveDatabase(hPackage);
|
||||
rc = MsiDatabaseOpenViewA(db, ExecSeqQuery, &view);
|
||||
MsiCloseHandle(db);
|
||||
package = msihandle2msiinfo(hPackage, MSIHANDLETYPE_PACKAGE);
|
||||
if (!package)
|
||||
return ERROR_INVALID_HANDLE;
|
||||
|
||||
rc = MsiDatabaseOpenViewA(package->db, ExecSeqQuery, &view);
|
||||
|
||||
if (rc != ERROR_SUCCESS)
|
||||
return rc;
|
||||
|
@ -2311,6 +2451,8 @@ static UINT ACTION_WriteRegistryValues(MSIHANDLE hPackage)
|
|||
LPSTR value_data = NULL;
|
||||
HKEY root_key, hkey;
|
||||
DWORD type,size;
|
||||
WCHAR component[0x100];
|
||||
INT component_index;
|
||||
|
||||
INT root;
|
||||
DWORD sz=0x100;
|
||||
|
@ -2322,6 +2464,18 @@ static UINT ACTION_WriteRegistryValues(MSIHANDLE hPackage)
|
|||
break;
|
||||
}
|
||||
|
||||
sz= 0x100;
|
||||
MsiRecordGetStringW(row,6,component,&sz);
|
||||
component_index = get_loaded_component(package,component);
|
||||
|
||||
if (!package->components[component_index].Enabled ||
|
||||
!package->components[component_index].FeatureState)
|
||||
{
|
||||
TRACE("Skipping write due to disabled component\n");
|
||||
MsiCloseHandle(row);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* null values have special meanings during uninstalls and such */
|
||||
|
||||
if(MsiRecordIsNull(row,5))
|
||||
|
@ -2380,6 +2534,7 @@ static UINT ACTION_WriteRegistryValues(MSIHANDLE hPackage)
|
|||
RegSetValueExW(hkey, name, 0, type, value_data, size);
|
||||
HeapFree(GetProcessHeap(),0,value_data);
|
||||
}
|
||||
progress_message(hPackage,2,1,0,0);
|
||||
|
||||
MsiCloseHandle(row);
|
||||
}
|
||||
|
@ -2468,6 +2623,123 @@ static DWORD deformat_string(MSIHANDLE hPackage, WCHAR* ptr,WCHAR** data)
|
|||
return size;
|
||||
}
|
||||
|
||||
static UINT ACTION_InstallInitialize(MSIHANDLE hPackage)
|
||||
{
|
||||
CHAR level[10000];
|
||||
INT install_level;
|
||||
DWORD sz;
|
||||
MSIPACKAGE *package;
|
||||
INT i,j;
|
||||
/* I do not know if this is where it should happen.. but */
|
||||
|
||||
TRACE("Checking Install Level\n");
|
||||
FIXME("The Attributes of the feature OVERRIDE THIS... unimplemented\n");
|
||||
FIXME("As does the ALLLOCAL and such propertys\n");
|
||||
|
||||
sz = 10000;
|
||||
if (MsiGetPropertyA(hPackage,"INSTALLLEVEL",level,&sz)==ERROR_SUCCESS)
|
||||
install_level = atoi(level);
|
||||
else
|
||||
install_level = 1;
|
||||
|
||||
package = msihandle2msiinfo(hPackage, MSIHANDLETYPE_PACKAGE);
|
||||
if (!package)
|
||||
return ERROR_INVALID_HANDLE;
|
||||
|
||||
/*
|
||||
* components FeatureState defaults to FALSE. the idea is we want to
|
||||
* enable the component is ANY feature that uses it is enabled to install
|
||||
*/
|
||||
for(i = 0; i < package->loaded_features; i++)
|
||||
{
|
||||
BOOL feature_state= ((package->features[i].Level > 0) &&
|
||||
(package->features[i].Level <= install_level));
|
||||
TRACE("Feature %s has a state of %i\n",
|
||||
debugstr_w(package->features[i].Feature), feature_state);
|
||||
for( j = 0; j < package->features[i].ComponentCount; j++)
|
||||
{
|
||||
package->components[package->features[i].Components[j]].FeatureState
|
||||
|= feature_state;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* so basically we ONLY want to install a component if its Enabled AND
|
||||
* FeatureState are both TRUE
|
||||
*/
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static UINT ACTION_InstallValidate(MSIHANDLE hPackage)
|
||||
{
|
||||
DWORD progress = 0;
|
||||
static const CHAR q1[]="SELECT * FROM Registry";
|
||||
static const CHAR q2[]=
|
||||
"select Action from InstallExecuteSequence where Sequence > 0 order by Sequence";
|
||||
UINT rc;
|
||||
MSIHANDLE view;
|
||||
MSIHANDLE row = 0;
|
||||
MSIHANDLE db;
|
||||
BOOL flipit= FALSE;
|
||||
MSIPACKAGE* package;
|
||||
|
||||
TRACE(" InstallValidate \n");
|
||||
|
||||
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 = MsiViewExecute(view, 0);
|
||||
while (1)
|
||||
{
|
||||
rc = MsiViewFetch(view,&row);
|
||||
if (rc != ERROR_SUCCESS)
|
||||
{
|
||||
rc = ERROR_SUCCESS;
|
||||
break;
|
||||
}
|
||||
progress +=1;
|
||||
|
||||
MsiCloseHandle(row);
|
||||
}
|
||||
MsiViewClose(view);
|
||||
MsiCloseHandle(view);
|
||||
MsiCloseHandle(db);
|
||||
|
||||
package = msihandle2msiinfo(hPackage, MSIHANDLETYPE_PACKAGE);
|
||||
progress_message(hPackage,0,progress+package->loaded_files,0,0);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Msi functions that seem approperate here */
|
||||
UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )
|
||||
{
|
||||
|
|
|
@ -145,6 +145,9 @@ http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/prope
|
|||
static VOID set_installer_properties(MSIHANDLE hPackage)
|
||||
{
|
||||
WCHAR pth[MAX_PATH];
|
||||
OSVERSIONINFOA OSVersion;
|
||||
DWORD verval;
|
||||
CHAR verstr[10];
|
||||
|
||||
static const WCHAR cszbs[]={'\\',0};
|
||||
static const WCHAR CFF[] =
|
||||
|
@ -204,12 +207,6 @@ VirtualMemory
|
|||
PhysicalMemory
|
||||
Intel
|
||||
ShellAdvSupport
|
||||
ServicePackLevel
|
||||
WindowsBuild
|
||||
Version9x
|
||||
Version95
|
||||
VersionNT
|
||||
AdminUser
|
||||
DefaultUIFont
|
||||
VersionMsi
|
||||
VersionDatabase
|
||||
|
@ -268,6 +265,29 @@ Privilaged
|
|||
|
||||
GetTempPathW(MAX_PATH,pth);
|
||||
MsiSetPropertyW(hPackage, TF, pth);
|
||||
|
||||
/* in a wine enviroment the user is always admin and privlaged */
|
||||
MsiSetPropertyA(hPackage,"AdminUser","1");
|
||||
MsiSetPropertyA(hPackage,"Privileged","1");
|
||||
|
||||
/* set the os things */
|
||||
OSVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
|
||||
GetVersionExA(&OSVersion);
|
||||
verval = OSVersion.dwMinorVersion+OSVersion.dwMajorVersion*100;
|
||||
sprintf(verstr,"%li",verval);
|
||||
switch (OSVersion.dwPlatformId)
|
||||
{
|
||||
case VER_PLATFORM_WIN32_WINDOWS:
|
||||
MsiSetPropertyA(hPackage,"Version9X",verstr);
|
||||
break;
|
||||
case VER_PLATFORM_WIN32_NT:
|
||||
MsiSetPropertyA(hPackage,"VersionNT",verstr);
|
||||
break;
|
||||
}
|
||||
sprintf(verstr,"%li",OSVersion.dwBuildNumber);
|
||||
MsiSetPropertyA(hPackage,"WindowsBuild",verstr);
|
||||
/* just fudge this */
|
||||
MsiSetPropertyA(hPackage,"ServicePackLevel","6");
|
||||
}
|
||||
|
||||
|
||||
|
@ -377,6 +397,9 @@ INT WINAPI MsiProcessMessage( MSIHANDLE hInstall, INSTALLMESSAGE eMessageType,
|
|||
log_type |= INSTALLLOGMODE_ACTIONSTART;
|
||||
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_ACTIONDATA)
|
||||
log_type |= INSTALLLOGMODE_ACTIONDATA;
|
||||
/* just a guess */
|
||||
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_PROGRESS)
|
||||
log_type |= 0x800;
|
||||
|
||||
message = HeapAlloc(GetProcessHeap(),0,1);
|
||||
message[0]=0;
|
||||
|
@ -396,7 +419,7 @@ INT WINAPI MsiProcessMessage( MSIHANDLE hInstall, INSTALLMESSAGE eMessageType,
|
|||
|
||||
if (msg_field > 1)
|
||||
{
|
||||
sprintf(number,"%i: ",i);
|
||||
sprintf(number," %i: ",i);
|
||||
strcat(message,number);
|
||||
}
|
||||
strcat(message,tmp);
|
||||
|
|
Loading…
Reference in New Issue