[PATCH 1/4] wusa: create temp directories for installer

Vijay Kiran Kamuju infyquest at gmail.com
Thu Mar 22 09:28:07 CDT 2018


From: Michael Müller <michael at fds-team.de>

Signed-off-by: Vijay Kiran Kamuju <infyquest at gmail.com>
---
 programs/wusa/main.c | 171 +++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 166 insertions(+), 5 deletions(-)

diff --git a/programs/wusa/main.c b/programs/wusa/main.c
index aa7a38fe178..77dd46d8bd4 100644
--- a/programs/wusa/main.c
+++ b/programs/wusa/main.c
@@ -1,5 +1,7 @@
 /*
  * Copyright 2012 Austin English
+ * Copyright 2015 Michael Müller
+ * Copyright 2015 Sebastian Lackner
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -17,17 +19,176 @@
  */
 
 #include "wine/debug.h"
+#include "wine/heap.h"
+#include "wine/list.h"
+#include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(wusa);
 
+struct installer_tempdir {
+   struct list entry;
+   WCHAR *path;
+};
+
+struct installer_state {
+    BOOL norestart;
+    BOOL quiet;
+    struct list tempdirs;
+};
+
+static const WCHAR *path_combine(const WCHAR *path, const WCHAR *filename)
+{
+    static const WCHAR backslashW[] = {'\\',0};
+    WCHAR *result;
+    DWORD length;
+
+    if (!path || !filename)
+        return NULL;
+    length = strlenW(path) + strlenW(filename) + 2;
+    if (!(result = heap_alloc(length * sizeof(WCHAR))))
+        return NULL;
+
+    strcpyW(result,path);
+    if (result[0] && result[strlenW(result) - 1] != '\\')
+        strcatW(result, backslashW);
+    strcatW(result,filename);
+    return result;
+}
+
+static BOOL delete_directory(const WCHAR *path)
+{
+    static const WCHAR starW[] = {'*',0};
+    static const WCHAR dotW[] = {'.',0};
+    static const WCHAR dotdotW[] = {'.','.',0};
+    WIN32_FIND_DATAW data;
+    WCHAR *full_path;
+    HANDLE search;
+
+    if (!(full_path = (WCHAR *)path_combine(path, starW)))
+        return FALSE;
+    search = FindFirstFileW(full_path, &data);
+    heap_free(full_path);
+
+    if (search != INVALID_HANDLE_VALUE)
+    {
+        do
+        {
+            if (!strcmpW(data.cFileName, dotW))
+                continue;
+            if (!strcmpW(data.cFileName, dotdotW))
+                continue;
+            if (!(full_path = (WCHAR *)path_combine(path, data.cFileName)))
+                continue;
+            if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+                delete_directory(full_path);
+            else
+                DeleteFileW(full_path);
+            heap_free(full_path);
+        } while (FindNextFileW(search, &data));
+        FindClose(search);
+    }
+
+    return RemoveDirectoryW(full_path);
+}
+
+static const WCHAR *create_temp_directory(struct installer_state *state)
+{
+    static const WCHAR msuW[] = {'m','s','u',0};
+    static UINT id;
+    struct installer_tempdir *entry;
+    WCHAR tmp[MAX_PATH];
+
+    if (!GetTempPathW(sizeof(tmp)/sizeof(WCHAR), tmp))
+        return NULL;
+    if (!(entry = heap_alloc(sizeof(*entry))))
+        return NULL;
+    if (!(entry->path = heap_alloc((MAX_PATH+20)*sizeof(WCHAR))))
+    {
+        heap_free(entry);
+        return NULL;
+    }
+
+    for(;;)
+    {
+        if (!GetTempFileNameW(tmp, msuW, ++id, entry->path))
+        {
+            heap_free(entry->path);
+            heap_free(entry);
+            return NULL;
+        }
+        if (CreateDirectoryW(entry->path, NULL))
+            break;
+    }
+
+    list_add_tail(&state->tempdirs, &entry->entry);
+    return entry->path;
+}
+
+static void installer_cleanup(struct installer_state *state)
+{
+    struct installer_tempdir *tempdir, *tempdir2;
+
+    LIST_FOR_EACH_ENTRY_SAFE(tempdir, tempdir2, &state->tempdirs, struct installer_tempdir, entry)
+    {
+        list_remove(&tempdir->entry);
+        delete_directory(tempdir->path);
+        heap_free(tempdir->path);
+        heap_free(tempdir);
+    }
+}
+
+static BOOL install_msu(WCHAR *filename, struct installer_state *state)
+{
+    const WCHAR *temp_path;
+
+    list_init(&state->tempdirs);
+
+    WINE_TRACE("Processing msu file %s\n", wine_dbgstr_w(filename));
+    if (!(temp_path = create_temp_directory(state)))
+        return FALSE;
+
+    installer_cleanup(state);
+    return TRUE;
+}
+
 int wmain(int argc, WCHAR *argv[])
 {
+    static const WCHAR norestartW[] = {'/','n','o','r','e','s','t','a','r','t',0};
+    static const WCHAR quietW[] = {'/','q','u','i','e','t',0};
+    struct installer_state state;
+    WCHAR *filename = NULL;
     int i;
 
-    WINE_FIXME("stub:");
-    for (i = 0; i < argc; i++)
-        WINE_FIXME(" %s", wine_dbgstr_w(argv[i]));
-    WINE_FIXME("\n");
+    if (TRACE_ON(wusa))
+    {
+        WINE_TRACE("Command line :");
+        for (i = 0; i < argc; i++)
+            WINE_TRACE(" %s", wine_dbgstr_w(argv[i]));
+        WINE_TRACE("\n");
+    }
+
+    for (i = 1; i < argc; i++)
+    {
+        if (argv[i][0] == '/')
+        {
+            if (!strcmpW(argv[i], norestartW))
+                state.norestart = TRUE;
+            else if (!strcmpW(argv[i], quietW))
+                state.quiet = TRUE;
+            else
+                WINE_FIXME("Unknown option: %s\n", wine_dbgstr_w(argv[i]));
+        }
+        else if (!filename)
+             filename = argv[i];
+        else
+             WINE_FIXME("Unknown option: %s\n", wine_dbgstr_w(argv[i]));
+    }
+
+    if (!filename)
+    {
+        WINE_FIXME("Missing filename argument\n");
+        return 1;
+    }
 
-    return 0;
+    return !install_msu(filename, &state);
 }
-- 
2.16.2




More information about the wine-devel mailing list