http://bugs.winehq.org/show_bug.cgi?id=20296
--- Comment #45 from Amos Wenger amos@official.fm 2011-04-06 16:13:25 CDT --- (In reply to comment #44)
From what I understood from the Wine code and reading some MSDN is that there are 2 different ways for an LOCAL server. [snip]
Yes, after digging into MSDN and Wine's OLE/COM/RPC implementation, things are now much cleaner in my head. I've played around, it's very easy to detect the presence of the DllSurrogate key and retrieve the correct dll path (from the InprocServer32 key). At first I was going to simply LoadLibrary and call DllRegisterServer but then I realized it would be the same as INPROC and that's not what we want to do here.
Then I read the documentation "Writing a Custom Surrogate" on MSDN, since I figured Wine didn't have a Surrogate implementation at all I might just write Wine's default surrogate server myself. I didn't know Window's default surrogate was in dllhost.exe, thanks for this information :) Although we can't really use it because it would then require a Windows install, right?
So my plan right now is to implement the ISurrogate interface in dlls/ole32/surrogate.c ie. only the LoadDllServer and FreeSurrogate functions as defined in include/objidl.idl I think LoadDllServer should do the LoadLibrary + GetProcAddr to call DllRegisterServer on the given dll, and FreeSurrogate should just, well, exit the process?
Then I thought I might add a hook to ole32.dll to start the surrogate server, so that in our LOCAL_SERVER case it would launch rundll32.exe with the help of CreateProcess calling the new hook (something like LaunchSystemSurrogate for example), which would then call LoadDllServer with the dll path retrieved from the registry using the clsid passed as an argument. *Phew*.
So anyway that's what I'm trying right now, let me know if you think it makes sense, unless someone tells me it's really stupid I'll continue that way ;) I think it might make sense to implement the surrogate a separate application (just like dllhost.exe), but right now I have no idea how to do that in Wine (add a .c file in tools/ ?) so I'm just trying to deal with how little I know of Wine's codebase right now.
Also, yes, I'm aware that League Of Legends' use of LOCAL_SERVER is probably useless in the case of Wine (because we don't do UAC etc., as you explained) but well, it shouldn't hurt anyway, and some other applications might depend on it so we're better off implementing it correctly anyway. Wish me luck!
But maybe it would also be possible to simply modify the registry entry of the CLSID to load the DLL in process instead of patching wine.
I'm not sure how that would be done. Deleting the DllSurrogate entry would still lead to failure since right now the LOCAL_SERVER code is expecting a LocalService entry, which (if I understood correctly) should be a .exe file launching a COM server of some sort. LoL doesn't provide this, just a Dll file with the symbols we need. So can we force inproc from the registry? That would be awesome, because then we could run LoL on stock wine without any patch :) (And without waiting for the next release with proper surrogate support)