Hello,
I've been trying to compile Wine on Cygwin with the idea of running Windows
apps through an X server. I've had mixed success.
Short story:
This is a picture of Wine's notepad.exe running on my Windows 7 Ultimate x64
and displayed on my Cygwin/X server. I tried to display it remotely - obviously
it works. There are some major problems, but I do believe that somebody who
knows Wine better than I do can fix these and make the damn thing work. :)
http://www.flickr.com/photos/54965063 at N03/5094624816/#/
Long story:
There were some problems compiling Wine's main libraries on Cygwin (ntdll,
user32, kernel32, winex11.drv, gdi32, wineserver) so I made a couple of minor
changes, which I do not think are a source of issues. The REAL problems started
when I tried to get things to work. :)
First of all - I do not use the "wine" loader. A lot of things are
being done in it prior to calling a program - most of which the Windows one does
anyways, but some (for example starting and connecting to the wine server) had
to be done explicitly. There are two problems here - I have put the starting and
connecting to the wineserver in DllMain in ntdl1.dll (note the '1' - all
wine dlls are the same as their Windows counterparts, only with a 1 instead of 2
(or 'l', in the case of ntdll :) ) in the end), hoping that this is
going to be one of the first DLLs to be loaded by the loader as all others
depend on it. This may or may not be a problem, I am not sure. The second is
this - is this the only thing that has to be done explicitly that the
"wine" loader does and the Windows' doesn't (connecting to
wineserver)? For example there is the "server_init_process_done"
function, which I am not explicitly calling - should it be? Also - I am calling
"server_init_thread" with NULL - perhaps that is important? I do not
fully comprehend what Wine does prior to jumping to the main function in a
program, so I need help from someone who knows what's going on. :)
Another problem with ntdll.dll - there were some missing symbols when linking. I
noticed that winebuild should have been generating an assembly file which should
have been assembled and linked to ntdll - well, it wasn't. I tried
generating it by hand and assembling it but the Cygwin's assembler
didn't like some syntax, after that it complained about missing symbols
(_end, which Cygwin's linker obviously doesn't support). You can diff
winebuild's directory with the original one to see the changes I made. Is
everything right?
Ntdll yet again - it passes a lot of file descriptors through sockets. Which is
not implemented in Cygwin. :) I went around it by using named pipes - I pass the
name of the fifo through the socket and open it from both sides. Seems to work
for most parts, except for example where you pass the file descriptor, which you
got from XOpenDisplay (in winex11.drv) through a socket - there is nothing I can
do about that. I tried opening it from the proc filesystem but doesn't seem
to work. Opening the same display from the server doesn't help either - I
probably get back a "different" display or something. Any solutions?
Is this FD actually used in wineserver?
winecrt0 - DllMain. The calls to _init and _fini are not possible like that. I
don't even understand where the hell _fini is being linked to... :) Take a
look at how I have changed that. Is it a problem?
So I built ntdl1.dll, kernel31.dll, gdi31.dll, user31.dll, winex11.drv,
notepad.exe. Notepad ran, didn't have dialog boxes. Compiled comdlg31.dll,
linked to it, ran notepad. This time there were dialog boxes for almost
everything - however the "open file" and "save as" don't
show files - the about box doesn't show up and so on. There are other
problems - you can't see for some reason on the picture, but the mouse is a
black box - which is kind of funny, because it IS fine in the beginning (before
some calls to "accept_hardware_message" or something) but then it
becomes like that. The title of the windows is... strange? Typing doesn't
work (but ESC and ALT+F4 do). It is not very responsive - clicking on buttons
takes a couple of seconds to take effect. And so on. Problems I can't figure
out. I tried adding shell31.dll and comctl31.dll, but no luck - the program
doesn't even run. I've been trying to figure it out - DllMain isn't
being invoked with DLL_PROCESS_ATTACH or something. And I am confused because
Cygwin adds its own code before the "real" DllMain is invoked so I
can't understand what's going on. I did see that some DllMains were
being called a couple of times without entering in the "real" DllMain
and after that being called with DLL_PROCESS_DETACH (that is with no
DLL_PROCESS_ATTACH before that, so some segmentation faults were happening)... I
did see that "int 3" is breaking apps so they don't run... I did
see that IDA went crazy at some point... I am really not sure what's going
on anymore and I'm tired. :) And I am not sure anymore that computers
actually do what you tell them to do. :)
Winex11.drv links shell31 and comctl31 in "delay mode". I use dlltool
to produce the static libraries for the delayed variant of the DLLs, but then I
had to find the delayimp static library in Cygwin - I couldn't. In
libs/delayimp I've added a version from somewhere... does it work?
Another design decision - I am trying to use the REAL ntdll.dll and kernel32.dll
as much as possible. This might be a problem when Wine must create a new process
(is it?) and it uses the real kernel32.dll's CreateProcess, which
doesn't communicate with wineserver...? Another problem is
GetCurrentThreadId and ProcessId - they return their Windows values, which are
different than those that wineserver has. This could be a problem.
I am using Windows 7 Ultimate x64. Anything else would be a problem - I've
tried running it on a 32-bit XP, but there are some functions missing from ntdll
and kernel32 (because it is an XP, and not Vista/7), which Wine uses, as well as
some Wow64 functions too (because it is a 32, not 64-bit OS)... so I guess using
Windows 7 x64 cannot be avoided, at least not without some pain.
I am using Wine 1.3.5. Is this a mistake?
libwine had a problem after just "making" it. The DLL didn't
include some symbols needed by other ones. I used the same compilation
"line" as Wine on Linux and it seems to be fine.
kernel32's spec file has a LOT of -private parts. This is not recognized by
Cygwin as valid syntax - had to comment those out.
There are some synchronization issues in ntdll with the communication with the
server. This must be looked at.
I think that's enough for starters. I've probably missed some things
that I have changed and/or think they are important, but anyway. I've made a
project in Google Code (I just wanted to upload a single file, why does it have
to be so hard?!), here's the link:
http://code.google.com/p/wine-on-windows/downloads/list
Read the build instructions and then say what you think. :)