Jacek Caban : urlmon: Added support for 'Run' setup hook.

Alexandre Julliard julliard at winehq.org
Fri Jan 4 12:26:03 CST 2013


Module: wine
Branch: master
Commit: 6f4c5f1dd8c350d2c434edf947d50248ab3386f2
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=6f4c5f1dd8c350d2c434edf947d50248ab3386f2

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Jan  4 14:45:48 2013 +0100

urlmon: Added support for 'Run' setup hook.

---

 dlls/urlmon/axinstall.c |  132 +++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 129 insertions(+), 3 deletions(-)

diff --git a/dlls/urlmon/axinstall.c b/dlls/urlmon/axinstall.c
index 9f53ce0..ca1aef6 100644
--- a/dlls/urlmon/axinstall.c
+++ b/dlls/urlmon/axinstall.c
@@ -142,6 +142,134 @@ static HRESULT setup_dll(install_ctx_t *ctx)
     return hres;
 }
 
+static void expand_command(install_ctx_t *ctx, const WCHAR *cmd, WCHAR *buf, size_t *size)
+{
+    const WCHAR *ptr = cmd, *prev_ptr = cmd;
+    size_t len = 0, len2;
+
+    static const WCHAR expand_dirW[] = {'%','E','X','T','R','A','C','T','_','D','I','R','%'};
+
+    while((ptr = strchrW(ptr, '%'))) {
+        if(buf)
+            memcpy(buf+len, prev_ptr, ptr-prev_ptr);
+        len += ptr-prev_ptr;
+
+        if(!strncmpiW(ptr, expand_dirW, sizeof(expand_dirW)/sizeof(WCHAR))) {
+            len2 = strlenW(ctx->tmp_dir);
+            if(buf)
+                memcpy(buf+len, ctx->tmp_dir, len2*sizeof(WCHAR));
+            len += len2;
+            ptr += sizeof(expand_dirW)/sizeof(WCHAR);
+        }else {
+            FIXME("Can't expand %s\n", debugstr_w(ptr));
+            if(buf)
+                buf[len] = '%';
+            len++;
+            ptr++;
+        }
+
+        prev_ptr = ptr;
+    }
+
+    if(buf)
+        strcpyW(buf+len, prev_ptr);
+    *size = len + strlenW(prev_ptr) + 1;
+}
+
+static HRESULT process_hook_section(install_ctx_t *ctx, const WCHAR *sect_name)
+{
+    WCHAR buf[2048], val[2*MAX_PATH];
+    const WCHAR *key;
+    DWORD len;
+    HRESULT hres;
+
+    static const WCHAR runW[] = {'r','u','n',0};
+
+    len = GetPrivateProfileStringW(sect_name, NULL, NULL, buf, sizeof(buf)/sizeof(*buf), ctx->install_file);
+    if(!len)
+        return S_OK;
+
+    for(key = buf; *key; key += strlenW(key)+1) {
+        if(!strcmpiW(key, runW)) {
+            WCHAR *cmd;
+            size_t size;
+
+            len = GetPrivateProfileStringW(sect_name, runW, NULL, val, sizeof(val)/sizeof(*val), ctx->install_file);
+
+            TRACE("Run %s\n", debugstr_w(val));
+
+            expand_command(ctx, val, NULL, &size);
+
+            cmd = heap_alloc(size*sizeof(WCHAR));
+            if(!cmd)
+                heap_free(cmd);
+
+            expand_command(ctx, val, cmd, &size);
+            hres = RunSetupCommandW(ctx->hwnd, cmd, NULL, ctx->tmp_dir, NULL, NULL, 0, NULL);
+            heap_free(cmd);
+            if(FAILED(hres))
+                return hres;
+        }else {
+            FIXME("Unsupported hook %s\n", debugstr_w(key));
+            return E_NOTIMPL;
+        }
+    }
+
+    return S_OK;
+}
+
+static HRESULT install_inf_file(install_ctx_t *ctx)
+{
+    WCHAR buf[2048], sect_name[128];
+    BOOL default_install = TRUE;
+    const WCHAR *key;
+    DWORD len;
+    HRESULT hres;
+
+    static const WCHAR setup_hooksW[] = {'S','e','t','u','p',' ','H','o','o','k','s',0};
+    static const WCHAR add_codeW[] = {'A','d','d','.','C','o','d','e',0};
+
+    len = GetPrivateProfileStringW(setup_hooksW, NULL, NULL, buf, sizeof(buf)/sizeof(*buf), ctx->install_file);
+    if(len) {
+        default_install = FALSE;
+
+        for(key = buf; *key; key += strlenW(key)+1) {
+            TRACE("[Setup Hooks] key: %s\n", debugstr_w(key));
+
+            len = GetPrivateProfileStringW(setup_hooksW, key, NULL, sect_name, sizeof(sect_name)/sizeof(*sect_name),
+                    ctx->install_file);
+            if(!len) {
+                WARN("Could not get key value\n");
+                return E_FAIL;
+            }
+
+            hres = process_hook_section(ctx, sect_name);
+            if(FAILED(hres))
+                return hres;
+        }
+    }
+
+    len = GetPrivateProfileStringW(add_codeW, NULL, NULL, buf, sizeof(buf)/sizeof(*buf), ctx->install_file);
+    if(len) {
+        FIXME("[Add.Code] section not supported\n");
+
+        /* Don't throw an error if we successfully ran setup hooks;
+           installation is likely to be complete enough */
+        if(default_install)
+            return E_NOTIMPL;
+    }
+
+    if(default_install) {
+        hres = RunSetupCommandW(ctx->hwnd, ctx->install_file, NULL, ctx->tmp_dir, NULL, NULL, RSC_FLAG_INF, NULL);
+        if(FAILED(hres)) {
+            WARN("RunSetupCommandW failed: %08x\n", hres);
+            return hres;
+        }
+    }
+
+    return S_OK;
+}
+
 static HRESULT install_cab_file(install_ctx_t *ctx)
 {
     WCHAR tmp_path[MAX_PATH], tmp_dir[MAX_PATH];
@@ -169,9 +297,7 @@ static HRESULT install_cab_file(install_ctx_t *ctx)
 
         switch(ctx->install_type) {
         case INSTALL_INF:
-            hres = RunSetupCommandW(ctx->hwnd, ctx->install_file, NULL, ctx->tmp_dir, NULL, NULL, RSC_FLAG_INF, NULL);
-            if(FAILED(hres))
-                WARN("RunSetupCommandW failed: %08x\n", hres);
+            hres = install_inf_file(ctx);
             break;
         case INSTALL_DLL:
             FIXME("Installing DLL, registering in temporary location\n");




More information about the wine-cvs mailing list