[PATCH 3/4] wusa: Parse update descriptions.
Hans Leidekker
hans at codeweavers.com
Mon Dec 2 03:11:51 CST 2019
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
programs/wusa/main.c | 46 +++++++++++++++++
programs/wusa/manifest.c | 106 +++++++++++++++++++++++++++++++++++++++
programs/wusa/wusa.h | 2 +
3 files changed, 154 insertions(+)
diff --git a/programs/wusa/main.c b/programs/wusa/main.c
index a1cdea4ee8..8df8731e2b 100644
--- a/programs/wusa/main.c
+++ b/programs/wusa/main.c
@@ -41,6 +41,7 @@ struct installer_state
BOOL quiet;
struct list tempdirs;
struct list assemblies;
+ struct list updates;
};
static void * CDECL cabinet_alloc(ULONG cb)
@@ -317,6 +318,7 @@ static void installer_cleanup(struct installer_state *state)
{
struct installer_tempdir *tempdir, *tempdir2;
struct assembly_entry *assembly, *assembly2;
+ struct dependency_entry *dependency, *dependency2;
LIST_FOR_EACH_ENTRY_SAFE(tempdir, tempdir2, &state->tempdirs, struct installer_tempdir, entry)
{
@@ -330,6 +332,11 @@ static void installer_cleanup(struct installer_state *state)
list_remove(&assembly->entry);
free_assembly(assembly);
}
+ LIST_FOR_EACH_ENTRY_SAFE(dependency, dependency2, &state->updates, struct dependency_entry, entry)
+ {
+ list_remove(&dependency->entry);
+ free_dependency(dependency);
+ }
}
static BOOL str_ends_with(const WCHAR *str, const WCHAR *suffix)
@@ -397,6 +404,7 @@ static BOOL install_msu(const WCHAR *filename, struct installer_state *state)
list_init(&state->tempdirs);
list_init(&state->assemblies);
+ list_init(&state->updates);
CoInitialize(NULL);
TRACE("Processing msu file %s\n", debugstr_w(filename));
@@ -428,6 +436,44 @@ static BOOL install_msu(const WCHAR *filename, struct installer_state *state)
FindClose(search);
}
+ /* load all update descriptions */
+ if (!(path = path_combine(temp_path, L"*.xml"))) goto done;
+ search = FindFirstFileW(path, &data);
+ heap_free(path);
+
+ if (search != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue;
+ if (!(path = path_combine(temp_path, data.cFileName))) continue;
+ if (!load_update(path, &state->updates))
+ ERR("Failed to load all updates from %s, ignoring\n", debugstr_w(path));
+ heap_free(path);
+ }
+ while (FindNextFileW(search, &data));
+ FindClose(search);
+ }
+
+ /* dump package information (for debugging) */
+ if (TRACE_ON(wusa))
+ {
+ struct dependency_entry *dependency;
+ struct assembly_entry *assembly;
+
+ TRACE("List of updates:\n");
+ LIST_FOR_EACH_ENTRY(dependency, &state->updates, struct dependency_entry, entry)
+ TRACE(" * %s\n", debugstr_w(dependency->identity.name));
+
+ TRACE("List of manifests (with dependencies):\n");
+ LIST_FOR_EACH_ENTRY(assembly, &state->assemblies, struct assembly_entry, entry)
+ {
+ TRACE(" * %s\n", debugstr_w(assembly->identity.name));
+ LIST_FOR_EACH_ENTRY(dependency, &assembly->dependencies, struct dependency_entry, entry)
+ TRACE(" -> %s\n", debugstr_w(dependency->identity.name));
+ }
+ }
+
ret = TRUE;
done:
diff --git a/programs/wusa/manifest.c b/programs/wusa/manifest.c
index 44c263f6c0..e80c11998c 100644
--- a/programs/wusa/manifest.c
+++ b/programs/wusa/manifest.c
@@ -565,3 +565,109 @@ done:
IXMLDOMElement_Release(root);
return entry;
}
+
+/* <unattend><servicing><package> */
+static BOOL read_update_package(IXMLDOMElement *child, WCHAR *tagname, void *context)
+{
+ struct dependency_entry *entry;
+ struct list *update_list = context;
+
+ if (!wcscmp(tagname, L"source")) return TRUE;
+ if (wcscmp(tagname, L"assemblyIdentity"))
+ {
+ TRACE("Ignoring unexpected tag %s\n", debugstr_w(tagname));
+ return TRUE;
+ }
+
+ if ((entry = alloc_dependency()))
+ {
+ if (read_identity(child, &entry->identity))
+ {
+ TRACE("Found update %s\n", debugstr_w(entry->identity.name));
+ list_add_tail(update_list, &entry->entry);
+ return TRUE;
+ }
+ free_dependency(entry);
+ }
+
+ return FALSE;
+}
+
+static BOOL iter_update_package(IXMLDOMElement *root, struct list *update_list)
+{
+ return call_xml_callbacks(root, read_update_package, update_list);
+}
+
+/* <unattend><servicing> */
+static BOOL read_servicing(IXMLDOMElement *child, WCHAR *tagname, void *context)
+{
+ struct list *update_list = context;
+ WCHAR *action;
+ BOOL ret = TRUE;
+
+ if (wcscmp(tagname, L"package"))
+ {
+ FIXME("Ignoring unexpected tag %s\n", debugstr_w(tagname));
+ return TRUE;
+ }
+
+ if (!(action = get_xml_attribute(child, L"action")))
+ {
+ FIXME("Servicing tag doesn't specify action\n");
+ return FALSE;
+ }
+
+ if (!wcscmp(action, L"install"))
+ ret = iter_update_package(child, update_list);
+ else
+ FIXME("action %s not supported\n", debugstr_w(action));
+
+ heap_free(action);
+ return ret;
+}
+
+static BOOL iter_servicing(IXMLDOMElement *root, struct list *update_list)
+{
+ return call_xml_callbacks(root, read_servicing, update_list);
+}
+
+/* <unattend> */
+static BOOL read_unattend(IXMLDOMElement *child, WCHAR *tagname, void *context)
+{
+ struct list *update_list = context;
+
+ if (wcscmp(tagname, L"servicing"))
+ {
+ FIXME("Ignoring unexpected tag %s\n", debugstr_w(tagname));
+ return TRUE;
+ }
+
+ return iter_servicing(child, update_list);
+
+}
+
+static BOOL iter_unattend(IXMLDOMElement *root, struct list *update_list)
+{
+ return call_xml_callbacks(root, read_unattend, update_list);
+}
+
+BOOL load_update(const WCHAR *filename, struct list *update_list)
+{
+ IXMLDOMElement *root = NULL;
+ BOOL ret = FALSE;
+
+ TRACE("Reading update %s\n", debugstr_w(filename));
+
+ if (!(root = load_xml(filename))) return FALSE;
+ if (!check_xml_tagname(root, L"unattend"))
+ {
+ FIXME("Didn't find unattend root node?\n");
+ goto done;
+ }
+
+ ret = iter_unattend(root, update_list);
+
+done:
+ IXMLDOMElement_Release(root);
+ return ret;
+}
diff --git a/programs/wusa/wusa.h b/programs/wusa/wusa.h
index 2c81b639b9..e717fad6e0 100644
--- a/programs/wusa/wusa.h
+++ b/programs/wusa/wusa.h
@@ -74,7 +74,9 @@ struct assembly_entry
};
void free_assembly(struct assembly_entry *entry) DECLSPEC_HIDDEN;
+void free_dependency(struct dependency_entry *entry) DECLSPEC_HIDDEN;
struct assembly_entry *load_manifest(const WCHAR *filename) DECLSPEC_HIDDEN;
+BOOL load_update(const WCHAR *filename, struct list *update_list) DECLSPEC_HIDDEN;
static void *heap_alloc(size_t len) __WINE_ALLOC_SIZE(1);
static inline void *heap_alloc(size_t len)
--
2.20.1
More information about the wine-devel
mailing list