[stdio] [communications] [security]

Using stdio

Choi Young-Kyu asked the following straight-forward questions in the comp.os.ms-windows.programmer.win32 newsgroup and received three excellent replies:

Questions:

1. Is it impossible to generate a console command which display an image onto the screen such as "xv" in UNIX ? For example in UNIX:

	% cat image.gif | ...image-processing... | xv -

2. If 1 is possible, what are those tools available in network ?

3. If not, what is the best approach to separate console commands and GUIs ?

Reply 1 - Charlie Beerman:

Choi, if you are writing a console-mode application you have to get the handles to the standard input/output/error streams. Here is an example:

    HANDLE hStderr;
    HANDLE hStdin;
    HANDLE hStdout;
    hStderr = GetStdHandle( STD_ERROR_HANDLE );
    hStdin = GetStdHandle( STD_INPUT_HANDLE );
    hStdout = GetStdHandle( STD_OUTPUT_HANDLE );

Then you can read from stdin and write to stdout/stderr using the ReadFile and WriteFile API calls. (The first argument to these calls is the appropriate file handle from the example.)

I haven' t tried passing non-text data through this mechanism though, so I'm not certain what will happen if your data contains a byte with value 26 decimal (CTRL-Z).

The main difficulty in what you are trying to do is to pipe data to a Windows application. In DOS and Windows 3.1, a "pipe" is implemented by a temporary file, so the input must be complete before the output can go to the other end of the "pipe". This is not true on NT, though. If XV can read data from the standard input, great. Otherwise, you have to trick the pipe into using a temporary file.

I just wrote a program to do something similar. What I had to do was to read the standard input using the mechanism I described above, and write the data to a temporary file. Then I could use CreateProcess to start my Windows application with the temporary filename as a command-line argument. Of course, I need to delete the temporary file at some point. I used the API call WaitForInputIdle to wait until the Windows app finished initializing. You can also use GetExitCodeProcess to find out if the Windows app has terminated and wait for that before deleting the temporary file.

If you want this program send me mail and I'll make it available to you. Let me know if you want the source and/or executable. The program is called PIPETO and is used as in this example:

  C:> dir | pipeto notepad

in which case the output of the DIR command is sent to the Windows NT Notepad. Like I said, I haven't tried it with binary data.

Reply 2 - Doug Hamilton (author of the Hamilton C-Shell):

No problem. You can write such an app under NT also. Even graphical apps inherit stdio handles, which they can retrieve with GetStdHandle. The only limitation you should bear in mind is that if the handle being passed to the graphical process is to a console window, it will not be valid outside that console window.

Let me give you an example: Suppose you write a graphical app that tries to use printf. You start it from the DOS command prompt running in a console window. No output shows up. Why? Because the handle you've passed it isn't valid in that new graphical window. Same thing if the graphical app had tried to read stdin and you'd passed it a handle tied to the keyboard in you console window.

But if the handles you pass are tied to any other kind of thing you might normally use with stdio, it'll work just fine. In your example, your xv app will have no trouble reading data from stdin because stdin will be tied to the output end of a pipe, which is certainly inheritable to a graphical app.

Reply 3 - Adrian Milliner

There is nothing to stop any console process from opening windows and reading the message queue. For example the following is quite OK:

#include <stdio.h>
#include <windows.h>
void main(int argc, char*argv[])
{
    if (argc > 1)
        MessageBox(NULL,argv[1],argv[0],MB_OK);
}

Obviously you have access to stdin, stdout etc. For graphics data, you'd have to set the the translation mode to binary using something like:

    _setmode(_fileno(stdin),_O_BINARY);

If you wanted to access stdin/out through a normal GUI application, then you can access HANDLEs to these streams using GetStdHandle().

If you already had an NT application that reads images from files, you could make it read from a pipe by writing a simple console app that copies stdin (in binary mode) to a temp file, then call the other app with that file as it's parameter...

Communications

Availability of ONC/RPC/XDR under NT

NetManage sells an RPC/XDR-SDK for NT, among other very useful TCP/IP products for Windows.

Noblenet (+1-508-460-8222) also has ONC RPC for NT. Thanks to Bill Duckett of NobleNet.

Also, GMD in Germany has a free version available (click here to download it).

Mimicking accept() and select() in NT

WaitForMultipleObjects works fine with connected sockets, it will not work with bound but non-connected sockets (the sort that you could do an accept() on in UNIX). This means if you have a select() loop that processes requests and also (under UNIX) will return on requests for new connections you can't use WaitForMultipleObjects(). You have to use another thread doing the Winsock select() and then cascade it up to the WaitForMultipleObjects via a pipe.... (tacky) - Thanks to Jeremy Allison

 

Setuid and Security Aspects

Well, finally as of NT version 3.51, the Security APIs have been made public. Since the final commercial release, build 1057, they actually work (the beta version, build 944, had some problems).

As an example, see the source code of an NT version of UNIX's su command written by David Wihl (editor of this FAQ) and Steffen Krause.

[stdio] [communications] [security]