Is the way that wine maps file handles from Unix (Linux, more specifically) to Windows predictable?
I have this Linux program that forks Wine to run a Windows program. The Windows program can easily access stdin/stdout/stderr the way one would expect in a forked Unix program but I am trying to pass one extra file descriptor to the windows program but I am not sure how to do that.
In the Unix program, the FD will be, say, 3. As I am forking then exec'ing Wine, wine itself will have access to this FD and, from Wine's point of view, it should also be 3. The problem is that it seems file handles in Windows are not like in Unix (for example, stdin is not 0, stdout is not 1 and stderr is not 2) so I am assuming that to make this FD available to the WIndows program, it is somehow mapped to a file handle with a different number too. I need to know which one it si to be able to use it. Any pointers on how to do that?
If I compile a C program with winegcc/winelib and fork/exec it, it looks like file handles and file descriptors match so one option is to use it. But I prefer to create the program in a different language so winelib is not ideal.
Any help would be much appreciated.
Try wine_server_fd_to_handle()
Once you register a fd with Wine that way, it lives inside wineserver, and during API calls, you just get back temporary copies of it, usually with different fd numbers.
On Sat, Dec 21, 2019 at 1:57 AM Bruno Albuquerque bga@gmail.com wrote:
Is the way that wine maps file handles from Unix (Linux, more specifically) to Windows predictable?
I have this Linux program that forks Wine to run a Windows program. The Windows program can easily access stdin/stdout/stderr the way one would expect in a forked Unix program but I am trying to pass one extra file descriptor to the windows program but I am not sure how to do that.
In the Unix program, the FD will be, say, 3. As I am forking then exec'ing Wine, wine itself will have access to this FD and, from Wine's point of view, it should also be 3. The problem is that it seems file handles in Windows are not like in Unix (for example, stdin is not 0, stdout is not 1 and stderr is not 2) so I am assuming that to make this FD available to the WIndows program, it is somehow mapped to a file handle with a different number too. I need to know which one it si to be able to use it. Any pointers on how to do that?
If I compile a C program with winegcc/winelib and fork/exec it, it looks like file handles and file descriptors match so one option is to use it. But I prefer to create the program in a different language so winelib is not ideal.
Any help would be much appreciated.
Thanks. That led me to the init_user_process_params() where it seems stdin/stdout/stderr are mapped to the running Windows program. I could not find any code that would do anything with other inherited opened fds and that led me to think that there is really no special handling and it somehow just happens to work with a winelib program (most likely because it has a bigger Linux surface to it).
Based on this, I guess what I really want to know is:
1 - Does a non-winelib Windows program have access to opened fds inherited during a fork/exec of Wine? 2 - If so, is there a way to actually use those fds in the Windows program?
On Fri, Dec 20, 2019 at 7:49 PM Damjan Jovanovic damjan.jov@gmail.com wrote:
Try wine_server_fd_to_handle()
Once you register a fd with Wine that way, it lives inside wineserver, and during API calls, you just get back temporary copies of it, usually with different fd numbers.
On Sat, Dec 21, 2019 at 1:57 AM Bruno Albuquerque bga@gmail.com wrote:
Is the way that wine maps file handles from Unix (Linux, more specifically) to Windows predictable?
I have this Linux program that forks Wine to run a Windows program. The Windows program can easily access stdin/stdout/stderr the way one would expect in a forked Unix program but I am trying to pass one extra file descriptor to the windows program but I am not sure how to do that.
In the Unix program, the FD will be, say, 3. As I am forking then exec'ing Wine, wine itself will have access to this FD and, from Wine's point of view, it should also be 3. The problem is that it seems file handles in Windows are not like in Unix (for example, stdin is not 0, stdout is not 1 and stderr is not 2) so I am assuming that to make this FD available to the WIndows program, it is somehow mapped to a file handle with a different number too. I need to know which one it si to be able to use it. Any pointers on how to do that?
If I compile a C program with winegcc/winelib and fork/exec it, it looks like file handles and file descriptors match so one option is to use it. But I prefer to create the program in a different language so winelib is not ideal.
Any help would be much appreciated.
On 12/21/19 5:34 PM, Bruno Albuquerque wrote:
Thanks. That led me to the init_user_process_params() where it seems stdin/stdout/stderr are mapped to the running Windows program. I could not find any code that would do anything with other inherited opened fds and that led me to think that there is really no special handling and it somehow just happens to work with a winelib program (most likely because it has a bigger Linux surface to it).
Based on this, I guess what I really want to know is:
1 - Does a non-winelib Windows program have access to opened fds inherited during a fork/exec of Wine? 2 - If so, is there a way to actually use those fds in the Windows program?
Hi Bruno,
I'm not sure if this is feasible to you, but keep in mind that "Windows programs" ran under Wine are technically still running on Linux. So you still have access to Linux syscalls (but not libraries, unless you load them manually, which is not worth it).
One possible hack to do this in a "generic" way would be:
1) Use an exception handler in your app.
2) Call the 'uname' system call to make sure the returned sysname is 'Linux'. If the syscall results in an exception, then it's obviously not running on Linux (it could be running on Windows), so do the necessary thing there.
3) If it's 'Linux' then mark it so and simply use Linux syscalls to use the fd and read or write to it. You can use inline assembly for this purpose.
If your program is not intended to run on non-Linux environments then you can skip the first two steps. I realize it's a hack but without winelib I don't think there's much else you can do.
On 12/22/19 6:40 AM, Gabriel Ivăncescu wrote:
On 12/21/19 5:34 PM, Bruno Albuquerque wrote:
Thanks. That led me to the init_user_process_params() where it seems stdin/stdout/stderr are mapped to the running Windows program. I could not find any code that would do anything with other inherited opened fds and that led me to think that there is really no special handling and it somehow just happens to work with a winelib program (most likely because it has a bigger Linux surface to it).
Based on this, I guess what I really want to know is:
1 - Does a non-winelib Windows program have access to opened fds inherited during a fork/exec of Wine? 2 - If so, is there a way to actually use those fds in the Windows program?
Hi Bruno,
I'm not sure if this is feasible to you, but keep in mind that "Windows programs" ran under Wine are technically still running on Linux. So you still have access to Linux syscalls (but not libraries, unless you load them manually, which is not worth it).
One possible hack to do this in a "generic" way would be:
Use an exception handler in your app.
Call the 'uname' system call to make sure the returned sysname is
'Linux'. If the syscall results in an exception, then it's obviously not running on Linux (it could be running on Windows), so do the necessary thing there.
There's also wine_get_host_version(), exported from ntdll, which would probably be easier.
In order to get access to file descriptors in the first place, you can use the counterpart wine_server_handle_to_fd() [also exported from ntdll].
- If it's 'Linux' then mark it so and simply use Linux syscalls to use
the fd and read or write to it. You can use inline assembly for this purpose.
If your program is not intended to run on non-Linux environments then you can skip the first two steps. I realize it's a hack but without winelib I don't think there's much else you can do.
Zebediah Figura z.figura12@gmail.com writes:
On 12/22/19 6:40 AM, Gabriel Ivăncescu wrote:
On 12/21/19 5:34 PM, Bruno Albuquerque wrote:
Thanks. That led me to the init_user_process_params() where it seems stdin/stdout/stderr are mapped to the running Windows program. I could not find any code that would do anything with other inherited opened fds and that led me to think that there is really no special handling and it somehow just happens to work with a winelib program (most likely because it has a bigger Linux surface to it).
Based on this, I guess what I really want to know is:
1 - Does a non-winelib Windows program have access to opened fds inherited during a fork/exec of Wine? 2 - If so, is there a way to actually use those fds in the Windows program?
Hi Bruno,
I'm not sure if this is feasible to you, but keep in mind that "Windows programs" ran under Wine are technically still running on Linux. So you still have access to Linux syscalls (but not libraries, unless you load them manually, which is not worth it).
One possible hack to do this in a "generic" way would be:
Use an exception handler in your app.
Call the 'uname' system call to make sure the returned sysname is
'Linux'. If the syscall results in an exception, then it's obviously not running on Linux (it could be running on Windows), so do the necessary thing there.
There's also wine_get_host_version(), exported from ntdll, which would probably be easier.
In order to get access to file descriptors in the first place, you can use the counterpart wine_server_handle_to_fd() [also exported from ntdll].
Or use wine_server_fd_to_handle() and call Win32 APIs instead of direct syscalls, that's even easier...
Thanks.
My question is now how to access that function from my Windows program as it does not seem to be directly available (i.e. in a importable header file). In any cae, is it similar to _get_osfhandle()? I was considering using it (it is documented by Microsoft) but I also failed at including "msvcrt/io.h" (not found).
On Sun, Dec 22, 2019 at 8:12 AM Alexandre Julliard julliard@winehq.org wrote:
Zebediah Figura z.figura12@gmail.com writes:
On 12/22/19 6:40 AM, Gabriel Ivăncescu wrote:
On 12/21/19 5:34 PM, Bruno Albuquerque wrote:
Thanks. That led me to the init_user_process_params() where it seems stdin/stdout/stderr are mapped to the running Windows program. I could not find any code that would do anything with other inherited opened
fds
and that led me to think that there is really no special handling and
it
somehow just happens to work with a winelib program (most
likely because
it has a bigger Linux surface to it).
Based on this, I guess what I really want to know is:
1 - Does a non-winelib Windows program have access to opened fds inherited during a fork/exec of Wine? 2 - If so, is there a way to actually use those fds in the Windows
program?
Hi Bruno,
I'm not sure if this is feasible to you, but keep in mind that "Windows programs" ran under Wine are technically still running on Linux. So you still have access to Linux syscalls (but not libraries, unless you load them manually, which is not worth it).
One possible hack to do this in a "generic" way would be:
Use an exception handler in your app.
Call the 'uname' system call to make sure the returned sysname is
'Linux'. If the syscall results in an exception, then it's obviously
not
running on Linux (it could be running on Windows), so do the necessary thing there.
There's also wine_get_host_version(), exported from ntdll, which would probably be easier.
In order to get access to file descriptors in the first place, you can use the counterpart wine_server_handle_to_fd() [also exported from
ntdll].
Or use wine_server_fd_to_handle() and call Win32 APIs instead of direct syscalls, that's even easier...
-- Alexandre Julliard julliard@winehq.org
FWIIW, got it to work by loading ntdll.dll and getting the proc to the wine_server_fd_to_handle() function and using it on the fd. After that I could use Win32 functions on the handle as suggested. It is kinda funny that I can use a handle to the underlying fd but I can not use the fd.
In any case, thanks for all your help.
On Sun, Dec 22, 2019 at 10:00 AM Bruno Albuquerque bga@gmail.com wrote:
Thanks.
My question is now how to access that function from my Windows program as it does not seem to be directly available (i.e. in a importable header file). In any cae, is it similar to _get_osfhandle()? I was considering using it (it is documented by Microsoft) but I also failed at including "msvcrt/io.h" (not found).
On Sun, Dec 22, 2019 at 8:12 AM Alexandre Julliard julliard@winehq.org wrote:
Zebediah Figura z.figura12@gmail.com writes:
On 12/22/19 6:40 AM, Gabriel Ivăncescu wrote:
On 12/21/19 5:34 PM, Bruno Albuquerque wrote:
Thanks. That led me to the init_user_process_params() where it seems stdin/stdout/stderr are mapped to the running Windows program. I
could
not find any code that would do anything with other inherited opened
fds
and that led me to think that there is really no special handling and
it
somehow just happens to work with a winelib program (most
likely because
it has a bigger Linux surface to it).
Based on this, I guess what I really want to know is:
1 - Does a non-winelib Windows program have access to opened fds inherited during a fork/exec of Wine? 2 - If so, is there a way to actually use those fds in the Windows
program?
Hi Bruno,
I'm not sure if this is feasible to you, but keep in mind that
"Windows
programs" ran under Wine are technically still running on Linux. So
you
still have access to Linux syscalls (but not libraries, unless you
load
them manually, which is not worth it).
One possible hack to do this in a "generic" way would be:
Use an exception handler in your app.
Call the 'uname' system call to make sure the returned sysname is
'Linux'. If the syscall results in an exception, then it's obviously
not
running on Linux (it could be running on Windows), so do the necessary thing there.
There's also wine_get_host_version(), exported from ntdll, which would probably be easier.
In order to get access to file descriptors in the first place, you can use the counterpart wine_server_handle_to_fd() [also exported from
ntdll].
Or use wine_server_fd_to_handle() and call Win32 APIs instead of direct syscalls, that's even easier...
-- Alexandre Julliard julliard@winehq.org
I am new to writing wine specific things so bear with me for a while. Is there a header file that I can include to get access to those ntdll functions (a cursory look only resulted in me finding the associated c file)? If not, do I have to use LoadLibrary() or some other trick?
Thanks again for all your help so far. It is much appreciated.
On Sun, Dec 22, 2019 at 8:04 AM Zebediah Figura z.figura12@gmail.com wrote:
On 12/22/19 6:40 AM, Gabriel Ivăncescu wrote:
On 12/21/19 5:34 PM, Bruno Albuquerque wrote:
Thanks. That led me to the init_user_process_params() where it seems stdin/stdout/stderr are mapped to the running Windows program. I could not find any code that would do anything with other inherited opened
fds
and that led me to think that there is really no special handling and
it
somehow just happens to work with a winelib program (most
likely because
it has a bigger Linux surface to it).
Based on this, I guess what I really want to know is:
1 - Does a non-winelib Windows program have access to opened fds inherited during a fork/exec of Wine? 2 - If so, is there a way to actually use those fds in the Windows
program?
Hi Bruno,
I'm not sure if this is feasible to you, but keep in mind that "Windows programs" ran under Wine are technically still running on Linux. So you still have access to Linux syscalls (but not libraries, unless you load them manually, which is not worth it).
One possible hack to do this in a "generic" way would be:
Use an exception handler in your app.
Call the 'uname' system call to make sure the returned sysname is
'Linux'. If the syscall results in an exception, then it's obviously not running on Linux (it could be running on Windows), so do the necessary thing there.
There's also wine_get_host_version(), exported from ntdll, which would probably be easier.
In order to get access to file descriptors in the first place, you can use the counterpart wine_server_handle_to_fd() [also exported from ntdll].
- If it's 'Linux' then mark it so and simply use Linux syscalls to use
the fd and read or write to it. You can use inline assembly for this purpose.
If your program is not intended to run on non-Linux environments then you can skip the first two steps. I realize it's a hack but without winelib I don't think there's much else you can do.