Alexandre, et. al,
Our WinMain doesn't get called because our patch prevents it. If it were to get called, we'd be on a different (Wine-created) stack, with all kinds of things that are hard to undo, like the exception handling, etc.
The goal of my patch was to have minimal impact on Wine, and allow the *same* wine code/binaries to be used for regular use as well as shared library, so any future Wine version you create will automatically also support shared library use.
I modeled the global __wine_shared_lib variable after the __wine_main_argX globals you introduced last year, assuming that following that style would create the least resistance of getting my patch accepted.
Having Wine set up the TEB and stack environment and actually call our WinMain and us then trying to 'undo' that in WinMain creates potential for future breakage of our library, in case you change something related to the TEB & stack. Having a variable in kernel that prevents creation of these, on the other hand, is easy to maintain, and really has no impact on performance or coding.
I will be happy to implement any suggestions you may have on how to solve it another way in a single codebase that doesn't intruce the potential of breaking it in the future. I may very well have overlooked something.
Regards, Peter
-----Original Message----- From: "Alexandre Julliard" julliard@winehq.org To: "Miguel de Icaza" miguel@ximian.com Cc: "Peter Dennis Bartok" peter@novonyx.com; "Robert Shearman" R.J.Shearman@warwick.ac.uk; wine-devel@winehq.org Date: 07 March, 2004 17:37 Subject: Re: Wine as shared library patch
Miguel de Icaza miguel@ximian.com writes:
Well, the issue is that our WinMain is never called, and we would rather not depend on this in our patch, but instead get the small global that says `Hey Wine, just return'.
The global variable thing is ugly; we could export a different entry point instead, but I'm not sure it's really necessary. Why doesn't your WinMain get called?
-- Alexandre Julliard julliard@winehq.org
"Peter Dennis Bartok" peter@novonyx.com writes:
Having Wine set up the TEB and stack environment and actually call our WinMain and us then trying to 'undo' that in WinMain creates potential for future breakage of our library, in case you change something related to the TEB & stack.
The TEB & stack layout are dictated by binary compatibility, and are much less likely to change than the Wine init code. It's not clear to me at all that this global variable hack is the right interface for a proper shared library implementation, and I'm not going to commit to supporting that interface in the future. OTOH WinMain and the TEB layout are not going to change, so you should build on top of that.
hello,m
Having Wine set up the TEB and stack environment and actually call our WinMain and us then trying to 'undo' that in WinMain creates potential for future breakage of our library, in case you change something related to the TEB & stack.
The TEB & stack layout are dictated by binary compatibility, and are much less likely to change than the Wine init code. It's not clear to me at all that this global variable hack is the right interface for a proper shared library implementation, and I'm not going to commit to supporting that interface in the future. OTOH WinMain and the TEB layout are not going to change, so you should build on top of that.
It still makes the code too hard for us to maintain.
Our patch is simple, and we lack the experience to work on Wine, TEB and what not. We just do not have the time to learn everything there is to Wine.
For now, we will ship a different Wine RPM, and use a different prefix to avoid conflicting or something like that.
Miguel.
Miguel de Icaza miguel@ximian.com writes:
Our patch is simple, and we lack the experience to work on Wine, TEB and what not. We just do not have the time to learn everything there is to Wine.
Something along these lines should do the trick:
#include <wine/library.h> #include <stdio.h> #include <windows.h> #include <winternl.h> #include <setjmp.h>
static jmp_buf jmpbuf;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) { longjmp( jmpbuf, 1 ); }
int SharedWineInit(void) { unsigned char Error[1024]=""; char *WineArguments[] = {"sharedapp", LIBPATH "/wine-sharedlib.exe.so", NULL};
if (!setjmp( jmpbuf )) { wine_init(2, WineArguments, Error, sizeof(Error)); printf( "should not get here\n" ); } NtCurrentTeb()->Tib.ExceptionList = (void *)~0UL; VirtualFree( NtCurrentTeb()->DeallocationStack, 0, MEM_RELEASE ); NtCurrentTeb()->DeallocationStack = NULL; NtCurrentTeb()->Tib.StackBase = (void*)~0UL; /* FIXME: should find actual limits here */ NtCurrentTeb()->Tib.StackLimit = 0; return(0); }
Hello,
Miguel de Icaza miguel@ximian.com writes:
Our patch is simple, and we lack the experience to work on Wine, TEB and what not. We just do not have the time to learn everything there is to Wine.
Something along these lines should do the trick:
I tested something like this (my version of the patch that is missing all the Teb stuff) and it works.
Could we get this in the official Wine distribution? Peter's patch includes the Makefile and configure magic as well (the rest could be dropped).
Miguel de Icaza miguel@ximian.com writes:
Could we get this in the official Wine distribution? Peter's patch includes the Makefile and configure magic as well (the rest could be dropped).
I would really prefer for you to ship it yourself. This is not a general solution, and we don't want other projects to start depending on that.
Alexandre Julliard wrote:
Miguel de Icaza miguel@ximian.com writes:
Could we get this in the official Wine distribution? Peter's patch includes the Makefile and configure magic as well (the rest could be dropped).
I would really prefer for you to ship it yourself. This is not a general solution, and we don't want other projects to start depending on that.
I strongly disagree!
I'm not sure what this patch can do. But if it lets you Inject into wine mid run from any Linux application or Library than it is tremendous. MPlayer can use it, a unixODBC to windowsODBC can use it, web-browser plug-ins can use it.
Perhaps if Migel or Peter can elaborate on what this patch can do? (Also if you could post somewhere public an example application that demonstrate the use of it.)
1) Can it enable a shared library to load Wine and hence even windows DLLS in-process? So a Linux Application becomes a Wine-Lib app mid run. 2) Or is it Just a way for a kind of WinLib2 type of application that wants to have its own main. Not needing to be run through wine, And can be linked as an ELF executable instead of shared-library. But if so what would prevent it to be 1. main was called somewhere. a Library entry point is called. Now it will call wine_init...
In any case this patch is very important and could make wine much (much) more usable from Linux land. Wine becomes not just a Windows Loader but also a basic service provider. Or at least a nice Fancy Winelib-App.
I would like to see this patch in. I agree that a global variable is bad. The Set-jump put NULLS every where, is even worse. It should be with a proper interface. Maybe even a "wine_init_ex". A regression test should be submitted that checks that this functionality is not broken with new code patches.
There are a lot of Wine orphans out there. One more is never good. In fact many of these orphans are so because of this above need. Load DLLs or Win32 functionality in a bigger Linux context. Where it is not practical to be a Winelib. So please bring these babies home. (Specially that ximian baby it looks like one with lots of potential :) )
Now if this patch is not what I think it is, and it is Just a bunch of crap. Than please forgive my big mouth. Perhaps some day there will be a patch that does what I'm looking for. (maybe I'm a dreamer, but I'm not the only one)
Free Life Boaz
On Tue, 09 Mar 2004 12:27:17 +0200, Boaz Harrosh wrote:
I strongly disagree!
I'm not sure what this patch can do. But if it lets you Inject into wine mid run from any Linux application or Library than it is tremendous. MPlayer can use it, a unixODBC to windowsODBC can use it, web-browser plug-ins can use it.
For the record there are still a ton of unresolved questions that Mono is just choosing to ignore here (because they can). For instance, multithreading won't always work correctly, but as S.W.F is not thread safe this doesn't seem to matter too much. I think stuff like exception handling and so on won't work either. So it really is not a general solution.
Being able to initialize winelib mid-flight is possible but a whole ton of work that very few people understand enough to do (in fact maybe only AJ).
thanks -mike
Mike Hearn wrote:
For the record there are still a ton of unresolved questions that Mono is just choosing to ignore here (because they can). For instance, multithreading won't always work correctly, but as S.W.F is not thread safe this doesn't seem to matter too much. I think stuff like exception handling and so on won't work either. So it really is not a general solution.
Than that is OK. The ground API work (wine_init_ex) should be laid out. Than if only a limited functionality can be used like user32 than OK. Any one using this, will have to QA heavily. But at least it is out there and people start using it and fixing it.( release early and often. No?) Just make sure it does not brake regular wine.
Mike Hearn wrote:
Being able to initialize winelib mid-flight is possible but a whole ton of work that very few people understand enough to do (in fact maybe only AJ).
thanks -mike
I'm Glad you said that. I'm sure you are absolutely right. But it looks like we do have a couple of talented guys out here that are willing to invest time in this. I would not want to disturb AJ schedule all that much. Just that he looks at it in a favorable way and lay down the road map of how and where to go. Than use the talents out there to do the actual work, under his guidance. I do think that a lot of people agree it is important outside the MONO project. And please none of that long-Jump stuff. (should I even begin to explain).
Alexandre Julliard wrote:
I would really prefer for you to ship it yourself. This is not a general solution, and we don't want other projects to start depending on that.
Now that I look at it again. I see what you are saying. But I think that you should not give up on them that easily. And some of these other projects look very interesting 2. Let them start depending on something solid even if it is limited in functionality (no threads) but let them never the less. I, for one, is very interested in this patch please don't make me go and fetch it somewhere else, and don't let me fight by myself every time a new PATCH breaks it. As mike said the final judgment is yours and I trust it. Just wanted to point out the importance of this and the doors it can open for wine.
Free Life Boaz
Hello,
I strongly disagree!
I'm not sure what this patch can do. But if it lets you Inject into wine mid run from any Linux application or Library than it is tremendous. MPlayer can use it, a unixODBC to windowsODBC can use it, web-browser plug-ins can use it.
The intention is to have a module wine-sharedlib.so that you can dlopen and call a method in there to have Wine initialize itself. After this you can call the API as a library.
Now, this might not be as helpful to others as you might thinkg, unless they dlopen/dlsym every symbol they want to import (this is what we do with Mono: every symbol we need has to be explicitly invoked).
MPlayer sounds like the perfect consumer for this though, and drivers as well.
Perhaps if Migel or Peter can elaborate on what this patch can do?v (Also if you could post somewhere public an example application that demonstrate the use of it.)
Mono on CVS (mono and mcs modules) now have the capability of running Windows.Forms applications.
Windows.Forms is basically an API to create GUI applications with .NET and its essentially a wrapper around Win32, hence our strong desire to use Wine as a runtime library.
- Can it enable a shared library to load Wine and hence even windows
DLLS in-process? So a Linux Application becomes a Wine-Lib app mid run.
Yes, it does that.
We need that to support third party components that might want to P/Invoke (.NET parlance for dlopen/dlsym/call) Win32 methods.
I would like to see this patch in. I agree that a global variable is bad. The Set-jump put NULLS every where, is even worse. It should be with a proper interface. Maybe even a "wine_init_ex". A regression test should be submitted that checks that this functionality is not broken with new code patches.
The global variable is gone; All you need is the sample program that Alexandre posted (and its Makefile)
Miguel
Hello,
Could we get this in the official Wine distribution? Peter's patch includes the Makefile and configure magic as well (the rest could be dropped).
I would really prefer for you to ship it yourself. This is not a general solution, and we don't want other projects to start depending on that.
Our issue is that we would need to create yet another package with a different dependency chain. If you ship this you make our live a lot simpler.
But we will ship it ourselves if we absolutely have to.
On Tue, 09 Mar 2004 09:51:40 -0500, Miguel de Icaza wrote:
Our issue is that we would need to create yet another package with a different dependency chain. If you ship this you make our live a lot simpler.
But we will ship it ourselves if we absolutely have to.
I'm not sure I understand - why do you need to have this shared lib with the longjmp stuff shipped with Wine? This is just a winelib app like any other right, so you can ship that with Mono and run it using whatever Wine is installed?
thanks -mike