Zebediah Figura : msi: Make MsiGetTargetPath() RPC-compatible.

Alexandre Julliard julliard at winehq.org
Mon Apr 23 17:58:36 CDT 2018


Module: wine
Branch: master
Commit: 49d67080c97cbe89ea6f665f692c6d32db272a0f
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=49d67080c97cbe89ea6f665f692c6d32db272a0f

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Sat Apr 21 19:33:45 2018 -0500

msi: Make MsiGetTargetPath() RPC-compatible.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msi/install.c       | 46 +++++-------------------
 dlls/msi/package.c       | 17 +++++++--
 dlls/msi/tests/custom.c  | 91 ++++++++++++++++++++++++++++++++++++++++++++++++
 dlls/msi/tests/install.c | 11 ++++++
 dlls/msi/winemsi.idl     |  2 +-
 5 files changed, 125 insertions(+), 42 deletions(-)

diff --git a/dlls/msi/install.c b/dlls/msi/install.c
index 2a5ff40..68d8eb5 100644
--- a/dlls/msi/install.c
+++ b/dlls/msi/install.c
@@ -27,7 +27,6 @@
 #include "windef.h"
 #include "winbase.h"
 #include "winerror.h"
-#include "wine/debug.h"
 #include "msi.h"
 #include "msidefs.h"
 #include "objbase.h"
@@ -35,6 +34,8 @@
 
 #include "msipriv.h"
 #include "winemsi.h"
+#include "wine/heap.h"
+#include "wine/debug.h"
 #include "wine/unicode.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(msi);
@@ -200,50 +201,19 @@ static UINT MSI_GetTargetPath( MSIHANDLE hInstall, LPCWSTR szFolder,
     package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE );
     if (!package)
     {
-        MSIHANDLE remote;
-        HRESULT hr;
         LPWSTR value = NULL;
-        BSTR folder;
-        DWORD len;
+        MSIHANDLE remote;
 
         if (!(remote = msi_get_remote(hInstall)))
             return ERROR_INVALID_HANDLE;
 
-        folder = SysAllocString( szFolder );
-        if (!folder)
-            return ERROR_OUTOFMEMORY;
-
-        len = 0;
-        hr = remote_GetTargetPath(remote, folder, NULL, &len);
-        if (FAILED(hr))
-            goto done;
-
-        len++;
-        value = msi_alloc(len * sizeof(WCHAR));
-        if (!value)
-        {
-            r = ERROR_OUTOFMEMORY;
-            goto done;
-        }
-
-        hr = remote_GetTargetPath(remote, folder, value, &len);
-        if (FAILED(hr))
-            goto done;
-
-        r = msi_strcpy_to_awstring( value, len, szPathBuf, pcchPathBuf );
+        r = remote_GetTargetPath(remote, szFolder, &value);
+        if (r != ERROR_SUCCESS)
+            return r;
 
-done:
-        SysFreeString( folder );
-        msi_free( value );
-
-        if (FAILED(hr))
-        {
-            if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
-                return HRESULT_CODE(hr);
-
-            return ERROR_FUNCTION_FAILED;
-        }
+        r = msi_strcpy_to_awstring(value, -1, szPathBuf, pcchPathBuf);
 
+        midl_user_free(value);
         return r;
     }
 
diff --git a/dlls/msi/package.c b/dlls/msi/package.c
index 161ba81..d1a6923 100644
--- a/dlls/msi/package.c
+++ b/dlls/msi/package.c
@@ -2474,10 +2474,21 @@ UINT __cdecl remote_Sequence(MSIHANDLE hinst, LPCWSTR table, int sequence)
     return MsiSequenceW(hinst, table, sequence);
 }
 
-HRESULT __cdecl remote_GetTargetPath(MSIHANDLE hinst, BSTR folder, BSTR value, DWORD *size)
+UINT __cdecl remote_GetTargetPath(MSIHANDLE hinst, LPCWSTR folder, LPWSTR *value)
 {
-    UINT r = MsiGetTargetPathW(hinst, folder, value, size);
-    return HRESULT_FROM_WIN32(r);
+    WCHAR empty[1];
+    DWORD size = 0;
+    UINT r;
+
+    r = MsiGetTargetPathW(hinst, folder, empty, &size);
+    if (r == ERROR_MORE_DATA)
+    {
+        *value = midl_user_allocate(++size * sizeof(WCHAR));
+        if (!*value)
+            return ERROR_OUTOFMEMORY;
+        r = MsiGetTargetPathW(hinst, folder, *value, &size);
+    }
+    return r;
 }
 
 HRESULT __cdecl remote_SetTargetPath(MSIHANDLE hinst, BSTR folder, BSTR value)
diff --git a/dlls/msi/tests/custom.c b/dlls/msi/tests/custom.c
index bfd1e85..5062ecd 100644
--- a/dlls/msi/tests/custom.c
+++ b/dlls/msi/tests/custom.c
@@ -453,6 +453,96 @@ UINT WINAPI nested(MSIHANDLE hinst)
     return ERROR_SUCCESS;
 }
 
+static void test_targetpath(MSIHANDLE hinst)
+{
+    static const WCHAR targetdirW[] = {'T','A','R','G','E','T','D','I','R',0};
+    static const WCHAR xyzW[] = {'C',':','\\',0};
+    static const WCHAR xyW[] = {'C',':',0};
+    char buffer[20];
+    WCHAR bufferW[20];
+    DWORD sz;
+    UINT r;
+
+    /* test invalid values */
+    r = MsiGetTargetPathA(hinst, NULL, NULL, NULL);
+    ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r);
+
+    r = MsiGetTargetPathA(hinst, "TARGETDIR", NULL, NULL );
+    ok(hinst, !r, "got %u\n", r);
+
+    r = MsiGetTargetPathA(hinst, "TARGETDIR", buffer, NULL );
+    ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r);
+
+    /* Returned size is in bytes, not chars, but only for custom actions.
+     * Seems to be a casualty of RPC... */
+
+    sz = 0;
+    r = MsiGetTargetPathA(hinst, "TARGETDIR", NULL, &sz);
+    ok(hinst, !r, "got %u\n", r);
+    todo_wine_ok(hinst, sz == 6, "got size %u\n", sz);
+
+    sz = 0;
+    strcpy(buffer,"q");
+    r = MsiGetTargetPathA(hinst, "TARGETDIR", buffer, &sz);
+    ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r);
+    ok(hinst, !strcmp(buffer, "q"), "got \"%s\"\n", buffer);
+    todo_wine_ok(hinst, sz == 6, "got size %u\n", sz);
+
+    sz = 1;
+    strcpy(buffer,"x");
+    r = MsiGetTargetPathA(hinst, "TARGETDIR", buffer, &sz);
+    ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r);
+    ok(hinst, !buffer[0], "got \"%s\"\n", buffer);
+    todo_wine_ok(hinst, sz == 6, "got size %u\n", sz);
+
+    sz = 3;
+    strcpy(buffer,"x");
+    r = MsiGetTargetPathA(hinst, "TARGETDIR", buffer, &sz);
+    ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r);
+    ok(hinst, !strcmp(buffer, "C:"), "got \"%s\"\n", buffer);
+    todo_wine_ok(hinst, sz == 6, "got size %u\n", sz);
+
+    sz = 4;
+    strcpy(buffer,"x");
+    r = MsiGetTargetPathA(hinst, "TARGETDIR", buffer, &sz);
+    ok(hinst, !r, "got %u\n", r);
+    ok(hinst, !strcmp(buffer, "C:\\"), "got \"%s\"\n", buffer);
+    ok(hinst, sz == 3, "got size %u\n", sz);
+
+    sz = 0;
+    r = MsiGetTargetPathW(hinst, targetdirW, NULL, &sz);
+    ok(hinst, !r, "got %u\n", r);
+    ok(hinst, sz == 3, "got size %u\n", sz);
+
+    sz = 0;
+    bufferW[0] = 'q';
+    r = MsiGetTargetPathW(hinst, targetdirW, bufferW, &sz);
+    ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r);
+    ok(hinst, bufferW[0] == 'q', "got %s\n", dbgstr_w(bufferW));
+    ok(hinst, sz == 3, "got size %u\n", sz);
+
+    sz = 1;
+    bufferW[0] = 'q';
+    r = MsiGetTargetPathW(hinst, targetdirW, bufferW, &sz);
+    ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r);
+    ok(hinst, !bufferW[0], "got %s\n", dbgstr_w(bufferW));
+    ok(hinst, sz == 3, "got size %u\n", sz);
+
+    sz = 3;
+    bufferW[0] = 'q';
+    r = MsiGetTargetPathW(hinst, targetdirW, bufferW, &sz);
+    ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r);
+    ok(hinst, !lstrcmpW(bufferW, xyW), "got %s\n", dbgstr_w(bufferW));
+    ok(hinst, sz == 3, "got size %u\n", sz);
+
+    sz = 4;
+    bufferW[0] = 'q';
+    r = MsiGetTargetPathW(hinst, targetdirW, bufferW, &sz);
+    ok(hinst, !r, "got %u\n", r);
+    ok(hinst, !lstrcmpW(bufferW, xyzW), "got %s\n", dbgstr_w(bufferW));
+    ok(hinst, sz == 3, "got size %u\n", sz);
+}
+
 /* Main test. Anything that doesn't depend on a specific install configuration
  * or have undesired side effects should go here. */
 UINT WINAPI main_test(MSIHANDLE hinst)
@@ -479,6 +569,7 @@ UINT WINAPI main_test(MSIHANDLE hinst)
     test_props(hinst);
     test_db(hinst);
     test_doaction(hinst);
+    test_targetpath(hinst);
 
     return ERROR_SUCCESS;
 }
diff --git a/dlls/msi/tests/install.c b/dlls/msi/tests/install.c
index c5d9243..6a7383b 100644
--- a/dlls/msi/tests/install.c
+++ b/dlls/msi/tests/install.c
@@ -695,6 +695,9 @@ static const CHAR wrv_component_dat[] = "Component\tComponentId\tDirectory_\tAtt
 static const CHAR ca1_install_exec_seq_dat[] = "Action\tCondition\tSequence\n"
                                                "s72\tS255\tI2\n"
                                                "InstallExecuteSequence\tAction\n"
+                                               "CostInitialize\t\t100\n"
+                                               "FileCost\t\t200\n"
+                                               "CostFinalize\t\t300\n"
                                                "embednull\t\t600\n"
                                                "maintest\tMAIN_TEST\t700\n"
                                                "testretval\tTEST_RETVAL\t710\n";
@@ -1709,7 +1712,13 @@ static const msi_table sf_tables[] =
 
 static const msi_table ca1_tables[] =
 {
+    ADD_TABLE(component),
+    ADD_TABLE(directory),
+    ADD_TABLE(feature),
+    ADD_TABLE(feature_comp),
+    ADD_TABLE(file),
     ADD_TABLE(property),
+    ADD_TABLE(directory),
     ADD_TABLE(ca1_install_exec_seq),
     ADD_TABLE(ca1_custom_action),
     ADD_TABLE(ca1_test_seq),
@@ -4120,6 +4129,7 @@ static void test_customaction1(void)
     MSIHANDLE hdb, record;
     UINT r;
 
+    create_test_files();
     create_database(msifile, ca1_tables, sizeof(ca1_tables) / sizeof(msi_table));
     add_custom_dll();
 
@@ -4158,6 +4168,7 @@ static void test_customaction1(void)
     r = MsiInstallProductA(msifile, "TEST_RETVAL=1");
     ok(r == ERROR_INSTALL_FAILURE, "Expected ERROR_INSTALL_FAILURE, got %u\n", r);
 
+    delete_test_files();
     DeleteFileA(msifile);
     DeleteFileA("unus");
     DeleteFileA("duo");
diff --git a/dlls/msi/winemsi.idl b/dlls/msi/winemsi.idl
index d103e9a..5e09c85 100644
--- a/dlls/msi/winemsi.idl
+++ b/dlls/msi/winemsi.idl
@@ -76,7 +76,7 @@ interface IWineMsiRemote
     int remote_ProcessMessage( [in] MSIHANDLE hinst, [in] INSTALLMESSAGE message, [in] struct wire_record *record );
     UINT remote_DoAction( [in] MSIHANDLE hinst, [in, string] LPCWSTR action );
     UINT remote_Sequence( [in] MSIHANDLE hinst, [in, string] LPCWSTR table, [in] int sequence );
-    HRESULT remote_GetTargetPath( [in] MSIHANDLE hinst, [in] BSTR folder, [out, size_is(*size)] BSTR value, [in, out] DWORD *size );
+    UINT remote_GetTargetPath( [in] MSIHANDLE hinst, [in, string] LPCWSTR folder, [out, string] LPWSTR *value );
     HRESULT remote_SetTargetPath( [in] MSIHANDLE hinst, [in] BSTR folder, [in] BSTR value );
     HRESULT remote_GetSourcePath( [in] MSIHANDLE hinst, [in] BSTR folder, [out, size_is(*size)] BSTR value, [in, out] DWORD *size );
     HRESULT remote_GetMode( [in] MSIHANDLE hinst, [in] MSIRUNMODE mode, [out] BOOL *ret );




More information about the wine-cvs mailing list