https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3919813408ffae7e45885fe81c54187fc4153749

commit 3919813408ffae7e45885fe81c54187fc4153749
Author:     winesync <[email protected]>
AuthorDate: Sat Mar 12 15:12:07 2022 +0100
Commit:     Mark Jansen <[email protected]>
CommitDate: Sun Mar 20 19:27:42 2022 +0100

    [WINESYNC] msi: Make MsiEnumComponentCosts RPC-compatible.
    
    Signed-off-by: Zebediah Figura <[email protected]>
    Signed-off-by: Hans Leidekker <[email protected]>
    Signed-off-by: Alexandre Julliard <[email protected]>
    
    wine commit id efb8ed4748e75e88240cb27f3f917f6ed3446901 by Zebediah Figura 
<[email protected]>
---
 dll/win32/msi/msi.c                     |  20 +++---
 dll/win32/msi/package.c                 |   9 ++-
 dll/win32/msi/winemsi.idl               |   4 +-
 modules/rostests/winetests/msi/custom.c | 111 +++++++++++++++++++++++++++++++-
 4 files changed, 124 insertions(+), 20 deletions(-)

diff --git a/dll/win32/msi/msi.c b/dll/win32/msi/msi.c
index c0af7f52f62..2ec94a1cfb6 100644
--- a/dll/win32/msi/msi.c
+++ b/dll/win32/msi/msi.c
@@ -2005,25 +2005,21 @@ UINT WINAPI MsiEnumComponentCostsW( MSIHANDLE handle, 
LPCWSTR component, DWORD i
     if (!drive || !buflen || !cost || !temp) return ERROR_INVALID_PARAMETER;
     if (!(package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE )))
     {
+        WCHAR buffer[3];
         MSIHANDLE remote;
-        HRESULT hr;
-        BSTR bname = NULL;
 
         if (!(remote = msi_get_remote(handle)))
             return ERROR_INVALID_HANDLE;
 
-        if (component && !(bname = SysAllocString( component )))
-            return ERROR_OUTOFMEMORY;
-
-        hr = remote_EnumComponentCosts(remote, bname, index, state, drive, 
buflen, cost, temp);
-
-        SysFreeString( bname );
-        if (FAILED(hr))
+        r = remote_EnumComponentCosts(remote, component, index, state, buffer, 
cost, temp);
+        if (r == ERROR_SUCCESS)
         {
-            if (HRESULT_FACILITY(hr) == FACILITY_WIN32) return 
HRESULT_CODE(hr);
-            return ERROR_FUNCTION_FAILED;
+            lstrcpynW(drive, buffer, *buflen);
+            if (*buflen < 3)
+                r = ERROR_MORE_DATA;
+            *buflen = 2;
         }
-        return ERROR_SUCCESS;
+        return r;
     }
 
     if (!msi_get_property_int( package->db, szCostingComplete, 0 ))
diff --git a/dll/win32/msi/package.c b/dll/win32/msi/package.c
index 12893f3ad1d..510dd43b2ad 100644
--- a/dll/win32/msi/package.c
+++ b/dll/win32/msi/package.c
@@ -2596,12 +2596,11 @@ UINT __cdecl remote_GetFeatureCost(MSIHANDLE hinst, 
LPCWSTR feature,
     return MsiGetFeatureCostW(hinst, feature, cost_tree, state, cost);
 }
 
-HRESULT __cdecl remote_EnumComponentCosts(MSIHANDLE hinst, BSTR component,
-                                              DWORD index, INSTALLSTATE state, 
BSTR drive,
-                                              DWORD *buflen, INT *cost, INT 
*temp)
+UINT __cdecl remote_EnumComponentCosts(MSIHANDLE hinst, LPCWSTR component,
+    DWORD index, INSTALLSTATE state, LPWSTR drive, INT *cost, INT *temp)
 {
-    UINT r = MsiEnumComponentCostsW(hinst, component, index, state, drive, 
buflen, cost, temp);
-    return HRESULT_FROM_WIN32(r);
+    DWORD size = 3;
+    return MsiEnumComponentCostsW(hinst, component, index, state, drive, 
&size, cost, temp);
 }
 
 UINT msi_package_add_info(MSIPACKAGE *package, DWORD context, DWORD options,
diff --git a/dll/win32/msi/winemsi.idl b/dll/win32/msi/winemsi.idl
index fa98ac00434..388450084e9 100644
--- a/dll/win32/msi/winemsi.idl
+++ b/dll/win32/msi/winemsi.idl
@@ -91,8 +91,8 @@ interface IWineMsiRemote
     UINT remote_FormatRecord( [in] MSIHANDLE hinst, [in] struct wire_record 
*record, [out, string] LPWSTR *value);
     MSICONDITION remote_EvaluateCondition( [in] MSIHANDLE hinst, [in, string] 
LPCWSTR condition );
     UINT remote_GetFeatureCost( [in] MSIHANDLE hinst, [in, string] LPCWSTR 
feature, [in] MSICOSTTREE cost_tree, [in] INSTALLSTATE state, [out] INT *cost );
-    HRESULT remote_EnumComponentCosts( [in] MSIHANDLE hinst, [in] BSTR 
component, [in] DWORD index, [in] INSTALLSTATE state,
-                                       [out, size_is(*buflen)] BSTR drive, 
[in, out] DWORD *buflen, [out] INT *cost, [out] INT *temp );
+    UINT remote_EnumComponentCosts( [in] MSIHANDLE hinst, [in, string, unique] 
LPCWSTR component, [in] DWORD index, [in] INSTALLSTATE state,
+                                    [out, string, size_is(3)] LPWSTR drive, 
[out] INT *cost, [out] INT *temp );
 
     HRESULT remote_GetActionInfo( [in] LPCGUID guid, [out] INT *type, [out] 
BSTR *dllname,
                                   [out] BSTR *function, [out] MSIHANDLE 
*package );
diff --git a/modules/rostests/winetests/msi/custom.c 
b/modules/rostests/winetests/msi/custom.c
index ecd172a7161..35b3d71f52b 100644
--- a/modules/rostests/winetests/msi/custom.c
+++ b/modules/rostests/winetests/msi/custom.c
@@ -857,7 +857,13 @@ static void test_format_record(MSIHANDLE hinst)
 
 static void test_costs(MSIHANDLE hinst)
 {
-    INT cost;
+    static const WCHAR oneW[] = {'O','n','e',0};
+    static const WCHAR xyzW[] = {'C',':',0};
+    static const WCHAR xyW[] = {'C',0};
+    WCHAR bufferW[10];
+    char buffer[10];
+    int cost, temp;
+    DWORD sz;
     UINT r;
 
     cost = 0xdead;
@@ -872,6 +878,109 @@ static void test_costs(MSIHANDLE hinst)
     r = MsiGetFeatureCostA(hinst, "One", MSICOSTTREE_CHILDREN, 
INSTALLSTATE_LOCAL, &cost);
     ok(hinst, !r, "got %u\n", r);
     todo_wine_ok(hinst, cost == 8, "got %d\n", cost);
+
+    sz = cost = temp = 0xdead;
+    r = MsiEnumComponentCostsA(hinst, "One", 0, INSTALLSTATE_LOCAL, NULL, &sz, 
&cost, &temp);
+    ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r);
+    ok(hinst, sz == 0xdead, "got size %d\n", sz);
+    ok(hinst, cost == 0xdead, "got cost %d\n", cost);
+    ok(hinst, temp == 0xdead, "got temp %d\n", temp);
+
+    cost = temp = 0xdead;
+    r = MsiEnumComponentCostsA(hinst, "One", 0, INSTALLSTATE_LOCAL, buffer, 
NULL, &cost, &temp);
+    ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r);
+    ok(hinst, cost == 0xdead, "got cost %d\n", cost);
+    ok(hinst, temp == 0xdead, "got temp %d\n", temp);
+
+    sz = temp = 0xdead;
+    r = MsiEnumComponentCostsA(hinst, "One", 0, INSTALLSTATE_LOCAL, buffer, 
&sz, NULL, &temp);
+    ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r);
+    ok(hinst, sz == 0xdead, "got size %d\n", sz);
+    ok(hinst, temp == 0xdead, "got temp %d\n", temp);
+
+    sz = cost = 0xdead;
+    r = MsiEnumComponentCostsA(hinst, "One", 0, INSTALLSTATE_LOCAL, buffer, 
&sz, &cost, NULL);
+    ok(hinst, r == ERROR_INVALID_PARAMETER, "got %u\n", r);
+    ok(hinst, sz == 0xdead, "got size %d\n", sz);
+    ok(hinst, cost == 0xdead, "got cost %d\n", cost);
+
+    cost = temp = 0xdead;
+    sz = sizeof(buffer);
+    r = MsiEnumComponentCostsA(hinst, NULL, 0, INSTALLSTATE_LOCAL, buffer, 
&sz, &cost, &temp);
+    ok(hinst, !r, "got %u\n", r);
+    ok(hinst, sz == 2, "got size %u\n", sz);
+    ok(hinst, !strcmp(buffer, "C:"), "got '%s'\n", buffer);
+    ok(hinst, !cost, "got cost %d\n", cost);
+    ok(hinst, temp && temp != 0xdead, "got temp %d\n", temp);
+
+    cost = temp = 0xdead;
+    sz = sizeof(buffer);
+    r = MsiEnumComponentCostsA(hinst, "One", 0, INSTALLSTATE_LOCAL, buffer, 
&sz, &cost, &temp);
+    ok(hinst, !r, "got %u\n", r);
+    ok(hinst, sz == 2, "got size %u\n", sz);
+    ok(hinst, !strcmp(buffer, "C:"), "got '%s'\n", buffer);
+    ok(hinst, cost == 8, "got cost %d\n", cost);
+    ok(hinst, !temp, "got temp %d\n", temp);
+
+    /* same string behaviour */
+    cost = temp = 0xdead;
+    sz = 0;
+    strcpy(buffer,"q");
+    r = MsiEnumComponentCostsA(hinst, "One", 0, INSTALLSTATE_LOCAL, buffer, 
&sz, &cost, &temp);
+    ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r);
+    ok(hinst, !strcmp(buffer, "q"), "got \"%s\"\n", buffer);
+    todo_wine_ok(hinst, sz == 4, "got size %u\n", sz);
+    ok(hinst, cost == 8, "got cost %d\n", cost);
+    ok(hinst, !temp, "got temp %d\n", temp);
+
+    sz = 1;
+    strcpy(buffer,"x");
+    r = MsiEnumComponentCostsA(hinst, "One", 0, INSTALLSTATE_LOCAL, buffer, 
&sz, &cost, &temp);
+    ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r);
+    todo_wine_ok(hinst, !buffer[0], "got \"%s\"\n", buffer);
+    todo_wine_ok(hinst, sz == 4, "got size %u\n", sz);
+
+    sz = 2;
+    strcpy(buffer,"x");
+    r = MsiEnumComponentCostsA(hinst, "One", 0, INSTALLSTATE_LOCAL, buffer, 
&sz, &cost, &temp);
+    ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r);
+    todo_wine_ok(hinst, !strcmp(buffer, "C"), "got \"%s\"\n", buffer);
+    todo_wine_ok(hinst, sz == 4, "got size %u\n", sz);
+
+    sz = 3;
+    strcpy(buffer,"x");
+    r = MsiEnumComponentCostsA(hinst, "One", 0, INSTALLSTATE_LOCAL, buffer, 
&sz, &cost, &temp);
+    ok(hinst, !r, "got %u\n", r);
+    ok(hinst, !strcmp(buffer, "C:"), "got \"%s\"\n", buffer);
+    ok(hinst, sz == 2, "got size %u\n", sz);
+
+    sz = 0;
+    bufferW[0] = 'q';
+    r = MsiEnumComponentCostsW(hinst, oneW, 0, INSTALLSTATE_LOCAL, bufferW, 
&sz, &cost, &temp);
+    ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r);
+    ok(hinst, bufferW[0] == 'q', "got %s\n", dbgstr_w(bufferW));
+    ok(hinst, sz == 2, "got size %u\n", sz);
+
+    sz = 1;
+    bufferW[0] = 'q';
+    r = MsiEnumComponentCostsW(hinst, oneW, 0, INSTALLSTATE_LOCAL, bufferW, 
&sz, &cost, &temp);
+    ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r);
+    ok(hinst, !bufferW[0], "got %s\n", dbgstr_w(bufferW));
+    ok(hinst, sz == 2, "got size %u\n", sz);
+
+    sz = 2;
+    bufferW[0] = 'q';
+    r = MsiEnumComponentCostsW(hinst, oneW, 0, INSTALLSTATE_LOCAL, bufferW, 
&sz, &cost, &temp);
+    ok(hinst, r == ERROR_MORE_DATA, "got %u\n", r);
+    ok(hinst, !lstrcmpW(bufferW, xyW), "got %s\n", dbgstr_w(bufferW));
+    ok(hinst, sz == 2, "got size %u\n", sz);
+
+    sz = 3;
+    bufferW[0] = 'q';
+    r = MsiEnumComponentCostsW(hinst, oneW, 0, INSTALLSTATE_LOCAL, bufferW, 
&sz, &cost, &temp);
+    ok(hinst, !r, "got %u\n", r);
+    ok(hinst, !lstrcmpW(bufferW, xyzW), "got %s\n", dbgstr_w(bufferW));
+    ok(hinst, sz == 2, "got size %u\n", sz);
 }
 
 /* Main test. Anything that doesn't depend on a specific install configuration

Reply via email to