diff --git a/dlls/msi/custom.c b/dlls/msi/custom.c index e2ed5a42fde..83b1687f5fa 100644 --- a/dlls/msi/custom.c +++ b/dlls/msi/custom.c @@ -34,6 +34,7 @@ #include "msipriv.h" #include "winemsi.h" +#include "wine/heap.h" #include "wine/debug.h" #include "wine/unicode.h" #include "wine/exception.h" @@ -64,6 +65,16 @@ static CRITICAL_SECTION msi_custom_action_cs = { &msi_custom_action_cs_debug, -1 static struct list msi_pending_custom_actions = LIST_INIT( msi_pending_custom_actions ); +void __RPC_FAR * __RPC_USER MIDL_user_allocate(SIZE_T len) +{ + return heap_alloc(len); +} + +void __RPC_USER MIDL_user_free(void __RPC_FAR * ptr) +{ + heap_free(ptr); +} + UINT msi_schedule_action( MSIPACKAGE *package, UINT script, const WCHAR *action ) { UINT count; diff --git a/dlls/msi/package.c b/dlls/msi/package.c index 4e1ac2f73d5..4986ec1af94 100644 --- a/dlls/msi/package.c +++ b/dlls/msi/package.c @@ -29,7 +29,6 @@ #include "winnls.h" #include "shlwapi.h" #include "wingdi.h" -#include "wine/debug.h" #include "msi.h" #include "msiquery.h" #include "objidl.h" @@ -39,11 +38,14 @@ #include "winver.h" #include "urlmon.h" #include "shlobj.h" -#include "wine/unicode.h" #include "objbase.h" #include "msidefs.h" #include "sddl.h" +#include "wine/heap.h" +#include "wine/debug.h" +#include "wine/unicode.h" + #include "msipriv.h" #include "winemsi.h" #include "resource.h" @@ -2396,52 +2398,34 @@ static UINT MSI_GetProperty( MSIHANDLE handle, LPCWSTR name, package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE ); if (!package) { - HRESULT hr; - LPWSTR value = NULL; + LPWSTR value = NULL, buffer; MSIHANDLE remote; - BSTR bname; if (!(remote = msi_get_remote(handle))) return ERROR_INVALID_HANDLE; - bname = SysAllocString( name ); - if (!bname) - return ERROR_OUTOFMEMORY; + r = remote_GetProperty(remote, name, &value, &len); + if (r != ERROR_SUCCESS) + return r; - hr = remote_GetProperty(remote, bname, NULL, &len); - if (FAILED(hr)) - goto done; - - len++; - value = msi_alloc(len * sizeof(WCHAR)); - if (!value) + /* String might contain embedded nulls. + * Native returns the correct size but truncates the string. */ + buffer = heap_alloc_zero((len + 1) * sizeof(WCHAR)); + if (!buffer) { - r = ERROR_OUTOFMEMORY; - goto done; + midl_user_free(value); + return ERROR_OUTOFMEMORY; } + strcpyW(buffer, value); - hr = remote_GetProperty(remote, bname, value, &len); - if (FAILED(hr)) - goto done; - - r = msi_strcpy_to_awstring( value, len, szValueBuf, pchValueBuf ); + r = msi_strcpy_to_awstring(buffer, len, szValueBuf, pchValueBuf); /* Bug required by Adobe installers */ - if (!szValueBuf->unicode && !szValueBuf->str.a) + if (pchValueBuf && !szValueBuf->unicode && !szValueBuf->str.a) *pchValueBuf *= sizeof(WCHAR); -done: - SysFreeString(bname); - msi_free(value); - - if (FAILED(hr)) - { - if (HRESULT_FACILITY(hr) == FACILITY_WIN32) - return HRESULT_CODE(hr); - - return ERROR_FUNCTION_FAILED; - } - + heap_free(buffer); + midl_user_free(value); return r; } @@ -2498,11 +2482,22 @@ HRESULT __cdecl remote_GetActiveDatabase(MSIHANDLE hinst, MSIHANDLE *handle) return S_OK; } -HRESULT __cdecl remote_GetProperty(MSIHANDLE hinst, BSTR property, BSTR value, DWORD *size) +UINT __cdecl remote_GetProperty(MSIHANDLE hinst, LPCWSTR property, LPWSTR *value, DWORD *size) { - UINT r = MsiGetPropertyW(hinst, property, value, size); - if (r != ERROR_SUCCESS) return HRESULT_FROM_WIN32(r); - return S_OK; + WCHAR empty[1]; + UINT r; + + *size = 0; + r = MsiGetPropertyW(hinst, property, empty, size); + if (r == ERROR_MORE_DATA) + { + ++*size; + *value = midl_user_allocate(*size * sizeof(WCHAR)); + if (!*value) + return ERROR_OUTOFMEMORY; + r = MsiGetPropertyW(hinst, property, *value, size); + } + return r; } HRESULT __cdecl remote_SetProperty(MSIHANDLE hinst, BSTR property, BSTR value) diff --git a/dlls/msi/winemsi.idl b/dlls/msi/winemsi.idl index 560b3067822..07a315b2171 100644 --- a/dlls/msi/winemsi.idl +++ b/dlls/msi/winemsi.idl @@ -42,7 +42,7 @@ interface IWineMsiRemote HRESULT remote_DatabaseOpenView( [in] MSIHANDLE db, [in] LPCWSTR query, [out] MSIHANDLE *view ); HRESULT remote_GetActiveDatabase( [in] MSIHANDLE hinst, [out] MSIHANDLE *handle ); - HRESULT remote_GetProperty( [in] MSIHANDLE hinst, [in] BSTR property, [out, size_is(*size)] BSTR value, [in, out] DWORD *size ); + UINT remote_GetProperty( [in] MSIHANDLE hinst, [in, string] LPCWSTR property, [out, string] LPWSTR *value, [out] DWORD *size ); HRESULT remote_SetProperty( [in] MSIHANDLE hinst, [in] BSTR property, [in] BSTR value ); HRESULT remote_ProcessMessage( [in] MSIHANDLE hinst, [in] INSTALLMESSAGE message, [in] MSIHANDLE record ); HRESULT remote_DoAction( [in] MSIHANDLE hinst, [in] BSTR action );