Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/msi/msi.c | 20 ++++----- dlls/msi/package.c | 9 ++-- dlls/msi/tests/custom.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++- dlls/msi/winemsi.idl | 4 +- 4 files changed, 124 insertions(+), 20 deletions(-)
diff --git a/dlls/msi/msi.c b/dlls/msi/msi.c index c0af7f5..2ec94a1 100644 --- a/dlls/msi/msi.c +++ b/dlls/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/dlls/msi/package.c b/dlls/msi/package.c index b633250..067e571 100644 --- a/dlls/msi/package.c +++ b/dlls/msi/package.c @@ -2589,12 +2589,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/dlls/msi/tests/custom.c b/dlls/msi/tests/custom.c index ecd172a..35b3d71 100644 --- a/dlls/msi/tests/custom.c +++ b/dlls/msi/tests/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 diff --git a/dlls/msi/winemsi.idl b/dlls/msi/winemsi.idl index fa98ac0..3884500 100644 --- a/dlls/msi/winemsi.idl +++ b/dlls/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 );