"That's ugly, please let's fix this the right way, we have all the necessary infrastructure now." -- Alexandre Julliard, 2009 [1]
This patchset is dedicated to Alexandre, who, to be fair, wasn't wrong, but wasn't exactly right either ;-)
This patchset fixes bug 18070. It also lays the groundwork to fix bugs 31741 and 37856. It can be viewed in full at [2].
The series is divided into roughly three major changes. The first (patches 0001-0003) replaces the method of IPC used (or at least intended to be used) from COM to RPC. This is necessary because the custom action might change the threading model and break our COM proxies, see [3] for more details. I chose RPC over one of the mentioned workarounds since it seemed a much cleaner solution, and additionally made the remote API much simpler (since e.g. we don't have to convert to and from HRESULTs).
The bulk of the series (patches 0004-0040) fix individual functions so that they can be used from a custom action. I use the subject "Make Msi*() RPC-compatible." for consistency's sake, but the changes made vary from tweaking IDL annotations and return types to implementing the entire function (as in MsiView*() which previously blithely returned a local handle).
The last part (patch 0041) performs the actual change, i.e. segregating ACTION_CallDllFunction() into a separate process and building the actual RPC stubs. With a bit of manual fixing this patch should be able to be applied directly on top of any other patch in the series, if it is desired for review purposes to be able to test a change in the "real-world" environment; this is how I did most of my debugging while building the series.
This patchset has been tested for regressions against all installers available through winetricks, plus a few various installers I have on my system. I also tested it against several installers mentioned in bug 18070 or duplicates thereof, including Adobe Acrobat X Pro, so I can confirm that the bug is indeed fixed.
[1] https://www.winehq.org/pipermail/wine-devel/2009-July/077148.html [2] https://github.com/zfigura/wine/tree/newmsi [3] https://www.winehq.org/pipermail/wine-devel/2018-April/125484.html
Zebediah Figura (41): msi: Stop vending WineMsiRemotePackage. msi: Allocate the remote handle on the server side. msi: Convert the IWineMsiRemote* remote interfaces to RPC stubs. msi: Make MsiGetProperty() RPC-compatible. msi: Make MsiSetProperty() RPC-compatible. msi/tests: Clean up property tests. msi: Also null-terminate WCHAR strings. msi/tests: Test properties from custom actions. msi: Make MsiProcessMessage() RPC-compatible. msi/tests: Improve COM test. msi: Make MsiGetActiveDatabase() RPC-compatible. msi: Make MsiDatabaseIsTablePersistent() RPC-compatible. msi: Make MsiDatabaseOpenView() RPC-compatible. msi: Make MsiViewExecute() RPC-compatible. msi: Make MsiViewFetch() RPC-compatible. msi: Make MsiViewClose() RPC-compatible. msi: Make MsiViewGetColumnInfo() RPC-compatible. msi: Make MsiViewModify() RPC-compatible. msi/tests: Add tests for MsiDatabaseGetPrimaryKeys(). msi: Make MsiDatabaseGetPrimaryKeys() RPC-compatible. msi: Make MsiGetSummaryInformation() RPC-compatible. msi: Make MsiDoAction() RPC-compatible. msi: Make MsiSequence() RPC-compatible. msi: Make MsiGetTargetPath() RPC-compatible. msi: Make MsiSetTargetPath() RPC-compatible. msi: Make MsiGetSourcePath() RPC-compatible. msi: Make MsiGetMode() RPC-compatible. msi: Make MsiSetMode() RPC-compatible. msi: Make MsiGetFeatureState() RPC-compatible. msi: Make MsiSetFeatureState() RPC-compatible. msi: Make MsiGetComponentState() RPC-compatible. msi: Make MsiSetComponentState() RPC-compatible. msi: Make MsiGetMode() RPC-compatible. msi: Make MsiSetInstallLevel() RPC-compatible. msi: Make MsiFormatRecord() RPC-compatible. msi: Make MsiEvaluateCondition() RPC-compatible. msi: Handle some invalid parameters in MsiGetFeatureCost(). msi: Make MsiGetFeatureCost() RPC-compatible. msi: Make MsiEnumComponentCosts RPC-compatible. msi: Make remote_GetActionInfo() RPC-compatible. msi: Execute custom actions in a separate process.
dlls/msi/Makefile.in | 8 +- dlls/msi/cond.y | 32 +- dlls/msi/custom.c | 292 ++++++-------- dlls/msi/database.c | 129 +------ dlls/msi/dialog.c | 5 +- dlls/msi/format.c | 43 +-- dlls/msi/handle.c | 30 +- dlls/msi/install.c | 447 +++++----------------- dlls/msi/msi.c | 31 +- dlls/msi/msi.spec | 2 + dlls/msi/msi_main.c | 14 - dlls/msi/msipriv.h | 13 +- dlls/msi/msiquery.c | 236 ++++++++---- dlls/msi/msiserver.idl | 70 ---- dlls/msi/package.c | 506 ++++++++----------------- dlls/msi/record.c | 106 ++++++ dlls/msi/suminfo.c | 27 +- dlls/msi/tests/custom.c | 922 ++++++++++++++++++++++++++++++++++++++++++++- dlls/msi/tests/custom.spec | 1 + dlls/msi/tests/db.c | 41 ++ dlls/msi/tests/install.c | 37 ++ dlls/msi/tests/package.c | 265 ++++++------- dlls/msi/winemsi.idl | 102 +++++ programs/msiexec/msiexec.c | 9 +- 24 files changed, 1938 insertions(+), 1430 deletions(-) create mode 100644 dlls/msi/winemsi.idl