Rolf Kalbermatter wrote:
The current service control API directly accesses the registry for most things. In native those fucntions are simple wrappers around RPC calls to the actual service.exe application. Mikolaj Zalewski offered about 3 months ago a possible aproach to implement the service.exe program.
Yes, we need to dig that out again. I forget what was blocking it being committed.
In there the proxy code generated through widl directly calls various RPC functions to communicate with the service manager executable. When doing some tests with native advapi32 under Wine I found that those fucntions seem to be implemented by simply calling more or less directly NdrCallClient2. Widl obviously doesn't generate code yet using this API and I'm sure wire compatibility can be achieved without using NdrCallClient2.
Exactly. The whole point of IDL in DCE/RPC is that it is independent of the DCE/RPC implementation as long as the generated code conforms to the NDR rules. With Microsoft's implementation, most of the NDR rules are implemented in rpcrt4 and all the IDL compiler as to do is output code to call the buffer size, marshall, unmarshall and free functions in the right order. widl should be correct in this respect. (There are some shortcuts that midl/widl take for marshalling base types and the alignments would have to be correct for these, but these are simple to get right.)
There is no reason to use NdrClientCall2 for any purpose in Wine.
But a few questions that came up here:
- How good or complete is Wine's NdrCallClient(2) implementation?
Pretty good, IMHO. We use exactly the code that's in Wine here at CodeWeavers for connecting to Exchange servers (the RPC code is MIDL-compiled code in DLLs used by Outlook).
Would it be feasable to use it for the implementation of the service rpc calls?
No. Everything (except multi-dimensional arrays, possibly) can already be done by the code we output already. Adding code to output -Oicf proc format strings in widl would be possible, but unnecessary.
It also adds problems because gcc and MSVC have differing opinions on how to return unions from functions. For this reason, we have implemented NdrClientCall2 in Wine by pretending it returns a LONG_PTR instead. widl would have to decide on whether it wanted to be compatible with our signature of the function or the MS one.
- Assuming it would be not a whole lot of work to make NdrCallClient(2) work
for this, would it be desirable to use this API instead of the code generated by widl currently from complexity and/or performance view?
It reduces code size (and on modern processors that is supposed to lead to performance gains), but that is the only advantage that it gives us.
- Of course this would mean that widl would have to support (some of) the
{Oi | Oic | Oif | Oicf} flags to generate the proxy code but as it seems the necessary code generator at least for the client side would be fairly trivial as it is mostly just a wrapper around NdrClientCall(2) and most of the nitty gritty work is done in in that function. A midl generated proxy code using -Oicf looks at least quite trivial.
Any opinions about this anyone?