--- trunk/reactos/lib/msi/action.c 2005-05-26 21:15:58 UTC (rev 15536)
+++ trunk/reactos/lib/msi/action.c 2005-05-26 21:55:34 UTC (rev 15537)
@@ -99,6 +99,7 @@
static UINT ACTION_ResolveSource(MSIPACKAGE *package);
static UINT ACTION_ExecuteAction(MSIPACKAGE *package);
static UINT ACTION_RegisterFonts(MSIPACKAGE *package);
+static UINT ACTION_PublishComponents(MSIPACKAGE *package);
/*
@@ -324,7 +325,7 @@
{ szInstallServices, NULL},
{ szPatchFiles, NULL},
{ szProcessComponents, ACTION_ProcessComponents },
- { szPublishComponents, NULL},
+ { szPublishComponents, ACTION_PublishComponents },
{ szPublishFeatures, ACTION_PublishFeatures },
{ szPublishProduct, ACTION_PublishProduct },
{ szRegisterClassInfo, ACTION_RegisterClassInfo },
@@ -380,6 +381,13 @@
memmove(filename, p+1, (strlenW(p+1)+1)*sizeof(WCHAR));
}
+inline static void reduce_to_shortfilename(WCHAR* filename)
+{
+ LPWSTR p = strchrW(filename,'|');
+ if (p)
+ *p = 0;
+}
+
WCHAR *load_dynamic_stringW(MSIRECORD *row, INT index)
{
UINT rc;
@@ -598,6 +606,7 @@
{
HeapFree(GetProcessHeap(),0,package->files[i].File);
HeapFree(GetProcessHeap(),0,package->files[i].FileName);
+ HeapFree(GetProcessHeap(),0,package->files[i].ShortName);
HeapFree(GetProcessHeap(),0,package->files[i].Version);
HeapFree(GetProcessHeap(),0,package->files[i].Language);
HeapFree(GetProcessHeap(),0,package->files[i].SourcePath);
@@ -630,15 +639,16 @@
MSI_ProcessMessage(package, INSTALLMESSAGE_PROGRESS, row);
msiobj_release(&row->hdr);
- msi_dialog_check_messages(package->dialog, NULL);
+ msi_dialog_check_messages(NULL);
}
static void ui_actiondata(MSIPACKAGE *package, LPCWSTR action, MSIRECORD * 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};
+ '`','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;
MSIQUERY * view;
@@ -655,12 +665,14 @@
if (rc != ERROR_SUCCESS)
{
MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
return;
}
rc = MSI_ViewFetch(view,&row);
if (rc != ERROR_SUCCESS)
{
MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
return;
}
@@ -705,8 +717,9 @@
{'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};
+ '`','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;
@@ -1005,14 +1018,14 @@
MSIRECORD * row = 0;
static const WCHAR ExecSeqQuery[] =
{'S','E','L','E','C','T',' ','*',' ','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',' ',
- 'S','e','q','u','e','n','c','e',' ', '=',' ','%','i',0};
+ '`','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',0};
static const WCHAR UISeqQuery[] =
{'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',
+ '`','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','`',
' ', '=',' ','%','i',0};
if (UI)
@@ -1090,18 +1103,19 @@
UINT rc;
static const WCHAR ExecSeqQuery[] =
{'S','E','L','E','C','T',' ','*',' ', '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',' ',
- 'S','e','q','u','e','n','c','e',' ', '>',' ','%','i',' ',
+ '`','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 };
+ '`','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};
+ {'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;
@@ -1225,10 +1239,12 @@
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',' ',
+ '`','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};
+ '`','S','e','q','u','e','n','c','e','`',0};
rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
@@ -1420,7 +1436,7 @@
if (!handled)
handled = ACTION_HandleDialogBox(package, action, &rc);
- msi_dialog_check_messages( package->dialog, NULL );
+ msi_dialog_check_messages( NULL );
if (!handled)
{
@@ -1493,9 +1509,10 @@
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','_',
+ {'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 };
+ '`','C','r','e','a','t','e','F','o','l','d','e','r','`',0 };
UINT rc;
MSIQUERY *view;
MSIFOLDER *folder;
@@ -1606,7 +1623,7 @@
sz = 96;
MSI_RecordGetStringW(row,6,package->components[index].KeyPath,&sz);
- package->components[index].Installed = INSTALLSTATE_UNKNOWN;
+ package->components[index].Installed = INSTALLSTATE_ABSENT;
package->components[index].Action = INSTALLSTATE_UNKNOWN;
package->components[index].ActionRequest = INSTALLSTATE_UNKNOWN;
@@ -1620,14 +1637,18 @@
int index = package->loaded_features;
DWORD sz;
static const WCHAR Query1[] =
- {'S','E','L','E','C','T',' ','C','o','m','p','o','n','e','n','t','_',
- ' ','F','R','O','M',' ','F','e','a','t','u','r','e',
- 'C','o','m','p','o','n','e','n','t','s',' ','W','H','E','R','E',' ',
- 'F','e', 'a','t','u','r','e','_','=','\'','%','s','\'',0};
+ {'S','E','L','E','C','T',' ',
+ '`','C','o','m','p','o','n','e','n','t','_','`',
+ ' ','F','R','O','M',' ','`','F','e','a','t','u','r','e',
+ 'C','o','m','p','o','n','e','n','t','s','`',' ',
+ 'W','H','E','R','E',' ',
+ '`','F','e', 'a','t','u','r','e','_','`',' ','=','\'','%','s','\'',0};
static const WCHAR Query2[] =
{'S','E','L','E','C','T',' ','*',' ','F','R', 'O','M',' ',
- 'C','o','m','p','o','n','e','n','t',' ','W','H','E','R','E',' ',
- 'C','o','m','p','o','n','e','n','t','=','\'','%','s','\'',0};
+ '`','C','o','m','p','o','n','e','n','t','`',' ',
+ 'W','H','E','R','E',' ',
+ '`','C','o','m','p','o','n','e','n','t','`',' ',
+ '=','\'','%','s','\'',0};
MSIQUERY * view;
MSIQUERY * view2;
MSIRECORD * row2;
@@ -1673,7 +1694,7 @@
package->features[index].Attributes= MSI_RecordGetInteger(row,8);
- package->features[index].Installed = INSTALLSTATE_UNKNOWN;
+ package->features[index].Installed = INSTALLSTATE_ABSENT;
package->features[index].Action = INSTALLSTATE_UNKNOWN;
package->features[index].ActionRequest = INSTALLSTATE_UNKNOWN;
@@ -1712,6 +1733,7 @@
c_indx);
package->features[index].Components[cnt] = c_indx;
package->features[index].ComponentCount ++;
+ msiobj_release( &row2->hdr );
continue;
}
@@ -1751,61 +1773,6 @@
msiobj_release(&view->hdr);
}
-/*
- * I am not doing any of the costing functionality yet.
- * Mostly looking at doing the Component and Feature loading
- *
- * The native MSI does A LOT of modification to tables here. Mostly adding
- * a lot of temporary columns to the Feature and Component tables.
- *
- * note: Native msi also tracks the short filename. But I am only going to
- * track the long ones. Also looking at this directory table
- * it appears that the directory table does not get the parents
- * resolved base on property only based on their entries in the
- * directory table.
- */
-static UINT ACTION_CostInitialize(MSIPACKAGE *package)
-{
- MSIQUERY * view;
- MSIRECORD * row;
- UINT rc;
- static const WCHAR Query_all[] =
- {'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
- 'F','e','a','t','u','r','e',0};
- static const WCHAR szCosting[] =
- {'C','o','s','t','i','n','g','C','o','m','p','l','e','t','e',0 };
- static const WCHAR szZero[] = { '0', 0 };
-
- MSI_SetPropertyW(package, szCosting, szZero);
- MSI_SetPropertyW(package, cszRootDrive , c_colon);
-
- rc = MSI_DatabaseOpenViewW(package->db,Query_all,&view);
- if (rc != ERROR_SUCCESS)
- return rc;
- rc = MSI_ViewExecute(view,0);
- if (rc != ERROR_SUCCESS)
- {
- MSI_ViewClose(view);
- msiobj_release(&view->hdr);
- return rc;
- }
- while (1)
- {
- DWORD rc;
-
- rc = MSI_ViewFetch(view,&row);
- if (rc != ERROR_SUCCESS)
- break;
-
- load_feature(package,row);
- msiobj_release(&row->hdr);
- }
- MSI_ViewClose(view);
- msiobj_release(&view->hdr);
-
- return ERROR_SUCCESS;
-}
-
static UINT load_file(MSIPACKAGE* package, MSIRECORD * row)
{
DWORD index = package->loaded_files;
@@ -1838,8 +1805,10 @@
HeapFree(GetProcessHeap(), 0, buffer);
package->files[index].FileName = load_dynamic_stringW(row,3);
+ reduce_to_longfilename(package->files[index].FileName);
- reduce_to_longfilename(package->files[index].FileName);
+ package->files[index].ShortName = load_dynamic_stringW(row,3);
+ reduce_to_shortfilename(package->files[index].ShortName);
package->files[index].FileSize = MSI_RecordGetInteger(row,4);
package->files[index].Version = load_dynamic_stringW(row, 5);
@@ -1855,15 +1824,15 @@
return ERROR_SUCCESS;
}
-static UINT ACTION_FileCost(MSIPACKAGE *package)
+static UINT load_all_files(MSIPACKAGE *package)
{
MSIQUERY * view;
MSIRECORD * row;
UINT rc;
static const WCHAR Query[] =
{'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
- 'F','i','l','e',' ', 'O','R','D','E','R',' ','B','Y',' ',
- 'S','e','q','u','e','n','c','e', 0};
+ '`','F','i','l','e','`',' ', 'O','R','D','E','R',' ','B','Y',' ',
+ '`','S','e','q','u','e','n','c','e','`', 0};
if (!package)
return ERROR_INVALID_HANDLE;
@@ -1897,16 +1866,88 @@
return ERROR_SUCCESS;
}
+
+/*
+ * I am not doing any of the costing functionality yet.
+ * Mostly looking at doing the Component and Feature loading
+ *
+ * The native MSI does A LOT of modification to tables here. Mostly adding
+ * a lot of temporary columns to the Feature and Component tables.
+ *
+ * note: Native msi also tracks the short filename. But I am only going to
+ * track the long ones. Also looking at this directory table
+ * it appears that the directory table does not get the parents
+ * resolved base on property only based on their entries in the
+ * directory table.
+ */
+static UINT ACTION_CostInitialize(MSIPACKAGE *package)
+{
+ MSIQUERY * view;
+ MSIRECORD * row;
+ UINT rc;
+ static const WCHAR Query_all[] =
+ {'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
+ '`','F','e','a','t','u','r','e','`',0};
+ static const WCHAR szCosting[] =
+ {'C','o','s','t','i','n','g','C','o','m','p','l','e','t','e',0 };
+ static const WCHAR szZero[] = { '0', 0 };
+ WCHAR buffer[3];
+ DWORD sz = 3;
+
+ MSI_GetPropertyW(package, szCosting, buffer, &sz);
+ if (buffer[0]=='1')
+ return ERROR_SUCCESS;
+
+ MSI_SetPropertyW(package, szCosting, szZero);
+ MSI_SetPropertyW(package, cszRootDrive , c_colon);
+
+ rc = MSI_DatabaseOpenViewW(package->db,Query_all,&view);
+ if (rc != ERROR_SUCCESS)
+ return rc;
+ rc = MSI_ViewExecute(view,0);
+ if (rc != ERROR_SUCCESS)
+ {
+ MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
+ return rc;
+ }
+ while (1)
+ {
+ DWORD rc;
+
+ rc = MSI_ViewFetch(view,&row);
+ if (rc != ERROR_SUCCESS)
+ break;
+
+ load_feature(package,row);
+ msiobj_release(&row->hdr);
+ }
+ MSI_ViewClose(view);
+ msiobj_release(&view->hdr);
+
+ load_all_files(package);
+
+ return ERROR_SUCCESS;
+}
+
+static UINT ACTION_FileCost(MSIPACKAGE *package)
+{
+ return ERROR_SUCCESS;
+}
+
+
static INT load_folder(MSIPACKAGE *package, const WCHAR* dir)
{
static const WCHAR Query[] =
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- 'D','i','r','e','c', 't','o','r','y',' ','W','H','E','R','E',' ','`',
- 'D','i','r','e','c','t', 'o','r','y','`',' ','=',' ','`','%','s','`',
+ '`','D','i','r','e','c', 't','o','r','y','`',' ',
+ 'W','H','E','R','E',' ', '`', 'D','i','r','e','c','t', 'o','r','y','`',
+ ' ','=',' ','\'','%','s','\'',
0};
UINT rc;
MSIQUERY * view;
LPWSTR ptargetdir, targetdir, parent, srcdir;
+ LPWSTR shortname = NULL;
MSIRECORD * row = 0;
INT index = -1;
DWORD i;
@@ -1972,15 +2013,16 @@
/* for now only pick long filename versions */
if (strchrW(targetdir,'|'))
{
+ shortname = targetdir;
targetdir = strchrW(targetdir,'|');
*targetdir = 0;
targetdir ++;
}
+ /* for the sourcedir pick the short filename */
if (srcdir && strchrW(srcdir,'|'))
{
- srcdir= strchrW(srcdir,'|');
- *srcdir= 0;
- srcdir ++;
+ LPWSTR p = strchrW(srcdir,'|');
+ *p = 0;
}
/* now check for root dirs */
@@ -1999,9 +2041,12 @@
if (srcdir)
package->folders[index].SourceDefault = strdupW(srcdir);
+ else if (shortname)
+ package->folders[index].SourceDefault = strdupW(shortname);
else if (targetdir)
package->folders[index].SourceDefault = strdupW(targetdir);
HeapFree(GetProcessHeap(), 0, ptargetdir);
+ TRACE(" SourceDefault = %s\n",debugstr_w(package->folders[index].SourceDefault));
parent = load_dynamic_stringW(row,2);
if (parent)
@@ -2105,6 +2150,7 @@
else if (source && package->folders[i].ResolvedSource)
{
path = strdupW(package->folders[i].ResolvedSource);
+ TRACE(" (source)already resolved to %s\n",debugstr_w(path));
return path;
}
else if (!source && package->folders[i].Property)
@@ -2136,6 +2182,7 @@
else
{
path = build_directory_name(3, p, package->folders[i].SourceDefault, NULL);
+ TRACE(" (source)resolved into %s\n",debugstr_w(path));
package->folders[i].ResolvedSource = strdupW(path);
}
HeapFree(GetProcessHeap(),0,p);
@@ -2201,17 +2248,25 @@
{
MSICOMPONENT* component = &package->components[feature->Components[i]];
+ TRACE("MODIFYING(%i): Component %s (Installed %i, Action %i, Request %i)\n",
+ newstate, debugstr_w(component->Component), component->Installed,
+ component->Action, component->ActionRequest);
+
if (!component->Enabled)
continue;
else
{
if (newstate == INSTALLSTATE_LOCAL)
+ {
component->ActionRequest = INSTALLSTATE_LOCAL;
+ component->Action = INSTALLSTATE_LOCAL;
+ }
else
{
int j,k;
component->ActionRequest = newstate;
+ component->Action = newstate;
/*if any other feature wants is local we need to set it local*/
for (j = 0;
@@ -2225,12 +2280,19 @@
{
if (package->features[j].ActionRequest ==
INSTALLSTATE_LOCAL)
+ {
+ TRACE("Saved by %s\n", debugstr_w(package->features[j].Feature));
component->ActionRequest = INSTALLSTATE_LOCAL;
+ component->Action = INSTALLSTATE_LOCAL;
+ }
break;
}
}
}
}
+ TRACE("Result (%i): Component %s (Installed %i, Action %i, Request %i)\n",
+ newstate, debugstr_w(component->Component), component->Installed,
+ component->Action, component->ActionRequest);
}
}
@@ -2344,10 +2406,26 @@
BOOL feature_state = ((package->features[i].Level > 0) &&
(package->features[i].Level <= install_level));
- if (feature_state)
+ if ((feature_state) &&
+ (package->features[i].Action == INSTALLSTATE_UNKNOWN))
{
- package->features[i].ActionRequest = INSTALLSTATE_LOCAL;
- package->features[i].Action = INSTALLSTATE_LOCAL;
+ if (package->features[i].Attributes &
+ msidbFeatureAttributesFavorSource)
+ {
+ package->features[i].ActionRequest = INSTALLSTATE_SOURCE;
+ package->features[i].Action = INSTALLSTATE_SOURCE;
+ }
+ else if (package->features[i].Attributes &
+ msidbFeatureAttributesFavorAdvertise)
+ {
+ package->features[i].ActionRequest =INSTALLSTATE_ADVERTISED;
+ package->features[i].Action =INSTALLSTATE_ADVERTISED;
+ }
+ else
+ {
+ package->features[i].ActionRequest = INSTALLSTATE_LOCAL;
+ package->features[i].Action = INSTALLSTATE_LOCAL;
+ }
}
}
}
@@ -2380,6 +2458,27 @@
component->Action = INSTALLSTATE_LOCAL;
component->ActionRequest = INSTALLSTATE_LOCAL;
}
+ else if (feature->ActionRequest == INSTALLSTATE_SOURCE)
+ {
+ if ((component->Action == INSTALLSTATE_UNKNOWN) ||
+ (component->Action == INSTALLSTATE_ABSENT) ||
+ (component->Action == INSTALLSTATE_ADVERTISED))
+
+ {
+ component->Action = INSTALLSTATE_SOURCE;
+ component->ActionRequest = INSTALLSTATE_SOURCE;
+ }
+ }
+ else if (feature->ActionRequest == INSTALLSTATE_ADVERTISED)
+ {
+ if ((component->Action == INSTALLSTATE_UNKNOWN) ||
+ (component->Action == INSTALLSTATE_ABSENT))
+
+ {
+ component->Action = INSTALLSTATE_ADVERTISED;
+ component->ActionRequest = INSTALLSTATE_ADVERTISED;
+ }
+ }
else if (feature->ActionRequest == INSTALLSTATE_ABSENT)
{
if (component->Action == INSTALLSTATE_UNKNOWN)
@@ -2415,10 +2514,10 @@
{
static const WCHAR ExecSeqQuery[] =
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- 'D','i','r','e','c','t','o','r','y',0};
+ '`','D','i','r','e','c','t','o','r','y','`',0};
static const WCHAR ConditionQuery[] =
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- 'C','o','n','d','i','t','i','o','n',0};
+ '`','C','o','n','d','i','t','i','o','n','`',0};
static const WCHAR szCosting[] =
{'C','o','s','t','i','n','g','C','o','m','p','l','e','t','e',0 };
static const WCHAR szlevel[] =
@@ -2428,7 +2527,13 @@
MSIQUERY * view;
DWORD i;
LPWSTR level;
+ DWORD sz = 3;
+ WCHAR buffer[3];
+ MSI_GetPropertyW(package, szCosting, buffer, &sz);
+ if (buffer[0]=='1')
+ return ERROR_SUCCESS;
+
TRACE("Building Directory properties\n");
rc = MSI_DatabaseOpenViewW(package->db, ExecSeqQuery, &view);
@@ -2669,6 +2774,7 @@
if (the_file == INVALID_HANDLE_VALUE)
{
+ ERR("Unable to create file %s\n",debugstr_w(source));
rc = ERROR_FUNCTION_FAILED;
goto end;
}
@@ -2771,7 +2877,7 @@
LPWSTR tracknametmp;
static const WCHAR tmpprefix[] = {'C','A','B','T','M','P','_',0};
- if (data->file_name && strcmp(data->file_name,pfdin->psz1))
+ if (data->file_name && lstrcmpiA(data->file_name,pfdin->psz1))
return 0;
file = cabinet_alloc((len+1)*sizeof(char));
@@ -2884,8 +2990,8 @@
return ret;
}
-static UINT ready_media_for_file(MSIPACKAGE *package, UINT sequence,
- WCHAR* path, WCHAR* file)
+static UINT ready_media_for_file(MSIPACKAGE *package, WCHAR* path,
+ MSIFILE* file)
{
UINT rc;
MSIQUERY * view;
@@ -2893,25 +2999,31 @@
static WCHAR source[MAX_PATH];
static const WCHAR ExecSeqQuery[] =
{'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
- 'M','e','d','i','a',' ','W','H','E','R','E',' ',
- 'L','a','s','t','S','e','q','u','e','n','c','e',' ','>','=',' ','%',
- 'i',' ','O','R','D','E','R',' ','B','Y',' ',
- 'L','a','s','t','S','e','q','u','e','n','c','e',0};
+ '`','M','e','d','i','a','`',' ','W','H','E','R','E',' ',
+ '`','L','a','s','t','S','e','q','u','e','n','c','e','`',' ','>','=',
+ ' ','%', 'i',' ','O','R','D','E','R',' ','B','Y',' ',
+ '`','L','a','s','t','S','e','q','u','e','n','c','e','`',0};
WCHAR Query[1024];
WCHAR cab[0x100];
DWORD sz=0x100;
INT seq;
static UINT last_sequence = 0;
- if (sequence <= last_sequence)
+ if (file->Attributes & msidbFileAttributesNoncompressed)
{
- TRACE("Media already ready (%u, %u)\n",sequence,last_sequence);
- /*extract_a_cabinet_file(package, source,path,file); */
+ TRACE("Uncompressed File, no media to ready.\n");
return ERROR_SUCCESS;
}
- sprintfW(Query,ExecSeqQuery,sequence);
+ if (file->Sequence <= last_sequence)
+ {
+ TRACE("Media already ready (%u, %u)\n",file->Sequence,last_sequence);
+ /*extract_a_cabinet_file(package, source,path,file->File); */
+ return ERROR_SUCCESS;
+ }
+ sprintfW(Query,ExecSeqQuery,file->Sequence);
+
rc = MSI_DatabaseOpenViewW(package->db, Query, &view);
if (rc != ERROR_SUCCESS)
return rc;
@@ -3038,12 +3150,10 @@
if ((file->State == 1) || (file->State == 2))
{
LPWSTR p;
- INT len;
MSICOMPONENT* comp = NULL;
TRACE("Installing %s\n",debugstr_w(file->File));
- rc = ready_media_for_file(package,file->Sequence,path_to_source,
- file->File);
+ rc = ready_media_for_file(package, path_to_source, file);
/*
* WARNING!
* our file table could change here because a new temp file
@@ -3068,12 +3178,19 @@
HeapFree(GetProcessHeap(),0,file->TargetPath);
file->TargetPath = build_directory_name(2, p, file->FileName);
+ HeapFree(GetProcessHeap(),0,p);
- len = strlenW(path_to_source) + strlenW(file->File) + 2;
- file->SourcePath = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR));
- strcpyW(file->SourcePath, path_to_source);
- strcatW(file->SourcePath, file->File);
+ if (file->Attributes & msidbFileAttributesNoncompressed)
+ {
+ p = resolve_folder(package, comp->Directory, TRUE, FALSE, NULL);
+ file->SourcePath = build_directory_name(2, p, file->ShortName);
+ HeapFree(GetProcessHeap(),0,p);
+ }
+ else
+ file->SourcePath = build_directory_name(2, path_to_source,
+ file->File);
+
TRACE("file paths %s to %s\n",debugstr_w(file->SourcePath),
debugstr_w(file->TargetPath));
@@ -3088,16 +3205,26 @@
msiobj_release( &uirow->hdr );
ui_progress(package,2,file->FileSize,0,0);
- if (!MoveFileW(file->SourcePath,file->TargetPath))
+
+ if (file->Attributes & msidbFileAttributesNoncompressed)
+ rc = CopyFileW(file->SourcePath,file->TargetPath,FALSE);
+ else
+ rc = MoveFileW(file->SourcePath, file->TargetPath);
+
+ if (!rc)
{
rc = GetLastError();
- ERR("Unable to move file (%s -> %s) (error %d)\n",
+ ERR("Unable to move/copy file (%s -> %s) (error %d)\n",
debugstr_w(file->SourcePath), debugstr_w(file->TargetPath),
rc);
if (rc == ERROR_ALREADY_EXISTS && file->State == 2)
{
- CopyFileW(file->SourcePath,file->TargetPath,FALSE);
- DeleteFileW(file->SourcePath);
+ if (!CopyFileW(file->SourcePath,file->TargetPath,FALSE))
+ ERR("Unable to copy file (%s -> %s) (error %ld)\n",
+ debugstr_w(file->SourcePath),
+ debugstr_w(file->TargetPath), GetLastError());
+ if (!(file->Attributes & msidbFileAttributesNoncompressed))
+ DeleteFileW(file->SourcePath);
rc = 0;
}
else if (rc == ERROR_FILE_NOT_FOUND)
@@ -3105,14 +3232,17 @@
ERR("Source File Not Found! Continuing\n");
rc = 0;
}
- else
+ else if (file->Attributes & msidbFileAttributesVital)
{
- ERR("Ignoring Error and continuing...\n");
+ ERR("Ignoring Error and continuing (nonvital file)...\n");
rc = 0;
}
}
else
+ {
file->State = 4;
+ rc = ERROR_SUCCESS;
+ }
}
}
@@ -3151,7 +3281,7 @@
MSIRECORD * row = 0;
static const WCHAR ExecSeqQuery[] =
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- 'D','u','p','l','i','c','a','t','e','F','i','l','e',0};
+ '`','D','u','p','l','i','c','a','t','e','F','i','l','e','`',0};
if (!package)
return ERROR_INVALID_HANDLE;
@@ -3304,21 +3434,35 @@
{
LPWSTR ptr;
CHAR byte[5];
- LPWSTR deformated;
+ LPWSTR deformated = NULL;
int count;
deformat_string(package, &value[2], &deformated);
/* binary value type */
- ptr = deformated;
- *type=REG_BINARY;
- *size = strlenW(ptr)/2;
+ ptr = deformated;
+ *type = REG_BINARY;
+ if (strlenW(ptr)%2)
+ *size = (strlenW(ptr)/2)+1;
+ else
+ *size = strlenW(ptr)/2;
+
data = HeapAlloc(GetProcessHeap(),0,*size);
-
+
byte[0] = '0';
byte[1] = 'x';
byte[4] = 0;
count = 0;
+ /* if uneven pad with a zero in front */
+ if (strlenW(ptr)%2)
+ {
+ byte[2]= '0';
+ byte[3]= *ptr;
+ ptr++;
+ data[count] = (BYTE)strtol(byte,NULL,0);
+ count ++;
+ TRACE("Uneven byte count\n");
+ }
while (*ptr)
{
byte[2]= *ptr;
@@ -3395,7 +3539,7 @@
MSIRECORD * row = 0;
static const WCHAR ExecSeqQuery[] =
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- 'R','e','g','i','s','t','r','y',0 };
+ '`','R','e','g','i','s','t','r','y','`',0 };
if (!package)
return ERROR_INVALID_HANDLE;
@@ -3438,6 +3582,7 @@
MSIRECORD * uirow;
LPWSTR uikey;
INT root;
+ BOOL check_first = FALSE;
rc = MSI_ViewFetch(view,&row);
if (rc != ERROR_SUCCESS)
@@ -3483,6 +3628,7 @@
{
HeapFree(GetProcessHeap(),0,name);
name = NULL;
+ check_first = TRUE;
}
}
@@ -3545,9 +3691,33 @@
deformat_string(package, name, &deformated);
- TRACE("Setting value %s\n",debugstr_w(deformated));
- RegSetValueExW(hkey, deformated, 0, type, value_data, size);
+ /* get the double nulls to terminate SZ_MULTI */
+ if (type == REG_MULTI_SZ)
+ size +=sizeof(WCHAR);
+ if (!check_first)
+ {
+ TRACE("Setting value %s of %s\n",debugstr_w(deformated),
+ debugstr_w(uikey));
+ RegSetValueExW(hkey, deformated, 0, type, value_data, size);
+ }
+ else
+ {
+ DWORD sz = 0;
+ rc = RegQueryValueExW(hkey, deformated, NULL, NULL, NULL, &sz);
+ if (rc == ERROR_SUCCESS || rc == ERROR_MORE_DATA)
+ {
+ TRACE("value %s of %s checked already exists\n",
+ debugstr_w(deformated), debugstr_w(uikey));
+ }
+ else
+ {
+ TRACE("Checked and setting value %s of %s\n",
+ debugstr_w(deformated), debugstr_w(uikey));
+ RegSetValueExW(hkey, deformated, 0, type, value_data, size);
+ }
+ }
+
uirow = MSI_CreateRecord(3);
MSI_RecordSetStringW(uirow,2,deformated);
MSI_RecordSetStringW(uirow,1,uikey);
@@ -3589,7 +3759,7 @@
DWORD total = 0;
static const WCHAR q1[]=
{'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
- 'R','e','g','i','s','t','r','y',0};
+ '`','R','e','g','i','s','t','r','y','`',0};
UINT rc;
MSIQUERY * view;
MSIRECORD * row = 0;
@@ -3629,6 +3799,14 @@
total += package->files[i].FileSize;
ui_progress(package,0,total,0,0);
+ for(i = 0; i < package->loaded_features; i++)
+ {
+ MSIFEATURE* feature = &package->features[i];
+ TRACE("Feature: %s; Installed: %i; Action %i; Request %i\n",
+ debugstr_w(feature->Feature), feature->Installed, feature->Action,
+ feature->ActionRequest);
+ }
+
return ERROR_SUCCESS;
}
@@ -3639,7 +3817,7 @@
MSIRECORD * row = 0;
static const WCHAR ExecSeqQuery[] =
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- 'L','a','u','n','c','h','C','o','n','d','i','t','i','o','n',0};
+ '`','L','a','u','n','c','h','C','o','n','d','i','t','i','o','n','`',0};
static const WCHAR title[]=
{'I','n','s','t','a','l','l',' ','F','a', 'i','l','e','d',0};
@@ -3708,8 +3886,9 @@
LPWSTR key,deformated,buffer,name,deformated_name;
static const WCHAR ExecSeqQuery[] =
{'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ',
- 'R','e','g','i','s','t','r','y',' ','W','H','E','R','E',' ',
- 'R','e','g','i','s','t','r','y',' ','=',' ' ,'`','%','s','`',0 };
+ '`','R','e','g','i','s','t','r','y','`',' ',
+ 'W','H','E','R','E',' ', '`','R','e','g','i','s','t','r','y','`',
+ ' ','=',' ' ,'\'','%','s','\'',0 };
static const WCHAR fmt[]={'%','0','2','i',':','\\','%','s','\\',0};
static const WCHAR fmt2[]=
{'%','0','2','i',':','\\','%','s','\\','%','s',0};
@@ -3941,9 +4120,6 @@
MSIRECORD * uirow;
squash_guid(package->components[i].ComponentId,squished_cc);
- rc = RegCreateKeyW(hkey,squished_cc,&hkey2);
- if (rc != ERROR_SUCCESS)
- continue;
keypath = resolve_keypath(package,i);
package->components[i].FullKeypath = keypath;
@@ -3951,8 +4127,9 @@
/* do the refcounting */
ACTION_RefCountComponent( package, i);
- TRACE("Component %s, Keypath=%s, RefCount=%i\n",
- debugstr_w(package->components[i].Component),
+ TRACE("Component %s (%s), Keypath=%s, RefCount=%i\n",
+ debugstr_w(package->components[i].Component),
+ debugstr_w(squished_cc),
debugstr_w(package->components[i].FullKeypath),
package->components[i].RefCount);
/*
@@ -3962,6 +4139,10 @@
if (ACTION_VerifyComponentForAction(package, i,
INSTALLSTATE_LOCAL))
{
+ rc = RegCreateKeyW(hkey,squished_cc,&hkey2);
+ if (rc != ERROR_SUCCESS)
+ continue;
+
if (keypath)
{
RegSetValueExW(hkey2,squished_pc,0,REG_SZ,(LPVOID)keypath,
@@ -3996,6 +4177,11 @@
INSTALLSTATE_ABSENT))
{
DWORD res;
+
[truncated at 1000 lines; 12545 more skipped]