Activate features and components based on their various conditions.

This commit is contained in:
Aric Stewart 2004-07-04 00:36:58 +00:00 committed by Alexandre Julliard
parent ec688fb4e0
commit 7d3e5973fe
2 changed files with 346 additions and 51 deletions

View File

@ -76,6 +76,7 @@ typedef struct tagMSICOMPONENT
WCHAR KeyPath[96]; WCHAR KeyPath[96];
INSTALLSTATE State; INSTALLSTATE State;
BOOL FeatureState;
BOOL Enabled; BOOL Enabled;
INT Cost; INT Cost;
}MSICOMPONENT; }MSICOMPONENT;
@ -136,6 +137,8 @@ static UINT ACTION_InstallFiles(MSIHANDLE hPackage);
static UINT ACTION_DuplicateFiles(MSIHANDLE hPackage); static UINT ACTION_DuplicateFiles(MSIHANDLE hPackage);
static UINT ACTION_WriteRegistryValues(MSIHANDLE hPackage); static UINT ACTION_WriteRegistryValues(MSIHANDLE hPackage);
static UINT ACTION_CustomAction(MSIHANDLE hPackage,const WCHAR *action); 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, static UINT HANDLE_CustomType1(MSIHANDLE hPackage, const LPWSTR source,
const LPWSTR target, const INT type); const LPWSTR target, const INT type);
@ -205,6 +208,22 @@ inline static int get_loaded_component(MSIPACKAGE* package, LPCWSTR Component )
return rc; 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) static UINT track_tempfile(MSIHANDLE hPackage, LPCWSTR name, LPCWSTR path)
{ {
MSIPACKAGE *package; 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 * 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}; {'C','o','s','t','I','n','i','t','i','a','l','i','z','e',0};
const static WCHAR szFileCost[] = const static WCHAR szFileCost[] =
{'F','i','l','e','C','o','s','t',0}; {'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)); 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) if (strcmpW(action,szCostInitialize)==0)
return ACTION_CostInitialize(hPackage); return ACTION_CostInitialize(hPackage);
if (strcmpW(action,szFileCost)==0) if (strcmpW(action,szFileCost)==0)
return ACTION_FileCost(hPackage); return ACTION_FileCost(hPackage);
if (strcmpW(action,szCostFinalize)==0) if (strcmpW(action,szCostFinalize)==0)
return ACTION_CostFinalize(hPackage); 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) if (strcmpW(action,szCreateFolders)==0)
return ACTION_CreateFolders(hPackage); return ACTION_CreateFolders(hPackage);
if (strcmpW(action,szInstallFiles)==0) if (strcmpW(action,szInstallFiles)==0)
@ -593,6 +637,7 @@ UINT ACTION_PerformAction(MSIHANDLE hPackage, const WCHAR *action)
return ACTION_DuplicateFiles(hPackage); return ACTION_DuplicateFiles(hPackage);
if (strcmpW(action,szWriteRegistryValues)==0) if (strcmpW(action,szWriteRegistryValues)==0)
return ACTION_WriteRegistryValues(hPackage); return ACTION_WriteRegistryValues(hPackage);
/* /*
Current called during itunes but unimplemented Current called during itunes but unimplemented
@ -602,14 +647,11 @@ UINT ACTION_PerformAction(MSIHANDLE hPackage, const WCHAR *action)
CostInitialize CostInitialize
MigrateFeatureStates MigrateFeatureStates
ResolveSource (sets SourceDir) ResolveSource (sets SourceDir)
FileCost
ValidateProductID (sets ProductID) ValidateProductID (sets ProductID)
IsolateComponents (Empty) IsolateComponents (Empty)
SetODBCFolders SetODBCFolders
MigrateFeatureStates MigrateFeatureStates
InstallValidate
RemoveExistingProducts RemoveExistingProducts
InstallInitialize
AllocateRegistrySpace AllocateRegistrySpace
ProcessComponents ProcessComponents
UnpublishComponents UnpublishComponents
@ -1092,6 +1134,7 @@ static int load_component(MSIPACKAGE* package, MSIHANDLE row)
package->components[index].State = INSTALLSTATE_UNKNOWN; package->components[index].State = INSTALLSTATE_UNKNOWN;
package->components[index].Enabled = TRUE; package->components[index].Enabled = TRUE;
package->components[index].FeatureState= FALSE;
return index; 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)); 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) if (!path)
return rc; return rc;
@ -1548,6 +1578,8 @@ static UINT resolve_folder(MSIHANDLE hPackage, LPCWSTR name, LPWSTR path,
if (set_prop) if (set_prop)
MsiSetPropertyW(hPackage,cszTargetDir,path); MsiSetPropertyW(hPackage,cszTargetDir,path);
} }
if (folder)
*folder = &(package->folders[0]);
return rc; return rc;
} }
else else
@ -1568,10 +1600,24 @@ static UINT resolve_folder(MSIHANDLE hPackage, LPCWSTR name, LPWSTR path,
} }
} }
} }
if (folder)
*folder = &(package->folders[0]);
return rc; 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]) if (!source && package->folders[i].ResolvedTarget[0])
{ {
strcpyW(path,package->folders[i].ResolvedTarget); 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 * The costing needs to be implemented at some point but for now I am going
* to focus on the directory building * to focus on the directory building
* *
*
*/ */
static UINT ACTION_CostFinalize(MSIHANDLE hPackage) static UINT ACTION_CostFinalize(MSIHANDLE hPackage)
{ {
static const CHAR *ExecSeqQuery = "select * from Directory"; static const CHAR *ExecSeqQuery = "select * from Directory";
static const CHAR *ConditionQuery = "select * from Condition";
UINT rc; UINT rc;
MSIHANDLE view; MSIHANDLE view;
MSIPACKAGE *package; MSIPACKAGE *package;
@ -1637,6 +1683,7 @@ static UINT ACTION_CostFinalize(MSIHANDLE hPackage)
TRACE("Building Directory properties\n"); TRACE("Building Directory properties\n");
package = msihandle2msiinfo(hPackage, MSIHANDLETYPE_PACKAGE); package = msihandle2msiinfo(hPackage, MSIHANDLETYPE_PACKAGE);
rc = MsiDatabaseOpenViewA(package->db, ExecSeqQuery, &view); rc = MsiDatabaseOpenViewA(package->db, ExecSeqQuery, &view);
if (rc != ERROR_SUCCESS) 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; return ERROR_SUCCESS;
} }
@ -2003,14 +2119,6 @@ static UINT ACTION_InstallFiles(MSIHANDLE hPackage)
INT index; INT index;
MSIPACKAGE *package; 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); package = msihandle2msiinfo(hPackage, MSIHANDLETYPE_PACKAGE);
if (!package) if (!package)
@ -2023,6 +2131,17 @@ static UINT ACTION_InstallFiles(MSIHANDLE hPackage)
file = &package->files[index]; 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)) if ((file->State == 1) || (file->State == 2))
{ {
TRACE("Installing %s\n",debugstr_w(file->File)); 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), 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);
rc = !MoveFileW(file->SourcePath,file->TargetPath); rc = !MoveFileW(file->SourcePath,file->TargetPath);
if (rc) if (rc)
ERR("Unable to move file\n"); ERR("Unable to move file\n");
@ -2066,7 +2186,6 @@ inline static UINT get_file_target(MSIHANDLE hPackage, LPCWSTR file_key,
INT index; INT index;
package = msihandle2msiinfo(hPackage, MSIHANDLETYPE_PACKAGE); package = msihandle2msiinfo(hPackage, MSIHANDLETYPE_PACKAGE);
if (!package) if (!package)
return ERROR_INVALID_HANDLE; 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) if (strcmpW(file_key,package->files[index].File)==0)
{ {
strcmpW(file_source,package->files[index].TargetPath); if (package->files[index].State >= 3)
return ERROR_SUCCESS; {
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 view;
MSIHANDLE row = 0; MSIHANDLE row = 0;
static const CHAR *ExecSeqQuery = "select * from DuplicateFile"; static const CHAR *ExecSeqQuery = "select * from DuplicateFile";
MSIHANDLE db; MSIPACKAGE* package;
package = msihandle2msiinfo(hPackage, MSIHANDLETYPE_PACKAGE);
if (!package)
return ERROR_INVALID_HANDLE;
/* rc = MsiDatabaseOpenViewA(package->db, ExecSeqQuery, &view);
* 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);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
return rc; return rc;
@ -2116,6 +2237,8 @@ static UINT ACTION_DuplicateFiles(MSIHANDLE hPackage)
WCHAR file_source[MAX_PATH]; WCHAR file_source[MAX_PATH];
WCHAR dest_name[0x100]; WCHAR dest_name[0x100];
WCHAR dest_path[MAX_PATH]; WCHAR dest_path[MAX_PATH];
WCHAR component[0x100];
INT component_index;
DWORD sz=0x100; DWORD sz=0x100;
@ -2126,6 +2249,24 @@ static UINT ACTION_DuplicateFiles(MSIHANDLE hPackage)
break; 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; sz=0x100;
rc = MsiRecordGetStringW(row,3,file_key,&sz); rc = MsiRecordGetStringW(row,3,file_key,&sz);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
@ -2283,14 +2424,13 @@ static UINT ACTION_WriteRegistryValues(MSIHANDLE hPackage)
MSIHANDLE view; MSIHANDLE view;
MSIHANDLE row = 0; MSIHANDLE row = 0;
static const CHAR *ExecSeqQuery = "select * from Registry"; static const CHAR *ExecSeqQuery = "select * from Registry";
MSIHANDLE db; MSIPACKAGE *package;
/* Again here we want to key off of the components being installed... package = msihandle2msiinfo(hPackage, MSIHANDLETYPE_PACKAGE);
* oh well if (!package)
*/ return ERROR_INVALID_HANDLE;
db = MsiGetActiveDatabase(hPackage);
rc = MsiDatabaseOpenViewA(db, ExecSeqQuery, &view); rc = MsiDatabaseOpenViewA(package->db, ExecSeqQuery, &view);
MsiCloseHandle(db);
if (rc != ERROR_SUCCESS) if (rc != ERROR_SUCCESS)
return rc; return rc;
@ -2311,6 +2451,8 @@ static UINT ACTION_WriteRegistryValues(MSIHANDLE hPackage)
LPSTR value_data = NULL; LPSTR value_data = NULL;
HKEY root_key, hkey; HKEY root_key, hkey;
DWORD type,size; DWORD type,size;
WCHAR component[0x100];
INT component_index;
INT root; INT root;
DWORD sz=0x100; DWORD sz=0x100;
@ -2322,6 +2464,18 @@ static UINT ACTION_WriteRegistryValues(MSIHANDLE hPackage)
break; 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 */ /* null values have special meanings during uninstalls and such */
if(MsiRecordIsNull(row,5)) if(MsiRecordIsNull(row,5))
@ -2380,6 +2534,7 @@ static UINT ACTION_WriteRegistryValues(MSIHANDLE hPackage)
RegSetValueExW(hkey, name, 0, type, value_data, size); RegSetValueExW(hkey, name, 0, type, value_data, size);
HeapFree(GetProcessHeap(),0,value_data); HeapFree(GetProcessHeap(),0,value_data);
} }
progress_message(hPackage,2,1,0,0);
MsiCloseHandle(row); MsiCloseHandle(row);
} }
@ -2468,6 +2623,123 @@ static DWORD deformat_string(MSIHANDLE hPackage, WCHAR* ptr,WCHAR** data)
return size; 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 */ /* Msi functions that seem approperate here */
UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction ) UINT WINAPI MsiDoActionA( MSIHANDLE hInstall, LPCSTR szAction )
{ {

View File

@ -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) static VOID set_installer_properties(MSIHANDLE hPackage)
{ {
WCHAR pth[MAX_PATH]; WCHAR pth[MAX_PATH];
OSVERSIONINFOA OSVersion;
DWORD verval;
CHAR verstr[10];
static const WCHAR cszbs[]={'\\',0}; static const WCHAR cszbs[]={'\\',0};
static const WCHAR CFF[] = static const WCHAR CFF[] =
@ -204,12 +207,6 @@ VirtualMemory
PhysicalMemory PhysicalMemory
Intel Intel
ShellAdvSupport ShellAdvSupport
ServicePackLevel
WindowsBuild
Version9x
Version95
VersionNT
AdminUser
DefaultUIFont DefaultUIFont
VersionMsi VersionMsi
VersionDatabase VersionDatabase
@ -268,6 +265,29 @@ Privilaged
GetTempPathW(MAX_PATH,pth); GetTempPathW(MAX_PATH,pth);
MsiSetPropertyW(hPackage, TF, 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; log_type |= INSTALLLOGMODE_ACTIONSTART;
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_ACTIONDATA) if ((eMessageType & 0xff000000) == INSTALLMESSAGE_ACTIONDATA)
log_type |= INSTALLLOGMODE_ACTIONDATA; log_type |= INSTALLLOGMODE_ACTIONDATA;
/* just a guess */
if ((eMessageType & 0xff000000) == INSTALLMESSAGE_PROGRESS)
log_type |= 0x800;
message = HeapAlloc(GetProcessHeap(),0,1); message = HeapAlloc(GetProcessHeap(),0,1);
message[0]=0; message[0]=0;
@ -396,7 +419,7 @@ 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);