Use MSI_IterateRecords for DuplicateFiles.
diff --git a/dlls/msi/files.c b/dlls/msi/files.c
index 6cfce96..352fff7 100644
--- a/dlls/msi/files.c
+++ b/dlls/msi/files.c
@@ -562,11 +562,109 @@
return rc;
}
+static UINT ITERATE_DuplicateFiles(MSIRECORD *row, LPVOID param)
+{
+ MSIPACKAGE *package = (MSIPACKAGE*)param;
+ WCHAR *file_source = NULL;
+ WCHAR dest_name[0x100];
+ LPWSTR dest_path, dest;
+ LPCWSTR file_key, component;
+ INT component_index;
+ DWORD sz;
+ DWORD rc;
+
+ component = MSI_RecordGetString(row,2);
+ component_index = get_loaded_component(package,component);
+
+ if (!ACTION_VerifyComponentForAction(package, component_index,
+ INSTALLSTATE_LOCAL))
+ {
+ TRACE("Skipping copy due to disabled component %s\n",
+ debugstr_w(component));
+
+ /* the action taken was the same as the current install state */
+ package->components[component_index].Action =
+ package->components[component_index].Installed;
+
+ return ERROR_SUCCESS;
+ }
+
+ package->components[component_index].Action = INSTALLSTATE_LOCAL;
+
+ file_key = MSI_RecordGetString(row,3);
+ if (!file_key)
+ {
+ ERR("Unable to get file key\n");
+ return ERROR_FUNCTION_FAILED;
+ }
+
+ rc = get_file_target(package,file_key,&file_source);
+
+ if (rc != ERROR_SUCCESS)
+ {
+ ERR("Original file unknown %s\n",debugstr_w(file_key));
+ HeapFree(GetProcessHeap(),0,file_source);
+ return ERROR_SUCCESS;
+ }
+
+ if (MSI_RecordIsNull(row,4))
+ {
+ strcpyW(dest_name,strrchrW(file_source,'\\')+1);
+ }
+ else
+ {
+ sz=0x100;
+ MSI_RecordGetStringW(row,4,dest_name,&sz);
+ reduce_to_longfilename(dest_name);
+ }
+
+ if (MSI_RecordIsNull(row,5))
+ {
+ LPWSTR p;
+ dest_path = strdupW(file_source);
+ p = strrchrW(dest_path,'\\');
+ if (p)
+ *p=0;
+ }
+ else
+ {
+ LPCWSTR destkey;
+ destkey = MSI_RecordGetString(row,5);
+ dest_path = resolve_folder(package, destkey, FALSE,FALSE,NULL);
+ if (!dest_path)
+ {
+ ERR("Unable to get destination folder\n");
+ HeapFree(GetProcessHeap(),0,file_source);
+ return ERROR_FUNCTION_FAILED;
+ }
+ }
+
+ dest = build_directory_name(2, dest_path, dest_name);
+
+ TRACE("Duplicating file %s to %s\n",debugstr_w(file_source),
+ debugstr_w(dest));
+
+ if (strcmpW(file_source,dest))
+ rc = !CopyFileW(file_source,dest,TRUE);
+ else
+ rc = ERROR_SUCCESS;
+
+ if (rc != ERROR_SUCCESS)
+ ERR("Failed to copy file %s -> %s, last error %ld\n", debugstr_w(file_source), debugstr_w(dest_path), GetLastError());
+
+ FIXME("We should track these duplicate files as well\n");
+
+ HeapFree(GetProcessHeap(),0,dest_path);
+ HeapFree(GetProcessHeap(),0,dest);
+ HeapFree(GetProcessHeap(),0,file_source);
+
+ return ERROR_SUCCESS;
+}
+
UINT ACTION_DuplicateFiles(MSIPACKAGE *package)
{
UINT rc;
MSIQUERY * view;
- 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};
@@ -578,122 +676,8 @@
if (rc != ERROR_SUCCESS)
return ERROR_SUCCESS;
- rc = MSI_ViewExecute(view, 0);
- if (rc != ERROR_SUCCESS)
- {
- MSI_ViewClose(view);
- msiobj_release(&view->hdr);
- return rc;
- }
-
- while (1)
- {
- WCHAR *file_source = NULL;
- WCHAR dest_name[0x100];
- LPWSTR dest_path, dest;
- LPCWSTR file_key, component;
- INT component_index;
-
- DWORD sz;
-
- rc = MSI_ViewFetch(view,&row);
- if (rc != ERROR_SUCCESS)
- {
- rc = ERROR_SUCCESS;
- break;
- }
-
- component = MSI_RecordGetString(row,2);
- component_index = get_loaded_component(package,component);
-
- if (!ACTION_VerifyComponentForAction(package, component_index,
- INSTALLSTATE_LOCAL))
- {
- TRACE("Skipping copy due to disabled component %s\n",
- debugstr_w(component));
-
- /* the action taken was the same as the current install state */
- package->components[component_index].Action =
- package->components[component_index].Installed;
-
- msiobj_release(&row->hdr);
- continue;
- }
-
- package->components[component_index].Action = INSTALLSTATE_LOCAL;
-
- file_key = MSI_RecordGetString(row,3);
- if (!file_key)
- {
- ERR("Unable to get file key\n");
- msiobj_release(&row->hdr);
- break;
- }
-
- rc = get_file_target(package,file_key,&file_source);
-
- if (rc != ERROR_SUCCESS)
- {
- ERR("Original file unknown %s\n",debugstr_w(file_key));
- msiobj_release(&row->hdr);
- HeapFree(GetProcessHeap(),0,file_source);
- continue;
- }
-
- if (MSI_RecordIsNull(row,4))
- {
- strcpyW(dest_name,strrchrW(file_source,'\\')+1);
- }
- else
- {
- sz=0x100;
- MSI_RecordGetStringW(row,4,dest_name,&sz);
- reduce_to_longfilename(dest_name);
- }
-
- if (MSI_RecordIsNull(row,5))
- {
- LPWSTR p;
- dest_path = strdupW(file_source);
- p = strrchrW(dest_path,'\\');
- if (p)
- *p=0;
- }
- else
- {
- LPCWSTR destkey;
- destkey = MSI_RecordGetString(row,5);
- dest_path = resolve_folder(package, destkey, FALSE,FALSE,NULL);
- if (!dest_path)
- {
- ERR("Unable to get destination folder\n");
- msiobj_release(&row->hdr);
- HeapFree(GetProcessHeap(),0,file_source);
- break;
- }
- }
-
- dest = build_directory_name(2, dest_path, dest_name);
-
- TRACE("Duplicating file %s to %s\n",debugstr_w(file_source),
- debugstr_w(dest));
-
- if (strcmpW(file_source,dest))
- rc = !CopyFileW(file_source,dest,TRUE);
- else
- rc = ERROR_SUCCESS;
-
- if (rc != ERROR_SUCCESS)
- ERR("Failed to copy file %s -> %s, last error %ld\n", debugstr_w(file_source), debugstr_w(dest_path), GetLastError());
-
- FIXME("We should track these duplicate files as well\n");
-
- msiobj_release(&row->hdr);
- HeapFree(GetProcessHeap(),0,dest_path);
- HeapFree(GetProcessHeap(),0,dest);
- HeapFree(GetProcessHeap(),0,file_source);
- }
- MSI_ViewClose(view);
+ rc = MSI_IterateRecords(view, NULL, ITERATE_DuplicateFiles, package);
msiobj_release(&view->hdr);
+
return rc;
}