I'm writing a program in which I have a Windows DLL that I need to load. The DLL contains a function that returns a pointer to some data, and I want to expose that data as file data in a Fuse file system. My first thought was that I could have the program load the DLL using winelib, but I'm not sure what's involved in this and whether the resulting program could also use the Fuse libraries. I'm a bit of a novice to Wine, and Linux programming in general, so I'd appreciate any expert opinions you guys have about the best way to do this.
Thanks in advance, Richard
I'm writing a program in which I have a Windows DLL that I need to load.
The DLL contains a function that
returns a pointer to some data, and I want to expose that data as file
data in a Fuse file system.
My first thought was that I could have the program load the DLL using
winelib, but I'm not sure what's
involved in this and whether the resulting program could also use the Fuse
libraries. I'm a bit of a
novice to Wine, and Linux programming in general, so I'd appreciate any
expert opinions you guys have about
the best way to do this.
Unfortunately you can't just link to winelib with -lwine or something, because the Wine DLLs(and most likely the Windows DLL) need some extra services running to work properly. That includes things like a certain memory layout, the registry, etc.
You have to use winegcc(see 'winemaker' for starting points). That way your app is compiled to a .exe.so file that can be run with 'wine foo.exe.so' or with a helper script. This application is a native Linux app, and it can link to Linux libraries like Fuse, and at the same time use Win32 API calls from Wine and e.g. open a DLL with LoadLibrary.
I tried but I've hit a problem. I'm just trying to compile the "Hello world" Fuse application. (http://fuse.sourceforge.net/helloworld.html) In regular gcc, I can compile and run it fine:
$ gcc -D_FILE_OFFSET_BITS=64 -DFUSE_USE_VERSION=22 -lfuse -o main main.c $ mkdir test $ ./main test $ cat test/hello Hello World! $ sudo umount test $ rm -r test
All goes well. However, if I try to compile this app with winegcc, it fails to run properly:
$ winegcc -D_FILE_OFFSET_BITS=64 -DFUSE_USE_VERSION=22 -lfuse -o main main.c $ mkdir test $ ./main test fusermount: failed to open /etc/fuse.conf: Permission denied fusermount: waitpid: No child processes $ sudo umount test
(I still had to umount the directory even though the mount failed, as mtab recorded that both /dev/fuse and main.exe.so were mounted to the directory, despite the failed mount. Using umount cleaned the entried from mtab.) I also tried to do so as root (given the whole permission denied thing):
$ sudo su # ./main test fuse: waitpid: No child processes # umount test # rm -r test
If I compile the app again using the first method, it goes flawlessly again. What do I need to do to get it working with winegcc?
On Wed, Dec 24, 2008 at 6:52 AM, Stefan Dösinger stefan@codeweavers.com wrote:
You have to use winegcc(see 'winemaker' for starting points). That way your app is compiled to a .exe.so file that can be run with 'wine foo.exe.so' or with a helper script. This application is a native Linux app, and it can link to Linux libraries like Fuse, and at the same time use Win32 API calls from Wine and e.g. open a DLL with LoadLibrary.
Richard Stitz wrote:
I tried but I've hit a problem. I'm just trying to compile the "Hello world" Fuse application. (http://fuse.sourceforge.net/helloworld.html) In regular gcc, I can compile and run it fine:
Just using "winegcc" is not enough. You have to run it with Wine: http://forum.winehq.org/viewtopic.php?t=3177
Vitaliy
I thought that the "main" executable being produced by winegcc was just a script that called wine with "main.exe.so"? This seems to be the case, as attempting to run "wine main" fails (Module not found), and running "wine main.exe.so" produces exactly the same results as running "./main" did.
On Wed, Dec 24, 2008 at 6:54 PM, Vitaliy Margolen wine-devel@kievinfo.com wrote:
Just using "winegcc" is not enough. You have to run it with Wine: http://forum.winehq.org/viewtopic.php?t=3177
Bottom post here!
Richard Stitz wrote:
On Wed, Dec 24, 2008 at 6:54 PM, Vitaliy Margolen wine-devel@kievinfo.com wrote:
Just using "winegcc" is not enough. You have to run it with Wine: http://forum.winehq.org/viewtopic.php?t=3177
I thought that the "main" executable being produced by winegcc was just a script that called wine with "main.exe.so"? This seems to be
No. It does much more then that.
the case, as attempting to run "wine main" fails (Module not found), and running "wine main.exe.so" produces exactly the same results as running "./main" did.
Have you actually looked at the winegcc command in that forum thread? I guess not. You didn't compile your binary properly.
Vitaliy
Tried adding in those other options and the only difference it makes is that I get an additional error message when I try to execute the program as a normal user. Instead of getting:
fusermount: failed to open /etc/fuse.conf: Permission denied fusermount: waitpid: No child processes
...I now get:
fixme:ntoskrnl:KeInitializeSpinLock 0x4577a4 fusermount: failed to open /etc/fuse.conf: Permission denied fusermount: waitpid: No child processes
Running the program as root behaves identically to before.
On Thu, Dec 25, 2008 at 10:05 AM, Vitaliy Margolen wine-devel@kievinfo.com wrote:
Have you actually looked at the winegcc command in that forum thread? I guess not. You didn't compile your binary properly.
So would the best way to do this be to have a separate process for the Wine program that loads the DLL, and then have the Fuse process communicate over pipes or some other IPC method?
$ winegcc -D_FILE_OFFSET_BITS=64 -DFUSE_USE_VERSION=22 -lfuse -o main main.c $ mkdir test $ ./main test fusermount: failed to open /etc/fuse.conf: Permission denied fusermount: waitpid: No child processes $ sudo umount test
Sorry, I've no idea. Probably fuse uses some sort of framework that expects you to use it in a specific way like Wine does too, and collides with Wine. I recommend you to ask this question on the Fuse mailing list too, probably they can help out.
There's at least one potential problem if Fuse creates a process or thread behind the application's back. In that case there is no Win32 process in Wine for that process(because Wine has no idea about it). No problem if it just runs Fuse's or your code, but if the Windows DLL code is called and it calls GetCurrentProcess() or something similar you have a problem.